Files
HL2Overcharged/game/server/overcharged/npc_sporegenerator.cpp
2025-05-21 21:20:08 +03:00

336 lines
9.1 KiB
C++

//========= Copyright © 2019 Overcharged ============//
//
// Purpose: op4 spore generation entity
//
//
// Îñíîâíàÿ ëîãèêà âîññîçäàíà, ÷òî îñòàëîñü:
// 1)Ñäåëàòü óñëîâèå åñëè ó èãðîêà ïîëíûé áîåçàïàñ ñïîð òî âîçâðàùàåì (return) ôóíêöèþ touch ÷òîáû ìîäåëü ñïîðû íå ðåàãèðîâàëà
// 2)Ïðè ïîïàäàíèè â ìîäåëü ñïîðû ÷òîáû ñïàâíèëàñü ðåàëüíàÿ åíòèòÿ ñïîðû è âûëåòàëà îò àòòà÷ìåíòà 'spore' âïåð¸ä îò ìîäåëè
// ïðè ýòîì âûçûâàÿ ñòàíäàðòíóþ ôóíêöèþ touch (îíà óæå óáåð¸ò áîäèãðóïïó è ïðîèãðàåò àíèìàöèþ)
// 3)Âïèñàòü íîâûé àììîòèï â ôóíêöèè touch()
//
// Âñå çàìåòêè ïîìå÷åíû òåãîì OVER
//
// ATTACHMENT 'spore'
//=============================================================================//
#include "cbase.h"
#include "ai_hull.h"
#include "ai_basenpc.h"
#include "ai_default.h"
#include "ai_schedule.h"
#include "ai_motor.h"
#include "ai_memory.h"
#include "ai_route.h"
#include "ai_task.h"
#include "npcevent.h"
#include "bitstring.h"
#include "eventqueue.h"
#include "engine/IEngineSound.h"
#include "soundent.h"
#include "npcevent.h"
#include "game.h"
#include "soundenvelope.h"
#include "hl2_gamerules.h"
#include "ammodef.h"
#include "npc_playercompanion.h"
#include "tier0/memdbgon.h"
#include "grenade_bullsquid.h"
#include "grenade_frag.h"
#include "grenade_strooper_instant.h"
ConVar oc_sporegenerator_regenerate_delay("oc_sporegenerator_regenerate_delay", "0.5", FCVAR_REPLICATED, "Spore generator regenerate delay.");
ConVar oc_sporegenerator_projectile_impulse("oc_sporegenerator_projectile_impulse", "20.0", FCVAR_ARCHIVE);
class CSporeGenerator : public CAI_BaseNPC//CNPC_PlayerCompanion//CNPC_PlayerCompanion
{
DECLARE_CLASS(CSporeGenerator, CAI_BaseNPC);
public:
DECLARE_DATADESC();
virtual Class_T Classify();
void Spawn(void);
void Precache(void);
void Touch(CBaseEntity *pOther);
void Think(void);
void SpitOut(void);
virtual int OnTakeDamage(const CTakeDamageInfo &info);
void SporePick(void);
void SporeReGenerate(void);
void MyTouch(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value);
void TraceAttack(const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator);
float m_flDmgTime;
float Time;
int bodygroup1;
int activity;
CSporeLauncherBouncedProjectile *Sphere; // Null
};
LINK_ENTITY_TO_CLASS(npc_sporegenerator, CSporeGenerator); // BriJee: Spore generator link
BEGIN_DATADESC(CSporeGenerator)
DEFINE_FIELD(m_flDmgTime, FIELD_FLOAT),
DEFINE_FIELD(bodygroup1, FIELD_INTEGER),
DEFINE_FIELD(activity, FIELD_INTEGER),
DEFINE_FIELD(Time, FIELD_FLOAT),
DEFINE_THINKFUNC(Think),
DEFINE_USEFUNC(MyTouch),
DEFINE_ENTITYFUNC(Touch),
END_DATADESC()
Class_T CSporeGenerator::Classify()
{
return CLASS_NONE;
}
void CSporeGenerator::Spawn(void)
{
Precache();
//======= BriJee: Different models & anims
if (random->RandomInt(0, 3) == 3)
{
SetModel("models/RaceX/spore_generator_up.mdl");
}
else
{
SetModel("models/RaceX/spore_generator.mdl");
}
//=====end
SetBodygroup(1, 1); // spore bodygroup enable by default
bodygroup1 = GetBodygroup(1);
SetMoveType(MOVETYPE_NONE);
SetSolid(SOLID_BBOX); // full physics model. old _BBOX
//AddSolidFlags(FSOLID_TRIGGER | FSOLID_NOT_SOLID); // BriJee: unused no collision
Time = cvar->FindVar("oc_sporegenerator_regenerate_delay")->GetFloat();
SetHullType(HULL_TINY);
SetHullSizeSmall();
SetBloodColor(BLOOD_COLOR_YELLOW);
NPCInit();
m_takedamage = DAMAGE_EVENTS_ONLY;
SetUse(&CSporeGenerator::MyTouch);
SetTouch(&CSporeGenerator::Touch);
SetThink(&CSporeGenerator::Think);
UTIL_SetSize(this, Vector(-10, -10, -10), Vector(10, 10, 10));
SetActivity(ACT_IDLE);
activity = ACT_IDLE;
SetNextThink(gpGlobals->curtime + 0.1);
SetCycle(random->RandomFloat(0, 1));
}
void CSporeGenerator::Precache(void)
{
PrecacheModel("models/RaceX/spore_generator.mdl");
PrecacheModel("models/RaceX/spore_generator_up.mdl");
PrecacheScriptSound("SporeGenerator.PickSpore");
}
void CSporeGenerator::TraceAttack(const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator)
{
/*if (GetActivity() == ACT_IDLE && GetBodygroup(1) == 1)
SpitOut();*/
BaseClass::TraceAttack(info, vecDir, ptr, pAccumulator);
}
int CSporeGenerator::OnTakeDamage(const CTakeDamageInfo &info)
{
if (GetActivity() == ACT_IDLE && GetBodygroup(1) == 1)
SpitOut();
return 0;
}
void CSporeGenerator::Think(void)
{
StudioFrameAdvance();
SetNextThink(gpGlobals->curtime + 0.1);
/*if (GetActivity() == 0)//LOAD game fix
{
SetActivity((Activity)activity);
}
if (GetActivity() == ACT_CROUCH)
{
if (IsSequenceFinished())
{
activity = ACT_CROUCHIDLE;
SetActivity((Activity)activity);
SporeReGenerate();
m_flDmgTime = gpGlobals->curtime + (SequenceDuration()*Time);
}
}
else if (GetActivity() == ACT_CROUCHIDLE)
{
if (m_flDmgTime <= gpGlobals->curtime)//(gpGlobals->curtime > m_flDmgTime)
{
SporePick();
}
}
else if (GetActivity() == ACT_STAND)
{
if (IsSequenceFinished())
{
activity = ACT_IDLE;
SetActivity((Activity)activity);
}
}*/
switch (GetActivity())
{
case ACT_RESET:
{
SetActivity((Activity)activity);
}
break;
case ACT_CROUCH:
if (IsSequenceFinished())
{
activity = ACT_CROUCHIDLE;
SetActivity((Activity)activity);
SporeReGenerate();
m_flDmgTime = gpGlobals->curtime + (SequenceDuration()*Time);
}
break;
case ACT_CROUCHIDLE:
{
if (m_flDmgTime <= gpGlobals->curtime)//(gpGlobals->curtime > m_flDmgTime)
{
SporePick();
}
}
break;
case ACT_STAND:
if (IsSequenceFinished())
{
activity = ACT_IDLE;
SetActivity((Activity)activity);
}
break;
default:
break;
}
}
void CSporeGenerator::MyTouch(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value)
{
Touch(pActivator);
}
void CSporeGenerator::Touch(CBaseEntity *pOther)
{
// OVER Åñëè ó èãðîêà ïîëíûé áîåçàïàñ ñïîð (ïðîâåðÿåì ïî àììîòèïó) òî return;
// òðîãàòü åíòèòþ ïðè ýòîì íå íóæíî ÷òîáû íå âûçûâàòü ïîñëåäóþùèå ôóíêöèè
//DevMsg("Player stand on spore \n");
if (pOther->IsPlayer())
{
if (pOther->MyCombatCharacterPointer()->GetAmmoCount("SporeAcid") == GetAmmoDef()->MaxCarry(GetAmmoDef()->Index("SporeAcid")))
return;
//m_flDmgTime = gpGlobals->curtime + cvar->FindVar("sk_sporegenerator_regenerate_delay")->GetInt(); // BriJee: 7 seconds to refill spore
if (GetActivity() == ACT_IDLE || GetActivity() == ACT_STAND)
{
bodygroup1 = 0;
SetBodygroup(1, bodygroup1); //disable spore bg
activity = ACT_CROUCH;
SetActivity((Activity)activity);
pOther->MyCombatCharacterPointer()->GiveAmmo(1, "SporeAcid", false);
// OVER Òóò äà¸ì èãðîêó 1 ñíàðÿä ñïîðû, âìåñòî "Pistol" âïèñàòü íîâîå íàçâàíèå
//CBasePlayer *pPlayer;
//pPlayer = (CBasePlayer *)pOther;
//pPlayer->GiveAmmo(1, "Pistol", false); // 1 ñïîðà, "àììîòèï ñïîðû", èêîíêà ñïðàâà ïðè ïîäáîðå
}
return;
}
}
void CSporeGenerator::SpitOut(void)
{
bodygroup1 = 0;
SetBodygroup(1, bodygroup1); //disable spore bg
activity = ACT_CROUCH;
SetActivity((Activity)activity);
Vector start, out;
QAngle ang;
GetAttachment("spore", start, ang);
Vector start2 = GetAbsOrigin();
start2.x += 200;
/*Sphere = CSporeLauncherBouncedProjectile::SporeCreate(GetAbsOrigin(), ang, 0, this, start);
Sphere->SetModelScale(1);*/
CBaseEntity *pGren = NULL;
pGren = CBaseEntity::Create("spore_launcher_bounced_projectile", start, ang); // Creates
pGren->PrecacheModel("models/spitball_medium.mdl");
pGren->SetModel("models/spitball_medium.mdl");
pGren->SetMoveType(MOVETYPE_VPHYSICS);
Vector res, vel;
/*if (abs(start.x) > abs(GetAbsOrigin().x))
{
if (start.x < 0 && GetAbsOrigin().x > 0)
res.x = start.x - GetAbsOrigin().x;
else if (start.x > 0 && GetAbsOrigin().x < 0)
res.x = start.x - GetAbsOrigin().x;
else if (start.x > 0 && GetAbsOrigin().x > 0)
res.x = start.x - GetAbsOrigin().x;
else if (start.x == 0 || GetAbsOrigin().x == 0)
res.x = start.x - GetAbsOrigin().x;
else if (start.x == 0 && GetAbsOrigin().x == 0)
res.x = start.x - GetAbsOrigin().x;
}
else if (start.x < GetAbsOrigin().x)
{
}*/
res.x = start.x - GetAbsOrigin().x;
res.y = start.y - GetAbsOrigin().y;
res.z = start.z - GetAbsOrigin().z;
/*res.x = start.x > GetAbsOrigin().x ? start.x - GetAbsOrigin().x : GetAbsOrigin().x - start.x;
res.y = start.y > GetAbsOrigin().y ? start.y - GetAbsOrigin().y : GetAbsOrigin().y - start.y;
res.z = start.z > GetAbsOrigin().z ? start.z - GetAbsOrigin().z : GetAbsOrigin().z - start.z;*/
vel = res * cvar->FindVar("oc_sporegenerator_projectile_impulse")->GetFloat();
pGren->SetAbsVelocity(vel);
pGren->SetDamage(cvar->FindVar("sk_npc_dmg_spore_acid_bounce")->GetFloat());
pGren->Spawn();
}
void CSporeGenerator::SporePick(void)
{
bodygroup1 = 1;
SetBodygroup(1, bodygroup1); //enable spore bg
activity = ACT_STAND;
SetActivity((Activity)activity);
variant_t Value;
g_EventQueue.AddEvent(STRING(m_target), "TurnOn", Value, 0, this, this);
}
void CSporeGenerator::SporeReGenerate(void)
{
variant_t Value;
g_EventQueue.AddEvent(STRING(m_target), "TurnOff", Value, 0, this, this);
CPASAttenuationFilter filter(this); // BriJee: Pick up spore sound // closed // after pick up
EmitSound(filter, entindex(), "SporeGenerator.PickSpore");
}