/* * 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 /** * 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; }