NSMonster: add the ability to chase path_corners and things.

This commit is contained in:
Marco Cawthorne 2023-10-03 11:04:46 -07:00
parent 19d6f22dc4
commit c59a76a53d
Signed by: eukara
GPG key ID: CE2032F0A2882A22
8 changed files with 116 additions and 28 deletions

View file

@ -698,7 +698,7 @@ NSClientPlayer::Save(float handle)
SaveFloat(handle, "weapontime", weapontime);
SaveInt(handle, "g_items", g_items);
SaveFloat(handle, "activeweapon", activeweapon);
SaveFloat(handle, "vehicle", num_for_edict(vehicle));
SaveEntity(handle, "vehicle", vehicle);
}
void
@ -775,7 +775,7 @@ NSClientPlayer::Restore(string strKey, string strValue)
activeweapon = ReadFloat(strValue);
break;
case "vehicle":
vehicle = edict_num(ReadFloat(strValue));
vehicle = ReadEntity(strValue);
break;
default:
super::Restore(strKey, strValue);

View file

@ -430,6 +430,8 @@ public:
nonvirtual int GetTriggerCondition(void);
/** Call to trigger their targets manually. */
virtual void TriggerTargets(void);
virtual void Trigger(entity, triggermode_t);
#endif
#ifdef CLIENT
@ -572,6 +574,7 @@ private:
nonvirtual void _LerpTurnToPos(vector);
nonvirtual void _LerpTurnToYaw(vector);
virtual void _Alerted(void);
nonvirtual void _ChaseAfterSpawn(void);
#endif
};

View file

@ -816,7 +816,11 @@ void
NSMonster::_LerpTurnToPos(vector turnPos)
{
vector vecWishAngle = vectoangles(turnPos - origin);
#if 1
_LerpTurnToYaw(vecWishAngle);
#else
angles[1] = input_angles[1] = v_angle[1] = vecWishAngle[1];
#endif
}
@ -1225,7 +1229,7 @@ NSMonster::WalkRoute(void)
if (GetState() == MONSTER_AIMING && m_eEnemy) {
input_angles = vectoangles(m_eEnemy.origin - origin);
input_angles[0] = input_angles[2] = 0;
} else if (m_iNodes && (GetState() == MONSTER_IDLE || GetState() == MONSTER_ALERT)) {
} else if ((m_iNodes || m_pathTarget) && (GetState() == MONSTER_IDLE || GetState() == MONSTER_ALERT)) {
input_angles = GetRouteDirection();
input_angles[0] = input_angles[2] = 0;
input_movevalues = GetRouteMovevalues() * m_flSequenceSpeed;
@ -1730,6 +1734,25 @@ NSMonster::Respawn(void)
SetState(MONSTER_DEAD);
SetFrame(_m_flFrame);
}
/* automatically start */
if (!targetname)
if (HasTriggerTarget() == true) {
ScheduleThink(_ChaseAfterSpawn, 0.0f);
}
}
void
NSMonster::Trigger(entity act, triggermode_t state)
{
ChasePath(GetTriggerTarget());
m_flSequenceSpeed = m_flWalkSpeed;
}
void
NSMonster::_ChaseAfterSpawn(void)
{
Trigger(this, TRIG_TOGGLE);
}
void
@ -1882,10 +1905,10 @@ NSMonster::SpawnKey(string strKey, string strValue)
m_iAlliance = ReadInt(strValue);
break;
case "health":
base_health = Skill_GetDefValue(strValue);
base_health = Skill_GetDefValue(ReadString(strValue));
break;
case "leap_damage":
m_flLeapDamage = Skill_GetDefValue(strValue);
m_flLeapDamage = Skill_GetDefValue(ReadString(strValue));
break;
/* simple tweaks */
case "dead":

View file

@ -42,6 +42,8 @@ private:
nodeslist_t *m_pRoute;
vector m_vecLastNode;
vector m_vecTurnAngle;
string m_pathTarget;
NSEntity m_pathEntity;
/* These are defined in side defs\*.def, ammo_types and ammo_names */
int m_iAmmoTypes[MAX_AMMO_TYPES];
@ -71,5 +73,9 @@ public:
virtual void CheckRoute(void);
/** When called, will plot a route to a given world coordinate and start moving. */
virtual void RouteToPosition(vector);
/** When called, will start following a path_corner */
virtual void ChasePath(string startPath);
/** Internal use only. Called every frame to see our route progression. */
virtual void CheckRoute_Path(void);
#endif
};

View file

@ -86,12 +86,35 @@ NSNavAI::RouteEnded(void)
}
void
NSNavAI::CheckRoute_Path(void)
{
float flDist = floor(vlen(m_pathEntity.GetOrigin() - GetOrigin()));
//print(sprintf("Check Path! %f\n", flDist));
/* close enough...? */
if (flDist < 80) {
NSNavAI_Log("^2%s::^3CheckRoute_Path^7: " \
"reached path node %s", classname, m_pathTarget);
m_pathTarget = m_pathEntity.target;
m_pathEntity = (NSEntity)m_pathEntity.GetTargetEntity();
velocity = [0,0,0]; /* clamp friction */
}
}
void
NSNavAI::CheckRoute(void)
{
float flDist;
vector evenpos;
if (m_pathTarget) {
CheckRoute_Path();
return;
}
if (!m_iNodes)
return;
@ -194,28 +217,39 @@ NSNavAI::GetRouteMovevalues(void)
{
vector vecDirection;
if (!m_iNodes)
return [0,0,0];
if (m_pathTarget) {
vecDirection = normalize(m_pathEntity.GetOrigin() - GetOrigin());
} else {
if (!m_iNodes)
return [0,0,0];
if (m_iCurNode < 0)
vecDirection = normalize(m_vecLastNode - origin);
else
vecDirection = normalize(m_pRoute[m_iCurNode].dest - origin);
if (m_iCurNode < 0)
vecDirection = normalize(m_vecLastNode - GetOrigin());
else
vecDirection = normalize(m_pRoute[m_iCurNode].dest - GetOrigin());
}
makevectors(angles);
makevectors(input_angles);
return [v_forward * vecDirection, v_right * vecDirection, v_up * vecDirection];
}
vector
NSNavAI::GetRouteDirection(void)
{
if (!m_iNodes)
return angles;
if (m_pathTarget) {
return vectoangles(m_pathEntity.GetOrigin() - GetOrigin());
} else {
if (m_iCurNode < 0)
return vectoangles(m_vecLastNode - origin);
else
return vectoangles(m_pRoute[m_iCurNode].dest - origin);
if (!m_iNodes) {
return angles;
}
if (m_iCurNode < 0) {
return vectoangles(m_vecLastNode - origin);
} else {
return vectoangles(m_pRoute[m_iCurNode].dest - origin);
}
}
}
void
@ -235,11 +269,11 @@ NSNavAI::RouteToPosition(vector destination)
/* can we walk directly to our target destination? */
if (trace_fraction == 1.0) {
NSNavAI_Log("^2%s::^3RouteToPosition^7: " \
"Walking directly to last node", classname);
"Walking directly to last node", p.classname);
p.m_iCurNode = -1;
} else {
NSNavAI_Log("^2%s::^3RouteToPosition^7: " \
"Path obstructed, calculating route", classname);
"Path obstructed, calculating route", p.classname);
/* run through all nodes, mark the closest direct path possible */
for (int i = 0; i < p.m_iNodes; i++) {
@ -273,6 +307,14 @@ NSNavAI::RouteToPosition(vector destination)
}
}
void
NSNavAI::ChasePath(string startPath)
{
m_pathTarget = startPath;
m_pathEntity = (NSEntity)find(world, ::targetname, m_pathTarget);
NSNavAI_Log("Actor %S chase Path set to %S\n", netname, m_pathEntity.targetname);
}
void
NSNavAI::RouteClear(void)
{

View file

@ -182,7 +182,7 @@ Empty(void)
void Util_Destroy(void);
string Util_TimeToString(float fTime);
int Util_IsTeamplay(void);
bool Util_IsTeamplay(void);
bool Util_IsPaused(void);
__wrap void

View file

@ -35,22 +35,22 @@ font_s g_fntDefault;
var int g_vguiWidgetCount;
/** Return whether a VGUI panel is active on the 2D overlay level. */
int
bool
VGUI_Active(void)
{
return (g_vguiWidgetCount > 0) ? TRUE : FALSE;
return (g_vguiWidgetCount > 0i) ? (true) : (false);
}
/** Returns whether our mouse cursor is in a specific region of the screen. */
int
bool
Util_MouseAbove(vector vecMousePos, vector vecPos, vector vecSize)
{
if (vecMousePos[0] >= vecPos[0] && vecMousePos[0] <= vecPos[0] + vecSize[0]) {
if (vecMousePos[1] >= vecPos[1] && vecMousePos[1] <= vecPos[1] + vecSize[1]) {
return (1);
return (true);
}
}
return (0);
return (false);
}
.bool isVGUI;

View file

@ -117,6 +117,20 @@ bool
VGUIMenuButton::Input (float flEVType, float flKey, float flChar, float flDevID)
{
bool ret = false;
bool mouseHover = false;
if (Util_MouseAbove(g_vecMousePos, m_parent.m_vecOrigin + m_vecOrigin, m_vecSize)) {
mouseHover = true;
}
if (mouseHover == true && HasFlag(BUTTON_HOVER) == false) {
FlagAdd(MBUTTON_HOVER);
// OnMouseEntered();
} else if (HasFlag(BUTTON_HOVER) && mouseHover == false) {
FlagRemove(MBUTTON_HOVER);
// OnMouseExited();
}
// If we're not ingame
if (clientstate() == 2 && !g_background) {
@ -131,14 +145,14 @@ VGUIMenuButton::Input (float flEVType, float flKey, float flChar, float flDevID)
if (flEVType == IE_KEYDOWN) {
if (flKey == K_MOUSE1) {
if (Util_MouseAbove(g_vecMousePos, m_parent.m_vecOrigin + m_vecOrigin, m_vecSize)) {
if (mouseHover == true) {
m_iFlags |= MBUTTON_DOWN;
ret = true;
}
}
} else if (flEVType == IE_KEYUP) {
if (flKey == K_MOUSE1) {
if (m_iFlags & MBUTTON_DOWN && Util_MouseAbove(g_vecMousePos, m_parent.m_vecOrigin + m_vecOrigin, m_vecSize)) {
if (m_iFlags & MBUTTON_DOWN && mouseHover == true) {
if (tmpVGUIMenuButton1) {
tmpVGUIMenuButton1();
}