mirror of
https://github.com/tbamud/tbamud.git
synced 2026-03-24 21:26:35 +01:00
Update skills for 5e system
This commit is contained in:
parent
0815cd6a96
commit
17d6221510
13 changed files with 474 additions and 143 deletions
|
|
@ -234,6 +234,7 @@ ACMD(do_report);
|
|||
ACMD(do_save);
|
||||
ACMD(do_skills);
|
||||
ACMD(do_sneak);
|
||||
ACMD(do_perception);
|
||||
ACMD(do_split);
|
||||
ACMD(do_steal);
|
||||
ACMD(do_title);
|
||||
|
|
|
|||
|
|
@ -126,7 +126,9 @@ ACMD(do_backstab)
|
|||
{
|
||||
char buf[MAX_INPUT_LENGTH];
|
||||
struct char_data *vict;
|
||||
int percent, prob;
|
||||
struct obj_data *weap;
|
||||
int roll, atk_bonus, total, target_ac;
|
||||
bool crit_success = FALSE, crit_fail = FALSE;
|
||||
|
||||
if (IS_NPC(ch) || !GET_SKILL(ch, SKILL_BACKSTAB)) {
|
||||
send_to_char(ch, "You have no idea how to do that.\r\n");
|
||||
|
|
@ -143,11 +145,12 @@ ACMD(do_backstab)
|
|||
send_to_char(ch, "How can you sneak up on yourself?\r\n");
|
||||
return;
|
||||
}
|
||||
if (!GET_EQ(ch, WEAR_WIELD)) {
|
||||
if (!(weap = GET_EQ(ch, WEAR_WIELD))) {
|
||||
send_to_char(ch, "You need to wield a weapon to make it a success.\r\n");
|
||||
return;
|
||||
}
|
||||
if (GET_OBJ_VAL(GET_EQ(ch, WEAR_WIELD), 3) != TYPE_PIERCE - TYPE_HIT) {
|
||||
/* Only piercing weapons allowed */
|
||||
if (GET_OBJ_VAL(weap, 3) != TYPE_PIERCE - TYPE_HIT) {
|
||||
send_to_char(ch, "Only piercing weapons can be used for backstabbing.\r\n");
|
||||
return;
|
||||
}
|
||||
|
|
@ -164,15 +167,50 @@ ACMD(do_backstab)
|
|||
return;
|
||||
}
|
||||
|
||||
percent = rand_number(1, 101); /* 101% is a complete failure */
|
||||
prob = GET_SKILL(ch, SKILL_BACKSTAB);
|
||||
/* --- d20 vs ascending AC --- */
|
||||
atk_bonus = GET_ABILITY_MOD(GET_DEX(ch)) +
|
||||
GET_PROFICIENCY(GET_SKILL(ch, SKILL_BACKSTAB));
|
||||
|
||||
roll = rand_number(1, 20);
|
||||
crit_fail = (roll == 1);
|
||||
crit_success = (roll == 20);
|
||||
|
||||
total = roll + atk_bonus;
|
||||
target_ac = compute_ascending_ac(vict);
|
||||
|
||||
if (!crit_fail && (crit_success || total >= target_ac)) {
|
||||
/* Successful backstab */
|
||||
act("You slip behind $N and drive your weapon home!", TRUE, ch, 0, vict, TO_CHAR);
|
||||
act("$n slips behind you and drives a weapon into your back!", TRUE, ch, 0, vict, TO_VICT);
|
||||
act("$n slips behind $N and drives a weapon home!", TRUE, ch, 0, vict, TO_NOTVICT);
|
||||
|
||||
/* Keeping this logic really simple so it can be adjusted later if need be */
|
||||
if (crit_success) {
|
||||
/* Simple crit = 2x damage */
|
||||
int base = dice(GET_OBJ_VAL(weap, 1), GET_OBJ_VAL(weap, 2));
|
||||
int dmg = base + GET_ABILITY_MOD(GET_DEX(ch));
|
||||
if (dmg < 1) dmg = 1;
|
||||
dmg *= 2;
|
||||
damage(ch, vict, dmg, SKILL_BACKSTAB);
|
||||
} else {
|
||||
/* Hit but not crit = 1.5x damage */
|
||||
int base = dice(GET_OBJ_VAL(weap, 1), GET_OBJ_VAL(weap, 2));
|
||||
int dmg = base + GET_ABILITY_MOD(GET_DEX(ch));
|
||||
if (dmg < 1) dmg = 1;
|
||||
dmg *= 1.5;
|
||||
damage(ch, vict, dmg, SKILL_BACKSTAB);
|
||||
}
|
||||
|
||||
gain_skill(ch, "backstab", TRUE);
|
||||
|
||||
} else {
|
||||
/* Missed backstab */
|
||||
act("You lunge at $N, but miss the mark.", TRUE, ch, 0, vict, TO_CHAR);
|
||||
act("$n lunges at you, but misses the mark!", TRUE, ch, 0, vict, TO_VICT);
|
||||
act("$n lunges at $N, but misses the mark!", TRUE, ch, 0, vict, TO_NOTVICT);
|
||||
|
||||
if (AWAKE(vict) && (percent > prob)) {
|
||||
damage(ch, vict, 0, SKILL_BACKSTAB);
|
||||
gain_skill(ch, "backstab", FALSE);
|
||||
} else {
|
||||
hit(ch, vict, SKILL_BACKSTAB);
|
||||
gain_skill(ch, "backstab", TRUE);
|
||||
}
|
||||
|
||||
WAIT_STATE(ch, 2 * PULSE_VIOLENCE);
|
||||
|
|
@ -271,7 +309,8 @@ ACMD(do_bash)
|
|||
{
|
||||
char arg[MAX_INPUT_LENGTH];
|
||||
struct char_data *vict;
|
||||
int percent, prob;
|
||||
int roll, atk_bonus, total, target_ac;
|
||||
bool crit_success = FALSE, crit_fail = FALSE;
|
||||
|
||||
one_argument(argument, arg);
|
||||
|
||||
|
|
@ -304,31 +343,59 @@ ACMD(do_bash)
|
|||
return;
|
||||
}
|
||||
|
||||
percent = rand_number(1, 101); /* 101% is a complete failure */
|
||||
prob = GET_SKILL(ch, SKILL_BASH);
|
||||
/* --- 5e-like attack roll vs ascending AC --- */
|
||||
atk_bonus = GET_ABILITY_MOD(GET_STR(ch)) +
|
||||
GET_PROFICIENCY(GET_SKILL(ch, SKILL_BASH));
|
||||
|
||||
roll = rand_number(1, 20);
|
||||
crit_success = (roll == 1);
|
||||
crit_fail = (roll == 20);
|
||||
|
||||
total = roll + atk_bonus;
|
||||
target_ac = compute_ascending_ac(vict);
|
||||
|
||||
/* Some mobs simply can't be bashed: force a miss like legacy code did. */
|
||||
if (MOB_FLAGGED(vict, MOB_NOBASH))
|
||||
percent = 101;
|
||||
crit_fail = TRUE;
|
||||
|
||||
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
|
||||
* room before we set them sitting. If we try to set the victim sitting
|
||||
* first to make sure they don't flee, then we can't bash them! So now
|
||||
* we only set them sitting if they didn't flee. -gg 9/21/98
|
||||
*/
|
||||
if (damage(ch, vict, 1, SKILL_BASH) > 0) { /* -1 = dead, 0 = miss */
|
||||
WAIT_STATE(vict, PULSE_VIOLENCE);
|
||||
if (!crit_fail && (crit_success || total >= target_ac)) {
|
||||
/* ---- HIT: small damage + knockdown ---- */
|
||||
|
||||
/* Damage = 1 + STR mod (min 1); double on crit */
|
||||
int dmg = 1 + GET_ABILITY_MOD(GET_STR(ch));
|
||||
if (dmg < 1) dmg = 1;
|
||||
if (crit_success) dmg *= 2;
|
||||
|
||||
if (crit_success) {
|
||||
act("You slam into $N with a crushing bash!", TRUE, ch, 0, vict, TO_CHAR);
|
||||
act("$n slams into you with a crushing bash!", TRUE, ch, 0, vict, TO_VICT);
|
||||
act("$n slams into $N with a crushing bash!", TRUE, ch, 0, vict, TO_NOTVICT);
|
||||
} else {
|
||||
act("You bash $N off balance.", TRUE, ch, 0, vict, TO_CHAR);
|
||||
act("$n bashes you off balance.", TRUE, ch, 0, vict, TO_VICT);
|
||||
act("$n bashes $N off balance.", TRUE, ch, 0, vict, TO_NOTVICT);
|
||||
}
|
||||
|
||||
/* Apply damage; legacy: >0 means still alive & not a pure miss */
|
||||
if (damage(ch, vict, dmg, SKILL_BASH) > 0) {
|
||||
WAIT_STATE(vict, PULSE_VIOLENCE); /* brief stun */
|
||||
if (IN_ROOM(ch) == IN_ROOM(vict)) {
|
||||
GET_POS(vict) = POS_SITTING;
|
||||
GET_POS(vict) = POS_SITTING; /* knockdown */
|
||||
gain_skill(ch, "bash", TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
/* ---- MISS: you eat the floor (attacker sits) ---- */
|
||||
act("You miss your bash at $N and lose your footing!", TRUE, ch, 0, vict, TO_CHAR);
|
||||
act("$n misses a bash at you and loses $s footing!", TRUE, ch, 0, vict, TO_VICT);
|
||||
act("$n misses a bash at $N and loses $s footing!", TRUE, ch, 0, vict, TO_NOTVICT);
|
||||
|
||||
damage(ch, vict, 0, SKILL_BASH);
|
||||
GET_POS(ch) = POS_SITTING;
|
||||
gain_skill(ch, "bash", FALSE);
|
||||
}
|
||||
|
||||
WAIT_STATE(ch, PULSE_VIOLENCE * 2);
|
||||
}
|
||||
|
||||
|
|
@ -336,7 +403,7 @@ ACMD(do_rescue)
|
|||
{
|
||||
char arg[MAX_INPUT_LENGTH];
|
||||
struct char_data *vict, *tmp_ch;
|
||||
int percent, prob;
|
||||
int roll, bonus, total, dc;
|
||||
|
||||
if (IS_NPC(ch) || !GET_SKILL(ch, SKILL_RESCUE)) {
|
||||
send_to_char(ch, "You have no idea how to do that.\r\n");
|
||||
|
|
@ -357,29 +424,40 @@ ACMD(do_rescue)
|
|||
send_to_char(ch, "How can you rescue someone you are trying to kill?\r\n");
|
||||
return;
|
||||
}
|
||||
for (tmp_ch = world[IN_ROOM(ch)].people; tmp_ch &&
|
||||
(FIGHTING(tmp_ch) != vict); tmp_ch = tmp_ch->next_in_room);
|
||||
|
||||
/* Find someone who is fighting the victim */
|
||||
for (tmp_ch = world[IN_ROOM(ch)].people; tmp_ch && (FIGHTING(tmp_ch) != vict); tmp_ch = tmp_ch->next_in_room)
|
||||
;
|
||||
|
||||
/* Handle the “already rescued” edge case from your original */
|
||||
if ((FIGHTING(vict) != NULL) && (FIGHTING(ch) == FIGHTING(vict)) && (tmp_ch == NULL)) {
|
||||
tmp_ch = FIGHTING(vict);
|
||||
if (FIGHTING(tmp_ch) == ch) {
|
||||
send_to_char(ch, "You have already rescued %s from %s.\r\n", GET_NAME(vict), GET_NAME(FIGHTING(ch)));
|
||||
return;
|
||||
}
|
||||
tmp_ch = FIGHTING(vict);
|
||||
if (FIGHTING(tmp_ch) == ch) {
|
||||
send_to_char(ch, "You have already rescued %s from %s.\r\n", GET_NAME(vict), GET_NAME(FIGHTING(ch)));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!tmp_ch) {
|
||||
act("But nobody is fighting $M!", FALSE, ch, 0, vict, TO_CHAR);
|
||||
return;
|
||||
}
|
||||
percent = rand_number(1, 101); /* 101% is a complete failure */
|
||||
prob = GET_SKILL(ch, SKILL_RESCUE);
|
||||
|
||||
if (percent > prob) {
|
||||
/* --- STR + proficiency ability check vs DC (no nat 1/20 rules) --- */
|
||||
bonus = GET_ABILITY_MOD(GET_STR(ch)) + GET_PROFICIENCY(GET_SKILL(ch, SKILL_RESCUE));
|
||||
dc = 10;
|
||||
if (FIGHTING(ch)) dc += 5; /* harder to pull off while already in melee */
|
||||
|
||||
roll = rand_number(1, 20);
|
||||
total = roll + bonus;
|
||||
|
||||
if (total < dc) {
|
||||
send_to_char(ch, "You fail the rescue!\r\n");
|
||||
gain_skill(ch, "rescue", FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Success: swap aggro */
|
||||
send_to_char(ch, "Banzai! To the rescue...\r\n");
|
||||
act("You are rescued by $N, you are confused!", FALSE, vict, 0, ch, TO_CHAR);
|
||||
act("$n heroically rescues $N!", FALSE, ch, 0, vict, TO_NOTVICT);
|
||||
|
|
@ -388,77 +466,109 @@ 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);
|
||||
|
||||
gain_skill(ch, "rescue", TRUE);
|
||||
|
||||
WAIT_STATE(vict, 2 * PULSE_VIOLENCE);
|
||||
}
|
||||
|
||||
/* 5e-like whirlwind tick: random characters (PCs & NPCs), d20 vs AC, friendly fire possible */
|
||||
EVENTFUNC(event_whirlwind)
|
||||
{
|
||||
struct char_data *ch, *tch;
|
||||
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)
|
||||
return 0;
|
||||
|
||||
/* For the sake of simplicity, we will place the event data in easily
|
||||
* referenced pointers */
|
||||
|
||||
pMudEvent = (struct mud_event_data *) event_obj;
|
||||
ch = (struct char_data *) pMudEvent->pStruct;
|
||||
|
||||
/* When using a list, we have to make sure to allocate the list as it
|
||||
* uses dynamic memory */
|
||||
ch = (struct char_data *) pMudEvent->pStruct;
|
||||
|
||||
if (!ch || IN_ROOM(ch) == NOWHERE || GET_POS(ch) < POS_FIGHTING)
|
||||
return 0;
|
||||
|
||||
room_list = create_list();
|
||||
|
||||
/* We search through the "next_in_room", and grab all NPCs and add them
|
||||
* to our list */
|
||||
for (tch = world[IN_ROOM(ch)].people; tch; tch = tch->next_in_room)
|
||||
if (IS_NPC(tch))
|
||||
add_to_list(tch, room_list);
|
||||
|
||||
/* If our list is empty or has "0" entries, we free it from memory and
|
||||
* close off our event */
|
||||
|
||||
/* === Target pool: everyone except self; skip protected mobs === */
|
||||
for (tch = world[IN_ROOM(ch)].people; tch; tch = tch->next_in_room) {
|
||||
if (tch == ch) continue;
|
||||
if (IS_NPC(tch) && MOB_FLAGGED(tch, MOB_NOKILL)) continue;
|
||||
if (GET_POS(tch) <= POS_DEAD) continue;
|
||||
add_to_list(tch, room_list);
|
||||
}
|
||||
|
||||
if (room_list->iSize == 0) {
|
||||
free_list(room_list);
|
||||
send_to_char(ch, "There is no one in the room to whirlwind!\r\n");
|
||||
send_to_char(ch, "There is no one here to whirlwind!\r\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* We spit out some ugly colour, making use of the new colour options,
|
||||
* to let the player know they are performing their whirlwind strike */
|
||||
send_to_char(ch, "\t[f313]You deliver a vicious \t[f014]\t[b451]WHIRLWIND!!!\tn\r\n");
|
||||
|
||||
/* Lets grab some a random NPC from the list, and hit() them up */
|
||||
|
||||
send_to_char(ch, "\t[f313]You deliver a vicious \t[f014]\t[b451]attack, spinning wildly!!!\tn\r\n");
|
||||
|
||||
/* Up to 1–4 rapid strikes (friendly fire possible) */
|
||||
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 */
|
||||
int roll, atk_bonus, total, target_ac, dmg;
|
||||
bool crit_success = FALSE, crit_fail = FALSE;
|
||||
|
||||
tch = (struct char_data *) random_from_list(room_list);
|
||||
if (!tch || IN_ROOM(tch) != IN_ROOM(ch) || GET_POS(tch) <= POS_DEAD)
|
||||
continue;
|
||||
|
||||
/* Attack roll vs ascending AC */
|
||||
atk_bonus = GET_ABILITY_MOD(GET_STR(ch)) + GET_PROFICIENCY(GET_SKILL(ch, SKILL_WHIRLWIND));
|
||||
roll = rand_number(1, 20);
|
||||
crit_fail = (roll == 1);
|
||||
crit_success = (roll == 20);
|
||||
|
||||
total = roll + atk_bonus;
|
||||
target_ac = compute_ascending_ac(tch);
|
||||
|
||||
if (!crit_fail && (crit_success || total >= target_ac)) {
|
||||
dmg = dice(1, 4) + GET_ABILITY_MOD(GET_STR(ch)) + GET_PROFICIENCY(GET_SKILL(ch, SKILL_WHIRLWIND));
|
||||
if (dmg < 1) dmg = 1;
|
||||
if (crit_success) dmg *= 2;
|
||||
|
||||
if (crit_success) {
|
||||
act("Your whirlwind catches $N with a devastating slash!", TRUE, ch, 0, tch, TO_CHAR);
|
||||
act("$n's whirlwind catches you with a devastating slash!", TRUE, ch, 0, tch, TO_VICT | TO_SLEEP);
|
||||
act("$n's whirlwind catches $N with a devastating slash!", TRUE, ch, 0, tch, TO_NOTVICT);
|
||||
} else {
|
||||
act("Your whirlwind slices into $N.", TRUE, ch, 0, tch, TO_CHAR);
|
||||
act("$n's whirlwind slices into you.", TRUE, ch, 0, tch, TO_VICT | TO_SLEEP);
|
||||
act("$n's whirlwind slices into $N.", TRUE, ch, 0, tch, TO_NOTVICT);
|
||||
}
|
||||
|
||||
damage(ch, tch, dmg, SKILL_WHIRLWIND);
|
||||
|
||||
/* Learning tick on a strong (crit) hit */
|
||||
if (crit_success)
|
||||
gain_skill(ch, "whirlwind", TRUE);
|
||||
|
||||
} else {
|
||||
act("Your whirlwind arcs wide past $N.", TRUE, ch, 0, tch, TO_CHAR);
|
||||
act("$n's whirlwind arcs wide past you.", TRUE, ch, 0, tch, TO_VICT | TO_SLEEP);
|
||||
act("$n's whirlwind arcs wide past $N.", TRUE, ch, 0, tch, TO_NOTVICT);
|
||||
|
||||
damage(ch, tch, 0, SKILL_WHIRLWIND);
|
||||
gain_skill(ch, "whirlwind", FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Now that our attack is done, let's free out list */
|
||||
|
||||
free_list(room_list);
|
||||
|
||||
/* The "return" of the event function is the time until the event is called
|
||||
* again. If we return 0, then the event is freed and removed from the list, but
|
||||
* any other numerical response will be the delay until the next call */
|
||||
|
||||
/* Continue spinning or stop */
|
||||
if (GET_SKILL(ch, SKILL_WHIRLWIND) < rand_number(1, 101)) {
|
||||
send_to_char(ch, "You stop spinning.\r\n");
|
||||
send_to_char(ch, "You stop spinning, but the world around you doesn't.\r\n");
|
||||
return 0;
|
||||
} else
|
||||
return 1.5 * PASSES_PER_SEC;
|
||||
}
|
||||
return (int)(1.5 * PASSES_PER_SEC);
|
||||
}
|
||||
|
||||
/* The "Whirlwind" skill is designed to provide a basic understanding of the
|
||||
|
|
@ -471,7 +581,7 @@ ACMD(do_whirlwind)
|
|||
return;
|
||||
}
|
||||
|
||||
if ROOM_FLAGGED(IN_ROOM(ch), ROOM_PEACEFUL) {
|
||||
if (ROOM_FLAGGED(IN_ROOM(ch), ROOM_PEACEFUL)) {
|
||||
send_to_char(ch, "This room just has such a peaceful, easy feeling...\r\n");
|
||||
return;
|
||||
}
|
||||
|
|
@ -505,7 +615,8 @@ ACMD(do_kick)
|
|||
{
|
||||
char arg[MAX_INPUT_LENGTH];
|
||||
struct char_data *vict;
|
||||
int percent, prob;
|
||||
int roll, atk_bonus, total, target_ac;
|
||||
bool crit_success = FALSE, crit_miss = FALSE;
|
||||
|
||||
if (IS_NPC(ch) || !GET_SKILL(ch, SKILL_KICK)) {
|
||||
send_to_char(ch, "You have no idea how.\r\n");
|
||||
|
|
@ -522,20 +633,53 @@ ACMD(do_kick)
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (vict == ch) {
|
||||
send_to_char(ch, "Aren't we funny today...\r\n");
|
||||
return;
|
||||
}
|
||||
/* 101% is a complete failure */
|
||||
percent = ((10 - (compute_armor_class(vict) / 10)) * 2) + rand_number(1, 101);
|
||||
prob = GET_SKILL(ch, SKILL_KICK);
|
||||
|
||||
if (percent > prob) {
|
||||
/* --- 5e-like attack roll vs ascending AC --- */
|
||||
atk_bonus = GET_ABILITY_MOD(GET_STR(ch)) +
|
||||
GET_PROFICIENCY(GET_SKILL(ch, SKILL_KICK));
|
||||
|
||||
roll = rand_number(1, 20);
|
||||
crit_miss = (roll == 1);
|
||||
crit_success = (roll == 20);
|
||||
|
||||
total = roll + atk_bonus;
|
||||
target_ac = compute_ascending_ac(vict);
|
||||
|
||||
if (!crit_miss && (crit_success || total >= target_ac)) {
|
||||
/* HIT */
|
||||
|
||||
/* Damage = 1 + STR mod, floored at 1 */
|
||||
int dmg = 1 + GET_ABILITY_MOD(GET_STR(ch));
|
||||
if (dmg < 1)
|
||||
dmg = 1;
|
||||
|
||||
if (crit_success) {
|
||||
dmg *= 2; /* simple crit rule: double damage */
|
||||
act("You land a brutal, bone-jarring kick on $N!", TRUE, ch, 0, vict, TO_CHAR);
|
||||
act("$n lands a brutal, bone-jarring kick on you!", TRUE, ch, 0, vict, TO_VICT);
|
||||
act("$n lands a brutal, bone-jarring kick on $N!", TRUE, ch, 0, vict, TO_NOTVICT);
|
||||
} else {
|
||||
act("You kick $N solidly.", TRUE, ch, 0, vict, TO_CHAR);
|
||||
act("$n kicks you solidly.", TRUE, ch, 0, vict, TO_VICT);
|
||||
act("$n kicks $N solidly.", TRUE, ch, 0, vict, TO_NOTVICT);
|
||||
}
|
||||
|
||||
damage(ch, vict, dmg, SKILL_KICK);
|
||||
gain_skill(ch, "kick", TRUE);
|
||||
|
||||
} else {
|
||||
/* MISS */
|
||||
act("You miss your kick at $N.", TRUE, ch, 0, vict, TO_CHAR);
|
||||
act("$n misses a kick at you.", TRUE, ch, 0, vict, TO_VICT);
|
||||
act("$n misses a kick at $N.", TRUE, ch, 0, vict, TO_NOTVICT);
|
||||
|
||||
damage(ch, vict, 0, SKILL_KICK);
|
||||
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);
|
||||
|
|
@ -544,11 +688,10 @@ ACMD(do_kick)
|
|||
ACMD(do_bandage)
|
||||
{
|
||||
char arg[MAX_INPUT_LENGTH];
|
||||
struct char_data * vict;
|
||||
int percent, prob;
|
||||
struct char_data *vict;
|
||||
int roll, bonus, total, dc;
|
||||
|
||||
if (!GET_SKILL(ch, SKILL_BANDAGE))
|
||||
{
|
||||
if (!GET_SKILL(ch, SKILL_BANDAGE)) {
|
||||
send_to_char(ch, "You are unskilled in the art of bandaging.\r\n");
|
||||
return;
|
||||
}
|
||||
|
|
@ -565,30 +708,63 @@ ACMD(do_bandage)
|
|||
return;
|
||||
}
|
||||
|
||||
if (GET_HIT(vict) >= 0) {
|
||||
send_to_char(ch, "You can only bandage someone who is close to death.\r\n");
|
||||
if (AFF_FLAGGED(vict, AFF_BANDAGED)) {
|
||||
send_to_char(ch, "That person has already been bandaged recently.\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (GET_HIT(vict) >= GET_MAX_HIT(vict)) {
|
||||
send_to_char(ch, "They don’t need bandaging right now.\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
WAIT_STATE(ch, PULSE_VIOLENCE * 2);
|
||||
|
||||
percent = rand_number(1, 101); /* 101% is a complete failure */
|
||||
prob = GET_SKILL(ch, SKILL_BANDAGE);
|
||||
/* --- WIS + proficiency ability check vs DC --- */
|
||||
bonus = GET_ABILITY_MOD(GET_WIS(ch)) + GET_PROFICIENCY(GET_SKILL(ch, SKILL_BANDAGE));
|
||||
dc = 10;
|
||||
if (FIGHTING(ch)) dc += 2; /* harder to bandage in combat */
|
||||
|
||||
roll = rand_number(1, 20);
|
||||
total = roll + bonus;
|
||||
|
||||
if (total < dc) {
|
||||
/* Failure: hurt the patient slightly */
|
||||
act("Your attempt to bandage fails.", FALSE, ch, 0, vict, TO_CHAR);
|
||||
act("$n tries to bandage $N, but fails miserably.", TRUE, ch, 0, vict, TO_NOTVICT);
|
||||
act("$n fumbles the bandage work on you. That hurts!", TRUE, ch, 0, vict, TO_VICT);
|
||||
|
||||
if (percent <= prob) {
|
||||
act("Your attempt to bandage fails.", FALSE, ch, 0, 0, TO_CHAR);
|
||||
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;
|
||||
}
|
||||
|
||||
/* Success: heal 1d4 + WIS mod + proficiency */
|
||||
int heal = dice(1, 4) + GET_ABILITY_MOD(GET_WIS(ch)) +
|
||||
GET_PROFICIENCY(GET_SKILL(ch, SKILL_BANDAGE));
|
||||
if (heal < 1) heal = 1;
|
||||
|
||||
GET_HIT(vict) = MIN(GET_MAX_HIT(vict), GET_HIT(vict) + heal);
|
||||
|
||||
act("You successfully bandage $N.", FALSE, ch, 0, vict, TO_CHAR);
|
||||
act("$n bandages $N, who looks a bit better now.", TRUE, ch, 0,
|
||||
vict, TO_NOTVICT);
|
||||
act("Someone bandages you, and you feel a bit better now.",
|
||||
FALSE, ch, 0, vict, TO_VICT);
|
||||
GET_HIT(vict) = 0;
|
||||
act("$n bandages $N, who looks a bit better now.", TRUE, ch, 0, vict, TO_NOTVICT);
|
||||
act("Someone bandages you, and you feel a bit better now.", FALSE, ch, 0, vict, TO_VICT);
|
||||
|
||||
/* Apply the bandaged cooldown: 30 minutes real-time (1800 sec) */
|
||||
struct affected_type af;
|
||||
new_affect(&af);
|
||||
|
||||
/* Field name is 'spell' in your headers (not 'type') */
|
||||
af.spell = SKILL_BANDAGE;
|
||||
af.duration = 30 RL_SEC; /* 30 minutes real time */
|
||||
af.modifier = 0;
|
||||
af.location = APPLY_NONE;
|
||||
|
||||
/* bitvector is an array; clear then set the AFF_BANDAGED bit */
|
||||
memset(af.bitvector, 0, sizeof(af.bitvector)); /* clear all bits; macro usually zeros the array */
|
||||
SET_BIT_AR(af.bitvector, AFF_BANDAGED);
|
||||
|
||||
affect_to_char(vict, &af);
|
||||
|
||||
gain_skill(ch, "bandage", TRUE);
|
||||
}
|
||||
|
|
|
|||
185
src/act.other.c
185
src/act.other.c
|
|
@ -99,49 +99,72 @@ ACMD(do_not_here)
|
|||
ACMD(do_sneak)
|
||||
{
|
||||
struct affected_type af;
|
||||
int chance;
|
||||
bool ok;
|
||||
int rolla, rollb, roll, bonus, total, dc;
|
||||
bool disadv = FALSE;
|
||||
|
||||
if (IS_NPC(ch) || !GET_SKILL(ch, SKILL_SNEAK)) {
|
||||
send_to_char(ch, "You have no idea how to do that.\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (FIGHTING(ch)){
|
||||
send_to_char(ch, "While fighting!?\r\n");
|
||||
return;
|
||||
} /* you can't sneak while in active melee */
|
||||
|
||||
send_to_char(ch, "Okay, you'll try to move silently for a while.\r\n");
|
||||
|
||||
/* Remove prior sneak affect if present (refresh logic) */
|
||||
if (AFF_FLAGGED(ch, AFF_SNEAK))
|
||||
affect_from_char(ch, SKILL_SNEAK);
|
||||
|
||||
/* Base chance: skill % + Dex-based adjustment */
|
||||
chance = GET_SKILL(ch, SKILL_SNEAK) + dex_app_skill[GET_DEX(ch)].sneak;
|
||||
if (chance < 0) chance = 0;
|
||||
if (chance > 100) chance = 100;
|
||||
/* --- 5e-style Stealth check (DEX + proficiency) --- */
|
||||
bonus = GET_ABILITY_MOD(GET_DEX(ch)) +
|
||||
GET_PROFICIENCY(GET_SKILL(ch, SKILL_SNEAK));
|
||||
|
||||
/* Apply disadvantage if heavy/bulky armor or flagged pieces */
|
||||
if (has_stealth_disadv(ch))
|
||||
ok = percent_success_disadv(chance);
|
||||
else
|
||||
ok = percent_success(chance);
|
||||
dc = 10;
|
||||
|
||||
if (!ok) {
|
||||
disadv = has_stealth_disadv(ch) ? TRUE : FALSE;
|
||||
|
||||
rolla = rand_number(1, 20);
|
||||
if (disadv) {
|
||||
rollb = rand_number(1, 20);
|
||||
roll = MIN(rolla, rollb); /* disadvantage: take lower roll */
|
||||
} else {
|
||||
roll = rolla;
|
||||
}
|
||||
|
||||
total = roll + bonus;
|
||||
|
||||
if (total < dc) {
|
||||
gain_skill(ch, "sneak", FALSE);
|
||||
WAIT_STATE(ch, PULSE_VIOLENCE / 2);
|
||||
GET_MOVE(ch) -= 10;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Success: apply Sneak affect */
|
||||
new_affect(&af);
|
||||
af.spell = SKILL_SNEAK;
|
||||
af.duration = GET_LEVEL(ch);
|
||||
af.spell = SKILL_SNEAK;
|
||||
af.location = APPLY_NONE;
|
||||
af.modifier = 0;
|
||||
af.duration = GET_LEVEL(ch); /* keep stock duration; adjust if desired */
|
||||
memset(af.bitvector, 0, sizeof(af.bitvector));
|
||||
SET_BIT_AR(af.bitvector, AFF_SNEAK);
|
||||
affect_to_char(ch, &af);
|
||||
|
||||
/* Store a stealth check value for movement contests (reuse Hide’s field) */
|
||||
/* If you’ve already hidden with a higher roll, keep the stronger value. */
|
||||
SET_STEALTH_CHECK(ch, MAX(GET_STEALTH_CHECK(ch), total));
|
||||
|
||||
gain_skill(ch, "sneak", TRUE);
|
||||
GET_MOVE(ch) -= 10;
|
||||
}
|
||||
|
||||
ACMD(do_hide)
|
||||
{
|
||||
int chance;
|
||||
bool ok;
|
||||
int rolla, rollb, roll, bonus, total, dc;
|
||||
bool disadv = FALSE;
|
||||
|
||||
if (IS_NPC(ch) || !GET_SKILL(ch, SKILL_HIDE)) {
|
||||
send_to_char(ch, "You have no idea how to do that.\r\n");
|
||||
|
|
@ -150,29 +173,135 @@ ACMD(do_hide)
|
|||
|
||||
send_to_char(ch, "You attempt to hide yourself.\r\n");
|
||||
|
||||
if (AFF_FLAGGED(ch, AFF_HIDE))
|
||||
/* If already hidden, drop it before re-attempting */
|
||||
if (AFF_FLAGGED(ch, AFF_HIDE)) {
|
||||
REMOVE_BIT_AR(AFF_FLAGS(ch), AFF_HIDE);
|
||||
GET_STEALTH_CHECK(ch) = 0;
|
||||
}
|
||||
|
||||
/* Base chance: skill % + Dex-based adjustment */
|
||||
chance = GET_SKILL(ch, SKILL_HIDE) + dex_app_skill[GET_DEX(ch)].hide;
|
||||
if (chance < 0) chance = 0;
|
||||
if (chance > 100) chance = 100;
|
||||
if (FIGHTING(ch)){
|
||||
send_to_char(ch, "While fighting!?\r\n");
|
||||
return;
|
||||
} /* you can't hide while in active melee */
|
||||
|
||||
/* Apply disadvantage if heavy/bulky armor or flagged pieces */
|
||||
if (has_stealth_disadv(ch))
|
||||
ok = percent_success_disadv(chance);
|
||||
else
|
||||
ok = percent_success(chance);
|
||||
/* --- 5e Stealth (DEX) ability check --- */
|
||||
bonus = GET_ABILITY_MOD(GET_DEX(ch)) + GET_PROFICIENCY(GET_SKILL(ch, SKILL_HIDE));
|
||||
|
||||
if (!ok) {
|
||||
/* Baseline difficulty: hiding in general */
|
||||
/* TODO: Maybe change dc based on terrain/populated rooms in the future */
|
||||
dc = 10;
|
||||
|
||||
/* Armor/gear can impose disadvantage */
|
||||
disadv = has_stealth_disadv(ch) ? TRUE : FALSE;
|
||||
|
||||
rolla = rand_number(1, 20);
|
||||
if (disadv) {
|
||||
rollb = rand_number(1, 20);
|
||||
roll = MIN(rolla, rollb); /* disadvantage: take the lower */
|
||||
} else {
|
||||
roll = rolla;
|
||||
}
|
||||
|
||||
total = roll + bonus;
|
||||
|
||||
if (total < dc) {
|
||||
/* Failure */
|
||||
gain_skill(ch, "hide", FALSE);
|
||||
WAIT_STATE(ch, PULSE_VIOLENCE / 2);
|
||||
GET_MOVE(ch) -= 10;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Success */
|
||||
/* Success: set flag and store this specific Stealth result */
|
||||
SET_BIT_AR(AFF_FLAGS(ch), AFF_HIDE);
|
||||
GET_STEALTH_CHECK(ch) = total;
|
||||
|
||||
send_to_char(ch, "You hide yourself as best you can.\r\n");
|
||||
gain_skill(ch, "hide", TRUE);
|
||||
WAIT_STATE(ch, PULSE_VIOLENCE / 2);
|
||||
GET_MOVE(ch) -= 10;
|
||||
}
|
||||
|
||||
/* Perception: scan the room for hidden creatures and objects */
|
||||
ACMD(do_perception)
|
||||
{
|
||||
struct char_data *tch;
|
||||
struct obj_data *obj, *next_obj;
|
||||
int roll, bonus, total;
|
||||
int found_chars = 0, found_objs = 0;
|
||||
|
||||
if (IS_NPC(ch) || !GET_SKILL(ch, SKILL_PERCEPTION)) {
|
||||
send_to_char(ch, "You have no idea how to do that.\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Roll once for this scan (active check) */
|
||||
bonus = GET_ABILITY_MOD(GET_WIS(ch)) +
|
||||
GET_PROFICIENCY(GET_SKILL(ch, SKILL_PERCEPTION));
|
||||
|
||||
roll = rand_number(1, 20);
|
||||
total = roll + bonus;
|
||||
|
||||
/* Optional: it’s harder to actively scan while in melee */
|
||||
if (FIGHTING(ch))
|
||||
total -= 4;
|
||||
|
||||
/* --- Scan characters in the room (PCs & NPCs) --- */
|
||||
for (tch = world[IN_ROOM(ch)].people; tch; tch = tch->next_in_room) {
|
||||
if (tch == ch)
|
||||
continue;
|
||||
if (!AFF_FLAGGED(tch, AFF_HIDE))
|
||||
continue;
|
||||
|
||||
/* Safety default if some legacy code set AFF_HIDE without a stored check */
|
||||
if (GET_STEALTH_CHECK(tch) <= 0)
|
||||
SET_STEALTH_CHECK(tch, 5);
|
||||
|
||||
if (total >= GET_STEALTH_CHECK(tch)) {
|
||||
/* Spotted! Reveal them. */
|
||||
REMOVE_BIT_AR(AFF_FLAGS(tch), AFF_HIDE);
|
||||
SET_STEALTH_CHECK(tch, 0);
|
||||
++found_chars;
|
||||
|
||||
act("You spot $N hiding!", FALSE, ch, 0, tch, TO_CHAR);
|
||||
act("$n seems to look right at you — you've been spotted!", FALSE, ch, 0, tch, TO_VICT);
|
||||
act("$n spots $N hiding nearby!", FALSE, ch, 0, tch, TO_NOTVICT);
|
||||
}
|
||||
}
|
||||
|
||||
/* --- Scan objects in the room (requires an ITEM_HIDDEN extra flag) --- */
|
||||
for (obj = world[IN_ROOM(ch)].contents; obj; obj = next_obj) {
|
||||
next_obj = obj->next_content;
|
||||
|
||||
/* If you don't have ITEM_HIDDEN yet, add it to your extra flags table and OBJ flag names. */
|
||||
#ifdef ITEM_HIDDEN
|
||||
if (OBJ_FLAGGED(obj, ITEM_HIDDEN)) {
|
||||
/* Simple baseline DC for hidden objects; tune as desired or add per-object difficulty. */
|
||||
int obj_dc = 12;
|
||||
if (FIGHTING(ch)) obj_dc += 2;
|
||||
|
||||
if (total >= obj_dc) {
|
||||
/* Reveal the object. */
|
||||
REMOVE_BIT_AR(GET_OBJ_EXTRA(obj), ITEM_HIDDEN);
|
||||
++found_objs;
|
||||
|
||||
act("You spot $p tucked out of sight.", FALSE, ch, obj, 0, TO_CHAR);
|
||||
act("$n notices $p tucked out of sight.", FALSE, ch, obj, 0, TO_ROOM);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!found_chars && !found_objs) {
|
||||
send_to_char(ch, "You search carefully but don’t uncover anything hidden.\r\n");
|
||||
gain_skill(ch, "perception", FALSE);
|
||||
} else {
|
||||
gain_skill(ch, "perception", TRUE);
|
||||
}
|
||||
|
||||
/* Small action taxes do disincline players from spamming perception */
|
||||
WAIT_STATE(ch, PULSE_VIOLENCE / 2);
|
||||
GET_MOVE(ch) -= 10;
|
||||
}
|
||||
|
||||
ACMD(do_steal)
|
||||
|
|
|
|||
12
src/class.c
12
src/class.c
|
|
@ -893,6 +893,7 @@ void do_start(struct char_data *ch)
|
|||
SET_SKILL(ch, SKILL_UNARMED, 5);
|
||||
SET_SKILL(ch, SKILL_SHIELD_USE, 5);
|
||||
SET_SKILL(ch, SKILL_PIERCING_WEAPONS, 5);
|
||||
SET_SKILL(ch, SKILL_PERCEPTION, 5);
|
||||
break;
|
||||
|
||||
case CLASS_WARRIOR:
|
||||
|
|
@ -905,6 +906,7 @@ void do_start(struct char_data *ch)
|
|||
SET_SKILL(ch, SKILL_PIERCING_WEAPONS, 5);
|
||||
SET_SKILL(ch, SKILL_BLUDGEONING_WEAPONS, 5);
|
||||
SET_SKILL(ch, SKILL_SHIELD_USE, 5);
|
||||
SET_SKILL(ch, SKILL_PERCEPTION, 5);
|
||||
break;
|
||||
|
||||
case CLASS_BARBARIAN:
|
||||
|
|
@ -915,6 +917,7 @@ void do_start(struct char_data *ch)
|
|||
SET_SKILL(ch, SKILL_UNARMED, 5);
|
||||
SET_SKILL(ch, SKILL_PIERCING_WEAPONS, 5);
|
||||
SET_SKILL(ch, SKILL_BLUDGEONING_WEAPONS, 5);
|
||||
SET_SKILL(ch, SKILL_PERCEPTION, 5);
|
||||
break;
|
||||
|
||||
case CLASS_RANGER:
|
||||
|
|
@ -927,6 +930,7 @@ void do_start(struct char_data *ch)
|
|||
SET_SKILL(ch, SKILL_SLASHING_WEAPONS, 5);
|
||||
SET_SKILL(ch, SKILL_PIERCING_WEAPONS, 5);
|
||||
SET_SKILL(ch, SKILL_SHIELD_USE, 5);
|
||||
SET_SKILL(ch, SKILL_PERCEPTION, 5);
|
||||
break;
|
||||
|
||||
case CLASS_BARD:
|
||||
|
|
@ -938,6 +942,7 @@ void do_start(struct char_data *ch)
|
|||
SET_SKILL(ch, SKILL_UNARMED, 5);
|
||||
SET_SKILL(ch, SKILL_PIERCING_WEAPONS, 5);
|
||||
SET_SKILL(ch, SKILL_SHIELD_USE, 5);
|
||||
SET_SKILL(ch, SKILL_PERCEPTION, 5);
|
||||
break;
|
||||
|
||||
case CLASS_DRUID:
|
||||
|
|
@ -949,6 +954,7 @@ void do_start(struct char_data *ch)
|
|||
SET_SKILL(ch, SKILL_UNARMED, 5);
|
||||
SET_SKILL(ch, SKILL_PIERCING_WEAPONS, 5);
|
||||
SET_SKILL(ch, SKILL_SHIELD_USE, 5);
|
||||
SET_SKILL(ch, SKILL_PERCEPTION, 5);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -1165,6 +1171,7 @@ void init_spell_levels(void)
|
|||
spell_level(SKILL_UNARMED, CLASS_THIEF, 1);
|
||||
spell_level(SKILL_PIERCING_WEAPONS, CLASS_THIEF, 1);
|
||||
spell_level(SKILL_SHIELD_USE, CLASS_THIEF, 1);
|
||||
spell_level(SKILL_PERCEPTION, CLASS_THIEF, 1);
|
||||
|
||||
/* WARRIORS */
|
||||
spell_level(SKILL_KICK, CLASS_WARRIOR, 1);
|
||||
|
|
@ -1176,6 +1183,7 @@ void init_spell_levels(void)
|
|||
spell_level(SKILL_PIERCING_WEAPONS, CLASS_WARRIOR, 1);
|
||||
spell_level(SKILL_BLUDGEONING_WEAPONS, CLASS_WARRIOR, 1);
|
||||
spell_level(SKILL_SHIELD_USE, CLASS_WARRIOR, 1);
|
||||
spell_level(SKILL_PERCEPTION, CLASS_WARRIOR, 1);
|
||||
|
||||
/* BARBARIANS */
|
||||
spell_level(SKILL_KICK, CLASS_BARBARIAN, 1);
|
||||
|
|
@ -1185,6 +1193,7 @@ void init_spell_levels(void)
|
|||
spell_level(SKILL_UNARMED, CLASS_BARBARIAN, 1);
|
||||
spell_level(SKILL_SLASHING_WEAPONS, CLASS_BARBARIAN, 1);
|
||||
spell_level(SKILL_BLUDGEONING_WEAPONS, CLASS_BARBARIAN, 1);
|
||||
spell_level(SKILL_PERCEPTION, CLASS_BARBARIAN, 1);
|
||||
|
||||
/* RANGERS */
|
||||
spell_level(SKILL_SNEAK, CLASS_RANGER, 1);
|
||||
|
|
@ -1196,6 +1205,7 @@ void init_spell_levels(void)
|
|||
spell_level(SKILL_SLASHING_WEAPONS, CLASS_RANGER, 1);
|
||||
spell_level(SKILL_PIERCING_WEAPONS, CLASS_RANGER, 1);
|
||||
spell_level(SKILL_SHIELD_USE, CLASS_RANGER, 1);
|
||||
spell_level(SKILL_PERCEPTION, CLASS_RANGER, 1);
|
||||
|
||||
/* BARDS */
|
||||
spell_level(SPELL_ARMOR, CLASS_BARD, 1);
|
||||
|
|
@ -1206,6 +1216,7 @@ void init_spell_levels(void)
|
|||
spell_level(SKILL_UNARMED, CLASS_BARD, 1);
|
||||
spell_level(SKILL_PIERCING_WEAPONS, CLASS_BARD, 1);
|
||||
spell_level(SKILL_SHIELD_USE, CLASS_BARD, 1);
|
||||
spell_level(SKILL_PERCEPTION, CLASS_BARD, 1);
|
||||
|
||||
/* DRUIDS */
|
||||
spell_level(SPELL_DETECT_INVIS, CLASS_DRUID, 1);
|
||||
|
|
@ -1216,6 +1227,7 @@ void init_spell_levels(void)
|
|||
spell_level(SKILL_UNARMED, CLASS_DRUID, 1);
|
||||
spell_level(SKILL_PIERCING_WEAPONS, CLASS_DRUID, 1);
|
||||
spell_level(SKILL_SHIELD_USE, CLASS_DRUID, 1);
|
||||
spell_level(SKILL_PERCEPTION, CLASS_DRUID, 1);
|
||||
}
|
||||
|
||||
/* This is the exp given to implementors -- it must always be greater than the
|
||||
|
|
|
|||
|
|
@ -167,10 +167,10 @@ int selfdelete_fastwipe = YES;
|
|||
|
||||
/* ROOM NUMBERS */
|
||||
/* Virtual number of room that mortals should enter at. */
|
||||
room_vnum mortal_start_room = 3001;
|
||||
room_vnum mortal_start_room = 131;
|
||||
|
||||
/* Virtual number of room that immorts should enter at by default. */
|
||||
room_vnum immort_start_room = 1204;
|
||||
room_vnum immort_start_room = 1;
|
||||
|
||||
/* Virtual number of room that frozen players should enter at. */
|
||||
room_vnum frozen_start_room = 1202;
|
||||
|
|
|
|||
4
src/db.c
4
src/db.c
|
|
@ -3480,6 +3480,8 @@ void clear_char(struct char_data *ch)
|
|||
GET_AC(ch) = 100; /* Basic Armor */
|
||||
if (ch->points.max_mana < 100)
|
||||
ch->points.max_mana = 100;
|
||||
|
||||
SET_STEALTH_CHECK(ch, 0);
|
||||
}
|
||||
|
||||
void clear_object(struct obj_data *obj)
|
||||
|
|
@ -3568,6 +3570,8 @@ void init_char(struct char_data *ch)
|
|||
ch->real_abils.con = 25;
|
||||
ch->real_abils.cha = 25;
|
||||
|
||||
SET_STEALTH_CHECK(ch, 0);
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
GET_COND(ch, i) = (GET_LEVEL(ch) == LVL_IMPL ? -1 : 24);
|
||||
|
||||
|
|
|
|||
|
|
@ -133,7 +133,6 @@ static const char *skill_name_for_gain(int skillnum) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#define IS_WEAPON(type) (((type) >= TYPE_HIT) && ((type) < TYPE_SUFFERING))
|
||||
/* The Fight related routines */
|
||||
void appear(struct char_data *ch)
|
||||
|
|
|
|||
|
|
@ -226,6 +226,7 @@ cpp_extern const struct command_info cmd_info[] = {
|
|||
{ "pick" , "pi" , POS_STANDING, do_gen_door , 1, SCMD_PICK },
|
||||
{ "page" , "pag" , POS_DEAD , do_page , 1, 0 },
|
||||
{ "pardon" , "pardon" , POS_DEAD , do_wizutil , LVL_GOD, SCMD_PARDON },
|
||||
{ "perception","per" , POS_RESTING , do_perception, 0, 0 },
|
||||
{ "plist" , "plist" , POS_DEAD , do_plist , LVL_GOD, 0 },
|
||||
{ "policy" , "pol" , POS_DEAD , do_gen_ps , 0, SCMD_POLICIES },
|
||||
{ "pour" , "pour" , POS_STANDING, do_pour , 0, SCMD_POUR },
|
||||
|
|
|
|||
|
|
@ -934,5 +934,6 @@ void mag_assign_spells(void) {
|
|||
skillo(SKILL_PIERCING_WEAPONS, "piercing weapons");
|
||||
skillo(SKILL_SLASHING_WEAPONS, "slashing weapons");
|
||||
skillo(SKILL_BLUDGEONING_WEAPONS, "bludgeoning weapons");
|
||||
skillo(SKILL_PERCEPTION, "perception");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -116,6 +116,7 @@
|
|||
#define SKILL_PIERCING_WEAPONS 144 /* Reserved Skill[] DO NOT CHANGE */
|
||||
#define SKILL_SLASHING_WEAPONS 145 /* Reserved Skill[] DO NOT CHANGE */
|
||||
#define SKILL_BLUDGEONING_WEAPONS 146 /* Reserved Skill[] DO NOT CHANGE */
|
||||
#define SKILL_PERCEPTION 147 /* Reserved Skill[] DO NOT CHANGE */
|
||||
|
||||
/* New skills may be added here up to MAX_SKILLS (200) */
|
||||
|
||||
|
|
|
|||
|
|
@ -290,8 +290,9 @@
|
|||
#define AFF_HIDE 20 /**< Char is hidden */
|
||||
#define AFF_FREE 21 /**< Room for future expansion */
|
||||
#define AFF_CHARM 22 /**< Char is charmed */
|
||||
#define AFF_BANDAGED 23 /**< Character was bandaged recently */
|
||||
/** Total number of affect flags */
|
||||
#define NUM_AFF_FLAGS 23
|
||||
#define NUM_AFF_FLAGS 24
|
||||
|
||||
/* Modes of connectedness: used by descriptor_data.state */
|
||||
#define CON_PLAYING 0 /**< Playing - Nominal state */
|
||||
|
|
@ -936,6 +937,7 @@ struct char_special_data
|
|||
int carry_weight; /**< Carried weight */
|
||||
byte carry_items; /**< Number of items carried */
|
||||
int timer; /**< Timer for update */
|
||||
int stealth_check; /* last rolled Stealth value for Hide; 0 = not hiding/opposed */
|
||||
|
||||
struct char_special_data_saved saved; /**< Constants saved for PCs. */
|
||||
};
|
||||
|
|
@ -1296,6 +1298,10 @@ struct recent_player
|
|||
#define VAL_ARMOR_DURABILITY 4
|
||||
#define VAL_ARMOR_STR_REQ 5
|
||||
|
||||
/* Helper macros */
|
||||
#define GET_STEALTH_CHECK(ch) ((ch)->char_specials.stealth_check)
|
||||
#define SET_STEALTH_CHECK(ch,v) ((ch)->char_specials.stealth_check = (v))
|
||||
|
||||
/* Config structs */
|
||||
|
||||
/** The game configuration structure used for configurating the game play
|
||||
|
|
|
|||
|
|
@ -1638,7 +1638,7 @@ int GET_PROFICIENCY(int pct) {
|
|||
}
|
||||
|
||||
/* Forward declaration */
|
||||
int situational_ac_mods(struct char_data *ch);
|
||||
int GET_SITUATIONAL_AC(struct char_data *ch);
|
||||
|
||||
void compute_ac_breakdown(struct char_data *ch, struct ac_breakdown *out)
|
||||
{
|
||||
|
|
@ -1688,7 +1688,7 @@ void compute_ac_breakdown(struct char_data *ch, struct ac_breakdown *out)
|
|||
}
|
||||
|
||||
/* Situational */
|
||||
out->situational = situational_ac_mods(ch);
|
||||
out->situational = GET_SITUATIONAL_AC(ch);
|
||||
|
||||
/* Total */
|
||||
out->total = out->base
|
||||
|
|
@ -1707,7 +1707,8 @@ int compute_ascending_ac(struct char_data *ch)
|
|||
}
|
||||
|
||||
/* Stub: situational AC mods */
|
||||
int situational_ac_mods(struct char_data *ch)
|
||||
/* Placeholder for future skill/spell enhancements such as Haste */
|
||||
int GET_SITUATIONAL_AC(struct char_data *ch)
|
||||
{
|
||||
int mod = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ struct ac_breakdown {
|
|||
int GET_ABILITY_MOD(int score);
|
||||
int GET_PROFICIENCY(int pct);
|
||||
int compute_ascending_ac(struct char_data *ch);
|
||||
int situational_ac_mods(struct char_data *ch);
|
||||
int GET_SITUATIONAL_AC(struct char_data *ch);
|
||||
int compute_armor_class_asc(struct char_data *ch);
|
||||
void compute_ac_breakdown(struct char_data *ch, struct ac_breakdown *out);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue