Crossfire Server  1.75.0
player.cpp
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 
33 void clear_player(player *pl) {
34  client_spell *info;
35  client_spell *next;
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  }
55  pl->delayed_buffers_used = 0;
56  if (pl->last_exit != NULL) {
58  pl->last_exit = NULL;
59  }
61 }
62 
69 void free_player(player *pl) {
70  if (first_player != pl) {
71  player *prev = first_player;
72 
73  while (prev != NULL && prev->next != NULL && prev->next != pl)
74  prev = prev->next;
75  if (!prev || prev->next != pl) {
76  LOG(llevError, "Free_player: Can't find previous player.\n");
77  exit(1);
78  }
79  prev->next = pl->next;
80  } else
81  first_player = pl->next;
82 
83  if (pl->ob != NULL) {
84  if (!QUERY_FLAG(pl->ob, FLAG_REMOVED))
85  object_remove(pl->ob);
87  }
88 
89  clear_player(pl);
90  free(pl);
91 }
92 
104 int atnr_is_dragon_enabled(int attacknr) {
105  if (attacknr == ATNR_MAGIC
106  || attacknr == ATNR_FIRE
107  || attacknr == ATNR_ELECTRICITY
108  || attacknr == ATNR_COLD
109  || attacknr == ATNR_ACID
110  || attacknr == ATNR_POISON)
111  return 1;
112  return 0;
113 }
114 
123 int is_dragon_pl(const object *op) {
124  if (op != NULL
125  && op->type == PLAYER
126  && op->arch != NULL
127  && op->arch->clone.race != NULL
128  && strcmp(op->arch->clone.race, "dragon") == 0)
129  return 1;
130  return 0;
131 }
132 
146  client_spell *info = pl->spell_state;
147 
148  while (info) {
149  if (info->spell == spell)
150  return info;
151  info = info->next;
152  }
153  /*
154  * Why take the time to malloc() and then memset()?
155  * Just calloc and its good to go!
156  */
157  info = (client_spell *)calloc(1, sizeof(client_spell));
158  if (info == NULL)
160  info->next = pl->spell_state;
161  info->spell = spell;
162  pl->spell_state = info;
163  return info;
164 }
165 
174 int is_wraith_pl(object *op) {
175  return op != NULL && op->type == PLAYER && op->arch != NULL && op->contr && op->contr->is_wraith;
176 }
177 
186 int is_old_wraith_pl(object *op) {
187  return op != NULL && op->type == PLAYER && op->arch != NULL && op->contr && op->contr->is_old_wraith && !is_wraith_pl(op);
188 }
189 
203 void player_set_dragon_title(player *pl, int level, const char *attack, int skin_resist) {
204  if (level == 0)
205  snprintf(pl->title, sizeof(pl->title), "%s hatchling", attack);
206  else if (level == 1)
207  snprintf(pl->title, sizeof(pl->title), "%s wyrm", attack);
208  else if (level == 2)
209  snprintf(pl->title, sizeof(pl->title), "%s wyvern", attack);
210  else if (level == 3)
211  snprintf(pl->title, sizeof(pl->title), "%s dragon", attack);
212  /* special titles for extra high resistance! */
213  else if (skin_resist > 80)
214  snprintf(pl->title, sizeof(pl->title), "legendary %s dragon", attack);
215  else if (skin_resist > 50)
216  snprintf(pl->title, sizeof(pl->title), "ancient %s dragon", attack);
217  else
218  snprintf(pl->title, sizeof(pl->title), "big %s dragon", attack);
219  pl->own_title[0] = '\0';
220 }
221 
233 void player_get_title(const player *pl, char *buf, size_t bufsize) {
234  if (pl->own_title[0] == '\0')
235  snprintf(buf, bufsize, "the %s", pl->title);
236  else
237  strlcpy(buf, pl->own_title, bufsize);
238 }
239 
248 int player_has_own_title(const struct player *pl) {
249  return pl->own_title[0] != '\0';
250 }
251 
261 const char *player_get_own_title(const struct player *pl) {
262  return pl->own_title;
263 }
264 
273 void player_set_own_title(struct player *pl, const char *title) {
274  strlcpy(pl->own_title, title, sizeof(pl->own_title));
276 }
277 
288 void link_player_skills(object *op) {
289  int skill;
290  FOR_INV_PREPARE(op, tmp) {
291  if (tmp->type == SKILL) {
292  for (skill = 0; skill < MAX_SKILLS; skill++) {
293  if (op->contr->last_skill_ob[skill] == NULL) {
294  /* Didn't find the skill, so add it */
295  op->contr->last_skill_ob[skill] = tmp;
296  op->contr->last_skill_exp[skill] = -1;
297  break;
298  }
299  if (op->contr->last_skill_ob[skill] == tmp) {
300  /* Skill already linked, nothing to do */
301  break;
302  }
303  }
304  }
305  } FOR_INV_FINISH();
306 }
307 
308 void commit_crime(object *op, const char *description) {
309  object *force = add_force(op, "criminal", 25); // 5 minutes
310  object_set_msg(force, description);
311 }
312 
313 bool is_criminal(object *op) {
314  return find_force(op, "criminal");
315 }
316 
321  if (pl->repeat_func == NULL)
322  return;
323 
324  char buf[MAX_BUF];
325  snprintf(buf, sizeof(buf), "You stop %s.", pl->repeat_action);
327  pl->repeat_func = NULL;
328  if (pl->repeat_action) {
330  pl->repeat_action = NULL;
331  }
332  if (pl->repeat_func_data != NULL) {
333  free(pl->repeat_func_data);
334  pl->repeat_func_data = NULL;
335  }
336 }
Error, serious thing.
Definition: logger.h:11
uint8_t delayed_buffers_allocated
Number of items in delayed_buffers_used.
Definition: player.h:226
int stack_position
Current stack position, 0 for no item.
Definition: player.h:221
#define ATNR_ELECTRICITY
Definition: attack.h:50
struct archetype * arch
Pointer to archetype.
Definition: object.h:424
void LOG(LogLevel logLevel, const char *format,...)
Logs a message to stderr, or to file.
Definition: logger.cpp:58
#define ATNR_FIRE
Definition: attack.h:49
void player_set_own_title(struct player *pl, const char *title)
Sets the custom title.
Definition: player.cpp:273
#define ATNR_ACID
Definition: attack.h:53
void player_set_dragon_title(player *pl, int level, const char *attack, int skin_resist)
Updates the title of a dragon player to reflect the current level, attack type, and resistances...
Definition: player.cpp:203
void object_set_msg(object *op, const char *msg)
Set the message field of an object.
Definition: object.cpp:4796
void object_remove(object *op)
This function removes the object op from the linked list of objects which it is currently tied to...
Definition: object.cpp:1818
object * spell
Spell object this structure is about.
Definition: player.h:88
player * first_player
First player.
Definition: init.cpp:106
int level
Definition: readable.cpp:1561
void link_player_skills(object *op)
This function goes through the player inventory and sets up the last_skills[] array in the player obj...
Definition: player.cpp:288
int is_dragon_pl(const object *op)
Checks if player is a dragon.
Definition: player.cpp:123
#define FREE_OBJ_NO_DESTROY_CALLBACK
Do not run the destroy callback.
Definition: object.h:547
This stores, for a spell a player knows, the last sp/gr/dam information sent to client.
Definition: player.h:87
int player_has_own_title(const struct player *pl)
Returns whether the player has a custom title.
Definition: player.cpp:248
char title[BIG_NAME]
Default title, like fighter, wizard, etc.
Definition: player.h:186
Global type definitions and header inclusions.
object * last_exit
Last exit used by player or NULL.
Definition: player.h:210
struct player * contr
Pointer to the player which control this object.
Definition: object.h:284
client_spell * spell_state
Spell information sent to client.
Definition: player.h:217
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *message)
Sends message to player(s).
Definition: main.cpp:308
#define FLAG_REMOVED
Object is not in any map or invenory.
Definition: define.h:219
repeat_cb repeat_func
If not NULL, automatically repeat the action repeat_func until interrupted.
Definition: player.h:231
void free_string(sstring str)
This will reduce the refcount, and if it has reached 0, str will be freed.
Definition: shstr.cpp:294
int is_old_wraith_pl(object *op)
Checks if player is a wraith without the &#39;wraith feed&#39; skill.
Definition: player.cpp:186
void object_free(object *ob, int flags)
Frees everything allocated by an object, removes it from the list of used objects, and puts it on the list of free objects.
Definition: object.cpp:1577
player * next
Pointer to next player, NULL if this is last.
Definition: player.h:108
#define MSG_TYPE_COMMAND
Responses to commands, eg, who.
Definition: newclient.h:420
tag_t * stack_items
Item stack for patch/dump/...
Definition: player.h:219
#define ATNR_COLD
Definition: attack.h:51
sstring repeat_action
Shared string with textual description of current repeat action (e.g.
Definition: player.h:232
#define QUERY_FLAG(xyz, p)
Definition: define.h:386
Information on one title.
Definition: readable.cpp:108
void player_get_title(const player *pl, char *buf, size_t bufsize)
Returns the player&#39;s title.
Definition: player.cpp:233
void object_free_drop_inventory(object *ob)
Frees everything allocated by an object, removes it from the list of used objects, and puts it on the list of free objects.
Definition: object.cpp:1545
#define FOR_INV_FINISH()
Finishes FOR_INV_PREPARE().
Definition: define.h:700
client_spell * get_client_spell_state(player *pl, object *spell)
Gets the (client-side) spell state for specified spell.
Definition: player.cpp:145
sstring race
Human, goblin, dragon, etc.
Definition: object.h:326
int atnr_is_dragon_enabled(int attacknr)
Determine if the attacktype represented by the specified attack-number is enabled for dragon players...
Definition: player.cpp:104
object * ob
The object representing the player.
Definition: player.h:179
const char * player_get_own_title(const struct player *pl)
Returns the player&#39;s own title.
Definition: player.cpp:261
object * find_force(object *op, const char *name)
Find a force with the given &#39;name&#39; in the slaying field.
Definition: object.cpp:5410
void free_player(player *pl)
Frees player structure, including pointed object (through object_free_drop_inventory()).
Definition: player.cpp:69
object * add_force(object *op, const char *name, int duration)
Add or return an existing force inside &#39;op&#39; with the given &#39;name&#39; and &#39;duration&#39; in units of 100 tick...
Definition: object.cpp:5415
#define FREE_AND_CLEAR_STR(xyz)
Release the shared string, and set it to NULL.
Definition: global.h:200
void fatal(enum fatal_error err)
fatal() is meant to be called whenever a fatal signal is intercepted.
Definition: utils.cpp:590
#define MAX_BUF
Used for all kinds of things.
Definition: define.h:35
void replace_unprintable_chars(char *buf)
Replaces any unprintable character in the given buffer with a space.
Definition: utils.cpp:447
#define ATNR_POISON
Definition: attack.h:57
int64_t last_skill_exp[MAX_SKILLS]
Last exp sent to client.
Definition: player.h:156
size_t strlcpy(char *dst, const char *src, size_t size)
Portable implementation of strlcpy(3).
Definition: porting.cpp:222
See Player.
Definition: object.h:112
struct client_spell * next
Next spell information.
Definition: player.h:92
bool is_old_wraith
Whether this player is a "old" wraith, initialized at load time and updated when eating.
Definition: player.h:230
Also see SKILL_TOOL (74) below.
Definition: object.h:148
object * last_skill_ob[MAX_SKILLS]
Exp objects sent to client.
Definition: player.h:155
#define MSG_TYPE_COMMAND_INFO
Generic info: resistances, etc.
Definition: newclient.h:547
uint8_t type
PLAYER, BULLET, etc.
Definition: object.h:348
uint8_t delayed_buffers_used
Used items in delayed_buffers_used.
Definition: player.h:227
#define ATNR_MAGIC
Definition: attack.h:48
SockList ** delayed_buffers
Buffers which will be sent after the player&#39;s tick completes.
Definition: player.h:228
#define NDI_UNIQUE
Print immediately, don&#39;t buffer.
Definition: newclient.h:270
int is_wraith_pl(object *op)
Tests if a player is a wraith.
Definition: player.cpp:174
One player.
Definition: player.h:107
bool is_criminal(object *op)
Definition: player.cpp:313
void commit_crime(object *op, const char *description)
Definition: player.cpp:308
StringBuffer * buf
Definition: readable.cpp:1563
char own_title[MAX_NAME]
Title the player has chosen for themself.
Definition: player.h:184
void clear_player(player *pl)
Clears data in player structure.
Definition: player.cpp:33
const char * unarmed_skill
Prefered skill to use in unarmed combat.
Definition: player.h:223
#define MAX_SKILLS
This is the maximum number of skills the game may handle.
Definition: skills.h:70
void player_cancel_repeat(player *pl)
If the player is repeating an action, cancel it.
Definition: player.cpp:320
#define FREE_AND_CLEAR(xyz)
Free the pointer and then set it to NULL.
Definition: global.h:195
bool is_wraith
Whether this player is a wraith or not, initialized at load time.
Definition: player.h:229
object clone
An object from which to do object_copy()
Definition: object.h:487
#define FOR_INV_PREPARE(op_, it_)
Constructs a loop iterating over the inventory of an object.
Definition: define.h:693
void * repeat_func_data
Arguments to pass into repeat_func.
Definition: player.h:233