1 #include "Special.h"
2
3 #include "Condition.h"
4 #include "Effect.h"
5 #include "UniverseObject.h"
6 #include "ValueRef.h"
7 #include "../util/OptionsDB.h"
8 #include "../util/Logger.h"
9 #include "../util/AppInterface.h"
10 #include "../util/CheckSums.h"
11 #include "../util/ScopedTimer.h"
12 #include "../util/i18n.h"
13
14 #include <boost/filesystem/fstream.hpp>
15
SpecialsManager()16 SpecialsManager::SpecialsManager()
17 {}
18
~SpecialsManager()19 SpecialsManager::~SpecialsManager()
20 {}
21
SpecialNames() const22 std::vector<std::string> SpecialsManager::SpecialNames() const {
23 CheckPendingSpecialsTypes();
24 std::vector<std::string> retval;
25 for (const auto& entry : m_specials) {
26 retval.push_back(entry.first);
27 }
28 return retval;
29 }
30
GetSpecial(const std::string & name) const31 const Special* SpecialsManager::GetSpecial(const std::string& name) const {
32 CheckPendingSpecialsTypes();
33 auto it = m_specials.find(name);
34 return it != m_specials.end() ? it->second.get() : nullptr;
35 }
36
GetCheckSum() const37 unsigned int SpecialsManager::GetCheckSum() const {
38 CheckPendingSpecialsTypes();
39 unsigned int retval{0};
40 for (auto const& name_type_pair : m_specials)
41 CheckSums::CheckSumCombine(retval, name_type_pair);
42 CheckSums::CheckSumCombine(retval, m_specials.size());
43 DebugLogger() << "SpecialsManager checksum: " << retval;
44 return retval;
45 }
46
SetSpecialsTypes(Pending::Pending<SpecialsTypeMap> && future)47 void SpecialsManager::SetSpecialsTypes(Pending::Pending<SpecialsTypeMap>&& future)
48 { m_pending_types = std::move(future); }
49
CheckPendingSpecialsTypes() const50 void SpecialsManager::CheckPendingSpecialsTypes() const {
51 if (!m_pending_types)
52 return;
53
54 Pending::SwapPending(m_pending_types, m_specials);
55 }
56
GetSpecialsManager()57 SpecialsManager& GetSpecialsManager() {
58 static SpecialsManager special_manager;
59 return special_manager;
60 }
61
62 /////////////////////////////////////////////////
63 // Special //
64 /////////////////////////////////////////////////
Special(const std::string & name,const std::string & description,std::unique_ptr<ValueRef::ValueRef<double>> && stealth,std::vector<std::unique_ptr<Effect::EffectsGroup>> && effects,double spawn_rate,int spawn_limit,std::unique_ptr<ValueRef::ValueRef<double>> && initial_capaicty,std::unique_ptr<Condition::Condition> && location,const std::string & graphic)65 Special::Special(const std::string& name, const std::string& description,
66 std::unique_ptr<ValueRef::ValueRef<double>>&& stealth,
67 std::vector<std::unique_ptr<Effect::EffectsGroup>>&& effects,
68 double spawn_rate /*= 1.0*/, int spawn_limit /*= 99999*/,
69 std::unique_ptr<ValueRef::ValueRef<double>>&& initial_capaicty /*= nullptr*/,
70 std::unique_ptr<Condition::Condition>&& location /*= nullptr*/,
71 const std::string& graphic /*= ""*/) :
72 m_name(name),
73 m_description(description),
74 m_stealth(std::move(stealth)),
75 m_effects(),
76 m_spawn_rate(spawn_rate),
77 m_spawn_limit(spawn_limit),
78 m_initial_capacity(std::move(initial_capaicty)),
79 m_location(std::move(location)),
80 m_graphic(graphic)
81 {
82 for (auto&& effect : effects)
83 m_effects.emplace_back(std::move(effect));
84
85 Init();
86 }
87
~Special()88 Special::~Special()
89 {}
90
Description() const91 std::string Special::Description() const {
92 std::stringstream result;
93
94 result << UserString(m_description) << "\n";
95
96 for (auto& effect : m_effects) {
97 const std::string& description = effect->GetDescription();
98
99 if (!description.empty()) {
100 result << "\n" << UserString(description) << "\n";
101 }
102 }
103
104 return result.str();
105 }
106
Init()107 void Special::Init() {
108 if (m_stealth)
109 m_stealth->SetTopLevelContent(m_name);
110 for (auto& effect : m_effects) {
111 effect->SetTopLevelContent(m_name);
112 }
113 if (m_initial_capacity)
114 m_initial_capacity->SetTopLevelContent(m_name);
115 if (m_location)
116 m_location->SetTopLevelContent(m_name);
117 }
118
Dump(unsigned short ntabs) const119 std::string Special::Dump(unsigned short ntabs) const {
120 std::string retval = DumpIndent(ntabs) + "Special\n";
121 retval += DumpIndent(ntabs+1) + "name = \"" + m_name + "\"\n";
122 retval += DumpIndent(ntabs+1) + "description = \"" + m_description + "\"\n";
123
124 if (m_stealth)
125 retval += DumpIndent(ntabs+1) + "stealth = " + m_stealth->Dump(ntabs+1) + "\n";
126
127 retval += DumpIndent(ntabs+1) + "spawnrate = " + std::to_string(m_spawn_rate) + "\n"
128 + DumpIndent(ntabs+1) + "spawnlimit = " + std::to_string(m_spawn_limit) + "\n";
129
130 if (m_initial_capacity) {
131 retval += DumpIndent(ntabs+1) + "initialcapacity = ";
132 retval += m_initial_capacity->Dump(ntabs+2);
133 }
134
135 if (m_location) {
136 retval += DumpIndent(ntabs+1) + "location =\n";
137 retval += m_location->Dump(ntabs+2);
138 }
139
140 if (m_effects.size() == 1) {
141 retval += DumpIndent(ntabs+1) + "effectsgroups =\n";
142 retval += m_effects[0]->Dump(ntabs+2);
143 } else {
144 retval += DumpIndent(ntabs+1) + "effectsgroups = [\n";
145 for (auto& effect : m_effects)
146 retval += effect->Dump(ntabs+2);
147 retval += DumpIndent(ntabs+1) + "]\n";
148 }
149 retval += DumpIndent(ntabs+1) + "graphic = \"" + m_graphic + "\"\n";
150 return retval;
151 }
152
InitialCapacity(int object_id) const153 float Special::InitialCapacity(int object_id) const {
154 if (!m_initial_capacity)
155 return 0.0f;
156
157 auto obj = Objects().get(object_id);
158 if (!obj)
159 return 0.0f;
160
161 return m_initial_capacity->Eval(ScriptingContext(obj));
162 }
163
GetCheckSum() const164 unsigned int Special::GetCheckSum() const {
165 unsigned int retval{0};
166
167 CheckSums::CheckSumCombine(retval, m_name);
168 CheckSums::CheckSumCombine(retval, m_description);
169 CheckSums::CheckSumCombine(retval, m_stealth);
170 CheckSums::CheckSumCombine(retval, m_effects);
171 CheckSums::CheckSumCombine(retval, m_initial_capacity);
172 CheckSums::CheckSumCombine(retval, m_location);
173 CheckSums::CheckSumCombine(retval, m_graphic);
174
175 return retval;
176 }
177
GetSpecial(const std::string & name)178 const Special* GetSpecial(const std::string& name)
179 { return GetSpecialsManager().GetSpecial(name); }
180
SpecialNames()181 std::vector<std::string> SpecialNames()
182 { return GetSpecialsManager().SpecialNames(); }
183