Allow selling excess weapons/powerups.

Change of plans for one DLC weapon choice.
Various small fixes and tweaks.
Doubled price of Ynykron, since it was too cheap.
Fixed Candygun spares not being picked up in coop.
Add option to toggle menu fuzz, for streamers concerned about bitrate.
Add MAP07 enemies to the vanilla boss enhancer.
This commit is contained in:
Mari the Deer 2020-05-19 14:29:07 +02:00
commit af1df2e18d
24 changed files with 197 additions and 44 deletions

View file

@ -4,7 +4,7 @@ Class GravityCell : Ammo
{
}
Class SplatCore : Ammo
Class SMW05Ammo : Ammo
{
}
@ -20,7 +20,11 @@ Class DarkCanister : Ammo
{
}
Class SMW05Ammo : Ammo
Class KinylumUnit : Ammo
{
}
Class NokronUnit : Ammo
{
}

View file

@ -0,0 +1,6 @@
// Tach-Engine Technologies Series x3 Sparkster Carbine (UnSX 2)
// Slot 7, spawns shared with Legacy Sparkster
Class ModernSparkster : SWWMWeapon
{
}

View file

@ -1,6 +0,0 @@
// Dr. Locke's Instant Room Painter aka "Splatter" (from SWWM Series)
// Slot 4, spawns shared with Wallbuster
Class Splatter : SWWMWeapon
{
}

View file

