diff --git a/src/actor.h b/src/actor.h index 6c283b03c..c37adf5e7 100644 --- a/src/actor.h +++ b/src/actor.h @@ -742,7 +742,18 @@ public: // What species am I? virtual FName GetSpecies(); - fixed_t GetBobOffset(fixed_t ticfrac=0) const + double GetBobOffset(fixed_t ticfrac = 0) const + { + if (!(flags2 & MF2_FLOATBOB)) + { + return 0; + } + return BobSin(FloatBobPhase + level.maptime + FIXED2FLOAT(ticfrac)); + } + + + + fixed_t _f_GetBobOffset(fixed_t ticfrac=0) const { if (!(flags2 & MF2_FLOATBOB)) { @@ -1123,6 +1134,7 @@ public: struct sector_t *Sector; subsector_t * subsector; double floorz, ceilingz; // closest together of contacted secs + double dropoffz; // killough 11/98: the lowest floor over all contacted Sectors. inline fixed_t _f_ceilingz() { @@ -1132,8 +1144,11 @@ public: { return FLOAT2FIXED(floorz); } + inline fixed_t _f_dropoffz() + { + return FLOAT2FIXED(dropoffz); + } - fixed_t dropoffz; // killough 11/98: the lowest floor over all contacted Sectors. struct sector_t *floorsector; FTextureID floorpic; // contacted sec floorpic @@ -1275,7 +1290,7 @@ public: FSoundIDNoInit WallBounceSound; FSoundIDNoInit CrushPainSound; - fixed_t MaxDropOffHeight; + double MaxDropOffHeight; double MaxStepHeight; fixed_t _f_MaxStepHeight() diff --git a/src/b_move.cpp b/src/b_move.cpp index f5eba7ea7..a879ef3d2 100644 --- a/src/b_move.cpp +++ b/src/b_move.cpp @@ -297,7 +297,7 @@ bool FCajunMaster::CleanAhead (AActor *thing, fixed_t x, fixed_t y, ticcmd_t *cm if ( !(thing->flags&(MF_DROPOFF|MF_FLOAT)) - && tm._f_floorz() - tm.dropoffz > thing->MaxDropOffHeight ) + && tm.floorz - tm.dropoffz > thing->MaxDropOffHeight ) return false; // don't stand over a dropoff } diff --git a/src/compatibility.cpp b/src/compatibility.cpp index a440ac088..8157506fd 100644 --- a/src/compatibility.cpp +++ b/src/compatibility.cpp @@ -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")) { @@ -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; diff --git a/src/doomdata.h b/src/doomdata.h index dc70d0ccf..9c86e4f3c 100644 --- a/src/doomdata.h +++ b/src/doomdata.h @@ -346,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; @@ -433,7 +431,7 @@ struct FPlayerStart FPlayerStart() { } FPlayerStart(const FMapThing *mthing, int pnum) - : pos(FIXED2DBL(mthing->x), FIXED2DBL(mthing->y), FIXED2DBL(mthing->z)), + : pos(mthing->pos), angle(mthing->angle), type(pnum) { } diff --git a/src/edata.cpp b/src/edata.cpp index 746528575..8176e6a98 100644 --- a/src/edata.cpp +++ b/src/edata.cpp @@ -92,7 +92,7 @@ struct EDMapthing int recordnum; int tid; int type; - fixed_t height; + double height; int args[5]; WORD skillfilter; DWORD flags; @@ -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; diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 8a302c1d7..3d9f2ba7b 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -4768,15 +4768,15 @@ static int SetCVar(AActor *activator, const char *cvarname, int value, bool is_s return 1; } -static bool DoSpawnDecal(AActor *actor, const FDecalTemplate *tpl, int flags, angle_t angle, fixed_t zofs, fixed_t distance) +static bool DoSpawnDecal(AActor *actor, const FDecalTemplate *tpl, int flags, DAngle angle, double zofs, double distance) { if (!(flags & SDF_ABSANGLE)) { - angle += actor->_f_angle(); + angle += actor->Angles.Yaw; } return NULL != ShootDecal(tpl, actor, actor->Sector, actor->X(), actor->Y(), - actor->Center() - actor->Floorclip + actor->GetBobOffset() + FIXED2DBL(zofs), - DAngle(ANGLE2DBL(angle)), FIXED2DBL(distance), !!(flags & SDF_PERMANENT)); + actor->Center() - actor->Floorclip + actor->GetBobOffset() + zofs, + angle, distance, !!(flags & SDF_PERMANENT)); } static void SetActorAngle(AActor *activator, int tid, int angle, bool interpolate) @@ -5674,9 +5674,9 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) if (tpl != NULL) { int flags = (argCount > 2) ? args[2] : 0; - angle_t angle = (argCount > 3) ? (args[3] << FRACBITS) : 0; - fixed_t zoffset = (argCount > 4) ? (args[4] << FRACBITS) : 0; - fixed_t distance = (argCount > 5) ? (args[5] << FRACBITS) : 64*FRACUNIT; + DAngle angle = ACSToAngle((argCount > 3) ? args[3] : 0); + int zoffset = (argCount > 4) ? args[4]: 0; + int distance = (argCount > 5) ? args[5] : 64; if (args[0] == 0) { @@ -8702,11 +8702,11 @@ scriptwait: } else if (pcd == PCD_GETACTORZ) { - STACK(1) = actor->_f_Z() + actor->GetBobOffset(); + STACK(1) = DoubleToACS(actor->Z() + actor->GetBobOffset()); } else { - STACK(1) = pcd == PCD_GETACTORX ? actor->_f_X() : pcd == PCD_GETACTORY ? actor->_f_Y() : actor->_f_Z(); + STACK(1) = DoubleToACS(pcd == PCD_GETACTORX ? actor->X() : pcd == PCD_GETACTORY ? actor->Y() : actor->Z()); } } break; diff --git a/src/p_buildmap.cpp b/src/p_buildmap.cpp index 25691aa3e..b676c8398 100644 --- a/src/p_buildmap.cpp +++ b/src/p_buildmap.cpp @@ -697,9 +697,9 @@ static int LoadSprites (spritetype *sprites, Xsprite *xsprites, int numsprites, for (int i = 0; i < numsprites; ++i) { mapthings[count].thingid = 0; - mapthings[count].x = (sprites[i].x << 12); - mapthings[count].y = -(sprites[i].y << 12); - mapthings[count].z = (bsectors[sprites[i].sectnum].floorZ - sprites[i].z) << 8; + mapthings[count].pos.X = sprites[i].x / 16.; + mapthings[count].pos.Y = -sprites[i].y / 16.; + mapthings[count].pos.Z = (bsectors[sprites[i].sectnum].floorZ - sprites[i].z) / 256.; mapthings[count].angle = (((2048-sprites[i].ang) & 2047) * 360) >> 11; mapthings[count].ClassFilter = 0xffff; mapthings[count].SkillFilter = 0xffff; @@ -786,8 +786,8 @@ static void CreateStartSpot (fixed_t *pos, FMapThing *start) short angle = LittleShort(*(WORD *)(&pos[3])); FMapThing mt = { 0, }; - mt.x = LittleLong(pos[0])<<12; - mt.y = (-LittleLong(pos[1]))<<12; + mt.pos.X = LittleLong(pos[0]) / 16.; + mt.pos.Y = -LittleLong(pos[1]) / 16.; mt.angle = short(Scale((2048-angle)&2047, 360, 2048)); mt.info = DoomEdMap.CheckKey(1); mt.EdNum = 1; diff --git a/src/p_checkposition.h b/src/p_checkposition.h index 0950efd66..713bc79b7 100644 --- a/src/p_checkposition.h +++ b/src/p_checkposition.h @@ -21,7 +21,7 @@ struct FCheckPosition sector_t *sector; double floorz; double ceilingz; - fixed_t dropoffz; + double dropoffz; FTextureID floorpic; int floorterrain; sector_t *floorsector; @@ -55,6 +55,10 @@ struct FCheckPosition { return FLOAT2FIXED(floorz); } + inline fixed_t _f_dropoffz() + { + return FLOAT2FIXED(dropoffz); + } }; diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index 77808344b..a75aa891b 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -879,7 +879,7 @@ void P_NewChaseDir(AActor * actor) } // Try to move away from a dropoff - if (actor->_f_floorz() - actor->dropoffz > actor->MaxDropOffHeight && + if (actor->floorz - actor->dropoffz > actor->MaxDropOffHeight && actor->Z() <= actor->floorz && !(actor->flags & MF_DROPOFF) && !(actor->flags2 & MF2_ONMOBJ) && !(actor->flags & MF_FLOAT) && !(i_compatflags & COMPATF_DROPOFF)) @@ -888,8 +888,8 @@ void P_NewChaseDir(AActor * actor) FBlockLinesIterator it(box); line_t *line; - fixed_t deltax = 0; - fixed_t deltay = 0; + double deltax = 0; + double deltay = 0; while ((line = it.Next())) { if (line->backsector && // Ignore one-sided linedefs @@ -899,31 +899,31 @@ void P_NewChaseDir(AActor * actor) box.Bottom() < line->bbox[BOXTOP] && box.BoxOnLineSide(line) == -1) { - fixed_t front = line->frontsector->floorplane.ZatPoint(actor->PosRelative(line)); - fixed_t back = line->backsector->floorplane.ZatPoint(actor->PosRelative(line)); - angle_t angle; + double front = line->frontsector->floorplane.ZatPointF(actor->PosRelative(line)); + double back = line->backsector->floorplane.ZatPointF(actor->PosRelative(line)); + DAngle angle; // The monster must contact one of the two floors, // and the other must be a tall dropoff. - if (back == actor->_f_Z() && front < actor->_f_Z() - actor->MaxDropOffHeight) + if (back == actor->Z() && front < actor->Z() - actor->MaxDropOffHeight) { - angle = R_PointToAngle2(0,0,line->dx,line->dy); // front side dropoff + angle = line->Delta().Angle(); // front side dropoff } - else if (front == actor->_f_Z() && back < actor->_f_Z() - actor->MaxDropOffHeight) + else if (front == actor->Z() && back < actor->Z() - actor->MaxDropOffHeight) { - angle = R_PointToAngle2(line->dx,line->dy,0,0); // back side dropoff + angle = line->Delta().Angle() + 180.; // back side dropoff } else continue; // Move away from dropoff at a standard speed. // Multiple contacted linedefs are cumulative (e.g. hanging over corner) - deltax -= finesine[angle >> ANGLETOFINESHIFT]*32; - deltay += finecosine[angle >> ANGLETOFINESHIFT]*32; + deltax -= 32 * angle.Sin(); + deltay += 32 * angle.Cos(); } } - if (deltax || deltay) + if (deltax != 0 || deltay != 0) { // [Graf Zahl] I have changed P_TryMove to only apply this logic when // being called from here. AVOIDINGDROPOFF activates the code that @@ -933,7 +933,7 @@ void P_NewChaseDir(AActor * actor) // use different dropoff movement logic in P_TryMove actor->flags5|=MF5_AVOIDINGDROPOFF; - P_DoNewChaseDir(actor, deltax, deltay); + P_DoNewChaseDir(actor, FLOAT2FIXED(deltax), FLOAT2FIXED(deltay)); actor->flags5&=~MF5_AVOIDINGDROPOFF; // If moving away from dropoff, set movecount to 1 so that @@ -2861,30 +2861,29 @@ void A_Face (AActor *self, AActor *other, angle_t _max_turn, angle_t _max_pitch, // disabled and is so by default. if (max_pitch <= 180.) { - fixedvec2 pos = self->_f_Vec2To(other); - DVector2 dist(pos.x, pos.y); + DVector2 dist = self->Vec2To(other); // Positioning ala missile spawning, 32 units above foot level - fixed_t source_z = self->_f_Z() + 32*FRACUNIT + self->GetBobOffset(); - fixed_t target_z = other->_f_Z() + 32*FRACUNIT + other->GetBobOffset(); + double source_z = self->Z() + 32 + self->GetBobOffset(); + double target_z = other->Z() + 32 + other->GetBobOffset(); // If the target z is above the target's head, reposition to the middle of // its body. - if (target_z >= other->_f_Top()) + if (target_z >= other->Top()) { - target_z = other->_f_Z() + (other->_f_height() / 2); + target_z = other->Center(); } //Note there is no +32*FRACUNIT on purpose. This is for customization sake. //If one doesn't want this behavior, just don't use FAF_BOTTOM. if (flags & FAF_BOTTOM) - target_z = other->_f_Z() + other->GetBobOffset(); + target_z = other->Z() + other->GetBobOffset(); if (flags & FAF_MIDDLE) - target_z = other->_f_Z() + (other->_f_height() / 2) + other->GetBobOffset(); + target_z = other->Center() + other->GetBobOffset(); if (flags & FAF_TOP) - target_z = other->_f_Z() + (other->_f_height()) + other->GetBobOffset(); + target_z = other->Top() + other->GetBobOffset(); - target_z += z_add; + target_z += FIXED2FLOAT(z_add); double dist_z = target_z - source_z; double ddist = g_sqrt(dist.X*dist.X + dist.Y*dist.Y + dist_z*dist_z); diff --git a/src/p_map.cpp b/src/p_map.cpp index 0bd03b868..851cc45f5 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -260,7 +260,7 @@ static bool PIT_FindFloorCeiling(FMultiBlockLinesIterator &mit, FMultiBlockLines tmf.touchmidtex = open.touchmidtex; tmf.abovemidtex = open.abovemidtex; if (ffcf_verbose) Printf(" Adjust floorz to %f\n", FIXED2FLOAT(open.bottom)); - if (tmf._f_floorz() > tmf.dropoffz + tmf.thing->MaxDropOffHeight) mit.StopDown(); + if (tmf.floorz > tmf.dropoffz + tmf.thing->MaxDropOffHeight) mit.StopDown(); } else if (open.bottom == tmf._f_floorz()) { @@ -268,11 +268,11 @@ static bool PIT_FindFloorCeiling(FMultiBlockLinesIterator &mit, FMultiBlockLines tmf.abovemidtex |= open.abovemidtex; } - if (open.lowfloor < tmf.dropoffz && open.lowfloor > FIXED_MIN) + if (open.lowfloor < tmf._f_dropoffz() && open.lowfloor > FIXED_MIN) { - tmf.dropoffz = open.lowfloor; + tmf.dropoffz = FIXED2DBL(open.lowfloor); if (ffcf_verbose) Printf(" Adjust dropoffz to %f\n", FIXED2FLOAT(open.bottom)); - if (tmf._f_floorz() > tmf.dropoffz + tmf.thing->MaxDropOffHeight) mit.StopDown(); + if (tmf.floorz > tmf.dropoffz + tmf.thing->MaxDropOffHeight) mit.StopDown(); } } return true; @@ -292,8 +292,7 @@ void P_GetFloorCeilingZ(FCheckPosition &tmf, int flags) F3DFloor *ffc, *fff; tmf.ceilingz = FIXED2DBL(sec->NextHighestCeilingAt(tmf.x, tmf.y, tmf.z, tmf.z + tmf.thing->_f_height(), flags, &tmf.ceilingsector, &ffc)); - tmf.dropoffz = sec->NextLowestFloorAt(tmf.x, tmf.y, tmf.z, flags, tmf.thing->_f_MaxStepHeight(), &tmf.floorsector, &fff); - tmf.floorz = FIXED2DBL(tmf.dropoffz); + tmf.floorz = tmf.dropoffz = FIXED2DBL(sec->NextLowestFloorAt(tmf.x, tmf.y, tmf.z, flags, tmf.thing->_f_MaxStepHeight(), &tmf.floorsector, &fff)); if (fff) { @@ -364,7 +363,7 @@ void P_FindFloorCeiling(AActor *actor, int flags) PIT_FindFloorCeiling(mit, cres, mit.Box(), tmf, flags|cres.portalflags); } - if (tmf.touchmidtex) tmf.dropoffz = tmf._f_floorz(); + if (tmf.touchmidtex) tmf.dropoffz = tmf.floorz; bool usetmf = !(flags & FFCF_ONLYSPAWNPOS) || (tmf.abovemidtex && (tmf.floorz <= actor->Z())); @@ -445,7 +444,7 @@ bool P_TeleportMove(AActor *thing, fixed_t x, fixed_t y, fixed_t z, bool telefra } thing->_f_SetZ(savedz); - if (tmf.touchmidtex) tmf.dropoffz = tmf._f_floorz(); + if (tmf.touchmidtex) tmf.dropoffz = tmf.floorz; FMultiBlockThingsIterator mit2(grouplist, x, y, z, thing->_f_height(), thing->_f_radius(), false, sector); FMultiBlockThingsIterator::CheckResult cres2; @@ -965,9 +964,9 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec tm.abovemidtex |= open.abovemidtex; } - if (open.lowfloor < tm.dropoffz) + if (open.lowfloor < tm._f_dropoffz()) { - tm.dropoffz = open.lowfloor; + tm.dropoffz = FIXED2FLOAT(open.lowfloor); } } @@ -1084,8 +1083,8 @@ static bool PIT_CheckPortal(FMultiBlockLinesIterator &mit, FMultiBlockLinesItera ret = true; } - if (open.lowfloor - zofs < tm.dropoffz) - tm.dropoffz = open.lowfloor - zofs; + if (open.lowfloor - zofs < tm._f_dropoffz()) + tm.dropoffz = FIXED2FLOAT(open.lowfloor - zofs); } tm.thing->_f_AddZ(-zofs); lp->backsector = sec; @@ -1224,7 +1223,7 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch { // [RH] Let monsters walk on actors as well as floors if ((tm.thing->flags3 & MF3_ISMONSTER) && - topz >= tm._f_floorz() && topz <= tm.thing->_f_Z() + tm.thing->_f_MaxStepHeight()) + topz >= tm.floorz && topz <= tm.thing->Z() + tm.thing->MaxStepHeight) { // The commented-out if is an attempt to prevent monsters from walking off a // thing further than they would walk off a ledge. I can't think of an easy @@ -1625,8 +1624,7 @@ bool P_CheckPosition(AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm, bo else { // With noclip2, we must ignore 3D floors and go right to the uppermost ceiling and lowermost floor. - tm.dropoffz = newsec->_f_LowestFloorAt(x, y, &tm.floorsector); - tm.floorz = FIXED2DBL(tm.dropoffz); + tm.floorz = tm.dropoffz = FIXED2FLOAT(newsec->_f_LowestFloorAt(x, y, &tm.floorsector)); tm.ceilingz = FIXED2DBL(newsec->_f_HighestCeilingAt(x, y, &tm.ceilingsector)); tm.floorpic = tm.floorsector->GetTexture(sector_t::floor); tm.floorterrain = tm.floorsector->GetTerrain(sector_t::floor); @@ -1727,7 +1725,7 @@ bool P_CheckPosition(AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm, bo fixed_t thingdropoffz = tm._f_floorz(); //bool onthing = (thingdropoffz != tmdropoffz); - tm.floorz = FIXED2DBL(tm.dropoffz); + tm.floorz = tm.dropoffz; bool good = true; @@ -1760,11 +1758,11 @@ bool P_CheckPosition(AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm, bo } if (tm.touchmidtex) { - tm.dropoffz = tm._f_floorz(); + tm.dropoffz = tm.floorz; } else if (tm.stepthing != NULL) { - tm.dropoffz = thingdropoffz; + tm.dropoffz = FIXED2FLOAT(thingdropoffz); } return (thing->BlockingMobj = thingblocker) == NULL; @@ -2111,7 +2109,7 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, thing->Vel.Z = -8; goto pushline; } - else if (thing->Z() < tm.floorz && tm._f_floorz() - tm.dropoffz > thing->MaxDropOffHeight) + else if (thing->Z() < tm.floorz && tm.floorz - tm.dropoffz > thing->MaxDropOffHeight) { thing->Vel.Z = 8; goto pushline; @@ -2167,7 +2165,7 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, } if (dropoff == 2 && // large jump down (e.g. dogs) - (tm._f_floorz() - tm.dropoffz > 128 * FRACUNIT || thing->target == NULL || thing->target->_f_Z() >tm.dropoffz)) + (tm.floorz - tm.dropoffz > 128. || thing->target == NULL || thing->target->Z() >tm.dropoffz)) { dropoff = false; } @@ -2186,7 +2184,7 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, floorz = MAX(thing->Z(), tm.floorz); } - if (FLOAT2FIXED(floorz) - tm.dropoffz > thing->MaxDropOffHeight && + if (floorz - tm.dropoffz > thing->MaxDropOffHeight && !(thing->flags2 & MF2_BLASTED) && !missileCheck) { // Can't move over a dropoff unless it's been blasted // [GZ] Or missile-spawned @@ -2199,7 +2197,7 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, { // special logic to move a monster off a dropoff // this intentionally does not check for standing on things. - if (thing->_f_floorz() - tm._f_floorz() > thing->MaxDropOffHeight || + if (thing->floorz - tm.floorz > thing->MaxDropOffHeight || thing->dropoffz - tm.dropoffz > thing->MaxDropOffHeight) { thing->flags6 &= ~MF6_INTRYMOVE; @@ -3105,7 +3103,7 @@ const secplane_t * P_CheckSlopeWalk(AActor *actor, fixed_t &xmove, fixed_t &ymov pos.x += xmove; pos.y += ymove; - if (sec->floorplane.ZatPoint(pos) >= actor->_f_Z() - actor->_f_MaxStepHeight()) + if (sec->floorplane.ZatPointF(pos) >= actor->Z() - actor->MaxStepHeight) { dopush = false; break; diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 6cdfbb640..9f894f0f0 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -369,7 +369,7 @@ void AActor::Serialize(FArchive &arc) << SeeState << MeleeState << MissileState - << MaxDropOffHeight + << MaxDropOffHeight << MaxStepHeight << BounceFlags << bouncefactor @@ -2208,13 +2208,13 @@ explode: // killough 8/11/98: add bouncers // killough 9/15/98: add objects falling off ledges // killough 11/98: only include bouncers hanging off ledges - if ((mo->flags & MF_CORPSE) || (mo->BounceFlags & BOUNCE_MBF && mo->_f_Z() > mo->dropoffz) || (mo->flags6 & MF6_FALLING)) + if ((mo->flags & MF_CORPSE) || (mo->BounceFlags & BOUNCE_MBF && mo->Z() > mo->dropoffz) || (mo->flags6 & MF6_FALLING)) { // Don't stop sliding if halfway off a step with some velocity - if (mo->_f_velx() > FRACUNIT/4 || mo->_f_velx() < -FRACUNIT/4 || mo->_f_vely() > FRACUNIT/4 || mo->_f_vely() < -FRACUNIT/4) + if (fabs(mo->Vel.X) > 0.25 || fabs(mo->Vel.Y) > 0.25) { - if (mo->_f_floorz() > mo->Sector->floorplane.ZatPoint(mo)) + if (mo->floorz > mo->Sector->floorplane.ZatPointF(mo)) { - if (mo->dropoffz != mo->_f_floorz()) // 3DMidtex or other special cases that must be excluded + if (mo->dropoffz != mo->floorz) // 3DMidtex or other special cases that must be excluded { unsigned i; for(i=0;iSector->e->XFloor.ffloors.Size();i++) @@ -3743,7 +3743,7 @@ void AActor::Tick () const sector_t *sec = node->m_sector; if (sec->floorplane.c >= STEEPSLOPE) { - if (floorplane.ZatPoint (PosRelative(node->m_sector)) >= _f_Z() - _f_MaxStepHeight()) + if (floorplane.ZatPointF (PosRelative(node->m_sector)) >= Z() - MaxStepHeight) { dopush = false; break; @@ -4192,8 +4192,7 @@ AActor *AActor::StaticSpawn (PClassActor *type, const DVector3 &pos, replace_t a actor->LinkToWorld (SpawningMapThing); actor->ClearInterpolation(); - actor->floorz = actor->Sector->floorplane.ZatPoint(pos); - actor->dropoffz = FLOAT2FIXED(actor->floorz); // killough 11/98: for tracking dropoffs + actor->dropoffz = actor->floorz = actor->Sector->floorplane.ZatPoint(pos); actor->ceilingz = actor->Sector->ceilingplane.ZatPoint(pos); // The z-coordinate needs to be set once before calling P_FindFloorCeiling @@ -4824,7 +4823,6 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position) PClassActor *i; int mask; AActor *mobj; - fixed_t x, y, z; if (mthing->EdNum == 0 || mthing->EdNum == -1) return NULL; @@ -4835,9 +4833,8 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position) if (mentry == NULL) { // [RH] Don't die if the map tries to spawn an unknown thing - Printf ("Unknown type %i at (%i, %i)\n", - mthing->EdNum, - mthing->x>>FRACBITS, mthing->y>>FRACBITS); + Printf("Unknown type %i at (%.1f, %.1f)\n", + mthing->EdNum, mthing->pos.X, mthing->pos.Y); mentry = DoomEdMap.CheckKey(0); if (mentry == NULL) // we need a valid entry for the rest of this function so if we can't find a default, let's exit right away. { @@ -4878,8 +4875,8 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position) { polyspawns_t *polyspawn = new polyspawns_t; polyspawn->next = polyspawns; - polyspawn->x = mthing->x; - polyspawn->y = mthing->y; + polyspawn->x = FLOAT2FIXED(mthing->pos.X); + polyspawn->y = FLOAT2FIXED(mthing->pos.Y); polyspawn->angle = mthing->angle; polyspawn->type = mentry->Special; polyspawns = polyspawn; @@ -5013,7 +5010,7 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position) } else { - P_PointInSector (mthing->x, mthing->y)->seqType = type; + P_PointInSector (mthing->pos)->seqType = type; } return NULL; } @@ -5034,8 +5031,8 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position) if (gameinfo.flags & GI_SHAREWARE) return NULL; - Printf ("%s at (%i, %i) has no frames\n", - i->TypeName.GetChars(), mthing->x>>FRACBITS, mthing->y>>FRACBITS); + Printf ("%s at (%.1f, %.1f) has no frames\n", + i->TypeName.GetChars(), mthing->pos.X, mthing->pos.Y); i = PClass::FindActor("Unknown"); assert(i->IsKindOf(RUNTIME_CLASS(PClassActor))); } @@ -5089,30 +5086,29 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position) } // spawn it - x = mthing->x; - y = mthing->y; + double sz; if (info->flags & MF_SPAWNCEILING) - z = ONCEILINGZ; + sz = ONCEILINGZ; else if (info->flags2 & MF2_SPAWNFLOAT) - z = FLOATRANDZ; + sz = FLOATRANDZ; else - z = ONFLOORZ; + sz = ONFLOORZ; - mobj = AActor::StaticSpawn (i, DVector3(FIXED2DBL(mthing->x), FIXED2DBL(mthing->y), z), NO_REPLACE, true); + mobj = AActor::StaticSpawn (i, DVector3(mthing->pos, sz), NO_REPLACE, true); - if (z == ONFLOORZ) + if (sz == ONFLOORZ) { - mobj->_f_AddZ(mthing->z); + mobj->AddZ(mthing->pos.Z); if ((mobj->flags2 & MF2_FLOATBOB) && (ib_compatflags & BCOMPATF_FLOATBOB)) { - mobj->specialf1 = FIXED2DBL(mthing->z); + mobj->specialf1 = mthing->pos.Z; } } - else if (z == ONCEILINGZ) - mobj->_f_AddZ(-mthing->z); + else if (sz == ONCEILINGZ) + mobj->AddZ(-mthing->pos.Z); - mobj->SpawnPoint = { FIXED2DBL(mthing->x), FIXED2DBL(mthing->y),FIXED2DBL(mthing->z) }; + mobj->SpawnPoint = mthing->pos; mobj->SpawnAngle = mthing->angle; mobj->SpawnFlags = mthing->flags; if (mthing->FloatbobPhase >= 0 && mthing->FloatbobPhase < 64) mobj->FloatBobPhase = mthing->FloatbobPhase; @@ -5884,7 +5880,7 @@ AActor *P_SpawnMissile (AActor *source, AActor *dest, PClassActor *type, AActor { return NULL; } - return P_SpawnMissileXYZ (source->_f_X(), source->_f_Y(), source->_f_Z() + 32*FRACUNIT + source->GetBobOffset(), + return P_SpawnMissileXYZ (source->_f_X(), source->_f_Y(), source->_f_Z() + 32*FRACUNIT + source->_f_GetBobOffset(), source, dest, type, true, owner); } @@ -6015,7 +6011,7 @@ AActor *P_SpawnMissileAngle (AActor *source, PClassActor *type, { return NULL; } - return P_SpawnMissileAngleZSpeed (source, source->_f_Z() + 32*FRACUNIT + source->GetBobOffset(), + return P_SpawnMissileAngleZSpeed (source, source->_f_Z() + 32*FRACUNIT + source->_f_GetBobOffset(), type, angle, vz, GetDefaultSpeed (type)); } @@ -6066,7 +6062,7 @@ AActor *P_SpawnMissileAngleSpeed (AActor *source, PClassActor *type, { return NULL; } - return P_SpawnMissileAngleZSpeed (source, source->_f_Z() + 32*FRACUNIT + source->GetBobOffset(), + return P_SpawnMissileAngleZSpeed (source, source->_f_Z() + 32*FRACUNIT + source->_f_GetBobOffset(), type, angle, vz, speed); } diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 08833a222..067075ee7 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -1671,8 +1671,8 @@ AActor *SpawnMapThing(int index, FMapThing *mt, int position) AActor *spawned = P_SpawnMapThing(mt, position); if (dumpspawnedthings) { - Printf("%5d: (%5d, %5d, %5d), doomednum = %5d, flags = %04x, type = %s\n", - index, mt->x>>FRACBITS, mt->y>>FRACBITS, mt->z>>FRACBITS, mt->EdNum, mt->flags, + Printf("%5d: (%5f, %5f, %5f), doomednum = %5d, flags = %04x, type = %s\n", + index, mt->pos.X, mt->pos.Y, mt->pos.Z, mt->EdNum, mt->flags, spawned? spawned->GetClass()->TypeName.GetChars() : "(none)"); } T_AddSpawnedThing(spawned); @@ -1765,8 +1765,8 @@ void P_LoadThings (MapData * map) mti[i].health = 1; mti[i].FloatbobPhase = -1; - mti[i].x = LittleShort(mt->x) << FRACBITS; - mti[i].y = LittleShort(mt->y) << FRACBITS; + mti[i].pos.X = LittleShort(mt->x); + mti[i].pos.Y = LittleShort(mt->y); mti[i].angle = LittleShort(mt->angle); mti[i].EdNum = LittleShort(mt->type); mti[i].info = DoomEdMap.CheckKey(mti[i].EdNum); @@ -1838,9 +1838,9 @@ void P_LoadThings2 (MapData * map) memset (&mti[i], 0, sizeof(mti[i])); mti[i].thingid = LittleShort(mth[i].thingid); - mti[i].x = LittleShort(mth[i].x)< &spots, TAr if (mentry != NULL && mentry->Type == NULL && mentry->Special >= SMT_PolyAnchor && mentry->Special <= SMT_PolySpawnHurt) { FNodeBuilder::FPolyStart newvert; - newvert.x = MapThingsConverted[i].x; - newvert.y = MapThingsConverted[i].y; + newvert.x = FLOAT2FIXED(MapThingsConverted[i].pos.X); + newvert.y = FLOAT2FIXED(MapThingsConverted[i].pos.Y); newvert.polynum = MapThingsConverted[i].angle; if (mentry->Special == SMT_PolyAnchor) { diff --git a/src/p_slopes.cpp b/src/p_slopes.cpp index 97cf2fb57..0265a1514 100644 --- a/src/p_slopes.cpp +++ b/src/p_slopes.cpp @@ -277,7 +277,7 @@ void P_VavoomSlope(sector_t * sec, int id, fixed_t x, fixed_t y, fixed_t z, int static void P_SetSlopesFromVertexHeights(FMapThing *firstmt, FMapThing *lastmt, const int *oldvertextable) { - TMap vt_heights[2]; + TMap vt_heights[2]; FMapThing *mt; bool vt_found = false; @@ -289,15 +289,15 @@ static void P_SetSlopesFromVertexHeights(FMapThing *firstmt, FMapThing *lastmt, { for (int i = 0; i < numvertexes; i++) { - if (vertexes[i].x == mt->x && vertexes[i].y == mt->y) + if (vertexes[i].fX() == mt->pos.X && vertexes[i].fY() == mt->pos.Y) { if (mt->info->Special == SMT_VertexFloorZ) { - vt_heights[0][i] = mt->z; + vt_heights[0][i] = mt->pos.Z; } else { - vt_heights[1][i] = mt->z; + vt_heights[1][i] = mt->pos.Z; } vt_found = true; } @@ -345,25 +345,20 @@ static void P_SetSlopesFromVertexHeights(FMapThing *firstmt, FMapThing *lastmt, vi3 = (sec->lines[1]->v1 == sec->lines[0]->v1 || sec->lines[1]->v1 == sec->lines[0]->v2)? int(sec->lines[1]->v2 - vertexes) : int(sec->lines[1]->v1 - vertexes); - vt1.X = FIXED2DBL(vertexes[vi1].x); - vt1.Y = FIXED2DBL(vertexes[vi1].y); - vt2.X = FIXED2DBL(vertexes[vi2].x); - vt2.Y = FIXED2DBL(vertexes[vi2].y); - vt3.X = FIXED2DBL(vertexes[vi3].x); - vt3.Y = FIXED2DBL(vertexes[vi3].y); + vt1 = DVector3(vertexes[vi1].fPos(), 0); + vt2 = DVector3(vertexes[vi2].fPos(), 0); + vt3 = DVector3(vertexes[vi3].fPos(), 0); for(int j=0; j<2; j++) { - fixed_t *h1 = vt_heights[j].CheckKey(vi1); - fixed_t *h2 = vt_heights[j].CheckKey(vi2); - fixed_t *h3 = vt_heights[j].CheckKey(vi3); - fixed_t z3; + double *h1 = vt_heights[j].CheckKey(vi1); + double *h2 = vt_heights[j].CheckKey(vi2); + double *h3 = vt_heights[j].CheckKey(vi3); if (h1==NULL && h2==NULL && h3==NULL) continue; - vt1.Z = FIXED2DBL(h1? *h1 : j==0? sec->GetPlaneTexZ(sector_t::floor) : sec->GetPlaneTexZ(sector_t::ceiling)); - vt2.Z = FIXED2DBL(h2? *h2 : j==0? sec->GetPlaneTexZ(sector_t::floor) : sec->GetPlaneTexZ(sector_t::ceiling)); - z3 = h3? *h3 : j==0? sec->GetPlaneTexZ(sector_t::floor) : sec->GetPlaneTexZ(sector_t::ceiling); - vt3.Z = FIXED2DBL(z3); + vt1.Z = h1? *h1 : j==0? sec->GetPlaneTexZF(sector_t::floor) : sec->GetPlaneTexZF(sector_t::ceiling); + vt2.Z = h2? *h2 : j==0? sec->GetPlaneTexZF(sector_t::floor) : sec->GetPlaneTexZF(sector_t::ceiling); + vt3.Z = h3? *h3 : j==0? sec->GetPlaneTexZF(sector_t::floor) : sec->GetPlaneTexZF(sector_t::ceiling); if (P_PointOnLineSidePrecise(vertexes[vi3].x, vertexes[vi3].y, sec->lines[0]) == 0) { @@ -401,7 +396,7 @@ static void P_SetSlopesFromVertexHeights(FMapThing *firstmt, FMapThing *lastmt, srcplane->ic = DivScale32 (1, srcplane->c); srcplane->d = -TMulScale16 (srcplane->a, vertexes[vi3].x, srcplane->b, vertexes[vi3].y, - srcplane->c, z3); + srcplane->c, FLOAT2FIXED(vt3.Z)); } } } @@ -422,14 +417,12 @@ void P_SpawnSlopeMakers (FMapThing *firstmt, FMapThing *lastmt, const int *oldve if (mt->info != NULL && mt->info->Type == NULL && (mt->info->Special >= SMT_SlopeFloorPointLine && mt->info->Special <= SMT_VavoomCeiling)) { - fixed_t x, y, z; + DVector3 pos = mt->pos; secplane_t *refplane; sector_t *sec; bool ceiling; - x = mt->x; - y = mt->y; - sec = P_PointInSector (x, y); + sec = P_PointInSector (mt->pos); if (mt->info->Special == SMT_SlopeCeilingPointLine || mt->info->Special == SMT_VavoomCeiling || mt->info->Special == SMT_SetCeilingSlope) { refplane = &sec->ceilingplane; @@ -440,7 +433,12 @@ void P_SpawnSlopeMakers (FMapThing *firstmt, FMapThing *lastmt, const int *oldve refplane = &sec->floorplane; ceiling = false; } - z = refplane->ZatPoint (x, y) + (mt->z); + pos.Z = refplane->ZatPoint (mt->pos) + mt->pos.Z; + + fixed_t x = FLOAT2FIXED(pos.X); + fixed_t y = FLOAT2FIXED(pos.Y); + fixed_t z = FLOAT2FIXED(pos.Z); + if (mt->info->Special <= SMT_SlopeCeilingPointLine) { // SlopeFloorPointLine and SlopCeilingPointLine P_SlopeLineToPoint (mt->args[0], x, y, z, ceiling); @@ -451,7 +449,7 @@ void P_SpawnSlopeMakers (FMapThing *firstmt, FMapThing *lastmt, const int *oldve } else { // VavoomFloor and VavoomCeiling - P_VavoomSlope(sec, mt->thingid, x, y, mt->z, ceiling); + P_VavoomSlope(sec, mt->thingid, x, y, FLOAT2FIXED(mt->pos.Z), ceiling); } mt->EdNum = 0; } @@ -462,7 +460,7 @@ void P_SpawnSlopeMakers (FMapThing *firstmt, FMapThing *lastmt, const int *oldve if (mt->info != NULL && mt->info->Type == NULL && (mt->info->Special == SMT_CopyFloorPlane || mt->info->Special == SMT_CopyCeilingPlane)) { - P_CopyPlane (mt->args[0], mt->x, mt->y, mt->info->Special == SMT_CopyCeilingPlane); + P_CopyPlane (mt->args[0], FLOAT2FIXED(mt->pos.X), FLOAT2FIXED(mt->pos.Y), mt->info->Special == SMT_CopyCeilingPlane); mt->EdNum = 0; } } diff --git a/src/p_things.cpp b/src/p_things.cpp index 470282f60..206b713f5 100644 --- a/src/p_things.cpp +++ b/src/p_things.cpp @@ -792,7 +792,7 @@ int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, } if ((flags & WARPF_BOB) && (reference->flags2 & MF2_FLOATBOB)) { - caller->_f_AddZ(reference->GetBobOffset()); + caller->_f_AddZ(reference->_f_GetBobOffset()); } } return true; diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index 89b5b9737..365dbb76b 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -487,15 +487,15 @@ public: break; case NAME_X: - th->x = CheckFixed(key); + th->pos.X = CheckFloat(key); break; case NAME_Y: - th->y = CheckFixed(key); + th->pos.Y = CheckFloat(key); break; case NAME_Height: - th->z = CheckFixed(key); + th->pos.Z = CheckFloat(key); break; case NAME_Angle: diff --git a/src/r_defs.h b/src/r_defs.h index 01150afd0..dedb49336 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -105,6 +105,11 @@ struct vertex_t return FIXED2DBL(y); } + DVector2 fPos() + { + return{ fX(), fY() }; + } + bool operator== (const vertex_t &other) { return x == other.x && y == other.y; diff --git a/src/r_things.cpp b/src/r_things.cpp index ac1a7725f..fa5145001 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -770,7 +770,7 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor fixedvec3 pos = thing->InterpolatedPosition(r_TicFrac); fx = pos.x; fy = pos.y; - fz = pos.z + thing->GetBobOffset(r_TicFrac); + fz = pos.z + thing->_f_GetBobOffset(r_TicFrac); tex = NULL; voxel = NULL; diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index bebfce769..86f6f4cf6 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -614,7 +614,7 @@ static void DoAttack (AActor *self, bool domelee, bool domissile, else if (domissile && MissileType != NULL) { // This seemingly senseless code is needed for proper aiming. - double add = MissileHeight + FIXED2FLOAT(self->GetBobOffset()) - 32; + double add = MissileHeight + self->GetBobOffset() - 32; self->AddZ(add); AActor *missile = P_SpawnMissileXYZ (self->PosPlusZ(32.), self, self->target, MissileType, false); self->AddZ(-add); @@ -1197,8 +1197,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomMissile) { PARAM_ACTION_PROLOGUE; PARAM_CLASS (ti, AActor); - PARAM_FIXED_OPT (spawnheight) { spawnheight = 32*FRACUNIT; } - PARAM_INT_OPT (spawnofs_xy) { spawnofs_xy = 0; } + PARAM_FLOAT_OPT (Spawnheight) { Spawnheight = 32; } + PARAM_FLOAT_OPT (Spawnofs_xy) { Spawnofs_xy = 0; } PARAM_DANGLE_OPT(Angle) { Angle = 0.; } PARAM_INT_OPT (flags) { flags = 0; } PARAM_DANGLE_OPT(Pitch) { Pitch = 0.; } @@ -1215,12 +1215,12 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomMissile) { if (ti) { - angle_t ang = (self->_f_angle() - ANGLE_90) >> ANGLETOFINESHIFT; - fixed_t x = spawnofs_xy * finecosine[ang]; - fixed_t y = spawnofs_xy * finesine[ang]; - fixed_t z = spawnheight + self->GetBobOffset() - 32*FRACUNIT + (self->player? FLOAT2FIXED(self->player->crouchoffset) : 0); + DAngle angle = self->Angles.Yaw - 90; + double x = Spawnofs_xy * angle.Cos(); + double y = Spawnofs_xy * angle.Sin(); + double z = Spawnheight + self->GetBobOffset() - 32 + (self->player? self->player->crouchoffset : 0.); - fixedvec3 pos = self->_f_Pos(); + DVector3 pos = self->Pos(); switch (aimmode) { case 0: @@ -1232,12 +1232,12 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomMissile) break; case 1: - missile = P_SpawnMissileXYZ(self->Vec3Offset(x, y, self->GetBobOffset() + spawnheight), self, ref, ti, false); + missile = P_SpawnMissileXYZ(self->Vec3Offset(x, y, self->GetBobOffset() + Spawnheight), self, ref, ti, false); break; case 2: - self->SetXYZ(self->Vec3Offset(x, y, 0)); - missile = P_SpawnMissileAngleZSpeed(self, self->_f_Z() + self->GetBobOffset() + spawnheight, ti, self->_f_angle(), 0, GetDefaultByType(ti)->_f_speed(), self, false); + self->SetXYZ(self->Vec3Offset(x, y, 0.)); + missile = P_SpawnMissileAngleZSpeed(self, self->Z() + self->GetBobOffset() + Spawnheight, ti, self->Angles.Yaw, 0, GetDefaultByType(ti)->Speed, self, false); self->SetXYZ(pos); flags |= CMF_ABSOLUTEPITCH; @@ -1443,7 +1443,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomComboAttack) { PARAM_ACTION_PROLOGUE; PARAM_CLASS (ti, AActor); - PARAM_FIXED (spawnheight); + PARAM_FLOAT (spawnheight); PARAM_INT (damage); PARAM_SOUND_OPT (meleesound) { meleesound = 0; } PARAM_NAME_OPT (damagetype) { damagetype = NAME_Melee; } @@ -1466,9 +1466,10 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomComboAttack) else if (ti) { // This seemingly senseless code is needed for proper aiming. - self->_f_AddZ(spawnheight + self->GetBobOffset() - 32*FRACUNIT); + double add = spawnheight + self->GetBobOffset() - 32; + self->AddZ(add); AActor *missile = P_SpawnMissileXYZ (self->PosPlusZ(32.), self, self->target, ti, false); - self->_f_AddZ(-(spawnheight + self->GetBobOffset() - 32*FRACUNIT)); + self->AddZ(-add); if (missile) { diff --git a/src/thingdef/thingdef_properties.cpp b/src/thingdef/thingdef_properties.cpp index ebc89dc4a..8c2a664e2 100644 --- a/src/thingdef/thingdef_properties.cpp +++ b/src/thingdef/thingdef_properties.cpp @@ -1256,7 +1256,7 @@ DEFINE_PROPERTY(maxstepheight, F, Actor) //========================================================================== DEFINE_PROPERTY(maxdropoffheight, F, Actor) { - PROP_FIXED_PARM(i, 0); + PROP_DOUBLE_PARM(i, 0); defaults->MaxDropOffHeight = i; } diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index aeeaec813..d416cf40a 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -184,7 +184,7 @@ ACTOR Actor native //: Thinker action native A_StopSoundEx(coerce name slot); action native A_SeekerMissile(int threshold, int turnmax, int flags = 0, int chance = 50, int distance = 10); action native state A_Jump(int chance = 256, state label, ...); - action native A_CustomMissile(class missiletype, float spawnheight = 32, int spawnofs_xy = 0, float angle = 0, int flags = 0, float pitch = 0, int ptr = AAPTR_TARGET); + action native A_CustomMissile(class missiletype, float spawnheight = 32, float spawnofs_xy = 0, float angle = 0, int flags = 0, float pitch = 0, int ptr = AAPTR_TARGET); action native A_CustomBulletAttack(float/*angle*/ spread_xy, float/*angle*/ spread_z, int numbullets, int damageperbullet, class pufftype = "BulletPuff", float range = 0, int flags = 0, int ptr = AAPTR_TARGET); action native A_CustomRailgun(int damage, int spawnofs_xy = 0, color color1 = "", color color2 = "", int flags = 0, int aim = 0, float maxdiff = 0, class pufftype = "BulletPuff", float/*angle*/ spread_xy = 0, float/*angle*/ spread_z = 0, float range = 0, int duration = 0, float sparsity = 1.0, float driftspeed = 1.0, class spawnclass = "none", float spawnofs_z = 0, int spiraloffset = 270); action native state A_JumpIfHealthLower(int health, state label, int ptr_selector = AAPTR_DEFAULT);