Beta 4 Hotfix 1:

- Nerfed Fireblaster, damage was too high for its speed (30/60 → 10/20), to compensate for the dramatic alt projectile nerf, its embers now deal short radius splash damage.
- Nerfed Impaler altfire, no longer an instant "I win" weapon (damage interval raised from 5 to 15 tics, also beam becomes weaker at low charge, starting to drop from 100% at half-charge to 50% at zero charge).
- Fixed Impaler crash when shooter dies while firing beam.
- Updated the reload code of the SMP, I forgot about it.
- Increased the Detector range again, 1024 is more reasonable.
- Fixed Minigun altfire not triggering if player was holding primary fire.
- Removed pistols from Super Shotgun replacement pool.
- Increased spawn chance of Flamethrower, since it almost never appears in practice.
- Capped maximum Flamethrower damage (75 → 20), this was way too high and made the weapon too overpowered.
This commit is contained in:
Marisa the Magician 2019-09-29 22:23:45 +02:00
commit 5db3f32274
7 changed files with 58 additions and 27 deletions

View file

@ -53,7 +53,7 @@ Class UFireball : Actor
Default Default
{ {
DamageType 'Fire'; DamageType 'Fire';
DamageFunction 30; DamageFunction 10;
Radius 4; Radius 4;
Height 4; Height 4;
Speed 15; Speed 15;
@ -121,7 +121,12 @@ Class UFireball : Actor
{ {
A_SetRenderStyle(1.,STYLE_Add); A_SetRenderStyle(1.,STYLE_Add);
A_NoGravity(); A_NoGravity();
if ( !bAMBUSH ) if ( bAMBUSH )
{
A_Explode(GetMissileDamage(0,0),20);
UTMainHandler.DoBlast(self,20,3000);
}
else
{ {
A_PlaySound("flamegun/exp",CHAN_VOICE,pitch:1.2); A_PlaySound("flamegun/exp",CHAN_VOICE,pitch:1.2);
Spawn("UFireLight",pos); Spawn("UFireLight",pos);
@ -177,7 +182,7 @@ Class UFireball2 : UFireball
{ {
Radius 8; Radius 8;
Height 8; Height 8;
DamageFunction 60; DamageFunction 20;
Speed 5; Speed 5;
UFireball.SpreadFactor 0.35; UFireball.SpreadFactor 0.35;
UFireball.NumSmokes 2; UFireball.NumSmokes 2;
@ -388,7 +393,16 @@ Class FlameGun : UnrealWeapon
} }
FGNF G 0 A_ClearRefire(); FGNF G 0 A_ClearRefire();
FGNF GHIJ 2; FGNF GHIJ 2;
FGNT A 0 A_PlaySound("flamegun/end",CHAN_6,Dampener.Active(self)?.1:1.); FGNT A 0
{
if ( invoker.CheckAmmo(0,false,true) && (waterlevel < 2) )
A_Refire("Fire");
}
FGNT A 0
{
A_PlaySound("flamegun/end",CHAN_6,Dampener.Active(self)?.1:1.);
A_ClearRefire();
}
FGNT ABCDEFGHIJKLM 2; FGNT ABCDEFGHIJKLM 2;
Goto Idle; Goto Idle;
Refire: Refire:

View file

@ -220,6 +220,11 @@ Class ImpalerBoltHit : Actor
+NOTELEPORT; +NOTELEPORT;
Scale 0.3; Scale 0.3;
} }
override void Tick()
{
Super.Tick();
if ( !master ) Destroy();
}
States States
{ {
Spawn: Spawn:
@ -264,16 +269,16 @@ Class ImpalerBolt : Actor
t.Trace(pos,cursector,x,beamsize,0); t.Trace(pos,cursector,x,beamsize,0);
for ( int i=0; i<t.HitList.Size(); i++ ) for ( int i=0; i<t.HitList.Size(); i++ )
{ {
if ( !(GetAge()%5) ) if ( !(GetAge()%15) )
{ {
UTMainHandler.DoKnockback(t.hitlist[i].hitactor,t.hitlist[i].x,500*specialf1**2); UTMainHandler.DoKnockback(t.hitlist[i].hitactor,t.hitlist[i].x,500*specialf1**2);
t.hitlist[i].hitactor.DamageMobj(self,target,int(10*specialf1**1.5),'Impaler',DMG_THRUSTLESS); t.hitlist[i].hitactor.DamageMobj(self,target,int(max(5,10*specialf1**1.5)),'Impaler',DMG_THRUSTLESS);
} }
if ( start.Hitlist.Find(t.HitList[i].HitActor) == start.HitList.Size() ) if ( start && (start.Hitlist.Find(t.HitList[i].HitActor) == start.HitList.Size()) )
start.Hitlist.Push(t.HitList[i].HitActor); start.Hitlist.Push(t.HitList[i].HitActor);
} }
// seeking // seeking
double closest = 500*specialf1; double closest = max(200,500*specialf1);
if ( tracer ) if ( tracer )
{ {
double tdist = Distance3D(tracer); double tdist = Distance3D(tracer);
@ -284,7 +289,7 @@ Class ImpalerBolt : Actor
while ( bt.Next() ) while ( bt.Next() )
{ {
let a = bt.Thing; let a = bt.Thing;
if ( !a || !a.bSHOOTABLE || !a.bISMONSTER || (a.Health <= 0) || target.IsFriend(a) || !CheckSight(a) || (start.Hitlist.Find(a) < start.HitList.Size()) ) continue; if ( !a || !a.bSHOOTABLE || !a.bISMONSTER || (a.Health <= 0) || target.IsFriend(a) || !CheckSight(a) || (start && (start.Hitlist.Find(a) < start.HitList.Size())) ) continue;
Vector3 dirto = level.Vec3Diff(pos,a.Vec3Offset(0,0,a.height/2)); Vector3 dirto = level.Vec3Diff(pos,a.Vec3Offset(0,0,a.height/2));
double dist = dirto.length(); double dist = dirto.length();
dirto /= dist; dirto /= dist;
@ -341,7 +346,7 @@ Class ImpalerBolt : Actor
s.scale *= .4; s.scale *= .4;
s.vel = (FRandom[Impaler](-1,1),FRandom[Impaler](-1,1),FRandom[Impaler](-1,1)).unit()*FRandom[Impaler](.2,.8); s.vel = (FRandom[Impaler](-1,1),FRandom[Impaler](-1,1),FRandom[Impaler](-1,1)).unit()*FRandom[Impaler](.2,.8);
} }
if ( (special1 < int(10*specialf1)) && (special2 < int(40*specialf1**.5)) && (start.hitlist.Size() < int(4*specialf1)) && (waterlevel <= 0) ) if ( (special1 < int(max(5,10*specialf1))) && (special2 < int(max(20,40*specialf1**.5))) && (start && (start.hitlist.Size() < int(max(4,4*specialf1)))) && (waterlevel <= 0) )
{ {
if ( !next ) if ( !next )
{ {
@ -353,7 +358,7 @@ Class ImpalerBolt : Actor
next.tracer = tracer; next.tracer = tracer;
next.special1 = special1+1; next.special1 = special1+1;
next.special2 = special2+1; next.special2 = special2+1;
next.specialf1 = max(1.,specialf1); next.specialf1 = specialf1;
next.oldx = dir; next.oldx = dir;
next.bHITOWNER = !sting_impself; next.bHITOWNER = !sting_impself;
} }
@ -361,20 +366,28 @@ Class ImpalerBolt : Actor
{ {
next.tracer = tracer; next.tracer = tracer;
next.special1 = special1+1; next.special1 = special1+1;
next.specialf1 = max(1.,specialf1); next.specialf1 = specialf1;
next.bHITOWNER = !sting_impself; next.bHITOWNER = !sting_impself;
next.UpdateBeam(self,t.Results.HitPos+normal,dir); next.UpdateBeam(self,t.Results.HitPos+normal,dir);
} }
if ( t.Results.HitType != TRACE_HitNone ) if ( t.Results.HitType != TRACE_HitNone )
{ {
if ( !weffect ) weffect = Spawn("ImpalerBoltHit",t.Results.HitPos+normal*4); if ( !weffect )
{
weffect = Spawn("ImpalerBoltHit",t.Results.HitPos+normal*4);
weffect.master = self;
}
weffect.SetOrigin(t.Results.HitPos+normal*4,true); weffect.SetOrigin(t.Results.HitPos+normal*4,true);
weffect.sprite = weffect.GetSpriteIndex('IHIT'); weffect.sprite = weffect.GetSpriteIndex('IHIT');
} }
else if ( weffect ) weffect.Destroy(); else if ( weffect ) weffect.Destroy();
return; return;
} }
if ( !weffect ) weffect = Spawn("ImpalerBoltHit",t.Results.HitPos+normal*4); if ( !weffect )
{
weffect = Spawn("ImpalerBoltHit",t.Results.HitPos+normal*4);
weffect.master = self;
}
if ( t.Results.HitType != TRACE_HitNone ) weffect.sprite = weffect.GetSpriteIndex('IHIT'); if ( t.Results.HitType != TRACE_HitNone ) weffect.sprite = weffect.GetSpriteIndex('IHIT');
else weffect.sprite = weffect.GetSpriteIndex('ICAP'); else weffect.sprite = weffect.GetSpriteIndex('ICAP');
weffect.SetOrigin(t.Results.HitPos+normal*4,true); weffect.SetOrigin(t.Results.HitPos+normal*4,true);
@ -738,7 +751,10 @@ Class Impaler : UnrealWeapon
if ( invoker.ClipCount <= 0 ) return; if ( invoker.ClipCount <= 0 ) return;
double mul = Amplifier.GetMult(self,10); double mul = Amplifier.GetMult(self,10);
if ( invoker.beam ) if ( invoker.beam )
{
invoker.beam.specialf1 = mul; invoker.beam.specialf1 = mul;
invoker.beam.specialf1 *= .5+clamp(invoker.clipcount/double(invoker.default.clipcount),.0,.5);
}
invoker.clipcount = max(0,invoker.clipcount-int(mul)); invoker.clipcount = max(0,invoker.clipcount-int(mul));
} }
invoker.FireEffect(); invoker.FireEffect();
@ -897,7 +913,7 @@ Class Impaler : UnrealWeapon
{ {
let weap = Weapon(invoker); let weap = Weapon(invoker);
int flags = 0; int flags = 0;
if ( weap.Ammo1.Amount > 0 ) flags |= WRF_ALLOWRELOAD; if ( (weap.Ammo1.Amount > 0) || (invoker.ClipCount > 0) ) flags |= WRF_ALLOWRELOAD;
if ( invoker.HasGem && ((invoker.ClipCount <= 0) || (waterlevel >= 2)) ) flags |= WRF_NOSECONDARY; if ( invoker.HasGem && ((invoker.ClipCount <= 0) || (waterlevel >= 2)) ) flags |= WRF_NOSECONDARY;
A_WeaponReady(flags); A_WeaponReady(flags);
} }

View file

@ -77,7 +77,7 @@ Class OnFire : Thinker
{ {
cnt = 10; cnt = 10;
if ( victim.bSHOOTABLE && (victim.Health > 0) && (amount > 0) ) if ( victim.bSHOOTABLE && (victim.Health > 0) && (amount > 0) )
victim.DamageMobj(instigator.FindInventory("UFlamethrower"),instigator,max(1,int(amount*(victim.bBOSS?0.05:0.15))),'Fire',DMG_THRUSTLESS); victim.DamageMobj(instigator.FindInventory("UFlamethrower"),instigator,clamp(int(amount*(victim.bBOSS?0.05:0.15)),1,20),'Fire',DMG_THRUSTLESS);
if ( !victim ) if ( !victim )
{ {
Destroy(); Destroy();

View file

@ -65,12 +65,13 @@ Class OLSMP : UnrealWeapon
{ {
int ClipCount; int ClipCount;
double AltAccuracy; double AltAccuracy;
bool ClipOut;
property ClipCount : ClipCount; property ClipCount : ClipCount;
override int, int, bool, bool GetClipAmount() override int, int, bool, bool GetClipAmount()
{ {
return ClipCount, -1, (ClipCount<35), false; return ClipOut?-1:ClipCount, -1, (ClipCount<35), false;
} }
override bool TryPickup( in out Actor toucher ) override bool TryPickup( in out Actor toucher )
{ {
@ -323,8 +324,7 @@ Class OLSMP : UnrealWeapon
AUTR A 0 A_JumpIf(invoker.clipcount>=min(invoker.default.clipcount,invoker.Ammo1.Amount),"Idle"); AUTR A 0 A_JumpIf(invoker.clipcount>=min(invoker.default.clipcount,invoker.Ammo1.Amount),"Idle");
AUTR A 0 AUTR A 0
{ {
invoker.special1 = min(invoker.default.clipcount,invoker.Ammo1.Amount)-invoker.clipcount; invoker.clipout = true;
invoker.clipcount = -1;
A_Overlay(-9999,null); A_Overlay(-9999,null);
A_WeaponOffset(0,32); // fix sudden psprite lowering A_WeaponOffset(0,32); // fix sudden psprite lowering
A_PlaySound("automag/click",CHAN_WEAPON,!Dampener.Active(self)?1.:.1,pitch:0.8); A_PlaySound("automag/click",CHAN_WEAPON,!Dampener.Active(self)?1.:.1,pitch:0.8);
@ -333,9 +333,10 @@ Class OLSMP : UnrealWeapon
AUTD ABCD 1; AUTD ABCD 1;
AUTD E 30 AUTD E 30
{ {
invoker.clipout = false;
invoker.clipcount = Min(invoker.default.clipcount,invoker.Ammo1.Amount); let aadd = min(invoker.Ammo1.Amount,invoker.default.clipcount-invoker.clipcount);
invoker.Ammo1.Amount -= invoker.special1; invoker.clipcount += aadd;
invoker.Ammo1.Amount -= aadd;
A_PlaySound("automag/reload",CHAN_WEAPON,!Dampener.Active(self)?1.:.1,pitch:0.8); A_PlaySound("automag/reload",CHAN_WEAPON,!Dampener.Active(self)?1.:.1,pitch:0.8);
if ( self is 'UTPlayer' ) if ( self is 'UTPlayer' )
UTPlayer(self).PlayReloading(); UTPlayer(self).PlayReloading();

View file

@ -202,7 +202,7 @@ Class UMinigun : UnrealWeapon
A_PlaySound("umini/fire",CHAN_WEAPON,Dampener.Active(self)?.1:1.,true); A_PlaySound("umini/fire",CHAN_WEAPON,Dampener.Active(self)?.1:1.,true);
} }
MGNF ABCDEFGHIJKLMNO 1 A_FireBullet(false); MGNF ABCDEFGHIJKLMNO 1 A_FireBullet(false);
MGNF A 0 A_JumpIf(invoker.bAltFire,1); MGNF A 0 A_JumpIf(player.cmd.buttons&BT_ALTATTACK,1);
Goto Hold+1; Goto Hold+1;
AltHold: AltHold:
MGNA A 0 MGNA A 0

View file

@ -919,7 +919,7 @@ Class UnrealMainHandler : EventHandler
} }
else if ( (e.Replacee == 'Shotgun') || (e.Replacee == 'SuperShotgun') || (e.Replacee == 'Crossbow') ) else if ( (e.Replacee == 'Shotgun') || (e.Replacee == 'SuperShotgun') || (e.Replacee == 'Crossbow') )
{ {
if ( !Random[Replacements](0,3) ) if ( !Random[Replacements](0,3) && (e.Replacee != 'SuperShotgun') )
{ {
if ( !Random[Replacements](0,2) ) e.Replacement = 'Betamag'; if ( !Random[Replacements](0,2) ) e.Replacement = 'Betamag';
else e.Replacement = 'Automag'; else e.Replacement = 'Automag';
@ -946,7 +946,7 @@ Class UnrealMainHandler : EventHandler
{ {
if ( !Random[Replacements](0,3) ) if ( !Random[Replacements](0,3) )
{ {
if ( !Random[Replacements](0,2) ) e.Replacement = 'UFlamethrower'; if ( Random[Replacements](0,1) ) e.Replacement = 'UFlamethrower';
else e.Replacement = 'FlameGun'; else e.Replacement = 'FlameGun';
} }
else if ( Random[Replacements](0,1) ) e.Replacement = 'UFlakCannon'; else if ( Random[Replacements](0,1) ) e.Replacement = 'UFlakCannon';

View file

@ -360,7 +360,7 @@ Class MotionDetector : UnrealInventory
for ( int i=0; i<nearscan.Size(); i++ ) for ( int i=0; i<nearscan.Size(); i++ )
{ {
Vector2 absofs = level.Vec2Diff(Owner.pos.xy,nearscan[i].pos.xy); Vector2 absofs = level.Vec2Diff(Owner.pos.xy,nearscan[i].pos.xy);
absofs *= (96./512.); absofs *= (96./1024.);
double ang = Owner.angle-90; double ang = Owner.angle-90;
Vector2 relofs = (absofs.x*cos(ang)+absofs.y*sin(ang),-absofs.y*cos(ang)+absofs.x*sin(ang)); Vector2 relofs = (absofs.x*cos(ang)+absofs.y*sin(ang),-absofs.y*cos(ang)+absofs.x*sin(ang));
if ( max(abs(relofs.x),abs(relofs.y)) > 48. ) continue; if ( max(abs(relofs.x),abs(relofs.y)) > 48. ) continue;
@ -389,7 +389,7 @@ Class MotionDetector : UnrealInventory
else if ( !bActive && tracer ) tracer.Destroy(); else if ( !bActive && tracer ) tracer.Destroy();
if ( !bActive ) return; if ( !bActive ) return;
nearscan.Clear(); nearscan.Clear();
let bi = BlockThingsIterator.Create(Owner,512); let bi = BlockThingsIterator.Create(Owner,1024);
while ( bi.Next() ) while ( bi.Next() )
{ {
if ( !bi.Thing || (bi.Thing == Owner) || !bi.Thing.bISMONSTER || bi.Thing.Health <= 0 ) continue; if ( !bi.Thing || (bi.Thing == Owner) || !bi.Thing.bISMONSTER || bi.Thing.Health <= 0 ) continue;