Rev 18 | Details | Compare with Previous | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 1 | pmbaty | 1 | #include "oil.h" |
| 20 | pmbaty | 2 | #include "brender/brender.h" |
| 1 | pmbaty | 3 | #include "finteray.h" |
| 4 | #include "globvars.h" |
||
| 5 | #include "globvrpb.h" |
||
| 6 | #include "harness/trace.h" |
||
| 7 | #include "loading.h" |
||
| 8 | #include "network.h" |
||
| 9 | #include "piping.h" |
||
| 10 | #include "utility.h" |
||
| 11 | #include <math.h> |
||
| 12 | #include <stdlib.h> |
||
| 13 | |||
| 14 | char* gOil_pixie_names[1] = { "OIL.PIX" }; |
||
| 15 | int gNext_oil_pixie = 0; |
||
| 16 | br_scalar gZ_buffer_diff; |
||
| 17 | br_scalar gMin_z_diff; |
||
| 18 | br_pixelmap* gOil_pixies[1]; |
||
| 19 | tOil_spill_info gOily_spills[15]; |
||
| 20 | |||
| 21 | // IDA: void __cdecl InitOilSpills() |
||
| 22 | void InitOilSpills(void) { |
||
| 23 | int i; |
||
| 24 | br_model* the_model; |
||
| 25 | br_material* the_material; |
||
| 26 | LOG_TRACE("()"); |
||
| 27 | |||
| 28 | for (i = 0; i < COUNT_OF(gOil_pixie_names); i++) { |
||
| 29 | gOil_pixies[i] = LoadPixelmap(gOil_pixie_names[i]); |
||
| 30 | BrMapAdd(gOil_pixies[i]); |
||
| 31 | } |
||
| 32 | |||
| 33 | for (i = 0; i < COUNT_OF(gOily_spills); i++) { |
||
| 34 | the_material = BrMaterialAllocate(NULL); |
||
| 35 | BrMaterialAdd(the_material); |
||
| 36 | the_material->ka = 0.99f; |
||
| 37 | the_material->kd = 0.0f; |
||
| 38 | the_material->ks = 0.0f; |
||
| 39 | the_material->power = 0.0f; |
||
| 40 | the_material->index_base = 0; |
||
| 41 | the_material->flags |= BR_MATF_LIGHT; |
||
| 42 | the_material->flags |= BR_MATF_PERSPECTIVE; |
||
| 43 | the_material->flags |= BR_MATF_SMOOTH; |
||
| 20 | pmbaty | 44 | // TODO: added by dethrace, investigate why oil spills in OG do not need this flag set to render correctly |
| 45 | the_material->flags |= BR_MATF_TWO_SIDED; |
||
| 1 | pmbaty | 46 | the_material->index_range = 0; |
| 47 | the_material->colour_map = NULL; |
||
| 48 | BrMatrix23Identity(&the_material->map_transform); |
||
| 49 | the_material->index_shade = BrTableFind("IDENTITY.TAB"); |
||
| 50 | BrMaterialUpdate(the_material, BR_MATU_ALL); |
||
| 51 | the_model = BrModelAllocate(NULL, 4, 2); |
||
| 52 | the_model->flags |= BR_MODF_KEEP_ORIGINAL; |
||
| 53 | |||
| 54 | the_model->faces[0].vertices[0] = 2; |
||
| 55 | the_model->faces[0].vertices[1] = 1; |
||
| 56 | the_model->faces[0].vertices[2] = 0; |
||
| 57 | the_model->faces[0].material = NULL; |
||
| 58 | the_model->faces[0].smoothing = 1; |
||
| 59 | the_model->faces[1].vertices[0] = 3; |
||
| 60 | the_model->faces[1].vertices[1] = 2; |
||
| 61 | the_model->faces[1].vertices[2] = 0; |
||
| 62 | the_model->faces[1].material = NULL; |
||
| 63 | the_model->faces[1].smoothing = 1; |
||
| 64 | BrVector3Set(&the_model->vertices[0].p, -1.f, 0.f, -1.f); |
||
| 65 | BrVector2Set(&the_model->vertices[0].map, 0.f, 1.f); |
||
| 66 | BrVector3Set(&the_model->vertices[1].p, 1.f, 0.f, 1.f); |
||
| 67 | BrVector2Set(&the_model->vertices[1].map, 0.f, 0.f); |
||
| 68 | BrVector3Set(&the_model->vertices[2].p, 1.f, 0.f, -1.f); |
||
| 69 | BrVector2Set(&the_model->vertices[2].map, 1.f, 0.f); |
||
| 70 | BrVector3Set(&the_model->vertices[3].p, -1.f, 0.f, 1.f); |
||
| 71 | BrVector2Set(&the_model->vertices[3].map, 1.f, 1.f); |
||
| 72 | gOily_spills[i].actor = BrActorAllocate(BR_ACTOR_MODEL, NULL); |
||
| 73 | gOily_spills[i].actor->model = the_model; |
||
| 74 | gOily_spills[i].actor->render_style = BR_RSTYLE_NONE; |
||
| 75 | gOily_spills[i].actor->material = the_material; |
||
| 76 | BrActorAdd(gNon_track_actor, gOily_spills[i].actor); |
||
| 77 | } |
||
| 78 | } |
||
| 79 | |||
| 80 | // IDA: void __cdecl ResetOilSpills() |
||
| 81 | void ResetOilSpills(void) { |
||
| 82 | int i; |
||
| 83 | LOG_TRACE("()"); |
||
| 84 | |||
| 85 | for (i = 0; i < COUNT_OF(gOily_spills); i++) { |
||
| 86 | gOily_spills[i].actor->render_style = BR_RSTYLE_NONE; |
||
| 87 | gOily_spills[i].car = NULL; |
||
| 88 | gOily_spills[i].stop_time = 0; |
||
| 89 | } |
||
| 90 | } |
||
| 91 | |||
| 92 | // IDA: void __usercall QueueOilSpill(tCar_spec *pCar@<EAX>) |
||
| 93 | void QueueOilSpill(tCar_spec* pCar) { |
||
| 94 | int i; |
||
| 95 | int oily_index; |
||
| 96 | int oldest_one; |
||
| 97 | tU32 the_time; |
||
| 98 | tU32 oldest_time; |
||
| 99 | LOG_TRACE("(%p)", pCar); |
||
| 100 | |||
| 101 | oldest_one = 0; |
||
| 102 | oily_index = -1; |
||
| 103 | the_time = GetTotalTime(); |
||
| 104 | oldest_time = GetTotalTime(); |
||
| 105 | |||
| 106 | for (i = 0; i < COUNT_OF(gOily_spills); i++) { |
||
| 107 | if (gOily_spills[i].car == pCar && the_time < gOily_spills[i].spill_time + 5000) { |
||
| 108 | return; |
||
| 109 | } |
||
| 110 | } |
||
| 111 | |||
| 112 | for (i = 0; i < COUNT_OF(gOily_spills); i++) { |
||
| 113 | if (gOily_spills[i].car == NULL) { |
||
| 114 | oily_index = i; |
||
| 115 | break; |
||
| 116 | } |
||
| 117 | if (gOily_spills[i].spill_time < oldest_time) { |
||
| 118 | oldest_time = gOily_spills[i].spill_time; |
||
| 119 | oldest_one = i; |
||
| 120 | } |
||
| 121 | } |
||
| 122 | |||
| 123 | if (oily_index < 0) { |
||
| 124 | oily_index = oldest_one; |
||
| 125 | } |
||
| 126 | gOily_spills[oily_index].car = pCar; |
||
| 127 | gOily_spills[oily_index].spill_time = the_time + 500; |
||
| 128 | gOily_spills[oily_index].full_size = SRandomBetween(.35f, .6f); |
||
| 129 | gOily_spills[oily_index].grow_rate = SRandomBetween(3e-5f, 10e-5f); |
||
| 130 | gOily_spills[oily_index].current_size = .1f; |
||
| 131 | gOily_spills[oily_index].actor->render_style = BR_RSTYLE_NONE; |
||
| 132 | } |
||
| 133 | |||
| 134 | // IDA: int __usercall OKToSpillOil@<EAX>(tOil_spill_info *pOil@<EAX>) |
||
| 135 | int OKToSpillOil(tOil_spill_info* pOil) { |
||
| 136 | //br_scalar temp; // Pierre-Marie Baty -- unused variable |
||
| 137 | //br_scalar size_with_margin; // Pierre-Marie Baty -- unused variable |
||
| 138 | br_scalar distance; |
||
| 139 | br_scalar mr_dotty; |
||
| 140 | br_vector3 v; |
||
| 141 | br_vector3 ray_pos; |
||
| 142 | br_vector3 ray_dir; |
||
| 143 | br_vector3 normal; |
||
| 144 | tCar_spec* car; |
||
| 145 | int i; |
||
| 146 | int face_count; |
||
| 147 | int found_one; |
||
| 148 | br_angle angle_to_rotate_by; |
||
| 149 | tBounds kev_bounds; |
||
| 150 | tFace_ref the_list[10]; |
||
| 151 | tFace_ref* face_ref; |
||
| 152 | LOG_TRACE("(%p)", pOil); |
||
| 153 | |||
| 154 | car = pOil->car; |
||
| 155 | if (car->driver >= eDriver_net_human && car->damage_units[eDamage_engine].damage_level <= 98 && car->damage_units[eDamage_transmission].damage_level <= 98) { |
||
| 156 | return 0; |
||
| 157 | } |
||
| 158 | angle_to_rotate_by = IRandomBetween(0, 0xffff); |
||
| 159 | kev_bounds.original_bounds.min.v[0] = -pOil->full_size; |
||
| 160 | kev_bounds.original_bounds.min.v[1] = 1.5f * car->car_model_actors[car->principal_car_actor].actor->model->bounds.min.v[1]; |
||
| 161 | kev_bounds.original_bounds.min.v[2] = -pOil->full_size; |
||
| 162 | kev_bounds.original_bounds.max.v[0] = pOil->full_size; |
||
| 163 | kev_bounds.original_bounds.max.v[1] = car->car_model_actors[car->principal_car_actor].actor->model->bounds.max.v[1]; |
||
| 164 | kev_bounds.original_bounds.max.v[2] = pOil->full_size; |
||
| 165 | BrMatrix34PreRotateY(&pOil->actor->t.t.mat, angle_to_rotate_by); |
||
| 166 | kev_bounds.mat = &car->car_master_actor->t.t.mat; |
||
| 167 | face_count = FindFacesInBox(&kev_bounds, the_list, COUNT_OF(the_list)); |
||
| 168 | BrVector3Set(&v, .0f, .2f, .0f); |
||
| 169 | BrMatrix34ApplyP(&ray_pos, &v, &car->car_master_actor->t.t.mat); |
||
| 20 | pmbaty | 170 | BrVector3Set(&ray_dir, 0.f, kev_bounds.original_bounds.min.v[1] - kev_bounds.original_bounds.max.v[1], 0.f);\ |
| 1 | pmbaty | 171 | if (face_count == 0) { |
| 172 | return 0; |
||
| 173 | } |
||
| 174 | found_one = 0; |
||
| 175 | for (i = 0; i < face_count; i++) { |
||
| 176 | face_ref = &the_list[i]; |
||
| 177 | if (!found_one) { |
||
| 178 | CheckSingleFace(face_ref, &ray_pos, &ray_dir, &normal, &distance); |
||
| 179 | if (distance < 100.f) { |
||
| 180 | found_one = 1; |
||
| 181 | BrVector3Copy((br_vector3*)pOil->actor->t.t.mat.m[1], &normal); |
||
| 182 | BrVector3Set(&v, 0.f, 0.f, 1.f); |
||
| 183 | BrVector3Cross((br_vector3*)pOil->actor->t.t.mat.m[0], &normal, &v); |
||
| 184 | BrVector3Set(&v, 1.f, 0.f, 0.f); |
||
| 185 | BrVector3Cross((br_vector3*)pOil->actor->t.t.mat.m[2], &normal, &v); |
||
| 186 | BrVector3Scale(&v, &ray_dir, distance); |
||
| 187 | BrVector3Add(&pOil->pos, &ray_pos, &v); |
||
| 188 | BrMatrix34PreRotateY(&pOil->actor->t.t.mat, angle_to_rotate_by); |
||
| 189 | } |
||
| 190 | } |
||
| 191 | } |
||
| 192 | if (!found_one || normal.v[1] < .97f) { |
||
| 193 | return 0; |
||
| 194 | } |
||
| 195 | for (i = 0; i < face_count; i++) { |
||
| 196 | face_ref = &the_list[i]; |
||
| 197 | mr_dotty = BrVector3Dot(&face_ref->normal, &normal); |
||
| 198 | if (mr_dotty < .98f && (mr_dotty > .8f || !NormalSideOfPlane(&pOil->actor->t.t.translate.t, &face_ref->normal, face_ref->d))) { |
||
| 199 | return 0; |
||
| 200 | } |
||
| 201 | } |
||
| 202 | return 1; |
||
| 203 | } |
||
| 204 | |||
| 205 | // IDA: void __usercall Vector3Interpolate(br_vector3 *pDst@<EAX>, br_vector3 *pFrom@<EDX>, br_vector3 *pTo@<EBX>, br_scalar pP) |
||
| 206 | void Vector3Interpolate(br_vector3* pDst, br_vector3* pFrom, br_vector3* pTo, br_scalar pP) { |
||
| 207 | LOG_TRACE("(%p, %p, %p, %f)", pDst, pFrom, pTo, pP); |
||
| 208 | |||
| 209 | pDst->v[0] = (pTo->v[0] - pFrom->v[0]) * pP + pFrom->v[0]; |
||
| 210 | pDst->v[1] = (pTo->v[1] - pFrom->v[1]) * pP + pFrom->v[1]; |
||
| 211 | pDst->v[2] = (pTo->v[2] - pFrom->v[2]) * pP + pFrom->v[2]; |
||
| 212 | } |
||
| 213 | |||
| 214 | // IDA: void __usercall EnsureGroundDetailVisible(br_vector3 *pNew_pos@<EAX>, br_vector3 *pGround_normal@<EDX>, br_vector3 *pOld_pos@<EBX>) |
||
| 215 | void EnsureGroundDetailVisible(br_vector3* pNew_pos, br_vector3* pGround_normal, br_vector3* pOld_pos) { |
||
| 216 | br_scalar factor; |
||
| 217 | br_scalar s; |
||
| 218 | br_scalar dist; |
||
| 219 | br_vector3 to_camera; |
||
| 220 | LOG_TRACE("(%p, %p, %p)", pNew_pos, pGround_normal, pOld_pos); |
||
| 221 | |||
| 222 | to_camera.v[0] = gCamera_to_world.m[3][0] - pOld_pos->v[0]; |
||
| 223 | to_camera.v[1] = gCamera_to_world.m[3][1] - pOld_pos->v[1]; |
||
| 224 | to_camera.v[2] = gCamera_to_world.m[3][2] - pOld_pos->v[2]; |
||
| 225 | dist = BrVector3Length(&to_camera); |
||
| 226 | if (dist > BR_SCALAR_EPSILON) { |
||
| 227 | factor = BrVector3Dot(pGround_normal, &to_camera) / dist; |
||
| 228 | if (fabsf(factor) <= 0.01f) { |
||
| 229 | s = 0.01f; |
||
| 230 | } else { |
||
| 231 | s = 0.01f / factor; |
||
| 232 | if (s > 0.1f) { |
||
| 233 | s = 0.1f; |
||
| 234 | } |
||
| 235 | } |
||
| 236 | Vector3Interpolate(pNew_pos, pOld_pos, (br_vector3*)gCamera_to_world.m[3], s); |
||
| 237 | } |
||
| 238 | } |
||
| 239 | |||
| 240 | // IDA: void __usercall MungeOilsHeightAboveGround(tOil_spill_info *pOil@<EAX>) |
||
| 241 | void MungeOilsHeightAboveGround(tOil_spill_info* pOil) { |
||
| 242 | LOG_TRACE("(%p)", pOil); |
||
| 243 | |||
| 244 | EnsureGroundDetailVisible(&pOil->actor->t.t.look_up.t, &pOil->actor->t.t.look_up.up, &pOil->pos); |
||
| 245 | } |
||
| 246 | |||
| 247 | // IDA: void __usercall MungeIndexedOilsHeightAboveGround(int pIndex@<EAX>) |
||
| 248 | void MungeIndexedOilsHeightAboveGround(int pIndex) { |
||
| 249 | LOG_TRACE("(%d)", pIndex); |
||
| 250 | |||
| 251 | MungeOilsHeightAboveGround(&gOily_spills[pIndex]); |
||
| 252 | } |
||
| 253 | |||
| 254 | // IDA: void __usercall SetInitialOilStuff(tOil_spill_info *pOil@<EAX>, br_model *pModel@<EDX>) |
||
| 255 | void SetInitialOilStuff(tOil_spill_info* pOil, br_model* pModel) { |
||
| 256 | LOG_TRACE("(%p, %p)", pOil, pModel); |
||
| 257 | |||
| 258 | pModel->vertices[0].p.v[0] = -0.1f; |
||
| 259 | pModel->vertices[0].p.v[2] = -0.1f; |
||
| 20 | pmbaty | 260 | pModel->vertices[1].p.v[0] = 0.1f; |
| 1 | pmbaty | 261 | pModel->vertices[1].p.v[2] = -0.1f; |
| 20 | pmbaty | 262 | pModel->vertices[2].p.v[0] = 0.1f; |
| 263 | pModel->vertices[2].p.v[2] = 0.1f; |
||
| 1 | pmbaty | 264 | pModel->vertices[3].p.v[0] = -0.1f; |
| 20 | pmbaty | 265 | pModel->vertices[3].p.v[2] = 0.1f; |
| 1 | pmbaty | 266 | pOil->actor->render_style = BR_RSTYLE_FACES; |
| 267 | BrMaterialUpdate(pOil->actor->material, BR_MATU_ALL); |
||
| 268 | BrModelUpdate(pModel, BR_MODU_ALL); |
||
| 269 | } |
||
| 270 | |||
| 271 | // IDA: void __usercall ProcessOilSpills(tU32 pFrame_period@<EAX>) |
||
| 272 | void ProcessOilSpills(tU32 pFrame_period) { |
||
| 273 | int i; |
||
| 274 | tU32 time; |
||
| 275 | br_model* the_model; |
||
| 276 | br_scalar grow_amount; |
||
| 277 | //br_scalar initial_size; // Pierre-Marie Baty -- unused variable |
||
| 278 | br_scalar this_size; |
||
| 279 | br_vector3 v; |
||
| 280 | tNet_message* message; |
||
| 281 | LOG_TRACE("(%d)", pFrame_period); |
||
| 282 | |||
| 283 | time = GetTotalTime(); |
||
| 284 | for (i = 0; i < COUNT_OF(gOily_spills); i++) { |
||
| 285 | if (gOily_spills[i].car == NULL) { |
||
| 286 | gOily_spills[i].actor->render_style = BR_RSTYLE_NONE; |
||
| 287 | } else { |
||
| 288 | the_model = gOily_spills[i].actor->model; |
||
| 20 | pmbaty | 289 | if (gOily_spills[i].actor->render_style == BR_RSTYLE_NONE && |
| 290 | gOily_spills[i].spill_time <= time && |
||
| 291 | fabsf(gOily_spills[i].car->v.v[0]) < .01f && |
||
| 292 | fabsf(gOily_spills[i].car->v.v[1]) < .01f && |
||
| 293 | fabsf(gOily_spills[i].car->v.v[2]) < .01f) { |
||
| 1 | pmbaty | 294 | if (gAction_replay_mode) { |
| 295 | SetInitialOilStuff(&gOily_spills[i], the_model); |
||
| 296 | } else { |
||
| 297 | if (!OKToSpillOil(&gOily_spills[i])) { |
||
| 298 | gOily_spills[i].car = NULL; |
||
| 299 | } else { |
||
| 300 | gOily_spills[i].spill_time = time; |
||
| 301 | gOily_spills[i].actor->material->colour_map = gOil_pixies[gNext_oil_pixie]; |
||
| 302 | gNext_oil_pixie++; |
||
| 303 | if (gNext_oil_pixie >= COUNT_OF(gOil_pixies)) { |
||
| 304 | gNext_oil_pixie = 0; |
||
| 305 | } |
||
| 306 | BrVector3Copy(&gOily_spills[i].original_pos, &gOily_spills[i].car->pos); |
||
| 307 | PipeSingleOilSpill(i, |
||
| 308 | &gOily_spills[i].actor->t.t.mat, |
||
| 309 | gOily_spills[i].full_size, |
||
| 310 | gOily_spills[i].grow_rate, |
||
| 311 | gOily_spills[i].spill_time, |
||
| 312 | gOily_spills[i].stop_time, |
||
| 313 | gOily_spills[i].car, |
||
| 314 | &gOily_spills[i].original_pos, |
||
| 315 | gOily_spills[i].actor->material->colour_map); |
||
| 316 | gOily_spills[i].stop_time = 0; |
||
| 317 | SetInitialOilStuff(&gOily_spills[i], the_model); |
||
| 318 | if (gNet_mode != eNet_mode_none) { |
||
| 319 | message = NetBuildMessage(30, 0); |
||
| 320 | message->contents.data.oil_spill.player = NetPlayerFromCar(gOily_spills[i].car)->ID; |
||
| 321 | message->contents.data.oil_spill.full_size = gOily_spills[i].full_size; |
||
| 322 | message->contents.data.oil_spill.grow_rate = gOily_spills[i].grow_rate; |
||
| 323 | message->contents.data.oil_spill.current_size = gOily_spills[i].current_size; |
||
| 324 | NetGuaranteedSendMessageToAllPlayers(gCurrent_net_game, message, NULL); |
||
| 325 | } |
||
| 326 | } |
||
| 327 | } |
||
| 328 | } else { |
||
| 20 | pmbaty | 329 | if (gOily_spills[i].actor->render_style == BR_RSTYLE_FACES && |
| 330 | (gOily_spills[i].stop_time == 0 || time < gOily_spills[i].stop_time)) { |
||
| 1 | pmbaty | 331 | BrVector3Sub(&v, &gOily_spills[i].original_pos, &gOily_spills[i].car->pos); |
| 332 | grow_amount = BrVector3LengthSquared(&v); |
||
| 333 | if (gOily_spills[i].stop_time != 0 || grow_amount <= 0.2f) { |
||
| 334 | this_size = 0.1f + (time - gOily_spills[i].spill_time) * gOily_spills[i].grow_rate; |
||
| 335 | if (this_size >= 0.1f) { |
||
| 336 | gOily_spills[i].actor->render_style = BR_RSTYLE_FACES; |
||
| 337 | if (this_size <= gOily_spills[i].full_size) { |
||
| 338 | the_model->vertices[0].p.v[0] = -this_size; |
||
| 339 | the_model->vertices[0].p.v[2] = -this_size; |
||
| 340 | the_model->vertices[1].p.v[0] = this_size; |
||
| 341 | the_model->vertices[1].p.v[2] = -this_size; |
||
| 342 | the_model->vertices[2].p.v[0] = this_size; |
||
| 343 | the_model->vertices[2].p.v[2] = this_size; |
||
| 344 | the_model->vertices[3].p.v[0] = -this_size; |
||
| 345 | the_model->vertices[3].p.v[2] = this_size; |
||
| 346 | gOily_spills[i].current_size = this_size; |
||
| 347 | } else { |
||
| 348 | the_model->vertices[0].p.v[0] = -gOily_spills[i].full_size; |
||
| 349 | the_model->vertices[0].p.v[2] = -gOily_spills[i].full_size; |
||
| 350 | the_model->vertices[1].p.v[0] = gOily_spills[i].full_size; |
||
| 351 | the_model->vertices[1].p.v[2] = -gOily_spills[i].full_size; |
||
| 352 | the_model->vertices[2].p.v[0] = gOily_spills[i].full_size; |
||
| 353 | the_model->vertices[2].p.v[2] = gOily_spills[i].full_size; |
||
| 354 | the_model->vertices[3].p.v[0] = -gOily_spills[i].full_size; |
||
| 355 | the_model->vertices[3].p.v[2] = gOily_spills[i].full_size; |
||
| 356 | gOily_spills[i].current_size = gOily_spills[i].full_size; |
||
| 357 | } |
||
| 358 | BrModelUpdate(the_model, BR_MODU_ALL); |
||
| 359 | } else { |
||
| 360 | gOily_spills[i].actor->render_style = BR_RSTYLE_NONE; |
||
| 361 | } |
||
| 362 | } else { |
||
| 363 | gOily_spills[i].stop_time = time; |
||
| 364 | continue; |
||
| 365 | } |
||
| 366 | } |
||
| 367 | } |
||
| 368 | } |
||
| 369 | if (gOily_spills[i].actor->render_style == BR_RSTYLE_FACES) { |
||
| 370 | MungeOilsHeightAboveGround(&gOily_spills[i]); |
||
| 371 | } |
||
| 372 | } |
||
| 373 | } |
||
| 374 | |||
| 375 | // IDA: int __cdecl GetOilSpillCount() |
||
| 376 | int GetOilSpillCount(void) { |
||
| 20 | pmbaty | 377 | //LOG_TRACE("()"); |
| 1 | pmbaty | 378 | |
| 379 | return COUNT_OF(gOily_spills); |
||
| 380 | } |
||
| 381 | |||
| 382 | // IDA: void __usercall GetOilSpillDetails(int pIndex@<EAX>, br_actor **pActor@<EDX>, br_scalar *pSize@<EBX>) |
||
| 383 | void GetOilSpillDetails(int pIndex, br_actor** pActor, br_scalar* pSize) { |
||
| 384 | LOG_TRACE("(%d, %p, %p)", pIndex, pActor, pSize); |
||
| 385 | |||
| 386 | if (gOily_spills[pIndex].car != NULL) { |
||
| 387 | *pActor = gOily_spills[pIndex].actor; |
||
| 388 | *pSize = gOily_spills[pIndex].full_size; |
||
| 389 | } else { |
||
| 390 | *pActor = NULL; |
||
| 391 | } |
||
| 392 | } |
||
| 393 | |||
| 20 | pmbaty | 394 | #define SQR(V) ((V)*(V)) |
| 1 | pmbaty | 395 | |
| 396 | // IDA: int __usercall PointInSpill@<EAX>(br_vector3 *pV@<EAX>, int pSpill@<EDX>) |
||
| 397 | int PointInSpill(br_vector3* pV, int pSpill) { |
||
| 398 | LOG_TRACE("(%p, %d)", pV, pSpill); |
||
| 399 | |||
| 400 | return gOily_spills[pSpill].current_size * gOily_spills[pSpill].current_size * 0.8f > SQR(pV->v[0] / WORLD_SCALE - gOily_spills[pSpill].actor->t.t.translate.t.v[0]) |
||
| 401 | && gOily_spills[pSpill].current_size * gOily_spills[pSpill].current_size * 0.8f > SQR(pV->v[2] / WORLD_SCALE - gOily_spills[pSpill].actor->t.t.translate.t.v[2]) |
||
| 402 | && fabsf(pV->v[1] / WORLD_SCALE - gOily_spills[pSpill].actor->t.t.translate.t.v[1]) < 0.1f; |
||
| 403 | } |
||
| 404 | |||
| 405 | // IDA: void __usercall GetOilFrictionFactors(tCar_spec *pCar@<EAX>, br_scalar *pFl_factor@<EDX>, br_scalar *pFr_factor@<EBX>, br_scalar *pRl_factor@<ECX>, br_scalar *pRr_factor) |
||
| 406 | void GetOilFrictionFactors(tCar_spec* pCar, br_scalar* pFl_factor, br_scalar* pFr_factor, br_scalar* pRl_factor, br_scalar* pRr_factor) { |
||
| 407 | int i; |
||
| 408 | br_vector3 wheel_world; |
||
| 409 | LOG_TRACE("(%p, %p, %p, %p, %p)", pCar, pFl_factor, pFr_factor, pRl_factor, pRr_factor); |
||
| 410 | |||
| 411 | *pFl_factor = 1.0f; |
||
| 412 | *pFr_factor = 1.0f; |
||
| 413 | *pRl_factor = 1.0f; |
||
| 414 | *pRr_factor = 1.0f; |
||
| 415 | switch (pCar->driver) { |
||
| 416 | case eDriver_non_car_unused_slot: |
||
| 417 | case eDriver_non_car: |
||
| 418 | return; |
||
| 419 | default: |
||
| 420 | break; |
||
| 421 | } |
||
| 422 | if (pCar->shadow_intersection_flags != 0) { |
||
| 423 | for (i = 0; i < COUNT_OF(gOily_spills); i++) { |
||
| 424 | if (((1 << i) & pCar->shadow_intersection_flags) != 0 && gOily_spills[i].car != NULL) { |
||
| 425 | BrMatrix34ApplyP(&wheel_world, &pCar->wpos[2], &pCar->car_master_actor->t.t.mat); |
||
| 426 | if (PointInSpill(&wheel_world, i)) { |
||
| 427 | pCar->oil_remaining[2] = SRandomBetween(1.5f, 2.5f); |
||
| 428 | } |
||
| 429 | BrMatrix34ApplyP(&wheel_world, &pCar->wpos[3], &pCar->car_master_actor->t.t.mat); |
||
| 430 | if (PointInSpill(&wheel_world, i)) { |
||
| 431 | pCar->oil_remaining[3] = SRandomBetween(1.5f, 2.5f); |
||
| 432 | } |
||
| 433 | BrMatrix34ApplyP(&wheel_world, &pCar->wpos[0], &pCar->car_master_actor->t.t.mat); |
||
| 434 | if (PointInSpill(&wheel_world, i)) { |
||
| 435 | pCar->oil_remaining[0] = SRandomBetween(1.5f, 2.5f); |
||
| 436 | } |
||
| 437 | BrMatrix34ApplyP(&wheel_world, &pCar->wpos[1], &pCar->car_master_actor->t.t.mat); |
||
| 438 | if (PointInSpill(&wheel_world, i)) { |
||
| 439 | pCar->oil_remaining[1] = SRandomBetween(1.5f, 2.5f); |
||
| 440 | } |
||
| 441 | } |
||
| 442 | } |
||
| 443 | } |
||
| 444 | if (pCar->oil_remaining[2] != 0.0f) { |
||
| 445 | *pFl_factor = SRandomBetween(0.01f, 0.15f); |
||
| 446 | } |
||
| 447 | if (pCar->oil_remaining[3] != 0.0f) { |
||
| 448 | *pFr_factor = SRandomBetween(0.01f, 0.15f); |
||
| 449 | } |
||
| 450 | if (pCar->oil_remaining[0] != 0.0f) { |
||
| 451 | *pRl_factor = SRandomBetween(0.01f, 0.15f); |
||
| 452 | } |
||
| 453 | if (pCar->oil_remaining[1] != 0.0f) { |
||
| 454 | *pRr_factor = SRandomBetween(0.01f, 0.15f); |
||
| 455 | } |
||
| 456 | } |
||
| 457 | |||
| 458 | // IDA: void __usercall AdjustOilSpill(int pIndex@<EAX>, br_matrix34 *pMat@<EDX>, br_scalar pFull_size, br_scalar pGrow_rate, tU32 pSpill_time, tU32 pStop_time, tCar_spec *pCar, br_vector3 *pOriginal_pos, br_pixelmap *pPixelmap) |
||
| 459 | void AdjustOilSpill(int pIndex, br_matrix34* pMat, br_scalar pFull_size, br_scalar pGrow_rate, tU32 pSpill_time, tU32 pStop_time, tCar_spec* pCar, br_vector3* pOriginal_pos, br_pixelmap* pPixelmap) { |
||
| 460 | LOG_TRACE("(%d, %p, %f, %f, %d, %d, %p, %p, %p)", pIndex, pMat, pFull_size, pGrow_rate, pSpill_time, pStop_time, pCar, pOriginal_pos, pPixelmap); |
||
| 461 | |||
| 462 | BrMatrix34Copy(&gOily_spills[pIndex].actor->t.t.mat, pMat); |
||
| 463 | gOily_spills[pIndex].full_size = pFull_size; |
||
| 464 | gOily_spills[pIndex].grow_rate = pGrow_rate; |
||
| 465 | gOily_spills[pIndex].spill_time = pSpill_time; |
||
| 466 | gOily_spills[pIndex].stop_time = pStop_time; |
||
| 467 | gOily_spills[pIndex].car = pCar; |
||
| 468 | BrVector3Copy(&gOily_spills[pIndex].original_pos, pOriginal_pos); |
||
| 469 | gOily_spills[pIndex].actor->material->colour_map = pPixelmap; |
||
| 470 | gOily_spills[pIndex].actor->render_style = BR_RSTYLE_NONE; |
||
| 471 | } |
||
| 472 | |||
| 473 | // IDA: void __usercall ReceivedOilSpill(tNet_contents *pContents@<EAX>) |
||
| 474 | void ReceivedOilSpill(tNet_contents* pContents) { |
||
| 475 | int i; |
||
| 476 | int oily_index; |
||
| 477 | int oldest_one; |
||
| 478 | tU32 the_time; |
||
| 479 | tU32 oldest_time; |
||
| 480 | tCar_spec* car; |
||
| 481 | LOG_TRACE("(%p)", pContents); |
||
| 482 | |||
| 483 | oldest_one = 0; |
||
| 484 | car = NetCarFromPlayerID(pContents->data.oil_spill.player); |
||
| 485 | if (car == NULL) { |
||
| 486 | return; |
||
| 487 | } |
||
| 488 | oily_index = -1; |
||
| 489 | the_time = GetTotalTime(); |
||
| 490 | oldest_time = GetTotalTime(); |
||
| 491 | for (i = 0; i < COUNT_OF(gOily_spills); i++) { |
||
| 492 | if (gOily_spills[i].car == car && the_time < gOily_spills[i].spill_time + 5000) { |
||
| 493 | return; |
||
| 494 | } |
||
| 495 | } |
||
| 496 | for (i = 0; i < COUNT_OF(gOily_spills); i++) { |
||
| 497 | if (gOily_spills[i].car == NULL) { |
||
| 498 | oily_index = i; |
||
| 499 | break; |
||
| 500 | } |
||
| 501 | if (gOily_spills[i].spill_time < oldest_time) { |
||
| 502 | oldest_time = gOily_spills[i].spill_time; |
||
| 503 | oldest_one = i; |
||
| 504 | } |
||
| 505 | } |
||
| 506 | if (oily_index < 0) { |
||
| 507 | oily_index = oldest_one; |
||
| 508 | } |
||
| 509 | gOily_spills[oily_index].car = car; |
||
| 510 | gOily_spills[oily_index].spill_time = the_time; |
||
| 511 | gOily_spills[oily_index].full_size = pContents->data.oil_spill.full_size; |
||
| 512 | gOily_spills[oily_index].grow_rate = pContents->data.oil_spill.grow_rate; |
||
| 513 | gOily_spills[oily_index].current_size = pContents->data.oil_spill.current_size; |
||
| 514 | gOily_spills[oily_index].actor->render_style = BR_RSTYLE_NONE; |
||
| 515 | } |