• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[General] Food Max system

Status
Not open for further replies.
Level 18
Joined
Jan 12, 2011
Messages
1,512
Okay so this is the thing.
The map has 12 players, has alliance by command (-ally or -unally)

the trigger i need is like this: You ally someone (and for example your ally group is 2 (you and him) ).

so then your food max (and his food max) goes like this:
300/2 = 150


you unally him (your and his ally group is now 1) and it goes like this:
300/1 = 300


if the division goes like 300/7 it should be something like: 43 or 42 food.


I don't know how to make the trigger but take in mind this:

if you use Player allies it has to be something like player allies +1 since you are counted in the division.


---------
PD: i'm talking about the food max (not food cap)
 
Level 25
Joined
Sep 26, 2009
Messages
2,378
You've made a thread about this once already - http://www.hiveworkshop.com/forums/world-editor-help-zone-98/limiting-food-acording-allies-234743/

Instead of picking all players, you pick all allies of player X (x being the player who wrote the command; note this should be done after your trigger that changes alliance aspects between players).

A side note:
Dynamic groups like that can be used advantage of - like player drops all alliaces so he has max food he can have, built an army and then he creates alliances again, ending up with for example 100/47 food - going way over the limit.
 
Level 18
Joined
Jan 12, 2011
Messages
1,512
You've made a thread about this once already - http://www.hiveworkshop.com/forums/world-editor-help-zone-98/limiting-food-acording-allies-234743/

Instead of picking all players, you pick all allies of player X (x being the player who wrote the command; note this should be done after your trigger that changes alliance aspects between players).

A side note:
Dynamic groups like that can be used advantage of - like player drops all alliaces so he has max food he can have, built an army and then he creates alliances again, ending up with for example 100/47 food - going way over the limit.


Yeah there's always a way to abuse stuff, but i'm not making this trigger for abusers, i'm making it for people who play correctly, players right now can get 300 food each when they are in like 4 man alliance so that's even worse.

--------------

also if i do that won't it just calculate the food / allies? it won't do allies +1 won't it?
 
Level 18
Joined
Jan 12, 2011
Messages
1,512
You need to set aspect of alliance first before you change food max.

Can you post the trigger where you set food max?

I did this is it right?:
  • Player Alliances
    • Events
    • Conditions
    • Actions
      • Set Integer_var = (Integer((300.00 / (Real(((Number of players in (All allies of (Picked player))) + 1))))))
      • Player Group - Pick every player in (All players) and do (Actions)
        • Loop - Actions
          • Player - Set (Picked player) Food max to Integer_var
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
I tested the food max and food cap, but food max for some reason did nothing all the time, food cap changes the maximum usable food you can have however(even if you have buildings for more food)

You should try that

also, the Number of Players in (All allies of (Picked player)) leaks, the All allies of (Picked player) is a force(Player group) which is created every time you call the function, you should store it and then call DestroyForce(udg_var) at the end
 
Level 18
Joined
Jan 12, 2011
Messages
1,512
I tested the food max and food cap, but food max for some reason did nothing all the time, food cap changes the maximum usable food you can have however(even if you have buildings for more food)

You should try that

also, the Number of Players in (All allies of (Picked player)) leaks, the All allies of (Picked player) is a force(Player group) which is created every time you call the function, you should store it and then call DestroyForce(udg_var) at the end

How would i do that? xD

also player max is changed but you need to wait some seconds before it appears in the resource UI (if you put your mouse in top of it you'll read it actually changed)
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
  • Trigger
    • Events
    • Conditions
    • Actions
      • Set f = (All allies of (Picked player))
      • Set i = (Integer((300.00 / ((Real((Number of players in f))) + 1.00))))
      • Player Group - Pick every player in f and do (Actions)
        • Loop - Actions
          • Player - Set (Picked player) Food max to i
      • Custom script: call DestroyForce(udg_f)
you dont need to Pick every players, just pick players in f(the force, in this case allies of Picked Player or who ever that whould be)
 
Level 18
Joined
Jan 12, 2011
Messages
1,512
  • Trigger
    • Events
    • Conditions
    • Actions
      • Set f = (All allies of (Picked player))
      • Set i = (Integer((300.00 / ((Real((Number of players in f))) + 1.00))))
      • Player Group - Pick every player in f and do (Actions)
        • Loop - Actions
          • Player - Set (Picked player) Food max to i
      • Custom script: call DestroyForce(udg_f)
you dont need to Pick every players, just pick players in f(the force, in this case allies of Picked Player or who ever that whould be)

Well thanks it worked perfectly, +rep to both
 
Level 25
Joined
Sep 26, 2009
Messages
2,378
I tested the food max and food cap, but food max for some reason did nothing all the time, food cap changes the maximum usable food you can have however
Food Cap = immediately changes amount of food capacity to your value (unless the number is higher than the one specified in gameplay constants). This number is constant and does not change even if that player builds food-producing buildings.

Food Max = sets the maximum food capacity that player can attain. You still need Food-producing buildings to increase your food capacity, but that number will not go over Food Max value you set.

Basically Food Cap = Food Max in the sense that they both set the maximum Food you can have. However Food Cap sets the capacity immediately to that amount while Food Max doesn't.
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
wellit shouldnt, I checked the BJ and it is creating new force, not using some global one, so it should be safe destroying the group
you could try tho, using Pick every player in Player group and print something to make sure there are players in
 
Level 18
Joined
Jan 12, 2011
Messages
1,512
wellit shouldnt, I checked the BJ and it is creating new force, not using some global one, so it should be safe destroying the group
you could try tho, using Pick every player in Player group and print something to make sure there are players in

also why does your
  • Set Integer_var = (Integer((300.00 / (Real(((Number of players in Playeralliestotal) + 1))))))

Instead of +1 has +1.00? does it have anything to do?
 
Level 25
Joined
Sep 26, 2009
Messages
2,378
In the Real or Integer menu there are Conversion options - like "Conversion - Convert Real to Integer" - this option converts real number to integer number.

Converting Real to Integer will round the number down.
Ex. You have real number 1.89; after conversion the number will be 1.
Real 3.44 will be 3; 95.99 will be 95 and so on.

You already use conversions in this action:
  • Set Integer_var = (Integer((300.00 / (Real((Number of players in Playeralliestotal) + 1))))))
