| 09-21-2008, 01:55 PM | #1 |
One of my spells I've ported into XE (and the nice methods of scoping / library): JASS:library BoostMoral initializer init requires xecast //************************************************************************* //* Boost Moral - Forsaken //* --------- //* Temporarily boosts spirit (gold) and moral (mana) for a targeted friendly //* unit, then removes those bonuses and checks for death (gold or mana < 0) //************************************************************************* globals private constant integer SPELL_ID = 'A00C' // rawcode for spell private unit u // target unit private player p // owner of u private real new // amount of mana/spirit to add on and for how long // the boost lasts (level of Boost Moral * 20) endglobals private function spellIdMatch takes nothing returns boolean return (GetSpellAbilityId()==SPELL_ID) endfunction private function onSpellEnd takes nothing returns nothing local timer t = GetExpiredTimer() // make changes to gold and unit's mana call SetUnitState(u, UNIT_STATE_MANA, GetUnitState( u, UNIT_STATE_MANA ) - new) call SetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD, R2I( GetPlayerState( p, PLAYER_STATE_RESOURCE_GOLD ) - new)) // check if death should ensue if(GetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD ) <= 0) then call KillUnit(u) endif if ( GetUnitState(u, UNIT_STATE_MANA ) <=0) then call KillUnit(u) endif call DestroyTimer(t) //cleanup set t = null endfunction private function onSpellEffect takes nothing returns nothing local timer t = CreateTimer() call SetUnitState( u, UNIT_STATE_MANA, GetUnitState( u, UNIT_STATE_MANA ) + new ) call SetPlayerState( p, PLAYER_STATE_RESOURCE_GOLD, R2I( GetPlayerState( p, PLAYER_STATE_RESOURCE_GOLD ) + new) ) // begin timer to remove boosts accurately call TimerStart( t, new, false, function onSpellEnd) endfunction private function init takes nothing returns nothing local trigger t = CreateTrigger() set u = GetSpellTargetUnit() set p = GetOwningPlayer(u) set new = I2R( 20 * GetUnitAbilityLevel( GetSpellAbilityUnit(), SPELL_ID ) ) call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT) call TriggerAddCondition(t, Condition(function spellIdMatch)) call TriggerAddAction(t, function onSpellEffect) set t=null endfunction endlibrary The more I think about it, the less I'm sure this spell is MUI. Are a local copy of the globals created upon each triggering of this spell (EVENT_PLAYER_UNIT_SPELL_EFFECT matching conditions of spellIdMatch) ? Or are 1 copy of the globals created at some point when the game starts or the first time the library is used? |
| 09-21-2008, 01:59 PM | #2 |
They are globals, they aren't local. Private only changes their name on compile to something like: <libraryname>___<variablename> To store that data, make it in the actions, and store it to a struct attached to the timer. |
| 09-21-2008, 04:06 PM | #3 |
nooo I wanted to circumvent attaching to stuff and stuff... |
| 09-21-2008, 04:09 PM | #4 | |
Quote:
For the record, I believe it is more like <libraryname><randomnumber>___<variablename> Attaching is a fine thing. TimerUtils is pretty awesome for this. A stack could work as well, though, if you set it up correctly. Be a damn waste, but it could work. |
| 09-21-2008, 04:12 PM | #5 | |
Quote:
|
| 09-21-2008, 04:33 PM | #6 |
I know i know...but wouldn't that be great? To have variables global to a particular instance of a spell? It would eliminate the need to attach stuff in pretty much every spell anyone would ever write. |
| 09-21-2008, 04:37 PM | #7 | ||
Quote:
JASS:scope someScope private function test takes nothing returns nothing endfunction endscope //... call someScope___test() I'd imagine the random number idea was scrapped since it's pointless (I recall it used to be there); if people really want to break a system by calling private functions, they can just remove the 'private' keyword. They're more for having functions unique to the scope for compiling purposes, such as ease of copying standard triggers (private function Actions ... and the like) in my experience. Quote:
The thing that fits that description as best you can is... attaching, via gamecache, arrays, or otherwise! (:P) |
| 09-21-2008, 04:43 PM | #8 |
Alright well not globals of an instance of a spell, but a variable INSIDE a particular scope declared as a local that's created everytime the spell is initialized: JASS:scope somescope local unit u local player p private function rar takes nothing returns nothing set u = getTriggeringUnit() endfunction endscope If that worked for EVERY instance of a spell... |
| 09-21-2008, 06:08 PM | #9 |
what you want are structs. JASS:scope somescope struct SpellData unit u player p endstruct private function rar takes nothing returns nothing local SpellData sd = SpellData.create() set sd.u= GetTriggeringUnit() endfunction endscope But DO NOT forget to clean up your struct calling the .destroy() method! Read more about structs in the vJass manual, if I remember correctly the links are still in your last thread. |
| 09-21-2008, 06:12 PM | #10 |
Can't you define an onDestroy method of the struct that is called automatically? Furthermore, for a local struct instance, do you need to set it to null (Such as in your example, setting sd = null) Edit: Structs are ints, they don't leak, nevermind. The 'onDestroy' question is still active though, anyone? |
| 09-21-2008, 06:31 PM | #11 |
well, the onDestroy() method is called whenever you call destroy() on an object. but you still have to call the .destroy() method yourself. |
