Initial commit
This commit is contained in:
193
engines/ultima/nuvie/usecode/u6_object_types.h
Normal file
193
engines/ultima/nuvie/usecode/u6_object_types.h
Normal file
@@ -0,0 +1,193 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
class U6UseCode;
|
||||
|
||||
const U6ObjectType U6ObjectTypes[] = {
|
||||
// (object,frame,distance to trigger,event(s),function,properties)
|
||||
{ &U6UseCode::use_egg, OBJ_U6_EGG, 0, 0, USE_EVENT_USE/*|USE_EVENT_LOAD*/, OBJTYPE_CONTAINER },
|
||||
|
||||
{ &U6UseCode::use_door, OBJ_U6_OAKEN_DOOR, 255, 0, USE_EVENT_USE, OBJTYPE_NONE },
|
||||
{ &U6UseCode::use_door, OBJ_U6_WINDOWED_DOOR, 255, 0, USE_EVENT_USE, OBJTYPE_NONE },
|
||||
{ &U6UseCode::use_door, OBJ_U6_CEDAR_DOOR, 255, 0, USE_EVENT_USE, OBJTYPE_NONE },
|
||||
{ &U6UseCode::use_door, OBJ_U6_STEEL_DOOR, 255, 0, USE_EVENT_USE, OBJTYPE_NONE },
|
||||
{ &U6UseCode::use_key, OBJ_U6_KEY, 255, 0, USE_EVENT_USE, OBJTYPE_NONE },
|
||||
{ &U6UseCode::use_key, OBJ_U6_LOCK_PICK, 255, 0, USE_EVENT_USE | USE_EVENT_SEARCH | USE_EVENT_GET, OBJTYPE_NONE },
|
||||
|
||||
{ &U6UseCode::magic_ring, OBJ_U6_PROTECTION_RING, 0, 0, USE_EVENT_READY, OBJTYPE_NONE },
|
||||
{ &U6UseCode::magic_ring, OBJ_U6_REGENERATION_RING, 0, 0, USE_EVENT_READY, OBJTYPE_NONE },
|
||||
{ &U6UseCode::magic_ring, OBJ_U6_INVISIBILITY_RING, 0, 0, USE_EVENT_READY, OBJTYPE_NONE },
|
||||
|
||||
{ &U6UseCode::use_staff, OBJ_U6_STAFF, 255, 0, USE_EVENT_USE, OBJTYPE_NONE },
|
||||
|
||||
{ &U6UseCode::storm_cloak, OBJ_U6_STORM_CLOAK, 0, 0, USE_EVENT_READY, OBJTYPE_NONE },
|
||||
|
||||
{ &U6UseCode::look_sign, OBJ_U6_SIGN, 255, 0, USE_EVENT_LOOK, OBJTYPE_BOOK },
|
||||
{ &U6UseCode::look_sign, OBJ_U6_BOOK, 255, 0, USE_EVENT_LOOK, OBJTYPE_BOOK },
|
||||
{ &U6UseCode::look_sign, OBJ_U6_SCROLL, 255, 0, USE_EVENT_LOOK, OBJTYPE_BOOK },
|
||||
{ &U6UseCode::look_sign, OBJ_U6_PICTURE, 255, 0, USE_EVENT_LOOK, OBJTYPE_BOOK },
|
||||
{ &U6UseCode::look_sign, OBJ_U6_SIGN_ARROW, 255, 0, USE_EVENT_LOOK, OBJTYPE_BOOK },
|
||||
{ &U6UseCode::look_sign, OBJ_U6_TOMBSTONE, 255, 0, USE_EVENT_LOOK, OBJTYPE_BOOK },
|
||||
{ &U6UseCode::look_sign, OBJ_U6_CROSS, 255, 0, USE_EVENT_LOOK, OBJTYPE_BOOK },
|
||||
{ &U6UseCode::look_sign, OBJ_U6_CODEX, 0, 0, USE_EVENT_LOOK, OBJTYPE_BOOK },
|
||||
{ &U6UseCode::look_sign, OBJ_U6_BOOK_OF_CIRCLES, 255, 0, USE_EVENT_LOOK, OBJTYPE_BOOK },
|
||||
|
||||
{ &U6UseCode::use_container, OBJ_U6_CRATE, 0, 0, USE_EVENT_SEARCH, OBJTYPE_CONTAINER },
|
||||
{ &U6UseCode::use_container, OBJ_U6_CRATE, 255, 0, USE_EVENT_USE, OBJTYPE_CONTAINER },
|
||||
{ &U6UseCode::use_container, OBJ_U6_BARREL, 0, 0, USE_EVENT_SEARCH, OBJTYPE_CONTAINER },
|
||||
{ &U6UseCode::use_container, OBJ_U6_BARREL, 255, 0, USE_EVENT_USE, OBJTYPE_CONTAINER },
|
||||
{ &U6UseCode::use_container, OBJ_U6_CHEST, 0, 0, USE_EVENT_SEARCH | USE_EVENT_USE, OBJTYPE_CONTAINER },
|
||||
{ &U6UseCode::use_container, OBJ_U6_CHEST, 255, 0, USE_EVENT_USE | USE_EVENT_GET, OBJTYPE_CONTAINER },
|
||||
{ &U6UseCode::use_secret_door, OBJ_U6_SECRET_DOOR, 255, 0, USE_EVENT_USE | USE_EVENT_SEARCH, OBJTYPE_NONE },
|
||||
{ &U6UseCode::use_container, OBJ_U6_BAG, 255, 0, USE_EVENT_SEARCH | USE_EVENT_USE, OBJTYPE_CONTAINER },
|
||||
{ &U6UseCode::use_container, OBJ_U6_BACKPACK, 255, 0, USE_EVENT_SEARCH | USE_EVENT_USE, OBJTYPE_CONTAINER },
|
||||
{ &U6UseCode::use_container, OBJ_U6_BASKET, 255, 0, USE_EVENT_SEARCH | USE_EVENT_USE, OBJTYPE_CONTAINER },
|
||||
{ &U6UseCode::use_container, OBJ_U6_DRAWER, 255, 0, USE_EVENT_SEARCH | USE_EVENT_USE, OBJTYPE_CONTAINER },
|
||||
{ &U6UseCode::use_container, OBJ_U6_DESK, 255, 0, USE_EVENT_SEARCH | USE_EVENT_USE, OBJTYPE_CONTAINER },
|
||||
{ &U6UseCode::use_container, OBJ_U6_STONE_LION, 1, 0, USE_EVENT_SEARCH | USE_EVENT_USE, OBJTYPE_NONE },
|
||||
{ &U6UseCode::use_container, OBJ_U6_MOUSE, 255, 0, USE_EVENT_SEARCH | USE_EVENT_USE, OBJTYPE_CONTAINER },
|
||||
{ &U6UseCode::use_container, OBJ_U6_GRAVE, 0, 0, USE_EVENT_SEARCH | USE_EVENT_USE, OBJTYPE_NONE },
|
||||
{ &U6UseCode::use_container, OBJ_U6_DEAD_ANIMAL, 255, 0, USE_EVENT_SEARCH | USE_EVENT_USE, OBJTYPE_CONTAINER },
|
||||
{ &U6UseCode::use_container, OBJ_U6_DEAD_BODY, 255, 0, USE_EVENT_SEARCH | USE_EVENT_USE, OBJTYPE_CONTAINER },
|
||||
{ &U6UseCode::use_container, OBJ_U6_DRAKE, 255, 0, USE_EVENT_SEARCH | USE_EVENT_USE, OBJTYPE_CONTAINER },
|
||||
{ &U6UseCode::use_container, OBJ_U6_DEAD_CYCLOPS, 255, 0, USE_EVENT_SEARCH | USE_EVENT_USE, OBJTYPE_CONTAINER },
|
||||
{ &U6UseCode::use_container, OBJ_U6_DEAD_GARGOYLE, 255, 0, USE_EVENT_SEARCH | USE_EVENT_USE, OBJTYPE_CONTAINER },
|
||||
{ &U6UseCode::use_container, OBJ_U6_REAPER, 255, 0, USE_EVENT_SEARCH | USE_EVENT_USE, OBJTYPE_CONTAINER },
|
||||
{ &U6UseCode::use_container, OBJ_U6_REMAINS, 255, 0, USE_EVENT_SEARCH | USE_EVENT_USE, OBJTYPE_CONTAINER },
|
||||
{ &U6UseCode::use_container, OBJ_U6_DEER, 255, 0, USE_EVENT_SEARCH | USE_EVENT_USE, OBJTYPE_CONTAINER },
|
||||
{ &U6UseCode::use_container, OBJ_U6_MONGBAT, 255, 0, USE_EVENT_SEARCH | USE_EVENT_USE, OBJTYPE_CONTAINER },
|
||||
|
||||
{ &U6UseCode::use_passthrough, OBJ_U6_V_PASSTHROUGH, 255, 0, USE_EVENT_USE, OBJTYPE_NONE },
|
||||
{ &U6UseCode::use_passthrough, OBJ_U6_H_PASSTHROUGH, 255, 0, USE_EVENT_USE, OBJTYPE_NONE },
|
||||
|
||||
{ &U6UseCode::use_switch, OBJ_U6_LEVER, 255, 0, USE_EVENT_USE, OBJTYPE_NONE },
|
||||
{ &U6UseCode::use_switch, OBJ_U6_SWITCH, 255, 0, USE_EVENT_USE, OBJTYPE_NONE },
|
||||
|
||||
{ &U6UseCode::use_churn, OBJ_U6_CHURN, 255, 0, USE_EVENT_USE, OBJTYPE_NONE },
|
||||
|
||||
{ &U6UseCode::use_fishing_pole, OBJ_U6_FISHING_POLE, 255, 0, USE_EVENT_USE, OBJTYPE_NONE },
|
||||
|
||||
|
||||
{ &U6UseCode::use_crank, OBJ_U6_CRANK, 255, 0, USE_EVENT_USE, OBJTYPE_NONE },
|
||||
|
||||
{ &U6UseCode::use_container, OBJ_U6_BED, 255, 0, USE_EVENT_SEARCH, OBJTYPE_CONTAINER },
|
||||
|
||||
{ &U6UseCode::use_firedevice, OBJ_U6_FIREPLACE, 255, 0, USE_EVENT_USE, OBJTYPE_NONE },
|
||||
{ &U6UseCode::use_firedevice, OBJ_U6_CANDLE, 255, 0, USE_EVENT_USE, OBJTYPE_NONE },
|
||||
{ &U6UseCode::use_firedevice, OBJ_U6_CANDELABRA, 255, 0, USE_EVENT_USE, OBJTYPE_NONE },
|
||||
{ &U6UseCode::use_firedevice, OBJ_U6_BRAZIER, 0, 0, USE_EVENT_USE, OBJTYPE_NONE },
|
||||
{ &U6UseCode::use_firedevice, OBJ_U6_BRAZIER, 1, 0, USE_EVENT_USE, OBJTYPE_NONE },
|
||||
{ &U6UseCode::holy_flame, OBJ_U6_BRAZIER, 2, 0, USE_EVENT_LOOK, OBJTYPE_NONE },
|
||||
{ &U6UseCode::torch, OBJ_U6_TORCH, 255, 0, USE_EVENT_USE | USE_EVENT_READY | USE_EVENT_GET | USE_EVENT_DROP, OBJTYPE_NONE },
|
||||
{ &U6UseCode::use_spellbook, OBJ_U6_SPELLBOOK, 255, 0, USE_EVENT_USE | USE_EVENT_LOOK, OBJTYPE_NONE },
|
||||
|
||||
{ &U6UseCode::use_moonstone, OBJ_U6_MOONSTONE, 255, 0, USE_EVENT_USE | USE_EVENT_GET, OBJTYPE_NONE },
|
||||
{ &U6UseCode::use_orb, OBJ_U6_ORB_OF_THE_MOONS, 255, 0, USE_EVENT_USE, OBJTYPE_NONE },
|
||||
{ &U6UseCode::enter_moongate, OBJ_U6_MOONGATE, 1, 0, USE_EVENT_PASS, OBJTYPE_NONE },
|
||||
{ &U6UseCode::enter_moongate, OBJ_U6_RED_GATE, 1, 0, USE_EVENT_PASS, OBJTYPE_NONE },
|
||||
{ &U6UseCode::use_ladder, OBJ_U6_LADDER, 255, 0, USE_EVENT_USE, OBJTYPE_NONE },
|
||||
{ &U6UseCode::enter_dungeon, OBJ_U6_CAVE, 255, 0, USE_EVENT_PASS, OBJTYPE_NONE },
|
||||
{ &U6UseCode::enter_dungeon, OBJ_U6_HOLE, 255, 0, USE_EVENT_USE | USE_EVENT_PASS, OBJTYPE_NONE },
|
||||
|
||||
{ &U6UseCode::look_clock, OBJ_U6_CLOCK, 255, 0, USE_EVENT_LOOK, OBJTYPE_NONE },
|
||||
{ &U6UseCode::look_clock, OBJ_U6_SUNDIAL, 255, 0, USE_EVENT_LOOK, OBJTYPE_NONE },
|
||||
{ &U6UseCode::look_mirror, OBJ_U6_MIRROR, 255, 0, USE_EVENT_LOOK, OBJTYPE_NONE },
|
||||
{ &U6UseCode::use_well, OBJ_U6_WELL, 255, 0, USE_EVENT_USE, OBJTYPE_NONE },
|
||||
{ &U6UseCode::use_powder_keg, OBJ_U6_POWDER_KEG, 255, 0, USE_EVENT_USE | USE_EVENT_MESSAGE, OBJTYPE_NONE },
|
||||
{ &U6UseCode::use_peer_gem, OBJ_U6_GEM, 0, 0, USE_EVENT_USE | USE_EVENT_MESSAGE, OBJTYPE_NONE },
|
||||
|
||||
{ &U6UseCode::use_beehive, OBJ_U6_BEEHIVE, 255, 0, USE_EVENT_USE, OBJTYPE_NONE },
|
||||
|
||||
{ &U6UseCode::use_potion, OBJ_U6_POTION, 255, 0, USE_EVENT_USE | USE_EVENT_MESSAGE, OBJTYPE_NONE },
|
||||
{ &U6UseCode::use_food, OBJ_U6_BUTTER, 0, 0, USE_EVENT_USE, OBJTYPE_FOOD },
|
||||
{ &U6UseCode::use_food, OBJ_U6_WINE, 0, 0, USE_EVENT_USE, OBJTYPE_FOOD },
|
||||
{ &U6UseCode::use_food, OBJ_U6_MEAD, 0, 0, USE_EVENT_USE, OBJTYPE_FOOD },
|
||||
{ &U6UseCode::use_food, OBJ_U6_ALE, 0, 0, USE_EVENT_USE, OBJTYPE_FOOD },
|
||||
{ &U6UseCode::use_food, OBJ_U6_BREAD, 0, 0, USE_EVENT_USE, OBJTYPE_FOOD },
|
||||
{ &U6UseCode::use_food, OBJ_U6_MEAT_PORTION, 0, 0, USE_EVENT_USE, OBJTYPE_FOOD },
|
||||
{ &U6UseCode::use_food, OBJ_U6_ROLLS, 0, 0, USE_EVENT_USE, OBJTYPE_FOOD },
|
||||
{ &U6UseCode::use_food, OBJ_U6_CAKE, 0, 0, USE_EVENT_USE, OBJTYPE_FOOD },
|
||||
{ &U6UseCode::use_food, OBJ_U6_CHEESE, 0, 0, USE_EVENT_USE, OBJTYPE_FOOD },
|
||||
{ &U6UseCode::use_food, OBJ_U6_RIBS, 0, 0, USE_EVENT_USE, OBJTYPE_FOOD },
|
||||
{ &U6UseCode::use_food, OBJ_U6_MEAT, 0, 0, USE_EVENT_USE, OBJTYPE_FOOD },
|
||||
{ &U6UseCode::use_food, OBJ_U6_GRAPES, 0, 0, USE_EVENT_USE, OBJTYPE_FOOD },
|
||||
{ &U6UseCode::use_food, OBJ_U6_HAM, 0, 0, USE_EVENT_USE, OBJTYPE_FOOD },
|
||||
{ &U6UseCode::use_food, OBJ_U6_GARLIC, 0, 0, USE_EVENT_USE, OBJTYPE_FOOD },
|
||||
{ &U6UseCode::use_food, OBJ_U6_HORSE_CHOPS, 0, 0, USE_EVENT_USE, OBJTYPE_FOOD },
|
||||
{ &U6UseCode::use_food, OBJ_U6_JAR_OF_HONEY, 0, 0, USE_EVENT_USE, OBJTYPE_FOOD },
|
||||
{ &U6UseCode::use_food, OBJ_U6_DRAGON_EGG, 0, 0, USE_EVENT_USE, OBJTYPE_FOOD },
|
||||
{ &U6UseCode::use_food, OBJ_U6_FISH, 0, 0, USE_EVENT_USE, OBJTYPE_FOOD },
|
||||
|
||||
{ &U6UseCode::use_fan, OBJ_U6_FAN, 0, 0, USE_EVENT_USE, OBJTYPE_NONE },
|
||||
{ &U6UseCode::use_sextant, OBJ_U6_SEXTANT, 0, 0, USE_EVENT_USE, OBJTYPE_NONE },
|
||||
|
||||
{ &U6UseCode::use_cow, OBJ_U6_COW, 255, 0, USE_EVENT_USE, OBJTYPE_NONE },
|
||||
{ &U6UseCode::use_horse, OBJ_U6_HORSE, 255, 0, USE_EVENT_USE, OBJTYPE_NONE },
|
||||
{ &U6UseCode::use_horse, OBJ_U6_HORSE_WITH_RIDER, 255, 0, USE_EVENT_USE, OBJTYPE_NONE },
|
||||
|
||||
{ &U6UseCode::use_boat, OBJ_U6_SHIP, 255, 0, USE_EVENT_USE | USE_EVENT_SEARCH | USE_EVENT_LOOK, OBJTYPE_NONE },
|
||||
{ &U6UseCode::use_boat, OBJ_U6_SKIFF, 255, 0, USE_EVENT_USE | USE_EVENT_GET | USE_EVENT_LOOK, OBJTYPE_NONE },
|
||||
{ &U6UseCode::use_boat, OBJ_U6_RAFT, 0, 0, USE_EVENT_USE, OBJTYPE_NONE },
|
||||
// don't want OBJTYPE_BOOK so that we will always use the plans when double clicking
|
||||
{ &U6UseCode::use_balloon_plans, OBJ_U6_BALLOON_PLANS, 0, 0, USE_EVENT_USE | USE_EVENT_LOOK, OBJTYPE_NONE },
|
||||
{ &U6UseCode::use_balloon, OBJ_U6_BALLOON, 0, 0, USE_EVENT_USE, OBJTYPE_NONE },
|
||||
{ &U6UseCode::use_balloon, OBJ_U6_INFLATED_BALLOON, 255, 0, USE_EVENT_USE, OBJTYPE_NONE },
|
||||
|
||||
{ &U6UseCode::pass_quest_barrier, OBJ_U6_QUEST_GATE, 0, 0, USE_EVENT_PASS, OBJTYPE_NONE },
|
||||
|
||||
{ &U6UseCode::use_rune, OBJ_U6_RUNE_HONESTY, 0, 0, USE_EVENT_USE | USE_EVENT_MESSAGE, OBJTYPE_NONE },
|
||||
{ &U6UseCode::use_rune, OBJ_U6_RUNE_COMPASSION, 0, 0, USE_EVENT_USE | USE_EVENT_MESSAGE, OBJTYPE_NONE },
|
||||
{ &U6UseCode::use_rune, OBJ_U6_RUNE_VALOR, 0, 0, USE_EVENT_USE | USE_EVENT_MESSAGE, OBJTYPE_NONE },
|
||||
{ &U6UseCode::use_rune, OBJ_U6_RUNE_JUSTICE, 0, 0, USE_EVENT_USE | USE_EVENT_MESSAGE, OBJTYPE_NONE },
|
||||
{ &U6UseCode::use_rune, OBJ_U6_RUNE_SACRIFICE, 0, 0, USE_EVENT_USE | USE_EVENT_MESSAGE, OBJTYPE_NONE },
|
||||
{ &U6UseCode::use_rune, OBJ_U6_RUNE_HONOR, 0, 0, USE_EVENT_USE | USE_EVENT_MESSAGE, OBJTYPE_NONE },
|
||||
{ &U6UseCode::use_rune, OBJ_U6_RUNE_SPIRITUALITY, 0, 0, USE_EVENT_USE | USE_EVENT_MESSAGE, OBJTYPE_NONE },
|
||||
{ &U6UseCode::use_rune, OBJ_U6_RUNE_HUMILITY, 0, 0, USE_EVENT_USE | USE_EVENT_MESSAGE, OBJTYPE_NONE },
|
||||
|
||||
{ &U6UseCode::use_firedevice, OBJ_U6_CAMPFIRE, 255, 0, USE_EVENT_USE, OBJTYPE_NONE },
|
||||
|
||||
{ &U6UseCode::use_vortex_cube, OBJ_U6_VORTEX_CUBE, 0, 0, USE_EVENT_SEARCH | USE_EVENT_USE, OBJTYPE_CONTAINER },
|
||||
{ &U6UseCode::use_bell, OBJ_U6_PULL_CHAIN, 0, 0, USE_EVENT_USE, OBJTYPE_NONE },
|
||||
{ &U6UseCode::use_bell, OBJ_U6_BELL, 255, 0, USE_EVENT_USE, OBJTYPE_NONE },
|
||||
{ &U6UseCode::use_shovel, OBJ_U6_SHOVEL, 0, 0, USE_EVENT_USE, OBJTYPE_NONE },
|
||||
{ &U6UseCode::use_shovel, OBJ_U6_PICK, 0, 0, USE_EVENT_USE, OBJTYPE_NONE },
|
||||
{ &U6UseCode::use_fountain, OBJ_U6_FOUNTAIN, 0, 0, USE_EVENT_USE | USE_EVENT_MESSAGE, OBJTYPE_NONE },
|
||||
{ &U6UseCode::use_rubber_ducky, OBJ_U6_RUBBER_DUCKY, 0, 0, USE_EVENT_USE, OBJTYPE_NONE },
|
||||
{ &U6UseCode::use_cannon, OBJ_U6_CANNON, 255, 0, USE_EVENT_USE | USE_EVENT_MOVE | USE_EVENT_MESSAGE, OBJTYPE_NONE },
|
||||
{ &U6UseCode::amulet_of_submission, OBJ_U6_AMULET_OF_SUBMISSION, 0, 0, USE_EVENT_READY | USE_EVENT_DROP | USE_EVENT_MOVE, OBJTYPE_NONE },
|
||||
{ &U6UseCode::gargish_vocabulary, OBJ_U6_GARGISH_VOCABULARY, 0, 0, USE_EVENT_USE, OBJTYPE_NONE },
|
||||
|
||||
{ &U6UseCode::use_crystal_ball, OBJ_U6_CRYSTAL_BALL, 0, 0, USE_EVENT_USE | USE_EVENT_MESSAGE, OBJTYPE_NONE },
|
||||
|
||||
{ &U6UseCode::play_instrument, OBJ_U6_PANPIPES, 0, 0, USE_EVENT_USE, OBJTYPE_NONE },
|
||||
{ &U6UseCode::use_harpsichord, OBJ_U6_HARPSICHORD, 0, 0, USE_EVENT_SEARCH | USE_EVENT_USE, OBJTYPE_NONE },
|
||||
{ &U6UseCode::play_instrument, OBJ_U6_HARP, 0, 0, USE_EVENT_USE, OBJTYPE_NONE },
|
||||
{ &U6UseCode::play_instrument, OBJ_U6_LUTE, 0, 0, USE_EVENT_USE, OBJTYPE_NONE },
|
||||
{ &U6UseCode::play_instrument, OBJ_U6_XYLOPHONE, 0, 0, USE_EVENT_USE, OBJTYPE_NONE },
|
||||
|
||||
{ nullptr, OBJ_U6_NOTHING, 0, 0, 0, OBJTYPE_NONE } // end indicator
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
3005
engines/ultima/nuvie/usecode/u6_usecode.cpp
Normal file
3005
engines/ultima/nuvie/usecode/u6_usecode.cpp
Normal file
File diff suppressed because it is too large
Load Diff
228
engines/ultima/nuvie/usecode/u6_usecode.h
Normal file
228
engines/ultima/nuvie/usecode/u6_usecode.h
Normal file
@@ -0,0 +1,228 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NUVIE_USECODE_U6_USECODE_H
|
||||
#define NUVIE_USECODE_U6_USECODE_H
|
||||
|
||||
#include "ultima/nuvie/core/obj_manager.h"
|
||||
#include "ultima/nuvie/core/timed_event.h"
|
||||
#include "ultima/nuvie/usecode/usecode.h"
|
||||
//object numbers
|
||||
#include "ultima/nuvie/core/u6_objects.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
#define U6_LORD_BRITISH_ACTOR_NUM 5 /*change to U6_NPC_LORD_BRITISH?*/
|
||||
#define U6_SHERRY_ACTOR_NUM 9
|
||||
#define U6_BEHLEM_ACTOR_NUM 164
|
||||
|
||||
#define U6_LORD_BRITISH_ORB_CHECK_FLAG 0x20 // this is set if the player has asked LB about the orb of moons
|
||||
|
||||
class U6UseCode;
|
||||
class CallBack;
|
||||
class Configuration;
|
||||
class MsgScroll;
|
||||
|
||||
// U6ObjectType properties
|
||||
#define OBJTYPE_NONE 0x0000
|
||||
#define OBJTYPE_FOOD 0x0001 /* food or drink */
|
||||
#define OBJTYPE_CONTAINER 0x0002 /* must be set on empty bag,crate,backpack */
|
||||
#define OBJTYPE_BOOK 0x0004 /* has book data (signs, paintings, books) */
|
||||
|
||||
#define TORCH_LIGHT_LEVEL 3
|
||||
|
||||
struct U6ObjectType { // object properties & usecode
|
||||
bool (U6UseCode::*usefunc)(Obj *, UseCodeEvent); // usecode function
|
||||
uint16 obj_n; // type
|
||||
uint8 frame_n; // 0xFF matches any frame
|
||||
uint8 dist; // distance to trigger (depends on event, usually 0)
|
||||
UseCodeEvent trigger; // accepted event(s)
|
||||
uint16 flags; // properties (OBJTYPE)
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
LAT,
|
||||
LON
|
||||
} U6UseCodeLatLonEnum;
|
||||
|
||||
class U6UseCode: public UseCode, public CallBack {
|
||||
public:
|
||||
|
||||
U6UseCode(Game *g, const Configuration *cfg);
|
||||
~U6UseCode() override;
|
||||
|
||||
bool use_obj(Obj *obj, Actor *actor) override;
|
||||
bool look_obj(Obj *obj, Actor *actor) override;
|
||||
bool pass_obj(Obj *obj, Actor *actor, uint16 x, uint16 y) override;
|
||||
bool search_obj(Obj *obj, Actor *actor) override;
|
||||
bool move_obj(Obj *obj, sint16 rel_x, sint16 rel_y) override;
|
||||
bool load_obj(Obj *obj) override;
|
||||
bool message_obj(Obj *obj, CallbackMessage msg, void *msg_data) override;
|
||||
bool ready_obj(Obj *obj, Actor *actor) override;
|
||||
bool get_obj(Obj *obj, Actor *actor) override;
|
||||
bool drop_obj(Obj *obj, Actor *actor, uint16 x, uint16 y, uint16 qty = 0) override;
|
||||
|
||||
bool has_usecode(Obj *obj, UseCodeEvent ev = USE_EVENT_USE) override;
|
||||
bool has_usecode(Actor *actor, UseCodeEvent ev = USE_EVENT_USE) override;
|
||||
bool cannot_unready(const Obj *obj) const override;
|
||||
|
||||
bool is_door(const Obj *obj) const {
|
||||
return (obj->obj_n >= 297 && obj->obj_n <= 300);
|
||||
}
|
||||
bool is_unlocked_door(const Obj *obj) const override {
|
||||
return (is_door(obj) && obj->frame_n != 9 && obj->frame_n != 11);
|
||||
}
|
||||
bool is_locked_door(const Obj *obj) const override {
|
||||
return (is_door(obj) && (obj->frame_n == 9 || obj->frame_n == 11));
|
||||
}
|
||||
bool is_magically_locked_door(const Obj *obj) const {
|
||||
return (is_door(obj) && (obj->frame_n == 13 || obj->frame_n == 15));
|
||||
}
|
||||
bool is_closed_door(const Obj *obj) const override {
|
||||
return (is_door(obj) && obj->frame_n > 3);
|
||||
}
|
||||
|
||||
bool is_chest(const Obj *obj) const override {
|
||||
return (obj->obj_n == OBJ_U6_CHEST);
|
||||
}
|
||||
bool is_closed_chest(const Obj *obj) const {
|
||||
return (is_chest(obj) && obj->frame_n > 0);
|
||||
}
|
||||
bool is_locked_chest(const Obj *obj) const {
|
||||
return (is_chest(obj) && obj->frame_n == 2);
|
||||
}
|
||||
bool is_magically_locked_chest(const Obj *obj) const {
|
||||
return (is_chest(obj) && obj->frame_n == 3);
|
||||
}
|
||||
void unlock_chest(Obj *obj) {
|
||||
if (is_locked_chest(obj)) obj->frame_n = 1;
|
||||
return;
|
||||
}
|
||||
void lock_chest(Obj *obj) {
|
||||
if (is_chest(obj) && obj->frame_n == 1) obj->frame_n = 2;
|
||||
return;
|
||||
}
|
||||
|
||||
bool is_locked(const Obj *obj) const {
|
||||
return (is_locked_door(obj) || is_locked_chest(obj));
|
||||
}
|
||||
bool is_magically_locked(const Obj *obj) const {
|
||||
return (is_magically_locked_door(obj) || is_magically_locked_chest(obj));
|
||||
}
|
||||
void unlock(Obj *obj);
|
||||
void lock(Obj *obj);
|
||||
|
||||
bool is_food(const Obj *obj) const override;
|
||||
bool is_container(const Obj *obj) const override;
|
||||
bool is_container(uint16 obj_n, uint8 frame_n) const override;
|
||||
bool is_readable(const Obj *obj) const override;
|
||||
|
||||
uint16 callback(uint16 msg, CallBack *caller, void *data = nullptr) override;
|
||||
|
||||
protected:
|
||||
bool uc_event(const U6ObjectType *type, UseCodeEvent ev, Obj *obj);
|
||||
inline const U6ObjectType *get_object_type(uint16 n, uint8 f, UseCodeEvent ev = 0) const;
|
||||
|
||||
public:
|
||||
// usecode
|
||||
bool use_orb(Obj *obj, UseCodeEvent ev);
|
||||
bool use_moonstone(Obj *obj, UseCodeEvent ev);
|
||||
bool use_door(Obj *obj, UseCodeEvent ev);
|
||||
bool use_secret_door(Obj *obj, UseCodeEvent ev);
|
||||
bool use_ladder(Obj *obj, UseCodeEvent ev);
|
||||
bool use_passthrough(Obj *obj, UseCodeEvent ev);
|
||||
bool use_switch(Obj *obj, UseCodeEvent ev);
|
||||
bool use_crank(Obj *obj, UseCodeEvent ev);
|
||||
bool use_food(Obj *obj, UseCodeEvent ev);
|
||||
bool use_firedevice(Obj *obj, UseCodeEvent ev);
|
||||
bool use_fan(Obj *obj, UseCodeEvent ev);
|
||||
bool use_sextant(Obj *obj, UseCodeEvent ev);
|
||||
bool use_staff(Obj *obj, UseCodeEvent ev);
|
||||
bool use_container(Obj *obj, UseCodeEvent ev);
|
||||
bool use_rune(Obj *obj, UseCodeEvent ev);
|
||||
bool use_vortex_cube(Obj *obj, UseCodeEvent ev);
|
||||
bool use_key(Obj *obj, UseCodeEvent ev);
|
||||
bool use_boat(Obj *obj, UseCodeEvent ev);
|
||||
inline Obj *use_boat_find_center(Obj *obj);
|
||||
inline bool use_boat_find_land(uint16 *x, uint16 *y, uint8 *z);
|
||||
bool use_balloon_plans(Obj *obj, UseCodeEvent ev);
|
||||
bool use_balloon(Obj *obj, UseCodeEvent ev);
|
||||
bool use_cow(Obj *obj, UseCodeEvent ev);
|
||||
bool use_well(Obj *obj, UseCodeEvent ev);
|
||||
bool fill_bucket(uint16 filled_bucket_obj_n);
|
||||
bool use_churn(Obj *obj, UseCodeEvent ev);
|
||||
bool use_beehive(Obj *obj, UseCodeEvent ev);
|
||||
bool use_horse(Obj *obj, UseCodeEvent ev);
|
||||
bool use_potion(Obj *obj, UseCodeEvent ev);
|
||||
bool use_bell(Obj *obj, UseCodeEvent ev);
|
||||
bool use_fishing_pole(Obj *obj, UseCodeEvent ev);
|
||||
bool use_shovel(Obj *obj, UseCodeEvent ev);
|
||||
bool use_fountain(Obj *obj, UseCodeEvent ev);
|
||||
bool use_rubber_ducky(Obj *obj, UseCodeEvent ev);
|
||||
bool use_crystal_ball(Obj *obj, UseCodeEvent ev);
|
||||
bool use_harpsichord(Obj *obj, UseCodeEvent ev);
|
||||
bool play_instrument(Obj *obj, UseCodeEvent ev);
|
||||
bool look_mirror(Obj *obj, UseCodeEvent ev);
|
||||
bool look_sign(Obj *obj, UseCodeEvent ev);
|
||||
bool look_clock(Obj *obj, UseCodeEvent ev);
|
||||
bool pass_quest_barrier(Obj *obj, UseCodeEvent ev);
|
||||
bool enter_dungeon(Obj *obj, UseCodeEvent ev);
|
||||
bool enter_moongate(Obj *obj, UseCodeEvent ev);
|
||||
// bool search_container(Obj *obj, UseCodeEvent ev);
|
||||
bool use_powder_keg(Obj *obj, UseCodeEvent ev);
|
||||
bool use_cannon(Obj *obj, UseCodeEvent ev);
|
||||
bool use_egg(Obj *obj, UseCodeEvent ev);
|
||||
bool sundial(Obj *obj, UseCodeEvent ev);
|
||||
bool torch(Obj *obj, UseCodeEvent ev);
|
||||
bool use_spellbook(Obj *obj, UseCodeEvent ev);
|
||||
bool use_peer_gem(Obj *obj, UseCodeEvent ev);
|
||||
bool magic_ring(Obj *obj, UseCodeEvent ev);
|
||||
bool storm_cloak(Obj *obj, UseCodeEvent ev);
|
||||
bool amulet_of_submission(Obj *obj, UseCodeEvent ev);
|
||||
bool gargish_vocabulary(Obj *obj, UseCodeEvent ev);
|
||||
bool holy_flame(Obj *obj, UseCodeEvent ev);
|
||||
|
||||
protected:
|
||||
// supplementary
|
||||
void remove_gargoyle_egg(uint16 x, uint16 y, uint8 z);
|
||||
Obj *drawbridge_find(Obj *crank_obj);
|
||||
void drawbridge_open(uint16 x, uint16 y, uint8 level, uint16 b_width);
|
||||
void drawbridge_close(uint16 x, uint16 y, uint8 level, uint16 b_width);
|
||||
void drawbridge_remove(uint16 x, uint16 y, uint8 level, uint16 *bridge_width);
|
||||
bool use_firedevice_message(Obj *obj, bool lit);
|
||||
void lock_door(Obj *obj);
|
||||
void unlock_door(Obj *obj);
|
||||
Obj *bell_find(Obj *chain_obj);
|
||||
void sundial_set_shadow(Obj *sundial, uint8 hour);
|
||||
void extinguish_torch(Obj *obj);
|
||||
void light_torch(Obj *obj);
|
||||
bool process_effects(Obj *container_obj, Actor *actor) override;
|
||||
sint16 parseLatLongString(U6UseCodeLatLonEnum mode, Std::string *input);
|
||||
|
||||
inline bool use_find_water(uint16 *x, uint16 *y, uint8 *z);
|
||||
inline bool lock_pick_dex_check();
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
314
engines/ultima/nuvie/usecode/usecode.cpp
Normal file
314
engines/ultima/nuvie/usecode/usecode.cpp
Normal file
@@ -0,0 +1,314 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ultima/nuvie/core/nuvie_defs.h"
|
||||
#include "ultima/nuvie/misc/u6_llist.h"
|
||||
#include "ultima/nuvie/gui/widgets/msg_scroll.h"
|
||||
#include "ultima/nuvie/actors/actor_manager.h"
|
||||
#include "ultima/nuvie/actors/actor.h"
|
||||
#include "ultima/nuvie/usecode/usecode.h"
|
||||
#include "ultima/nuvie/gui/widgets/map_window.h"
|
||||
#include "ultima/nuvie/script/script.h"
|
||||
#include "ultima/nuvie/core/events.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
UseCode::UseCode(Game *g, const Configuration *cfg) : game(g), config(cfg),
|
||||
obj_manager(nullptr), map(nullptr), player(nullptr), scroll(nullptr),
|
||||
actor_manager(nullptr), party(nullptr), script(nullptr), script_thread(nullptr) {
|
||||
clear_items();
|
||||
}
|
||||
|
||||
UseCode::~UseCode() {
|
||||
if (script_thread) {
|
||||
delete script_thread;
|
||||
}
|
||||
}
|
||||
|
||||
bool UseCode::init(ObjManager *om, Map *m, Player *p, MsgScroll *ms) {
|
||||
obj_manager = om;
|
||||
map = m;
|
||||
player = p;
|
||||
scroll = ms;
|
||||
|
||||
actor_manager = game->get_actor_manager();
|
||||
party = player->get_party();
|
||||
script = game->get_script();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Clear items.
|
||||
*/
|
||||
void UseCode::clear_items() {
|
||||
memset(&items, 0, sizeof(items));
|
||||
/* items.uint_ref = nullptr;
|
||||
items.sint_ref = nullptr;
|
||||
items.obj_ref = nullptr;
|
||||
items.actor_ref = items.actor2_ref = nullptr;
|
||||
items.mapcoord_ref = nullptr;
|
||||
items.msg_ref = nullptr;
|
||||
items.string_ref = nullptr;
|
||||
items.ent_ref = nullptr;
|
||||
items.data_ref = nullptr; */
|
||||
}
|
||||
|
||||
ScriptThread *UseCode::get_running_script() {
|
||||
if (script_thread && script_thread->is_running())
|
||||
return script_thread;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool UseCode::is_script_running() {
|
||||
if (script_thread && script_thread->is_running())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool UseCode::is_container(const Obj *obj) const {
|
||||
return script->call_is_container_obj(obj->obj_n);
|
||||
}
|
||||
|
||||
bool UseCode::has_usecode(Obj *obj, UseCodeEvent ev) {
|
||||
return script->call_has_usecode(obj, ev);
|
||||
}
|
||||
|
||||
bool UseCode::use_obj(Obj *obj, Actor *actor) {
|
||||
if (script_thread) {
|
||||
delete script_thread;
|
||||
script_thread = nullptr;
|
||||
}
|
||||
|
||||
script_thread = script->call_use_obj(obj, actor);
|
||||
|
||||
if (script_thread) {
|
||||
script_thread->start();
|
||||
if (script_thread->finished()) {
|
||||
delete script_thread;
|
||||
script_thread = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return true;//script->call_use_obj(obj, actor);
|
||||
}
|
||||
|
||||
// use obj at location with src_obj as object_ref
|
||||
bool UseCode::use_obj(uint16 x, uint16 y, uint8 z, Obj *src_obj) {
|
||||
Obj *obj;
|
||||
|
||||
obj = obj_manager->get_obj(x, y, z, true);
|
||||
|
||||
if (obj == nullptr)
|
||||
return false;
|
||||
|
||||
return use_obj(obj, src_obj);
|
||||
}
|
||||
|
||||
bool UseCode::ready_obj(Obj *obj, Actor *actor) {
|
||||
return script->call_ready_obj(obj, actor);
|
||||
}
|
||||
|
||||
bool UseCode::move_obj(Obj *obj, sint16 rel_x, sint16 rel_y) {
|
||||
return script->call_move_obj(obj, rel_x, rel_y);
|
||||
}
|
||||
|
||||
void UseCode::toggle_frame(Obj *obj) {
|
||||
if (obj->frame_n > 0)
|
||||
obj->frame_n--;
|
||||
else
|
||||
obj->frame_n = 1;
|
||||
}
|
||||
|
||||
|
||||
/* Print container contents and dump them on top of the container.
|
||||
*/
|
||||
//FIXME! some of this logic should go elsewhere.
|
||||
bool UseCode::search_container(Obj *obj, bool show_string) {
|
||||
Obj *temp_obj;
|
||||
U6Link *obj_link;
|
||||
|
||||
/* Test whether this object has items inside it. */
|
||||
if ((obj->container != nullptr) &&
|
||||
((obj_link = obj->container->start()) != nullptr)) {
|
||||
/* Add objects to obj_list. */
|
||||
for (; obj_link != nullptr;) {
|
||||
temp_obj = (Obj *)obj_link->data;
|
||||
obj_link = obj_link->next;
|
||||
/*
|
||||
obj_list->add(temp_obj);
|
||||
temp_obj->status |= OBJ_STATUS_OK_TO_TAKE;
|
||||
temp_obj->set_on_map(obj_list); //ERIC temp_obj->status &= ~OBJ_STATUS_IN_CONTAINER;
|
||||
temp_obj->x = obj->x;
|
||||
temp_obj->y = obj->y;
|
||||
temp_obj->z = obj->z;
|
||||
*/
|
||||
obj_manager->moveto_map(temp_obj, obj->is_in_container() ? MapCoord(obj->get_container_obj(true)) : MapCoord(obj));
|
||||
if (show_string) {
|
||||
scroll->display_string(obj_manager->look_obj(temp_obj, true));
|
||||
if (obj_link) // more objects left
|
||||
scroll->display_string(obj_link->next ? ", " : ", and ");
|
||||
}
|
||||
}
|
||||
/* Remove objects from the container. */
|
||||
//obj->container->removeAll();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/* Remove last object in container and return a pointer to it.
|
||||
*/
|
||||
Obj *UseCode::get_obj_from_container(Obj *obj) {
|
||||
Obj *temp_obj;
|
||||
if (obj->container && obj->container->end()) {
|
||||
temp_obj = (Obj *)obj->container->end()->data;
|
||||
obj->container->remove(temp_obj); // a pop_back() may be more efficient
|
||||
return temp_obj;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
/* Print name of event being sent and the object receiving it.
|
||||
*/
|
||||
void UseCode::dbg_print_event(UseCodeEvent event, Obj *obj) {
|
||||
string do_string = "";
|
||||
switch (event) {
|
||||
case USE_EVENT_USE:
|
||||
do_string = "Use";
|
||||
break;
|
||||
case USE_EVENT_LOOK:
|
||||
do_string = "Look at";
|
||||
break;
|
||||
case USE_EVENT_PASS:
|
||||
do_string = "Pass";
|
||||
break;
|
||||
case USE_EVENT_SEARCH:
|
||||
do_string = "Search";
|
||||
break;
|
||||
case USE_EVENT_MOVE:
|
||||
do_string = "Move";
|
||||
break;
|
||||
case USE_EVENT_LOAD:
|
||||
do_string = "Load";
|
||||
break;
|
||||
case USE_EVENT_MESSAGE:
|
||||
do_string = "Message";
|
||||
break;
|
||||
case USE_EVENT_READY:
|
||||
do_string = "(Un)Equip";
|
||||
break;
|
||||
case USE_EVENT_GET:
|
||||
do_string = "Get";
|
||||
break;
|
||||
case USE_EVENT_DROP:
|
||||
do_string = "Drop";
|
||||
break;
|
||||
}
|
||||
if (do_string != "")
|
||||
DEBUG(0, LEVEL_DEBUGGING, "UseCode: %s object %d:%d (%03x,%03x,%x)\n", do_string.c_str(),
|
||||
obj->obj_n, obj->frame_n, obj->x, obj->y, obj->z);
|
||||
else
|
||||
DEBUG(0, LEVEL_DEBUGGING, "UseCode: Events 0x%04x sent to object %d:%d (%03x,%03x,%x)\n",
|
||||
event, obj->obj_n, obj->frame_n, obj->x, obj->y, obj->z);
|
||||
}
|
||||
|
||||
|
||||
/* Subtract `count' from object quantity. Destroy the object completely if all
|
||||
* stacked objects were removed, or the object is not stackable, or `count' is
|
||||
* 0. This means it will be removed from the world or an actor's inventory, and
|
||||
* deleted.
|
||||
* Returns the original object if it still exists, because the count was smaller
|
||||
* than the object stack, or it could not be completely destroyed for whatever
|
||||
* reason. Returns nullptr if the object was destroyed.
|
||||
*/
|
||||
Obj *UseCode::destroy_obj(Obj *obj, uint32 count, bool run_usecode) {
|
||||
//ActorManager *actor_manager = Game::get_game()->get_actor_manager();
|
||||
//bool removed = false;
|
||||
|
||||
// subtract
|
||||
if (count > 0 && obj_manager->is_stackable(obj) && obj->qty > count)
|
||||
obj->qty -= count;
|
||||
else { // destroy
|
||||
obj_manager->unlink_from_engine(obj, run_usecode);
|
||||
delete_obj(obj);
|
||||
obj = nullptr;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/*
|
||||
* don't autowalk long distances to objects when foes are nearby or select obj outside of range
|
||||
*/
|
||||
bool UseCode::out_of_use_range(Obj *obj, bool check_enemies) {
|
||||
if (!obj) // this should be checked before you get here
|
||||
return true;
|
||||
if (obj->is_in_inventory())
|
||||
return false;
|
||||
|
||||
MapCoord player_loc = player->get_actor()->get_location();
|
||||
MapCoord obj_loc = MapCoord(obj->x, obj->y, obj->z);
|
||||
|
||||
if (!check_enemies) {
|
||||
if (player_loc.distance(obj_loc) > 1
|
||||
&& game->get_map_window()->get_interface() == INTERFACE_NORMAL) {
|
||||
scroll->display_string("\nOut of range.\n");
|
||||
return true;
|
||||
} else if (!game->get_map_window()->can_get_obj(player->get_actor(), obj)) {
|
||||
scroll->display_string("\nBlocked.\n");
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
} else if (player_loc.distance(obj_loc) > 1) { // only setup for objects that already checked range and blocking limit
|
||||
ActorList *enemies = nullptr;
|
||||
|
||||
if ((enemies = player->get_actor()->find_enemies())) {
|
||||
scroll->display_string("\nOut of range.\n");
|
||||
delete enemies;
|
||||
return true;
|
||||
}
|
||||
delete enemies;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *useCodeTypeToString(UseCodeType type) {
|
||||
switch (type) {
|
||||
case USE :
|
||||
return "use";
|
||||
case MOVE :
|
||||
return "move";
|
||||
case GET :
|
||||
return "get";
|
||||
default :
|
||||
return "other";
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
307
engines/ultima/nuvie/usecode/usecode.h
Normal file
307
engines/ultima/nuvie/usecode/usecode.h
Normal file
@@ -0,0 +1,307 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NUVIE_USECODE_USECODE_H
|
||||
#define NUVIE_USECODE_USECODE_H
|
||||
|
||||
#include "ultima/shared/std/string.h"
|
||||
#include "ultima/nuvie/misc/call_back.h"
|
||||
#include "ultima/nuvie/misc/map_entity.h"
|
||||
#include "ultima/nuvie/core/obj_manager.h"
|
||||
#include "ultima/nuvie/core/player.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
// The game triggers one of these events on an object to activate its UseCode
|
||||
// function(s). The return value meaning is different for each event.
|
||||
#define USE_EVENT_USE 0x01 /* return value undefined */
|
||||
#define USE_EVENT_LOOK 0x02 /* true: allow search, false: disallow search */
|
||||
#define USE_EVENT_PASS 0x04 /* true: do normal move, false: object blocks */
|
||||
#define USE_EVENT_MESSAGE 0x08 /* internal message or data return */
|
||||
#define USE_EVENT_SEARCH 0x10 /*undefined (true = had objects?); might remove*/
|
||||
//#define USE_EVENT_ON 0x20 /* post-move/idle */
|
||||
#define USE_EVENT_MOVE 0x40 /* true: move object, false: don't move object */
|
||||
#define USE_EVENT_LOAD 0x80 /* return value undefined */
|
||||
#define USE_EVENT_READY 0x0100 /* true: object may be equipped */
|
||||
#define USE_EVENT_GET 0x0200 /* true: do normal get */
|
||||
#define USE_EVENT_DROP 0x0400 /* true: do normal drop */
|
||||
#define USE_EVENT_INPUT_CANCEL 0x501 /* note this shares a bit with USE_EVENT_USE so it can pass through uc_event(). return undefined */
|
||||
//#define USE_EVENT_NEAR 0x00 /* mirrors; might use ON with distance val */
|
||||
//#define USE_EVENT_ATTACK 0x00 /* doors, chests, mirrors */
|
||||
//#define USE_EVENT_ENTER 0x00 /* object enters view (clocks) */
|
||||
//#define USE_EVENT_LEAVE 0x00 /* object leaves view */
|
||||
|
||||
typedef uint16 UseCodeEvent;
|
||||
|
||||
/* Events:
|
||||
* USE
|
||||
* Returns: undefined
|
||||
* Use the object.
|
||||
* actor_ref - the actor using it (the player actor typically)
|
||||
*
|
||||
* PASS (Quest Barrier)
|
||||
* Returns: True if actor may move, False if object blocks
|
||||
* Called when an actor attempts to step onto an object.
|
||||
* actor_ref - actor trying to pass
|
||||
* mapcoord_ref - location the actor is trying to pass (for multi-tile objects)
|
||||
*
|
||||
* LOOK (signs)
|
||||
* Returns: True if an object can be searched
|
||||
* Called when someone looks at the object. Some objects aren't searched (books
|
||||
* for example) and should return false.
|
||||
*
|
||||
* MESSAGE (fumaroles, earthquakes?, powder kegs, clocks)
|
||||
* An internal event from the engine. It must have been previously requested.
|
||||
* Includes TIMED events, and DATA returns. Be careful that the object still
|
||||
* exists.
|
||||
*
|
||||
* MOVE (cannons)
|
||||
* Returns: True to push object to the new position
|
||||
* Use this to perform special move functions for some objects. A cannon can be
|
||||
* aimed with MOVE.
|
||||
* mapcoord_ref - target location
|
||||
*
|
||||
* (UN)LOAD unimplemented (fumaroles)
|
||||
* Returns: undefined
|
||||
* Called when the object is cached in or out (or when it would have been in the
|
||||
* original game... about 16 to 32 spaces away), and when new objects are created.
|
||||
* It can be used to start timers, or to hatch eggs.
|
||||
*
|
||||
* Actor NEAR unimplemented (mirrors)
|
||||
* Set something to happen when an actor moves close to or away from object.
|
||||
* Distance will be used.
|
||||
*
|
||||
* Actor ON (chairs, traps) unimplemented
|
||||
* Returns: undefined
|
||||
* Called each turn for any objects in the view-area with actors standing on
|
||||
* them.
|
||||
*
|
||||
* ENTER view-area unimplemented
|
||||
*
|
||||
* LEAVE view-area unimplemented
|
||||
* Enter and leave will be used to start and stop sound effects. Distance will
|
||||
* be used.
|
||||
*
|
||||
* (UN)READY (Amulet of Submission)
|
||||
* Returns: True if the object may be worn, or removed
|
||||
* This is called before the object is is equipped or removed. Check the
|
||||
* object's flags to determine if it is being equipped or not. (if its readied
|
||||
* flag is set it is being removed). Special un/ready functions can be created
|
||||
* with this.
|
||||
* actor_ref - the actor un/readying it
|
||||
*
|
||||
* ATTACK (doors, chests)
|
||||
*
|
||||
* DROP (breakables, torches)
|
||||
* Returns: True to allow normal drop at the target.
|
||||
* Special drop functions can be created with this.
|
||||
* actor_ref - the actor dropping it
|
||||
* mapcoord_ref - the desired drop target
|
||||
*
|
||||
* GET (torches, runes?)
|
||||
* Returns: True if the actor can get the object.
|
||||
* Special get functions can be created with this.
|
||||
* actor_ref - the actor getting it
|
||||
*
|
||||
* SEARCH (graves, secret doors)
|
||||
* Returns: True if the object contained other objects.
|
||||
* FIXME: might remove this and add as a player action
|
||||
*
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
USE,
|
||||
GET,
|
||||
MOVE
|
||||
} UseCodeType;
|
||||
|
||||
const char *useCodeTypeToString(UseCodeType type);
|
||||
|
||||
class ActorManager;
|
||||
class Configuration;
|
||||
class Events;
|
||||
class Game;
|
||||
class Map;
|
||||
class MsgScroll;
|
||||
class MapCoord;
|
||||
class Party;
|
||||
class Player;
|
||||
class Script;
|
||||
class ScriptThread;
|
||||
|
||||
class UseCode {
|
||||
private:
|
||||
ScriptThread *script_thread;
|
||||
|
||||
protected:
|
||||
Game *game;
|
||||
const Configuration *config;
|
||||
ObjManager *obj_manager;
|
||||
Map *map;
|
||||
Player *player;
|
||||
MsgScroll *scroll;
|
||||
ActorManager *actor_manager;
|
||||
Party *party;
|
||||
Script *script;
|
||||
|
||||
// pass parameters to usecode functions via items (nullptr itemref is unset)
|
||||
struct {
|
||||
uint32 *uint_ref;
|
||||
sint32 *sint_ref;
|
||||
Obj *obj_ref;
|
||||
Actor *actor_ref, *actor2_ref;
|
||||
MapCoord *mapcoord_ref;
|
||||
CallbackMessage *msg_ref;
|
||||
Std::string *string_ref;
|
||||
MapEntity *ent_ref;
|
||||
char *data_ref;
|
||||
} items;
|
||||
void clear_items();
|
||||
|
||||
public:
|
||||
|
||||
UseCode(Game *g, const Configuration *cfg);
|
||||
virtual ~UseCode();
|
||||
|
||||
virtual bool init(ObjManager *om, Map *m, Player *p, MsgScroll *ms);
|
||||
|
||||
bool use_obj(uint16 x, uint16 y, uint8 z, Obj *src_obj = nullptr);
|
||||
bool use_obj(Obj *obj, Obj *src_obj = nullptr) {
|
||||
return (use_obj(obj, player->get_actor())); // ??
|
||||
}
|
||||
|
||||
virtual bool use_obj(Obj *obj, Actor *actor);
|
||||
virtual bool look_obj(Obj *obj, Actor *actor) {
|
||||
return false;
|
||||
}
|
||||
virtual bool pass_obj(Obj *obj, Actor *actor, uint16 x, uint16 y) {
|
||||
return false;
|
||||
}
|
||||
virtual bool search_obj(Obj *obj, Actor *actor) {
|
||||
return false;
|
||||
}
|
||||
virtual bool move_obj(Obj *obj, sint16 rel_x, sint16 rel_y);
|
||||
virtual bool load_obj(Obj *obj) {
|
||||
return false;
|
||||
}
|
||||
virtual bool message_obj(Obj *obj, CallbackMessage msg, void *msg_data) {
|
||||
return false;
|
||||
}
|
||||
virtual bool ready_obj(Obj *obj, Actor *actor);
|
||||
virtual bool get_obj(Obj *obj, Actor *actor) {
|
||||
return false;
|
||||
}
|
||||
virtual bool drop_obj(Obj *obj, Actor *actor, uint16 x, uint16 y, uint16 qty = 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool has_usecode(Obj *obj, UseCodeEvent ev = USE_EVENT_USE);
|
||||
virtual bool has_usecode(Actor *actor, UseCodeEvent ev = USE_EVENT_USE) {
|
||||
return false;
|
||||
}
|
||||
virtual bool has_lookcode(Obj *obj) {
|
||||
return has_usecode(obj, USE_EVENT_LOOK);
|
||||
}
|
||||
virtual bool has_passcode(Obj *obj) {
|
||||
return has_usecode(obj, USE_EVENT_PASS);
|
||||
}
|
||||
virtual bool has_movecode(Obj *obj) {
|
||||
return has_usecode(obj, USE_EVENT_MOVE);
|
||||
}
|
||||
virtual bool has_loadcode(Obj *obj) {
|
||||
return has_usecode(obj, USE_EVENT_LOAD);
|
||||
}
|
||||
virtual bool has_readycode(Obj *obj) {
|
||||
return has_usecode(obj, USE_EVENT_READY);
|
||||
}
|
||||
virtual bool cannot_unready(const Obj *obj) const {
|
||||
return false;
|
||||
}
|
||||
virtual bool has_getcode(Obj *obj) {
|
||||
return has_usecode(obj, USE_EVENT_GET);
|
||||
}
|
||||
virtual bool has_dropcode(Obj *obj) {
|
||||
return has_usecode(obj, USE_EVENT_DROP);
|
||||
}
|
||||
|
||||
bool is_door(const Obj *obj) const {
|
||||
return (is_locked_door(obj) || is_unlocked_door(obj));
|
||||
}
|
||||
virtual bool is_locked_door(const Obj *obj) const {
|
||||
return false;
|
||||
}
|
||||
virtual bool is_unlocked_door(const Obj *obj) const {
|
||||
return false;
|
||||
}
|
||||
virtual bool is_closed_door(const Obj *obj) const {
|
||||
return false;
|
||||
}
|
||||
virtual bool process_effects(Obj *container_obj, Actor *actor) {
|
||||
return false;
|
||||
}
|
||||
virtual bool is_food(const Obj *obj) const {
|
||||
return false;
|
||||
}
|
||||
virtual bool is_container(const Obj *obj) const;
|
||||
virtual bool is_container(uint16 obj_n, uint8 frame_n) const {
|
||||
return false;
|
||||
}
|
||||
virtual bool is_readable(const Obj *obj) const {
|
||||
return false;
|
||||
}
|
||||
virtual bool is_chest(const Obj *obj) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
void set_itemref(sint32 *val) {
|
||||
items.sint_ref = val;
|
||||
}
|
||||
void set_itemref(Obj *val) {
|
||||
items.obj_ref = val;
|
||||
}
|
||||
void set_itemref(Actor *val, Actor *val2 = nullptr) {
|
||||
items.actor_ref = val;
|
||||
items.actor2_ref = val2;
|
||||
}
|
||||
void set_itemref(MapCoord *val) {
|
||||
items.mapcoord_ref = val;
|
||||
}
|
||||
|
||||
Obj *get_obj_from_container(Obj *obj);
|
||||
bool search_container(Obj *obj, bool show_string = true);
|
||||
Obj *destroy_obj(Obj *obj, uint32 count = 0, bool run_usecode = true);
|
||||
bool out_of_use_range(Obj *obj, bool check_enemies);
|
||||
|
||||
ScriptThread *get_running_script();
|
||||
bool is_script_running();
|
||||
|
||||
protected:
|
||||
|
||||
void toggle_frame(Obj *obj);
|
||||
void dbg_print_event(UseCodeEvent event, Obj *obj);
|
||||
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user