Silver Bullet JET fully implemented.
Ammo rebalancing. Damage boost to Candy Gun. Various small adjustments. Grilled Cheese Sandwich now gives 3 seconds of invulnerability on activation.
This commit is contained in:
parent
0975e30107
commit
fb078b7232
65 changed files with 1095 additions and 69 deletions
|
|
@ -196,7 +196,7 @@ Class RedShell : Ammo
|
|||
Tag "$T_REDSHELLS";
|
||||
Stamina 500;
|
||||
Inventory.Amount 1;
|
||||
Inventory.MaxAmount 48;
|
||||
Inventory.MaxAmount 40;
|
||||
Ammo.BackpackAmount 8;
|
||||
Ammo.DropAmount 3;
|
||||
+FLOATBOB;
|
||||
|
|
@ -255,7 +255,7 @@ Class GreenShell : Ammo
|
|||
Tag "$T_GREENSHELLS";
|
||||
Stamina 800;
|
||||
Inventory.Amount 1;
|
||||
Inventory.MaxAmount 40;
|
||||
Inventory.MaxAmount 32;
|
||||
Ammo.BackpackAmount 4;
|
||||
Ammo.DropAmount 2;
|
||||
+FLOATBOB;
|
||||
|
|
@ -540,7 +540,7 @@ Class EvisceratorShell : Ammo
|
|||
Inventory.PickupMessage "$T_EVISHELL";
|
||||
Stamina 2500;
|
||||
Inventory.Amount 1;
|
||||
Inventory.MaxAmount 30;
|
||||
Inventory.MaxAmount 24;
|
||||
Ammo.BackpackAmount 3;
|
||||
Ammo.DropAmount 2;
|
||||
+FLOATBOB;
|
||||
|
|
@ -577,7 +577,7 @@ Class HellblazerMissiles : Ammo
|
|||
Inventory.PickupMessage "$T_HELLMISSILE";
|
||||
Stamina 6000;
|
||||
Inventory.Amount 1;
|
||||
Inventory.MaxAmount 60;
|
||||
Inventory.MaxAmount 30;
|
||||
Ammo.BackpackAmount 3;
|
||||
Ammo.DropAmount 1;
|
||||
+FLOATBOB;
|
||||
|
|
@ -609,7 +609,7 @@ Class HellblazerCrackshots : Ammo
|
|||
Inventory.PickupMessage "$T_HELLCLUSTER";
|
||||
Stamina 8000;
|
||||
Inventory.Amount 1;
|
||||
Inventory.MaxAmount 24;
|
||||
Inventory.MaxAmount 18;
|
||||
Ammo.BackpackAmount 2;
|
||||
Ammo.DropAmount 1;
|
||||
+FLOATBOB;
|
||||
|
|
@ -707,7 +707,7 @@ Class SparkUnit : Ammo
|
|||
Inventory.PickupMessage "$T_SPARKUNIT";
|
||||
Stamina 50000;
|
||||
Inventory.Amount 1;
|
||||
Inventory.MaxAmount 8;
|
||||
Inventory.MaxAmount 4;
|
||||
Ammo.BackpackAmount 1;
|
||||
Ammo.DropAmount 1;
|
||||
+FLOATBOB;
|
||||
|
|
@ -733,8 +733,8 @@ Class SilverBulletAmmo : Ammo
|
|||
Inventory.PickupMessage "$T_XSBMAG";
|
||||
Stamina 70000;
|
||||
Inventory.Amount 1;
|
||||
Inventory.MaxAmount 5;
|
||||
Ammo.BackpackAmount 1;
|
||||
Inventory.MaxAmount 3;
|
||||
Ammo.BackpackAmount 0;
|
||||
Ammo.DropAmount 1;
|
||||
+FLOATBOB;
|
||||
FloatBobStrength 0.25;
|
||||
|
|
@ -759,7 +759,7 @@ Class CandyGunAmmo : Ammo
|
|||
Inventory.PickupMessage "$T_CANDYMAG";
|
||||
Stamina 100000;
|
||||
Inventory.Amount 1;
|
||||
Inventory.MaxAmount 4;
|
||||
Inventory.MaxAmount 2;
|
||||
Ammo.BackpackAmount 0;
|
||||
Ammo.DropAmount 1;
|
||||
+FLOATBOB;
|
||||
|
|
|
|||
|
|
@ -1841,7 +1841,7 @@ Class Hellblazer : SWWMWeapon
|
|||
XZWQ KLM 2;
|
||||
XZWQ N 2 A_Parry(9);
|
||||
XZWQ OP 1;
|
||||
XZWQ Q 1 A_Melee(75,"demolitionist/whitl");
|
||||
XZWQ Q 1 A_Melee(75,"demolitionist/whitl",1.05);
|
||||
XZWQ RSTUV 2;
|
||||
XZWQ W 2 A_StartSound("hellblazer/meleeend",CHAN_WEAPON,CHANF_OVERLAP);
|
||||
XZWQ XYZ 2;
|
||||
|
|
|
|||
|
|
@ -636,8 +636,8 @@ Class Wallbuster : SWWMWeapon
|
|||
{
|
||||
t.HitList[i].HitActor.TraceBleed(realdmg,self);
|
||||
t.HitList[i].HitActor.SpawnBlood(t.HitList[i].HitLocation,atan2(t.HitList[i].x.y,t.HitList[i].x.x)+180,realdmg);
|
||||
if ( large ) t.HitList[i].HitActor.A_StartSound("spreadgun/slugf",CHAN_BODY,CHANF_OVERLAP,1.,2.);
|
||||
else t.HitList[i].HitActor.A_StartSound("spreadgun/pelletf",CHAN_BODY,CHANF_OVERLAP,.4,4.);
|
||||
if ( large ) t.HitList[i].HitActor.A_StartSound("spreadgun/slugf",CHAN_FOOTSTEP,CHANF_OVERLAP,1.,2.);
|
||||
else t.HitList[i].HitActor.A_StartSound("spreadgun/pelletf",CHAN_FOOTSTEP,CHANF_OVERLAP,.4,4.);
|
||||
}
|
||||
}
|
||||
if ( (t.Results.HitType != TRACE_HitNone) && (t.Results.HitType != TRACE_HasHitSky) )
|
||||
|
|
@ -746,7 +746,7 @@ Class Wallbuster : SWWMWeapon
|
|||
int qk = min(9,1+howmany/5);
|
||||
int ql = min(25,6+howmany/2);
|
||||
A_QuakeEx(qk,qk,qk,ql,0,8,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:qk*.15);
|
||||
A_ZoomFactor(1.+qk*.04,ZOOM_INSTANT);
|
||||
A_ZoomFactor(1.-qk*.04,ZOOM_INSTANT);
|
||||
A_ZoomFactor(1.);
|
||||
A_AlertMonsters(alertness);
|
||||
A_PlayerFire();
|
||||
|
|
@ -1390,7 +1390,7 @@ Class Wallbuster : SWWMWeapon
|
|||
XZW9 GHI 2;
|
||||
XZW9 J 2 A_Parry(9);
|
||||
XZW9 KLM 1;
|
||||
XZW9 N 1 A_Melee(70,"demolitionist/whitl");
|
||||
XZW9 N 1 A_Melee(70,"demolitionist/whitl",1.2);
|
||||
XZW9 OPQRS 2;
|
||||
XZW9 T 2 A_StartSound("wallbuster/meleeend",CHAN_WEAPON,CHANF_OVERLAP);
|
||||
XZW9 UVW 2;
|
||||
|
|
|
|||
|
|
@ -2811,22 +2811,22 @@ Class SWWMHandler : EventHandler
|
|||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
if ( Random[Replacements](0,1) ) e.Replacement = 'HellblazerMissiles';
|
||||
if ( Random[Replacements](0,2) ) e.Replacement = 'HellblazerMissiles';
|
||||
else e.Replacement = 'HellblazerMissileMag';
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
if ( Random[Replacements](0,2) ) e.Replacement = 'HellblazerCrackshots';
|
||||
if ( Random[Replacements](0,3) ) e.Replacement = 'HellblazerCrackshots';
|
||||
else e.Replacement = 'HellblazerCrackshotMag';
|
||||
break;
|
||||
case 7:
|
||||
case 8:
|
||||
if ( Random[Replacements](0,3) ) e.Replacement = 'HellblazerRavagers';
|
||||
if ( Random[Replacements](0,4) ) e.Replacement = 'HellblazerRavagers';
|
||||
else e.Replacement = 'HellblazerRavagerMag';
|
||||
break;
|
||||
case 9:
|
||||
if ( Random[Replacements](0,4) ) e.Replacement = 'HellblazerWarheads';
|
||||
if ( Random[Replacements](0,5) ) e.Replacement = 'HellblazerWarheads';
|
||||
else e.Replacement = 'HellblazerWarheadMag';
|
||||
break;
|
||||
}
|
||||
|
|
@ -3088,6 +3088,9 @@ Class SWWMHandler : EventHandler
|
|||
Screen.Dim(Color(96,255,64),.1875*fstr,0,0,Screen.GetWidth(),Screen.GetHeight());
|
||||
}
|
||||
}
|
||||
// weapon underlays
|
||||
if ( players[consoleplayer].ReadyWeapon is 'SWWMWeapon' )
|
||||
SWWMWeapon(players[consoleplayer].ReadyWeapon).RenderUnderlay(e);
|
||||
if ( !statusbar || !(statusbar is 'SWWMStatusBar') ) return;
|
||||
SWWMStatusBar(statusbar).viewpos = e.viewpos;
|
||||
SWWMStatusBar(statusbar).viewrot = (e.viewangle,e.viewpitch,e.viewroll);
|
||||
|
|
|
|||
|
|
@ -918,7 +918,7 @@ Class Eviscerator : SWWMWeapon
|
|||
XZW9 AB 1;
|
||||
XZW9 C 1 A_Parry(9);
|
||||
XZW9 D 1;
|
||||
XZW9 E 2 A_Melee(60,"demolitionist/whitm");
|
||||
XZW9 E 2 A_Melee(60,"demolitionist/whitm",1.1);
|
||||
XZW9 FGH 2;
|
||||
XZW9 I 2 A_StartSound("eviscerator/meleeend",CHAN_WEAPON,CHANF_OVERLAP);
|
||||
XZW9 JKL 2;
|
||||
|
|
@ -929,7 +929,7 @@ Class Eviscerator : SWWMWeapon
|
|||
XZWA QRS 1;
|
||||
XZWA T 1 A_Parry(9);
|
||||
XZWA U 1;
|
||||
XZWA V 2 A_Melee(60,"demolitionist/whitm");
|
||||
XZWA V 2 A_Melee(60,"demolitionist/whitm",1.1);
|
||||
XZWA WXY 2;
|
||||
XZWA Z 2 A_StartSound("eviscerator/meleeend",CHAN_WEAPON,CHANF_OVERLAP);
|
||||
XZWB ABC 2;
|
||||
|
|
|
|||
|
|
@ -976,6 +976,10 @@ Class SWWMWeapon : Weapon abstract
|
|||
virtual ui void HudTick()
|
||||
{
|
||||
}
|
||||
// extra drawing, usually scopes
|
||||
virtual ui void RenderUnderlay( RenderEvent e )
|
||||
{
|
||||
}
|
||||
// animations
|
||||
action void A_PlayerFire()
|
||||
{
|
||||
|
|
@ -1048,12 +1052,12 @@ Class SWWMWeapon : Weapon abstract
|
|||
if ( !FindInventory("ParryDamageChecker") )
|
||||
GiveInventory("ParryDamageChecker",1); // need this so parried projectiles deal extra damage
|
||||
}
|
||||
private action bool TryMelee( double angle, int dmg, String hitsound = "" )
|
||||
private action bool TryMelee( double angle, int dmg, String hitsound = "", double rangemul = 1. )
|
||||
{
|
||||
FTranslatedLineTarget t;
|
||||
double slope = AimLineAttack(angle,1.5*DEFMELEERANGE,t,0.,ALF_CHECK3D);
|
||||
double slope = AimLineAttack(angle,1.5*DEFMELEERANGE*rangemul,t,0.,ALF_CHECK3D);
|
||||
FLineTraceData d;
|
||||
LineTrace(angle,1.5*DEFMELEERANGE,slope,0,player.viewheight,data:d);
|
||||
LineTrace(angle,1.5*DEFMELEERANGE*rangemul,slope,0,player.viewheight,data:d);
|
||||
bool raging = CountInv("RagekitPower");
|
||||
if ( d.HitType == TRACE_HitActor )
|
||||
{
|
||||
|
|
@ -1105,7 +1109,7 @@ Class SWWMWeapon : Weapon abstract
|
|||
}
|
||||
return false;
|
||||
}
|
||||
action void A_Melee( int dmg = 40, String hitsound = "" )
|
||||
action void A_Melee( int dmg = 40, String hitsound = "", double rangemul = 1. )
|
||||
{
|
||||
// temporarily disable parry field so we can trace through
|
||||
if ( invoker.pfield ) invoker.pfield.bSHOOTABLE = false;
|
||||
|
|
@ -1113,7 +1117,7 @@ Class SWWMWeapon : Weapon abstract
|
|||
let ut = new("UseLineTracer");
|
||||
ut.uses.Clear();
|
||||
ut.glass.Clear();
|
||||
ut.Trace(Vec3Offset(0,0,player.viewheight),CurSector,(cos(angle)*cos(pitch),sin(angle)*cos(pitch),sin(-pitch)),DEFMELEERANGE,0);
|
||||
ut.Trace(Vec3Offset(0,0,player.viewheight),CurSector,(cos(angle)*cos(pitch),sin(angle)*cos(pitch),sin(-pitch)),DEFMELEERANGE*rangemul,0);
|
||||
for ( int i=0; i<ut.uses.Size(); i++ )
|
||||
{
|
||||
if ( ut.uses[i].hitactor )
|
||||
|
|
@ -1138,7 +1142,7 @@ Class SWWMWeapon : Weapon abstract
|
|||
int maxang = raging?18:12;
|
||||
for ( int i=0; i<maxang; i++ )
|
||||
{
|
||||
if ( TryMelee(angle+i*(45./16),dmg,hitsound) || TryMelee(angle-i*(45./16),dmg,hitsound) )
|
||||
if ( TryMelee(angle+i*(45./16),dmg,hitsound,rangemul) || TryMelee(angle-i*(45./16),dmg,hitsound,rangemul) )
|
||||
{
|
||||
if ( invoker.pfield ) invoker.pfield.bSHOOTABLE = true;
|
||||
return;
|
||||
|
|
@ -1147,9 +1151,9 @@ Class SWWMWeapon : Weapon abstract
|
|||
if ( invoker.pfield ) invoker.pfield.bSHOOTABLE = true;
|
||||
// check for walls instead
|
||||
FTranslatedLineTarget t;
|
||||
double slope = AimLineAttack(angle,DEFMELEERANGE,t,0.,ALF_CHECK3D);
|
||||
double slope = AimLineAttack(angle,DEFMELEERANGE*rangemul,t,0.,ALF_CHECK3D);
|
||||
FLineTraceData d;
|
||||
LineTrace(angle,DEFMELEERANGE,slope,TRF_THRUACTORS,player.viewheight,data:d);
|
||||
LineTrace(angle,DEFMELEERANGE*rangemul,slope,TRF_THRUACTORS,player.viewheight,data:d);
|
||||
if ( d.HitType == TRACE_HitNone ) return;
|
||||
Vector3 HitNormal = -d.HitDir;
|
||||
if ( d.HitType == TRACE_HitFloor )
|
||||
|
|
|
|||
|
|
@ -392,7 +392,7 @@ Class PusherWeapon : SWWMWeapon
|
|||
{
|
||||
d.HitActor.TraceBleed(dmg,invoker);
|
||||
d.HitActor.SpawnBlood(d.HitLocation,atan2(d.HitDir.y,d.HitDir.x)+180,dmg);
|
||||
d.HitActor.A_StartSound("pusher/meat",CHAN_ITEMEXTRA,CHANF_OVERLAP);
|
||||
d.HitActor.A_StartSound("pusher/meat",CHAN_FOOTSTEP,CHANF_OVERLAP);
|
||||
}
|
||||
// move towards target
|
||||
bJUSTATTACKED = true;
|
||||
|
|
@ -477,7 +477,7 @@ Class PusherWeapon : SWWMWeapon
|
|||
{
|
||||
d.HitActor.TraceBleed(dmg,invoker);
|
||||
d.HitActor.SpawnBlood(d.HitLocation,atan2(d.HitDir.y,d.HitDir.x)+180,dmg);
|
||||
d.HitActor.A_StartSound("pusher/altmeat",CHAN_ITEMEXTRA,CHANF_OVERLAP);
|
||||
d.HitActor.A_StartSound("pusher/altmeat",CHAN_FOOTSTEP,CHANF_OVERLAP);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -683,7 +683,7 @@ Class PusherWeapon : SWWMWeapon
|
|||
XZW5 ABC 2;
|
||||
XZW5 D 1 A_Parry(9);
|
||||
XZW5 EFGH 1;
|
||||
XZW5 I 0 A_Melee(70,"demolitionist/whitl");
|
||||
XZW5 I 0 A_Melee(70,"demolitionist/whitl",1.1);
|
||||
XZW5 IJ 2;
|
||||
XZW5 K 2 { invoker.PlayUpSound(self); }
|
||||
XZW5 LM 2;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,18 @@
|
|||
// Powerups go here
|
||||
Class GrilledCheeseSafeguard : Powerup
|
||||
{
|
||||
Default
|
||||
{
|
||||
Inventory.Icon "graphics/HUD/Icons/I_Sandwich.png";
|
||||
Powerup.Duration -3;
|
||||
}
|
||||
|
||||
override void ModifyDamage( int damage, Name damageType, out int newdamage, bool passive, Actor inflictor, Actor source, int flags )
|
||||
{
|
||||
if ( passive ) newdamage = 0;
|
||||
}
|
||||
}
|
||||
|
||||
Class GrilledCheeseSandwich : Inventory
|
||||
{
|
||||
Mixin SWWMAutoUseFix;
|
||||
|
|
@ -37,6 +51,9 @@ Class GrilledCheeseSandwich : Inventory
|
|||
SWWMLoreLibrary.Add(Owner.player,"Nugget");
|
||||
SWWMLoreLibrary.Add(Owner.player,"BlastSuit");
|
||||
SWWMLoreLibrary.Add(Owner.player,"WarArmor");
|
||||
let s = Owner.FindInventory("GrilledCheeseSafeguard");
|
||||
if ( !s ) Owner.GiveInventory("GrilledCheeseSafeguard",1);
|
||||
else Powerup(s).EffectTics = Powerup(s).default.EffectTics;
|
||||
}
|
||||
override bool Use( bool pickup )
|
||||
{
|
||||
|
|
@ -48,6 +65,8 @@ Class GrilledCheeseSandwich : Inventory
|
|||
}
|
||||
override void AbsorbDamage( int damage, Name damageType, out int newdamage, Actor inflictor, Actor source, int flags )
|
||||
{
|
||||
if ( Owner.FindInventory("GrilledCheeseSafeguard") )
|
||||
return; // the safeguard absorbs all
|
||||
if ( Owner.ApplyDamageFactor(damageType,damage) <= 0 )
|
||||
return; // this damage type is ignored by the player, so it does not affect us
|
||||
if ( damageType == 'EndLevel' )
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ Class SpreadgunTracer : LineTracer
|
|||
// go right on through if dead
|
||||
if ( Results.HitActor.health-amt <= 0 ) return TRACE_Skip;
|
||||
// stap
|
||||
return TRACE_Abort;
|
||||
return TRACE_Stop;
|
||||
}
|
||||
return TRACE_Skip;
|
||||
}
|
||||
|
|
@ -198,7 +198,7 @@ Class SpreadSlugTracer : SpreadgunTracer
|
|||
ent.hitdamage = min(Results.HitActor.health+int(Results.HitActor.GetSpawnHealth()*gameinfo.gibfactor),int(penetration));
|
||||
hitlist.Push(ent);
|
||||
penetration = max(0,penetration-ent.hitdamage);
|
||||
if ( penetration <= 0 ) return TRACE_Abort;
|
||||
if ( penetration <= 0 ) return TRACE_Stop;
|
||||
return TRACE_Skip;
|
||||
}
|
||||
return TRACE_Skip;
|
||||
|
|
@ -2056,11 +2056,11 @@ Class Spreadgun : SWWMWeapon
|
|||
{
|
||||
t.HitList[i].HitActor.TraceBleed(realdmg,self);
|
||||
t.HitList[i].HitActor.SpawnBlood(t.HitList[i].HitLocation,atan2(t.HitList[i].x.y,t.HitList[i].x.x)+180,realdmg);
|
||||
if ( large ) t.HitList[i].HitActor.A_StartSound("spreadgun/slugf",CHAN_BODY,CHANF_OVERLAP,1.,2.);
|
||||
else t.HitList[i].HitActor.A_StartSound("spreadgun/pelletf",CHAN_BODY,CHANF_OVERLAP,.4,4.);
|
||||
if ( large ) t.HitList[i].HitActor.A_StartSound("spreadgun/slugf",CHAN_FOOTSTEP,CHANF_OVERLAP,1.,2.);
|
||||
else t.HitList[i].HitActor.A_StartSound("spreadgun/pelletf",CHAN_FOOTSTEP,CHANF_OVERLAP,.4,4.);
|
||||
}
|
||||
}
|
||||
if ( (t.Results.HitType != TRACE_HitNone) && (t.Results.HitType != TRACE_HasHitSky) )
|
||||
if ( (t.Results.HitType != TRACE_HitNone) && (t.Results.HitType != TRACE_HasHitSky) && (t.Results.HitType != TRACE_HitActor) )
|
||||
{
|
||||
Vector3 hitnormal = -t.Results.HitVector;
|
||||
if ( t.Results.HitType == TRACE_HitFloor )
|
||||
|
|
@ -2100,7 +2100,7 @@ Class Spreadgun : SWWMWeapon
|
|||
A_StartSound(sounds[i],CHAN_WEAPON,CHANF_OVERLAP,attenuation:.6);
|
||||
A_AlertMonsters(louds[i]);
|
||||
A_QuakeEx(quakes[i],quakes[i],quakes[i],9,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:.2*quakes[i]);
|
||||
A_ZoomFactor(1.+quakes[i]*.04,ZOOM_INSTANT);
|
||||
A_ZoomFactor(1.-quakes[i]*.04,ZOOM_INSTANT);
|
||||
A_ZoomFactor(1.);
|
||||
A_PlayerFire();
|
||||
SWWMHandler.DoFlash(self,cols[i],5);
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@ Class CandyBeam : Actor
|
|||
Obituary "$O_CANDYGUN";
|
||||
RenderStyle "Add";
|
||||
Alpha 0.4;
|
||||
DamageFunction 20;
|
||||
DamageFunction 25;
|
||||
ReactionTime 12;
|
||||
Radius 0.1;
|
||||
Height 0;
|
||||
|
|
@ -238,14 +238,13 @@ Class CandyPop : Actor
|
|||
BLPF B 3 NoDelay
|
||||
{
|
||||
SWWMHandler.DoBlast(self,120,60000);
|
||||
A_Explode(100,120);
|
||||
A_Explode(200,120);
|
||||
Scale *= FRandom[ExploS](0.6,1.8);
|
||||
Scale.x *= RandomPick[ExploS](-1,1);
|
||||
Scale.y *= RandomPick[ExploS](-1,1);
|
||||
roll = FRandom[Explos](0,360);
|
||||
Spawn("CandyPLight",pos);
|
||||
FlashPlayer(60,800);
|
||||
A_StartSound("candygun/hit",CHAN_VOICE,CHANF_DEFAULT,.08,.6,1.3);
|
||||
int numpt = Random[ExploS](-3,3);
|
||||
for ( int i=0; i<numpt; i++ )
|
||||
{
|
||||
|
|
@ -279,7 +278,7 @@ Class TinyCandyBeam : CandyBeam
|
|||
Default
|
||||
{
|
||||
ReactionTime 12;
|
||||
DamageFunction 10;
|
||||
DamageFunction 15;
|
||||
}
|
||||
States
|
||||
{
|
||||
|
|
@ -304,7 +303,7 @@ Class TinyCandyPop : CandyPop
|
|||
BLPF B 3 NoDelay
|
||||
{
|
||||
SWWMHandler.DoBlast(self,80,32000);
|
||||
A_Explode(40,80);
|
||||
A_Explode(60,80);
|
||||
Scale *= FRandom[ExploS](0.6,1.8);
|
||||
Scale.x *= RandomPick[ExploS](-1,1);
|
||||
Scale.y *= RandomPick[ExploS](-1,1);
|
||||
|
|
@ -364,7 +363,7 @@ Class CandyMagArm : Actor
|
|||
SWWMHandler.DoBlast(self,50+6*reactiontime,3000+800*reactiontime);
|
||||
double spd = vel.length();
|
||||
vel = (vel*.1+(FRandom[ExploS](-.7,.7),FRandom[ExploS](-.7,.7),FRandom[ExploS](-.7,.7))).unit()*spd;
|
||||
A_Explode(40+reactiontime*5,50+6*reactiontime);
|
||||
A_Explode(80+reactiontime*7,50+6*reactiontime);
|
||||
Vector3 pvel = (FRandom[ExploS](-1,1),FRandom[ExploS](-1,1),FRandom[ExploS](-1,1)).unit()*FRandom[ExploS](1,5);
|
||||
let s = Spawn("SWWMSmoke",pos);
|
||||
s.vel = pvel+vel*.2;
|
||||
|
|
@ -440,7 +439,7 @@ Class CandyMagArmBig : CandyMagArm
|
|||
SWWMHandler.DoBlast(self,100+8*reactiontime,3000+900*reactiontime);
|
||||
double spd = vel.length();
|
||||
vel = (vel*.1+(FRandom[ExploS](-.5,.5),FRandom[ExploS](-.5,.5),FRandom[ExploS](-.5,.5))).unit()*spd;
|
||||
A_Explode(80+reactiontime*8,100+8*reactiontime);
|
||||
A_Explode(120+reactiontime*10,100+8*reactiontime);
|
||||
Vector3 pvel = (FRandom[ExploS](-1,1),FRandom[ExploS](-1,1),FRandom[ExploS](-1,1)).unit()*FRandom[ExploS](1,5);
|
||||
let s = Spawn("SWWMSmoke",pos);
|
||||
s.vel = pvel+vel*.2;
|
||||
|
|
@ -473,7 +472,6 @@ Class CandyMagArmBig : CandyMagArm
|
|||
s.pitch = pt;
|
||||
s.ReactionTime += Random[ExploS](10,30);
|
||||
}
|
||||
A_StartSound("candygun/maghit",CHAN_VOICE,CHANF_DEFAULT,.5,.4,1.5);
|
||||
Destroy();
|
||||
}
|
||||
}
|
||||
|
|
@ -518,7 +516,7 @@ Class CandyGunProj : Actor
|
|||
Scale *= 6.+.2*special1;
|
||||
A_AlertMonsters(40000);
|
||||
SWWMHandler.DoBlast(self,300+20*special1,80000+8000*special1);
|
||||
A_Explode(3000+400*special1,300+20*special1);
|
||||
A_Explode(3500+500*special1,300+20*special1);
|
||||
A_QuakeEx(9,9,9,70,0,1500+100*special1,"",QF_RELATIVE|QF_SCALEDOWN,falloff:1200,rollintensity:2.);
|
||||
A_StartSound("candygun/gunhit",CHAN_VOICE,attenuation:.24);
|
||||
A_StartSound("candygun/gunhit",CHAN_WEAPON,attenuation:.12);
|
||||
|
|
@ -628,7 +626,7 @@ Class CandyMagProj : Actor
|
|||
Scale *= 3.+.2*special1;
|
||||
A_AlertMonsters(20000);
|
||||
SWWMHandler.DoBlast(self,250+25*special1,80000+8000*special1);
|
||||
A_Explode(600+400*special1,250+25*special1);
|
||||
A_Explode(700+600*special1,250+25*special1);
|
||||
A_QuakeEx(9,9,9,30,0,500+80*special1,"",QF_RELATIVE|QF_SCALEDOWN,falloff:500,rollintensity:2.);
|
||||
A_StartSound("candygun/maghit",CHAN_VOICE,attenuation:.24);
|
||||
A_StartSound("candygun/maghit",CHAN_WEAPON,attenuation:.12);
|
||||
|
|
@ -721,7 +719,7 @@ Class CandyBulletImpact : Actor
|
|||
Super.PostBeginPlay();
|
||||
A_AlertMonsters(9000);
|
||||
SWWMHandler.DoBlast(self,200,48000);
|
||||
A_Explode(350,200);
|
||||
A_Explode(700,200);
|
||||
A_QuakeEx(6,6,6,15,0,300,"",QF_RELATIVE|QF_SCALEDOWN,falloff:200,rollintensity:0.2);
|
||||
A_StartSound("candygun/hit",CHAN_VOICE,attenuation:.25);
|
||||
A_StartSound("candygun/hit",CHAN_WEAPON,attenuation:.5);
|
||||
|
|
@ -916,7 +914,7 @@ Class CandyGun : SWWMWeapon
|
|||
SWWMBulletTrail.DoTrail(self,origin,dir,10000,2);
|
||||
if ( d.HitType == TRACE_HitActor )
|
||||
{
|
||||
int dmg = 500;
|
||||
int dmg = 900;
|
||||
SWWMHandler.DoKnockback(d.HitActor,d.HitDir,72000);
|
||||
dmg = d.HitActor.DamageMobj(invoker,self,dmg,'Explodium',DMG_USEANGLE|DMG_THRUSTLESS,atan2(d.HitDir.y,d.HitDir.x));
|
||||
if ( d.HitActor.bNOBLOOD || d.HitActor.bINVULNERABLE )
|
||||
|
|
|
|||
|
|
@ -1,27 +1,382 @@
|
|||
// Blackmann-Forx Silver Bullet JET (successor to Silver Bullet from Zanaveth Ultra Suite)
|
||||
// Slot 8, replaces Plasma Rifle, Hellstaff, Quietus (hilt)
|
||||
|
||||
Class SilverBulletCasing : SWWMCasing
|
||||
{
|
||||
Default
|
||||
{
|
||||
BounceSound "silverbullet/casing";
|
||||
}
|
||||
}
|
||||
|
||||
Class SilverBulletMag : SWWMCasing
|
||||
{
|
||||
Default
|
||||
{
|
||||
Mass 10;
|
||||
BounceFactor 0.4;
|
||||
WallBounceFactor 0.4;
|
||||
BounceSound "silverbullet/mag";
|
||||
}
|
||||
override void PostBeginPlay()
|
||||
{
|
||||
Super.PostBeginPlay();
|
||||
heat = 0;
|
||||
}
|
||||
States
|
||||
{
|
||||
Death:
|
||||
#### # -1
|
||||
{
|
||||
pitch = 0;
|
||||
angle = FRandom[Junk](0,360);
|
||||
roll = RandomPick[Junk](-90,90);
|
||||
}
|
||||
Stop;
|
||||
}
|
||||
}
|
||||
Class SilverBulletMagEmpty : SilverBulletMag
|
||||
{
|
||||
}
|
||||
|
||||
Class SilverAirRip : Actor
|
||||
{
|
||||
Default
|
||||
{
|
||||
Radius 0.1;
|
||||
Height 0;
|
||||
+NOGRAVITY;
|
||||
+NOCLIP;
|
||||
+DONTSPLASH;
|
||||
+NOTELEPORT;
|
||||
+FORCERADIUSDMG;
|
||||
+NODAMAGETHRUST;
|
||||
}
|
||||
override void PostBeginPlay()
|
||||
{
|
||||
Super.PostBeginPlay();
|
||||
SWWMHandler.DoBlast(self,80,4000.,target);
|
||||
A_Explode(20,80,0);
|
||||
Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
Class SilverImpact : Actor
|
||||
{
|
||||
Default
|
||||
{
|
||||
Radius 0.1;
|
||||
Height 0;
|
||||
+NOGRAVITY;
|
||||
+NOCLIP;
|
||||
+DONTSPLASH;
|
||||
+NOTELEPORT;
|
||||
}
|
||||
override void PostBeginPlay()
|
||||
{
|
||||
Super.PostBeginPlay();
|
||||
if ( swwm_extraalert ) A_AlertMonsters(500);
|
||||
A_QuakeEx(4,4,4,20,0,200,"",QF_RELATIVE|QF_SCALEDOWN,falloff:100,rollIntensity:.9);
|
||||
A_StartSound("silverbullet/hit",CHAN_VOICE,CHANF_DEFAULT,1.,.7);
|
||||
A_SprayDecal("BigBulletChip",-20);
|
||||
A_SprayDecal("HugeWallCrack",-20);
|
||||
int numpt = Random[Silverbullet](15,25);
|
||||
Vector3 x = (cos(angle)*cos(pitch),sin(angle)*cos(pitch),-sin(pitch));
|
||||
for ( int i=0; i<numpt; i++ )
|
||||
{
|
||||
Vector3 pvel = (x+(FRandom[Silverbullet](-.4,.4),FRandom[Silverbullet](-.4,.4),FRandom[Silverbullet](-.4,.4))).unit()*FRandom[Silverbullet](.4,2.);
|
||||
let s = Spawn("SWWMSmoke",pos);
|
||||
s.vel = pvel;
|
||||
s.scale *= 1.8;
|
||||
s.special1 = Random[Silverbullet](1,3);
|
||||
s.SetShade(Color(1,1,1)*Random[Silverbullet](96,192));
|
||||
}
|
||||
numpt = Random[Silverbullet](6,9);
|
||||
for ( int i=0; i<numpt; i++ )
|
||||
{
|
||||
Vector3 pvel = (FRandom[Silverbullet](-1,1),FRandom[Silverbullet](-1,1),FRandom[Silverbullet](-1,1)).unit()*FRandom[Silverbullet](2,8);
|
||||
let s = Spawn("SWWMSpark",pos);
|
||||
s.scale *= 1.3;
|
||||
s.vel = pvel;
|
||||
}
|
||||
numpt = Random[Silverbullet](10,15);
|
||||
for ( int i=0; i<numpt; i++ )
|
||||
{
|
||||
Vector3 pvel = (x+(FRandom[Silverbullet](-.6,.6),FRandom[Silverbullet](-.6,.6),FRandom[Silverbullet](-.6,.6))).unit()*FRandom[Silverbullet](6,20);
|
||||
let s = Spawn("SWWMChip",pos);
|
||||
s.scale *= 1.6;
|
||||
s.vel = pvel;
|
||||
}
|
||||
}
|
||||
States
|
||||
{
|
||||
Spawn:
|
||||
TNT1 A 20;
|
||||
Stop;
|
||||
}
|
||||
}
|
||||
|
||||
Class SilverBullet : SWWMWeapon
|
||||
{
|
||||
bool chambered;
|
||||
bool chambered, fired;
|
||||
int clipcount;
|
||||
|
||||
transient ui TextureID WeaponBox[2], ZoomBar;
|
||||
transient ui Font TewiFont;
|
||||
transient ui DynamicValueInterpolator ZoomInter;
|
||||
|
||||
bool zoomed;
|
||||
double zoomlevel;
|
||||
ui TextureID reticle;
|
||||
bool initialized;
|
||||
|
||||
State dezoomstate;
|
||||
|
||||
Property ClipCount : clipcount;
|
||||
|
||||
// leave these while it's still unimplemented
|
||||
override void DrawWeapon( double TicFrac, double bx, double by, Vector2 hs, Vector2 ss )
|
||||
{
|
||||
if ( !WeaponBox[0] ) WeaponBox[0] = TexMan.CheckForTexture("graphics/HUD/SilverBulletDisplay.png",TexMan.Type_Any);
|
||||
if ( !WeaponBox[1] ) WeaponBox[1] = TexMan.CheckForTexture("graphics/HUD/SilverBulletZoomDisplay.png",TexMan.Type_Any);
|
||||
if ( !ZoomBar ) ZoomBar = TexMan.CheckForTexture("graphics/HUD/SilverBulletZoomBar.png",TexMan.Type_Any);
|
||||
if ( !TewiFont ) TewiFont = Font.GetFont('TewiShaded');
|
||||
int zl = clamp(ZoomInter?ZoomInter.GetValue():int(zoomlevel*10),0,160);
|
||||
if ( zl >= 10 )
|
||||
{
|
||||
Screen.DrawTexture(WeaponBox[1],false,bx-56,by-34,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
||||
Screen.DrawText(TewiFont,Font.CR_WHITE,bx-54,by-34,String.Format("%2dx",zl/10),DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
||||
int zw = int(zl*31./160.);
|
||||
Screen.DrawTexture(ZoomBar,false,bx-33,by-32,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_WindowRight,zw);
|
||||
}
|
||||
Screen.DrawTexture(WeaponBox[0],false,bx-56,by-22,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
||||
if ( chambered && !fired ) Screen.DrawText(TewiFont,Font.CR_FIRE,bx-19,by-21,"⁺¹",DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_Spacing,-1);
|
||||
Screen.DrawText(TewiFont,Font.CR_FIRE,bx-16,by-14,String.Format("%d",max(clipcount,0)),DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
||||
int cx = (Ammo1.Amount>9)?53:50;
|
||||
Screen.DrawText(TewiFont,Font.CR_FIRE,bx-cx,by-18,String.Format("%d",Ammo1.Amount),DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
||||
}
|
||||
override void HudTick()
|
||||
{
|
||||
if ( !ZoomInter ) ZoomInter = DynamicValueInterpolator.Create(int(zoomlevel*10),.5,1,20);
|
||||
ZoomInter.Update(int(zoomlevel*10));
|
||||
}
|
||||
|
||||
override bool ReportHUDAmmo()
|
||||
{
|
||||
return false;
|
||||
if ( (chambered && !fired) || (clipcount > 0) ) return true;
|
||||
if ( Ammo1.Amount <= 0 ) return false;
|
||||
return Super.ReportHUDAmmo();
|
||||
}
|
||||
override bool CheckAmmo( int firemode, bool autoswitch, bool requireammo, int ammocount )
|
||||
{
|
||||
return false;
|
||||
if ( sv_infiniteammo || Owner.FindInventory('PowerInfiniteAmmo',true) ) return true;
|
||||
if ( fireMode == PrimaryFire ) return ((chambered && !fired) || (clipcount > 0) || (Ammo1.Amount > 0));
|
||||
if ( fireMode == AltFire ) return true; // it's just a zoom
|
||||
return Super.CheckAmmo(firemode,autoswitch,requireammo,ammocount);
|
||||
}
|
||||
override void AttachToOwner( Actor other )
|
||||
{
|
||||
Super.AttachToOwner(other);
|
||||
if ( other.player == players[consoleplayer] )
|
||||
Console.Printf("\cgSILVER BULLET JET NOT IMPLEMENTED\c-");
|
||||
if ( !initialized )
|
||||
{
|
||||
initialized = true;
|
||||
// first copy always has a bullet in the chamber
|
||||
chambered = true;
|
||||
fired = false;
|
||||
}
|
||||
}
|
||||
override void DetachFromOwner()
|
||||
{
|
||||
// force disable zoom
|
||||
zoomed = false;
|
||||
if ( Owner.player == players[consoleplayer] )
|
||||
Shader.SetEnabled(players[consoleplayer],"SilverScope",false);
|
||||
Super.DetachFromOwner();
|
||||
}
|
||||
override void DoEffect()
|
||||
{
|
||||
Super.DoEffect();
|
||||
if ( zoomed ) crosshair = 99;
|
||||
else crosshair = 0;
|
||||
}
|
||||
override void RenderUnderlay( RenderEvent e )
|
||||
{
|
||||
if ( zoomed && (Owner.player == players[consoleplayer]) )
|
||||
{
|
||||
Vector2 ss = (Screen.GetWidth(),Screen.GetHeight());
|
||||
ss *= (512./ss.y);
|
||||
Shader.SetEnabled(players[consoleplayer],"SilverScope",true);
|
||||
if ( !reticle ) reticle = TexMan.CheckForTexture("graphics/SBReticle.png",TexMan.Type_Any);
|
||||
Screen.DrawTexture(reticle,false,ss.x*.5,ss.y*.5,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_LegacyRenderStyle,STYLE_Stencil,DTA_FillColor,Color(0,0,0));
|
||||
}
|
||||
else Shader.SetEnabled(players[consoleplayer],"SilverScope",false);
|
||||
}
|
||||
|
||||
action void ProcessTraceHit( SpreadgunTracer t, Vector3 origin, Vector3 dir )
|
||||
{
|
||||
for ( int i=0; i<t.ShootThroughList.Size(); i++ )
|
||||
{
|
||||
t.ShootThroughList[i].Activate(self,0,SPAC_PCross);
|
||||
if ( t.ShootThroughList[i].special == GlassBreak ) // fuck glass
|
||||
t.ShootThroughList[i].Activate(target,0,SPAC_Impact);
|
||||
}
|
||||
for ( int i=0; i<t.WaterHitList.Size(); i++ )
|
||||
{
|
||||
let b = Spawn("InvisibleSplasher",t.WaterHitList[i].hitpos);
|
||||
b.A_CheckTerrain();
|
||||
}
|
||||
for ( int i=8; i<t.Results.Distance; i+=16 )
|
||||
{
|
||||
let s = Spawn("SilverAirRip",level.Vec3Offset(origin,dir*i));
|
||||
s.target = self;
|
||||
if ( !Random[Boolet](0,1) ) continue;
|
||||
let b = Spawn("SWWMSmoke",level.Vec3Offset(origin,dir*i));
|
||||
b.Scale *= FRandom[Boolet](.9,1.6);
|
||||
b.alpha *= .5;
|
||||
b.special1 = Random[Boolet](0,2);
|
||||
}
|
||||
for ( int i=0; i<t.HitList.Size(); i++ )
|
||||
{
|
||||
int realdmg = t.HitList[i].HitDamage;
|
||||
SWWMDamageAccumulator.Accumulate(t.HitList[i].HitActor,realdmg,invoker,self,'shot');
|
||||
SWWMHandler.DoKnockback(t.HitList[i].HitActor,t.HitList[i].x+(0,0,0.025),realdmg*20.*FRandom[SilverBullet](.8,1.2));
|
||||
if ( t.HitList[i].HitActor.bNOBLOOD || t.HitList[i].HitActor.bINVULNERABLE )
|
||||
{
|
||||
let p = Spawn("SilverImpact",t.HitList[i].HitLocation);
|
||||
p.angle = atan2(t.HitList[i].x.y,t.HitList[i].x.x)+180;
|
||||
p.pitch = asin(t.HitList[i].x.z);
|
||||
}
|
||||
else
|
||||
{
|
||||
t.HitList[i].HitActor.TraceBleed(realdmg,self);
|
||||
t.HitList[i].HitActor.SpawnBlood(t.HitList[i].HitLocation,atan2(t.HitList[i].x.y,t.HitList[i].x.x)+180,realdmg);
|
||||
t.HitList[i].HitActor.A_StartSound("silverbullet/flesh",CHAN_FOOTSTEP,CHANF_OVERLAP,1.,2.);
|
||||
}
|
||||
}
|
||||
if ( (t.Results.HitType != TRACE_HitNone) && (t.Results.HitType != TRACE_HasHitSky) && (t.Results.HitType != TRACE_HitActor) )
|
||||
{
|
||||
Vector3 hitnormal = -t.Results.HitVector;
|
||||
if ( t.Results.HitType == TRACE_HitFloor )
|
||||
{
|
||||
if ( t.Results.FFloor ) hitnormal = -t.Results.FFloor.top.Normal;
|
||||
else hitnormal = t.Results.HitSector.floorplane.Normal;
|
||||
}
|
||||
else if ( t.Results.HitType == TRACE_HitCeiling )
|
||||
{
|
||||
if ( t.Results.FFloor ) hitnormal = -t.Results.FFloor.bottom.Normal;
|
||||
else hitnormal = t.Results.HitSector.ceilingplane.Normal;
|
||||
}
|
||||
else if ( t.Results.HitType == TRACE_HitWall )
|
||||
{
|
||||
hitnormal = (-t.Results.HitLine.delta.y,t.Results.HitLine.delta.x,0).unit();
|
||||
if ( !t.Results.Side ) hitnormal *= -1;
|
||||
}
|
||||
let p = Spawn("SilverImpact",t.Results.HitPos+hitnormal*4);
|
||||
p.angle = atan2(hitnormal.y,hitnormal.x);
|
||||
p.pitch = asin(-hitnormal.z);
|
||||
if ( t.Results.HitLine ) t.Results.HitLine.RemoteActivate(self,t.Results.Side,SPAC_Impact,t.Results.HitPos);
|
||||
}
|
||||
}
|
||||
action void A_SilverFire()
|
||||
{
|
||||
A_SWWMFlash();
|
||||
A_StartSound("silverbullet/fire",CHAN_WEAPON,CHANF_OVERLAP,attenuation:.3);
|
||||
A_AlertMonsters(16000);
|
||||
A_QuakeEx(8,8,8,10,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:2.);
|
||||
double basezoom = invoker.zoomed?clamp(invoker.zoomlevel,1.,16.):1.;
|
||||
A_ZoomFactor(basezoom*.76,ZOOM_INSTANT);
|
||||
A_ZoomFactor(basezoom);
|
||||
A_PlayerFire();
|
||||
SWWMHandler.DoFlash(self,Color(110,255,192,80),8);
|
||||
A_Overlay(-9999,"Jet");
|
||||
Vector3 x, y, z;
|
||||
[x, y, z] = swwm_CoordUtil.GetAxes(pitch,angle,roll);
|
||||
Vector3 origin = level.Vec3Offset(Vec2OffsetZ(0,0,player.viewz),10*x+1*y-1*z);
|
||||
Vector3 x2, y2, z2;
|
||||
[x2, y2, z2] = swwm_CoordUtil.GetAxes(BulletSlope(),angle,roll);
|
||||
SpreadSlugTracer sst = new("SpreadSlugTracer");
|
||||
sst.ignoreme = self;
|
||||
sst.penetration = 1500.;
|
||||
sst.hitlist.Clear();
|
||||
sst.shootthroughlist.Clear();
|
||||
sst.waterhitlist.Clear();
|
||||
sst.Trace(origin,level.PointInSector(origin.xy),x2,20000.,TRACE_HitSky);
|
||||
ProcessTraceHit(sst,origin,x2);
|
||||
for ( int i=0; i<10; i++ )
|
||||
{
|
||||
let s = Spawn("SWWMViewSmoke",origin);
|
||||
SWWMViewSmoke(s).ofs = (10,1,-1);
|
||||
s.target = self;
|
||||
s.SetShade(Color(1,1,1)*Random[Silverbullet](96,192));
|
||||
s.alpha *= .5;
|
||||
}
|
||||
for ( int i=0; i<16; i++ )
|
||||
{
|
||||
let s = Spawn("SWWMSmoke",origin);
|
||||
s.scale *= 1.3;
|
||||
s.alpha *= .5;
|
||||
s.special1 = Random[Silverbullet](0,3);
|
||||
s.SetShade(Color(1,1,1)*Random[Silverbullet](96,192));
|
||||
s.vel += vel*.5+x*FRandom[Silverbullet](2.,7.)+y*FRandom[Silverbullet](-2.,2.)+z*FRandom[Silverbullet](-2.,2.);
|
||||
}
|
||||
for ( int i=0; i<34; i++ )
|
||||
{
|
||||
let s = Spawn("SWWMSmoke",origin);
|
||||
s.scale *= 1.8;
|
||||
s.alpha *= .8;
|
||||
s.special1 = Random[Silverbullet](0,2);
|
||||
s.SetShade(Color(1,1,1)*Random[Silverbullet](96,192));
|
||||
s.vel += vel*.5+y*FRandom[Silverbullet](2.,8.)*RandomPick[SilverBullet](-1,1);
|
||||
}
|
||||
for ( int i=0; i<20; i++ )
|
||||
{
|
||||
let s = Spawn("SWWMSpark",origin);
|
||||
s.scale *= .4;
|
||||
s.alpha *= .4;
|
||||
s.vel += vel*.5+x*FRandom[Silverbullet](4.,8.)+y*FRandom[Silverbullet](-1,1)+z*FRandom[Silverbullet](-1,1);
|
||||
}
|
||||
SWWMHandler.DoKnockback(self,-x,320000.);
|
||||
}
|
||||
action void A_DropCasing()
|
||||
{
|
||||
Vector3 x, y, z;
|
||||
[x, y, z] = swwm_CoordUtil.GetAxes(pitch,angle,roll);
|
||||
Vector3 origin = level.Vec3Offset(Vec2OffsetZ(0,0,player.viewz),10*x+10*y-8*z);
|
||||
let c = Spawn("SilverBulletCasing",origin);
|
||||
c.angle = angle;
|
||||
c.pitch = pitch;
|
||||
c.vel = x*FRandom[Junk](-.5,.5)+y*FRandom[Junk](4,8)-(0,0,FRandom[Junk](1,3));
|
||||
c.vel += vel*.5;
|
||||
}
|
||||
action void A_DropMag()
|
||||
{
|
||||
Vector3 x, y, z;
|
||||
[x, y, z] = swwm_CoordUtil.GetAxes(pitch,angle,roll);
|
||||
Vector3 origin = level.Vec3Offset(Vec2OffsetZ(0,0,player.viewz),6*x-15*z);
|
||||
let c = Spawn((invoker.clipcount>0)?"SilverBulletMag":"SilverBulletMagEmpty",origin);
|
||||
c.angle = angle;
|
||||
c.pitch = pitch;
|
||||
c.vel = x*FRandom[Junk](-.5,.5)+y*FRandom[Junk](-.5,.5)-(0,0,FRandom[Junk](2,3));
|
||||
c.vel += vel*.5;
|
||||
}
|
||||
action void A_JetCompensate()
|
||||
{
|
||||
invoker.specialf1 -= .06;
|
||||
Vector3 x, y, z;
|
||||
[x, y, z] = swwm_CoordUtil.GetAxes(pitch,angle,roll);
|
||||
vel += x*min(1.,invoker.specialf1)*(600./Mass);
|
||||
A_OverlayAlpha(PSP_WEAPON+2,clamp(invoker.specialf1*3.,0.,1.));
|
||||
if ( Random[SilverBullet](0,int(invoker.specialf1*4)) )
|
||||
self.DamageMobj(invoker,self,2,'jet');
|
||||
Vector3 origin = level.Vec3Offset(Vec2OffsetZ(0,0,player.viewz),-x*10-z*10);
|
||||
for ( int i=0; i<4; i++ )
|
||||
{
|
||||
let s = Spawn("SWWMSmoke",origin);
|
||||
s.scale *= 1.3;
|
||||
s.alpha *= .5*invoker.specialf1;
|
||||
s.special1 = Random[Silverbullet](0,3);
|
||||
s.SetShade(Color(1,1,1)*Random[Silverbullet](224,255));
|
||||
s.vel += vel*.5+x*FRandom[Silverbullet](-8.,-5.)+y*FRandom[Silverbullet](3.,6.)*RandomPick[Silverbullet](-1,1)+z*FRandom[Silverbullet](-3.,-2.);
|
||||
}
|
||||
}
|
||||
|
||||
Default
|
||||
|
|
@ -31,6 +386,7 @@ Class SilverBullet : SWWMWeapon
|
|||
Obituary "$O_SILVERBULLET";
|
||||
Weapon.SlotNumber 8;
|
||||
Weapon.SelectionOrder 1400;
|
||||
Weapon.UpSound "silverbullet/select";
|
||||
Stamina 400000;
|
||||
Weapon.AmmoType1 "SilverBulletAmmo";
|
||||
Weapon.AmmoGive1 1;
|
||||
|
|
@ -44,20 +400,263 @@ Class SilverBullet : SWWMWeapon
|
|||
XZW1 A -1;
|
||||
Stop;
|
||||
Select:
|
||||
TNT1 A 1
|
||||
{
|
||||
Console.Printf("\cgSILVER BULLET JET NOT IMPLEMENTED\c-");
|
||||
A_FullRaise();
|
||||
}
|
||||
XZW2 G 2 A_FullRaise();
|
||||
XZW2 HIJKLMN 2;
|
||||
Goto Ready;
|
||||
Ready:
|
||||
TNT1 A 1 A_WeaponReady();
|
||||
XZW2 A 1
|
||||
{
|
||||
int flg = WRF_ALLOWZOOM|WRF_ALLOWUSER1;
|
||||
if ( (invoker.clipcount < invoker.default.clipcount) && (sv_infiniteammo || FindInventory('PowerInfiniteAmmo',true) || (invoker.Ammo1.Amount > 0)) )
|
||||
flg |= WRF_ALLOWRELOAD;
|
||||
A_WeaponReady(flg);
|
||||
if ( player.cmd.buttons&BT_ATTACK )
|
||||
invoker.CheckAmmo(EitherFire,true);
|
||||
}
|
||||
Wait;
|
||||
ZoomReady:
|
||||
TNT1 A 1
|
||||
{
|
||||
int flg = WRF_ALLOWZOOM|WRF_ALLOWUSER1;
|
||||
if ( (invoker.clipcount < invoker.default.clipcount) && (sv_infiniteammo || FindInventory('PowerInfiniteAmmo',true) || (invoker.Ammo1.Amount > 0)) )
|
||||
flg |= WRF_ALLOWRELOAD;
|
||||
A_WeaponReady(flg);
|
||||
if ( player.cmd.buttons&BT_ATTACK )
|
||||
invoker.CheckAmmo(EitherFire,true);
|
||||
}
|
||||
Wait;
|
||||
Fire:
|
||||
XZW2 A 1
|
||||
{
|
||||
if ( !invoker.chambered || invoker.fired )
|
||||
{
|
||||
if ( !invoker.fired && (invoker.clipcount <= 0) && (sv_infiniteammo || FindInventory('PowerInfiniteAmmo',true) || (invoker.Ammo1.Amount > 0)) )
|
||||
return ResolveState("Reload");
|
||||
return ResolveState("Cock");
|
||||
}
|
||||
A_SilverFire();
|
||||
invoker.fired = true;
|
||||
return A_JumpIf(invoker.zoomed,"ZoomFire");
|
||||
}
|
||||
XZW2 OPQR 2;
|
||||
XZW2 STUVW 3;
|
||||
XZW2 A 1 A_JumpIf(invoker.specialf1<=0.,"Ready");
|
||||
Wait;
|
||||
Jet:
|
||||
TNT1 A 3
|
||||
{
|
||||
invoker.specialf1 = 1.5;
|
||||
}
|
||||
TNT1 A 0
|
||||
{
|
||||
A_StartSound("silverbullet/jet",CHAN_WEAPON,CHANF_OVERLAP);
|
||||
A_Overlay(PSP_WEAPON+2,"JetSmoke");
|
||||
A_OverlayFlags(PSP_WEAPON+2,PSPF_RENDERSTYLE|PSPF_ALPHA|PSPF_FORCESTYLE|PSPF_FORCEALPHA,true);
|
||||
A_OverlayRenderStyle(PSP_WEAPON+2,STYLE_Add);
|
||||
}
|
||||
TNT1 A 1
|
||||
{
|
||||
A_JetCompensate();
|
||||
return A_JumpIf(invoker.specialf1<=0.,1);
|
||||
}
|
||||
Wait;
|
||||
TNT1 A 1;
|
||||
Stop;
|
||||
JetSmoke:
|
||||
XZW7 PQR 2;
|
||||
XZW7 STUVW 3;
|
||||
XZW7 X 1 A_JumpIf(invoker.specialf1<=0.,1);
|
||||
Wait;
|
||||
TNT1 A 1;
|
||||
Stop;
|
||||
Cock:
|
||||
XZW2 A 0
|
||||
{
|
||||
if ( invoker.zoomed )
|
||||
{
|
||||
invoker.dezoomstate = ResolveState("DoCock");
|
||||
return ResolveState("AltFireZoom");
|
||||
}
|
||||
return ResolveState(null);
|
||||
}
|
||||
DoCock:
|
||||
XZW2 A 2 A_StartSound("silverbullet/meleestart",CHAN_WEAPON,CHANF_OVERLAP);
|
||||
XZW2 XYZ 2;
|
||||
XZW3 AB 2;
|
||||
XZW3 C 2
|
||||
{
|
||||
A_StartSound("silverbullet/boltopen",CHAN_WEAPON,CHANF_OVERLAP);
|
||||
invoker.fired = false;
|
||||
if ( invoker.chambered )
|
||||
A_Overlay(PSP_WEAPON+1,"Casing");
|
||||
invoker.chambered = (invoker.clipcount>0);
|
||||
invoker.clipcount = max(0,invoker.clipcount-1);
|
||||
}
|
||||
XZW3 DEFG 2;
|
||||
XZW3 H 2 A_StartSound("silverbullet/boltclose",CHAN_WEAPON,CHANF_OVERLAP);
|
||||
XZW3 I 2 A_StartSound("silverbullet/meleeend",CHAN_WEAPON,CHANF_OVERLAP);
|
||||
XZW3 JKLMNOPQR 2;
|
||||
Goto Ready;
|
||||
Casing:
|
||||
XZW7 DE 2;
|
||||
XZW7 FGHIJKLMNO 1;
|
||||
TNT1 A 0 A_DropCasing();
|
||||
Stop;
|
||||
ZoomFire:
|
||||
TNT1 A 24;
|
||||
TNT1 A 1 A_JumpIf(invoker.specialf1<=0.,"ZoomReady");
|
||||
Wait;
|
||||
AltFire:
|
||||
XZW2 A 0 A_JumpIf(invoker.zoomed,"AltFireZoom");
|
||||
XZW2 A 2
|
||||
{
|
||||
A_StartSound("silverbullet/zoomstart",CHAN_WEAPON,CHANF_OVERLAP);
|
||||
invoker.zoomlevel = 0;
|
||||
}
|
||||
XZW3 STUVWX 1;
|
||||
TNT1 A 1
|
||||
{
|
||||
invoker.zoomed = true;
|
||||
invoker.zoomlevel = clamp(invoker.zoomlevel*1.1+.1,1.,16.);
|
||||
A_ZoomFactor(invoker.zoomlevel);
|
||||
if ( !(level.maptime%2) && (invoker.zoomlevel < 16.) ) A_StartSound("silverbullet/zooming",CHAN_WEAPON,CHANF_OVERLAP,.2);
|
||||
if ( !(player.cmd.buttons&BT_ALTATTACK) )
|
||||
return ResolveState("ZoomReady");
|
||||
return ResolveState(null);
|
||||
}
|
||||
Wait;
|
||||
AltFireZoom:
|
||||
XZW3 X 1
|
||||
{
|
||||
A_StartSound("silverbullet/zoomend",CHAN_WEAPON,CHANF_OVERLAP);
|
||||
invoker.zoomed = false;
|
||||
invoker.zoomlevel = 0;
|
||||
A_ZoomFactor(1.,ZOOM_INSTANT);
|
||||
}
|
||||
XZW3 YZ 1;
|
||||
XZW4 ABC 1;
|
||||
XZW2 A 0
|
||||
{
|
||||
if ( invoker.dezoomstate )
|
||||
{
|
||||
State tmp = invoker.dezoomstate;
|
||||
invoker.dezoomstate = null;
|
||||
return tmp;
|
||||
}
|
||||
return ResolveState(null);
|
||||
}
|
||||
Goto Ready;
|
||||
Reload:
|
||||
XZW2 A 0
|
||||
{
|
||||
if ( invoker.zoomed )
|
||||
{
|
||||
invoker.dezoomstate = ResolveState("Unload");
|
||||
return ResolveState("AltFireZoom");
|
||||
}
|
||||
return ResolveState(null);
|
||||
}
|
||||
Unload:
|
||||
XZW2 A 2
|
||||
{
|
||||
A_PlayerReload();
|
||||
A_StartSound("silverbullet/meleestart",CHAN_WEAPON,CHANF_OVERLAP);
|
||||
return A_JumpIf(invoker.clipcount<=0,"UnloadEmpty");
|
||||
}
|
||||
XZW4 DEFGHI 2;
|
||||
XZW4 J 2 A_StartSound("silverbullet/magout",CHAN_WEAPON,CHANF_OVERLAP);
|
||||
XZW4 KLMN 2;
|
||||
Goto Load;
|
||||
UnloadEmpty:
|
||||
XZW2 A 2;
|
||||
XZW4 OPQRST 2;
|
||||
XZW4 U 2 A_StartSound("silverbullet/magout",CHAN_WEAPON,CHANF_OVERLAP);
|
||||
XZW4 VWXY 2;
|
||||
Goto Load;
|
||||
Load:
|
||||
XZW4 Z 2
|
||||
{
|
||||
A_DropMag();
|
||||
invoker.clipcount = invoker.default.clipcount;
|
||||
if ( !sv_infiniteammo && !FindInventory('PowerInfiniteAmmo',true) )
|
||||
invoker.Ammo1.Amount = max(0,invoker.Ammo1.Amount-1);
|
||||
}
|
||||
XZW5 ABC 2;
|
||||
XZW5 D 2 A_StartSound("silverbullet/magin",CHAN_WEAPON,CHANF_OVERLAP);
|
||||
XZW5 E 2 A_StartSound("silverbullet/meleeend",CHAN_WEAPON,CHANF_OVERLAP);
|
||||
XZW5 FGHIJKLMN 2;
|
||||
Goto Ready;
|
||||
Zoom:
|
||||
XZW2 A 0
|
||||
{
|
||||
if ( invoker.zoomed )
|
||||
{
|
||||
invoker.dezoomstate = ResolveState("DoZoom");
|
||||
return ResolveState("AltFireZoom");
|
||||
}
|
||||
return ResolveState(null);
|
||||
}
|
||||
DoZoom:
|
||||
XZW2 A 2
|
||||
{
|
||||
A_StartSound("silverbullet/idle",CHAN_WEAPON,CHANF_OVERLAP);
|
||||
A_PlayerCheckGun();
|
||||
}
|
||||
XZW5 OPQR 3;
|
||||
XZW5 STUV 2;
|
||||
XZW5 WXYZ 3;
|
||||
XZW6 ABCD 4;
|
||||
XZW6 EFGH 3;
|
||||
Goto Ready;
|
||||
User1:
|
||||
XZW2 A 0
|
||||
{
|
||||
if ( invoker.zoomed )
|
||||
{
|
||||
invoker.dezoomstate = ResolveState("DoUser1");
|
||||
return ResolveState("AltFireZoom");
|
||||
}
|
||||
return ResolveState(null);
|
||||
}
|
||||
DoUser1:
|
||||
XZW2 A 2
|
||||
{
|
||||
A_StartSound("silverbullet/meleestart",CHAN_WEAPON,CHANF_OVERLAP);
|
||||
A_StartSound("demolitionist/wswing",CHAN_WEAPON,CHANF_OVERLAP);
|
||||
A_PlayerMelee();
|
||||
}
|
||||
XZW6 IJK 3;
|
||||
XZW6 L 1 A_Parry(9);
|
||||
XZW6 MN 1;
|
||||
XZW6 O 1 A_Melee(90,"demolitionist/whitl",1.6);
|
||||
XZW6 PQ 1;
|
||||
XZW6 RST 2;
|
||||
XZW6 U 3 A_StartSound("silverbullet/meleeend",CHAN_WEAPON,CHANF_OVERLAP);
|
||||
XZW6 VWXYZ 3;
|
||||
XZW7 ABC 2;
|
||||
Goto Ready;
|
||||
Deselect:
|
||||
TNT1 A -1 A_FullLower();
|
||||
XZW2 A 0
|
||||
{
|
||||
if ( invoker.zoomed )
|
||||
{
|
||||
invoker.dezoomstate = ResolveState("DoDeselect");
|
||||
return ResolveState("AltFireZoom");
|
||||
}
|
||||
return ResolveState(null);
|
||||
}
|
||||
DoDeselect:
|
||||
XZW2 A 2 A_StartSound("silverbullet/deselect",CHAN_WEAPON,CHANF_OVERLAP);
|
||||
XZW2 BCDEF 2;
|
||||
XZW2 G -1 A_FullLower();
|
||||
Stop;
|
||||
Flash:
|
||||
XZWZ A 2 Bright
|
||||
{
|
||||
let l = Spawn("SWWMWeaponLight",pos);
|
||||
l.args[3] = 200;
|
||||
l.target = self;
|
||||
}
|
||||
Stop;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue