OSDN Git Service

Nazghul-0.7.1
[nazghul-jp/nazghul-jp.git] / src / object.h
1 //
2 // nazghul - an old-school RPG engine
3 // Copyright (C) 2002, 2003 Gordon McNutt
4 //
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)
8 // any later version.
9 //
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
13 // more details.
14 //
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
18 //
19 // Gordon McNutt
20 // gmcnutt@users.sourceforge.net
21 //
22 #ifndef object_h
23 #define object_h
24
25 #include "clock.h"
26 #include "list.h"
27 #include "olist.h"
28 #include "closure.h"
29 #include "console.h"            // SAM: for DEBUG purposes...
30 #include "sound.h"
31
32 #include <assert.h>
33
34
35 // Wrappers for session_add() and session_rm() that do the ref-counting.
36 #define session_add_obj(session, obj, dtor, save, start)                      \
37         do {                                                                  \
38                 obj_inc_ref((obj));                                           \
39                 (obj)->handle = session_add((session), (obj), (dtor), (save), \
40                                             (start));                         \
41         } while (0)
42
43 #define session_rm_obj(session, obj)                                          \
44         do {                                                                  \
45                 session_rm((session), (obj)->handle);                         \
46                 obj_dec_ref((obj));                                           \
47         } while (0)
48
49 /* Hack: until movement modes implemented in objects */
50 #define obj_mmode(obj) ((obj)->getMovementMode())
51
52 /* Hooks id's */
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            */
75
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   */
80
81 // Note: if you change the layers you'll probably need to change the save
82 //       file
83 // Proper rendering depends on keeping these in order!
84 enum layer {
85         null_layer       = 0,
86         tfeat_layer      = 1,
87         mech_layer       = 2,
88         portal_layer     = 3,
89         vehicle_layer    = 4,
90         bed_layer        = 5,
91         container_layer  = 6,
92         item_layer       = 7,
93         field_layer      = 8,
94         being_layer      = 9,
95         projectile_layer = 10,
96         cursor_layer     = 11
97 };
98
99 enum control_mode {
100         CONTROL_MODE_AUTO = 0,
101         CONTROL_MODE_PLAYER,
102         CONTROL_MODE_IDLE,
103         CONTROL_MODE_FOLLOW,
104         CONTROL_MODE_TASK
105 };
106
107 enum MoveResult {
108         MovedOk,
109         ExitedMap,
110         EngagedEnemy,
111         WasOccupied,
112         WasImpassable,
113         SlowProgress,
114         SwitchedOccupants,
115         CouldNotSwitchOccupants,
116         OffMap, // and no parent
117         NotFollowMode,
118         CantRendezvous,
119         NotApplicable,
120         ChangedFacing,
121         AvoidedHazard,
122         OutOfRange,
123         NoDestination,
124         UserCanceled,
125         StationaryObject,
126         NotInVehicle
127 };
128
129 struct inv_entry {
130         struct list list;
131         struct list auxlist;
132         int count;
133         int ref;
134         class ObjectType *type;
135 };
136
137 struct filter {
138         bool (*fx)(struct inv_entry *ie, void *fdata);
139         void *fdata;
140 };
141
142 typedef struct hook_entry {
143         struct list list;
144         struct effect *effect;
145         struct gob *gob;
146         clock_alarm_t expiration;
147         int flags;
148         char started : 1; /* unsaved flag */
149 } hook_entry_t;
150
151 class ObjectType {
152
153       public:
154         virtual bool isType(int classID);
155         virtual int getType();
156         ObjectType();
157         ObjectType(const char *tag, const char *name, struct sprite *sprite, 
158                    enum layer layer);
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(); 
174         
175         // This might turn out to be too vague. We'll see.
176         virtual int getRequiredActionPoints();
177
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);
181
182         bool isUsable();    // items, etc
183         bool isReadyable(); // arms
184         bool isMixable();   // reagents
185         bool isCastable();  // spells
186         bool canExec();     // mechs, etc
187         bool canGet();
188         bool canOpen();
189         bool canStep();
190         bool canHandle();
191         bool canSense();
192         bool canXamine();
193         bool canAttack();
194         bool canOnAttack();
195         bool canEnter();
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'
200         bool isQuestItem();
201
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);
219
220         closure_t *getGifc();
221         void setGifc(closure_t *gifc, int cap);
222
223         void setPluralName(char *val);
224         void setGob(struct gob *gob);
225         struct gob * getGob();
226         void setQuestItemFlag(bool val);
227
228
229       protected:
230         char *tag;
231         char *name;
232         struct sprite *sprite;
233         enum layer layer;
234         int speed;
235         int required_action_points;
236         int max_hp;
237
238         /* ghulscript-interface (gifc) */
239         closure_t *gifc;
240         int gifc_cap;
241         struct gob *gob;
242         struct mmode *movementMode;
243
244  private:
245         bool hasDescribeHook();
246         void runDescribeHook(Object *obj);
247
248         char *pluralName;
249         char *getPluralName();
250         bool questItemFlag;
251 };
252
253 class Object {
254
255       public:
256         virtual bool isType(int classID);
257         virtual int getType();
258
259         Object(class ObjectType * type); // preferred constructor
260
261         Object();
262         virtual ~Object();
263         virtual void init(int x, int y, struct place *place,
264                           class ObjectType * type);
265         virtual void init(class ObjectType * type);
266
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();
272         virtual int getHp();
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();
283         virtual int getX();
284         virtual int getY();
285         virtual int getDx();
286         virtual int getDy();
287
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);
298
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, 
318                               int flags = 0,
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();
333         virtual void exec();
334         virtual int getActionPointsPerTurn();
335         virtual void applyEffect(closure_t *effect);
336         virtual int getActionPoints();
337         virtual void resetActionPoints();
338         virtual void burn();
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);
352
353         // Hook/effect API.
354         virtual void hookForEach(int hook_id, 
355                                  int (*cb)(struct hook_entry *entry, 
356                                            void *data),
357                                  void *data);
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);
364         
365
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);        
371
372         // ghulscript-object (gob) access.
373         void setGob(struct gob *gob);
374         struct gob * getGob();
375
376         // State variables affected by script execution
377         virtual void setSprite(struct sprite *sprite);
378         virtual struct sprite *getSprite(); 
379
380         virtual void setOpacity(bool opaque);
381         virtual bool isOpaque();
382         virtual bool tryToRelocateToNewPlace(struct place *place, 
383                                              int x, int y,
384                                              struct closure *cutscene);
385
386         // Proxies into script signals
387         bool canEnter();
388         bool canStep();
389                 bool canSense();
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);
395
396         // Conversation interface
397         void setConversation(struct conv *conv);
398         virtual struct conv *getConversation();
399         virtual Object *getSpeaker();
400
401         virtual bool isTemporary();
402         virtual void setTemporary(bool val);
403
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();
411
412         int getTTL(void);
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);
416
417         bool ignoresTimeStop();
418         void setIgnoreTimeStop(bool val);
419         
420         struct node *clink; // points back to node in container's list
421
422         char *tag;
423         struct list list;       // for the loader, not the place
424
425         struct node *turn_list; /* points back to node in place's turn list */
426
427         // The session handle for removing/checking the orphan list
428         void *handle;
429
430         // The session id of the last save.
431         int saved;
432
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
435          * zero. */
436         int refcount;
437
438         bool setFacing(int facing);
439         int getFacing();
440         struct sprite *getPortrait();
441         void setPortrait(struct sprite *sprite);
442
443       protected:
444         virtual void setup();
445
446         class ObjectType * type;
447         int x;
448         int y;
449         int dx;
450         int dy;
451         int count;
452         struct place *place;
453         bool selected;
454         bool destroyed;
455         int action_points;
456         enum control_mode control_mode;
457         bool camera_attached;
458         int hp;
459         bool is_on_map;
460         struct conv *conv;
461         struct mview *view;
462         int light;
463         bool temporary;
464
465         struct hook_list {
466                 struct list list;
467                 int lock;
468         } hooks[OBJ_NUM_HOOKS];
469
470         // (Possibly null) pointer to this object's corresponding ghulscript
471         // object.
472         struct gob *gob;
473
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;
477         bool opacity;
478
479         // Used for invisibility;
480         int visible;
481
482         // Forces addEffect() to add the given effect without allowing the
483         // "add-hook-hook" effects to prevent it. Used by start().
484         bool forceEffect;
485
486         // For fields, mechs and other objects that affect passability:
487         int pclass;
488
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).
493         int ttl;
494
495  private:
496         bool surreptitiouslyRemove();
497         bool started;
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,
501                                 int flags);
502         void triggerOnTileExit(struct place *tilePlace, int tileX, int tileY,
503                                int flags);
504         int facing;
505         bool ignoreTimeStop;
506
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.
510         int sprite_frame;
511
512         // Used for critters that can go underwater.
513         bool submerged;
514
515         struct sprite *portrait;
516 };
517
518 #include "macros.h"
519 BEGIN_DECL
520
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)
524
525 END_DECL
526
527 #endif                          // object_h