- floatification of bot code.

This commit is contained in:
Christoph Oelckers 2016-03-26 00:34:56 +01:00
parent 8e13d13916
commit e42b0171b3
17 changed files with 198 additions and 232 deletions

View File

@ -828,16 +828,6 @@ public:
return P_AproxDistance(_f_X() - otherx, _f_Y() - othery);
}
fixed_t __f_AngleTo(fixed_t otherx, fixed_t othery)
{
return R_PointToAngle2(_f_X(), _f_Y(), otherx, othery);
}
fixed_t __f_AngleTo(fixedvec2 other)
{
return R_PointToAngle2(_f_X(), _f_Y(), other.x, other.y);
}
// 'absolute' is reserved for a linked portal implementation which needs
// to distinguish between portal-aware and portal-unaware distance calculation.
fixed_t AproxDistance(AActor *other, bool absolute = false)
@ -846,13 +836,14 @@ public:
return P_AproxDistance(_f_X() - otherpos.x, _f_Y() - otherpos.y);
}
/*
fixed_t AproxDistance(AActor *other, fixed_t xadd, fixed_t yadd, bool absolute = false)
{
fixedvec3 otherpos = absolute ? other->_f_Pos() : other->_f_PosRelative(this);
return P_AproxDistance(_f_X() - otherpos.x + xadd, _f_Y() - otherpos.y + yadd);
}
*/
// more precise, but slower version, being used in a few places
double Distance2D(AActor *other, bool absolute = false)
{
DVector2 otherpos = absolute ? other->Pos() : other->PosRelative(this);
@ -864,6 +855,13 @@ public:
return DVector2(X() - x, Y() - y).Length();
}
double Distance2D(AActor *other, double xadd, double yadd, bool absolute = false)
{
DVector3 otherpos = absolute ? other->Pos() : other->PosRelative(this);
return DVector2(X() - otherpos.X + xadd, Y() - otherpos.Y + yadd).Length();
}
// a full 3D version of the above
double Distance3D(AActor *other, bool absolute = false)
{
@ -871,17 +869,6 @@ public:
return (Pos() - otherpos).Length();
}
angle_t __f_AngleTo(AActor *other, bool absolute = false)
{
fixedvec3 otherpos = absolute ? other->_f_Pos() : other->_f_PosRelative(this);
return R_PointToAngle2(_f_X(), _f_Y(), otherpos.x, otherpos.y);
}
angle_t __f_AngleTo(AActor *other, fixed_t oxofs, fixed_t oyofs, bool absolute = false) const
{
return R_PointToAngle2(_f_X(), _f_Y(), other->_f_X() + oxofs, other->_f_Y() + oyofs);
}
DAngle AngleTo(AActor *other, bool absolute = false)
{
DVector2 otherpos = absolute ? other->Pos() : other->PosRelative(this);
@ -1064,6 +1051,10 @@ public:
SetOrigin(npos.x, npos.y, npos.z, moving);
}
void Move(const DVector3 &vel)
{
SetOrigin(Pos() + vel, true);
}
void SetOrigin(double x, double y, double z, bool moving)
{
SetOrigin(FLOAT2FIXED(x), FLOAT2FIXED(y), FLOAT2FIXED(z), moving);

View File

@ -815,7 +815,7 @@ CVAR(Bool, am_portaloverlay, true, CVAR_ARCHIVE)
CCMD(am_togglefollow)
{
am_followplayer = !am_followplayer;
f_oldloc.x = FIXED_MAX;
f_oldloc.x = FLT_MAX;
Printf ("%s\n", GStrings(am_followplayer ? "AMSTR_FOLLOWON" : "AMSTR_FOLLOWOFF"));
}
@ -1022,7 +1022,7 @@ bool AM_addMark ()
static void AM_findMinMaxBoundaries ()
{
min_x = min_y = FIXED_MAX;
min_x = min_y = FLT_MAX;
max_x = max_y = FIXED_MIN;
for (int i = 0; i < numvertexes; i++)
@ -1094,7 +1094,7 @@ static void AM_ClipRotatedExtents (double pivotx, double pivoty)
xs[2] = max_x; ys[2] = max_y;
xs[3] = min_x; ys[3] = max_y;
xs[4] = m_x + m_w/2; ys[4] = m_y + m_h/2;
rmin_x = rmin_y = FIXED_MAX;
rmin_x = rmin_y = FLT_MAX;
rmax_x = rmax_y = FIXED_MIN;
for (i = 0; i < 5; ++i)
@ -1175,7 +1175,7 @@ void AM_changeWindowLoc ()
if (m_paninc.x || m_paninc.y)
{
am_followplayer = false;
f_oldloc.x = FIXED_MAX;
f_oldloc.x = FLT_MAX;
}
double oldmx = m_x, oldmy = m_y;
@ -1220,7 +1220,7 @@ void AM_initVariables ()
Button_AM_ZoomOut.Reset();
f_oldloc.x = FIXED_MAX;
f_oldloc.x = FLT_MAX;
amclock = 0;
m_paninc.x = m_paninc.y = 0;

View File

@ -33,7 +33,7 @@ DBot::DBot ()
void DBot::Clear ()
{
player = NULL;
angle = 0;
Angle = 0.;
dest = NULL;
prev = NULL;
enemy = NULL;
@ -52,27 +52,15 @@ void DBot::Clear ()
sleft = false;
allround = false;
increase = false;
oldx = 0;
oldy = 0;
old = { 0, 0 };
}
void DBot::Serialize (FArchive &arc)
{
Super::Serialize (arc);
if (SaveVersion < 4515)
{
angle_t savedyaw;
int savedpitch;
arc << savedyaw
<< savedpitch;
}
else
{
arc << player;
}
arc << angle
arc << player
<< Angle
<< dest
<< prev
<< enemy
@ -91,8 +79,7 @@ void DBot::Serialize (FArchive &arc)
<< sleft
<< allround
<< increase
<< oldx
<< oldy;
<< old;
}
void DBot::Tick ()

View File

@ -31,18 +31,18 @@
#define BOTFILENAME "bots.cfg"
#define MAX_TRAVERSE_DIST 100000000 //10 meters, used within b_func.c
#define AVOID_DIST 45000000 //Try avoid incoming missiles once they reached this close
#define SAFE_SELF_MISDIST (140*FRACUNIT) //Distance from self to target where it's safe to pull a rocket.
#define FRIEND_DIST 15000000 //To friend.
#define DARK_DIST 5000000 //Distance that bot can see enemies in the dark from.
#define MAX_TRAVERSE_DIST (100000000/65536.) //10 meters, used within b_func.c
#define AVOID_DIST (45000000/65536.) //Try avoid incoming missiles once they reached this close
#define SAFE_SELF_MISDIST (140.) //Distance from self to target where it's safe to pull a rocket.
#define FRIEND_DIST (15000000/65536.) //To friend.
#define DARK_DIST (5000000/65536.) //Distance that bot can see enemies in the dark from.
#define WHATS_DARK 50 //light value thats classed as dark.
#define MAX_MONSTER_TARGET_DIST 50000000 //Too high can slow down the performance, see P_mobj.c
#define ENEMY_SCAN_FOV (120*ANGLE_1)
#define MAX_MONSTER_TARGET_DIST (50000000/65536.) //Too high can slow down the performance, see P_mobj.c
#define ENEMY_SCAN_FOV (120.)
#define THINGTRYTICK 1000
#define MAXMOVEHEIGHT (32*FRACUNIT) //MAXSTEPMOVE but with jumping counted in.
#define GETINCOMBAT 35000000 //Max distance to item. if it's due to be icked up in a combat situation.
#define SHOOTFOV (60*ANGLE_1)
#define MAXMOVEHEIGHT (32) //MAXSTEPMOVE but with jumping counted in.
#define GETINCOMBAT (35000000/65536.) //Max distance to item. if it's due to be icked up in a combat situation.
#define SHOOTFOV (60.)
#define AFTERTICS (2*TICRATE) //Seconds that bot will be alert on an recent enemy. Ie not looking the other way
#define MAXROAM (4*TICRATE) //When this time is elapsed the bot will roam after something else.
//monster mod
@ -104,11 +104,11 @@ public:
void FinishTravel ();
bool IsLeader (player_t *player);
void SetBodyAt (const DVector3 &pos, int hostnum);
fixed_t FakeFire (AActor *source, AActor *dest, ticcmd_t *cmd);
bool SafeCheckPosition (AActor *actor, fixed_t x, fixed_t y, FCheckPosition &tm);
double FakeFire (AActor *source, AActor *dest, ticcmd_t *cmd);
bool SafeCheckPosition (AActor *actor, double x, double y, FCheckPosition &tm);
//(b_move.cpp)
bool CleanAhead (AActor *thing, fixed_t x, fixed_t y, ticcmd_t *cmd);
bool CleanAhead (AActor *thing, double x, double y, ticcmd_t *cmd);
bool IsDangerous (sector_t *sec);
TArray<FString> getspawned; //Array of bots (their names) which should be spawned when starting a game.
@ -149,10 +149,10 @@ public:
void WhatToGet (AActor *item);
//(b_func.cpp)
bool Check_LOS (AActor *to, angle_t vangle);
bool Check_LOS (AActor *to, DAngle vangle);
player_t *player;
angle_t angle; // The wanted angle that the bot try to get every tic.
DAngle Angle; // The wanted angle that the bot try to get every tic.
// (used to get a smooth view movement)
TObjPtr<AActor> dest; // Move Destination.
TObjPtr<AActor> prev; // Previous move destination.
@ -183,8 +183,7 @@ public:
bool allround;
bool increase;
fixed_t oldx;
fixed_t oldy;
DVector2 old;
private:
//(b_think.cpp)
@ -197,7 +196,7 @@ private:
void Dofire (ticcmd_t *cmd);
AActor *Choose_Mate ();
AActor *Find_enemy ();
angle_t FireRox (AActor *enemy, ticcmd_t *cmd);
DAngle FireRox (AActor *enemy, ticcmd_t *cmd);
//(b_move.cpp)
void Roam (ticcmd_t *cmd);

View File

@ -34,32 +34,32 @@ bool DBot::Reachable (AActor *rtarget)
if (player->mo == rtarget)
return false;
if ((rtarget->Sector->ceilingplane.ZatPoint (rtarget) -
rtarget->Sector->floorplane.ZatPoint (rtarget))
< player->mo->_f_height()) //Where rtarget is, player->mo can't be.
if ((rtarget->Sector->ceilingplane.ZatPointF (rtarget) -
rtarget->Sector->floorplane.ZatPointF (rtarget))
< player->mo->Height) //Where rtarget is, player->mo can't be.
return false;
sector_t *last_s = player->mo->Sector;
fixed_t last_z = last_s->floorplane.ZatPoint (player->mo);
fixed_t estimated_dist = player->mo->AproxDistance(rtarget);
double last_z = last_s->floorplane.ZatPointF (player->mo);
double estimated_dist = player->mo->Distance2D(rtarget);
bool reachable = true;
FPathTraverse it(player->mo->_f_X()+player->mo->_f_velx(), player->mo->_f_Y()+player->mo->_f_vely(), rtarget->_f_X(), rtarget->_f_Y(), PT_ADDLINES|PT_ADDTHINGS);
FPathTraverse it(player->mo->X()+player->mo->Vel.X, player->mo->Y()+player->mo->Vel.Y, rtarget->X(), rtarget->Y(), PT_ADDLINES|PT_ADDTHINGS);
intercept_t *in;
while ((in = it.Next()))
{
fixed_t hitx, hity;
fixed_t frac;
double hitx, hity;
double frac;
line_t *line;
AActor *thing;
fixed_t dist;
double dist;
sector_t *s;
frac = in->frac - FixedDiv (4*FRACUNIT, MAX_TRAVERSE_DIST);
dist = FixedMul (frac, MAX_TRAVERSE_DIST);
frac = in->Frac - 4 /MAX_TRAVERSE_DIST;
dist = frac * MAX_TRAVERSE_DIST;
hitx = it.Trace().x + FixedMul (player->mo->_f_velx(), frac);
hity = it.Trace().y + FixedMul (player->mo->_f_vely(), frac);
hitx = it.Trace().x + player->mo->Vel.X * frac;
hity = it.Trace().y + player->mo->Vel.Y * frac;
if (in->isaline)
{
@ -73,13 +73,13 @@ bool DBot::Reachable (AActor *rtarget)
{
//Determine if going to use backsector/frontsector.
s = (line->backsector == last_s) ? line->frontsector : line->backsector;
fixed_t ceilingheight = s->ceilingplane.ZatPoint (hitx, hity);
fixed_t floorheight = s->floorplane.ZatPoint (hitx, hity);
double ceilingheight = s->ceilingplane.ZatPoint (hitx, hity);
double floorheight = s->floorplane.ZatPoint (hitx, hity);
if (!bglobal.IsDangerous (s) && //Any nukage/lava?
(floorheight <= (last_z+MAXMOVEHEIGHT)
&& ((ceilingheight == floorheight && line->special)
|| (ceilingheight - floorheight) >= player->mo->_f_height()))) //Does it fit?
|| (ceilingheight - floorheight) >= player->mo->Height))) //Does it fit?
{
last_z = floorheight;
last_s = s;
@ -100,7 +100,7 @@ bool DBot::Reachable (AActor *rtarget)
thing = in->d.thing;
if (thing == player->mo) //Can't reach self in this case.
continue;
if (thing == rtarget && (rtarget->Sector->floorplane.ZatPoint (rtarget) <= (last_z+MAXMOVEHEIGHT)))
if (thing == rtarget && (rtarget->Sector->floorplane.ZatPointF (rtarget) <= (last_z+MAXMOVEHEIGHT)))
{
return true;
}
@ -118,16 +118,16 @@ bool DBot::Reachable (AActor *rtarget)
//if these conditions are true, the function returns true.
//GOOD TO KNOW is that the player's view angle
//in doom is 90 degrees infront.
bool DBot::Check_LOS (AActor *to, angle_t vangle)
bool DBot::Check_LOS (AActor *to, DAngle vangle)
{
if (!P_CheckSight (player->mo, to, SF_SEEPASTBLOCKEVERYTHING))
return false; // out of sight
if (vangle == ANGLE_MAX)
if (vangle >= 360.)
return true;
if (vangle == 0)
return false; //Looker seems to be blind.
return absangle(player->mo->AngleTo(to), player->mo->Angles.Yaw) <= ANGLE2FLOAT(vangle/2);
return absangle(player->mo->AngleTo(to), player->mo->Angles.Yaw) <= (vangle/2);
}
//-------------------------------------
@ -140,10 +140,9 @@ void DBot::Dofire (ticcmd_t *cmd)
bool no_fire; //used to prevent bot from pumping rockets into nearby walls.
int aiming_penalty=0; //For shooting at shading target, if screen is red, MAKEME: When screen red.
int aiming_value; //The final aiming value.
fixed_t dist;
double fdist;
angle_t an;
int m;
double Dist;
DAngle an;
DAngle m;
double fm;
if (!enemy || !(enemy->flags & MF_SHOOTABLE) || enemy->health <= 0)
@ -172,7 +171,7 @@ void DBot::Dofire (ticcmd_t *cmd)
no_fire = true;
//Distance to enemy.
dist = player->mo->AproxDistance(enemy, player->mo->_f_velx() - enemy->_f_velx(), player->mo->_f_vely() - enemy->_f_vely());
Dist = player->mo->Distance2D(enemy, player->mo->Vel.X - enemy->Vel.X, player->mo->Vel.Y - enemy->Vel.Y);
//FIRE EACH TYPE OF WEAPON DIFFERENT: Here should all the different weapons go.
if (player->ReadyWeapon->WeaponFlags & WIF_MELEEWEAPON)
@ -194,7 +193,7 @@ void DBot::Dofire (ticcmd_t *cmd)
else
{
//*4 is for atmosphere, the chainsaws sounding and all..
no_fire = (dist > (FLOAT2FIXED(MELEERANGE)*4));
no_fire = (Dist > MELEERANGE*4);
}
}
else if (player->ReadyWeapon->WeaponFlags & WIF_BOT_BFG)
@ -210,11 +209,11 @@ void DBot::Dofire (ticcmd_t *cmd)
{
//Special rules for RL
an = FireRox (enemy, cmd);
if(an)
if(an != 0)
{
angle = an;
Angle = an;
//have to be somewhat precise. to avoid suicide.
if (absangle(angle - player->mo->_f_angle()) < 12*ANGLE_1)
if (absangle(an, player->mo->Angles.Yaw) < 12.)
{
t_rocket = 9;
no_fire = false;
@ -223,17 +222,17 @@ void DBot::Dofire (ticcmd_t *cmd)
}
// prediction aiming
shootmissile:
fdist = player->mo->Distance2D(enemy);
fm = fdist / GetDefaultByType (player->ReadyWeapon->ProjectileType)->Speed;
Dist = player->mo->Distance2D(enemy);
fm = Dist / GetDefaultByType (player->ReadyWeapon->ProjectileType)->Speed;
bglobal.SetBodyAt(enemy->Pos() + enemy->Vel.XY() * fm * 2, 1);
angle = player->mo->__f_AngleTo(bglobal.body1);
Angle = player->mo->AngleTo(bglobal.body1);
if (Check_LOS (enemy, SHOOTFOV))
no_fire = false;
}
else
{
//Other weapons, mostly instant hit stuff.
angle = player->mo->__f_AngleTo(enemy);
Angle = player->mo->AngleTo(enemy);
aiming_penalty = 0;
if (enemy->flags & MF_SHADOW)
aiming_penalty += (pr_botdofire()%25)+10;
@ -246,17 +245,17 @@ shootmissile:
aiming_value = 1;
m = ((SHOOTFOV/2)-(aiming_value*SHOOTFOV/200)); //Higher skill is more accurate
if (m <= 0)
m = 1; //Prevents lock.
m = 1.; //Prevents lock.
if (m)
if (m != 0)
{
if (increase)
angle += m;
Angle += m;
else
angle -= m;
Angle -= m;
}
if (absangle(angle - player->mo->_f_angle()) < 4*ANGLE_1)
if (absangle(Angle, player->mo->Angles.Yaw) < 4.)
{
increase = !increase;
}
@ -291,7 +290,7 @@ bool FCajunMaster::IsLeader (player_t *player)
AActor *DBot::Choose_Mate ()
{
int count;
fixed_t closest_dist, test;
double closest_dist, test;
AActor *target;
AActor *observer;
@ -312,7 +311,7 @@ AActor *DBot::Choose_Mate ()
last_mate = NULL;
target = NULL;
closest_dist = FIXED_MAX;
closest_dist = FLT_MAX;
if (bot_observer)
observer = players[consoleplayer].mo;
else
@ -334,7 +333,7 @@ AActor *DBot::Choose_Mate ()
{
if (P_CheckSight (player->mo, client->mo, SF_IGNOREVISIBILITY))
{
test = client->mo->AproxDistance(player->mo);
test = client->mo->Distance2D(player->mo);
if (test < closest_dist)
{
@ -368,9 +367,9 @@ AActor *DBot::Choose_Mate ()
AActor *DBot::Find_enemy ()
{
int count;
fixed_t closest_dist, temp; //To target.
double closest_dist, temp; //To target.
AActor *target;
angle_t vangle;
DAngle vangle;
AActor *observer;
if (!deathmatch)
@ -380,13 +379,13 @@ AActor *DBot::Find_enemy ()
//Note: It's hard to ambush a bot who is not alone
if (allround || mate)
vangle = ANGLE_MAX;
vangle = 360.;
else
vangle = ENEMY_SCAN_FOV;
allround = false;
target = NULL;
closest_dist = FIXED_MAX;
closest_dist = FLT_MAX;
if (bot_observer)
observer = players[consoleplayer].mo;
else
@ -404,7 +403,7 @@ AActor *DBot::Find_enemy ()
if (Check_LOS (client->mo, vangle)) //Here's a strange one, when bot is standing still, the P_CheckSight within Check_LOS almost always returns false. tought it should be the same checksight as below but.. (below works) something must be fuckin wierd screded up.
//if(P_CheckSight(player->mo, players[count].mo))
{
temp = client->mo->AproxDistance(player->mo);
temp = client->mo->Distance2D(player->mo);
//Too dark?
if (temp > DARK_DIST &&
@ -463,7 +462,7 @@ void FCajunMaster::SetBodyAt (const DVector3 &pos, int hostnum)
//Emulates missile travel. Returns distance travelled.
fixed_t FCajunMaster::FakeFire (AActor *source, AActor *dest, ticcmd_t *cmd)
double FCajunMaster::FakeFire (AActor *source, AActor *dest, ticcmd_t *cmd)
{
AActor *th = Spawn ("CajunTrace", source->PosPlusZ(4*8.), NO_REPLACE);
@ -472,23 +471,22 @@ fixed_t FCajunMaster::FakeFire (AActor *source, AActor *dest, ticcmd_t *cmd)
th->Vel = source->Vec3To(dest).Resized(th->Speed);
fixed_t dist = 0;
double dist = 0;
while (dist < SAFE_SELF_MISDIST)
{
dist += th->_f_speed();
th->Move(th->_f_velx(), th->_f_vely(), th->_f_velz());
if (!CleanAhead (th, th->_f_X(), th->_f_Y(), cmd))
dist += th->Speed;
th->Move(th->Vel);
if (!CleanAhead (th, th->X(), th->Y(), cmd))
break;
}
th->Destroy ();
return dist;
}
angle_t DBot::FireRox (AActor *enemy, ticcmd_t *cmd)
DAngle DBot::FireRox (AActor *enemy, ticcmd_t *cmd)
{
double dist;
angle_t ang;
AActor *actor;
double m;
@ -497,8 +495,8 @@ angle_t DBot::FireRox (AActor *enemy, ticcmd_t *cmd)
actor = bglobal.body2;
dist = actor->Distance2D (enemy);
if (dist < SAFE_SELF_MISDIST/FRACUNIT)
return 0;
if (dist < SAFE_SELF_MISDIST)
return 0.;
//Predict.
m = ((dist+1) / GetDefaultByName("Rocket")->Speed);
@ -508,12 +506,11 @@ angle_t DBot::FireRox (AActor *enemy, ticcmd_t *cmd)
if (P_CheckSight (actor, bglobal.body1, SF_IGNOREVISIBILITY)) //See the predicted location, so give a test missile
{
FCheckPosition tm;
if (bglobal.SafeCheckPosition (player->mo, actor->_f_X(), actor->_f_Y(), tm))
if (bglobal.SafeCheckPosition (player->mo, actor->X(), actor->Y(), tm))
{
if (bglobal.FakeFire (actor, bglobal.body1, cmd) >= SAFE_SELF_MISDIST)
{
ang = actor->__f_AngleTo(bglobal.body1);
return ang;
return actor->AngleTo(bglobal.body1);
}
}
}
@ -522,21 +519,20 @@ angle_t DBot::FireRox (AActor *enemy, ticcmd_t *cmd)
{
if (bglobal.FakeFire (player->mo, enemy, cmd) >= SAFE_SELF_MISDIST)
{
ang = player->mo->__f_AngleTo(enemy);
return ang;
return player->mo->AngleTo(enemy);
}
}
return 0;
return 0.;
}
// [RH] We absolutely do not want to pick things up here. The bot code is
// executed apart from all the other simulation code, so we don't want it
// creating side-effects during gameplay.
bool FCajunMaster::SafeCheckPosition (AActor *actor, fixed_t x, fixed_t y, FCheckPosition &tm)
bool FCajunMaster::SafeCheckPosition (AActor *actor, double x, double y, FCheckPosition &tm)
{
ActorFlags savedFlags = actor->flags;
actor->flags &= ~MF_PICKUP;
bool res = P_CheckPosition (actor, x, y, tm);
bool res = P_CheckPosition (actor, DVector2(x, y), tm);
actor->flags = savedFlags;
return res;
}

View File

@ -35,21 +35,21 @@ extern dirtype_t diags[4];
//which can be a weapon/enemy/item whatever.
void DBot::Roam (ticcmd_t *cmd)
{
int delta;
if (Reachable(dest))
{ // Straight towards it.
angle = player->mo->__f_AngleTo(dest);
Angle = player->mo->AngleTo(dest);
}
else if (player->mo->movedir < 8) // turn towards movement direction if not there yet
{
angle &= (angle_t)(7<<29);
delta = angle - (player->mo->movedir << 29);
// no point doing this with floating point angles...
unsigned angle = Angle.BAMs() & (unsigned)(7 << 29);
int delta = angle - (player->mo->movedir << 29);
if (delta > 0)
angle -= ANG45;
Angle -= 45;
else if (delta < 0)
angle += ANG45;
Angle += 45;
}
// chase towards destination.
@ -61,7 +61,7 @@ void DBot::Roam (ticcmd_t *cmd)
bool DBot::Move (ticcmd_t *cmd)
{
fixed_t tryx, tryy;
double tryx, tryy;
bool try_ok;
int good;
@ -71,8 +71,8 @@ bool DBot::Move (ticcmd_t *cmd)
if ((unsigned)player->mo->movedir >= 8)
I_Error ("Weird bot movedir!");
tryx = player->mo->_f_X() + 8*xspeed[player->mo->movedir];
tryy = player->mo->_f_Y() + 8*yspeed[player->mo->movedir];
tryx = player->mo->X() + 8*xspeed[player->mo->movedir];
tryy = player->mo->Y() + 8*yspeed[player->mo->movedir];
try_ok = bglobal.CleanAhead (player->mo, tryx, tryy, cmd);
@ -148,18 +148,18 @@ void DBot::NewChaseDir (ticcmd_t *cmd)
olddir = (dirtype_t)player->mo->movedir;
turnaround = opposite[olddir];
fixedvec2 delta = player->mo->_f_Vec2To(dest);
DVector2 delta = player->mo->Vec2To(dest);
if (delta.x > 10*FRACUNIT)
if (delta.X > 10)
d[1] = DI_EAST;
else if (delta.x < -10*FRACUNIT)
else if (delta.X < -10)
d[1] = DI_WEST;
else
d[1] = DI_NODIR;
if (delta.y < -10*FRACUNIT)
if (delta.Y < -10)
d[2] = DI_SOUTH;
else if (delta.y > 10*FRACUNIT)
else if (delta.Y > 10)
d[2] = DI_NORTH;
else
d[2] = DI_NODIR;
@ -167,19 +167,19 @@ void DBot::NewChaseDir (ticcmd_t *cmd)
// try direct route
if (d[1] != DI_NODIR && d[2] != DI_NODIR)
{
player->mo->movedir = diags[((delta.y<0)<<1)+(delta.x>0)];
player->mo->movedir = diags[((delta.Y < 0) << 1) + (delta.X > 0)];
if (player->mo->movedir != turnaround && TryWalk(cmd))
return;
}
// try other directions
if (pr_botnewchasedir() > 200
|| abs(delta.y)>abs(delta.x))
{
tdir=d[1];
d[1]=d[2];
d[2]=(dirtype_t)tdir;
}
if (pr_botnewchasedir() > 200
|| fabs(delta.Y) > fabs(delta.X))
{
tdir = d[1];
d[1] = d[2];
d[2] = (dirtype_t)tdir;
}
if (d[1]==turnaround)
d[1]=DI_NODIR;
@ -260,7 +260,7 @@ void DBot::NewChaseDir (ticcmd_t *cmd)
// This is also a traverse function for
// bots pre-rocket fire (preventing suicide)
//
bool FCajunMaster::CleanAhead (AActor *thing, fixed_t x, fixed_t y, ticcmd_t *cmd)
bool FCajunMaster::CleanAhead (AActor *thing, double x, double y, ticcmd_t *cmd)
{
FCheckPosition tm;
@ -272,14 +272,14 @@ bool FCajunMaster::CleanAhead (AActor *thing, fixed_t x, fixed_t y, ticcmd_t *cm
if (tm.ceilingz - tm.floorz < thing->Height)
return false; // doesn't fit
double maxmove = FIXED2FLOAT(MAXMOVEHEIGHT);
double maxmove = MAXMOVEHEIGHT;
if (!(thing->flags&MF_MISSILE))
{
if(tm.floorz > (thing->Sector->floorplane._f_ZatPointF(x, y)+maxmove)) //Too high wall
if(tm.floorz > (thing->Sector->floorplane.ZatPoint(x, y)+maxmove)) //Too high wall
return false;
//Jumpable
if(tm.floorz > (thing->Sector->floorplane._f_ZatPointF(x, y)+thing->MaxStepHeight))
if(tm.floorz > (thing->Sector->floorplane.ZatPoint(x, y)+thing->MaxStepHeight))
cmd->ucmd.buttons |= BT_JUMP;
@ -289,7 +289,7 @@ bool FCajunMaster::CleanAhead (AActor *thing, fixed_t x, fixed_t y, ticcmd_t *cm
// jump out of water
// if((thing->eflags & (MF_UNDERWATER|MF_TOUCHWATER))==(MF_UNDERWATER|MF_TOUCHWATER))
// maxstep=37*FRACUNIT;
// maxstep=37;
if ( !(thing->flags & MF_TELEPORT) &&
(tm.floorz - thing->Z() > thing->MaxStepHeight) )
@ -327,11 +327,11 @@ void DBot::TurnToAng ()
if(enemy)
if(!dest) //happens when running after item in combat situations, or normal, prevents weak turns
if(player->ReadyWeapon->ProjectileType == NULL && !(player->ReadyWeapon->WeaponFlags & WIF_MELEEWEAPON))
if(Check_LOS(enemy, SHOOTFOV+5*ANGLE_1))
if(Check_LOS(enemy, SHOOTFOV+5))
maxturn = 3;
}
DAngle distance = deltaangle(player->mo->Angles.Yaw, ANGLE2DBL(angle));
DAngle distance = deltaangle(player->mo->Angles.Yaw, Angle);
if (fabs (distance) < OKAYRANGE && !enemy)
return;
@ -348,8 +348,8 @@ void DBot::Pitch (AActor *target)
double aim;
double diff;
diff = target->_f_Z() - player->mo->_f_Z();
aim = g_atan(diff / (double)player->mo->AproxDistance(target));
diff = target->Z() - player->mo->Z();
aim = g_atan(diff / player->mo->Distance2D(target));
player->mo->Angles.Pitch = ToDegrees(aim);
}

View File

@ -75,38 +75,41 @@ void DBot::Think ()
}
}
#define THINKDISTSQ (50000.*50000./(65536.*65536.))
//how the bot moves.
//MAIN movement function.
void DBot::ThinkForMove (ticcmd_t *cmd)
{
fixed_t dist;
double dist;
bool stuck;
int r;
stuck = false;
dist = dest ? player->mo->AproxDistance(dest) : 0;
dist = dest ? player->mo->Distance2D(dest) : 0;
if (missile &&
((!missile->_f_velx() || !missile->_f_vely()) || !Check_LOS(missile, SHOOTFOV*3/2)))
(!missile->Vel.X || !missile->Vel.Y || !Check_LOS(missile, SHOOTFOV*3/2)))
{
sleft = !sleft;
missile = NULL; //Probably ended its travel.
}
#if 0 // this has always been broken and without any reference it cannot be fixed.
if (player->mo->Angles.Pitch > 0)
player->mo->Angles.Pitch -= 80;
else if (player->mo->Angles.Pitch <= -60)
player->mo->Angles.Pitch += 80;
#endif
//HOW TO MOVE:
if (missile && (player->mo->AproxDistance(missile)<AVOID_DIST)) //try avoid missile got from P_Mobj.c thinking part.
if (missile && (player->mo->Distance2D(missile)<AVOID_DIST)) //try avoid missile got from P_Mobj.c thinking part.
{
Pitch (missile);
angle = player->mo->__f_AngleTo(missile);
Angle = player->mo->AngleTo(missile);
cmd->ucmd.sidemove = sleft ? -SIDERUN : SIDERUN;
cmd->ucmd.forwardmove = -FORWARDRUN; //Back IS best.
if ((player->mo->AproxDistance(oldx, oldy)<50000)
if ((player->mo->Pos() - old).LengthSquared() < THINKDISTSQ
&& t_strafe<=0)
{
t_strafe = 5;
@ -159,7 +162,7 @@ void DBot::ThinkForMove (ticcmd_t *cmd)
t_fight = AFTERTICS;
if (t_strafe <= 0 &&
(player->mo->AproxDistance(oldx, oldy)<50000
((player->mo->Pos() - old).LengthSquared() < THINKDISTSQ
|| ((pr_botmove()%30)==10))
)
{
@ -168,7 +171,7 @@ void DBot::ThinkForMove (ticcmd_t *cmd)
sleft = !sleft;
}
angle = player->mo->__f_AngleTo(enemy);
Angle = player->mo->AngleTo(enemy);
if (player->ReadyWeapon == NULL ||
player->mo->Distance2D(enemy) >
@ -196,7 +199,7 @@ void DBot::ThinkForMove (ticcmd_t *cmd)
}
else if (mate && !enemy && (!dest || dest==mate)) //Follow mate move.
{
fixed_t matedist;
double matedist;
Pitch (mate);
@ -209,9 +212,9 @@ void DBot::ThinkForMove (ticcmd_t *cmd)
goto roam;
}
angle = player->mo->__f_AngleTo(mate);
Angle = player->mo->AngleTo(mate);
matedist = player->mo->AproxDistance(mate);
matedist = player->mo->Distance2D(mate);
if (matedist > (FRIEND_DIST*2))
cmd->ucmd.forwardmove = FORWARDRUN;
else if (matedist > FRIEND_DIST)
@ -244,7 +247,7 @@ void DBot::ThinkForMove (ticcmd_t *cmd)
(pr_botmove()%100)>skill.isp) && player->ReadyWeapon != NULL && !(player->ReadyWeapon->WeaponFlags & WIF_WIMPY_WEAPON))
dest = enemy;//Dont let enemy kill the bot by supressive fire. So charge enemy.
else //hide while t_fight, but keep view at enemy.
angle = player->mo->__f_AngleTo(enemy);
Angle = player->mo->AngleTo(enemy);
} //Just a monster, so kill it.
else
dest = enemy;
@ -306,8 +309,7 @@ void DBot::ThinkForMove (ticcmd_t *cmd)
if (t_fight<(AFTERTICS/2))
player->mo->flags |= MF_DROPOFF;
oldx = player->mo->_f_X();
oldy = player->mo->_f_Y();
old = player->mo->Pos();
}
//BOT_WhatToGet

View File

@ -350,7 +350,7 @@ enum
{
BCOMPATF_SETSLOPEOVERFLOW = 1 << 0, // SetSlope things can overflow
BCOMPATF_RESETPLAYERSPEED = 1 << 1, // Set player speed to 1.0 when changing maps
BCOMPATF_VILEGHOSTS = 1 << 2, // Monsters' _f_radius() and height aren't restored properly when resurrected.
BCOMPATF_VILEGHOSTS = 1 << 2, // Monsters' radius and height aren't restored properly when resurrected.
BCOMPATF_BADTELEPORTERS = 1 << 3, // Ignore tags on Teleport specials
BCOMPATF_BADPORTALS = 1 << 4, // Restores the old unstable portal behavior
BCOMPATF_REBUILDNODES = 1 << 5, // Force node rebuild

View File

@ -99,8 +99,9 @@ dirtype_t diags[4] =
DI_NORTHWEST, DI_NORTHEAST, DI_SOUTHWEST, DI_SOUTHEAST
};
fixed_t xspeed[8] = {FRACUNIT,46341,0,-46341,-FRACUNIT,-46341,0,46341};
fixed_t yspeed[8] = {0,46341,FRACUNIT,46341,0,-46341,-FRACUNIT,-46341};
#define SQRTHALF 0.7071075439453125
double xspeed[8] = {1,SQRTHALF,0,-SQRTHALF,-1,-SQRTHALF,0,SQRTHALF};
double yspeed[8] = {0,SQRTHALF,1,SQRTHALF,0,-SQRTHALF,-1,-SQRTHALF};
void P_RandomChaseDir (AActor *actor);
@ -511,8 +512,8 @@ bool P_Move (AActor *actor)
}
}
tryx = (origx = actor->_f_X()) + (deltax = FixedMul (speed, xspeed[actor->movedir]));
tryy = (origy = actor->_f_Y()) + (deltay = FixedMul (speed, yspeed[actor->movedir]));
tryx = (origx = actor->_f_X()) + (deltax = fixed_t (speed * xspeed[actor->movedir]));
tryy = (origy = actor->_f_Y()) + (deltay = fixed_t (speed * yspeed[actor->movedir]));
// Like P_XYMovement this should do multiple moves if the step size is too large
@ -2599,8 +2600,8 @@ static bool P_CheckForResurrection(AActor *self, bool usevilestates)
{
const fixed_t absSpeed = abs (self->_f_speed());
fixedvec2 viletry = self->Vec2Offset(
FixedMul (absSpeed, xspeed[self->movedir]),
FixedMul (absSpeed, yspeed[self->movedir]), true);
int (absSpeed * xspeed[self->movedir]),
int (absSpeed * yspeed[self->movedir]), true);
FPortalGroupArray check(FPortalGroupArray::PGA_Full3d);

View File

@ -24,7 +24,7 @@ enum dirtype_t
NUMDIRS
};
extern fixed_t xspeed[8], yspeed[8];
extern double xspeed[8], yspeed[8];
enum LO_Flags
{

View File

@ -281,10 +281,14 @@ inline bool P_CheckPosition(AActor *thing, const fixedvec3 &pos, bool actorsonly
{
return P_CheckPosition(thing, pos.x, pos.y, actorsonly);
}
inline bool P_CheckPosition(AActor *thing, const DVector3 &pos, bool actorsonly = false)
inline bool P_CheckPosition(AActor *thing, const DVector2 &pos, bool actorsonly = false)
{
return P_CheckPosition(thing, FLOAT2FIXED(pos.X), FLOAT2FIXED(pos.Y), actorsonly);
}
inline bool P_CheckPosition(AActor *thing, const DVector2 &pos, FCheckPosition &tm, bool actorsonly = false)
{
return P_CheckPosition(thing, FLOAT2FIXED(pos.X), FLOAT2FIXED(pos.Y), tm, actorsonly);
}
AActor *P_CheckOnmobj (AActor *thing);
void P_FakeZMovement (AActor *mo);
bool P_TryMove (AActor* thing, fixed_t x, fixed_t y, int dropoff, const secplane_t * onfloor, FCheckPosition &tm, bool missileCheck = false);

View File

@ -2828,7 +2828,7 @@ void FSlide::SlideTraverse(fixed_t startx, fixed_t starty, fixed_t endx, fixed_t
}
// set openrange, opentop, openbottom
P_LineOpening(open, slidemo, li, it.InterceptPoint(in));
P_LineOpening(open, slidemo, li, it._f_InterceptPoint(in));
if (open.range < slidemo->Height)
goto isblocking; // doesn't fit
@ -3184,7 +3184,7 @@ bool FSlide::BounceTraverse(fixed_t startx, fixed_t starty, fixed_t endx, fixed_
}
P_LineOpening(open, slidemo, li, it.InterceptPoint(in)); // set openrange, opentop, openbottom
P_LineOpening(open, slidemo, li, it._f_InterceptPoint(in)); // set openrange, opentop, openbottom
if (open.range < slidemo->Height)
goto bounceblocking; // doesn't fit
@ -3806,7 +3806,7 @@ struct aim_t
// Crosses a two sided line.
// A two sided line will restrict the possible target ranges.
FLineOpening open;
P_LineOpening(open, NULL, li, it.InterceptPoint(in), FIXED_MIN, 0, FFCF_NODROPOFF);
P_LineOpening(open, NULL, li, it._f_InterceptPoint(in), FIXED_MIN, 0, FFCF_NODROPOFF);
// The following code assumes that portals on the front of the line have already been processed.
@ -3831,7 +3831,7 @@ struct aim_t
return;
int planestocheck;
if (!AimTraverse3DFloors(it.Trace(), in, frontflag, &planestocheck))
if (!AimTraverse3DFloors(it._f_Trace(), in, frontflag, &planestocheck))
return;
if (aimdebug)
@ -3961,7 +3961,7 @@ struct aim_t
fixed_t cosine = finecosine[thingpitch >> ANGLETOFINESHIFT];
if (cosine != 0)
{
fixed_t d3 = FixedDiv(FixedMul(P_AproxDistance(it.Trace().dx, it.Trace().dy), in->frac), cosine);
fixed_t d3 = FixedDiv(FixedMul(P_AproxDistance(it._f_Trace().dx, it._f_Trace().dy), in->frac), cosine);
if (d3 > attackrange)
{
return;
@ -4560,7 +4560,7 @@ void P_TraceBleed(int damage, AActor *target, angle_t angle, int pitch)
void P_TraceBleed(int damage, AActor *target, AActor *missile)
{
int pitch;
DAngle pitch;
if (target == NULL || missile->flags3 & MF3_BLOODLESSIMPACT)
{
@ -4572,15 +4572,13 @@ void P_TraceBleed(int damage, AActor *target, AActor *missile)
double aim;
aim = g_atan((double)missile->_f_velz() / (double)target->AproxDistance(missile));
pitch = -(int)(aim * ANGLE_180 / PI);
pitch = -ToDegrees(aim);
}
else
{
pitch = 0;
pitch = 0.;
}
P_TraceBleed(damage, target->_f_X(), target->_f_Y(), target->_f_Z() + target->_f_height() / 2,
target, missile->__f_AngleTo(target),
pitch);
P_TraceBleed(damage, target->PosPlusZ(target->Height/2), target, missile->AngleTo(target), pitch);
}
//==========================================================================
@ -4958,7 +4956,7 @@ bool P_UseTraverse(AActor *usething, fixed_t startx, fixed_t starty, fixed_t end
}
else
{
P_LineOpening(open, NULL, in->d.line, it.InterceptPoint(in));
P_LineOpening(open, NULL, in->d.line, it._f_InterceptPoint(in));
}
if (open.range <= 0 ||
(in->d.line->special != 0 && (i_compatflags & COMPATF_USEBLOCKING)))
@ -5066,7 +5064,7 @@ bool P_NoWayTraverse(AActor *usething, fixed_t startx, fixed_t starty, fixed_t e
if (ld->special) continue;
if (ld->isLinePortal()) return false;
if (ld->flags&(ML_BLOCKING | ML_BLOCKEVERYTHING | ML_BLOCK_PLAYERS)) return true;
P_LineOpening(open, NULL, ld, it.InterceptPoint(in));
P_LineOpening(open, NULL, ld, it._f_InterceptPoint(in));
if (open.range <= 0 ||
open.bottom > usething->Z() + usething->MaxStepHeight ||
open.top < usething->Top()) return true;
@ -5148,7 +5146,7 @@ bool P_UsePuzzleItem(AActor *PuzzleItemUser, int PuzzleItemType)
{ // Check line
if (in->d.line->special != UsePuzzleItem)
{
P_LineOpening(open, NULL, in->d.line, it.InterceptPoint(in));
P_LineOpening(open, NULL, in->d.line, it._f_InterceptPoint(in));
if (open.range <= 0)
{
return false; // can't use through a wall

View File

@ -1425,6 +1425,7 @@ intercept_t *FPathTraverse::Next()
{
dist = scan->frac;
in = scan;
in->Frac = FIXED2FLOAT(in->frac);
}
}
@ -1658,6 +1659,10 @@ void FPathTraverse::init (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, int fl
break;
}
}
ftrace.dx = FIXED2DBL(trace.dx);
ftrace.dy = FIXED2DBL(trace.dy);
ftrace.x = FIXED2DBL(trace.x);
ftrace.y = FIXED2DBL(trace.y);
}
//===========================================================================

View File

@ -25,6 +25,7 @@ struct divline_t
struct intercept_t
{
double Frac;
fixed_t frac; // along trace line
bool isaline;
bool done;
@ -390,6 +391,7 @@ class FPathTraverse
protected:
static TArray<intercept_t> intercepts;
divline_t ftrace;
fdivline_t trace;
fixed_t startfrac;
unsigned int intercept_index;
@ -407,12 +409,17 @@ public:
{
init(x1, y1, x2, y2, flags, startfrac);
}
FPathTraverse(double x1, double y1, double x2, double y2, int flags, double startfrac = 0)
{
init(FLOAT2FIXED(x1), FLOAT2FIXED(y1), FLOAT2FIXED(x2), FLOAT2FIXED(y2), flags, FLOAT2FIXED(startfrac));
}
void init(fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, int flags, fixed_t startfrac = 0);
int PortalRelocate(intercept_t *in, int flags, fixedvec3 *optpos = NULL);
virtual ~FPathTraverse();
const fdivline_t &Trace() const { return trace; }
const fdivline_t &_f_Trace() const { return trace; }
const divline_t &Trace() const { return ftrace; }
inline fixedvec2 InterceptPoint(const intercept_t *in)
inline fixedvec2 _f_InterceptPoint(const intercept_t *in)
{
return
{
@ -420,6 +427,14 @@ public:
trace.y + FixedMul(trace.dy, in->frac)
};
}
inline DVector2 InterceptPoint(const intercept_t *in)
{
return
{
FIXED2DBL(trace.x + FixedMul(trace.dx, in->frac)),
FIXED2DBL(trace.y + FixedMul(trace.dy, in->frac))
};
}
};

View File

@ -3171,9 +3171,8 @@ bool AActor::IsOkayToAttack (AActor *link)
// to only allow the check to succeed if the enemy was in a ~84<38> FOV of the player
if (flags3 & MF3_SCREENSEEKER)
{
angle_t angle = Friend->__f_AngleTo(link) - Friend->_f_angle();
angle >>= 24;
if (angle>226 || angle<30)
DAngle angle = absangle(Friend->AngleTo(link), Friend->Angles.Yaw);
if (angle < 30 * (256./360.))
{
return true;
}
@ -3562,7 +3561,7 @@ void AActor::Tick ()
{
if (!players[i].Bot->missile && (flags3 & MF3_WARNBOT))
{ //warn for incoming missiles.
if (target != players[i].mo && players[i].Bot->Check_LOS (this, ANGLE_90))
if (target != players[i].mo && players[i].Bot->Check_LOS (this, 90.))
players[i].Bot->missile = this;
}
}

View File

@ -3183,37 +3183,6 @@ void player_t::Serialize (FArchive &arc)
onground = (mo->Z() <= mo->floorz) || (mo->flags2 & MF2_ONMOBJ) || (mo->BounceFlags & BOUNCE_MBF) || (cheats & CF_NOCLIP2);
}
if (SaveVersion < 4514 && IsBot)
{
Bot = new DBot;
arc << Bot->angle
<< Bot->dest
<< Bot->prev
<< Bot->enemy
<< Bot->missile
<< Bot->mate
<< Bot->last_mate
<< Bot->skill
<< Bot->t_active
<< Bot->t_respawn
<< Bot->t_strafe
<< Bot->t_react
<< Bot->t_fight
<< Bot->t_roam
<< Bot->t_rocket
<< Bot->first_shot
<< Bot->sleft
<< Bot->allround
<< Bot->oldx
<< Bot->oldy;
}
if (SaveVersion < 4516 && Bot != NULL)
{
Bot->player = this;
}
if (arc.IsLoading ())
{
// If the player reloaded because they pressed +use after dying, we

View File

@ -716,7 +716,7 @@ fixedvec2 P_GetOffsetPosition(fixed_t x, fixed_t y, fixed_t dx, fixed_t dy)
// Teleport portals are intentionally ignored since skipping this stuff is their entire reason for existence.
if (port->mFlags & PORTF_INTERACTIVE)
{
fixedvec2 hit = it.InterceptPoint(in);
fixedvec2 hit = it._f_InterceptPoint(in);
if (port->mType == PORTT_LINKED)
{