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_PARTY_H
24 #define NUVIE_CORE_PARTY_H
25 
26 #include "ultima/shared/std/string.h"
27 #include "ultima/nuvie/core/obj_manager.h"
28 #include "ultima/nuvie/core/map.h"
29 
30 namespace Ultima {
31 namespace Nuvie {
32 
33 class Configuration;
34 class Game;
35 class Actor;
36 class ActorManager;
37 class MapCoord;
38 class Map;
39 class NuvieIO;
40 class PartyPathFinder;
41 class PartySeek;
42 
43 typedef enum { TARGET_ACTOR, TARGET_LOCATION, TARGET_NONE } CombatTargetType;
44 
45 struct CombatTarget {
46 	CombatTargetType type;
47 	uint8 actor_num;
48 	MapCoord loc;
49 };
50 
51 struct PartyMember {
52 	char name[14];
53 	Actor *actor;
54 //bool inactive; // true if not in formation
55 	uint8 combat_position;
56 	sint8 form_x; // relative position left or right of leader
57 	sint8 form_y; // relative position in front or in back of leader
58 	// (leader is at 0,0 in formation)
59 	CombatTarget target;
60 };
61 
62 #define PARTY_MAX_MEMBERS 16
63 #define PARTY_NAME_MAX_LENGTH 13
64 
65 #define PARTY_KEEP_PARTY_FLAG true
66 
67 /* party walking formations: */
68 #define PARTY_FORM_STANDARD 0
69 #define PARTY_FORM_COLUMN   1
70 #define PARTY_FORM_ROW      2
71 #define PARTY_FORM_DELTA    3
72 #define PARTY_FORM_COMBAT   7
73 #define PARTY_FORM_REST     8
74 
75 /*   0 <- standard  *
76  *  1 2             *
77  * 4 3 5            *
78  *  6 7             *
79  *                  *
80  * 0 <- column      * 3210 <- row
81  * 1                * 7654
82  * 2                *
83  * 3...             *
84  *                  *
85  *    0 <- delta
86  *   172
87  *  38 94
88  * 5A   B6
89  *
90  * (Combat positions are dynamic, based on combat mode)
91  */
92 
93 class Party {
94 protected:
95 	friend class PartyPathFinder;
96 	Game *game; // get pointers here to avoid construct order issues in loadGame()
97 	Configuration *config;
98 	ActorManager *actor_manager;
99 	Map *map;
100 	PartyPathFinder *pathfinder;
101 
102 	PartyMember member[PARTY_MAX_MEMBERS];
103 	uint8 lightsources;
104 	uint8 num_in_party; // number of party members.
105 	uint8 formation; // walking formation
106 	uint16 prev_leader_x; // last location of leader
107 	uint16 prev_leader_y;
108 
109 	bool autowalk; // party is automatically walking to a destination
110 	bool in_vehicle; //Party is in a vehicle.
111 	bool in_combat_mode;
112 
113 	bool defer_removing_dead_members;
114 
115 	Obj *rest_campfire;
116 
117 public:
118 
119 	Party(Configuration *cfg);
120 	virtual ~Party();
121 
122 	virtual bool init(Game *g, ActorManager *am);
123 	virtual bool load(NuvieIO *objlist);
124 	virtual bool save(NuvieIO *objlist);
125 
126 // Basic methods
127 	void follow(sint8 rel_x, sint8 rel_y); // follow in direction leader moved
128 	bool move(uint16 dx, uint16 dy, uint8 dz);
129 	void show(); // Actor::show()
130 	void hide(); // Actor::hide()
131 	virtual void dismount_from_horses();
132 	virtual void update_music(); // set music depending on party location
133 	virtual void split_gold();
134 	virtual void gather_gold();
135 	bool add_actor(Actor *actor);
136 	bool remove_actor(Actor *actor, bool keep_party_flag = false);
137 	bool remove_dead_actor(Actor *actor);
138 	bool resurrect_dead_members();
139 	void heal();
140 	void cure();
141 	void set_ethereal(bool ethereal);
142 //void set_active(uint8 member_num, bool state) { member[member_num].inactive = !state; }
get_formation()143 	uint8 get_formation() {
144 		return formation;    // walking formation
145 	}
set_formation(uint8 val)146 	void set_formation(uint8 val) {
147 		formation = val;
148 		reform_party();
149 	}
150 // Properties
151 	uint8 get_party_size();
get_party_max()152 	virtual uint8 get_party_max() {
153 		return (8);    // U6
154 	}
155 	sint8 get_leader(); // returns -1 if party has no leader and can't move
156 	MapCoord get_leader_location();
157 	MapCoord get_location(uint8 m = 0);
158 	MapCoord get_formation_coords(uint8 m);
159 	void set_in_vehicle(bool value);
160 	void set_in_combat_mode(bool value);
is_in_vehicle()161 	bool is_in_vehicle() {
162 		return in_vehicle;
163 	}
is_in_combat_mode()164 	bool is_in_combat_mode() {
165 		return in_combat_mode;
166 	}
167 	Actor *get_slowest_actor(); // actor with lowest move count
168 
169 // Check specific actors
170 	uint8 get_actor_num(uint8 member_num); //get actor id_n from party_member num.
171 	Actor *get_actor(uint8 member_num);
172 	sint8 get_member_num(Actor *actor);
173 	sint8 get_member_num(uint8 a);
174 	Actor *get_leader_actor();
175 	char *get_actor_name(uint8 member_num);
is_leader(Actor * actor)176 	bool is_leader(Actor *actor) {
177 		return (get_member_num(actor) == get_leader());
178 	}
179 	bool contains_actor(Actor *actor);
180 	bool contains_actor(uint8 actor_num);
181 
182 // Check entire party
183 	bool is_at(uint16 x, uint16 y, uint8 z, uint32 threshold = 0);
184 	bool is_at(MapCoord &xyz, uint32 threshold = 0);
185 	bool is_anyone_at(uint16 x, uint16 y, uint8 z, uint32 threshold = 0);
186 	bool is_anyone_at(MapCoord &xyz, uint32 threshold = 0);
187 	bool has_obj(uint16 obj_n, uint8 quality, bool match_zero_qual = true);
188 	bool remove_obj(uint16 obj_n, uint8 quality);
189 	Actor *who_has_obj(uint16 obj_n, uint8 quality, bool match_zero_qual = true);
190 	Obj *get_obj(uint16 obj_n, uint8 quality, bool match_qual_zero = true, uint8 frame_n = 0, bool match_frame_n = false);
191 	bool is_horsed(); // is anyone on a horse?
192 	bool is_everyone_horsed();
193 	Obj *get_food(); // used while resting
194 
195 // Automatic-walking. These methods should be replaced with ActorActions.
196 	void walk(MapCoord *walkto, MapCoord *teleport, uint32 step_delay = 0);
197 	void walk(MapCoord *walkto, uint32 step_delay = 0) {
198 		walk(walkto, NULL, step_delay);
199 	}
200 	void walk(Obj *moongate, MapCoord *teleport, uint32 step_delay = 0);
201 	void enter_vehicle(Obj *ship_obj, uint32 step_delay = 0);
202 	void exit_vehicle(uint16 x, uint16 y, uint16 z);
203 	void stop_walking(bool force_music_change);
get_autowalk()204 	bool get_autowalk() {
205 		return (autowalk);
206 	}
207 	void rest_gather();
208 	void rest_sleep(uint8 hours, sint16 guard);
209 	bool can_rest(Std::string &err_str);
210 
211 	void set_combat_target(uint8 member_num, Actor *target);
212 	void set_combat_target(uint8 member_num, MapCoord target);
213 	void clear_combat_target(uint8 member_num);
214 	CombatTarget get_combat_target(uint8 member_num);
215 	bool has_light_source();
add_light_source()216 	void add_light_source() {
217 		lightsources++; /* fprintf(stderr, "lightsources = %d\n", lightsources); */
218 	}
subtract_light_source()219 	void subtract_light_source() { /*assert(lightsources != 0);*/
220 		lightsources--; /*fprintf(stderr, "lightsources = %d\n", lightsources); */
221 	}
222 	void update_light_sources();
223 
224 	bool combat_changes_music, vehicles_change_music;
225 
226 protected:
227 	void reform_party(); // call when adding or removing members
228 
229 };
230 
231 } // End of namespace Nuvie
232 } // End of namespace Ultima
233 
234 #endif
235