effects.zsc (10047B)
1 class EffectBase : Actor 2 { 3 default 4 { 5 +MOVEWITHSECTOR 6 // +FLOORCLIP 7 } 8 9 bool mirrored; 10 11 override void PostBeginPlay() 12 { 13 self.mirrored = false; 14 super.PostBeginPlay(); 15 } 16 17 void flipSprite() 18 { 19 if (mirrored) 20 { 21 A_SetScale(1, 1); 22 mirrored = FALSE; 23 } 24 else 25 { 26 A_SetScale(-1, 1); 27 mirrored = TRUE; 28 } 29 } 30 } 31 32 //these actors can get picked up by dust devils. Don't call orbitCenter until orbitAngle, orbitDistance, and orbitHeight are set. 33 class WhirlDebris : EffectBase 34 { 35 36 Default 37 { 38 // Projectile; 39 Species "debris"; 40 +THRUSPECIES 41 } 42 43 double orbitAngle; 44 double orbitDistance; 45 double orbitHeight; 46 actor orbitTarget; 47 48 49 override bool CanCollideWith(Actor other, bool passive) 50 { 51 if (orbitTarget) 52 { 53 return false; 54 } 55 56 //TODO: might move these for performance sake 57 if (other.GetClassName() == "DustDevil") 58 { 59 orbitTarget = other; 60 orbitDistance = Distance2D(orbitTarget); 61 orbitHeight = pos.z - orbitTarget.pos.z; 62 orbitAngle = orbitTarget.AngleTo(self, false); 63 64 65 if (ResolveState("Orbit")) 66 { 67 SetStateLabel("Orbit"); 68 } 69 } 70 71 return false; 72 } 73 74 void orbitCenter(bool interp) 75 { 76 if (orbitTarget) 77 { 78 Vector3 newpos; 79 newpos = orbitTarget.Vec3Angle(orbitDistance, orbitAngle, orbitHeight, FALSE); 80 SetOrigin(newpos, interp); 81 82 if (orbitDistance < 10) 83 { 84 orbitDistance += 1; 85 } 86 87 double ospeed; 88 ospeed = (1 / orbitDistance) * 500; 89 90 orbitAngle += ospeed; 91 } 92 } 93 } 94 95 class FeatherFlutter : WhirlDebris 96 { 97 Default 98 { 99 Radius 32; 100 Height 2; 101 -NOGRAVITY 102 +SOLID 103 +MOVEWITHSECTOR 104 // +CLIENTSIDEONLY 105 Gravity 0.005; 106 } 107 108 void featSOrbit(bool flyup = true) //special feather orbit quarks 109 { 110 if(flyup) 111 { 112 if (orbitHeight < 50) 113 { 114 orbitHeight += 0.6; 115 } 116 } 117 else 118 { 119 if (orbitHeight > 10) 120 { 121 orbitHeight -= 0.5; 122 } 123 } 124 125 if (!orbitTarget) 126 { 127 SetStateLabel("StopOrbit"); 128 } 129 } 130 131 States 132 { 133 Crash: 134 XDeath: 135 Death: 136 FEAT B 1 137 { 138 bThruActors = false; 139 } 140 FEAT B -1; 141 Stop; 142 Spawn: 143 FEAT A 1 NoDelay 144 { 145 if (random(0, 1)) 146 { 147 flipSprite(); 148 } 149 } 150 Flutter: 151 FEAT ABC 12 152 { 153 Vel.X = 0; 154 Vel.Y = 0; 155 if (pos.z <= floorz) 156 { 157 SetStateLabel("Death"); 158 } 159 if (orbitTarget) 160 { 161 SetStateLabel("Orbit"); 162 } 163 } 164 TNT1 A 0 165 { 166 flipSprite(); 167 } 168 loop; 169 Orbit: 170 FEAT G 1 171 { 172 bNoGravity = true; 173 if (!orbitTarget) 174 { 175 SetStateLabel("StopOrbit"); 176 } 177 } 178 OrbitLoop: 179 TNT1 A 0 180 { 181 if (orbitDistance > 40) 182 { 183 int denom = 14; 184 if (orbitDistance > 55) 185 { 186 int denom = 2; 187 } 188 if (!random(0, denom)) 189 { 190 SetStateLabel("StopOrbit"); 191 orbitTarget = null; 192 bThruActors = true; 193 } 194 } 195 196 197 if (random(0, 1)) 198 { 199 flipSprite(); 200 } 201 202 int ran = random(1, 4); 203 if (ran == 4) 204 SetStateLabel("OrbitA"); 205 if (ran == 3) 206 SetStateLabel("OrbitB"); 207 if (ran == 2) 208 SetStateLabel("OrbitC"); 209 if (ran == 1) 210 SetStateLabel("OrbitD"); 211 } 212 goto Flutter; 213 OrbitA: 214 FEAT GGGGGGGG 2 215 { 216 orbitCenter(TRUE); 217 featSOrbit(TRUE); 218 } 219 goto OrbitLoop; 220 OrbitB: 221 FEAT HHHHHHHH 2 222 { 223 orbitCenter(TRUE); 224 featSOrbit(TRUE); 225 } 226 goto OrbitLoop; 227 OrbitC: 228 FEAT IIIIIIII 2 229 { 230 orbitCenter(TRUE); 231 featSOrbit(FALSE); 232 } 233 goto OrbitLoop; 234 OrbitD: 235 FEAT JJJJJJJJ 2 236 { 237 orbitCenter(TRUE); 238 featSOrbit(FALSE); 239 } 240 goto OrbitLoop; 241 StopOrbit: 242 FEAT J 15 243 { 244 Vel.Z += .6; 245 Thrust(2, orbitAngle); 246 bNoGravity = false; 247 } 248 TNT1 A 0 249 { 250 Vel.Z = 0; 251 } 252 goto Flutter; 253 } 254 } 255 256 class DustPuff : WhirlDebris 257 { 258 Default 259 { 260 Radius 3; 261 Height 3; 262 Projectile; 263 +THRUACTORS 264 +FORCEXYBILLBOARD 265 } 266 267 states 268 { 269 Spawn: 270 TNT1 A 1 NoDelay 271 { 272 orbitAngle = random(-180, 180); 273 orbitDistance = random(10, 50); 274 orbitHeight = random(10, 50); 275 orbitTarget = target; 276 orbitCenter(FALSE); //don't interpolate setting to initial position, so you don't see the sprite zipping up into place after it spawns 277 } 278 DST1 AAAAAAAAAAAAAAAA 2 279 { 280 if (!target) 281 { 282 A_Remove(AAPTR_DEFAULT, RMVF_EVERYTHING); 283 } 284 orbitCenter(TRUE); 285 orbitHeight += 0.5; 286 // orbitAngle = orbitAngle + 10; 287 } 288 Stop; 289 } 290 291 } 292 293 class DustDevil : Actor 294 { 295 Default 296 { 297 Radius 100; 298 Height 64; 299 Speed 0; 300 // +NOBLOCKMAP 301 // +THRUACTORS 302 +SOLID 303 } 304 305 //TODO: merge with other colliding dust devils 306 override bool CanCollideWith(Actor other, bool passive) 307 { 308 if(other.species == "debris") 309 { 310 return true; 311 } 312 return false; 313 } 314 315 316 action void spawnDust() 317 { 318 actor puff; 319 puff = spawn("DustPuff", pos, NO_REPLACE); 320 321 if (puff) 322 { 323 puff.target = self; 324 } 325 } 326 327 action void checkCanSpawn(int radius) 328 { 329 Vector3 cpoint; 330 cpoint.x = pos.x + radius; 331 cpoint.y = pos.y; 332 cpoint.z = pos.z; 333 if(level.IsPointInLevel(cpoint)) 334 { 335 cpoint.x = pos.x - radius; 336 if(level.IsPointInLevel(cpoint)) 337 { 338 cpoint.x = pos.x; 339 cpoint.y = pos.y + radius; 340 if(level.IsPointInLevel(cpoint)) 341 { 342 cpoint.y = pos.y - radius; 343 if(level.IsPointInLevel(cpoint)) 344 { 345 return; 346 } 347 } 348 } 349 } 350 351 A_Remove(AAPTR_DEFAULT, RMVF_EVERYTHING); 352 return; 353 } 354 355 states 356 { 357 Spawn: 358 TNT1 A 1; 359 TNT1 A 0 360 { 361 CheckPosition(pos.xy); 362 A_StartSound("whirlwind", 50, CHANF_LOOP, 0.3); 363 } 364 TNT1 AAA 15 spawnDust(); 365 TNT1 A 0 366 { 367 checkCanSpawn(200); 368 } 369 TNT1 AAAA 10 spawnDust(); 370 Full: 371 TNT1 A 0 A_StartSound("whirlwind", 50, CHANF_LOOP, 1.0); 372 TNT1 AAAAAAA 6 373 { 374 spawnDust(); 375 CheckPosition(pos.xy); 376 } 377 TNT1 AAAAAAA 6 378 { 379 spawnDust(); 380 CheckPosition(pos.xy); 381 } 382 TNT1 AAAAAAA 6 383 { 384 spawnDust(); 385 CheckPosition(pos.xy); 386 } 387 TNT1 AAAAAAA 6 388 { 389 spawnDust(); 390 CheckPosition(pos.xy); 391 } 392 TNT1 A 1 A_Jump(200, "Full"); 393 Taper: 394 TNT1 A 0 A_StartSound("whirlwind", 50, CHANF_LOOP, 0.3); 395 TNT1 AAAA 10 spawnDust(); 396 TNT1 AAA 15 spawnDust(); 397 TNT1 A 0 A_StopSound(50); 398 Stop; 399 } 400 } 401 402 class ChoppedRocket : Actor 403 { 404 default 405 { 406 Radius 11; 407 Height 4; 408 Projectile; 409 Speed 4; 410 -NOGRAVITY 411 -NOBLOCKMAP 412 +THRUACTORS 413 +MOVEWITHSECTOR 414 +FLOORCLIP 415 +CLIENTSIDEONLY 416 } 417 418 states 419 { 420 Spawn: 421 MSLC BCDA 3; 422 loop; 423 Crash: 424 XDeath: 425 Death: 426 MSLC A -1; 427 stop; 428 } 429 430 } 431 432 class SHorizBlood : EffectBase 433 { 434 default 435 { 436 Radius 4; 437 Height 4; 438 Speed 0; 439 +THRUACTORS 440 Projectile; 441 -NOGRAVITY 442 Gravity 1.0; 443 +FORCEXYBILLBOARD 444 Decal "BloodSplat"; 445 } 446 447 States 448 { 449 Spawn: 450 ASHL C 1; 451 Loop; 452 Crash: 453 Death: 454 XDeath: 455 Stop; 456 } 457 } 458 459 class FeatherBurst : Actor 460 { 461 Default 462 { 463 Radius 1; 464 Height 1; 465 Projectile; 466 Speed 0; 467 // +CLIENTSIDEONLY; 468 +THRUACTORS 469 Damage 0; 470 } 471 472 action void spawnFeather() 473 { 474 int randx; 475 int randy; 476 int randz; 477 randx = random(-40, 40); 478 randy = random(-40, 40); 479 randz = random(-10, 20); 480 A_SpawnItemEx("FeatherFlutter", 40 + randx, 0 + randy, 10 + randz, 0, 0, 0, 0, SXF_NOCHECKPOSITION); 481 } 482 483 484 States 485 { 486 Spawn: 487 TNT1 A 2; 488 TNT1 A 3 spawnFeather(); 489 TNT1 A 1 A_Jump(120, "FeatTwo"); 490 Goto Death; 491 FeatTwo: 492 TNT1 A 1 spawnFeather(); 493 TNT1 A 1 A_Jump(50, "FeatThree"); 494 Goto Death; 495 FeatThree: 496 TNT1 A 1 spawnFeather(); 497 Crash: 498 XDeath: //when hitting a bleeding actor 499 Death: 500 TNT1 A 1; 501 Stop; 502 } 503 } 504 505 class MaybeFeather : FeatherBurst 506 { 507 States 508 { 509 Spawn: 510 TNT1 A 2; 511 TNT1 A 3 512 { 513 if (random(0, 3) == 3) 514 { 515 spawnFeather(); 516 } 517 } 518 Crash: 519 XDeath: //when hitting a bleeding actor 520 Death: 521 TNT1 A 1; 522 Stop; 523 } 524 } 525 526 class HugeFeatherBurst: FeatherBurst //just for performance testing 527 { 528 529 action void spawnFeatherBigSpread() 530 { 531 int randx; 532 int randy; 533 int randz; 534 randx = random(-300, 300); 535 randy = random(-300, 300); 536 randz = random(-10, 20); 537 A_SpawnItemEx("FeatherFlutter", 40 + randx, 0 + randy, 10 + randz, 0, 0, 0, 0, SXF_NOCHECKPOSITION); 538 } 539 540 States 541 { 542 Spawn: 543 TNT1 A 2; 544 TNT1 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 1 545 { 546 spawnFeatherBigSpread(); 547 spawnFeatherBigSpread(); 548 spawnFeatherBigSpread(); 549 spawnFeatherBigSpread(); 550 spawnFeatherBigSpread(); 551 spawnFeatherBigSpread(); 552 spawnFeatherBigSpread(); 553 spawnFeatherBigSpread(); 554 spawnFeatherBigSpread(); 555 spawnFeatherBigSpread(); 556 557 } 558 Death: 559 TNT1 A 1; 560 stop; 561 562 } 563 } 564 565 class BigFeatherBurst : FeatherBurst 566 { 567 States 568 { 569 Spawn: 570 TNT1 A 2; 571 TNT1 AAAAAAAA 1 572 { 573 spawnFeather(); 574 } 575 TNT1 A 1 A_Jump(150, "FeatOne"); 576 Goto Death; 577 FeatOne: 578 TNT1 AAAAA 1 579 { 580 spawnFeather(); 581 } 582 TNT1 A 1 A_Jump(50, "FeatTwo"); 583 Goto Death; 584 FeatTwo: 585 TNT1 AAAA 1 586 { 587 spawnFeather(); 588 } 589 TNT1 A 1 A_Jump(30, "FeatThree"); 590 Goto Death; 591 FeatThree: 592 TNT1 AAA 1 593 { 594 spawnFeather(); 595 } 596 Crash: 597 XDeath: //when hitting a bleeding actor 598 Death: 599 TNT1 A 1; 600 Stop; 601 } 602 } 603 604 class ZippySpark : Actor 605 { 606 Default 607 { 608 +NOGRAVITY 609 } 610 611 612 Double TurnSpeed, PitchSpeed; 613 614 States 615 { 616 Spawn: 617 TNT1 A 4 NoDelay 618 { 619 Angle = frandom(0, 360); 620 Pitch = frandom(0, 360); 621 TurnSpeed = random(-30, 30) + 60 + (120 * random(-1, 0)); 622 PitchSpeed = random(-30, 30) + 60 + (120 * random(-1, 0)); 623 } 624 Fly: 625 PLSS AABBAA 2 Bright 626 { 627 Angle += TurnSpeed; 628 Pitch += PitchSpeed; 629 Vel3DFromAngle(10, Angle, Pitch); 630 } 631 Death: 632 TNT1 A 1; 633 Stop; 634 } 635 636 }