Implement damage accumulator for flak chunks (auto-gibs at specific threshold).

Rebalances to ammo amounts and spawns.
Rebalances to ripper speed and pulsegun beam damage.
More tweaks to UT movement.
This commit is contained in:
Marisa the Magician 2018-09-15 12:46:31 +02:00
commit cdfea51f31
5 changed files with 97 additions and 28 deletions

View file

@ -105,6 +105,53 @@ Class ChunkTrail : Actor
}
}
Class FlakAccumulator : Thinker
{
Actor victim;
int amount;
int cnt;
override void Tick()
{
Super.Tick();
cnt++;
if ( cnt < 5 ) return;
Destroy();
}
static void Accumulate( Actor victim, int amount )
{
let ti = ThinkerIterator.Create("FlakAccumulator",STAT_USER);
FlakAccumulator a, match = null;
while ( a = FlakAccumulator(ti.Next()) )
{
if ( a.victim != victim ) continue;
match = a;
break;
}
if ( !match )
{
match = new("FlakAccumulator");
match.ChangeStatNum(STAT_USER);
match.victim = victim;
}
match.cnt = 0;
match.amount += amount;
}
static int GetAmount( Actor victim )
{
let ti = ThinkerIterator.Create("FlakAccumulator",STAT_USER);
FlakAccumulator a;
while ( a = FlakAccumulator(ti.Next()) )
{
if ( a.victim != victim ) continue;
return a.amount;
}
return 0;
}
}
Class FlakChunk : Actor
{
ChunkTrail trail;
@ -208,6 +255,10 @@ Class FlakChunk : Actor
override int DoSpecialDamage( Actor target, int damage, Name damagetype )
{
if ( vel.length() <= 5.0 ) return 0;
FlakAccumulator.Accumulate(target,damage);
int gibhealth = (target.GibHealth==int.min)?-target.SpawnHealth():target.GibHealth;
int calcdmg = FlakAccumulator.GetAmount(target);
if ( target.Health-calcdmg <= (gibhealth/2) ) bEXTREMEDEATH = true;
if ( !target.bNOBLOOD )
{
target.SpawnBlood(pos,AngleTo(target),damage);

View file

@ -6,7 +6,7 @@ Class PulseAmmo : Ammo
Inventory.PickupMessage "You picked up a Pulse Cell.";
Inventory.Amount 25;
Inventory.MaxAmount 200;
Ammo.BackpackAmount 50;
Ammo.BackpackAmount 40;
Ammo.BackpackMaxAmount 400;
Ammo.DropAmount 10;
}
@ -373,12 +373,12 @@ Class PulseBolt : Actor
if ( !damagedactor )
{
accdamage = min(0.5*(level.time-lasthit),0.1);
t.Results.HitActor.DamageMobj(self,target,int(Random[Pulse](70,90)*accdamage),'zapped',DMG_USEANGLE,atan2(x.y,x.x));
t.Results.HitActor.DamageMobj(self,target,int(Random[Pulse](80,100)*accdamage),'zapped',DMG_USEANGLE,atan2(x.y,x.x));
accdamage = 0;
}
else if ( t.Results.HitActor != damagedactor )
{
t.Results.HitActor.DamageMobj(self,target,int(Random[Pulse](70,90)*accdamage),'zapped',DMG_USEANGLE,atan2(x.y,x.x));
t.Results.HitActor.DamageMobj(self,target,int(Random[Pulse](80,100)*accdamage),'zapped',DMG_USEANGLE,atan2(x.y,x.x));
accdamage = 0;
}
lasthit = level.time;
@ -386,7 +386,7 @@ Class PulseBolt : Actor
accdamage += 1./TICRATE;
if ( accdamage > 0.17 )
{
t.Results.HitActor.DamageMobj(self,target,int(Random[Pulse](70,90)*accdamage),'zapped',DMG_USEANGLE,atan2(x.y,x.x));
t.Results.HitActor.DamageMobj(self,target,int(Random[Pulse](80,100)*accdamage),'zapped',DMG_USEANGLE,atan2(x.y,x.x));
accdamage = 0;
}
}

View file

@ -4,11 +4,11 @@ Class RipperAmmo : Ammo
{
Tag "Razor Blades";
Inventory.PickupMessage "You picked up Razor Blades.";
Inventory.Amount 25;
Inventory.MaxAmount 75;
Ammo.BackpackAmount 50;
Ammo.BackpackMaxAmount 150;
Ammo.DropAmount 10;
Inventory.Amount 10;
Inventory.MaxAmount 40;
Ammo.BackpackAmount 20;
Ammo.BackpackMaxAmount 80;
Ammo.DropAmount 5;
}
States
{
@ -58,7 +58,7 @@ Class Razor2 : Actor
Radius 2;
Height 2;
Speed 27;
DamageFunction (Random[Ripper](25,35)*((DamageType=='Decapitated')?3.5:1.0));
DamageFunction (Random[Ripper](20,25)*((DamageType=='Decapitated')?3:1.0));
DamageType 'Shredded';
Obituary "%k ripped a chunk of meat out of %o with the Ripper.";
BounceType "Doom";
@ -259,7 +259,7 @@ Class Ripper2 : UTWeapon
Weapon.AmmoUse 1;
Weapon.AmmoType2 "RipperAmmo";
Weapon.AmmoUse2 1;
Weapon.AmmoGive 15;
Weapon.AmmoGive 10;
UTWeapon.DropAmmo 5;
}
action void A_RazorFire( bool alt = false )
@ -308,11 +308,11 @@ Class Ripper2 : UTWeapon
Loop;
Fire:
RZRF A 0 A_RazorFire();
RZRF ABDEGHIJKLMNO 1;
RZRF ABCDEFGHIJKLMNO 1;
Goto Idle;
AltFire:
RZRF A 0 A_RazorFire(true);
RZRF ABDEG 3;
RZRF ABCDEFG 3;
RZRF HIJKLMNO 1;
Goto Idle;
Deselect:

View file

@ -379,7 +379,7 @@ Class ShockBeam : Actor
t.Results.HitLine.RemoteActivate(target,t.Results.Side,SPAC_Impact,pos);
// calculate normal
HitNormal = (-t.Results.HitLine.delta.y,t.Results.HitLine.delta.x,0).unit();
if ( t.Results.Side == 1 ) HitNormal *= -1;
if ( t.Results.Side == 0 ) HitNormal *= -1;
}
else if ( t.Results.HitType == TRACE_HitFloor )
HitNormal = t.Results.HitSector.floorplane.Normal;

