server-1.12/common/player.c

202 lines
5.1 KiB
C

/*
* static char *rcsid_player_c =
* "$Id: player.c 11578 2009-02-23 22:02:27Z lalo $";
*/
/*
CrossFire, A Multiplayer game for X-windows
Copyright (C) 2002 Mark Wedel & Crossfire Development Team
Copyright (C) 1992 Frank Tore Johansen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
The authors can be reached via e-mail at crossfire-devel@real-time.com
*/
/**
* @file
* Player-structure related functions.
*/
#include <global.h>
/**
* Clears data in player structure.
*
* Socket isn't touched. Nor is anything that doesn't need to be freed. So you
* may need to do a memset() to clear out values.
*
* @param pl
* player to clear. Pointer is still valid, and can be reused for "play again".
*/
void clear_player(player *pl) {
client_spell *info;
client_spell *next;
/* Clear item stack (used by DMs only) */
if (pl->stack_items)
free(pl->stack_items);
pl->stack_position = 0;
info = pl->spell_state;
while (info) {
next = info->next;
free(info);
info = next;
}
}
/**
* Clears player structure, including pointed object (through free_object()).
*
* @param pl
* player to clear. Pointer is invalid after this call.
*/
void free_player(player *pl) {
if (first_player != pl) {
player *prev = first_player;
while (prev != NULL && prev->next != NULL && prev->next != pl)
prev = prev->next;
if (prev->next != pl) {
LOG(llevError, "Free_player: Can't find previous player.\n");
exit(1);
}
prev->next = pl->next;
} else
first_player = pl->next;
if (pl->ob != NULL) {
if (!QUERY_FLAG(pl->ob, FLAG_REMOVED))
remove_ob(pl->ob);
free_object(pl->ob);
}
clear_player(pl);
free(pl->socket.faces_sent);
CFREE(pl);
}
/**
* Determine if the attacktype represented by the
* specified attack-number is enabled for dragon players.
* A dragon player (quetzal) can gain resistances for
* all enabled attacktypes.
*
* @param attacknr
* attacktype to check
* @return
* TRUE if player can gain resistances in that, FALSE else.
*/
int atnr_is_dragon_enabled(int attacknr) {
if (attacknr == ATNR_MAGIC
|| attacknr == ATNR_FIRE
|| attacknr == ATNR_ELECTRICITY
|| attacknr == ATNR_COLD
|| attacknr == ATNR_ACID
|| attacknr == ATNR_POISON)
return 1;
return 0;
}
/**
* Checks if player is a dragon.
*
* @param op
* player to check. Can be NULL.
* @return
* TRUE if the adressed object 'ob' is a player of the dragon race.
*/
int is_dragon_pl(const object *op) {
if (op != NULL
&& op->type == PLAYER
&& op->arch != NULL
&& op->arch->clone.race != NULL
&& strcmp(op->arch->clone.race, "dragon") == 0)
return 1;
return 0;
}
/**
* Gets the (client-side) spell state for specified spell. Will be created to empty state if not found.
*
* @note
* will fatal() in case of memory allocation failure.
* @param pl
* player we're handling.
* @param spell
* spell for which to search data.
* @return
* state information for that spell.
*/
client_spell *get_client_spell_state(player *pl, object *spell) {
client_spell *info = pl->spell_state;
while (info) {
if (info->spell == spell)
return info;
info = info->next;
}
info = (client_spell *)malloc(sizeof(client_spell));
if (info == NULL)
fatal(OUT_OF_MEMORY);
memset(info, 0, sizeof(client_spell));
info->next = pl->spell_state;
info->spell = spell;
pl->spell_state = info;
return info;
}
/**
* Tests if a player is a wraith.
*
* @param op
* player to check.
* @return
* true if the adressed object 'ob' is a wraith player, false else.
*/
int is_wraith_pl(object *op) {
object *item = NULL;
if (op != NULL && op->type == PLAYER && op->arch != NULL)
for (item = op->inv; item != NULL && strcmp(item->name, "wraith feed"); item = item->below)
;
if (item)
return 1;
return 0;
}
/**
* Checks if player is a wraith without the 'wraith feed' skill.
*
* @param op
* player to check.
* @return
* true if the adressed object 'ob' is an old wraith player, false else.
*/
int is_old_wraith_pl(object *op) {
object *item = NULL;
if (op != NULL && op->type == PLAYER && op->arch != NULL)
for (item = op->inv; item != NULL && strcmp(item->name, "Wraith_Force"); item = item->below)
;
if (item)
return !is_wraith_pl(op);
return 0;
}