I assume you haven't done much in the trigger editor.
If you open up the trigger editor, you find that there has already been made a trigger for you called "Melee Initialization". Under that you will find a line called "Melee - Set default melee options for all players". If you dont want the standard victory conditions to be in place, delete that line.
Next, to make your own win conditions.. You need to make your own trigger, add a relevant event, probally some conditions, and then to end the game for a player you can use the function
Game - End game in [Victory/Tie/Defeat] for player X ([Show/Hide] dialogs, [Show/Hide] score screen)
If you tell us what victory conditions you want, we could probally be more specific about a solution.
Thanks for the reply. Yeah I was just starting to look into the triggers when I had to run out for an appointment this afternoon. You are right, however, that I've had very little experience with triggers thus far, though I've managed to implement a few items using them yesterday, so I'm starting to see how they work. It was a difficult mental leap to not want to development them in code instead of the pseudo-code that GE seems to push you towards. ;)
My victory condition is this: The player who solely occupies a region at the end of a Timer wins. If at the end of the timer there are more players in the region then 1, it goes into overtime sudden death and the first player who is the only occupant of that region wins.
A little History:
In the Warcraft editor, the entire scripting was done with triggers and such. But there was a script language called "Jass" and each trigger function called a corresponding function in "jass". At some point in time, as a mapper you were given the choise wheter you want to use the trigger editor's "pseudo-code" or actual jass code. I have little doubt that it will be the same for GE at some point. So if you are more the typing kind of guy, just sit back.
Enough History.
I take from your post that you do have some scripting experience. That's good.
The Trigger editor basicly works the same way as any programming language for the most part.
There are different kinds of functions. All Functions can take parameters and have local variables.
There's things called "Action Definitions" These are basically sub-functions. They perform a squence of actions.
Then there's "Condition Definitions" Those are basically functions with the return type "boolean". These can be use as conditions.
Then there's Triggers. Those are your scripts connection to the game.
Trigger have Events, Conditons and actions. Simply put, if the event starts and the conditions are met, the actions are fired.
That's enough for now, getting weary xD
So on to the problem.
If we forget about sudden death for now its easy:
I dont care how you set up your data system. But you will obviously need a variable for the timer.
Var MyTimer:timer
Var MyRegion:Region
Trigger: Main Round
Event: Timer MyTimer expires
Condition:
Local Variables:
p: integer
winner: integer
foundOne: boolean
Action:
For Each Player (p) in (All Players) Do
- if (HasAUnitInRegion(p))
- - then if(foundOne) /* if we found one and now found annother, means theres no winner yet */
- - - then < Sudden Death Placeholder >; Skip Remaining Actions
- - - else set winner = p; set foundOne = true
- - else
/* (End Loop) <- the end will be obvious in the editor */
/* if we get to this point, we have a winner */
VictoryFunction(winner)
:::::::::::::::::::::::::::::::::::::::::::::::::::::::
Condition Definition: HasAUnitInRegion
Parameters: p: integer
Local Variables: u: Unit
Actions:
For Each Unit (u) in (Units in Region (MyRegion)) Do
- if (Owner of (u)) == p
- - then Return true
- - else
/* (End Loop) <- the end will be obvious in the editor */
return false
:::::::::::::::::::::::::::::::::::::::::::::::::::::::
Action Definition: VictoryFunction
Parameters: winner: integer
Local Variables: p: integer
Actions:
For Each Player (p) in (All Players) Do
- if (p == winner)
- - then End Game For (p) in Victory (.....)
- - else End Game For (p) in Defeat (.....)
:::::::::::::::::::::::::::::::::::::::::::::::::::::::
Normally I'd explain stuff but I think you get this as a scripter. When you have that, we'll care about sudden death. No more time to write right now.
Thanks a bunch for your help! I get your logic and follow the pseudo-code and I'm starting to get how to implement this as a trigger in the editor. I'm having some difficulty, however, finding how to implement "HasUnitInRegion(p)" in the editor. This should be a condition in the If Then statement right?
Currently I have the following:
Event:
Timer - Game Timer expires
Local Variables:
p = 0<Integer>
winner = 0 <Integer>
foundOne = false <Boolean>
Conditions:
None
Actions:
Player Group - For each player p in (All players) do (Actions)
- Actions
- - General - If (Conditions) then do (Actions) else do (Actions)
- - - If /* This is where I'm stumped */
- - - Then
- - - - If (foundOne)
- - - - - Then -Sudden Death Placeholder
- - - - - Else
- - - - - - Variable - Set winner = p
- - - - - - Variable - Set foundOne = true
- - - - Else
Well and for the Sudden death I would advise this:
Trigger: Sudden Death (Initially OFF!)
Events:
Any Unit Leaves MyRegion
Any Unit Dies
Condition:
Local Variables:
p: integer
winner: integer
foundOne: boolean
Action:
For Each Player (p) in (All Players) Do
- if (HasAUnitInRegion(p))
- - then if(foundOne)
- - - then skip remaining actions
- - - else set winner = p; set foundOne = true
- - else
VictoryFunction(winner)
::::::::::::::::::::::::::::::::::
Then in the Placeholder it should say:
Turn Trigger (Sudden Death) On.
What I do is set up a trigger for each set of variables that = and end game sequence.
So say if timer runs out and player 1 has so many units in region 1 and player 1 has more than 50 minerals, then fade out instantly, kill all units, create a bunker for player 1, and then set default melee options.
You can maybe do something similar.
I don't know though. I'm just into hard core basics done awesome.
What I do is set up a trigger for each set of variables that = and end game sequence.
So say if timer runs out and player 1 has so many units in region 1 and player 1 has more than 50 minerals, then fade out instantly, kill all units, create a bunker for player 1, and then set default melee options.
You can maybe do something similar.
I don't know though. I'm just into hard core basics done awesome.
No offense but that solution is very poor.
It will always just be a black screen upon both victory and defeat.
It doesn't allow you to set up what victory or defeat looks like.
For instance in my map, upon defeat I zoom out the camera and let the player see his base overrun by enemies. There is also a transmission saying stuff like "this is our doom".
And if the player wants to, he can press "return to game" and see what status it was in before he lost.
All of these things are not possible with your solution. Victory and defeat will both look boring.
Okay so I'm having some trouble "HasUnitInRegion" condition definition.
You suggested...
"For Each Unit (u) in (Units in Region (MyRegion)) Do"
but the closest thing I could figure out was...
"Unit Group - For each unit u in (Any units in Win Region owned by player Any Player matching Excluded: Missile, Dead, Hidden, with at most Any Amount) do (Actions)"
Do I have to create a condition definition for "UnitsInRegion" as well?
In any event, the result has been a defeat for the player even if they have units in the region. What am I missing?
I haven't read the other replys, but I have been working on a king of the hill map recently and I had to do a similar thing in terms of working out when players were and wern't in a region...
I think this might help you...
Make a global variable of type integer for each player. Call it something like "Unit Count Player 1, Unit Count Player 2" etc
then set up a trigger that says each time a unit owned by player 1 enters the region add 1 to that players unit count. Then you need a trigger that says if a unit owned by player 1 leaves that region minus 1 from that players unit count. Finally you need a tigger that says if a unit dies in that region then minus 1 from that players unit count...
What this effectivly means is that the varible "Unit count" for each player will always store the number of units they have in the region. So once the timer reaches 0 you could say if player 1 unit count > 0 and player 2 unit count = 0 then player one wins. Obviously there would be a few if then statements for each different senario that could play out when the timer reaches 0...
I dunno if I made that sound a lot more complicated then it actually is, but if you need anymore help let me know..
Okay so I'm having some trouble "HasUnitInRegion" condition definition.
You suggested...
"For Each Unit (u) in (Units in Region (MyRegion)) Do"
but the closest thing I could figure out was...
"Unit Group - For each unit u in (Any units in Win Region owned by player Any Player matching Excluded: Missile, Dead, Hidden, with at most Any Amount) do (Actions)"
Do I have to create a condition definition for "UnitsInRegion" as well?
In any event, the result has been a defeat for the player even if they have units in the region. What am I missing?
Thats the right function you found. I just shortened it. The entire any player and exluded stuff is standard.
It should actually work.
Can you show us the code you have right now? Including the HasAUnitInRegion Condition definition in particular.
@James7285: Go
You're sulotion should work, but its takes some more memory space than mine.
SouLCarveRR's suggenstion is right. "Number of units in region matching conditions" is an integer return type function. So you need to look into integer functions to find it.
Sure here is what we have so far...
Variables:
Win Region = Region 001 <Region>
_winner = 0 <Integer>
Trigger: Determine Winner
:::::::::::::::::::::::::::::::::::::::::::::
Determine Winner
Events
Timer - GameTimer expires
Local Variables
p = 0 <Integer>
foundOne = false <Boolean>
Conditions
Actions
Player Group - For each player p in (All players) do (Actions)
Actions
General - If (Conditions) then do (Actions) else do (Actions)
If
HasUnitInRegion(p)
Then
General - If (Conditions) then do (Actions) else do (Actions)
If
foundOne == true
Then
Trigger - Turn Sudden Death On
Else
Variable - Set _winner = p
Variable - Set foundOne = true
Else
VictoryFunction(_winner)
Condition Definition: HasUnitInRegion
::::::::::::::::::::::::::::::::::::::::::::::::::::::::
HasUnitInRegion
Options: Condition
Return Type: Boolean
Parameters
p = 0 <Integer>
Grammar Text: HasUnitInRegion(p)
Hint Text: (None)
Custom Script Code
Local Variables
lv = false <Boolean>
u = Any Unit <Unit>
Actions
Unit Group - For each unit u in (Any units in Win Region owned by player Any Player matching Excluded: Air, Missile, Dead, Hidden, with at most Any Amount) do (Actions)
Actions
General - If (Conditions) then do (Actions) else do (Actions)
If
(Owner of u) == p
Then
Variable - Set lv = true
Else
General - Return lv
Function: VictoryFunction
::::::::::::::::::::::::::::::::::::::::::
HasUnitInRegion
Options: Condition
Return Type: Boolean
Parameters
p = 0 <Integer>
Grammar Text: HasUnitInRegion(p)
Hint Text: (None)
Custom Script Code
Local Variables
lv = false <Boolean>
u = Any Unit <Unit>
Actions
Unit Group - For each unit u in (Any units in Win Region owned by player Any Player matching Excluded: Air, Missile, Dead, Hidden, with at most Any Amount) do (Actions)
Actions
General - If (Conditions) then do (Actions) else do (Actions)
If
(Owner of u) == p
Then
Variable - Set lv = true
Else
General - Return lv
Trigger: Sudden Death (initially off)
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::
Sudden Death
Events
Unit - Any Unit dies
Unit - Any Unit Leaves Region 001
Local Variables
p = 0 <Integer>
winner = 0 <Integer>
foundOne = false <Boolean>
Conditions
Actions
Player Group - For each player p in (All players) do (Actions)
Actions
General - If (Conditions) then do (Actions) else do (Actions)
If
HasUnitInRegion(p)
Then
General - If (Conditions) then do (Actions) else do (Actions)
If
foundOne == true
Then
General - Skip remaining actions
Else
Variable - Set winner = p
Variable - Set foundOne = true
Else
VictoryFunction(winner)
Eureka! We've gotten it to work. It turns out that if there are any Neutral player units in the region, they would give us false feedback on our test runs. Also, more importantly, there was a missing line in the Determine Winner Trigger that was causing some hick-ups that we found and fixed. So all it good for the moment. Now on to playtesting! Thanks guys and kudos to Xelaran for helping us with the pseudo-code scripting!
Can someone point me to a reference about how to change win conditions?
I assume you haven't done much in the trigger editor.
If you open up the trigger editor, you find that there has already been made a trigger for you called "Melee Initialization". Under that you will find a line called "Melee - Set default melee options for all players". If you dont want the standard victory conditions to be in place, delete that line.
Next, to make your own win conditions.. You need to make your own trigger, add a relevant event, probally some conditions, and then to end the game for a player you can use the function
Game - End game in [Victory/Tie/Defeat] for player X ([Show/Hide] dialogs, [Show/Hide] score screen)
If you tell us what victory conditions you want, we could probally be more specific about a solution.
@SBeier: Go
Thanks for the reply. Yeah I was just starting to look into the triggers when I had to run out for an appointment this afternoon. You are right, however, that I've had very little experience with triggers thus far, though I've managed to implement a few items using them yesterday, so I'm starting to see how they work. It was a difficult mental leap to not want to development them in code instead of the pseudo-code that GE seems to push you towards. ;)
My victory condition is this: The player who solely occupies a region at the end of a Timer wins. If at the end of the timer there are more players in the region then 1, it goes into overtime sudden death and the first player who is the only occupant of that region wins.
Sounds pretty simple. ;)
Thanks for your help. -z
@zenasprime: Go
A little History:
In the Warcraft editor, the entire scripting was done with triggers and such. But there was a script language called "Jass" and each trigger function called a corresponding function in "jass". At some point in time, as a mapper you were given the choise wheter you want to use the trigger editor's "pseudo-code" or actual jass code. I have little doubt that it will be the same for GE at some point. So if you are more the typing kind of guy, just sit back.
Enough History.
I take from your post that you do have some scripting experience. That's good.
The Trigger editor basicly works the same way as any programming language for the most part.
There are different kinds of functions. All Functions can take parameters and have local variables.
There's things called "Action Definitions" These are basically sub-functions. They perform a squence of actions.
Then there's "Condition Definitions" Those are basically functions with the return type "boolean". These can be use as conditions.
Then there's Triggers. Those are your scripts connection to the game.
Trigger have Events, Conditons and actions. Simply put, if the event starts and the conditions are met, the actions are fired.
That's enough for now, getting weary xD
So on to the problem.
If we forget about sudden death for now its easy:
I dont care how you set up your data system. But you will obviously need a variable for the timer.
Var MyTimer:timer
Var MyRegion:Region
Trigger: Main Round
Event: Timer MyTimer expires
Condition:
Local Variables:
p: integer
winner: integer
foundOne: boolean
Action:
For Each Player (p) in (All Players) Do
- if (HasAUnitInRegion(p))
- - then if(foundOne) /* if we found one and now found annother, means theres no winner yet */
- - - then < Sudden Death Placeholder >; Skip Remaining Actions
- - - else set winner = p; set foundOne = true
- - else
/* (End Loop) <- the end will be obvious in the editor */
/* if we get to this point, we have a winner */
VictoryFunction(winner)
:::::::::::::::::::::::::::::::::::::::::::::::::::::::
Condition Definition: HasAUnitInRegion
Parameters: p: integer
Local Variables: u: Unit
Actions:
For Each Unit (u) in (Units in Region (MyRegion)) Do
- if (Owner of (u)) == p
- - then Return true
- - else
/* (End Loop) <- the end will be obvious in the editor */
return false
:::::::::::::::::::::::::::::::::::::::::::::::::::::::
Action Definition: VictoryFunction
Parameters: winner: integer
Local Variables: p: integer
Actions:
For Each Player (p) in (All Players) Do
- if (p == winner)
- - then End Game For (p) in Victory (.....)
- - else End Game For (p) in Defeat (.....)
:::::::::::::::::::::::::::::::::::::::::::::::::::::::
Normally I'd explain stuff but I think you get this as a scripter. When you have that, we'll care about sudden death. No more time to write right now.
Thanks a bunch for your help! I get your logic and follow the pseudo-code and I'm starting to get how to implement this as a trigger in the editor. I'm having some difficulty, however, finding how to implement "HasUnitInRegion(p)" in the editor. This should be a condition in the If Then statement right?
Currently I have the following:
Event:
Timer - Game Timer expires
Local Variables:
p = 0<Integer>
winner = 0 <Integer>
foundOne = false <Boolean>
Conditions:
None
Actions:
Player Group - For each player p in (All players) do (Actions)
- Actions
- - General - If (Conditions) then do (Actions) else do (Actions)
- - - If /* This is where I'm stumped */
- - - Then
- - - - If (foundOne)
- - - - - Then
-Sudden Death Placeholder- - - - - Else
- - - - - - Variable - Set winner = p
- - - - - - Variable - Set foundOne = true
- - - - Else
@zenasprime: Go
I think I figured it out. I'll report back tomorrow. ;)
Thanks guys.
@zenasprime: Go
Well and for the Sudden death I would advise this:
Trigger: Sudden Death (Initially OFF!)
Events:
Any Unit Leaves MyRegion
Any Unit Dies
Condition:
Local Variables:
p: integer
winner: integer
foundOne: boolean
Action:
For Each Player (p) in (All Players) Do
- if (HasAUnitInRegion(p))
- - then if(foundOne)
- - - then skip remaining actions
- - - else set winner = p; set foundOne = true
- - else
VictoryFunction(winner)
::::::::::::::::::::::::::::::::::
Then in the Placeholder it should say:
Turn Trigger (Sudden Death) On.
What I do is set up a trigger for each set of variables that = and end game sequence.
So say if timer runs out and player 1 has so many units in region 1 and player 1 has more than 50 minerals, then fade out instantly, kill all units, create a bunker for player 1, and then set default melee options.
You can maybe do something similar.
I don't know though. I'm just into hard core basics done awesome.
No offense but that solution is very poor.
It will always just be a black screen upon both victory and defeat.
It doesn't allow you to set up what victory or defeat looks like.
For instance in my map, upon defeat I zoom out the camera and let the player see his base overrun by enemies. There is also a transmission saying stuff like "this is our doom".
And if the player wants to, he can press "return to game" and see what status it was in before he lost.
All of these things are not possible with your solution. Victory and defeat will both look boring.
@Xelaran: Go
Okay so I'm having some trouble "HasUnitInRegion" condition definition.
You suggested...
"For Each Unit (u) in (Units in Region (MyRegion)) Do"
but the closest thing I could figure out was...
"Unit Group - For each unit u in (Any units in Win Region owned by player Any Player matching Excluded: Missile, Dead, Hidden, with at most Any Amount) do (Actions)"
Do I have to create a condition definition for "UnitsInRegion" as well?
In any event, the result has been a defeat for the player even if they have units in the region. What am I missing?
@zenasprime: Go
Bumping cause were still stumped! (see above post) :(
@zenasprime: Go
I haven't read the other replys, but I have been working on a king of the hill map recently and I had to do a similar thing in terms of working out when players were and wern't in a region...
I think this might help you...
Make a global variable of type integer for each player. Call it something like "Unit Count Player 1, Unit Count Player 2" etc
then set up a trigger that says each time a unit owned by player 1 enters the region add 1 to that players unit count. Then you need a trigger that says if a unit owned by player 1 leaves that region minus 1 from that players unit count. Finally you need a tigger that says if a unit dies in that region then minus 1 from that players unit count...
What this effectivly means is that the varible "Unit count" for each player will always store the number of units they have in the region. So once the timer reaches 0 you could say if player 1 unit count > 0 and player 2 unit count = 0 then player one wins. Obviously there would be a few if then statements for each different senario that could play out when the timer reaches 0...
I dunno if I made that sound a lot more complicated then it actually is, but if you need anymore help let me know..
@James7285: Go
Or you can just do ..... Number of units in regions matching conditions....
@SouLCarveRR: Go
I couldn't find any triggers relating to that.
I'm pretty new to a lot of this myself tho :)
Thats the right function you found. I just shortened it. The entire any player and exluded stuff is standard.
It should actually work.
Can you show us the code you have right now? Including the HasAUnitInRegion Condition definition in particular.
@James7285: Go You're sulotion should work, but its takes some more memory space than mine.
SouLCarveRR's suggenstion is right. "Number of units in region matching conditions" is an integer return type function. So you need to look into integer functions to find it.
@Xelaran: Go
Sure here is what we have so far...
Variables:
Win Region = Region 001 <Region>
_winner = 0 <Integer>
Trigger: Determine Winner
:::::::::::::::::::::::::::::::::::::::::::::
Determine Winner
Events
Timer - GameTimer expires
Local Variables
p = 0 <Integer>
foundOne = false <Boolean>
Conditions
Actions
Player Group - For each player p in (All players) do (Actions)
Actions
General - If (Conditions) then do (Actions) else do (Actions)
If
HasUnitInRegion(p)
Then
General - If (Conditions) then do (Actions) else do (Actions)
If
foundOne == true
Then
Trigger - Turn Sudden Death On
Else
Variable - Set _winner = p
Variable - Set foundOne = true
Else
VictoryFunction(_winner)
Condition Definition: HasUnitInRegion
::::::::::::::::::::::::::::::::::::::::::::::::::::::::
HasUnitInRegion
Options: Condition
Return Type: Boolean
Parameters
p = 0 <Integer>
Grammar Text: HasUnitInRegion(p)
Hint Text: (None)
Custom Script Code
Local Variables
lv = false <Boolean>
u = Any Unit <Unit>
Actions
Unit Group - For each unit u in (Any units in Win Region owned by player Any Player matching Excluded: Air, Missile, Dead, Hidden, with at most Any Amount) do (Actions)
Actions
General - If (Conditions) then do (Actions) else do (Actions)
If
(Owner of u) == p
Then
Variable - Set lv = true
Else
General - Return lv
Function: VictoryFunction
::::::::::::::::::::::::::::::::::::::::::
HasUnitInRegion
Options: Condition
Return Type: Boolean
Parameters
p = 0 <Integer>
Grammar Text: HasUnitInRegion(p)
Hint Text: (None)
Custom Script Code
Local Variables
lv = false <Boolean>
u = Any Unit <Unit>
Actions
Unit Group - For each unit u in (Any units in Win Region owned by player Any Player matching Excluded: Air, Missile, Dead, Hidden, with at most Any Amount) do (Actions)
Actions
General - If (Conditions) then do (Actions) else do (Actions)
If
(Owner of u) == p
Then
Variable - Set lv = true
Else
General - Return lv
Trigger: Sudden Death (initially off)
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::
Sudden Death
Events
Unit - Any Unit dies
Unit - Any Unit Leaves Region 001
Local Variables
p = 0 <Integer>
winner = 0 <Integer>
foundOne = false <Boolean>
Conditions
Actions
Player Group - For each player p in (All players) do (Actions)
Actions
General - If (Conditions) then do (Actions) else do (Actions)
If
HasUnitInRegion(p)
Then
General - If (Conditions) then do (Actions) else do (Actions)
If
foundOne == true
Then
General - Skip remaining actions
Else
Variable - Set winner = p
Variable - Set foundOne = true
Else
VictoryFunction(winner)
Eureka! We've gotten it to work. It turns out that if there are any Neutral player units in the region, they would give us false feedback on our test runs. Also, more importantly, there was a missing line in the Determine Winner Trigger that was causing some hick-ups that we found and fixed. So all it good for the moment. Now on to playtesting! Thanks guys and kudos to Xelaran for helping us with the pseudo-code scripting!
-z
How do I make win conditions that are: "The team that no longer has any forces loses."