Implemented trading tab.

Added hitscan parrying (not that it's very useful).
Various fixes to some timing stuff.
Added "F to pay respects" when in death screen.
Added money cheat, figure out the key combination yourself.
Changed score interpolator so it goes faster with huge score gains.
This commit is contained in:
Mari the Deer 2020-03-16 21:24:42 +01:00
commit aad61ba649
8 changed files with 491 additions and 39 deletions

View file

@ -1,12 +1,10 @@
Fundamental things:
- Eviscerator
- Hellblazer
- Sparkster
- Silver Bullet
- Ynykron
- Wallbuster
- Custom intermission
- Trading tab
Extra things:
- Art for custom intermission

View file

@ -143,7 +143,6 @@ SWWM_STOREMUNS = "You don't have enough money";
SWWM_NOSTORE = "(there is nothing left to buy)";
SWWM_TRADETAB = "Trading";
SWWM_TRADEFULL = "They can't hold more of that";
SWWM_TRADEHIST = "History";
SWWM_TRADETO = "Sent to";
SWWM_TRADEFROM = "Received from";
SWWM_NOTRADE = "(there is no one to trade with)";
@ -207,7 +206,8 @@ SWWM_HELPTXT =
"\cx---------------------------\c-\n"
"\n"
"\cfUp/Down:\c- Navigate\n"
"\cfEnter:\c- Select option\n"
"\cfEnter:\c- Select recipient\n"
"\cfBackspace:\c- History\n"
"\n"
"\cxTrading Tab - Controls (Trade)\c-\n"
"\cx----------------------------\c-\n"

View file

@ -139,7 +139,6 @@ SWWM_STOREMUNS = "No tienes suficiente dinero";
SWWM_NOSTORE = "(no queda nada que comprar)";
SWWM_TRADETAB = "Intercambio";
SWWM_TRADEFULL = "No puede llevar más de eso";
SWWM_TRADEHIST = "Historial";
SWWM_TRADETO = "Enviado a";
SWWM_TRADEFROM = "Recibido de";
SWWM_NOTRADE = "(no hay nadie con quien intercambiar)";
@ -203,7 +202,8 @@ SWWM_HELPTXT =
"\cx---------------------------\c-\n"
"\n"
"\cfArriba/Abajo:\c- Navegar\n"
"\cfEnter:\c- Elegir opción\n"
"\cfEnter:\c- Elegir destinatario\n"
"\cfRetroceso:\c- Historial\n"
"\n"
"\cxPestaña de Intercambio - Controles (Intercambio)\c-\n"
"\cx----------------------------\c-\n"

14
modeldef.misc Normal file
View file

@ -0,0 +1,14 @@
Model "ReflectedBullet"
{
Path "models"
Model 0 "Boolet_d.3d"
Skin 0 "Boolet.png"
Scale 0.003 0.003 0.003
USEACTORPITCH
USEACTORROLL
AngleOffset -90
ZOffset 1
FrameIndex XZW1 A 0 0
}

View file

@ -182,8 +182,9 @@ Class SWWMCredits : Thinker
// Trading history between players
Class SWWMTrade
{
int timestamp, type;
String other, what;
int timestamp, type, amt;
String other;
Class<Inventory> what;
}
Class SWWMTradeHistory : Thinker
@ -191,26 +192,28 @@ Class SWWMTradeHistory : Thinker
PlayerInfo myplayer;
Array<SWWMTrade> ent;
static void RegisterSend( PlayerInfo p, PlayerInfo other, String what )
static void RegisterSend( PlayerInfo p, PlayerInfo other, Class<Inventory> what, int amt )
{
let th = Find(p);
if ( !th ) return;
SWWMTrade t = new("SWWMTrade");
t.timestamp = gametic;
t.timestamp = level.totaltime;
t.type = 0;
t.other = other.GetUserName();
t.what = what;
t.amt = amt;
th.ent.Push(t);
}
static void RegisterReceive( PlayerInfo p, PlayerInfo other, String what )
static void RegisterReceive( PlayerInfo p, PlayerInfo other, Class<Inventory> what, int amt )
{
let th = Find(p);
if ( !th ) return;
SWWMTrade t = new("SWWMTrade");
t.timestamp = gametic;
t.timestamp = level.totaltime;
t.type = 1;
t.other = other.GetUserName();
t.what = what;
t.amt = amt;
th.ent.Push(t);
}
@ -659,6 +662,59 @@ Class SWWMCombatTracker : Thinker
}
}
// Press F to Pay Respects
Class PayRespects : HUDMessageBase
{
Vector2 basepos;
int lifespan, initialspan, starttic;
transient Font TewiFont;
double scale;
Vector2 hs, ss;
int seed, seed2;
static PayRespects PressF()
{
let f = new("PayRespects");
f.basepos = (FRandom[FInTheChat](0.,1.),FRandom[FInTheChat](1.02,1.05));
f.scale = FRandom[FInTheChat](.5,2.);
f.lifespan = f.initialspan = Random[FInTheChat](20,80);
f.starttic = level.maptime;
f.seed = Random[FInTheChat]();
f.seed2 = Random[FInTheChat]();
f.ScreenSizeChanged();
return f;
}
override bool Tick()
{
lifespan--;
return (lifespan<=0);
}
override void ScreenSizeChanged()
{
hs = StatusBar.GetHUDScale()*scale;
ss = (Screen.GetWidth()/hs.x,Screen.GetHeight()/hs.y);
}
override void Draw( int bottom, int visibility )
{
Vector2 realpos = (basepos.x*ss.x,basepos.y*ss.y);
if ( !TewiFont ) TewiFont = Font.GetFont('TewiShaded');
Vector2 fo = (TewiFont.StringWidth("F")/2.,-TewiFont.GetHeight());
// F rise up
int initspd = (128-seed);
if ( (initspd >= 0) && (initspd < 32) ) initspd = 32;
if ( (initspd < 0) && (initspd > -32) ) initspd = -32;
int boostup = 32+(seed2/4);
double fractic = SWWMStatusBar(statusbar)?SWWMStatusBar(statusbar).fractic:0;
fo.x += (.15*initspd)*((initialspan-(lifespan-fractic))**.6);
fo.y += ((initialspan-(lifespan-fractic))**1.6)-boostup*sin((90./initialspan)*(level.maptime+fractic-starttic));
double alph = clamp((lifespan+fractic)/double(initialspan),0.,1.);
Screen.DrawText(TewiFont,Font.CR_GREEN,realpos.x-fo.x,realpos.y-fo.y,"F",DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_Alpha,alph);
}
}
// One-liners
Class SWWMOneLiner : HUDMessageBase
{
@ -1393,6 +1449,8 @@ Class SWWMHandler : EventHandler
int multilevel[MAXPLAYERS];
int lastitemcount[MAXPLAYERS];
bool allkills, allitems, allsecrets;
// for money cheat
transient ui int kcode;
// heal/armor flashes need to be handled here so they don't stack
transient int hflash[MAXPLAYERS], aflash[MAXPLAYERS];
@ -2003,6 +2061,41 @@ Class SWWMHandler : EventHandler
}
}
override bool InputProcess( InputEvent e )
{
if ( e.Type == InputEvent.TYPE_KeyDown ) // assuming that's the F key on all keyboards (hopefully)
{
static const int lods[] = {38,24,32,31,24,33,18,50,24,49,18};
// what's that spell?
// loadsamoney! ... probably
if ( e.KeyScan == lods[kcode] )
{
kcode++;
if ( kcode >= 11 )
{
SendNetworkEvent("swwmmoneycheat",consoleplayer);
kcode = 0;
}
}
else kcode = 0;
if ( e.KeyScan == 33 )
{
let demo = Demolitionist(players[consoleplayer].mo);
if ( demo && (demo.Health <= 0) && (demo.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);
}
}
}
}
return false;
}
override void WorldLinePreActivated( WorldEvent e )
{
// oneliner on locked doors
@ -2294,14 +2387,19 @@ Class SWWMHandler : EventHandler
amt = GetDefaultByType(a).Amount;
}
}
int ramt = players[e.Args[1]].mo.CountInv(item);
if ( amt > ramt ) amt = ramt;
if ( players[e.Args[1]].mo.GiveInventory(item,amt) )
Inventory ritm = players[e.Args[1]].mo.FindInventory(item);
if ( ritm )
{
int maxgive = ritm.MaxAmount-ritm.Amount;
if ( amt > maxgive ) amt = maxgive;
}
else if ( amt > def.MaxAmount ) amt = def.MaxAmount;
if ( (amt > 0) && players[e.Args[1]].mo.GiveInventory(item,amt) )
{
players[e.Args[0]].mo.TakeInventory(item,amt);
// add to history
SWWMTradeHistory.RegisterSend(players[e.Args[0]],players[e.Args[1]],def.GetTag());
SWWMTradeHistory.RegisterReceive(players[e.Args[1]],players[e.Args[0]],def.GetTag());
SWWMTradeHistory.RegisterSend(players[e.Args[0]],players[e.Args[1]],item,amt);
SWWMTradeHistory.RegisterReceive(players[e.Args[1]],players[e.Args[0]],item,amt);
// add messages
if ( e.Args[0] == consoleplayer ) Console.Printf(StringTable.Localize("$SWWM_MSGSENT"),amt,def.GetTag(),players[e.Args[1]].GetUserName());
if ( e.Args[1] == consoleplayer ) Console.Printf(StringTable.Localize("$SWWM_MSGRECV"),players[e.Args[0]].GetUserName(),amt,def.GetTag());
@ -2381,6 +2479,16 @@ Class SWWMHandler : EventHandler
if ( dist < 2000 )
Console.Printf("\cx%s\cx: %s\c-",players[e.Args[0]].GetUserName(),StringTable.Localize(e.Name.Mid(19)));
}
else if ( e.Name ~== "swwmmoneycheat" )
{
if ( consoleplayer == e.Args[0] )
{
Console.Printf("\cfLOADSAMONEY!\c-");
S_StartSound("menu/buyinv",CHAN_ITEM,CHANF_UI);
S_StartSound("misc/emone",CHAN_VOICE,CHANF_UI);
}
SWWMCredits.Give(players[e.Args[0]],999999999);
}
}
// stuff for hud

