Weapon swap adjustments for dual-wieldables.
Weapon swap fix for Candygun.
This commit is contained in:
parent
d20773a56f
commit
c782fec486
6 changed files with 232 additions and 12 deletions
|
|
@ -1,3 +1,3 @@
|
|||
[default]
|
||||
SWWM_MODVER="\chSWWM \czGZ\c- \cw1.2pre r101 \cu(Wed 29 Dec 21:46:20 CET 2021)\c-";
|
||||
SWWM_SHORTVER="\cw1.2pre r101 \cu(2021-12-29 21:46:20)\c-";
|
||||
SWWM_MODVER="\chSWWM \czGZ\c- \cw1.2pre r102 \cu(Thu 30 Dec 01:52:21 CET 2021)\c-";
|
||||
SWWM_SHORTVER="\cw1.2pre r102 \cu(2021-12-30 01:52:21)\c-";
|
||||
|
|
|
|||
|
|
@ -570,3 +570,16 @@ Model "DualExplodiumGun"
|
|||
FrameIndex XZWN O 1 306
|
||||
FrameIndex XZWN P 1 307
|
||||
}
|
||||
|
||||
Model "SWWMDualWeaponGiver"
|
||||
{
|
||||
Path "models"
|
||||
|
||||
Model 0 "ExplodiumGunPickupDual_d.3d"
|
||||
Skin 0 "ExplodiumGun.png"
|
||||
Scale 0.05 0.05 0.05
|
||||
ZOffset 16
|
||||
ROTATING
|
||||
|
||||
FrameIndex XZW1 A 0 0
|
||||
}
|
||||
|
|
|
|||
BIN
models/ExplodiumGunPickupDual_a.3d
Normal file
BIN
models/ExplodiumGunPickupDual_a.3d
Normal file
Binary file not shown.
BIN
models/ExplodiumGunPickupDual_d.3d
Normal file
BIN
models/ExplodiumGunPickupDual_d.3d
Normal file
Binary file not shown.
|
|
@ -26,6 +26,13 @@ Class SWWMWeapon : Weapon abstract
|
|||
let w = SWWMWeapon(i);
|
||||
if ( w && !w.bNoSwapWeapon && (SlotNumber != -1) && (w.SlotNumber == SlotNumber) )
|
||||
return true;
|
||||
let wg = SWWMDualWeaponGiver(i);
|
||||
if ( wg )
|
||||
{
|
||||
let w = wg.giveme[0];
|
||||
if ( w && !w.bNoSwapWeapon && (SlotNumber != -1) & (w.SlotNumber == SlotNumber) )
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -79,20 +86,33 @@ Class SWWMWeapon : Weapon abstract
|
|||
SWWMWeapon sw;
|
||||
if ( swwm_swapweapons && (sw = HasSwapWeapon(user)) )
|
||||
{
|
||||
// special case, otherwise candy gun won't drop itself
|
||||
if ( sw is 'CandyGun' ) CandyGun(sw).swapdrop = true;
|
||||
if ( (sw == user.player.ReadyWeapon) || (sw.SisterWeapon && (sw.SisterWeapon == user.player.ReadyWeapon)) )
|
||||
swapto = true;
|
||||
int ngun = sw.Amount;
|
||||
double ang = -15*(ngun-1);
|
||||
for ( int i=0; i<ngun; i++ )
|
||||
if ( ngun == 2 )
|
||||
{
|
||||
// create a dual giver
|
||||
let dg = SWWMDualWeaponGiver(Spawn("SWWMDualWeaponGiver",pos));
|
||||
dg.angle = angle;
|
||||
dg.vel = vel;
|
||||
dg.FloatBobPhase = FloatBobPhase;
|
||||
// transfer both guns
|
||||
dg.giveme[0] = SWWMWeapon(sw.CreateTossable(1));
|
||||
dg.giveme[0].AttachToOwner(dg);
|
||||
dg.giveme[1] = SWWMWeapon(sw.CreateTossable(1));
|
||||
dg.giveme[1].AttachToOwner(dg);
|
||||
dg.SetPickupState();
|
||||
}
|
||||
else
|
||||
{
|
||||
// swap in-place
|
||||
let d = user.DropInventory(sw);
|
||||
if ( !d || (ngun <= 1) ) continue;
|
||||
// adjust angle for multi-drops
|
||||
d.angle = user.angle+ang;
|
||||
d.vel.xy = RotateVector((5,0),d.angle);
|
||||
d.vel.z = 1;
|
||||
d.vel += user.vel;
|
||||
ang += 30;
|
||||
d.SetOrigin(pos,false);
|
||||
d.angle = angle;
|
||||
d.vel = vel;
|
||||
d.FloatBobPhase = FloatBobPhase;
|
||||
}
|
||||
// don't autoswitch just yet (hacky)
|
||||
if ( swapto )
|
||||
|
|
@ -443,3 +463,188 @@ Class SWWMWeapon : Weapon abstract
|
|||
FloatBobStrength 0.25;
|
||||
}
|
||||
}
|
||||
|
||||
// used for dual swapweapons
|
||||
Class SWWMDualWeaponGiver : Inventory
|
||||
{
|
||||
Mixin SWWMOverlapPickupSound;
|
||||
Mixin SWWMRespawn;
|
||||
|
||||
bool bUsePickup;
|
||||
SWWMWeapon giveme[2];
|
||||
|
||||
Default
|
||||
{
|
||||
Inventory.PickupSound "misc/w_pkup";
|
||||
Inventory.RestrictedTo "Demolitionist";
|
||||
Inventory.PickupFlash "SWWMRedPickupFlash";
|
||||
+WEAPONSPAWN;
|
||||
+FLOATBOB;
|
||||
+INVENTORY.NEVERRESPAWN;
|
||||
+INVENTORY.QUIET;
|
||||
FloatBobStrength 0.25;
|
||||
}
|
||||
|
||||
override void Touch( Actor toucher )
|
||||
{
|
||||
// show prompt to swap weapon, and prevent normal pickup
|
||||
SWWMWeapon sw;
|
||||
if ( bSPECIAL && swwm_swapweapons && (sw = giveme[0].HasSwapWeapon(toucher)) )
|
||||
{
|
||||
if ( toucher.CheckLocalView() )
|
||||
{
|
||||
// use sisterweapon tag for dual wield (slot 2 weapons)
|
||||
if ( sw.SisterWeapon && (sw.Amount > 1) )
|
||||
Console.MidPrint(SmallFont,String.Format(StringTable.Localize("$SWWM_SWAPWEAPON"),sw.SisterWeapon.GetTag(),GetTag()));
|
||||
else Console.MidPrint(SmallFont,String.Format(StringTable.Localize("$SWWM_SWAPWEAPON"),sw.GetTag(),GetTag()));
|
||||
}
|
||||
return;
|
||||
}
|
||||
// explicit use-to pickup, function must be called from Used() virtual
|
||||
if ( toucher.player && swwm_usetopickup && !bUsePickup )
|
||||
return;
|
||||
Super.Touch(toucher);
|
||||
}
|
||||
|
||||
override bool Used( Actor user )
|
||||
{
|
||||
// can't pick up
|
||||
if ( !bSPECIAL ) return false;
|
||||
// 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;
|
||||
// if the toucher owns our SwapWeapon, drop it before picking us up
|
||||
bool swapto = false;
|
||||
SWWMWeapon sw;
|
||||
if ( swwm_swapweapons && (sw = giveme[0].HasSwapWeapon(user)) )
|
||||
{
|
||||
// no need for candygun check here
|
||||
if ( (sw == user.player.ReadyWeapon) || (sw.SisterWeapon && (sw.SisterWeapon == user.player.ReadyWeapon)) )
|
||||
swapto = true;
|
||||
int ngun = sw.Amount;
|
||||
if ( ngun == 2 )
|
||||
{
|
||||
// create a dual giver
|
||||
let dg = SWWMDualWeaponGiver(Spawn("SWWMDualWeaponGiver",pos));
|
||||
dg.angle = angle;
|
||||
dg.vel = vel;
|
||||
dg.FloatBobPhase = FloatBobPhase;
|
||||
// transfer both guns
|
||||
dg.giveme[0] = SWWMWeapon(sw.CreateTossable(1));
|
||||
dg.giveme[0].AttachToOwner(dg);
|
||||
dg.giveme[1] = SWWMWeapon(sw.CreateTossable(1));
|
||||
dg.giveme[1].AttachToOwner(dg);
|
||||
dg.SetPickupState();
|
||||
}
|
||||
else
|
||||
{
|
||||
// swap in-place
|
||||
let d = user.DropInventory(sw);
|
||||
d.SetOrigin(pos,false);
|
||||
d.angle = angle;
|
||||
d.vel = vel;
|
||||
d.FloatBobPhase = FloatBobPhase;
|
||||
}
|
||||
// don't autoswitch just yet (hacky)
|
||||
if ( swapto )
|
||||
{
|
||||
user.player.ReadyWeapon = null;
|
||||
user.player.PendingWeapon = WP_NOCHANGE;
|
||||
}
|
||||
}
|
||||
bUsePickup = true;
|
||||
Touch(user);
|
||||
bUsePickup = false;
|
||||
// we got picked up
|
||||
if ( bDestroyed || Owner || !bSPECIAL )
|
||||
{
|
||||
// autoswitch to us if we got swapped
|
||||
if ( swapto ) user.A_SelectWeapon(giveme[0].GetClass());
|
||||
Vector3 tracedir = level.Vec3Diff(userpos,itempos);
|
||||
double dist = tracedir.length();
|
||||
tracedir /= dist;
|
||||
let cf = new("CrossLineFinder");
|
||||
cf.Trace(userpos,level.PointInSector(userpos.xy),tracedir,dist,0);
|
||||
// trigger all player cross lines found between user and item
|
||||
for ( int i=0; i<cf.clines.Size(); i++ )
|
||||
cf.clines[i].Activate(user,cf.csides[i],SPAC_Cross);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
override bool TryPickup( in out Actor toucher )
|
||||
{
|
||||
if ( giveme[0].HasSwapWeapon(toucher) )
|
||||
return false;
|
||||
let cur = toucher.FindInventory(giveme[0].GetClass());
|
||||
if ( !cur )
|
||||
{
|
||||
// give both guns and go away
|
||||
if ( !giveme[1].CallTryPickup(toucher) ) giveme[1].Destroy();
|
||||
if ( !giveme[0].CallTryPickup(toucher) ) giveme[0].Destroy();
|
||||
Spawn(PickupFlash,pos,ALLOW_REPLACE);
|
||||
PrintPickupMessage(toucher.CheckLocalView(),GetTag());
|
||||
PlayPickupSound(toucher);
|
||||
if ( toucher.player ) toucher.player.bonuscount = BONUSADD;
|
||||
GoAwayAndDie();
|
||||
return true;
|
||||
}
|
||||
else if ( cur.Amount < 2 )
|
||||
{
|
||||
// give one gun
|
||||
if ( !giveme[1].CallTryPickup(toucher) ) giveme[1].Destroy();
|
||||
// drop the other where we stand
|
||||
giveme[0].BecomePickup();
|
||||
giveme[0].SetOrigin(pos,false);
|
||||
giveme[0].Angle = Angle;
|
||||
giveme[0].Vel = Vel;
|
||||
giveme[0].bNoGravity = false;
|
||||
giveme[0].ClearCounters();
|
||||
giveme[0].FloatBobPhase = FloatBobPhase;
|
||||
// don't forget to reattach its glow
|
||||
if ( (giveme[1].PickupFlash is 'SWWMPickupFlash') && swwm_itemglows )
|
||||
{
|
||||
let p = Spawn(giveme[0].PickupFlash,giveme[0].Vec3Offset(0,0,16));
|
||||
p.target = giveme[0];
|
||||
p.SetStateLabel("Pickup");
|
||||
}
|
||||
// and then go away
|
||||
Spawn(PickupFlash,pos,ALLOW_REPLACE);
|
||||
PrintPickupMessage(toucher.CheckLocalView(),giveme[0].PickupMessage());
|
||||
PlayPickupSound(toucher);
|
||||
if ( toucher.player ) toucher.player.bonuscount = BONUSADD;
|
||||
GoAwayAndDie();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SetPickupState()
|
||||
{
|
||||
if ( giveme[0] is 'PlasmaBlast' )
|
||||
{
|
||||
SetTag("$T_PLASMABLAST2");
|
||||
SetState(SpawnState+1);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetTag("$T_EXPLODIUM2");
|
||||
SetState(SpawnState);
|
||||
}
|
||||
A_SetSize(giveme[0].default.radius,giveme[0].default.height);
|
||||
}
|
||||
|
||||
States
|
||||
{
|
||||
Spawn:
|
||||
XZW1 AB -1; // A: Explodium Gun, B: Plasma Blaster
|
||||
Stop;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ Class CandyGun : SWWMWeapon
|
|||
double casex, casey;
|
||||
transient ui TextureID WeaponBox;
|
||||
bool tospecial;
|
||||
bool swapdrop; // used by weapon swapping so CreateTossable actually tosses the gun, rather than spares
|
||||
|
||||
Property ClipCount : ClipCount;
|
||||
|
||||
|
|
@ -324,7 +325,7 @@ Class CandyGun : SWWMWeapon
|
|||
|
||||
override Inventory CreateTossable( int amt )
|
||||
{
|
||||
if ( Ammo2.Amount > 0 )
|
||||
if ( (Ammo2.Amount > 0) && !swapdrop )
|
||||
{
|
||||
// drop an empty spare
|
||||
let spare = Inventory(Spawn('CandyGun',Owner.Pos,NO_REPLACE));
|
||||
|
|
@ -339,6 +340,7 @@ Class CandyGun : SWWMWeapon
|
|||
Ammo2.Amount--;
|
||||
return spare;
|
||||
}
|
||||
swapdrop = false;
|
||||
return Super.CreateTossable(amt);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue