mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-29 07:22:05 +00:00
Merge branch 'master' of https://github.com/rheit/zdoom
This commit is contained in:
commit
58a3b86813
16 changed files with 377 additions and 80 deletions
|
@ -983,6 +983,8 @@ public:
|
|||
|
||||
FNameNoInit PainType;
|
||||
FNameNoInit DeathType;
|
||||
const PClass *TeleFogSourceType;
|
||||
const PClass *TeleFogDestType;
|
||||
|
||||
FState *SpawnState;
|
||||
FState *SeeState;
|
||||
|
|
|
@ -152,23 +152,33 @@ IOKitJoystick::IOKitJoystick( IOHIDDeviceRef device )
|
|||
: m_device( device )
|
||||
, m_sensitivity( DEFAULT_SENSITIVITY )
|
||||
{
|
||||
IOHIDElementRef element = HIDGetFirstDeviceElement( device, kHIDElementTypeInput );
|
||||
|
||||
while ( NULL != element )
|
||||
assert(NULL != device);
|
||||
assert(IOHIDDeviceGetTypeID() == CFGetTypeID(device));
|
||||
|
||||
CFArrayRef elements = IOHIDDeviceCopyMatchingElements(device, NULL, kIOHIDOptionsTypeNone);
|
||||
assert(NULL != elements);
|
||||
assert(CFArrayGetTypeID() == CFGetTypeID(elements));
|
||||
|
||||
for (CFIndex i = 0, count = CFArrayGetCount(elements); i < count; ++i)
|
||||
{
|
||||
const IOHIDElementRef element =
|
||||
static_cast<IOHIDElementRef>(const_cast<void*>(CFArrayGetValueAtIndex(elements, i)));
|
||||
assert(NULL != element);
|
||||
assert(IOHIDElementGetTypeID() == CFGetTypeID(element));
|
||||
|
||||
const uint32_t usagePage = IOHIDElementGetUsagePage( element );
|
||||
|
||||
|
||||
if ( kHIDPage_GenericDesktop == usagePage )
|
||||
{
|
||||
const uint32_t usage = IOHIDElementGetUsage( element );
|
||||
|
||||
if ( kHIDUsage_GD_Slider == usage
|
||||
|
||||
if ( kHIDUsage_GD_Slider == usage
|
||||
|| kHIDUsage_GD_X == usage || kHIDUsage_GD_Y == usage || kHIDUsage_GD_Z == usage
|
||||
|| kHIDUsage_GD_Rx == usage || kHIDUsage_GD_Ry == usage || kHIDUsage_GD_Rz == usage )
|
||||
{
|
||||
AxisInfo axis;
|
||||
memset( &axis, 0, sizeof( axis ) );
|
||||
|
||||
|
||||
if ( const CFStringRef name = IOHIDElementGetName( element ) )
|
||||
{
|
||||
CFStringGetCString( name, axis.name, sizeof( axis.name ) - 1, kCFStringEncodingUTF8 );
|
||||
|
@ -177,22 +187,22 @@ IOKitJoystick::IOKitJoystick( IOHIDDeviceRef device )
|
|||
{
|
||||
snprintf( axis.name, sizeof( axis.name ), "Axis %i", m_axes.Size() + 1 );
|
||||
}
|
||||
|
||||
|
||||
axis.element = element;
|
||||
|
||||
|
||||
m_axes.Push( axis );
|
||||
|
||||
|
||||
IOHIDElement_SetCalibrationMin( element, -1 );
|
||||
IOHIDElement_SetCalibrationMax( element, 1 );
|
||||
|
||||
|
||||
HIDQueueElement( m_device, element );
|
||||
}
|
||||
else if ( kHIDUsage_GD_Hatswitch == usage && m_POVs.Size() < 4 )
|
||||
{
|
||||
m_POVs.Push( element );
|
||||
|
||||
|
||||
HIDQueueElement( m_device, element );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( kHIDPage_Button == usagePage )
|
||||
{
|
||||
|
@ -200,10 +210,10 @@ IOKitJoystick::IOKitJoystick( IOHIDDeviceRef device )
|
|||
|
||||
HIDQueueElement( m_device, element );
|
||||
}
|
||||
|
||||
element = HIDGetNextDeviceElement( element, kHIDElementTypeInput );
|
||||
}
|
||||
|
||||
CFRelease(elements);
|
||||
|
||||
SetDefaultConfig();
|
||||
}
|
||||
|
||||
|
|
|
@ -109,6 +109,7 @@ enum SAW_Flags
|
|||
SF_NOUSEAMMO = 16,
|
||||
SF_NOPULLIN = 32,
|
||||
SF_NOTURN = 64,
|
||||
SF_STEALARMOR = 128,
|
||||
};
|
||||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw)
|
||||
|
@ -119,7 +120,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw)
|
|||
AActor *linetarget;
|
||||
int actualdamage;
|
||||
|
||||
ACTION_PARAM_START(9);
|
||||
ACTION_PARAM_START(11);
|
||||
ACTION_PARAM_SOUND(fullsound, 0);
|
||||
ACTION_PARAM_SOUND(hitsound, 1);
|
||||
ACTION_PARAM_INT(damage, 2);
|
||||
|
@ -129,6 +130,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw)
|
|||
ACTION_PARAM_ANGLE(Spread_XY, 6);
|
||||
ACTION_PARAM_ANGLE(Spread_Z, 7);
|
||||
ACTION_PARAM_FIXED(LifeSteal, 8);
|
||||
ACTION_PARAM_INT(lifestealmax, 9);
|
||||
ACTION_PARAM_CLASS(armorbonustype, 10);
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
{
|
||||
|
@ -184,7 +187,31 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw)
|
|||
}
|
||||
|
||||
if (LifeSteal && !(linetarget->flags5 & MF5_DONTDRAIN))
|
||||
P_GiveBody (self, (actualdamage * LifeSteal) >> FRACBITS);
|
||||
{
|
||||
if (Flags & SF_STEALARMOR)
|
||||
{
|
||||
if (!armorbonustype) armorbonustype = PClass::FindClass("ArmorBonus");
|
||||
|
||||
if (armorbonustype->IsDescendantOf (RUNTIME_CLASS(ABasicArmorBonus)))
|
||||
{
|
||||
ABasicArmorBonus *armorbonus = static_cast<ABasicArmorBonus *>(Spawn (armorbonustype, 0,0,0, NO_REPLACE));
|
||||
armorbonus->SaveAmount *= (actualdamage * LifeSteal) >> FRACBITS;
|
||||
armorbonus->MaxSaveAmount = lifestealmax <= 0 ? armorbonus->MaxSaveAmount : lifestealmax;
|
||||
armorbonus->flags |= MF_DROPPED;
|
||||
armorbonus->ClearCounters();
|
||||
|
||||
if (!armorbonus->CallTryPickup (self))
|
||||
{
|
||||
armorbonus->Destroy ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
P_GiveBody (self, (actualdamage * LifeSteal) >> FRACBITS, lifestealmax);
|
||||
}
|
||||
}
|
||||
|
||||
S_Sound (self, CHAN_WEAPON, hitsound, 1, ATTN_NORM);
|
||||
|
||||
|
|
|
@ -4438,6 +4438,8 @@ enum EACSFunctions
|
|||
ACSF_PickActor,
|
||||
ACSF_IsPointerEqual,
|
||||
ACSF_CanRaiseActor,
|
||||
ACSF_SetActorTeleFog, // 86
|
||||
ACSF_SwapActorTeleFog,
|
||||
|
||||
/* Zandronum's - these must be skipped when we reach 99!
|
||||
-100:ResetMap(0),
|
||||
|
@ -4749,6 +4751,82 @@ static void SetActorPitch(AActor *activator, int tid, int angle, bool interpolat
|
|||
}
|
||||
}
|
||||
|
||||
static void SetActorTeleFog(AActor *activator, int tid, FName telefogsrc, FName telefogdest)
|
||||
{
|
||||
//Simply put, if it doesn't exist, it won't change. One can use "" in this scenario.
|
||||
const PClass *check;
|
||||
if (tid == 0)
|
||||
{
|
||||
if (activator != NULL)
|
||||
{
|
||||
check = PClass::FindClass(telefogsrc);
|
||||
if (check == NULL || !stricmp(telefogsrc, "none") || !stricmp(telefogsrc, "null"))
|
||||
activator->TeleFogSourceType = NULL;
|
||||
else
|
||||
activator->TeleFogSourceType = check;
|
||||
|
||||
check = PClass::FindClass(telefogdest);
|
||||
if (check == NULL || !stricmp(telefogdest, "none") || !stricmp(telefogdest, "null"))
|
||||
activator->TeleFogDestType = NULL;
|
||||
else
|
||||
activator->TeleFogDestType = check;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FActorIterator iterator(tid);
|
||||
AActor *actor;
|
||||
|
||||
while ((actor = iterator.Next()))
|
||||
{
|
||||
check = PClass::FindClass(telefogsrc);
|
||||
if (check == NULL || !stricmp(telefogsrc, "none") || !stricmp(telefogsrc, "null"))
|
||||
actor->TeleFogSourceType = NULL;
|
||||
else
|
||||
actor->TeleFogSourceType = check;
|
||||
|
||||
check = PClass::FindClass(telefogdest);
|
||||
if (check == NULL || !stricmp(telefogdest, "none") || !stricmp(telefogdest, "null"))
|
||||
actor->TeleFogDestType = NULL;
|
||||
else
|
||||
actor->TeleFogDestType = check;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int SwapActorTeleFog(AActor *activator, int tid)
|
||||
{
|
||||
int count = 0;
|
||||
if (tid == 0)
|
||||
{
|
||||
if ((activator == NULL) || (activator->TeleFogSourceType = activator->TeleFogDestType))
|
||||
return 0; //Does nothing if they're the same.
|
||||
else
|
||||
{
|
||||
const PClass *temp = activator->TeleFogSourceType;
|
||||
activator->TeleFogSourceType = activator->TeleFogDestType;
|
||||
activator->TeleFogDestType = temp;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FActorIterator iterator(tid);
|
||||
AActor *actor;
|
||||
|
||||
while ((actor = iterator.Next()))
|
||||
{
|
||||
if (actor->TeleFogSourceType == actor->TeleFogDestType)
|
||||
continue; //They're the same. Save the effort.
|
||||
const PClass *temp = actor->TeleFogSourceType;
|
||||
actor->TeleFogSourceType = actor->TeleFogDestType;
|
||||
actor->TeleFogDestType = temp;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args, const SDWORD *stack, int stackdepth)
|
||||
|
@ -5662,7 +5740,18 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
|||
SetActorPitch(activator, args[0], args[1], argCount > 2 ? !!args[2] : false);
|
||||
}
|
||||
break;
|
||||
|
||||
case ACSF_SetActorTeleFog:
|
||||
if (argCount >= 3)
|
||||
{
|
||||
SetActorTeleFog(activator, args[0], FBehavior::StaticLookupString(args[1]), FBehavior::StaticLookupString(args[2]));
|
||||
}
|
||||
break;
|
||||
case ACSF_SwapActorTeleFog:
|
||||
if (argCount >= 1)
|
||||
{
|
||||
return SwapActorTeleFog(activator, args[0]);
|
||||
}
|
||||
break;
|
||||
case ACSF_PickActor:
|
||||
if (argCount >= 5)
|
||||
{
|
||||
|
|
|
@ -3003,6 +3003,10 @@ bool P_BounceActor(AActor *mo, AActor *BlockingMobj, bool ontop)
|
|||
{
|
||||
if (mo->bouncecount > 0 && --mo->bouncecount == 0) return false;
|
||||
|
||||
if (mo->flags7 & MF7_HITTARGET) mo->target = BlockingMobj;
|
||||
if (mo->flags7 & MF7_HITMASTER) mo->master = BlockingMobj;
|
||||
if (mo->flags7 & MF7_HITTRACER) mo->tracer = BlockingMobj;
|
||||
|
||||
if (!ontop)
|
||||
{
|
||||
fixed_t speed;
|
||||
|
@ -3746,6 +3750,8 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance,
|
|||
hity = t1->y + FixedMul(vy, dist);
|
||||
hitz = shootz + FixedMul(vz, dist);
|
||||
|
||||
|
||||
|
||||
// Spawn bullet puffs or blood spots, depending on target type.
|
||||
if ((puffDefaults != NULL && puffDefaults->flags3 & MF3_PUFFONACTORS) ||
|
||||
(trace.Actor->flags & MF_NOBLOOD) ||
|
||||
|
@ -3758,6 +3764,13 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance,
|
|||
puff = P_SpawnPuff(t1, pufftype, hitx, hity, hitz, angle - ANG180, 2, puffFlags | PF_HITTHING);
|
||||
}
|
||||
|
||||
if (puffDefaults != NULL && trace.Actor != NULL && puff != NULL)
|
||||
{
|
||||
if (puffDefaults->flags7 && MF7_HITTARGET) puff->target = trace.Actor;
|
||||
if (puffDefaults->flags7 && MF7_HITMASTER) puff->master = trace.Actor;
|
||||
if (puffDefaults->flags7 && MF7_HITTRACER) puff->tracer = trace.Actor;
|
||||
}
|
||||
|
||||
// Allow puffs to inflict poison damage, so that hitscans can poison, too.
|
||||
if (puffDefaults != NULL && puffDefaults->PoisonDamage > 0 && puffDefaults->PoisonDuration != INT_MIN)
|
||||
{
|
||||
|
@ -3776,7 +3789,7 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance,
|
|||
{
|
||||
dmgflags |= DMG_NO_ARMOR;
|
||||
}
|
||||
|
||||
|
||||
if (puff == NULL)
|
||||
{
|
||||
// Since the puff is the damage inflictor we need it here
|
||||
|
@ -4150,7 +4163,7 @@ void P_RailAttack(AActor *source, int damage, int offset_xy, fixed_t offset_z, i
|
|||
int flags;
|
||||
|
||||
assert(puffclass != NULL); // Because we set it to a default above
|
||||
AActor *puffDefaults = GetDefaultByType(puffclass->GetReplacement());
|
||||
AActor *puffDefaults = GetDefaultByType(puffclass->GetReplacement()); //Contains all the flags such as FOILINVUL, etc.
|
||||
|
||||
flags = (puffDefaults->flags6 & MF6_NOTRIGGER) ? 0 : TRACE_PCross | TRACE_Impact;
|
||||
rail_data.StopAtInvul = (puffDefaults->flags3 & MF3_FOILINVUL) ? false : true;
|
||||
|
@ -4200,6 +4213,12 @@ void P_RailAttack(AActor *source, int damage, int offset_xy, fixed_t offset_z, i
|
|||
{
|
||||
P_SpawnPuff(source, puffclass, x, y, z, (source->angle + angleoffset) - ANG90, 1, puffflags);
|
||||
}
|
||||
if (hitactor != NULL && puffDefaults != NULL && thepuff != NULL)
|
||||
{
|
||||
if (puffDefaults->flags7 & MF7_HITTARGET) thepuff->target = hitactor;
|
||||
if (puffDefaults->flags7 & MF7_HITMASTER) thepuff->master = hitactor;
|
||||
if (puffDefaults->flags7 & MF7_HITTRACER) thepuff->tracer = hitactor;
|
||||
}
|
||||
if (puffDefaults && puffDefaults->PoisonDamage > 0 && puffDefaults->PoisonDuration != INT_MIN)
|
||||
{
|
||||
P_PoisonMobj(hitactor, thepuff ? thepuff : source, source, puffDefaults->PoisonDamage, puffDefaults->PoisonDuration, puffDefaults->PoisonPeriod, puffDefaults->PoisonDamageType);
|
||||
|
@ -4208,6 +4227,7 @@ void P_RailAttack(AActor *source, int damage, int offset_xy, fixed_t offset_z, i
|
|||
dmgFlagPass += (puffDefaults->flags3 & MF3_FOILINVUL) ? DMG_FOILINVUL : 0; //[MC]Because the original foilinvul check wasn't working.
|
||||
dmgFlagPass += (puffDefaults->flags7 & MF7_FOILBUDDHA) ? DMG_FOILBUDDHA : 0;
|
||||
int newdam = P_DamageMobj(hitactor, thepuff ? thepuff : source, source, damage, damagetype, dmgFlagPass);
|
||||
|
||||
if (bleed)
|
||||
{
|
||||
P_SpawnBlood(x, y, z, (source->angle + angleoffset) - ANG180, newdam > 0 ? newdam : damage, hitactor);
|
||||
|
|
|
@ -333,7 +333,11 @@ void AActor::Serialize (FArchive &arc)
|
|||
{
|
||||
arc << FriendPlayer;
|
||||
}
|
||||
|
||||
if (SaveVersion >= 4517)
|
||||
{
|
||||
arc << TeleFogSourceType
|
||||
<< TeleFogDestType;
|
||||
}
|
||||
{
|
||||
FString tagstr;
|
||||
if (arc.IsStoring() && Tag != NULL && Tag->Len() > 0) tagstr = *Tag;
|
||||
|
@ -2680,18 +2684,10 @@ void P_NightmareRespawn (AActor *mobj)
|
|||
mo->PrevZ = z; // Do not interpolate Z position if we changed it since spawning.
|
||||
|
||||
// spawn a teleport fog at old spot because of removal of the body?
|
||||
mo = Spawn ("TeleportFog", mobj->x, mobj->y, mobj->z, ALLOW_REPLACE);
|
||||
if (mo != NULL)
|
||||
{
|
||||
mo->z += TELEFOGHEIGHT;
|
||||
}
|
||||
P_SpawnTeleportFog(mobj, mobj->x, mobj->y, mobj->z + TELEFOGHEIGHT, true);
|
||||
|
||||
// spawn a teleport fog at the new spot
|
||||
mo = Spawn ("TeleportFog", x, y, z, ALLOW_REPLACE);
|
||||
if (mo != NULL)
|
||||
{
|
||||
mo->z += TELEFOGHEIGHT;
|
||||
}
|
||||
P_SpawnTeleportFog(mobj, x, y, z + TELEFOGHEIGHT, false);
|
||||
|
||||
// remove the old monster
|
||||
mobj->Destroy ();
|
||||
|
|
|
@ -903,6 +903,7 @@ bool EV_DoChange (line_t *line, EChange changetype, int tag);
|
|||
//
|
||||
// P_TELEPT
|
||||
//
|
||||
void P_SpawnTeleportFog(AActor *mobj, fixed_t x, fixed_t y, fixed_t z, bool beforeTele = true, bool setTarget = false); //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).
|
||||
bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, bool useFog, bool sourceFog, bool keepOrientation, bool haltVelocity = true, bool keepHeight = false);
|
||||
bool EV_Teleport (int tid, int tag, line_t *line, int side, AActor *thing, bool fog, bool sourceFog, bool keepOrientation, bool haltVelocity = true, bool keepHeight = false);
|
||||
bool EV_SilentLineTeleport (line_t *line, int side, AActor *thing, int id, INTBOOL reverse);
|
||||
|
|
|
@ -74,19 +74,22 @@ void ATeleportFog::PostBeginPlay ()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void P_SpawnTeleportFog(fixed_t x, fixed_t y, fixed_t z, int spawnid)
|
||||
void P_SpawnTeleportFog(AActor *mobj, fixed_t x, fixed_t y, fixed_t z, bool beforeTele, bool setTarget)
|
||||
{
|
||||
const PClass *fog = P_GetSpawnableType(spawnid);
|
||||
|
||||
if (fog == NULL)
|
||||
AActor *mo;
|
||||
if ((beforeTele ? mobj->TeleFogSourceType : mobj->TeleFogDestType) == NULL)
|
||||
{
|
||||
AActor *mo = Spawn ("TeleportFog", x, y, z + TELEFOGHEIGHT, ALLOW_REPLACE);
|
||||
//Do nothing.
|
||||
mo = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
AActor *mo = Spawn (fog, x, y, z, ALLOW_REPLACE);
|
||||
if (mo != NULL) S_Sound(mo, CHAN_BODY, mo->SeeSound, 1.f, ATTN_NORM);
|
||||
mo = Spawn((beforeTele ? mobj->TeleFogSourceType : mobj->TeleFogDestType), x, y, z, ALLOW_REPLACE);
|
||||
}
|
||||
|
||||
if (mo != NULL && setTarget)
|
||||
mo->target = mobj;
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -186,8 +189,7 @@ bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle,
|
|||
if (sourceFog && !predicting)
|
||||
{
|
||||
fixed_t fogDelta = thing->flags & MF_MISSILE ? 0 : TELEFOGHEIGHT;
|
||||
AActor *fog = Spawn<ATeleportFog> (oldx, oldy, oldz + fogDelta, ALLOW_REPLACE);
|
||||
fog->target = thing;
|
||||
P_SpawnTeleportFog(thing, oldx, oldy, oldz, true, true); //Passes the actor through which then pulls the TeleFog metadate types based on properties.
|
||||
}
|
||||
if (useFog)
|
||||
{
|
||||
|
@ -195,9 +197,8 @@ bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle,
|
|||
{
|
||||
fixed_t fogDelta = thing->flags & MF_MISSILE ? 0 : TELEFOGHEIGHT;
|
||||
an = angle >> ANGLETOFINESHIFT;
|
||||
AActor *fog = Spawn<ATeleportFog>(x + 20 * finecosine[an],
|
||||
y + 20 * finesine[an], thing->z + fogDelta, ALLOW_REPLACE);
|
||||
fog->target = thing;
|
||||
P_SpawnTeleportFog(thing, x + 20 * finecosine[an], y + 20 * finesine[an], thing->z + fogDelta, false, true);
|
||||
|
||||
}
|
||||
if (thing->player)
|
||||
{
|
||||
|
|
|
@ -92,7 +92,7 @@ bool P_Thing_Spawn (int tid, AActor *source, int type, angle_t angle, bool fog,
|
|||
mobj->angle = (angle != ANGLE_MAX ? angle : spot->angle);
|
||||
if (fog)
|
||||
{
|
||||
Spawn<ATeleportFog> (spot->x, spot->y, spot->z + TELEFOGHEIGHT, ALLOW_REPLACE);
|
||||
P_SpawnTeleportFog(mobj, spot->x, spot->y, spot->z + TELEFOGHEIGHT, false);
|
||||
}
|
||||
if (mobj->flags & MF_SPECIAL)
|
||||
mobj->flags |= MF_DROPPED; // Don't respawn
|
||||
|
@ -130,8 +130,8 @@ bool P_MoveThing(AActor *source, fixed_t x, fixed_t y, fixed_t z, bool fog)
|
|||
{
|
||||
if (fog)
|
||||
{
|
||||
Spawn<ATeleportFog> (x, y, z + TELEFOGHEIGHT, ALLOW_REPLACE);
|
||||
Spawn<ATeleportFog> (oldx, oldy, oldz + TELEFOGHEIGHT, ALLOW_REPLACE);
|
||||
P_SpawnTeleportFog(source, x, y, z);
|
||||
P_SpawnTeleportFog(source, oldx, oldy, oldz, false);
|
||||
}
|
||||
source->PrevX = x;
|
||||
source->PrevY = y;
|
||||
|
|
|
@ -1385,17 +1385,20 @@ enum
|
|||
CPF_PULLIN = 4,
|
||||
CPF_NORANDOMPUFFZ = 8,
|
||||
CPF_NOTURN = 16,
|
||||
CPF_STEALARMOR = 32,
|
||||
};
|
||||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomPunch)
|
||||
{
|
||||
ACTION_PARAM_START(5);
|
||||
ACTION_PARAM_START(8);
|
||||
ACTION_PARAM_INT(Damage, 0);
|
||||
ACTION_PARAM_BOOL(norandom, 1);
|
||||
ACTION_PARAM_INT(flags, 2);
|
||||
ACTION_PARAM_CLASS(PuffType, 3);
|
||||
ACTION_PARAM_FIXED(Range, 4);
|
||||
ACTION_PARAM_FIXED(LifeSteal, 5);
|
||||
ACTION_PARAM_INT(lifestealmax, 6);
|
||||
ACTION_PARAM_CLASS(armorbonustype, 7);
|
||||
|
||||
if (!self->player) return;
|
||||
|
||||
|
@ -1428,7 +1431,31 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomPunch)
|
|||
if (linetarget)
|
||||
{
|
||||
if (LifeSteal && !(linetarget->flags5 & MF5_DONTDRAIN))
|
||||
P_GiveBody (self, (actualdamage * LifeSteal) >> FRACBITS);
|
||||
{
|
||||
if (flags & CPF_STEALARMOR)
|
||||
{
|
||||
if (!armorbonustype) armorbonustype = PClass::FindClass("ArmorBonus");
|
||||
|
||||
if (armorbonustype->IsDescendantOf (RUNTIME_CLASS(ABasicArmorBonus)))
|
||||
{
|
||||
ABasicArmorBonus *armorbonus = static_cast<ABasicArmorBonus *>(Spawn (armorbonustype, 0,0,0, NO_REPLACE));
|
||||
armorbonus->SaveAmount *= (actualdamage * LifeSteal) >> FRACBITS;
|
||||
armorbonus->MaxSaveAmount = lifestealmax <= 0 ? armorbonus->MaxSaveAmount : lifestealmax;
|
||||
armorbonus->flags |= MF_DROPPED;
|
||||
armorbonus->ClearCounters();
|
||||
|
||||
if (!armorbonus->CallTryPickup (self))
|
||||
{
|
||||
armorbonus->Destroy ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
P_GiveBody (self, (actualdamage * LifeSteal) >> FRACBITS, lifestealmax);
|
||||
}
|
||||
}
|
||||
|
||||
if (weapon != NULL)
|
||||
{
|
||||
|
@ -2938,9 +2965,10 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Respawn)
|
|||
{
|
||||
ACTION_PARAM_START(1);
|
||||
ACTION_PARAM_INT(flags, 0);
|
||||
|
||||
bool oktorespawn = false;
|
||||
|
||||
fixed_t oldx = self->x;
|
||||
fixed_t oldy = self->y;
|
||||
fixed_t oldz = self->z;
|
||||
self->flags |= MF_SOLID;
|
||||
self->height = self->GetDefault()->height;
|
||||
CALL_ACTION(A_RestoreSpecialPosition, self);
|
||||
|
@ -2998,7 +3026,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Respawn)
|
|||
|
||||
if (flags & RSF_FOG)
|
||||
{
|
||||
Spawn<ATeleportFog> (self->x, self->y, self->z + TELEFOGHEIGHT, ALLOW_REPLACE);
|
||||
P_SpawnTeleportFog(self, oldx, oldy, oldz, true);
|
||||
P_SpawnTeleportFog(self, self->x, self->y, self->z, false);
|
||||
}
|
||||
if (self->CountsAsKill())
|
||||
{
|
||||
|
@ -4119,9 +4148,16 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetUserArray)
|
|||
//===========================================================================
|
||||
enum T_Flags
|
||||
{
|
||||
TF_TELEFRAG = 1, // Allow telefrag in order to teleport.
|
||||
TF_RANDOMDECIDE = 2, // Randomly fail based on health. (A_Srcr2Decide)
|
||||
TF_FORCED = 4, // Forget what's in the way. TF_Telefrag takes precedence though.
|
||||
TF_TELEFRAG = 0x00000001, // Allow telefrag in order to teleport.
|
||||
TF_RANDOMDECIDE = 0x00000002, // Randomly fail based on health. (A_Srcr2Decide)
|
||||
TF_FORCED = 0x00000004, // Forget what's in the way. TF_Telefrag takes precedence though.
|
||||
TF_KEEPVELOCITY = 0x00000008, // Preserve velocity.
|
||||
TF_KEEPANGLE = 0x00000010, // Keep angle.
|
||||
TF_USESPOTZ = 0x00000020, // Set the z to the spot's z, instead of the floor.
|
||||
TF_NOSRCFOG = 0x00000040, // Don't leave any fog behind when teleporting.
|
||||
TF_NODESTFOG = 0x00000080, // Don't spawn any fog at the arrival position.
|
||||
TF_USEACTORFOG = 0x00000100, // Use the actor's TeleFogSourceType and TeleFogDestType fogs.
|
||||
TF_NOJUMP = 0x00000200, // Don't jump after teleporting.
|
||||
};
|
||||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Teleport)
|
||||
|
@ -4152,14 +4188,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Teleport)
|
|||
if (pr_teleport() >= chance[chanceindex]) return;
|
||||
}
|
||||
|
||||
if (TeleportState == NULL)
|
||||
{
|
||||
// Default to Teleport.
|
||||
TeleportState = self->FindState("Teleport");
|
||||
// If still nothing, then return.
|
||||
if (!TeleportState) return;
|
||||
}
|
||||
|
||||
DSpotState *state = DSpotState::GetSpotState();
|
||||
if (state == NULL) return;
|
||||
|
||||
|
@ -4171,34 +4199,66 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Teleport)
|
|||
fixed_t prevX = self->x;
|
||||
fixed_t prevY = self->y;
|
||||
fixed_t prevZ = self->z;
|
||||
bool teleResult = false;
|
||||
|
||||
//Take precedence and cooperate with telefragging first.
|
||||
if (P_TeleportMove(self, spot->x, spot->y, spot->z, Flags & TF_TELEFRAG))
|
||||
teleResult = true;
|
||||
bool teleResult = P_TeleportMove(self, spot->x, spot->y, spot->z, Flags & TF_TELEFRAG);
|
||||
|
||||
if ((!(teleResult)) && (Flags & TF_FORCED))
|
||||
{
|
||||
//If for some reason the original move didn't work, regardless of telefrag, force it to move.
|
||||
self->SetOrigin(spot->x, spot->y, spot->z);
|
||||
teleResult = true;
|
||||
|
||||
}
|
||||
|
||||
if (teleResult)
|
||||
{
|
||||
ACTION_SET_RESULT(false); // Jumps should never set the result for inventory state chains!
|
||||
|
||||
if (FogType)
|
||||
{
|
||||
Spawn(FogType, prevX, prevY, prevZ, ALLOW_REPLACE);
|
||||
//If a fog type is defined in the parameter, or the user wants to use the actor's predefined fogs,
|
||||
//and if there's no desire to be fogless, spawn a fog based upon settings.
|
||||
if (FogType || (Flags & TF_USEACTORFOG))
|
||||
{
|
||||
if (!(Flags & TF_NOSRCFOG))
|
||||
{
|
||||
if (Flags & TF_USEACTORFOG)
|
||||
P_SpawnTeleportFog(self, prevX, prevY, prevZ, true);
|
||||
else
|
||||
Spawn(FogType, prevX, prevY, prevZ, ALLOW_REPLACE);
|
||||
}
|
||||
if (!(Flags & TF_NODESTFOG))
|
||||
{
|
||||
if (Flags & TF_USEACTORFOG)
|
||||
P_SpawnTeleportFog(self, self->x, self->y, self->z, false);
|
||||
else
|
||||
Spawn(FogType, self->x, self->y, self->z, ALLOW_REPLACE);
|
||||
}
|
||||
}
|
||||
|
||||
if (Flags & TF_USESPOTZ)
|
||||
self->z = spot->z;
|
||||
else
|
||||
self->z = self->floorz;
|
||||
|
||||
ACTION_JUMP(TeleportState);
|
||||
if (!(Flags & TF_KEEPANGLE))
|
||||
self->angle = spot->angle;
|
||||
|
||||
self->z = self->floorz;
|
||||
self->angle = spot->angle;
|
||||
self->velx = self->vely = self->velz = 0;
|
||||
if (!(Flags & TF_KEEPVELOCITY))
|
||||
self->velx = self->vely = self->velz = 0;
|
||||
|
||||
if (!(Flags & TF_NOJUMP))
|
||||
{
|
||||
ACTION_SET_RESULT(false); // Jumps should never set the result for inventory state chains!
|
||||
if (TeleportState == NULL)
|
||||
{
|
||||
// Default to Teleport.
|
||||
TeleportState = self->FindState("Teleport");
|
||||
// If still nothing, then return.
|
||||
if (!TeleportState) return;
|
||||
}
|
||||
ACTION_JUMP(TeleportState);
|
||||
return;
|
||||
}
|
||||
}
|
||||
ACTION_SET_RESULT(teleResult);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -5377,3 +5437,53 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Remove)
|
|||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// A_SetTeleFog
|
||||
//
|
||||
// Sets the teleport fog(s) for the calling actor.
|
||||
// Takes a name of the classes for te source and destination.
|
||||
// Can set both at the same time. Use "" to retain the previous fog without
|
||||
// changing it.
|
||||
//===========================================================================
|
||||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetTeleFog)
|
||||
{
|
||||
ACTION_PARAM_START(2);
|
||||
ACTION_PARAM_NAME(oldpos, 0);
|
||||
ACTION_PARAM_NAME(newpos, 1);
|
||||
const PClass *check = PClass::FindClass(oldpos);
|
||||
if (check == NULL || !stricmp(oldpos, "none") || !stricmp(oldpos, "null"))
|
||||
self->TeleFogSourceType = NULL;
|
||||
else if (!stricmp(oldpos, ""))
|
||||
{ //Don't change it if it's just ""
|
||||
}
|
||||
else
|
||||
self->TeleFogSourceType = check;
|
||||
|
||||
check = PClass::FindClass(newpos);
|
||||
if (check == NULL || !stricmp(newpos, "none") || !stricmp(newpos, "null"))
|
||||
self->TeleFogDestType = NULL;
|
||||
else if (!stricmp(newpos, ""))
|
||||
{ //Don't change it if it's just ""
|
||||
}
|
||||
else
|
||||
self->TeleFogDestType = check;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// A_SwapTeleFog
|
||||
//
|
||||
// Switches the source and dest telefogs around.
|
||||
//===========================================================================
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_SwapTeleFog)
|
||||
{
|
||||
if ((self->TeleFogSourceType != self->TeleFogDestType)) //Does nothing if they're the same.
|
||||
{
|
||||
const PClass *temp = self->TeleFogSourceType;
|
||||
self->TeleFogSourceType = self->TeleFogDestType;
|
||||
self->TeleFogDestType = temp;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1416,6 +1416,26 @@ DEFINE_PROPERTY(stamina, I, Actor)
|
|||
defaults->stamina = i;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_PROPERTY(telefogsourcetype, S, Actor)
|
||||
{
|
||||
PROP_STRING_PARM(str, 0);
|
||||
if (!stricmp(str, "") || (!stricmp(str, "none")) || (!stricmp(str, "null")) || *str == 0) defaults->TeleFogSourceType = NULL;
|
||||
else defaults->TeleFogSourceType = FindClassTentative(str,"TeleportFog");
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_PROPERTY(telefogdesttype, S, Actor)
|
||||
{
|
||||
PROP_STRING_PARM(str, 0);
|
||||
if (!stricmp(str, "") || (!stricmp(str, "none")) || (!stricmp(str, "null")) || *str == 0) defaults->TeleFogDestType = NULL;
|
||||
else defaults->TeleFogDestType = FindClassTentative(str, "TeleportFog");
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Special inventory properties
|
||||
|
|
|
@ -76,7 +76,7 @@ const char *GetVersionString();
|
|||
|
||||
// Use 4500 as the base git save version, since it's higher than the
|
||||
// SVN revision ever got.
|
||||
#define SAVEVER 4516
|
||||
#define SAVEVER 4517
|
||||
|
||||
#define SAVEVERSTRINGIFY2(x) #x
|
||||
#define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x)
|
||||
|
|
|
@ -26,6 +26,8 @@ ACTOR Actor native //: Thinker
|
|||
DesignatedTeam 255
|
||||
PainType Normal
|
||||
DeathType Normal
|
||||
TeleFogSourceType "TeleportFog"
|
||||
TeleFogDestType "TeleportFog"
|
||||
|
||||
// Variables for the expression evaluator
|
||||
// NOTE: fixed_t and angle_t are only used here to ensure proper conversion
|
||||
|
@ -317,6 +319,8 @@ ACTOR Actor native //: Thinker
|
|||
action native A_GiveToSiblings(class<Inventory> itemtype, int amount = 0);
|
||||
action native A_TakeFromChildren(class<Inventory> itemtype, int amount = 0);
|
||||
action native A_TakeFromSiblings(class<Inventory> itemtype, int amount = 0);
|
||||
action native A_SetTeleFog(name oldpos, name newpos);
|
||||
action native A_SwapTeleFog();
|
||||
|
||||
action native A_CheckSightOrRange(float distance, state label);
|
||||
action native A_CheckRange(float distance, state label);
|
||||
|
|
|
@ -16,6 +16,7 @@ const int SF_NOUSEAMMOMISS = 8;
|
|||
const int SF_NOUSEAMMO = 16;
|
||||
const int SF_NOPULLIN = 32;
|
||||
const int SF_NOTURN = 64;
|
||||
const int SF_STEALARMOR = 128;
|
||||
|
||||
// Flags for A_CustomMissile
|
||||
const int CMF_AIMOFFSET = 1;
|
||||
|
@ -176,15 +177,29 @@ const int CPF_DAGGER = 2;
|
|||
const int CPF_PULLIN = 4;
|
||||
const int CPF_NORANDOMPUFFZ = 8;
|
||||
const int CPF_NOTURN = 16;
|
||||
const int CPF_STEALARMOR = 32;
|
||||
|
||||
// Flags for A_CustomMissile
|
||||
const int FPF_AIMATANGLE = 1;
|
||||
const int FPF_TRANSFERTRANSLATION = 2;
|
||||
|
||||
// Flags for A_Teleport
|
||||
const int TF_TELEFRAG = 1;
|
||||
const int TF_RANDOMDECIDE = 2;
|
||||
const int TF_FORCED = 4;
|
||||
enum
|
||||
{
|
||||
TF_TELEFRAG = 0x00000001, // Allow telefrag in order to teleport.
|
||||
TF_RANDOMDECIDE = 0x00000002, // Randomly fail based on health. (A_Srcr2Decide)
|
||||
TF_FORCED = 0x00000004, // Forget what's in the way. TF_Telefrag takes precedence though.
|
||||
TF_KEEPVELOCITY = 0x00000008, // Preserve velocity.
|
||||
TF_KEEPANGLE = 0x00000010, // Keep angle.
|
||||
TF_USESPOTZ = 0x00000020, // Set the z to the spot's z, instead of the floor.
|
||||
TF_NOSRCFOG = 0x00000040, // Don't leave any fog behind when teleporting.
|
||||
TF_NODESTFOG = 0x00000080, // Don't spawn any fog at the arrival position.
|
||||
TF_USEACTORFOG = 0x00000100, // Use the actor's TeleFogSourceType and TeleFogDestType fogs.
|
||||
TF_NOJUMP = 0x00000200, // Don't jump after teleporting.
|
||||
|
||||
TF_KEEPORIENTATION = TF_KEEPVELOCITY|TF_KEEPANGLE,
|
||||
TF_NOFOG = TF_NOSRCFOG|TF_NODESTFOG,
|
||||
};
|
||||
|
||||
// Flags for A_WolfAttack
|
||||
const int WAF_NORANDOM = 1;
|
||||
|
|
|
@ -8,7 +8,7 @@ ACTOR Inventory native
|
|||
Inventory.PickupMessage "$TXT_DEFAULTPICKUPMSG"
|
||||
|
||||
action native 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);
|
||||
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");
|
||||
action native A_FireBullets(float spread_xy, float spread_z, int numbullets, int damageperbullet, class<Actor> pufftype = "BulletPuff", int flags = 1, float range = 0);
|
||||
action native A_FireCustomMissile(class<Actor> missiletype, float angle = 0, bool useammo = true, int spawnofs_xy = 0, float spawnheight = 0, bool aimatangle = false, float pitch = 0);
|
||||
action native A_RailAttack(int damage, int spawnofs_xy = 0, int useammo = true, color color1 = "", color color2 = "", int flags = 0, float maxdiff = 0, class<Actor> pufftype = "BulletPuff", float spread_xy = 0, float 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);
|
||||
|
@ -41,7 +41,7 @@ ACTOR Inventory native
|
|||
action native A_ClearReFire();
|
||||
action native A_CheckReload();
|
||||
action native A_GunFlash(state flash = "", int flags = 0);
|
||||
action native A_Saw(sound fullsound = "weapons/sawfull", sound hitsound = "weapons/sawhit", int damage = 2, class<Actor> pufftype = "BulletPuff", int flags = 0, float range = 0, float spread_xy = 2.8125, float spread_z = 0, float lifesteal = 0);
|
||||
action native A_Saw(sound fullsound = "weapons/sawfull", sound hitsound = "weapons/sawhit", int damage = 2, class<Actor> pufftype = "BulletPuff", int flags = 0, float range = 0, float spread_xy = 2.8125, float spread_z = 0, float lifesteal = 0, int lifestealmax = 0, class<BasicArmorBonus> armorbonustype = "ArmorBonus");
|
||||
action native A_CheckForReload(int counter, state label, bool dontincrement = false);
|
||||
action native A_ResetReloadCounter();
|
||||
action native A_RestoreSpecialPosition();
|
||||
|
|
|
@ -665,6 +665,7 @@ OptionMenu "VideoOptions"
|
|||
Slider "Screen size", "screenblocks", 3.0, 12.0, 1.0, 0
|
||||
Slider "Brightness", "Gamma", 0.75, 3.0, 0.05, 2
|
||||
Option "Vertical Sync", "vid_vsync", "OnOff"
|
||||
Option "Rendering Interpolation", "cl_capfps", "OffOn"
|
||||
Option "Column render mode", "r_columnmethod", "ColumnMethods"
|
||||
|
||||
StaticText " "
|
||||
|
@ -685,6 +686,7 @@ OptionMenu "VideoOptions"
|
|||
Option "Blood Type", "cl_bloodtype", "BloodTypes"
|
||||
Option "Bullet Puff Type", "cl_pufftype", "PuffTypes"
|
||||
Slider "Number of particles", "r_maxparticles", 100, 10000, 100, 0
|
||||
Slider "Number of decals", "cl_maxdecals", 0, 10000, 100, 0
|
||||
Option "Show player sprites", "r_drawplayersprites", "OnOff"
|
||||
Option "Death camera", "r_deathcamera", "OnOff"
|
||||
Option "Teleporter zoom", "telezoom", "OnOff"
|
||||
|
|
Loading…
Reference in a new issue