|
Atrinik Server 2.5
|
00001 /************************************************************************ 00002 * Atrinik, a Multiplayer Online Role Playing Game * 00003 * * 00004 * Copyright (C) 2009-2011 Alex Tokar and Atrinik Development Team * 00005 * * 00006 * Fork from Daimonin (Massive Multiplayer Online Role Playing Game) * 00007 * and Crossfire (Multiplayer game for X-windows). * 00008 * * 00009 * This program is free software; you can redistribute it and/or modify * 00010 * it under the terms of the GNU General Public License as published by * 00011 * the Free Software Foundation; either version 2 of the License, or * 00012 * (at your option) any later version. * 00013 * * 00014 * This program is distributed in the hope that it will be useful, * 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00017 * GNU General Public License for more details. * 00018 * * 00019 * You should have received a copy of the GNU General Public License * 00020 * along with this program; if not, write to the Free Software * 00021 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 00022 * * 00023 * The author can be reached at admin@atrinik.org * 00024 ************************************************************************/ 00025 00031 #include <global.h> 00032 00036 void move_gate(object *op) 00037 { 00038 object *tmp; 00039 /* default update is only face */ 00040 int update = UP_OBJ_FACE; 00041 00042 if (op->stats.wc < 0 || (int) op->stats.wc >= (NUM_ANIMATIONS(op) / NUM_FACINGS(op))) 00043 { 00044 LOG(llevBug, "move_gate(): Gate animation was %d, max=%d\n", op->stats.wc, (NUM_ANIMATIONS(op) / NUM_FACINGS(op))); 00045 op->stats.wc = 0; 00046 } 00047 00048 /* We're going down (or reverse up) */ 00049 if (op->value) 00050 { 00051 /* Reached bottom, let's stop */ 00052 if (--op->stats.wc <= 0) 00053 { 00054 op->stats.wc = 0; 00055 00056 if (op->arch->clone.speed) 00057 { 00058 op->value = 0; 00059 } 00060 else 00061 { 00062 op->speed = 0; 00063 update_ob_speed(op); 00064 } 00065 } 00066 00067 if ((int) op->stats.wc < ((NUM_ANIMATIONS(op) / NUM_FACINGS(op)) / 2 + 1)) 00068 { 00069 /* We do the QUERY_FLAG() here to check we must rebuild the tile flags or not, 00070 * if we don't change the object settings here, just change the face but 00071 * don't rebuild the flag tiles. 00072 * If != 0, we have a reversed timed gate, which starts open */ 00073 if (op->last_heal) 00074 { 00075 if (!QUERY_FLAG(op, FLAG_NO_PASS)) 00076 { 00077 update = UP_OBJ_FLAGFACE; 00078 } 00079 00080 /* The coast is clear, block the way */ 00081 SET_FLAG(op, FLAG_NO_PASS); 00082 00083 if (!op->arch->clone.stats.ac) 00084 { 00085 if (!QUERY_FLAG(op, FLAG_BLOCKSVIEW)) 00086 { 00087 update = UP_OBJ_FLAGFACE; 00088 } 00089 00090 SET_FLAG(op, FLAG_BLOCKSVIEW); 00091 } 00092 } 00093 else 00094 { 00095 if (QUERY_FLAG(op, FLAG_NO_PASS)) 00096 { 00097 update = UP_OBJ_FLAGFACE; 00098 } 00099 00100 CLEAR_FLAG(op, FLAG_NO_PASS); 00101 00102 if (QUERY_FLAG(op, FLAG_BLOCKSVIEW)) 00103 { 00104 update = UP_OBJ_FLAGFACE; 00105 } 00106 00107 CLEAR_FLAG(op, FLAG_BLOCKSVIEW); 00108 } 00109 } 00110 00111 op->state = (uint8) op->stats.wc; 00112 SET_ANIMATION(op, (NUM_ANIMATIONS(op) / NUM_FACINGS(op)) * op->direction + op->state); 00113 update_object(op, update); 00114 00115 return; 00116 } 00117 00118 /* First, lets see if we are already at the top */ 00119 if ((unsigned char) op->stats.wc == ((NUM_ANIMATIONS(op) / NUM_FACINGS(op)) - 1)) 00120 { 00121 /* Check to make sure that only non pickable and non rollable 00122 * objects are above the gate. If so, we finish closing the gate, 00123 * otherwise, we fall through to the code below which should lower 00124 * the gate slightly. */ 00125 for (tmp = GET_BOTTOM_MAP_OB(op); tmp; tmp = tmp->above) 00126 { 00127 if (QUERY_FLAG(tmp, FLAG_CAN_ROLL) || IS_LIVE(tmp)) 00128 { 00129 break; 00130 } 00131 } 00132 00133 if (tmp == NULL) 00134 { 00135 if (op->arch->clone.speed) 00136 { 00137 op->value = 1; 00138 } 00139 else 00140 { 00141 op->speed = 0; 00142 00143 /* Reached top, let's stop */ 00144 update_ob_speed(op); 00145 } 00146 00147 return; 00148 } 00149 } 00150 00151 /* The gate is going temporarily down */ 00152 if (op->stats.food) 00153 { 00154 /* Gone all the way down? */ 00155 if (--op->stats.wc <= 0) 00156 { 00157 /* Then let's try again */ 00158 op->stats.food = 0; 00159 op->stats.wc = 0; 00160 } 00161 } 00162 /* The gate is still going up */ 00163 else 00164 { 00165 op->stats.wc++; 00166 00167 if ((int) op->stats.wc >= ((NUM_ANIMATIONS(op) / NUM_FACINGS(op)))) 00168 { 00169 op->stats.wc = (signed char) (NUM_ANIMATIONS(op) / NUM_FACINGS(op)) - 1; 00170 } 00171 00172 /* If there is something on top of the gate, we try to roll it off. 00173 * If a player/monster, we don't roll, we just hit them with damage */ 00174 if ((int) op->stats.wc >= (NUM_ANIMATIONS(op) / NUM_FACINGS(op)) / 2) 00175 { 00176 object *next; 00177 00178 /* Halfway or further, check blocks */ 00179 for (tmp = GET_BOTTOM_MAP_OB(op); tmp; tmp = next) 00180 { 00181 next = tmp->above; 00182 00183 /* If the object is alive or the object rolls, move the object 00184 * off the gate. */ 00185 if (QUERY_FLAG(tmp, FLAG_CAN_ROLL) || IS_LIVE(tmp)) 00186 { 00187 int i; 00188 00189 if (IS_LIVE(tmp)) 00190 { 00191 hit_player(tmp, 4, op, AT_PHYSICAL); 00192 new_draw_info_format(0, COLOR_WHITE, tmp, "You are crushed by the %s!", op->name); 00193 } 00194 00195 i = find_free_spot(tmp->arch, tmp, op->map, op->x, op->y, 1, 9); 00196 00197 /* If there is a free spot, move the object someplace. */ 00198 if (i != -1) 00199 { 00200 remove_ob(tmp); 00201 check_walk_off(tmp, NULL, MOVE_APPLY_VANISHED); 00202 tmp->x += freearr_x[i]; 00203 tmp->y += freearr_y[i]; 00204 insert_ob_in_map(tmp, op->map, op, 0); 00205 } 00206 } 00207 } 00208 00209 /* If there is still something, start putting the gate down */ 00210 if (tmp) 00211 { 00212 op->stats.food = 1; 00213 } 00214 else 00215 { 00216 /* If != 0, we have a reversed timed gate, which starts open */ 00217 if (op->last_heal) 00218 { 00219 if (QUERY_FLAG(op, FLAG_NO_PASS)) 00220 { 00221 update = UP_OBJ_FLAGFACE; 00222 } 00223 00224 CLEAR_FLAG(op, FLAG_NO_PASS); 00225 00226 if (QUERY_FLAG(op, FLAG_BLOCKSVIEW)) 00227 { 00228 update = UP_OBJ_FLAGFACE; 00229 } 00230 00231 CLEAR_FLAG(op, FLAG_BLOCKSVIEW); 00232 } 00233 else 00234 { 00235 if (!QUERY_FLAG(op, FLAG_NO_PASS)) 00236 { 00237 update = UP_OBJ_FLAGFACE; 00238 } 00239 00240 /* The coast is clear, block the way */ 00241 SET_FLAG(op, FLAG_NO_PASS); 00242 00243 if (!op->arch->clone.stats.ac) 00244 { 00245 if (!QUERY_FLAG(op, FLAG_BLOCKSVIEW)) 00246 { 00247 update = UP_OBJ_FLAGFACE; 00248 } 00249 00250 SET_FLAG(op, FLAG_BLOCKSVIEW); 00251 } 00252 } 00253 } 00254 } 00255 00256 op->state = (uint8) op->stats.wc; 00257 SET_ANIMATION(op, (NUM_ANIMATIONS(op) / NUM_FACINGS(op)) * op->direction + op->state); 00258 00259 /* Takes care about map tile and player los update! */ 00260 update_object(op, update); 00261 } 00262 } 00263 00267 void move_timed_gate(object *op) 00268 { 00269 int v = op->value; 00270 00271 if (op->stats.sp) 00272 { 00273 move_gate(op); 00274 00275 /* Change direction? */ 00276 if (op->value != v) 00277 { 00278 op->stats.sp = 0; 00279 } 00280 00281 return; 00282 } 00283 00284 /* Keep gate down */ 00285 if (--op->stats.hp <= 0) 00286 { 00287 move_gate(op); 00288 00289 /* Ready? */ 00290 if (op->value != v) 00291 { 00292 op->speed = 0; 00293 update_ob_speed(op); 00294 } 00295 } 00296 }
1.7.4