| 01-28-2009, 10:14 PM | #1 | ||
Spell Code://***************************************************************** //* spell template - LimitedSummon //* //* written by: Anitarf //* requires: -Table //* -LinkedList //* //* -a unit summoning ability //* -a unit summoned by the above ability //* //* description: Limits the number of summoned units of one type //* that a single caster may summon. If the caster //* summons more than that many the oldest summoned //* unit belonging to that caster is removed. //* //* technical: The spell may malfunction if the summoned units //* can be removed by triggers before they die. To //* avoid this, always kill your units before removing //* them, not just because of this spell but because //* removing units in general is a lame thing to do. //* //***************************************************************** scope LimitedSummon initializer Init globals private constant integer SUMMON_UNIT_ID = 'h000' //the type of the summoned unit private constant integer SUMMON_ABILITY_ID = 'A000' //the ability used to summon the unit //the special effect to be used when an old summoned unit is killed to make room for the new: private constant string KILL_EFFECT_PATH = "Abilities\\Spells\\Other\\Charm\\CharmTarget.mdl" private constant string KILL_EFFECT_POINT = "origin" endglobals private function SummonLimit takes unit u returns integer //this determines how many units of the chosen type a caster can control return 2*GetUnitAbilityLevel(u, SUMMON_ABILITY_ID) endfunction // END OF CALIBRATION SECTION // ================================================================ globals private HandleTable gc endglobals private struct summoner unit u List l static method create takes unit u returns summoner local summoner s = summoner.allocate() set gc[u] = integer(s) set s.l = List.create() set s.u = u return s endmethod static method get takes unit u returns summoner local summoner s = summoner(gc[u]) if s==0 then return summoner.create(u) endif return s endmethod method onDestroy takes nothing returns nothing call gc.flush(.u) call .l.destroy() endmethod endstruct // ================================================================ private struct summoned unit u Link l summoner parent static method get takes unit u returns summoned return summoned(gc[u]) endmethod static method create takes unit u, unit summoning returns summoned local summoned s = summoned.allocate() local summoner sum = summoner.get(summoning) local unit k set s.u = u set s.parent = sum set s.l = Link.create(sum.l, integer(s)) set gc[u] = integer(s) loop if s.parent.l.size > SummonLimit(s.parent.u) then set k = summoned(s.parent.l.last.data).u call DestroyEffect(AddSpecialEffectTarget(KILL_EFFECT_PATH, k, KILL_EFFECT_POINT)) call KillUnit(k) set k = null else exitwhen true endif endloop return s endmethod method onDestroy takes nothing returns nothing call gc.flush(.u) call .l.destroy() if .parent.l.size==0 then call .parent.destroy() endif endmethod endstruct // ================================================================ private function Summoning takes nothing returns boolean if GetUnitTypeId(GetSummonedUnit())==SUMMON_UNIT_ID then call summoned.create(GetSummonedUnit(), GetSummoningUnit()) endif return false endfunction private function SummonDeath takes nothing returns boolean local summoned s if GetUnitTypeId(GetTriggerUnit())==SUMMON_UNIT_ID then set s = summoned.get(GetTriggerUnit()) if s != 0 then call s.destroy() endif endif return false endfunction // ================================================================ private function Init takes nothing returns nothing local trigger t = CreateTrigger() call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SUMMON) call TriggerAddCondition(t, Condition(function Summoning)) set t = CreateTrigger() call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_DEATH) call TriggerAddCondition(t, Condition(function SummonDeath)) set gc = HandleTable.create() endfunction endscope |
| 01-28-2009, 10:54 PM | #2 |
I don't actually like the implementation at all, really. In order to implement, you copy and paste this as many times as you have summoning skills you need to limit. That isn't even considering that there may be more code associated with the nature of the summon to begin with. I think being able to register a spell raw id to the system that is then monitored would be substantially more useful and more modular. call RegisterSummonedUnitLimit(SUMMON_ID, SUMMON_SPELL_ID, KillEffect, KillEffectPath, SummonLimit). The only disadvantage to this that I can see is the inability to have the SummonLimit depend upon skill level. I think function interfaces might be able to solve that issue, though, if I got anything out of Vex's tutorial. :) If you keep it like this, though, I think the only section of the resource database it would make sense is "Samples." |
| 01-28-2009, 11:26 PM | #3 | ||
Quote:
Quote:
|
| 01-29-2009, 12:54 PM | #4 |
Doesn't mean I have to like it or find it useful in this form. :p |
| 01-29-2009, 02:13 PM | #5 | |
Quote:
Sure it could get into an actual system or stuff. But does it really have to? Those structs must be private though. |
| 01-29-2009, 02:52 PM | #6 | |||
Quote:
Quote:
Quote:
|
| 01-29-2009, 06:49 PM | #7 | |
Quote:
Anyways, Vex didn't say anything else exciting, and it looks okay to me, so I am going to approve it as a sample. |
| 01-30-2009, 01:39 AM | #8 |
BTW if I implement such system, would it be approved? I just thought I could write a library in a way that would satisfy Dusk. |
| 01-30-2009, 03:36 AM | #9 |
I don't know, you'd basically just be copying his code with some wrapper overhead. It'd be kind of silly. Besides, I do see the use of having level-dependent summon counts. That's something you couldn't easily implement as a system. (Without some dumb struct based adjusting stuff) |
| 01-30-2009, 10:23 AM | #10 |
I haven't actually seen the uh... codes, but if this is what I think it is, I was really looking for a similar system (the one I finally made myself was a bit complicated and in GUI but it allowed for a level up in which more of the type of unit can be summoned at higher levels). Would be great if someone made a simpler and better system for it. |
| 01-30-2009, 11:51 AM | #11 |
The discourses in submission threads are particularly amusing. The people work/talk on the script together. |
| 01-31-2009, 11:08 AM | #12 | ||
Quote:
That might be true, as it would have some overhead for array lookup instead of constants. But I think this can be done with arrays and groups with functions, instead of structs; for this reason, I have little idea about performance difference. Quote:
Still, I myself doubt writing a new one for this purpose would worth the efforts. |
| 08-04-2009, 10:09 PM | #13 |
The map has been updated to work with Warcraft patch 1.24 (a simple matter of updating Table to 3.0, the spell code wasn't changed). |
