1 ////////////////////////////////////////////////////////////////////////////////
2 // Copyright (C) 2004-2010 by The Allacrost Project
3 // All Rights Reserved
4 //
5 // This code is licensed under the GNU GPL version 2. It is free software
6 // and you may modify it and/or redistribute it under the terms of this license.
7 // See http://www.gnu.org/copyleft/gpl.html for details.
8 ////////////////////////////////////////////////////////////////////////////////
9
10 /** ****************************************************************************
11 *** \file global_objects.cpp
12 *** \author Tyler Olsen, roots@allacrost.org
13 *** \brief Source file for global game objects
14 *** ***************************************************************************/
15
16 #include "script.h"
17 #include "video.h"
18
19 #include "global_objects.h"
20 #include "global_effects.h"
21 #include "global.h"
22
23 using namespace std;
24
25 using namespace hoa_utils;
26 using namespace hoa_script;
27 using namespace hoa_video;
28
29 using namespace hoa_global::private_global;
30
31 namespace hoa_global {
32
33 ////////////////////////////////////////////////////////////////////////////////
34 // GlobalObject class
35 ////////////////////////////////////////////////////////////////////////////////
36
_LoadObjectData(hoa_script::ReadScriptDescriptor & script)37 void GlobalObject::_LoadObjectData(hoa_script::ReadScriptDescriptor& script) {
38 _name = MakeUnicodeString(script.ReadString("name"));
39 _description = MakeUnicodeString(script.ReadString("description"));
40 _price = script.ReadUInt("standard_price");
41 string icon_file = script.ReadString("icon");
42 if (_icon_image.Load(icon_file) == false) {
43 IF_PRINT_WARNING(GLOBAL_DEBUG) << "failed to load icon image for item: " << _id << endl;
44 _InvalidateObject();
45 }
46 }
47
48 ////////////////////////////////////////////////////////////////////////////////
49 // GlobalItem class
50 ////////////////////////////////////////////////////////////////////////////////
51
GlobalItem(uint32 id,uint32 count)52 GlobalItem::GlobalItem(uint32 id, uint32 count) :
53 GlobalObject(id, count)
54 {
55 if ((_id == 0) || (_id > MAX_ITEM_ID)) {
56 IF_PRINT_WARNING(GLOBAL_DEBUG) << "invalid id in constructor: " << _id << endl;
57 _InvalidateObject();
58 return;
59 }
60
61 ReadScriptDescriptor& script_file = GlobalManager->GetItemsScript();
62 if (script_file.DoesTableExist(_id) == false) {
63 IF_PRINT_WARNING(GLOBAL_DEBUG) << "no valid data for item in definition file: " << _id << endl;
64 _InvalidateObject();
65 return;
66 }
67
68 // Load the item data from the script
69 script_file.OpenTable(_id);
70 _LoadObjectData(script_file);
71
72 _target_type = static_cast<GLOBAL_TARGET>(script_file.ReadInt("target_type"));
73 if (script_file.DoesFunctionExist("BattleUse")) {
74 _battle_use_function = new ScriptObject();
75 *_battle_use_function = script_file.ReadFunctionPointer("BattleUse");
76 }
77 if (script_file.DoesFunctionExist("FieldUse")) {
78 _field_use_function = new ScriptObject();
79 *_field_use_function = script_file.ReadFunctionPointer("FieldUse");
80 }
81
82
83 script_file.CloseTable();
84 if (script_file.IsErrorDetected()) {
85 if (GLOBAL_DEBUG) {
86 PRINT_WARNING << "one or more errors occurred while reading item data - they are listed below" << endl;
87 cerr << script_file.GetErrorMessages() << endl;
88 }
89 _InvalidateObject();
90 }
91 } // void GlobalItem::GlobalItem(uint32 id, uint32 count = 1)
92
93
94
~GlobalItem()95 GlobalItem::~GlobalItem() {
96 if (_battle_use_function != NULL) {
97 delete _battle_use_function;
98 _battle_use_function = NULL;
99 }
100 if (_field_use_function != NULL) {
101 delete _field_use_function;
102 _field_use_function = NULL;
103 }
104 }
105
106
107
GlobalItem(const GlobalItem & copy)108 GlobalItem::GlobalItem(const GlobalItem& copy) :
109 GlobalObject(copy)
110 {
111 _target_type = copy._target_type;
112
113 // Make copies of valid ScriptObject function pointers
114 if (copy._battle_use_function == NULL)
115 _battle_use_function = NULL;
116 else
117 _battle_use_function = new ScriptObject(*copy._battle_use_function);
118
119 if (copy._field_use_function == NULL)
120 _field_use_function = NULL;
121 else
122 _field_use_function = new ScriptObject(*copy._field_use_function);
123 }
124
125
126
operator =(const GlobalItem & copy)127 GlobalItem& GlobalItem::operator=(const GlobalItem& copy) {
128 if (this == ©) // Handle self-assignment case
129 return *this;
130
131 GlobalObject::operator=(copy);
132 _target_type = copy._target_type;
133
134 // Make copies of valid ScriptObject function pointers
135 if (copy._battle_use_function == NULL)
136 _battle_use_function = NULL;
137 else
138 _battle_use_function = new ScriptObject(*copy._battle_use_function);
139
140 if (copy._field_use_function == NULL)
141 _field_use_function = NULL;
142 else
143 _field_use_function = new ScriptObject(*copy._field_use_function);
144
145 return *this;
146 }
147
148 ////////////////////////////////////////////////////////////////////////////////
149 // GlobalWeapon class
150 ////////////////////////////////////////////////////////////////////////////////
151
GlobalWeapon(uint32 id,uint32 count)152 GlobalWeapon::GlobalWeapon(uint32 id, uint32 count) :
153 GlobalObject(id, count)
154 {
155 // Initialize all elemental effects as neutral
156 _elemental_effects.insert(pair<GLOBAL_ELEMENTAL, GLOBAL_INTENSITY>(GLOBAL_ELEMENTAL_FIRE, GLOBAL_INTENSITY_NEUTRAL));
157 _elemental_effects.insert(pair<GLOBAL_ELEMENTAL, GLOBAL_INTENSITY>(GLOBAL_ELEMENTAL_WATER, GLOBAL_INTENSITY_NEUTRAL));
158 _elemental_effects.insert(pair<GLOBAL_ELEMENTAL, GLOBAL_INTENSITY>(GLOBAL_ELEMENTAL_VOLT, GLOBAL_INTENSITY_NEUTRAL));
159 _elemental_effects.insert(pair<GLOBAL_ELEMENTAL, GLOBAL_INTENSITY>(GLOBAL_ELEMENTAL_EARTH, GLOBAL_INTENSITY_NEUTRAL));
160 _elemental_effects.insert(pair<GLOBAL_ELEMENTAL, GLOBAL_INTENSITY>(GLOBAL_ELEMENTAL_SLICING, GLOBAL_INTENSITY_NEUTRAL));
161 _elemental_effects.insert(pair<GLOBAL_ELEMENTAL, GLOBAL_INTENSITY>(GLOBAL_ELEMENTAL_SMASHING, GLOBAL_INTENSITY_NEUTRAL));
162 _elemental_effects.insert(pair<GLOBAL_ELEMENTAL, GLOBAL_INTENSITY>(GLOBAL_ELEMENTAL_MAULING, GLOBAL_INTENSITY_NEUTRAL));
163 _elemental_effects.insert(pair<GLOBAL_ELEMENTAL, GLOBAL_INTENSITY>(GLOBAL_ELEMENTAL_PIERCING, GLOBAL_INTENSITY_NEUTRAL));
164
165 if ((_id <= MAX_ITEM_ID) || (_id > MAX_WEAPON_ID)) {
166 IF_PRINT_WARNING(GLOBAL_DEBUG) << "invalid id in constructor: " << _id << endl;
167 _InvalidateObject();
168 return;
169 }
170
171 ReadScriptDescriptor& script_file = GlobalManager->GetWeaponsScript();
172 if (script_file.DoesTableExist(_id) == false) {
173 IF_PRINT_WARNING(GLOBAL_DEBUG) << "no valid data for weapon in definition file: " << _id << endl;
174 _InvalidateObject();
175 return;
176 }
177
178 // Load the weapon data from the script
179 script_file.OpenTable(_id);
180 _LoadObjectData(script_file);
181
182 _physical_attack = script_file.ReadUInt("physical_attack");
183 _metaphysical_attack = script_file.ReadUInt("metaphysical_attack");
184 _usable_by = script_file.ReadUInt("usable_by");
185
186 script_file.CloseTable();
187 if (script_file.IsErrorDetected()) {
188 if (GLOBAL_DEBUG) {
189 PRINT_WARNING << "one or more errors occurred while reading weapon data - they are listed below" << endl;
190 cerr << script_file.GetErrorMessages() << endl;
191 }
192 _InvalidateObject();
193 }
194 } // void GlobalWeapon::GlobalWeapon(uint32 id, uint32 count = 1)
195
196 ////////////////////////////////////////////////////////////////////////////////
197 // GlobalArmor class
198 ////////////////////////////////////////////////////////////////////////////////
199
GlobalArmor(uint32 id,uint32 count)200 GlobalArmor::GlobalArmor(uint32 id, uint32 count) :
201 GlobalObject(id, count)
202 {
203 // Initialize all elemental effects as neutral
204 _elemental_effects.insert(pair<GLOBAL_ELEMENTAL, GLOBAL_INTENSITY>(GLOBAL_ELEMENTAL_FIRE, GLOBAL_INTENSITY_NEUTRAL));
205 _elemental_effects.insert(pair<GLOBAL_ELEMENTAL, GLOBAL_INTENSITY>(GLOBAL_ELEMENTAL_WATER, GLOBAL_INTENSITY_NEUTRAL));
206 _elemental_effects.insert(pair<GLOBAL_ELEMENTAL, GLOBAL_INTENSITY>(GLOBAL_ELEMENTAL_VOLT, GLOBAL_INTENSITY_NEUTRAL));
207 _elemental_effects.insert(pair<GLOBAL_ELEMENTAL, GLOBAL_INTENSITY>(GLOBAL_ELEMENTAL_EARTH, GLOBAL_INTENSITY_NEUTRAL));
208 _elemental_effects.insert(pair<GLOBAL_ELEMENTAL, GLOBAL_INTENSITY>(GLOBAL_ELEMENTAL_SLICING, GLOBAL_INTENSITY_NEUTRAL));
209 _elemental_effects.insert(pair<GLOBAL_ELEMENTAL, GLOBAL_INTENSITY>(GLOBAL_ELEMENTAL_SMASHING, GLOBAL_INTENSITY_NEUTRAL));
210 _elemental_effects.insert(pair<GLOBAL_ELEMENTAL, GLOBAL_INTENSITY>(GLOBAL_ELEMENTAL_MAULING, GLOBAL_INTENSITY_NEUTRAL));
211 _elemental_effects.insert(pair<GLOBAL_ELEMENTAL, GLOBAL_INTENSITY>(GLOBAL_ELEMENTAL_PIERCING, GLOBAL_INTENSITY_NEUTRAL));
212
213 if ((_id <= MAX_WEAPON_ID) || (_id > MAX_LEG_ARMOR_ID)) {
214 IF_PRINT_WARNING(GLOBAL_DEBUG) << "invalid id in constructor: " << _id << endl;
215 _InvalidateObject();
216 return;
217 }
218
219 // Figure out the appropriate script reference to grab based on the id value
220 ReadScriptDescriptor* script_file;
221 switch (GetObjectType()) {
222 case GLOBAL_OBJECT_HEAD_ARMOR:
223 script_file = &(GlobalManager->GetHeadArmorScript());
224 break;
225 case GLOBAL_OBJECT_TORSO_ARMOR:
226 script_file = &(GlobalManager->GetTorsoArmorScript());
227 break;
228 case GLOBAL_OBJECT_ARM_ARMOR:
229 script_file = &(GlobalManager->GetArmArmorScript());
230 break;
231 case GLOBAL_OBJECT_LEG_ARMOR:
232 script_file = &(GlobalManager->GetLegArmorScript());
233 break;
234 default:
235 IF_PRINT_WARNING(GLOBAL_DEBUG) << "could not determine armor type: " << _id << endl;
236 _InvalidateObject();
237 return;
238 }
239
240 if (script_file->DoesTableExist(_id) == false) {
241 IF_PRINT_WARNING(GLOBAL_DEBUG) << "no valid data for armor in definition file: " << _id << endl;
242 _InvalidateObject();
243 return;
244 }
245
246 // Load the armor data from the script
247 script_file->OpenTable(_id);
248 _LoadObjectData(*script_file);
249
250 _physical_defense = script_file->ReadUInt("physical_defense");
251 _metaphysical_defense = script_file->ReadUInt("metaphysical_defense");
252 _usable_by = script_file->ReadUInt("usable_by");
253
254 script_file->CloseTable();
255 if (script_file->IsErrorDetected()) {
256 if (GLOBAL_DEBUG) {
257 PRINT_WARNING << "one or more errors occurred while reading armor data - they are listed below" << endl;
258 cerr << script_file->GetErrorMessages() << endl;
259 }
260 _InvalidateObject();
261 }
262 } // void GlobalArmor::GlobalArmor(uint32 id, uint32 count = 1)
263
264
265
GetObjectType() const266 GLOBAL_OBJECT GlobalArmor::GetObjectType() const {
267 if ((_id > MAX_WEAPON_ID) && (_id <= MAX_HEAD_ARMOR_ID))
268 return GLOBAL_OBJECT_HEAD_ARMOR;
269 else if ((_id > MAX_HEAD_ARMOR_ID) && (_id <= MAX_TORSO_ARMOR_ID))
270 return GLOBAL_OBJECT_TORSO_ARMOR;
271 else if ((_id > MAX_TORSO_ARMOR_ID) && (_id <= MAX_ARM_ARMOR_ID))
272 return GLOBAL_OBJECT_ARM_ARMOR;
273 else if ((_id > MAX_ARM_ARMOR_ID) && (_id <= MAX_LEG_ARMOR_ID))
274 return GLOBAL_OBJECT_LEG_ARMOR;
275 else
276 return GLOBAL_OBJECT_INVALID;
277 }
278
279 ////////////////////////////////////////////////////////////////////////////////
280 // GlobalShard class
281 ////////////////////////////////////////////////////////////////////////////////
282
GlobalShard(uint32 id,uint32 count)283 GlobalShard::GlobalShard(uint32 id, uint32 count) :
284 GlobalObject(id, count)
285 {
286 if ((_id <= MAX_LEG_ARMOR_ID) || (_id > MAX_SHARD_ID)) {
287 IF_PRINT_WARNING(GLOBAL_DEBUG) << "invalid id in constructor: " << _id << endl;
288 _InvalidateObject();
289 return;
290 }
291
292 // TODO: uncomment the code below when shards scripts are available
293 // ReadScriptDescriptor& script_file = GlobalManager->GetShardsScript();
294 // if (script_file.DoesTableExist(_id) == false) {
295 // IF_PRINT_WARNING(GLOBAL_DEBUG) << "no valid data for shard in definition file: " << _id << endl;
296 // _InvalidateObject();
297 // return;
298 // }
299 //
300 // // Load the shard data from the script
301 // script_file.OpenTable(_id);
302 // _LoadObjectData(script_file);
303 //
304 // script_file.CloseTable();
305 // if (script_file.IsErrorDetected()) {
306 // if (GLOBAL_DEBUG) {
307 // PRINT_WARNING << "one or more errors occurred while reading shard data - they are listed below" << endl;
308 // cerr << script_file.GetErrorMessages() << endl;
309 // }
310 // _InvalidateObject();
311 // }
312 } // void GlobalShard::GlobalShard(uint32 id, uint32 count = 1)
313
314 ////////////////////////////////////////////////////////////////////////////////
315 // GlobalKeyItem class
316 ////////////////////////////////////////////////////////////////////////////////
317
GlobalKeyItem(uint32 id,uint32 count)318 GlobalKeyItem::GlobalKeyItem(uint32 id, uint32 count) :
319 GlobalObject(id, count)
320 {
321 if ((_id <= MAX_SHARD_ID) || (_id > MAX_KEY_ITEM_ID)) {
322 IF_PRINT_WARNING(GLOBAL_DEBUG) << "invalid id in constructor: " << _id << endl;
323 _InvalidateObject();
324 return;
325 }
326
327 // TODO: uncomment the code below when key item scripts are available
328 // ReadScriptDescriptor& script_file = GlobalManager->GetKeyItemsScript();
329 // if (script_file.DoesTableExist(_id) == false) {
330 // IF_PRINT_WARNING(GLOBAL_DEBUG) << "no valid data for key item in definition file: " << _id << endl;
331 // _InvalidateObject();
332 // return;
333 // }
334 //
335 // // Load the key item data from the script
336 // script_file.OpenTable(_id);
337 // _LoadObjectData(script_file);
338 //
339 // script_file.CloseTable();
340 // if (script_file.IsErrorDetected()) {
341 // if (GLOBAL_DEBUG) {
342 // PRINT_WARNING << "one or more errors occurred while reading key item data - they are listed below" << endl;
343 // cerr << script_file.GetErrorMessages() << endl;
344 // }
345 // _InvalidateObject();
346 // }
347 } // void GlobalKeyItem::GlobalKeyItem(uint32 id, uint32 count = 1)
348
349 } // namespace hoa_global
350