Crossfire Server, Trunk  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 }
player::stack_items
tag_t * stack_items
Item stack for patch/dump/...
Definition: player.h:219
PLAYER
@ PLAYER
Definition: object.h:112
player::next
player * next
Pointer to next player, NULL if this is last.
Definition: player.h:108
global.h
first_player
player * first_player
First player.
Definition: init.cpp:106
player::unarmed_skill
const char * unarmed_skill
Prefered skill to use in unarmed combat.
Definition: player.h:223
llevError
@ llevError
Error, serious thing.
Definition: logger.h:11
LOG
void LOG(LogLevel logLevel, const char *format,...)
Logs a message to stderr, or to file.
Definition: logger.cpp:58
client_spell
This stores, for a spell a player knows, the last sp/gr/dam information sent to client.
Definition: player.h:87
player
One player.
Definition: player.h:107
ATNR_ACID
#define ATNR_ACID
Definition: attack.h:53
QUERY_FLAG
#define QUERY_FLAG(xyz, p)
Definition: define.h:371
player::is_wraith
bool is_wraith
Whether this player is a wraith or not, initialized at load time.
Definition: player.h:229
player::spell_state
client_spell * spell_state
Spell information sent to client.
Definition: player.h:217
object::arch
struct archetype * arch
Pointer to archetype.
Definition: object.h:424
client_spell::next
struct client_spell * next
Next spell information.
Definition: player.h:92
player::ob
object * ob
The object representing the player.
Definition: player.h:179
player_set_own_title
void player_set_own_title(struct player *pl, const char *title)
Sets the custom title.
Definition: player.cpp:273
player::delayed_buffers
SockList ** delayed_buffers
Buffers which will be sent after the player's tick completes.
Definition: player.h:228
SKILL
@ SKILL
Also see SKILL_TOOL (74) below.
Definition: object.h:148
player_has_own_title
int player_has_own_title(const struct player *pl)
Returns whether the player has a custom title.
Definition: player.cpp:248
buf
StringBuffer * buf
Definition: readable.cpp:1565
MSG_TYPE_COMMAND
#define MSG_TYPE_COMMAND
Responses to commands, eg, who.
Definition: newclient.h:408
FLAG_REMOVED
#define FLAG_REMOVED
Object is not in any map or invenory.
Definition: define.h:219
draw_ext_info
vs only yadda is in because all tags get reset on the next draw_ext_info In the second since it is all in one draw_ext_info
Definition: media-tags.txt:61
object_free_drop_inventory
void object_free_drop_inventory(object *ob)
Frees everything allocated by an object, removes it from the list of used objects,...
Definition: object.cpp:1545
object::contr
struct player * contr
Pointer to the player which control this object.
Definition: object.h:284
is_criminal
bool is_criminal(object *op)
Definition: player.cpp:313
FREE_OBJ_NO_DESTROY_CALLBACK
#define FREE_OBJ_NO_DESTROY_CALLBACK
Do not run the destroy callback.
Definition: object.h:545
archetype::clone
object clone
An object from which to do object_copy()
Definition: object.h:487
MSG_TYPE_COMMAND_INFO
#define MSG_TYPE_COMMAND_INFO
Generic info: resistances, etc.
Definition: newclient.h:530
player::delayed_buffers_used
uint8_t delayed_buffers_used
Used items in delayed_buffers_used.
Definition: player.h:227
commit_crime
void commit_crime(object *op, const char *description)
Definition: player.cpp:308
player::last_skill_exp
int64_t last_skill_exp[MAX_SKILLS]
Last exp sent to client.
Definition: player.h:156
client_spell::spell
object * spell
Spell object this structure is about.
Definition: player.h:88
description
spell prayer lvl t sp speed range duration short description
Definition: spell-summary.txt:2
object::type
uint8_t type
PLAYER, BULLET, etc.
Definition: object.h:348
spell
with a maximum of six This is not so if you are wearing plate you receive no benefit Armour is additive with all the supplementry forms of which means that it lasts until the next semi permanent spell effect is cast upon the character spell
Definition: tome-of-magic.txt:44
object_free
void object_free(object *ob, int flags)
Frees everything allocated by an object, removes it from the list of used objects,...
Definition: object.cpp:1577
title
Information on one title.
Definition: readable.cpp:108
player_cancel_repeat
void player_cancel_repeat(player *pl)
If the player is repeating an action, cancel it.
Definition: player.cpp:320
FOR_INV_FINISH
#define FOR_INV_FINISH()
Finishes FOR_INV_PREPARE().
Definition: define.h:661
ATNR_POISON
#define ATNR_POISON
Definition: attack.h:57
MAX_SKILLS
#define MAX_SKILLS
This is the maximum number of skills the game may handle.
Definition: skills.h:70
object::race
sstring race
Human, goblin, dragon, etc.
Definition: object.h:326
replace_unprintable_chars
void replace_unprintable_chars(char *buf)
Replaces any unprintable character in the given buffer with a space.
Definition: utils.cpp:447
fatal
void fatal(enum fatal_error err)
fatal() is meant to be called whenever a fatal signal is intercepted.
Definition: utils.cpp:590
player::last_skill_ob
object * last_skill_ob[MAX_SKILLS]
Exp objects sent to client.
Definition: player.h:155
MAX_BUF
#define MAX_BUF
Used for all kinds of things.
Definition: define.h:35
strlcpy
size_t strlcpy(char *dst, const char *src, size_t size)
Portable implementation of strlcpy(3).
Definition: porting.cpp:222
is_wraith_pl
int is_wraith_pl(object *op)
Tests if a player is a wraith.
Definition: player.cpp:174
free_string
void free_string(sstring str)
This will reduce the refcount, and if it has reached 0, str will be freed.
Definition: shstr.cpp:294
FREE_AND_CLEAR_STR
#define FREE_AND_CLEAR_STR(xyz)
Release the shared string, and set it to NULL.
Definition: global.h:200
ATNR_FIRE
#define ATNR_FIRE
Definition: attack.h:49
NDI_UNIQUE
#define NDI_UNIQUE
Print immediately, don't buffer.
Definition: newclient.h:266
get_client_spell_state
client_spell * get_client_spell_state(player *pl, object *spell)
Gets the (client-side) spell state for specified spell.
Definition: player.cpp:145
FREE_AND_CLEAR
#define FREE_AND_CLEAR(xyz)
Free the pointer and then set it to NULL.
Definition: global.h:195
is_dragon_pl
int is_dragon_pl(const object *op)
Checks if player is a dragon.
Definition: player.cpp:123
player::is_old_wraith
bool is_old_wraith
Whether this player is a "old" wraith, initialized at load time and updated when eating.
Definition: player.h:230
player::own_title
char own_title[MAX_NAME]
Title the player has chosen for themself.
Definition: player.h:184
object_set_msg
void object_set_msg(object *op, const char *msg)
Set the message field of an object.
Definition: object.cpp:4796
ATNR_MAGIC
#define ATNR_MAGIC
Definition: attack.h:48
add_force
object * add_force(object *op, const char *name, int duration)
Add or return an existing force inside 'op' with the given 'name' and 'duration' in units of 100 tick...
Definition: object.cpp:5415
atnr_is_dragon_enabled
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
level
int level
Definition: readable.cpp:1563
find_force
object * find_force(object *op, const char *name)
Find a force with the given 'name' in the slaying field.
Definition: object.cpp:5410
player::repeat_func_data
void * repeat_func_data
Arguments to pass into repeat_func.
Definition: player.h:233
player::repeat_action
sstring repeat_action
Shared string with textual description of current repeat action (e.g.
Definition: player.h:232
player_set_dragon_title
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
skill
skill
Definition: arch-handbook.txt:585
player::delayed_buffers_allocated
uint8_t delayed_buffers_allocated
Number of items in delayed_buffers_used.
Definition: player.h:226
object_remove
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
ATNR_COLD
#define ATNR_COLD
Definition: attack.h:51
player::stack_position
int stack_position
Current stack position, 0 for no item.
Definition: player.h:221
is_old_wraith_pl
int is_old_wraith_pl(object *op)
Checks if player is a wraith without the 'wraith feed' skill.
Definition: player.cpp:186
player::title
char title[BIG_NAME]
Default title, like fighter, wizard, etc.
Definition: player.h:186
player_get_own_title
const char * player_get_own_title(const struct player *pl)
Returns the player's own title.
Definition: player.cpp:261
player::last_exit
object * last_exit
Last exit used by player or NULL.
Definition: player.h:210
ATNR_ELECTRICITY
#define ATNR_ELECTRICITY
Definition: attack.h:50
clear_player
void clear_player(player *pl)
Clears data in player structure.
Definition: player.cpp:33
player::repeat_func
repeat_cb repeat_func
If not NULL, automatically repeat the action repeat_func until interrupted.
Definition: player.h:231
link_player_skills
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
OUT_OF_MEMORY
@ OUT_OF_MEMORY
Definition: define.h:48
FOR_INV_PREPARE
#define FOR_INV_PREPARE(op_, it_)
Constructs a loop iterating over the inventory of an object.
Definition: define.h:654
free_player
void free_player(player *pl)
Frees player structure, including pointed object (through object_free_drop_inventory()).
Definition: player.cpp:69
player_get_title
void player_get_title(const player *pl, char *buf, size_t bufsize)
Returns the player's title.
Definition: player.cpp:233