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_USECODE_USECODE_H 24 #define NUVIE_USECODE_USECODE_H 25 26 #include "ultima/shared/std/string.h" 27 #include "ultima/nuvie/misc/call_back.h" 28 #include "ultima/nuvie/misc/map_entity.h" 29 #include "ultima/nuvie/core/obj_manager.h" 30 #include "ultima/nuvie/core/player.h" 31 32 namespace Ultima { 33 namespace Nuvie { 34 35 // The game triggers one of these events on an object to activate its UseCode 36 // function(s). The return value meaning is different for each event. 37 #define USE_EVENT_USE 0x01 /* return value undefined */ 38 #define USE_EVENT_LOOK 0x02 /* true: allow search, false: disallow search */ 39 #define USE_EVENT_PASS 0x04 /* true: do normal move, false: object blocks */ 40 #define USE_EVENT_MESSAGE 0x08 /* internal message or data return */ 41 #define USE_EVENT_SEARCH 0x10 /*undefined (true = had objects?); might remove*/ 42 //#define USE_EVENT_ON 0x20 /* post-move/idle */ 43 #define USE_EVENT_MOVE 0x40 /* true: move object, false: don't move object */ 44 #define USE_EVENT_LOAD 0x80 /* return value undefined */ 45 #define USE_EVENT_READY 0x0100 /* true: object may be equipped */ 46 #define USE_EVENT_GET 0x0200 /* true: do normal get */ 47 #define USE_EVENT_DROP 0x0400 /* true: do normal drop */ 48 #define USE_EVENT_INPUT_CANCEL 0x501 /* note this shares a bit with USE_EVENT_USE so it can pass through uc_event(). return undefined */ 49 //#define USE_EVENT_NEAR 0x00 /* mirrors; might use ON with distance val */ 50 //#define USE_EVENT_ATTACK 0x00 /* doors, chests, mirrors */ 51 //#define USE_EVENT_ENTER 0x00 /* object enters view (clocks) */ 52 //#define USE_EVENT_LEAVE 0x00 /* object leaves view */ 53 54 typedef uint16 UseCodeEvent; 55 56 /* Events: 57 * USE 58 * Returns: undefined 59 * Use the object. 60 * actor_ref - the actor using it (the player actor typically) 61 * 62 * PASS (Quest Barrier) 63 * Returns: True if actor may move, False if object blocks 64 * Called when an actor attempts to step onto an object. 65 * actor_ref - actor trying to pass 66 * mapcoord_ref - location the actor is trying to pass (for multi-tile objects) 67 * 68 * LOOK (signs) 69 * Returns: True if an object can be searched 70 * Called when someone looks at the object. Some objects aren't searched (books 71 * for example) and should return false. 72 * 73 * MESSAGE (fumaroles, earthquakes?, powder kegs, clocks) 74 * An internal event from the engine. It must have been previously requested. 75 * Includes TIMED events, and DATA returns. Be careful that the object still 76 * exists. 77 * 78 * MOVE (cannons) 79 * Returns: True to push object to the new position 80 * Use this to perform special move functions for some objects. A cannon can be 81 * aimed with MOVE. 82 * mapcoord_ref - target location 83 * 84 * (UN)LOAD unimplemented (fumaroles) 85 * Returns: undefined 86 * Called when the object is cached in or out (or when it would have been in the 87 * original game... about 16 to 32 spaces away), and when new objects are created. 88 * It can be used to start timers, or to hatch eggs. 89 * 90 * Actor NEAR unimplemented (mirrors) 91 * Set something to happen when an actor moves close to or away from object. 92 * Distance will be used. 93 * 94 * Actor ON (chairs, traps) unimplemented 95 * Returns: undefined 96 * Called each turn for any objects in the view-area with actors standing on 97 * them. 98 * 99 * ENTER view-area unimplemented 100 * 101 * LEAVE view-area unimplemented 102 * Enter and leave will be used to start and stop sound effects. Distance will 103 * be used. 104 * 105 * (UN)READY (Amulet of Submission) 106 * Returns: True if the object may be worn, or removed 107 * This is called before the object is is equipped or removed. Check the 108 * object's flags to determine if it is being equipped or not. (if its readied 109 * flag is set it is being removed). Special un/ready functions can be created 110 * with this. 111 * actor_ref - the actor un/readying it 112 * 113 * ATTACK (doors, chests) 114 * 115 * DROP (breakables, torches) 116 * Returns: True to allow normal drop at the target. 117 * Special drop functions can be created with this. 118 * actor_ref - the actor dropping it 119 * mapcoord_ref - the desired drop target 120 * 121 * GET (torches, runes?) 122 * Returns: True if the actor can get the object. 123 * Special get functions can be created with this. 124 * actor_ref - the actor getting it 125 * 126 * SEARCH (graves, secret doors) 127 * Returns: True if the object contained other objects. 128 * FIXME: might remove this and add as a player action 129 * 130 */ 131 132 typedef enum { 133 USE, 134 GET, 135 MOVE 136 } UseCodeType; 137 138 const char *useCodeTypeToString(UseCodeType type); 139 140 class ActorManager; 141 class Configuration; 142 class Events; 143 class Game; 144 class Map; 145 class MsgScroll; 146 class MapCoord; 147 class Party; 148 class Player; 149 class Script; 150 class ScriptThread; 151 152 class UseCode { 153 private: 154 ScriptThread *script_thread; 155 156 protected: 157 Game *game; 158 Configuration *config; 159 ObjManager *obj_manager; 160 Map *map; 161 Player *player; 162 MsgScroll *scroll; 163 ActorManager *actor_manager; 164 Party *party; 165 Script *script; 166 167 // pass parameters to usecode functions via items (NULL itemref is unset) 168 struct { 169 uint32 *uint_ref; 170 sint32 *sint_ref; 171 Obj *obj_ref; 172 Actor *actor_ref, *actor2_ref; 173 MapCoord *mapcoord_ref; 174 CallbackMessage *msg_ref; 175 Std::string *string_ref; 176 MapEntity *ent_ref; 177 char *data_ref; 178 } items; 179 void clear_items(); 180 181 public: 182 183 UseCode(Game *g, Configuration *cfg); 184 virtual ~UseCode(); 185 186 virtual bool init(ObjManager *om, Map *m, Player *p, MsgScroll *ms); 187 188 bool use_obj(uint16 x, uint16 y, uint8 z, Obj *src_obj = NULL); 189 bool use_obj(Obj *obj, Obj *src_obj = NULL) { 190 return (use_obj(obj, player->get_actor())); // ?? 191 } 192 193 virtual bool use_obj(Obj *obj, Actor *actor); look_obj(Obj * obj,Actor * actor)194 virtual bool look_obj(Obj *obj, Actor *actor) { 195 return (false); 196 } pass_obj(Obj * obj,Actor * actor,uint16 x,uint16 y)197 virtual bool pass_obj(Obj *obj, Actor *actor, uint16 x, uint16 y) { 198 return (false); 199 } search_obj(Obj * obj,Actor * actor)200 virtual bool search_obj(Obj *obj, Actor *actor) { 201 return (false); 202 } 203 virtual bool move_obj(Obj *obj, sint16 rel_x, sint16 rel_y); load_obj(Obj * obj)204 virtual bool load_obj(Obj *obj) { 205 return (false); 206 } message_obj(Obj * obj,CallbackMessage msg,void * msg_data)207 virtual bool message_obj(Obj *obj, CallbackMessage msg, void *msg_data) { 208 return (false); 209 } 210 virtual bool ready_obj(Obj *obj, Actor *actor); get_obj(Obj * obj,Actor * actor)211 virtual bool get_obj(Obj *obj, Actor *actor) { 212 return (false); 213 } 214 virtual bool drop_obj(Obj *obj, Actor *actor, uint16 x, uint16 y, uint16 qty = 0) { 215 return (false); 216 } 217 218 virtual bool has_usecode(Obj *obj, UseCodeEvent ev = USE_EVENT_USE); 219 virtual bool has_usecode(Actor *actor, UseCodeEvent ev = USE_EVENT_USE) { 220 return (false); 221 } has_lookcode(Obj * obj)222 virtual bool has_lookcode(Obj *obj) { 223 return (has_usecode(obj, USE_EVENT_LOOK)); 224 } has_passcode(Obj * obj)225 virtual bool has_passcode(Obj *obj) { 226 return (has_usecode(obj, USE_EVENT_PASS)); 227 } has_movecode(Obj * obj)228 virtual bool has_movecode(Obj *obj) { 229 return (has_usecode(obj, USE_EVENT_MOVE)); 230 } has_loadcode(Obj * obj)231 virtual bool has_loadcode(Obj *obj) { 232 return (has_usecode(obj, USE_EVENT_LOAD)); 233 } has_readycode(Obj * obj)234 virtual bool has_readycode(Obj *obj) { 235 return (has_usecode(obj, USE_EVENT_READY)); 236 } cannot_unready(Obj * obj)237 virtual bool cannot_unready(Obj *obj) { 238 return false; 239 } has_getcode(Obj * obj)240 virtual bool has_getcode(Obj *obj) { 241 return (has_usecode(obj, USE_EVENT_GET)); 242 } has_dropcode(Obj * obj)243 virtual bool has_dropcode(Obj *obj) { 244 return (has_usecode(obj, USE_EVENT_DROP)); 245 } 246 is_door(Obj * obj)247 bool is_door(Obj *obj) { 248 return (is_locked_door(obj) || is_unlocked_door(obj)); 249 } is_locked_door(Obj * obj)250 virtual bool is_locked_door(Obj *obj) { 251 return (false); 252 } is_unlocked_door(Obj * obj)253 virtual bool is_unlocked_door(Obj *obj) { 254 return (false); 255 } is_closed_door(Obj * obj)256 virtual bool is_closed_door(Obj *obj) { 257 return (false); 258 } process_effects(Obj * container_obj,Actor * actor)259 virtual bool process_effects(Obj *container_obj, Actor *actor) { 260 return (false); 261 } is_food(Obj * obj)262 virtual bool is_food(Obj *obj) { 263 return (false); 264 } 265 virtual bool is_container(Obj *obj); is_container(uint16 obj_n,uint8 frame_n)266 virtual bool is_container(uint16 obj_n, uint8 frame_n) { 267 return (false); 268 } is_readable(Obj * obj)269 virtual bool is_readable(Obj *obj) { 270 return (false); 271 } is_chest(Obj * obj)272 virtual bool is_chest(Obj *obj) { 273 return (false); 274 } 275 set_itemref(sint32 * val)276 void set_itemref(sint32 *val) { 277 items.sint_ref = val; 278 } set_itemref(Obj * val)279 void set_itemref(Obj *val) { 280 items.obj_ref = val; 281 } 282 void set_itemref(Actor *val, Actor *val2 = NULL) { 283 items.actor_ref = val; 284 items.actor2_ref = val2; 285 } set_itemref(MapCoord * val)286 void set_itemref(MapCoord *val) { 287 items.mapcoord_ref = val; 288 } 289 290 Obj *get_obj_from_container(Obj *obj); 291 bool search_container(Obj *obj, bool show_string = true); 292 Obj *destroy_obj(Obj *obj, uint32 count = 0, bool run_usecode = true); 293 bool out_of_use_range(Obj *obj, bool check_enemies); 294 295 ScriptThread *get_running_script(); 296 bool is_script_running(); 297 298 protected: 299 300 void toggle_frame(Obj *obj); 301 void dbg_print_event(UseCodeEvent event, Obj *obj); 302 303 }; 304 305 } // End of namespace Nuvie 306 } // End of namespace Ultima 307 308 #endif 309