1 /* Outfit.h
2 Copyright (c) 2014 by Michael Zahniser
3
4 Endless Sky is free software: you can redistribute it and/or modify it under the
5 terms of the GNU General Public License as published by the Free Software
6 Foundation, either version 3 of the License, or (at your option) any later version.
7
8 Endless Sky is distributed in the hope that it will be useful, but WITHOUT ANY
9 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
10 PARTICULAR PURPOSE. See the GNU General Public License for more details.
11 */
12
13 #ifndef OUTFIT_H_
14 #define OUTFIT_H_
15
16 #include "Weapon.h"
17
18 #include "Dictionary.h"
19
20 #include <map>
21 #include <string>
22 #include <utility>
23 #include <vector>
24
25 class Body;
26 class DataNode;
27 class Effect;
28 class Sound;
29 class Sprite;
30
31
32
33 // Class representing an outfit that can be installed in a ship. A ship's
34 // "attributes" are simply stored as a series of key-value pairs, and an outfit
35 // can add to or subtract from any of those values. Weapons also have another
36 // set of attributes unique to them, and outfits can also specify additional
37 // information like the sprite to use in the outfitter panel for selling them,
38 // or the sprite or sound to be used for an engine flare.
39 class Outfit : public Weapon {
40 public:
41 // These are all the possible category strings for outfits.
42 static const std::vector<std::string> CATEGORIES;
43
44 public:
45 // An "outfit" can be loaded from an "outfit" node or from a ship's
46 // "attributes" node.
47 void Load(const DataNode &node);
48 bool IsDefined() const;
49
50 const std::string &Name() const;
51 void SetName(const std::string &name);
52 const std::string &PluralName() const;
53 const std::string &Category() const;
54 const std::string &Description() const;
55 int64_t Cost() const;
56 double Mass() const;
57 // Get the licenses needed to buy or operate this ship.
58 const std::vector<std::string> &Licenses() const;
59 // Get the image to display in the outfitter when buying this item.
60 const Sprite *Thumbnail() const;
61
62 double Get(const char *attribute) const;
63 double Get(const std::string &attribute) const;
64 const Dictionary &Attributes() const;
65
66 // Determine whether the given number of instances of the given outfit can
67 // be added to a ship with the attributes represented by this instance. If
68 // not, return the maximum number that can be added.
69 int CanAdd(const Outfit &other, int count = 1) const;
70 // For tracking a combination of outfits in a ship: add the given number of
71 // instances of the given outfit to this outfit.
72 void Add(const Outfit &other, int count = 1);
73 // Modify this outfit's attributes. Note that this cannot be used to change
74 // special attributes, like cost and mass.
75 void Set(const char *attribute, double value);
76
77 // Get this outfit's engine flare sprites, if any.
78 const std::vector<std::pair<Body, int>> &FlareSprites() const;
79 const std::vector<std::pair<Body, int>> &ReverseFlareSprites() const;
80 const std::vector<std::pair<Body, int>> &SteeringFlareSprites() const;
81 const std::map<const Sound *, int> &FlareSounds() const;
82 const std::map<const Sound *, int> &ReverseFlareSounds() const;
83 const std::map<const Sound *, int> &SteeringFlareSounds() const;
84 // Get the afterburner effect, if any.
85 const std::map<const Effect *, int> &AfterburnerEffects() const;
86 // Get this oufit's jump effects and sounds, if any.
87 const std::map<const Effect *, int> &JumpEffects() const;
88 const std::map<const Sound *, int> &HyperSounds() const;
89 const std::map<const Sound *, int> &HyperInSounds() const;
90 const std::map<const Sound *, int> &HyperOutSounds() const;
91 const std::map<const Sound *, int> &JumpSounds() const;
92 const std::map<const Sound *, int> &JumpInSounds() const;
93 const std::map<const Sound *, int> &JumpOutSounds() const;
94 // Get the sprite this outfit uses when dumped into space.
95 const Sprite *FlotsamSprite() const;
96
97
98 private:
99 bool isDefined = false;
100 std::string name;
101 std::string pluralName;
102 std::string category;
103 std::string description;
104 const Sprite *thumbnail = nullptr;
105 int64_t cost = 0;
106 double mass = 0.;
107 // Licenses needed to purchase this item.
108 std::vector<std::string> licenses;
109
110 Dictionary attributes;
111
112 // The integers in these pairs/maps indicate the number of
113 // sprites/effects/sounds to be placed/played.
114 std::vector<std::pair<Body, int>> flareSprites;
115 std::vector<std::pair<Body, int>> reverseFlareSprites;
116 std::vector<std::pair<Body, int>> steeringFlareSprites;
117 std::map<const Sound *, int> flareSounds;
118 std::map<const Sound *, int> reverseFlareSounds;
119 std::map<const Sound *, int> steeringFlareSounds;
120 std::map<const Effect *, int> afterburnerEffects;
121 std::map<const Effect *, int> jumpEffects;
122 std::map<const Sound *, int> hyperSounds;
123 std::map<const Sound *, int> hyperInSounds;
124 std::map<const Sound *, int> hyperOutSounds;
125 std::map<const Sound *, int> jumpSounds;
126 std::map<const Sound *, int> jumpInSounds;
127 std::map<const Sound *, int> jumpOutSounds;
128 const Sprite *flotsamSprite = nullptr;
129 };
130
131
132
133 // These get called a lot, so inline them for speed.
Cost()134 inline int64_t Outfit::Cost() const { return cost; }
Mass()135 inline double Outfit::Mass() const { return mass; }
136
137
138
139 #endif
140