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 == &copy) // 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