11Player Flags Component (58)
22---------------------------
33
4- This component likely manages the player flags.
4+ This component manages the player flags. See :doc: `../game-mechanics/flag-system ` for the list of all known flags.
5+
6+ .. note ::
7+
8+ Tooltip flags are unrelated to this component. See :doc: `004-character ` for information regarding these.
59
610Relevant Database Tables
711........................
@@ -10,24 +14,85 @@ This component uses the following tables:
1014
1115* :doc: `../database/PlayerFlags `
1216
13- Relevant Game Messages:
14- .......................
17+ Relevant Game Messages
18+ ......................
19+
20+ * :gm:server: `SetFlag `
21+ * :gm:client: `NotifyClientFlagChange `
22+
23+ Component XML Format
24+ ....................
25+
26+ | :samp:`flag` - Player Flag Component data
27+ | :samp:`f` - Player flag
28+ | :samp:`attr id` - This flags index
29+ | :samp:`attr v` - This flags value
30+ | :samp:`s` - Session flag
31+ | :samp:`attr si` - Session flag Id as a literal number (ex. 114). Each session flag gets its own :samp:`s` element.
32+
33+ Flags are always saved as blocks of 64 bits.
34+ When a flag is set, its index in the flags list is the flag id divided by 64, truncated to an int.
35+ The position at the index calculated above is the flag id modulo 64.
36+
37+ Example code to set a player flag:
38+
39+ .. code-block :: python
40+
41+ player_flags = {}
42+ def set_player_flag (flag_id , turn_flag_on ):
43+ # First calculate the index, in this case it equals 17
44+ flag_index = int (flag_id / 64 )
45+ # Then calculate the position, which is also 17, and set the bit at that position.
46+ flag_value_shifted = 1 << flag_id % 64
47+ # Then check if we already have flags at this flag index
48+ flag_to_update = player_flags.get(flag_index)
49+ if flag_to_update != None :
50+ if turn_flag_on == True :
51+ # Turn the bit at flag_value_shifted in flag_to_update to True
52+ flag_to_update = flag_to_update | flag_value_shifted
53+ else :
54+ # Turn the bit at flag_value_shifted in flag_to_update to False by inverting the binary
55+ # value of flag_value_shifted and ANDing with flag_to_update
56+ flag_to_update = flag_to_update & ~ flag_value_shifted
57+ player_flags[flag_index] = flag_to_update
58+ else :
59+ # Create the new flag value and insert it into the dictionary of flags
60+ new_flag_value = flag_value_shifted
61+ player_flags[flag_index] = new_flag_value
62+
63+ # Turns player flag 1105 on
64+ set_player_flag(1105 , True )
65+ # {17: 131072}
66+ print (player_flags)
67+ # Does nothing since player flag 1105 is already on
68+ set_player_flag(1105 , True )
69+ # {17: 131072}
70+ print (player_flags)
71+ # Turns player flag 2 on
72+ set_player_flag(2 , True )
73+ # {17: 131072, 0: 4}
74+ print (player_flags)
75+ # Turns player flag 1105 off
76+ set_player_flag(1105 , False )
77+ # {17: 0, 0: 4}
78+ print (player_flags)
1579
16- * :gm: `SetTooltipFlag `
17- * :gm: `SetFlag `
18- * :gm: `NotifyClientFlagChange `
80+ Here is how flag changes are communicated between the client and the WorldServer:
1981
20- XML Serialization :samp: `<flag> `
21- ................................
82+ .. uml ::
2283
23- This component is serialized to XML to store its data.
84+ @startuml
85+ skinparam sequenceMessageAlign center
86+ group Client sets a flag
87+ Client -> WorldServer: [<b>Game Message SetFlag</b>]
88+ end
2489
25- Flags :samp: ` <f> `
26- '''''''''''''''''
90+ WorldServer -> Client: [<b>Game Message NotifyClientFlagChange</b>]
91+ @enduml
2792
28- Flags are serialized as blocks of 64 bit. The ID of such a block is
29- the common prefix you get when shifting all flags indices to the right
30- by 6 bits .
93+ If a flag is a session flag, it should be set for the duration of a session and when the player changes character
94+ or logs out, these flags should be cleared. A session flag can be found by querying the :doc: ` ../database/PlayerFlags `
95+ table and if the :samp: ` SessionOnly ` boolean is set to true, the flag is set for the session .
3196
32- :id: The ID of the flag group
33- :v: The value of 64 flags
97+ There are two flags in live, flags :samp: ` 1110 ` and :samp: ` 2099 ` which have :samp: ` SessionZoneOnly ` set to true.
98+ The use of :samp: ` SessionZoneOnly ` is guessed to be to detect if a player has done something in a zone this session.
0 commit comments