This is how he set the action:
set i = integer(A / (B + C)).

This is how you set the action:
set i = integer(A / (B + C))

The red colored letters are converted integer numbers. As you can see, you converted both letters B and C, while he did only B... that's the reason why C is real number 1.00 in his case and in yours it is integer number 1.
 
Level 18
Joined
Jan 12, 2011
Messages
1,512
Wait don't i need to destroy the integer too? since it's a variable i mean because i still can't find the problem of why it's only usable 1 time and then it stops working, also if a player starts with let's say 150 food and 1 ally and they unally his ally his food goes down to 100 for an unknown reason.
 
Level 18
Joined
Jan 12, 2011
Messages
1,512
Okay since idk how to make 1 trigger for all 12 players i made 12 triggers

Each 1 is like this:
Player red allies:
  • Player Alliances Red
    • Events
      • Player - Player 1 (Red) changes alliance settings
    • Conditions
    • Actions
      • Set Playeralliestotal = (All allies of Player 1 (Red))
      • Set Integer_var = (Integer((300.00 / (Real(((Number of players in Playeralliestotal) + 1))))))
      • Player Group - Pick every player in Playeralliestotal and do (Actions)
        • Loop - Actions
          • Player - Set Player 1 (Red) Food max to Integer_var
      • Custom script: call DestroyForce(udg_Playeralliestotal)
However I do not know this:

Is PlayerAlliesTotal supposed to be an integer or a Player Group type of variable?
Also does it need to have a size? or just empty group (0)?

and also about Integer_var (i suppose this one is an integer right?)
 
Level 25
Joined
Sep 26, 2009
Messages
2,378
Playeralliestotal = unit group. It doesn't have to be array (doesn't have to have size), because you don't store more than group of players (you store them at the start of the trigger and destroy it at the end without any waits)

Integer_var is indeed integer variable.

Atm the only thing I see wrong is that in the group loop you "Set Player 1 (Red) Fodd max to Integer_var"... Instead of Player 1 change it to (Picked player)

I'll try to recreate your trigger and see what I can do with it.
 
Level 18
Joined
Jan 12, 2011
Messages
1,512
Playeralliestotal = unit group. It doesn't have to be array (doesn't have to have size), because you don't store more than group of players (you store them at the start of the trigger and destroy it at the end without any waits)

Integer_var is indeed integer variable.

Atm the only thing I see wrong is that in the group loop you "Set Player 1 (Red) Fodd max to Integer_var"... Instead of Player 1 change it to (Picked player)

I'll try to recreate your trigger and see what I can do with it.

Other 2 things to take into account:

I'm testing in single player (though i'm testing with allied computers)
and another thing is that i also have this trigger at the start to set the players starting food depending of their allies:
  • Allies Food primary
    • Events
      • Time - Elapsed game time is 5.00 seconds
    • Conditions
    • Actions
      • Player - Set Player 1 (Red) Food max to 150
      • Player - Set Player 2 (Blue) Food max to 150
      • Player - Set Player 3 (Teal) Food max to 150
      • Player - Set Player 4 (Purple) Food max to 150
      • Player - Set Player 5 (Yellow) Food max to 150
      • Player - Set Player 6 (Orange) Food max to 150
      • Player - Set Player 7 (Green) Food max to 150
      • Player - Set Player 8 (Pink) Food max to 300
      • Player - Set Player 9 (Gray) Food max to 300
      • Player - Set Player 10 (Light Blue) Food max to 300
      • Player - Set Player 11 (Dark Green) Food max to 150
      • Player - Set Player 12 (Brown) Food max to 300
 
Level 25
Joined
Sep 26, 2009
Messages
2,378
Seems I found the error.

First off, I was wrong, writing that this line:
  • Set Integer_var = (Integer((300.00 / (Real((Number of players in Playeralliestotal) + 1))))))
