Crossfire Server, Branches 1.12  R18729
skill_util.c File Reference
#include <global.h>
#include <object.h>
#include <sproto.h>
#include <living.h>
#include <spells.h>
+ Include dependency graph for skill_util.c:

Go to the source code of this file.

Macros

#define WANT_UNARMED_SKILLS
 

Functions

static objectadjust_skill_tool (object *who, object *skill, object *skill_tool)
 
static int attack_hth (object *pl, int dir, const char *string, object *skill)
 
static int attack_melee_weapon (object *op, int dir, const char *string, object *skill)
 
sint64 calc_skill_exp (object *who, object *op, object *skill)
 
int change_skill (object *who, object *new_skill, int flag)
 
void clear_skill (object *who)
 
static int clipped_percent (sint64 a, sint64 b)
 
int do_skill (object *op, object *part, object *skill, int dir, const char *string)
 
static int do_skill_attack (object *tmp, object *op, const char *string, object *skill)
 
static objectfind_best_player_hth_skill (object *op)
 
objectfind_skill_by_name (object *who, const char *name)
 
objectfind_skill_by_number (object *who, int skillno)
 
void init_skills (void)
 
int learn_skill (object *pl, object *scroll)
 
void link_player_skills (object *op)
 
void show_skills (object *op, const char *search)
 
int skill_attack (object *tmp, object *pl, int dir, const char *string, object *skill)
 
int use_skill (object *op, const char *string)
 

Variables

const char * skill_names [NUM_SKILLS]
 

Detailed Description

Various skill-related functions.

Created July 95 to separate skill utilities from actual skills -b.t.

Reconfigured skills code to allow linking of skills to experience categories. This is done solely through the init_new_exp_system() fctn. June/July 1995 -b.t. thoma.nosp@m.s@as.nosp@m.tro.p.nosp@m.su.e.nosp@m.du

July 1995 - Initial associated skills coding. Experience gains come solely from the use of skills. Overcoming an opponent (in combat, finding/disarming a trap, stealing from somebeing, etc) gains experience. Calc_skill_exp() handles the gained experience using modifications in the skills[] table. - b.t.

Definition in file skill_util.c.

Macro Definition Documentation

#define WANT_UNARMED_SKILLS

Definition at line 49 of file skill_util.c.

Function Documentation

static object* adjust_skill_tool ( object who,
object skill,
object skill_tool 
)
static

This returns specified skill if it can be used, potentially using tool to help.

Skill and tool can't be NULL at the same time.

Factored from find_skill_by_name() and find_skill_by_number().

The skill tool will be applied if not NULL, so the player can benefit from its bonuses.

Parameters
whoplayer trying to ready a skill.
skillskill to ready. Can be NULL.
skill_toolskill tool. Can be NULL.
Returns
skill object if it can be used, NULL else.
Note
clawing skill is special, as claws are declared as SKILLTOOL but shouldn't be applied.
Todo:
rewrite some.

Definition at line 153 of file skill_util.c.

References apply_special(), FLAG_APPLIED, FLAG_CAN_USE_SKILL, give_skill_by_name(), link_player_skills(), QUERY_FLAG, and obj::skill.

Referenced by find_skill_by_name(), and find_skill_by_number().

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int attack_hth ( object pl,
int  dir,
const char *  string,
object skill 
)
static

This handles all hand-to-hand attacks.

Will unapply equipped weapons if needed.

