From 9db9a3d75bc103b42b793dc89479883f3c11e715 Mon Sep 17 00:00:00 2001 From: jdevnull <37560372+jdevnull@users.noreply.github.com> Date: Tue, 26 Nov 2024 22:17:31 -1000 Subject: [PATCH 1/9] Synthacardium rating adds to platelets cardiac test --- src/limits.cpp | 58 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 23 deletions(-) diff --git a/src/limits.cpp b/src/limits.cpp index 33600b291..832dea2f3 100644 --- a/src/limits.cpp +++ b/src/limits.cpp @@ -660,32 +660,44 @@ bool check_bioware(struct char_data *ch) return FALSE; } - struct obj_data *bio; + struct obj_data *bio = NULL, *platelets = NULL; + int synthacardium = 0; for (bio = ch->bioware; bio; bio = bio->next_content) { - if (GET_BIOWARE_TYPE(bio) == BIO_PLATELETFACTORY) - { - if (--GET_BIOWARE_PLATELETFACTORY_DATA(bio) < 1) { - GET_BIOWARE_PLATELETFACTORY_DATA(bio) = 12; - if (success_test(GET_REAL_BOD(ch), 3 + GET_BIOWARE_PLATELETFACTORY_DIFFICULTY(bio)) < 1) { - send_to_char("Your blood seems to erupt.\r\n", ch); - act("$n collapses to the floor, twitching.", TRUE, ch, 0, 0, TO_ROOM); - if (damage(ch, ch, 10, TYPE_BIOWARE, PHYSICAL)) - return TRUE; - } else { - send_to_char("Your heart strains, and you have a feeling of impending doom. Your need for blood thinners is dire!\r\n", ch); - } - GET_BIOWARE_PLATELETFACTORY_DIFFICULTY(bio)++; - } - if (GET_BIOWARE_PLATELETFACTORY_DATA(bio) == 4) - send_to_char("You kinda feel like you should be taking some aspirin.\r\n", ch); - else if (GET_BIOWARE_PLATELETFACTORY_DATA(bio) == 3) - send_to_char("You could definitely go for some aspirin right now.\r\n", ch); - else if (GET_BIOWARE_PLATELETFACTORY_DATA(bio) <= 2) - send_to_char("You really feel like you need to take some aspirin.\r\n", ch); - else if (GET_BIOWARE_PLATELETFACTORY_DATA(bio) == 1) - send_to_char("Your heart strains, and you have a feeling of impending doom. Your need for blood thinners is dire!\r\n", ch); + // Find the 'ware we care about + if (GET_BIOWARE_TYPE(bio) == BIO_PLATELETFACTORY) { + platelets = bio; + } else if (GET_BIOWARE_TYPE(bio) == BIO_SYNTHACARDIUM) { + synthacardium = GET_BIOWARE_RATING(bio); + } + + if (platelets && synthacardium) break; + } + + if (platelets) { + // Embolism + if (--GET_BIOWARE_PLATELETFACTORY_DATA(platelets) < 1) { + GET_BIOWARE_PLATELETFACTORY_DATA(platelets) = 12; + if (success_test(GET_REAL_BOD(ch) + synthacardium, 3 + GET_BIOWARE_PLATELETFACTORY_DIFFICULTY(platelets)) < 1) { + send_to_char("Your blood seems to erupt.\r\n", ch); + act("$n collapses to the floor, twitching.", TRUE, ch, 0, 0, TO_ROOM); + if (damage(ch, ch, 10, TYPE_BIOWARE, PHYSICAL)) + return TRUE; + } else { + send_to_char("Your heart strains, and you have a feeling of impending doom. Your need for blood thinners is dire!\r\n", ch); + } + GET_BIOWARE_PLATELETFACTORY_DIFFICULTY(platelets)++; } + + // Warning messages start 4 mud hours out + if (GET_BIOWARE_PLATELETFACTORY_DATA(platelets) == 4) + send_to_char("You kinda feel like you should be taking some aspirin.\r\n", ch); + else if (GET_BIOWARE_PLATELETFACTORY_DATA(platelets) == 3) + send_to_char("You could definitely go for some aspirin right now.\r\n", ch); + else if (GET_BIOWARE_PLATELETFACTORY_DATA(platelets) == 2) + send_to_char("You really feel like you need to take some aspirin.\r\n", ch); + else if (GET_BIOWARE_PLATELETFACTORY_DATA(platelets) == 1) + send_to_char("Your heart strains, and you have a feeling of impending doom. Your need for blood thinners is dire!\r\n", ch); } return FALSE; } From d0aae790ef42b5ec2536969178a82d595a87e2d3 Mon Sep 17 00:00:00 2001 From: jdevnull <37560372+jdevnull@users.noreply.github.com> Date: Sat, 14 Dec 2024 17:19:40 -1000 Subject: [PATCH 2/9] Stop vehicle when driver is picked up by docwagon --- src/fight.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/fight.cpp b/src/fight.cpp index ba19ad763..32887fef6 100644 --- a/src/fight.cpp +++ b/src/fight.cpp @@ -2353,6 +2353,18 @@ void docwagon_retrieve(struct char_data *ch) { if (CH_IN_COMBAT(ch)) stop_fighting(ch); + // Stop their vehicle + if ((ch->in_veh && AFF_FLAGGED(ch, AFF_PILOT)) || PLR_FLAGGED(ch, PLR_REMOTE)) { + struct veh_data *veh; + RIG_VEH(ch, veh); + + send_to_veh("Now driverless, the vehicle slows to a stop.\r\n", veh, ch, FALSE); + AFF_FLAGS(ch).RemoveBits(AFF_PILOT, AFF_RIG, ENDBIT); + stop_chase(veh); + if (!veh->dest) + veh->cspeed = SPEED_OFF; + } + // Stop all their sustained spells as if they died. if (GET_SUSTAINED(ch)) { end_all_sustained_spells(ch); From 2f65cdda1e79ad37da7d971b87fe516fcc1a4694 Mon Sep 17 00:00:00 2001 From: jdevnull <37560372+jdevnull@users.noreply.github.com> Date: Sat, 14 Dec 2024 17:46:13 -1000 Subject: [PATCH 3/9] reset platelets on death + some cleanup --- src/act.other.cpp | 8 ++++---- src/fight.cpp | 27 ++++++++++++++++++--------- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/act.other.cpp b/src/act.other.cpp index 8bae630e2..2dc04a0d3 100644 --- a/src/act.other.cpp +++ b/src/act.other.cpp @@ -761,10 +761,10 @@ ACMD(do_use) if (do_drug_take(ch, obj)) return; } else if (GET_OBJ_SPEC(obj) && GET_OBJ_SPEC(obj) == anticoagulant) { - for (struct obj_data *cyber = ch->bioware; cyber; cyber = cyber->next_content) { - if (GET_OBJ_VAL(cyber, 0) == BIO_PLATELETFACTORY) { - GET_OBJ_VAL(cyber, 5) = 36; - GET_OBJ_VAL(cyber, 6) = 0; + for (struct obj_data *bio = ch->bioware; bio; bio = bio->next_content) { + if (GET_BIOWARE_TYPE(bio) == BIO_PLATELETFACTORY) { + GET_BIOWARE_PLATELETFACTORY_DATA(bio) = 36; + GET_BIOWARE_PLATELETFACTORY_DIFFICULTY(bio) = 0; break; } } diff --git a/src/fight.cpp b/src/fight.cpp index 32887fef6..c166b8584 100644 --- a/src/fight.cpp +++ b/src/fight.cpp @@ -887,7 +887,7 @@ void death_cry(struct char_data * ch, idnum_t cause_of_death_idnum) void raw_kill(struct char_data * ch, idnum_t cause_of_death_idnum) { - struct obj_data *bio, *obj, *o; + struct obj_data *obj, *o; struct room_data *dest_room; if (CH_IN_COMBAT(ch)) @@ -926,21 +926,26 @@ void raw_kill(struct char_data * ch, idnum_t cause_of_death_idnum) make_corpse(ch); if (!IS_NPC(ch)) { - for (bio = ch->bioware; bio; bio = bio->next_content) { + // Disable bioware etc that resets on death. + for (struct obj_data *bio = ch->bioware; bio; bio = bio->next_content) { switch (GET_BIOWARE_TYPE(bio)) { case BIO_ADRENALPUMP: - if (GET_OBJ_VAL(bio, 5) > 0) { + if (GET_BIOWARE_PUMP_ADRENALINE(bio) > 0) { for (int affect_idx = 0; affect_idx < MAX_OBJ_AFFECT; affect_idx++) affect_modify(ch, bio->affected[affect_idx].location, bio->affected[affect_idx].modifier, bio->obj_flags.bitvector, FALSE); - GET_OBJ_VAL(bio, 5) = 0; + GET_BIOWARE_PUMP_ADRENALINE(bio) = 0; } break; case BIO_PAINEDITOR: GET_BIOWARE_IS_ACTIVATED(bio) = 0; break; + case BIO_PLATELETFACTORY: + GET_BIOWARE_PLATELETFACTORY_DATA(bio) = 36; + GET_BIOWARE_PLATELETFACTORY_DIFFICULTY(bio) = 0; + break; } } @@ -2392,18 +2397,22 @@ void docwagon_retrieve(struct char_data *ch) { for (struct obj_data *bio = ch->bioware; bio; bio = bio->next_content) { switch (GET_BIOWARE_TYPE(bio)) { case BIO_ADRENALPUMP: - if (GET_OBJ_VAL(bio, 5) > 0) { - for (int i = 0; i < MAX_OBJ_AFFECT; i++) + if (GET_BIOWARE_PUMP_ADRENALINE(bio) > 0) { + for (int affect_idx = 0; affect_idx < MAX_OBJ_AFFECT; affect_idx++) affect_modify(ch, - bio->affected[i].location, - bio->affected[i].modifier, + bio->affected[affect_idx].location, + bio->affected[affect_idx].modifier, bio->obj_flags.bitvector, FALSE); - GET_OBJ_VAL(bio, 5) = 0; + GET_BIOWARE_PUMP_ADRENALINE(bio) = 0; } break; case BIO_PAINEDITOR: GET_BIOWARE_IS_ACTIVATED(bio) = 0; break; + case BIO_PLATELETFACTORY: + GET_BIOWARE_PLATELETFACTORY_DATA(bio) = 36; + GET_BIOWARE_PLATELETFACTORY_DIFFICULTY(bio) = 0; + break; } } From 9c661f5967f9f5939023a40c62e3b72661fea1a2 Mon Sep 17 00:00:00 2001 From: jdevnull <37560372+jdevnull@users.noreply.github.com> Date: Fri, 3 Jan 2025 10:56:41 -1000 Subject: [PATCH 4/9] stop_driving when stunned/morted/dead --- src/fight.cpp | 27 ++++----------------------- 1 file changed, 4 insertions(+), 23 deletions(-) diff --git a/src/fight.cpp b/src/fight.cpp index ad04ea521..3e33e8ac2 100644 --- a/src/fight.cpp +++ b/src/fight.cpp @@ -106,6 +106,7 @@ extern bool check_sentinel_snap_back(struct char_data *ch); extern void end_quest(struct char_data *ch, bool succeeded); extern bool npc_vs_vehicle_blocked_by_quest_protection(idnum_t quest_id, struct veh_data *veh); extern bool ch_is_in_viewers_visual_range(struct char_data *ch, struct char_data *viewer); +extern void stop_driving(struct char_data *ch, bool is_involuntary); // Corpse saving externs. extern bool Storage_get_filename(vnum_t vnum, char *filename, int filename_size); @@ -965,17 +966,6 @@ void raw_kill(struct char_data * ch, idnum_t cause_of_death_idnum) dest_room = get_jurisdiction_docwagon_room(GET_JURISDICTION(in_room)); } - if ((ch->in_veh && AFF_FLAGGED(ch, AFF_PILOT)) || PLR_FLAGGED(ch, PLR_REMOTE)) { - struct veh_data *veh; - RIG_VEH(ch, veh); - - send_to_veh("Now driverless, the vehicle slows to a stop.\r\n", veh, ch, FALSE); - AFF_FLAGS(ch).RemoveBits(AFF_PILOT, AFF_RIG, ENDBIT); - stop_chase(veh); - if (!veh->dest) - veh->cspeed = SPEED_OFF; - } - if (ch->persona) { if (access_level(ch, LVL_PRESIDENT)) send_to_char(ch, "^YExtracted icon from host.\r\n"); @@ -2364,18 +2354,6 @@ void docwagon_retrieve(struct char_data *ch) { if (CH_IN_COMBAT(ch)) stop_fighting(ch); - // Stop their vehicle - if ((ch->in_veh && AFF_FLAGGED(ch, AFF_PILOT)) || PLR_FLAGGED(ch, PLR_REMOTE)) { - struct veh_data *veh; - RIG_VEH(ch, veh); - - send_to_veh("Now driverless, the vehicle slows to a stop.\r\n", veh, ch, FALSE); - AFF_FLAGS(ch).RemoveBits(AFF_PILOT, AFF_RIG, ENDBIT); - stop_chase(veh); - if (!veh->dest) - veh->cspeed = SPEED_OFF; - } - // Stop all their sustained spells as if they died. if (GET_SUSTAINED(ch)) { end_all_sustained_spells(ch); @@ -3535,6 +3513,7 @@ bool raw_damage(struct char_data *ch, struct char_data *victim, int dam, int att switch (GET_POS(victim)) { case POS_MORTALLYW: + stop_driving(ch, TRUE); if (IS_NPC(victim) && MOB_FLAGGED(victim, MOB_INANIMATE)) { act("$n is critically damaged, and will fail soon, if not aided.", TRUE, victim, 0, 0, TO_ROOM); @@ -3558,6 +3537,7 @@ bool raw_damage(struct char_data *ch, struct char_data *victim, int dam, int att } break; case POS_STUNNED: + stop_driving(ch, TRUE); if (IS_NPC(victim) && MOB_FLAGGED(victim, MOB_INANIMATE)) { act("$n is rebooting from heavy damage.", TRUE, victim, 0, 0, TO_ROOM); @@ -3571,6 +3551,7 @@ bool raw_damage(struct char_data *ch, struct char_data *victim, int dam, int att } break; case POS_DEAD: + stop_driving(ch, TRUE); if (IS_NPC(victim)) { if (MOB_FLAGGED(victim, MOB_INANIMATE)) { act("$n terminally fails in a shower of sparks!", FALSE, victim, 0, 0, TO_ROOM); From aad7d793d8a6f6ee79252007227ce5a3c6d2f3d2 Mon Sep 17 00:00:00 2001 From: jdevnull <37560372+jdevnull@users.noreply.github.com> Date: Sun, 12 Jan 2025 09:35:41 -1000 Subject: [PATCH 5/9] Add stop_driving to raw_kill/docwagon_retrieve for staff/debug cmds --- src/fight.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/fight.cpp b/src/fight.cpp index 3e33e8ac2..dea1d03b2 100644 --- a/src/fight.cpp +++ b/src/fight.cpp @@ -966,6 +966,8 @@ void raw_kill(struct char_data * ch, idnum_t cause_of_death_idnum) dest_room = get_jurisdiction_docwagon_room(GET_JURISDICTION(in_room)); } + stop_driving(ch, TRUE); + if (ch->persona) { if (access_level(ch, LVL_PRESIDENT)) send_to_char(ch, "^YExtracted icon from host.\r\n"); @@ -2359,6 +2361,8 @@ void docwagon_retrieve(struct char_data *ch) { end_all_sustained_spells(ch); } + stop_driving(ch, TRUE); + // Remove them from the Matrix. if (ch->persona) { snprintf(buf, sizeof(buf), "%s depixelizes and vanishes from the host.\r\n", CAP(ch->persona->name)); From 588050825ccab40eb1fa7ac73a2ea11514c68e79 Mon Sep 17 00:00:00 2001 From: jdevnull <37560372+jdevnull@users.noreply.github.com> Date: Sun, 12 Jan 2025 09:39:23 -1000 Subject: [PATCH 6/9] add is_involuntary to stop_driving prototype --- src/act.drive.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/act.drive.cpp b/src/act.drive.cpp index e473bcd1b..2ebada130 100644 --- a/src/act.drive.cpp +++ b/src/act.drive.cpp @@ -29,7 +29,7 @@ ACMD_CONST(do_return); int get_vehicle_modifier(struct veh_data *veh, bool include_weather=TRUE); void stop_vehicle(struct veh_data *veh); void stop_rigging(struct char_data *ch); -void stop_driving(struct char_data *ch); +void stop_driving(struct char_data *ch, bool is_involuntary); int calculate_vehicle_entry_load(struct veh_data *veh); extern int max_npc_vehicle_lootwreck_time; From 553467e93080eb8ed860e929a8555c3a4840858b Mon Sep 17 00:00:00 2001 From: jdevnull <37560372+jdevnull@users.noreply.github.com> Date: Sun, 12 Jan 2025 09:55:39 -1000 Subject: [PATCH 7/9] Autonav still applies in a driverless crash --- src/act.drive.cpp | 8 ++++---- src/act.movement.cpp | 2 +- src/fight.cpp | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/act.drive.cpp b/src/act.drive.cpp index 2ebada130..7e1b66488 100644 --- a/src/act.drive.cpp +++ b/src/act.drive.cpp @@ -104,7 +104,7 @@ void stop_chase(struct veh_data *veh) veh->following = NULL; } -void crash_test(struct char_data *ch, bool force_zero_successes) +void crash_test(struct char_data *ch, bool no_driver) { int target = 0, skill = 0; int power, attack_resist = 0, damage_total = SERIOUS; @@ -119,9 +119,9 @@ void crash_test(struct char_data *ch, bool force_zero_successes) snprintf(buf, sizeof(buf), "%s begins to lose control!\r\n", capitalize(GET_VEH_NAME_NOFORMAT(veh))); send_to_room(buf, get_veh_in_room(veh), veh); - skill = veh_skill(ch, veh, &target) + veh->autonav; + skill = (no_driver ? 0 : veh_skill(ch, veh, &target)) + veh->autonav; - if (!force_zero_successes && success_test(skill, target, ch, "crash_test vehicle skill test") > 0) + if (success_test(skill, target, ch, "crash_test vehicle skill test") > 0) { snprintf(crash_buf, sizeof(crash_buf), "^y%s shimmies sickeningly under you, but you manage to keep control.^n\r\n", capitalize(GET_VEH_NAME_NOFORMAT(veh))); send_to_veh(crash_buf, veh, NULL, TRUE); @@ -2586,7 +2586,7 @@ void stop_driving(struct char_data *ch, bool is_involuntary) { send_to_veh(buf1, VEH, ch, FALSE); if (ch->in_veh->cspeed > SPEED_IDLE) { - // Crash test with zero successes-- they've gone unconscious or something. + // Crash test with no driver -- they've gone unconscious or something. crash_test(ch, TRUE); } } else { diff --git a/src/act.movement.cpp b/src/act.movement.cpp index 0033c6394..0eff57a81 100644 --- a/src/act.movement.cpp +++ b/src/act.movement.cpp @@ -830,7 +830,7 @@ void move_vehicle(struct char_data *ch, int dir) struct room_data *was_in = NULL; struct veh_data *veh; struct veh_follow *v, *nextv; - extern void crash_test(struct char_data *, bool); + extern void crash_test(struct char_data *, bool no_driver); char empty_argument = '\0'; RIG_VEH(ch, veh); diff --git a/src/fight.cpp b/src/fight.cpp index dea1d03b2..9c22e908f 100644 --- a/src/fight.cpp +++ b/src/fight.cpp @@ -96,7 +96,7 @@ extern struct zone_data *zone_table; extern void perform_tell(struct char_data *, struct char_data *, char *); extern int can_wield_both(struct char_data *, struct obj_data *, struct obj_data *); extern void find_and_draw_weapon(struct char_data *); -extern void crash_test(struct char_data *ch, bool force_zero_successes); +extern void crash_test(struct char_data *ch, bool no_driver); extern int get_vehicle_modifier(struct veh_data *veh, bool include_weather=TRUE); extern bool mob_magic(struct char_data *ch); extern void cast_spell(struct char_data *ch, int spell, int sub, int force, char *arg); From ce46a72618e566b4bfe3091c563927f218c046d2 Mon Sep 17 00:00:00 2001 From: jdevnull <37560372+jdevnull@users.noreply.github.com> Date: Sun, 12 Jan 2025 11:26:26 -1000 Subject: [PATCH 8/9] Fix involuntary stop_driving order of operations --- src/act.drive.cpp | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/src/act.drive.cpp b/src/act.drive.cpp index 7e1b66488..ca1b71a92 100644 --- a/src/act.drive.cpp +++ b/src/act.drive.cpp @@ -2574,26 +2574,25 @@ void stop_driving(struct char_data *ch, bool is_involuntary) { if (!ch || !ch->in_veh) return; + if (is_involuntary) { + send_to_char("The controls slip from your unresponsive fingers.\r\n", ch); + snprintf(buf1, sizeof(buf1), "%s slumps, the controls slipping from %s fingers.\r\n", capitalize(GET_NAME(ch)), HSHR(ch)); + send_to_veh(buf1, VEH, ch, FALSE); + + if (ch->in_veh->cspeed > SPEED_IDLE) { + // Crash test with no driver -- they've gone unconscious or something. + crash_test(ch, TRUE); + } + } else { + send_to_char("You relinquish the driver's seat.\r\n", ch); + snprintf(buf1, sizeof(buf1), "%s relinquishes the driver's seat.\r\n", capitalize(GET_NAME(ch))); + send_to_veh(buf1, VEH, ch, FALSE); + } + if (AFF_FLAGGED(ch, AFF_RIG) || PLR_FLAGGED(ch, PLR_REMOTE)) { stop_rigging(ch); } else if (AFF_FLAGGED(ch, AFF_PILOT)) { stop_vehicle(ch->in_veh); AFF_FLAGS(ch).RemoveBit(AFF_PILOT); - - if (is_involuntary) { - send_to_char("The controls slip from your unresponsive fingers.\r\n", ch); - snprintf(buf1, sizeof(buf1), "%s slumps, the controls slipping from %s fingers.\r\n", capitalize(GET_NAME(ch)), HSHR(ch)); - send_to_veh(buf1, VEH, ch, FALSE); - - if (ch->in_veh->cspeed > SPEED_IDLE) { - // Crash test with no driver -- they've gone unconscious or something. - crash_test(ch, TRUE); - } - } else { - send_to_char("You relinquish the driver's seat.\r\n", ch); - snprintf(buf1, sizeof(buf1), "%s relinquishes the driver's seat.\r\n", capitalize(GET_NAME(ch))); - send_to_veh(buf1, VEH, ch, FALSE); - } } - } \ No newline at end of file From 62040ba216f48f63fbcbf1d627e194e2bec4d07a Mon Sep 17 00:00:00 2001 From: jdevnull <37560372+jdevnull@users.noreply.github.com> Date: Sun, 12 Jan 2025 11:35:06 -1000 Subject: [PATCH 9/9] Fixes to crash_test effects --- src/act.drive.cpp | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/act.drive.cpp b/src/act.drive.cpp index ca1b71a92..b39da0d36 100644 --- a/src/act.drive.cpp +++ b/src/act.drive.cpp @@ -123,10 +123,12 @@ void crash_test(struct char_data *ch, bool no_driver) if (success_test(skill, target, ch, "crash_test vehicle skill test") > 0) { - snprintf(crash_buf, sizeof(crash_buf), "^y%s shimmies sickeningly under you, but you manage to keep control.^n\r\n", capitalize(GET_VEH_NAME_NOFORMAT(veh))); + snprintf(crash_buf, sizeof(crash_buf), "^y%s shimmies sickeningly under you, but remains under control.^n\r\n", capitalize(GET_VEH_NAME_NOFORMAT(veh))); send_to_veh(crash_buf, veh, NULL, TRUE); - if (!number(0, 10)) - send_to_char("^YYou don't have the skills to be driving like this!^n\r\n", ch); + + // we didn't crash, so we *do* have the skills to be driving like this? - Khai + // if (!number(0, 10)) + // send_to_char("^YYou don't have the skills to be driving like this!^n\r\n", ch); return; } @@ -156,11 +158,17 @@ void crash_test(struct char_data *ch, bool no_driver) char_to_room(tch, get_veh_in_room(veh)); damage_total = convert_damage(stage(0 - success_test(GET_BOD(tch), power, tch, "crash_test damage resist"), MODERATE)); send_to_char(tch, "You are thrown from the %s!\r\n", veh->type == VEH_BIKE ? "bike" : "boat"); - if (damage(tch, tch, damage_total, TYPE_CRASH, PHYSICAL)) { - continue; - } - AFF_FLAGS(tch).RemoveBits(AFF_PILOT, AFF_RIG, ENDBIT); + damage(tch, tch, damage_total, TYPE_CRASH, PHYSICAL); } + AFF_FLAGS(ch).RemoveBits(AFF_PILOT, AFF_RIG, ENDBIT); + veh->cspeed = SPEED_OFF; + return; + } + + // Can't drive wrecked vehicles + if (veh->damage >= VEH_DAM_THRESHOLD_DESTROYED) { + send_to_veh("You slam against your straps as you jerk to a sudden stop.\r\n", veh, 0, TRUE); + AFF_FLAGS(ch).RemoveBits(AFF_PILOT, AFF_RIG, ENDBIT); veh->cspeed = SPEED_OFF; } }