didn't have any effect (damn brackets confused me). It does have effect.
The actual set up by edo is Food Max = (A / B) + C ... (300 / Allies) + 1, because he wanted to add 1 food for cases like when you have allies of 7 players.
Situation with 7 players looks like this:
(300 / 7) + 1... 300/7 = 42.8 as a real number, and 42 as integer number (it's rounded down), which is why he later adds 42 + 1, to make up for the lost 0.8 food.

However what you have is
300 / (allies + 1). So when you have only 1 player alone, you have 300 / (1+1) => 300 / 2 => 150 Food Max when player is alone.

----------
With the above written, that may explain why did your trigger work only once. It work only once because it recalculated food max for "allies of triggering player" + 1.

The problem is in the player group itself. When I change alliance settings mutually between 2 players and then use either
  • Set PlayerGroup = (All allies of (Triggering player))
or a more complicated
  • Set PlayerGroup = (All players matching (((Matching player) is an ally of (Triggering player)) Equal to True))
that PlayerGroup has only the triggering player in it, not its allies (i.e. there is only 1 player in that group).

Testing further, I found out that for the above actions to work, that player you make ally with has to be either User-controlled (with occupied slot) or Computer-controlled.

So most likely to fix this, you need to have those player slots full (either by player or by computer).

-------------
I don't think I need to post the trigger I used, since the problem lies in player slots not being used and the food max calculation I wrote about at the beggining of this post.
However if you need it, I can post both the trigger and the test map here.
 
Last edited:
Level 23
Joined
Apr 16, 2012
Messages
4,041
PlayerAllies is force(GUI Player Group), how would you store players in unit group?
and yes it can be empty, because the function call will create new group every time

When I get to computer, I will test it and see if it works for me
 
Level 25
Joined
Sep 26, 2009
Messages
2,378
eh, I meant player group. Anyway, I edited my post, because I got an idea what may cause the problem and it did indeed cause it.

Seems the function "allies of player" picks only those players whose player slots are occupied (by either computer or active player).
If that slot is meant for player, but is not used atm, it will not consider that player as ally of triggering player.
 
Level 18
Joined
Jan 12, 2011
Messages
1,512
eh, I meant player group. Anyway, I edited my post, because I got an idea what may cause the problem and it did indeed cause it.

Seems the function "allies of player" picks only those players whose player slots are occupied (by either computer or active player).
If that slot is meant for player, but is not used atm, it will not consider that player as ally of triggering player.

Can you post the trigger i gotta use? i didn't understand what you said xD
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
he means that you should make one custom group for each player(lets say array, you will give it size 12) and use the indexes as players that you want their allies be in

When Player 1 allies Player 3, you update force[0] and force[2], to 0 you add player 3, to 2 you add player 1, if they unally you do the same but remove them

It requires a bit more work to set, but you no longer need to destroy the force(you shouldnt, because you are only adding/removing players from it not creating it all over again, if you destroy such group(like All Players), you will no longer be able to use it)
 
Level 18
Joined
Jan 12, 2011
Messages
1,512
he means that you should make one custom group for each player(lets say array, you will give it size 12) and use the indexes as players that you want their allies be in

When Player 1 allies Player 3, you update force[0] and force[2], to 0 you add player 3, to 2 you add player 1, if they unally you do the same but remove them

It requires a bit more work to set, but you no longer need to destroy the force(you shouldnt, because you are only adding/removing players from it not creating it all over again, if you destroy such group(like All Players), you will no longer be able to use it)

wat i think i need test map or triggers in trigger tags X_X
 
Level 25
Joined
Sep 26, 2009
Messages
2,378
Attached test map.

An important note
I made the whole thing to work with -ally XY and -unally XY commands (XY being number of player you want to create/break alliance with).

However that command system is made for test purpose only, it is by far from complete command system and because of that, if the command is written incorrectly, it either not work, but may also crash your game.

If you want to make it work with command system, I suggest you look and use one of the command systems here on hive (those are fully complete and will not crash your game if command is written incorrectly).

In the test map is an info note that has examples of good and bad commands.


The trigger I used:
  • Food Max
    • Events
      • Player - Player 1 (Red) types a chat message containing -ally as A substring
      • Player - Player 2 (Blue) types a chat message containing -ally as A substring
      • Player - Player 3 (Teal) types a chat message containing -ally as A substring
      • Player - Player 4 (Purple) types a chat message containing -ally as A substring
      • Player - Player 5 (Yellow) types a chat message containing -ally as A substring
      • Player - Player 6 (Orange) types a chat message containing -ally as A substring
      • Player - Player 7 (Green) types a chat message containing -ally as A substring
      • Player - Player 8 (Pink) types a chat message containing -ally as A substring
      • Player - Player 9 (Gray) types a chat message containing -ally as A substring
      • Player - Player 10 (Light Blue) types a chat message containing -ally as A substring
      • Player - Player 11 (Dark Green) types a chat message containing -ally as A substring
      • Player - Player 12 (Brown) types a chat message containing -ally as A substring
      • Player - Player 1 (Red) types a chat message containing -unally as A substring
      • Player - Player 2 (Blue) types a chat message containing -unally as A substring
      • Player - Player 3 (Teal) types a chat message containing -unally as A substring
      • Player - Player 4 (Purple) types a chat message containing -unally as A substring
      • Player - Player 5 (Yellow) types a chat message containing -unally as A substring
      • Player - Player 6 (Orange) types a chat message containing -unally as A substring
      • Player - Player 7 (Green) types a chat message containing -unally as A substring
      • Player - Player 8 (Pink) types a chat message containing -unally as A substring
      • Player - Player 9 (Gray) types a chat message containing -unally as A substring
      • Player - Player 10 (Light Blue) types a chat message containing -unally as A substring
      • Player - Player 11 (Dark Green) types a chat message containing -unally as A substring
      • Player - Player 12 (Brown) types a chat message containing -unally as A substring
    • Conditions
    • Actions
      • Set string = (Entered chat string)
      • -------- ------------------------------------------------------------------------------------------ --------
      • -------- Condition below checks if second and third letter is "AL" to find out if -ally or -unally has been written --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Substring(string, 2, 3)) Equal to al
        • Then - Actions
          • -------- Takes 7th and 8th letter to get number of player you want to ally --------
          • Set int = (Integer((Substring(string, 7, 8))))
          • -------- ------------------------------------------------------------------------------------------ --------
          • -------- ------------------------------------------------------------------------------------------ --------
          • Player - Make (Triggering player) treat (Player(int)) as an Ally with shared vision
          • Player - Make (Player(int)) treat (Triggering player) as an Ally with shared vision
        • Else - Actions
          • -------- Does the same as above, however here we know that the written string is "-unally" --------
          • -------- so we take 9th and 10th letter to find out player's number --------
          • Set int = (Integer((Substring(string, 9, 10))))
          • Player - Make (Triggering player) treat (Player(int)) as an Enemy
          • -------- ------------------------------------------------------------------------------------------ --------
          • -------- ------------------------------------------------------------------------------------------ --------
          • Player - Make (Player(int)) treat (Triggering player) as an Enemy
      • Set string = <Empty String>
      • Set allies = (All allies of (Triggering player))
      • Set int = (Integer((300.00 / (Real((Number of players in allies))))))
      • Player Group - Pick every player in allies and do (Actions)
        • Loop - Actions
          • Player - Set (Picked player) Food max to int
          • -------- ---------------------------------------------------------------------- --------
          • -------- Adding 1 used Food and then subtracting it will actualize Food Max --------
          • -------- if your current Food Max is higher than the calculated value "int" --------
          • Player - Set (Picked player) Food used to (((Picked player) Food used) + 1)
          • Player - Set (Picked player) Food used to (((Picked player) Food used) - 1)
      • -------- ---------------------------------------------------------------------- --------
      • -------- ---------------------------------------------------------------------- --------
      • -------- ---------------------------------------------------------------------- --------
      • -------- Clear leaks --------
      • Custom script: call DestroyForce(udg_allies)
 

