| 06-20-2006, 02:54 PM | #1 |
I know you can use GetBooleanAnd to use two conditions like the script below. JASS:local integer udg_localinteger if (GetBooleanAnd(udg_TeamHeroBoolean[localinteger]==true, IsUnitAliveBJ(udg_TeamHero[localinteger]))) then //blah blah actions endif The above script worked fine no compile errors. I've looked but cannot find how to use more than two conditions in a if/then. I'm using as much custom text to clean up my triggers and converting some totally to JASS to better understand it, but I can't figure out how I would go about converting something like the trigger below to JASS. Trigger: Previous posts taught me the editor creates a new function for if/then/else, and I want to get by that, so I can use a local integer variable for every [1] array. If I try to use GetBooleanAnd with more than 2 conditions I get compile errors. My question is, is there more proper method of using multiple conditions? |
| 06-20-2006, 02:58 PM | #2 |
You don't need to use GetBooleanAnd. You can just use 'and' between the two boolean statements. In your example: JASS:if udg_TeamHeroBoolean[localinteger] == true and IsUnitAliveBJ(udg_TeamHero[localinteger]) then //blah blah actions endif You can combine as many statements as you want in this way, eg: JASS:if i == 1 and j == 2 or IsUnitAliveBJ(u) then //actions endif |
| 06-20-2006, 03:38 PM | #3 |
That's a heck of a lot easier than I thought it was gonna be. So, when using any boolean, if you don't specify true or false the game will automatically assume it's true? |
| 06-20-2006, 03:45 PM | #4 |
Well, what actually happens is, i == 1 returns a boolean value (true or false). Saying (i == 1) == true is basically like saying true == true. You need never compare to true and false. JASS:if IsUnitAliveBJ(u) == true //same as if IsUnitAliveBJ(u) JASS:if IsUnitAliveBJ(u) == false //same as if not IsUnitAliveBJ(u) |
| 06-20-2006, 03:45 PM | #5 |
Yes, it will test it against true. |
| 06-20-2006, 04:32 PM | #6 |
So far so good. I am trying to track "TeamHero" which will be the best hero off of a team based on hero kills. A problem is if a player leaves it is supposed to set the next player's hero on the team as the team hero, so it's not lost unless a whole team is empty. JASS://Player 1 Leaves if udg_Hero[1]==udg_TeamHero[1] and GetPlayerSlotState(Player(2))==PLAYER_SLOT_STATE_PLAYING then set udg_TeamHero[1] = udg_Hero[2] endif if udg_Hero[1]==udg_TeamHero[1] and GetPlayerSlotState(Player(2))==PLAYER_SLOT_STATE_EMPTY and GetPlayerSlotState(Player(3))==PLAYER_SLOT_STATE_PLAYING then set udg_TeamHero[1] = udg_Hero[3] endif if udg_Hero[1]==udg_TeamHero[1] and GetPlayerSlotState(Player(2))==PLAYER_SLOT_STATE_EMPTY and GetPlayerSlotState(Player(3))==PLAYER_SLOT_STATE_EMPTY then set udg_Hero[1] = null endif The above trigger worked fine. My question is, will PLAYER_SLOT_STATE_EMPTY work if a player has left the game instead of using PLAYER_SLOT_STATE_LEFT? I tried to use an "or" inbetween but it crashed the editor when i tried adding too many ands and ors. Like this below crashed the editor: JASS:if udg_Hero[1]==udg_TeamHero[1] and GetPlayerSlotState(Player(2))==PLAYER_SLOT_STATE_EMPTY or GetPlayerSlotState(Player(2))== PLAYER_SLOT_STATE_LEFT and GetPlayerSlotState(Player(3))==PLAYER_SLOT_STATE_EMPTY or GetPlayerSlotState(Player(3))==PLAYER_SLOT_STATE_LEFT then Edit: Also, I'm not converting the whole trigger to JASS. It may have crashed because of trying to use too many ands and ors in a custom script line. IDK if this is the reason it crashed but I'm gonna test it now. |
| 06-20-2006, 04:58 PM | #7 |
For the sake of clarity, try to separate each respective and and or within parentheses. It even helps the interpreter/compiler to get the priority between each boolean evaluation. Like this: JASS:udg_Hero[1]==udg_TeamHero[1] and (GetPlayerSlotState(Player(2))==PLAYER_SLOT_STATE_EMPTY or GetPlayerSlotState(Player(2))== PLAYER_SLOT_STATE_LEFT) and (GetPlayerSlotState(Player(3))==PLAYER_SLOT_STATE_EMPTY or GetPlayerSlotState(Player(3))==PLAYER_SLOT_STATE_LEFT) And, you could put an evaluation in a function in any case. Like: JASS:function PlayerGone takes integer which returns boolean return (GetPlayerSlotState(Player(which))==PLAYER_SLOT_STATE_EMPTY or GetPlayerSlotState(Player(which))== PLAYER_SLOT_STATE_LEFT) endfunction ... if udg_Hero[1]==udg_TeamHero[1] and PlayerGone(2) and PlayerGone(3) then |
| 06-20-2006, 05:01 PM | #8 |
Well, you need brackets i would say. Instead of having: JASS:if(Something and Something or SomethingElse and SomethingElse Do: JASS:if(Something and Something) or (SomethingElse and SomethingElse) BTW: In your trigger, i slightly changed it to be more efficent Old Trigger://Player 1 Leaves if udg_Hero[1]==udg_TeamHero[1] and GetPlayerSlotState(Player(2))==PLAYER_SLOT_STATE_PLAYING then set udg_TeamHero[1] = udg_Hero[2] endif if udg_Hero[1]==udg_TeamHero[1] and GetPlayerSlotState(Player(2))==PLAYER_SLOT_STATE_EMPTY and GetPlayerSlotState(Player(3))==PLAYER_SLOT_STATE_PLAYING then set udg_TeamHero[1] = udg_Hero[3] endif if udg_Hero[1]==udg_TeamHero[1] and GetPlayerSlotState(Player(2))==PLAYER_SLOT_STATE_EMPTY and GetPlayerSlotState(Player(3))==PLAYER_SLOT_STATE_EMPTY then set udg_Hero[1] = null endif New Trigger://Player 1 Leaves if udg_Hero[1]==udg_TeamHero[1] and GetPlayerSlotState(Player(2))==PLAYER_SLOT_STATE_PLAYING then set udg_TeamHero[1] = udg_Hero[2] elseif udg_Hero[1]==udg_TeamHero[1] and GetPlayerSlotState(Player(2))==PLAYER_SLOT_STATE_EMPTY and GetPlayerSlotState(Player(3))==PLAYER_SLOT_STATE_PLAYING then set udg_TeamHero[1] = udg_Hero[3] elseif udg_Hero[1]==udg_TeamHero[1] and GetPlayerSlotState(Player(2))==PLAYER_SLOT_STATE_EMPTY and GetPlayerSlotState(Player(3))==PLAYER_SLOT_STATE_EMPTY then set udg_Hero[1] = null endif |
| 06-20-2006, 06:37 PM | #10 |
Apparently, yes. A little stuff could be furtehr optimized, like: JASS://Further ispenction lead me to believe PlayerIsActive should be more logical and slightly faster than PlayerGone function PlayerIsActive takes integer A returns boolean return (GetPlayerSlotState(Player(A))==PLAYER_SLOT_STATE_PLAYING) endfunction function Trig_Player_1_Leaves_Copy_Conditions takes nothing returns boolean if ( (not(udg_Defeat[1])) and not(PlayerIsActive(0) )then return true endif return false endfunction //I know there must be a way this function could get rid of. Sadly, don't remember how... :( function KillEnumUnit takes nothing returns nothing call KillUnit( GetEnumUnit() ) endfunction function Trig_Player_1_Leaves_Copy_Actions takes nothing returns nothing local group TempGroup //no need for a global, I guess set udg_Hero[1] = null //if you are setting it here to null, why are you comparing it later? set TempGroup = GetUnitsOfPlayerAll(Player(0)) call ForGroupBJ( TempGroup, function KillEnumUnit ) call DestroyGroup( TempGroup ) call MultiboardSetItemValueBJ( udg_Multiboard, 1, 2, ( "|CFFFF0000" + "*Left/Defeated*|r" ) ) call DisplayTextToForce( GetPlayersAll(), ( GetPlayerName(Player(0)) + " has left the game." ) ) call ForceRemovePlayerSimple( Player(0), udg_ForceOne ) if udg_Hero[1]==udg_TeamHero[1] then if PlayerIsActive(1) then set udg_TeamHero[1] = udg_Hero[2] elseif PlayerIsActive(2) then set udg_TeamHero[1] = udg_Hero[3] else set udg_TeamHero[1] = null endif endif set udg_AliveHeroes = ( udg_AliveHeroes - 1 ) //shouldn't this be affected despite whatever happened in the conditions? call TriggerExecute( gg_trg_RemoveShopsNoPlayer ) call TriggerExecute( gg_trg_Victory ) call DestroyTrigger( GetTriggeringTrigger() ) endfunction //=========================================================================== function InitTrig_Player_1_Leaves_Copy takes nothing returns nothing set gg_trg_Player_1_Leaves_Copy = CreateTrigger( ) call TriggerRegisterTimerEventPeriodic( gg_trg_Player_1_Leaves_Copy, 5.00 ) call TriggerAddCondition( gg_trg_Player_1_Leaves_Copy, Condition( function Trig_Player_1_Leaves_Copy_Conditions ) ) call TriggerAddAction( gg_trg_Player_1_Leaves_Copy, function Trig_Player_1_Leaves_Copy_Actions ) endfunction I must be missing a lot of stuff, so don't take this for granted |
| 06-20-2006, 07:20 PM | #11 |
That works fine, and it's a bit cleaner. As for your concerns: I remember reading about getting rid of the "KillEnumUnit" function using a "FirstOfGoup" loop or another, I might add that in after I get this all straightened out. Setting Hero[#] to null was my mistake, I realized that after posting. It shouldn't be set to null until the end of the trigger. AliveHeroes is to keep track of the ammount of team heroes in the game, and is tracked in many other triggers. When a player reaches that first hero kill, it adds +1 only one time per team in another trigger (for only a total of 4), and it has to remove one permanently if an entire team is gone. So, if the last person on a force leaves, it only subtracts it then, which is why it subtracts only if the other 2 players are gone. I'm pretty sure there is no problem thus far with the way it's being tracked. Thank you all for your help, I think I'm good to go now. |
| 06-20-2006, 08:05 PM | #12 |
To get rid of the extra Enum function, you cant use ForGroup, you would just have to kill them all yourself using a loop and a local unit variable, like this: JASS:local group TempGroup local unit CurrentUnit loop set CurrentUnit = FirstOfGroup(TempGroup) exitwhen CurrentUnit == null // All Your actions you want to happen here. call KillUnit(CurrentUnit) call GroupRemoveUnit(TempGroup, CurrentUnit) endloop call DestroyGroup(TempGroup) set TempGroup = null In your case, you could change your code to: (Im using Alevice's optimizedish code because im lazy)://Further ispenction lead me to believe PlayerIsActive should be more logical and slightly faster than PlayerGone function PlayerIsActive takes integer A returns boolean return (GetPlayerSlotState(Player(A))==PLAYER_SLOT_STATE_PLAYING) endfunction function Trig_Player_1_Leaves_Copy_Conditions takes nothing returns boolean if ( (not(udg_Defeat[1])) and not(PlayerIsActive(0) )then return true endif return false endfunction //I know there must be a way this function could get rid of. Sadly, don't remember how... :( function Trig_Player_1_Leaves_Copy_Actions takes nothing returns nothing local group TempGroup //no need for a global, I guess local unit TempUnit set udg_Hero[1] = null //if you are setting it here to null, why are you comparing it later? set TempGroup = GetUnitsOfPlayerAll(Player(0)) loop set TempUnit = FirstOfGroup(TempGroup) exitwhen(TempUnit == null) call KillUnit(TempUnit) call GroupRemoveUnit(TempGroup, TempUnit) endloop call DestroyGroup( TempGroup ) call MultiboardSetItemValueBJ( udg_Multiboard, 1, 2, ( "|CFFFF0000" + "*Left/Defeated*|r" ) ) call DisplayTextToForce( GetPlayersAll(), ( GetPlayerName(Player(0)) + " has left the game." ) ) call ForceRemovePlayerSimple( Player(0), udg_ForceOne ) if udg_Hero[1]==udg_TeamHero[1] then if PlayerIsActive(1) then set udg_TeamHero[1] = udg_Hero[2] elseif PlayerIsActive(2) then set udg_TeamHero[1] = udg_Hero[3] else set udg_TeamHero[1] = null endif endif set udg_AliveHeroes = ( udg_AliveHeroes - 1 ) //shouldn't this be affected despite whatever happened in the conditions? call TriggerExecute( gg_trg_RemoveShopsNoPlayer ) call TriggerExecute( gg_trg_Victory ) call DestroyTrigger( GetTriggeringTrigger() ) endfunction //=========================================================================== function InitTrig_Player_1_Leaves_Copy takes nothing returns nothing set gg_trg_Player_1_Leaves_Copy = CreateTrigger( ) call TriggerRegisterTimerEventPeriodic( gg_trg_Player_1_Leaves_Copy, 5.00 ) call TriggerAddCondition( gg_trg_Player_1_Leaves_Copy, Condition( function Trig_Player_1_Leaves_Copy_Conditions ) ) call TriggerAddAction( gg_trg_Player_1_Leaves_Copy, function Trig_Player_1_Leaves_Copy_Actions ) endfunction |
