Crossfire Server, Trunk
|
#include "global.h"
#include <assert.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "living.h"
#include "object.h"
#include "shop.h"
#include "skills.h"
#include "spells.h"
#include "sproto.h"
#include "assets.h"
Go to the source code of this file.
Macros | |
#define | WANT_UNARMED_SKILLS |
Functions | |
static object * | adjust_skill_tool (object *who, object *skill, object *skill_tool) |
static void | attack_hth (object *pl, int dir, const char *string, object *skill) |
static void | attack_melee_weapon (object *op, int dir, const char *string, object *skill) |
int64_t | calc_skill_exp (const object *who, const object *op, const object *skill) |
int | change_skill (object *who, object *new_skill, int flag) |
void | clear_skill (object *who) |
static int | clipped_percent (int64_t a, int64_t b) |
static int | digits_in_long (int64_t num) |
static void | do_each_skill (archetype *at) |
int | do_skill (object *op, object *part, object *skill, int dir, const char *string) |
static void | do_skill_attack (object *tmp, object *op, const char *string, object *skill) |
static object * | find_best_player_hth_skill (object *op) |
object * | find_skill_by_name (object *who, const char *name) |
object * | find_skill_by_number (object *who, int skillno) |
static int | free_skill_index () |
int | get_skill_client_code (const char *skill_name) |
void | init_skills (void) |
int | learn_skill (object *pl, object *scroll) |
void | show_skills (object *op, const char *parms) |
void | skill_attack (object *tmp, object *pl, int dir, const char *string, object *skill) |
int | use_skill (object *op, const char *string) |
Variables | |
const Face * | skill_faces [MAX_SKILLS] |
const char * | skill_names [MAX_SKILLS] |
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 s@as tro.p su.e 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.
#define WANT_UNARMED_SKILLS |
Definition at line 35 of file skill_util.c.
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.
who | player trying to ready a skill. |
skill | skill to ready. Can be NULL. |
skill_tool | skill tool. Can be NULL. |
Definition at line 140 of file skill_util.c.
References apply_special(), FLAG_APPLIED, FLAG_CAN_USE_SKILL, give_skill_by_name(), link_player_skills(), QUERY_FLAG, obj::skill, and autojail::who.
Referenced by find_skill_by_name(), and find_skill_by_number().
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.
pl | object attacking. |
dir | attack direction. |
string | describes the attack ("claw", "punch", ...). |
skill | attack skill used. |
Definition at line 1342 of file skill_util.c.
References AP_NOPRINT, AP_UNAPPLY, apply_special(), draw_ext_info(), draw_ext_info_format(), FLAG_READY_WEAPON, MAX_BUF, MSG_TYPE_SKILL, MSG_TYPE_SKILL_ERROR, obj::name, NDI_UNIQUE, object_find_by_type_applied(), QUERY_FLAG, query_name(), skill_attack(), and WEAPON.
Referenced by do_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 maneuver with sai) based on player SK_level and weapon type.
op | living thing attacking. |
dir | attack direction. |
string | describes the attack ("claw", "punch", ...). |
skill | attack skill used. |
Definition at line 1386 of file skill_util.c.
References draw_ext_info(), FLAG_READY_WEAPON, MSG_TYPE_SKILL, MSG_TYPE_SKILL_ERROR, NDI_UNIQUE, give::op, PLAYER, QUERY_FLAG, and skill_attack().
Referenced by do_skill().
Calculates amount of experience can be gained for successful 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 relevant 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
Note that the experience is calculated for one "instance" of op, whatever its count.
who | player/creature that used the skill. |
op | object that was 'defeated'. |
skill | used skill. If none, it should just point back to who or be NULL. |
Definition at line 658 of file skill_util.c.
References obj::arch, archt::clone, liv::exp, FLAG_ALIVE, obj::level, llevDebug, LOG(), MAX, give::op, PLAYER, QUERY_FLAG, RUNE, settings, Settings::simple_exp, SKILL, obj::stats, TRAP, obj::type, autojail::value, and autojail::who.
Referenced by book_type_apply(), detect_curse_on_item(), detect_magic_on_item(), do_hidden_move(), find_traps(), hide(), identify_object_with_skill(), kill_object(), pick_lock(), remove_trap(), scroll_type_apply(), singing(), spellbook_type_apply(), steal(), use_oratory(), and write_scroll().
This changes the object's 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.
who | living to change skill for. |
new_skill | skill to use. If NULL, this just unapplies the current skill. |
flag | has the current meaning:
|
0 | change failure. |
1 | success |
Definition at line 350 of file skill_util.c.
References AP_APPLY, AP_NOPRINT, AP_UNAPPLY, apply_special(), PLAYER, range_skill, obj::skill, autojail::who, and guild_entry::x1.
Referenced by apply_special(), cast_destruction(), cast_spell(), command_rskill(), and do_skill_attack().
void clear_skill | ( | object * | who | ) |
This function just clears the chosen_skill and range_skill values in the player.
who | living to clear. |
Definition at line 389 of file skill_util.c.
References CLEAR_FLAG, FLAG_READY_SKILL, PLAYER, range_none, range_skill, and autojail::who.
Referenced by unapply_special().
|
static |
Gives a percentage clipped to 0% -> 100% of a/b.
a | current value |
b | max value |
Definition at line 805 of file skill_util.c.
References disinfect::a, Ice::b, and make_face_from_files::int.
Referenced by show_skills().
|
static |
Gives the number of digits that ld will print for a long int
num | any integer (negative values not supported) |
Definition at line 830 of file skill_util.c.
Referenced by show_skills().
|
static |
Definition at line 74 of file skill_util.c.
References add_refcount(), archt::clone, obj::face, fatal(), free_skill_index(), llevError, LOG(), MAX_SKILLS, SEE_LAST_ERROR, SKILL, obj::skill, skill_faces, skill_names, and obj::type.
Referenced by init_skills().
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.
op | The object actually using the skill |
part | actual part using the skill, used by throwing for monsters |
skill | The skill used by op |
dir | The direction in which the skill is used |
string | A parameter string, necessary to use some skills |
0 | skill failure. |
1 | use of the skill was successful. |
Definition at line 422 of file skill_util.c.
References obj::anim_suffix, apply_anim_suffix(), attack_hth(), attack_melee_weapon(), change_exp(), CLEAR_FLAG, do_harvest(), draw_ext_info(), find_traps(), fix_object(), FLAG_APPLIED, give_skill_by_name(), hide(), jump(), llevDebug, llevError, LOG(), MAX_BUF, meditate(), MSG_TYPE_SKILL, MSG_TYPE_SKILL_ERROR, MSG_TYPE_SKILL_SUCCESS, give::name, NDI_UNIQUE, object_find_by_type_and_skill(), give::op, pick_lock(), PLAYER, pray(), QUERY_FLAG, query_name(), remove_trap(), SET_FLAG, shop_describe(), singing(), SK_AIR_MAGIC, SK_ALCHEMY, SK_BARGAINING, SK_BOWYER, SK_CLAWING, SK_CLIMBING, SK_DET_CURSE, SK_DET_MAGIC, SK_DISARM_TRAPS, SK_EARTH_MAGIC, SK_EVOCATION, SK_FIND_TRAPS, SK_FIRE_MAGIC, 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_WATER_MAGIC, SK_WOODSMAN, SK_WRAITH_FEED, SKILL, obj::skill, skill_ident(), skill_throw(), steal(), obj::subtype, Ice::tmp, obj::type, use_alchemy(), use_oratory(), nlohmann::detail::void(), and write_on_item().
Referenced by do_skill_by_number(), fire(), monster_use_skill(), player_attack_door(), and use_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.
tmp | targeted monster. |
op | what is attacking. |
string | describes the damage ("claw", "punch", ...). |
skill | skill used to damage. |
Definition at line 1122 of file skill_util.c.
References attack_ob(), change_skill(), draw_ext_info(), draw_ext_info_format(), find_best_player_hth_skill(), find_skill_by_name(), FLAG_FREED, FLAG_READY_WEAPON, llevError, LOG(), MAX_BUF, MSG_TYPE_ATTACK, MSG_TYPE_ATTACK_DID_HIT, MSG_TYPE_ATTACK_MISS, 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, object_find_by_type_applied(), object_update(), give::op, PLAYER, QUERY_FLAG, query_name(), Ice::tmp, UP_OBJ_FACE, and WEAPON.
Referenced by skill_attack().
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.
op | player to get skill for. |
Definition at line 1033 of file skill_util.c.
References draw_ext_info_format(), find_skill_by_name(), find_skill_by_number(), FLAG_CAN_USE_SKILL, FOR_INV_FINISH, FOR_INV_PREPARE, is_dragon_pl(), MSG_TYPE_SKILL, MSG_TYPE_SKILL_MISSING, NDI_UNIQUE, give::op, QUERY_FLAG, SK_CLAWING, SKILL, obj::subtype, and Ice::tmp.
Referenced by do_skill_attack().
This returns the skill pointer of the given name (the one that accumulates 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.
Because a multiple skill names are allowed, we have to use arrays to store the intermediate results - we can't have skill_tool point to praying with skill pointing to fire magic.
who | Player to get skill. |
name | skill to find. Needs not to be a shared string. name can be a comma separated list of skill names - in that case, we will find the skill of the highest level. |
Definition at line 202 of file skill_util.c.
References adjust_skill_tool(), FLAG_APPLIED, FLAG_UNPAID, FOR_INV_FINISH, FOR_INV_PREPARE, obj::level, llevError, LOG(), MAX_SKILLS, give::name, QUERY_FLAG, SKILL, skill_names, SKILL_TOOL, Ice::tmp, and autojail::who.
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_unarmed_skill(), do_skill_attack(), dragon_ability_gain(), find_best_player_hth_skill(), inscribe_scroll_cmd(), player_attack_door(), spellbook_type_apply(), and write_on_item().
This returns the first skill pointer of the given subtype (the one that accumulates 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 subtype.
Warning: skill subtypes are not unique to skills, various skills (eg harvesting-like) will share the same subtype, so this function should only be used if the skill's subtype is known to be used only by one skill.
who | player applying a skill. |
skillno | skill subtype. |
Definition at line 305 of file skill_util.c.
References adjust_skill_tool(), FLAG_APPLIED, FOR_INV_FINISH, FOR_INV_PREPARE, MAX_SKILLS, QUERY_FLAG, SKILL, SKILL_TOOL, Ice::tmp, and autojail::who.
Referenced by find_best_player_hth_skill().
|
static |
Definition at line 65 of file skill_util.c.
References MAX_SKILLS, skill_faces, and skill_names.
Referenced by do_each_skill().
int get_skill_client_code | ( | const char * | skill_name | ) |
Return the code of the skill for a client, the index in the skill_names array.
skill_name | skill name. |
Definition at line 107 of file skill_util.c.
References npc_dialog::index, MAX_SKILLS, and skill_names.
Referenced by esrv_update_stats(), hiscore_check(), and hiscore_init().
void init_skills | ( | void | ) |
This just sets up the skill_names table above. The index into the array is simply the order the skill is found.
Definition at line 91 of file skill_util.c.
References archetypes_for_each(), do_each_skill(), MAX_SKILLS, skill_faces, and skill_names.
Referenced by init().
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.
0 | player already knows the skill. |
1 | the player learns the skill. |
2 | some failure. |
Definition at line 750 of file skill_util.c.
References FLAG_CAN_USE_SKILL, FOR_INV_FINISH, FOR_INV_PREPARE, get_learn_spell(), give_skill_by_name(), commongive::inv, link_player_skills(), llevError, LOG(), obj::name, PREFER_LOW, QUERY_FLAG, random_roll(), SET_FLAG, SKILL, obj::skill, and Ice::tmp.
Referenced by skillscroll_type_apply().
void show_skills | ( | object * | op, |
const char * | parms | ||
) |
Displays a player's skill list, and some other non skill related info (god, max weapon improvements, 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.
op | player wanting to examine skills. |
parms | optional parameters, usually a string to restrict skills to show. |
Definition at line 851 of file skill_util.c.
References clipped_percent(), determine_god(), digits_in_long(), draw_ext_info(), draw_ext_info_format(), exp_level(), FMT64, FOR_INV_FINISH, FOR_INV_PREPARE, level_exp(), MAX_BUF, MAX_SKILLS, MSG_TYPE_SKILL, MSG_TYPE_SKILL_ERROR, MSG_TYPE_SKILL_LIST, NDI_RED, NDI_UNIQUE, give::op, give::parms, PERM_EXP, Settings::permanent_exp_ratio, settings, SKILL, and Ice::tmp.
Referenced by command_skills().
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 s@as tro.p su.e du
tmp | victim. Can be NULL. |
pl | who is attacking. |
dir | direction to attack. |
string | describes the damage ("claw", "punch", ...). |
skill | attack skill. |
Definition at line 1272 of file skill_util.c.
References do_skill_attack(), draw_ext_info(), FLAG_ALIVE, FLAG_CAN_ROLL, FOR_MAP_FINISH, FOR_MAP_PREPARE, freearr_x, freearr_y, get_map_flags(), GET_MAP_MOVE_BLOCK, LOCKED_DOOR, m, 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, and Ice::tmp.
Referenced by attack_hth(), attack_melee_weapon(), attempt_jump(), monster_move(), and move_player_attack().
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.
op | player trying to use a skill. |
string | parameter for the skill to use. |
0 | unable to change to the requested skill, or unable to use the skill properly. |
1 | skill correctly used. |
Definition at line 955 of file skill_util.c.
References do_skill(), draw_ext_info_format(), FLAG_CAN_USE_SKILL, FLAG_UNPAID, FOR_INV_FINISH, FOR_INV_PREPARE, llevDebug, LOG(), MIN, MSG_TYPE_SKILL, MSG_TYPE_SKILL_MISSING, give::name, NDI_UNIQUE, give::op, QUERY_FLAG, SKILL, obj::skill, SKILL_TOOL, and Ice::tmp.
Referenced by command_uskill().
const Face* skill_faces[MAX_SKILLS] |
Will contain the face numbers for the skills, initialized by init_skill().
Definition at line 63 of file skill_util.c.
Referenced by do_each_skill(), free_skill_index(), init_skills(), and send_skill_info().
const char* skill_names[MAX_SKILLS] |
Will contain a number-name mapping for skills, initialized by init_skills().
Definition at line 59 of file skill_util.c.
Referenced by append_spell(), do_each_skill(), find_skill_by_name(), free_skill_index(), get_skill_client_code(), hiscore_init(), init_skills(), and send_skill_info().