1 /* bzflag
2  * Copyright (c) 1993-2021 Tim Riker
3  *
4  * This package is free software;  you can redistribute it and/or
5  * modify it under the terms of the license found in the file
6  * named COPYING that should have accompanied this file.
7  *
8  * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
9  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
10  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
11  */
12 
13 /** @file
14  * Flags add some spice to the game.  There are two kinds of flags:
15  * team flags and super flags.  Super flags come in two types: good
16  * and bad.
17  *
18  *   When playing a "capture the flag" style game, each team with at
19  * least one player has a team flag which has the same color as the
20  * team.  A team flag will remain in the game as long as there is a
21  * player on that team.  A team flag may be picked up and freely
22  * dropped at any time.  It may be captured, which causes it to go
23  * back to it's home position (centered in the team base).  If a
24  * flag is dropped by a hostile player in a third team's base, the
25  * flag will go to the third team's flag safety position.  For example,
26  * if a Green Team player dropped the Red Flag on Blue's Base, the
27  * Red Flag would go to the Blue Team's safety position.  This is
28  * because if it stayed in the Blue Base, any Red Team member who
29  * picked it up would instantly have brought his team flag into
30  * enemy territory and so blow up his whole team.
31  *
32  *   A super flag causes the characteristics of the tank that possesses
33  * it to change.  A good super flag generally makes the tank more
34  * powerful or deadly.  A bad super flag generally does the opposite.
35  * A good super flag may always be dropped.  A bad super flag is
36  * "sticky" which means that it can't be freely dropped.  The server
37  * may have some means of getting rid of a bad super flag (perhaps
38  * by destroying an enemy or two or after waiting 20 seconds).
39  * The creation and destruction of super flags is under the server's
40  * control so super flags may appear and disappear seemingly at
41  * random.
42  */
43 
44 #ifndef BZF_FLAG_H
45 #define BZF_FLAG_H
46 
47 #include "common.h"
48 
49 /* system interface headers */
50 #include <set>
51 #include <map>
52 #include <string>
53 
54 /* common interface headers */
55 #include "global.h"
56 #include "Address.h"
57 
58 
59 /** This enum says where a flag is. */
60 enum FlagStatus
61 {
62     /// the flag is not present in the world
63     FlagNoExist = 0,
64     /// the flag is sitting on the ground and can be picked up
65     FlagOnGround,
66     /// the flag is being carried by a tank
67     FlagOnTank,
68     /// the flag is falling through the air
69     FlagInAir,
70     /// the flag is entering the world
71     FlagComing,
72     /// the flag is leaving the world
73     FlagGoing
74 };
75 
76 /** This enum tells us if the flag type is droppable, and what happens to it
77     when it's droppped. */
78 enum FlagEndurance
79 {
80     /// permanent flag
81     FlagNormal = 0,
82     /// disappears after use
83     FlagUnstable = 1,
84     /// can't be dropped normally
85     FlagSticky = 2
86 };
87 
88 /** This enum tells the "quality" of the flag type, i.e. whether it's good
89     or bad */
90 enum FlagQuality
91 {
92     FlagGood = 0,
93     FlagBad = 1,
94     NumQualities
95 };
96 
97 /** This enum says if the flag type gives the carrier a special shooting
98     ability. */
99 enum ShotType
100 {
101     NormalShot = 0,
102     SpecialShot = 1
103 };
104 
105 const int       FlagPLen = 55;
106 
107 class FlagType;
108 typedef std::map<std::string, FlagType*> FlagTypeMap;
109 typedef std::set<FlagType*> FlagSet;
110 
111 #define FlagPackSize 2
112 
113 /** This class represents a flagtype, like "GM" or "CL". */
114 class FlagType
115 {
116 public:
117     FlagType( const std::string& name, const std::string& abbv, FlagEndurance _endurance,
118               ShotType sType, FlagQuality quality, TeamColor team, const std::string& help,
119               bool _custom = false ) :
flagName(name)120         flagName(name),
121         flagAbbv(abbv),
122         flagHelp(help)
123     {
124         endurance = _endurance;
125         flagShot = sType;
126         flagQuality = quality;
127         flagTeam = team;
128         custom = _custom;
129 
130         /* allocate flagset array on first use to work around mipspro
131          * std::set compiler bug of making flagSets a fixed array.
132          */
133         if (flagSets == NULL)
134             flagSets = new FlagSet[NumQualities];
135 
136         if (custom)
137             customFlags.insert(this);
138 
139         flagSets[flagQuality].insert(this);
140         getFlagMap()[flagAbbv] = this;
141     }
142 
143     /** returns a label of flag name and abbreviation with the flag name
144      * excentuating the abbreviation if relevant.
145      */
146     const std::string label() const;
147 
148     /** returns information about a flag including the name, abbreviation, and
149      * description.  format is "name ([+|-]abbrev): description" where +|-
150      * indicates whether the flag is inherently good or bad by default.
151      */
152     const std::string information() const;
153 
154     /** returns the color of the flag */
155     const float* getColor() const;
156 
157     /** returns the color of the flag as it should be shown on the radar */
158     const float* getRadarColor() const;
159 
160     /** network serialization */
161     void* pack(void* buf) const;
162     void* fakePack(void* buf) const;
163     void* packCustom(void* buf) const;
164 
165     /** network deserialization */
166     static const void* unpack(const void* buf, FlagType* &desc);
167     static const void* unpackCustom(const void* buf, FlagType* &desc);
168 
169     /** Static wrapper function that makes sure that the flag map is
170      * initialized before it's used.
171      */
172     static FlagTypeMap& getFlagMap();
173 
174     const std::string flagName;
175     const std::string flagAbbv;
176     const std::string flagHelp;
177     FlagEndurance endurance;
178     FlagQuality flagQuality;
179     ShotType flagShot;
180     TeamColor flagTeam;
181     bool custom;
182 
183     static FlagSet *flagSets;
184     static FlagSet customFlags;
185     static const int packSize;
186 };
187 
188 
189 /** This class represents an actual flag. It has functions for serialization
190     and deserialization as well as static functions that returns sets of
191     all good or bad flags, and maps flag abbreviations to FlagType objects. */
192 class Flag
193 {
194 public:
195     /** This function serializes this object into a @c void* buffer for network
196         transfer. */
197     void* pack(void*) const;
198     /** This function serializes this object into a @c void* buffer for network
199         transfer. */
200     void* fakePack(void*) const;
201     /** This function uses the given serialization to set the member variables
202         of this object. This really hide the type of flag */
203     const void* unpack(const void*);
204 
205     /** This function returns a set of all good flagtypes that are available in
206         the game.
207         @see FlagType
208         @see FlagQuality
209     */
210     static FlagSet& getGoodFlags();
211 
212     /** This function returns a set of all bad flagtypes that are available in
213         the game.
214         @see FlagType
215         @see FlagQuality
216     */
217     static FlagSet& getBadFlags();
218 
219     /** This function returns a pointer to the FlagType object that is associated
220         with the given abbreviation. If there is no such FlagType object, NULL
221         is returned. */
222     static FlagType* getDescFromAbbreviation(const char* abbreviation);
223 
224     FlagType* type;
225     FlagStatus status;
226     FlagEndurance endurance;
227     PlayerId owner;       // who has flag
228     float position[3];        // position on ground
229     float launchPosition[3];  // position flag launched from
230     float landingPosition[3]; // position flag will land
231     float flightTime;     // flight time so far
232     float flightEnd;      // total duration of flight
233     float initialVelocity;    // initial launch velocity
234 };
235 
236 /** Flags no longer use enumerated IDs. Over the wire, flags are all
237     represented by their abbreviation, null-padded to two bytes. Internally,
238     flags are now represented by pointers to singleton FlagType classes.
239 
240     For more information about these flags, see Flag.cxx where these FlagType
241     instances are created.
242 */
243 namespace Flags
244 {
245 extern FlagType
246 *Null,
247 *RedTeam, *GreenTeam, *BlueTeam, *PurpleTeam, *Velocity, *QuickTurn,
248 *OscillationOverthruster, *RapidFire, *MachineGun, *GuidedMissile, *Laser,
249 *Ricochet, *SuperBullet, *InvisibleBullet, *Stealth, *Tiny, *Narrow,
250 *Shield, *Steamroller, *ShockWave, *PhantomZone, *Genocide, *Jumping,
251 *Identify, *Cloaking, *Useless, *Masquerade, *Seer, *Thief, *Burrow,
252 *Wings, *ReverseControls, *Agility,
253 *Colorblindness, *Obesity, *LeftTurnOnly, *RightTurnOnly, *Momentum,
254 *Blindness, *Jamming, *WideAngle, *NoJumping, *TriggerHappy,
255 *ReverseOnly, *ForwardOnly, *Bouncy;
256 
257 /** This function initializes all the FlagType objects in the Flags
258     namespace. */
259 void init();
260 void kill();
261 
262 /** Clear all the custom flags (i.e. when switching servers) */
263 void clearCustomFlags();
264 }
265 
266 #endif // BZF_FLAG_H
267 
268 // Local Variables: ***
269 // mode: C++ ***
270 // tab-width: 4 ***
271 // c-basic-offset: 4 ***
272 // indent-tabs-mode: nil ***
273 // End: ***
274 // ex: shiftwidth=4 tabstop=4
275