Various improvements, fixes and rebalances that I'm too tired to list through.

This commit is contained in:
Marisa the Magician 2018-08-18 20:42:28 +02:00
commit a99c38fd75
13 changed files with 260 additions and 74 deletions

Binary file not shown.

View file

@ -26,10 +26,10 @@ Model "FlakSlug"
Path "models"
Model 0 "flakslugm_d.3d"
Skin 0 "jflakslugel1.png"
Scale 0.048 0.048 0.04
Scale 0.048 0.04 0.04
AngleOffset 180
PitchOffset 90
PITCHFROMMOMENTUM
USEACTORPITCH
FrameIndex FSLG A 0 0
}

View file

@ -110,6 +110,7 @@ misc/chat2 newbeep
misc/teleport resp2a
misc/ut_keg utsuperh
misc/ut_heal uthealth
$volume misc/ut_heal 0.7 // a bit too loud otherwise
misc/ut_shard shardpck
misc/ut_armor armorut
belt/pickup beltsnd

View file

@ -27,6 +27,7 @@ Class UTRocketAmmo2 : UTRocketAmmo
Inventory.PickupMessage "You picked up a Single Rocket.";
Inventory.Amount 1;
Ammo.DropAmount 1;
+INVENTORY.IGNORESKILL;
}
States
{
@ -102,13 +103,15 @@ Class RocketExplLight : SlugLight
Class UTRocket : Actor
{
Vector3 InitialDir, Acceleration;
int ticcnt;
Default
{
Obituary "%o was smacked down by %k's Rocket Launcher.";
DamageType 'RocketDeath';
Radius 2;
Height 2;
Speed 18;
Speed 20;
PROJECTILE;
+SKYEXPLODE;
+EXPLODEONWATER;
@ -122,6 +125,8 @@ Class UTRocket : Actor
let l = Spawn("UTRocketTrail",pos);
l.target = self;
A_PlaySound("utrl/fly",CHAN_VOICE,1.0,true,2.5);
if ( tracer ) vel *= 0.9;
Acceleration = vel.unit()*50;
}
action void A_RocketExplode( int dmg, int rad )
{
@ -159,17 +164,38 @@ Class UTRocket : Actor
s.scale *= FRandom[Eightball](0.9,2.7);
}
}
action void A_RocketSeek()
{
if ( invoker.InitialDir.length() < double.epsilon ) invoker.InitialDir = vel.unit();
if ( tracer && (tracer != target) )
{
Vector3 SeekingDir = level.Vec3Diff(pos,tracer.Vec3Offset(0,0,tracer.height/2)).unit();
if ( SeekingDir dot invoker.InitialDir > 0 )
{
double MagnitudeVel = Vel.length();
SeekingDir = (SeekingDir*0.5*MagnitudeVel+Vel).unit();
Vel = MagnitudeVel * SeekingDir;
invoker.Acceleration = 25 * SeekingDir;
}
}
}
States
{
Spawn:
RCKT B 1
{
A_SetRoll(roll+30,SPF_INTERPOLATE);
if ( invoker.ticcnt++ > 3 )
{
invoker.ticcnt = 0;
A_RocketSeek();
}
vel += invoker.Acceleration/TICRATE;
if ( vel.length() > 45. ) vel = Vel.unit()*45.;
Vector3 dir = vel.unit();
if ( waterlevel <= 0 ) vel = dir*min(vel.length()+1,32);
A_SetAngle(atan2(dir.y,dir.x),SPF_INTERPOLATE);
A_SetPitch(asin(-dir.z),SPF_INTERPOLATE);
if ( tracer ) A_SeekerMissile(0,2,SMF_PRECISE);
for ( int i=0; i<3; i++ )
{
let s = Spawn("UTSmoke",pos);

View file

@ -29,13 +29,17 @@ Class FlakAmmo : Ammo
Default
{
Tag "Flak Shells";
Inventory.PickupMessage "You picked up 10 Flak Shells.";
Inventory.PickupMessage "You picked up %d Flak Shells.";
Inventory.Amount 10;
Inventory.MaxAmount 50;
Ammo.BackpackAmount 20;
Ammo.BackpackMaxAmount 100;
Ammo.DropAmount 5;
}
override String PickupMessage()
{
return String.Format(pickupmsg,Amount);
}
States
{
Spawn:
@ -52,6 +56,7 @@ Class FlakAmmo2 : FlakAmmo
Inventory.PickupMessage "You picked up a Flak Shell.";
Inventory.Amount 1;
Ammo.DropAmount 1;
+INVENTORY.IGNORESKILL;
}
States
{
@ -143,10 +148,10 @@ Class FlakChunk : Actor
DamageType 'Shredded';
BounceType "Doom";
BounceFactor 0.8;
WallBounceFactor 0.8;
PROJECTILE;
+USEBOUNCESTATE;
-BOUNCEAUTOOFF;
+BOUNCEAUTOOFFFLOORONLY;
+CANBOUNCEWATER;
+SKYEXPLODE;
Scale 0.3;
@ -224,9 +229,10 @@ Class FlakChunk : Actor
invoker.rollvel = FRandom[Flak](50,100)*RandomPick[Flak](-1,1)*(vel.length()/speed);
invoker.pitchvel = FRandom[Flak](50,100)*RandomPick[Flak](-1,1)*(vel.length()/speed);
invoker.yawvel = FRandom[Flak](50,100)*RandomPick[Flak](-1,1)*(vel.length()/speed);
vel = (vel.unit()+(FRandom[Flak](-0.4,0.4),FRandom[Flak](-0.4,0.4),FRandom[Flak](-0.4,0.4))).unit()*vel.length();
vel = (vel.unit()+(FRandom[Flak](-0.2,0.2),FRandom[Flak](-0.2,0.2),FRandom[Flak](-0.2,0.2))).unit()*vel.length();
A_PlaySound("flak/bounce",volume:0.3);
A_AlertMonsters();
bBOUNCEAUTOOFFFLOORONLY = true;
if ( vel.length() < 4.0 ) ExplodeMissile();
}
override int DoSpecialDamage( Actor target, int damage, Name damagetype )

View file

@ -28,7 +28,6 @@ Class UTHealthBox : Health replaces Medikit
Tag "Health Box";
Inventory.Amount 50;
Inventory.PickupMessage "You picked up a Health Box.";
Health.LowMessage 25,"You picked up a Health Box that you REALLY need!";
Inventory.PickupSound "misc/ut_heal";
}
States

View file

@ -30,13 +30,17 @@ Class MiniAmmo : Ammo
Default
{
Tag "Large Bullets";
Inventory.PickupMessage "You picked up 50 bullets.";
Inventory.PickupMessage "You picked up %d bullets.";
Inventory.Amount 50;
Inventory.MaxAmount 200;
Ammo.BackpackAmount 100;
Ammo.BackpackMaxAmount 400;
Ammo.DropAmount 20;
}
override String PickupMessage()
{
return String.Format(pickupmsg,Amount);
}
States
{
Spawn:
@ -102,7 +106,7 @@ Class Minigun : UTWeapon
A_Overlay(-2,"MuzzleFlash",true);
A_OverlayFlags(-2,PSPF_RENDERSTYLE|PSPF_FORCESTYLE,true);
A_OverlayRenderstyle(-2,STYLE_Add);
if ( (alt && (invoker.bcnt++ < 3)) || (invoker.bcnt++ < 5) ) return;
if ( (alt && (invoker.bcnt++ < 2)) || (invoker.bcnt++ < 4) ) return;
invoker.bcnt = 0;
if ( !weap.DepleteAmmo(weap.bAltFire,true,1) ) return;
invoker.FireEffect();

View file

@ -52,13 +52,18 @@ Class DamageAmplifier : Powerup
Powerup.Color "EE00FF", 0.15;
}
override void BeginPlay()
{
Super.BeginPlay();
if ( deathmatch ) EffectTics /= 2;
}
override void InitEffect()
{
Super.InitEffect();
l = Spawn("DamageAmpLight",Owner.pos);
l.target = Owner;
l.master = self;
if ( deathmatch ) EffectTics /= 2;
}
override void DoEffect()
@ -197,11 +202,16 @@ Class PowerUTInvisibility : PowerInvisibility
{
Default
{
Powerup.Duration -80;
Powerup.Duration -100;
Powerup.Strength 90;
Powerup.Mode "Additive";
Powerup.Color "FFFFFF", 0.1;
}
override void BeginPlay()
{
Super.BeginPlay();
if ( deathmatch ) EffectTics /= 2;
}
override void EndEffect()
{
Super.EndEffect();

View file

@ -58,7 +58,7 @@ Class Razor2 : Actor
Radius 2;
Height 2;
Speed 40; // should be 26 but it looks way too slow
DamageFunction Random[Ripper](30,40);
DamageFunction (Random[Ripper](30,40)*((DamageType=='Decapitated')?3.5:1.0));
DamageType 'Ripper';
Obituary "%k ripped a chunk of meat out of %o with the Ripper.";
BounceType "Doom";
@ -84,12 +84,11 @@ Class Razor2 : Actor
}
override int SpecialMissileHit( Actor victim )
{
if ( pos.z > victim.pos.z+victim.height*0.8 ) DamageType = 'Decapitated';
if ( pos.z > victim.pos.z+victim.height*0.75 ) DamageType = 'Decapitated';
return -1;
}
override int DoSpecialDamage( Actor target, int damage, Name damagetype )
{
if ( pos.z > target.pos.z+target.height*0.8 ) damage *= 2;
if ( !target.bNOBLOOD )
{
target.SpawnBlood(pos,AngleTo(target),damage);

View file

@ -1115,9 +1115,9 @@ Class EnhancedShockAmmo : Ammo
{
int ticcnt;
override void PostBeginPlay()
override void BeginPlay()
{
Super.PostBeginPlay();
Super.BeginPlay();
if ( deathmatch )
{
MaxAmount /= 2;
@ -1167,7 +1167,6 @@ Class EnhancedShockRifle : UTWeapon replaces InvulnerabilitySphere
override void PostBeginPlay()
{
Super.PostBeginPlay();
if ( deathmatch ) AmmoGive1 /= 2;
}
action void A_SShockFire()
{
@ -1266,6 +1265,7 @@ Class EnhancedShockRifle : UTWeapon replaces InvulnerabilitySphere
+WEAPON.AMMO_OPTIONAL;
+WEAPON.ALT_AMMO_OPTIONAL;
+WEAPON.CHEATNOTWEAPON;
+INVENTORY.IGNORESKILL;
}
States
{

View file

@ -26,6 +26,7 @@ Class RifleAmmo2 : RifleAmmo
Inventory.PickupMessage "You got a Rifle Round.";
Inventory.Amount 1;
Ammo.DropAmount 1;
+INVENTORY.IGNORESKILL;
}
States
{

View file

@ -5,14 +5,18 @@ Class UTPlayer : DoomPlayer
transient CVar footsteps, utmovement, doomspeed, doomaircontrol, nowalkdrop;
Vector2 acceleration;
Vector3 acceleration3;
int last_fm_tap, last_sm_tap;
int last_fm, last_sm;
int last_fm_tap, last_sm_tap;
int last_tap_fm, last_tap_sm;
int last_jump_held;
const groundspeed = 400.;
const accelrate = 2048.;
const walkfactor = 0.3;
const utaircontrol = 0.35;
const groundspeed_doomish = 600.;
const fluidfriction = 1.2;
const terminalvelocity = 2500.;
Default
{
@ -184,6 +188,7 @@ Class UTPlayer : DoomPlayer
bool forcefootstep = false;
if ( player.onground && !bNoGravity && !lastground && (waterlevel < 3) )
{
player.jumptics = 0;
if ( lastvelz < -4 )
{
double vol = clamp((-lastvelz-4)*0.05,0.01,1.0);
@ -240,38 +245,83 @@ 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);
Vector2 dodge = (0,0);
int fm = cmd.forwardmove;
int sm = cmd.sidemove;
if ( fm )
{
int clk = abs(gametic-last_fm_tap);
if ( (clk < 8) && (last_fm*fm == 0) && (last_tap_fm*fm>0) )
dodge += RotateVector((fm,0),angle).unit();
if ( !last_fm && (last_jump_held < gametic-1) )
{
last_fm_tap = gametic;
last_tap_fm = fm;
}
}
last_fm = fm;
if ( sm )
{
int clk = abs(gametic-last_sm_tap);
if ( (clk < 8) && (last_sm*sm == 0) && (last_tap_sm*sm>0) )
dodge += RotateVector((0,-sm),angle).unit();
if ( !last_sm && (last_jump_held < gametic-1) )
{
last_sm_tap = gametic;
last_tap_sm = sm;
}
}
last_sm = sm;
if ( player.onground )
{
if ( nowalkdrop.GetBool() )
bNODROPOFF = ((acceleration.length() > double.epsilon) && (cmd.buttons&BT_SPEED));
// Hook in Unreal physics
Vector2 dir = (0,0);
if ( vel.xy.length() > double.epsilon ) dir = vel.xy.unit();
if ( acceleration.length() <= double.epsilon )
if ( !bNoGravity && !waterlevel && (dodge.length() > 0) )
{
Vector2 oldvel = vel.xy;
vel.xy = vel.xy - (2 * dir) * vel.xy.length() * friction/TICRATE;
if ( oldvel dot vel.xy < 0.0 ) vel.xy *= 0;
if ( doomspeed.GetBool() ) vel += dodge.unit()*(groundspeed_doomish*1.5)/TICRATE;
else vel += dodge.unit()*(groundspeed*1.5)/TICRATE;
vel.z += jumpz*0.5;
bOnMobj = false;
if ( !(player.cheats&CF_PREDICTING) )
A_PlaySound("*jump",CHAN_BODY);
if ( player.cheats & CF_REVERTPLEASE )
{
player.cheats &= ~CF_REVERTPLEASE;
player.camera = player.mo;
}
player.vel *= 0;
}
else
{
Vector2 acceldir = acceleration.unit();
acceleration = acceldir * Min(acceleration.length(), accelrate/TICRATE);
vel.xy = vel.xy - (dir - acceldir) * vel.xy.length() * friction/TICRATE;
if ( nowalkdrop.GetBool() )
bNODROPOFF = ((acceleration.length() > double.epsilon) && (cmd.buttons&BT_SPEED));
// Hook in Unreal physics
Vector2 dir = (0,0);
if ( vel.xy.length() > double.epsilon ) dir = vel.xy.unit();
if ( acceleration.length() <= double.epsilon )
{
Vector2 oldvel = vel.xy;
vel.xy = vel.xy - (2 * dir) * vel.xy.length() * friction/TICRATE;
if ( oldvel dot vel.xy < 0.0 ) vel.xy *= 0;
}
else
{
Vector2 acceldir = acceleration.unit();
acceleration = acceldir * Min(acceleration.length(), accelrate/TICRATE);
vel.xy = vel.xy - (dir - acceldir) * vel.xy.length() * friction/TICRATE;
}
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 ( vel.xy.length() > maxvel ) vel.xy = vel.xy.unit()*maxvel;
if ( !(player.cheats & CF_PREDICTING) )
{
if ( acceleration.length() <= double.epsilon ) PlayIdle();
else PlayRunning();
}
player.vel = vel.xy;
}
vel.xy = vel.xy + acceleration * (1./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 ( vel.xy.length() > maxvel ) vel.xy = vel.xy.unit()*maxvel;
if ( !(player.cheats & CF_PREDICTING) )
{
if ( acceleration.length() <= double.epsilon ) PlayIdle();
else PlayRunning();
}
player.vel = vel.xy;
}
else if ( !bNoGravity && !waterlevel )
{
@ -281,8 +331,23 @@ Class UTPlayer : DoomPlayer
maxaccel += (40.-vel.xy.length())/TICRATE;
if ( acceleration.length() > maxaccel )
acceleration = acceleration.unit()*maxaccel;
acceleration *= doomaircontrol.GetBool()?level.aircontrol:0.35;
vel.xy += acceleration/TICRATE;
Vector2 dir = (0,0);
if ( vel.xy.length() > double.epsilon ) dir = vel.xy.unit();
if ( acceleration.length() <= double.epsilon )
{
Vector2 oldvel = vel.xy;
vel.xy = vel.xy - (2 * dir) * vel.xy.length() * fluidfriction/TICRATE;
if ( oldvel dot vel.xy < 0.0 ) vel.xy *= 0;
}
else
{
Vector2 acceldir = acceleration.unit();
acceleration = acceldir * Min(acceleration.length(), accelrate/TICRATE);
vel.xy = vel.xy - (dir - acceldir) * vel.xy.length() * fluidfriction/TICRATE;
}
acceleration *= doomaircontrol.GetBool()?level.aircontrol:utaircontrol;
vel.xy = vel.xy + acceleration/TICRATE;
if ( vel.length() > terminalvelocity/TICRATE ) vel = vel.unit()*(terminalvelocity/TICRATE);
player.vel *= 0;
}
else
@ -327,44 +392,41 @@ Class UTPlayer : DoomPlayer
player.camera = player.mo;
}
}
override void CheckJump()
{
if ( !utmovement ) utmovement = CVar.GetCVar('flak_utmovement');
if ( !doomspeed ) doomspeed = CVar.GetCVar('flak_doomspeed');
if ( utmovement.GetBool() && player.onground && !bNoGravity && !waterlevel && (player.jumptics == 0) && (player.cmd.forwardmove || player.cmd.sidemove) )
if ( !utmovement.GetBool() )
{
int fm = player.cmd.forwardmove;
int sm = player.cmd.sidemove;
Vector2 dodge = (0,0);
if ( fm )
Super.CheckJump();
return;
}
if ( player.cmd.buttons&BT_JUMP )
{
if ( player.crouchoffset ) player.crouching = 1;
else if ( waterlevel >= 2 ) Vel.z = 4*Speed;
else if ( bNoGravity ) Vel.z = 3.;
else if ( level.IsJumpingAllowed() && player.onground && (player.jumpTics == 0) && (last_jump_held < gametic-1) )
{
int clk = abs(gametic-last_fm_tap);
if ( (clk < 5) && (clk > 1) && (last_fm*fm>0) )
dodge += RotateVector((fm,0),angle).unit();
last_fm_tap = gametic;
last_fm = fm;
}
if ( sm )
{
int clk = abs(gametic-last_sm_tap);
if ( (clk < 5) && (clk > 1) && (last_sm*sm>0) )
dodge += RotateVector((0,-sm),angle).unit();
last_sm_tap = gametic;
last_sm = sm;
}
if ( dodge.length() > 0 )
{
if ( doomspeed.GetBool() ) vel += dodge.unit()*(groundspeed_doomish*1.5)/TICRATE;
else vel += dodge.unit()*(groundspeed*1.5)/TICRATE;
vel.z += jumpz*0.5;
double jumpvelz = JumpZ;
double jumpfac = 0;
for ( let p = Inv; p != null; p = p.Inv )
{
let pp = PowerHighJump(p);
if ( !pp ) continue;
double f = pp.Strength;
if ( f > jumpfac ) jumpfac = f;
}
if ( jumpfac > 0 ) jumpvelz *= jumpfac;
Vel.z += jumpvelz;
bOnMobj = false;
player.jumpTics = -1;
if ( !(player.cheats&CF_PREDICTING) )
A_PlaySound("*jump",CHAN_BODY);
}
last_jump_held = gametic;
}
Super.CheckJump();
if ( !player.onground || player.jumptics )
last_jump_held = gametic;
}
}
@ -388,6 +450,7 @@ Class RandomSpawner2 : RandomSpawner
Class UTWeapon : Weapon
{
int DropAmmo;
bool bExtraPickup;
Property DropAmmo: DropAmmo;
@ -434,6 +497,79 @@ Class UTWeapon : Weapon
A_ClearRefire();
}
override bool HandlePickup( Inventory item )
{
if (item.GetClass() == GetClass())
{
if ( Weapon(item).PickupForAmmo(self) )
item.bPickupGood = true;
if ( (MaxAmount > 1) || bALWAYSPICKUP )
return Inventory.HandlePickup(item);
return true;
}
return false;
}
override bool ShouldStay()
{
if ( ((multiplayer && (!deathmatch && !alwaysapplydmflags)) || sv_weaponstay) && !bDropped )
return (!bExtraPickup && !bALWAYSPICKUP);
return false;
}
override bool TryPickup( in out Actor toucher )
{
if ( !bExtraPickup ) bExtraPickup = ((MaxAmount > 1) && (toucher.CountInv(GetClass()) < MaxAmount));
return Super.TryPickup(toucher);
}
// Whole chain of function rewrites because of some stupid hardcoded deathmatch ammo multiplier
override bool TryPickupRestricted( in out Actor toucher )
{
if ( ShouldStay() ) return false;
bExtraPickup = false;
bool gaveSome = !!(NonIdioticAddAmmo(toucher,AmmoType1,AmmoGive1));
gaveSome |= !!(NonIdioticAddAmmo(toucher,AmmoType2,AmmoGive2));
if ( gaveSome ) GoAwayAndDie();
return gaveSome;
}
override void AttachToOwner( Actor other )
{
bExtraPickup = false;
Inventory.AttachToOwner(other);
Ammo1 = NonIdioticAddAmmo(Owner,AmmoType1,AmmoGive1);
Ammo2 = NonIdioticAddAmmo(Owner,AmmoType2,AmmoGive2);
SisterWeapon = AddWeapon(SisterWeaponType);
if ( Owner.player )
{
if ( !Owner.player.GetNeverSwitch() && !bNo_Auto_Switch )
Owner.player.PendingWeapon = self;
if ( Owner.player.mo == players[consoleplayer].camera )
StatusBar.ReceivedWeapon(self);
}
GivenAsMorphWeapon = false;
}
// rewrite of AddAmmo without stupid hardcoded 2.5x ammo multiplier
protected Ammo NonIdioticAddAmmo( Actor other, Class<Ammo> ammotype, int amount )
{
if ( !ammotype ) return null;
Ammo ammoitem;
if ( !bIgnoreSkill ) amount = int(amount*G_SkillPropertyFloat(SKILLP_AmmoFactor));
ammoitem = Ammo(other.FindInventory(ammotype));
if ( !ammoitem )
{
ammoitem = Ammo(Spawn(ammotype));
ammoitem.Amount = min(amount,ammoitem.MaxAmount);
ammoitem.AttachToOwner(other);
}
else if ( ammoitem.Amount < ammoitem.MaxAmount )
{
ammoitem.Amount += amount;
if ( ammoitem.Amount > ammoitem.MaxAmount )
ammoitem.Amount = ammoitem.MaxAmount;
}
return ammoitem;
}
Default
{
Weapon.BobStyle "Smooth";
@ -1022,7 +1158,9 @@ Class UTMainHandler : StaticEventHandler
ui void StartMenu()
{
int proto = CVar.GetCVar('flak_protomenu',players[consoleplayer]).GetInt();
CVar protomenu = CVar.GetCVar('flak_protomenu',players[consoleplayer]);
if ( !protomenu ) return; // this can happen
int proto = protomenu.GetInt();
if ( proto )
{
tex = TexMan.CheckForTexture("protobg",TexMan.Type_Any);

View file

@ -11,6 +11,7 @@ Class WarheadAmmo : Ammo
Ammo.BackpackMaxAmount 3;
Ammo.DropAmount 1;
Inventory.RespawnTics 2100;
+INVENTORY.IGNORESKILL;
}
States
{
@ -710,6 +711,7 @@ Class WarheadLauncher : UTWeapon replaces BFG9000
Weapon.AmmoGive 1;
Inventory.RespawnTics 2100;
+INVENTORY.ALWAYSPICKUP;
+INVENTORY.IGNORESKILL;
+WEAPON.NOAUTOFIRE;
UTWeapon.DropAmmo 1;
}