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