| 11-16-2007, 11:28 PM | #1 |
I have a function that crashes when it gets to MoveLightning because for some reason or another my lightning doesn't really exist. GetLightningA, etc also crash. The only clue I have as to what's going wrong is the fact that H2I on the lightning returns the same number as the struct id. The function I am having trouble with is called Remove, it's towards the bottom. Note that the RemoveLast, Move and MoveLast all work perfectly even though they're very similar. JASS:library RP initializer Init //THESE ARE THE CONFIGURATION GLOBALS. IT IS SAFE TO TOUCH THESE IF YOU KNOW WHAT THEY DO //=========================================================================== globals private constant integer Range = 70 private constant integer Limit = 2147483456 endglobals //DO NOT TOUCH ANYTHING BELOW THIS LINE //=========================================================================== globals private trigger Trig_Train = CreateTrigger() private trigger Trig_Deselect = CreateTrigger() private trigger Trig_Select = CreateTrigger() private gamecache cache = InitGameCache("RP.w3v") private boolexpr BTrue private timer array TIMERS private integer TIMERS_N = 0 endglobals // Attaching Stuff private keyword UnitData private keyword FlagData private keyword OriginData private keyword TypeData private function H2I takes handle h returns integer return h return 0 endfunction //! textmacro GetSet takes TYPE private function Get$TYPE$Data takes handle h returns integer return GetStoredInteger(cache, I2S(H2I(h)), "$TYPE$"+SCOPE_PRIVATE) endfunction private function Set$TYPE$Data takes handle h, $TYPE$Data c returns nothing call StoreInteger(cache, I2S(H2I(h)), "$TYPE$"+SCOPE_PRIVATE, c) endfunction private function Flush$TYPE$Data takes handle h returns nothing call StoreInteger(cache, I2S(H2I(h)), "$TYPE$"+SCOPE_PRIVATE, 0) endfunction //! endtextmacro //! runtextmacro GetSet("Unit") //! runtextmacro GetSet("Flag") //! runtextmacro GetSet("Origin") //! runtextmacro GetSet("Type") // CS Safety private function NewTimer takes nothing returns timer if (TIMERS_N==0) then return CreateTimer() endif set TIMERS_N = TIMERS_N - 1 return TIMERS[TIMERS_N] endfunction private function ReleaseTimer takes timer t returns nothing call PauseTimer(t) set TIMERS[TIMERS_N] = t set TIMERS_N = TIMERS_N + 1 endfunction // General private function FTrue takes nothing returns boolean return true endfunction private function CloneGroup takes group g returns group set bj_groupAddGroupDest = CreateGroup() call ForGroup(g, function GroupAddGroupEnum) return bj_groupAddGroupDest endfunction // Struct Data private struct UnitData OriginData o integer lastflag = 1 endstruct private struct FlagData OriginData o unit flag integer no real x real y trigger t lightning l group units = CreateGroup() method onDestroy takes nothing returns nothing local unit u local UnitData ud loop set u = FirstOfGroup(.units) exitwhen u == null call GroupRemoveUnit(.units, u) set ud = GetUnitData(u) call ud.destroy() call FlushUnitData(u) endloop call DestroyGroup(.units) call DestroyLightning(.l) call DestroyTrigger(.t) call RemoveUnit(.flag) endmethod endstruct private struct OriginData TypeData t integer flagno = 0 group flags = CreateGroup() unit u method onDestroy takes nothing returns nothing local unit u local FlagData f loop set u = FirstOfGroup(.flags) exitwhen u == null call GroupRemoveUnit(.flags, u) set f = GetFlagData(u) call f.destroy() endloop call DestroyGroup(.flags) endmethod endstruct private struct TypeData integer flagid real rotation = 0 string order = "attack" string ltype integer red = 1 integer blue = 1 integer green = 1 group origins method onDestroy takes nothing returns nothing local unit u local OriginData o loop set u = FirstOfGroup(.origins) exitwhen u == null call GroupRemoveUnit(.origins, u) set o = GetOriginData(u) call o.destroy() endloop call DestroyGroup(.origins) endmethod endstruct //The Rally Point System private function GetFlagXData takes OriginData o, integer i returns FlagData local group g = CloneGroup(o.flags) local unit u local FlagData f loop set u = FirstOfGroup(g) exitwhen u == null call GroupRemoveUnit(g, u) set f = GetFlagData(u) if f.no == i then return f exitwhen true endif endloop return 0 endfunction public function Unregister takes unit u returns nothing local OriginData o = GetOriginData(u) call o.destroy() endfunction private function MoveToNextFlag takes nothing returns nothing local unit u = GetTriggerUnit() local trigger t = GetTriggeringTrigger() local UnitData ud = GetUnitData(u) local FlagData f = GetFlagData(t) if f.no < Limit then if ud.lastflag == f.no and ud.o == f.o then if f.no == ud.o.flagno then set f = GetFlagXData(ud.o, ud.lastflag) call GroupRemoveUnit(f.units, u) call ud.destroy() call FlushUnitData(u) else set f = GetFlagXData(ud.o, ud.lastflag) call GroupRemoveUnit(f.units, u) set ud.lastflag = ud.lastflag + 1 set f = GetFlagXData(ud.o, ud.lastflag) call GroupAddUnit(f.units, u) call IssuePointOrder(u, ud.o.t.order, f.x, f.y) endif endif else set f = GetFlagXData(ud.o, ud.lastflag) call ud.destroy() call FlushUnitData(u) endif set u = null set t = null endfunction private function MoveToFirstFlag takes nothing returns nothing local unit u = GetTriggerUnit() local unit m local OriginData o = GetOriginData(u) local UnitData ud local FlagData f set m = GetTrainedUnit() if m == null then set m = GetSoldUnit() if m == null then set m = GetRevivingUnit() endif endif if Limit > 0 and o.flagno > 0 then set ud = UnitData.create() set ud.o = o call SetUnitData(m, ud) set f = GetFlagXData(o, 1) call GroupAddUnit(f.units, m) call IssuePointOrder(m, o.t.order, f.x, f.y) endif set u = null set m = null endfunction public function AddLast takes unit u, real x, real y returns integer local OriginData o = GetOriginData(u) local FlagData f local FlagData ft if o.flagno < Limit then set o.flagno = o.flagno + 1 set f = FlagData.create() set f.o = o set f.no = o.flagno set f.x = x set f.y = y if o.flagno > 1 then set ft = GetFlagXData(o, o.flagno-1) set f.l = AddLightning(o.t.ltype, false, ft.x, ft.y, x, y) else set f.l = AddLightning(o.t.ltype, false, GetUnitX(u), GetUnitY(u), x, y) endif call SetLightningColor( f.l, 0, 0, 0, 0) set f.flag = CreateUnit(GetOwningPlayer(u), o.t.flagid, x, y, o.t.rotation) call ShowUnit(f.flag,false) if GetLocalPlayer() == GetOwningPlayer(u) then call ShowUnit(f.flag,true) call SetLightningColor( f.l, o.t.red, o.t.green, o.t.blue, 1) endif call GroupAddUnit(o.flags, f.flag) call SetFlagData(f.flag,f) set f.t = CreateTrigger() call TriggerAddAction(f.t, function MoveToNextFlag) call TriggerRegisterUnitInRange(f.t, f.flag, Range, BTrue) call SetFlagData(f.t, f) endif return o.flagno endfunction public function RemoveLast takes unit u returns nothing local OriginData o = GetOriginData(u) local FlagData f if o.flagno > 0 then set f = GetFlagXData(o, o.flagno) call f.destroy() set o.flagno = o.flagno - 1 endif endfunction public function RemoveAll takes unit u returns nothing local integer i = 0 local OriginData o = GetOriginData(u) loop set i = i + 1 exitwhen i > o.flagno call GetFlagXData(o, i).destroy() endloop set o.flagno = 0 endfunction private function Select takes nothing returns nothing local integer i = 0 local unit u = GetTriggerUnit() local OriginData o = GetOriginData(u) local FlagData f loop set i = i + 1 exitwhen i > o.flagno if GetLocalPlayer() == GetOwningPlayer(u) then set f = GetFlagXData(o, i) call SetLightningColor( f.l, o.t.red, o.t.green, o.t.blue, 1) call ShowUnit( f.flag, true ) endif endloop set u = null endfunction private function Deselect takes nothing returns nothing local integer i = 0 local unit u = GetTriggerUnit() local OriginData o = GetOriginData(u) local FlagData f loop set i = i + 1 exitwhen i > o.flagno set f = GetFlagXData(o, i) call SetLightningColor( f.l, 0, 0, 0, 0) call ShowUnit( f.flag, false ) endloop set u = null endfunction private function Init takes nothing returns nothing call TriggerAddAction(Trig_Train, function MoveToFirstFlag) call TriggerAddAction(Trig_Select, function Select) call TriggerAddAction(Trig_Deselect, function Deselect) set BTrue = Condition(function FTrue) endfunction public function Register takes unit u, TypeData t returns boolean local OriginData o if GetOriginData(u) == 0 then set o = OriginData.create() //Order units when trained call TriggerRegisterUnitEvent( Trig_Train, u, EVENT_UNIT_SELL ) call TriggerRegisterUnitEvent( Trig_Train, u, EVENT_UNIT_TRAIN_FINISH ) call TriggerRegisterUnitEvent( Trig_Train, u, EVENT_UNIT_HERO_REVIVE_FINISH ) //Show points when selected call TriggerRegisterUnitEvent( Trig_Select, u, EVENT_UNIT_SELECTED ) call TriggerRegisterUnitEvent( Trig_Deselect, u, EVENT_UNIT_DESELECTED ) //Set rp set o.u = u set o.t = t call SetOriginData(u, o) call GroupAddUnit(t.origins, u) return true endif return false endfunction public function Define takes integer flag, real rotation, string ltype, integer red, integer green, integer blue returns TypeData local TypeData t = TypeData.create() set t.flagid = flag set t.rotation = rotation set t.ltype = ltype set t.red = red set t.green = green set t.blue = blue return t endfunction public function IsRegistered takes unit u returns boolean if GetOriginData(u) > 0 then return true endif return false endfunction public function AddDefaultAbility takes unit u returns nothing call UnitRemoveAbility(u, 'ARal') endfunction public function RemoveDefaultAbility takes unit u returns nothing call UnitRemoveAbility(u, 'ARal') endfunction public function SetOrder takes TypeData t, string s returns nothing set t.order = s endfunction public function DestroyType takes TypeData t returns nothing call t.destroy() endfunction public function Remove takes unit u, integer i returns nothing local OriginData o = GetOriginData(u) local FlagData f local FlagData ft local integer n = i+1 if i > 0 and i <= o.flagno then set f = GetFlagXData(o, i) call f.destroy() if i < o.flagno then loop exitwhen n > o.flagno set ft = GetFlagXData(o, n) set ft.no = ft.no - 1 set n = n + 1 endloop set f = GetFlagXData(o, i) if i == 1 then call MoveLightning(f.l, false, GetUnitX(o.u), GetUnitY(o.u), f.x, f.y) else set ft = GetFlagXData(o, i-1) call MoveLightning(f.l, false, ft.x, ft.y, f.x, f.y) endif endif set o.flagno = o.flagno - 1 endif set u = null endfunction public function Add takes unit u, integer i, real x, real y returns nothing local OriginData o = GetOriginData(u) local FlagData f local FlagData ft local integer n = i if i > 0 and i <= o.flagno then loop exitwhen n > o.flagno set f = GetFlagXData(o, n) set f.no = f.no + 1 set n = n + 1 endloop set o.flagno = o.flagno + 1 set f = FlagData.create() set f.o = o set f.no = i set f.x = x set f.y = y if i > 1 then set ft = GetFlagXData(o, i) set f.l = AddLightning(o.t.ltype, false,ft.x,ft.y,f.x,f.y) set ft = GetFlagXData(o, i+1) call MoveLightning(f.l, false, f.x, f.y, ft.x, ft.y) else set f.l = AddLightning(o.t.ltype, false,GetUnitX(u),GetUnitY(u),f.x,f.y) set ft = GetFlagXData(o, i+1) call MoveLightning(f.l, false, f.x, f.y, ft.x, ft.y) endif call SetLightningColor( f.l, 0, 0, 0, 0) set f.flag = CreateUnit(GetOwningPlayer(u), o.t.flagid, x, y, o.t.rotation) call ShowUnit(f.flag,false) if GetLocalPlayer() == GetOwningPlayer(u) then call ShowUnit(f.flag,true) call SetLightningColor( f.l, o.t.red, o.t.green, o.t.blue, 1) endif call GroupAddUnit(o.flags, f.flag) call SetFlagData(f.flag,f) set f.t = CreateTrigger() call TriggerAddAction(f.t, function MoveToNextFlag) call TriggerRegisterUnitInRange(f.t, f.flag, Range, BTrue) call SetFlagData(f.t, f) endif set u = null endfunction public function Move takes unit u, integer i, real x, real y returns nothing local OriginData o = GetOriginData(u) local FlagData f local FlagData ft if o.flagno > 0 and i <= o.flagno then set f = GetFlagXData(o, i) call SetUnitPosition(f.flag, x, y) set f.x = GetUnitX(f.flag) set f.y = GetUnitY(f.flag) if i == 1 then call MoveLightning(f.l, false, GetUnitX(o.u), GetUnitY(o.u), f.x, f.y ) else set ft = GetFlagXData(o, i-1) call MoveLightning(f.l, false, ft.x, ft.y, f.x, f.y ) endif set ft = GetFlagXData(o, i+1) call MoveLightning(ft.l, false, f.x, f.y, ft.x, ft.y ) call DestroyTrigger(f.t) set f.t = CreateTrigger() call TriggerAddAction(f.t, function MoveToNextFlag) call TriggerRegisterUnitInRange(f.t, f.flag, Range, BTrue) call SetFlagData(f.t, f) endif endfunction public function MoveLast takes unit u, real x, real y returns nothing local OriginData o = GetOriginData(u) local FlagData f local FlagData ft if o.flagno > 0 then set f = GetFlagXData(o, o.flagno) call SetUnitPosition(f.flag, x, y) set f.x = GetUnitX(f.flag) set f.y = GetUnitY(f.flag) if o.flagno == 1 then call MoveLightning(f.l, false, GetUnitX(o.u), GetUnitY(o.u), f.x, f.y ) else set ft = GetFlagXData(o, o.flagno-1) call MoveLightning(f.l, false, ft.x, ft.y, f.x, f.y ) endif call DestroyTrigger(f.t) set f.t = CreateTrigger() call TriggerAddAction(f.t, function MoveToNextFlag) call TriggerRegisterUnitInRange(f.t, f.flag, Range, BTrue) call SetFlagData(f.t, f) endif endfunction endlibrary Edit: Fixed cohadar's name and added GetXData. Edit2: Decided to uploaded the entire script, since no one was looking at the map. |
| 11-17-2007, 02:28 AM | #2 |
Tons of functions I am not seeing, like GetOriginData, GetFlagData , etc. So I can't really debug this. |
| 11-17-2007, 04:05 AM | #3 |
Ok I will not talk about attaching here. But in case you want to know why your code crashes send me a PM and we will talk about attaching and a little about spelling. |
| 11-17-2007, 05:40 AM | #4 |
As I said, SetXData and GetXData were simply attaching via gamecache. They'rein the map, but I'll put them up here in a sec. I know attaching stuff isn't the problem anyway, since it gets the structs correctly. It just doesn't refer to the lightning properly. Sorry for spelling your name wrong, cohadar. Edit: Changed their to they're. |
| 11-17-2007, 10:26 AM | #5 |
JASS:
//==================================================================================================
// CSData
// ¯¯¯¯¯¯
// CSDatas are like UserData in units and items, they are faster than gamecache unless you have more
// than 8191 handles in your map. In that case it would be a little slower but only for those
// handles. And if you have more than 8191 handles your map is too slow already anyways.
//
// Notice that for public spells or systems to be distributed you should only use these
// for private objects (those who the mapper would never have access to) If you are making something
// for your map you can use them wherever you want.
//
// Best to be used in conjunction to CSArrays so you just specify an array id for a handle.
//
// DO NOT USE THIS ON THESE HANDLE TYPES: -lightning, -ubersplat, -image, -texttag,
// -any 'argument' handle (like playerstate, damagetype, etc)
//
function SetCSData takes handle h, integer v returns nothing
local integer i=CS_H2I(h)-0x100000
if (i>=8191) then
call StoreInteger(cs_cache,"csdata",I2S(i),v)
else
set cs_array3[i]=v
endif
endfunction
function GetCSData takes handle h returns integer
local integer i=CS_H2I(h)-0x100000
if (i>=8191) then
//can't use Get without Set
return GetStoredInteger(cs_cache,"csdata",I2S(i))
endif
return cs_array3[i]
endfunction
@Vexorian: How did you come up with that DO NOT USE THIS list? |
| 11-17-2007, 10:48 AM | #6 |
Testing... most probably... |
| 11-17-2007, 11:46 AM | #7 |
Cohadar: he is not using CSData. -- You are creating the lightning for the Local Player but then you move the lightning regardless of who you created it for... Try creating the lightning for everyone and set it to invisible or only move the lightning to the player that is supposed to have it. |
| 11-17-2007, 12:35 PM | #8 |
I know he is not using CSData, what am I blind? But he is using lightning attaching so I thought to give him a hint. |
| 11-17-2007, 12:40 PM | #9 | |
Quote:
There is a limit in the number of texttags you can create; applying H2I on them will always return an integer between 0 and 100. The rest are probably similar. For the 'argument' types, the explanation is simple: they are special flags not meant to point instanceable objects. |
| 11-17-2007, 01:51 PM | #10 |
So basically those are not real handles. |
| 11-17-2007, 07:23 PM | #11 |
Yes, PLAYER_STATE_SOMETHING, EVENT_SOMETHING, DAMAGE_TYPE_SOMETHING don't look like real handles to me, just some crappy integers (which they basically are), so using ints as handles.......bad. |
| 11-17-2007, 08:46 PM | #12 |
No of the posts below mine make any sense to me, excepts Vex's. However, that's not the problem because I just fixed that and it still crashes and I can move it in other functions without a crash. |
| 11-17-2007, 09:17 PM | #13 |
This is all happening because you are not using ABC.... ... Why the fuck don't we have an evil smiley on this forum? |
| 11-17-2007, 09:36 PM | #14 |
........................................__.......................................................... .... .................................,-~*`¯lllllll`*~,................................................. ...........................,-~*`lllllllllllllllllllllllllll¯`*-,..................................... ......................,-~*llllllllllllllllllllllllllllllllllllllllllll*-,.............................. ..................,-*llllllllllllllllllllllllllllllllllllllllllllllllllllll.\............................ ................;*`lllllllllllllllllllllllllll,-~*~-,llllllllllllllllllll\........................... ................\lllllllllllllllllllllllllll/...........\;;;;llllllllllll,-`~-,......................... .................\lllllllllllllllllllll,-*.............`~-~-,...(.(¯`*,`,.......................... ...................\llllllllllll,-~*........................)_-\..*`*;..)........................... .....................\,-*`¯,*`)............,-~*`~................../............................... .....................|/.../.../~,......-~*,-~*`;.................../.\.............................. .................../.../..../..../..,-,..*~,.`*~*..................*...\............................. ...................|.../.../..../.*`...\................................)....)¯`~,.................... ...................|./..../..../........).........)`*~-,............../.....|..)...`~-,.............. .................././.../....,*`-,.....`-,....*`....,---......\...../...../..|..........¯```*~-,,,, .................(............)`*~-,.....`*`.,-~*.,-*.......|.../..../..../...............\.......... ..................*-,.......`*-,...`~,..``.,,,-*.............|.,*...,*....|.................\......... ......................*,.........`-,....)-,..................,-*`...,-*.....(`-,..............\........ ........................f`-,........`-,/...*-,___,,-~*.....,-*......|....`-,...............\....... I know the problem isn't to do with attaching stuff. All the other data on the struct works perfectly and the lightning works perfectly when refered to in other functions. Edit: Hmmm, thats a terrible face palm guy. BRB finding a better one. Edit2: That's slightly better. |
| 11-18-2007, 10:08 AM | #15 |
Have you checked if the lightning is even created? Because there are some issues (at least with me) with the checkVisibility boolean parameter (in lightning functions). Instead of setting that boolean to false, try setting it's alpha to 0 (this most probably isn't the problem, but still try). Btw, just outta curiosity, why do you do this: JASS:if something then call DoSomething() call DoSomethingElse() else call DoSomething() endif instead of this: JASS:if something then call DoSomethingElse() endif call DoSomething() Saves you space. |
