1 ////////////////////////////////////////////////////////////////////////////////
2 //            Copyright (C) 2004-2011 by The Allacrost Project
3 //            Copyright (C) 2012-2018 by Bertram (Valyria Tear)
4 //                         All Rights Reserved
5 //
6 // This code is licensed under the GNU GPL version 2. It is free software
7 // and you may modify it and/or redistribute it under the terms of this license.
8 // See http://www.gnu.org/copyleft/gpl.html for details.
9 ////////////////////////////////////////////////////////////////////////////////
10 
11 #include "global_party.h"
12 
13 #include "global_character.h"
14 
15 namespace vt_global
16 {
17 
18 extern bool GLOBAL_DEBUG;
19 
AddCharacter(GlobalCharacter * character,int32_t index)20 void GlobalParty::AddCharacter(GlobalCharacter* character, int32_t index)
21 {
22     if(character == nullptr) {
23         IF_PRINT_WARNING(GLOBAL_DEBUG) << "function received a nullptr character argument" << std::endl;
24         return;
25     }
26 
27     if(_allow_duplicates == false) {
28         // Check that this character is not already in the party
29         for(uint32_t i = 0; i < _characters.size(); ++i) {
30             if(character->GetID() == _characters[i]->GetID()) {
31                 IF_PRINT_WARNING(GLOBAL_DEBUG) << "attempted to add an character that was already in the party "
32                                                << "when duplicates were not allowed: " << character->GetID() << std::endl;
33                 return;
34             }
35         }
36     }
37 
38     // Add character to the end of the party if index is negative
39     if(index < 0) {
40         _characters.push_back(character);
41         return;
42     }
43 
44     // Check that the requested index does not exceed the size of the container
45     if(static_cast<uint32_t>(index) >= _characters.size()) {
46         IF_PRINT_WARNING(GLOBAL_DEBUG) << "index argument exceeded the current party size: " << index << std::endl;
47         _characters.push_back(character); // Add the character to the end of the party instead
48         return;
49     } else {
50         std::vector<GlobalCharacter *>::iterator position = _characters.begin();
51         for(int32_t i = 0; i < index; ++i, ++position);
52         _characters.insert(position, character);
53     }
54 }
55 
RemoveCharacterAtIndex(uint32_t index)56 GlobalCharacter* GlobalParty::RemoveCharacterAtIndex(uint32_t index)
57 {
58     if(index >= _characters.size()) {
59         IF_PRINT_WARNING(GLOBAL_DEBUG) << "index argument exceeded current party size: "
60                                        << index << std::endl;
61         return nullptr;
62     }
63 
64     GlobalCharacter *removed_character = _characters[index];
65     std::vector<GlobalCharacter *>::iterator position = _characters.begin();
66     for(uint32_t i = 0; i < index; ++i, ++position);
67     _characters.erase(position);
68 
69     return removed_character;
70 }
71 
RemoveCharacterByID(uint32_t id)72 GlobalCharacter *GlobalParty::RemoveCharacterByID(uint32_t id)
73 {
74     if(_allow_duplicates) {
75         IF_PRINT_WARNING(GLOBAL_DEBUG) << "tried to remove character when duplicates were allowed in the party: " << id << std::endl;
76         return nullptr;
77     }
78 
79     GlobalCharacter *removed_character = nullptr;
80     for(std::vector<GlobalCharacter *>::iterator position = _characters.begin(); position != _characters.end(); ++position) {
81         if(id == (*position)->GetID()) {
82             removed_character = *position;
83             _characters.erase(position);
84             break;
85         }
86     }
87 
88     if(removed_character == nullptr) {
89         IF_PRINT_WARNING(GLOBAL_DEBUG) << "failed to find an character in the party with the requested id: " << id << std::endl;
90     }
91 
92     return removed_character;
93 }
94 
GetCharacterAtIndex(uint32_t index) const95 GlobalCharacter* GlobalParty::GetCharacterAtIndex(uint32_t index) const
96 {
97     if(index >= _characters.size()) {
98         IF_PRINT_WARNING(GLOBAL_DEBUG) << "index argument exceeded current party size: " << index << std::endl;
99         return nullptr;
100     }
101 
102     return _characters[index];
103 }
104 
GetCharacterByID(uint32_t id) const105 GlobalCharacter* GlobalParty::GetCharacterByID(uint32_t id) const
106 {
107     if(_allow_duplicates) {
108         IF_PRINT_WARNING(GLOBAL_DEBUG) << "tried to retrieve character when duplicates were allowed in the party: " << id << std::endl;
109         return nullptr;
110     }
111 
112     for(uint32_t i = 0; i < _characters.size(); ++i) {
113         if(_characters[i]->GetID() == id) {
114             return _characters[i];
115         }
116     }
117 
118     IF_PRINT_WARNING(GLOBAL_DEBUG) << "failed to find an character in the party with the requested id: " << id << std::endl;
119     return nullptr;
120 }
121 
SwapCharactersByIndex(uint32_t first_index,uint32_t second_index)122 void GlobalParty::SwapCharactersByIndex(uint32_t first_index, uint32_t second_index)
123 {
124     if(first_index == second_index) {
125         IF_PRINT_WARNING(GLOBAL_DEBUG) << "first_index and second_index arguments had the same value: " << first_index << std::endl;
126         return;
127     }
128     if(first_index >= _characters.size()) {
129         IF_PRINT_WARNING(GLOBAL_DEBUG) << "first_index argument exceeded current party size: " << first_index << std::endl;
130         return;
131     }
132     if(second_index >= _characters.size()) {
133         IF_PRINT_WARNING(GLOBAL_DEBUG) << "second_index argument exceeded current party size: " << second_index << std::endl;
134         return;
135     }
136 
137     GlobalCharacter* tmp = _characters[first_index];
138     _characters[first_index] = _characters[second_index];
139     _characters[second_index] = tmp;
140 }
141 
SwapCharactersByID(uint32_t first_id,uint32_t second_id)142 void GlobalParty::SwapCharactersByID(uint32_t first_id, uint32_t second_id)
143 {
144     if(first_id == second_id) {
145         IF_PRINT_WARNING(GLOBAL_DEBUG) << "first_id and second_id arguments had the same value: " << first_id << std::endl;
146         return;
147     }
148     if(_allow_duplicates) {
149         IF_PRINT_WARNING(GLOBAL_DEBUG) << "tried to swap characters when duplicates were allowed in the party: " << first_id << std::endl;
150         return;
151     }
152 
153     std::vector<GlobalCharacter *>::iterator first_position;
154     std::vector<GlobalCharacter *>::iterator second_position;
155     for(first_position = _characters.begin(); first_position != _characters.end(); ++first_position) {
156         if((*first_position)->GetID() == first_id)
157             break;
158     }
159     for(second_position = _characters.begin(); second_position != _characters.end(); ++second_position) {
160         if((*second_position)->GetID() == second_id)
161             break;
162     }
163 
164     if(first_position == _characters.end()) {
165         IF_PRINT_WARNING(GLOBAL_DEBUG) << "failed to find an character in the party with the requested first_id: " << first_id << std::endl;
166         return;
167     }
168     if(second_position == _characters.end()) {
169         IF_PRINT_WARNING(GLOBAL_DEBUG) << "failed to find an character in the party with the requested second_id: " << second_id << std::endl;
170         return;
171     }
172 
173     GlobalCharacter *tmp = *first_position;
174     *first_position = *second_position;
175     *second_position = tmp;
176 }
177 
ReplaceCharacterByIndex(uint32_t index,GlobalCharacter * new_character)178 GlobalCharacter* GlobalParty::ReplaceCharacterByIndex(uint32_t index, GlobalCharacter* new_character)
179 {
180     if(new_character == nullptr) {
181         IF_PRINT_WARNING(GLOBAL_DEBUG) << "function received a nullptr new_character argument" << std::endl;
182         return nullptr;
183     }
184     if(index >= _characters.size()) {
185         IF_PRINT_WARNING(GLOBAL_DEBUG) << "index argument exceeded current party size: " << index << std::endl;
186         return nullptr;
187     }
188 
189     GlobalCharacter *tmp = _characters[index];
190     _characters[index] = new_character;
191     return tmp;
192 }
193 
ReplaceCharacterByID(uint32_t id,GlobalCharacter * new_character)194 GlobalCharacter* GlobalParty::ReplaceCharacterByID(uint32_t id, GlobalCharacter* new_character)
195 {
196     if(_allow_duplicates) {
197         IF_PRINT_WARNING(GLOBAL_DEBUG) << "tried to replace character when duplicates were allowed in the party: " << id << std::endl;
198         return nullptr;
199     }
200     if(new_character == nullptr) {
201         IF_PRINT_WARNING(GLOBAL_DEBUG) << "function received a nullptr new_character argument" << std::endl;
202         return nullptr;
203     }
204 
205     GlobalCharacter *removed_character = nullptr;
206     for(std::vector<GlobalCharacter *>::iterator position = _characters.begin(); position != _characters.end(); ++position) {
207         if((*position)->GetID() == id) {
208             removed_character = *position;
209             *position = new_character;
210             break;
211         }
212     }
213 
214     if(removed_character == nullptr) {
215         IF_PRINT_WARNING(GLOBAL_DEBUG) << "failed to find an character in the party with the requested id: " << id << std::endl;
216     }
217 
218     return removed_character;
219 }
220 
AverageExperienceLevel() const221 float GlobalParty::AverageExperienceLevel() const
222 {
223     if(_characters.empty())
224         return 0.0f;
225 
226     float xp_level_sum = 0.0f;
227     for(uint32_t i = 0; i < _characters.size(); ++i)
228         xp_level_sum += static_cast<float>(_characters[i]->GetExperienceLevel());
229     return (xp_level_sum / static_cast<float>(_characters.size()));
230 }
231 
AddHitPoints(uint32_t hp)232 void GlobalParty::AddHitPoints(uint32_t hp)
233 {
234     for(std::vector<GlobalCharacter *>::iterator i = _characters.begin(); i != _characters.end(); ++i) {
235         (*i)->AddHitPoints(hp);
236     }
237 }
238 
AddSkillPoints(uint32_t sp)239 void GlobalParty::AddSkillPoints(uint32_t sp)
240 {
241     for(std::vector<GlobalCharacter *>::iterator i = _characters.begin(); i != _characters.end(); ++i) {
242         (*i)->AddSkillPoints(sp);
243     }
244 }
245 
246 // Returns the character party position
GetPartyPosition(GlobalCharacter * character)247 uint32_t GlobalParty::GetPartyPosition(GlobalCharacter* character) {
248     for (uint32_t i = 0; i < _characters.size(); ++i) {
249         if (_characters[i] == character)
250             return i;
251     }
252     // Default case
253     return 0;
254 }
255 
256 } // namespace vt_global
257