Added Eightball "2 second hold" feature from Unreal Bible.
Added Stinger projectile bounce from 0.866 and below. Added Stinger damage charge&explosion from Unreal Bible.
This commit is contained in:
parent
d3d6dc5705
commit
46ebde2750
8 changed files with 309 additions and 7 deletions
|
|
@ -12,9 +12,12 @@ Doom Tournament (currently the devel branch is required).
|
|||
- Automag (slot 2) (replaces pistol)
|
||||
- Dual Automags
|
||||
- Stinger (slot 3) (replaces shotguns)
|
||||
- Projectile bouncing from 0.866 and below
|
||||
- Tarydium charge & explosion described in Unreal Bible
|
||||
- ASMD (slot 4) (replaces shotguns)
|
||||
- Eightball (slot 5) (replaces rocket launcher)
|
||||
- Single rocket mode for Eightball
|
||||
- "Hold up to 2 seconds" feature from Unreal Bible
|
||||
- Flak Cannon (slot 6) (replaces rocket launcher)
|
||||
- SMP 7243 (slot 0) (replaces bfg9000)
|
||||
- Backpack (replaces backpack, identical to Doom Tournament version)
|
||||
|
|
@ -57,11 +60,10 @@ Doom Tournament (currently the devel branch is required).
|
|||
## Planned
|
||||
|
||||
- Unreal Bible & prototype build behaviour restoration
|
||||
- Stinger projectile remanence & explosion
|
||||
- Stinger projectile bouncing
|
||||
- Razorjack hold fire to increase blade speed
|
||||
- Rifle restored rapid fire
|
||||
- Rifle restored flashlight
|
||||
- Biorifle "Hold up to 2 seconds" feature from Unreal Bible
|
||||
|
||||
- QOL improvements
|
||||
- Make Razorjack altfire actually seek where player is aiming
|
||||
|
|
|
|||
|
|
@ -76,3 +76,7 @@ server bool sting_olsmp = false; // adds the stupid oldskool SMP 7243 to
|
|||
// an option
|
||||
server bool sting_autoscuba = false; // SCUBA gear toggles automatically
|
||||
// when needed
|
||||
server bool sting_ehold = false; // eightball can be held fully loaded
|
||||
// for up to 2 seconds
|
||||
server bool sting_bhold = false; // biorifle can be held fully loaded
|
||||
// for up to 2 seconds
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ O_OWNSENTRY = "%o was gunned down by %p own Minigun Sentry.";
|
|||
O_OSENTRY = "%%o took a bullet from %s.";
|
||||
O_OWNOSENTRY = "%o took a bullet from %p own Light Sentry.";
|
||||
O_STINGERX = "%o ate flaming Tarydium death thanks to %k.";
|
||||
O_STINGERX2 = "%o ate flaming Tarydium death.";
|
||||
O_OLSMP = "%o didn't stand a chance against %k's SMP 7243.";
|
||||
/* Pickup messages */
|
||||
I_WPOWERUP = "You got a Dispersion Pistol Powerup.";
|
||||
|
|
@ -217,6 +218,8 @@ STING_STINGERB = "Stinger projectiles bounce";
|
|||
STING_RIFLE = "Rifle burst altfire";
|
||||
STING_RIFLEL = "Rifle flashlight";
|
||||
STING_RAZOR = "Razorjack charging";
|
||||
STING_EHOLD = "Loaded Eightball can be held for 2 seconds";
|
||||
STING_BHOLD = "Charged Biorifle can be held for 2 seconds";
|
||||
STING_FLAMET = "Old Flamethrower model";
|
||||
STING_DOPTS = "Weapon dual wielding";
|
||||
STING_AUTODUAL = "Automags";
|
||||
|
|
@ -276,6 +279,7 @@ O_OWNSENTRY = "%o fue abatid@[ao_esp] por su propi@[ao_esp] Torreta.";
|
|||
O_OSENTRY = "%%o se llevó un tiro de la %s.";
|
||||
O_OWNOSENTRY = "%o se llevó un tiro de su propi@[ao_esp] Torreta Ligera.";
|
||||
O_STINGERX = "%o tragó muerte ardiente de Tarydium gracias a %k.";
|
||||
O_STINGERX2 = "%o tragó muerte ardiente de Tarydium.";
|
||||
O_OLSMP = "%o no tenía ninguna oportunidad contra el SMP 7243 de %k.";
|
||||
/* Pickup messages */
|
||||
I_WPOWERUP = "Has obtenido una Mejora para la Pistola de Dispersión.";
|
||||
|
|
@ -438,6 +442,8 @@ STING_STINGERB = "Los projectiles del Arma Aguijón rebotan";
|
|||
STING_RIFLE = "Fuego alternativo en ráfaga de Rifle";
|
||||
STING_RIFLEL = "Linterna de Rifle";
|
||||
STING_RAZOR = "Carga de Razorjack";
|
||||
STING_EHOLD = "El Eightball se puede mantener cargado por 2 segundos";
|
||||
STING_BHOLD = "El Biorifle se puede mantener cargado por 2 segundos";
|
||||
STING_FLAMET = "Modelo viejo de Lanzallamas";
|
||||
STING_DOPTS = "Armas a dos manos";
|
||||
STING_AUTODUAL = "Autoarmas";
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@ OptionMenu "UnrealOptionMenu"
|
|||
Option "$STING_RIFLE", "sting_rifle", "YesNo"
|
||||
Option "$STING_RIFLEL", "sting_riflel", "YesNo"
|
||||
Option "$STING_RAZOR", "sting_razor", "YesNo"
|
||||
Option "$STING_EHOLD", "sting_ehold", "YesNo"
|
||||
Option "$STING_BHOLD", "sting_bhold", "YesNo"
|
||||
Option "$STING_FLAMET", "sting_flamet", "YesNo"
|
||||
StaticText " "
|
||||
StaticText "$STING_DOPTS", "Gold"
|
||||
|
|
|
|||
|
|
@ -22,3 +22,9 @@ DoomEdNums
|
|||
4510 = UTranslator
|
||||
4511 = TranslatorEvent
|
||||
}
|
||||
|
||||
DamageType TarydiumCharge
|
||||
{
|
||||
// obituary for no instigator
|
||||
Obituary = "$O_STINGERX2"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -147,8 +147,199 @@ Class ViewStingerChunk : StingerChunk
|
|||
}
|
||||
}
|
||||
|
||||
Class TarydiumExLight : PaletteLight
|
||||
{
|
||||
Default
|
||||
{
|
||||
Tag "Blue2";
|
||||
Args 0,0,0,60;
|
||||
ReactionTime 30;
|
||||
}
|
||||
}
|
||||
|
||||
Class TarydiumExplosion : Actor
|
||||
{
|
||||
Default
|
||||
{
|
||||
RenderStyle "Add";
|
||||
+NOGRAVITY;
|
||||
+NOBLOCKMAP;
|
||||
+FORCEXYBILLBOARD;
|
||||
+FORCERADIUSDMG;
|
||||
+NODAMAGETHRUST;
|
||||
DamageType 'TarydiumCharge';
|
||||
Obituary "$O_STINGERX";
|
||||
}
|
||||
override void PostBeginPlay()
|
||||
{
|
||||
Super.PostBeginPlay();
|
||||
A_Explode(special1,int(90*scale.x));
|
||||
UTMainHandler.DoBlast(self,90*scale.x,90000);
|
||||
A_PlaySound("flare/explode");
|
||||
let l = Spawn("TarydiumExLight",pos);
|
||||
l.args[3] = int(60*scale.x);
|
||||
scale.x *= RandomPick[Stinger](-1,1);
|
||||
scale.y *= RandomPick[Stinger](-1,1);
|
||||
double ang, pt;
|
||||
int numpt = Random[Stinger](10,15)*min(3,special1/60);
|
||||
for ( int i=0; i<numpt; i++ )
|
||||
{
|
||||
ang = FRandom[Stinger](0,360);
|
||||
pt = FRandom[Stinger](-90,90);
|
||||
let c = Spawn("UTSmoke",pos);
|
||||
c.vel = (cos(ang)*cos(pt),sin(ang)*cos(pt),-sin(pt))*FRandom[Stinger](2,7);
|
||||
c.SetShade(Color(1,3,4)*Random[Stinger](24,63));
|
||||
c.scale *= 3.;
|
||||
}
|
||||
numpt = Random[Stinger](4,8)*min(8,special1/25);
|
||||
for ( int i=0; i<numpt; i++ )
|
||||
{
|
||||
ang = FRandom[Stinger](0,360);
|
||||
pt = FRandom[Stinger](-90,90);
|
||||
let c = Spawn("StingerChunk",pos);
|
||||
c.angle = ang;
|
||||
c.pitch = pt;
|
||||
c.vel = (cos(ang)*cos(pt),sin(ang)*cos(pt),-sin(pt))*FRandom[Stinger](6,12);
|
||||
}
|
||||
numpt = Random[Stinger](10,20)*min(4,special1/40);
|
||||
for ( int i=0; i<numpt; i++ )
|
||||
{
|
||||
ang = FRandom[Stinger](0,360);
|
||||
pt = FRandom[Stinger](-90,90);
|
||||
let c = Spawn("UTChip",pos);
|
||||
c.vel = (cos(ang)*cos(pt),sin(ang)*cos(pt),-sin(pt))*FRandom[Stinger](6,12);
|
||||
c.scale *= FRandom[Stinger](0.9,1.5);
|
||||
}
|
||||
}
|
||||
States
|
||||
{
|
||||
Spawn:
|
||||
TNT1 A 0 NoDelay A_Jump(128,"Explo2");
|
||||
Explo1:
|
||||
TEX1 ABCDEFGHI 3 Bright;
|
||||
Stop;
|
||||
Explo2:
|
||||
TEX2 ABCDEFGHIJK 3 Bright;
|
||||
Stop;
|
||||
}
|
||||
}
|
||||
|
||||
Class TarydiumDebuff : Thinker
|
||||
{
|
||||
Actor victim, instigator;
|
||||
int amount; // accumulated damage for the explosion
|
||||
Vector3 oldvel;
|
||||
bool wasonair, reentrant;
|
||||
|
||||
void UpdateEffect()
|
||||
{
|
||||
if ( !victim )
|
||||
{
|
||||
BlowUp();
|
||||
return;
|
||||
}
|
||||
victim.A_AttachLight('TDEBUFFLIGHT',DynamicLight.PointLight,Color(1,3,4)*min(amount,63),int(max(victim.radius,victim.height))+60+min(amount/4,40),0,DynamicLight.LF_ATTENUATE,(0,0,victim.height/2));
|
||||
if ( Random[Stinger](0,amount) > 100 )
|
||||
{
|
||||
amount += 30;
|
||||
BlowUp();
|
||||
}
|
||||
}
|
||||
|
||||
void BlowUp()
|
||||
{
|
||||
reentrant = true;
|
||||
let b = victim.Spawn("TarydiumExplosion",victim.Vec3Offset(0,0,victim.height/2));
|
||||
b.target = instigator;
|
||||
b.special1 = amount;
|
||||
b.scale *= 1.+min(1.5,amount*0.02);
|
||||
Destroy();
|
||||
}
|
||||
|
||||
override void OnDestroy()
|
||||
{
|
||||
Super.OnDestroy();
|
||||
if ( victim ) victim.A_RemoveLight('TDEBUFFLIGHT');
|
||||
}
|
||||
|
||||
override void Tick()
|
||||
{
|
||||
if ( !victim || (victim.Health <= 0) )
|
||||
{
|
||||
BlowUp();
|
||||
return;
|
||||
}
|
||||
if ( victim.pos.z > victim.floorz ) wasonair = true;
|
||||
else
|
||||
{
|
||||
if ( wasonair && (oldvel.z < -20) )
|
||||
{
|
||||
Amount += min(int(-oldvel.z),100);
|
||||
BlowUp();
|
||||
return;
|
||||
}
|
||||
wasonair = false;
|
||||
}
|
||||
oldvel = victim.vel;
|
||||
if ( !(level.maptime%20) )
|
||||
{
|
||||
amount--;
|
||||
UpdateEffect();
|
||||
if ( amount <= 0 )
|
||||
{
|
||||
Destroy();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ( level.maptime%3 ) return;
|
||||
int numpt = clamp(int(Random[Stinger](1,3)*amount*0.02),1,8);
|
||||
for ( int i=0; i<numpt; i++ )
|
||||
{
|
||||
Vector3 pos = victim.Vec3Offset(FRandom[Stinger](-victim.radius,victim.radius),FRandom[Stinger](-victim.radius,victim.radius),FRandom[Stinger](0,victim.height));
|
||||
let l = victim.Spawn("StingerBurstLight",pos);
|
||||
l.Args[3] /= 2;
|
||||
double ang, pt;
|
||||
int numpt2 = Random[Stinger](2,5);
|
||||
for ( int i=0; i<numpt; i++ )
|
||||
{
|
||||
ang = FRandom[Stinger](0,360);
|
||||
pt = FRandom[Stinger](-90,90);
|
||||
let c = victim.Spawn("UTSmoke",pos);
|
||||
c.vel = (cos(ang)*cos(pt),sin(ang)*cos(pt),-sin(pt))*FRandom[Stinger](0.3,0.8);
|
||||
c.SetShade(Color(1,3,4)*Random[Stinger](24,63));
|
||||
c.scale *= 3.;
|
||||
c.alpha *= 0.35;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void Apply( Actor victim, Actor instigator, int amount )
|
||||
{
|
||||
if ( !victim || (victim.Health <= 0) || !victim.bISMONSTER ) return;
|
||||
let ti = ThinkerIterator.Create("TarydiumDebuff",STAT_USER);
|
||||
TarydiumDebuff t;
|
||||
while ( t = TarydiumDebuff(ti.Next()) )
|
||||
{
|
||||
if ( t.victim != victim ) continue;
|
||||
if ( instigator ) t.instigator = instigator;
|
||||
t.amount += amount;
|
||||
t.UpdateEffect();
|
||||
return;
|
||||
}
|
||||
t = new("TarydiumDebuff");
|
||||
t.ChangeStatNum(STAT_USER);
|
||||
t.victim = victim;
|
||||
t.instigator = instigator;
|
||||
t.amount = amount;
|
||||
t.oldvel = victim.vel;
|
||||
t.wasonair = (victim.pos.z>victim.floorz);
|
||||
t.UpdateEffect();
|
||||
}
|
||||
}
|
||||
|
||||
Class StingerProjectile : Actor
|
||||
{
|
||||
Vector3 oldvel;
|
||||
Default
|
||||
{
|
||||
Obituary "$O_STINGER";
|
||||
|
|
@ -160,6 +351,66 @@ Class StingerProjectile : Actor
|
|||
PROJECTILE;
|
||||
+SKYEXPLODE;
|
||||
}
|
||||
override void PostBeginPlay()
|
||||
{
|
||||
Super.PostBeginPlay();
|
||||
if ( sting_stingerb )
|
||||
{
|
||||
// set bounce stuff
|
||||
bBOUNCEONWALLS = true;
|
||||
bBOUNCEONFLOORS = true;
|
||||
bBOUNCEONCEILINGS = true;
|
||||
bALLOWBOUNCEONACTORS = true;
|
||||
bCANBOUNCEWATER = true;
|
||||
bUSEBOUNCESTATE = true;
|
||||
BounceCount = 4;
|
||||
BounceFactor = 1.;
|
||||
WallBounceFactor = 1.;
|
||||
}
|
||||
}
|
||||
override void Tick()
|
||||
{
|
||||
oldvel = vel;
|
||||
Super.Tick();
|
||||
}
|
||||
void A_HandleBounce()
|
||||
{
|
||||
// cancel bounce based on "incidence"
|
||||
if ( vel dot oldvel < 0.87 )
|
||||
{
|
||||
ClearBounce();
|
||||
ExplodeMissile();
|
||||
return;
|
||||
}
|
||||
if ( !Random[Stinger](0,2) ) A_PlaySound("stinger/hit2",CHAN_BODY,0.5,pitch:FRandom[Stinger](0.5,1.5));
|
||||
else A_PlaySound("stinger/hit",CHAN_BODY,0.6);
|
||||
A_SprayDecal("WallCrack",-20);
|
||||
A_AlertMonsters();
|
||||
let l = Spawn("StingerBurstLight",pos);
|
||||
l.Args[3] /= 2;
|
||||
double ang, pt;
|
||||
int numpt = Random[Stinger](1,3);
|
||||
for ( int i=0; i<numpt; i++ )
|
||||
{
|
||||
ang = FRandom[Stinger](0,360);
|
||||
pt = FRandom[Stinger](-90,90);
|
||||
let c = Spawn("StingerChunk",pos);
|
||||
c.scale *= 0.5;
|
||||
c.angle = ang;
|
||||
c.pitch = pt;
|
||||
c.vel = (cos(ang)*cos(pt),sin(ang)*cos(pt),-sin(pt))*FRandom[Stinger](3,9);
|
||||
}
|
||||
numpt = Random[Stinger](2,5);
|
||||
for ( int i=0; i<numpt; i++ )
|
||||
{
|
||||
ang = FRandom[Stinger](0,360);
|
||||
pt = FRandom[Stinger](-90,90);
|
||||
let c = Spawn("UTSmoke",pos);
|
||||
c.vel = (cos(ang)*cos(pt),sin(ang)*cos(pt),-sin(pt))*FRandom[Stinger](0.3,0.8);
|
||||
c.SetShade(Color(1,3,4)*Random[Stinger](48,63));
|
||||
c.alpha *= 0.35;
|
||||
}
|
||||
}
|
||||
override int DoSpecialDamage( Actor target, int damage, Name damagetype )
|
||||
{
|
||||
if ( !target.bNOBLOOD )
|
||||
|
|
@ -167,6 +418,7 @@ Class StingerProjectile : Actor
|
|||
target.SpawnBlood(pos,AngleTo(target),damage);
|
||||
A_PlaySound("stinger/flesh");
|
||||
A_AlertMonsters();
|
||||
if ( sting_stinger ) TarydiumDebuff.Apply(target,self.target,damage/4);
|
||||
}
|
||||
return damage;
|
||||
}
|
||||
|
|
@ -204,6 +456,9 @@ Class StingerProjectile : Actor
|
|||
Spawn:
|
||||
TPRJ A -1 Bright;
|
||||
Stop;
|
||||
Bounce:
|
||||
TPRJ A 0 Bright A_HandleBounce();
|
||||
Goto Spawn;
|
||||
Death:
|
||||
Crash:
|
||||
TNT1 A 1 A_StingerHit();
|
||||
|
|
|
|||
|
|
@ -577,13 +577,26 @@ Class Eightball : UnrealWeapon
|
|||
EBLL LMNOPQRSTUVWXYZ[ 1;
|
||||
EBLL Z 0;
|
||||
EBLI A 0;
|
||||
EBLI A 1 A_JumpIf(invoker.special1>=6,2);
|
||||
EBLI A 1
|
||||
{
|
||||
if ( invoker.special1 >= 6 )
|
||||
{
|
||||
if ( sting_ehold )
|
||||
{
|
||||
invoker.special2 = 70;
|
||||
return ResolveState("LoadHold");
|
||||
}
|
||||
else return ResolveState("Release");
|
||||
}
|
||||
return ResolveState(null);
|
||||
}
|
||||
EBLI A 0 A_LoadedRefire("Loading");
|
||||
Goto Release;
|
||||
EBLI A 2;
|
||||
LoadHold:
|
||||
EBLI C 2;
|
||||
EBLI C 0 A_LoadedRefire("LoadHold");
|
||||
EBLI A 2;
|
||||
LoadHoldL:
|
||||
EBLI C 1 A_JumpIf(--invoker.special2<0,"Release");
|
||||
EBLI C 0 A_LoadedRefire("LoadHoldL");
|
||||
Goto Release;
|
||||
Release:
|
||||
EBLF A 0 A_FireRockets(invoker.special1);
|
||||
|
|
|
|||
|
|
@ -812,6 +812,20 @@ Class UnrealMainHandler : EventHandler
|
|||
{
|
||||
Array<AmmoUsedInSlot> AmmoSlots;
|
||||
|
||||
override void WorldThingDamaged( WorldEvent e )
|
||||
{
|
||||
// blow up stinger pumped actors when taking damage from other sources
|
||||
if ( e.DamageType == 'Stinger' ) return;
|
||||
let ti = ThinkerIterator.Create("TarydiumDebuff",Thinker.STAT_USER);
|
||||
TarydiumDebuff t;
|
||||
while ( t = TarydiumDebuff(ti.Next()) )
|
||||
{
|
||||
if ( (t.victim != e.Thing) || t.reentrant ) continue; // make sure to skip any debuffs that already blew up to prevent infinite recursion on chain reactions
|
||||
t.Amount += e.Damage/2;
|
||||
t.BlowUp();
|
||||
break;
|
||||
}
|
||||
}
|
||||
override void CheckReplacement( ReplaceEvent e )
|
||||
{
|
||||
if ( (e.Replacee == 'Chainsaw') || (e.Replacee == 'Gauntlets') )
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue