00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00028 #include <global.h>
00029 #include <ob_methods.h>
00030 #include <ob_types.h>
00031 #include <sounds.h>
00032 #include <sproto.h>
00033
00034 static method_ret gate_type_process(ob_methods *context, object *op);
00035 static method_ret timed_gate_type_process(ob_methods *context, object *op);
00036
00040 void init_type_gate(void) {
00041 register_process(GATE, gate_type_process);
00042 register_process(TIMED_GATE, timed_gate_type_process);
00043 }
00044
00051 static method_ret gate_type_process(ob_methods *context, object *op) {
00052 object *tmp;
00053
00054 if (op->stats.wc < 0 || (int)op->stats.wc >= NUM_ANIMATIONS(op)) {
00055 StringBuffer *sb;
00056 char *diff;
00057
00058 LOG(llevError, "Gate error: animation was %d, max=%d\n", op->stats.wc, NUM_ANIMATIONS(op));
00059 sb = stringbuffer_new();
00060 dump_object(op, sb);
00061 diff = stringbuffer_finish(sb);
00062 LOG(llevError, "%s\n", diff);
00063 free(diff);
00064 op->stats.wc = 0;
00065 }
00066
00067
00068 if (op->value) {
00069 if (--op->stats.wc <= 0) {
00070 op->stats.wc = 0;
00071 if (op->arch->clone.speed)
00072 op->value = 0;
00073 else {
00074 op->speed = 0;
00075 update_ob_speed(op);
00076 }
00077 }
00078 if ((int)op->stats.wc < (NUM_ANIMATIONS(op)/2+1)) {
00079 op->move_block = 0;
00080 CLEAR_FLAG(op, FLAG_BLOCKSVIEW);
00081 update_all_los(op->map, op->x, op->y);
00082 }
00083 SET_ANIMATION(op, op->stats.wc);
00084 update_object(op, UP_OBJ_CHANGE);
00085 return METHOD_OK;
00086 }
00087
00088
00089
00090
00091 if ((unsigned char)op->stats.wc == (NUM_ANIMATIONS(op)-1)) {
00092
00093
00094
00095
00096
00097
00098 for (tmp = op->above; tmp != NULL; tmp = tmp->above)
00099 if (!QUERY_FLAG(tmp, FLAG_NO_PICK)
00100 || QUERY_FLAG(tmp, FLAG_CAN_ROLL)
00101 || QUERY_FLAG(tmp, FLAG_ALIVE))
00102 break;
00103
00104 if (tmp == NULL) {
00105 if (op->arch->clone.speed)
00106 op->value = 1;
00107 else {
00108 op->speed = 0;
00109 update_ob_speed(op);
00110 }
00111 return METHOD_OK;
00112 }
00113 }
00114
00115 if (op->stats.food) {
00116 if (--op->stats.wc <= 0) {
00117 op->stats.food = 0;
00118 op->stats.wc = 0;
00119 }
00120 } else {
00121 op->stats.wc++;
00122
00123 if ((int)op->stats.wc >= (NUM_ANIMATIONS(op)))
00124 op->stats.wc = (signed char)NUM_ANIMATIONS(op)-1;
00125
00126
00127
00128
00129 if ((int)op->stats.wc >= NUM_ANIMATIONS(op)/2) {
00130
00131
00132 for (tmp = op->above; tmp != NULL && tmp->above != NULL; tmp = tmp->above)
00133 ;
00134
00135 if (tmp != NULL) {
00136 if (QUERY_FLAG(tmp, FLAG_ALIVE)) {
00137 hit_player(tmp, random_roll(1, op->stats.dam, tmp, PREFER_LOW), op, AT_PHYSICAL, 1);
00138 if (tmp->type == PLAYER)
00139 draw_ext_info_format(NDI_UNIQUE, 0, tmp, MSG_TYPE_VICTIM, MSG_TYPE_VICTIM_WAS_HIT,
00140 "You are crushed by the %s!",
00141 "You are crushed by the %s!",
00142 op->name);
00143 } else
00144
00145
00146
00147
00148 if (!QUERY_FLAG(tmp, FLAG_ALIVE)
00149 && (!QUERY_FLAG(tmp, FLAG_NO_PICK) || QUERY_FLAG(tmp, FLAG_CAN_ROLL))) {
00150
00151 int i = find_free_spot(tmp, op->map, op->x, op->y, 1, 9);
00152
00153
00154 if (i != -1) {
00155 remove_ob(tmp);
00156 tmp->x += freearr_x[i],
00157 tmp->y += freearr_y[i];
00158 insert_ob_in_map(tmp, op->map, op, 0);
00159 }
00160 }
00161 }
00162
00163
00164 for (tmp = op->above; tmp != NULL; tmp = tmp->above)
00165 if (!QUERY_FLAG(tmp, FLAG_NO_PICK)
00166 || QUERY_FLAG(tmp, FLAG_CAN_ROLL)
00167 || QUERY_FLAG(tmp, FLAG_ALIVE))
00168 break;
00169
00170
00171 if (tmp) {
00172 op->stats.food = 1;
00173 } else {
00174 op->move_block = MOVE_ALL;
00175 if (!op->arch->clone.stats.ac)
00176 SET_FLAG(op, FLAG_BLOCKSVIEW);
00177 update_all_los(op->map, op->x, op->y);
00178 }
00179 }
00180
00181 SET_ANIMATION(op, op->stats.wc);
00182 update_object(op, UP_OBJ_CHANGE);
00183 }
00184
00185 return METHOD_OK;
00186 }
00187
00198 static method_ret timed_gate_type_process(ob_methods *context, object *op) {
00199 int v = op->value;
00200
00201 if (op->stats.sp) {
00202 gate_type_process(context, op);
00203 if (op->value != v)
00204 op->stats.sp = 0;
00205 return METHOD_OK;
00206 }
00207 if (--op->stats.hp <= 0) {
00208 gate_type_process(context, op);
00209 if (op->value != v) {
00210 op->speed = 0;
00211 update_ob_speed(op);
00212 }
00213 }
00214 return METHOD_OK;
00215 }