From c59a76a53d2381c4a5f87e0efc6b604ac8711cac Mon Sep 17 00:00:00 2001 From: Marco Cawthorne Date: Tue, 3 Oct 2023 11:04:46 -0700 Subject: [PATCH] NSMonster: add the ability to chase path_corners and things. --- src/shared/NSClientPlayer.qc | 4 +- src/shared/NSMonster.h | 3 ++ src/shared/NSMonster.qc | 29 +++++++++++++-- src/shared/NSNavAI.h | 6 +++ src/shared/NSNavAI.qc | 72 ++++++++++++++++++++++++++++-------- src/shared/defs.h | 2 +- src/vgui/ui.qc | 10 ++--- src/vgui/ui_menubutton.qc | 18 ++++++++- 8 files changed, 116 insertions(+), 28 deletions(-) diff --git a/src/shared/NSClientPlayer.qc b/src/shared/NSClientPlayer.qc index b95a7158..d53f3751 100644 --- a/src/shared/NSClientPlayer.qc +++ b/src/shared/NSClientPlayer.qc @@ -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); diff --git a/src/shared/NSMonster.h b/src/shared/NSMonster.h index 81b3bb06..a6369f93 100644 --- a/src/shared/NSMonster.h +++ b/src/shared/NSMonster.h @@ -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 }; diff --git a/src/shared/NSMonster.qc b/src/shared/NSMonster.qc index 8c30c078..648f1d44 100644 --- a/src/shared/NSMonster.qc +++ b/src/shared/NSMonster.qc @@ -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": diff --git a/src/shared/NSNavAI.h b/src/shared/NSNavAI.h index aa0fccd1..f502b455 100644 --- a/src/shared/NSNavAI.h +++ b/src/shared/NSNavAI.h @@ -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 }; diff --git a/src/shared/NSNavAI.qc b/src/shared/NSNavAI.qc index 429b4129..fe862fd2 100644 --- a/src/shared/NSNavAI.qc +++ b/src/shared/NSNavAI.qc @@ -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) { diff --git a/src/shared/defs.h b/src/shared/defs.h index 9bf14af5..9f5d8a31 100644 --- a/src/shared/defs.h +++ b/src/shared/defs.h @@ -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 diff --git a/src/vgui/ui.qc b/src/vgui/ui.qc index 13a44772..26f0f348 100644 --- a/src/vgui/ui.qc +++ b/src/vgui/ui.qc @@ -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; diff --git a/src/vgui/ui_menubutton.qc b/src/vgui/ui_menubutton.qc index eae60a9a..087c343c 100644 --- a/src/vgui/ui_menubutton.qc +++ b/src/vgui/ui_menubutton.qc @@ -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(); }