diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 9815e88e9..4c3ec318b 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -5985,21 +5985,21 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) case ACSF_SpawnParticle: { - fixed_t x = args[0]; - fixed_t y = args[1]; - fixed_t z = args[2]; - fixed_t xvel = args[3]; - fixed_t yvel = args[4]; - fixed_t zvel = args[5]; - PalEntry color = args[6]; - int lifetime = args[7]; - bool fullbright = argCount > 8 ? !!args[8] : false; - int startalpha = argCount > 9 ? args[9] : 0xFF; // Byte trans - int size = argCount > 10 ? args[10] : 1; - int fadestep = argCount > 11 ? args[11] : -1; - fixed_t accelx = argCount > 12 ? args[12] : 0; - fixed_t accely = argCount > 13 ? args[13] : 0; - fixed_t accelz = argCount > 14 ? args[14] : 0; + PalEntry color = args[0]; + bool fullbright = argCount > 1 ? !!args[1] : false; + int lifetime = argCount > 2 ? args[2] : 35; + int size = argCount > 3 ? args[3] : 1; + fixed_t x = argCount > 4 ? args[4] : 0; + fixed_t y = argCount > 5 ? args[5] : 0; + fixed_t z = argCount > 6 ? args[6] : 0; + fixed_t xvel = argCount > 7 ? args[7] : 0; + fixed_t yvel = argCount > 8 ? args[8] : 0; + fixed_t zvel = argCount > 9 ? args[9] : 0; + fixed_t accelx = argCount > 10 ? args[10] : 0; + fixed_t accely = argCount > 11 ? args[11] : 0; + fixed_t accelz = argCount > 12 ? args[12] : 0; + int startalpha = argCount > 13 ? args[13] : 0xFF; // Byte trans + int fadestep = argCount > 14 ? args[14] : -1; startalpha = clamp(startalpha, 0, 0xFF); // Clamp to byte lifetime = clamp(lifetime, 0, 0xFF); // Clamp to byte diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 69083d686..963ecbca8 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -1779,7 +1779,8 @@ bool P_SeekerMissile (AActor *actor, angle_t thresh, angle_t turnMax, bool preci angle_t pitch = 0; if (!(actor->flags3 & (MF3_FLOORHUGGER|MF3_CEILINGHUGGER))) { // Need to seek vertically - double dist = MAX(1.0, FVector2(actor->Vec2To(target)).Length()); + fixedvec2 vec = actor->Vec2To(target); + double dist = MAX(1.0, TVector2(vec.x, vec.y).Length()); // Aim at a player's eyes and at the middle of the actor for everything else. fixed_t aimheight = target->height/2; if (target->IsKindOf(RUNTIME_CLASS(APlayerPawn))) @@ -2516,7 +2517,7 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz) { if ((mo->flags & MF_MISSILE) && !(mo->flags & MF_NOCLIP)) { - mo->AddZ(mo->floorz); + mo->SetZ(mo->floorz); if (mo->BounceFlags & BOUNCE_Floors) { mo->FloorBounceMissile (mo->floorsector->floorplane); @@ -3342,7 +3343,7 @@ void AActor::Tick () UnlinkFromWorld (); flags |= MF_NOBLOCKMAP; - SetXYZ(Vec3Offset(velx, vely, vely)); + SetXYZ(Vec3Offset(velx, vely, velz)); SetMovement(velx, vely, velz); LinkToWorld (); } diff --git a/src/p_spec.cpp b/src/p_spec.cpp index bcab07508..f40f6c8ef 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -463,7 +463,7 @@ void P_PlayerInSpecialSector (player_t *player, sector_t * sector) } else if (level.time % sector->damageinterval == 0) { - P_DamageMobj(player->mo, NULL, NULL, sector->damageamount, sector->damagetype); + if (!(player->cheats & (CF_GODMODE|CF_GODMODE2))) P_DamageMobj(player->mo, NULL, NULL, sector->damageamount, sector->damagetype); if ((sector->Flags & SECF_ENDLEVEL) && player->health <= 10 && (!deathmatch || !(dmflags & DF_NO_EXIT))) { G_ExitLevel(0, false); diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 6a03a727f..5054d8fe5 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -2882,34 +2882,66 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnDebris) // A_SpawnParticle // //=========================================================================== +enum SPFflag +{ + SPF_FULLBRIGHT = 1, + SPF_RELPOS = 1 << 1, + SPF_RELVEL = 1 << 2, + SPF_RELACCEL = 1 << 3, + SPF_RELANG = 1 << 4, +}; + DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnParticle) { PARAM_ACTION_PROLOGUE; - PARAM_FIXED (xoff); - PARAM_FIXED (yoff); - PARAM_FIXED (zoff); - PARAM_FIXED (xvel); - PARAM_FIXED (yvel); - PARAM_FIXED (zvel); PARAM_COLOR (color); - PARAM_INT (lifetime); - PARAM_BOOL_OPT (fullbright) { fullbright = false; } - PARAM_INT_OPT (startalpha) { startalpha = 255; } // Byte trans - PARAM_INT_OPT (size) { size = -1; } - PARAM_INT_OPT (fadestep) { fadestep = -1; } + PARAM_INT_OPT (flags) { flags = 0; } + PARAM_INT_OPT (lifetime) { lifetime = 35; } + PARAM_INT_OPT (size) { size = 1; } + PARAM_ANGLE_OPT (angle) { angle = 0; } + PARAM_FIXED_OPT (xoff) { xoff = 0; } + PARAM_FIXED_OPT (yoff) { yoff = 0; } + PARAM_FIXED_OPT (zoff) { zoff = 0; } + PARAM_FIXED_OPT (xvel) { xvel = 0; } + PARAM_FIXED_OPT (yvel) { yvel = 0; } + PARAM_FIXED_OPT (zvel) { zvel = 0; } PARAM_FIXED_OPT (accelx) { accelx = 0; } PARAM_FIXED_OPT (accely) { accely = 0; } PARAM_FIXED_OPT (accelz) { accelz = 0; } + PARAM_FIXED_OPT (startalphaf) { startalphaf = FRACUNIT; } + PARAM_FIXED_OPT (fadestepf) { fadestepf = -FRACUNIT; } - startalpha = clamp(startalpha, 0, 0xFF); // Clamp to byte - lifetime = clamp(lifetime, 0, 0xFF); // Clamp to byte - fadestep = clamp(fadestep, -1, 0xFF); // Clamp to byte inc. -1 (indicating automatic) + BYTE startalpha = (BYTE)(clamp(startalphaf, 0, FRACUNIT) * 255 / FRACUNIT); + int fadestep = fadestepf < 0 ? -1 : clamp(fadestepf, 0, FRACUNIT) * 255 / FRACUNIT; size = clamp(size, 0, 0xFF); // Clamp to byte if (lifetime != 0) { - fixedvec3 pos = self->Vec3Offset(xoff, yoff, zoff); - P_SpawnParticle(pos.x, pos.y, pos.z, xvel, yvel, zvel, color, fullbright, startalpha, lifetime, size, fadestep, accelx, accely, accelz); + const angle_t ang = (angle + ((flags & SPF_RELANG) ? self->angle : 0)) >> ANGLETOFINESHIFT; + fixedvec3 pos; + //[MC] Code ripped right out of A_SpawnItemEx. + if (flags & SPF_RELPOS) + { + // in relative mode negative y values mean 'left' and positive ones mean 'right' + // This is the inverse orientation of the absolute mode! + const fixed_t xof1 = xoff; + xoff = FixedMul(xof1, finecosine[ang]) + FixedMul(yoff, finesine[ang]); + yoff = FixedMul(xof1, finesine[ang]) - FixedMul(yoff, finecosine[ang]); + } + if (flags & SPF_RELVEL) + { + const fixed_t newxvel = FixedMul(xvel, finecosine[ang]) + FixedMul(yvel, finesine[ang]); + yvel = FixedMul(xvel, finesine[ang]) - FixedMul(yvel, finecosine[ang]); + xvel = newxvel; + } + if (flags & SPF_RELACCEL) + { + fixed_t newaccelx = FixedMul(accelx, finecosine[ang]) + FixedMul(accely, finesine[ang]); + accely = FixedMul(accelx, finesine[ang]) - FixedMul(accely, finecosine[ang]); + accelx = newaccelx; + } + pos = self->Vec3Offset(xoff, yoff, zoff); + P_SpawnParticle(pos.x, pos.y, pos.z, xvel, yvel, zvel, color, !!(flags & SPF_FULLBRIGHT), startalpha, lifetime, size, fadestep, accelx, accely, accelz); } return 0; } @@ -6438,4 +6470,4 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckBlock) ACTION_JUMP(block); } return numret; -} +} diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index 82b861b48..40c7b4288 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -202,7 +202,7 @@ ACTOR Actor native //: Thinker action native A_SetScale(float scalex, float scaley = 0, int ptr = AAPTR_DEFAULT); action native A_SetMass(int mass); action native A_SpawnDebris(class spawntype, bool transfer_translation = false, float mult_h = 1, float mult_v = 1); - action native A_SpawnParticle(float xoff, float yoff, float zoff, float velx, float vely, float velz, color color1, int lifetime, bool fullbright = false, int startalpha = 255, int size = 1, int fadestep = -1, float accelx = 0.0, float accely = 0.0, float accelz = 0.0); + action native A_SpawnParticle(color color1, int flags = 0, int lifetime = 35, int size = 1, float angle = 0, float xoff = 0, float yoff = 0, float zoff = 0, float velx = 0, float vely = 0, float velz = 0, float accelx = 0, float accely = 0, float accelz = 0, float startalphaf = 1, float fadestepf = -1); action native A_CheckSight(state label); action native A_ExtChase(bool usemelee, bool usemissile, bool playactive = true, bool nightmarefast = false); action native A_DropInventory(class itemtype); diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt index f750772b1..51e8e845d 100644 --- a/wadsrc/static/actors/constants.txt +++ b/wadsrc/static/actors/constants.txt @@ -510,3 +510,14 @@ enum CBF_SETTRACER = 1 << 3, //^ but with tracer. CBF_SETONPTR = 1 << 4, //Sets the pointer change on the actor doing the checking instead of self. }; + +enum +{ + SPF_FULLBRIGHT = 1, + SPF_RELPOS = 1 << 1, + SPF_RELVEL = 1 << 2, + SPF_RELACCEL = 1 << 3, + SPF_RELANG = 1 << 4, + + SPF_RELATIVE = SPF_RELPOS|SPF_RELVEL|SPF_RELACCEL|SPF_RELANG +};