Subversion Repositories Games.Carmageddon

Rev

Rev 20 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 20 Rev 21
Line 1234... Line 1234...
1234
            if ((BrVector3Length(&pOpponent_spec->car_spec->v) < .01f && BrVector3Length(&pOpponent_spec->car_spec->omega) < 1.f) || gTime_stamp_for_this_munging - pOpponent_spec->levitate_data.time_started > 4000) {
1234
            if ((BrVector3Length(&pOpponent_spec->car_spec->v) < .01f && BrVector3Length(&pOpponent_spec->car_spec->omega) < 1.f) || gTime_stamp_for_this_munging - pOpponent_spec->levitate_data.time_started > 4000) {
1235
                pOpponent_spec->levitate_data.waiting_to_levitate = 0;
1235
                pOpponent_spec->levitate_data.waiting_to_levitate = 0;
1236
                pOpponent_spec->levitate_data.time_started = gTime_stamp_for_this_munging;
1236
                pOpponent_spec->levitate_data.time_started = gTime_stamp_for_this_munging;
1237
                pOpponent_spec->levitate_data.initial_y = pOpponent_spec->car_spec->car_master_actor->t.t.translate.t.v[1];
1237
                pOpponent_spec->levitate_data.initial_y = pOpponent_spec->car_spec->car_master_actor->t.t.translate.t.v[1];
1238
                if (pOpponent_spec->car_spec->has_been_stolen) {
1238
                if (pOpponent_spec->car_spec->has_been_stolen) {
1239
                    NewTextHeadupSlot(4, 250, 2500, -4, GetMiscString(kMiscString_CarAddedToChangeCarList));
1239
                    NewTextHeadupSlot(eHeadupSlot_misc, 250, 2500, -4, GetMiscString(kMiscString_CarAddedToChangeCarList));
1240
                }
1240
                }
1241
            } else {
1241
            } else {
1242
                pOpponent_spec->car_spec->brake_force = 15.f * pOpponent_spec->car_spec->M;
1242
                pOpponent_spec->car_spec->brake_force = 15.f * pOpponent_spec->car_spec->M;
1243
                pOpponent_spec->car_spec->acc_force = 0.f;
1243
                pOpponent_spec->car_spec->acc_force = 0.f;
1244
                BrVector3InvScale(&pOpponent_spec->car_spec->omega, &pOpponent_spec->car_spec->omega,
1244
                BrVector3InvScale(&pOpponent_spec->car_spec->omega, &pOpponent_spec->car_spec->omega,
Line 2530... Line 2530...
2530
        gProgram_state.AI_vehicles.cops[i].cunting_buttfuck_timer = 0;
2530
        gProgram_state.AI_vehicles.cops[i].cunting_buttfuck_timer = 0;
2531
        gProgram_state.AI_vehicles.cops[i].finished_for_this_race = 0;
2531
        gProgram_state.AI_vehicles.cops[i].finished_for_this_race = 0;
2532
        gProgram_state.AI_vehicles.cops[i].physics_me = 1;
2532
        gProgram_state.AI_vehicles.cops[i].physics_me = 1;
2533
        gProgram_state.AI_vehicles.cops[i].pursue_from_start = 0;
2533
        gProgram_state.AI_vehicles.cops[i].pursue_from_start = 0;
2534
        gProgram_state.AI_vehicles.cops[i].cheating = 0;
2534
        gProgram_state.AI_vehicles.cops[i].cheating = 0;
-
 
2535
        gProgram_state.AI_vehicles.cops[i].knackeredness_detected = 0;
2535
        gProgram_state.AI_vehicles.cops[i].murder_reported = 0;
2536
        gProgram_state.AI_vehicles.cops[i].murder_reported = 0;
2536
        gProgram_state.AI_vehicles.cops[i].finished_for_this_race = 0;
2537
        gProgram_state.AI_vehicles.cops[i].finished_for_this_race = 0;
2537
        gProgram_state.AI_vehicles.cops[i].players_section_when_last_calced_full_path = -1;
2538
        gProgram_state.AI_vehicles.cops[i].players_section_when_last_calced_full_path = -1;
2538
        gProgram_state.AI_vehicles.cops[i].nnext_sections = 0;
2539
        gProgram_state.AI_vehicles.cops[i].nnext_sections = 0;
2539
        gProgram_state.AI_vehicles.cops[i].new_objective_required = 1;
2540
        gProgram_state.AI_vehicles.cops[i].new_objective_required = 1;
Line 3055... Line 3056...
3055
            ObjectiveComplete(&gProgram_state.AI_vehicles.opponents[i]);
3056
            ObjectiveComplete(&gProgram_state.AI_vehicles.opponents[i]);
3056
        }
3057
        }
3057
        for (i = 0; i < gProgram_state.AI_vehicles.number_of_cops; i++) {
3058
        for (i = 0; i < gProgram_state.AI_vehicles.number_of_cops; i++) {
3058
            ObjectiveComplete(&gProgram_state.AI_vehicles.cops[i]);
3059
            ObjectiveComplete(&gProgram_state.AI_vehicles.cops[i]);
3059
        }
3060
        }
3060
        NewTextHeadupSlot(4, 0, 2000, -1, "OPPONENTS SWITCHED ON");
3061
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "OPPONENTS SWITCHED ON");
3061
    } else {
3062
    } else {
3062
        for (i = 0; i < gProgram_state.AI_vehicles.number_of_opponents; i++) {
3063
        for (i = 0; i < gProgram_state.AI_vehicles.number_of_opponents; i++) {
3063
            gProgram_state.AI_vehicles.opponents[i].physics_me = 0;
3064
            gProgram_state.AI_vehicles.opponents[i].physics_me = 0;
3064
        }
3065
        }
3065
        for (i = 0; i < gProgram_state.AI_vehicles.number_of_cops; i++) {
3066
        for (i = 0; i < gProgram_state.AI_vehicles.number_of_cops; i++) {
3066
            gProgram_state.AI_vehicles.opponents[i].physics_me = 0;
3067
            gProgram_state.AI_vehicles.opponents[i].physics_me = 0;
3067
        }
3068
        }
3068
        gActive_car_list_rebuild_required = 1;
3069
        gActive_car_list_rebuild_required = 1;
3069
        RebuildActiveCarList();
3070
        RebuildActiveCarList();
3070
        NewTextHeadupSlot(4, 0, 2000, -1, "OPPONENTS SWITCHED OFF");
3071
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "OPPONENTS SWITCHED OFF");
3071
    }
3072
    }
3072
}
3073
}
3073
 
3074
 
3074
// IDA: void __cdecl ToggleMellowOpponents()
3075
// IDA: void __cdecl ToggleMellowOpponents()
3075
void ToggleMellowOpponents(void) {
3076
void ToggleMellowOpponents(void) {
3076
    int i;
3077
    int i;
3077
    LOG_TRACE("()");
3078
    LOG_TRACE("()");
3078
 
3079
 
3079
    gMellow_opponents = !gMellow_opponents;
3080
    gMellow_opponents = !gMellow_opponents;
3080
    if (gMellow_opponents) {
3081
    if (gMellow_opponents) {
3081
        NewTextHeadupSlot(4, 0, 3000, -1, "Opponents all nice and fluffy");
3082
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 3000, -1, "Opponents all nice and fluffy");
3082
        for (i = 0; i < gProgram_state.AI_vehicles.number_of_opponents; i++) {
3083
        for (i = 0; i < gProgram_state.AI_vehicles.number_of_opponents; i++) {
3083
            ObjectiveComplete(&gProgram_state.AI_vehicles.opponents[i]);
3084
            ObjectiveComplete(&gProgram_state.AI_vehicles.opponents[i]);
3084
        }
3085
        }
3085
    } else {
3086
    } else {
3086
        NewTextHeadupSlot(4, 0, 2000, -1, "Opponents hostile again");
3087
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "Opponents hostile again");
3087
    }
3088
    }
3088
}
3089
}
3089
 
3090
 
