1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #ifndef NUVIE_CORE_MAGIC_H
24 #define NUVIE_CORE_MAGIC_H
25 
26 #include "ultima/nuvie/core/events.h"
27 #include "ultima/nuvie/misc/call_back.h"
28 
29 namespace Ultima {
30 namespace Nuvie {
31 
32 #define REAGENT_U6_MANDRAKE_ROOT 0x01
33 #define REAGENT_U6_NIGHTSHADE    0x02
34 #define REAGENT_U6_BLACK_PEARL   0x04
35 #define REAGENT_U6_BLOOD_MOSS    0x08
36 #define REAGENT_U6_SPIDER_SILK   0x10
37 #define REAGENT_U6_GARLIC        0x20
38 #define REAGENT_U6_GINSENG       0x40
39 #define REAGENT_U6_SULFUROUS_ASH 0x80
40 
41 #define MAX_SCRIPT_LENGTH 65000
42 #define MAX_TOKEN_LENGTH 255
43 #define MAX_STACK_DEPTH 255
44 
45 #define MAGIC_STATE_READY      0x00
46 #define MAGIC_STATE_SELECT_SPELL   0x01
47 #define MAGIC_STATE_PROCESS_SCRIPT 0x02
48 #define MAGIC_STATE_ACQUIRE_TARGET 0x03
49 #define MAGIC_STATE_ACQUIRE_INPUT  0x04
50 #define MAGIC_STATE_ACQUIRE_DIRECTION  0x05
51 #define MAGIC_STATE_ACQUIRE_INV_OBJ  0x06
52 #define MAGIC_STATE_TALK_TO_ACTOR 0x07
53 #define MAGIC_STATE_ACQUIRE_SPELL  0x08
54 #define MAGIC_STATE_ACQUIRE_OBJ    0x09
55 
56 #define MAGIC_ALL_SPELLS 255
57 
58 class ScriptThread;
59 class NuvieIOFileRead;
60 
61 class Spell {
62 public: /* saves using dumb get / set functions */
63 	uint8 num;
64 	char *name;  // eg. "Heal"
65 	char *invocation;  // eg. "im"
66 	uint8 reagents; // reagents used
67 
68 	Spell(uint8 new_num, const char *new_name = "undefined name", const char *new_invocation = "kawo", uint8 new_reagents = 255) {
69 		num = new_num;
70 		name = scumm_strdup(new_name);
71 		invocation = scumm_strdup(new_invocation);
72 		reagents = new_reagents;
73 	};
~Spell()74 	~Spell() {
75 		delete[] name;
76 		delete[] invocation;
77 	}
78 };
79 
80 class Magic : public CallBack {
81 private:
82 	Spell *spell[256]; // spell list;
83 	char cast_buffer_str[26]; // buffer for spell syllables typed.
84 	uint8 cast_buffer_len; // how many characters typed in the spell buffer.
85 	Events *event;
86 	//Actor *target_actor;
87 	Obj *target_object;
88 	uint8 state;
89 
90 	ScriptThread *magic_script;
91 	Obj *spellbook_obj;
92 	/* TODO
93 	 * add a register array, or a pointer to a list of variables?
94 	 */
95 public:
96 	Magic();
97 	~Magic() override;
98 	bool init(Events *evt);
99 
100 	bool read_spell_list();
clear_cast_buffer()101 	void clear_cast_buffer() {
102 		cast_buffer_str[0] = '\0';
103 		cast_buffer_len = 0;
104 	}
105 	bool start_new_spell();
106 	Obj *book_equipped();
107 	bool cast();
108 	void cast_spell_directly(uint8 spell_num);
109 
110 	uint16 callback(uint16 msg, CallBack *caller, void *data = NULL) override;
111 	bool process_script_return(uint8 ret);
112 	bool resume(MapCoord location);
113 	bool resume(uint8 dir);
114 	bool resume_with_spell_num(uint8 spell_num);
115 	bool resume(Obj *obj);
116 	bool resume();
is_waiting_for_location()117 	bool is_waiting_for_location() {
118 		if (magic_script && state == MAGIC_STATE_ACQUIRE_TARGET) return true;
119 		else return false;
120 	}
is_waiting_for_direction()121 	bool is_waiting_for_direction() {
122 		if (magic_script && state == MAGIC_STATE_ACQUIRE_DIRECTION) return true;
123 		else return false;
124 	}
is_waiting_for_inventory_obj()125 	bool is_waiting_for_inventory_obj() {
126 		if (magic_script && state == MAGIC_STATE_ACQUIRE_INV_OBJ) return true;
127 		else return false;
128 	}
is_waiting_for_obj()129 	bool is_waiting_for_obj() {
130 		if (magic_script && state == MAGIC_STATE_ACQUIRE_OBJ) return true;
131 		else return false;
132 	}
is_waiting_to_talk()133 	bool is_waiting_to_talk() {
134 		if (state == MAGIC_STATE_TALK_TO_ACTOR) return true;
135 		else return false;
136 	}
is_waiting_for_spell()137 	bool is_waiting_for_spell() {
138 		if (magic_script && state == MAGIC_STATE_ACQUIRE_SPELL) return true;
139 		else return false;
140 	}
is_selecting_spell()141 	bool is_selecting_spell() {
142 		if (magic_script && state == MAGIC_STATE_SELECT_SPELL) return true;
143 		else return false;
144 	}
145 
is_waiting_to_resume()146 	bool is_waiting_to_resume() {
147 		if (magic_script) return true;
148 		else return false;
149 	}
150 
get_spell(uint8 spell_num)151 	Spell *get_spell(uint8 spell_num) {
152 		return spell[spell_num];
153 	}
get_spellbook_obj()154 	Obj *get_spellbook_obj() {
155 		return spellbook_obj;
156 	}
157 
158 	Actor *get_actor_from_script();
159 	void show_spell_description(uint8 index);
160 private:
161 	bool spellbook_has_spell(Obj *book, uint8 spell_index);
162 	void display_ingredients(uint8 index);
163 	void display_spell_incantation(uint8 index);
164 
165 };
166 
167 } // End of namespace Nuvie
168 } // End of namespace Ultima
169 
170 #endif
171