Skip to content

Commit 597a496

Browse files
committed
Implement DoDetaching
1 parent 07596e4 commit 597a496

4 files changed

Lines changed: 163 additions & 8 deletions

File tree

src/carma2/common/crush.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ C2_HOOK_VARIABLE_DECLARE_ARRAY(tCrush_net_reattach_bit_list_item, gNet_crush_rea
3333
C2_HOOK_VARIABLE_DECLARE_ARRAY(tCrush_detach_list_item, gCrush_detach_list, 16);
3434
C2_HOOK_VARIABLE_DECLARE_ARRAY(tCar_damge_crush_list_item, gCar_damage_crush_list, 8);
3535
C2_HOOK_VARIABLE_DECLARE(br_vector3, gBatty_gravity);
36+
C2_HOOK_VARIABLE_DECLARE(int, gCount_crush_detach_list);
37+
C2_HOOK_VARIABLE_DECLARE(int, gCount_net_crush_detach_list);
38+
C2_HOOK_VARIABLE_DECLARE(int, gCount_net_crush_semi_detach_bit_list);
3639

3740
void C2_HOOK_FASTCALL InitCrushSystems(void);
3841

src/carma2/common/flap.c

Lines changed: 124 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
#include "flap.h"
22

33
#include "car.h"
4+
#include "compress.h"
45
#include "crush.h"
6+
#include "globvars.h"
7+
#include "globvrpb.h"
8+
#include "network.h"
59
#include "physics.h"
610
#include "piping.h"
711

@@ -50,13 +54,131 @@ void C2_HOOK_FASTCALL SendSemiDetachBit(tCar_spec* pCar, br_actor* pActor, float
5054
}
5155
C2_HOOK_FUNCTION_ORIGINAL(0x0042dab0, SendSemiDetachBit, SendSemiDetachBit_original)
5256

57+
int C2_HOOK_FASTCALL BitIsInBentPartOfCar(br_actor* pActor, float pArg2, float pArg3) {
58+
tCar_spec* car;
59+
float delta;
60+
61+
C2_HOOK_STATIC_ASSERT_STRUCT_OFFSET(tCar_spec, old_frame_mat, 0x1c);
62+
63+
if (pActor->user == NULL) {
64+
return 1;
65+
}
66+
/* FIXME: what type is stored in pActor->user? */
67+
car = *(tCar_spec**)pActor->user;
68+
if (car == NULL) {
69+
return 1;
70+
}
71+
delta = .4f * (pArg2 - pArg3);
72+
if (delta < 0.f) {
73+
return pArg3 + delta > car->old_frame_mat.m[2][2];
74+
} else {
75+
return pArg3 + delta < car->old_frame_mat.m[3][2];
76+
}
77+
}
78+
79+
void C2_HOOK_FASTCALL SendDetachBit(tCar_spec* pCar, br_actor* pActor) {
80+
tNet_message* message;
81+
br_vector3 p1;
82+
br_vector3 p2;
83+
br_vector3 p3;
84+
br_bounds3 bnds;
85+
86+
C2_HOOK_STATIC_ASSERT_STRUCT_OFFSET(tNet_message, guaranteed.contents.detach_bit.ID, 0x1c);
87+
C2_HOOK_STATIC_ASSERT_STRUCT_OFFSET(tNet_message, guaranteed.contents.detach_bit.field_0x4, 0x20);
88+
C2_HOOK_STATIC_ASSERT_STRUCT_OFFSET(tNet_message, guaranteed.contents.detach_bit.field_0x8, 0x24);
89+
C2_HOOK_STATIC_ASSERT_STRUCT_OFFSET(tNet_message, guaranteed.contents.detach_bit.bounds_min, 0x28);
90+
C2_HOOK_STATIC_ASSERT_STRUCT_OFFSET(tNet_message, guaranteed.contents.detach_bit.bounds_max, 0x2e);
91+
92+
#if !defined(C2_HOOKS_ENABLED)
93+
NOT_IMPLEMENTED(); /* FIXME: what type is pActor->user? */
94+
#endif
95+
96+
message = NetBuildGuaranteedMessage(51, 0);
97+
message->guaranteed.contents.detach_bit.ID = NetPlayerFromCar(pCar)->ID;
98+
message->guaranteed.contents.detach_bit.field_0x4 = ((undefined**)pActor->user)[0x8][0x20];
99+
message->guaranteed.contents.detach_bit.field_0x8 = C2V(gPHIL_last_physics_tick) + 120;
100+
if (!GetSDBJointPosAndBounds(&p1, &p2, &p3, &bnds, pActor)) {
101+
CompressVector3(&message->guaranteed.contents.detach_bit.bounds_min, &bnds.min, -10.f, 10.f);
102+
CompressVector3(&message->guaranteed.contents.detach_bit.bounds_max, &bnds.max, -10.f, 10.f);
103+
NetGuaranteedSendMessageToEverybody(C2V(gCurrent_net_game), message, 0);
104+
}
105+
}
106+
53107
void (C2_HOOK_FASTCALL * DoDetaching_original)(void);
54108
void C2_HOOK_FASTCALL DoDetaching(void) {
55109

56-
#if defined(C2_HOOKS_ENABLED)
110+
#if 0//defined(C2_HOOKS_ENABLED)
57111
DoDetaching_original();
58112
#else
59-
NOT_IMPLEMENTED();
113+
114+
C2_HOOK_STATIC_ASSERT_STRUCT_OFFSET(tCar_crush_spec, field_0x174, 0x174);
115+
C2_HOOK_STATIC_ASSERT_STRUCT_OFFSET(tCar_crush_spec, field_0x180, 0x180);
116+
117+
if (C2V(gNet_mode) == eNet_mode_none || C2V(gNet_mode) == eNet_mode_host) {
118+
int new_count_crush_detach_list;
119+
int i;
120+
121+
new_count_crush_detach_list = 0;
122+
for (i = 0; i < C2V(gCount_crush_detach_list); i++) {
123+
tCrush_detach_list_item* detach_list_item;
124+
int keep;
125+
int synced;
126+
127+
detach_list_item = &C2V(gCrush_detach_list)[i];
128+
keep = 1;
129+
synced = 0;
130+
if (C2V(gPHIL_last_physics_tick) >= detach_list_item->time) {
131+
keep = 0;
132+
133+
if (!((detach_list_item->car->car_crush_spec->field_0x144
134+
&& BitIsInBentPartOfCar(detach_list_item->actor,
135+
detach_list_item->car->car_crush_spec->field_0x174,
136+
detach_list_item->car->car_crush_spec->field_0x180))
137+
|| detach_list_item->car->car_crush_spec->field_0x4b8)) {
138+
139+
if (C2V(gNet_mode) == eNet_mode_none) {
140+
if (detach_list_item->field_0x10) {
141+
142+
DetachBit(detach_list_item->car, detach_list_item->actor, NULL);
143+
} else {
144+
SemiDetachBit(detach_list_item->car, detach_list_item->actor, detach_list_item->field_0x8, &keep, NULL, NULL, NULL, NULL);
145+
}
146+
} else {
147+
if (detach_list_item->field_0x10) {
148+
int j;
149+
150+
for (j = 0; j < C2V(gCount_net_crush_detach_list); j++) {
151+
if (C2V(gNet_crush_detach_list)[j].actor == detach_list_item->actor) {
152+
synced = 1;
153+
break;
154+
}
155+
}
156+
if (!synced) {
157+
SendDetachBit(detach_list_item->car, detach_list_item->actor);
158+
}
159+
} else {
160+
int j;
161+
162+
for (j = 0; j < C2V(gCount_net_crush_semi_detach_bit_list); j++) {
163+
if (C2V(gNet_crush_semi_detach_bit_list)[j].actor == detach_list_item->actor) {
164+
synced = 1;
165+
break;
166+
}
167+
}
168+
if (!synced) {
169+
SendSemiDetachBit(detach_list_item->car, detach_list_item->actor, detach_list_item->field_0x8, NULL);
170+
}
171+
}
172+
}
173+
}
174+
}
175+
if (keep && i != new_count_crush_detach_list) {
176+
C2V(gCrush_detach_list)[new_count_crush_detach_list] = C2V(gCrush_detach_list)[i];
177+
new_count_crush_detach_list += 1;
178+
}
179+
}
180+
C2V(gCount_crush_detach_list) = new_count_crush_detach_list;
181+
}
60182
#endif
61183
}
62184
C2_HOOK_FUNCTION_ORIGINAL(0x00436ad0, DoDetaching, DoDetaching_original)

src/carma2/common/flap.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ int C2_HOOK_FASTCALL GetSDBJointPosAndBounds(br_vector3* pP1, br_vector3* pP2, b
1313

1414
void C2_HOOK_FASTCALL SendSemiDetachBit(tCar_spec* pCar, br_actor* pActor, float pArg3, undefined4* pArg4);
1515

16+
int C2_HOOK_FASTCALL BitIsInBentPartOfCar(br_actor* pActor, float pArg2, float pArg3);
17+
1618
void C2_HOOK_FASTCALL DoDetaching(void);
1719

1820
void C2_HOOK_FASTCALL SetBitForDetachment(br_actor* pActor, tCar_spec* pCar, float pArg3, int pArg4);

src/carma2/include/rec2_types.h

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3629,7 +3629,11 @@ typedef struct tCar_crush_spec {
36293629
float bendability_factor;
36303630
float bend_z_min;
36313631
float bend_z_max;
3632-
undefined field_0x154[120];
3632+
undefined field_0x154[0x174 - 0x154];
3633+
float field_0x174;
3634+
undefined field_0x178[0x180 - 0x178];
3635+
float field_0x180;
3636+
undefined field_0x184[0x1cc - 0x184];
36333637
tCar_crush_vertex_data* field_0x1cc;
36343638
undefined field_0x1d0[28];
36353639
br_vector3 field_0x1ec[6];
@@ -3655,13 +3659,13 @@ typedef struct tCar_crush_spec {
36553659
} tCar_crush_spec;
36563660

36573661
typedef struct tCrush_net_detach_list_item {
3658-
undefined4 field_0x0;
3662+
br_actor* actor;
36593663
tCar_spec* car;
36603664
undefined field_0x8[28];
36613665
} tCrush_net_detach_list_item;
36623666

36633667
typedef struct tCrush_net_semi_detach_bit_list_item {
3664-
undefined4 field_0x0;
3668+
br_actor* actor;
36653669
tCar_spec* car;
36663670
undefined field_0x8[68];
36673671
} tCrush_net_semi_detach_bit_list_item;
@@ -3677,9 +3681,11 @@ typedef struct tCrush_net_reattach_bit_list_item {
36773681
} tCrush_net_reattach_bit_list_item;
36783682

36793683
typedef struct tCrush_detach_list_item {
3680-
undefined4 field_0x0;
3684+
br_actor* actor;
36813685
tCar_spec* car;
3682-
undefined field_0x8[12];
3686+
float field_0x8;
3687+
tU32 time;
3688+
undefined4 field_0x10;
36833689
} tCrush_detach_list_item;
36843690

36853691
typedef struct tCar_damge_crush_list_item {
@@ -4765,6 +4771,19 @@ typedef struct {
47654771
tCompressed_car_crush car_crush;
47664772
} tNet_message_car_crush;
47674773

4774+
typedef struct {
4775+
int ID;
4776+
tU8 field_0x4;
4777+
undefined field_0x5[0x8 - 0x5];
4778+
tU32 field_0x8;
4779+
tCompressed_vector3 bounds_min;
4780+
tCompressed_vector3 bounds_max;
4781+
} tNet_message_chunk_detach_bit;
4782+
4783+
typedef struct {
4784+
tNet_message_chunk_header header;
4785+
} tNet_message_guaranteed;
4786+
47684787
typedef struct {
47694788
tNet_message_chunk_header header;
47704789
tU8 data[];
@@ -4850,6 +4869,7 @@ typedef union {
48504869
tNet_message_chunk_oil_spill oil_spill; /* type = 0x1f*/
48514870
tNet_message_car_crush car_crush; /* type = 0x20 */
48524871
tNet_message_chunk_toggle_doors toggle_doors; /* type = 0x2c */
4872+
tNet_message_chunk_detach_bit detach_bit; /* type = 0x33 */
48534873
} tNet_message_chunk;
48544874

48554875
typedef struct {
@@ -4862,9 +4882,17 @@ typedef struct {
48624882
undefined2 field_0x16;
48634883
} tNet_message_header;
48644884

4885+
typedef struct {
4886+
tNet_message_guaranteed header;
4887+
tNet_message_chunk contents;
4888+
} tNet_guaranteed_body;
4889+
48654890
typedef struct tNet_message {
48664891
tNet_message_header header;
4867-
tNet_message_chunk contents;
4892+
union {
4893+
tNet_message_chunk contents;
4894+
tNet_guaranteed_body guaranteed;
4895+
};
48684896
} tNet_message;
48694897

48704898
typedef struct tNet_message_memory {

0 commit comments

Comments
 (0)