@ -1,5 +1,5 @@
// Blackmann Arms "Puntzer Gamma" SMW.05 Assault Carbine (was planned for SWWM Z)
// Slot 7, spawns shared with Legacy Sparkster
// Slot 4, spawns shared with Wallbuster
Class PuntzerGamma : SWWMWeapon
{

View file

@ -209,6 +209,11 @@ Class SWWMUtility
a.roll = -fpitch*ddiff1;
a.angle = dang;
}
static clearscope int Round100( double x )
{
return int(ceil(x/100.)*100.);
}
}
// Stats
@ -805,7 +810,7 @@ Class SWWMCombatTracker : Thinker
t = new("SWWMCombatTracker");
t.ChangeStatNum(STAT_USER);
t.mytarget = target;
if ( target.player || target.bISMONSTER )
if ( target.player || target.bISMONSTER || (target is 'BossBrain') )
t.mytag = target.player?target.player.GetUserName():target.GetTag();
else t.mytag = "";
if ( target.player )
@ -897,6 +902,11 @@ Class SWWMCombatTracker : Thinker
// any visible enemies within 600mu
if ( (mytarget.Vec3To(players[consoleplayer].mo).length() < 600) && players[consoleplayer].mo.CheckSight(mytarget) ) updated = level.maptime;
}
else if ( mytarget is 'BossBrain' )
{
// teh romero, only if visible
if ( (mytarget.Vec3To(players[consoleplayer].mo).length() < 600) && players[consoleplayer].mo.CheckSight(mytarget) ) updated = level.maptime;
}
lasthealth = newhealth;
intp.Update(lasthealth);
}
@ -2328,11 +2338,14 @@ Class SWWMHandler : EventHandler
}
if ( spawnme ) SWWMScoreObj.Spawn(-e.Damage,e.Thing.Vec3Offset(FRandom[ScoreBits](-8,8),FRandom[ScoreBits](-8,8),FRandom[ScoreBits](-8,8)+e.Thing.Height/2),Font.CR_RED,e.Thing);
// update combat tracker for it
for ( SWWMCombatTracker t=trackers; t; t=t.next )
if ( !(e.Thing is 'BossBrain') )
{
if ( t.mytarget != e.Thing ) continue;
t.updated = level.maptime+35;
break;
for ( SWWMCombatTracker t=trackers; t; t=t.next )
{
if ( t.mytarget != e.Thing ) continue;
t.updated = level.maptime+35;
break;
}
}
}
if ( e.Thing.player )
@ -2415,7 +2428,7 @@ Class SWWMHandler : EventHandler
{
scr.xscore[ofs] = 0;
scr.xtcolor[ofs] = Font.CR_FIRE;
scr.xstr[ofs] = "$SWWM_OVERKILL";
scr.xstr[ofs] = StringTable.Localize("$SWWM_OVERKILL");
scr.xcnt = ++ofs;
}
}
@ -2426,7 +2439,7 @@ Class SWWMHandler : EventHandler
{
scr.xscore[ofs] = (multilevel[pnum]>=16)?int.max:(multilevel[pnum]+1);
scr.xtcolor[ofs] = Font.CR_FIRE;
scr.xstr[ofs] = "$SWWM_MULTIKILL";
scr.xstr[ofs] = StringTable.Localize("$SWWM_MULTIKILL");
scr.xcnt = ++ofs;
}
}
@ -2440,7 +2453,7 @@ Class SWWMHandler : EventHandler
{
scr.xscore[ofs] = spreecount[pnum]+1;
scr.xtcolor[ofs] = Font.CR_FIRE;
scr.xstr[ofs] = "$SWWM_SPREEKILL";
scr.xstr[ofs] = StringTable.Localize("$SWWM_SPREEKILL");
scr.xcnt = ++ofs;
}
}
@ -2451,7 +2464,7 @@ Class SWWMHandler : EventHandler
{
scr.xscore[ofs] = 0;
scr.xtcolor[ofs] = Font.CR_FIRE;
scr.xstr[ofs] = "$SWWM_BOSSKILL";
scr.xstr[ofs] = StringTable.Localize("$SWWM_BOSSKILL");
scr.xcnt = ++ofs;
}
}
@ -2502,14 +2515,34 @@ Class SWWMHandler : EventHandler
if ( hnd ) hnd.DoKeyTagFix(a);
}
// spreads apart overlapping inventory items, since they'll look bad otherwise
private void CheckSpreadOut( Actor a )
{
let bt = BlockThingsIterator.Create(a,16);
while ( bt.Next() )
{
let t = bt.Thing;
if ( !t || (t == a) || !(t is 'Inventory') || !(t.spawnpoint ~== a.spawnpoint) ) continue;
double ang = FRandom[Spreading](0,360);
a.vel += (cos(ang)*4,sin(ang)*4,3);
break;
}
}
override void WorldThingSpawned( WorldEvent e )
{
if ( e.Thing is 'Inventory' )
CheckSpreadOut(e.Thing);
if ( e.Thing is 'Key' )
{
DoKeyTagFix(e.Thing);
SWWMInterest.Spawn(thekey:Key(e.Thing));
}
else if ( e.Thing is 'BossBrain' ) e.Thing.SetTag("$FN_BOSSBRAIN");
else if ( e.Thing is 'BossBrain' )
{
e.Thing.SetTag("$FN_BOSSBRAIN");
e.Thing.A_SetSize(20,70);
}
else if ( e.Thing is 'CommanderKeen' ) e.Thing.SetTag("$FN_KEEN");
if ( (e.Thing.bSHOOTABLE || e.Thing.bISMONSTER) && !(e.Thing is 'LampMoth') && !(e.Thing is 'CompanionLamp') ) SWWMCombatTracker.Spawn(e.Thing);
}

View file

@ -30,7 +30,7 @@ Class Ynykron : SWWMWeapon
Obituary "$O_YNYKRON";
Weapon.SlotNumber 0;
Weapon.SelectionOrder 1000;
Stamina 2500000;
Stamina 5000000;
Weapon.AmmoType1 "YnykronAmmo";
Weapon.AmmoGive1 1;
+SWWMWEAPON.NOFIRSTGIVE;

View file

