Stuff and things.

This commit is contained in:
Mari the Deer 2020-01-26 21:17:20 +01:00
commit cf29142ff5
8 changed files with 283 additions and 39 deletions

View file

@ -10,6 +10,50 @@ enum ESWWMGZChannels
CHAN_JETPACK = 63206
};
// Scoreing
Class SWWMCredits : Thinker
{
PlayerInfo myplayer;
int credits;
static void GiveCredits( PlayerInfo p, int amount )
{
let c = FindCredits(p);
if ( (c.credits+amount < c.credits) || (c.credits+amount > 999999999) ) c.credits = 999999999;
else c.credits += amount;
}
static bool TakeCredits( PlayerInfo p, int amount )
{
let c = FindCredits(p);
// too much!
if ( (c.credits-amount < 0) || (c.credits-amount > c.credits) ) return false;
c.credits -= amount;
return true;
}
static int GetCredits( PlayerInfo p )
{
let c = FindCredits(p);
return c.credits;
}
private static SWWMCredits FindCredits( PlayerInfo p )
{
let ti = ThinkerIterator.Create("SWWMCredits",STAT_STATIC);
SWWMCredits t;
while ( t = SWWMCredits(ti.Next()) )
{
if ( t.myplayer != p ) continue;
return t;
}
t = new("SWWMCredits");
t.ChangeStatNum(STAT_STATIC);
t.myplayer = p;
return t;
}
}
// One-liners
Class SWWMOneLiner : HUDMessageBase
{
@ -579,6 +623,8 @@ Class SWWMHandler : EventHandler
int spreecount[MAXPLAYERS];
int lastkill[MAXPLAYERS];
int multilevel[MAXPLAYERS];
int lastitemcount[MAXPLAYERS];
int creditsbridge[MAXPLAYERS]; // curse the gap between play/ui
transient CVar mutevoice;
@ -642,6 +688,24 @@ Class SWWMHandler : EventHandler
flashes.Delete(i);
i--;
}
// countable item scoring
for ( int i=0; i<MAXPLAYERS; i++ )
{
if ( !playeringame[i] ) continue;
// while we're at it, also update the bridge var for counting credits
creditsbridge[i] = SWWMCredits.GetCredits(players[i]);
if ( players[i].itemcount > lastitemcount[i] )
{
int score = 25;
if ( level.total_items == level.found_items )
{
score = 2500;
Console.Printf(StringTable.Localize("$SWWM_LASTITEM"),players[i].GetUserName(),score);
}
SWWMCredits.GiveCredits(players[i],score);
lastitemcount[i] = players[i].itemcount;
}
}
// combat tracking
// prune old entries
for ( int i=0; i<combatactors.Size(); i++ )
@ -715,6 +779,14 @@ Class SWWMHandler : EventHandler
if ( !e.Thing.player && !e.Thing.bIsMonster && !e.Thing.bCountKill ) return;
if ( (e.DamageSource && e.DamageSource.player && (e.DamageSource != e.Thing)) )
{
if ( e.DamageSource == players[consoleplayer].mo )
{
highesttic = gametic;
if ( (!lastcombat || (gametic > lastcombat+20)) && (mutevoice.GetInt() < 1) )
lastcombat = AddOneliner("scorekill",15);
}
if ( !e.Thing.default.bCountKill ) // no credits
return;
int pnum = e.DamageSource.PlayerNumber();
if ( level.maptime < (lastkill[pnum]+5*Thinker.TICRATE) )
multilevel[pnum]++;
@ -726,14 +798,14 @@ Class SWWMHandler : EventHandler
score = int(score*(1.+.5*min(multilevel[pnum],16)));
if ( !tookdamage[pnum] ) score += 100+50*spreecount[pnum];
if ( e.Thing.bBOSS ) score += 10000;
if ( level.killed_monsters == level.total_monsters ) score += 5000;
e.DamageSource.GiveInventory("SWWMCredits",score);
if ( level.killed_monsters == level.total_monsters )
{
score += 5000;
Console.Printf(StringTable.Localize("$SWWM_LASTMONSTER",e.DamageSource.player.GetUserName()),5000);
}
SWWMCredits.GiveCredits(e.DamageSource.player,score);
// TODO floating score for HUD
spreecount[pnum]++;
if ( e.DamageSource != players[consoleplayer].mo ) return;
highesttic = gametic;
if ( (!lastcombat || (gametic > lastcombat+20)) && (mutevoice.GetInt() < 1) )
lastcombat = AddOneliner("scorekill",15);
}
}

View file