3090
// IDA: void __cdecl RepairOpponentsSystems()
3091
// IDA: void __cdecl RepairOpponentsSystems()
3091
void RepairOpponentsSystems(void) {
3092
void RepairOpponentsSystems(void) {
Line 3097... Line 3098...
3097
            TotallyRepairACar(gProgram_state.AI_vehicles.opponents[i].car_spec);
3098
            TotallyRepairACar(gProgram_state.AI_vehicles.opponents[i].car_spec);
3098
            TurnOpponentPhysicsOff(&gProgram_state.AI_vehicles.opponents[i]);
3099
            TurnOpponentPhysicsOff(&gProgram_state.AI_vehicles.opponents[i]);
3099
            gProgram_state.AI_vehicles.opponents[i].knackeredness_detected = 0;
3100
            gProgram_state.AI_vehicles.opponents[i].knackeredness_detected = 0;
3100
        }
3101
        }
3101
    }
3102
    }
3102
    NewTextHeadupSlot(4, 0, 3000, -1, "Opponents systems repaired (but not bodywork)");
3103
    NewTextHeadupSlot(eHeadupSlot_misc, 0, 3000, -1, "Opponents systems repaired (but not bodywork)");
3103
}
3104
}
3104
 
3105
 
3105
// IDA: void __usercall CopyVertex(br_vertex *pDest_vertex@<EAX>, br_vertex *pSrc_vertex@<EDX>)
3106
// IDA: void __usercall CopyVertex(br_vertex *pDest_vertex@<EAX>, br_vertex *pSrc_vertex@<EDX>)
3106
//  Suffix added to avoid duplicate symbol
3107
//  Suffix added to avoid duplicate symbol
3107
void CopyVertex__opponent(br_vertex* pDest_vertex, br_vertex* pSrc_vertex) {
3108
void CopyVertex__opponent(br_vertex* pDest_vertex, br_vertex* pSrc_vertex) {
Line 3310... Line 3311...
3310
    LOG_TRACE("(%d, %d)", pMax_not_min, pAdjustment);
3311
    LOG_TRACE("(%d, %d)", pMax_not_min, pAdjustment);
3311
 
3312
 
3312
    if (gOppo_paths_shown) {
3313
    if (gOppo_paths_shown) {
3313
        section_no = FindNearestPathSection(&gSelf->t.t.translate.t, &direction_v, &intersect, &distance);
3314
        section_no = FindNearestPathSection(&gSelf->t.t.translate.t, &direction_v, &intersect, &distance);
3314
        if (!gAlready_elasticating && distance > 10.f) {
3315
        if (!gAlready_elasticating && distance > 10.f) {
3315
            NewTextHeadupSlot(4, 0, 2000, -1, "Can't find any paths close enough");
3316
            NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "Can't find any paths close enough");
3316
        } else {
3317
        } else {
3317
            BrVector3Sub(&wank, &gSelf->t.t.translate.t, &gProgram_state.AI_vehicles.path_nodes[gProgram_state.AI_vehicles.path_sections[section_no].node_indices[0]].p);
3318
            BrVector3Sub(&wank, &gSelf->t.t.translate.t, &gProgram_state.AI_vehicles.path_nodes[gProgram_state.AI_vehicles.path_sections[section_no].node_indices[0]].p);
3318
            dist_to_start = BrVector3Length(&wank);
3319
            dist_to_start = BrVector3Length(&wank);
3319
            BrVector3Sub(&wank, &gSelf->t.t.translate.t, &gProgram_state.AI_vehicles.path_nodes[gProgram_state.AI_vehicles.path_sections[section_no].node_indices[1]].p);
3320
            BrVector3Sub(&wank, &gSelf->t.t.translate.t, &gProgram_state.AI_vehicles.path_nodes[gProgram_state.AI_vehicles.path_sections[section_no].node_indices[1]].p);
3320
            dist_to_finish = BrVector3Length(&wank);
3321
            dist_to_finish = BrVector3Length(&wank);
Line 3348... Line 3349...
3348
                sprintf(str, "Towards section start - Min Speed %d mph - Max speed %d mph",
3349
                sprintf(str, "Towards section start - Min Speed %d mph - Max speed %d mph",
3349
                    (int)(2.2f * gProgram_state.AI_vehicles.path_sections[section_no].min_speed[0]),
3350
                    (int)(2.2f * gProgram_state.AI_vehicles.path_sections[section_no].min_speed[0]),
3350
                    (int)(2.2f * gProgram_state.AI_vehicles.path_sections[section_no].max_speed[0]));
3351
                    (int)(2.2f * gProgram_state.AI_vehicles.path_sections[section_no].max_speed[0]));
3351
            }
3352
            }
3352
            ShowOppoPaths();
3353
            ShowOppoPaths();
3353
            NewTextHeadupSlot(4, 0, 2000, -1, str);
3354
            NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, str);
3354
        }
3355
        }
3355
    }
3356
    }
3356
}
3357
}
3357
 
3358
 
3358
// IDA: void __cdecl RecalcNearestPathSectionWidth(br_scalar pAdjustment)
3359
// IDA: void __cdecl RecalcNearestPathSectionWidth(br_scalar pAdjustment)
Line 3366... Line 3367...
3366
 
3367
 
3367
    if (gOppo_paths_shown) {
3368
    if (gOppo_paths_shown) {
3368
        if (!gAlready_elasticating) {
3369
        if (!gAlready_elasticating) {
3369
            section_no = FindNearestPathSection(&gSelf->t.t.translate.t, &direction_v, &intersect, &distance);
3370
            section_no = FindNearestPathSection(&gSelf->t.t.translate.t, &direction_v, &intersect, &distance);
3370
            if (distance > 10.f) {
3371
            if (distance > 10.f) {
3371
                NewTextHeadupSlot(4, 0, 2000, -1, "Can't find any paths close enough");
3372
                NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "Can't find any paths close enough");
3372
                return;
3373
                return;
3373
            }
3374
            }
3374
        } else {
3375
        } else {
3375
            section_no = gMobile_section;
3376
            section_no = gMobile_section;
3376
        }
3377
        }
Line 3378... Line 3379...
3378
        if (gProgram_state.AI_vehicles.path_sections[section_no].width < .05f) {
3379
        if (gProgram_state.AI_vehicles.path_sections[section_no].width < .05f) {
3379
            gProgram_state.AI_vehicles.path_sections[section_no].width = .05f;
3380
            gProgram_state.AI_vehicles.path_sections[section_no].width = .05f;
3380
        }
3381
        }
3381
        ShowOppoPaths();
3382
        ShowOppoPaths();
3382
        sprintf(str, "Width %2.1f BRU", 2.f * gProgram_state.AI_vehicles.path_sections[section_no].width);
3383
        sprintf(str, "Width %2.1f BRU", 2.f * gProgram_state.AI_vehicles.path_sections[section_no].width);
3383
        NewTextHeadupSlot(4, 0, 2000, -1, str);
3384
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, str);
3384
    }
3385
    }
3385
}
3386
}
3386
 
3387
 
3387
// IDA: void __usercall CalcNegativeXVector(br_vector3 *pNegative_x_vector@<EAX>, br_vector3 *pStart@<EDX>, br_vector3 *pFinish@<EBX>, br_scalar pLength)
3388
// IDA: void __usercall CalcNegativeXVector(br_vector3 *pNegative_x_vector@<EAX>, br_vector3 *pStart@<EDX>, br_vector3 *pFinish@<EBX>, br_scalar pLength)
3388
void CalcNegativeXVector(br_vector3* pNegative_x_vector, br_vector3* pStart, br_vector3* pFinish, br_scalar pLength) {
3389
void CalcNegativeXVector(br_vector3* pNegative_x_vector, br_vector3* pStart, br_vector3* pFinish, br_scalar pLength) {
Line 3838... Line 3839...
3838
 
3839
 
3839
    if (!gOppo_paths_shown) {
3840
    if (!gOppo_paths_shown) {
3840
        if (gOppo_path_actor != NULL) {
3841
        if (gOppo_path_actor != NULL) {
3841
            gOppo_path_actor->render_style = BR_RSTYLE_NONE;
3842
            gOppo_path_actor->render_style = BR_RSTYLE_NONE;
3842
        }
3843
        }
3843
        NewTextHeadupSlot(4, 0, 1000, -1, "Not displaying any paths");
3844
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 1000, -1, "Not displaying any paths");
3844
    } else {
3845
    } else {
3845
        RebuildOppoPathModel();
3846
        RebuildOppoPathModel();
3846
        sprintf(str, "Total %d nodes, %d sections",
3847
        sprintf(str, "Total %d nodes, %d sections",
3847
            gProgram_state.AI_vehicles.number_of_path_nodes,
3848
            gProgram_state.AI_vehicles.number_of_path_nodes,
3848
            gProgram_state.AI_vehicles.number_of_path_sections);
3849
            gProgram_state.AI_vehicles.number_of_path_sections);
3849
        NewTextHeadupSlot(4, 0, 1000, -1, str);
3850
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 1000, -1, str);
3850
    }
3851
    }