View file

@ -12,7 +12,7 @@ Class UTPlayer : DoomPlayer
int last_jump_held;
const groundspeed = 400.;
const accelrate = 2048.;
const baseaccelrate = 2048.;
const walkfactor = 0.3;
const utaircontrol = 0.35;
const groundspeed_doomish = 600.;
@ -239,7 +239,7 @@ Class UTPlayer : DoomPlayer
else Angle += cmd.yaw*(360./65536.);
player.onground = (pos.z <= floorz) || bOnMobj || bMBFBouncer || (player.cheats & CF_NOCLIP2);
if ( player.onground ) lastgroundtic = gametic;
if ( (abs(lastgroundtic-gametic) < 4) && (player.jumptics == 0) ) player.onground = true;
if ( (abs(pos.z-floorz) <= maxdropoffheight) && (player.jumptics == 0) ) player.onground = true;
double friction = FrictionToUnreal();
double fs = TweakSpeeds(1.0,0.0);
if ( !doomspeed.GetBool() )
@ -249,6 +249,7 @@ Class UTPlayer : DoomPlayer
else fs *= max(abs(cmd.forwardmove/12800.),abs(cmd.sidemove/10240.));
if ( CanCrouch() && (player.crouchfactor != -1) ) fs *= player.crouchfactor;
acceleration = rotatevector((cmd.forwardmove,-cmd.sidemove),angle);
double accelrate = baseaccelrate*fs;
Vector2 dodge = (0,0);
int fm = cmd.forwardmove;
int sm = cmd.sidemove;
@ -301,6 +302,7 @@ Class UTPlayer : DoomPlayer
// Hook in Unreal physics
Vector2 dir = (0,0);
if ( vel.xy.length() > double.epsilon ) dir = vel.xy.unit();
double doomfriction = clamp(GetFriction()/ORIG_FRICTION,0.0,1.0);
if ( acceleration.length() <= double.epsilon )
{
Vector2 oldvel = vel.xy;
@ -315,10 +317,9 @@ Class UTPlayer : DoomPlayer
}
vel.xy = vel.xy + acceleration/TICRATE;
double maxvel;
if ( doomspeed.GetBool() ) maxvel = (groundspeed_doomish*fs)/TICRATE;
else maxvel = (groundspeed*fs)/TICRATE;
double doomfriction = clamp(GetFriction()/ORIG_FRICTION,0.0,1.0);
maxvel *= doomfriction;
if ( doomspeed.GetBool() ) maxvel = groundspeed_doomish/TICRATE;
else maxvel = groundspeed/TICRATE;
maxvel *= fs*doomfriction;
if ( vel.xy.length() > maxvel ) vel.xy = vel.xy.unit()*maxvel;
if ( !(player.cheats & CF_PREDICTING) )
{
@ -356,6 +357,7 @@ Class UTPlayer : DoomPlayer
else vel.xy = vel.xy+acceleration/TICRATE;
if ( vel.length() > terminalvelocity/TICRATE ) vel = vel.unit()*(terminalvelocity/TICRATE);
player.vel *= 0;
player.jumptics = -2;
}
else
{
@ -1206,12 +1208,13 @@ Class UTMainHandler : StaticEventHandler
else if ( e.Replacee == 'Pistol' ) e.Replacement = 'Enforcer';
else if ( (e.Replacee == 'Shotgun') || (e.Replacee == 'SuperShotgun') )
{
if ( Random[Replacements](0,1) ) e.Replacement = 'BioRifle';
if ( !Random[Replacements](0,3) ) e.Replacement = 'Enforcer';
else if ( Random[Replacements](0,1) ) e.Replacement = 'BioRifle';
else e.Replacement = 'ShockRifle';
}
else if ( e.Replacee == 'Chaingun' )
{
if ( Random[Replacements](0,1) ) e.Replacement = 'PulseGun';
if ( Random[Replacements](0,2) ) e.Replacement = 'PulseGun';
else e.Replacement = 'Ripper2';
}
else if ( e.Replacee == 'RocketLauncher' )
@ -1225,15 +1228,21 @@ Class UTMainHandler : StaticEventHandler
else e.Replacement = 'SniperRifle';
}
else if ( e.Replacee == 'BFG9000' ) e.Replacement = 'WarheadLauncher';
else if ( e.Replacee == 'Clip' ) e.Replacement = 'EClip';
else if ( e.Replacee == 'Clip' )
{
if ( Random[Replacements](0,1) ) e.Replacement = 'RifleAmmo2';
else e.Replacement = 'EClip';
}
else if ( e.Replacee == 'ClipBox' )
{
if ( Random[Replacements](0,1) ) e.Replacement = 'PulseAmmo';
if ( !Random[Replacements](0,2) ) e.Replacement = 'EClip';
else if ( Random[Replacements](0,2) ) e.Replacement = 'PulseAmmo';
else e.Replacement = 'RipperAmmo';
}
else if ( e.Replacee == 'Shell' )
{
if ( Random[Replacements](0,1) ) e.Replacement = 'BioAmmo2';
if ( !Random[Replacements](0,2) ) e.Replacement = 'EClip';
else if ( Random[Replacements](0,1) ) e.Replacement = 'BioAmmo2';
else e.Replacement = 'ShockAmmo2';
}
else if ( e.Replacee == 'ShellBox' )
@ -1243,8 +1252,16 @@ Class UTMainHandler : StaticEventHandler
}
else if ( e.Replacee == 'RocketAmmo' )
{
if ( Random[Replacements](0,1) ) e.Replacement = 'FlakAmmo2';
else e.Replacement = 'UTRocketAmmo2';
if ( Random[Replacements](0,1) )
{
if ( !Random[Replacements](0,3) ) e.Replacement = 'FlakAmmo';
else e.Replacement = 'FlakAmmo2';
}
else
{
if ( !Random[Replacements](0,3) ) e.Replacement = 'UTRocketAmmo';
else e.Replacement = 'UTRocketAmmo2';
}
}
else if ( e.Replacee == 'RocketBox' )
{
@ -1254,11 +1271,12 @@ Class UTMainHandler : StaticEventHandler
else if ( e.Replacee == 'Cell' )
{
if ( Random[Replacements](0,1) ) e.Replacement = 'EClip';
else if ( !Random[Replacements](0,3) ) e.Replacement = 'RifleAmmo';
else e.Replacement = 'RifleAmmo2';
}
else if ( e.Replacee == 'CellPack' )
{
if ( !Random[Replacements](0,5) ) e.Replacement = 'WarheadAmmo';
if ( !Random[Replacements](0,6) ) e.Replacement = 'WarheadAmmo';
else if ( Random[Replacements](0,1) ) e.Replacement = 'MiniAmmo';
else e.Replacement = 'RifleAmmo';
}