1
1
Player Flags Component (58)
2
2
---------------------------
3
3
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.
5
9
6
10
Relevant Database Tables
7
11
........................
@@ -10,24 +14,85 @@ This component uses the following tables:
10
14
11
15
* :doc: `../database/PlayerFlags `
12
16
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)
15
79
16
- * :gm: `SetTooltipFlag `
17
- * :gm: `SetFlag `
18
- * :gm: `NotifyClientFlagChange `
80
+ Here is how flag changes are communicated between the client and the WorldServer:
19
81
20
- XML Serialization :samp: `<flag> `
21
- ................................
82
+ .. uml ::
22
83
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
24
89
25
- Flags :samp: ` <f> `
26
- '''''''''''''''''
90
+ WorldServer -> Client: [<b>Game Message NotifyClientFlagChange</b>]
91
+ @enduml
27
92
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 .
31
96
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