| 11-17-2009, 02:59 PM | #1 |
hi! i'm trying to 'patch' wc3-tft by making a map-pack with some abilites/spells/units changes (mostly for personal use in lan parties). for example, i tried to make every channeling ultimate to last at least 5 seconds, interrupted or not, in a following way: 1. hero cast fake spell. timer starts 2. dummy casts real spell 3. spell is interrupted. a) if timer is expired (5 sec) nothing happens b) if timer is not expired, spell is continually casted by dummy till 5 sec this works well for all channeling spells, with two exceptions: 1. earthquake - despite code being identical to others, i've managed this one to either not work at all, exit to desktop or work for 5 seconds regardless of interruption 2. big bad voodoo - spell works correctly, except when interrupted during first 5 sec, shadow hunter gets under its influence for the remaining time (until 5 sec expires) i would greatly appreciate suggestions or any other help. btw, my coding probably sucks to great extent, i'm aware of it i've attached screenshot of defective earthquake trigger(s), as well as a test map thanks in advance! |
| 11-17-2009, 03:49 PM | #2 |
Could you also post one of the triggers that work for a side-by-side comparison? Also, you don't need to post screenshots, you can just select the "copy as text" option on the trigger and then paste it into your post using the [trigger] tags, like this: |
| 11-17-2009, 05:34 PM | #4 |
Well, I don't see what the problem could be but I see other issues: for example, if multiple heroes cast an ultimate at about the same time, the code will get messed up because of shared variables. You are better off using a vJass system for this, I can write something quickly for you if you want. |
| 11-17-2009, 07:27 PM | #5 |
yes, it would be most helpful, thank you! |
| 11-17-2009, 08:40 PM | #6 |
Here, completely untested, requires TimerUtils, Table and SpellEvent. JASS:scope SetupUltiChannel initializer Init private function Init takes nothing returns nothing // hero ability, caster ability, orderstring, min duration call NewUltiChannel('A000', 'A001', "starfall", 5.0) // repeat for each ultimate. endfunction endscope library UltiChannel initializer Init requires Table, TimerUtils, SpellEvent globals private constant integer CASTER_UNIT_ID = 'hfoo' endglobals private struct ultiData static Table spellTable static method get takes integer spellId returns ultiData return ultiData.spellTable[spellId] endmethod static method onInit takes nothing returns nothing set ultiData.spellTable=Table.create() endmethod integer heroSpellId integer casterSpellId string orderstring real minDuration static method create takes integer heroSpellId, integer casterSpellId, string spellOrderstring, real minSpellDuration returns ultiData local ultiData this=ultiData.allocate() set .heroSpellId=heroSpellId set .casterSpellId=casterSpellId set .minDuration=minSpellDuration set .orderstring=spellOrderstring set ultiData.spellTable[heroSpellId]=this return this endmethod endstruct private struct ultiSpell static HandleTable casterTable static method get takes unit caster returns ultiSpell return ultiSpell.casterTable[caster] endmethod static method onInit takes nothing returns nothing set ultiSpell.casterTable=HandleTable.create() endmethod private unit hero private unit caster private boolean stopped=false private boolean finished=false private static method expire takes nothing returns nothing local ultiSpell this=ultiSpell(GetTimerData(GetExpiredTimer())) call ReleaseTimer(GetExpiredTimer()) set .finished=true if .stopped then call .destroy() endif endmethod static method create takes unit u, ultiData d returns ultiSpell local ultiSpell this=ultiSpell.allocate() local timer t=NewTimer() set .hero=u set .caster=CreateUnit(GetOwningPlayer(u), CASTER_UNIT_ID, GetUnitX(u), GetUnitY(u),GetUnitFacing(u)) call UnitAddAbility(.caster, d.casterSpellId) call SetUnitAbilityLevel(.caster, d.casterSpellId, GetUnitAbilityLevel(u, d.heroSpellId)) if SpellEvent.TargetUnit!=null then call IssueTargetOrder(.caster, d.orderstring, SpellEvent.TargetUnit) elseif SpellEvent.TargetX!=0.0 or SpellEvent.TargetY!=0.0 then call IssuePointOrder(.caster, d.orderstring, SpellEvent.TargetX, SpellEvent.TargetY) else call IssueImmediateOrder(.caster, d.orderstring) endif call SetTimerData(t, integer(this)) call TimerStart(t, d.minDuration, false, function ultiSpell.expire) set ultiSpell.casterTable[u]=this return this endmethod method onDestroy takes nothing returns nothing call ultiSpell.casterTable.flush(.hero) call KillUnit(.caster) endmethod static method SpellStop takes nothing returns nothing local ultiSpell this=ultiSpell.get(SpellEvent.CastingUnit) if this!=0 then set .stopped=true if .finished then call .destroy() endif endif endmethod static method SpellCast takes nothing returns nothing local ultiData d=ultiData.get(SpellEvent.AbilityId) if d!=0 then call ultiSpell.create(SpellEvent.CastingUnit, d) endif endmethod endstruct function NewUltiChannel takes integer heroSpellId, integer casterSpellId, string spellOrderstring, real minSpellDuration returns nothing local ultiData d=ultiData.create(heroSpellId, casterSpellId, spellOrderstring, minSpellDuration) endfunction private function Init takes nothing returns nothing call RegisterSpellEffectResponse(0, ultiSpell.SpellCast) call RegisterSpellEndCastResponse(0, ultiSpell.SpellStop) endfunction endlibrary |
| 11-17-2009, 09:24 PM | #7 |
wow. thanks! it will probably take me some time to understand how this functions, but i believe it will be useful. thanks again |
