swwmgz_m/zscript/handler/swwm_handler_process.zsc

636 lines
25 KiB
Text

// event processing
extend Class SWWMHandler
{
// for menu events
transient Array<MenuTransaction> checklist;
override void ConsoleProcess( ConsoleEvent e )
{
// doing it with an event because this way we can control WHEN it should be openable
if ( e.Name ~== "swwmdemomenu" )
{
if ( (gamestate != GS_LEVEL) || (players[consoleplayer].Health <= 0) || !(players[consoleplayer].mo is 'Demolitionist') )
return;
if ( !(Menu.GetCurrentMenu() is 'DemolitionistMenu') )
Menu.SetMenu('DemolitionistMenu');
}
else if ( e.Name ~== "swwmzoomin" )
{
if ( (gamestate != GS_LEVEL) || (players[consoleplayer].Health <= 0) || !(players[consoleplayer].mo is 'Demolitionist') )
return;
double val = swwm_mm_zoom;
if ( val > 1. ) val = max(1.,val-.5);
else val = max(.5,val-.25);
CVar.FindCVar('swwm_mm_zoom').SetFloat(val);
}
else if ( e.Name ~== "swwmzoomout" )
{
if ( (gamestate != GS_LEVEL) || (players[consoleplayer].Health <= 0) || !(players[consoleplayer].mo is 'Demolitionist') )
return;
double maxval = level.allmap?2.:1.;
double val = swwm_mm_zoom;
if ( val >= 1. ) val = min(maxval,val+.5);
else val = min(1.,val+.25);
CVar.FindCVar('swwm_mm_zoom').SetFloat(val);
}
}
override void NetworkProcess( ConsoleEvent e )
{
static const Class<Ammo> cbttypes[] = {"RedShell","GreenShell","BlueShell","PurpleShell"};
if ( e.Name ~== "swwmgesture" )
{
if ( (e.player == -1) || !playeringame[e.player] || !players[e.player].mo ) return;
let mo = players[e.player].mo;
switch( e.Args[0] )
{
case 0:
SWWMGesture.SetGesture(mo,GS_Wave);
break;
case 1:
SWWMGesture.SetGesture(mo,GS_ThumbsUp);
break;
case 2:
SWWMGesture.SetGesture(mo,GS_Victory);
break;
case 3:
SWWMGesture.SetGesture(mo,GS_BlowKiss);
break;
}
return;
}
else if ( e.Name ~== "swwmsetwalk" )
{
if ( (e.player == -1) || !playeringame[e.player] || !players[e.player].mo ) return;
let mo = Demolitionist(players[e.player].mo);
if ( mo ) mo.bWalking = e.Args[0];
return;
}
else if ( e.Name ~== "swwmfixitemcaps" )
{
// this command is only really needed when I update item max amounts mid-playthrough
if ( multiplayer && (e.player != Net_Arbitrator) )
{
if ( e.player == consoleplayer )
Console.Printf("Only the net arbitrator can call this event.");
return;
}
for ( int i=0; i<MAXPLAYERS; i++ )
{
if ( !playeringame[i] || !players[i].mo ) continue;
let mo = players[i].mo;
Inventory hams = mo.FindInventory("HammerspaceEmbiggener");
if ( hams )
{
if ( hams.MaxAmount != hams.default.MaxAmount )
Console.Printf("Adjust %s capacity (%d -> %d)",hams.GetTag(),hams.MaxAmount,hams.default.MaxAmount);
hams.MaxAmount = hams.default.MaxAmount;
hams.Amount = min(hams.Amount,hams.MaxAmount);
}
for ( Inventory inv=mo.inv; inv; inv=inv.inv )
{
if ( inv is 'Ammo' )
{
Ammo(inv).BackpackMaxAmount = Ammo(inv).default.BackpackMaxAmount;
int newmax = inv.default.MaxAmount;
if ( (hams.Amount > 0) && (Ammo(inv).BackpackMaxAmount > 0) )
{
double factor = (Ammo(inv).BackpackMaxAmount-inv.default.MaxAmount)/double(hams.MaxAmount);
newmax = int(inv.default.MaxAmount+hams.Amount*factor);
}
if ( inv.MaxAmount != newmax )
Console.Printf("Adjust %s capacity (%d -> %d)",inv.GetTag(),inv.MaxAmount,newmax);
int dropme = max(0,inv.Amount-newmax);
if ( dropme )
{
Console.Printf("Dropped %dx %s.",dropme,inv.GetTag());
// non-SWWM ammos won't subdivide, but whatever, this is a debug command
inv.CreateTossable(dropme);
}
inv.MaxAmount = newmax;
}
else if ( inv is 'MagAmmo' )
{
if ( inv.MaxAmount != inv.default.MaxAmount )
Console.Printf("Adjust %s capacity (%d -> %d)",inv.GetTag(),inv.MaxAmount,inv.default.MaxAmount);
// just drop the extras
int dropme = max(0,inv.Amount-inv.default.MaxAmount);
if ( dropme )
{
Console.Printf("Dropped %dx %s.",dropme,inv.GetTag());
inv.CreateTossable(dropme);
}
inv.MaxAmount = inv.default.MaxAmount;
}
else
{
if ( inv.MaxAmount != inv.default.MaxAmount )
Console.Printf("Adjust %s capacity (%d -> %d)",inv.GetTag(),inv.MaxAmount,inv.default.MaxAmount);
// only drop droppables (obviously)
if ( !inv.bUNDROPPABLE && !inv.bUNTOSSABLE )
{
int dropme = max(0,inv.Amount-inv.default.MaxAmount);
if ( dropme )
{
Console.Printf("Dropped %dx %s.",dropme,inv.GetTag());
for ( int j=0; j<dropme; j++ ) inv.CreateTossable(j);
}
}
inv.MaxAmount = inv.default.MaxAmount;
inv.Amount = min(inv.Amount,inv.MaxAmount);
}
}
}
}
else if ( e.Name ~== "swwmupdatetrackers" )
{
if ( multiplayer && (e.player != Net_Arbitrator) )
{
if ( e.player == consoleplayer )
Console.Printf("Only the net arbitrator can call this event.");
return;
}
if ( swwm_notrack )
{
int n = trackers_cnt;
while ( trackers )
{
let next = trackers.next;
trackers.Destroy(); // wow that's simple, all in one line
trackers = next;
}
trackers_cnt = 0;
Console.Printf("%d trackers removed.",n);
}
else
{
int n = trackers_cnt;
let ti = ThinkerIterator.Create("Actor");
Actor a;
while ( a = Actor(ti.Next()) )
{
if ( (!a.bSHOOTABLE && !a.bISMONSTER) || (a is 'LampMoth') || (a is 'CompanionLamp') ) continue;
let trk = SWWMCombatTracker.Spawn(a,true);
if ( !a.player ) trk.maxhealth = max(a.health,a.GetSpawnHealth());
}
n = (trackers_cnt-n);
Console.Printf("%d trackers added.",n);
}
return;
}
else if ( e.Name ~== "swwmtrimsuckables" )
{
if ( multiplayer && (e.player != Net_Arbitrator) )
{
if ( e.player == consoleplayer )
Console.Printf("Only the net arbitrator can call this event.");
return;
}
int n = 0;
for ( int i=0; i<suckableactors.Size(); i++ )
{
if ( suckableactors[i] && (suckableactors[i].bSHOOTABLE || suckableactors[i].bMISSILE) ) continue;
suckableactors.Delete(i);
i--;
n++;
}
Console.Printf("%d suckable actors trimmed.",n);
return;
}
else if ( e.Name ~== "swwmcleareffects" )
{
if ( multiplayer && (e.player != Net_Arbitrator) )
{
if ( e.player == consoleplayer )
Console.Printf("Only the net arbitrator can call this event.");
return;
}
int n = casings_cnt+chips_cnt+blods_cnt+meats_cnt;
CleanQueues();
Console.Printf("%d effects cleared.",n);
return;
}
else if ( e.Name ~== "swwmdebugdumprng" )
{
if ( multiplayer && (e.player != Net_Arbitrator) )
{
if ( e.player == consoleplayer )
Console.Printf("Only the net arbitrator can call this event.");
return;
}
// dump the values of all mod RNGs (might help someday to track down what desyncs)
String msg = String.Format("\cxRNG dump for player %d (\c-%s\cx):\c-",consoleplayer,players[consoleplayer].GetUserName());
msg.AppendFormat("\n\n\cfPlay RNG (will cause desyncs if mismatched):\c-\n");
msg.AppendFormat("\nBlood: %08x",Random2[Blood]());
msg.AppendFormat("\nBoolet: %08x",Random2[Boolet]());
msg.AppendFormat("\nBundle: %08x",Random2[Bundle]());
msg.AppendFormat("\nCandy: %08x",Random2[Candy]());
msg.AppendFormat("\nChancebox: %08x",Random2[Chancebox]());
msg.AppendFormat("\nCorrode: %08x",Random2[Corrode]());
msg.AppendFormat("\nDemolitionist: %08x",Random2[Demolitionist]());
msg.AppendFormat("\nDoBlast: %08x",Random2[DoBlast]());
msg.AppendFormat("\nDropChance: %08x",Random2[DropChance]());
msg.AppendFormat("\nEviscerator: %08x",Random2[Eviscerator]());
msg.AppendFormat("\nExplodium: %08x",Random2[Explodium]());
msg.AppendFormat("\nExploS: %08x",Random2[ExploS]());
msg.AppendFormat("\nExtraMissiles: %08x",Random2[ExtraMissiles]());
msg.AppendFormat("\nFlameT: %08x",Random2[FlameT]());
msg.AppendFormat("\nFlicker: %08x",Random2[Flicker]());
msg.AppendFormat("\nGesture: %08x",Random2[Gesture]());
msg.AppendFormat("\nGibs: %08x",Random2[Gibs]());
msg.AppendFormat("\nGoldDrop: %08x",Random2[GoldDrop]());
msg.AppendFormat("\nGoldy: %08x",Random2[Goldy]());
msg.AppendFormat("\nGunFlash: %08x",Random2[GunFlash]());
msg.AppendFormat("\nHellblazer: %08x",Random2[Hellblazer]());
msg.AppendFormat("\nImpact: %08x",Random2[Impact]());
msg.AppendFormat("\nInvinciball: %08x",Random2[Invinciball]());
msg.AppendFormat("\nJunk: %08x",Random2[Junk]());
msg.AppendFormat("\nMoth: %08x",Random2[Moth]());
msg.AppendFormat("\nMykradvo: %08x",Random2[Mykradvo]());
msg.AppendFormat("\nNugget: %08x",Random2[Nugget]());
msg.AppendFormat("\nParry: %08x",Random2[Parry]());
msg.AppendFormat("\nPonch: %08x",Random2[Ponch]());
msg.AppendFormat("\nPuff: %08x",Random2[Puff]());
msg.AppendFormat("\nPusher: %08x",Random2[Pusher]());
msg.AppendFormat("\nRage: %08x",Random2[Rage]());
msg.AppendFormat("\nReplacements: %08x",Random2[Replacements]());
msg.AppendFormat("\nShellDrop: %08x",Random2[ShellDrop]());
msg.AppendFormat("\nShivers: %08x",Random2[Shivers]());
msg.AppendFormat("\nSilverbullet: %08x",Random2[Silverbullet]());
msg.AppendFormat("\nSpareShells: %08x",Random2[SpareShells]());
msg.AppendFormat("\nSparkster: %08x",Random2[Sparkster]());
msg.AppendFormat("\nSpread: %08x",Random2[Spread]());
msg.AppendFormat("\nSpreadgun: %08x",Random2[Spreadgun]());
msg.AppendFormat("\nWallbuster: %08x",Random2[Wallbuster]());
msg.AppendFormat("\nYnykron: %08x",Random2[Ynykron]());
msg.AppendFormat("\n\n\cfUI RNG (should not cause desyncs if mismatched):\c-\n");
msg.AppendFormat("\nbdscreen: %08x",Random2[bdscreen]());
msg.AppendFormat("\nClientSparkles: %08x",Random2[ClientSparkles]());
msg.AppendFormat("\nDemoLines: %08x",Random2[DemoLines]());
msg.AppendFormat("\nFInTheChat: %08x",Random2[FInTheChat]());
msg.AppendFormat("\nFunTags: %08x",Random2[FunTags]());
msg.AppendFormat("\nhdscreen: %08x",Random2[hdscreen]());
msg.AppendFormat("\nHudStuff: %08x",Random2[HudStuff]());
msg.AppendFormat("\nInterArt: %08x",Random2[InterArt]());
msg.AppendFormat("\nScoreBits: %08x",Random2[ScoreBits]());
msg.AppendFormat("\nTUID: %08x",Random2[TUID]());
msg.AppendFormat("\nUIStuff: %08x",Random2[UIStuff]());
msg.AppendFormat("\nWallbusterMenu: %08x",Random2[WallbusterMenu]());
Console.Printf(msg);
return;
}
else if ( e.Name ~== "swwmdebugdlglines" )
{
if ( multiplayer && (e.player != Net_Arbitrator) )
{
if ( e.player == consoleplayer )
Console.Printf("Only the net arbitrator can call this event.");
return;
}
// checks that ALL dialogue text fits in 3 lines
String alldlg_pack = "SWWM_SAYAPHOBOS1:SWWM_SAYAPHOBOS2:SWWM_SAYAPHOBOS3:SWWM_SAYAPHOBOS4:SWWM_SAYADEIMOS1:SWWM_SAYADEIMOS2:SWWM_SAYADEIMOS3:SWWM_SAYADEIMOS4:SWWM_SAYADIS1:SWWM_SAYADIS2:SWWM_SAYADIS3:SWWM_SAYADIS4:SWWM_SAYATHY1:SWWM_SAYATHY2:SWWM_SAYATHY3:SWWM_SAYATHY4:SWWM_CYTHOSIGIL1:SWWM_CYTHOSIGIL2:SWWM_CYTHOSIGIL3:SWWM_CYTHOSIGIL4:SWWM_SAYADIMPLE1:SWWM_SAYADIMPLE2:SWWM_SAYADIMPLE3:SWWM_SAYADIMPLE4:SWWM_SAYADIMPLE5:SWWM_SAYACIRCLE1:SWWM_SAYACIRCLE2:SWWM_SAYACIRCLE3:SWWM_SAYACIRCLE4:SWWM_SAYACIRCLE5:SWWM_SAYAGOTCHA1:SWWM_SAYAGOTCHA2:SWWM_SAYAGOTCHA3:SWWM_SAYAGOTCHA4:SWWM_SAYAGOTCHA5:SWWM_SAYAGOTCHAEND1:SWWM_SAYAGOTCHAEND2:SWWM_SAYAGOTCHAEND3:SWWM_SAYAGOTCHAEND4:SWWM_SAYAGOTCHAEND5:SWWM_SAYAIOS1:SWWM_SAYAIOS2:SWWM_SAYAIOS3:SWWM_SAYAIOS4:SWWM_SAYAIOS5:SWWM_SAYARAMPANCY1:SWWM_SAYARAMPANCY2:SWWM_SAYARAMPANCY3:SWWM_SAYARAMPANCY4:SWWM_CYTHONERVE1:SWWM_CYTHONERVE2:SWWM_CYTHONERVE3:SWWM_CYTHONERVE4:SWWM_CYTHONERVE5:SWWM_SAYAEVIA1:SWWM_SAYAEVIA2:SWWM_SAYAEVIA3:SWWM_SAYAEVIA4:SWWM_SAYAEVIB1:SWWM_SAYAEVIB2:SWWM_SAYAMAW1:SWWM_SAYAMAW2:SWWM_SAYAMAW3:SWWM_SAYAMAW4:SWWM_SAYAMAW5:SWWM_SAYAMASTERS1:SWWM_SAYAMASTERS2:SWWM_SAYAMASTERS3:SWWM_SAYAMASTERS4:SWWM_SAYAMASTERS5:SWWM_SAYADSPARIL1:SWWM_SAYADSPARIL2:SWWM_SAYADSPARIL3:SWWM_SAYADSPARIL4:SWWM_SAYADSPARIL5:SWWM_SAYAHEADS1:SWWM_SAYAHEADS2:SWWM_SAYAHEADS3:SWWM_SAYAHEADS4:SWWM_SAYAHEADS5:SWWM_SAYAHEADS6:SWWM_SAYABULLS1:SWWM_SAYABULLS2:SWWM_SAYABULLS3:SWWM_SAYABULLS4:SWWM_SAYABULLS5:SWWM_SAYAGREETA1:SWWM_SAYAGREETA2:SWWM_SAYAGREETA3:SWWM_SAYAGREETB1:SWWM_SAYAGREETC1:SWWM_SAYAGREETD1:SWWM_SAYAGREETE1:SWWM_SAYAGREETF1:SWWM_SAYABLOODA1:SWWM_SAYABLOODA2:SWWM_SAYABLOODB1:SWWM_SAYABLOODC1:SWWM_SAYABLOODD1:SWWM_SAYAHYPO1:SWWM_SAYAHYPO2:SWWM_SAYAHYPO3:SWWM_SAYAHYPO4:SWWM_KIRINWORSHIPA1:SWWM_KIRINWORSHIPB1:SWWM_KIRINWORSHIPC1:SWWM_KIRINWORSHIPD1:SWWM_KIRINWORSHIPD2:SWWM_SAYAGAMEA1:SWWM_SAYAGAMEA2:SWWM_SAYAGAMEB1:SWWM_SAYAGAMEC1:SWWM_SAYAMASTERSA1:SWWM_SAYAMASTERSA2:SWWM_SAYAMASTERSB1:SWWM_SAYAMASTERSC1:SWWM_SAYAMASTERSD1:SWWM_SAYAMASTERSE1:SWWM_SAYAMASTERSF1:SWWM_SAYAFIGHTER1:SWWM_SAYAFIGHTER2:SWWM_SAYACLERICA1:SWWM_SAYACLERICA2:SWWM_SAYACLERICB1:SWWM_SAYACLERICC1:SWWM_SAYACLERICC2:SWWM_SAYAMAGE1:SWWM_SAYAMAGE2:SWWM_SAYAMAGE3:SWWM_SAYAMAGE4:SWWM_SAYAKORAXA1:SWWM_SAYAKORAXB1:SWWM_SAYAKORAXC1:SWWM_SAYAKORAXD1:SWWM_SAYAKORAXE1:SWWM_SAYABLIGHTA1:SWWM_SAYABLIGHTB1:SWWM_SAYABLIGHTC1:SWWM_SAYABLIGHTC2:SWWM_SAYACONSTABLEA1:SWWM_SAYACONSTABLEA2:SWWM_SAYACONSTABLEB1:SWWM_SAYACONSTABLEC1:SWWM_SAYACONSTABLED1:SWWM_SAYANAVEA1:SWWM_SAYANAVEA2:SWWM_SAYANAVEB1:SWWM_SAYANAVEC1:SWWM_SAYANAVED1:SWWM_SAYANAVEE1:SWWM_SAYANAVEF1:SWWM_SAYADEATHKINGS1:SWWM_KIRINPUZZLEA1:SWWM_KIRINPUZZLEA2:SWWM_KIRINPUZZLEB1:SWWM_KIRINPUZZLEC1:SWWM_KIRINPUZZLEC2:SWWM_KIRINPUZZLED1:SWWM_KIRINPUZZLED2:SWWM_KIRINPUZZLEE1:SWWM_KIRINPUZZLEE2:SWWM_KIRINPUZZLEF1:SWWM_KIRINPUZZLEF2:SWWM_KIRINPUZZLEF3:SWWM_KIRINPUZZLEG1:SWWM_KIRINPUZZLEH1:SWWM_KIRINPUZZLEI1:SWWM_KIRINPUZZLEI2:SWWM_KIRINPUZZLEJ1:SWWM_KIRINPUZZLEJ2:SWWM_KIRINPUZZLEK1:SWWM_KIRINPUZZLEL1:SWWM_KIRINPUZZLEM1:SWWM_KIRINPUZZLEN1:SWWM_KIRINPUZZLEO1:SWWM_KIRINPUZZLEP1:SWWM_KIRINPUZZLEQ1:SWWM_KIRINPUZZLER1:SWWM_KIRINPUZZLER2:SWWM_KIRINPUZZLER3:SWWM_KIRINPUZZLES1:SWWM_KIRINPUZZLET1:SWWM_KIRINPUZZLEU1:SWWM_ZNVTXT1:SWWM_ZNVTXT2:SWWM_ZNVTXT3:SWWM_ZNVTXT4:SWWM_ZNVTXT5";
Array<String> alldlg;
alldlg_pack.Split(alldlg,":");
let mSmallFont = Font.GetFont('TewiFont');
for ( int i=0; i<alldlg.Size(); i++ )
{
let l = mSmallFont.BreakLines(StringTable.Localize(alldlg[i],false),220);
if ( l.Count() > 3 ) Console.Printf("\cg%s exceeds line limit (%d > 3)\c-",alldlg[i],l.Count());
else
{
if ( !e.Args[0] )
{
l.Destroy();
continue;
}
Console.Printf("\cd%s is within line limit (%d <= 3)\c-",alldlg[i],l.Count());
}
for ( int j=0; j<l.Count(); j++ ) Console.Printf("> %s",l.StringAt(j));
l.Destroy();
}
return;
}
else if ( e.Name ~== "swwmprofilehandler" )
{
if ( multiplayer && (e.player != Net_Arbitrator) )
{
if ( e.player == consoleplayer )
Console.Printf("Only the net arbitrator can call this event.");
return;
}
bprofiletics = profiletics = (e.Args[0]<=0)?10:e.Args[0];
profiling = true;
for ( int i=0; i<8; i++ )
{
prof_ms[i] = 0;
prof_avg[i] = 0;
prof_calls[i] = 0;
}
Console.Printf("Gathering data for %d tic%s...",bprofiletics,(bprofiletics>1)?"s":"");
return;
}
if ( e.IsManual ) return;
if ( e.Name.Left(14) ~== "swwmstoregive." )
{
Class<Inventory> item = e.Name.Mid(14);
if ( !item ) return;
if ( SWWMCredits.Take(players[e.Args[0]],e.Args[1]) )
{
let def = GetDefaultByType(item);
SWWMWeapon sw;
// drop the swapweapon if we own it first
if ( swwm_swapweapons && (item is 'SWWMWeapon') && (sw = SWWMWeapon(def).HasSwapWeapon(players[e.Args[0]].mo)) )
{
// special case, otherwise candy gun won't drop itself
if ( sw is 'CandyGun' ) CandyGun(sw).swapdrop = true;
bool swapto = (sw == players[e.Args[0]].ReadyWeapon) || (sw.SisterWeapon && (sw.Sisterweapon == players[e.Args[0]].ReadyWeapon));
int ngun = sw.Amount;
if ( ngun == 2 )
{
// create a dual giver to drop
let dg = SWWMDualWeaponGiver(Actor.Spawn("SWWMDualWeaponGiver",players[e.Args[0]].mo.pos+(0,0,10)));
dg.angle = players[e.Args[0]].mo.angle;
dg.VelFromAngle(5.);
dg.vel.z += 1.;
dg.vel += players[e.Args[0]].mo.vel;
// transfer both guns
dg.giveme[0] = SWWMWeapon(sw.CreateTossable(1));
dg.giveme[0].AttachToOwner(dg);
dg.giveme[1] = SWWMWeapon(sw.CreateTossable(1));
dg.giveme[1].AttachToOwner(dg);
dg.SetPickupState();
}
else players[e.Args[0]].mo.DropInventory(sw); // just drop it
// don't autoswitch just yet (hacky)
if ( swapto )
{
players[e.Args[0]].ReadyWeapon = null;
players[e.Args[0]].PendingWeapon = WP_NOCHANGE;
}
}
if ( (item is 'ArmorNuggetItem') || (item is 'HealthNuggetItem') )
{
// these have to be given in a loop because fun reasons
for ( int i=0; i<e.Args[2]; i++ )
players[e.Args[0]].mo.GiveInventory(item,1,true);
}
else players[e.Args[0]].mo.GiveInventory(item,e.Args[2],true);
// fucky workaround
let inv = players[e.Args[0]].mo.FindInventory(item);
if ( inv && (inv.Amount <= 0) && !inv.bKEEPDEPLETED ) inv.Destroy();
if ( item is 'Weapon' )
{
// special case, select dual guns if we bought a second one
if ( (item is 'ExplodiumGun') && (players[e.Args[0]].mo.CountInv("ExplodiumGun") > 1) )
players[e.Args[0]].mo.A_SelectWeapon("DualExplodiumGun");
else players[e.Args[0]].mo.A_SelectWeapon((Class<Weapon>)(item));
}
}
}
else if ( e.Name.Left(14) ~== "swwmstoretake." )
{
Class<Inventory> item = e.Name.Mid(14);
if ( !item ) return;
int amt = e.Args[2];
if ( item is 'CandyGun' )
{
// check if we can sell a spare instead, for the same price
int n = players[e.Args[0]].mo.CountInv('CandyGunSpares');
if ( n >= amt )
{
players[e.Args[0]].mo.TakeInventory('CandyGunSpares',amt);
SWWMCredits.Give(players[e.Args[0]],e.Args[1]);
return;
}
}
// if player currently has the dual wield weapon selected, switch over
if ( item is 'SWWMWeapon' )
{
let c = Weapon(players[e.Args[0]].mo.FindInventory(item));
if ( c.SisterWeapon && (players[e.Args[0]].ReadyWeapon == c.SisterWeapon) )
{
players[e.Args[0]].ReadyWeapon = c;
players[e.Args[0]].SetPSprite(PSP_WEAPON,c.FindState("Ready"));
players[e.Args[0]].SetPSprite(PSP_WEAPON+1,null); // delete left weapon psprite
}
}
// if we're selling an embiggener, we need to readjust ammo
if ( item is 'HammerspaceEmbiggener' )
{
let ritm = players[e.Args[0]].mo.FindInventory(item);
for ( Inventory i=players[e.Args[0]].mo.Inv; i; i=i.Inv )
{
if ( !(i is 'Ammo') ) continue;
if ( Ammo(i).BackpackMaxAmount > 0 )
{
double factor = (Ammo(i).BackpackMaxAmount-i.default.MaxAmount)/double(ritm.MaxAmount);
i.MaxAmount = int(i.default.MaxAmount+(ritm.Amount-amt)*factor);
}
// drop excess ammo
int excess = i.Amount-i.MaxAmount;
if ( excess > 0 ) i.CreateTossable(excess);
}
}
players[e.Args[0]].mo.TakeInventory(item,amt);
SWWMCredits.Give(players[e.Args[0]],e.Args[1]);
}
else if ( e.Name.Left(17) ~== "swwmmarkloreread." )
{
let l = SWWMLoreLibrary.Find(players[e.Args[0]]);
let idx = l.FindEntry(e.Name.Mid(17));
l.MarkRead(idx);
}
else if ( e.Name.Left(12) ~== "swwmuseitem." )
{
Class<Inventory> item = e.Name.Mid(12);
if ( !item ) return;
let i = players[e.Args[0]].mo.FindInventory(item);
if ( !i ) return;
bool rslt = players[e.Args[0]].mo.UseInventory(i);
if ( e.Args[0] == consoleplayer )
{
let t = new("MenuTransaction");
t.uid = e.Args[1];
t.type = MenuTransaction.TT_ITEMUSE;
let w = (Class<Weapon>)(item);
if ( w )
{
t.result = (players[e.Args[0]].PendingWeapon==Weapon(i));
// dual wield gun support
if ( (i is 'SWWMWeapon') && (players[e.Args[0]].PendingWeapon==Weapon(i).SisterWeapon) )
t.result = true;
}
else t.result = rslt;
t.used = item;
t.usedup = (!i||(i.Amount<=0));
checklist.Push(t);
}
}
else if ( e.Name.Left(13) ~== "swwmdropitem." )
{
Class<Inventory> item = e.Name.Mid(13);
if ( !item ) return;
let i = players[e.Args[0]].mo.FindInventory(item);
if ( !i ) return;
int amt = i.default.Amount;
// if it's an ammo, check the largest unit givable
if ( i is 'Ammo' )
{
for ( int i=0; i<AllActorClasses.Size(); i++ )
{
let a = (Class<Ammo>)(AllActorClasses[i]);
if ( !a || (a.GetParentClass() != item) || (GetDefaultByType(a).Amount < amt) ) continue;
amt = GetDefaultByType(a).Amount;
}
}
if ( i is 'MagAmmo' )
{
for ( int i=0; i<AllActorClasses.Size(); i++ )
{
let a = (Class<MagAmmo>)(AllActorClasses[i]);
if ( !a || (a.GetParentClass() != item) || (GetDefaultByType(a).Amount < amt) ) continue;
amt = GetDefaultByType(a).Amount;
}
}
if ( amt > i.Amount ) amt = i.Amount;
let drop = players[e.Args[0]].mo.DropInventory(i,amt);
// add some random velocity so multiple drops don't get bunched together
if ( drop ) drop.vel += (Actor.RotateVector((FRandom[Junk](-1.5,.5),FRandom[Junk](-2.5,2.5)),players[e.Args[0]].mo.angle),FRandom[Junk](2.,5.));
if ( e.Args[0] == consoleplayer )
{
let t = new("MenuTransaction");
t.uid = e.Args[1];
t.type = MenuTransaction.TT_ITEMDROP;
t.used = item;
t.result = drop;
t.usedup = (!i||(i.Amount<=0));
checklist.Push(t);
}
}
else if ( e.Name ~== "swwmkoraxline" )
{
if ( consoleplayer != e.Args[1] ) return;
switch ( e.Args[0] )
{
case 0:
AddOneliner("koraxgreet",3,60);
break;
case 1:
AddOneliner("koraxblood",3,150);
break;
case 2:
AddOneliner("koraxgame",3,120);
break;
case 3:
AddOneliner("koraxworship",3,80);
break;
case 4:
AddOneliner("koraxmasters",3,90);
break;
}
}
else if ( e.Name.Left(17) ~== "swwmstoremessage." )
{
if ( consoleplayer != e.Args[2] ) return;
SWWMFullHistory.PushMessage(e.Name.Mid(17),e.Args[0],e.Args[1]);
}
else if ( e.Name.Left(16) ~== "swwmremoteliner." )
{
if ( consoleplayer == e.Args[0] ) return;
if ( swwm_mutevoice >= e.Args[1] ) return;
players[e.Args[0]].mo.A_StartSound(e.Name.Mid(16),CHAN_DEMOVOICE,attenuation:.5);
}
else if ( e.Name.Left(19) ~== "swwmremotelinertxt." )
{
if ( consoleplayer == e.Args[0] ) return;
if ( swwm_mutevoice >= e.Args[1] ) return;
double dist = players[consoleplayer].Camera.Distance3D(players[e.Args[0]].mo);
if ( dist < 2000 )
{
Console.Printf("\cx%s\cx: %s\c-",players[e.Args[0]].GetUserName(),StringTable.Localize(e.Name.Mid(19)));
if ( swwm_voicelog ) SWWMFullHistory.PushMessage("\cd"..players[e.Args[0]].GetUserName().."\c-: "..StringTable.Localize(e.Name.Mid(19)),level.totaltime,PRINT_CHAT);
}
}
else if ( e.Name.Left(8) ~== "swwmcbt." )
{
// from wikipedia, the free encyclopedia
if ( !playeringame[e.Args[0]] || !players[e.Args[0]].mo ) return;
let cbt = Wallbuster(players[e.Args[0]].mo.FindInventory("Wallbuster"));
if ( !cbt ) return;
cbt.reloadqueue.Clear();
if ( e.Name.Mid(8) ~== "EMPTY" ) cbt.clearout = true;
else
{
cbt.clearout = false;
Array<String> qs;
qs.Clear();
String rite = e.Name.Mid(8);
rite.Split(qs,",",TOK_SKIPEMPTY);
for ( int i=0; i<qs.Size(); i++ )
{
int qi = qs[i].ToInt();
if ( (qi < 0) || (qi > 3) ) continue;
cbt.reloadqueue.Push(cbttypes[qi]);
}
}
cbt.waitreload = false;
}
else if ( e.Name ~== "swwmcleartransaction" )
{
if ( e.Args[1] != consoleplayer ) return;
for ( int i=0; i<checklist.Size(); i++ )
{
if ( checklist[i].uid != e.Args[0] ) continue;
checklist.Delete(i);
i--;
}
}
else if ( e.Name ~== "swwmclearalltransactions" )
{
if ( e.Args[0] != consoleplayer ) return;
checklist.Clear();
}
else if ( e.Name ~== "swwmstorepuzzlecnt" )
{
let s = SWWMStats.Find(players[e.Args[0]]);
if ( s )
{
s.puzzlecnt = e.Args[1];
s.realpuzzlecnt = e.Args[2];
}
}
else if ( e.Name ~== "swwmsetoldcheat" )
{
let s = SWWMStats.Find(players[e.Args[0]]);
if ( s ) s.oldcheat = true;
}
// cheats go here
else CheatEvent(e);
}
override bool InputProcess( InputEvent e )
{
if ( (e.Type == InputEvent.TYPE_KeyDown) && (e.KeyChar >= 0x61) && (e.KeyChar <= 0x7A) )
{
// F
if ( e.KeyChar == 0x66 )
{
let demo = Demolitionist(players[consoleplayer].mo);
let gone = PlayerGone(players[consoleplayer].mo);
if ( (demo && (demo.Health <= 0) && (demo.deadtimer > 40))
|| (gone && (gone.Health <= 0) && (gone.deadtimer > 40)) )
{
// pay respects
int numf = Random[FInTheChat](1,6);
for ( int i=0; i<numf; i++ )
{
let f = PayRespects.PressF();
StatusBar.AttachMessage(f,0,layer:StatusBar.HUDMSGLayer_OverHUD);
}
}
}
if ( CheatInput(e) ) return true;
}
return false;
}
}