2022-12-17 13:32:43 +01:00
|
|
|
/***
|
2013-08-30 13:34:05 -07:00
|
|
|
*
|
|
|
|
* Copyright (c) 1996-2001, Valve LLC. All rights reserved.
|
|
|
|
*
|
|
|
|
* This product contains software technology licensed from Id
|
|
|
|
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
|
|
|
* All Rights Reserved.
|
|
|
|
*
|
|
|
|
* This source code contains proprietary and confidential information of
|
|
|
|
* Valve LLC and its suppliers. Access to this code is restricted to
|
|
|
|
* persons who have executed a written SDK license with Valve. Any access,
|
|
|
|
* use or distribution of this code by or to any unlicensed person is illegal.
|
|
|
|
*
|
|
|
|
****/
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
h_tentacle.cpp - silo of death tentacle monster (half life)
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
#include "extdll.h"
|
|
|
|
#include "util.h"
|
|
|
|
#include "cbase.h"
|
|
|
|
#include "monsters.h"
|
|
|
|
#include "weapons.h"
|
|
|
|
#include "soundent.h"
|
2013-08-30 13:34:05 -07:00
|
|
|
|
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
#define ACT_T_IDLE 1010
|
|
|
|
#define ACT_T_TAP 1020
|
|
|
|
#define ACT_T_STRIKE 1030
|
|
|
|
#define ACT_T_REARIDLE 1040
|
2013-08-30 13:34:05 -07:00
|
|
|
|
|
|
|
class CTentacle : public CBaseMonster
|
|
|
|
{
|
|
|
|
public:
|
2021-03-05 20:54:33 +01:00
|
|
|
CTentacle();
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
void Spawn() override;
|
|
|
|
void Precache() override;
|
|
|
|
bool KeyValue(KeyValueData* pkvd) override;
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
bool Save(CSave& save) override;
|
|
|
|
bool Restore(CRestore& restore) override;
|
|
|
|
static TYPEDESCRIPTION m_SaveData[];
|
2013-08-30 13:34:05 -07:00
|
|
|
|
|
|
|
// Don't allow the tentacle to go across transitions!!!
|
2021-11-29 20:31:17 +01:00
|
|
|
int ObjectCaps() override { return CBaseMonster::ObjectCaps() & ~FCAP_ACROSS_TRANSITION; }
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-03-05 23:07:22 +01:00
|
|
|
void SetObjectCollisionBox() override
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
|
|
|
pev->absmin = pev->origin + Vector(-400, -400, 0);
|
|
|
|
pev->absmax = pev->origin + Vector(400, 400, 850);
|
|
|
|
}
|
|
|
|
|
2021-03-05 20:54:33 +01:00
|
|
|
void EXPORT Cycle();
|
2021-11-28 16:54:48 +01:00
|
|
|
void EXPORT CommandUse(CBaseEntity* pActivator, CBaseEntity* pCaller, USE_TYPE useType, float value);
|
2021-03-05 20:54:33 +01:00
|
|
|
void EXPORT Start();
|
|
|
|
void EXPORT DieThink();
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-03-05 20:54:33 +01:00
|
|
|
void EXPORT Test();
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
void EXPORT HitTouch(CBaseEntity* pOther);
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-03-05 23:48:27 +01:00
|
|
|
float HearingSensitivity() override { return 2.0; }
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
bool TakeDamage(entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType) override;
|
|
|
|
void HandleAnimEvent(MonsterEvent_t* pEvent) override;
|
|
|
|
void Killed(entvars_t* pevAttacker, int iGib) override;
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
MONSTERSTATE GetIdealState() override { return MONSTERSTATE_IDLE; }
|
2021-03-05 23:07:22 +01:00
|
|
|
//TODO: should override base, but has different signature
|
2021-11-28 16:54:48 +01:00
|
|
|
bool CanPlaySequence(bool fDisregardState) { return true; }
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-03-05 23:07:22 +01:00
|
|
|
int Classify() override;
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
int Level(float dz);
|
2021-03-05 20:54:33 +01:00
|
|
|
int MyLevel();
|
|
|
|
float MyHeight();
|
2013-08-30 13:34:05 -07:00
|
|
|
|
|
|
|
float m_flInitialYaw;
|
|
|
|
int m_iGoalAnim;
|
|
|
|
int m_iLevel;
|
|
|
|
int m_iDir;
|
|
|
|
float m_flFramerateAdj;
|
|
|
|
float m_flSoundYaw;
|
|
|
|
int m_iSoundLevel;
|
|
|
|
float m_flSoundTime;
|
|
|
|
float m_flSoundRadius;
|
|
|
|
int m_iHitDmg;
|
|
|
|
float m_flHitTime;
|
|
|
|
|
|
|
|
float m_flTapRadius;
|
|
|
|
|
|
|
|
float m_flNextSong;
|
2021-11-28 15:32:26 +01:00
|
|
|
static bool g_fFlySound;
|
|
|
|
static bool g_fSquirmSound;
|
2013-08-30 13:34:05 -07:00
|
|
|
|
|
|
|
float m_flMaxYaw;
|
|
|
|
int m_iTapSound;
|
|
|
|
|
|
|
|
Vector m_vecPrevSound;
|
|
|
|
float m_flPrevSoundTime;
|
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
static const char* pHitSilo[];
|
|
|
|
static const char* pHitDirt[];
|
|
|
|
static const char* pHitWater[];
|
2013-08-30 13:34:05 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-11-29 20:31:17 +01:00
|
|
|
bool CTentacle::g_fFlySound;
|
|
|
|
bool CTentacle::g_fSquirmSound;
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
LINK_ENTITY_TO_CLASS(monster_tentacle, CTentacle);
|
2013-08-30 13:34:05 -07:00
|
|
|
|
|
|
|
// stike sounds
|
|
|
|
#define TE_NONE -1
|
|
|
|
#define TE_SILO 0
|
|
|
|
#define TE_DIRT 1
|
|
|
|
#define TE_WATER 2
|
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
const char* CTentacle::pHitSilo[] =
|
|
|
|
{
|
|
|
|
"tentacle/te_strike1.wav",
|
|
|
|
"tentacle/te_strike2.wav",
|
2013-08-30 13:34:05 -07:00
|
|
|
};
|
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
const char* CTentacle::pHitDirt[] =
|
|
|
|
{
|
|
|
|
"player/pl_dirt1.wav",
|
|
|
|
"player/pl_dirt2.wav",
|
|
|
|
"player/pl_dirt3.wav",
|
|
|
|
"player/pl_dirt4.wav",
|
2013-08-30 13:34:05 -07:00
|
|
|
};
|
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
const char* CTentacle::pHitWater[] =
|
|
|
|
{
|
|
|
|
"player/pl_slosh1.wav",
|
|
|
|
"player/pl_slosh2.wav",
|
|
|
|
"player/pl_slosh3.wav",
|
|
|
|
"player/pl_slosh4.wav",
|
2013-08-30 13:34:05 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
TYPEDESCRIPTION CTentacle::m_SaveData[] =
|
|
|
|
{
|
|
|
|
DEFINE_FIELD(CTentacle, m_flInitialYaw, FIELD_FLOAT),
|
|
|
|
DEFINE_FIELD(CTentacle, m_iGoalAnim, FIELD_INTEGER),
|
|
|
|
DEFINE_FIELD(CTentacle, m_iLevel, FIELD_INTEGER),
|
|
|
|
DEFINE_FIELD(CTentacle, m_iDir, FIELD_INTEGER),
|
|
|
|
DEFINE_FIELD(CTentacle, m_flFramerateAdj, FIELD_FLOAT),
|
|
|
|
DEFINE_FIELD(CTentacle, m_flSoundYaw, FIELD_FLOAT),
|
|
|
|
DEFINE_FIELD(CTentacle, m_iSoundLevel, FIELD_INTEGER),
|
|
|
|
DEFINE_FIELD(CTentacle, m_flSoundTime, FIELD_TIME),
|
|
|
|
DEFINE_FIELD(CTentacle, m_flSoundRadius, FIELD_FLOAT),
|
|
|
|
DEFINE_FIELD(CTentacle, m_iHitDmg, FIELD_INTEGER),
|
|
|
|
DEFINE_FIELD(CTentacle, m_flHitTime, FIELD_TIME),
|
|
|
|
DEFINE_FIELD(CTentacle, m_flTapRadius, FIELD_FLOAT),
|
|
|
|
DEFINE_FIELD(CTentacle, m_flNextSong, FIELD_TIME),
|
|
|
|
DEFINE_FIELD(CTentacle, m_iTapSound, FIELD_INTEGER),
|
|
|
|
DEFINE_FIELD(CTentacle, m_flMaxYaw, FIELD_FLOAT),
|
|
|
|
DEFINE_FIELD(CTentacle, m_vecPrevSound, FIELD_POSITION_VECTOR),
|
|
|
|
DEFINE_FIELD(CTentacle, m_flPrevSoundTime, FIELD_TIME),
|
2013-08-30 13:34:05 -07:00
|
|
|
};
|
2021-11-28 16:54:48 +01:00
|
|
|
IMPLEMENT_SAVERESTORE(CTentacle, CBaseMonster);
|
2013-08-30 13:34:05 -07:00
|
|
|
|
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
// animation sequence aliases
|
2013-08-30 13:34:05 -07:00
|
|
|
typedef enum
|
|
|
|
{
|
|
|
|
TENTACLE_ANIM_Pit_Idle,
|
|
|
|
|
|
|
|
TENTACLE_ANIM_rise_to_Temp1,
|
|
|
|
TENTACLE_ANIM_Temp1_to_Floor,
|
|
|
|
TENTACLE_ANIM_Floor_Idle,
|
|
|
|
TENTACLE_ANIM_Floor_Fidget_Pissed,
|
|
|
|
TENTACLE_ANIM_Floor_Fidget_SmallRise,
|
|
|
|
TENTACLE_ANIM_Floor_Fidget_Wave,
|
|
|
|
TENTACLE_ANIM_Floor_Strike,
|
|
|
|
TENTACLE_ANIM_Floor_Tap,
|
|
|
|
TENTACLE_ANIM_Floor_Rotate,
|
|
|
|
TENTACLE_ANIM_Floor_Rear,
|
|
|
|
TENTACLE_ANIM_Floor_Rear_Idle,
|
|
|
|
TENTACLE_ANIM_Floor_to_Lev1,
|
|
|
|
|
|
|
|
TENTACLE_ANIM_Lev1_Idle,
|
|
|
|
TENTACLE_ANIM_Lev1_Fidget_Claw,
|
|
|
|
TENTACLE_ANIM_Lev1_Fidget_Shake,
|
|
|
|
TENTACLE_ANIM_Lev1_Fidget_Snap,
|
|
|
|
TENTACLE_ANIM_Lev1_Strike,
|
|
|
|
TENTACLE_ANIM_Lev1_Tap,
|
|
|
|
TENTACLE_ANIM_Lev1_Rotate,
|
|
|
|
TENTACLE_ANIM_Lev1_Rear,
|
|
|
|
TENTACLE_ANIM_Lev1_Rear_Idle,
|
|
|
|
TENTACLE_ANIM_Lev1_to_Lev2,
|
|
|
|
|
|
|
|
TENTACLE_ANIM_Lev2_Idle,
|
|
|
|
TENTACLE_ANIM_Lev2_Fidget_Shake,
|
|
|
|
TENTACLE_ANIM_Lev2_Fidget_Swing,
|
|
|
|
TENTACLE_ANIM_Lev2_Fidget_Tut,
|
|
|
|
TENTACLE_ANIM_Lev2_Strike,
|
|
|
|
TENTACLE_ANIM_Lev2_Tap,
|
|
|
|
TENTACLE_ANIM_Lev2_Rotate,
|
|
|
|
TENTACLE_ANIM_Lev2_Rear,
|
|
|
|
TENTACLE_ANIM_Lev2_Rear_Idle,
|
|
|
|
TENTACLE_ANIM_Lev2_to_Lev3,
|
|
|
|
|
|
|
|
TENTACLE_ANIM_Lev3_Idle,
|
|
|
|
TENTACLE_ANIM_Lev3_Fidget_Shake,
|
|
|
|
TENTACLE_ANIM_Lev3_Fidget_Side,
|
|
|
|
TENTACLE_ANIM_Lev3_Fidget_Swipe,
|
|
|
|
TENTACLE_ANIM_Lev3_Strike,
|
|
|
|
TENTACLE_ANIM_Lev3_Tap,
|
|
|
|
TENTACLE_ANIM_Lev3_Rotate,
|
|
|
|
TENTACLE_ANIM_Lev3_Rear,
|
|
|
|
TENTACLE_ANIM_Lev3_Rear_Idle,
|
|
|
|
|
|
|
|
TENTACLE_ANIM_Lev1_Door_reach,
|
|
|
|
|
|
|
|
TENTACLE_ANIM_Lev3_to_Engine,
|
|
|
|
TENTACLE_ANIM_Engine_Idle,
|
|
|
|
TENTACLE_ANIM_Engine_Sway,
|
|
|
|
TENTACLE_ANIM_Engine_Swat,
|
|
|
|
TENTACLE_ANIM_Engine_Bob,
|
|
|
|
TENTACLE_ANIM_Engine_Death1,
|
|
|
|
TENTACLE_ANIM_Engine_Death2,
|
|
|
|
TENTACLE_ANIM_Engine_Death3,
|
|
|
|
|
|
|
|
TENTACLE_ANIM_none
|
|
|
|
} TENTACLE_ANIM;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//=========================================================
|
2021-11-28 16:54:48 +01:00
|
|
|
// Classify - indicates this monster's place in the
|
2013-08-30 13:34:05 -07:00
|
|
|
// relationship table.
|
|
|
|
//=========================================================
|
2021-11-29 20:31:17 +01:00
|
|
|
int CTentacle::Classify()
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
2021-11-28 16:54:48 +01:00
|
|
|
return CLASS_ALIEN_MONSTER;
|
2013-08-30 13:34:05 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Tentacle Spawn
|
|
|
|
//
|
2021-11-29 20:31:17 +01:00
|
|
|
void CTentacle::Spawn()
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
2021-11-28 16:54:48 +01:00
|
|
|
Precache();
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
pev->solid = SOLID_BBOX;
|
|
|
|
pev->movetype = MOVETYPE_FLY;
|
|
|
|
pev->effects = 0;
|
|
|
|
pev->health = 75;
|
|
|
|
pev->sequence = 0;
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2022-03-28 12:37:15 +02:00
|
|
|
//Always interpolate tentacles since they don't actually move.
|
|
|
|
m_EFlags |= EFLAG_SLERP;
|
|
|
|
|
2013-08-30 13:34:05 -07:00
|
|
|
SET_MODEL(ENT(pev), "models/tentacle2.mdl");
|
2021-11-28 16:54:48 +01:00
|
|
|
UTIL_SetSize(pev, Vector(-32, -32, 0), Vector(32, 32, 64));
|
|
|
|
|
|
|
|
pev->takedamage = DAMAGE_AIM;
|
|
|
|
pev->flags |= FL_MONSTER;
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
m_bloodColor = BLOOD_COLOR_GREEN;
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
SetThink(&CTentacle::Start);
|
|
|
|
SetTouch(&CTentacle::HitTouch);
|
|
|
|
SetUse(&CTentacle::CommandUse);
|
2013-08-30 13:34:05 -07:00
|
|
|
|
|
|
|
pev->nextthink = gpGlobals->time + 0.2;
|
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
ResetSequenceInfo();
|
2013-08-30 13:34:05 -07:00
|
|
|
m_iDir = 1;
|
|
|
|
|
|
|
|
pev->yaw_speed = 18;
|
|
|
|
m_flInitialYaw = pev->angles.y;
|
|
|
|
pev->ideal_yaw = m_flInitialYaw;
|
|
|
|
|
2021-11-19 13:43:33 +01:00
|
|
|
g_fFlySound = false;
|
|
|
|
g_fSquirmSound = false;
|
2013-08-30 13:34:05 -07:00
|
|
|
|
|
|
|
m_iHitDmg = 20;
|
|
|
|
|
|
|
|
if (m_flMaxYaw <= 0)
|
|
|
|
m_flMaxYaw = 65;
|
|
|
|
|
|
|
|
m_MonsterState = MONSTERSTATE_IDLE;
|
|
|
|
|
|
|
|
// SetThink( Test );
|
2021-11-28 16:54:48 +01:00
|
|
|
UTIL_SetOrigin(pev, pev->origin);
|
2013-08-30 13:34:05 -07:00
|
|
|
}
|
|
|
|
|
2021-11-29 20:31:17 +01:00
|
|
|
void CTentacle::Precache()
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
|
|
|
PRECACHE_MODEL("models/tentacle2.mdl");
|
|
|
|
|
|
|
|
PRECACHE_SOUND("ambience/flies.wav");
|
|
|
|
PRECACHE_SOUND("ambience/squirm2.wav");
|
|
|
|
|
|
|
|
PRECACHE_SOUND("tentacle/te_alert1.wav");
|
|
|
|
PRECACHE_SOUND("tentacle/te_alert2.wav");
|
|
|
|
PRECACHE_SOUND("tentacle/te_flies1.wav");
|
|
|
|
PRECACHE_SOUND("tentacle/te_move1.wav");
|
|
|
|
PRECACHE_SOUND("tentacle/te_move2.wav");
|
|
|
|
PRECACHE_SOUND("tentacle/te_roar1.wav");
|
|
|
|
PRECACHE_SOUND("tentacle/te_roar2.wav");
|
|
|
|
PRECACHE_SOUND("tentacle/te_search1.wav");
|
|
|
|
PRECACHE_SOUND("tentacle/te_search2.wav");
|
|
|
|
PRECACHE_SOUND("tentacle/te_sing1.wav");
|
|
|
|
PRECACHE_SOUND("tentacle/te_sing2.wav");
|
|
|
|
PRECACHE_SOUND("tentacle/te_squirm2.wav");
|
|
|
|
PRECACHE_SOUND("tentacle/te_strike1.wav");
|
|
|
|
PRECACHE_SOUND("tentacle/te_strike2.wav");
|
|
|
|
PRECACHE_SOUND("tentacle/te_swing1.wav");
|
|
|
|
PRECACHE_SOUND("tentacle/te_swing2.wav");
|
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
PRECACHE_SOUND_ARRAY(pHitSilo);
|
|
|
|
PRECACHE_SOUND_ARRAY(pHitDirt);
|
|
|
|
PRECACHE_SOUND_ARRAY(pHitWater);
|
2013-08-30 13:34:05 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
CTentacle::CTentacle()
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
|
|
|
m_flMaxYaw = 65;
|
|
|
|
m_iTapSound = 0;
|
|
|
|
}
|
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
bool CTentacle::KeyValue(KeyValueData* pkvd)
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
|
|
|
if (FStrEq(pkvd->szKeyName, "sweeparc"))
|
|
|
|
{
|
|
|
|
m_flMaxYaw = atof(pkvd->szValue) / 2.0;
|
2021-11-28 15:32:26 +01:00
|
|
|
return true;
|
2013-08-30 13:34:05 -07:00
|
|
|
}
|
|
|
|
else if (FStrEq(pkvd->szKeyName, "sound"))
|
|
|
|
{
|
|
|
|
m_iTapSound = atoi(pkvd->szValue);
|
2021-11-28 15:32:26 +01:00
|
|
|
return true;
|
2013-08-30 13:34:05 -07:00
|
|
|
}
|
2021-11-28 15:32:26 +01:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
return CBaseMonster::KeyValue(pkvd);
|
2013-08-30 13:34:05 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-11-29 20:31:17 +01:00
|
|
|
int CTentacle::Level(float dz)
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
|
|
|
if (dz < 216)
|
|
|
|
return 0;
|
|
|
|
if (dz < 408)
|
|
|
|
return 1;
|
|
|
|
if (dz < 600)
|
|
|
|
return 2;
|
|
|
|
return 3;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-11-29 20:31:17 +01:00
|
|
|
float CTentacle::MyHeight()
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
2021-11-28 16:54:48 +01:00
|
|
|
switch (MyLevel())
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
return 256;
|
|
|
|
case 2:
|
|
|
|
return 448;
|
|
|
|
case 3:
|
|
|
|
return 640;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-11-29 20:31:17 +01:00
|
|
|
int CTentacle::MyLevel()
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
2021-11-28 16:54:48 +01:00
|
|
|
switch (pev->sequence)
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
2021-11-28 16:54:48 +01:00
|
|
|
case TENTACLE_ANIM_Pit_Idle:
|
2013-08-30 13:34:05 -07:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
case TENTACLE_ANIM_rise_to_Temp1:
|
|
|
|
case TENTACLE_ANIM_Temp1_to_Floor:
|
|
|
|
case TENTACLE_ANIM_Floor_to_Lev1:
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
case TENTACLE_ANIM_Floor_Idle:
|
|
|
|
case TENTACLE_ANIM_Floor_Fidget_Pissed:
|
|
|
|
case TENTACLE_ANIM_Floor_Fidget_SmallRise:
|
|
|
|
case TENTACLE_ANIM_Floor_Fidget_Wave:
|
|
|
|
case TENTACLE_ANIM_Floor_Strike:
|
|
|
|
case TENTACLE_ANIM_Floor_Tap:
|
|
|
|
case TENTACLE_ANIM_Floor_Rotate:
|
|
|
|
case TENTACLE_ANIM_Floor_Rear:
|
|
|
|
case TENTACLE_ANIM_Floor_Rear_Idle:
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
case TENTACLE_ANIM_Lev1_Idle:
|
|
|
|
case TENTACLE_ANIM_Lev1_Fidget_Claw:
|
|
|
|
case TENTACLE_ANIM_Lev1_Fidget_Shake:
|
|
|
|
case TENTACLE_ANIM_Lev1_Fidget_Snap:
|
|
|
|
case TENTACLE_ANIM_Lev1_Strike:
|
|
|
|
case TENTACLE_ANIM_Lev1_Tap:
|
|
|
|
case TENTACLE_ANIM_Lev1_Rotate:
|
|
|
|
case TENTACLE_ANIM_Lev1_Rear:
|
|
|
|
case TENTACLE_ANIM_Lev1_Rear_Idle:
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
case TENTACLE_ANIM_Lev1_to_Lev2:
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
case TENTACLE_ANIM_Lev2_Idle:
|
|
|
|
case TENTACLE_ANIM_Lev2_Fidget_Shake:
|
|
|
|
case TENTACLE_ANIM_Lev2_Fidget_Swing:
|
|
|
|
case TENTACLE_ANIM_Lev2_Fidget_Tut:
|
|
|
|
case TENTACLE_ANIM_Lev2_Strike:
|
|
|
|
case TENTACLE_ANIM_Lev2_Tap:
|
|
|
|
case TENTACLE_ANIM_Lev2_Rotate:
|
|
|
|
case TENTACLE_ANIM_Lev2_Rear:
|
|
|
|
case TENTACLE_ANIM_Lev2_Rear_Idle:
|
|
|
|
return 2;
|
|
|
|
|
|
|
|
case TENTACLE_ANIM_Lev2_to_Lev3:
|
|
|
|
return 2;
|
|
|
|
|
|
|
|
case TENTACLE_ANIM_Lev3_Idle:
|
|
|
|
case TENTACLE_ANIM_Lev3_Fidget_Shake:
|
|
|
|
case TENTACLE_ANIM_Lev3_Fidget_Side:
|
|
|
|
case TENTACLE_ANIM_Lev3_Fidget_Swipe:
|
|
|
|
case TENTACLE_ANIM_Lev3_Strike:
|
|
|
|
case TENTACLE_ANIM_Lev3_Tap:
|
|
|
|
case TENTACLE_ANIM_Lev3_Rotate:
|
|
|
|
case TENTACLE_ANIM_Lev3_Rear:
|
|
|
|
case TENTACLE_ANIM_Lev3_Rear_Idle:
|
|
|
|
return 3;
|
|
|
|
|
|
|
|
case TENTACLE_ANIM_Lev1_Door_reach:
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-11-29 20:31:17 +01:00
|
|
|
void CTentacle::Test()
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
|
|
|
pev->sequence = TENTACLE_ANIM_Floor_Strike;
|
|
|
|
pev->framerate = 0;
|
2021-11-28 16:54:48 +01:00
|
|
|
StudioFrameAdvance();
|
2013-08-30 13:34:05 -07:00
|
|
|
pev->nextthink = gpGlobals->time + 0.1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// TentacleThink
|
|
|
|
//
|
2021-11-29 20:31:17 +01:00
|
|
|
void CTentacle::Cycle()
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
|
|
|
// ALERT( at_console, "%s %.2f %d %d\n", STRING( pev->targetname ), pev->origin.z, m_MonsterState, m_IdealMonsterState );
|
2021-11-28 16:54:48 +01:00
|
|
|
pev->nextthink = gpGlobals->time + 0.1;
|
2013-08-30 13:34:05 -07:00
|
|
|
|
|
|
|
// ALERT( at_console, "%s %d %d %d %f %f\n", STRING( pev->targetname ), pev->sequence, m_iGoalAnim, m_iDir, pev->framerate, pev->health );
|
|
|
|
|
|
|
|
if (m_MonsterState == MONSTERSTATE_SCRIPT || m_IdealMonsterState == MONSTERSTATE_SCRIPT)
|
|
|
|
{
|
|
|
|
pev->angles.y = m_flInitialYaw;
|
2021-11-28 16:54:48 +01:00
|
|
|
pev->ideal_yaw = m_flInitialYaw;
|
|
|
|
ClearConditions(IgnoreConditions());
|
|
|
|
MonsterThink();
|
2013-08-30 13:34:05 -07:00
|
|
|
m_iGoalAnim = TENTACLE_ANIM_Pit_Idle;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
DispatchAnimEvents();
|
|
|
|
StudioFrameAdvance();
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
ChangeYaw(pev->yaw_speed);
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
CSound* pSound;
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
Listen();
|
2013-08-30 13:34:05 -07:00
|
|
|
|
|
|
|
// Listen will set this if there's something in my sound list
|
2021-11-28 16:54:48 +01:00
|
|
|
if (HasConditions(bits_COND_HEAR_SOUND))
|
2013-08-30 13:34:05 -07:00
|
|
|
pSound = PBestSound();
|
|
|
|
else
|
|
|
|
pSound = NULL;
|
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
if (pSound)
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
|
|
|
Vector vecDir;
|
|
|
|
if (gpGlobals->time - m_flPrevSoundTime < 0.5)
|
|
|
|
{
|
|
|
|
float dt = gpGlobals->time - m_flPrevSoundTime;
|
|
|
|
vecDir = pSound->m_vecOrigin + (pSound->m_vecOrigin - m_vecPrevSound) / dt - pev->origin;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
vecDir = pSound->m_vecOrigin - pev->origin;
|
|
|
|
}
|
|
|
|
m_flPrevSoundTime = gpGlobals->time;
|
|
|
|
m_vecPrevSound = pSound->m_vecOrigin;
|
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
m_flSoundYaw = UTIL_VecToYaw(vecDir) - m_flInitialYaw;
|
|
|
|
m_iSoundLevel = Level(vecDir.z);
|
2013-08-30 13:34:05 -07:00
|
|
|
|
|
|
|
if (m_flSoundYaw < -180)
|
|
|
|
m_flSoundYaw += 360;
|
|
|
|
if (m_flSoundYaw > 180)
|
|
|
|
m_flSoundYaw -= 360;
|
|
|
|
|
|
|
|
// ALERT( at_console, "sound %d %.0f\n", m_iSoundLevel, m_flSoundYaw );
|
|
|
|
if (m_flSoundTime < gpGlobals->time)
|
|
|
|
{
|
|
|
|
// play "I hear new something" sound
|
2021-11-28 16:54:48 +01:00
|
|
|
const char* sound;
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
switch (RANDOM_LONG(0, 1))
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
2021-11-28 16:54:48 +01:00
|
|
|
case 0:
|
|
|
|
sound = "tentacle/te_alert1.wav";
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
sound = "tentacle/te_alert2.wav";
|
|
|
|
break;
|
2013-08-30 13:34:05 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// UTIL_EmitAmbientSound(ENT(pev), pev->origin + Vector( 0, 0, MyHeight()), sound, 1.0, ATTN_NORM, 0, 100);
|
|
|
|
}
|
2021-11-28 16:54:48 +01:00
|
|
|
m_flSoundTime = gpGlobals->time + RANDOM_FLOAT(5.0, 10.0);
|
2013-08-30 13:34:05 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// clip ideal_yaw
|
|
|
|
float dy = m_flSoundYaw;
|
2021-11-28 16:54:48 +01:00
|
|
|
switch (pev->sequence)
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
|
|
|
case TENTACLE_ANIM_Floor_Rear:
|
|
|
|
case TENTACLE_ANIM_Floor_Rear_Idle:
|
|
|
|
case TENTACLE_ANIM_Lev1_Rear:
|
|
|
|
case TENTACLE_ANIM_Lev1_Rear_Idle:
|
|
|
|
case TENTACLE_ANIM_Lev2_Rear:
|
|
|
|
case TENTACLE_ANIM_Lev2_Rear_Idle:
|
|
|
|
case TENTACLE_ANIM_Lev3_Rear:
|
|
|
|
case TENTACLE_ANIM_Lev3_Rear_Idle:
|
|
|
|
if (dy < 0 && dy > -m_flMaxYaw)
|
|
|
|
dy = -m_flMaxYaw;
|
|
|
|
if (dy > 0 && dy < m_flMaxYaw)
|
|
|
|
dy = m_flMaxYaw;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
if (dy < -m_flMaxYaw)
|
|
|
|
dy = -m_flMaxYaw;
|
|
|
|
if (dy > m_flMaxYaw)
|
|
|
|
dy = m_flMaxYaw;
|
|
|
|
}
|
|
|
|
pev->ideal_yaw = m_flInitialYaw + dy;
|
|
|
|
|
|
|
|
if (m_fSequenceFinished)
|
|
|
|
{
|
|
|
|
// ALERT( at_console, "%s done %d %d\n", STRING( pev->targetname ), pev->sequence, m_iGoalAnim );
|
|
|
|
if (pev->health <= 1)
|
|
|
|
{
|
|
|
|
m_iGoalAnim = TENTACLE_ANIM_Pit_Idle;
|
|
|
|
if (pev->sequence == TENTACLE_ANIM_Pit_Idle)
|
|
|
|
{
|
|
|
|
pev->health = 75;
|
|
|
|
}
|
|
|
|
}
|
2021-11-28 16:54:48 +01:00
|
|
|
else if (m_flSoundTime > gpGlobals->time)
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
|
|
|
if (m_flSoundYaw >= -(m_flMaxYaw + 30) && m_flSoundYaw <= (m_flMaxYaw + 30))
|
|
|
|
{
|
|
|
|
// strike
|
2021-11-28 16:54:48 +01:00
|
|
|
m_iGoalAnim = LookupActivity(ACT_T_STRIKE + m_iSoundLevel);
|
2013-08-30 13:34:05 -07:00
|
|
|
}
|
2021-11-28 16:54:48 +01:00
|
|
|
else if (m_flSoundYaw >= -m_flMaxYaw * 2 && m_flSoundYaw <= m_flMaxYaw * 2)
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
|
|
|
// tap
|
2021-11-28 16:54:48 +01:00
|
|
|
m_iGoalAnim = LookupActivity(ACT_T_TAP + m_iSoundLevel);
|
2013-08-30 13:34:05 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// go into rear idle
|
2021-11-28 16:54:48 +01:00
|
|
|
m_iGoalAnim = LookupActivity(ACT_T_REARIDLE + m_iSoundLevel);
|
2013-08-30 13:34:05 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (pev->sequence == TENTACLE_ANIM_Pit_Idle)
|
|
|
|
{
|
|
|
|
// stay in pit until hear noise
|
|
|
|
m_iGoalAnim = TENTACLE_ANIM_Pit_Idle;
|
|
|
|
}
|
|
|
|
else if (pev->sequence == m_iGoalAnim)
|
|
|
|
{
|
|
|
|
if (MyLevel() >= 0 && gpGlobals->time < m_flSoundTime)
|
|
|
|
{
|
2021-11-28 16:54:48 +01:00
|
|
|
if (RANDOM_LONG(0, 9) < m_flSoundTime - gpGlobals->time)
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
|
|
|
// continue stike
|
2021-11-28 16:54:48 +01:00
|
|
|
m_iGoalAnim = LookupActivity(ACT_T_STRIKE + m_iSoundLevel);
|
2013-08-30 13:34:05 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// tap
|
2021-11-28 16:54:48 +01:00
|
|
|
m_iGoalAnim = LookupActivity(ACT_T_TAP + m_iSoundLevel);
|
2013-08-30 13:34:05 -07:00
|
|
|
}
|
|
|
|
}
|
2021-11-28 16:54:48 +01:00
|
|
|
else if (MyLevel() < 0)
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
2021-11-28 16:54:48 +01:00
|
|
|
m_iGoalAnim = LookupActivity(ACT_T_IDLE + 0);
|
2013-08-30 13:34:05 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (m_flNextSong < gpGlobals->time)
|
|
|
|
{
|
|
|
|
// play "I hear new something" sound
|
2021-11-28 16:54:48 +01:00
|
|
|
const char* sound;
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
switch (RANDOM_LONG(0, 1))
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
2021-11-28 16:54:48 +01:00
|
|
|
case 0:
|
|
|
|
sound = "tentacle/te_sing1.wav";
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
sound = "tentacle/te_sing2.wav";
|
|
|
|
break;
|
2013-08-30 13:34:05 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EMIT_SOUND(ENT(pev), CHAN_VOICE, sound, 1.0, ATTN_NORM);
|
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
m_flNextSong = gpGlobals->time + RANDOM_FLOAT(10, 20);
|
2013-08-30 13:34:05 -07:00
|
|
|
}
|
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
if (RANDOM_LONG(0, 15) == 0)
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
|
|
|
// idle on new level
|
2021-11-28 16:54:48 +01:00
|
|
|
m_iGoalAnim = LookupActivity(ACT_T_IDLE + RANDOM_LONG(0, 3));
|
2013-08-30 13:34:05 -07:00
|
|
|
}
|
2021-11-28 16:54:48 +01:00
|
|
|
else if (RANDOM_LONG(0, 3) == 0)
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
|
|
|
// tap
|
2021-11-28 16:54:48 +01:00
|
|
|
m_iGoalAnim = LookupActivity(ACT_T_TAP + MyLevel());
|
2013-08-30 13:34:05 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// idle
|
2021-11-28 16:54:48 +01:00
|
|
|
m_iGoalAnim = LookupActivity(ACT_T_IDLE + MyLevel());
|
2013-08-30 13:34:05 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (m_flSoundYaw < 0)
|
2021-11-28 16:54:48 +01:00
|
|
|
m_flSoundYaw += RANDOM_FLOAT(2, 8);
|
2013-08-30 13:34:05 -07:00
|
|
|
else
|
2021-11-28 16:54:48 +01:00
|
|
|
m_flSoundYaw -= RANDOM_FLOAT(2, 8);
|
2013-08-30 13:34:05 -07:00
|
|
|
}
|
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
pev->sequence = FindTransition(pev->sequence, m_iGoalAnim, &m_iDir);
|
2013-08-30 13:34:05 -07:00
|
|
|
|
|
|
|
if (m_iDir > 0)
|
|
|
|
{
|
|
|
|
pev->frame = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_iDir = -1; // just to safe
|
|
|
|
pev->frame = 255;
|
|
|
|
}
|
2021-11-28 16:54:48 +01:00
|
|
|
ResetSequenceInfo();
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
m_flFramerateAdj = RANDOM_FLOAT(-0.2, 0.2);
|
2013-08-30 13:34:05 -07:00
|
|
|
pev->framerate = m_iDir * 1.0 + m_flFramerateAdj;
|
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
switch (pev->sequence)
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
|
|
|
case TENTACLE_ANIM_Floor_Tap:
|
|
|
|
case TENTACLE_ANIM_Lev1_Tap:
|
|
|
|
case TENTACLE_ANIM_Lev2_Tap:
|
2021-11-29 20:55:01 +01:00
|
|
|
case TENTACLE_ANIM_Lev3_Tap:
|
|
|
|
{
|
2021-11-28 16:54:48 +01:00
|
|
|
Vector vecSrc;
|
|
|
|
UTIL_MakeVectors(pev->angles);
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
TraceResult tr1, tr2;
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
vecSrc = pev->origin + Vector(0, 0, MyHeight() - 4);
|
|
|
|
UTIL_TraceLine(vecSrc, vecSrc + gpGlobals->v_forward * 512, ignore_monsters, ENT(pev), &tr1);
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
vecSrc = pev->origin + Vector(0, 0, MyHeight() + 8);
|
|
|
|
UTIL_TraceLine(vecSrc, vecSrc + gpGlobals->v_forward * 512, ignore_monsters, ENT(pev), &tr2);
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
// ALERT( at_console, "%f %f\n", tr1.flFraction * 512, tr2.flFraction * 512 );
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
m_flTapRadius = SetBlending(0, RANDOM_FLOAT(tr1.flFraction * 512, tr2.flFraction * 512));
|
|
|
|
}
|
|
|
|
break;
|
2013-08-30 13:34:05 -07:00
|
|
|
default:
|
|
|
|
m_flTapRadius = 336; // 400 - 64
|
|
|
|
break;
|
|
|
|
}
|
2021-11-28 16:54:48 +01:00
|
|
|
pev->view_ofs.z = MyHeight();
|
2013-08-30 13:34:05 -07:00
|
|
|
// ALERT( at_console, "seq %d\n", pev->sequence );
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m_flPrevSoundTime + 2.0 > gpGlobals->time)
|
|
|
|
{
|
|
|
|
// 1.5 normal speed if hears sounds
|
|
|
|
pev->framerate = m_iDir * 1.5 + m_flFramerateAdj;
|
|
|
|
}
|
|
|
|
else if (m_flPrevSoundTime + 5.0 > gpGlobals->time)
|
|
|
|
{
|
|
|
|
// slowdown to normal
|
|
|
|
pev->framerate = m_iDir + m_iDir * (5 - (gpGlobals->time - m_flPrevSoundTime)) / 2 + m_flFramerateAdj;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
void CTentacle::CommandUse(CBaseEntity* pActivator, CBaseEntity* pCaller, USE_TYPE useType, float value)
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
2021-11-28 16:54:48 +01:00
|
|
|
// ALERT( at_console, "%s triggered %d\n", STRING( pev->targetname ), useType );
|
|
|
|
switch (useType)
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
|
|
|
case USE_OFF:
|
|
|
|
pev->takedamage = DAMAGE_NO;
|
2021-11-28 16:54:48 +01:00
|
|
|
SetThink(&CTentacle::DieThink);
|
2013-08-30 13:34:05 -07:00
|
|
|
m_iGoalAnim = TENTACLE_ANIM_Engine_Death1;
|
|
|
|
break;
|
|
|
|
case USE_ON:
|
|
|
|
if (pActivator)
|
|
|
|
{
|
|
|
|
// ALERT( at_console, "insert sound\n");
|
2021-11-28 16:54:48 +01:00
|
|
|
CSoundEnt::InsertSound(bits_SOUND_WORLD, pActivator->pev->origin, 1024, 1.0);
|
2013-08-30 13:34:05 -07:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case USE_SET:
|
|
|
|
break;
|
|
|
|
case USE_TOGGLE:
|
|
|
|
pev->takedamage = DAMAGE_NO;
|
2021-11-28 16:54:48 +01:00
|
|
|
SetThink(&CTentacle::DieThink);
|
2013-08-30 13:34:05 -07:00
|
|
|
m_iGoalAnim = TENTACLE_ANIM_Engine_Idle;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-11-29 20:31:17 +01:00
|
|
|
void CTentacle::DieThink()
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
2021-11-28 16:54:48 +01:00
|
|
|
pev->nextthink = gpGlobals->time + 0.1;
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
DispatchAnimEvents();
|
|
|
|
StudioFrameAdvance();
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
ChangeYaw(24);
|
2013-08-30 13:34:05 -07:00
|
|
|
|
|
|
|
if (m_fSequenceFinished)
|
|
|
|
{
|
|
|
|
if (pev->sequence == m_iGoalAnim)
|
|
|
|
{
|
2021-11-28 16:54:48 +01:00
|
|
|
switch (m_iGoalAnim)
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
|
|
|
case TENTACLE_ANIM_Engine_Idle:
|
|
|
|
case TENTACLE_ANIM_Engine_Sway:
|
|
|
|
case TENTACLE_ANIM_Engine_Swat:
|
|
|
|
case TENTACLE_ANIM_Engine_Bob:
|
2021-11-28 16:54:48 +01:00
|
|
|
m_iGoalAnim = TENTACLE_ANIM_Engine_Sway + RANDOM_LONG(0, 2);
|
2013-08-30 13:34:05 -07:00
|
|
|
break;
|
|
|
|
case TENTACLE_ANIM_Engine_Death1:
|
|
|
|
case TENTACLE_ANIM_Engine_Death2:
|
|
|
|
case TENTACLE_ANIM_Engine_Death3:
|
2021-11-28 16:54:48 +01:00
|
|
|
UTIL_Remove(this);
|
2013-08-30 13:34:05 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ALERT( at_console, "%d : %d => ", pev->sequence, m_iGoalAnim );
|
2021-11-28 16:54:48 +01:00
|
|
|
pev->sequence = FindTransition(pev->sequence, m_iGoalAnim, &m_iDir);
|
2013-08-30 13:34:05 -07:00
|
|
|
// ALERT( at_console, "%d\n", pev->sequence );
|
|
|
|
|
|
|
|
if (m_iDir > 0)
|
|
|
|
{
|
|
|
|
pev->frame = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pev->frame = 255;
|
|
|
|
}
|
2021-11-28 16:54:48 +01:00
|
|
|
ResetSequenceInfo();
|
2013-08-30 13:34:05 -07:00
|
|
|
|
|
|
|
float dy;
|
2021-11-28 16:54:48 +01:00
|
|
|
switch (pev->sequence)
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
|
|
|
case TENTACLE_ANIM_Floor_Rear:
|
|
|
|
case TENTACLE_ANIM_Floor_Rear_Idle:
|
|
|
|
case TENTACLE_ANIM_Lev1_Rear:
|
|
|
|
case TENTACLE_ANIM_Lev1_Rear_Idle:
|
|
|
|
case TENTACLE_ANIM_Lev2_Rear:
|
|
|
|
case TENTACLE_ANIM_Lev2_Rear_Idle:
|
|
|
|
case TENTACLE_ANIM_Lev3_Rear:
|
|
|
|
case TENTACLE_ANIM_Lev3_Rear_Idle:
|
|
|
|
case TENTACLE_ANIM_Engine_Idle:
|
|
|
|
case TENTACLE_ANIM_Engine_Sway:
|
|
|
|
case TENTACLE_ANIM_Engine_Swat:
|
|
|
|
case TENTACLE_ANIM_Engine_Bob:
|
|
|
|
case TENTACLE_ANIM_Engine_Death1:
|
|
|
|
case TENTACLE_ANIM_Engine_Death2:
|
|
|
|
case TENTACLE_ANIM_Engine_Death3:
|
2021-11-28 16:54:48 +01:00
|
|
|
pev->framerate = RANDOM_FLOAT(m_iDir - 0.2, m_iDir + 0.2);
|
2013-08-30 13:34:05 -07:00
|
|
|
dy = 180;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
pev->framerate = 1.5;
|
|
|
|
dy = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
pev->ideal_yaw = m_flInitialYaw + dy;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-11-29 20:31:17 +01:00
|
|
|
void CTentacle::HandleAnimEvent(MonsterEvent_t* pEvent)
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
2021-11-28 16:54:48 +01:00
|
|
|
const char* sound;
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
switch (pEvent->event)
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
2021-11-28 16:54:48 +01:00
|
|
|
case 1: // bang
|
|
|
|
{
|
|
|
|
Vector vecSrc, vecAngles;
|
|
|
|
GetAttachment(0, vecSrc, vecAngles);
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
// Vector vecSrc = pev->origin + m_flTapRadius * Vector( cos( pev->angles.y * (3.14192653 / 180.0) ), sin( pev->angles.y * (M_PI / 180.0) ), 0.0 );
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
// vecSrc.z += MyHeight( );
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
switch (m_iTapSound)
|
|
|
|
{
|
|
|
|
case TE_SILO:
|
|
|
|
UTIL_EmitAmbientSound(ENT(pev), vecSrc, RANDOM_SOUND_ARRAY(pHitSilo), 1.0, ATTN_NORM, 0, 100);
|
|
|
|
break;
|
|
|
|
case TE_NONE:
|
|
|
|
break;
|
|
|
|
case TE_DIRT:
|
|
|
|
UTIL_EmitAmbientSound(ENT(pev), vecSrc, RANDOM_SOUND_ARRAY(pHitDirt), 1.0, ATTN_NORM, 0, 100);
|
|
|
|
break;
|
|
|
|
case TE_WATER:
|
|
|
|
UTIL_EmitAmbientSound(ENT(pev), vecSrc, RANDOM_SOUND_ARRAY(pHitWater), 1.0, ATTN_NORM, 0, 100);
|
|
|
|
break;
|
2013-08-30 13:34:05 -07:00
|
|
|
}
|
2021-11-28 16:54:48 +01:00
|
|
|
gpGlobals->force_retouch++;
|
|
|
|
}
|
|
|
|
break;
|
2013-08-30 13:34:05 -07:00
|
|
|
|
|
|
|
case 3: // start killing swing
|
|
|
|
m_iHitDmg = 200;
|
|
|
|
// UTIL_EmitAmbientSound(ENT(pev), pev->origin + Vector( 0, 0, MyHeight()), "tentacle/te_swing1.wav", 1.0, ATTN_NORM, 0, 100);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 4: // end killing swing
|
|
|
|
m_iHitDmg = 25;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 5: // just "whoosh" sound
|
|
|
|
// UTIL_EmitAmbientSound(ENT(pev), pev->origin + Vector( 0, 0, MyHeight()), "tentacle/te_swing2.wav", 1.0, ATTN_NORM, 0, 100);
|
|
|
|
break;
|
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
case 2: // tap scrape
|
2013-08-30 13:34:05 -07:00
|
|
|
case 6: // light tap
|
2021-11-28 16:54:48 +01:00
|
|
|
{
|
|
|
|
Vector vecSrc = pev->origin + m_flTapRadius * Vector(cos(pev->angles.y * (M_PI / 180.0)), sin(pev->angles.y * (M_PI / 180.0)), 0.0);
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
vecSrc.z += MyHeight();
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
float flVol = RANDOM_FLOAT(0.3, 0.5);
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
switch (m_iTapSound)
|
|
|
|
{
|
|
|
|
case TE_SILO:
|
|
|
|
UTIL_EmitAmbientSound(ENT(pev), vecSrc, RANDOM_SOUND_ARRAY(pHitSilo), flVol, ATTN_NORM, 0, 100);
|
|
|
|
break;
|
|
|
|
case TE_NONE:
|
|
|
|
break;
|
|
|
|
case TE_DIRT:
|
|
|
|
UTIL_EmitAmbientSound(ENT(pev), vecSrc, RANDOM_SOUND_ARRAY(pHitDirt), flVol, ATTN_NORM, 0, 100);
|
|
|
|
break;
|
|
|
|
case TE_WATER:
|
|
|
|
UTIL_EmitAmbientSound(ENT(pev), vecSrc, RANDOM_SOUND_ARRAY(pHitWater), flVol, ATTN_NORM, 0, 100);
|
|
|
|
break;
|
2013-08-30 13:34:05 -07:00
|
|
|
}
|
2021-11-28 16:54:48 +01:00
|
|
|
}
|
|
|
|
break;
|
2013-08-30 13:34:05 -07:00
|
|
|
|
|
|
|
|
|
|
|
case 7: // roar
|
2021-11-28 16:54:48 +01:00
|
|
|
switch (RANDOM_LONG(0, 1))
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
2021-11-29 20:05:47 +01:00
|
|
|
default:
|
2021-11-28 16:54:48 +01:00
|
|
|
case 0:
|
|
|
|
sound = "tentacle/te_roar1.wav";
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
sound = "tentacle/te_roar2.wav";
|
|
|
|
break;
|
2013-08-30 13:34:05 -07:00
|
|
|
}
|
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
UTIL_EmitAmbientSound(ENT(pev), pev->origin + Vector(0, 0, MyHeight()), sound, 1.0, ATTN_NORM, 0, 100);
|
2013-08-30 13:34:05 -07:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 8: // search
|
2021-11-28 16:54:48 +01:00
|
|
|
switch (RANDOM_LONG(0, 1))
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
2021-11-29 20:05:47 +01:00
|
|
|
default:
|
2021-11-28 16:54:48 +01:00
|
|
|
case 0:
|
|
|
|
sound = "tentacle/te_search1.wav";
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
sound = "tentacle/te_search2.wav";
|
|
|
|
break;
|
2013-08-30 13:34:05 -07:00
|
|
|
}
|
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
UTIL_EmitAmbientSound(ENT(pev), pev->origin + Vector(0, 0, MyHeight()), sound, 1.0, ATTN_NORM, 0, 100);
|
2013-08-30 13:34:05 -07:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 9: // swing
|
2021-11-28 16:54:48 +01:00
|
|
|
switch (RANDOM_LONG(0, 1))
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
2021-11-29 20:05:47 +01:00
|
|
|
default:
|
2021-11-28 16:54:48 +01:00
|
|
|
case 0:
|
|
|
|
sound = "tentacle/te_move1.wav";
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
sound = "tentacle/te_move2.wav";
|
|
|
|
break;
|
2013-08-30 13:34:05 -07:00
|
|
|
}
|
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
UTIL_EmitAmbientSound(ENT(pev), pev->origin + Vector(0, 0, MyHeight()), sound, 1.0, ATTN_NORM, 0, 100);
|
2013-08-30 13:34:05 -07:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2021-11-28 16:54:48 +01:00
|
|
|
CBaseMonster::HandleAnimEvent(pEvent);
|
2013-08-30 13:34:05 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// TentacleStart
|
|
|
|
//
|
2021-11-29 20:31:17 +01:00
|
|
|
// void CTentacle:: Start( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
|
|
|
|
void CTentacle::Start()
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
2021-11-28 16:54:48 +01:00
|
|
|
SetThink(&CTentacle::Cycle);
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
if (!g_fFlySound)
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
2021-11-28 16:54:48 +01:00
|
|
|
EMIT_SOUND(ENT(pev), CHAN_BODY, "ambience/flies.wav", 1, ATTN_NORM);
|
2021-11-19 13:45:16 +01:00
|
|
|
g_fFlySound = true;
|
2021-11-28 16:54:48 +01:00
|
|
|
// pev->nextthink = gpGlobals-> time + 0.1;
|
2013-08-30 13:34:05 -07:00
|
|
|
}
|
2021-11-28 16:54:48 +01:00
|
|
|
else if (!g_fSquirmSound)
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
2021-11-28 16:54:48 +01:00
|
|
|
EMIT_SOUND(ENT(pev), CHAN_BODY, "ambience/squirm2.wav", 1, ATTN_NORM);
|
2021-11-19 13:45:16 +01:00
|
|
|
g_fSquirmSound = true;
|
2013-08-30 13:34:05 -07:00
|
|
|
}
|
2021-11-28 16:54:48 +01:00
|
|
|
|
2013-08-30 13:34:05 -07:00
|
|
|
pev->nextthink = gpGlobals->time + 0.1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-11-29 20:31:17 +01:00
|
|
|
void CTentacle::HitTouch(CBaseEntity* pOther)
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
2021-11-28 16:54:48 +01:00
|
|
|
TraceResult tr = UTIL_GetGlobalTrace();
|
2013-08-30 13:34:05 -07:00
|
|
|
|
|
|
|
if (pOther->pev->modelindex == pev->modelindex)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (m_flHitTime > gpGlobals->time)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// only look at the ones where the player hit me
|
|
|
|
if (tr.pHit == NULL || tr.pHit->v.modelindex != pev->modelindex)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (tr.iHitgroup >= 3)
|
|
|
|
{
|
2021-11-28 16:54:48 +01:00
|
|
|
pOther->TakeDamage(pev, pev, m_iHitDmg, DMG_CRUSH);
|
2013-08-30 13:34:05 -07:00
|
|
|
// ALERT( at_console, "wack %3d : ", m_iHitDmg );
|
|
|
|
}
|
|
|
|
else if (tr.iHitgroup != 0)
|
|
|
|
{
|
2021-11-28 16:54:48 +01:00
|
|
|
pOther->TakeDamage(pev, pev, 20, DMG_CRUSH);
|
2013-08-30 13:34:05 -07:00
|
|
|
// ALERT( at_console, "tap %3d : ", 20 );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return; // Huh?
|
|
|
|
}
|
|
|
|
|
|
|
|
m_flHitTime = gpGlobals->time + 0.5;
|
|
|
|
|
|
|
|
// ALERT( at_console, "%s : ", STRING( tr.pHit->v.classname ) );
|
|
|
|
|
|
|
|
// ALERT( at_console, "%.0f : %s : %d\n", pev->angles.y, STRING( pOther->pev->classname ), tr.iHitgroup );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
bool CTentacle::TakeDamage(entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType)
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
|
|
|
if (flDamage > pev->health)
|
|
|
|
{
|
|
|
|
pev->health = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pev->health -= flDamage;
|
|
|
|
}
|
2021-11-28 15:32:26 +01:00
|
|
|
return true;
|
2013-08-30 13:34:05 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-11-29 20:31:17 +01:00
|
|
|
void CTentacle::Killed(entvars_t* pevAttacker, int iGib)
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
|
|
|
m_iGoalAnim = TENTACLE_ANIM_Pit_Idle;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class CTentacleMaw : public CBaseMonster
|
|
|
|
{
|
|
|
|
public:
|
2021-11-28 16:54:48 +01:00
|
|
|
void Spawn() override;
|
|
|
|
void Precache() override;
|
2013-08-30 13:34:05 -07:00
|
|
|
};
|
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
LINK_ENTITY_TO_CLASS(monster_tentaclemaw, CTentacleMaw);
|
2013-08-30 13:34:05 -07:00
|
|
|
|
|
|
|
//
|
|
|
|
// Tentacle Spawn
|
|
|
|
//
|
2021-11-29 20:31:17 +01:00
|
|
|
void CTentacleMaw::Spawn()
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
2021-11-28 16:54:48 +01:00
|
|
|
Precache();
|
2013-08-30 13:34:05 -07:00
|
|
|
SET_MODEL(ENT(pev), "models/maw.mdl");
|
|
|
|
UTIL_SetSize(pev, Vector(-32, -32, 0), Vector(32, 32, 64));
|
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
pev->solid = SOLID_NOT;
|
|
|
|
pev->movetype = MOVETYPE_STEP;
|
|
|
|
pev->effects = 0;
|
|
|
|
pev->health = 75;
|
|
|
|
pev->yaw_speed = 8;
|
|
|
|
pev->sequence = 0;
|
|
|
|
|
|
|
|
pev->angles.x = 90;
|
2013-08-30 13:34:05 -07:00
|
|
|
// ResetSequenceInfo( );
|
|
|
|
}
|
|
|
|
|
2021-11-29 20:31:17 +01:00
|
|
|
void CTentacleMaw::Precache()
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
|
|
|
PRECACHE_MODEL("models/maw.mdl");
|
|
|
|
}
|