- Joined
- Jun 5, 2008
- Messages
- 2,573
Just wanted to share with you guys an system i wrote for my needs.
I didn't know where to put it for suggestions/comments so i guessed this is as good place as any.
Anyhow here is the code, please note i am not up to speed with current WC3 scripts as i started using jass a long time ago, then stopped and am only kind of using it for personal needs only.
I will probably refine it more since i grow quite fond of it. (add recycling triggers and more stuff)
Enjoy, and please do comment if you like the idea.
(Works by extending damageInstance by a normal struct, rewriting onDamageTaken/Dealt methods then calling SaveInstance(<struct>, <unit>))
I didn't know where to put it for suggestions/comments so i guessed this is as good place as any.
Anyhow here is the code, please note i am not up to speed with current WC3 scripts as i started using jass a long time ago, then stopped and am only kind of using it for personal needs only.
I will probably refine it more since i grow quite fond of it. (add recycling triggers and more stuff)
Enjoy, and please do comment if you like the idea.
(Works by extending damageInstance by a normal struct, rewriting onDamageTaken/Dealt methods then calling SaveInstance(<struct>, <unit>))
JASS:
library InstanceDD initializer Init
globals
private trigger EVENT_RESPONSE = CreateTrigger()
private trigger RECYCLE_TRIG = CreateTrigger()
private hashtable Dx
group INSTANCE_GROUP = CreateGroup()
private group ENUM_GROUP = CreateGroup()
private group SAFETY_GROUP = CreateGroup()
endglobals
struct damageInstance
stub method onDamageTaken takes unit source, unit target, real damage returns real
return damage
endmethod
stub method onDamageDealt takes unit source, unit target, real damage returns real
return damage
endmethod
endstruct
private struct dd
unit u
integer stack
method release takes nothing returns nothing
local integer i = 1
local damageInstance t
loop
exitwhen i > .stack
set t = LoadInteger(Dx, GetHandleId(.u), i)
call t.destroy()
set i = i +1
endloop
set .u = null
call .destroy()
endmethod
method run takes unit source, unit target, real damage returns nothing
local integer i = 1
local integer max
local real oldDmg = damage
local real newDmg = damage
local damageInstance t
local dd other
if IsUnitInGroup(target, SAFETY_GROUP) == false then
loop
exitwhen i > .stack
set t = LoadInteger(Dx, GetHandleId(target), i)
set newDmg = t.onDamageTaken(source, target, newDmg)
set i = i +1
endloop
set other = LoadInteger(Dx, GetHandleId(source),0)
set i = 1
loop
exitwhen i > other.stack
set t = LoadInteger(Dx, GetHandleId(source), i)
set newDmg = t.onDamageDealt(source, target, newDmg)
set i = i +1
endloop
call GroupAddUnit(SAFETY_GROUP, target)
call UnitDamageTarget(source, target, newDmg - oldDmg , true, true, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, null)
call GroupRemoveUnit(SAFETY_GROUP, target)
endif
endmethod
method addInstance takes damageInstance h returns nothing
call SaveInteger(Dx, GetHandleId(this.u), this.stack, h)
set this.stack = this.stack + 1
endmethod
endstruct
function SaveDamageInstance takes damageInstance d, unit u returns nothing
local dd dmg = LoadInteger(Dx, GetHandleId(u),0)
if dmg.u == null then
set dmg = dd.create()
set dmg.u = u
set dmg.stack = 1
call SaveInteger(Dx, GetHandleId(u),0,dmg)
endif
call dmg.addInstance(d)
endfunction
function CreateInstance takes unit u returns nothing
local dd data = dd.create()
set data.u = u
set data.stack = 1
call SaveInteger(Dx, GetHandleId(u),0,data)
endfunction
private function returnTrue takes nothing returns boolean
return true
endfunction
private function runDD takes nothing returns boolean
local dd data = LoadInteger(Dx, GetHandleId(GetTriggerUnit()),0)
if data.u != null then
call data.run(GetEventDamageSource(),GetTriggerUnit(),GetEventDamage())
else
call data.release()
endif
return false
endfunction
private function AddToEvent takes nothing returns boolean
if IsUnitInGroup(GetTriggerUnit(), INSTANCE_GROUP) == false then
call TriggerRegisterUnitEvent(EVENT_RESPONSE, GetTriggerUnit(), EVENT_UNIT_DAMAGED)
call CreateInstance(GetTriggerUnit())
call GroupAddUnit(INSTANCE_GROUP, GetTriggerUnit())
endif
return false
endfunction
private function Init takes nothing returns nothing
local trigger t = CreateTrigger()
local group g = CreateGroup()
local rect r = GetPlayableMapRect()
local region reg = CreateRegion()
local unit u
set Dx = InitHashtable()
call RegionAddRect(reg, r)
call GroupEnumUnitsInRect(g, r,function returnTrue)
set u = FirstOfGroup(g)
loop
exitwhen u == null
call TriggerRegisterUnitEvent(EVENT_RESPONSE, u, EVENT_UNIT_DAMAGED)
call CreateInstance(u)
call GroupAddUnit(INSTANCE_GROUP, u)
call GroupRemoveUnit(g,u)
set u = FirstOfGroup(g)
endloop
call TriggerRegisterEnterRegion(t, reg, function returnTrue)
call TriggerAddCondition(EVENT_RESPONSE, function runDD)
call TriggerAddCondition(t, function AddToEvent)
call DestroyGroup(g)
call RemoveRect(r)
set g = null
set r = null
endfunction
endlibrary