| 08-30-2007, 10:00 PM | #1 |
An unexpected problem occurred while modifying an event for a trigger. Before going into details, let me first post the code. JASS://Implementation: *copy dummy unit over, and make a passive ability and add it to units so they know they get it(though this code does not) // *paste this code into a trigger called Meteor // *configure the options given, as well as alter dummy unit to your liking(height, size, projectile for attack, etc.) and viola! //Documentation: This should work a whole lot better, most of the config is in the dummy unit itself, not here scope Meteor globals //config options private constant integer unit1_id = 'h01B' //tower 1 id private constant integer unit2_id = 'h02A' //tower 2 id private constant integer dum1_id = 'e006' //dummy unit 1 id private constant integer dum2_id = 'e005' //dummy unit 2 id private constant real sub_int = 1. //interval to create meteors at (how often they occur in seconds) private constant real area = 500. //area in which the meteor may fall to, around the tower //needed variables private timer subT = CreateTimer() private group mainG = CreateGroup() private boolean timer_on = false endglobals //get correct dummy private function get_dummy takes integer towerid returns integer if towerid==unit1_id then return dum1_id else return dum2_id endif endfunction //create meteor for all available towers private function Meteor_Create takes nothing returns nothing local unit u = GetEnumUnit() local integer id = get_dummy(GetUnitTypeId(u)) local real x = GetUnitX(u) local real y = GetUnitY(u) local unit meteor = CreateUnit(GetOwningPlayer(u),id,x,y,0.) call IssuePointOrder(meteor,"attackground",x+GetRandomReal(50.,area)*Cos(GetRandomReal(0.,360.)*bj_DEGTORAD),y+GetRandomReal(50.,area)*Sin(GetRandomReal(0.,360.)*bj_DEGTORAD)) call UnitApplyTimedLife(meteor,'BTLF',1.) set u = null set meteor = null endfunction //remove dead towers/allow meteors to be created for alive ones private function Meteor_Actions2 takes nothing returns nothing //call Msg("Runnin",Player(0)) if FirstOfGroup(mainG)!=null then //call Msg("Go",Player(0)) call ForGroup(mainG,function Meteor_Create) else call PauseTimer(subT) set timer_on = false endif endfunction //remove dead towers from main group function Meteor_Death_Conditions takes nothing returns boolean local unit u = GetTriggerUnit() if GetUnitTypeId(u)==unit1_id or GetUnitTypeId(u)==unit2_id then //call Msg("Removed",Player(0)) call GroupRemoveUnit(mainG,u) endif set u = null return false endfunction //add entering towers to check function Meteor_Conditions takes nothing returns boolean return GetUnitTypeId(GetTriggerUnit())==unit1_id or GetUnitTypeId(GetTriggerUnit())==unit2_id endfunction function Meteor_Actions takes nothing returns nothing //call Msg("Added",Player(0)) call GroupAddUnit(mainG,GetTriggerUnit()) if timer_on==false then call TimerStart(subT,sub_int,true,function Meteor_Actions2) set timer_on = true endif endfunction endscope //=========================================================================== function InitTrig_Meteor takes nothing returns nothing local trigger trig = CreateTrigger() //call TriggerRegisterEnterRectSimple(trig,bj_mapInitialPlayableArea) call TriggerRegisterAnyUnitEventBJ(trig,EVENT_PLAYER_UNIT_UPGRADE_FINISH) call TriggerAddCondition(trig,Condition(function Meteor_Conditions)) call TriggerAddAction(trig,function Meteor_Actions) set trig = CreateTrigger() call TriggerRegisterAnyUnitEventBJ(trig,EVENT_PLAYER_UNIT_DEATH) call TriggerAddCondition(trig,Condition(function Meteor_Death_Conditions)) set trig = null endfunction You will notice that this was the event first used: JASS:call TriggerRegisterEnterRectSimple(trig,bj_mapInitialPlayableArea) It was changed because units that enter play via an upgrade do not fire this trigger, thus, it didn't work with the towers it should have. This is what it became: JASS:call TriggerRegisterAnyUnitEventBJ(trig,EVENT_PLAYER_UNIT_UPGRADE_FINISH) What is the problem? When the appropriate unit finishes upgrading, the game fatal errors with message a brief moment after (i.e. when the trigger would fire). Any help would be appreciated. |
| 08-31-2007, 12:22 AM | #2 |
Mightn't it be that the functions should be public functions? It seems to me that functions in scopes that aren't private are declared as public instead of just having no public/private keyword. Additionally, it would be better to just make them all private functions and then just reference them correctly: JASS://Implementation: *copy dummy unit over, and make a passive ability and add it to units so they know they get it(though this code does not) // *paste this code into a trigger called Meteor // *configure the options given, as well as alter dummy unit to your liking(height, size, projectile for attack, etc.) and viola! //Documentation: This should work a whole lot better, most of the config is in the dummy unit itself, not here scope Meteor globals //config options private constant integer unit1_id = 'h01B' //tower 1 id private constant integer unit2_id = 'h02A' //tower 2 id private constant integer dum1_id = 'e006' //dummy unit 1 id private constant integer dum2_id = 'e005' //dummy unit 2 id private constant real sub_int = 1. //interval to create meteors at (how often they occur in seconds) private constant real area = 500. //area in which the meteor may fall to, around the tower //needed variables private timer subT = CreateTimer() private group mainG = CreateGroup() private boolean timer_on = false endglobals //get correct dummy private function get_dummy takes integer towerid returns integer if towerid==unit1_id then return dum1_id else return dum2_id endif endfunction //create meteor for all available towers private function Meteor_Create takes nothing returns nothing local unit u = GetEnumUnit() local integer id = get_dummy(GetUnitTypeId(u)) local real x = GetUnitX(u) local real y = GetUnitY(u) local unit meteor = CreateUnit(GetOwningPlayer(u),id,x,y,0.) call IssuePointOrder(meteor,"attackground",x+GetRandomReal(50.,area)*Cos(GetRandomReal(0.,360.)*bj_DEGTORAD),y+GetRandomReal(50.,area)*Sin(GetRandomReal(0.,360.)*bj_DEGTORAD)) call UnitApplyTimedLife(meteor,'BTLF',1.) set u = null set meteor = null endfunction //remove dead towers/allow meteors to be created for alive ones private function Meteor_Actions2 takes nothing returns nothing //call Msg("Runnin",Player(0)) if FirstOfGroup(mainG)!=null then //call Msg("Go",Player(0)) call ForGroup(mainG,function Meteor_Create) else call PauseTimer(subT) set timer_on = false endif endfunction //remove dead towers from main group private function Meteor_Death_Conditions takes nothing returns boolean local unit u = GetTriggerUnit() if GetUnitTypeId(u)==unit1_id or GetUnitTypeId(u)==unit2_id then //call Msg("Removed",Player(0)) call GroupRemoveUnit(mainG,u) endif set u = null return false endfunction //add entering towers to check private function Meteor_Conditions takes nothing returns boolean return GetUnitTypeId(GetTriggerUnit())==unit1_id or GetUnitTypeId(GetTriggerUnit())==unit2_id endfunction private function Meteor_Actions takes nothing returns nothing //call Msg("Added",Player(0)) call GroupAddUnit(mainG,GetTriggerUnit()) if timer_on==false then call TimerStart(subT,sub_int,true,function Meteor_Actions2) set timer_on = true endif endfunction endscope //=========================================================================== function InitTrig_Meteor takes nothing returns nothing local trigger trig = CreateTrigger() //call TriggerRegisterEnterRectSimple(trig,bj_mapInitialPlayableArea) call TriggerRegisterAnyUnitEventBJ(trig,EVENT_PLAYER_UNIT_UPGRADE_FINISH) call TriggerAddCondition(trig,Condition(function Meteor_Meteor_Conditions)) call TriggerAddAction(trig,function Meteor_Meteor_Actions) set trig = CreateTrigger() call TriggerRegisterAnyUnitEventBJ(trig,EVENT_PLAYER_UNIT_DEATH) call TriggerAddCondition(trig,Condition(function Meteor_Meteor_Death_Conditions)) set trig = null endfunction |
| 08-31-2007, 09:40 PM | #3 |
Your code does not save, is it suitable for vJASS? At any rate, I don't think it is anything related to that. The trigger worked fine when it was event - unit enters playable area. What is causing it to crash is the change in events, but I don't get why. |
| 08-31-2007, 10:15 PM | #4 |
Hmm Pyro, it seems that you're testing your luck :) You set private to all the functions, so they only will work inside the scope. Because Meteor_Death_Conditions and Meteor_Actions are needed outside of the scope, they must be public or normal functions. I suggest to make them public just for readability. @Karawasa: My suggestions:
I hope it helps to solve your problem :) |
| 09-01-2007, 01:14 AM | #5 |
Oh... fuck. I was close; I thought you could reference private functions as long as you prefixed them with the scope name... but apparently you must do it to public functions and it can't be done to privates. Dur. |
| 09-02-2007, 01:35 AM | #6 |
Neither me nor emjlr3 can figure out why it crashes with the changed event. Nothing in the code stands out. Again, any help would be appreciated. |
| 09-02-2007, 02:05 AM | #7 |
I have a feeling that the upgrade event may fire when you upgrade something like "Iron Swords" upgrades, not when you upgrade structures to new structures. Try using EVENT_PLAYER_UNIT_CONSTRUCT_FINISH for the event and tell me what happens. |
| 09-02-2007, 02:18 AM | #8 |
I tried the event, it doesn't crash, but it doesn't do anything. I'm pretty sure the event I was using is correct, I believe you are thinking of: EVENT_PLAYER_UNIT_RESEARCH_FINISH |
| 09-02-2007, 08:12 PM | #9 |
im just going to make it work differently, thnx for the help with names Moyack, it will help me down the road still no idea why it crashes..., maybe ill try Grim to see the last function call... |
