| 02-09-2007, 08:40 PM | #1 |
Hello, I've got this spell that removes a unit from the map and then (depending on the identity of the original unit) creates a summoned unit. I want the player to know that the summoned unit is temporary, so I add an expiration timer with an amount of time equal to (lifetime of summoned unit) + 0.1 seconds. There is a timer-controlled function that reaches in at (lifetime of summoned unit) and switches them back if the summoned unit is still alive. However, most of the time (but not all of the time) the summoned unit's expiration timer seems to expire and th uint then registers as "dead" when the timer-activated function goes looking for it. Is the unit expiration timer not precise? Thanks, Capt. Picard |
| 02-10-2007, 03:17 AM | #2 |
Code? |
| 02-10-2007, 05:50 AM | #3 |
JASS:function CreateNagaMyrmidon takes integer UnitID returns boolean if ( UnitID < 'h61M' ) then if ( UnitID == 'edoc' ) then return true elseif ( UnitID == 'edcm' ) then return true elseif ( UnitID == 'h00B' ) then return true elseif (UnitID == 'n603' ) then return true endif else if (UnitID == 'h61M' ) then return true elseif (UnitID == 'hhes' ) then return true elseif (UnitID == 'n65R' ) then return true elseif (UnitID == 'n65S' ) then return true endif endif return false endfunction function CreateNagaSnapDragon takes integer UnitID returns boolean if ( UnitID < 'n00E' ) then if ( UnitID == 'earc' ) then return true elseif ( UnitID == 'edry' ) then return true elseif ( UnitID == 'h61C' ) then return true endif else if ( UnitID == 'n00E' ) then return true elseif ( UnitID == 'n65F' ) then return true elseif ( UnitID == 'nhea' ) then return true endif endif return false endfunction function CreateNagaReaver takes integer UnitID returns boolean if ( UnitID == 'n00C' ) then return true elseif ( UnitID == 'n65D' ) then return true elseif ( UnitID == 'n00D' ) then return true endif return false endfunction function CreateNagaDragonTurtle takes integer UnitID returns boolean if ( UnitID == 'e601' ) then return true elseif ( UnitID == 'esen' ) then return true endif return false endfunction function CreateNagaRoyalGuard takes integer UnitID returns boolean if ( UnitID == 'h61B' ) then return true elseif ( UnitID == 'emtg' ) then return true elseif ( UnitID == 'h004' ) then return true endif return false endfunction function CreateNagaSiren takes integer UnitID returns boolean if ( UnitID == 'h005' ) then return true elseif ( UnitID == 'n602' ) then return true elseif ( UnitID == 'edot' ) then return true endif return false endfunction function SerpentranceSwapBack takes nothing returns nothing local real TargetLife local real TargetMana local real TargetFacing local string s local unit Serpent local unit Target local location TargetLoc local player TargetPlayer local player CasterPlayer set s = I2S( H2I( GetExpiredTimer() ) ) call DestroyTimer( GetExpiredTimer() ) set Serpent = I2U( GetStoredInteger(udg_AbilityCache, s, "Serpent") ) // Check: are we over deep water? set TargetLoc = GetUnitLoc( Serpent ) if ( IsTerrainPathableBJ(TargetLoc, PATHING_TYPE_WALKABILITY) ) then if ( IsTerrainPathableBJ(TargetLoc, PATHING_TYPE_FLOATABILITY) == false ) then call KillUnit( Serpent ) endif endif call RemoveLocation( TargetLoc ) // Swap back! if ( IsUnitAliveBJ( Serpent ) ) then // Information on the serpent set TargetLoc = GetUnitLoc( Serpent ) set TargetFacing = GetUnitFacing( Serpent ) set TargetLife = GetUnitLifePercent( Serpent ) if ( GetUnitStateSwap( UNIT_STATE_MAX_MANA, Serpent ) > 0.0 ) then set TargetMana = GetUnitManaPercent( Serpent ) else set TargetMana = GetStoredReal(udg_AbilityCache, s, "TargetMana") endif // Put the original unit back set CasterPlayer = GetOwningPlayer(Serpent) if (IsUnitSelected( Serpent, CasterPlayer ) ) then call SelectUnitRemoveForPlayer( Serpent, CasterPlayer ) endif call RemoveUnit( Serpent ) set TargetPlayer = Player(GetStoredInteger(udg_AbilityCache, s, "TargetPlayer")) call RestoreUnitLocFacingAngleBJ( "Target", s, udg_AbilityCache, TargetPlayer, TargetLoc, TargetFacing ) set Target = bj_lastLoadedUnit call ScaleMapUnits( Target ) call SetUnitLifePercentBJ( Target, TargetLife ) call SetUnitManaPercentBJ( Target, TargetMana ) call AddSpecialEffectTargetUnitBJ( "origin", Target, "Abilities\\Spells\\Other\\Charm\\CharmTarget.mdl" ) call DestroyEffectBJ( GetLastCreatedEffectBJ() ) call RemoveLocation( TargetLoc ) endif // Destroy the game cache data call FlushStoredMission(udg_AbilityCache, s) // Set non-elemental variables to null set Serpent = null set Target = null set TargetLoc = null set TargetPlayer = null set CasterPlayer = null endfunction function SerpentranceCasterStop takes nothing returns nothing local string s local integer SerpentLevel local unit Caster local timer t set t = GetExpiredTimer() set s = I2S( H2I( t ) ) set SerpentLevel = GetStoredInteger(udg_AbilityCache, s, "level") set Caster = I2U( GetStoredInteger(udg_AbilityCache, s, "Caster") ) call SetUnitAnimation( Caster, "stand" ) call TimerStart(t, I2R(5*SerpentLevel+9), false, function SerpentranceSwapBack) // Set non-elemental variables to null set Caster = null set t = null endfunction function Trig_Cast_Serpentrance_Conditions takes nothing returns boolean if ( GetSpellAbilityId() == 'A669' ) then return true endif return false endfunction function Trig_Cast_Serpentrance_Actions takes nothing returns nothing local integer TargetID local integer NewUnitID local integer SerpentLevel local real TargetLife local real TargetMana local real TargetFacing local real SerpentScale local unit Caster local unit Target local unit Serpent local player CasterPlayer local player TargetPlayer local group SelectGroup local location TargetLoc local timer t local string s // Get information about the target and caster set Caster = GetSpellAbilityUnit() set CasterPlayer = GetOwningPlayer( Caster ) set Target = GetSpellTargetUnit() set TargetID = GetUnitTypeId( Target ) set SerpentLevel = GetUnitAbilityLevelSwapped('A669', Caster ) // Decide which unit to make set NewUnitID = 0 set SerpentScale = 0.0 if ( CreateNagaMyrmidon( TargetID ) ) then if ( SerpentLevel == 1 ) then set NewUnitID = 'n65W' elseif ( SerpentLevel == 2 ) then set NewUnitID = 'n65X' elseif ( SerpentLevel == 3 ) then set NewUnitID = 'n65Y' elseif ( SerpentLevel == 4 ) then set NewUnitID = 'n65Z' endif set SerpentScale = 90.0 elseif ( CreateNagaSnapDragon( TargetID ) ) then if ( SerpentLevel == 1 ) then set NewUnitID = 'n660' elseif ( SerpentLevel == 2 ) then set NewUnitID = 'n661' elseif ( SerpentLevel == 3 ) then set NewUnitID = 'n662' elseif ( SerpentLevel == 4 ) then set NewUnitID = 'n663' endif set SerpentScale = 81.0 elseif ( CreateNagaDragonTurtle( TargetID ) ) then if ( SerpentLevel == 1 ) then set NewUnitID = 'n664' elseif ( SerpentLevel == 2 ) then set NewUnitID = 'n665' elseif ( SerpentLevel == 3 ) then set NewUnitID = 'n666' elseif ( SerpentLevel == 4 ) then set NewUnitID = 'n667' endif set SerpentScale = 72.0 elseif ( CreateNagaReaver( TargetID ) ) then if ( SerpentLevel == 1 ) then set NewUnitID = 'n669' elseif ( SerpentLevel == 2 ) then set NewUnitID = 'n66A' elseif ( SerpentLevel == 3 ) then set NewUnitID = 'n668' elseif ( SerpentLevel == 4 ) then set NewUnitID = 'n66B' endif set SerpentScale = 100.0 elseif ( CreateNagaRoyalGuard( TargetID ) ) then if ( SerpentLevel == 1 ) then set NewUnitID = 'n66D' elseif ( SerpentLevel == 2 ) then set NewUnitID = 'n66E' elseif ( SerpentLevel == 3 ) then set NewUnitID = 'n66C' elseif ( SerpentLevel == 4 ) then set NewUnitID = 'n66F' endif set SerpentScale = 115.0 elseif ( CreateNagaSiren( TargetID ) ) then if ( SerpentLevel == 1 ) then set NewUnitID = 'n66H' elseif ( SerpentLevel == 2 ) then set NewUnitID = 'n66I' elseif ( SerpentLevel == 3 ) then set NewUnitID = 'n66G' elseif ( SerpentLevel == 4 ) then set NewUnitID = 'n66J' endif set SerpentScale = 90.0 endif set SerpentScale = SerpentScale*(0.4+0.2*I2R(SerpentLevel) ) // Create the new unit if appropriate if ( NewUnitID > 0 ) then // More information on the target set TargetLoc = GetUnitLoc( Target ) set TargetFacing = GetUnitFacing( Target ) set TargetPlayer = GetOwningPlayer( Target ) set TargetLife = GetUnitLifePercent( Target ) if ( GetUnitStateSwap( UNIT_STATE_MAX_MANA, Target ) > 0.0 ) then set TargetMana = GetUnitManaPercent( Target ) else set TargetMana = 0.0 endif // Drop target unit items call UnitRemoveItemFromSlotSwapped( 1, Target ) call UnitRemoveItemFromSlotSwapped( 2, Target ) // Swap! set t = CreateTimer() set s = I2S(H2I(t)) call StoreUnit(udg_AbilityCache, s, "Target", Target) call RemoveUnit( Target ) call CreateNUnitsAtLoc( 1, NewUnitID, CasterPlayer, TargetLoc, TargetFacing ) set Serpent = GetLastCreatedUnit() call RemoveLocation( TargetLoc ) call SetUnitLifePercentBJ( Serpent, TargetLife ) call SetUnitManaPercentBJ( Serpent, TargetMana ) call UnitApplyTimedLifeBJ( I2R(5*SerpentLevel + 10) + 1.0, 'BFig', Serpent ) call UnitPauseTimedLifeBJ( false, Serpent ) call UnitAddTypeBJ( UNIT_TYPE_SUMMONED, Serpent ) call AddSpecialEffectTargetUnitBJ( "origin", Serpent, "Abilities\\Spells\\Other\\Charm\\CharmTarget.mdl" ) call DestroyEffectBJ( GetLastCreatedEffectBJ() ) // Add serpent to caster's selection set SelectGroup = GetUnitsSelectedAll(CasterPlayer) if ( CountUnitsInGroup(udg_ArcRain_Group) < 12 ) then call SelectUnitAddForPlayer( Serpent, CasterPlayer ) endif call DestroyGroup( SelectGroup ) // Wait call StoreInteger(udg_AbilityCache, s, "level", SerpentLevel) call StoreInteger(udg_AbilityCache, s, "Serpent", H2I(Serpent)) call StoreInteger(udg_AbilityCache, s, "Caster", H2I(Caster)) call StoreInteger(udg_AbilityCache, s, "TargetPlayer", GetConvertedPlayerId(TargetPlayer)-1) call StoreReal(udg_AbilityCache, s, "TargetMana", TargetMana) call TimerStart(t, 1.0, false, function SerpentranceCasterStop) endif // Set non-elemental variables to null set Caster = null set Target = null set Serpent = null set CasterPlayer = null set TargetPlayer = null set TargetLoc = null set t = null set SelectGroup = null endfunction //=========================================================================== function InitTrig_Cast_Serpentrance takes nothing returns nothing set gg_trg_Cast_Serpentrance = CreateTrigger( ) call TriggerRegisterAnyUnitEventBJ( gg_trg_Cast_Serpentrance, EVENT_PLAYER_UNIT_SPELL_EFFECT ) call TriggerAddCondition( gg_trg_Cast_Serpentrance, Condition( function Trig_Cast_Serpentrance_Conditions ) ) call TriggerAddAction( gg_trg_Cast_Serpentrance, function Trig_Cast_Serpentrance_Actions ) call Preload("Abilities\\Spells\\Other\\Charm\\CharmTarget.mdl") endfunction There are a number of functions to help me organize the various units that might come of each casting of the spell. The timer is set for 1 second so I can trigger the casting unit to stop it's animation, then the timer is set again for the rest of the time the summoned unit should last, barring its being killed. I'm stumped unless the expiration timer isn't precise. |