@ -12,37 +12,105 @@ Class SWWMStatusBar : BaseStatusBar
HealthTex[4], FuelTex, DashTex;
HUDFont mTewiFont;
Array<MsgLine> ChatMsgs, DeathMsgs, MiscMsgs, PickMsgs;
// "Full History" contains all messages since session start, nothing is flushed
// this can be accessed from a section of the knowledge base
Array<MsgLine> MainQueue, PickupQueue, FullHistory;
Actor targetactors[40], scoreactors[60], keyactors[10];
Vector3 exitpoints[10], uselines[10];
// client cvars
transient CVar safezone, maxchat[2], maxpick;
transient CVar safezone, maxchat[2], maxpick, chatduration, msgduration, pickduration, chatcol, teamcol, obitcol, critcol, pickcol;
// shared stuff
Vector2 ss, hs;
int margin;
double FracTic;
int chatopen;
DynamicValueInterpolator HealthInter, ScoreInter, FuelInter, DashInter;
override void FlushNotify()
{
ChatMsgs.Clear();
DeathMsgs.Clear();
MiscMsgs.Clear();
PickMsgs.Clear();
// flush non-chat messages
for ( int i=0; i<MainQueue.Size(); i++ )
{
if ( MainQueue[i].type >= PRINT_CHAT ) continue;
MainQueue.Delete(i);
i--;
}
}
override bool ProcessNotify( EPrintLevel printlevel, String outline )
{
if ( !chatduration ) chatduration = CVar.GetCVar('swwm_chatduration',players[consoleplayer]);
if ( !msgduration ) msgduration = CVar.GetCVar('swwm_msgduration',players[consoleplayer]);
if ( !pickduration ) pickduration = CVar.GetCVar('swwm_pickduration',players[consoleplayer]);
let m = new("MsgLine");
m.str = outline.Left(outline.Length()-1); // strip newline
m.type = printlevel;
m.tic = gametic;
// set lifespan for each type
if ( printlevel == PRINT_LOW ) m.tic += pickduration.GetInt();
else if ( printlevel <= PRINT_HIGH ) m.tic += msgduration.GetInt();
else m.tic += chatduration.GetInt();
m.rep = 1;
// append to full history
FullHistory.Push(m);
// ignore during intermission
if ( gamestate != GS_LEVEL ) return false;
if ( (printlevel < PRINT_LOW) || (printlevel > PRINT_TEAMCHAT) ) return true; // we couldn't care less about these
if ( printlevel == PRINT_LOW )
{
// check if repeated
for ( int i=0; i<PickupQueue.Size(); i++ )
{
if ( PickupQueue[i].str != m.str ) continue;
// delete old one and add its repeats
m.rep += PickupQueue[i].rep;
PickupQueue.Delete(i);
break;
}
PickupQueue.Push(m);
}
else
{
// check if repeated
for ( int i=0; i<MainQueue.Size(); i++ )
{
if ( MainQueue[i].str != m.str ) continue;
// delete old one and add its repeats
m.rep += MainQueue[i].rep;
MainQueue.Delete(i);
break;
}
MainQueue.Push(m);
}
return true;
}
override void Tick()
{
Super.Tick();
// prune old messages
for ( int i=0; i<PickupQueue.Size(); i++ )
{
if ( gametic < PickupQueue[i].tic ) continue;
PickupQueue.Delete(i);
i--;
}
for ( int i=0; i<MainQueue.Size(); i++ )
{
if ( gametic < MainQueue[i].tic ) continue;
MainQueue.Delete(i);
i--;
}
// update target actors
// update floating scores
// update interpolators
HealthInter.Update(CPlayer.health);
ScoreInter.Update(CPlayer.mo.CountInv("SWWMCredits"));
let hnd = SWWMHandler(EventHandler.Find("SWWMHandler"));
if ( hnd ) ScoreInter.Update(hnd.creditsbridge[CPlayer.mo.PlayerNumber()]);
else ScoreInter.Update(0);
let d = Demolitionist(CPlayer.mo);
if ( d )
{
@ -69,6 +137,9 @@ Class SWWMStatusBar : BaseStatusBar
HealthTex[3] = TexMan.CheckForTexture("graphics/HUD/HealthBar3.png",TexMan.Type_Any);
ScoreTex = TexMan.CheckForTexture("graphics/HUD/ScoreBox.png",TexMan.Type_Any);
WeaponTex = TexMan.CheckForTexture("graphics/HUD/WeaponBox.png",TexMan.Type_Any);
ChatTex[0] = TexMan.CheckForTexture("graphics/HUD/ChatBoxTop.png",TexMan.Type_Any);
ChatTex[1] = TexMan.CheckForTexture("graphics/HUD/ChatBoxLine.png",TexMan.Type_Any);
ChatTex[2] = TexMan.CheckForTexture("graphics/HUD/ChatBoxBottom.png",TexMan.Type_Any);
mTewiFont = HUDFont.Create("TewiShaded");
HealthInter = DynamicValueInterpolator.Create(100,.1,1,100);
ScoreInter = DynamicValueInterpolator.Create(0,.1,1,1000);
@ -171,8 +242,95 @@ Class SWWMStatusBar : BaseStatusBar
private void DrawMessages()
{
if ( !pickcol ) pickcol = CVar.GetCVar('msg0color',players[consoleplayer]);
if ( !obitcol ) obitcol = CVar.GetCVar('msg1color',players[consoleplayer]);
if ( !critcol ) critcol = CVar.GetCVar('msg2color',players[consoleplayer]);
if ( !chatcol ) chatcol = CVar.GetCVar('msg3color',players[consoleplayer]);
if ( !teamcol ) teamcol = CVar.GetCVar('msg4color',players[consoleplayer]);
// common message area
if ( MainQueue.Size() > 0 )
{
int mstart = max(0,MainQueue.Size()-(1+maxchat[chatopen>=gametic].GetInt()));
double xx = margin, yy = margin;
Screen.DrawTexture(ChatTex[0],false,xx,yy,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
yy++;
for ( int i=mstart; i<MainQueue.Size(); i++ )
{
int col = critcol.GetInt();
if ( MainQueue[i].type == PRINT_MEDIUM ) col = obitcol.GetInt();
else if ( MainQueue[i].type == PRINT_CHAT ) col = chatcol.GetInt();
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);
BrokenLines l = mTewiFont.mFont.BreakLines(cstr,361);
for ( int j=0; j<l.Count(); j++ )
{
Screen.DrawTexture(ChatTex[1],false,xx,yy,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
Screen.DrawText(mTewiFont.mFont,col,xx+4,yy,l.StringAt(j),DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
yy += 13;
}
}
Screen.DrawTexture(ChatTex[2],false,xx,yy,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
}
// pickup messages
if ( PickupQueue.Size() > 0 )
{
// reverse order since they're drawn bottom to top
int mend = max(0,PickupQueue.Size()-(1+maxpick.GetInt()));
double yy = ss.y-(margin+40);
for ( int i=PickupQueue.Size()-1; i>=mend; i-- )
{
String cstr = PickupQueue[i].str;
if ( PickupQueue[i].rep > 1 ) cstr.AppendFormat(" (x%d)",PickupQueue[i].rep);
BrokenLines l = mTewiFont.mFont.BreakLines(cstr,int(ss.x*.75));
for ( int j=l.Count()-1; j>=0; j-- )
{
int len = mTewiFont.mFont.StringWidth(l.StringAt(j));
double xx = (ss.x-len)/2.;
Screen.Dim("Black",.8,int((xx-6)*hs.x),int(yy*hs.y),int((len+12)*hs.x),int(15*hs.y));
Screen.DrawText(mTewiFont.mFont,pickcol.GetInt(),xx,yy+1,l.StringAt(j),DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
yy -= 15;
}
}
}
}
override bool DrawChat( String txt )
{
// ignore during intermission
if ( gamestate != GS_LEVEL ) return false;
chatopen = gametic+1; // have to add 1 because DrawChat is called after everything else
double xx = 2;
double yy = ss.y-14;
Screen.Dim("Black",.8,0,Screen.GetHeight()-int(15*hs.y),Screen.GetWidth(),int(15*hs.y));
String pname = players[consoleplayer].GetUserName();
// strip colors
for ( int i=0; i<pname.CodePointCount(); i++ )
{
int remlen = 0;
if ( pname.GetNextCodePoint(i) != 0x1C )
continue;
remlen++;
if ( pname.GetNextCodePoint(i+remlen) == 0x5B )
while ( pname.GetNextCodePoint(i+remlen) != 0x5D )
remlen++;
remlen++;
pname.Remove(i,remlen);
}
String fullstr = String.Format("\cq%s\cd@\cqdemolitionist%d\cn ~ \c-wall %s%s",pname,consoleplayer+1,txt,mTewiFont.mFont.GetCursor());
// cut out to fit
int w = mTewiFont.mFont.StringWidth(fullstr);
if ( w > ss.x-4 )
{
// draw trailing dots
Screen.DrawText(mTewiFont.mFont,Font.CR_WHITE,xx,yy,"...",DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
// shift back
xx -= w-(ss.x-4);
// draw trimmed
Screen.DrawText(mTewiFont.mFont,Font.CR_WHITE,xx,yy,fullstr,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_ClipLeft,int(26*hs.x));
}
else Screen.DrawText(mTewiFont.mFont,Font.CR_WHITE,xx,yy,fullstr,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
return true;
}
override void Draw( int state, double TicFrac )

View file

@ -1,17 +1,3 @@
// Scoring
Class SWWMCredits : Inventory
{
Default
{
+INVENTORY.UNTOSSABLE;
+INVENTORY.UNDROPPABLE;
+INVENTORY.UNCLEARABLE;
+INVENTORY.ALWAYSPICKUP;
Inventory.MaxAmount 999999999;
Inventory.InterHubAmount 999999999;
}
}
// Base class for all SWWM Armors
Class SWWMArmor : Armor
{

View file

@ -6,6 +6,7 @@ Class Demolitionist : PlayerPawn
double dashfuel, dashboost;
int dashcooldown, boostcooldown, fuelcooldown;
bool dashsnd;
bool key_reentrant;
int lastdamage;
bool lastground;
@ -109,6 +110,8 @@ Class Demolitionist : PlayerPawn
override void Tick()
{
Super.Tick();
if ( !myvoice ) myvoice = CVar.GetCVar('swwm_voicetype',player);
if ( !mute ) mute = CVar.GetCVar('swwm_mutevoice',player);
if ( player.onground && !bNoGravity && !lastground && (waterlevel < 2) && (health > 0) )
{
if ( lastvelz < -30 )
@ -127,6 +130,8 @@ Class Demolitionist : PlayerPawn
}
}
if ( lastvelz < -10 ) A_StartSound("demolitionist/runstop",CHAN_FOOTSTEP,CHANF_OVERLAP);
if ( (lastvelz < -gruntspeed) && (mute.GetInt() < 4) )
A_StartSound(String.Format("voice/%s/grunt",myvoice.GetString()),CHAN_DEMOVOICE,CHANF_OVERLAP);
A_Footstep(0,true,clamp(-lastvelz*0.05,0.01,1.0));
}
lastground = player.onground;
@ -454,11 +459,15 @@ Class Demolitionist : PlayerPawn
if ( !mute ) mute = CVar.GetCVar('swwm_mutevoice',player);
int score = 500;
// last secret (this is called before counting it up, so have to subtract)
if ( level.found_secrets == level.total_secrets-1 ) score = 5000;
Console.Printf(StringTable.Localize("$SWWM_FINDSECRET"),player.GetUserName(),score);
if ( level.found_secrets == level.total_secrets-1 )
{
score = 5000;
Console.Printf(StringTable.Localize("$SWWM_LASTSECRET"),player.GetUserName(),score);
}
else Console.Printf(StringTable.Localize("$SWWM_FINDSECRET"),player.GetUserName(),score);
if ( CheckLocalView() && (mute.GetInt() < 2) ) SWWMHandler.AddOneliner("findsecret",40);
GiveInventory("SWWMCredits",score);
return true;
SWWMCredits.GiveCredits(player,score);
return false;
}
override void AddInventory( Inventory item )
{
@ -466,14 +475,20 @@ Class Demolitionist : PlayerPawn
Super.AddInventory(item);
if ( (item is 'Weapon') && CheckLocalView() && (mute.GetInt() < 2) )
SWWMHandler.AddOneliner("getweapon");
if ( multiplayer && (item is 'Key') )
if ( (item is 'Key') && !key_reentrant )
{
// score
int score = 250;
Console.Printf(StringTable.Localize("$SWWM_FINDKEY"),player.GetUserName(),item.GetTag(),score);
SWWMCredits.GiveCredits(player,score);
// share all keys in mp
for ( int i=0; i<MAXPLAYERS; i++ )
{
if ( !playeringame[i] || !players[i].mo || (i == PlayerNumber()) )
continue;
if ( players[i].mo is 'Demolitionist' ) Demolitionist(players[i].mo).key_reentrant = true;
players[i].mo.GiveInventory(item.GetClass(),1);
if ( players[i].mo is 'Demolitionist' ) Demolitionist(players[i].mo).key_reentrant = false;
}
}
}

View file

@ -398,6 +398,7 @@ Class ExplodiumGun : SWWMWeapon
p.pitch = asin(-dir.z);
p.vel = dir*p.speed;
p.vel.z += 5.;
p.vel += vel*.5;
}
action void A_DropMag( bool loaded = false )
@ -409,6 +410,7 @@ Class ExplodiumGun : SWWMWeapon
c.angle = angle;
c.pitch = pitch;
c.vel = x*FRandom[Junk](-.5,.5)+y*FRandom[Junk](-1.2,.3)-(0,0,FRandom[Junk](2,3));
c.vel += vel*.5;
}
action void A_DropCasing()
@ -421,6 +423,7 @@ Class ExplodiumGun : SWWMWeapon
c.angle = angle;
c.pitch = pitch;
c.vel = x*FRandom[Junk](-.5,.5)+y*FRandom[Junk](2,4)-(0,0,FRandom[Junk](2,3));
c.vel += vel*.5;
}
Default