Bot improvements, some more work done on the grenades.
This commit is contained in:
parent
3f636e0a3d
commit
29281e8101
14 changed files with 270 additions and 35 deletions
|
@ -17,20 +17,22 @@ TFCHallucination_Insert(vector viewPosition, vector viewDirection)
|
|||
traceline(viewPosition, halluPos, MOVE_NORMAL, pSeat->m_ePlayer);
|
||||
halluPos = trace_endpos;
|
||||
|
||||
makevectors(viewDirection);
|
||||
makevectors([0, viewDirection[1], 0]);
|
||||
|
||||
r = (int)(floor(random(0, 8)));
|
||||
r = (int)(floor(random(0, 10)));
|
||||
|
||||
switch (r) {
|
||||
case 1:
|
||||
case 1: /* blood splats */
|
||||
for (int i = 0; i < 3; i++) {
|
||||
halluPos = viewPosition;
|
||||
halluPos += v_forward * random(8, 64);
|
||||
halluPos += v_up * random(-64, 64);
|
||||
halluPos += v_right * random(-64, 64);
|
||||
FX_Blood(halluPos, [1,0,0]);
|
||||
halluPos += v_forward * random(8, 128);
|
||||
halluPos += v_up * random(-64, 128);
|
||||
halluPos += v_right * random(-256, 256);
|
||||
}
|
||||
pointsound(viewPosition, "weapons/cbar_hitbod1.wav", 1, ATTN_NORM);
|
||||
break;
|
||||
case 2:
|
||||
case 2: /* explosions */
|
||||
pointparticles(particleeffectnum("fx_explosion.main"), halluPos, [0,0,0], 1);
|
||||
pSeat->m_flShakeDuration = 2;
|
||||
pSeat->m_flShakeAmp = 5.0;
|
||||
|
@ -38,46 +40,105 @@ TFCHallucination_Insert(vector viewPosition, vector viewDirection)
|
|||
pSeat->m_flShakeTime = 2;
|
||||
pointsound(halluPos, sprintf("weapons/explode%d.wav", floor(random() * 2) + 3), 1, ATTN_NORM);
|
||||
break;
|
||||
case 3:
|
||||
case 3: /* shotgun impact */
|
||||
traceline(viewPosition, halluPos + (v_forward * 1024), MOVE_NORMAL, pSeat->m_ePlayer);
|
||||
SurfData_Impact(world, trace_endpos, [0,0,0]);
|
||||
DecalGroups_Place("Impact.Shot", trace_endpos);
|
||||
pointsound(halluPos, "weapons/sbarrel1.wav", 1, ATTN_NORM);
|
||||
break;
|
||||
case 4:
|
||||
case 4: /* being hit by a crowbar */
|
||||
pSeat->m_flShakeDuration = 1;
|
||||
pSeat->m_flShakeAmp = 1.0;
|
||||
pSeat->m_flShakeFreq = 2;
|
||||
pSeat->m_flShakeTime = 2;
|
||||
pointsound(halluPos, "weapons/cbar_hitbod1.wav", 1, ATTN_NORM);
|
||||
break;
|
||||
case 5:
|
||||
case 5: /* sniper impact */
|
||||
traceline(viewPosition, halluPos + (v_forward * 1024), MOVE_NORMAL, pSeat->m_ePlayer);
|
||||
SurfData_Impact(world, trace_endpos, [0,0,0]);
|
||||
DecalGroups_Place("Impact.Shot", trace_endpos);
|
||||
pointsound(halluPos, "weapons/sniper.wav", 1, ATTN_NORM);
|
||||
break;
|
||||
case 6:
|
||||
case 6: /* nailgun impact */
|
||||
traceline(viewPosition, halluPos + (v_forward * 1024), MOVE_NORMAL, pSeat->m_ePlayer);
|
||||
SurfData_Impact(world, trace_endpos, [0,0,0]);
|
||||
DecalGroups_Place("Impact.Shot", trace_endpos);
|
||||
pointsound(halluPos, "weapons/airgun_1.wav", 1, ATTN_NORM);
|
||||
break;
|
||||
case 7:
|
||||
case 7: /* nade thrown about */
|
||||
int nadeSelection = (int)floor(random(0, 8));
|
||||
NSRenderableEntity eNade = spawn(NSRenderableEntity);
|
||||
eNade.SetModel("models/w_grenade.mdl");
|
||||
eNade.SetOrigin(halluPos);
|
||||
|
||||
switch (nadeSelection) {
|
||||
case 1:
|
||||
eNade.SetModel("models/emp_grenade.mdl");
|
||||
break;
|
||||
case 2:
|
||||
eNade.SetModel("models/spy_grenade.mdl");
|
||||
break;
|
||||
case 3:
|
||||
eNade.SetModel("models/napalm.mdl");
|
||||
break;
|
||||
case 4:
|
||||
eNade.SetModel("models/mirv_grenade.mdl");
|
||||
break;
|
||||
case 5:
|
||||
eNade.SetModel("models/ngrenade.mdl");
|
||||
break;
|
||||
case 6:
|
||||
eNade.SetModel("models/conc_grenade.mdl");
|
||||
break;
|
||||
case 7:
|
||||
eNade.SetModel("models/caltrop.mdl");
|
||||
break;
|
||||
default:
|
||||
eNade.SetModel("models/w_grenade.mdl");
|
||||
}
|
||||
eNade.SetOrigin(viewPosition + (v_forward * -32) + (v_right * random(-64, 64)));
|
||||
eNade.SetMovetype(MOVETYPE_BOUNCE);
|
||||
eNade.SetSolid(SOLID_NOT);
|
||||
eNade.SetGravity(1.0f);
|
||||
eNade.SetVelocity(v_forward * random(-320,320) + v_right * random(-64, 64) + v_up * 200);
|
||||
eNade.SetVelocity(v_forward * 300 + v_right * random(-64, 64) + v_up * 200);
|
||||
eNade.SetAngularVelocity([300, 300, 300]);
|
||||
eNade.SetAngles(vectoangles(eNade.GetVelocity()));
|
||||
eNade.ScheduleThink(eNade.Destroy, 5.0f);
|
||||
eNade.drawmask = MASK_ENGINE;
|
||||
pointsound(halluPos, "weapons/grenade_hit3.wav", 1, ATTN_NORM);
|
||||
break;
|
||||
case 8: /* nail shot around */
|
||||
halluPos = viewPosition + (v_forward * -32) + (v_right * random(-64, 64));
|
||||
NSRenderableEntity eNail = spawn(NSRenderableEntity);
|
||||
eNail.SetModel("models/nail.mdl");
|
||||
eNail.SetOrigin(halluPos);
|
||||
eNail.SetMovetype(MOVETYPE_NOCLIP);
|
||||
eNail.SetSolid(SOLID_NOT);
|
||||
eNail.SetGravity(1.0f);
|
||||
eNail.SetVelocity(v_forward * 800 + v_right * random(-800, 800));
|
||||
eNail.SetAngles(vectoangles(eNail.GetVelocity()));
|
||||
eNail.ScheduleThink(eNail.Destroy, 5.0f);
|
||||
eNail.drawmask = MASK_ENGINE;
|
||||
pointsound(halluPos, "weapons/airgun_1.wav", 1, ATTN_NORM);
|
||||
break;
|
||||
case 9: /* fire eruption */
|
||||
/* get it close to the player than usual */
|
||||
halluPos = viewPosition;
|
||||
halluPos += v_forward * random(8, 64);
|
||||
halluPos += v_up * random(-16, 16);
|
||||
halluPos += v_right * random(-64, 64);
|
||||
|
||||
env_sprite eFired = spawn(env_sprite);
|
||||
eFired.SetOrigin(halluPos);
|
||||
eFired.SetModel("sprites/fthrow.spr");
|
||||
eFired.SetMaxFrame(modelframecount(eFired.modelindex));
|
||||
eFired.SetFramerate(20);
|
||||
eFired.SetLoopFlag(false);
|
||||
eFired.SetRenderMode(RM_ADDITIVE);
|
||||
eFired.SetRenderAmt(1.0f);
|
||||
eFired.nextthink = time + 0.05f;
|
||||
pointsound(halluPos, "weapons/flmfire2.wav", 1, ATTN_NORM);
|
||||
break;
|
||||
default:
|
||||
/* rocket launcher firing */
|
||||
pointsound(halluPos, "weapons/rocketfire1.wav", 1, ATTN_NORM);
|
||||
break;
|
||||
}
|
||||
|
|
21
src/server/bot.qc
Normal file
21
src/server/bot.qc
Normal file
|
@ -0,0 +1,21 @@
|
|||
class
|
||||
TFCBot:bot
|
||||
{
|
||||
void TFCBot(void);
|
||||
|
||||
//virtual void CreateObjective(void);
|
||||
};
|
||||
|
||||
void
|
||||
TFCBot::TFCBot(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#if 0
|
||||
void
|
||||
TFCBot::CreateObjective(void)
|
||||
{
|
||||
super:: CreateObjective();
|
||||
}
|
||||
#endif
|
|
@ -19,6 +19,11 @@
|
|||
#include "../../../valve/src/server/flashlight.h"
|
||||
#include "sentry.h"
|
||||
|
||||
var bool g_tfcHasBlueTeam = false;
|
||||
var bool g_tfcHasRedTeam = false;
|
||||
var bool g_tfcHasYellowTeam = false;
|
||||
var bool g_tfcHasGreenTeam = false;
|
||||
|
||||
/* returns if a player already has a teleporter/exit built */
|
||||
bool
|
||||
TFC_ExistsForPlayer(entity pl, string cname)
|
||||
|
|
|
@ -18,6 +18,7 @@ class TFCGameRules:CGameRules
|
|||
{
|
||||
void(void) TFCGameRules;
|
||||
|
||||
virtual bool ConsoleCommand(NSClientPlayer, string);
|
||||
virtual bool IsTeamplay(void);
|
||||
|
||||
virtual void PlayerConnect(NSClientPlayer);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 Marco Cawthorne <marco@icculus.org>
|
||||
* Copyright (c) 2016-2023 Marco Cawthorne <marco@icculus.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -14,6 +14,52 @@
|
|||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
void CSEv_TeamJoin_f(float f);
|
||||
void CSEv_ClassJoin_f(float f);
|
||||
|
||||
void
|
||||
TFCGameRules_BotJoin(void)
|
||||
{
|
||||
spawnfunc_TFCBot();
|
||||
CSEv_TeamJoin_f(0);
|
||||
CSEv_ClassJoin_f(0);
|
||||
}
|
||||
|
||||
void
|
||||
TFCGameRules::TFCGameRules(void)
|
||||
{
|
||||
/* wipe the serverinfo clean */
|
||||
forceinfokey(world, "teams", "0");
|
||||
forceinfokey(world, "team_1", "");
|
||||
forceinfokey(world, "team_2", "");
|
||||
forceinfokey(world, "team_3", "");
|
||||
forceinfokey(world, "team_4", "");
|
||||
forceinfokey(world, "teamscore_1", "");
|
||||
forceinfokey(world, "teamscore_2", "");
|
||||
forceinfokey(world, "teamscore_3", "");
|
||||
forceinfokey(world, "teamscore_4", "");
|
||||
}
|
||||
|
||||
bool
|
||||
TFCGameRules::ConsoleCommand(NSClientPlayer pp, string cmd)
|
||||
{
|
||||
tokenize(cmd);
|
||||
|
||||
switch (argv(0)) {
|
||||
case "bot_add":
|
||||
entity bot_ent = Bot_AddQuick();
|
||||
if (bot_ent) {
|
||||
bot_ent.think = TFCGameRules_BotJoin;
|
||||
bot_ent.nextthink = time;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return (false);
|
||||
}
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
bool
|
||||
TFCGameRules::IsTeamplay(void)
|
||||
{
|
||||
|
@ -182,6 +228,7 @@ TFCGameRules::InitPostEnts(void)
|
|||
team_count += 1;
|
||||
forceinfokey(world, sprintf("team_%i", team_count), "Blue");
|
||||
forceinfokey(world, sprintf("teamscore_%i", team_count), "0");
|
||||
g_tfcHasBlueTeam = true;
|
||||
}
|
||||
|
||||
e = find(world, ::classname, "info_teamspawn_red");
|
||||
|
@ -189,6 +236,7 @@ TFCGameRules::InitPostEnts(void)
|
|||
team_count += 1;
|
||||
forceinfokey(world, sprintf("team_%i", team_count), "Red");
|
||||
forceinfokey(world, sprintf("teamscore_%i", team_count), "0");
|
||||
g_tfcHasRedTeam = true;
|
||||
}
|
||||
|
||||
e = find(world, ::classname, "info_teamspawn_green");
|
||||
|
@ -196,6 +244,7 @@ TFCGameRules::InitPostEnts(void)
|
|||
team_count += 1;
|
||||
forceinfokey(world, sprintf("team_%i", team_count), "Green");
|
||||
forceinfokey(world, sprintf("teamscore_%i", team_count), "0");
|
||||
g_tfcHasGreenTeam = true;
|
||||
}
|
||||
|
||||
e = find(world, ::classname, "info_teamspawn_yellow");
|
||||
|
@ -203,22 +252,8 @@ TFCGameRules::InitPostEnts(void)
|
|||
team_count += 1;
|
||||
forceinfokey(world, sprintf("team_%i", team_count), "Yellow");
|
||||
forceinfokey(world, sprintf("teamscore_%i", team_count), "0");
|
||||
g_tfcHasYellowTeam = true;
|
||||
}
|
||||
|
||||
forceinfokey(world, "teams", itos(team_count));
|
||||
}
|
||||
|
||||
void
|
||||
TFCGameRules::TFCGameRules(void)
|
||||
{
|
||||
/* wipe the serverinfo clean */
|
||||
forceinfokey(world, "teams", "0");
|
||||
forceinfokey(world, "team_1", "");
|
||||
forceinfokey(world, "team_2", "");
|
||||
forceinfokey(world, "team_3", "");
|
||||
forceinfokey(world, "team_4", "");
|
||||
forceinfokey(world, "teamscore_1", "");
|
||||
forceinfokey(world, "teamscore_2", "");
|
||||
forceinfokey(world, "teamscore_3", "");
|
||||
forceinfokey(world, "teamscore_4", "");
|
||||
}
|
||||
|
|
|
@ -47,6 +47,8 @@ info_player_teamspawn::info_player_teamspawn(void)
|
|||
classname = "info_teamspawn_green";
|
||||
break;
|
||||
}
|
||||
|
||||
botinfo = BOTINFO_SPAWNPOINT;
|
||||
}
|
||||
|
||||
CLASSEXPORT(i_p_t, info_player_teamspawn)
|
||||
|
|
|
@ -179,6 +179,7 @@ info_tfgoal::Touch(entity eToucher)
|
|||
|
||||
/* mark as removed on the player end, too. */
|
||||
pl.g_items &= ~ITEM_GOALITEM;
|
||||
pl.flags &= ~FL_GOALITEM;
|
||||
forceinfokey(pl, "*goalitem_t", "");
|
||||
}
|
||||
|
||||
|
@ -286,6 +287,10 @@ info_tfgoal::Respawn(void)
|
|||
SetModel(GetSpawnModel());
|
||||
SetSize(VEC_HULL_MIN, VEC_HULL_MAX);
|
||||
SetOrigin(GetSpawnOrigin());
|
||||
team = m_iTeamUses;
|
||||
|
||||
if (frags > 0)
|
||||
botinfo = BOTINFO_TEAM_GOALCAPTURE;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -446,6 +451,10 @@ i_t_g::Respawn(void)
|
|||
SetModel(GetSpawnModel());
|
||||
SetOrigin(GetSpawnOrigin());
|
||||
Hide();
|
||||
team = m_iTeamUses;
|
||||
|
||||
if (frags > 0)
|
||||
botinfo = BOTINFO_TEAM_GOALCAPTURE;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -167,6 +167,7 @@ item_armor::Respawn(void)
|
|||
SetSolid(SOLID_TRIGGER);
|
||||
SetOrigin(GetSpawnOrigin());
|
||||
DropToFloor();
|
||||
botinfo = BOTINFO_ARMOR;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -90,6 +90,7 @@ item_healthkit::Respawn(void)
|
|||
SetSolid(SOLID_TRIGGER);
|
||||
SetOrigin(GetSpawnOrigin());
|
||||
DropToFloor();
|
||||
botinfo = BOTINFO_HEALTH;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -158,6 +158,7 @@ item_tfgoal::Touch(entity eToucher)
|
|||
|
||||
Disappear();
|
||||
pl.g_items |= ITEM_GOALITEM;
|
||||
pl.flags |= FL_GOALITEM;
|
||||
forceinfokey(pl, "*goalitem_t", itos(m_iTeamOwner));
|
||||
|
||||
m_eActivator = pl;
|
||||
|
@ -221,6 +222,16 @@ item_tfgoal::Respawn(void)
|
|||
ReleaseThink();
|
||||
m_status = GISTATUS_HOME;
|
||||
|
||||
/* helps with bots */
|
||||
team = m_iTeamOwner;
|
||||
|
||||
/* it's either a goal item... or some other pickup */
|
||||
if (m_dItemID) {
|
||||
botinfo = BOTINFO_TEAM_GOALITEM;
|
||||
} else {
|
||||
botinfo = BOTINFO_AMMO;
|
||||
}
|
||||
|
||||
if (m_iTeamOwner) {
|
||||
SetRenderAmt(1.0f);
|
||||
SetRenderFX(RFX_GLOWSHELL);
|
||||
|
|
|
@ -103,6 +103,28 @@ TFCNade_ThrowConcussion(player pl)
|
|||
}
|
||||
}
|
||||
|
||||
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
|
||||
WriteByte(MSG_MULTICAST, EV_BEAMCYLINDER);
|
||||
WriteCoord(MSG_MULTICAST, self.origin[0]);
|
||||
WriteCoord(MSG_MULTICAST, self.origin[1]);
|
||||
WriteCoord(MSG_MULTICAST, self.origin[2]);
|
||||
WriteCoord(MSG_MULTICAST, 0);
|
||||
WriteCoord(MSG_MULTICAST, 128);
|
||||
WriteCoord(MSG_MULTICAST, 0);
|
||||
WriteShort(MSG_MULTICAST, getmodelindex("sprites/shockwave.spr"));
|
||||
WriteByte(MSG_MULTICAST, 0);
|
||||
WriteByte(MSG_MULTICAST, 10);
|
||||
WriteByte(MSG_MULTICAST, 2);
|
||||
WriteByte(MSG_MULTICAST, 16);
|
||||
WriteByte(MSG_MULTICAST, 0);
|
||||
WriteByte(MSG_MULTICAST, 255);
|
||||
WriteByte(MSG_MULTICAST, 255);
|
||||
WriteByte(MSG_MULTICAST, 255);
|
||||
WriteByte(MSG_MULTICAST, 255);
|
||||
WriteByte(MSG_MULTICAST, 0);
|
||||
msg_entity = self;
|
||||
multicast(self.origin, MULTICAST_PVS);
|
||||
|
||||
NSEntity::Destroy();
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,9 @@ func_nogrenades.qc
|
|||
|
||||
vox.qc
|
||||
../../../valve/src/server/items.qc
|
||||
../../../src/botlib/include.src
|
||||
bot.qc
|
||||
|
||||
info_player_teamspawn.qc
|
||||
item_tfgoal.qc
|
||||
info_tfgoal.qc
|
||||
|
@ -46,8 +49,6 @@ server.qc
|
|||
../../../valve/src/server/flashlight.qc
|
||||
../../../valve/src/server/modelevent.qc
|
||||
|
||||
../../../src/botlib/include.src
|
||||
|
||||
spawn.qc
|
||||
|
||||
../../../src/server/include.src
|
||||
|
|
|
@ -14,11 +14,77 @@
|
|||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
float
|
||||
TFCTeamJoin_SmallestTeam(int blue, int red, int yellow, int green)
|
||||
{
|
||||
while (blue > 0i || red > 0i || yellow > 0i || green > 0i) {
|
||||
/* the first team that goes to 0, gets picked. */
|
||||
if (blue <= 0i)
|
||||
return 1;
|
||||
else if (red <= 0i)
|
||||
return 2;
|
||||
else if (yellow <= 0i)
|
||||
return 3;
|
||||
else if (green <= 0i)
|
||||
return 4;
|
||||
|
||||
blue--;
|
||||
red--;
|
||||
yellow--;
|
||||
green--;
|
||||
}
|
||||
|
||||
/* the first team that goes to 0, gets picked. */
|
||||
if (blue == 0i)
|
||||
return 1;
|
||||
else if (red == 0i)
|
||||
return 2;
|
||||
else if (yellow == 0i)
|
||||
return 3;
|
||||
else if (green == 0i)
|
||||
return 4;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
CSEv_TeamJoin_f(float f)
|
||||
{
|
||||
player pl = (player)self;
|
||||
|
||||
/* random... */
|
||||
if (f == 0) {
|
||||
int bluePlayers = 0i;
|
||||
int redPlayers = 0i;
|
||||
int yellowPlayers = 0i;
|
||||
int greenPlayers = 0i;
|
||||
|
||||
/* hack to get it to never pick this team */
|
||||
if (g_tfcHasBlueTeam == false)
|
||||
bluePlayers = (int)cvar("sv_playerslots");
|
||||
if (g_tfcHasRedTeam == false)
|
||||
redPlayers = (int)cvar("sv_playerslots");
|
||||
if (g_tfcHasYellowTeam == false)
|
||||
yellowPlayers = (int)cvar("sv_playerslots");
|
||||
if (g_tfcHasGreenTeam == false)
|
||||
greenPlayers = (int)cvar("sv_playerslots");
|
||||
|
||||
/* count all valid players within each team */
|
||||
for (entity e = world; (e = find(e, ::classname, "player"));) {
|
||||
if (e.team == 1)
|
||||
bluePlayers++;
|
||||
else if (e.team == 2)
|
||||
redPlayers++;
|
||||
else if (e.team == 3)
|
||||
yellowPlayers++;
|
||||
else if (e.team == 4)
|
||||
greenPlayers++;
|
||||
}
|
||||
|
||||
/* assign us to the team with the lowest amount of players */
|
||||
f = TFCTeamJoin_SmallestTeam(bluePlayers, redPlayers, yellowPlayers, greenPlayers);
|
||||
}
|
||||
|
||||
/* mess, do it better */
|
||||
if (f == 1) {
|
||||
pl.team = 1; /* Blue */
|
||||
|
@ -40,7 +106,6 @@ CSEv_TeamJoin_f(float f)
|
|||
forceinfokey(pl, "topcolor", "0x3bff00");
|
||||
forceinfokey(pl, "bottomcolor", "0x3bff00");
|
||||
} else {
|
||||
/* invalid */
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -420,7 +420,7 @@ player::ReceiveEntity(float new, float flChanged)
|
|||
return;
|
||||
|
||||
TFCHallucination_Insert(origin, v_angle);
|
||||
m_flNextHallucination = time + 0.5f + random();
|
||||
m_flNextHallucination = time + 0.25f + random(0.25,0.75);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue