Crossfire Server, Trunk
player.c
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 1999-2014 Mark Wedel and the Crossfire Development Team
5  * Copyright (c) 1992 Frank Tore Johansen
6  *
7  * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
8  * welcome to redistribute it under certain conditions. For details, please
9  * see COPYING and LICENSE.
10  *
11  * The authors can be reached via e-mail at <crossfire@metalforge.org>.
12  */
13 
19 #include "global.h"
20 
21 #include <stdlib.h>
22 #include <string.h>
23 
34  client_spell *info;
36 
37  /* Clear item stack (used by DMs only) */
38  free(pl->stack_items);
39  pl->stack_position = 0;
40 
41  info = pl->spell_state;
42  while (info) {
43  next = info->next;
44  free(info);
45  info = next;
46  }
47  if (pl->unarmed_skill)
49 
50  for (uint8_t db = 0; db < pl->delayed_buffers_allocated; db++) {
51  free(pl->delayed_buffers[db]);
52  }
56  if (pl->last_exit != NULL) {
58  pl->last_exit = NULL;
59  }
60 }
61 
69  if (first_player != pl) {
70  player *prev = first_player;
71 
72  while (prev != NULL && prev->next != NULL && prev->next != pl)
73  prev = prev->next;
74  if (!prev || prev->next != pl) {
75  LOG(llevError, "Free_player: Can't find previous player.\n");
76  exit(1);
77  }
78  prev->next = pl->next;
79  } else
80  first_player = pl->next;
81 
82  if (pl->ob != NULL) {
83  if (!QUERY_FLAG(pl->ob, FLAG_REMOVED))
86  }
87 
89  free(pl);
90 }
91 
103 int atnr_is_dragon_enabled(int attacknr) {
104  if (attacknr == ATNR_MAGIC
105  || attacknr == ATNR_FIRE
106  || attacknr == ATNR_ELECTRICITY
107  || attacknr == ATNR_COLD
108  || attacknr == ATNR_ACID
109  || attacknr == ATNR_POISON)
110  return 1;
111  return 0;
112 }
113 
122 int is_dragon_pl(const object *op) {
123  if (op != NULL
124  && op->type == PLAYER
125  && op->arch != NULL
126  && op->arch->clone.race != NULL
127  && strcmp(op->arch->clone.race, "dragon") == 0)
128  return 1;
129  return 0;
130 }
131 
145  client_spell *info = pl->spell_state;
146 
147  while (info) {
148  if (info->spell == spell)
149  return info;
150  info = info->next;
151  }
152  /*
153  * Why take the time to malloc() and then memset()?
154  * Just calloc and its good to go!
155  */
156  info = (client_spell *)calloc(1, sizeof(client_spell));
157  if (info == NULL)
159  info->next = pl->spell_state;
160  info->spell = spell;
161  pl->spell_state = info;
162  return info;
163 }
164 
173 int is_wraith_pl(object *op) {
174  return op != NULL && op->type == PLAYER && op->arch != NULL && object_find_by_name(op, "wraith feed") != NULL;
175 }
176 
185 int is_old_wraith_pl(object *op) {
186  return op != NULL && op->type == PLAYER && op->arch != NULL && object_find_by_name(op, "Wraith_Force") != NULL && !is_wraith_pl(op);
187 }
188 
202 void player_set_dragon_title(struct pl *pl, int level, const char *attack, int skin_resist) {
203  if (level == 0)
204  snprintf(pl->title, sizeof(pl->title), "%s hatchling", attack);
205  else if (level == 1)
206  snprintf(pl->title, sizeof(pl->title), "%s wyrm", attack);
207  else if (level == 2)
208  snprintf(pl->title, sizeof(pl->title), "%s wyvern", attack);
209  else if (level == 3)
210  snprintf(pl->title, sizeof(pl->title), "%s dragon", attack);
211  /* special titles for extra high resistance! */
212  else if (skin_resist > 80)
213  snprintf(pl->title, sizeof(pl->title), "legendary %s dragon", attack);
214  else if (skin_resist > 50)
215  snprintf(pl->title, sizeof(pl->title), "ancient %s dragon", attack);
216  else
217  snprintf(pl->title, sizeof(pl->title), "big %s dragon", attack);
218  pl->own_title[0] = '\0';
219 }
220 
232 void player_get_title(const struct pl *pl, char *buf, size_t bufsize) {
233  if (pl->own_title[0] == '\0')
234  snprintf(buf, bufsize, "the %s", pl->title);
235  else
236  strlcpy(buf, pl->own_title, bufsize);
237 }
238 
247 int player_has_own_title(const struct pl *pl) {
248  return pl->own_title[0] != '\0';
249 }
250 
260 const char *player_get_own_title(const struct pl *pl) {
261  return pl->own_title;
262 }
263 
272 void player_set_own_title(struct pl *pl, const char *title) {
273  strlcpy(pl->own_title, title, sizeof(pl->own_title));
275 }
276 
287 void link_player_skills(object *op) {
288  int skill;
290  if (tmp->type == SKILL) {
291  for (skill = 0; skill < MAX_SKILLS; skill++) {
292  if (op->contr->last_skill_ob[skill] == NULL) {
293  /* Didn't find the skill, so add it */
294  op->contr->last_skill_ob[skill] = tmp;
295  op->contr->last_skill_exp[skill] = -1;
296  break;
297  }
298  if (op->contr->last_skill_ob[skill] == tmp) {
299  /* Skill already linked, nothing to do */
300  break;
301  }
302  }
303  }
304  } FOR_INV_FINISH();
305 }
306 
307 void commit_crime(object *op, const char *description) {
308  object *force = add_force(op, "criminal", 25); // 5 minutes
309  object_set_msg(force, description);
310 }
311 
312 bool is_criminal(object *op) {
313  return find_force(op, "criminal");
314 }
commit_crime
void commit_crime(object *op, const char *description)
Definition: player.c:307
give.next
def next
Definition: give.py:44
pl::delayed_buffers
SockList ** delayed_buffers
Definition: player.h:225
PLAYER
@ PLAYER
Definition: object.h:107
global.h
FREE_OBJ_NO_DESTROY_CALLBACK
#define FREE_OBJ_NO_DESTROY_CALLBACK
Definition: object.h:531
object_free
void object_free(object *ob, int flags)
Definition: object.c:1578
object_remove
void object_remove(object *op)
Definition: object.c:1819
llevError
@ llevError
Definition: logger.h:11
client_spell
Definition: player.h:87
ATNR_ACID
#define ATNR_ACID
Definition: attack.h:55
QUERY_FLAG
#define QUERY_FLAG(xyz, p)
Definition: define.h:226
client_spell::next
struct client_spell * next
Definition: player.h:92
player_has_own_title
int player_has_own_title(const struct pl *pl)
Definition: player.c:247
pl
Definition: player.h:105
pl::ob
object * ob
Definition: player.h:176
SKILL
@ SKILL
Definition: object.h:143
pl::delayed_buffers_used
uint8_t delayed_buffers_used
Definition: player.h:224
Ice.tmp
int tmp
Definition: Ice.py:207
player_set_own_title
void player_set_own_title(struct pl *pl, const char *title)
Definition: player.c:272
find_force
object * find_force(object *op, const char *name)
Definition: object.c:5391
is_old_wraith_pl
int is_old_wraith_pl(object *op)
Definition: player.c:185
pl::next
struct pl * next
Definition: player.h:106
link_player_skills
void link_player_skills(object *op)
Definition: player.c:287
titlestruct
Definition: readable.c:107
pl::unarmed_skill
const char * unarmed_skill
Definition: player.h:220
fatal
void fatal(enum fatal_error err)
Definition: utils.c:580
client_spell::spell
object * spell
Definition: player.h:88
first_player
EXTERN player * first_player
Definition: global.h:115
FOR_INV_FINISH
#define FOR_INV_FINISH()
Definition: define.h:677
clear_player
void clear_player(player *pl)
Definition: player.c:33
is_criminal
bool is_criminal(object *op)
Definition: player.c:312
ATNR_POISON
#define ATNR_POISON
Definition: attack.h:59
replace_unprintable_chars
void replace_unprintable_chars(char *buf)
Definition: utils.c:457
MAX_SKILLS
#define MAX_SKILLS
Definition: skills.h:70
player_get_own_title
const char * player_get_own_title(const struct pl *pl)
Definition: player.c:260
get_client_spell_state
client_spell * get_client_spell_state(player *pl, object *spell)
Definition: player.c:144
is_dragon_pl
int is_dragon_pl(const object *op)
Definition: player.c:122
strlcpy
size_t strlcpy(char *dst, const char *src, size_t size)
Definition: porting.c:220
FREE_AND_CLEAR_STR
#define FREE_AND_CLEAR_STR(xyz)
Definition: global.h:195
ATNR_FIRE
#define ATNR_FIRE
Definition: attack.h:51
pl::spell_state
client_spell * spell_state
Definition: player.h:214
is_wraith_pl
int is_wraith_pl(object *op)
Definition: player.c:173
object_set_msg
void object_set_msg(object *op, const char *msg)
Definition: object.c:4781
FLAG_REMOVED
#define FLAG_REMOVED
Definition: define.h:232
FREE_AND_CLEAR
#define FREE_AND_CLEAR(xyz)
Definition: global.h:190
LOG
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.c:51
pl::delayed_buffers_allocated
uint8_t delayed_buffers_allocated
Definition: player.h:223
give.op
op
Definition: give.py:33
ATNR_MAGIC
#define ATNR_MAGIC
Definition: attack.h:50
pl::stack_position
int stack_position
Definition: player.h:218
buf
StringBuffer * buf
Definition: readable.c:1610
pl::own_title
char own_title[MAX_NAME]
Definition: player.h:181
object_free_drop_inventory
void object_free_drop_inventory(object *ob)
Definition: object.c:1546
pl::last_exit
struct obj * last_exit
Definition: player.h:207
free_player
void free_player(player *pl)
Definition: player.c:68
object_find_by_name
object * object_find_by_name(const object *who, const char *name)
Definition: object.c:3927
add_force
object * add_force(object *op, const char *name, int duration)
Definition: object.c:5396
ATNR_COLD
#define ATNR_COLD
Definition: attack.h:53
atnr_is_dragon_enabled
int atnr_is_dragon_enabled(int attacknr)
Definition: player.c:103
pl::stack_items
tag_t * stack_items
Definition: player.h:216
player_set_dragon_title
void player_set_dragon_title(struct pl *pl, int level, const char *attack, int skin_resist)
Definition: player.c:202
ATNR_ELECTRICITY
#define ATNR_ELECTRICITY
Definition: attack.h:52
player_get_title
void player_get_title(const struct pl *pl, char *buf, size_t bufsize)
Definition: player.c:232
OUT_OF_MEMORY
@ OUT_OF_MEMORY
Definition: define.h:48
FOR_INV_PREPARE
#define FOR_INV_PREPARE(op_, it_)
Definition: define.h:670
pl::title
char title[BIG_NAME]
Definition: player.h:183
dragon_attune.force
force
Definition: dragon_attune.py:45
level
Definition: level.py:1