| 01-11-2009, 09:58 PM | #1 |
Yes yes, a great title. Now, onto the problem. I am making an accuracy script - simply damaging a small area based on range rather than using an actual missile. While everything works fine on it - the conditions don't. In order for the script to work, it has to have a correct weapon. However, if the unit has 2 weapons the script should not work. The problem is - the script does activate even if the unit has 2+ weapons. So.. -Unit has no weapon on him (Script works normal) -Unit has single weapon on him (Script works normal) -Unit has 2 different weapons (Script does not work right, activating both weapon scripts) And onto the goody script part. This is obviously the condition. It does 2 things. First, it checks if the script has the correct weapon buff (b) Than, it checks (CompareBuff) if the unit has other weapon buffs on him. JASS:private function conditions takes nothing returns boolean local boolean b = GetUnitAbilityLevel( GetAttacker(), BUFF_ID ) > 0 local boolean c = CompareBuff ( BUFF_ID, GetAttacker() ) if b == true then if c == true then return true endif endif return false endfunction This is the comparebuff script. See the next script for WBA. This one does a loop - checking if the current WBA is equal to the weapon buff. If the unit has the WBA buff AND the wba buff is not equal to the weapon buff, than it should return false (thus not letting the weapon script work) JASS:function CompareBuff takes integer CB, unit UA returns boolean set in = 1 //integer for counting loop loop exitwhen in == 3 if (GetUnitAbilityLevel(UA, WBA[in]) > 0) then if WBA[in] != CB then return false endif endif set in = in + 1 endloop return true endfunction Finally, setting the WBA array. Weapon Buff Array simply holds all the buffs. JASS:globals private trigger t = CreateTrigger() integer array WBA endglobals private function actions takes nothing returns nothing set WBA[1] = 'b000' set WBA[2] = 'B001' set WBA[3] = 'B002' endfunction And here is the complete accuracy script. JASS:scope AccGun initializer init globals private constant integer BUFF_ID = 'B001' private constant string EFFECT = "war3mapImported\\part_GunShot01.mdx" private constant string fss = "war3mapImported\\GunShot11.wav" private constant string fsse = "war3mapImported\\Echo06.wav" private constant integer l = 100 private trigger t = CreateTrigger() private real deviation = 75.0 private sound array fs private sound array fse private sound array fsw private integer fsi = 0 private integer in = 0 endglobals // CB = Units orignal buff // UA = Unit which has the buff function CompareBuff takes integer CB, unit UA returns boolean set in = 1 //integer for counting loop loop exitwhen in == 3 if (GetUnitAbilityLevel(UA, WBA[in]) > 0) then if WBA[in] != CB then return false endif endif set in = in + 1 endloop return true endfunction private function conditions takes nothing returns boolean local boolean b = GetUnitAbilityLevel( GetAttacker(), BUFF_ID ) > 0 local boolean c = CompareBuff ( BUFF_ID, GetAttacker() ) if b == true then if c == true then return true endif endif return false endfunction function DistanceBetweenCoords takes real x1, real y1, real x2, real y2 returns real return SquareRoot( ( x1-x2 ) * ( x1-x2 ) + ( y1-y2 ) * ( y1-y2 ) ) endfunction function PolarProjectionX takes real x, real dist, real angle returns real return x + dist * Cos( angle * bj_DEGTORAD ) endfunction function PolarProjectionY takes real y, real dist, real angle returns real return y + dist * Sin( angle * bj_DEGTORAD ) endfunction private function actions takes nothing returns nothing local unit ua = GetTriggerUnit() // Attacked Unit local unit ub = GetAttacker() // Attacking Unit local real xa = GetUnitX( ua ) local real ya = GetUnitY( ua ) local real xb = GetUnitX( ub ) local real yb = GetUnitY( ub ) local real di = DistanceBetweenCoords( xa, ya, xb, yb ) local real md = di / deviation local real od = GetRandomReal( 0, md ) local real lx = PolarProjectionX( xa, od, GetRandomReal( 0, 180 ) ) local real ly = PolarProjectionX( ya, od, GetRandomReal( 0, 180 ) ) /////////////////////////////////////////////////////////////////// // SOUND STUFF // set fsi = fsi + 1 set in = GetRandomInt (0, 5 ) if in == 0 then set in = GetRandomInt (1, 5) set fsw[fsi] = CreateSound ( "war3mapImported\\whine0" + (I2S(in) + ".wav" ), false, true, false, 80000, 80000, "") call SetSoundPosition (fsw[fsi], lx, ly, 0) call SetSoundDistances (fse[fsi], 1000, 3000) call SetSoundDistanceCutoff (fsw[fsi], 2000) call SetSoundVolume (fsw[fsi], 125) call StartSound (fsw[fsi]) call KillSoundWhenDone (fsw[fsi]) endif set fse[fsi] = CreateSound (fsse, false, true, false, 800000, 800000, "") set fs[fsi] = CreateSound (fss, false, true, false, 800000, 800000, "DefaultEAXON") call SetSoundPosition (fs[fsi], xb, yb, 1000) call SetSoundPosition (fse[fsi], xb, yb, 1000) //call AttachSoundToUnit (fs[fsi],ub) //call AttachSoundToUnit (fse[fsi], ub) call SetSoundDistances (fs[fsi], 100, 500000) call SetSoundDistances (fse[fsi], 100, 500000) call SetSoundDistanceCutoff (fs[fsi], 15000) call SetSoundDistanceCutoff (fse[fsi], 15000) call SetSoundVolume (fs[fsi], 125) call SetSoundVolume (fse[fsi], 125) call StartSound( fs[fsi]) call StartSound( fse[fsi]) call KillSoundWhenDone( fs[fsi]) call KillSoundWhenDone( fse[fsi]) if fsi == l then set fsi = 0 endif // // /////////////////////////////////////////////////////////////// call DisableTrigger( t ) call UnitDamagePoint( ub, 0.05, 15, lx, ly, 150, true, false, ATTACK_TYPE_MELEE, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS ) call EnableTrigger( t ) call DestroyEffect( AddSpecialEffect( EFFECT, lx, ly ) ) set ua = null set ub = null endfunction private function init takes nothing returns nothing call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_ATTACKED ) call TriggerAddCondition( t, Condition( function conditions ) ) call TriggerAddAction( t, function actions ) endfunction endscope If I let anything out , please tell me. I've been straining my eyes over this for days and still can't get it to work correctly! |
| 01-12-2009, 11:05 AM | #2 |
If unitA is attacked by unitB and if unitB has buffA, then run trigger actions; am I correct? If so, rewrite your condition as such. New Condition:private function conditions takes nothing returns boolean return GetUnitAbilityLevel( GetAttacker(), BUFF_ID ) > 0 endfunction EDIT: I'm pretty sure I misunderstood what you're attempting to express. Please clarify after reading this. Revisions:globals // Your globals are here somewhere... // Here are some things that might be useful. You can also place limits on arrays // using certain vJASS syntax or something. private integer array WBA private constant integer WBA_LIMIT = 2 endglobals //Right after your first globals block is a good place for a configurable function. private function Config takes nothing returns nothing set WBA[0] = 'B000' // I assume you intended that 'b000' to be capitalized? set WBA[1] = 'B001' set WBA[2] = 'B002' // Please keep WBA_LIMIT in mind. endfunction // You shouldn't even need CompareBuff(). At all. private function conditions takes nothing returns boolean local integer i = 0 loop if GetUnitAbilityLevel( GetAttacker(), WBA[i] ) > 0 then return true endif exitwhen i == WBA_LIMIT set i = i + 1 endloop return false endfunction // // Your trigger action and utility functions are here somewhere... // private function init takes nothing returns nothing // Configure your array variables during initialization and not during trigger actions // if you intend for them to be used like constants. call Config() call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_ATTACKED ) call TriggerAddCondition( t, Condition( function conditions ) ) call TriggerAddAction( t, function actions ) endfunction |
| 01-12-2009, 03:24 PM | #3 |
The conditions is meant to prevent the unit from attacking if it has 2 or more weapon buffs. Your method simply checks if it has the buff of the current loop (meaning a unit could have an assault rifle + shotgun and they would both fire. I need it so neither fires if they have both) In the object editor, buffs are B000, B001, ect. They are capitalized in my world editor in raw view. I made comparebuff a function since I plan on using it multiple scripts for varying purposes. |
| 01-12-2009, 04:50 PM | #4 |
Is the buff added by an active or a passive ability or by trigger? If it is an ability, is it on an item? If it is on an item, could you instead check to see if the unit has the item? If it is either a buff from a passive ability or an item, could you use a priority system? If it is a buff from an active ability, could you swap the buffs as though the unit draws a different weapon? I suppose what I'm getting at here is that I have trouble imagining why you would want to disable the use of weapons if the unit has multiple weapons (like the unit is unable to decide which to use?) and why multiple weapon buffs would co-exist in the first place when it would be an easy task to remove/add the buffs as needed. For instance: Click the "Shotgun" item, item activates "Equip (Shotgun)" ability, a trigger detects the use of the "Equip (Shotgun)" ability and then removes other equipped-item buffs and adds the "Equipped Shotgun" buff. Your trigger detects which equipped-item buff the unit has and behaves accordingly. Additionally, your trigger doesn't appear multi-instancable. Why do you disable the trigger before applying damage and re-enable it after? I assume to avoid setting off the trigger again from the damage. But if that were a problem, you could set UnitDamagePoint's booleanattack argument to false. |
| 01-13-2009, 07:10 PM | #5 |
Windex, UnitDamagePoint desyncs macs |
