Ynykron initial implementation (not functional).

Removed Chanceboxes completely, they were a dumb idea.
Various itty bitty adjustments.
This commit is contained in:
Mari the Deer 2020-06-14 23:34:47 +02:00
commit aec8a71de6
83 changed files with 841 additions and 1152 deletions

View file

@ -460,7 +460,7 @@ Class CorpseFallTracker : Thinker
// play fall thumps
bool isflying = ((mybody.pos.z>mybody.floorz)&&mybody.TestMobjZ());
if ( wasflying && !isflying && (lastvelz < -10) )
mybody.A_StartSound("misc/bodythump",CHAN_FOOTSTEP,CHANF_OVERLAP);
mybody.A_StartSound("misc/bodythump",CHAN_DAMAGE,CHANF_OVERLAP);
wasflying = isflying;
lastvelz = mybody.vel.z;
// wait until body is dead on floor and at the last state of animation

View file

@ -637,8 +637,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_FOOTSTEP,CHANF_OVERLAP,1.,2.);
else t.HitList[i].HitActor.A_StartSound("spreadgun/pelletf",CHAN_FOOTSTEP,CHANF_OVERLAP,.4,4.);
if ( large ) t.HitList[i].HitActor.A_StartSound("spreadgun/slugf",CHAN_DAMAGE,CHANF_OVERLAP,1.,2.);
else t.HitList[i].HitActor.A_StartSound("spreadgun/pelletf",CHAN_DAMAGE,CHANF_OVERLAP,.4,4.);
}
}
if ( (t.Results.HitType != TRACE_HitNone) && (t.Results.HitType != TRACE_HasHitSky) && (t.Results.HitType != TRACE_HitActor) )

View file