July 5, 1995 - I broke up attack_hth() into 2 parts. In the first (attack_hth) we check for weapon use, etc in the second (the new function skill_attack() we actually attack.

Parameters
plobject attacking.
dirattack direction.
stringdescribes the attack ("claw", "punch", ...).
skillattack skill used.
Returns
0 if no attack was done, non zero else.

Definition at line 1196 of file skill_util.c.

References AP_NOPRINT, AP_UNAPPLY, apply_special(), obj::below, draw_ext_info(), draw_ext_info_format(), FLAG_APPLIED, FLAG_READY_WEAPON, obj::inv, MAX_BUF, MSG_TYPE_SKILL, MSG_TYPE_SKILL_ERROR, obj::name, NDI_UNIQUE, QUERY_FLAG, query_name(), skill_attack(), and WEAPON.

Referenced by do_skill().

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int attack_melee_weapon ( object op,
int  dir,
const char *  string,
object skill 
)
static

This handles melee weapon attacks -b.t.

For now we are just checking to see if we have a ready weapon here. But there is a real neato possible feature of this scheme which bears mentioning: Since we are only calling this from do_skill() in the future we may make this routine handle 'special' melee weapons attacks (like disarming manuever with sai) based on player SK_level and weapon type.

Parameters
opliving thing attacking.
dirattack direction.
stringdescribes the attack ("claw", "punch", ...).
skillattack skill used.
Returns
0 if no attack was done, non zero else.

Definition at line 1244 of file skill_util.c.

References draw_ext_info(), FLAG_READY_WEAPON, MSG_TYPE_SKILL, MSG_TYPE_SKILL_ERROR, NDI_UNIQUE, PLAYER, QUERY_FLAG, skill_attack(), and obj::type.

Referenced by do_skill().

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

sint64 calc_skill_exp ( object who,
object op,
object skill 
)

Calculates amount of experience can be gained for successfull use of a skill.

Here we take the view that a player must 'overcome an opponent' in order to gain experience. Examples include foes killed combat, finding/disarming a trap, stealing from somebeing, etc.

The gained experience is based primarily on the difference in levels, exp point value of vanquished foe, the relevent stats of the skill being used and modifications in the skills[] table.

For now, monsters and players will be treated differently. Below I give the algorithm for *PLAYER *experience gain. Monster exp gain is simpler. Monsters just get 10% of the exp of the opponent.

Players get a ratio, eg, opponent lvl / player level. This is then multiplied by various things. If simple exp is true, then this multiplier, include the level difference, is always 1. This revised method prevents some cases where there are big gaps in the amount you get just because you are now equal level vs lower level

Parameters
whoplayer/creature that used the skill.
opobject that was 'defeated'.
skillused skill. If none, it should just point back to who.
Returns
experience for the skill use.

Definition at line 599 of file skill_util.c.

References obj::arch, liv::Cha, archt::clone, mapdef::difficulty, liv::exp, FLAG_ALIVE, obj::level, llevDebug, LOG(), obj::magic, obj::map, MAX, obj::name, PLAYER, QUERY_FLAG, RUNE, settings, Settings::simple_exp, SKILL, obj::stats, TRAP, and obj::type.

Referenced by attempt_jump(), book_type_apply(), do_hidden_move(), do_skill_detect_curse(), do_skill_detect_magic(), do_skill_ident2(), find_traps(), hide(), kill_object(), pick_lock(), remove_trap(), scroll_type_apply(), singing(), spellbook_type_apply(), steal(), use_oratory(), and write_scroll().

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int change_skill ( object who,
object new_skill,
int  flag 
)

This changes the objects skill to new_skill. Note that this function doesn't always need to get used - you can now add skill exp to the player without the chosen_skill being set. This function is of most interest to players to update the various range information.

Parameters
wholiving to change skill for.
new_skillskill to use. If NULL, this just unapplies the current skill.
flaghas the current meaning:
  • 0x1: If set, don't update the range pointer. This is useful when we need to ready a new skill, but don't want to clobber range.
Return values
0change failure.
1success

Definition at line 301 of file skill_util.c.

References AP_APPLY, AP_NOPRINT, AP_UNAPPLY, apply_special(), obj::chosen_skill, obj::contr, PLAYER, range_skill, pl::shoottype, and obj::type.

Referenced by apply_special(), cast_destruction(), cast_spell(), command_rskill(), and do_skill_attack().

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void clear_skill ( object who)

This function just clears the chosen_skill and range_skill values in the player.

Parameters
wholiving to clear.

Definition at line 340 of file skill_util.c.

References obj::chosen_skill, CLEAR_FLAG, obj::contr, FLAG_READY_SKILL, PLAYER, range_none, range_skill, pl::ranges, pl::shoottype, and obj::type.

Referenced by unapply_special().

+ Here is the caller graph for this function:

static int clipped_percent ( sint64  a,
sint64  b 
)
static

Gives a percentage clipped to 0% -> 100% of a/b.

Parameters
acurrent value
bmax value
Returns
value between 0 and 100.
Todo:
Probably belongs in some global utils-type file?

Definition at line 741 of file skill_util.c.

Referenced by show_skills().

+ Here is the caller graph for this function:

int do_skill ( object op,
object part,
object skill,
int  dir,
const char *  string 
)

Main skills use function-similar in scope to cast_spell(). We handle all requests for skill use outside of some combat here. We require a separate routine outside of fire() so as to allow monsters to utilize skills.

This is changed (2002-11-30) from the old method that returned exp - no caller needed that info, but it also prevented the callers from know if a skill was actually used, as many skills don't give any exp for their direct use (eg, throwing).

Gives experience if appropriate.

Parameters
opThe object actually using the skill
partactual part using the skill, used by throwing for monsters
skillThe skill used by op
dirThe direction in which the skill is used
stringA parameter string, necessary to use some skills
Return values
0skill failure.
1use of the skill was successful.

Definition at line 373 of file skill_util.c.

References obj::anim_suffix, apply_anim_suffix(), attack_hth(), attack_melee_weapon(), obj::below, change_exp(), obj::chosen_skill, CLEAR_FLAG, describe_shop(), do_harvest(), draw_ext_info(), find_traps(), fix_object(), FLAG_APPLIED, give_skill_by_name(), hide(), obj::inv, jump(), llevDebug, LOG(), MAX_BUF, meditate(), MSG_TYPE_SKILL, MSG_TYPE_SKILL_ERROR, MSG_TYPE_SKILL_SUCCESS, NDI_UNIQUE, pick_lock(), PLAYER, pray(), QUERY_FLAG, query_name(), remove_trap(), SET_FLAG, singing(), SK_ALCHEMY, SK_BARGAINING, SK_BOWYER, SK_CLAWING, SK_CLIMBING, SK_DET_CURSE, SK_DET_MAGIC, SK_DISARM_TRAPS, SK_EVOCATION, SK_FIND_TRAPS, SK_FLAME_TOUCH, SK_HARVESTING, SK_HIDING, SK_INSCRIPTION, SK_JEWELER, SK_JUMPING, SK_KARATE, SK_LEVITATION, SK_LITERACY, SK_LOCKPICKING, SK_MEDITATION, SK_MISSILE_WEAPON, SK_ONE_HANDED_WEAPON, SK_ORATORY, SK_PRAYING, SK_PUNCHING, SK_PYROMANCY, SK_SET_TRAP, SK_SINGING, SK_SMITHERY, SK_SORCERY, SK_STEALING, SK_SUBTRACT_SKILL_EXP, SK_SUMMONING, SK_THAUMATURGY, SK_THROWING, SK_TWO_HANDED_WEAPON, SK_USE_MAGIC_ITEM, SK_WOODSMAN, SK_WRAITH_FEED, SKILL, obj::skill, skill_ident(), skill_throw(), liv::sp, obj::speed_left, obj::stats, steal(), obj::subtype, obj::type, use_alchemy(), use_oratory(), and write_on_item().

Referenced by command_throw(), fire(), monster_use_skill(), and use_skill().

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int do_skill_attack ( object tmp,
object op,
const char *  string,
object skill 
)
static

We have got an appropriate opponent from either move_player_attack() or skill_attack(). In this part we get on with attacking, take care of messages from the attack and changes in invisible.

Parameters
tmptargetted monster.
opwhat is attacking.
stringdescribes the damage ("claw", "punch", ...).
skillskill used to damage.
Returns
true if the attack damaged the opponent.

Definition at line 987 of file skill_util.c.

References attack_ob(), obj::below, change_skill(), obj::chosen_skill, obj::contr, obj::current_weapon, draw_ext_info(), draw_ext_info_format(), find_best_player_hth_skill(), find_skill_by_name(), FLAG_APPLIED, FLAG_FREED, FLAG_READY_WEAPON, obj::hide, obj::inv, obj::invisible, llevError, LOG(), MAX_BUF, MSG_TYPE_ATTACK, MSG_TYPE_ATTACK_DID_HIT, MSG_TYPE_SKILL, MSG_TYPE_SKILL_ERROR, MSG_TYPE_SKILL_MISSING, MSG_TYPE_VICTIM, MSG_TYPE_VICTIM_WAS_HIT, obj::name, NDI_BLACK, NDI_UNIQUE, PLAYER, QUERY_FLAG, query_name(), obj::skill, obj::subtype, pl::tmp_invis, obj::type, UP_OBJ_FACE, update_object(), and WEAPON.

Referenced by skill_attack().

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static object* find_best_player_hth_skill ( object op)
static

Finds the best unarmed skill the player has, and returns it. Best can vary a little - we consider clawing to always be the best for dragons.

This could be more intelligent, eg, look at the skill level of the skill and go from there (eg, a level 40 puncher is is probably better than level 1 karate). OTOH, if you don't bother to set up your skill properly, that is the players problem (although, it might be nice to have a preferred skill field the player can set.

Unlike the old code, we don't give out any skills - it is possible you just don't have any ability to get into unarmed combat. If everyone race/class should have one, this should be handled in the starting treasurelists, not in the code.

Parameters
opplayer to get skill for.
Returns
attack skill, NULL if no suitable found.

Definition at line 937 of file skill_util.c.

References obj::below, find_skill_by_number(), FLAG_CAN_USE_SKILL, obj::inv, is_dragon_pl(), QUERY_FLAG, SK_CLAWING, SKILL, obj::subtype, and obj::type.

Referenced by do_skill_attack().

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

object* find_skill_by_name ( object who,
const char *  name 
)

This returns the skill pointer of the given name (the one that accumlates exp, has the level, etc).

It is presumed that the player will be needing to actually use the skill, so a skill tool will be equipped if one if found to benefit from its bonuses.

This code is basically the same as find_skill_by_number() below, but instead of a skill number, we search by the name.

Parameters
whoPlayer to get skill.
nameskill to find. Needs not to be a shared string.
Returns
pointer to skill object, or NULL if player doesn't have it.
Todo:
check if name shouldn't be made a shared string.

Definition at line 207 of file skill_util.c.

References adjust_skill_tool(), obj::below, FLAG_APPLIED, obj::inv, QUERY_FLAG, SKILL, SKILL_TOOL, and strncasecmp().

Referenced by apply_special(), attempt_do_alchemy(), attempt_recipe(), book_type_apply(), cast_destruction(), cast_dust(), cast_spell(), command_addexp(), command_cast_spell(), command_rskill(), command_throw(), do_skill_attack(), dragon_ability_gain(), inscribe_scroll_cmd(), scroll_type_apply(), spellbook_type_apply(), and write_on_item().

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

object* find_skill_by_number ( object who,
int  skillno 
)

This returns the skill pointer of the given name (the one that accumlates exp, has the level, etc).

It is presumed that the player will be needing to actually use the skill, so a skill tool will be equipped if one if found to benefit from its bonuses.

This code is basically the same as find_skill_by_name() above, but instead of a skill name, we search by matching number.

Parameters
whoplayer applying a skill.
skillnoskill subtype.
Returns
skill object if player can use it, NULL else.

Definition at line 257 of file skill_util.c.

References adjust_skill_tool(), obj::below, FLAG_APPLIED, obj::inv, NUM_SKILLS, QUERY_FLAG, SKILL, and SKILL_TOOL.

Referenced by find_best_player_hth_skill().

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void init_skills ( void  )

This just sets up the skill_names table above. The index into the array is set up by the subtypes.

Definition at line 71 of file skill_util.c.

References add_refcount(), add_string(), archt::clone, first_archetype, llevError, LOG(), archt::next, NUM_SKILLS, SKILL, obj::skill, skill_names, obj::subtype, and obj::type.

Referenced by init().

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int learn_skill ( object pl,
object scroll 
)

Player is trying to learn a skill. Success is based on Int.

This inserts the requested skill in the player's inventory. The skill field of the scroll should have the exact name of the requested skill.

This one actually teaches the player the skill as something they can equip.

Return values
0player already knows the skill.
1the player learns the skill.
2some failure.

Definition at line 690 of file skill_util.c.

References obj::below, FLAG_CAN_USE_SKILL, give_skill_by_name(), liv::Int, obj::inv, learn_spell, obj::level, link_player_skills(), llevError, LOG(), obj::name, PREFER_LOW, QUERY_FLAG, random_roll(), SET_FLAG, SKILL, obj::skill, obj::stats, strncasecmp(), and obj::type.

Referenced by skillscroll_type_apply().

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void link_player_skills ( object op)

This function goes through the player inventory and sets up the last_skills[] array in the player object. The last_skills[] is used to more quickly lookup skills - mostly used for sending exp.

Parameters
opplayer to link skills for. Must be a player.

Definition at line 112 of file skill_util.c.

References obj::below, obj::contr, obj::inv, pl::last_skill_exp, pl::last_skill_ob, llevError, LOG(), NUM_SKILLS, SKILL, obj::skill, obj::subtype, and obj::type.

Referenced by adjust_skill_tool(), become_follower(), check_login(), food_type_apply(), give_initial_items(), key_change_class(), and learn_skill().

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void show_skills ( object op,
const char *  search 
)

Displays a player's skill list, and some other non skill related info (god, max weapon improvments, item power).

This shows the amount of exp they have in the skills.

Note this function is a bit more complicated because we we want ot sort the skills before printing them. If we just dumped this as we found it, this would be a bit simpler.

Parameters
opplayer wanting to examine skills.
searchoptional string to restrict skills to show.

Definition at line 773 of file skill_util.c.

References obj::below, clipped_percent(), obj::contr, determine_god(), draw_ext_info(), draw_ext_info_format(), liv::exp, obj::expmul, obj::inv, pl::item_power, obj::level, level_exp(), MAX_BUF, MSG_TYPE_SKILL, MSG_TYPE_SKILL_ERROR, MSG_TYPE_SKILL_LIST, obj::name, NDI_RED, NDI_UNIQUE, NUM_SKILLS, obj::perm_exp, Settings::permanent_exp_ratio, settings, SKILL, snprintf(), obj::stats, and obj::type.

Referenced by command_skills().

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int skill_attack ( object tmp,
object pl,
int  dir,
const char *  string,
object skill 
)

Core routine for use when we attack using a skills system. In essence, this code handles all skill-based attacks, ie hth, missile and melee weapons should be treated here. If an opponent is already supplied by move_player(), we move right onto do_skill_attack(), otherwise we find if an appropriate opponent exists.

This is called by move_player() and attack_hth()

Initial implementation by -bt thoma.nosp@m.s@as.nosp@m.tro.p.nosp@m.su.e.nosp@m.du

Parameters
tmpvictim. Can be NULL.
plwho is attacking.
dirdirection to attack.
stringdescribes the damage ("claw", "punch", ...).
skillattack skill.
Returns
0 if no attack, non zero if an attack was done.

Definition at line 1126 of file skill_util.c.

References obj::above, obj::contr, do_skill_attack(), draw_ext_info(), obj::facing, FLAG_ALIVE, FLAG_CAN_ROLL, freearr_x, freearr_y, get_map_flags(), GET_MAP_MOVE_BLOCK, GET_MAP_OB, liv::hp, LOCKED_DOOR, obj::map, MSG_TYPE_SKILL, MSG_TYPE_SKILL_FAILURE, NDI_UNIQUE, OB_TYPE_MOVE_BLOCK, P_IS_ALIVE, P_OUT_OF_MAP, pl::party, PLAYER, QUERY_FLAG, obj::stats, obj::type, obj::x, and obj::y.

Referenced by attack_hth(), attack_melee_weapon(), attempt_jump(), move_monster(), and move_player_attack().

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int use_skill ( object op,
const char *  string 
)

Similar to invoke command, it executes the skill in the direction that the user is facing.

This is tricky because skills can have spaces. We basically roll our own find_skill_by_name so we can try to do better string matching.

Parameters
opplayer trying to use a skill.
stringparameter for the skill to use.
Return values
0unable to change to the requested skill, or unable to use the skill properly.
1skill correctly used.

Definition at line 863 of file skill_util.c.

References obj::below, do_skill(), draw_ext_info_format(), obj::facing, FLAG_CAN_USE_SKILL, obj::inv, llevDebug, LOG(), MIN, MSG_TYPE_SKILL, MSG_TYPE_SKILL_MISSING, NDI_UNIQUE, QUERY_FLAG, SKILL, obj::skill, SKILL_TOOL, strncasecmp(), and obj::type.

Referenced by command_disarm(), command_search(), and command_uskill().

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Variable Documentation

const char* skill_names[NUM_SKILLS]

Will contain a number-name mapping for skills, initialized by init_skills().

Definition at line 65 of file skill_util.c.

Referenced by append_spell(), check_spells(), command_disarm(), command_search(), command_throw(), init_skills(), scroll_type_apply(), and send_skill_info().