|
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 00030 #include <global.h> 00031 00036 void move_player_mover(object *op) 00037 { 00038 object *victim, *victim_next; 00039 mapstruct *mt; 00040 int xt, yt, dir = op->direction; 00041 00042 op->value = pticks; 00043 00044 if (!(blocked(NULL, op->map, op->x, op->y, TERRAIN_NOTHING) & (P_IS_ALIVE | P_IS_PLAYER))) 00045 { 00046 return; 00047 } 00048 00049 /* Determine direction now for random movers so we do the right thing. */ 00050 if (!dir) 00051 { 00052 dir = get_random_dir(); 00053 } 00054 00055 for (victim = GET_BOTTOM_MAP_OB(op); victim; victim = victim_next) 00056 { 00057 victim_next = victim->above; 00058 00059 if (IS_LIVE(victim) && (!(QUERY_FLAG(victim, FLAG_FLYING)) || op->stats.maxhp)) 00060 { 00061 if (QUERY_FLAG(op, FLAG_LIFESAVE) && op->stats.hp-- < 0) 00062 { 00063 destruct_ob(op); 00064 return; 00065 } 00066 00067 /* No direction, this means 'xrays 1' was set; so use the 00068 * victim's direction instead. */ 00069 if (!op->direction && QUERY_FLAG(op, FLAG_XRAYS)) 00070 { 00071 dir = victim->direction; 00072 } 00073 00074 xt = op->x + freearr_x[dir]; 00075 yt = op->y + freearr_y[dir]; 00076 00077 if (!(mt = get_map_from_coord(op->map, &xt, &yt))) 00078 { 00079 return; 00080 } 00081 00082 /* Flag to stop moving if there's a wall. */ 00083 if (QUERY_FLAG(op, FLAG_STAND_STILL) && blocked(victim, mt, xt, yt, victim->terrain_flag)) 00084 { 00085 continue; 00086 } 00087 00088 /* Unless there is an alive object or a player on the square 00089 * this object is being moved onto, disable the mover on that 00090 * square, if any. This is done so the object doesn't rocket 00091 * across a bunch of movers. */ 00092 if (!(blocked(NULL, mt, xt, yt, TERRAIN_NOTHING) & (P_IS_ALIVE | P_IS_PLAYER))) 00093 { 00094 object *nextmover; 00095 00096 for (nextmover = GET_MAP_OB(mt, xt, yt); nextmover; nextmover = nextmover->above) 00097 { 00098 /* Only disable movers that didn't go this tick yet; 00099 * otherwise they wouldn't trigger on the next tick to 00100 * move objects they may have on top of them. */ 00101 if (nextmover->type == PLAYERMOVER && nextmover->value != op->value) 00102 { 00103 nextmover->speed_left--; 00104 } 00105 } 00106 } 00107 00108 if (victim->type == PLAYER) 00109 { 00110 /* only level >=1 movers move people */ 00111 if (op->level) 00112 { 00113 /* Following is a bit of hack. We need to make sure it 00114 * is cleared, otherwise the player will get stuck in 00115 * place. This can happen if the player used a spell to 00116 * get to this space. */ 00117 CONTR(victim)->fire_on = 0; 00118 victim->speed_left = -FABS(victim->speed); 00119 move_player(victim, dir); 00120 /* Clear player's path; they probably can't move there 00121 * any more after being pushed, or might not want to. */ 00122 player_path_clear(CONTR(victim)); 00123 } 00124 else 00125 { 00126 continue; 00127 } 00128 } 00129 else if (op->stats.grace) 00130 { 00131 move_object(victim, dir); 00132 } 00133 else 00134 { 00135 continue; 00136 } 00137 00138 if (!op->stats.maxsp && op->stats.sp) 00139 { 00140 op->stats.maxsp = 2; 00141 } 00142 00143 /* flag to paralyze the player */ 00144 if (op->stats.sp) 00145 { 00146 victim->speed_left = -(op->stats.maxsp * FABS(victim->speed)); 00147 } 00148 } 00149 } 00150 }
1.7.4