@ -1,516 +0,0 @@
// gacha nonsense
Class Chancebox : Inventory abstract
{
Class<Actor> dropclass;
Property DropClass : dropclass;
override Inventory CreateCopy( Actor other )
{
// additional lore
SWWMLoreLibrary.Add(other.player,"Lootbox");
return Super.CreateCopy(other);
}
override bool Use( bool pickup )
{
if ( pickup ) return false;
Console.Printf("\cgTHESE ITEMS ARE NOT YET FULLY IMPLEMENTED\c-");
Vector3 x, y, z;
[x, y, z] = swwm_CoordUtil.GetAxes(Owner.pitch,Owner.angle,Owner.roll);
Vector3 origin = level.Vec3Offset(Owner.Vec2OffsetZ(0,0,Owner.player.viewz),x*20-z*8);
if ( !level.IsPointInLevel(origin) ) return false;
let b = Spawn(dropclass,origin);
if ( !b ) return false;
if ( !b.TestMobjLocation() )
{
b.Destroy();
return false;
}
b.angle = Owner.angle-180;
b.vel = x*10;
b.vel.z += 2.;
return true;
}
Default
{
+INVENTORY.INVBAR;
+FLOATBOB;
Inventory.MaxAmount 32;
Inventory.InterHubAmount 32;
FloatBobStrength 0.25;
}
States
{
Spawn:
XZW1 A -1;
Stop;
}
}
// top side of chancebox, shoots upwards
Class ChanceTop : Actor abstract
{
Default
{
Radius 16;
Height 4;
PROJECTILE;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
vel = (0,0,20);
}
States
{
Spawn:
XZW1 A 1
{
double magvel = vel.length();
if ( magvel > 0. )
{
magvel = min(60,magvel*1.2);
vel = vel.unit()*magvel;
}
}
Wait;
Death:
TNT1 A 1 A_SpawnItemEx("ExplodiumBulletImpact");
Stop;
}
}
// left/right side of chancebox, shoots forward
Class ChanceSide : Actor abstract
{
Default
{
Radius 16;
Height 32;
PROJECTILE;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
vel = (cos(angle)*cos(pitch),sin(angle)*cos(pitch),-sin(pitch))*20;
}
States
{
Spawn:
XZW1 A 1
{
double magvel = vel.length();
if ( magvel > 0. )
{
magvel = min(60,magvel*1.2);
vel = vel.unit()*magvel;
}
}
Wait;
Death:
TNT1 A 1 A_SpawnItemEx("ExplodiumBulletImpact");
Stop;
}
}
Class ChanceTopTier1 : ChanceTop {}
Class ChanceTopTier2 : ChanceTop {}
Class ChanceTopTier3 : ChanceTop {}
Class ChanceTopTier4 : ChanceTop {}
Class ChanceSideTier1 : ChanceSide {}
Class ChanceSideTier2 : ChanceSide {}
Class ChanceSideTier3 : ChanceSide {}
Class ChanceSideTier4 : ChanceSide {}
Class DroppedChancebox : Actor abstract
{
Class<Actor> topclass, sideclass;
Property TopClass : topclass;
Property SideClass : sideclass;
double rang;
action void A_DropSomething()
{
int num = 0;
// first pass, count up the max rng number
for ( DropItem d=GetDropItems(); d; d=d.Next )
num += d.Probability;
// second pass, pick the item
int choice = Random[Chancebox](0,num);
int num2 = 0;
for ( DropItem d=GetDropItems(); d; d=d.Next )
{
num2 += d.Probability;
if ( num2 < choice ) continue;
let thedrop = Spawn(d.Name,pos);
thedrop.angle = angle;
break;
}
int numpt = Random[ExploS](16,32);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[ExploS](-1,1),FRandom[ExploS](-1,1),FRandom[ExploS](-1,1)).unit()*FRandom[ExploS](.3,8);
let s = Spawn("SWWMSmoke",Vec3Offset(0,0,16));
s.vel = pvel;
s.SetShade(FillColor*Random[ExploS](64,85));
s.special1 = Random[ExploS](1,4);
s.alpha *= .4;
s.scale *= 2.4;
}
}
action void A_Confetti()
{
A_StartSound("chancebox/tada",CHAN_ITEM);
double ang, pt;
int numpt = Random[ExploS](64,128);
for ( int i=0; i<numpt; i++ )
{
ang = FRandom[ExploS](0,360);
pt = FRandom[ExploS](-90,30);
let c = Spawn("FancyConfetti",Vec3Offset(0,0,16));
c.vel = (cos(pt)*cos(ang),cos(pt)*sin(ang),-sin(pt))*FRandom[ExploS](2,8);
}
}
Default
{
Radius 16;
Height 32;
Gravity .7;
+CANNOTPUSH;
+MOVEWITHSECTOR;
+BLOCKASPLAYER;
+ROLLSPRITE;
}
States
{
Spawn:
XZW1 A 1 A_JumpIf(pos.z<=floorz,1);
Wait;
XZW1 A 35
{
A_Stop();
A_StartSound("chancebox/land",CHAN_BODY);
rang = angle;
}
XZW1 A 0 A_StartSound("chancebox/drumroll",CHAN_WEAPON);
XZW1 A 1
{
angle = rang+FRandom[Chancebox](-5,5);
pitch = FRandom[Chancebox](-5,5);
roll = FRandom[Chancebox](-5,5);
special1++;
return A_JumpIf(special1>40,"BlowUp");
}
Wait;
BlowUp:
XZW2 A 1
{
A_QuakeEx(2,2,2,9,0,500,"",QF_RELATIVE|QF_SCALEDOWN,falloff:200,rollIntensity:.2);
A_StartSound("chancebox/explode",CHAN_VOICE);
angle = rang;
pitch = roll = 0;
let t = Spawn(TopClass,Vec3Offset(0,0,32));
t.angle = angle;
let s1 = Spawn(SideClass,level.Vec3Offset(pos,(RotateVector((16,0),angle+90),0)));
s1.angle = angle+90;
let s2 = Spawn(SideClass,level.Vec3Offset(pos,(RotateVector((16,0),angle-90),0)));
s2.angle = angle-90;
A_DropSomething();
}
XZW2 BCDEFGHIJKLMNO 1;
XZW2 P -1 A_Confetti();
Stop;
Dummy:
XZW1 BCDEFG -1; // these won't actually be used, found a better way
Stop;
}
}
Class DroppedChanceboxTier1 : DroppedChancebox
{
Default
{
DroppedChancebox.TopClass "ChanceTopTier1";
DroppedChancebox.SideClass "ChanceSideTier1";
StencilColor "01 01 03";
DropItem "ChanceDropShells1", 6;
DropItem "ChanceDropShells2", 6;
DropItem "ChanceDropShells3", 5;
DropItem "ChanceDropShells4", 4;
DropItem "ChanceDropShells5", 3;
DropItem "ChanceDropShells6", 2;
}
}
Class DroppedChanceboxTier2 : DroppedChancebox
{
Default
{
DroppedChancebox.TopClass "ChanceTopTier2";
DroppedChancebox.SideClass "ChanceSideTier2";
StencilColor "01 03 01";
}
}
Class DroppedChanceboxTier3 : DroppedChancebox
{
Default
{
DroppedChancebox.TopClass "ChanceTopTier3";
DroppedChancebox.SideClass "ChanceSideTier3";
StencilColor "03 01 01";
}
}
Class DroppedChanceboxTier4 : DroppedChancebox
{
Default
{
DroppedChancebox.TopClass "ChanceTopTier4";
DroppedChancebox.SideClass "ChanceSideTier4";
StencilColor "03 03 01";
}
}
Class ChanceboxTier1 : Chancebox
{
Default
{
Tag "$T_LOOTBOX1";
Inventory.PickupMessage "$T_LOOTBOX1";
Inventory.Icon "graphics/HUD/Icons/I_Chancebox1.png";
Stamina 1500;
Chancebox.DropClass "DroppedChanceboxTier1";
}
}
Class ChanceboxTier2 : Chancebox
{
Default
{
Tag "$T_LOOTBOX2";
Inventory.PickupMessage "$T_LOOTBOX2";
Inventory.Icon "graphics/HUD/Icons/I_Chancebox2.png";
Stamina 9000;
Chancebox.DropClass "DroppedChanceboxTier2";
}
}
Class ChanceboxTier3 : Chancebox
{
Default
{
Tag "$T_LOOTBOX3";
Inventory.PickupMessage "$T_LOOTBOX3";
Inventory.Icon "graphics/HUD/Icons/I_Chancebox3.png";
Stamina 60000;
Chancebox.DropClass "DroppedChanceboxTier3";
}
}
Class ChanceboxTier4 : Chancebox
{
Default
{
Tag "$T_LOOTBOX4";
Inventory.PickupMessage "$T_LOOTBOX4";
Inventory.Icon "graphics/HUD/Icons/I_Chancebox4.png";
Stamina 1500000;
Chancebox.DropClass "DroppedChanceboxTier4";
}
}
Class FancyConfetti : Actor
{
int deadtimer;
double anglevel, pitchvel, rollvel;
Default
{
Radius 2;
Height 2;
+NOBLOCKMAP;
+DROPOFF;
+MOVEWITHSECTOR;
+THRUACTORS;
+NOTELEPORT;
+DONTSPLASH;
+INTERPOLATEANGLES;
+ROLLSPRITE;
+ROLLCENTER;
+SLIDESONWALLS;
Gravity 0.05;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
deadtimer = 0;
anglevel = FRandom[Junk](3,12)*RandomPick[Junk](-1,1);
pitchvel = FRandom[Junk](3,12)*RandomPick[Junk](-1,1);
rollvel = FRandom[Junk](3,12)*RandomPick[Junk](-1,1);
if ( bAMBUSH ) frame = 0;
else frame = Random[Junk](0,9);
scale *= Frandom[Junk](0.8,1.2);
}
override void Tick()
{
Super.Tick();
if ( isFrozen() ) return;
vel.xy *= 0.98;
if ( vel.z > 0 ) vel.z *= 0.98;
if ( InStateSequence(CurState,ResolveState("Death")) )
{
deadtimer++;
if ( deadtimer > 300 ) A_FadeOut(0.05);
return;
}
}
States
{
Spawn:
XZW1 # 1
{
angle += anglevel;
pitch += pitchvel;
roll += rollvel;
return A_JumpIf(pos.z<=floorz,"Death");
}
Loop;
Death:
XZW1 # -1
{
A_Stop();
pitch = roll = 0;
}
Stop;
Dummy:
XZW1 ABCDEFGHIJ -1;
Stop;
}
}
// Chancebox drops
Class ChanceDrop : Actor abstract
{
Default
{
StencilColor "03 03 03";
+NOBLOCKMAP;
+NOGRAVITY;
}
action void A_DropTheGoods()
{
int num = 0;
for ( DropItem d=GetDropItems(); d; d=d.Next )
{
if ( Random[Chancebox](0,255) > d.Probability ) continue;
Actor i = Spawn(d.Name,pos);
i.bDROPPED = true;
i.bNOGRAVITY = false;
i.vel.z = FRandom[Chancebox](2,4);
switch ( num )
{
case 0:
i.vel.xy = (0,0);
break;
case 1:
i.vel.xy = RotateVector((FRandom[Chancebox](3,6),0),angle);
break;
case 2:
i.vel.xy = RotateVector((FRandom[Chancebox](3,6),0),angle+90);
break;
case 3:
i.vel.xy = RotateVector((FRandom[Chancebox](3,6),0),angle-90);
break;
case 4:
i.vel.xy = RotateVector((FRandom[Chancebox](3,6),0),angle+180);
break;
default:
i.vel.xy = RotateVector((FRandom[Chancebox](3,6),0),FRandom[Chancebox](0,360));
break;
}
num++;
if ( i is 'Inventory' ) Inventory(i).bTOSSED = true;
}
}
States
{
Spawn:
TNT1 A 1 NoDelay A_DropTheGoods();
Stop;
}
}
Class ChanceDropShells1 : ChanceDrop
{
Default
{
DropItem "RedShell2", 256;
DropItem "RedShell4", 224;
DropItem "RedShell4", 224;
DropItem "RedShell8", 192;
DropItem "RedShell8", 192;
}
}
Class ChanceDropShells2 : ChanceDrop
{
Default
{
DropItem "GreenShell2", 256;
DropItem "GreenShell4", 192;
DropItem "GreenShell4", 192;
DropItem "GreenShell8", 160;
DropItem "GreenShell8", 160;
}
}
Class ChanceDropShells3 : ChanceDrop
{
Default
{
DropItem "BlueShell2", 256;
DropItem "BlueShell4", 160;
DropItem "BlueShell4", 160;
DropItem "BlueShell8", 128;
DropItem "BlueShell8", 128;
}
}
Class ChanceDropShells4 : ChanceDrop
{
Default
{
DropItem "PurpleShell2", 256;
DropItem "PurpleShell2", 128;
DropItem "PurpleShell2", 128;
DropItem "PurpleShell4", 96;
DropItem "PurpleShell4", 96;
}
}
Class ChanceDropShells5 : ChanceDrop
{
Default
{
DropItem "WhiteShell", 256;
DropItem "WhiteShell", 128;
DropItem "WhiteShell", 128;
DropItem "WhiteShell2", 96;
DropItem "WhiteShell2", 96;
}
}
Class ChanceDropShells6 : ChanceDrop
{
Default
{
DropItem "BlackShell", 256;
DropItem "BlackShell", 64;
DropItem "BlackShell", 64;
}
}
Class ChanceDropShells7 : ChanceDrop
{
Default
{
DropItem "GoldShell", 256;
}
}