3851
    if (ConsistencyCheck()) {
3852
    if (ConsistencyCheck()) {
3852
        WriteOutOppoPaths();
3853
        WriteOutOppoPaths();
3853
    }
3854
    }
3854
}
3855
}
Line 3978... Line 3979...
3978
        one_wayness = gProgram_state.AI_vehicles.path_sections[gMobile_section].one_way;
3979
        one_wayness = gProgram_state.AI_vehicles.path_sections[gMobile_section].one_way;
3979
        new_node = ReallocExtraPathNodes(1);
3980
        new_node = ReallocExtraPathNodes(1);
3980
        gMobile_section = ReallocExtraPathSections(1);
3981
        gMobile_section = ReallocExtraPathSections(1);
3981
    } else {
3982
    } else {
3982
        if (!gOppo_paths_shown) {
3983
        if (!gOppo_paths_shown) {
3983
            NewTextHeadupSlot(4, 0, 2000, -1, "You must show paths before adding to them (F5)");
3984
            NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "You must show paths before adding to them (F5)");
3984
            return;
3985
            return;
3985
        }
3986
        }
3986
        if (gProgram_state.AI_vehicles.number_of_path_nodes == 0) {
3987
        if (gProgram_state.AI_vehicles.number_of_path_nodes == 0) {
3987
            NewTextHeadupSlot(4, 0, 2000, -1, "Not implemented yet. Go away.");
3988
            NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "Not implemented yet. Go away.");
3988
            return;
3989
            return;
3989
        }
3990
        }
3990
        old_node = FindNearestPathNode(&gSelf->t.t.translate.t, &distance);
3991
        old_node = FindNearestPathNode(&gSelf->t.t.translate.t, &distance);
3991
        if (distance > 10.f) {
3992
        if (distance > 10.f) {
3992
            NewTextHeadupSlot(4, 0, 2000, -1, "Can't find any nodes close enough");
3993
            NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "Can't find any nodes close enough");
3993
            return;
3994
            return;
3994
        }
3995
        }
3995
        original_type = 0;
3996
        original_type = 0;
3996
        if (gProgram_state.AI_vehicles.path_nodes[old_node].number_of_sections != 0) {
3997
        if (gProgram_state.AI_vehicles.path_nodes[old_node].number_of_sections != 0) {
3997
            for (section_no_index = 1; section_no_index < gProgram_state.AI_vehicles.path_nodes[old_node].number_of_sections; section_no_index++) {
3998
            for (section_no_index = 1; section_no_index < gProgram_state.AI_vehicles.path_nodes[old_node].number_of_sections; section_no_index++) {
Line 4028... Line 4029...
4028
    gProgram_state.AI_vehicles.path_nodes[new_node].number_of_sections += 1;
4029
    gProgram_state.AI_vehicles.path_nodes[new_node].number_of_sections += 1;
4029
    gProgram_state.AI_vehicles.path_nodes[old_node].sections[gProgram_state.AI_vehicles.path_nodes[old_node].number_of_sections] = gMobile_section;
4030
    gProgram_state.AI_vehicles.path_nodes[old_node].sections[gProgram_state.AI_vehicles.path_nodes[old_node].number_of_sections] = gMobile_section;
4030
    gProgram_state.AI_vehicles.path_nodes[old_node].number_of_sections += 1;
4031
    gProgram_state.AI_vehicles.path_nodes[old_node].number_of_sections += 1;
4031
    ShowOppoPaths();
4032
    ShowOppoPaths();
4032
    sprintf(str, "New section #%d, new node #%d", gMobile_section, new_node);
4033
    sprintf(str, "New section #%d, new node #%d", gMobile_section, new_node);
4033
    NewTextHeadupSlot(4, 0, 2000, -1, str);
4034
    NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, str);
4034
}
4035
}
4035
 
4036
 
4036
// IDA: void __cdecl InsertAndElasticate()
4037
// IDA: void __cdecl InsertAndElasticate()
4037
void InsertAndElasticate(void) {
4038
void InsertAndElasticate(void) {
4038
    tS16 inserted_node;
4039
    tS16 inserted_node;
Line 4063... Line 4064...
4063
            &intersect);
4064
            &intersect);
4064
        if (BrVector3Length(&wank) == 0.f) {
4065
        if (BrVector3Length(&wank) == 0.f) {
4065
            not_perp = 1;
4066
            not_perp = 1;
4066
        }
4067
        }
4067
        if (not_perp || distance > 10.f) {
4068
        if (not_perp || distance > 10.f) {
4068
            NewTextHeadupSlot(4, 0, 2000, -1, "Get nearer to the section");
4069
            NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "Get nearer to the section");
4069
        } else {
4070
        } else {
4070
            new_section = ReallocExtraPathSections(1);
4071
            new_section = ReallocExtraPathSections(1);
4071
            if (gAlready_elasticating) {
4072
            if (gAlready_elasticating) {
4072
                inserted_node = gProgram_state.AI_vehicles.path_sections[gMobile_section].node_indices[1];
4073
                inserted_node = gProgram_state.AI_vehicles.path_sections[gMobile_section].node_indices[1];
4073
                section_type = gProgram_state.AI_vehicles.path_sections[gMobile_section].type;
4074
                section_type = gProgram_state.AI_vehicles.path_sections[gMobile_section].type;
Line 4100... Line 4101...
4100
            gProgram_state.AI_vehicles.path_nodes[elasticatey_node].number_of_sections += 1;
4101
            gProgram_state.AI_vehicles.path_nodes[elasticatey_node].number_of_sections += 1;
4101
            gAlready_elasticating = 1;
4102
            gAlready_elasticating = 1;
4102
            ShowOppoPaths();
4103
            ShowOppoPaths();
4103
            sprintf(str, "New section %d, new node #%d inserted into section #%d",
4104
            sprintf(str, "New section %d, new node #%d inserted into section #%d",
4104
                gMobile_section, inserted_node, section_no);
4105
                gMobile_section, inserted_node, section_no);
4105
            NewTextHeadupSlot(4, 0, 2000, -1, str);
4106
            NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, str);
4106
        }
4107
        }
4107
    }
4108
    }
4108
}
4109
}
4109
 
4110
 
4110
// IDA: void __cdecl InsertAndDontElasticate()
4111
// IDA: void __cdecl InsertAndDontElasticate()
Line 4129... Line 4130...
4129
        BrVector3Sub(&wank, &gProgram_state.AI_vehicles.path_nodes[gProgram_state.AI_vehicles.path_sections[section_no].node_indices[1]].p, &intersect);
4130
        BrVector3Sub(&wank, &gProgram_state.AI_vehicles.path_nodes[gProgram_state.AI_vehicles.path_sections[section_no].node_indices[1]].p, &intersect);
4130
        if (BrVector3Length(&wank) == 0.f) {
4131
        if (BrVector3Length(&wank) == 0.f) {
4131
            not_perp = 1;
4132
            not_perp = 1;
4132
        }
4133
        }