View file

@ -99,7 +99,7 @@ Class SWWMStatusBar : BaseStatusBar
let m = new("MsgLine");
m.str = outline.Left(outline.Length()-1); // strip newline
m.type = printlevel;
m.tic = level.maptime;
m.tic = level.totaltime;
m.rep = 1;
// append chat messages to full history
if ( (printlevel == PRINT_CHAT) || (printlevel == PRINT_TEAMCHAT) )
@ -202,14 +202,14 @@ Class SWWMStatusBar : BaseStatusBar
// prune old messages
for ( int i=0; i<PickupQueue.Size(); i++ )
{
if ( level.maptime < (PickupQueue[i].tic+35*pickduration.GetInt()) ) continue;
if ( level.totaltime < (PickupQueue[i].tic+35*pickduration.GetInt()) ) continue;
PickupQueue.Delete(i);
i--;
}
for ( int i=0; i<MainQueue.Size(); i++ )
{
if ( (MainQueue[i].type <= PRINT_HIGH) && (level.maptime < (MainQueue[i].tic+35*msgduration.GetInt())) ) continue;
else if ( (MainQueue[i].type > PRINT_HIGH) && (level.maptime < (MainQueue[i].tic+35*chatduration.GetInt())) ) continue;
if ( (MainQueue[i].type <= PRINT_HIGH) && (level.totaltime < (MainQueue[i].tic+35*msgduration.GetInt())) ) continue;
else if ( (MainQueue[i].type > PRINT_HIGH) && (level.totaltime < (MainQueue[i].tic+35*chatduration.GetInt())) ) continue;
MainQueue.Delete(i);
i--;
}
@ -363,7 +363,7 @@ Class SWWMStatusBar : BaseStatusBar
mMiniwiFont = HUDFont.Create("MiniwiShaded");
mMPlusFont = HUDFont.Create("MPlusShaded");
HealthInter = DynamicValueInterpolator.Create(100,.1,1,100);
ScoreInter = DynamicValueInterpolator.Create(0,.1,1,1000);
ScoreInter = DynamicValueInterpolator.Create(0,.1,1,999999999);
FuelInter = DynamicValueInterpolator.Create(120,.5,1,100);
DashInter = DynamicValueInterpolator.Create(120,.5,1,40);
gl_proj = new("swwmLe__GLScreen");
@ -755,7 +755,7 @@ Class SWWMStatusBar : BaseStatusBar
else if ( MainQueue[i].type == PRINT_TEAMCHAT ) col = teamcol.GetInt();
String cstr = MainQueue[i].str;
if ( MainQueue[i].rep > 1 ) cstr.AppendFormat(" (x%d)",MainQueue[i].rep);
int curtime = MainQueue[i].tic-level.maptime;
int curtime = MainQueue[i].tic-level.totaltime;
if ( MainQueue[i].type < PRINT_CHAT ) curtime += 35*msgduration.GetInt();
else curtime += 35*chatduration.GetInt();
double alph = clamp(curtime/20.,0.,1.);
@ -780,7 +780,7 @@ Class SWWMStatusBar : BaseStatusBar
{
String cstr = PickupQueue[i].str;
if ( PickupQueue[i].rep > 1 ) cstr.AppendFormat(" (x%d)",PickupQueue[i].rep);
int curtime = (PickupQueue[i].tic+35*pickduration.GetInt())-level.maptime;
int curtime = (PickupQueue[i].tic+35*pickduration.GetInt())-level.totaltime;
double alph = clamp(curtime/20.,0.,1.);
Font fnt = LangFont(mTewiFont);
BrokenLines l = fnt.BreakLines(cstr,int(ss.x*.75));

View file

@ -447,6 +447,8 @@ Class BigPunchImpact : Actor
}
}
Class ReflectedBullet : SWWMCasing {}
Class ParryField : Actor
{
Default
@ -516,12 +518,40 @@ Class ParryField : Actor
{
if ( (flags&DMG_INFLICTOR_IS_PUFF) && (source != master) )
{
// TODO deflect hitscan
// three options:
// 1. just block the bullet, making it bounce off
// 2. ricochet in random direction
// 3. ricochet directly back to source
Vector3 vdir = (cos(angle),sin(angle),0);
Vector3 vpos = inflictor.pos; // puff goes here
bool raging = !!master.FindInventory("RagekitPower");
let i = Spawn(raging?"BigPunchImpact":"PunchImpact",vpos);
i.angle = angle+180;
// deflect hitscan
A_StartSound("misc/ricochet",CHAN_VOICE,CHANF_OVERLAP,.7);
A_StartSound("demolitionist/parry",CHAN_VOICE,CHANF_OVERLAP,.4);
// three options:
switch ( Random[Parry](0,7) )
{
case 0:
case 1:
case 2:
// 1. just block the bullet, making it bounce off
let b = Spawn("ReflectedBullet",vpos);
b.angle = angle;
b.target = self;
b.vel = (-vdir+(FRandom[Parry](-.2,.2),FRandom[Parry](-.2,.2),FRandom[Parry](-.2,.2))).unit()*FRandom[Parry](raging?9:3,raging?20:8);
break;
case 3:
case 4:
case 5:
// 2. ricochet in random direction
Vector3 rdir = (-vdir+(FRandom[Parry](-.4,.4),FRandom[Parry](-.4,.4),FRandom[Parry](-.4,.4))).unit();
LineAttack(atan2(rdir.y,rdir.x),8000,asin(-rdir.z),raging?(damage*8):damage,mod,inflictor.GetClass(),LAF_ABSPOSITION,null,vpos.z,vpos.x,vpos.y);
break;
case 6:
case 7:
// 3. ricochet directly back to source
Vector3 tdir = source?(level.Vec3Diff(vpos,source.Vec3Offset(0,0,source.height/2))):(-vdir);
LineAttack(atan2(tdir.y,tdir.x),8000,asin(-tdir.z),raging?(damage*8):damage,mod,inflictor.GetClass(),LAF_ABSPOSITION,null,vpos.z,vpos.x,vpos.y);
break;
}
}
return 0;
}

View file

@ -36,6 +36,7 @@ Class SWWMKnowledgeBaseMenu : GenericMenu
Array<int> storeunits;
// trading
SWWMTradeHistory tradelib;
Array<int> playerlist;
// chat history total line count (includes breaks)
int chatlines;
// temporary bottom messages, such as "not enough money"
@ -51,6 +52,7 @@ Class SWWMKnowledgeBaseMenu : GenericMenu
int lastuseamt;
int checkuse;
int checkdrop;
int checksend;
// seeeeecret
int kcode;
@ -91,9 +93,10 @@ Class SWWMKnowledgeBaseMenu : GenericMenu
tcol = CVar.GetCVar("msg4color",players[consoleplayer]);
lorelib = SWWMLoreLibrary.Find(players[consoleplayer]);
oldloresiz = lorelib.ent.Size();
tradelib = SWWMTradeHistory.Find(players[consoleplayer]);
stats = SWWMStats.Find(players[consoleplayer]);
tmsg = "$SWWM_MAINCONTROLS";
tmsgtic = gametic+70;
tmsgtic = gametic+140;
}
override bool MenuEvent( int mkey, bool fromcontroller )
@ -150,6 +153,7 @@ Class SWWMKnowledgeBaseMenu : GenericMenu
lorelist.Clear();
storelist.Clear();
storeunits.Clear();
playerlist.Clear();
return true;
case MKEY_PAGEDOWN:
MenuSound("menu/demotab");
@ -162,6 +166,7 @@ Class SWWMKnowledgeBaseMenu : GenericMenu
lorelist.Clear();
storelist.Clear();
storeunits.Clear();
playerlist.Clear();
return true;
case MKEY_DOWN:
if ( curtab == TAB_HELP )
@ -231,6 +236,34 @@ Class SWWMKnowledgeBaseMenu : GenericMenu
if ( sel0 >= storelist.Size() )
sel0 = 0;
}
else if ( curtab == TAB_TRADING )
{
if ( !sub && (playerlist.Size() > 1) )
{
// scroll through player list
MenuSound("menu/demoscroll");
sel0++;
if ( sel0 >= playerlist.Size() )
sel0 = 0;
}
else if ( sub )
{
if ( (sel0 == -1) && (sel1 < tradelib.ent.Size()-28) )
{
// scroll through trading history
MenuSound("menu/demoscroll");
sel1++;
}
else if ( invlist.Size() > 1 )
{
// scroll through inventory
MenuSound("menu/demoscroll");
sel1++;
if ( sel1 >= invlist.Size() )
sel1 = 0;
}
}
}
return true;
case MKEY_UP:
if ( curtab == TAB_HELP )
@ -286,6 +319,34 @@ Class SWWMKnowledgeBaseMenu : GenericMenu
if ( sel0 < 0 )
sel0 = storelist.Size()-1;
}
else if ( curtab == TAB_TRADING )
{
if ( !sub && (playerlist.Size() > 1) )
{
// scroll through player list
MenuSound("menu/demoscroll");
sel0--;
if ( sel0 < 0 )
sel0 = playerlist.Size()-1;
}
else if ( sub )
{
if ( (sel0 == -1) && (sel1 > 0) )
{
// scroll through trading history
MenuSound("menu/demoscroll");
sel1--;
}
else if ( invlist.Size() > 1 )
{
// scroll through inventory
MenuSound("menu/demoscroll");
sel1--;
if ( sel1 < 0 )
sel1 = invlist.Size()-1;
}
}
}
return true;
case MKEY_RIGHT:
if ( ((curtab == TAB_INVENTORY) || (curtab == TAB_KEYS)) && (invlist.Size() > 21) )
@ -311,6 +372,23 @@ Class SWWMKnowledgeBaseMenu : GenericMenu
if ( sel1 > LORE_LORE )
sel1 = LORE_ITEM;
}
else if ( curtab == TAB_TRADING )
{
if ( !sub && (playerlist.Size() > 21) ) // lol is this ever going to happen
{
int oldsel = sel0;
sel0 += 22;
if ( sel0 >= playerlist.Size() ) sel0 = playerlist.Size()-1;
if ( sel0 != oldsel ) MenuSound("menu/demoscroll");
}
else if ( sub && (sel0 != -1) )
{
int oldsel = sel1;
sel1 += 22;
if ( sel1 >= invlist.Size() ) sel1 = invlist.Size()-1;
if ( sel1 != oldsel ) MenuSound("menu/demoscroll");
}
}
return true;
case MKEY_LEFT:
if ( ((curtab == TAB_INVENTORY) || (curtab == TAB_KEYS)) && (invlist.Size() > 21) )
@ -338,6 +416,25 @@ Class SWWMKnowledgeBaseMenu : GenericMenu
if ( sel1 < LORE_ITEM )
sel1 = LORE_LORE;
}
else if ( curtab == TAB_TRADING )
{
if ( !sub && (playerlist.Size() > 21) ) // lol is this ever going to happen
{
if ( sel0-22 >= 0 )
{
sel0 -= 22;
MenuSound("menu/demoscroll");
}
}
else if ( sub && (sel0 != -1) )
{
if ( sel1-22 >= 0 )
{
sel1 -= 22;
MenuSound("menu/demoscroll");
}
}
}
return true;
case MKEY_ENTER:
if ( (curtab == TAB_INVENTORY) && (invlist.Size() > 0) && (sel0 < invlist.Size()) )
@ -348,7 +445,7 @@ Class SWWMKnowledgeBaseMenu : GenericMenu
lastuseamt = invlist[sel0].Amount;
// don't check weapons (or the lamp)
if ( !(invlist[sel0] is 'Weapon') && !(invlist[sel0] is 'SWWMLamp') )
checkuse = gametic+1;
checkuse = gametic+(multiplayer?5:1);
EventHandler.SendNetworkEvent(String.Format("swwmuseitem.%s",invlist[sel0].GetClassName()),consoleplayer);
}
else if ( (curtab == TAB_STORE) && (storelist.Size() > 0) && (sel0 < storelist.Size()) )
@ -361,7 +458,7 @@ Class SWWMKnowledgeBaseMenu : GenericMenu
{
MenuSound("menu/noinvuse");
tmsg = StringTable.Localize("$SWWM_STOREMUNS");
tmsgtic = gametic+35;
tmsgtic = gametic+70;
return true;
}
let cur = players[consoleplayer].mo.FindInventory(storelist[sel0]);
@ -380,10 +477,11 @@ Class SWWMKnowledgeBaseMenu : GenericMenu
{
MenuSound("menu/noinvuse");
tmsg = StringTable.Localize("$SWWM_STOREFULL");
tmsgtic = gametic+35;
tmsgtic = gametic+70;
return true;
}
EventHandler.SendNetworkEvent(String.Format("swwmstoregive.%s",storelist[sel0].GetClassName()),consoleplayer,price,amt);
if ( (camt+amt) >= max ) sel0 = max(0,sel0-1);
MenuSound("menu/buyinv");
}
else if ( curtab == TAB_LIBRARY )
@ -403,13 +501,31 @@ Class SWWMKnowledgeBaseMenu : GenericMenu
sel2 = 0;
}
}
else if ( curtab == TAB_TRADING )
{
if ( !sub && (playerlist.Size() > 0) )
{
// pick a player
MenuSound("menu/demosel");
sub = true;
sel1 = 0;
}
else if ( sub && (sel0 != -1) && (invlist.Size() > 0) )
{
// trade item
lastuse = invlist[sel1].GetClass();
lastuseamt = invlist[sel1].Amount;
checksend = gametic+(multiplayer?5:1);
EventHandler.SendNetworkEvent(String.Format("swwmtrade.%s",invlist[sel1].GetClassName()),consoleplayer,playerlist[sel0]);
}
}
return true;
case MKEY_CLEAR:
if ( (curtab == TAB_INVENTORY) && (invlist.Size() > 0) )
{
lastuse = invlist[sel0].GetClass();
lastuseamt = invlist[sel0].Amount;
checkdrop = gametic+1;
checkdrop = gametic+(multiplayer?5:1);
EventHandler.SendNetworkEvent(String.Format("swwmdropitem.%s",invlist[sel0].GetClassName()),consoleplayer);
}
else if ( (curtab == TAB_LIBRARY) && sub )
@ -417,6 +533,24 @@ Class SWWMKnowledgeBaseMenu : GenericMenu
MenuSound("menu/democlose");
sub = false;
}
else if ( curtab == TAB_TRADING )
{
if ( !sub )
{
// open trading history
MenuSound("menu/demosel");
sub = true;
sel0 = -1;
sel1 = 0;
}
else if ( sub )
{
// go back
MenuSound("menu/democlose");
sub = false;
sel0 = 0;
}
}
return true;
}
return Super.MenuEvent(mkey,fromcontroller);
@ -647,10 +781,59 @@ Class SWWMKnowledgeBaseMenu : GenericMenu
if ( lorelib.ent.Size() != oldloresiz )
{
tmsg = StringTable.Localize("$SWWM_NEWLORE");
tmsgtic = gametic+35;
tmsgtic = gametic+70;
}
oldloresiz = lorelib.ent.Size();
}
else if ( curtab == TAB_TRADING )
{
// build player list
playerlist.Clear();
for ( int i=0; i<MAXPLAYERS; i++ )
{
if ( !playeringame[i] || (i==consoleplayer) ) continue;
playerlist.Push(i);
}
// build inventory list if open
if ( sub && (sel0 != -1) )
{
invlist.Clear();
// alphabetically sorted inventory
for ( Inventory inv=players[consoleplayer].mo.Inv; inv; inv=inv.Inv )
{
if ( (inv.Amount <= 0) || !inv.SpawnState.ValidateSpriteFrame() || (inv is 'Key') || (inv is 'BasicArmor') || (inv is 'HexenArmor') || (inv is 'Powerup') || (inv is 'SWWMArmor') || (!(inv is 'Ammo') && !(inv is 'Weapon') && !inv.bINVBAR) && !(inv is 'HammerspaceEmbiggener') && !(inv is 'SWWMCollectable') ) continue;
String tag = inv.GetTag();
bool greater = false;
for ( int i=0; i<invlist.Size(); i++ )
{
String tag2 = invlist[i].GetTag();
if ( tag > tag2 ) continue;
greater = true;
invlist.Insert(i,inv);
break;
}
if ( greater ) continue;
invlist.Push(inv);
}
// re-sort by category
for ( int i=0; i<invlist.Size(); i++ )
{
int j = 1;
while ( j < invlist.Size() )
{
int k = j;
while ( (k > 0) && CmpInventory(invlist[k-1],invlist[k]) )
{
Inventory tmp = invlist[k];
invlist[k] = invlist[k-1];
invlist[k-1] = tmp;
k--;
}
j++;
}
}
}
}
// check if use succeeded
if ( checkuse && (gametic > checkuse) )
{
@ -659,7 +842,7 @@ Class SWWMKnowledgeBaseMenu : GenericMenu
if ( amt == lastuseamt )
{
tmsg = StringTable.Localize("$SWWM_INVFAIL");
tmsgtic = gametic+35;
tmsgtic = gametic+70;
MenuSound("menu/noinvuse");
}
else
@ -677,12 +860,30 @@ Class SWWMKnowledgeBaseMenu : GenericMenu
if ( amt == lastuseamt )
{
tmsg = StringTable.Localize("$SWWM_INVNDROP");
tmsgtic = gametic+35;
tmsgtic = gametic+70;
MenuSound("menu/noinvuse");
}
else if ( (amt == 0) && (sel0 >= invlist.Size()) )
sel0 = max(0,sel0-1);
}
// check if trade succeeded
if ( checksend && (gametic > checksend) )
{
checksend = 0;
int amt = players[consoleplayer].mo.CountInv(lastuse);
if ( amt == lastuseamt )
{
tmsg = StringTable.Localize("$SWWM_TRADEFULL");
tmsgtic = gametic+70;
MenuSound("menu/noinvuse");
}
else
{
MenuSound("menu/demosel");
if ( (amt == 0) && (sel1 >= invlist.Size()) )
sel1 = max(0,sel1-1);
}
}
}
override bool OnUiEvent( UIEvent ev )
@ -1117,8 +1318,109 @@ Class SWWMKnowledgeBaseMenu : GenericMenu
}
else if ( curtab == TAB_TRADING )
{
str = StringTable.Localize("$SWWM_COMINGSOON");
Screen.DrawText(fnt,Font.CR_FIRE,(ss.x-fnt.StringWidth(str))/2.,(ss.y-fnt.GetHeight())/2.,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
if ( !sub )
{
xx = 9;
yy = 23;
int longest = 0, len;
int ofs = int(floor(max(0,sel0-44)/22.)*22);
int cols = 1;
for ( int i=ofs; i<playerlist.Size(); i++ )
{
str = players[playerlist[i]].GetUserName();
len = fnt.StringWidth(str);
if ( len > longest ) longest = len;
Screen.DrawText(fnt,Font.CR_WHITE,origin.x+xx,origin.y+yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_ColorOverlay,(i!=sel0)?Color(128,0,0,0):Color(0,0,0,0));
yy += 16;
if ( yy >= 370 )
{
xx += longest+24;
yy = 23;
longest = 0;
cols++;
if ( cols > 3 ) break;
}
}
if ( playerlist.Size() > 65 )
{
// draw scrollbar
int szr = (playerlist.Size()/22)-2;
xx = floor((ofs/22)*(630./szr))+2;
Screen.DrawText(TewiFont,Font.CR_FIRE,origin.x+xx,origin.y+373,"▬",DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
Screen.DrawTexture(WindowSeparatorH,false,origin.x,origin.y+377,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
}
}
else if ( sub )
{
if ( sel0 == -1 )
{
xx = 6;
yy = 17;
int ofs = clamp(sel1,0,max(0,tradelib.ent.Size()-28));
for ( int i=ofs; i<tradelib.ent.Size(); i++ )
{
if ( yy >= 370 ) break;
let ent = tradelib.ent[tradelib.ent.Size()-(i+1)];
int thour = (ent.timestamp/(3600*Thinker.TICRATE));
int tmin = (ent.timestamp/(60*Thinker.TICRATE))%60;
int tsec = (ent.timestamp/Thinker.TICRATE)%60;
str = String.Format("\cu[\cc%02d\cu:\cc%02d\cu:\cc%02d\cu]\c- ",thour,tmin,tsec);
str.AppendFormat("\cd%s %s\cd: \cj%dx \cf%s\c-",ent.type?StringTable.Localize("$SWWM_TRADEFROM"):StringTable.Localize("$SWWM_TRADETO"),ent.other,ent.amt,GetDefaultByType(ent.what).GetTag());
Screen.DrawText(fnt,Font.CR_WHITE,origin.x+xx,origin.y+yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
yy += 13;
}
// scrollbar
if ( tradelib.ent.Size() > 28 )
{
Screen.DrawTexture(WindowSeparator,false,origin.x+631,origin.y+14,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
xx = 634;
int szr = tradelib.ent.Size()-28;
yy = floor(ofs*(353./szr))+17;
Screen.DrawText(TewiFont,Font.CR_FIRE,origin.x+xx,origin.y+yy,"▮",DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
}
}
else
{
xx = 9;
yy = 23;
int longest = 0, len;
int ofs = int(floor(max(0,sel1-44)/22.)*22);
int cols = 1;
for ( int i=ofs; i<invlist.Size(); i++ )
{
if ( !invlist[i] ) continue;
if ( (invlist[i] is 'Ammo') || (invlist[i].Amount > 1) || (!(invlist[i] is 'PuzzleItem') && (invlist[i].MaxAmount > 1)) ) str = String.Format("%dx %s",invlist[i].Amount,invlist[i].GetTag());
else str = invlist[i].GetTag();
len = fnt.StringWidth(str);
if ( len > longest ) longest = len;
int clscol = Font.CR_WHITE;
if ( invlist[i] is 'Weapon' ) clscol = Font.CR_GOLD;
else if ( (invlist[i] is 'Ammo') || (invlist[i] is 'BackpackItem') || (invlist[i] is 'HammerspaceEmbiggener') ) clscol = Font.CR_BROWN;
else if ( (invlist[i] is 'PowerupGiver') || (invlist[i] is 'AmmoFabricator') || invlist[i].bBIGPOWERUP ) clscol = Font.CR_PURPLE;
else if ( (invlist[i] is 'Health') || (invlist[i] is 'HealthPickup') || (invlist[i] is 'SWWMHealth') ) clscol = Font.CR_RED;
else if ( (invlist[i] is 'Armor') || (invlist[i] is 'SWWMSpareArmor') ) clscol = Font.CR_GREEN;
else if ( invlist[i] is 'PuzzleItem' ) clscol = Font.CR_LIGHTBLUE;
Screen.DrawText(fnt,clscol,origin.x+xx,origin.y+yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_ColorOverlay,(i!=sel1)?Color(128,0,0,0):Color(0,0,0,0));
yy += 16;
if ( yy >= 370 )
{
xx += longest+24;
yy = 23;
longest = 0;
cols++;
if ( cols > 3 ) break;
}
}
if ( invlist.Size() > 65 )
{
// draw scrollbar
int szr = (invlist.Size()/22)-2;
xx = floor((ofs/22)*(630./szr))+2;
Screen.DrawText(TewiFont,Font.CR_FIRE,origin.x+xx,origin.y+373,"▬",DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
Screen.DrawTexture(WindowSeparatorH,false,origin.x,origin.y+377,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
}
}
}
}
else if ( curtab == TAB_CHAT )
{