View file

@ -2,14 +2,16 @@
enum ESWWMGZChannels
{
CHAN_YOUDONEFUCKEDUP = 63200, // exception handler
CHAN_DEMOVOICE = 63201, // demolitionist voices
CHAN_FOOTSTEP = 63202, // footstep sounds and others
CHAN_DEMOVOICE = 63201, // demolitionist voices
CHAN_FOOTSTEP = 63202, // footstep sounds and others
CHAN_WEAPONEXTRA = 63203, // additional weapon sounds (usually loops)
CHAN_POWERUP = 63204, // powerup sounds
CHAN_POWERUP = 63204, // powerup sounds
CHAN_POWERUPEXTRA = 63205, // additional powerup sounds
CHAN_JETPACK = 63206, // jetpack sound
CHAN_ITEMEXTRA = 63207, // additional item sounds
CHAN_AMBEXTRA = 63208 // player ambience when submerged
CHAN_JETPACK = 63206, // jetpack sound
CHAN_ITEMEXTRA = 63207, // additional item sounds
CHAN_WEAPONEXTRA2 = 63208, // additional weapon sound slot
CHAN_DAMAGE = 63209, // used for impact/hit sounds
CHAN_AMBEXTRA = 63210 // player ambience when submerged
};
// Misc. Utility code
@ -1419,6 +1421,75 @@ Class SWWMChip : Actor
}
}
Class FancyConfetti : Actor
{
int deadtimer;
double anglevel, pitchvel, rollvel;
Default
{
Radius 2;
Height 2;
+NOBLOCKMAP;
+DROPOFF;
+MOVEWITHSECTOR;
+THRUACTORS;
+NOTELEPORT;
+DONTSPLASH;
+INTERPOLATEANGLES;
+ROLLSPRITE;
+ROLLCENTER;
+SLIDESONWALLS;
Gravity 0.05;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
deadtimer = 0;
anglevel = FRandom[Junk](3,12)*RandomPick[Junk](-1,1);
pitchvel = FRandom[Junk](3,12)*RandomPick[Junk](-1,1);
rollvel = FRandom[Junk](3,12)*RandomPick[Junk](-1,1);
if ( bAMBUSH ) frame = 0;
else frame = Random[Junk](0,9);
scale *= Frandom[Junk](0.8,1.2);
}
override void Tick()
{
Super.Tick();
if ( isFrozen() ) return;
vel.xy *= 0.98;
if ( vel.z > 0 ) vel.z *= 0.98;
if ( InStateSequence(CurState,ResolveState("Death")) )
{
deadtimer++;
if ( deadtimer > 300 ) A_FadeOut(0.05);
return;
}
}
States
{
Spawn:
XZW1 # 1
{
angle += anglevel;
pitch += pitchvel;
roll += rollvel;
return A_JumpIf(pos.z<=floorz,"Death");
}
Loop;
Death:
XZW1 # -1
{
A_Stop();
pitch = roll = 0;
}
Stop;
Dummy:
XZW1 ABCDEFGHIJ -1;
Stop;
}
}
Class SWWMNothing : Actor
{
States

View file

@ -3,24 +3,122 @@
Class Ynykron : SWWMWeapon
{
transient ui TextureID WeaponBox, ChargeBar[2], BoxSide[2];
transient ui Font TewiFont;
transient ui DynamicValueInterpolator ChargeInter;
enum EChargeState
{
CS_IDLE,
CS_CHARGING,
CS_READY,
CS_DISCHARGING
};
int chargestate;
double chargelevel;
bool inverted;
double ventalpha, ventfade;
int ventcooldown;
int clipcount;
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 ) WeaponBox = TexMan.CheckForTexture("graphics/HUD/YnykronDisplay.png",TexMan.Type_Any);
if ( !ChargeBar[0] ) ChargeBar[0] = TexMan.CheckForTexture("graphics/HUD/YnykronBarA.png",TexMan.Type_Any);
if ( !ChargeBar[1] ) ChargeBar[1] = TexMan.CheckForTexture("graphics/HUD/YnykronBarB.png",TexMan.Type_Any);
if ( !BoxSide[0] ) BoxSide[0] = TexMan.CheckForTexture("graphics/HUD/YnykronSideA.png",TexMan.Type_Any);
if ( !BoxSide[1] ) BoxSide[1] = TexMan.CheckForTexture("graphics/HUD/YnykronSideB.png",TexMan.Type_Any);
if ( !TewiFont ) TewiFont = Font.GetFont('TewiShaded');
Screen.DrawTexture(WeaponBox,false,bx-33,by-44,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
int chg = clamp(ChargeInter?ChargeInter.GetValue():int(chargelevel*10),0,400);
int ct = int(((by-2)-chg/10.)*hs.y);
Screen.DrawText(TewiFont,Font.CR_FIRE,bx-30,by-16,String.Format("%d",Ammo1.Amount),DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
Screen.DrawTexture(BoxSide[inverted],false,bx-23,by-31,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_ColorOverlay,clipcount?Color(0,0,0,0):Color(128,0,0,0));
Screen.DrawTexture(ChargeBar[inverted],false,bx-6,by-42,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_ColorOverlay,(chargestate==CS_READY)?Color(int(clamp(sin((level.maptime+TicFrac)*8)*40+24,0.,64.)),255,255,255):Color(0,0,0,0),DTA_ClipTop,ct);
}
override void HudTick()
{
if ( !ChargeInter ) ChargeInter = DynamicValueInterpolator.Create(int(chargelevel*10),.5,1,400);
ChargeInter.Update(int(chargelevel*10));
}
override bool ReportHUDAmmo()
{
return false;
if ( clipcount > 0 ) return true;
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) || (fireMode == AltFire) )
return ((clipcount > 0) || (Ammo1.Amount > 0));
return Super.CheckAmmo(firemode,autoswitch,requireammo,ammocount);
}
override void AttachToOwner( Actor other )
override void Travelled()
{
Super.AttachToOwner(other);
if ( other.player == players[consoleplayer] )
Console.Printf("\cgYNYKRON ARTIFACT NOT IMPLEMENTED\c-");
Super.Travelled();
if ( Owner.player && (Owner.player.Readyweapon == self) )
{
Owner.A_StartSound("ynykron/idle",CHAN_WEAPONEXTRA,CHANF_LOOPING,.3,4.);
if ( chargestate > CS_IDLE )
Owner.A_StartSound("ynykron/ready",CHAN_WEAPONEXTRA2,CHANF_LOOPING,(.025*chargelevel)**3.,2.);
}
}
action void A_YnykronFire()
{
A_StopSound(CHAN_WEAPONEXTRA2);
A_SWWMFlash();
A_Overlay(PSP_WEAPON+1,"FireSmoke");
A_OverlayFlags(PSP_WEAPON+1,PSPF_RENDERSTYLE|PSPF_ALPHA|PSPF_FORCESTYLE|PSPF_FORCEALPHA,true);
A_OverlayRenderStyle(PSP_WEAPON+1,STYLE_Add);
A_OverlayAlpha(PSP_WEAPON+1,0.);
invoker.chargestate = CS_IDLE;
invoker.clipcount = 0;
}
override void DoEffect()
{
Super.DoEffect();
if ( chargestate == CS_IDLE ) chargelevel = 0.;
else if ( chargestate == CS_CHARGING )
{
chargelevel = min(chargelevel*0.997+.16,40.);
if ( chargelevel >= 40. )
{
if ( (Owner.player.ReadyWeapon != self) && (Owner.player == players[consoleplayer]) )
Console.Printf(StringTable.Localize("$SWWM_YNYKRONREADY"));
chargestate = CS_READY;
ventcooldown = 0;
}
if ( Owner.player.ReadyWeapon == self )
Owner.A_SoundVolume(CHAN_WEAPONEXTRA2,(.025*chargelevel)**3.);
}
if ( Owner.player.ReadyWeapon != self ) return;
let pspm = Owner.player.FindPSprite(PSP_WEAPON);
if ( pspm )
{
double shiver = (chargelevel*.025)**2.;
pspm.x = FRandom[Shivers](-1.,1.)*shiver;
pspm.y = 32+FRandom[Shivers](-1.,1.)*shiver;
}
let psp = Owner.player.FindPSprite(PSP_WEAPON+1);
if ( !psp ) return;
ventalpha = clamp(ventalpha+ventfade,0.,1.);
psp.alpha = ventalpha;
if ( chargestate == CS_DISCHARGING )
{
chargelevel = max(chargelevel*1.005-.24,0.);
if ( chargelevel <= 0. ) chargestate = CS_IDLE;
if ( Owner.player.ReadyWeapon == self )
Owner.A_SoundVolume(CHAN_WEAPONEXTRA2,(.025*chargelevel)**3.);
}
}
Default
@ -30,6 +128,7 @@ Class Ynykron : SWWMWeapon
Obituary "$O_YNYKRON";
Weapon.SlotNumber 0;
Weapon.SelectionOrder 1000;
Weapon.UpSound "ynykron/select";
Stamina 5000000;
Weapon.AmmoType1 "YnykronAmmo";
Weapon.AmmoGive1 1;
@ -43,20 +142,247 @@ Class Ynykron : SWWMWeapon
XZW1 A -1;
Stop;
Select:
TNT1 A 1
XZW2 L 2
{
Console.Printf("\cgYNYKRON ARTIFACT NOT IMPLEMENTED\c-");
if ( player == players[consoleplayer] )
Console.Printf("\cgYNYKRON NOT YET FULLY IMPLEMENTED\c-");
invoker.ventcooldown = Random[Ynykron](6,15);
A_StartSound("ynykron/idle",CHAN_WEAPONEXTRA,CHANF_LOOPING,.3,4.);
if ( invoker.chargelevel > 0. )
A_StartSound("ynykron/ready",CHAN_WEAPONEXTRA2,CHANF_LOOPING,(.025*invoker.chargelevel)**3.,2.);
A_FullRaise();
}
XZW2 MNOPQRSTUVWXYZ 2;
XZW3 A 2;
Goto Ready;
Ready:
TNT1 A 1 A_WeaponReady();
XZW2 A 1
{
if ( invoker.chargestate == CS_DISCHARGING )
return ResolveState("Discharge");
int flg = WRF_ALLOWZOOM|WRF_ALLOWUSER1;
if ( (invoker.chargestate > CS_IDLE) || ((invoker.clipcount <= 0) && ((invoker.Ammo1.Amount > 1) || sv_infiniteammo || FindInventory('PowerInfiniteAmmo',true))) )
flg |= WRF_ALLOWRELOAD;
if ( (invoker.clipcount <= 0) || (invoker.chargestate > CS_IDLE) )
flg |= WRF_NOSECONDARY;
if ( invoker.chargestate == CS_CHARGING )
flg |= WRF_NOPRIMARY;
A_WeaponReady(flg);
if ( invoker.chargelevel >= 40. )
{
invoker.ventcooldown--;
if ( invoker.ventcooldown <= 0 )
return ResolveState("ReadyVent");
}
return ResolveState(null);
}
Wait;
ReadyVent:
XZW2 A 1
{
invoker.ventcooldown = Random[Ynykron](6,15)*5;
A_Overlay(PSP_WEAPON+1,"ReadyVentSmoke");
A_OverlayFlags(PSP_WEAPON+1,PSPF_RENDERSTYLE|PSPF_ALPHA|PSPF_FORCESTYLE|PSPF_FORCEALPHA,true);
A_OverlayRenderStyle(PSP_WEAPON+1,STYLE_Add);
A_OverlayAlpha(PSP_WEAPON+1,0.);
A_WeaponReady(WRF_NOFIRE|WRF_NOSWITCH);
}
XZWA ABCDEFGHI 2 A_WeaponReady(WRF_NOFIRE|WRF_NOSWITCH);
Goto Ready;
ReadyVentSmoke:
XZWB D 1
{
invoker.ventfade = .3;
}
XZWB EF 2;
XZWB G 2
{
invoker.ventfade = -.1;
}
XZWB HIJKLM 2;
Stop;
Fire:
TNT1 A 1;
XZW2 A 1
{
if ( (invoker.clipcount <= 0) && ((invoker.Ammo1.Amount > 1) || sv_infiniteammo || FindInventory('PowerInfiniteAmmo',true)) )
return ResolveState("Reload");
if ( invoker.chargestate == CS_IDLE )
return ResolveState("Charge");
A_YnykronFire();
return ResolveState(null);
}
XZW3 JK 2;
XZW3 LMNOPQR 3;
Goto Ready;
FireSmoke:
XZWA J 1
{
invoker.ventfade = .3;
}
XZWA KLMNO 2;
XZWA P 3
{
invoker.ventfade = -.1;
}
XZWA QRS 3;
Stop;
AltFire:
XZW2 A 2
{
A_StartSound("ynykron/meleestart",CHAN_WEAPON,CHANF_OVERLAP);
return A_JumpIf(invoker.inverted,"TakeInverted");
}
TakeNormal:
XZW3 STUVWXYZ 2;
XZW4 ABCDEFGHIJKLMNO 2;
XZW4 P 0
{
invoker.inverted = true;
}
Goto PutInverted;
TakeInverted:
XZW5 PQRSTUVWXYZ 2;
XZW6 ABCDEFGHIJKLM 2;
XZW6 N 0
{
invoker.inverted = false;
}
Goto PutNormal;
PutNormal:
XZW4 PQRSTUVWXYZ 2;
XZW5 A 2 A_StartSound("ynykron/meleeend",CHAN_WEAPON,CHANF_OVERLAP);
XZW5 BCDEFGHIJK 2;
XZW5 L 4;
Goto Ready;
PutInverted:
XZW6 NOPQRSTUVWXY 2;
XZW6 Z 2 A_StartSound("ynykron/meleeend",CHAN_WEAPON,CHANF_OVERLAP);
XZW7 ABCDEFGHIJ 2;
XZW7 K 4;
XZW5 P 0;
Goto Ready;
Discharge:
XZW2 A 2;
XZW7 NOP 2;
XZW7 Q 2
{
invoker.chargestate = CS_DISCHARGING;
A_Overlay(PSP_WEAPON+1,"DischargeSmoke");
A_OverlayFlags(PSP_WEAPON+1,PSPF_RENDERSTYLE|PSPF_ALPHA|PSPF_FORCESTYLE|PSPF_FORCEALPHA,true);
A_OverlayRenderStyle(PSP_WEAPON+1,STYLE_Add);
A_OverlayAlpha(PSP_WEAPON+1,0.);
A_WeaponReady(WRF_NOFIRE|WRF_NOSWITCH);
}
XZW7 RSTUV 2 A_WeaponReady(WRF_NOFIRE|WRF_NOSWITCH);
XZW7 W 2
{
A_WeaponReady(WRF_NOFIRE|WRF_NOSWITCH);
return A_JumpIf(invoker.chargestate==CS_IDLE,1);
}
Wait;
XZW7 W 3 A_WeaponReady(WRF_NOFIRE|WRF_NOSWITCH);
XZW7 XYZ 2 A_WeaponReady(WRF_NOFIRE|WRF_NOSWITCH);
Goto Ready;
DischargeSmoke:
XZWA T 2
{
invoker.ventfade = .3;
}
XZWA UVWXY 2;
XZWA Z 2 A_JumpIf(invoker.chargestate==CS_IDLE,1);
Wait;
XZWA Z 3
{
invoker.ventfade = -.1;
}
XZWB ABCD 2;
Stop;
Charge:
XZW2 A 2;
XZW3 BCDEFGHI 2;
XZW2 A 0
{
invoker.chargestate = CS_CHARGING;
A_StartSound("ynykron/ready",CHAN_WEAPONEXTRA2,CHANF_LOOPING,.01,2.);
}
Goto Ready;
Reload:
XZW2 A 2
{
if ( invoker.chargestate>CS_IDLE ) return ResolveState("Discharge");
if ( invoker.inverted ) return ResolveState("UnloadInverted");
A_StartSound("ynykron/meleestart",CHAN_WEAPON,CHANF_OVERLAP);
return ResolveState(null);
}
UnloadNormal:
XZW3 STUVWXYZ 2;
XZW4 ABCDEFGHIJKLMNO 2;
XZW4 P 0
{
if ( !sv_infiniteammo && !FindInventory('PowerInfiniteAmmo',true) )
invoker.Ammo1.Amount = max(invoker.Ammo1.Amount-1,0);
invoker.clipcount = 1;
invoker.inverted = false;
}
Goto PutNormal;
UnloadInverted:
XZW5 PQRSTUVWXYZ 2;
XZW6 ABCDEFGHIJKLM 2;
XZW6 N 0
{
if ( !sv_infiniteammo && !FindInventory('PowerInfiniteAmmo',true) )
invoker.Ammo1.Amount = max(invoker.Ammo1.Amount-1,0);
invoker.clipcount = 1;
invoker.inverted = false;
}
Goto PutNormal;
Zoom:
XZW2 A 2
{
invoker.ventcooldown = Random[Ynykron](6,15);
A_StartSound("ynykron/checkout",CHAN_WEAPON,CHANF_OVERLAP);
}
XZW8 ABCDEFGHIJKLMNOPQRSTUVW 2;
XZW8 X 4; // smoothen more
Goto Ready;
User1:
XZW2 A 2
{
invoker.ventcooldown = Random[Ynykron](6,15);
A_StartSound("ynykron/meleestart",CHAN_WEAPON,CHANF_OVERLAP);
A_StartSound("demolitionist/wswing",CHAN_WEAPON,CHANF_OVERLAP);
A_PlayerMelee();
}
XZW8 YZ 2;
XZW9 AB 2;
XZW9 C 1 A_Parry(9);
XZW9 DE 1;
XZW9 F 1 A_Melee(100,"demolitionist/whitl",1.5);
XZW9 GHIJK 1;
XZW9 LMNO 2;
XZW9 P 2 A_StartSound("ynykron/meleeend",CHAN_WEAPON,CHANF_OVERLAP);
XZW9 QRSTUVWXYZ 2;
Goto Ready;
Deselect:
TNT1 A -1 A_FullLower();
XZW2 A 2 A_StartSound("ynykron/deselect",CHAN_WEAPON,CHANF_OVERLAP);
XZW2 BCDEFGHIJK 2;
XZW2 L -1
{
A_StopSound(CHAN_WEAPONEXTRA);
A_StopSound(CHAN_WEAPONEXTRA2);
A_FullLower();
}
Stop;
Flash:
XZWZ A 2 Bright
{
let l = Spawn("SWWMWeaponLight",pos);
l.args[0] = 255;
l.args[1] = 255;
l.args[2] = 255;
l.args[3] = 500;
l.target = self;
}
Stop;
}
}