4133
        if (not_perp || distance > 10.f) {
4134
        if (not_perp || distance > 10.f) {
4134
            NewTextHeadupSlot(4, 0, 2000, -1, "Get nearer to the section");
4135
            NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "Get nearer to the section");
4135
        } else {
4136
        } else {
4136
            if (gAlready_elasticating) {
4137
            if (gAlready_elasticating) {
4137
                gAlready_elasticating = 0;
4138
                gAlready_elasticating = 0;
4138
                inserted_node = gProgram_state.AI_vehicles.path_sections[gMobile_section].node_indices[1];
4139
                inserted_node = gProgram_state.AI_vehicles.path_sections[gMobile_section].node_indices[1];
4139
            } else {
4140
            } else {
Line 4141... Line 4142...
4141
                gProgram_state.AI_vehicles.path_nodes[inserted_node].number_of_sections = 0;
4142
                gProgram_state.AI_vehicles.path_nodes[inserted_node].number_of_sections = 0;
4142
            }
4143
            }
4143
            InsertThisNodeInThisSectionHere(inserted_node, section_no, &gSelf->t.t.translate.t);
4144
            InsertThisNodeInThisSectionHere(inserted_node, section_no, &gSelf->t.t.translate.t);
4144
            ShowOppoPaths();
4145
            ShowOppoPaths();
4145
            sprintf(str, "New node #%d inserted into section #%d", inserted_node, section_no);
4146
            sprintf(str, "New node #%d inserted into section #%d", inserted_node, section_no);
4146
            NewTextHeadupSlot(4, 0, 2000, -1, str);
4147
            NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, str);
4147
        }
4148
        }
4148
    }
4149
    }
4149
}
4150
}
4150
 
4151
 
4151
// IDA: void __cdecl DropDeadEndNode()
4152
// IDA: void __cdecl DropDeadEndNode()
Line 4160... Line 4161...
4160
            &gSelf->t.t.translate.t);
4161
            &gSelf->t.t.translate.t);
4161
        ShowOppoPaths();
4162
        ShowOppoPaths();
4162
        sprintf(str, "New section #%d, finish node #%d",
4163
        sprintf(str, "New section #%d, finish node #%d",
4163
            gMobile_section,
4164
            gMobile_section,
4164
            gProgram_state.AI_vehicles.path_sections[gMobile_section].node_indices[1]);
4165
            gProgram_state.AI_vehicles.path_sections[gMobile_section].node_indices[1]);
4165
        NewTextHeadupSlot(4, 0, 4000, -1, str);
4166
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 4000, -1, str);
4166
    }
4167
    }
4167
}
4168
}
4168
 
4169
 
4169
// IDA: void __cdecl DropNodeOnNodeAndStopElasticating()
4170
// IDA: void __cdecl DropNodeOnNodeAndStopElasticating()
4170
void DropNodeOnNodeAndStopElasticating(void) {
4171
void DropNodeOnNodeAndStopElasticating(void) {
Line 4174... Line 4175...
4174
    LOG_TRACE("()");
4175
    LOG_TRACE("()");
4175
 
4176
 
4176
    if (gAlready_elasticating) {
4177
    if (gAlready_elasticating) {
4177
        node_no = FindNearestPathNode(&gSelf->t.t.translate.t, &distance);
4178
        node_no = FindNearestPathNode(&gSelf->t.t.translate.t, &distance);
4178
        if (gProgram_state.AI_vehicles.path_sections[gMobile_section].node_indices[0] == node_no || distance > 10.f) {
4179
        if (gProgram_state.AI_vehicles.path_sections[gMobile_section].node_indices[0] == node_no || distance > 10.f) {
4179
            NewTextHeadupSlot(4, 0, 2000, -1, "Can't find any nodes close enough");
4180
            NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "Can't find any nodes close enough");
4180
        } else if (gProgram_state.AI_vehicles.path_nodes[node_no].number_of_sections >= COUNT_OF(gProgram_state.AI_vehicles.path_nodes[node_no].sections)) {
4181
        } else if (gProgram_state.AI_vehicles.path_nodes[node_no].number_of_sections >= COUNT_OF(gProgram_state.AI_vehicles.path_nodes[node_no].sections)) {
4181
            sprintf(str, "Sorry, node #%d already has %d sections attached", node_no, (int)COUNT_OF(gProgram_state.AI_vehicles.path_nodes[node_no].sections));
4182
            sprintf(str, "Sorry, node #%d already has %d sections attached", node_no, (int)COUNT_OF(gProgram_state.AI_vehicles.path_nodes[node_no].sections));
4182
            NewTextHeadupSlot(4, 0, 2000, -1, str);
4183
            NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, str);
4183
        } else {
4184
        } else {
4184
            gAlready_elasticating = 0;
4185
            gAlready_elasticating = 0;
4185
            gProgram_state.AI_vehicles.number_of_path_nodes -= 1;
4186
            gProgram_state.AI_vehicles.number_of_path_nodes -= 1;
4186
            gProgram_state.AI_vehicles.path_sections[gMobile_section].node_indices[1] = node_no;
4187
            gProgram_state.AI_vehicles.path_sections[gMobile_section].node_indices[1] = node_no;
4187
            gProgram_state.AI_vehicles.path_nodes[node_no].sections[gProgram_state.AI_vehicles.path_nodes[node_no].number_of_sections] = gMobile_section;
4188
            gProgram_state.AI_vehicles.path_nodes[node_no].sections[gProgram_state.AI_vehicles.path_nodes[node_no].number_of_sections] = gMobile_section;
4188
            gProgram_state.AI_vehicles.path_nodes[node_no].number_of_sections += 1;
4189
            gProgram_state.AI_vehicles.path_nodes[node_no].number_of_sections += 1;
4189
            ShowOppoPaths();
4190
            ShowOppoPaths();
4190
            sprintf(str, "New section #%d, attached to existing node #%d",
4191
            sprintf(str, "New section #%d, attached to existing node #%d",
4191
                gMobile_section,
4192
                gMobile_section,
4192
                gProgram_state.AI_vehicles.path_sections[gMobile_section].node_indices[1]);
4193
                gProgram_state.AI_vehicles.path_sections[gMobile_section].node_indices[1]);
4193
            NewTextHeadupSlot(4, 0, 4000, -1, str);
4194
            NewTextHeadupSlot(eHeadupSlot_misc, 0, 4000, -1, str);
4194
        }
4195
        }
4195
    }
4196
    }
4196
}
4197
}
4197
 
4198
 
4198
// IDA: void __cdecl WidenOppoPathSection()
4199
// IDA: void __cdecl WidenOppoPathSection()
Line 4256... Line 4257...
4256
    br_scalar distance;
4257
    br_scalar distance;
4257
    LOG_TRACE("()");
4258
    LOG_TRACE("()");
4258
 
4259
 
4259
    if (gOppo_paths_shown) {
4260
    if (gOppo_paths_shown) {
4260
        if (gAlready_elasticating) {
4261
        if (gAlready_elasticating) {
4261
            NewTextHeadupSlot(4, 0, 2000, -1, "Not while you're elasticating");
4262
            NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "Not while you're elasticating");
4262
        } else {
4263
        } else {
4263
            node_no = FindNearestPathNode(&gSelf->t.t.translate.t, &distance);
4264
            node_no = FindNearestPathNode(&gSelf->t.t.translate.t, &distance);
4264
            if (distance > 10.f) {
4265
            if (distance > 10.f) {
4265
                NewTextHeadupSlot(4, 0, 2000, -1, "Can't find any paths close enough");
4266
                NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "Can't find any paths close enough");
4266
            } else {
4267
            } else {
4267
                BrVector3Copy(&gProgram_state.AI_vehicles.path_nodes[node_no].p, &gSelf->t.t.translate.t);
4268
                BrVector3Copy(&gProgram_state.AI_vehicles.path_nodes[node_no].p, &gSelf->t.t.translate.t);
4268
                ShowOppoPaths();
4269
                ShowOppoPaths();
4269
                NewTextHeadupSlot(4, 0, 2000, -1, "Bing!");
4270
                NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "Bing!");
4270
            }
4271
            }
4271
        }
4272
        }
4272
    }
4273
    }
4273
}
4274
}
4274
 
4275
 
Line 4278... Line 4279...
4278
    char str[256];
4279
    char str[256];