@ -635,8 +635,8 @@ Class SWWMStatusBar : BaseStatusBar
fnt = LangFont(mMiniwiFont);
for ( int i=0; i<snum.xcnt; i++ )
{
tag = StringTable.Localize(snum.xstr[i]);
if ( snum.xscore[i] == int.max ) tag.AppendFormat(" %s",StringTable.Localize("$SWWM_MAX"));
tag = snum.xstr[i];
if ( snum.xscore[i] == int.max ) tag.AppendFormat(" MAX");
else if ( snum.xscore[i] > 0 ) tag.AppendFormat(" x%d",snum.xscore[i]);
Screen.DrawText(fnt,snum.xtcolor[i],(vpos.x-hss.x*(fo.x+fnt.StringWidth(tag)/2.))/hss.x,(vpos.y-hss.y*(fo.y+(fnt.GetHeight()/2.)))/hss.y,tag,DTA_VirtualWidthF,sss.x,DTA_VirtualHeightF,sss.y,DTA_KeepRatio,true,DTA_Alpha,alph);
fo.y += fnt.GetHeight();

View file

@ -5,6 +5,15 @@ Mixin Class SWWMAutoUseFix
{
if ( GetClass() == item.GetClass() )
{
// sell excess if there's a price
if ( bALWAYSPICKUP && (Amount+item.Amount > MaxAmount) && (Stamina > 0) )
{
int sellprice = SWWMUtility.Round100(Stamina*.7);
SWWMScoreObj.Spawn(sellprice,Owner.Vec3Offset(FRandom[ScoreBits](-8,8),FRandom[ScoreBits](-8,8),FRandom[ScoreBits](-8,8)+Owner.Height/2),Font.CR_GOLD);
SWWMCredits.Give(Owner.player,sellprice);
if ( Owner.player )
Console.Printf(StringTable.Localize("$SWWM_SELLEXTRA"),Owner.player.GetUserName(),GetTag(),sellprice);
}
if ( Use(true) ) Amount--;
}
return Super.HandlePickup(item);
@ -906,6 +915,26 @@ Class SWWMWeapon : Weapon abstract
FlagDef NoFirstGive : SWeaponFlags, 0; // don't give ammo on first pickup (for weapons with a clip count)
override bool HandlePickup( Inventory item )
{
if ( (GetClass() == item.GetClass()) )
{
if ( Weapon(item).PickupForAmmo(self) )
item.bPickupGood = true;
if ( (Amount+item.Amount > MaxAmount) && (Stamina > 0) )
{
// sell excess
int sellprice = SWWMUtility.Round100(Stamina*.7);
SWWMScoreObj.Spawn(sellprice,Owner.Vec3Offset(FRandom[ScoreBits](-8,8),FRandom[ScoreBits](-8,8),FRandom[ScoreBits](-8,8)+Owner.Height/2),Font.CR_GOLD);
SWWMCredits.Give(Owner.player,sellprice);
if ( Owner.player )
Console.Printf(StringTable.Localize("$SWWM_SELLEXTRA"),Owner.player.GetUserName(),GetTag(),sellprice);
item.bPickupGood = true;
}
return true;
}
return Super.HandlePickup(item);
}
override void AttachToOwner( Actor other )
{
Inventory.AttachToOwner(other);

View file

@ -17,7 +17,7 @@ Class SWWMKnowledgeBaseMenu : GenericMenu
TextureID MainWindow, TabSeparator, WindowSeparator, WindowSeparatorH,
FancyBg, EasterEgg, LoreSeparator, LoreSeparatorW;
transient CVar lang;
transient CVar lang, fuzz;
transient Font TewiFont, MPlusFont;
int curtab, oldtab;
// for scrolling
@ -1833,7 +1833,9 @@ Class SWWMKnowledgeBaseMenu : GenericMenu
double hs = max(min(floor(Screen.GetWidth()/640.),floor(Screen.GetHeight()/400.)),1.);
Vector2 ss = (Screen.GetWidth(),Screen.GetHeight())/hs;
Vector2 origin = (ss.x-640,ss.y-400)/2.;
Screen.DrawTexture(FancyBg,false,origin.x,origin.y,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_LegacyRenderStyle,STYLE_Add,DTA_Alpha,.5);
if ( !fuzz ) fuzz = CVar.GetCvar('swwm_fuzz',players[consoleplayer]);
if ( fuzz.GetBool() )
Screen.DrawTexture(FancyBg,false,origin.x,origin.y,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_LegacyRenderStyle,STYLE_Add,DTA_Alpha,.5);
Screen.DrawTexture(MainWindow,false,origin.x,origin.y,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
// draw tabs
double xx = 3, yy = 0;

View file

@ -1450,7 +1450,16 @@ Class SWWMLamp : Inventory
// add charge
if ( item.GetClass() == GetClass() )
{
if ( Charge > 0 )
if ( (Charge >= Default.Charge) && (Amount+item.Amount > MaxAmount) )
{
// sell excess
int sellprice = SWWMUtility.Round100(Stamina*.7);
SWWMScoreObj.Spawn(sellprice,Owner.Vec3Offset(FRandom[ScoreBits](-8,8),FRandom[ScoreBits](-8,8),FRandom[ScoreBits](-8,8)+Owner.Height/2),Font.CR_GOLD);
SWWMCredits.Give(Owner.player,sellprice);
if ( Owner.player )
Console.Printf(StringTable.Localize("$SWWM_SELLEXTRA"),Owner.player.GetUserName(),GetTag(),sellprice);
}
else if ( Charge > 0 )
{
int AddCharge = Charge+SWWMLamp(item).Charge;
Charge = min(Default.Charge,AddCharge);

View file

@ -1564,8 +1564,8 @@ Class GoldenImpact : Actor
{
Super.PostBeginPlay();
A_AlertMonsters(40000);
SWWMHandler.DoBlast(self,200,120000);
A_Explode(7777,200);
SWWMHandler.DoBlast(self,600,1200000);
A_Explode(7777,600);
A_QuakeEx(9,9,9,40,0,5000,"",QF_RELATIVE|QF_SCALEDOWN,falloff:500,rollintensity:1.5);
A_StartSound("spreadgun/goldexpl",CHAN_VOICE,attenuation:.3);
A_StartSound("spreadgun/goldexpl",CHAN_WEAPON,attenuation:.15);
@ -1691,8 +1691,8 @@ Class GoldenSubImpact : Actor
override void PostBeginPlay()
{
Super.PostBeginPlay();
SWWMHandler.DoBlast(self,200,90000);
A_Explode(777,200);
SWWMHandler.DoBlast(self,400,900000);
A_Explode(777,400);
A_QuakeEx(7,7,7,20,0,2000,"",QF_RELATIVE|QF_SCALEDOWN,falloff:200,rollintensity:.8);
A_SprayDecal("BigScorch",-172);
Scale *= FRandom[ExploS](0.8,1.1);
@ -1816,7 +1816,7 @@ Class GoldenSubSubImpact : Actor
override void PostBeginPlay()
{
Super.PostBeginPlay();
SWWMHandler.DoBlast(self,200,60000);
SWWMHandler.DoBlast(self,200,600000);
A_Explode(77,200);
A_QuakeEx(4,4,4,15,0,1000,"",QF_RELATIVE|QF_SCALEDOWN,falloff:100,rollintensity:.4);
A_SprayDecal("Scorch",-172);

View file

@ -427,6 +427,8 @@ Class ExplodiumGun : SWWMWeapon
Weapon.UpSound "explodium/select";
Weapon.SlotNumber 2;
Weapon.SelectionOrder 2600;
//Inventory.MaxAmount 2;
//Weapon.SisterWeapon "DualExplodiumGun";
Stamina 8000;
ExplodiumGun.ClipCount 7;
}
@ -568,3 +570,21 @@ Class ExplodiumGun : SWWMWeapon
Stop;
}
}
// TODO Dual Explodium Guns (eventually)
/*
Class DualExplodiumGun : ExplodiumGun
{
override bool CheckAmmo( int firemode, bool autoswitch, bool requireammo, int ammocount )
{
if ( (firemode == PrimaryFire) || (firemode == AltFire) )
return (SisterWeapon&&(SisterWeapon.Amount > 1));
return Super.CheckAmmo(firemode,autoswitch,requireammo,ammocount);
}
Default
{
Tag "$T_EXPLODIUM2";
Weapon.SisterWeapon "ExplodiumGun";
}
}*/

View file

@ -838,6 +838,42 @@ Class CandyGun : SWWMWeapon
Property ClipCount : ClipCount;
// re-edit to allow picking up spares in coop
override bool HandlePickup( Inventory item )
{
if ( item.GetClass() == GetClass() )
{
bool ammoget, spareget;
[ammoget, spareget] = CandyGun(item).PickupForAmmoAndSpares(self);
if ( ammoget )
{
item.bPickupGood = true;
if ( !spareget )
{
// sell excess
int sellprice = SWWMUtility.Round100(Stamina*.7);
SWWMScoreObj.Spawn(sellprice,Owner.Vec3Offset(FRandom[ScoreBits](-8,8),FRandom[ScoreBits](-8,8),FRandom[ScoreBits](-8,8)+Owner.Height/2),Font.CR_GOLD);
SWWMCredits.Give(Owner.player,sellprice);
if ( Owner.player )
Console.Printf(StringTable.Localize("$SWWM_SELLEXTRA"),Owner.player.GetUserName(),GetTag(),sellprice);
}
return true;
}
}
return Super.HandlePickup(item);
}
protected bool, bool PickupForAmmoAndSpares( Weapon ownedWeapon )
{
bool gotstuff = false, gotspares = false;
int oldamount = ownedWeapon.Ammo1.Amount;
gotstuff = AddExistingAmmo(ownedWeapon.Ammo1,AmmoGive1);
gotspares = AddExistingAmmo(ownedWeapon.Ammo2,AmmoGive2);
let Owner = ownedWeapon.Owner;
if ( gotstuff && Owner && Owner.player && (oldamount == 0) )
PlayerPawn(Owner).CheckWeaponSwitch(ownedWeapon.Ammo1.GetClass());
return gotstuff, gotspares;
}
override void DrawWeapon( double TicFrac, double bx, double by, Vector2 hs, Vector2 ss )
{
if ( !WeaponBox ) WeaponBox = TexMan.CheckForTexture("graphics/HUD/CandygunDisplay.png",TexMan.Type_Any);

View file

@ -57,6 +57,16 @@ Class SWWMVanillaBossHandler : EventHandler
}
bosstag = "$BT_SPIDER";
}
else if ( level.mapname ~== "MAP07" )
{
if ( (e.Thing is 'Fatso') || (e.Thing is 'Arachnotron') )
{
bossactors.Push(e.Thing);
if ( upgrademe )
e.Thing.Health *= 2;
}
bosstag = "$BT_DIMPLE";
}
else if ( level.mapname ~== "MAP30" )
{
if ( e.Thing is 'BossBrain' )
@ -116,19 +126,19 @@ Class SWWMVanillaBossHandler : EventHandler
if ( e.Thing is 'ClericBoss' )
{
bossactors.Push(e.Thing);
if ( upgrademe ) e.Thing.Health *= 3;
if ( upgrademe ) e.Thing.Health *= 2;
bosstag = "$BT_CLERIC";
}
else if ( e.Thing is 'FighterBoss' )
{
bossactors.Push(e.Thing);
if ( upgrademe ) e.Thing.Health *= 3;
if ( upgrademe ) e.Thing.Health *= 2;
bosstag = "$BT_FIGHTER";
}
else if ( e.Thing is 'MageBoss' )
{
bossactors.Push(e.Thing);
if ( upgrademe ) e.Thing.Health *= 3;
if ( upgrademe ) e.Thing.Health *= 2;
bosstag = "$BT_MAGE";
}
else if ( e.Thing is 'Dragon' )
@ -175,7 +185,7 @@ Class SWWMVanillaBossHandler : EventHandler
for ( int i=0; i<bossactors.Size(); i++ )
{
if ( !bossactors[i] ) continue;
thealth += bossactors[i].Health;
thealth += max(0,bossactors[i].Health);
}
hmax = thealth;
for ( int i=0; i<30; i++ ) oldhealth[i] = thealth;
@ -192,7 +202,7 @@ Class SWWMVanillaBossHandler : EventHandler
for ( int i=0; i<bossactors.Size(); i++ )
{
if ( !bossactors[i] ) continue;
newhealth += bossactors[i].Health;
newhealth += max(0,bossactors[i].Health);
}
oldhealth[0] = newhealth;
int curcumm = max(0,thealth-newhealth);