From d978e66cf86d0d8019626c14f038460d9fbbbfa1 Mon Sep 17 00:00:00 2001 From: Dethrace Labs Date: Sun, 11 Sep 2022 15:30:59 +1200 Subject: [PATCH 1/4] implements crash earnings, fixes wasted message --- src/DETHRACE/common/car.c | 8 +- src/DETHRACE/common/crush.c | 347 ++++++++++++++++++++++- src/DETHRACE/common/displays.c | 1 + src/DETHRACE/common/mainloop.c | 2 +- src/DETHRACE/common/opponent.c | 489 +++++++++++++++++++++++++-------- src/DETHRACE/common/spark.c | 2 +- src/DETHRACE/common/world.c | 25 +- 7 files changed, 745 insertions(+), 129 deletions(-) diff --git a/src/DETHRACE/common/car.c b/src/DETHRACE/common/car.c index 54791c64..474cbce6 100644 --- a/src/DETHRACE/common/car.c +++ b/src/DETHRACE/common/car.c @@ -144,8 +144,7 @@ void DamageUnitWithSmoke(tCar_spec* pCar, int pUnit_type, int pDamage_amount) { void DamageEngine(int pDamage_amount) { LOG_TRACE("(%d)", pDamage_amount); - // DamageUnitWithSmoke(&gProgram_state.current_car, eDamage_engine, pDamage_amount); - DamageUnitWithSmoke(gProgram_state.AI_vehicles.opponents[0].car_spec, eDamage_engine, pDamage_amount); + DamageUnitWithSmoke(&gProgram_state.current_car, eDamage_engine, pDamage_amount); } // IDA: void __usercall DamageTrans(int pDamage_amount@) @@ -538,6 +537,11 @@ void SetInitialPosition(tRace_info* pThe_race, int pCar_index, int pGrid_index) if (gNet_mode && car->disabled && car_actor->t.t.translate.t.v[0] < 500.0) { DisableCar(car); } + // Enable to start all opponent cars upside down ;) + // if (strstr(car->name, "EAGLE") == 0) { + // car_actor->t.t.translate.t.v[1] += 2; + // car_actor->t.t.look_up.up.v[1] = -1; + // } } // IDA: void __usercall SetInitialPositions(tRace_info *pThe_race@) diff --git a/src/DETHRACE/common/crush.c b/src/DETHRACE/common/crush.c index 2f372ae4..1d5a348d 100644 --- a/src/DETHRACE/common/crush.c +++ b/src/DETHRACE/common/crush.c @@ -8,13 +8,19 @@ #include "graphics.h" #include "harness/trace.h" #include "loading.h" +#include "mainloop.h" #include "netgame.h" +#include "network.h" #include "oil.h" #include "opponent.h" +#include "pd/sys.h" #include "pedestrn.h" #include "piping.h" +#include "pratcam.h" +#include "raycast.h" #include "replay.h" #include "spark.h" +#include "structur.h" #include "utility.h" #include "world.h" #include @@ -462,13 +468,25 @@ void TotallyRepairCar() { // IDA: void __cdecl CheckLastCar() void CheckLastCar() { LOG_TRACE("()"); - NOT_IMPLEMENTED(); + + if (gNet_mode == eNet_mode_none && GetCarCount(eVehicle_opponent) != 0 && NumberOfOpponentsLeft() == 0) { + NewTextHeadupSlot(4, 0, 5000, -4, GetMiscString(10)); + RaceCompleted(eRace_over_opponents); + } } // IDA: void __usercall KnackerThisCar(tCar_spec *pCar@) void KnackerThisCar(tCar_spec* pCar) { LOG_TRACE("(%p)", pCar); - NOT_IMPLEMENTED(); + + pCar->knackered = 1; + QueueWastedMassage(pCar->index); + CheckLastCar(); + QueueOilSpill(pCar); + if (gNet_mode == eNet_mode_none) { + KillGroovadelic(pCar->index); + KillFunkotronic(pCar->index); + } } // IDA: void __usercall SetKnackeredFlag(tCar_spec *pCar@) @@ -587,7 +605,18 @@ void CheckPiledriverBonus(tCar_spec* pCar, br_vector3* pImpact_point, br_vector3 // IDA: tImpact_location __usercall CalcModifiedLocation@(tCar_spec *pCar@) tImpact_location CalcModifiedLocation(tCar_spec* pCar) { LOG_TRACE("(%p)", pCar); - NOT_IMPLEMENTED(); + + if (pCar->last_impact_location != eImpact_left && pCar->last_impact_location != eImpact_right && pCar->last_impact_location != eImpact_top && pCar->last_impact_location != eImpact_bottom) { + return pCar->last_impact_location; + } + if (pCar->last_col_prop_z < 0.25f) { + return eImpact_front; + } + if (pCar->last_col_prop_z > 0.75f) { + return eImpact_back; + } else { + return pCar->last_impact_location; + } } // IDA: void __usercall DoPratcamHit(br_vector3 *pHit_vector@) @@ -784,7 +813,25 @@ tImpact_location GetDirection(br_vector3* pVelocity) { br_scalar mag_y; br_scalar mag_z; LOG_TRACE("(%p)", pVelocity); - NOT_IMPLEMENTED(); + + mag_x = fabsf(pVelocity->v[0]); + mag_y = fabsf(pVelocity->v[1]); + mag_z = fabsf(pVelocity->v[2]); + if (mag_y >= mag_x || mag_z >= mag_x) { + if (mag_y <= mag_x || mag_z >= mag_y) { + if (pVelocity->v[2] >= 0.0f) { + return eImpact_back; + } else { + return eImpact_front; + } + } else { + return pVelocity->v[1] < 0.0; + } + } else if (pVelocity->v[0] >= 0.0) { + return eImpact_right; + } else { + return eImpact_left; + } } // IDA: void __usercall SetSmokeLastDamageLevel(tCar_spec *pCar@) @@ -876,7 +923,297 @@ int DoCrashEarnings(tCar_spec* pCar1, tCar_spec* pCar2) { tNet_message* message; LOG_TRACE("(%p, %p)", pCar1, pCar2); - STUB_ONCE(); + culprit = 0; + victim = 0; + head_on = 0; + bonus_level = 1; + car_1_culpable = 0; + car_2_culpable = 0; + mutual_culpability = 0; + the_time = PDGetTotalTime(); + inherited_damage = 0; + if (pCar1->driver <= eDriver_non_car) { + dam_acc_1 = 0; + } else { + dam_acc_1 = pCar1->damage_magnitude_accumulator; + } + // dam_acc_2 = pCar2 + // && (pCar2->driver <= eDriver_non_car ? (v21 = 0.0) : (v21 = pCar2->damage_magnitude_accumulator), v21 != 0.0); + + dam_acc_2 = 0; + if (pCar2) { + if (pCar1->driver <= eDriver_non_car) { + dam_acc_2 = 0; + } else { + dam_acc_2 = pCar2->damage_magnitude_accumulator != 0; + } + } + + if (pCar1->driver <= eDriver_non_car) { + if (pCar2 == NULL || pCar2->driver <= eDriver_non_car) { + return 0; + } + pCar1 = pCar2; + pCar2 = NULL; + } + if (pCar2 != NULL && pCar2->driver <= eDriver_non_car) { + pCar2 = NULL; + } + + if (pCar1->pre_car_col_knackered || (pCar2 && pCar2->pre_car_col_knackered) || (pCar2 && pCar2->damage_magnitude_accumulator <= 0.00005f && pCar1->damage_magnitude_accumulator <= 0.00005f)) { + return dam_acc_1 || (pCar2 && dam_acc_2); + } + // if (!pCar1->pre_car_col_knackered + // && (pCar2 == NULL || !pCar2->pre_car_col_knackered) + // && (pCar2 == NULL || pCar2->damage_magnitude_accumulator > 0.00005f || pCar1->damage_magnitude_accumulator > 0.00005f)) { + + modified_location_1 = CalcModifiedLocation(pCar1); + car_direction_1 = GetDirection(&pCar1->pre_car_col_velocity_car_space); + impact_in_moving_direction_1 = car_direction_1 == modified_location_1; + if (pCar2 != NULL) { + modified_location_2 = CalcModifiedLocation(pCar2); + car_direction_2 = GetDirection(&pCar2->pre_car_col_velocity_car_space); + impact_in_moving_direction_2 = car_direction_2 == modified_location_2; + } + if (pCar1->driver >= eDriver_net_human && pCar2) { + if (impact_in_moving_direction_1 && (pCar1->driver < eDriver_net_human || (pCar1->pre_car_col_velocity_car_space.v[2] != 0.0 && pCar1->pre_car_col_velocity_car_space.v[2] > 0.0 != pCar1->gear > 0 && (pCar1->keys.acc != 0 || pCar1->joystick.acc > 0x8000)))) { + pCar2->time_last_hit = the_time; + pCar2->last_hit_by = pCar1; + } + } else if (pCar2 && pCar2->driver >= eDriver_net_human && impact_in_moving_direction_2 && (pCar2->driver < eDriver_net_human || (pCar2->pre_car_col_velocity_car_space.v[2] != 0.0f && pCar2->pre_car_col_velocity_car_space.v[2] > 0.0f != pCar2->gear > 0 && (pCar2->keys.acc != 0 || pCar2->joystick.acc > 0x8000)))) { + pCar1->time_last_hit = the_time; + pCar1->last_hit_by = pCar2; + } + if (pCar2) { + if (impact_in_moving_direction_1 + && pCar1->pre_car_col_speed * 5.0f > pCar2->pre_car_col_speed + && pCar1->pre_car_col_speed > 0.0005f + && (pCar1->driver < eDriver_net_human + || (pCar1->pre_car_col_velocity_car_space.v[2] != 0.0f + && pCar1->pre_car_col_velocity_car_space.v[2] > 0.0f != pCar1->gear > 0 + && (pCar1->keys.acc != 0 || pCar1->joystick.acc > 0x8000)))) { + car_1_culpable = 1; + } + if (impact_in_moving_direction_2 + && pCar2->pre_car_col_speed * 5.0f > pCar1->pre_car_col_speed + && pCar2->pre_car_col_speed > 0.0005f + && (pCar2->driver < eDriver_net_human + || (pCar2->pre_car_col_velocity_car_space.v[2] != 0.0f + && pCar2->pre_car_col_velocity_car_space.v[2] > 0.0f != pCar2->gear > 0 + && (pCar2->keys.acc != 0 || pCar2->joystick.acc > 0x8000)))) { + car_2_culpable = 1; + } + if (gNet_mode && car_1_culpable && car_2_culpable) { + mutual_culpability = 1; + } else { + if (car_2_culpable && pCar2->driver == eDriver_local_human) { + car_1_culpable = 0; + } + if (car_1_culpable) { + culprit = pCar1; + victim = pCar2; + dp = BrVector3Dot(&pCar1->pre_car_col_direction, &pCar1->pre_car_col_direction); /* pCar1->pre_car_col_direction.v[2] * pCar2->pre_car_col_direction.v[2] + + pCar2->pre_car_col_direction.v[1] * pCar1->pre_car_col_direction.v[1] + + pCar2->pre_car_col_direction.v[0] * pCar1->pre_car_col_direction.v[0];*/ + if (modified_location_1 == eImpact_front && modified_location_2 == eImpact_front && pCar1->pre_car_col_speed > 0.001f && pCar2->pre_car_col_speed > 0.001f && dp < -0.7f) { + head_on = 1; + bonus_level = 2; + } else { + bonus_level = 1; + } + } else if (car_2_culpable) { + culprit = pCar2; + victim = pCar1; + // dp = pCar1->pre_car_col_direction.v[2] * pCar2->pre_car_col_direction.v[2] + // + pCar2->pre_car_col_direction.v[1] * pCar1->pre_car_col_direction.v[1] + // + pCar2->pre_car_col_direction.v[0] * pCar1->pre_car_col_direction.v[0]; + dp = BrVector3Dot(&pCar1->pre_car_col_direction, &pCar1->pre_car_col_direction); + if (modified_location_1 == eImpact_front && modified_location_2 == eImpact_front && pCar1->pre_car_col_speed > 0.001f && pCar2->pre_car_col_speed > 0.001f && dp < -0.7f) { + head_on = 1; + bonus_level = 2; + } else { + bonus_level = 1; + } + } + } + } else { + // LOG_DEBUG("no pCar2, timediff is %d", the_time - pCar1->time_last_hit); + if (the_time - pCar1->time_last_hit >= 3000) { + return 1; + } + culprit = pCar1->last_hit_by; + victim = pCar1; + bonus_level = 1; + inherited_damage = 1; + } + if (!mutual_culpability && (!victim || culprit->driver < eDriver_net_human)) { + if (pCar2 && pCar2->last_culprit == pCar1 && the_time - pCar2->time_last_victim < 750) { + inherited_damage = 1; + culprit = pCar1; + victim = pCar2; + } else if (pCar2 && pCar1->last_culprit == pCar2 && the_time - pCar1->time_last_victim < 750) { + inherited_damage = 1; + culprit = pCar2; + victim = pCar1; + } else if (!pCar2 && the_time - pCar1->time_last_victim < 750) { + inherited_damage = 1; + culprit = pCar1->last_culprit; + victim = pCar1; + } + } + if (culprit && victim) { + RecordOpponentTwattageOccurrence(culprit, victim); + total_units_of_damage = 0; + for (i = 0; i < COUNT_OF(victim->damage_units); i++) { + if (victim->damage_units[i].damage_level > victim->damage_units[i].last_level) { + victim->damage_units[i].damage_level = (victim->damage_units[i].damage_level - victim->damage_units[i].last_level) * 2.0f + victim->damage_units[i].last_level; + if (victim->damage_units[i].damage_level >= 99) { + victim->damage_units[i].damage_level = 99; + } + total_units_of_damage += victim->damage_units[i].damage_level - victim->damage_units[i].last_level; + } + if (culprit->damage_units[i].damage_level > culprit->damage_units[i].last_level) { + culprit->damage_units[i].damage_level = (culprit->damage_units[i].damage_level - culprit->damage_units[i].last_level) * 0.1f + (double)culprit->damage_units[i].last_level; + if (culprit->damage_units[i].damage_level < 0) { + culprit->damage_units[i].damage_level = 0; + } + } + } + } + // TODO: tidy this up + for (net_loop = 0; 2 - (mutual_culpability == 0) > net_loop; net_loop++) { + if (mutual_culpability) { + if (net_loop) { + culprit = pCar1; + victim = pCar2; + } else { + culprit = pCar2; + victim = pCar1; + } + total_units_of_damage = 0; + for (i = 0; i < COUNT_OF(victim->damage_units); i++) { + if (victim->damage_units[i].damage_level > victim->damage_units[i].last_level) { + total_units_of_damage += victim->damage_units[i].damage_level - victim->damage_units[i].last_level; + } + } + } + if (culprit && (culprit->driver == eDriver_local_human || gNet_mode) && victim) { + SetKnackeredFlag(victim); + if (victim->knackered && !victim->pre_car_col_knackered) { + victim->pre_car_col_knackered = 1; + credits_squared = sqr(0.7f / victim->car_model_actors[victim->principal_car_actor].crush_data.softness_factor) * gWasted_creds[gProgram_state.skill_level] + 50.0f; + credits = 100 * (int)(credits_squared / 100.0f); + if (gNet_mode) { + message = NetBuildMessage(0x18u, 0); + message->contents.data.wasted.victim = NetPlayerFromCar(victim)->ID; + if (NetPlayerFromCar(culprit)) { + message->contents.data.wasted.culprit = NetPlayerFromCar(culprit)->ID; + } else { + message->contents.data.wasted.culprit = -2; + } + NetGuaranteedSendMessageToEverybody(gCurrent_net_game, message, NULL); + NetEarnCredits(NetPlayerFromCar(culprit), credits); + } else { + PratcamEvent(32); + DoFancyHeadup(11); + credits_squared = sqr(0.7f / victim->car_model_actors[victim->principal_car_actor].crush_data.softness_factor) * gWasted_creds[gProgram_state.skill_level] + 50.0f; + credits = 100 * (int)(credits_squared / 100.0); + AwardTime(gWasted_time[gProgram_state.skill_level]); + EarnCredits(credits); + if (victim->can_be_stolen && !gOpponents[victim->index].dead && ((PercentageChance(50) && gSteal_ranks[gOpponents[victim->index].strength_rating] >= gProgram_state.rank) || victim->index == 4)) { + StealCar(victim); + } + } + } + victim->time_last_hit = the_time; + victim->last_hit_by = culprit; + if (!inherited_damage) { + victim->time_last_victim = the_time; + victim->last_culprit = culprit; + } + if (victim && (fabs(victim->omega.v[0]) > 4.0f || fabs(victim->omega.v[1]) > 6.0f || fabs(victim->omega.v[2]) > 4.0f)) { + bonus_level *= 2; + } + if (pCar1->number_of_wheels_on_ground) { + car_off_ground_1 = 0; + } else { + // car_1_pos.v[0] = pCar1->car_master_actor->t.t.mat.m[3][0] / 6.9000001; + // car_1_pos.v[1] = pCar1->car_master_actor->t.t.mat.m[3][1] / 6.9000001; + // car_1_pos.v[2] = pCar1->car_master_actor->t.t.mat.m[3][2] / 6.9000001; + BrVector3InvScale(&car_1_pos, &pCar1->car_master_actor->t.t.translate.t, WORLD_SCALE); + BrMatrix34ApplyV(&car_1_offset, &pCar1->car_model_actors[pCar1->principal_car_actor].actor->t.t.translate.t, &pCar1->car_master_actor->t.t.mat); + // car_1_pos.v[0] = car_1_offset.v[0] + car_1_pos.v[0]; + // car_1_pos.v[1] = car_1_offset.v[1] + car_1_pos.v[1]; + // car_1_pos.v[2] = car_1_offset.v[2] + car_1_pos.v[2]; + BrVector3Accumulate(&car_1_pos, &car_1_offset); + car_1_pos.v[1] += 0.15f; + car_1_height = FindYVerticallyBelow2(&car_1_pos); + car_off_ground_1 = car_1_height > -100.0f + && pCar1->car_model_actors[pCar1->principal_car_actor].actor->t.t.translate.t.v[1] * 4.0f <= car_1_pos.v[1] - car_1_height - 0.15f; + } + if (!pCar2 || pCar2->number_of_wheels_on_ground) { + car_off_ground_2 = 0; + } else { + BrVector3InvScale(&car_2_pos, &pCar2->car_master_actor->t.t.translate.t, WORLD_SCALE); + BrMatrix34ApplyV(&car_2_offset, &pCar2->car_model_actors[pCar2->principal_car_actor].actor->t.t.translate.t, &pCar2->car_master_actor->t.t.mat); + BrVector3Accumulate(&car_2_pos, &car_2_offset); + car_2_pos.v[1] += 0.15f; + car_2_height = FindYVerticallyBelow2(&car_2_pos); + car_off_ground_2 = car_2_height > -100.0f + && pCar2->car_model_actors[pCar2->principal_car_actor].actor->t.t.translate.t.v[1] * 4.0f <= car_2_pos.v[1] - car_2_height - 0.15f; + } + if (car_off_ground_1) { + bonus_level *= 2; + } + if (car_off_ground_2) { + bonus_level *= 2; + } + total_units_of_damage = 0.7f / victim->car_model_actors[victim->principal_car_actor].crush_data.softness_factor * total_units_of_damage; + if (!victim->has_been_stolen) { + credits = 100 * (int)((gCar_cred_value[gProgram_state.skill_level] * MIN(bonus_level, 8) * total_units_of_damage + 50.0f) / 100.0f); + if (credits || victim->knackered) { + if (!victim->knackered) { + if (gNet_mode) { + NetEarnCredits(NetPlayerFromCar(culprit), MIN(credits, 2000)); + } else { + EarnCredits(MIN(credits, 2000)); + } + last_earn_time = the_time; + if (gNet_mode == eNet_mode_none) { + time = 5 * (int)((total_units_of_damage * gCar_time_value[gProgram_state.skill_level] + 2.5f) / 5.0f); + AwardTime(MIN(time, 90)); + if (pCar2) { + if (head_on) { + DoFancyHeadup(10); + } else if (bonus_level <= 2) { + if (bonus_level > 1) { + DoFancyHeadup(2); + } + } else { + DoFancyHeadup(3); + } + } + } + } + for (i = 0; i < COUNT_OF(victim->damage_units); i++) { + victim->damage_units[i].last_level = victim->damage_units[i].damage_level; + } + } + } + } else { + pCar1->time_last_hit = 0; + if (pCar2) { + pCar2->time_last_hit = 0; + } + } + } + pCar1->damage_magnitude_accumulator = 0.0f; + if (pCar2) { + pCar2->damage_magnitude_accumulator = 0.0f; + } + return 1; + + // return dam_acc_1 || pCar2 && dam_acc_2; } // IDA: void __usercall DoWheelDamage(tU32 pFrame_period@) diff --git a/src/DETHRACE/common/displays.c b/src/DETHRACE/common/displays.c index 962fcf4c..d458315b 100644 --- a/src/DETHRACE/common/displays.c +++ b/src/DETHRACE/common/displays.c @@ -1429,6 +1429,7 @@ void AwardTime(tU32 pTime) { if (gRace_finished || gFreeze_timer || gNet_mode != eNet_mode_none || pTime == 0) { return; } + original_amount = pTime; the_time = GetTotalTime(); for (i = COUNT_OF(gOld_times) - 1; i > 0; i--) { diff --git a/src/DETHRACE/common/mainloop.c b/src/DETHRACE/common/mainloop.c index 3b2b20ee..b87e1651 100644 --- a/src/DETHRACE/common/mainloop.c +++ b/src/DETHRACE/common/mainloop.c @@ -120,7 +120,7 @@ void QueueWastedMassage(int pIndex) { if (gQueued_wasted_massages_count == 0) { gLast_wasted_massage_start = GetTotalTime(); } - gQueued_wasted_massages[gQueued_wasted_massages_count + 1] = pIndex; + gQueued_wasted_massages[gQueued_wasted_massages_count] = pIndex; gQueued_wasted_massages_count++; } diff --git a/src/DETHRACE/common/opponent.c b/src/DETHRACE/common/opponent.c index 6d8a377f..9d8fea83 100644 --- a/src/DETHRACE/common/opponent.c +++ b/src/DETHRACE/common/opponent.c @@ -664,7 +664,38 @@ void CalcReturnToStartPointRoute(tOpponent_spec* pOpponent_spec) { tRoute_section temp_store[10]; tRoute_section perm_store[10]; LOG_TRACE("(%p)", pOpponent_spec); - NOT_IMPLEMENTED(); + + ClearOpponentsProjectedRoute(pOpponent_spec); + section_no = FindNearestPathSection(&pOpponent_spec->car_spec->car_master_actor->t.t.translate.t, §ion_v, &intersect, &distance); + distance = BrVector3Length(§ion_v); + BrVector3Normalise(§ion_v, §ion_v); + + if (BrVector3Dot(&pOpponent_spec->car_spec->direction, §ion_v) <= 0.0f) { + AddToOpponentsProjectedRoute(pOpponent_spec, section_no, 0); + } else { + AddToOpponentsProjectedRoute(pOpponent_spec, section_no, 1); + } + temp_store[0] = pOpponent_spec->next_sections[pOpponent_spec->nnext_sections - 1]; + gSFS_count++; + gSFS_cycles_this_time = 0; + SearchForSection(temp_store, perm_store, &num_of_perm_store_sections, pOpponent_spec->return_to_start_data.section_no, 1, 0.0f, pOpponent_spec); + gSFS_total_cycles += gSFS_cycles_this_time; + if (gSFS_max_cycles < gSFS_cycles_this_time) { + gSFS_max_cycles = gSFS_cycles_this_time; + } + if (num_of_perm_store_sections <= 1) { + if (pOpponent_spec->nnext_sections <= 6) { + TopUpRandomRoute(pOpponent_spec, 4 - pOpponent_spec->nnext_sections + 4); + } + } else { + sections_to_copy = 10 - pOpponent_spec->nnext_sections; + if (sections_to_copy >= num_of_perm_store_sections - 1) { + sections_to_copy = num_of_perm_store_sections - 1; + } + memcpy(&pOpponent_spec->next_sections[pOpponent_spec->nnext_sections], &perm_store[1], sizeof(tRoute_section) * sections_to_copy); + pOpponent_spec->nnext_sections += sections_to_copy; + TopUpRandomRoute(pOpponent_spec, 1); + } } // IDA: void __usercall ClearOpponentsProjectedRoute(tOpponent_spec *pOpponent_spec@) @@ -905,7 +936,7 @@ void ProcessPursueAndTwat(tOpponent_spec* pOpponent_spec, tProcess_objective_com return; } - if ((pOpponent_spec->car_spec->car_ID & 0xFF00) == 0x300 && pOpponent_spec->distance_from_home > 75.0) { + if (CAR_SPEC_IS_ROZZER(pOpponent_spec->car_spec) && pOpponent_spec->distance_from_home > 75.0f) { dr_dprintf("%s: Completing pursuit objective because I'm out of my precinct", pOpponent_spec->car_spec->driver_name); NewObjective(pOpponent_spec, eOOT_return_to_start); return; @@ -921,8 +952,7 @@ void ProcessPursueAndTwat(tOpponent_spec* pOpponent_spec, tProcess_objective_com return; } if (data->state != ePCS_backing_up) { - if (data->time_last_twatted_em + 1000 >= gTime_stamp_for_this_munging || data->time_last_twatted_em + 3000 <= gTime_stamp_for_this_munging - || BrVector3Length(&data->pursuee->v) >= 0.3f) { + if (data->time_last_twatted_em + 1000 >= gTime_stamp_for_this_munging || data->time_last_twatted_em + 3000 <= gTime_stamp_for_this_munging || BrVector3Length(&data->pursuee->v) >= 0.3f) { if (data->time_last_away_from_pursuee + 7000 >= gTime_stamp_for_this_munging || data->time_last_twatted_em + 7000 >= gTime_stamp_for_this_munging || data->start_backup_time + 10000 >= gTime_stamp_for_this_munging) { if (pOpponent_spec->cheating) { if (pOpponent_spec->player_to_oppo_d < 50.0f @@ -980,9 +1010,7 @@ void ProcessPursueAndTwat(tOpponent_spec* pOpponent_spec, tProcess_objective_com data->state = ePCS_following_trail; section_no = FindNearestTrailSection(pOpponent_spec, data->pursuee, §ion_v, &intersect, &distance); dr_dprintf("%s: Trail got away; found new trail section %d", pOpponent_spec->car_spec->driver_name, section_no); - if (section_no == -1 - || distance > 20.0f - || !PointVisibleFromHere(&intersect, &pOpponent_spec->car_spec->car_master_actor->t.t.translate.t)) { + if (section_no == -1 || distance > 20.0f || !PointVisibleFromHere(&intersect, &pOpponent_spec->car_spec->car_master_actor->t.t.translate.t)) { dr_dprintf("%s: ...which unfortunately is too far away (%fBRU) or not visible - end of pursuit", pOpponent_spec->car_spec->driver_name, distance); NewObjective(pOpponent_spec, eOOT_get_near_player); return; @@ -1001,16 +1029,10 @@ void ProcessPursueAndTwat(tOpponent_spec* pOpponent_spec, tProcess_objective_com } break; case ePCS_following_line_of_sight: - data->direct_line_nodes[0].p.v[0] = pOpponent_spec->car_spec->car_master_actor->t.t.mat.m[3][0]; - data->direct_line_nodes[0].p.v[1] = pOpponent_spec->car_spec->car_master_actor->t.t.mat.m[3][1]; - data->direct_line_nodes[0].p.v[2] = pOpponent_spec->car_spec->car_master_actor->t.t.mat.m[3][2]; - wank.v[0] = data->pursuee->car_master_actor->t.t.mat.m[3][0] - pOpponent_spec->car_spec->car_master_actor->t.t.mat.m[3][0]; - wank.v[1] = data->pursuee->car_master_actor->t.t.mat.m[3][1] - pOpponent_spec->car_spec->car_master_actor->t.t.mat.m[3][1]; - wank.v[2] = data->pursuee->car_master_actor->t.t.mat.m[3][2] - pOpponent_spec->car_spec->car_master_actor->t.t.mat.m[3][2]; + BrVector3Copy(&data->direct_line_nodes[0].p, &pOpponent_spec->car_spec->car_master_actor->t.t.translate.t); + BrVector3Sub(&wank, &data->pursuee->car_master_actor->t.t.translate.t, &pOpponent_spec->car_spec->car_master_actor->t.t.translate.t); s = BrVector3Length(&wank); - wank.v[0] = data->pursuee->v.v[0] - pOpponent_spec->car_spec->v.v[0]; - wank.v[1] = data->pursuee->v.v[1] - pOpponent_spec->car_spec->v.v[1]; - wank.v[2] = data->pursuee->v.v[2] - pOpponent_spec->car_spec->v.v[2]; + BrVector3Sub(&wank, &data->pursuee->v, &pOpponent_spec->car_spec->v); t = BrVector3Length(&wank); if (t >= 1.0f) { d = s / t / 2.0; @@ -1018,13 +1040,7 @@ void ProcessPursueAndTwat(tOpponent_spec* pOpponent_spec, tProcess_objective_com } else { d = 0.0; } - // data->direct_line_nodes[1].p.v[0] = data->pursuee->v.v[0] * d; - // data->direct_line_nodes[1].p.v[1] = data->pursuee->v.v[1] * d; - // data->direct_line_nodes[1].p.v[2] = data->pursuee->v.v[2] * d; - BrVector3Scale(&data->direct_line_nodes[1].p, &data->direct_line_nodes[1].p, d); - // data->direct_line_nodes[1].p.v[0] = data->pursuee->car_master_actor->t.t.mat.m[3][0] + data->direct_line_nodes[1].p.v[0]; - // data->direct_line_nodes[1].p.v[1] = data->pursuee->car_master_actor->t.t.mat.m[3][1] + data->direct_line_nodes[1].p.v[1]; - // data->direct_line_nodes[1].p.v[2] = data->pursuee->car_master_actor->t.t.mat.m[3][2] + data->direct_line_nodes[1].p.v[2]; + BrVector3Scale(&data->direct_line_nodes[1].p, &data->pursuee->v, d); BrVector3Accumulate(&data->direct_line_nodes[1].p, &data->pursuee->car_master_actor->t.t.translate.t); if (s >= 2.0f) { ProcessFollowPath(pOpponent_spec, ePOC_run, 1, 1, 0); @@ -1034,14 +1050,14 @@ void ProcessPursueAndTwat(tOpponent_spec* pOpponent_spec, tProcess_objective_com break; case ePCS_backing_up: if (data->start_backup_time + 2200 >= gTime_stamp_for_this_munging) { - pOpponent_spec->car_spec->curvature = 0.0; - pOpponent_spec->car_spec->brake_force = 0.0; - pOpponent_spec->car_spec->acc_force = pOpponent_spec->car_spec->M * -8.0; + pOpponent_spec->car_spec->curvature = 0.0f; + pOpponent_spec->car_spec->brake_force = 0.0f; + pOpponent_spec->car_spec->acc_force = pOpponent_spec->car_spec->M * -8.0f; } else { pOpponent_spec->car_spec->acc_force = 0.0; - pOpponent_spec->car_spec->brake_force = pOpponent_spec->car_spec->M * 15.0; + pOpponent_spec->car_spec->brake_force = pOpponent_spec->car_spec->M * 15.0f; if (data->start_backup_time + 3000 < gTime_stamp_for_this_munging) { - pOpponent_spec->car_spec->brake_force = 0.0; + pOpponent_spec->car_spec->brake_force = 0.0f; data->state = ePCS_what_now; dr_dprintf("%s: Finished backing up.", pOpponent_spec->car_spec->driver_name); } @@ -1061,7 +1077,52 @@ void ProcessRunAway(tOpponent_spec* pOpponent_spec, tProcess_objective_command p br_vector3 direction_v; char str[256]; LOG_TRACE("(%p, %d)", pOpponent_spec, pCommand); - NOT_IMPLEMENTED(); + + switch (pCommand) { + + case ePOC_run: + if (pOpponent_spec->run_away_data.time_to_stop >= gTime_stamp_for_this_munging) { + if (pOpponent_spec->follow_path_data.section_no > 20000) { + ShiftOpponentsProjectedRoute(pOpponent_spec, pOpponent_spec->follow_path_data.section_no - 20000); + pOpponent_spec->follow_path_data.section_no = 20000; + } + if (pOpponent_spec->nnext_sections < 10) { + TopUpRandomRoute(pOpponent_spec, 10 - pOpponent_spec->nnext_sections); + } + if (ProcessFollowPath(pOpponent_spec, ePOC_run, 0, 0, 0) == eFPR_given_up) { + ClearOpponentsProjectedRoute(pOpponent_spec); + section_no = FindNearestPathSection(&pOpponent_spec->car_spec->car_master_actor->t.t.translate.t, &direction_v, &intersect, &distance); + if (BrVector3Dot(&pOpponent_spec->car_spec->direction, &direction_v) < 0.0f) { + AddToOpponentsProjectedRoute(pOpponent_spec, section_no, 0); + } else { + AddToOpponentsProjectedRoute(pOpponent_spec, section_no, 1); + } + TopUpRandomRoute(pOpponent_spec, -1); + ProcessFollowPath(pOpponent_spec, ePOC_start, 0, 0, 0); + } + } else { + ObjectiveComplete(pOpponent_spec); + } + break; + + case ePOC_start: + dr_dprintf("%s: ProcessRunAway() - new objective started", pOpponent_spec->car_spec->driver_name); + pOpponent_spec->run_away_data.time_to_stop = gTime_stamp_for_this_munging + 1000 * IRandomBetween(30, 90); + ClearOpponentsProjectedRoute(pOpponent_spec); + section_no = FindNearestPathSection(&pOpponent_spec->car_spec->car_master_actor->t.t.translate.t, &direction_v, &intersect, &distance); + if (BrVector3Dot(&pOpponent_spec->car_spec->direction, &direction_v) < 0.0f) { + AddToOpponentsProjectedRoute(pOpponent_spec, section_no, 0); + } else { + AddToOpponentsProjectedRoute(pOpponent_spec, section_no, 1); + } + TopUpRandomRoute(pOpponent_spec, -1); + ProcessFollowPath(pOpponent_spec, ePOC_start, 0, 0, 0); + sprintf(str, "%s: Shit! I'm out of here...", pOpponent_spec->car_spec->driver_name); + break; + + case ePOC_die: + break; + } } // IDA: void __usercall ProcessWaitForSomeHaplessSod(tOpponent_spec *pOpponent_spec@, tProcess_objective_command pCommand@) @@ -1086,7 +1147,54 @@ void ProcessReturnToStart(tOpponent_spec* pOpponent_spec, tProcess_objective_com br_scalar distance; int res; LOG_TRACE("(%p, %d)", pOpponent_spec, pCommand); - NOT_IMPLEMENTED(); + + switch (pCommand) { + case ePOC_run: + if (TeleportCopToStart(pOpponent_spec)) { + break; + } + if (pOpponent_spec->return_to_start_data.waiting_near_start) { + pOpponent_spec->car_spec->brake_force = pOpponent_spec->car_spec->M * 15.0f; + } else { + our_pos_xz = pOpponent_spec->car_spec->car_master_actor->t.t.translate.t; + our_pos_xz.v[1] = 0.0f; + BrVector3Sub(&cop_to_start, &pOpponent_spec->start_pos, &our_pos_xz); + if (BrVector3Length(&cop_to_start) >= 10.0) { + if (pOpponent_spec->follow_path_data.section_no > 20000) { + ShiftOpponentsProjectedRoute(pOpponent_spec, pOpponent_spec->follow_path_data.section_no - 20000); + pOpponent_spec->follow_path_data.section_no = 20000; + } + if (pOpponent_spec->nnext_sections <= 4) { + CalcReturnToStartPointRoute(pOpponent_spec); + } + res = ProcessFollowPath(pOpponent_spec, ePOC_run, 0, 0, 0); + if (res == eFPR_given_up || res == eFPR_end_of_path) { + if (res == eFPR_given_up) { + dr_dprintf("%s: Restarting return_to_start route because ProcessFollowPath() gave up.", pOpponent_spec->car_spec->driver_name); + } else { + dr_dprintf("%s: Restarting return_to_start route because ran out of path!", pOpponent_spec->car_spec->driver_name); + } + ClearOpponentsProjectedRoute(pOpponent_spec); + CalcReturnToStartPointRoute(pOpponent_spec); + ProcessFollowPath(pOpponent_spec, ePOC_start, 0, 0, 0); + } + } else { + pOpponent_spec->return_to_start_data.waiting_near_start = 1; + pOpponent_spec->car_spec->brake_force = pOpponent_spec->car_spec->M * 15.0f; + } + } + break; + case ePOC_start: + dr_dprintf("%s: ProcessReturnToStart() - new objective started", pOpponent_spec->car_spec->driver_name); + pOpponent_spec->return_to_start_data.waiting_near_start = 0; + pOpponent_spec->return_to_start_data.section_no = FindNearestPathSection(&pOpponent_spec->start_pos, §ion_v, &pOpponent_spec->return_to_start_data.nearest_path_point, &distance); + pOpponent_spec->return_to_start_data.nearest_path_point.v[1] = 0.0; + CalcReturnToStartPointRoute(pOpponent_spec); + ProcessFollowPath(pOpponent_spec, ePOC_start, 0, 0, 0); + break; + default: + break; + } } // IDA: void __usercall ProcessLevitate(tOpponent_spec *pOpponent_spec@, tProcess_objective_command pCommand@) @@ -1189,7 +1297,8 @@ int LastTwatteeAPlayer(tOpponent_spec* pOpponent_spec) { // IDA: int __usercall LastTwatterAPlayer@(tOpponent_spec *pOpponent_spec@) int LastTwatterAPlayer(tOpponent_spec* pOpponent_spec) { LOG_TRACE("(%p)", pOpponent_spec); - NOT_IMPLEMENTED(); + + return pOpponent_spec->car_spec->last_person_to_hit_us && pOpponent_spec->car_spec->last_person_to_hit_us->driver == eDriver_local_human; } // IDA: void __usercall ObjectiveComplete(tOpponent_spec *pOpponent_spec@) @@ -1603,20 +1712,21 @@ int TeleportCopToStart(tOpponent_spec* pOpponent_spec) { br_vector3 wank; LOG_TRACE("(%p)", pOpponent_spec); - if (pOpponent_spec->cheating || (pOpponent_spec->car_spec->car_ID & 0xff00) == 0x300) { - BrVector3Sub(&wank, &gProgram_state.current_car.car_master_actor->t.t.translate.t, &pOpponent_spec->start_pos); - if (BrVector3Length(&wank) > gIn_view_distance) { - BrVector3Copy(&pOpponent_spec->car_spec->car_master_actor->t.t.translate.t, &pOpponent_spec->start_pos); - PointActorAlongThisBloodyVector(pOpponent_spec->car_spec->car_master_actor, - &pOpponent_spec->start_direction); - RematerialiseOpponent(pOpponent_spec, 0); - TurnOpponentPhysicsOff(pOpponent_spec); - RebuildActiveCarList(); - NewObjective(pOpponent_spec, eOOT_wait_for_some_hapless_sod); - return 1; - } + if (!pOpponent_spec->cheating || !CAR_SPEC_IS_ROZZER(pOpponent_spec->car_spec)) { + return 0; } - return 0; + BrVector3Sub(&wank, &gProgram_state.current_car.car_master_actor->t.t.translate.t, &pOpponent_spec->start_pos); + if (BrVector3Length(&wank) <= gIn_view_distance) { + return 0; + } + pOpponent_spec->car_spec->car_master_actor->t.t.euler.t = pOpponent_spec->start_pos; + PointActorAlongThisBloodyVector(pOpponent_spec->car_spec->car_master_actor, &pOpponent_spec->start_direction); + pOpponent_spec->physics_me = 0; + RematerialiseOpponent(pOpponent_spec, 0.0); + TurnOpponentPhysicsOff(pOpponent_spec); + RebuildActiveCarList(); + NewObjective(pOpponent_spec, eOOT_wait_for_some_hapless_sod); + return 1; } // IDA: void __usercall CalcDistanceFromHome(tOpponent_spec *pOpponent_spec@) @@ -1636,7 +1746,75 @@ int MassageOpponentPosition(tOpponent_spec* pOpponent_spec, int pMassage_count) br_vector3 positive_y_vector; br_vector3 direction_v; LOG_TRACE("(%p, %d)", pOpponent_spec, pMassage_count); - NOT_IMPLEMENTED(); + + BrVector3Set(&positive_y_vector, 0, 1, 0); + mat = &pOpponent_spec->car_spec->car_master_actor->t.t.mat; + car_trans = &pOpponent_spec->car_spec->car_master_actor->t.t.translate.t; + if (pMassage_count > 22) { + return 0; + } + if (pMassage_count <= 20) { + direction_v.v[0] = -pOpponent_spec->car_spec->car_master_actor->t.t.mat.m[2][0]; + direction_v.v[1] = -pOpponent_spec->car_spec->car_master_actor->t.t.mat.m[2][1]; + direction_v.v[2] = -pOpponent_spec->car_spec->car_master_actor->t.t.mat.m[2][2]; + if (pMassage_count % 4 >= 2) { + // displacement_0 = 1.0 * direction_v_2 - direction_v_1 * 0.0; + // displacement_1 = direction_v_0 * 0.0 - 0.0 * direction_v_2; + // displacement_2 = 0.0 * direction_v_1 - direction_v_0 * 1.0; + BrVector3Cross(&displacement, &positive_y_vector, &direction_v); + // v8 = sqrtf(displacement_0 * displacement_0 + displacement_1 * displacement_1 + displacement_2 * displacement_2); + // if (v10 | v11) { + // displacement_0 = 1.0; + // displacement_1 = 0.0; + // displacement_2 = 0.0; + // } else { + + // a_0 = v8; + // v12 = 1.0 / a_0; + // a_1 = v12; + // displacement_0 = v12 * displacement_0; + // displacement_1 = displacement_1 * a_1; + // displacement_2 = displacement_2 * a_1; + // } + BrVector3Normalise(&displacement, &displacement); + // displacement_0 = (double)(pMassage_count / 4) * 0.1 * displacement_0; + // displacement_1 = (double)(pMassage_count / 4) * 0.1 * displacement_1; + // displacement_2 = (double)(pMassage_count / 4) * 0.1 * displacement_2; + BrVector3Scale(&displacement, &displacement, (pMassage_count / 4) * 0.1f); + } else { + // v3 = sqrtf(direction_v_2 * direction_v_2 + direction_v_0 * direction_v_0 + direction_v_1 * direction_v_1); + // if (v5 | v6) { + // displacement_0 = 1.0; + // displacement_1 = 0.0; + // displacement_2 = 0.0; + // } else { + // a_2 = v3; + // v7 = 1.0 / a_2; + // a_2 = v7; + // displacement_0 = v7 * direction_v_0; + // displacement_1 = direction_v_1 * a_2; + // displacement_2 = direction_v_2 * a_2; + // } + BrVector3Normalise(&displacement, &displacement); + // displacement_0 = (double)(pMassage_count / 4) * 0.5 * displacement_0; + // displacement_1 = (double)(pMassage_count / 4) * 0.5 * displacement_1; + // displacement_2 = (double)(pMassage_count / 4) * 0.5 * displacement_2; + BrVector3Scale(&displacement, &displacement, (pMassage_count / 4) * 0.5f); + } + if (pMassage_count % 2) { + // displacement_0 = -displacement_0; + // displacement_1 = -displacement_1; + // displacement_2 = -displacement_2; + BrVector3Negate(&displacement, &displacement); + } + // car_trans->v[0] = car_trans->v[0] + displacement_0; + // car_trans->v[1] = car_trans->v[1] + displacement_1; + // car_trans->v[2] = car_trans->v[2] + displacement_2; + BrVector3Accumulate(car_trans, &displacement); + } else { + car_trans->v[1] = (pMassage_count - 20) * 2.0f + car_trans->v[1]; + } + return 1; } // IDA: int __usercall RematerialiseOpponentOnThisSection@(tOpponent_spec *pOpponent_spec@, br_scalar pSpeed, tS16 pSection_no) @@ -2032,18 +2210,13 @@ void LoadInOppoPaths(FILE* pF) { for (j = 0; j < gProgram_state.AI_vehicles.number_of_cops; j++) { PossibleService(); GetNScalars(pF, 6, scalars); - BrVector3Set(&gProgram_state.AI_vehicles.cop_start_points[j], - scalars[0], scalars[1], scalars[2]); + BrVector3Set(&gProgram_state.AI_vehicles.cop_start_points[j], scalars[0], scalars[1], scalars[2]); if (scalars[3] == 9.0f && scalars[4] == 9.0f && scalars[5] == 9.0f) { gBIG_APC_index = j; } - FindNearestPathSection( - &gProgram_state.AI_vehicles.cop_start_points[j], - &cop_to_section, - &intersect, - &distance); + FindNearestPathSection(&gProgram_state.AI_vehicles.cop_start_points[j], &cop_to_section, &intersect, &distance); BrVector3Set(&gProgram_state.AI_vehicles.cop_start_vectors[j], cop_to_section.v[2] * 1.0f - cop_to_section.v[1] * 0.0f, cop_to_section.v[0] * 0.0f - cop_to_section.v[2] * 0.0f, @@ -2096,79 +2269,85 @@ void MungeOpponents(tU32 pFrame_period) { LOG_TRACE("(%d)", pFrame_period); un_stun_flag = 0; - if (gProgram_state.AI_vehicles.number_of_opponents != 0 || gNumber_of_cops_before_faffage != 0) { - gAcme_frame_count++; - gTime_stamp_for_this_munging = GetTotalTime(); - gFrame_period_for_this_munging = pFrame_period; - gFrame_period_for_this_munging_in_secs = pFrame_period / 1000.f; - if (!gAcknowledged_start && !gCountdown) { - gAcknowledged_start = 1; - if (!gStart_jumped) { - un_stun_flag = 1; - } - } - if (gProgram_state.current_car.no_of_processes_recording_my_trail == 0) { - StartRecordingTrail(&gProgram_state.current_car); - } else { - RecordNextTrailNode(&gProgram_state.current_car); + + if (gProgram_state.AI_vehicles.number_of_opponents == 0 && gNumber_of_cops_before_faffage == 0) { + return; + } + gAcme_frame_count++; + gTime_stamp_for_this_munging = GetTotalTime(); + gFrame_period_for_this_munging = pFrame_period; + gFrame_period_for_this_munging_in_secs = pFrame_period / 1000.f; + if (!gAcknowledged_start && !gCountdown) { + gAcknowledged_start = 1; + if (!gStart_jumped) { + un_stun_flag = 1; } - TrackElasticateyPath(); - if (gProcessing_opponents) { - gNum_of_opponents_pursuing = 0; - gNum_of_opponents_getting_near = 0; - gNum_of_opponents_completing_race = 0; - for (i = 0; i < gProgram_state.AI_vehicles.number_of_opponents; i++) { - if (!gProgram_state.AI_vehicles.opponents[i].finished_for_this_race) { - switch (gProgram_state.AI_vehicles.opponents[i].current_objective) { - case eOOT_pursue_and_twat: - gNum_of_opponents_pursuing++; - break; - case eOOT_get_near_player: - gNum_of_opponents_getting_near++; - break; - case eOOT_complete_race: - gNum_of_opponents_completing_race++; - break; - default: - break; - } + } + if (gProgram_state.current_car.no_of_processes_recording_my_trail == 0) { + StartRecordingTrail(&gProgram_state.current_car); + } else { + RecordNextTrailNode(&gProgram_state.current_car); + } + TrackElasticateyPath(); + if (gProcessing_opponents) { + gNum_of_opponents_pursuing = 0; + gNum_of_opponents_getting_near = 0; + gNum_of_opponents_completing_race = 0; + for (i = 0; i < gProgram_state.AI_vehicles.number_of_opponents; i++) { + if (!gProgram_state.AI_vehicles.opponents[i].finished_for_this_race) { + switch (gProgram_state.AI_vehicles.opponents[i].current_objective) { + case eOOT_pursue_and_twat: + gNum_of_opponents_pursuing++; + break; + case eOOT_get_near_player: + gNum_of_opponents_getting_near++; + break; + case eOOT_complete_race: + gNum_of_opponents_completing_race++; + break; + default: + break; } } - for (i = 0; i < gProgram_state.AI_vehicles.number_of_opponents; i++) { - if (!gProgram_state.AI_vehicles.opponents[i].finished_for_this_race) { - if (un_stun_flag) { - UnStunTheBugger(&gProgram_state.AI_vehicles.opponents[i]); - } - CalcOpponentConspicuousnessWithAViewToCheatingLikeFuck(&gProgram_state.AI_vehicles.opponents[i]); - CalcPlayerConspicuousness(&gProgram_state.AI_vehicles.opponents[i]); - ProcessThisOpponent(&gProgram_state.AI_vehicles.opponents[i]); - ClearTwattageOccurrenceVariables(&gProgram_state.AI_vehicles.opponents[i]); + } + for (i = 0; i < gProgram_state.AI_vehicles.number_of_opponents; i++) { + if (!gProgram_state.AI_vehicles.opponents[i].finished_for_this_race) { + if (un_stun_flag) { + UnStunTheBugger(&gProgram_state.AI_vehicles.opponents[i]); } + CalcOpponentConspicuousnessWithAViewToCheatingLikeFuck(&gProgram_state.AI_vehicles.opponents[i]); + CalcPlayerConspicuousness(&gProgram_state.AI_vehicles.opponents[i]); + ProcessThisOpponent(&gProgram_state.AI_vehicles.opponents[i]); + ClearTwattageOccurrenceVariables(&gProgram_state.AI_vehicles.opponents[i]); } - for (i = 0; i < gNumber_of_cops_before_faffage; i++) { - if (!gProgram_state.AI_vehicles.opponents[i].finished_for_this_race) { - if (un_stun_flag) { - UnStunTheBugger(&gProgram_state.AI_vehicles.cops[i]); - } - CalcDistanceFromHome(&gProgram_state.AI_vehicles.cops[i]); - CalcOpponentConspicuousnessWithAViewToCheatingLikeFuck(&gProgram_state.AI_vehicles.cops[i]); - CalcPlayerConspicuousness(&gProgram_state.AI_vehicles.cops[i]); - ProcessThisOpponent(&gProgram_state.AI_vehicles.cops[i]); - ClearTwattageOccurrenceVariables(&gProgram_state.AI_vehicles.cops[i]); - gProgram_state.AI_vehicles.cops[i].murder_reported = 0; + } + for (i = 0; i < gNumber_of_cops_before_faffage; i++) { + if (!gProgram_state.AI_vehicles.opponents[i].finished_for_this_race) { + if (un_stun_flag) { + UnStunTheBugger(&gProgram_state.AI_vehicles.cops[i]); } + CalcDistanceFromHome(&gProgram_state.AI_vehicles.cops[i]); + CalcOpponentConspicuousnessWithAViewToCheatingLikeFuck(&gProgram_state.AI_vehicles.cops[i]); + CalcPlayerConspicuousness(&gProgram_state.AI_vehicles.cops[i]); + ProcessThisOpponent(&gProgram_state.AI_vehicles.cops[i]); + ClearTwattageOccurrenceVariables(&gProgram_state.AI_vehicles.cops[i]); + gProgram_state.AI_vehicles.cops[i].murder_reported = 0; } - if (gNext_grudge_reduction < gTime_stamp_for_this_munging) { - gNext_grudge_reduction = gTime_stamp_for_this_munging + 3000; - for (i = 0; i < gProgram_state.AI_vehicles.number_of_opponents; i++) { - if (!gProgram_state.AI_vehicles.opponents[i].finished_for_this_race) { - gOpponents[gProgram_state.AI_vehicles.opponents[i].index].psyche.grudge_against_player = MIN(gGrudge_reduction_per_period, gOpponents[gProgram_state.AI_vehicles.opponents[i].index].psyche.grudge_against_player); + } + if (gNext_grudge_reduction < gTime_stamp_for_this_munging) { + gNext_grudge_reduction = gTime_stamp_for_this_munging + 3000; + for (i = 0; i < gProgram_state.AI_vehicles.number_of_opponents; i++) { + if (!gProgram_state.AI_vehicles.opponents[i].finished_for_this_race) { + if (gOpponents[gProgram_state.AI_vehicles.opponents[i].index].psyche.grudge_against_player >= gGrudge_reduction_per_period) { + gOpponents[gProgram_state.AI_vehicles.opponents[i].index].psyche.grudge_against_player -= gGrudge_reduction_per_period; + } else { + gOpponents[gProgram_state.AI_vehicles.opponents[i].index].psyche.grudge_against_player = 0; } } } - RebuildActiveCarList(); - gFirst_frame = 0; } + RebuildActiveCarList(); + gFirst_frame = 0; } } @@ -2179,9 +2358,8 @@ void SetInitialCopPositions() { for (i = 0; i < GetCarCount(eVehicle_rozzer); i++) { BrVector3Copy(&gProgram_state.AI_vehicles.cops[i].car_spec->car_master_actor->t.t.translate.t, &gProgram_state.AI_vehicles.cop_start_points[i]); - PointActorAlongThisBloodyVector(gProgram_state.AI_vehicles.cops[i].car_spec->car_master_actor, - &gProgram_state.AI_vehicles.cop_start_vectors[i]); - gProgram_state.AI_vehicles.cops[i].has_moved_at_some_point = 0; + PointActorAlongThisBloodyVector(gProgram_state.AI_vehicles.cops[i].car_spec->car_master_actor, &gProgram_state.AI_vehicles.cop_start_vectors[i]); + gProgram_state.AI_vehicles.cops[i].physics_me = 0; RematerialiseOpponent(&gProgram_state.AI_vehicles.cops[i], 0.f); InitCarSkidStuff(gProgram_state.AI_vehicles.cops[i].car_spec); } @@ -2710,7 +2888,82 @@ void RecordOpponentTwattageOccurrence(tCar_spec* pTwatter, tCar_spec* pTwattee) tOpponent_spec* twattee_opponent_spec; tOpponent_spec* twatter_opponent_spec; LOG_TRACE("(%p, %p)", pTwatter, pTwattee); - NOT_IMPLEMENTED(); + + if (pTwatter->driver != eDriver_oppo && pTwattee->driver != eDriver_oppo) { + return; + } + damage = pTwattee->damage_magnitude_accumulator; + bangness = MIN(sqrtf(damage * 300000.0f), 100); + grudginess_caused_by_damage = bangness / 10 + 50 * CAR_SPEC_IS_ROZZER(pTwattee); + dr_dprintf("Frame %0.6d: %s hit %s, damage %f, bangness %d, gBig_bang %d, grudginess %d", + gAcme_frame_count, + pTwatter->driver_name, + pTwattee->driver_name, + damage, + bangness, + gBig_bang, + grudginess_caused_by_damage); + if (gMin_bangness <= bangness) { + if (gMax_bangness < bangness) { + gMax_bangness = bangness; + dr_dprintf("(New gMax_bangness - %d)", bangness); + } + } else { + gMin_bangness = bangness; + dr_dprintf("(New gMin_bangness - %d)", bangness); + } + if (bangness >= 5) { + pTwatter->last_collision_time = gTime_stamp_for_this_munging; + pTwatter->last_person_we_hit = pTwattee; + pTwattee->last_collision_time = gTime_stamp_for_this_munging; + pTwattee->last_person_to_hit_us = pTwatter; + pTwattee->grudge_raised_recently = 1; + if (bangness >= gBig_bang || CAR_SPEC_IS_ROZZER(pTwattee)) { + pTwattee->big_bang = 1; + } + if (bangness >= 80) { + pTwattee->scary_bang = 1; + } + if (pTwatter->driver == eDriver_local_human) { + twattee_opponent_spec = GetOpponentSpecFromCarSpec(pTwattee); + if (pTwattee->scary_bang) { + StunTheBugger(twattee_opponent_spec, 30 * bangness + 1000); + } + new_grudge_value = grudginess_caused_by_damage + gOpponents[twattee_opponent_spec->index].psyche.grudge_against_player; + if (new_grudge_value > 100) { + new_grudge_value = 100; + } + gOpponents[twattee_opponent_spec->index].psyche.grudge_against_player = new_grudge_value; + } else if (pTwattee->driver == eDriver_local_human) { + twatter_opponent_spec = GetOpponentSpecFromCarSpec(pTwatter); + if (twatter_opponent_spec->current_objective == eOOT_pursue_and_twat && twatter_opponent_spec->pursue_car_data.pursuee == pTwattee) { + twatter_opponent_spec->pursue_car_data.time_last_twatted_em = gTime_stamp_for_this_munging; + } + twatter_index = twatter_opponent_spec->index; + new_grudge_value = gOpponents[twatter_index].psyche.grudge_against_player - (twatter_opponent_spec->current_objective == eOOT_pursue_and_twat ? 0 : 2 * grudginess_caused_by_damage); + if (new_grudge_value < 0) { + new_grudge_value = 0; + } + gOpponents[twatter_index].psyche.grudge_against_player = new_grudge_value; + } else { + twatter_opponent_spec = GetOpponentSpecFromCarSpec(pTwatter); + twattee_opponent_spec = GetOpponentSpecFromCarSpec(pTwattee); + if (pTwattee->scary_bang) { + StunTheBugger(twattee_opponent_spec, 30 * bangness + 1000); + } + twattee_index = twattee_opponent_spec->index; + if (twatter_opponent_spec->current_objective == eOOT_pursue_and_twat && twatter_opponent_spec->pursue_car_data.pursuee == pTwattee) { + twatter_opponent_spec->pursue_car_data.time_last_twatted_em = gTime_stamp_for_this_munging; + } + if (CAR_SPEC_IS_OPPONENT(pTwatter) && CAR_SPEC_IS_ROZZER(pTwattee)) { + new_grudge_value = grudginess_caused_by_damage + gOpponents[twattee_index].psyche.grudge_against_player; + if (new_grudge_value > 100) { + new_grudge_value = 100; + } + gOpponents[twattee_index].psyche.grudge_against_player = new_grudge_value; + } + } + } } // IDA: void __cdecl ToggleOpponentTest() diff --git a/src/DETHRACE/common/spark.c b/src/DETHRACE/common/spark.c index 22069781..d944d374 100644 --- a/src/DETHRACE/common/spark.c +++ b/src/DETHRACE/common/spark.c @@ -1173,7 +1173,7 @@ void RenderSmoke(br_pixelmap* pRender_screen, br_pixelmap* pDepth_buffer, br_act LOG_TRACE("(%p, %p, %p, %p, %d)", pRender_screen, pDepth_buffer, pCamera, pCamera_to_world, pTime); not_lonely = 0; - DrawTheGlow(pRender_screen, pDepth_buffer, pCamera); + // DrawTheGlow(pRender_screen, pDepth_buffer, pCamera); if (gSmoke_flags != 0) { seed = rand(); diff --git a/src/DETHRACE/common/world.c b/src/DETHRACE/common/world.c index f1d86d7f..645b3b36 100644 --- a/src/DETHRACE/common/world.c +++ b/src/DETHRACE/common/world.c @@ -1590,7 +1590,17 @@ void KillGroovadelic(int pOwner) { int i; tGroovidelic_spec* the_groove; LOG_TRACE("(%d)", pOwner); - NOT_IMPLEMENTED(); + + for (i = 0; i < gGroovidelics_array_size; i++) { + the_groove = &gGroovidelics_array[i]; + if (the_groove->owner == pOwner + && the_groove->path_mode != eMove_controlled + && the_groove->path_mode != eMove_absolute + && the_groove->object_mode != eMove_controlled + && the_groove->object_mode != eMove_absolute) { + the_groove->owner = -999; + } + } } // IDA: void __usercall KillFunkotronic(int pOwner@) @@ -1598,7 +1608,18 @@ void KillFunkotronic(int pOwner) { int i; tFunkotronic_spec* the_funk; LOG_TRACE("(%d)", pOwner); - NOT_IMPLEMENTED(); + + for (i = 0; i < gFunkotronics_array_size; i++) { + the_funk = &gFunkotronics_array[i]; + if (the_funk->owner == pOwner + && the_funk->matrix_mode != eMove_controlled + && the_funk->matrix_mode != eMove_absolute + && the_funk->lighting_animation_type != eMove_controlled + && the_funk->lighting_animation_type != eMove_absolute + && (the_funk->texture_animation_data.frames_info.mode != eMove_controlled || the_funk->texture_animation_type)) { + the_funk->owner = -999; + } + } } // IDA: br_uint_32 __usercall DeleteBastards@(br_actor *pActor@, br_matrix34 *pMatrix@, void *pArg@) From 674e7fb849381bcd4d5a288c13776cc6ade003e5 Mon Sep 17 00:00:00 2001 From: Dethrace Labs Date: Sun, 11 Sep 2022 15:40:34 +1200 Subject: [PATCH 2/4] tidy --- src/DETHRACE/common/oppoproc.c | 143 ++------------------------------- src/DETHRACE/common/spark.c | 6 +- 2 files changed, 13 insertions(+), 136 deletions(-) diff --git a/src/DETHRACE/common/oppoproc.c b/src/DETHRACE/common/oppoproc.c index 99b493cc..9962f5c2 100644 --- a/src/DETHRACE/common/oppoproc.c +++ b/src/DETHRACE/common/oppoproc.c @@ -24,9 +24,8 @@ int StraightestArcForCorner2D(br_vector2* pCent, br_scalar* pRadius, br_scalar* NOT_IMPLEMENTED(); } -// FIXME: is this an older implementation? -// FIXME: is this function correct? -// FIXME: later iterations probably convert br_vector3 to br_vector2 +// There appears to be two different implementations of this function in different binaries. +// One does calculations in 2d space, this one calculates in 3d space. static void StraightestArcForCorner(float* p1, float* p2, float* p3, br_vector3* p4, br_vector3* p5, br_vector3* p6, br_vector3* p7, br_vector3* p8, float p9, float p10) { br_vector3 rel1; br_vector3 rel3; @@ -209,44 +208,12 @@ tFollow_path_result ProcessFollowPath(tOpponent_spec* pOpponent_spec, tProcess_o return FollowCheatyPath(pOpponent_spec); } if (!pIgnore_end && !data->made_it && data->borrowed_time_start + 1000 < gTime_stamp_for_this_munging && gTime_stamp_for_this_munging < data->borrowed_time_start + 10000) { - - // float v59, v58, v57, v55, v54; - // br_vector3 v56; - - // v59 = GetOpponentsSectionFinishNodePoint(pOpponent_spec, data->section_no)->v[0]; - // section_dir.v[0] = v59 - GetOpponentsSectionStartNodePoint(pOpponent_spec, data->section_no)->v[0]; - // v58 = GetOpponentsSectionFinishNodePoint(pOpponent_spec, data->section_no)->v[1]; - // section_dir.v[1] = v58 - GetOpponentsSectionStartNodePoint(pOpponent_spec, data->section_no)->v[1]; - // v57 = GetOpponentsSectionFinishNodePoint(pOpponent_spec, data->section_no)->v[2]; - // section_dir.v[2] = v57 - GetOpponentsSectionStartNodePoint(pOpponent_spec, data->section_no)->v[2]; - BrVector3Sub(§ion_dir, GetOpponentsSectionFinishNodePoint(pOpponent_spec, data->section_no), GetOpponentsSectionStartNodePoint(pOpponent_spec, data->section_no)); - - // v56.v[0] = pOpponent_spec->car_spec->car_master_actor->t.t.mat.m[3][0]; - // goal_dir.v[0] = v56.v[0] - GetOpponentsSectionStartNodePoint(pOpponent_spec, data->section_no)->v[0]; - // v55 = pOpponent_spec->car_spec->car_master_actor->t.t.mat.m[3][1]; - // goal_dir.v[1] = v55 - GetOpponentsSectionStartNodePoint(pOpponent_spec, data->section_no)->v[1]; - // v54 = pOpponent_spec->car_spec->car_master_actor->t.t.mat.m[3][2]; - // goal_dir.v[2] = v54 - GetOpponentsSectionStartNodePoint(pOpponent_spec, data->section_no)->v[2]; - BrVector3Sub(&goal_dir, &car_master_actor->t.t.translate.t, GetOpponentsSectionStartNodePoint(pOpponent_spec, data->section_no)); - dist_along = BrVector3LengthSquared(&goal_dir) / BrVector3LengthSquared(§ion_dir); - // (goal_dir.v[1] * section_dir.v[1] - // + goal_dir.v[2] * section_dir.v[2] - // + goal_dir.v[0] * section_dir.v[0]) - // / (section_dir.v[1] * section_dir.v[1] - // + section_dir.v[2] * section_dir.v[2] - // + section_dir.v[0] * section_dir.v[0]); - // section_v.v[0] = section_dir.v[0] * dist_along; - // section_v.v[1] = section_dir.v[1] * dist_along; - // section_v.v[2] = section_dir.v[2] * dist_along; BrVector3Scale(§ion_v, §ion_dir, dist_along); - // wank.v[0] = goal_dir.v[0] - section_v.v[0]; - // wank.v[1] = goal_dir.v[1] - section_v.v[1]; - // wank.v[2] = goal_dir.v[2] - section_v.v[2]; BrVector3Sub(&wank, &goal_dir, §ion_v); - goal_width = BrVector3Length(&wank); // sqrtf(wank.v[2] * wank.v[2] + wank.v[1] * wank.v[1] + wank.v[0] * wank.v[0]); + goal_width = BrVector3Length(&wank); if (GetOpponentsSectionWidth(pOpponent_spec, data->section_no) >= goal_width) { data->made_it = 1; } @@ -257,11 +224,6 @@ tFollow_path_result ProcessFollowPath(tOpponent_spec* pOpponent_spec, tProcess_o } car_spec->keys.acc = 1; speed = BrVector3Length(&car_spec->v); - // sqrtf( - // car_spec->v.v[2] * car_spec->v.v[2] - // + car_spec->v.v[1] * car_spec->v.v[1] - // + car_spec->v.v[0] * car_spec->v.v[0]); - if (speed > 0.2f) { data->has_moved_during_this_task = 1; pOpponent_spec->has_moved_at_some_point = 1; @@ -308,34 +270,13 @@ tFollow_path_result ProcessFollowPath(tOpponent_spec* pOpponent_spec, tProcess_o } } } - // car_to_end.v[0] = GetOpponentsSectionFinishNodePoint(pOpponent_spec, data->section_no)->v[0] - // - pOpponent_spec->car_spec->car_master_actor->t.t.mat.m[3][0]; - // car_to_end.v[1] = GetOpponentsSectionFinishNodePoint(pOpponent_spec, data->section_no)->v[1] - // - pOpponent_spec->car_spec->car_master_actor->t.t.mat.m[3][1]; - // car_to_end.v[2] = GetOpponentsSectionFinishNodePoint(pOpponent_spec, data->section_no)->v[2] - // - pOpponent_spec->car_spec->car_master_actor->t.t.mat.m[3][2]; - BrVector3Sub(&car_to_end, GetOpponentsSectionFinishNodePoint(pOpponent_spec, data->section_no), &pOpponent_spec->car_spec->car_master_actor->t.t.translate.t); car_to_end.v[1] = 0.0; dist_to_end = BrVector3Length(&car_to_end) * WORLD_SCALE; dist_to_goal = dist_to_end; if (dist_to_end > 15.0f) { - // float v53_2 = GetOpponentsSectionFinishNodePoint(pOpponent_spec, data->section_no)->v[0]; - // wank.v[0] = v53_2 - GetOpponentsSectionStartNodePoint(pOpponent_spec, data->section_no)->v[0]; - // float v52_1 = GetOpponentsSectionFinishNodePoint(pOpponent_spec, data->section_no)->v[1]; - // wank.v[1] = v52_1 - GetOpponentsSectionStartNodePoint(pOpponent_spec, data->section_no)->v[1]; - // float v51_0 = GetOpponentsSectionFinishNodePoint(pOpponent_spec, data->section_no)->v[2]; - // wank.v[2] = v51_0 - GetOpponentsSectionStartNodePoint(pOpponent_spec, data->section_no)->v[2]; BrVector3Sub(&wank, GetOpponentsSectionFinishNodePoint(pOpponent_spec, data->section_no), GetOpponentsSectionStartNodePoint(pOpponent_spec, data->section_no)); - BrVector3Normalise(&a, &wank); - // temp_2 = pOpponent_spec->car_spec->car_master_actor->t.t.mat.m[3][0]; - // wank.v[0] = temp_2 - GetOpponentsSectionStartNodePoint(pOpponent_spec, data->section_no)->v[0]; - // temp_1 = pOpponent_spec->car_spec->car_master_actor->t.t.mat.m[3][1]; - // wank.v[1] = temp_1 - GetOpponentsSectionStartNodePoint(pOpponent_spec, data->section_no)->v[1]; - // temp_0 = pOpponent_spec->car_spec->car_master_actor->t.t.mat.m[3][2]; - // wank.v[2] = temp_0 - GetOpponentsSectionStartNodePoint(pOpponent_spec, data->section_no)->v[2]; - BrVector3Sub(&wank, &pOpponent_spec->car_spec->car_master_actor->t.t.translate.t, GetOpponentsSectionStartNodePoint(pOpponent_spec, data->section_no)); dot_a = BrVector3Dot(&a, &wank); // v62.v[2] * wank.v[2] + v62.v[1] * wank.v[1] + v62.v[0] * wank.v[0]; @@ -343,64 +284,27 @@ tFollow_path_result ProcessFollowPath(tOpponent_spec* pOpponent_spec, tProcess_o wank2.v[2] = a.v[2] * dot_a; car_to_end.v[0] = wank2.v[0] - wank.v[0]; car_to_end.v[2] = wank2.v[2] - wank.v[2]; - car_to_end.v[1] = 0.0; - // float v16 = BrVector3Length(&car_to_end); // sqrtf(car_to_end.v[0] * car_to_end.v[0] + 0.0 * 0.0 + car_to_end.v[2] * car_to_end.v[2]); + car_to_end.v[1] = 0.0f; dist_to_end = BrVector3Length(&car_to_end) * WORLD_SCALE; if (dist_to_end < 15.0f) { - t = sqrtf(225.0 - dist_to_end * dist_to_end) / WORLD_SCALE; + t = sqrtf(225.0f - dist_to_end * dist_to_end) / WORLD_SCALE; if (t + dot_a >= 0.0) { wank.v[0] = a.v[0] * t; wank.v[2] = a.v[2] * t; wank.v[1] = 0.0; BrVector3Accumulate(&car_to_end, &wank); - // car_to_end.v[0] = wank.v[0] + car_to_end.v[0]; - // car_to_end.v[1] = car_to_end.v[1] + 0.0; - // car_to_end.v[2] = wank.v[2] + car_to_end.v[2]; } else { - // car_to_end.v[0] = GetOpponentsSectionStartNodePoint(pOpponent_spec, data->section_no)->v[0] - // - pOpponent_spec->car_spec->car_master_actor->t.t.mat.m[3][0]; - // car_to_end.v[1] = GetOpponentsSectionStartNodePoint(pOpponent_spec, data->section_no)->v[1] - // - pOpponent_spec->car_spec->car_master_actor->t.t.mat.m[3][1]; - // car_to_end.v[2] = GetOpponentsSectionStartNodePoint(pOpponent_spec, data->section_no)->v[2] - // - pOpponent_spec->car_spec->car_master_actor->t.t.mat.m[3][2]; BrVector3Sub(&car_to_end, GetOpponentsSectionStartNodePoint(pOpponent_spec, data->section_no), &pOpponent_spec->car_spec->car_master_actor->t.t.translate.t); dist_to_end = BrVector3Length(&car_to_end) * WORLD_SCALE; - // sqrtf( - // car_to_end.v[0] * car_to_end.v[0] - // + car_to_end.v[1] * car_to_end.v[1] - // + car_to_end.v[2] * car_to_end.v[2]) - // * 6.9; BrVector3Scale(&car_to_end, &car_to_end, 15.0f / dist_to_end); - // car_to_end.v[0] = 15.0 / dist_to_end * car_to_end.v[0]; - // car_to_end.v[1] = 15.0 / dist_to_end * car_to_end.v[1]; - // car_to_end.v[2] = 15.0 / dist_to_end * car_to_end.v[2]; } dist_to_end = 15.0f; } else if (dot_a < 0.0f) { - // car_to_end.v[0] = GetOpponentsSectionStartNodePoint(pOpponent_spec, data->section_no)->v[0] - // - pOpponent_spec->car_spec->car_master_actor->t.t.mat.m[3][0]; - // car_to_end.v[1] = GetOpponentsSectionStartNodePoint(pOpponent_spec, data->section_no)->v[1] - // - pOpponent_spec->car_spec->car_master_actor->t.t.mat.m[3][1]; - // car_to_end.v[2] = GetOpponentsSectionStartNodePoint(pOpponent_spec, data->section_no)->v[2] - // - pOpponent_spec->car_spec->car_master_actor->t.t.mat.m[3][2]; - // dist_to_end = sqrtf( - // car_to_end.v[0] * car_to_end.v[0] - // + car_to_end.v[1] * car_to_end.v[1] - // + car_to_end.v[2] * car_to_end.v[2]) - // * 6.9; - // car_to_end.v[0] = 15.0 / dist_to_end * car_to_end.v[0]; - // car_to_end.v[1] = 15.0 / dist_to_end * car_to_end.v[1]; - // car_to_end.v[2] = 15.0 / dist_to_end * car_to_end.v[2]; - BrVector3Sub(&car_to_end, GetOpponentsSectionStartNodePoint(pOpponent_spec, data->section_no), &pOpponent_spec->car_spec->car_master_actor->t.t.translate.t); dist_to_end = BrVector3Length(&car_to_end) * WORLD_SCALE; BrVector3Scale(&car_to_end, &car_to_end, 15.0f / dist_to_end); } } - // float v20 = car_spec->v.v[1] * car_to_end.v[1] - // + car_spec->v.v[2] * car_to_end.v[2] - // + car_spec->v.v[0] * car_to_end.v[0]; - // v94 = v20 / sqrtf(v20); section_width = GetOpponentsSectionWidth(pOpponent_spec, data->section_no) * WORLD_SCALE; if (!pIgnore_end && speed * 1.5f > dist_to_goal) { dr_dprintf("%s: ProcessFollowPath() - *** CHANGING SECTIONS ***", pOpponent_spec->car_spec->driver_name); @@ -422,6 +326,7 @@ tFollow_path_result ProcessFollowPath(tOpponent_spec* pOpponent_spec, tProcess_o } not_our_dir = (br_vector3*)&car_master_actor->t.t.mat.m[2]; + // FIXME: should be BrVector3Cross wank.v[0] = car_master_actor->t.t.mat.m[2][2] * car_to_end.v[1] - car_master_actor->t.t.mat.m[2][1] * car_to_end.v[2]; wank.v[1] = car_master_actor->t.t.mat.m[2][0] * car_to_end.v[2] - car_master_actor->t.t.mat.m[2][2] * car_to_end.v[0]; wank.v[2] = car_master_actor->t.t.mat.m[2][1] * car_to_end.v[0] - car_master_actor->t.t.mat.m[2][0] * car_to_end.v[1]; @@ -466,45 +371,23 @@ tFollow_path_result ProcessFollowPath(tOpponent_spec* pOpponent_spec, tProcess_o next_turning_radius = pOpponent_spec->car_spec->car_master_actor->t.t.translate.t.v[0] * -wank.v[2] + pOpponent_spec->car_spec->car_master_actor->t.t.translate.t.v[2] * wank.v[0]; next_corner_size = GetOpponentsSectionFinishNodePoint(pOpponent_spec, data->section_no)->v[0] * -wank.v[2]; next_turning_radius = next_turning_radius - (GetOpponentsSectionFinishNodePoint(pOpponent_spec, data->section_no)->v[2] * wank.v[0] + next_corner_size); + // FIXME: added temporary variable float v104 = -wank.v[2] * not_our_dir->v[0] + not_our_dir->v[2] * wank.v[0]; if (v104 * next_turning_radius > 0.0f) { goal_width = 0.0f; speed2d = speed * speed / 24.0f + speed * 1.5f; p = pOpponent_spec->car_spec->car_master_actor->t.t.translate.t; - // start.v[0] = -(next_turning_radius / v104) * not_our_dir->v[0]; - // start.v[1] = -(next_turning_radius / v104) * not_our_dir->v[1]; - // start.v[2] = -(next_turning_radius / v104) * not_our_dir->v[2]; BrVector3Scale(&start, not_our_dir, -(next_turning_radius / v104)); - // start.v[0] = pOpponent_spec->car_spec->car_master_actor->t.t.mat.m[3][0] + start.v[0]; - // start.v[1] = pOpponent_spec->car_spec->car_master_actor->t.t.mat.m[3][1] + start.v[1]; - // start.v[2] = pOpponent_spec->car_spec->car_master_actor->t.t.mat.m[3][2] + start.v[2]; BrVector3Accumulate(&start, &pOpponent_spec->car_spec->car_master_actor->t.t.translate.t); section_no = data->section_no; for (sx = 0; GetOpponentsNextSection(pOpponent_spec, section_no) != -1; sx++) { if (sx >= 4) { break; } - // int nxt_section_temp = GetOpponentsNextSection(pOpponent_spec, section_no); - // next.v[0] = GetOpponentsSectionFinishNodePoint(pOpponent_spec, nxt_section_temp)->v[0]; - // // nxt_section_temp = GetOpponentsNextSection(pOpponent_spec, section_no); - // next.v[1] = GetOpponentsSectionFinishNodePoint(pOpponent_spec, nxt_section_temp)->v[1]; - // // nxt_section_temp = GetOpponentsNextSection(pOpponent_spec, section_no); - // next.v[2] = GetOpponentsSectionFinishNodePoint(pOpponent_spec, nxt_section_temp)->v[2]; - // // nxt_section_temp = GetOpponentsNextSection(pOpponent_spec, data->section_no); BrVector3Copy(&next, GetOpponentsSectionFinishNodePoint(pOpponent_spec, GetOpponentsNextSection(pOpponent_spec, section_no))); next_width = GetOpponentsSectionWidth(pOpponent_spec, GetOpponentsNextSection(pOpponent_spec, section_no)); width = GetOpponentsSectionWidth(pOpponent_spec, data->section_no); - StraightestArcForCorner( - &corner_speed, - &corner_speed2, - &dot_a, - &p, - &start, - &next, - &p, - &start, - width, - next_width); + StraightestArcForCorner(&corner_speed, &corner_speed2, &dot_a, &p, &start, &next, &p, &start, width, next_width); dot_a *= WORLD_SCALE; goal_width = dot_a + goal_width; if (goal_width > speed2d) { @@ -527,17 +410,7 @@ tFollow_path_result ProcessFollowPath(tOpponent_spec* pOpponent_spec, tProcess_o } } } - // if ((car_spec->car_ID & 0xFF00) == 768) { - // effective_speed_factor = gCop_speed_factor; - // } else { - // effective_speed_factor = gOpponent_speed_factor; - // } effective_speed_factor = CAR_SPEC_GET_SPEED_FACTOR(car_spec); - // if (effective_speed_factor >= 1.0) { - // acc_factor = effective_speed_factor; - // } else { - // acc_factor = 1.0; - // } acc_factor = MAX(1.0f, effective_speed_factor); if (engine_damage <= 50 || engine_damage >= 98) { if (engine_damage >= 98) { diff --git a/src/DETHRACE/common/spark.c b/src/DETHRACE/common/spark.c index d944d374..605d0676 100644 --- a/src/DETHRACE/common/spark.c +++ b/src/DETHRACE/common/spark.c @@ -1173,7 +1173,7 @@ void RenderSmoke(br_pixelmap* pRender_screen, br_pixelmap* pDepth_buffer, br_act LOG_TRACE("(%p, %p, %p, %p, %d)", pRender_screen, pDepth_buffer, pCamera, pCamera_to_world, pTime); not_lonely = 0; - // DrawTheGlow(pRender_screen, pDepth_buffer, pCamera); + DrawTheGlow(pRender_screen, pDepth_buffer, pCamera); if (gSmoke_flags != 0) { seed = rand(); @@ -1833,6 +1833,10 @@ void DrawTheGlow(br_pixelmap* pRender_screen, br_pixelmap* pDepth_buffer, br_act tU32 seed; LOG_TRACE("(%p, %p, %p)", pRender_screen, pDepth_buffer, pCamera); + // FIXME: sometimes this function causes a segfault (most commonly when looking at a glow fairly close up and the camera swings away). Stubbing it out for now. + LOG_WARN_ONCE("DrawTheGlow is stubbed out"); + return; + if (gColumn_flags) { seed = rand(); srand(GetTotalTime()); From cea42b97c6a60587c41c7ba78bef552dbd8226c0 Mon Sep 17 00:00:00 2001 From: Dethrace Labs Date: Sun, 11 Sep 2022 15:46:25 +1200 Subject: [PATCH 3/4] tidy 2 --- src/DETHRACE/common/crush.c | 23 ++--------------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/src/DETHRACE/common/crush.c b/src/DETHRACE/common/crush.c index 1d5a348d..bcc079fa 100644 --- a/src/DETHRACE/common/crush.c +++ b/src/DETHRACE/common/crush.c @@ -937,8 +937,6 @@ int DoCrashEarnings(tCar_spec* pCar1, tCar_spec* pCar2) { } else { dam_acc_1 = pCar1->damage_magnitude_accumulator; } - // dam_acc_2 = pCar2 - // && (pCar2->driver <= eDriver_non_car ? (v21 = 0.0) : (v21 = pCar2->damage_magnitude_accumulator), v21 != 0.0); dam_acc_2 = 0; if (pCar2) { @@ -963,9 +961,6 @@ int DoCrashEarnings(tCar_spec* pCar1, tCar_spec* pCar2) { if (pCar1->pre_car_col_knackered || (pCar2 && pCar2->pre_car_col_knackered) || (pCar2 && pCar2->damage_magnitude_accumulator <= 0.00005f && pCar1->damage_magnitude_accumulator <= 0.00005f)) { return dam_acc_1 || (pCar2 && dam_acc_2); } - // if (!pCar1->pre_car_col_knackered - // && (pCar2 == NULL || !pCar2->pre_car_col_knackered) - // && (pCar2 == NULL || pCar2->damage_magnitude_accumulator > 0.00005f || pCar1->damage_magnitude_accumulator > 0.00005f)) { modified_location_1 = CalcModifiedLocation(pCar1); car_direction_1 = GetDirection(&pCar1->pre_car_col_velocity_car_space); @@ -1012,9 +1007,7 @@ int DoCrashEarnings(tCar_spec* pCar1, tCar_spec* pCar2) { if (car_1_culpable) { culprit = pCar1; victim = pCar2; - dp = BrVector3Dot(&pCar1->pre_car_col_direction, &pCar1->pre_car_col_direction); /* pCar1->pre_car_col_direction.v[2] * pCar2->pre_car_col_direction.v[2] - + pCar2->pre_car_col_direction.v[1] * pCar1->pre_car_col_direction.v[1] - + pCar2->pre_car_col_direction.v[0] * pCar1->pre_car_col_direction.v[0];*/ + dp = BrVector3Dot(&pCar1->pre_car_col_direction, &pCar2->pre_car_col_direction); if (modified_location_1 == eImpact_front && modified_location_2 == eImpact_front && pCar1->pre_car_col_speed > 0.001f && pCar2->pre_car_col_speed > 0.001f && dp < -0.7f) { head_on = 1; bonus_level = 2; @@ -1024,10 +1017,7 @@ int DoCrashEarnings(tCar_spec* pCar1, tCar_spec* pCar2) { } else if (car_2_culpable) { culprit = pCar2; victim = pCar1; - // dp = pCar1->pre_car_col_direction.v[2] * pCar2->pre_car_col_direction.v[2] - // + pCar2->pre_car_col_direction.v[1] * pCar1->pre_car_col_direction.v[1] - // + pCar2->pre_car_col_direction.v[0] * pCar1->pre_car_col_direction.v[0]; - dp = BrVector3Dot(&pCar1->pre_car_col_direction, &pCar1->pre_car_col_direction); + dp = BrVector3Dot(&pCar1->pre_car_col_direction, &pCar2->pre_car_col_direction); if (modified_location_1 == eImpact_front && modified_location_2 == eImpact_front && pCar1->pre_car_col_speed > 0.001f && pCar2->pre_car_col_speed > 0.001f && dp < -0.7f) { head_on = 1; bonus_level = 2; @@ -1037,7 +1027,6 @@ int DoCrashEarnings(tCar_spec* pCar1, tCar_spec* pCar2) { } } } else { - // LOG_DEBUG("no pCar2, timediff is %d", the_time - pCar1->time_last_hit); if (the_time - pCar1->time_last_hit >= 3000) { return 1; } @@ -1137,14 +1126,8 @@ int DoCrashEarnings(tCar_spec* pCar1, tCar_spec* pCar2) { if (pCar1->number_of_wheels_on_ground) { car_off_ground_1 = 0; } else { - // car_1_pos.v[0] = pCar1->car_master_actor->t.t.mat.m[3][0] / 6.9000001; - // car_1_pos.v[1] = pCar1->car_master_actor->t.t.mat.m[3][1] / 6.9000001; - // car_1_pos.v[2] = pCar1->car_master_actor->t.t.mat.m[3][2] / 6.9000001; BrVector3InvScale(&car_1_pos, &pCar1->car_master_actor->t.t.translate.t, WORLD_SCALE); BrMatrix34ApplyV(&car_1_offset, &pCar1->car_model_actors[pCar1->principal_car_actor].actor->t.t.translate.t, &pCar1->car_master_actor->t.t.mat); - // car_1_pos.v[0] = car_1_offset.v[0] + car_1_pos.v[0]; - // car_1_pos.v[1] = car_1_offset.v[1] + car_1_pos.v[1]; - // car_1_pos.v[2] = car_1_offset.v[2] + car_1_pos.v[2]; BrVector3Accumulate(&car_1_pos, &car_1_offset); car_1_pos.v[1] += 0.15f; car_1_height = FindYVerticallyBelow2(&car_1_pos); @@ -1212,8 +1195,6 @@ int DoCrashEarnings(tCar_spec* pCar1, tCar_spec* pCar2) { pCar2->damage_magnitude_accumulator = 0.0f; } return 1; - - // return dam_acc_1 || pCar2 && dam_acc_2; } // IDA: void __usercall DoWheelDamage(tU32 pFrame_period@) From 057a23fced85ae4896277ed102a9b433fcb674f0 Mon Sep 17 00:00:00 2001 From: Dethrace Labs Date: Sun, 11 Sep 2022 15:49:24 +1200 Subject: [PATCH 4/4] tidy 3 --- src/DETHRACE/common/opponent.c | 43 +--------------------------------- 1 file changed, 1 insertion(+), 42 deletions(-) diff --git a/src/DETHRACE/common/opponent.c b/src/DETHRACE/common/opponent.c index 9d8fea83..e7681065 100644 --- a/src/DETHRACE/common/opponent.c +++ b/src/DETHRACE/common/opponent.c @@ -1758,58 +1758,17 @@ int MassageOpponentPosition(tOpponent_spec* pOpponent_spec, int pMassage_count) direction_v.v[1] = -pOpponent_spec->car_spec->car_master_actor->t.t.mat.m[2][1]; direction_v.v[2] = -pOpponent_spec->car_spec->car_master_actor->t.t.mat.m[2][2]; if (pMassage_count % 4 >= 2) { - // displacement_0 = 1.0 * direction_v_2 - direction_v_1 * 0.0; - // displacement_1 = direction_v_0 * 0.0 - 0.0 * direction_v_2; - // displacement_2 = 0.0 * direction_v_1 - direction_v_0 * 1.0; + BrVector3Cross(&displacement, &positive_y_vector, &direction_v); - // v8 = sqrtf(displacement_0 * displacement_0 + displacement_1 * displacement_1 + displacement_2 * displacement_2); - // if (v10 | v11) { - // displacement_0 = 1.0; - // displacement_1 = 0.0; - // displacement_2 = 0.0; - // } else { - - // a_0 = v8; - // v12 = 1.0 / a_0; - // a_1 = v12; - // displacement_0 = v12 * displacement_0; - // displacement_1 = displacement_1 * a_1; - // displacement_2 = displacement_2 * a_1; - // } BrVector3Normalise(&displacement, &displacement); - // displacement_0 = (double)(pMassage_count / 4) * 0.1 * displacement_0; - // displacement_1 = (double)(pMassage_count / 4) * 0.1 * displacement_1; - // displacement_2 = (double)(pMassage_count / 4) * 0.1 * displacement_2; BrVector3Scale(&displacement, &displacement, (pMassage_count / 4) * 0.1f); } else { - // v3 = sqrtf(direction_v_2 * direction_v_2 + direction_v_0 * direction_v_0 + direction_v_1 * direction_v_1); - // if (v5 | v6) { - // displacement_0 = 1.0; - // displacement_1 = 0.0; - // displacement_2 = 0.0; - // } else { - // a_2 = v3; - // v7 = 1.0 / a_2; - // a_2 = v7; - // displacement_0 = v7 * direction_v_0; - // displacement_1 = direction_v_1 * a_2; - // displacement_2 = direction_v_2 * a_2; - // } BrVector3Normalise(&displacement, &displacement); - // displacement_0 = (double)(pMassage_count / 4) * 0.5 * displacement_0; - // displacement_1 = (double)(pMassage_count / 4) * 0.5 * displacement_1; - // displacement_2 = (double)(pMassage_count / 4) * 0.5 * displacement_2; BrVector3Scale(&displacement, &displacement, (pMassage_count / 4) * 0.5f); } if (pMassage_count % 2) { - // displacement_0 = -displacement_0; - // displacement_1 = -displacement_1; - // displacement_2 = -displacement_2; BrVector3Negate(&displacement, &displacement); } - // car_trans->v[0] = car_trans->v[0] + displacement_0; - // car_trans->v[1] = car_trans->v[1] + displacement_1; - // car_trans->v[2] = car_trans->v[2] + displacement_2; BrVector3Accumulate(car_trans, &displacement); } else { car_trans->v[1] = (pMassage_count - 20) * 2.0f + car_trans->v[1];