NameNotPresent Posted July 24, 2015 Share Posted July 24, 2015 I am trying to remove equipped armor pieces from characters using "removeme" and "removemeIR" but it is not working. Is this wrong? shield.removemeIR Link to comment Share on other sites More sharing options...
DrakeTheDragon Posted July 24, 2015 Share Posted July 24, 2015 Used in this context the RemoveMe commands should work. The Wiki page disagrees on its use via explicit referencing, "shield.RemoveMe", but following basic ObScript syntax it should still work regardless.The OBSE command, however, is documented to work exactly that way. But it depends on how you obtained "shield" in this case. If the script itself is running on the item (an Object script attached to the item to be removed), the non-explicit use "RemoveMe" or "RemoveMeIR" without any calling reference given (the object the script is running on is implicitly used as the calling reference automatically where omitted) is almost guaranteed to work. Though if the reference "shield" was obtained via basic inventory access functions, like "set shield to actor.GetEquippedObject <slot>" or "set shield to actor.GetEquipmentSlotMask <slotmask>", what those returned were the "Base Objects" of the items equipped, not the actual references, thus their return value cannot be used as a calling reference to "RemoveMe" or "RemoveMeIR". So, could you give us perhaps a little more of the script framework surrounding your use of "RemoveMe" or "RemoveMeIR" so we could spot any possible mistakes in that area as well? Link to comment Share on other sites More sharing options...
NameNotPresent Posted July 26, 2015 Author Share Posted July 26, 2015 (edited) Here is the whole script. This scripted is called by an event handler. I am also trying to decide/figure out, how to track whether or not the hit was a power attack. I have tried various methods to remove the shield includeing trying to unequip it first, which did not work either. scn AAANNPonhitFunctionref targetref attackerref attackweaponshort KnockawayChanceshort knockawayforceshort targetagilityshort attackweapontypefloat attackweaponSPEEDshort shieldbreakChancefloat shieldHealthref shieldbegin function { target, attacker } set attackweapon to attacker.GetEquippedObject 16 set attackweapontype to attackweapon.GetWeaponType set attackweaponSPEED to attackweapon.GetWeaponSpeed if target.IsBlocking ==1 ;--------------------------------------------------------------------- Shield Break Chance if target.IsShieldOut ==0 return else set shieldbreakChance to GetRandomPercent + 1 set shieldHealth to target.GetEquippedCurrentHealth 13 if shieldHealth <=100 set shieldHealth to shieldHealth / 2 endif if attackweapontype ==2 ;Effect of 1H Blunt if shieldbreakChance <=10 set shield to target.GetEquippedObject 13 shield.UnequipMe shield.RemoveMeIR endif else if attackweapontype ==3 ;Effect of 2H Blunt if attackweaponSPEED <=0.65 if shieldbreakChance <=20 set shield to target.GetEquippedObject 13 target.SetEquippedCurrentHealth 0 13 target.RemoveItemNS shield 1 endif endif else return endif endif endif ;--------------------------------------------------------------------------------------- else ;---------------------------------------------------------------------- Knockback chance on attack ;MessageEX "Weapon is %n", attackweapon if attackweapontype ==3 if attackweaponSPEED <=0.65 set KnockawayChance to GetRandomPercent + 1 if KnockawayChance > 70 set targetagility to target.GetActorValue agility set knockawayforce to 40/(1+targetagility*-.008) attacker.PushActorAway target, knockawayforce endif endif endif ;----------------------------------------------------------------------- endif ;target.PlayMagicShaderVisuals effectFireDamage 1 ;attacker.PlayMagicShaderVisuals effectFrostDamage 1end Edited July 26, 2015 by NameNotPresent Link to comment Share on other sites More sharing options...
Maskar Posted July 26, 2015 Share Posted July 26, 2015 GetEquippedObject returns a base object. Link to comment Share on other sites More sharing options...
Surilindur Posted July 26, 2015 Share Posted July 26, 2015 (edited) The problem is probably, as Drake said, the part where you set the 'shield' to a "<ref>.GetEquippedObject <slot>" that returns the base object, not the reference currently equipped. That is why RemoveMeIR will not work, as the 'shield' is not referring to the one equipped but the base object of the equipped item. You can get the reference (not base object) using ForEach loop with a ref iterator-sort-of-thingy-whatever-it-is-named, which will return a reference. A ForEach with a ref could probably work like that in your case (also found in OBSE command documentation): ref rActor ; Actor, the 'container' in this loop ref rTemp ; Temporary ref pointing to the reference, not base object ForEach rTemp <- rActor If ( rTemp.GetEquipmentSlot == 13 ) ; For example ; Here, rTemp can be used OR - as you would probably want to do, ; as you want to get the refs, store it in another variable, like 'shield' ElseIf ( ...) ... EndIf Loop With that one in use, your script, when using references instead of base objects, might look like that (not like that, but maybe work in a way that distantly resembles it): ScriptName AAANNPonhitFunction ref rTemp ref rTarget ref rAttacker ref rAttackerWeapon short iAttackerWeaponType float fAttackerWeaponSpeed short iKnockawayChance float fKnockawayForce short iTargetAgility ref rTargetShield short iTargetShieldBreakChance float fTargetShieldHealth Begin Function { rTarget, rAttacker } ForEach rTemp <- rAttacker ; Find attacker's weapon If ( rTemp.GetEquipmentSlot == 16 ) && ( rTemp.IsEquipped ) let rAttackerWeapon := rTemp EndIf Loop ; If attacker has no weapon, and is armed with fists? Should the rest if the script be ignored? If ( rAttackerWeapon == 0 ) MessageEX "%n has no weapon in slot 16", rAttacker Return EndIf ForEach rTemp <- rTarget ; Find target's shield If ( rTemp.GetEquipmentSlot == 13 ) && ( rTemp.IsEquipped ) let rTargetShield := rTemp EndIf Loop let iAttackerWeaponType := rAttackerWeapon.GetWeaponType let fAttackerWeaponSpeed := rAttackerWeapon.GetWeaponSpeed If ( rTarget.IsBlocking ) ;--------------------------------------------------------------------- Shield Break Chance If ( rTarget.IsShieldOut == 0 ) Return EndIf let iTargetShieldBreakChance := GetRandomPercent + 1 let fTargetShieldHealth := rTargetShield.GetCurrentHealth If ( fTargetShieldHealth <= 100 ) let fTargetShieldHealth /= 2 ; Not sure why this is done... ? ; Is this one below what you wanted? I commented it out in case not. ;rTargetShield.SetCurrentHealth fTargetShieldHealth EndIf If ( iAttackerWeaponType == 2 && iTargetShieldBreakChance <= 10 ) ; Blunt 1H Effect ;rTargetShield.UnequipMe ; Probably unnecessary? rTargetShield.RemoveMeIR ElseIf ( iAttackerWeaponType == 3 && fAttackerWeaponSpeed <= 0.65 && iTargetShieldBreakChance <= 20 ) ; Blunt 2H Effect ;rTargetShield.SetCurrentHealth 0 ; Probably unnecessary? ;rTargetShield.UnequipMe ; Probably unnecessary? rTargetShield.RemoveMeIR EndIf Return ;--------------------------------------------------------------------------------------- Else ;---------------------------------------------------------------------- Knockback chance on attack ;MessageEX "Weapon is %n", rAttackerWeapon If ( iAttackerWeaponType == 3 && fAttackerWeaponSpeed <= 0.65 ) let iKnockawayChance := GetRandomPercent + 1 If ( iKnockawayChance > 70 ) let iTargetAgility := rTarget.GetActorValue Agility let fKnockawayForce := ( 40 / ( 1 + iTargetAgility * ( -1 ) * 0.008 ) ) rAttacker.PushActorAway rTarget, fKnockawayForce EndIf EndIf ;----------------------------------------------------------------------- EndIf ;rTarget.PlayMagicShaderVisuals effectFireDamage 1 ;rAttacker.PlayMagicShaderVisuals effectFrostDamage 1 End Something like that? It is guaranteed to be 100% untested. But the idea should be clear. Also, from what I have read, Oblivion processes (or at least reads) also every line inside If statements. So making them short is usually recommended. At least the overly long ones. I put all the conditions on the same line because of that. Might not be necessary, but at least it makes the code easier to read and a bit shorter. Or at least in my opinion. :) Edit: Maskar also beat me to it. I really need to learn to type faster. :( Edit 2: Also, I do not know if there are other commands to get inventory references. ForEach two times in a row... looks odd now. But maybe it is fine. I have no idea what its performance impact is compared to possible other functions to get a reference. But maybe it is not too much? Edited July 26, 2015 by PhilippePetain Link to comment Share on other sites More sharing options...
NameNotPresent Posted July 28, 2015 Author Share Posted July 28, 2015 That is a big help thank you. let fTargetShieldHealth /= 2 ; Not sure why this is done... ? That is done to double the break chance. I have not been using the "&&" for the if statement because the wiki advised against it and I read on the nexus that Oblivion will check both connditions even if it has found one to be false. I should add that return at the begining too. Link to comment Share on other sites More sharing options...
Surilindur Posted July 28, 2015 Share Posted July 28, 2015 All right. You are welcome. But if you want to double the break chance, should you divide the break chance instead, to 'double' it, if the chance to break is greater the smaller the breaking chance variable is? In my example, that would then be let iTargetShieldBreakChance /= 2 instead of the current one with shield health. As it would seem that you are currently dividing the health by two, instead of the break chance variable. Not just in my example, but also in your original script, there is this: if shieldHealth <= 100 set shieldHealth to shieldHealth / 2 endifWhen it should probably be this ( to use the "/=" from OBSE to make it easier): if shieldHealth <= 100 let shieldBreakChance /= 2 endifMaybe? I am not sure. You are welcome. :) Link to comment Share on other sites More sharing options...
Recommended Posts