4279
    br_scalar distance;
4280
    br_scalar distance;
4280
    LOG_TRACE("()");
4281
    LOG_TRACE("()");
4281
 
4282
 
4282
    if (!gOppo_paths_shown) {
4283
    if (!gOppo_paths_shown) {
4283
        NewTextHeadupSlot(4, 0, 2000, -1, "Show paths first (F5)");
4284
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "Show paths first (F5)");
4284
    } else if (gAlready_elasticating) {
4285
    } else if (gAlready_elasticating) {
4285
        sprintf(str, "Next point will be #%d",
4286
        sprintf(str, "Next point will be #%d",
4286
            gProgram_state.AI_vehicles.path_sections[gMobile_section].node_indices[1]);
4287
            gProgram_state.AI_vehicles.path_sections[gMobile_section].node_indices[1]);
4287
        NewTextHeadupSlot(4, 0, 2000, -1, str);
4288
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, str);
4288
    } else {
4289
    } else {
4289
        node_no = FindNearestPathNode(&gSelf->t.t.translate.t, &distance);
4290
        node_no = FindNearestPathNode(&gSelf->t.t.translate.t, &distance);
4290
        if (distance > 10.f) {
4291
        if (distance > 10.f) {
4291
            NewTextHeadupSlot(4, 0, 2000, -1, "Can't find any nodes close enough");
4292
            NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "Can't find any nodes close enough");
4292
        } else {
4293
        } else {
4293
            sprintf(str, "Nearest node #%d has %d attached sections",
4294
            sprintf(str, "Nearest node #%d has %d attached sections",
4294
                node_no,
4295
                node_no,
4295
                gProgram_state.AI_vehicles.path_nodes[node_no].number_of_sections);
4296
                gProgram_state.AI_vehicles.path_nodes[node_no].number_of_sections);
4296
            NewTextHeadupSlot(4, 0, 2000, -1, str);
4297
            NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, str);
4297
        }
4298
        }
4298
    }
4299
    }
4299
}
4300
}
4300
 
4301
 
4301
// IDA: void __cdecl ShowSectionInfo1()
4302
// IDA: void __cdecl ShowSectionInfo1()
Line 4306... Line 4307...
4306
    br_vector3 direction_v;
4307
    br_vector3 direction_v;
4307
    br_vector3 intersect;
4308
    br_vector3 intersect;
4308
    LOG_TRACE("()");
4309
    LOG_TRACE("()");
4309
 
4310
 
4310
    if (!gOppo_paths_shown) {
4311
    if (!gOppo_paths_shown) {
4311
      NewTextHeadupSlot(4, 0, 2000, -1, "Show paths first (F5)");
4312
      NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "Show paths first (F5)");
4312
    } else if (gAlready_elasticating) {
4313
    } else if (gAlready_elasticating) {
4313
        sprintf(str, "This section will be #%d attached to nodes #%d and #%d",
4314
        sprintf(str, "This section will be #%d attached to nodes #%d and #%d",
4314
            gMobile_section,
4315
            gMobile_section,
4315
            gProgram_state.AI_vehicles.path_sections[gMobile_section].node_indices[0],
4316
            gProgram_state.AI_vehicles.path_sections[gMobile_section].node_indices[0],
4316
            gProgram_state.AI_vehicles.path_sections[gMobile_section].node_indices[1]);
4317
            gProgram_state.AI_vehicles.path_sections[gMobile_section].node_indices[1]);
4317
        NewTextHeadupSlot(4, 0, 2000, -1, str);
4318
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, str);
4318
    } else {
4319
    } else {
4319
        section_no = FindNearestPathSection(&gSelf->t.t.translate.t, &direction_v, &intersect, &distance);
4320
        section_no = FindNearestPathSection(&gSelf->t.t.translate.t, &direction_v, &intersect, &distance);
4320
        if (distance > 10.f) {
4321
        if (distance > 10.f) {
4321
            NewTextHeadupSlot(4, 0, 2000, -1, "Can't find any sections close enough");
4322
            NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "Can't find any sections close enough");
4322
        } else {
4323
        } else {
4323
            sprintf(str, "Nearest section #%d, start node #%d, finish node #%d",
4324
            sprintf(str, "Nearest section #%d, start node #%d, finish node #%d",
4324
                section_no,
4325
                section_no,
4325
                gProgram_state.AI_vehicles.path_sections[gMobile_section].node_indices[0],
4326
                gProgram_state.AI_vehicles.path_sections[gMobile_section].node_indices[0],
4326
                gProgram_state.AI_vehicles.path_sections[gMobile_section].node_indices[1]);
4327
                gProgram_state.AI_vehicles.path_sections[gMobile_section].node_indices[1]);
4327
            NewTextHeadupSlot(4, 0, 2000, -1, str);
4328
            NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, str);
4328
        }
4329
        }
4329
    }
4330
    }
4330
}
4331
}
4331
 
4332
 
4332
// IDA: void __cdecl ShowSectionInfo2()
4333
// IDA: void __cdecl ShowSectionInfo2()
Line 4337... Line 4338...
4337
    br_vector3 direction_v;
4338
    br_vector3 direction_v;
4338
    br_vector3 intersect;
4339
    br_vector3 intersect;
4339
    LOG_TRACE("()");
4340
    LOG_TRACE("()");
4340
 
4341
 
4341
    if (!gOppo_paths_shown) {
4342
    if (!gOppo_paths_shown) {
4342
        NewTextHeadupSlot(4, 0, 2000, -1, "Show paths first (F5)");
4343
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "Show paths first (F5)");
4343
    } else if (gAlready_elasticating) {
4344
    } else if (gAlready_elasticating) {
4344
        sprintf(str, "Towards start - min %d max %d, finish - min %d, max %d mph",
4345
        sprintf(str, "Towards start - min %d max %d, finish - min %d, max %d mph",
4345
            (int)(2.2f * gProgram_state.AI_vehicles.path_sections[gMobile_section].min_speed[0]),
4346
            (int)(2.2f * gProgram_state.AI_vehicles.path_sections[gMobile_section].min_speed[0]),
4346
            (int)(2.2f * gProgram_state.AI_vehicles.path_sections[gMobile_section].max_speed[0]),
4347
            (int)(2.2f * gProgram_state.AI_vehicles.path_sections[gMobile_section].max_speed[0]),
4347
            (int)(2.2f * gProgram_state.AI_vehicles.path_sections[gMobile_section].min_speed[1]),
4348
            (int)(2.2f * gProgram_state.AI_vehicles.path_sections[gMobile_section].min_speed[1]),
4348
            (int)(2.2f * gProgram_state.AI_vehicles.path_sections[gMobile_section].max_speed[1]));
4349
            (int)(2.2f * gProgram_state.AI_vehicles.path_sections[gMobile_section].max_speed[1]));
4349
        NewTextHeadupSlot(4, 0, 2000, -1, str);
4350
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, str);
4350
    } else {
4351
    } else {
4351
        section_no = FindNearestPathSection(&gSelf->t.t.translate.t, &direction_v, &intersect, &distance);
4352
        section_no = FindNearestPathSection(&gSelf->t.t.translate.t, &direction_v, &intersect, &distance);
4352
        if (distance > 10.f) {
4353
        if (distance > 10.f) {
4353
            NewTextHeadupSlot(4, 0, 2000, -1, "Can't find any sections close enough");
4354
            NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "Can't find any sections close enough");
4354
        } else {
4355
        } else {
4355
            sprintf(str, "Towards start - min %d max %d, finish - min %d, max %d mph",
4356
            sprintf(str, "Towards start - min %d max %d, finish - min %d, max %d mph",
4356
                (int)(2.2f * gProgram_state.AI_vehicles.path_sections[section_no].min_speed[0]),
4357
                (int)(2.2f * gProgram_state.AI_vehicles.path_sections[section_no].min_speed[0]),
4357
                (int)(2.2f * gProgram_state.AI_vehicles.path_sections[section_no].max_speed[0]),
4358
                (int)(2.2f * gProgram_state.AI_vehicles.path_sections[section_no].max_speed[0]),
4358
                (int)(2.2f * gProgram_state.AI_vehicles.path_sections[section_no].min_speed[1]),
4359
                (int)(2.2f * gProgram_state.AI_vehicles.path_sections[section_no].min_speed[1]),
4359
                (int)(2.2f * gProgram_state.AI_vehicles.path_sections[section_no].max_speed[1]));
4360
                (int)(2.2f * gProgram_state.AI_vehicles.path_sections[section_no].max_speed[1]));
4360
            NewTextHeadupSlot(4, 0, 2000, -1, str);
4361
            NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, str);
4361
        }
