Several changes from devel once more:

- Fuck it, Quadravol will be lever action.
 - Tiny cleanup.
 - Rewrite the weapon replacement system (less of a mess now maybe?).
 - Some menu fixes.
 - Minimap zoom increments like in the Common Library.
 - Add missing sound definition for Safety Tether.
   (This mostly went unnoticed because it's VERY rare to have it play)
 - Shift Sparkster x3 (DLC2) to slot 7.
   This way you can have both it and the Quadravol simultaneously.
   It would be unfair to not let you hold both "iconic" UnSX weapons at once.
 - Small lore tweak on Quadravol stance swap.
 - Fix off-by-one bug in looping palette lights.
 - Re-do logo shader. Use separate layer textures.
 - Fix Elemental Coating breaking "End Level" damage sectors.
(This will be the last batch of changes before I continue working on menus)
This commit is contained in:
Mari the Deer 2021-12-08 18:14:18 +01:00
commit 4d7019ae86
41 changed files with 287 additions and 186 deletions

View file

@ -1,5 +1,5 @@
// Tach-Engine & Nekuratek Sparkster x3 (from UnSX 2)
// Slot 6, spawns shared with Hellblazer
// Slot 7, spawns shared with Biospark Carbine
Class ModernSparkster : SWWMWeapon
{
@ -19,7 +19,7 @@ Class ModernSparkster : SWWMWeapon
Obituary "$O_NEWSPARKSTER";
SWWMWeapon.Tooltip "$TT_NEWSPARKSTER";
Inventory.Icon "graphics/HUD/Icons/W_NewSparkster.png";
Weapon.SlotNumber 6;
Weapon.SlotNumber 7;
Weapon.SlotPriority 3.;
Weapon.SelectionOrder 625;
Weapon.AmmoType1 "SparksterBAmmo";

View file

@ -18,7 +18,9 @@ extend Class SWWMHandler
{
if ( (gamestate != GS_LEVEL) || (players[consoleplayer].Health <= 0) || !(players[consoleplayer].mo is 'Demolitionist') )
return;
double val = max(.5,swwm_mm_zoom/2.);
double val = swwm_mm_zoom;
if ( val > 1. ) val = max(1.,val-.5);
else val = max(.5,val-.25);
CVar.FindCVar('swwm_mm_zoom').SetFloat(val);
}
else if ( e.Name ~== "swwmzoomout" )
@ -26,7 +28,9 @@ extend Class SWWMHandler
if ( (gamestate != GS_LEVEL) || (players[consoleplayer].Health <= 0) || !(players[consoleplayer].mo is 'Demolitionist') )
return;
double maxval = players[consoleplayer].mo.FindInventory("Omnisight")?2.:1.;
double val = min(maxval,swwm_mm_zoom*2.);
double val = swwm_mm_zoom;
if ( val >= 1. ) val = min(maxval,val+.5);
else val = min(1.,val+.25);
CVar.FindCVar('swwm_mm_zoom').SetFloat(val);
}
}

View file

@ -616,9 +616,9 @@ extend Class SWWMHandler
else if ( (e.Replacee is 'Chainsaw') || (e.Replacee is 'Gauntlets') || (e.Replacee is 'FWeapAxe') ) e.Replacement = SWWMUtility.PickSWWMSlot1();
else if ( (e.Replacee is 'Fist') || (e.Replacee is 'Staff') ) e.Replacement = 'DeepImpact';
else if ( (e.Replacee is 'Pistol') || (e.Replacee is 'GoldWand') || (e.Replacee is 'FWeapFist') || (e.Replacee is 'CWeapMace') || (e.Replacee is 'MWeapWand') ) e.Replacement = SWWMUtility.PickSWWMSlot2();
else if ( (e.Replacee is 'Shotgun') || (e.Replacee is 'CWeapStaff') ) e.Replacement = SWWMUtility.IsDoomOne()?SWWMUtility.PickHereticSlot3():SWWMUtility.PickSWWMSlot3();
else if ( (e.Replacee is 'Shotgun') || (e.Replacee is 'CWeapStaff') ) e.Replacement = SWWMUtility.IsDoomOne()?SWWMUtility.PickDoomSlot3():SWWMUtility.PickSWWMSlot3();
else if ( (e.Replacee is 'SuperShotgun') || (e.Replacee is 'MWeapFrost') ) e.Replacement = SWWMUtility.PickSWWMSlot4();
else if ( e.Replacee is 'Crossbow' ) e.Replacement = SWWMUtility.PickHereticSlot3();
else if ( e.Replacee is 'Crossbow' ) e.Replacement = SWWMUtility.PickDoomSlot3();
else if ( (e.Replacee is 'Chaingun') || (e.Replacee is 'Blaster') || (e.Replacee is 'FWeaponPiece3') ) e.Replacement = SWWMUtility.PickSWWMSlot5();
else if ( (e.Replacee is 'RocketLauncher') || (e.Replacee is 'PhoenixRod') || (e.Replacee is 'FWeapHammer') ) e.Replacement = SWWMUtility.PickSWWMSlot6();
else if ( (e.Replacee is 'PlasmaRifle') || (e.Replacee is 'SkullRod') ) e.Replacement = SWWMUtility.PickDoomSlot6();

View file

@ -207,17 +207,6 @@ Class SWWMAmmo : Ammo
return Super.HandlePickup(item);
}
override void DoEffect()
{
Super.DoEffect();
// drop excess ammo
if ( !sv_infiniteammo && !Owner.FindInventory('PowerInfiniteAmmo') )
{
int excess = Amount-MaxAmount;
if ( excess > 0 ) CreateTossable(excess);
}
}
override bool CanPickup( Actor toucher )
{
// don't allow picking up ammo for weapons we can't pick up
@ -486,12 +475,6 @@ Class MagAmmo : Inventory abstract
override void DoEffect()
{
Super.DoEffect();
// drop excess ammo
if ( !sv_infiniteammo && !Owner.FindInventory('PowerInfiniteAmmo') )
{
int excess = Amount-MaxAmount;
if ( excess > 0 ) CreateTossable(excess);
}
if ( !pamo )
{
pamo = Ammo(Owner.FindInventory(ParentAmmo));

View file

@ -2174,6 +2174,33 @@ Class BarrierPower : PowerIronFeet
if ( !snd ) snd = Spawn("BarrierSnd",Owner.pos);
snd.target = Owner;
snd.master = self;
// break ourselves if we're in an endlevel sector
bool endlv = false;
for ( int i=0; i<Owner.CurSector.Get3DFloorCount(); i++ )
{
F3DFloor ff = Owner.CurSector.Get3DFloor(i);
if ( !(ff.flags&(F3DFloor.FF_EXISTS|F3DFloor.FF_SWIMMABLE)) ) continue;
if ( (ff.model.DamageAmount <= 0) || (ff.model.damageinterval <= 0) ) continue;
if ( ff.top.ZAtPoint(Owner.pos.xy) <= Owner.pos.z ) continue;
if ( ff.bottom.ZAtPoint(Owner.pos.xy) >= (Owner.pos.z+Owner.Height) ) continue;
if ( !(ff.model.flags&Sector.SECF_ENDLEVEL) ) continue;
endlv = true;
break;
}
if ( !endlv && (Owner.pos.z <= Owner.floorz) )
{
bool damageterrain = false;
if ( (Owner.floorsector.damageamount > 0) && (Owner.floorsector.damageinterval > 0) ) damageterrain = true;
else
{
let t = Owner.GetFloorTerrain();
if ( t && (t.DamageAmount > 0) && (t.DamageTimeMask > 0) )
damageterrain = true;
}
if ( damageterrain && (Owner.floorsector.flags&Sector.SECF_ENDLEVEL) ) endlv = true;
}
if ( !endlv ) return;
EffectTics = min(0,EffectTics);
}
}
@ -2226,6 +2253,7 @@ Class EBarrier : Inventory
override void DoEffect()
{
Super.DoEffect();
if ( !Owner || (Owner.Health <= 0) ) return;
// check terrain for auto-use
let b = Powerup(Owner.FindInventory("BarrierPower"));
if ( b && (b.EffectTics > 5) )
@ -2234,6 +2262,7 @@ Class EBarrier : Inventory
return;
}
bool damageterrain = false;
bool endlevelterrain = false;
// check any 3d floors first
for ( int i=0; i<Owner.CurSector.Get3DFloorCount(); i++ )
{
@ -2242,6 +2271,7 @@ Class EBarrier : Inventory
if ( (ff.model.DamageAmount <= 0) || (ff.model.damageinterval <= 0) ) continue;
if ( ff.top.ZAtPoint(Owner.pos.xy) <= Owner.pos.z ) continue;
if ( ff.bottom.ZAtPoint(Owner.pos.xy) >= (Owner.pos.z+Owner.Height) ) continue;
if ( ff.model.flags&Sector.SECF_ENDLEVEL ) endlevelterrain = true;
damageterrain = true;
break;
}
@ -2254,7 +2284,10 @@ Class EBarrier : Inventory
if ( t && (t.DamageAmount > 0) && (t.DamageTimeMask > 0) )
damageterrain = true;
}
if ( damageterrain && (Owner.floorsector.flags&Sector.SECF_ENDLEVEL) ) endlevelterrain = true;
}
// do not auto-use for these
if ( endlevelterrain ) return;
if ( !damageterrain )
{
terrainwait = max(0,terrainwait-1);

View file

@ -15,7 +15,7 @@ Class PaletteLight : PointLight
}
private void UpdateLight()
{
int index = clamp(255-((255*ReactionTime)/abs(InitialReactionTime)),0,255);
int index = clamp(255-((255*ReactionTime)/InitialReactionTime),0,255);
args[LIGHT_RED] = pal[index].r;
args[LIGHT_GREEN] = pal[index].g;
args[LIGHT_BLUE] = pal[index].b;
@ -23,7 +23,6 @@ Class PaletteLight : PointLight
override void PostBeginPlay()
{
Super.PostBeginPlay();
InitialReactionTime = ReactionTime;
String palname = GetTag();
int sep = palname.IndexOf(",");
int palnum = 0;
@ -43,9 +42,10 @@ Class PaletteLight : PointLight
}
if ( ReactionTime < 0 )
{
ReactionTime = -ReactionTime;
ReactionTime = abs(ReactionTime)-1;
IsLooping = true;
}
InitialReactionTime = ReactionTime;
UpdateLight();
}
override void Tick()

