Jonnycakes
New Member
- Reaction score
- 6
Hi, I have been trying to make a trip wire ability-the premise is that the user targets two trees and then a trip wire is created between the two trees. If an enemy unit crosses the wire, it explodes. I am using Anitarf's spell here as a reference, but I am still running into a lot of problems.
The initial ability ('A00N') is based off of sentinel-when it is cast, the trigger stops the unit and forces the owner to hit the hotkey (T for trip wire) again, creating another tree selection cursor. Now the fun stuff happens-the unit gets a new instant cast dummy ability based on channel and the trigger spams its hotkey (L) for the player. If the second tree targeting is canceled, the dummy spell will be used, canceling the cast and triggering a clean-up of any variables involved.
This is where I am having issues. The function that is supposed to be spamming "L" is running, but the player variable that stores the owner of the casting unit (this.owner) is null for some reason. I can't figure out why this is, because when the struct (target) is created, .owner is NOT null. Shortly afterward, it is. Can anyone help me out on this one? (If you find other errors, that is appreciated as well!)
NOTE: I have only worked on the first part of this spell, which sets up the trip wire. It is fully functional as is-it just doesn't actually set up the trip wire. I will add the second half when I figure this out.
EDIT: Attached a test map. The unit is the mechanic, the spell is trip wire, and the current trigger is Trip Wire NEW. There are some BJDebugs that may get annoying as well-just a warning.
The initial ability ('A00N') is based off of sentinel-when it is cast, the trigger stops the unit and forces the owner to hit the hotkey (T for trip wire) again, creating another tree selection cursor. Now the fun stuff happens-the unit gets a new instant cast dummy ability based on channel and the trigger spams its hotkey (L) for the player. If the second tree targeting is canceled, the dummy spell will be used, canceling the cast and triggering a clean-up of any variables involved.
This is where I am having issues. The function that is supposed to be spamming "L" is running, but the player variable that stores the owner of the casting unit (this.owner) is null for some reason. I can't figure out why this is, because when the struct (target) is created, .owner is NOT null. Shortly afterward, it is. Can anyone help me out on this one? (If you find other errors, that is appreciated as well!)
NOTE: I have only worked on the first part of this spell, which sets up the trip wire. It is fully functional as is-it just doesn't actually set up the trip wire. I will add the second half when I figure this out.
EDIT: Attached a test map. The unit is the mechanic, the spell is trip wire, and the current trigger is Trip Wire NEW. There are some BJDebugs that may get annoying as well-just a warning.
JASS:
scope tripwire initializer init
globals
private hashtable h=InitHashtable()
endglobals
private function CheckTree takes destructable tree1, destructable tree2 returns boolean
local real x=GetDestructableX(tree1)
local real y=GetDestructableY(tree1)
local real xx=GetDestructableX(tree2)
local real yy=GetDestructableY(tree2)
return true
//return SquareRoot((xx-x)*(xx-x)+(yy-y)*(yy-y))<=600 and tree1!=tree2
endfunction
private struct trip
unit caster
player owner
destructable tree1
destructable tree2
lightning l
real duration
private integer index
private static trip array wire
private static integer count=0
private static timer time
endstruct
private struct target
unit caster
player owner
destructable tree1
private integer index=1
static target array targ
private static integer count=1
private static timer time
static method create takes unit u, destructable tree returns target
local target t=target.allocate()
set t.caster=u
set t.owner=GetOwningPlayer(u)
set t.tree1=tree
set t.index=-1
return t
endmethod
static method spam takes nothing returns nothing
local integer i=1
loop
exitwhen i==target.count
if GetLocalPlayer()==target.targ<i>.owner then
call ForceUIKey("l")
endif
//if target.targ<i>.owner==null then
//call BJDebugMsg("null "+I2S(i))
//endif
set i=i+1
endloop
endmethod
method start takes nothing returns nothing
set .index=target.count
call UnitAddAbility(.caster, 039;A00C039;)
call SaveInteger(h, GetHandleId(.caster), 0, .index)
if GetLocalPlayer()==.owner then
call ForceUIKey("t")
endif
if .owner==null then
call BJDebugMsg("null owner")
endif
if target.count==1 then
call TimerStart(target.time, .1, true, function target.spam)
endif
set target.count=target.count+1
call BJDebugMsg("start "+I2S(target.count))
endmethod
method stop takes nothing returns nothing
set target.count=target.count-1
set target.targ[target.count].index=.index
set target.targ[.index]=target.targ[target.count]
set .index=-1
if target.count==1 then
call PauseTimer(target.time)
endif
call BJDebugMsg("stop "+I2S(target.count))
endmethod
static method onInit takes nothing returns nothing
set target.time=CreateTimer()
endmethod
endstruct
private function spellcast takes nothing returns boolean
local unit u
local target t
local destructable tree
if GetIssuedOrderId()==OrderId("sentinel") then
set u=GetTriggerUnit()
set tree=GetOrderTargetDestructable()
if LoadInteger(h, GetHandleId(u), 0)==null then //the unit has not cast the first target
set t=target.create(u, tree)
if t.caster==null or t.owner==null or t.tree1==null then
call BJDebugMsg("null struct create")
endif
call DisableTrigger(GetTriggeringTrigger())
call PauseUnit(u, true)
call IssueImmediateOrder(u, "stop")
call PauseUnit(u, false)
call EnableTrigger(GetTriggeringTrigger())
call t.start()
else //the unit HAS cast the first target, validate second now...
set t=target.targ[LoadInteger(h, GetHandleId(u), 0)]
call t.stop()
call FlushChildHashtable(h, GetHandleId(u))
call UnitRemoveAbility(u, 039;A00C039;)
if CheckTree(t.tree1, tree) then
else
call DisableTrigger(GetTriggeringTrigger())
call PauseUnit(u, true)
call IssueImmediateOrder(u, "stop")
call PauseUnit(u, false)
call EnableTrigger(GetTriggeringTrigger())
call t.start()
endif
endif
set u=null
set tree=null
endif
return false
endfunction
private function spelleffect takes nothing returns boolean
local unit u
local target t
if GetSpellAbilityId()==039;A00N039; then
set u=GetTriggerUnit()
set t=target.targ[LoadInteger(h, GetHandleId(u), 0)]
call trip.create()
//call t.destroy()
call FlushChildHashtable(h, GetHandleId(u))
call UnitRemoveAbility(u, 039;A00C039;)
set u=null
endif
return false
endfunction
private function cancel takes nothing returns boolean
local unit u
local target t
if GetIssuedOrderId()==OrderId("channel") then
set u=GetOrderedUnit()
set t=target.targ[LoadInteger(h, GetHandleId(u), 0)]
call t.stop()
call FlushChildHashtable(h, GetHandleId(u))
call UnitRemoveAbility(u, 039;A00C039;)
call t.destroy()
set u=null
endif
return false
endfunction
private function herotype takes nothing returns boolean
return GetUnitTypeId(GetFilterUnit())==039;H003039;
endfunction
//===========================================================================
private function init takes nothing returns nothing
local trigger t=CreateTrigger()
local integer x=0
call TriggerAddCondition(t, Condition(function spellcast))
loop
exitwhen x==12
call TriggerRegisterPlayerUnitEvent(t, Player(x), EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER, Filter(function herotype))
set x=x+1
endloop
set x=0
set t=CreateTrigger()
call TriggerAddCondition(t, Condition(function spelleffect))
loop
exitwhen x==12
call TriggerRegisterPlayerUnitEvent(t, Player(x), EVENT_PLAYER_UNIT_SPELL_EFFECT, Filter(function herotype))
set x=x+1
endloop
set x=0
set t=CreateTrigger()
call TriggerAddCondition(t, Condition(function cancel))
loop
exitwhen x==12
call TriggerRegisterPlayerUnitEvent(t, Player(x), EVENT_PLAYER_UNIT_ISSUED_ORDER, Filter(function herotype))
set x=x+1
endloop
set t=null
endfunction
endscope</i></i>