Attachments

  • FoodMax.w3x
    21.3 KB · Views: 57
Level 18
Joined
Jan 12, 2011
Messages
1,512
Attached test map.

An important note
I made the whole thing to work with -ally XY and -unally XY commands (XY being number of player you want to create/break alliance with).

However that command system is made for test purpose only, it is by far from complete command system and because of that, if the command is written incorrectly, it either not work, but may also crash your game.

If you want to make it work with command system, I suggest you look and use one of the command systems here on hive (those are fully complete and will not crash your game if command is written incorrectly).

In the test map is an info note that has examples of good and bad commands.


The trigger I used:
  • Food Max
    • Events
      • Player - Player 1 (Red) types a chat message containing -ally as A substring
      • Player - Player 2 (Blue) types a chat message containing -ally as A substring
      • Player - Player 3 (Teal) types a chat message containing -ally as A substring
      • Player - Player 4 (Purple) types a chat message containing -ally as A substring
      • Player - Player 5 (Yellow) types a chat message containing -ally as A substring
      • Player - Player 6 (Orange) types a chat message containing -ally as A substring
      • Player - Player 7 (Green) types a chat message containing -ally as A substring
      • Player - Player 8 (Pink) types a chat message containing -ally as A substring
      • Player - Player 9 (Gray) types a chat message containing -ally as A substring
      • Player - Player 10 (Light Blue) types a chat message containing -ally as A substring
      • Player - Player 11 (Dark Green) types a chat message containing -ally as A substring
      • Player - Player 12 (Brown) types a chat message containing -ally as A substring
      • Player - Player 1 (Red) types a chat message containing -unally as A substring
      • Player - Player 2 (Blue) types a chat message containing -unally as A substring
      • Player - Player 3 (Teal) types a chat message containing -unally as A substring
      • Player - Player 4 (Purple) types a chat message containing -unally as A substring
      • Player - Player 5 (Yellow) types a chat message containing -unally as A substring
      • Player - Player 6 (Orange) types a chat message containing -unally as A substring
      • Player - Player 7 (Green) types a chat message containing -unally as A substring
      • Player - Player 8 (Pink) types a chat message containing -unally as A substring
      • Player - Player 9 (Gray) types a chat message containing -unally as A substring
      • Player - Player 10 (Light Blue) types a chat message containing -unally as A substring
      • Player - Player 11 (Dark Green) types a chat message containing -unally as A substring
      • Player - Player 12 (Brown) types a chat message containing -unally as A substring
    • Conditions
    • Actions
      • Set string = (Entered chat string)
      • -------- ------------------------------------------------------------------------------------------ --------
      • -------- Condition below checks if second and third letter is "AL" to find out if -ally or -unally has been written --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Substring(string, 2, 3)) Equal to al
        • Then - Actions
          • -------- Takes 7th and 8th letter to get number of player you want to ally --------
          • Set int = (Integer((Substring(string, 7, 8))))
          • -------- ------------------------------------------------------------------------------------------ --------
          • -------- ------------------------------------------------------------------------------------------ --------
          • Player - Make (Triggering player) treat (Player(int)) as an Ally with shared vision
          • Player - Make (Player(int)) treat (Triggering player) as an Ally with shared vision
        • Else - Actions
          • -------- Does the same as above, however here we know that the written string is "-unally" --------
          • -------- so we take 9th and 10th letter to find out player's number --------
          • Set int = (Integer((Substring(string, 9, 10))))
          • Player - Make (Triggering player) treat (Player(int)) as an Enemy
          • -------- ------------------------------------------------------------------------------------------ --------
          • -------- ------------------------------------------------------------------------------------------ --------
          • Player - Make (Player(int)) treat (Triggering player) as an Enemy
      • Set string = <Empty String>
      • Set allies = (All allies of (Triggering player))
      • Set int = (Integer((300.00 / (Real((Number of players in allies))))))
      • Player Group - Pick every player in allies and do (Actions)
        • Loop - Actions
          • Player - Set (Picked player) Food max to int
          • -------- ---------------------------------------------------------------------- --------
          • -------- Adding 1 used Food and then subtracting it will actualize Food Max --------
          • -------- if your current Food Max is higher than the calculated value "int" --------
          • Player - Set (Picked player) Food used to (((Picked player) Food used) + 1)
          • Player - Set (Picked player) Food used to (((Picked player) Food used) - 1)
      • -------- ---------------------------------------------------------------------- --------
      • -------- ---------------------------------------------------------------------- --------
      • -------- ---------------------------------------------------------------------- --------
      • -------- Clear leaks --------
      • Custom script: call DestroyForce(udg_allies)


