787 lines
23 KiB
Text
787 lines
23 KiB
Text
// additional hud things
|
|
|
|
// Press F to Pay Respects
|
|
Class PayRespects : HUDMessageBase
|
|
{
|
|
Vector2 basepos;
|
|
int lifespan, initialspan, starttic;
|
|
double scale;
|
|
double hs;
|
|
Vector2 ss;
|
|
int seed, seed2;
|
|
Font mSmallFont;
|
|
|
|
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();
|
|
f.mSmallFont = Font.GetFont('TewiFont');
|
|
return f;
|
|
}
|
|
|
|
override bool Tick()
|
|
{
|
|
lifespan--;
|
|
return (lifespan<=0);
|
|
}
|
|
|
|
override void ScreenSizeChanged()
|
|
{
|
|
hs = CleanXFac*scale;
|
|
ss = (Screen.GetWidth(),Screen.GetHeight())/hs;
|
|
}
|
|
|
|
override void Draw( int bottom, int visibility )
|
|
{
|
|
Vector2 realpos = (basepos.x*ss.x,basepos.y*ss.y);
|
|
Vector2 fo = (mSmallFont.StringWidth("F")/2.,-mSmallFont.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 = System.GetTimeFrac();
|
|
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(mSmallFont,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;
|
|
transient BrokenLines l;
|
|
int lifespan, curtime;
|
|
Font mSmallFont;
|
|
|
|
static SWWMOneLiner Make( String whichline, int lifespan )
|
|
{
|
|
let l = new("SWWMOneLiner");
|
|
if ( StringTable.Localize(whichline) == "" ) l.whichline = "";
|
|
else l.whichline = StringTable.Localize("$SWWM_LQUOTE")..StringTable.Localize(whichline)..StringTable.Localize("$SWWM_RQUOTE");
|
|
l.curtime = l.lifespan = lifespan;
|
|
l.mSmallFont = Font.GetFont('TewiFont');
|
|
return l;
|
|
}
|
|
|
|
override bool Tick()
|
|
{
|
|
if ( players[consoleplayer].Health <= 0 ) curtime = int.min;
|
|
curtime--;
|
|
return (curtime<-20);
|
|
}
|
|
|
|
override void ScreenSizeChanged()
|
|
{
|
|
if ( l ) l.Destroy();
|
|
}
|
|
|
|
override void Draw( int bottom, int visibility )
|
|
{
|
|
int margin = swwm_hudmargin;
|
|
double hs = max(min(floor(Screen.GetWidth()/640.),floor(Screen.GetHeight()/360.)),1.);
|
|
Vector2 ss = (Screen.GetWidth()/hs,Screen.GetHeight()/hs);
|
|
if ( whichline == "" ) return; // don't draw empty strings
|
|
// split so it can fit
|
|
if ( !l ) l = mSmallFont.BreakLines(whichline,int(ss.x*.5));
|
|
int maxlen = 0;
|
|
for ( int i=0; i<l.Count(); i++ )
|
|
{
|
|
int len = mSmallFont.StringWidth(l.StringAt(i));
|
|
if ( len > maxlen ) maxlen = len;
|
|
}
|
|
int h = mSmallFont.GetHeight();
|
|
int fh = h*l.Count();
|
|
double fractic = System.GetTimeFrac();
|
|
double fcurtime = curtime-fractic;
|
|
double alph = clamp((fcurtime/20.)+1.,0.,1.);
|
|
alph *= clamp((lifespan-fcurtime)/10.,0.,1.);
|
|
Screen.Dim("Black",alph*.8,int((Screen.GetWidth()-(maxlen+12)*hs)/2.),int(bottom-(margin+2+fh)*hs),int((maxlen+12)*hs),int((fh+4)*hs));
|
|
int yy = margin+fh;
|
|
for ( int i=0; i<l.Count(); i++ )
|
|
{
|
|
int len = mSmallFont.StringWidth(l.StringAt(i));
|
|
Screen.DrawText(mSmallFont,Font.CR_FIRE,int((ss.x-len)/2.),(bottom/hs)-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;
|
|
double fractic = System.GetTimeFrac();
|
|
double falpha = alpha-fractic*(1./duration);
|
|
Screen.Dim(col,(col.a/255.)*falpha*swwm_flashstrength,0,0,Screen.GetWidth(),Screen.GetHeight(),STYLE_Add);
|
|
}
|
|
}
|
|
|
|
Class QueuedFlash
|
|
{
|
|
Color c;
|
|
int duration;
|
|
int tic;
|
|
Actor cam;
|
|
}
|
|
|
|
// Achievement notification
|
|
Class SWWMAchievementNotification : HUDMessageBase
|
|
{
|
|
String tag, txt;
|
|
transient BrokenLines l;
|
|
TextureID icon, frame;
|
|
double tics, holdtics, fadeintics, fadeouttics;
|
|
Font mSmallFont, mTinyFont;
|
|
|
|
SWWMAchievementNotification Init( String bname, TextureID icon, int num = 0 )
|
|
{
|
|
tag = StringTable.Localize("$SWWM_ACHIEVEMENT_"..bname.."_TAG");
|
|
txt = StringTable.Localize("$SWWM_ACHIEVEMENT_"..bname.."_TXT");
|
|
if ( num ) txt = String.Format(txt,num);
|
|
self.icon = icon;
|
|
frame = TexMan.CheckForTexture("graphics/HUD/AchievementNotification.png",TexMan.Type_Any);
|
|
holdtics = 150;
|
|
fadeintics = 20;
|
|
fadeouttics = 30;
|
|
tics = 0;
|
|
mSmallFont = Font.GetFont('TewiFont');
|
|
mTinyFont = Font.GetFont('MiniwiFont');
|
|
return self;
|
|
}
|
|
|
|
override bool Tick()
|
|
{
|
|
return (++tics > holdtics+fadeintics+fadeouttics);
|
|
}
|
|
|
|
override void Draw( int bottom, int visibility )
|
|
{
|
|
double margin = swwm_hudmargin;
|
|
double hs = max(min(floor(Screen.GetWidth()/640.),floor(Screen.GetHeight()/360.)),1.);
|
|
Vector2 ss = (Screen.GetWidth()/hs,Screen.GetHeight()/hs);
|
|
double fractic = System.GetTimeFrac();
|
|
double ftics = tics+fractic;
|
|
double alpha = (ftics<fadeintics)?(ftics/fadeintics):(ftics<(fadeintics+holdtics))?1.:(1.-(ftics-(fadeintics+holdtics))/fadeouttics);
|
|
Vector2 pos = (int(ss.x-256)/2,(ss.y-(margin+36))+int(margin+40)*(1.-alpha));
|
|
if ( !l ) l = mTinyFont.BreakLines(txt,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(mSmallFont,Font.CR_GREEN,pos.x+40,pos.y+yy,tag,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(mTinyFont,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;
|
|
}
|
|
}
|
|
}
|
|
|
|
// weapon tooltips
|
|
Class SWWMWeaponTooltip : HUDMessageBase
|
|
{
|
|
String wpn, txt;
|
|
double tics, holdtics, fadeintics, fadeouttics;
|
|
transient BrokenLines l;
|
|
SWWMWeaponTooltip next;
|
|
Font mSmallFont, mTinyFont;
|
|
|
|
SWWMWeaponTooltip Init( Class<SWWMWeapon> weapon )
|
|
{
|
|
let def = GetDefaultByType(weapon);
|
|
wpn = def.GetTag();
|
|
txt = StringTable.Localize(def.tooltip);
|
|
holdtics = 150;
|
|
fadeintics = 5;
|
|
fadeouttics = 15;
|
|
tics = -10;
|
|
mSmallFont = Font.GetFont('TewiFont');
|
|
mTinyFont = Font.GetFont('MiniwiFont');
|
|
return self;
|
|
}
|
|
|
|
override bool Tick()
|
|
{
|
|
bool clearme = (++tics > holdtics+fadeintics+fadeouttics);
|
|
if ( clearme && next ) StatusBar.AttachMessage(next,-2910);
|
|
return clearme;
|
|
}
|
|
|
|
override void Draw( int bottom, int visibility )
|
|
{
|
|
if ( tics <= 0 ) return;
|
|
double hs = max(min(floor(Screen.GetWidth()/640.),floor(Screen.GetHeight()/360.)),1.);
|
|
Vector2 ss = (Screen.GetWidth()/hs,Screen.GetHeight()/hs);
|
|
double fractic = System.GetTimeFrac();
|
|
double ftics = tics+fractic;
|
|
double alpha = (ftics<fadeintics)?(ftics/fadeintics):(ftics<(fadeintics+holdtics))?1.:(1.-(ftics-(fadeintics+holdtics))/fadeouttics);
|
|
int w = mSmallFont.StringWidth(wpn);
|
|
if ( !l ) l = mTinyFont.BreakLines(txt,600);
|
|
int w1 = w;
|
|
w = 0;
|
|
for ( int i=0; i<l.Count(); i++ )
|
|
{
|
|
let lw = mTinyFont.StringWidth(l.StringAt(i));
|
|
if ( lw > w ) w = lw;
|
|
}
|
|
int cw = int(ceil((max(w1,w)+8)/6.))*6;
|
|
int h = mSmallFont.GetHeight()+8+mTinyFont.GetHeight()*l.Count();
|
|
Vector2 pos = (int(ss.x/2),ss.y-(swwm_hudmargin+80+h));
|
|
Screen.Dim("Black",.5*alpha,int((pos.x-(cw+4)/2)*hs),int((pos.y-2)*hs),int((cw+4)*hs),int((h+4)*hs));
|
|
Screen.DrawText(mSmallFont,Font.CR_FIRE,pos.x-w1/2,pos.y,wpn,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_Alpha,alpha);
|
|
for ( int i=0; i<cw; i+=6 )
|
|
Screen.DrawChar(mSmallFont,Font.CR_FIRE,(pos.x-cw/2)+i,pos.y+6,0x5F,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_Alpha,alpha);
|
|
pos.y += mSmallFont.GetHeight()+8;
|
|
for ( int i=0; i<l.Count(); i++ )
|
|
{
|
|
Screen.DrawText(mTinyFont,Font.CR_WHITE,pos.x-w/2,pos.y,l.StringAt(i),DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_Alpha,alpha);
|
|
pos.y += mTinyFont.GetHeight();
|
|
}
|
|
}
|
|
}
|
|
|
|
// Used sparingly for some events
|
|
Class SWWMDirectMessage : HUDMessageBase
|
|
{
|
|
TextureID MessageBox, BG, Avatar, Blink[2], Talk[5], Noiz[4];
|
|
transient BrokenLines l;
|
|
String seqname, chrname, chrfullname;
|
|
bool znvspecial; // seqnum 2 string replacement
|
|
int seqnum, seqcnt, delay, charcnt, blinktics, talktics, talkframe;
|
|
int startdelay, enddelay, pausedelay;
|
|
int rss;
|
|
int fadein, fadeout;
|
|
double hs;
|
|
Vector2 ss, origin;
|
|
SWWMDirectMessage nextmsg; // for chaining messages together from different characters
|
|
bool nextdirect; // skips directly to next message without delays or fades
|
|
Font mSmallFont;
|
|
|
|
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;
|
|
startdelay = 30;
|
|
enddelay = 40;
|
|
pausedelay = 30;
|
|
rss = 1232;
|
|
mSmallFont = Font.GetFont('TewiFont');
|
|
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);
|
|
if ( l ) l.Destroy();
|
|
l = mSmallFont.BreakLines(txt,220);
|
|
// append to the player's chat log (if it's valid)
|
|
if ( (seqnum < 1) || (seqnum > seqcnt) ) return;
|
|
EventHandler.SendNetworkEvent("swwmstoremessage."..chrname..": "..txt,level.totaltime,PRINT_CHAT,consoleplayer);
|
|
}
|
|
|
|
private void DrawText()
|
|
{
|
|
if ( !l ) SetText();
|
|
int cur = charcnt;
|
|
Vector2 pos = origin+(47,3);
|
|
for ( int i=0; i<l.Count(); i++ )
|
|
{
|
|
if ( cur <= 0 ) break;
|
|
String part = l.StringAt(i).Left(cur);
|
|
Screen.DrawText(mSmallFont,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( double fractic )
|
|
{
|
|
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[int(((gametic+fractic)/GameTicRate)*15)%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("menu/demochat",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("menu/demochat",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 = startdelay;
|
|
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.;
|
|
double fractic = System.GetTimeFrac();
|
|
if ( seqnum == 0 ) alph = (fadein+fractic)/15.;
|
|
else if ( seqnum == (seqcnt+1) ) alph = 1.-(fadeout+fractic)/30.;
|
|
double hs = max(min(floor(Screen.GetWidth()/640.),floor(Screen.GetHeight()/360.)),1.);
|
|
ss = (Screen.GetWidth()/hs,Screen.GetHeight()/hs);
|
|
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(fractic);
|
|
DrawText();
|
|
}
|
|
}
|
|
|
|
// used to manually trigger dialogues through a hacky method in the hud
|
|
// because zscript is fucking stupid with its handling of names, we can't
|
|
// pass the dialogue name to arguments, so it'll have to be hardcoded
|
|
Class SWWMDialogueTrigger : Actor
|
|
{
|
|
default
|
|
{
|
|
+NOBLOCKMAP;
|
|
+NOGRAVITY;
|
|
+NOINTERACTION;
|
|
+DONTSPLASH;
|
|
}
|
|
override void Activate( Actor activator )
|
|
{
|
|
static const String dlglist[] =
|
|
{
|
|
"swwmultdoom2map20dlg"
|
|
};
|
|
if ( !swwm_nomapmsg )
|
|
Console.MidPrint(null,dlglist[args[0]]);
|
|
Destroy();
|
|
}
|
|
override void Tick() {}
|
|
}
|
|
|
|
// I'm just doing this as an experiment, don't mind me
|
|
|
|
Class DSMapTitle : HUDMessageBase
|
|
{
|
|
Struct FntGlyph
|
|
{
|
|
int x, y, width, height, xofs, yofs, advance;
|
|
};
|
|
|
|
TextureID atlas, atlas_sub;
|
|
FntGlyph glyphs[256], glyphs_sub[256];
|
|
int fheight, fheight_sub;
|
|
|
|
String txt, txtsub;
|
|
int tics, holdtics, fadeintics, fadeouttics;
|
|
int ultics;
|
|
|
|
// all the actual hard code
|
|
int MyStringWidth( String str )
|
|
{
|
|
int w = 0;
|
|
int lw = 0;
|
|
int len = str.CodePointCount();
|
|
for ( int i=0, pos=0; i<len; i++ )
|
|
{
|
|
int ch;
|
|
[ch, pos] = str.GetNextCodePoint(pos);
|
|
if ( ch > 255 ) continue;
|
|
lw += glyphs[ch].advance;
|
|
// newline, restart line width
|
|
if ( ch == 0x0a )
|
|
{
|
|
w = max(w,lw);
|
|
lw = 0;
|
|
}
|
|
}
|
|
w = max(w,lw);
|
|
return w;
|
|
}
|
|
int MySubStringWidth( String str )
|
|
{
|
|
int w = 0;
|
|
int lw = 0;
|
|
int len = str.CodePointCount();
|
|
for ( int i=0, pos=0; i<len; i++ )
|
|
{
|
|
int ch;
|
|
[ch, pos] = str.GetNextCodePoint(pos);
|
|
if ( ch > 255 ) continue;
|
|
lw += glyphs_sub[ch].advance;
|
|
// newline, restart line width
|
|
if ( ch == 0x0a )
|
|
{
|
|
w = max(w,lw);
|
|
lw = 0;
|
|
}
|
|
}
|
|
w = max(w,lw);
|
|
return w;
|
|
}
|
|
void MyDrawText( String str, double x, double y, Vector2 ss, double alpha = 1. )
|
|
{
|
|
int len = str.CodePointCount();
|
|
double xx = x;
|
|
double yy = y;
|
|
for ( int i=0, pos=0; i<len; i++ )
|
|
{
|
|
int ch;
|
|
[ch, pos] = str.GetNextCodePoint(pos);
|
|
if ( ch > 255 ) continue;
|
|
if ( glyphs[ch].width && glyphs[ch].height )
|
|
{
|
|
Screen.DrawTexture(atlas,false,xx-glyphs[ch].xofs,yy-glyphs[ch].yofs,
|
|
DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,
|
|
DTA_SrcX,glyphs[ch].x,DTA_SrcY,glyphs[ch].y,
|
|
DTA_SrcWidth,glyphs[ch].width,DTA_SrcHeight,glyphs[ch].height,
|
|
DTA_DestWidth,glyphs[ch].width,DTA_DestHeight,glyphs[ch].height,
|
|
DTA_Alpha,alpha);
|
|
}
|
|
xx += glyphs[ch].advance;
|
|
// newline
|
|
if ( ch == 0x0a )
|
|
{
|
|
xx = x;
|
|
yy += fheight;
|
|
}
|
|
}
|
|
}
|
|
void MySubDrawText( String str, double x, double y, Vector2 ss, double alpha = 1. )
|
|
{
|
|
int len = str.CodePointCount();
|
|
double xx = x;
|
|
double yy = y;
|
|
for ( int i=0, pos=0; i<len; i++ )
|
|
{
|
|
int ch;
|
|
[ch, pos] = str.GetNextCodePoint(pos);
|
|
if ( ch > 255 ) continue;
|
|
if ( glyphs_sub[ch].width && glyphs_sub[ch].height )
|
|
{
|
|
Screen.DrawTexture(atlas_sub,false,xx-glyphs_sub[ch].xofs,yy-glyphs_sub[ch].yofs,
|
|
DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,
|
|
DTA_SrcX,glyphs_sub[ch].x,DTA_SrcY,glyphs_sub[ch].y,
|
|
DTA_SrcWidth,glyphs_sub[ch].width,DTA_SrcHeight,glyphs_sub[ch].height,
|
|
DTA_DestWidth,glyphs_sub[ch].width,DTA_DestHeight,glyphs_sub[ch].height,
|
|
DTA_Alpha,alpha);
|
|
}
|
|
xx += glyphs_sub[ch].advance;
|
|
// newline
|
|
if ( ch == 0x0a )
|
|
{
|
|
xx = x;
|
|
yy += fheight_sub;
|
|
}
|
|
}
|
|
}
|
|
// stretches the "_" glyph over a specific width, center-aligned
|
|
void DrawUnderline( double x, double y, Vector2 ss, double width, double alpha = 1. )
|
|
{
|
|
double xx = x-width/2;
|
|
// l stem
|
|
Screen.DrawTexture(atlas,false,xx-4,y,
|
|
DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,
|
|
DTA_SrcX,glyphs[95].x,DTA_SrcY,glyphs[95].y,
|
|
DTA_SrcWidth,4,DTA_SrcHeight,glyphs[95].height,
|
|
DTA_DestWidthF,4,DTA_DestHeight,glyphs[95].height,
|
|
DTA_Alpha,alpha);
|
|
// long
|
|
Screen.DrawTexture(atlas,false,xx,y,
|
|
DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,
|
|
DTA_SrcX,glyphs[95].x+4,DTA_SrcY,glyphs[95].y,
|
|
DTA_SrcWidth,glyphs[95].width-8,DTA_SrcHeight,glyphs[95].height,
|
|
DTA_DestWidthF,width,DTA_DestHeight,glyphs[95].height,
|
|
DTA_Alpha,alpha);
|
|
// r stem
|
|
Screen.DrawTexture(atlas,false,xx+width,y,
|
|
DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,
|
|
DTA_SrcX,glyphs[95].x+(glyphs[95].width-4),DTA_SrcY,glyphs[95].y,
|
|
DTA_SrcWidth,4,DTA_SrcHeight,glyphs[95].height,
|
|
DTA_DestWidthF,4,DTA_DestHeight,glyphs[95].height,
|
|
DTA_Alpha,alpha);
|
|
}
|
|
|
|
DSMapTitle Init()
|
|
{
|
|
txt = level.levelname;
|
|
txtsub = level.authorname;
|
|
if ( txt.Left(1) == "$" ) txt = StringTable.Localize(txt);
|
|
if ( txtsub.Left(1) == "$" ) txtsub = StringTable.Localize(txtsub);
|
|
tics = -10;
|
|
holdtics = 140;
|
|
fadeintics = 20;
|
|
fadeouttics = 40;
|
|
ultics = 50;
|
|
atlas = TexMan.CheckForTexture("graphics/dsmapfont.png",TexMan.Type_Any);
|
|
if ( !atlas.IsValid() || atlas.IsNull() ) ThrowAbortException("font atlas texture not found");
|
|
let lmp = Wads.CheckNumForFullname("graphics/dsmapfont.txt");
|
|
if ( lmp == -1 ) ThrowAbortException("font definition file not found");
|
|
String dat = Wads.ReadLump(lmp);
|
|
Array<String> list, ln;
|
|
// fucking Windows
|
|
dat.Replace("\r","");
|
|
list.Clear();
|
|
dat.Split(list,"\n");
|
|
int ch = 0;
|
|
for ( int i=0; i<list.Size(); i++ )
|
|
{
|
|
if ( (list[i].Length() == 0) || (list[i].Left(2) == "//") || (list[i].Left(1) == "") )
|
|
continue;
|
|
if ( i == 0 )
|
|
{
|
|
// first line is always font height
|
|
fheight = list[i].ToInt();
|
|
continue;
|
|
}
|
|
ln.Clear();
|
|
list[i].Split(ln," ",0);
|
|
glyphs[ch].x = ln[0].ToInt();
|
|
glyphs[ch].y = ln[1].ToInt();
|
|
glyphs[ch].width = ln[2].ToInt();
|
|
glyphs[ch].height = ln[3].ToInt();
|
|
glyphs[ch].xofs = ln[4].ToInt();
|
|
glyphs[ch].yofs = ln[5].ToInt();
|
|
glyphs[ch].advance = ln[6].ToInt();
|
|
ch++;
|
|
}
|
|
if ( ch != 256 ) ThrowAbortException("font definition does not list all 256 glyphs");
|
|
atlas_sub = TexMan.CheckForTexture("graphics/dsmapfont_sub.png",TexMan.Type_Any);
|
|
if ( !atlas_sub.IsValid() || atlas_sub.IsNull() ) ThrowAbortException("sub font atlas texture not found");
|
|
lmp = Wads.CheckNumForFullname("graphics/dsmapfont_sub.txt");
|
|
if ( lmp == -1 ) ThrowAbortException("sub font definition file not found");
|
|
dat = Wads.ReadLump(lmp);
|
|
// fucking Windows
|
|
dat.Replace("\r","");
|
|
list.Clear();
|
|
dat.Split(list,"\n");
|
|
ch = 0;
|
|
for ( int i=0; i<list.Size(); i++ )
|
|
{
|
|
if ( (list[i].Length() == 0) || (list[i].Left(2) == "//") || (list[i].Left(1) == "") )
|
|
continue;
|
|
if ( i == 0 )
|
|
{
|
|
// first line is always font height
|
|
fheight_sub = list[i].ToInt();
|
|
continue;
|
|
}
|
|
ln.Clear();
|
|
list[i].Split(ln," ",0);
|
|
glyphs_sub[ch].x = ln[0].ToInt();
|
|
glyphs_sub[ch].y = ln[1].ToInt();
|
|
glyphs_sub[ch].width = ln[2].ToInt();
|
|
glyphs_sub[ch].height = ln[3].ToInt();
|
|
glyphs_sub[ch].xofs = ln[4].ToInt();
|
|
glyphs_sub[ch].yofs = ln[5].ToInt();
|
|
glyphs_sub[ch].advance = ln[6].ToInt();
|
|
ch++;
|
|
}
|
|
if ( ch != 256 ) ThrowAbortException("sub font definition does not list all 256 glyphs");
|
|
return self;
|
|
}
|
|
|
|
override bool Tick()
|
|
{
|
|
if ( tics == 0 ) S_StartSound("misc/newarea",CHAN_VOICE,CHANF_UI,pitch:.75); // dunno why the source file is pitched up
|
|
return (++tics > holdtics+fadeintics+fadeouttics);
|
|
}
|
|
|
|
override void Draw( int bottom, int visibility )
|
|
{
|
|
if ( tics <= 0 ) return;
|
|
double hs = max(min(floor(Screen.GetWidth()/640.),floor(Screen.GetHeight()/360.)),1.);
|
|
Vector2 ss = (Screen.GetWidth(),Screen.GetHeight())/hs;
|
|
double fractic = System.GetTimeFrac();
|
|
double ftics = tics+fractic;
|
|
double alpha = (ftics<fadeintics)?(ftics/fadeintics):(ftics<(fadeintics+holdtics))?1.:(1.-(ftics-(fadeintics+holdtics))/fadeouttics);
|
|
int w = MyStringWidth(txt);
|
|
int w2 = MySubStringWidth(txtsub);
|
|
double xx = int(ss.x/2.);
|
|
double yy = int(ss.y/2.)-64.;
|
|
double wfact = clamp(ftics/double(ultics),0.,1.);
|
|
DrawUnderline(xx,yy+1,ss,(w+32)*wfact,alpha);
|
|
MyDrawText(txt,xx-w/2,yy,ss,alpha);
|
|
MySubDrawText(txtsub,xx-w2/2,yy+fheight_sub+12,ss,alpha);
|
|
}
|
|
}
|