diff --git a/src/dobjtype.cpp b/src/dobjtype.cpp index cacfec84d4..d2df43fded 100644 --- a/src/dobjtype.cpp +++ b/src/dobjtype.cpp @@ -3152,16 +3152,20 @@ DObject *PClass::CreateNew() const // // PClass :: InitializeSpecials // -// Initialize special fields of a newly-created instance (e.g. strings). +// Initialize special fields (e.g. strings) of a newly-created instance. // //========================================================================== void PClass::InitializeSpecials(void *addr) const { - if (ParentClass != NULL) + // Once we reach a native class, we can stop going up the family tree, + // since native classes handle initialization natively. + if (!bRuntimeClass) { - ParentClass->InitializeSpecials(addr); + return; } + assert(ParentClass != NULL); + ParentClass->InitializeSpecials(addr); for (auto tao : SpecialInits) { tao.first->InitializeValue((BYTE*)addr + tao.second, Defaults + tao.second); @@ -3172,19 +3176,27 @@ void PClass::InitializeSpecials(void *addr) const // // PClass :: DestroySpecials // +// Destroy special fields (e.g. strings) of an instance that is about to be +// deleted. +// //========================================================================== void PClass::DestroySpecials(void *addr) const { - if (ParentClass != NULL) + // Once we reach a native class, we can stop going up the family tree, + // since native classes handle deinitialization natively. + if (!bRuntimeClass) { - ParentClass->DestroySpecials(addr); + return; } + assert(ParentClass != NULL); + ParentClass->DestroySpecials(addr); for (auto tao : SpecialInits) { tao.first->DestroyValue((BYTE *)addr + tao.second); } } + //========================================================================== // // PClass :: Derive diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 2c7f8633d3..40fe650c1e 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -9073,14 +9073,14 @@ scriptwait: // projectile a TID. // Thing_Projectile2 (tid, type, angle, speed, vspeed, gravity, newtid); P_Thing_Projectile(STACK(7), activator, STACK(6), NULL, STACK(5) * (360. / 256.), - ACSToDouble(STACK(4)) / 8., ACSToDouble(STACK(3)) / 8., 0, NULL, STACK(2), STACK(1), false); + STACK(4) / 8., STACK(3) / 8., 0, NULL, STACK(2), STACK(1), false); sp -= 7; break; case PCD_SPAWNPROJECTILE: // Same, but takes an actor name instead of a spawn ID. P_Thing_Projectile(STACK(7), activator, 0, FBehavior::StaticLookupString(STACK(6)), STACK(5) * (360. / 256.), - ACSToDouble(STACK(4)) / 8., ACSToDouble(STACK(3)) / 8., 0, NULL, STACK(2), STACK(1), false); + STACK(4) / 8., STACK(3) / 8., 0, NULL, STACK(2), STACK(1), false); sp -= 7; break; diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index 784c70fd54..19b9169569 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -2820,7 +2820,7 @@ void A_Face(AActor *self, AActor *other, DAngle max_turn, DAngle max_pitch, DAng self->flags &= ~MF_AMBUSH; DAngle other_angle = self->AngleTo(other); - DAngle delta = deltaangle(self->Angles.Yaw, other_angle); + DAngle delta = -deltaangle(self->Angles.Yaw, other_angle); // 0 means no limit. Also, if we turn in a single step anyways, no need to go through the algorithms. // It also means that there is no need to check for going past the other. diff --git a/src/p_map.cpp b/src/p_map.cpp index 82c55eeaa6..26c08af260 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -335,6 +335,8 @@ bool P_TeleportMove(AActor* thing, const DVector3 &pos, bool telefrag, bool modi tmf.abovemidtex = false; P_GetFloorCeilingZ(tmf, 0); + spechit.Clear(); // this is needed so that no more specials get activated after crossing a teleporter. + bool StompAlwaysFrags = ((thing->flags2 & MF2_TELESTOMP) || (level.flags & LEVEL_MONSTERSTELEFRAG) || telefrag) && !(thing->flags7 & MF7_NOTELESTOMP); // P_LineOpening requires the thing's z to be the destination z in order to work. @@ -2284,12 +2286,7 @@ bool P_TryMove(AActor *thing, const DVector2 &pos, line_t *ld = spec.line; // see if the line was crossed - // One more case of trying to preserve some side effects from the original: - // If the reference position is the same as the actor's position before checking the spechits, - // we use the thing's actual position, including all the side effects of the original. - // If some portal transition has to be considered here, we cannot do that and use the reference position stored with the spechit. - bool posisoriginal = (spec.Refpos == lastpos); - side = posisoriginal? P_PointOnLineSide(thing->Pos(), ld) : P_PointOnLineSide(spec.Refpos, ld); + side = P_PointOnLineSide(spec.Refpos, ld); oldside = P_PointOnLineSide(spec.Oldrefpos, ld); if (side != oldside && ld->special && !(thing->flags6 & MF6_NOTRIGGER)) { @@ -5049,7 +5046,7 @@ void P_RadiusAttack(AActor *bombspot, AActor *bombsource, int bombdamage, int bo double bombdamagefloat = (double)bombdamage; FPortalGroupArray grouplist(FPortalGroupArray::PGA_Full3d); - FMultiBlockThingsIterator it(grouplist, bombspot->X(), bombspot->Y(), bombspot->Z() - bombdistance, bombspot->Height + bombdistance*2, bombdistancefloat, false, bombspot->Sector); + FMultiBlockThingsIterator it(grouplist, bombspot->X(), bombspot->Y(), bombspot->Z() - bombdistance, bombspot->Height + bombdistance*2, bombdistance, false, bombspot->Sector); FMultiBlockThingsIterator::CheckResult cres; if (flags & RADF_SOURCEISSPOT) diff --git a/src/p_maputl.cpp b/src/p_maputl.cpp index f51baac160..1235915c27 100644 --- a/src/p_maputl.cpp +++ b/src/p_maputl.cpp @@ -65,21 +65,6 @@ int P_AproxDistance (int dx, int dy) return (dx < dy) ? dx+dy-(dx>>1) : dx+dy-(dy>>1); } -//========================================================================== -// -// P_PointOnDivlineSideCompat -// -// Returns the fractional intercept point along the first divline -// with compatibility flag handling -// -//========================================================================== - -inline int P_PointOnDivlineSideCompat(double x, double y, const divline_t *line) -{ - return (i_compatflags2 & COMPATF2_POINTONLINE) - ? P_VanillaPointOnDivlineSide(x, y, line) : P_PointOnDivlineSide(x, y, line); -} - //========================================================================== // // P_InterceptVector @@ -1168,20 +1153,8 @@ void FPathTraverse::AddLineIntercepts(int bx, int by) double frac; divline_t dl; - // avoid precision problems with two routines - if ( trace.dx > 16 - || trace.dy > 16 - || trace.dx < -16 - || trace.dy < -16) - { - s1 = P_PointOnDivlineSideCompat (ld->v1->fX(), ld->v1->fY(), &trace); - s2 = P_PointOnDivlineSideCompat (ld->v2->fX(), ld->v2->fY(), &trace); - } - else - { - s1 = P_PointOnLineSide (trace.x, trace.y, ld); - s2 = P_PointOnLineSide (trace.x+trace.dx, trace.y+trace.dy, ld); - } + s1 = P_PointOnDivlineSide (ld->v1->fX(), ld->v1->fY(), &trace); + s2 = P_PointOnDivlineSide (ld->v2->fX(), ld->v2->fY(), &trace); if (s1 == s2) continue; // line isn't crossed @@ -1232,81 +1205,82 @@ void FPathTraverse::AddThingIntercepts (int bx, int by, FBlockThingsIterator &it switch (i) { case 0: // Top edge - line.x = thing->X() + thing->radius; line.y = thing->Y() + thing->radius; + if (trace.y < line.y) continue; + line.x = thing->X() + thing->radius; line.dx = -thing->radius * 2; line.dy = 0; break; case 1: // Right edge line.x = thing->X() + thing->radius; + if (trace.x < line.x) continue; line.y = thing->Y() - thing->radius; line.dx = 0; line.dy = thing->radius * 2; break; case 2: // Bottom edge - line.x = thing->X() - thing->radius; line.y = thing->Y() - thing->radius; + if (trace.y > line.y) continue; + line.x = thing->X() - thing->radius; line.dx = thing->radius * 2; line.dy = 0; break; case 3: // Left edge line.x = thing->X() - thing->radius; + if (trace.x > line.x) continue; line.y = thing->Y() + thing->radius; line.dx = 0; line.dy = thing->radius * -2; break; } // Check if this side is facing the trace origin - if (P_PointOnDivlineSide (trace.x, trace.y, &line) == 0) + numfronts++; + + // If it is, see if the trace crosses it + if (P_PointOnDivlineSide (line.x, line.y, &trace) != + P_PointOnDivlineSide (line.x + line.dx, line.y + line.dy, &trace)) { - numfronts++; - - // If it is, see if the trace crosses it - if (P_PointOnDivlineSide (line.x, line.y, &trace) != - P_PointOnDivlineSide (line.x + line.dx, line.y + line.dy, &trace)) - { - // It's a hit - double frac = P_InterceptVector (&trace, &line); - if (frac < Startfrac) - { // behind source - if (Startfrac > 0) + // It's a hit + double frac = P_InterceptVector (&trace, &line); + if (frac < Startfrac) + { // behind source + if (Startfrac > 0) + { + // check if the trace starts within this actor + switch (i) { - // check if the trace starts within this actor - switch (i) - { - case 0: - line.y -= 2 * thing->radius; - break; + case 0: + line.y -= 2 * thing->radius; + break; - case 1: - line.x -= 2 * thing->radius; - break; + case 1: + line.x -= 2 * thing->radius; + break; - case 2: - line.y += 2 * thing->radius; - break; + case 2: + line.y += 2 * thing->radius; + break; - case 3: - line.x += 2 * thing->radius; - break; - } - double frac2 = P_InterceptVector(&trace, &line); - if (frac2 >= Startfrac) goto addit; + case 3: + line.x += 2 * thing->radius; + break; } - continue; + double frac2 = P_InterceptVector(&trace, &line); + if (frac2 >= Startfrac) goto addit; } - addit: - intercept_t newintercept; - newintercept.frac = frac; - newintercept.isaline = false; - newintercept.done = false; - newintercept.d.thing = thing; - intercepts.Push (newintercept); continue; } + addit: + intercept_t newintercept; + newintercept.frac = frac; + newintercept.isaline = false; + newintercept.done = false; + newintercept.d.thing = thing; + intercepts.Push (newintercept); + break; } } @@ -1350,8 +1324,8 @@ void FPathTraverse::AddThingIntercepts (int bx, int by, FBlockThingsIterator &it y2 = thing->Y() + thing->radius; } - s1 = P_PointOnDivlineSideCompat (x1, y1, &trace); - s2 = P_PointOnDivlineSideCompat (x2, y2, &trace); + s1 = P_PointOnDivlineSide (x1, y1, &trace); + s2 = P_PointOnDivlineSide (x2, y2, &trace); if (s1 != s2) { @@ -1478,7 +1452,7 @@ void FPathTraverse::init(double x1, double y1, double x2, double y2, int flags, if (mapex > mapx) { mapxstep = 1; - partialx = xs_CeilToInt(xt1) - xt1; + partialx = 1. - xt1 + xs_FloorToInt(xt1); ystep = (y2 - y1) / fabs(x2 - x1); } else if (mapex < mapx) @@ -1495,11 +1469,10 @@ void FPathTraverse::init(double x1, double y1, double x2, double y2, int flags, } yintercept = yt1 + partialx * ystep; - if (mapey > mapy) { mapystep = 1; - partialy = xs_CeilToInt(yt1) - yt1; + partialy = 1. - yt1 + xs_FloorToInt(yt1); xstep = (x2 - x1) / fabs(y2 - y1); } else if (mapey < mapy) @@ -1894,60 +1867,6 @@ int P_VanillaPointOnLineSide(double x, double y, const line_t* line) return 1; // back side } -//=========================================================================== -// -// P_VanillaPointOnDivlineSide -// P_PointOnDivlineSideCompat() from the initial Doom source code release -// -//=========================================================================== - -int P_VanillaPointOnDivlineSide(double x, double y, const divline_t* line) -{ - int dx; - int dy; - int left; - int right; - int ldx; - int ldy; - - if (!line->dx) - { - if (x <= line->x) - return line->dy > 0; - - return line->dy < 0; - } - if (!line->dy) - { - if (y <= line->y) - return line->dx < 0; - - return line->dx > 0; - } - - // This is supposed to be compatible so the rest needs to be done - // with the same broken fixed point checks as the original - dx = FloatToFixed(x - line->x); - dy = FloatToFixed(y - line->y); - ldx = FloatToFixed(line->dx); - ldy = FloatToFixed(line->dy); - - // try to quickly decide by looking at sign bits - if ( (ldy ^ ldx ^ dx ^ dy)&0x80000000 ) - { - if ( (ldy ^ dx) & 0x80000000 ) - return 1; // (left is negative) - return 0; - } - - left = MulScale16( ldy>>8, dx>>8 ); - right = MulScale16( dy>>8 , ldx>>8 ); - - if (right < left) - return 0; // front side - return 1; // back side -} - //========================================================================== // // Use buggy PointOnSide and fix actors that lie on diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 0bbda1568c..bacef28e40 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -1675,7 +1675,7 @@ bool P_SeekerMissile (AActor *actor, double thresh, double turnMax, bool precise } pitch = DVector2(dist, target->Z() + aimheight - actor->Center()).Angle(); } - actor->Vel3DFromAngle(pitch, speed); + actor->Vel3DFromAngle(-pitch, speed); } return true; diff --git a/src/p_sectors.cpp b/src/p_sectors.cpp index 87c0c45bd6..357b608723 100644 --- a/src/p_sectors.cpp +++ b/src/p_sectors.cpp @@ -624,7 +624,7 @@ double sector_t::FindHighestFloorPoint (vertex_t **v) const if (linecount == 0) *v = &vertexes[0]; else *v = lines[0]->v1; } - return floorplane.fD(); + return -floorplane.fD(); } for (i = 0; i < linecount; i++) diff --git a/src/p_sight.cpp b/src/p_sight.cpp index 57106b2cf0..f8d2043fd0 100644 --- a/src/p_sight.cpp +++ b/src/p_sight.cpp @@ -651,7 +651,7 @@ bool SightCheck::P_SightPathTraverse () if (mapex > mapx) { mapxstep = 1; - partialx = xs_CeilToInt(xt1) - xt1; + partialx = 1. - xt1 + xs_FloorToInt(xt1); ystep = (y2 - y1) / fabs(x2 - x1); } else if (mapex < mapx) @@ -671,7 +671,7 @@ bool SightCheck::P_SightPathTraverse () if (mapey > mapy) { mapystep = 1; - partialy = xs_CeilToInt(yt1) - yt1; + partialy = 1. - yt1 + xs_FloorToInt(yt1); xstep = (x2 - x1) / fabs(y2 - y1); } else if (mapey < mapy) diff --git a/src/p_spec.h b/src/p_spec.h index c934d73126..4098319434 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -836,7 +836,7 @@ enum //Spawns teleport fog. Pass the actor to pluck TeleFogFromType and TeleFogToType. 'from' determines if this is the fog to spawn at the old position (true) or new (false). void P_SpawnTeleportFog(AActor *mobj, const DVector3 &pos, bool beforeTele = true, bool setTarget = false); -inline bool P_Teleport(AActor *thing, DVector3 pos, DAngle angle, int flags); +bool P_Teleport(AActor *thing, DVector3 pos, DAngle angle, int flags); bool EV_Teleport (int tid, int tag, line_t *line, int side, AActor *thing, int flags); bool EV_SilentLineTeleport (line_t *line, int side, AActor *thing, int id, INTBOOL reverse); bool EV_TeleportOther (int other_tid, int dest_tid, bool fog); diff --git a/src/p_user.cpp b/src/p_user.cpp index 63f05ef321..64c4f3a116 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -1510,7 +1510,6 @@ void APlayerPawn::TweakSpeeds (double &forward, double &side) } if (fabs(side) < 0x2800) - if ((unsigned int)(side + 0x27ff) < 0x4fff) { side *= SideMove1; } diff --git a/src/r_defs.h b/src/r_defs.h index 91f81be1c0..5b8d440acc 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -1360,7 +1360,7 @@ struct line_t { vertex_t *v1, *v2; // vertices, from v1 to v2 private: - fixed_t dx, dy; // precalculated v2 - v1 for side checking + DVector2 delta; // precalculated v2 - v1 for side checking public: DWORD flags; DWORD activation; // activation type @@ -1377,19 +1377,12 @@ public: DVector2 Delta() const { - return{ FIXED2DBL(dx), FIXED2DBL(dy) }; - } - - void setDelta(fixed_t x, fixed_t y) - { - dx = x; - dy = y; + return delta; } void setDelta(double x, double y) { - dx = FLOAT2FIXED(x); - dy = FLOAT2FIXED(y); + delta = { x, y }; } void setAlpha(double a) diff --git a/src/s_sound.cpp b/src/s_sound.cpp index c7ac7cebc5..d1fee071e5 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -665,6 +665,7 @@ static void CalcPosVel(int type, const AActor *actor, const sector_t *sector, if (listener != NULL) { listenpos = listener->Pos(); + *pos = listener->SoundPos(); pgroup = listener->Sector->PortalGroup; } else @@ -1276,7 +1277,8 @@ void S_Sound (const FPolyObj *poly, int channel, FSoundID sound_id, float volume void S_Sound(const DVector3 &pos, int channel, FSoundID sound_id, float volume, float attenuation) { - FVector3 p((float)pos.X, (float)pos.Y, (float)pos.Z); + // The sound system switches Y and Z around. + FVector3 p((float)pos.X, (float)pos.Z, (float)pos.Y); S_StartSound (NULL, NULL, NULL, &p, channel, sound_id, volume, attenuation); } diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 09a23d8437..d0a1579329 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -2109,7 +2109,7 @@ bool DoTakeInventory(AActor *receiver, bool orresult, VM_ARGS) if (itemtype == NULL) { - return true; + return false; } if (!orresult) { diff --git a/src/thingdef/thingdef_parse.cpp b/src/thingdef/thingdef_parse.cpp index cd893f13fe..a86be2bc9e 100644 --- a/src/thingdef/thingdef_parse.cpp +++ b/src/thingdef/thingdef_parse.cpp @@ -816,6 +816,7 @@ static bool ParsePropertyParams(FScanner &sc, FPropertyInfo *prop, AActor *defau conv.s = NULL; pref.s = NULL; pref.i = -1; + bag.ScriptPosition = sc; switch ((*p) & 223) { case 'X': // Expression in parentheses or number. diff --git a/src/thingdef/thingdef_properties.cpp b/src/thingdef/thingdef_properties.cpp index 63e74cb24f..c435cd5755 100644 --- a/src/thingdef/thingdef_properties.cpp +++ b/src/thingdef/thingdef_properties.cpp @@ -2358,14 +2358,7 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, face, S, PlayerPawn) FString tmp = str; tmp.ToUpper(); - if (tmp.Len() != 3) - { - bag.ScriptPosition.Message(MSG_WARNING, - "Invalid face '%s' for '%s';\nSTF replacement codes must be 3 characters.\n", - tmp.GetChars(), info->TypeName.GetChars ()); - } - - bool valid = ( + bool valid = (tmp.Len() == 3 && (((tmp[0] >= 'A') && (tmp[0] <= 'Z')) || ((tmp[0] >= '0') && (tmp[0] <= '9'))) && (((tmp[1] >= 'A') && (tmp[1] <= 'Z')) || ((tmp[1] >= '0') && (tmp[1] <= '9'))) && (((tmp[2] >= 'A') && (tmp[2] <= 'Z')) || ((tmp[2] >= '0') && (tmp[2] <= '9'))) @@ -2373,7 +2366,7 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, face, S, PlayerPawn) if (!valid) { bag.ScriptPosition.Message(MSG_WARNING, - "Invalid face '%s' for '%s';\nSTF replacement codes must be alphanumeric.\n", + "Invalid face '%s' for '%s';\nSTF replacement codes must be 3 alphanumeric characters.\n", tmp.GetChars(), info->TypeName.GetChars ()); }