- Joined
- Nov 30, 2007
- Messages
- 1,202
I decided to revisit this old spell I had resting on my drive. Not exactly sure where I want to go with this so any feedback is much appreciated, in particular things that improves the use case flexibility, how to make it more balanced or aestheticly pleasing.
Code improvement is welcome as well, but I'm mostly focusing on how it should work right now.
I'm not really satesfied with how it looks when spreading, but I'm not sure how to improve on it.
Features
Code improvement is welcome as well, but I'm mostly focusing on how it should work right now.
I'm not really satesfied with how it looks when spreading, but I'm not sure how to improve on it.
Features
- Passive spell used by units to ignite buildings when sufficient fire damage has been sustained.
- Fire can spread to nearby buildings.
- Multiple flames can be created on the same building.
- Once ignited a building will burn down eventually.
- Flames can be targeted, currently by firefighters.
- Burning buildings cannot operate.
- A building that burns down will detonate and create a number of small flames nearby with the potential to start a new fire on another building (not done yet).
- Configuration of building fire resistance (not done yet).
- Level configuration (not done yet)
- Add Fire Started Event (not done yet)
- Add Fire Ended Event (not done yet)
JASS:
[/LIST] function isUnitFireDamaged takes unit u returns boolean return GetUnitAbilityLevel(u, udg_FS_BUFF_FIRE) != 0 endfunction function isUnitBurning takes unit u returns boolean return LoadUnitHandle(udg_FS_hash, GetHandleId(u), 3) != null endfunction function unitIsFlame takes unit u returns boolean return GetUnitTypeId(u) == udg_FS_UT_FLAME endfunction function Trig_FireDamage_Conditions takes nothing returns boolean return ((isUnitFireDamaged(udg_GDD_DamagedUnit) == true) and IsUnitType(udg_GDD_DamagedUnit, UNIT_TYPE_STRUCTURE) == true) endfunction function Trig_FireDamage_BuildingDeath takes nothing returns boolean local unit u = GetTriggerUnit() if ((IsUnitType(u, UNIT_TYPE_STRUCTURE) == true) and isUnitBurning(u)) then call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 10., "burning building dies") endif return false endfunction function FireDamage_TimerExpires takes nothing returns nothing local timer t = GetExpiredTimer() local integer thid = GetHandleId(t) local unit u = LoadUnitHandle(udg_FS_hash, thid, 2) local integer uhid = GetHandleId(u) set bj_lastCreatedEffect = LoadEffectHandle(udg_FS_hash, uhid, 4) call DestroyEffect(bj_lastCreatedEffect) call PauseTimer(t) call DestroyTimer(t) call PauseUnit(u, false) call FlushChildHashtable(udg_FS_hash, thid) call FlushChildHashtable(udg_FS_hash, uhid) call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 10., "timer expired") set t = null set u = null endfunction function FireDamage_CreateFlameOnUnit takes unit target returns nothing local real angle local real dist local real x local real y local real ratio if (isUnitBurning(target) == true) then set angle = GetRandomReal(0, 360) set dist = BlzGetUnitCollisionSize(target) + 36 set x = GetUnitX(target) + dist*Cos(angle*bj_DEGTORAD) set y = GetUnitY(target) + dist*Sin(angle*bj_DEGTORAD) set bj_lastCreatedUnit = CreateUnit(Player(PLAYER_NEUTRAL_AGGRESSIVE), udg_FS_UT_FLAME, x, y, 0) set ratio = GetUnitState(bj_lastCreatedUnit, UNIT_STATE_MAX_LIFE)*udg_FS_FLAME_START_HP_CHILD else call PauseUnit(target, true) set x = GetUnitX(target) set y = GetUnitY(target) call AddSpecialEffect("Objects\\Spawnmodels\\Other\\NeutralBuildingExplosion\\NeutralBuildingExplosion.mdl", x, y) set bj_lastCreatedUnit = CreateUnit(Player(PLAYER_NEUTRAL_AGGRESSIVE), udg_FS_UT_FLAME, x, y, 0) set ratio = GetUnitState(bj_lastCreatedUnit, UNIT_STATE_MAX_LIFE)*udg_FS_FLAME_START_HP endif call SetUnitState(bj_lastCreatedUnit, UNIT_STATE_LIFE, ratio) call SetUnitScale(bj_lastCreatedUnit, ratio, ratio, ratio) call GroupAddUnit(udg_FS_flames, bj_lastCreatedUnit) if (IsTriggerEnabled(gg_trg_UpdateFlames) == false) then call EnableTrigger(gg_trg_UpdateFlames) endif endfunction function Trig_FireDamage_Actions takes nothing returns nothing local real dmg = udg_GDD_Damage local unit u = udg_GDD_DamagedUnit local unit attacker = udg_GDD_DamageSource local integer uhid local real stack_dmg local timer t if (dmg == 0) then return endif // Stack damage and reset timer set uhid = GetHandleId(u) set stack_dmg = LoadReal(udg_FS_hash, uhid, 0) + dmg set t = LoadTimerHandle(udg_FS_hash, uhid, 1) if (t == null) then set t = CreateTimer() call SaveTimerHandle(udg_FS_hash, uhid, 1, t) call SaveUnitHandle(udg_FS_hash, GetHandleId(t), 2, u) set bj_lastCreatedEffect = AddSpecialEffectTarget("Abilities\\Spells\\Orc\\LiquidFire\\Liquidfire.mdl" , u, "origin") call SaveEffectHandle(udg_FS_hash, uhid, 4, bj_lastCreatedEffect) endif call TimerStart(t, udg_FS_FIRE_DAMAGE_DURATION, false, function FireDamage_TimerExpires) // If the unit is a flame then give it back life if (unitIsFlame(attacker) == true) then call SetUnitState(attacker, UNIT_STATE_LIFE, GetUnitState(attacker, UNIT_STATE_LIFE) + dmg*udg_FS_REGEN_FACTOR) call SaveUnitHandle(udg_FS_hash, uhid, 3, u) endif // If the conditions are met then spawn a new flame if (stack_dmg >= GetUnitState(u, UNIT_STATE_MAX_LIFE)*udg_FS_DMG_REQ) then set stack_dmg = stack_dmg - GetUnitState(u, UNIT_STATE_MAX_LIFE)*udg_FS_DMG_REQ call FireDamage_CreateFlameOnUnit(u) endif call SaveReal(udg_FS_hash, uhid, 0, stack_dmg) endfunction //=========================================================================== function InitTrig_FireDamage takes nothing returns nothing local trigger t_dmg = CreateTrigger() local trigger t_death = CreateTrigger() local integer i local player p call TriggerRegisterVariableEvent(t_dmg, "udg_GDD_Event", EQUAL, 0) call TriggerAddCondition(t_dmg, Condition( function Trig_FireDamage_Conditions)) call TriggerAddAction(t_dmg, function Trig_FireDamage_Actions) set i = 0 loop set p = Player(i) call TriggerRegisterPlayerUnitEvent(t_death, p, EVENT_PLAYER_UNIT_DEATH, null) set i = i + 1 exitwhen i == bj_MAX_PLAYER_SLOTS endloop call TriggerAddCondition(t_death, Condition( function Trig_FireDamage_BuildingDeath)) set t_death = null set t_dmg = null set p = null endfunction
JASS:function FlamesIterator takes nothing returns nothing local real r set bj_lastCreatedUnit = GetEnumUnit() set r = GetUnitState(bj_lastCreatedUnit, UNIT_STATE_LIFE)/GetUnitState(bj_lastCreatedUnit, UNIT_STATE_MAX_LIFE) call SetUnitScale(bj_lastCreatedUnit, r, r, r) set bj_isUnitGroupEmptyResult = false endfunction function Trig_UpdateFlames_Actions takes nothing returns nothing set bj_isUnitGroupEmptyResult = true call ForGroup(udg_FS_flames, function FlamesIterator) if (bj_isUnitGroupEmptyResult == true) then call DisableTrigger(gg_trg_UpdateFlames) endif endfunction //=========================================================================== function InitTrig_UpdateFlames takes nothing returns nothing set gg_trg_UpdateFlames = CreateTrigger() call TriggerRegisterTimerEvent(gg_trg_UpdateFlames, 0.5, true) call TriggerAddAction(gg_trg_UpdateFlames, function Trig_UpdateFlames_Actions) call DisableTrigger(gg_trg_UpdateFlames) endfunction
Feel free to try and burn up some stuff and tell me what you think.
Attachments
Last edited: