Merge branch 'floatcvt'

This commit is contained in:
Christoph Oelckers 2016-04-05 21:42:09 +02:00
commit 1a5a00a76e
314 changed files with 14459 additions and 13379 deletions

View file

@ -164,7 +164,7 @@ if( MSVC )
string(REPLACE " /GR" " " CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} )
else()
set( REL_LINKER_FLAGS "" )
set( ALL_C_FLAGS "" )
set( ALL_C_FLAGS "-ffp-contract=off" )
set( REL_C_FLAGS "" )
set( DEB_C_FLAGS "" )

View file

@ -1159,6 +1159,22 @@ add_executable( zdoom WIN32 MACOSX_BUNDLE
g_shared/sbar_mugshot.cpp
g_shared/shared_hud.cpp
g_shared/shared_sbar.cpp
math/asin.c
math/atan.c
math/const.c
math/cosh.c
math/exp.c
math/isnan.c
math/log.c
math/log10.c
math/mtherr.c
math/polevl.c
math/sin.c
math/sinh.c
math/sqrt.c
math/tan.c
math/tanh.c
math/fastsin.cpp
resourcefiles/ancientzip.cpp
resourcefiles/file_7z.cpp
resourcefiles/file_grp.cpp
@ -1355,6 +1371,7 @@ source_group("Games\\Hexen Game" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR
source_group("Games\\Raven Shared" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/g_raven/.+")
source_group("Games\\Strife Game" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/g_strife/.+")
source_group("Intermission" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/intermission/.+")
source_group("Math" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/math/.+")
source_group("Menu" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/menu/.+")
source_group("Render Core\\Render Headers" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/r_.+\\.h$")
source_group("Render Core\\Render Sources" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/r_.+\\.cpp$")

View file

@ -25,6 +25,7 @@
// Basics.
#include "tables.h"
#include "templates.h"
// We need the thinker_t stuff.
#include "dthinker.h"
@ -414,24 +415,12 @@ enum ActorRenderFlag
RF_FORCEXYBILLBOARD = 0x20000, // [BB] OpenGL only: draw with xy axis billboard, i.e. unanchored (overrides gl_billboard_mode setting)
};
#define TRANSLUC25 (FRACUNIT/4)
#define TRANSLUC33 (FRACUNIT/3)
#define TRANSLUC50 (FRACUNIT/2)
#define TRANSLUC66 ((FRACUNIT*2)/3)
#define TRANSLUC75 ((FRACUNIT*3)/4)
// <wingdi.h> also #defines OPAQUE
#ifndef OPAQUE
#define OPAQUE (FRACUNIT)
#endif
// This translucency value produces the closest match to Heretic's TINTTAB.
// ~40% of the value of the overlaid image shows through.
#define HR_SHADOW (0x6800)
const double HR_SHADOW = (0x6800 / 65536.);
// Hexen's TINTTAB is the same as Heretic's, just reversed.
#define HX_SHADOW (0x9800)
#define HX_ALTSHADOW (0x6800)
const double HX_SHADOW = (0x9800 / 65536.);
const double HX_ALTSHADOW = (0x6800 / 65536.);
// This could easily be a bool but then it'd be much harder to find later. ;)
enum replace_t
@ -533,6 +522,10 @@ enum EThingSpecialActivationType
THINGSPEC_Switch = 1<<10, // The thing is alternatively activated and deactivated when triggered
};
#define ONFLOORZ FIXED_MIN
#define ONCEILINGZ FIXED_MAX
#define FLOATRANDZ (FIXED_MAX-1)
class FDecalBase;
class AInventory;
@ -568,9 +561,7 @@ public:
int Amount;
};
fixed_t P_AproxDistance (fixed_t dx, fixed_t dy); // since we cannot include p_local here...
angle_t R_PointToAngle2 (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2); // same reason here with r_defs.h
const double MinVel = EQUAL_EPSILON;
// Map Object definition.
class AActor : public DThinker
@ -586,7 +577,7 @@ public:
void Serialize (FArchive &arc);
static AActor *StaticSpawn (PClassActor *type, fixed_t x, fixed_t y, fixed_t z, replace_t allowreplacement, bool SpawningMapThing = false);
static AActor *StaticSpawn (PClassActor *type, const DVector3 &pos, replace_t allowreplacement, bool SpawningMapThing = false);
inline AActor *GetDefault () const
{
@ -596,11 +587,11 @@ public:
DDropItem *GetDropItems() const;
// Return true if the monster should use a missile attack, false for melee
bool SuggestMissileAttack (fixed_t dist);
bool SuggestMissileAttack (double dist);
// Adjusts the angle for deflection/reflection of incoming missiles
// Returns true if the missile should be allowed to explode anyway
bool AdjustReflectionAngle (AActor *thing, angle_t &angle);
bool AdjustReflectionAngle (AActor *thing, DAngle &angle);
// Returns true if this actor is within melee range of its target
bool CheckMeleeRange();
@ -644,7 +635,7 @@ public:
// Called when an actor is to be reflected by a disc of repulsion.
// Returns true to continue normal blast processing.
virtual bool SpecialBlastHandling (AActor *source, fixed_t strength);
virtual bool SpecialBlastHandling (AActor *source, double strength);
// Called by RoughBlockCheck
bool IsOkayToAttack (AActor *target);
@ -743,18 +734,18 @@ public:
inline bool IsNoClip2() const;
void CheckPortalTransition(bool islinked);
fixedvec3 GetPortalTransition(fixed_t byoffset, sector_t **pSec = NULL);
DVector3 GetPortalTransition(double byoffset, sector_t **pSec = NULL);
// What species am I?
virtual FName GetSpecies();
fixed_t GetBobOffset(fixed_t ticfrac=0) const
double GetBobOffset(double ticfrac = 0) const
{
if (!(flags2 & MF2_FLOATBOB))
{
return 0;
}
return finesine[MulScale22(((FloatBobPhase + level.maptime) << FRACBITS) + ticfrac, FINEANGLES) & FINEMASK] * 8;
if (!(flags2 & MF2_FLOATBOB))
{
return 0;
}
return BobSin(FloatBobPhase + level.maptime + ticfrac);
}
// Enter the crash state
@ -763,7 +754,7 @@ public:
// Return starting health adjusted by skill level
int SpawnHealth() const;
int GetGibHealth() const;
fixed_t GetCameraHeight() const;
double GetCameraHeight() const;
inline bool isMissile(bool precise=true)
{
@ -782,9 +773,9 @@ public:
}
// These also set CF_INTERPVIEW for players.
void SetPitch(int p, bool interpolate, bool forceclamp = false);
void SetAngle(angle_t ang, bool interpolate);
void SetRoll(angle_t roll, bool interpolate);
void SetPitch(DAngle p, bool interpolate, bool forceclamp = false);
void SetAngle(DAngle ang, bool interpolate);
void SetRoll(DAngle roll, bool interpolate);
PClassActor *GetBloodType(int type = 0) const
{
@ -813,142 +804,137 @@ public:
return bloodcls;
}
fixed_t AproxDistance(fixed_t otherx, fixed_t othery)
double Distance2D(AActor *other, bool absolute = false)
{
return P_AproxDistance(X() - otherx, Y() - othery);
DVector2 otherpos = absolute ? other->Pos() : other->PosRelative(this);
return (Pos().XY() - otherpos).Length();
}
fixed_t AngleTo(fixed_t otherx, fixed_t othery)
double Distance2D(double x, double y) const
{
return R_PointToAngle2(X(), Y(), otherx, othery);
return DVector2(X() - x, Y() - y).Length();
}
fixed_t AngleTo(fixedvec2 other)
double Distance2D(AActor *other, double xadd, double yadd, bool absolute = false)
{
return R_PointToAngle2(X(), Y(), other.x, other.y);
DVector3 otherpos = absolute ? other->Pos() : other->PosRelative(this);
return DVector2(X() - otherpos.X + xadd, Y() - otherpos.Y + yadd).Length();
}
// '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)
{
fixedvec3 otherpos = absolute ? other->Pos() : other->PosRelative(this);
return P_AproxDistance(X() - otherpos.x, Y() - otherpos.y);
}
fixed_t AproxDistance(AActor *other, fixed_t xadd, fixed_t yadd, bool absolute = false)
{
fixedvec3 otherpos = absolute ? other->Pos() : other->PosRelative(this);
return P_AproxDistance(X() - otherpos.x + xadd, Y() - otherpos.y + yadd);
}
fixed_t AproxDistance3D(AActor *other, bool absolute = false)
{
return P_AproxDistance(AproxDistance(other), Z() - other->Z());
}
// more precise, but slower version, being used in a few places
fixed_t Distance2D(AActor *other, bool absolute = false)
{
fixedvec3 otherpos = absolute ? other->Pos() : other->PosRelative(this);
return xs_RoundToInt(DVector2(X() - otherpos.x, Y() - otherpos.y).Length());
}
// a full 3D version of the above
fixed_t Distance3D(AActor *other, bool absolute = false)
double Distance3D(AActor *other, bool absolute = false)
{
fixedvec3 otherpos = absolute ? other->Pos() : other->PosRelative(this);
return xs_RoundToInt(DVector3(X() - otherpos.x, Y() - otherpos.y, Z() - otherpos.z).Length());
DVector3 otherpos = absolute ? other->Pos() : other->PosRelative(this);
return (Pos() - otherpos).Length();
}
angle_t AngleTo(AActor *other, bool absolute = false)
DAngle AngleTo(AActor *other, bool absolute = false)
{
fixedvec3 otherpos = absolute ? other->Pos() : other->PosRelative(this);
return R_PointToAngle2(X(), Y(), otherpos.x, otherpos.y);
DVector2 otherpos = absolute ? other->Pos() : other->PosRelative(this);
return VecToAngle(otherpos - Pos().XY());
}
angle_t AngleTo(AActor *other, fixed_t oxofs, fixed_t oyofs, bool absolute = false) const
DAngle AngleTo(AActor *other, double oxofs, double oyofs, bool absolute = false) const
{
return R_PointToAngle2(X(), Y(), other->X() + oxofs, other->Y() + oyofs);
DVector2 otherpos = absolute ? other->Pos() : other->PosRelative(this);
return VecToAngle(otherpos - Pos() + DVector2(oxofs, oyofs));
}
fixedvec2 Vec2To(AActor *other) const
DVector2 Vec2To(AActor *other) const
{
fixedvec3 otherpos = other->PosRelative(this);
fixedvec2 ret = { otherpos.x - X(), otherpos.y - Y() };
return ret;
return other->PosRelative(this) - Pos();
}
fixedvec3 Vec3To(AActor *other) const
DVector3 Vec3To(AActor *other) const
{
fixedvec3 otherpos = other->PosRelative(this);
fixedvec3 ret = { otherpos.x - X(), otherpos.y - Y(), otherpos.z - Z() };
return ret;
return other->PosRelative(this) - Pos();
}
fixedvec2 Vec2Offset(fixed_t dx, fixed_t dy, bool absolute = false)
DVector2 Vec2Offset(double dx, double dy, bool absolute = false)
{
if (absolute)
{
fixedvec2 ret = { X() + dx, Y() + dy };
return ret;
}
else return P_GetOffsetPosition(X(), Y(), dx, dy);
}
fixedvec2 Vec2Angle(fixed_t length, angle_t angle, bool absolute = false)
{
if (absolute)
{
fixedvec2 ret = { X() + FixedMul(length, finecosine[angle >> ANGLETOFINESHIFT]),
Y() + FixedMul(length, finesine[angle >> ANGLETOFINESHIFT]) };
return ret;
}
else return P_GetOffsetPosition(X(), Y(), FixedMul(length, finecosine[angle >> ANGLETOFINESHIFT]), FixedMul(length, finesine[angle >> ANGLETOFINESHIFT]));
}
fixedvec3 Vec3Offset(fixed_t dx, fixed_t dy, fixed_t dz, bool absolute = false)
{
if (absolute)
{
fixedvec3 ret = { X() + dx, Y() + dy, Z() + dz };
return ret;
return { X() + dx, Y() + dy };
}
else
{
fixedvec2 op = P_GetOffsetPosition(X(), Y(), dx, dy);
fixedvec3 pos = { op.x, op.y, Z() + dz };
return pos;
return P_GetOffsetPosition(X(), Y(), dx, dy);
}
}
fixedvec3 Vec3Angle(fixed_t length, angle_t angle, fixed_t dz, bool absolute = false)
DVector3 Vec2OffsetZ(double dx, double dy, double atz, bool absolute = false)
{
if (absolute)
{
fixedvec3 ret = { X() + FixedMul(length, finecosine[angle >> ANGLETOFINESHIFT]),
Y() + FixedMul(length, finesine[angle >> ANGLETOFINESHIFT]), Z() + dz };
return ret;
return{ X() + dx, Y() + dy, atz };
}
else
{
fixedvec2 op = P_GetOffsetPosition(X(), Y(), FixedMul(length, finecosine[angle >> ANGLETOFINESHIFT]), FixedMul(length, finesine[angle >> ANGLETOFINESHIFT]));
fixedvec3 pos = { op.x, op.y, Z() + dz };
return pos;
DVector2 v = P_GetOffsetPosition(X(), Y(), dx, dy);
return DVector3(v, atz);
}
}
DVector2 Vec2Angle(double length, DAngle angle, bool absolute = false)
{
if (absolute)
{
return{ X() + length * angle.Cos(), Y() + length * angle.Sin() };
}
else
{
return P_GetOffsetPosition(X(), Y(), length*angle.Cos(), length*angle.Sin());
}
}
DVector3 Vec3Offset(double dx, double dy, double dz, bool absolute = false)
{
if (absolute)
{
return { X() + dx, Y() + dy, Z() + dz };
}
else
{
DVector2 v = P_GetOffsetPosition(X(), Y(), dx, dy);
return DVector3(v, Z() + dz);
}
}
DVector3 Vec3Offset(const DVector3 &ofs, bool absolute = false)
{
return Vec3Offset(ofs.X, ofs.Y, ofs.Z, absolute);
}
DVector3 Vec3Angle(double length, DAngle angle, double dz, bool absolute = false)
{
if (absolute)
{
return{ X() + length * angle.Cos(), Y() + length * angle.Sin(), Z() + dz };
}
else
{
DVector2 v = P_GetOffsetPosition(X(), Y(), length*angle.Cos(), length*angle.Sin());
return DVector3(v, Z() + dz);
}
}
double AccuracyFactor()
{
return 1. / (1 << (accuracy * 5 / 100));
}
void ClearInterpolation();
void Move(fixed_t dx, fixed_t dy, fixed_t dz)
void Move(const DVector3 &vel)
{
SetOrigin(X() + dx, Y() + dy, Z() + dz, true);
SetOrigin(Pos() + vel, true);
}
void SetOrigin(const fixedvec3 & npos, bool moving)
virtual void SetOrigin(double x, double y, double z, bool moving);
void SetOrigin(const DVector3 & npos, bool moving)
{
SetOrigin(npos.x, npos.y, npos.z, moving);
SetOrigin(npos.X, npos.Y, npos.Z, moving);
}
inline void SetFriendPlayer(player_t *player);
@ -960,7 +946,7 @@ public:
bool CanSeek(AActor *target) const;
fixed_t GetGravity() const;
double GetGravity() const;
bool IsSentient() const;
const char *GetTag(const char *def = NULL) const;
void SetTag(const char *def);
@ -971,36 +957,39 @@ public:
// info for drawing
// NOTE: The first member variable *must* be snext.
AActor *snext, **sprev; // links in sector (if needed)
fixedvec3 __pos; // double underscores so that it won't get used by accident. Access to this should be exclusively through the designated access functions.
DVector3 __Pos; // double underscores so that it won't get used by accident. Access to this should be exclusively through the designated access functions.
DRotator Angles;
DVector3 Vel;
double Speed;
double FloatSpeed;
angle_t angle;
WORD sprite; // used to find patch_t and flip value
BYTE frame; // sprite frame to draw
fixed_t scaleX, scaleY; // Scaling values; FRACUNIT is normal size
DVector2 Scale; // Scaling values; 1 is normal size
FRenderStyle RenderStyle; // Style to draw this actor with
ActorRenderFlags renderflags; // Different rendering flags
FTextureID picnum; // Draw this instead of sprite if valid
DWORD effects; // [RH] see p_effect.h
fixed_t alpha;
double Alpha; // Since P_CheckSight makes an alpha check this can't be a float. It has to be a double.
DWORD fillcolor; // Color to draw when STYLE_Shaded
// interaction info
fixed_t pitch;
angle_t roll; // This was fixed_t before, which is probably wrong
FBlockNode *BlockNode; // links in blocks (if needed)
struct sector_t *Sector;
subsector_t * subsector;
fixed_t floorz, ceilingz; // closest together of contacted secs
fixed_t dropoffz; // killough 11/98: the lowest floor over all contacted Sectors.
double floorz, ceilingz; // closest together of contacted secs
double dropoffz; // killough 11/98: the lowest floor over all contacted Sectors.
struct sector_t *floorsector;
FTextureID floorpic; // contacted sec floorpic
int floorterrain;
struct sector_t *ceilingsector;
FTextureID ceilingpic; // contacted sec ceilingpic
fixed_t radius, height; // for movement checking
fixed_t projectilepassheight; // height for clipping projectile movement against this actor
fixedvec3 vel;
double radius, Height; // for movement checking
double projectilepassheight; // height for clipping projectile movement against this actor
SDWORD tics; // state tic counter
FState *state;
VMFunction *Damage; // For missiles and monster railgun
@ -1018,6 +1007,9 @@ public:
int special1; // Special info
int special2; // Special info
double specialf1; // With floats we cannot use the int versions for storing position or angle data without reverting to fixed point (which we do not want.)
double specialf2;
int weaponspecial; // Special info for weapons.
int health;
BYTE movedir; // 0-7
@ -1035,7 +1027,7 @@ public:
// no matter what (even if shot)
player_t *player; // only valid if type of APlayerPawn
TObjPtr<AActor> LastLookActor; // Actor last looked for (if TIDtoHate != 0)
fixed_t SpawnPoint[3]; // For nightmare respawn
DVector3 SpawnPoint; // For nightmare respawn
WORD SpawnAngle;
int StartHealth;
BYTE WeaveIndexXY; // Separated from special2 because it's used by globally accessible functions.
@ -1045,7 +1037,8 @@ public:
FNameNoInit Species; // For monster families
TObjPtr<AActor> tracer; // Thing being chased/attacked for tracers
TObjPtr<AActor> master; // Thing which spawned this one (prevents mutual attacks)
fixed_t floorclip; // value to use for floor clipping
double Floorclip; // value to use for floor clipping
int tid; // thing identifier
int special; // special
int args[5]; // special arguments
@ -1060,18 +1053,18 @@ public:
SBYTE LastLookPlayerNumber;// Player number last looked for (if TIDtoHate == 0)
ActorBounceFlags BounceFlags; // which bouncing type?
DWORD SpawnFlags; // Increased to DWORD because of Doom 64
fixed_t meleerange; // specifies how far a melee attack reaches.
fixed_t meleethreshold; // Distance below which a monster doesn't try to shoot missiles anynore
double meleerange; // specifies how far a melee attack reaches.
double meleethreshold; // Distance below which a monster doesn't try to shoot missiles anynore
// but instead tries to come closer for a melee attack.
// This is not the same as meleerange
fixed_t maxtargetrange; // any target farther away cannot be attacked
fixed_t bouncefactor; // Strife's grenades use 50%, Hexen's Flechettes 70.
fixed_t wallbouncefactor; // The bounce factor for walls can be different.
double maxtargetrange; // any target farther away cannot be attacked
double bouncefactor; // Strife's grenades use 50%, Hexen's Flechettes 70.
double wallbouncefactor; // The bounce factor for walls can be different.
int bouncecount; // Strife's grenades only bounce twice before exploding
fixed_t gravity; // [GRB] Gravity factor
fixed_t Friction;
double Gravity; // [GRB] Gravity factor
double Friction;
int FastChaseStrafeCount;
fixed_t pushfactor;
double pushfactor;
int lastpush;
int activationtype; // How the thing behaves when activated with USESPECIAL or BUMPSPECIAL
int lastbump; // Last time the actor was bumped, used to control BUMPSPECIAL
@ -1115,16 +1108,16 @@ public:
FSoundIDNoInit WallBounceSound;
FSoundIDNoInit CrushPainSound;
fixed_t Speed;
fixed_t FloatSpeed;
fixed_t MaxDropOffHeight, MaxStepHeight;
double MaxDropOffHeight;
double MaxStepHeight;
SDWORD Mass;
SWORD PainChance;
int PainThreshold;
FNameNoInit DamageType;
FNameNoInit DamageTypeReceived;
fixed_t DamageFactor;
fixed_t DamageMultiply;
double DamageFactor;
double DamageMultiply;
FNameNoInit PainType;
FNameNoInit DeathType;
@ -1147,8 +1140,8 @@ public:
FDecalBase *DecalGenerator;
// [RH] Used to interpolate the view to get >35 FPS
fixed_t PrevX, PrevY, PrevZ;
angle_t PrevAngle;
DVector3 Prev;
DRotator PrevAngles;
int PrevPortalGroup;
// ThingIDs
@ -1156,6 +1149,7 @@ public:
void AddToHash ();
void RemoveFromHash ();
private:
static AActor *TIDHash[128];
static inline int TIDHASH (int key) { return key & 127; }
@ -1170,11 +1164,10 @@ public:
void LinkToWorld (bool spawningmapthing=false, sector_t *sector = NULL);
void UnlinkFromWorld ();
void AdjustFloorClip ();
void SetOrigin (fixed_t x, fixed_t y, fixed_t z, bool moving = false);
bool InStateSequence(FState * newstate, FState * basestate);
int GetTics(FState * newstate);
bool SetState (FState *newstate, bool nofunction=false);
virtual bool UpdateWaterLevel (fixed_t oldz, bool splash=true);
virtual bool UpdateWaterLevel (bool splash=true);
bool isFast();
bool isSlow();
void SetIdle(bool nofunction=false);
@ -1200,90 +1193,168 @@ public:
bool HasSpecialDeathStates () const;
fixed_t X() const
double X() const
{
return __pos.x;
return __Pos.X;
}
fixed_t Y() const
double Y() const
{
return __pos.y;
return __Pos.Y;
}
fixed_t Z() const
double Z() const
{
return __pos.z;
return __Pos.Z;
}
fixedvec3 Pos() const
DVector3 Pos() const
{
return __pos;
return __Pos;
}
// Note: Never compare z directly with a plane height if you want to know if the actor is *on* the plane. Some very minor inaccuracies may creep in. Always use these inline functions!
// Comparing with floorz is ok because those values come from the same calculations.
bool isAbove(double checkz) const
{
return Z() > checkz + EQUAL_EPSILON;
}
bool isBelow(double checkz) const
{
return Z() < checkz - EQUAL_EPSILON;
}
bool isAtZ(double checkz) const
{
return fabs(Z() - checkz) < EQUAL_EPSILON;
}
fixedvec3 PosRelative(int grp) const;
fixedvec3 PosRelative(const AActor *other) const;
fixedvec3 PosRelative(sector_t *sec) const;
fixedvec3 PosRelative(line_t *line) const;
DVector3 PosRelative(int grp) const;
DVector3 PosRelative(const AActor *other) const;
DVector3 PosRelative(sector_t *sec) const;
DVector3 PosRelative(line_t *line) const;
fixed_t SoundX() const
FVector3 SoundPos() const
{
return X();
// the sound system switches y and z axes so this function must, too.
// fixme: This still needs portal handling
return{ float(X()), float(Z()), float(Y()) };
}
fixed_t SoundY() const
DVector3 InterpolatedPosition(double ticFrac) const
{
return Y();
return Prev + (ticFrac * (Pos() - Prev));
}
fixed_t SoundZ() const
DVector3 PosPlusZ(double zadd) const
{
return Z();
return { X(), Y(), Z() + zadd };
}
fixedvec3 InterpolatedPosition(fixed_t ticFrac) const
DVector3 PosAtZ(double zadd) const
{
fixedvec3 ret;
ret.x = PrevX + FixedMul (ticFrac, X() - PrevX);
ret.y = PrevY + FixedMul (ticFrac, Y() - PrevY);
ret.z = PrevZ + FixedMul (ticFrac, Z() - PrevZ);
return ret;
return{ X(), Y(), zadd };
}
fixedvec3 PosPlusZ(fixed_t zadd) const
double Top() const
{
fixedvec3 ret = { X(), Y(), Z() + zadd };
return ret;
return Z() + Height;
}
fixed_t Top() const
double Center() const
{
return Z() + height;
return Z() + Height/2;
}
void SetZ(fixed_t newz, bool moving = true)
void SetZ(double newz, bool moving = true)
{
__pos.z = newz;
__Pos.Z = newz;
}
void AddZ(fixed_t newz, bool moving = true)
void AddZ(double newz, bool moving = true)
{
__pos.z += newz;
__Pos.Z += newz;
if (!moving) Prev.Z = Z();
}
// These are not for general use as they do not link the actor into the world!
void SetXY(fixed_t xx, fixed_t yy)
void SetXY(const DVector2 &npos)
{
__pos.x = xx;
__pos.y = yy;
__Pos.X = npos.X;
__Pos.Y = npos.Y;
}
void SetXYZ(fixed_t xx, fixed_t yy, fixed_t zz)
void SetXYZ(double xx, double yy, double zz)
{
__pos.x = xx;
__pos.y = yy;
__pos.z = zz;
__Pos = { xx,yy,zz };
}
void SetXY(const fixedvec2 &npos)
void SetXYZ(const DVector3 &npos)
{
__pos.x = npos.x;
__pos.y = npos.y;
__Pos = npos;
}
void SetXYZ(const fixedvec3 &npos)
double VelXYToSpeed() const
{
__pos.x = npos.x;
__pos.y = npos.y;
__pos.z = npos.z;
return DVector2(Vel.X, Vel.Y).Length();
}
double VelToSpeed() const
{
return Vel.Length();
}
void AngleFromVel()
{
Angles.Yaw = VecToAngle(Vel.X, Vel.Y);
}
void VelFromAngle()
{
Vel.X = Speed * Angles.Yaw.Cos();
Vel.Y = Speed * Angles.Yaw.Sin();
}
void VelFromAngle(double speed)
{
Vel.X = speed * Angles.Yaw.Cos();
Vel.Y = speed * Angles.Yaw.Sin();
}
void VelFromAngle(DAngle angle, double speed)
{
Vel.X = speed * angle.Cos();
Vel.Y = speed * angle.Sin();
}
void Thrust()
{
Vel.X += Speed * Angles.Yaw.Cos();
Vel.Y += Speed * Angles.Yaw.Sin();
}
void Thrust(double speed)
{
Vel.X += speed * Angles.Yaw.Cos();
Vel.Y += speed * Angles.Yaw.Sin();
}
void Thrust(DAngle angle, double speed)
{
Vel.X += speed * angle.Cos();
Vel.Y += speed * angle.Sin();
}
void Vel3DFromAngle(DAngle angle, DAngle pitch, double speed)
{
double cospitch = pitch.Cos();
Vel.X = speed * cospitch * angle.Cos();
Vel.Y = speed * cospitch * angle.Sin();
Vel.Z = speed * -pitch.Sin();
}
void Vel3DFromAngle(DAngle pitch, double speed)
{
double cospitch = pitch.Cos();
Vel.X = speed * cospitch * Angles.Yaw.Cos();
Vel.Y = speed * cospitch * Angles.Yaw.Sin();
Vel.Z = speed * -pitch.Sin();
}
// This is used by many vertical velocity calculations.
// Better have it in one place, if something needs to be changed about the formula.
double DistanceBySpeed(AActor *dest, double speed)
{
return MAX(1., Distance2D(dest) / speed);
}
int ApplyDamageFactor(FName damagetype, int damage) const;
};
class FActorIterator
@ -1352,56 +1423,46 @@ public:
bool P_IsTIDUsed(int tid);
int P_FindUniqueTID(int start_tid, int limit);
inline AActor *Spawn (PClassActor *type, fixed_t x, fixed_t y, fixed_t z, replace_t allowreplacement)
PClassActor *ClassForSpawn(FName classname);
inline AActor *Spawn(PClassActor *type)
{
return AActor::StaticSpawn (type, x, y, z, allowreplacement);
}
inline AActor *Spawn (PClassActor *type, const fixedvec3 &pos, replace_t allowreplacement)
{
return AActor::StaticSpawn (type, pos.x, pos.y, pos.z, allowreplacement);
return AActor::StaticSpawn(type, DVector3(0, 0, 0), NO_REPLACE);
}
AActor *Spawn (const char *type, fixed_t x, fixed_t y, fixed_t z, replace_t allowreplacement);
AActor *Spawn (FName classname, fixed_t x, fixed_t y, fixed_t z, replace_t allowreplacement);
inline AActor *Spawn (const char *type, const fixedvec3 &pos, replace_t allowreplacement)
inline AActor *Spawn(PClassActor *type, const DVector3 &pos, replace_t allowreplacement)
{
return Spawn (type, pos.x, pos.y, pos.z, allowreplacement);
return AActor::StaticSpawn(type, pos, allowreplacement);
}
inline AActor *Spawn (FName classname, const fixedvec3 &pos, replace_t allowreplacement)
inline AActor *Spawn(FName type)
{
return Spawn (classname, pos.x, pos.y, pos.z, allowreplacement);
return AActor::StaticSpawn(ClassForSpawn(type), DVector3(0, 0, 0), NO_REPLACE);
}
template<class T>
inline T *Spawn (fixed_t x, fixed_t y, fixed_t z, replace_t allowreplacement)
inline AActor *Spawn(FName type, const DVector3 &pos, replace_t allowreplacement)
{
return static_cast<T *>(AActor::StaticSpawn (RUNTIME_TEMPLATE_CLASS(T), x, y, z, allowreplacement));
return AActor::StaticSpawn(ClassForSpawn(type), pos, allowreplacement);
}
template<class T>
inline T *Spawn (const fixedvec3 &pos, replace_t allowreplacement)
template<class T> inline T *Spawn(const DVector3 &pos, replace_t allowreplacement)
{
return static_cast<T *>(AActor::StaticSpawn (RUNTIME_TEMPLATE_CLASS(T), pos.x, pos.y, pos.z, allowreplacement));
return static_cast<T *>(AActor::StaticSpawn(RUNTIME_TEMPLATE_CLASS(T), pos, allowreplacement));
}
inline fixedvec2 Vec2Angle(fixed_t length, angle_t angle)
template<class T> inline T *Spawn() // for inventory items we do not need coordinates and replacement info.
{
fixedvec2 ret = { FixedMul(length, finecosine[angle >> ANGLETOFINESHIFT]),
FixedMul(length, finesine[angle >> ANGLETOFINESHIFT]) };
return ret;
return static_cast<T *>(AActor::StaticSpawn(RUNTIME_TEMPLATE_CLASS(T), DVector3(0, 0, 0), NO_REPLACE));
}
void PrintMiscActorInfo(AActor * query);
AActor *P_LinePickActor(AActor *t1, angle_t angle, fixed_t distance, int pitch, ActorFlags actorMask, DWORD wallMask);
AActor *P_LinePickActor(AActor *t1, DAngle angle, double distance, DAngle pitch, ActorFlags actorMask, DWORD wallMask);
// If we want to make P_AimLineAttack capable of handling arbitrary portals, it needs to pass a lot more info than just the linetarget actor.
struct FTranslatedLineTarget
{
AActor *linetarget;
angle_t angleFromSource;
DAngle angleFromSource;
bool unlinked; // found by a trace that went through an unlinked portal.
};

File diff suppressed because it is too large Load diff

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 ()
@ -269,7 +256,7 @@ void InitBotStuff()
AWeapon *w = (AWeapon*)GetDefaultByType(cls);
if (w != NULL)
{
w->MoveCombatDist = botinits[i].movecombatdist;
w->MoveCombatDist = botinits[i].movecombatdist/65536.;
w->WeaponFlags |= botinits[i].weaponflags;
w->ProjectileType = PClass::FindActor(botinits[i].projectile);
}

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
@ -103,12 +103,13 @@ public:
void StartTravel ();
void FinishTravel ();
bool IsLeader (player_t *player);
void SetBodyAt (fixed_t x, fixed_t y, fixed_t z, int hostnum);
fixed_t FakeFire (AActor *source, AActor *dest, ticcmd_t *cmd);
bool SafeCheckPosition (AActor *actor, fixed_t x, fixed_t y, FCheckPosition &tm);
void SetBodyAt (const DVector3 &pos, int hostnum);
double FakeFire (AActor *source, AActor *dest, ticcmd_t *cmd);
bool SafeCheckPosition (AActor *actor, double x, double y, FCheckPosition &tm);
void BotTick(AActor *mo);
//(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 +150,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 +184,7 @@ public:
bool allround;
bool increase;
fixed_t oldx;
fixed_t oldy;
DVector2 old;
private:
//(b_think.cpp)
@ -197,7 +197,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

@ -36,30 +36,30 @@ bool DBot::Reachable (AActor *rtarget)
if ((rtarget->Sector->ceilingplane.ZatPoint (rtarget) -
rtarget->Sector->floorplane.ZatPoint (rtarget))
< player->mo->height) //Where rtarget is, player->mo can't be.
< 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.ZatPoint (player->mo);
double estimated_dist = player->mo->Distance2D(rtarget);
bool reachable = true;
FPathTraverse it(player->mo->X()+player->mo->vel.x, player->mo->Y()+player->mo->vel.y, rtarget->X(), rtarget->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->vel.x, frac);
hity = it.Trace().y + FixedMul (player->mo->vel.y, 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->height))) //Does it fit?
|| (ceilingheight - floorheight) >= player->mo->Height))) //Does it fit?
{
last_z = floorheight;
last_s = s;
@ -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->angle) <= vangle/2;
return absangle(player->mo->AngleTo(to), player->mo->Angles.Yaw) <= (vangle/2);
}
//-------------------------------------
@ -140,9 +140,10 @@ 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;
angle_t an;
int m;
double Dist;
DAngle an;
DAngle m;
double fm;
if (!enemy || !(enemy->flags & MF_SHOOTABLE) || enemy->health <= 0)
return;
@ -170,7 +171,7 @@ void DBot::Dofire (ticcmd_t *cmd)
no_fire = true;
//Distance to enemy.
dist = player->mo->AproxDistance(enemy, player->mo->vel.x - enemy->vel.x, player->mo->vel.y - enemy->vel.y);
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)
@ -192,7 +193,7 @@ void DBot::Dofire (ticcmd_t *cmd)
else
{
//*4 is for atmosphere, the chainsaws sounding and all..
no_fire = (dist > (MELEERANGE*4));
no_fire = (Dist > MELEERANGE*4);
}
}
else if (player->ReadyWeapon->WeaponFlags & WIF_BOT_BFG)
@ -208,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->angle) < 12*ANGLE_1)
if (absangle(an, player->mo->Angles.Yaw) < 12.)
{
t_rocket = 9;
no_fire = false;
@ -221,17 +222,17 @@ void DBot::Dofire (ticcmd_t *cmd)
}
// prediction aiming
shootmissile:
dist = player->mo->AproxDistance (enemy);
m = dist / GetDefaultByType (player->ReadyWeapon->ProjectileType)->Speed;
bglobal.SetBodyAt (enemy->X() + enemy->vel.x*m*2, enemy->Y() + enemy->vel.y*m*2, enemy->Z(), 1);
angle = player->mo->AngleTo(bglobal.body1);
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->AngleTo(bglobal.body1);
if (Check_LOS (enemy, SHOOTFOV))
no_fire = false;
}
else
{
//Other weapons, mostly instant hit stuff.
angle = player->mo->AngleTo(enemy);
Angle = player->mo->AngleTo(enemy);
aiming_penalty = 0;
if (enemy->flags & MF_SHADOW)
aiming_penalty += (pr_botdofire()%25)+10;
@ -244,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->angle) < 4*ANGLE_1)
if (absangle(Angle, player->mo->Angles.Yaw) < 4.)
{
increase = !increase;
}
@ -283,13 +284,55 @@ bool FCajunMaster::IsLeader (player_t *player)
return false;
}
extern int BotWTG;
void FCajunMaster::BotTick(AActor *mo)
{
BotSupportCycles.Clock();
bglobal.m_Thinking = true;
for (int i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i] || players[i].Bot == NULL)
continue;
if (mo->flags3 & MF3_ISMONSTER)
{
if (mo->health > 0
&& !players[i].Bot->enemy
&& mo->player ? !mo->IsTeammate(players[i].mo) : true
&& mo->Distance2D(players[i].mo) < MAX_MONSTER_TARGET_DIST
&& P_CheckSight(players[i].mo, mo, SF_SEEPASTBLOCKEVERYTHING))
{ //Probably a monster, so go kill it.
players[i].Bot->enemy = mo;
}
}
else if (mo->flags & MF_SPECIAL)
{ //Item pickup time
//clock (BotWTG);
players[i].Bot->WhatToGet(mo);
//unclock (BotWTG);
BotWTG++;
}
else if (mo->flags & MF_MISSILE)
{
if (!players[i].Bot->missile && (mo->flags3 & MF3_WARNBOT))
{ //warn for incoming missiles.
if (mo->target != players[i].mo && players[i].Bot->Check_LOS(mo, 90.))
players[i].Bot->missile = mo;
}
}
}
bglobal.m_Thinking = false;
BotSupportCycles.Unclock();
}
//This function is called every
//tick (for each bot) to set
//the mate (teammate coop mate).
AActor *DBot::Choose_Mate ()
{
int count;
fixed_t closest_dist, test;
double closest_dist, test;
AActor *target;
AActor *observer;
@ -310,7 +353,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
@ -332,7 +375,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)
{
@ -366,9 +409,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)
@ -378,13 +421,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
@ -402,7 +445,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 &&
@ -425,28 +468,28 @@ AActor *DBot::Find_enemy ()
//Creates a temporary mobj (invisible) at the given location.
void FCajunMaster::SetBodyAt (fixed_t x, fixed_t y, fixed_t z, int hostnum)
void FCajunMaster::SetBodyAt (const DVector3 &pos, int hostnum)
{
if (hostnum == 1)
{
if (body1)
{
body1->SetOrigin (x, y, z, false);
body1->SetOrigin (pos, false);
}
else
{
body1 = Spawn ("CajunBodyNode", x, y, z, NO_REPLACE);
body1 = Spawn ("CajunBodyNode", pos, NO_REPLACE);
}
}
else if (hostnum == 2)
{
if (body2)
{
body2->SetOrigin (x, y, z, false);
body2->SetOrigin (pos, false);
}
else
{
body2 = Spawn ("CajunBodyNode", x, y, z, NO_REPLACE);
body2 = Spawn ("CajunBodyNode", pos, NO_REPLACE);
}
}
}
@ -461,27 +504,21 @@ void FCajunMaster::SetBodyAt (fixed_t x, fixed_t y, fixed_t z, 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*FRACUNIT), NO_REPLACE);
AActor *th = Spawn ("CajunTrace", source->PosPlusZ(4*8.), NO_REPLACE);
th->target = source; // where it came from
float speed = (float)th->Speed;
fixedvec3 fixvel = source->Vec3To(dest);
DVector3 velocity(fixvel.x, fixvel.y, fixvel.z);
velocity.MakeUnit();
th->vel.x = FLOAT2FIXED(velocity[0] * speed);
th->vel.y = FLOAT2FIXED(velocity[1] * speed);
th->vel.z = FLOAT2FIXED(velocity[2] * speed);
th->Vel = source->Vec3To(dest).Resized(th->Speed);
fixed_t dist = 0;
double dist = 0;
while (dist < SAFE_SELF_MISDIST)
{
dist += th->Speed;
th->Move(th->vel.x, th->vel.y, th->vel.z);
th->Move(th->Vel);
if (!CleanAhead (th, th->X(), th->Y(), cmd))
break;
}
@ -489,27 +526,23 @@ fixed_t FCajunMaster::FakeFire (AActor *source, AActor *dest, ticcmd_t *cmd)
return dist;
}
angle_t DBot::FireRox (AActor *enemy, ticcmd_t *cmd)
DAngle DBot::FireRox (AActor *enemy, ticcmd_t *cmd)
{
fixed_t dist;
angle_t ang;
double dist;
AActor *actor;
int m;
double m;
bglobal.SetBodyAt (player->mo->X() + FixedMul(player->mo->vel.x, 5*FRACUNIT),
player->mo->Y() + FixedMul(player->mo->vel.y, 5*FRACUNIT),
player->mo->Z() + (player->mo->height / 2), 2);
bglobal.SetBodyAt(player->mo->PosPlusZ(player->mo->Height / 2) + player->mo->Vel.XY() * 5, 2);
actor = bglobal.body2;
dist = actor->AproxDistance (enemy);
dist = actor->Distance2D (enemy);
if (dist < SAFE_SELF_MISDIST)
return 0;
return 0.;
//Predict.
m = (((dist+1)/FRACUNIT) / GetDefaultByName("Rocket")->Speed);
m = ((dist+1) / GetDefaultByName("Rocket")->Speed);
bglobal.SetBodyAt (enemy->X() + FixedMul(enemy->vel.x, (m+2*FRACUNIT)),
enemy->Y() + FixedMul(enemy->vel.y, (m+2*FRACUNIT)), ONFLOORZ, 1);
bglobal.SetBodyAt(DVector3((enemy->Pos() + enemy->Vel * (m + 2)), ONFLOORZ), 1);
//try the predicted location
if (P_CheckSight (actor, bglobal.body1, SF_IGNOREVISIBILITY)) //See the predicted location, so give a test missile
@ -519,8 +552,7 @@ angle_t DBot::FireRox (AActor *enemy, ticcmd_t *cmd)
{
if (bglobal.FakeFire (actor, bglobal.body1, cmd) >= SAFE_SELF_MISDIST)
{
ang = actor->AngleTo(bglobal.body1);
return ang;
return actor->AngleTo(bglobal.body1);
}
}
}
@ -529,21 +561,20 @@ angle_t DBot::FireRox (AActor *enemy, ticcmd_t *cmd)
{
if (bglobal.FakeFire (player->mo, enemy, cmd) >= SAFE_SELF_MISDIST)
{
ang = player->mo->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

@ -21,6 +21,7 @@
#include "d_player.h"
#include "p_spec.h"
#include "p_checkposition.h"
#include "math/cmath.h"
static FRandom pr_botopendoor ("BotOpenDoor");
static FRandom pr_bottrywalk ("BotTryWalk");
@ -34,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->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.
@ -60,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;
@ -147,18 +148,18 @@ void DBot::NewChaseDir (ticcmd_t *cmd)
olddir = (dirtype_t)player->mo->movedir;
turnaround = opposite[olddir];
fixedvec2 delta = player->mo->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;
@ -166,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;
@ -259,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;
@ -268,30 +269,30 @@ bool FCajunMaster::CleanAhead (AActor *thing, fixed_t x, fixed_t y, ticcmd_t *cm
if (!(thing->flags & MF_NOCLIP) )
{
fixed_t maxstep = thing->MaxStepHeight;
if (tm.ceilingz - tm.floorz < thing->height)
if (tm.ceilingz - tm.floorz < thing->Height)
return false; // doesn't fit
double maxmove = MAXMOVEHEIGHT;
if (!(thing->flags&MF_MISSILE))
{
if(tm.floorz > (thing->Sector->floorplane.ZatPoint (x, y)+MAXMOVEHEIGHT)) //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.ZatPoint (x, y)+thing->MaxStepHeight))
if(tm.floorz > (thing->Sector->floorplane.ZatPoint(x, y)+thing->MaxStepHeight))
cmd->ucmd.buttons |= BT_JUMP;
if ( !(thing->flags & MF_TELEPORT) &&
tm.ceilingz - thing->Z() < thing->height)
tm.ceilingz < thing->Top())
return false; // mobj must lower itself to fit
// 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() > maxstep ) )
(tm.floorz - thing->Z() > thing->MaxStepHeight) )
return false; // too big a step up
@ -304,13 +305,13 @@ bool FCajunMaster::CleanAhead (AActor *thing, fixed_t x, fixed_t y, ticcmd_t *cm
return true;
}
#define OKAYRANGE (5*ANGLE_1) //counts *2, when angle is in range, turning is not executed.
#define MAXTURN (15*ANGLE_1) //Max degrees turned in one tic. Lower is smother but may cause the bot not getting where it should = crash
#define OKAYRANGE (5) //counts *2, when angle is in range, turning is not executed.
#define MAXTURN (15) //Max degrees turned in one tic. Lower is smother but may cause the bot not getting where it should = crash
#define TURNSENS 3 //Higher is smoother but slower turn.
void DBot::TurnToAng ()
{
int maxturn = MAXTURN;
double maxturn = MAXTURN;
if (player->ReadyWeapon != NULL)
{
@ -326,20 +327,20 @@ 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;
}
int distance = angle - player->mo->angle;
DAngle distance = deltaangle(player->mo->Angles.Yaw, Angle);
if (abs (distance) < OKAYRANGE && !enemy)
if (fabs (distance) < OKAYRANGE && !enemy)
return;
distance /= TURNSENS;
if (abs (distance) > maxturn)
if (fabs (distance) > maxturn)
distance = distance < 0 ? -maxturn : maxturn;
player->mo->angle += distance;
player->mo->Angles.Yaw += distance;
}
void DBot::Pitch (AActor *target)
@ -348,8 +349,8 @@ void DBot::Pitch (AActor *target)
double diff;
diff = target->Z() - player->mo->Z();
aim = atan(diff / (double)player->mo->AproxDistance(target));
player->mo->pitch = -(int)(aim * ANGLE_180/M_PI);
aim = g_atan(diff / player->mo->Distance2D(target));
player->mo->Angles.Pitch = DAngle::ToDegrees(aim);
}
//Checks if a sector is dangerous.

View file

@ -20,6 +20,7 @@
#include "d_net.h"
#include "d_event.h"
#include "d_player.h"
#include "vectors.h"
static FRandom pr_botmove ("BotMove");
@ -39,20 +40,21 @@ void DBot::Think ()
if (teamplay || !deathmatch)
mate = Choose_Mate ();
angle_t oldyaw = player->mo->angle;
int oldpitch = player->mo->pitch;
AActor *actor = player->mo;
DAngle oldyaw = actor->Angles.Yaw;
DAngle oldpitch = actor->Angles.Pitch;
Set_enemy ();
ThinkForMove (cmd);
TurnToAng ();
cmd->ucmd.yaw = (short)((player->mo->angle - oldyaw) >> 16) / ticdup;
cmd->ucmd.pitch = (short)((oldpitch - player->mo->pitch) >> 16);
cmd->ucmd.yaw = (short)((actor->Angles.Yaw - oldyaw).Degrees * (65536 / 360.f)) / ticdup;
cmd->ucmd.pitch = (short)((oldpitch - actor->Angles.Pitch).Degrees * (65536 / 360.f));
if (cmd->ucmd.pitch == -32768)
cmd->ucmd.pitch = -32767;
cmd->ucmd.pitch /= ticdup;
player->mo->angle = oldyaw + (cmd->ucmd.yaw << 16) * ticdup;
player->mo->pitch = oldpitch - (cmd->ucmd.pitch << 16) * ticdup;
actor->Angles.Yaw = oldyaw + DAngle(cmd->ucmd.yaw * ticdup * (360 / 65536.f));
actor->Angles.Pitch = oldpitch - DAngle(cmd->ucmd.pitch * ticdup * (360 / 65536.f));
}
if (t_active) t_active--;
@ -73,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->vel.x || !missile->vel.y) || !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 (player->mo->pitch > 0)
player->mo->pitch -= 80;
else if (player->mo->pitch <= -60)
player->mo->pitch += 80;
#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->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;
@ -157,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))
)
{
@ -166,10 +171,10 @@ void DBot::ThinkForMove (ticcmd_t *cmd)
sleft = !sleft;
}
angle = player->mo->AngleTo(enemy);
Angle = player->mo->AngleTo(enemy);
if (player->ReadyWeapon == NULL ||
player->mo->AproxDistance(enemy) >
player->mo->Distance2D(enemy) >
player->ReadyWeapon->MoveCombatDist)
{
// If a monster, use lower speed (just for cooler apperance while strafing down doomed monster)
@ -194,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);
@ -207,9 +212,9 @@ void DBot::ThinkForMove (ticcmd_t *cmd)
goto roam;
}
angle = player->mo->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)
@ -242,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->AngleTo(enemy);
Angle = player->mo->AngleTo(enemy);
} //Just a monster, so kill it.
else
dest = enemy;
@ -304,8 +309,7 @@ void DBot::ThinkForMove (ticcmd_t *cmd)
if (t_fight<(AFTERTICS/2))
player->mo->flags |= MF_DROPOFF;
oldx = player->mo->X();
oldy = player->mo->Y();
old = player->mo->Pos();
}
//BOT_WhatToGet

View file

@ -1,16 +1,6 @@
#ifndef __BASICTYPES_H
#define __BASICTYPES_H
#ifdef _MSC_VER
typedef __int8 SBYTE;
typedef unsigned __int8 BYTE;
typedef __int16 SWORD;
typedef unsigned __int16 WORD;
typedef __int32 SDWORD;
typedef unsigned __int32 uint32;
typedef __int64 SQWORD;
typedef unsigned __int64 QWORD;
#else
#include <stdint.h>
typedef int8_t SBYTE;
@ -21,11 +11,6 @@ typedef int32_t SDWORD;
typedef uint32_t uint32;
typedef int64_t SQWORD;
typedef uint64_t QWORD;
#endif
typedef SDWORD int32;
typedef float real32;
typedef double real64;
// windef.h, included by windows.h, has its own incompatible definition
// of DWORD as a long. In files that mix Doom and Windows code, you
@ -73,7 +58,7 @@ union QWORD_UNION
};
//
// Fixed point, 32bit as 16.16.
// fixed point, 32bit as 16.16.
//
#define FRACBITS 16
#define FRACUNIT (1<<FRACBITS)
@ -81,89 +66,6 @@ union QWORD_UNION
typedef SDWORD fixed_t;
typedef DWORD dsfixed_t; // fixedpt used by span drawer
struct fixedvec2
{
fixed_t x, y;
fixedvec2 &operator +=(const fixedvec2 &other)
{
x += other.x;
y += other.y;
return *this;
}
};
struct fixedvec3
{
fixed_t x, y, z;
fixedvec3 &operator +=(const fixedvec3 &other)
{
x += other.x;
y += other.y;
z += other.z;
return *this;
}
fixedvec3 &operator +=(const fixedvec2 &other)
{
x += other.x;
y += other.y;
return *this;
}
fixedvec3 &operator -=(const fixedvec2 &other)
{
x -= other.x;
y -= other.y;
return *this;
}
fixedvec3 &operator -=(const fixedvec3 &other)
{
x -= other.x;
y -= other.y;
z -= other.z;
return *this;
}
operator fixedvec2()
{
return { x, y };
}
};
inline fixedvec2 operator +(const fixedvec2 &v1, const fixedvec2 &v2)
{
return { v1.x + v2.x, v1.y + v2.y };
}
inline fixedvec2 operator -(const fixedvec2 &v1, const fixedvec2 &v2)
{
return { v1.x - v2.x, v1.y - v2.y };
}
inline fixedvec3 operator +(const fixedvec3 &v1, const fixedvec3 &v2)
{
return { v1.x + v2.x, v1.y + v2.y, v1.z + v2.z };
}
inline fixedvec3 operator +(const fixedvec3 &v1, const fixedvec2 &v2)
{
return { v1.x + v2.x, v1.y + v2.y, v1.z };
}
inline fixedvec3 operator -(const fixedvec3 &v1, const fixedvec2 &v2)
{
return{ v1.x - v2.x, v1.y - v2.y, v1.z };
}
inline fixedvec3 operator -(const fixedvec3 &v1, const fixedvec3 &v2)
{
return{ v1.x - v2.x, v1.y - v2.y, v1.z - v2.z };
}
#define FIXED_MAX (signed)(0x7fffffff)
#define FIXED_MIN (signed)(0x80000000)

View file

@ -875,7 +875,7 @@ CCMD(linetarget)
FTranslatedLineTarget t;
if (CheckCheatmode () || players[consoleplayer].mo == NULL) return;
P_AimLineAttack(players[consoleplayer].mo,players[consoleplayer].mo->angle,MISSILERANGE, &t, 0);
P_AimLineAttack(players[consoleplayer].mo,players[consoleplayer].mo->Angles.Yaw, MISSILERANGE, &t, 0.);
if (t.linetarget)
{
Printf("Target=%s, Health=%d, Spawnhealth=%d\n",
@ -892,8 +892,8 @@ CCMD(info)
FTranslatedLineTarget t;
if (CheckCheatmode () || players[consoleplayer].mo == NULL) return;
P_AimLineAttack(players[consoleplayer].mo,players[consoleplayer].mo->angle,MISSILERANGE,
&t, 0, ALF_CHECKNONSHOOTABLE|ALF_FORCENOSMART);
P_AimLineAttack(players[consoleplayer].mo,players[consoleplayer].mo->Angles.Yaw, MISSILERANGE,
&t, 0., ALF_CHECKNONSHOOTABLE|ALF_FORCENOSMART);
if (t.linetarget)
{
Printf("Target=%s, Health=%d, Spawnhealth=%d\n",
@ -943,9 +943,8 @@ static void PrintFilteredActorList(const ActorTypeChecker IsActorType, const cha
{
if ((FilterClass == NULL || mo->IsA(FilterClass)) && IsActorType(mo))
{
Printf ("%s at (%d,%d,%d)\n",
mo->GetClass()->TypeName.GetChars(),
mo->X() >> FRACBITS, mo->Y() >> FRACBITS, mo->Z() >> FRACBITS);
Printf ("%s at (%f,%f,%f)\n",
mo->GetClass()->TypeName.GetChars(), mo->X(), mo->Y(), mo->Z());
}
}
}
@ -1087,7 +1086,7 @@ CCMD(currentpos)
if(mo)
{
Printf("Current player position: (%1.3f,%1.3f,%1.3f), angle: %1.3f, floorheight: %1.3f, sector:%d, lightlevel: %d\n",
FIXED2DBL(mo->X()), FIXED2DBL(mo->Y()), FIXED2DBL(mo->Z()), ANGLE2DBL(mo->angle), FIXED2DBL(mo->floorz), mo->Sector->sectornum, mo->Sector->lightlevel);
mo->X(), mo->Y(), mo->Z(), mo->Angles.Yaw.Normalized360().Degrees, mo->floorz, mo->Sector->sectornum, mo->Sector->lightlevel);
}
else
{
@ -1245,9 +1244,9 @@ CCMD(angleconvtest)
Printf("Testing degrees to angle conversion:\n");
for (double ang = -5 * 180.; ang < 5 * 180.; ang += 45.)
{
angle_t ang1 = FLOAT2ANGLE(ang);
angle_t ang2 = (angle_t)(ang * (ANGLE_90 / 90.));
angle_t ang3 = (angle_t)(int)(ang * (ANGLE_90 / 90.));
unsigned ang1 = DAngle(ang).BAMs();
unsigned ang2 = (unsigned)(ang * (0x40000000 / 90.));
unsigned ang3 = (unsigned)(int)(ang * (0x40000000 / 90.));
Printf("Angle = %.5f: xs_RoundToInt = %08x, unsigned cast = %08x, signed cast = %08x\n",
ang, ang1, ang2, ang3);
}

View file

@ -732,15 +732,15 @@ static void C_DrawNotifyText ()
if (!show_messages && NotifyStrings[i].PrintLevel != 128)
continue;
fixed_t alpha;
double alpha;
if (j < NOTIFYFADETIME)
{
alpha = OPAQUE * j / NOTIFYFADETIME;
alpha = 1. * j / NOTIFYFADETIME;
}
else
{
alpha = OPAQUE;
alpha = 1;
}
if (NotifyStrings[i].PrintLevel >= PRINTLEVELS)
@ -752,23 +752,23 @@ static void C_DrawNotifyText ()
{
if (!center)
screen->DrawText (SmallFont, color, 0, line, NotifyStrings[i].Text,
DTA_CleanNoMove, true, DTA_Alpha, alpha, TAG_DONE);
DTA_CleanNoMove, true, DTA_AlphaF, alpha, TAG_DONE);
else
screen->DrawText (SmallFont, color, (SCREENWIDTH -
SmallFont->StringWidth (NotifyStrings[i].Text)*CleanXfac)/2,
line, NotifyStrings[i].Text, DTA_CleanNoMove, true,
DTA_Alpha, alpha, TAG_DONE);
DTA_AlphaF, alpha, TAG_DONE);
}
else if (con_scaletext == 0)
{
if (!center)
screen->DrawText (SmallFont, color, 0, line, NotifyStrings[i].Text,
DTA_Alpha, alpha, TAG_DONE);
DTA_AlphaF, alpha, TAG_DONE);
else
screen->DrawText (SmallFont, color, (SCREENWIDTH -
SmallFont->StringWidth (NotifyStrings[i].Text))/2,
line, NotifyStrings[i].Text,
DTA_Alpha, alpha, TAG_DONE);
DTA_AlphaF, alpha, TAG_DONE);
}
else
{
@ -777,7 +777,7 @@ static void C_DrawNotifyText ()
DTA_VirtualWidth, screen->GetWidth() / 2,
DTA_VirtualHeight, screen->GetHeight() / 2,
DTA_KeepRatio, true,
DTA_Alpha, alpha, TAG_DONE);
DTA_AlphaF, alpha, TAG_DONE);
else
screen->DrawText (SmallFont, color, (screen->GetWidth() / 2 -
SmallFont->StringWidth (NotifyStrings[i].Text))/2,
@ -785,7 +785,7 @@ static void C_DrawNotifyText ()
DTA_VirtualWidth, screen->GetWidth() / 2,
DTA_VirtualHeight, screen->GetHeight() / 2,
DTA_KeepRatio, true,
DTA_Alpha, alpha, TAG_DONE);
DTA_AlphaF, alpha, TAG_DONE);
}
line += lineadv;
canskip = false;
@ -865,7 +865,7 @@ void C_DrawConsole (bool hw2d)
DTA_DestWidth, screen->GetWidth(),
DTA_DestHeight, screen->GetHeight(),
DTA_ColorOverlay, conshade,
DTA_Alpha, (hw2d && gamestate != GS_FULLCONSOLE) ? FLOAT2FIXED(con_alpha) : FRACUNIT,
DTA_AlphaF, (hw2d && gamestate != GS_FULLCONSOLE) ? (double)con_alpha : 1.,
DTA_Masked, false,
TAG_DONE);
if (conline && visheight < screen->GetHeight())

View file

@ -290,7 +290,7 @@ void ParseCompatibility()
sc.MustGetNumber();
CompatParams.Push(sc.Number);
sc.MustGetFloat();
CompatParams.Push(FLOAT2FIXED(sc.Float));
CompatParams.Push(int(sc.Float*65536.));
}
else if (sc.Compare("setwallyscale"))
{
@ -303,7 +303,7 @@ void ParseCompatibility()
sc.MustGetString();
CompatParams.Push(sc.MustMatchString(WallTiers));
sc.MustGetFloat();
CompatParams.Push(FLOAT2FIXED(sc.Float));
CompatParams.Push(int(sc.Float*65536.));
}
else if (sc.Compare("setthingz"))
{
@ -312,7 +312,7 @@ void ParseCompatibility()
sc.MustGetNumber();
CompatParams.Push(sc.Number);
sc.MustGetFloat();
CompatParams.Push(FLOAT2FIXED(sc.Float));
CompatParams.Push(int(sc.Float*256)); // do not use full fixed here so that it can eventually handle larger levels
}
else if (sc.Compare("setsectortag"))
{
@ -522,7 +522,7 @@ void SetCompatibilityParams()
{
sector_t *sec = &sectors[CompatParams[i+1]];
sec->floorplane.ChangeHeight(CompatParams[i+2]);
sec->ChangePlaneTexZ(sector_t::floor, CompatParams[i+2]);
sec->ChangePlaneTexZ(sector_t::floor, CompatParams[i+2] / 65536.);
}
i += 3;
break;
@ -534,7 +534,7 @@ void SetCompatibilityParams()
side_t *side = lines[CompatParams[i+1]].sidedef[CompatParams[i+2]];
if (side != NULL)
{
side->SetTextureYScale(CompatParams[i+3], CompatParams[i+4]);
side->SetTextureYScale(CompatParams[i+3], CompatParams[i+4] / 65536.);
}
}
i += 5;
@ -545,7 +545,7 @@ void SetCompatibilityParams()
// When this is called, the things haven't been spawned yet so we can alter the position inside the MapThings array.
if ((unsigned)CompatParams[i+1] < MapThingsConverted.Size())
{
MapThingsConverted[CompatParams[i+1]].z = CompatParams[i+2];
MapThingsConverted[CompatParams[i+1]].pos.Z = CompatParams[i+2]/256.;
}
i += 3;
break;

View file

@ -215,7 +215,7 @@ DehInfo deh =
2, // .KFAAC
"PLAY", // Name of player sprite
255, // Rocket explosion style, 255=use cvar
FRACUNIT*2/3, // Rocket explosion alpha
2./3., // Rocket explosion alpha
false, // .NoAutofreeze
40, // BFG cells per shot
};
@ -353,6 +353,11 @@ static bool ReadChars (char **stuff, int size);
static char *igets (void);
static int GetLine (void);
inline double DEHToDouble(int acsval)
{
return acsval / 65536.;
}
static void PushTouchedActor(PClassActor *cls)
{
for(unsigned i = 0; i < TouchedActors.Size(); i++)
@ -647,7 +652,7 @@ static int CreateMushroomFunc(VMFunctionBuilder &buildit, int value1, int value2
}
else
{
buildit.Emit(OP_PARAM, 0, REGT_FLOAT | REGT_KONST, buildit.GetConstantFloat(FIXED2DBL(value1)));
buildit.Emit(OP_PARAM, 0, REGT_FLOAT | REGT_KONST, buildit.GetConstantFloat(DEHToDouble(value1)));
}
// hrange
if (value2 == 0)
@ -656,7 +661,7 @@ static int CreateMushroomFunc(VMFunctionBuilder &buildit, int value1, int value2
}
else
{
buildit.Emit(OP_PARAM, 0, REGT_FLOAT | REGT_KONST, buildit.GetConstantFloat(FIXED2DBL(value2)));
buildit.Emit(OP_PARAM, 0, REGT_FLOAT | REGT_KONST, buildit.GetConstantFloat(DEHToDouble(value2)));
}
return 5;
}
@ -896,14 +901,14 @@ static int PatchThing (int thingy)
}
else if (linelen == 12 && stricmp (Line1, "Translucency") == 0)
{
info->alpha = val;
info->Alpha = DEHToDouble(val);
info->RenderStyle = STYLE_Translucent;
hadTranslucency = true;
hadStyle = true;
}
else if (linelen == 6 && stricmp (Line1, "Height") == 0)
{
info->height = val;
info->Height = DEHToDouble(val);
info->projectilepassheight = 0; // needs to be disabled
hadHeight = true;
}
@ -915,20 +920,20 @@ static int PatchThing (int thingy)
{
if (stricmp (Line1, "Speed") == 0)
{
info->Speed = val;
info->Speed = val; // handle fixed point later.
}
else if (stricmp (Line1, "Width") == 0)
{
info->radius = val;
info->radius = DEHToDouble(val);
}
else if (stricmp (Line1, "Alpha") == 0)
{
info->alpha = (fixed_t)(atof (Line2) * FRACUNIT);
info->Alpha = atof (Line2);
hadTranslucency = true;
}
else if (stricmp (Line1, "Scale") == 0)
{
info->scaleY = info->scaleX = clamp<fixed_t> (FLOAT2FIXED(atof (Line2)), 1, 256*FRACUNIT);
info->Scale.Y = info->Scale.X = clamp(atof (Line2), 1./65536, 256.);
}
else if (stricmp (Line1, "Decal") == 0)
{
@ -1141,14 +1146,12 @@ static int PatchThing (int thingy)
}
// MBF bounce factors depend on flag combos:
enum
{
MBF_BOUNCE_NOGRAVITY = FRACUNIT, // With NOGRAVITY: full momentum
MBF_BOUNCE_FLOATDROPOFF = (FRACUNIT * 85) / 100,// With FLOAT and DROPOFF: 85%
MBF_BOUNCE_FLOAT = (FRACUNIT * 70) / 100,// With FLOAT alone: 70%
MBF_BOUNCE_DEFAULT = (FRACUNIT * 45) / 100,// Without the above flags: 45%
MBF_BOUNCE_WALL = (FRACUNIT * 50) / 100,// Bouncing off walls: 50%
};
const double MBF_BOUNCE_NOGRAVITY = 1; // With NOGRAVITY: full momentum
const double MBF_BOUNCE_FLOATDROPOFF = 0.85; // With FLOAT and DROPOFF: 85%
const double MBF_BOUNCE_FLOAT = 0.7; // With FLOAT alone: 70%
const double MBF_BOUNCE_DEFAULT = 0.45; // Without the above flags: 45%
const double MBF_BOUNCE_WALL = 0.5; // Bouncing off walls: 50%
info->bouncefactor = ((value[0] & MF_NOGRAVITY) ? MBF_BOUNCE_NOGRAVITY
: (value[0] & MF_FLOAT) ? (value[0] & MF_DROPOFF) ? MBF_BOUNCE_FLOATDROPOFF
: MBF_BOUNCE_FLOAT : MBF_BOUNCE_DEFAULT);
@ -1215,7 +1218,7 @@ static int PatchThing (int thingy)
}
if (value[1] & 0x00000001)
{
info->gravity = FRACUNIT/4;
info->Gravity = 1./4;
value[1] &= ~0x00000001;
}
info->flags2 = ActorFlags2::FromInt (value[1]);
@ -1226,11 +1229,11 @@ static int PatchThing (int thingy)
{
hadTranslucency = true;
if (value[2] & 1)
info->alpha = TRANSLUC25;
info->Alpha = 0.25;
else if (value[2] & 2)
info->alpha = TRANSLUC50;
info->Alpha = 0.5;
else if (value[2] & 4)
info->alpha = TRANSLUC75;
info->Alpha = 0.75;
info->RenderStyle = STYLE_Translucent;
}
if (value[2] & 8)
@ -1257,7 +1260,7 @@ static int PatchThing (int thingy)
!hadHeight &&
thingy <= (int)OrgHeights.Size() && thingy > 0)
{
info->height = OrgHeights[thingy - 1] * FRACUNIT;
info->Height = OrgHeights[thingy - 1];
info->projectilepassheight = 0;
}
// If the thing's shadow changed, change its fuzziness if not already specified
@ -1268,7 +1271,7 @@ static int PatchThing (int thingy)
if (!hadStyle)
info->RenderStyle = STYLE_OptFuzzy;
if (!hadTranslucency)
info->alpha = FRACUNIT/5;
info->Alpha = 0.5;
}
else
{ // changed from shadow
@ -1276,11 +1279,11 @@ static int PatchThing (int thingy)
info->RenderStyle = STYLE_Normal;
}
}
// If this thing's speed is really low (i.e. meant to be a monster),
// bump it up, because all speeds are fixed point now.
if (abs(info->Speed) < 256)
// Speed could be either an int of fixed value, depending on its use
// If this value is very large it needs to be rescaled.
if (fabs(info->Speed) >= 256)
{
info->Speed <<= FRACBITS;
info->Speed /= 65536;
}
if (info->flags & MF_SPECIAL)
@ -1853,7 +1856,7 @@ static int PatchMisc (int dummy)
}
else if (stricmp (Line1, "Rocket Explosion Alpha") == 0)
{
deh.ExplosionAlpha = (fixed_t)(atof (Line2) * FRACUNIT);
deh.ExplosionAlpha = atof (Line2);
}
else if (stricmp (Line1, "Monsters Infight") == 0)
{
@ -1940,13 +1943,13 @@ static int PatchMisc (int dummy)
if (armor!=NULL)
{
armor->SaveAmount = 100 * deh.GreenAC;
armor->SavePercent = deh.GreenAC == 1 ? FRACUNIT/3 : FRACUNIT/2;
armor->SavePercent = deh.GreenAC == 1 ? 0.33335 : 0.5;
}
armor = static_cast<ABasicArmorPickup *> (GetDefaultByName ("BlueArmor"));
if (armor!=NULL)
{
armor->SaveAmount = 100 * deh.BlueAC;
armor->SavePercent = deh.BlueAC == 1 ? FRACUNIT/3 : FRACUNIT/2;
armor->SavePercent = deh.BlueAC == 1 ? 0.33335 : 0.5;
}
ABasicArmorBonus *barmor;

View file

@ -2203,7 +2203,7 @@ void Net_DoCommand (int type, BYTE **stream, int player)
x = ReadWord (stream);
y = ReadWord (stream);
z = ReadWord (stream);
P_TeleportMove (players[player].mo, x * 65536, y * 65536, z * 65536, true);
P_TeleportMove (players[player].mo, DVector3(x, y, z), true);
}
break;
@ -2321,7 +2321,7 @@ void Net_DoCommand (int type, BYTE **stream, int player)
else
{
const AActor *def = GetDefaultByType (typeinfo);
fixedvec3 spawnpos = source->Vec3Angle(def->radius * 2 + source->radius, source->angle, 8 * FRACUNIT);
DVector3 spawnpos = source->Vec3Angle(def->radius * 2 + source->radius, source->Angles.Yaw, 8.);
AActor *spawned = Spawn (typeinfo, spawnpos, ALLOW_REPLACE);
if (spawned != NULL)
@ -2348,7 +2348,7 @@ void Net_DoCommand (int type, BYTE **stream, int player)
}
if (type >= DEM_SUMMON2 && type <= DEM_SUMMONFOE2)
{
spawned->angle = source->angle - (ANGLE_1 * angle);
spawned->Angles.Yaw = source->Angles.Yaw - angle;
spawned->tid = tid;
spawned->special = special;
for(i = 0; i < 5; i++) {
@ -2366,19 +2366,15 @@ void Net_DoCommand (int type, BYTE **stream, int player)
{
FTraceResults trace;
angle_t ang = players[player].mo->angle >> ANGLETOFINESHIFT;
angle_t pitch = (angle_t)(players[player].mo->pitch) >> ANGLETOFINESHIFT;
fixed_t vx = FixedMul (finecosine[pitch], finecosine[ang]);
fixed_t vy = FixedMul (finecosine[pitch], finesine[ang]);
fixed_t vz = -finesine[pitch];
DAngle ang = players[player].mo->Angles.Yaw;
DAngle pitch = players[player].mo->Angles.Pitch;
double c = pitch.Cos();
DVector3 vec(c * ang.Cos(), c * ang.Sin(), -pitch.Sin());
s = ReadString (stream);
if (Trace (players[player].mo->X(), players[player].mo->Y(),
players[player].mo->Top() - (players[player].mo->height>>2),
players[player].mo->Sector,
vx, vy, vz, 172*FRACUNIT, 0, ML_BLOCKEVERYTHING, players[player].mo,
trace, TRACE_NoSky))
if (Trace (players[player].mo->PosPlusZ(players[player].mo->Height/2), players[player].mo->Sector,
vec, 172., 0, ML_BLOCKEVERYTHING, players[player].mo, trace, TRACE_NoSky))
{
if (trace.HitType == TRACE_HitWall)
{
@ -2656,8 +2652,8 @@ void Net_DoCommand (int type, BYTE **stream, int player)
break;
case DEM_SETPITCHLIMIT:
players[player].MinPitch = ReadByte(stream) * -ANGLE_1; // up
players[player].MaxPitch = ReadByte(stream) * ANGLE_1; // down
players[player].MinPitch = -(double)ReadByte(stream); // up
players[player].MaxPitch = (double)ReadByte(stream); // down
break;
case DEM_ADVANCEINTER:

View file

@ -878,33 +878,6 @@ void D_ReadUserInfoStrings (int pnum, BYTE **stream, bool update)
*stream += strlen (*((char **)stream)) + 1;
}
void ReadCompatibleUserInfo(FArchive &arc, userinfo_t &info)
{
char netname[MAXPLAYERNAME + 1];
BYTE team;
int aimdist, color, colorset, skin, gender;
bool neverswitch;
//fixed_t movebob, stillbob; These were never serialized!
//int playerclass; "
info.Reset();
arc.Read(&netname, sizeof(netname));
arc << team << aimdist << color << skin << gender << neverswitch << colorset;
*static_cast<FStringCVar *>(info[NAME_Name]) = netname;
*static_cast<FIntCVar *>(info[NAME_Team]) = team;
*static_cast<FFloatCVar *>(info[NAME_Autoaim]) = ANGLE2FLOAT(aimdist);
*static_cast<FIntCVar *>(info[NAME_Skin]) = skin;
*static_cast<FIntCVar *>(info[NAME_Gender]) = gender;
*static_cast<FBoolCVar *>(info[NAME_NeverSwitchOnPickup]) = neverswitch;
*static_cast<FIntCVar *>(info[NAME_ColorSet]) = colorset;
UCVarValue val;
val.Int = color;
static_cast<FColorCVar *>(info[NAME_Color])->SetGenericRep(val, CVAR_Int);
}
void WriteUserInfo(FArchive &arc, userinfo_t &info)
{
TMapIterator<FName, FBaseCVar *> it(info);
@ -945,12 +918,6 @@ void ReadUserInfo(FArchive &arc, userinfo_t &info, FString &skin)
char *str = NULL;
UCVarValue val;
if (SaveVersion < 4253)
{
ReadCompatibleUserInfo(arc, info);
return;
}
info.Reset();
skin = NULL;
for (arc << name; name != NAME_None; arc << name)

View file

@ -89,7 +89,7 @@ public:
FString Slot[10];
FName InvulMode;
FName HealingRadiusType;
fixed_t HexenArmor[5];
double HexenArmor[5];
BYTE ColorRangeStart; // Skin color range
BYTE ColorRangeEnd;
FPlayerColorSetMap ColorSets;
@ -114,7 +114,7 @@ public:
virtual void PlayIdle ();
virtual void PlayRunning ();
virtual void ThrowPoisonBag ();
virtual void TweakSpeeds (int &forwardmove, int &sidemove);
virtual void TweakSpeeds (double &forwardmove, double &sidemove);
virtual void MorphPlayerThink ();
virtual void ActivateMorphWeapon ();
AWeapon *PickNewWeapon (PClassAmmo *ammotype);
@ -149,25 +149,25 @@ public:
TObjPtr<AInventory> InvSel; // selected inventory item
// [GRB] Player class properties
fixed_t JumpZ;
fixed_t GruntSpeed;
fixed_t FallingScreamMinSpeed, FallingScreamMaxSpeed;
fixed_t ViewHeight;
fixed_t ForwardMove1, ForwardMove2;
fixed_t SideMove1, SideMove2;
double JumpZ;
double GruntSpeed;
double FallingScreamMinSpeed, FallingScreamMaxSpeed;
double ViewHeight;
double ForwardMove1, ForwardMove2;
double SideMove1, SideMove2;
FTextureID ScoreIcon;
int SpawnMask;
FNameNoInit MorphWeapon;
fixed_t AttackZOffset; // attack height, relative to player center
fixed_t UseRange; // [NS] Distance at which player can +use
fixed_t AirCapacity; // Multiplier for air supply underwater.
double AttackZOffset; // attack height, relative to player center
double UseRange; // [NS] Distance at which player can +use
double AirCapacity; // Multiplier for air supply underwater.
PClassActor *FlechetteType;
// [CW] Fades for when you are being damaged.
PalEntry DamageFade;
bool UpdateWaterLevel (fixed_t oldz, bool splash);
bool UpdateWaterLevel (bool splash);
bool ResetAirSupply (bool playgasp = true);
int GetMaxHealth() const;
@ -292,7 +292,7 @@ struct userinfo_t : TMap<FName,FBaseCVar *>
{
~userinfo_t();
int GetAimDist() const
double GetAimDist() const
{
if (dmflags2 & DF2_NOAUTOAIM)
{
@ -302,11 +302,11 @@ struct userinfo_t : TMap<FName,FBaseCVar *>
float aim = *static_cast<FFloatCVar *>(*CheckKey(NAME_Autoaim));
if (aim > 35 || aim < 0)
{
return ANGLE_1*35;
return 35.;
}
else
{
return xs_RoundToInt(fabs(aim * ANGLE_1));
return aim;
}
}
const char *GetName() const
@ -329,13 +329,13 @@ struct userinfo_t : TMap<FName,FBaseCVar *>
{
return *static_cast<FBoolCVar *>(*CheckKey(NAME_NeverSwitchOnPickup));
}
fixed_t GetMoveBob() const
double GetMoveBob() const
{
return FLOAT2FIXED(*static_cast<FFloatCVar *>(*CheckKey(NAME_MoveBob)));
return *static_cast<FFloatCVar *>(*CheckKey(NAME_MoveBob));
}
fixed_t GetStillBob() const
double GetStillBob() const
{
return FLOAT2FIXED(*static_cast<FFloatCVar *>(*CheckKey(NAME_StillBob)));
return *static_cast<FFloatCVar *>(*CheckKey(NAME_StillBob));
}
int GetPlayerClassNum() const
{
@ -402,16 +402,16 @@ public:
float DesiredFOV; // desired field of vision
float FOV; // current field of vision
fixed_t viewz; // focal origin above r.z
fixed_t viewheight; // base height above floor for viewz
fixed_t deltaviewheight; // squat speed.
fixed_t bob; // bounded/scaled total velocity
double viewz; // focal origin above r.z
double viewheight; // base height above floor for viewz
double deltaviewheight; // squat speed.
double bob; // bounded/scaled total velocity
// killough 10/98: used for realistic bobbing (i.e. not simply overall speed)
// mo->vel.x and mo->vel.y represent true velocity experienced by player.
// mo->velx and mo->vely represent true velocity experienced by player.
// This only represents the thrust that the player applies himself.
// This avoids anomalies with such things as Boom ice and conveyors.
fixedvec2 vel;
DVector2 Vel;
bool centering;
BYTE turnticks;
@ -488,30 +488,30 @@ public:
FString LogText; // [RH] Log for Strife
int MinPitch; // Viewpitch limits (negative is up, positive is down)
int MaxPitch;
DAngle MinPitch; // Viewpitch limits (negative is up, positive is down)
DAngle MaxPitch;
fixed_t crouchfactor;
fixed_t crouchoffset;
fixed_t crouchviewdelta;
double crouchfactor;
double crouchoffset;
double crouchviewdelta;
FWeaponSlots weapons;
// [CW] I moved these here for multiplayer conversation support.
TObjPtr<AActor> ConversationNPC, ConversationPC;
angle_t ConversationNPCAngle;
DAngle ConversationNPCAngle;
bool ConversationFaceTalker;
fixed_t GetDeltaViewHeight() const
double GetDeltaViewHeight() const
{
return (mo->ViewHeight + crouchviewdelta - viewheight) >> 3;
return (mo->ViewHeight + crouchviewdelta - viewheight) / 8;
}
void Uncrouch()
{
if (crouchfactor != FRACUNIT)
if (crouchfactor != 1)
{
crouchfactor = FRACUNIT;
crouchfactor = 1;
crouchoffset = 0;
crouchdir = 0;
crouching = 0;
@ -533,7 +533,7 @@ extern player_t players[MAXPLAYERS];
FArchive &operator<< (FArchive &arc, player_t *&p);
void P_CheckPlayerSprite(AActor *mo, int &spritenum, fixed_t &scalex, fixed_t &scaley);
void P_CheckPlayerSprite(AActor *mo, int &spritenum, DVector2 &scale);
inline void AActor::SetFriendPlayer(player_t *player)
{
@ -556,7 +556,7 @@ inline bool AActor::IsNoClip2() const
return false;
}
#define CROUCHSPEED (FRACUNIT/12)
#define CROUCHSPEED (1./12)
bool P_IsPlayerTotallyFrozen(const player_t *player);

View file

@ -50,9 +50,6 @@
#define NETD_ID BIGE_ID('N','E','T','D')
#define WEAP_ID BIGE_ID('W','E','A','P')
#define ANGLE2SHORT(x) ((((x)/360) & 65535)
#define SHORT2ANGLE(x) ((x)*360)
struct zdemoheader_s {
BYTE demovermajor;

View file

@ -52,7 +52,7 @@
FDecalLib DecalLibrary;
static fixed_t ReadScale (FScanner &sc);
static double ReadScale (FScanner &sc);
static TArray<BYTE> DecalTranslations;
// A decal group holds multiple decals and returns one randomly
@ -148,7 +148,7 @@ public:
int TimeToStartDecay;
int TimeToEndDecay;
fixed_t StartTrans;
double StartTrans;
private:
DDecalFader () {}
};
@ -186,7 +186,7 @@ struct FDecalStretcherAnim : public FDecalAnimator
int StretchStart;
int StretchTime;
fixed_t GoalX, GoalY;
double GoalX, GoalY;
};
class DDecalStretcher : public DDecalThinker
@ -199,10 +199,10 @@ public:
int TimeToStart;
int TimeToStop;
fixed_t GoalX;
fixed_t StartX;
fixed_t GoalY;
fixed_t StartY;
double GoalX;
double StartX;
double GoalY;
double StartY;
bool bStretchX;
bool bStretchY;
bool bStarted;
@ -217,7 +217,7 @@ struct FDecalSliderAnim : public FDecalAnimator
int SlideStart;
int SlideTime;
fixed_t /*DistX,*/ DistY;
double /*DistX,*/ DistY;
};
class DDecalSlider : public DDecalThinker
@ -230,10 +230,10 @@ public:
int TimeToStart;
int TimeToStop;
/* fixed_t DistX; */
fixed_t DistY;
fixed_t StartX;
fixed_t StartY;
/* double DistX; */
double DistY;
double StartX;
double StartY;
bool bStarted;
private:
DDecalSlider () {}
@ -453,10 +453,10 @@ void FDecalLib::ParseDecal (FScanner &sc)
memset ((void *)&newdecal, 0, sizeof(newdecal));
newdecal.PicNum.SetInvalid();
newdecal.ScaleX = newdecal.ScaleY = FRACUNIT;
newdecal.ScaleX = newdecal.ScaleY = 1.;
newdecal.RenderFlags = RF_WALLSPRITE;
newdecal.RenderStyle = STYLE_Normal;
newdecal.Alpha = 0x8000;
newdecal.Alpha = 1.;
for (;;)
{
@ -492,13 +492,13 @@ void FDecalLib::ParseDecal (FScanner &sc)
case DECAL_ADD:
sc.MustGetFloat ();
newdecal.Alpha = (WORD)(32768.f * sc.Float);
newdecal.Alpha = sc.Float;
newdecal.RenderStyle = STYLE_Add;
break;
case DECAL_TRANSLUCENT:
sc.MustGetFloat ();
newdecal.Alpha = (WORD)(32768.f * sc.Float);
newdecal.Alpha = sc.Float;
newdecal.RenderStyle = STYLE_Translucent;
break;
@ -681,7 +681,7 @@ void FDecalLib::ParseFader (FScanner &sc)
void FDecalLib::ParseStretcher (FScanner &sc)
{
FString stretcherName;
fixed_t goalX = -1, goalY = -1;
double goalX = -1, goalY = -1;
int startTime = 0, takeTime = 0;
sc.MustGetString ();
@ -732,7 +732,7 @@ void FDecalLib::ParseStretcher (FScanner &sc)
void FDecalLib::ParseSlider (FScanner &sc)
{
FString sliderName;
fixed_t distX = 0, distY = 0;
double distX = 0, distY = 0;
int startTime = 0, takeTime = 0;
sc.MustGetString ();
@ -773,7 +773,7 @@ void FDecalLib::ParseSlider (FScanner &sc)
else if (sc.Compare ("DistY"))
{
sc.MustGetFloat ();
distY = (fixed_t)(sc.Float * FRACUNIT);
distY = sc.Float;
}
else
{
@ -1046,7 +1046,7 @@ void FDecalTemplate::ApplyToDecal (DBaseDecal *decal, side_t *wall) const
decal->ScaleX = ScaleX;
decal->ScaleY = ScaleY;
decal->PicNum = PicNum;
decal->Alpha = Alpha << 1;
decal->Alpha = Alpha;
decal->RenderStyle = RenderStyle;
decal->RenderFlags = (RenderFlags & ~(DECAL_RandomFlipX|DECAL_RandomFlipY)) |
(decal->RenderFlags & (RF_RELMASK|RF_CLIPMASK|RF_INVISIBLE|RF_ONESIDED));
@ -1184,7 +1184,7 @@ void DDecalFader::Tick ()
int distanceToEnd = TimeToEndDecay - level.maptime;
int fadeDistance = TimeToEndDecay - TimeToStartDecay;
TheDecal->Alpha = Scale (StartTrans, distanceToEnd, fadeDistance);
TheDecal->Alpha = StartTrans * distanceToEnd / fadeDistance;
}
}
@ -1278,11 +1278,11 @@ void DDecalStretcher::Tick ()
int maxDistance = TimeToStop - TimeToStart;
if (bStretchX)
{
TheDecal->ScaleX = StartX + Scale (GoalX - StartX, distance, maxDistance);
TheDecal->ScaleX = StartX + (GoalX - StartX) * distance / maxDistance;
}
if (bStretchY)
{
TheDecal->ScaleY = StartY + Scale (GoalY - StartY, distance, maxDistance);
TheDecal->ScaleY = StartY + (GoalY - StartY) * distance / maxDistance;
}
}
@ -1339,8 +1339,8 @@ void DDecalSlider::Tick ()
int distance = level.maptime - TimeToStart;
int maxDistance = TimeToStop - TimeToStart;
/*TheDecal->LeftDistance = StartX + Scale (DistX, distance, maxDistance);*/
TheDecal->Z = StartY + Scale (DistY, distance, maxDistance);
/*TheDecal->LeftDistance = StartX + DistX * distance / maxDistance);*/
TheDecal->Z = StartY + DistY * distance / maxDistance;
}
DThinker *FDecalCombinerAnim::CreateThinker (DBaseDecal *actor, side_t *wall) const
@ -1428,8 +1428,8 @@ DThinker *FDecalColorerAnim::CreateThinker (DBaseDecal *actor, side_t *wall) con
return Colorer;
}
static fixed_t ReadScale (FScanner &sc)
static double ReadScale (FScanner &sc)
{
sc.MustGetFloat ();
return fixed_t(clamp (sc.Float * FRACUNIT, 256.0, 256.0*FRACUNIT));
return clamp (sc.Float, 1/256.0, 256.0);
}

View file

@ -74,13 +74,13 @@ public:
const FDecalTemplate *GetDecal () const;
void ReplaceDecalRef (FDecalBase *from, FDecalBase *to);
fixed_t ScaleX, ScaleY;
double ScaleX, ScaleY;
DWORD ShadeColor;
DWORD Translation;
FRenderStyle RenderStyle;
FTextureID PicNum;
WORD RenderFlags;
WORD Alpha; // same as (actor->alpha >> 1)
double Alpha; // same as actor->alpha
const FDecalAnimator *Animator;
const FDecalBase *LowerDecal;

View file

@ -80,8 +80,6 @@ PName *TypeName;
PSound *TypeSound;
PColor *TypeColor;
PStatePointer *TypeState;
PFixed *TypeFixed;
PAngle *TypeAngle;
// PRIVATE DATA DEFINITIONS ------------------------------------------------
@ -663,9 +661,7 @@ void PType::StaticInit()
RUNTIME_CLASS(PPrototype)->TypeTableType = RUNTIME_CLASS(PPrototype);
RUNTIME_CLASS(PClass)->TypeTableType = RUNTIME_CLASS(PClass);
RUNTIME_CLASS(PStatePointer)->TypeTableType = RUNTIME_CLASS(PStatePointer);
RUNTIME_CLASS(PFixed)->TypeTableType = RUNTIME_CLASS(PFixed);
RUNTIME_CLASS(PAngle)->TypeTableType = RUNTIME_CLASS(PAngle);
// Create types and add them type the type table.
TypeTable.AddType(TypeError = new PErrorType);
TypeTable.AddType(TypeVoid = new PVoidType);
@ -683,8 +679,6 @@ void PType::StaticInit()
TypeTable.AddType(TypeSound = new PSound);
TypeTable.AddType(TypeColor = new PColor);
TypeTable.AddType(TypeState = new PStatePointer);
TypeTable.AddType(TypeFixed = new PFixed);
TypeTable.AddType(TypeAngle = new PAngle);
GlobalSymbols.AddSymbol(new PSymbolType(NAME_sByte, TypeSInt8));
GlobalSymbols.AddSymbol(new PSymbolType(NAME_Byte, TypeUInt8));
@ -702,8 +696,6 @@ void PType::StaticInit()
GlobalSymbols.AddSymbol(new PSymbolType(NAME_Sound, TypeSound));
GlobalSymbols.AddSymbol(new PSymbolType(NAME_Color, TypeColor));
GlobalSymbols.AddSymbol(new PSymbolType(NAME_State, TypeState));
GlobalSymbols.AddSymbol(new PSymbolType(NAME_Fixed, TypeFixed));
GlobalSymbols.AddSymbol(new PSymbolType(NAME_Angle, TypeAngle));
}
@ -1694,242 +1686,6 @@ PColor::PColor()
assert(sizeof(PalEntry) == __alignof(PalEntry));
}
/* PFixed *****************************************************************/
IMPLEMENT_CLASS(PFixed)
//==========================================================================
//
// PFixed Default Constructor
//
//==========================================================================
PFixed::PFixed()
: PFloat(sizeof(fixed_t))
{
}
//==========================================================================
//
// PFixed :: WriteValue
//
//==========================================================================
void PFixed::WriteValue(FArchive &ar, const void *addr) const
{
ar.WriteByte(VAL_Fixed);
ar << *(fixed_t *)addr;
}
//==========================================================================
//
// PFixed :: ReadValue
//
//==========================================================================
bool PFixed::ReadValue(FArchive &ar, void *addr) const
{
BYTE tag;
ar << tag;
if (tag == VAL_Fixed)
{
ar << *(fixed_t *)addr;
return true;
}
else
{
double val;
if (ReadValueDbl(ar, &val, tag))
{
*(fixed_t *)addr = FLOAT2FIXED(val);
return true;
}
return false;
}
}
//==========================================================================
//
// PFixed :: SetValue
//
//==========================================================================
void PFixed::SetValue(void *addr, int val)
{
assert(((intptr_t)addr & (Align - 1)) == 0 && "unaligned address");
*(fixed_t *)addr = val << FRACBITS;
}
void PFixed::SetValue(void *addr, double val)
{
assert(((intptr_t)addr & (Align - 1)) == 0 && "unaligned address");
*(fixed_t *)addr = FLOAT2FIXED(val);
}
//==========================================================================
//
// PFixed :: GetValueInt
//
//==========================================================================
int PFixed::GetValueInt(void *addr) const
{
assert(((intptr_t)addr & (Align - 1)) == 0 && "unaligned address");
return *(fixed_t *)addr >> FRACBITS;
}
//==========================================================================
//
// PFixed :: GetValueFloat
//
//==========================================================================
double PFixed::GetValueFloat(void *addr) const
{
assert(((intptr_t)addr & (Align - 1)) == 0 && "unaligned address");
return FIXED2DBL(*(fixed_t *)addr);
}
//==========================================================================
//
// PFixed :: GetStoreOp
//
//==========================================================================
int PFixed::GetStoreOp() const
{
return OP_SX;
}
//==========================================================================
//
// PFixed :: GetLoadOp
//
//==========================================================================
int PFixed::GetLoadOp() const
{
return OP_LX;
}
/* PAngle *****************************************************************/
IMPLEMENT_CLASS(PAngle)
//==========================================================================
//
// PAngle Default Constructor
//
//==========================================================================
PAngle::PAngle()
: PFloat(sizeof(angle_t))
{
}
//==========================================================================
//
// PAngle :: WriteValue
//
//==========================================================================
void PAngle::WriteValue(FArchive &ar, const void *addr) const
{
ar.WriteByte(VAL_BAM);
ar.WriteInt32(*(angle_t *)addr);
}
//==========================================================================
//
// PAngle :: ReadValue
//
//==========================================================================
bool PAngle::ReadValue(FArchive &ar, void *addr) const
{
BYTE tag;
ar << tag;
if (tag == VAL_BAM)
{
ar << *(angle_t *)addr;
return true;
}
else
{
double val;
if (ReadValueDbl(ar, &val, tag))
{
*(angle_t *)addr = FLOAT2ANGLE(val);
return true;
}
return false;
}
}
//==========================================================================
//
// PAngle :: SetValue
//
//==========================================================================
void PAngle::SetValue(void *addr, int val)
{
assert(((intptr_t)addr & (Align - 1)) == 0 && "unaligned address");
*(angle_t *)addr = Scale(val, ANGLE_90, 90);
}
void PAngle::SetValue(void *addr, double val)
{
assert(((intptr_t)addr & (Align - 1)) == 0 && "unaligned address");
*(angle_t *)addr = (angle_t)(val * ANGLE_90 / 90);
}
//==========================================================================
//
// PAngle :: GetValueInt
//
//==========================================================================
int PAngle::GetValueInt(void *addr) const
{
assert(((intptr_t)addr & (Align - 1)) == 0 && "unaligned address");
return *(angle_t *)addr / ANGLE_1;
}
//==========================================================================
//
// PAngle :: GetValueFloat
//
//==========================================================================
double PAngle::GetValueFloat(void *addr) const
{
assert(((intptr_t)addr & (Align - 1)) == 0 && "unaligned address");
return (double)(*(angle_t *)addr) / ANGLE_1;
}
//==========================================================================
//
// PAngle :: GetStoreOp
//
//==========================================================================
int PAngle::GetStoreOp() const
{
return OP_SANG;
}
//==========================================================================
//
// PAngle :: GetLoadOp
//
//==========================================================================
int PAngle::GetLoadOp() const
{
return OP_LANG;
}
/* PStatePointer **********************************************************/
IMPLEMENT_CLASS(PStatePointer)
@ -3537,8 +3293,8 @@ PField *PClass::AddField(FName name, PType *type, DWORD flags)
PField *field = Super::AddField(name, type, flags);
if (field != NULL)
{
Defaults = (BYTE *)M_Realloc(Defaults, Size);
memset(Defaults + oldsize, 0, Size - oldsize);
Defaults = (BYTE *)M_Realloc(Defaults, Size);
memset(Defaults + oldsize, 0, Size - oldsize);
// If this is a native class, then we must not initialize and
// destroy any of its members. We do, however, initialize the
// default instance since it's not a normal instance of the class.

View file

@ -456,43 +456,6 @@ public:
PColor();
};
// Variations of floating point types ---------------------------------------
// These get converted to floats when they're loaded from memory.
class PFixed : public PFloat
{
DECLARE_CLASS(PFixed, PFloat);
public:
PFixed();
void WriteValue(FArchive &ar, const void *addr) const override;
bool ReadValue(FArchive &ar, void *addr) const override;
virtual void SetValue(void *addr, int val);
virtual void SetValue(void *addr, double val);
virtual int GetValueInt(void *addr) const;
virtual double GetValueFloat(void *addr) const;
virtual int GetStoreOp() const;
virtual int GetLoadOp() const;
};
class PAngle : public PFloat
{
DECLARE_CLASS(PAngle, PFloat);
public:
PAngle();
void WriteValue(FArchive &ar, const void *addr) const override;
bool ReadValue(FArchive &ar, void *addr) const override;
virtual void SetValue(void *addr, int val);
virtual void SetValue(void *addr, double val);
virtual int GetValueInt(void *addr) const;
virtual double GetValueFloat(void *addr) const;
virtual int GetStoreOp() const;
virtual int GetLoadOp() const;
};
// Pointers -----------------------------------------------------------------
class PStatePointer : public PBasicType
@ -878,8 +841,6 @@ extern PName *TypeName;
extern PSound *TypeSound;
extern PColor *TypeColor;
extern PStatePointer *TypeState;
extern PFixed *TypeFixed;
extern PAngle *TypeAngle;
// A constant value ---------------------------------------------------------

View file

@ -26,6 +26,7 @@
// The most basic types we use, portability.
#include "doomtype.h"
#include "vectors.h"
// Some global defines, that configure the game.
#include "doomdef.h"
@ -345,9 +346,7 @@ struct FDoomEdEntry;
struct FMapThing
{
int thingid;
fixed_t x;
fixed_t y;
fixed_t z;
DVector3 pos;
short angle;
WORD SkillFilter;
WORD ClassFilter;
@ -357,11 +356,10 @@ struct FMapThing
int special;
int args[5];
int Conversation;
fixed_t gravity;
fixed_t alpha;
double Gravity;
double Alpha;
DWORD fillcolor;
fixed_t scaleX;
fixed_t scaleY;
DVector2 Scale;
int health;
int score;
short pitch;
@ -428,12 +426,12 @@ enum EMapThingFlags
// A simplified mapthing for player starts
struct FPlayerStart
{
fixed_t x, y, z;
DVector3 pos;
short angle, type;
FPlayerStart() { }
FPlayerStart(const FMapThing *mthing, int pnum)
: x(mthing->x), y(mthing->y), z(mthing->z),
: pos(mthing->pos),
angle(mthing->angle),
type(pnum)
{ }

View file

@ -340,7 +340,7 @@ enum : unsigned int
COMPATF2_BADANGLES = 1 << 0, // It is impossible to face directly NSEW.
COMPATF2_FLOORMOVE = 1 << 1, // Use the same floor motion behavior as Doom.
COMPATF2_SOUNDCUTOFF = 1 << 2, // Cut off sounds when an actor vanishes instead of making it owner-less
COMPATF2_POINTONLINE = 1 << 3, // Use original but buggy P_PointOnLineSide() and P_PointOnDivlineSide()
COMPATF2_POINTONLINE = 1 << 3, // Use original but buggy P_PointOnLineSide() and P_PointOnDivlineSideCompat()
COMPATF2_MULTIEXIT = 1 << 4, // Level exit can be triggered multiple times (required by Daedalus's travel tubes, thanks to a faulty script)
};
@ -365,11 +365,11 @@ enum
// linedefs. More friction can create mud, sludge,
// magnetized floors, etc. Less friction can create ice.
#define MORE_FRICTION_VELOCITY 15000 // mud factor based on velocity
#define ORIG_FRICTION 0xE800 // original value
#define ORIG_FRICTION_FACTOR 2048 // original value
#define FRICTION_LOW 0xf900
#define FRICTION_FLY 0xeb00
#define MORE_FRICTION_VELOCITY (15000/65536.) // mud factor based on velocity
#define ORIG_FRICTION (0xE800/65536.) // original value
#define ORIG_FRICTION_FACTOR (2048/65536.) // original value
#define FRICTION_LOW (0xf900/65536.)
#define FRICTION_FLY (0xeb00/65536.)
#define BLINKTHRESHOLD (4*32)

View file

@ -233,7 +233,7 @@ struct DehInfo
int KFAAC;
char PlayerSprite[5];
BYTE ExplosionStyle;
fixed_t ExplosionAlpha;
double ExplosionAlpha;
int NoAutofreeze;
int BFGCells;
};

View file

@ -44,7 +44,6 @@
#include "tarray.h"
#include "name.h"
#include "zstring.h"
#include "vectors.h"
class PClassActor;
typedef TMap<int, PClassActor *> FClassMap;
@ -252,10 +251,13 @@ enum ESSType
SS_BGRA
};
#ifndef M_PI
#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h
// always use our own definition for consistency.
#ifdef M_PI
#undef M_PI
#endif
const double M_PI = 3.14159265358979323846; // matches value in gcc v2 math.h
template <typename T, size_t N>
char ( &_ArraySizeHelper( T (&array)[N] ))[N];

View file

@ -133,7 +133,7 @@ DMovingCeiling::DMovingCeiling (sector_t *sector)
interpolation = sector->SetInterpolation(sector_t::CeilingMove, true);
}
bool DMover::MoveAttached(int crush, fixed_t move, int floorOrCeiling, bool resetfailed)
bool DMover::MoveAttached(int crush, double move, int floorOrCeiling, bool resetfailed)
{
if (!P_Scroll3dMidtex(m_Sector, crush, move, !!floorOrCeiling) && resetfailed)
{
@ -155,20 +155,20 @@ bool DMover::MoveAttached(int crush, fixed_t move, int floorOrCeiling, bool rese
// (Use -1 to prevent it from trying to crush)
// dest is the desired d value for the plane
//
DMover::EResult DMover::MovePlane (fixed_t speed, fixed_t dest, int crush,
DMover::EResult DMover::MovePlane (double speed, double dest, int crush,
int floorOrCeiling, int direction, bool hexencrush)
{
bool flag;
fixed_t lastpos;
fixed_t movedest;
fixed_t move;
//fixed_t destheight; //jff 02/04/98 used to keep floors/ceilings
double lastpos;
double movedest;
double move;
//double destheight; //jff 02/04/98 used to keep floors/ceilings
// from moving thru each other
switch (floorOrCeiling)
{
case 0:
// FLOOR
lastpos = m_Sector->floorplane.d;
lastpos = m_Sector->floorplane.fD();
switch (direction)
{
case -1:
@ -180,11 +180,11 @@ DMover::EResult DMover::MovePlane (fixed_t speed, fixed_t dest, int crush,
if (!MoveAttached(crush, move, 0, true)) return crushed;
m_Sector->floorplane.d = dest;
m_Sector->floorplane.setD(dest);
flag = P_ChangeSector (m_Sector, crush, move, 0, false);
if (flag)
{
m_Sector->floorplane.d = lastpos;
m_Sector->floorplane.setD(lastpos);
P_ChangeSector (m_Sector, crush, -move, 0, true);
MoveAttached(crush, -move, 0, false);
}
@ -199,12 +199,12 @@ DMover::EResult DMover::MovePlane (fixed_t speed, fixed_t dest, int crush,
{
if (!MoveAttached(crush, -speed, 0, true)) return crushed;
m_Sector->floorplane.d = movedest;
m_Sector->floorplane.setD(movedest);
flag = P_ChangeSector (m_Sector, crush, -speed, 0, false);
if (flag)
{
m_Sector->floorplane.d = lastpos;
m_Sector->floorplane.setD(lastpos);
P_ChangeSector (m_Sector, crush, speed, 0, true);
MoveAttached(crush, speed, 0, false);
return crushed;
@ -222,11 +222,10 @@ DMover::EResult DMover::MovePlane (fixed_t speed, fixed_t dest, int crush,
// jff 02/04/98 keep floor from moving thru ceilings
// [RH] not so easy with arbitrary planes
//destheight = (dest < m_Sector->ceilingheight) ? dest : m_Sector->ceilingheight;
if ((m_Sector->ceilingplane.a | m_Sector->ceilingplane.b |
m_Sector->floorplane.a | m_Sector->floorplane.b) == 0 &&
(!(i_compatflags2 & COMPATF2_FLOORMOVE) && -dest > m_Sector->ceilingplane.d))
if (!m_Sector->ceilingplane.isSlope() && !m_Sector->floorplane.isSlope() &&
(!(i_compatflags2 & COMPATF2_FLOORMOVE) && -dest > m_Sector->ceilingplane.fD()))
{
dest = -m_Sector->ceilingplane.d;
dest = -m_Sector->ceilingplane.fD();
}
movedest = m_Sector->floorplane.GetChangedHeight (speed);
@ -237,12 +236,12 @@ DMover::EResult DMover::MovePlane (fixed_t speed, fixed_t dest, int crush,
if (!MoveAttached(crush, move, 0, true)) return crushed;
m_Sector->floorplane.d = dest;
m_Sector->floorplane.setD(dest);
flag = P_ChangeSector (m_Sector, crush, move, 0, false);
if (flag)
{
m_Sector->floorplane.d = lastpos;
m_Sector->floorplane.setD(lastpos);
P_ChangeSector (m_Sector, crush, -move, 0, true);
MoveAttached(crush, -move, 0, false);
}
@ -257,7 +256,7 @@ DMover::EResult DMover::MovePlane (fixed_t speed, fixed_t dest, int crush,
{
if (!MoveAttached(crush, speed, 0, true)) return crushed;
m_Sector->floorplane.d = movedest;
m_Sector->floorplane.setD(movedest);
// COULD GET CRUSHED
flag = P_ChangeSector (m_Sector, crush, speed, 0, false);
@ -269,7 +268,7 @@ DMover::EResult DMover::MovePlane (fixed_t speed, fixed_t dest, int crush,
m_Sector->AdjustFloorClip ();
return crushed;
}
m_Sector->floorplane.d = lastpos;
m_Sector->floorplane.setD(lastpos);
P_ChangeSector (m_Sector, crush, -speed, 0, true);
MoveAttached(crush, -speed, 0, false);
return crushed;
@ -283,7 +282,7 @@ DMover::EResult DMover::MovePlane (fixed_t speed, fixed_t dest, int crush,
case 1:
// CEILING
lastpos = m_Sector->ceilingplane.d;
lastpos = m_Sector->ceilingplane.fD();
switch (direction)
{
case -1:
@ -291,11 +290,10 @@ DMover::EResult DMover::MovePlane (fixed_t speed, fixed_t dest, int crush,
// jff 02/04/98 keep ceiling from moving thru floors
// [RH] not so easy with arbitrary planes
//destheight = (dest > m_Sector->floorheight) ? dest : m_Sector->floorheight;
if ((m_Sector->ceilingplane.a | m_Sector->ceilingplane.b |
m_Sector->floorplane.a | m_Sector->floorplane.b) == 0 &&
(!(i_compatflags2 & COMPATF2_FLOORMOVE) && dest < -m_Sector->floorplane.d))
if (!m_Sector->ceilingplane.isSlope() && !m_Sector->floorplane.isSlope() &&
(!(i_compatflags2 & COMPATF2_FLOORMOVE) && dest < -m_Sector->floorplane.fD()))
{
dest = -m_Sector->floorplane.d;
dest = -m_Sector->floorplane.fD();
}
movedest = m_Sector->ceilingplane.GetChangedHeight (-speed);
if (movedest <= dest)
@ -304,12 +302,12 @@ DMover::EResult DMover::MovePlane (fixed_t speed, fixed_t dest, int crush,
if (!MoveAttached(crush, move, 1, true)) return crushed;
m_Sector->ceilingplane.d = dest;
m_Sector->ceilingplane.setD(dest);
flag = P_ChangeSector (m_Sector, crush, move, 1, false);
if (flag)
{
m_Sector->ceilingplane.d = lastpos;
m_Sector->ceilingplane.setD(lastpos);
P_ChangeSector (m_Sector, crush, -move, 1, true);
MoveAttached(crush, -move, 1, false);
}
@ -323,7 +321,7 @@ DMover::EResult DMover::MovePlane (fixed_t speed, fixed_t dest, int crush,
{
if (!MoveAttached(crush, -speed, 1, true)) return crushed;
m_Sector->ceilingplane.d = movedest;
m_Sector->ceilingplane.setD(movedest);
// COULD GET CRUSHED
flag = P_ChangeSector (m_Sector, crush, -speed, 1, false);
@ -334,7 +332,7 @@ DMover::EResult DMover::MovePlane (fixed_t speed, fixed_t dest, int crush,
m_Sector->ChangePlaneTexZ(sector_t::ceiling, m_Sector->ceilingplane.HeightDiff (lastpos));
return crushed;
}
m_Sector->ceilingplane.d = lastpos;
m_Sector->ceilingplane.setD(lastpos);
P_ChangeSector (m_Sector, crush, speed, 1, true);
MoveAttached(crush, speed, 1, false);
return crushed;
@ -352,12 +350,12 @@ DMover::EResult DMover::MovePlane (fixed_t speed, fixed_t dest, int crush,
if (!MoveAttached(crush, move, 1, true)) return crushed;
m_Sector->ceilingplane.d = dest;
m_Sector->ceilingplane.setD(dest);
flag = P_ChangeSector (m_Sector, crush, move, 1, false);
if (flag)
{
m_Sector->ceilingplane.d = lastpos;
m_Sector->ceilingplane.setD(lastpos);
P_ChangeSector (m_Sector, crush, move, 1, true);
MoveAttached(crush, move, 1, false);
}
@ -371,12 +369,12 @@ DMover::EResult DMover::MovePlane (fixed_t speed, fixed_t dest, int crush,
{
if (!MoveAttached(crush, speed, 1, true)) return crushed;
m_Sector->ceilingplane.d = movedest;
m_Sector->ceilingplane.setD(movedest);
flag = P_ChangeSector (m_Sector, crush, speed, 1, false);
if (flag)
{
m_Sector->ceilingplane.d = lastpos;
m_Sector->ceilingplane.setD(lastpos);
P_ChangeSector (m_Sector, crush, -speed, 1, true);
MoveAttached(crush, -speed, 1, false);
return crushed;

View file

@ -30,26 +30,26 @@ protected:
enum EResult { ok, crushed, pastdest };
TObjPtr<DInterpolation> interpolation;
private:
bool MoveAttached(int crush, fixed_t move, int floorOrCeiling, bool resetfailed);
EResult MovePlane (fixed_t speed, fixed_t dest, int crush, int floorOrCeiling, int direction, bool hexencrush);
bool MoveAttached(int crush, double move, int floorOrCeiling, bool resetfailed);
EResult MovePlane (double speed, double dest, int crush, int floorOrCeiling, int direction, bool hexencrush);
protected:
DMover ();
void Serialize (FArchive &arc);
void Destroy();
void StopInterpolation(bool force = false);
inline EResult MoveFloor (fixed_t speed, fixed_t dest, int crush, int direction, bool hexencrush)
inline EResult MoveFloor (double speed, double dest, int crush, int direction, bool hexencrush)
{
return MovePlane (speed, dest, crush, 0, direction, hexencrush);
}
inline EResult MoveFloor (fixed_t speed, fixed_t dest, int direction)
inline EResult MoveFloor (double speed, double dest, int direction)
{
return MovePlane (speed, dest, -1, 0, direction, false);
}
inline EResult MoveCeiling (fixed_t speed, fixed_t dest, int crush, int direction, bool hexencrush)
inline EResult MoveCeiling (double speed, double dest, int crush, int direction, bool hexencrush)
{
return MovePlane (speed, dest, crush, 1, direction, hexencrush);
}
inline EResult MoveCeiling (fixed_t speed, fixed_t dest, int direction)
inline EResult MoveCeiling (double speed, double dest, int direction)
{
return MovePlane (speed, dest, -1, 1, direction, false);
}

View file

@ -92,7 +92,7 @@ struct EDMapthing
int recordnum;
int tid;
int type;
fixed_t height;
double height;
int args[5];
WORD skillfilter;
DWORD flags;
@ -105,7 +105,7 @@ struct EDLinedef
int tag;
int id;
int args[5];
fixed_t alpha;
double alpha;
DWORD flags;
DWORD activation;
};
@ -140,10 +140,10 @@ struct EDSector
bool colorSet;
// colormaptop//bottom cannot be used because ZDoom has no corresponding properties.
FTransform planexform[2];
double xoffs[2], yoffs[2];
DAngle angle[2];
DWORD portalflags[2];
fixed_t overlayalpha[2];
double Overlayalpha[2];
};
static FString EDMap;
@ -158,7 +158,7 @@ static void parseLinedef(FScanner &sc)
bool argsset = false;
memset(&ld, 0, sizeof(ld));
ld.alpha = FRACUNIT;
ld.alpha = 1.;
sc.MustGetStringName("{");
while (!sc.CheckString("}"))
@ -216,7 +216,7 @@ static void parseLinedef(FScanner &sc)
{
sc.CheckString("=");
sc.MustGetFloat();
ld.alpha = FLOAT2FIXED(sc.Float);
ld.alpha = sc.Float;
}
else if (sc.Compare("extflags"))
{
@ -275,7 +275,7 @@ static void parseSector(FScanner &sc)
EDSector sec;
memset(&sec, 0, sizeof(sec));
sec.overlayalpha[sector_t::floor] = sec.overlayalpha[sector_t::ceiling] = FRACUNIT;
sec.Overlayalpha[sector_t::floor] = sec.Overlayalpha[sector_t::ceiling] = 1.;
sec.floorterrain = sec.ceilingterrain = -1;
sc.MustGetStringName("{");
@ -398,19 +398,19 @@ static void parseSector(FScanner &sc)
{
sc.CheckString("=");
sc.MustGetFloat();
sec.planexform[sector_t::floor].angle = FLOAT2ANGLE(sc.Float);
sec.angle[sector_t::floor] = sc.Float;
}
else if (sc.Compare("flooroffsetx"))
{
sc.CheckString("=");
sc.MustGetFloat();
sec.planexform[sector_t::floor].xoffs = FLOAT2FIXED(sc.Float);
sec.xoffs[sector_t::floor] = sc.Float;
}
else if (sc.Compare("flooroffsety"))
{
sc.CheckString("=");
sc.MustGetFloat();
sec.planexform[sector_t::floor].yoffs = FLOAT2FIXED(sc.Float);
sec.yoffs[sector_t::floor] = sc.Float;
}
else if (sc.Compare("ceilingterrain"))
{
@ -422,19 +422,19 @@ static void parseSector(FScanner &sc)
{
sc.CheckString("=");
sc.MustGetFloat();
sec.planexform[sector_t::ceiling].angle = FLOAT2ANGLE(sc.Float);
sec.angle[sector_t::ceiling] = sc.Float;
}
else if (sc.Compare("ceilingoffsetx"))
{
sc.CheckString("=");
sc.MustGetFloat();
sec.planexform[sector_t::ceiling].xoffs = FLOAT2FIXED(sc.Float);
sec.xoffs[sector_t::ceiling] = sc.Float;
}
else if (sc.Compare("ceilingoffsety"))
{
sc.CheckString("=");
sc.MustGetFloat();
sec.planexform[sector_t::ceiling].yoffs = FLOAT2FIXED(sc.Float);
sec.yoffs[sector_t::ceiling] = sc.Float;
}
else if (sc.Compare("colormaptop") || sc.Compare("colormapbottom"))
{
@ -464,14 +464,14 @@ static void parseSector(FScanner &sc)
sc.MustGetNumber();
if (sc.CheckString("%")) sc.Float = sc.Number / 100.f;
else sc.Float = sc.Number / 255.f;
sec.overlayalpha[sector_t::floor] = FLOAT2FIXED(sc.Float);
sec.Overlayalpha[sector_t::floor] = sc.Float;
}
else if (sc.Compare("ceiling"))
{
sc.MustGetFloat();
if (sc.CheckString("%")) sc.Float = sc.Number / 100.f;
else sc.Float = sc.Number / 255.f;
sec.overlayalpha[sector_t::floor] = FLOAT2FIXED(sc.Float);
sec.Overlayalpha[sector_t::floor] = sc.Float;
}
}
else if (sc.Compare("portalflags"))
@ -585,7 +585,7 @@ static void parseMapthing(FScanner &sc)
{
sc.CheckString("=");
sc.MustGetFloat(); // no idea if Eternity allows fractional numbers. Better be safe and do it anyway.
mt.height = FLOAT2FIXED(sc.Float);
mt.height = sc.Float;
}
else if (sc.Compare("options"))
{
@ -682,7 +682,7 @@ void ProcessEDMapthing(FMapThing *mt, int recordnum)
mt->thingid = emt->tid;
mt->EdNum = emt->type;
mt->info = DoomEdMap.CheckKey(mt->EdNum);
mt->z = emt->height;
mt->pos.Z = emt->height;
memcpy(mt->args, emt->args, sizeof(mt->args));
mt->SkillFilter = emt->skillfilter;
mt->flags = emt->flags;
@ -703,7 +703,7 @@ void ProcessEDLinedef(line_t *ld, int recordnum)
ld->special = eld->special;
ld->activation = eld->activation;
ld->flags = (ld->flags&~fmask) | eld->flags;
ld->Alpha = eld->alpha;
ld->setAlpha(eld->alpha);
memcpy(ld->args, eld->args, sizeof(ld->args));
tagManager.AddLineID(int(ld - lines), eld->tag);
}
@ -742,10 +742,10 @@ void ProcessEDSector(sector_t *sec, int recordnum)
const DWORD pflagmask = PLANEF_DISABLED | PLANEF_NORENDER | PLANEF_NOPASS | PLANEF_BLOCKSOUND | PLANEF_ADDITIVE;
for (int i = 0; i < 2; i++)
{
sec->planes[i].xform.xoffs = esec->planexform[i].xoffs;
sec->planes[i].xform.yoffs = esec->planexform[i].yoffs;
sec->planes[i].xform.angle = esec->planexform[i].angle;
sec->planes[i].alpha = esec->overlayalpha[i];
sec->SetXOffset(i, esec->xoffs[i]);
sec->SetYOffset(i, esec->yoffs[i]);
sec->SetAngle(i, esec->angle[i]);
sec->SetAlpha(i, esec->Overlayalpha[i]);
sec->planes[i].Flags = (sec->planes[i].Flags & ~pflagmask) | esec->portalflags[i];
}
}

View file

@ -269,12 +269,13 @@ bool wipe_doBurn (int ticks)
}
// Draw the screen
fixed_t xstep, ystep, firex, firey;
int xstep, ystep, firex, firey;
int x, y;
BYTE *to, *fromold, *fromnew;
const int SHIFT = 16;
xstep = (FIREWIDTH * FRACUNIT) / SCREENWIDTH;
ystep = (FIREHEIGHT * FRACUNIT) / SCREENHEIGHT;
xstep = (FIREWIDTH << SHIFT) / SCREENWIDTH;
ystep = (FIREHEIGHT << SHIFT) / SCREENHEIGHT;
to = screen->GetBuffer();
fromold = (BYTE *)wipe_scr_start;
fromnew = (BYTE *)wipe_scr_end;
@ -285,7 +286,7 @@ bool wipe_doBurn (int ticks)
{
int fglevel;
fglevel = burnarray[(firex>>FRACBITS)+(firey>>FRACBITS)*FIREWIDTH] / 2;
fglevel = burnarray[(firex>>SHIFT)+(firey>>SHIFT)*FIREWIDTH] / 2;
if (fglevel >= 63)
{
to[x] = fromnew[x];
@ -340,7 +341,7 @@ bool wipe_doFade (int ticks)
else
{
int x, y;
fixed_t bglevel = 64 - fade;
int bglevel = 64 - fade;
DWORD *fg2rgb = Col2RGB8[fade];
DWORD *bg2rgb = Col2RGB8[bglevel];
BYTE *fromnew = (BYTE *)wipe_scr_end;

View file

@ -1562,3 +1562,21 @@ FArchive &operator<< (FArchive &arc, side_t *&side)
{
return arc.SerializePointer (sides, (BYTE **)&side, sizeof(*sides));
}
FArchive &operator<<(FArchive &arc, DAngle &ang)
{
arc << ang.Degrees;
return arc;
}
FArchive &operator<<(FArchive &arc, DVector3 &vec)
{
arc << vec.X << vec.Y << vec.Z;
return arc;
}
FArchive &operator<<(FArchive &arc, DVector2 &vec)
{
arc << vec.X << vec.Y;
return arc;
}

View file

@ -331,6 +331,10 @@ FArchive &operator<< (FArchive &arc, line_t *&line);
FArchive &operator<< (FArchive &arc, vertex_t *&vert);
FArchive &operator<< (FArchive &arc, side_t *&side);
FArchive &operator<<(FArchive &arc, DAngle &ang);
FArchive &operator<<(FArchive &arc, DVector3 &vec);
FArchive &operator<<(FArchive &arc, DVector2 &vec);
template<typename T, typename TT>

View file

@ -46,7 +46,7 @@ public:
return *this;
}
FileReaderBase &operator>> (fixed_t &v)
FileReaderBase &operator>> (int &v)
{
Read (&v, 4);
v = LittleLong(v);
@ -171,7 +171,7 @@ public:
return *this;
}
FileReaderZ &operator>> (fixed_t &v)
FileReaderZ &operator>> (int &v)
{
Read (&v, 4);
v = LittleLong(v);
@ -233,7 +233,7 @@ public:
return *this;
}
FileReaderBZ2 &operator>> (fixed_t &v)
FileReaderBZ2 &operator>> (int &v)
{
Read (&v, 4);
v = LittleLong(v);
@ -297,7 +297,7 @@ public:
return *this;
}
FileReaderLZMA &operator>> (fixed_t &v)
FileReaderLZMA &operator>> (int &v)
{
Read (&v, 4);
v = LittleLong(v);

View file

@ -165,7 +165,7 @@ void FS_EmulateCmd(char * string)
else if (sc.Compare("viewheight"))
{
sc.MustGetFloat();
fixed_t playerviewheight = (fixed_t)(sc.Float*FRACUNIT);
double playerviewheight = sc.Float;
for(int i=0;i<MAXPLAYERS;i++)
{
// No, this is not correct. But this is the way Legacy WADs expect it to be handled!

View file

@ -115,7 +115,7 @@ void DHUDPicManager::DoDraw (int linenum, int x, int y, int hudheight, float tra
{
FTexture * tex = TexMan[piclist[i].texturenum];
if (tex) screen->DrawTexture(tex, piclist[i].xpos, piclist[i].ypos, DTA_320x200, true,
DTA_Alpha, (fixed_t)(translucent*basetrans*FRACUNIT), TAG_DONE);
DTA_AlphaF, translucent*basetrans, TAG_DONE);
}
}

View file

@ -68,13 +68,11 @@
#include "farchive.h"
#include "p_setup.h"
#include "p_spec.h"
#include "r_utility.h"
#include "math/cmath.h"
static FRandom pr_script("FScript");
#define AngleToFixed(x) ((((double) x) / ((double) ANG45/45)) * FRACUNIT)
#define FixedToAngle(x) ((((double) x) / FRACUNIT) * ANG45/45)
// functions. FParser::SF_ means Script Function not, well.. heh, me
/////////// actually running a function /////////////
@ -860,43 +858,43 @@ void FParser::SF_Player(void)
void FParser::SF_Spawn(void)
{
int x, y, z;
DVector3 pos;
PClassActor *pclass;
angle_t angle = 0;
DAngle angle = 0.;
if (CheckArgs(3))
{
if (!(pclass=T_GetMobjType(t_argv[0]))) return;
x = fixedvalue(t_argv[1]);
y = fixedvalue(t_argv[2]);
pos.X = floatvalue(t_argv[1]);
pos.Y = floatvalue(t_argv[2]);
if(t_argc >= 5)
{
z = fixedvalue(t_argv[4]);
pos.Z = floatvalue(t_argv[4]);
// [Graf Zahl] added option of spawning with a relative z coordinate
if(t_argc > 5)
{
if (intvalue(t_argv[5])) z+=P_PointInSector(x, y)->floorplane.ZatPoint(x,y);
if (intvalue(t_argv[5])) pos.Z += P_PointInSector(pos)->floorplane.ZatPoint(pos);
}
}
else
{
// Legacy compatibility is more important than correctness.
z = ONFLOORZ;// (GetDefaultByType(PClass)->flags & MF_SPAWNCEILING) ? ONCEILINGZ : ONFLOORZ;
pos.Z = ONFLOORZ;// (GetDefaultByType(PClass)->flags & MF_SPAWNCEILING) ? ONCEILINGZ : ONFLOORZ;
}
if(t_argc >= 4)
{
angle = intvalue(t_argv[3]) * (SQWORD)ANG45 / 45;
angle = floatvalue(t_argv[3]);
}
t_return.type = svt_mobj;
t_return.value.mobj = Spawn(pclass, x, y, z, ALLOW_REPLACE);
t_return.value.mobj = Spawn(pclass, pos, ALLOW_REPLACE);
if (t_return.value.mobj)
{
t_return.value.mobj->angle = angle;
t_return.value.mobj->Angles.Yaw = angle;
if (!DFraggleThinker::ActiveThinker->nocheckposition)
{
@ -981,8 +979,7 @@ void FParser::SF_ObjX(void)
mo = Script->trigger;
}
t_return.type = svt_fixed; // haleyjd: SoM's fixed-point fix
t_return.value.f = mo ? mo->X() : 0; // null ptr check
t_return.setDouble(mo ? mo->X() : 0.);
}
//==========================================================================
@ -1004,8 +1001,7 @@ void FParser::SF_ObjY(void)
mo = Script->trigger;
}
t_return.type = svt_fixed; // haleyjd
t_return.value.f = mo ? mo->Y() : 0; // null ptr check
t_return.setDouble(mo ? mo->Y() : 0.);
}
//==========================================================================
@ -1027,8 +1023,7 @@ void FParser::SF_ObjZ(void)
mo = Script->trigger;
}
t_return.type = svt_fixed; // haleyjd
t_return.value.f = mo ? mo->Z() : 0; // null ptr check
t_return.setDouble(mo ? mo->Z() : 0.);
}
@ -1051,8 +1046,7 @@ void FParser::SF_ObjAngle(void)
mo = Script->trigger;
}
t_return.type = svt_fixed; // haleyjd: fixed-point -- SoM again :)
t_return.value.f = mo ? (fixed_t)AngleToFixed(mo->angle) : 0; // null ptr check
t_return.setDouble(mo ? mo->Angles.Yaw.Degrees : 0.);
}
@ -1256,10 +1250,9 @@ void FParser::SF_PushThing(void)
AActor * mo = actorvalue(t_argv[0]);
if(!mo) return;
angle_t angle = (angle_t)FixedToAngle(fixedvalue(t_argv[1]));
fixed_t force = fixedvalue(t_argv[2]);
P_ThrustMobj(mo, angle, force);
DAngle angle = floatvalue(t_argv[1]);
double force = floatvalue(t_argv[2]);
mo->Thrust(angle, force);
}
}
@ -1333,11 +1326,10 @@ void FParser::SF_MobjMomx(void)
if(t_argc > 1)
{
if(mo)
mo->vel.x = fixedvalue(t_argv[1]);
mo->Vel.X = floatvalue(t_argv[1]);
}
t_return.type = svt_fixed;
t_return.value.f = mo ? mo->vel.x : 0;
t_return.setDouble(mo ? mo->Vel.X : 0.);
}
}
@ -1356,12 +1348,11 @@ void FParser::SF_MobjMomy(void)
mo = actorvalue(t_argv[0]);
if(t_argc > 1)
{
if(mo)
mo->vel.y = fixedvalue(t_argv[1]);
if(mo)
mo->Vel.Y = floatvalue(t_argv[1]);
}
t_return.type = svt_fixed;
t_return.value.f = mo ? mo->vel.y : 0;
t_return.setDouble(mo ? mo->Vel.Y : 0.);
}
}
@ -1378,14 +1369,13 @@ void FParser::SF_MobjMomz(void)
if (CheckArgs(1))
{
mo = actorvalue(t_argv[0]);
if(t_argc > 1)
if (t_argc > 1)
{
if(mo)
mo->vel.z = fixedvalue(t_argv[1]);
if (mo)
mo->Vel.Z = floatvalue(t_argv[1]);
}
t_return.type = svt_fixed;
t_return.value.f = mo ? mo->vel.z : 0;
t_return.setDouble(mo ? mo->Vel.Z : 0.);
}
}
@ -1402,15 +1392,12 @@ void FParser::SF_PointToAngle(void)
{
if (CheckArgs(4))
{
fixed_t x1 = fixedvalue(t_argv[0]);
fixed_t y1 = fixedvalue(t_argv[1]);
fixed_t x2 = fixedvalue(t_argv[2]);
fixed_t y2 = fixedvalue(t_argv[3]);
double x1 = floatvalue(t_argv[0]);
double y1 = floatvalue(t_argv[1]);
double x2 = floatvalue(t_argv[2]);
double y2 = floatvalue(t_argv[3]);
angle_t angle = R_PointToAngle2(x1, y1, x2, y2);
t_return.type = svt_fixed;
t_return.value.f = (fixed_t)AngleToFixed(angle);
t_return.setDouble(DVector2(x2 - x1, y2 - y1).Angle().Normalized360().Degrees);
}
}
@ -1428,9 +1415,7 @@ void FParser::SF_PointToDist(void)
// Doing this in floating point is actually faster with modern computers!
double x = floatvalue(t_argv[2]) - floatvalue(t_argv[0]);
double y = floatvalue(t_argv[3]) - floatvalue(t_argv[1]);
t_return.type = svt_fixed;
t_return.value.f = FLOAT2FIXED(sqrt(x*x+y*y));
t_return.setDouble(g_sqrt(x*x+y*y));
}
}
@ -1447,7 +1432,7 @@ void FParser::SF_PointToDist(void)
void FParser::SF_SetCamera(void)
{
angle_t angle;
DAngle angle;
player_t * player;
AActor * newcamera;
@ -1463,21 +1448,16 @@ void FParser::SF_SetCamera(void)
return; // nullptr check
}
angle = t_argc < 2 ? newcamera->angle : (fixed_t)FixedToAngle(fixedvalue(t_argv[1]));
angle = t_argc < 2 ? newcamera->Angles.Yaw : floatvalue(t_argv[1]);
newcamera->special1=newcamera->angle;
newcamera->special2=newcamera->Z();
newcamera->SetZ(t_argc < 3 ? (newcamera->Z() + (41 << FRACBITS)) : (intvalue(t_argv[2]) << FRACBITS));
newcamera->angle = angle;
if(t_argc < 4) newcamera->pitch = 0;
else
{
fixed_t pitch = fixedvalue(t_argv[3]);
if (pitch < -50 * FRACUNIT) pitch = -50 * FRACUNIT;
if (pitch > 50 * FRACUNIT) pitch = 50 * FRACUNIT;
newcamera->pitch = xs_CRoundToUInt((pitch / 65536.0f)*(ANGLE_45 / 45.0f)*(20.0f / 32.0f));
}
newcamera->specialf1 = newcamera->Angles.Yaw.Degrees;
newcamera->specialf2 = newcamera->Z();
newcamera->SetZ(t_argc < 3 ? newcamera->Z() + 41 : floatvalue(t_argv[2]));
newcamera->Angles.Yaw = angle;
if (t_argc < 4) newcamera->Angles.Pitch = 0.;
else newcamera->Angles.Pitch = clamp(floatvalue(t_argv[3]), -50., 50.) * (20. / 32.);
player->camera=newcamera;
R_ResetViewInterpolation();
}
}
@ -1497,8 +1477,8 @@ void FParser::SF_ClearCamera(void)
if (cam)
{
player->camera=player->mo;
cam->angle=cam->special1;
cam->SetZ(cam->special2);
cam->Angles.Yaw = cam->specialf1;
cam->SetZ(cam->specialf2);
}
}
@ -1557,16 +1537,13 @@ void FParser::SF_StartSectorSound(void)
/************* Sector functions ***************/
//DMover::EResult P_MoveFloor (sector_t * m_Sector, fixed_t speed, fixed_t dest, int crush, int direction, int flags=0);
//DMover::EResult P_MoveCeiling (sector_t * m_Sector, fixed_t speed, fixed_t dest, int crush, int direction, int flags=0);
class DFloorChanger : public DFloor
{
public:
DFloorChanger(sector_t * sec)
: DFloor(sec) {}
bool Move(fixed_t speed, fixed_t dest, int crush, int direction)
bool Move(double speed, double dest, int crush, int direction)
{
bool res = DMover::crushed != MoveFloor(speed, dest, crush, direction, false);
Destroy();
@ -1589,8 +1566,8 @@ void FParser::SF_FloorHeight(void)
{
int tagnum;
int secnum;
fixed_t dest;
int returnval = 1; // haleyjd: SoM's fixes
double dest;
double returnval = 1; // haleyjd: SoM's fixes
if (CheckArgs(1))
{
@ -1602,7 +1579,7 @@ void FParser::SF_FloorHeight(void)
int crush = (t_argc >= 3) ? intvalue(t_argv[2]) : false;
i = -1;
dest = fixedvalue(t_argv[1]);
dest = floatvalue(t_argv[1]);
// set all sectors with tag
@ -1613,7 +1590,7 @@ void FParser::SF_FloorHeight(void)
DFloorChanger * f = new DFloorChanger(&sectors[i]);
if (!f->Move(
abs(dest - sectors[i].CenterFloor()),
fabs(dest - sectors[i].CenterFloor()),
sectors[i].floorplane.PointToDist (sectors[i].centerspot, dest),
crush? 10:-1,
(dest > sectors[i].CenterFloor()) ? 1 : -1))
@ -1630,13 +1607,11 @@ void FParser::SF_FloorHeight(void)
script_error("sector not found with tagnum %i\n", tagnum);
return;
}
returnval = sectors[secnum].CenterFloor() >> FRACBITS;
returnval = sectors[secnum].CenterFloor();
}
// return floor height
t_return.type = svt_int;
t_return.value.i = returnval;
t_return.setDouble(returnval);
}
}
@ -1648,7 +1623,7 @@ void FParser::SF_FloorHeight(void)
class DMoveFloor : public DFloor
{
public:
DMoveFloor(sector_t * sec,int moveheight,int _m_Direction,int crush,int movespeed)
DMoveFloor(sector_t * sec,double moveheight,int _m_Direction,int crush,double movespeed)
: DFloor(sec)
{
m_Type = floorRaiseByValue;
@ -1658,7 +1633,7 @@ public:
m_FloorDestDist = moveheight;
// Do not interpolate instant movement floors.
fixed_t movedist = abs(-sec->floorplane.d - moveheight);
double movedist = fabs(-sec->floorplane.fD() - moveheight);
if (m_Speed >= movedist)
{
StopInterpolation(true);
@ -1680,13 +1655,14 @@ void FParser::SF_MoveFloor(void)
{
int secnum = -1;
sector_t *sec;
int tagnum, platspeed = 1, destheight, crush;
int tagnum, crush;
double platspeed = 1, destheight;
if (CheckArgs(2))
{
tagnum = intvalue(t_argv[0]);
destheight = intvalue(t_argv[1]) * FRACUNIT;
platspeed = t_argc > 2 ? fixedvalue(t_argv[2]) : FRACUNIT;
destheight = intvalue(t_argv[1]);
platspeed = t_argc > 2 ? floatvalue(t_argv[2]) : 1.;
crush = (t_argc > 3 ? intvalue(t_argv[3]) : -1);
// move all sectors with tag
@ -1698,8 +1674,8 @@ void FParser::SF_MoveFloor(void)
// Don't start a second thinker on the same floor
if (sec->floordata) continue;
new DMoveFloor(sec,sec->floorplane.PointToDist(sec->centerspot,destheight),
destheight < sec->CenterFloor() ? -1:1,crush,platspeed);
new DMoveFloor(sec, sec->floorplane.PointToDist(sec->centerspot, destheight),
destheight < sec->CenterFloor() ? -1 : 1, crush, platspeed);
}
}
}
@ -1716,7 +1692,7 @@ public:
DCeilingChanger(sector_t * sec)
: DCeiling(sec) {}
bool Move(fixed_t speed, fixed_t dest, int crush, int direction)
bool Move(double speed, double dest, int crush, int direction)
{
bool res = DMover::crushed != MoveCeiling(speed, dest, crush, direction, false);
Destroy();
@ -1736,10 +1712,10 @@ public:
// ceiling height of sector
void FParser::SF_CeilingHeight(void)
{
fixed_t dest;
double dest;
int secnum;
int tagnum;
int returnval = 1;
double returnval = 1;
if (CheckArgs(1))
{
@ -1751,7 +1727,7 @@ void FParser::SF_CeilingHeight(void)
int crush = (t_argc >= 3) ? intvalue(t_argv[2]) : false;
i = -1;
dest = fixedvalue(t_argv[1]);
dest = floatvalue(t_argv[1]);
// set all sectors with tag
FSSectorTagIterator itr(tagnum);
@ -1761,7 +1737,7 @@ void FParser::SF_CeilingHeight(void)
DCeilingChanger * c = new DCeilingChanger(&sectors[i]);
if (!c->Move(
abs(dest - sectors[i].CenterCeiling()),
fabs(dest - sectors[i].CenterCeiling()),
sectors[i].ceilingplane.PointToDist (sectors[i].centerspot, dest),
crush? 10:-1,
(dest > sectors[i].CenterCeiling()) ? 1 : -1))
@ -1778,12 +1754,11 @@ void FParser::SF_CeilingHeight(void)
script_error("sector not found with tagnum %i\n", tagnum);
return;
}
returnval = sectors[secnum].CenterCeiling() >> FRACBITS;
returnval = sectors[secnum].CenterCeiling();
}
// return ceiling height
t_return.type = svt_int;
t_return.value.i = returnval;
t_return.setDouble(returnval);
}
}
@ -1798,7 +1773,7 @@ class DMoveCeiling : public DCeiling
{
public:
DMoveCeiling(sector_t * sec,int tag,fixed_t destheight,fixed_t speed,int silent,int crush)
DMoveCeiling(sector_t * sec,int tag,double destheight,double speed,int silent,int crush)
: DCeiling(sec)
{
m_Crush = crush;
@ -1807,10 +1782,10 @@ public:
m_Type = DCeiling::ceilLowerByValue; // doesn't really matter as long as it's no special value
m_Tag=tag;
m_TopHeight=m_BottomHeight=sec->ceilingplane.PointToDist(sec->centerspot,destheight);
m_Direction=destheight>sec->GetPlaneTexZ(sector_t::ceiling)? 1:-1;
m_Direction=destheight>sec->GetPlaneTexZF(sector_t::ceiling)? 1:-1;
// Do not interpolate instant movement ceilings.
fixed_t movedist = abs(sec->ceilingplane.d - m_BottomHeight);
double movedist = fabs(sec->ceilingplane.fD() - m_BottomHeight);
if (m_Speed >= movedist)
{
StopInterpolation (true);
@ -1831,15 +1806,16 @@ void FParser::SF_MoveCeiling(void)
{
int secnum = -1;
sector_t *sec;
int tagnum, platspeed = 1, destheight;
int tagnum;
double platspeed = 1, destheight;
int crush;
int silent;
if (CheckArgs(2))
{
tagnum = intvalue(t_argv[0]);
destheight = intvalue(t_argv[1]) * FRACUNIT;
platspeed = /*FLOORSPEED **/ (t_argc > 2 ? fixedvalue(t_argv[2]) : FRACUNIT);
destheight = intvalue(t_argv[1]);
platspeed = /*FLOORSPEED **/ (t_argc > 2 ? floatvalue(t_argv[2]) : 1);
crush=t_argc>3 ? intvalue(t_argv[3]):-1;
silent=t_argc>4 ? intvalue(t_argv[4]):1;
@ -2190,7 +2166,7 @@ void FParser::SF_OpenDoor(void)
if(t_argc > 2) speed = intvalue(t_argv[2]);
else speed = 1; // 1= normal speed
EV_DoDoor(wait_time? DDoor::doorRaise:DDoor::doorOpen,NULL,NULL,sectag,2*FRACUNIT*clamp(speed,1,127),wait_time,0,0);
EV_DoDoor(wait_time ? DDoor::doorRaise : DDoor::doorOpen, NULL, NULL, sectag, 2. * clamp(speed, 1, 127), wait_time, 0, 0);
}
}
@ -2215,7 +2191,7 @@ void FParser::SF_CloseDoor(void)
if(t_argc > 1) speed = intvalue(t_argv[1]);
else speed = 1; // 1= normal speed
EV_DoDoor(DDoor::doorClose,NULL,NULL,sectag,2*FRACUNIT*clamp(speed,1,127),0,0,0);
EV_DoDoor(DDoor::doorClose, NULL, NULL, sectag, 2.*clamp(speed, 1, 127), 0, 0, 0);
}
}
@ -2429,12 +2405,10 @@ void FParser::SF_SetLineTexture(void)
void FParser::SF_Max(void)
{
fixed_t n1, n2;
if (CheckArgs(2))
{
n1 = fixedvalue(t_argv[0]);
n2 = fixedvalue(t_argv[1]);
auto n1 = fixedvalue(t_argv[0]);
auto n2 = fixedvalue(t_argv[1]);
t_return.type = svt_fixed;
t_return.value.f = (n1 > n2) ? n1 : n2;
@ -2450,12 +2424,10 @@ void FParser::SF_Max(void)
void FParser::SF_Min(void)
{
fixed_t n1, n2;
if (CheckArgs(1))
{
n1 = fixedvalue(t_argv[0]);
n2 = fixedvalue(t_argv[1]);
auto n1 = fixedvalue(t_argv[0]);
auto n2 = fixedvalue(t_argv[1]);
t_return.type = svt_fixed;
t_return.value.f = (n1 < n2) ? n1 : n2;
@ -2471,11 +2443,10 @@ void FParser::SF_Min(void)
void FParser::SF_Abs(void)
{
fixed_t n1;
if (CheckArgs(1))
{
n1 = fixedvalue(t_argv[0]);
auto n1 = fixedvalue(t_argv[0]);
t_return.type = svt_fixed;
t_return.value.f = (n1 < 0) ? -n1 : n1;
@ -2587,7 +2558,7 @@ static void FS_GiveInventory (AActor *actor, const char * type, int amount)
AWeapon *savedPendingWeap = actor->player != NULL? actor->player->PendingWeapon : NULL;
bool hadweap = actor->player != NULL ? actor->player->ReadyWeapon != NULL : true;
AInventory *item = static_cast<AInventory *>(Spawn (info, 0,0,0, NO_REPLACE));
AInventory *item = static_cast<AInventory *>(Spawn (info));
// This shouldn't count for the item statistics!
item->ClearCounters();
@ -2795,7 +2766,7 @@ void FParser::SF_MaxPlayerAmmo()
if(amount < 0) amount = 0;
if (!iammo)
{
iammo = static_cast<AAmmo *>(Spawn (ammotype, 0, 0, 0, NO_REPLACE));
iammo = static_cast<AAmmo *>(Spawn (ammotype));
iammo->Amount = 0;
iammo->AttachToOwner (players[playernum].mo);
}
@ -3067,166 +3038,57 @@ void FParser::SF_SetWeapon()
//
// movecamera(camera, targetobj, targetheight, movespeed, targetangle, anglespeed)
//
// This has been completely rewritten in a sane fashion, using actual vector math.
//
//==========================================================================
void FParser::SF_MoveCamera(void)
{
fixed_t x, y, z;
fixed_t zdist, xydist, movespeed;
fixed_t xstep, ystep, zstep, targetheight;
angle_t anglespeed, anglestep, angledist, targetangle,
mobjangle, bigangle, smallangle;
// I have to use floats for the math where angles are divided
// by fixed values.
double fangledist, fanglestep, fmovestep;
int angledir;
AActor* target;
int moved;
int quad1, quad2;
AActor * cam;
angledir = moved = 0;
if (CheckArgs(6))
{
cam = actorvalue(t_argv[0]);
target = actorvalue(t_argv[1]);
if(!cam || !target)
AActor *cam = actorvalue(t_argv[0]);
AActor *target = actorvalue(t_argv[1]);
if(!cam || !target)
{
script_error("invalid target for camera\n"); return;
}
targetheight = fixedvalue(t_argv[2]);
movespeed = fixedvalue(t_argv[3]);
targetangle = (angle_t)FixedToAngle(fixedvalue(t_argv[4]));
anglespeed = (angle_t)FixedToAngle(fixedvalue(t_argv[5]));
// figure out how big one step will be
fixedvec2 dist = cam->Vec2To(target);
zdist = targetheight - cam->Z();
// Angle checking...
// 90
// Q1|Q0
//180--+--0
// Q2|Q3
// 270
quad1 = targetangle / ANG90;
quad2 = cam->angle / ANG90;
bigangle = targetangle > cam->angle ? targetangle : cam->angle;
smallangle = targetangle < cam->angle ? targetangle : cam->angle;
if((quad1 > quad2 && quad1 - 1 == quad2) || (quad2 > quad1 && quad2 - 1 == quad1) ||
quad1 == quad2)
double targetheight = floatvalue(t_argv[2]);
DVector3 campos = cam->Pos();
DVector3 targpos = DVector3(target->Pos(), targetheight);
if (campos != targpos)
{
angledist = bigangle - smallangle;
angledir = targetangle > cam->angle ? 1 : -1;
}
else
{
angle_t diff180 = (bigangle + ANG180) - (smallangle + ANG180);
if(quad2 == 3 && quad1 == 0)
DVector3 movement = targpos - campos;
double movelen = movement.Length();
double movespeed = floatvalue(t_argv[3]);
DVector3 movepos;
bool finished = (movespeed >= movelen);
if (finished) movepos = targpos;
else movepos = campos + movement.Resized(movespeed);
DAngle targetangle = floatvalue(t_argv[4]);
DAngle anglespeed = floatvalue(t_argv[5]);
DAngle diffangle = deltaangle(cam->Angles.Yaw, targetangle);
if (movespeed > 0 && anglespeed == 0.)
{
angledist = diff180;
angledir = 1;
}
else if(quad1 == 3 && quad2 == 0)
{
angledist = diff180;
angledir = -1;
if (!finished) targetangle = diffangle * movespeed / movelen;
}
else
{
angledist = bigangle - smallangle;
if(angledist > ANG180)
{
angledist = diff180;
angledir = targetangle > cam->angle ? -1 : 1;
}
else
angledir = targetangle > cam->angle ? 1 : -1;
targetangle = cam->Angles.Yaw + anglespeed;
}
}
// set step variables based on distance and speed
mobjangle = cam->AngleTo(target);
xydist = cam->Distance2D(target);
xstep = FixedMul(finecosine[mobjangle >> ANGLETOFINESHIFT], movespeed);
ystep = FixedMul(finesine[mobjangle >> ANGLETOFINESHIFT], movespeed);
if(xydist && movespeed)
zstep = FixedDiv(zdist, FixedDiv(xydist, movespeed));
else
zstep = zdist > 0 ? movespeed : -movespeed;
if(xydist && movespeed && !anglespeed)
{
fangledist = ((double)angledist / (ANG45/45));
fmovestep = ((double)FixedDiv(xydist, movespeed) / FRACUNIT);
if(fmovestep)
fanglestep = fangledist / fmovestep;
else
fanglestep = 360;
anglestep =(angle_t) (fanglestep * (ANG45/45));
}
else
anglestep = anglespeed;
if(abs(xstep) >= (abs(dist.x) - 1))
x = cam->X() + dist.x;
else
{
x = cam->X() + xstep;
moved = 1;
}
if(abs(ystep) >= (abs(dist.y) - 1))
y = cam->Y() + dist.y;
else
{
y = cam->Y() + ystep;
moved = 1;
}
if(abs(zstep) >= (abs(zdist) - 1))
z = targetheight;
else
{
z = cam->Z() + zstep;
moved = 1;
}
if(anglestep >= angledist)
cam->angle = targetangle;
else
{
if(angledir == 1)
{
cam->angle += anglestep;
moved = 1;
}
else if(angledir == -1)
{
cam->angle -= anglestep;
moved = 1;
}
}
cam->radius=8;
cam->height=8;
if ((x != cam->X() || y != cam->Y()) && !P_TryMove(cam, x, y, true))
{
Printf("Illegal camera move to (%f, %f)\n", x/65536.f, y/65536.f);
return;
cam->radius = 1 / 8192.;
cam->Height = 1 / 8192.;
cam->SetOrigin(movepos, true);
t_return.value.i = 1;
}
else
{
t_return.value.i = 0;
}
cam->SetZ(z);
t_return.type = svt_int;
t_return.value.i = moved;
}
}
@ -3348,7 +3210,7 @@ void FParser::SF_FixedValue(void)
void FParser::SF_SpawnExplosion()
{
fixed_t x, y, z;
DVector3 pos;
AActor* spawn;
PClassActor * pclass;
@ -3356,14 +3218,14 @@ void FParser::SF_SpawnExplosion()
{
if (!(pclass=T_GetMobjType(t_argv[0]))) return;
x = fixedvalue(t_argv[1]);
y = fixedvalue(t_argv[2]);
pos.X = floatvalue(t_argv[1]);
pos.Y = floatvalue(t_argv[2]);
if(t_argc > 3)
z = fixedvalue(t_argv[3]);
pos.Z = floatvalue(t_argv[3]);
else
z = P_PointInSector(x, y)->floorplane.ZatPoint(x,y);
pos.Z = P_PointInSector(pos)->floorplane.ZatPoint(pos);
spawn = Spawn (pclass, x, y, z, ALLOW_REPLACE);
spawn = Spawn (pclass, pos, ALLOW_REPLACE);
t_return.type = svt_int;
t_return.value.i=0;
if (spawn)
@ -3417,9 +3279,9 @@ void FParser::SF_SetObjPosition()
if (!mobj) return;
mobj->SetOrigin(
fixedvalue(t_argv[1]),
(t_argc >= 3)? fixedvalue(t_argv[2]) : mobj->Y(),
(t_argc >= 4)? fixedvalue(t_argv[3]) : mobj->Z(), false);
floatvalue(t_argv[1]),
(t_argc >= 3)? floatvalue(t_argv[2]) : mobj->Y(),
(t_argc >= 4)? floatvalue(t_argv[3]) : mobj->Z(), false);
}
}
@ -3750,7 +3612,7 @@ void FParser::SF_Resurrect()
return;
mo->SetState(state);
mo->height = mo->GetDefault()->height;
mo->Height = mo->GetDefault()->Height;
mo->radius = mo->GetDefault()->radius;
mo->flags = mo->GetDefault()->flags;
mo->flags2 = mo->GetDefault()->flags2;
@ -3771,14 +3633,15 @@ void FParser::SF_Resurrect()
void FParser::SF_LineAttack()
{
AActor *mo;
int damage, angle, slope;
int damage;
DAngle angle, slope;
if (CheckArgs(3))
{
mo = actorvalue(t_argv[0]);
damage = intvalue(t_argv[2]);
angle = (intvalue(t_argv[1]) * (ANG45 / 45));
angle = floatvalue(t_argv[1]);
slope = P_AimLineAttack(mo, angle, MISSILERANGE);
P_LineAttack(mo, angle, MISSILERANGE, slope, damage, NAME_Hitscan, NAME_BulletPuff);
@ -3828,8 +3691,7 @@ void FParser::SF_Sin()
{
if (CheckArgs(1))
{
t_return.type = svt_fixed;
t_return.value.f = FLOAT2FIXED(sin(floatvalue(t_argv[0])));
t_return.setDouble(g_sin(floatvalue(t_argv[0])));
}
}
@ -3838,8 +3700,7 @@ void FParser::SF_ASin()
{
if (CheckArgs(1))
{
t_return.type = svt_fixed;
t_return.value.f = FLOAT2FIXED(asin(floatvalue(t_argv[0])));
t_return.setDouble(g_asin(floatvalue(t_argv[0])));
}
}
@ -3848,8 +3709,7 @@ void FParser::SF_Cos()
{
if (CheckArgs(1))
{
t_return.type = svt_fixed;
t_return.value.f = FLOAT2FIXED(cos(floatvalue(t_argv[0])));
t_return.setDouble(g_cos(floatvalue(t_argv[0])));
}
}
@ -3858,8 +3718,7 @@ void FParser::SF_ACos()
{
if (CheckArgs(1))
{
t_return.type = svt_fixed;
t_return.value.f = FLOAT2FIXED(acos(floatvalue(t_argv[0])));
t_return.setDouble(g_acos(floatvalue(t_argv[0])));
}
}
@ -3868,8 +3727,7 @@ void FParser::SF_Tan()
{
if (CheckArgs(1))
{
t_return.type = svt_fixed;
t_return.value.f = FLOAT2FIXED(tan(floatvalue(t_argv[0])));
t_return.setDouble(g_tan(floatvalue(t_argv[0])));
}
}
@ -3878,8 +3736,7 @@ void FParser::SF_ATan()
{
if (CheckArgs(1))
{
t_return.type = svt_fixed;
t_return.value.f = FLOAT2FIXED(atan(floatvalue(t_argv[0])));
t_return.setDouble(g_atan(floatvalue(t_argv[0])));
}
}
@ -3888,8 +3745,7 @@ void FParser::SF_Exp()
{
if (CheckArgs(1))
{
t_return.type = svt_fixed;
t_return.value.f = FLOAT2FIXED(exp(floatvalue(t_argv[0])));
t_return.setDouble(g_exp(floatvalue(t_argv[0])));
}
}
@ -3897,8 +3753,7 @@ void FParser::SF_Log()
{
if (CheckArgs(1))
{
t_return.type = svt_fixed;
t_return.value.f = FLOAT2FIXED(log(floatvalue(t_argv[0])));
t_return.setDouble(g_log(floatvalue(t_argv[0])));
}
}
@ -3907,8 +3762,7 @@ void FParser::SF_Sqrt()
{
if (CheckArgs(1))
{
t_return.type = svt_fixed;
t_return.value.f = FLOAT2FIXED(sqrt(floatvalue(t_argv[0])));
t_return.setDouble(g_sqrt(floatvalue(t_argv[0])));
}
}
@ -3918,7 +3772,7 @@ void FParser::SF_Floor()
if (CheckArgs(1))
{
t_return.type = svt_fixed;
t_return.value.f = fixedvalue(t_argv[0]) & 0xffFF0000;
t_return.value.f = fixedvalue(t_argv[0]) & 0xffff0000;
}
}
@ -3927,8 +3781,7 @@ void FParser::SF_Pow()
{
if (CheckArgs(2))
{
t_return.type = svt_fixed;
t_return.value.f = FLOAT2FIXED(pow(floatvalue(t_argv[0]), floatvalue(t_argv[1])));
t_return.setDouble(pow(floatvalue(t_argv[0]), floatvalue(t_argv[1])));
}
}
@ -4008,10 +3861,9 @@ void FParser::SF_SetCorona(void)
return;
}
int num = t_argv[0].value.i; // which corona we want to modify
int what = t_argv[1].value.i; // what we want to modify (type, color, offset,...)
int ival = t_argv[2].value.i; // the value of what we modify
double fval = ((double) t_argv[2].value.f / FRACUNIT);
int num = intvalue(t_argv[0]); // which corona we want to modify
int what = intvalue(t_argv[1]); // what we want to modify (type, color, offset,...)
double val = floatvalue(t_argv[2]); // the value of what we modify
/*
switch (what)
@ -4042,7 +3894,7 @@ void FParser::SF_SetCorona(void)
break;
case 6:
lspr[num].dynamic_radius = fval;
lspr[num].dynamic_sqrradius = sqrt(lspr[num].dynamic_radius);
lspr[num].dynamic_sqrradius = g_sqrt(lspr[num].dynamic_radius);
break;
default:
CONS_Printf("Error in setcorona\n");
@ -4108,11 +3960,9 @@ void FParser::SF_MobjRadius(void)
if(t_argc > 1)
{
if(mo)
mo->radius = fixedvalue(t_argv[1]);
mo->radius = floatvalue(t_argv[1]);
}
t_return.type = svt_fixed;
t_return.value.f = mo ? mo->radius : 0;
t_return.setDouble(mo ? mo->radius : 0.);
}
}
@ -4133,11 +3983,9 @@ void FParser::SF_MobjHeight(void)
if(t_argc > 1)
{
if(mo)
mo->height = fixedvalue(t_argv[1]);
mo->Height = floatvalue(t_argv[1]);
}
t_return.type = svt_fixed;
t_return.value.f = mo ? mo->height : 0;
t_return.setDouble(mo ? mo->Height : 0.);
}
}
@ -4260,33 +4108,34 @@ void FParser::SF_SpawnShot2(void)
{
AActor *source = NULL;
PClassActor * pclass;
int z=0;
double z = 0;
// t_argv[0] = type to spawn
// t_argv[1] = source mobj, optional, -1 to default
// shoots at source's angle
if (CheckArgs(2))
{
if(t_argv[1].type == svt_int && t_argv[1].value.i < 0)
if (t_argv[1].type == svt_int && t_argv[1].value.i < 0)
source = Script->trigger;
else
source = actorvalue(t_argv[1]);
if (t_argc>2) z=fixedvalue(t_argv[2]);
if(!source) return;
if (!(pclass=T_GetMobjType(t_argv[0]))) return;
if (t_argc > 2) z = floatvalue(t_argv[2]);
if (!source) return;
if (!(pclass = T_GetMobjType(t_argv[0]))) return;
t_return.type = svt_mobj;
AActor *mo = Spawn (pclass, source->PosPlusZ(z), ALLOW_REPLACE);
if (mo)
AActor *mo = Spawn(pclass, source->PosPlusZ(z), ALLOW_REPLACE);
if (mo)
{
S_Sound (mo, CHAN_VOICE, mo->SeeSound, 1, ATTN_NORM);
S_Sound(mo, CHAN_VOICE, mo->SeeSound, 1, ATTN_NORM);
mo->target = source;
P_ThrustMobj(mo, mo->angle = source->angle, mo->Speed);
mo->Angles.Yaw = source->Angles.Yaw;
mo->Thrust();
if (!P_CheckMissileSpawn(mo, source->radius)) mo = NULL;
}
t_return.value.mobj = mo;

View file

@ -360,8 +360,7 @@ void FParser::OPmultiply(svalue_t &result,int start, int n, int stop)
// haleyjd: 8-17
if(left.type == svt_fixed || right.type == svt_fixed)
{
result.type = svt_fixed;
result.value.f = FixedMul(fixedvalue(left), fixedvalue(right));
result.setDouble(floatvalue(left) * floatvalue(right));
}
else
{
@ -385,21 +384,20 @@ void FParser::OPdivide(svalue_t &result, int start, int n, int stop)
// haleyjd: 8-17
if(left.type == svt_fixed || right.type == svt_fixed)
{
fixed_t fr;
auto fr = floatvalue(right);
if((fr = fixedvalue(right)) == 0)
if(fr == 0)
script_error("divide by zero\n");
else
{
result.type = svt_fixed;
result.value.f = FixedDiv(fixedvalue(left), fr);
result.setDouble(floatvalue(left) / fr);
}
}
else
{
int ir;
auto ir = intvalue(right);
if(!(ir = intvalue(right)))
if(!ir)
script_error("divide by zero\n");
else
{
@ -509,8 +507,7 @@ void FParser::OPincrement(svalue_t &result, int start, int n, int stop)
}
else
{
result.value.f = fixedvalue(result) + FRACUNIT;
result.type = svt_fixed;
result.setDouble(floatvalue(result)+1);
var->SetValue (result);
}
}
@ -535,8 +532,7 @@ void FParser::OPincrement(svalue_t &result, int start, int n, int stop)
}
else
{
newvalue.type = svt_fixed;
newvalue.value.f = fixedvalue(result) + FRACUNIT;
newvalue.setDouble(floatvalue(result)+1);
var->SetValue (newvalue);
}
}
@ -574,7 +570,7 @@ void FParser::OPdecrement(svalue_t &result, int start, int n, int stop)
}
else
{
result.value.f = fixedvalue(result) - FRACUNIT;
result.setDouble(floatvalue(result)-1);
result.type = svt_fixed;
var->SetValue (result);
}
@ -600,8 +596,7 @@ void FParser::OPdecrement(svalue_t &result, int start, int n, int stop)
}
else
{
newvalue.type = svt_fixed;
newvalue.value.f = fixedvalue(result) - FRACUNIT;
newvalue.setDouble(floatvalue(result)-1);
var->SetValue (newvalue);
}
}

View file

@ -567,8 +567,7 @@ void FParser::SimpleEvaluate(svalue_t &returnvar, int n)
case number:
if(strchr(Tokens[n], '.'))
{
returnvar.type = svt_fixed;
returnvar.value.f = (fixed_t)(atof(Tokens[n]) * FRACUNIT);
returnvar.setDouble(atof(Tokens[n]));
}
else
{

View file

@ -82,15 +82,17 @@ enum
//
//
//==========================================================================
typedef int fsfix;
struct svalue_t
{
int type;
FString string;
union
{
int i;
fixed_t f; // haleyjd: 8-17
fsfix f; // haleyjd: 8-17
AActor *mobj;
} value;
@ -106,10 +108,28 @@ struct svalue_t
string = other.string;
value = other.value;
}
void setInt(int ip)
{
value.i = ip;
type = svt_int;
}
void setFixed(fsfix fp)
{
value.f = fp;
type = svt_fixed;
}
void setDouble(double dp)
{
value.f = fsfix(dp/65536);
type = svt_fixed;
}
};
int intvalue(const svalue_t & v);
fixed_t fixedvalue(const svalue_t & v);
fsfix fixedvalue(const svalue_t & v);
double floatvalue(const svalue_t & v);
const char *stringvalue(const svalue_t & v);
AActor *actorvalue(const svalue_t &svalue);
@ -153,7 +173,7 @@ public:
union value_t
{
SDWORD i;
fixed_t fixed; // haleyjd: fixed-point
fsfix fixed; // haleyjd: fixed-point
// the following are only used in the global script so we don't need to bother with them
// when serializing variables.

View file

@ -66,7 +66,7 @@
int intvalue(const svalue_t &v)
{
return (v.type == svt_string ? atoi(v.string) :
v.type == svt_fixed ? (int)(v.value.f / FRACUNIT) :
v.type == svt_fixed ? (int)(v.value.f / 65536.) :
v.type == svt_mobj ? -1 : v.value.i );
}
@ -76,11 +76,11 @@ int intvalue(const svalue_t &v)
//
//==========================================================================
fixed_t fixedvalue(const svalue_t &v)
fsfix fixedvalue(const svalue_t &v)
{
return (v.type == svt_fixed ? v.value.f :
v.type == svt_string ? (fixed_t)(atof(v.string) * FRACUNIT) :
v.type == svt_mobj ? -1*FRACUNIT : v.value.i * FRACUNIT );
v.type == svt_string ? (fsfix)(atof(v.string) * 65536.) :
v.type == svt_mobj ? -65536 : v.value.i * 65536 );
}
//==========================================================================
@ -93,7 +93,7 @@ double floatvalue(const svalue_t &v)
{
return
v.type == svt_string ? atof(v.string) :
v.type == svt_fixed ? FIXED2DBL(v.value.f) :
v.type == svt_fixed ? v.value.f * 65536. :
v.type == svt_mobj ? -1. : (double)v.value.i;
}
@ -118,7 +118,7 @@ const char *stringvalue(const svalue_t & v)
case svt_fixed:
{
double val = ((double)v.value.f) / FRACUNIT;
double val = v.value.f / 65536.;
mysnprintf(buffer, countof(buffer), "%g", val);
return buffer;
}

View file

@ -13,7 +13,7 @@
// PIT_VileCheck
// Detect a corpse that could be raised.
//
void A_Fire(AActor *self, int height);
void A_Fire(AActor *self, double height);
//
@ -50,13 +50,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireCrackle)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Fire)
{
PARAM_ACTION_PROLOGUE;
PARAM_FIXED_OPT(height) { height = 0; }
PARAM_FLOAT_OPT(height) { height = 0; }
A_Fire(self, height);
return 0;
}
void A_Fire(AActor *self, int height)
void A_Fire(AActor *self, double height)
{
AActor *dest;
@ -68,7 +68,7 @@ void A_Fire(AActor *self, int height)
if (!P_CheckSight (self->target, dest, 0) )
return;
fixedvec3 newpos = dest->Vec3Angle(24 * FRACUNIT, dest->angle, height);
DVector3 newpos = dest->Vec3Angle(24., dest->Angles.Yaw, height);
self->SetOrigin(newpos, true);
}
@ -116,7 +116,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_VileAttack)
PARAM_INT_OPT (dmg) { dmg = 20; }
PARAM_INT_OPT (blastdmg) { blastdmg = 70; }
PARAM_INT_OPT (blastrad) { blastrad = 70; }
PARAM_FIXED_OPT (thrust) { thrust = FRACUNIT; }
PARAM_FLOAT_OPT (thrust) { thrust = 1; }
PARAM_NAME_OPT (dmgtype) { dmgtype = NAME_Fire; }
PARAM_INT_OPT (flags) { flags = 0; }
@ -147,14 +147,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_VileAttack)
if (fire != NULL)
{
// move the fire between the vile and the player
fixedvec3 pos = target->Vec3Angle(-24 * FRACUNIT, self->angle, 0);
DVector3 pos = target->Vec3Angle(-24., self->Angles.Yaw, 0);
fire->SetOrigin (pos, true);
P_RadiusAttack (fire, self, blastdmg, blastrad, dmgtype, 0);
}
if (!(target->flags7 & MF7_DONTTHRUST))
{
target->vel.z = Scale(thrust, 1000, target->Mass);
target->Vel.Z = thrust * 1000 / MAX(1, target->Mass);
}
return 0;
}

View file

@ -31,13 +31,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_BrainPain)
return 0;
}
static void BrainishExplosion (fixed_t x, fixed_t y, fixed_t z)
static void BrainishExplosion (const DVector3 &pos)
{
AActor *boom = Spawn("Rocket", x, y, z, NO_REPLACE);
AActor *boom = Spawn("Rocket", pos, NO_REPLACE);
if (boom != NULL)
{
boom->DeathSound = "misc/brainexplode";
boom->vel.z = pr_brainscream() << 9;
boom->Vel.Z = pr_brainscream() /128.;
PClassActor *cls = PClass::FindActor("BossBrain");
if (cls != NULL)
@ -57,12 +57,11 @@ static void BrainishExplosion (fixed_t x, fixed_t y, fixed_t z)
DEFINE_ACTION_FUNCTION(AActor, A_BrainScream)
{
PARAM_ACTION_PROLOGUE;
fixed_t x;
for (x = self->X() - 196*FRACUNIT; x < self->X() + 320*FRACUNIT; x += 8*FRACUNIT)
for (double x = -196; x < +320; x += 8)
{
BrainishExplosion (x, self->Y() - 320*FRACUNIT,
128 + (pr_brainscream() << (FRACBITS + 1)));
// (1 / 512.) is actually what the original value of 128 did, even though it probably meant 128 map units.
BrainishExplosion(self->Vec2OffsetZ(x, -320, (1 / 512.) + pr_brainexplode() * 2));
}
S_Sound (self, CHAN_VOICE, "brain/death", 1, ATTN_NONE);
return 0;
@ -71,9 +70,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_BrainScream)
DEFINE_ACTION_FUNCTION(AActor, A_BrainExplode)
{
PARAM_ACTION_PROLOGUE;
fixed_t x = self->X() + pr_brainexplode.Random2()*2048;
fixed_t z = 128 + pr_brainexplode()*2*FRACUNIT;
BrainishExplosion (x, self->Y(), z);
double x = pr_brainexplode.Random2() / 32.;
DVector3 pos = self->Vec2OffsetZ(x, 0, 1 / 512. + pr_brainexplode() * 2);
BrainishExplosion(pos);
return 0;
}
@ -144,17 +143,17 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BrainSpit)
spit->master = self;
// [RH] Do this correctly for any trajectory. Doom would divide by 0
// if the target had the same y coordinate as the spitter.
if ((spit->vel.x | spit->vel.y) == 0)
if (spit->Vel.X == 0 && spit->Vel.Y == 0)
{
spit->special2 = 0;
}
else if (abs(spit->vel.y) > abs(spit->vel.x))
else if (fabs(spit->Vel.X) > fabs(spit->Vel.Y))
{
spit->special2 = (targ->Y() - self->Y()) / spit->vel.y;
spit->special2 = int((targ->Y() - self->Y()) / spit->Vel.Y);
}
else
{
spit->special2 = (targ->X() - self->X()) / spit->vel.x;
spit->special2 = int((targ->X() - self->X()) / spit->Vel.X);
}
// [GZ] Calculates when the projectile will have reached destination
spit->special2 += level.maptime;

View file

@ -47,7 +47,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BarrelDestroy)
if (dmflags2 & DF2_BARRELS_RESPAWN)
{
self->height = self->GetDefault()->height;
self->Height = self->GetDefault()->Height;
self->renderflags |= RF_INVISIBLE;
self->flags &= ~MF_SOLID;
}

View file

@ -30,9 +30,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_Punch)
{
PARAM_ACTION_PROLOGUE;
angle_t angle;
DAngle angle;
int damage;
int pitch;
DAngle pitch;
FTranslatedLineTarget t;
if (self->player != NULL)
@ -50,9 +50,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Punch)
if (self->FindInventory<APowerStrength>())
damage *= 10;
angle = self->angle;
angle += pr_punch.Random2() << 18;
angle = self->Angles.Yaw + pr_punch.Random2() * (5.625 / 256);
pitch = P_AimLineAttack (self, angle, MELEERANGE);
P_LineAttack (self, angle, MELEERANGE, pitch, damage, NAME_Melee, NAME_BulletPuff, LAF_ISMELEEATTACK, &t);
@ -61,7 +59,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Punch)
if (t.linetarget)
{
S_Sound (self, CHAN_WEAPON, "*fist", 1, ATTN_NORM);
self->angle = t.angleFromSource;
self->Angles.Yaw = t.angleFromSource;
}
return 0;
}
@ -124,15 +122,15 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw)
PARAM_INT_OPT (damage) { damage = 2; }
PARAM_CLASS_OPT (pufftype, AActor) { pufftype = NULL; }
PARAM_INT_OPT (flags) { flags = 0; }
PARAM_FIXED_OPT (range) { range = 0; }
PARAM_ANGLE_OPT(spread_xy) { spread_xy = 33554432; /*angle_t(2.8125 * (ANGLE_90 / 90.0));*/ } // The floating point expression does not get optimized away.
PARAM_ANGLE_OPT (spread_z) { spread_z = 0; }
PARAM_FIXED_OPT (lifesteal) { lifesteal = 0; }
PARAM_FLOAT_OPT (range) { range = 0; }
PARAM_ANGLE_OPT (spread_xy) { spread_xy = 2.8125; }
PARAM_ANGLE_OPT (spread_z) { spread_z = 0.; }
PARAM_FLOAT_OPT (lifesteal) { lifesteal = 0; }
PARAM_INT_OPT (lifestealmax) { lifestealmax = 0; }
PARAM_CLASS_OPT (armorbonustype, ABasicArmorBonus) { armorbonustype = NULL; }
angle_t angle;
angle_t slope;
DAngle angle;
DAngle slope;
player_t *player;
FTranslatedLineTarget t;
int actualdamage;
@ -155,12 +153,12 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw)
damage *= (pr_saw()%10+1);
}
if (range == 0)
{ // use meleerange + 1 so the puff doesn't skip the flash (i.e. plays all states)
range = MELEERANGE+1;
{
range = SAWRANGE;
}
angle = self->angle + (pr_saw.Random2() * (spread_xy / 255));
slope = P_AimLineAttack (self, angle, range, &t) + (pr_saw.Random2() * (spread_z / 255));
angle = self->Angles.Yaw + spread_xy * (pr_saw.Random2() / 255.);
slope = P_AimLineAttack (self, angle, range, &t) + spread_z * (pr_saw.Random2() / 255.);
AWeapon *weapon = self->player->ReadyWeapon;
if ((weapon != NULL) && !(flags & SF_NOUSEAMMO) && !(!t.linetarget && (flags & SF_NOUSEAMMOMISS)) && !(weapon->WeaponFlags & WIF_DEHAMMO) && ACTION_CALL_FROM_WEAPON())
@ -209,8 +207,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw)
if (armorbonustype != NULL)
{
assert(armorbonustype->IsDescendantOf (RUNTIME_CLASS(ABasicArmorBonus)));
ABasicArmorBonus *armorbonus = static_cast<ABasicArmorBonus *>(Spawn(armorbonustype, 0,0,0, NO_REPLACE));
armorbonus->SaveAmount *= (actualdamage * lifesteal) >> FRACBITS;
ABasicArmorBonus *armorbonus = static_cast<ABasicArmorBonus *>(Spawn(armorbonustype));
armorbonus->SaveAmount = int(armorbonus->SaveAmount * actualdamage * lifesteal);
armorbonus->MaxSaveAmount = lifestealmax <= 0 ? armorbonus->MaxSaveAmount : lifestealmax;
armorbonus->flags |= MF_DROPPED;
armorbonus->ClearCounters();
@ -224,7 +222,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw)
else
{
P_GiveBody (self, (actualdamage * lifesteal) >> FRACBITS, lifestealmax);
P_GiveBody (self, int(actualdamage * lifesteal), lifestealmax);
}
}
@ -233,20 +231,21 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw)
// turn to face target
if (!(flags & SF_NOTURN))
{
angle = t.angleFromSource;
if (angle - self->angle > ANG180)
DAngle anglediff = deltaangle(self->Angles.Yaw, t.angleFromSource);
if (anglediff < 0.0)
{
if (angle - self->angle < (angle_t)(-ANG90 / 20))
self->angle = angle + ANG90 / 21;
if (anglediff < -4.5)
self->Angles.Yaw = angle + 90.0 / 21;
else
self->angle -= ANG90 / 20;
self->Angles.Yaw -= 4.5;
}
else
{
if (angle - self->angle > ANG90 / 20)
self->angle = angle - ANG90 / 21;
if (anglediff > 4.5)
self->Angles.Yaw = angle - 90.0 / 21;
else
self->angle += ANG90 / 20;
self->Angles.Yaw += 4.5;
}
}
if (!(flags & SF_NOPULLIN))
@ -280,7 +279,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireShotgun)
}
player->mo->PlayAttacking2 ();
angle_t pitch = P_BulletSlope (self);
DAngle pitch = P_BulletSlope (self);
for (i = 0; i < 7; i++)
{
@ -297,7 +296,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireShotgun2)
PARAM_ACTION_PROLOGUE;
int i;
angle_t angle;
DAngle angle;
int damage;
player_t *player;
@ -318,13 +317,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireShotgun2)
player->mo->PlayAttacking2 ();
angle_t pitch = P_BulletSlope (self);
DAngle pitch = P_BulletSlope (self);
for (i=0 ; i<20 ; i++)
{
damage = 5*(pr_fireshotgun2()%3+1);
angle = self->angle;
angle += pr_fireshotgun2.Random2() << 19;
angle = self->Angles.Yaw + pr_fireshotgun2.Random2() * (11.25 / 256);
// Doom adjusts the bullet slope by shifting a random number [-255,255]
// left 5 places. At 2048 units away, this means the vertical position
@ -335,7 +333,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireShotgun2)
P_LineAttack (self,
angle,
PLAYERMISSILERANGE,
pitch + (pr_fireshotgun2.Random2() * 332063), damage,
pitch + pr_fireshotgun2.Random2() * (7.097 / 256), damage,
NAME_Hitscan, NAME_BulletPuff);
}
return 0;
@ -507,10 +505,10 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireSTGrenade)
}
// Temporarily raise the pitch to send the grenade slightly upwards
fixed_t SavedPlayerPitch = self->pitch;
self->pitch -= (1152 << FRACBITS);
DAngle SavedPlayerPitch = self->Angles.Pitch;
self->Angles.Pitch -= 6.328125; //(1152 << F RACBITS);
P_SpawnPlayerMissile(self, grenade);
self->pitch = SavedPlayerPitch;
self->Angles.Pitch = SavedPlayerPitch;
return 0;
}
@ -572,7 +570,11 @@ static void FireRailgun(AActor *self, int offset_xy, bool fromweapon)
damage = deathmatch ? 100 : 150;
P_RailAttack (self, damage, offset_xy);
FRailParams p;
p.source = self;
p.damage = damage;
p.offset_xy = offset_xy;
P_RailAttack (&p);
}
@ -625,7 +627,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireBFG)
return 0;
}
P_SpawnPlayerMissile (self, 0, 0, 0, PClass::FindActor("BFGBall"), self->angle, NULL, NULL, !!(dmflags2 & DF2_NO_FREEAIMBFG));
P_SpawnPlayerMissile (self, 0, 0, 0, PClass::FindActor("BFGBall"), self->Angles.Yaw, NULL, NULL, !!(dmflags2 & DF2_NO_FREEAIMBFG));
return 0;
}
@ -638,25 +640,25 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray)
{
PARAM_ACTION_PROLOGUE;
PARAM_CLASS_OPT (spraytype, AActor) { spraytype = NULL; }
PARAM_INT_OPT (numrays) { numrays = 40; }
PARAM_INT_OPT (damagecnt) { damagecnt = 15; }
PARAM_ANGLE_OPT (angle) { angle = ANGLE_90; }
PARAM_FIXED_OPT (distance) { distance = 16*64*FRACUNIT; }
PARAM_ANGLE_OPT (vrange) { vrange = 32*ANGLE_1; }
PARAM_INT_OPT (numrays) { numrays = 0; }
PARAM_INT_OPT (damagecnt) { damagecnt = 0; }
PARAM_ANGLE_OPT (angle) { angle = 0.; }
PARAM_FLOAT_OPT (distance) { distance = 0; }
PARAM_ANGLE_OPT (vrange) { vrange = 0.; }
PARAM_INT_OPT (defdamage) { defdamage = 0; }
int i;
int j;
int damage;
angle_t an;
DAngle an;
FTranslatedLineTarget t;
if (spraytype == NULL) spraytype = PClass::FindActor("BFGExtra");
if (numrays <= 0) numrays = 40;
if (damagecnt <= 0) damagecnt = 15;
if (angle == 0) angle = ANG90;
if (distance <= 0) distance = 16 * 64 * FRACUNIT;
if (vrange == 0) vrange = ANGLE_1 * 32;
if (angle == 0) angle = 90.;
if (distance <= 0) distance = 16 * 64;
if (vrange == 0) vrange = 32.;
// [RH] Don't crash if no target
if (!self->target)
@ -665,14 +667,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray)
// offset angles from its attack angle
for (i = 0; i < numrays; i++)
{
an = self->angle - angle / 2 + angle / numrays*i;
an = self->Angles.Yaw - angle / 2 + angle / numrays*i;
// self->target is the originator (player) of the missile
P_AimLineAttack(self->target, an, distance, &t, vrange);
if (t.linetarget != NULL)
{
AActor *spray = Spawn(spraytype, t.linetarget->PosPlusZ(t.linetarget->height >> 2), ALLOW_REPLACE);
AActor *spray = Spawn(spraytype, t.linetarget->PosPlusZ(t.linetarget->Height / 4), ALLOW_REPLACE);
int dmgFlags = 0;
FName dmgType = NAME_BFGSplash;
@ -702,7 +704,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray)
damage = defdamage;
}
int newdam = P_DamageMobj(t.linetarget, self->target, self->target, damage, dmgType, dmgFlags|DMG_USEANGLE, t.angleFromSource);
int newdam = P_DamageMobj(t.linetarget, self->target, self->target, damage, dmgType, dmgFlags|DMG_USEANGLE, t.angleFromSource.Degrees);
P_TraceBleed(newdam > 0 ? newdam : damage, &t, self);
}
}
@ -755,16 +757,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireOldBFG)
self->player->extralight = 2;
// Save values temporarily
angle_t SavedPlayerAngle = self->angle;
fixed_t SavedPlayerPitch = self->pitch;
DAngle SavedPlayerAngle = self->Angles.Yaw;
DAngle SavedPlayerPitch = self->Angles.Pitch;
for (int i = 0; i < 2; i++) // Spawn two plasma balls in sequence
{
self->angle += ((pr_oldbfg()&127) - 64) * (ANG90/768);
self->pitch += ((pr_oldbfg()&127) - 64) * (ANG90/640);
self->Angles.Yaw += ((pr_oldbfg()&127) - 64) * (90./768);
self->Angles.Pitch += ((pr_oldbfg()&127) - 64) * (90./640);
mo = P_SpawnPlayerMissile (self, plasma[i]);
// Restore saved values
self->angle = SavedPlayerAngle;
self->pitch = SavedPlayerPitch;
self->Angles.Yaw = SavedPlayerAngle;
self->Angles.Pitch = SavedPlayerPitch;
}
if (doesautoaim && weapon != NULL)
{ // Restore autoaim setting

View file

@ -15,7 +15,7 @@
// firing three missiles in three different directions?
// Doesn't look like it.
//
#define FATSPREAD (ANG90/8)
#define FATSPREAD (90./8)
DEFINE_ACTION_FUNCTION(AActor, A_FatRaise)
{
@ -32,7 +32,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack1)
PARAM_CLASS_OPT(spawntype, AActor) { spawntype = NULL; }
AActor *missile;
angle_t an;
if (!self->target)
return 0;
@ -41,16 +40,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack1)
A_FaceTarget (self);
// Change direction to ...
self->angle += FATSPREAD;
self->Angles.Yaw += FATSPREAD;
P_SpawnMissile (self, self->target, spawntype);
missile = P_SpawnMissile (self, self->target, spawntype);
if (missile != NULL)
{
missile->angle += FATSPREAD;
an = missile->angle >> ANGLETOFINESHIFT;
missile->vel.x = FixedMul (missile->Speed, finecosine[an]);
missile->vel.y = FixedMul (missile->Speed, finesine[an]);
missile->Angles.Yaw += FATSPREAD;
missile->VelFromAngle();
}
return 0;
}
@ -61,7 +58,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack2)
PARAM_CLASS_OPT(spawntype, AActor) { spawntype = NULL; }
AActor *missile;
angle_t an;
if (!self->target)
return 0;
@ -70,16 +66,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack2)
A_FaceTarget (self);
// Now here choose opposite deviation.
self->angle -= FATSPREAD;
self->Angles.Yaw -= FATSPREAD;
P_SpawnMissile (self, self->target, spawntype);
missile = P_SpawnMissile (self, self->target, spawntype);
if (missile != NULL)
{
missile->angle -= FATSPREAD*2;
an = missile->angle >> ANGLETOFINESHIFT;
missile->vel.x = FixedMul (missile->Speed, finecosine[an]);
missile->vel.y = FixedMul (missile->Speed, finesine[an]);
missile->Angles.Yaw -= FATSPREAD*2;
missile->VelFromAngle();
}
return 0;
}
@ -90,7 +84,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack3)
PARAM_CLASS_OPT(spawntype, AActor) { spawntype = NULL; }
AActor *missile;
angle_t an;
if (!self->target)
return 0;
@ -102,19 +95,15 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack3)
missile = P_SpawnMissile (self, self->target, spawntype);
if (missile != NULL)
{
missile->angle -= FATSPREAD/2;
an = missile->angle >> ANGLETOFINESHIFT;
missile->vel.x = FixedMul (missile->Speed, finecosine[an]);
missile->vel.y = FixedMul (missile->Speed, finesine[an]);
missile->Angles.Yaw -= FATSPREAD/2;
missile->VelFromAngle();
}
missile = P_SpawnMissile (self, self->target, spawntype);
if (missile != NULL)
{
missile->angle += FATSPREAD/2;
an = missile->angle >> ANGLETOFINESHIFT;
missile->vel.x = FixedMul (missile->Speed, finecosine[an]);
missile->vel.y = FixedMul (missile->Speed, finesine[an]);
missile->Angles.Yaw += FATSPREAD/2;
missile->VelFromAngle();
}
return 0;
}
@ -137,8 +126,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Mushroom)
PARAM_CLASS_OPT (spawntype, AActor) { spawntype = NULL; }
PARAM_INT_OPT (n) { n = 0; }
PARAM_INT_OPT (flags) { flags = 0; }
PARAM_FIXED_OPT (vrange) { vrange = 4*FRACUNIT; }
PARAM_FIXED_OPT (hrange) { hrange = FRACUNIT/2; }
PARAM_FLOAT_OPT (vrange) { vrange = 4; }
PARAM_FLOAT_OPT (hrange) { hrange = 0.5; }
int i, j;
@ -152,20 +141,20 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Mushroom)
}
P_RadiusAttack (self, self->target, 128, 128, self->DamageType, (flags & MSF_DontHurt) ? 0 : RADF_HURTSOURCE);
P_CheckSplash(self, 128<<FRACBITS);
P_CheckSplash(self, 128.);
// Now launch mushroom cloud
AActor *target = Spawn("Mapspot", self->Pos(), NO_REPLACE); // We need something to aim at.
AActor *master = (flags & MSF_DontHurt) ? (AActor*)(self->target) : self;
target->height = self->height;
target->Height = self->Height;
for (i = -n; i <= n; i += 8)
{
for (j = -n; j <= n; j += 8)
{
AActor *mo;
target->SetXYZ(
self->X() + (i << FRACBITS), // Aim in many directions from source
self->Y() + (j << FRACBITS),
self->X() + i, // Aim in many directions from source
self->Y() + j,
self->Z() + (P_AproxDistance(i,j) * vrange)); // Aim up fairly high
if ((flags & MSF_Classic) || // Flag explicitely set, or no flags and compat options
(flags == 0 && (self->state->DefineFlags & SDF_DEHACKED) && (i_compatflags & COMPATF_MUSHROOM)))
@ -178,9 +167,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Mushroom)
}
if (mo != NULL)
{ // Slow it down a bit
mo->vel.x = FixedMul(mo->vel.x, hrange);
mo->vel.y = FixedMul(mo->vel.y, hrange);
mo->vel.z = FixedMul(mo->vel.z, hrange);
mo->Vel *= hrange;
mo->flags &= ~MF_NOGRAVITY; // Make debris fall under gravity
}
}

View file

@ -35,7 +35,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_KeenDie)
}
}
EV_DoDoor (DDoor::doorOpen, NULL, NULL, doortag, 2*FRACUNIT, 0, 0, 0);
EV_DoDoor (DDoor::doorOpen, NULL, NULL, doortag, 2., 0, 0, 0);
return 0;
}

View file

@ -19,12 +19,9 @@
// Fly at the player like a missile.
//
void A_SkullAttack(AActor *self, fixed_t speed)
void A_SkullAttack(AActor *self, double speed)
{
AActor *dest;
angle_t an;
int dist;
if (!self->target)
return;
@ -33,21 +30,14 @@ void A_SkullAttack(AActor *self, fixed_t speed)
S_Sound (self, CHAN_VOICE, self->AttackSound, 1, ATTN_NORM);
A_FaceTarget (self);
an = self->angle >> ANGLETOFINESHIFT;
self->vel.x = FixedMul (speed, finecosine[an]);
self->vel.y = FixedMul (speed, finesine[an]);
dist = self->AproxDistance (dest);
dist = dist / speed;
if (dist < 1)
dist = 1;
self->vel.z = (dest->Z() + (dest->height>>1) - self->Z()) / dist;
self->VelFromAngle(speed);
self->Vel.Z = (dest->Center() - self->Z()) / self->DistanceBySpeed(dest, speed);
}
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SkullAttack)
{
PARAM_ACTION_PROLOGUE;
PARAM_FIXED_OPT(speed) { speed = SKULLSPEED; }
PARAM_FLOAT_OPT(speed) { speed = SKULLSPEED; }
if (speed <= 0)
speed = SKULLSPEED;

View file

@ -10,8 +10,6 @@
#include "doomstat.h"
*/
DECLARE_ACTION(A_SkullAttack)
enum PA_Flags
{
PAF_NOSKULLATTACK = 1,
@ -23,21 +21,21 @@ enum PA_Flags
// A_PainShootSkull
// Spawn a lost soul and launch it at the target
//
void A_PainShootSkull (AActor *self, angle_t angle, PClassActor *spawntype, int flags = 0, int limit = -1)
void A_PainShootSkull (AActor *self, DAngle Angle, PClassActor *spawntype, int flags = 0, int limit = -1)
{
AActor *other;
int prestep;
double prestep;
if (spawntype == NULL) spawntype = PClass::FindActor("LostSoul");
assert(spawntype != NULL);
if (self->DamageType == NAME_Massacre) return;
// [RH] check to make sure it's not too close to the ceiling
if (self->Top() + 8*FRACUNIT > self->ceilingz)
if (self->Top() + 8 > self->ceilingz)
{
if (self->flags & MF_FLOAT)
{
self->vel.z -= 2*FRACUNIT;
self->Vel.Z -= 2;
self->flags |= MF_INFLOAT;
self->flags4 |= MF4_VFRICTION;
}
@ -64,14 +62,13 @@ void A_PainShootSkull (AActor *self, angle_t angle, PClassActor *spawntype, int
}
// okay, there's room for another one
prestep = 4*FRACUNIT +
3*(self->radius + GetDefaultByType(spawntype)->radius)/2;
prestep = 4 + (self->radius + GetDefaultByType(spawntype)->radius) * 1.5;
// NOTE: The following code contains some advance work for line-to-line portals which is currenty inactive.
fixedvec2 dist = Vec2Angle(prestep, angle);
fixedvec3 pos = self->Vec3Offset(dist.x, dist.y, 8 * FRACUNIT, true);
fixedvec3 src = self->Pos();
DVector2 dist = Angle.ToVector(prestep);
DVector3 pos = self->Vec3Offset(dist.X, dist.Y, 8., true);
DVector3 src = self->Pos();
for (int i = 0; i < 2; i++)
{
@ -79,7 +76,7 @@ void A_PainShootSkull (AActor *self, angle_t angle, PClassActor *spawntype, int
// wall or an impassible line, or a "monsters can't cross" line.// |
// If it is, then we don't allow the spawn. // V
FBoundingBox box(MIN(src.x, pos.x), MIN(src.y, pos.y), MAX(src.x, pos.x), MAX(src.y, pos.y));
FBoundingBox box(MIN(src.X, pos.X), MIN(src.Y, pos.Y), MAX(src.X, pos.X), MAX(src.Y, pos.Y));
FBlockLinesIterator it(box);
line_t *ld;
bool inportal = false;
@ -88,8 +85,8 @@ void A_PainShootSkull (AActor *self, angle_t angle, PClassActor *spawntype, int
{
if (ld->isLinePortal() && i == 0)
{
if (P_PointOnLineSidePrecise(src.x, src.y, ld) == 0 &&
P_PointOnLineSidePrecise(pos.x, pos.y, ld) == 1)
if (P_PointOnLineSidePrecise(src, ld) == 0 &&
P_PointOnLineSidePrecise(pos, ld) == 1)
{
// crossed a portal line from front to back, we need to repeat the check on the other side as well.
inportal = true;
@ -98,12 +95,9 @@ void A_PainShootSkull (AActor *self, angle_t angle, PClassActor *spawntype, int
else if (!(ld->flags & ML_TWOSIDED) ||
(ld->flags & (ML_BLOCKING | ML_BLOCKMONSTERS | ML_BLOCKEVERYTHING)))
{
if (!(box.Left() > ld->bbox[BOXRIGHT] ||
box.Right() < ld->bbox[BOXLEFT] ||
box.Top() < ld->bbox[BOXBOTTOM] ||
box.Bottom() > ld->bbox[BOXTOP]))
if (box.inRange(ld))
{
if (P_PointOnLineSidePrecise(src.x, src.y, ld) != P_PointOnLineSidePrecise(pos.x, pos.y, ld))
if (P_PointOnLineSidePrecise(src, ld) != P_PointOnLineSidePrecise(pos, ld))
return; // line blocks trajectory // ^
}
}
@ -111,20 +105,19 @@ void A_PainShootSkull (AActor *self, angle_t angle, PClassActor *spawntype, int
if (!inportal) break;
// recalculate position and redo the check on the other side of the portal
pos = self->Vec3Offset(dist.x, dist.y, 8 * FRACUNIT);
src.x = pos.x - dist.x;
src.y = pos.y - dist.y;
pos = self->Vec3Offset(dist.X, dist.Y, 8.);
src.X = pos.X - dist.X;
src.Y = pos.Y - dist.Y;
}
other = Spawn (spawntype, pos.x, pos.y, pos.z, ALLOW_REPLACE);
other = Spawn (spawntype, pos, ALLOW_REPLACE);
// Check to see if the new Lost Soul's z value is above the
// ceiling of its new sector, or below the floor. If so, kill it.
if ((other->Top() >
(other->Sector->HighestCeilingAt(other))) ||
(other->Z() < other->Sector->LowestFloorAt(other)))
if (other->Top() > other->Sector->HighestCeilingAt(other) ||
other->Z() < other->Sector->LowestFloorAt(other))
{
// kill it immediately
P_DamageMobj (other, self, self, TELEFRAG_DAMAGE, NAME_None);// ^
@ -160,13 +153,13 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PainAttack)
return 0;
PARAM_CLASS_OPT (spawntype, AActor) { spawntype = NULL; }
PARAM_ANGLE_OPT (angle) { angle = 0; }
PARAM_ANGLE_OPT (angle) { angle = 0.; }
PARAM_INT_OPT (flags) { flags = 0; }
PARAM_INT_OPT (limit) { limit = -1; }
if (!(flags & PAF_AIMFACING))
A_FaceTarget (self);
A_PainShootSkull (self, self->angle+angle, spawntype, flags, limit);
A_PainShootSkull (self, self->Angles.Yaw + angle, spawntype, flags, limit);
return 0;
}
@ -179,8 +172,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DualPainAttack)
return 0;
A_FaceTarget (self);
A_PainShootSkull (self, self->angle + ANG45, spawntype);
A_PainShootSkull (self, self->angle - ANG45, spawntype);
A_PainShootSkull (self, self->Angles.Yaw + 45., spawntype);
A_PainShootSkull (self, self->Angles.Yaw - 45., spawntype);
return 0;
}
@ -194,8 +187,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PainDie)
self->flags &= ~MF_FRIENDLY;
}
A_Unblock(self, true);
A_PainShootSkull (self, self->angle + ANG90, spawntype);
A_PainShootSkull (self, self->angle + ANG180, spawntype);
A_PainShootSkull (self, self->angle + ANG270, spawntype);
A_PainShootSkull (self, self->Angles.Yaw + 90, spawntype);
A_PainShootSkull (self, self->Angles.Yaw + 180, spawntype);
A_PainShootSkull (self, self->Angles.Yaw + 270, spawntype);
return 0;
}

View file

@ -22,19 +22,19 @@ DEFINE_ACTION_FUNCTION(AActor, A_PosAttack)
{
PARAM_ACTION_PROLOGUE;
int angle;
int damage;
int slope;
DAngle angle;
DAngle slope;
if (!self->target)
return 0;
A_FaceTarget (self);
angle = self->angle;
angle = self->Angles.Yaw;
slope = P_AimLineAttack (self, angle, MISSILERANGE);
S_Sound (self, CHAN_WEAPON, "grunt/attack", 1, ATTN_NORM);
angle += pr_posattack.Random2() << 20;
angle += pr_posattack.Random2() * (22.5 / 256);
damage = ((pr_posattack()%5)+1)*3;
P_LineAttack (self, angle, MISSILERANGE, slope, damage, NAME_Hitscan, NAME_BulletPuff);
return 0;
@ -43,16 +43,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_PosAttack)
static void A_SPosAttack2 (AActor *self)
{
int i;
int bangle;
int slope;
DAngle bangle;
DAngle slope;
A_FaceTarget (self);
bangle = self->angle;
bangle = self->Angles.Yaw;
slope = P_AimLineAttack (self, bangle, MISSILERANGE);
for (i=0 ; i<3 ; i++)
{
int angle = bangle + (pr_sposattack.Random2() << 20);
DAngle angle = bangle + pr_sposattack.Random2() * (22.5 / 256);
int damage = ((pr_sposattack()%5)+1)*3;
P_LineAttack(self, angle, MISSILERANGE, slope, damage, NAME_Hitscan, NAME_BulletPuff);
}
@ -88,10 +88,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_CPosAttack)
{
PARAM_ACTION_PROLOGUE;
int angle;
int bangle;
DAngle angle;
DAngle bangle;
int damage;
int slope;
DAngle slope;
if (!self->target)
return 0;
@ -104,10 +104,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_CPosAttack)
S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM);
A_FaceTarget (self);
bangle = self->angle;
bangle = self->Angles.Yaw;
slope = P_AimLineAttack (self, bangle, MISSILERANGE);
angle = bangle + (pr_cposattack.Random2() << 20);
angle = bangle + pr_cposattack.Random2() * (22.5 / 256);
damage = ((pr_cposattack()%5)+1)*3;
P_LineAttack (self, angle, MISSILERANGE, slope, damage, NAME_Hitscan, NAME_BulletPuff);
return 0;

View file

@ -28,27 +28,26 @@ DEFINE_ACTION_FUNCTION(AActor, A_SkelMissile)
return 0;
A_FaceTarget (self);
self->AddZ(16*FRACUNIT);
missile = P_SpawnMissile (self, self->target, PClass::FindActor("RevenantTracer"));
self->AddZ(-16*FRACUNIT);
self->AddZ(16.);
missile = P_SpawnMissile(self, self->target, PClass::FindActor("RevenantTracer"));
self->AddZ(-16.);
if (missile != NULL)
{
missile->SetOrigin(missile->Vec3Offset(missile->vel.x, missile->vel.y, 0), false);
missile->SetOrigin(missile->Vec3Offset(missile->Vel.X, missile->Vel.Y, 0.), false);
missile->tracer = self->target;
}
return 0;
}
#define TRACEANGLE (0xc000000)
#define TRACEANGLE (16.875)
DEFINE_ACTION_FUNCTION(AActor, A_Tracer)
{
PARAM_ACTION_PROLOGUE;
angle_t exact;
fixed_t dist;
fixed_t slope;
double dist;
double slope;
AActor *dest;
AActor *smoke;
@ -65,11 +64,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_Tracer)
return 0;
// spawn a puff of smoke behind the rocket
P_SpawnPuff (self, PClass::FindActor(NAME_BulletPuff), self->Pos(), self->angle, self->angle, 3);
P_SpawnPuff (self, PClass::FindActor(NAME_BulletPuff), self->Pos(), self->Angles.Yaw, self->Angles.Yaw, 3);
smoke = Spawn ("RevenantTracerSmoke", self->Vec3Offset(-self->vel.x, -self->vel.y, 0), ALLOW_REPLACE);
smoke = Spawn ("RevenantTracerSmoke", self->Vec3Offset(-self->Vel.X, -self->Vel.Y, 0.), ALLOW_REPLACE);
smoke->vel.z = FRACUNIT;
smoke->Vel.Z = 1.;
smoke->tics -= pr_tracer()&3;
if (smoke->tics < 1)
smoke->tics = 1;
@ -81,49 +80,42 @@ DEFINE_ACTION_FUNCTION(AActor, A_Tracer)
return 0;
// change angle
exact = self->AngleTo(dest);
DAngle exact = self->AngleTo(dest);
DAngle diff = deltaangle(self->Angles.Yaw, exact);
if (exact != self->angle)
if (diff < 0)
{
if (exact - self->angle > 0x80000000)
{
self->angle -= TRACEANGLE;
if (exact - self->angle < 0x80000000)
self->angle = exact;
}
else
{
self->angle += TRACEANGLE;
if (exact - self->angle > 0x80000000)
self->angle = exact;
}
self->Angles.Yaw -= TRACEANGLE;
if (deltaangle(self->Angles.Yaw, exact) > 0)
self->Angles.Yaw = exact;
}
exact = self->angle>>ANGLETOFINESHIFT;
self->vel.x = FixedMul (self->Speed, finecosine[exact]);
self->vel.y = FixedMul (self->Speed, finesine[exact]);
else if (diff > 0)
{
self->Angles.Yaw += TRACEANGLE;
if (deltaangle(self->Angles.Yaw, exact) < 0.)
self->Angles.Yaw = exact;
}
self->VelFromAngle();
if (!(self->flags3 & (MF3_FLOORHUGGER|MF3_CEILINGHUGGER)))
{
// change slope
dist = self->AproxDistance (dest) / self->Speed;
dist = self->DistanceBySpeed(dest, self->Speed);
if (dist < 1)
dist = 1;
if (dest->height >= 56*FRACUNIT)
if (dest->Height >= 56.)
{
slope = (dest->Z()+40*FRACUNIT - self->Z()) / dist;
slope = (dest->Z() + 40. - self->Z()) / dist;
}
else
{
slope = (dest->Z() + self->height*2/3 - self->Z()) / dist;
slope = (dest->Z() + self->Height*(2./3) - self->Z()) / dist;
}
if (slope < self->vel.z)
self->vel.z -= FRACUNIT/8;
if (slope < self->Vel.Z)
self->Vel.Z -= 1. / 8;
else
self->vel.z += FRACUNIT/8;
self->Vel.Z += 1. / 8;
}
return 0;
}

View file

@ -275,14 +275,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_Saw)
A_FaceTarget (self);
if (self->CheckMeleeRange ())
{
angle_t angle;
DAngle angle;
FTranslatedLineTarget t;
damage *= (pr_m_saw()%10+1);
angle = self->angle + (pr_m_saw.Random2() << 18);
angle = self->Angles.Yaw + pr_m_saw.Random2() * (5.625 / 256);
P_LineAttack (self, angle, MELEERANGE+1,
P_AimLineAttack (self, angle, MELEERANGE+1), damage,
P_LineAttack (self, angle, SAWRANGE,
P_AimLineAttack (self, angle, SAWRANGE), damage,
NAME_Melee, pufftype, false, &t);
if (!t.linetarget)
@ -294,19 +294,21 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_Saw)
// turn to face target
angle = t.angleFromSource;
if (angle - self->angle > ANG180)
DAngle anglediff = deltaangle(self->Angles.Yaw, angle);
if (anglediff < 0.0)
{
if (angle - self->angle < (angle_t)(-ANG90/20))
self->angle = angle + ANG90/21;
if (anglediff < -4.5)
self->Angles.Yaw = angle + 90.0 / 21;
else
self->angle -= ANG90/20;
self->Angles.Yaw -= 4.5;
}
else
{
if (angle - self->angle > ANG90/20)
self->angle = angle - ANG90/21;
if (anglediff > 4.5)
self->Angles.Yaw = angle - 90.0 / 21;
else
self->angle += ANG90/20;
self->Angles.Yaw += 4.5;
}
}
else
@ -325,9 +327,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_Saw)
static void MarinePunch(AActor *self, int damagemul)
{
angle_t angle;
DAngle angle;
int damage;
int pitch;
DAngle pitch;
FTranslatedLineTarget t;
if (self->target == NULL)
@ -336,7 +338,7 @@ static void MarinePunch(AActor *self, int damagemul)
damage = ((pr_m_punch()%10+1) << 1) * damagemul;
A_FaceTarget (self);
angle = self->angle + (pr_m_punch.Random2() << 18);
angle = self->Angles.Yaw + pr_m_punch.Random2() * (5.625 / 256);
pitch = P_AimLineAttack (self, angle, MELEERANGE);
P_LineAttack (self, angle, MELEERANGE, pitch, damage, NAME_Melee, NAME_BulletPuff, true, &t);
@ -344,7 +346,7 @@ static void MarinePunch(AActor *self, int damagemul)
if (t.linetarget)
{
S_Sound (self, CHAN_WEAPON, "*fist", 1, ATTN_NORM);
self->angle = t.angleFromSource;
self->Angles.Yaw = t.angleFromSource;
}
}
@ -363,17 +365,17 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_Punch)
//
//============================================================================
void P_GunShot2 (AActor *mo, bool accurate, int pitch, PClassActor *pufftype)
void P_GunShot2 (AActor *mo, bool accurate, DAngle pitch, PClassActor *pufftype)
{
angle_t angle;
DAngle angle;
int damage;
damage = 5*(pr_m_gunshot()%3+1);
angle = mo->angle;
angle = mo->Angles.Yaw;
if (!accurate)
{
angle += pr_m_gunshot.Random2 () << 18;
angle += pr_m_gunshot.Random2() * (5.625 / 256);
}
P_LineAttack (mo, angle, MISSILERANGE, pitch, damage, NAME_Hitscan, pufftype);
@ -395,7 +397,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_FirePistol)
S_Sound (self, CHAN_WEAPON, "weapons/pistol", 1, ATTN_NORM);
A_FaceTarget (self);
P_GunShot2 (self, accurate, P_AimLineAttack (self, self->angle, MISSILERANGE),
P_GunShot2 (self, accurate, P_AimLineAttack (self, self->Angles.Yaw, MISSILERANGE),
PClass::FindActor(NAME_BulletPuff));
return 0;
}
@ -410,14 +412,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_M_FireShotgun)
{
PARAM_ACTION_PROLOGUE;
int pitch;
DAngle pitch;
if (self->target == NULL)
return 0;
S_Sound (self, CHAN_WEAPON, "weapons/shotgf", 1, ATTN_NORM);
A_FaceTarget (self);
pitch = P_AimLineAttack (self, self->angle, MISSILERANGE);
pitch = P_AimLineAttack (self, self->Angles.Yaw, MISSILERANGE);
for (int i = 0; i < 7; ++i)
{
P_GunShot2 (self, false, pitch, PClass::FindActor(NAME_BulletPuff));
@ -457,21 +459,21 @@ DEFINE_ACTION_FUNCTION(AActor, A_M_FireShotgun2)
{
PARAM_ACTION_PROLOGUE;
int pitch;
DAngle pitch;
if (self->target == NULL)
return 0;
S_Sound (self, CHAN_WEAPON, "weapons/sshotf", 1, ATTN_NORM);
A_FaceTarget (self);
pitch = P_AimLineAttack (self, self->angle, MISSILERANGE);
pitch = P_AimLineAttack (self, self->Angles.Yaw, MISSILERANGE);
for (int i = 0; i < 20; ++i)
{
int damage = 5*(pr_m_fireshotgun2()%3+1);
angle_t angle = self->angle + (pr_m_fireshotgun2.Random2() << 19);
DAngle angle = self->Angles.Yaw + pr_m_fireshotgun2.Random2() * (11.25 / 256);
P_LineAttack (self, angle, MISSILERANGE,
pitch + (pr_m_fireshotgun2.Random2() * 332063), damage,
pitch + pr_m_fireshotgun2.Random2() * (7.097 / 256), damage,
NAME_Hitscan, NAME_BulletPuff);
}
self->special1 = level.maptime;
@ -494,7 +496,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_FireCGun)
S_Sound (self, CHAN_WEAPON, "weapons/chngun", 1, ATTN_NORM);
A_FaceTarget (self);
P_GunShot2 (self, accurate, P_AimLineAttack (self, self->angle, MISSILERANGE),
P_GunShot2 (self, accurate, P_AimLineAttack (self, self->Angles.Yaw, MISSILERANGE),
PClass::FindActor(NAME_BulletPuff));
return 0;
}
@ -647,13 +649,11 @@ void AScriptedMarine::SetSprite (PClassActor *source)
{ // A valid actor class wasn't passed, so use the standard sprite
SpriteOverride = sprite = GetClass()->OwnedStates[0].sprite;
// Copy the standard scaling
scaleX = GetDefault()->scaleX;
scaleY = GetDefault()->scaleY;
Scale = GetDefault()->Scale;
}
else
{ // Use the same sprite and scaling the passed class spawns with
SpriteOverride = sprite = GetDefaultByType (source)->SpawnState->sprite;
scaleX = GetDefaultByType(source)->scaleX;
scaleY = GetDefaultByType(source)->scaleY;
Scale = GetDefaultByType(source)->Scale;
}
}

View file

@ -197,9 +197,9 @@ short consistancy[MAXPLAYERS][BACKUPTICS];
float normforwardmove[2] = {0x19, 0x32}; // [RH] For setting turbo from console
float normsidemove[2] = {0x18, 0x28}; // [RH] Ditto
fixed_t forwardmove[2], sidemove[2];
fixed_t angleturn[4] = {640, 1280, 320, 320}; // + slow turn
fixed_t flyspeed[2] = {1*256, 3*256};
int forwardmove[2], sidemove[2];
int angleturn[4] = {640, 1280, 320, 320}; // + slow turn
int flyspeed[2] = {1*256, 3*256};
int lookspeed[2] = {450, 512};
#define SLOWTURNTICS 6
@ -1182,8 +1182,7 @@ void G_Ticker ()
}
if (players[i].mo)
{
DWORD sum = rngsum + players[i].mo->X() + players[i].mo->Y() + players[i].mo->Z()
+ players[i].mo->angle + players[i].mo->pitch;
DWORD sum = rngsum + int((players[i].mo->X() + players[i].mo->Y() + players[i].mo->Z())*257) + players[i].mo->Angles.Yaw.BAMs() + players[i].mo->Angles.Pitch.BAMs();
sum ^= players[i].health;
consistancy[i][buf] = sum;
}
@ -1288,7 +1287,7 @@ void G_PlayerFinishLevel (int player, EFinishLevelType mode, int flags)
p->mo->flags &= ~MF_SHADOW;
}
p->mo->RenderStyle = p->mo->GetDefault()->RenderStyle;
p->mo->alpha = p->mo->GetDefault()->alpha;
p->mo->Alpha = p->mo->GetDefault()->Alpha;
p->extralight = 0; // cancel gun flashes
p->fixedcolormap = NOFIXEDCOLORMAP; // cancel ir goggles
p->fixedlightlevel = -1;
@ -1423,33 +1422,30 @@ void G_PlayerReborn (int player)
bool G_CheckSpot (int playernum, FPlayerStart *mthing)
{
fixed_t x;
fixed_t y;
fixed_t z, oldz;
DVector3 spot;
double oldz;
int i;
if (mthing->type == 0) return false;
x = mthing->x;
y = mthing->y;
z = mthing->z;
spot = mthing->pos;
if (!(level.flags & LEVEL_USEPLAYERSTARTZ))
{
z = 0;
spot.Z = 0;
}
z += P_PointInSector (x, y)->floorplane.ZatPoint (x, y);
spot.Z += P_PointInSector (spot)->floorplane.ZatPoint (spot);
if (!players[playernum].mo)
{ // first spawn of level, before corpses
for (i = 0; i < playernum; i++)
if (players[i].mo && players[i].mo->X() == x && players[i].mo->Y() == y)
if (players[i].mo && players[i].mo->X() == spot.X && players[i].mo->Y() == spot.Y)
return false;
return true;
}
oldz = players[playernum].mo->Z(); // [RH] Need to save corpse's z-height
players[playernum].mo->SetZ(z); // [RH] Checks are now full 3-D
players[playernum].mo->SetZ(spot.Z); // [RH] Checks are now full 3-D
// killough 4/2/98: fix bug where P_CheckPosition() uses a non-solid
// corpse to detect collisions with other players in DM starts
@ -1459,7 +1455,7 @@ bool G_CheckSpot (int playernum, FPlayerStart *mthing)
// return false;
players[playernum].mo->flags |= MF_SOLID;
i = P_CheckPosition(players[playernum].mo, x, y);
i = P_CheckPosition(players[playernum].mo, spot);
players[playernum].mo->flags &= ~MF_SOLID;
players[playernum].mo->SetZ(oldz); // [RH] Restore corpse's height
if (!i)
@ -1476,10 +1472,10 @@ bool G_CheckSpot (int playernum, FPlayerStart *mthing)
//
// [RH] Returns the distance of the closest player to the given mapthing
static fixed_t PlayersRangeFromSpot (FPlayerStart *spot)
static double PlayersRangeFromSpot (FPlayerStart *spot)
{
fixed_t closest = INT_MAX;
fixed_t distance;
double closest = INT_MAX;
double distance;
int i;
for (i = 0; i < MAXPLAYERS; i++)
@ -1487,7 +1483,7 @@ static fixed_t PlayersRangeFromSpot (FPlayerStart *spot)
if (!playeringame[i] || !players[i].mo || players[i].health <= 0)
continue;
distance = players[i].mo->AproxDistance (spot->x, spot->y);
distance = players[i].mo->Distance2D(spot->pos.X, spot->pos.Y);
if (distance < closest)
closest = distance;
@ -1499,13 +1495,13 @@ static fixed_t PlayersRangeFromSpot (FPlayerStart *spot)
// [RH] Select the deathmatch spawn spot farthest from everyone.
static FPlayerStart *SelectFarthestDeathmatchSpot (size_t selections)
{
fixed_t bestdistance = 0;
double bestdistance = 0;
FPlayerStart *bestspot = NULL;
unsigned int i;
for (i = 0; i < selections; i++)
{
fixed_t distance = PlayersRangeFromSpot (&deathmatchstarts[i]);
double distance = PlayersRangeFromSpot (&deathmatchstarts[i]);
if (distance > bestdistance)
{
@ -1645,8 +1641,8 @@ static void G_QueueBody (AActor *body)
const AActor *const defaultActor = body->GetDefault();
const FPlayerSkin &skin = skins[skinidx];
body->scaleX = Scale(body->scaleX, skin.ScaleX, defaultActor->scaleX);
body->scaleY = Scale(body->scaleY, skin.ScaleY, defaultActor->scaleY);
body->Scale.X *= skin.Scale.X / defaultActor->Scale.X;
body->Scale.Y *= skin.Scale.Y / defaultActor->Scale.Y;
}
bodyqueslot++;
@ -1933,13 +1929,6 @@ void G_DoLoadGame ()
BYTE *vars_p = (BYTE *)text;
C_ReadCVars (&vars_p);
delete[] text;
if (SaveVersion <= 4509)
{
// account for the flag shuffling for making freelook a 3-state option
INTBOOL flag = dmflags & DF_YES_FREELOOK;
dmflags = dmflags & ~DF_YES_FREELOOK;
if (flag) dmflags2 = dmflags2 | DF2_RESPAWN_SUPER;
}
}
// dearchive all the modifications

View file

@ -41,13 +41,13 @@ void AChickenPlayer::MorphPlayerThink ()
{
return;
}
if (!(vel.x | vel.y) && pr_chickenplayerthink () < 160)
if (Vel.X == 0 && Vel.Y == 0 && pr_chickenplayerthink () < 160)
{ // Twitch view angle
angle += pr_chickenplayerthink.Random2 () << 19;
Angles.Yaw += pr_chickenplayerthink.Random2() * (360. / 256. / 32.);
}
if ((Z() <= floorz) && (pr_chickenplayerthink() < 32))
{ // Jump and noise
vel.z += JumpZ;
Vel.Z += JumpZ;
FState * painstate = FindState(NAME_Pain);
if (painstate != NULL) SetState (painstate);
@ -105,11 +105,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_Feathers)
}
for (i = 0; i < count; i++)
{
mo = Spawn("Feather", self->PosPlusZ(20*FRACUNIT), NO_REPLACE);
mo = Spawn("Feather", self->PosPlusZ(20.), NO_REPLACE);
mo->target = self;
mo->vel.x = pr_feathers.Random2() << 8;
mo->vel.y = pr_feathers.Random2() << 8;
mo->vel.z = FRACUNIT + (pr_feathers() << 9);
mo->Vel.X = pr_feathers.Random2() / 256.;
mo->Vel.Y = pr_feathers.Random2() / 256.;
mo->Vel.Z = 1. + pr_feathers() / 128.;
mo->SetState (mo->SpawnState + (pr_feathers()&7));
}
return 0;
@ -125,8 +125,7 @@ void P_UpdateBeak (AActor *self)
{
if (self->player != NULL)
{
self->player->psprites[ps_weapon].sy = WEAPONTOP +
(self->player->chickenPeck << (FRACBITS-1));
self->player->psprites[ps_weapon].sy = WEAPONTOP + self->player->chickenPeck / 2;
}
}
@ -172,9 +171,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_BeakAttackPL1)
{
PARAM_ACTION_PROLOGUE;
angle_t angle;
DAngle angle;
int damage;
int slope;
DAngle slope;
player_t *player;
FTranslatedLineTarget t;
@ -184,12 +183,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_BeakAttackPL1)
}
damage = 1 + (pr_beakatkpl1()&3);
angle = player->mo->angle;
angle = player->mo->Angles.Yaw;
slope = P_AimLineAttack (player->mo, angle, MELEERANGE);
P_LineAttack (player->mo, angle, MELEERANGE, slope, damage, NAME_Melee, "BeakPuff", true, &t);
if (t.linetarget)
{
player->mo->angle = t.angleFromSource;
player->mo->Angles.Yaw = t.angleFromSource;
}
P_PlayPeck (player->mo);
player->chickenPeck = 12;
@ -207,9 +206,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_BeakAttackPL2)
{
PARAM_ACTION_PROLOGUE;
angle_t angle;
DAngle angle;
int damage;
int slope;
DAngle slope;
player_t *player;
FTranslatedLineTarget t;
@ -219,12 +218,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_BeakAttackPL2)
}
damage = pr_beakatkpl2.HitDice (4);
angle = player->mo->angle;
angle = player->mo->Angles.Yaw;
slope = P_AimLineAttack (player->mo, angle, MELEERANGE);
P_LineAttack (player->mo, angle, MELEERANGE, slope, damage, NAME_Melee, "BeakPuff", true, &t);
if (t.linetarget)
{
player->mo->angle = t.angleFromSource;
player->mo->Angles.Yaw = t.angleFromSource;
}
P_PlayPeck (player->mo);
player->chickenPeck = 12;

View file

@ -67,8 +67,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Srcr1Attack)
PARAM_ACTION_PROLOGUE;
AActor *mo;
fixed_t vz;
angle_t angle;
DAngle angle;
if (!self->target)
{
@ -86,17 +85,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_Srcr1Attack)
PClassActor *fx = PClass::FindActor("SorcererFX1");
if (self->health > (self->SpawnHealth()/3)*2)
{ // Spit one fireball
P_SpawnMissileZ (self, self->Z() + 48*FRACUNIT, self->target, fx );
P_SpawnMissileZ (self, self->Z() + 48, self->target, fx );
}
else
{ // Spit three fireballs
mo = P_SpawnMissileZ (self, self->Z() + 48*FRACUNIT, self->target, fx);
mo = P_SpawnMissileZ (self, self->Z() + 48, self->target, fx);
if (mo != NULL)
{
vz = mo->vel.z;
angle = mo->angle;
P_SpawnMissileAngleZ (self, self->Z() + 48*FRACUNIT, fx, angle-ANGLE_1*3, vz);
P_SpawnMissileAngleZ (self, self->Z() + 48*FRACUNIT, fx, angle+ANGLE_1*3, vz);
angle = mo->Angles.Yaw;
P_SpawnMissileAngleZ(self, self->Z() + 48, fx, angle - 3, mo->Vel.Z);
P_SpawnMissileAngleZ(self, self->Z() + 48, fx, angle + 3, mo->Vel.Z);
}
if (self->health < self->SpawnHealth()/3)
{ // Maybe attack again
@ -130,7 +128,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcererRise)
mo = Spawn("Sorcerer2", self->Pos(), ALLOW_REPLACE);
mo->Translation = self->Translation;
mo->SetState (mo->FindState("Rise"));
mo->angle = self->angle;
mo->Angles.Yaw = self->Angles.Yaw;
mo->CopyFriendliness (self, true);
return 0;
}
@ -143,31 +141,27 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcererRise)
void P_DSparilTeleport (AActor *actor)
{
fixed_t prevX;
fixed_t prevY;
fixed_t prevZ;
DVector3 prev;
AActor *mo;
AActor *spot;
DSpotState *state = DSpotState::GetSpotState();
if (state == NULL) return;
spot = state->GetSpotWithMinMaxDistance(PClass::FindClass("BossSpot"), actor->X(), actor->Y(), 128*FRACUNIT, 0);
spot = state->GetSpotWithMinMaxDistance(PClass::FindClass("BossSpot"), actor->X(), actor->Y(), 128, 0);
if (spot == NULL) return;
prevX = actor->X();
prevY = actor->Y();
prevZ = actor->Z();
prev = actor->Pos();
if (P_TeleportMove (actor, spot->Pos(), false))
{
mo = Spawn("Sorcerer2Telefade", prevX, prevY, prevZ, ALLOW_REPLACE);
mo = Spawn("Sorcerer2Telefade", prev, ALLOW_REPLACE);
if (mo) mo->Translation = actor->Translation;
S_Sound (mo, CHAN_BODY, "misc/teleport", 1, ATTN_NORM);
actor->SetState (actor->FindState("Teleport"));
S_Sound (actor, CHAN_BODY, "misc/teleport", 1, ATTN_NORM);
actor->SetZ(actor->floorz, false);
actor->angle = spot->angle;
actor->vel.x = actor->vel.y = actor->vel.z = 0;
actor->SetZ(actor->floorz);
actor->Angles.Yaw = spot->Angles.Yaw;
actor->Vel.Zero();
}
}
@ -230,8 +224,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_Srcr2Attack)
PClassActor *fx = PClass::FindActor("Sorcerer2FX2");
if (fx)
{
P_SpawnMissileAngle (self, fx, self->angle-ANG45, FRACUNIT/2);
P_SpawnMissileAngle (self, fx, self->angle+ANG45, FRACUNIT/2);
P_SpawnMissileAngle(self, fx, self->Angles.Yaw - 45, 0.5);
P_SpawnMissileAngle(self, fx, self->Angles.Yaw + 45, 0.5);
}
}
else
@ -257,9 +251,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_BlueSpark)
for (i = 0; i < 2; i++)
{
mo = Spawn("Sorcerer2FXSpark", self->Pos(), ALLOW_REPLACE);
mo->vel.x = pr_bluespark.Random2() << 9;
mo->vel.y = pr_bluespark.Random2() << 9;
mo->vel.z = FRACUNIT + (pr_bluespark()<<8);
mo->Vel.X = pr_bluespark.Random2() / 128.;
mo->Vel.Y = pr_bluespark.Random2() / 128.;
mo->Vel.Z = 1. + pr_bluespark() / 256.;
}
return 0;
}
@ -279,7 +273,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_GenWizard)
mo = Spawn("Wizard", self->Pos(), ALLOW_REPLACE);
if (mo != NULL)
{
mo->AddZ(-mo->GetDefault()->height / 2, false);
mo->AddZ(-mo->GetDefault()->Height / 2, false);
if (!P_TestMobjLocation (mo))
{ // Didn't fit
mo->ClearCounters();
@ -289,7 +283,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_GenWizard)
{ // [RH] Make the new wizards inherit D'Sparil's target
mo->CopyFriendliness (self->target, true);
self->vel.x = self->vel.y = self->vel.z = 0;
self->Vel.Zero();
self->SetState (self->FindState(NAME_Death));
self->flags &= ~MF_MISSILE;
mo->master = self->target;

View file

@ -49,12 +49,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_TimeBomb)
{
PARAM_ACTION_PROLOGUE;
self->AddZ(32*FRACUNIT, false);
self->PrevZ = self->Z(); // no interpolation!
self->AddZ(32, false);
self->RenderStyle = STYLE_Add;
self->alpha = FRACUNIT;
self->Alpha = 1.;
P_RadiusAttack (self, self->target, 128, 128, self->DamageType, RADF_HURTSOURCE);
P_CheckSplash(self, 128<<FRACBITS);
P_CheckSplash(self, 128);
return 0;
}
@ -70,9 +69,8 @@ IMPLEMENT_CLASS (AArtiTimeBomb)
bool AArtiTimeBomb::Use (bool pickup)
{
angle_t angle = Owner->angle >> ANGLETOFINESHIFT;
AActor *mo = Spawn("ActivatedTimeBomb",
Owner->Vec3Angle(24*FRACUNIT, Owner->angle, - Owner->floorclip), ALLOW_REPLACE);
Owner->Vec3Angle(24., Owner->Angles.Yaw, - Owner->Floorclip), ALLOW_REPLACE);
mo->target = Owner;
return true;
}

View file

@ -28,7 +28,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ImpMsAttack)
self->SetState (self->SeeState);
return 0;
}
A_SkullAttack(self, 12 * FRACUNIT);
A_SkullAttack(self, 12.);
return 0;
}
@ -47,14 +47,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_ImpExplode)
self->flags &= ~MF_NOGRAVITY;
chunk = Spawn("HereticImpChunk1", self->Pos(), ALLOW_REPLACE);
chunk->vel.x = pr_imp.Random2 () << 10;
chunk->vel.y = pr_imp.Random2 () << 10;
chunk->vel.z = 9*FRACUNIT;
chunk->Vel.X = pr_imp.Random2() / 64.;
chunk->Vel.Y = pr_imp.Random2() / 64.;
chunk->Vel.Z = 9;
chunk = Spawn("HereticImpChunk2", self->Pos(), ALLOW_REPLACE);
chunk->vel.x = pr_imp.Random2 () << 10;
chunk->vel.y = pr_imp.Random2 () << 10;
chunk->vel.z = 9*FRACUNIT;
chunk->Vel.X = pr_imp.Random2() / 64.;
chunk->Vel.Y = pr_imp.Random2() / 64.;
chunk->Vel.Z = 9;
if (self->special1 == 666)
{ // Extreme death crash
self->SetState (self->FindState("XCrash"));

View file

@ -59,11 +59,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PodPain)
}
for (count = chance > 240 ? 2 : 1; count; count--)
{
goo = Spawn(gootype, self->PosPlusZ(48*FRACUNIT), ALLOW_REPLACE);
goo = Spawn(gootype, self->PosPlusZ(48.), ALLOW_REPLACE);
goo->target = self;
goo->vel.x = pr_podpain.Random2() << 9;
goo->vel.y = pr_podpain.Random2() << 9;
goo->vel.z = FRACUNIT/2 + (pr_podpain() << 9);
goo->Vel.X = pr_podpain.Random2() / 128.;
goo->Vel.Y = pr_podpain.Random2() / 128.;
goo->Vel.Z = 0.5 + pr_podpain() / 128.;
}
return 0;
}
@ -104,23 +104,19 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_MakePod)
PARAM_CLASS_OPT(podtype, AActor) { podtype = PClass::FindActor("Pod"); }
AActor *mo;
fixed_t x;
fixed_t y;
if (self->special1 == MAX_GEN_PODS)
{ // Too many generated pods
return 0;
}
x = self->X();
y = self->Y();
mo = Spawn(podtype, x, y, ONFLOORZ, ALLOW_REPLACE);
if (!P_CheckPosition (mo, x, y))
mo = Spawn(podtype, self->PosAtZ(ONFLOORZ), ALLOW_REPLACE);
if (!P_CheckPosition (mo, mo->Pos()))
{ // Didn't fit
mo->Destroy ();
return 0;
}
mo->SetState (mo->FindState("Grow"));
P_ThrustMobj (mo, pr_makepod()<<24, (fixed_t)(4.5*FRACUNIT));
mo->Thrust(pr_makepod() * (360. / 256), 4.5);
S_Sound (mo, CHAN_BODY, self->AttackSound, 1, ATTN_IDLE);
self->special1++; // Increment generated pod count
mo->master = self; // Link the generator to the pod
@ -139,7 +135,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_AccTeleGlitter)
if (++self->health > 35)
{
self->vel.z += self->vel.z/2;
self->Vel.Z *= 1.5;
}
return 0;
}
@ -172,19 +168,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_VolcanoBlast)
int i;
int count;
AActor *blast;
angle_t angle;
count = 1 + (pr_blast() % 3);
for (i = 0; i < count; i++)
{
blast = Spawn("VolcanoBlast", self->PosPlusZ(44*FRACUNIT), ALLOW_REPLACE);
blast = Spawn("VolcanoBlast", self->PosPlusZ(44.), ALLOW_REPLACE);
blast->target = self;
angle = pr_blast () << 24;
blast->angle = angle;
angle >>= ANGLETOFINESHIFT;
blast->vel.x = FixedMul (1*FRACUNIT, finecosine[angle]);
blast->vel.y = FixedMul (1*FRACUNIT, finesine[angle]);
blast->vel.z = (FRACUNIT*5/2) + (pr_blast() << 10);
blast->Angles.Yaw = pr_blast() * (360 / 256.);
blast->VelFromAngle(1.);
blast->Vel.Z = 2.5 + pr_blast() / 64.;
S_Sound (blast, CHAN_BODY, "world/volcano/shoot", 1, ATTN_NORM);
P_CheckMissileSpawn (blast, self->radius);
}
@ -203,26 +195,22 @@ DEFINE_ACTION_FUNCTION(AActor, A_VolcBallImpact)
unsigned int i;
AActor *tiny;
angle_t angle;
if (self->Z() <= self->floorz)
{
self->flags |= MF_NOGRAVITY;
self->gravity = FRACUNIT;
self->AddZ(28*FRACUNIT);
//self->vel.z = 3*FRACUNIT;
self->Gravity = 1;
self->AddZ(28);
//self->Vel.Z = 3;
}
P_RadiusAttack (self, self->target, 25, 25, NAME_Fire, RADF_HURTSOURCE);
for (i = 0; i < 4; i++)
{
tiny = Spawn("VolcanoTBlast", self->Pos(), ALLOW_REPLACE);
tiny->target = self;
angle = i*ANG90;
tiny->angle = angle;
angle >>= ANGLETOFINESHIFT;
tiny->vel.x = FixedMul (FRACUNIT*7/10, finecosine[angle]);
tiny->vel.y = FixedMul (FRACUNIT*7/10, finesine[angle]);
tiny->vel.z = FRACUNIT + (pr_volcimpact() << 9);
tiny->Angles.Yaw = 90.*i;
tiny->VelFromAngle(0.7);
tiny->Vel.Z = 1. + pr_volcimpact() / 128.;
P_CheckMissileSpawn (tiny, self->radius);
}
return 0;

View file

@ -63,8 +63,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_StaffAttack)
{
PARAM_ACTION_PROLOGUE;
angle_t angle;
int slope;
DAngle angle;
DAngle slope;
player_t *player;
FTranslatedLineTarget t;
@ -86,15 +86,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_StaffAttack)
{
puff = PClass::FindActor(NAME_BulletPuff); // just to be sure
}
angle = self->angle;
angle += pr_sap.Random2() << 18;
angle = self->Angles.Yaw + pr_sap.Random2() * (5.625 / 256);
slope = P_AimLineAttack (self, angle, MELEERANGE);
P_LineAttack (self, angle, MELEERANGE, slope, damage, NAME_Melee, puff, true, &t);
if (t.linetarget)
{
//S_StartSound(player->mo, sfx_stfhit);
// turn to face target
self->angle = t.angleFromSource;
self->Angles.Yaw = t.angleFromSource;
}
return 0;
}
@ -110,7 +109,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireGoldWandPL1)
{
PARAM_ACTION_PROLOGUE;
angle_t angle;
DAngle angle;
int damage;
player_t *player;
@ -122,18 +121,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireGoldWandPL1)
AWeapon *weapon = player->ReadyWeapon;
if (weapon != NULL)
{
if (!weapon->DepleteAmmo (weapon->bAltFire))
if (!weapon->DepleteAmmo(weapon->bAltFire))
return 0;
}
angle_t pitch = P_BulletSlope(self);
damage = 7+(pr_fgw()&7);
angle = self->angle;
DAngle pitch = P_BulletSlope(self);
damage = 7 + (pr_fgw() & 7);
angle = self->Angles.Yaw;
if (player->refire)
{
angle += pr_fgw.Random2() << 18;
angle += pr_fgw.Random2() * (5.625 / 256);
}
P_LineAttack (self, angle, PLAYERMISSILERANGE, pitch, damage, NAME_Hitscan, "GoldWandPuff1");
S_Sound (self, CHAN_WEAPON, "weapons/wandhit", 1, ATTN_NORM);
P_LineAttack(self, angle, PLAYERMISSILERANGE, pitch, damage, NAME_Hitscan, "GoldWandPuff1");
S_Sound(self, CHAN_WEAPON, "weapons/wandhit", 1, ATTN_NORM);
return 0;
}
@ -148,9 +147,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireGoldWandPL2)
PARAM_ACTION_PROLOGUE;
int i;
angle_t angle;
DAngle angle;
int damage;
fixed_t vz;
double vz;
player_t *player;
if (NULL == (player = self->player))
@ -164,17 +163,17 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireGoldWandPL2)
if (!weapon->DepleteAmmo (weapon->bAltFire))
return 0;
}
angle_t pitch = P_BulletSlope(self);
vz = FixedMul (GetDefaultByName("GoldWandFX2")->Speed,
finetangent[FINEANGLES/4-((signed)pitch>>ANGLETOFINESHIFT)]);
P_SpawnMissileAngle (self, PClass::FindActor("GoldWandFX2"), self->angle-(ANG45/8), vz);
P_SpawnMissileAngle (self, PClass::FindActor("GoldWandFX2"), self->angle+(ANG45/8), vz);
angle = self->angle-(ANG45/8);
DAngle pitch = P_BulletSlope(self);
vz = -GetDefaultByName("GoldWandFX2")->Speed * pitch.TanClamped();
P_SpawnMissileAngle(self, PClass::FindActor("GoldWandFX2"), self->Angles.Yaw - (45. / 8), vz);
P_SpawnMissileAngle(self, PClass::FindActor("GoldWandFX2"), self->Angles.Yaw + (45. / 8), vz);
angle = self->Angles.Yaw - (45. / 8);
for(i = 0; i < 5; i++)
{
damage = 1+(pr_fgw2()&7);
P_LineAttack (self, angle, PLAYERMISSILERANGE, pitch, damage, NAME_Hitscan, "GoldWandPuff2");
angle += ((ANG45/8)*2)/4;
angle += ((45. / 8) * 2) / 4;
}
S_Sound (self, CHAN_WEAPON, "weapons/wandhit", 1, ATTN_NORM);
return 0;
@ -204,8 +203,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireCrossbowPL1)
return 0;
}
P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX1"));
P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX3"), self->angle-(ANG45/10));
P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX3"), self->angle+(ANG45/10));
P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX3"), self->Angles.Yaw - 4.5);
P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX3"), self->Angles.Yaw + 4.5);
return 0;
}
@ -233,10 +232,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireCrossbowPL2)
return 0;
}
P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX2"));
P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX2"), self->angle-(ANG45/10));
P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX2"), self->angle+(ANG45/10));
P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX3"), self->angle-(ANG45/5));
P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX3"), self->angle+(ANG45/5));
P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX2"), self->Angles.Yaw - 4.5);
P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX2"), self->Angles.Yaw + 4.5);
P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX3"), self->Angles.Yaw - 9.);
P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX3"), self->Angles.Yaw + 9.);
return 0;
}
@ -250,11 +249,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_GauntletAttack)
{
PARAM_ACTION_PROLOGUE;
angle_t angle;
DAngle Angle;
int damage;
int slope;
DAngle slope;
int randVal;
fixed_t dist;
double dist;
player_t *player;
PClassActor *pufftype;
FTranslatedLineTarget t;
@ -273,25 +272,25 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_GauntletAttack)
if (!weapon->DepleteAmmo (weapon->bAltFire))
return 0;
}
player->psprites[ps_weapon].sx = ((pr_gatk()&3)-2) * FRACUNIT;
player->psprites[ps_weapon].sy = WEAPONTOP + (pr_gatk()&3) * FRACUNIT;
angle = self->angle;
player->psprites[ps_weapon].sx = ((pr_gatk()&3)-2);
player->psprites[ps_weapon].sy = WEAPONTOP + (pr_gatk()&3);
Angle = self->Angles.Yaw;
if (power)
{
damage = pr_gatk.HitDice (2);
dist = 4*MELEERANGE;
angle += pr_gatk.Random2() << 17;
Angle += pr_gatk.Random2() * (2.8125 / 256);
pufftype = PClass::FindActor("GauntletPuff2");
}
else
{
damage = pr_gatk.HitDice (2);
dist = MELEERANGE+1;
angle += pr_gatk.Random2() << 18;
dist = SAWRANGE;
Angle += pr_gatk.Random2() * (5.625 / 256);
pufftype = PClass::FindActor("GauntletPuff1");
}
slope = P_AimLineAttack (self, angle, dist);
P_LineAttack (self, angle, dist, slope, damage, NAME_Melee, pufftype, false, &t, &actualdamage);
slope = P_AimLineAttack (self, Angle, dist);
P_LineAttack (self, Angle, dist, slope, damage, NAME_Melee, pufftype, false, &t, &actualdamage);
if (!t.linetarget)
{
if (pr_gatk() > 64)
@ -324,20 +323,22 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_GauntletAttack)
S_Sound (self, CHAN_AUTO, "weapons/gauntletshit", 1, ATTN_NORM);
}
// turn to face target
angle = t.angleFromSource;
if (angle-self->angle > ANG180)
DAngle angle = t.angleFromSource;
DAngle anglediff = deltaangle(self->Angles.Yaw, angle);
if (anglediff < 0.0)
{
if ((int)(angle-self->angle) < -ANG90/20)
self->angle = angle+ANG90/21;
if (anglediff < -4.5)
self->Angles.Yaw = angle + 90.0 / 21;
else
self->angle -= ANG90/20;
self->Angles.Yaw -= 4.5;
}
else
{
if (angle-self->angle > ANG90/20)
self->angle = angle-ANG90/21;
if (anglediff > 4.5)
self->Angles.Yaw = angle - 90.0 / 21;
else
self->angle += ANG90/20;
self->Angles.Yaw += 4.5;
}
self->flags |= MF_JUSTATTACKED;
return 0;
@ -387,7 +388,6 @@ int AMaceFX4::DoSpecialDamage (AActor *target, int damage, FName damagetype)
void FireMacePL1B (AActor *actor)
{
AActor *ball;
angle_t angle;
player_t *player;
if (NULL == (player = actor->player))
@ -401,16 +401,13 @@ void FireMacePL1B (AActor *actor)
if (!weapon->DepleteAmmo (weapon->bAltFire))
return;
}
ball = Spawn("MaceFX2", actor->PosPlusZ(28*FRACUNIT - actor->floorclip), ALLOW_REPLACE);
ball->vel.z = 2*FRACUNIT+/*((player->lookdir)<<(FRACBITS-5))*/
finetangent[FINEANGLES/4-(actor->pitch>>ANGLETOFINESHIFT)];
angle = actor->angle;
ball = Spawn("MaceFX2", actor->PosPlusZ(28 - actor->Floorclip), ALLOW_REPLACE);
ball->Vel.Z = 2 - player->mo->Angles.Pitch.TanClamped();
ball->target = actor;
ball->angle = angle;
ball->AddZ(2*finetangent[FINEANGLES/4-(actor->pitch>>ANGLETOFINESHIFT)]);
angle >>= ANGLETOFINESHIFT;
ball->vel.x = (actor->vel.x>>1) + FixedMul(ball->Speed, finecosine[angle]);
ball->vel.y = (actor->vel.y>>1) + FixedMul(ball->Speed, finesine[angle]);
ball->Angles.Yaw = actor->Angles.Yaw;
ball->AddZ(ball->Vel.Z);
ball->VelFromAngle();
ball->Vel += actor->Vel.XY()/2;
S_Sound (ball, CHAN_BODY, "weapons/maceshoot", 1, ATTN_NORM);
P_CheckMissileSpawn (ball, actor->radius);
}
@ -435,19 +432,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireMacePL1)
if (pr_maceatk() < 28)
{
FireMacePL1B (self);
FireMacePL1B(self);
return 0;
}
AWeapon *weapon = player->ReadyWeapon;
if (weapon != NULL)
{
if (!weapon->DepleteAmmo (weapon->bAltFire))
if (!weapon->DepleteAmmo(weapon->bAltFire))
return 0;
}
player->psprites[ps_weapon].sx = ((pr_maceatk()&3)-2)*FRACUNIT;
player->psprites[ps_weapon].sy = WEAPONTOP+(pr_maceatk()&3)*FRACUNIT;
ball = P_SpawnPlayerMissile (self, PClass::FindActor("MaceFX1"),
self->angle+(((pr_maceatk()&7)-4)<<24));
player->psprites[ps_weapon].sx = ((pr_maceatk() & 3) - 2);
player->psprites[ps_weapon].sy = WEAPONTOP + (pr_maceatk() & 3);
ball = P_SpawnPlayerMissile(self, PClass::FindActor("MaceFX1"), self->Angles.Yaw + (((pr_maceatk() & 7) - 4) * (360. / 256)));
if (ball)
{
ball->special1 = 16; // tics till dropoff
@ -476,21 +472,19 @@ DEFINE_ACTION_FUNCTION(AActor, A_MacePL1Check)
}
self->special1 = 0;
self->flags &= ~MF_NOGRAVITY;
self->gravity = FRACUNIT/8;
self->Gravity = 1. / 8;;
// [RH] Avoid some precision loss by scaling the velocity directly
#if 0
// This is the original code, for reference.
angle_t angle = self->angle>>ANGLETOFINESHIFT;
self->vel.x = FixedMul(7*FRACUNIT, finecosine[angle]);
self->vel.y = FixedMul(7*FRACUNIT, finesine[angle]);
a.ngle_t angle = self->angle>>ANGLETOF.INESHIFT;
self->velx = F.ixedMul(7*F.RACUNIT, f.inecosine[angle]);
self->vely = F.ixedMul(7*F.RACUNIT, f.inesine[angle]);
#else
double velscale = sqrt ((double)self->vel.x * (double)self->vel.x +
(double)self->vel.y * (double)self->vel.y);
velscale = 458752 / velscale;
self->vel.x = (int)(self->vel.x * velscale);
self->vel.y = (int)(self->vel.y * velscale);
double velscale = 7 / self->Vel.XY().Length();
self->Vel.X *= velscale;
self->Vel.Y *= velscale;
#endif
self->vel.z -= self->vel.z >> 1;
self->Vel.Z *= 0.5;
return 0;
}
@ -507,16 +501,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_MaceBallImpact)
if ((self->health != MAGIC_JUNK) && (self->flags & MF_INBOUNCE))
{ // Bounce
self->health = MAGIC_JUNK;
self->vel.z = (self->vel.z * 192) >> 8;
self->Vel.Z *= 0.75;
self->BounceFlags = BOUNCE_None;
self->SetState (self->SpawnState);
S_Sound (self, CHAN_BODY, "weapons/macebounce", 1, ATTN_NORM);
}
else
{ // Explode
self->vel.x = self->vel.y = self->vel.z = 0;
self->Vel.Zero();
self->flags |= MF_NOGRAVITY;
self->gravity = FRACUNIT;
self->Gravity = 1;
S_Sound (self, CHAN_BODY, "weapons/macehit", 1, ATTN_NORM);
}
return 0;
@ -533,7 +527,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_MaceBallImpact2)
PARAM_ACTION_PROLOGUE;
AActor *tiny;
angle_t angle;
if ((self->Z() <= self->floorz) && P_HitFloor (self))
{ // Landed in some sort of liquid
@ -542,42 +535,36 @@ DEFINE_ACTION_FUNCTION(AActor, A_MaceBallImpact2)
}
if (self->flags & MF_INBOUNCE)
{
if (self->vel.z < 2*FRACUNIT)
if (self->Vel.Z < 2)
{
goto boom;
}
// Bounce
self->vel.z = (self->vel.z * 192) >> 8;
self->Vel.Z *= 0.75;
self->SetState (self->SpawnState);
tiny = Spawn("MaceFX3", self->Pos(), ALLOW_REPLACE);
angle = self->angle+ANG90;
tiny->target = self->target;
tiny->angle = angle;
angle >>= ANGLETOFINESHIFT;
tiny->vel.x = (self->vel.x>>1) + FixedMul(self->vel.z-FRACUNIT, finecosine[angle]);
tiny->vel.y = (self->vel.y>>1) + FixedMul(self->vel.z-FRACUNIT, finesine[angle]);
tiny->vel.z = self->vel.z;
tiny->Angles.Yaw = self->Angles.Yaw + 90.;
tiny->VelFromAngle(self->Vel.Z - 1.);
tiny->Vel += { self->Vel.X * .5, self->Vel.Y * .5, self->Vel.Z };
P_CheckMissileSpawn (tiny, self->radius);
tiny = Spawn("MaceFX3", self->Pos(), ALLOW_REPLACE);
angle = self->angle-ANG90;
tiny->target = self->target;
tiny->angle = angle;
angle >>= ANGLETOFINESHIFT;
tiny->vel.x = (self->vel.x>>1) + FixedMul(self->vel.z-FRACUNIT, finecosine[angle]);
tiny->vel.y = (self->vel.y>>1) + FixedMul(self->vel.z-FRACUNIT, finesine[angle]);
tiny->vel.z = self->vel.z;
tiny->Angles.Yaw = self->Angles.Yaw - 90.;
tiny->VelFromAngle(self->Vel.Z - 1.);
tiny->Vel += { self->Vel.X * .5, self->Vel.Y * .5, self->Vel.Z };
P_CheckMissileSpawn (tiny, self->radius);
}
else
{ // Explode
boom:
self->vel.x = self->vel.y = self->vel.z = 0;
self->Vel.Zero();
self->flags |= MF_NOGRAVITY;
self->BounceFlags = BOUNCE_None;
self->gravity = FRACUNIT;
self->Gravity = 1;
}
return 0;
}
@ -607,13 +594,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireMacePL2)
if (!weapon->DepleteAmmo (weapon->bAltFire))
return 0;
}
mo = P_SpawnPlayerMissile (self, 0,0,0, RUNTIME_CLASS(AMaceFX4), self->angle, &t);
mo = P_SpawnPlayerMissile (self, 0,0,0, RUNTIME_CLASS(AMaceFX4), self->Angles.Yaw, &t);
if (mo)
{
mo->vel.x += self->vel.x;
mo->vel.y += self->vel.y;
mo->vel.z = 2*FRACUNIT+
clamp<fixed_t>(finetangent[FINEANGLES/4-(self->pitch>>ANGLETOFINESHIFT)], -5*FRACUNIT, 5*FRACUNIT);
mo->Vel += self->Vel.XY();
mo->Vel.Z = 2 - player->mo->Angles.Pitch.TanClamped();
if (t.linetarget && !t.unlinked)
{
mo->tracer = t.linetarget;
@ -635,7 +620,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_DeathBallImpact)
int i;
AActor *target;
angle_t angle = 0;
DAngle angle = 0.;
bool newAngle;
FTranslatedLineTarget t;
@ -646,7 +631,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_DeathBallImpact)
}
if (self->flags & MF_INBOUNCE)
{
if (self->vel.z < 2*FRACUNIT)
if (self->Vel.Z < 2)
{
goto boom;
}
@ -668,10 +653,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_DeathBallImpact)
}
else
{ // Find new target
angle = 0;
angle = 0.;
for (i = 0; i < 16; i++)
{
P_AimLineAttack (self, angle, 10*64*FRACUNIT, &t, 0, ALF_NOFRIENDS|ALF_PORTALRESTRICT, NULL, self->target);
P_AimLineAttack (self, angle, 640., &t, 0., ALF_NOFRIENDS|ALF_PORTALRESTRICT, NULL, self->target);
if (t.linetarget && self->target != t.linetarget)
{
self->tracer = t.linetarget;
@ -679,15 +664,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_DeathBallImpact)
newAngle = true;
break;
}
angle += ANGLE_45/2;
angle += 22.5;
}
}
if (newAngle)
{
self->angle = angle;
angle >>= ANGLETOFINESHIFT;
self->vel.x = FixedMul (self->Speed, finecosine[angle]);
self->vel.y = FixedMul (self->Speed, finesine[angle]);
self->Angles.Yaw = angle;
self->VelFromAngle();
}
self->SetState (self->SpawnState);
S_Sound (self, CHAN_BODY, "weapons/macestop", 1, ATTN_NORM);
@ -695,9 +678,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_DeathBallImpact)
else
{ // Explode
boom:
self->vel.x = self->vel.y = self->vel.z = 0;
self->Vel.Zero();
self->flags |= MF_NOGRAVITY;
self->gravity = FRACUNIT;
self->Gravity = 1;
S_Sound (self, CHAN_BODY, "weapons/maceexplode", 1, ATTN_NORM);
}
return 0;
@ -737,7 +720,7 @@ void ABlasterFX1::Effect ()
{
if (pr_bfx1t() < 64)
{
Spawn("BlasterSmoke", X(), Y(), MAX<fixed_t> (Z() - 8 * FRACUNIT, floorz), ALLOW_REPLACE);
Spawn("BlasterSmoke", PosAtZ(MAX(Z() - 8., floorz)), ALLOW_REPLACE);
}
}
@ -778,7 +761,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireBlasterPL1)
{
PARAM_ACTION_PROLOGUE;
angle_t angle;
DAngle angle;
int damage;
player_t *player;
@ -793,12 +776,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireBlasterPL1)
if (!weapon->DepleteAmmo (weapon->bAltFire))
return 0;
}
angle_t pitch = P_BulletSlope(self);
DAngle pitch = P_BulletSlope(self);
damage = pr_fb1.HitDice (4);
angle = self->angle;
angle = self->Angles.Yaw;
if (player->refire)
{
angle += pr_fb1.Random2() << 18;
angle += pr_fb1.Random2() * (5.625 / 256);
}
P_LineAttack (self, angle, PLAYERMISSILERANGE, pitch, damage, NAME_Hitscan, "BlasterPuff");
S_Sound (self, CHAN_WEAPON, "weapons/blastershoot", 1, ATTN_NORM);
@ -816,18 +799,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpawnRippers)
PARAM_ACTION_PROLOGUE;
unsigned int i;
angle_t angle;
DAngle angle;
AActor *ripper;
for(i = 0; i < 8; i++)
{
ripper = Spawn<ARipper> (self->Pos(), ALLOW_REPLACE);
angle = i*ANG45;
angle = i*45.;
ripper->target = self->target;
ripper->angle = angle;
angle >>= ANGLETOFINESHIFT;
ripper->vel.x = FixedMul (ripper->Speed, finecosine[angle]);
ripper->vel.y = FixedMul (ripper->Speed, finesine[angle]);
ripper->Angles.Yaw = angle;
ripper->VelFromAngle();
P_CheckMissileSpawn (ripper, self->radius);
}
return 0;
@ -955,7 +936,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireSkullRodPL2)
if (!weapon->DepleteAmmo (weapon->bAltFire))
return 0;
}
P_SpawnPlayerMissile (self, 0,0,0, RUNTIME_CLASS(AHornRodFX2), self->angle, &t, &MissileActor);
P_SpawnPlayerMissile (self, 0,0,0, RUNTIME_CLASS(AHornRodFX2), self->Angles.Yaw, &t, &MissileActor);
// Use MissileActor instead of the return value from
// P_SpawnPlayerMissile because we need to give info to the mobj
// even if it exploded immediately.
@ -1071,10 +1052,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_SkullRodStorm)
{ // Fudge rain frequency
return 0;
}
fixedvec2 pos = self->Vec2Offset(
((pr_storm()&127) - 64) * FRACUNIT,
((pr_storm()&127) - 64) * FRACUNIT);
mo = Spawn<ARainPillar> (pos.x, pos.y, ONCEILINGZ, ALLOW_REPLACE);
double xo = ((pr_storm() & 127) - 64);
double yo = ((pr_storm() & 127) - 64);
DVector3 pos = self->Vec2OffsetZ(xo, yo, ONCEILINGZ);
mo = Spawn<ARainPillar> (pos, ALLOW_REPLACE);
// We used bouncecount to store the 3D floor index in A_HideInCeiling
if (!mo) return 0;
if (mo->Sector->PortalGroup != self->Sector->PortalGroup)
@ -1083,19 +1064,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_SkullRodStorm)
mo->Destroy();
return 0;
}
fixed_t newz;
if (self->bouncecount >= 0 && (unsigned)self->bouncecount < self->Sector->e->XFloor.ffloors.Size())
newz = self->Sector->e->XFloor.ffloors[self->bouncecount]->bottom.plane->ZatPoint(mo);// - 40 * FRACUNIT;
pos.Z = self->Sector->e->XFloor.ffloors[self->bouncecount]->bottom.plane->ZatPoint(mo);
else
newz = self->Sector->ceilingplane.ZatPoint(mo);
int moceiling = P_Find3DFloor(NULL, pos.x, pos.y, newz, false, false, newz);
if (moceiling >= 0)
mo->SetZ(newz - mo->height, false);
mo->Translation = multiplayer ?
TRANSLATION(TRANSLATION_RainPillar,self->special2) : 0;
pos.Z = self->Sector->ceilingplane.ZatPoint(mo);
int moceiling = P_Find3DFloor(NULL, pos, false, false, pos.Z);
if (moceiling >= 0) mo->SetZ(pos.Z - mo->Height);
mo->Translation = multiplayer ? TRANSLATION(TRANSLATION_RainPillar,self->special2) : 0;
mo->target = self->target;
mo->vel.x = 1; // Force collision detection
mo->vel.z = -mo->Speed;
mo->Vel.X = MinVel; // Force collision detection
mo->Vel.Z = -mo->Speed;
mo->special2 = self->special2; // Transfer player number
P_CheckMissileSpawn (mo, self->radius);
if (self->special1 != -1 && !S_IsActorPlayingSomething (self, CHAN_BODY, -1))
@ -1136,21 +1114,21 @@ DEFINE_ACTION_FUNCTION(AActor, A_HideInCeiling)
PARAM_ACTION_PROLOGUE;
// We use bouncecount to store the 3D floor index
fixed_t foo;
for (unsigned int i=0; i< self->Sector->e->XFloor.ffloors.Size(); i++)
double foo;
for (int i = self->Sector->e->XFloor.ffloors.Size() - 1; i >= 0; i--)
{
F3DFloor * rover = self->Sector->e->XFloor.ffloors[i];
if(!(rover->flags & FF_SOLID) || !(rover->flags & FF_EXISTS)) continue;
if ((foo = rover->bottom.plane->ZatPoint(self)) >= (self->Top()))
if (!(rover->flags & FF_SOLID) || !(rover->flags & FF_EXISTS)) continue;
if ((foo = rover->bottom.plane->ZatPoint(self)) >= self->Top())
{
self->SetZ(foo + 4*FRACUNIT, false);
self->SetZ(foo + 4, false);
self->bouncecount = i;
return 0;
}
}
self->bouncecount = -1;
self->SetZ(self->ceilingz + 4*FRACUNIT, false);
self->SetZ(self->ceilingz + 4, false);
return 0;
}
@ -1237,7 +1215,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_FirePhoenixPL1)
{
PARAM_ACTION_PROLOGUE;
angle_t angle;
player_t *player;
if (NULL == (player = self->player))
@ -1252,10 +1229,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FirePhoenixPL1)
return 0;
}
P_SpawnPlayerMissile (self, RUNTIME_CLASS(APhoenixFX1));
angle = self->angle + ANG180;
angle >>= ANGLETOFINESHIFT;
self->vel.x += FixedMul (4*FRACUNIT, finecosine[angle]);
self->vel.y += FixedMul (4*FRACUNIT, finesine[angle]);
self->Thrust(self->Angles.Yaw + 180, 4);
return 0;
}
@ -1270,22 +1244,17 @@ DEFINE_ACTION_FUNCTION(AActor, A_PhoenixPuff)
PARAM_ACTION_PROLOGUE;
AActor *puff;
angle_t angle;
DAngle angle;
//[RH] Heretic never sets the target for seeking
//P_SeekerMissile (self, ANGLE_1*5, ANGLE_1*10);
//P_SeekerMissile (self, 5, 10);
puff = Spawn("PhoenixPuff", self->Pos(), ALLOW_REPLACE);
angle = self->angle + ANG90;
angle >>= ANGLETOFINESHIFT;
puff->vel.x = FixedMul (FRACUNIT*13/10, finecosine[angle]);
puff->vel.y = FixedMul (FRACUNIT*13/10, finesine[angle]);
puff->vel.z = 0;
angle = self->Angles.Yaw + 90;
puff->Vel = DVector3(angle.ToVector(1.3), 0);
puff = Spawn("PhoenixPuff", self->Pos(), ALLOW_REPLACE);
angle = self->angle - ANG90;
angle >>= ANGLETOFINESHIFT;
puff->vel.x = FixedMul (FRACUNIT*13/10, finecosine[angle]);
puff->vel.y = FixedMul (FRACUNIT*13/10, finesine[angle]);
puff->vel.z = 0;
angle = self->Angles.Yaw - 90;
puff->Vel = DVector3(angle.ToVector(1.3), 0);
return 0;
}
@ -1323,9 +1292,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_FirePhoenixPL2)
PARAM_ACTION_PROLOGUE;
AActor *mo;
angle_t angle;
fixed_t slope;
double slope;
FSoundID soundid;
player_t *player;
APhoenixRod *flamethrower;
@ -1345,20 +1313,19 @@ DEFINE_ACTION_FUNCTION(AActor, A_FirePhoenixPL2)
S_StopSound (self, CHAN_WEAPON);
return 0;
}
angle = self->angle;
fixed_t xo = (pr_fp2.Random2() << 9);
fixed_t yo = (pr_fp2.Random2() << 9);
fixedvec3 pos = self->Vec3Offset(xo, yo,
26*FRACUNIT + finetangent[FINEANGLES/4-(self->pitch>>ANGLETOFINESHIFT)] - self->floorclip);
slope = -self->Angles.Pitch.TanClamped();
double xo = pr_fp2.Random2() / 128.;
double yo = pr_fp2.Random2() / 128.;
DVector3 pos = self->Vec3Offset(xo, yo, 26 + slope - self->Floorclip);
slope = finetangent[FINEANGLES/4-(self->pitch>>ANGLETOFINESHIFT)] + (FRACUNIT/10);
slope += 0.1;
mo = Spawn("PhoenixFX2", pos, ALLOW_REPLACE);
mo->target = self;
mo->angle = angle;
mo->vel.x = self->vel.x + FixedMul (mo->Speed, finecosine[angle>>ANGLETOFINESHIFT]);
mo->vel.y = self->vel.y + FixedMul (mo->Speed, finesine[angle>>ANGLETOFINESHIFT]);
mo->vel.z = FixedMul (mo->Speed, slope);
mo->Angles.Yaw = self->Angles.Yaw;
mo->VelFromAngle();
mo->Vel += self->Vel.XY();
mo->Vel.Z = mo->Speed * slope;
if (!player->refire || !S_IsActorPlayingSomething (self, CHAN_WEAPON, -1))
{
S_Sound (self, CHAN_WEAPON|CHAN_LOOP, soundid, 1, ATTN_NORM);
@ -1403,7 +1370,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FlameEnd)
{
PARAM_ACTION_PROLOGUE;
self->vel.z += FRACUNIT*3/2;
self->Vel.Z += 1.5;
return 0;
}
@ -1417,7 +1384,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FloatPuff)
{
PARAM_ACTION_PROLOGUE;
self->vel.z += FRACUNIT*18/10;
self->Vel.Z += 1.8;
return 0;
}

View file

@ -30,9 +30,9 @@ int AWhirlwind::DoSpecialDamage (AActor *target, int damage, FName damagetype)
if (!(target->flags7 & MF7_DONTTHRUST))
{
target->angle += pr_foo.Random2() << 20;
target->vel.x += pr_foo.Random2() << 10;
target->vel.y += pr_foo.Random2() << 10;
target->Angles.Yaw += pr_foo.Random2() * (360 / 4096.);
target->Vel.X += pr_foo.Random2() / 64.;
target->Vel.Y += pr_foo.Random2() / 64.;
}
if ((level.time & 16) && !(target->flags2 & MF2_BOSS) && !(target->flags7 & MF7_DONTTHRUST))
@ -42,10 +42,10 @@ int AWhirlwind::DoSpecialDamage (AActor *target, int damage, FName damagetype)
{
randVal = 160;
}
target->vel.z += randVal << 11;
if (target->vel.z > 12*FRACUNIT)
target->Vel.Z += randVal / 32.;
if (target->Vel.Z > 12)
{
target->vel.z = 12*FRACUNIT;
target->Vel.Z = 12;
}
}
if (!(level.time & 7))
@ -73,7 +73,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_LichAttack)
int randAttack;
static const int atkResolve1[] = { 50, 150 };
static const int atkResolve2[] = { 150, 200 };
int dist;
// Ice ball (close 20% : far 60%)
// Fire column (close 40% : far 20%)
@ -93,7 +92,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LichAttack)
P_TraceBleed (newdam > 0 ? newdam : damage, target, self);
return 0;
}
dist = self->AproxDistance (target) > 8*64*FRACUNIT;
int dist = self->Distance2D(target) > 8 * 64;
randAttack = pr_atk ();
if (randAttack < atkResolve1[dist])
{ // Ice ball
@ -114,10 +113,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_LichAttack)
S_Sound (self, CHAN_BODY, "ironlich/attack1", 1, ATTN_NORM);
}
fire->target = baseFire->target;
fire->angle = baseFire->angle;
fire->vel.x = baseFire->vel.x;
fire->vel.y = baseFire->vel.y;
fire->vel.z = baseFire->vel.z;
fire->Angles.Yaw = baseFire->Angles.Yaw;
fire->Vel = baseFire->Vel;
fire->Damage = NULL;
fire->health = (i+1) * 2;
P_CheckMissileSpawn (fire, self->radius);
@ -129,7 +126,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LichAttack)
mo = P_SpawnMissile (self, target, RUNTIME_CLASS(AWhirlwind));
if (mo != NULL)
{
mo->AddZ(-32*FRACUNIT, false);
mo->AddZ(-32);
mo->tracer = target;
mo->health = 20*TICRATE; // Duration
S_Sound (self, CHAN_BODY, "ironlich/attack3", 1, ATTN_NORM);
@ -151,21 +148,21 @@ DEFINE_ACTION_FUNCTION(AActor, A_WhirlwindSeek)
self->health -= 3;
if (self->health < 0)
{
self->vel.x = self->vel.y = self->vel.z = 0;
self->SetState (self->FindState(NAME_Death));
self->Vel.Zero();
self->SetState(self->FindState(NAME_Death));
self->flags &= ~MF_MISSILE;
return 0;
}
if ((self->threshold -= 3) < 0)
{
self->threshold = 58 + (pr_seek() & 31);
S_Sound (self, CHAN_BODY, "ironlich/attack3", 1, ATTN_NORM);
S_Sound(self, CHAN_BODY, "ironlich/attack3", 1, ATTN_NORM);
}
if (self->tracer && self->tracer->flags&MF_SHADOW)
{
return 0;
}
P_SeekerMissile (self, ANGLE_1*10, ANGLE_1*30);
P_SeekerMissile(self, 10, 30);
return 0;
}
@ -180,19 +177,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_LichIceImpact)
PARAM_ACTION_PROLOGUE;
unsigned int i;
angle_t angle;
AActor *shard;
for (i = 0; i < 8; i++)
{
shard = Spawn("HeadFX2", self->Pos(), ALLOW_REPLACE);
angle = i*ANG45;
shard->target = self->target;
shard->angle = angle;
angle >>= ANGLETOFINESHIFT;
shard->vel.x = FixedMul (shard->Speed, finecosine[angle]);
shard->vel.y = FixedMul (shard->Speed, finesine[angle]);
shard->vel.z = -FRACUNIT*6/10;
shard->Angles.Yaw = i*45.;
shard->VelFromAngle();
shard->Vel.Z = -.6;
P_CheckMissileSpawn (shard, self->radius);
}
return 0;
@ -209,7 +202,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LichFireGrow)
PARAM_ACTION_PROLOGUE;
self->health--;
self->AddZ(9*FRACUNIT);
self->AddZ(9.);
if (self->health == 0)
{
self->Damage = self->GetDefault()->Damage;

View file

@ -25,12 +25,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_DripBlood)
AActor *mo;
fixed_t xo = (pr_dripblood.Random2() << 11);
fixed_t yo = (pr_dripblood.Random2() << 11);
mo = Spawn ("Blood", self->Vec3Offset(xo, yo, 0), ALLOW_REPLACE);
mo->vel.x = pr_dripblood.Random2 () << 10;
mo->vel.y = pr_dripblood.Random2 () << 10;
mo->gravity = FRACUNIT/8;
double xo = pr_dripblood.Random2() / 32.;
double yo = pr_dripblood.Random2() / 32.;
mo = Spawn ("Blood", self->Vec3Offset(xo, yo, 0.), ALLOW_REPLACE);
mo->Vel.X = pr_dripblood.Random2 () / 64.;
mo->Vel.Y = pr_dripblood.Random2() / 64.;
mo->Gravity = 1./8;
return 0;
}
@ -60,11 +60,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_KnightAttack)
S_Sound (self, CHAN_BODY, self->AttackSound, 1, ATTN_NORM);
if (self->flags & MF_SHADOW || pr_knightatk () < 40)
{ // Red axe
P_SpawnMissileZ (self, self->Z() + 36*FRACUNIT, self->target, PClass::FindActor("RedAxe"));
P_SpawnMissileZ (self, self->Z() + 36, self->target, PClass::FindActor("RedAxe"));
return 0;
}
// Green axe
P_SpawnMissileZ (self, self->Z() + 36*FRACUNIT, self->target, PClass::FindActor("KnightAxe"));
P_SpawnMissileZ (self, self->Z() + 36, self->target, PClass::FindActor("KnightAxe"));
return 0;
}

View file

@ -53,7 +53,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_WizAtk2)
PARAM_ACTION_PROLOGUE;
A_FaceTarget (self);
self->alpha = HR_SHADOW;
self->Alpha = HR_SHADOW;
self->RenderStyle = STYLE_Translucent;
self->flags3 |= MF3_GHOST;
return 0;
@ -88,8 +88,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_WizAtk3)
mo = P_SpawnMissile (self, self->target, fx);
if (mo != NULL)
{
P_SpawnMissileAngle(self, fx, mo->angle-(ANG45/8), mo->vel.z);
P_SpawnMissileAngle(self, fx, mo->angle+(ANG45/8), mo->vel.z);
P_SpawnMissileAngle(self, fx, mo->Angles.Yaw - 45. / 8, mo->Vel.Z);
P_SpawnMissileAngle(self, fx, mo->Angles.Yaw + 45. / 8, mo->Vel.Z);
}
return 0;
}

View file

@ -39,7 +39,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BatSpawn)
AActor *mo;
int delta;
angle_t angle;
DAngle angle;
// Countdown until next spawn
if (self->special1-- > 0) return 0;
@ -47,7 +47,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_BatSpawn)
delta = self->args[1];
if (delta==0) delta=1;
angle = self->angle + (((pr_batspawn()%delta)-(delta>>1))<<24);
angle = self->Angles.Yaw + (((pr_batspawn() % delta) - (delta >> 1)) * (360 / 256.));
mo = P_SpawnMissileAngle (self, PClass::FindActor("Bat"), angle, 0);
if (mo)
{
@ -64,7 +66,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BatMove)
{
PARAM_ACTION_PROLOGUE;
angle_t newangle;
DAngle newangle;
if (self->special2 < 0)
{
@ -74,17 +76,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_BatMove)
if (pr_batmove()<128)
{
newangle = self->angle + ANGLE_1*self->args[4];
newangle = self->Angles.Yaw + self->args[4];
}
else
{
newangle = self->angle - ANGLE_1*self->args[4];
newangle = self->Angles.Yaw - self->args[4];
}
// Adjust velocity vector to new direction
newangle >>= ANGLETOFINESHIFT;
self->vel.x = FixedMul (self->Speed, finecosine[newangle]);
self->vel.y = FixedMul (self->Speed, finesine[newangle]);
self->VelFromAngle(newangle, self->Speed);
if (pr_batmove()<15)
{
@ -92,7 +92,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BatMove)
}
// Handle Z movement
self->SetZ(self->target->Z() + 16*finesine[self->args[0] << BOBTOFINESHIFT]);
self->SetZ(self->target->Z() + 2 * BobSin(self->args[0]));
self->args[0] = (self->args[0]+3)&63;
return 0;
}

View file

@ -80,7 +80,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopMissileWeave)
{
PARAM_ACTION_PROLOGUE;
A_Weave(self, 2, 2, 2*FRACUNIT, FRACUNIT);
A_Weave(self, 2, 2, 2., 1.);
return 0;
}
@ -118,15 +118,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopDoBlur)
self->special1 = (pr_doblur() & 3) + 3; // Random number of blurs
if (pr_doblur() < 120)
{
P_ThrustMobj (self, self->angle + ANG90, 11*FRACUNIT);
self->Thrust(self->Angles.Yaw + 90, 11);
}
else if (pr_doblur() > 125)
{
P_ThrustMobj (self, self->angle - ANG90, 11*FRACUNIT);
self->Thrust(self->Angles.Yaw - 90, 11);
}
else
{ // Thrust forward
P_ThrustMobj (self, self->angle, 11*FRACUNIT);
self->Thrust(11);
}
S_Sound (self, CHAN_BODY, "BishopBlur", 1, ATTN_NORM);
return 0;
@ -146,8 +146,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopSpawnBlur)
if (!--self->special1)
{
self->vel.x = 0;
self->vel.y = 0;
self->Vel.X = self->Vel.Y = 0;
if (pr_sblur() > 96)
{
self->SetState (self->SeeState);
@ -160,7 +159,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopSpawnBlur)
mo = Spawn ("BishopBlur", self->Pos(), ALLOW_REPLACE);
if (mo)
{
mo->angle = self->angle;
mo->Angles.Yaw = self->Angles.Yaw;
}
return 0;
}
@ -175,9 +174,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopChase)
{
PARAM_ACTION_PROLOGUE;
fixed_t newz = self->Z() - finesine[self->special2 << BOBTOFINESHIFT] * 4;
double newz = self->Z() - BobSin(self->special2) / 2.;
self->special2 = (self->special2 + 4) & 63;
newz += finesine[self->special2 << BOBTOFINESHIFT] * 4;
newz += BobSin(self->special2) / 2.;
self->SetZ(newz);
return 0;
}
@ -194,10 +193,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopPuff)
AActor *mo;
mo = Spawn ("BishopPuff", self->PosPlusZ(40*FRACUNIT), ALLOW_REPLACE);
mo = Spawn ("BishopPuff", self->PosPlusZ(40.), ALLOW_REPLACE);
if (mo)
{
mo->vel.z = FRACUNIT/2;
mo->Vel.Z = -.5;
}
return 0;
}
@ -219,13 +218,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopPainBlur)
self->SetState (self->FindState ("Blur"));
return 0;
}
fixed_t xo = (pr_pain.Random2() << 12);
fixed_t yo = (pr_pain.Random2() << 12);
fixed_t zo = (pr_pain.Random2() << 11);
double xo = pr_pain.Random2() / 16.;
double yo = pr_pain.Random2() / 16.;
double zo = pr_pain.Random2() / 32.;
mo = Spawn ("BishopPainBlur", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE);
if (mo)
{
mo->angle = self->angle;
mo->Angles.Yaw = self->Angles.Yaw;
}
return 0;
}

View file

@ -9,8 +9,8 @@
*/
/* For reference, the default values:
#define BLAST_RADIUS_DIST 255*FRACUNIT
#define BLAST_SPEED 20*FRACUNIT
#define BLAST_RADIUS_DIST 255*F.RACUNIT
#define BLAST_SPEED 20*F.RACUNIT
#define BLAST_FULLSTRENGTH 255
*/
@ -22,11 +22,11 @@
//
//==========================================================================
void BlastActor (AActor *victim, fixed_t strength, fixed_t speed, AActor *Owner, PClassActor *blasteffect, bool dontdamage)
void BlastActor (AActor *victim, double strength, double speed, AActor *Owner, PClassActor *blasteffect, bool dontdamage)
{
angle_t angle,ang;
DAngle angle;
AActor *mo;
fixedvec3 pos;
DVector3 pos;
if (!victim->SpecialBlastHandling (Owner, strength))
{
@ -34,35 +34,33 @@ void BlastActor (AActor *victim, fixed_t strength, fixed_t speed, AActor *Owner,
}
angle = Owner->AngleTo(victim);
angle >>= ANGLETOFINESHIFT;
victim->vel.x = FixedMul (speed, finecosine[angle]);
victim->vel.y = FixedMul (speed, finesine[angle]);
DVector2 move = angle.ToVector(speed);
victim->Vel.X = move.X;
victim->Vel.Y = move.Y;
// Spawn blast puff
ang = victim->AngleTo(Owner);
ang >>= ANGLETOFINESHIFT;
angle -= 180.;
pos = victim->Vec3Offset(
FixedMul (victim->radius+FRACUNIT, finecosine[ang]),
FixedMul (victim->radius+FRACUNIT, finesine[ang]),
-victim->floorclip + (victim->height>>1));
(victim->radius + 1) * angle.Cos(),
(victim->radius + 1) * angle.Sin(),
(victim->Height / 2) - victim->Floorclip);
mo = Spawn (blasteffect, pos, ALLOW_REPLACE);
if (mo)
{
mo->vel.x = victim->vel.x;
mo->vel.y = victim->vel.y;
mo->Vel.X = victim->Vel.X;
mo->Vel.Y = victim->Vel.Y;
}
if (victim->flags & MF_MISSILE)
{
// [RH] Floor and ceiling huggers should not be blasted vertically.
if (!(victim->flags3 & (MF3_FLOORHUGGER|MF3_CEILINGHUGGER)))
{
victim->vel.z = 8*FRACUNIT;
mo->vel.z = victim->vel.z;
mo->Vel.Z = victim->Vel.Z = 8;
}
}
else
{
victim->vel.z = (1000 / victim->Mass) << FRACBITS;
victim->Vel.Z = 1000. / victim->Mass;
}
if (victim->player)
{
@ -99,15 +97,14 @@ DEFINE_ACTION_FUNCTION_PARAMS (AActor, A_Blast)
{
PARAM_ACTION_PROLOGUE;
PARAM_INT_OPT (blastflags) { blastflags = 0; }
PARAM_FIXED_OPT (strength) { strength = 255*FRACUNIT; }
PARAM_FIXED_OPT (radius) { radius = 255*FRACUNIT; }
PARAM_FIXED_OPT (speed) { speed = 20*FRACUNIT; }
PARAM_FLOAT_OPT (strength) { strength = 255; }
PARAM_FLOAT_OPT (radius) { radius = 255; }
PARAM_FLOAT_OPT (speed) { speed = 20; }
PARAM_CLASS_OPT (blasteffect, AActor) { blasteffect = PClass::FindActor("BlastEffect"); }
PARAM_SOUND_OPT (blastsound) { blastsound = "BlastRadius"; }
AActor *mo;
TThinkerIterator<AActor> iterator;
fixed_t dist;
if (self->player && (blastflags & BF_USEAMMO) && ACTION_CALL_FROM_WEAPON())
{
@ -146,8 +143,7 @@ DEFINE_ACTION_FUNCTION_PARAMS (AActor, A_Blast)
{ // Must be monster, player, missile, touchy or vulnerable
continue;
}
dist = self->AproxDistance (mo);
if (dist > radius)
if (self->Distance2D(mo) > radius)
{ // Out of range
continue;
}

View file

@ -29,7 +29,7 @@ bool AArtiBoostArmor::Use (bool pickup)
for (int i = 0; i < 4; ++i)
{
armor = Spawn<AHexenArmor> (0,0,0, NO_REPLACE);
armor = Spawn<AHexenArmor>();
armor->flags |= MF_DROPPED;
armor->health = i;
armor->Amount = 1;
@ -46,7 +46,7 @@ bool AArtiBoostArmor::Use (bool pickup)
}
else
{
ABasicArmorBonus *armor = Spawn<ABasicArmorBonus> (0,0,0, NO_REPLACE);
ABasicArmorBonus *armor = Spawn<ABasicArmorBonus>();
armor->flags |= MF_DROPPED;
armor->SaveAmount = 50;
armor->MaxSaveAmount = 300;

View file

@ -13,9 +13,8 @@
#include "thingdef/thingdef.h"
*/
const fixed_t FLAMESPEED = fixed_t(0.45*FRACUNIT);
const fixed_t CFLAMERANGE = 12*64*FRACUNIT;
const fixed_t FLAMEROTSPEED = 2*FRACUNIT;
const double FLAMESPEED = 0.45;
const double FLAMEROTSPEED = 2.;
static FRandom pr_missile ("CFlameMissile");
@ -43,20 +42,18 @@ void ACFlameMissile::BeginPlay ()
void ACFlameMissile::Effect ()
{
fixed_t newz;
if (!--special1)
{
special1 = 4;
newz = Z()-12*FRACUNIT;
double newz = Z() - 12;
if (newz < floorz)
{
newz = floorz;
}
AActor *mo = Spawn ("CFlameFloor", X(), Y(), newz, ALLOW_REPLACE);
AActor *mo = Spawn ("CFlameFloor", PosAtZ(newz), ALLOW_REPLACE);
if (mo)
{
mo->angle = angle;
mo->Angles.Yaw = Angles.Yaw;
}
}
}
@ -99,9 +96,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CFlamePuff)
PARAM_ACTION_PROLOGUE;
self->renderflags &= ~RF_INVISIBLE;
self->vel.x = 0;
self->vel.y = 0;
self->vel.z = 0;
self->Vel.Zero();
S_Sound (self, CHAN_BODY, "ClericFlameExplode", 1, ATTN_NORM);
return 0;
}
@ -117,8 +112,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_CFlameMissile)
PARAM_ACTION_PROLOGUE;
int i;
int an, an90;
fixed_t dist;
DAngle an;
double dist;
AActor *mo;
self->renderflags &= ~RF_INVISIBLE;
@ -126,33 +121,28 @@ DEFINE_ACTION_FUNCTION(AActor, A_CFlameMissile)
AActor *BlockingMobj = self->BlockingMobj;
if (BlockingMobj && BlockingMobj->flags&MF_SHOOTABLE)
{ // Hit something, so spawn the flame circle around the thing
dist = BlockingMobj->radius+18*FRACUNIT;
dist = BlockingMobj->radius + 18;
for (i = 0; i < 4; i++)
{
an = (i*ANG45)>>ANGLETOFINESHIFT;
an90 = (i*ANG45+ANG90)>>ANGLETOFINESHIFT;
mo = Spawn ("CircleFlame", BlockingMobj->Vec3Offset(
FixedMul(dist, finecosine[an]),
FixedMul(dist, finesine[an]),
5*FRACUNIT), ALLOW_REPLACE);
an = i*45.;
mo = Spawn ("CircleFlame", BlockingMobj->Vec3Angle(dist, an, 5), ALLOW_REPLACE);
if (mo)
{
mo->angle = an<<ANGLETOFINESHIFT;
mo->Angles.Yaw = an;
mo->target = self->target;
mo->vel.x = mo->special1 = FixedMul(FLAMESPEED, finecosine[an]);
mo->vel.y = mo->special2 = FixedMul(FLAMESPEED, finesine[an]);
mo->VelFromAngle(FLAMESPEED);
mo->specialf1 = mo->Vel.X;
mo->specialf2 = mo->Vel.Y;
mo->tics -= pr_missile()&3;
}
mo = Spawn ("CircleFlame", BlockingMobj->Vec3Offset(
-FixedMul(dist, finecosine[an]),
-FixedMul(dist, finesine[an]),
5*FRACUNIT), ALLOW_REPLACE);
mo = Spawn("CircleFlame", BlockingMobj->Vec3Angle(dist, an, 5), ALLOW_REPLACE);
if(mo)
{
mo->angle = ANG180+(an<<ANGLETOFINESHIFT);
mo->Angles.Yaw = an + 180.;
mo->target = self->target;
mo->vel.x = mo->special1 = FixedMul(-FLAMESPEED, finecosine[an]);
mo->vel.y = mo->special2 = FixedMul(-FLAMESPEED, finesine[an]);
mo->VelFromAngle(-FLAMESPEED);
mo->specialf1 = mo->Vel.X;
mo->specialf2 = mo->Vel.Y;
mo->tics -= pr_missile()&3;
}
}
@ -171,11 +161,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_CFlameRotate)
{
PARAM_ACTION_PROLOGUE;
int an;
DAngle an = self->Angles.Yaw + 90.;
self->VelFromAngle(an, FLAMEROTSPEED);
self->Vel += DVector2(self->specialf1, self->specialf2);
an = (self->angle+ANG90)>>ANGLETOFINESHIFT;
self->vel.x = self->special1+FixedMul(FLAMEROTSPEED, finecosine[an]);
self->vel.y = self->special2+FixedMul(FLAMEROTSPEED, finesine[an]);
self->angle += ANG90/15;
self->Angles.Yaw += 6.;
return 0;
}

View file

@ -63,7 +63,7 @@ IMPLEMENT_CLASS (ACWeapWraithverge)
IMPLEMENT_CLASS (AHolySpirit)
bool AHolySpirit::Slam (AActor *thing)
bool AHolySpirit::Slam(AActor *thing)
{
if (thing->flags&MF_SHOOTABLE && thing != target)
{
@ -91,14 +91,14 @@ bool AHolySpirit::Slam (AActor *thing)
// ghost burns out faster when attacking players/bosses
health -= 6;
}
P_DamageMobj (thing, this, target, dam, NAME_Melee);
P_DamageMobj(thing, this, target, dam, NAME_Melee);
if (pr_spiritslam() < 128)
{
Spawn ("HolyPuff", Pos(), ALLOW_REPLACE);
S_Sound (this, CHAN_WEAPON, "SpiritAttack", 1, ATTN_NORM);
Spawn("HolyPuff", Pos(), ALLOW_REPLACE);
S_Sound(this, CHAN_WEAPON, "SpiritAttack", 1, ATTN_NORM);
if (thing->flags3&MF3_ISMONSTER && pr_spiritslam() < 128)
{
thing->Howl ();
thing->Howl();
}
}
}
@ -110,7 +110,7 @@ bool AHolySpirit::Slam (AActor *thing)
return true;
}
bool AHolySpirit::SpecialBlastHandling (AActor *source, fixed_t strength)
bool AHolySpirit::SpecialBlastHandling (AActor *source, double strength)
{
if (tracer == source)
{
@ -133,7 +133,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_CHolyAttack2)
PARAM_ACTION_PROLOGUE;
int j;
int i;
AActor *mo;
for (j = 0; j < 4; j++)
@ -145,23 +144,24 @@ DEFINE_ACTION_FUNCTION(AActor, A_CHolyAttack2)
}
switch (j)
{ // float bob index
case 0:
mo->special2 = pr_holyatk2(8 << BOBTOFINESHIFT); // upper-left
mo->WeaveIndexZ = pr_holyatk2() & 7; // upper-left
break;
case 1:
mo->special2 = FINEANGLES/2 + pr_holyatk2(8 << BOBTOFINESHIFT); // upper-right
mo->WeaveIndexZ = 32 + (pr_holyatk2() & 7); // upper-right
break;
case 2:
mo->special2 = (FINEANGLES/2 + pr_holyatk2(8 << BOBTOFINESHIFT)) << 16; // lower-left
mo->WeaveIndexXY = 32 + (pr_holyatk2() & 7); // lower-left
break;
case 3:
i = pr_holyatk2(8 << BOBTOFINESHIFT);
mo->special2 = ((FINEANGLES/2 + i) << 16) + FINEANGLES/2 + pr_holyatk2(8 << BOBTOFINESHIFT);
mo->WeaveIndexXY = 32 + (pr_holyatk2() & 7);
mo->WeaveIndexZ = 32 + (pr_holyatk2() & 7);
break;
}
mo->SetZ(self->Z());
mo->angle = self->angle+(ANGLE_45+ANGLE_45/2)-ANGLE_45*j;
P_ThrustMobj(mo, mo->angle, mo->Speed);
mo->Angles.Yaw = self->Angles.Yaw + 67.5 - 45.*j;
mo->Thrust();
mo->target = self->target;
mo->args[0] = 10; // initial turn value
mo->args[1] = 0; // initial look angle
@ -225,7 +225,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CHolyAttack)
if (!weapon->DepleteAmmo (weapon->bAltFire))
return 0;
}
AActor *missile = P_SpawnPlayerMissile (self, 0,0,0, PClass::FindActor("HolyMissile"), self->angle, &t);
AActor *missile = P_SpawnPlayerMissile (self, 0,0,0, PClass::FindActor("HolyMissile"), self->Angles.Yaw, &t);
if (missile != NULL && !t.unlinked)
{
missile->tracer = t.linetarget;
@ -263,42 +263,41 @@ DEFINE_ACTION_FUNCTION(AActor, A_CHolyPalette)
//
//============================================================================
static void CHolyTailFollow (AActor *actor, fixed_t dist)
static void CHolyTailFollow(AActor *actor, double dist)
{
AActor *child;
int an;
fixed_t oldDistance, newDistance;
DAngle an;
double oldDistance, newDistance;
while (actor)
{
child = actor->tracer;
if (child)
{
an = actor->AngleTo(child) >> ANGLETOFINESHIFT;
oldDistance = child->AproxDistance (actor);
if (P_TryMove (child, actor->X()+FixedMul(dist, finecosine[an]),
actor->Y()+FixedMul(dist, finesine[an]), true))
an = actor->AngleTo(child);
oldDistance = child->Distance2D(actor);
if (P_TryMove(child, actor->Pos().XY() + an.ToVector(dist), true))
{
newDistance = child->AproxDistance (actor)-FRACUNIT;
if (oldDistance < FRACUNIT)
newDistance = child->Distance2D(actor) - 1;
if (oldDistance < 1)
{
if (child->Z() < actor->Z())
{
child->SetZ(actor->Z()-dist);
child->SetZ(actor->Z() - dist);
}
else
{
child->SetZ(actor->Z()+dist);
child->SetZ(actor->Z() + dist);
}
}
else
{
child->SetZ(actor->Z() + Scale (newDistance, child->Z()-actor->Z(), oldDistance));
child->SetZ(actor->Z() + (newDistance * (child->Z() - actor->Z()) / oldDistance));
}
}
}
actor = child;
dist -= FRACUNIT;
dist -= 1;
}
}
@ -341,13 +340,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_CHolyTail)
}
else
{
if (P_TryMove (self,
parent->X() - 14*finecosine[parent->angle>>ANGLETOFINESHIFT],
parent->Y() - 14*finesine[parent->angle>>ANGLETOFINESHIFT], true))
if (P_TryMove(self, parent->Vec2Angle(14., parent->Angles.Yaw, true), true))
{
self->SetZ(parent->Z()-5*FRACUNIT);
self->SetZ(parent->Z() - 5.);
}
CHolyTailFollow (self, 10*FRACUNIT);
CHolyTailFollow(self, 10);
}
return 0;
}
@ -377,34 +374,32 @@ static void CHolyFindTarget (AActor *actor)
// Similar to P_SeekerMissile, but seeks to a random Z on the target
//============================================================================
static void CHolySeekerMissile (AActor *actor, angle_t thresh, angle_t turnMax)
static void CHolySeekerMissile (AActor *actor, DAngle thresh, DAngle turnMax)
{
int dir;
int dist;
angle_t delta;
angle_t angle;
DAngle delta;
AActor *target;
fixed_t newZ;
fixed_t deltaZ;
double newZ;
double deltaZ;
target = actor->tracer;
if (target == NULL)
{
return;
}
if(!(target->flags&MF_SHOOTABLE)
|| (!(target->flags3&MF3_ISMONSTER) && !target->player))
if (!(target->flags&MF_SHOOTABLE)
|| (!(target->flags3&MF3_ISMONSTER) && !target->player))
{ // Target died/target isn't a player or creature
actor->tracer = NULL;
actor->flags &= ~(MF_NOCLIP|MF_SKULLFLY);
actor->flags &= ~(MF_NOCLIP | MF_SKULLFLY);
actor->flags |= MF_MISSILE;
CHolyFindTarget (actor);
CHolyFindTarget(actor);
return;
}
dir = P_FaceMobj (actor, target, &delta);
if (delta > thresh)
{
delta >>= 1;
delta /= 2;
if (delta > turnMax)
{
delta = turnMax;
@ -412,72 +407,36 @@ static void CHolySeekerMissile (AActor *actor, angle_t thresh, angle_t turnMax)
}
if (dir)
{ // Turn clockwise
actor->angle += delta;
actor->Angles.Yaw += delta;
}
else
{ // Turn counter clockwise
actor->angle -= delta;
actor->Angles.Yaw -= delta;
}
angle = actor->angle>>ANGLETOFINESHIFT;
actor->vel.x = FixedMul (actor->Speed, finecosine[angle]);
actor->vel.y = FixedMul (actor->Speed, finesine[angle]);
actor->VelFromAngle();
if (!(level.time&15)
|| actor->Z() > target->Top()
|| actor->Top() < target->Z())
{
newZ = target->Z()+((pr_holyseeker()*target->height)>>8);
newZ = target->Z() + ((pr_holyseeker()*target->Height) / 256.);
deltaZ = newZ - actor->Z();
if (abs(deltaZ) > 15*FRACUNIT)
if (fabs(deltaZ) > 15)
{
if (deltaZ > 0)
{
deltaZ = 15*FRACUNIT;
deltaZ = 15;
}
else
{
deltaZ = -15*FRACUNIT;
deltaZ = -15;
}
}
dist = actor->AproxDistance (target);
dist = dist / actor->Speed;
if (dist < 1)
{
dist = 1;
}
actor->vel.z = deltaZ / dist;
actor->Vel.Z = deltaZ / actor->DistanceBySpeed(target, actor->Speed);
}
return;
}
//============================================================================
//
// A_CHolyWeave
//
//============================================================================
void CHolyWeave (AActor *actor, FRandom &pr_random)
{
fixed_t newX, newY, newZ;
int weaveXY, weaveZ;
int angle;
weaveXY = actor->special2 >> 16;
weaveZ = actor->special2 & FINEMASK;
angle = (actor->angle + ANG90) >> ANGLETOFINESHIFT;
newX = actor->X() - FixedMul(finecosine[angle], finesine[weaveXY] * 32);
newY = actor->Y() - FixedMul(finesine[angle], finesine[weaveXY] * 32);
weaveXY = (weaveXY + pr_random(5 << BOBTOFINESHIFT)) & FINEMASK;
newX += FixedMul(finecosine[angle], finesine[weaveXY] * 32);
newY += FixedMul(finesine[angle], finesine[weaveXY] * 32);
P_TryMove(actor, newX, newY, true);
newZ = actor->Z();
newZ -= finesine[weaveZ] * 16;
weaveZ = (weaveZ + pr_random(5 << BOBTOFINESHIFT)) & FINEMASK;
newZ += finesine[weaveZ] * 16;
actor->SetZ(newZ);
actor->special2 = weaveZ + (weaveXY << 16);
}
//============================================================================
//
// A_CHolySeek
@ -491,23 +450,25 @@ DEFINE_ACTION_FUNCTION(AActor, A_CHolySeek)
self->health--;
if (self->health <= 0)
{
self->vel.x >>= 2;
self->vel.y >>= 2;
self->vel.z = 0;
self->Vel.X /= 4;
self->Vel.Y /= 4;
self->Vel.Z = 0;
self->SetState (self->FindState(NAME_Death));
self->tics -= pr_holyseek()&3;
return 0;
}
if (self->tracer)
{
CHolySeekerMissile (self, self->args[0]*ANGLE_1,
self->args[0]*ANGLE_1*2);
CHolySeekerMissile (self, (double)self->args[0], self->args[0]*2.);
if (!((level.time+7)&15))
{
self->args[0] = 5+(pr_holyseek()/20);
}
}
CHolyWeave (self, pr_holyweave);
int xyspeed = (pr_holyweave() % 5);
int zspeed = (pr_holyweave() % 5);
A_Weave(self, xyspeed, zspeed, 4., 2.);
return 0;
}
@ -546,7 +507,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ClericAttack)
if (!self->target) return 0;
AActor * missile = P_SpawnMissileZ (self, self->Z() + 40*FRACUNIT, self->target, PClass::FindActor ("HolyMissile"));
AActor * missile = P_SpawnMissileZ (self, self->Z() + 40., self->target, PClass::FindActor ("HolyMissile"));
if (missile != NULL) missile->tracer = NULL; // No initial target
S_Sound (self, CHAN_WEAPON, "HolySymbolFire", 1, ATTN_NORM);
return 0;

View file

@ -17,9 +17,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_CMaceAttack)
{
PARAM_ACTION_PROLOGUE;
angle_t angle;
DAngle angle;
int damage;
int slope;
DAngle slope;
int i;
player_t *player;
FTranslatedLineTarget t;
@ -36,7 +36,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CMaceAttack)
{
for (int j = 1; j >= -1; j -= 2)
{
angle = player->mo->angle + j*i*(ANG45 / 16);
angle = player->mo->Angles.Yaw + j*i*(45. / 16);
slope = P_AimLineAttack(player->mo, angle, 2 * MELEERANGE, &t);
if (t.linetarget)
{
@ -44,7 +44,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CMaceAttack)
if (t.linetarget != NULL)
{
AdjustPlayerAngle(player->mo, &t);
goto macedone;
return 0;
}
}
}
@ -52,9 +52,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_CMaceAttack)
// didn't find any creatures, so try to strike any walls
player->mo->weaponspecial = 0;
angle = player->mo->angle;
angle = player->mo->Angles.Yaw;
slope = P_AimLineAttack (player->mo, angle, MELEERANGE);
P_LineAttack (player->mo, angle, MELEERANGE, slope, damage, NAME_Melee, hammertime);
macedone:
return 0;
}

View file

@ -51,8 +51,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheck)
APlayerPawn *pmo;
int damage;
int newLife, max;
angle_t angle;
int slope;
DAngle angle;
DAngle slope;
int i;
player_t *player;
FTranslatedLineTarget t;
@ -72,14 +72,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheck)
{
for (int j = 1; j >= -1; j -= 2)
{
angle = pmo->angle + j*i*(ANG45 / 16);
slope = P_AimLineAttack(pmo, angle, fixed_t(1.5*MELEERANGE), &t, 0, ALF_CHECK3D);
angle = pmo->Angles.Yaw + j*i*(45. / 16);
slope = P_AimLineAttack(pmo, angle, 1.5 * MELEERANGE, &t, 0., ALF_CHECK3D);
if (t.linetarget)
{
P_LineAttack(pmo, angle, fixed_t(1.5*MELEERANGE), slope, damage, NAME_Melee, puff, false, &t);
P_LineAttack(pmo, angle, 1.5 * MELEERANGE, slope, damage, NAME_Melee, puff, false, &t);
if (t.linetarget != NULL)
{
pmo->angle = t.angleFromSource;
pmo->Angles.Yaw = t.angleFromSource;
if (((t.linetarget->player && (!t.linetarget->IsTeammate(pmo) || level.teamdamage != 0)) || t.linetarget->flags3&MF3_ISMONSTER)
&& (!(t.linetarget->flags2&(MF2_DORMANT | MF2_INVULNERABLE))))
{
@ -131,12 +131,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffAttack)
if (!weapon->DepleteAmmo (weapon->bAltFire))
return 0;
}
mo = P_SpawnPlayerMissile (self, RUNTIME_CLASS(ACStaffMissile), self->angle-(ANG45/15));
mo = P_SpawnPlayerMissile (self, RUNTIME_CLASS(ACStaffMissile), self->Angles.Yaw - 3.0);
if (mo)
{
mo->WeaveIndexXY = 32;
}
mo = P_SpawnPlayerMissile (self, RUNTIME_CLASS(ACStaffMissile), self->angle+(ANG45/15));
mo = P_SpawnPlayerMissile (self, RUNTIME_CLASS(ACStaffMissile), self->Angles.Yaw + 3.0);
if (mo)
{
mo->WeaveIndexXY = 0;
@ -155,7 +155,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffMissileSlither)
{
PARAM_ACTION_PROLOGUE;
A_Weave(self, 3, 0, FRACUNIT, 0);
A_Weave(self, 3, 0, 1., 0.);
return 0;
}

View file

@ -22,16 +22,15 @@ DECLARE_ACTION(A_DragonFlight)
//
//============================================================================
static void DragonSeek (AActor *actor, angle_t thresh, angle_t turnMax)
static void DragonSeek (AActor *actor, DAngle thresh, DAngle turnMax)
{
int dir;
int dist;
angle_t delta;
angle_t angle;
double dist;
DAngle delta;
AActor *target;
int i;
angle_t bestAngle;
angle_t angleToSpot, angleToTarget;
DAngle bestAngle;
DAngle angleToSpot, angleToTarget;
AActor *mo;
target = actor->tracer;
@ -42,7 +41,7 @@ static void DragonSeek (AActor *actor, angle_t thresh, angle_t turnMax)
dir = P_FaceMobj (actor, target, &delta);
if (delta > thresh)
{
delta >>= 1;
delta /= 2;
if (delta > turnMax)
{
delta = turnMax;
@ -50,30 +49,25 @@ static void DragonSeek (AActor *actor, angle_t thresh, angle_t turnMax)
}
if (dir)
{ // Turn clockwise
actor->angle += delta;
actor->Angles.Yaw += delta;
}
else
{ // Turn counter clockwise
actor->angle -= delta;
actor->Angles.Yaw -= delta;
}
angle = actor->angle>>ANGLETOFINESHIFT;
actor->vel.x = FixedMul (actor->Speed, finecosine[angle]);
actor->vel.y = FixedMul (actor->Speed, finesine[angle]);
dist = actor->AproxDistance (target) / actor->Speed;
actor->VelFromAngle();
dist = actor->DistanceBySpeed(target, actor->Speed);
if (actor->Top() < target->Z() ||
target->Top() < actor->Z())
{
if (dist < 1)
{
dist = 1;
}
actor->vel.z = (target->Z() - actor->Z())/dist;
actor->Vel.Z = (target->Z() - actor->Z()) / dist;
}
if (target->flags&MF_SHOOTABLE && pr_dragonseek() < 64)
{ // attack the destination mobj if it's attackable
AActor *oldTarget;
if (absangle(actor->angle - actor->AngleTo(target)) < ANGLE_45/2)
if (absangle(actor->Angles.Yaw, actor->AngleTo(target)) < 22.5)
{
oldTarget = actor->target;
actor->target = target;
@ -97,7 +91,7 @@ static void DragonSeek (AActor *actor, angle_t thresh, angle_t turnMax)
if (actor->target && pr_dragonseek() < 200)
{
AActor *bestActor = NULL;
bestAngle = ANGLE_MAX;
bestAngle = 360.;
angleToTarget = actor->AngleTo(actor->target);
for (i = 0; i < 5; i++)
{
@ -112,9 +106,10 @@ static void DragonSeek (AActor *actor, angle_t thresh, angle_t turnMax)
continue;
}
angleToSpot = actor->AngleTo(mo);
if (absangle(angleToSpot-angleToTarget) < bestAngle)
DAngle diff = absangle(angleToSpot, angleToTarget);
if (diff < bestAngle)
{
bestAngle = absangle(angleToSpot-angleToTarget);
bestAngle = diff;
bestActor = mo;
}
}
@ -182,9 +177,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_DragonFlight)
{
PARAM_ACTION_PROLOGUE;
angle_t angle;
DAngle angle;
DragonSeek (self, 4*ANGLE_1, 8*ANGLE_1);
DragonSeek (self, 4., 8.);
if (self->target)
{
if(!(self->target->flags&MF_SHOOTABLE))
@ -192,15 +187,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_DragonFlight)
self->target = NULL;
return 0;
}
angle = self->AngleTo(self->target);
if (absangle(self->angle-angle) < ANGLE_45/2 && self->CheckMeleeRange())
angle = absangle(self->Angles.Yaw, self->AngleTo(self->target));
if (angle <22.5 && self->CheckMeleeRange())
{
int damage = pr_dragonflight.HitDice (8);
int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee);
P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM);
}
else if (absangle(self->angle-angle) <= ANGLE_1*20)
else if (angle <= 20)
{
self->SetState (self->MissileState);
S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM);
@ -266,9 +261,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_DragonFX2)
delay = 16+(pr_dragonfx2()>>3);
for (i = 1+(pr_dragonfx2()&3); i; i--)
{
fixed_t xo = ((pr_dragonfx2() - 128) << 14);
fixed_t yo = ((pr_dragonfx2() - 128) << 14);
fixed_t zo = ((pr_dragonfx2() - 128) << 12);
double xo = (pr_dragonfx2() - 128) / 4.;
double yo = (pr_dragonfx2() - 128) / 4.;
double zo = (pr_dragonfx2() - 128) / 16.;
mo = Spawn ("DragonExplosion", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE);
if (mo)

View file

@ -13,7 +13,7 @@
#include "thingdef/thingdef.h"
*/
#define AXERANGE ((fixed_t)(2.25*MELEERANGE))
#define AXERANGE (2.25 * MELEERANGE)
static FRandom pr_axeatk ("FAxeAtk");
@ -199,10 +199,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeAttack)
{
PARAM_ACTION_PROLOGUE;
angle_t angle;
fixed_t power;
DAngle angle;
int power;
int damage;
int slope;
DAngle slope;
int i;
int useMana;
player_t *player;
@ -223,7 +223,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeAttack)
if (player->ReadyWeapon->Ammo1->Amount > 0)
{
damage <<= 1;
power = 6*FRACUNIT;
power = 6;
pufftype = PClass::FindActor ("AxePuffGlow");
useMana = 1;
}
@ -236,7 +236,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeAttack)
{
for (int j = 1; j >= -1; j -= 2)
{
angle = pmo->angle + j*i*(ANG45 / 16);
angle = pmo->Angles.Yaw + j*i*(45. / 16);
slope = P_AimLineAttack(pmo, angle, AXERANGE, &t);
if (t.linetarget)
{
@ -245,7 +245,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeAttack)
{
if (t.linetarget->flags3&MF3_ISMONSTER || t.linetarget->player)
{
P_ThrustMobj(t.linetarget, t.angleFromSource, power);
t.linetarget->Thrust(t.angleFromSource, power);
}
AdjustPlayerAngle(pmo, &t);
useMana++;
@ -257,7 +257,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeAttack)
// didn't find any creatures, so try to strike any walls
pmo->weaponspecial = 0;
angle = pmo->angle;
angle = pmo->Angles.Yaw;
slope = P_AimLineAttack (pmo, angle, MELEERANGE);
P_LineAttack (pmo, angle, MELEERANGE, slope, damage, NAME_Melee, pufftype, true);

View file

@ -13,7 +13,7 @@
#include "thingdef/thingdef.h"
*/
const fixed_t HAMMER_RANGE = MELEERANGE+MELEERANGE/2;
const double HAMMER_RANGE = 1.5 * MELEERANGE;
static FRandom pr_hammeratk ("FHammerAtk");
@ -27,10 +27,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_FHammerAttack)
{
PARAM_ACTION_PROLOGUE;
angle_t angle;
DAngle angle;
int damage;
fixed_t power;
int slope;
DAngle slope;
int i;
player_t *player;
FTranslatedLineTarget t;
@ -43,46 +42,32 @@ DEFINE_ACTION_FUNCTION(AActor, A_FHammerAttack)
AActor *pmo=player->mo;
damage = 60+(pr_hammeratk()&63);
power = 10*FRACUNIT;
hammertime = PClass::FindActor("HammerPuff");
for (i = 0; i < 16; i++)
{
angle = pmo->angle + i*(ANG45/32);
slope = P_AimLineAttack (pmo, angle, HAMMER_RANGE, &t, 0, ALF_CHECK3D);
if (t.linetarget != NULL)
for (int j = 1; j >= -1; j -= 2)
{
P_LineAttack(pmo, angle, HAMMER_RANGE, slope, damage, NAME_Melee, hammertime, true, &t);
angle = pmo->Angles.Yaw + j*i*(45. / 32);
slope = P_AimLineAttack(pmo, angle, HAMMER_RANGE, &t, 0., ALF_CHECK3D);
if (t.linetarget != NULL)
{
AdjustPlayerAngle(pmo, &t);
if (t.linetarget->flags3 & MF3_ISMONSTER || t.linetarget->player)
P_LineAttack(pmo, angle, HAMMER_RANGE, slope, damage, NAME_Melee, hammertime, true, &t);
if (t.linetarget != NULL)
{
P_ThrustMobj(t.linetarget, t.angleFromSource, power);
AdjustPlayerAngle(pmo, &t);
if (t.linetarget->flags3 & MF3_ISMONSTER || t.linetarget->player)
{
t.linetarget->Thrust(t.angleFromSource, 10);
}
pmo->weaponspecial = false; // Don't throw a hammer
goto hammerdone;
}
pmo->weaponspecial = false; // Don't throw a hammer
goto hammerdone;
}
}
angle = pmo->angle-i*(ANG45/32);
slope = P_AimLineAttack(pmo, angle, HAMMER_RANGE, &t, 0, ALF_CHECK3D);
if (t.linetarget != NULL)
{
P_LineAttack(pmo, angle, HAMMER_RANGE, slope, damage, NAME_Melee, hammertime, true, &t);
if (t.linetarget != NULL)
{
AdjustPlayerAngle(pmo, &t);
if (t.linetarget->flags3 & MF3_ISMONSTER || t.linetarget->player)
{
P_ThrustMobj(t.linetarget, t.angleFromSource, power);
}
pmo->weaponspecial = false; // Don't throw a hammer
goto hammerdone;
}
}
}
// didn't find any targets in meleerange, so set to throw out a hammer
angle = pmo->angle;
slope = P_AimLineAttack (pmo, angle, HAMMER_RANGE, NULL, 0, ALF_CHECK3D);
angle = pmo->Angles.Yaw;
slope = P_AimLineAttack (pmo, angle, HAMMER_RANGE, NULL, 0., ALF_CHECK3D);
if (P_LineAttack (pmo, angle, HAMMER_RANGE, slope, damage, NAME_Melee, hammertime, true) != NULL)
{
pmo->weaponspecial = false;

View file

@ -23,29 +23,25 @@ static FRandom pr_fpatk ("FPunchAttack");
//
//============================================================================
#define MAX_ANGLE_ADJUST (5*ANGLE_1)
#define MAX_ANGLE_ADJUST (5.)
void AdjustPlayerAngle (AActor *pmo, FTranslatedLineTarget *t)
{
angle_t angle;
int difference;
angle = pmo->AngleTo(t->linetarget);
difference = (int)angle - (int)pmo->angle;
if (abs(difference) > MAX_ANGLE_ADJUST)
DAngle difference = deltaangle(pmo->Angles.Yaw, pmo->AngleTo(t->linetarget));
if (fabs(difference) > MAX_ANGLE_ADJUST)
{
if (difference > 0)
{
pmo->angle += MAX_ANGLE_ADJUST;
pmo->Angles.Yaw += MAX_ANGLE_ADJUST;
}
else
{
pmo->angle -= MAX_ANGLE_ADJUST;
pmo->Angles.Yaw -= MAX_ANGLE_ADJUST;
}
}
else
{
pmo->angle = angle;
pmo->Angles.Yaw = t->angleFromSource;
}
}
@ -57,11 +53,11 @@ void AdjustPlayerAngle (AActor *pmo, FTranslatedLineTarget *t)
//
//============================================================================
static bool TryPunch(APlayerPawn *pmo, angle_t angle, int damage, fixed_t power)
static bool TryPunch(APlayerPawn *pmo, DAngle angle, int damage, int power)
{
PClassActor *pufftype;
FTranslatedLineTarget t;
int slope;
DAngle slope;
slope = P_AimLineAttack (pmo, angle, 2*MELEERANGE, &t);
if (t.linetarget != NULL)
@ -82,7 +78,7 @@ static bool TryPunch(APlayerPawn *pmo, angle_t angle, int damage, fixed_t power)
if (t.linetarget->player != NULL ||
(t.linetarget->Mass != INT_MAX && (t.linetarget->flags3 & MF3_ISMONSTER)))
{
P_ThrustMobj (t.linetarget, t.angleFromSource, power);
t.linetarget->Thrust(t.angleFromSource, power);
}
AdjustPlayerAngle (pmo, &t);
return true;
@ -102,7 +98,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_FPunchAttack)
PARAM_ACTION_PROLOGUE;
int damage;
fixed_t power;
int i;
player_t *player;
@ -113,11 +108,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_FPunchAttack)
APlayerPawn *pmo = player->mo;
damage = 40+(pr_fpatk()&15);
power = 2*FRACUNIT;
for (i = 0; i < 16; i++)
{
if (TryPunch(pmo, pmo->angle + i*(ANG45/16), damage, power) ||
TryPunch(pmo, pmo->angle - i*(ANG45/16), damage, power))
if (TryPunch(pmo, pmo->Angles.Yaw + i*(45./16), damage, 2) ||
TryPunch(pmo, pmo->Angles.Yaw - i*(45./16), damage, 2))
{ // hit something
if (pmo->weaponspecial >= 3)
{
@ -131,7 +125,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FPunchAttack)
// didn't find any creatures, so try to strike any walls
pmo->weaponspecial = 0;
int slope = P_AimLineAttack (pmo, pmo->angle, MELEERANGE);
P_LineAttack (pmo, pmo->angle, MELEERANGE, slope, damage, NAME_Melee, PClass::FindActor("PunchPuff"), true);
DAngle slope = P_AimLineAttack (pmo, pmo->Angles.Yaw, MELEERANGE);
P_LineAttack (pmo, pmo->Angles.Yaw, MELEERANGE, slope, damage, NAME_Melee, PClass::FindActor("PunchPuff"), true);
return 0;
}

View file

@ -31,7 +31,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DropWeaponPieces)
PARAM_CLASS(p2, AActor);
PARAM_CLASS(p3, AActor);
for (int i = 0, j = 0, fineang = 0; i < 3; ++i)
for (int i = 0, j = 0; i < 3; ++i)
{
PClassActor *cls = j == 0 ? p1 : j == 1 ? p2 : p3;
if (cls)
@ -39,11 +39,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DropWeaponPieces)
AActor *piece = Spawn (cls, self->Pos(), ALLOW_REPLACE);
if (piece != NULL)
{
piece->vel.x = self->vel.x + finecosine[fineang];
piece->vel.y = self->vel.y + finesine[fineang];
piece->vel.z = self->vel.z;
piece->Vel = self->Vel + DAngle(i*120.).ToVector(1);
piece->flags |= MF_DROPPED;
fineang += FINEANGLES/3;
j = (j == 0) ? (pr_quietusdrop() & 1) + 1 : 3-j;
}
}
@ -95,11 +92,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_FSwordAttack)
if (!weapon->DepleteAmmo (weapon->bAltFire))
return 0;
}
P_SpawnPlayerMissile (self, 0, 0, -10*FRACUNIT, RUNTIME_CLASS(AFSwordMissile), self->angle+ANGLE_45/4);
P_SpawnPlayerMissile (self, 0, 0, -5*FRACUNIT, RUNTIME_CLASS(AFSwordMissile), self->angle+ANGLE_45/8);
P_SpawnPlayerMissile (self, 0, 0, 0, RUNTIME_CLASS(AFSwordMissile), self->angle);
P_SpawnPlayerMissile (self, 0, 0, 5*FRACUNIT, RUNTIME_CLASS(AFSwordMissile), self->angle-ANGLE_45/8);
P_SpawnPlayerMissile (self, 0, 0, 10*FRACUNIT, RUNTIME_CLASS(AFSwordMissile), self->angle-ANGLE_45/4);
P_SpawnPlayerMissile (self, 0, 0, -10, RUNTIME_CLASS(AFSwordMissile), self->Angles.Yaw + (45./4));
P_SpawnPlayerMissile (self, 0, 0, -5, RUNTIME_CLASS(AFSwordMissile), self->Angles.Yaw + (45./8));
P_SpawnPlayerMissile (self, 0, 0, 0, RUNTIME_CLASS(AFSwordMissile), self->Angles.Yaw);
P_SpawnPlayerMissile (self, 0, 0, 5, RUNTIME_CLASS(AFSwordMissile), self->Angles.Yaw - (45./8));
P_SpawnPlayerMissile (self, 0, 0, 10, RUNTIME_CLASS(AFSwordMissile), self->Angles.Yaw - (45./4));
S_Sound (self, CHAN_WEAPON, "FighterSwordFire", 1, ATTN_NORM);
return 0;
}
@ -118,9 +115,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_FSwordFlames)
for (i = 1+(pr_fswordflame()&3); i; i--)
{
fixed_t xo = ((pr_fswordflame() - 128) << 12);
fixed_t yo = ((pr_fswordflame() - 128) << 12);
fixed_t zo = ((pr_fswordflame() - 128) << 11);
double xo = (pr_fswordflame() - 128) / 16.;
double yo = (pr_fswordflame() - 128) / 16.;
double zo = (pr_fswordflame() - 128) / 8.;
Spawn ("FSwordFlame", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE);
}
return 0;
@ -138,13 +135,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_FighterAttack)
if (!self->target) return 0;
angle_t angle = self->angle;
P_SpawnMissileAngle (self, RUNTIME_CLASS(AFSwordMissile), angle+ANG45/4, 0);
P_SpawnMissileAngle (self, RUNTIME_CLASS(AFSwordMissile), angle+ANG45/8, 0);
P_SpawnMissileAngle (self, RUNTIME_CLASS(AFSwordMissile), angle, 0);
P_SpawnMissileAngle (self, RUNTIME_CLASS(AFSwordMissile), angle-ANG45/8, 0);
P_SpawnMissileAngle (self, RUNTIME_CLASS(AFSwordMissile), angle-ANG45/4, 0);
P_SpawnMissileAngle(self, RUNTIME_CLASS(AFSwordMissile), self->Angles.Yaw + (45. / 4), 0);
P_SpawnMissileAngle(self, RUNTIME_CLASS(AFSwordMissile), self->Angles.Yaw + (45. / 8), 0);
P_SpawnMissileAngle(self, RUNTIME_CLASS(AFSwordMissile), self->Angles.Yaw, 0);
P_SpawnMissileAngle(self, RUNTIME_CLASS(AFSwordMissile), self->Angles.Yaw - (45. / 8), 0);
P_SpawnMissileAngle(self, RUNTIME_CLASS(AFSwordMissile), self->Angles.Yaw - (45. / 4), 0);
S_Sound (self, CHAN_WEAPON, "FighterSwordFire", 1, ATTN_NORM);
return 0;
}

View file

@ -9,7 +9,7 @@
#include "thingdef/thingdef.h"
*/
#define FIREDEMON_ATTACK_RANGE 64*8*FRACUNIT
#define FIREDEMON_ATTACK_RANGE (64*8.)
static FRandom pr_firedemonrock ("FireDemonRock");
static FRandom pr_smbounce ("SMBounce");
@ -54,16 +54,16 @@ void A_FiredSpawnRock (AActor *actor)
break;
}
fixed_t xo = ((pr_firedemonrock() - 128) << 12);
fixed_t yo = ((pr_firedemonrock() - 128) << 12);
fixed_t zo = (pr_firedemonrock() << 11);
double xo = (pr_firedemonrock() - 128) / 16.;
double yo = (pr_firedemonrock() - 128) / 16.;
double zo = pr_firedemonrock() / 32.;
mo = Spawn (rtype, actor->Vec3Offset(xo, yo, zo), ALLOW_REPLACE);
if (mo)
{
mo->target = actor;
mo->vel.x = (pr_firedemonrock() - 128) <<10;
mo->vel.y = (pr_firedemonrock() - 128) <<10;
mo->vel.z = (pr_firedemonrock() << 10);
mo->Vel.X = (pr_firedemonrock() - 128) / 64.;
mo->Vel.Y = (pr_firedemonrock() - 128) / 64.;
mo->Vel.Z = (pr_firedemonrock() / 64.);
mo->special1 = 2; // Number bounces
}
@ -101,10 +101,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_SmBounce)
PARAM_ACTION_PROLOGUE;
// give some more velocity (x,y,&z)
self->SetZ(self->floorz + FRACUNIT);
self->vel.z = (2*FRACUNIT) + (pr_smbounce() << 10);
self->vel.x = pr_smbounce()%3<<FRACBITS;
self->vel.y = pr_smbounce()%3<<FRACBITS;
self->SetZ(self->floorz + 1);
self->Vel.Z = 2. + pr_smbounce() / 64.;
self->Vel.X = pr_smbounce() % 3;
self->Vel.Y = pr_smbounce() % 3;
return 0;
}
@ -137,20 +137,20 @@ DEFINE_ACTION_FUNCTION(AActor, A_FiredChase)
int weaveindex = self->special1;
AActor *target = self->target;
angle_t ang;
fixed_t dist;
DAngle ang;
double dist;
if (self->reactiontime) self->reactiontime--;
if (self->threshold) self->threshold--;
// Float up and down
self->AddZ(finesine[weaveindex << BOBTOFINESHIFT] * 8);
self->AddZ(BobSin(weaveindex));
self->special1 = (weaveindex + 2) & 63;
// Ensure it stays above certain height
if (self->Z() < self->floorz + (64*FRACUNIT))
if (self->Z() < self->floorz + 64)
{
self->AddZ(2*FRACUNIT);
self->AddZ(2);
}
if(!self->target || !(self->target->flags&MF_SHOOTABLE))
@ -167,20 +167,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_FiredChase)
else
{
self->special2 = 0;
self->vel.x = self->vel.y = 0;
dist = self->AproxDistance (target);
self->Vel.X = self->Vel.Y = 0;
dist = self->Distance2D(target);
if (dist < FIREDEMON_ATTACK_RANGE)
{
if (pr_firedemonchase() < 30)
{
ang = self->AngleTo(target);
if (pr_firedemonchase() < 128)
ang += ANGLE_90;
ang += 90;
else
ang -= ANGLE_90;
ang >>= ANGLETOFINESHIFT;
self->vel.x = finecosine[ang] << 3; //FixedMul (8*FRACUNIT, finecosine[ang]);
self->vel.y = finesine[ang] << 3; //FixedMul (8*FRACUNIT, finesine[ang]);
ang -= 90;
self->Thrust(ang, 8);
self->special2 = 3; // strafe time
}
}
@ -235,16 +233,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_FiredSplotch)
mo = Spawn ("FireDemonSplotch1", self->Pos(), ALLOW_REPLACE);
if (mo)
{
mo->vel.x = (pr_firedemonsplotch() - 128) << 11;
mo->vel.y = (pr_firedemonsplotch() - 128) << 11;
mo->vel.z = (pr_firedemonsplotch() << 10) + FRACUNIT*3;
mo->Vel.X = (pr_firedemonsplotch() - 128) / 32.;
mo->Vel.Y = (pr_firedemonsplotch() - 128) / 32.;
mo->Vel.Z = (pr_firedemonsplotch() / 64.) + 3;
}
mo = Spawn ("FireDemonSplotch2", self->Pos(), ALLOW_REPLACE);
if (mo)
{
mo->vel.x = (pr_firedemonsplotch() - 128) << 11;
mo->vel.y = (pr_firedemonsplotch() - 128) << 11;
mo->vel.z = (pr_firedemonsplotch() << 10) + FRACUNIT*3;
mo->Vel.X = (pr_firedemonsplotch() - 128) / 32.;
mo->Vel.Y = (pr_firedemonsplotch() - 128) / 32.;
mo->Vel.Z = (pr_firedemonsplotch() / 64.) + 3;
}
return 0;
}

View file

@ -39,13 +39,10 @@ IMPLEMENT_CLASS (AArtiPoisonBag1)
bool AArtiPoisonBag1::Use (bool pickup)
{
angle_t angle = Owner->angle >> ANGLETOFINESHIFT;
AActor *mo;
mo = Spawn ("PoisonBag", Owner->Vec3Offset(
16*finecosine[angle],
24*finesine[angle],
-Owner->floorclip+8*FRACUNIT), ALLOW_REPLACE);
AActor *mo = Spawn("PoisonBag", Owner->Vec3Offset(
16 * Owner->Angles.Yaw.Cos(),
24 * Owner->Angles.Yaw.Sin(),
-Owner->Floorclip + 8), ALLOW_REPLACE);
if (mo)
{
mo->target = Owner;
@ -67,13 +64,10 @@ IMPLEMENT_CLASS (AArtiPoisonBag2)
bool AArtiPoisonBag2::Use (bool pickup)
{
angle_t angle = Owner->angle >> ANGLETOFINESHIFT;
AActor *mo;
mo = Spawn ("FireBomb", Owner->Vec3Offset(
16*finecosine[angle],
24*finesine[angle],
-Owner->floorclip+8*FRACUNIT), ALLOW_REPLACE);
AActor *mo = Spawn("FireBomb", Owner->Vec3Offset(
16 * Owner->Angles.Yaw.Cos(),
24 * Owner->Angles.Yaw.Sin(),
-Owner->Floorclip + 8), ALLOW_REPLACE);
if (mo)
{
mo->target = Owner;
@ -97,14 +91,14 @@ bool AArtiPoisonBag3::Use (bool pickup)
{
AActor *mo;
mo = Spawn("ThrowingBomb", Owner->PosPlusZ(-Owner->floorclip+35*FRACUNIT + (Owner->player? Owner->player->crouchoffset : 0)), ALLOW_REPLACE);
mo = Spawn("ThrowingBomb", Owner->PosPlusZ(35. - Owner->Floorclip + (Owner->player? Owner->player->crouchoffset : 0)), ALLOW_REPLACE);
if (mo)
{
mo->angle = Owner->angle + (((pr_poisonbag()&7) - 4) << 24);
mo->Angles.Yaw = Owner->Angles.Yaw + (((pr_poisonbag() & 7) - 4) * (360./256.));
/* Original flight code from Hexen
* mo->momz = 4*FRACUNIT+((player->lookdir)<<(FRACBITS-4));
* mo->z += player->lookdir<<(FRACBITS-4);
* mo->momz = 4*F.RACUNIT+((player->lookdir)<<(F.RACBITS-4));
* mo->z += player->lookdir<<(F.RACBITS-4);
* P_ThrustMobj(mo, mo->angle, mo->info->speed);
* mo->momx += player->mo->momx>>1;
* mo->momy += player->mo->momy>>1;
@ -114,16 +108,16 @@ bool AArtiPoisonBag3::Use (bool pickup)
// is as set by the projectile. To accommodate this with a proper trajectory, we
// aim the projectile ~20 degrees higher than we're looking at and increase the
// speed we fire at accordingly.
angle_t orgpitch = angle_t(-Owner->pitch) >> ANGLETOFINESHIFT;
angle_t modpitch = angle_t(0xDC00000 - Owner->pitch) >> ANGLETOFINESHIFT;
angle_t angle = mo->angle >> ANGLETOFINESHIFT;
fixed_t speed = fixed_t(sqrt((double)mo->Speed*mo->Speed + (4.0*65536*4*65536)));
fixed_t xyscale = FixedMul(speed, finecosine[modpitch]);
DAngle orgpitch = -Owner->Angles.Pitch;
DAngle modpitch = clamp<DAngle>(-Owner->Angles.Pitch + 20, -89., 89.);
DAngle angle = mo->Angles.Yaw;
double speed = DVector2(mo->Speed, 4.).Length();
double xyscale = speed * modpitch.Cos();
mo->vel.z = FixedMul(speed, finesine[modpitch]);
mo->vel.x = FixedMul(xyscale, finecosine[angle]) + (Owner->vel.x >> 1);
mo->vel.y = FixedMul(xyscale, finesine[angle]) + (Owner->vel.y >> 1);
mo->AddZ(FixedMul(mo->Speed, finesine[orgpitch]));
mo->Vel.Z = speed * modpitch.Sin();
mo->Vel.X = xyscale * angle.Cos() + Owner->Vel.X / 2;
mo->Vel.Y = xyscale * angle.Sin() + Owner->Vel.Y / 2;
mo->AddZ(mo->Speed * orgpitch.Sin());
mo->target = Owner;
mo->tics -= pr_poisonbag()&3;
@ -265,7 +259,7 @@ AInventory *AArtiPoisonBag::CreateCopy (AActor *other)
AInventory *copy;
PClassActor *spawntype = GetFlechetteType(other);
copy = static_cast<AInventory *>(Spawn (spawntype, 0, 0, 0, NO_REPLACE));
copy = static_cast<AInventory *>(Spawn (spawntype));
copy->Amount = Amount;
copy->MaxAmount = MaxAmount;
GoAwayAndDie ();
@ -306,7 +300,7 @@ IMPLEMENT_CLASS (APoisonCloud)
void APoisonCloud::BeginPlay ()
{
vel.x = 1; // missile objects must move to impact other objects
Vel.X = MinVel; // missile objects must move to impact other objects
special1 = 24+(pr_poisoncloud()&7);
special2 = 0;
}
@ -324,7 +318,7 @@ int APoisonCloud::DoSpecialDamage (AActor *victim, int damage, FName damagetype)
}
else
{
dopoison = victim->player->poisoncount < (int)(4.f * level.teamdamage);
dopoison = victim->player->poisoncount < (int)(4. * level.teamdamage);
}
if (dopoison)
@ -332,7 +326,7 @@ int APoisonCloud::DoSpecialDamage (AActor *victim, int damage, FName damagetype)
int damage = 15 + (pr_poisoncloudd()&15);
if (mate)
{
damage = (int)((double)damage * level.teamdamage);
damage = (int)(damage * level.teamdamage);
}
// Handle passive damage modifiers (e.g. PowerProtection)
if (victim->Inventory != NULL)
@ -340,11 +334,7 @@ int APoisonCloud::DoSpecialDamage (AActor *victim, int damage, FName damagetype)
victim->Inventory->ModifyDamage(damage, damagetype, damage, true);
}
// Modify with damage factors
damage = FixedMul(damage, victim->DamageFactor);
if (damage > 0)
{
damage = DamageTypeDefinition::ApplyMobjDamageFactor(damage, damagetype, victim->GetClass()->DamageFactors);
}
damage = victim->ApplyDamageFactor(damagetype, damage);
if (damage > 0)
{
P_PoisonDamage (victim->player, this,
@ -376,7 +366,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_PoisonBagInit)
AActor *mo;
mo = Spawn<APoisonCloud> (self->PosPlusZ(28*FRACUNIT), ALLOW_REPLACE);
mo = Spawn<APoisonCloud> (self->PosPlusZ(28.), ALLOW_REPLACE);
if (mo)
{
mo->target = self->target;
@ -419,7 +409,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_PoisonBagDamage)
P_RadiusAttack (self, self->target, 4, 40, self->DamageType, RADF_HURTSOURCE);
bobIndex = self->special2;
self->AddZ(finesine[bobIndex << BOBTOFINESHIFT] >> 1);
self->AddZ(BobSin(bobIndex) / 16);
self->special2 = (bobIndex + 1) & 63;
return 0;
}
@ -452,15 +442,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_CheckThrowBomb2)
PARAM_ACTION_PROLOGUE;
// [RH] Check using actual velocity, although the vel.z < 2 check still stands
//if (abs(self->vel.x) < FRACUNIT*3/2 && abs(self->vel.y) < FRACUNIT*3/2
// && self->vel.z < 2*FRACUNIT)
if (self->vel.z < 2*FRACUNIT &&
TMulScale32 (self->vel.x, self->vel.x, self->vel.y, self->vel.y, self->vel.z, self->vel.z)
< (3*3)/(2*2))
if (self->Vel.Z < 2 && self->Vel.LengthSquared() < (9./4.))
{
self->SetState (self->SpawnState + 6);
self->SetZ(self->floorz);
self->vel.z = 0;
self->Vel.Z = 0;
self->BounceFlags = BOUNCE_None;
self->flags &= ~MF_MISSILE;
}

View file

@ -84,26 +84,24 @@ DEFINE_ACTION_FUNCTION(AActor, A_FlyBuzz)
return 0;
}
angle_t ang = self->AngleTo(targ);
self->angle = ang;
self->Angles.Yaw = self->AngleTo(targ);
self->args[0]++;
ang >>= ANGLETOFINESHIFT;
if (!P_TryMove(self, self->X() + 6 * finecosine[ang], self->Y() + 6 * finesine[ang], true))
if (!P_TryMove(self, self->Pos().XY() + self->Angles.Yaw.ToVector(6), true))
{
self->SetIdle(true);
return 0;
}
if (self->args[0] & 2)
{
self->vel.x += (pr_fly() - 128) << BOBTOFINESHIFT;
self->vel.y += (pr_fly() - 128) << BOBTOFINESHIFT;
self->Vel.X += (pr_fly() - 128) / 512.;
self->Vel.Y += (pr_fly() - 128) / 512.;
}
int zrand = pr_fly();
if (targ->Z() + 5*FRACUNIT < self->Z() && zrand > 150)
if (targ->Z() + 5. < self->Z() && zrand > 150)
{
zrand = -zrand;
}
self->vel.z = zrand << BOBTOFINESHIFT;
self->Vel.Z = zrand / 512.;
if (pr_fly() < 40)
{
S_Sound(self, CHAN_VOICE, self->ActiveSound, 0.5f, ATTN_STATIC);

View file

@ -15,7 +15,7 @@ static FRandom pr_fogspawn ("FogSpawn");
// args[3] Lifetime countdown
// args[4] Boolean: fog moving?
// special1 Internal: Counter for spawn frequency
// special2 Internal: Index into floatbob table
// WeaveIndexZ Internal: Index into floatbob table
//
//==========================================================================
@ -37,7 +37,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FogSpawn)
};
AActor *mo = NULL;
angle_t delta;
int delta;
if (self->special1-- > 0)
{
@ -51,13 +51,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_FogSpawn)
{
delta = self->args[1];
if (delta==0) delta=1;
mo->angle = self->angle + (((pr_fogspawn()%delta)-(delta>>1))<<24);
mo->Angles.Yaw = self->Angles.Yaw + (((pr_fogspawn() % delta) - (delta >> 1)) * (360 / 256.));
mo->target = self;
if (self->args[0] < 1) self->args[0] = 1;
mo->args[0] = (pr_fogspawn() % (self->args[0]))+1; // Random speed
mo->args[3] = self->args[3]; // Set lifetime
mo->args[4] = 1; // Set to moving
mo->special2 = pr_fogspawn()&63;
mo->WeaveIndexZ = pr_fogspawn()&63;
}
return 0;
}
@ -72,8 +72,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FogMove)
{
PARAM_ACTION_PROLOGUE;
int speed = self->args[0]<<FRACBITS;
angle_t angle;
double speed = self->args[0];
int weaveindex;
if (!self->args[4])
@ -89,14 +88,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_FogMove)
if ((self->args[3] % 4) == 0)
{
weaveindex = self->special2;
self->AddZ(finesine[weaveindex << BOBTOFINESHIFT] * 4);
self->special2 = (weaveindex + 1) & 63;
weaveindex = self->WeaveIndexZ;
self->AddZ(BobSin(weaveindex) / 2);
self->WeaveIndexZ = (weaveindex + 1) & 63;
}
angle = self->angle>>ANGLETOFINESHIFT;
self->vel.x = FixedMul(speed, finecosine[angle]);
self->vel.y = FixedMul(speed, finesine[angle]);
self->VelFromAngle(speed);
return 0;
}

View file

@ -12,7 +12,7 @@
#include "doomstat.h"
*/
#define HEAL_RADIUS_DIST 255*FRACUNIT
#define HEAL_RADIUS_DIST 255.
static FRandom pr_healradius ("HealRadius");
@ -42,7 +42,7 @@ bool AArtiHealingRadius::Use (bool pickup)
if (playeringame[i] &&
players[i].mo != NULL &&
players[i].mo->health > 0 &&
players[i].mo->AproxDistance (Owner) <= HEAL_RADIUS_DIST)
players[i].mo->Distance2D (Owner) <= HEAL_RADIUS_DIST)
{
// Q: Is it worth it to make this selectable as a player property?
// A: Probably not - but it sure doesn't hurt.
@ -52,7 +52,7 @@ bool AArtiHealingRadius::Use (bool pickup)
case NAME_Armor:
for (int j = 0; j < 4; ++j)
{
AHexenArmor *armor = Spawn<AHexenArmor> (0,0,0, NO_REPLACE);
AHexenArmor *armor = Spawn<AHexenArmor> ();
armor->health = j;
armor->Amount = 1;
if (!armor->CallTryPickup (players[i].mo))

View file

@ -16,7 +16,7 @@
// Sorcerer stuff
//
// Sorcerer Variables
// special1 Angle of ball 1 (all others relative to that)
// specialf1 Angle of ball 1 (all others relative to that)
// StopBall which ball to stop at in stop mode (MT_???)
// args[0] Defense time
// args[1] Number of full rotations since stopping mode
@ -24,7 +24,7 @@
// args[3] Movement mode (see SORC_ macros)
// args[4] Current ball orbit speed
// Sorcerer Ball Variables
// special1 Previous angle of ball (for woosh)
// specialf1 Previous angle of ball (for woosh)
// special2 Countdown of rapid fire (FX4)
//============================================================================
@ -45,9 +45,9 @@
#define SORC_NORMAL 5
#define SORC_FIRING_SPELL 6
#define BALL1_ANGLEOFFSET 0
#define BALL2_ANGLEOFFSET (ANGLE_MAX/3)
#define BALL3_ANGLEOFFSET ((ANGLE_MAX/3)*2)
#define BALL1_ANGLEOFFSET 0.
#define BALL2_ANGLEOFFSET 120.
#define BALL3_ANGLEOFFSET 240.
void A_SlowBalls (AActor *actor);
void A_StopBalls (AActor *actor);
@ -65,6 +65,7 @@ class AHeresiarch : public AActor
DECLARE_CLASS (AHeresiarch, AActor)
public:
const PClass *StopBall;
DAngle BallAngle;
void Serialize (FArchive &arc);
void Die (AActor *source, AActor *inflictor, int dmgflags);
@ -75,7 +76,7 @@ IMPLEMENT_CLASS (AHeresiarch)
void AHeresiarch::Serialize (FArchive &arc)
{
Super::Serialize (arc);
arc << StopBall;
arc << StopBall << BallAngle;
}
void AHeresiarch::Die (AActor *source, AActor *inflictor, int dmgflags)
@ -101,15 +102,16 @@ public:
virtual void DoFireSpell ();
virtual void SorcUpdateBallAngle ();
virtual void CastSorcererSpell ();
angle_t AngleOffset;
DAngle AngleOffset;
DAngle OldAngle;
void Serialize (FArchive &arc)
{
Super::Serialize (arc);
arc << AngleOffset;
arc << AngleOffset << OldAngle;
}
bool SpecialBlastHandling (AActor *source, fixed_t strength)
bool SpecialBlastHandling (AActor *source, double strength)
{ // don't blast sorcerer balls
return false;
}
@ -169,26 +171,6 @@ IMPLEMENT_CLASS (ASorcBall3)
// Sorcerer spell 1 (The burning, bouncing head thing) ----------------------
/*
class ASorcFX1 : public AActor
{
DECLARE_CLASS (ASorcFX1, AActor)
public:
bool FloorBounceMissile (secplane_t &plane)
{
fixed_t orgvelz = vel.z;
if (!Super::FloorBounceMissile (plane))
{
vel.z = -orgvelz; // no energy absorbed
return false;
}
return true;
}
};
IMPLEMENT_CLASS (ASorcFX1)
*/
//============================================================================
//
// SorcBall::DoFireSpell
@ -231,7 +213,7 @@ void ASorcBall1::DoFireSpell ()
DEFINE_ACTION_FUNCTION(AActor, A_SorcSpinBalls)
{
PARAM_ACTION_PROLOGUE;
PARAM_ACTION_PROLOGUE_TYPE(AHeresiarch);
AActor *mo;
@ -240,9 +222,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcSpinBalls)
self->args[0] = 0; // Currently no defense
self->args[3] = SORC_NORMAL;
self->args[4] = SORCBALL_INITIAL_SPEED; // Initial orbit speed
self->special1 = ANGLE_1;
self->BallAngle = 1.;
fixedvec3 pos = self->PosPlusZ(-self->floorclip + self->height);
DVector3 pos = self->PosPlusZ(-self->Floorclip + self->Height);
mo = Spawn("SorcBall1", pos, NO_REPLACE);
if (mo)
@ -262,11 +244,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcSpinBalls)
//
// A_SorcBallOrbit
//
// - actor is ball
//============================================================================
DEFINE_ACTION_FUNCTION(AActor, A_SorcBallOrbit)
{
PARAM_ACTION_PROLOGUE;
PARAM_ACTION_PROLOGUE_TYPE(ASorcBall);
// [RH] If no parent, then die instead of crashing
if (self->target == NULL)
@ -275,78 +258,78 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcBallOrbit)
return 0;
}
ASorcBall *actor;
angle_t angle, baseangle;
int mode = self->target->args[3];
AHeresiarch *parent = barrier_cast<AHeresiarch *>(self->target);
int dist = parent->radius - (self->radius<<1);
angle_t prevangle = self->special1;
double dist = parent->radius - (self->radius*2);
#if 0
// This cannot happen anymore because this is defined locally in SorcBall
if (!self->IsKindOf (RUNTIME_CLASS(ASorcBall)))
{
I_Error ("Corrupted sorcerer:\nTried to use a %s", self->GetClass()->TypeName.GetChars());
}
actor = static_cast<ASorcBall *> (self);
#endif
if (actor->target->health <= 0)
if (self->target->health <= 0)
{
actor->SetState (actor->FindState(NAME_Pain));
self->SetState (self->FindState(NAME_Pain));
return 0;
}
baseangle = (angle_t)parent->special1;
angle = baseangle + actor->AngleOffset;
actor->angle = angle;
angle >>= ANGLETOFINESHIFT;
DAngle prevangle = self->OldAngle;
DAngle baseangle = parent->BallAngle;
DAngle angle = baseangle + self->AngleOffset;
self->Angles.Yaw = angle;
switch (mode)
{
case SORC_NORMAL: // Balls rotating normally
actor->SorcUpdateBallAngle ();
self->SorcUpdateBallAngle ();
break;
case SORC_DECELERATE: // Balls decelerating
A_DecelBalls(actor);
actor->SorcUpdateBallAngle ();
A_DecelBalls(self);
self->SorcUpdateBallAngle ();
break;
case SORC_ACCELERATE: // Balls accelerating
A_AccelBalls(actor);
actor->SorcUpdateBallAngle ();
A_AccelBalls(self);
self->SorcUpdateBallAngle ();
break;
case SORC_STOPPING: // Balls stopping
if ((parent->StopBall == actor->GetClass()) &&
if ((parent->StopBall == self->GetClass()) &&
(parent->args[1] > SORCBALL_SPEED_ROTATIONS) &&
(absangle(angle - (parent->angle>>ANGLETOFINESHIFT)) < (30<<5)))
absangle(angle, parent->Angles.Yaw) < 42.1875)
{
// Can stop now
actor->target->args[3] = SORC_FIRESPELL;
actor->target->args[4] = 0;
self->target->args[3] = SORC_FIRESPELL;
self->target->args[4] = 0;
// Set angle so self angle == sorcerer angle
parent->special1 = (int)(parent->angle - actor->AngleOffset);
parent->BallAngle = parent->Angles.Yaw - self->AngleOffset;
}
else
{
actor->SorcUpdateBallAngle ();
self->SorcUpdateBallAngle ();
}
break;
case SORC_FIRESPELL: // Casting spell
if (parent->StopBall == actor->GetClass())
if (parent->StopBall == self->GetClass())
{
// Put sorcerer into special throw spell anim
if (parent->health > 0)
parent->SetState (parent->FindState("Attack1"));
actor->DoFireSpell ();
self->DoFireSpell ();
}
break;
case SORC_FIRING_SPELL:
if (parent->StopBall == actor->GetClass())
if (parent->StopBall == self->GetClass())
{
if (actor->special2-- <= 0)
if (self->special2-- <= 0)
{
// Done rapid firing
parent->args[3] = SORC_STOPPED;
@ -357,7 +340,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcBallOrbit)
else
{
// Do rapid fire spell
A_SorcOffense2(actor);
A_SorcOffense2(self);
}
}
break;
@ -367,21 +350,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcBallOrbit)
break;
}
if ((angle < prevangle) && (parent->args[4]==SORCBALL_TERMINAL_SPEED))
if (deltaangle(angle, prevangle) < 0 && (parent->args[4]==SORCBALL_TERMINAL_SPEED))
{
parent->args[1]++; // Bump rotation counter
// Completed full rotation - make woosh sound
S_Sound (actor, CHAN_BODY, "SorcererBallWoosh", 1, ATTN_NORM);
S_Sound (self, CHAN_BODY, "SorcererBallWoosh", 1, ATTN_NORM);
}
actor->special1 = angle; // Set previous angle
self->OldAngle = angle; // Set previous angle
fixedvec3 pos = parent->Vec3Offset(
FixedMul(dist, finecosine[angle]),
FixedMul(dist, finesine[angle]),
-parent->floorclip + parent->height);
actor->SetOrigin (pos, true);
actor->floorz = parent->floorz;
actor->ceilingz = parent->ceilingz;
DVector3 pos = parent->Vec3Angle(dist, angle, -parent->Floorclip + parent->Height);
self->SetOrigin (pos, true);
self->floorz = parent->floorz;
self->ceilingz = parent->ceilingz;
return 0;
}
@ -411,10 +391,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpeedBalls)
//
//============================================================================
void A_SlowBalls(AActor *actor)
void A_SlowBalls(AActor *self)
{
actor->args[3] = SORC_DECELERATE; // slow mode
actor->args[2] = SORCBALL_INITIAL_SPEED; // target speed
self->args[3] = SORC_DECELERATE; // slow mode
self->args[2] = SORCBALL_INITIAL_SPEED; // target speed
}
//============================================================================
@ -428,23 +408,23 @@ void A_SlowBalls(AActor *actor)
void A_StopBalls(AActor *scary)
{
AHeresiarch *actor = static_cast<AHeresiarch *> (scary);
AHeresiarch *self = static_cast<AHeresiarch *> (scary);
int chance = pr_heresiarch();
actor->args[3] = SORC_STOPPING; // stopping mode
actor->args[1] = 0; // Reset rotation counter
self->args[3] = SORC_STOPPING; // stopping mode
self->args[1] = 0; // Reset rotation counter
if ((actor->args[0] <= 0) && (chance < 200))
if ((self->args[0] <= 0) && (chance < 200))
{
actor->StopBall = RUNTIME_CLASS(ASorcBall2); // Blue
self->StopBall = RUNTIME_CLASS(ASorcBall2); // Blue
}
else if((actor->health < (actor->SpawnHealth() >> 1)) &&
else if((self->health < (self->SpawnHealth() >> 1)) &&
(chance < 200))
{
actor->StopBall = RUNTIME_CLASS(ASorcBall3); // Green
self->StopBall = RUNTIME_CLASS(ASorcBall3); // Green
}
else
{
actor->StopBall = RUNTIME_CLASS(ASorcBall1); // Yellow
self->StopBall = RUNTIME_CLASS(ASorcBall1); // Yellow
}
}
@ -456,9 +436,9 @@ void A_StopBalls(AActor *scary)
//
//============================================================================
void A_AccelBalls(AActor *actor)
void A_AccelBalls(AActor *self)
{
AActor *sorc = actor->target;
AActor *sorc = self->target;
if (sorc->args[4] < sorc->args[2])
{
@ -483,9 +463,9 @@ void A_AccelBalls(AActor *actor)
//
//============================================================================
void A_DecelBalls(AActor *actor)
void A_DecelBalls(AActor *self)
{
AActor *sorc = actor->target;
AActor *sorc = self->target;
if (sorc->args[4] > sorc->args[2])
{
@ -506,7 +486,7 @@ void A_DecelBalls(AActor *actor)
void ASorcBall1::SorcUpdateBallAngle ()
{
target->special1 += ANGLE_1*target->args[4];
barrier_cast<AHeresiarch*>(target)->BallAngle += target->args[4];
}
//============================================================================
@ -551,7 +531,7 @@ void ASorcBall2::CastSorcererSpell ()
AActor *parent = target;
AActor *mo;
mo = Spawn("SorcFX2", PosPlusZ(-parent->floorclip + SORC_DEFENSE_HEIGHT*FRACUNIT), ALLOW_REPLACE);
mo = Spawn("SorcFX2", PosPlusZ(parent->Floorclip + SORC_DEFENSE_HEIGHT), ALLOW_REPLACE);
parent->flags2 |= MF2_REFLECTIVE|MF2_INVULNERABLE;
parent->args[0] = SORC_DEFENSE_TIME;
if (mo) mo->target = parent;
@ -570,24 +550,24 @@ void ASorcBall3::CastSorcererSpell ()
Super::CastSorcererSpell ();
AActor *mo;
angle_t ang1, ang2;
DAngle ang1, ang2;
AActor *parent = target;
ang1 = angle - ANGLE_45;
ang2 = angle + ANGLE_45;
ang1 = Angles.Yaw.Degrees - 45;
ang2 = Angles.Yaw.Degrees + 45;
PClassActor *cls = PClass::FindActor("SorcFX3");
if (health < (SpawnHealth()/3))
{ // Spawn 2 at a time
mo = P_SpawnMissileAngle(parent, cls, ang1, 4*FRACUNIT);
mo = P_SpawnMissileAngle(parent, cls, ang1, 4.);
if (mo) mo->target = parent;
mo = P_SpawnMissileAngle(parent, cls, ang2, 4*FRACUNIT);
mo = P_SpawnMissileAngle(parent, cls, ang2, 4.);
if (mo) mo->target = parent;
}
else
{
if (pr_heresiarch() < 128)
ang1 = ang2;
mo = P_SpawnMissileAngle(parent, cls, ang1, 4*FRACUNIT);
mo = P_SpawnMissileAngle(parent, cls, ang1, 4.);
if (mo) mo->target = parent;
}
}
@ -596,12 +576,12 @@ void ASorcBall3::CastSorcererSpell ()
/*
void A_SpawnReinforcements(AActor *actor)
{
AActor *parent = actor->target;
AActor *parent = self->target;
AActor *mo;
angle_t ang;
DAngle ang;
ang = ANGLE_1 * P_Random();
mo = P_SpawnMissileAngle(actor, MT_SORCFX3, ang, 5*FRACUNIT);
ang = P_Random();
mo = P_SpawnMissileAngle(actor, MT_SORCFX3, ang, 5.);
if (mo) mo->target = parent;
}
*/
@ -619,11 +599,11 @@ void ASorcBall1::CastSorcererSpell ()
Super::CastSorcererSpell ();
AActor *mo;
angle_t ang1, ang2;
DAngle ang1, ang2;
AActor *parent = target;
ang1 = angle + ANGLE_1*70;
ang2 = angle - ANGLE_1*70;
ang1 = Angles.Yaw.Degrees + 70;
ang2 = Angles.Yaw.Degrees - 70;
PClassActor *cls = PClass::FindActor("SorcFX1");
mo = P_SpawnMissileAngle (parent, cls, ang1, 0);
if (mo)
@ -651,14 +631,15 @@ void ASorcBall1::CastSorcererSpell ()
//
//============================================================================
void A_SorcOffense2(AActor *actor)
void A_SorcOffense2(AActor *self)
{
angle_t ang1;
DAngle ang1;
AActor *mo;
int delta, index;
AActor *parent = actor->target;
double delta;
int index;
AActor *parent = self->target;
AActor *dest = parent->target;
int dist;
double dist;
// [RH] If no enemy, then don't try to shoot.
if (dest == NULL)
@ -666,18 +647,17 @@ void A_SorcOffense2(AActor *actor)
return;
}
index = actor->args[4] << 5;
actor->args[4] = (actor->args[4] + 15) & 255;
delta = (finesine[index])*SORCFX4_SPREAD_ANGLE;
delta = (delta>>FRACBITS)*ANGLE_1;
ang1 = actor->angle + delta;
index = self->args[4];
self->args[4] = (self->args[4] + 15) & 255;
delta = DAngle(index * (360 / 256.f)).Sin() * SORCFX4_SPREAD_ANGLE;
ang1 = self->Angles.Yaw + delta;
mo = P_SpawnMissileAngle(parent, PClass::FindActor("SorcFX4"), ang1, 0);
if (mo)
{
mo->special2 = 35*5/2; // 5 seconds
dist = mo->AproxDistance(dest) / mo->Speed;
if(dist < 1) dist = 1;
mo->vel.z = (dest->Z() - mo->Z()) / dist;
dist = mo->DistanceBySpeed(dest, mo->Speed);
mo->Vel.Z = (dest->Z() - mo->Z()) / dist;
}
}
@ -709,22 +689,21 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcBossAttack)
DEFINE_ACTION_FUNCTION(AActor, A_SpawnFizzle)
{
PARAM_ACTION_PROLOGUE;
fixed_t dist = 5*FRACUNIT;
fixed_t speed = self->Speed >> FRACBITS;
angle_t rangle;
int speed = (int)self->Speed;
DAngle rangle;
AActor *mo;
int ix;
fixedvec3 pos = self->Vec3Angle(dist, self->angle, -self->floorclip + (self->height >> 1));
DVector3 pos = self->Vec3Angle(5., self->Angles.Yaw, -self->Floorclip + self->Height / 2. );
for (ix=0; ix<5; ix++)
{
mo = Spawn("SorcSpark1", pos, ALLOW_REPLACE);
if (mo)
{
rangle = (self->angle >> ANGLETOFINESHIFT) + ((pr_heresiarch()%5) << 1);
mo->vel.x = FixedMul(pr_heresiarch()%speed, finecosine[rangle]);
mo->vel.y = FixedMul(pr_heresiarch()%speed, finesine[rangle]);
mo->vel.z = FRACUNIT*2;
rangle = self->Angles.Yaw + (pr_heresiarch() % 5) * (4096 / 360.);
mo->Vel.X = (pr_heresiarch() % speed) * rangle.Cos();
mo->Vel.Y = (pr_heresiarch() % speed) * rangle.Sin();
mo->Vel.Z = 2;
}
}
return 0;
@ -744,7 +723,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcFX1Seek)
PARAM_ACTION_PROLOGUE;
A_DoBounceCheck (self, "SorcererHeadScream");
P_SeekerMissile (self,ANGLE_1*2,ANGLE_1*6);
P_SeekerMissile(self, 2, 6);
return 0;
}
@ -758,7 +737,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcFX1Seek)
//============================================================================
//
// FX2 Variables
// special1 current angle
// specialf1 current angle
// special2
// args[0] 0 = CW, 1 = CCW
// args[1]
@ -776,7 +755,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcFX2Split)
{
mo->target = self->target;
mo->args[0] = 0; // CW
mo->special1 = self->angle; // Set angle
mo->specialf1 = self->Angles.Yaw.Degrees; // Set angle
mo->SetState (mo->FindState("Orbit"));
}
mo = Spawn(self->GetClass(), self->Pos(), NO_REPLACE);
@ -784,7 +763,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcFX2Split)
{
mo->target = self->target;
mo->args[0] = 1; // CCW
mo->special1 = self->angle; // Set angle
mo->specialf1 = self->Angles.Yaw.Degrees; // Set angle
mo->SetState (mo->FindState("Orbit"));
}
self->Destroy ();
@ -803,8 +782,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcFX2Orbit)
{
PARAM_ACTION_PROLOGUE;
angle_t angle;
fixedvec3 pos;
DAngle angle;
DVector3 pos;
AActor *parent = self->target;
// [RH] If no parent, then disappear
@ -814,7 +793,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcFX2Orbit)
return 0;
}
fixed_t dist = parent->radius;
double dist = parent->radius;
if ((parent->health <= 0) || // Sorcerer is dead
(!parent->args[0])) // Time expired
@ -835,25 +814,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcFX2Orbit)
// Move to new position based on angle
if (self->args[0]) // Counter clock-wise
{
self->special1 += ANGLE_1*10;
angle = ((angle_t)self->special1) >> ANGLETOFINESHIFT;
pos = parent->Vec3Offset(
FixedMul(dist, finecosine[angle]),
FixedMul(dist, finesine[angle]),
parent->floorclip + SORC_DEFENSE_HEIGHT*FRACUNIT);
pos.z += FixedMul(15*FRACUNIT,finecosine[angle]);
self->specialf1 += 10;
angle = self->specialf1;
pos = parent->Vec3Angle(dist, angle, parent->Floorclip + SORC_DEFENSE_HEIGHT);
pos.Z += 15 * angle.Cos();
// Spawn trailer
Spawn("SorcFX2T1", pos, ALLOW_REPLACE);
}
else // Clock wise
{
self->special1 -= ANGLE_1*10;
angle = ((angle_t)self->special1) >> ANGLETOFINESHIFT;
pos = parent->Vec3Offset(
FixedMul(dist, finecosine[angle]),
FixedMul(dist, finesine[angle]),
parent->floorclip + SORC_DEFENSE_HEIGHT*FRACUNIT);
pos.z += FixedMul(20*FRACUNIT,finesine[angle]);
self->specialf1 -= 10;
pos = parent->Vec3Angle(dist, angle, parent->Floorclip + SORC_DEFENSE_HEIGHT);
pos.Z += 20 * angle.Sin();
// Spawn trailer
Spawn("SorcFX2T1", pos, ALLOW_REPLACE);
}
@ -943,11 +915,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcBallPop)
S_Sound (self, CHAN_BODY, "SorcererBallPop", 1, ATTN_NONE);
self->flags &= ~MF_NOGRAVITY;
self->gravity = FRACUNIT/8;
self->vel.x = ((pr_heresiarch()%10)-5) << FRACBITS;
self->vel.y = ((pr_heresiarch()%10)-5) << FRACBITS;
self->vel.z = (2+(pr_heresiarch()%3)) << FRACBITS;
self->special2 = 4*FRACUNIT; // Initial bounce factor
self->Gravity = 1. / 8;;
self->Vel.X = ((pr_heresiarch()%10)-5);
self->Vel.Y = ((pr_heresiarch()%10)-5);
self->Vel.Z = (2+(pr_heresiarch()%3));
self->args[4] = BOUNCE_TIME_UNIT; // Bounce time unit
self->args[3] = 5; // Bounce time in seconds
return 0;

View file

@ -10,7 +10,7 @@ class AHolySpirit : public AActor
DECLARE_CLASS (AHolySpirit, AActor)
public:
bool Slam (AActor *thing);
bool SpecialBlastHandling (AActor *source, fixed_t strength);
bool SpecialBlastHandling (AActor *source, double strength);
};
class AFighterWeapon : public AWeapon

View file

@ -66,9 +66,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_PotteryExplode)
if (mo)
{
mo->SetState (mo->SpawnState + (pr_pottery()%5));
mo->vel.z = ((pr_pottery()&7)+5)*(3*FRACUNIT/4);
mo->vel.x = (pr_pottery.Random2())<<(FRACBITS-6);
mo->vel.y = (pr_pottery.Random2())<<(FRACBITS-6);
mo->Vel.X = pr_pottery.Random2() / 64.;
mo->Vel.Y = pr_pottery.Random2() / 64.;
mo->Vel.Z = ((pr_pottery() & 7) + 5) * 0.75;
}
}
S_Sound (mo, CHAN_BODY, "PotteryExplode", 1, ATTN_NORM);
@ -117,7 +117,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_PotteryCheck)
if (playeringame[i])
{
AActor *pmo = players[i].mo;
if (P_CheckSight (self, pmo) && (absangle(pmo->AngleTo(self) - pmo->angle) <= ANGLE_45))
if (P_CheckSight (self, pmo) && (absangle(pmo->AngleTo(self), pmo->Angles.Yaw) <= 45))
{ // Previous state (pottery bit waiting state)
self->SetState (self->state - 1);
return 0;
@ -141,7 +141,7 @@ IMPLEMENT_CLASS (AZCorpseLynchedNoHeart)
void AZCorpseLynchedNoHeart::PostBeginPlay ()
{
Super::PostBeginPlay ();
Spawn ("BloodPool", X(), Y(), floorz, ALLOW_REPLACE);
Spawn ("BloodPool", PosAtZ(floorz), ALLOW_REPLACE);
}
//============================================================================
@ -156,7 +156,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CorpseBloodDrip)
if (pr_drip() <= 128)
{
Spawn ("CorpseBloodDrip", self->PosPlusZ(self->height/2), ALLOW_REPLACE);
Spawn ("CorpseBloodDrip", self->PosPlusZ(self->Height / 2), ALLOW_REPLACE);
}
return 0;
}
@ -180,9 +180,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_CorpseExplode)
if (mo)
{
mo->SetState (mo->SpawnState + (pr_foo()%3));
mo->vel.z = ((pr_foo()&7)+5)*(3*FRACUNIT/4);
mo->vel.x = pr_foo.Random2()<<(FRACBITS-6);
mo->vel.y = pr_foo.Random2()<<(FRACBITS-6);
mo->Vel.X = pr_foo.Random2() / 64.;
mo->Vel.Y = pr_foo.Random2() / 64.;
mo->Vel.Z = ((pr_foo() & 7) + 5) * 0.75;
}
}
// Spawn a skull
@ -190,9 +190,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_CorpseExplode)
if (mo)
{
mo->SetState (mo->SpawnState + 3);
mo->vel.z = ((pr_foo()&7)+5)*(3*FRACUNIT/4);
mo->vel.x = pr_foo.Random2()<<(FRACBITS-6);
mo->vel.y = pr_foo.Random2()<<(FRACBITS-6);
mo->Vel.X = pr_foo.Random2() / 64.;
mo->Vel.Y = pr_foo.Random2() / 64.;
mo->Vel.Z = ((pr_foo() & 7) + 5) * 0.75;
}
S_Sound (self, CHAN_BODY, self->DeathSound, 1, ATTN_IDLE);
self->Destroy ();
@ -214,15 +214,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_LeafSpawn)
for (i = (pr_leaf()&3)+1; i; i--)
{
fixed_t xo = (pr_leaf.Random2() << 14);
fixed_t yo = (pr_leaf.Random2() << 14);
fixed_t zo = (pr_leaf() << 14);
double xo = pr_leaf.Random2() / 4.;
double yo = pr_leaf.Random2() / 4.;
double zo = pr_leaf() / 4.;
mo = Spawn (pr_leaf()&1 ? PClass::FindActor ("Leaf1") : PClass::FindActor ("Leaf2"),
self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE);
if (mo)
{
P_ThrustMobj (mo, self->angle, (pr_leaf()<<9)+3*FRACUNIT);
mo->Thrust(pr_leaf() / 128. + 3);
mo->target = self;
mo->special1 = 0;
}
@ -242,7 +242,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LeafThrust)
if (pr_leafthrust() <= 96)
{
self->vel.z += (pr_leafthrust()<<9)+FRACUNIT;
self->Vel.Z += pr_leafthrust() / 128. + 1;
}
return 0;
}
@ -263,18 +263,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_LeafCheck)
self->SetState (NULL);
return 0;
}
angle_t ang = self->target ? self->target->angle : self->angle;
DAngle ang = self->target ? self->target->Angles.Yaw : self->Angles.Yaw;
if (pr_leafcheck() > 64)
{
if (!self->vel.x && !self->vel.y)
if (self->Vel.X == 0 && self->Vel.Y == 0)
{
P_ThrustMobj (self, ang, (pr_leafcheck()<<9)+FRACUNIT);
self->Thrust(ang, pr_leafcheck() / 128. + 1);
}
return 0;
}
self->SetState (self->SpawnState + 7);
self->vel.z = (pr_leafcheck()<<9)+FRACUNIT;
P_ThrustMobj (self, ang, (pr_leafcheck()<<9)+2*FRACUNIT);
self->Vel.Z = pr_leafcheck() / 128. + 1;
self->Thrust(ang, pr_leafcheck() / 128. + 2);
self->flags |= MF_MISSILE;
return 0;
}
@ -289,7 +289,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_PoisonShroom)
{
PARAM_ACTION_PROLOGUE;
self->tics = 128+(pr_shroom()<<1);
self->tics = 128 + (pr_shroom() << 1);
return 0;
}
@ -308,16 +308,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_SoAExplode)
for (i = 0; i < 10; i++)
{
fixed_t xo = ((pr_soaexplode() - 128) << 12);
fixed_t yo = ((pr_soaexplode() - 128) << 12);
fixed_t zo = (pr_soaexplode()*self->height / 256);
double xo = (pr_soaexplode() - 128) / 16.;
double yo = (pr_soaexplode() - 128) / 16.;
double zo = pr_soaexplode()*self->Height / 256.;
mo = Spawn ("ZArmorChunk", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE);
if (mo)
{
mo->SetState (mo->SpawnState + i);
mo->vel.z = ((pr_soaexplode()&7)+5)*FRACUNIT;
mo->vel.x = pr_soaexplode.Random2()<<(FRACBITS-6);
mo->vel.y = pr_soaexplode.Random2()<<(FRACBITS-6);
mo->Vel.X = pr_soaexplode.Random2() / 64.;
mo->Vel.Y = pr_soaexplode.Random2() / 64.;
mo->Vel.Z = (pr_soaexplode() & 7) + 5;
}
}
// Spawn an item?
@ -365,7 +365,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BellReset1)
PARAM_ACTION_PROLOGUE;
self->flags |= MF_NOGRAVITY;
self->height <<= 2;
self->Height *= 4;
if (self->special)
{ // Initiate death action
P_ExecuteSpecial(self->special, NULL, NULL, false, self->args[0],

View file

@ -28,19 +28,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_IceGuyLook)
{
PARAM_ACTION_PROLOGUE;
fixed_t dist;
fixed_t an;
double dist;
DAngle an;
CALL_ACTION(A_Look, self);
if (pr_iceguylook() < 64)
{
dist = ((pr_iceguylook()-128)*self->radius)>>7;
an = (self->angle+ANG90)>>ANGLETOFINESHIFT;
Spawn(WispTypes[pr_iceguylook() & 1], self->Vec3Offset(
FixedMul(dist, finecosine[an]),
FixedMul(dist, finesine[an]),
60 * FRACUNIT), ALLOW_REPLACE);
dist = (pr_iceguylook() - 128) * self->radius / 128.;
an = self->Angles.Yaw + 90;
Spawn(WispTypes[pr_iceguylook() & 1], self->Vec3Angle(dist, an, 60.), ALLOW_REPLACE);
}
return 0;
}
@ -55,25 +51,19 @@ DEFINE_ACTION_FUNCTION(AActor, A_IceGuyChase)
{
PARAM_ACTION_PROLOGUE;
fixed_t dist;
fixed_t an;
double dist;
DAngle an;
AActor *mo;
A_Chase (stack, self);
A_Chase(stack, self);
if (pr_iceguychase() < 128)
{
dist = ((pr_iceguychase()-128)*self->radius)>>7;
an = (self->angle+ANG90)>>ANGLETOFINESHIFT;
mo = Spawn(WispTypes[pr_iceguychase() & 1], self->Vec3Offset(
FixedMul(dist, finecosine[an]),
FixedMul(dist, finesine[an]),
60 * FRACUNIT), ALLOW_REPLACE);
dist = (pr_iceguychase() - 128) * self->radius / 128.;
an = self->Angles.Yaw + 90;
mo = Spawn(WispTypes[pr_iceguylook() & 1], self->Vec3Angle(dist, an, 60.), ALLOW_REPLACE);
if (mo)
{
mo->vel.x = self->vel.x;
mo->vel.y = self->vel.y;
mo->vel.z = self->vel.z;
mo->Vel = self->Vel;
mo->target = self;
}
}
@ -94,8 +84,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_IceGuyAttack)
{
return 0;
}
P_SpawnMissileXYZ(self->Vec3Angle(self->radius>>1, self->angle+ANG90, 40*FRACUNIT), self, self->target, PClass::FindActor ("IceGuyFX"));
P_SpawnMissileXYZ(self->Vec3Angle(self->radius>>1, self->angle-ANG90, 40*FRACUNIT), self, self->target, PClass::FindActor ("IceGuyFX"));
P_SpawnMissileXYZ(self->Vec3Angle(self->radius / 2, self->Angles.Yaw + 90, 40.), self, self->target, PClass::FindActor("IceGuyFX"));
P_SpawnMissileXYZ(self->Vec3Angle(self->radius / 2, self->Angles.Yaw - 90, 40.), self, self->target, PClass::FindActor("IceGuyFX"));
S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM);
return 0;
}
@ -110,10 +100,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_IceGuyDie)
{
PARAM_ACTION_PROLOGUE;
self->vel.x = 0;
self->vel.y = 0;
self->vel.z = 0;
self->height = self->GetDefault()->height;
self->Vel.Zero();
self->Height = self->GetDefault()->Height;
CALL_ACTION(A_FreezeDeathChunks, self);
return 0;
}
@ -133,8 +121,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_IceGuyMissileExplode)
for (i = 0; i < 8; i++)
{
mo = P_SpawnMissileAngleZ (self, self->Z()+3*FRACUNIT,
PClass::FindActor("IceGuyFX2"), i*ANG45, (fixed_t)(-0.3*FRACUNIT));
mo = P_SpawnMissileAngleZ (self, self->Z()+3, PClass::FindActor("IceGuyFX2"), DAngle(i*45.), -0.3);
if (mo)
{
mo->target = self->target;

View file

@ -37,18 +37,18 @@ const int KORAX_TID = 245;
const int KORAX_FIRST_TELEPORT_TID = 248;
const int KORAX_TELEPORT_TID = 249;
const int KORAX_DELTAANGLE = 85*ANGLE_1;
const int KORAX_DELTAANGLE = 85;
const int KORAX_ARM_EXTENSION_SHORT = 40;
const int KORAX_ARM_EXTENSION_LONG = 55;
const int KORAX_ARM1_HEIGHT = 108*FRACUNIT;
const int KORAX_ARM2_HEIGHT = 82*FRACUNIT;
const int KORAX_ARM3_HEIGHT = 54*FRACUNIT;
const int KORAX_ARM4_HEIGHT = 104*FRACUNIT;
const int KORAX_ARM5_HEIGHT = 86*FRACUNIT;
const int KORAX_ARM6_HEIGHT = 53*FRACUNIT;
const int KORAX_ARM1_HEIGHT = 108;
const int KORAX_ARM2_HEIGHT = 82;
const int KORAX_ARM3_HEIGHT = 54;
const int KORAX_ARM4_HEIGHT = 104;
const int KORAX_ARM5_HEIGHT = 86;
const int KORAX_ARM6_HEIGHT = 53;
const int KORAX_BOLT_HEIGHT = 48*FRACUNIT;
const double KORAX_BOLT_HEIGHT = 48.;
const int KORAX_BOLT_LIFETIME = 3;
@ -76,8 +76,7 @@ void A_KBoltRaise (AActor *);
void KoraxFire (AActor *actor, PClassActor *type, int arm);
void KSpiritInit (AActor *spirit, AActor *korax);
AActor *P_SpawnKoraxMissile (fixed_t x, fixed_t y, fixed_t z,
AActor *source, AActor *dest, PClassActor *type);
AActor *P_SpawnKoraxMissile (const DVector3 &pos, AActor *source, AActor *dest, PClassActor *type);
extern void SpawnSpiritTail (AActor *spirit);
@ -99,7 +98,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_KoraxChase)
spot = iterator.Next ();
if (spot != NULL)
{
P_Teleport (self, spot->X(), spot->Y(), ONFLOORZ, spot->angle, TELF_SOURCEFOG | TELF_DESTFOG);
P_Teleport (self, spot->PosAtZ(ONFLOORZ), spot->Angles.Yaw, TELF_SOURCEFOG | TELF_DESTFOG);
}
P_StartScript (self, NULL, 249, NULL, NULL, 0, 0);
@ -141,7 +140,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_KoraxChase)
self->tracer = spot;
if (spot)
{
P_Teleport (self, spot->X(), spot->Y(), ONFLOORZ, spot->angle, TELF_SOURCEFOG | TELF_DESTFOG);
P_Teleport (self, spot->PosAtZ(ONFLOORZ), spot->Angles.Yaw, TELF_SOURCEFOG | TELF_DESTFOG);
}
}
}
@ -164,7 +163,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_KoraxBonePop)
// Spawn 6 spirits equalangularly
for (i = 0; i < 6; ++i)
{
mo = P_SpawnMissileAngle (self, PClass::FindActor("KoraxSpirit"), ANGLE_60*i, 5*FRACUNIT);
mo = P_SpawnMissileAngle (self, PClass::FindActor("KoraxSpirit"), DAngle(60.*i), 5.);
if (mo)
{
KSpiritInit (mo, self);
@ -186,7 +185,7 @@ void KSpiritInit (AActor *spirit, AActor *korax)
spirit->health = KORAX_SPIRIT_LIFETIME;
spirit->tracer = korax; // Swarm around korax
spirit->special2 = FINEANGLES/2 + pr_kspiritinit(8 << BOBTOFINESHIFT); // Float bob index
spirit->WeaveIndexZ = 32 + (pr_kspiritinit() & 7); // Float bob index
spirit->args[0] = 10; // initial turn value
spirit->args[1] = 0; // initial look angle
@ -235,23 +234,23 @@ DEFINE_ACTION_FUNCTION(AActor, A_KoraxMissile)
{ "SerpentFX", "CentaurLeaderAttack" }
};
int type = pr_koraxmissile()%6;
int type = pr_koraxmissile() % 6;
int i;
PClassActor *info;
S_Sound (self, CHAN_VOICE, "KoraxAttack", 1, ATTN_NORM);
S_Sound(self, CHAN_VOICE, "KoraxAttack", 1, ATTN_NORM);
info = PClass::FindActor(choices[type].type);
if (info == NULL)
{
I_Error ("Unknown Korax missile: %s\n", choices[type].type);
I_Error("Unknown Korax missile: %s\n", choices[type].type);
}
// Fire all 6 missiles at once
S_Sound (self, CHAN_WEAPON, choices[type].sound, 1, ATTN_NONE);
S_Sound(self, CHAN_WEAPON, choices[type].sound, 1, ATTN_NONE);
for (i = 0; i < 6; ++i)
{
KoraxFire (self, info, i);
KoraxFire(self, info, i);
}
return 0;
}
@ -267,17 +266,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_KoraxMissile)
DEFINE_ACTION_FUNCTION(AActor, A_KoraxCommand)
{
PARAM_ACTION_PROLOGUE;
angle_t ang;
DAngle ang;
int numcommands;
S_Sound (self, CHAN_VOICE, "KoraxCommand", 1, ATTN_NORM);
// Shoot stream of lightning to ceiling
ang = (self->angle - ANGLE_90) >> ANGLETOFINESHIFT;
fixedvec3 pos = self->Vec3Offset(
KORAX_COMMAND_OFFSET * finecosine[ang],
KORAX_COMMAND_OFFSET * finesine[ang],
KORAX_COMMAND_HEIGHT*FRACUNIT);
ang = self->Angles.Yaw - 90;
DVector3 pos = self->Vec3Angle(KORAX_COMMAND_OFFSET, ang, KORAX_COMMAND_HEIGHT);
Spawn("KoraxBolt", pos, ALLOW_REPLACE);
if (self->health <= (self->SpawnHealth() >> 1))
@ -319,7 +315,7 @@ void KoraxFire (AActor *actor, PClassActor *type, int arm)
KORAX_ARM_EXTENSION_LONG,
KORAX_ARM_EXTENSION_LONG
};
static const fixed_t armheight[6] =
static const int armheight[6] =
{
KORAX_ARM1_HEIGHT,
KORAX_ARM2_HEIGHT,
@ -329,40 +325,24 @@ void KoraxFire (AActor *actor, PClassActor *type, int arm)
KORAX_ARM6_HEIGHT
};
angle_t ang;
ang = (actor->angle + (arm < 3 ? -KORAX_DELTAANGLE : KORAX_DELTAANGLE)) >> ANGLETOFINESHIFT;
fixedvec3 pos = actor->Vec3Offset(
extension[arm] * finecosine[ang],
extension[arm] * finesine[ang],
-actor->floorclip + armheight[arm]);
P_SpawnKoraxMissile (pos.x, pos.y, pos.z, actor, actor->target, type);
DAngle ang = actor->Angles.Yaw + (arm < 3 ? -KORAX_DELTAANGLE : KORAX_DELTAANGLE);
DVector3 pos = actor->Vec3Angle(extension[arm], ang, armheight[arm] - actor->Floorclip);
P_SpawnKoraxMissile (pos, actor, actor->target, type);
}
//============================================================================
//
// A_KSpiritWeave
// [BL] Was identical to CHolyWeave so lets just use that
//
//============================================================================
void CHolyWeave (AActor *actor, FRandom &pr_random);
//============================================================================
//
// A_KSpiritSeeker
//
//============================================================================
void A_KSpiritSeeker (AActor *actor, angle_t thresh, angle_t turnMax)
static void A_KSpiritSeeker (AActor *actor, DAngle thresh, DAngle turnMax)
{
int dir;
int dist;
angle_t delta;
angle_t angle;
DAngle delta;
AActor *target;
fixed_t newZ;
fixed_t deltaZ;
double newZ;
double deltaZ;
target = actor->tracer;
if (target == NULL)
@ -372,7 +352,7 @@ void A_KSpiritSeeker (AActor *actor, angle_t thresh, angle_t turnMax)
dir = P_FaceMobj (actor, target, &delta);
if (delta > thresh)
{
delta >>= 1;
delta /= 2;
if(delta > turnMax)
{
delta = turnMax;
@ -380,39 +360,33 @@ void A_KSpiritSeeker (AActor *actor, angle_t thresh, angle_t turnMax)
}
if(dir)
{ // Turn clockwise
actor->angle += delta;
actor->Angles.Yaw += delta;
}
else
{ // Turn counter clockwise
actor->angle -= delta;
actor->Angles.Yaw -= delta;
}
angle = actor->angle>>ANGLETOFINESHIFT;
actor->vel.x = FixedMul (actor->Speed, finecosine[angle]);
actor->vel.y = FixedMul (actor->Speed, finesine[angle]);
actor->VelFromAngle();
if (!(level.time&15)
|| actor->Z() > target->Z()+(target->GetDefault()->height)
|| actor->Z() > target->Z() + target->GetDefault()->Height
|| actor->Top() < target->Z())
{
newZ = target->Z()+((pr_kspiritseek()*target->GetDefault()->height)>>8);
newZ = target->Z() + pr_kspiritseek() * target->GetDefault()->Height / 256;
deltaZ = newZ-actor->Z();
if (abs(deltaZ) > 15*FRACUNIT)
if (fabs(deltaZ) > 15)
{
if(deltaZ > 0)
{
deltaZ = 15*FRACUNIT;
deltaZ = 15;
}
else
{
deltaZ = -15*FRACUNIT;
deltaZ = -15;
}
}
dist = actor->AproxDistance (target) / actor->Speed;
if (dist < 1)
{
dist = 1;
}
actor->vel.z = deltaZ/dist;
actor->Vel.Z = deltaZ + actor->DistanceBySpeed(target, actor->Speed);
}
return;
}
@ -436,10 +410,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_KSpiritRoam)
{
if (self->tracer)
{
A_KSpiritSeeker (self, self->args[0]*ANGLE_1,
self->args[0]*ANGLE_1*2);
A_KSpiritSeeker(self, (double)self->args[0], self->args[0] * 2.);
}
CHolyWeave(self, pr_kspiritweave);
int xyspeed = (pr_kspiritweave() % 5);
int zspeed = (pr_kspiritweave() % 5);
A_Weave(self, xyspeed, zspeed, 4., 2.);
if (pr_kspiritroam()<50)
{
S_Sound (self, CHAN_VOICE, "SpiritActive", 1, ATTN_NONE);
@ -477,14 +453,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_KBoltRaise)
PARAM_ACTION_PROLOGUE;
AActor *mo;
fixed_t z;
// Spawn a child upward
z = self->Z() + KORAX_BOLT_HEIGHT;
double z = self->Z() + KORAX_BOLT_HEIGHT;
if ((z + KORAX_BOLT_HEIGHT) < self->ceilingz)
{
mo = Spawn("KoraxBolt", self->X(), self->Y(), z, ALLOW_REPLACE);
mo = Spawn("KoraxBolt", self->PosAtZ(z), ALLOW_REPLACE);
if (mo)
{
mo->special1 = KORAX_BOLT_LIFETIME;
@ -503,30 +478,22 @@ DEFINE_ACTION_FUNCTION(AActor, A_KBoltRaise)
//
//============================================================================
AActor *P_SpawnKoraxMissile (fixed_t x, fixed_t y, fixed_t z,
AActor *source, AActor *dest, PClassActor *type)
AActor *P_SpawnKoraxMissile (const DVector3 &pos, AActor *source, AActor *dest, PClassActor *type)
{
AActor *th;
angle_t an;
int dist;
DAngle an;
double dist;
z -= source->floorclip;
th = Spawn (type, x, y, z, ALLOW_REPLACE);
th = Spawn (type, source->PosPlusZ(-source->Floorclip), ALLOW_REPLACE);
th->target = source; // Originator
an = th->AngleTo(dest);
if (dest->flags & MF_SHADOW)
{ // Invisible target
an += pr_kmissile.Random2()<<21;
an += pr_kmissile.Random2() * (45/256.);
}
th->angle = an;
an >>= ANGLETOFINESHIFT;
th->vel.x = FixedMul (th->Speed, finecosine[an]);
th->vel.y = FixedMul (th->Speed, finesine[an]);
dist = dest->AproxDistance (th) / th->Speed;
if (dist < 1)
{
dist = 1;
}
th->vel.z = (dest->Z()-z+(30*FRACUNIT))/dist;
th->Angles.Yaw = an;
th->VelFromAngle();
dist = dest->DistanceBySpeed(th, th->Speed);
th->Vel.Z = (dest->Z() - pos.Z + 30) / dist;
return (P_CheckMissileSpawn(th, source->radius) ? th : NULL);
}

View file

@ -53,9 +53,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireConePL1)
{
PARAM_ACTION_PROLOGUE;
angle_t angle;
DAngle angle;
int damage;
int slope;
DAngle slope;
int i;
AActor *mo;
bool conedone=false;
@ -78,11 +78,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireConePL1)
damage = 90+(pr_cone()&15);
for (i = 0; i < 16; i++)
{
angle = self->angle+i*(ANG45/16);
slope = P_AimLineAttack (self, angle, MELEERANGE, &t, 0, ALF_CHECK3D);
angle = self->Angles.Yaw + i*(45./16);
slope = P_AimLineAttack (self, angle, MELEERANGE, &t, 0., ALF_CHECK3D);
if (t.linetarget)
{
P_DamageMobj (t.linetarget, self, self, damage, NAME_Ice, DMG_USEANGLE, t.angleFromSource);
P_DamageMobj (t.linetarget, self, self, damage, NAME_Ice, DMG_USEANGLE, t.angleFromSource.Degrees);
conedone = true;
break;
}
@ -128,35 +128,35 @@ DEFINE_ACTION_FUNCTION(AActor, A_ShedShard)
// every so many calls, spawn a new missile in its set directions
if (spawndir & SHARDSPAWN_LEFT)
{
mo = P_SpawnMissileAngleZSpeed (self, self->Z(), RUNTIME_CLASS(AFrostMissile), self->angle+(ANG45/9),
0, (20+2*spermcount)<<FRACBITS, self->target);
mo = P_SpawnMissileAngleZSpeed(self, self->Z(), RUNTIME_CLASS(AFrostMissile),
self->Angles.Yaw + 5, 0, (20. + 2 * spermcount), self->target);
if (mo)
{
mo->special1 = SHARDSPAWN_LEFT;
mo->special2 = spermcount;
mo->vel.z = self->vel.z;
mo->Vel.Z = self->Vel.Z;
mo->args[0] = (spermcount==3)?2:0;
}
}
if (spawndir & SHARDSPAWN_RIGHT)
{
mo = P_SpawnMissileAngleZSpeed (self, self->Z(), RUNTIME_CLASS(AFrostMissile), self->angle-(ANG45/9),
0, (20+2*spermcount)<<FRACBITS, self->target);
mo = P_SpawnMissileAngleZSpeed(self, self->Z(), RUNTIME_CLASS(AFrostMissile),
self->Angles.Yaw - 5, 0, (20. + 2 * spermcount), self->target);
if (mo)
{
mo->special1 = SHARDSPAWN_RIGHT;
mo->special2 = spermcount;
mo->vel.z = self->vel.z;
mo->Vel.Z = self->Vel.Z;
mo->args[0] = (spermcount==3)?2:0;
}
}
if (spawndir & SHARDSPAWN_UP)
{
mo = P_SpawnMissileAngleZSpeed (self, self->Z()+8*FRACUNIT, RUNTIME_CLASS(AFrostMissile), self->angle,
0, (15+2*spermcount)<<FRACBITS, self->target);
mo = P_SpawnMissileAngleZSpeed(self, self->Z() + 8., RUNTIME_CLASS(AFrostMissile),
self->Angles.Yaw, 0, (15. + 2 * spermcount), self->target);
if (mo)
{
mo->vel.z = self->vel.z;
mo->Vel.Z = self->Vel.Z;
if (spermcount & 1) // Every other reproduction
mo->special1 = SHARDSPAWN_UP | SHARDSPAWN_LEFT | SHARDSPAWN_RIGHT;
else
@ -167,11 +167,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_ShedShard)
}
if (spawndir & SHARDSPAWN_DOWN)
{
mo = P_SpawnMissileAngleZSpeed (self, self->Z()-4*FRACUNIT, RUNTIME_CLASS(AFrostMissile), self->angle,
0, (15+2*spermcount)<<FRACBITS, self->target);
mo = P_SpawnMissileAngleZSpeed(self, self->Z() - 4., RUNTIME_CLASS(AFrostMissile),
self->Angles.Yaw, 0, (15. + 2 * spermcount), self->target);
if (mo)
{
mo->vel.z = self->vel.z;
mo->Vel.Z = self->Vel.Z;
if (spermcount & 1) // Every other reproduction
mo->special1 = SHARDSPAWN_DOWN | SHARDSPAWN_LEFT | SHARDSPAWN_RIGHT;
else

View file

@ -14,7 +14,7 @@
#include "g_level.h"
*/
#define ZAGSPEED FRACUNIT
#define ZAGSPEED 1.
static FRandom pr_lightningready ("LightningReady");
static FRandom pr_lightningclip ("LightningClip");
@ -42,8 +42,8 @@ int ALightning::SpecialMissileHit (AActor *thing)
{
if (thing->Mass != INT_MAX)
{
thing->vel.x += vel.x>>4;
thing->vel.y += vel.y>>4;
thing->Vel.X += Vel.X / 16;
thing->Vel.Y += Vel.Y / 16;
}
if ((!thing->player && !(thing->flags2&MF2_BOSS))
|| !(level.time&1))
@ -161,7 +161,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LightningClip)
}
else if (self->flags3 & MF3_CEILINGHUGGER)
{
self->SetZ(self->ceilingz-self->height);
self->SetZ(self->ceilingz - self->Height);
target = self->tracer;
}
if (self->flags3 & MF3_FLOORHUGGER)
@ -170,19 +170,19 @@ DEFINE_ACTION_FUNCTION(AActor, A_LightningClip)
zigZag = pr_lightningclip();
if((zigZag > 128 && self->special1 < 2) || self->special1 < -2)
{
P_ThrustMobj(self, self->angle+ANG90, ZAGSPEED);
self->Thrust(self->Angles.Yaw + 90, ZAGSPEED);
if(cMo)
{
P_ThrustMobj(cMo, self->angle+ANG90, ZAGSPEED);
cMo->Thrust(self->Angles.Yaw + 90, ZAGSPEED);
}
self->special1++;
}
else
{
P_ThrustMobj(self, self->angle-ANG90, ZAGSPEED);
self->Thrust(self->Angles.Yaw - 90, ZAGSPEED);
if(cMo)
{
P_ThrustMobj(cMo, cMo->angle-ANG90, ZAGSPEED);
cMo->Thrust(self->Angles.Yaw - 90, ZAGSPEED);
}
self->special1--;
}
@ -195,10 +195,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_LightningClip)
}
else
{
self->angle = self->AngleTo(target);
self->vel.x = 0;
self->vel.y = 0;
P_ThrustMobj (self, self->angle, self->Speed>>1);
self->Angles.Yaw = self->AngleTo(target);
self->VelFromAngle(self->Speed / 2);
}
}
return 0;
@ -217,7 +215,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_LightningZap)
PClassActor *lightning = PClass::FindActor(self->GetClass()->MissileName);
AActor *mo;
fixed_t deltaZ;
if (lightning == NULL)
{
@ -232,32 +229,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_LightningZap)
self->SetState (self->FindState(NAME_Death));
return 0;
}
if (self->flags3 & MF3_FLOORHUGGER)
{
deltaZ = 10*FRACUNIT;
}
else
{
deltaZ = -10*FRACUNIT;
}
fixed_t xo = ((pr_zap() - 128)*self->radius / 256);
fixed_t yo = ((pr_zap() - 128)*self->radius / 256);
double deltaX = (pr_zap() - 128) * self->radius / 256;
double deltaY = (pr_zap() - 128) * self->radius / 256;
double deltaZ = (self->flags3 & MF3_FLOORHUGGER) ? 10 : -10;
mo = Spawn(lightning, self->Vec3Offset(xo, yo, deltaZ), ALLOW_REPLACE);
mo = Spawn(lightning, self->Vec3Offset(deltaX, deltaY, deltaZ), ALLOW_REPLACE);
if (mo)
{
mo->lastenemy = self;
mo->vel.x = self->vel.x;
mo->vel.y = self->vel.y;
mo->Vel.X = self->Vel.X;
mo->Vel.Y = self->Vel.Y;
mo->Vel.Z = (self->flags3 & MF3_FLOORHUGGER) ? 20 : -20;
mo->target = self->target;
if (self->flags3 & MF3_FLOORHUGGER)
{
mo->vel.z = 20*FRACUNIT;
}
else
{
mo->vel.z = -20*FRACUNIT;
}
}
if ((self->flags3 & MF3_FLOORHUGGER) && pr_zapf() < 160)
{
@ -328,8 +311,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_ZapMimic)
}
else
{
self->vel.x = mo->vel.x;
self->vel.y = mo->vel.y;
self->Vel.X = mo->Vel.X;
self->Vel.Y = mo->Vel.Y;
}
}
return 0;
@ -356,7 +339,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LastZap)
if (mo)
{
mo->SetState (mo->FindState (NAME_Death));
mo->vel.z = 40*FRACUNIT;
mo->Vel.Z = 40;
mo->Damage = NULL;
}
return 0;

View file

@ -64,7 +64,7 @@ class AMageStaffFX2 : public AActor
DECLARE_CLASS(AMageStaffFX2, AActor)
public:
int SpecialMissileHit (AActor *victim);
bool SpecialBlastHandling (AActor *source, fixed_t strength);
bool SpecialBlastHandling (AActor *source, double strength);
};
IMPLEMENT_CLASS (AMageStaffFX2)
@ -81,7 +81,7 @@ int AMageStaffFX2::SpecialMissileHit (AActor *victim)
return -1;
}
bool AMageStaffFX2::SpecialBlastHandling (AActor *source, fixed_t strength)
bool AMageStaffFX2::SpecialBlastHandling (AActor *source, double strength)
{
// Reflect to originator
tracer = target;
@ -97,13 +97,12 @@ bool AMageStaffFX2::SpecialBlastHandling (AActor *source, fixed_t strength)
//
//============================================================================
void MStaffSpawn (AActor *pmo, angle_t angle, AActor *alttarget)
void MStaffSpawn (AActor *pmo, DAngle angle, AActor *alttarget)
{
AActor *mo;
FTranslatedLineTarget t;
mo = P_SpawnPlayerMissile (pmo, 0, 0, 8*FRACUNIT,
RUNTIME_CLASS(AMageStaffFX2), angle, &t);
mo = P_SpawnPlayerMissile (pmo, 0, 0, 8, RUNTIME_CLASS(AMageStaffFX2), angle, &t);
if (mo)
{
mo->target = pmo;
@ -124,7 +123,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MStaffAttack)
{
PARAM_ACTION_PROLOGUE;
angle_t angle;
DAngle angle;
player_t *player;
FTranslatedLineTarget t;
@ -139,21 +138,21 @@ DEFINE_ACTION_FUNCTION(AActor, A_MStaffAttack)
if (!weapon->DepleteAmmo (weapon->bAltFire))
return 0;
}
angle = self->angle;
angle = self->Angles.Yaw;
// [RH] Let's try and actually track what the player aimed at
P_AimLineAttack (self, angle, PLAYERMISSILERANGE, &t, ANGLE_1*32);
P_AimLineAttack (self, angle, PLAYERMISSILERANGE, &t, 32.);
if (t.linetarget == NULL)
{
BlockCheckLine.x = self->X();
BlockCheckLine.y = self->Y();
BlockCheckLine.dx = -finesine[angle >> ANGLETOFINESHIFT];
BlockCheckLine.dy = -finecosine[angle >> ANGLETOFINESHIFT];
BlockCheckLine.dx = -angle.Sin();
BlockCheckLine.dy = -angle.Cos();
t.linetarget = P_BlockmapSearch (self, 10, FrontBlockCheck);
}
MStaffSpawn (self, angle, t.linetarget);
MStaffSpawn (self, angle-ANGLE_1*5, t.linetarget);
MStaffSpawn (self, angle+ANGLE_1*5, t.linetarget);
MStaffSpawn (self, angle-5, t.linetarget);
MStaffSpawn (self, angle+5, t.linetarget);
S_Sound (self, CHAN_WEAPON, "MageStaffFire", 1, ATTN_NORM);
weapon->MStaffCount = 3;
return 0;
@ -194,7 +193,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MStaffTrack)
{
self->tracer = P_RoughMonsterSearch (self, 10, true);
}
P_SeekerMissile (self, ANGLE_1*2, ANGLE_1*10);
P_SeekerMissile(self, 2, 10);
return 0;
}
@ -214,7 +213,7 @@ static AActor *FrontBlockCheck (AActor *mo, int index, void *)
{
if (link->Me != mo)
{
if (P_PointOnDivlineSide (link->Me->X(), link->Me->Y(), &BlockCheckLine) == 0 &&
if (P_PointOnDivlineSide(link->Me->X(), link->Me->Y(), &BlockCheckLine) == 0 &&
mo->IsOkayToAttack (link->Me))
{
return link->Me;
@ -230,12 +229,11 @@ static AActor *FrontBlockCheck (AActor *mo, int index, void *)
//
//============================================================================
void MStaffSpawn2 (AActor *actor, angle_t angle)
void MStaffSpawn2 (AActor *actor, DAngle angle)
{
AActor *mo;
mo = P_SpawnMissileAngleZ (actor, actor->Z()+40*FRACUNIT,
RUNTIME_CLASS(AMageStaffFX2), angle, 0);
mo = P_SpawnMissileAngleZ (actor, actor->Z()+40, RUNTIME_CLASS(AMageStaffFX2), angle, 0.);
if (mo)
{
mo->target = actor;
@ -257,11 +255,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_MageAttack)
{
return 0;
}
angle_t angle;
angle = self->angle;
MStaffSpawn2 (self, angle);
MStaffSpawn2 (self, angle-ANGLE_1*5);
MStaffSpawn2 (self, angle+ANGLE_1*5);
S_Sound (self, CHAN_WEAPON, "MageStaffFire", 1, ATTN_NORM);
DAngle angle = self->Angles.Yaw;
MStaffSpawn2(self, angle);
MStaffSpawn2(self, angle - 5);
MStaffSpawn2(self, angle + 5);
S_Sound(self, CHAN_WEAPON, "MageStaffFire", 1, ATTN_NORM);
return 0;
}

View file

@ -35,7 +35,7 @@ void APigPlayer::MorphPlayerThink ()
{
return;
}
if(!(vel.x | vel.y) && pr_pigplayerthink() < 64)
if(Vel.X == 0 && Vel.Y == 0 && pr_pigplayerthink() < 64)
{ // Snout sniff
if (player->ReadyWeapon != NULL)
{
@ -60,9 +60,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_SnoutAttack)
{
PARAM_ACTION_PROLOGUE;
angle_t angle;
DAngle angle;
int damage;
int slope;
DAngle slope;
player_t *player;
AActor *puff;
FTranslatedLineTarget t;
@ -73,7 +73,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SnoutAttack)
}
damage = 3+(pr_snoutattack()&3);
angle = player->mo->angle;
angle = player->mo->Angles.Yaw;
slope = P_AimLineAttack(player->mo, angle, MELEERANGE);
puff = P_LineAttack(player->mo, angle, MELEERANGE, slope, damage, NAME_Melee, "SnoutPuff", true, &t);
S_Sound(player->mo, CHAN_VOICE, "PigActive", 1, ATTN_NORM);
@ -101,7 +101,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_PigPain)
CALL_ACTION(A_Pain, self);
if (self->Z() <= self->floorz)
{
self->vel.z = FRACUNIT*7/2;
self->Vel.Z = 3.5;
}
return 0;
}

View file

@ -28,7 +28,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SerpentUnHide)
PARAM_ACTION_PROLOGUE;
self->renderflags &= ~RF_INVISIBLE;
self->floorclip = 24*FRACUNIT;
self->Floorclip = 24;
return 0;
}
@ -43,7 +43,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SerpentHide)
PARAM_ACTION_PROLOGUE;
self->renderflags |= RF_INVISIBLE;
self->floorclip = 0;
self->Floorclip = 0;
return 0;
}
@ -58,7 +58,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SerpentRaiseHump)
{
PARAM_ACTION_PROLOGUE;
self->floorclip -= 4*FRACUNIT;
self->Floorclip -= 4;
return 0;
}
@ -72,7 +72,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SerpentLowerHump)
{
PARAM_ACTION_PROLOGUE;
self->floorclip += 4*FRACUNIT;
self->Floorclip += 4;
return 0;
}
@ -228,17 +228,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_SerpentSpawnGibs)
for (int i = countof(GibTypes)-1; i >= 0; --i)
{
fixedvec2 pos = self->Vec2Offset(
((pr_serpentgibs() - 128) << 12),
((pr_serpentgibs() - 128) << 12));
double x = (pr_serpentgibs() - 128) / 16.;
double y = (pr_serpentgibs() - 128) / 16.;
mo = Spawn (GibTypes[i], pos.x, pos.y,
self->floorz+FRACUNIT, ALLOW_REPLACE);
mo = Spawn (GibTypes[i], self->Vec2OffsetZ(x, y, self->floorz + 1), ALLOW_REPLACE);
if (mo)
{
mo->vel.x = (pr_serpentgibs()-128)<<6;
mo->vel.y = (pr_serpentgibs()-128)<<6;
mo->floorclip = 6*FRACUNIT;
mo->Vel.X = (pr_serpentgibs() - 128) / 1024.f;
mo->Vel.Y = (pr_serpentgibs() - 128) / 1024.f;
mo->Floorclip = 6;
}
}
return 0;
@ -254,7 +252,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FloatGib)
{
PARAM_ACTION_PROLOGUE;
self->floorclip -= FRACUNIT;
self->Floorclip -= 1;
return 0;
}
@ -268,7 +266,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SinkGib)
{
PARAM_ACTION_PROLOGUE;
self->floorclip += FRACUNIT;
self->Floorclip += 1;;
return 0;
}

View file

@ -82,7 +82,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ThrustInitUp)
self->special2 = 5; // Raise speed
self->args[0] = 1; // Mark as up
self->floorclip = 0;
self->Floorclip = 0;
self->flags = MF_SOLID;
self->flags2 = MF2_NOTELEPORT|MF2_FLOORCLIP;
self->special1 = 0L;
@ -95,7 +95,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ThrustInitDn)
self->special2 = 5; // Raise speed
self->args[0] = 0; // Mark as down
self->floorclip = self->GetDefault()->height;
self->Floorclip = self->GetDefault()->Height;
self->flags = 0;
self->flags2 = MF2_NOTELEPORT|MF2_FLOORCLIP;
self->renderflags = RF_INVISIBLE;
@ -111,7 +111,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ThrustRaise)
AThrustFloor *actor = static_cast<AThrustFloor *>(self);
if (A_RaiseMobj (actor, self->special2*FRACUNIT))
if (A_RaiseMobj (actor, self->special2))
{ // Reached it's target height
actor->args[0] = 1;
if (actor->args[1])
@ -121,7 +121,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ThrustRaise)
}
// Lose the dirt clump
if ((actor->floorclip < actor->height) && actor->DirtClump)
if ((actor->Floorclip < actor->Height) && actor->DirtClump)
{
actor->DirtClump->Destroy ();
actor->DirtClump = NULL;
@ -138,7 +138,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ThrustLower)
{
PARAM_ACTION_PROLOGUE;
if (A_SinkMobj (self, 6*FRACUNIT))
if (A_SinkMobj (self, 6))
{
self->args[0] = 0;
if (self->args[1])
@ -160,8 +160,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_ThrustImpale)
FMultiBlockThingsIterator::CheckResult cres;
while (it.Next(&cres))
{
fixed_t blockdist = self->radius + cres.thing->radius;
if (abs(cres.thing->X() - cres.position.x) >= blockdist || abs(cres.thing->Y() - cres.position.y) >= blockdist)
double blockdist = self->radius + cres.thing->radius;
if (fabs(cres.thing->X() - cres.Position.X) >= blockdist || fabs(cres.thing->Y() - cres.Position.Y) >= blockdist)
continue;
// Q: Make this z-aware for everything? It never was before.

View file

@ -36,7 +36,7 @@ bool AArtiDarkServant::Use (bool pickup)
{
mo->target = Owner;
mo->tracer = Owner;
mo->vel.z = 5*FRACUNIT;
mo->Vel.Z = 5;
}
return true;
}
@ -53,13 +53,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_Summon)
AMinotaurFriend *mo;
mo = Spawn<AMinotaurFriend> (self->Pos(), ALLOW_REPLACE);
mo = Spawn<AMinotaurFriend>(self->Pos(), ALLOW_REPLACE);
if (mo)
{
if (P_TestMobjLocation(mo) == false || !self->tracer)
{ // Didn't fit - change back to artifact
mo->Destroy ();
AActor *arti = Spawn<AArtiDarkServant> (self->Pos(), ALLOW_REPLACE);
mo->Destroy();
AActor *arti = Spawn<AArtiDarkServant>(self->Pos(), ALLOW_REPLACE);
if (arti) arti->flags |= MF_DROPPED;
return 0;
}
@ -72,14 +72,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_Summon)
else
{
mo->tracer = self->tracer; // Pointer to master
AInventory *power = Spawn<APowerMinotaur> (0, 0, 0, NO_REPLACE);
power->CallTryPickup (self->tracer);
AInventory *power = Spawn<APowerMinotaur>();
power->CallTryPickup(self->tracer);
mo->SetFriendPlayer(self->tracer->player);
}
// Make smoke puff
Spawn ("MinotaurSmoke", self->Pos(), ALLOW_REPLACE);
S_Sound (self, CHAN_VOICE, mo->ActiveSound, 1, ATTN_NORM);
Spawn("MinotaurSmoke", self->Pos(), ALLOW_REPLACE);
S_Sound(self, CHAN_VOICE, mo->ActiveSound, 1, ATTN_NORM);
}
return 0;
}

View file

@ -55,11 +55,9 @@ static void TeloSpawn (AActor *source, const char *type)
if (fx)
{
fx->special1 = TELEPORT_LIFE; // Lifetime countdown
fx->angle = source->angle;
fx->Angles.Yaw = source->Angles.Yaw;
fx->target = source->target;
fx->vel.x = source->vel.x >> 1;
fx->vel.y = source->vel.y >> 1;
fx->vel.z = source->vel.z >> 1;
fx->Vel = source->Vel / 2;
}
}
@ -166,14 +164,12 @@ int ATelOtherFX1::DoSpecialDamage (AActor *target, int damage, FName damagetype)
void P_TeleportToPlayerStarts (AActor *victim)
{
fixed_t destX,destY;
angle_t destAngle;
DVector3 dest;
FPlayerStart *start = G_PickPlayerStart(0, PPS_FORCERANDOM | PPS_NOBLOCKINGCHECK);
destX = start->x;
destY = start->y;
destAngle = ANG45 * (start->angle/45);
P_Teleport (victim, destX, destY, ONFLOORZ, destAngle, TELF_SOURCEFOG | TELF_DESTFOG);
dest = start->pos;
dest.Z = ONFLOORZ;
P_Teleport (victim, dest, (double)start->angle, TELF_SOURCEFOG | TELF_DESTFOG);
}
//===========================================================================
@ -185,17 +181,15 @@ void P_TeleportToPlayerStarts (AActor *victim)
void P_TeleportToDeathmatchStarts (AActor *victim)
{
unsigned int i, selections;
fixed_t destX,destY;
angle_t destAngle;
DVector3 dest;
selections = deathmatchstarts.Size ();
if (selections > 0)
{
i = pr_teledm() % selections;
destX = deathmatchstarts[i].x;
destY = deathmatchstarts[i].y;
destAngle = ANG45 * (deathmatchstarts[i].angle/45);
P_Teleport (victim, destX, destY, ONFLOORZ, destAngle, TELF_SOURCEFOG | TELF_DESTFOG);
dest = deathmatchstarts[i].pos;
dest.Z = ONFLOORZ;
P_Teleport (victim, dest, (double)deathmatchstarts[i].angle, TELF_SOURCEFOG | TELF_DESTFOG);
}
else
{

View file

@ -15,12 +15,6 @@ static FRandom pr_wraithfx2 ("WraithFX2");
static FRandom pr_wraithfx3 ("WraithFX3");
static FRandom pr_wraithfx4 ("WraithFX4");
//============================================================================
// Wraith Variables
//
// special1 Internal index into floatbob
//============================================================================
//============================================================================
//
// A_WraithInit
@ -31,15 +25,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_WraithInit)
{
PARAM_ACTION_PROLOGUE;
self->AddZ(48<<FRACBITS);
self->AddZ(48);
// [RH] Make sure the wraith didn't go into the ceiling
if (self->Top() > self->ceilingz)
{
self->SetZ(self->ceilingz - self->height);
self->SetZ(self->ceilingz - self->Height);
}
self->special1 = 0; // index into floatbob
self->WeaveIndexZ = 0; // index into floatbob
return 0;
}
@ -57,7 +51,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_WraithRaiseInit)
self->flags2 &= ~MF2_NONSHOOTABLE;
self->flags3 &= ~MF3_DONTBLAST;
self->flags |= MF_SHOOTABLE|MF_SOLID;
self->floorclip = self->height;
self->Floorclip = self->Height;
return 0;
}
@ -71,7 +65,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_WraithRaise)
{
PARAM_ACTION_PROLOGUE;
if (A_RaiseMobj (self, 2*FRACUNIT))
if (A_RaiseMobj (self, 2))
{
// Reached it's target height
// [RH] Once a buried wraith is fully raised, it should be
@ -119,7 +113,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_WraithFX2)
PARAM_ACTION_PROLOGUE;
AActor *mo;
angle_t angle;
DAngle angle;
int i;
for (i = 2; i; --i)
@ -127,21 +121,17 @@ DEFINE_ACTION_FUNCTION(AActor, A_WraithFX2)
mo = Spawn ("WraithFX2", self->Pos(), ALLOW_REPLACE);
if(mo)
{
if (pr_wraithfx2 ()<128)
angle = pr_wraithfx2() * (360 / 1024.f);
if (pr_wraithfx2() >= 128)
{
angle = self->angle+(pr_wraithfx2()<<22);
angle = -angle;
}
else
{
angle = self->angle-(pr_wraithfx2()<<22);
}
mo->vel.z = 0;
mo->vel.x = FixedMul((pr_wraithfx2()<<7)+FRACUNIT,
finecosine[angle>>ANGLETOFINESHIFT]);
mo->vel.y = FixedMul((pr_wraithfx2()<<7)+FRACUNIT,
finesine[angle>>ANGLETOFINESHIFT]);
angle += self->Angles.Yaw;
mo->Vel.X = ((pr_wraithfx2() << 7) + 1) * angle.Cos();
mo->Vel.Y = ((pr_wraithfx2() << 7) + 1) * angle.Sin();
mo->Vel.Z = 0;
mo->target = self;
mo->floorclip = 10*FRACUNIT;
mo->Floorclip = 10;
}
}
return 0;
@ -160,15 +150,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_WraithFX3)
PARAM_ACTION_PROLOGUE;
AActor *mo;
int numdropped = pr_wraithfx3()%15;
int numdropped = pr_wraithfx3() % 15;
while (numdropped-- > 0)
{
fixed_t xo = (pr_wraithfx3() - 128) << 11;
fixed_t yo = (pr_wraithfx3() - 128) << 11;
fixed_t zo = pr_wraithfx3() << 10;
double xo = (pr_wraithfx3() - 128) / 32.;
double yo = (pr_wraithfx3() - 128) / 32.;
double zo = pr_wraithfx3() / 64.;
mo = Spawn ("WraithFX3", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE);
mo = Spawn("WraithFX3", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE);
if (mo)
{
mo->floorz = self->floorz;
@ -216,9 +206,9 @@ void A_WraithFX4 (AActor *self)
if (spawn4)
{
fixed_t xo = (pr_wraithfx4() - 128) << 12;
fixed_t yo = (pr_wraithfx4() - 128) << 12;
fixed_t zo = (pr_wraithfx4() << 10);
double xo = (pr_wraithfx4() - 128) / 16.;
double yo = (pr_wraithfx4() - 128) / 16.;
double zo = (pr_wraithfx4() / 64.);
mo = Spawn ("WraithFX4", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE);
if (mo)
@ -230,9 +220,9 @@ void A_WraithFX4 (AActor *self)
}
if (spawn5)
{
fixed_t xo = (pr_wraithfx4() - 128) << 11;
fixed_t yo = (pr_wraithfx4() - 128) << 11;
fixed_t zo = (pr_wraithfx4()<<10);
double xo = (pr_wraithfx4() - 128) / 32.;
double yo = (pr_wraithfx4() - 128) / 32.;
double zo = (pr_wraithfx4() / 64.);
mo = Spawn ("WraithFX5", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE);
if (mo)
@ -254,10 +244,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_WraithChase)
{
PARAM_ACTION_PROLOGUE;
int weaveindex = self->special1;
self->AddZ(finesine[weaveindex << BOBTOFINESHIFT] * 8);
self->special1 = (weaveindex + 2) & 63;
// if (self->floorclip > 0)
int weaveindex = self->WeaveIndexZ;
self->AddZ(BobSin(weaveindex));
self->WeaveIndexZ = (weaveindex + 2) & 63;
// if (self->Floorclip > 0)
// {
// P_SetMobjState(self, S_WRAITH_RAISE2);
// return;

View file

@ -1228,7 +1228,7 @@ void G_FinishTravel ()
{
Printf(TEXTCOLOR_RED "No player %d start to travel to!\n", pnum + 1);
// Move to the coordinates this player had when they left the level.
pawn->SetXYZ(pawndup->X(), pawndup->Y(), pawndup->Z());
pawn->SetXYZ(pawndup->Pos());
}
}
oldpawn = pawndup;
@ -1240,13 +1240,10 @@ void G_FinishTravel ()
{
if (!(changeflags & CHANGELEVEL_KEEPFACING))
{
pawn->angle = pawndup->angle;
pawn->pitch = pawndup->pitch;
pawn->Angles = pawndup->Angles;
}
pawn->SetXYZ(pawndup->X(), pawndup->Y(), pawndup->Z());
pawn->vel.x = pawndup->vel.x;
pawn->vel.y = pawndup->vel.y;
pawn->vel.z = pawndup->vel.z;
pawn->SetXYZ(pawndup->Pos());
pawn->Vel = pawndup->Vel;
pawn->Sector = pawndup->Sector;
pawn->floorz = pawndup->floorz;
pawn->ceilingz = pawndup->ceilingz;
@ -1256,7 +1253,7 @@ void G_FinishTravel ()
pawn->floorterrain = pawndup->floorterrain;
pawn->ceilingsector = pawndup->ceilingsector;
pawn->ceilingpic = pawndup->ceilingpic;
pawn->floorclip = pawndup->floorclip;
pawn->Floorclip = pawndup->Floorclip;
pawn->waterlevel = pawndup->waterlevel;
}
else
@ -1316,7 +1313,7 @@ void G_InitLevelLocals ()
NormalLight.ChangeColor (PalEntry (255, 255, 255), 0);
level.gravity = sv_gravity * 35/TICRATE;
level.aircontrol = (fixed_t)(sv_aircontrol * 65536.f);
level.aircontrol = sv_aircontrol;
level.teamdamage = teamdamage;
level.flags = 0;
level.flags2 = 0;
@ -1357,7 +1354,7 @@ void G_InitLevelLocals ()
}
if (info->aircontrol != 0.f)
{
level.aircontrol = (fixed_t)(info->aircontrol * 65536.f);
level.aircontrol = info->aircontrol;
}
if (info->teamdamage != 0.f)
{
@ -1462,15 +1459,14 @@ FString CalcMapName (int episode, int level)
void G_AirControlChanged ()
{
if (level.aircontrol <= 256)
if (level.aircontrol <= 1/256.)
{
level.airfriction = FRACUNIT;
level.airfriction = 1.;
}
else
{
// Friction is inversely proportional to the amount of control
float fric = ((float)level.aircontrol/65536.f) * -0.0941f + 1.0004f;
level.airfriction = (fixed_t)(fric * 65536.f);
level.airfriction = level.aircontrol * -0.0941 + 1.0004;
}
}
@ -1497,26 +1493,11 @@ void G_SerializeLevel (FArchive &arc, bool hubLoad)
<< level.maptime
<< i;
if (SaveVersion >= 3313)
{
// This is a player property now
int nextmusic;
arc << nextmusic;
}
// Hub transitions must keep the current total time
if (!hubLoad)
level.totaltime = i;
if (SaveVersion >= 4507)
{
arc << level.skytexture1 << level.skytexture2;
}
else
{
level.skytexture1 = TexMan.GetTexture(arc.ReadName(), FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_ReturnFirst);
level.skytexture2 = TexMan.GetTexture(arc.ReadName(), FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_ReturnFirst);
}
arc << level.skytexture1 << level.skytexture2;
if (arc.IsLoading())
{
sky1texture = level.skytexture1;
@ -1557,12 +1538,7 @@ void G_SerializeLevel (FArchive &arc, bool hubLoad)
P_SerializeSubsectors(arc);
StatusBar->Serialize (arc);
if (SaveVersion >= 4222)
{ // This must be done *after* thinkers are serialized.
arc << level.DefaultSkybox;
}
arc << level.total_monsters << level.total_items << level.total_secrets;
arc << level.DefaultSkybox << level.total_monsters << level.total_items << level.total_secrets;
// Does this level have custom translations?
FRemapTable *trans;
@ -1792,8 +1768,6 @@ void G_WriteSnapshots (FILE *file)
void G_ReadSnapshots (PNGHandle *png)
{
DWORD chunkLen;
BYTE namelen;
char mapname[256];
FString MapName;
level_info_t *i;
@ -1806,14 +1780,7 @@ void G_ReadSnapshots (PNGHandle *png)
DWORD snapver;
arc << snapver;
if (SaveVersion < 4508)
{
arc << namelen;
arc.Read(mapname, namelen);
mapname[namelen] = 0;
MapName = mapname;
}
else arc << MapName;
arc << MapName;
i = FindLevelInfo (MapName);
i->snapshotVer = snapver;
i->snapshot = new FCompressedMemFile;
@ -1828,14 +1795,7 @@ void G_ReadSnapshots (PNGHandle *png)
DWORD snapver;
arc << snapver;
if (SaveVersion < 4508)
{
arc << namelen;
arc.Read(mapname, namelen);
mapname[namelen] = 0;
MapName = mapname;
}
else arc << MapName;
arc << MapName;
TheDefaultLevelInfo.snapshotVer = snapver;
TheDefaultLevelInfo.snapshot = new FCompressedMemFile;
TheDefaultLevelInfo.snapshot->Serialize (arc);
@ -1846,25 +1806,10 @@ void G_ReadSnapshots (PNGHandle *png)
{
FPNGChunkArchive arc (png->File->GetFile(), VIST_ID, chunkLen);
if (SaveVersion < 4508)
while (arc << MapName, MapName.Len() > 0)
{
arc << namelen;
while (namelen != 0)
{
arc.Read(mapname, namelen);
mapname[namelen] = 0;
i = FindLevelInfo(mapname);
i->flags |= LEVEL_VISITED;
arc << namelen;
}
}
else
{
while (arc << MapName, MapName.Len() > 0)
{
i = FindLevelInfo(MapName);
i->flags |= LEVEL_VISITED;
}
i = FindLevelInfo(MapName);
i->flags |= LEVEL_VISITED;
}
}
@ -1960,8 +1905,6 @@ void P_WriteACSDefereds (FILE *file)
void P_ReadACSDefereds (PNGHandle *png)
{
BYTE namelen;
char mapname[256];
FString MapName;
size_t chunklen;
@ -1971,33 +1914,14 @@ void P_ReadACSDefereds (PNGHandle *png)
{
FPNGChunkArchive arc (png->File->GetFile(), ACSD_ID, chunklen);
if (SaveVersion < 4508)
while (arc << MapName, MapName.Len() > 0)
{
arc << namelen;
while (namelen != 0)
level_info_t *i = FindLevelInfo(MapName);
if (i == NULL)
{
arc.Read(mapname, namelen);
mapname[namelen] = 0;
level_info_t *i = FindLevelInfo(mapname);
if (i == NULL)
{
I_Error("Unknown map '%s' in savegame", mapname);
}
arc << i->defered;
arc << namelen;
}
}
else
{
while (arc << MapName, MapName.Len() > 0)
{
level_info_t *i = FindLevelInfo(MapName);
if (i == NULL)
{
I_Error("Unknown map '%s' in savegame", MapName.GetChars());
}
arc << i->defered;
I_Error("Unknown map '%s' in savegame", MapName.GetChars());
}
arc << i->defered;
}
}
png->File->ResetFilePtr();

View file

@ -304,8 +304,8 @@ struct level_info_t
DWORD outsidefog;
int cdtrack;
unsigned int cdid;
float gravity;
float aircontrol;
double gravity;
double aircontrol;
int WarpTrans;
int airsupply;
DWORD compatflags, compatflags2;
@ -329,7 +329,7 @@ struct level_info_t
FString SoundInfo;
FString SndSeq;
float teamdamage;
double teamdamage;
FOptData optdata;
FMusicMap MusicMap;
@ -377,7 +377,7 @@ struct level_info_t
// [RH] These get zeroed every tic and are updated by thinkers.
struct FSectorScrollValues
{
fixed_t ScrollX, ScrollY;
DVector2 Scroll;
};
struct FLevelLocals
@ -429,9 +429,9 @@ struct FLevelLocals
int total_monsters;
int killed_monsters;
float gravity;
fixed_t aircontrol;
fixed_t airfriction;
double gravity;
double aircontrol;
double airfriction;
int airsupply;
int DefaultEnvironment; // Default sound environment.
@ -444,7 +444,7 @@ struct FLevelLocals
bool FromSnapshot; // The current map was restored from a snapshot
float teamdamage;
double teamdamage;
bool IsJumpingAllowed() const;
bool IsCrouchingAllowed() const;
@ -545,28 +545,33 @@ void G_ClearHubInfo();
enum ESkillProperty
{
SKILLP_AmmoFactor,
SKILLP_DropAmmoFactor,
SKILLP_DamageFactor,
SKILLP_FastMonsters,
SKILLP_Respawn,
SKILLP_RespawnLimit,
SKILLP_Aggressiveness,
SKILLP_DisableCheats,
SKILLP_AutoUseHealth,
SKILLP_SpawnFilter,
SKILLP_EasyBossBrain,
SKILLP_ACSReturn,
SKILLP_MonsterHealth,
SKILLP_FriendlyHealth,
SKILLP_NoPain,
SKILLP_ArmorFactor,
SKILLP_HealthFactor,
SKILLP_EasyKey,
SKILLP_SlowMonsters,
SKILLP_Infight,
};
enum EFSkillProperty // floating point properties
{
SKILLP_AmmoFactor,
SKILLP_DropAmmoFactor,
SKILLP_ArmorFactor,
SKILLP_HealthFactor,
SKILLP_DamageFactor,
SKILLP_Aggressiveness,
SKILLP_MonsterHealth,
SKILLP_FriendlyHealth,
};
int G_SkillProperty(ESkillProperty prop);
double G_SkillProperty(EFSkillProperty prop);
const char * G_SkillName();
typedef TMap<FName, FString> SkillMenuNames;
@ -576,8 +581,11 @@ typedef TMap<FName, FName> SkillActorReplacement;
struct FSkillInfo
{
FName Name;
fixed_t AmmoFactor, DoubleAmmoFactor, DropAmmoFactor;
fixed_t DamageFactor;
double AmmoFactor, DoubleAmmoFactor, DropAmmoFactor;
double DamageFactor;
double ArmorFactor;
double HealthFactor;
bool FastMonsters;
bool SlowMonsters;
bool DisableCheats;
@ -587,7 +595,7 @@ struct FSkillInfo
bool EasyKey;
int RespawnCounter;
int RespawnLimit;
fixed_t Aggressiveness;
double Aggressiveness;
int SpawnFilter;
int ACSReturn;
FString MenuName;
@ -599,12 +607,10 @@ struct FSkillInfo
FString TextColor;
SkillActorReplacement Replace;
SkillActorReplacement Replaced;
fixed_t MonsterHealth;
fixed_t FriendlyHealth;
double MonsterHealth;
double FriendlyHealth;
bool NoPain;
int Infighting;
fixed_t ArmorFactor;
fixed_t HealthFactor;
FSkillInfo() {}
FSkillInfo(const FSkillInfo &other)

View file

@ -989,14 +989,14 @@ DEFINE_MAP_OPTION(gravity, true)
{
parse.ParseAssign();
parse.sc.MustGetFloat();
info->gravity = float(parse.sc.Float);
info->gravity = parse.sc.Float;
}
DEFINE_MAP_OPTION(aircontrol, true)
{
parse.ParseAssign();
parse.sc.MustGetFloat();
info->aircontrol = float(parse.sc.Float);
info->aircontrol = parse.sc.Float;
}
DEFINE_MAP_OPTION(airsupply, true)
@ -1150,7 +1150,7 @@ DEFINE_MAP_OPTION(teamdamage, true)
{
parse.ParseAssign();
parse.sc.MustGetFloat();
info->teamdamage = float(parse.sc.Float);
info->teamdamage = parse.sc.Float;
}
DEFINE_MAP_OPTION(mapbackground, true)

View file

@ -27,26 +27,24 @@ IMPLEMENT_CLASS (AArtiTeleport)
bool AArtiTeleport::Use (bool pickup)
{
fixed_t destX;
fixed_t destY;
angle_t destAngle;
DVector3 dest;
int destAngle;
if (deathmatch)
{
unsigned int selections = deathmatchstarts.Size ();
unsigned int i = pr_tele() % selections;
destX = deathmatchstarts[i].x;
destY = deathmatchstarts[i].y;
destAngle = ANG45 * (deathmatchstarts[i].angle/45);
dest = deathmatchstarts[i].pos;
destAngle = deathmatchstarts[i].angle;
}
else
{
FPlayerStart *start = G_PickPlayerStart(int(Owner->player - players));
destX = start->x;
destY = start->y;
destAngle = ANG45 * (start->angle/45);
dest = start->pos;
destAngle = start->angle;
}
P_Teleport (Owner, destX, destY, ONFLOORZ, destAngle, TELF_SOURCEFOG | TELF_DESTFOG);
dest.Z = ONFLOORZ;
P_Teleport (Owner, dest, (double)destAngle, TELF_SOURCEFOG | TELF_DESTFOG);
bool canlaugh = true;
if (Owner->player->morphTics && (Owner->player->MorphStyle & MORPH_UNDOBYCHAOSDEVICE))
{ // Teleporting away will undo any morph effects (pig)

View file

@ -161,7 +161,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurAtk1)
if ((player = self->target->player) != NULL &&
player->mo == self->target)
{ // Squish the player
player->deltaviewheight = -16*FRACUNIT;
player->deltaviewheight = -16;
}
}
return 0;
@ -175,16 +175,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurAtk1)
//
//----------------------------------------------------------------------------
#define MNTR_CHARGE_SPEED (13*FRACUNIT)
#define MNTR_CHARGE_SPEED (13.)
DEFINE_ACTION_FUNCTION(AActor, A_MinotaurDecide)
{
PARAM_ACTION_PROLOGUE;
bool friendly = !!(self->flags5 & MF5_SUMMONEDMONSTER);
angle_t angle;
AActor *target;
int dist;
double dist;
target = self->target;
if (!target)
@ -195,11 +194,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurDecide)
{
S_Sound (self, CHAN_WEAPON, "minotaur/sight", 1, ATTN_NORM);
}
dist = self->AproxDistance (target);
dist = self->Distance2D(target);
if (target->Top() > self->Z()
&& target->Top() < self->Top()
&& dist < (friendly ? 16*64*FRACUNIT : 8*64*FRACUNIT)
&& dist > 1*64*FRACUNIT
&& dist < (friendly ? 16*64. : 8*64.)
&& dist > 1*64.
&& pr_minotaurdecide() < 150)
{ // Charge attack
// Don't call the state function right away
@ -210,13 +209,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurDecide)
self->flags2 |= MF2_INVULNERABLE;
}
A_FaceTarget (self);
angle = self->angle>>ANGLETOFINESHIFT;
self->vel.x = FixedMul (MNTR_CHARGE_SPEED, finecosine[angle]);
self->vel.y = FixedMul (MNTR_CHARGE_SPEED, finesine[angle]);
self->VelFromAngle(MNTR_CHARGE_SPEED);
self->special1 = TICRATE/2; // Charge duration
}
else if (target->Z() == target->floorz
&& dist < 9*64*FRACUNIT
&& dist < 9*64.
&& pr_minotaurdecide() < (friendly ? 100 : 220))
{ // Floor fire attack
self->SetState (self->FindState ("Hammer"));
@ -260,7 +257,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurCharge)
type = PClass::FindActor("PunchPuff");
}
puff = Spawn (type, self->Pos(), ALLOW_REPLACE);
puff->vel.z = 2*FRACUNIT;
puff->Vel.Z = 2;
self->special1--;
}
else
@ -285,9 +282,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurAtk2)
PARAM_ACTION_PROLOGUE;
AActor *mo;
angle_t angle;
fixed_t vz;
fixed_t z;
DAngle angle;
double vz;
double z;
bool friendly = !!(self->flags5 & MF5_SUMMONEDMONSTER);
if (self->target == NULL)
@ -303,7 +300,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurAtk2)
P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
return 0;
}
z = self->Z() + 40*FRACUNIT;
z = self->Z() + 40;
PClassActor *fx = PClass::FindActor("MinotaurFX1");
if (fx)
{
@ -311,12 +308,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurAtk2)
if (mo != NULL)
{
// S_Sound (mo, CHAN_WEAPON, "minotaur/attack2", 1, ATTN_NORM);
vz = mo->vel.z;
angle = mo->angle;
P_SpawnMissileAngleZ (self, z, fx, angle-(ANG45/8), vz);
P_SpawnMissileAngleZ (self, z, fx, angle+(ANG45/8), vz);
P_SpawnMissileAngleZ (self, z, fx, angle-(ANG45/16), vz);
P_SpawnMissileAngleZ (self, z, fx, angle+(ANG45/16), vz);
vz = mo->Vel.Z;
angle = mo->Angles.Yaw;
P_SpawnMissileAngleZ (self, z, fx, angle-(45./8), vz);
P_SpawnMissileAngleZ (self, z, fx, angle+(45./8), vz);
P_SpawnMissileAngleZ (self, z, fx, angle-(45./16), vz);
P_SpawnMissileAngleZ (self, z, fx, angle+(45./16), vz);
}
}
return 0;
@ -353,12 +350,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurAtk3)
if ((player = self->target->player) != NULL &&
player->mo == self->target)
{ // Squish the player
player->deltaviewheight = -16*FRACUNIT;
player->deltaviewheight = -16;
}
}
else
{
if (self->floorclip > 0 && (i_compatflags & COMPATF_MINOTAUR))
if (self->Floorclip > 0 && (i_compatflags & COMPATF_MINOTAUR))
{
// only play the sound.
S_Sound (self, CHAN_WEAPON, "minotaur/fx2hit", 1, ATTN_NORM);
@ -393,12 +390,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_MntrFloorFire)
AActor *mo;
self->SetZ(self->floorz);
fixedvec2 pos = self->Vec2Offset(
(pr_fire.Random2 () << 10),
(pr_fire.Random2 () << 10));
mo = Spawn("MinotaurFX3", pos.x, pos.y, self->floorz, ALLOW_REPLACE);
double x = pr_fire.Random2() / 64.;
double y = pr_fire.Random2() / 64.;
mo = Spawn("MinotaurFX3", self->Vec2OffsetZ(x, y, self->floorz), ALLOW_REPLACE);
mo->target = self->target;
mo->vel.x = 1; // Force block checking
mo->Vel.X = MinVel; // Force block checking
P_CheckMissileSpawn (mo, self->radius);
return 0;
}
@ -411,18 +408,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_MntrFloorFire)
void P_MinotaurSlam (AActor *source, AActor *target)
{
angle_t angle;
fixed_t thrust;
DAngle angle;
double thrust;
int damage;
angle = source->AngleTo(target);
angle >>= ANGLETOFINESHIFT;
thrust = 16*FRACUNIT+(pr_minotaurslam()<<10);
target->vel.x += FixedMul (thrust, finecosine[angle]);
target->vel.y += FixedMul (thrust, finesine[angle]);
thrust = 16 + pr_minotaurslam() / 64.;
target->VelFromAngle(angle, thrust);
damage = pr_minotaurslam.HitDice (static_cast<AMinotaur *>(source) ? 4 : 6);
int newdam = P_DamageMobj (target, NULL, NULL, damage, NAME_Melee);
P_TraceBleed (newdam > 0 ? newdam : damage, target, angle, 0);
P_TraceBleed (newdam > 0 ? newdam : damage, target, angle, 0.);
if (target->player)
{
target->reactiontime = 14+(pr_minotaurslam()&7);
@ -491,7 +486,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurRoam)
//
// Look for enemy of player
//----------------------------------------------------------------------------
#define MINOTAUR_LOOK_DIST (16*54*FRACUNIT)
#define MINOTAUR_LOOK_DIST (16*54.)
DEFINE_ACTION_FUNCTION(AActor, A_MinotaurLook)
{
@ -505,7 +500,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurLook)
AActor *mo = NULL;
player_t *player;
fixed_t dist;
double dist;
int i;
AActor *master = self->tracer;
@ -519,7 +514,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurLook)
mo = player->mo;
if (mo == master) continue;
if (mo->health <= 0) continue;
dist = self->AproxDistance(mo);
dist = self->Distance2D(mo);
if (dist > MINOTAUR_LOOK_DIST) continue;
self->target = mo;
break;
@ -544,7 +539,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurLook)
if (!(mo->flags3 & MF3_ISMONSTER)) continue;
if (mo->health <= 0) continue;
if (!(mo->flags & MF_SHOOTABLE)) continue;
dist = self->AproxDistance(mo);
dist = self->Distance2D(mo);
if (dist > MINOTAUR_LOOK_DIST) continue;
if ((mo == master) || (mo == self)) continue;
if ((mo->flags5 & MF5_SUMMONEDMONSTER) && (mo->tracer == master)) continue;

View file

@ -63,7 +63,7 @@ void A_Unblock(AActor *self, bool drop)
// [RH] Andy Baker's stealth monsters
if (self->flags & MF_STEALTH)
{
self->alpha = OPAQUE;
self->Alpha = 1.;
self->visdir = 0;
}
@ -142,7 +142,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_UnSetFloorClip)
PARAM_ACTION_PROLOGUE;
self->flags2 &= ~MF2_FLOORCLIP;
self->floorclip = 0;
self->Floorclip = 0;
return 0;
}
@ -189,7 +189,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FreezeDeath)
self->flags |= MF_SOLID|MF_SHOOTABLE|MF_NOBLOOD|MF_ICECORPSE;
self->flags2 |= MF2_PUSHABLE|MF2_TELESTOMP|MF2_PASSMOBJ|MF2_SLIDE;
self->flags3 |= MF3_CRASHED;
self->height = self->GetDefault()->height;
self->Height = self->GetDefault()->Height;
// Remove fuzz effects from frozen actors.
if (self->RenderStyle.BlendOp >= STYLEOP_Fuzz && self->RenderStyle.BlendOp <= STYLEOP_FuzzOrRevSub)
{
@ -201,7 +201,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FreezeDeath)
// [RH] Andy Baker's stealth monsters
if (self->flags & MF_STEALTH)
{
self->alpha = OPAQUE;
self->Alpha = 1;
self->visdir = 0;
}
@ -274,12 +274,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_FreezeDeathChunks)
int numChunks;
AActor *mo;
if ((self->vel.x || self->vel.y || self->vel.z) && !(self->flags6 & MF6_SHATTERING))
if (!self->Vel.isZero() && !(self->flags6 & MF6_SHATTERING))
{
self->tics = 3*TICRATE;
return 0;
}
self->vel.x = self->vel.y = self->vel.z = 0;
self->Vel.Zero();
S_Sound (self, CHAN_BODY, "misc/icebreak", 1, ATTN_NORM);
// [RH] In Hexen, this creates a random number of shards (range [24,56])
@ -287,23 +287,24 @@ DEFINE_ACTION_FUNCTION(AActor, A_FreezeDeathChunks)
// base the number of shards on the size of the dead thing, so bigger
// things break up into more shards than smaller things.
// An actor with radius 20 and height 64 creates ~40 chunks.
numChunks = MAX<int> (4, (self->radius>>FRACBITS)*(self->height>>FRACBITS)/32);
numChunks = MAX<int>(4, int(self->radius * self->Height)/32);
i = (pr_freeze.Random2()) % (numChunks/4);
for (i = MAX (24, numChunks + i); i >= 0; i--)
{
fixed_t xo = (((pr_freeze() - 128)*self->radius) >> 7);
fixed_t yo = (((pr_freeze() - 128)*self->radius) >> 7);
fixed_t zo = (pr_freeze()*self->height / 255);
double xo = (pr_freeze() - 128)*self->radius / 128;
double yo = (pr_freeze() - 128)*self->radius / 128;
double zo = (pr_freeze()*self->Height / 255);
mo = Spawn("IceChunk", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE);
if (mo)
{
mo->SetState (mo->SpawnState + (pr_freeze()%3));
mo->vel.z = FixedDiv(mo->Z() - self->Z(), self->height)<<2;
mo->vel.x = pr_freeze.Random2 () << (FRACBITS-7);
mo->vel.y = pr_freeze.Random2 () << (FRACBITS-7);
mo->SetState (mo->SpawnState + (pr_freeze()%3));
mo->Vel.X = pr_freeze.Random2() / 128.;
mo->Vel.Y = pr_freeze.Random2() / 128.;
mo->Vel.Z = (mo->Z() - self->Z()) / self->Height * 4;
CALL_ACTION(A_IceSetTics, mo); // set a random tic wait
mo->RenderStyle = self->RenderStyle;
mo->alpha = self->alpha;
mo->Alpha = self->Alpha;
}
}
if (self->player)
@ -311,11 +312,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_FreezeDeathChunks)
AActor *head = Spawn("IceChunkHead", self->PosPlusZ(self->player->mo->ViewHeight), ALLOW_REPLACE);
if (head != NULL)
{
head->vel.z = FixedDiv(head->Z() - self->Z(), self->height)<<2;
head->vel.x = pr_freeze.Random2 () << (FRACBITS-7);
head->vel.y = pr_freeze.Random2 () << (FRACBITS-7);
head->Vel.X = pr_freeze.Random2() / 128.;
head->Vel.Y = pr_freeze.Random2() / 128.;
head->Vel.Z = (mo->Z() - self->Z()) / self->Height * 4;
head->health = self->health;
head->angle = self->angle;
head->Angles.Yaw = self->Angles.Yaw;
if (head->IsKindOf(RUNTIME_CLASS(APlayerPawn)))
{
head->player = self->player;
@ -323,9 +325,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_FreezeDeathChunks)
self->player = NULL;
head->ObtainInventory (self);
}
head->pitch = 0;
head->Angles.Pitch = 0.;
head->RenderStyle = self->RenderStyle;
head->alpha = self->alpha;
head->Alpha = self->Alpha;
if (head->player->camera == self)
{
head->player->camera = head;
@ -611,7 +613,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Gravity)
PARAM_ACTION_PROLOGUE;
self->flags &= ~MF_NOGRAVITY;
self->gravity = FRACUNIT;
self->Gravity = 1;
return 0;
}
@ -626,7 +628,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LowGravity)
PARAM_ACTION_PROLOGUE;
self->flags &= ~MF_NOGRAVITY;
self->gravity = FRACUNIT/8;
self->Gravity = 1. / 8;;
return 0;
}
@ -636,34 +638,33 @@ DEFINE_ACTION_FUNCTION(AActor, A_LowGravity)
//
//===========================================================================
void FaceMovementDirection (AActor *actor)
void FaceMovementDirection(AActor *actor)
{
switch (actor->movedir)
{
case DI_EAST:
actor->angle = 0<<24;
actor->Angles.Yaw = 0.;
break;
case DI_NORTHEAST:
actor->angle = 32<<24;
actor->Angles.Yaw = 45.;
break;
case DI_NORTH:
actor->angle = 64<<24;
actor->Angles.Yaw = 90.;
break;
case DI_NORTHWEST:
actor->angle = 96<<24;
actor->Angles.Yaw = 135.;
break;
case DI_WEST:
actor->angle = 128<<24;
actor->Angles.Yaw = 180.;
break;
case DI_SOUTHWEST:
actor->angle = 160<<24;
actor->Angles.Yaw = 225.;
break;
case DI_SOUTH:
actor->angle = 192<<24;
actor->Angles.Yaw = 270.;
break;
case DI_SOUTHEAST:
actor->angle = 224<<24;
actor->Angles.Yaw = 315.;
break;
}
}

View file

@ -24,12 +24,7 @@ IMPLEMENT_CLASS (AHexenArmor)
void ABasicArmor::Serialize (FArchive &arc)
{
Super::Serialize (arc);
arc << SavePercent << BonusCount << MaxAbsorb << MaxFullAbsorb << AbsorbCount << ArmorType;
if (SaveVersion >= 4511)
{
arc << ActualSaveAmount;
}
arc << SavePercent << BonusCount << MaxAbsorb << MaxFullAbsorb << AbsorbCount << ArmorType << ActualSaveAmount;
}
//===========================================================================
@ -67,8 +62,8 @@ AInventory *ABasicArmor::CreateCopy (AActor *other)
{
// BasicArmor that is in use is stored in the inventory as BasicArmor.
// BasicArmor that is in reserve is not.
ABasicArmor *copy = Spawn<ABasicArmor> (0, 0, 0, NO_REPLACE);
copy->SavePercent = SavePercent != 0 ? SavePercent : FRACUNIT/3;
ABasicArmor *copy = Spawn<ABasicArmor> ();
copy->SavePercent = SavePercent != 0 ? SavePercent : 0.33335; // slightly more than 1/3 to avoid roundoff errors.
copy->Amount = Amount;
copy->MaxAmount = MaxAmount;
copy->Icon = Icon;
@ -96,13 +91,13 @@ bool ABasicArmor::HandlePickup (AInventory *item)
{
ABasicArmorBonus *armor = static_cast<ABasicArmorBonus*>(item);
armor->SaveAmount = FixedMul(armor->SaveAmount, G_SkillProperty(SKILLP_ArmorFactor));
armor->SaveAmount = int(armor->SaveAmount * G_SkillProperty(SKILLP_ArmorFactor));
}
else if (item->IsKindOf(RUNTIME_CLASS(ABasicArmorPickup)) && !(item->ItemFlags & IF_IGNORESKILL))
{
ABasicArmorPickup *armor = static_cast<ABasicArmorPickup*>(item);
armor->SaveAmount = FixedMul(armor->SaveAmount, G_SkillProperty(SKILLP_ArmorFactor));
armor->SaveAmount = int(armor->SaveAmount * G_SkillProperty(SKILLP_ArmorFactor));
}
if (Inventory != NULL)
{
@ -130,7 +125,7 @@ void ABasicArmor::AbsorbDamage (int damage, FName damageType, int &newdamage)
}
else
{
saved = full + FixedMul (damage - full, SavePercent);
saved = full + int((damage - full) * SavePercent);
if (MaxAbsorb > 0 && saved + AbsorbCount > MaxAbsorb)
{
saved = MAX(0, MaxAbsorb - AbsorbCount);
@ -179,15 +174,10 @@ void ABasicArmor::AbsorbDamage (int damage, FName damageType, int &newdamage)
// This code is taken and adapted from APowerProtection::ModifyDamage().
// The differences include not using a default value, and of course the way
// the damage factor info is obtained.
const fixed_t *pdf = NULL;
DmgFactors *df = PClass::FindActor(ArmorType)->DamageFactors;
if (df != NULL && df->CountUsed() != 0)
if (df != NULL)
{
pdf = df->CheckFactor(damageType);
if (pdf != NULL)
{
damage = newdamage = FixedMul(damage, *pdf);
}
damage = newdamage = df->Apply(damageType, damage);
}
}
if (Inventory != NULL)
@ -221,7 +211,7 @@ AInventory *ABasicArmorPickup::CreateCopy (AActor *other)
if (!(ItemFlags & IF_IGNORESKILL))
{
SaveAmount = FixedMul(SaveAmount, G_SkillProperty(SKILLP_ArmorFactor));
SaveAmount = int(SaveAmount * G_SkillProperty(SKILLP_ArmorFactor));
}
copy->SavePercent = SavePercent;
@ -249,7 +239,7 @@ bool ABasicArmorPickup::Use (bool pickup)
if (armor == NULL)
{
armor = Spawn<ABasicArmor> (0,0,0, NO_REPLACE);
armor = Spawn<ABasicArmor> ();
armor->BecomeItem ();
Owner->AddInventory (armor);
}
@ -303,7 +293,7 @@ AInventory *ABasicArmorBonus::CreateCopy (AActor *other)
if (!(ItemFlags & IF_IGNORESKILL))
{
SaveAmount = FixedMul(SaveAmount, G_SkillProperty(SKILLP_ArmorFactor));
SaveAmount = int(SaveAmount * G_SkillProperty(SKILLP_ArmorFactor));
}
copy->SavePercent = SavePercent;
@ -332,7 +322,7 @@ bool ABasicArmorBonus::Use (bool pickup)
if (armor == NULL)
{
armor = Spawn<ABasicArmor> (0,0,0, NO_REPLACE);
armor = Spawn<ABasicArmor> ();
armor->BecomeItem ();
armor->Amount = 0;
armor->MaxAmount = MaxSaveAmount;
@ -401,7 +391,7 @@ AInventory *AHexenArmor::CreateCopy (AActor *other)
// Like BasicArmor, HexenArmor is used in the inventory but not the map.
// health is the slot this armor occupies.
// Amount is the quantity to give (0 = normal max).
AHexenArmor *copy = Spawn<AHexenArmor> (0, 0, 0, NO_REPLACE);
AHexenArmor *copy = Spawn<AHexenArmor> ();
copy->AddArmorToSlot (other, health, Amount);
GoAwayAndDie ();
return copy;
@ -452,7 +442,7 @@ bool AHexenArmor::HandlePickup (AInventory *item)
bool AHexenArmor::AddArmorToSlot (AActor *actor, int slot, int amount)
{
APlayerPawn *ppawn;
int hits;
double hits;
if (actor->player != NULL)
{
@ -478,9 +468,9 @@ bool AHexenArmor::AddArmorToSlot (AActor *actor, int slot, int amount)
}
else
{
hits = amount * 5 * FRACUNIT;
fixed_t total = Slots[0]+Slots[1]+Slots[2]+Slots[3]+Slots[4];
fixed_t max = SlotsIncrement[0]+SlotsIncrement[1]+SlotsIncrement[2]+SlotsIncrement[3]+Slots[4]+4*5*FRACUNIT;
hits = amount * 5;
auto total = Slots[0] + Slots[1] + Slots[2] + Slots[3] + Slots[4];
auto max = SlotsIncrement[0] + SlotsIncrement[1] + SlotsIncrement[2] + SlotsIncrement[3] + Slots[4] + 4 * 5;
if (total < max)
{
Slots[slot] += hits;
@ -500,13 +490,13 @@ void AHexenArmor::AbsorbDamage (int damage, FName damageType, int &newdamage)
{
if (!DamageTypeDefinition::IgnoreArmor(damageType))
{
fixed_t savedPercent = Slots[0] + Slots[1] + Slots[2] + Slots[3] + Slots[4];
double savedPercent = Slots[0] + Slots[1] + Slots[2] + Slots[3] + Slots[4];
if (savedPercent)
{ // armor absorbed some damage
if (savedPercent > 100*FRACUNIT)
if (savedPercent > 100)
{
savedPercent = 100*FRACUNIT;
savedPercent = 100;
}
for (int i = 0; i < 4; i++)
{
@ -516,15 +506,8 @@ void AHexenArmor::AbsorbDamage (int damage, FName damageType, int &newdamage)
// with the dragon skin bracers.
if (damage < 10000)
{
#if __APPLE__ && __GNUC__ == 4 && __GNUC_MINOR__ == 2 && __GNUC_PATCHLEVEL__ == 1
// -O1 optimizer bug work around. Only needed for
// GCC 4.2.1 on OS X for 10.4/10.5 tools compatibility.
volatile fixed_t tmp = 300;
Slots[i] -= Scale (damage, SlotsIncrement[i], tmp);
#else
Slots[i] -= Scale (damage, SlotsIncrement[i], 300);
#endif
if (Slots[i] < 2*FRACUNIT)
Slots[i] -= damage * SlotsIncrement[i] / 300.;
if (Slots[i] < 2)
{
Slots[i] = 0;
}
@ -535,10 +518,10 @@ void AHexenArmor::AbsorbDamage (int damage, FName damageType, int &newdamage)
}
}
}
int saved = Scale (damage, savedPercent, 100*FRACUNIT);
if (saved > savedPercent >> (FRACBITS-1))
int saved = int(damage * savedPercent / 100.);
if (saved > savedPercent*2)
{
saved = savedPercent >> (FRACBITS-1);
saved = int(savedPercent*2);
}
newdamage -= saved;
damage = newdamage;

Some files were not shown because too many files have changed in this diff Show more