4362
        }
4362
    }
4363
    }
4363
}
4364
}
4364
 
4365
 
4365
// IDA: void __cdecl DeleteOppoPathSection()
4366
// IDA: void __cdecl DeleteOppoPathSection()
Line 4369... Line 4370...
4369
    br_vector3 direction_v;
4370
    br_vector3 direction_v;
4370
    tS16 section_no;
4371
    tS16 section_no;
4371
    LOG_TRACE("()");
4372
    LOG_TRACE("()");
4372
 
4373
 
4373
    if (gOppo_paths_shown == 0) {
4374
    if (gOppo_paths_shown == 0) {
4374
        NewTextHeadupSlot(4, 0, 2000, -1, "Show paths first (F5)");
4375
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "Show paths first (F5)");
4375
    } else if (gAlready_elasticating) {
4376
    } else if (gAlready_elasticating) {
4376
        NewTextHeadupSlot(4, 0, 2000, -1, "Not while you're creating a new section");
4377
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "Not while you're creating a new section");
4377
    } else {
4378
    } else {
4378
        section_no = FindNearestPathSection(&gSelf->t.t.translate.t, &direction_v, &intersect, &distance);
4379
        section_no = FindNearestPathSection(&gSelf->t.t.translate.t, &direction_v, &intersect, &distance);
4379
        if (distance > 10.f) {
4380
        if (distance > 10.f) {
4380
            NewTextHeadupSlot(4, 0, 2000, -1, "Can't find any sections close enough");
4381
            NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "Can't find any sections close enough");
4381
        } else {
4382
        } else {
4382
            DeleteSection(section_no);
4383
            DeleteSection(section_no);
4383
            DeleteOrphanNodes();
4384
            DeleteOrphanNodes();
4384
            ShowOppoPaths();
4385
            ShowOppoPaths();
4385
            NewTextHeadupSlot(4, 0, 2000, -1, "Pop!");
4386
            NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "Pop!");
4386
        }
4387
        }
4387
    }
4388
    }
4388
}
4389
}
4389
 
4390
 
4390
// IDA: void __cdecl DeleteOppoPathNodeAndSections()
4391
// IDA: void __cdecl DeleteOppoPathNodeAndSections()
Line 4392... Line 4393...
4392
    br_scalar distance;
4393
    br_scalar distance;
4393
    tS16 node_no;
4394
    tS16 node_no;
4394
    LOG_TRACE("()");
4395
    LOG_TRACE("()");
4395
 
4396
 
4396
    if (!gOppo_paths_shown) {
4397
    if (!gOppo_paths_shown) {
4397
        NewTextHeadupSlot(4, 0, 2000, -1, "Show paths first (F5)");
4398
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "Show paths first (F5)");
4398
    }
4399
    }
4399
    else if (gAlready_elasticating) {
4400
    else if (gAlready_elasticating) {
4400
        NewTextHeadupSlot(4, 0, 2000, -1, "Not while you're creating a new section");
4401
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "Not while you're creating a new section");
4401
    } else {
4402
    } else {
4402
        node_no = FindNearestPathNode(&gSelf->t.t.translate.t, &distance);
4403
        node_no = FindNearestPathNode(&gSelf->t.t.translate.t, &distance);
4403
        if (distance > 10.f) {
4404
        if (distance > 10.f) {
4404
            NewTextHeadupSlot(4, 0, 2000, -1, "Can't find any nodes close enough");
4405
            NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "Can't find any nodes close enough");
4405
        } else {
4406
        } else {
4406
            DeleteNode(node_no, 1);
4407
            DeleteNode(node_no, 1);
4407
            DeleteOrphanNodes();
4408
            DeleteOrphanNodes();
4408
            ShowOppoPaths();
4409
            ShowOppoPaths();
4409
            NewTextHeadupSlot(4, 0, 2000, -1, "Blam!");
4410
            NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "Blam!");
4410
        }
4411
        }
4411
    }
4412
    }
4412
}
4413
}
4413
 
4414
 
4414
// IDA: void __cdecl DeleteOppoPathNodeAndJoin()
4415
// IDA: void __cdecl DeleteOppoPathNodeAndJoin()
Line 4416... Line 4417...
4416
    br_scalar distance;
4417
    br_scalar distance;
4417
    tS16 node_no;
4418
    tS16 node_no;
4418
    LOG_TRACE("()");
4419
    LOG_TRACE("()");
4419
 
4420
 
4420
    if (!gOppo_paths_shown) {
4421
    if (!gOppo_paths_shown) {
4421
        NewTextHeadupSlot(4, 0, 2000, -1, "Show paths first (F5)");
4422
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "Show paths first (F5)");
4422
    } else if (gAlready_elasticating) {
4423
    } else if (gAlready_elasticating) {
4423
        NewTextHeadupSlot(4, 0, 2000, -1, "Not while you're creating a new section");
4424
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "Not while you're creating a new section");
4424
    } else {
4425
    } else {
4425
        node_no = FindNearestPathNode(&gSelf->t.t.translate.t, &distance);
4426
        node_no = FindNearestPathNode(&gSelf->t.t.translate.t, &distance);
4426
        if (distance > 10.f) {
4427
        if (distance > 10.f) {
4427
            NewTextHeadupSlot(4, 0, 2000, -1, "Can't find any nodes close enough");
4428
            NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "Can't find any nodes close enough");
4428
        } else if (gProgram_state.AI_vehicles.path_nodes[node_no].number_of_sections != 2) {
4429
        } else if (gProgram_state.AI_vehicles.path_nodes[node_no].number_of_sections != 2) {
4429
            NewTextHeadupSlot(4, 0, 2000, -1, "Node must have exactly 2 sections attached");
4430
            NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "Node must have exactly 2 sections attached");
4430
        } else if ((gProgram_state.AI_vehicles.path_sections[gProgram_state.AI_vehicles.path_nodes[node_no].sections[0]].node_indices[0] == node_no
4431
        } else if ((gProgram_state.AI_vehicles.path_sections[gProgram_state.AI_vehicles.path_nodes[node_no].sections[0]].node_indices[0] == node_no
4431
                    && gProgram_state.AI_vehicles.path_sections[gProgram_state.AI_vehicles.path_nodes[node_no].sections[1]].node_indices[1] == node_no) ||
4432
                    && gProgram_state.AI_vehicles.path_sections[gProgram_state.AI_vehicles.path_nodes[node_no].sections[1]].node_indices[1] == node_no) ||
4432
                (gProgram_state.AI_vehicles.path_sections[gProgram_state.AI_vehicles.path_nodes[node_no].sections[1]].node_indices[0] == node_no
4433
                (gProgram_state.AI_vehicles.path_sections[gProgram_state.AI_vehicles.path_nodes[node_no].sections[1]].node_indices[0] == node_no
4433
                    && gProgram_state.AI_vehicles.path_sections[gProgram_state.AI_vehicles.path_nodes[node_no].sections[0]].node_indices[1] == node_no)) {
4434
                    && gProgram_state.AI_vehicles.path_sections[gProgram_state.AI_vehicles.path_nodes[node_no].sections[0]].node_indices[1] == node_no)) {
4434
            ConsistencyCheck();
4435
            ConsistencyCheck();
4435
            DeleteNode(node_no,0);
4436
            DeleteNode(node_no,0);
4436
            ConsistencyCheck();
4437
            ConsistencyCheck();
4437
            DeleteOrphanNodes();
4438
            DeleteOrphanNodes();
4438
            ConsistencyCheck();
4439
            ConsistencyCheck();
4439
            ShowOppoPaths();
4440
            ShowOppoPaths();
4440
            NewTextHeadupSlot(4, 0, 2000, -1, "Blam!");
4441
            NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "Blam!");
