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