| 06-30-2009, 10:34 AM | #1 |
Stated above. JASS:scope Overseermight initializer Init globals private constant integer DMGAURA = 'A00F' private constant integer SPELLBOOK = 'A00V' private constant integer SPELL = 'A00U' private constant string EFFECT = "Abilities\\Spells\\Items\\AIco\\CrownOfCmndTarget.mdl" private constant string BLINK = "Abilities\\Spells\\NightElf\\Blink\\BlinkTarget.mdl" endglobals private struct data implement AutoData static group Done = CreateGroup() unit target integer instances integer agi integer atkspeed integer life static method create takes unit target returns data local data d = data.allocate() set d.instances = 0 set d.agi = 0 set d.atkspeed = 0 set d.life = 0 set data[target] = d return d endmethod endstruct private function LConditions takes nothing returns boolean return GetLearnedSkill() == SPELL endfunction private function LActions takes nothing returns nothing local unit u = GetTriggerUnit() local integer i = GetUnitAbilityLevel(u,SPELL) if GetLearnedSkill() > 0 then call UnitAddAbility(u,SPELLBOOK) endif call SetUnitAbilityLevel(u,DMGAURA,i) set u = null endfunction private function Conditions takes nothing returns boolean return GetSpellAbilityId() == SPELL endfunction private function Actions takes nothing returns nothing local unit u = GetTriggerUnit() local data d = data[u] local unit t = GetSpellTargetUnit() local real x = GetUnitX(u) local real y = GetUnitY(u) local real tx = GetUnitX(t) local real ty = GetUnitY(t) if d == 0 then set d = data.create(u) endif call SetUnitX(t,x) call SetUnitY(t,y) call DestroyEffect(AddSpecialEffect(BLINK,x,y)) call SetUnitX(u,tx) call SetUnitY(u,ty) call DestroyEffect(AddSpecialEffect(BLINK,tx,ty)) call AddTimedEffectTarget(EFFECT,u,"overhead",5) set d.agi = DelayedAgi(u,15,5) // d.agi is the struct instance of the agi struct and same goes for the rest set d.life = DelayedMaxLife(u,200,5) set d.atkspeed = DelayedAttackSpeed(u,40,5) set d.instances = d.instances + 1 // what am I doing with this and not using a boolean? Well I don't know, i am currently thinking of how to make it stackable set u = null set t = null endfunction private function ConditionDeath takes nothing returns boolean local unit u = GetKillingUnit() local unit a = GetTriggerUnit() local integer i = GetUnitAbilityLevel(u,SPELL) local data d = data[u] if IsUnitEnemy(a,GetOwningPlayer(u)) and i > 0 and d.instances > 0 then call BJDebugMsg("Adding") call AddAgiDuration(d.agi,1) // increase duration of the instance by 1 call AddMaxLifeDuration(d.life,1) // same thing.. call AddAttackSpeedDuration(d.atkspeed,1) // auto data overwrites the existing struct so it isn't multiple unit instances for a specific unit 2 times and more endif set u = null set a = null return false endfunction //=========================================================================== private function Init takes nothing returns nothing local trigger t = CreateTrigger() local integer i = 0 loop exitwhen i > 12 call SetPlayerAbilityAvailable(Player(i),SPELLBOOK,false) set i = i + 1 endloop call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_HERO_SKILL) call TriggerAddAction(t, function LActions ) call TriggerAddCondition(t,Condition(function LConditions)) set t = CreateTrigger() call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT) call TriggerAddAction(t, function Actions) call TriggerAddCondition(t,Condition(function Conditions)) set t = CreateTrigger() call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_DEATH) call TriggerAddCondition(t,Condition(function ConditionDeath)) endfunction endscope I wrote the problems in the comments but to sum it up. Right now it's not stackable and how do I make it so? Making huge arrays in the struct make less instances possible. EDIT: Would using table for a struct instance work well or is there any other good alternatives? EDIT2: JASS:scope Overseermight initializer Init globals private constant integer DMGAURA = 'A00F' private constant integer SPELLBOOK = 'A00V' private constant integer SPELL = 'A00U' private constant string EFFECT = "Abilities\\Spells\\Items\\AIco\\CrownOfCmndTarget.mdl" private constant string BLINK = "Abilities\\Spells\\NightElf\\Blink\\BlinkTarget.mdl" endglobals private struct data implement AutoData static group Done = CreateGroup() Table Agi Table AttackSpeed Table MaxLife unit target integer Count = 0 static method create takes unit target returns data local data d = data.allocate() set d.target = target set d.Agi = Table.create() set d.MaxLife = Table.create() set d.AttackSpeed = Table.create() set data[target] = d return d endmethod endstruct private function LConditions takes nothing returns boolean return GetLearnedSkill() == SPELL endfunction private function LActions takes nothing returns nothing local unit u = GetTriggerUnit() local integer i = GetUnitAbilityLevel(u,SPELL) if GetLearnedSkill() > 0 then call UnitAddAbility(u,SPELLBOOK) endif call SetUnitAbilityLevel(u,DMGAURA,i) set u = null endfunction private function Conditions takes nothing returns boolean return GetSpellAbilityId() == SPELL endfunction private function Actions takes nothing returns nothing local unit u = GetTriggerUnit() local data d = data[u] local unit t = GetSpellTargetUnit() local real x = GetUnitX(u) local real y = GetUnitY(u) local real tx = GetUnitX(t) local real ty = GetUnitY(t) if d == 0 then set d = data.create(u) endif call SetUnitX(t,x) call SetUnitY(t,y) call DestroyEffect(AddSpecialEffect(BLINK,x,y)) call SetUnitX(u,tx) call SetUnitY(u,ty) call DestroyEffect(AddSpecialEffect(BLINK,tx,ty)) call AddTimedEffectTarget(EFFECT,u,"overhead",5) set d.Agi[d.Count] = DelayedAgi(u,15,5) set d.MaxLife[d.Count] = DelayedMaxLife(u,200,5) set d.AttackSpeed[d.Count] = DelayedAttackSpeed(u,40,5) set d.Count = d.Count + 1 set u = null set t = null endfunction private function ConditionDeath takes nothing returns boolean local unit u = GetKillingUnit() local unit a = GetTriggerUnit() local integer i = GetUnitAbilityLevel(u,SPELL) local integer j = 0 local data d = data[u] if IsUnitEnemy(a,GetOwningPlayer(u)) and i > 0 and d.instances > 0 then loop exitwhen j >= d.Count call AddAgiDuration(d.agi,1) call AddMaxLifeDuration(d.life,1) call AddAttackSpeedDuration(d.atkspeed,1) set j = j + 1 endloop endif set u = null set a = null return false endfunction //=========================================================================== private function Init takes nothing returns nothing local trigger t = CreateTrigger() local integer i = 0 loop exitwhen i > 12 call SetPlayerAbilityAvailable(Player(i),SPELLBOOK,false) set i = i + 1 endloop call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_HERO_SKILL) call TriggerAddAction(t, function LActions ) call TriggerAddCondition(t,Condition(function LConditions)) set t = CreateTrigger() call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT) call TriggerAddAction(t, function Actions) call TriggerAddCondition(t,Condition(function Conditions)) set t = CreateTrigger() call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_DEATH) call TriggerAddCondition(t,Condition(function ConditionDeath)) endfunction endscope Tried a Table verison but I got confused and it wouldn't work, when would I set d.Count to d.Count - 1, I don't want to modify the UP Delayed Script. |
| 06-30-2009, 01:08 PM | #2 |
what are "stackable instances for a unit"? I don't get what your system does. and please give some explanation about the internal working of your system. also, maybe you have some ideas where in your script the bug may be located, so that we have a starting point for our search. |
| 06-30-2009, 01:24 PM | #3 |
JASS:library DelayedUPRemoval requires TimerUtils, OperatorWrappers //! textmacro UP takes name function interface Face$name$ takes D$name$ d returns nothing struct D$name$ unit target timer t real value Face$name$ face static method Remove takes nothing returns nothing local D$name$ this = GetTimerData(GetExpiredTimer()) call UnitModify$name$(.target,-.value) call .face.execute(this) call .destroy() endmethod static method create takes unit u, real r, real time returns D$name$ local D$name$ this = D$name$.allocate() set .target = u set .t = NewTimer() set .value = r set .face = 0 call SetTimerData(.t,this) call UnitModify$name$(.target,.value) call TimerStart(.t,time,false,function D$name$.Remove) return this endmethod method onDestroy takes nothing returns nothing call ReleaseTimer(.t) endmethod endstruct function Delayed$name$ takes unit u, real r, real time returns integer local D$name$ d = D$name$.create(u,r,time) return d endfunction function Add$name$Duration takes D$name$ d, real dur returns nothing local real remaining = TimerGetRemaining(d.t) call ReleaseTimer(d.t) set d.t = NewTimer() call SetTimerData(d.t,d) call TimerStart(d.t,dur+remaining,false,function D$name$.Remove) endfunction function Delayed$name$Code takes D$name$ c, Face$name$ d returns nothing set c.face = d endfunction //! endtextmacro //! runtextmacro UP("Agi") //! runtextmacro UP("Int") //! runtextmacro UP("Str") //! runtextmacro UP("LifeRegen") //! runtextmacro UP("ManaRegen") //! runtextmacro UP("ManaRegenPercent") //! runtextmacro UP("Armor") //! runtextmacro UP("Damage") //! runtextmacro UP("AttackSpeed") //! runtextmacro UP("MoveSpeed") //! runtextmacro UP("AttackEvasion") //! runtextmacro UP("AttackMiss") //! runtextmacro UP("MaxLife") //! runtextmacro UP("MaxMana") endlibrary You can ignore the effects call, it has nothing to do with the problem. I wrote comments on the code but let me say it here so it's easire to view, AutoData overwrites the existing struct on a unit meaning that it cannot be multiple instances available a unit so my method would fail if 2 instances on a unit was running. EDIT: Now I fixed the coding and tell me if the code is good or not JASS:scope Overseermight initializer Init globals private constant integer DMGAURA = 'A00F' private constant integer SPELLBOOK = 'A00V' private constant integer SPELL = 'A00U' private constant string EFFECT = "Abilities\\Spells\\Items\\AIco\\CrownOfCmndTarget.mdl" private constant string BLINK = "Abilities\\Spells\\NightElf\\Blink\\BlinkTarget.mdl" endglobals private struct data implement AutoData static group Done = CreateGroup() Table Agi Table AttackSpeed Table MaxLife unit target integer Count = 0 static method create takes unit target returns data local data d = data.allocate() set d.target = target set d.Agi = Table.create() set d.MaxLife = Table.create() set d.AttackSpeed = Table.create() set data[target] = d return d endmethod endstruct private function LConditions takes nothing returns boolean return GetLearnedSkill() == SPELL endfunction private function LActions takes nothing returns nothing local unit u = GetTriggerUnit() local integer i = GetUnitAbilityLevel(u,SPELL) if GetLearnedSkill() > 0 then call UnitAddAbility(u,SPELLBOOK) endif call SetUnitAbilityLevel(u,DMGAURA,i) set u = null endfunction private function RemovalAttackSpeed takes unit target returns nothing local data c = data[target] call BJDebugMsg(I2S(c.Count)) set c.Count = c.Count - 1 call BJDebugMsg(I2S(c.Count)) endfunction private function Conditions takes nothing returns boolean return GetSpellAbilityId() == SPELL endfunction private function Actions takes nothing returns nothing local unit u = GetTriggerUnit() local data d = data[u] local unit t = GetSpellTargetUnit() local real x = GetUnitX(u) local real y = GetUnitY(u) local real tx = GetUnitX(t) local real ty = GetUnitY(t) if d == 0 then set d = data.create(u) endif call SetUnitX(t,x) call SetUnitY(t,y) call DestroyEffect(AddSpecialEffect(BLINK,x,y)) call SetUnitX(u,tx) call SetUnitY(u,ty) call DestroyEffect(AddSpecialEffect(BLINK,tx,ty)) call AddTimedEffectTarget(EFFECT,u,"overhead",5) set d.Agi[d.Count] = DelayedAgi(u,15,5) // call DelayedAgiCode(d.Agi[d.Count],RemovalAgi) set d.MaxLife[d.Count] = DelayedMaxLife(u,200,5) // call DelayedMaxLifeCode(d.MaxLife[d.Count],RemovalMaxLife) set d.AttackSpeed[d.Count] = DelayedAttackSpeed(u,40,5) call DelayedAttackSpeedCode(d.AttackSpeed[d.Count],RemovalAttackSpeed) set d.Count = d.Count + 1 call GroupAddUnit(d.Done,u) set u = null set t = null endfunction private function ConditionDeath takes nothing returns boolean local unit u = GetKillingUnit() local unit a = GetTriggerUnit() local integer i = GetUnitAbilityLevel(u,SPELL) local integer j = 0 local data d = data[u] if IsUnitEnemy(a,GetOwningPlayer(u)) and i > 0 and IsUnitInGroup(u,d.Done) then loop exitwhen j >= d.Count call AddAgiDuration(d.Agi[j],1) call AddMaxLifeDuration(d.MaxLife[j],1) call AddAttackSpeedDuration(d.AttackSpeed[j],1) set j = j + 1 endloop endif set u = null set a = null return false endfunction //=========================================================================== private function Init takes nothing returns nothing local trigger t = CreateTrigger() local integer i = 0 loop exitwhen i > 12 call SetPlayerAbilityAvailable(Player(i),SPELLBOOK,false) set i = i + 1 endloop call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_HERO_SKILL) call TriggerAddAction(t, function LActions ) call TriggerAddCondition(t,Condition(function LConditions)) set t = CreateTrigger() call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT) call TriggerAddAction(t, function Actions) call TriggerAddCondition(t,Condition(function Conditions)) set t = CreateTrigger() call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_DEATH) call TriggerAddCondition(t,Condition(function ConditionDeath)) endfunction endscope |
| 06-30-2009, 04:04 PM | #4 |
I thin you need the UnitListModule. |
| 06-30-2009, 04:06 PM | #5 |
Which doesn't compile. |
| 06-30-2009, 07:14 PM | #6 |
Well, grim001 should fix it soon enough. |
| 06-30-2009, 10:17 PM | #7 |
It's updated. If you can't figure out how to make it work, post your best try here, and maybe you will get help. |
