Maybe that is done only on the server.
Samapico - Thu Aug 20, 2009 11:36 am
Post subject:
Ok, so player A kills player B, A->flags increase.
What happens when player A drops his flags? what ID will the flags have?
As for why there are ID's....
Player A picks up a flag.
I'm player B... some flag has to be removed from my map, which one... I wonder.
JoWie - Thu Aug 20, 2009 2:48 pm
Post subject:
It seems like continuum only tracks flag id's for flags on the map not for flags that are carried. This is why ASSS goes to all kind of hoops to maintain consistency in the flag id's.
if you look in flagcore.c, when a player enters the arena, he is only sent flag update's for flags on the map (S2C_FLAGLOC), not for the carried flags. He is notified by the carried flags using S2C_PLAYERENTERING which contains just a flagcount.
So your solution would be to store per flag id a boolean value "onmap", and NOT if it is NONE, ONMAP or CARRIED. Since in reality, flags have no CARRIED state. just NONE or ONMAP.
So when a flag is picked up set it to NONE instead of CARRIED.
When someone is killed, update the flagcarried count (up to the carryflags setting) and do not care about the extra
grazzhoppa - Fri Aug 21, 2009 6:53 am
Post subject:
Well, I believe I finally have a system to do this. There will be 5 states that flags can be in.
struct FLAG_ {
FLAG_ID id; /* server's ID for this flag */
POINT_TILE location; /* tile location of the flag */
FREQ freq_owner; /* team which this flag is owned/captured by. FREQ_NONE if neutral/unowned */
PLAYER_ID carrier; /* if being carried, the pid of the carrier. PID_NONE if not carried */
bool valid; /* accounting for continuum protocol's gayness of not giving flag ids in 0x06 (kill/death packet) so flags ids transferred during kills/deaths are unknown */
}; |
The five states of flag associations based on the values of a FLAG
- .carrier == PID_NONE && .valid == false
means the FLAG.id has been carried since bot entered arena. No way of knowing which PLAYER is carrying this FLAG.id until it gets dropped and picked up again due to gayness of continuum protocol. FLAG.location is meaningless.
- .carrier != PID_NONE && .valid == false
means the FLAG.id could be part of a FLAG_GROUP. If it is, it is uncertainly carried by that FLAG_GROUP.possible_carrier. FLAG.location is meaningless.
struct FLAG_GROUP_ {
vector<map<FLAG_ID, FLAG>::iterator> flags; /* all possible flags carried by
* .possible_carrier due to a kill/death
* partial flag transfer (AKA overflow)
*/
PLAYER_ID possible_carrier;
uint16_t flags_transfered; /* amount of flags of this group that are carried by possible_carrier */
}; |
- If a flag from #2 is actually not in a FLAG_GROUP,
it means it was orphaned by FLAG.carrier (ship/freq/arena change), FLAG.location is meaningless, but soon a FlagLocation packet will be received for this flag.
- .valid == true && .carrier == PID_NONE
means the FLAG.id is surely dropped at FLAG.location
- .valid == true && .carrier != PID_NONE
means the FLAG.carrier is surely carrying this FLAG.id. FLAG.location is meaningless. the FLAG.carrier's location is the location of the flag since it's being carried by that player.
Using this system:
when the client/bot enters the arena, flags that are being carried will never have an association to a player until they are placed on the map. The association can only happen when the player changes ship/freq/arena, or they drop flags via expired flag timer.
All other flags that are dropped will be able to be tracked from the time the client/bot enters the arena.
When the "overflow" situation happens: It will break flag associations temporarily. Eventually when enough flags are dropped, we can regain associations.
Create a FLAG_GROUP, add all the flags carried by the killed. Note the "flags transfered" value in the kill packet.
Assign ownership (group.possible_carrier) to the killer.
if killer dies, transfer ownership of the group to the new killer
if killer dies to a player with ownership of another group, combine the groups and assign this new larger group to the newest killer
Remove a flag from this group when a FlagLocation packet comes in for it.
after removing the flag, if the amount of .flags in the group == .flags_transfered, associate all remaining flags to owner of the group and discard the group
This system will allow regaining associations faster, BUT ONLY in SOME cases, than simply disassociating all non-map flags.
Bottom lines are:
(1 For arenas without overflow situations) if a flag never touches the map since the client/bot entered the arena, there is no way to know which player is carrying that flag until there is only 1 flag carrier in the arena.
(2) in overflow situations, if kill events continually generate overflow events all flags will eventually end up in FLAG_GROUPs meaning they are loosely associated with a Player, but in order to certainly know the associations, we have to wait for FlagLocation packets.
JoWie - Fri Aug 21, 2009 7:35 am
Post subject:
ok, imagine this situation that is possible in the continuum protocol (however ASSS prevents this from happening, don't know about subgame):
Flag game with 4 flags (flag id 0,1, 2, 3). Two players A and B
- All the flags are on the map somewhere. S2CFlagLocation
- A picks up flag 0 and 1. S2CFlagPickup
- B picks up flag 2 and 3. S2CFlagPickup
- B drops his flags. S2CFlagDrop
- The server decides 2 flags should reappear on the map because of B's flagdrop
- The server places flag 0 and 1 on the map. (ASSS would always place 2 and 3 here) S2CFlagLocation
This means the flags player A originally picked up are reused by subgame for the dropping of B's flags.
If the above is NOT the case, then subgame HAS to track the flag id's carried and must do something similar to ASSS' flagcore.
Again, I have no idea if subgame does this, I am just stating this is possible.