Crossfire Server, Branches 1.12  R18729
gate.c
Go to the documentation of this file.
1 /*
2  CrossFire, A Multiplayer game for X-windows
3 
4  Copyright (C) 2007 Mark Wedel & Crossfire Development Team
5  Copyright (C) 1992 Frank Tore Johansen
6 
7  This program is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 2 of the License, or
10  (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., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21  The authors can be reached via e-mail at crossfire-devel@real-time.com
22 */
23 
28 #include <global.h>
29 #include <ob_methods.h>
30 #include <ob_types.h>
31 #include <sounds.h>
32 #include <sproto.h>
33 
34 static method_ret gate_type_process(ob_methods *context, object *op);
35 static method_ret timed_gate_type_process(ob_methods *context, object *op);
36 
40 void init_type_gate(void) {
43 }
44 
51 static method_ret gate_type_process(ob_methods *context, object *op) {
52  object *tmp;
53 
54  if (op->stats.wc < 0 || (int)op->stats.wc >= NUM_ANIMATIONS(op)) {
55  StringBuffer *sb;
56  char *diff;
57 
58  LOG(llevError, "Gate error: animation was %d, max=%d\n", op->stats.wc, NUM_ANIMATIONS(op));
59  sb = stringbuffer_new();
60  dump_object(op, sb);
61  diff = stringbuffer_finish(sb);
62  LOG(llevError, "%s\n", diff);
63  free(diff);
64  op->stats.wc = 0;
65  }
66 
67  /* We're going down */
68  if (op->value) {
69  if (--op->stats.wc <= 0) { /* Reached bottom, let's stop */
70  op->stats.wc = 0;
71  if (op->arch->clone.speed)
72  op->value = 0;
73  else {
74  op->speed = 0;
75  update_ob_speed(op);
76  }
77  }
78  if ((int)op->stats.wc < (NUM_ANIMATIONS(op)/2+1)) {
79  op->move_block = 0;
81  update_all_los(op->map, op->x, op->y);
82  }
83  SET_ANIMATION(op, op->stats.wc);
85  return METHOD_OK;
86  }
87 
88  /* We're going up */
89 
90  /* First, lets see if we are already at the top */
91  if ((unsigned char)op->stats.wc == (NUM_ANIMATIONS(op)-1)) {
92  /* Check to make sure that only non pickable and non rollable
93  * objects are above the gate. If so, we finish closing the gate,
94  * otherwise, we fall through to the code below which should lower
95  * the gate slightly.
96  */
97 
98  for (tmp = op->above; tmp != NULL; tmp = tmp->above)
99  if (!QUERY_FLAG(tmp, FLAG_NO_PICK)
100  || QUERY_FLAG(tmp, FLAG_CAN_ROLL)
101  || QUERY_FLAG(tmp, FLAG_ALIVE))
102  break;
103 
104  if (tmp == NULL) {
105  if (op->arch->clone.speed)
106  op->value = 1;
107  else {
108  op->speed = 0;
109  update_ob_speed(op); /* Reached top, let's stop */
110  }
111  return METHOD_OK;
112  }
113  }
114 
115  if (op->stats.food) { /* The gate is going temporarily down */
116  if (--op->stats.wc <= 0) { /* Gone all the way down? */
117  op->stats.food = 0; /* Then let's try again */
118  op->stats.wc = 0;
119  }
120  } else { /* The gate is still going up */
121  op->stats.wc++;
122 
123  if ((int)op->stats.wc >= (NUM_ANIMATIONS(op)))
124  op->stats.wc = (signed char)NUM_ANIMATIONS(op)-1;
125 
126  /* If there is something on top of the gate, we try to roll it off.
127  * If a player/monster, we don't roll, we just hit them with damage
128  */
129  if ((int)op->stats.wc >= NUM_ANIMATIONS(op)/2) {
130  /* Halfway or further, check blocks */
131  /* First, get the top object on the square. */
132  for (tmp = op->above; tmp != NULL && tmp->above != NULL; tmp = tmp->above)
133  ;
134 
135  if (tmp != NULL) {
136  if (QUERY_FLAG(tmp, FLAG_ALIVE)) {
137  hit_player(tmp, random_roll(1, op->stats.dam, tmp, PREFER_LOW), op, AT_PHYSICAL, 1);
138  if (tmp->type == PLAYER)
140  "You are crushed by the %s!",
141  "You are crushed by the %s!",
142  op->name);
143  } else
144  /* If the object is not alive, and the object either can
145  * be picked up or the object rolls, move the object
146  * off the gate.
147  */
148  if (!QUERY_FLAG(tmp, FLAG_ALIVE)
149  && (!QUERY_FLAG(tmp, FLAG_NO_PICK) || QUERY_FLAG(tmp, FLAG_CAN_ROLL))) {
150  /* If it has speed, it should move itself, otherwise: */
151  int i = find_free_spot(tmp, op->map, op->x, op->y, 1, 9);
152 
153  /* If there is a free spot, move the object someplace */
154  if (i != -1) {
155  remove_ob(tmp);
156  tmp->x += freearr_x[i],
157  tmp->y += freearr_y[i];
158  insert_ob_in_map(tmp, op->map, op, 0);
159  }
160  }
161  }
162 
163  /* See if there is still anything blocking the gate */
164  for (tmp = op->above; tmp != NULL; tmp = tmp->above)
165  if (!QUERY_FLAG(tmp, FLAG_NO_PICK)
166  || QUERY_FLAG(tmp, FLAG_CAN_ROLL)
167  || QUERY_FLAG(tmp, FLAG_ALIVE))
168  break;
169 
170  /* IF there is, start putting the gate down */
171  if (tmp) {
172  op->stats.food = 1;
173  } else {
174  op->move_block = MOVE_ALL;
175  if (!op->arch->clone.stats.ac)
177  update_all_los(op->map, op->x, op->y);
178  }
179  } /* gate is halfway up */
180 
181  SET_ANIMATION(op, op->stats.wc);
183  } /* gate is going up */
184 
185  return METHOD_OK;
186 }
187 
198 static method_ret timed_gate_type_process(ob_methods *context, object *op) {
199  int v = op->value;
200 
201  if (op->stats.sp) {
202  gate_type_process(context, op);
203  if (op->value != v) /* change direction ? */
204  op->stats.sp = 0;
205  return METHOD_OK;
206  }
207  if (--op->stats.hp <= 0) { /* keep gate down */
208  gate_type_process(context, op);
209  if (op->value != v) { /* ready ? */
210  op->speed = 0;
211  update_ob_speed(op);
212  }
213  }
214  return METHOD_OK;
215 }
static method_ret gate_type_process(ob_methods *context, object *op)
Definition: gate.c:51
sint8 ac
Definition: living.h:79
#define SET_FLAG(xyz, p)
Definition: define.h:510
static method_ret timed_gate_type_process(ob_methods *context, object *op)
Definition: gate.c:198
StringBuffer * stringbuffer_new(void)
Definition: stringbuffer.c:64
#define SET_ANIMATION(ob, newanim)
Definition: global.h:247
object clone
Definition: object.h:326
short freearr_x[SIZEOFFREE]
Definition: object.c:75
#define PREFER_LOW
Definition: define.h:909
void update_object(object *op, int action)
Definition: object.c:1112
#define MSG_TYPE_VICTIM_WAS_HIT
Definition: newclient.h:567
struct obj * above
Definition: object.h:146
sint16 x
Definition: object.h:179
sint16 sp
Definition: living.h:83
void draw_ext_info_format(int flags, int pri, const object *pl, uint8 type, uint8 subtype, const char *new_format, const char *old_format,...)
Definition: standalone.c:175
#define PLAYER
Definition: define.h:113
sint16 hp
Definition: living.h:81
#define FLAG_CAN_ROLL
Definition: define.h:550
short freearr_y[SIZEOFFREE]
Definition: object.c:81
#define MOVE_ALL
Definition: define.h:706
char method_ret
Definition: ob_methods.h:41
void remove_ob(object *op)
Definition: object.c:1515
#define FLAG_ALIVE
Definition: define.h:526
#define MSG_TYPE_VICTIM
Definition: newclient.h:336
void update_all_los(const mapstruct *map, int x, int y)
Definition: los.c:544
#define METHOD_OK
Definition: ob_methods.h:42
struct mapdef * map
Definition: object.h:155
void dump_object(object *op, StringBuffer *sb)
Definition: object.c:372
sint16 dam
Definition: living.h:87
#define FLAG_BLOCKSVIEW
Definition: define.h:565
const char * name
Definition: object.h:167
void init_type_gate(void)
Definition: gate.c:40
sint16 y
Definition: object.h:179
#define AT_PHYSICAL
Definition: attack.h:104
float speed
Definition: object.h:181
#define QUERY_FLAG(xyz, p)
Definition: define.h:514
#define CLEAR_FLAG(xyz, p)
Definition: define.h:512
object * insert_ob_in_map(object *op, mapstruct *m, object *originator, int flag)
Definition: object.c:1992
sint8 wc
Definition: living.h:79
#define TIMED_GATE
Definition: define.h:138
#define UP_OBJ_CHANGE
Definition: object.h:355
#define NUM_ANIMATIONS(ob)
Definition: global.h:255
living stats
Definition: object.h:219
struct archt * arch
Definition: object.h:263
void register_process(int ob_type, process_func method)
Definition: ob_types.c:88
void update_ob_speed(object *op)
Definition: object.c:1008
int find_free_spot(const object *ob, mapstruct *m, int x, int y, int start, int stop)
Definition: object.c:3200
#define NDI_UNIQUE
Definition: newclient.h:219
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.c:63
MoveType move_block
Definition: object.h:278
int random_roll(int min, int max, const object *op, int goodbad)
Definition: utils.c:51
#define FLAG_NO_PICK
Definition: define.h:535
#define GATE
Definition: define.h:273
sint32 value
Definition: object.h:201
int hit_player(object *op, int dam, object *hitter, uint32 type, int full_hit)
Definition: attack.c:1868
char * stringbuffer_finish(StringBuffer *sb)
Definition: stringbuffer.c:78
uint8 type
Definition: object.h:189
sint32 food
Definition: living.h:89