Something I'm having trouble with is making weapon switching work within this system; since there's no way (that I know of) to let the player equip two weapons at the same time, I'm faking it with one mega weapon class that simply calls different states for each "weapon" you choose to equip. So, the number keys cycle "spells" while the Reload key cycles your physical weapon. The image below illustrates further. Number keys do technically change your active weapon, but these are only extra classes to define more fire states for your "spells" hand. Literally everything else is inherited from the master weapon class. The problem is that none of this weapon switching (either the "spells" hand or the Reload function for gun/sword) seem to be working, and the whole system in general feels pretty finnicky. The machinegun will often get stuck in a non-firing state if you mash keys together too quickly. Psprites are still kind of sorcery to me, and I only basically vaguely how the system works. Could someone more in-the-know check for any glaring flaws in this system? I'm sure there's a much better way to define this.
If the code below is too hard to troubleshoot, I also have a playable test level so you can try it firsthand. Mega thanks for any help!
Code: Select all
class SkrangWeapon : ComboFriendlyWeapon
{
//VARIABLES/////////////////////////////////////////////////////////////////////////////////////
bool weaponToggle;
bool shootRetry;
bool swingRetry;
bool spellRetry;
bool reloadRetry;
default
{
MeleeRange 60;
Weapon.Bobstyle "alpha";
Weapon.BobSpeed 1.5;
+WEAPON.NOAUTOAIM;
}
enum WeaponLayers
{
PSP_SPELLHAND = 1001,
PSP_WEAPONHAND = 1002,
};
//FUNCTIONS/////////////////////////////////////////////////////////////////////////////////////
override void PostBeginPlay()
{
swingRetry = 1;
shootRetry = 1;
spellRetry = 1;
weaponToggle = 1;
super.postbeginplay();
}
//STATES////////////////////////////////////////////////////////////////////////////////////////
states
{
Select:
CONE AA 0 ;
CONE A 1 a_raise;
loop;
Deselect:
CONE AA 0 ;
CONE A 1 a_lower;
loop;
Fire:
tnt1 a 0;
stop;
Ready:
tnt1 A 1
{
a_overlay(1001, "ReadySpell");
a_overlay(1002, "ReadyGun");
}
stop;
ReadyGun: //ready weapon hand
GRGN A 1
{
A_WeaponReady(WRF_NOFIRE | WRF_ALLOWRELOAD);
if (pressingFire() && invoker.shootRetry == 1)
SetWeaponState("GunFire", PSP_WEAPONHAND);
}
loop;
ReadySword: //ready sword hand
FSRD A 1
{
A_WeaponReady(WRF_NOFIRE | WRF_ALLOWRELOAD);
if (pressingFire() && invoker.swingRetry == 1)
SetWeaponState("SwordSwing", PSP_WEAPONHAND);
if (pressingUser1())
SetWeaponState("Block", PSP_WEAPONHAND);
}
loop;
ReadySpell: //ready spell hand
CONE A 1
{
A_WeaponReady(WRF_NOFIRE | WRF_ALLOWRELOAD);
if (pressingAltFire() && invoker.spellRetry == 1)
SetWeaponState("SpellFire", PSP_SPELLHAND);
}
loop;
SpellFire:
TNT1 a 0;
goto ready;
GunFire:
GRGN a 3 bright
{
invoker.shootRetry = 0;
A_FireBullets(5.1, 5.1, -1, 5, "BulletPuff");
A_StartSound("M3/fire");
A_gunflash("Gunflash");
}
GRGN a 3 bright
{
A_FireBullets(5.1, 5.1, -1, 5, "BulletPuff");
A_StartSound("M3/fire");
A_gunflash("Gunflash2");
invoker.shootRetry = 1;
}
GRGN a 0 A_StartSound("M3/end");
goto readyGun;
SwordSwing:
tnt1 a 0 { invoker.swingRetry = 0 ;}
TNT1 a 0
{
a_startsound("skeleton/swing");
a_overlay(4, "RECOIL");
}
FSRD fe 1;
FSRD ddef 1;
FSRD g 2 a_custompunch(10, 0, 0, "SwordPuff");
FSRD i 2;
FSRD j 2 { a_jumpifinventory("StunEffect", 1, "stunned"); }
FSRD abc 2;
tnt1 a 0 { invoker.swingRetry = 1 ;}
goto readySword;
Block:
FSRD f 8
{
a_clearoverlays(6, 7);
let Player = SkrangPlayer(invoker.owner);
if (Player)
player.IsBlocking = true;
}
FSRD d 7
{
let Player = SkrangPlayer(invoker.owner);
if (Player)
player.IsBlocking = false;
}
goto ReadySword;
Stunned:
BLOC a 2
{
a_takeinventory("stuneffect", 1);
a_recoil(10);
}
BLOC bcde 2;
goto ReadySword;
Reload:
TNT1 a 1
{
if (invoker.weaponToggle == 1)
{
invoker.weaponToggle = 0;
Console.Midprint("bigfont", "Sword Selected");
setWeaponState("readysword", PSP_WEAPONHAND);
}
else if (invoker.weaponToggle == 0)
{
invoker.weaponToggle = 1;
Console.Midprint("bigfont", "Machinegun Selected");
setWeaponState("readygun", PSP_WEAPONHAND);
}
}
goto ready;
GunFlash:
FLSH A 1 bright;
stop;
GunFlash2:
FLSH B 1 bright;
stop;
Recoil:
//raise
tnt1 a 1 a_setpitch(pitch - .07, SPF_INTERPOLATE);
tnt1 a 1 a_setpitch(pitch - .02, SPF_INTERPOLATE);
tnt1 a 1 a_setpitch(pitch - .01, SPF_INTERPOLATE);
tnt1 a 1
{
a_setpitch(pitch + .1, SPF_INTERPOLATE);
a_setangle(angle - 0.1);
}
tnt1 a 1
{
a_setpitch(pitch + .2, SPF_INTERPOLATE);
a_setangle(angle - 0.1);
}
tnt1 a 1
{
a_setpitch(pitch + .15, SPF_INTERPOLATE);
a_setangle(angle - 0.1);
}
tnt1 a 1 a_setpitch(pitch + .25, SPF_INTERPOLATE);
tnt1 a 1 a_setpitch(pitch + .2, SPF_INTERPOLATE);
tnt1 a 1 a_setpitch(pitch + .1, SPF_INTERPOLATE);
//lower
tnt1 a 1
{
a_setpitch(pitch - .2, SPF_INTERPOLATE);
a_setangle(angle + 0.1);
}
tnt1 a 1
{
a_setpitch(pitch - .15, SPF_INTERPOLATE);
a_setangle(angle + 0.1);
}
tnt1 a 1
{
a_setpitch(pitch - .15, SPF_INTERPOLATE);
a_setangle(angle + 0.1);
}
tnt1 a 1 a_setpitch(pitch - .10, SPF_INTERPOLATE);
tnt1 a 1 a_setpitch(pitch - .10, SPF_INTERPOLATE);
tnt1 a 1 a_setpitch(pitch - .05, SPF_INTERPOLATE);
tnt1 a 1 a_setpitch(pitch - .05, SPF_INTERPOLATE);
stop;
}
}
CLASS EnergySpell : SkrangWeapon
{
DEFAULT
{
Tag "Magic Missile";
}
STATES
{
SpellFire:
CONE abcd 1;
CONE e 5 a_fireplasma;
CONE fgha 2;
goto ReadySpell;
}
}
class FireSpell : SkrangWeapon
{
DEFAULT
{
Tag "Fire Blast";
}
STATES
{
SpellFire: //fireball spell
CONE abcd 1;
FireballHold:
CONE D 2 a_fireprojectile("skrangfireball",random(-6,6),0,-6.0,0,0,random(-3,3));
CONE e 1;
CONE f 2 { if(pressingaltfire()) setWeaponState("Fireballhold",PSP_SPELLHAND); }
FireballEnd:
CONE gha 2;
goto ReadySpell;
}
}