Cleanup bot code

This commit is contained in:
aurhat
2015-06-21 10:34:07 +02:00
parent bfc273ee52
commit 9613098697
13 changed files with 22 additions and 433 deletions
+9 -18
View File
@@ -6,15 +6,15 @@
#
# FILE DESCRIPTION:
#
# Lines starting with a # and blank lines will be ignored. In this file you
# can modify the reaction delays and aim speeds used by the bots. If this file
# Lines starting with a # and blank lines will be ignored. In this file you
# can modify the reaction delays and aim speeds used by the bots. If this file
# doesnt exist default settings will be used.
#
#
# BOT SKILL VARIABLE NOTES:
#
# min_XXX is the minimum amount of time\distance\degrees before a bot will respond
# max_XXX is the maximum amount of time\distance\degrees a bot will respond
#
#
#
# BOT AIM VARIABLE NOTES:
#
@@ -66,18 +66,13 @@
# Description = Sets if the bot will predict their enemy's position.
# Unit of Measure = Bool(1 = on, 0 = off)
#
# shoot_at_feet_percent <value>
# Description = Sets the percentage the bot will shoot at the enemies feet when using
# a weapon like a rocket launcher.
# Unit of Measure = Percentage (highest value is 100)
#
# max_hear_volume <value>
# Description = Sets 'how much' the bot can hear, how lower the value, how lower the max distance a
# bot can still hear a sound.
# Unit of Measure = Integer (100 is max).
# Unit of Measure = Integer (100 is max).
#
# field_of_view <value>
# Description = Sets bot field of view.
# Description = Sets bot field of view.
# Unit of Measure = Integer (degrees, 240 = max)
#
# max_always_detect_distance
@@ -88,7 +83,7 @@
#
# There are five skill levels to edit (and choose from ingame). SKILL1 is the highest skill level
# while SKILL5 is the lowest skill level.
#
#
#-----------------------------------------------------------------------------------------------
@@ -115,7 +110,6 @@ can_predict_position 1
can_circle_strafe 1
can_search_items_in_combat 1
shoot_at_feet_percent 85
max_hear_volume 75
field_of_view 200
@@ -145,7 +139,6 @@ can_predict_position 1
can_circle_strafe 1
can_search_items_in_combat 1
shoot_at_feet_percent 60
max_hear_volume 60
field_of_view 160
@@ -172,7 +165,6 @@ can_predict_position 0
can_circle_strafe 1
can_search_items_in_combat 0
shoot_at_feet_percent 25
max_hear_volume 40
field_of_view 140
@@ -199,7 +191,6 @@ can_predict_position 0
can_circle_strafe 0
can_search_items_in_combat 0
shoot_at_feet_percent 10
max_hear_volume 30
field_of_view 120
@@ -226,6 +217,6 @@ can_predict_position 0
can_circle_strafe 0
can_search_items_in_combat 0
shoot_at_feet_percent 0
max_hear_volume 15
field_of_view 110
field_of_view 110
+1 -1
View File
@@ -1,2 +1,2 @@
RVSF
CLA
CLA
-5
View File
@@ -13,8 +13,6 @@
#include "cube.h"
#include "bot.h"
#ifdef AC_CUBE
extern int triggertime;
extern itemstat itemstats[];
extern void spawnstate(playerent *d);
@@ -46,7 +44,6 @@ void CACBot::Spawn()
m_iEnemySearchDelay = 0;
m_bCombatJump = false;
m_iCombatJumpDelay = 0;
m_bShootAtFeet = (RandomLong(1, 100) <= m_pBotSkill->sShootAtFeetWithRLPercent);
m_iHuntDelay = 0;
m_vHuntLocation = m_vPrevHuntLocation = g_vecZero;
m_pHuntTarget = NULL;
@@ -74,5 +71,3 @@ void CACBot::CheckItemPickup()
}
// AC Bot class end
#endif
-7
View File
@@ -13,8 +13,6 @@
#ifndef AC_BOT_H
#define AC_BOT_H
#ifdef AC_CUBE
//#define BOTDEBUG
#define MAX_WEAPONS 10
@@ -48,9 +46,4 @@ inline void AddDebugText(const char *t, ...)
#endif
}
#endif
#endif
-9
View File
@@ -11,8 +11,6 @@
#include "cube.h"
#include "bot.h"
#ifdef AC_CUBE
weaponinfo_s WeaponInfoTable[MAX_WEAPONS] =
{
// DD: desired distance
@@ -124,11 +122,6 @@ bool CACBot::ChoosePreferredWeapon()
}
}
if (WeaponInfoTable[m_pMyEnt->gunselect].eWeaponType == TYPE_ROCKET)
{
m_bShootAtFeet = true;
}
if(lastmillis > m_iChangeWeaponDelay)
{
SelectGun(bestWeapon);
@@ -361,5 +354,3 @@ bool CACBot::DoSPStuff()
}
// Code of CACBot - End
#endif
-1
View File
@@ -63,7 +63,6 @@ void CBot::Spawn()
m_iSawEnemyTime = 0;
m_bCombatJump = false;
m_iCombatJumpDelay = 0;
m_bShootAtFeet = (RandomLong(1, 100) <= m_pBotSkill->sShootAtFeetWithRLPercent);
m_iHuntDelay = 0;
m_vHuntLocation = m_vPrevHuntLocation = g_vecZero;
m_pHuntTarget = NULL;
+1 -25
View File
@@ -21,8 +21,6 @@
-bots should ignore players that are too far away ?
-bots should dodge/jump when shot at
-If the bot's only weapon is the fist it should make looking for ammo its priority - Done ?
-bots should rocket jump to get quads and the 150 armor if normal jumping doesn't
work (only if health is x so they don't suicide).
-Make all the "UNDONE's" done :)
-Finish waypoint navigation
-Make bot personalities
@@ -33,7 +31,6 @@
-Waypoint experience file
-Bots should avoid team mates
-Handle failed goals better(ie remember them)
-Test multiplayer
-Fix bots getting stuck in each other
-Optimize hunting code
-Check/Fix msg code
@@ -42,14 +39,7 @@
#ifndef BOT_H
#define BOT_H
//#define RELEASE_BUILD // Set when you want to make a release build
// Set for which mod the code is
//#define VANILLA_CUBE
#define AC_CUBE
//#define CUBE_X
#define RELEASE_BUILD // Set when you want to make a release build
#include "bot_util.h"
#include "bot_waypoint.h"
@@ -107,8 +97,6 @@ struct bot_skill_s
float flMaxEnemySearchDelay; // Maximal delay for when a bot can search for an
// enemy again
float flAlwaysDetectDistance;
short sShootAtFeetWithRLPercent; // Percent that a bot shoot with a rocket
// launcher at the enemy feet.
int iMaxHearVolume; // Max volume that bot can hear
int iFov; // bots field of view
bool bCanPredict; // Can this bot predict his enemy position?
@@ -121,7 +109,6 @@ enum EBotWeaponTypes
TYPE_MELEE, // Fist, knife etc
TYPE_NORMAL, // Normal weapon, distance doesn't really matter(ie pistol)
TYPE_SHOTGUN,
TYPE_ROCKET,
TYPE_SNIPER, // Rifle, sniper etc
TYPE_GRENADE,
TYPE_AUTO // Chain gun, machine gun etc
@@ -360,7 +347,6 @@ class CBotManager
void InitBotItems(void);
friend class CBot;
friend class CCubeBot;
friend class CACBot;
friend class CWaypointClass;
@@ -403,21 +389,11 @@ public:
char *szOutput);
};
#if defined VANILLA_CUBE
#include "cube_bot.h"
#elif defined AC_CUBE
#include "ac_bot.h"
#endif
extern CBotManager BotManager;
extern const vec g_vecZero;
#if defined AC_CUBE
extern CACWaypointClass WaypointClass;
#elif defined VANILLA_CUBE
extern CCubeWaypointClass WaypointClass;
#endif
extern void kickallbots();
#endif
+4 -37
View File
@@ -21,43 +21,11 @@ vec CBot::GetEnemyPos(playerent *d)
vec o = m_pMyEnt->weaponsel->type == GUN_SNIPER && d->head.x >= 0 ? d->head : d->o, offset;
float flDist = GetDistance(o), flScale;
if (WeaponInfoTable[m_pMyEnt->gunselect].eWeaponType == TYPE_ROCKET)
if (m_pBotSkill->bCanPredict)
{
// Bot is using a rocket launcher, aim at enemy feet?
if (m_bShootAtFeet && !OUTBORD(d->o.x, d->o.y))
{
// Only do this when enemy is fairly close to the ground
vec end = o;
end.z -= 900.0f;
traceresult_s tr;
TraceLine(o, end, NULL, false, &tr);
if ((o.z - tr.end.z) < 8.0f)
{
end = o;
end.z = tr.end.z;
if (IsVisible(end))
{
// Target at ground
o.z = tr.end.z;
}
}
}
if (m_pBotSkill->bCanPredict)
{
// How higher the skill, how further the bot predicts
float flPredictTime = RandomFloat(1.25f, 1.7f) / (m_sSkillNr+1);
o = PredictPos(o, d->vel, flPredictTime);
}
}
else
{
if (m_pBotSkill->bCanPredict)
{
// How higher the skill, how 'more' the bot predicts
float flPredictTime = RandomFloat(0.8f, 1.2f) / (m_sSkillNr+1);
o = PredictPos(o, d->vel, flPredictTime);
}
// How higher the skill, how 'more' the bot predicts
float flPredictTime = RandomFloat(0.8f, 1.2f) / (m_sSkillNr+1);
o = PredictPos(o, d->vel, flPredictTime);
}
if (flDist > 60.0f)
@@ -648,7 +616,6 @@ void CBot::CheckWeaponSwitch()
{
m_pMyEnt->prevweaponsel = m_pMyEnt->weaponsel;
m_pMyEnt->weaponsel = m_pMyEnt->nextweaponsel;
if(m_pMyEnt->weaponsel!=NULL) addmsg(SV_WEAPCHANGE, "ri", m_pMyEnt->weaponsel->type); // 2011jan17:ft: message possibly not needed in a local game!?!
m_pMyEnt->weaponchanging = 0;
m_iChangeWeaponDelay = 0;
if(!m_pMyEnt->weaponsel->mag)
-4
View File
@@ -480,11 +480,7 @@ bool IsInGame(dynent *d)
{
loopv(players)
{
#ifdef VANILLA_CUBE
if (!players[i] || (players[i]->state == CS_DEDHOST)) continue;
#elif defined(AC_CUBE)
if (!players[i]) continue;
#endif
if (players[i] == d)
return true;
}
-237
View File
@@ -12,11 +12,7 @@
vec v_debuggoal = g_vecZero;
#if defined AC_CUBE
CACWaypointClass WaypointClass;
#elif defined VANILLA_CUBE
CCubeWaypointClass WaypointClass;
#endif
VAR(xhairwpsel, 0, 1, 1);
// FIXME: multiple selections support ?
@@ -775,19 +771,6 @@ void CWaypointClass::DrawNearWaypoints()
glEnable(GL_CULL_FACE);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
if (intermission) return;
/*for(int i=0;i<MAX_STORED_LOCATIONS;i++)
{
if (player1->PrevLocations.prevloc[i]==g_vecZero) continue;
vec v1 = player1->PrevLocations.prevloc[i];
v1.z -= 1.0f;
vec v2 = v1;
v2.z += 2.0f;
linestyle(2.5f, 0xFF, 0x40, 0x40);
line(int(v1.x), int(v1.y), int(v1.z), int(v2.x), int(v2.y), int(v2.z));
}*/
}
// Add waypoint at location o, returns pointer of created wp
@@ -1687,215 +1670,14 @@ void CWaypointClass::GetNodeIndexes(const vec &v_origin, short *i, short *j)
#endif // WP_FLOOD
// Waypoint class end
#if defined AC_CUBE
// AC waypoint class begin
void CACWaypointClass::StartFlood()
{
// UNDONE?
CWaypointClass::StartFlood();
}
// AC waypoint class end
#elif defined VANILLA_CUBE
// Cube waypoint class begin
void CCubeWaypointClass::StartFlood()
{
CWaypointClass::StartFlood();
// Add wps at triggers and teleporters and their destination
loopv(ents)
{
entity &e = ents[i];
if (OUTBORD(e.x, e.y)) continue;
if (e.type == TELEPORT)
{
vec telepos = { e.x, e.y, S(e.x, e.y)->floor+player1->eyeheight }, teledestpos = g_vecZero;
// Find the teleport destination
int n = -1, tag = e.attr1, beenhere = -1;
for(;;)
{
n = findentity(TELEDEST, n+1);
if(n==beenhere || n<0) { conoutf("no teleport destination for tag %d", tag); break; };
if(beenhere<0) beenhere = n;
if(ents[n].attr2==tag)
{
teledestpos.x = ents[n].x;
teledestpos.y = ents[n].y;
teledestpos.z = S(ents[n].x, ents[n].y)->floor+player1->eyeheight;
break;
}
}
if (vis(teledestpos, g_vecZero)) continue;
int flags = (W_FL_FLOOD | W_FL_TELEPORT);
if (S((int)telepos.x, (int)telepos.y)->tag) flags |= W_FL_INTAG;
// Add waypoint at teleporter and teleport destination
node_s *pWP = new node_s(telepos, flags, 0);
short i, j;
GetNodeIndexes(telepos, &i, &j);
m_Waypoints[i][j].PushNode(pWP);
BotManager.AddWaypoint(pWP);
m_iFloodSize += sizeof(node_s);
m_iWaypointCount++;
flags = (W_FL_FLOOD | W_FL_TELEPORTDEST);
if (S((int)teledestpos.x, (int)teledestpos.y)->tag) flags |= W_FL_INTAG;
node_s *pWP2 = new node_s(teledestpos, flags, 0);
GetNodeIndexes(teledestpos, &i, &j);
m_Waypoints[i][j].PushNode(pWP2);
BotManager.AddWaypoint(pWP2);
m_iFloodSize += sizeof(node_s);
m_iWaypointCount++;
// Connect the teleporter waypoint with the teleport-destination waypoint(1 way)
AddPath(pWP, pWP2);
// Connect with other nearby nodes
ConnectFloodWP(pWP);
}
else if (e.type == CARROT)
{
vec pos = { e.x, e.y, S(e.x, e.y)->floor+player1->eyeheight };
int flags = (W_FL_FLOOD | W_FL_TRIGGER);
if (S(e.x, e.y)->tag) flags |= W_FL_INTAG;
node_s *pWP = new node_s(pos, flags, 0);
short i, j;
GetNodeIndexes(pos, &i, &j);
m_Waypoints[i][j].PushNode(pWP);
BotManager.AddWaypoint(pWP);
m_iFloodSize += sizeof(node_s);
m_iWaypointCount++;
// Connect with other nearby nodes
ConnectFloodWP(pWP);
}
else if (e.type == MAPMODEL)
{
mapmodelinfo &mmi = getmminfo(e.attr2);
if(!&mmi || !mmi.h || !mmi.rad) continue;
float floor = (float)(S(e.x, e.y)->floor+mmi.zoff+e.attr3)+mmi.h;
float x1 = e.x - mmi.rad;
float x2 = e.x + mmi.rad;
float y1 = e.y - mmi.rad;
float y2 = e.y + mmi.rad;
// UNDONE?
for (float x=(x1+1.0f);x<=(x2-1.0f);x++)
{
for (float y=(y1+1.0f);y<=(y2-1.0f);y++)
{
vec from = { x, y, floor+2.0f };
if (GetNearestFloodWP(from, 2.0f, NULL)) continue;
// Add WP
int flags = W_FL_FLOOD;
if (S((int)x, (int)y)->tag) flags |= W_FL_INTAG;
node_s *pWP = new node_s(from, flags, 0);
short i, j;
GetNodeIndexes(from, &i, &j);
m_Waypoints[i][j].PushNode(pWP);
BotManager.AddWaypoint(pWP);
m_iFloodSize += sizeof(node_s);
m_iWaypointCount++;
// Connect with other nearby nodes
ConnectFloodWP(pWP);
}
}
}
}
CWaypointClass::StartFlood();
}
void CCubeWaypointClass::CreateWPsAtTeleporters()
{
loopv(ents)
{
entity &e = ents[i];
if (e.type != TELEPORT) continue;
if (OUTBORD(e.x, e.y)) continue;
vec telepos = { e.x, e.y, S(e.x, e.y)->floor+player1->eyeheight }, teledestpos = g_vecZero;
// Find the teleport destination
int n = -1, tag = e.attr1, beenhere = -1;
for(;;)
{
n = findentity(TELEDEST, n+1);
if(n==beenhere || n<0) { conoutf("no teleport destination for tag %d", tag); continue; };
if(beenhere<0) beenhere = n;
if(ents[n].attr2==tag)
{
teledestpos.x = ents[n].x;
teledestpos.y = ents[n].y;
teledestpos.z = S(ents[n].x, ents[n].y)->floor+player1->eyeheight;
break;
}
}
if (vis(teledestpos, g_vecZero)) continue;
// Add waypoint at teleporter and teleport destination
node_s *telewp = AddWaypoint(telepos, false);
node_s *teledestwp = AddWaypoint(teledestpos, false);
if (telewp && teledestwp)
{
// Connect the teleporter waypoint with the teleport-destination waypoint(1 way)
AddPath(telewp, teledestwp);
// Flag waypoints
telewp->iFlags = W_FL_TELEPORT;
teledestwp->iFlags = W_FL_TELEPORTDEST;
}
}
}
void CCubeWaypointClass::CreateWPsAtTriggers()
{
loopv(ents)
{
entity &e = ents[i];
if (e.type != CARROT) continue;
if (OUTBORD(e.x, e.y)) continue;
vec pos = { e.x, e.y, S(e.x, e.y)->floor+player1->eyeheight };
node_s *wp = AddWaypoint(pos, false);
if (wp)
{
// Flag waypoints
wp->iFlags = W_FL_TRIGGER;
}
}
}
#endif
// Cube waypoint class end
// Waypoint commands begin
void addwp(int *autoconnect)
@@ -2075,25 +1857,6 @@ void wpflood(void)
COMMAND(wpflood, "");
#endif
#ifdef VANILLA_CUBE
// Commands specific for cube
void addtelewps(void)
{
WaypointClass.SetWaypointsVisible(true);
WaypointClass.CreateWPsAtTeleporters();
}
COMMAND(addtelewps, "");
void addtriggerwps(void)
{
WaypointClass.SetWaypointsVisible(true);
WaypointClass.CreateWPsAtTriggers();
}
COMMAND(addtriggerwps, "");
#endif
// Debug functions
#ifdef WP_FLOOD
-12
View File
@@ -176,16 +176,4 @@ public:
#endif
};
class CCubeWaypointClass: public CWaypointClass
{
public:
void CreateWPsAtTeleporters(void);
void CreateWPsAtTriggers(void);
#ifdef WP_FLOOD
// Flood functions
virtual void StartFlood(void);
#endif
};
#endif // BOT_WAYPOINT_H
-77
View File
@@ -13,11 +13,8 @@
#include "cube.h"
#include "bot.h"
#ifndef VANILLA_CUBE // UNDONE
bool dedserv = false;
#define CS_DEDHOST 0xFF
#endif
extern void respawnself();
@@ -314,8 +311,6 @@ void CBotManager::RenderBots()
{
if (bots[i] && (bots[i] != m_pBotToView))
{
/*drawblue = (m_sp || isteam(player1->team, bots[i]->team));
renderclient(bots[i], drawblue, "playermodels/counterterrorist", 1.6f);*/
renderclient(bots[i]);
}
}
@@ -634,12 +629,6 @@ void CBotManager::CreateSkillData()
{
m_BotSkills[SkillNr].flAlwaysDetectDistance = value;
}
else if (strcasecmp(cmd, "shoot_at_feet_percent") == 0)
{
if (value < 0) value = 0;
else if (value > 100) value = 100;
m_BotSkills[SkillNr].sShootAtFeetWithRLPercent = (short)value;
}
else if (strcasecmp(cmd, "can_predict_position") == 0)
{
m_BotSkills[SkillNr].bCanPredict = value!=0;
@@ -687,7 +676,6 @@ void CBotManager::InitSkillData()
m_BotSkills[0].flMinEnemySearchDelay = 0.09f;
m_BotSkills[0].flMaxEnemySearchDelay = 0.12f;
m_BotSkills[0].flAlwaysDetectDistance = 12.0f;
m_BotSkills[0].sShootAtFeetWithRLPercent = 85;
m_BotSkills[0].bCanPredict = true;
m_BotSkills[0].iMaxHearVolume = 75;
m_BotSkills[0].iFov = 200;
@@ -710,7 +698,6 @@ void CBotManager::InitSkillData()
m_BotSkills[1].flMinEnemySearchDelay = 0.12f;
m_BotSkills[1].flMaxEnemySearchDelay = 0.17f;
m_BotSkills[1].flAlwaysDetectDistance = 10.0f;
m_BotSkills[1].sShootAtFeetWithRLPercent = 60;
m_BotSkills[1].bCanPredict = true;
m_BotSkills[1].iMaxHearVolume = 60;
m_BotSkills[1].iFov = 160;
@@ -733,7 +720,6 @@ void CBotManager::InitSkillData()
m_BotSkills[2].flMinEnemySearchDelay = 0.18f;
m_BotSkills[2].flMaxEnemySearchDelay = 0.22f;
m_BotSkills[2].flAlwaysDetectDistance = 8.0f;
m_BotSkills[2].sShootAtFeetWithRLPercent = 25;
m_BotSkills[2].bCanPredict = false;
m_BotSkills[2].iMaxHearVolume = 45;
m_BotSkills[2].iFov = 130;
@@ -756,7 +742,6 @@ void CBotManager::InitSkillData()
m_BotSkills[3].flMinEnemySearchDelay = 0.25f;
m_BotSkills[3].flMaxEnemySearchDelay = 0.30f;
m_BotSkills[3].flAlwaysDetectDistance = 6.0f;
m_BotSkills[3].sShootAtFeetWithRLPercent = 10;
m_BotSkills[3].bCanPredict = false;
m_BotSkills[3].iMaxHearVolume = 30;
m_BotSkills[3].iFov = 120;
@@ -779,7 +764,6 @@ void CBotManager::InitSkillData()
m_BotSkills[4].flMinEnemySearchDelay = 0.30f;
m_BotSkills[4].flMaxEnemySearchDelay = 0.36f;
m_BotSkills[4].flAlwaysDetectDistance = 4.0f;
m_BotSkills[4].sShootAtFeetWithRLPercent = 0;
m_BotSkills[4].bCanPredict = false;
m_BotSkills[4].iMaxHearVolume = 15;
m_BotSkills[4].iFov = 110;
@@ -874,13 +858,6 @@ void CBotManager::PickNextTrigger()
{
entity &e = ents[i];
#if defined AC_CUBE
/* if ((e.type != TRIGGER) || !e.spawned)
continue;*/
#elif defined VANILLA_CUBE
if ((e.type != CARROT) || !e.spawned)
continue;
#endif
if (OUTBORD(e.x, e.y)) continue;
vec o(e.x, e.y, S(e.x, e.y)->floor+player1->eyeheight);
@@ -930,14 +907,7 @@ botent *CBotManager::CreateBot(const char *team, const char *skill, const char *
loopi(NUMGUNS) m->ammo[i] = m->mag[i] = 0;
m->lifesequence = 0;
setskin(m, rnd(6));
// Create new bot class, dependand on the current mod
#if defined VANILLA_CUBE
m->pBot = new CCubeBot;
#elif defined AC_CUBE
m->pBot = new CACBot;
#else
#error "Unsupported mod!"
#endif
m->type = ENT_BOT;
m->pBot->m_pMyEnt = m;
m->pBot->m_iLastBotUpdate = 0;
@@ -1047,18 +1017,6 @@ void idlebots(int *Idle)
COMMAND(idlebots, "i");
void drawbeamtobots()
{
if(!botmode()) return;
loopv(bots)
{
if (bots[i])
particle_trail(PART_SMOKE, 500, player1->o, bots[i]->o);
}
}
COMMAND(drawbeamtobots, "");
void kickbot(const char *szName)
{
if(!botmode()) return;
@@ -1184,34 +1142,6 @@ COMMAND(botskillall, "s");
#ifndef RELEASE_BUILD
#ifdef VANILLA_CUBE
void drawbeamtocarrots()
{
loopv(ents)
{
entity &e = ents[i];
vec o = { e.x, e.y, S(e.x, e.y)->floor+player1->eyeheight };
if ((e.type != CARROT) || !e.spawned) continue;
particle_trail(PART_SMOKE, 500, player1->o, o);
}
}
COMMAND(drawbeamtocarrots, "");
void drawbeamtoteleporters()
{
loopv(ents)
{
entity &e = ents[i];
vec o = { e.x, e.y, S(e.x, e.y)->floor+player1->eyeheight };
if (e.type != TELEPORT) continue;
particle_trail(PART_SMOKE, 500, player1->o, o);
}
}
COMMAND(drawbeamtoteleporters, "");
#endif
void telebot(void)
{
vec dest = player1->o, forward, right, up;
@@ -1311,11 +1241,4 @@ void testvisible(int iDir)
COMMANDF(testvisible, "i", (int *dir) { testvisible(*dir); });
void mapsize(void)
{
intret(sfactor);
}
COMMAND(mapsize, "");
#endif
+7
View File
@@ -731,6 +731,13 @@ bool empty_world(int factor, bool force) // main empty world creation routine
return true;
}
void mapsize(void)
{
intret(sfactor);
}
COMMAND(mapsize, "");
void mapenlarge() { if(empty_world(-1, false)) addmsg(SV_NEWMAP, "ri", -1); }
void mapshrink() { if(empty_world(-2, false)) addmsg(SV_NEWMAP, "ri", -2); }
void newmap(int *i)