I already got a -ally -unally system thanks a lot nichilus you're veeeeeeeery helpful :DD
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
Btw, afaik reals are not rounded when converting to integers. They get truncated, which can also be called rounding down. (Everything past comma is ignored)

I will elaborate.

If you want to have real rounding of reals, you have to do Integer(some real + 0.5) which will convert any real closer to higher value to it and closer to lower to it. So 9.96 becomes 10 instead of 9 while 5.46 stays 5
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
if you have real number in WC3, it will truncate, which means that everything after decimal place is ignored(so 1234.99 is still 1234), to avoid this effect you can add to that real number 0.5 before converting it, which will change that number to 1235.49 which is 1235, so it is rounded not truncated
 
Level 25
Joined
Sep 26, 2009
Messages
2,378
In WCIII, Food is an integer number.
However when you divide 300 food between players of same alliance, that number will not always be integer number.
Ex. 300 food / 7 players => 42.86 Food. However the number "42.86" is a real number, not an integer, which means the game will convert that real number into integer number (else it would not be able to use it as a Food resource).

WCIII converts reals into integers by rounding them down.
So in the above case with 7 players, each will have 42 Food, because rounding down the number 42.86 is 42.

Now rounding brings a lot of problems - as you can see, you distribute 300 food among 7 players, but each will get 42 food. If you calculate how much food that alliance has, it will not be 300!
300 / 7 = 42.86 => rounding down => 42... 42 * 7 = 294 Food for an alliance of 7 players.

If you do the same with 6 players, their alliance will have 300 Food
300 / 6 = 50 => no rounding needed => 50 * 6 = 300

Edit:
Ah I'm too slow :D

Darklycan, your problem is that you don't know what integer and real numbers are. Translate those terms into your mother language and then search it on wikipedia.
 
Level 18
Joined
Jan 12, 2011
Messages
1,512
In WCIII, Food is an integer number.
However when you divide 300 food between players of same alliance, that number will not always be integer number.
Ex. 300 food / 7 players => 42.86 Food. However the number "42.86" is a real number, not an integer, which means the game will convert that real number into integer number (else it would not be able to use it as a Food resource).

WCIII converts reals into integers by rounding them down.
So in the above case with 7 players, each will have 42 Food, because rounding down the number 42.86 is 42.

Now rounding brings a lot of problems - as you can see, you distribute 300 food among 7 players, but each will get 42 food. If you calculate how much food that alliance has, it will not be 300!
300 / 7 = 42.86 => rounding down => 42... 42 * 7 = 294 Food for an alliance of 7 players.

If you do the same with 6 players, their alliance will have 300 Food
300 / 6 = 50 => no rounding needed => 50 * 6 = 300

Edit:
Ah I'm too slow :D

Darklycan, your problem is that you don't know what integer and real numbers are. Translate those terms into your mother language and then search it on wikipedia.

Well 6 food isn't that bad anyways lol, also i doubt 7 players will be allying so no probs there.

---
edit: I understand now, i knew that since the begining Xonok, it's obvious that if 7 players ally there won't be 300 food as it would be impossible for wc3, and obviously it won't give you 43 food as 43x7= 301 and that's more than the division...
 
Level 18
Joined
Jan 12, 2011
Messages
1,512
Nichilus here's my ally and unally trigger for each player:
Ally:
  • Ally Red
    • Events
      • Player - Player 2 (Blue) types a chat message containing -ally red as An exact match
      • Player - Player 3 (Teal) types a chat message containing -ally red as An exact match
      • Player - Player 4 (Purple) types a chat message containing -ally red as An exact match
      • Player - Player 5 (Yellow) types a chat message containing -ally red as An exact match
      • Player - Player 6 (Orange) types a chat message containing -ally red as An exact match
      • Player - Player 7 (Green) types a chat message containing -ally red as An exact match
      • Player - Player 8 (Pink) types a chat message containing -ally red as An exact match
      • Player - Player 9 (Gray) types a chat message containing -ally red as An exact match
      • Player - Player 10 (Light Blue) types a chat message containing -ally red as An exact match
      • Player - Player 11 (Dark Green) types a chat message containing -ally red as An exact match
      • Player - Player 12 (Brown) types a chat message containing -ally red as An exact match
    • Conditions
      • ((Triggering player) is an ally of Player 1 (Red)) Equal to (==) False
    • Actions
      • Player - Make (Triggering player) treat Player 1 (Red) as an Ally with shared vision
      • Set PlayerAllies[(Player number of (Triggering player))] = (PlayerAllies[(Player number of (Triggering player))] + 1)
      • Wait 0.01 seconds
      • Multiboard - Set the text for (Last created multiboard) item in column 3, row 2 to (String(PlayerAllies[1]))
      • Multiboard - Set the text for (Last created multiboard) item in column 3, row 3 to (String(PlayerAllies[2]))
      • Multiboard - Set the text for (Last created multiboard) item in column 3, row 4 to (String(PlayerAllies[3]))
      • Multiboard - Set the text for (Last created multiboard) item in column 3, row 5 to (String(PlayerAllies[4]))
      • Multiboard - Set the text for (Last created multiboard) item in column 3, row 6 to (String(PlayerAllies[5]))
      • Multiboard - Set the text for (Last created multiboard) item in column 3, row 7 to (String(PlayerAllies[6]))
      • Multiboard - Set the text for (Last created multiboard) item in column 3, row 8 to (String(PlayerAllies[7]))
      • Multiboard - Set the text for (Last created multiboard) item in column 3, row 9 to (String(PlayerAllies[8]))
      • Multiboard - Set the text for (Last created multiboard) item in column 3, row 10 to (String(PlayerAllies[9]))
      • Multiboard - Set the text for (Last created multiboard) item in column 3, row 11 to (String(PlayerAllies[10]))
      • Multiboard - Set the text for (Last created multiboard) item in column 3, row 12 to (String(PlayerAllies[11]))
      • Multiboard - Set the text for (Last created multiboard) item in column 3, row 13 to (String(PlayerAllies[12]))


Unally:
  • Unally Red
    • Events
      • Player - Player 2 (Blue) types a chat message containing -unally red as An exact match
      • Player - Player 3 (Teal) types a chat message containing -unally red as An exact match
      • Player - Player 4 (Purple) types a chat message containing -unally red as An exact match
      • Player - Player 5 (Yellow) types a chat message containing -unally red as An exact match
      • Player - Player 6 (Orange) types a chat message containing -unally red as An exact match
      • Player - Player 7 (Green) types a chat message containing -unally red as An exact match
      • Player - Player 8 (Pink) types a chat message containing -unally red as An exact match
      • Player - Player 9 (Gray) types a chat message containing -unally red as An exact match
      • Player - Player 10 (Light Blue) types a chat message containing -unally red as An exact match
      • Player - Player 11 (Dark Green) types a chat message containing -unally red as An exact match
      • Player - Player 12 (Brown) types a chat message containing -unally red as An exact match
    • Conditions
      • ((Triggering player) is an ally of Player 1 (Red)) Equal to (==) True
    • Actions
      • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Player 1 (Red) is an ally of (Triggering player)) Equal to (==) True
        • Then - Actions
          • Player - Make (Triggering player) treat Player 1 (Red) as an Enemy
          • Player - Make Player 1 (Red) treat (Triggering player) as an Enemy
          • Set PlayerAllies[(Player number of (Triggering player))] = (PlayerAllies[(Player number of (Triggering player))] - 1)
          • Set PlayerAllies[1] = (PlayerAllies[1] - 1)
          • Wait 0.01 seconds
          • Multiboard - Set the text for (Last created multiboard) item in column 3, row 2 to (String(PlayerAllies[1]))
          • Multiboard - Set the text for (Last created multiboard) item in column 3, row 3 to (String(PlayerAllies[2]))
          • Multiboard - Set the text for (Last created multiboard) item in column 3, row 4 to (String(PlayerAllies[3]))
          • Multiboard - Set the text for (Last created multiboard) item in column 3, row 5 to (String(PlayerAllies[4]))
          • Multiboard - Set the text for (Last created multiboard) item in column 3, row 6 to (String(PlayerAllies[5]))
          • Multiboard - Set the text for (Last created multiboard) item in column 3, row 7 to (String(PlayerAllies[6]))
          • Multiboard - Set the text for (Last created multiboard) item in column 3, row 8 to (String(PlayerAllies[7]))
          • Multiboard - Set the text for (Last created multiboard) item in column 3, row 9 to (String(PlayerAllies[8]))
          • Multiboard - Set the text for (Last created multiboard) item in column 3, row 10 to (String(PlayerAllies[9]))
          • Multiboard - Set the text for (Last created multiboard) item in column 3, row 11 to (String(PlayerAllies[10]))
          • Multiboard - Set the text for (Last created multiboard) item in column 3, row 12 to (String(PlayerAllies[11]))
          • Multiboard - Set the text for (Last created multiboard) item in column 3, row 13 to (String(PlayerAllies[12]))
        • Else - Actions
          • Player - Make (Triggering player) treat Player 1 (Red) as an Enemy
          • Player - Make Player 1 (Red) treat (Triggering player) as an Enemy
          • Set PlayerAllies[(Player number of (Triggering player))] = (PlayerAllies[(Player number of (Triggering player))] - 1)
          • Wait 0.01 seconds
          • Multiboard - Set the text for (Last created multiboard) item in column 3, row 2 to (String(PlayerAllies[1]))
          • Multiboard - Set the text for (Last created multiboard) item in column 3, row 3 to (String(PlayerAllies[2]))
          • Multiboard - Set the text for (Last created multiboard) item in column 3, row 4 to (String(PlayerAllies[3]))
          • Multiboard - Set the text for (Last created multiboard) item in column 3, row 5 to (String(PlayerAllies[4]))
          • Multiboard - Set the text for (Last created multiboard) item in column 3, row 6 to (String(PlayerAllies[5]))
          • Multiboard - Set the text for (Last created multiboard) item in column 3, row 7 to (String(PlayerAllies[6]))
          • Multiboard - Set the text for (Last created multiboard) item in column 3, row 8 to (String(PlayerAllies[7]))
          • Multiboard - Set the text for (Last created multiboard) item in column 3, row 9 to (String(PlayerAllies[8]))
          • Multiboard - Set the text for (Last created multiboard) item in column 3, row 10 to (String(PlayerAllies[9]))
          • Multiboard - Set the text for (Last created multiboard) item in column 3, row 11 to (String(PlayerAllies[10]))
          • Multiboard - Set the text for (Last created multiboard) item in column 3, row 12 to (String(PlayerAllies[11]))
          • Multiboard - Set the text for (Last created multiboard) item in column 3, row 13 to (String(PlayerAllies[12]))
      • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Player 1 (Red) slot status) Equal to (==) Has left the game
        • Then - Actions
          • Wait 0.01 seconds
          • Multiboard - Hide (Last created multiboard)
          • Multiboard - Show MultiBoard
        • Else - Actions
          • Do nothing
      • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Player 1 (Red) slot status) Equal to (==) Is unused
        • Then - Actions
          • Wait 0.01 seconds
          • Multiboard - Hide (Last created multiboard)
          • Multiboard - Show MultiBoard
        • Else - Actions
          • Do nothing