4441
        }
4442
        }
4442
        else {
4443
        else {
4443
            NewTextHeadupSlot(4, 0, 2000, -1, "Sections must point in same direction");
4444
            NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "Sections must point in same direction");
4444
        }
4445
        }
4445
    }
4446
    }
4446
}
4447
}
4447
 
4448
 
4448
// IDA: void __cdecl ReverseSectionDirection()
4449
// IDA: void __cdecl ReverseSectionDirection()
Line 4454... Line 4455...
4454
    br_vector3 direction_v;
4455
    br_vector3 direction_v;
4455
    tS16 section_no;
4456
    tS16 section_no;
4456
    LOG_TRACE("()");
4457
    LOG_TRACE("()");
4457
 
4458
 
4458
    if (!gOppo_paths_shown) {
4459
    if (!gOppo_paths_shown) {
4459
        NewTextHeadupSlot(4, 0, 2000, -1, "Show paths first (F5)");
4460
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "Show paths first (F5)");
4460
    } else if (gAlready_elasticating) {
4461
    } else if (gAlready_elasticating) {
4461
        NewTextHeadupSlot(4, 0, 2000, -1, "Not while you're creating a new section");
4462
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "Not while you're creating a new section");
4462
    } else {
4463
    } else {
4463
        section_no = FindNearestPathSection(&gSelf->t.t.translate.t,  &direction_v, &intersect, &distance);
4464
        section_no = FindNearestPathSection(&gSelf->t.t.translate.t,  &direction_v, &intersect, &distance);
4464
        if (distance > 10.f) {
4465
        if (distance > 10.f) {
4465
            NewTextHeadupSlot(4, 0, 2000, -1, "Can't find any sections close enough");
4466
            NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "Can't find any sections close enough");
4466
        } else {
4467
        } else {
4467
            temp = gProgram_state.AI_vehicles.path_sections[section_no].node_indices[0];
4468
            temp = gProgram_state.AI_vehicles.path_sections[section_no].node_indices[0];
4468
            gProgram_state.AI_vehicles.path_sections[section_no].node_indices[0] =
4469
            gProgram_state.AI_vehicles.path_sections[section_no].node_indices[0] =
4469
                gProgram_state.AI_vehicles.path_sections[section_no].node_indices[1];
4470
                gProgram_state.AI_vehicles.path_sections[section_no].node_indices[1];
4470
            gProgram_state.AI_vehicles.path_sections[section_no].node_indices[1] = temp;
4471
            gProgram_state.AI_vehicles.path_sections[section_no].node_indices[1] = temp;
Line 4492... Line 4493...
4492
    tS16 section_no;
4493
    tS16 section_no;
4493
    char str[256];
4494
    char str[256];
4494
    LOG_TRACE("()");
4495
    LOG_TRACE("()");
4495
 
4496
 
4496
    if (!gOppo_paths_shown) {
4497
    if (!gOppo_paths_shown) {
4497
        NewTextHeadupSlot(4, 0, 2000, -1, "Show paths first (F5)");
4498
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "Show paths first (F5)");
4498
    } else if (gAlready_elasticating) {
4499
    } else if (gAlready_elasticating) {
4499
        NewTextHeadupSlot(4, 0, 2000, -1, "Not while you're creating a new section");
4500
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "Not while you're creating a new section");
4500
    } else {
4501
    } else {
4501
        section_no = FindNearestPathSection(&gSelf->t.t.translate.t, &direction_v, &intersect, &distance);
4502
        section_no = FindNearestPathSection(&gSelf->t.t.translate.t, &direction_v, &intersect, &distance);
4502
        if (distance > 10.f) {
4503
        if (distance > 10.f) {
4503
            NewTextHeadupSlot(4, 0, 2000, -1, "Can't find any sections close enough");
4504
            NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "Can't find any sections close enough");
4504
        } else {
4505
        } else {
4505
            gProgram_state.AI_vehicles.path_sections[section_no].type =
4506
            gProgram_state.AI_vehicles.path_sections[section_no].type =
4506
                (gProgram_state.AI_vehicles.path_sections[section_no].type + 1) % 3;
4507
                (gProgram_state.AI_vehicles.path_sections[section_no].type + 1) % 3;
4507
            sprintf(str, "%s section",  gPath_section_type_names[gProgram_state.AI_vehicles.path_sections[section_no].type]);
4508
            sprintf(str, "%s section",  gPath_section_type_names[gProgram_state.AI_vehicles.path_sections[section_no].type]);
4508
            ShowOppoPaths();
4509
            ShowOppoPaths();
4509
            NewTextHeadupSlot(4, 0, 2000, -1, str);
4510
            NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, str);
4510
        }
4511
        }
4511
    }
4512
    }
4512
}
4513
}
4513
 
4514
 
4514
// IDA: void __cdecl ToggleOneWayNess()
4515
// IDA: void __cdecl ToggleOneWayNess()
Line 4518... Line 4519...
4518
    br_vector3 direction_v;
4519
    br_vector3 direction_v;
4519
    tS16 section_no;
4520
    tS16 section_no;
4520
    LOG_TRACE("()");
4521
    LOG_TRACE("()");
4521
 
4522
 
4522
    if (!gOppo_paths_shown) {
4523
    if (!gOppo_paths_shown) {
4523
        NewTextHeadupSlot(4, 0, 2000, -1, "Show paths first (F5)");
4524
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "Show paths first (F5)");
4524
    } else if (gAlready_elasticating) {
4525
    } else if (gAlready_elasticating) {
4525
        NewTextHeadupSlot(4, 0, 2000, -1, "Not while you're creating a new section");
4526
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "Not while you're creating a new section");
4526
    } else {
4527
    } else {
4527
        section_no = FindNearestPathSection(&gSelf->t.t.translate.t, &direction_v, &intersect, &distance);
4528
        section_no = FindNearestPathSection(&gSelf->t.t.translate.t, &direction_v, &intersect, &distance);
4528
        if (distance > 10.f) {
4529
        if (distance > 10.f) {
4529
            NewTextHeadupSlot(4, 0, 2000, -1, "Can't find any sections close enough");
4530
            NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "Can't find any sections close enough");
4530
        } else {
4531
        } else {
4531
            if (gProgram_state.AI_vehicles.path_sections[section_no].one_way) {
4532
            if (gProgram_state.AI_vehicles.path_sections[section_no].one_way) {
4532
                gProgram_state.AI_vehicles.path_sections[section_no].one_way = 0;
4533
                gProgram_state.AI_vehicles.path_sections[section_no].one_way = 0;
4533
            }
4534
            }
4534
            else {
4535
            else {
4535
                gProgram_state.AI_vehicles.path_sections[section_no].one_way = 1;
4536
                gProgram_state.AI_vehicles.path_sections[section_no].one_way = 1;
4536
            }
4537
            }
4537
            ShowOppoPaths();
4538
            ShowOppoPaths();
4538
            if (gProgram_state.AI_vehicles.path_sections[section_no].one_way) {
4539
            if (gProgram_state.AI_vehicles.path_sections[section_no].one_way) {
4539
                NewTextHeadupSlot(4, 0, 2000, -1, "ONE-WAY");
4540
                NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "ONE-WAY");
4540
            } else {
4541
            } else {
4541
                NewTextHeadupSlot(4, 0, 2000, -1, "TWO-WAY");
4542
                NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "TWO-WAY");
4542
            }
4543
            }
4543
        }
4544
        }
4544
    }
4545
    }
4545
}
4546
}
4546
 
4547
 
Line 4555... Line 4556...
4555
    LOG_TRACE("()");
4556
    LOG_TRACE("()");
4556
 
4557
 
4557
    closest = -1;
4558
    closest = -1;
4558
    closest_distance = FLT_MAX;
4559
    closest_distance = FLT_MAX;