View file

@ -214,7 +214,7 @@ Class DeepImpact : SWWMWeapon
if ( !AmmoBar ) AmmoBar = TexMan.CheckForTexture("graphics/HUD/DeepImpactBar.png",TexMan.Type_Any);
Screen.DrawTexture(WeaponBox,false,bx-36,by-54,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
int chg = clamp(ChargeInter?ChargeInter.GetValue():clipcount,0,100);
int ct = int(((by-3)-(chg*50./100.))*hs.y);
int ct = int(((by-2)-(chg*50./100.))*hs.y);
Screen.DrawTexture(AmmoBar,false,bx-7,by-52,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_ClipTop,ct);
Screen.DrawText(TewiFont,Font.CR_FIRE,bx-35,by-13,String.Format("%3d%%",chg),DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
}

View file

@ -951,6 +951,7 @@ Class SWWMWeapon : Weapon abstract
{
Owner.A_StopSound(CHAN_WEAPON);
Owner.A_StopSound(CHAN_WEAPONEXTRA);
Owner.A_StopSound(CHAN_WEAPONEXTRA2);
Super.DetachFromOwner();
}
override void OwnerDied()
@ -959,6 +960,7 @@ Class SWWMWeapon : Weapon abstract
{
Owner.A_StopSound(CHAN_WEAPON);
Owner.A_StopSound(CHAN_WEAPONEXTRA);
Owner.A_StopSound(CHAN_WEAPONEXTRA2);
}
A_ClearRefire();
Super.OwnerDied();

View file

@ -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_FOOTSTEP,CHANF_OVERLAP);
d.HitActor.A_StartSound("pusher/meat",CHAN_DAMAGE,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_FOOTSTEP,CHANF_OVERLAP);
d.HitActor.A_StartSound("pusher/altmeat",CHAN_DAMAGE,CHANF_OVERLAP);
}
}
else

