2 // nazghul - an old-school RPG engine
3 // Copyright (C) 2002, 2003 Gordon McNutt
5 // This program is free software; you can redistribute it and/or modify it
6 // under the terms of the GNU General Public License as published by the Free
7 // Software Foundation; either version 2 of the License, or (at your option)
10 // This program is distributed in the hope that it will be useful, but WITHOUT
11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 // You should have received a copy of the GNU General Public License along with
16 // this program; if not, write to the Free Foundation, Inc., 59 Temple Place,
17 // Suite 330, Boston, MA 02111-1307 USA
20 // gmcnutt@users.sourceforge.net
29 #include "console.h" // SAM: for DEBUG purposes...
35 // Wrappers for session_add() and session_rm() that do the ref-counting.
36 #define session_add_obj(session, obj, dtor, save, start) \
39 (obj)->handle = session_add((session), (obj), (dtor), (save), \
43 #define session_rm_obj(session, obj) \
45 session_rm((session), (obj)->handle); \
49 /* Hack: until movement modes implemented in objects */
50 #define obj_mmode(obj) ((obj)->getMovementMode())
53 #define OBJ_HOOK_START_OF_TURN 0 /* after ap assigned at start of turn */
54 #define OBJ_HOOK_ADD_HOOK 1 /* whan a new effects is added */
55 #define OBJ_HOOK_DAMAGE 2 /* when the object takes damage */
56 #define OBJ_HOOK_KEYSTROKE 3 /* when PC is given a command */
57 #define OBJ_HOOK_NIL 4 /* never (effect just exists) */
58 #define OBJ_HOOK_ON_DEATH 5 /* character just died */
59 #define OBJ_HOOK_READY_EQUIP 6 /* PC readies */
60 #define OBJ_HOOK_UNREADY_EQUIP 7 /* PC unreadies */
61 #define OBJ_HOOK_MOVE_DONE 8 /* character just moved */
62 #define OBJ_HOOK_ATTACK_DONE 9 /* character just attacked */
63 #define OBJ_HOOK_CAST_DONE 10 /* character just cast a spell */
64 #define OBJ_HOOK_DROP_DONE 11 /* character just dropped something */
65 #define OBJ_HOOK_YUSE_DONE 12 /* character just yused a skill */
66 #define OBJ_HOOK_GET_DONE 13 /* character just got something */
67 #define OBJ_HOOK_HANDLE_DONE 14 /* character just handled something */
68 #define OBJ_HOOK_OPEN_DONE 15 /* character just opened something */
69 #define OBJ_HOOK_READY_DONE 16 /* character finished equipping */
70 #define OBJ_HOOK_TALK_DONE 17 /* character finished talking */
71 #define OBJ_HOOK_USE_DONE 18 /* character finished using something */
72 #define OBJ_HOOK_MIX_DONE 19 /* character finished using something */
73 #define OBJ_HOOK_KAMP_START 20 /* character about to start camping */
74 #define OBJ_NUM_HOOKS 21 /* total number of object hooks */
76 /* Relocation flags. Used to avoid triggers in special cases. */
77 #define REL_NOSTEP (1<<0) /* don't trigger "step" */
78 #define REL_NOSENSE (1<<1) /* don't trigger "sense" */
79 #define REL_NOTRIG (REL_NOSTEP|REL_NOSENSE) /* don't trigger anything */
81 // Note: if you change the layers you'll probably need to change the save
83 // Proper rendering depends on keeping these in order!
95 projectile_layer = 10,
100 CONTROL_MODE_AUTO = 0,
115 CouldNotSwitchOccupants,
116 OffMap, // and no parent
134 class ObjectType *type;
138 bool (*fx)(struct inv_entry *ie, void *fdata);
142 typedef struct hook_entry {
144 struct effect *effect;
146 clock_alarm_t expiration;
148 char started : 1; /* unsaved flag */
154 virtual bool isType(int classID);
155 virtual int getType();
157 ObjectType(const char *tag, const char *name, struct sprite *sprite,
159 virtual ~ObjectType();
160 virtual bool init(char *tag, char *name, enum layer layer,
161 struct sprite * sprite);
162 virtual void setSprite(struct sprite *sprite);
163 virtual const char *getTag();
164 virtual const char *getName();
165 virtual struct sprite *getSprite();
166 virtual enum layer getLayer();
167 virtual class Object *createInstance();
168 virtual bool isVisible();
169 virtual void describe(Object *obj);
170 virtual int getSpeed();
171 virtual int getMaxHp();
172 virtual void setMovementMode(struct mmode *mmode);
173 virtual struct mmode *getMovementMode();
175 // This might turn out to be too vague. We'll see.
176 virtual int getRequiredActionPoints();
178 // This version of describe() can't run any hooks; it's used for
179 // inventory descriptions, where there are no object instances.
180 void describeType(int count);
182 bool isUsable(); // items, etc
183 bool isReadyable(); // arms
184 bool isMixable(); // reagents
185 bool isCastable(); // spells
186 bool canExec(); // mechs, etc
196 bool canBump(); // attempted entry onto same tile
197 bool canHitLocation(); // weapon hitting a target location
198 bool canBuy(); // has a hook for 'buy'
199 bool canSearch(); // has a hook for 'search'
202 // These return the result of closure_exec:
203 int use(Object *user);
204 int exec(Object *obj);
205 int get(Object *obj, Object *getter);
206 int open(Object *obj, Object *opener);
207 int step(Object *obj, Object *stepper);
208 int sense(Object *obj, Object *stepper);
209 int xamine(Object *obj, Object *xaminer);
210 int handle(Object *obj, Object *handler);
211 int attack(Object *obj, Object *attacker);
212 int onAttack(Object *obj, Object *attacker);
213 int enter(Object *obj, Object *enterer);
214 int cast(Object *caster);
215 int bump(Object *obj, Object *bumper);
216 int hitLocation(Object *obj, Object *attacker, Object *target, struct place *place, int x, int y, int dam);
217 int buy(Object *buyer, int q);
218 int search(Object *obj, Object *searcher);
220 closure_t *getGifc();
221 void setGifc(closure_t *gifc, int cap);
223 void setPluralName(char *val);
224 void setGob(struct gob *gob);
225 struct gob * getGob();
226 void setQuestItemFlag(bool val);
232 struct sprite *sprite;
235 int required_action_points;
238 /* ghulscript-interface (gifc) */
242 struct mmode *movementMode;
245 bool hasDescribeHook();
246 void runDescribeHook(Object *obj);
249 char *getPluralName();
256 virtual bool isType(int classID);
257 virtual int getType();
259 Object(class ObjectType * type); // preferred constructor
263 virtual void init(int x, int y, struct place *place,
264 class ObjectType * type);
265 virtual void init(class ObjectType * type);
267 virtual sound_t *getDamageSound();
268 virtual sound_t *get_movement_sound();
269 virtual int getActivity();
270 virtual enum control_mode getControlMode();
271 virtual int getCount();
273 virtual enum layer getLayer(void);
274 virtual int getLight();
275 virtual int getMaxHp();
276 virtual const char *getName(void);
277 virtual class ObjectType *getObjectType();
278 virtual struct place *getPlace();
279 virtual int getRequiredActionPoints();
280 virtual int getSpeed();
281 virtual struct mview *getView();
282 virtual int getVisionRadius();
288 virtual bool isCompanionOf(class Object *other);
289 virtual bool isDestroyed();
290 virtual bool isOnMap();
291 virtual bool isDead();
292 virtual bool isSelected();
293 virtual bool isTurnEnded();
294 virtual bool isCameraAttached();
295 virtual bool isPlayerPartyMember();
296 virtual bool isPlayerControlled();
297 virtual bool canWanderTo(int x, int y);
299 virtual void addView();
300 virtual void rmView();
301 virtual void updateView();
302 virtual bool addToInventory(class Object *object);
303 virtual bool hasInInventory(class ObjectType *type);
304 virtual void attachCamera(bool val);
305 virtual void heal(int amount);
306 virtual void save(struct save *save);
307 virtual void setLight(int val);
308 virtual void setOnMap(bool val);
309 virtual void setX(int x);
310 virtual void setY(int y);
311 virtual void changeX(int dx);
312 virtual void changeY(int dy);
313 virtual void setCount(int count);
314 virtual void setPlace(struct place *place);
315 virtual void select(bool val);
316 virtual void destroy();
317 virtual void relocate(struct place *newplace, int newx, int newy,
319 struct closure *place_switch_hook = NULL);
320 virtual void remove();
321 virtual void start();
322 virtual bool isVisible();
323 virtual void setVisible(bool val);
324 virtual bool isSubmerged();
325 virtual void setSubmerged(bool val);
326 virtual bool isShaded();
327 virtual void describe();
328 virtual void examine();
329 virtual void paint(int sx, int sy);
330 virtual class Object *clone();
331 virtual bool joinPlayer(void);
332 virtual void synchronize();
334 virtual int getActionPointsPerTurn();
335 virtual void applyEffect(closure_t *effect);
336 virtual int getActionPoints();
337 virtual void resetActionPoints();
339 virtual void sleep();
340 virtual void damage(int amount);
341 virtual void inflictDamage(int amount,class Character *attacker);
342 virtual void decActionPoints(int points);
343 virtual void setActionPoints(int amount);
344 virtual void endTurn();
345 virtual void startTurn();
346 virtual void setControlMode(enum control_mode);
347 virtual bool putOnMap(struct place *place, int x, int y, int r,
348 int flags /* PFLAG_* (see place.h) */);
349 virtual void setView(struct mview *view);
350 virtual void changePlaceHook();
351 virtual MoveResult move(int dx, int dy);
354 virtual void hookForEach(int hook_id,
355 int (*cb)(struct hook_entry *entry,
358 virtual bool addEffect(struct effect *effect, struct gob *gob);
359 virtual void restoreEffect(struct effect *effect, struct gob *gob,
360 int flags, clock_alarm_t expiration);
361 virtual void runHook(int hook_id, const char *fmt, ...);
362 virtual void saveHooks(struct save *save);
363 virtual bool removeEffect(struct effect *effect);
366 // Virtual container ops
367 virtual bool addFood(int quantity);
368 virtual bool addGold(int quantity);
369 virtual bool add(ObjectType *type, int amount);
370 virtual bool takeOut(ObjectType *type, int amount);
372 // ghulscript-object (gob) access.
373 void setGob(struct gob *gob);
374 struct gob * getGob();
376 // State variables affected by script execution
377 virtual void setSprite(struct sprite *sprite);
378 virtual struct sprite *getSprite();
380 virtual void setOpacity(bool opaque);
381 virtual bool isOpaque();
382 virtual bool tryToRelocateToNewPlace(struct place *place,
384 struct closure *cutscene);
386 // Proxies into script signals
390 void step(Object *stepper);
391 void sense(Object *stepper);
392 void attack(Object *attacker);
393 void onAttack(Object *user);
394 void enter(Object *enterer);
396 // Conversation interface
397 void setConversation(struct conv *conv);
398 virtual struct conv *getConversation();
399 virtual Object *getSpeaker();
401 virtual bool isTemporary();
402 virtual void setTemporary(bool val);
404 virtual int getMovementCost(int pclass);
405 virtual struct mmode *getMovementMode();
406 virtual void setMovementMode(struct mmode *mmode);
407 virtual bool isPassable(int pclass);
408 virtual void setPclass(int val);
409 virtual int getPclass();
410 virtual bool isStationary();
413 // These two might destroy the object so make them class methods:
414 static void setTTL(class Object *obj, int val);
415 static void decrementTTL(class Object *obj);
417 bool ignoresTimeStop();
418 void setIgnoreTimeStop(bool val);
420 struct node *clink; // points back to node in container's list
423 struct list list; // for the loader, not the place
425 struct node *turn_list; /* points back to node in place's turn list */
427 // The session handle for removing/checking the orphan list
430 // The session id of the last save.
433 /* The reference count. Use the obj_inc_ref() and obj_dec_ref() macros
434 * to change this. obj_dec_ref() will destroy the object when this hits
438 bool setFacing(int facing);
440 struct sprite *getPortrait();
441 void setPortrait(struct sprite *sprite);
444 virtual void setup();
446 class ObjectType * type;
456 enum control_mode control_mode;
457 bool camera_attached;
468 } hooks[OBJ_NUM_HOOKS];
470 // (Possibly null) pointer to this object's corresponding ghulscript
474 // Used to shadow the ObjectType sprite for objects whose sprite is
475 // determined by their gob state (like mechs).
476 struct sprite *current_sprite;
479 // Used for invisibility;
482 // Forces addEffect() to add the given effect without allowing the
483 // "add-hook-hook" effects to prevent it. Used by start().
486 // For fields, mechs and other objects that affect passability:
489 // Time to live: if > 0, this is decremented whenever the object
490 // executes a turn. When it falls to zero the object is removed from
491 // the map, which will destroy it once nothing else references
492 // it. Defaults to -1 (ie, infinite).
496 bool surreptitiouslyRemove();
498 void triggerSense(struct place *tilePlace, int tileX, int tileY);
499 void triggerStep(struct place *tilePlace, int tileX, int tileY);
500 void triggerOnTileEntry(struct place *tilePlace, int tileX, int tileY,
502 void triggerOnTileExit(struct place *tilePlace, int tileX, int tileY,
507 // Each object has its own sprite_frame, which breaks up the
508 // "synchronized dancing" problem. It also allows us to animate only
509 // player-controlled characters during Time Stop.
512 // Used for critters that can go underwater.
515 struct sprite *portrait;
521 extern void obj_inc_ref(Object *obj);
522 extern void obj_dec_ref(Object *obj);
523 #define obj_dec_ref_safe(obj) do { if ((obj)) obj_dec_ref(obj); } while (0)