4559
    if (!gOppo_paths_shown) {
4560
    if (!gOppo_paths_shown) {
4560
      NewTextHeadupSlot(4, 0, 2000, -1, "Show paths first (F5)");
4561
      NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "Show paths first (F5)");
4561
    } else {
4562
    } else {
4562
        for (i = 0; i < gProgram_state.AI_vehicles.number_of_cops; i++) {
4563
        for (i = 0; i < gProgram_state.AI_vehicles.number_of_cops; i++) {
4563
            BrVector3Sub(&car_to_point, &gSelf->t.t.translate.t, &gProgram_state.AI_vehicles.cop_start_points[i]);
4564
            BrVector3Sub(&car_to_point, &gSelf->t.t.translate.t, &gProgram_state.AI_vehicles.cop_start_points[i]);
4564
            distance = BrVector3LengthSquared(&car_to_point);
4565
            distance = BrVector3LengthSquared(&car_to_point);
4565
            if (distance < closest_distance) {
4566
            if (distance < closest_distance) {
4566
                closest = i;
4567
                closest = i;
4567
                closest_distance = distance;
4568
                closest_distance = distance;
4568
            }
4569
            }
4569
        }
4570
        }
4570
        if (closest < 0 || closest_distance > 10.f) {
4571
        if (closest < 0 || closest_distance > 10.f) {
4571
            NewTextHeadupSlot(4, 0, 2000, -1, "No cop start points close enough");
4572
            NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "No cop start points close enough");
4572
        } else {
4573
        } else {
4573
            sprintf(str, "Nearest cop start point #%d", closest);
4574
            sprintf(str, "Nearest cop start point #%d", closest);
4574
            NewTextHeadupSlot(4, 0, 2000, -1, str);
4575
            NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, str);
4575
        }
4576
        }
4576
    }
4577
    }
4577
}
4578
}
4578
 
4579
 
4579
// IDA: void __cdecl DropCopStartPoint()
4580
// IDA: void __cdecl DropCopStartPoint()
4580
void DropCopStartPoint(void) {
4581
void DropCopStartPoint(void) {
4581
    char str[256];
4582
    char str[256];
4582
    LOG_TRACE("()");
4583
    LOG_TRACE("()");
4583
 
4584
 
4584
    if (!gOppo_paths_shown) {
4585
    if (!gOppo_paths_shown) {
4585
        NewTextHeadupSlot(4, 0, 2000, -1, "Show paths first (F5)");
4586
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "Show paths first (F5)");
4586
    } else if (gAlready_elasticating) {
4587
    } else if (gAlready_elasticating) {
4587
        NewTextHeadupSlot(4, 0, 2000, -1, "Not while you're creating a new section");
4588
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "Not while you're creating a new section");
4588
    } else {
4589
    } else {
4589
        if (gProgram_state.AI_vehicles.number_of_cops < COUNT_OF(gProgram_state.AI_vehicles.cop_start_points)) {
4590
        if (gProgram_state.AI_vehicles.number_of_cops < COUNT_OF(gProgram_state.AI_vehicles.cop_start_points)) {
4590
            BrVector3Copy(&gProgram_state.AI_vehicles.cop_start_points[gProgram_state.AI_vehicles.number_of_cops], &gSelf->t.t.translate.t);
4591
            BrVector3Copy(&gProgram_state.AI_vehicles.cop_start_points[gProgram_state.AI_vehicles.number_of_cops], &gSelf->t.t.translate.t);
4591
            gProgram_state.AI_vehicles.number_of_cops += 1;
4592
            gProgram_state.AI_vehicles.number_of_cops += 1;
4592
            ShowOppoPaths();
4593
            ShowOppoPaths();
4593
            sprintf(str, "New cop start point dropped (%d of %d)", gProgram_state.AI_vehicles.number_of_cops, (int)COUNT_OF(gProgram_state.AI_vehicles.cop_start_points));
4594
            sprintf(str, "New cop start point dropped (%d of %d)", gProgram_state.AI_vehicles.number_of_cops, (int)COUNT_OF(gProgram_state.AI_vehicles.cop_start_points));
4594
            NewTextHeadupSlot(4, 0, 2000, -1, str);
4595
            NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, str);
4595
        } else {
4596
        } else {
4596
            sprintf(str, "Sorry, no more than %d cop start points", (int)COUNT_OF(gProgram_state.AI_vehicles.cop_start_points));
4597
            sprintf(str, "Sorry, no more than %d cop start points", (int)COUNT_OF(gProgram_state.AI_vehicles.cop_start_points));
4597
            NewTextHeadupSlot(4, 0, 2000, -1, str);
4598
            NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, str);
4598
        }
4599
        }
4599
    }
4600
    }
4600
}
4601
}
4601
 
4602
 
4602
// IDA: void __cdecl DeleteCopStartPoint()
4603
// IDA: void __cdecl DeleteCopStartPoint()
Line 4610... Line 4611...
4610
    LOG_TRACE("()");
4611
    LOG_TRACE("()");
4611
 
4612
 
4612
    closest = -1;
4613
    closest = -1;
4613
    closest_distance = FLT_MAX;
4614
    closest_distance = FLT_MAX;
4614
    if (!gOppo_paths_shown) {
4615
    if (!gOppo_paths_shown) {
4615
        NewTextHeadupSlot(4, 0, 2000, -1, "Show paths first (F5)");
4616
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "Show paths first (F5)");
4616
    } else if (gAlready_elasticating) {
4617
    } else if (gAlready_elasticating) {
4617
        NewTextHeadupSlot(4, 0, 2000, -1, "Not while you're creating a new section");
4618
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "Not while you're creating a new section");
4618
    } else {
4619
    } else {
4619
        for (i = 0; i < gProgram_state.AI_vehicles.number_of_cops; i++) {
4620
        for (i = 0; i < gProgram_state.AI_vehicles.number_of_cops; i++) {
4620
            BrVector3Sub(&car_to_point, &gSelf->t.t.translate.t, &gProgram_state.AI_vehicles.cop_start_points[i]);
4621
            BrVector3Sub(&car_to_point, &gSelf->t.t.translate.t, &gProgram_state.AI_vehicles.cop_start_points[i]);
4621
            distance = BrVector3Length(&car_to_point);
4622
            distance = BrVector3Length(&car_to_point);
4622
            if (distance < closest_distance) {
4623
            if (distance < closest_distance) {
4623
                closest = i;
4624
                closest = i;
4624
                closest_distance = distance;
4625
                closest_distance = distance;
4625
            }
4626
            }
4626
        }
4627
        }
4627
        if (closest < 0 || closest_distance > 10.f) {
4628
        if (closest < 0 || closest_distance > 10.f) {
4628
            NewTextHeadupSlot(4, 0, 2000, -1, "No cop start points close enough");
4629
            NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, "No cop start points close enough");
4629
        } else {
4630
        } else {
4630
            for (i = closest; i < gProgram_state.AI_vehicles.number_of_cops - 1; i++) {
4631
            for (i = closest; i < gProgram_state.AI_vehicles.number_of_cops - 1; i++) {
4631
                BrVector3Copy(&gProgram_state.AI_vehicles.cop_start_points[i],
4632
                BrVector3Copy(&gProgram_state.AI_vehicles.cop_start_points[i],
4632
                    &gProgram_state.AI_vehicles.cop_start_points[i + 1]);
4633
                    &gProgram_state.AI_vehicles.cop_start_points[i + 1]);
4633
            }
4634
            }
4634
            gProgram_state.AI_vehicles.number_of_cops -= 1;
4635
            gProgram_state.AI_vehicles.number_of_cops -= 1;
4635
            ShowOppoPaths();
4636
            ShowOppoPaths();
4636
            sprintf(str, "Deleted cop start point #%d", closest);
4637
            sprintf(str, "Deleted cop start point #%d", closest);
4637
            NewTextHeadupSlot(4, 0, 2000, -1, str);
4638
            NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -1, str);
4638
        }
4639
        }
4639
    }
4640
    }
4640
}
4641
}
4641
 
4642
 
4642
// IDA: void __cdecl CycleCopStartPointType()
4643
// IDA: void __cdecl CycleCopStartPointType()