mirror of
https://github.com/Gigaslav/HL2Overcharged.git
synced 2026-01-13 18:09:51 +03:00
2230 lines
55 KiB
C++
2230 lines
55 KiB
C++
//========= Copyright Msalinas2877, All rights reserved. ======================//
|
|
//
|
|
// Purpose: MapAdd Script System
|
|
//
|
|
//=============================================================================//
|
|
#include "cbase.h"
|
|
#include "map_parser.h"
|
|
#include "filesystem.h"
|
|
#include "ai_baseactor.h"
|
|
#include "ai_network.h"
|
|
#include "ai_node.h"
|
|
#include "ai_hint.h"
|
|
#include "UtlSortVector.h"
|
|
#include "smod_nodelistparser.h"
|
|
#include "lights.h"
|
|
#include "lua_mapadd.h"
|
|
#include "mapadd.h"
|
|
|
|
#include "triggers.h"
|
|
|
|
#include <iostream>
|
|
#include <fstream>
|
|
#define DEBUG_MSG FALSE // Change this to "TRUE" to show Debug Info on Release Mode
|
|
|
|
#if DEBUG_MSG || DEBUG
|
|
#define DebugColorMsg(msg) ConColorMsg(Color(124, 252, 0, 255), msg)
|
|
#else
|
|
#define DebugColorMsg(msg)
|
|
#endif
|
|
|
|
ConVar disable_loadmapadd("disable_loadmapadd", "0");
|
|
|
|
|
|
class CSortedMapAddEntList
|
|
{
|
|
public:
|
|
CSortedMapAddEntList() : m_sortedList(), m_emptyCount(0) {}
|
|
|
|
typedef CBaseEntity *ENTITYPTR;
|
|
class CEntityReportLess
|
|
{
|
|
public:
|
|
bool Less(const ENTITYPTR &src1, const ENTITYPTR &src2, void *pCtx)
|
|
{
|
|
if (stricmp(src1->GetClassname(), src2->GetClassname()) < 0)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
};
|
|
|
|
void AddEntityToList(CBaseEntity *pEntity)
|
|
{
|
|
if (!pEntity)
|
|
{
|
|
m_emptyCount++;
|
|
}
|
|
else
|
|
{
|
|
m_sortedList.Insert(pEntity);
|
|
}
|
|
}
|
|
void ParseEntites()
|
|
{
|
|
bool bSuccess = false;
|
|
|
|
KeyValues *kvEnts = NULL;
|
|
//KeyValues *kvTrigs = NULL;
|
|
|
|
const char *pLastClass = "";
|
|
int count = 0;
|
|
int edicts = 0;
|
|
for (int i = 0; i < m_sortedList.Count(); i++)
|
|
{
|
|
CBaseEntity *pEntity = m_sortedList[i];
|
|
if (!pEntity)
|
|
continue;
|
|
else if (pEntity->GetOwnerEntity() && pEntity->GetOwnerEntity()->IsPlayer())
|
|
continue;
|
|
if (pEntity->edict())
|
|
edicts++;
|
|
|
|
const char *pClassname = pEntity->GetClassname();
|
|
if (!FStrEq(pClassname, pLastClass))
|
|
{
|
|
if (count)
|
|
{
|
|
ConColorMsg(Color(0, 0, 255, 255), "Class: %s (%d)\n", pLastClass, count);
|
|
}
|
|
|
|
pLastClass = pClassname;
|
|
count = 1;
|
|
}
|
|
else
|
|
count++;
|
|
|
|
|
|
if (kvEnts == NULL)
|
|
kvEnts = new KeyValues("entites");
|
|
|
|
KeyValues *pKVMap = new KeyValues(pClassname);
|
|
|
|
char origin[_MAX_PATH];
|
|
Q_snprintf(origin, sizeof(origin), "%.2f %.2f %.2f", pEntity->GetAbsOrigin().x, pEntity->GetAbsOrigin().y, pEntity->GetAbsOrigin().z);
|
|
char angle[_MAX_PATH];
|
|
Q_snprintf(angle, sizeof(angle), "%.2f %.2f %.2f", pEntity->GetAbsAngles().x, pEntity->GetAbsAngles().y, pEntity->GetAbsAngles().z);
|
|
pKVMap->SetString("origin", origin);
|
|
pKVMap->SetString("angle", angle);
|
|
|
|
|
|
KeyValues *kvPToEnt = new KeyValues("keyvalues");
|
|
|
|
char targetname[_MAX_PATH];
|
|
Q_snprintf(targetname, sizeof(targetname), "%s", pEntity->GetEntityName());
|
|
kvPToEnt->SetString("targetname", targetname);
|
|
char model[_MAX_PATH];
|
|
Q_snprintf(model, sizeof(model), "%s", pEntity->GetModelName());
|
|
kvPToEnt->SetString("model", model);
|
|
|
|
if (AllocPooledString(pClassname) == AllocPooledString("instant_trig"))
|
|
{
|
|
KeyValues *newKV = kvEnts->CreateNewKey();
|
|
//newKV->SetName(var.String());
|
|
//newKV->SetString("This block is relative to instant_trig below", "___");
|
|
//newKV->SetString("Put below some logik you want", "also for correct mapadd parsing you need to move this block from the <entity> block to an empty space in this document");
|
|
|
|
variant_t var;
|
|
if (pEntity->ReadKeyField("label", &var))
|
|
{
|
|
//KeyValues *kvs = new KeyValues("keyvalues");
|
|
kvPToEnt->SetString("label", var.String());
|
|
//pKVMap->AddSubKey(kvs);
|
|
|
|
//KeyValues *newKV = kvEnts->CreateNewKey();
|
|
char name[_MAX_PATH];
|
|
Q_snprintf(name, sizeof(name), "entities:%s", var.String());
|
|
|
|
newKV->SetName(name);
|
|
newKV->SetString("This block is relative to instant_trig below", "___");
|
|
newKV->SetString("Put below some logik you want", "also for correct mapadd parsing you need to move this block from the <entity> block to an empty space in this document");
|
|
}
|
|
variant_t var2;
|
|
if (pEntity->ReadKeyField("radius", &var2))
|
|
{
|
|
kvPToEnt->SetString("radius", var2.String());
|
|
}
|
|
variant_t var3;
|
|
if (pEntity->ReadKeyField("timer", &var3))
|
|
{
|
|
kvPToEnt->SetString("timer", var3.String());
|
|
}
|
|
}
|
|
|
|
pKVMap->AddSubKey(kvPToEnt);
|
|
|
|
kvEnts->AddSubKey(pKVMap);
|
|
}
|
|
if (pLastClass[0] != 0 && count)
|
|
{
|
|
ConColorMsg(Color(255, 155, 155, 255), "Class: %s (%d)\n", pLastClass, count);
|
|
}
|
|
if (m_sortedList.Count())
|
|
{
|
|
ConColorMsg(Color(255, 0, 255, 255), "Total %d entities (%d empty, %d edicts)\n", m_sortedList.Count(), m_emptyCount, edicts);
|
|
}
|
|
|
|
char fullpath[_MAX_PATH];
|
|
Q_snprintf(fullpath, sizeof(fullpath), "mapadd_generated/%s.txt", gpGlobals->mapname);
|
|
|
|
char GameInfoPath[MAX_PATH];
|
|
g_pFullFileSystem->RelativePathToFullPath("gameinfo.txt", "MOD", GameInfoPath, sizeof(GameInfoPath));
|
|
|
|
char localpath[_MAX_PATH];
|
|
Q_FixSlashes(GameInfoPath, '/');
|
|
Q_snprintf(localpath, sizeof(localpath), "%s/mapadd_generated/%s.txt", GameInfoPath, gpGlobals->mapname);
|
|
ConColorMsg(Color(255, 255, 255, 255), "Generated in: %s \n", localpath);
|
|
ConColorMsg(Color(0, 255, 0, 255), "Done! \n");
|
|
//Create txt file
|
|
std::ofstream outfile(localpath);
|
|
//outfile << "my text here!" << std::endl;
|
|
outfile.close();
|
|
|
|
// save the data out to a file
|
|
bSuccess = kvEnts->SaveToFile(g_pFullFileSystem, fullpath, NULL);
|
|
if (!bSuccess)
|
|
{
|
|
ConColorMsg(Color(0, 0, 255, 255), "BuildMode - Error saving file", "Error: Could not save changes. File is most likely read only.");
|
|
}
|
|
|
|
kvEnts->deleteThis();
|
|
|
|
|
|
|
|
|
|
|
|
/*KeyValues *kvTrigs = NULL;
|
|
const char *pLastClass2 = "";
|
|
int count2 = 0;
|
|
int edicts2 = 0;
|
|
for (int is = 0; is < m_sortedList.Count(); is++)
|
|
{
|
|
CBaseEntity *pEntity = m_sortedList[is];
|
|
if (!pEntity)
|
|
continue;
|
|
|
|
if (pEntity->edict())
|
|
edicts2++;
|
|
|
|
const char *pClassname2 = pEntity->GetClassname();
|
|
if (!FStrEq(pClassname2, pLastClass))
|
|
{
|
|
if (count2)
|
|
{
|
|
ConColorMsg(Color(0, 0, 255, 255), "Class: %s (%d)\n", pLastClass, count2);
|
|
}
|
|
|
|
pLastClass = pClassname2;
|
|
count2 = 1;
|
|
}
|
|
else
|
|
count2++;
|
|
|
|
|
|
|
|
if (kvTrigs == NULL)
|
|
{
|
|
kvTrigs = new KeyValues("Here you got event in instant trigs");
|
|
}
|
|
|
|
|
|
if (AllocPooledString(pClassname2) == AllocPooledString("instant_trig"))
|
|
{
|
|
variant_t var;
|
|
if (pEntity->ReadKeyField("label", &var))
|
|
{
|
|
if (kvTrigs->LoadFromFile(filesystem, fullpath))
|
|
{
|
|
|
|
}
|
|
|
|
KeyValues *kvs = new KeyValues("keyvalues");
|
|
kvs->SetString("label", var.String());
|
|
pKVMap->AddSubKey(kvs);
|
|
|
|
KeyValues *newKV = kvEnts->CreateNewKey();
|
|
newKV->SetName(var.String());
|
|
newKV->SetString("Put here some logik you want -->", "");
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
kvEnts->AddSubKey(pKVMap);
|
|
|
|
}
|
|
bool success = kvTrigs->SaveToFile(g_pFullFileSystem, fullpath, NULL);
|
|
if (!bSuccess)
|
|
{
|
|
ConColorMsg(Color(0, 0, 255, 255), "BuildMode - Error saving file", "Error: Could not save changes. File is most likely read only.");
|
|
}
|
|
kvTrigs->deleteThis();*/
|
|
|
|
}
|
|
private:
|
|
CUtlSortVector< CBaseEntity *, CEntityReportLess > m_sortedList;
|
|
int m_emptyCount;
|
|
};
|
|
CON_COMMAND(mapadd_generate, "Command will generate all entite's info on this map into folder <<mapadd_generated/cur_map*>>")
|
|
{
|
|
if (!UTIL_IsCommandIssuedByServerAdmin())
|
|
return;
|
|
CSortedMapAddEntList list;
|
|
CBaseEntity *pEntity = gEntList.FirstEnt();
|
|
while (pEntity)
|
|
{
|
|
list.AddEntityToList(pEntity);
|
|
pEntity = gEntList.NextEnt(pEntity);
|
|
}
|
|
|
|
CBaseTrigger *pTrig = dynamic_cast<CBaseTrigger*>(gEntList.FirstEnt());
|
|
while (pTrig)
|
|
{
|
|
list.AddEntityToList(pTrig);
|
|
pTrig = dynamic_cast<CBaseTrigger*>(gEntList.NextEnt(pTrig));
|
|
}
|
|
|
|
list.ParseEntites();
|
|
}
|
|
|
|
|
|
class CMapAddTriggerOnce : public CBaseEntity
|
|
{
|
|
DECLARE_CLASS(CMapAddTriggerOnce, CBaseEntity);
|
|
|
|
DECLARE_DATADESC();
|
|
public:
|
|
CMapAddTriggerOnce(void) {};
|
|
|
|
CMapAddTriggerOnce *entCreate(const Vector &position);
|
|
|
|
Vector _min = Vector(-10, -10, -10);
|
|
Vector _max = Vector(10, 10, 10);
|
|
|
|
string_t labelName;
|
|
|
|
string_t RS_CH = MAKE_STRING("player");
|
|
|
|
COutputEvent m_OnTrigger; // Output event when the counter reaches the threshold
|
|
|
|
void SetBounds(CMapAddTriggerOnce *trigger);
|
|
|
|
void Touch(CBaseEntity *pOther);
|
|
};
|
|
|
|
LINK_ENTITY_TO_CLASS(mapadd_trigger_once, CMapAddTriggerOnce);
|
|
|
|
BEGIN_DATADESC(CMapAddTriggerOnce)
|
|
|
|
DEFINE_KEYFIELD(labelName, FIELD_STRING, "label"),
|
|
|
|
DEFINE_KEYFIELD(RS_CH, FIELD_STRING, "Response"),
|
|
|
|
DEFINE_OUTPUT(m_OnTrigger, "OnTrigger"),
|
|
|
|
DEFINE_ENTITYFUNC(Touch),
|
|
|
|
END_DATADESC()
|
|
|
|
CMapAddTriggerOnce *CMapAddTriggerOnce::entCreate(const Vector &position)
|
|
{
|
|
CMapAddTriggerOnce *pEnt = CREATE_ENTITY(CMapAddTriggerOnce, "mapadd_trigger_once");
|
|
pEnt->SetAbsOrigin(position);
|
|
pEnt->SetCollisionGroup(COLLISION_GROUP_PLAYER);
|
|
pEnt->SetSolid(SOLID_BBOX);
|
|
pEnt->AddSolidFlags(FSOLID_TRIGGER | FSOLID_NOT_SOLID);
|
|
pEnt->SetMoveType(MOVETYPE_NONE);
|
|
|
|
UTIL_SetSize(pEnt, pEnt->_min, pEnt->_max);
|
|
|
|
return pEnt;
|
|
}
|
|
|
|
void CMapAddTriggerOnce::SetBounds(CMapAddTriggerOnce *trigger)
|
|
{
|
|
UTIL_SetSize(trigger, _min, _max);
|
|
}
|
|
|
|
void CMapAddTriggerOnce::Touch(CBaseEntity *pOther)
|
|
{
|
|
if (!pOther)
|
|
return;
|
|
|
|
bool hit = false;
|
|
|
|
if (FStrEq(STRING(RS_CH), "player") && pOther->IsPlayer())
|
|
{
|
|
hit = true;
|
|
|
|
m_OnTrigger.FireOutput(pOther, this);
|
|
|
|
const char *mainLabelName = "entities";
|
|
const char *childLabelName = STRING(labelName);
|
|
|
|
CMapScriptParser *parser = GetMapScriptParser();
|
|
if (parser)
|
|
{
|
|
parser->ParseTriggerEvents(mainLabelName, childLabelName);
|
|
|
|
UTIL_Remove(this);
|
|
}
|
|
}
|
|
if (FStrEq(STRING(RS_CH), "npc") && pOther->IsNPC())
|
|
{
|
|
hit = true;
|
|
|
|
m_OnTrigger.FireOutput(pOther, this);
|
|
|
|
const char *mainLabelName = "entities";
|
|
const char *childLabelName = STRING(labelName);
|
|
|
|
CMapScriptParser *parser = GetMapScriptParser();
|
|
if (parser)
|
|
{
|
|
parser->ParseTriggerEvents(mainLabelName, childLabelName);
|
|
|
|
UTIL_Remove(this);
|
|
}
|
|
}
|
|
|
|
if (hit)
|
|
UTIL_Remove(this);
|
|
}
|
|
|
|
class CMapAddTriggerMultiple : public CBaseEntity
|
|
{
|
|
DECLARE_CLASS(CMapAddTriggerMultiple, CBaseEntity);
|
|
|
|
DECLARE_DATADESC();
|
|
public:
|
|
CMapAddTriggerMultiple();
|
|
|
|
CMapAddTriggerMultiple *entCreate(const Vector &position);
|
|
|
|
Vector _min = Vector(-10, -10, -10);
|
|
Vector _max = Vector(10, 10, 10);
|
|
|
|
string_t labelName;
|
|
|
|
float delayThink = 5.f;
|
|
|
|
float thinkLimit = 50.f;
|
|
|
|
string_t RS_CH = MAKE_STRING("player");
|
|
|
|
COutputEvent m_OnTrigger; // Output event when the counter reaches the threshold
|
|
|
|
void SetBounds(CMapAddTriggerMultiple *trigger);
|
|
|
|
void Touch(CBaseEntity *pOther);
|
|
|
|
private:
|
|
float m_flNextThink;
|
|
};
|
|
|
|
LINK_ENTITY_TO_CLASS(mapadd_trigger_multiple, CMapAddTriggerMultiple);
|
|
|
|
BEGIN_DATADESC(CMapAddTriggerMultiple)
|
|
|
|
DEFINE_FIELD(m_flNextThink, FIELD_TIME),
|
|
|
|
DEFINE_KEYFIELD(labelName, FIELD_STRING, "label"),
|
|
|
|
DEFINE_KEYFIELD(RS_CH, FIELD_STRING, "Response"),
|
|
|
|
DEFINE_KEYFIELD(delayThink, FIELD_FLOAT, "delay"),
|
|
|
|
DEFINE_KEYFIELD(thinkLimit, FIELD_FLOAT, "limit"),
|
|
|
|
DEFINE_OUTPUT(m_OnTrigger, "OnTrigger"),
|
|
|
|
DEFINE_ENTITYFUNC(Touch),
|
|
|
|
END_DATADESC()
|
|
|
|
CMapAddTriggerMultiple *CMapAddTriggerMultiple::entCreate(const Vector &position)
|
|
{
|
|
CMapAddTriggerMultiple *pEnt = CREATE_ENTITY(CMapAddTriggerMultiple, "mapadd_trigger_multiple");
|
|
pEnt->SetAbsOrigin(position);
|
|
pEnt->SetCollisionGroup(COLLISION_GROUP_PLAYER);
|
|
pEnt->SetSolid(SOLID_BBOX);
|
|
pEnt->AddSolidFlags(FSOLID_TRIGGER | FSOLID_NOT_SOLID);
|
|
pEnt->SetMoveType(MOVETYPE_NONE);
|
|
pEnt->m_flNextThink = 0.f;
|
|
UTIL_SetSize(pEnt, pEnt->_min, pEnt->_max);
|
|
|
|
return pEnt;
|
|
}
|
|
|
|
CMapAddTriggerMultiple::CMapAddTriggerMultiple()
|
|
{
|
|
m_flNextThink = 0.f;
|
|
}
|
|
|
|
void CMapAddTriggerMultiple::SetBounds(CMapAddTriggerMultiple *trigger)
|
|
{
|
|
UTIL_SetSize(trigger, _min, _max);
|
|
}
|
|
|
|
void CMapAddTriggerMultiple::Touch(CBaseEntity *pOther)
|
|
{
|
|
if (!pOther)
|
|
return;
|
|
|
|
if (m_flNextThink < gpGlobals->curtime)
|
|
{
|
|
m_flNextThink = gpGlobals->curtime + delayThink;
|
|
|
|
bool hit = false;
|
|
|
|
if (FStrEq(STRING(RS_CH), "player") && pOther->IsPlayer())
|
|
{
|
|
hit = true;
|
|
|
|
m_OnTrigger.FireOutput(pOther, this);
|
|
|
|
const char *mainLabelName = "entities";
|
|
const char *childLabelName = STRING(labelName);
|
|
|
|
CMapScriptParser *parser = GetMapScriptParser();
|
|
if (parser)
|
|
{
|
|
parser->ParseTriggerEvents(mainLabelName, childLabelName);
|
|
|
|
//UTIL_Remove(this);
|
|
}
|
|
}
|
|
if (FStrEq(STRING(RS_CH), "npc") && pOther->IsNPC())
|
|
{
|
|
hit = true;
|
|
|
|
m_OnTrigger.FireOutput(pOther, this);
|
|
|
|
const char *mainLabelName = "entities";
|
|
const char *childLabelName = STRING(labelName);
|
|
|
|
CMapScriptParser *parser = GetMapScriptParser();
|
|
if (parser)
|
|
{
|
|
parser->ParseTriggerEvents(mainLabelName, childLabelName);
|
|
|
|
//UTIL_Remove(this);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (m_flNextThink >= thinkLimit)
|
|
UTIL_Remove(this);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class CMapAddNPCTrigger1 : public CMapAdd
|
|
{
|
|
public:
|
|
DECLARE_CLASS(CMapAddNPCTrigger1, CMapAdd);
|
|
DECLARE_DATADESC();
|
|
|
|
|
|
// Constructor
|
|
CMapAddNPCTrigger1(int MnEntIndex = 0);
|
|
|
|
void Spawn()
|
|
{
|
|
BaseClass::Spawn();
|
|
SetNextThink(gpGlobals->curtime); // Think now
|
|
}
|
|
//CMapAddITrigger *Pointer();
|
|
void Think();
|
|
void ActionAdd(KeyValues *pMapAddEnt);
|
|
void ActionMod(KeyValues *pMapAddEnt);
|
|
|
|
private:
|
|
CBaseEntity *mapaddEnt = NULL;
|
|
string_t labelName;
|
|
float m_nTriggerArea; // Count at which to fire our output
|
|
float m_nTimer; // Count at which to fire our output
|
|
bool m_bDeleteOnFire;
|
|
COutputEvent m_OnTrigger; // Output event when the counter reaches the threshold
|
|
protected:
|
|
int m_nEntIndexM;
|
|
};
|
|
LINK_ENTITY_TO_CLASS(instant_trig_npc, CMapAddNPCTrigger1);
|
|
|
|
// Start of our data description for the class
|
|
BEGIN_DATADESC(CMapAddNPCTrigger1)
|
|
|
|
// Links our member variable to our keyvalue from Hammer
|
|
DEFINE_KEYFIELD(m_nTriggerArea, FIELD_FLOAT, "radius"),
|
|
DEFINE_KEYFIELD(m_nTimer, FIELD_FLOAT, "timer"),
|
|
DEFINE_KEYFIELD(labelName, FIELD_STRING, "label"),
|
|
// Links our member variable to our keyvalue from Hammer
|
|
DEFINE_KEYFIELD(m_bDeleteOnFire, FIELD_BOOLEAN, "deleteonfire"),
|
|
// Links our input name from Hammer to our input member function
|
|
//DEFINE_INPUTFUNC( FIELD_VOID, "RunLabel", InputRunLabel ),
|
|
|
|
// Links our output member to the output name used by Hammer
|
|
DEFINE_OUTPUT(m_OnTrigger, "OnTrigger"),
|
|
|
|
DEFINE_THINKFUNC(Think), // Register new think function
|
|
|
|
END_DATADESC()
|
|
|
|
CMapAddNPCTrigger1::CMapAddNPCTrigger1(int MnEntIndex)
|
|
{
|
|
m_nEntIndexM = MnEntIndex;
|
|
m_nTriggerArea = 32.0f;
|
|
m_nTimer = 0.f;
|
|
m_bDeleteOnFire = true;
|
|
}
|
|
void CMapAddNPCTrigger1::Think()
|
|
{
|
|
if (!cvar->FindVar("oc_mapadd_enabled")->GetBool())
|
|
UTIL_Remove(this);
|
|
|
|
SetNextThink(gpGlobals->curtime + 0.01f + m_nTimer); // Think again in 1 second
|
|
BaseClass::Think();
|
|
|
|
CBaseEntity *ppEnts[512];
|
|
int nEntCount = UTIL_EntitiesInSphere(ppEnts, 512, this->GetAbsOrigin(), m_nTriggerArea, 0);
|
|
|
|
char szSSName[50];
|
|
Q_snprintf(szSSName, sizeof(szSSName), "Trigger_%d", entindex());
|
|
string_t iszSSName = AllocPooledString(szSSName);
|
|
this->SetName(iszSSName);
|
|
|
|
|
|
|
|
int i;
|
|
for (i = 0; i < nEntCount; i++)
|
|
{
|
|
//Look through the entities it found
|
|
if (ppEnts[i] != NULL)
|
|
if (ppEnts[i]->IsNPC())
|
|
{
|
|
|
|
char labelname[FILENAME_MAX];
|
|
Q_snprintf(labelname, sizeof(labelname), "entities:%s", labelName);
|
|
KeyValues* m_pLabel = NULL;
|
|
CMapScriptParser *parser = GetMapScriptParser();
|
|
if (parser)
|
|
{
|
|
m_pLabel = parser->m_pMapScript->FindKey(labelname);
|
|
if (m_pLabel)
|
|
parser->ParseEntities(m_pLabel);
|
|
}
|
|
|
|
if (m_pLabel)
|
|
{
|
|
UTIL_Remove(this);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
class CMapAddITrigger1 : public CMapAdd
|
|
{
|
|
public:
|
|
DECLARE_CLASS(CMapAddITrigger1, CMapAdd);
|
|
DECLARE_DATADESC();
|
|
|
|
|
|
// Constructor
|
|
CMapAddITrigger1(int MnEntIndex = 0);
|
|
|
|
void Spawn()
|
|
{
|
|
BaseClass::Spawn();
|
|
SetNextThink(gpGlobals->curtime); // Think now
|
|
}
|
|
//CMapAddITrigger *Pointer();
|
|
void Think();
|
|
void ActionAdd(KeyValues *pMapAddEnt);
|
|
void ActionMod(KeyValues *pMapAddEnt);
|
|
|
|
private:
|
|
CBaseEntity *mapaddEnt = NULL;
|
|
string_t labelName;
|
|
float m_nTriggerArea; // Count at which to fire our output
|
|
float m_nTimer; // Count at which to fire our output
|
|
bool m_bDeleteOnFire;
|
|
COutputEvent m_OnTrigger; // Output event when the counter reaches the threshold
|
|
protected:
|
|
int m_nEntIndexM;
|
|
};
|
|
LINK_ENTITY_TO_CLASS(instant_trig1111, CMapAddITrigger1);
|
|
|
|
// Start of our data description for the class
|
|
BEGIN_DATADESC(CMapAddITrigger1)
|
|
|
|
// Links our member variable to our keyvalue from Hammer
|
|
DEFINE_KEYFIELD(m_nTriggerArea, FIELD_FLOAT, "radius"),
|
|
DEFINE_KEYFIELD(m_nTimer, FIELD_FLOAT, "timer"),
|
|
DEFINE_KEYFIELD(labelName, FIELD_STRING, "label"),
|
|
// Links our member variable to our keyvalue from Hammer
|
|
DEFINE_KEYFIELD(m_bDeleteOnFire, FIELD_BOOLEAN, "deleteonfire"),
|
|
// Links our input name from Hammer to our input member function
|
|
//DEFINE_INPUTFUNC( FIELD_VOID, "RunLabel", InputRunLabel ),
|
|
|
|
// Links our output member to the output name used by Hammer
|
|
DEFINE_OUTPUT(m_OnTrigger, "OnTrigger"),
|
|
|
|
DEFINE_THINKFUNC(Think), // Register new think function
|
|
|
|
END_DATADESC()
|
|
|
|
CMapAddITrigger1::CMapAddITrigger1(int MnEntIndex)
|
|
{
|
|
m_nEntIndexM = MnEntIndex;
|
|
m_nTriggerArea = 32.0f;
|
|
m_nTimer = 0.f;
|
|
m_bDeleteOnFire = true;
|
|
}
|
|
void CMapAddITrigger1::Think()
|
|
{
|
|
if (!cvar->FindVar("oc_mapadd_enabled")->GetBool())
|
|
UTIL_Remove(this);
|
|
|
|
SetNextThink(gpGlobals->curtime + 0.01f + m_nTimer); // Think again in 1 second
|
|
BaseClass::Think();
|
|
|
|
CBaseEntity *ppEnts[512];
|
|
int nEntCount = UTIL_EntitiesInSphere(ppEnts, 512, this->GetAbsOrigin(), m_nTriggerArea, 0);
|
|
|
|
char szSSName[50];
|
|
Q_snprintf(szSSName, sizeof(szSSName), "Trigger_%d", entindex());
|
|
string_t iszSSName = AllocPooledString(szSSName);
|
|
this->SetName(iszSSName);
|
|
//DevMsg("m_nTimer %2f \n", m_nTimer);
|
|
if (m_nTimer != 0)
|
|
{
|
|
//m_nTimer = m_nTimer - 0.01f;
|
|
CBasePlayer *playerEnt = UTIL_GetLocalPlayer();
|
|
if (playerEnt)
|
|
SetAbsOrigin(playerEnt->GetAbsOrigin());
|
|
}
|
|
|
|
//if (m_nTimer == 0)
|
|
{
|
|
int i;
|
|
for (i = 0; i < nEntCount; i++)
|
|
{
|
|
//Look through the entities it found
|
|
if (ppEnts[i] != NULL)
|
|
if (ppEnts[i]->IsPlayer())
|
|
{
|
|
//m_OnTrigger.FireOutput(ppEnts[i], this);
|
|
|
|
|
|
char labelname[FILENAME_MAX];
|
|
Q_snprintf(labelname, sizeof(labelname), "entities:%s", labelName);
|
|
KeyValues* m_pLabel = NULL;
|
|
CMapScriptParser *parser = GetMapScriptParser();
|
|
if (parser && parser->m_pMapScript)
|
|
{
|
|
|
|
m_pLabel = parser->m_pMapScript->FindKey(labelname);
|
|
if (m_pLabel)
|
|
parser->ParseEntities(m_pLabel);
|
|
DevMsg("INSTANT_TRIG TRIGGERED WITH m_pLabel %s\n", m_pLabel);
|
|
}
|
|
DevMsg("INSTANT_TRIG TRIGGERED \n");
|
|
DevMsg("INSTANT_TRIG TRIGGERED WITH labelName %s\n", labelName);
|
|
|
|
if (m_pLabel)
|
|
{
|
|
UTIL_Remove(this);
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
//SetNextThink(gpGlobals->curtime + 0.01f); // Think again in 1 second
|
|
}
|
|
|
|
//Im lazy to put this on another file
|
|
class CEvent : public CLogicalEntity
|
|
{
|
|
public:
|
|
DECLARE_CLASS(CEvent, CLogicalEntity)
|
|
void Spawn()
|
|
{
|
|
SetNextThink(gpGlobals->curtime + m_flDelay);
|
|
}
|
|
void Think()
|
|
{
|
|
CBaseEntity *pEntity = gEntList.FindEntityByName(NULL, m_szTarget);
|
|
if (pEntity)
|
|
UTIL_Remove(pEntity);
|
|
}
|
|
|
|
string_t m_szTarget;
|
|
string_t m_szInput;
|
|
float m_flDelay;
|
|
};
|
|
|
|
LINK_ENTITY_TO_CLASS(event, CEvent)
|
|
|
|
|
|
CMapScriptParser::CMapScriptParser(char const *name) : CAutoGameSystem(name)
|
|
{
|
|
m_bRestored = false;
|
|
}
|
|
|
|
CMapScriptParser g_MapScriptParser("MapScriptParser");
|
|
|
|
CMapScriptParser *GetMapScriptParser()
|
|
{
|
|
return &g_MapScriptParser;
|
|
}
|
|
|
|
|
|
void CMapScriptParser::LevelInitParsing()
|
|
{
|
|
if (!cvar->FindVar("oc_mapadd_enabled")->GetBool())
|
|
return;
|
|
|
|
if (m_bRestored)
|
|
return;
|
|
|
|
|
|
/*GetLuaManager()->InitDll();
|
|
|
|
if (!GetLuaHandle())
|
|
Lua = new MapAddLua();*/
|
|
|
|
|
|
char mapadd_preset[FILENAME_MAX];
|
|
Q_snprintf(mapadd_preset, sizeof(mapadd_preset), (cvar->FindVar("oc_mapadd_preset")->GetString()));
|
|
|
|
char filename[FILENAME_MAX];
|
|
//if (GetNodeListParser())
|
|
{
|
|
Q_snprintf(filename, sizeof(filename), "%s/nodes/%s.snl", mapadd_preset, gpGlobals->mapname);
|
|
GetNodeListParser()->ParseScriptFile(filename);
|
|
}
|
|
|
|
/*Q_snprintf(filename, sizeof(filename), "%s/official/%s.txt", mapadd_preset, gpGlobals->mapname);
|
|
ParseScriptFile(filename, true);*/
|
|
|
|
Q_snprintf(filename, sizeof(filename), "%s/%s.txt", mapadd_preset, gpGlobals->mapname);
|
|
ParseScriptFile(filename);
|
|
|
|
/*if (Lua)
|
|
{
|
|
delete Lua;
|
|
Lua = NULL;
|
|
}
|
|
|
|
GetLuaManager()->ShutdownDll();*/
|
|
}
|
|
|
|
void CMapScriptParser::LevelPostInitParsing()
|
|
{
|
|
if (!cvar->FindVar("oc_mapadd_enabled")->GetBool())
|
|
return;
|
|
char mapadd_preset[FILENAME_MAX];
|
|
Q_snprintf(mapadd_preset, sizeof(mapadd_preset), (cvar->FindVar("oc_mapadd_preset")->GetString()));
|
|
|
|
char filename[FILENAME_MAX];
|
|
{
|
|
Q_snprintf(filename, sizeof(filename), "%s/nodes/%s.snl", mapadd_preset, gpGlobals->mapname);
|
|
GetNodeListParser()->ParseScriptFile(filename);
|
|
}
|
|
|
|
Q_snprintf(filename, sizeof(filename), "%s/%s.txt", mapadd_preset, gpGlobals->mapname);
|
|
PostParseScriptFile(filename);
|
|
}
|
|
|
|
void CMapScriptParser::OnRestore()
|
|
{
|
|
return;
|
|
}
|
|
|
|
void CMapScriptParser::ParseScriptFile(const char* filename, bool official)
|
|
{
|
|
/*if (disable_loadmapadd.GetBool())
|
|
return;*/
|
|
|
|
if (!m_pMapScript)
|
|
m_pMapScript = new KeyValues("MapScript");
|
|
|
|
if (m_pMapScript->LoadFromFile(filesystem, filename))
|
|
{
|
|
//KeyValues *mainKey = m_pMapScript->GetNextKey();
|
|
while (m_pMapScript)
|
|
{
|
|
if (FStrEq(m_pMapScript->GetName(), "precache"))
|
|
{
|
|
DebugColorMsg("Found precache Key \n");
|
|
FOR_EACH_VALUE(m_pMapScript, pType)
|
|
{
|
|
if (!Q_strcmp(pType->GetName(), "entity"))
|
|
{
|
|
UTIL_PrecacheOther(pType->GetString());
|
|
|
|
DebugColorMsg("Precaching Entity: ");
|
|
DebugColorMsg(pType->GetString());
|
|
DebugColorMsg("\n");
|
|
}
|
|
else if (!Q_strcmp(pType->GetName(), "model") || !Q_strcmp(pType->GetName(), "Model"))
|
|
{
|
|
CBaseEntity::PrecacheModel(pType->GetString());
|
|
|
|
DebugColorMsg("Precaching Model: ");
|
|
DebugColorMsg(pType->GetString());
|
|
DebugColorMsg("\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
if (FStrEq(m_pMapScript->GetName(), "entities"))
|
|
{
|
|
ParseEntities(m_pMapScript);
|
|
}
|
|
|
|
if (FStrEq(m_pMapScript->GetName(), "randomspawn"))
|
|
{
|
|
ParseRandomEntities(m_pMapScript);
|
|
}
|
|
|
|
m_pMapScript = m_pMapScript->GetNextKey();
|
|
|
|
if (m_pMapScript == NULL)
|
|
break;
|
|
}
|
|
}
|
|
|
|
m_pMapScript->deleteThis();
|
|
m_pMapScript = nullptr;
|
|
}
|
|
|
|
void CMapScriptParser::PostParseScriptFile(const char* filename, bool official)
|
|
{
|
|
|
|
if (!m_pMapScript)
|
|
m_pMapScript = new KeyValues("MapScript");
|
|
|
|
if (m_pMapScript->LoadFromFile(filesystem, filename))
|
|
{
|
|
while (m_pMapScript)
|
|
{
|
|
if (FStrEq(m_pMapScript->GetName(), "Init"))
|
|
{
|
|
if (gpGlobals->eLoadType != MapLoad_NewGame)
|
|
break;
|
|
|
|
ParsePostInit(m_pMapScript);
|
|
|
|
break;
|
|
}
|
|
|
|
m_pMapScript = m_pMapScript->GetNextKey();
|
|
|
|
if (m_pMapScript == NULL)
|
|
break;
|
|
}
|
|
}
|
|
|
|
m_pMapScript->deleteThis();
|
|
m_pMapScript = nullptr;
|
|
}
|
|
|
|
void CMapScriptParser::LevelShutdownPostEntity()
|
|
{
|
|
if (m_pMapScript)
|
|
{
|
|
m_pMapScript->deleteThis();
|
|
m_pMapScript = nullptr;
|
|
}
|
|
}
|
|
|
|
void CMapScriptParser::ExecuteRandomEntites()
|
|
{
|
|
KeyValues *pRandom = m_pMapScript->FindKey("randomspawn");
|
|
if (pRandom)
|
|
{
|
|
ParseRandomEntities(pRandom);
|
|
}
|
|
}
|
|
|
|
ConVar oc_mapadd_randomspawn_safe_distance("oc_mapadd_randomspawn_safe_distance", "50", FCVAR_ARCHIVE);
|
|
void CMapScriptParser::ParseRandomEntities(KeyValues *keyvalues)
|
|
{
|
|
FOR_EACH_SUBKEY(keyvalues, pClassname)
|
|
{
|
|
/*if (!Q_strcmp(pClassname->GetName(), "removenodes"))
|
|
{
|
|
FOR_EACH_VALUE(pClassname, value)
|
|
{
|
|
Vector VecOrigin;
|
|
|
|
float radius = 0.f;
|
|
|
|
if (!Q_strcmp(pClassname->GetName(), "origin"))
|
|
{
|
|
UTIL_StringToVector(VecOrigin.Base(), value->GetString());
|
|
}
|
|
if (!Q_strcmp(pClassname->GetName(), "radius"))
|
|
{
|
|
radius = value->GetFloat("radius", 50.f);
|
|
}
|
|
for (int i = 0; i < g_pBigAINet->NumNodes(); i++)
|
|
{
|
|
Vector sum = VecOrigin + g_pBigAINet->GetNode(i)->GetOrigin();
|
|
if (VectorLength(sum) >= radius)
|
|
{
|
|
g_pBigAINet->GetNode(i)->Unlock();
|
|
g_pBigAINet->GetNode(i)->ClearLinks();
|
|
}
|
|
}
|
|
}
|
|
|
|
continue;
|
|
}
|
|
if (!Q_strcmp(pClassname->GetName(), "removeairnodes"))
|
|
{
|
|
// no implementation for it now.
|
|
continue;
|
|
}*/
|
|
|
|
CBaseEntity *ppEnts[512];
|
|
|
|
int iCount = pClassname->GetInt("count", 0);
|
|
for (int currentNumber = 0; currentNumber < iCount; currentNumber++)
|
|
{
|
|
if (!g_pBigAINet->GetNode(0))
|
|
return;
|
|
//CBaseEntity *pEntity = CreateEntityByName(pClassname->GetName());
|
|
|
|
int index = RandomInt(0, g_pBigAINet->NumNodes() - 1);
|
|
|
|
CAI_Hint *pHint = g_pBigAINet->GetNode(index)->GetHint();
|
|
|
|
int max_iterations = g_pBigAINet->NumNodes();
|
|
|
|
if (pHint)
|
|
{
|
|
/*if*/while (max_iterations < g_pBigAINet->NumNodes() && (pHint->HintType() == HINT_ANTLION_BURROW_POINT ||
|
|
pHint->HintType() == HINT_ANTLION_THUMPER_FLEE_POINT ||
|
|
pHint->HintType() == HINT_HEADCRAB_BURROW_POINT ||
|
|
pHint->HintType() == HINT_HEADCRAB_EXIT_POD_POINT ||
|
|
pHint->HintType() == HINT_NOT_USED_PSTORM_ROCK_SPAWN ||
|
|
pHint->HintType() == HINT_NOT_USED_ROLLER_PATROL_POINT ||
|
|
pHint->HintType() == HINT_NOT_USED_ROLLER_CLEANUP_POINT ||
|
|
pHint->HintType() == HINT_WORLD_VISUALLY_INTERESTING ||
|
|
pHint->HintType() == HINT_WORLD_VISUALLY_INTERESTING_DONT_AIM))
|
|
{
|
|
//continue;
|
|
int newIndx = index++;
|
|
|
|
if (newIndx >= g_pBigAINet->NumNodes() - 1)
|
|
newIndx = 0;
|
|
|
|
pHint = g_pBigAINet->GetNode(newIndx)->GetHint();
|
|
|
|
max_iterations++;
|
|
}
|
|
}
|
|
|
|
CBaseEntity *pEntity = NULL;
|
|
|
|
Vector pos = g_pBigAINet->GetNode(index)->GetPosition(HULL_HUMAN);
|
|
//if (gEntList.FindEntityGenericNearest(pClassname->GetName(), pEntity->GetAbsOrigin(), oc_mapadd_randomspawn_safe_distance.GetFloat()) != NULL)
|
|
if (UTIL_EntitiesInSphere(ppEnts, 512, pos, oc_mapadd_randomspawn_safe_distance.GetFloat(), 0) > 0)
|
|
{
|
|
//UTIL_Remove(pEntity);
|
|
continue;
|
|
}
|
|
else
|
|
pEntity = CreateEntityByName(pClassname->GetName());
|
|
|
|
if (pEntity)
|
|
{
|
|
//Vector pos = g_pBigAINet->GetNode(RandomInt(1, g_pBigAINet->NumNodes() - 1))->GetPosition(HULL_HUMAN);
|
|
|
|
const char *sWeapon = pClassname->GetString("weapon", NULL);
|
|
if (sWeapon)
|
|
pEntity->KeyValue("additionalequipment", sWeapon);
|
|
const char *sModel = pClassname->GetString("model", NULL);
|
|
if (sModel)
|
|
pEntity->KeyValue("model", sModel);
|
|
|
|
char key[512];
|
|
char value[512];
|
|
char tokenname[512];
|
|
|
|
const char *pValue = pClassname->GetString("values", NULL);
|
|
if (pValue)
|
|
{
|
|
pValue = nexttoken(tokenname, pValue, ' ');
|
|
while (pValue && Q_strlen(tokenname) > 0)
|
|
{
|
|
Q_strcpy(key, tokenname);
|
|
pValue = nexttoken(tokenname, pValue, ' ');
|
|
Q_strcpy(value, tokenname);
|
|
pEntity->KeyValue(key, value);
|
|
pValue = nexttoken(tokenname, pValue, ' ');
|
|
}
|
|
}
|
|
|
|
pEntity->SetAbsOrigin(pos);
|
|
pEntity->Precache();
|
|
DispatchSpawn(pEntity);
|
|
pEntity->Activate();
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
void StringToColorArray(CUtlVector<int> *pVector, const char *pString, const char *separator, int size)
|
|
{
|
|
CUtlVector<char*, CUtlMemory<char*> > arr;
|
|
|
|
Q_SplitString(pString, separator, arr);
|
|
|
|
pVector->RemoveAll();
|
|
|
|
for (int i = 0; i < arr.Count(); i++)
|
|
{
|
|
int k = atoi(arr.Element(i));
|
|
pVector->AddToTail(k);
|
|
}
|
|
|
|
//Size check
|
|
for (int i = 0; i < 4; i++)
|
|
{
|
|
if (!pVector->Element(i))
|
|
pVector->AddToTail(0);
|
|
}
|
|
}
|
|
|
|
#include "OverCharged/RTT/env_global_light.h"
|
|
#include "icommandline.h"
|
|
|
|
void CMapScriptParser::ParseCSMInfo(KeyValues *keyvalues, const Vector &origin, const QAngle &originAngle)
|
|
{
|
|
/*if (CommandLine()->CheckParm("-oc_enable_dynamic_shadows") == NULL)
|
|
return;*/
|
|
if (!cvar->FindVar("oc_global_lightning_enabled")->GetBool())
|
|
return;
|
|
|
|
KeyValues *pKeyValuesOrig = keyvalues->FindKey("keyvalues");
|
|
if (pKeyValuesOrig)
|
|
{
|
|
KeyValues *pKeyValues = pKeyValuesOrig->FindKey("global_lightning_keyvalues");
|
|
if (pKeyValues)
|
|
{
|
|
CBaseEntity *pEntity = CBaseEntity::CreateNoSpawn("global_lightning", origin, originAngle);
|
|
if (pEntity)
|
|
{
|
|
CGlobalLight *glEnt = static_cast<CGlobalLight*>(pEntity);
|
|
//g_GlobalLightning = glEnt;
|
|
|
|
if (glEnt)
|
|
{
|
|
gEntList.NotifyCreateEntity(glEnt);
|
|
|
|
FOR_EACH_VALUE(pKeyValues, pValue)
|
|
{
|
|
glEnt->KeyValue(pValue->GetName(), pValue->GetString());
|
|
}
|
|
|
|
glEnt->Precache();
|
|
|
|
DispatchSpawn(glEnt);
|
|
|
|
glEnt->Activate();
|
|
|
|
glEnt->EnableFromMapAdd();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CMapScriptParser::MapaddChangeLevel(KeyValues *keyvalues)
|
|
{
|
|
if (FStrEq(keyvalues->GetName(), "mapadd_trigger_once") || FStrEq(keyvalues->GetName(), "instant_trig"))
|
|
{
|
|
CMapAddTriggerOnce *pTriggerOnce = nullptr;
|
|
|
|
Vector origin = Vector(0, 0, 0);
|
|
Vector bounds = Vector(10, 10, 10);
|
|
float radius = 10.f;
|
|
bool setSize = false;
|
|
|
|
FOR_EACH_VALUE(keyvalues, value)
|
|
{
|
|
if (FStrEq(value->GetName(), "origin"))
|
|
{
|
|
UTIL_StringToVector(origin.Base(), value->GetString());
|
|
}
|
|
if (FStrEq(value->GetName(), "bounds"))
|
|
{
|
|
UTIL_StringToVector(bounds.Base(), value->GetString());
|
|
setSize = true;
|
|
}
|
|
if (FStrEq(value->GetName(), "radius"))
|
|
{
|
|
radius = value->GetFloat();
|
|
bounds.x = bounds.y = bounds.z = radius;
|
|
setSize = true;
|
|
}
|
|
}
|
|
|
|
pTriggerOnce = pTriggerOnce->entCreate(origin);
|
|
|
|
if (setSize)
|
|
{
|
|
pTriggerOnce->_max = bounds;
|
|
pTriggerOnce->_min = bounds * -1.f;
|
|
|
|
pTriggerOnce->SetBounds(pTriggerOnce);
|
|
}
|
|
|
|
pTriggerOnce->Precache();
|
|
|
|
gEntList.NotifyCreateEntity(pTriggerOnce);
|
|
|
|
KeyValues *pKeyValues = keyvalues->FindKey("keyvalues");
|
|
if (pKeyValues)
|
|
{
|
|
FOR_EACH_VALUE(pKeyValues, pValues)
|
|
{
|
|
pTriggerOnce->KeyValue(pValues->GetName(), pValues->GetString());
|
|
|
|
Vector newBounds;
|
|
float newRadius;
|
|
bool newSize = false;
|
|
if (FStrEq(pValues->GetName(), "bounds"))
|
|
{
|
|
UTIL_StringToVector(newBounds.Base(), pValues->GetString());
|
|
newSize = true;
|
|
}
|
|
if (FStrEq(pValues->GetName(), "radius"))
|
|
{
|
|
newRadius = pValues->GetFloat();
|
|
bounds.x = bounds.y = bounds.z = newRadius;
|
|
newSize = true;
|
|
}
|
|
if (FStrEq(pValues->GetName(), "response"))
|
|
{
|
|
const char* responseChannel = pValues->GetString();
|
|
|
|
if (FStrEq(responseChannel, "player"))
|
|
{
|
|
pTriggerOnce->SetCollisionGroup(COLLISION_GROUP_PLAYER);
|
|
}
|
|
if (FStrEq(responseChannel, "npc"))
|
|
{
|
|
pTriggerOnce->SetCollisionGroup(COLLISION_GROUP_NPC);
|
|
}
|
|
}
|
|
if (newSize)
|
|
{
|
|
pTriggerOnce->_max = bounds;
|
|
pTriggerOnce->_min = bounds * -1.f;
|
|
|
|
pTriggerOnce->SetBounds(pTriggerOnce);
|
|
}
|
|
}
|
|
}
|
|
|
|
DispatchSpawn(pTriggerOnce);
|
|
|
|
pTriggerOnce->Activate();
|
|
}
|
|
if (FStrEq(keyvalues->GetName(), "mapadd_trigger_multiple"))
|
|
{
|
|
CMapAddTriggerMultiple *pTriggerMult = nullptr;
|
|
|
|
Vector origin = Vector(0, 0, 0);
|
|
Vector bounds = Vector(10, 10, 10);
|
|
float radius = 10.f;
|
|
bool setSize = false;
|
|
float delay = 5.f;
|
|
float limit = 50.f;
|
|
|
|
FOR_EACH_VALUE(keyvalues, value)
|
|
{
|
|
if (FStrEq(value->GetName(), "origin"))
|
|
{
|
|
UTIL_StringToVector(origin.Base(), value->GetString());
|
|
}
|
|
if (FStrEq(value->GetName(), "bounds"))
|
|
{
|
|
UTIL_StringToVector(bounds.Base(), value->GetString());
|
|
setSize = true;
|
|
}
|
|
if (FStrEq(value->GetName(), "radius"))
|
|
{
|
|
radius = value->GetFloat();
|
|
bounds.x = bounds.y = bounds.z = radius;
|
|
setSize = true;
|
|
}
|
|
if (FStrEq(value->GetName(), "delay"))
|
|
{
|
|
delay = value->GetFloat();
|
|
}
|
|
if (FStrEq(value->GetName(), "limit"))
|
|
{
|
|
limit = value->GetFloat();
|
|
}
|
|
}
|
|
|
|
pTriggerMult = pTriggerMult->entCreate(origin);
|
|
|
|
if (setSize)
|
|
{
|
|
pTriggerMult->_max = bounds;
|
|
pTriggerMult->_min = bounds * -1.f;
|
|
|
|
pTriggerMult->SetBounds(pTriggerMult);
|
|
}
|
|
|
|
pTriggerMult->Precache();
|
|
|
|
gEntList.NotifyCreateEntity(pTriggerMult);
|
|
|
|
KeyValues *pKeyValues = keyvalues->FindKey("keyvalues");
|
|
if (pKeyValues)
|
|
{
|
|
FOR_EACH_VALUE(pKeyValues, pValues)
|
|
{
|
|
pTriggerMult->KeyValue(pValues->GetName(), pValues->GetString());
|
|
|
|
Vector newBounds;
|
|
float newRadius;
|
|
bool newSize = false;
|
|
if (FStrEq(pValues->GetName(), "bounds"))
|
|
{
|
|
UTIL_StringToVector(newBounds.Base(), pValues->GetString());
|
|
newSize = true;
|
|
}
|
|
if (FStrEq(pValues->GetName(), "radius"))
|
|
{
|
|
newRadius = pValues->GetFloat();
|
|
bounds.x = bounds.y = bounds.z = newRadius;
|
|
newSize = true;
|
|
}
|
|
if (FStrEq(pValues->GetName(), "response"))
|
|
{
|
|
const char* responseChannel = pValues->GetString();
|
|
|
|
if (FStrEq(responseChannel, "player"))
|
|
{
|
|
pTriggerMult->SetCollisionGroup(COLLISION_GROUP_PLAYER);
|
|
}
|
|
if (FStrEq(responseChannel, "npc"))
|
|
{
|
|
pTriggerMult->SetCollisionGroup(COLLISION_GROUP_NPC);
|
|
}
|
|
}
|
|
if (newSize)
|
|
{
|
|
pTriggerMult->_max = bounds;
|
|
pTriggerMult->_min = bounds * -1.f;
|
|
|
|
pTriggerMult->SetBounds(pTriggerMult);
|
|
}
|
|
}
|
|
}
|
|
|
|
DispatchSpawn(pTriggerMult);
|
|
|
|
pTriggerMult->Activate();
|
|
}
|
|
}
|
|
|
|
void CMapScriptParser::ParseTriggerEvents(const char *parentLabelName, const char *childLabelName)
|
|
{
|
|
char mapadd_preset[FILENAME_MAX];
|
|
Q_snprintf(mapadd_preset, sizeof(mapadd_preset), (cvar->FindVar("oc_mapadd_preset")->GetString()));
|
|
|
|
char filename[FILENAME_MAX];
|
|
|
|
Q_snprintf(filename, sizeof(filename), "%s/%s.txt", mapadd_preset, gpGlobals->mapname);
|
|
|
|
if (!m_pMapScript)
|
|
m_pMapScript = new KeyValues("MapScript");
|
|
|
|
if (m_pMapScript->LoadFromFile(filesystem, filename))
|
|
{
|
|
char fullEventName[FILENAME_MAX];
|
|
Q_snprintf(fullEventName, sizeof(fullEventName), "%s:%s", parentLabelName, childLabelName);
|
|
|
|
while (m_pMapScript)
|
|
{
|
|
if (FStrEq(m_pMapScript->GetName(), fullEventName))
|
|
{
|
|
ParseEntities(m_pMapScript);
|
|
}
|
|
|
|
m_pMapScript = m_pMapScript->GetNextKey();
|
|
|
|
if (m_pMapScript == NULL)
|
|
break;
|
|
}
|
|
}
|
|
|
|
m_pMapScript->deleteThis();
|
|
m_pMapScript = nullptr;
|
|
}
|
|
|
|
void CMapScriptParser::ParsePostInit(KeyValues *keyvalues)
|
|
{
|
|
FOR_EACH_SUBKEY(keyvalues, pClassname)
|
|
{
|
|
if (FStrEq(pClassname->GetName(), "Give_Equipment"))
|
|
{
|
|
CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
|
|
if (pPlayer)
|
|
{
|
|
FOR_EACH_SUBKEY(pClassname, pSubKey)
|
|
{
|
|
if (FStrEq(pSubKey->GetName(), "Ammo"))
|
|
{
|
|
FOR_EACH_VALUE(pSubKey, pAmmo)
|
|
{
|
|
//engine->ServerCommand("give weapon_ar2\n");
|
|
pPlayer->GiveAmmo(pAmmo->GetInt(), pAmmo->GetName());
|
|
}
|
|
}
|
|
|
|
if (FStrEq(pSubKey->GetName(), "Item"))
|
|
{
|
|
FOR_EACH_VALUE(pSubKey, pItem)
|
|
{
|
|
if (FStrEq(pItem->GetString(), "item_suit"))
|
|
{
|
|
pPlayer->EquipSuit(true);
|
|
}
|
|
else
|
|
{
|
|
char iszItem[256];
|
|
Q_snprintf(iszItem, ARRAYSIZE(iszItem), "%s_%s", pItem->GetName(), pItem->GetString());
|
|
|
|
//string_t iszItem = AllocPooledString(pItem->GetString("") + pItem->GetString("")); // Make a copy of the classname
|
|
pPlayer->GiveNamedItem(iszItem);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CMapScriptParser::ModifyEnt(CBaseEntity *modEnt, KeyValues *pClassname, Vector &VelVector, variant_t &emptyVariant, char szSmodEntityName[128], bool &freeze, bool findedEnt)
|
|
{
|
|
FOR_EACH_VALUE(pClassname, value)
|
|
{
|
|
if (FStrEq(value->GetName(), "model") && findedEnt)
|
|
{
|
|
modEnt->PrecacheModel(value->GetString(""));
|
|
modEnt->SetModel(value->GetString(""));
|
|
}
|
|
else if (FStrEq(value->GetName(), "models") && findedEnt)
|
|
{
|
|
CUtlVector<char*, CUtlMemory<char*> > arr;
|
|
Q_SplitString(value->GetString(), "||", arr);
|
|
|
|
int i = random->RandomInt(0, arr.Count()-1);
|
|
|
|
modEnt->PrecacheModel(arr.Element(i));
|
|
modEnt->SetModel(arr.Element(i));
|
|
}
|
|
|
|
if (FStrEq(value->GetName(), "action") && findedEnt)
|
|
{
|
|
Q_snprintf(szSmodEntityName, sizeof(szSmodEntityName), "%s", AllocPooledString(value->GetString("")));
|
|
CBasePlayer *playerEnt = UTIL_GetLocalPlayer();
|
|
if (playerEnt)
|
|
{
|
|
modEnt->AcceptInput(value->GetString(""), playerEnt, modEnt, emptyVariant, 0);
|
|
}
|
|
else
|
|
modEnt->AcceptInput(value->GetString(""), NULL, modEnt, emptyVariant, 0);
|
|
}
|
|
|
|
if (FStrEq(value->GetName(), "value") && findedEnt)
|
|
{
|
|
if (value->GetString("value", ""))
|
|
{
|
|
emptyVariant.SetString(AllocPooledString(value->GetString("")));
|
|
}
|
|
else if (value->GetFloat("value"))
|
|
{
|
|
emptyVariant.SetFloat(value->GetFloat());
|
|
}
|
|
CBasePlayer *playerEnt = UTIL_GetLocalPlayer();
|
|
if (playerEnt)
|
|
{
|
|
modEnt->AcceptInput(szSmodEntityName, playerEnt, modEnt, emptyVariant, 0);
|
|
}
|
|
else
|
|
modEnt->AcceptInput(szSmodEntityName, NULL, modEnt, emptyVariant, 0);
|
|
}
|
|
|
|
if (FStrEq(value->GetName(), "delaytime") && findedEnt)
|
|
{
|
|
emptyVariant.SetFloat(value->GetFloat());
|
|
CBasePlayer *playerEnt = UTIL_GetLocalPlayer();
|
|
if (playerEnt)
|
|
{
|
|
modEnt->AcceptInput(szSmodEntityName, playerEnt, modEnt, emptyVariant, 0);
|
|
}
|
|
else
|
|
modEnt->AcceptInput(szSmodEntityName, NULL, modEnt, emptyVariant, 0);
|
|
}
|
|
|
|
if (FStrEq(value->GetName(), "freeze") && findedEnt)
|
|
{
|
|
modEnt->SetMoveType(MOVETYPE_NONE);
|
|
modEnt->SetSolid(SOLID_VPHYSICS);
|
|
modEnt->VPhysicsInitStatic();
|
|
freeze = false;
|
|
}
|
|
|
|
if (FStrEq(value->GetName(), "velocity") && findedEnt)
|
|
{
|
|
VelVector = Vector(0, 0, 0);
|
|
UTIL_StringToVector(VelVector.Base(), value->GetString());
|
|
modEnt->ApplyLocalVelocityImpulse(VelVector);
|
|
//vel = false;
|
|
}
|
|
|
|
if (FStrEq(value->GetName(), "longrange") && findedEnt)
|
|
{
|
|
modEnt->AddSpawnFlags(SF_NPC_LONG_RANGE);
|
|
}
|
|
else
|
|
{
|
|
if (modEnt)
|
|
modEnt->KeyValue(value->GetName(), value->GetString(""));
|
|
}
|
|
}
|
|
|
|
KeyValues *pKeyValues = pClassname->FindKey("keyvalues");
|
|
if (pKeyValues)
|
|
{
|
|
FOR_EACH_VALUE(pKeyValues, pValues)
|
|
{
|
|
//if (!Q_strcmp(pValues->GetName(), "model") || !Q_strcmp(pValues->GetName(), "Model"))
|
|
if (FStrEq(pValues->GetName(), "model") || FStrEq(pValues->GetName(), "Model"))
|
|
{
|
|
CBaseEntity::PrecacheModel(pValues->GetString());
|
|
modEnt->SetModel(pValues->GetString());
|
|
continue;
|
|
}
|
|
|
|
modEnt->KeyValue(pValues->GetName(), pValues->GetString());
|
|
}
|
|
}
|
|
}
|
|
|
|
void CMapScriptParser::ParseSystemTriggers(KeyValues *pClassname)
|
|
{
|
|
if (FStrEq(pClassname->GetName(), "trigger_changelevel"))
|
|
{
|
|
CBaseTrigger *pTrigger = dynamic_cast<CBaseTrigger*>(CreateEntityByName(pClassname->GetName()));
|
|
gEntList.NotifyCreateEntity(pTrigger);
|
|
|
|
Vector extendMaxSize = Vector(100, 100, 100);
|
|
Vector extendMinSize = Vector(-100, -100, -100);
|
|
|
|
if (pTrigger)
|
|
{
|
|
Vector vecOriginTrig;
|
|
|
|
pTrigger->SetAbsOrigin(Vector(0, 0, 0));
|
|
|
|
FOR_EACH_VALUE(pClassname, value)
|
|
{
|
|
//if (!Q_strcmp(value->GetName(), "origin"))
|
|
if (FStrEq(value->GetName(), "origin"))
|
|
{
|
|
UTIL_StringToVector(vecOriginTrig.Base(), value->GetString());
|
|
|
|
pTrigger->SetAbsOrigin(vecOriginTrig);
|
|
}
|
|
|
|
if (FStrEq(value->GetName(), "bounds"))
|
|
{
|
|
UTIL_StringToVector(extendMaxSize.Base(), value->GetString());
|
|
UTIL_StringToVector(extendMinSize.Base(), value->GetString());
|
|
}
|
|
}
|
|
|
|
|
|
//ent_bbox trigger_changelevel
|
|
pTrigger->SetSize(extendMinSize, extendMaxSize);
|
|
UTIL_SetSize(pTrigger, extendMinSize, extendMaxSize);
|
|
pTrigger->SetCollisionGroup(COLLISION_GROUP_PLAYER);
|
|
pTrigger->SetSolid(SOLID_NONE);
|
|
pTrigger->AddSolidFlags(FSOLID_TRIGGER);
|
|
pTrigger->CollisionProp()->UseTriggerBounds(true, extendMaxSize.x);
|
|
|
|
KeyValues *pKeyValues = pClassname->FindKey("keyvalues");
|
|
if (pKeyValues)
|
|
{
|
|
FOR_EACH_VALUE(pKeyValues, pValues)
|
|
{
|
|
pTrigger->KeyValue(pValues->GetName(), pValues->GetString());
|
|
}
|
|
}
|
|
pTrigger->Precache();
|
|
DispatchSpawn(pTrigger);
|
|
|
|
pTrigger->SetSize(extendMinSize, extendMaxSize);
|
|
UTIL_SetSize(pTrigger, extendMinSize, extendMaxSize);
|
|
/*pTrigger->SetCollisionGroup(COLLISION_GROUP_PLAYER);*/
|
|
|
|
pTrigger->Activate();
|
|
pTrigger->InitTrigger();
|
|
}
|
|
}
|
|
else if (FStrEq(pClassname->GetName(), "trigger_transition"))
|
|
{
|
|
CTriggerVolume *pTrigger = dynamic_cast<CTriggerVolume*>(CreateEntityByName(pClassname->GetName()));
|
|
gEntList.NotifyCreateEntity(pTrigger);
|
|
|
|
Vector extendMaxSize = Vector(100, 100, 100);
|
|
Vector extendMinSize = Vector(-100, -100, -100);
|
|
|
|
if (pTrigger)
|
|
{
|
|
Vector vecOriginTrig;
|
|
|
|
pTrigger->SetAbsOrigin(Vector(0, 0, 0));
|
|
|
|
FOR_EACH_VALUE(pClassname, value)
|
|
{
|
|
//if (!Q_strcmp(value->GetName(), "origin"))
|
|
if (FStrEq(value->GetName(), "origin"))
|
|
{
|
|
UTIL_StringToVector(vecOriginTrig.Base(), value->GetString());
|
|
|
|
pTrigger->SetAbsOrigin(vecOriginTrig);
|
|
}
|
|
|
|
if (FStrEq(value->GetName(), "bounds"))
|
|
{
|
|
UTIL_StringToVector(extendMaxSize.Base(), value->GetString());
|
|
UTIL_StringToVector(extendMinSize.Base(), value->GetString());
|
|
}
|
|
}
|
|
|
|
|
|
//ent_bbox trigger_changelevel
|
|
pTrigger->SetSize(extendMinSize, extendMaxSize);
|
|
UTIL_SetSize(pTrigger, extendMinSize, extendMaxSize);
|
|
pTrigger->SetCollisionGroup(COLLISION_GROUP_PLAYER);
|
|
pTrigger->SetSolid(SOLID_NONE);
|
|
pTrigger->AddSolidFlags(FSOLID_TRIGGER);
|
|
pTrigger->CollisionProp()->UseTriggerBounds(true, extendMaxSize.x);
|
|
|
|
KeyValues *pKeyValues = pClassname->FindKey("keyvalues");
|
|
if (pKeyValues)
|
|
{
|
|
FOR_EACH_VALUE(pKeyValues, pValues)
|
|
{
|
|
pTrigger->KeyValue(pValues->GetName(), pValues->GetString());
|
|
}
|
|
}
|
|
pTrigger->Precache();
|
|
DispatchSpawn(pTrigger);
|
|
|
|
pTrigger->SetSize(extendMinSize, extendMaxSize);
|
|
UTIL_SetSize(pTrigger, extendMinSize, extendMaxSize);
|
|
/*pTrigger->SetCollisionGroup(COLLISION_GROUP_PLAYER);*/
|
|
|
|
pTrigger->Activate();
|
|
//pTrigger->InitTrigger();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CBaseTrigger *pTrigger = dynamic_cast<CBaseTrigger*>(CreateEntityByName(pClassname->GetName()));
|
|
gEntList.NotifyCreateEntity(pTrigger);
|
|
|
|
Vector extendMaxSize = Vector(100, 100, 100);
|
|
Vector extendMinSize = Vector(-100, -100, -100);
|
|
|
|
Collision_Group_t group = COLLISION_GROUP_PLAYER;
|
|
|
|
/*char iszItem[64];
|
|
|
|
bool hasName = false;*/
|
|
|
|
if (pTrigger)
|
|
{
|
|
Vector vecOriginTrig;
|
|
|
|
pTrigger->SetAbsOrigin(Vector(0, 0, 0));
|
|
|
|
FOR_EACH_VALUE(pClassname, value)
|
|
{
|
|
/*if (FStrEq(value->GetName(), "trigger_name"))
|
|
{
|
|
Q_snprintf(iszItem, ARRAYSIZE(iszItem), "%s", value->GetString());
|
|
hasName = true;
|
|
}*/
|
|
|
|
if (FStrEq(value->GetName(), "origin"))
|
|
{
|
|
UTIL_StringToVector(vecOriginTrig.Base(), value->GetString());
|
|
|
|
pTrigger->SetAbsOrigin(vecOriginTrig);
|
|
}
|
|
|
|
if (FStrEq(value->GetName(), "bounds"))
|
|
{
|
|
UTIL_StringToVector(extendMaxSize.Base(), value->GetString());
|
|
UTIL_StringToVector(extendMinSize.Base(), value->GetString());
|
|
}
|
|
|
|
if (FStrEq(value->GetName(), "Response"))
|
|
{
|
|
group = (Collision_Group_t)value->GetInt();
|
|
}
|
|
}
|
|
|
|
|
|
/*if (!hasName)
|
|
{
|
|
Q_snprintf(iszItem, ARRAYSIZE(iszItem), "%s", "NULL");
|
|
}*/
|
|
|
|
//ent_bbox trigger_changelevel
|
|
pTrigger->SetSize(extendMinSize, extendMaxSize);
|
|
UTIL_SetSize(pTrigger, extendMinSize, extendMaxSize);
|
|
pTrigger->SetCollisionGroup(group);
|
|
pTrigger->SetSolid(SOLID_NONE);
|
|
pTrigger->AddSolidFlags(FSOLID_TRIGGER);
|
|
pTrigger->CollisionProp()->UseTriggerBounds(true, extendMaxSize.x);
|
|
|
|
KeyValues *pKeyValues = pClassname->FindKey("keyvalues");
|
|
if (pKeyValues)
|
|
{
|
|
FOR_EACH_VALUE(pKeyValues, pValues)
|
|
{
|
|
pTrigger->KeyValue(pValues->GetName(), pValues->GetString());
|
|
}
|
|
}
|
|
pTrigger->Precache();
|
|
DispatchSpawn(pTrigger);
|
|
|
|
pTrigger->SetSize(extendMinSize, extendMaxSize);
|
|
UTIL_SetSize(pTrigger, extendMinSize, extendMaxSize);
|
|
|
|
pTrigger->Activate();
|
|
pTrigger->InitTrigger();
|
|
}
|
|
}
|
|
}
|
|
|
|
void CMapScriptParser::ParseEntities(KeyValues *keyvalues)
|
|
{
|
|
bool freeze = false;
|
|
//bool vel = false;
|
|
//bool isOldCoord = false;
|
|
Vector VelVector;
|
|
Vector VecOrigin;
|
|
Vector VecAngle;
|
|
Vector VecOldOrigin = Vector(0, 0, 0);
|
|
QAngle AngOldOrigin = QAngle(0, 0, 0);
|
|
variant_t emptyVariant;
|
|
char szSmodEntityName[128];
|
|
FOR_EACH_SUBKEY(keyvalues, pClassname)
|
|
{
|
|
//if (cvar->FindVar("oc_mapadd_lua_enabled")->GetBool())
|
|
{
|
|
if (FStrEq(pClassname->GetName(), "lua") && GetLuaHandle())
|
|
{
|
|
if (GetLuaHandle()->OpenFile(gpGlobals->mapname.ToCStr()))
|
|
{
|
|
m_hasLua = true;
|
|
GetLuaHandle()->CallFunction(pClassname->GetString("callfunc", ""));
|
|
}
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
m_hasLua = false;
|
|
}
|
|
}
|
|
/*else
|
|
{
|
|
m_hasLua = false;
|
|
}*/
|
|
|
|
if (FStrEq(pClassname->GetName(), "SystemTriggers"))
|
|
{
|
|
FOR_EACH_SUBKEY(pClassname, pSubKey)
|
|
{
|
|
ParseSystemTriggers(pSubKey);
|
|
}
|
|
|
|
continue;
|
|
}
|
|
|
|
if (Q_strstr(pClassname->GetName(), "trigger") || Q_strstr(pClassname->GetName(), "instant_trig"))
|
|
{
|
|
if (cvar->FindVar("oc_mapadd_enabled")->GetBool())
|
|
MapaddChangeLevel(pClassname);
|
|
continue;
|
|
}
|
|
|
|
/*if (FStrEq(pClassname->GetName(), "env_sun"))
|
|
{
|
|
if (cvar->FindVar("oc_mapadd_enabled")->GetBool())
|
|
ParseCSMInfo(pClassname);
|
|
continue;
|
|
}*/
|
|
|
|
//if (!Q_strcmp(pClassname->GetName(), "player"))
|
|
if (FStrEq(pClassname->GetName(), "player"))
|
|
{
|
|
FOR_EACH_VALUE(pClassname, value)
|
|
{
|
|
|
|
//if (!Q_strcmp(value->GetName(), "origin"))
|
|
if (FStrEq(value->GetName(), "origin"))
|
|
{
|
|
Vector VecOrigin;
|
|
UTIL_StringToVector(VecOrigin.Base(), value->GetString());
|
|
|
|
UTIL_GetLocalPlayer()->SetAbsOrigin(VecOrigin);
|
|
}
|
|
//else if (!Q_strcmp(value->GetName(), "angle"))
|
|
else if (FStrEq(value->GetName(), "angle"))
|
|
{
|
|
Vector VecAngle;
|
|
UTIL_StringToVector(VecAngle.Base(), value->GetString());
|
|
|
|
UTIL_GetLocalPlayer()->SetLocalAngles(QAngle(VecAngle.x, VecAngle.y, VecAngle.z));
|
|
}
|
|
//else if (!Q_strcmp(value->GetName(), "message"))
|
|
else if (FStrEq(value->GetName(), "message"))
|
|
{
|
|
CBasePlayer *playerEnt = UTIL_GetLocalPlayer();
|
|
if (playerEnt)
|
|
{
|
|
engine->Con_NPrintf(9, value->GetString());
|
|
/*UTIL_ShowMessage(value->GetString(), playerEnt);
|
|
UTIL_SayText(value->GetString(), playerEnt);*/
|
|
/*hudtextparms_s htp;
|
|
htp.r2 = 255;
|
|
htp.g2 = 255;
|
|
htp.b2 = 255;
|
|
htp.a2 = 255;
|
|
htp.channel = 1;
|
|
htp.fxTime = 10.f;
|
|
htp.holdTime = 10.f;*/
|
|
//htp.x = 50;
|
|
//htp.y = 50;
|
|
//UTIL_HudMessage(playerEnt, htp, value->GetString());
|
|
//UTIL_HudHintText(playerEnt, value->GetString());
|
|
}
|
|
}
|
|
//else if (!Q_strcmp(value->GetName(), "fadein"))
|
|
else if (FStrEq(value->GetName(), "fadein"))
|
|
{
|
|
color32 black = { 0, 0, 0, 255 };
|
|
UTIL_ScreenFade(UTIL_GetLocalPlayer(), black, 0, value->GetInt(), FFADE_IN);
|
|
}
|
|
//else if (!Q_strcmp(value->GetName(), "fadeout"))
|
|
else if (FStrEq(value->GetName(), "fadeout"))
|
|
{
|
|
color32 black = { 32, 63, 100, 200 };
|
|
UTIL_ScreenFade(UTIL_GetLocalPlayer(), black, value->GetInt(), 0.5, FFADE_OUT);
|
|
}
|
|
//else if (!Q_strcmp(value->GetName(), "music"))
|
|
else if (FStrEq(value->GetName(), "music"))
|
|
{
|
|
CBasePlayer *playerEnt = UTIL_GetLocalPlayer();
|
|
if (playerEnt)
|
|
{
|
|
playerEnt->PrecacheScriptSound(value->GetString());
|
|
playerEnt->EmitAmbientSound(playerEnt->entindex(), playerEnt->GetAbsOrigin(), value->GetString());
|
|
}
|
|
}
|
|
}
|
|
continue;
|
|
}
|
|
else if (!Q_strcmp(pClassname->GetName(), "removeentity"))
|
|
{
|
|
FOR_EACH_VALUE(pClassname, value)
|
|
{
|
|
CBaseEntity *pEntity = NULL;
|
|
|
|
//if (!Q_strcmp(value->GetName(), "classname"))
|
|
if (FStrEq(value->GetName(), "classname"))
|
|
{
|
|
if (UTIL_GetLocalPlayer())
|
|
pEntity = gEntList.FindEntityByClassname(UTIL_GetLocalPlayer(), value->GetString());
|
|
if (!pEntity)
|
|
pEntity = gEntList.FindEntityByClassname(NULL, value->GetString());
|
|
}
|
|
|
|
bool searchBySphere = false;
|
|
|
|
float sRadius = 100.f;
|
|
|
|
Vector sphereLoc;
|
|
|
|
//if (!Q_strcmp(value->GetName(), "targetname"))
|
|
if (FStrEq(value->GetName(), "targetname"))
|
|
{
|
|
if (UTIL_GetLocalPlayer())
|
|
pEntity = gEntList.FindEntityByName(UTIL_GetLocalPlayer(), value->GetString());
|
|
if (!pEntity)
|
|
pEntity = gEntList.FindEntityByName(NULL, value->GetString());
|
|
}
|
|
else if (FStrEq(value->GetName(), "sphere_location"))
|
|
{
|
|
searchBySphere = true;
|
|
|
|
|
|
UTIL_StringToVector(sphereLoc.Base(), value->GetString());
|
|
}
|
|
else if (FStrEq(value->GetName(), "sphere_radius"))
|
|
{
|
|
if (searchBySphere)
|
|
{
|
|
sRadius = value->GetFloat();
|
|
|
|
pEntity = gEntList.FindEntityInSphere(NULL, sphereLoc, sRadius);
|
|
}
|
|
}
|
|
//else if (!Q_strcmp(value->GetName(), "model") || !Q_strcmp(value->GetName(), "Model"))
|
|
else if (FStrEq(value->GetName(), "model") || FStrEq(value->GetName(), "Model"))
|
|
{
|
|
if (UTIL_GetLocalPlayer())
|
|
pEntity = gEntList.FindEntityByModel(UTIL_GetLocalPlayer(), value->GetString());
|
|
if (!pEntity)
|
|
pEntity = gEntList.FindEntityByModel(NULL, value->GetString());
|
|
|
|
}
|
|
if (pEntity)
|
|
UTIL_Remove(pEntity);
|
|
}
|
|
}
|
|
else if (!Q_strcmp(pClassname->GetName(), "event"))
|
|
{
|
|
CBaseEntity *modEnt = NULL;
|
|
|
|
bool findedEnt = false;
|
|
|
|
FOR_EACH_VALUE(pClassname, value)
|
|
{
|
|
if (!modEnt)
|
|
{
|
|
if (FStrEq(value->GetName(), "targetname"))
|
|
{
|
|
modEnt = gEntList.FindEntityByName(NULL, value->GetString(""));
|
|
if (modEnt)
|
|
findedEnt = true;
|
|
}
|
|
else if (FStrEq(value->GetName(), "classname"))
|
|
{
|
|
while ((modEnt = gEntList.FindEntityByClassname(modEnt, value->GetString(""))) != NULL)
|
|
{
|
|
if (modEnt)
|
|
{
|
|
findedEnt = true;
|
|
|
|
ModifyEnt(modEnt, pClassname, VelVector, emptyVariant, szSmodEntityName, freeze, findedEnt);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
if (!findedEnt)
|
|
{
|
|
float sRadius = 100.f;
|
|
|
|
if (FStrEq(value->GetName(), "sphere_radius"))
|
|
{
|
|
sRadius = value->GetFloat();
|
|
}
|
|
if (FStrEq(value->GetName(), "sphere_location"))
|
|
{
|
|
Vector VecSphere;
|
|
UTIL_StringToVector(VecSphere.Base(), value->GetString());
|
|
|
|
modEnt = gEntList.FindEntityInSphere(NULL, VecSphere, sRadius);
|
|
if (modEnt)
|
|
findedEnt = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (findedEnt && modEnt)
|
|
{
|
|
ModifyEnt(modEnt, pClassname, VelVector, emptyVariant, szSmodEntityName, freeze, findedEnt);
|
|
break;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|
|
if (AllocPooledString(pClassname->GetName()) != AllocPooledString("event")
|
|
&& AllocPooledString(pClassname->GetName()) != AllocPooledString("removeentity")
|
|
&& AllocPooledString(pClassname->GetName()) != AllocPooledString("env_sun")
|
|
&& AllocPooledString(pClassname->GetName()) != AllocPooledString("lua")
|
|
&& AllocPooledString(pClassname->GetName()) != AllocPooledString("player"))
|
|
{
|
|
CBaseEntity *pEntity = CreateEntityByName(pClassname->GetName());
|
|
|
|
gEntList.NotifyCreateEntity(pEntity);
|
|
|
|
if (pEntity)
|
|
{
|
|
pEntity->SetAbsOrigin(Vector(0,0,0));
|
|
|
|
FOR_EACH_VALUE(pClassname, value)
|
|
{
|
|
//if (!Q_strcmp(value->GetName(), "origin"))
|
|
if (FStrEq(value->GetName(), "origin"))
|
|
{
|
|
UTIL_StringToVector(VecOrigin.Base(), value->GetString());
|
|
|
|
pEntity->SetAbsOrigin(VecOrigin);
|
|
}
|
|
else if (FStrEq(value->GetName(), "angle"))//if (!Q_strcmp(value->GetName(), "angle"))
|
|
{
|
|
|
|
UTIL_StringToVector(VecAngle.Base(), value->GetString());
|
|
|
|
pEntity->SetAbsAngles(QAngle(VecAngle.x, VecAngle.y, VecAngle.z));
|
|
DebugColorMsg("With Angles: ");
|
|
DebugColorMsg(value->GetString());
|
|
DebugColorMsg("\n");
|
|
}
|
|
|
|
//if (!Q_strcmp(value->GetName(), "x"))
|
|
if (FStrEq(value->GetName(), "x"))
|
|
{
|
|
VecOldOrigin.x = value->GetFloat("x", VecOldOrigin.x);
|
|
pEntity->SetAbsOrigin(VecOldOrigin);
|
|
}
|
|
|
|
//if (!Q_strcmp(value->GetName(), "y"))
|
|
if (FStrEq(value->GetName(), "y"))
|
|
{
|
|
VecOldOrigin.y = value->GetFloat("y", VecOldOrigin.y);
|
|
pEntity->SetAbsOrigin(VecOldOrigin);
|
|
}
|
|
|
|
//if (!Q_strcmp(value->GetName(), "z"))
|
|
if (FStrEq(value->GetName(), "z"))
|
|
{
|
|
VecOldOrigin.z = value->GetFloat("z", VecOldOrigin.z);
|
|
pEntity->SetAbsOrigin(VecOldOrigin);
|
|
}
|
|
|
|
//if (!Q_strcmp(value->GetName(), "roll"))
|
|
if (FStrEq(value->GetName(), "roll"))
|
|
{
|
|
AngOldOrigin[ROLL] = value->GetInt("yaw", AngOldOrigin[ROLL]);
|
|
pEntity->SetAbsAngles(AngOldOrigin);
|
|
}
|
|
|
|
//if (!Q_strcmp(value->GetName(), "yaw"))
|
|
if (FStrEq(value->GetName(), "yaw"))
|
|
{
|
|
AngOldOrigin[YAW] = value->GetInt("yaw", AngOldOrigin[YAW]);
|
|
pEntity->SetAbsAngles(AngOldOrigin);
|
|
}
|
|
|
|
//if (!Q_strcmp(value->GetName(), "pitch"))
|
|
if (FStrEq(value->GetName(), "pitch"))
|
|
{
|
|
AngOldOrigin[PITCH] = value->GetInt("pitch", AngOldOrigin[PITCH]);
|
|
pEntity->SetAbsAngles(AngOldOrigin);
|
|
}
|
|
|
|
|
|
}
|
|
|
|
KeyValues *pKeyValues = pClassname->FindKey("keyvalues");
|
|
if (pKeyValues)
|
|
{
|
|
FOR_EACH_VALUE(pKeyValues, pValues)
|
|
{
|
|
//if (!Q_strcmp(pValues->GetName(), "model") || !Q_strcmp(pValues->GetName(), "Model"))
|
|
if (FStrEq(pValues->GetName(), "model") || FStrEq(pValues->GetName(), "Model"))
|
|
{
|
|
CBaseEntity::PrecacheModel(pValues->GetString());
|
|
pEntity->SetModel(pValues->GetString());
|
|
continue;
|
|
}
|
|
|
|
pEntity->KeyValue(pValues->GetName(), pValues->GetString());
|
|
}
|
|
}
|
|
|
|
pEntity->Precache();
|
|
DispatchSpawn(pEntity);
|
|
|
|
if (pEntity)
|
|
{
|
|
FOR_EACH_VALUE(pClassname, value)
|
|
{
|
|
//if (!Q_strcmp(value->GetName(), "freeze"))
|
|
if (FStrEq(value->GetName(), "freeze"))
|
|
{
|
|
freeze = true;
|
|
pEntity->SetMoveType(MOVETYPE_NONE);
|
|
pEntity->SetSolid(SOLID_VPHYSICS);
|
|
pEntity->VPhysicsInitStatic();
|
|
}
|
|
|
|
//if (!Q_strcmp(value->GetName(), "velocity"))
|
|
if (FStrEq(value->GetName(), "velocity"))
|
|
{
|
|
//vel = true;
|
|
VelVector = Vector(0, 0, 0);
|
|
UTIL_StringToVector(VelVector.Base(), value->GetString());
|
|
pEntity->ApplyLocalVelocityImpulse(VelVector);
|
|
}
|
|
|
|
//if (!Q_strcmp(value->GetName(), "longrange"))
|
|
if (FStrEq(value->GetName(), "longrange"))
|
|
{
|
|
pEntity->AddSpawnFlags(SF_NPC_LONG_RANGE);
|
|
}
|
|
}
|
|
}
|
|
|
|
pEntity->Activate();
|
|
}
|
|
}
|
|
else if (AllocPooledString(pClassname->GetName()) == AllocPooledString("env_sun"))
|
|
{
|
|
|
|
FOR_EACH_VALUE(pClassname, value)
|
|
{
|
|
//if (!Q_strcmp(value->GetName(), "x"))
|
|
if (FStrEq(value->GetName(), "x"))
|
|
{
|
|
VecOldOrigin.x = value->GetFloat("x", VecOldOrigin.x);
|
|
}
|
|
|
|
//if (!Q_strcmp(value->GetName(), "y"))
|
|
if (FStrEq(value->GetName(), "y"))
|
|
{
|
|
VecOldOrigin.y = value->GetFloat("y", VecOldOrigin.y);
|
|
}
|
|
|
|
//if (!Q_strcmp(value->GetName(), "z"))
|
|
if (FStrEq(value->GetName(), "z"))
|
|
{
|
|
VecOldOrigin.z = value->GetFloat("z", VecOldOrigin.z);
|
|
}
|
|
|
|
//if (!Q_strcmp(value->GetName(), "roll"))
|
|
if (FStrEq(value->GetName(), "roll"))
|
|
{
|
|
AngOldOrigin[ROLL] = value->GetFloat();
|
|
}
|
|
|
|
//if (!Q_strcmp(value->GetName(), "yaw"))
|
|
if (FStrEq(value->GetName(), "yaw"))
|
|
{
|
|
AngOldOrigin[YAW] = value->GetFloat();
|
|
}
|
|
|
|
//if (!Q_strcmp(value->GetName(), "pitch"))
|
|
if (FStrEq(value->GetName(), "pitch"))
|
|
{
|
|
AngOldOrigin[PITCH] = value->GetFloat();
|
|
}
|
|
}
|
|
|
|
ParseCSMInfo(pClassname, VecOldOrigin, AngOldOrigin);
|
|
|
|
CBaseEntity *pEntity = CBaseEntity::CreateNoSpawn(pClassname->GetName(), VecOldOrigin, AngOldOrigin);
|
|
|
|
gEntList.NotifyCreateEntity(pEntity);
|
|
KeyValues *pKeyValues = pClassname->FindKey("keyvalues");
|
|
if (pKeyValues)
|
|
{
|
|
FOR_EACH_VALUE(pKeyValues, pValues)
|
|
{
|
|
//if (!Q_strcmp(pValues->GetName(), "model") || !Q_strcmp(pValues->GetName(), "Model"))
|
|
if (FStrEq(pValues->GetName(), "model") || FStrEq(pValues->GetName(), "Model"))
|
|
{
|
|
CBaseEntity::PrecacheModel(pValues->GetString());
|
|
pEntity->SetModel(pValues->GetString());
|
|
continue;
|
|
}
|
|
pEntity->KeyValue(pValues->GetName(), pValues->GetString());
|
|
}
|
|
}
|
|
|
|
pEntity->Precache();
|
|
|
|
DispatchSpawn(pEntity);
|
|
|
|
if (pEntity)
|
|
{
|
|
FOR_EACH_VALUE(pClassname, value)
|
|
{
|
|
//if (!Q_strcmp(value->GetName(), "freeze"))
|
|
if (FStrEq(value->GetName(), "freeze"))
|
|
{
|
|
freeze = true;
|
|
pEntity->SetMoveType(MOVETYPE_NONE);
|
|
pEntity->SetSolid(SOLID_VPHYSICS);
|
|
pEntity->VPhysicsInitStatic();
|
|
}
|
|
|
|
//if (!Q_strcmp(value->GetName(), "velocity"))
|
|
if (FStrEq(value->GetName(), "velocity"))
|
|
{
|
|
//vel = true;
|
|
VelVector = Vector(0, 0, 0);
|
|
UTIL_StringToVector(VelVector.Base(), value->GetString());
|
|
pEntity->ApplyLocalVelocityImpulse(VelVector);
|
|
}
|
|
|
|
//if (!Q_strcmp(value->GetName(), "longrange"))
|
|
if (FStrEq(value->GetName(), "longrange"))
|
|
{
|
|
pEntity->AddSpawnFlags(SF_NPC_LONG_RANGE);
|
|
}
|
|
}
|
|
}
|
|
pEntity->Activate();
|
|
}
|
|
}
|
|
} |