version 1.204 | | version 1.205 |
---|
| | |
/* | | /* |
* static char *rcsid_player_c = | | * static char *rcsid_player_c = |
* "$Id: player.c,v 1.204 2006/09/10 00:04:35 qal21 Exp $"; | | * "$Id: player.c,v 1.205 2006/09/10 14:55:05 qal21 Exp $"; |
*/ | | */ |
| | |
/* | | /* |
| | |
return 1; | | return 1; |
} | | } |
| | |
/** | | /* This no longer sets the player map. Also, it now updates |
* This no longer sets the player map. Also, it now updates | | |
* all the pointers so the caller doesn't need to do that. | | * all the pointers so the caller doesn't need to do that. |
* Caller is responsible for setting the correct map. | | * Caller is responsible for setting the correct map. |
* | | * |
| | |
} | | } |
| | |
| | |
/** This loads the first map an puts the player on it. */ | | /* This loads the first map an puts the player on it. */ |
static void set_first_map(object *op) | | static void set_first_map(object *op) |
{ | | { |
strcpy(op->contr->maplevel, first_map_path); | | strcpy(op->contr->maplevel, first_map_path); |
| | |
return 0; | | return 0; |
} | | } |
| | |
/** | | /* get_player_archetype() return next player archetype from archetype |
* get_player_archetype() return next player archetype from archetype | | |
* list. Not very efficient routine, but used only creating new players. | | * list. Not very efficient routine, but used only creating new players. |
* Note: there MUST be at least one player archetype! | | * Note: there MUST be at least one player archetype! |
*/ | | */ |
| | |
return op; | | return op; |
} | | } |
| | |
/** | | /* I believe this can safely go to 2, 3 is questionable, 4 will likely |
* I believe this can safely go to 2, 3 is questionable, 4 will likely | | |
* result in a monster paths backtracking. It basically determines how large a | | * result in a monster paths backtracking. It basically determines how large a |
* detour a monster will take from the direction path when looking | | * detour a monster will take from the direction path when looking |
* for a path to the player. The values are in the amount of direction | | * for a path to the player. The values are in the amount of direction |
| | |
*/ | | */ |
#define DETOUR_AMOUNT 2 | | #define DETOUR_AMOUNT 2 |
| | |
/** | | /* This is used to prevent infinite loops. Consider a case where the |
* This is used to prevent infinite loops. Consider a case where the | | |
* player is in a chamber (with gate closed), and monsters are outside. | | * player is in a chamber (with gate closed), and monsters are outside. |
* with DETOUR_AMOUNT==2, the function will turn each corner, trying to | | * with DETOUR_AMOUNT==2, the function will turn each corner, trying to |
* find a path into the chamber. This is a good thing, but since there | | * find a path into the chamber. This is a good thing, but since there |
| | |
#define MAX_SPACES 50 | | #define MAX_SPACES 50 |
| | |
| | |
/** | | /* Returns the direction to the player, if valid. Returns 0 otherwise. |
* Returns the direction to the player, if valid. Returns 0 otherwise. | | |
* modified to verify there is a path to the player. Does this by stepping towards | | * modified to verify there is a path to the player. Does this by stepping towards |
* player and if path is blocked then see if blockage is close enough to player that | | * player and if path is blocked then see if blockage is close enough to player that |
* direction to player is changed (ie zig or zag). Continue zig zag until either | | * direction to player is changed (ie zig or zag). Continue zig zag until either |
| | |
} | | } |
| | |
| | |
/** This rolls four 1-6 rolls and sums the best 3 of the 4. */ | | /* This rolls four 1-6 rolls and sums the best 3 of the 4. */ |
int roll_stat(void) { | | int roll_stat(void) { |
int a[4],i,j,k; | | int a[4],i,j,k; |
| | |
| | |
} | | } |
| | |
| | |
/** | | /* This code has been greatly reduced, because with set_attr_value |
* This code has been greatly reduced, because with set_attr_value | | |
* and get_attr_value, the stats can be accessed just numeric | | * and get_attr_value, the stats can be accessed just numeric |
* ids. stat_trans is a table that translate the number entered | | * ids. stat_trans is a table that translate the number entered |
* into the actual stat. It is needed because the order the stats | | * into the actual stat. It is needed because the order the stats |
| | |
} | | } |
| | |
| | |
/** | | /* check_pick sees if there is stuff to be picked up/picks up stuff. |
* check_pick sees if there is stuff to be picked up/picks up stuff. | | |
* IT returns 1 if the player should keep on moving, 0 if he should | | * IT returns 1 if the player should keep on moving, 0 if he should |
* stop. | | * stop. |
*/ | | */ |
| | |
| | |
if(op->contr->mode & PU_NOTHING) return 1; | | if(op->contr->mode & PU_NOTHING) return 1; |
| | |
/* if mode is set to stop when encountering objects, return */ | | /* if mode is set to stop when encountering objects, return. |
/* take STOP before INHIBIT since it doesn't actually pick | | * Take STOP before INHIBIT since it doesn't actually pick |
* anything up */ | | * anything up */ |
| | |
if(op->contr->mode & PU_STOP) return 0; | | if(op->contr->mode & PU_STOP) return 0; |
| | |
* pickups */ | | * pickups */ |
if(op->contr->mode & PU_RATIO) | | if(op->contr->mode & PU_RATIO) |
{ | | { |
/* use value density to decide what else to grab */ | | /* use value density to decide what else to grab. |
/* >=7 was >= op->contr->mode */ | | * >=7 was >= op->contr->mode |
/* >=7 is the old standard setting. Now we take the last 4 bits | | * >=7 is the old standard setting. Now we take the last 4 bits |
* and multiply them by 5, giving 0..15*5== 5..75 */ | | * and multiply them by 5, giving 0..15*5== 5..75 */ |
wvratio=(op->contr->mode & PU_RATIO) * 5; | | wvratio=(op->contr->mode & PU_RATIO) * 5; |
if ((query_cost(tmp, op, F_TRUE)*100 / (tmp->weight * MAX(tmp->nrof, 1))) >= wvratio) | | if ((query_cost(tmp, op, F_TRUE)*100 / (tmp->weight * MAX(tmp->nrof, 1))) >= wvratio) |
| | |
return ! stop; | | return ! stop; |
} | | } |
| | |
/** | | /* Find an arrow in the inventory and after that |
* Find an arrow in the inventory and after that | | |
* in the right type container (quiver). Pointer to the | | * in the right type container (quiver). Pointer to the |
* found object is returned. | | * found object is returned. |
*/ | | */ |
| | |
return tmp; | | return tmp; |
} | | } |
| | |
/** | | /* Similar to find_arrow, but looks for (roughly) the best arrow to use |
* Similar to find_arrow, but looks for (roughly) the best arrow to use | | |
* against the target. A full test is not performed, simply a basic test | | * against the target. A full test is not performed, simply a basic test |
* of resistances. The archer is making a quick guess at what he sees down | | * of resistances. The archer is making a quick guess at what he sees down |
* the hall. Failing that it does it's best to pick the highest plus arrow. | | * the hall. Failing that it does it's best to pick the highest plus arrow. |
| | |
return tmp; | | return tmp; |
} | | } |
| | |
/** | | /* looks in a given direction, finds the first valid target, and calls |
* looks in a given direction, finds the first valid target, and calls | | |
* find_better_arrow to find a decent arrow to use. | | * find_better_arrow to find a decent arrow to use. |
* op = the shooter | | * op = the shooter |
* type = bow->race | | * type = bow->race |
| | |
return find_better_arrow(op, tmp, type, &i); | | return find_better_arrow(op, tmp, type, &i); |
} | | } |
| | |
/** | | /* Creature fires a bow - op can be monster or player. Returns |
* Creature fires a bow - op can be monster or player. Returns | | |
* 1 if bow was actually fired, 0 otherwise. | | * 1 if bow was actually fired, 0 otherwise. |
* op is the object firing the bow. | | * op is the object firing the bow. |
* part is for multipart creatures - the part firing the bow. | | * part is for multipart creatures - the part firing the bow. |
| | |
return 1; | | return 1; |
} | | } |
| | |
/** | | /* Special fire code for players - this takes into |
* Special fire code for players - this takes into | | |
* account the special fire modes players can have | | * account the special fire modes players can have |
* but monsters can't. Putting that code here | | * but monsters can't. Putting that code here |
* makes the fire_bow code much cleaner. | | * makes the fire_bow code much cleaner. |
| | |
} | | } |
| | |
| | |
/** | | /* Fires a misc (wand/rod/horn) object in 'dir'. |
* Fires a misc (wand/rod/horn) object in 'dir'. | | |
* Broken apart from 'fire' to keep it more readable. | | * Broken apart from 'fire' to keep it more readable. |
*/ | | */ |
static void fire_misc_object(object *op, int dir) | | static void fire_misc_object(object *op, int dir) |
| | |
} | | } |
} | | } |
| | |
/** | | /* Received a fire command for the player - go and do it. |
* Received a fire command for the player - go and do it. | | |
*/ | | */ |
void fire(object *op,int dir) { | | void fire(object *op,int dir) { |
int spellcost=0; | | int spellcost=0; |
| | |
| | |
| | |
| | |
/** | | /* We try to find a key for the door as passed. If we find a key |
* We try to find a key for the door as passed. If we find a key | | |
* and successfully use it, we return the key, otherwise NULL | | * and successfully use it, we return the key, otherwise NULL |
* This function merges both normal and locked door, since the logic | | * This function merges both normal and locked door, since the logic |
* for both is the same - just the specific key is different. | | * for both is the same - just the specific key is different. |
| | |
return tmp; | | return tmp; |
} | | } |
| | |
/** | | /* moved door processing out of move_player_attack. |
* moved door processing out of move_player_attack. | | |
* returns 1 if player has opened the door with a key | | * returns 1 if player has opened the door with a key |
* such that the caller should not do anything more, | | * such that the caller should not do anything more, |
* 0 otherwise | | * 0 otherwise |
| | |
return 0; | | return 0; |
} | | } |
| | |
/** | | /* This function is just part of a breakup from move_player. |
* This function is just part of a breakup from move_player. | | |
* It should keep the code cleaner. | | * It should keep the code cleaner. |
* When this is called, the players direction has been updated | | * When this is called, the players direction has been updated |
* (taking into account confusion.) The player is also actually | | * (taking into account confusion.) The player is also actually |
| | |
} | | } |
/* Remove transport speed. Give player just a little speed - | | /* Remove transport speed. Give player just a little speed - |
* enough so that they will get an action again quickly. | | * enough so that they will get an action again quickly. |
* | | |
*/ | | */ |
transport->speed_left -= 1.0; | | transport->speed_left -= 1.0; |
if (op->speed_left < 0.0) op->speed_left = -0.01; | | if (op->speed_left < 0.0) op->speed_left = -0.01; |
| | |
return 0; | | return 0; |
} | | } |
| | |
/** | | /* This is similar to handle_player, below, but is only used by the |
* This is similar to handle_player, below, but is only used by the | | |
* new client/server stuff. | | * new client/server stuff. |
* This is sort of special, in that the new client/server actually uses | | * This is sort of special, in that the new client/server actually uses |
* the new speed values for commands. | | * the new speed values for commands. |
| | |
return 0; | | return 0; |
} | | } |
| | |
/** | | /* Returns 1 if player had his life saved by an item. |
* Returns 1 if player had his life saved by an item. | | |
* In this case, first item saving life is removed. | | * In this case, first item saving life is removed. |
*/ | | */ |
static int save_life(object *op) { | | static int save_life(object *op) { |
| | |
return 0; | | return 0; |
} | | } |
| | |
/** | | /* This goes throws the inventory and removes unpaid objects, and puts them |
* This goes throws the inventory and removes unpaid objects, and puts them | | |
* back in the map (location and map determined by values of env). This | | * back in the map (location and map determined by values of env). This |
* function will descend into containers. op is the object to start the search | | * function will descend into containers. op is the object to start the search |
* from. | | * from. |
| | |
} | | } |
| | |
| | |
/** | | /* Returns pointer a static string containing gravestone text |
* Returns pointer a static string containing gravestone text | | |
* Moved from apply.c to player.c - player.c is what | | * Moved from apply.c to player.c - player.c is what |
* actually uses this function. player.c may not be quite the | | * actually uses this function. player.c may not be quite the |
* best, a misc file for object actions is probably better, | | * best, a misc file for object actions is probably better, |
| | |
return buf2; | | return buf2; |
} | | } |
| | |
/** | | /* Regenerate hp/sp/gr, decreases food. This only works for players. |
* Regenerate hp/sp/gr, decreases food. This only works for players. | | |
* Will grab food if needed, or kill player. | | * Will grab food if needed, or kill player. |
*/ | | */ |
void do_some_living(object *op) { | | void do_some_living(object *op) { |
| | |
} | | } |
| | |
| | |
/** | | /* If the player should die (lack of hp, food, etc), we call this. |
* If the player should die (lack of hp, food, etc), we call this. | | |
* op is the player in jeopardy. If the player can not be saved (not | | * op is the player in jeopardy. If the player can not be saved (not |
* permadeath, no lifesave), this will take care of removing the player | | * permadeath, no lifesave), this will take care of removing the player |
* file. | | * file. |
| | |
tmp->x=op->x,tmp->y=op->y; | | tmp->x=op->x,tmp->y=op->y; |
insert_ob_in_map (tmp, op->map, NULL,0); | | insert_ob_in_map (tmp, op->map, NULL,0); |
| | |
/**************************************/ | | |
/* */ | | |
/* Subtract the experience points, */ | | |
/* if we died cause of food, give us */ | | |
/* food, and reset HP's... */ | | |
/* */ | | |
/**************************************/ | | |
| | |
/* remove any poisoning and confusion the character may be suffering.*/ | | |
/* restore player */ | | /* restore player: remove any poisoning, disease and confusion the |
| | * character may be suffering.*/ |
at = find_archetype("poisoning"); | | at = find_archetype("poisoning"); |
tmp=present_arch_in_ob(at,op); | | tmp=present_arch_in_ob(at,op); |
if (tmp) { | | if (tmp) { |
| | |
} | | } |
cure_disease(op,0); /* remove any disease */ | | cure_disease(op,0); /* remove any disease */ |
| | |
/*add_exp(op, (op->stats.exp * -0.20)); */ | | /* Subtract the experience points, if we died cause of food, give |
| | * us food, and reset HP's... |
| | */ |
apply_death_exp_penalty(op); | | apply_death_exp_penalty(op); |
if(op->stats.food < 100) op->stats.food = 900; | | if(op->stats.food < 100) op->stats.food = 900; |
op->stats.hp = op->stats.maxhp; | | op->stats.hp = op->stats.maxhp; |
op->stats.sp = MAX(op->stats.sp, op->stats.maxsp); | | op->stats.sp = MAX(op->stats.sp, op->stats.maxsp); |
op->stats.grace = MAX(op->stats.grace, op->stats.maxgrace); | | op->stats.grace = MAX(op->stats.grace, op->stats.maxgrace); |
| | |
/* | | /* Check to see if the player is in a shop. IF so, then check to see if |
* Check to see if the player is in a shop. IF so, then check to see if | | |
* the player has any unpaid items. If so, remove them and put them back | | * the player has any unpaid items. If so, remove them and put them back |
* in the map. | | * in the map. |
*/ | | */ |
if (is_in_shop(op)) | | if (is_in_shop(op)) |
remove_unpaid_objects(op->inv, op); | | remove_unpaid_objects(op->inv, op); |
| | |
/****************************************/ | | /* Move player to his current respawn-position (usually last savebed) */ |
/* */ | | |
/* Move player to his current respawn- */ | | |
/* position (usually last savebed) */ | | |
/* */ | | |
/****************************************/ | | |
| | |
enter_player_savebed(op); | | enter_player_savebed(op); |
| | |
/* Save the player before inserting the force to reduce | | /* Save the player before inserting the force to reduce chance of abuse. */ |
* chance of abuse. | | |
*/ | | |
op->contr->braced=0; | | op->contr->braced=0; |
save_player(op,1); | | save_player(op,1); |
| | |
| | |
fix_player(op); | | fix_player(op); |
| | |
} | | } |
/**************************************/ | | |
/* */ | | |
/* Repaint the characters inv, and */ | | |
/* stats, and show a nasty message ;) */ | | |
/* */ | | |
/**************************************/ | | |
| | |
| | /* Tell the player they have died */ |
new_draw_info(NDI_UNIQUE, 0,op,"YOU HAVE DIED."); | | new_draw_info(NDI_UNIQUE, 0,op,"YOU HAVE DIED."); |
return; | | return; |
} /* NOT_PERMADETH */ | | } /* NOT_PERMADETH */ |
| | |
delete_character(op->name,0); | | delete_character(op->name,0); |
if (settings.resurrection == TRUE) { | | if (settings.resurrection == TRUE) { |
/* save playerfile sans equipment when player dies | | /* save playerfile sans equipment when player dies |
** then save it as player.pl.dead so that future resurrection | | * -then save it as player.pl.dead so that future resurrection |
** type spells will work on them nicely | | * -type spells will work on them nicely |
*/ | | */ |
delete_character(op->name,0); | | delete_character(op->name,0); |
op->stats.hp = op->stats.maxhp; | | op->stats.hp = op->stats.maxhp; |
| | |
} | | } |
} | | } |
| | |
/** | | /* fix_weight(): Check recursively the weight of all players, and fix |
* fix_weight(): Check recursively the weight of all players, and fix | | |
* what needs to be fixed. Refresh windows and fix speed if anything | | * what needs to be fixed. Refresh windows and fix speed if anything |
* was changed. | | * was changed. |
*/ | | */ |
| | |
} | | } |
| | |
| | |
/** | | /* Handles op throwing objects of type 'DUST'. |
* Handles op throwing objects of type 'DUST'. | | |
* This is much simpler in the new spell code - we basically | | * This is much simpler in the new spell code - we basically |
* just treat this as any other spell casting object. | | * just treat this as any other spell casting object. |
*/ | | */ |
| | |
return 0; | | return 0; |
} | | } |
| | |
/** | | /* Look at the surrounding terrain to determine |
* Look at the surrounding terrain to determine | | |
* the hideability of this object. Positive levels | | * the hideability of this object. Positive levels |
* indicate greater hideability. | | * indicate greater hideability. |
*/ | | */ |
| | |
| | |
/* this also picks up whether the object is glowing. | | /* this also picks up whether the object is glowing. |
* If you carry a light on a non-dark map, its not | | * If you carry a light on a non-dark map, its not |
* as bad as carrying a light on a pitch dark map */ | | * as bad as carrying a light on a pitch dark map |
| | */ |
if(has_carried_lights(ob)) level =- (10 + (2*ob->map->darkness)); | | if(has_carried_lights(ob)) level =- (10 + (2*ob->map->darkness)); |
| | |
/* scan through all nearby squares for terrain to hide in */ | | /* scan through all nearby squares for terrain to hide in */ |
| | |
return level; | | return level; |
} | | } |
| | |
/** | | /* For Hidden creatures - a chance of becoming 'unhidden' |
* For Hidden creatures - a chance of becoming 'unhidden' | | |
* every time they move - as we subtract off 'invisibility' | | * every time they move - as we subtract off 'invisibility' |
* AND, for players, if they move into a ridiculously unhideable | | * AND, for players, if they move into a ridiculously unhideable |
* spot (surrounded by clear terrain in broad daylight). -b.t. | | * spot (surrounded by clear terrain in broad daylight). -b.t. |
*/ | | */ |
| | |
void do_hidden_move (object *op) { | | void do_hidden_move (object *op) { |
int hide=0, num=random_roll(0, 19, op, PREFER_LOW); | | int hide=0, num=random_roll(0, 19, op, PREFER_LOW); |
object *skop; | | object *skop; |
| | |
} | | } |
} | | } |
| | |
/** determine if who is standing near a hostile creature. */ | | /* determine if who is standing near a hostile creature. */ |
| | |
int stand_near_hostile( object *who ) { | | int stand_near_hostile( object *who ) { |
object *tmp=NULL; | | object *tmp=NULL; |
int i,friendly=0,player=0, mflags; | | int i,friendly=0,player=0, mflags; |
| | |
return 0; | | return 0; |
} | | } |
| | |
/** | | /* Check the player los field for viewability of the |
* Check the player los field for viewability of the | | |
* object op. This function works fine for monsters, | | * object op. This function works fine for monsters, |
* but we dont worry if the object isnt the top one in | | * but we dont worry if the object isnt the top one in |
* a pile (say a coin under a table would return "viewable" | | * a pile (say a coin under a table would return "viewable" |
| | |
* -b.t. | | * -b.t. |
* This function is now map tiling safe. | | * This function is now map tiling safe. |
*/ | | */ |
| | |
int player_can_view (object *pl,object *op) { | | int player_can_view (object *pl,object *op) { |
rv_vector rv; | | rv_vector rv; |
int dx,dy; | | int dx,dy; |
| | |
return 0; | | return 0; |
} | | } |
| | |
/** | | /* routine for both players and monsters. We call this when |
* routine for both players and monsters. We call this when | | |
* there is a possibility for our action distrubing our hiding | | * there is a possibility for our action distrubing our hiding |
* place or invisiblity spell. Artefact invisiblity is not | | * place or invisiblity spell. Artefact invisiblity is not |
* effected by this. If we arent invisible to begin with, we | | * effected by this. If we arent invisible to begin with, we |
| | |
return 0; | | return 0; |
} | | } |
| | |
/** | | /* op_on_battleground - checks if the given object op (usually |
* op_on_battleground - checks if the given object op (usually | | |
* a player) is standing on a valid battleground-tile, | | * a player) is standing on a valid battleground-tile, |
* function returns TRUE/FALSE. If true x, y returns the battleground | | * function returns TRUE/FALSE. If true x, y returns the battleground |
* -exit-coord. (and if x, y not NULL) | | * -exit-coord. (and if x, y not NULL) |
| | |
return 0; | | return 0; |
} | | } |
| | |
/** | | /* When a dragon-player gains a new stage of evolution, |
* When a dragon-player gains a new stage of evolution, | | |
* he gets some treasure | | * he gets some treasure |
* | | * |
* attributes: | | * attributes: |
| | |
} | | } |
} | | } |
| | |
/** | | /* Unready an object for a player. This function does nothing if the object was |
* Unready an object for a player. This function does nothing if the object was | | |
* not readied. | | * not readied. |
*/ | | */ |
void player_unready_range_ob(player *pl, object *ob) { | | void player_unready_range_ob(player *pl, object *ob) { |