View file

@ -2063,138 +2063,196 @@ Class SWWMUtility
}
// multi-weapon spawn stuff
static private Class<Inventory> PickPair( Class<Inventory> a, Class<Inventory> b, int weight = 1 )
static private Class<Weapon> PickPair( Class<Weapon> a, Class<Weapon> b )
{
if ( CheckNeedsItem(a) ) return a;
if ( CheckNeedsItem(b) ) return b;
return Random[Replacements](weight,0)?a:b;
if ( ItemExists(a,mapstart:true) ) return b;
return Random[Replacements](0,1)?a:b;
}
static private Class<Inventory> PickTrio( Class<Inventory> a, Class<Inventory> b, Class<Inventory> c, int weight1 = 1, int weight2 = 1 )
static private Class<Weapon> PickTrio( Class<Weapon> a, Class<Weapon> b, Class<Weapon> c )
{
if ( CheckNeedsItem(a) ) return a;
if ( CheckNeedsItem(b) ) return b;
if ( CheckNeedsItem(c) ) return c;
return Random[Replacements](weight1,0)?a:Random[Replacements](weight2,0)?b:c;
if ( ItemExists(a,mapstart:true) )
{
if ( ItemExists(b,mapstart:true) )
return c;
return Random[Replacements](0,1)?b:c;
}
if ( ItemExists(b,mapstart:true) )
{
if ( ItemExists(c,mapstart:true) )
return a;
return Random[Replacements](0,1)?a:c;
}
if ( ItemExists(c,mapstart:true) )
Random[Replacements](0,1)?a:b;
switch ( Random[Replacements](0,2) )
{
case 0:
return a;
case 1:
return b;
}
return c;
}
// boy, this one got complicated fast
static Class<Inventory> PickSWWMSlot1()
// melee weapons + extra slot 2 guns (50% chance)
static Class<Weapon> PickSWWMSlot1()
{
// so the player can recover it if they decided to drop it in a previous map, or they didn't start with it
if ( CheckNeedsItem('DeepImpact') ) return 'DeepImpact';
bool needsmelee = CheckNeedsItem('PusherWeapon')/*|CheckNeedsItem('ItamexHammer')|CheckNeedsItem('FistGun')*/;
bool needsgun = CheckNeedsItem('ExplodiumGun',true)/*|CheckNeedsItem('PlasmaBlast',true)*/;
if ( !needsmelee && !needsgun )
{
static const Class<Weapon> wpns[] =
{
'ExplodiumGun', 'PusherWeapon',
'PlasmaBlast', 'ItamexHammer',
'FistGun'
};
//return wpns[Random[Replacements](0,4)];
//return wpns[Random[Replacements](0,3)];
return wpns[Random[Replacements](0,1)];
}
if ( !needsmelee && needsgun )
{
//bool needsexplo = CheckNeedsItem('ExplodiumGun',true);
//bool needsblast = CheckNeedsItem('PlasmaBlast',true);
//if ( needsexplo && !needsblast ) return 'ExplodiumGun';
//if ( !needsexplo && needsblast ) return 'PlasmaBlast';
//return Random[Replacements](0,1)?'ExplodiumGun':'PlasmaBlast';
return 'ExplodiumGun';
}
if ( needsmelee && !needsgun )
{
//return PickTrio('PusherWeapon','ItamexHammer','FistGun');
//return PickPair('PusherWeapon','ItamexHammer');
return 'PusherWeapon';
}
if ( CheckNeedsItem('ExplodiumGun',true) && Random[Replacements](0,1) ) return 'ExplodiumGun';
//if ( CheckNeedsItem('PlasmaBlast',true) && Random[Replacements](0,1) ) return 'PlasmaBlast';
bool hasmelee = (!CheckNeedsItem('PusherWeapon')/*||!CheckNeedsItem('ItamexHammer')||!CheckNeedsItem('FistGun')*/);
bool gunexists = ItemExists('ExplodiumGun',worldonly:true)/*||ItemExists('PlasmaBlast',worldonly:true)*/;
// if the player already has a melee weapon, 50% chance to spawn either slot 2 weapon as long as one doesn't exist in the map already
if ( hasmelee && !gunexists && Random[Replacements](0,1) )
return PickSWWMSlot2();
//return PickTrio('PusherWeapon','ItamexHammer','FistGun');
//return PickPair('PusherWeapon','ItamexHammer');
return 'PusherWeapon';
}
static Class<Inventory> PickSWWMSlot2()
// pistol spawn, pretty simple
static Class<Weapon> PickSWWMSlot2()
{
//return PickPair('ExplodiumGun','PlasmaBlast');
return 'ExplodiumGun';
}
static Class<Inventory> PickSWWMSlot3()
// shotgun spawn
static Class<Weapon> PickSWWMSlot3()
{
//return PickPair('Spreadgun','PuntzerBeta');
return 'Spreadgun';
}
static Class<Inventory> PickSWWMSlot4()
// super shotgun spawn
static Class<Weapon> PickSWWMSlot4()
{
//return PickPair('Wallbuster','PuntzerGamma');
return 'Wallbuster';
}
static Class<Inventory> PickSWWMSlot5()
// chaingun spawn
static Class<Weapon> PickSWWMSlot5()
{
//return PickPair('Eviscerator','HeavyMahSheenGun');
return 'Eviscerator';
}
static Class<Inventory> PickSWWMSlot6()
// rocket launcher spawn
static Class<Weapon> PickSWWMSlot6()
{
//return PickTrip('Hellblazer','Quadravol','ModernSparkster');
//return PickTrio('Hellblazer','Quadravol','ModernSparkster');
//return PickPair('Hellblazer','Quadravol');
return 'Hellblazer';
}
static Class<Inventory> PickSWWMSlot7()
// first plasma rifle spawn
static Class<Weapon> PickSWWMSlot7()
{
//return PickPair('Sparkster','BlackfireIgniter');
return 'Sparkster';
}
static Class<Inventory> PickSWWMSlot8()
// second plasma rifle spawn
static Class<Weapon> PickSWWMSlot8()
{
//return PickPair('SilverBullet','EMPCarbine');
return 'SilverBullet';
}
static Class<Inventory> PickSWWMSlot9()
// first bfg spawn
static Class<Weapon> PickSWWMSlot9()
{
//return PickTrio('CandyGun','RayKhom','MisterRifle');
//return PickPair('CandyGun','RayKhom');
return 'CandyGun';
}
static Class<Inventory> PickSWWMSlot0()
// second bfg spawn (each weapon can only exist once)
static Class<Weapon> PickSWWMSlot0( bool fallback = true )
{
/*if ( !CheckNeedsItem('Ynykron') )
/*if ( ItemExists('Ynykron',mapstart:true) )
{
if ( !CheckNeedsItem('GrandLance') )
if ( ItemExists('GrandLance',mapstart:true) )
{
if ( !CheckNeedsItem('RafanKos') )
return PickSWWMSlot9();
if ( ItemExists('RafanKos',null,true) )
return fallback?PickSWWMSlot9():null;
return 'RafanKos';
}
if ( !CheckNeedsItem('RafanKos') )
if ( ItemExists('RafanKos',mapstart:true) )
return 'GrandLance';
return PickPair('GrandLance','RafanKos');
return Random[Replacements](0,1)?'GrandLance':'RafanKos';
}
return PickTrio('Ynykron','GrandLance','RafanKos');*/
/*if ( !CheckNeedsItem('Ynykron') )
if ( ItemExists('GrandLance',mapstart:true) )
{
if ( !CheckNeedsItem('GrandLance') )
return PickSWWMSlot9();
if ( ItemExists('RafanKos',mapstart:true) )
return 'Ynykron';
return Random[Replacements](0,1)?'Ynykron':'RafanKos';
}
if ( ItemExists('RafanKos',mapstart:truee) )
return Random[Replacements](0,1)?'Ynykron':'GrandLance';
switch ( Random[Replacements](0,2) )
{
case 0:
return 'Ynykron';
case 1:
return 'GrandLance';
}
return PickPair('Ynykron','GrandLance');*/
return !CheckNeedsItem('Ynykron')?'CandyGun':'Ynykron';
return 'RafanKos';*/
/*if ( ItemExists('Ynykron',mapstart:true) )
{
if ( ItemExists('GrandLance',mapstart:true) )
return fallback?PickSWWMSlot9():null;
return 'GrandLance';
}
if ( ItemExists('GrandLance',mapstart:true) )
return 'Ynykron';
return Random[Replacements](0,1)?'Ynykron':'GrandLance';*/
if ( ItemExists('Ynykron',mapstart:true) ) return fallback?PickSWWMSlot9():null;
return 'Ynykron';
}
static Class<Inventory> PickDoomSlot6()
// either plasma rifle spawn
static Class<Weapon> PickDoomSlot6()
{
return PickPair(PickSWWMSlot7(),PickSWWMSlot8(),2);
bool hasslot7 = (!CheckNeedsItem('Sparkster')/*||!CheckNeedsItem('BlackfireIgniter')*/);
bool hasslot8 = (!CheckNeedsItem('SilverBullet')/*||!CheckNeedsItem('EMPCarbine')*/);
// if the player already has a slot 7 weapon...
if ( hasslot7 )
{
// ... and also has a slot 8 weapon, 33% chance of a slot 8 spawn
// otherwise, guaranteed slot 8 spawn
if ( hasslot8 && Random[Replacements](0,2) ) return PickSWWMSlot7();
else return PickSWWMSlot8();
}
// otherwise, always spawn a slot 7 weapon first
return PickSWWMSlot7();
}
static Class<Inventory> PickDoomSlot7()
// either bfg spawn
static Class<Weapon> PickDoomSlot7()
{
return PickPair(PickSWWMSlot9(),PickSWWMSlot0(),2);
bool hasslot9 = (!CheckNeedsItem('CandyGun')/*||!CheckNeedsItem('RayKhom')||!CheckNeedsItem('MortalRifle')*/);
bool hasslot0 = (!CheckNeedsItem('Ynykron')/*||!CheckNeedsItem('GrandLance')||!CheckNeedsItem('RafanKos')*/);
let rep = PickSWWMSlot0(false);
// if the player already has a slot 9 weapon (and a slot 0 weapon can still spawn)...
if ( hasslot9 && rep )
{
// ... and also has a slot 0 weapon already, 33% chance of a slot 0 spawn
// otherwise, guaranteed slot 0 spawn
if ( hasslot0 && Random[Replacements](0,2) ) return PickSWWMSlot9();
else return rep;
}
// otherwise, always spawn a slot 9 weapon first
return PickSWWMSlot9();
}
static Class<Inventory> PickHereticSlot3() // also used for Doom 1
// either shotgun spawn (also used for Heretic)
static Class<Weapon> PickDoomSlot3()
{
if ( level.maptime ) return PickSWWMSlot3(); // always slot 3 after map start, prevents shotgun guys from dropping wallbusters
return PickPair(PickSWWMSlot3(),PickSWWMSlot4(),2);
// always slot 3 after map start, prevents shotgun guys from dropping wallbusters, which is weird af
if ( level.maptime ) return PickSWWMSlot3();
bool hasslot3 = (!CheckNeedsItem('Spreadgun')/*||!CheckNeedsItem('PuntzerBeta')*/);
bool hasslot4 = (!CheckNeedsItem('Wallbuster')/*||!CheckNeedsItem('PuntzerGamma')*/);
// if the player already has a slot 3 weapon...
if ( hasslot3 )
{
// ... and also has a slot 4 weapon, 33% chance of a slot 4 spawn
// otherwise, guaranteed slot 4 spawn
if ( hasslot4 && Random[Replacements](0,2) ) return PickSWWMSlot3();
return PickSWWMSlot4();
}
// otherwise, always spawn a slot 3 weapon first
return PickSWWMSlot3();
}
// what RandomSpawner does, basically (simplified for items)
static play void TransferItemProp( Actor a, Actor b, bool bundlehack = false )

View file

@ -41,7 +41,7 @@ Class SWWMWeapon : Weapon abstract
override void Touch( Actor toucher )
{
// cannot pick up swapweapon unless explicitly pressing use
// show prompt to swap weapon, and prevent normal pickup
SWWMWeapon sw;
if ( bSPECIAL && swwm_swapweapons && (sw = HasSwapWeapon(toucher)) )
{
@ -54,6 +54,7 @@ Class SWWMWeapon : Weapon abstract
}
return;
}
// explicit use-to pickup, function must be called from Used() virtual
if ( toucher.player && swwm_usetopickup && !bUsePickup )
return;
Super.Touch(toucher);
@ -388,10 +389,6 @@ Class SWWMWeapon : Weapon abstract
if ( swwm_enemydrops > 0 ) return false;
else if ( swwm_enemydrops == 0 )
{
// first, check if no others exist in the map, just in
// case this weapon drop MAY be needed
if ( !SWWMUtility.ItemExists(GetClass(),self) )
return false; // drop us
// drop our corresponding ammo
if ( !DropAmmoType ) return true;
let a = Spawn(DropAmmoType,pos,ALLOW_REPLACE);