How would i add the food system you gave it to me there?
 
Level 25
Joined
Sep 26, 2009
Messages
2,378
Well 6 food isn't that bad anyways lol, also i doubt 7 players will be allying so no probs there.
Yes. Though as you wrote, this problem can only occur in alliance of 7/8/9/11 players.

If you wanted to take care of it, you could calculate the remainder of the division (there is function for it called Math - Modulo) - the remainder would have value X.
Then you would pick X allies of triggering player and add 1 food for them.

So in alliance of 7 players, you would find out the remainder of 300/7 division, which is 6.
Then you would pick 6 players of that alliance and add 1 food to them.
So 6 players would have 43 food and 1 from that alliance 42.
I can't say its really fair for that 1 player, but whatever.


----------------------
You cannot implement what I gave you into your system, because your trigger fires from specific command (= exact match), while my from "dynamic" command (a substring).
My "system" fires when part of what I wrote is -ally or -unally. Then it picks number I add after the command. Your trigger fires when you write -ally red / -unally red exactly. It will not fire when you write part of the command - like -ally / -unally.

That aside, I don't really know - even if you did make it dynamic, you still use player's color to determinate which player to ally... I use player's number, which can be easily called by triggers.
Through color though, I have no idea how to convert/compare string and player's color.

----------------------
The only way I can think of atm is that you create a list of strings at map initialization - like this:
  • Actions
    • Color[1] = Red
    • Color[2] = Blue
    • etc.
That "Color" variable is a string array.

In your alliance trigger you take the part of string which is supposed to be color and then through loop you check if string in the list and your written color match. Like this:
  • Food Max
    • Events
    • Conditions
    • Actions
      • For each (Integer LoopIntegerA) from 1 to 12, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Color[LoopIntegerA] Equal to String
            • Then - Actions
              • Set PlayerColor = LoopIntegerA
            • Else - Actions
The String in the If/Then/Else condition is a substring of your entered command and should contain the color player wrote about.
 
Last edited:
Level 18
Joined
Jan 12, 2011
Messages
1,512
how did you make this part?
  • For each (Integer LoopIntegerA) from 1 to 12, do (Actions)
Idk if it's Integer LoopInteger A or just For Each Integer A (because i can't find where to put Integer LoopInteger A) x.x

Is it fine like this?
  • Do Multiple ActionsFor each (Integer A) from 1 to 12, do (Actions)
    • Loop - Actions
      • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
        • Then - Actions
        • Else - Actions
 
Level 25
Joined
Sep 26, 2009
Messages
2,378
IntegerA is buggy, don't use it.
What I use is the action "For Each Integer Variable, Do Multiple Actions" and in the field for variable I put my own integer variable.
(that action should be 3rd in the For Each... list - first being For Each Integer A; second for Each Integer B and the last is for your custom integer variable)

I named my variable LoopIntegerA (because I am used to it, you can call it however you want).

Ex. the variable I use is called Int_var
  • For each (Integer Int_var) from 1 to 12, do (Actions)
    • Loop - Actions
 
Level 18
Joined
Jan 12, 2011
Messages
1,512
IntegerA is buggy, don't use it.
What I use is the action "For Each Integer Variable, Do Multiple Actions" and in the field for variable I put my own integer variable.
(that action should be 3rd in the For Each... list - first being For Each Integer A; second for Each Integer B and the last is for your custom integer variable)

I named my variable LoopIntegerA (because I am used to it, you can call it however you want).

