Skip to content

Commit

Permalink
Merge pull request #170 from NeonKnightOA/domsupport
Browse files Browse the repository at this point in the history
Domination AI Improvements
  • Loading branch information
NeonKnightOA authored Mar 12, 2024
2 parents 3959ed9 + 077f85d commit 41a796a
Show file tree
Hide file tree
Showing 14 changed files with 463 additions and 29 deletions.
1 change: 1 addition & 0 deletions botfiles/match.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//Double Domination messages
#define MSG_HOLDPOINTA 90
#define MSG_HOLDPOINTB 91
#define MSG_HOLDDOMPOINT 92 //defend a DOM point
//
#define MSG_ME 100
#define MSG_EVERYONE 101
Expand Down
17 changes: 17 additions & 0 deletions botfiles/teamplay.h
Original file line number Diff line number Diff line change
Expand Up @@ -544,3 +544,20 @@ type "cmd_holdpointb"
{
0, " dominate point B";
}

//Domination stuff:
type "dom_point_hold_start"
{
"I'll pick a control point and hold it!";
}

type "dom_point_holding"
{
"Holding control of ", 1;
}

//Domination orders:
type "cmd_holddompoint"
{
0, " pick a control point and defend it!";
}
124 changes: 124 additions & 0 deletions code/game/ai_cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,11 @@ void BotPrintTeamGoal(bot_state_t *bs) {
BotAI_Print(PRT_MESSAGE, "%s: I'm gonna take care of point B for %1.0f secs\n", netname, t);
break;
}
case LTG_HOLDDOMPOINT:
{
BotAI_Print(PRT_MESSAGE, "%s: I'm gonna defend DOM point %i for %1.0f secs\n", netname, BotGetDominationPoint(bs), t);
break;
}
default:
{
if (bs->ctfroam_time > FloatTime()) {
Expand Down Expand Up @@ -474,6 +479,58 @@ int BotGPSToPosition(char *buf, vec3_t position) {
return qtrue;
}

void BotMatch_HoldDOMPoint(bot_state_t *bs, bot_match_t *match);

/*
==================
BotGetDominationPoint
Returns the actual Domination point the bot is acting on. Prevents currentPoint from being accessed directly.
==================
*/
int BotGetDominationPoint(bot_state_t *bs) {
return bs->currentPoint;
}

/*
==================
BotSetDominationPoint
Selects a point for Domination. It's saved in the field currentPoint.
==================
*/
void BotSetDominationPoint(bot_state_t *bs, int controlPoint) {
int i;
qboolean allTaken = qtrue;

// Domination only
if (gametype != GT_DOMINATION) return;
// If there are no points, just assign the neutral one.
if (level.domination_points_count > 1) {
bs->currentPoint = 0;
return;
}
// If a control point point has been passed,
// and falls inside of both gametype AND map limits, assign it.
if (controlPoint >= 0 &&
controlPoint < level.domination_points_count &&
controlPoint < MAX_DOMINATION_POINTS) {
bs->currentPoint = controlPoint;
return;
}
// Search for points our team don't own.
for (i=1;i<level.domination_points_count;i++) {
if ((BotTeam(bs) == TEAM_RED && level.pointStatusDom[i] != TEAM_RED) ||
(BotTeam(bs) == TEAM_BLUE && level.pointStatusDom[i] != TEAM_BLUE)) {
allTaken = qfalse;
bs->currentPoint = i;
break;
}
}
// If we own all of the points, operate in a random one.
if (allTaken == qfalse) {
bs->currentPoint = rand() % level.domination_points_count;
}
}

void BotMatch_TakeA(bot_state_t *bs, bot_match_t *match);
void BotMatch_TakeB(bot_state_t *bs, bot_match_t *match);

Expand Down Expand Up @@ -620,6 +677,12 @@ void BotMatch_DefendKeyArea(bot_state_t *bs, bot_match_t *match) {
BotMatch_TakeB(bs,match);
return;
}
// Domination has clear rules
if (gametype == GT_DOMINATION) {
// Reroll to get a different DOM point.
BotSetDominationPoint(bs,-1);
BotMatch_HoldDOMPoint(bs,match);
}
//if not addressed to this bot
if (!BotAddressedToBot(bs, match)) return;
//get the match variable
Expand Down Expand Up @@ -755,6 +818,48 @@ void BotMatch_TakeB(bot_state_t *bs, bot_match_t *match) {
#endif //DEBUG
}

/*
==================
BotMatch_HoldDOMPoint
For Domination
==================
*/
void BotMatch_HoldDOMPoint(bot_state_t *bs, bot_match_t *match) {
char netname[MAX_MESSAGE_SIZE];
int client;

if (gametype != GT_DOMINATION) return;
if (level.domination_points_count < 1) return;
//if not addressed to this bot
if (!BotAddressedToBot(bs, match)) return;
//get the match variable
//
trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname));
//
client = ClientFromName(netname);
//the team mate who ordered
bs->decisionmaker = client;
bs->ordered = qtrue;
bs->order_time = FloatTime();
//set the time to send a message to the team mates
bs->teammessage_time = FloatTime() + 2 * random();
//set the ltg type
bs->ltgtype = LTG_HOLDDOMPOINT;
//get the team goal time
bs->teamgoal_time = BotGetTime(match);
//set the team goal time
if (!bs->teamgoal_time) bs->teamgoal_time = FloatTime() + TEAM_HOLDDOMPOINT_TIME;
//away from defending
bs->defendaway_time = 0;
//
BotSetTeamStatus(bs);
// remember last ordered task
BotRememberLastOrderedTask(bs);
#ifdef DEBUG
BotPrintTeamGoal(bs);
#endif //DEBUG
}

/*
==================
BotMatch_GetItem
Expand Down Expand Up @@ -1002,6 +1107,11 @@ void BotMatch_AttackEnemyBase(bot_state_t *bs, bot_match_t *match) {
BotMatch_TakeA(bs,match);
return;
}
else if (gametype == GT_DOMINATION) {
// Reroll to get a different DOM point.
BotSetDominationPoint(bs,-1);
BotMatch_HoldDOMPoint(bs,match);
}
else {
return;
}
Expand Down Expand Up @@ -1560,6 +1670,11 @@ void BotMatch_WhatAreYouDoing(bot_state_t *bs, bot_match_t *match) {
BotAI_BotInitialChat(bs, "dd_holdingpointb", NULL);
break;
}
case LTG_HOLDDOMPOINT:
{
BotAI_BotInitialChat(bs, "dom_holdpoint", NULL);
break;
}
default:
{
BotAI_BotInitialChat(bs, "roaming", NULL);
Expand Down Expand Up @@ -1881,6 +1996,10 @@ void BotMatch_EnterGame(bot_state_t *bs, bot_match_t *match) {
if (client >= 0) {
notleader[client] = qfalse;
}
if (gametype == GT_DOMINATION) {
// Assign a control point at start.
BotSetDominationPoint(bs,-1);
}
//NOTE: eliza chats will catch this
//Com_sprintf(buf, sizeof(buf), "heya %s", netname);
//EA_Say(bs->client, buf);
Expand Down Expand Up @@ -2097,6 +2216,11 @@ int BotMatchMessage(bot_state_t *bs, char *message) {
BotMatch_TakeB(bs, &match);
break;
}
case MSG_HOLDDOMPOINT:
{
BotMatch_HoldDOMPoint(bs, &match);
break;
}
default:
{
BotAI_Print(PRT_MESSAGE, "unknown match type\n");
Expand Down
3 changes: 3 additions & 0 deletions code/game/ai_cmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,6 @@ extern int notleader[MAX_CLIENTS];
int BotMatchMessage(bot_state_t *bs, char *message);
void BotPrintTeamGoal(bot_state_t *bs);

// Neon_Knight: Used for DOM point assignment
int BotGetDominationPoint(bot_state_t *bs);
void BotSetDominationPoint(bot_state_t *bs, int controlPoint);
36 changes: 36 additions & 0 deletions code/game/ai_dmnet.c
Original file line number Diff line number Diff line change
Expand Up @@ -1078,6 +1078,42 @@ int BotGetLongTermGoal(bot_state_t *bs, int tfl, int retreat, bot_goal_t *goal)
return qtrue;
}
}
else if (gametype == GT_DOMINATION) {
// If the bot has an assigned control point that falls outside of the limits,
// assign a new one before proceeding.
if (!(BotGetDominationPoint(bs) >= 0 &&
BotGetDominationPoint(bs) < MAX_DOMINATION_POINTS &&
BotGetDominationPoint(bs) < level.domination_points_count)) {
BotSetDominationPoint(bs,-1);
}
if ((bs->ltgtype == LTG_DEFENDKEYAREA) ||
(bs->ltgtype == LTG_ATTACKENEMYBASE) ||
(bs->ltgtype == LTG_HOLDDOMPOINT)) {
//check for bot typing status message
if (bs->teammessage_time && bs->teammessage_time < FloatTime()) {
trap_BotGoalName(bs->teamgoal.number, buf, sizeof(buf));
BotAI_BotInitialChat(bs, "dom_point_hold_start", buf, level.domination_points_names[BotGetDominationPoint(bs)]);
trap_BotEnterChat(bs->cs, 0, CHAT_TEAM);
//BotVoiceChatOnly(bs, -1, VOICECHAT_ONDEFENSE);
bs->teammessage_time = 0;
}
//set the bot goal
memcpy(goal, &dom_points_bot[BotGetDominationPoint(bs)], sizeof(bot_goal_t));
//if very close... go away for some time
VectorSubtract(goal->origin, bs->origin, dir);
if (VectorLengthSquared(dir) < Square(70)) {
trap_BotResetAvoidReach(bs->ms);
bs->defendaway_time = FloatTime() + 3 + 3 * random();
if (BotHasPersistantPowerupAndWeapon(bs)) {
bs->defendaway_range = 100;
}
else {
bs->defendaway_range = 350;
}
}
return qtrue;
}
}

//normal goal stuff
return BotGetItemLongTermGoal(bs, tfl, goal);
Expand Down
Loading

0 comments on commit 41a796a

Please sign in to comment.