diff --git a/src/act.movement.c b/src/act.movement.c index a1ba0de..9afd977 100644 --- a/src/act.movement.c +++ b/src/act.movement.c @@ -570,6 +570,7 @@ static void do_doorcmd(struct char_data *ch, struct obj_data *obj, int door, int TOGGLE_LOCK(other_room, obj, rev_dir[door]); send_to_char(ch, "The lock quickly yields to your skills.\r\n"); len = strlcpy(buf, "$n skillfully picks the lock on ", sizeof(buf)); + gain_skill(ch, "pick lock", TRUE); break; } @@ -597,14 +598,19 @@ static int ok_pick(struct char_data *ch, obj_vnum keynum, int pickproof, int scm percent = rand_number(1, 101); skill_lvl = GET_SKILL(ch, SKILL_PICK_LOCK) + dex_app_skill[GET_DEX(ch)].p_locks; - if (keynum == NOTHING) + if (keynum == NOTHING) { send_to_char(ch, "Odd - you can't seem to find a keyhole.\r\n"); - else if (pickproof) + } + else if (pickproof) { send_to_char(ch, "It resists your attempts to pick it.\r\n"); - else if (percent > skill_lvl) + } + else if (percent > skill_lvl) { send_to_char(ch, "You failed to pick the lock.\r\n"); - else + gain_skill(ch, "pick lock", FALSE); + } + else { return (1); + } return (0); } diff --git a/src/act.offensive.c b/src/act.offensive.c index b66ac8d..2ba3662 100644 --- a/src/act.offensive.c +++ b/src/act.offensive.c @@ -167,10 +167,13 @@ ACMD(do_backstab) percent = rand_number(1, 101); /* 101% is a complete failure */ prob = GET_SKILL(ch, SKILL_BACKSTAB); - if (AWAKE(vict) && (percent > prob)) + if (AWAKE(vict) && (percent > prob)) { damage(ch, vict, 0, SKILL_BACKSTAB); - else + gain_skill(ch, "backstab", FALSE); + } else { hit(ch, vict, SKILL_BACKSTAB); + gain_skill(ch, "backstab", TRUE); + } WAIT_STATE(ch, 2 * PULSE_VIOLENCE); } @@ -256,7 +259,7 @@ ACMD(do_flee) if (was_fighting && ch == FIGHTING(was_fighting)) stop_fighting(was_fighting); } else { - act("$n tries to flee, but can't!", TRUE, ch, 0, 0, TO_ROOM); + act("$n tries to flee, but can't!", TRUE, ch, 0, 0, TO_ROOM); } return; } @@ -310,6 +313,7 @@ ACMD(do_bash) if (percent > prob) { damage(ch, vict, 0, SKILL_BASH); GET_POS(ch) = POS_SITTING; + gain_skill(ch, "bash", FALSE); } else { /* * If we bash a player and they wimp out, they will move to the previous @@ -319,8 +323,10 @@ ACMD(do_bash) */ if (damage(ch, vict, 1, SKILL_BASH) > 0) { /* -1 = dead, 0 = miss */ WAIT_STATE(vict, PULSE_VIOLENCE); - if (IN_ROOM(ch) == IN_ROOM(vict)) + if (IN_ROOM(ch) == IN_ROOM(vict)) { GET_POS(vict) = POS_SITTING; + gain_skill(ch, "bash", TRUE); + } } } WAIT_STATE(ch, PULSE_VIOLENCE * 2); @@ -371,6 +377,7 @@ ACMD(do_rescue) if (percent > prob) { send_to_char(ch, "You fail the rescue!\r\n"); + gain_skill(ch, "rescue", FALSE); return; } send_to_char(ch, "Banzai! To the rescue...\r\n"); @@ -381,8 +388,10 @@ ACMD(do_rescue) stop_fighting(vict); if (FIGHTING(tmp_ch)) stop_fighting(tmp_ch); - if (FIGHTING(ch)) + if (FIGHTING(ch)) { stop_fighting(ch); + gain_skill(ch, "rescue", TRUE); + } set_fighting(ch, tmp_ch); set_fighting(tmp_ch, ch); @@ -396,6 +405,7 @@ EVENTFUNC(event_whirlwind) struct mud_event_data *pMudEvent; struct list_data *room_list; int count; + int roll; /* This is just a dummy check, but we'll do it anyway */ if (event_obj == NULL) @@ -432,6 +442,10 @@ EVENTFUNC(event_whirlwind) for (count = dice(1, 4); count > 0; count--) { tch = random_from_list(room_list); hit(ch, tch, TYPE_UNDEFINED); + roll = rand_number(1, 20); + if (roll >= 20) { + gain_skill(ch, "whirlwind", FALSE); /* on a critical success, give whirlwind a chance to gain */ + } } /* Now that our attack is done, let's free out list */ @@ -518,8 +532,11 @@ ACMD(do_kick) if (percent > prob) { damage(ch, vict, 0, SKILL_KICK); - } else + gain_skill(ch, "kick", FALSE); + } else { damage(ch, vict, GET_LEVEL(ch) / 2, SKILL_KICK); + gain_skill(ch, "kick", TRUE); + } WAIT_STATE(ch, PULSE_VIOLENCE * 3); } @@ -563,6 +580,7 @@ ACMD(do_bandage) act("$n tries to bandage $N, but fails miserably.", TRUE, ch, 0, vict, TO_NOTVICT); damage(vict, vict, 2, TYPE_SUFFERING); + gain_skill(ch, "bandage", FALSE); return; } @@ -572,4 +590,5 @@ ACMD(do_bandage) act("Someone bandages you, and you feel a bit better now.", FALSE, ch, 0, vict, TO_VICT); GET_HIT(vict) = 0; + gain_skill(ch, "bandage", TRUE); } diff --git a/src/act.other.c b/src/act.other.c index 7dd6205..3e16168 100644 --- a/src/act.other.c +++ b/src/act.other.c @@ -111,14 +111,17 @@ ACMD(do_sneak) percent = rand_number(1, 101); /* 101% is a complete failure */ - if (percent > GET_SKILL(ch, SKILL_SNEAK) + dex_app_skill[GET_DEX(ch)].sneak) + if (percent > GET_SKILL(ch, SKILL_SNEAK) + dex_app_skill[GET_DEX(ch)].sneak){ + gain_skill(ch, "sneak", FALSE); return; - - new_affect(&af); - af.spell = SKILL_SNEAK; - af.duration = GET_LEVEL(ch); - SET_BIT_AR(af.bitvector, AFF_SNEAK); - affect_to_char(ch, &af); + } else { + new_affect(&af); + af.spell = SKILL_SNEAK; + af.duration = GET_LEVEL(ch); + SET_BIT_AR(af.bitvector, AFF_SNEAK); + affect_to_char(ch, &af); + gain_skill(ch, "sneak", TRUE); + } } ACMD(do_hide) @@ -137,10 +140,13 @@ ACMD(do_hide) percent = rand_number(1, 101); /* 101% is a complete failure */ - if (percent > GET_SKILL(ch, SKILL_HIDE) + dex_app_skill[GET_DEX(ch)].hide) + if (percent > GET_SKILL(ch, SKILL_HIDE) + dex_app_skill[GET_DEX(ch)].hide){ + gain_skill(ch, "hide", FALSE); return; - - SET_BIT_AR(AFF_FLAGS(ch), AFF_HIDE); + } else { + SET_BIT_AR(AFF_FLAGS(ch), AFF_HIDE); + send_to_char(ch, "You hide yourself as best you can.\r\n"); + } } ACMD(do_steal) @@ -219,16 +225,16 @@ ACMD(do_steal) percent += GET_OBJ_WEIGHT(obj); /* Make heavy harder */ if (percent > GET_SKILL(ch, SKILL_STEAL)) { - ohoh = TRUE; - send_to_char(ch, "Oops..\r\n"); - act("$n tried to steal something from you!", FALSE, ch, 0, vict, TO_VICT); - act("$n tries to steal something from $N.", TRUE, ch, 0, vict, TO_NOTVICT); + ohoh = TRUE; + send_to_char(ch, "Oops..\r\n"); + act("$n tried to steal something from you!", FALSE, ch, 0, vict, TO_VICT); + act("$n tries to steal something from $N.", TRUE, ch, 0, vict, TO_NOTVICT); + gain_skill(ch, "steal", FALSE); } else { /* Steal the item */ - if (IS_CARRYING_N(ch) + 1 < CAN_CARRY_N(ch)) { - if (!give_otrigger(obj, vict, ch) || - !receive_mtrigger(ch, vict, obj) ) { - send_to_char(ch, "Impossible!\r\n"); - return; + if (IS_CARRYING_N(ch) + 1 < CAN_CARRY_N(ch)) { + if (!give_otrigger(obj, vict, ch) || !receive_mtrigger(ch, vict, obj) ) { + send_to_char(ch, "Impossible!\r\n"); + return; } if (IS_CARRYING_W(ch) + GET_OBJ_WEIGHT(obj) < CAN_CARRY_W(ch)) { obj_from_char(obj); @@ -245,20 +251,22 @@ ACMD(do_steal) send_to_char(ch, "Oops..\r\n"); act("You discover that $n has $s hands in your wallet.", FALSE, ch, 0, vict, TO_VICT); act("$n tries to steal gold from $N.", TRUE, ch, 0, vict, TO_NOTVICT); + gain_skill(ch, "steal", FALSE); } else { /* Steal some gold coins */ gold = (GET_GOLD(vict) * rand_number(1, 10)) / 100; gold = MIN(1782, gold); if (gold > 0) { - increase_gold(ch, gold); - decrease_gold(vict, gold); + increase_gold(ch, gold); + decrease_gold(vict, gold); + gain_skill(ch, "steal", TRUE); if (gold > 1) - send_to_char(ch, "Bingo! You got %d gold coins.\r\n", gold); - else - send_to_char(ch, "You manage to swipe a solitary gold coin.\r\n"); - } else { - send_to_char(ch, "You couldn't get any gold...\r\n"); - } + send_to_char(ch, "Bingo! You got %d gold coins.\r\n", gold); + else + send_to_char(ch, "You manage to swipe a solitary gold coin.\r\n"); + } else { + send_to_char(ch, "You couldn't get any gold...\r\n"); + } } } diff --git a/src/graph.c b/src/graph.c index 08670a0..b0636f9 100644 --- a/src/graph.c +++ b/src/graph.c @@ -173,11 +173,13 @@ ACMD(do_track) dir = rand_number(0, DIR_COUNT - 1); } while (!CAN_GO(ch, dir) && --tries); send_to_char(ch, "You sense a trail %s from here!\r\n", dirs[dir]); + gain_skill(ch, "track", FALSE); return; } /* They passed the skill check. */ dir = find_first_step(IN_ROOM(ch), IN_ROOM(vict)); + gain_skill(ch, "track", TRUE); switch (dir) { case BFS_ERROR: diff --git a/src/limits.c b/src/limits.c index 4796464..6fe0259 100644 --- a/src/limits.c +++ b/src/limits.c @@ -12,6 +12,7 @@ #include "sysdep.h" #include "structs.h" #include "utils.h" +#include "constants.h" #include "spells.h" #include "comm.h" #include "db.h" @@ -220,6 +221,34 @@ void run_autowiz(void) #endif /* CIRCLE_UNIX || CIRCLE_WINDOWS */ } +void gain_skill(struct char_data *ch, char *skill, bool success) +{ + int skill_num, base, roll, increase; + + if (IS_NPC(ch)) + return; + + skill_num = find_skill_num(skill); + if (skill_num <= 0) + return; + + base = GET_SKILL(ch, skill_num); + + if (success) { /* learning from successes is more difficult */ + roll = rand_number(1, 400); + if (roll >= (400 - (wis_app[GET_WIS(ch)].bonus) * 4)) { + increase = base + 1; + SET_SKILL(ch, skill_num, MIN(90, increase)); + } + } else { /* learning from failures is easier */ + roll = rand_number(1, 100); + if (roll >= (100 - wis_app[GET_WIS(ch)].bonus)) { + increase = base + 1; + SET_SKILL(ch, skill_num, MIN(90, increase)); + } + } +} + void gain_exp(struct char_data *ch, int gain) { int is_altered = FALSE; diff --git a/src/spell_parser.c b/src/spell_parser.c index dd2f7f7..f835d79 100644 --- a/src/spell_parser.c +++ b/src/spell_parser.c @@ -627,6 +627,7 @@ ACMD(do_cast) { /* You throws the dice and you takes your chances.. 101% is total failure */ if (rand_number(0, 101) > GET_SKILL(ch, spellnum)) { WAIT_STATE(ch, PULSE_VIOLENCE); + gain_skill(ch, s, FALSE); if (!tch || !skill_message(0, ch, tch, spellnum)) send_to_char(ch, "You lost your concentration!\r\n"); if (mana > 0) @@ -636,6 +637,7 @@ ACMD(do_cast) { } else { /* cast spell returns 1 on success; subtract mana & set waitstate */ if (cast_spell(ch, tch, tobj, spellnum)) { WAIT_STATE(ch, PULSE_VIOLENCE); + gain_skill(ch, s, TRUE); if (mana > 0) GET_MANA(ch) = MAX(0, MIN(GET_MAX_MANA(ch), GET_MANA(ch) - mana)); } diff --git a/src/utils.h b/src/utils.h index fe97d02..ebd16e9 100644 --- a/src/utils.h +++ b/src/utils.h @@ -130,6 +130,7 @@ void set_title(struct char_data *ch, char *title); void gain_exp(struct char_data *ch, int gain); void gain_exp_regardless(struct char_data *ch, int gain); void gain_condition(struct char_data *ch, int condition, int value); +void gain_skill(struct char_data *ch, char *skill, bool failure); void point_update(void); void update_pos(struct char_data *victim); void run_autowiz(void);