Serious-Engine/Sources/EntitiesMP/Projectile.es

3801 lines
132 KiB
Erlang
Raw Normal View History

2016-03-11 14:57:17 +01:00
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
501
%{
#include "StdH.h"
#include "Models/Weapons/Laser/Projectile/LaserProjectile.h"
#include "EntitiesMP/EnemyBase.h"
//#include "EntitiesMP/Dragonman.h"
#include "Models/Enemies/Elementals/Projectile/IcePyramid.h"
#include "Models/Enemies/ElementalLava/Projectile/LavaStone.h"
#include "Models/Enemies/ElementalLava/Projectile/LavaBomb.h"
#include "Models/Enemies/Headman/Projectile/Blade.h"
#include "Models/Enemies/Huanman/Projectile/Projectile.h"
#include "Models/Enemies/Cyborg/Projectile/LaserProjectile.h"
#include "ModelsMP/Enemies/Grunt/Projectile/GruntProjectile.h"
#include "ModelsMP/Enemies/Guffy/Projectile/GuffyProjectile.h"
#include "ModelsMP/Enemies/ExotechLarva/Weapons/PlasmaGun.h"
#include "EntitiesMP/PlayerWeapons.h"
#include "EntitiesMP/Shooter.h"
#define DEVIL_LASER_SPEED 100.0f
#define DEVIL_ROCKET_SPEED 60.0f
%}
uses "EntitiesMP/BasicEffects";
uses "EntitiesMP/Light";
uses "EntitiesMP/Flame";
enum ProjectileType {
0 PRT_ROCKET "Rocket", // player rocket
1 PRT_GRENADE "Grenade", // player grenade
2 PRT_FLAME "Flame", // player flamer flame
3 PRT_LASER_RAY "Laser", // player laser ray
4 PRT_WALKER_ROCKET "WalkerRocket", // walker rocket
10 PRT_CATMAN_FIRE "Catman", // catman fire
11 PRT_HEADMAN_FIRECRACKER "Firecracker", // headman firecracker
12 PRT_HEADMAN_ROCKETMAN "Rocketman", // headman rocketman
13 PRT_HEADMAN_BOMBERMAN "Bomberman", // headman bomberman
14 PRT_BONEMAN_FIRE "Boneman", // boneman fire
15 PRT_WOMAN_FIRE "Woman", // woman fire
16 PRT_DRAGONMAN_FIRE "Dragonman", // dragonman fire
17 PRT_DRAGONMAN_STRONG_FIRE "Dragonman Strong", // dragonman strong fire
18 PRT_STONEMAN_FIRE "Stoneman", // stoneman fire rock
19 PRT_STONEMAN_BIG_FIRE "Stoneman Big", // stoneman big fire rock
20 PRT_STONEMAN_LARGE_FIRE "Stoneman Large", // stoneman large fire rock
21 PRT_LAVAMAN_BIG_BOMB "Lavaman Big Bomb", // lavaman big bomb
22 PRT_LAVAMAN_BOMB "Lavaman Bomb", // lavaman bomb
23 PRT_LAVAMAN_STONE "Lavaman Stone", // lavaman rock projectile
27 PRT_ICEMAN_FIRE "Iceman", // iceman ice cube
28 PRT_ICEMAN_BIG_FIRE "Iceman Big", // iceman big ice cube
29 PRT_ICEMAN_LARGE_FIRE "Iceman Large", // iceman large ice cube
41 PRT_HUANMAN_FIRE "Huanman", // huanman fire
42 PRT_FISHMAN_FIRE "Fishman", // fishman fire
43 PRT_MANTAMAN_FIRE "Mantaman", // mantaman fire
44 PRT_CYBORG_LASER "Cyborg Laser", // cyborg laser
45 PRT_CYBORG_BOMB "Cyborg Bomb", // cyborg bomb
50 PRT_LAVA_COMET "Lava Comet", // lava comet
51 PRT_BEAST_PROJECTILE "Beast Projectile", // beast projectile
52 PRT_BEAST_BIG_PROJECTILE "Beast Big Projectile", // big beast projectile
53 PRT_BEAST_DEBRIS "Beast Debris", // beast projectile's debris
54 PRT_BEAST_BIG_DEBRIS "Beast Big Debris", // big beast projectile's debris
55 PRT_DEVIL_LASER "Devil Laser", // devil laser
56 PRT_DEVIL_ROCKET "Devil Rocket", // devil rocket
57 PRT_DEVIL_GUIDED_PROJECTILE "Devil Guided Projectile", // devil guided projectile
60 PRT_GRUNT_PROJECTILE_SOL "Grunt Soldier Laser", // grunt laser
64 PRT_GRUNT_PROJECTILE_COM "Grunt Commander Laser", // grunt commander laser
61 PRT_GUFFY_PROJECTILE "Guffy Projectile", // guffy rocket
62 PRT_DEMON_FIREBALL "Demon Fireball", // demon fireball
63 PRT_DEMON_FIREBALL_DEBRIS "Demon Fireball Debris", // demon fireball debris
70 PRT_SHOOTER_WOODEN_DART "Shooter Wooden Dart", // shooter's wooden dart
71 PRT_SHOOTER_FIREBALL "Shooter Fireball", // shooter's fireball
72 PRT_SHOOTER_FLAME "Shooter Flame", // shooter's flame
73 PRT_LARVA_PLASMA "ExotechLarva Plasma", //exotech larva plasma gun
74 PRT_LARVA_TAIL_PROJECTILE "ExotechLarva Tail Projectile", //exotech larva tail projectile
75 PRT_AIRELEMENTAL_WIND "Air Elemental Wind Blast", //air elemental wind blast
76 PRT_AFTERBURNER_DEBRIS "Afterburner debris",
77 PRT_METEOR "Meteor",
};
enum ProjectileMovingType {
0 PMT_FLYING "", // flying through space
1 PMT_SLIDING "", // sliding on floor
2 PMT_GUIDED "", // guided projectile
3 PMT_GUIDED_FAST "", // fast guided projectile
4 PMT_FLYING_REBOUNDING "", // flying and rebounding from walls a few times
5 PMT_GUIDED_SLIDING "", // sliding on floor and guided at the same time
};
// input parameter for launching the projectile
event ELaunchProjectile {
CEntityPointer penLauncher, // who launched it
enum ProjectileType prtType, // type of projectile
FLOAT fSpeed, // optional - projectile speed (only for some projectiles)
FLOAT fStretch, // optional - projectile stretch (only for some projectiles)
};
%{
#define DRAGONMAN_NORMAL 0
#define DRAGONMAN_STRONG 1
#define ELEMENTAL_LARGE 2
#define ELEMENTAL_BIG 1
#define ELEMENTAL_NORMAL 0
#define ELEMENTAL_STONEMAN 0
#define ELEMENTAL_LAVAMAN 1
#define ELEMENTAL_ICEMAN 2
void CProjectile_OnInitClass(void)
{
}
void CProjectile_OnPrecache(CDLLEntityClass *pdec, INDEX iUser)
{
pdec->PrecacheTexture(TEX_REFL_BWRIPLES01);
pdec->PrecacheTexture(TEX_REFL_BWRIPLES02);
pdec->PrecacheTexture(TEX_REFL_LIGHTMETAL01);
pdec->PrecacheTexture(TEX_REFL_LIGHTBLUEMETAL01);
pdec->PrecacheTexture(TEX_REFL_DARKMETAL);
pdec->PrecacheTexture(TEX_REFL_PURPLE01);
pdec->PrecacheTexture(TEX_SPEC_WEAK);
pdec->PrecacheTexture(TEX_SPEC_MEDIUM);
pdec->PrecacheTexture(TEX_SPEC_STRONG);
switch ((ProjectileType)iUser) {
case PRT_ROCKET :
case PRT_WALKER_ROCKET :
case PRT_DEVIL_ROCKET :
pdec->PrecacheModel(MODEL_ROCKET );
pdec->PrecacheTexture(TEXTURE_ROCKET);
pdec->PrecacheSound(SOUND_FLYING );
pdec->PrecacheClass(CLASS_BASIC_EFFECT, BET_ROCKET);
pdec->PrecacheClass(CLASS_BASIC_EFFECT, BET_EXPLOSIONSTAIN);
pdec->PrecacheClass(CLASS_BASIC_EFFECT, BET_SHOCKWAVE);
pdec->PrecacheClass(CLASS_BASIC_EFFECT, BET_ROCKET_PLANE);
break;
case PRT_GRENADE:
pdec->PrecacheModel(MODEL_GRENADE);
pdec->PrecacheTexture(TEXTURE_GRENADE);
pdec->PrecacheSound(SOUND_GRENADE_BOUNCE);
pdec->PrecacheClass(CLASS_BASIC_EFFECT, BET_GRENADE);
pdec->PrecacheClass(CLASS_BASIC_EFFECT, BET_EXPLOSIONSTAIN);
pdec->PrecacheClass(CLASS_BASIC_EFFECT, BET_SHOCKWAVE);
pdec->PrecacheClass(CLASS_BASIC_EFFECT, BET_GRENADE_PLANE);
break;
case PRT_FLAME:
pdec->PrecacheModel(MODEL_FLAME);
pdec->PrecacheClass(CLASS_FLAME);
break;
case PRT_LASER_RAY:
pdec->PrecacheModel(MODEL_LASER );
pdec->PrecacheTexture(TEXTURE_GREEN_LASER );
pdec->PrecacheClass(CLASS_BASIC_EFFECT, BET_LASERWAVE);
break;
case PRT_GRUNT_PROJECTILE_SOL:
pdec->PrecacheModel(MODEL_GRUNT_PROJECTILE );
pdec->PrecacheTexture(TEXTURE_GRUNT_PROJECTILE_01 );
pdec->PrecacheClass(CLASS_BASIC_EFFECT, BET_LASERWAVE);
break;
case PRT_GRUNT_PROJECTILE_COM:
pdec->PrecacheModel(MODEL_GRUNT_PROJECTILE );
pdec->PrecacheTexture(TEXTURE_GRUNT_PROJECTILE_02 );
pdec->PrecacheClass(CLASS_BASIC_EFFECT, BET_LASERWAVE);
break;
case PRT_CATMAN_FIRE:
pdec->PrecacheModel(MODEL_CATMAN_FIRE );
pdec->PrecacheTexture(TEXTURE_CATMAN_FIRE );
break;
case PRT_HEADMAN_FIRECRACKER:
pdec->PrecacheModel(MODEL_HEADMAN_FIRECRACKER );
pdec->PrecacheTexture(TEXTURE_HEADMAN_FIRECRACKER );
break;
case PRT_HEADMAN_ROCKETMAN:
pdec->PrecacheModel(MODEL_HEADMAN_BLADE );
pdec->PrecacheTexture(TEXTURE_HEADMAN_BLADE );
pdec->PrecacheModel(MODEL_HEADMAN_BLADE_FLAME );
pdec->PrecacheTexture(TEXTURE_HEADMAN_BLADE_FLAME );
break;
case PRT_HEADMAN_BOMBERMAN:
pdec->PrecacheModel(MODEL_HEADMAN_BOMB );
pdec->PrecacheTexture(TEXTURE_HEADMAN_BOMB );
pdec->PrecacheClass(CLASS_BASIC_EFFECT, BET_BOMB);
pdec->PrecacheClass(CLASS_BASIC_EFFECT, BET_EXPLOSIONSTAIN);
pdec->PrecacheClass(CLASS_BASIC_EFFECT, BET_GRENADE_PLANE);
break;
case PRT_BONEMAN_FIRE:
pdec->PrecacheModel(MODEL_BONEMAN_FIRE );
pdec->PrecacheTexture(TEXTURE_BONEMAN_FIRE );
break;
case PRT_WOMAN_FIRE:
pdec->PrecacheModel(MODEL_WOMAN_FIRE );
pdec->PrecacheTexture(TEXTURE_WOMAN_FIRE );
break;
case PRT_DRAGONMAN_FIRE:
case PRT_DRAGONMAN_STRONG_FIRE:
pdec->PrecacheModel(MODEL_DRAGONMAN_FIRE );
pdec->PrecacheTexture(TEXTURE_DRAGONMAN_FIRE1 );
pdec->PrecacheTexture(TEXTURE_DRAGONMAN_FIRE2 );
break;
case PRT_STONEMAN_FIRE:
case PRT_STONEMAN_BIG_FIRE:
case PRT_STONEMAN_LARGE_FIRE:
pdec->PrecacheModel(MODEL_ELEM_STONE );
pdec->PrecacheTexture(TEXTURE_ELEM_STONE );
break;
case PRT_LAVAMAN_BIG_BOMB:
case PRT_LAVAMAN_BOMB:
case PRT_LAVAMAN_STONE:
pdec->PrecacheModel(MODEL_ELEM_LAVA_STONE);
pdec->PrecacheModel(MODEL_ELEM_LAVA_STONE_FLARE);
pdec->PrecacheModel(MODEL_ELEM_LAVA_BOMB);
pdec->PrecacheModel(MODEL_ELEM_LAVA_BOMB_FLARE);
pdec->PrecacheTexture(TEXTURE_ELEM_LAVA_STONE);
pdec->PrecacheTexture(TEXTURE_ELEM_LAVA_STONE_FLARE );
pdec->PrecacheTexture(TEXTURE_ELEM_LAVA_BOMB);
pdec->PrecacheTexture(TEXTURE_ELEM_LAVA_BOMB_FLARE);
pdec->PrecacheClass(CLASS_BASIC_EFFECT, BET_SHOCKWAVE);
pdec->PrecacheClass(CLASS_BLOOD_SPRAY);
break;
case PRT_METEOR:
pdec->PrecacheSound(SOUND_FLYING );
pdec->PrecacheSound(SOUND_METEOR_BLAST );
pdec->PrecacheModel(MODEL_ELEM_LAVA_BOMB);
pdec->PrecacheTexture(TEXTURE_ELEM_LAVA_BOMB);
pdec->PrecacheClass(CLASS_BLOOD_SPRAY);
pdec->PrecacheClass(CLASS_BASIC_EFFECT, BET_CANNON);
break;
case PRT_ICEMAN_FIRE:
case PRT_ICEMAN_BIG_FIRE:
case PRT_ICEMAN_LARGE_FIRE:
pdec->PrecacheModel(MODEL_ELEM_ICE );
pdec->PrecacheModel(MODEL_ELEM_ICE_FLARE );
pdec->PrecacheTexture(TEXTURE_ELEM_ICE );
//pdec->PrecacheTexture(TEXTURE_ELEM_ICE_FLARE);
break;
case PRT_HUANMAN_FIRE:
pdec->PrecacheModel(MODEL_HUANMAN_FIRE );
pdec->PrecacheTexture(TEXTURE_HUANMAN_FIRE );
pdec->PrecacheModel(MODEL_HUANMAN_FLARE );
pdec->PrecacheTexture(TEXTURE_HUANMAN_FLARE );
break;
case PRT_FISHMAN_FIRE:
pdec->PrecacheModel(MODEL_FISHMAN_FIRE );
pdec->PrecacheTexture(TEXTURE_FISHMAN_FIRE );
break;
case PRT_MANTAMAN_FIRE:
pdec->PrecacheModel(MODEL_MANTAMAN_FIRE );
pdec->PrecacheTexture(TEXTURE_MANTAMAN_FIRE );
break;
case PRT_DEVIL_LASER:
/*
pdec->PrecacheModel(MODEL_DEVIL_LASER );
pdec->PrecacheTexture(TEXTURE_DEVIL_LASER );
break;
*/
case PRT_CYBORG_LASER:
case PRT_CYBORG_BOMB:
pdec->PrecacheModel(MODEL_CYBORG_LASER );
pdec->PrecacheTexture(TEXTURE_CYBORG_LASER );
pdec->PrecacheModel(MODEL_CYBORG_BOMB );
pdec->PrecacheTexture(TEXTURE_CYBORG_BOMB );
pdec->PrecacheClass(CLASS_BASIC_EFFECT, BET_BOMB);
pdec->PrecacheClass(CLASS_BASIC_EFFECT, BET_EXPLOSIONSTAIN);
pdec->PrecacheClass(CLASS_BASIC_EFFECT, BET_GRENADE_PLANE);
break;
case PRT_LAVA_COMET:
pdec->PrecacheModel(MODEL_ELEM_LAVA_STONE);
pdec->PrecacheModel(MODEL_ELEM_LAVA_STONE_FLARE);
pdec->PrecacheModel(MODEL_ELEM_LAVA_BOMB);
pdec->PrecacheModel(MODEL_ELEM_LAVA_BOMB_FLARE);
pdec->PrecacheTexture(TEXTURE_ELEM_LAVA_STONE);
pdec->PrecacheTexture(TEXTURE_ELEM_LAVA_STONE_FLARE );
pdec->PrecacheTexture(TEXTURE_ELEM_LAVA_BOMB);
pdec->PrecacheTexture(TEXTURE_ELEM_LAVA_BOMB_FLARE);
pdec->PrecacheClass(CLASS_BASIC_EFFECT, BET_SHOCKWAVE);
pdec->PrecacheClass(CLASS_BLOOD_SPRAY);
pdec->PrecacheModel(MODEL_LAVA );
pdec->PrecacheTexture(TEXTURE_LAVA );
pdec->PrecacheModel(MODEL_LAVA_FLARE );
pdec->PrecacheTexture(TEXTURE_LAVA_FLARE);
pdec->PrecacheClass(CLASS_BASIC_EFFECT, BET_SHOCKWAVE);
pdec->PrecacheClass(CLASS_BLOOD_SPRAY);
break;
case PRT_BEAST_PROJECTILE:
case PRT_BEAST_DEBRIS:
pdec->PrecacheSound(SOUND_BEAST_FLYING );
pdec->PrecacheModel(MODEL_BEAST_FIRE);
pdec->PrecacheTexture(TEXTURE_BEAST_FIRE);
pdec->PrecacheClass(CLASS_BASIC_EFFECT, BET_CANNON);
break;
case PRT_GUFFY_PROJECTILE:
pdec->PrecacheSound(SOUND_FLYING );
pdec->PrecacheModel(MODEL_GUFFY_PROJECTILE );
pdec->PrecacheTexture(TEXTURE_GUFFY_PROJECTILE );
pdec->PrecacheClass(CLASS_BASIC_EFFECT, BET_ROCKET );
break;
case PRT_BEAST_BIG_PROJECTILE:
case PRT_DEVIL_GUIDED_PROJECTILE:
case PRT_BEAST_BIG_DEBRIS:
case PRT_SHOOTER_FIREBALL:
pdec->PrecacheSound(SOUND_BEAST_FLYING );
pdec->PrecacheModel(MODEL_BEAST_FIRE);
pdec->PrecacheTexture(TEXTURE_BEAST_BIG_FIRE);
pdec->PrecacheClass(CLASS_BASIC_EFFECT, BET_LIGHT_CANNON);
break;
case PRT_DEMON_FIREBALL:
case PRT_DEMON_FIREBALL_DEBRIS:
pdec->PrecacheSound(SOUND_DEMON_FLYING );
pdec->PrecacheModel(MODEL_DEMON_FIREBALL);
pdec->PrecacheTexture(TEXTURE_DEMON_FIREBALL);
pdec->PrecacheClass(CLASS_BASIC_EFFECT, BET_LIGHT_CANNON);
break;
case PRT_LARVA_PLASMA:
pdec->PrecacheSound(SOUND_DEMON_FLYING );
pdec->PrecacheModel(MODEL_LARVA_PLASMA);
pdec->PrecacheTexture(TEXTURE_LARVA_PLASMA);
pdec->PrecacheClass(CLASS_BASIC_EFFECT, BET_LIGHT_CANNON);
break;
case PRT_LARVA_TAIL_PROJECTILE:
pdec->PrecacheSound(SOUND_LARVETTE );
pdec->PrecacheModel(MODEL_LARVA_TAIL);
pdec->PrecacheTexture(TEXTURE_LARVA_TAIL);
pdec->PrecacheClass(CLASS_BASIC_EFFECT, BET_CANNON);
break;
case PRT_SHOOTER_WOODEN_DART:
pdec->PrecacheModel(MODEL_SHTR_WOODEN_DART);
pdec->PrecacheTexture(TEX_SHTR_WOODEN_DART);
break;
case PRT_SHOOTER_FLAME:
pdec->PrecacheModel(MODEL_FLAME);
pdec->PrecacheClass(CLASS_FLAME);
break;
case PRT_AIRELEMENTAL_WIND:
pdec->PrecacheModel(MODEL_WINDBLAST);
pdec->PrecacheTexture(TEXTURE_WINDBLAST);
break;
case PRT_AFTERBURNER_DEBRIS:
pdec->PrecacheModel(MODEL_MARKER);
pdec->PrecacheTexture(TEXTURE_MARKER);
break;
default:
ASSERT(FALSE);
}
}
%}
class export CProjectile : CMovableModelEntity {
name "Projectile";
thumbnail "";
features "ImplementsOnInitClass", "ImplementsOnPrecache", "CanBePredictable";
properties:
1 CEntityPointer m_penLauncher, // who lanuched it
2 enum ProjectileType m_prtType = PRT_ROCKET, // type of the projectile
3 enum ProjectileMovingType m_pmtMove = PMT_FLYING, // projectile moving type
4 CEntityPointer m_penParticles, // another entity for particles
5 CEntityPointer m_penTarget, // guided projectile's target
6 CEntityPointer m_penLastDamaged, // last entity this projectile damaged
10 FLOAT m_fSpeed = 0.0f, // projectile speed (optional, only for some projectiles)
11 FLOAT m_fIgnoreTime = 0.0f, // time when laucher will be ignored
12 FLOAT m_fFlyTime = 0.0f, // fly time before explode/disappear
13 FLOAT m_fStartTime = 0.0f, // start time when launched
14 FLOAT m_fDamageAmount = 0.0f, // damage amount when hit something
15 FLOAT m_fRangeDamageAmount = 0.0f, // range damage amount
16 FLOAT m_fDamageHotSpotRange = 0.0f, // hot spot range damage for exploding projectile
17 FLOAT m_fDamageFallOffRange = 0.0f, // fall off range damage for exploding projectile
18 FLOAT m_fSoundRange = 0.0f, // sound range where explosion can be heard
19 BOOL m_bExplode = FALSE, // explode -> range damage
20 BOOL m_bLightSource = FALSE, // projectile is also light source
21 BOOL m_bCanHitHimself = FALSE, // projectile can him himself
22 BOOL m_bCanBeDestroyed = FALSE, // projectile can be destroyed from something else
23 FLOAT m_fWaitAfterDeath = 0.0f, // wait after death for particles
24 FLOAT m_aRotateSpeed = 0.0f, // speed of rotation for guided projectiles
25 FLOAT m_tmExpandBox = 0.0f, // expand collision after a few seconds
26 FLOAT m_tmInvisibility = 0.0f, // don't render before given time
27 INDEX m_iRebounds = 0, // how many times to rebound
28 FLOAT m_fStretch=1.0f, // stretch
30 CSoundObject m_soEffect, // sound channel
31 CSoundObject m_soExplosion, // sound channel
35 FLOAT m_fGuidedMaxSpeedFactor = 30.0f, // speed factor for guided projectiles
50 BOOL bLockedOn = TRUE,
51 BOOL m_bLeftFlame = FALSE,
{
CLightSource m_lsLightSource;
}
components:
1 class CLASS_BASIC_EFFECT "Classes\\BasicEffect.ecl",
2 class CLASS_LIGHT "Classes\\Light.ecl",
3 class CLASS_PROJECTILE "Classes\\Projectile.ecl",
4 class CLASS_BLOOD_SPRAY "Classes\\BloodSpray.ecl",
// ********* PLAYER ROCKET *********
5 model MODEL_ROCKET "Models\\Weapons\\RocketLauncher\\Projectile\\Rocket.mdl",
6 texture TEXTURE_ROCKET "Models\\Weapons\\RocketLauncher\\Projectile\\Rocket.tex",
8 sound SOUND_FLYING "Sounds\\Weapons\\RocketFly.wav",
9 sound SOUND_BEAST_FLYING "Sounds\\Weapons\\ProjectileFly.wav",
// ********* PLAYER GRENADE *********
10 model MODEL_GRENADE "Models\\Weapons\\GrenadeLauncher\\Grenade\\Grenade.mdl",
11 texture TEXTURE_GRENADE "Models\\Weapons\\GrenadeLauncher\\Grenade\\Grenade.tex",
12 sound SOUND_GRENADE_BOUNCE "Models\\Weapons\\GrenadeLauncher\\Sounds\\Bounce.wav",
// ********* PLAYER FLAME *********
15 model MODEL_FLAME "ModelsMP\\Weapons\\Flamer\\Projectile\\Invisible.mdl",
16 class CLASS_FLAME "Classes\\Flame.ecl",
// ********* CATMAN FIRE *********
20 model MODEL_CATMAN_FIRE "Models\\Enemies\\Catman\\Projectile\\Projectile.mdl",
21 texture TEXTURE_CATMAN_FIRE "Models\\Enemies\\Catman\\Projectile\\Projectile.tex",
// ********* HEADMAN FIRE *********
30 model MODEL_HEADMAN_FIRECRACKER "Models\\Enemies\\Headman\\Projectile\\FireCracker.mdl",
31 texture TEXTURE_HEADMAN_FIRECRACKER "Models\\Enemies\\Headman\\Projectile\\Texture.tex",
32 model MODEL_HEADMAN_BLADE "Models\\Enemies\\Headman\\Projectile\\Blade.mdl",
33 texture TEXTURE_HEADMAN_BLADE "Models\\Enemies\\Headman\\Projectile\\Blade.tex",
34 model MODEL_HEADMAN_BLADE_FLAME "Models\\Enemies\\Headman\\Projectile\\FireTrail.mdl",
35 texture TEXTURE_HEADMAN_BLADE_FLAME "Models\\Enemies\\Headman\\Projectile\\FireTrail.tex",
36 model MODEL_HEADMAN_BOMB "Models\\Enemies\\Headman\\Projectile\\Bomb.mdl",
37 texture TEXTURE_HEADMAN_BOMB "Models\\Enemies\\Headman\\Projectile\\Bomb.tex",
// ********* LAVA *********
40 model MODEL_LAVA "Models\\Effects\\Debris\\Lava01\\Lava.mdl",
41 texture TEXTURE_LAVA "Models\\Effects\\Debris\\Lava01\\Lava.tex",
42 model MODEL_LAVA_FLARE "Models\\Effects\\Debris\\Lava01\\LavaFlare.mdl",
43 texture TEXTURE_LAVA_FLARE "Models\\Effects\\Debris\\Lava01\\Flare.tex",
// ********* PLAYER LASER *********
50 model MODEL_LASER "Models\\Weapons\\Laser\\Projectile\\LaserProjectile.mdl",
51 texture TEXTURE_GREEN_LASER "Models\\Weapons\\Laser\\Projectile\\LaserProjectile.tex",
52 texture TEXTURE_BLUE_LASER "Models\\Weapons\\Laser\\Projectile\\LaserProjectileBlue.tex",
// ********* BONEMAN FIRE *********
60 model MODEL_BONEMAN_FIRE "Models\\Enemies\\Boneman\\Projectile\\Projectile.mdl",
61 texture TEXTURE_BONEMAN_FIRE "Models\\Enemies\\Boneman\\Projectile\\Projectile.tex",
// ********* WOMAN FIRE *********
65 model MODEL_WOMAN_FIRE "Models\\Enemies\\Woman\\Projectile\\Projectile.mdl",
66 texture TEXTURE_WOMAN_FIRE "Models\\Enemies\\Woman\\Projectile\\Projectile.tex",
// ********* DRAGONMAN FIRE *********
70 model MODEL_DRAGONMAN_FIRE "Models\\Enemies\\Dragonman\\Projectile\\Projectile.mdl",
71 texture TEXTURE_DRAGONMAN_FIRE1 "Models\\Enemies\\Dragonman\\Projectile\\Projectile1.tex",
72 texture TEXTURE_DRAGONMAN_FIRE2 "Models\\Enemies\\Dragonman\\Projectile\\Projectile2.tex",
// ********* ELEMENTAL FIRE *********
80 model MODEL_ELEM_STONE "Models\\Enemies\\Elementals\\Projectile\\Stone.mdl",
81 model MODEL_ELEM_ICE "Models\\Enemies\\Elementals\\Projectile\\IcePyramid.mdl",
82 model MODEL_ELEM_ICE_FLARE "Models\\Enemies\\Elementals\\Projectile\\IcePyramidFlare.mdl",
83 model MODEL_ELEM_LAVA_BOMB "Models\\Enemies\\Elementals\\Projectile\\LavaBomb.mdl",
84 model MODEL_ELEM_LAVA_BOMB_FLARE "Models\\Enemies\\Elementals\\Projectile\\LavaBombFlare.mdl",
85 model MODEL_ELEM_LAVA_STONE "Models\\Enemies\\Elementals\\Projectile\\LavaStone.mdl",
86 model MODEL_ELEM_LAVA_STONE_FLARE "Models\\Enemies\\Elementals\\Projectile\\LavaStoneFlare.mdl",
90 texture TEXTURE_ELEM_STONE "Models\\Enemies\\Elementals\\Projectile\\Stone.tex",
91 texture TEXTURE_ELEM_ICE "Models\\Enemies\\Elementals\\Projectile\\IcePyramid.tex",
//92 texture TEXTURE_ELEM_ICE_FLARE "Textures\\Effects\\Flares\\03\\Flare06.tex",
93 texture TEXTURE_ELEM_LAVA_BOMB "Models\\Enemies\\Elementals\\Projectile\\LavaBomb.tex",
94 texture TEXTURE_ELEM_LAVA_BOMB_FLARE "Models\\Enemies\\Elementals\\Projectile\\LavaBombFlare.tex",
95 texture TEXTURE_ELEM_LAVA_STONE "Models\\Enemies\\Elementals\\Projectile\\LavaStone.tex",
96 texture TEXTURE_ELEM_LAVA_STONE_FLARE "Models\\Enemies\\Elementals\\Projectile\\LavaBombFlare.tex",
// ********* HUANMAN FIRE *********
105 model MODEL_HUANMAN_FIRE "Models\\Enemies\\Huanman\\Projectile\\Projectile.mdl",
106 texture TEXTURE_HUANMAN_FIRE "Models\\Enemies\\Huanman\\Projectile\\Projectile.tex",
107 model MODEL_HUANMAN_FLARE "Models\\Enemies\\Huanman\\Projectile\\Flare.mdl",
108 texture TEXTURE_HUANMAN_FLARE "Textures\\Effects\\Flares\\01\\WhiteRedRing66.tex",
// ********* FISHMAN FIRE *********
110 model MODEL_FISHMAN_FIRE "Models\\Enemies\\Fishman\\Projectile\\Projectile.mdl",
111 texture TEXTURE_FISHMAN_FIRE "Models\\Enemies\\Fishman\\Projectile\\Water.tex",
// ********* FISHMAN FIRE *********
120 model MODEL_MANTAMAN_FIRE "Models\\Enemies\\Mantaman\\Projectile\\Projectile.mdl",
121 texture TEXTURE_MANTAMAN_FIRE "Models\\Enemies\\Mantaman\\Projectile\\Water.tex",
// ********* CYBORG FIRE *********
130 model MODEL_CYBORG_LASER "Models\\Weapons\\Laser\\Projectile\\LaserProjectile.mdl",
132 texture TEXTURE_CYBORG_LASER "Models\\Weapons\\Laser\\Projectile\\LaserProjectileBlue.tex",
133 model MODEL_CYBORG_BOMB "Models\\Enemies\\Cyborg\\Projectile\\Projectile.mdl",
134 texture TEXTURE_CYBORG_BOMB "Models\\Enemies\\Cyborg\\Projectile\\Projectile.tex",
// ********* GRUNT PROJECTILES *********
135 model MODEL_GRUNT_PROJECTILE "ModelsMP\\Enemies\\Grunt\\Projectile\\GruntProjectile.mdl",
136 texture TEXTURE_GRUNT_PROJECTILE_01 "ModelsMP\\Enemies\\Grunt\\Projectile\\GruntProjectileSoldier.tex",
137 texture TEXTURE_GRUNT_PROJECTILE_02 "ModelsMP\\Enemies\\Grunt\\Projectile\\GruntProjectileCommander.tex",
// ********* DEVIL FIRE *********
/*
135 model MODEL_DEVIL_LASER "Models\\Enemies\\Devil\\Weapons\\DevilLaserProjectile.mdl",
136 texture TEXTURE_DEVIL_LASER "Models\\Enemies\\Devil\\Weapons\\DevilLaserProjectile.tex",
*/
// ********* BEAST FIRE *********
140 model MODEL_BEAST_FIRE "Models\\Enemies\\Beast\\Projectile\\Projectile.mdl",
141 texture TEXTURE_BEAST_FIRE "Models\\Enemies\\Beast\\Projectile\\Projectile.tex",
142 texture TEXTURE_BEAST_BIG_FIRE "Models\\Enemies\\Beast\\Projectile\\ProjectileBig.tex",
// ********* DEMON FIREBALL *********
150 model MODEL_DEMON_FIREBALL "ModelsMP\\Enemies\\Demon\\Projectile\\Projectile.mdl",
151 texture TEXTURE_DEMON_FIREBALL "ModelsMP\\Enemies\\Demon\\Projectile\\Projectile.tex",
152 sound SOUND_DEMON_FLYING "SoundsMP\\Weapons\\ProjectileFly.wav",
// ********** SHOOTERS **********
160 model MODEL_SHTR_WOODEN_DART "ModelsMP\\Enemies\\Shooters\\Arrow01.mdl",
161 texture TEX_SHTR_WOODEN_DART "ModelsMP\\Enemies\\Shooters\\Arrow01.tex",
// ********** GUFFY PROJECTILE **********
170 model MODEL_GUFFY_PROJECTILE "ModelsMP\\Enemies\\Guffy\\Projectile\\GuffyProjectile.mdl",
171 texture TEXTURE_GUFFY_PROJECTILE "ModelsMP\\Enemies\\Guffy\\Projectile\\GuffyProjectile.tex",
// ********** LARVA PROJECTILES **********
172 model MODEL_LARVA_PLASMA "ModelsMP\\Enemies\\ExotechLarva\\Projectile\\Projectile.mdl",
173 texture TEXTURE_LARVA_PLASMA "ModelsMP\\Enemies\\ExotechLarva\\Projectile\\Projectile.tex",
174 model MODEL_LARVA_PLASMA_BALL "ModelsMP\\Enemies\\ExotechLarva\\Weapons\\PlasmaGun.mdl",
175 texture TEXTURE_LARVA_PLASMA_BALL "ModelsMP\\Enemies\\ExotechLarva\\Weapons\\PlasmaGun.tex",
176 model MODEL_LARVA_TAIL "ModelsMP\\Enemies\\ExotechLarva\\Projectile\\TailProjectile.mdl",
177 texture TEXTURE_LARVA_TAIL "ModelsMP\\Enemies\\ExotechLarva\\Projectile\\TailProjectile.tex",
178 sound SOUND_LARVETTE "ModelsMP\\Enemies\\ExotechLarva\\Sounds\\Squeak.wav",
// ********** AIR ELEMENTAL WIND BLAST **********
180 model MODEL_WINDBLAST "ModelsMP\\Enemies\\AirElemental\\Projectile\\WindBlast.mdl",
181 texture TEXTURE_WINDBLAST "ModelsMP\\Enemies\\AirElemental\\Projectile\\WindBlast.tex",
// ****************** METEOR ******************
185 sound SOUND_METEOR_BLAST "SoundsMP\\Weapons\\MeteorBlast.wav",
// ************** REFLECTIONS **************
200 texture TEX_REFL_BWRIPLES01 "Models\\ReflectionTextures\\BWRiples01.tex",
201 texture TEX_REFL_BWRIPLES02 "Models\\ReflectionTextures\\BWRiples02.tex",
202 texture TEX_REFL_LIGHTMETAL01 "Models\\ReflectionTextures\\LightMetal01.tex",
203 texture TEX_REFL_LIGHTBLUEMETAL01 "Models\\ReflectionTextures\\LightBlueMetal01.tex",
204 texture TEX_REFL_DARKMETAL "Models\\ReflectionTextures\\DarkMetal.tex",
205 texture TEX_REFL_PURPLE01 "Models\\ReflectionTextures\\Purple01.tex",
// ************** SPECULAR **************
210 texture TEX_SPEC_WEAK "Models\\SpecularTextures\\Weak.tex",
211 texture TEX_SPEC_MEDIUM "Models\\SpecularTextures\\Medium.tex",
212 texture TEX_SPEC_STRONG "Models\\SpecularTextures\\Strong.tex",
220 model MODEL_MARKER "Models\\Editor\\Axis.mdl",
221 texture TEXTURE_MARKER "Models\\Editor\\Vector.tex"
functions:
// premoving
void PreMoving(void) {
if (m_tmExpandBox>0) {
if (_pTimer->CurrentTick()>m_fStartTime+m_tmExpandBox) {
ChangeCollisionBoxIndexWhenPossible(1);
m_tmExpandBox = 0;
}
}
CMovableModelEntity::PreMoving();
}
// postmoving
void PostMoving(void) {
CMovableModelEntity::PostMoving();
// if flamer flame
if (m_prtType==PRT_FLAME || m_prtType==PRT_SHOOTER_FLAME) {
// if came to water
CContentType &ctDn = GetWorld()->wo_actContentTypes[en_iDnContent];
// stop existing
if (!(ctDn.ct_ulFlags&CTF_BREATHABLE_LUNGS)) {
m_fWaitAfterDeath = 0.0f; // immediate stop
SendEvent(EEnd());
}
}
};
/* Read from stream. */
void Read_t( CTStream *istr) // throw char *
{
CMovableModelEntity::Read_t(istr);
// setup light source
if( m_bLightSource) {
SetupLightSource(TRUE);
}
}
// dump sync data to text file
export void DumpSync_t(CTStream &strm, INDEX iExtensiveSyncCheck) // throw char *
{
CMovableModelEntity ::DumpSync_t(strm, iExtensiveSyncCheck);
strm.FPrintF_t("projectile type: %d\n", m_prtType);
strm.FPrintF_t("launcher:");
if (m_penLauncher!=NULL) {
strm.FPrintF_t("id:%05d '%s'(%s) (%g, %g, %g)\n",
m_penLauncher->en_ulID,
m_penLauncher->GetName(), m_penLauncher->GetClass()->ec_pdecDLLClass->dec_strName,
m_penLauncher->GetPlacement().pl_PositionVector(1),
m_penLauncher->GetPlacement().pl_PositionVector(2),
m_penLauncher->GetPlacement().pl_PositionVector(3));
} else {
strm.FPrintF_t("<none>\n");
}
}
/* Get static light source information. */
CLightSource *GetLightSource(void)
{
if( m_bLightSource && !IsPredictor()) {
return &m_lsLightSource;
} else {
return NULL;
}
}
export void Copy(CEntity &enOther, ULONG ulFlags)
{
CMovableModelEntity::Copy(enOther, ulFlags);
CProjectile *penOther = (CProjectile *)(&enOther);
if (ulFlags&COPY_PREDICTOR) {
//m_lsLightSource;
//SetupLightSource(); //? is this ok !!!!
m_bLightSource = FALSE;
}
}
BOOL AdjustShadingParameters(FLOAT3D &vLightDirection, COLOR &colLight, COLOR &colAmbient)
{
// if time now is inside invisibility time, don't render model
CModelObject *pmo = GetModelObject();
if ( (pmo != NULL) && (_pTimer->GetLerpedCurrentTick() < (m_fStartTime+m_tmInvisibility) ) )
{
// make it invisible
pmo->mo_colBlendColor = 0;
}
else
{
// make it visible
pmo->mo_colBlendColor = C_WHITE|CT_OPAQUE;
}
return CEntity::AdjustShadingParameters(vLightDirection, colLight, colAmbient);
}
// Setup light source
void SetupLightSource(BOOL bLive)
{
// setup light source
CLightSource lsNew;
lsNew.ls_ulFlags = LSF_NONPERSISTENT|LSF_DYNAMIC;
lsNew.ls_rHotSpot = 0.0f;
switch (m_prtType) {
case PRT_ROCKET:
case PRT_WALKER_ROCKET:
case PRT_DEVIL_ROCKET:
if( bLive)
{
lsNew.ls_colColor = 0xA0A080FF;
}
else
{
lsNew.ls_colColor = C_BLACK|CT_OPAQUE;
}
lsNew.ls_rFallOff = 5.0f;
lsNew.ls_plftLensFlare = &_lftYellowStarRedRingFar;
break;
case PRT_GUFFY_PROJECTILE:
lsNew.ls_colColor = C_BLUE;
lsNew.ls_rFallOff = 1.5f;
lsNew.ls_plftLensFlare = NULL;
case PRT_GRENADE:
lsNew.ls_colColor = 0x2F1F0F00;
lsNew.ls_rFallOff = 2.0f;
lsNew.ls_rHotSpot = 0.2f;
lsNew.ls_plftLensFlare = &_lftYellowStarRedRingFar;
break;
case PRT_FLAME:
lsNew.ls_colColor = C_dORANGE;
lsNew.ls_rFallOff = 1.0f;
lsNew.ls_plftLensFlare = NULL;
break;
case PRT_LASER_RAY:
lsNew.ls_colColor = C_vdGREEN;
lsNew.ls_rFallOff = 1.5f;
lsNew.ls_plftLensFlare = NULL;
break;
case PRT_GRUNT_PROJECTILE_SOL:
lsNew.ls_colColor = C_vdRED;
lsNew.ls_rFallOff = 1.5f;
lsNew.ls_plftLensFlare = NULL;
break;
case PRT_GRUNT_PROJECTILE_COM:
lsNew.ls_colColor = C_vdRED;
lsNew.ls_rFallOff = 1.5f;
lsNew.ls_plftLensFlare = NULL;
break;
case PRT_CATMAN_FIRE:
lsNew.ls_colColor = C_BLUE;
lsNew.ls_rFallOff = 3.5f;
lsNew.ls_plftLensFlare = &_lftCatmanFireGlow;
break;
case PRT_HEADMAN_FIRECRACKER:
lsNew.ls_colColor = C_ORANGE;
lsNew.ls_rFallOff = 1.5f;
lsNew.ls_plftLensFlare = NULL;
break;
case PRT_HEADMAN_ROCKETMAN:
lsNew.ls_colColor = C_YELLOW;
lsNew.ls_rFallOff = 1.5f;
lsNew.ls_plftLensFlare = NULL;
break;
case PRT_WOMAN_FIRE:
lsNew.ls_colColor = C_WHITE;
lsNew.ls_rFallOff = 3.5f;
lsNew.ls_plftLensFlare = &_lftCatmanFireGlow;
break;
case PRT_DRAGONMAN_FIRE:
lsNew.ls_colColor = C_YELLOW;
lsNew.ls_rFallOff = 3.5f;
lsNew.ls_plftLensFlare = &_lftProjectileYellowBubbleGlow;
break;
case PRT_DRAGONMAN_STRONG_FIRE:
lsNew.ls_colColor = C_RED;
lsNew.ls_rFallOff = 3.5f;
lsNew.ls_plftLensFlare = &_lftProjectileStarGlow;
break;
case PRT_HUANMAN_FIRE:
lsNew.ls_colColor = C_lBLUE;
lsNew.ls_rFallOff = 2.0f;
lsNew.ls_plftLensFlare = NULL;
break;
case PRT_FISHMAN_FIRE:
lsNew.ls_colColor = C_lBLUE;
lsNew.ls_rFallOff = 2.0f;
lsNew.ls_plftLensFlare = NULL;
break;
case PRT_MANTAMAN_FIRE:
lsNew.ls_colColor = C_lBLUE;
lsNew.ls_rFallOff = 2.0f;
lsNew.ls_plftLensFlare = NULL;
break;
case PRT_CYBORG_LASER:
lsNew.ls_colColor = C_dBLUE;
lsNew.ls_rFallOff = 1.5f;
lsNew.ls_plftLensFlare = NULL;
break;
case PRT_DEVIL_LASER:
lsNew.ls_colColor = C_dBLUE;
lsNew.ls_rFallOff = 5.0f;
lsNew.ls_plftLensFlare = &_lftYellowStarRedRingFar;
break;
case PRT_LARVA_PLASMA:
lsNew.ls_colColor = C_dBLUE;
lsNew.ls_rFallOff = 5.0f;
lsNew.ls_plftLensFlare = &_lftCatmanFireGlow;
break;
case PRT_SHOOTER_FIREBALL:
lsNew.ls_colColor = C_dORANGE;
lsNew.ls_rFallOff = 5.0f;
lsNew.ls_plftLensFlare = &_lftYellowStarRedRingFar;
break;
case PRT_SHOOTER_FLAME:
lsNew.ls_colColor = C_dORANGE;
lsNew.ls_rFallOff = 1.0f;
lsNew.ls_plftLensFlare = NULL;
break;
default:
ASSERTALWAYS("Unknown light source");
}
lsNew.ls_ubPolygonalMask = 0;
lsNew.ls_paoLightAnimation = NULL;
m_lsLightSource.ls_penEntity = this;
m_lsLightSource.SetLightSource(lsNew);
}
// render particles
void RenderParticles(void) {
switch (m_prtType) {
case PRT_ROCKET:
case PRT_WALKER_ROCKET: Particles_RocketTrail(this, 1.0f); break;
case PRT_DEVIL_ROCKET: Particles_RocketTrail(this, 8.0f); break;
case PRT_GUFFY_PROJECTILE: break;// Particles_RocketTrail(this, 1.0f); break;
case PRT_GRENADE: {
//Particles_GrenadeTrail(this);
FLOAT fSpeedRatio = en_vCurrentTranslationAbsolute.Length()/140.0f;
Particles_CannonBall(this, fSpeedRatio);
break;
}
case PRT_FLAME: {
// elapsed time
FLOAT fLeaderLiving, fFollowerLiving, fInFrontLiving;
fInFrontLiving=0.05f;
fLeaderLiving = _pTimer->GetLerpedCurrentTick() - m_fStartTime;
// not NULL or deleted
if (m_penParticles!=NULL && !(m_penParticles->GetFlags()&ENF_DELETED)) {
FLOAT3D vDirLeader=en_vCurrentTranslationAbsolute;
vDirLeader.Normalize();
// if last is not flame thrower pipe
if(IsOfClass(m_penParticles, "Projectile"))
{
CProjectile &prLast=(CProjectile &)*m_penParticles;
// if pre last is flame thrower pipe
if( IsOfClass(prLast.m_penParticles, "Player Weapons"))
{
CPlayerWeapons &plw=(CPlayerWeapons&)*prLast.m_penParticles;
if(!(plw.GetPlayer()->GetFlags()&ENF_ALIVE))
{
return;
}
CPlacement3D plPipe, plInFrontOfPipe;
((CPlayerWeapons&)*prLast.m_penParticles).GetFlamerSourcePlacement(plPipe, plInFrontOfPipe);
fFollowerLiving = _pTimer->GetLerpedCurrentTick() - ((CProjectile&)*m_penParticles).m_fStartTime;
FLOAT3D vDirPipeFront;
AnglesToDirectionVector( plInFrontOfPipe.pl_OrientationAngle, vDirPipeFront);
vDirPipeFront.Normalize();
Particles_FlameThrower(GetLerpedPlacement(), plInFrontOfPipe,
vDirLeader, vDirPipeFront,
fLeaderLiving, fInFrontLiving, en_ulID, FALSE);
}
// draw particles with another projectile
else
{
fFollowerLiving = _pTimer->GetLerpedCurrentTick() - ((CProjectile&)*m_penParticles).m_fStartTime;
FLOAT3D vDirFollower = ((CMovableModelEntity*)(CEntity*)m_penParticles)->en_vCurrentTranslationAbsolute;
vDirFollower.Normalize();
Particles_FlameThrower(GetLerpedPlacement(), m_penParticles->GetLerpedPlacement(),
vDirLeader, vDirFollower, fLeaderLiving, fFollowerLiving, en_ulID, FALSE);
}
// draw particles with player weapons
} else if (IsOfClass(m_penParticles, "Player Weapons")) {
CPlayerWeapons &plw=(CPlayerWeapons&)*m_penParticles;
if(!(plw.GetPlayer()->GetFlags()&ENF_ALIVE))
{
return;
}
CPlacement3D plPipe, plInFrontOfPipe;
plw.GetFlamerSourcePlacement(plPipe, plInFrontOfPipe);
FLOAT3D vDirPipeFront;
AnglesToDirectionVector( plInFrontOfPipe.pl_OrientationAngle, vDirPipeFront);
FLOAT3D vViewDir;
AnglesToDirectionVector( plPipe.pl_OrientationAngle, vViewDir);
FLOAT3D vDirFollower = vViewDir.Normalize();
/*
Particles_FlameThrower(GetLerpedPlacement(), plPipe,
vDirLeader, vDirFollower,
fLeaderLiving, 0.0f, en_ulID, TRUE);
*/
Particles_FlameThrower(plInFrontOfPipe, plPipe,
vDirPipeFront, vDirFollower,
fInFrontLiving, 0.0f, en_ulID, TRUE);
Particles_FlameThrowerStart(plPipe, plw.m_tmFlamerStart, plw.m_tmFlamerStop);
}
}
break;
}
case PRT_CATMAN_FIRE: Particles_RocketTrail(this, 1.0f); break;
case PRT_HEADMAN_FIRECRACKER: Particles_FirecrackerTrail(this); break;
case PRT_HEADMAN_ROCKETMAN: Particles_Fireball01Trail(this); break;
case PRT_HEADMAN_BOMBERMAN: Particles_BombTrail(this); break;
case PRT_LAVA_COMET: Particles_LavaTrail(this); break;
case PRT_LAVAMAN_BIG_BOMB: Particles_LavaBombTrail(this, 4.0f); break;
case PRT_LAVAMAN_BOMB: Particles_LavaBombTrail(this, 1.0f); break;
case PRT_BEAST_PROJECTILE: Particles_BeastProjectileTrail( this, 2.0f, 0.25f, 48); break;
case PRT_BEAST_BIG_PROJECTILE:
case PRT_DEMON_FIREBALL:
Particles_BeastBigProjectileTrail( this, 4.0f, 0.25f, 0.0f, 64);
Particles_AfterBurner( this, m_fStartTime, 1.0f);
break;
case PRT_DEVIL_GUIDED_PROJECTILE:
Particles_BeastBigProjectileTrail( this, 6.0f, 0.375f, 0.0f, 64);
break;
case PRT_BEAST_DEBRIS: Particles_BeastProjectileDebrisTrail(this, 0.20f); break;
case PRT_BEAST_BIG_DEBRIS: Particles_BeastProjectileDebrisTrail(this, 0.25f); break;
case PRT_SHOOTER_WOODEN_DART: Particles_RocketTrail(this, 0.25f); break;
case PRT_SHOOTER_FIREBALL: Particles_Fireball01Trail(this); break;
case PRT_SHOOTER_FLAME: {
// elapsed time
FLOAT fTimeElapsed, fParticlesTimeElapsed;
fTimeElapsed = _pTimer->GetLerpedCurrentTick() - m_fStartTime;
// not NULL or deleted
if (m_penParticles!=NULL && !(m_penParticles->GetFlags()&ENF_DELETED)) {
// draw particles with another projectile
if (IsOfClass(m_penParticles, "Projectile")) {
fParticlesTimeElapsed = _pTimer->GetLerpedCurrentTick() - ((CProjectile&)*m_penParticles).m_fStartTime;
Particles_ShooterFlame(GetLerpedPlacement(), m_penParticles->GetLerpedPlacement(),
fTimeElapsed, fParticlesTimeElapsed);
} else if (IsOfClass(m_penParticles, "Shooter")) {
Particles_ShooterFlame(GetLerpedPlacement(),
((CShooter&)*m_penParticles).GetPlacement(),
fTimeElapsed, 0.0f);
}
}
break;
}
case PRT_METEOR:
Particles_MeteorTrail(this, m_fStretch, 1.0f, en_vCurrentTranslationAbsolute);
Particles_AfterBurner(this, m_fStartTime, m_fStretch*4.0f, 2);
break;
case PRT_AFTERBURNER_DEBRIS:
Particles_AfterBurner(this, m_fStartTime, m_fStretch);
break;
case PRT_AIRELEMENTAL_WIND:
Particles_Windblast(this, m_fStretch/4.0f, m_fStartTime+3.0f);
break;
}
}
/************************************************************
* PLAYER ROCKET / GRENADE *
************************************************************/
void PlayerRocket(void) {
// set appearance
InitAsModel();
SetPhysicsFlags(EPF_PROJECTILE_FLYING);
SetCollisionFlags(ECF_PROJECTILE_SOLID);
SetModel(MODEL_ROCKET);
SetModelMainTexture(TEXTURE_ROCKET);
// start moving
LaunchAsPropelledProjectile(FLOAT3D(0.0f, 0.0f, -30.0f), (CMovableEntity*)(CEntity*)m_penLauncher);
SetDesiredRotation(ANGLE3D(0, 0, 0));
// play the flying sound
m_soEffect.Set3DParameters(20.0f, 2.0f, 1.0f, 1.0f);
PlaySound(m_soEffect, SOUND_FLYING, SOF_3D|SOF_LOOP);
m_fFlyTime = 30.0f;
if( GetSP()->sp_bCooperative)
{
m_fDamageAmount = 100.0f;
m_fRangeDamageAmount = 50.0f;
}
else
{
m_fDamageAmount = 75.0f;
m_fRangeDamageAmount = 75.0f;
}
m_fDamageHotSpotRange = 4.0f;
m_fDamageFallOffRange = 8.0f;
m_fSoundRange = 50.0f;
m_bExplode = TRUE;
m_bLightSource = TRUE;
m_bCanHitHimself = TRUE;
m_bCanBeDestroyed = TRUE;
m_fWaitAfterDeath = 1.125f;
m_tmExpandBox = 0.1f;
m_tmInvisibility = 0.05f;
SetHealth(5.0f);
m_pmtMove = PMT_FLYING;
};
void WalkerRocket(void) {
// set appearance
InitAsModel();
SetPhysicsFlags(EPF_PROJECTILE_FLYING);
SetCollisionFlags(ECF_PROJECTILE_SOLID);
SetModel(MODEL_ROCKET);
SetModelMainTexture(TEXTURE_ROCKET);
// start moving
LaunchAsPropelledProjectile(FLOAT3D(0.0f, 0.0f, -30.0f), (CMovableEntity*)(CEntity*)m_penLauncher);
SetDesiredRotation(ANGLE3D(0, 0, 0));
// play the flying sound
m_soEffect.Set3DParameters(20.0f, 2.0f, 1.0f, 1.0f);
PlaySound(m_soEffect, SOUND_FLYING, SOF_3D|SOF_LOOP);
m_fFlyTime = 30.0f;
if (GetSP()->sp_gdGameDifficulty<=CSessionProperties::GD_EASY) {
m_fDamageAmount = 40.0f;
m_fRangeDamageAmount = 20.0f;
} else {
m_fDamageAmount = 100.0f;
m_fRangeDamageAmount = 50.0f;
}
m_fDamageHotSpotRange = 4.0f;
m_fDamageFallOffRange = 8.0f;
m_fSoundRange = 50.0f;
m_bExplode = TRUE;
m_bLightSource = TRUE;
m_bCanHitHimself = TRUE;
m_bCanBeDestroyed = TRUE;
m_fWaitAfterDeath = 1.125f;
m_tmExpandBox = 0.1f;
m_tmInvisibility = 0.05f;
SetHealth(5.0f);
m_pmtMove = PMT_FLYING;
};
void WalkerRocketExplosion(void) {
PlayerRocketExplosion();
}
void PlayerRocketExplosion(void) {
ESpawnEffect ese;
FLOAT3D vPoint;
FLOATplane3D vPlaneNormal;
FLOAT fDistanceToEdge;
// explosion
ese.colMuliplier = C_WHITE|CT_OPAQUE;
ese.betType = BET_ROCKET;
ese.vStretch = FLOAT3D(1,1,1);
SpawnEffect(GetPlacement(), ese);
// spawn sound event in range
if( IsDerivedFromClass( m_penLauncher, "Player")) {
SpawnRangeSound( m_penLauncher, this, SNDT_PLAYER, m_fSoundRange);
}
// explosion debris
ese.betType = BET_EXPLOSION_DEBRIS;
SpawnEffect(GetPlacement(), ese);
// explosion smoke
ese.betType = BET_EXPLOSION_SMOKE;
SpawnEffect(GetPlacement(), ese);
// on plane
if (GetNearestPolygon(vPoint, vPlaneNormal, fDistanceToEdge)) {
if ((vPoint-GetPlacement().pl_PositionVector).Length() < 3.5f) {
// stain
ese.betType = BET_EXPLOSIONSTAIN;
ese.vNormal = FLOAT3D(vPlaneNormal);
SpawnEffect(CPlacement3D(vPoint, ANGLE3D(0, 0, 0)), ese);
// shock wave
ese.betType = BET_SHOCKWAVE;
ese.vNormal = FLOAT3D(vPlaneNormal);
SpawnEffect(CPlacement3D(vPoint, ANGLE3D(0, 0, 0)), ese);
// second explosion on plane
ese.betType = BET_ROCKET_PLANE;
ese.vNormal = FLOAT3D(vPlaneNormal);
SpawnEffect(CPlacement3D(vPoint+ese.vNormal/50.0f, ANGLE3D(0, 0, 0)), ese);
}
}
};
void PlayerGrenade(void) {
// set appearance
InitAsModel();
SetPhysicsFlags(EPF_MODEL_BOUNCING);
SetCollisionFlags(ECF_PROJECTILE_SOLID);
SetModel(MODEL_GRENADE);
SetModelMainTexture(TEXTURE_GRENADE);
// start moving
LaunchAsFreeProjectile(FLOAT3D(0.0f, 5.0f, -m_fSpeed), (CMovableEntity*)&*m_penLauncher);
SetDesiredRotation(ANGLE3D(0, FRnd()*120.0f+120.0f, FRnd()*250.0f-125.0f));
en_fBounceDampNormal = 0.75f;
en_fBounceDampParallel = 0.6f;
en_fJumpControlMultiplier = 0.0f;
en_fCollisionSpeedLimit = 45.0f;
en_fCollisionDamageFactor = 10.0f;
m_fFlyTime = 3.0f;
m_fDamageAmount = 75.0f;
m_fRangeDamageAmount = 100.0f;
m_fDamageHotSpotRange = 4.0f;
m_fDamageFallOffRange = 8.0f;
m_fSoundRange = 50.0f;
m_bExplode = TRUE;
en_fDeceleration = 25.0f;
m_bLightSource = TRUE;
m_bCanHitHimself = TRUE;
m_bCanBeDestroyed = TRUE;
m_fWaitAfterDeath = 0.0f;
SetHealth(20.0f);
m_pmtMove = PMT_SLIDING;
m_tmInvisibility = 0.05f;
m_tmExpandBox = 0.1f;
};
void PlayerGrenadeExplosion(void) {
ESpawnEffect ese;
FLOAT3D vPoint;
FLOATplane3D vPlaneNormal;
FLOAT fDistanceToEdge;
// explosion
ese.colMuliplier = C_WHITE|CT_OPAQUE;
ese.betType = BET_GRENADE;
ese.vStretch = FLOAT3D(1,1,1);
SpawnEffect(GetPlacement(), ese);
// spawn sound event in range
if( IsDerivedFromClass( m_penLauncher, "Player")) {
SpawnRangeSound( m_penLauncher, this, SNDT_PLAYER, m_fSoundRange);
}
// on plane
if (GetNearestPolygon(vPoint, vPlaneNormal, fDistanceToEdge)) {
if ((vPoint-GetPlacement().pl_PositionVector).Length() < 3.5f) {
// wall stain
ese.betType = BET_EXPLOSIONSTAIN;
ese.vNormal = FLOAT3D(vPlaneNormal);
SpawnEffect(CPlacement3D(vPoint, ANGLE3D(0, 0, 0)), ese);
// shock wave
ese.betType = BET_SHOCKWAVE;
ese.vNormal = FLOAT3D(vPlaneNormal);
SpawnEffect(CPlacement3D(vPoint, ANGLE3D(0, 0, 0)), ese);
// second explosion on plane
ese.betType = BET_GRENADE_PLANE;
ese.vNormal = FLOAT3D(vPlaneNormal);
SpawnEffect(CPlacement3D(vPoint+ese.vNormal/50.0f, ANGLE3D(0, 0, 0)), ese);
}
}
};
/************************************************************
* PLAYER FLAME *
************************************************************/
void PlayerFlame(void) {
// set appearance
InitAsEditorModel();
SetPhysicsFlags(EPF_MODEL_SLIDING&~EPF_TRANSLATEDBYGRAVITY&~EPF_ORIENTEDBYGRAVITY);
//SetPhysicsFlags(EPF_PROJECTILE_FLYING);
SetCollisionFlags(ECF_PROJECTILE_MAGIC);
SetFlags(GetFlags() | ENF_SEETHROUGH);
SetModel(MODEL_FLAME);
//SetModel(MODEL_BEAST_FIRE);
//SetModelMainTexture(TEXTURE_ROCKET);
// add player's forward velocity to flame
CMovableEntity *penPlayer = (CMovableEntity*)(CEntity*)m_penLauncher;
FLOAT3D vDirection = penPlayer->en_vCurrentTranslationAbsolute;
FLOAT3D vFront = -GetRotationMatrix().GetColumn(3);
FLOAT fSpeedFwd = ClampDn( vDirection%vFront, 0.0f);
// start moving
LaunchAsPropelledProjectile(FLOAT3D(0.0f, 0.0f, -(25.0f+fSpeedFwd)), penPlayer);
SetDesiredRotation(ANGLE3D(0, 0, 0));
m_fFlyTime = 1.0f;
m_fDamageAmount = (GetSP()->sp_bCooperative) ? 10.0f : 4.0f;
m_fSoundRange = 0.0f;
m_bExplode = FALSE;
m_bLightSource = TRUE;
m_bCanHitHimself = FALSE;
m_bCanBeDestroyed = FALSE;
m_fWaitAfterDeath = 0.3f;
m_tmExpandBox = 0.1f;
m_pmtMove = PMT_SLIDING;
};
/************************************************************
* PLAYER LASER *
************************************************************/
void PlayerLaserRay(void) {
// set appearance
InitAsModel();
SetPhysicsFlags(EPF_PROJECTILE_FLYING);
SetCollisionFlags(ECF_PROJECTILE_SOLID);
SetFlags(GetFlags() | ENF_SEETHROUGH);
SetModel(MODEL_LASER);
CModelObject *pmo = GetModelObject();
if(pmo != NULL)
{
pmo->PlayAnim( LASERPROJECTILE_ANIM_GROW, 0);
}
SetModelMainTexture(TEXTURE_GREEN_LASER);
// start moving
LaunchAsPropelledProjectile(FLOAT3D(0.0f, 0.0f, -120.0f), (CMovableEntity*)(CEntity*)m_penLauncher);
SetDesiredRotation(ANGLE3D(0, 0, 0));
m_fFlyTime = 3.0f;
m_fDamageAmount = 20.0f;
m_fSoundRange = 0.0f;
m_bExplode = FALSE;
m_bLightSource = TRUE;
m_bCanHitHimself = FALSE;
m_bCanBeDestroyed = FALSE;
m_fWaitAfterDeath = 0.0f;
m_tmExpandBox = 0.1f;
// time when laser ray becomes visible
m_tmInvisibility = 0.025f;
m_pmtMove = PMT_FLYING;
};
void PlayerLaserWave(void) {
ESpawnEffect ese;
FLOAT3D vPoint;
FLOATplane3D vPlaneNormal;
FLOAT fDistanceToEdge;
// on plane
if (GetNearestPolygon(vPoint, vPlaneNormal, fDistanceToEdge)) {
if ((vPoint-GetPlacement().pl_PositionVector).Length() < 3.5f) {
// shock wave
ese.colMuliplier = C_dRED|CT_OPAQUE;
ese.betType = BET_LASERWAVE;
ese.vNormal = FLOAT3D(vPlaneNormal);
SpawnEffect(CPlacement3D(vPoint, ANGLE3D(0, 0, 0)), ese);
}
}
};
/************************************************************
* CATMAN PROJECTILE *
************************************************************/
void CatmanProjectile(void) {
// set appearance
InitAsModel();
SetPhysicsFlags(EPF_PROJECTILE_FLYING);
SetCollisionFlags(ECF_PROJECTILE_MAGIC);
SetFlags(GetFlags() | ENF_SEETHROUGH);
SetModel(MODEL_CATMAN_FIRE);
SetModelMainTexture(TEXTURE_CATMAN_FIRE);
// start moving
LaunchAsPropelledProjectile(FLOAT3D(0.0f, 0.0f, -15.0f), (CMovableEntity*)(CEntity*)m_penLauncher);
SetDesiredRotation(ANGLE3D(0, 0, 0));
m_fFlyTime = 5.0f;
m_fDamageAmount = 5.0f;
m_fSoundRange = 0.0f;
m_bExplode = FALSE;
m_bLightSource = TRUE;
m_bCanHitHimself = FALSE;
m_bCanBeDestroyed = FALSE;
m_fWaitAfterDeath = 0.0f;
m_pmtMove = PMT_FLYING;
};
/************************************************************
* HEADMAN PROJECTILE *
************************************************************/
void HeadmanFirecracker(void) {
// set appearance
InitAsModel();
SetPhysicsFlags(EPF_MODEL_SLIDING);
SetCollisionFlags(ECF_PROJECTILE_MAGIC);
SetFlags(GetFlags() | ENF_SEETHROUGH);
SetModel(MODEL_HEADMAN_FIRECRACKER);
SetModelMainTexture(TEXTURE_HEADMAN_FIRECRACKER);
GetModelObject()->StretchModel(FLOAT3D(0.75f, 0.75f, 0.75f));
ModelChangeNotify();
// start moving
LaunchAsPropelledProjectile(FLOAT3D(0.0f, 0.0f, -25.0f), (CMovableEntity*)(CEntity*)m_penLauncher);
SetDesiredRotation(ANGLE3D(0, 0, FRnd()*20.0f-10.0f));
m_fFlyTime = 5.0f;
m_fDamageAmount = 4.0f;
m_fSoundRange = 0.0f;
m_bExplode = FALSE;
m_bLightSource = FALSE;
m_bCanHitHimself = FALSE;
m_bCanBeDestroyed = FALSE;
m_fWaitAfterDeath = 0.0f;
m_pmtMove = PMT_SLIDING;
};
void HeadmanRocketman(void) {
// set appearance
InitAsModel();
SetPhysicsFlags(EPF_PROJECTILE_FLYING);
SetCollisionFlags(ECF_PROJECTILE_MAGIC);
SetFlags(GetFlags() | ENF_SEETHROUGH);
SetComponents(this, *GetModelObject(), MODEL_HEADMAN_BLADE, TEXTURE_HEADMAN_BLADE,
TEX_REFL_LIGHTBLUEMETAL01, TEX_SPEC_MEDIUM, 0);
AddAttachmentToModel(this, *GetModelObject(), BLADE_ATTACHMENT_FLAME01,
MODEL_HEADMAN_BLADE_FLAME, TEXTURE_HEADMAN_BLADE_FLAME, 0, 0, 0);
AddAttachmentToModel(this, *GetModelObject(), BLADE_ATTACHMENT_FLAME02,
MODEL_HEADMAN_BLADE_FLAME, TEXTURE_HEADMAN_BLADE_FLAME, 0, 0, 0);
AddAttachmentToModel(this, *GetModelObject(), BLADE_ATTACHMENT_FLAME03,
MODEL_HEADMAN_BLADE_FLAME, TEXTURE_HEADMAN_BLADE_FLAME, 0, 0, 0);
GetModelObject()->StretchModel(FLOAT3D(0.5f, 0.5f, 0.5f));
ModelChangeNotify();
// start moving
LaunchAsPropelledProjectile(FLOAT3D(0.0f, 0.0f, -30.0f), (CMovableEntity*)(CEntity*)m_penLauncher);
SetDesiredRotation(ANGLE3D(0, 0, 0));
m_fFlyTime = 5.0f;
m_fDamageAmount = 5.0f;
m_fSoundRange = 0.0f;
m_bExplode = FALSE;
m_bLightSource = TRUE;
m_bCanHitHimself = FALSE;
m_bCanBeDestroyed = FALSE;
m_fWaitAfterDeath = 0.0f;
m_pmtMove = PMT_FLYING;
};
void HeadmanBomberman(void) {
// set appearance
InitAsModel();
SetPhysicsFlags(EPF_MODEL_BOUNCING);
SetCollisionFlags(ECF_PROJECTILE_SOLID);
SetModel(MODEL_HEADMAN_BOMB);
SetModelMainTexture(TEXTURE_HEADMAN_BOMB);
// start moving
LaunchAsFreeProjectile(FLOAT3D(0.0f, 0.0f, -m_fSpeed), (CMovableEntity*)&*m_penLauncher);
SetDesiredRotation(ANGLE3D(0, FRnd()*360.0f-180.0f, FRnd()*360.0f-180.0f));
m_fFlyTime = 2.5f;
m_fDamageAmount = 10.0f;
m_fRangeDamageAmount = 15.0f;
m_fDamageHotSpotRange = 1.0f;
m_fDamageFallOffRange = 6.0f;
m_fSoundRange = 25.0f;
m_bExplode = TRUE;
m_bLightSource = FALSE;
m_bCanHitHimself = TRUE;
m_bCanBeDestroyed = TRUE;
m_fWaitAfterDeath = 0.0f;
SetHealth(5.0f);
m_pmtMove = PMT_FLYING;
};
void HeadmanBombermanExplosion(void) {
ESpawnEffect ese;
FLOAT3D vPoint;
FLOATplane3D vPlaneNormal;
FLOAT fDistanceToEdge;
// explosion
ese.colMuliplier = C_WHITE|CT_OPAQUE;
ese.betType = BET_BOMB;
ese.vStretch = FLOAT3D(1.0f,1.0f,1.0f);
SpawnEffect(GetPlacement(), ese);
// on plane
if (GetNearestPolygon(vPoint, vPlaneNormal, fDistanceToEdge)) {
if ((vPoint-GetPlacement().pl_PositionVector).Length() < 3.5f) {
// wall stain
ese.betType = BET_EXPLOSIONSTAIN;
ese.vNormal = FLOAT3D(vPlaneNormal);
SpawnEffect(CPlacement3D(vPoint, ANGLE3D(0, 0, 0)), ese);
ese.betType = BET_GRENADE_PLANE;
ese.vNormal = FLOAT3D(vPlaneNormal);
SpawnEffect(CPlacement3D(vPoint+ese.vNormal/50.0f, ANGLE3D(0, 0, 0)), ese);
}
}
};
void CyborgBombExplosion(void)
{
ESpawnEffect ese;
FLOAT3D vPoint;
FLOATplane3D vPlaneNormal;
FLOAT fDistanceToEdge;
// explosion
ese.colMuliplier = C_WHITE|CT_OPAQUE;
ese.betType = BET_BOMB;
ese.vStretch = FLOAT3D(1.0f,1.0f,1.0f);
SpawnEffect(GetPlacement(), ese);
// on plane
if (GetNearestPolygon(vPoint, vPlaneNormal, fDistanceToEdge)) {
if ((vPoint-GetPlacement().pl_PositionVector).Length() < 3.5f) {
// wall stain
ese.betType = BET_EXPLOSIONSTAIN;
ese.vNormal = FLOAT3D(vPlaneNormal);
SpawnEffect(CPlacement3D(vPoint, ANGLE3D(0, 0, 0)), ese);
ese.betType = BET_GRENADE_PLANE;
ese.vNormal = FLOAT3D(vPlaneNormal);
SpawnEffect(CPlacement3D(vPoint+ese.vNormal/50.0f, ANGLE3D(0, 0, 0)), ese);
}
}
};
/************************************************************
* BONEMAN PROJECTILE *
************************************************************/
void BonemanProjectile(void) {
// set appearance
InitAsModel();
SetPhysicsFlags(EPF_PROJECTILE_FLYING);
SetCollisionFlags(ECF_PROJECTILE_MAGIC);
SetFlags(GetFlags() | ENF_SEETHROUGH);
SetModel(MODEL_BONEMAN_FIRE);
SetModelMainTexture(TEXTURE_BONEMAN_FIRE);
// start moving
LaunchAsPropelledProjectile(FLOAT3D(0.0f, 0.0f, -30.0f), (CMovableEntity*)(CEntity*)m_penLauncher);
SetDesiredRotation(ANGLE3D(0, 0, 0));
m_fFlyTime = 5.0f;
m_fDamageAmount = 10.0f;
m_fSoundRange = 0.0f;
m_bExplode = FALSE;
m_bLightSource = FALSE;
m_bCanHitHimself = FALSE;
m_bCanBeDestroyed = FALSE;
m_fWaitAfterDeath = 0.0f;
m_pmtMove = PMT_SLIDING;
};
/************************************************************
* WOMAN PROJECTILE *
************************************************************/
void WomanProjectile(void) {
// set appearance
InitAsModel();
SetPhysicsFlags(EPF_PROJECTILE_FLYING);
SetCollisionFlags(ECF_PROJECTILE_MAGIC);
SetFlags(GetFlags() | ENF_SEETHROUGH);
SetModel(MODEL_WOMAN_FIRE);
SetModelMainTexture(TEXTURE_WOMAN_FIRE);
// start moving
LaunchAsPropelledProjectile(FLOAT3D(0.0f, 0.0f, -30.0f), (CMovableEntity*)(CEntity*)m_penLauncher);
SetDesiredRotation(ANGLE3D(0, 0, 0));
m_fFlyTime = 5.0f;
m_fDamageAmount = 8.0f;
m_fSoundRange = 0.0f;
m_bExplode = FALSE;
m_bLightSource = TRUE;
m_bCanHitHimself = FALSE;
m_bCanBeDestroyed = FALSE;
m_fWaitAfterDeath = 0.0f;
m_pmtMove = PMT_FLYING;
};
/************************************************************
* DRAGONMAN PROJECTILE *
************************************************************/
void DragonmanProjectile(INDEX iType) {
// set appearance
InitAsModel();
SetPhysicsFlags(EPF_ONBLOCK_SLIDE|EPF_PUSHABLE|EPF_MOVABLE);
SetCollisionFlags(ECF_PROJECTILE_MAGIC);
SetFlags(GetFlags() | ENF_SEETHROUGH);
SetModel(MODEL_DRAGONMAN_FIRE);
if (iType==DRAGONMAN_STRONG) {
SetModelMainTexture(TEXTURE_DRAGONMAN_FIRE2);
} else {
SetModelMainTexture(TEXTURE_DRAGONMAN_FIRE1);
}
// start moving
if (iType==DRAGONMAN_STRONG) {
LaunchAsPropelledProjectile(FLOAT3D(0.0f, 0.0f, -40.0f), (CMovableEntity*)(CEntity*)m_penLauncher);
m_fDamageAmount = 14.0f;
} else {
LaunchAsPropelledProjectile(FLOAT3D(0.0f, 0.0f, -30.0f), (CMovableEntity*)(CEntity*)m_penLauncher);
m_fDamageAmount = 7.0f;
}
SetDesiredRotation(ANGLE3D(0, 0, 0));
m_fFlyTime = 5.0f;
m_fSoundRange = 0.0f;
m_bExplode = FALSE;
m_bLightSource = TRUE;
m_bCanHitHimself = FALSE;
m_bCanBeDestroyed = FALSE;
m_fWaitAfterDeath = 0.0f;
m_pmtMove = PMT_FLYING;
};
/************************************************************
* ELEMENTAL PROJECTILE *
************************************************************/
void ElementalRock(INDEX iSize, INDEX iType) {
// set appearance
InitAsModel();
SetPhysicsFlags(EPF_ONBLOCK_SLIDE|EPF_PUSHABLE|EPF_MOVABLE);
SetCollisionFlags(ECF_PROJECTILE_SOLID);
switch (iType) {
case ELEMENTAL_STONEMAN:
SetModel(MODEL_ELEM_STONE);
SetModelMainTexture(TEXTURE_ELEM_STONE);
break;
case ELEMENTAL_LAVAMAN:
SetModel(MODEL_ELEM_LAVA_STONE);
SetModelMainTexture(TEXTURE_ELEM_LAVA_STONE);
AddAttachmentToModel(this, *GetModelObject(), LAVASTONE_ATTACHMENT_FLARE,
MODEL_ELEM_LAVA_STONE_FLARE, TEXTURE_ELEM_LAVA_STONE_FLARE, 0, 0, 0);
break;
case ELEMENTAL_ICEMAN:
SetModel(MODEL_ELEM_ICE);
SetModelMainTexture(TEXTURE_ELEM_ICE);
//AddAttachmentToModel(this, *GetModelObject(), ICEPYRAMID_ATTACHMENT_FLARE,
// MODEL_ELEM_ICE_FLARE, TEXTURE_ELEM_ICE_FLARE, 0, 0, 0);
break;
}
if (iSize==ELEMENTAL_LARGE) {
GetModelObject()->StretchModel(FLOAT3D(2.25f, 2.25f, 2.25f));
} else if (iSize==ELEMENTAL_BIG) {
GetModelObject()->StretchModel(FLOAT3D(0.75f, 0.75f, 0.75f));
} else {
GetModelObject()->StretchModel(FLOAT3D(0.4f, 0.4f, 0.4f));
}
ModelChangeNotify();
// start moving
if (iSize==ELEMENTAL_LARGE) {
LaunchAsPropelledProjectile(FLOAT3D(0.0f, 0.0f, -80.0f), (CMovableEntity*)(CEntity*)m_penLauncher);
m_fDamageAmount = 20.0f;
SetHealth(40.0f);
} else if (iSize==ELEMENTAL_BIG) {
LaunchAsPropelledProjectile(FLOAT3D(0.0f, 0.0f, -50.0f), (CMovableEntity*)(CEntity*)m_penLauncher);
m_fDamageAmount = 12.5f;
SetHealth(20.0f);
} else {
LaunchAsPropelledProjectile(FLOAT3D(0.0f, 0.0f, -30.0f), (CMovableEntity*)(CEntity*)m_penLauncher);
m_fDamageAmount = 7.0f;
SetHealth(10.0f);
}
SetDesiredRotation(ANGLE3D(0, 0, FRnd()*1800.0f-900.0f));
en_fCollisionSpeedLimit = 1000.0f;
en_fCollisionDamageFactor = 0.0f;
m_fFlyTime = 5.0f;
m_fSoundRange = 0.0f;
m_bExplode = FALSE;
m_bLightSource = FALSE;
m_bCanHitHimself = FALSE;
m_bCanBeDestroyed = TRUE;
m_fWaitAfterDeath = 0.0f;
m_pmtMove = PMT_SLIDING;
};
void LavaManBomb(void)
{
// set appearance
InitAsModel();
SetPhysicsFlags(EPF_MODEL_BOUNCING);
SetCollisionFlags(ECF_PROJECTILE_SOLID);
SetModel(MODEL_ELEM_LAVA_BOMB);
SetModelMainTexture(TEXTURE_ELEM_LAVA_BOMB);
AddAttachmentToModel(this, *GetModelObject(), LAVABOMB_ATTACHMENT_FLARE,
MODEL_ELEM_LAVA_BOMB_FLARE, TEXTURE_ELEM_LAVA_BOMB_FLARE, 0, 0, 0);
if (m_prtType == PRT_LAVAMAN_BIG_BOMB)
{
GetModelObject()->StretchModel(FLOAT3D(6.0f, 6.0f, 6.0f));
m_fDamageAmount = 20.0f;
m_fRangeDamageAmount = 10.0f;
m_fDamageHotSpotRange = 7.5f;
m_fDamageFallOffRange = 15.0f;
SetHealth(30.0f);
}
else if (m_prtType == PRT_LAVAMAN_BOMB)
{
GetModelObject()->StretchModel(FLOAT3D(1.5f, 1.5f, 1.5f));
m_fDamageAmount = 10.0f;
m_fRangeDamageAmount = 5.0f;
m_fDamageHotSpotRange = 5.0f;
m_fDamageFallOffRange = 10.0f;
SetHealth(10.0f);
}
ModelChangeNotify();
// start moving
LaunchAsFreeProjectile(FLOAT3D(0.0f, 0.0f, -m_fSpeed), (CMovableEntity*)&*m_penLauncher);
SetDesiredRotation(ANGLE3D(0, FRnd()*360.0f-180.0f, 0.0f));
m_fFlyTime = 20.0f;
m_fSoundRange = 50.0f;
m_bExplode = TRUE;
m_bLightSource = FALSE;
m_bCanHitHimself = FALSE;
m_bCanBeDestroyed = TRUE;
m_pmtMove = PMT_FLYING;
m_fWaitAfterDeath = 4.0f;
if (m_prtType == PRT_LAVAMAN_BIG_BOMB)
{
// spawn particle debris
CPlacement3D plSpray = GetPlacement();
CEntityPointer penSpray = CreateEntity( plSpray, CLASS_BLOOD_SPRAY);
penSpray->SetParent( this);
ESpawnSpray eSpawnSpray;
eSpawnSpray.colBurnColor=C_WHITE|CT_OPAQUE;
eSpawnSpray.fDamagePower = 4.0f;
eSpawnSpray.fSizeMultiplier = 0.5f;
eSpawnSpray.sptType = SPT_LAVA_STONES;
eSpawnSpray.vDirection = FLOAT3D(0,-0.5f,0);
eSpawnSpray.penOwner = this;
penSpray->Initialize( eSpawnSpray);
}
}
void LavamanBombExplosion(void)
{
ESpawnEffect ese;
FLOAT3D vPoint;
FLOATplane3D vPlaneNormal;
FLOAT fDistanceToEdge;
if (GetNearestPolygon(vPoint, vPlaneNormal, fDistanceToEdge))
{
if ((vPoint-GetPlacement().pl_PositionVector).Length() < 3.5f)
{
// shock wave
ese.colMuliplier = C_WHITE|CT_OPAQUE;
ese.betType = BET_SHOCKWAVE;
ese.vNormal = FLOAT3D(vPlaneNormal);
SpawnEffect(CPlacement3D(vPoint, ANGLE3D(0, 0, 0)), ese);
}
}
// shock wave
ese.colMuliplier = C_WHITE|CT_OPAQUE;
ese.betType = BET_LIGHT_CANNON;
ese.vStretch = FLOAT3D(4,4,4);
SpawnEffect(GetPlacement(), ese);
// spawn particle debris
CPlacement3D plSpray = GetPlacement();
CEntityPointer penSpray = CreateEntity( plSpray, CLASS_BLOOD_SPRAY);
penSpray->SetParent( this);
ESpawnSpray eSpawnSpray;
eSpawnSpray.colBurnColor=C_WHITE|CT_OPAQUE;
eSpawnSpray.fDamagePower = 4.0f;
eSpawnSpray.fSizeMultiplier = 0.5f;
eSpawnSpray.sptType = SPT_LAVA_STONES;
eSpawnSpray.vDirection = en_vCurrentTranslationAbsolute/32.0f;
eSpawnSpray.penOwner = this;
penSpray->Initialize( eSpawnSpray);
// spawn smaller lava bombs
for( INDEX iDebris=0; iDebris<3+IRnd()%3; iDebris++)
{
FLOAT fHeading = (FRnd()-0.5f)*180.0f;
FLOAT fPitch = 10.0f+FRnd()*40.0f;
FLOAT fSpeed = 10.0+FRnd()*50.0f;
// launch
CPlacement3D pl = GetPlacement();
pl.pl_PositionVector(2) += 2.0f;
pl.pl_OrientationAngle = m_penLauncher->GetPlacement().pl_OrientationAngle;
pl.pl_OrientationAngle(1) += AngleDeg(fHeading);
pl.pl_OrientationAngle(2) = AngleDeg(fPitch);
CEntityPointer penProjectile = CreateEntity(pl, CLASS_PROJECTILE);
ELaunchProjectile eLaunch;
eLaunch.penLauncher = this;
eLaunch.prtType = PRT_LAVAMAN_BOMB;
eLaunch.fSpeed = fSpeed;
penProjectile->Initialize(eLaunch);
// spawn particle debris
CPlacement3D plSpray = pl;
CEntityPointer penSpray = CreateEntity( plSpray, CLASS_BLOOD_SPRAY);
penSpray->SetParent( penProjectile);
ESpawnSpray eSpawnSpray;
eSpawnSpray.colBurnColor=C_WHITE|CT_OPAQUE;
eSpawnSpray.fDamagePower = 1.0f;
eSpawnSpray.fSizeMultiplier = 0.5f;
eSpawnSpray.sptType = SPT_LAVA_STONES;
eSpawnSpray.vDirection = FLOAT3D(0,-0.5f,0);
eSpawnSpray.penOwner = penProjectile;
penSpray->Initialize( eSpawnSpray);
}
};
void LavamanBombDebrisExplosion(void)
{
ESpawnEffect ese;
FLOAT3D vPoint;
FLOATplane3D vPlaneNormal;
FLOAT fDistanceToEdge;
// spawn shock wave
if (GetNearestPolygon(vPoint, vPlaneNormal, fDistanceToEdge))
{
if ((vPoint-GetPlacement().pl_PositionVector).Length() < 3.5f)
{
ese.colMuliplier = C_WHITE|CT_OPAQUE;
ese.betType = BET_SHOCKWAVE;
ese.vNormal = FLOAT3D(vPlaneNormal);
SpawnEffect(CPlacement3D(vPoint, ANGLE3D(0, 0, 0)), ese);
}
}
// spawn explosion
ese.colMuliplier = C_WHITE|CT_OPAQUE;
ese.betType = BET_LIGHT_CANNON;
ese.vStretch = FLOAT3D(2,2,2);
SpawnEffect(GetPlacement(), ese);
// spawn particle debris
CPlacement3D plSpray = GetPlacement();
CEntityPointer penSpray = CreateEntity( plSpray, CLASS_BLOOD_SPRAY);
penSpray->SetParent( this);
ESpawnSpray eSpawnSpray;
eSpawnSpray.colBurnColor=C_WHITE|CT_OPAQUE;
eSpawnSpray.fSizeMultiplier = 4.0f;
eSpawnSpray.fDamagePower = 2.0f;
eSpawnSpray.sptType = SPT_LAVA_STONES;
eSpawnSpray.vDirection = en_vCurrentTranslationAbsolute/16.0f;
eSpawnSpray.penOwner = this;
penSpray->Initialize( eSpawnSpray);
}
/************************************************************
* HUANMAN PROJECTILE *
************************************************************/
void HuanmanProjectile(void) {
// set appearance
InitAsModel();
SetPhysicsFlags(EPF_PROJECTILE_FLYING);
SetCollisionFlags(ECF_PROJECTILE_MAGIC);
SetFlags(GetFlags() | ENF_SEETHROUGH);
SetComponents(this, *GetModelObject(), MODEL_HUANMAN_FIRE, TEXTURE_HUANMAN_FIRE,
TEX_REFL_LIGHTMETAL01, TEX_SPEC_STRONG, 0);
AddAttachmentToModel(this, *GetModelObject(), PROJECTILE_ATTACHMENT_FLARE,
MODEL_HUANMAN_FLARE, TEXTURE_HUANMAN_FLARE, 0, 0, 0);
GetModelObject()->StretchModel(FLOAT3D(0.5f, 0.5f, 0.5f));
ModelChangeNotify();
// start moving
LaunchAsPropelledProjectile(FLOAT3D(0.0f, 0.0f, -30.0f), (CMovableEntity*)(CEntity*)m_penLauncher);
SetDesiredRotation(ANGLE3D(0, 0, 0));
m_fFlyTime = 5.0f;
m_fDamageAmount = 10.0f;
m_fSoundRange = 0.0f;
m_bExplode = FALSE;
m_bLightSource = TRUE;
m_bCanHitHimself = FALSE;
m_bCanBeDestroyed = FALSE;
m_fWaitAfterDeath = 0.0f;
m_pmtMove = PMT_FLYING;
};
/************************************************************
* BEAST PROJECTILE *
************************************************************/
void BeastProjectile(void) {
// we need target for guied misile
if (IsDerivedFromClass(m_penLauncher, "Enemy Base")) {
m_penTarget = ((CEnemyBase *) &*m_penLauncher)->m_penEnemy;
}
// set appearance
InitAsModel();
SetPhysicsFlags(EPF_MODEL_FREE_FLYING);
SetCollisionFlags(ECF_PROJECTILE_SOLID);
SetModel(MODEL_BEAST_FIRE);
SetModelMainTexture(TEXTURE_BEAST_FIRE);
GetModelObject()->StretchModel(FLOAT3D(1.5f, 1.5f, 1.5f));
ModelChangeNotify();
// play the flying sound
m_soEffect.Set3DParameters(20.0f, 2.0f, 1.0f, 1.0f);
PlaySound(m_soEffect, SOUND_BEAST_FLYING, SOF_3D|SOF_LOOP);
// start moving
LaunchAsPropelledProjectile(FLOAT3D(0.0f, 0.0f, -60.0f), (CMovableEntity*)(CEntity*)m_penLauncher);
SetDesiredRotation(ANGLE3D(0, 0, 0));
m_fFlyTime = 10.0f;
m_fDamageAmount = 10.0f;
m_fSoundRange = 0.0f;
m_bExplode = FALSE;
m_bLightSource = FALSE;
m_bCanHitHimself = FALSE;
m_bCanBeDestroyed = TRUE;
m_fWaitAfterDeath = 0.0f;
m_pmtMove = PMT_GUIDED;
m_fGuidedMaxSpeedFactor = 30.0f;
m_aRotateSpeed = 175.0f;
SetHealth(10.0f);
};
void BeastBigProjectile(void) {
// we need target for guided misile
if (IsDerivedFromClass(m_penLauncher, "Enemy Base")) {
m_penTarget = ((CEnemyBase *) &*m_penLauncher)->m_penEnemy;
}
// set appearance
InitAsModel();
SetPhysicsFlags(EPF_MODEL_FREE_FLYING);
SetCollisionFlags(ECF_PROJECTILE_SOLID);
SetModel(MODEL_BEAST_FIRE);
SetModelMainTexture(TEXTURE_BEAST_BIG_FIRE);
GetModelObject()->StretchModel(FLOAT3D(2.5f, 2.5f, 2.5f));
ModelChangeNotify();
// play the flying sound
m_soEffect.Set3DParameters(50.0f, 2.0f, 1.0f, 0.75f);
PlaySound(m_soEffect, SOUND_BEAST_FLYING, SOF_3D|SOF_LOOP);
// start moving
LaunchAsPropelledProjectile(FLOAT3D(0.0f, 0.0f, -60.0f), (CMovableEntity*)(CEntity*)m_penLauncher);
SetDesiredRotation(ANGLE3D(0, 0, 0));
m_fFlyTime = 10.0f;
m_fDamageAmount = 20.0f;
m_fSoundRange = 0.0f;
m_bExplode = FALSE;
m_bLightSource = FALSE;
m_bCanHitHimself = FALSE;
m_bCanBeDestroyed = FALSE;
m_fWaitAfterDeath = 0.0f;
m_pmtMove = PMT_GUIDED_FAST;
m_fGuidedMaxSpeedFactor = 90.0f;
SetHealth(10000.0f);
m_aRotateSpeed = 100.0f;
};
void BeastDebris(void)
{
// set appearance
InitAsModel();
SetPhysicsFlags(EPF_MODEL_BOUNCING);
SetCollisionFlags(ECF_PROJECTILE_SOLID);
SetModel(MODEL_BEAST_FIRE);
GetModelObject()->StretchModel(FLOAT3D(0.75f, 0.75f, 0.75f));
SetModelMainTexture(TEXTURE_BEAST_FIRE);
GetModelObject()->StartAnim(1+(ULONG)FRnd()*5.0f);
ModelChangeNotify();
// start moving
LaunchAsFreeProjectile(FLOAT3D(0.0f, 0.0f, -20.0f), (CMovableEntity*)&*m_penLauncher);
SetDesiredRotation(ANGLE3D(0, 0, 0));
m_fFlyTime = 10.0f;
m_fDamageAmount = 0.0f;
m_fSoundRange = 0.0f;
m_bExplode = FALSE;
m_bLightSource = FALSE;
m_bCanHitHimself = FALSE;
m_bCanBeDestroyed = TRUE;
m_fWaitAfterDeath = 0.0f;
m_pmtMove = PMT_FLYING;
SetHealth(1.0f);
m_aRotateSpeed = 100.0f;
};
void BeastBigDebris(void)
{
// set appearance
InitAsModel();
SetPhysicsFlags(EPF_MODEL_BOUNCING);
SetCollisionFlags(ECF_PROJECTILE_SOLID);
SetModel(MODEL_BEAST_FIRE);
SetModelMainTexture(TEXTURE_BEAST_BIG_FIRE);
GetModelObject()->StretchModel(FLOAT3D(1.0f, 1.0f, 1.0f));
GetModelObject()->StartAnim(1+(ULONG)FRnd()*5.0f);
ModelChangeNotify();
// start moving
LaunchAsFreeProjectile(FLOAT3D(0.0f, 0.0f, -20.0f), (CMovableEntity*)&*m_penLauncher);
SetDesiredRotation(ANGLE3D(0, 0, 0));
m_fFlyTime = 10.0f;
m_fDamageAmount = 0.0f;
m_fSoundRange = 0.0f;
m_bExplode = FALSE;
m_bLightSource = FALSE;
m_bCanHitHimself = FALSE;
m_bCanBeDestroyed = TRUE;
m_fWaitAfterDeath = 0.0f;
m_pmtMove = PMT_FLYING;
SetHealth(1.0f);
m_aRotateSpeed = 100.0f;
};
void BeastDebrisExplosion(void)
{
// explosion
ESpawnEffect ese;
ese.colMuliplier = C_GREEN|CT_OPAQUE;
ese.betType = BET_LIGHT_CANNON;
ese.vStretch = FLOAT3D(0.75,0.75,0.75);
SpawnEffect(GetPlacement(), ese);
// spawn particles
CPlacement3D plSpray = GetPlacement();
CEntityPointer penSpray = CreateEntity( plSpray, CLASS_BLOOD_SPRAY);
penSpray->SetParent( this);
ESpawnSpray eSpawnSpray;
eSpawnSpray.colBurnColor=C_WHITE|CT_OPAQUE;
eSpawnSpray.fDamagePower = 2.0f;
eSpawnSpray.fSizeMultiplier = 0.75f;
eSpawnSpray.sptType = SPT_BEAST_PROJECTILE_SPRAY;
eSpawnSpray.vDirection = en_vCurrentTranslationAbsolute/64.0f;
eSpawnSpray.penOwner = this;
penSpray->Initialize( eSpawnSpray);
}
void BeastBigDebrisExplosion(void)
{
// explosion
ESpawnEffect ese;
ese.colMuliplier = C_WHITE|CT_OPAQUE;
ese.betType = BET_LIGHT_CANNON;
ese.vStretch = FLOAT3D(1,1,1);
SpawnEffect(GetPlacement(), ese);
// spawn particles
CPlacement3D plSpray = GetPlacement();
CEntityPointer penSpray = CreateEntity( plSpray, CLASS_BLOOD_SPRAY);
penSpray->SetParent( this);
ESpawnSpray eSpawnSpray;
eSpawnSpray.colBurnColor=C_WHITE|CT_OPAQUE;
eSpawnSpray.fDamagePower = 2.0f;
eSpawnSpray.fSizeMultiplier = 1.0f;
eSpawnSpray.sptType = SPT_LAVA_STONES;
eSpawnSpray.vDirection = en_vCurrentTranslationAbsolute/64.0f;
eSpawnSpray.penOwner = this;
penSpray->Initialize( eSpawnSpray);
}
void BeastProjectileExplosion(void)
{
// explosion
ESpawnEffect ese;
ese.colMuliplier = C_GREEN|CT_OPAQUE;
ese.betType = BET_LIGHT_CANNON;
ese.vStretch = FLOAT3D(1.25,1.25,1.25);
SpawnEffect(GetPlacement(), ese);
// particles
CPlacement3D plSpray = GetPlacement();
CEntityPointer penSpray = CreateEntity( plSpray, CLASS_BLOOD_SPRAY);
penSpray->SetParent( this);
ESpawnSpray eSpawnSpray;
eSpawnSpray.colBurnColor=C_WHITE|CT_OPAQUE;
eSpawnSpray.fDamagePower = 2.0f;
eSpawnSpray.fSizeMultiplier = 1.0f;
eSpawnSpray.sptType = SPT_BEAST_PROJECTILE_SPRAY;
eSpawnSpray.vDirection = en_vCurrentTranslationAbsolute/64.0f;
eSpawnSpray.penOwner = this;
penSpray->Initialize( eSpawnSpray);
FLOAT fHeading = 20.0f+(FRnd()-0.5f)*60.0f;
// debris
for( INDEX iDebris=0; iDebris<2; iDebris++)
{
FLOAT fPitch = 10.0f+FRnd()*10.0f;
FLOAT fSpeed = 5.0+FRnd()*20.0f;
// launch
CPlacement3D pl = GetPlacement();
pl.pl_OrientationAngle(1) += AngleDeg(fHeading);
// turn to other way
fHeading = -fHeading;
pl.pl_OrientationAngle(2) = AngleDeg(fPitch);
CEntityPointer penProjectile = CreateEntity(pl, CLASS_PROJECTILE);
ELaunchProjectile eLaunch;
eLaunch.penLauncher = this;
eLaunch.prtType = PRT_BEAST_DEBRIS;
eLaunch.fSpeed = fSpeed;
penProjectile->Initialize(eLaunch);
// spawn particle debris
CPlacement3D plSpray = pl;
CEntityPointer penSpray = CreateEntity( plSpray, CLASS_BLOOD_SPRAY);
penSpray->SetParent( penProjectile);
ESpawnSpray eSpawnSpray;
eSpawnSpray.colBurnColor=C_WHITE|CT_OPAQUE;
eSpawnSpray.fDamagePower = 0.5f;
eSpawnSpray.fSizeMultiplier = 0.25f;
eSpawnSpray.sptType = SPT_BEAST_PROJECTILE_SPRAY;
eSpawnSpray.vDirection = FLOAT3D(0,-0.5f,0);
eSpawnSpray.penOwner = penProjectile;
penSpray->Initialize( eSpawnSpray);
}
}
void BeastBigProjectileExplosion(void)
{
// explosion
ESpawnEffect ese;
ese.colMuliplier = C_WHITE|CT_OPAQUE;
ese.betType = BET_LIGHT_CANNON;
ese.vStretch = FLOAT3D(2,2,2);
SpawnEffect(GetPlacement(), ese);
// particles
CPlacement3D plSpray = GetPlacement();
CEntityPointer penSpray = CreateEntity( plSpray, CLASS_BLOOD_SPRAY);
penSpray->SetParent( this);
ESpawnSpray eSpawnSpray;
eSpawnSpray.colBurnColor=C_WHITE|CT_OPAQUE;
eSpawnSpray.fDamagePower = 4.0f;
eSpawnSpray.fSizeMultiplier = 0.5f;
eSpawnSpray.sptType = SPT_LAVA_STONES;
eSpawnSpray.vDirection = en_vCurrentTranslationAbsolute/32.0f;
eSpawnSpray.penOwner = this;
penSpray->Initialize( eSpawnSpray);
// debris
for( INDEX iDebris=0; iDebris<3+IRnd()%2; iDebris++)
{
FLOAT fHeading = (FRnd()-0.5f)*180.0f;
FLOAT fPitch = 10.0f+FRnd()*40.0f;
FLOAT fSpeed = 10.0+FRnd()*50.0f;
// launch
CPlacement3D pl = GetPlacement();
pl.pl_OrientationAngle(1) += AngleDeg(fHeading);
pl.pl_OrientationAngle(2) += AngleDeg(fPitch);
CEntityPointer penProjectile = CreateEntity(pl, CLASS_PROJECTILE);
ELaunchProjectile eLaunch;
eLaunch.penLauncher = this;
eLaunch.prtType = PRT_BEAST_BIG_DEBRIS;
eLaunch.fSpeed = fSpeed;
penProjectile->Initialize(eLaunch);
// spawn particle debris
CPlacement3D plSpray = pl;
CEntityPointer penSpray = CreateEntity( plSpray, CLASS_BLOOD_SPRAY);
penSpray->SetParent( penProjectile);
ESpawnSpray eSpawnSpray;
eSpawnSpray.colBurnColor=C_WHITE|CT_OPAQUE;
eSpawnSpray.fDamagePower = 1.0f;
eSpawnSpray.fSizeMultiplier = 0.5f;
eSpawnSpray.sptType = SPT_LAVA_STONES;
eSpawnSpray.vDirection = FLOAT3D(0,-0.5f,0);
eSpawnSpray.penOwner = penProjectile;
penSpray->Initialize( eSpawnSpray);
}
}
/************************************************************
* FISHMAN PROJECTILE *
************************************************************/
void FishmanProjectile(void) {
// set appearance
InitAsModel();
SetPhysicsFlags(EPF_PROJECTILE_FLYING);
SetCollisionFlags(ECF_PROJECTILE_MAGIC);
SetFlags(GetFlags() | ENF_SEETHROUGH);
SetComponents(this, *GetModelObject(), MODEL_FISHMAN_FIRE, TEXTURE_FISHMAN_FIRE, 0, 0, 0);
ModelChangeNotify();
// start moving
LaunchAsPropelledProjectile(FLOAT3D(0.0f, 0.0f, -30.0f), (CMovableEntity*)(CEntity*)m_penLauncher);
SetDesiredRotation(ANGLE3D(0, 0, 0));
m_fFlyTime = 5.0f;
m_fDamageAmount = 5.0f;
m_fSoundRange = 0.0f;
m_bExplode = FALSE;
m_bLightSource = TRUE;
m_bCanHitHimself = FALSE;
m_bCanBeDestroyed = FALSE;
m_fWaitAfterDeath = 0.0f;
m_pmtMove = PMT_FLYING;
};
/************************************************************
* MANTAMAN PROJECTILE *
************************************************************/
void MantamanProjectile(void) {
// set appearance
InitAsModel();
SetPhysicsFlags(EPF_PROJECTILE_FLYING);
SetCollisionFlags(ECF_PROJECTILE_MAGIC);
SetFlags(GetFlags() | ENF_SEETHROUGH);
SetComponents(this, *GetModelObject(), MODEL_MANTAMAN_FIRE, TEXTURE_MANTAMAN_FIRE, 0, 0, 0);
ModelChangeNotify();
// start moving
LaunchAsPropelledProjectile(FLOAT3D(0.0f, 0.0f, -35.0f), (CMovableEntity*)(CEntity*)m_penLauncher);
SetDesiredRotation(ANGLE3D(0, 0, 0));
m_fFlyTime = 5.0f;
m_fDamageAmount = 7.0f;
m_fSoundRange = 0.0f;
m_bExplode = FALSE;
m_bLightSource = TRUE;
m_bCanHitHimself = FALSE;
m_bCanBeDestroyed = FALSE;
m_fWaitAfterDeath = 0.0f;
m_pmtMove = PMT_FLYING;
};
/************************************************************
* DEVIL PROJECTILES *
************************************************************/
void DevilLaser(void) {
// set appearance
InitAsModel();
SetPhysicsFlags(EPF_PROJECTILE_FLYING);
SetCollisionFlags(ECF_PROJECTILE_MAGIC);
SetFlags(GetFlags() | ENF_SEETHROUGH);
SetComponents(this, *GetModelObject(), MODEL_CYBORG_LASER, TEXTURE_CYBORG_LASER, 0, 0, 0);
GetModelObject()->StretchModel(FLOAT3D(4.0f, 4.0f, 2.0f));
ModelChangeNotify();
// start moving
LaunchAsPropelledProjectile(FLOAT3D(0.0f, 0.0f, -DEVIL_LASER_SPEED), (CMovableEntity*)(CEntity*)m_penLauncher);
SetDesiredRotation(ANGLE3D(0, 0, 0));
m_fFlyTime = 5.0f;
m_fDamageAmount = 10.0f;
m_fSoundRange = 0.0f;
m_bExplode = FALSE;
m_bLightSource = TRUE;
m_bCanHitHimself = FALSE;
m_bCanBeDestroyed = FALSE;
m_fWaitAfterDeath = 0.0f;
m_pmtMove = PMT_FLYING;
};
void DevilRocket(void) {
// set appearance
InitAsModel();
SetPhysicsFlags(EPF_PROJECTILE_FLYING);
SetCollisionFlags(ECF_PROJECTILE_SOLID);
SetModel(MODEL_ROCKET);
SetModelMainTexture(TEXTURE_ROCKET);
GetModelObject()->StretchModel(FLOAT3D(12.0f, 12.0f, 8.0f));
ModelChangeNotify();
// start moving
LaunchAsPropelledProjectile(FLOAT3D(0.0f, 0.0f, -DEVIL_ROCKET_SPEED), (CMovableEntity*)(CEntity*)m_penLauncher);
SetDesiredRotation(ANGLE3D(0, 0, 0));
// play the flying sound
m_soEffect.Set3DParameters(100.0f, 2.0f, 1.0f, 1.0f);
PlaySound(m_soEffect, SOUND_FLYING, SOF_3D|SOF_LOOP);
m_fFlyTime = 50.0f;
m_fDamageAmount = 50.0f;
m_fRangeDamageAmount = 50.0f;
m_fDamageHotSpotRange = 2.0f;
m_fDamageFallOffRange = 10.0f;
m_fSoundRange = 100.0f;
m_bExplode = TRUE;
m_bLightSource = TRUE;
m_bCanHitHimself = TRUE;
m_bCanBeDestroyed = TRUE;
m_fWaitAfterDeath = 1.125f;
m_tmExpandBox = 10000.0f;
m_tmInvisibility = 0.05f;
SetHealth(25.0f);
m_pmtMove = PMT_FLYING;
};
void DevilRocketExplosion(void) {
ESpawnEffect ese;
FLOAT3D vPoint;
FLOATplane3D vPlaneNormal;
FLOAT fDistanceToEdge;
// explosion
ese.colMuliplier = C_WHITE|CT_OPAQUE;
ese.betType = BET_GRENADE;
ese.vStretch = FLOAT3D(2,2,2);
SpawnEffect(GetPlacement(), ese);
// spawn sound event in range
if( IsDerivedFromClass( m_penLauncher, "Player")) {
SpawnRangeSound( m_penLauncher, this, SNDT_PLAYER, m_fSoundRange);
}
// on plane
if (GetNearestPolygon(vPoint, vPlaneNormal, fDistanceToEdge)) {
if ((vPoint-GetPlacement().pl_PositionVector).Length() < 3.5f) {
// stain
ese.betType = BET_EXPLOSIONSTAIN;
ese.vNormal = FLOAT3D(vPlaneNormal);
ese.vStretch = FLOAT3D(2,2,2);
SpawnEffect(CPlacement3D(vPoint, ANGLE3D(0, 0, 0)), ese);
// shock wave
ese.betType = BET_SHOCKWAVE;
ese.vNormal = FLOAT3D(vPlaneNormal);
ese.vStretch = FLOAT3D(2,2,2);
SpawnEffect(CPlacement3D(vPoint, ANGLE3D(0, 0, 0)), ese);
// second explosion on plane
ese.betType = BET_GRENADE_PLANE;
ese.vNormal = FLOAT3D(vPlaneNormal);
ese.vStretch = FLOAT3D(2,2,2);
SpawnEffect(CPlacement3D(vPoint+ese.vNormal/50.0f, ANGLE3D(0, 0, 0)), ese);
}
}
};
void DevilGuidedProjectile(void) {
// we need target for guied misile
if (IsDerivedFromClass(m_penLauncher, "Enemy Base")) {
m_penTarget = ((CEnemyBase *) &*m_penLauncher)->m_penEnemy;
}
// set appearance
InitAsModel();
SetPhysicsFlags(EPF_MODEL_FREE_FLYING);
SetCollisionFlags(ECF_PROJECTILE_SOLID);
SetModel(MODEL_BEAST_FIRE);
SetModelMainTexture(TEXTURE_BEAST_BIG_FIRE);
GetModelObject()->StretchModel(FLOAT3D(2.5f, 2.5f, 2.5f));
ModelChangeNotify();
// play the flying sound
m_soEffect.Set3DParameters(250.0f, 2.0f, 1.0f, 0.75f);
PlaySound(m_soEffect, SOUND_FLYING, SOF_3D|SOF_LOOP);
// start moving
LaunchAsPropelledProjectile(FLOAT3D(0.0f, 0.0f, -80.0f), (CMovableEntity*)(CEntity*)m_penLauncher);
SetDesiredRotation(ANGLE3D(0, 0, 0));
m_fFlyTime = 20.0f;
m_fDamageAmount = 20.0f;
m_fSoundRange = 0.0f;
m_bExplode = FALSE;
m_bLightSource = FALSE;
m_bCanHitHimself = FALSE;
m_bCanBeDestroyed = TRUE;
m_fWaitAfterDeath = 0.0f;
m_pmtMove = PMT_GUIDED;
m_fGuidedMaxSpeedFactor = 30.0f;
SetHealth(30.0f);
m_aRotateSpeed = 100.0f;
};
void DevilGuidedProjectileExplosion(void)
{
// explosion
ESpawnEffect ese;
ese.colMuliplier = C_WHITE|CT_OPAQUE;
ese.betType = BET_LIGHT_CANNON;
ese.vStretch = FLOAT3D(4,4,4);
SpawnEffect(GetPlacement(), ese);
// particles
CPlacement3D plSpray = GetPlacement();
CEntityPointer penSpray = CreateEntity( plSpray, CLASS_BLOOD_SPRAY);
penSpray->SetParent( this);
ESpawnSpray eSpawnSpray;
eSpawnSpray.colBurnColor=C_WHITE|CT_OPAQUE;
eSpawnSpray.fDamagePower = 8.0f;
eSpawnSpray.fSizeMultiplier = 1.0f;
eSpawnSpray.sptType = SPT_LAVA_STONES;
eSpawnSpray.vDirection = en_vCurrentTranslationAbsolute/32.0f;
eSpawnSpray.penOwner = this;
penSpray->Initialize( eSpawnSpray);
// debris
for( INDEX iDebris=0; iDebris<3+IRnd()%2; iDebris++)
{
FLOAT fHeading = (FRnd()-0.5f)*180.0f;
FLOAT fPitch = 10.0f+FRnd()*40.0f;
FLOAT fSpeed = 10.0+FRnd()*50.0f;
// launch
CPlacement3D pl = GetPlacement();
pl.pl_OrientationAngle(1) += AngleDeg(fHeading);
pl.pl_OrientationAngle(2) += AngleDeg(fPitch);
CEntityPointer penProjectile = CreateEntity(pl, CLASS_PROJECTILE);
ELaunchProjectile eLaunch;
eLaunch.penLauncher = this;
eLaunch.prtType = PRT_BEAST_BIG_DEBRIS;
eLaunch.fSpeed = fSpeed;
penProjectile->Initialize(eLaunch);
// spawn particle debris
CPlacement3D plSpray = pl;
CEntityPointer penSpray = CreateEntity( plSpray, CLASS_BLOOD_SPRAY);
penSpray->SetParent( penProjectile);
ESpawnSpray eSpawnSpray;
eSpawnSpray.colBurnColor=C_WHITE|CT_OPAQUE;
eSpawnSpray.fDamagePower = 2.0f;
eSpawnSpray.fSizeMultiplier = 1.0f;
eSpawnSpray.sptType = SPT_LAVA_STONES;
eSpawnSpray.vDirection = FLOAT3D(0,-0.5f,0);
eSpawnSpray.penOwner = penProjectile;
penSpray->Initialize( eSpawnSpray);
}
}
/************************************************************
* CYBORG LASER / PROJECTILE *
************************************************************/
void CyborgLaser(void) {
// set appearance
InitAsModel();
SetPhysicsFlags(EPF_PROJECTILE_FLYING);
SetCollisionFlags(ECF_PROJECTILE_MAGIC);
SetFlags(GetFlags() | ENF_SEETHROUGH);
SetComponents(this, *GetModelObject(), MODEL_CYBORG_LASER, TEXTURE_CYBORG_LASER, 0, 0, 0);
ModelChangeNotify();
// start moving
LaunchAsPropelledProjectile(FLOAT3D(0.0f, 0.0f, -60.0f), (CMovableEntity*)(CEntity*)m_penLauncher);
SetDesiredRotation(ANGLE3D(0, 0, 0));
m_fFlyTime = 4.0f;
m_fDamageAmount = 5.0f;
m_fSoundRange = 0.0f;
m_bExplode = FALSE;
m_bLightSource = TRUE;
m_bCanHitHimself = FALSE;
m_bCanBeDestroyed = FALSE;
m_fWaitAfterDeath = 0.0f;
m_pmtMove = PMT_FLYING;
};
void CyborgBomb(void)
{
// set appearance
InitAsModel();
SetPhysicsFlags(EPF_MODEL_BOUNCING);
SetCollisionFlags(ECF_PROJECTILE_SOLID);
SetModel(MODEL_CYBORG_BOMB);
SetModelMainTexture(TEXTURE_CYBORG_BOMB);
ModelChangeNotify();
// just freefall
LaunchAsFreeProjectile(FLOAT3D(0.0f, 0.0f, -m_fSpeed), (CMovableEntity*)&*m_penLauncher);
SetDesiredRotation(ANGLE3D(0, 0, 0));
m_fFlyTime = 2.5f;
m_fDamageAmount = 10.0f;
m_fRangeDamageAmount = 15.0f;
m_fDamageHotSpotRange = 1.0f;
m_fDamageFallOffRange = 6.0f;
m_fSoundRange = 25.0f;
m_bExplode = TRUE;
m_bLightSource = FALSE;
m_bCanHitHimself = TRUE;
m_bCanBeDestroyed = TRUE;
m_fWaitAfterDeath = 0.0f;
SetHealth(5.0f);
m_pmtMove = PMT_FLYING;
};
/************************************************************
* LAVA BALL *
************************************************************/
void LavaBall(void) {
// set appearance
InitAsModel();
SetPhysicsFlags(EPF_MODEL_FALL);
SetCollisionFlags(ECF_PROJECTILE_MAGIC);
SetModel(MODEL_LAVA);
SetModelMainTexture(TEXTURE_LAVA);
AddAttachment(0, MODEL_LAVA_FLARE, TEXTURE_LAVA_FLARE);
// start moving
LaunchAsFreeProjectile(FLOAT3D(0.0f, 0.0f, -m_fSpeed), (CMovableEntity*)&*m_penLauncher);
SetDesiredRotation(ANGLE3D(0, FRnd()*360.0f-180.0f, FRnd()*360.0f-180.0f));
m_fFlyTime = 5.0f;
m_fDamageAmount = 5.0f;
m_fRangeDamageAmount = 5.0f;
m_fDamageHotSpotRange = 1.0f;
m_fDamageFallOffRange = 4.0f;
m_fSoundRange = 0.0f;
m_bExplode = TRUE;
m_bLightSource = FALSE;
m_bCanHitHimself = FALSE;
m_bCanBeDestroyed = FALSE;
m_fWaitAfterDeath = 0.0f;
m_pmtMove = PMT_FLYING;
};
void LavaBallExplosion(void) {
ESpawnEffect ese;
FLOAT3D vPoint;
FLOATplane3D vPlaneNormal;
FLOAT fDistanceToEdge;
if (GetNearestPolygon(vPoint, vPlaneNormal, fDistanceToEdge)) {
if ((vPoint-GetPlacement().pl_PositionVector).Length() < 3.5f) {
// shock wave
ese.colMuliplier = C_WHITE|CT_OPAQUE;
ese.betType = BET_SHOCKWAVE;
ese.vNormal = FLOAT3D(vPlaneNormal);
SpawnEffect(CPlacement3D(vPoint, ANGLE3D(0, 0, 0)), ese);
}
}
};
/************************************************************
* G R U N T L A S E R *
************************************************************/
void GruntSoldierLaser(void) {
// set appearance
InitAsModel();
SetPhysicsFlags(EPF_PROJECTILE_FLYING);
SetCollisionFlags(ECF_PROJECTILE_MAGIC);
SetFlags(GetFlags() | ENF_SEETHROUGH);
SetModel(MODEL_GRUNT_PROJECTILE);
CModelObject *pmo = GetModelObject();
if(pmo != NULL)
{
pmo->PlayAnim(GRUNTPROJECTILE_ANIM_DEFAULT, 0);
}
SetModelMainTexture(TEXTURE_GRUNT_PROJECTILE_01);
// start moving
LaunchAsPropelledProjectile(FLOAT3D(0.0f, 0.0f, -45.0f), (CMovableEntity*)(CEntity*)m_penLauncher);
SetDesiredRotation(ANGLE3D(0, 0, 0));
m_fFlyTime = 3.0f;
m_fDamageAmount = 10.0f;
m_fSoundRange = 0.0f;
m_bExplode = FALSE;
m_bLightSource = TRUE;
m_bCanHitHimself = FALSE;
m_bCanBeDestroyed = FALSE;
m_fWaitAfterDeath = 0.0f;
m_tmExpandBox = 0.1f;
// time when laser ray becomes visible
m_tmInvisibility = 0.025f;
m_pmtMove = PMT_FLYING;
};
void GruntCommanderLaser(void) {
// set appearance
InitAsModel();
SetPhysicsFlags(EPF_PROJECTILE_FLYING);
SetCollisionFlags(ECF_PROJECTILE_MAGIC);
SetFlags(GetFlags() | ENF_SEETHROUGH);
SetModel(MODEL_GRUNT_PROJECTILE);
CModelObject *pmo = GetModelObject();
if(pmo != NULL)
{
pmo->PlayAnim(GRUNTPROJECTILE_ANIM_DEFAULT, 0);
}
SetModelMainTexture(TEXTURE_GRUNT_PROJECTILE_02);
// start moving
LaunchAsPropelledProjectile(FLOAT3D(0.0f, 0.0f, -55.0f), (CMovableEntity*)(CEntity*)m_penLauncher);
SetDesiredRotation(ANGLE3D(0, 0, 0));
m_fFlyTime = 3.0f;
m_fDamageAmount = 10.0f;
m_fSoundRange = 0.0f;
m_bExplode = FALSE;
m_bLightSource = TRUE;
m_bCanHitHimself = FALSE;
m_bCanBeDestroyed = FALSE;
m_fWaitAfterDeath = 0.0f;
m_tmExpandBox = 0.1f;
// time when laser ray becomes visible
m_tmInvisibility = 0.025f;
m_pmtMove = PMT_FLYING;
};
/************************************************************
* G U F F Y R O C K E T *
************************************************************/
void GuffyProjectile(void) {
// set appearance
InitAsModel();
SetPhysicsFlags(EPF_PROJECTILE_FLYING);
SetCollisionFlags(ECF_PROJECTILE_MAGIC);
SetModel(MODEL_GUFFY_PROJECTILE);
SetModelMainTexture(TEXTURE_GUFFY_PROJECTILE);
GetModelObject()->StretchModel(FLOAT3D(1.0f, 1.0f, 1.0f));
CModelObject *pmo = GetModelObject();
if(pmo != NULL)
{
pmo->PlayAnim(GUFFYPROJECTILE_ANIM_ROTATE01, AOF_LOOPING);
}
// start moving
LaunchAsPropelledProjectile(FLOAT3D(0.0f, 0.0f, -50.0f), (CMovableEntity*)(CEntity*)m_penLauncher);
SetDesiredRotation(ANGLE3D(0, 0, 0));
// play the flying sound
m_soEffect.Set3DParameters(20.0f, 2.0f, 1.0f, 1.0f);
PlaySound(m_soEffect, SOUND_FLYING, SOF_3D|SOF_LOOP);
m_fFlyTime = 30.0f;
m_fDamageAmount = 10.0f;
m_fRangeDamageAmount = 10.0f;
m_fDamageHotSpotRange = 4.0f;
m_fDamageFallOffRange = 8.0f;
m_fSoundRange = 50.0f;
m_bExplode = TRUE;
m_bLightSource = TRUE;
m_bCanHitHimself = FALSE;
m_bCanBeDestroyed = FALSE;
m_fWaitAfterDeath = 1.125f;
m_tmExpandBox = 0.1f;
m_tmInvisibility = 0.05f;
SetHealth(10000.0f);
m_pmtMove = PMT_FLYING;
};
void GuffyProjectileExplosion(void) {
PlayerRocketExplosion();
}
/************************************************************
* D E M O N F I R E B A L L *
************************************************************/
void DemonFireball(void) {
// we need target for guided misile
if (IsDerivedFromClass(m_penLauncher, "Enemy Base")) {
m_penTarget = ((CEnemyBase *) &*m_penLauncher)->m_penEnemy;
}
// set appearance
InitAsModel();
SetPhysicsFlags(EPF_MODEL_FREE_FLYING);
SetCollisionFlags(ECF_PROJECTILE_SOLID);
SetModel(MODEL_DEMON_FIREBALL);
SetModelMainTexture(TEXTURE_DEMON_FIREBALL);
GetModelObject()->StretchModel(FLOAT3D(2.5f, 2.5f, 2.5f));
ModelChangeNotify();
// play the flying sound
m_soEffect.Set3DParameters(50.0f, 2.0f, 1.0f, 0.75f);
PlaySound(m_soEffect, SOUND_BEAST_FLYING, SOF_3D|SOF_LOOP);
// start moving
LaunchAsPropelledProjectile(FLOAT3D(0.0f, 0.0f, -100.0f), (CMovableEntity*)(CEntity*)m_penLauncher);
SetDesiredRotation(ANGLE3D(0, 0, 0));
m_fFlyTime = 12.0f;
m_fDamageAmount = 20.0f;
m_fSoundRange = 0.0f;
m_bExplode = FALSE;
m_bLightSource = FALSE;
m_bCanHitHimself = FALSE;
m_bCanBeDestroyed = TRUE;
m_fWaitAfterDeath = 0.0f;
m_pmtMove = PMT_GUIDED_FAST;
m_fGuidedMaxSpeedFactor = 90.0f;
SetHealth(10000.0f);
m_aRotateSpeed = 200.0f;
};
void DemonFireballExplosion(void)
{
// explosion
ESpawnEffect ese;
ese.colMuliplier = C_WHITE|CT_OPAQUE;
ese.betType = BET_LIGHT_CANNON;
ese.vStretch = FLOAT3D(2,2,2);
SpawnEffect(GetPlacement(), ese);
// particles
CPlacement3D plSpray = GetPlacement();
CEntityPointer penSpray = CreateEntity( plSpray, CLASS_BLOOD_SPRAY);
penSpray->SetParent( this);
ESpawnSpray eSpawnSpray;
eSpawnSpray.colBurnColor=C_WHITE|CT_OPAQUE;
eSpawnSpray.fDamagePower = 4.0f;
eSpawnSpray.fSizeMultiplier = 0.5f;
eSpawnSpray.sptType = SPT_LAVA_STONES;
eSpawnSpray.vDirection = en_vCurrentTranslationAbsolute/32.0f;
eSpawnSpray.penOwner = this;
penSpray->Initialize( eSpawnSpray);
}
/************************************************************
* L A R V A P R O J E C T I L E S *
************************************************************/
void LarvaPlasma(void) {
// set appearance
InitAsModel();
SetPhysicsFlags(EPF_PROJECTILE_FLYING);
SetCollisionFlags(ECF_PROJECTILE_MAGIC);
SetModel(MODEL_LARVA_PLASMA_BALL);
SetModelMainTexture(TEXTURE_LARVA_PLASMA_BALL);
AddAttachmentToModel(this, *GetModelObject(), PLASMAGUN_ATTACHMENT_PROJECTILE,
MODEL_LARVA_PLASMA, TEXTURE_LARVA_PLASMA, 0, 0, 0);
GetModelObject()->StretchModel(FLOAT3D(2.5f, 2.5f, 2.5f));
ModelChangeNotify();
// start moving
LaunchAsPropelledProjectile(FLOAT3D(0.0f, 0.0f, -60.0f), (CMovableEntity*)(CEntity*)m_penLauncher);
SetDesiredRotation(ANGLE3D(0, 0, 0));
// play the flying sound
m_soEffect.Set3DParameters(20.0f, 2.0f, 1.0f, 1.0f);
PlaySound(m_soEffect, SOUND_FLYING, SOF_3D|SOF_LOOP);
m_fFlyTime = 30.0f;
if( GetSP()->sp_bCooperative)
{
m_fDamageAmount = 30.0f;
m_fRangeDamageAmount = 30.0f;
}
else
{
m_fDamageAmount = 25.0f;
m_fRangeDamageAmount = 25.0f;
}
m_fDamageHotSpotRange = 4.0f;
m_fDamageFallOffRange = 8.0f;
m_fSoundRange = 50.0f;
m_bExplode = TRUE;
m_bLightSource = TRUE;
m_bCanHitHimself = FALSE;
m_bCanBeDestroyed = FALSE;
m_fWaitAfterDeath = 0.05f;
m_tmExpandBox = 0.1f;
m_tmInvisibility = 0.05f;
SetHealth(100.0f);
m_iRebounds = 4;
m_pmtMove = PMT_FLYING_REBOUNDING;
}
void LarvaPlasmaExplosion(void) {
// explosion
ESpawnEffect ese;
ese.colMuliplier = C_WHITE|CT_OPAQUE;
ese.betType = BET_LIGHT_CANNON;
ese.vStretch = FLOAT3D(2,2,2);
SpawnEffect(GetPlacement(), ese);
// particles
CPlacement3D plSpray = GetPlacement();
CEntityPointer penSpray = CreateEntity( plSpray, CLASS_BLOOD_SPRAY);
penSpray->SetParent( this);
ESpawnSpray eSpawnSpray;
eSpawnSpray.colBurnColor=C_WHITE|CT_OPAQUE;
eSpawnSpray.fDamagePower = 1.0f;
eSpawnSpray.fSizeMultiplier = 0.25f;
eSpawnSpray.sptType = SPT_PLASMA;
eSpawnSpray.vDirection = FLOAT3D(0.0f, 2.5f, 0.0f);
eSpawnSpray.penOwner = this;
penSpray->Initialize( eSpawnSpray);
}
void LarvaTail(void) {
// we need target for guied misile
if (IsDerivedFromClass(m_penLauncher, "Enemy Base")) {
m_penTarget = ((CEnemyBase *) &*m_penLauncher)->m_penEnemy;
}
// set appearance
InitAsModel();
SetPhysicsFlags(EPF_MODEL_SLIDING);
SetCollisionFlags(ECF_PROJECTILE_SOLID);
SetModel(MODEL_LARVA_TAIL);
SetModelMainTexture(TEXTURE_LARVA_TAIL);
GetModelObject()->StretchModel(FLOAT3D(4.0f, 4.0f, 4.0f));
ModelChangeNotify();
// play the flying sound
m_soEffect.Set3DParameters(50.0f, 10.0f, 1.0f, 1.0f);
PlaySound(m_soEffect, SOUND_LARVETTE, SOF_3D|SOF_LOOP);
// start moving
LaunchAsPropelledProjectile(FLOAT3D(0.0f, 0.0f, -30.0f), (CMovableEntity*)(CEntity*)m_penLauncher);
SetDesiredRotation(ANGLE3D(0, 0, 0));
m_fFlyTime = 12.0f;
m_fDamageAmount = 10.0f;
m_fSoundRange = 0.0f;
m_bExplode = FALSE;
m_bLightSource = FALSE;
m_bCanHitHimself = FALSE;
m_bCanBeDestroyed = TRUE;
m_fWaitAfterDeath = 0.0f;
m_pmtMove = PMT_GUIDED_SLIDING;
m_aRotateSpeed = 275.0f;
SetHealth(10.0f);
}
void LarvaTailExplosion(void) {
PlayerRocketExplosion();
}
/*****************************************************************
* A I R E L E M E N T A L P R O J E C T I L E S *
*****************************************************************/
void WindBlast(void) {
// set appearance
InitAsEditorModel();
SetPhysicsFlags(EPF_MODEL_SLIDING);
SetCollisionFlags(ECF_PROJECTILE_MAGIC);
SetFlags(GetFlags() | ENF_SEETHROUGH);
SetModel(MODEL_WINDBLAST);
SetModelMainTexture(TEXTURE_WINDBLAST);
GetModelObject()->StretchModel(FLOAT3D(3.0f, 3.0f, 3.0f));
ModelChangeNotify();
// start moving
LaunchAsPropelledProjectile(FLOAT3D(0.0f, 0.0f, -50.0f), (CMovableEntity*)(CEntity*)m_penLauncher);
SetDesiredRotation(ANGLE3D(0, 0, 0));
m_fFlyTime = 5.0f;
m_fDamageAmount = 20.0f;
m_fSoundRange = 0.0f;
m_bExplode = FALSE;
m_bLightSource = FALSE;
m_bCanHitHimself = FALSE;
m_bCanBeDestroyed = FALSE;
m_fWaitAfterDeath = 0.0f;
m_pmtMove = PMT_SLIDING;
}
/************************************************************
* M E T E O R *
************************************************************/
void Meteor() {
// set appearance
InitAsModel();
SetPhysicsFlags(EPF_PROJECTILE_FLYING);
SetCollisionFlags(ECF_PROJECTILE_SOLID);
SetModel(MODEL_ELEM_LAVA_BOMB);
SetModelMainTexture(TEXTURE_ELEM_LAVA_BOMB);
/*AddAttachmentToModel(this, *GetModelObject(), LAVABOMB_ATTACHMENT_FLARE,
MODEL_ELEM_LAVA_BOMB_FLARE, TEXTURE_ELEM_LAVA_BOMB_FLARE, 0, 0, 0);*/
GetModelObject()->StretchModel(FLOAT3D(m_fStretch, m_fStretch, m_fStretch));
ModelChangeNotify();
Particles_AfterBurner_Prepare(this);
// start moving
LaunchAsPropelledProjectile(FLOAT3D(0.0f, 0.0f, -m_fSpeed), (CMovableEntity*)(CEntity*)m_penLauncher);
SetDesiredRotation(ANGLE3D(0, 0, 0));
// play the flying sound
m_soEffect.Set3DParameters(250.0f, 10.0f, 2.0f, 1.0f);
PlaySound(m_soEffect, SOUND_FLYING, SOF_3D|SOF_LOOP);
m_fFlyTime = 30.0f;
m_fDamageAmount = 100.0f;
m_fRangeDamageAmount = 100.0f;
m_fDamageHotSpotRange = 15.0f;
m_fDamageFallOffRange = 30.0f;
m_fSoundRange = 100.0f;
m_bExplode = TRUE;
m_bLightSource = FALSE;
m_bCanHitHimself = TRUE;
m_bCanBeDestroyed = FALSE;
m_fWaitAfterDeath = GetSoundLength(SOUND_METEOR_BLAST)+0.25f;
m_tmExpandBox = 0.1f;
m_tmInvisibility = 0.05f;
SetHealth(100.0f);
m_pmtMove = PMT_FLYING;
}
void MeteorExplosion() {
//LavamanBombExplosion();
//PlayerRocketExplosion();
// spawn particle debris
CPlacement3D plSpray = GetPlacement();
CEntityPointer penSpray = CreateEntity( plSpray, CLASS_BLOOD_SPRAY);
penSpray->SetParent( this);
ESpawnSpray eSpawnSpray;
eSpawnSpray.colBurnColor=C_WHITE|CT_OPAQUE;
eSpawnSpray.fDamagePower = 4.0f;
eSpawnSpray.fSizeMultiplier = 0.5f;
eSpawnSpray.sptType = SPT_LAVA_STONES;
eSpawnSpray.vDirection = en_vCurrentTranslationAbsolute/32.0f;
eSpawnSpray.penOwner = this;
penSpray->Initialize( eSpawnSpray);
ESpawnEffect ese;
FLOAT3D vPoint;
FLOATplane3D vPlaneNormal;
FLOAT fDistanceToEdge;
// explosion
ese.colMuliplier = C_WHITE|CT_OPAQUE;
ese.betType = BET_CANNON;
ese.vStretch = FLOAT3D(5,5,5);
SpawnEffect(GetPlacement(), ese);
// spawn sound event in range
if( IsDerivedFromClass( m_penLauncher, "Player")) {
SpawnRangeSound( m_penLauncher, this, SNDT_PLAYER, m_fSoundRange);
}
// explosion debris
ese.betType = BET_EXPLOSION_DEBRIS;
SpawnEffect(GetPlacement(), ese);
// explosion smoke
ese.betType = BET_EXPLOSION_SMOKE;
SpawnEffect(GetPlacement(), ese);
// on plane
if (GetNearestPolygon(vPoint, vPlaneNormal, fDistanceToEdge)) {
if ((vPoint-GetPlacement().pl_PositionVector).Length() < 3.5f) {
// stain
ese.betType = BET_EXPLOSIONSTAIN;
ese.vNormal = FLOAT3D(vPlaneNormal);
SpawnEffect(CPlacement3D(vPoint, ANGLE3D(0, 0, 0)), ese);
// shock wave
ese.betType = BET_SHOCKWAVE;
ese.vNormal = FLOAT3D(vPlaneNormal);
SpawnEffect(CPlacement3D(vPoint, ANGLE3D(0, 0, 0)), ese);
// second explosion on plane
ese.betType = BET_ROCKET_PLANE;
ese.vNormal = FLOAT3D(vPlaneNormal);
SpawnEffect(CPlacement3D(vPoint+ese.vNormal/50.0f, ANGLE3D(0, 0, 0)), ese);
}
}
m_soExplosion.Set3DParameters(150.0f, 10.0f, 1.5f, 1.0f);
PlaySound(m_soExplosion, SOUND_METEOR_BLAST, SOF_3D);
}
/************************************************************
* S H O O T E R S *
************************************************************/
void ShooterWoodenDart(void) {
// set appearance
InitAsModel();
SetPhysicsFlags(EPF_PROJECTILE_FLYING);
SetCollisionFlags(ECF_PROJECTILE_SOLID);
SetModel(MODEL_SHTR_WOODEN_DART);
SetModelMainTexture(TEX_SHTR_WOODEN_DART);
// start moving
LaunchAsPropelledProjectile(FLOAT3D(0.0f, 0.0f, -30.0f), (CMovableEntity*)(CEntity*)m_penLauncher);
SetDesiredRotation(ANGLE3D(0, 0, 0));
/*// play the flying sound
m_soEffect.Set3DParameters(20.0f, 2.0f, 1.0f, 1.0f);
PlaySound(m_soEffect, SOUND_FLYING, SOF_3D|SOF_LOOP);*/
m_fFlyTime = 10.0f;
if (GetSP()->sp_gdGameDifficulty<=CSessionProperties::GD_EASY) {
m_fDamageAmount = 5.0f;
} else {
m_fDamageAmount = 10.0f;
}
m_bExplode = FALSE;
m_bLightSource = FALSE;
m_bCanHitHimself = FALSE;
m_bCanBeDestroyed = TRUE;
m_fWaitAfterDeath = 1.125f;
m_tmExpandBox = 0.1f;
m_tmInvisibility = 0.05f;
SetHealth(5.0f);
m_pmtMove = PMT_FLYING;
};
void ShooterWoodenDartExplosion() {
// particles
CPlacement3D plSpray = GetPlacement();
CEntityPointer penSpray = CreateEntity( plSpray, CLASS_BLOOD_SPRAY);
penSpray->SetParent( this);
ESpawnSpray eSpawnSpray;
eSpawnSpray.colBurnColor=C_WHITE|CT_OPAQUE;
eSpawnSpray.fDamagePower = 0.5f;
eSpawnSpray.fSizeMultiplier = 0.1f;
eSpawnSpray.sptType = SPT_WOOD;
eSpawnSpray.vDirection = -en_vCurrentTranslationAbsolute/32.0f;
eSpawnSpray.penOwner = this;
penSpray->Initialize( eSpawnSpray);
};
void ShooterFireball(void) {
// set appearance
InitAsModel();
SetPhysicsFlags(EPF_PROJECTILE_FLYING);
SetCollisionFlags(ECF_PROJECTILE_SOLID);
SetModel(MODEL_BEAST_FIRE);
SetModelMainTexture(TEXTURE_BEAST_BIG_FIRE);
GetModelObject()->StretchModel(FLOAT3D(0.25f, 0.25f, 0.25f));
ModelChangeNotify();
// start moving
LaunchAsPropelledProjectile(FLOAT3D(0.0f, 0.0f, -30.0f), (CMovableEntity*)(CEntity*)m_penLauncher);
SetDesiredRotation(ANGLE3D(0, 0, 0));
/*// play the flying sound
m_soEffect.Set3DParameters(20.0f, 2.0f, 1.0f, 1.0f);
PlaySound(m_soEffect, SOUND_FLYING, SOF_3D|SOF_LOOP);*/
m_fFlyTime = 10.0f;
if (GetSP()->sp_gdGameDifficulty<=CSessionProperties::GD_EASY) {
m_fDamageAmount = 7.5f;
} else {
m_fDamageAmount = 15.0f;
}
m_bExplode = FALSE;
m_bLightSource = TRUE;
m_bCanHitHimself = FALSE;
m_bCanBeDestroyed = TRUE;
m_fWaitAfterDeath = 0.125f;
m_tmExpandBox = 0.1f;
m_tmInvisibility = 0.05f;
SetHealth(5.0f);
m_pmtMove = PMT_FLYING;
};
void ShooterFireballExplosion() {
// particles
CPlacement3D plSpray = GetPlacement();
CEntityPointer penSpray = CreateEntity( plSpray, CLASS_BLOOD_SPRAY);
penSpray->SetParent( this);
ESpawnSpray eSpawnSpray;
eSpawnSpray.colBurnColor=C_WHITE|CT_OPAQUE;
eSpawnSpray.fDamagePower = 1.0f;
eSpawnSpray.fSizeMultiplier = 0.5f;
eSpawnSpray.sptType = SPT_LAVA_STONES;
eSpawnSpray.vDirection = -en_vCurrentTranslationAbsolute/32.0f;
eSpawnSpray.penOwner = this;
penSpray->Initialize( eSpawnSpray);
};
void ShooterFlame(void) {
// set appearance
InitAsModel();
SetPhysicsFlags(EPF_PROJECTILE_FLYING);
SetCollisionFlags(ECF_PROJECTILE_SOLID);
SetFlags(GetFlags() | ENF_SEETHROUGH);
SetModel(MODEL_FLAME);
// start moving
LaunchAsPropelledProjectile(FLOAT3D(0.0f, 0.0f, -10.0f), (CMovableEntity*)(CEntity*)m_penLauncher);
SetDesiredRotation(ANGLE3D(0, 0, 0));
m_fFlyTime = 1.0f;
m_fDamageAmount = 3.0f;
m_fSoundRange = 0.0f;
m_bExplode = FALSE;
m_bLightSource = TRUE;
m_bCanHitHimself = FALSE;
m_bCanBeDestroyed = FALSE;
m_fWaitAfterDeath = 0.3f;
m_pmtMove = PMT_FLYING;
};
void AfterburnerDebris(void)
{
Particles_AfterBurner_Prepare(this);
// set appearance
InitAsEditorModel();
SetPhysicsFlags(EPF_MODEL_FALL);
SetCollisionFlags(ECF_PROJECTILE_MAGIC);
SetModel(MODEL_MARKER);
SetModelMainTexture(TEXTURE_MARKER);
// start moving
LaunchAsFreeProjectile(FLOAT3D(0.0f, 0.0f, -m_fSpeed), (CMovableEntity*)&*m_penLauncher);
SetDesiredRotation(ANGLE3D(0, FRnd()*360.0f-180.0f, FRnd()*360.0f-180.0f));
m_fFlyTime = 10.0f;
m_fDamageAmount = 0.0f;
m_fRangeDamageAmount = 0.0f;
m_fDamageHotSpotRange = 0.0f;
m_fDamageFallOffRange = 0.0f;
m_fSoundRange = 0.0f;
m_bExplode = TRUE;
m_bLightSource = FALSE;
m_bCanHitHimself = FALSE;
m_bCanBeDestroyed = FALSE;
m_fWaitAfterDeath = 2.0f;
m_pmtMove = PMT_FLYING;
}
/************************************************************
* C O M M O N F U N C T I O N S *
************************************************************/
// projectile touch his valid target
void ProjectileTouch(CEntityPointer penHit)
{
// explode if needed
ProjectileHit();
// direct damage
FLOAT3D vDirection;
FLOAT fTransLen = en_vIntendedTranslation.Length();
if( fTransLen>0.5f)
{
vDirection = en_vIntendedTranslation/fTransLen;
}
else
{
vDirection = -en_vGravityDir;
}
// spawn flame
const FLOAT fDamageMul = GetSeriousDamageMultiplier(m_penLauncher);
if ((m_prtType==PRT_FLAME||m_prtType==PRT_SHOOTER_FLAME) && m_fWaitAfterDeath>0.0f) {
// don't burn the same entity twice while passing through it
if (m_penLastDamaged==penHit) {
return;
} else {
m_penLastDamaged=penHit;
}
// don't spawn flame on AirElemental
BOOL bSpawnFlame=TRUE;
BOOL bInflictDamage=TRUE;
if (IsOfClass(penHit, "AirElemental"))
{
bSpawnFlame=FALSE;
}
EntityInfo *pei=(EntityInfo *)penHit->GetEntityInfo();
if(pei!=NULL && pei->Eeibt==EIBT_ICE)
{
bSpawnFlame=FALSE;
bInflictDamage=FALSE;
}
if( bSpawnFlame)
{
SpawnFlame(m_penLauncher, penHit, GetPlacement().pl_PositionVector);
}
if(bInflictDamage)
{
InflictDirectDamage(penHit, m_penLauncher, DMT_BURNING, m_fDamageAmount*fDamageMul,
GetPlacement().pl_PositionVector, vDirection);
}
// don't damage the same entity twice (wind blast)
} else if (m_prtType==PRT_AIRELEMENTAL_WIND) {
if (penHit==m_penLastDamaged) {
return;
} else {
m_penLastDamaged=penHit;
}
InflictDirectDamage(penHit, m_penLauncher, DMT_PROJECTILE, m_fDamageAmount*fDamageMul,
GetPlacement().pl_PositionVector, vDirection);
// other projectiles
} else {
InflictDirectDamage(penHit, m_penLauncher, DMT_PROJECTILE, m_fDamageAmount*fDamageMul,
GetPlacement().pl_PositionVector, vDirection);
}
};
// projectile hit (or time expired or can't move any more)
void ProjectileHit(void)
{
// explode ...
if (m_bExplode) {
const FLOAT fDamageMul = GetSeriousDamageMultiplier(m_penLauncher);
InflictRangeDamage(m_penLauncher, DMT_EXPLOSION, m_fRangeDamageAmount*fDamageMul,
GetPlacement().pl_PositionVector, m_fDamageHotSpotRange, m_fDamageFallOffRange);
}
// sound event
if (m_fSoundRange>0.0f && IsDerivedFromClass( m_penLauncher, "Player"))
{
ESound eSound;
eSound.EsndtSound = SNDT_EXPLOSION;
eSound.penTarget = m_penLauncher;
SendEventInRange(eSound, FLOATaabbox3D(GetPlacement().pl_PositionVector, m_fSoundRange));
}
};
// spawn effect
void SpawnEffect(const CPlacement3D &plEffect, const ESpawnEffect &eSpawnEffect) {
CEntityPointer penEffect = CreateEntity(plEffect, CLASS_BASIC_EFFECT);
penEffect->Initialize(eSpawnEffect);
};
/************************************************************
* S O U N D S *
************************************************************/
void BounceSound(void) {
switch (m_prtType) {
case PRT_GRENADE:
if (en_vCurrentTranslationAbsolute.Length() > 3.0f) {
m_soEffect.Set3DParameters(20.0f, 2.0f, 1.0f, 1.0f);
PlaySound(m_soEffect, SOUND_GRENADE_BOUNCE, SOF_3D);
}
break;
}
};
// Calculate current rotation speed to rich given orientation in future
ANGLE GetRotationSpeed(ANGLE aWantedAngle, ANGLE aRotateSpeed, FLOAT fWaitFrequency)
{
ANGLE aResult;
// if desired position is smaller
if ( aWantedAngle<-aRotateSpeed*fWaitFrequency)
{
// start decreasing
aResult = -aRotateSpeed;
}
// if desired position is bigger
else if (aWantedAngle>aRotateSpeed*fWaitFrequency)
{
// start increasing
aResult = +aRotateSpeed;
}
// if desired position is more-less ahead
else
{
aResult = aWantedAngle/fWaitFrequency;
}
return aResult;
}
/* Receive damage */
void ReceiveDamage(CEntity *penInflictor, enum DamageType dmtType,
FLOAT fDamageAmmount, const FLOAT3D &vHitPoint, const FLOAT3D &vDirection)
{
// cannonball immediately destroys demons fireball
if (m_prtType==PRT_DEMON_FIREBALL && dmtType==DMT_CANNONBALL)
{
fDamageAmmount*=10001.0f;
}
if (m_prtType==PRT_FLAME && IsOfClass(penInflictor, "Moving Brush"))
{
Destroy();
}
CMovableModelEntity::ReceiveDamage(penInflictor,
dmtType, fDamageAmmount, vHitPoint, vDirection);
}
/************************************************************
* P R O C E D U R E S *
************************************************************/
procedures:
// --->>> PROJECTILE FLY IN SPACE
ProjectileFly(EVoid) {
// if already inside some entity
CEntity *penObstacle;
if (CheckForCollisionNow(0, &penObstacle)) {
// explode now
ProjectileTouch(penObstacle);
// if flame, continue existing
/*if (m_prtType==PRT_FLAME && ((CEntity &)*&penObstacle).en_RenderType==RT_MODEL) {
resume;
}*/
return EEnd();
}
// fly loop
wait(m_fFlyTime) {
on (EBegin) : { resume; }
on (EPass epass) : {
BOOL bHit;
// ignore launcher within 1 second
bHit = epass.penOther!=m_penLauncher || _pTimer->CurrentTick()>m_fIgnoreTime;
// ignore another projectile of same type
bHit &= !((!m_bCanHitHimself && IsOfClass(epass.penOther, "Projectile") &&
((CProjectile*)&*epass.penOther)->m_prtType==m_prtType));
// ignore twister
bHit &= !IsOfClass(epass.penOther, "Twister");
if (bHit) {
ProjectileTouch(epass.penOther);
// player flame passes through enemies
//if (m_prtType==PRT_FLAME && IsDerivedFromClass((CEntity *)&*(epass.penOther), "Enemy Base")) { resume; }
stop;
}
resume;
}
on (ETouch etouch) : {
// clear time limit for launcher
m_fIgnoreTime = 0.0f;
// ignore another projectile of same type
BOOL bHit;
bHit = !((!m_bCanHitHimself && IsOfClass(etouch.penOther, "Projectile") &&
((CProjectile*)&*etouch.penOther)->m_prtType==m_prtType));
if (bHit) {
ProjectileTouch(etouch.penOther);
stop;
}
resume;
}
on (EDeath) : {
if (m_bCanBeDestroyed) {
ProjectileHit();
stop;
}
resume;
}
on (ETimer) : {
ProjectileHit();
stop;
}
}
return EEnd();
};
// --->>> GUIDED PROJECTILE FLY IN SPACE
ProjectileGuidedFly(EVoid) {
// if already inside some entity
CEntity *penObstacle;
if (CheckForCollisionNow(0, &penObstacle)) {
// explode now
ProjectileTouch(penObstacle);
return EEnd();
}
// fly loop
while( _pTimer->CurrentTick()<(m_fStartTime+m_fFlyTime))
{
FLOAT fWaitFrequency = 0.1f;
// beast big projectile destroys soon after passing near the player
/*if (m_prtType==PRT_BEAST_BIG_PROJECTILE &&
DistanceTo(this, m_penTarget)<20.0f &&
(m_fStartTime+m_fFlyTime-_pTimer->CurrentTick())>1.5f)
{
m_fFlyTime = _pTimer->CurrentTick() - m_fStartTime + 1.5f;
}*/
if (m_penTarget!=NULL) {
// calculate desired position and angle
EntityInfo *pei= (EntityInfo*) (m_penTarget->GetEntityInfo());
FLOAT3D vDesiredPosition;
GetEntityInfoPosition( m_penTarget, pei->vSourceCenter, vDesiredPosition);
FLOAT3D vDesiredDirection = (vDesiredPosition-GetPlacement().pl_PositionVector).Normalize();
// for heading
ANGLE aWantedHeading = GetRelativeHeading( vDesiredDirection);
/*if (m_prtType==PRT_BEAST_BIG_PROJECTILE && m_fStartTime+m_fFlyTime-_pTimer->CurrentTick()<1.5f)
{
m_aRotateSpeed = 10.0f;
}*/
ANGLE aHeading = GetRotationSpeed( aWantedHeading, m_aRotateSpeed, fWaitFrequency);
// factor used to decrease speed of projectiles oriented opposite of its target
FLOAT fSpeedDecreasingFactor = ((180-Abs(aWantedHeading))/180.0f);
// factor used to increase speed when far away from target
FLOAT fSpeedIncreasingFactor = (vDesiredPosition-GetPlacement().pl_PositionVector).Length()/100;
fSpeedIncreasingFactor = ClampDn(fSpeedIncreasingFactor, 1.0f);
// decrease speed acodring to target's direction
FLOAT fMaxSpeed = m_fGuidedMaxSpeedFactor*fSpeedIncreasingFactor;
FLOAT fMinSpeedRatio = 0.5f;
FLOAT fWantedSpeed = fMaxSpeed*( fMinSpeedRatio+(1-fMinSpeedRatio)*fSpeedDecreasingFactor);
// adjust translation velocity
SetDesiredTranslation( FLOAT3D(0, 0, -fWantedSpeed));
// adjust rotation speed
m_aRotateSpeed = 75.0f*(1+0.5f*fSpeedDecreasingFactor);
// calculate distance factor
FLOAT fDistanceFactor = (vDesiredPosition-GetPlacement().pl_PositionVector).Length()/50.0;
fDistanceFactor = ClampUp(fDistanceFactor, 4.0f);
FLOAT fRNDHeading = (FRnd()-0.5f)*180*fDistanceFactor;
FLOAT fRNDPitch = (FRnd()-0.5f)*90*fDistanceFactor;
// if we are looking near direction of target
if( Abs( aWantedHeading) < 30.0f)
{
// calculate pitch speed
ANGLE aWantedPitch = GetRelativePitch( vDesiredDirection);
ANGLE aPitch = GetRotationSpeed( aWantedPitch, m_aRotateSpeed*1.5f, fWaitFrequency);
// adjust heading and pich
SetDesiredRotation(ANGLE3D(aHeading+fRNDHeading,aPitch+fRNDPitch,0));
}
// just adjust heading
else
{
SetDesiredRotation(ANGLE3D(aHeading,fDistanceFactor*40,0));
}
}
wait( fWaitFrequency)
{
on (EBegin) : { resume; }
on (EPass epass) : {
BOOL bHit;
// ignore launcher within 1 second
bHit = epass.penOther!=m_penLauncher || _pTimer->CurrentTick()>m_fIgnoreTime;
// ignore another projectile of same type
bHit &= !((!m_bCanHitHimself && IsOfClass(epass.penOther, "Projectile") &&
((CProjectile*)&*epass.penOther)->m_prtType==m_prtType));
// ignore twister
bHit &= !IsOfClass(epass.penOther, "Twister");
if (bHit) {
ProjectileTouch(epass.penOther);
return EEnd();
}
resume;
}
on (EDeath) :
{
if (m_bCanBeDestroyed)
{
ProjectileHit();
return EEnd();
}
resume;
}
on (ETimer) :
{
stop;
}
}
}
return EEnd();
};
ProjectileGuidedFastFly(EVoid) {
// if already inside some entity
CEntity *penObstacle;
if (CheckForCollisionNow(0, &penObstacle)) {
// explode now
ProjectileTouch(penObstacle);
return EEnd();
}
// fly loop
while( _pTimer->CurrentTick()<(m_fStartTime+m_fFlyTime))
{
FLOAT fWaitFrequency = 0.1f;
// beast big projectile destroys soon after passing near the player
if (m_prtType==PRT_BEAST_BIG_PROJECTILE &&
DistanceTo(this, m_penTarget)<20.0f &&
(m_fStartTime+m_fFlyTime-_pTimer->CurrentTick())>1.5f)
{
m_fFlyTime = _pTimer->CurrentTick() - m_fStartTime + 1.5f;
}
if (m_penTarget!=NULL) {
// calculate desired position and angle
EntityInfo *pei= (EntityInfo*) (m_penTarget->GetEntityInfo());
FLOAT3D vDesiredPosition;
GetEntityInfoPosition( m_penTarget, pei->vSourceCenter, vDesiredPosition);
FLOAT3D vDesiredDirection = (vDesiredPosition-GetPlacement().pl_PositionVector).Normalize();
// for heading
ANGLE aWantedHeading = GetRelativeHeading( vDesiredDirection);
ANGLE aHeading = GetRotationSpeed( aWantedHeading, 5.0f/*m_aRotateSpeed*/, fWaitFrequency);
// factor used to decrease speed of projectiles oriented opposite of its target
FLOAT fSpeedDecreasingFactor = ((180-Abs(aWantedHeading))/180.0f);
// factor used to increase speed when far away from target
FLOAT fSpeedIncreasingFactor = (vDesiredPosition-GetPlacement().pl_PositionVector).Length()/100;
fSpeedIncreasingFactor = ClampDn(fSpeedIncreasingFactor, 1.0f);
// decrease speed acording to target's direction
FLOAT fMaxSpeed = m_fGuidedMaxSpeedFactor*fSpeedIncreasingFactor;
FLOAT fMinSpeedRatio = 10.0f;
FLOAT fWantedSpeed = fMaxSpeed*( fMinSpeedRatio+(1-fMinSpeedRatio)*fSpeedDecreasingFactor);
// adjust translation velocity
SetDesiredTranslation( FLOAT3D(0, 0, -fWantedSpeed));
// adjust rotation speed
m_aRotateSpeed = 110.0f*(1+0.5f*fSpeedDecreasingFactor);
// calculate distance factor
FLOAT fDistanceFactor = (vDesiredPosition-GetPlacement().pl_PositionVector).Length()/50.0;
fDistanceFactor = ClampUp(fDistanceFactor, 4.0f);
// if we are looking near direction of target
if( Abs( aWantedHeading) < 30.0f)
{
bLockedOn = TRUE;
// calculate pitch speed
ANGLE aWantedPitch = GetRelativePitch( vDesiredDirection);
ANGLE aPitch = GetRotationSpeed( aWantedPitch, m_aRotateSpeed*1.5f, fWaitFrequency);
// adjust heading and pitch
SetDesiredRotation(ANGLE3D(aHeading, aPitch, 0));
}
// just adjust heading
else
{
if (bLockedOn) // we just missed the player
{
ANGLE3D aBankingUp;
aBankingUp = GetPlacement().pl_OrientationAngle;
aBankingUp(3) = 0.0f;
SetPlacement(CPlacement3D(GetPlacement().pl_PositionVector, aBankingUp));
}
bLockedOn = FALSE;
//SetDesiredRotation(ANGLE3D(aHeading,fDistanceFactor*40,0));
SetDesiredRotation(ANGLE3D(aHeading,400,0));
}
}
wait( fWaitFrequency)
{
on (EBegin) : { resume; }
on (ETouch etouch) : {
// clear time limit for launcher
m_fIgnoreTime = 0.0f;
// ignore itself and the demon
BOOL bHit;
bHit = !((!m_bCanHitHimself && IsOfClass(etouch.penOther, "Projectile") &&
((CProjectile*)&*etouch.penOther)->m_prtType==m_prtType));
bHit &= !IsOfClass(etouch.penOther, "Demon");
FLOAT3D vTrans = en_vCurrentTranslationAbsolute;
bHit &= Abs(vTrans.Normalize() % FLOAT3D(etouch.plCollision)) > 0.35;
if (bHit) {
ProjectileTouch(etouch.penOther);
return EEnd();
}
resume;
}
on (EPass epass) : {
BOOL bHit;
// ignore launcher within 1 second
bHit = epass.penOther!=m_penLauncher || _pTimer->CurrentTick()>m_fIgnoreTime;
// ignore another projectile of same type
bHit &= !((!m_bCanHitHimself && IsOfClass(epass.penOther, "Projectile") &&
((CProjectile*)&*epass.penOther)->m_prtType==m_prtType));
// ignore twister
bHit &= !IsOfClass(epass.penOther, "Twister");
// if demons projectile, ignore all other projectiles
bHit &= !(m_prtType==PRT_DEMON_FIREBALL && IsOfClass(epass.penOther, "Projectile"));
bHit &= !(m_prtType==PRT_BEAST_BIG_PROJECTILE && IsOfClass(epass.penOther, "Projectile"));
if (bHit) {
ProjectileTouch(epass.penOther);
return EEnd();
}
resume;
}
on (EDeath) :
{
if (m_bCanBeDestroyed)
{
ProjectileHit();
return EEnd();
}
resume;
}
on (ETimer) :
{
stop;
}
}
}
return EEnd();
};
ProjectileGuidedSlide(EVoid) {
// if already inside some entity
CEntity *penObstacle;
if (CheckForCollisionNow(0, &penObstacle)) {
// explode now
ProjectileTouch(penObstacle);
return EEnd();
}
// fly loop
while( _pTimer->CurrentTick()<(m_fStartTime+m_fFlyTime))
{
FLOAT fWaitFrequency = 0.1f;
if (m_penTarget!=NULL) {
// calculate desired position and angle
EntityInfo *pei= (EntityInfo*) (m_penTarget->GetEntityInfo());
FLOAT3D vDesiredPosition;
GetEntityInfoPosition( m_penTarget, pei->vSourceCenter, vDesiredPosition);
FLOAT3D vDesiredDirection = (vDesiredPosition-GetPlacement().pl_PositionVector).Normalize();
// for heading
ANGLE aWantedHeading = GetRelativeHeading( vDesiredDirection);
ANGLE aHeading = GetRotationSpeed( aWantedHeading, m_aRotateSpeed, fWaitFrequency);
// factor used to decrease speed of projectiles oriented opposite of its target
FLOAT fSpeedDecreasingFactor = ((180-Abs(aWantedHeading))/180.0f);
// factor used to increase speed when far away from target
FLOAT fSpeedIncreasingFactor = (vDesiredPosition-GetPlacement().pl_PositionVector).Length()/100;
fSpeedIncreasingFactor = ClampDn(fSpeedIncreasingFactor, 1.0f);
// decrease speed acodring to target's direction
FLOAT fMaxSpeed = 30.0f*fSpeedIncreasingFactor;
FLOAT fMinSpeedRatio = 0.5f;
FLOAT fWantedSpeed = fMaxSpeed*( fMinSpeedRatio+(1-fMinSpeedRatio)*fSpeedDecreasingFactor);
// adjust translation velocity
SetDesiredTranslation( FLOAT3D(0, 0, -fWantedSpeed));
// adjust rotation speed
m_aRotateSpeed = 75.0f*(1+0.5f*fSpeedDecreasingFactor);
// calculate distance factor
FLOAT fDistanceFactor = (vDesiredPosition-GetPlacement().pl_PositionVector).Length()/50.0;
fDistanceFactor = ClampUp(fDistanceFactor, 4.0f);
FLOAT fRNDHeading = (FRnd()-0.5f)*180*fDistanceFactor;
// if we are looking near direction of target
if( Abs( aWantedHeading) < 30.0f)
{
// adjust heading and pich
SetDesiredRotation(ANGLE3D(aHeading+fRNDHeading,0,0));
}
// just adjust heading
else
{
SetDesiredRotation(ANGLE3D(aHeading,0,0));
}
}
wait( fWaitFrequency)
{
on (EBegin) : { resume; }
on (EPass epass) : {
BOOL bHit;
// ignore launcher within 1 second
bHit = epass.penOther!=m_penLauncher || _pTimer->CurrentTick()>m_fIgnoreTime;
// ignore another projectile of same type
bHit &= !((!m_bCanHitHimself && IsOfClass(epass.penOther, "Projectile") &&
((CProjectile*)&*epass.penOther)->m_prtType==m_prtType));
// ignore twister
bHit &= !IsOfClass(epass.penOther, "Twister");
if (bHit) {
ProjectileTouch(epass.penOther);
return EEnd();
}
resume;
}
on (EDeath) :
{
if (m_bCanBeDestroyed)
{
ProjectileHit();
return EEnd();
}
resume;
}
on (ETimer) :
{
stop;
}
}
}
return EEnd();
};
// --->>> PROJECTILE SLIDE ON BRUSH
ProjectileSlide(EVoid) {
// if already inside some entity
CEntity *penObstacle;
if (CheckForCollisionNow(0, &penObstacle)) {
// explode now
ProjectileTouch(penObstacle);
return EEnd();
}
// fly loop
wait(m_fFlyTime) {
on (EBegin) : { resume; }
on (EPass epass) : {
BOOL bHit;
// ignore launcher within 1 second
bHit = epass.penOther!=m_penLauncher || _pTimer->CurrentTick()>m_fIgnoreTime;
// ignore another projectile of same type
bHit &= !((!m_bCanHitHimself && IsOfClass(epass.penOther, "Projectile") &&
((CProjectile*)&*epass.penOther)->m_prtType==m_prtType));
// ignore twister
bHit &= !IsOfClass(epass.penOther, "Twister");
if (epass.penOther!=m_penLauncher) {
bHit = bHit ;
}
if (bHit) {
ProjectileTouch(epass.penOther);
// player flame passes through enemies
if (m_prtType==PRT_FLAME && IsDerivedFromClass((CEntity *)&*(epass.penOther), "Enemy Base")) {
resume;
}
// wind blast passes through movable entities
if (m_prtType==PRT_AIRELEMENTAL_WIND && IsDerivedFromClass((CEntity *)&*(epass.penOther), "MovableEntity")) {
resume;
}
stop;
}
resume;
}
on (ETouch etouch) : {
// clear time limit for launcher
m_fIgnoreTime = 0.0f;
// ignore brushes
BOOL bHit;
bHit = !(etouch.penOther->GetRenderType() & RT_BRUSH);
if( m_prtType==PRT_FLAME && !bHit && !m_bLeftFlame)
{
SpawnFlame(m_penLauncher, etouch.penOther, GetPlacement().pl_PositionVector);
m_bLeftFlame=TRUE;
}
if (!bHit) { BounceSound(); }
// ignore another projectile of same type
bHit &= !((!m_bCanHitHimself && IsOfClass(etouch.penOther, "Projectile") &&
((CProjectile*)&*etouch.penOther)->m_prtType==m_prtType));
if (bHit) {
ProjectileTouch(etouch.penOther);
stop;
}
// projectile is moving to slow (stuck somewhere) -> kill it
if (en_vCurrentTranslationAbsolute.Length() < 0.25f*en_vDesiredTranslationRelative.Length()) {
ProjectileHit();
stop;
}
resume;
}
on (EDeath) : {
if (m_bCanBeDestroyed) {
ProjectileHit();
stop;
}
resume;
}
on (ETimer) : {
ProjectileHit();
stop;
}
}
return EEnd();
};
// --->>> PROJECTILE FLY IN SPACE WITH REBOUNDING
ProjectileFlyRebounding(EVoid) {
// if already inside some entity
CEntity *penObstacle;
if (CheckForCollisionNow(0, &penObstacle)) {
// explode now
ProjectileTouch(penObstacle);
return EEnd();
}
// fly loop
wait(m_fFlyTime) {
on (EBegin) : { resume; }
on (EPass epass) : {
BOOL bHit;
// ignore launcher within 1 second
bHit = epass.penOther!=m_penLauncher || _pTimer->CurrentTick()>m_fIgnoreTime;
// ignore another projectile of same type
bHit &= !((!m_bCanHitHimself && IsOfClass(epass.penOther, "Projectile") &&
((CProjectile*)&*epass.penOther)->m_prtType==m_prtType));
// ignore twister
bHit &= !IsOfClass(epass.penOther, "Twister");
if (bHit) {
ProjectileTouch(epass.penOther);
stop;
}
resume;
}
on (ETouch etouch) : {
// clear time limit for launcher
m_fIgnoreTime = 0.0f;
BOOL bHit;
// if brush hit
bHit = (etouch.penOther->GetRenderType() == RT_BRUSH);
if (bHit && m_iRebounds>0) {
//reverse direction
ReflectDirectionVectorByPlane(etouch.plCollision, en_vCurrentTranslationAbsolute);
ReflectRotationMatrixByPlane_cols(etouch.plCollision, en_mRotation);
m_iRebounds--;
} else {
// ignore another projectile of same type
bHit = !((!m_bCanHitHimself && IsOfClass(etouch.penOther, "Projectile") &&
((CProjectile*)&*etouch.penOther)->m_prtType==m_prtType));
if (bHit) {
ProjectileTouch(etouch.penOther);
stop;
}
}
resume;
}
on (EDeath) : {
if (m_bCanBeDestroyed) {
ProjectileHit();
stop;
}
resume;
}
on (ETimer) : {
ProjectileHit();
stop;
}
}
return EEnd();
};
// --->>> MAIN
Main(ELaunchProjectile eLaunch) {
// remember the initial parameters
ASSERT(eLaunch.penLauncher!=NULL);
m_penLauncher = eLaunch.penLauncher;
m_prtType = eLaunch.prtType;
m_fSpeed = eLaunch.fSpeed;
m_fStretch=eLaunch.fStretch;
SetPredictable(TRUE);
// remember lauching time
m_fIgnoreTime = _pTimer->CurrentTick() + 1.0f;
m_penLastDamaged = NULL;
switch (m_prtType) {
case PRT_DEVIL_ROCKET:
case PRT_WALKER_ROCKET:
case PRT_ROCKET:
case PRT_SHOOTER_WOODEN_DART:
{
Particles_RocketTrail_Prepare(this);
break;
}
case PRT_GUFFY_PROJECTILE: break; //Particles_RocketTrail_Prepare(this); break;
case PRT_GRENADE: Particles_GrenadeTrail_Prepare(this); break;
case PRT_CATMAN_FIRE: Particles_RocketTrail_Prepare(this); break;
case PRT_HEADMAN_FIRECRACKER: Particles_FirecrackerTrail_Prepare(this); break;
case PRT_HEADMAN_ROCKETMAN: Particles_Fireball01Trail_Prepare(this); break;
case PRT_HEADMAN_BOMBERMAN: Particles_BombTrail_Prepare(this); break;
case PRT_LAVA_COMET: Particles_LavaTrail_Prepare(this); break;
case PRT_LAVAMAN_BIG_BOMB: Particles_LavaBombTrail_Prepare(this); break;
case PRT_LAVAMAN_BOMB: Particles_LavaBombTrail_Prepare(this); break;
case PRT_BEAST_PROJECTILE: Particles_Fireball01Trail_Prepare(this); break;
case PRT_BEAST_BIG_PROJECTILE:
case PRT_DEVIL_GUIDED_PROJECTILE:
case PRT_DEMON_FIREBALL:
//case PRT_METEOR:
Particles_FirecrackerTrail_Prepare(this);
break;
case PRT_SHOOTER_FIREBALL: Particles_Fireball01Trail_Prepare(this); break;
}
// projectile initialization
switch (m_prtType)
{
case PRT_WALKER_ROCKET: WalkerRocket(); break;
case PRT_ROCKET: PlayerRocket(); break;
case PRT_GRENADE: PlayerGrenade(); break;
case PRT_FLAME: PlayerFlame(); break;
case PRT_LASER_RAY: PlayerLaserRay(); break;
case PRT_CATMAN_FIRE: CatmanProjectile(); break;
case PRT_HEADMAN_FIRECRACKER: HeadmanFirecracker(); break;
case PRT_HEADMAN_ROCKETMAN: HeadmanRocketman(); break;
case PRT_HEADMAN_BOMBERMAN: HeadmanBomberman(); break;
case PRT_BONEMAN_FIRE: BonemanProjectile(); break;
case PRT_WOMAN_FIRE: WomanProjectile(); break;
case PRT_DRAGONMAN_FIRE: DragonmanProjectile(DRAGONMAN_NORMAL); break;
case PRT_DRAGONMAN_STRONG_FIRE: DragonmanProjectile(DRAGONMAN_STRONG); break;
case PRT_STONEMAN_FIRE: ElementalRock(ELEMENTAL_NORMAL, ELEMENTAL_STONEMAN); break;
case PRT_STONEMAN_BIG_FIRE: ElementalRock(ELEMENTAL_BIG, ELEMENTAL_STONEMAN); break;
case PRT_STONEMAN_LARGE_FIRE: ElementalRock(ELEMENTAL_LARGE, ELEMENTAL_STONEMAN); break;
case PRT_LAVAMAN_BIG_BOMB: LavaManBomb(); break;
case PRT_LAVAMAN_BOMB: LavaManBomb(); break;
case PRT_LAVAMAN_STONE: ElementalRock(ELEMENTAL_NORMAL, ELEMENTAL_LAVAMAN); break;
case PRT_ICEMAN_FIRE: ElementalRock(ELEMENTAL_NORMAL, ELEMENTAL_ICEMAN); break;
case PRT_ICEMAN_BIG_FIRE: ElementalRock(ELEMENTAL_BIG, ELEMENTAL_ICEMAN); break;
case PRT_ICEMAN_LARGE_FIRE: ElementalRock(ELEMENTAL_LARGE, ELEMENTAL_ICEMAN); break;
case PRT_HUANMAN_FIRE: HuanmanProjectile(); break;
case PRT_FISHMAN_FIRE: FishmanProjectile(); break;
case PRT_MANTAMAN_FIRE: MantamanProjectile(); break;
case PRT_CYBORG_LASER: CyborgLaser(); break;
case PRT_CYBORG_BOMB: CyborgBomb(); break;
case PRT_LAVA_COMET: LavaBall(); break;
case PRT_BEAST_PROJECTILE: BeastProjectile(); break;
case PRT_BEAST_BIG_PROJECTILE: BeastBigProjectile(); break;
case PRT_BEAST_DEBRIS: BeastDebris(); break;
case PRT_BEAST_BIG_DEBRIS: BeastBigDebris(); break;
case PRT_DEVIL_LASER: DevilLaser(); break;
case PRT_DEVIL_ROCKET: DevilRocket(); break;
case PRT_DEVIL_GUIDED_PROJECTILE: DevilGuidedProjectile(); break;
case PRT_GRUNT_PROJECTILE_SOL: GruntSoldierLaser(); break;
case PRT_GRUNT_PROJECTILE_COM: GruntCommanderLaser(); break;
case PRT_GUFFY_PROJECTILE: GuffyProjectile(); break;
case PRT_DEMON_FIREBALL: DemonFireball(); break;
case PRT_LARVA_PLASMA: LarvaPlasma(); break;
case PRT_LARVA_TAIL_PROJECTILE: LarvaTail(); break;
case PRT_SHOOTER_WOODEN_DART: ShooterWoodenDart(); break;
case PRT_SHOOTER_FIREBALL: ShooterFireball(); break;
case PRT_SHOOTER_FLAME: ShooterFlame(); break;
case PRT_AFTERBURNER_DEBRIS: AfterburnerDebris(); break;
case PRT_AIRELEMENTAL_WIND: WindBlast(); break;
case PRT_METEOR: Meteor(); break;
default: ASSERTALWAYS("Unknown projectile type");
}
// setup light source
if (m_bLightSource) { SetupLightSource(TRUE); }
// fly
m_fStartTime = _pTimer->CurrentTick();
// if guided projectile
if( m_pmtMove == PMT_GUIDED) {
autocall ProjectileGuidedFly() EEnd;
} else if (m_pmtMove==PMT_GUIDED_FAST) {
autocall ProjectileGuidedFastFly() EEnd;
} else if (m_pmtMove==PMT_FLYING) {
autocall ProjectileFly() EEnd;
} else if (m_pmtMove==PMT_SLIDING) {
autocall ProjectileSlide() EEnd;
} else if (m_pmtMove==PMT_FLYING_REBOUNDING) {
autocall ProjectileFlyRebounding() EEnd;
} else if (m_pmtMove==PMT_GUIDED_SLIDING) {
autocall ProjectileGuidedSlide() EEnd;
}
// projectile explosion
switch (m_prtType) {
case PRT_WALKER_ROCKET: WalkerRocketExplosion(); break;
case PRT_ROCKET: PlayerRocketExplosion(); break;
case PRT_GRENADE: PlayerGrenadeExplosion(); break;
case PRT_LASER_RAY: PlayerLaserWave(); break;
case PRT_HEADMAN_BOMBERMAN: HeadmanBombermanExplosion(); break;
case PRT_CYBORG_BOMB: CyborgBombExplosion(); break;
case PRT_LAVA_COMET: LavamanBombDebrisExplosion(); break;
case PRT_LAVAMAN_BIG_BOMB: LavamanBombExplosion(); break;
case PRT_LAVAMAN_BOMB: LavamanBombDebrisExplosion(); break;
case PRT_BEAST_BIG_PROJECTILE: BeastBigProjectileExplosion(); break;
case PRT_BEAST_PROJECTILE: BeastProjectileExplosion(); break;
case PRT_BEAST_DEBRIS: BeastDebrisExplosion(); break;
case PRT_BEAST_BIG_DEBRIS: BeastBigDebrisExplosion(); break;
case PRT_DEVIL_ROCKET: DevilRocketExplosion(); break;
case PRT_DEVIL_GUIDED_PROJECTILE: DevilGuidedProjectileExplosion(); break;
case PRT_GUFFY_PROJECTILE: GuffyProjectileExplosion(); break;
case PRT_DEMON_FIREBALL: DemonFireballExplosion(); break;
case PRT_LARVA_PLASMA: LarvaPlasmaExplosion(); break;
case PRT_LARVA_TAIL_PROJECTILE: LarvaTailExplosion(); break;
case PRT_SHOOTER_WOODEN_DART: ShooterWoodenDartExplosion(); break;
case PRT_SHOOTER_FIREBALL: ShooterFireballExplosion(); break;
case PRT_METEOR: MeteorExplosion(); break;
}
// wait after death
if (m_fWaitAfterDeath>0.0f) {
SwitchToEditorModel();
ForceFullStop();
SetCollisionFlags(ECF_IMMATERIAL);
// kill light source
if (m_bLightSource) { SetupLightSource(FALSE); }
autowait(m_fWaitAfterDeath);
}
Destroy();
return;
}
};