mirror of
https://github.com/ptitSeb/Serious-Engine
synced 2024-12-01 22:25:53 +01:00
554 lines
17 KiB
Erlang
554 lines
17 KiB
Erlang
|
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
||
|
|
||
|
343
|
||
|
%{
|
||
|
#include "StdH.h"
|
||
|
//#include "ModelsMP/Enemies/Grunt/Grunt.h"
|
||
|
%}
|
||
|
|
||
|
uses "EntitiesMP/EnemyBase";
|
||
|
uses "EntitiesMP/BasicEffects";
|
||
|
|
||
|
enum GruntSkaType {
|
||
|
0 GT_SOLDIER "Grunt soldier",
|
||
|
1 GT_COMMANDER "Grunt commander",
|
||
|
};
|
||
|
|
||
|
%{
|
||
|
#define STRETCH_SOLDIER 1.2f
|
||
|
#define STRETCH_COMMANDER 1.4f
|
||
|
|
||
|
// info structure
|
||
|
static EntityInfo eiGruntSoldier = {
|
||
|
EIBT_FLESH, 200.0f,
|
||
|
0.0f, 1.9f*STRETCH_SOLDIER, 0.0f, // source (eyes)
|
||
|
0.0f, 1.3f*STRETCH_SOLDIER, 0.0f, // target (body)
|
||
|
};
|
||
|
|
||
|
static EntityInfo eiGruntCommander = {
|
||
|
EIBT_FLESH, 250.0f,
|
||
|
0.0f, 1.9f*STRETCH_COMMANDER, 0.0f, // source (eyes)
|
||
|
0.0f, 1.3f*STRETCH_COMMANDER, 0.0f, // target (body)
|
||
|
};
|
||
|
|
||
|
#define FIREPOS_SOLDIER FLOAT3D(0.07f, 1.36f, -0.78f)*STRETCH_SOLDIER
|
||
|
#define FIREPOS_COMMANDER_UP FLOAT3D(0.09f, 1.45f, -0.62f)*STRETCH_COMMANDER
|
||
|
#define FIREPOS_COMMANDER_DN FLOAT3D(0.10f, 1.30f, -0.60f)*STRETCH_COMMANDER
|
||
|
|
||
|
#define COMANDER_SMC_MODEL "ModelsSKA\\Enemies\\Grunt\\Commander.smc"
|
||
|
#define SOLIDER_SMC_MODEL "ModelsSKA\\Enemies\\Grunt\\Grunt.smc"
|
||
|
|
||
|
#define GRUNT_MESH
|
||
|
#define GRUNT_SKELETON
|
||
|
#define GRUNT_ANIMSET
|
||
|
#define GRUNT_TEXTURE
|
||
|
|
||
|
#define CLEAR_ANIM_TIME 0.2f
|
||
|
|
||
|
static INDEX idGrunt_Wound = -1;
|
||
|
static INDEX idGrunt_Run = -1;
|
||
|
static INDEX idGrunt_IdlePatrol = -1;
|
||
|
static INDEX idGrunt_IdleAttack = -1;
|
||
|
static INDEX idGrunt_Fire = -1;
|
||
|
static INDEX idGrunt_Default = -1;
|
||
|
static INDEX idGrunt_DeathForward = -1;
|
||
|
static INDEX idGrunt_DeathBackward = -1;
|
||
|
static INDEX idGrunt_GunModel = -1;
|
||
|
|
||
|
static INDEX idGrund_NormalBox = -1;
|
||
|
static INDEX idGrund_DeathBox = -1;
|
||
|
|
||
|
static CTextureObject _toStar01;
|
||
|
|
||
|
#define SHP_BASE_TEXTURE 0
|
||
|
|
||
|
%}
|
||
|
|
||
|
|
||
|
class CGruntSka: CEnemyBase {
|
||
|
name "GruntSka";
|
||
|
thumbnail "Thumbnails\\Grunt.tbn";
|
||
|
|
||
|
properties:
|
||
|
1 enum GruntSkaType m_gtType "Type" 'Y' = GT_SOLDIER,
|
||
|
|
||
|
10 CSoundObject m_soFire1,
|
||
|
11 CSoundObject m_soFire2,
|
||
|
20 FLOAT m_fMidBoneRot = 0.0f,
|
||
|
30 CModelInstance m_miTest,
|
||
|
|
||
|
|
||
|
// class internal
|
||
|
|
||
|
components:
|
||
|
1 class CLASS_BASE "Classes\\EnemyBase.ecl",
|
||
|
3 class CLASS_PROJECTILE "Classes\\Projectile.ecl",
|
||
|
|
||
|
// ************** SOUNDS **************
|
||
|
50 sound SOUND_IDLE "ModelsMP\\Enemies\\Grunt\\Sounds\\Idle.wav",
|
||
|
52 sound SOUND_SIGHT "ModelsMP\\Enemies\\Grunt\\Sounds\\Sight.wav",
|
||
|
53 sound SOUND_WOUND "ModelsMP\\Enemies\\Grunt\\Sounds\\Wound.wav",
|
||
|
57 sound SOUND_FIRE "ModelsMP\\Enemies\\Grunt\\Sounds\\Fire.wav",
|
||
|
58 sound SOUND_DEATH "ModelsMP\\Enemies\\Grunt\\Sounds\\Death.wav",
|
||
|
|
||
|
functions:
|
||
|
|
||
|
void CGruntSka(void)
|
||
|
{
|
||
|
// Get animation id's
|
||
|
idGrunt_Wound = ska_GetIDFromStringTable("Grunt_Wound");
|
||
|
idGrunt_Run = ska_GetIDFromStringTable("Grunt_Run");
|
||
|
idGrunt_IdlePatrol = ska_GetIDFromStringTable("Grunt_IdlePatrol");
|
||
|
idGrunt_IdleAttack = ska_GetIDFromStringTable("Grunt_IdleAttack");
|
||
|
idGrunt_Fire = ska_GetIDFromStringTable("Grunt_Fire");
|
||
|
idGrunt_Default = ska_GetIDFromStringTable("Grunt_Default");
|
||
|
idGrunt_DeathForward = ska_GetIDFromStringTable("Grunt_DeathForward");
|
||
|
idGrunt_DeathBackward = ska_GetIDFromStringTable("Grunt_DeathBackward");
|
||
|
idGrunt_GunModel = ska_GetIDFromStringTable("Flamer");
|
||
|
|
||
|
// Get colision box id's
|
||
|
idGrund_NormalBox = ska_GetIDFromStringTable("Normal");
|
||
|
idGrund_DeathBox = ska_GetIDFromStringTable("Death");
|
||
|
};
|
||
|
|
||
|
void CreateTestModelInstance()
|
||
|
{
|
||
|
try {
|
||
|
m_miTest.AddMesh_t((CTString)"ModelsSKA\\Test\\Arm\\Arm.bm");
|
||
|
m_miTest.AddSkeleton_t((CTString)"ModelsSKA\\Test\\Arm\\Arm.bs");
|
||
|
m_miTest.AddAnimSet_t((CTString)"ModelsSKA\\Test\\Arm\\Arm.ba");
|
||
|
m_miTest.AddTexture_t((CTString)"ModelsSKA\\Test\\Arm\\Objects\\Arm.tex","Arm",NULL);
|
||
|
m_miTest.AddColisionBox("Default",FLOAT3D(-0.5f,0.0f,-0.5f),FLOAT3D(0.5f,2.0f,0.5f));
|
||
|
} catch (char *strErr) {
|
||
|
FatalError(strErr);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void BuildGruntModel()
|
||
|
{
|
||
|
// CreateTestModelInstance();
|
||
|
|
||
|
en_pmiModelInstance = CreateModelInstance("GruntSka");
|
||
|
CModelInstance *pmi = GetModelInstance();
|
||
|
try{
|
||
|
// setup grunt solider
|
||
|
pmi->AddMesh_t((CTString)"ModelsSKA\\Enemies\\Grunt\\Grunt.bm");
|
||
|
pmi->AddSkeleton_t((CTString)"ModelsSKA\\Enemies\\Grunt\\Grunt.bs");
|
||
|
pmi->AddAnimSet_t((CTString)"ModelsSKA\\Enemies\\Grunt\\Grunt.ba");
|
||
|
pmi->AddTexture_t((CTString)"ModelsSKA\\Enemies\\Grunt\\Soldier.tex","Grunt",NULL);
|
||
|
pmi->AddColisionBox("Default",FLOAT3D(-0.5f,0.0f,-0.5f),FLOAT3D(0.5f,2.0f,0.5f));
|
||
|
|
||
|
// setup weapon
|
||
|
CModelInstance *pmiFlamer = CreateModelInstance("Flamer");
|
||
|
pmiFlamer->AddMesh_t((CTString)"ModelsSKA\\Weapons\\Flamer\\Flamer.bm");
|
||
|
pmiFlamer->AddSkeleton_t((CTString)"ModelsSKA\\Weapons\\Flamer\\Flamer.bs");
|
||
|
pmiFlamer->AddAnimSet_t((CTString)"ModelsSKA\\Weapons\\Flamer\\Flamer.ba");
|
||
|
pmiFlamer->AddTexture_t((CTString)"ModelsSKA\\Weapons\\Flamer\\Flamer.tex","Flamer",NULL);
|
||
|
pmiFlamer->AddTexture_t((CTString)"ModelsSKA\\Enemies\\Grunt\\Lava04FX.tex","Lava04FX",NULL);
|
||
|
// Set flamer offset
|
||
|
pmiFlamer->SetOffsetRot(ANGLE3D(0,0,180));
|
||
|
// Attach flamer to grunt
|
||
|
pmi->AddChild(pmiFlamer);
|
||
|
|
||
|
// Set flamer parent bone
|
||
|
INDEX iParenBoneID = ska_GetIDFromStringTable("R_Hand");
|
||
|
pmiFlamer->SetParentBone(iParenBoneID);
|
||
|
|
||
|
// Set colision info
|
||
|
SetSkaColisionInfo();
|
||
|
} catch(char *strErr) {
|
||
|
FatalError(strErr);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
void BuildCommanderModel(CEntity *penGrunt)
|
||
|
{
|
||
|
SetSkaModel("ModelsSKA\\Enemies\\Grunt\\CommanderNoGun.smc");
|
||
|
CModelInstance *pmiFlamer = NULL;
|
||
|
try{
|
||
|
pmiFlamer = ParseSmcFile_t("ModelsSKA\\Weapons\\Flamer\\Flamer.smc");
|
||
|
} catch(char *strErr) {
|
||
|
FatalError(strErr);
|
||
|
}
|
||
|
// Set flamer parent bone
|
||
|
INDEX iParenBoneID = ska_GetIDFromStringTable("R_Hand");
|
||
|
CModelInstance *pmi = GetModelInstance();
|
||
|
pmi->AddChild(pmiFlamer);
|
||
|
pmiFlamer->SetParentBone(iParenBoneID);
|
||
|
// Set flamer offset
|
||
|
pmiFlamer->SetOffsetRot(ANGLE3D(0,0,180));
|
||
|
// Set colision info
|
||
|
SetSkaColisionInfo();
|
||
|
};
|
||
|
/*
|
||
|
void Particles_OneParticle( FLOAT3D vPos )
|
||
|
{
|
||
|
Particle_PrepareTexture(&_toStar01, PBT_ADDALPHA);
|
||
|
Particle_SetTexturePart( 512, 512, 0, 0);
|
||
|
|
||
|
COLOR col = RGBAToColor(128, 128, 128, 128);
|
||
|
Particle_RenderSquare( vPos, 1.0f, 0.0f, col);
|
||
|
Particle_Flush();
|
||
|
}
|
||
|
|
||
|
void RenderParticles(void) {
|
||
|
INDEX iBoneID = ska_GetIDFromStringTable("R_Hand");
|
||
|
FLOAT3D vStartPoint;
|
||
|
FLOAT3D vEndPoint;
|
||
|
if(GetBoneAbsPosition(iBoneID,vStartPoint,vEndPoint)) {
|
||
|
Particles_OneParticle(vStartPoint);
|
||
|
}
|
||
|
};
|
||
|
*/
|
||
|
/*
|
||
|
void AdjustBones()
|
||
|
{
|
||
|
INDEX iBoneID = ska_GetIDFromStringTable("MidTorso");
|
||
|
RenBone *rb = RM_FindRenBone(iBoneID);
|
||
|
if(rb!=NULL) {
|
||
|
FLOATquat3D quat;
|
||
|
quat.FromEuler(ANGLE3D(0,0,AngleRad(Sin(m_fMidBoneRot)/3.0f)));
|
||
|
rb->rb_arRot.ar_qRot = quat;
|
||
|
}
|
||
|
m_fMidBoneRot+=1;
|
||
|
};
|
||
|
*/
|
||
|
/*
|
||
|
void AdjustBones()
|
||
|
{
|
||
|
INDEX ctrb = 0;
|
||
|
RenBone *pRenBones=RM_GetRenBoneArray(ctrb);
|
||
|
// for each t ren bones after first dummy one
|
||
|
for(INDEX irb=1;irb<ctrb-3;irb+=3) {
|
||
|
RenBone &rb = pRenBones[irb];
|
||
|
FLOATquat3D quat;
|
||
|
quat.FromEuler(ANGLE3D(0,0,AngleRad(Sin(m_fMidBoneRot)/3.0f)));
|
||
|
rb.rb_arRot.ar_qRot = quat;
|
||
|
}
|
||
|
m_fMidBoneRot+=1;
|
||
|
}
|
||
|
*/
|
||
|
/*
|
||
|
void AdjustShaderParams(INDEX iSurfaceID,CShader *pShader,ShaderParams &spParams)
|
||
|
{
|
||
|
INDEX iFlamerMeshID = ska_GetIDFromStringTable("Top");
|
||
|
|
||
|
|
||
|
if(iSurfaceID == iFlamerMeshID) {
|
||
|
if(pShader != NULL) {
|
||
|
ShaderDesc sdDesc;
|
||
|
pShader->GetShaderDesc(sdDesc);
|
||
|
if(sdDesc.sd_astrTextureNames.Count() > SHP_BASE_TEXTURE) {
|
||
|
spParams.sp_aiTextureIDs[SHP_BASE_TEXTURE] = ska_GetIDFromStringTable("Lava04FX");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
*/
|
||
|
/*
|
||
|
CModelInstance *GetModelInstanceForRendering()
|
||
|
{
|
||
|
return &m_miTest;
|
||
|
};
|
||
|
*/
|
||
|
|
||
|
// describe how this enemy killed player
|
||
|
virtual CTString GetPlayerKillDescription(const CTString &strPlayerName, const EDeath &eDeath)
|
||
|
{
|
||
|
CTString str;
|
||
|
str.PrintF(TRANS("A Grunt sent %s into the halls of Valhalla"), strPlayerName);
|
||
|
return str;
|
||
|
}
|
||
|
|
||
|
/* Entity info */
|
||
|
void *GetEntityInfo(void) {
|
||
|
if (m_gtType==GT_SOLDIER) {
|
||
|
return &eiGruntSoldier;
|
||
|
} else if (m_gtType==GT_COMMANDER) {
|
||
|
return &eiGruntSoldier;
|
||
|
} else {
|
||
|
ASSERT("Unknown grunt type!");
|
||
|
return NULL;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
virtual const CTFileName &GetComputerMessageName(void) const {
|
||
|
static DECLARE_CTFILENAME(fnmSoldier, "DataMP\\Messages\\Enemies\\GruntSoldier.txt");
|
||
|
static DECLARE_CTFILENAME(fnmCommander, "DataMP\\Messages\\Enemies\\GruntCommander.txt");
|
||
|
switch(m_gtType) {
|
||
|
default: ASSERT(FALSE);
|
||
|
case GT_SOLDIER: return fnmSoldier;
|
||
|
case GT_COMMANDER: return fnmCommander;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
void Precache(void) {
|
||
|
CEnemyBase::Precache();
|
||
|
|
||
|
if (m_gtType==GT_SOLDIER) {
|
||
|
PrecacheClass(CLASS_PROJECTILE, PRT_GRUNT_PROJECTILE_SOL);
|
||
|
}
|
||
|
if (m_gtType==GT_COMMANDER) {
|
||
|
PrecacheClass(CLASS_PROJECTILE, PRT_GRUNT_PROJECTILE_COM);
|
||
|
}
|
||
|
|
||
|
PrecacheSound(SOUND_IDLE);
|
||
|
PrecacheSound(SOUND_SIGHT);
|
||
|
PrecacheSound(SOUND_WOUND);
|
||
|
PrecacheSound(SOUND_FIRE);
|
||
|
PrecacheSound(SOUND_DEATH);
|
||
|
};
|
||
|
|
||
|
/* Receive damage */
|
||
|
void ReceiveDamage(CEntity *penInflictor, enum DamageType dmtType,
|
||
|
FLOAT fDamageAmmount, const FLOAT3D &vHitPoint, const FLOAT3D &vDirection)
|
||
|
{
|
||
|
CEnemyBase::ReceiveDamage(penInflictor, dmtType, fDamageAmmount, vHitPoint, vDirection);
|
||
|
};
|
||
|
|
||
|
// damage anim
|
||
|
INDEX AnimForDamage(FLOAT fDamage) {
|
||
|
GetModelInstance()->AddAnimation(idGrunt_Wound,AN_CLEAR,1,0);
|
||
|
return idGrunt_Wound;
|
||
|
};
|
||
|
|
||
|
// death
|
||
|
INDEX AnimForDeath(void) {
|
||
|
INDEX idAnimDeath;
|
||
|
FLOAT3D vFront;
|
||
|
GetHeadingDirection(0, vFront);
|
||
|
FLOAT fDamageDir = m_vDamage%vFront;
|
||
|
if (fDamageDir<0) {
|
||
|
idAnimDeath = idGrunt_DeathBackward;
|
||
|
} else {
|
||
|
idAnimDeath = idGrunt_DeathForward;
|
||
|
}
|
||
|
|
||
|
GetModelInstance()->AddAnimation(idAnimDeath,AN_CLEAR,1,0);
|
||
|
|
||
|
return idAnimDeath;
|
||
|
};
|
||
|
|
||
|
FLOAT WaitForDust(FLOAT3D &vStretch) {
|
||
|
|
||
|
vStretch=FLOAT3D(1,1,2);
|
||
|
if(GetModelInstance()->IsAnimationPlaying(idGrunt_DeathBackward)) {
|
||
|
return 0.5f;
|
||
|
} else if(GetModelInstance()->IsAnimationPlaying(idGrunt_DeathForward)) {
|
||
|
return 1.0f;
|
||
|
}
|
||
|
return -1.0f;
|
||
|
};
|
||
|
|
||
|
void DeathNotify(void) {
|
||
|
INDEX iBoxIndex = GetModelInstance()->GetColisionBoxIndex(idGrund_DeathBox);
|
||
|
ASSERT(iBoxIndex>=0);
|
||
|
ChangeCollisionBoxIndexWhenPossible(iBoxIndex);
|
||
|
en_fDensity = 500.0f;
|
||
|
};
|
||
|
|
||
|
// virtual anim functions
|
||
|
void StandingAnim(void) {
|
||
|
GetModelInstance()->AddAnimation(idGrunt_IdleAttack,AN_LOOPING|AN_NORESTART|AN_CLEAR,1,0);
|
||
|
};
|
||
|
/*void StandingAnimFight(void)
|
||
|
{
|
||
|
StartModelAnim(HEADMAN_ANIM_IDLE_FIGHT, AOF_LOOPING|AOF_NORESTART);
|
||
|
}*/
|
||
|
void RunningAnim(void) {
|
||
|
GetModelInstance()->AddAnimation(idGrunt_Run,AN_LOOPING|AN_NORESTART|AN_CLEAR,1,0);
|
||
|
};
|
||
|
void WalkingAnim(void) {
|
||
|
RunningAnim();
|
||
|
};
|
||
|
void RotatingAnim(void) {
|
||
|
RunningAnim();
|
||
|
};
|
||
|
|
||
|
// virtual sound functions
|
||
|
void IdleSound(void) {
|
||
|
PlaySound(m_soSound, SOUND_IDLE, SOF_3D);
|
||
|
};
|
||
|
void SightSound(void) {
|
||
|
PlaySound(m_soSound, SOUND_SIGHT, SOF_3D);
|
||
|
};
|
||
|
void WoundSound(void) {
|
||
|
PlaySound(m_soSound, SOUND_WOUND, SOF_3D);
|
||
|
};
|
||
|
void DeathSound(void) {
|
||
|
PlaySound(m_soSound, SOUND_DEATH, SOF_3D);
|
||
|
};
|
||
|
|
||
|
// adjust sound and watcher parameters here if needed
|
||
|
void EnemyPostInit(void)
|
||
|
{
|
||
|
// set sound default parameters
|
||
|
m_soFire1.Set3DParameters(160.0f, 50.0f, 1.0f, 1.0f);
|
||
|
m_soFire2.Set3DParameters(160.0f, 50.0f, 1.0f, 1.0f);
|
||
|
};
|
||
|
|
||
|
procedures:
|
||
|
/************************************************************
|
||
|
* A T T A C K E N E M Y *
|
||
|
************************************************************/
|
||
|
Fire(EVoid) : CEnemyBase::Fire {
|
||
|
// soldier
|
||
|
if (m_gtType == GT_SOLDIER) {
|
||
|
autocall SoldierAttack() EEnd;
|
||
|
// commander
|
||
|
} else if (m_gtType == GT_COMMANDER) {
|
||
|
autocall CommanderAttack() EEnd;
|
||
|
// should never get here
|
||
|
} else{
|
||
|
ASSERT(FALSE);
|
||
|
}
|
||
|
return EReturn();
|
||
|
};
|
||
|
|
||
|
// Soldier attack
|
||
|
SoldierAttack(EVoid) {
|
||
|
|
||
|
StandingAnimFight();
|
||
|
autowait(0.2f + FRnd()*0.25f);
|
||
|
|
||
|
GetModelInstance()->AddAnimation(idGrunt_Fire,AN_CLEAR,1.0f,0);
|
||
|
|
||
|
ShootProjectile(PRT_GRUNT_PROJECTILE_SOL, FIREPOS_SOLDIER, ANGLE3D(0, 0, 0));
|
||
|
PlaySound(m_soFire1, SOUND_FIRE, SOF_3D);
|
||
|
|
||
|
autowait(0.15f + FRnd()*0.1f);
|
||
|
GetModelInstance()->AddAnimation(idGrunt_Fire,AN_CLEAR,1.0f,0);
|
||
|
ShootProjectile(PRT_GRUNT_PROJECTILE_SOL, FIREPOS_SOLDIER, ANGLE3D(0, 0, 0));
|
||
|
PlaySound(m_soFire2, SOUND_FIRE, SOF_3D);
|
||
|
|
||
|
|
||
|
autowait(FRnd()*0.333f);
|
||
|
return EEnd();
|
||
|
};
|
||
|
|
||
|
// Commander attack (predicted firing on moving player)
|
||
|
CommanderAttack(EVoid) {
|
||
|
StandingAnimFight();
|
||
|
autowait(0.2f + FRnd()*0.25f);
|
||
|
|
||
|
/*FLOAT3D vGunPosAbs = GetPlacement().pl_PositionVector + FLOAT3D(0.0f, 1.0f, 0.0f)*GetRotationMatrix();
|
||
|
FLOAT3D vEnemySpeed = ((CMovableEntity&) *m_penEnemy).en_vCurrentTranslationAbsolute;
|
||
|
FLOAT3D vEnemyPos = ((CMovableEntity&) *m_penEnemy).GetPlacement().pl_PositionVector;
|
||
|
FLOAT fLaserSpeed = 45.0f; // m/s
|
||
|
FLOAT3D vPredictedEnemyPosition = CalculatePredictedPosition(vGunPosAbs,
|
||
|
vEnemyPos, fLaserSpeed, vEnemySpeed, GetPlacement().pl_PositionVector(2) );
|
||
|
ShootPredictedProjectile(PRT_GRUNT_LASER, vPredictedEnemyPosition, FLOAT3D(0.0f, 1.0f, 0.0f), ANGLE3D(0, 0, 0));*/
|
||
|
|
||
|
GetModelInstance()->AddAnimation(idGrunt_Fire,AN_CLEAR,1,0);
|
||
|
ShootProjectile(PRT_GRUNT_PROJECTILE_COM, FIREPOS_COMMANDER_DN, ANGLE3D(-20, 0, 0));
|
||
|
PlaySound(m_soFire1, SOUND_FIRE, SOF_3D);
|
||
|
|
||
|
autowait(0.035f);
|
||
|
GetModelInstance()->AddAnimation(idGrunt_Fire,AN_CLEAR,1,0);
|
||
|
ShootProjectile(PRT_GRUNT_PROJECTILE_COM, FIREPOS_COMMANDER_DN, ANGLE3D(-10, 0, 0));
|
||
|
PlaySound(m_soFire2, SOUND_FIRE, SOF_3D);
|
||
|
|
||
|
autowait(0.035f);
|
||
|
GetModelInstance()->AddAnimation(idGrunt_Fire,AN_CLEAR,1,0);
|
||
|
ShootProjectile(PRT_GRUNT_PROJECTILE_COM, FIREPOS_COMMANDER_DN, ANGLE3D(0, 0, 0));
|
||
|
PlaySound(m_soFire1, SOUND_FIRE, SOF_3D);
|
||
|
|
||
|
autowait(0.035f);
|
||
|
GetModelInstance()->AddAnimation(idGrunt_Fire,AN_CLEAR,1,0);
|
||
|
ShootProjectile(PRT_GRUNT_PROJECTILE_COM, FIREPOS_COMMANDER_DN, ANGLE3D(10, 0, 0));
|
||
|
PlaySound(m_soFire2, SOUND_FIRE, SOF_3D);
|
||
|
|
||
|
autowait(0.035f);
|
||
|
GetModelInstance()->AddAnimation(idGrunt_Fire,AN_CLEAR,1,0);
|
||
|
ShootProjectile(PRT_GRUNT_PROJECTILE_COM, FIREPOS_COMMANDER_DN, ANGLE3D(20, 0, 0));
|
||
|
PlaySound(m_soFire2, SOUND_FIRE, SOF_3D);
|
||
|
|
||
|
autowait(FRnd()*0.5f);
|
||
|
return EEnd();
|
||
|
};
|
||
|
|
||
|
/************************************************************
|
||
|
* M A I N *
|
||
|
************************************************************/
|
||
|
Main(EVoid) {
|
||
|
// declare yourself as a model
|
||
|
InitAsSkaModel();
|
||
|
SetPhysicsFlags(EPF_MODEL_WALKING|EPF_HASLUNGS);
|
||
|
SetCollisionFlags(ECF_MODEL);
|
||
|
SetFlags(GetFlags()|ENF_ALIVE);
|
||
|
en_tmMaxHoldBreath = 5.0f;
|
||
|
en_fDensity = 2000.0f;
|
||
|
//m_fBlowUpSize = 2.0f;
|
||
|
|
||
|
//_toStar01.SetData_t(CTFILENAME("Models\\Items\\Particles\\Star01.tex"));
|
||
|
|
||
|
|
||
|
// set your appearance
|
||
|
switch (m_gtType) {
|
||
|
case GT_SOLDIER:
|
||
|
SetSkaModel(SOLIDER_SMC_MODEL);
|
||
|
// BuildGruntModel();
|
||
|
|
||
|
// setup moving speed
|
||
|
m_fWalkSpeed = FRnd() + 2.5f;
|
||
|
m_aWalkRotateSpeed = AngleDeg(FRnd()*10.0f + 500.0f);
|
||
|
m_fAttackRunSpeed = FRnd() + 6.5f;
|
||
|
m_aAttackRotateSpeed = AngleDeg(FRnd()*50 + 245.0f);
|
||
|
m_fCloseRunSpeed = FRnd() + 6.5f;
|
||
|
m_aCloseRotateSpeed = AngleDeg(FRnd()*50 + 245.0f);
|
||
|
// setup attack distances
|
||
|
m_fAttackDistance = 80.0f;
|
||
|
m_fCloseDistance = 0.0f;
|
||
|
m_fStopDistance = 8.0f;
|
||
|
m_fAttackFireTime = 2.0f;
|
||
|
m_fCloseFireTime = 1.0f;
|
||
|
m_fIgnoreRange = 200.0f;
|
||
|
//m_fBlowUpAmount = 65.0f;
|
||
|
m_fBlowUpAmount = 80.0f;
|
||
|
m_fBodyParts = 4;
|
||
|
m_fDamageWounded = 0.0f;
|
||
|
m_iScore = 500;
|
||
|
SetHealth(40.0f);
|
||
|
m_fMaxHealth = 40.0f;
|
||
|
// set stretch factors for height and width
|
||
|
GetModelInstance()->StretchModel(FLOAT3D(STRETCH_SOLDIER, STRETCH_SOLDIER, STRETCH_SOLDIER));
|
||
|
break;
|
||
|
|
||
|
case GT_COMMANDER:
|
||
|
|
||
|
SetSkaModel(COMANDER_SMC_MODEL);
|
||
|
// BuildCommanderModel();
|
||
|
|
||
|
m_fWalkSpeed = FRnd() + 2.5f;
|
||
|
m_aWalkRotateSpeed = AngleDeg(FRnd()*10.0f + 500.0f);
|
||
|
m_fAttackRunSpeed = FRnd() + 8.0f;
|
||
|
m_aAttackRotateSpeed = AngleDeg(FRnd()*50 + 245.0f);
|
||
|
m_fCloseRunSpeed = FRnd() + 8.0f;
|
||
|
m_aCloseRotateSpeed = AngleDeg(FRnd()*50 + 245.0f);
|
||
|
// setup attack distances
|
||
|
m_fAttackDistance = 90.0f;
|
||
|
m_fCloseDistance = 0.0f;
|
||
|
m_fStopDistance = 15.0f;
|
||
|
m_fAttackFireTime = 4.0f;
|
||
|
m_fCloseFireTime = 2.0f;
|
||
|
//m_fBlowUpAmount = 180.0f;
|
||
|
m_fIgnoreRange = 200.0f;
|
||
|
// damage/explode properties
|
||
|
m_fBodyParts = 5;
|
||
|
m_fDamageWounded = 0.0f;
|
||
|
m_iScore = 800;
|
||
|
SetHealth(60.0f);
|
||
|
m_fMaxHealth = 60.0f;
|
||
|
// set stretch factors for height and width
|
||
|
GetModelInstance()->StretchModel(FLOAT3D(STRETCH_COMMANDER, STRETCH_COMMANDER, STRETCH_COMMANDER));
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
ModelChangeNotify();
|
||
|
StandingAnim();
|
||
|
|
||
|
// continue behavior in base class
|
||
|
jump CEnemyBase::MainLoop();
|
||
|
};
|
||
|
};
|