mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-27 14:22:13 +00:00
Merge branch 'master' of https://github.com/rheit/zdoom
This commit is contained in:
commit
bce9929c22
13 changed files with 205 additions and 30 deletions
|
@ -543,6 +543,7 @@ if( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE )
|
||||||
# C++11 support using SDKs 10.7 and 10.8.
|
# C++11 support using SDKs 10.7 and 10.8.
|
||||||
if ( APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang" )
|
if ( APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang" )
|
||||||
set( CMAKE_CXX_FLAGS "-stdlib=libc++ ${CMAKE_CXX_FLAGS}" )
|
set( CMAKE_CXX_FLAGS "-stdlib=libc++ ${CMAKE_CXX_FLAGS}" )
|
||||||
|
set( CMAKE_EXE_LINKER_FLAGS "-stdlib=libc++ ${CMAKE_EXE_LINKER_FLAGS}" )
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
# Remove extra warnings when using the official DirectX headers.
|
# Remove extra warnings when using the official DirectX headers.
|
||||||
|
|
|
@ -147,7 +147,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BrainSpit)
|
||||||
{
|
{
|
||||||
spit->special2 = 0;
|
spit->special2 = 0;
|
||||||
}
|
}
|
||||||
else if (fabs(spit->Vel.X) > fabs(spit->Vel.Y))
|
else if (fabs(spit->Vel.Y) > fabs(spit->Vel.X))
|
||||||
{
|
{
|
||||||
spit->special2 = int((targ->Y() - self->Y()) / spit->Vel.Y);
|
spit->special2 = int((targ->Y() - self->Y()) / spit->Vel.Y);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1127,12 +1127,27 @@ void APowerWeaponLevel2::InitEffect ()
|
||||||
|
|
||||||
assert (sister->SisterWeapon == weapon);
|
assert (sister->SisterWeapon == weapon);
|
||||||
|
|
||||||
Owner->player->ReadyWeapon = sister;
|
|
||||||
|
|
||||||
if (weapon->GetReadyState() != sister->GetReadyState())
|
if (weapon->GetReadyState() != sister->GetReadyState())
|
||||||
{
|
{
|
||||||
|
Owner->player->ReadyWeapon = sister;
|
||||||
P_SetPsprite(Owner->player, PSP_WEAPON, sister->GetReadyState());
|
P_SetPsprite(Owner->player, PSP_WEAPON, sister->GetReadyState());
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPSprite *psp = Owner->player->FindPSprite(PSP_WEAPON);
|
||||||
|
if (psp != nullptr && psp->GetCaller() == Owner->player->ReadyWeapon)
|
||||||
|
{
|
||||||
|
// If the weapon changes but the state does not, we have to manually change the PSprite's caller here.
|
||||||
|
psp->SetCaller(sister);
|
||||||
|
Owner->player->ReadyWeapon = sister;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Something went wrong. Initiate a regular weapon change.
|
||||||
|
Owner->player->PendingWeapon = sister;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
|
@ -642,7 +642,18 @@ void AWeapon::EndPowerup ()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Owner->player->ReadyWeapon = SisterWeapon;
|
DPSprite *psp = Owner->player->FindPSprite(PSP_WEAPON);
|
||||||
|
if (psp != nullptr && psp->GetCaller() == Owner->player->ReadyWeapon)
|
||||||
|
{
|
||||||
|
// If the weapon changes but the state does not, we have to manually change the PSprite's caller here.
|
||||||
|
psp->SetCaller(SisterWeapon);
|
||||||
|
Owner->player->ReadyWeapon = SisterWeapon;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Something went wrong. Initiate a regular weapon change.
|
||||||
|
Owner->player->PendingWeapon = SisterWeapon;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,6 +81,7 @@ CVAR (Int , hud_showtime, 0, CVAR_ARCHIVE); // Show time on HUD
|
||||||
CVAR (Int , hud_timecolor, CR_GOLD,CVAR_ARCHIVE); // Color of in-game time on HUD
|
CVAR (Int , hud_timecolor, CR_GOLD,CVAR_ARCHIVE); // Color of in-game time on HUD
|
||||||
CVAR (Int , hud_showlag, 0, CVAR_ARCHIVE); // Show input latency (maketic - gametic difference)
|
CVAR (Int , hud_showlag, 0, CVAR_ARCHIVE); // Show input latency (maketic - gametic difference)
|
||||||
|
|
||||||
|
CVAR (Int, hud_ammo_order, 0, CVAR_ARCHIVE); // ammo image and text order
|
||||||
CVAR (Int, hud_ammo_red, 25, CVAR_ARCHIVE) // ammo percent less than which status is red
|
CVAR (Int, hud_ammo_red, 25, CVAR_ARCHIVE) // ammo percent less than which status is red
|
||||||
CVAR (Int, hud_ammo_yellow, 50, CVAR_ARCHIVE) // ammo percent less is yellow more green
|
CVAR (Int, hud_ammo_yellow, 50, CVAR_ARCHIVE) // ammo percent less is yellow more green
|
||||||
CVAR (Int, hud_health_red, 25, CVAR_ARCHIVE) // health amount less than which status is red
|
CVAR (Int, hud_health_red, 25, CVAR_ARCHIVE) // health amount less than which status is red
|
||||||
|
@ -586,9 +587,21 @@ static int DrawAmmo(player_t *CPlayer, int x, int y)
|
||||||
// ok, we got all ammo types. Now draw the list back to front (bottom to top)
|
// ok, we got all ammo types. Now draw the list back to front (bottom to top)
|
||||||
|
|
||||||
int def_width = ConFont->StringWidth("000/000");
|
int def_width = ConFont->StringWidth("000/000");
|
||||||
x-=def_width;
|
|
||||||
int yadd = ConFont->GetHeight();
|
int yadd = ConFont->GetHeight();
|
||||||
|
|
||||||
|
int xtext = x - def_width;
|
||||||
|
int ximage = x;
|
||||||
|
|
||||||
|
if (hud_ammo_order > 0)
|
||||||
|
{
|
||||||
|
xtext -= 24;
|
||||||
|
ximage -= 20;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ximage -= def_width + 20;
|
||||||
|
}
|
||||||
|
|
||||||
for(i=orderedammos.Size()-1;i>=0;i--)
|
for(i=orderedammos.Size()-1;i>=0;i--)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -613,8 +626,8 @@ static int DrawAmmo(player_t *CPlayer, int x, int y)
|
||||||
ammo < ( (maxammo * hud_ammo_red) / 100) ? CR_RED :
|
ammo < ( (maxammo * hud_ammo_red) / 100) ? CR_RED :
|
||||||
ammo < ( (maxammo * hud_ammo_yellow) / 100) ? CR_GOLD : CR_GREEN );
|
ammo < ( (maxammo * hud_ammo_yellow) / 100) ? CR_GOLD : CR_GREEN );
|
||||||
|
|
||||||
DrawHudText(ConFont, fontcolor, buf, x-tex_width, y+yadd, trans);
|
DrawHudText(ConFont, fontcolor, buf, xtext-tex_width, y+yadd, trans);
|
||||||
DrawImageToBox(TexMan[icon], x-20, y, 16, 8, trans);
|
DrawImageToBox(TexMan[icon], ximage, y, 16, 8, trans);
|
||||||
y-=10;
|
y-=10;
|
||||||
}
|
}
|
||||||
return y;
|
return y;
|
||||||
|
|
|
@ -325,7 +325,8 @@ enum // P_LineAttack flags
|
||||||
{
|
{
|
||||||
LAF_ISMELEEATTACK = 1,
|
LAF_ISMELEEATTACK = 1,
|
||||||
LAF_NORANDOMPUFFZ = 2,
|
LAF_NORANDOMPUFFZ = 2,
|
||||||
LAF_NOIMPACTDECAL = 4
|
LAF_NOIMPACTDECAL = 4,
|
||||||
|
LAF_NOINTERACT = 8,
|
||||||
};
|
};
|
||||||
|
|
||||||
AActor *P_LineAttack(AActor *t1, DAngle angle, double distance, DAngle pitch, int damage, FName damageType, PClassActor *pufftype, int flags = 0, FTranslatedLineTarget *victim = NULL, int *actualdamage = NULL);
|
AActor *P_LineAttack(AActor *t1, DAngle angle, double distance, DAngle pitch, int damage, FName damageType, PClassActor *pufftype, int flags = 0, FTranslatedLineTarget *victim = NULL, int *actualdamage = NULL);
|
||||||
|
|
|
@ -4096,6 +4096,7 @@ static ETraceStatus CheckForActor(FTraceResults &res, void *userdata)
|
||||||
AActor *P_LineAttack(AActor *t1, DAngle angle, double distance,
|
AActor *P_LineAttack(AActor *t1, DAngle angle, double distance,
|
||||||
DAngle pitch, int damage, FName damageType, PClassActor *pufftype, int flags, FTranslatedLineTarget*victim, int *actualdamage)
|
DAngle pitch, int damage, FName damageType, PClassActor *pufftype, int flags, FTranslatedLineTarget*victim, int *actualdamage)
|
||||||
{
|
{
|
||||||
|
bool nointeract = !!(flags & LAF_NOINTERACT);
|
||||||
DVector3 direction;
|
DVector3 direction;
|
||||||
double shootz;
|
double shootz;
|
||||||
FTraceResults trace;
|
FTraceResults trace;
|
||||||
|
@ -4185,26 +4186,32 @@ AActor *P_LineAttack(AActor *t1, DAngle angle, double distance,
|
||||||
}
|
}
|
||||||
|
|
||||||
int tflags;
|
int tflags;
|
||||||
if (puffDefaults != NULL && puffDefaults->flags6 & MF6_NOTRIGGER) tflags = TRACE_NoSky;
|
if (nointeract || (puffDefaults && puffDefaults->flags6 & MF6_NOTRIGGER)) tflags = TRACE_NoSky;
|
||||||
else tflags = TRACE_NoSky | TRACE_Impact;
|
else tflags = TRACE_NoSky | TRACE_Impact;
|
||||||
|
|
||||||
if (!Trace(t1->PosAtZ(shootz), t1->Sector, direction, distance, MF_SHOOTABLE,
|
if (!Trace(t1->PosAtZ(shootz), t1->Sector, direction, distance, MF_SHOOTABLE,
|
||||||
ML_BLOCKEVERYTHING | ML_BLOCKHITSCAN, t1, trace, tflags, CheckForActor, &TData))
|
ML_BLOCKEVERYTHING | ML_BLOCKHITSCAN, t1, trace, tflags, CheckForActor, &TData))
|
||||||
{ // hit nothing
|
{ // hit nothing
|
||||||
if (puffDefaults == NULL)
|
if (!nointeract && puffDefaults && puffDefaults->ActiveSound)
|
||||||
{
|
|
||||||
}
|
|
||||||
else if (puffDefaults->ActiveSound)
|
|
||||||
{ // Play miss sound
|
{ // Play miss sound
|
||||||
S_Sound(t1, CHAN_WEAPON, puffDefaults->ActiveSound, 1, ATTN_NORM);
|
S_Sound(t1, CHAN_WEAPON, puffDefaults->ActiveSound, 1, ATTN_NORM);
|
||||||
}
|
}
|
||||||
if (puffDefaults != NULL && puffDefaults->flags3 & MF3_ALWAYSPUFF)
|
|
||||||
|
// [MC] LAF_NOINTERACT guarantees puff spawning and returns it directly to the calling function.
|
||||||
|
// No damage caused, no sounds played, no blood splatters.
|
||||||
|
|
||||||
|
if (nointeract || (puffDefaults && puffDefaults->flags3 & MF3_ALWAYSPUFF))
|
||||||
{ // Spawn the puff anyway
|
{ // Spawn the puff anyway
|
||||||
puff = P_SpawnPuff(t1, pufftype, trace.HitPos, trace.SrcAngleFromTarget, trace.SrcAngleFromTarget, 2, puffFlags);
|
puff = P_SpawnPuff(t1, pufftype, trace.HitPos, trace.SrcAngleFromTarget, trace.SrcAngleFromTarget, 2, puffFlags);
|
||||||
|
|
||||||
|
if (nointeract)
|
||||||
|
{
|
||||||
|
return puff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -4212,12 +4219,17 @@ AActor *P_LineAttack(AActor *t1, DAngle angle, double distance,
|
||||||
if (trace.HitType != TRACE_HitActor)
|
if (trace.HitType != TRACE_HitActor)
|
||||||
{
|
{
|
||||||
// position a bit closer for puffs
|
// position a bit closer for puffs
|
||||||
if (trace.HitType != TRACE_HitWall || ((trace.Line->special != Line_Horizon) || spawnSky))
|
if (nointeract || trace.HitType != TRACE_HitWall || ((trace.Line->special != Line_Horizon) || spawnSky))
|
||||||
{
|
{
|
||||||
DVector2 pos = P_GetOffsetPosition(trace.HitPos.X, trace.HitPos.Y, -trace.HitVector.X * 4, -trace.HitVector.Y * 4);
|
DVector2 pos = P_GetOffsetPosition(trace.HitPos.X, trace.HitPos.Y, -trace.HitVector.X * 4, -trace.HitVector.Y * 4);
|
||||||
puff = P_SpawnPuff(t1, pufftype, DVector3(pos, trace.HitPos.Z - trace.HitVector.Z * 4), trace.SrcAngleFromTarget,
|
puff = P_SpawnPuff(t1, pufftype, DVector3(pos, trace.HitPos.Z - trace.HitVector.Z * 4), trace.SrcAngleFromTarget,
|
||||||
trace.SrcAngleFromTarget - 90, 0, puffFlags);
|
trace.SrcAngleFromTarget - 90, 0, puffFlags);
|
||||||
puff->radius = 1/65536.;
|
puff->radius = 1/65536.;
|
||||||
|
|
||||||
|
if (nointeract)
|
||||||
|
{
|
||||||
|
return puff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// [RH] Spawn a decal
|
// [RH] Spawn a decal
|
||||||
|
@ -4255,14 +4267,6 @@ AActor *P_LineAttack(AActor *t1, DAngle angle, double distance,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool bloodsplatter = (t1->flags5 & MF5_BLOODSPLATTER) ||
|
|
||||||
(t1->player != NULL && t1->player->ReadyWeapon != NULL &&
|
|
||||||
(t1->player->ReadyWeapon->WeaponFlags & WIF_AXEBLOOD));
|
|
||||||
|
|
||||||
bool axeBlood = (t1->player != NULL &&
|
|
||||||
t1->player->ReadyWeapon != NULL &&
|
|
||||||
(t1->player->ReadyWeapon->WeaponFlags & WIF_AXEBLOOD));
|
|
||||||
|
|
||||||
// Hit a thing, so it could be either a puff or blood
|
// Hit a thing, so it could be either a puff or blood
|
||||||
DVector3 bleedpos = trace.HitPos;
|
DVector3 bleedpos = trace.HitPos;
|
||||||
// position a bit closer for puffs/blood if using compatibility mode.
|
// position a bit closer for puffs/blood if using compatibility mode.
|
||||||
|
@ -4275,7 +4279,7 @@ AActor *P_LineAttack(AActor *t1, DAngle angle, double distance,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Spawn bullet puffs or blood spots, depending on target type.
|
// Spawn bullet puffs or blood spots, depending on target type.
|
||||||
if ((puffDefaults != NULL && puffDefaults->flags3 & MF3_PUFFONACTORS) ||
|
if (nointeract || (puffDefaults && puffDefaults->flags3 & MF3_PUFFONACTORS) ||
|
||||||
(trace.Actor->flags & MF_NOBLOOD) ||
|
(trace.Actor->flags & MF_NOBLOOD) ||
|
||||||
(trace.Actor->flags2 & (MF2_INVULNERABLE | MF2_DORMANT)))
|
(trace.Actor->flags2 & (MF2_INVULNERABLE | MF2_DORMANT)))
|
||||||
{
|
{
|
||||||
|
@ -4284,6 +4288,11 @@ AActor *P_LineAttack(AActor *t1, DAngle angle, double distance,
|
||||||
|
|
||||||
// We must pass the unreplaced puff type here
|
// We must pass the unreplaced puff type here
|
||||||
puff = P_SpawnPuff(t1, pufftype, bleedpos, trace.SrcAngleFromTarget, trace.SrcAngleFromTarget - 90, 2, puffFlags | PF_HITTHING, trace.Actor);
|
puff = P_SpawnPuff(t1, pufftype, bleedpos, trace.SrcAngleFromTarget, trace.SrcAngleFromTarget - 90, 2, puffFlags | PF_HITTHING, trace.Actor);
|
||||||
|
|
||||||
|
if (nointeract)
|
||||||
|
{
|
||||||
|
return puff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow puffs to inflict poison damage, so that hitscans can poison, too.
|
// Allow puffs to inflict poison damage, so that hitscans can poison, too.
|
||||||
|
@ -4320,6 +4329,14 @@ AActor *P_LineAttack(AActor *t1, DAngle angle, double distance,
|
||||||
}
|
}
|
||||||
if (!(puffDefaults != NULL && puffDefaults->flags3&MF3_BLOODLESSIMPACT))
|
if (!(puffDefaults != NULL && puffDefaults->flags3&MF3_BLOODLESSIMPACT))
|
||||||
{
|
{
|
||||||
|
bool bloodsplatter = (t1->flags5 & MF5_BLOODSPLATTER) ||
|
||||||
|
(t1->player != nullptr && t1->player->ReadyWeapon != nullptr &&
|
||||||
|
(t1->player->ReadyWeapon->WeaponFlags & WIF_AXEBLOOD));
|
||||||
|
|
||||||
|
bool axeBlood = (t1->player != nullptr &&
|
||||||
|
t1->player->ReadyWeapon != nullptr &&
|
||||||
|
(t1->player->ReadyWeapon->WeaponFlags & WIF_AXEBLOOD));
|
||||||
|
|
||||||
if (!bloodsplatter && !axeBlood &&
|
if (!bloodsplatter && !axeBlood &&
|
||||||
!(trace.Actor->flags & MF_NOBLOOD) &&
|
!(trace.Actor->flags & MF_NOBLOOD) &&
|
||||||
!(trace.Actor->flags2 & (MF2_INVULNERABLE | MF2_DORMANT)))
|
!(trace.Actor->flags2 & (MF2_INVULNERABLE | MF2_DORMANT)))
|
||||||
|
|
|
@ -77,6 +77,7 @@ public:
|
||||||
FState* GetState() const { return State; }
|
FState* GetState() const { return State; }
|
||||||
DPSprite* GetNext() { return Next; }
|
DPSprite* GetNext() { return Next; }
|
||||||
AActor* GetCaller() { return Caller; }
|
AActor* GetCaller() { return Caller; }
|
||||||
|
void SetCaller(AActor *newcaller) { Caller = newcaller; }
|
||||||
|
|
||||||
double x, y;
|
double x, y;
|
||||||
double oldx, oldy;
|
double oldx, oldy;
|
||||||
|
|
|
@ -1622,8 +1622,13 @@ enum CBA_Flags
|
||||||
CBAF_EXPLICITANGLE = 4,
|
CBAF_EXPLICITANGLE = 4,
|
||||||
CBAF_NOPITCH = 8,
|
CBAF_NOPITCH = 8,
|
||||||
CBAF_NORANDOMPUFFZ = 16,
|
CBAF_NORANDOMPUFFZ = 16,
|
||||||
|
CBAF_PUFFTARGET = 32,
|
||||||
|
CBAF_PUFFMASTER = 64,
|
||||||
|
CBAF_PUFFTRACER = 128,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void AimBulletMissile(AActor *proj, AActor *puff, int flags, bool temp, bool cba);
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomBulletAttack)
|
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomBulletAttack)
|
||||||
{
|
{
|
||||||
PARAM_SELF_PROLOGUE(AActor);
|
PARAM_SELF_PROLOGUE(AActor);
|
||||||
|
@ -1635,6 +1640,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomBulletAttack)
|
||||||
PARAM_FLOAT_OPT (range) { range = 0; }
|
PARAM_FLOAT_OPT (range) { range = 0; }
|
||||||
PARAM_INT_OPT (flags) { flags = 0; }
|
PARAM_INT_OPT (flags) { flags = 0; }
|
||||||
PARAM_INT_OPT (ptr) { ptr = AAPTR_TARGET; }
|
PARAM_INT_OPT (ptr) { ptr = AAPTR_TARGET; }
|
||||||
|
PARAM_CLASS_OPT (missile, AActor) { missile = nullptr; }
|
||||||
|
PARAM_FLOAT_OPT (Spawnheight) { Spawnheight = 32; }
|
||||||
|
PARAM_FLOAT_OPT (Spawnofs_xy) { Spawnofs_xy = 0; }
|
||||||
|
|
||||||
AActor *ref = COPY_AAPTR(self, ptr);
|
AActor *ref = COPY_AAPTR(self, ptr);
|
||||||
|
|
||||||
|
@ -1679,7 +1687,30 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomBulletAttack)
|
||||||
if (!(flags & CBAF_NORANDOM))
|
if (!(flags & CBAF_NORANDOM))
|
||||||
damage *= ((pr_cabullet()%3)+1);
|
damage *= ((pr_cabullet()%3)+1);
|
||||||
|
|
||||||
P_LineAttack(self, angle, range, slope, damage, NAME_Hitscan, pufftype, laflags);
|
AActor *puff = P_LineAttack(self, angle, range, slope, damage, NAME_Hitscan, pufftype, laflags);
|
||||||
|
if (missile != nullptr && pufftype != nullptr)
|
||||||
|
{
|
||||||
|
double x = Spawnofs_xy * angle.Cos();
|
||||||
|
double y = Spawnofs_xy * angle.Sin();
|
||||||
|
|
||||||
|
DVector3 pos = self->Pos();
|
||||||
|
self->SetXYZ(self->Vec3Offset(x, y, 0.));
|
||||||
|
AActor *proj = P_SpawnMissileAngleZSpeed(self, self->Z() + self->GetBobOffset() + Spawnheight, missile, self->Angles.Yaw, 0, GetDefaultByType(missile)->Speed, self, false);
|
||||||
|
self->SetXYZ(pos);
|
||||||
|
|
||||||
|
if (proj)
|
||||||
|
{
|
||||||
|
bool temp = (puff == nullptr);
|
||||||
|
if (!puff)
|
||||||
|
{
|
||||||
|
puff = P_LineAttack(self, angle, range, slope, 0, NAME_Hitscan, pufftype, laflags | LAF_NOINTERACT);
|
||||||
|
}
|
||||||
|
if (puff)
|
||||||
|
{
|
||||||
|
AimBulletMissile(proj, puff, flags, temp, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1808,8 +1839,46 @@ enum FB_Flags
|
||||||
FBF_NOPITCH = 8,
|
FBF_NOPITCH = 8,
|
||||||
FBF_NOFLASH = 16,
|
FBF_NOFLASH = 16,
|
||||||
FBF_NORANDOMPUFFZ = 32,
|
FBF_NORANDOMPUFFZ = 32,
|
||||||
|
FBF_PUFFTARGET = 64,
|
||||||
|
FBF_PUFFMASTER = 128,
|
||||||
|
FBF_PUFFTRACER = 256,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void AimBulletMissile(AActor *proj, AActor *puff, int flags, bool temp, bool cba)
|
||||||
|
{
|
||||||
|
if (proj && puff)
|
||||||
|
{
|
||||||
|
if (proj)
|
||||||
|
{
|
||||||
|
// FAF_BOTTOM = 1
|
||||||
|
// Aim for the base of the puff as that's where blood puffs will spawn... roughly.
|
||||||
|
|
||||||
|
A_Face(proj, puff, 0., 0., 0., 0., 1);
|
||||||
|
proj->Vel3DFromAngle(-proj->Angles.Pitch, proj->Speed);
|
||||||
|
|
||||||
|
if (!temp)
|
||||||
|
{
|
||||||
|
if (cba)
|
||||||
|
{
|
||||||
|
if (flags & CBAF_PUFFTARGET) proj->target = puff;
|
||||||
|
if (flags & CBAF_PUFFMASTER) proj->master = puff;
|
||||||
|
if (flags & CBAF_PUFFTRACER) proj->tracer = puff;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (flags & FBF_PUFFTARGET) proj->target = puff;
|
||||||
|
if (flags & FBF_PUFFMASTER) proj->master = puff;
|
||||||
|
if (flags & FBF_PUFFTRACER) proj->tracer = puff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (puff && temp)
|
||||||
|
{
|
||||||
|
puff->Destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireBullets)
|
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireBullets)
|
||||||
{
|
{
|
||||||
PARAM_ACTION_PROLOGUE;
|
PARAM_ACTION_PROLOGUE;
|
||||||
|
@ -1817,9 +1886,12 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireBullets)
|
||||||
PARAM_ANGLE (spread_z);
|
PARAM_ANGLE (spread_z);
|
||||||
PARAM_INT (numbullets);
|
PARAM_INT (numbullets);
|
||||||
PARAM_INT (damageperbullet);
|
PARAM_INT (damageperbullet);
|
||||||
PARAM_CLASS_OPT (pufftype, AActor) { pufftype = NULL; }
|
PARAM_CLASS_OPT (pufftype, AActor) { pufftype = nullptr; }
|
||||||
PARAM_INT_OPT (flags) { flags = FBF_USEAMMO; }
|
PARAM_INT_OPT (flags) { flags = FBF_USEAMMO; }
|
||||||
PARAM_FLOAT_OPT (range) { range = 0; }
|
PARAM_FLOAT_OPT (range) { range = 0; }
|
||||||
|
PARAM_CLASS_OPT (missile, AActor) { missile = nullptr; }
|
||||||
|
PARAM_FLOAT_OPT (Spawnheight) { Spawnheight = 0; }
|
||||||
|
PARAM_FLOAT_OPT (Spawnofs_xy) { Spawnofs_xy = 0; }
|
||||||
|
|
||||||
if (!self->player) return 0;
|
if (!self->player) return 0;
|
||||||
|
|
||||||
|
@ -1858,7 +1930,24 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireBullets)
|
||||||
if (!(flags & FBF_NORANDOM))
|
if (!(flags & FBF_NORANDOM))
|
||||||
damage *= ((pr_cwbullet()%3)+1);
|
damage *= ((pr_cwbullet()%3)+1);
|
||||||
|
|
||||||
P_LineAttack(self, bangle, range, bslope, damage, NAME_Hitscan, pufftype, laflags);
|
AActor *puff = P_LineAttack(self, bangle, range, bslope, damage, NAME_Hitscan, pufftype, laflags);
|
||||||
|
|
||||||
|
if (missile != nullptr)
|
||||||
|
{
|
||||||
|
bool temp = false;
|
||||||
|
DAngle ang = self->Angles.Yaw - 90;
|
||||||
|
DVector2 ofs = ang.ToVector(Spawnofs_xy);
|
||||||
|
AActor *proj = P_SpawnPlayerMissile(self, ofs.X, ofs.Y, Spawnheight, missile, bangle, nullptr, nullptr, false, true);
|
||||||
|
if (proj)
|
||||||
|
{
|
||||||
|
if (!puff)
|
||||||
|
{
|
||||||
|
temp = true;
|
||||||
|
puff = P_LineAttack(self, bangle, range, bslope, 0, NAME_Hitscan, pufftype, laflags | LAF_NOINTERACT);
|
||||||
|
}
|
||||||
|
AimBulletMissile(proj, puff, flags, temp, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1885,7 +1974,24 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireBullets)
|
||||||
if (!(flags & FBF_NORANDOM))
|
if (!(flags & FBF_NORANDOM))
|
||||||
damage *= ((pr_cwbullet()%3)+1);
|
damage *= ((pr_cwbullet()%3)+1);
|
||||||
|
|
||||||
P_LineAttack(self, angle, range, slope, damage, NAME_Hitscan, pufftype, laflags);
|
AActor *puff = P_LineAttack(self, angle, range, slope, damage, NAME_Hitscan, pufftype, laflags);
|
||||||
|
|
||||||
|
if (missile != nullptr)
|
||||||
|
{
|
||||||
|
bool temp = false;
|
||||||
|
DAngle ang = self->Angles.Yaw - 90;
|
||||||
|
DVector2 ofs = ang.ToVector(Spawnofs_xy);
|
||||||
|
AActor *proj = P_SpawnPlayerMissile(self, ofs.X, ofs.Y, Spawnheight, missile, angle, nullptr, nullptr, false, true);
|
||||||
|
if (proj)
|
||||||
|
{
|
||||||
|
if (!puff)
|
||||||
|
{
|
||||||
|
temp = true;
|
||||||
|
puff = P_LineAttack(self, angle, range, slope, 0, NAME_Hitscan, pufftype, laflags | LAF_NOINTERACT);
|
||||||
|
}
|
||||||
|
AimBulletMissile(proj, puff, flags, temp, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -189,7 +189,7 @@ ACTOR Actor native //: Thinker
|
||||||
native void A_SeekerMissile(int threshold, int turnmax, int flags = 0, int chance = 50, int distance = 10);
|
native void A_SeekerMissile(int threshold, int turnmax, int flags = 0, int chance = 50, int distance = 10);
|
||||||
native state A_Jump(int chance = 256, state label, ...);
|
native state A_Jump(int chance = 256, state label, ...);
|
||||||
native void A_CustomMissile(class<Actor> missiletype, float spawnheight = 32, float spawnofs_xy = 0, float angle = 0, int flags = 0, float pitch = 0, int ptr = AAPTR_TARGET);
|
native void A_CustomMissile(class<Actor> missiletype, float spawnheight = 32, float spawnofs_xy = 0, float angle = 0, int flags = 0, float pitch = 0, int ptr = AAPTR_TARGET);
|
||||||
native void A_CustomBulletAttack(float/*angle*/ spread_xy, float/*angle*/ spread_z, int numbullets, int damageperbullet, class<Actor> pufftype = "BulletPuff", float range = 0, int flags = 0, int ptr = AAPTR_TARGET);
|
native void A_CustomBulletAttack(float/*angle*/ spread_xy, float/*angle*/ spread_z, int numbullets, int damageperbullet, class<Actor> pufftype = "BulletPuff", float range = 0, int flags = 0, int ptr = AAPTR_TARGET, class<Actor> missile = "", float Spawnheight = 32, float Spawnofs_xy = 0);
|
||||||
native void A_CustomRailgun(int damage, int spawnofs_xy = 0, color color1 = "", color color2 = "", int flags = 0, int aim = 0, float maxdiff = 0, class<Actor> 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<Actor> spawnclass = "none", float spawnofs_z = 0, int spiraloffset = 270, int limit = 0);
|
native void A_CustomRailgun(int damage, int spawnofs_xy = 0, color color1 = "", color color2 = "", int flags = 0, int aim = 0, float maxdiff = 0, class<Actor> 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<Actor> spawnclass = "none", float spawnofs_z = 0, int spiraloffset = 270, int limit = 0);
|
||||||
native state A_JumpIfHealthLower(int health, state label, int ptr_selector = AAPTR_DEFAULT);
|
native state A_JumpIfHealthLower(int health, state label, int ptr_selector = AAPTR_DEFAULT);
|
||||||
native state A_JumpIfCloser(float distance, state label, bool noz = false);
|
native state A_JumpIfCloser(float distance, state label, bool noz = false);
|
||||||
|
|
|
@ -9,7 +9,7 @@ ACTOR Inventory native
|
||||||
|
|
||||||
action native state A_JumpIfNoAmmo(state label);
|
action native state A_JumpIfNoAmmo(state label);
|
||||||
action native A_CustomPunch(int damage, bool norandom = false, int flags = CPF_USEAMMO, class<Actor> pufftype = "BulletPuff", float range = 0, float lifesteal = 0, int lifestealmax = 0, class<BasicArmorBonus> armorbonustype = "ArmorBonus", sound MeleeSound = "", sound MissSound = "");
|
action native A_CustomPunch(int damage, bool norandom = false, int flags = CPF_USEAMMO, class<Actor> pufftype = "BulletPuff", float range = 0, float lifesteal = 0, int lifestealmax = 0, class<BasicArmorBonus> armorbonustype = "ArmorBonus", sound MeleeSound = "", sound MissSound = "");
|
||||||
action native A_FireBullets(float/*angle*/ spread_xy, float/*angle*/ spread_z, int numbullets, int damageperbullet, class<Actor> pufftype = "BulletPuff", int flags = 1, float range = 0);
|
action native A_FireBullets(float/*angle*/ spread_xy, float/*angle*/ spread_z, int numbullets, int damageperbullet, class<Actor> pufftype = "BulletPuff", int flags = 1, float range = 0, class<Actor> missile = "", float Spawnheight = 32, float Spawnofs_xy = 0);
|
||||||
action native A_FireCustomMissile(class<Actor> missiletype, float angle = 0, bool useammo = true, float spawnofs_xy = 0, float spawnheight = 0, int flags = 0, float pitch = 0);
|
action native A_FireCustomMissile(class<Actor> missiletype, float angle = 0, bool useammo = true, float spawnofs_xy = 0, float spawnheight = 0, int flags = 0, float pitch = 0);
|
||||||
action native A_RailAttack(int damage, int spawnofs_xy = 0, bool useammo = true, color color1 = "", color color2 = "", int flags = 0, float maxdiff = 0, class<Actor> 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<Actor> spawnclass = "none", float spawnofs_z = 0, int spiraloffset = 270, int limit = 0);
|
action native A_RailAttack(int damage, int spawnofs_xy = 0, bool useammo = true, color color1 = "", color color2 = "", int flags = 0, float maxdiff = 0, class<Actor> 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<Actor> spawnclass = "none", float spawnofs_z = 0, int spiraloffset = 270, int limit = 0);
|
||||||
action native A_Light(int extralight);
|
action native A_Light(int extralight);
|
||||||
|
|
|
@ -1835,6 +1835,7 @@ ALTHUDMNU_SHOWAMMO = "Show ammo for";
|
||||||
ALTHUDMNU_SHOWTIME = "Show time";
|
ALTHUDMNU_SHOWTIME = "Show time";
|
||||||
ALTHUDMNU_TIMECOLOR = "Time color";
|
ALTHUDMNU_TIMECOLOR = "Time color";
|
||||||
ALTHUDMNU_SHOWLAG = "Show network latency";
|
ALTHUDMNU_SHOWLAG = "Show network latency";
|
||||||
|
ALTHUDMNU_AMMOORDER = "Ammo display order";
|
||||||
ALTHUDMNU_AMMORED = "Red ammo display below %";
|
ALTHUDMNU_AMMORED = "Red ammo display below %";
|
||||||
ALTHUDMNU_AMMOYELLOW = "Yellow ammo display below %";
|
ALTHUDMNU_AMMOYELLOW = "Yellow ammo display below %";
|
||||||
ALTHUDMNU_HEALTHRED = "Red health display below";
|
ALTHUDMNU_HEALTHRED = "Red health display below";
|
||||||
|
@ -2210,6 +2211,8 @@ OPTVAL_SYSTEMSECONDS = "System, seconds";
|
||||||
OPTVAL_SYSTEM = "System";
|
OPTVAL_SYSTEM = "System";
|
||||||
OPTVAL_NETGAMESONLY = "Netgames only";
|
OPTVAL_NETGAMESONLY = "Netgames only";
|
||||||
OPTVAL_ALWAYS = "Always";
|
OPTVAL_ALWAYS = "Always";
|
||||||
|
OPTVAL_AMMOIMAGETEXT = "Image and Text";
|
||||||
|
OPTVAL_AMMOTEXTIMAGE = "Text and Image";
|
||||||
OPTVAL_SCRIPTSONLY = "Scripts Only";
|
OPTVAL_SCRIPTSONLY = "Scripts Only";
|
||||||
OPTVAL_NEVER = "Never";
|
OPTVAL_NEVER = "Never";
|
||||||
OPTVAL_ALL = "All";
|
OPTVAL_ALL = "All";
|
||||||
|
|
|
@ -833,6 +833,12 @@ OptionValue "AltHUDLag"
|
||||||
2, "$OPTVAL_ALWAYS"
|
2, "$OPTVAL_ALWAYS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OptionValue "AltHUDAmmoOrder"
|
||||||
|
{
|
||||||
|
0, "$OPTVAL_AMMOIMAGETEXT"
|
||||||
|
1, "$OPTVAL_AMMOTEXTIMAGE"
|
||||||
|
}
|
||||||
|
|
||||||
OptionMenu "AltHUDOptions"
|
OptionMenu "AltHUDOptions"
|
||||||
{
|
{
|
||||||
Title "$ALTHUDMNU_TITLE"
|
Title "$ALTHUDMNU_TITLE"
|
||||||
|
@ -849,6 +855,7 @@ OptionMenu "AltHUDOptions"
|
||||||
Option "$ALTHUDMNU_SHOWTIME", "hud_showtime", "AltHUDTime"
|
Option "$ALTHUDMNU_SHOWTIME", "hud_showtime", "AltHUDTime"
|
||||||
Option "$ALTHUDMNU_TIMECOLOR", "hud_timecolor", "TextColors"
|
Option "$ALTHUDMNU_TIMECOLOR", "hud_timecolor", "TextColors"
|
||||||
Option "$ALTHUDMNU_SHOWLAG", "hud_showlag", "AltHUDLag"
|
Option "$ALTHUDMNU_SHOWLAG", "hud_showlag", "AltHUDLag"
|
||||||
|
Option "$ALTHUDMNU_AMMOORDER", "hud_ammo_order", "AltHUDAmmoOrder"
|
||||||
Slider "$ALTHUDMNU_AMMORED", "hud_ammo_red", 0, 100, 1, 0
|
Slider "$ALTHUDMNU_AMMORED", "hud_ammo_red", 0, 100, 1, 0
|
||||||
Slider "$ALTHUDMNU_AMMOYELLOW", "hud_ammo_yellow", 0, 100, 1, 0
|
Slider "$ALTHUDMNU_AMMOYELLOW", "hud_ammo_yellow", 0, 100, 1, 0
|
||||||
Slider "$ALTHUDMNU_HEALTHRED", "hud_health_red", 0, 100, 1, 0
|
Slider "$ALTHUDMNU_HEALTHRED", "hud_health_red", 0, 100, 1, 0
|
||||||
|
|
Loading…
Reference in a new issue