// event processing extend Class SWWMHandler { // for menu events transient Array checklist; // for the compact hud transient int WeaponFlash[10]; // weapon selector transient ui SWWMWeaponSelect wsel; 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') || paused ) 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 InterfaceProcess( ConsoleEvent e ) { if ( e.IsManual ) return; if ( e.Name ~== "swwmsetdialogue" ) SWWMDialogues.StartSeq(e.Args[0]); else if ( e.Name.Left(11) ~== "swwmkeyget." ) { let bar = SWWMStatusBar(StatusBar); if ( !bar || (bar.CPlayer != players[e.Args[0]]) ) return; String kname = e.Name.Mid(11); Class k = kname; if ( k ) { let kg = new("KeyGet"); kg.got = k; kg.flashtime = gametic+25; bar.keyflash.Push(kg); } } else if ( e.Name.Left(15) ~== "swwmwpntooltip." ) { let bar = SWWMStatusBar(StatusBar); if ( !bar ) return; String wname = e.Name.Mid(15); Class w = wname; if ( w ) { let tt = new("SWWMWeaponTooltip").Init(w); bool appended = false; for ( SWWMWeaponTooltip t=bar.ctip; t; t=t.next ) { if ( t.next ) continue; appended = true; t.next = tt; break; } if ( !appended ) { bar.ctip = tt; bar.AttachMessage(tt,-2910); } } } else if ( e.Name.Left(12) ~== "swwmnametag." ) { let bar = SWWMStatusBar(StatusBar); if ( !bar ) return; bar.ntagstr = StringTable.Localize(e.Name.Mid(12)); bar.ntagtic = level.totaltime; bar.ntagcol = nametagcolor; } } override void NetworkProcess( ConsoleEvent e ) { 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 ~== "swwmsetradius" ) { if ( multiplayer && (e.player != Net_Arbitrator) ) { if ( e.player == consoleplayer ) Console.Printf("Only the net arbitrator can call this event."); return; } let mo = players[e.player].mo; if ( !mo ) return; FLineTraceData d; mo.LineTrace(mo.angle,10000.,mo.pitch,TRF_ABSPOSITION|TRF_THRUBLOCK|TRF_THRUHITSCAN|TRF_ALLACTORS,mo.player.viewz,mo.pos.x,mo.pos.y,d); if ( d.HitType != TRACE_HitActor ) return; Console.Printf("Change %s radius from %g to %g.",d.HitActor.GetTag(),d.HitActor.radius,e.Args[0]); d.HitActor.A_SetSize(e.Args[0],-1); } else if ( e.Name ~== "swwmsetheight" ) { if ( multiplayer && (e.player != Net_Arbitrator) ) { if ( e.player == consoleplayer ) Console.Printf("Only the net arbitrator can call this event."); return; } let mo = players[e.player].mo; if ( !mo ) return; FLineTraceData d; mo.LineTrace(mo.angle,10000.,mo.pitch,TRF_ABSPOSITION|TRF_THRUBLOCK|TRF_THRUHITSCAN|TRF_ALLACTORS,mo.player.viewz,mo.pos.x,mo.pos.y,d); if ( d.HitType != TRACE_HitActor ) return; Console.Printf("Change %s height from %g to %g.",d.HitActor.GetTag(),d.HitActor.height,e.Args[0]); d.HitActor.A_SetSize(-1,e.Args[0]); } 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 %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; j1)?"s":""); return; } if ( e.IsManual ) return; if ( e.Name.Left(14) ~== "swwmstoregive." ) { Class item = e.Name.Mid(14); if ( !item ) return; if ( SWWMCredits.Take(players[e.Args[0]],e.Args[1]) ) { let def = GetDefaultByType(item); if ( (item is 'ArmorNuggetItem') || (item is 'HealthNuggetItem') ) { // these have to be given in a loop because fun reasons for ( int i=0; i 1) ) players[e.Args[0]].mo.A_SelectWeapon("DualExplodiumGun"); else players[e.Args[0]].mo.A_SelectWeapon((Class)(item)); } } } else if ( e.Name.Left(14) ~== "swwmstoretake." ) { Class 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 && 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 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)(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 if ( (i is 'Key') || (i is 'SWWMCollectible') ) 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 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' ) { foreach ( cls:AllActorClasses ) { let a = (Class)(cls); if ( !a || (a.GetParentClass() != item) || (GetDefaultByType(a).Amount < amt) ) continue; amt = GetDefaultByType(a).Amount; } } if ( i is 'MagAmmo' ) { foreach ( cls:AllActorClasses ) { let a = (Class)(cls); 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); // randomize movement direction so multiple drops don't get bunched together if ( drop ) { Vector2 vel2d = drop.vel.xy; drop.vel.xy = Actor.RotateVector(vel2d,FRandom[Junk](-15,15)); drop.vel.xy *= FRandom[Junk](.9,1.1); } 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(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 ) { String txt = StringTable.Localize(e.Name.Mid(19)); txt.Replace("\c-","\c*"); // fix color reset escapes Console.PrintfEx(PRINT_CHAT,"\cx%s\cx: %s\c-",players[e.Args[0]].GetUserName(),txt); } } else if ( e.Name ~== "swwmcleartransaction" ) { if ( e.Args[1] != consoleplayer ) return; for ( int i=0; i 9) ) return; WeaponFlash[e.Args[0]] = gametic+25; } else if ( e.Name ~== "swwmccstart" ) gdat.ccstartonce = true; else if ( e.Name.Left(14) ~== "swwmselweapon." ) { Class wpn = e.Name.Mid(14); if ( !wpn ) return; let w = Weapon(players[e.player].mo.FindInventory(wpn)); if ( !w ) return; if ( !w.CheckAmmo(Weapon.EitherFire,false) ) { S_StartSound("menu/democlose",CHAN_AUTO,CHANF_UI); return; } players[e.player].mo.UseInventory(w); if ( e.player != consoleplayer ) return; bool rslt = (players[e.player].PendingWeapon == w); if ( (w is 'SWWMWeapon') && (players[e.player].PendingWeapon == w.SisterWeapon) ) rslt = true; // switching to dual gun S_StartSound(rslt?"menu/demosel":"menu/democlose",CHAN_AUTO,CHANF_UI); } // cheats go here else CheatEvent(e); } override bool InputProcess( InputEvent e ) { if ( e.Type != InputEvent.TYPE_KeyDown ) return false; // block invprev/next inputs when paused String cmd = Bindings.GetBinding(e.KeyScan); if ( paused ) { if ( (cmd ~== "invprev") || (cmd ~== "invnext") ) return true; // skip the rest of this function return false; } // weapon selector is active int WeapSel = 0; if ( cmd ~== "weapnext" ) WeapSel = 1; else if ( cmd ~== "weapprev" ) WeapSel = -1; if ( wsel && (wsel.stage < 2) ) { if ( WeapSel == 1 ) { wsel.WeapNext(); return true; } if ( WeapSel == -1 ) { wsel.WeapPrev(); return true; } if ( cmd ~== "+attack" ) { wsel.WeapSel(); return true; } if ( cmd ~== "+altattack" ) { wsel.WeapCancel(); return true; } } else if ( WeapSel && swwm_useweaponbar && !paused && (players[consoleplayer].playerstate == PST_LIVE) && players[consoleplayer].mo && (gamestate == GS_LEVEL) ) { // only if player owns any selectable weapons if ( !wsel && SWWMWeaponSelect.PlayerHasWeapons(players[consoleplayer].mo) ) { wsel = new("SWWMWeaponSelect").Init(players[consoleplayer].mo); StatusBar.AttachMessage(wsel,-2920); } return true; } // 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= 0x61) && (e.KeyChar <= 0x7A) && !paused ) { if ( CheatInput(e) ) return true; } return false; } }