2016-03-11 14:57:17 +01:00
|
|
|
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
|
|
|
|
|
|
|
340
|
|
|
|
%{
|
2016-04-01 20:04:24 +02:00
|
|
|
#include "EntitiesMP/StdH/StdH.h"
|
2016-03-11 14:57:17 +01:00
|
|
|
#include "ModelsMP/Enemies/Mental/Mental.h"
|
|
|
|
%}
|
|
|
|
|
|
|
|
uses "EntitiesMP/EnemyBase";
|
|
|
|
uses "EntitiesMP/BasicEffects";
|
|
|
|
|
|
|
|
enum BigHeadType {
|
|
|
|
0 BHT_NORMAL "Normal",
|
|
|
|
1 BHT_ZOMBIE "Zombie",
|
|
|
|
2 BHT_SAINT "Saint",
|
|
|
|
};
|
|
|
|
|
|
|
|
%{
|
|
|
|
// info structure
|
|
|
|
static EntityInfo eiMental = {
|
|
|
|
EIBT_FLESH, 200.0f,
|
|
|
|
0.0f, 1.5f, 0.0f, // source (eyes)
|
|
|
|
0.0f, 1.0f, 0.0f, // target (body)
|
|
|
|
};
|
|
|
|
|
|
|
|
#define GREET_SENSE_RANGE 10.0f
|
|
|
|
#define GREET_SENSE_DELAY 30.0f
|
|
|
|
|
|
|
|
%}
|
|
|
|
|
|
|
|
class CBigHead: CEnemyBase {
|
|
|
|
name "BigHead";
|
|
|
|
thumbnail "Thumbnails\\Mental.tbn";
|
|
|
|
|
|
|
|
properties:
|
|
|
|
// class internal
|
|
|
|
1 CTFileName m_fnmHeadTex "Head texture" 'H' = CTString(""),
|
|
|
|
2 CTFileName m_fnmNameSnd "Name sound" 'S' = CTString(""),
|
|
|
|
3 FLOAT m_tmLastGreetTime = -100.0f,
|
|
|
|
4 enum BigHeadType m_bhtType "Type" 'Y'= BHT_NORMAL,
|
|
|
|
5 BOOL m_bIgnorePlayer "Ignore player" 'I' = FALSE,
|
|
|
|
6 BOOL m_bPlayingWalkSound = FALSE,
|
|
|
|
7 BOOL m_bSleeping "Sleeping" 'S' = FALSE, // set to make it sleep initally
|
|
|
|
8 FLOAT m_tmLastWalkingSoundTime = -100.0f,
|
|
|
|
9 FLOAT m_tmWalkingSound "Walk sound frequency" = 5.0f,
|
|
|
|
|
|
|
|
{
|
|
|
|
CAutoPrecacheSound m_aps;
|
|
|
|
CAutoPrecacheTexture m_apt;
|
|
|
|
}
|
|
|
|
|
|
|
|
components:
|
|
|
|
1 class CLASS_BASE "Classes\\EnemyBase.ecl",
|
|
|
|
2 class CLASS_BLOOD_SPRAY "Classes\\BloodSpray.ecl",
|
|
|
|
3 class CLASS_BASIC_EFFECT "Classes\\BasicEffect.ecl",
|
|
|
|
|
|
|
|
// ************** DATA **************
|
|
|
|
10 model MODEL_MENTAL "ModelsMP\\Enemies\\Mental\\Mental.mdl",
|
|
|
|
11 texture TEXTURE_MENTAL "ModelsMP\\Enemies\\Mental\\Mental.tex",
|
|
|
|
12 model MODEL_HEAD "ModelsMP\\Enemies\\Mental\\Head.mdl",
|
|
|
|
13 model MODEL_HORNS "ModelsMP\\Enemies\\Mental\\Horns.mdl",
|
|
|
|
14 texture TEXTURE_HORNS "ModelsMP\\Enemies\\Mental\\Horns.tex",
|
|
|
|
15 model MODEL_AURA "ModelsMP\\Enemies\\Mental\\Aura.mdl",
|
|
|
|
16 texture TEXTURE_AURA "ModelsMP\\Enemies\\Mental\\Aura.tex",
|
|
|
|
|
|
|
|
50 sound SOUND_IDLE "Models\\Enemies\\Mental\\Sounds\\Idle.wav",
|
|
|
|
51 sound SOUND_SIGHT "Models\\Enemies\\Mental\\Sounds\\Sight.wav",
|
|
|
|
52 sound SOUND_WOUND "Models\\Enemies\\Mental\\Sounds\\Wound.wav",
|
|
|
|
53 sound SOUND_DEATH "Models\\Enemies\\Mental\\Sounds\\Death.wav",
|
|
|
|
54 sound SOUND_WALKZOMBIE "ModelsMP\\Enemies\\Mental\\Sounds\\ComeToDaddy.wav",
|
|
|
|
55 sound SOUND_WALKSAINT "ModelsMP\\Enemies\\Mental\\Sounds\\PeaceWithYou.wav",
|
|
|
|
|
|
|
|
functions:
|
|
|
|
BOOL HandleEvent(const CEntityEvent &ee)
|
|
|
|
{
|
|
|
|
if (m_bIgnorePlayer) {
|
|
|
|
if (ee.ee_slEvent==EVENTCODE_ETouch) {
|
|
|
|
ETouch &et = (ETouch &)ee;
|
|
|
|
if (IsOfClass(et.penOther, "Player")) {
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return CEnemyBase::HandleEvent(ee);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Entity info */
|
|
|
|
void *GetEntityInfo(void)
|
|
|
|
{
|
|
|
|
return &eiMental;
|
|
|
|
};
|
|
|
|
|
|
|
|
void Precache(void)
|
|
|
|
{
|
|
|
|
CEnemyBase::Precache();
|
|
|
|
PrecacheSound(SOUND_SIGHT);
|
|
|
|
PrecacheSound(SOUND_IDLE);
|
|
|
|
PrecacheSound(SOUND_WOUND);
|
|
|
|
PrecacheSound(SOUND_DEATH);
|
|
|
|
PrecacheSound(SOUND_WALKZOMBIE);
|
|
|
|
PrecacheSound(SOUND_WALKSAINT);
|
|
|
|
m_aps.Precache(m_fnmNameSnd);
|
|
|
|
m_apt.Precache(m_fnmHeadTex);
|
|
|
|
};
|
|
|
|
|
|
|
|
INDEX GetWalkAnim(void)
|
|
|
|
{
|
|
|
|
if (m_bhtType==BHT_ZOMBIE) {
|
|
|
|
return MENTAL_ANIM_WALKZOMBIE;
|
|
|
|
} else if (m_bhtType==BHT_SAINT) {
|
|
|
|
return MENTAL_ANIM_WALKANGEL;
|
|
|
|
} else {
|
|
|
|
return MENTAL_ANIM_RUN;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// damage anim
|
|
|
|
INDEX AnimForDamage(FLOAT fDamage) {
|
|
|
|
INDEX iAnim;
|
|
|
|
iAnim = MENTAL_ANIM_PANIC;
|
|
|
|
StartModelAnim(iAnim, 0);
|
|
|
|
return iAnim;
|
|
|
|
};
|
|
|
|
|
|
|
|
// death
|
|
|
|
INDEX AnimForDeath(void) {
|
|
|
|
INDEX iAnim;
|
|
|
|
iAnim = MENTAL_ANIM_DEATH;
|
|
|
|
StartModelAnim(iAnim, 0);
|
|
|
|
return iAnim;
|
|
|
|
};
|
|
|
|
|
|
|
|
void DeathNotify(void) {
|
|
|
|
// ChangeCollisionBoxIndexWhenPossible(HEADMAN_COLLISION_BOX_DEATH);
|
|
|
|
en_fDensity = 500.0f;
|
|
|
|
};
|
|
|
|
|
|
|
|
// virtual anim functions
|
|
|
|
void StandingAnim(void) {
|
|
|
|
StartModelAnim(MENTAL_ANIM_GROUNDREST, AOF_LOOPING|AOF_NORESTART);
|
|
|
|
};
|
|
|
|
void WalkingAnim(void) {
|
|
|
|
PlayWalkSound();
|
|
|
|
StartModelAnim(GetWalkAnim(), AOF_LOOPING|AOF_NORESTART);
|
|
|
|
|
|
|
|
if (!m_bIgnorePlayer && _pTimer->CurrentTick()>m_tmLastGreetTime+GREET_SENSE_DELAY) {
|
|
|
|
m_fSenseRange = GREET_SENSE_RANGE;
|
|
|
|
m_bDeaf = FALSE;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
void RunningAnim(void)
|
|
|
|
{
|
|
|
|
PlayWalkSound();
|
|
|
|
StartModelAnim(GetWalkAnim(), AOF_LOOPING|AOF_NORESTART);
|
|
|
|
};
|
|
|
|
void RotatingAnim(void) {
|
|
|
|
RunningAnim();
|
|
|
|
};
|
|
|
|
|
|
|
|
void PlayWalkSound(void)
|
|
|
|
{
|
|
|
|
INDEX iSound = SOUND_WALKZOMBIE;
|
|
|
|
if (m_bhtType==BHT_ZOMBIE) {
|
|
|
|
iSound = SOUND_WALKZOMBIE;
|
|
|
|
} else if (m_bhtType==BHT_SAINT) {
|
|
|
|
iSound = SOUND_WALKSAINT;
|
|
|
|
} else {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (!m_bPlayingWalkSound || _pTimer->CurrentTick()-m_tmLastWalkingSoundTime>m_tmWalkingSound) {
|
|
|
|
m_bPlayingWalkSound = TRUE;
|
|
|
|
m_tmLastWalkingSoundTime = _pTimer->CurrentTick();
|
|
|
|
PlaySound(m_soSound, iSound, SOF_3D);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// virtual sound functions
|
|
|
|
void IdleSound(void) {
|
|
|
|
if (m_bIgnorePlayer) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
PlaySound(m_soSound, SOUND_IDLE, SOF_3D);
|
|
|
|
m_bPlayingWalkSound = FALSE;
|
|
|
|
};
|
|
|
|
|
|
|
|
void SightSound(void) {
|
|
|
|
PlaySound(m_soSound, SOUND_SIGHT, SOF_3D);
|
|
|
|
m_bPlayingWalkSound = FALSE;
|
|
|
|
};
|
|
|
|
void WoundSound(void) {
|
|
|
|
PlaySound(m_soSound, SOUND_WOUND, SOF_3D);
|
|
|
|
m_bPlayingWalkSound = FALSE;
|
|
|
|
};
|
|
|
|
void DeathSound(void) {
|
|
|
|
PlaySound(m_soSound, SOUND_DEATH, SOF_3D);
|
|
|
|
m_bPlayingWalkSound = FALSE;
|
|
|
|
};
|
|
|
|
|
|
|
|
procedures:
|
|
|
|
Fire(EVoid) : CEnemyBase::Fire {
|
|
|
|
// hit
|
|
|
|
if (CalcDist(m_penEnemy) <= m_fStopDistance*1.1f) {
|
|
|
|
if (m_fnmNameSnd!="") {
|
|
|
|
PlaySound(m_soSound, m_fnmNameSnd, SOF_3D);
|
|
|
|
m_bPlayingWalkSound = FALSE;
|
|
|
|
}
|
|
|
|
m_bBlind = TRUE;
|
|
|
|
m_bDeaf = TRUE;
|
|
|
|
m_fSenseRange = 0.0f;
|
|
|
|
m_tmLastGreetTime = _pTimer->CurrentTick();
|
|
|
|
SetTargetNone();
|
|
|
|
StartModelAnim(MENTAL_ANIM_GREET, 0);
|
|
|
|
autowait(GetModelObject()->GetCurrentAnimLength());
|
|
|
|
StandingAnim();
|
|
|
|
return EReconsiderBehavior();
|
|
|
|
}
|
|
|
|
return EReturn();
|
|
|
|
}
|
|
|
|
|
|
|
|
Sleep(EVoid)
|
|
|
|
{
|
|
|
|
// start sleeping anim
|
|
|
|
StartModelAnim(MENTAL_ANIM_SNORE, AOF_LOOPING);
|
|
|
|
// repeat
|
|
|
|
wait() {
|
|
|
|
// if triggered
|
|
|
|
on(ETrigger eTrigger) : {
|
|
|
|
// // remember enemy
|
|
|
|
// SetTargetSoft(eTrigger.penCaused);
|
|
|
|
// wake up
|
|
|
|
jump WakeUp();
|
|
|
|
}
|
|
|
|
/* // if damaged
|
|
|
|
on(EDamage eDamage) : {
|
|
|
|
// wake up
|
|
|
|
jump WakeUp();
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
otherwise() : {
|
|
|
|
resume;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
WakeUp(EVoid)
|
|
|
|
{
|
|
|
|
// wakeup anim
|
|
|
|
SightSound();
|
|
|
|
StartModelAnim(MENTAL_ANIM_GETUP, 0);
|
|
|
|
autowait(GetModelObject()->GetCurrentAnimLength());
|
|
|
|
|
|
|
|
// trigger your target
|
|
|
|
// SendToTarget(m_penDeathTarget, m_eetDeathType);
|
|
|
|
// proceed with normal functioning
|
|
|
|
return EReturn();
|
|
|
|
}
|
|
|
|
|
|
|
|
// overridable called before main enemy loop actually begins
|
|
|
|
PreMainLoop(EVoid) : CEnemyBase::PreMainLoop
|
|
|
|
{
|
|
|
|
// if sleeping
|
|
|
|
if (m_bSleeping) {
|
|
|
|
m_bSleeping = FALSE;
|
|
|
|
// go to sleep until waken up
|
|
|
|
wait() {
|
|
|
|
on (EBegin) : {
|
|
|
|
call Sleep();
|
|
|
|
}
|
|
|
|
on (EReturn) : {
|
|
|
|
stop;
|
|
|
|
};
|
|
|
|
// if dead
|
|
|
|
on(EDeath eDeath) : {
|
|
|
|
// die
|
|
|
|
jump CEnemyBase::Die(eDeath);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return EReturn();
|
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************
|
|
|
|
* M A I N *
|
|
|
|
************************************************************/
|
|
|
|
Main(EVoid) {
|
|
|
|
// declare yourself as a model
|
|
|
|
InitAsModel();
|
|
|
|
SetPhysicsFlags(EPF_MODEL_WALKING|EPF_HASLUNGS);
|
|
|
|
SetCollisionFlags(ECF_MODEL);
|
|
|
|
SetFlags(GetFlags()|ENF_ALIVE);
|
|
|
|
SetHealth(20.0f);
|
|
|
|
m_fMaxHealth = 20.0f;
|
|
|
|
en_tmMaxHoldBreath = 5.0f;
|
|
|
|
en_fDensity = 2000.0f;
|
|
|
|
m_fBlowUpSize = 2.0f;
|
|
|
|
|
|
|
|
// set your appearance
|
|
|
|
SetModel(MODEL_MENTAL);
|
|
|
|
SetModelMainTexture(TEXTURE_MENTAL);
|
|
|
|
AddAttachment(0, MODEL_HEAD, TEXTURE_MENTAL);
|
|
|
|
if (m_fnmHeadTex!="") {
|
|
|
|
// try to
|
|
|
|
try {
|
|
|
|
CAttachmentModelObject *pamoHead = GetModelObject()->GetAttachmentModel(0);
|
|
|
|
if (pamoHead!=NULL) {
|
|
|
|
pamoHead->amo_moModelObject.mo_toTexture.SetData_t(m_fnmHeadTex);
|
|
|
|
}
|
|
|
|
// if anything failed
|
|
|
|
} catch (char *strError) {
|
|
|
|
// report error
|
|
|
|
CPrintF("%s\n", strError);
|
|
|
|
AddAttachment(0, MODEL_HEAD, TEXTURE_MENTAL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (m_bhtType==BHT_ZOMBIE) {
|
|
|
|
AddAttachment(MENTAL_ATTACHMENT_HORNS, MODEL_HORNS, TEXTURE_HORNS);
|
|
|
|
} else if (m_bhtType==BHT_SAINT) {
|
|
|
|
AddAttachment(MENTAL_ATTACHMENT_AURA, MODEL_AURA, TEXTURE_AURA);
|
|
|
|
}
|
|
|
|
|
|
|
|
// setup moving speed
|
|
|
|
m_fWalkSpeed = FRnd() + 1.5f;
|
|
|
|
m_aWalkRotateSpeed = AngleDeg(FRnd()*10.0f + 500.0f);
|
|
|
|
m_fAttackRunSpeed = FRnd()*2.0f + 6.0f;
|
|
|
|
m_aAttackRotateSpeed = AngleDeg(FRnd()*50 + 245.0f);
|
|
|
|
m_fCloseRunSpeed = FRnd()*2.0f + 6.0f;
|
|
|
|
m_aCloseRotateSpeed = AngleDeg(FRnd()*50 + 245.0f);
|
|
|
|
// setup attack distances
|
|
|
|
m_fAttackDistance = 50.0f;
|
|
|
|
m_fCloseDistance = 0.0f;
|
|
|
|
m_fStopDistance = 5.0f; // greeting distance
|
|
|
|
m_fAttackFireTime = 0.1f;
|
|
|
|
m_fCloseFireTime = 0.1f;
|
|
|
|
m_fIgnoreRange = 200.0f;
|
|
|
|
// damage/explode properties
|
|
|
|
m_fBlowUpAmount = 65.0f;
|
|
|
|
m_fBodyParts = 4;
|
|
|
|
m_fDamageWounded = 1.0f;
|
|
|
|
m_iScore = 0;
|
|
|
|
if (m_bIgnorePlayer) {
|
|
|
|
m_bBlind = TRUE;
|
|
|
|
m_bDeaf = TRUE;
|
|
|
|
m_fSenseRange = 0;
|
|
|
|
} else {
|
|
|
|
m_bBlind = TRUE;
|
|
|
|
m_fSenseRange = GREET_SENSE_RANGE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// set stretch factors for height and width
|
|
|
|
const FLOAT fSize = 0.6f;
|
|
|
|
GetModelObject()->StretchModel(FLOAT3D(fSize, fSize, fSize));
|
|
|
|
ModelChangeNotify();
|
|
|
|
StandingAnim();
|
|
|
|
|
|
|
|
// continue behavior in base class
|
|
|
|
jump CEnemyBase::MainLoop();
|
|
|
|
};
|
|
|
|
};
|