496 lines
14 KiB
Text
496 lines
14 KiB
Text
// additional hud things
|
|
|
|
// 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;
|
|
hs.y = hs.x;
|
|
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
|
|
{
|
|
String whichline;
|
|
int lifespan, curtime;
|
|
transient Font TewiFont, MPlusFont;
|
|
|
|
static SWWMOneLiner Make( String whichline, int lifespan )
|
|
{
|
|
let l = new("SWWMOneLiner");
|
|
l.whichline = whichline;
|
|
l.curtime = l.lifespan = lifespan;
|
|
return l;
|
|
}
|
|
|
|
override bool Tick()
|
|
{
|
|
if ( players[consoleplayer].Health <= 0 ) curtime = int.min;
|
|
curtime--;
|
|
return (curtime<-20);
|
|
}
|
|
|
|
override void Draw( int bottom, int visibility )
|
|
{
|
|
if ( !TewiFont ) TewiFont = Font.GetFont('TewiShaded');
|
|
if ( !MPlusFont ) MPlusFont = Font.GetFont('MPlusShaded');
|
|
int margin = swwm_hudmargin;
|
|
Vector2 hs;
|
|
if ( swwm_hudscale <= 0 ) hs = StatusBar.GetHUDScale();
|
|
else hs.x = swwm_hudscale;
|
|
hs.y = hs.x;
|
|
Vector2 ss = (Screen.GetWidth()/hs.x,Screen.GetHeight()/hs.y);
|
|
String loc = StringTable.Localize(whichline);
|
|
if ( loc.Length() <= 0 ) return; // don't draw empty strings
|
|
String locs = StringTable.Localize("$SWWM_LQUOTE")..loc..StringTable.Localize("$SWWM_RQUOTE");
|
|
Font fnt = TewiFont;
|
|
if ( language ~== "jp" ) fnt = MPlusFont;
|
|
// split so it can fit
|
|
BrokenLines l = fnt.BreakLines(locs,int(ss.x*.5));
|
|
int maxlen = 0;
|
|
for ( int i=0; i<l.Count(); i++ )
|
|
{
|
|
int len = fnt.StringWidth(l.StringAt(i));
|
|
if ( len > maxlen ) maxlen = len;
|
|
}
|
|
int h = fnt.GetHeight();
|
|
int fh = h*l.Count();
|
|
double alph = clamp((curtime/20.)+1.,0.,1.);
|
|
alph *= clamp((lifespan-curtime)/10.,0.,1.);
|
|
Screen.Dim("Black",alph*.8,int((Screen.GetWidth()-(maxlen+12)*hs.x)/2.),int(bottom-(margin+2+fh)*hs.y),int((maxlen+12)*hs.x),int((fh+4)*hs.y));
|
|
int yy = margin+fh;
|
|
for ( int i=0; i<l.Count(); i++ )
|
|
{
|
|
int len = fnt.StringWidth(l.StringAt(i));
|
|
Screen.DrawText(fnt,Font.CR_FIRE,int((ss.x-len)/2.),(bottom/hs.y)-yy,l.StringAt(i),DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_Alpha,alph);
|
|
yy -= h;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Screen flashes from DT
|
|
Class GenericFlash : HUDMessageBase
|
|
{
|
|
Color col;
|
|
int duration;
|
|
double alpha;
|
|
Actor cam;
|
|
|
|
GenericFlash Setup( Actor camera, Color c, int d )
|
|
{
|
|
alpha = 1.0;
|
|
col = c;
|
|
duration = d;
|
|
cam = camera;
|
|
return self;
|
|
}
|
|
override bool Tick()
|
|
{
|
|
if ( duration > 0 ) alpha -= 1./duration;
|
|
return (alpha<=0)||(!cam);
|
|
}
|
|
override void Draw( int bottom, int visibility )
|
|
{
|
|
if ( automapactive || (visibility != BaseStatusBar.HUDMSGLayer_UnderHUD) ) return;
|
|
if ( cam && (players[consoleplayer].camera != cam) ) return;
|
|
Screen.Dim(col,(col.a/255.)*alpha*swwm_flashstrength,0,0,Screen.GetWidth(),Screen.GetHeight());
|
|
}
|
|
}
|
|
|
|
Class QueuedFlash
|
|
{
|
|
Color c;
|
|
int duration;
|
|
int tic;
|
|
Actor cam;
|
|
}
|
|
|
|
// Achievement notification
|
|
Class SWWMAchievementNotification : HUDMessageBase
|
|
{
|
|
String tag, txt;
|
|
int num;
|
|
TextureID icon, frame;
|
|
double tics, holdtics, fadeintics, fadeouttics;
|
|
transient Font tewifont, mplusfont, miniwifont, k6x8font;
|
|
|
|
SWWMAchievementNotification Init( String bname, TextureID icon, int bnum = 0 )
|
|
{
|
|
tag = "$SWWM_ACHIEVEMENT_"..bname.."_TAG";
|
|
txt = "$SWWM_ACHIEVEMENT_"..bname.."_TXT";
|
|
num = bnum;
|
|
self.icon = icon;
|
|
frame = TexMan.CheckForTexture("graphics/HUD/AchievementNotification.png",TexMan.Type_Any);
|
|
holdtics = 150;
|
|
fadeintics = 20;
|
|
fadeouttics = 30;
|
|
tics = 0;
|
|
return self;
|
|
}
|
|
|
|
override bool Tick()
|
|
{
|
|
return (++tics > holdtics+fadeintics+fadeouttics);
|
|
}
|
|
|
|
override void Draw( int bottom, int visibility )
|
|
{
|
|
if ( !tewifont ) tewifont = Font.GetFont('TewiShaded');
|
|
if ( !mplusfont ) mplusfont = Font.GetFont('MPlusShaded');
|
|
if ( !miniwifont ) miniwifont = Font.GetFont('MiniwiShaded');
|
|
if ( !k6x8font ) k6x8font = Font.GetFont('k6x8Shaded');
|
|
let fnt = tewifont;
|
|
let fnt2 = miniwifont;
|
|
if ( language ~== "jp" )
|
|
{
|
|
fnt = mplusfont;
|
|
fnt2 = k6x8font;
|
|
}
|
|
double margin = swwm_hudmargin;
|
|
Vector2 hs;
|
|
if ( swwm_hudscale <= 0 ) hs = StatusBar.GetHUDScale();
|
|
else hs.x = swwm_hudscale;
|
|
hs.y = hs.x;
|
|
Vector2 ss = (Screen.GetWidth()/hs.x,Screen.GetHeight()/hs.y);
|
|
double alpha = (tics<fadeintics)?(tics/fadeintics):(tics<(fadeintics+holdtics))?1.:(1.-(tics-(fadeintics+holdtics))/fadeouttics);
|
|
Vector2 pos = (int(ss.x-256)/2,(ss.y-(margin+36))+int(margin+40)*(1.-alpha));
|
|
String loctag = StringTable.Localize(tag);
|
|
String loctxt = num?String.Format(StringTable.Localize(txt),num):StringTable.Localize(txt);
|
|
BrokenLines l = fnt2.BreakLines(loctxt,200);
|
|
int th = 14+(9*l.Count());
|
|
Screen.DrawTexture(frame,false,pos.x,pos.y,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_Alpha,alpha);
|
|
if ( icon.IsValid() ) Screen.DrawTexture(icon,false,pos.x+2,pos.y+2,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_Alpha,alpha);
|
|
int yy = 2+(32-th)/2;
|
|
Screen.DrawText(fnt,Font.CR_GREEN,pos.x+40,pos.y+yy,loctag,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_Alpha,alpha);
|
|
yy += 14;
|
|
for ( int i=0; i<l.Count(); i++ )
|
|
{
|
|
Screen.DrawText(fnt2,Font.CR_WHITE,pos.x+44,pos.y+yy,l.StringAt(i),DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_Alpha,alpha);
|
|
yy += 9;
|
|
}
|
|
}
|
|
}
|
|
|
|
Class SWWMSewerCount : HUDMessageBase
|
|
{
|
|
int tics;
|
|
String str;
|
|
|
|
SWWMSewerCount Init()
|
|
{
|
|
tics = 200;
|
|
str = String.Format("Sewer Count: %d",swwm_sewercount);
|
|
return self;
|
|
}
|
|
|
|
override bool Tick()
|
|
{
|
|
if ( tics == 100 ) S_StartSound("misc/sewercount",CHAN_VOICE,CHANF_UI,1.,0.);
|
|
return (tics--<=0);
|
|
}
|
|
|
|
override void Draw( int bottom, int visibility )
|
|
{
|
|
if ( tics > 100 ) return;
|
|
double alph = clamp(tics/20.,0.,1.);
|
|
double x = (Screen.GetWidth()-(newsmallfont.StringWidth(str)*CleanXFac*2))/2;
|
|
double y = int(Screen.GetHeight()*.75)-(newsmallfont.GetHeight()*CleanYFac*2)/2;
|
|
Screen.DrawText(newsmallfont,Font.CR_GREEN,x,y,str,DTA_ScaleX,CleanXFac*2,DTA_ScaleY,CleanYFac*2,DTA_Alpha,alph);
|
|
}
|
|
}
|
|
|
|
// Used sparingly for some events
|
|
Class SWWMDirectMessage : HUDMessageBase
|
|
{
|
|
TextureID MessageBox, BG, Avatar, Blink[2], Talk[5], Noiz[4];
|
|
transient Font fnt, jpfnt;
|
|
transient BrokenLines l;
|
|
String seqname, chrname, chrfullname;
|
|
bool znvspecial; // seqnum 2 string replacement
|
|
int seqnum, seqcnt, delay, charcnt, blinktics, talktics, talkframe;
|
|
int enddelay, pausedelay;
|
|
int rss;
|
|
int fadein, fadeout;
|
|
Vector2 ss, hs, origin;
|
|
SWWMDirectMessage nextmsg; // for chaining messages together from different characters
|
|
bool nextdirect; // skips directly to next message without delays or fades
|
|
|
|
private int GetRandom()
|
|
{
|
|
return (rss = (rss<<1)*35447+(rss/87));
|
|
}
|
|
|
|
virtual SWWMDirectMessage Init( String chrn, String chrfn, String texn )
|
|
{
|
|
MessageBox = TexMan.CheckForTexture("graphics/HUD/DM/DirectMessageBox.png",TexMan.Type_Any);
|
|
BG = TexMan.CheckForTexture("graphics/HUD/DM/"..texn.."AvatarBG.png",TexMan.Type_Any);
|
|
Avatar = TexMan.CheckForTexture("graphics/HUD/DM/"..texn.."Avatar.png",TexMan.Type_Any);
|
|
for ( int i=0; i<2; i++ )
|
|
Blink[i] = TexMan.CheckForTexture("graphics/HUD/DM/"..texn.."AvatarBlink"..i..".png",TexMan.Type_Any);
|
|
for ( int i=0; i<5; i++ )
|
|
Talk[i] = TexMan.CheckForTexture("graphics/HUD/DM/"..texn.."AvatarTalk"..i..".png",TexMan.Type_Any);
|
|
for ( int i=0; i<4; i++ )
|
|
Noiz[i] = TexMan.CheckForTexture("graphics/HUD/DM/DirectMessageStatic"..i..".png",TexMan.Type_Any);
|
|
chrname = chrn;
|
|
chrfullname = chrfn;
|
|
seqnum = -1;
|
|
charcnt = 0;
|
|
blinktics = 30;
|
|
talktics = 0;
|
|
talkframe = -1;
|
|
enddelay = 40;
|
|
pausedelay = 30;
|
|
rss = 1232;
|
|
return self;
|
|
}
|
|
|
|
private void SetText()
|
|
{
|
|
String txt;
|
|
if ( (seqnum == 2) && znvspecial )
|
|
{
|
|
// replace with number of years since 2010
|
|
int nyears = SystemTime.Format("%Y",SystemTime.Now()).ToInt()-2010;
|
|
txt = String.Format(StringTable.Localize("$SWWM_"..seqname..seqnum),nyears);
|
|
}
|
|
else txt = StringTable.Localize("$SWWM_"..seqname..seqnum);
|
|
l = fnt.BreakLines(txt,220);
|
|
// append to the player's chat log
|
|
let bar = SWWMStatusBar(StatusBar);
|
|
if ( bar )
|
|
{
|
|
let l = new("MsgLine");
|
|
l.str = chrname..": "..txt;
|
|
l.tic = level.totaltime;
|
|
l.rep = 1;
|
|
l.type = PRINT_CHAT;
|
|
bar.FullHistory.Push(l);
|
|
}
|
|
}
|
|
|
|
private void DrawText()
|
|
{
|
|
if ( !fnt ) fnt = Font.GetFont('TewiShaded');
|
|
if ( !jpfnt ) jpfnt = Font.GetFont('MPlusShaded');
|
|
if ( !l ) SetText();
|
|
int cur = charcnt;
|
|
Vector2 pos = origin+(47,2);
|
|
for ( int i=0; i<l.Count(); i++ )
|
|
{
|
|
if ( cur <= 0 ) break;
|
|
String part = l.StringAt(i).Left(cur);
|
|
Screen.DrawText((language~=="jp")?jpfnt:fnt,Font.CR_WHITE,pos.x,pos.y,part,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
pos.y += 13;
|
|
cur -= l.StringAt(i).Length();
|
|
}
|
|
}
|
|
|
|
private void DrawAvatar()
|
|
{
|
|
int blinkframe = -1;
|
|
switch ( blinktics )
|
|
{
|
|
case -1:
|
|
case -3:
|
|
blinkframe = 0;
|
|
break;
|
|
case -2:
|
|
blinkframe = 1;
|
|
break;
|
|
}
|
|
Screen.DrawTexture(BG,false,origin.x+2,origin.y+2,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
Screen.DrawTexture(Avatar,false,origin.x+2,origin.y+2,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
if ( (seqnum > 0) && (seqnum < (seqcnt+1)) )
|
|
{
|
|
if ( blinkframe >= 0 ) Screen.DrawTexture(Blink[blinkframe],false,origin.x+2,origin.y+2,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
if ( talkframe >= 0 ) Screen.DrawTexture(Talk[talkframe],false,origin.x+2,origin.y+2,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
}
|
|
Screen.DrawTexture(Noiz[(gametic/2)%4],false,origin.x+2,origin.y+2,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_LegacyRenderStyle,STYLE_Multiply);
|
|
}
|
|
|
|
private int TotalLength()
|
|
{
|
|
if ( !l ) SetText();
|
|
int len = 0;
|
|
for ( int i=0; i<l.Count(); i++ )
|
|
len += l.StringAt(i).Length();
|
|
return len;
|
|
}
|
|
|
|
private String GetChar( int pos )
|
|
{
|
|
if ( !l ) SetText();
|
|
int cur = pos;
|
|
for ( int i=0; i<l.Count(); i++ )
|
|
{
|
|
int len = l.StringAt(i).Length();
|
|
if ( cur < len )
|
|
return l.StringAt(i).Mid(cur,1);
|
|
cur -= len;
|
|
}
|
|
return "";
|
|
}
|
|
|
|
private void AdvanceText()
|
|
{
|
|
String notalk = " \t\n,;:.-!?";
|
|
String punctuation = ",;:.";
|
|
if ( charcnt >= TotalLength() )
|
|
{
|
|
seqnum++;
|
|
charcnt = 0;
|
|
if ( (seqnum > seqcnt) && !nextdirect ) S_StartSound("misc/chat",CHAN_VOICE,CHANF_UI,1.,0.);
|
|
else SetText();
|
|
return;
|
|
}
|
|
String ch = GetChar(charcnt);
|
|
// skip over color escapes
|
|
if ( ch == "\c" )
|
|
{
|
|
ch = GetChar(++charcnt);
|
|
if ( ch == "[" ) while ( (ch = GetChar(++charcnt)) != "]" );
|
|
charcnt++;
|
|
ch = GetChar(charcnt);
|
|
}
|
|
// speech
|
|
if ( notalk.IndexOf(ch) == -1 )
|
|
{
|
|
S_StartSound("misc/voice",CHAN_VOICE,CHANF_UI,.6,ATTN_NONE);
|
|
talktics = 5;
|
|
}
|
|
// delay relative to stuff
|
|
delay = 1;
|
|
int idx = punctuation.IndexOf(ch);
|
|
if ( idx >= 0 ) delay += (idx*2)+1;
|
|
charcnt++;
|
|
// utf-8 skipping (naive but works, as we don't have to EXPECT invalid sequences in the input)
|
|
if ( ch.ByteAt(0)&0xE0 == 0xC0 ) charcnt++;
|
|
else if ( ch.ByteAt(0)&0xF0 == 0xE0 ) charcnt += 2;
|
|
else if ( ch.ByteAt(0)&0xF8 == 0xF0 ) charcnt += 3;
|
|
if ( charcnt >= TotalLength() ) delay += (seqnum==seqcnt)?enddelay:pausedelay;
|
|
}
|
|
|
|
override bool Tick()
|
|
{
|
|
if ( seqnum < 0 )
|
|
{
|
|
delay--;
|
|
if ( delay <= 0 )
|
|
{
|
|
Console.Printf(StringTable.Localize("$SWWM_INCOMINGMSG"),chrfullname);
|
|
S_StartSound("misc/chat",CHAN_VOICE,CHANF_UI,1.,0.);
|
|
seqnum++;
|
|
}
|
|
return false;
|
|
}
|
|
if ( blinktics <= 0 )
|
|
{
|
|
blinktics--;
|
|
if ( blinktics < -3 ) blinktics = (abs(GetRandom())%10)?(60+abs(GetRandom())%30):6;
|
|
}
|
|
else blinktics--;
|
|
if ( talktics > 0 )
|
|
{
|
|
if ( !(gametic%3) ) talkframe = (talkframe==-1)?(abs(GetRandom())%5):-1;
|
|
talktics--;
|
|
}
|
|
else talkframe = -1;
|
|
if ( seqnum > (seqcnt+1) )
|
|
{
|
|
if ( nextmsg ) StatusBar.AttachMessage(nextmsg,-1232);
|
|
return true;
|
|
}
|
|
if ( seqnum == 0 )
|
|
{
|
|
fadein++;
|
|
if ( fadein > 15 )
|
|
{
|
|
delay = 30;
|
|
seqnum++;
|
|
}
|
|
return false;
|
|
}
|
|
if ( seqnum == (seqcnt+1) )
|
|
{
|
|
if ( nextmsg && nextdirect )
|
|
{
|
|
nextmsg.seqnum = 1;
|
|
StatusBar.AttachMessage(nextmsg,-1232);
|
|
return true;
|
|
}
|
|
fadeout++;
|
|
if ( fadeout > 30 ) seqnum++;
|
|
return false;
|
|
}
|
|
if ( delay > 0 )
|
|
{
|
|
delay--;
|
|
return false;
|
|
}
|
|
AdvanceText();
|
|
return false;
|
|
}
|
|
|
|
override void Draw( int bottom, int visibility )
|
|
{
|
|
if ( (seqnum < 0) || (seqnum > (seqcnt+1)) ) return;
|
|
double alph = 1.;
|
|
if ( seqnum == 0 ) alph = fadein/15.;
|
|
else if ( seqnum == (seqcnt+1) ) alph = 1.-fadeout/30.;
|
|
if ( swwm_hudscale <= 0 ) hs = StatusBar.GetHUDScale();
|
|
else hs.x = swwm_hudscale;
|
|
hs.y = hs.x;
|
|
ss = (Screen.GetWidth()/hs.x,Screen.GetHeight()/hs.y);
|
|
origin = (int(ss.x-270)/2,swwm_hudmargin+70);
|
|
Screen.DrawTexture(MessageBox,false,origin.x,origin.y,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_Alpha,alph);
|
|
if ( (seqnum < 1) || (seqnum > seqcnt) ) return;
|
|
DrawAvatar();
|
|
DrawText();
|
|
}
|
|
}
|