Add "exclusive use to pickup" option.

Make "pickup through melee" optional (disabled by default).
Increased leniency of use to pickup (nice for items with small hitboxes).
This commit is contained in:
Mari the Deer 2021-05-29 23:26:12 +02:00
commit 3500f72db0
38 changed files with 170 additions and 13 deletions

View file

@ -38,16 +38,23 @@ Class CrossLineFinder : LineTracer
Mixin Class SWWMUseToPickup
{
bool bUsePickup;
// allow pickup by use
override bool Used( Actor user )
{
// no use through melee
if ( (user.player.ReadyWeapon is 'SWWMWeapon') && SWWMWeapon(user.player.ReadyWeapon).wallponch && !swwm_meleepickup )
return false;
Vector3 itempos = Vec3Offset(0,0,Height/2),
userpos = user.Vec2OffsetZ(0,0,user.player.viewz);
// test vertical range
Vector3 diff = level.Vec3Diff(user.Vec3Offset(0,0,user.Height/2),Vec3Offset(0,0,Height/2));
double rang = user.player?PlayerPawn(user.player.mo).UseRange:(user.Height/2);
if ( abs(diff.z) > rang ) return false;
bUsePickup = true;
Touch(user);
bUsePickup = false;
// we got picked up
if ( bDestroyed || Owner || !bSPECIAL )
{
@ -63,6 +70,13 @@ Mixin Class SWWMUseToPickup
}
return false;
}
override void Touch( Actor toucher )
{
if ( toucher.player && swwm_usetopickup && !bUsePickup )
return;
Super.Touch(toucher);
}
}
Mixin Class SWWMOverlapPickupSound

View file

@ -1206,6 +1206,26 @@ Class SWWMBulletTrail : LineTracer
}
}
// finds the first pickup-able item
Class SWWMItemTracer : LineTracer
{
override ETraceStatus TraceCallback()
{
if ( Results.HitType == TRACE_HitActor )
{
if ( (Results.HitActor is 'Inventory') && Results.HitActor.bSPECIAL ) return TRACE_Stop;
return TRACE_Skip;
}
else if ( (Results.HitType == TRACE_HitWall) && (Results.Tier == TIER_Middle) )
{
if ( !Results.HitLine.sidedef[1] || (Results.HitLine.Flags&(Line.ML_BlockUse|Line.ML_BlockEverything)) )
return TRACE_Stop;
return TRACE_Skip;
}
return TRACE_Stop;
}
}
// Blob shadows
Class SWWMShadow : Actor
{

View file

@ -69,6 +69,8 @@ Class Demolitionist : PlayerPawn
Actor froggy;
transient int lastuse, failcounter, failcooldown;
transient SWWMItemTracer itrace;
bool meleeuse;
Property DashFuel : dashfuel;
@ -559,6 +561,33 @@ Class Demolitionist : PlayerPawn
else d.HitSector.SetTexture(0,replacewith);
}
}
void CheckItemUsePickup()
{
if ( player.usedown )
return;
if ( !itrace ) itrace = new("SWWMItemTracer");
Vector3 x, y, z, dir;
[x, y, z] = swwm_CoordUtil.GetAxes(pitch,angle,roll);
Vector3 origin = Vec2OffsetZ(0,0,player.viewz);
Sector os = level.PointInSector(origin.xy);
int rings = 1;
Array<Actor> ignoreme;
ignoreme.Clear();
for ( double i=0; i<.2; i+=.02 )
{
for ( int j=0; j<360; j+=(360/rings) )
{
dir = (x+y*cos(j)*i+z*sin(j)*i).unit();
itrace.Trace(origin,os,dir,UseRange,0);
if ( itrace.Results.HitType != TRACE_HitActor ) continue;
if ( ignoreme.Find(itrace.Results.HitActor) < ignoreme.Size() ) continue;
player.usedown = true; // we found an item, ignore further uses
if ( itrace.Results.HitActor.Used(self) ) return;
ignoreme.Push(itrace.Results.HitActor);
}
rings += 2;
}
}
void CheckUnderwaterAmb( bool restore = false )
{
Vector3 headpos = Vec3Offset(0,0,player.viewheight);
@ -729,6 +758,8 @@ Class Demolitionist : PlayerPawn
CheckDefaceTexture();
if ( !player.usedown && froggy )
player.usedown = froggy.Used(self);
// try to "use" the item closest to the crosshair
CheckItemUsePickup();
}
Super.PlayerThink();
if ( (gametic == lastuse) && IsActorPlayingSound(CHAN_VOICE,"*usefail") )

View file

@ -5,6 +5,7 @@ Class SWWMWeapon : Weapon abstract
Mixin SWWMRespawn;
bool wasused;
bool bUsePickup;
private int SWeaponFlags;
Class<Ammo> dropammotype;
@ -50,11 +51,16 @@ Class SWWMWeapon : Weapon abstract
}
return;
}
if ( toucher.player && swwm_usetopickup && !bUsePickup )
return;
Super.Touch(toucher);
}
// allow pickup by use + swap weapon support
override bool Used( Actor user )
{
// no use through melee
if ( (user.player.ReadyWeapon is 'SWWMWeapon') && SWWMWeapon(user.player.ReadyWeapon).wallponch && !swwm_meleepickup )
return false;
Vector3 itempos = Vec3Offset(0,0,Height/2),
userpos = user.Vec2OffsetZ(0,0,user.player.viewz);
// test vertical range
@ -88,7 +94,9 @@ Class SWWMWeapon : Weapon abstract
user.player.PendingWeapon = WP_NOCHANGE;
}
}
bUsePickup = true;
Touch(user);
bUsePickup = false;
// we got picked up
if ( bDestroyed || Owner || !bSPECIAL )
{