Atrinik Server  4.0
player_mover.c
Go to the documentation of this file.
1 /*************************************************************************
2  * Atrinik, a Multiplayer Online Role Playing Game *
3  * *
4  * Copyright (C) 2009-2014 Alex Tokar and Atrinik Development Team *
5  * *
6  * Fork from Crossfire (Multiplayer game for X-windows). *
7  * *
8  * This program is free software; you can redistribute it and/or modify *
9  * it under the terms of the GNU General Public License as published by *
10  * the Free Software Foundation; either version 2 of the License, or *
11  * (at your option) any later version. *
12  * *
13  * This program is distributed in the hope that it will be useful, *
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16  * GNU General Public License for more details. *
17  * *
18  * You should have received a copy of the GNU General Public License *
19  * along with this program; if not, write to the Free Software *
20  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
21  * *
22  * The author can be reached at admin@atrinik.org *
23  ************************************************************************/
24 
32 #include <global.h>
33 #include <object.h>
34 #include <player.h>
35 #include <object_methods.h>
36 
47 static void player_mover_handle(object *op, object *victim, bool process)
48 {
49  HARD_ASSERT(op != NULL);
50  HARD_ASSERT(victim != NULL);
51 
52  if (!IS_LIVE(victim)) {
53  return;
54  }
55 
56  if (QUERY_FLAG(victim, FLAG_FLYING) && op->stats.maxhp == 0) {
57  return;
58  }
59 
60  if (QUERY_FLAG(op, FLAG_LIFESAVE) && op->stats.hp-- < 0) {
61  object_destruct(op);
62  return;
63  }
64 
65  int dir;
66  /* No direction, this means 'xrays 1' was set; so use the
67  * victim's direction instead. */
68  if (op->direction == 0 && QUERY_FLAG(op, FLAG_XRAYS)) {
69  dir = victim->direction;
70  } else {
71  dir = op->direction;
72  if (dir == 0) {
73  dir = get_random_dir();
74  }
75  }
76 
77  int x = op->x + freearr_x[dir];
78  int y = op->y + freearr_y[dir];
79  mapstruct *map = get_map_from_coord(op->map, &x, &y);
80  if (map == NULL) {
81  return;
82  }
83 
84  /* Flag to stop moving if there's a wall. */
85  if (QUERY_FLAG(op, FLAG_STAND_STILL) &&
86  blocked(victim, map, x, y, victim->terrain_flag)) {
87  return;
88  }
89 
90  if (!DBL_EQUAL(op->speed, 0.0)) {
91  object *nextmover;
92  FOR_MAP_LAYER_BEGIN(map, x, y, LAYER_SYS, -1, nextmover) {
93  if (nextmover->type == op->type && nextmover->value != pticks) {
94  nextmover->speed_left--;
95  }
97  }
98 
99  if (victim->type == PLAYER) {
100  if (op->level == 0) {
101  return;
102  }
103  } else if (op->stats.hp == 0) {
104  return;
105  }
106 
107  if (process || !QUERY_FLAG(op, FLAG_IS_MAGICAL)) {
108  if (victim->type == PLAYER) {
109  victim->speed_left = -FABS(victim->speed);
110  /* Clear player's path; they probably can't move there
111  * any more after being pushed, or might not want to. */
112  player_path_clear(CONTR(victim));
113  }
114 
115  OBJECTS_DESTROYED_BEGIN(victim) {
116  move_object(victim, dir);
117 
118  if (OBJECTS_DESTROYED(victim)) {
119  return;
120  }
122  }
123 
124  if (op->stats.maxsp == 0 && op->stats.sp) {
125  op->stats.maxsp = 2;
126  }
127 
128  /* Flag to paralyze the player. */
129  if (op->stats.sp != 0) {
130  victim->speed_left = -(op->stats.maxsp * FABS(victim->speed));
131  }
132 }
133 
135 static void process_func(object *op)
136 {
137  HARD_ASSERT(op != NULL);
138 
139  op->value = pticks;
140 
141  if (!(GET_MAP_FLAGS(op->map, op->x, op->y) & (P_IS_MONSTER |
142  P_IS_PLAYER))) {
143  return;
144  }
145 
146  FOR_MAP_PREPARE(op->map, op->x, op->y, victim) {
147  player_mover_handle(op, victim, true);
148  } FOR_MAP_FINISH();
149 }
150 
152 static int
153 move_on_func (object *op, object *victim, object *originator, int state)
154 {
155  HARD_ASSERT(op != NULL);
156  HARD_ASSERT(victim != NULL);
157 
158  player_mover_handle(op, victim, false);
159  return OBJECT_METHOD_OK;
160 }
161 
166 {
167  OBJECT_METHODS(PLAYER_MOVER)->process_func = process_func;
168  OBJECT_METHODS(PLAYER_MOVER)->move_on_func = move_on_func;
169 }
OBJECT_TYPE_INIT_DEFINE(player_mover)
Definition: player_mover.c:165
double speed_left
Definition: object.h:472
mapstruct * get_map_from_coord(mapstruct *m, int *x, int *y)
Definition: map.c:1869
int blocked(object *op, mapstruct *m, int x, int y, int terrain)
Definition: map.c:598
void object_destruct(object *op)
Definition: object.c:1521
#define IS_LIVE(op)
Definition: define.h:841
#define PLAYER
Definition: define.h:122
int16_t sp
Definition: living.h:78
#define OBJECTS_DESTROYED_BEGIN(...)
Definition: object.h:765
#define QUERY_FLAG(xyz, p)
Definition: define.h:761
#define FLAG_STAND_STILL
Definition: define.h:1133
int16_t maxsp
Definition: living.h:81
int32_t hp
Definition: living.h:72
#define LAYER_SYS
Definition: map.h:47
int16_t y
Definition: object.h:276
int32_t maxhp
Definition: living.h:75
#define FLAG_LIFESAVE
Definition: define.h:1125
#define P_IS_PLAYER
Definition: map.h:256
int8_t direction
Definition: object.h:350
struct mapdef * map
Definition: object.h:139
#define PLAYER_MOVER
Definition: define.h:238
#define move_object(__op, __dir)
Definition: global.h:253
#define OBJECTS_DESTROYED(obj)
Definition: object.h:811
#define FLAG_FLYING
Definition: define.h:918
#define FOR_MAP_LAYER_END
Definition: define.h:1657
double speed
Definition: object.h:469
#define FOR_MAP_FINISH()
Definition: define.h:1759
void player_path_clear(player *pl)
Definition: player.c:1086
int16_t x
Definition: object.h:273
#define FOR_MAP_LAYER_BEGIN(_m, _x, _y, _layer, _sub_layer, _obj)
Definition: define.h:1630
#define OBJECTS_DESTROYED_END()
Definition: object.h:816
#define FLAG_XRAYS
Definition: define.h:1110
static void process_func(object *op)
Definition: player_mover.c:135
living stats
Definition: object.h:481
int get_random_dir(void)
Definition: move.c:41
int freearr_x[SIZEOFFREE]
Definition: object.c:84
uint8_t type
Definition: object.h:360
#define OBJECT_METHODS(type)
uint16_t terrain_flag
Definition: object.h:301
#define OBJECT_METHOD_OK
#define FLAG_IS_MAGICAL
Definition: define.h:1129
#define P_IS_MONSTER
Definition: map.h:258
static int move_on_func(object *op, object *victim, object *originator, int state)
Definition: player_mover.c:153
Definition: map.h:536
int8_t level
Definition: object.h:347
int freearr_y[SIZEOFFREE]
Definition: object.c:99
static void player_mover_handle(object *op, object *victim, bool process)
Definition: player_mover.c:47
int64_t value
Definition: object.h:240
#define FOR_MAP_PREPARE(map_, mx_, my_, it_)
Definition: define.h:1752