item_tfgoal: proper drop & return code, add support for 'pausetime', 'noise3' and 'noise4' spawn keys

This commit is contained in:
Marco Cawthorne 2022-07-10 13:07:35 -07:00
parent d375315027
commit e78ae3cf86
Signed by: eukara
GPG Key ID: CE2032F0A2882A22
3 changed files with 112 additions and 10 deletions

View File

@ -28,5 +28,7 @@ class TFCGameRules:CGameRules
virtual void(NSClientPlayer) PlayerRespawn;
virtual void(NSClientPlayer) PlayerDeath;
virtual void(NSClientPlayer) DropGoalItem;
virtual void(void) LevelNewParms;
};

View File

@ -22,6 +22,35 @@ TFCGameRules::IsTeamPlay(void)
return TRUE;
}
void
TFCGameRules::DropGoalItem(NSClientPlayer pp)
{
/* skip normal players */
if (!(pp.g_items & ITEM_GOALITEM))
return;
item_tfgoal target;
for (entity e = world; (e = find(e, ::classname, "item_tfgoal"));) {
target = (item_tfgoal)e;
/* item is still pick-upable */
if (target.solid != SOLID_NOT) {
print("the item is not picked up. \n");
continue;
}
/* that's us, yup */
if (target.m_eActivator == pp) {
target.DropReturnable(pp);
return;
}
}
print("^1WARNING: ^7Player marked as having impossible goal-item\n");
}
/* we check what fields have changed over the course of the frame and network
* only the ones that have actually changed */
void
@ -66,6 +95,7 @@ TFCGameRules::PlayerDeath(NSClientPlayer pp)
{
player pl = (player)pp;
DropGoalItem(pp);
pl.SetSolid(SOLID_NOT);
pl.SetMovetype(MOVETYPE_NONE);
pl.think = PlayerRespawn;

View File

@ -27,6 +27,7 @@ A gameplay pickup. It generally gets picked up and held.
"goal_no" : Identifer for this pickup, should be unique per map
"team_no" : Which team can use this item (0 means all)
"owned_by" : Which team owns this item (aka who can return it)
"pausetime" : How long the item will stay on ground for when dropped
"b_b" : Message to show to all when picked up
"message" : Message to show to the activator when picked up
"b_t" : Message to show to activator's team when picked up
@ -34,6 +35,9 @@ A gameplay pickup. It generally gets picked up and held.
"b_o" : Message to show to owner team when picked up
"non_owners_team_broadcast" : Message to show to everyone else?
"noise3" : Message to the owner team when the item is returned
"noise4" : Message to the other team when the item is returned
"speak" : VOX announcement to everyone when picked up
"AP_speak" : VOX announcement to activator when picked up
"team_speak" : VOX announcement to activator's team when picked up
@ -48,6 +52,12 @@ Duplicate keys:
*/
typedef enum
{
GISTATUS_HOME,
GISTATUS_DROPPED
} goalitem_status_e;
class item_tfgoal:NSRenderableEntity
{
float m_dItemID;
@ -58,6 +68,8 @@ class item_tfgoal:NSRenderableEntity
string m_strSound;
player m_eActivator;
goalitem_status_e m_status;
/* visual fluff */
string m_msgAll; /* global */
string m_msgActivator; /* AP */
@ -73,12 +85,50 @@ class item_tfgoal:NSRenderableEntity
string m_voxOwnerTeam; /* owner team */
string m_voxNonOwnerTeams; /* non-owner team */
string m_returnTeam;
string m_returnOwner;
float m_flPausetime;
void(void) item_tfgoal;
virtual void(entity) Touch;
virtual void(void) Respawn;
virtual void(string, string) SpawnKey;
virtual void(NSClientPlayer) DropReturnable;
virtual void(void) TeamOwnerReturns;
virtual void(void) Spawned;
};
void
item_tfgoal::DropReturnable(NSClientPlayer pp)
{
player pl = (player)pp;
/* make it available again, put it exactly where we died */
Respawn();
SetOrigin(pl.origin);
/* untag it from the player */
pl.g_items &= ~ITEM_GOALITEM;
/* return after N secs */
think = TeamOwnerReturns;
nextthink = time + m_flPausetime;
}
void
item_tfgoal::TeamOwnerReturns(void)
{
Respawn();
for (entity e = world; (e = find(e, ::classname, "player")); ) {
if (e.team == m_iTeamUses)
env_message_single(e, m_returnTeam);
else if (e.team == m_iTeamOwner)
env_message_single(e, m_returnOwner);
}
}
void
item_tfgoal::Touch(entity eToucher)
{
@ -88,6 +138,15 @@ item_tfgoal::Touch(entity eToucher)
player pl = (player)eToucher;
/* if it's dropped, just let the other team return it...
otherwise let the other teams pick it up as normal */
if (m_status == GISTATUS_DROPPED) {
if (m_iTeamOwner == pl.team) {
TeamOwnerReturns();
return;
}
}
/* team filter */
if (m_iTeamUses)
if (m_iTeamUses != pl.team)
@ -147,10 +206,9 @@ item_tfgoal::Touch(entity eToucher)
void
item_tfgoal::Respawn(void)
{
solid = SOLID_TRIGGER;
movetype = MOVETYPE_NONE;
SetModel(GetSpawnModel());
setsize(this, VEC_HULL_MIN, VEC_HULL_MAX);
SetSize(VEC_HULL_MIN, VEC_HULL_MAX);
SetSolid(SOLID_TRIGGER);
SetOrigin(GetSpawnOrigin());
m_eActivator = __NULL__;
}
@ -215,20 +273,32 @@ item_tfgoal::SpawnKey(string strKey, string strValue)
case "non_owners_team_speak":
m_voxNonOwnerTeams = strValue; /* non-owner team */
break;
case "noise4":
m_returnTeam = strValue;
break;
case "noise3":
m_returnOwner = strValue;
break;
case "pausetime":
m_flPausetime = stof(strValue);
break;
default:
super::SpawnKey(strKey, strValue);
break;
}
}
void
item_tfgoal::Spawned(void)
{
super::Spawned();
precache_sound(m_strSound);
}
void
item_tfgoal::item_tfgoal(void)
{
for (int i = 1; i < (tokenize(__fullspawndata) - 1); i += 2) {
SpawnKey(argv(i), argv(i+1));
}
precache_sound(m_strSound);
super::NSRenderableEntity();
item_tfgoal::Respawn();
m_status = GISTATUS_HOME;
m_returnOwner = m_returnTeam = __NULL__;
m_flPausetime = 0;
}