Ex. the variable I use is called Int_var
  • For each (Integer Int_var) from 1 to 12, do (Actions)
    • Loop - Actions

Oh okay, and in what part do i place it? i don't see the string part in the ally unally triggers i got, do i just past it at the end?
-------
pd
  • Color[LoopIntegerA] Equal to String
"String" is?
  • Set PlayerColor = LoopIntegerA
when i select set Color[1] = X i only have the optiont o select strings and not integers
 
Last edited:
Level 25
Joined
Sep 26, 2009
Messages
2,378
You need string variable and then save into it the command you wrote into chat
  • Set YOUR_STRING_VARIABLE = (Entered chat string)
You can then use the action substring to get part of your string variable and check what that part has.

For example you take substring 7,8 from your -ally red command.
That will pick all letters starting from the 7th letter and stops at the 8th letter of your command, so substring 7,8 will return "re"

Now that I look at it, each player's color has unique first 3 letters. You could do it from that - you create a substring to get the first 3 letters where color is supposed to be and then check it with string list you create at map ini. If it matches, you get the player.

The problem with this system, however would be if instead of color you used similar word.

For example if I wrote "-ally grass" command, which makes no sense, the trigger would still fire and ally me with player 9 (gray), because the first 3 letter in "grass" are same as the first 3 letters in "gray" => both return substring "gra"
 
Last edited:
Level 18
Joined
Jan 12, 2011
Messages
1,512
You need string variable and then save into it the command you wrote into chat
  • Set YOUR_STRING_VARIABLE = (Entered chat string)
You can then use the action substring to get part of your string variable and check what that part has.

For example you take substring 7,8 from your -ally red command.
That will pick all letters starting from the 7th letter and stops at the 8th letter of your command, so substring 7,8 will return "re"

Now that I look at it, each player's color has unique first 3 letters. You could do it from that - you create a substring to get the first 3 letters where color is supposed to be and then check it with string list you create at map ini. If it matches, you get the player.

The problem with this system, however would be if instead of color you used similar word.

For example if I wrote "-ally grass" command, which makes no sense, the trigger would still fire and ally me with player 9 (gray), because the first 3 letter in "grass" are same as the first 3 letters in "gray" => both return substring "gra"

well there's 12 ally and 12 unally triggers as each need a custom table edit
so i could just make for example the first 3 letters for red, the first 4 letters for pink etc
 
Level 25
Joined
Sep 26, 2009
Messages
2,378
No. If your trigger fires only when you write "-ally red" then you know that the triggering player wants to ally red player! There is no need to get substring to find out if "-ally red" contains substring red, because they way you set it up, if the entered chat message didn't contain exactly "-ally red", then the trigger would not even fire.

Notice the difference between these 2 events.
  • Player - Player 1 (Red) types a chat message containing -ally as A substring
  • Player - Player 1 (Red) types a chat message containing -ally red as An exact match
My trigger with the test map used the first event: -ally as a substring (meaning part of the message contained -ally)
Your trigger fires when you write: -ally red as an exact match (meaning the whole entered chat message has to look exactly as how you wrote it in the event... it will not fire if the message contains something else)

If you want for this whole (un)alliance system only 1 trigger, you need to do it my way (similarly to what I posted in the test map a few posts before).
If you do it your way - 12 ally and 12 unally triggers, then each trigger has different event.

So just merge the important parts of my trigger into your trigger - like this:
  • Ally Red
    • Events
      • Player - Player 2 (Blue) types a chat message containing -ally red as An exact match
      • Player - Player 3 (Teal) types a chat message containing -ally red as An exact match
      • Player - Player 4 (Purple) types a chat message containing -ally red as An exact match
      • Player - Player 5 (Yellow) types a chat message containing -ally red as An exact match
      • Player - Player 6 (Orange) types a chat message containing -ally red as An exact match
      • Player - Player 7 (Green) types a chat message containing -ally red as An exact match
      • Player - Player 8 (Pink) types a chat message containing -ally red as An exact match
      • Player - Player 9 (Gray) types a chat message containing -ally red as An exact match
      • Player - Player 10 (Light Blue) types a chat message containing -ally red as An exact match
      • Player - Player 11 (Dark Green) types a chat message containing -ally red as An exact match
      • Player - Player 12 (Brown) types a chat message containing -ally red as An exact match
    • Conditions
      • ((Triggering player) is an ally of Player 1 (Red)) Equal to False
    • Actions
      • Player - Make (Triggering player) treat Player 1 (Red) as an Ally with shared vision
      • Player - Make Player 1 (Red) treat (Triggering player) as an Ally with shared vision
      • Set allies = (All allies of (Triggering player))
      • Set int = (Integer((300.00 / (Real((Number of players in allies))))))
      • Player Group - Pick every player in allies and do (Actions)
        • Loop - Actions
          • Player - Set (Picked player) Food max to int
          • Player - Set (Picked player) Food used to (((Picked player) Food used) + 1)
          • Player - Set (Picked player) Food used to (((Picked player) Food used) - 1)
      • Custom script: call DestroyForce(udg_allies)
      • -------- --------------------------------------------------------------- --------
      • -------- Here is the part where you update your multiboard --------
For -unally red the trigger is same, except the event (you have to change which command fires that trigger to -unally red), condition (now you check that they are allies instead of checking that they are not allies) and that you set their alliance as enemy.

Then you just copy it 11 times for other players.
 
Status
Not open for further replies.
Top