--- deliantra/server/server/skill_util.C 2006/09/07 10:01:58 1.8 +++ deliantra/server/server/skill_util.C 2006/09/10 15:59:57 1.9 @@ -1,7 +1,9 @@ + /* * static char *rcsid_skill_util_c = - * "$Id: skill_util.C,v 1.8 2006/09/07 10:01:58 pippijn Exp $"; + * "$Id: skill_util.C,v 1.9 2006/09/10 15:59:57 root Exp $"; */ + /* CrossFire, A Multiplayer game for X-windows @@ -40,6 +42,7 @@ */ /* define the following for skills utility debuging */ + /* #define SKILL_UTIL_DEBUG */ #define WANT_UNARMED_SKILLS @@ -47,13 +50,13 @@ #include #include #ifndef __CEXTRACT__ -#include +# include #endif -#include /* for defs of STR,CON,DEX,etc. -b.t.*/ +#include /* for defs of STR,CON,DEX,etc. -b.t. */ #include -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); +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); shstr skill_names[NUM_SKILLS]; @@ -61,28 +64,35 @@ * above. The index into the array is set up by the * subtypes. */ -void init_skills(void) { - int i; - archetype *at; - - for(at = first_archetype;at!=NULL;at=at->next) { - if (at->clone.type == SKILL) { - if (skill_names[at->clone.subtype] != NULL) { - LOG(llevError, "init_skills: multiple skill using same subtype %d, %s, %s\n", - at->clone.subtype, &skill_names[at->clone.subtype], &at->clone.skill); - } else { - skill_names[at->clone.subtype] = at->clone.skill; +void +init_skills (void) +{ + int i; + archetype *at; + + for (at = first_archetype; at != NULL; at = at->next) + { + if (at->clone.type == SKILL) + { + if (skill_names[at->clone.subtype] != NULL) + { + LOG (llevError, "init_skills: multiple skill using same subtype %d, %s, %s\n", + at->clone.subtype, &skill_names[at->clone.subtype], &at->clone.skill); + } + else + { + skill_names[at->clone.subtype] = at->clone.skill; } } } - /* This isn't really an error if there is no skill subtype set, but - * checking for this may catch some user errors. - */ - for (i=1; iinv; tmp; tmp=tmp->below) { - if (tmp->type == SKILL) { - /* This is really a warning, hence no else below */ - if (op->contr->last_skill_ob[tmp->subtype] && op->contr->last_skill_ob[tmp->subtype] != tmp) { - LOG(llevError,"Multiple skills with the same subtype? %s, %s\n", - &op->contr->last_skill_ob[tmp->subtype]->skill, &tmp->skill); + for (tmp = op->inv; tmp; tmp = tmp->below) + { + if (tmp->type == SKILL) + { + /* This is really a warning, hence no else below */ + if (op->contr->last_skill_ob[tmp->subtype] && op->contr->last_skill_ob[tmp->subtype] != tmp) + { + LOG (llevError, "Multiple skills with the same subtype? %s, %s\n", + &op->contr->last_skill_ob[tmp->subtype]->skill, &tmp->skill); } - if (tmp->subtype >= NUM_SKILLS) { - LOG(llevError,"Invalid subtype number %d (range 0-%d)\n", - tmp->subtype, NUM_SKILLS); - } else { - op->contr->last_skill_ob[tmp->subtype] = tmp; - op->contr->last_skill_exp[tmp->subtype] = -1; + if (tmp->subtype >= NUM_SKILLS) + { + LOG (llevError, "Invalid subtype number %d (range 0-%d)\n", tmp->subtype, NUM_SKILLS); + } + else + { + op->contr->last_skill_ob[tmp->subtype] = tmp; + op->contr->last_skill_exp[tmp->subtype] = -1; } } } @@ -121,48 +137,57 @@ * use the skill, so thus if use of the skill requires a skill * tool, this code will equip it. */ -object *find_skill_by_name(object *who, const char *name) +object * +find_skill_by_name (object *who, const char *name) { - object *skill = NULL, *skill_tool = NULL, *tmp; + object *skill = NULL, *skill_tool = NULL, *tmp; - if (!name) return NULL; + if (!name) + return NULL; - /* We make sure the length of the string in the object is greater - * in length than the passed string. Eg, if we have a skill called - * 'hi', we don't want to match if the user passed 'high' - */ - for (tmp = who->inv; tmp != NULL; tmp = tmp->below) { - if (tmp->type == SKILL && !strncasecmp(name, tmp->skill, strlen(name)) && - (size_t) strlen(tmp->skill) >= strlen(name)) skill = tmp; - - /* Try to find appropriate skilltool. If the player has one already - * applied, we try to keep using that one. - */ - else if (tmp->type == SKILL_TOOL && !strncasecmp(name, tmp->skill, strlen(name)) && - (size_t) strlen(tmp->skill) >= strlen(name)) { - if (QUERY_FLAG(tmp, FLAG_APPLIED)) skill_tool = tmp; - else if (!skill_tool || !QUERY_FLAG(skill_tool, FLAG_APPLIED)) - skill_tool = tmp; + /* We make sure the length of the string in the object is greater + * in length than the passed string. Eg, if we have a skill called + * 'hi', we don't want to match if the user passed 'high' + */ + for (tmp = who->inv; tmp != NULL; tmp = tmp->below) + { + if (tmp->type == SKILL && !strncasecmp (name, tmp->skill, strlen (name)) && (size_t) strlen (tmp->skill) >= strlen (name)) + skill = tmp; + + /* Try to find appropriate skilltool. If the player has one already + * applied, we try to keep using that one. + */ + else if (tmp->type == SKILL_TOOL && !strncasecmp (name, tmp->skill, strlen (name)) && (size_t) strlen (tmp->skill) >= strlen (name)) + { + if (QUERY_FLAG (tmp, FLAG_APPLIED)) + skill_tool = tmp; + else if (!skill_tool || !QUERY_FLAG (skill_tool, FLAG_APPLIED)) + skill_tool = tmp; } } - /* If this is a skill that can be used without a tool, return it */ - if (skill && QUERY_FLAG(skill, FLAG_CAN_USE_SKILL)) return skill; - - /* Player has a tool to use the skill. IF not applied, apply it - - * if not successful, return null. If they do have the skill tool - * but not the skill itself, give it to them. - */ - if (skill_tool) { - if (!QUERY_FLAG(skill_tool, FLAG_APPLIED)) { - if (apply_special(who, skill_tool, 0)) return NULL; + /* If this is a skill that can be used without a tool, return it */ + if (skill && QUERY_FLAG (skill, FLAG_CAN_USE_SKILL)) + return skill; + + /* Player has a tool to use the skill. IF not applied, apply it - + * if not successful, return null. If they do have the skill tool + * but not the skill itself, give it to them. + */ + if (skill_tool) + { + if (!QUERY_FLAG (skill_tool, FLAG_APPLIED)) + { + if (apply_special (who, skill_tool, 0)) + return NULL; } - if (!skill) { - skill = give_skill_by_name(who, skill_tool->skill); - link_player_skills(who); + if (!skill) + { + skill = give_skill_by_name (who, skill_tool->skill); + link_player_skills (who); } - return skill; + return skill; } - return NULL; + return NULL; } @@ -177,42 +202,53 @@ * but instead a skill name, we search by matching number. * this replaces find_skill. */ -object *find_skill_by_number(object *who, int skillno) +object * +find_skill_by_number (object *who, int skillno) { - object *skill=NULL, *skill_tool=NULL, *tmp; + object *skill = NULL, *skill_tool = NULL, *tmp; - if (skillno < 1 || skillno >= NUM_SKILLS) return NULL; + if (skillno < 1 || skillno >= NUM_SKILLS) + return NULL; - for (tmp=who->inv; tmp!=NULL; tmp=tmp->below) { - if (tmp->type == SKILL && tmp->subtype == skillno) skill = tmp; + for (tmp = who->inv; tmp != NULL; tmp = tmp->below) + { + if (tmp->type == SKILL && tmp->subtype == skillno) + skill = tmp; - /* Try to find appropriate skilltool. If the player has one already - * applied, we try to keep using that one. - */ - else if (tmp->type == SKILL_TOOL && tmp->subtype == skillno) { - if (QUERY_FLAG(tmp, FLAG_APPLIED)) skill_tool = tmp; - else if (!skill_tool || !QUERY_FLAG(skill_tool, FLAG_APPLIED)) - skill_tool = tmp; + /* Try to find appropriate skilltool. If the player has one already + * applied, we try to keep using that one. + */ + else if (tmp->type == SKILL_TOOL && tmp->subtype == skillno) + { + if (QUERY_FLAG (tmp, FLAG_APPLIED)) + skill_tool = tmp; + else if (!skill_tool || !QUERY_FLAG (skill_tool, FLAG_APPLIED)) + skill_tool = tmp; } } - /* If this is a skill that can be used without a tool, return it */ - if (skill && QUERY_FLAG(skill, FLAG_CAN_USE_SKILL)) return skill; - - /* Player has a tool to use the skill. IF not applied, apply it - - * if not successful, return null. If they do have the skill tool - * but not the skill itself, give it to them. - */ - if (skill_tool) { - if (!QUERY_FLAG(skill_tool, FLAG_APPLIED)) { - if (apply_special(who, skill_tool, 0)) return NULL; + /* If this is a skill that can be used without a tool, return it */ + if (skill && QUERY_FLAG (skill, FLAG_CAN_USE_SKILL)) + return skill; + + /* Player has a tool to use the skill. IF not applied, apply it - + * if not successful, return null. If they do have the skill tool + * but not the skill itself, give it to them. + */ + if (skill_tool) + { + if (!QUERY_FLAG (skill_tool, FLAG_APPLIED)) + { + if (apply_special (who, skill_tool, 0)) + return NULL; } - if (!skill) { - skill = give_skill_by_name(who, skill_tool->skill); - link_player_skills(who); + if (!skill) + { + skill = give_skill_by_name (who, skill_tool->skill); + link_player_skills (who); } - return skill; + return skill; } - return NULL; + return NULL; } /* This changes the objects skill to new_skill. @@ -227,49 +263,55 @@ * return 1 on success, 0 on error */ -int change_skill (object *who, object *new_skill, int flag) +int +change_skill (object *who, object *new_skill, int flag) { - int old_range; + int old_range; - if ( who->type != PLAYER ) - return 0; - - old_range = who->contr->shoottype; + if (who->type != PLAYER) + return 0; + + old_range = who->contr->shoottype; - if (who->chosen_skill && who->chosen_skill == new_skill) + if (who->chosen_skill && who->chosen_skill == new_skill) { - /* optimization for changing skill to current skill */ - if (who->type == PLAYER && !(flag & 0x1)) - who->contr->shoottype = range_skill; - return 1; + /* optimization for changing skill to current skill */ + if (who->type == PLAYER && !(flag & 0x1)) + who->contr->shoottype = range_skill; + return 1; } - if (!new_skill || who->chosen_skill) - if (who->chosen_skill) apply_special(who, who->chosen_skill, AP_UNAPPLY); + if (!new_skill || who->chosen_skill) + if (who->chosen_skill) + apply_special (who, who->chosen_skill, AP_UNAPPLY); - /* Only goal in this case was to unapply a skill */ - if (!new_skill) return 0; + /* Only goal in this case was to unapply a skill */ + if (!new_skill) + return 0; - if (apply_special (who, new_skill, AP_APPLY)) { - return 0; + if (apply_special (who, new_skill, AP_APPLY)) + { + return 0; } - if (flag & 0x1) - who->contr->shoottype = (rangetype) old_range; + if (flag & 0x1) + who->contr->shoottype = (rangetype) old_range; - return 1; + return 1; } /* This function just clears the chosen_skill and range_skill values * inthe player. */ -void clear_skill(object *who) +void +clear_skill (object *who) { - who->chosen_skill = NULL; - CLEAR_FLAG(who, FLAG_READY_SKILL); - if (who->type == PLAYER) { - who->contr->ranges[range_skill] = NULL; - if (who->contr->shoottype == range_skill) - who->contr->shoottype = range_none; + who->chosen_skill = NULL; + CLEAR_FLAG (who, FLAG_READY_SKILL); + if (who->type == PLAYER) + { + who->contr->ranges[range_skill] = NULL; + if (who->contr->shoottype == range_skill) + who->contr->shoottype = range_none; } } @@ -284,123 +326,133 @@ * It returns 0 if no skill was used. */ -int do_skill (object *op, object *part, object *skill, int dir, const char *string) { - int success=0, exp=0; - int did_alc = 0; - object *tmp, *next; - - if (!skill) return 0; - - /* The code below presumes that the skill points to the object that - * holds the exp, level, etc of the skill. So if this is a player - * go and try to find the actual real skill pointer, and if the - * the player doesn't have a bucket for that, create one. - */ - if (skill->type != SKILL && op->type == PLAYER) { - for (tmp = op->inv; tmp!=NULL; tmp=tmp->below) { - if (tmp->type == SKILL && tmp->skill == skill->skill) break; +int +do_skill (object *op, object *part, object *skill, int dir, const char *string) +{ + int success = 0, exp = 0; + int did_alc = 0; + object *tmp, *next; + + if (!skill) + return 0; + + /* The code below presumes that the skill points to the object that + * holds the exp, level, etc of the skill. So if this is a player + * go and try to find the actual real skill pointer, and if the + * the player doesn't have a bucket for that, create one. + */ + if (skill->type != SKILL && op->type == PLAYER) + { + for (tmp = op->inv; tmp != NULL; tmp = tmp->below) + { + if (tmp->type == SKILL && tmp->skill == skill->skill) + break; } - if (!tmp) tmp=give_skill_by_name(op, skill->skill); - skill = tmp; + if (!tmp) + tmp = give_skill_by_name (op, skill->skill); + skill = tmp; } - // skill, by_whom, on_which_object, which direction, skill_argument - if (INVOKE_OBJECT (USE_SKILL, skill, ARG_OBJECT (op), ARG_OBJECT (part), ARG_INT (dir), ARG_STRING (string))) - return 0; + // skill, by_whom, on_which_object, which direction, skill_argument + if (INVOKE_OBJECT (USE_SKILL, skill, ARG_OBJECT (op), ARG_OBJECT (part), ARG_INT (dir), ARG_STRING (string))) + return 0; - switch(skill->subtype) { + switch (skill->subtype) + { case SK_LEVITATION: - /* Not 100% sure if this will work with new movement code - - * the levitation skill has move_type for flying, so when - * equipped, that should transfer to player, when not, - * shouldn't. - */ - if(QUERY_FLAG(skill,FLAG_APPLIED)) { - CLEAR_FLAG(skill,FLAG_APPLIED); - new_draw_info(NDI_UNIQUE,0,op,"You come to earth."); + /* Not 100% sure if this will work with new movement code - + * the levitation skill has move_type for flying, so when + * equipped, that should transfer to player, when not, + * shouldn't. + */ + if (QUERY_FLAG (skill, FLAG_APPLIED)) + { + CLEAR_FLAG (skill, FLAG_APPLIED); + new_draw_info (NDI_UNIQUE, 0, op, "You come to earth."); } - else { - SET_FLAG(skill,FLAG_APPLIED); - new_draw_info(NDI_UNIQUE,0,op,"You rise into the air!."); + else + { + SET_FLAG (skill, FLAG_APPLIED); + new_draw_info (NDI_UNIQUE, 0, op, "You rise into the air!."); } - fix_player(op); - success=1; - break; + fix_player (op); + success = 1; + break; case SK_STEALING: - exp = success = steal(op, dir, skill); - break; + exp = success = steal (op, dir, skill); + break; case SK_LOCKPICKING: - exp = success = pick_lock(op, dir, skill); - break; + exp = success = pick_lock (op, dir, skill); + break; case SK_HIDING: - exp = success = hide(op, skill); - break; + exp = success = hide (op, skill); + break; case SK_JUMPING: - success = jump(op, dir, skill); - break; + success = jump (op, dir, skill); + break; case SK_INSCRIPTION: - exp = success = write_on_item(op,string, skill); - break; + exp = success = write_on_item (op, string, skill); + break; case SK_MEDITATION: - meditate(op, skill); - success=1; - break; - /* note that the following 'attack' skills gain exp through hit_player() */ + meditate (op, skill); + success = 1; + break; + /* note that the following 'attack' skills gain exp through hit_player() */ case SK_KARATE: - (void) attack_hth(op,dir,"karate-chopped", skill); - break; + (void) attack_hth (op, dir, "karate-chopped", skill); + break; case SK_PUNCHING: - (void) attack_hth(op,dir,"punched", skill); - break; + (void) attack_hth (op, dir, "punched", skill); + break; case SK_FLAME_TOUCH: - (void) attack_hth(op,dir,"flamed", skill); - break; + (void) attack_hth (op, dir, "flamed", skill); + break; case SK_SPARK_TOUCH: - (void) attack_hth(op,dir,"zapped", skill); - break; + (void) attack_hth (op, dir, "zapped", skill); + break; case SK_SHIVER: - (void) attack_hth(op,dir,"froze", skill); - break; + (void) attack_hth (op, dir, "froze", skill); + break; case SK_ACID_SPLASH: - (void) attack_hth(op,dir,"dissolved", skill); - break; + (void) attack_hth (op, dir, "dissolved", skill); + break; case SK_POISON_NAIL: - (void) attack_hth(op,dir,"injected poison into", skill); - break; + (void) attack_hth (op, dir, "injected poison into", skill); + break; case SK_CLAWING: - (void) attack_hth(op,dir,"clawed", skill); - break; + (void) attack_hth (op, dir, "clawed", skill); + break; case SK_ONE_HANDED_WEAPON: case SK_TWO_HANDED_WEAPON: - (void) attack_melee_weapon(op,dir,NULL, skill); - break; + (void) attack_melee_weapon (op, dir, NULL, skill); + break; case SK_FIND_TRAPS: - exp = success = find_traps(op, skill); - break; + exp = success = find_traps (op, skill); + break; case SK_SINGING: - exp = success = singing(op,dir, skill); - break; + exp = success = singing (op, dir, skill); + break; case SK_ORATORY: - exp = success = use_oratory(op,dir, skill); - break; + exp = success = use_oratory (op, dir, skill); + break; case SK_SMITHERY: case SK_BOWYER: @@ -409,83 +461,86 @@ case SK_THAUMATURGY: case SK_LITERACY: case SK_WOODSMAN: - /* first, we try to find a cauldron, and do the alchemy thing. - * failing that, we go and identify stuff. - */ - for (tmp=get_map_ob(op->map, op->x, op->y); tmp != NULL;tmp=next) { - next=tmp->above; - if(QUERY_FLAG(tmp, FLAG_IS_CAULDRON)) { - attempt_do_alchemy(op, tmp); - if (QUERY_FLAG(tmp, FLAG_APPLIED)) - esrv_send_inventory(op, tmp); - did_alc=1; + /* first, we try to find a cauldron, and do the alchemy thing. + * failing that, we go and identify stuff. + */ + for (tmp = get_map_ob (op->map, op->x, op->y); tmp != NULL; tmp = next) + { + next = tmp->above; + if (QUERY_FLAG (tmp, FLAG_IS_CAULDRON)) + { + attempt_do_alchemy (op, tmp); + if (QUERY_FLAG (tmp, FLAG_APPLIED)) + esrv_send_inventory (op, tmp); + did_alc = 1; } } - if (did_alc == 0) - exp = success = skill_ident(op,skill); - break; + if (did_alc == 0) + exp = success = skill_ident (op, skill); + break; case SK_DET_MAGIC: case SK_DET_CURSE: - exp = success = skill_ident(op,skill); - break; + exp = success = skill_ident (op, skill); + break; case SK_DISARM_TRAPS: - exp = success = remove_trap(op,dir, skill); - break; + exp = success = remove_trap (op, dir, skill); + break; case SK_THROWING: - success = skill_throw(op,part,dir,string, skill); - break; + success = skill_throw (op, part, dir, string, skill); + break; case SK_SET_TRAP: - new_draw_info(NDI_UNIQUE, 0,op,"This skill is not currently implemented."); - break; + new_draw_info (NDI_UNIQUE, 0, op, "This skill is not currently implemented."); + break; case SK_USE_MAGIC_ITEM: case SK_MISSILE_WEAPON: - new_draw_info(NDI_UNIQUE, 0,op,"There is no special attack for this skill."); - break; + new_draw_info (NDI_UNIQUE, 0, op, "There is no special attack for this skill."); + break; case SK_PRAYING: - success = pray(op, skill); - break; + success = pray (op, skill); + break; case SK_BARGAINING: - success = describe_shop(op); - break; + success = describe_shop (op); + break; case SK_SORCERY: case SK_EVOCATION: case SK_PYROMANCY: case SK_SUMMONING: case SK_CLIMBING: - new_draw_info(NDI_UNIQUE, 0,op,"This skill is already in effect."); - break; + new_draw_info (NDI_UNIQUE, 0, op, "This skill is already in effect."); + break; default: - LOG(llevDebug,"%s attempted to use unknown skill: %d\n" - ,query_name(op), op->chosen_skill->stats.sp); - break; + LOG (llevDebug, "%s attempted to use unknown skill: %d\n", query_name (op), op->chosen_skill->stats.sp); + break; } - /* For players we now update the speed_left from using the skill. - * Monsters have no skill use time because of the random nature in - * which use_monster_skill is called already simulates this. - * If certain skills should take more/less time, that should be - * in the code for the skill itself. - */ - - if(op->type==PLAYER) op->speed_left -= 1.0; - - /* this is a good place to add experience for successfull use of skills. - * Note that add_exp() will figure out player/monster experience - * gain problems. - */ - - if(success && exp) change_exp(op,exp, skill->skill, 0); - - return success; + /* For players we now update the speed_left from using the skill. + * Monsters have no skill use time because of the random nature in + * which use_monster_skill is called already simulates this. + * If certain skills should take more/less time, that should be + * in the code for the skill itself. + */ + + if (op->type == PLAYER) + op->speed_left -= 1.0; + + /* this is a good place to add experience for successfull use of skills. + * Note that add_exp() will figure out player/monster experience + * gain problems. + */ + + if (success && exp) + change_exp (op, exp, skill->skill, 0); + + return success; } /* calc_skill_exp() - calculates amount of experience can be gained for @@ -514,76 +569,94 @@ * */ -int calc_skill_exp(object *who, object *op, object *skill) { - int op_exp=0,op_lvl= 0; - float base,value,lvl_mult=0.0; - - if (!skill) skill = who; - - /* Oct 95 - where we have an object, I expanded our treatment - * to 3 cases: - * non-living magic obj, runes and everything else. - * - * If an object is not alive and magical we set the base exp higher to - * help out exp awards for skill_ident skills. Also, if - * an item is type RUNE, we give out exp based on stats.Cha - * and level (this was the old system) -b.t. - */ - - if(!op) { /* no item/creature */ - op_lvl= who->map->difficulty < 1 ? 1: who->map->difficulty; - op_exp = 0; - } else if(op->type==RUNE || op->type==TRAP) { /* all traps. If stats.Cha > 1 we use that +int +calc_skill_exp (object *who, object *op, object *skill) +{ + int op_exp = 0, op_lvl = 0; + float base, value, lvl_mult = 0.0; + + if (!skill) + skill = who; + + /* Oct 95 - where we have an object, I expanded our treatment + * to 3 cases: + * non-living magic obj, runes and everything else. + * + * If an object is not alive and magical we set the base exp higher to + * help out exp awards for skill_ident skills. Also, if + * an item is type RUNE, we give out exp based on stats.Cha + * and level (this was the old system) -b.t. + */ + + if (!op) + { /* no item/creature */ + op_lvl = who->map->difficulty < 1 ? 1 : who->map->difficulty; + op_exp = 0; + } + else if (op->type == RUNE || op->type == TRAP) + { /* all traps. If stats.Cha > 1 we use that * for the amount of experience */ - op_exp = op->stats.Cha>1 ? op->stats.Cha : op->stats.exp; - op_lvl = op->level; - } else { /* all other items/living creatures */ - op_exp = op->stats.exp; - op_lvl = op->level; - if(!QUERY_FLAG(op,FLAG_ALIVE)) { /* for ident/make items */ - op_lvl += 5 * abs(op->magic); - } - } - - if(op_lvl<1) op_lvl = 1; - - if(who->type!=PLAYER) { /* for monsters only */ - return ((int) (op_exp*0.1)+1); /* we add one to insure positive value is returned */ - } else { /* for players */ - base = op_exp; - /* if skill really is a skill, then we can look at the skill archetype for - * bse reward value (exp) and level multiplier factor. - */ - if (skill->type == SKILL) { - base += skill->arch->clone.stats.exp; - if (settings.simple_exp) { - if (skill->arch->clone.level) - lvl_mult = (float) skill->arch->clone.level / 100.0; - else - lvl_mult = 1.0; /* no adjustment */ + op_exp = op->stats.Cha > 1 ? op->stats.Cha : op->stats.exp; + op_lvl = op->level; + } + else + { /* all other items/living creatures */ + op_exp = op->stats.exp; + op_lvl = op->level; + if (!QUERY_FLAG (op, FLAG_ALIVE)) + { /* for ident/make items */ + op_lvl += 5 * abs (op->magic); + } + } + + if (op_lvl < 1) + op_lvl = 1; + + if (who->type != PLAYER) + { /* for monsters only */ + return ((int) (op_exp * 0.1) + 1); /* we add one to insure positive value is returned */ + } + else + { /* for players */ + base = op_exp; + /* if skill really is a skill, then we can look at the skill archetype for + * bse reward value (exp) and level multiplier factor. + */ + if (skill->type == SKILL) + { + base += skill->arch->clone.stats.exp; + if (settings.simple_exp) + { + if (skill->arch->clone.level) + lvl_mult = (float) skill->arch->clone.level / 100.0; + else + lvl_mult = 1.0; /* no adjustment */ } - else { - if (skill->level) - lvl_mult = ((float) skill->arch->clone.level * (float) op_lvl) / ((float) skill->level * 100.0); - else - lvl_mult = 1.0; + else + { + if (skill->level) + lvl_mult = ((float) skill->arch->clone.level * (float) op_lvl) / ((float) skill->level * 100.0); + else + lvl_mult = 1.0; } - } else { - /* Don't divide by zero here! */ - lvl_mult = (float) op_lvl / (float) (skill->level?skill->level:1); + } + else + { + /* Don't divide by zero here! */ + lvl_mult = (float) op_lvl / (float) (skill->level ? skill->level : 1); } } - - /* assemble the exp total, and return value */ - - value = base * lvl_mult; - if (value < 1) value=1; /* Always give at least 1 exp point */ - + + /* assemble the exp total, and return value */ + + value = base * lvl_mult; + if (value < 1) + value = 1; /* Always give at least 1 exp point */ + #ifdef SKILL_UTIL_DEBUG - LOG(llevDebug,"calc_skill_exp(): who: %s(lvl:%d) op:%s(lvl:%d)\n", - who->name,skill->level,op->name,op_lvl); + LOG (llevDebug, "calc_skill_exp(): who: %s(lvl:%d) op:%s(lvl:%d)\n", who->name, skill->level, op->name, op_lvl); #endif - return ( (int) value); + return ((int) value); } /* Learn skill. This inserts the requested skill in the player's @@ -594,64 +667,71 @@ * Return 0 if the player knows the skill, 1 if the * player learns the skill, 2 otherwise. */ - + int -learn_skill (object *pl, object *scroll) { - object *tmp; +learn_skill (object *pl, object *scroll) +{ + object *tmp; - if (!scroll->skill) { - LOG(llevError,"skill scroll %s does not have skill pointer set.\n", &scroll->name); - return 2; + if (!scroll->skill) + { + LOG (llevError, "skill scroll %s does not have skill pointer set.\n", &scroll->name); + return 2; } - /* can't use find_skill_by_name because we want skills the player knows - * but can't use natively. - */ + /* can't use find_skill_by_name because we want skills the player knows + * but can't use natively. + */ - for (tmp=pl->inv; tmp!=NULL; tmp=tmp->below) - if (tmp->type == SKILL && !strncasecmp(scroll->skill, tmp->skill, strlen(scroll->skill))) break; + for (tmp = pl->inv; tmp != NULL; tmp = tmp->below) + if (tmp->type == SKILL && !strncasecmp (scroll->skill, tmp->skill, strlen (scroll->skill))) + break; - /* player already knows it */ - if (tmp && QUERY_FLAG(tmp, FLAG_CAN_USE_SKILL)) return 0; + /* player already knows it */ + if (tmp && QUERY_FLAG (tmp, FLAG_CAN_USE_SKILL)) + return 0; - /* now a random change to learn, based on player Int. - * give bonus based on level - otherwise stupid characters - * might never be able to learn anything. - */ - if(random_roll(0, 99, pl, PREFER_LOW)>(learn_spell[pl->stats.Int] + (pl->level/5))) - return 2; /* failure :< */ + /* now a random change to learn, based on player Int. + * give bonus based on level - otherwise stupid characters + * might never be able to learn anything. + */ + if (random_roll (0, 99, pl, PREFER_LOW) > (learn_spell[pl->stats.Int] + (pl->level / 5))) + return 2; /* failure :< */ - if (!tmp) - tmp = give_skill_by_name(pl, scroll->skill); + if (!tmp) + tmp = give_skill_by_name (pl, scroll->skill); - if (!tmp) { - LOG(llevError,"skill scroll %s does not have valid skill name (%s).\n", &scroll->name, &scroll->skill); - return 2; + if (!tmp) + { + LOG (llevError, "skill scroll %s does not have valid skill name (%s).\n", &scroll->name, &scroll->skill); + return 2; } - SET_FLAG(tmp, FLAG_CAN_USE_SKILL); - link_player_skills(pl); - return 1; + SET_FLAG (tmp, FLAG_CAN_USE_SKILL); + link_player_skills (pl); + return 1; } /* Gives a percentage clipped to 0% -> 100% of a/b. */ + /* Probably belongs in some global utils-type file? */ -static int clipped_percent(sint64 a, sint64 b) +static int +clipped_percent (sint64 a, sint64 b) { int rv; if (b <= 0) return 0; - rv = (int)((100.0f * ((float)a) / ((float)b) ) + 0.5f); - + rv = (int) ((100.0f * ((float) a) / ((float) b)) + 0.5f); + if (rv < 0) return 0; else if (rv > 100) return 100; - + return rv; } @@ -665,67 +745,74 @@ * just dumped this as we found it, this would be a bit * simpler. */ - -void show_skills(object *op, const char* search) { - object *tmp=NULL; - char buf[MAX_BUF]; - const char *cp; - int i,num_skills_found=0; - static const char *const periods = "........................................"; - /* Need to have a pointer and use strdup for qsort to work properly */ - char skills[NUM_SKILLS][MAX_BUF]; - - - for (tmp=op->inv; tmp!=NULL; tmp=tmp->below) { - if (tmp->type == SKILL) { - if ( search && strstr(tmp->name,search)==NULL ) continue; - /* Basically want to fill this out to 40 spaces with periods */ - sprintf(buf,"%s%s", &tmp->name, periods); - buf[40] = 0; - - if (settings.permanent_exp_ratio) { - sprintf(skills[num_skills_found++],"%slvl:%3d (xp:%lld/%lld/%d%%)", - buf,tmp->level, - (long long)tmp->stats.exp, - (long long)level_exp(tmp->level+1, op->expmul), - clipped_percent(tmp->perm_exp,tmp->stats.exp)); - } else { - sprintf(skills[num_skills_found++], "%slvl:%3d (xp:%lld/%lld)", - buf,tmp->level, - (long long)tmp->stats.exp, - (long long)level_exp(tmp->level+1, op->expmul)); + +void +show_skills (object *op, const char *search) +{ + object *tmp = NULL; + char buf[MAX_BUF]; + const char *cp; + int i, num_skills_found = 0; + static const char *const periods = "........................................"; + + /* Need to have a pointer and use strdup for qsort to work properly */ + char skills[NUM_SKILLS][MAX_BUF]; + + + for (tmp = op->inv; tmp != NULL; tmp = tmp->below) + { + if (tmp->type == SKILL) + { + if (search && strstr (tmp->name, search) == NULL) + continue; + /* Basically want to fill this out to 40 spaces with periods */ + sprintf (buf, "%s%s", &tmp->name, periods); + buf[40] = 0; + + if (settings.permanent_exp_ratio) + { + sprintf (skills[num_skills_found++], "%slvl:%3d (xp:%lld/%lld/%d%%)", + buf, tmp->level, + (long long) tmp->stats.exp, + (long long) level_exp (tmp->level + 1, op->expmul), clipped_percent (tmp->perm_exp, tmp->stats.exp)); + } + else + { + sprintf (skills[num_skills_found++], "%slvl:%3d (xp:%lld/%lld)", + buf, tmp->level, (long long) tmp->stats.exp, (long long) level_exp (tmp->level + 1, op->expmul)); } - /* I don't know why some characters get a bunch of skills, but - * it sometimes happens (maybe a leftover from bugier earlier code - * and those character are still about). In any case, lets handle - * it so it doesn't crash the server - otherwise, one character may - * crash the server numerous times. - */ - if (num_skills_found >= NUM_SKILLS) { - new_draw_info(NDI_RED, 0, op, "Your character has too many skills."); - new_draw_info(NDI_RED, 0, op, "Something isn't right - contact the server admin"); - break; + /* I don't know why some characters get a bunch of skills, but + * it sometimes happens (maybe a leftover from bugier earlier code + * and those character are still about). In any case, lets handle + * it so it doesn't crash the server - otherwise, one character may + * crash the server numerous times. + */ + if (num_skills_found >= NUM_SKILLS) + { + new_draw_info (NDI_RED, 0, op, "Your character has too many skills."); + new_draw_info (NDI_RED, 0, op, "Something isn't right - contact the server admin"); + break; } } } - clear_win_info(op); - new_draw_info(NDI_UNIQUE, 0,op,"Player skills:"); - if (num_skills_found > 1) qsort(skills, num_skills_found, MAX_BUF, (int (*)(const void*, const void*))strcmp); + clear_win_info (op); + new_draw_info (NDI_UNIQUE, 0, op, "Player skills:"); + if (num_skills_found > 1) + qsort (skills, num_skills_found, MAX_BUF, (int (*)(const void *, const void *)) strcmp); - for (i=0; ilevel/5+5); + new_draw_info_format (NDI_UNIQUE, 0, op, "You can handle %d weapon improvements.", op->level / 5 + 5); - cp = determine_god(op); - new_draw_info_format(NDI_UNIQUE, 0, op, - "You worship %s.", cp?cp:"no god at current time"); + cp = determine_god (op); + new_draw_info_format (NDI_UNIQUE, 0, op, "You worship %s.", cp ? cp : "no god at current time"); - new_draw_info_format(NDI_UNIQUE,0,op, "Your equipped item power is %d out of %d\n", - op->contr->item_power, (int) (op->level * settings.item_power_factor)); + new_draw_info_format (NDI_UNIQUE, 0, op, "Your equipped item power is %d out of %d\n", + op->contr->item_power, (int) (op->level * settings.item_power_factor)); } /* use_skill() - similar to invoke command, it executes the skill in the @@ -735,49 +822,58 @@ * our own find_skill_by_name so we can try to do better string matching. */ -int use_skill(object *op, const char *string) { - object *skop; - size_t len; - - if (!string) return 0; - - for (skop = op->inv; skop != NULL; skop=skop->below) { - if (skop->type == SKILL && QUERY_FLAG(skop, FLAG_CAN_USE_SKILL) && - !strncasecmp(string, skop->skill, MIN(strlen(string), (size_t) strlen(skop->skill)))) - break; - else if (skop->type == SKILL_TOOL && - !strncasecmp(string, skop->skill, MIN(strlen(string), (size_t) strlen(skop->skill)))) - break; +int +use_skill (object *op, const char *string) +{ + object *skop; + size_t len; + + if (!string) + return 0; + + for (skop = op->inv; skop != NULL; skop = skop->below) + { + if (skop->type == SKILL && QUERY_FLAG (skop, FLAG_CAN_USE_SKILL) && + !strncasecmp (string, skop->skill, MIN (strlen (string), (size_t) strlen (skop->skill)))) + break; + else if (skop->type == SKILL_TOOL && !strncasecmp (string, skop->skill, MIN (strlen (string), (size_t) strlen (skop->skill)))) + break; } - if (!skop) { - new_draw_info_format(NDI_UNIQUE, 0, op, - "Unable to find skill %s", string); - return 0; + if (!skop) + { + new_draw_info_format (NDI_UNIQUE, 0, op, "Unable to find skill %s", string); + return 0; } - len=strlen(skop->skill); + len = strlen (skop->skill); - /* All this logic goes and skips over the skill name to find any - * options given to the skill. Its pretty simple - if there - * are extra parameters (as deteremined by string length), we - * want to skip over any leading spaces. - */ - if(len>=strlen(string)) { - string=NULL; - } else { - string += len; - while(*string==0x20) string++; - if(strlen(string)==0) string = NULL; + /* All this logic goes and skips over the skill name to find any + * options given to the skill. Its pretty simple - if there + * are extra parameters (as deteremined by string length), we + * want to skip over any leading spaces. + */ + if (len >= strlen (string)) + { + string = NULL; } - + else + { + string += len; + while (*string == 0x20) + string++; + if (strlen (string) == 0) + string = NULL; + } + #ifdef SKILL_UTIL_DEBUG - LOG(llevDebug,"use_skill() got skill: %s\n",sknum>-1?skills[sknum].name:"none"); + LOG (llevDebug, "use_skill() got skill: %s\n", sknum > -1 ? skills[sknum].name : "none"); #endif - /* Change to the new skill, then execute it. */ - if(do_skill(op,op,skop, op->facing,string)) return 1; - - return 0; + /* Change to the new skill, then execute it. */ + if (do_skill (op, op, skop, op->facing, string)) + return 1; + + return 0; } @@ -796,33 +892,40 @@ * combat. If everyone race/class should have one, this should * be handled in the starting treasurelists, not in the code. */ -static object *find_best_player_hth_skill(object *op) +static object * +find_best_player_hth_skill (object *op) { - object *tmp, *best_skill=NULL; - int dragon = is_dragon_pl(op), last_skill=sizeof(unarmed_skills), i; + object *tmp, *best_skill = NULL; + int dragon = is_dragon_pl (op), last_skill = sizeof (unarmed_skills), i; - for (tmp=op->inv; tmp; tmp=tmp->below) { - if (tmp->type == SKILL) { - if (dragon && tmp->subtype == SK_CLAWING) return tmp; - - /* The order in the array is preferred order. So basically, - * we just cut down the number to search - eg, if we find a skill - * early on in flame touch, then we only need to look into the unarmed_array - * to the entry before flame touch - don't care about the entries afterward, - * because they are infrerior skills. - * if we end up finding the best skill (i==0) might as well return - * right away - can't get any better than that. - */ - for (i=0; isubtype == unarmed_skills[i] && QUERY_FLAG(tmp, FLAG_CAN_USE_SKILL)) { - best_skill = tmp; - last_skill = i; - if (i==0) return best_skill; + for (tmp = op->inv; tmp; tmp = tmp->below) + { + if (tmp->type == SKILL) + { + if (dragon && tmp->subtype == SK_CLAWING) + return tmp; + + /* The order in the array is preferred order. So basically, + * we just cut down the number to search - eg, if we find a skill + * early on in flame touch, then we only need to look into the unarmed_array + * to the entry before flame touch - don't care about the entries afterward, + * because they are infrerior skills. + * if we end up finding the best skill (i==0) might as well return + * right away - can't get any better than that. + */ + for (i = 0; i < last_skill; i++) + { + if (tmp->subtype == unarmed_skills[i] && QUERY_FLAG (tmp, FLAG_CAN_USE_SKILL)) + { + best_skill = tmp; + last_skill = i; + if (i == 0) + return best_skill; } } } } - return best_skill; + return best_skill; } /* do_skill_attack() - We have got an appropriate opponent from either @@ -834,104 +937,121 @@ * string is passed along to describe what messages to describe * the damage. */ - -static int do_skill_attack(object *tmp, object *op, const char *string, object *skill) { - int success; - - if (INVOKE_OBJECT (SKILL_ATTACK, op, ARG_OBJECT (tmp), ARG_STRING (string), ARG_OBJECT (skill))) - return RESULT_INT (0); - - /* For Players only: if there is no ready weapon, and no "attack" skill - * is readied either then try to find a skill for the player to use. - * it is presumed that if skill is set, it is a valid attack skill (eg, - * the caller should have set it appropriately). We still want to pass - * through that code if skill is set to change to the skill. - */ - if(op->type==PLAYER) { - if (!QUERY_FLAG(op,FLAG_READY_WEAPON)) { - size_t i; - - if (!skill) { - /* See if the players chosen skill is a combat skill, and use - * it if appropriate. - */ - if (op->chosen_skill) { - for (i=0; ichosen_skill->subtype == unarmed_skills[i]) { - skill = op->chosen_skill; - break; - } + +static int +do_skill_attack (object *tmp, object *op, const char *string, object *skill) +{ + int success; + + if (INVOKE_OBJECT (SKILL_ATTACK, op, ARG_OBJECT (tmp), ARG_STRING (string), ARG_OBJECT (skill))) + return RESULT_INT (0); + + /* For Players only: if there is no ready weapon, and no "attack" skill + * is readied either then try to find a skill for the player to use. + * it is presumed that if skill is set, it is a valid attack skill (eg, + * the caller should have set it appropriately). We still want to pass + * through that code if skill is set to change to the skill. + */ + if (op->type == PLAYER) + { + if (!QUERY_FLAG (op, FLAG_READY_WEAPON)) + { + size_t i; + + if (!skill) + { + /* See if the players chosen skill is a combat skill, and use + * it if appropriate. + */ + if (op->chosen_skill) + { + for (i = 0; i < sizeof (unarmed_skills); i++) + if (op->chosen_skill->subtype == unarmed_skills[i]) + { + skill = op->chosen_skill; + break; + } } - /* If we didn't find a skill above, look harder for a good skill */ - if (!skill) { - skill = find_best_player_hth_skill(op); - - if (!skill) { - new_draw_info(NDI_BLACK, 0, op, "You have no unarmed combat skills!"); - return 0; + /* If we didn't find a skill above, look harder for a good skill */ + if (!skill) + { + skill = find_best_player_hth_skill (op); + + if (!skill) + { + new_draw_info (NDI_BLACK, 0, op, "You have no unarmed combat skills!"); + return 0; } } } - if (skill != op->chosen_skill) { - /* now try to ready the new skill */ - if(!change_skill(op,skill,0)) { /* oh oh, trouble! */ - new_draw_info_format(NDI_UNIQUE, 0, tmp, "Couldn't change to skill %s", &skill->name); - return 0; + if (skill != op->chosen_skill) + { + /* now try to ready the new skill */ + if (!change_skill (op, skill, 0)) + { /* oh oh, trouble! */ + new_draw_info_format (NDI_UNIQUE, 0, tmp, "Couldn't change to skill %s", &skill->name); + return 0; } } - } else { - /* Seen some crashes below where current_weapon is not set, - * even though the flag says it is. So if current weapon isn't set, - * do some work in trying to find the object to use. - */ - if (!op->current_weapon) { - object *tmp; - - LOG(llevError,"Player %s does not have current weapon set but flag_ready_weapon is set\n", - &op->name); - for (tmp=op->inv; tmp; tmp=tmp->below) - if (tmp->type == WEAPON && QUERY_FLAG(tmp, FLAG_APPLIED)) break; - - if (!tmp) { - LOG(llevError,"Could not find applied weapon on %s\n", - &op->name); - op->current_weapon=NULL; - return 0; - } else { - op->current_weapon = tmp; + } + else + { + /* Seen some crashes below where current_weapon is not set, + * even though the flag says it is. So if current weapon isn't set, + * do some work in trying to find the object to use. + */ + if (!op->current_weapon) + { + object *tmp; + + LOG (llevError, "Player %s does not have current weapon set but flag_ready_weapon is set\n", &op->name); + for (tmp = op->inv; tmp; tmp = tmp->below) + if (tmp->type == WEAPON && QUERY_FLAG (tmp, FLAG_APPLIED)) + break; + + if (!tmp) + { + LOG (llevError, "Could not find applied weapon on %s\n", &op->name); + op->current_weapon = NULL; + return 0; + } + else + { + op->current_weapon = tmp; } } - /* Has ready weapon - make sure chosen_skill is set up properly */ - if (!op->chosen_skill || op->current_weapon->skill != op->chosen_skill->skill) { - change_skill(op, find_skill_by_name(op, op->current_weapon->skill), 1); + /* Has ready weapon - make sure chosen_skill is set up properly */ + if (!op->chosen_skill || op->current_weapon->skill != op->chosen_skill->skill) + { + change_skill (op, find_skill_by_name (op, op->current_weapon->skill), 1); } } } - /* lose invisiblity/hiding status for running attacks */ - - if(op->type==PLAYER && op->contr->tmp_invis) { - op->contr->tmp_invis=0; - op->invisible=0; - op->hide=0; - update_object(op,UP_OBJ_FACE); - } - - success = attack_ob(tmp,op); - - /* print appropriate messages to the player */ - - if(success && string!=NULL && tmp && !QUERY_FLAG(tmp,FLAG_FREED)) { - if(op->type==PLAYER) - new_draw_info_format(NDI_UNIQUE, 0,op, - "You %s %s!",string,query_name(tmp)); - else if(tmp->type==PLAYER) - new_draw_info_format(NDI_UNIQUE, 0,tmp, - "%s %s you!",query_name(op),string); + /* lose invisiblity/hiding status for running attacks */ + + if (op->type == PLAYER && op->contr->tmp_invis) + { + op->contr->tmp_invis = 0; + op->invisible = 0; + op->hide = 0; + update_object (op, UP_OBJ_FACE); } - return success; -} + + success = attack_ob (tmp, op); + + /* print appropriate messages to the player */ + + if (success && string != NULL && tmp && !QUERY_FLAG (tmp, FLAG_FREED)) + { + if (op->type == PLAYER) + new_draw_info_format (NDI_UNIQUE, 0, op, "You %s %s!", string, query_name (tmp)); + else if (tmp->type == PLAYER) + new_draw_info_format (NDI_UNIQUE, 0, tmp, "%s %s you!", query_name (op), string); + } + return success; +} /* skill_attack() - Core routine for use when we attack using a skills @@ -945,75 +1065,86 @@ * * Initial implementation by -bt thomas@astro.psu.edu */ - -int skill_attack (object *tmp, object *pl, int dir, const char *string, object *skill) { - sint16 tx,ty; - mapstruct *m; - int mflags; - - if(!dir) dir=pl->facing; - tx=freearr_x[dir]; - ty=freearr_y[dir]; - - /* If we don't yet have an opponent, find if one exists, and attack. - * Legal opponents are the same as outlined in move_player_attack() - */ - - if(tmp==NULL) { - m = pl->map; - tx = pl->x + freearr_x[dir]; - ty = pl->y + freearr_y[dir]; - - mflags = get_map_flags(m, &m, tx, ty, &tx, &ty); - if (mflags & P_OUT_OF_MAP) return 0; - - /* space must be blocked for there to be anything interesting to do */ - if (!OB_TYPE_MOVE_BLOCK(pl, GET_MAP_MOVE_BLOCK(m, tx,ty))) return 0; - - for(tmp=get_map_ob(m, tx, ty); tmp; tmp=tmp->above) - if((QUERY_FLAG(tmp,FLAG_ALIVE) && tmp->stats.hp>=0) - || QUERY_FLAG(tmp, FLAG_CAN_ROLL) - || tmp->type==LOCKED_DOOR ) { - /* Don't attack party members */ - if((pl->type==PLAYER && tmp->type==PLAYER) && (pl->contr->party!=NULL - && pl->contr->party==tmp->contr->party)) - return 0; - break; - } - } - if (!tmp) { - if(pl->type==PLAYER) - new_draw_info(NDI_UNIQUE, 0,pl,"There is nothing to attack!"); + +int +skill_attack (object *tmp, object *pl, int dir, const char *string, object *skill) +{ + sint16 tx, ty; + mapstruct *m; + int mflags; + + if (!dir) + dir = pl->facing; + tx = freearr_x[dir]; + ty = freearr_y[dir]; + + /* If we don't yet have an opponent, find if one exists, and attack. + * Legal opponents are the same as outlined in move_player_attack() + */ + + if (tmp == NULL) + { + m = pl->map; + tx = pl->x + freearr_x[dir]; + ty = pl->y + freearr_y[dir]; + + mflags = get_map_flags (m, &m, tx, ty, &tx, &ty); + if (mflags & P_OUT_OF_MAP) + return 0; + + /* space must be blocked for there to be anything interesting to do */ + if (!OB_TYPE_MOVE_BLOCK (pl, GET_MAP_MOVE_BLOCK (m, tx, ty))) return 0; + + for (tmp = get_map_ob (m, tx, ty); tmp; tmp = tmp->above) + if ((QUERY_FLAG (tmp, FLAG_ALIVE) && tmp->stats.hp >= 0) || QUERY_FLAG (tmp, FLAG_CAN_ROLL) || tmp->type == LOCKED_DOOR) + { + /* Don't attack party members */ + if ((pl->type == PLAYER && tmp->type == PLAYER) && (pl->contr->party != NULL && pl->contr->party == tmp->contr->party)) + return 0; + break; + } + } + if (!tmp) + { + if (pl->type == PLAYER) + new_draw_info (NDI_UNIQUE, 0, pl, "There is nothing to attack!"); + return 0; } - return do_skill_attack(tmp,pl,string, skill); + return do_skill_attack (tmp, pl, string, skill); } /* attack_hth() - this handles all hand-to-hand attacks -b.t. */ + /* 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. */ -static int attack_hth(object *pl, int dir, const char *string, object *skill) { - object *enemy=NULL,*weapon; +static int +attack_hth (object *pl, int dir, const char *string, object *skill) +{ + object *enemy = NULL, *weapon; - if(QUERY_FLAG(pl, FLAG_READY_WEAPON)) - for(weapon=pl->inv;weapon;weapon=weapon->below) { - if (weapon->type==WEAPON && QUERY_FLAG(weapon, FLAG_APPLIED)) { - CLEAR_FLAG(weapon,FLAG_APPLIED); - CLEAR_FLAG(pl,FLAG_READY_WEAPON); - fix_player(pl); - if(pl->type==PLAYER) { - new_draw_info(NDI_UNIQUE, 0,pl,"You unwield your weapon in order to attack."); - esrv_update_item(UPD_FLAGS, pl, weapon); - } - break; - } - } - return skill_attack(enemy,pl,dir,string, skill); + if (QUERY_FLAG (pl, FLAG_READY_WEAPON)) + for (weapon = pl->inv; weapon; weapon = weapon->below) + { + if (weapon->type == WEAPON && QUERY_FLAG (weapon, FLAG_APPLIED)) + { + CLEAR_FLAG (weapon, FLAG_APPLIED); + CLEAR_FLAG (pl, FLAG_READY_WEAPON); + fix_player (pl); + if (pl->type == PLAYER) + { + new_draw_info (NDI_UNIQUE, 0, pl, "You unwield your weapon in order to attack."); + esrv_update_item (UPD_FLAGS, pl, weapon); + } + break; + } + } + return skill_attack (enemy, pl, dir, string, skill); } @@ -1027,13 +1158,16 @@ * weapon type. */ -static int attack_melee_weapon(object *op, int dir, const char *string, object *skill) { +static int +attack_melee_weapon (object *op, int dir, const char *string, object *skill) +{ - if(!QUERY_FLAG(op, FLAG_READY_WEAPON)) { - if(op->type==PLAYER) - new_draw_info(NDI_UNIQUE, 0,op,"You have no ready weapon to attack with!"); - return 0; + if (!QUERY_FLAG (op, FLAG_READY_WEAPON)) + { + if (op->type == PLAYER) + new_draw_info (NDI_UNIQUE, 0, op, "You have no ready weapon to attack with!"); + return 0; } - return skill_attack(NULL,op,dir,string, skill); + return skill_attack (NULL, op, dir, string, skill); }