View file

@ -1518,8 +1518,6 @@ Class SWWMKnowledgeBaseMenu : GenericMenu
{
let type = (Class<Inventory>)(AllActorClasses[i]);
if ( !type ) continue;
// skip chanceboxes, since they're not yet implemented
if ( type is 'Chancebox' ) continue;
// no fabricators outside of hexen
if ( !(gameinfo.gametype&GAME_Hexen) && (type is 'AmmoFabricator') ) continue;
// skip maxed items

View file

@ -218,7 +218,6 @@ Class Demolitionist : PlayerPawn
{
let type = (class<Inventory>)(AllActorClasses[i]);
if ( !type ) continue;
if ( type is 'Chancebox' ) continue; // do not give these until they're fully implemented
if ( !(gameinfo.gametype&GAME_Hexen) && (type is 'AmmoFabricator') ) continue; // no fabricators outside of hexen
let def = GetDefaultByType (type);
if ( def.Icon.isValid() &&
@ -603,8 +602,8 @@ Class Demolitionist : PlayerPawn
if ( !CheckSight(a,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) ) continue;
// large monsters will stop the player (unless hit from above if we're going at ground pound speed)
A_QuakeEx(4,4,4,10,0,128,"",QF_RELATIVE|QF_SCALEDOWN);
A_StartSound("demolitionist/bump",CHAN_FOOTSTEP,CHANF_OVERLAP);
a.A_StartSound("demolitionist/bump",CHAN_FOOTSTEP,CHANF_OVERLAP);
A_StartSound("demolitionist/bump",CHAN_DAMAGE,CHANF_OVERLAP);
a.A_StartSound("demolitionist/bump",CHAN_DAMAGE,CHANF_OVERLAP);
if ( (diff.z < a.height) && (lastvelz >= -25) && (a.bDONTTHRUST || (a.Mass >= Mass*1.5)) )
{
if ( bumped ) continue;

View file

@ -1352,9 +1352,9 @@ Class TheBall : Actor
int whichclonk = Random[Spreadgun](1,11);
String snd = String.Format("misc/clonk%d",whichclonk);
A_AlertMonsters(2500);
A_StartSound(snd,CHAN_FOOTSTEP,CHANF_OVERLAP,1.,.2);
A_StartSound(snd,CHAN_VOICE,CHANF_OVERLAP,1.,.2);
victim.A_QuakeEx(8,8,8,8,0,3000,"",QF_RELATIVE|QF_SCALEDOWN,falloff:300,rollIntensity:1.);
victim.A_StartSound(snd,CHAN_FOOTSTEP,CHANF_OVERLAP,1.,.2);
victim.A_StartSound(snd,CHAN_DAMAGE,CHANF_OVERLAP,1.,.2);
slamforce *= 4;
dmg *= 4;
vel *= 1.1;
@ -1379,7 +1379,7 @@ Class TheBall : Actor
A_StartSound("spreadgun/ballf",CHAN_VOICE,CHANF_OVERLAP,(vel.length()/30.)**.5);
if ( victim )
{
victim.A_StartSound("spreadgun/ballf",CHAN_FOOTSTEP,CHANF_OVERLAP,(vel.length()/30.)**.5);
victim.A_StartSound("spreadgun/ballf",CHAN_DAMAGE,CHANF_OVERLAP,(vel.length()/30.)**.5);
victim.TraceBleed(dmg,self);
victim.SpawnBlood(pos,atan2(dir.y,dir.x),dmg);
}
@ -1387,7 +1387,7 @@ Class TheBall : Actor
else
{
A_StartSound("spreadgun/ball",CHAN_VOICE,CHANF_OVERLAP,(vel.length()/30.)**.5);
if ( victim ) victim.A_StartSound("spreadgun/ball",CHAN_FOOTSTEP,CHANF_OVERLAP,(vel.length()/30.)**.5);
if ( victim ) victim.A_StartSound("spreadgun/ball",CHAN_DAMAGE,CHANF_OVERLAP,(vel.length()/30.)**.5);
if ( vel.length() > 15. )
{
let s = Spawn("BallImpact",pos);
@ -2056,8 +2056,8 @@ 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_FOOTSTEP,CHANF_OVERLAP,1.,2.);
else t.HitList[i].HitActor.A_StartSound("spreadgun/pelletf",CHAN_FOOTSTEP,CHANF_OVERLAP,.4,4.);
if ( large ) t.HitList[i].HitActor.A_StartSound("spreadgun/slugf",CHAN_DAMAGE,CHANF_OVERLAP,1.,2.);
else t.HitList[i].HitActor.A_StartSound("spreadgun/pelletf",CHAN_DAMAGE,CHANF_OVERLAP,.4,4.);
}
}
if ( (t.Results.HitType != TRACE_HitNone) && (t.Results.HitType != TRACE_HasHitSky) && (t.Results.HitType != TRACE_HitActor) )

View file

@ -178,8 +178,13 @@ Class SilverBullet : SWWMWeapon
override bool CheckAmmo( int firemode, bool autoswitch, bool requireammo, int ammocount )
{
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
if ( (fireMode == PrimaryFire) || (fireMode == AltFire) )
{
// allow player to still use the zoom even if there's no ammo left
// (should work fine, assuming I've correctly interpreted the execution chain of all this stuff)
if ( autoswitch && (fireMode == AltFire) ) return true;
return ((chambered && !fired) || (clipcount > 0) || (Ammo1.Amount > 0));
}
return Super.CheckAmmo(firemode,autoswitch,requireammo,ammocount);
}
override void AttachToOwner( Actor other )
@ -257,7 +262,7 @@ Class SilverBullet : 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);
t.HitList[i].HitActor.A_StartSound("silverbullet/flesh",CHAN_FOOTSTEP,CHANF_OVERLAP,1.,2.);
t.HitList[i].HitActor.A_StartSound("silverbullet/flesh",CHAN_DAMAGE,CHANF_OVERLAP,1.,2.);
let p = Spawn("SilverImpact",t.HitList[i].HitLocation);
p.special1 = 1;
p.target = self;
@ -410,6 +415,7 @@ Class SilverBullet : SWWMWeapon
SilverBullet.ClipCount 5;
+SWWMWEAPON.NOFIRSTGIVE;
+WEAPON.NO_AUTO_SWITCH;
+WEAPON.ALT_AMMO_OPTIONAL;
}
States
{