| | 1 | #include "system.h" |
| | 2 | #include "prototyp.h" |
| | 3 | #include "stratdef.h" |
| | 4 | #include "bh_types.h" |
| | 5 | #include "dynamics.h" |
| | 6 | #include "kshape.h" |
| | 7 | #include "sfx.h" |
| | 8 | #include "lighting.h" |
| | 9 | #include "bh_light.h" |
| | 10 | #include "npc_xenoborg.h" |
| | 11 | #include "weapons.h" |
| | 12 | #include "weaponbehaviour.h" |
| | 13 | #include "pldghost.h" |
| | 14 | #include "userprofile.h" |
| | 15 | #include "savegame.h" |
| | 16 | #include "los.h" |
| | 17 | #include <math.h> |
| | 18 | #include <assert.h> |
| | 19 | |
| | 20 | #define MAX_NO_OF_PHEROMONE_TRAILS 500 |
| | 21 | #define MAX_NO_OF_EXPLOSIONS 10 |
| | 22 | #define TRAIL_DECAY_SPEED (51*65536*5) |
| | 23 | |
| | 24 | static PHEROMONE_TRAIL TrailStorage[MAX_NO_OF_PHEROMONE_TRAILS]; |
| | 25 | |
| | 26 | static PARTICLE ParticleStorage[MAX_NO_OF_PARTICLES]; |
| | 27 | static PARTICLE BloodParticleStorage[MAX_NO_OF_BLOOD_PARTICLES]; |
| | 28 | |
| | 29 | static struct VOLUMETRIC_EXPLOSION ExplosionStorage[MAX_NO_OF_EXPLOSIONS]; |
| | 30 | static struct VOLUMETRIC_EXPLOSION* active_volumetric_explosion[MAX_NO_OF_EXPLOSIONS]; |
| | 31 | static int NumActiveTrails; |
| | 32 | static int NumActiveParticles; |
| | 33 | static int CurrentExplosionIndex; |
| | 34 | |
| | 35 | extern int SeededFastRandom(); |
| | 36 | extern void SetSeededFastRandom(int seed); |
| | 37 | |
| | 38 | extern void PostLandscapeRendering(); |
| | 39 | extern void DrawParticle_Rain(PARTICLE *particlePtr, VECTORCH *prevPositionPtr); |
| | 40 | extern void AttachSpearGunArrow(DISPLAYBLOCK *dptr); |
| | 41 | extern void ZBufferedGouraudTexturedPolygon_Output(POLYHEADER *inputPolyPtr, RENDERVERTEX *renderVerticesPtr); |
| | 42 | |
| | 43 | extern DISPLAYBLOCK *ActiveBlockList[]; |
| | 44 | extern int NumActiveBlocks; |
| | 45 | extern int PrevNormalFrameTime; |
| | 46 | extern int CloakingPhase; |
| | 47 | extern SOUND3DDATA PredPistolExplosion_SoundData; |
| | 48 | |
| | 49 | extern struct KObject VisibleObjects[maxobjects]; |
| | 50 | extern int numVisObjs; |
| | 51 | |
| | 52 | int NumberOfBloodParticles; |
| | 53 | |
| | 54 | const PARTICLE_DESC ParticleDescription[MAX_NO_OF_PARTICLE_IDS] = |
| | 55 | { |
| | 56 | /* PARTICLE_PREDATOR_BLOOD */ |
| | 57 | { |
| | 58 | //int StartU; |
| | 59 | 0<<16, |
| | 60 | //int StartV; |
| | 61 | 64<<16, |
| | 62 | //int EndU; |
| | 63 | 63<<16, |
| | 64 | //int EndV; |
| | 65 | 127<<16, |
| | 66 | //unsigned int Size; |
| | 67 | 200, |
| | 68 | |
| | 69 | TRANSLUCENCY_GLOWING, |
| | 70 | |
| | 71 | //unsigned char Alpha; |
| | 72 | 128, |
| | 73 | //unsigned char RedScale; |
| | 74 | {0, 0, 255, 255, 255}, |
| | 75 | //unsigned char GreenScale; |
| | 76 | {255, 255, 255, 255, 0}, |
| | 77 | //unsigned char BlueScale; |
| | 78 | {0, 0, 255, 255, 0}, |
| | 79 | |
| | 80 | //unsigned char IsLit:1; |
| | 81 | 0, |
| | 82 | //IsDrawnInFront:1; |
| | 83 | 0, |
| | 84 | //IsDrawnAtBack:1; |
| | 85 | 0, |
| | 86 | |
| | 87 | }, |
| | 88 | /* PARTICLE_ALIEN_BLOOD */ |
| | 89 | { |
| | 90 | //int StartU; |
| | 91 | 0<<16, |
| | 92 | //int StartV; |
| | 93 | 64<<16, |
| | 94 | //int EndU; |
| | 95 | 63<<16, |
| | 96 | //int EndV; |
| | 97 | 127<<16, |
| | 98 | //unsigned int Size; |
| | 99 | 50, |
| | 100 | |
| | 101 | TRANSLUCENCY_GLOWING, |
| | 102 | |
| | 103 | //unsigned char Alpha; |
| | 104 | 128, |
| | 105 | //unsigned char RedScale; |
| | 106 | {255, 255, 0, 16, 255}, |
| | 107 | //unsigned char GreenScale; |
| | 108 | {255, 255, 255, 0, 255}, |
| | 109 | //unsigned char BlueScale; |
| | 110 | {0, 0, 0, 255, 255}, |
| | 111 | |
| | 112 | //unsigned char IsLit:1; |
| | 113 | 1, |
| | 114 | //IsDrawnInFront:1; |
| | 115 | 0, |
| | 116 | //IsDrawnAtBack:1; |
| | 117 | 0, |
| | 118 | |
| | 119 | }, |
| | 120 | /* PARTICLE_HUMAN_BLOOD */ |
| | 121 | { |
| | 122 | //int StartU; |
| | 123 | 0<<16, |
| | 124 | //int StartV; |
| | 125 | 63<<16, |
| | 126 | //int EndU; |
| | 127 | 63<<16, |
| | 128 | //int EndV; |
| | 129 | 127<<16, |
| | 130 | //unsigned int Size; |
| | 131 | 50, |
| | 132 | |
| | 133 | TRANSLUCENCY_INVCOLOUR, |
| | 134 | |
| | 135 | //unsigned char Alpha; |
| | 136 | 255, |
| | 137 | //unsigned char RedScale; |
| | 138 | {0, 0, 0, 0 , 0}, |
| | 139 | //unsigned char GreenScale; |
| | 140 | {255, 255, 64, 64, 255}, |
| | 141 | //unsigned char BlueScale; |
| | 142 | {255, 255, 0, 64, 255}, |
| | 143 | |
| | 144 | //unsigned char IsLit:1; |
| | 145 | 0, |
| | 146 | //IsDrawnInFront:1; |
| | 147 | 0, |
| | 148 | //IsDrawnAtBack:1; |
| | 149 | 0, |
| | 150 | }, |
| | 151 | /* PARTICLE_ANDROID_BLOOD */ |
| | 152 | { |
| | 153 | //int StartU; |
| | 154 | 0<<16, |
| | 155 | //int StartV; |
| | 156 | 63<<16, |
| | 157 | //int EndU; |
| | 158 | 63<<16, |
| | 159 | //int EndV; |
| | 160 | 127<<16, |
| | 161 | //unsigned int Size; |
| | 162 | 50, |
| | 163 | |
| | 164 | TRANSLUCENCY_GLOWING, |
| | 165 | |
| | 166 | //unsigned char Alpha; |
| | 167 | 255, |
| | 168 | //unsigned char RedScale; |
| | 169 | {255, 255, 255, 255, 255}, |
| | 170 | //unsigned char GreenScale; |
| | 171 | {255, 255, 255, 255, 255}, |
| | 172 | //unsigned char BlueScale; |
| | 173 | {255, 255, 255, 255, 255}, |
| | 174 | |
| | 175 | //unsigned char IsLit:1; |
| | 176 | 1, |
| | 177 | //IsDrawnInFront:1; |
| | 178 | 0, |
| | 179 | //IsDrawnAtBack:1; |
| | 180 | 0, |
| | 181 | }, |
| | 182 | /* PARTICLE_MUZZLEFLASH */ |
| | 183 | { |
| | 184 | //int StartU; |
| | 185 | 64<<16, |
| | 186 | //int StartV; |
| | 187 | 64<<16, |
| | 188 | //int EndU; |
| | 189 | 127<<16, |
| | 190 | //int EndV; |
| | 191 | 127<<16, |
| | 192 | //unsigned int Size; |
| | 193 | 200, |
| | 194 | |
| | 195 | TRANSLUCENCY_GLOWING, |
| | 196 | |
| | 197 | //unsigned char Alpha; |
| | 198 | 255, |
| | 199 | //100/2, |
| | 200 | //unsigned char RedScale; |
| | 201 | {255, 255, 255, 255, 255}, |
| | 202 | //unsigned char GreenScale; |
| | 203 | {192, 255, 255, 0 , 255}, |
| | 204 | //unsigned char BlueScale; |
| | 205 | {128, 255, 255, 0 , 0}, |
| | 206 | |
| | 207 | //unsigned char IsLit:1; |
| | 208 | 0, |
| | 209 | //IsDrawnInFront:1; |
| | 210 | 0, |
| | 211 | //IsDrawnAtBack:1; |
| | 212 | 0, |
| | 213 | }, |
| | 214 | /* PARTICLE_WATERSPRAY */ |
| | 215 | { |
| | 216 | //int StartU; |
| | 217 | 0<<16, |
| | 218 | //int StartV; |
| | 219 | 64<<16, |
| | 220 | //int EndU; |
| | 221 | 63<<16, |
| | 222 | //int EndV; |
| | 223 | 127<<16, |
| | 224 | //unsigned int Size; |
| | 225 | 80, |
| | 226 | |
| | 227 | TRANSLUCENCY_GLOWING, |
| | 228 | |
| | 229 | //unsigned char Alpha; |
| | 230 | 64, |
| | 231 | //unsigned char RedScale; |
| | 232 | {200, 200, 0, 0}, |
| | 233 | //unsigned char GreenScale; |
| | 234 | {230, 230, 240, 0}, |
| | 235 | //unsigned char BlueScale; |
| | 236 | {255, 255, 0, 120}, |
| | 237 | |
| | 238 | //unsigned char IsLit:1; |
| | 239 | 1, |
| | 240 | //IsDrawnInFront:1; |
| | 241 | 0, |
| | 242 | //IsDrawnAtBack:1; |
| | 243 | 0, |
| | 244 | }, |
| | 245 | /* PARTICLE_WATERFALLSPRAY */ |
| | 246 | { |
| | 247 | //int StartU; |
| | 248 | 0<<16, |
| | 249 | //int StartV; |
| | 250 | 64<<16, |
| | 251 | //int EndU; |
| | 252 | 63<<16, |
| | 253 | //int EndV; |
| | 254 | 127<<16, |
| | 255 | //unsigned int Size; |
| | 256 | 1600,//200, |
| | 257 | |
| | 258 | TRANSLUCENCY_GLOWING, |
| | 259 | |
| | 260 | //unsigned char Alpha; |
| | 261 | 32, |
| | 262 | //unsigned char RedScale; |
| | 263 | {100, 200, 240, 120, 120, 120}, |
| | 264 | //unsigned char GreenScale; |
| | 265 | {130, 230, 240, 120, 120, 120}, |
| | 266 | //unsigned char BlueScale; |
| | 267 | {255, 255, 240, 120, 120, 120}, |
| | 268 | |
| | 269 | //unsigned char IsLit:1; |
| | 270 | 0, |
| | 271 | //IsDrawnInFront:1; |
| | 272 | 0, |
| | 273 | //IsDrawnAtBack:1; |
| | 274 | 0, |
| | 275 | }, |
| | 276 | /* PARTICLE_BLACKSMOKE */ |
| | 277 | { |
| | 278 | //int StartU; |
| | 279 | 0<<16, |
| | 280 | //int StartV; |
| | 281 | 130<<16, |
| | 282 | //int EndU; |
| | 283 | 28<<16, |
| | 284 | //int EndV; |
| | 285 | 157<<16, |
| | 286 | //unsigned int Size; |
| | 287 | 200, |
| | 288 | |
| | 289 | TRANSLUCENCY_INVCOLOUR, |
| | 290 | |
| | 291 | //unsigned char Alpha; |
| | 292 | 255, |
| | 293 | //unsigned char RedScale; |
| | 294 | {64, 64, 64, 64, 64}, |
| | 295 | //unsigned char GreenScale; |
| | 296 | {64, 64, 64, 64, 64}, |
| | 297 | //unsigned char BlueScale; |
| | 298 | {64, 64, 64, 64, 64}, |
| | 299 | |
| | 300 | //unsigned char IsLit:1; |
| | 301 | 0, |
| | 302 | //IsDrawnInFront:1; |
| | 303 | 0, |
| | 304 | //IsDrawnAtBack:1; |
| | 305 | 0, |
| | 306 | }, |
| | 307 | /* PARTICLE_FLARESMOKE */ |
| | 308 | { |
| | 309 | //int StartU; |
| | 310 | 128<<16, |
| | 311 | //int StartV; |
| | 312 | 0<<16, |
| | 313 | //int EndU; |
| | 314 | 195<<16, |
| | 315 | //int EndV; |
| | 316 | 63<<16, |
| | 317 | //unsigned int Size; |
| | 318 | 200, |
| | 319 | |
| | 320 | TRANSLUCENCY_GLOWING, |
| | 321 | |
| | 322 | //unsigned char Alpha; |
| | 323 | 64, |
| | 324 | //unsigned char RedScale; |
| | 325 | {255, 255, 255, 255, 64}, |
| | 326 | //unsigned char GreenScale; |
| | 327 | {255, 255, 255, 0, 64}, |
| | 328 | //unsigned char BlueScale; |
| | 329 | {255, 255, 255, 64, 0}, |
| | 330 | |
| | 331 | //unsigned char IsLit:1; |
| | 332 | 0, |
| | 333 | //IsDrawnInFront:1; |
| | 334 | 0, |
| | 335 | //IsDrawnAtBack:1; |
| | 336 | 0, |
| | 337 | }, |
| | 338 | /* PARTICLE_STEAM */ |
| | 339 | { |
| | 340 | //int StartU; |
| | 341 | 0<<16, |
| | 342 | //int StartV; |
| | 343 | 130<<16, |
| | 344 | //int EndU; |
| | 345 | 28<<16, |
| | 346 | //int EndV; |
| | 347 | 157<<16, |
| | 348 | //unsigned int Size; |
| | 349 | 100, |
| | 350 | |
| | 351 | TRANSLUCENCY_GLOWING, |
| | 352 | |
| | 353 | //unsigned char Alpha; |
| | 354 | 64, |
| | 355 | //unsigned char RedScale; |
| | 356 | {128, 128, 128, 128, 64}, |
| | 357 | //unsigned char GreenScale; |
| | 358 | {128, 128, 128, 128, 64}, |
| | 359 | //unsigned char BlueScale; |
| | 360 | {128, 128, 128, 128, 0}, |
| | 361 | |
| | 362 | //unsigned char IsLit:1; |
| | 363 | 0, |
| | 364 | //IsDrawnInFront:1; |
| | 365 | 0, |
| | 366 | //IsDrawnAtBack:1; |
| | 367 | 0, |
| | 368 | }, |
| | 369 | /* PARTICLE_IMPACTSMOKE */ |
| | 370 | { |
| | 371 | //int StartU; |
| | 372 | 0<<16, |
| | 373 | //int StartV; |
| | 374 | 130<<16, |
| | 375 | //int EndU; |
| | 376 | 28<<16, |
| | 377 | //int EndV; |
| | 378 | 157<<16, |
| | 379 | //unsigned int Size; |
| | 380 | //100, |
| | 381 | 50, |
| | 382 | |
| | 383 | TRANSLUCENCY_INVCOLOUR, |
| | 384 | |
| | 385 | //unsigned char Alpha; |
| | 386 | 255, |
| | 387 | //unsigned char RedScale; |
| | 388 | {64, 64, 64, 64, 64}, |
| | 389 | //unsigned char GreenScale; |
| | 390 | {64, 64, 64, 64, 64}, |
| | 391 | //unsigned char BlueScale; |
| | 392 | {64, 64, 64, 64, 64}, |
| | 393 | |
| | 394 | //unsigned char IsLit:1; |
| | 395 | 0, |
| | 396 | //IsDrawnInFront:1; |
| | 397 | 0, |
| | 398 | //IsDrawnAtBack:1; |
| | 399 | 0, |
| | 400 | }, |
| | 401 | /* PARTICLE_GUNMUZZLE_SMOKE */ |
| | 402 | { |
| | 403 | //int StartU; |
| | 404 | 128<<16, |
| | 405 | //int StartV; |
| | 406 | 0<<16, |
| | 407 | //int EndU; |
| | 408 | 195<<16, |
| | 409 | //int EndV; |
| | 410 | 63<<16, |
| | 411 | //unsigned int Size; |
| | 412 | 32, |
| | 413 | |
| | 414 | TRANSLUCENCY_GLOWING, |
| | 415 | |
| | 416 | //unsigned char Alpha; |
| | 417 | 64, |
| | 418 | //unsigned char RedScale; |
| | 419 | {255, 255, 255, 255, 64}, |
| | 420 | //unsigned char GreenScale; |
| | 421 | {255, 255, 255, 0, 64}, |
| | 422 | //unsigned char BlueScale; |
| | 423 | {255, 255, 255, 64, 0}, |
| | 424 | |
| | 425 | //unsigned char IsLit:1; |
| | 426 | 1, |
| | 427 | //IsDrawnInFront:1; |
| | 428 | 0, |
| | 429 | //IsDrawnAtBack:1; |
| | 430 | 0, |
| | 431 | }, |
| | 432 | /* PARTICLE_FLAME */ |
| | 433 | { |
| | 434 | //int StartU; |
| | 435 | 64<<16, |
| | 436 | //int StartV; |
| | 437 | 0<<16, |
| | 438 | //int EndU; |
| | 439 | (64+127)<<16, |
| | 440 | //int EndV; |
| | 441 | 63<<16, |
| | 442 | //unsigned int Size; |
| | 443 | 0, |
| | 444 | |
| | 445 | TRANSLUCENCY_GLOWING, |
| | 446 | |
| | 447 | //unsigned char Alpha; |
| | 448 | 64, |
| | 449 | //unsigned char RedScale; |
| | 450 | {255, 255, 255, 128, 128, 0}, |
| | 451 | //unsigned char GreenScale; |
| | 452 | {128, 128, 255, 64, 64, 128}, |
| | 453 | //unsigned char BlueScale; |
| | 454 | {64, 64, 255, 255, 0, 0}, |
| | 455 | |
| | 456 | //unsigned char IsLit:1; |
| | 457 | 0, |
| | 458 | //IsDrawnInFront:1; |
| | 459 | 0, |
| | 460 | //IsDrawnAtBack:1; |
| | 461 | 0, |
| | 462 | }, |
| | 463 | /* PARTICLE_NONCOLLIDINGFLAME */ |
| | 464 | { |
| | 465 | //int StartU; |
| | 466 | 64<<16, |
| | 467 | //int StartV; |
| | 468 | 0<<16, |
| | 469 | //int EndU; |
| | 470 | (64+127)<<16, |
| | 471 | //int EndV; |
| | 472 | 63<<16, |
| | 473 | //unsigned int Size; |
| | 474 | 0, |
| | 475 | |
| | 476 | TRANSLUCENCY_GLOWING, |
| | 477 | |
| | 478 | //unsigned char Alpha; |
| | 479 | 64, |
| | 480 | //unsigned char RedScale; |
| | 481 | {255, 255, 255, 128, 128, 0}, |
| | 482 | //unsigned char GreenScale; |
| | 483 | {128, 128, 255, 64, 64, 128}, |
| | 484 | //unsigned char BlueScale; |
| | 485 | {64, 64, 255, 255, 0, 0}, |
| | 486 | |
| | 487 | //unsigned char IsLit:1; |
| | 488 | 0, |
| | 489 | //IsDrawnInFront:1; |
| | 490 | 0, |
| | 491 | //IsDrawnAtBack:1; |
| | 492 | 0, |
| | 493 | }, |
| | 494 | /* PARTICLE_NONDAMAGINGFLAME */ |
| | 495 | { |
| | 496 | //int StartU; |
| | 497 | 64<<16, |
| | 498 | //int StartV; |
| | 499 | 0<<16, |
| | 500 | //int EndU; |
| | 501 | (64+127)<<16, |
| | 502 | //int EndV; |
| | 503 | 63<<16, |
| | 504 | //unsigned int Size; |
| | 505 | 0, |
| | 506 | |
| | 507 | TRANSLUCENCY_GLOWING, |
| | 508 | |
| | 509 | //unsigned char Alpha; |
| | 510 | 64, |
| | 511 | //unsigned char RedScale; |
| | 512 | {255, 255, 255, 128, 128, 0}, |
| | 513 | //unsigned char GreenScale; |
| | 514 | {128, 128, 255, 64, 64, 128}, |
| | 515 | //unsigned char BlueScale; |
| | 516 | {64, 64, 255, 255, 0, 0}, |
| | 517 | |
| | 518 | //unsigned char IsLit:1; |
| | 519 | 0, |
| | 520 | //IsDrawnInFront:1; |
| | 521 | 0, |
| | 522 | //IsDrawnAtBack:1; |
| | 523 | 0, |
| | 524 | }, |
| | 525 | /* PARTICLE_FIRE */ |
| | 526 | { |
| | 527 | //int StartU; |
| | 528 | 0<<16, |
| | 529 | //int StartV; |
| | 530 | 0<<16, |
| | 531 | //int EndU; |
| | 532 | 63<<16, |
| | 533 | //int EndV; |
| | 534 | 63<<16, |
| | 535 | //unsigned int Size; |
| | 536 | 0, |
| | 537 | |
| | 538 | TRANSLUCENCY_GLOWING, |
| | 539 | |
| | 540 | //unsigned char Alpha; |
| | 541 | 64, |
| | 542 | //unsigned char RedScale; |
| | 543 | {255, 255, 255, 128, 128, 0}, |
| | 544 | //unsigned char GreenScale; |
| | 545 | {128, 128, 255, 64, 64, 128}, |
| | 546 | //unsigned char BlueScale; |
| | 547 | {64, 64, 255, 255, 0, 0}, |
| | 548 | |
| | 549 | //unsigned char IsLit:1; |
| | 550 | 0, |
| | 551 | //IsDrawnInFront:1; |
| | 552 | 0, |
| | 553 | //IsDrawnAtBack:1; |
| | 554 | 0, |
| | 555 | }, |
| | 556 | /* PARTICLE_EXPLOSIONFIRE */ |
| | 557 | { |
| | 558 | //int StartU; |
| | 559 | 0<<16, |
| | 560 | //int StartV; |
| | 561 | 0<<16, |
| | 562 | //int EndU; |
| | 563 | 48<<16, |
| | 564 | //int EndV; |
| | 565 | 63<<16, |
| | 566 | //unsigned int Size; |
| | 567 | 800, |
| | 568 | |
| | 569 | TRANSLUCENCY_GLOWING, |
| | 570 | |
| | 571 | //unsigned char Alpha; |
| | 572 | 255, |
| | 573 | //unsigned char RedScale; |
| | 574 | {255, 255, 255, 128, 128, 0}, |
| | 575 | //unsigned char GreenScale; |
| | 576 | {128, 128, 255, 64, 64, 128}, |
| | 577 | //unsigned char BlueScale; |
| | 578 | {64, 64, 255, 255, 0, 0}, |
| | 579 | |
| | 580 | //unsigned char IsLit:1; |
| | 581 | 0, |
| | 582 | //IsDrawnInFront:1; |
| | 583 | 0, |
| | 584 | //IsDrawnAtBack:1; |
| | 585 | 0, |
| | 586 | }, |
| | 587 | /* PARTICLE_MOLOTOVFLAME */ |
| | 588 | { |
| | 589 | //int StartU; |
| | 590 | 64<<16, |
| | 591 | //int StartV; |
| | 592 | 0<<16, |
| | 593 | //int EndU; |
| | 594 | (64+127)<<16, |
| | 595 | //int EndV; |
| | 596 | 63<<16, |
| | 597 | //unsigned int Size; |
| | 598 | 800, |
| | 599 | |
| | 600 | TRANSLUCENCY_GLOWING, |
| | 601 | |
| | 602 | //unsigned char Alpha; |
| | 603 | 255, |
| | 604 | //unsigned char RedScale; |
| | 605 | {255, 255, 255, 128, 128, 0}, |
| | 606 | //unsigned char GreenScale; |
| | 607 | {128, 128, 255, 64, 64, 128}, |
| | 608 | //unsigned char BlueScale; |
| | 609 | {64, 64, 255, 255, 0, 0}, |
| | 610 | |
| | 611 | //unsigned char IsLit:1; |
| | 612 | 0, |
| | 613 | //IsDrawnInFront:1; |
| | 614 | 0, |
| | 615 | //IsDrawnAtBack:1; |
| | 616 | 0, |
| | 617 | }, |
| | 618 | /* PARTICLE_SPARK */ |
| | 619 | { |
| | 620 | //int StartU; |
| | 621 | 1<<16, |
| | 622 | //int StartV; |
| | 623 | 1<<16, |
| | 624 | //int EndU; |
| | 625 | 64<<16, |
| | 626 | //int EndV; |
| | 627 | 64<<16, |
| | 628 | //unsigned int Size; |
| | 629 | 200/8, |
| | 630 | |
| | 631 | TRANSLUCENCY_GLOWING, |
| | 632 | |
| | 633 | //unsigned char Alpha; |
| | 634 | 64, |
| | 635 | //unsigned char RedScale; |
| | 636 | {255, 255, 255, 255, 255}, |
| | 637 | //unsigned char GreenScale; |
| | 638 | {128, 128, 255, 0, 255}, |
| | 639 | //unsigned char BlueScale; |
| | 640 | {64, 64, 255, 0, 0}, |
| | 641 | |
| | 642 | //unsigned char IsLit:1; |
| | 643 | 0, |
| | 644 | //IsDrawnInFront:1; |
| | 645 | 0, |
| | 646 | //IsDrawnAtBack:1; |
| | 647 | 0, |
| | 648 | }, |
| | 649 | /* PARTICLE_RICOCHET_SPARK */ |
| | 650 | { |
| | 651 | //int StartU; |
| | 652 | 1<<16, |
| | 653 | //int StartV; |
| | 654 | 1<<16, |
| | 655 | //int EndU; |
| | 656 | 64<<16, |
| | 657 | //int EndV; |
| | 658 | 64<<16, |
| | 659 | //unsigned int Size; |
| | 660 | 200/8, |
| | 661 | |
| | 662 | TRANSLUCENCY_GLOWING, |
| | 663 | |
| | 664 | //unsigned char Alpha; |
| | 665 | 64, |
| | 666 | //unsigned char RedScale; |
| | 667 | {255, 255, 255, 255, 255}, |
| | 668 | //unsigned char GreenScale; |
| | 669 | {128, 128, 255, 0, 255}, |
| | 670 | //unsigned char BlueScale; |
| | 671 | {64, 64, 255, 0, 255}, |
| | 672 | |
| | 673 | //unsigned char IsLit:1; |
| | 674 | 0, |
| | 675 | //IsDrawnInFront:1; |
| | 676 | 0, |
| | 677 | //IsDrawnAtBack:1; |
| | 678 | 0, |
| | 679 | }, |
| | 680 | /* PARTICLE_ORANGE_SPARK */ |
| | 681 | { |
| | 682 | //int StartU; |
| | 683 | 224<<16, |
| | 684 | //int StartV; |
| | 685 | 192<<16, |
| | 686 | //int EndU; |
| | 687 | 255<<16, |
| | 688 | //int EndV; |
| | 689 | 223<<16, |
| | 690 | //unsigned int Size; |
| | 691 | 50, |
| | 692 | |
| | 693 | TRANSLUCENCY_GLOWING, |
| | 694 | |
| | 695 | //unsigned char Alpha; |
| | 696 | 255, |
| | 697 | //unsigned char RedScale; |
| | 698 | {255, 64, 64, 64, 64}, |
| | 699 | //unsigned char GreenScale; |
| | 700 | {255, 64, 64, 64, 64}, |
| | 701 | //unsigned char BlueScale; |
| | 702 | {255, 64, 64, 64, 64}, |
| | 703 | |
| | 704 | //unsigned char IsLit:1; |
| | 705 | 0, |
| | 706 | //IsDrawnInFront:1; |
| | 707 | 0, |
| | 708 | //IsDrawnAtBack:1; |
| | 709 | 0, |
| | 710 | }, |
| | 711 | /* PARTICLE_ORANGE_PLASMA */ |
| | 712 | { |
| | 713 | //int StartU; |
| | 714 | 224<<16, |
| | 715 | //int StartV; |
| | 716 | 192<<16, |
| | 717 | //int EndU; |
| | 718 | 255<<16, |
| | 719 | //int EndV; |
| | 720 | 223<<16, |
| | 721 | //unsigned int Size; |
| | 722 | 50, |
| | 723 | |
| | 724 | TRANSLUCENCY_GLOWING, |
| | 725 | |
| | 726 | //unsigned char Alpha; |
| | 727 | 255, |
| | 728 | //unsigned char RedScale; |
| | 729 | {255, 64, 64, 64, 64, 0}, |
| | 730 | //unsigned char GreenScale; |
| | 731 | {255, 64, 64, 64, 64, 64}, |
| | 732 | //unsigned char BlueScale; |
| | 733 | {255, 64, 64, 64, 64, 0}, |
| | 734 | |
| | 735 | //unsigned char IsLit:1; |
| | 736 | 0, |
| | 737 | //IsDrawnInFront:1; |
| | 738 | 0, |
| | 739 | //IsDrawnAtBack:1; |
| | 740 | 0, |
| | 741 | }, |
| | 742 | |
| | 743 | /* PARTICLE_PLASMATRAIL */ |
| | 744 | { |
| | 745 | //int StartU; |
| | 746 | 64<<16, |
| | 747 | //int StartV; |
| | 748 | 64<<16, |
| | 749 | //int EndU; |
| | 750 | 127<<16, |
| | 751 | //int EndV; |
| | 752 | 127<<16, |
| | 753 | //unsigned int Size; |
| | 754 | 200/4, |
| | 755 | |
| | 756 | TRANSLUCENCY_GLOWING, |
| | 757 | |
| | 758 | //unsigned char Alpha; |
| | 759 | 64, |
| | 760 | //unsigned char RedScale; |
| | 761 | {255, 255, 255, 255, 255, 0}, |
| | 762 | //unsigned char GreenScale; |
| | 763 | {128, 128, 255, 0, 255, 255}, |
| | 764 | //unsigned char BlueScale; |
| | 765 | {64, 64, 255, 0, 0, 0}, |
| | 766 | |
| | 767 | //unsigned char IsLit:1; |
| | 768 | 0, |
| | 769 | //IsDrawnInFront:1; |
| | 770 | 0, |
| | 771 | //IsDrawnAtBack:1; |
| | 772 | 0, |
| | 773 | }, |
| | 774 | /* PARTICLE_LASERBEAM */ |
| | 775 | { |
| | 776 | //int StartU; |
| | 777 | 32<<16, |
| | 778 | //int StartV; |
| | 779 | 0<<16, |
| | 780 | //int EndU; |
| | 781 | 32<<16, |
| | 782 | //int EndV; |
| | 783 | 63<<16, |
| | 784 | //unsigned int Size; |
| | 785 | 50, |
| | 786 | |
| | 787 | TRANSLUCENCY_GLOWING, |
| | 788 | |
| | 789 | //unsigned char Alpha; |
| | 790 | 64, |
| | 791 | //unsigned char RedScale; |
| | 792 | {255, 255, 255, 255, 255, 0}, |
| | 793 | //unsigned char GreenScale; |
| | 794 | {128, 128, 255, 0, 255, 255}, |
| | 795 | //unsigned char BlueScale; |
| | 796 | {64, 64, 255, 0, 0, 0}, |
| | 797 | |
| | 798 | //unsigned char IsLit:1; |
| | 799 | 0, |
| | 800 | //IsDrawnInFront:1; |
| | 801 | 0, |
| | 802 | //IsDrawnAtBack:1; |
| | 803 | 0, |
| | 804 | }, |
| | 805 | /* PARTICLE_PLASMABEAM */ |
| | 806 | { |
| | 807 | //int StartU; |
| | 808 | 192<<16, |
| | 809 | //int StartV; |
| | 810 | 224<<16, |
| | 811 | //int EndU; |
| | 812 | 223<<16, |
| | 813 | //int EndV; |
| | 814 | 255<<16, |
| | 815 | //unsigned int Size; |
| | 816 | 50, |
| | 817 | |
| | 818 | TRANSLUCENCY_GLOWING, |
| | 819 | |
| | 820 | //unsigned char Alpha; |
| | 821 | 64, |
| | 822 | //unsigned char RedScale; |
| | 823 | {255, 255, 255, 255, 255, 0}, |
| | 824 | //unsigned char GreenScale; |
| | 825 | {128, 128, 255, 0, 255, 255}, |
| | 826 | //unsigned char BlueScale; |
| | 827 | {64, 64, 255, 0, 0, 0}, |
| | 828 | |
| | 829 | //unsigned char IsLit:1; |
| | 830 | 0, |
| | 831 | //IsDrawnInFront:1; |
| | 832 | 0, |
| | 833 | //IsDrawnAtBack:1; |
| | 834 | 0, |
| | 835 | }, |
| | 836 | /* PARTICLE_LIGHTFLARE */ |
| | 837 | { |
| | 838 | //int StartU; |
| | 839 | 64<<16, |
| | 840 | //int StartV; |
| | 841 | 64<<16, |
| | 842 | //int EndU; |
| | 843 | 127<<16, |
| | 844 | //int EndV; |
| | 845 | 127<<16, |
| | 846 | //unsigned int Size; |
| | 847 | 200, |
| | 848 | |
| | 849 | TRANSLUCENCY_GLOWING, |
| | 850 | |
| | 851 | //unsigned char Alpha; |
| | 852 | 255, |
| | 853 | //unsigned char RedScale; |
| | 854 | {255, 255, 255, 255, 255, 0}, |
| | 855 | //unsigned char GreenScale; |
| | 856 | {255, 255, 255, 0, 255, 255}, |
| | 857 | //unsigned char BlueScale; |
| | 858 | {255, 255, 255, 0, 0, 0}, |
| | 859 | |
| | 860 | //unsigned char IsLit:1; |
| | 861 | 0, |
| | 862 | //IsDrawnInFront:1; |
| | 863 | 1, |
| | 864 | //IsDrawnAtBack:1; |
| | 865 | 0, |
| | 866 | }, |
| | 867 | /* PARTICLE_STAR */ |
| | 868 | { |
| | 869 | //int StartU; |
| | 870 | 64<<16, |
| | 871 | //int StartV; |
| | 872 | 64<<16, |
| | 873 | //int EndU; |
| | 874 | 127<<16, |
| | 875 | //int EndV; |
| | 876 | 127<<16, |
| | 877 | //unsigned int Size; |
| | 878 | 200, |
| | 879 | |
| | 880 | TRANSLUCENCY_GLOWING, |
| | 881 | |
| | 882 | //unsigned char Alpha; |
| | 883 | 255, |
| | 884 | //unsigned char RedScale; |
| | 885 | {255, 255, 255, 255, 255, 0}, |
| | 886 | //unsigned char GreenScale; |
| | 887 | {255, 255, 255, 0, 255, 255}, |
| | 888 | //unsigned char BlueScale; |
| | 889 | {255, 255, 255, 0, 0, 0}, |
| | 890 | |
| | 891 | //unsigned char IsLit:1; |
| | 892 | 0, |
| | 893 | //IsDrawnInFront:1; |
| | 894 | 0, |
| | 895 | //IsDrawnAtBack:1; |
| | 896 | 1, |
| | 897 | }, |
| | 898 | /* PARTICLE_FLECHETTE */ |
| | 899 | { |
| | 900 | //int StartU; |
| | 901 | 64<<16, |
| | 902 | //int StartV; |
| | 903 | 64<<16, |
| | 904 | //int EndU; |
| | 905 | 127<<16, |
| | 906 | //int EndV; |
| | 907 | 127<<16, |
| | 908 | //unsigned int Size; |
| | 909 | 100, |
| | 910 | |
| | 911 | TRANSLUCENCY_NORMAL, |
| | 912 | |
| | 913 | //unsigned char Alpha; |
| | 914 | 255, |
| | 915 | //unsigned char RedScale; |
| | 916 | {255, 255, 255, 255, 255, 0}, |
| | 917 | //unsigned char GreenScale; |
| | 918 | {255, 255, 255, 0, 255, 255}, |
| | 919 | //unsigned char BlueScale; |
| | 920 | {255, 255, 255, 0, 0, 0}, |
| | 921 | |
| | 922 | //unsigned char IsLit:1; |
| | 923 | 0, |
| | 924 | //IsDrawnInFront:1; |
| | 925 | 0, |
| | 926 | //IsDrawnAtBack:1; |
| | 927 | 0, |
| | 928 | }, |
| | 929 | /* PARTICLE_SMOKECLOUD */ |
| | 930 | { |
| | 931 | //int StartU; |
| | 932 | 128<<16, |
| | 933 | //int StartV; |
| | 934 | 64<<16, |
| | 935 | //int EndU; |
| | 936 | 191<<16, |
| | 937 | //int EndV; |
| | 938 | 127<<16, |
| | 939 | //unsigned int Size; |
| | 940 | 1000, |
| | 941 | |
| | 942 | TRANSLUCENCY_GLOWING, |
| | 943 | |
| | 944 | //unsigned char Alpha; |
| | 945 | 255, |
| | 946 | //unsigned char RedScale; |
| | 947 | {128, 64, 64, 64, 0}, |
| | 948 | //unsigned char GreenScale; |
| | 949 | {128, 64, 64, 64, 64}, |
| | 950 | //unsigned char BlueScale; |
| | 951 | {128, 64, 64, 64, 0}, |
| | 952 | |
| | 953 | //unsigned char IsLit:1; |
| | 954 | 1, |
| | 955 | //IsDrawnInFront:1; |
| | 956 | 0, |
| | 957 | //IsDrawnAtBack:1; |
| | 958 | 0, |
| | 959 | }, |
| | 960 | /* PARTICLE_ELECTRICALPLASMASPHERE */ |
| | 961 | { |
| | 962 | //int StartU; |
| | 963 | 64<<16, |
| | 964 | //int StartV; |
| | 965 | 128<<16, |
| | 966 | //int EndU; |
| | 967 | 127<<16, |
| | 968 | //int EndV; |
| | 969 | 191<<16, |
| | 970 | //unsigned int Size; |
| | 971 | 2000, |
| | 972 | |
| | 973 | TRANSLUCENCY_GLOWING, |
| | 974 | |
| | 975 | //unsigned char Alpha; |
| | 976 | 255, |
| | 977 | //unsigned char RedScale; |
| | 978 | {255, 64, 64, 64, 64, 0}, |
| | 979 | //unsigned char GreenScale; |
| | 980 | {255, 64, 64, 64, 64, 255}, |
| | 981 | //unsigned char BlueScale; |
| | 982 | {255, 64, 64, 64, 0, 0}, |
| | 983 | |
| | 984 | //unsigned char IsLit:1; |
| | 985 | 0, |
| | 986 | //IsDrawnInFront:1; |
| | 987 | 0, |
| | 988 | //IsDrawnAtBack:1; |
| | 989 | 0, |
| | 990 | }, |
| | 991 | /* PARTICLE_FLECHETTE_NONDAMAGING */ |
| | 992 | { |
| | 993 | //int StartU; |
| | 994 | 64<<16, |
| | 995 | //int StartV; |
| | 996 | 64<<16, |
| | 997 | //int EndU; |
| | 998 | 127<<16, |
| | 999 | //int EndV; |
| | 1000 | 127<<16, |
| | 1001 | //unsigned int Size; |
| | 1002 | 100, |
| | 1003 | |
| | 1004 | TRANSLUCENCY_NORMAL, |
| | 1005 | |
| | 1006 | //unsigned char Alpha; |
| | 1007 | 255, |
| | 1008 | //unsigned char RedScale; |
| | 1009 | {255, 255, 255, 255, 255, 0}, |
| | 1010 | //unsigned char GreenScale; |
| | 1011 | {255, 255, 255, 0, 255, 255}, |
| | 1012 | //unsigned char BlueScale; |
| | 1013 | {255, 255, 255, 0, 0, 0}, |
| | 1014 | |
| | 1015 | //unsigned char IsLit:1; |
| | 1016 | 0, |
| | 1017 | //IsDrawnInFront:1; |
| | 1018 | 0, |
| | 1019 | //IsDrawnAtBack:1; |
| | 1020 | 0, |
| | 1021 | }, |
| | 1022 | /* PARTICLE_DEWLINE */ |
| | 1023 | { |
| | 1024 | //int StartU; |
| | 1025 | 64<<16, |
| | 1026 | //int StartV; |
| | 1027 | 64<<16, |
| | 1028 | //int EndU; |
| | 1029 | 127<<16, |
| | 1030 | //int EndV; |
| | 1031 | 127<<16, |
| | 1032 | //unsigned int Size; |
| | 1033 | 200/4, |
| | 1034 | |
| | 1035 | TRANSLUCENCY_GLOWING, |
| | 1036 | |
| | 1037 | //unsigned char Alpha; |
| | 1038 | 64, |
| | 1039 | //unsigned char RedScale; |
| | 1040 | {255, 255, 255, 255, 255, 0}, |
| | 1041 | //unsigned char GreenScale; |
| | 1042 | {128, 128, 255, 0, 255, 255}, |
| | 1043 | //unsigned char BlueScale; |
| | 1044 | {64, 64, 255, 0, 0, 0}, |
| | 1045 | |
| | 1046 | //unsigned char IsLit:1; |
| | 1047 | 0, |
| | 1048 | //IsDrawnInFront:1; |
| | 1049 | 0, |
| | 1050 | //IsDrawnAtBack:1; |
| | 1051 | 0, |
| | 1052 | } |
| | 1053 | }; |
| | 1054 | |
| | 1055 | #define MAX_NO_OF_RIPPLES 100 |
| | 1056 | #define MAX_RAINDROPS 1000 |
| | 1057 | |
| | 1058 | static struct |
| | 1059 | { |
| | 1060 | int Active; |
| | 1061 | int X; |
| | 1062 | int Z; |
| | 1063 | int Amplitude; |
| | 1064 | int Radius; |
| | 1065 | int InvRadius; |
| | 1066 | |
| | 1067 | } RippleStorage[MAX_NO_OF_RIPPLES]; |
| | 1068 | |
| | 1069 | static PARTICLE RainDropStorage[MAX_RAINDROPS]; |
| | 1070 | int ActiveRippleNumber; |
| | 1071 | |
| | 1072 | static void InitialiseRainDrops() |
| | 1073 | { |
| | 1074 | int i = MAX_RAINDROPS; |
| | 1075 | ActiveRippleNumber = 0; |
| | 1076 | |
| | 1077 | for(i=0; i < MAX_RAINDROPS; ++i) |
| | 1078 | { |
| | 1079 | PARTICLE *particlePtr = &RainDropStorage[i]; |
| | 1080 | particlePtr->Position.vy = 0x7fffffff; |
| | 1081 | particlePtr->LifeTime = 0; |
| | 1082 | } |
| | 1083 | |
| | 1084 | i = MAX_NO_OF_RIPPLES; |
| | 1085 | |
| | 1086 | for(i=0; i < MAX_NO_OF_RIPPLES; ++i) |
| | 1087 | RippleStorage[i].Active = 0; |
| | 1088 | } |
| | 1089 | |
| | 1090 | void InitialiseParticleSystem() |
| | 1091 | { |
| | 1092 | NumActiveParticles = NumberOfBloodParticles = NumActiveTrails = CurrentExplosionIndex = 0; |
| | 1093 | |
| | 1094 | InitialiseRainDrops(); |
| | 1095 | } |
| | 1096 | |
| | 1097 | static PHEROMONE_TRAIL* AllocatePheromoneTrail() |
| | 1098 | { |
| | 1099 | return (NumActiveTrails < MAX_NO_OF_PHEROMONE_TRAILS) ? &TrailStorage[NumActiveTrails++] : NULL; |
| | 1100 | } |
| | 1101 | |
| | 1102 | static struct VOLUMETRIC_EXPLOSION* AllocateVolumetricExplosion() |
| | 1103 | { |
| | 1104 | if (CurrentExplosionIndex >= MAX_NO_OF_EXPLOSIONS) |
| | 1105 | CurrentExplosionIndex = 0; |
| | 1106 | |
| | 1107 | active_volumetric_explosion[CurrentExplosionIndex] = &ExplosionStorage[CurrentExplosionIndex]; |
| | 1108 | |
| | 1109 | return &ExplosionStorage[CurrentExplosionIndex++]; |
| | 1110 | } |
| | 1111 | |
| | 1112 | void MakeBloodParticle(VECTORCH *positionPtr, VECTORCH *velocityPtr, enum PARTICLE_ID particleID) |
| | 1113 | { |
| | 1114 | if (NumberOfBloodParticles < UserProfile.GameOptions.BloodParticles) |
| | 1115 | { |
| | 1116 | PARTICLE *particlePtr = &BloodParticleStorage[NumberOfBloodParticles]; |
| | 1117 | const PARTICLE_DESC *particleDescPtr = &ParticleDescription[particleID]; |
| | 1118 | particlePtr->Position = *positionPtr; |
| | 1119 | particlePtr->Velocity = *velocityPtr; |
| | 1120 | particlePtr->ParticleID = particleID; |
| | 1121 | particlePtr->Colour = RGBA_MAKE (particleDescPtr->RedScale[PlayerStatus.VisionMode], |
| | 1122 | particleDescPtr->GreenScale[PlayerStatus.VisionMode], |
| | 1123 | particleDescPtr->BlueScale[PlayerStatus.VisionMode], |
| | 1124 | particleDescPtr->Alpha); |
| | 1125 | |
| | 1126 | particlePtr->Size = particleDescPtr->Size; |
| | 1127 | |
| | 1128 | switch(particlePtr->ParticleID) |
| | 1129 | { |
| | 1130 | case PARTICLE_ALIEN_BLOOD: |
| | 1131 | case PARTICLE_HUMAN_BLOOD: |
| | 1132 | case PARTICLE_PREDATOR_BLOOD: |
| | 1133 | case PARTICLE_ANDROID_BLOOD: |
| | 1134 | particlePtr->Offset = particlePtr->Position; |
| | 1135 | particlePtr->LifeTime = ONE_FIXED * 4; |
| | 1136 | break; |
| | 1137 | case PARTICLE_SPARK: |
| | 1138 | particlePtr->LifeTime = ONE_FIXED; |
| | 1139 | default: |
| | 1140 | return; |
| | 1141 | } |
| | 1142 | |
| | 1143 | NumberOfBloodParticles++; |
| | 1144 | } |
| | 1145 | } |
| | 1146 | |
| | 1147 | void MakeParticle(const VECTORCH *positionPtr, const VECTORCH *velocityPtr, enum PARTICLE_ID particleID) |
| | 1148 | { |
| | 1149 | if (NumActiveParticles < UserProfile.GameOptions.NoneBloodParticles) |
| | 1150 | { |
| | 1151 | PARTICLE *particlePtr = &ParticleStorage[NumActiveParticles]; |
| | 1152 | |
| | 1153 | const PARTICLE_DESC *particleDescPtr = &ParticleDescription[particleID]; |
| | 1154 | particlePtr->Position = *positionPtr; |
| | 1155 | particlePtr->Velocity = *velocityPtr; |
| | 1156 | particlePtr->ParticleID = particleID; |
| | 1157 | particlePtr->Colour = RGBA_MAKE ( particleDescPtr->RedScale[PlayerStatus.VisionMode], |
| | 1158 | particleDescPtr->GreenScale[PlayerStatus.VisionMode], |
| | 1159 | particleDescPtr->BlueScale[PlayerStatus.VisionMode], |
| | 1160 | particleDescPtr->Alpha); |
| | 1161 | |
| | 1162 | particlePtr->Size = particleDescPtr->Size; |
| | 1163 | |
| | 1164 | switch(particlePtr->ParticleID) |
| | 1165 | { |
| | 1166 | case PARTICLE_BLACKSMOKE: |
| | 1167 | particlePtr->LifeTime = ONE_FIXED + (FastRandom() & 32767); |
| | 1168 | particlePtr->Offset.vx = ((FastRandom()&1023) - 512) * 2; |
| | 1169 | particlePtr->Offset.vz = ((FastRandom()&1023) - 512) * 2; |
| | 1170 | break; |
| | 1171 | case PARTICLE_FLARESMOKE: |
| | 1172 | case PARTICLE_STEAM: |
| | 1173 | particlePtr->LifeTime = (ONE_FIXED) /2 + (FastRandom() & 32767); |
| | 1174 | particlePtr->Offset.vx = ((FastRandom() & 8191) - 4096); |
| | 1175 | particlePtr->Offset.vz = ((FastRandom() & 8191) - 4096); |
| | 1176 | break; |
| | 1177 | case PARTICLE_IMPACTSMOKE: |
| | 1178 | particlePtr->LifeTime = ONE_FIXED + (FastRandom() & 32767); |
| | 1179 | particlePtr->Offset.vx = ((FastRandom() & 1023) - 512)*2; |
| | 1180 | particlePtr->Offset.vz = ((FastRandom() & 1023) - 512)*2; |
| | 1181 | break; |
| | 1182 | case PARTICLE_GUNMUZZLE_SMOKE: |
| | 1183 | particlePtr->LifeTime = ONE_FIXED/2 + (FastRandom() & 32767); |
| | 1184 | particlePtr->Offset.vx = ((FastRandom() & 1023) - 512); |
| | 1185 | particlePtr->Offset.vz = ((FastRandom() & 1023) - 512); |
| | 1186 | break; |
| | 1187 | case PARTICLE_SPARK: |
| | 1188 | particlePtr->LifeTime = ONE_FIXED; |
| | 1189 | break; |
| | 1190 | case PARTICLE_RICOCHET_SPARK: |
| | 1191 | case PARTICLE_ORANGE_SPARK: |
| | 1192 | particlePtr->LifeTime = ONE_FIXED/4; |
| | 1193 | break; |
| | 1194 | case PARTICLE_FLAME: |
| | 1195 | case PARTICLE_NONCOLLIDINGFLAME: |
| | 1196 | case PARTICLE_NONDAMAGINGFLAME: |
| | 1197 | particlePtr->Offset.vx = (FastRandom() & 4095); |
| | 1198 | particlePtr->Offset.vy = ((FastRandom() & 32767) - 16384); |
| | 1199 | particlePtr->LifeTime = ONE_FIXED/2; |
| | 1200 | break; |
| | 1201 | case PARTICLE_FIRE: |
| | 1202 | particlePtr->LifeTime = ONE_FIXED/2 + (FastRandom() & 16383); |
| | 1203 | break; |
| | 1204 | case PARTICLE_MOLOTOVFLAME: |
| | 1205 | particlePtr->LifeTime = ONE_FIXED*2 - (FastRandom() & 32767); |
| | 1206 | break; |
| | 1207 | case PARTICLE_FLECHETTE: |
| | 1208 | case PARTICLE_FLECHETTE_NONDAMAGING: |
| | 1209 | particlePtr->LifeTime = ONE_FIXED * 8; |
| | 1210 | particlePtr->Offset.vy = 1; |
| | 1211 | break; |
| | 1212 | case PARTICLE_SMOKECLOUD: |
| | 1213 | particlePtr->LifeTime = ONE_FIXED*16-1; |
| | 1214 | particlePtr->Offset.vx = (FastRandom() & 4095); |
| | 1215 | particlePtr->Offset.vy = ((FastRandom() & 16383) - 8192); |
| | 1216 | break; |
| | 1217 | case PARTICLE_ELECTRICALPLASMASPHERE: |
| | 1218 | particlePtr->LifeTime = 32767; |
| | 1219 | break; |
| | 1220 | case PARTICLE_ORANGE_PLASMA: |
| | 1221 | particlePtr->LifeTime = ONE_FIXED/8; |
| | 1222 | break; |
| | 1223 | case PARTICLE_PLASMATRAIL: |
| | 1224 | case PARTICLE_DEWLINE: |
| | 1225 | particlePtr->LifeTime = ONE_FIXED; |
| | 1226 | particlePtr->Offset = particlePtr->Position; |
| | 1227 | break; |
| | 1228 | case PARTICLE_WATERSPRAY: |
| | 1229 | particlePtr->LifeTime = ONE_FIXED/2; |
| | 1230 | break; |
| | 1231 | case PARTICLE_WATERFALLSPRAY: |
| | 1232 | particlePtr->LifeTime = ONE_FIXED*10; |
| | 1233 | break; |
| | 1234 | default: |
| | 1235 | { |
| | 1236 | assert(0); |
| | 1237 | return; |
| | 1238 | } |
| | 1239 | } |
| | 1240 | |
| | 1241 | NumActiveParticles++; |
| | 1242 | } |
| | 1243 | } |
| | 1244 | |
| | 1245 | static void DoFlareCorona(DISPLAYBLOCK *objectPtr) |
| | 1246 | { |
| | 1247 | if(IsThisObjectVisibleFromThisPosition_WithIgnore(objectPtr, PlayerStatus.DisplayBlock, &Global_VDB.VDB_World)) |
| | 1248 | { |
| | 1249 | LIGHTBLOCK *lPtr = objectPtr->ObLights[0]; |
| | 1250 | int a = lPtr->LightBright >> 8; |
| | 1251 | int colour; |
| | 1252 | |
| | 1253 | if (a > 255) |
| | 1254 | a = 255; |
| | 1255 | |
| | 1256 | switch (PlayerStatus.VisionMode) |
| | 1257 | { |
| | 1258 | case VISION_MODE_NORMAL: |
| | 1259 | default: |
| | 1260 | colour = 0xffc8ff + (a<<24); |
| | 1261 | break; |
| | 1262 | case VISION_MODE_IMAGEINTENSIFIER: |
| | 1263 | colour = 0xffffffff; |
| | 1264 | break; |
| | 1265 | case VISION_MODE_PRED_THERMAL: |
| | 1266 | case VISION_MODE_PRED_SEEALIENS: |
| | 1267 | case VISION_MODE_PRED_SEEPREDTECH: |
| | 1268 | { |
| | 1269 | int b = MUL_FIXED(lPtr->RedScale + lPtr->GreenScale + lPtr->BlueScale, lPtr->LightBright) >> 10; |
| | 1270 | |
| | 1271 | if (b > 255) |
| | 1272 | b = 255; |
| | 1273 | |
| | 1274 | colour = 0xff000000 + (b << 16) + ((b >> 1) << 8); |
| | 1275 | } |
| | 1276 | } |
| | 1277 | |
| | 1278 | RenderLightFlare(&objectPtr->ObWorld, colour); |
| | 1279 | } |
| | 1280 | } |
| | 1281 | |
| | 1282 | static void HandleRipples() |
| | 1283 | { |
| | 1284 | int i; |
| | 1285 | |
| | 1286 | for(i=0; i < MAX_NO_OF_RIPPLES; i++) |
| | 1287 | { |
| | 1288 | if (RippleStorage[i].Active) |
| | 1289 | { |
| | 1290 | RippleStorage[i].Radius += MUL_FIXED(2400, NormalFrameTime); |
| | 1291 | RippleStorage[i].InvRadius = DIV_FIXED(4090, RippleStorage[i].Radius); |
| | 1292 | RippleStorage[i].Amplitude -= MUL_FIXED(50, NormalFrameTime); |
| | 1293 | |
| | 1294 | if (RippleStorage[i].Amplitude < 0) |
| | 1295 | RippleStorage[i].Active = 0; |
| | 1296 | } |
| | 1297 | } |
| | 1298 | } |
| | 1299 | |
| | 1300 | static void HandleVolumetricExplosion() |
| | 1301 | { |
| | 1302 | int x; |
| | 1303 | for (x = 0; x < CurrentExplosionIndex;) |
| | 1304 | { |
| | 1305 | struct VOLUMETRIC_EXPLOSION *expPtr = active_volumetric_explosion[x]; |
| | 1306 | RenderExplosionSurface(expPtr); |
| | 1307 | |
| | 1308 | int i, v_temp = DIV_FIXED(SPHERE_VERTICES, expPtr->NumberVerticesMoving+1) + ONE_FIXED; |
| | 1309 | int velocityModifier = MUL_FIXED(GetSin(expPtr->LifeTime/64)/16, v_temp); |
| | 1310 | PARTICLE particle; |
| | 1311 | particle.ParticleID = PARTICLE_EXPLOSIONFIRE; |
| | 1312 | |
| | 1313 | for(i=0; i < SPHERE_VERTICES; i++) |
| | 1314 | { |
| | 1315 | if (expPtr->Velocity[i].vx || expPtr->Velocity[i].vy || expPtr->Velocity[i].vz) |
| | 1316 | { |
| | 1317 | particle.Velocity = expPtr->Velocity[i]; |
| | 1318 | int v = GetSin((CloakingPhase*4+expPtr->RipplePhase[i]) & 4095) / 4; |
| | 1319 | v = velocityModifier + MUL_FIXED(v, velocityModifier); |
| | 1320 | particle.Velocity.vx = MUL_FIXED(particle.Velocity.vx, v); |
| | 1321 | particle.Velocity.vy = MUL_FIXED(particle.Velocity.vy, v); |
| | 1322 | particle.Velocity.vz = MUL_FIXED(particle.Velocity.vz, v); |
| | 1323 | particle.Position = expPtr->Position[i]; |
| | 1324 | |
| | 1325 | if(expPtr->UseCollisions) |
| | 1326 | { |
| | 1327 | VECTORCH obstacleNormal; |
| | 1328 | int moduleIndex; |
| | 1329 | |
| | 1330 | if(ParticleDynamics(&particle, &obstacleNormal, &moduleIndex)) |
| | 1331 | { |
| | 1332 | if(-1 != moduleIndex) // make explosion deformable against none modules? |
| | 1333 | { |
| | 1334 | /* |
| | 1335 | int magOfPerpImp = DotProduct(&obstacleNormal, &expPtr->Velocity[i]); |
| | 1336 | expPtr->Velocity[i].vx -= MUL_FIXED(obstacleNormal.vx, magOfPerpImp); |
| | 1337 | expPtr->Velocity[i].vy -= MUL_FIXED(obstacleNormal.vy, magOfPerpImp); |
| | 1338 | expPtr->Velocity[i].vz -= MUL_FIXED(obstacleNormal.vz, magOfPerpImp); |
| | 1339 | */ |
| | 1340 | expPtr->Velocity[i] = particle.Velocity; |
| | 1341 | |
| | 1342 | if(!expPtr->BeenStopped[i]) |
| | 1343 | { |
| | 1344 | expPtr->BeenStopped[i] = 1; |
| | 1345 | expPtr->NumberVerticesMoving--; |
| | 1346 | MakeDecal(DECAL_SCORCHED, &obstacleNormal, &particle.Position, moduleIndex); |
| | 1347 | } |
| | 1348 | } |
| | 1349 | } |
| | 1350 | } |
| | 1351 | else |
| | 1352 | { |
| | 1353 | particle.Position.vx += MUL_FIXED(particle.Velocity.vx, NormalFrameTime); |
| | 1354 | particle.Position.vy += MUL_FIXED(particle.Velocity.vy, NormalFrameTime); |
| | 1355 | particle.Position.vz += MUL_FIXED(particle.Velocity.vz, NormalFrameTime); |
| | 1356 | } |
| | 1357 | |
| | 1358 | expPtr->Position[i] = particle.Position; |
| | 1359 | } |
| | 1360 | } |
| | 1361 | |
| | 1362 | expPtr->LifeTime -= NormalFrameTime; |
| | 1363 | |
| | 1364 | if (expPtr->LifeTime <= 0) |
| | 1365 | { |
| | 1366 | if(--CurrentExplosionIndex) |
| | 1367 | { |
| | 1368 | active_volumetric_explosion[x] = active_volumetric_explosion[CurrentExplosionIndex]; |
| | 1369 | continue; |
| | 1370 | } |
| | 1371 | else |
| | 1372 | { |
| | 1373 | return; |
| | 1374 | } |
| | 1375 | } |
| | 1376 | x++; |
| | 1377 | } |
| | 1378 | } |
| | 1379 | |
| | 1380 | static void DrawXenoborgMainLaserbeam(LASER_BEAM_DESC *laserPtr) |
| | 1381 | { |
| | 1382 | if (laserPtr->BeamHasHitPlayer) |
| | 1383 | { |
| | 1384 | int colour; |
| | 1385 | switch (PlayerStatus.VisionMode) |
| | 1386 | { |
| | 1387 | default: |
| | 1388 | case VISION_MODE_NORMAL: |
| | 1389 | colour = 0xff0000ff; |
| | 1390 | break; |
| | 1391 | case VISION_MODE_IMAGEINTENSIFIER: |
| | 1392 | colour = 0xffffffff; |
| | 1393 | break; |
| | 1394 | case VISION_MODE_PRED_THERMAL: |
| | 1395 | case VISION_MODE_PRED_SEEALIENS: |
| | 1396 | case VISION_MODE_PRED_SEEPREDTECH: |
| | 1397 | colour = 0xffff8000; |
| | 1398 | } |
| | 1399 | |
| | 1400 | RenderLightFlare(&laserPtr->SourcePosition, colour); |
| | 1401 | RenderLightFlare(&laserPtr->SourcePosition, 0xffffffff); |
| | 1402 | } |
| | 1403 | else |
| | 1404 | { |
| | 1405 | PARTICLE particle; |
| | 1406 | switch (PlayerStatus.VisionMode) |
| | 1407 | { |
| | 1408 | default: |
| | 1409 | case VISION_MODE_NORMAL: |
| | 1410 | particle.Colour = RGBA_MAKE(0,0,255,255); |
| | 1411 | break; |
| | 1412 | case VISION_MODE_IMAGEINTENSIFIER: |
| | 1413 | particle.Colour = RGBA_MAKE(255,255,255,255); |
| | 1414 | break; |
| | 1415 | case VISION_MODE_PRED_THERMAL: |
| | 1416 | case VISION_MODE_PRED_SEEALIENS: |
| | 1417 | case VISION_MODE_PRED_SEEPREDTECH: |
| | 1418 | particle.Colour = RGBA_MAKE(255,128,0,255); |
| | 1419 | } |
| | 1420 | particle.Colour = RGBA_MAKE(255,255,255,255); |
| | 1421 | particle.ParticleID = PARTICLE_PLASMABEAM; |
| | 1422 | particle.Position = laserPtr->SourcePosition; |
| | 1423 | particle.Offset = laserPtr->TargetPosition; |
| | 1424 | particle.Size = 32; |
| | 1425 | RenderParticle(&particle); |
| | 1426 | // particle.Colour = RGBA_MAKE(255,255,255,255); |
| | 1427 | // particle.Size = 20; |
| | 1428 | // RenderParticle(&particle); |
| | 1429 | } |
| | 1430 | } |
| | 1431 | |
| | 1432 | #include "frustum.h" |
| | 1433 | static void RenderTrailSegment(PHEROMONE_TRAIL *trailPtr) |
| | 1434 | { |
| | 1435 | POLYHEADER fakeHeader; |
| | 1436 | VECTORCH temp; |
| | 1437 | int Uoffset = GetCos(CloakingPhase & 4095) * 128; |
| | 1438 | int Voffset = GetSin(CloakingPhase & 4095) * 128; |
| | 1439 | |
| | 1440 | temp.vx = trailPtr->Vertex[0].vx - MUL_FIXED(trailPtr->Perp[0].vx, trailPtr->Size[0]/65536); |
| | 1441 | temp.vy = trailPtr->Vertex[0].vy - MUL_FIXED(trailPtr->Perp[0].vy, trailPtr->Size[0]/65536); |
| | 1442 | temp.vz = trailPtr->Vertex[0].vz - MUL_FIXED(trailPtr->Perp[0].vz, trailPtr->Size[0]/65536); |
| | 1443 | VerticesBuffer[0].U = (temp.vx+temp.vz)*8192+Uoffset; |
| | 1444 | VerticesBuffer[0].V = (temp.vy+temp.vz)*8192+Voffset; |
| | 1445 | TranslatePointIntoViewspace(&temp); |
| | 1446 | VerticesBuffer[0].X = temp.vx; |
| | 1447 | VerticesBuffer[0].Y = temp.vy; |
| | 1448 | VerticesBuffer[0].Z = temp.vz; |
| | 1449 | // VerticesBuffer[0].U = ParticleDescription[PARTICLE_PLASMABEAM].StartU/2; |
| | 1450 | // VerticesBuffer[0].V = ParticleDescription[PARTICLE_PLASMABEAM].StartV/2; |
| | 1451 | |
| | 1452 | temp.vx = trailPtr->Vertex[0].vx + MUL_FIXED(trailPtr->Perp[0].vx,trailPtr->Size[0]/65536); |
| | 1453 | temp.vy = trailPtr->Vertex[0].vy + MUL_FIXED(trailPtr->Perp[0].vy,trailPtr->Size[0]/65536); |
| | 1454 | temp.vz = trailPtr->Vertex[0].vz + MUL_FIXED(trailPtr->Perp[0].vz,trailPtr->Size[0]/65536); |
| | 1455 | VerticesBuffer[1].U = (temp.vx+temp.vz)*8192+Uoffset; |
| | 1456 | VerticesBuffer[1].V = (temp.vy+temp.vz)*8192+Voffset; |
| | 1457 | TranslatePointIntoViewspace(&temp); |
| | 1458 | VerticesBuffer[1].X = temp.vx; |
| | 1459 | VerticesBuffer[1].Y = temp.vy; |
| | 1460 | VerticesBuffer[1].Z = temp.vz; |
| | 1461 | // VerticesBuffer[1].U = ParticleDescription[PARTICLE_PLASMABEAM].StartU/2; |
| | 1462 | // VerticesBuffer[1].V = ParticleDescription[PARTICLE_PLASMABEAM].EndV/2; |
| | 1463 | |
| | 1464 | temp.vx = trailPtr->Vertex[1].vx + MUL_FIXED(trailPtr->Perp[1].vx,trailPtr->Size[1]/65536); |
| | 1465 | temp.vy = trailPtr->Vertex[1].vy + MUL_FIXED(trailPtr->Perp[1].vy,trailPtr->Size[1]/65536); |
| | 1466 | temp.vz = trailPtr->Vertex[1].vz + MUL_FIXED(trailPtr->Perp[1].vz,trailPtr->Size[1]/65536); |
| | 1467 | VerticesBuffer[2].U = (temp.vx+temp.vz)*8192+Uoffset; |
| | 1468 | VerticesBuffer[2].V = (temp.vy+temp.vz)*8192+Voffset; |
| | 1469 | TranslatePointIntoViewspace(&temp); |
| | 1470 | VerticesBuffer[2].X = temp.vx; |
| | 1471 | VerticesBuffer[2].Y = temp.vy; |
| | 1472 | VerticesBuffer[2].Z = temp.vz; |
| | 1473 | // VerticesBuffer[2].U = ParticleDescription[PARTICLE_PLASMABEAM].EndU/2; |
| | 1474 | // VerticesBuffer[2].V = ParticleDescription[PARTICLE_PLASMABEAM].EndV/2; |
| | 1475 | |
| | 1476 | temp.vx = trailPtr->Vertex[1].vx - MUL_FIXED(trailPtr->Perp[1].vx, trailPtr->Size[1]/65536); |
| | 1477 | temp.vy = trailPtr->Vertex[1].vy - MUL_FIXED(trailPtr->Perp[1].vy, trailPtr->Size[1]/65536); |
| | 1478 | temp.vz = trailPtr->Vertex[1].vz - MUL_FIXED(trailPtr->Perp[1].vz, trailPtr->Size[1]/65536); |
| | 1479 | VerticesBuffer[3].U = (temp.vx+temp.vz)*8192+Uoffset; |
| | 1480 | VerticesBuffer[3].V = (temp.vy+temp.vz)*8192+Voffset; |
| | 1481 | TranslatePointIntoViewspace(&temp); |
| | 1482 | VerticesBuffer[3].X = temp.vx; |
| | 1483 | VerticesBuffer[3].Y = temp.vy; |
| | 1484 | VerticesBuffer[3].Z = temp.vz; |
| | 1485 | // VerticesBuffer[3].U = ParticleDescription[PARTICLE_PLASMABEAM].EndU/2; |
| | 1486 | // VerticesBuffer[3].V = ParticleDescription[PARTICLE_PLASMABEAM].StartV/2; |
| | 1487 | |
| | 1488 | { |
| | 1489 | extern int SpecialFXImageNumber; |
| | 1490 | extern int CloudyImageNumber; |
| | 1491 | fakeHeader.PolyFlags = iflag_transparent; |
| | 1492 | fakeHeader.PolyColour = SpecialFXImageNumber; |
| | 1493 | fakeHeader.PolyColour = CloudyImageNumber; |
| | 1494 | } |
| | 1495 | |
| | 1496 | RenderPolygon.TranslucencyMode = TRANSLUCENCY_GLOWING; |
| | 1497 | |
| | 1498 | { |
| | 1499 | int i = 0; |
| | 1500 | for (; i < 4; i++) |
| | 1501 | { |
| | 1502 | VerticesBuffer[i].A = trailPtr->Size[i/2]/65536; |
| | 1503 | |
| | 1504 | VerticesBuffer[i].R = 255; |
| | 1505 | VerticesBuffer[i].G = 255; |
| | 1506 | VerticesBuffer[i].B = 255; |
| | 1507 | VerticesBuffer[i].SpecularR = 0; |
| | 1508 | VerticesBuffer[i].SpecularG = 0; |
| | 1509 | VerticesBuffer[i].SpecularB = 0; |
| | 1510 | |
| | 1511 | } |
| | 1512 | |
| | 1513 | RenderPolygon.NumberOfVertices = 4; |
| | 1514 | } |
| | 1515 | |
| | 1516 | GouraudTexturedPolygon_ClipWithZ(); |
| | 1517 | |
| | 1518 | if(RenderPolygon.NumberOfVertices < 3) |
| | 1519 | return; |
| | 1520 | |
| | 1521 | GouraudTexturedPolygon_ClipWithNegativeX(); |
| | 1522 | |
| | 1523 | if(RenderPolygon.NumberOfVertices < 3) |
| | 1524 | return; |
| | 1525 | |
| | 1526 | GouraudTexturedPolygon_ClipWithPositiveY(); |
| | 1527 | |
| | 1528 | if(RenderPolygon.NumberOfVertices < 3) |
| | 1529 | return; |
| | 1530 | |
| | 1531 | GouraudTexturedPolygon_ClipWithNegativeY(); |
| | 1532 | |
| | 1533 | if(RenderPolygon.NumberOfVertices < 3) |
| | 1534 | return; |
| | 1535 | |
| | 1536 | GouraudTexturedPolygon_ClipWithPositiveX(); |
| | 1537 | |
| | 1538 | if(RenderPolygon.NumberOfVertices < 3) |
| | 1539 | return; |
| | 1540 | |
| | 1541 | ZBufferedGouraudTexturedPolygon_Output(&fakeHeader, RenderPolygon.Vertices); |
| | 1542 | } |
| | 1543 | |
| | 1544 | static void HandlePheromoneTrails() |
| | 1545 | { |
| | 1546 | int i = NumActiveTrails; |
| | 1547 | PHEROMONE_TRAIL *trailPtr = TrailStorage; |
| | 1548 | int decayDelta = MUL_FIXED(TRAIL_DECAY_SPEED, NormalFrameTime); |
| | 1549 | //printf("Pheromone Segments active:%d\n", NumActiveTrails); |
| | 1550 | |
| | 1551 | while(i) |
| | 1552 | { |
| | 1553 | --i; |
| | 1554 | trailPtr->Size[0] -= decayDelta; |
| | 1555 | trailPtr->Size[1] -= decayDelta; |
| | 1556 | |
| | 1557 | if (trailPtr->Size[1] < 0) |
| | 1558 | trailPtr->Size[1] = 0; |
| | 1559 | |
| | 1560 | if (trailPtr->Size[0] < 0) |
| | 1561 | { |
| | 1562 | *trailPtr = TrailStorage[--NumActiveTrails]; |
| | 1563 | } |
| | 1564 | else |
| | 1565 | { |
| | 1566 | RenderTrailSegment(trailPtr); |
| | 1567 | trailPtr++; |
| | 1568 | } |
| | 1569 | } |
| | 1570 | } |
| | 1571 | |
| | 1572 | void DrawMuzzleFlash(VECTORCH *positionPtr, VECTORCH *directionPtr, enum MUZZLE_FLASH_ID muzzleFlashID) |
| | 1573 | { |
| | 1574 | int i; |
| | 1575 | const PARTICLE_DESC *particleDescPtr = &ParticleDescription[PARTICLE_MUZZLEFLASH]; |
| | 1576 | PARTICLE particle; |
| | 1577 | particle.ParticleID = PARTICLE_MUZZLEFLASH; |
| | 1578 | particle.Position = *positionPtr; |
| | 1579 | particle.Size = particleDescPtr->Size; |
| | 1580 | DecalSystem_Setup(); |
| | 1581 | |
| | 1582 | particle.Colour = |
| | 1583 | RGBA_MAKE(particleDescPtr->RedScale[PlayerStatus.VisionMode], |
| | 1584 | particleDescPtr->GreenScale[PlayerStatus.VisionMode], |
| | 1585 | particleDescPtr->BlueScale[PlayerStatus.VisionMode], |
| | 1586 | particleDescPtr->Alpha); |
| | 1587 | |
| | 1588 | switch (muzzleFlashID) |
| | 1589 | { |
| | 1590 | case MUZZLE_FLASH_AMORPHOUS: |
| | 1591 | { |
| | 1592 | RenderParticle(&particle); |
| | 1593 | /* |
| | 1594 | particle.Position.vx += MUL_FIXED(100, directionPtr->vx); |
| | 1595 | particle.Position.vy += MUL_FIXED(100, directionPtr->vy); |
| | 1596 | particle.Position.vz += MUL_FIXED(100, directionPtr->vz); |
| | 1597 | RenderParticle(&particle); |
| | 1598 | */ |
| | 1599 | |
| | 1600 | /* |
| | 1601 | particle.Position.vx += MUL_FIXED(100, directionPtr->vx); |
| | 1602 | particle.Position.vy += MUL_FIXED(100, directionPtr->vy); |
| | 1603 | particle.Position.vz += MUL_FIXED(100, directionPtr->vz); |
| | 1604 | RenderParticle(&particle); |
| | 1605 | */ |
| | 1606 | |
| | 1607 | /* |
| | 1608 | particle.Size = 20; |
| | 1609 | |
| | 1610 | for (i=0; i < 16; i++) |
| | 1611 | { |
| | 1612 | RenderParticle(&particle); |
| | 1613 | particle.Position.vx = positionPtr->vx + MUL_FIXED(100, directionPtr->vx) + (FastRandom()&127)-64; |
| | 1614 | particle.Position.vy = positionPtr->vy + MUL_FIXED(100, directionPtr->vy) + (FastRandom()&127)-64; |
| | 1615 | particle.Position.vz = positionPtr->vz + MUL_FIXED(100, directionPtr->vz) + (FastRandom()&127)-64; |
| | 1616 | } |
| | 1617 | */ |
| | 1618 | } |
| | 1619 | break; |
| | 1620 | case MUZZLE_FLASH_SMARTGUN: |
| | 1621 | { |
| | 1622 | MATRIXCH muzzleMatrix; |
| | 1623 | MATRIXCH rotmat; |
| | 1624 | MakeMatrixFromDirection(directionPtr, &muzzleMatrix); |
| | 1625 | |
| | 1626 | { |
| | 1627 | int angle = 4096/12; |
| | 1628 | int cos = GetCos(angle); |
| | 1629 | int sin = GetSin(angle); |
| | 1630 | rotmat.mat11 = cos; |
| | 1631 | rotmat.mat12 = sin; |
| | 1632 | rotmat.mat13 = 0; |
| | 1633 | rotmat.mat21 = -sin; |
| | 1634 | rotmat.mat22 = cos; |
| | 1635 | rotmat.mat23 = 0; |
| | 1636 | rotmat.mat31 = 0; |
| | 1637 | rotmat.mat32 = 0; |
| | 1638 | rotmat.mat33 = 65536; |
| | 1639 | } |
| | 1640 | |
| | 1641 | { |
| | 1642 | particle.Position.vx += MUL_FIXED(100 - (FastRandom()&15), directionPtr->vx); |
| | 1643 | particle.Position.vy += MUL_FIXED(100 - (FastRandom()&15), directionPtr->vy); |
| | 1644 | particle.Position.vz += MUL_FIXED(100 - (FastRandom()&15), directionPtr->vz); |
| | 1645 | |
| | 1646 | for (i=0; i < 16; i++) |
| | 1647 | { |
| | 1648 | RenderParticle(&particle); |
| | 1649 | particle.Position.vx += MUL_FIXED(50 - (FastRandom()&15), directionPtr->vx); |
| | 1650 | particle.Position.vy += MUL_FIXED(50 - (FastRandom()&15), directionPtr->vy); |
| | 1651 | particle.Position.vz += MUL_FIXED(50 - (FastRandom()&15), directionPtr->vz); |
| | 1652 | particle.Size -= (FastRandom()&3)+3; |
| | 1653 | } |
| | 1654 | } |
| | 1655 | |
| | 1656 | for (i = 0; i < 12; i++) |
| | 1657 | { |
| | 1658 | int j = 8; |
| | 1659 | |
| | 1660 | particle.Position = *positionPtr; |
| | 1661 | particle.Position.vx += -MUL_FIXED(200,directionPtr->vx) + MUL_FIXED(50, muzzleMatrix.mat21); |
| | 1662 | particle.Position.vy += -MUL_FIXED(200,directionPtr->vy) + MUL_FIXED(50, muzzleMatrix.mat22); |
| | 1663 | particle.Position.vz += -MUL_FIXED(200,directionPtr->vz) + MUL_FIXED(50, muzzleMatrix.mat23); |
| | 1664 | |
| | 1665 | particle.Size = 50; |
| | 1666 | |
| | 1667 | if (!(i & 1)) |
| | 1668 | j += 8; |
| | 1669 | |
| | 1670 | while(j--) |
| | 1671 | { |
| | 1672 | RenderParticle(&particle); |
| | 1673 | particle.Position.vx += MUL_FIXED((FastRandom()&31)+16, muzzleMatrix.mat21); |
| | 1674 | particle.Position.vy += MUL_FIXED((FastRandom()&31)+16, muzzleMatrix.mat22); |
| | 1675 | particle.Position.vz += MUL_FIXED((FastRandom()&31)+16, muzzleMatrix.mat23); |
| | 1676 | particle.Size += (FastRandom()&15); |
| | 1677 | } |
| | 1678 | |
| | 1679 | MatrixMultiply(&muzzleMatrix, &rotmat, &muzzleMatrix); |
| | 1680 | } |
| | 1681 | } |
| | 1682 | break; |
| | 1683 | case MUZZLE_FLASH_SKEETER: |
| | 1684 | { |
| | 1685 | RenderParticle(&particle); |
| | 1686 | particle.Position.vx += MUL_FIXED(20, directionPtr->vx); |
| | 1687 | particle.Position.vy += MUL_FIXED(20, directionPtr->vy); |
| | 1688 | particle.Position.vz += MUL_FIXED(20, directionPtr->vz); |
| | 1689 | RenderParticle(&particle); |
| | 1690 | particle.Position.vx += MUL_FIXED(20, directionPtr->vx); |
| | 1691 | particle.Position.vy += MUL_FIXED(20, directionPtr->vy); |
| | 1692 | particle.Position.vz += MUL_FIXED(20, directionPtr->vz); |
| | 1693 | RenderParticle(&particle); |
| | 1694 | particle.Size = 20; |
| | 1695 | |
| | 1696 | for(i=0; i < 16; i++) |
| | 1697 | { |
| | 1698 | RenderParticle(&particle); |
| | 1699 | particle.Position.vx = positionPtr->vx + MUL_FIXED(100, directionPtr->vx) + (FastRandom()&127)-64; |
| | 1700 | particle.Position.vy = positionPtr->vy + MUL_FIXED(100, directionPtr->vy) + (FastRandom()&127)-64; |
| | 1701 | particle.Position.vz = positionPtr->vz + MUL_FIXED(100, directionPtr->vz) + (FastRandom()&127)-64; |
| | 1702 | } |
| | 1703 | } |
| | 1704 | } |
| | 1705 | DecalSystem_End(); |
| | 1706 | } |
| | 1707 | |
| | 1708 | static void DrawSfxObject(DISPLAYBLOCK *dispPtr) |
| | 1709 | { |
| | 1710 | struct sfxblock *sfxPtr = dispPtr->SfxPtr; |
| | 1711 | |
| | 1712 | switch(sfxPtr->SfxID) |
| | 1713 | { |
| | 1714 | case SFX_MUZZLE_FLASH_AMORPHOUS: |
| | 1715 | { |
| | 1716 | sfxPtr->EffectDrawnLastFrame = !sfxPtr->EffectDrawnLastFrame; |
| | 1717 | |
| | 1718 | if (sfxPtr->EffectDrawnLastFrame) |
| | 1719 | { |
| | 1720 | VECTORCH direction; |
| | 1721 | |
| | 1722 | direction.vx = dispPtr->ObMat.mat31; |
| | 1723 | direction.vy = dispPtr->ObMat.mat32; |
| | 1724 | direction.vz = dispPtr->ObMat.mat33; |
| | 1725 | DrawMuzzleFlash(&dispPtr->ObWorld, &direction, MUZZLE_FLASH_AMORPHOUS); |
| | 1726 | } |
| | 1727 | } |
| | 1728 | break; |
| | 1729 | case SFX_MUZZLE_FLASH_SMARTGUN: |
| | 1730 | { |
| | 1731 | VECTORCH direction; |
| | 1732 | |
| | 1733 | direction.vx = dispPtr->ObMat.mat31; |
| | 1734 | direction.vy = dispPtr->ObMat.mat32; |
| | 1735 | direction.vz = dispPtr->ObMat.mat33; |
| | 1736 | DrawMuzzleFlash(&dispPtr->ObWorld, &direction, MUZZLE_FLASH_SMARTGUN); |
| | 1737 | } |
| | 1738 | break; |
| | 1739 | case SFX_MUZZLE_FLASH_SKEETER: |
| | 1740 | { |
| | 1741 | sfxPtr->EffectDrawnLastFrame = !sfxPtr->EffectDrawnLastFrame; |
| | 1742 | |
| | 1743 | if (sfxPtr->EffectDrawnLastFrame) |
| | 1744 | { |
| | 1745 | VECTORCH direction; |
| | 1746 | |
| | 1747 | direction.vx = dispPtr->ObMat.mat31; |
| | 1748 | direction.vy = dispPtr->ObMat.mat32; |
| | 1749 | direction.vz = dispPtr->ObMat.mat33; |
| | 1750 | DrawMuzzleFlash(&dispPtr->ObWorld, &direction, MUZZLE_FLASH_SKEETER); |
| | 1751 | } |
| | 1752 | } |
| | 1753 | break; |
| | 1754 | case SFX_FRISBEE_PLASMA_BOLT: |
| | 1755 | { |
| | 1756 | int i; |
| | 1757 | PARTICLE particle; |
| | 1758 | VECTORCH direction; |
| | 1759 | direction.vx = dispPtr->ObMat.mat31; |
| | 1760 | direction.vy = dispPtr->ObMat.mat32; |
| | 1761 | direction.vz = dispPtr->ObMat.mat33; |
| | 1762 | particle.Position = dispPtr->ObWorld; |
| | 1763 | particle.ParticleID = PARTICLE_MUZZLEFLASH; |
| | 1764 | particle.Colour = RGBA_MAKE(255,255,255,255); |
| | 1765 | particle.Size = 200; |
| | 1766 | |
| | 1767 | for(i=0; i < 16; i++) |
| | 1768 | { |
| | 1769 | RenderParticle(&particle); |
| | 1770 | particle.Position.vx -= MUL_FIXED(50, direction.vx); |
| | 1771 | particle.Position.vy -= MUL_FIXED(50, direction.vy); |
| | 1772 | particle.Position.vz -= MUL_FIXED(50, direction.vz); |
| | 1773 | particle.Size -= 10; |
| | 1774 | } |
| | 1775 | } |
| | 1776 | break; |
| | 1777 | case SFX_PREDATOR_PLASMA_BOLT: |
| | 1778 | { |
| | 1779 | int i; |
| | 1780 | PARTICLE particle; |
| | 1781 | VECTORCH direction; |
| | 1782 | direction.vx = dispPtr->ObMat.mat31; |
| | 1783 | direction.vy = dispPtr->ObMat.mat32; |
| | 1784 | direction.vz = dispPtr->ObMat.mat33; |
| | 1785 | particle.Position = dispPtr->ObWorld; |
| | 1786 | particle.ParticleID = PARTICLE_MUZZLEFLASH; |
| | 1787 | particle.Colour = RGBA_MAKE(50,255,255,255); |
| | 1788 | particle.Size = 200; |
| | 1789 | |
| | 1790 | for (i=0; i < 16; i++) |
| | 1791 | { |
| | 1792 | RenderParticle(&particle); |
| | 1793 | particle.Position.vx -= MUL_FIXED(50, direction.vx); |
| | 1794 | particle.Position.vy -= MUL_FIXED(50, direction.vy); |
| | 1795 | particle.Position.vz -= MUL_FIXED(50, direction.vz); |
| | 1796 | particle.Size -= 10; |
| | 1797 | } |
| | 1798 | } |
| | 1799 | break; |
| | 1800 | case SFX_SMALL_PREDATOR_PLASMA_BOLT: |
| | 1801 | { |
| | 1802 | PARTICLE particle; |
| | 1803 | particle.Position = dispPtr->ObWorld; |
| | 1804 | particle.ParticleID = PARTICLE_ELECTRICALPLASMASPHERE; |
| | 1805 | particle.Colour = RGBA_MAKE(255,255,255,128); |
| | 1806 | particle.Size = 200; |
| | 1807 | RenderParticle(&particle); |
| | 1808 | particle.ParticleID = PARTICLE_MUZZLEFLASH; |
| | 1809 | particle.Colour = RGBA_MAKE(255,255,255,64); |
| | 1810 | particle.Size = 1000; |
| | 1811 | RenderParticle(&particle); |
| | 1812 | //RenderParticle(&particle); |
| | 1813 | } |
| | 1814 | default: |
| | 1815 | break; |
| | 1816 | } |
| | 1817 | } |
| | 1818 | |
| | 1819 | static void NoneBloodParticles() |
| | 1820 | { |
| | 1821 | int i; |
| | 1822 | |
| | 1823 | for(i = 0; i < NumActiveParticles; i++) |
| | 1824 | { |
| | 1825 | PARTICLE *particlePtr = &ParticleStorage[i]; |
| | 1826 | const PARTICLE_DESC *particleDescPtr = &ParticleDescription[particlePtr->ParticleID]; |
| | 1827 | |
| | 1828 | switch(particlePtr->ParticleID) |
| | 1829 | { |
| | 1830 | case PARTICLE_IMPACTSMOKE: |
| | 1831 | case PARTICLE_BLACKSMOKE: |
| | 1832 | { |
| | 1833 | particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy, NormalFrameTime); |
| | 1834 | |
| | 1835 | if (particlePtr->Velocity.vy > -1300) |
| | 1836 | particlePtr->Velocity.vy -= MUL_FIXED(3000, NormalFrameTime); |
| | 1837 | |
| | 1838 | if (particlePtr->Velocity.vx > 0) |
| | 1839 | { |
| | 1840 | particlePtr->Velocity.vx -= MUL_FIXED(2000, NormalFrameTime); |
| | 1841 | |
| | 1842 | if (particlePtr->Velocity.vx < 0) |
| | 1843 | particlePtr->Velocity.vx = 0; |
| | 1844 | } |
| | 1845 | else if (particlePtr->Velocity.vx < 0) |
| | 1846 | { |
| | 1847 | particlePtr->Velocity.vx += MUL_FIXED(2000, NormalFrameTime); |
| | 1848 | |
| | 1849 | if (particlePtr->Velocity.vx > 0) |
| | 1850 | particlePtr->Velocity.vx = 0; |
| | 1851 | } |
| | 1852 | |
| | 1853 | if (particlePtr->Velocity.vz > 0) |
| | 1854 | { |
| | 1855 | particlePtr->Velocity.vz -= MUL_FIXED(2000, NormalFrameTime); |
| | 1856 | |
| | 1857 | if (particlePtr->Velocity.vz < 0) |
| | 1858 | particlePtr->Velocity.vz = 0; |
| | 1859 | } |
| | 1860 | else if (particlePtr->Velocity.vz < 0) |
| | 1861 | { |
| | 1862 | particlePtr->Velocity.vz += MUL_FIXED(2000, NormalFrameTime); |
| | 1863 | |
| | 1864 | if (particlePtr->Velocity.vz > 0) |
| | 1865 | particlePtr->Velocity.vz = 0; |
| | 1866 | } |
| | 1867 | |
| | 1868 | particlePtr->Position.vx += MUL_FIXED ( particlePtr->Velocity.vx+ MUL_FIXED |
| | 1869 | ( -GetSin((particlePtr->Position.vz+particlePtr->Position.vy)&4095)/4, particlePtr->Offset.vx ), NormalFrameTime ); |
| | 1870 | |
| | 1871 | particlePtr->Position.vz += MUL_FIXED |
| | 1872 | ( particlePtr->Velocity.vz+ MUL_FIXED ( GetCos((particlePtr->Position.vx+particlePtr->Position.vy)&4095)/4, particlePtr->Offset.vz ),
NormalFrameTime ); |
| | 1873 | |
| | 1874 | { |
| | 1875 | int colour = particlePtr->LifeTime >> 11; |
| | 1876 | particlePtr->Colour = RGBA_MAKE(colour, colour, colour, 255); |
| | 1877 | } |
| | 1878 | } |
| | 1879 | break; |
| | 1880 | case PARTICLE_GUNMUZZLE_SMOKE: |
| | 1881 | { |
| | 1882 | particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy, NormalFrameTime); |
| | 1883 | |
| | 1884 | if (particlePtr->Velocity.vy > -1300) |
| | 1885 | particlePtr->Velocity.vy -= MUL_FIXED(1024, NormalFrameTime); |
| | 1886 | |
| | 1887 | if (particlePtr->Velocity.vx > 0) |
| | 1888 | { |
| | 1889 | particlePtr->Velocity.vx -= MUL_FIXED(1024, NormalFrameTime); |
| | 1890 | |
| | 1891 | if (particlePtr->Velocity.vx < 0) |
| | 1892 | particlePtr->Velocity.vx = 0; |
| | 1893 | } |
| | 1894 | else if (particlePtr->Velocity.vx < 0) |
| | 1895 | { |
| | 1896 | particlePtr->Velocity.vx += MUL_FIXED(1024, NormalFrameTime); |
| | 1897 | |
| | 1898 | if (particlePtr->Velocity.vx > 0) |
| | 1899 | particlePtr->Velocity.vx = 0; |
| | 1900 | } |
| | 1901 | |
| | 1902 | if (particlePtr->Velocity.vz > 0) |
| | 1903 | { |
| | 1904 | particlePtr->Velocity.vz -= MUL_FIXED(1024, NormalFrameTime); |
| | 1905 | |
| | 1906 | if (particlePtr->Velocity.vz < 0) |
| | 1907 | particlePtr->Velocity.vz = 0; |
| | 1908 | } |
| | 1909 | else if (particlePtr->Velocity.vz < 0) |
| | 1910 | { |
| | 1911 | particlePtr->Velocity.vz += MUL_FIXED(1024, NormalFrameTime); |
| | 1912 | |
| | 1913 | if (particlePtr->Velocity.vz > 0) |
| | 1914 | particlePtr->Velocity.vz = 0; |
| | 1915 | } |
| | 1916 | |
| | 1917 | particlePtr->Position.vx += MUL_FIXED ( particlePtr->Velocity.vx+ MUL_FIXED |
| | 1918 | ( -GetSin(((particlePtr->Position.vz+particlePtr->Position.vy)*16)&4095)/4, particlePtr->Offset.vx ), NormalFrameTime ); |
| | 1919 | |
| | 1920 | particlePtr->Position.vz += MUL_FIXED ( particlePtr->Velocity.vz+ MUL_FIXED |
| | 1921 | ( GetCos(((particlePtr->Position.vx+particlePtr->Position.vy)*16)&4095)/4, particlePtr->Offset.vz ), NormalFrameTime ); |
| | 1922 | |
| | 1923 | particlePtr->Size = MUL_FIXED(ONE_FIXED-particlePtr->LifeTime, 48); |
| | 1924 | { |
| | 1925 | int colour = particlePtr->LifeTime >> 11; |
| | 1926 | particlePtr->Colour = RGBA_MAKE(32,32,32,colour); |
| | 1927 | } |
| | 1928 | } |
| | 1929 | break; |
| | 1930 | case PARTICLE_FLARESMOKE: |
| | 1931 | { |
| | 1932 | particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy, NormalFrameTime); |
| | 1933 | |
| | 1934 | if (particlePtr->Velocity.vy > -1300) |
| | 1935 | particlePtr->Velocity.vy -= MUL_FIXED(4000, NormalFrameTime); |
| | 1936 | |
| | 1937 | if (particlePtr->Velocity.vx > 0) |
| | 1938 | { |
| | 1939 | particlePtr->Velocity.vx -= MUL_FIXED(2000, NormalFrameTime); |
| | 1940 | |
| | 1941 | if (particlePtr->Velocity.vx < 0) |
| | 1942 | particlePtr->Velocity.vx = 0; |
| | 1943 | } |
| | 1944 | else if (particlePtr->Velocity.vx < 0) |
| | 1945 | { |
| | 1946 | particlePtr->Velocity.vx += MUL_FIXED(2000, NormalFrameTime); |
| | 1947 | |
| | 1948 | if (particlePtr->Velocity.vx > 0) |
| | 1949 | particlePtr->Velocity.vx = 0; |
| | 1950 | } |
| | 1951 | |
| | 1952 | if (particlePtr->Velocity.vz > 0) |
| | 1953 | { |
| | 1954 | particlePtr->Velocity.vz -= MUL_FIXED(2000, NormalFrameTime); |
| | 1955 | |
| | 1956 | if (particlePtr->Velocity.vz < 0) |
| | 1957 | particlePtr->Velocity.vz = 0; |
| | 1958 | } |
| | 1959 | else if (particlePtr->Velocity.vz < 0) |
| | 1960 | { |
| | 1961 | particlePtr->Velocity.vz += MUL_FIXED(2000, NormalFrameTime); |
| | 1962 | |
| | 1963 | if (particlePtr->Velocity.vz > 0) |
| | 1964 | particlePtr->Velocity.vz = 0; |
| | 1965 | } |
| | 1966 | |
| | 1967 | particlePtr->Position.vx += MUL_FIXED ( particlePtr->Velocity.vx+ MUL_FIXED |
| | 1968 | ( -GetSin((particlePtr->Position.vz+particlePtr->Position.vy)&4095)/4, particlePtr->Offset.vx ), NormalFrameTime ); |
| | 1969 | |
| | 1970 | particlePtr->Position.vz += MUL_FIXED ( particlePtr->Velocity.vz+ MUL_FIXED |
| | 1971 | ( GetCos((particlePtr->Position.vx+particlePtr->Position.vy)&4095)/4, particlePtr->Offset.vz ), NormalFrameTime ); |
| | 1972 | |
| | 1973 | particlePtr->Colour = RGBA_MAKE ( particleDescPtr->RedScale[PlayerStatus.VisionMode], |
| | 1974 | particleDescPtr->GreenScale[PlayerStatus.VisionMode], |
| | 1975 | particleDescPtr->BlueScale[PlayerStatus.VisionMode], |
| | 1976 | (particlePtr->LifeTime >> 10)); |
| | 1977 | |
| | 1978 | particlePtr->Size = MUL_FIXED(ONE_FIXED-particlePtr->LifeTime,200)+50; |
| | 1979 | } |
| | 1980 | break; |
| | 1981 | case PARTICLE_RICOCHET_SPARK: |
| | 1982 | { |
| | 1983 | particlePtr->Offset = particlePtr->Position; |
| | 1984 | |
| | 1985 | particlePtr->Position.vx += MUL_FIXED(particlePtr->Velocity.vx, NormalFrameTime); |
| | 1986 | particlePtr->Velocity.vx -= MUL_FIXED(particlePtr->Velocity.vx, NormalFrameTime); |
| | 1987 | particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy, NormalFrameTime); |
| | 1988 | particlePtr->Velocity.vy -= MUL_FIXED(particlePtr->Velocity.vy, NormalFrameTime); |
| | 1989 | particlePtr->Position.vz += MUL_FIXED(particlePtr->Velocity.vz, NormalFrameTime); |
| | 1990 | particlePtr->Velocity.vz -= MUL_FIXED(particlePtr->Velocity.vz, NormalFrameTime); |
| | 1991 | |
| | 1992 | { |
| | 1993 | int l = particlePtr->LifeTime*8; |
| | 1994 | l = MUL_FIXED(255,l); |
| | 1995 | |
| | 1996 | if (l > 255) |
| | 1997 | { |
| | 1998 | switch (PlayerStatus.VisionMode) |
| | 1999 | { |
| | 2000 | default: |
| | 2001 | case VISION_MODE_NORMAL: |
| | 2002 | particlePtr->Colour = RGBA_MAKE(255,255,l-255,255); |
| | 2003 | break; |
| | 2004 | case VISION_MODE_IMAGEINTENSIFIER: |
| | 2005 | particlePtr->Colour = RGBA_MAKE(l/2,l/2,l/2,255); |
| | 2006 | break; |
| | 2007 | case VISION_MODE_PRED_THERMAL: |
| | 2008 | particlePtr->Colour = RGBA_MAKE(l-255,255,255,255); |
| | 2009 | break; |
| | 2010 | case VISION_MODE_PRED_SEEALIENS: |
| | 2011 | case VISION_MODE_PRED_SEEPREDTECH: |
| | 2012 | particlePtr->Colour = RGBA_MAKE(255,255,l-255,255); |
| | 2013 | } |
| | 2014 | } |
| | 2015 | else |
| | 2016 | { |
| | 2017 | switch (PlayerStatus.VisionMode) |
| | 2018 | { |
| | 2019 | default: |
| | 2020 | case VISION_MODE_NORMAL: |
| | 2021 | particlePtr->Colour = RGBA_MAKE(255,l,0,l); |
| | 2022 | break; |
| | 2023 | case VISION_MODE_IMAGEINTENSIFIER: |
| | 2024 | particlePtr->Colour = RGBA_MAKE(l/2,l/2,128,l); |
| | 2025 | break; |
| | 2026 | case VISION_MODE_PRED_THERMAL: |
| | 2027 | particlePtr->Colour = RGBA_MAKE(0,l,l,l); |
| | 2028 | break; |
| | 2029 | case VISION_MODE_PRED_SEEALIENS: |
| | 2030 | case VISION_MODE_PRED_SEEPREDTECH: |
| | 2031 | particlePtr->Colour = RGBA_MAKE(l,l,0,l); |
| | 2032 | } |
| | 2033 | } |
| | 2034 | } |
| | 2035 | } |
| | 2036 | break; |
| | 2037 | case PARTICLE_SPARK: |
| | 2038 | { |
| | 2039 | particlePtr->Offset = particlePtr->Position; |
| | 2040 | |
| | 2041 | particlePtr->Position.vx += MUL_FIXED(particlePtr->Velocity.vx, NormalFrameTime); |
| | 2042 | particlePtr->Velocity.vx -= MUL_FIXED(particlePtr->Velocity.vx, NormalFrameTime); |
| | 2043 | particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy, NormalFrameTime); |
| | 2044 | particlePtr->Velocity.vy += MUL_FIXED(5000, NormalFrameTime); |
| | 2045 | particlePtr->Position.vz += MUL_FIXED(particlePtr->Velocity.vz, NormalFrameTime); |
| | 2046 | particlePtr->Velocity.vz -= MUL_FIXED(particlePtr->Velocity.vz, NormalFrameTime); |
| | 2047 | |
| | 2048 | { |
| | 2049 | int l = particlePtr->LifeTime * 2; |
| | 2050 | l = MUL_FIXED(255,l); |
| | 2051 | |
| | 2052 | if (l > 255) |
| | 2053 | { |
| | 2054 | switch (PlayerStatus.VisionMode) |
| | 2055 | { |
| | 2056 | default: |
| | 2057 | case VISION_MODE_NORMAL: |
| | 2058 | particlePtr->Colour = RGBA_MAKE(l/2,l/2,255,255); |
| | 2059 | break; |
| | 2060 | case VISION_MODE_IMAGEINTENSIFIER: |
| | 2061 | particlePtr->Colour = RGBA_MAKE(l/2,l/2,l/2,255); |
| | 2062 | break; |
| | 2063 | case VISION_MODE_PRED_THERMAL: |
| | 2064 | particlePtr->Colour = RGBA_MAKE(l-255,255,255,255); |
| | 2065 | break; |
| | 2066 | case VISION_MODE_PRED_SEEALIENS: |
| | 2067 | case VISION_MODE_PRED_SEEPREDTECH: |
| | 2068 | particlePtr->Colour = RGBA_MAKE(255,255,l-255,255); |
| | 2069 | } |
| | 2070 | } |
| | 2071 | else |
| | 2072 | { |
| | 2073 | switch (PlayerStatus.VisionMode) |
| | 2074 | { |
| | 2075 | default: |
| | 2076 | case VISION_MODE_NORMAL: |
| | 2077 | particlePtr->Colour = RGBA_MAKE(l/2,l/2,l,l); |
| | 2078 | break; |
| | 2079 | case VISION_MODE_IMAGEINTENSIFIER: |
| | 2080 | particlePtr->Colour = RGBA_MAKE(l/2,l/2,128,l); |
| | 2081 | break; |
| | 2082 | case VISION_MODE_PRED_THERMAL: |
| | 2083 | particlePtr->Colour = RGBA_MAKE(0,l,l,l); |
| | 2084 | break; |
| | 2085 | case VISION_MODE_PRED_SEEALIENS: |
| | 2086 | case VISION_MODE_PRED_SEEPREDTECH: |
| | 2087 | particlePtr->Colour = RGBA_MAKE(l,l,0,l); |
| | 2088 | } |
| | 2089 | } |
| | 2090 | } |
| | 2091 | } |
| | 2092 | break; |
| | 2093 | case PARTICLE_FLAME: |
| | 2094 | case PARTICLE_NONDAMAGINGFLAME: |
| | 2095 | { |
| | 2096 | particlePtr->Size = 20+(ONE_FIXED/2-particlePtr->LifeTime)/64; |
| | 2097 | |
| | 2098 | if (particlePtr->LifeTime == ONE_FIXED / 2) |
| | 2099 | { |
| | 2100 | switch (PlayerStatus.VisionMode) |
| | 2101 | { |
| | 2102 | default: |
| | 2103 | case VISION_MODE_NORMAL: |
| | 2104 | particlePtr->Colour = RGBA_MAKE(16, 16, 128, (particlePtr->LifeTime >>8) | 9); |
| | 2105 | break; |
| | 2106 | case VISION_MODE_IMAGEINTENSIFIER: |
| | 2107 | particlePtr->Colour = RGBA_MAKE(0, 32, 0, (particlePtr->LifeTime >> 8 ) | 9); |
| | 2108 | break; |
| | 2109 | case VISION_MODE_PRED_THERMAL: |
| | 2110 | particlePtr->Colour = RGBA_MAKE(0, 0, 128, (particlePtr->LifeTime >> 8) | 9); |
| | 2111 | break; |
| | 2112 | case VISION_MODE_PRED_SEEALIENS: |
| | 2113 | case VISION_MODE_PRED_SEEPREDTECH: |
| | 2114 | particlePtr->Colour = RGBA_MAKE(192, 128, 32, (particlePtr->LifeTime >> 8) | 9); |
| | 2115 | } |
| | 2116 | } |
| | 2117 | else |
| | 2118 | { |
| | 2119 | particlePtr->Colour = RGBA_MAKE ( particleDescPtr->RedScale[PlayerStatus.VisionMode], |
| | 2120 | particleDescPtr->GreenScale[PlayerStatus.VisionMode], |
| | 2121 | particleDescPtr->BlueScale[PlayerStatus.VisionMode], |
| | 2122 | (particlePtr->LifeTime >> 8) | 9); |
| | 2123 | } |
| | 2124 | } |
| | 2125 | break; |
| | 2126 | case PARTICLE_FIRE: |
| | 2127 | particlePtr->Size = 300 - (FastRandom() & 127); |
| | 2128 | break; |
| | 2129 | case PARTICLE_MOLOTOVFLAME: |
| | 2130 | { |
| | 2131 | VECTORCH obstacleNormal; |
| | 2132 | int moduleIndex; |
| | 2133 | |
| | 2134 | particlePtr->Colour = RGBA_MAKE ( particleDescPtr->RedScale[PlayerStatus.VisionMode], |
| | 2135 | particleDescPtr->GreenScale[PlayerStatus.VisionMode], |
| | 2136 | particleDescPtr->BlueScale[PlayerStatus.VisionMode], |
| | 2137 | (particlePtr->LifeTime >> 10) | 9); |
| | 2138 | |
| | 2139 | particlePtr->Velocity.vy += MUL_FIXED(8000, NormalFrameTime); |
| | 2140 | |
| | 2141 | ParticleDynamics(particlePtr, &obstacleNormal, &moduleIndex); |
| | 2142 | |
| | 2143 | particlePtr->Size = 800 - (FastRandom() & 255); |
| | 2144 | } |
| | 2145 | break; |
| | 2146 | case PARTICLE_NONCOLLIDINGFLAME: |
| | 2147 | particlePtr->Size = 20 + (ONE_FIXED / 2 - particlePtr->LifeTime) / 64; |
| | 2148 | break; |
| | 2149 | case PARTICLE_ORANGE_SPARK: |
| | 2150 | { |
| | 2151 | particlePtr->Offset = particlePtr->Position; |
| | 2152 | |
| | 2153 | particlePtr->Position.vx += MUL_FIXED(particlePtr->Velocity.vx, NormalFrameTime); |
| | 2154 | particlePtr->Velocity.vx -= MUL_FIXED(particlePtr->Velocity.vx, NormalFrameTime); |
| | 2155 | particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy, NormalFrameTime); |
| | 2156 | particlePtr->Velocity.vy -= MUL_FIXED(particlePtr->Velocity.vy, NormalFrameTime); |
| | 2157 | particlePtr->Position.vz += MUL_FIXED(particlePtr->Velocity.vz, NormalFrameTime); |
| | 2158 | particlePtr->Velocity.vz -= MUL_FIXED(particlePtr->Velocity.vz, NormalFrameTime); |
| | 2159 | |
| | 2160 | { |
| | 2161 | int l = particlePtr->LifeTime * 8; |
| | 2162 | l = MUL_FIXED(255, l); |
| | 2163 | |
| | 2164 | if (l > 255) |
| | 2165 | { |
| | 2166 | switch (PlayerStatus.VisionMode) |
| | 2167 | { |
| | 2168 | default: |
| | 2169 | case VISION_MODE_NORMAL: |
| | 2170 | particlePtr->Colour = RGBA_MAKE(255,255,l-255,255); |
| | 2171 | break; |
| | 2172 | case VISION_MODE_IMAGEINTENSIFIER: |
| | 2173 | particlePtr->Colour = RGBA_MAKE(l/2,l/2,l/2,255); |
| | 2174 | break; |
| | 2175 | case VISION_MODE_PRED_THERMAL: |
| | 2176 | case VISION_MODE_PRED_SEEALIENS: |
| | 2177 | case VISION_MODE_PRED_SEEPREDTECH: |
| | 2178 | particlePtr->Colour = RGBA_MAKE(l-255,255,255,255); |
| | 2179 | } |
| | 2180 | } |
| | 2181 | else |
| | 2182 | { |
| | 2183 | switch (PlayerStatus.VisionMode) |
| | 2184 | { |
| | 2185 | default: |
| | 2186 | case VISION_MODE_NORMAL: |
| | 2187 | particlePtr->Colour = RGBA_MAKE(255,l,0,l); |
| | 2188 | break; |
| | 2189 | case VISION_MODE_IMAGEINTENSIFIER: |
| | 2190 | particlePtr->Colour = RGBA_MAKE(l/2,l/2,128,l); |
| | 2191 | break; |
| | 2192 | case VISION_MODE_PRED_THERMAL: |
| | 2193 | case VISION_MODE_PRED_SEEALIENS: |
| | 2194 | case VISION_MODE_PRED_SEEPREDTECH: |
| | 2195 | particlePtr->Colour = RGBA_MAKE(0,l,l,l); |
| | 2196 | } |
| | 2197 | } |
| | 2198 | } |
| | 2199 | } |
| | 2200 | break; |
| | 2201 | case PARTICLE_ORANGE_PLASMA: |
| | 2202 | { |
| | 2203 | particlePtr->Offset = particlePtr->Position; |
| | 2204 | |
| | 2205 | particlePtr->Position.vx += MUL_FIXED(particlePtr->Velocity.vx, NormalFrameTime); |
| | 2206 | particlePtr->Velocity.vx -= MUL_FIXED(particlePtr->Velocity.vx, NormalFrameTime); |
| | 2207 | particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy, NormalFrameTime); |
| | 2208 | particlePtr->Velocity.vy -= MUL_FIXED(particlePtr->Velocity.vy, NormalFrameTime); |
| | 2209 | particlePtr->Position.vz += MUL_FIXED(particlePtr->Velocity.vz, NormalFrameTime); |
| | 2210 | particlePtr->Velocity.vz -= MUL_FIXED(particlePtr->Velocity.vz, NormalFrameTime); |
| | 2211 | |
| | 2212 | { |
| | 2213 | int l = particlePtr->LifeTime * 16; |
| | 2214 | l = MUL_FIXED(255,l); |
| | 2215 | |
| | 2216 | if (l > 255) |
| | 2217 | { |
| | 2218 | switch (PlayerStatus.VisionMode) |
| | 2219 | { |
| | 2220 | default: |
| | 2221 | case VISION_MODE_NORMAL: |
| | 2222 | particlePtr->Colour = RGBA_MAKE(255,255,l-255,255); |
| | 2223 | break; |
| | 2224 | case VISION_MODE_IMAGEINTENSIFIER: |
| | 2225 | particlePtr->Colour = RGBA_MAKE(l/2,l/2,l/2,255); |
| | 2226 | break; |
| | 2227 | case VISION_MODE_PRED_THERMAL: |
| | 2228 | case VISION_MODE_PRED_SEEALIENS: |
| | 2229 | case VISION_MODE_PRED_SEEPREDTECH: |
| | 2230 | particlePtr->Colour = RGBA_MAKE(l-255,255,255,255); |
| | 2231 | } |
| | 2232 | } |
| | 2233 | else |
| | 2234 | { |
| | 2235 | switch (PlayerStatus.VisionMode) |
| | 2236 | { |
| | 2237 | default: |
| | 2238 | case VISION_MODE_NORMAL: |
| | 2239 | particlePtr->Colour = RGBA_MAKE(255,l,0,l); |
| | 2240 | break; |
| | 2241 | case VISION_MODE_IMAGEINTENSIFIER: |
| | 2242 | particlePtr->Colour = RGBA_MAKE(l/2,l/2,128,l); |
| | 2243 | break; |
| | 2244 | case VISION_MODE_PRED_THERMAL: |
| | 2245 | case VISION_MODE_PRED_SEEALIENS: |
| | 2246 | case VISION_MODE_PRED_SEEPREDTECH: |
| | 2247 | particlePtr->Colour = RGBA_MAKE(0,l,l,l); |
| | 2248 | } |
| | 2249 | } |
| | 2250 | } |
| | 2251 | } |
| | 2252 | break; |
| | 2253 | case PARTICLE_DEWLINE: |
| | 2254 | { |
| | 2255 | int l = (particlePtr->LifeTime)/64/4; |
| | 2256 | |
| | 2257 | if (l > 255) |
| | 2258 | { |
| | 2259 | switch (PlayerStatus.VisionMode) |
| | 2260 | { |
| | 2261 | default: |
| | 2262 | case VISION_MODE_NORMAL: |
| | 2263 | particlePtr->Colour = RGBA_MAKE(255,255,255,255); |
| | 2264 | break; |
| | 2265 | case VISION_MODE_IMAGEINTENSIFIER: |
| | 2266 | particlePtr->Colour = RGBA_MAKE(0,255,0,255); |
| | 2267 | break; |
| | 2268 | case VISION_MODE_PRED_THERMAL: |
| | 2269 | particlePtr->Colour = RGBA_MAKE(255,0,0,255); |
| | 2270 | break; |
| | 2271 | case VISION_MODE_PRED_SEEALIENS: |
| | 2272 | case VISION_MODE_PRED_SEEPREDTECH: |
| | 2273 | particlePtr->Colour = RGBA_MAKE(255,128,64,255); |
| | 2274 | } |
| | 2275 | } |
| | 2276 | else |
| | 2277 | { |
| | 2278 | particlePtr->Position.vx += MUL_FIXED(particlePtr->Velocity.vx, NormalFrameTime); |
| | 2279 | particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy, NormalFrameTime); |
| | 2280 | particlePtr->Position.vz += MUL_FIXED(particlePtr->Velocity.vz, NormalFrameTime); |
| | 2281 | |
| | 2282 | switch (PlayerStatus.VisionMode) |
| | 2283 | { |
| | 2284 | default: |
| | 2285 | case VISION_MODE_NORMAL: |
| | 2286 | particlePtr->Colour = RGBA_MAKE(255,128+(l/2),64+((3*l)/4),l); |
| | 2287 | break; |
| | 2288 | case VISION_MODE_IMAGEINTENSIFIER: |
| | 2289 | particlePtr->Colour = RGBA_MAKE(l/2,l/2,l/2,l); |
| | 2290 | break; |
| | 2291 | case VISION_MODE_PRED_THERMAL: |
| | 2292 | particlePtr->Colour = RGBA_MAKE(255,l/2,l/2,l); |
| | 2293 | break; |
| | 2294 | case VISION_MODE_PRED_SEEALIENS: |
| | 2295 | case VISION_MODE_PRED_SEEPREDTECH: |
| | 2296 | particlePtr->Colour = RGBA_MAKE(255,l/2,l/4,l); |
| | 2297 | } |
| | 2298 | |
| | 2299 | particlePtr->Size = 32+(FastRandom()&31); |
| | 2300 | } |
| | 2301 | } |
| | 2302 | break; |
| | 2303 | case PARTICLE_PLASMATRAIL: |
| | 2304 | { |
| | 2305 | int l = (particlePtr->LifeTime)/64/4; |
| | 2306 | |
| | 2307 | if (l > 255) |
| | 2308 | { |
| | 2309 | switch (PlayerStatus.VisionMode) |
| | 2310 | { |
| | 2311 | default: |
| | 2312 | case VISION_MODE_NORMAL: |
| | 2313 | particlePtr->Colour = RGBA_MAKE(0,0,255,255); |
| | 2314 | break; |
| | 2315 | case VISION_MODE_IMAGEINTENSIFIER: |
| | 2316 | particlePtr->Colour = RGBA_MAKE(0,255,0,255); |
| | 2317 | break; |
| | 2318 | case VISION_MODE_PRED_THERMAL: |
| | 2319 | particlePtr->Colour = RGBA_MAKE(0,0,255,255); |
| | 2320 | break; |
| | 2321 | case VISION_MODE_PRED_SEEALIENS: |
| | 2322 | case VISION_MODE_PRED_SEEPREDTECH: |
| | 2323 | particlePtr->Colour = RGBA_MAKE(255,128,64,255); |
| | 2324 | } |
| | 2325 | } |
| | 2326 | else |
| | 2327 | { |
| | 2328 | particlePtr->Position.vx += MUL_FIXED(particlePtr->Velocity.vx,NormalFrameTime); |
| | 2329 | particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy,NormalFrameTime); |
| | 2330 | particlePtr->Position.vz += MUL_FIXED(particlePtr->Velocity.vz,NormalFrameTime); |
| | 2331 | |
| | 2332 | switch (PlayerStatus.VisionMode) |
| | 2333 | { |
| | 2334 | default: |
| | 2335 | case VISION_MODE_NORMAL: |
| | 2336 | particlePtr->Colour = RGBA_MAKE(l/4,l/2,255,l); |
| | 2337 | break; |
| | 2338 | case VISION_MODE_IMAGEINTENSIFIER: |
| | 2339 | particlePtr->Colour = RGBA_MAKE(l/2,l/2,l/2,l); |
| | 2340 | break; |
| | 2341 | case VISION_MODE_PRED_THERMAL: |
| | 2342 | particlePtr->Colour = RGBA_MAKE(l/4,l/2,255,l); |
| | 2343 | break; |
| | 2344 | case VISION_MODE_PRED_SEEALIENS: |
| | 2345 | case VISION_MODE_PRED_SEEPREDTECH: |
| | 2346 | particlePtr->Colour = RGBA_MAKE(255,l/2,l/4,l); |
| | 2347 | } |
| | 2348 | |
| | 2349 | particlePtr->Size = 32+(FastRandom()&31); |
| | 2350 | } |
| | 2351 | } |
| | 2352 | break; |
| | 2353 | case PARTICLE_WATERSPRAY: |
| | 2354 | { |
| | 2355 | particlePtr->Colour = RGBA_MAKE ( particleDescPtr->RedScale[PlayerStatus.VisionMode], |
| | 2356 | particleDescPtr->GreenScale[PlayerStatus.VisionMode], |
| | 2357 | particleDescPtr->BlueScale[PlayerStatus.VisionMode], |
| | 2358 | particleDescPtr->Alpha); |
| | 2359 | |
| | 2360 | particlePtr->Position.vx += MUL_FIXED(particlePtr->Velocity.vx,NormalFrameTime); |
| | 2361 | particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy,NormalFrameTime); |
| | 2362 | particlePtr->Position.vz += MUL_FIXED(particlePtr->Velocity.vz,NormalFrameTime); |
| | 2363 | particlePtr->Velocity.vy += MUL_FIXED(10000,NormalFrameTime); |
| | 2364 | } |
| | 2365 | break; |
| | 2366 | case PARTICLE_WATERFALLSPRAY: |
| | 2367 | { |
| | 2368 | extern int WaterFallBase; |
| | 2369 | int y = particlePtr->Position.vy; |
| | 2370 | particlePtr->Colour = RGBA_MAKE ( particleDescPtr->RedScale[PlayerStatus.VisionMode], |
| | 2371 | particleDescPtr->GreenScale[PlayerStatus.VisionMode], |
| | 2372 | particleDescPtr->BlueScale[PlayerStatus.VisionMode], |
| | 2373 | particleDescPtr->Alpha); |
| | 2374 | |
| | 2375 | particlePtr->Position.vx += MUL_FIXED(particlePtr->Velocity.vx, NormalFrameTime); |
| | 2376 | particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy, NormalFrameTime); |
| | 2377 | particlePtr->Position.vz += MUL_FIXED(particlePtr->Velocity.vz, NormalFrameTime); |
| | 2378 | particlePtr->Velocity.vy += MUL_FIXED(10000+(FastRandom()&511), NormalFrameTime); |
| | 2379 | |
| | 2380 | if(particlePtr->Position.vz < 54885 && particlePtr->Position.vx < 179427) |
| | 2381 | { |
| | 2382 | if (y < 4742 && particlePtr->Position.vy > 4742) |
| | 2383 | { |
| | 2384 | particlePtr->Position.vy = 4742; |
| | 2385 | particlePtr->Velocity.vy = -MUL_FIXED(particlePtr->Velocity.vy, ONE_FIXED/2-(FastRandom()&16384)); |
| | 2386 | } |
| | 2387 | } |
| | 2388 | else if (particlePtr->Position.vz < 58600) |
| | 2389 | { |
| | 2390 | int l = DIV_FIXED(particlePtr->Position.vz - 54885,58600-54885); |
| | 2391 | |
| | 2392 | if (particlePtr->Position.vx < 179427 - MUL_FIXED(l,179427-175545)) |
| | 2393 | { |
| | 2394 | int yThreshold = 4742 + MUL_FIXED(l,8635-4742); |
| | 2395 | |
| | 2396 | if (y < yThreshold && particlePtr->Position.vy > yThreshold) |
| | 2397 | { |
| | 2398 | particlePtr->Position.vy = yThreshold; |
| | 2399 | particlePtr->Velocity.vy = -MUL_FIXED(particlePtr->Velocity.vy,ONE_FIXED/2-(FastRandom()&16384)); |
| | 2400 | } |
| | 2401 | } |
| | 2402 | } |
| | 2403 | |
| | 2404 | particlePtr->Offset.vx = particlePtr->Position.vx - particlePtr->Velocity.vx/4; |
| | 2405 | particlePtr->Offset.vy = particlePtr->Position.vy - particlePtr->Velocity.vy/4; |
| | 2406 | particlePtr->Offset.vz = particlePtr->Position.vz - particlePtr->Velocity.vz/4; |
| | 2407 | |
| | 2408 | if (particlePtr->Position.vy > WaterFallBase) |
| | 2409 | particlePtr->LifeTime = 0; |
| | 2410 | } |
| | 2411 | break; |
| | 2412 | case PARTICLE_FLECHETTE: |
| | 2413 | case PARTICLE_FLECHETTE_NONDAMAGING: |
| | 2414 | { |
| | 2415 | { |
| | 2416 | int l = particlePtr->LifeTime/4; |
| | 2417 | l = MUL_FIXED(255,l); |
| | 2418 | |
| | 2419 | if (l > 255) |
| | 2420 | { |
| | 2421 | switch (PlayerStatus.VisionMode) |
| | 2422 | { |
| | 2423 | default: |
| | 2424 | case VISION_MODE_NORMAL: |
| | 2425 | particlePtr->Colour = RGBA_MAKE((l-255)/2+32,0,0,255); |
| | 2426 | break; |
| | 2427 | case VISION_MODE_IMAGEINTENSIFIER: |
| | 2428 | particlePtr->Colour = RGBA_MAKE(l/2,l/2,l/2,255); |
| | 2429 | break; |
| | 2430 | case VISION_MODE_PRED_THERMAL: |
| | 2431 | case VISION_MODE_PRED_SEEALIENS: |
| | 2432 | case VISION_MODE_PRED_SEEPREDTECH: |
| | 2433 | particlePtr->Colour = RGBA_MAKE(l-255,255,255,255); |
| | 2434 | } |
| | 2435 | } |
| | 2436 | else |
| | 2437 | { |
| | 2438 | switch (PlayerStatus.VisionMode) |
| | 2439 | { |
| | 2440 | default: |
| | 2441 | case VISION_MODE_NORMAL: |
| | 2442 | particlePtr->Colour = RGBA_MAKE(32,0,0,l); |
| | 2443 | break; |
| | 2444 | case VISION_MODE_IMAGEINTENSIFIER: |
| | 2445 | particlePtr->Colour = RGBA_MAKE(l/2,l/2,l/2,l); |
| | 2446 | break; |
| | 2447 | case VISION_MODE_PRED_THERMAL: |
| | 2448 | case VISION_MODE_PRED_SEEALIENS: |
| | 2449 | case VISION_MODE_PRED_SEEPREDTECH: |
| | 2450 | particlePtr->Colour = RGBA_MAKE(0,l,l,l); |
| | 2451 | } |
| | 2452 | } |
| | 2453 | } |
| | 2454 | |
| | 2455 | if (particlePtr->Offset.vy) //particlePtr->Velocity.vx || particlePtr->Velocity.vy || particlePtr->Velocity.vz) |
| | 2456 | { |
| | 2457 | VECTORCH obstacleNormal; |
| | 2458 | int moduleIndex; |
| | 2459 | VECTORCH velocityBackup = particlePtr->Velocity; |
| | 2460 | |
| | 2461 | if(ParticleDynamics(particlePtr, &obstacleNormal, &moduleIndex)) |
| | 2462 | { |
| | 2463 | if(moduleIndex == -1) |
| | 2464 | { |
| | 2465 | particlePtr->LifeTime = 0; |
| | 2466 | } |
| | 2467 | else |
| | 2468 | { |
| | 2469 | particlePtr->Offset.vy = 0; |
| | 2470 | particlePtr->Velocity = velocityBackup; |
| | 2471 | particlePtr->Position.vx += particlePtr->Velocity.vx >> 10; |
| | 2472 | particlePtr->Position.vy += particlePtr->Velocity.vy >> 10; |
| | 2473 | particlePtr->Position.vz += particlePtr->Velocity.vz >> 10; |
| | 2474 | } |
| | 2475 | } |
| | 2476 | } |
| | 2477 | } |
| | 2478 | break; |
| | 2479 | case PARTICLE_SMOKECLOUD: |
| | 2480 | { |
| | 2481 | if (particlePtr->LifeTime < ONE_FIXED*8) |
| | 2482 | { |
| | 2483 | int colour = (particlePtr->LifeTime/(8*256*4)); |
| | 2484 | particlePtr->Colour = RGBA_MAKE(255,255,255,colour); |
| | 2485 | } |
| | 2486 | else |
| | 2487 | { |
| | 2488 | particlePtr->Colour = RGBA_MAKE(255,255,255,64); |
| | 2489 | } |
| | 2490 | |
| | 2491 | particlePtr->Size = 1000+500-(particlePtr->LifeTime>>10); |
| | 2492 | |
| | 2493 | AddEffectsOfForceGenerators(&particlePtr->Position, &particlePtr->Velocity, 32*64); |
| | 2494 | } |
| | 2495 | break; |
| | 2496 | case PARTICLE_ELECTRICALPLASMASPHERE: |
| | 2497 | { |
| | 2498 | int colour = (particlePtr->LifeTime/128); |
| | 2499 | particlePtr->Size = 200+(ONE_FIXED-particlePtr->LifeTime)/16; |
| | 2500 | particlePtr->Colour = RGBA_MAKE(255,255,255,colour); |
| | 2501 | } |
| | 2502 | break; |
| | 2503 | case PARTICLE_STEAM: |
| | 2504 | { |
| | 2505 | particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy, NormalFrameTime); |
| | 2506 | |
| | 2507 | if (particlePtr->Velocity.vy > -1300) |
| | 2508 | particlePtr->Velocity.vy -= MUL_FIXED(4000, NormalFrameTime); |
| | 2509 | |
| | 2510 | if (particlePtr->Velocity.vx > 0) |
| | 2511 | { |
| | 2512 | particlePtr->Velocity.vx -= MUL_FIXED(2000, NormalFrameTime); |
| | 2513 | |
| | 2514 | if (particlePtr->Velocity.vx < 0) |
| | 2515 | particlePtr->Velocity.vx = 0; |
| | 2516 | } |
| | 2517 | else if (particlePtr->Velocity.vx < 0) |
| | 2518 | { |
| | 2519 | particlePtr->Velocity.vx += MUL_FIXED(2000, NormalFrameTime); |
| | 2520 | |
| | 2521 | if (particlePtr->Velocity.vx > 0) |
| | 2522 | particlePtr->Velocity.vx = 0; |
| | 2523 | } |
| | 2524 | |
| | 2525 | if (particlePtr->Velocity.vz > 0) |
| | 2526 | { |
| | 2527 | particlePtr->Velocity.vz -= MUL_FIXED(2000, NormalFrameTime); |
| | 2528 | |
| | 2529 | if (particlePtr->Velocity.vz < 0) |
| | 2530 | particlePtr->Velocity.vz = 0; |
| | 2531 | } |
| | 2532 | else if (particlePtr->Velocity.vz < 0) |
| | 2533 | { |
| | 2534 | particlePtr->Velocity.vz += MUL_FIXED(2000, NormalFrameTime); |
| | 2535 | |
| | 2536 | if (particlePtr->Velocity.vz > 0) |
| | 2537 | particlePtr->Velocity.vz = 0; |
| | 2538 | } |
| | 2539 | |
| | 2540 | particlePtr->Position.vx += MUL_FIXED ( particlePtr->Velocity.vx+ |
| | 2541 | MUL_FIXED(-GetSin((particlePtr->Position.vz+particlePtr->Position.vy)&4095)/4, particlePtr->Offset.vx ), NormalFrameTime ); |
| | 2542 | |
| | 2543 | particlePtr->Position.vz += MUL_FIXED ( particlePtr->Velocity.vz+ MUL_FIXED |
| | 2544 | ( GetCos((particlePtr->Position.vx+particlePtr->Position.vy)&4095)/4, particlePtr->Offset.vz ), NormalFrameTime ); |
| | 2545 | |
| | 2546 | particlePtr->Colour = RGBA_MAKE ( |
| | 2547 | particleDescPtr->RedScale[PlayerStatus.VisionMode], |
| | 2548 | particleDescPtr->GreenScale[PlayerStatus.VisionMode], |
| | 2549 | particleDescPtr->BlueScale[PlayerStatus.VisionMode], |
| | 2550 | (particlePtr->LifeTime >> 14) + 17 |
| | 2551 | ); |
| | 2552 | } |
| | 2553 | default: |
| | 2554 | { |
| | 2555 | /* particle initialised wrongly */ |
| | 2556 | assert(0); |
| | 2557 | break; |
| | 2558 | } |
| | 2559 | } |
| | 2560 | } |
| | 2561 | |
| | 2562 | i = NumActiveParticles; |
| | 2563 | |
| | 2564 | while(i) |
| | 2565 | { |
| | 2566 | PARTICLE *particlePtr = &ParticleStorage[--i]; |
| | 2567 | |
| | 2568 | //printf("Active particle %d id %d\n ", NumActiveParticles, particlePtr->ParticleID); |
| | 2569 | VECTORCH position = particlePtr->Position; |
| | 2570 | TranslatePointIntoViewspace(&position); |
| | 2571 | |
| | 2572 | switch(particlePtr->ParticleID) |
| | 2573 | { |
| | 2574 | case PARTICLE_FLARESMOKE: |
| | 2575 | { |
| | 2576 | VECTORCH impulse = {0,0,0}; |
| | 2577 | int t = MUL_FIXED(NormalFrameTime, NormalFrameTime*4); |
| | 2578 | AddEffectsOfForceGenerators(&particlePtr->Position, &impulse, 8); |
| | 2579 | particlePtr->Position.vx += MUL_FIXED(impulse.vx, t); |
| | 2580 | particlePtr->Position.vy += MUL_FIXED(impulse.vy, t); |
| | 2581 | particlePtr->Position.vz += MUL_FIXED(impulse.vz, t); |
| | 2582 | RenderParticle(particlePtr); |
| | 2583 | } |
| | 2584 | break; |
| | 2585 | case PARTICLE_FLAME: |
| | 2586 | case PARTICLE_NONDAMAGINGFLAME: |
| | 2587 | { |
| | 2588 | VECTORCH obstacleNormal; |
| | 2589 | int moduleIndex; |
| | 2590 | RenderParticle(particlePtr); |
| | 2591 | |
| | 2592 | ParticleDynamics(particlePtr, &obstacleNormal, &moduleIndex); |
| | 2593 | |
| | 2594 | particlePtr->Velocity.vy -= MUL_FIXED(8000, NormalFrameTime); |
| | 2595 | |
| | 2596 | //if(!(FastRandom() & 15) && ParticleDynamics(particlePtr, &obstacleNormal, &moduleIndex)) |
| | 2597 | if(ParticleDynamics(particlePtr, &obstacleNormal, &moduleIndex)) |
| | 2598 | { |
| | 2599 | MakeDecal(DECAL_SCORCHED, &obstacleNormal, &particlePtr->Position, moduleIndex); |
| | 2600 | //particlePtr->LifeTime = 0; |
| | 2601 | } |
| | 2602 | else |
| | 2603 | { |
| | 2604 | AddEffectsOfForceGenerators(&particlePtr->Position, &particlePtr->Velocity, 32*16); |
| | 2605 | } |
| | 2606 | } |
| | 2607 | break; |
| | 2608 | case PARTICLE_FIRE: |
| | 2609 | { |
| | 2610 | RenderParticle(particlePtr); |
| | 2611 | |
| | 2612 | particlePtr->Position.vx += MUL_FIXED(particlePtr->Velocity.vx, NormalFrameTime); |
| | 2613 | particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy, NormalFrameTime); |
| | 2614 | particlePtr->Position.vz += MUL_FIXED(particlePtr->Velocity.vz, NormalFrameTime); |
| | 2615 | particlePtr->Velocity.vy -= MUL_FIXED(4000, NormalFrameTime); |
| | 2616 | } |
| | 2617 | break; |
| | 2618 | case PARTICLE_NONCOLLIDINGFLAME: |
| | 2619 | { |
| | 2620 | RenderParticle(particlePtr); |
| | 2621 | |
| | 2622 | particlePtr->Position.vx += MUL_FIXED(particlePtr->Velocity.vx, NormalFrameTime); |
| | 2623 | particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy, NormalFrameTime); |
| | 2624 | particlePtr->Position.vz += MUL_FIXED(particlePtr->Velocity.vz, NormalFrameTime); |
| | 2625 | particlePtr->Velocity.vy -= MUL_FIXED(8000, NormalFrameTime); |
| | 2626 | } |
| | 2627 | break; |
| | 2628 | case PARTICLE_IMPACTSMOKE: |
| | 2629 | case PARTICLE_RICOCHET_SPARK: |
| | 2630 | case PARTICLE_SPARK: |
| | 2631 | case PARTICLE_STEAM: |
| | 2632 | case PARTICLE_BLACKSMOKE: |
| | 2633 | case PARTICLE_GUNMUZZLE_SMOKE: |
| | 2634 | case PARTICLE_MOLOTOVFLAME: |
| | 2635 | case PARTICLE_ORANGE_SPARK: |
| | 2636 | case PARTICLE_ORANGE_PLASMA: |
| | 2637 | case PARTICLE_PLASMATRAIL: |
| | 2638 | case PARTICLE_DEWLINE: |
| | 2639 | case PARTICLE_WATERSPRAY: |
| | 2640 | case PARTICLE_WATERFALLSPRAY: |
| | 2641 | case PARTICLE_SMOKECLOUD: |
| | 2642 | case PARTICLE_ELECTRICALPLASMASPHERE: |
| | 2643 | RenderParticle(particlePtr); |
| | 2644 | break; |
| | 2645 | case PARTICLE_FLECHETTE: |
| | 2646 | case PARTICLE_FLECHETTE_NONDAMAGING: |
| | 2647 | RenderFlechetteParticle(particlePtr); |
| | 2648 | break; |
| | 2649 | default: |
| | 2650 | { |
| | 2651 | /* particle initialised wrongly */ |
| | 2652 | assert(0); |
| | 2653 | break; |
| | 2654 | } |
| | 2655 | } |
| | 2656 | |
| | 2657 | particlePtr->LifeTime -= NormalFrameTime; |
| | 2658 | |
| | 2659 | if (particlePtr->LifeTime <= 0) |
| | 2660 | { |
| | 2661 | switch(particlePtr->ParticleID) |
| | 2662 | { |
| | 2663 | case PARTICLE_MOLOTOVFLAME: |
| | 2664 | case PARTICLE_NONCOLLIDINGFLAME: |
| | 2665 | if ( (FastRandom() & 65535) < 4096) |
| | 2666 | { |
| | 2667 | VECTORCH zero = {0,0,0}; |
| | 2668 | MakeParticle(&particlePtr->Position, &zero, PARTICLE_IMPACTSMOKE); |
| | 2669 | } |
| | 2670 | default: |
| | 2671 | break; |
| | 2672 | } |
| | 2673 | |
| | 2674 | *particlePtr = ParticleStorage[--NumActiveParticles]; |
| | 2675 | } |
| | 2676 | } |
| | 2677 | } |
| | 2678 | |
| | 2679 | static void blood_particles() |
| | 2680 | { |
| | 2681 | int i; |
| | 2682 | |
| | 2683 | for(i = NumberOfBloodParticles-1; i >= 0; i--) |
| | 2684 | { |
| | 2685 | PARTICLE *particlePtr = &BloodParticleStorage[i]; |
| | 2686 | //printf("Active blood particle %d id %d\n ", NumberOfBloodParticles, particlePtr->ParticleID); |
| | 2687 | |
| | 2688 | VECTORCH position = particlePtr->Position; |
| | 2689 | TranslatePointIntoViewspace(&position); |
| | 2690 | |
| | 2691 | switch(particlePtr->ParticleID) |
| | 2692 | { |
| | 2693 | case PARTICLE_ALIEN_BLOOD: |
| | 2694 | { |
| | 2695 | VECTORCH obstacleNormal; |
| | 2696 | int moduleIndex; |
| | 2697 | //particlePtr->Size = 64 - (FastRandom() & 31); |
| | 2698 | particlePtr->Size = 20; |
| | 2699 | particlePtr->Offset = particlePtr->Position; |
| | 2700 | particlePtr->Offset.vx += particlePtr->Velocity.vx >> 4; |
| | 2701 | particlePtr->Offset.vy += particlePtr->Velocity.vy >> 4; |
| | 2702 | particlePtr->Offset.vz += particlePtr->Velocity.vz >> 4; |
| | 2703 | |
| | 2704 | if(ParticleDynamics(particlePtr, &obstacleNormal, &moduleIndex)) |
| | 2705 | { |
| | 2706 | MATRIXCH orientation; |
| | 2707 | VECTORCH velocity; |
| | 2708 | MakeMatrixFromDirection(&obstacleNormal, &orientation); |
| | 2709 | velocity.vx = ((FastRandom()&1023) - 512); |
| | 2710 | velocity.vy = ((FastRandom()&1023) - 512); |
| | 2711 | velocity.vz = (255+(FastRandom()&255)); |
| | 2712 | RotateVector(&velocity, &orientation); |
| | 2713 | MakeParticle(&particlePtr->Position, &velocity, PARTICLE_IMPACTSMOKE); |
| | 2714 | MakeDecal(DECAL_SCORCHED, &obstacleNormal, &particlePtr->Position, moduleIndex); |
| | 2715 | |
| | 2716 | if((FastRandom() & 255) < 16) |
| | 2717 | Sound_Play(SID_ACID_SPRAY, "dpv", &particlePtr->Position, (FastRandom() & 255) - 128, 40); |
| | 2718 | |
| | 2719 | particlePtr->LifeTime = 0; |
| | 2720 | } |
| | 2721 | else |
| | 2722 | { |
| | 2723 | particlePtr->Velocity.vy += MUL_FIXED(10000, NormalFrameTime); |
| | 2724 | AddEffectsOfForceGenerators(&particlePtr->Position, &particlePtr->Velocity, 32*16); |
| | 2725 | RenderParticle(particlePtr); |
| | 2726 | } |
| | 2727 | } |
| | 2728 | break; |
| | 2729 | case PARTICLE_HUMAN_BLOOD: |
| | 2730 | { |
| | 2731 | VECTORCH obstacleNormal; |
| | 2732 | int moduleIndex; |
| | 2733 | //particlePtr->Size = 64 - (FastRandom() & 31); |
| | 2734 | particlePtr->Size = 20; |
| | 2735 | particlePtr->Offset = particlePtr->Position; |
| | 2736 | particlePtr->Offset.vx += particlePtr->Velocity.vx >> 4; |
| | 2737 | particlePtr->Offset.vy += particlePtr->Velocity.vy >> 4; |
| | 2738 | particlePtr->Offset.vz += particlePtr->Velocity.vz >> 4; |
| | 2739 | |
| | 2740 | if(ParticleDynamics(particlePtr, &obstacleNormal, &moduleIndex)) |
| | 2741 | { |
| | 2742 | MakeDecal(DECAL_HUMAN_BLOOD, &obstacleNormal, &particlePtr->Position, moduleIndex); |
| | 2743 | particlePtr->LifeTime = 0; |
| | 2744 | } |
| | 2745 | else |
| | 2746 | { |
| | 2747 | particlePtr->Velocity.vy += MUL_FIXED(10000, NormalFrameTime); |
| | 2748 | AddEffectsOfForceGenerators(&particlePtr->Position, &particlePtr->Velocity, 32*16); |
| | 2749 | RenderParticle(particlePtr); |
| | 2750 | } |
| | 2751 | } |
| | 2752 | break; |
| | 2753 | case PARTICLE_PREDATOR_BLOOD: |
| | 2754 | { |
| | 2755 | VECTORCH obstacleNormal; |
| | 2756 | int moduleIndex; |
| | 2757 | //particlePtr->Size = 64 - (FastRandom() & 31); |
| | 2758 | particlePtr->Size = 20; |
| | 2759 | particlePtr->Offset = particlePtr->Position; |
| | 2760 | particlePtr->Offset.vx += particlePtr->Velocity.vx >> 4; |
| | 2761 | particlePtr->Offset.vy += particlePtr->Velocity.vy >> 4; |
| | 2762 | particlePtr->Offset.vz += particlePtr->Velocity.vz >> 4; |
| | 2763 | |
| | 2764 | if(ParticleDynamics(particlePtr, &obstacleNormal, &moduleIndex)) |
| | 2765 | { |
| | 2766 | MakeDecal(DECAL_PREDATOR_BLOOD, &obstacleNormal, &particlePtr->Position, moduleIndex); |
| | 2767 | particlePtr->LifeTime = 0; |
| | 2768 | } |
| | 2769 | else |
| | 2770 | { |
| | 2771 | particlePtr->Velocity.vy += MUL_FIXED(10000, NormalFrameTime); |
| | 2772 | AddEffectsOfForceGenerators(&particlePtr->Position, &particlePtr->Velocity, 32*16); |
| | 2773 | RenderParticle(particlePtr); |
| | 2774 | } |
| | 2775 | } |
| | 2776 | break; |
| | 2777 | case PARTICLE_ANDROID_BLOOD: |
| | 2778 | { |
| | 2779 | VECTORCH obstacleNormal; |
| | 2780 | int moduleIndex; |
| | 2781 | //particlePtr->Size = 64 - (FastRandom() & 31); |
| | 2782 | particlePtr->Size = 20; |
| | 2783 | particlePtr->Offset = particlePtr->Position; |
| | 2784 | particlePtr->Offset.vx += particlePtr->Velocity.vx >> 4; |
| | 2785 | particlePtr->Offset.vy += particlePtr->Velocity.vy >> 4; |
| | 2786 | particlePtr->Offset.vz += particlePtr->Velocity.vz >> 4; |
| | 2787 | |
| | 2788 | if(ParticleDynamics(particlePtr, &obstacleNormal, &moduleIndex)) |
| | 2789 | { |
| | 2790 | MakeDecal(DECAL_ANDROID_BLOOD, &obstacleNormal, &particlePtr->Position, moduleIndex); |
| | 2791 | particlePtr->LifeTime = 0; |
| | 2792 | } |
| | 2793 | else |
| | 2794 | { |
| | 2795 | particlePtr->Velocity.vy += MUL_FIXED(10000, NormalFrameTime); |
| | 2796 | AddEffectsOfForceGenerators(&particlePtr->Position, &particlePtr->Velocity, 32*16); |
| | 2797 | RenderParticle(particlePtr); |
| | 2798 | } |
| | 2799 | } |
| | 2800 | break; |
| | 2801 | case PARTICLE_SPARK: |
| | 2802 | { |
| | 2803 | particlePtr->Offset = particlePtr->Position; |
| | 2804 | |
| | 2805 | particlePtr->Position.vx += MUL_FIXED(particlePtr->Velocity.vx, NormalFrameTime); |
| | 2806 | particlePtr->Velocity.vx -= MUL_FIXED(particlePtr->Velocity.vx, NormalFrameTime); |
| | 2807 | particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy, NormalFrameTime); |
| | 2808 | particlePtr->Velocity.vy += MUL_FIXED(5000, NormalFrameTime); |
| | 2809 | particlePtr->Position.vz += MUL_FIXED(particlePtr->Velocity.vz, NormalFrameTime); |
| | 2810 | particlePtr->Velocity.vz -= MUL_FIXED(particlePtr->Velocity.vz, NormalFrameTime); |
| | 2811 | |
| | 2812 | { |
| | 2813 | int l = particlePtr->LifeTime * 2; |
| | 2814 | l = MUL_FIXED(255,l); |
| | 2815 | |
| | 2816 | if (l > 255) |
| | 2817 | { |
| | 2818 | switch (PlayerStatus.VisionMode) |
| | 2819 | { |
| | 2820 | default: |
| | 2821 | case VISION_MODE_NORMAL: |
| | 2822 | particlePtr->Colour = RGBA_MAKE(l/2,l/2,255,255); |
| | 2823 | break; |
| | 2824 | case VISION_MODE_IMAGEINTENSIFIER: |
| | 2825 | particlePtr->Colour = RGBA_MAKE(l/2,l/2,l/2,255); |
| | 2826 | break; |
| | 2827 | case VISION_MODE_PRED_THERMAL: |
| | 2828 | particlePtr->Colour = RGBA_MAKE(l-255,255,255,255); |
| | 2829 | break; |
| | 2830 | case VISION_MODE_PRED_SEEALIENS: |
| | 2831 | case VISION_MODE_PRED_SEEPREDTECH: |
| | 2832 | particlePtr->Colour = RGBA_MAKE(255,255,l-255,255); |
| | 2833 | } |
| | 2834 | } |
| | 2835 | else |
| | 2836 | { |
| | 2837 | switch (PlayerStatus.VisionMode) |
| | 2838 | { |
| | 2839 | default: |
| | 2840 | case VISION_MODE_NORMAL: |
| | 2841 | particlePtr->Colour = RGBA_MAKE(l/2,l/2,l,l); |
| | 2842 | break; |
| | 2843 | case VISION_MODE_IMAGEINTENSIFIER: |
| | 2844 | particlePtr->Colour = RGBA_MAKE(l/2,l/2,128,l); |
| | 2845 | break; |
| | 2846 | case VISION_MODE_PRED_THERMAL: |
| | 2847 | particlePtr->Colour = RGBA_MAKE(0,l,l,l); |
| | 2848 | break; |
| | 2849 | case VISION_MODE_PRED_SEEALIENS: |
| | 2850 | case VISION_MODE_PRED_SEEPREDTECH: |
| | 2851 | particlePtr->Colour = RGBA_MAKE(l,l,0,l); |
| | 2852 | } |
| | 2853 | } |
| | 2854 | } |
| | 2855 | } |
| | 2856 | default: |
| | 2857 | break; |
| | 2858 | } |
| | 2859 | |
| | 2860 | particlePtr->LifeTime -= NormalFrameTime; |
| | 2861 | |
| | 2862 | if (particlePtr->LifeTime <= 0) |
| | 2863 | *particlePtr = BloodParticleStorage[--NumberOfBloodParticles]; |
| | 2864 | |
| | 2865 | } |
| | 2866 | } |
| | 2867 | |
| | 2868 | void HandleParticleSystem() |
| | 2869 | { |
| | 2870 | int i; |
| | 2871 | HandleRipples(); |
| | 2872 | |
| | 2873 | DecalSystem_Setup(); |
| | 2874 | HandleDecalSystem(); |
| | 2875 | PostLandscapeRendering(); |
| | 2876 | //DecalSystem_End(); |
| | 2877 | DecalSystem_Setup(); |
| | 2878 | OutputTranslucentPolyList(); |
| | 2879 | NoneBloodParticles(); |
| | 2880 | blood_particles(); |
| | 2881 | |
| | 2882 | for(i=0; i < numVisObjs; ++i) |
| | 2883 | { |
| | 2884 | DISPLAYBLOCK *objectPtr = VisibleObjects[i].DispPtr; |
| | 2885 | STRATEGYBLOCK *sbPtr = objectPtr->ObStrategyBlock; |
| | 2886 | |
| | 2887 | if (objectPtr->SfxPtr) |
| | 2888 | { |
| | 2889 | DrawSfxObject(objectPtr); |
| | 2890 | continue; |
| | 2891 | } |
| | 2892 | |
| | 2893 | if (sbPtr) |
| | 2894 | { |
| | 2895 | if (objectPtr->HModelControlBlock) |
| | 2896 | ScanHModelForDecals(objectPtr, objectPtr->HModelControlBlock->section_data); |
| | 2897 | |
| | 2898 | switch(sbPtr->type) |
| | 2899 | { |
| | 2900 | case I_BehaviourFlare: |
| | 2901 | if (UserProfile.GameOptions.LightCoronas) |
| | 2902 | DoFlareCorona(objectPtr); |
| | 2903 | break; |
| | 2904 | case I_BehaviourNetGhost: |
| | 2905 | { |
| | 2906 | NETGHOSTDATABLOCK *ghostDataPtr = (NETGHOSTDATABLOCK *)sbPtr->dataptr; |
| | 2907 | |
| | 2908 | if (ghostDataPtr->type == I_BehaviourFlare && UserProfile.GameOptions.LightCoronas) |
| | 2909 | DoFlareCorona(objectPtr); |
| | 2910 | } |
| | 2911 | break; |
| | 2912 | case I_BehaviourXenoborg: |
| | 2913 | { |
| | 2914 | XENO_STATUS_BLOCK *statusPtr = (XENO_STATUS_BLOCK *)sbPtr->dataptr; |
| | 2915 | LASER_BEAM_DESC *laserPtr = statusPtr->TargetingLaser; |
| | 2916 | int i; |
| | 2917 | for (i=0; i < 3; ++i) |
| | 2918 | { |
| | 2919 | if (laserPtr->BeamIsOn) |
| | 2920 | { |
| | 2921 | if (laserPtr->BeamHasHitPlayer) |
| | 2922 | { |
| | 2923 | int colour; |
| | 2924 | switch (PlayerStatus.VisionMode) |
| | 2925 | { |
| | 2926 | default: |
| | 2927 | case VISION_MODE_NORMAL: |
| | 2928 | colour = 0xffff0000; |
| | 2929 | break; |
| | 2930 | case VISION_MODE_IMAGEINTENSIFIER: |
| | 2931 | colour = 0xffffffff; |
| | 2932 | break; |
| | 2933 | case VISION_MODE_PRED_THERMAL: |
| | 2934 | case VISION_MODE_PRED_SEEALIENS: |
| | 2935 | case VISION_MODE_PRED_SEEPREDTECH: |
| | 2936 | colour = 0xffff8000; |
| | 2937 | } |
| | 2938 | |
| | 2939 | RenderLightFlare(&laserPtr->SourcePosition, colour); |
| | 2940 | } |
| | 2941 | else |
| | 2942 | { |
| | 2943 | PARTICLE particle; |
| | 2944 | switch (PlayerStatus.VisionMode) |
| | 2945 | { |
| | 2946 | default: |
| | 2947 | case VISION_MODE_NORMAL: |
| | 2948 | particle.Colour = RGBA_MAKE(255,0,0,255); |
| | 2949 | break; |
| | 2950 | case VISION_MODE_IMAGEINTENSIFIER: |
| | 2951 | particle.Colour = RGBA_MAKE(255,255,255,255); |
| | 2952 | break; |
| | 2953 | case VISION_MODE_PRED_THERMAL: |
| | 2954 | case VISION_MODE_PRED_SEEALIENS: |
| | 2955 | case VISION_MODE_PRED_SEEPREDTECH: |
| | 2956 | particle.Colour = RGBA_MAKE(255,128,0,255); |
| | 2957 | } |
| | 2958 | |
| | 2959 | particle.ParticleID = PARTICLE_LASERBEAM; |
| | 2960 | particle.Position = laserPtr->SourcePosition; |
| | 2961 | particle.Offset = laserPtr->TargetPosition; |
| | 2962 | particle.Size = 20; |
| | 2963 | RenderParticle(&particle); |
| | 2964 | } |
| | 2965 | } |
| | 2966 | laserPtr++; |
| | 2967 | } |
| | 2968 | |
| | 2969 | if (statusPtr->LeftMainBeam.BeamIsOn) |
| | 2970 | DrawXenoborgMainLaserbeam(&statusPtr->LeftMainBeam); |
| | 2971 | |
| | 2972 | if (statusPtr->RightMainBeam.BeamIsOn) |
| | 2973 | DrawXenoborgMainLaserbeam(&statusPtr->RightMainBeam); |
| | 2974 | } |
| | 2975 | break; |
| | 2976 | case I_BehaviourSpeargunBolt: |
| | 2977 | { |
| | 2978 | SPEAR_BEHAV_BLOCK *bbPtr = (SPEAR_BEHAV_BLOCK * ) sbPtr->dataptr; |
| | 2979 | |
| | 2980 | if (bbPtr->SpearThroughFragment) |
| | 2981 | { |
| | 2982 | extern const DISPLAYBLOCK Zero_Displayblock; |
| | 2983 | DISPLAYBLOCK displayblock = Zero_Displayblock; |
| | 2984 | |
| | 2985 | displayblock.ObWorld.vx = bbPtr->Position.vx + sbPtr->DynPtr->Position.vx; |
| | 2986 | displayblock.ObWorld.vy = bbPtr->Position.vy + sbPtr->DynPtr->Position.vy; |
| | 2987 | displayblock.ObWorld.vz = bbPtr->Position.vz + sbPtr->DynPtr->Position.vz; |
| | 2988 | displayblock.ObMat = bbPtr->Orient; |
| | 2989 | displayblock.ObShape = GetLoadedShapeMSL("spear"); |
| | 2990 | displayblock.ShapeData = GetShapeData(displayblock.ObShape); |
| | 2991 | |
| | 2992 | displayblock.ObView.vx = displayblock.ObWorld.vx - Global_VDB.VDB_World.vx; |
| | 2993 | displayblock.ObView.vy = displayblock.ObWorld.vy - Global_VDB.VDB_World.vy; |
| | 2994 | displayblock.ObView.vz = displayblock.ObWorld.vz - Global_VDB.VDB_World.vz; |
| | 2995 | |
| | 2996 | RotateVector(&displayblock.ObView, &Global_VDB.VDB_Mat); |
| | 2997 | AttachSpearGunArrow(&displayblock); |
| | 2998 | } |
| | 2999 | } |
| | 3000 | default: |
| | 3001 | break; |
| | 3002 | } |
| | 3003 | } |
| | 3004 | } |
| | 3005 | |
| | 3006 | HandlePheromoneTrails(); |
| | 3007 | HandleVolumetricExplosion(); |
| | 3008 | DecalSystem_End(); |
| | 3009 | } |
| | 3010 | |
| | 3011 | static void AddRipple(int x, int z, int amplitude) |
| | 3012 | { |
| | 3013 | RippleStorage[ActiveRippleNumber].Active = 1; |
| | 3014 | RippleStorage[ActiveRippleNumber].X = x; |
| | 3015 | RippleStorage[ActiveRippleNumber].Z = z; |
| | 3016 | RippleStorage[ActiveRippleNumber].Radius = 200; |
| | 3017 | RippleStorage[ActiveRippleNumber].Amplitude = amplitude; |
| | 3018 | |
| | 3019 | if (++ActiveRippleNumber == MAX_NO_OF_RIPPLES) |
| | 3020 | ActiveRippleNumber = 0; |
| | 3021 | } |
| | 3022 | |
| | 3023 | void HandleRainDrops(MODULE *modulePtr, int numberOfRaindrops) |
| | 3024 | { |
| | 3025 | int i; |
| | 3026 | |
| | 3027 | for(i=0; i < numberOfRaindrops; ++i) |
| | 3028 | { |
| | 3029 | PARTICLE *particlePtr = &RainDropStorage[i]; |
| | 3030 | |
| | 3031 | if((particlePtr->Position.vy > modulePtr->m_world.vy+modulePtr->m_maxy-500) |
| | 3032 | ||(particlePtr->Position.vx < modulePtr->m_world.vx+modulePtr->m_minx) |
| | 3033 | ||(particlePtr->Position.vx > modulePtr->m_world.vx+modulePtr->m_maxx) |
| | 3034 | ||(particlePtr->Position.vz < modulePtr->m_world.vz+modulePtr->m_minz) |
| | 3035 | ||(particlePtr->Position.vz > modulePtr->m_world.vz+modulePtr->m_maxz)) |
| | 3036 | { |
| | 3037 | AddRipple(particlePtr->Position.vx, particlePtr->Position.vz,400); |
| | 3038 | particlePtr->Position.vy = modulePtr->m_world.vy+modulePtr->m_miny; |
| | 3039 | particlePtr->Position.vx = modulePtr->m_world.vx+modulePtr->m_minx+(FastRandom()%(modulePtr->m_maxz-modulePtr->m_minx)); |
| | 3040 | particlePtr->Position.vz = modulePtr->m_world.vz+modulePtr->m_minz+(FastRandom()%(modulePtr->m_maxz-modulePtr->m_minz)); |
| | 3041 | // particlePtr->Velocity.vy = (FastRandom()&8191)+15000; |
| | 3042 | // particlePtr->Velocity.vx = (FastRandom()&255)+5000; |
| | 3043 | // particlePtr->Velocity.vz = (FastRandom()&255)-128; |
| | 3044 | particlePtr->Velocity.vy = (FastRandom()&8191)+15000; |
| | 3045 | particlePtr->Velocity.vx = (FastRandom()&255)-128; |
| | 3046 | particlePtr->Velocity.vz = (FastRandom()&255)-128; |
| | 3047 | { |
| | 3048 | particlePtr->Offset.vx = -particlePtr->Velocity.vz; |
| | 3049 | particlePtr->Offset.vy = 0; |
| | 3050 | particlePtr->Offset.vz = particlePtr->Velocity.vx; |
| | 3051 | Normalise(&(particlePtr->Offset)); |
| | 3052 | // particlePtr->Offset.vx = MUL_FIXED(particlePtr->Offset.vx,20); |
| | 3053 | // particlePtr->Offset.vz = MUL_FIXED(particlePtr->Offset.vz,20); |
| | 3054 | particlePtr->Offset.vx = MUL_FIXED(particlePtr->Offset.vx,50); |
| | 3055 | particlePtr->Offset.vz = MUL_FIXED(particlePtr->Offset.vz,50); |
| | 3056 | } |
| | 3057 | } |
| | 3058 | { |
| | 3059 | VECTORCH prevPosition = particlePtr->Position; |
| | 3060 | |
| | 3061 | particlePtr->Position.vx += MUL_FIXED(particlePtr->Velocity.vx,NormalFrameTime); |
| | 3062 | particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy,NormalFrameTime); |
| | 3063 | particlePtr->Position.vz += MUL_FIXED(particlePtr->Velocity.vz,NormalFrameTime); |
| | 3064 | |
| | 3065 | if (particlePtr->Position.vy > modulePtr->m_world.vy + modulePtr->m_maxy - 500) |
| | 3066 | particlePtr->Position.vy = modulePtr->m_world.vy+modulePtr->m_maxy-495; |
| | 3067 | |
| | 3068 | DrawParticle_Rain(particlePtr, &prevPosition); |
| | 3069 | } |
| | 3070 | } |
| | 3071 | } |
| | 3072 | |
| | 3073 | void HandleRain(int numberOfRaindrops) |
| | 3074 | { |
| | 3075 | int i; |
| | 3076 | /* KJL 15:23:37 12/8/97 - this is written to work with the yard in genshd1 */ |
| | 3077 | |
| | 3078 | assert( numberOfRaindrops < MAX_RAINDROPS); |
| | 3079 | |
| | 3080 | for (i=0; i < numberOfRaindrops; i++) |
| | 3081 | { |
| | 3082 | PARTICLE *particlePtr = &RainDropStorage[i]; |
| | 3083 | int killDrop = 0; |
| | 3084 | |
| | 3085 | if((particlePtr->Position.vx > -10418) |
| | 3086 | &&(particlePtr->Position.vy > -4030) |
| | 3087 | &&(particlePtr->Position.vz < 35070) |
| | 3088 | &&(particlePtr->Position.vz > -11600)) |
| | 3089 | { |
| | 3090 | killDrop = 1; |
| | 3091 | } |
| | 3092 | if((particlePtr->Position.vx > -45486) |
| | 3093 | &&(particlePtr->Position.vx < -29901) |
| | 3094 | &&(particlePtr->Position.vy > -6000) |
| | 3095 | &&(particlePtr->Position.vz < -50656) |
| | 3096 | &&(particlePtr->Position.vz > -70130)) |
| | 3097 | { |
| | 3098 | killDrop = 1; |
| | 3099 | } |
| | 3100 | |
| | 3101 | if((particlePtr->Position.vy > 3000) |
| | 3102 | ||(particlePtr->Position.vx < -77000) |
| | 3103 | ||(particlePtr->Position.vx > 134000) |
| | 3104 | ||(particlePtr->Position.vz < -145000)//modulePtr->m_world.vz+modulePtr->m_minz) |
| | 3105 | ||(particlePtr->Position.vz > 48706)) |
| | 3106 | { |
| | 3107 | killDrop = 1; |
| | 3108 | } |
| | 3109 | |
| | 3110 | if (killDrop) |
| | 3111 | { |
| | 3112 | particlePtr->Position.vy = -10000; |
| | 3113 | particlePtr->Position.vx = -77000+(FastRandom()%(211000)); |
| | 3114 | particlePtr->Position.vz = -145000+(FastRandom()%(145000+49000)); |
| | 3115 | particlePtr->Velocity.vy = (FastRandom()&8191)+15000; |
| | 3116 | particlePtr->Velocity.vx = (FastRandom()&255)+5000; |
| | 3117 | particlePtr->Velocity.vz = (FastRandom()&255)-128; |
| | 3118 | { |
| | 3119 | particlePtr->Offset.vx = -particlePtr->Velocity.vz; |
| | 3120 | particlePtr->Offset.vy = 0; |
| | 3121 | particlePtr->Offset.vz = particlePtr->Velocity.vx; |
| | 3122 | Normalise(&(particlePtr->Offset)); |
| | 3123 | particlePtr->Offset.vx = MUL_FIXED(particlePtr->Offset.vx,20); |
| | 3124 | particlePtr->Offset.vz = MUL_FIXED(particlePtr->Offset.vz,20); |
| | 3125 | } |
| | 3126 | } |
| | 3127 | { |
| | 3128 | VECTORCH prevPosition = particlePtr->Position; |
| | 3129 | |
| | 3130 | particlePtr->Position.vx += MUL_FIXED(particlePtr->Velocity.vx,NormalFrameTime); |
| | 3131 | particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy,NormalFrameTime); |
| | 3132 | particlePtr->Position.vz += MUL_FIXED(particlePtr->Velocity.vz,NormalFrameTime); |
| | 3133 | DrawParticle_Rain(particlePtr,&prevPosition); |
| | 3134 | } |
| | 3135 | } |
| | 3136 | } |
| | 3137 | |
| | 3138 | void HandleRainShaft(MODULE *modulePtr, int bottomY, int topY, int numberOfRaindrops) |
| | 3139 | { |
| | 3140 | int i; |
| | 3141 | const PARTICLE_DESC *particleDescPtr = &ParticleDescription[PARTICLE_WATERFALLSPRAY]; |
| | 3142 | |
| | 3143 | assert(numberOfRaindrops < MAX_RAINDROPS); |
| | 3144 | |
| | 3145 | for (i=0; i < numberOfRaindrops; ++i) |
| | 3146 | { |
| | 3147 | PARTICLE *particlePtr = &RainDropStorage[i]; |
| | 3148 | |
| | 3149 | if((particlePtr->Position.vx < modulePtr->m_world.vx+modulePtr->m_minx) |
| | 3150 | ||(particlePtr->Position.vx > modulePtr->m_world.vx+modulePtr->m_maxx) |
| | 3151 | ||(particlePtr->Position.vz < modulePtr->m_world.vz+modulePtr->m_minz) |
| | 3152 | ||(particlePtr->Position.vz > modulePtr->m_world.vz+modulePtr->m_maxz)) |
| | 3153 | { |
| | 3154 | particlePtr->LifeTime = 0; |
| | 3155 | } |
| | 3156 | else if(particlePtr->Position.vy > bottomY) |
| | 3157 | { |
| | 3158 | particlePtr->Position.vy = bottomY; |
| | 3159 | particlePtr->Velocity.vy = -particlePtr->Velocity.vy; |
| | 3160 | particlePtr->Velocity.vx = particlePtr->Velocity.vx; |
| | 3161 | particlePtr->Velocity.vz = particlePtr->Velocity.vz; |
| | 3162 | particlePtr->LifeTime = 1; |
| | 3163 | particlePtr->Size = 100; |
| | 3164 | AddRipple(particlePtr->Position.vx, particlePtr->Position.vz, 100); |
| | 3165 | } |
| | 3166 | |
| | 3167 | if (particlePtr->LifeTime <= 0) |
| | 3168 | { |
| | 3169 | particlePtr->Position.vy = topY; |
| | 3170 | particlePtr->Position.vx = modulePtr->m_world.vx+modulePtr->m_minx+(FastRandom()%(modulePtr->m_maxz-modulePtr->m_minx)); |
| | 3171 | particlePtr->Position.vz = modulePtr->m_world.vz+modulePtr->m_minz+(FastRandom()%(modulePtr->m_maxz-modulePtr->m_minz)); |
| | 3172 | particlePtr->Velocity.vy = (FastRandom()&8191)+15000; |
| | 3173 | particlePtr->Velocity.vx = (FastRandom()&1023)-512; |
| | 3174 | particlePtr->Velocity.vz = (FastRandom()&1023)-512; |
| | 3175 | particlePtr->LifeTime = 100*ONE_FIXED; |
| | 3176 | particlePtr->ParticleID = PARTICLE_WATERFALLSPRAY; |
| | 3177 | particlePtr->Colour = RGBA_MAKE ( particleDescPtr->RedScale[PlayerStatus.VisionMode], |
| | 3178 | particleDescPtr->GreenScale[PlayerStatus.VisionMode], |
| | 3179 | particleDescPtr->BlueScale[PlayerStatus.VisionMode], |
| | 3180 | particleDescPtr->Alpha); |
| | 3181 | particlePtr->Size = 20; |
| | 3182 | } |
| | 3183 | else |
| | 3184 | { |
| | 3185 | particlePtr->LifeTime -= NormalFrameTime; |
| | 3186 | } |
| | 3187 | |
| | 3188 | { |
| | 3189 | particlePtr->Position.vx += MUL_FIXED(particlePtr->Velocity.vx,NormalFrameTime); |
| | 3190 | particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy,NormalFrameTime); |
| | 3191 | particlePtr->Position.vz += MUL_FIXED(particlePtr->Velocity.vz,NormalFrameTime); |
| | 3192 | particlePtr->Offset.vx = particlePtr->Position.vx - particlePtr->Velocity.vx/16; |
| | 3193 | particlePtr->Offset.vy = particlePtr->Position.vy - particlePtr->Velocity.vy/16; |
| | 3194 | particlePtr->Offset.vz = particlePtr->Position.vz - particlePtr->Velocity.vz/16; |
| | 3195 | |
| | 3196 | RenderParticle(particlePtr); |
| | 3197 | } |
| | 3198 | } |
| | 3199 | } |
| | 3200 | |
| | 3201 | int EffectOfRipples(VECTORCH *point) |
| | 3202 | { |
| | 3203 | int i; |
| | 3204 | int offset = GetSin((point->vx+point->vz+CloakingPhase)&4095)>>11; |
| | 3205 | offset += GetSin((point->vx-point->vz*2+CloakingPhase/2)&4095)>>12; |
| | 3206 | |
| | 3207 | for(i=0; i < MAX_NO_OF_RIPPLES; i++) |
| | 3208 | { |
| | 3209 | if (RippleStorage[i].Active) |
| | 3210 | { |
| | 3211 | int dx = point->vx - RippleStorage[i].X; |
| | 3212 | int dz = point->vz - RippleStorage[i].Z; |
| | 3213 | |
| | 3214 | if (dx < 0) |
| | 3215 | dx = -dx; |
| | 3216 | if (dz < 0) |
| | 3217 | dz = -dz; |
| | 3218 | |
| | 3219 | { |
| | 3220 | int a; |
| | 3221 | |
| | 3222 | if (dx > dz) |
| | 3223 | a = dx + (dz >> 1); |
| | 3224 | else |
| | 3225 | a = dz + (dx >> 1); |
| | 3226 | |
| | 3227 | if (a < RippleStorage[i].Radius) |
| | 3228 | { |
| | 3229 | a = MUL_FIXED(a, RippleStorage[i].InvRadius); |
| | 3230 | |
| | 3231 | offset += MUL_FIXED(RippleStorage[i].Amplitude, GetSin(a)); |
| | 3232 | } |
| | 3233 | } |
| | 3234 | } |
| | 3235 | } |
| | 3236 | |
| | 3237 | if (offset > 256) |
| | 3238 | offset = 256; |
| | 3239 | else if (offset < -256) |
| | 3240 | offset = -256; |
| | 3241 | |
| | 3242 | return offset; |
| | 3243 | } |
| | 3244 | |
| | 3245 | void CheckForObjectsInWater(int minX, int maxX, int minZ, int maxZ, int averageY) |
| | 3246 | { |
| | 3247 | int i; |
| | 3248 | //printf("ACTIVE OBJCE %d\n", NumActiveBlocks); |
| | 3249 | for(i = 0; i < NumActiveBlocks; ++i) |
| | 3250 | { |
| | 3251 | DISPLAYBLOCK* objectPtr = ActiveBlockList[i]; |
| | 3252 | |
| | 3253 | if(objectPtr->ObStrategyBlock) |
| | 3254 | { |
| | 3255 | DYNAMICSBLOCK *dynPtr = objectPtr->ObStrategyBlock->DynPtr; |
| | 3256 | |
| | 3257 | if (dynPtr) |
| | 3258 | { |
| | 3259 | int overlapInY; |
| | 3260 | int overlapInX; |
| | 3261 | int overlapInZ; |
| | 3262 | |
| | 3263 | /* floating objects are ignored to avoid positive feedback */ |
| | 3264 | if(!DynamicObjectIsMoving(dynPtr) || dynPtr->IsFloating) |
| | 3265 | continue; |
| | 3266 | |
| | 3267 | if (dynPtr->Position.vy > dynPtr->PrevPosition.vy) |
| | 3268 | { |
| | 3269 | overlapInY = ((dynPtr->Position.vy + objectPtr->extent.radius > averageY) && (dynPtr->PrevPosition.vy -
objectPtr->extent.radius < averageY)); |
| | 3270 | } |
| | 3271 | else |
| | 3272 | { |
| | 3273 | overlapInY = ((dynPtr->PrevPosition.vy + objectPtr->extent.radius > averageY) && (dynPtr->Position.vy -
objectPtr->extent.radius < averageY)); |
| | 3274 | } |
| | 3275 | |
| | 3276 | if (!overlapInY) continue; |
| | 3277 | |
| | 3278 | if (dynPtr->Position.vx > dynPtr->PrevPosition.vx) |
| | 3279 | { |
| | 3280 | overlapInX = ((dynPtr->Position.vx + objectPtr->extent.radius > minX) && (dynPtr->PrevPosition.vx -
objectPtr->extent.radius < maxX)); |
| | 3281 | } |
| | 3282 | else |
| | 3283 | { |
| | 3284 | overlapInX = ((dynPtr->PrevPosition.vx + objectPtr->extent.radius > minX) && (dynPtr->Position.vx -
objectPtr->extent.radius < maxX)); |
| | 3285 | } |
| | 3286 | |
| | 3287 | if (!overlapInX) continue; |
| | 3288 | |
| | 3289 | if (dynPtr->Position.vz > dynPtr->PrevPosition.vz) |
| | 3290 | { |
| | 3291 | overlapInZ = ((dynPtr->Position.vz + objectPtr->extent.radius > minZ) && (dynPtr->PrevPosition.vz -
objectPtr->extent.radius < maxZ)); |
| | 3292 | } |
| | 3293 | else |
| | 3294 | { |
| | 3295 | overlapInZ = ((dynPtr->PrevPosition.vz + objectPtr->extent.radius > minZ) && (dynPtr->Position.vz -
objectPtr->extent.radius < maxZ)); |
| | 3296 | } |
| | 3297 | |
| | 3298 | if (!overlapInZ) continue; |
| | 3299 | |
| | 3300 | //if (!overlapInY && !overlapInX && !overlapInZ) continue; |
| | 3301 | //puts(" OVERLAP "); |
| | 3302 | /* we have an overlap */ |
| | 3303 | |
| | 3304 | switch(objectPtr->ObStrategyBlock->type) |
| | 3305 | { |
| | 3306 | case I_BehaviourFlare: |
| | 3307 | { |
| | 3308 | VECTORCH upwards = {0, -65536, 0}; |
| | 3309 | dynPtr->IsFloating = 1; |
| | 3310 | dynPtr->GravityOn = 0; |
| | 3311 | dynPtr->Elasticity = 0; |
| | 3312 | MakeMatrixFromDirection(&upwards, &dynPtr->OrientMat); |
| | 3313 | } |
| | 3314 | break; |
| | 3315 | case I_BehaviourPredatorPlayer: |
| | 3316 | { |
| | 3317 | PlayerStatus.CloakingEffectiveness -= NormalFrameTime / 4; |
| | 3318 | |
| | 3319 | if(PlayerStatus.CloakingEffectiveness < 0) |
| | 3320 | PlayerStatus.CloakingEffectiveness = 0; |
| | 3321 | } // no break |
| | 3322 | case I_BehaviourAlienPlayer: |
| | 3323 | case I_BehaviourMarinePlayer: |
| | 3324 | { |
| | 3325 | if(SOUND_NOACTIVEINDEX == PlayerStatus.sound_watersplash) |
| | 3326 | { |
| | 3327 | switch (FastRandom() & 3) |
| | 3328 | { |
| | 3329 | case 0: |
| | 3330 | Sound_Play(SID_SPLASH1, "de", &dynPtr->Position, &PlayerStatus.sound_watersplash); |
| | 3331 | break; |
| | 3332 | case 1: |
| | 3333 | Sound_Play(SID_SPLASH2, "de", &dynPtr->Position, &PlayerStatus.sound_watersplash); |
| | 3334 | break; |
| | 3335 | case 2: |
| | 3336 | Sound_Play(SID_SPLASH3, "de", &dynPtr->Position, &PlayerStatus.sound_watersplash); |
| | 3337 | break; |
| | 3338 | default: |
| | 3339 | Sound_Play(SID_SPLASH4, "de", &dynPtr->Position, &PlayerStatus.sound_watersplash); |
| | 3340 | } |
| | 3341 | //printf("playing water splash %d\n", random()); |
| | 3342 | } |
| | 3343 | PlayerStatus.Noise = 1; |
| | 3344 | |
| | 3345 | if (PlayerStatus.sbptr->DamageBlock.IsOnFire) |
| | 3346 | Sound_Stop(PlayerStatus.soundCracklingFire); |
| | 3347 | } |
| | 3348 | default: |
| | 3349 | break; |
| | 3350 | } |
| | 3351 | |
| | 3352 | /* KJL 16:37:29 27/08/98 - if object is on fire its now put out */ |
| | 3353 | objectPtr->ObStrategyBlock->DamageBlock.IsOnFire = 0; |
| | 3354 | |
| | 3355 | AddRipple(dynPtr->Position.vx, dynPtr->Position.vz, 100); |
| | 3356 | } |
| | 3357 | } |
| | 3358 | } |
| | 3359 | } |
| | 3360 | |
| | 3361 | void MakeFlareParticle(DYNAMICSBLOCK *dynPtr) |
| | 3362 | { |
| | 3363 | VECTORCH velocity; |
| | 3364 | velocity.vx = ((FastRandom()&2047) - 1024); |
| | 3365 | velocity.vy = ((FastRandom()&2047) - 1024); |
| | 3366 | velocity.vz = (1000+(FastRandom()&255))*2; |
| | 3367 | RotateVector(&velocity, &dynPtr->OrientMat); |
| | 3368 | MakeParticle(&dynPtr->Position, &velocity, PARTICLE_FLARESMOKE); |
| | 3369 | } |
| | 3370 | |
| | 3371 | void MakeRocketTrailParticles(VECTORCH *prevPositionPtr, VECTORCH *positionPtr) |
| | 3372 | { |
| | 3373 | VECTORCH disp; |
| | 3374 | |
| | 3375 | disp.vx = positionPtr->vx - prevPositionPtr->vx; |
| | 3376 | disp.vy = positionPtr->vy - prevPositionPtr->vy; |
| | 3377 | disp.vz = positionPtr->vz - prevPositionPtr->vz; |
| | 3378 | |
| | 3379 | if (disp.vx || disp.vy || disp.vz) |
| | 3380 | { |
| | 3381 | int i = 1; |
| | 3382 | //int i = 16; |
| | 3383 | //do |
| | 3384 | { |
| | 3385 | VECTORCH position; |
| | 3386 | VECTORCH velocity; |
| | 3387 | velocity.vx = (FastRandom()&1023) - 512; |
| | 3388 | velocity.vy = (FastRandom()&1023) - 512; |
| | 3389 | velocity.vz = (FastRandom()&1023) - 512; |
| | 3390 | |
| | 3391 | position.vx = prevPositionPtr->vx + (disp.vx*i)/16; |
| | 3392 | position.vy = prevPositionPtr->vy + (disp.vy*i)/16; |
| | 3393 | position.vz = prevPositionPtr->vz + (disp.vz*i)/16; |
| | 3394 | |
| | 3395 | MakeParticle(&position, &velocity, PARTICLE_BLACKSMOKE); |
| | 3396 | |
| | 3397 | }// while(i--); |
| | 3398 | } |
| | 3399 | } |
| | 3400 | |
| | 3401 | void MakeGrenadeTrailParticles(VECTORCH *prevPositionPtr, VECTORCH *positionPtr) |
| | 3402 | { |
| | 3403 | VECTORCH disp; |
| | 3404 | |
| | 3405 | disp.vx = positionPtr->vx - prevPositionPtr->vx; |
| | 3406 | disp.vy = positionPtr->vy - prevPositionPtr->vy; |
| | 3407 | disp.vz = positionPtr->vz - prevPositionPtr->vz; |
| | 3408 | |
| | 3409 | if (disp.vx || disp.vy || disp.vz) |
| | 3410 | { |
| | 3411 | int i = 8; |
| | 3412 | do |
| | 3413 | { |
| | 3414 | VECTORCH position; |
| | 3415 | VECTORCH velocity; |
| | 3416 | velocity.vx = (FastRandom()&1023) - 512; |
| | 3417 | velocity.vy = (FastRandom()&1023) - 512; |
| | 3418 | velocity.vz = (FastRandom()&1023) - 512; |
| | 3419 | |
| | 3420 | position.vx = prevPositionPtr->vx + (disp.vx*i)/16; |
| | 3421 | position.vy = prevPositionPtr->vy + (disp.vy*i)/16; |
| | 3422 | position.vz = prevPositionPtr->vz + (disp.vz*i)/16; |
| | 3423 | |
| | 3424 | MakeParticle(&position, &velocity, PARTICLE_FLARESMOKE); |
| | 3425 | |
| | 3426 | } while(i--); |
| | 3427 | } |
| | 3428 | } |
| | 3429 | |
| | 3430 | void MakeImpactSmoke(MATRIXCH *orientationPtr, VECTORCH *positionPtr) |
| | 3431 | { |
| | 3432 | //int i = 5; |
| | 3433 | //while(i--) |
| | 3434 | { |
| | 3435 | VECTORCH velocity; |
| | 3436 | velocity.vx = ((FastRandom() & 1023) - 512); |
| | 3437 | velocity.vy = ((FastRandom() & 1023) - 512); |
| | 3438 | velocity.vz = (255+ (FastRandom() & 255)); |
| | 3439 | RotateVector(&velocity, orientationPtr); |
| | 3440 | MakeParticle(positionPtr, &velocity, PARTICLE_IMPACTSMOKE); |
| | 3441 | } |
| | 3442 | } |
| | 3443 | |
| | 3444 | static void MakeRicochetSound(VECTORCH *position) |
| | 3445 | { |
| | 3446 | switch(NormalFrameTime & 0x3) |
| | 3447 | { |
| | 3448 | case 0: |
| | 3449 | Sound_Play(SID_RICOCH1, "pd", ((FastRandom()&255)-128),position); |
| | 3450 | break; |
| | 3451 | case 1: |
| | 3452 | Sound_Play(SID_RICOCH2, "pd", ((FastRandom()&255)-128),position); |
| | 3453 | break; |
| | 3454 | case 2: |
| | 3455 | Sound_Play(SID_RICOCH3, "pd", ((FastRandom()&255)-128),position); |
| | 3456 | break; |
| | 3457 | case 3: |
| | 3458 | Sound_Play(SID_RICOCH4, "pd", ((FastRandom()&255)-128),position); |
| | 3459 | default: |
| | 3460 | break; |
| | 3461 | } |
| | 3462 | } |
| | 3463 | |
| | 3464 | void MakeImpactSparks(VECTORCH *incidentPtr, VECTORCH *normalPtr, VECTORCH *positionPtr) |
| | 3465 | { |
| | 3466 | int noOfSparks = 5; |
| | 3467 | |
| | 3468 | VECTORCH velocity; |
| | 3469 | int d = -2 * DotProduct(incidentPtr, normalPtr); |
| | 3470 | velocity.vx = (incidentPtr->vx + MUL_FIXED(d, normalPtr->vx)) >> 3; |
| | 3471 | velocity.vy = (incidentPtr->vy + MUL_FIXED(d, normalPtr->vy)) >> 3; |
| | 3472 | velocity.vz = (incidentPtr->vz + MUL_FIXED(d, normalPtr->vz)) >> 3; |
| | 3473 | |
| | 3474 | do |
| | 3475 | { |
| | 3476 | velocity.vx = velocity.vx + (FastRandom() & 2047) - 1024; |
| | 3477 | velocity.vy = velocity.vy + (FastRandom() & 2047) - 1024; |
| | 3478 | velocity.vz = velocity.vz + (FastRandom() & 2047) - 1024; |
| | 3479 | MakeParticle(positionPtr, &velocity,PARTICLE_RICOCHET_SPARK); |
| | 3480 | |
| | 3481 | } while(--noOfSparks); |
| | 3482 | |
| | 3483 | MakeRicochetSound(positionPtr); |
| | 3484 | } |
| | 3485 | |
| | 3486 | void MakeSprayOfSparks(MATRIXCH *orientationPtr, VECTORCH *positionPtr) |
| | 3487 | { |
| | 3488 | int noOfSparks = 15; |
| | 3489 | |
| | 3490 | do |
| | 3491 | { |
| | 3492 | VECTORCH velocity; |
| | 3493 | velocity.vx = (FastRandom()&2047)-1024; |
| | 3494 | velocity.vy = (FastRandom()&2047); |
| | 3495 | velocity.vz = -(FastRandom()&2047)-1024; |
| | 3496 | RotateVector(&velocity, orientationPtr); |
| | 3497 | MakeParticle(positionPtr, &velocity, PARTICLE_SPARK); |
| | 3498 | |
| | 3499 | } while(--noOfSparks); |
| | 3500 | |
| | 3501 | MakeLightElement(positionPtr, LIGHTELEMENT_ELECTRICAL_SPARKS); |
| | 3502 | } |
| | 3503 | |
| | 3504 | void MakeMolotovExplosionAt(VECTORCH *positionPtr) |
| | 3505 | { |
| | 3506 | /* KJL 11:49:25 19/08/98 - check to see if explosion is inside environment */ |
| | 3507 | if (ModuleFromPosition(positionPtr, NULL)) |
| | 3508 | { |
| | 3509 | int i = 0; |
| | 3510 | int seed = 0; |
| | 3511 | |
| | 3512 | //need to get a random number seed for this explosion |
| | 3513 | while(!seed) |
| | 3514 | seed = FastRandom(); |
| | 3515 | |
| | 3516 | SetSeededFastRandom(seed); |
| | 3517 | |
| | 3518 | for (; i < 100; i++) |
| | 3519 | { |
| | 3520 | VECTORCH velocity; |
| | 3521 | int phi = SeededFastRandom()&4095; |
| | 3522 | |
| | 3523 | velocity.vy = -(SeededFastRandom()&65535); |
| | 3524 | { |
| | 3525 | float y = ((float)velocity.vy)/65536.0; |
| | 3526 | y = sqrt(1-y*y); |
| | 3527 | |
| | 3528 | velocity.vx = ((float)GetCos(phi) * y); |
| | 3529 | velocity.vz = ((float)GetSin(phi) * y); |
| | 3530 | } |
| | 3531 | velocity.vx /= 8; |
| | 3532 | velocity.vy /= 16; |
| | 3533 | velocity.vz /= 8; |
| | 3534 | |
| | 3535 | MakeParticle(positionPtr, &velocity, PARTICLE_MOLOTOVFLAME); |
| | 3536 | } |
| | 3537 | } |
| | 3538 | } |
| | 3539 | |
| | 3540 | void MakeElectricalExplosion(const VECTORCH *positionPtr) |
| | 3541 | { |
| | 3542 | Sound_Play(SID_PRED_PISTOL_EXPLOSION, "d", positionPtr); |
| | 3543 | MakeParticle(positionPtr, positionPtr, PARTICLE_ELECTRICALPLASMASPHERE); |
| | 3544 | MakeLightElement(positionPtr, LIGHTELEMENT_ELECTRICAL_EXPLOSION); |
| | 3545 | |
| | 3546 | //if(SinglePlayer != AvP.PlayMode) AddNetMsg_MakeExplosion(centrePtr, EXPLOSION_PREDATORPISTOL); |
| | 3547 | } |
| | 3548 | |
| | 3549 | void MakeVolumetricExplosionAt(VECTORCH *positionPtr, enum EXPLOSION_ID explosionID) |
| | 3550 | { |
| | 3551 | /* KJL 11:49:25 19/08/98 - check to see if explosion is inside environment */ |
| | 3552 | |
| | 3553 | if(ModuleFromPosition(positionPtr, NULL)) |
| | 3554 | { |
| | 3555 | unsigned int i; |
| | 3556 | struct VOLUMETRIC_EXPLOSION *expPtr = AllocateVolumetricExplosion(); |
| | 3557 | |
| | 3558 | for(i=0; i < SPHERE_VERTICES; i++) |
| | 3559 | { |
| | 3560 | expPtr->Position[i] = *positionPtr; |
| | 3561 | expPtr->Velocity[i].vx = SphereVertex[i].vx; |
| | 3562 | expPtr->Velocity[i].vy = SphereVertex[i].vy; |
| | 3563 | expPtr->Velocity[i].vz = SphereVertex[i].vz; |
| | 3564 | expPtr->BeenStopped[i] = 0; |
| | 3565 | expPtr->RipplePhase[i] = FastRandom() & 4095; |
| | 3566 | expPtr->NumberVerticesMoving = SPHERE_VERTICES; |
| | 3567 | } |
| | 3568 | |
| | 3569 | if ((positionPtr->vx != PlayerStatus.DisplayBlock->ObWorld.vx) |
| | 3570 | || (positionPtr->vy != PlayerStatus.DisplayBlock->ObWorld.vy) |
| | 3571 | || (positionPtr->vz != PlayerStatus.DisplayBlock->ObWorld.vz)) |
| | 3572 | MakeLightElement(positionPtr, LIGHTELEMENT_EXPLOSION); |
| | 3573 | |
| | 3574 | switch (explosionID) |
| | 3575 | { |
| | 3576 | case EXPLOSION_SADAR_BLAST: |
| | 3577 | { |
| | 3578 | expPtr->UseCollisions = 1; |
| | 3579 | expPtr->LifeTime = ONE_FIXED-1;// + 20000; |
| | 3580 | |
| | 3581 | for (i=0; i < LocalDetailLevels.NumberOfSmokeParticlesFromLargeExplosion; i++) |
| | 3582 | { |
| | 3583 | VECTORCH position = *positionPtr; |
| | 3584 | position.vx += (FastRandom() & 2047) - 1024; |
| | 3585 | position.vy += (FastRandom() & 2047) - 1024; |
| | 3586 | position.vz += (FastRandom() & 2047) - 1024; |
| | 3587 | MakeParticle(&position, positionPtr, PARTICLE_SMOKECLOUD); |
| | 3588 | } |
| | 3589 | } |
| | 3590 | break; |
| | 3591 | case EXPLOSION_GRENADE_BLAST: |
| | 3592 | case EXPLOSION_GRENADE_NOCOLLISIONS: |
| | 3593 | { |
| | 3594 | expPtr->UseCollisions = (EXPLOSION_GRENADE_BLAST == explosionID); |
| | 3595 | expPtr->LifeTime = ONE_FIXED-1; |
| | 3596 | |
| | 3597 | for (i=0; i < LocalDetailLevels.NumberOfSmokeParticlesFromLargeExplosion; i++) |
| | 3598 | { |
| | 3599 | VECTORCH position = *positionPtr; |
| | 3600 | position.vx += (FastRandom() & 2047) - 1024; |
| | 3601 | position.vy += (FastRandom() & 2047) - 1024; |
| | 3602 | position.vz += (FastRandom() & 2047) - 1024; |
| | 3603 | MakeParticle(&position, positionPtr, PARTICLE_SMOKECLOUD); |
| | 3604 | } |
| | 3605 | } |
| | 3606 | break; |
| | 3607 | case EXPLOSION_PULSEGRENADE: |
| | 3608 | case EXPLOSION_SMALL_NOCOLLISIONS: |
| | 3609 | { |
| | 3610 | expPtr->UseCollisions = (EXPLOSION_PULSEGRENADE == explosionID); |
| | 3611 | expPtr->LifeTime = ONE_FIXED/2; |
| | 3612 | |
| | 3613 | i = LocalDetailLevels.NumberOfSmokeParticlesFromSmallExplosion; |
| | 3614 | |
| | 3615 | for (i=0; i < LocalDetailLevels.NumberOfSmokeParticlesFromSmallExplosion; i++) |
| | 3616 | { |
| | 3617 | VECTORCH position = *positionPtr; |
| | 3618 | position.vx += (FastRandom() & 1023)-512; |
| | 3619 | position.vy += (FastRandom() & 1023)-512; |
| | 3620 | position.vz += (FastRandom() & 1023)-512; |
| | 3621 | MakeParticle(&position, positionPtr, PARTICLE_SMOKECLOUD); |
| | 3622 | } |
| | 3623 | } |
| | 3624 | default: |
| | 3625 | return; |
| | 3626 | } |
| | 3627 | |
| | 3628 | //if(SinglePlayer != AvP.PlayMode) AddNetMsg_MakeExplosion(positionPtr, explosionID); |
| | 3629 | } |
| | 3630 | } |
| | 3631 | |
| | 3632 | void MakeFlechetteExplosionAt(VECTORCH *positionPtr, int seed) |
| | 3633 | { |
| | 3634 | extern SOUND3DDATA Explosion_SoundData; |
| | 3635 | int i; |
| | 3636 | enum PARTICLE_ID particle_to_use; |
| | 3637 | |
| | 3638 | Explosion_SoundData.position = *positionPtr; |
| | 3639 | Sound_Play(SID_FRAG_RICOCHETS, "n", &Explosion_SoundData); |
| | 3640 | |
| | 3641 | if(!seed) |
| | 3642 | { |
| | 3643 | //need to get a random number seed for this explosion |
| | 3644 | while(!seed) |
| | 3645 | seed = FastRandom(); |
| | 3646 | |
| | 3647 | //explosion originated on this computer , so use damaging type |
| | 3648 | particle_to_use = PARTICLE_FLECHETTE; |
| | 3649 | |
| | 3650 | //if in a network game , send explosion to other players |
| | 3651 | if(SinglePlayer != AvP.PlayMode) |
| | 3652 | AddNetMsg_MakeFlechetteExplosion(positionPtr, seed); |
| | 3653 | } |
| | 3654 | else |
| | 3655 | { |
| | 3656 | //explosion passed across the network |
| | 3657 | //use the nondamaging flechette |
| | 3658 | particle_to_use = PARTICLE_FLECHETTE_NONDAMAGING; |
| | 3659 | } |
| | 3660 | |
| | 3661 | SetSeededFastRandom(seed); |
| | 3662 | |
| | 3663 | /* KJL 11:49:25 19/08/98 - check to see if explosion is inside environment */ |
| | 3664 | if (ModuleFromPosition(positionPtr, NULL)) |
| | 3665 | { |
| | 3666 | for (i=0; i < 100; i++) |
| | 3667 | { |
| | 3668 | VECTORCH velocity; |
| | 3669 | int phi = SeededFastRandom() & 4095; |
| | 3670 | |
| | 3671 | velocity.vy = -(SeededFastRandom() & 65535); |
| | 3672 | |
| | 3673 | { |
| | 3674 | float y = ((float)velocity.vy)/65536.0; |
| | 3675 | y = sqrt(1-y*y); |
| | 3676 | |
| | 3677 | velocity.vx = ((float)GetCos(phi) * y); |
| | 3678 | velocity.vz = ((float)GetSin(phi) * y); |
| | 3679 | } |
| | 3680 | |
| | 3681 | MakeParticle(positionPtr, &velocity, particle_to_use); |
| | 3682 | } |
| | 3683 | |
| | 3684 | MakeLightElement(positionPtr, LIGHTELEMENT_EXPLOSION); |
| | 3685 | } |
| | 3686 | } |
| | 3687 | |
| | 3688 | void MakeFocusedExplosion(VECTORCH *originPtr, VECTORCH *blastPositionPtr, int noOfParticles, enum PARTICLE_ID particleID) |
| | 3689 | { |
| | 3690 | VECTORCH blastDir; |
| | 3691 | int i; |
| | 3692 | |
| | 3693 | blastDir.vx = originPtr->vx - blastPositionPtr->vx; |
| | 3694 | blastDir.vy = originPtr->vy - blastPositionPtr->vy; |
| | 3695 | blastDir.vz = originPtr->vz - blastPositionPtr->vz; |
| | 3696 | |
| | 3697 | for (i=0; i < noOfParticles; i++) |
| | 3698 | { |
| | 3699 | VECTORCH velocity,position; |
| | 3700 | int phi = FastRandom() & 4095; |
| | 3701 | int speed = FastRandom() & 2047; |
| | 3702 | |
| | 3703 | velocity.vz = (FastRandom() & 131071) - ONE_FIXED; |
| | 3704 | { |
| | 3705 | float z = ((float)velocity.vz)/65536.0; |
| | 3706 | z = sqrt(1-z*z); |
| | 3707 | |
| | 3708 | velocity.vx = ((float)GetCos(phi) * z); |
| | 3709 | velocity.vy = ((float)GetSin(phi) * z); |
| | 3710 | } |
| | 3711 | |
| | 3712 | if (DotProduct(&velocity,&blastDir) < 0) |
| | 3713 | { |
| | 3714 | velocity.vx = -velocity.vx; |
| | 3715 | velocity.vy = -velocity.vy; |
| | 3716 | velocity.vz = -velocity.vz; |
| | 3717 | } |
| | 3718 | |
| | 3719 | int r = FastRandom() % 127; |
| | 3720 | position.vx = originPtr->vx + MUL_FIXED(velocity.vx,r); |
| | 3721 | position.vy = originPtr->vy + MUL_FIXED(velocity.vy,r); |
| | 3722 | position.vz = originPtr->vz + MUL_FIXED(velocity.vz,r); |
| | 3723 | |
| | 3724 | velocity.vx = MUL_FIXED(velocity.vx, speed); |
| | 3725 | velocity.vy = MUL_FIXED(velocity.vy, speed); |
| | 3726 | velocity.vz = MUL_FIXED(velocity.vz, speed); |
| | 3727 | |
| | 3728 | MakeParticle(&position, &velocity, particleID); |
| | 3729 | } |
| | 3730 | } |
| | 3731 | |
| | 3732 | void MakeBloodExplosion(VECTORCH *originPtr, int creationRadius, VECTORCH *blastPositionPtr, int noOfParticles, enum PARTICLE_ID particleID) |
| | 3733 | { |
| | 3734 | VECTORCH blastDir; |
| | 3735 | int i; |
| | 3736 | |
| | 3737 | blastDir.vx = originPtr->vx - blastPositionPtr->vx; |
| | 3738 | blastDir.vy = originPtr->vy - blastPositionPtr->vy; |
| | 3739 | blastDir.vz = originPtr->vz - blastPositionPtr->vz; |
| | 3740 | |
| | 3741 | for (i=0; i < noOfParticles; i++) |
| | 3742 | { |
| | 3743 | VECTORCH velocity; |
| | 3744 | VECTORCH position; |
| | 3745 | int phi = FastRandom()&4095; |
| | 3746 | int speed = 6000+(FastRandom()&4095); |
| | 3747 | int r; |
| | 3748 | //speed = FastRandom()&2047; |
| | 3749 | |
| | 3750 | velocity.vz = (FastRandom()&131071) - ONE_FIXED; |
| | 3751 | { |
| | 3752 | float z = ((float)velocity.vz)/65536.0; |
| | 3753 | z = sqrt(1-z*z); |
| | 3754 | |
| | 3755 | velocity.vx = ((float)GetCos(phi) * z); |
| | 3756 | velocity.vy = ((float)GetSin(phi) * z); |
| | 3757 | } |
| | 3758 | |
| | 3759 | if (DotProduct(&velocity, &blastDir) < 0) |
| | 3760 | { |
| | 3761 | velocity.vx = -velocity.vx; |
| | 3762 | velocity.vy = -velocity.vy; |
| | 3763 | velocity.vz = -velocity.vz; |
| | 3764 | } |
| | 3765 | |
| | 3766 | r = FastRandom() % creationRadius; |
| | 3767 | position.vx = originPtr->vx + MUL_FIXED(velocity.vx,r); |
| | 3768 | position.vy = originPtr->vy + MUL_FIXED(velocity.vy,r); |
| | 3769 | position.vz = originPtr->vz + MUL_FIXED(velocity.vz,r); |
| | 3770 | |
| | 3771 | velocity.vx = MUL_FIXED(velocity.vx,speed); |
| | 3772 | velocity.vy = MUL_FIXED(velocity.vy,speed); |
| | 3773 | velocity.vz = MUL_FIXED(velocity.vz,speed); |
| | 3774 | |
| | 3775 | MakeBloodParticle(&position, &velocity, particleID); |
| | 3776 | } |
| | 3777 | } |
| | 3778 | |
| | 3779 | void MakePlasmaExplosion(VECTORCH *positionPtr, VECTORCH *fromPositionPtr, enum EXPLOSION_ID explosionID) |
| | 3780 | { |
| | 3781 | if(EXPLOSION_DISSIPATINGPLASMA == explosionID) |
| | 3782 | { |
| | 3783 | MakeLightElement(positionPtr, LIGHTELEMENT_PLASMACASTERHIT); |
| | 3784 | //MakeBloodExplosion(fromPositionPtr, 127, positionPtr, 200, PARTICLE_ORANGE_SPARK); |
| | 3785 | MakeFocusedExplosion(fromPositionPtr, positionPtr, 200, PARTICLE_ORANGE_SPARK); |
| | 3786 | Sound_Play(SID_PLASMABOLT_DISSIPATE, "d", positionPtr); |
| | 3787 | } |
| | 3788 | else // should be EXPLOSION_FOCUSEDPLASMA |
| | 3789 | { |
| | 3790 | MakeLightElement(positionPtr, LIGHTELEMENT_PLASMACASTERHIT); |
| | 3791 | MakeFocusedExplosion(fromPositionPtr, positionPtr, 100, PARTICLE_ORANGE_PLASMA); |
| | 3792 | Sound_Play(SID_PLASMABOLT_HIT, "d", positionPtr); |
| | 3793 | } |
| | 3794 | } |
| | 3795 | |
| | 3796 | void MakePlasmaTrailParticles(DYNAMICSBLOCK *dynPtr, int number) |
| | 3797 | { |
| | 3798 | VECTORCH disp; |
| | 3799 | |
| | 3800 | disp.vx = dynPtr->Position.vx - dynPtr->PrevPosition.vx; |
| | 3801 | disp.vy = dynPtr->Position.vy - dynPtr->PrevPosition.vy; |
| | 3802 | disp.vz = dynPtr->Position.vz - dynPtr->PrevPosition.vz; |
| | 3803 | |
| | 3804 | int i = number; |
| | 3805 | do |
| | 3806 | { |
| | 3807 | VECTORCH velocity; |
| | 3808 | VECTORCH position; |
| | 3809 | int phi = FastRandom()&4095; |
| | 3810 | int speed = 512; |
| | 3811 | |
| | 3812 | velocity.vz = (FastRandom() & 131071) - ONE_FIXED; |
| | 3813 | |
| | 3814 | { |
| | 3815 | float z = ((float)velocity.vz)/65536.0; |
| | 3816 | z = sqrt(1-z*z); |
| | 3817 | |
| | 3818 | velocity.vx = ((float)GetCos(phi) * z); |
| | 3819 | velocity.vy = ((float)GetSin(phi) * z); |
| | 3820 | } |
| | 3821 | |
| | 3822 | velocity.vx = MUL_FIXED(velocity.vx, speed);//+dynPtr->LinVelocity.vx/32; |
| | 3823 | velocity.vy = MUL_FIXED(velocity.vy, speed);//+dynPtr->LinVelocity.vy/32; |
| | 3824 | velocity.vz = MUL_FIXED(velocity.vz, speed);//+dynPtr->LinVelocity.vz/32; |
| | 3825 | position.vx = dynPtr->PrevPosition.vx + (disp.vx*i) / number; |
| | 3826 | position.vy = dynPtr->PrevPosition.vy + (disp.vy*i) / number; |
| | 3827 | position.vz = dynPtr->PrevPosition.vz + (disp.vz*i) / number; |
| | 3828 | |
| | 3829 | MakeParticle(&position, &velocity, PARTICLE_PLASMATRAIL); |
| | 3830 | |
| | 3831 | } while(i--); |
| | 3832 | } |
| | 3833 | |
| | 3834 | void MakeDewlineTrailParticles(DYNAMICSBLOCK *dynPtr, int number) |
| | 3835 | { |
| | 3836 | VECTORCH disp; |
| | 3837 | |
| | 3838 | disp.vx = dynPtr->Position.vx - dynPtr->PrevPosition.vx; |
| | 3839 | disp.vy = dynPtr->Position.vy - dynPtr->PrevPosition.vy; |
| | 3840 | disp.vz = dynPtr->Position.vz - dynPtr->PrevPosition.vz; |
| | 3841 | |
| | 3842 | // if (disp.vx!=0 || disp.vy!=0 || disp.vz!=0) |
| | 3843 | { |
| | 3844 | int i=number; |
| | 3845 | do |
| | 3846 | { |
| | 3847 | VECTORCH velocity; |
| | 3848 | VECTORCH position; |
| | 3849 | int phi = FastRandom()&4095; |
| | 3850 | int speed = 256; //512 |
| | 3851 | |
| | 3852 | velocity.vz = (FastRandom()&131071) - ONE_FIXED; |
| | 3853 | { |
| | 3854 | float z = ((float)velocity.vz)/65536.0; |
| | 3855 | z = sqrt(1-z*z); |
| | 3856 | |
| | 3857 | velocity.vx = ((float)GetCos(phi) * z); |
| | 3858 | velocity.vy = ((float)GetSin(phi) * z); |
| | 3859 | } |
| | 3860 | |
| | 3861 | velocity.vx = MUL_FIXED(velocity.vx,speed);//+dynPtr->LinVelocity.vx/32; |
| | 3862 | velocity.vy = MUL_FIXED(velocity.vy,speed);//+dynPtr->LinVelocity.vy/32; |
| | 3863 | velocity.vz = MUL_FIXED(velocity.vz,speed);//+dynPtr->LinVelocity.vz/32; |
| | 3864 | position.vx = dynPtr->PrevPosition.vx + (disp.vx*i)/number; |
| | 3865 | position.vy = dynPtr->PrevPosition.vy + (disp.vy*i)/number; |
| | 3866 | position.vz = dynPtr->PrevPosition.vz + (disp.vz*i)/number; |
| | 3867 | |
| | 3868 | MakeParticle(&position, &velocity, PARTICLE_DEWLINE); |
| | 3869 | |
| | 3870 | } while(i--); |
| | 3871 | } |
| | 3872 | } |
| | 3873 | |
| | 3874 | /* KJL 16:37:03 20/06/98 - stupid but quick implementation */ |
| | 3875 | #define NO_OF_VERTICES_IN_TRAIL 300 |
| | 3876 | PHEROMONE_TRAIL Trail[NO_OF_VERTICES_IN_TRAIL]; |
| | 3877 | |
| | 3878 | void NewTrailPoint(DYNAMICSBLOCK *dynPtr) |
| | 3879 | { |
| | 3880 | PHEROMONE_TRAIL *trailPtr = AllocatePheromoneTrail(); |
| | 3881 | |
| | 3882 | if (NULL != trailPtr) |
| | 3883 | { |
| | 3884 | assert(dynPtr); |
| | 3885 | trailPtr->Vertex[0] = dynPtr->Position; |
| | 3886 | // trailPtr->Vertex[0].vy -=1000; |
| | 3887 | |
| | 3888 | trailPtr->Perp[0] = *((VECTORCH*)&(dynPtr->OrientMat.mat11)); |
| | 3889 | trailPtr->Size[0] = 127*65536; |
| | 3890 | |
| | 3891 | trailPtr->Vertex[1] = dynPtr->PrevPosition; |
| | 3892 | // trailPtr->Vertex[1].vy -=1000; |
| | 3893 | trailPtr->Perp[1] = *((VECTORCH*)&(dynPtr->PrevOrientMat.mat11)); |
| | 3894 | trailPtr->Size[1] = 127*65536-MUL_FIXED(TRAIL_DECAY_SPEED,PrevNormalFrameTime); |
| | 3895 | } |
| | 3896 | } |
| | 3897 | |
| | 3898 | void PlayerPheromoneTrail(DYNAMICSBLOCK *dynPtr) |
| | 3899 | { |
| | 3900 | PHEROMONE_TRAIL *trailPtr = AllocatePheromoneTrail(); |
| | 3901 | |
| | 3902 | if (NULL != trailPtr) |
| | 3903 | { |
| | 3904 | VECTORCH disp; |
| | 3905 | disp.vx = dynPtr->Position.vx-dynPtr->PrevPosition.vx; |
| | 3906 | disp.vy = dynPtr->Position.vy-dynPtr->PrevPosition.vy; |
| | 3907 | disp.vz = dynPtr->Position.vz-dynPtr->PrevPosition.vz; |
| | 3908 | |
| | 3909 | trailPtr->Vertex[0] = dynPtr->Position; |
| | 3910 | trailPtr->Vertex[0].vx -= dynPtr->OrientMat.mat21>>6; |
| | 3911 | trailPtr->Vertex[0].vy -= dynPtr->OrientMat.mat22>>6; |
| | 3912 | trailPtr->Vertex[0].vz -= dynPtr->OrientMat.mat23>>6; |
| | 3913 | |
| | 3914 | trailPtr->Perp[0] = *((VECTORCH*) & dynPtr->OrientMat.mat11); |
| | 3915 | trailPtr->Size[0] = 127*65536*4; |
| | 3916 | |
| | 3917 | trailPtr->Vertex[1] = dynPtr->PrevPosition; |
| | 3918 | trailPtr->Vertex[1].vx -= dynPtr->PrevOrientMat.mat21 >> 6; |
| | 3919 | trailPtr->Vertex[1].vy -= dynPtr->PrevOrientMat.mat22 >> 6; |
| | 3920 | trailPtr->Vertex[1].vz -= dynPtr->PrevOrientMat.mat23 >> 6; |
| | 3921 | |
| | 3922 | trailPtr->Perp[1] = *((VECTORCH*)&dynPtr->PrevOrientMat.mat11); |
| | 3923 | trailPtr->Size[1] = 127*65536*4 - MUL_FIXED(TRAIL_DECAY_SPEED, PrevNormalFrameTime); |
| | 3924 | } |
| | 3925 | } |
| | 3926 | |
| | 3927 | void RenderParticlesInMirror() |
| | 3928 | { |
| | 3929 | int i = NumActiveParticles; |
| | 3930 | PARTICLE *particlePtr = ParticleStorage; |
| | 3931 | |
| | 3932 | DecalSystem_Setup(); |
| | 3933 | |
| | 3934 | while(i--) |
| | 3935 | { |
| | 3936 | switch(particlePtr->ParticleID) |
| | 3937 | { |
| | 3938 | case PARTICLE_FLARESMOKE: |
| | 3939 | case PARTICLE_STEAM: |
| | 3940 | case PARTICLE_BLACKSMOKE: |
| | 3941 | case PARTICLE_IMPACTSMOKE: |
| | 3942 | case PARTICLE_SMOKECLOUD: |
| | 3943 | particlePtr->Position.vx = MirroringAxis - particlePtr->Position.vx; |
| | 3944 | RenderParticle(particlePtr); |
| | 3945 | particlePtr->Position.vx = MirroringAxis - particlePtr->Position.vx; |
| | 3946 | default: |
| | 3947 | break; |
| | 3948 | } |
| | 3949 | particlePtr++; |
| | 3950 | } |
| | 3951 | |
| | 3952 | int numOfObjects = numVisObjs; |
| | 3953 | |
| | 3954 | while(numOfObjects--) |
| | 3955 | { |
| | 3956 | DISPLAYBLOCK *objectPtr = VisibleObjects[numOfObjects].DispPtr; |
| | 3957 | |
| | 3958 | if (objectPtr->SfxPtr) |
| | 3959 | DrawSfxObject(objectPtr); |
| | 3960 | } |
| | 3961 | |
| | 3962 | DecalSystem_End(); |
| | 3963 | } |
| | 3964 | |
| | 3965 | void TimeScaleThingy() |
| | 3966 | { |
| | 3967 | extern int TimeScale; |
| | 3968 | extern int RealFrameTime; |
| | 3969 | int DesiredTimeScale = ONE_FIXED; |
| | 3970 | int i = 0; |
| | 3971 | |
| | 3972 | for(; i < NumActiveBlocks; i++) |
| | 3973 | { |
| | 3974 | STRATEGYBLOCK* sbPtr = ActiveBlockList[i]->ObStrategyBlock; |
| | 3975 | |
| | 3976 | if(sbPtr) |
| | 3977 | { |
| | 3978 | switch(sbPtr->type) |
| | 3979 | { |
| | 3980 | case I_BehaviourAlien: |
| | 3981 | case I_BehaviourQueenAlien: |
| | 3982 | case I_BehaviourFaceHugger: |
| | 3983 | case I_BehaviourPredator: |
| | 3984 | case I_BehaviourXenoborg: |
| | 3985 | case I_BehaviourMarine: |
| | 3986 | case I_BehaviourAutoGun: |
| | 3987 | DesiredTimeScale = MUL_FIXED(DesiredTimeScale, ONE_FIXED*.8); |
| | 3988 | break; |
| | 3989 | case I_BehaviourGrenade: |
| | 3990 | case I_BehaviourRocket: |
| | 3991 | case I_BehaviourFrisbee: |
| | 3992 | case I_BehaviourPulseGrenade: |
| | 3993 | case I_BehaviourMolotov: |
| | 3994 | DesiredTimeScale = MUL_FIXED(DesiredTimeScale, ONE_FIXED*.7); |
| | 3995 | default: |
| | 3996 | break; |
| | 3997 | } |
| | 3998 | } |
| | 3999 | } |
| | 4000 | |
| | 4001 | for(i=0; i < CurrentExplosionIndex; i++) |
| | 4002 | DesiredTimeScale = MUL_FIXED(DesiredTimeScale, ONE_FIXED*.5); |
| | 4003 | |
| | 4004 | if(DesiredTimeScale < ONE_FIXED) |
| | 4005 | DesiredTimeScale = MUL_FIXED(DesiredTimeScale, ONE_FIXED*.8); |
| | 4006 | |
| | 4007 | if(DesiredTimeScale < ONE_FIXED/10) |
| | 4008 | DesiredTimeScale = ONE_FIXED/10; |
| | 4009 | |
| | 4010 | if(TimeScale < DesiredTimeScale) |
| | 4011 | { |
| | 4012 | TimeScale += RealFrameTime/8; |
| | 4013 | |
| | 4014 | if(TimeScale > DesiredTimeScale) |
| | 4015 | TimeScale = DesiredTimeScale; |
| | 4016 | } |
| | 4017 | else if (TimeScale > DesiredTimeScale) |
| | 4018 | { |
| | 4019 | TimeScale -= RealFrameTime; |
| | 4020 | |
| | 4021 | if(TimeScale < DesiredTimeScale) |
| | 4022 | TimeScale = DesiredTimeScale; |
| | 4023 | } |
| | 4024 | } |
| | 4025 | |
| | 4026 | /*----------------------** |
| | 4027 | ** Load/Save particles ** |
| | 4028 | **----------------------*/ |
| | 4029 | |
| | 4030 | typedef struct particle_save_block_header |
| | 4031 | { |
| | 4032 | SAVE_BLOCK_HEADER header; |
| | 4033 | |
| | 4034 | int NumActiveParticles; |
| | 4035 | int NumberOfBloodParticles; |
| | 4036 | |
| | 4037 | //followed by paricle array after this block |
| | 4038 | |
| | 4039 | } PARTICLE_SAVE_BLOCK_HEADER; |
| | 4040 | |
| | 4041 | void Load_Particles(SAVE_BLOCK_HEADER* header) |
| | 4042 | { |
| | 4043 | PARTICLE_SAVE_BLOCK_HEADER* block = (PARTICLE_SAVE_BLOCK_HEADER*) header; |
| | 4044 | PARTICLE* saved_particle = (PARTICLE*)(block+1); |
| | 4045 | int expected_size; |
| | 4046 | int i; |
| | 4047 | |
| | 4048 | //make sure the block is the correct size |
| | 4049 | expected_size = sizeof(*block); |
| | 4050 | expected_size += sizeof(PARTICLE) * block->NumActiveParticles; |
| | 4051 | if(header->size != expected_size) |
| | 4052 | return; |
| | 4053 | |
| | 4054 | //right copy the stuff then |
| | 4055 | NumActiveParticles = block->NumActiveParticles; |
| | 4056 | NumberOfBloodParticles = block->NumberOfBloodParticles; |
| | 4057 | |
| | 4058 | for(i=0; i < NumActiveParticles; i++) |
| | 4059 | ParticleStorage[i] = *saved_particle++; |
| | 4060 | } |
| | 4061 | |
| | 4062 | void Save_Particles() |
| | 4063 | { |
| | 4064 | PARTICLE_SAVE_BLOCK_HEADER* block; |
| | 4065 | |
| | 4066 | if(NumActiveParticles > 0) |
| | 4067 | { |
| | 4068 | int i; |
| | 4069 | //get memory for header |
| | 4070 | GET_SAVE_BLOCK_POINTER(block); |
| | 4071 | |
| | 4072 | //fill in header |
| | 4073 | block->header.type = SaveBlock_Particles; |
| | 4074 | block->header.size = sizeof(*block) + NumActiveParticles * sizeof(PARTICLE); |
| | 4075 | |
| | 4076 | block->NumActiveParticles = NumActiveParticles; |
| | 4077 | block->NumberOfBloodParticles = NumberOfBloodParticles; |
| | 4078 | |
| | 4079 | //now save the particles |
| | 4080 | for(i=0; i < NumActiveParticles; i++) |
| | 4081 | { |
| | 4082 | PARTICLE* particle = GetPointerForSaveBlock(sizeof(PARTICLE)); |
| | 4083 | *particle = ParticleStorage[i]; |
| | 4084 | } |
| | 4085 | } |
| | 4086 | } |
| | 4087 | |
| | 4088 | /*----------------------** |
| | 4089 | ** Load/Save Explosions ** |
| | 4090 | **----------------------*/ |
| | 4091 | |
| | 4092 | typedef struct explosion_save_block_header |
| | 4093 | { |
| | 4094 | SAVE_BLOCK_HEADER header; |
| | 4095 | |
| | 4096 | int NumActiveExplosions; |
| | 4097 | //followed by explosion array after this block |
| | 4098 | |
| | 4099 | } EXPLOSION_SAVE_BLOCK_HEADER; |
| | 4100 | |
| | 4101 | void Load_VolumetricExplosions(SAVE_BLOCK_HEADER* header) |
| | 4102 | { |
| | 4103 | int i; |
| | 4104 | EXPLOSION_SAVE_BLOCK_HEADER* block = (EXPLOSION_SAVE_BLOCK_HEADER*) header; |
| | 4105 | struct VOLUMETRIC_EXPLOSION* saved_explosion = (struct VOLUMETRIC_EXPLOSION*) (block+1); |
| | 4106 | |
| | 4107 | //make sure the block is the correct size |
| | 4108 | int expected_size = sizeof(*block); |
| | 4109 | expected_size += sizeof(struct VOLUMETRIC_EXPLOSION) * block->NumActiveExplosions; |
| | 4110 | |
| | 4111 | if(header->size == expected_size) |
| | 4112 | { |
| | 4113 | for(i=0; i < block->NumActiveExplosions; i++) |
| | 4114 | { |
| | 4115 | struct VOLUMETRIC_EXPLOSION* explosion = AllocateVolumetricExplosion(); |
| | 4116 | *explosion = *saved_explosion++; |
| | 4117 | } |
| | 4118 | } |
| | 4119 | } |
| | 4120 | |
| | 4121 | void Save_VolumetricExplosions() |
| | 4122 | { |
| | 4123 | if(CurrentExplosionIndex > 0) |
| | 4124 | { |
| | 4125 | int i; |
| | 4126 | EXPLOSION_SAVE_BLOCK_HEADER* block; |
| | 4127 | |
| | 4128 | //get memory for header |
| | 4129 | GET_SAVE_BLOCK_POINTER(block); |
| | 4130 | |
| | 4131 | //fill in header |
| | 4132 | block->header.type = SaveBlock_VolumetricExplosions; |
| | 4133 | block->header.size = sizeof(*block) + CurrentExplosionIndex * sizeof(struct VOLUMETRIC_EXPLOSION); |
| | 4134 | |
| | 4135 | block->NumActiveExplosions = CurrentExplosionIndex; |
| | 4136 | |
| | 4137 | for(i=0; i < CurrentExplosionIndex; i++) |
| | 4138 | { |
| | 4139 | struct VOLUMETRIC_EXPLOSION* explosion = GetPointerForSaveBlock(sizeof(struct VOLUMETRIC_EXPLOSION)); |
| | 4140 | *explosion = *active_volumetric_explosion[i]; |
| | 4141 | } |
| | 4142 | } |
| | 4143 | } |
| | 4144 | |
| | 4145 | /*----------------------------** |
| | 4146 | ** Load/Save pheromone trails ** |
| | 4147 | **----------------------------*/ |
| | 4148 | |
| | 4149 | typedef struct pheromone_save_block_header |
| | 4150 | { |
| | 4151 | SAVE_BLOCK_HEADER header; |
| | 4152 | |
| | 4153 | int NumActiveTrails; |
| | 4154 | //followed by pheromone array after this block |
| | 4155 | |
| | 4156 | } PHEROMONE_SAVE_BLOCK_HEADER; |
| | 4157 | |
| | 4158 | void Load_PheromoneTrails(SAVE_BLOCK_HEADER* header) |
| | 4159 | { |
| | 4160 | int i; |
| | 4161 | PHEROMONE_SAVE_BLOCK_HEADER* block = (PHEROMONE_SAVE_BLOCK_HEADER*) header; |
| | 4162 | PHEROMONE_TRAIL* saved_trail = (PHEROMONE_TRAIL*) (block+1); |
| | 4163 | int expected_size; |
| | 4164 | |
| | 4165 | //make sure the block is the correct size |
| | 4166 | expected_size = sizeof(*block); |
| | 4167 | expected_size += sizeof(PHEROMONE_TRAIL) * block->NumActiveTrails; |
| | 4168 | if(header->size != expected_size) |
| | 4169 | return; |
| | 4170 | |
| | 4171 | for(i=0; i < block->NumActiveTrails; i++) |
| | 4172 | { |
| | 4173 | PHEROMONE_TRAIL* trail = AllocatePheromoneTrail(); |
| | 4174 | |
| | 4175 | if(trail) |
| | 4176 | *trail = *saved_trail++; |
| | 4177 | } |
| | 4178 | } |
| | 4179 | |
| | 4180 | void Save_PheromoneTrails() |
| | 4181 | { |
| | 4182 | if(NumActiveTrails > 0) |
| | 4183 | { |
| | 4184 | PHEROMONE_SAVE_BLOCK_HEADER* block; |
| | 4185 | int i; |
| | 4186 | |
| | 4187 | //get memory for header |
| | 4188 | GET_SAVE_BLOCK_POINTER(block); |
| | 4189 | |
| | 4190 | //fill in header |
| | 4191 | block->header.type = SaveBlock_PheromoneTrail; |
| | 4192 | block->header.size = sizeof(*block) + NumActiveTrails * sizeof(PHEROMONE_TRAIL); |
| | 4193 | |
| | 4194 | block->NumActiveTrails = NumActiveTrails; |
| | 4195 | |
| | 4196 | //now save the trails |
| | 4197 | for(i=0; i < NumActiveTrails; i++) |
| | 4198 | { |
| | 4199 | PHEROMONE_TRAIL* trail = GET_SAVE_BLOCK_POINTER(trail); |
| | 4200 | *trail = TrailStorage[i]; |
| | 4201 | } |
| | 4202 | } |
| | 4203 | } |