Added Unreal '96 intro.

Fully implemented all Translator features, including mouse input.
"Class icons" for player config menu (DT xdevel change).
Fix pickup messages for some ammo types (also in DT xdevel).
This commit is contained in:
Marisa the Magician 2019-09-01 22:10:42 +02:00
commit 9c916d09d9
25 changed files with 252 additions and 76 deletions

View file

@ -1,7 +1,8 @@
user int stinger_hudmode = 0; // hud mode
user int stinger_introtype = 0; // 0 - standard
user int stinger_introtype = 0; // 0 - unreal '98
// 1 - unreal '97
// 2 - unreal '95
// 2 - unreal '96
// 3 - unreal '95
server bool sting_telegun = false; // enable teleport capsules
server bool sting_flares = false; // enable light/dark flares
server bool sting_stinger = false; // unreal bible stinger detonation

View file

@ -199,6 +199,10 @@ HardwareShader Texture "graphics/95Bg.png"
{
Shader "shaders/glsl/95Bg.fp"
}
HardwareShader Texture "graphics/96Bg.png"
{
Shader "shaders/glsl/96Bg.fp"
}
HardwareShader Texture "graphics/97Bg.png"
{
Shader "shaders/glsl/97Bg.fp"

BIN
graphics/96Bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

BIN
graphics/96BgC.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
graphics/96BgF.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

After

Width:  |  Height:  |  Size: 1.7 MiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 135 KiB

After

Width:  |  Height:  |  Size: 144 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 KiB

After

Width:  |  Height:  |  Size: 152 KiB

Before After
Before After

BIN
graphics/UnLogo3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

View file

@ -150,7 +150,7 @@ T_SCUBA = "SCUBA Gear";
TR_NOMSG = "No new messages";
TR_NEWMSG = "New Translator message";
TR_MSG = "Translator message";
TR_TESTMSG1 = "This is a test Translator Message.\n\nLorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
TR_TESTMSG1 = "This is a test Translator Message.\n\nLorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Suspendisse interdum consectetur libero id faucibus nisl. Enim sed faucibus turpis in eu mi bibendum. Nullam vehicula ipsum a arcu cursus vitae congue mauris rhoncus. Pulvinar sapien et ligula ullamcorper malesuada proin. Aenean pharetra magna ac placerat. Diam maecenas sed enim ut sem. Vestibulum sed arcu non odio euismod lacinia at quis risus. Turpis massa sed elementum tempus egestas sed. Dolor morbi non arcu risus quis varius. Tempor orci eu lobortis elementum nibh tellus molestie nunc non. Velit aliquet sagittis id consectetur purus ut. Sit amet mattis vulputate enim. Donec massa sapien faucibus et molestie ac feugiat. Adipiscing bibendum est ultricies integer. Eget nullam non nisi est sit amet facilisis magna. Sed libero enim sed faucibus turpis in eu. Pellentesque pulvinar pellentesque habitant morbi tristique senectus et netus.";
TR_TESTMSG2 = "This is another test Translator Message.\n\nColour escapes should work.\n\n \cgRed\c- \ckYellow\c- \chBlue\c-";
TR_TESTMSG3 = "This is yet another test Translator Message.\n\nJust some more filler text, also there's a hint.";
TR_TESTHNT3 = "This is a test hint.\n\nTo defeat the Cyberdemon, shoot it until it dies.";
@ -172,8 +172,9 @@ STING_HOPTS = "HUD Options";
STING_HUDMODE = "HUD mode";
STING_TRANSEXT = "Extended Translator (fits more text)";
STING_INTRO = "Intro type";
STING_UNREAL99 = "Standard";
STING_UNREAL98 = "Unreal '98";
STING_UNREAL97 = "Unreal '97";
STING_UNREAL96 = "Unreal '96";
STING_UNREAL95 = "Unreal '95";
STING_POPTS = "Prototype features";
STING_TELEHAND = "Teleport Capsules";
@ -367,7 +368,6 @@ STING_HOPTS = "Opciones de HUD";
STING_HUDMODE = "Modo de HUD";
STING_TRANSEXT = "Traductor extendido (cabe más texto)";
STING_INTRO = "Tipo de intro";
STING_UNREAL99 = "Estándar";
STING_POPTS = "Características de prototipo";
STING_TELEHAND = "Cápsulas de Teletransporte";
STING_FLARES = "Bengalas de luz/oscuridad";

View file

@ -1,8 +1,9 @@
OptionValue "IntroTypeMenu"
{
0, "$STING_UNREAL99"
0, "$STING_UNREAL98"
1, "$STING_UNREAL97"
2, "$STING_UNREAL95"
2, "$STING_UNREAL96"
3, "$STING_UNREAL95"
}
OptionMenu "UnrealOptionMenu"

BIN
music/isotox96.s3m Normal file

Binary file not shown.

22
shaders/glsl/96Bg.fp Normal file
View file

@ -0,0 +1,22 @@
vec4 ProcessTexel()
{
vec2 uv = vTexCoord.st;
uv.x += 1.;
float ang = timer*0.05;
vec2 uv2 = vec2(uv.x*cos(ang)-uv.y*sin(ang),uv.y*cos(ang)+uv.x*sin(ang))*1.3;
vec3 col = getTexel(fract(uv2)).rgb;
uv.y -= 2.;
ang = timer*0.03;
uv2 = vec2(uv.x*cos(ang)-uv.y*sin(ang),uv.y*cos(ang)+uv.x*sin(ang))*1.5;
col += getTexel(fract(uv2)).rgb;
uv.x -= 3.;
ang = timer*0.04;
uv2 = vec2(uv.x*cos(ang)-uv.y*sin(ang),uv.y*cos(ang)+uv.x*sin(ang))*1.6;
col += getTexel(fract(uv2)).rgb;
uv.y += 4.;
ang = timer*0.02;
uv2 = vec2(uv.x*cos(ang)-uv.y*sin(ang),uv.y*cos(ang)+uv.x*sin(ang))*1.2;
col += getTexel(fract(uv2)).rgb;
col *= 0.25;
return vec4(col,1.);
}

BIN
sprites/player/AMANA0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
sprites/player/ASH_A0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
sprites/player/AWOMA0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
sprites/player/DANTA0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
sprites/player/GINAA0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
sprites/player/KURGA0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

BIN
sprites/player/SONYA0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

View file

@ -13,6 +13,7 @@ Class UFlakBox : Ammo
}
override String PickupMessage()
{
if ( PickupMsg.Length() > 0 ) return Super.PickupMessage();
return String.Format("%s%d%s",StringTable.Localize("$I_FLAKAMMOL"),Amount,StringTable.Localize("$I_FLAKAMMOR"));
}
States

View file

@ -12,6 +12,7 @@ Class UMiniAmmo : Ammo
}
override String PickupMessage()
{
if ( PickupMsg.Length() > 0 ) return Super.PickupMessage();
return String.Format("%s%d%s",StringTable.Localize("$I_MINIAMMOL"),Amount,StringTable.Localize("$I_MINIAMMOR"));
}
}

View file

@ -334,6 +334,12 @@ Class UPlayerFemale1 : UPlayerFemale
UTPlayer.VoiceType VOICE_FemaleTwo;
-NOMENU;
}
States
{
See:
GINA A -1;
Stop;
}
}
Class UPlayerFemale2 : UPlayerFemale
{
@ -344,6 +350,12 @@ Class UPlayerFemale2 : UPlayerFemale
Player.Portrait "";
-NOMENU;
}
States
{
See:
SONY A -1;
Stop;
}
}
Class UMaleTorsoGibber : UTGibber
@ -463,6 +475,12 @@ Class UPlayerMale1 : UPlayerMale
Player.Portrait "";
-NOMENU;
}
States
{
See:
KURG A -1;
Stop;
}
}
Class UPlayerMale2 : UPlayerMale
{
@ -473,6 +491,12 @@ Class UPlayerMale2 : UPlayerMale
Player.Portrait "";
-NOMENU;
}
States
{
See:
ASH_ A -1;
Stop;
}
}
Class UPlayerMale3 : UPlayerMale
{
@ -484,6 +508,12 @@ Class UPlayerMale3 : UPlayerMale
UTPlayer.VoiceType VOICE_MaleTwo;
-NOMENU;
}
States
{
See:
DANT A -1;
Stop;
}
}
Class UnrealInventory : Inventory
@ -599,7 +629,7 @@ Class UnrealWeapon : UTWeapon
Class UnrealStaticHandler : StaticEventHandler
{
ui TextureID tex[6];
ui TextureID tex[8];
ui int mtics, cur;
ui String lastmusic;
@ -610,11 +640,14 @@ Class UnrealStaticHandler : StaticEventHandler
int proto = protomenu.GetInt();
tex[0] = TexMan.CheckForTexture("graphics/UnLogo0.png",TexMan.Type_Any);
tex[1] = TexMan.CheckForTexture("graphics/UnLogo1.png",TexMan.Type_Any);
tex[2] = TexMan.CheckForTexture("graphics/UnLogo2.png",TexMan.Type_Any);
tex[3] = TexMan.CheckForTexture("graphics/UnBg.png",TexMan.Type_Any);
tex[4] = TexMan.CheckForTexture("graphics/97Bg.png",TexMan.Type_Any);
tex[5] = TexMan.CheckForTexture("graphics/95Bg.png",TexMan.Type_Any);
if ( proto > 1 ) S_ChangeMusic("Unreal");
tex[2] = TexMan.CheckForTexture("graphics/UnLogo3.png",TexMan.Type_Any);
tex[3] = TexMan.CheckForTexture("graphics/UnLogo2.png",TexMan.Type_Any);
tex[4] = TexMan.CheckForTexture("graphics/UnBg.png",TexMan.Type_Any);
tex[5] = TexMan.CheckForTexture("graphics/97Bg.png",TexMan.Type_Any);
tex[6] = TexMan.CheckForTexture("graphics/96Bg.png",TexMan.Type_Any);
tex[7] = TexMan.CheckForTexture("graphics/95Bg.png",TexMan.Type_Any);
if ( proto > 2 ) S_ChangeMusic("Unreal");
else if ( proto == 2 ) S_ChangeMusic("Isotox96");
else if ( proto == 1 ) S_ChangeMusic("Unreal2");
else S_ChangeMusic("FlyBy");
cur = proto;
@ -649,13 +682,13 @@ Class UnrealStaticHandler : StaticEventHandler
{
if ( gamestate != GS_TITLELEVEL ) return;
double ar = Screen.GetAspectRatio();
Vector2 tsize = TexMan.GetScaledSize(tex[cur+3]);
Vector2 tsize = TexMan.GetScaledSize(tex[cur+4]);
double sar = tsize.x/tsize.y;
Vector2 vsize;
if ( sar > ar ) vsize = (tsize.y*ar,tsize.y);
else if ( sar < ar ) vsize = (tsize.x,tsize.x/ar);
else vsize = tsize;
Screen.DrawTexture(tex[cur+3],false,(vsize.x-tsize.x)/2,(vsize.y-tsize.y)/2,DTA_VirtualWidthF,vsize.x,DTA_VirtualHeightF,vsize.y,DTA_KeepRatio,true);
Screen.DrawTexture(tex[cur+4],false,(vsize.x-tsize.x)/2,(vsize.y-tsize.y)/2,DTA_VirtualWidthF,vsize.x,DTA_VirtualHeightF,vsize.y,DTA_KeepRatio,true);
Screen.Dim("Black",clamp(1.-((mtics+e.FracTic)/Thinker.TICRATE)*.2,0.,1.),0,0,Screen.GetWidth(),Screen.GetHeight());
if ( menuactive ) return;
tsize = TexMan.GetScaledSize(tex[cur]);
@ -676,8 +709,16 @@ Class UnrealStaticHandler : StaticEventHandler
}
}
Class AmmoUsedInSlot
{
Class<Ammo> AmmoType;
bool UsedInSlot[10];
}
Class UnrealMainHandler : EventHandler
{
Array<AmmoUsedInSlot> AmmoSlots;
override void CheckReplacement( ReplaceEvent e )
{
if ( (e.Replacee == 'Chainsaw') || (e.Replacee == 'Gauntlets') )
@ -1017,5 +1058,32 @@ Class UnrealMainHandler : EventHandler
level.ReplaceTextures("uAlnWl2b","C_WAL19A",0);
level.ReplaceTextures("xAlnWl2b","C_WAL19F",0);
}
// populate ammo-by-slot array
AmmoSlots.Clear();
for ( int i=0; i<AllActorClasses.Size(); i++ )
{
let type = (class<Weapon>)(AllActorClasses[i]);
if ( !type || (type == "Weapon") ) continue;
let rep = Actor.GetReplacement(type);
if ( (rep != type) && !(rep is "DehackedPickup") ) continue;
readonly<Weapon> def = GetDefaultByType(type);
int wslot = def.SlotNumber;
if ( wslot == -1 ) continue;
if ( !def.AmmoType1 ) continue;
int found = -1;
for ( int j=0; j<AmmoSlots.Size(); j++ )
{
if ( AmmoSlots[j].AmmoType != def.AmmoType1 ) continue;
found = j;
}
if ( found == -1 )
{
let asl = new("AmmoUsedInSlot");
asl.AmmoType = def.AmmoType1;
asl.UsedInSlot[wslot] = true;
AmmoSlots.Push(asl);
}
else AmmoSlots[found].UsedInSlot[wslot] = true;
}
}
}

View file

@ -3,6 +3,9 @@ Class UnrealHUD : BaseStatusBar
{
double FracTic;
// for easy access to ammo slots
UnrealMainHandler hnd;
// Unreal HUD variables
Color RedColor, GreenColor, BlackColor;
int HudMode;
@ -301,36 +304,23 @@ Class UnrealHUD : BaseStatusBar
let pw = CPlayer.PendingWeapon;
int pwslot = -1;
if ( pw && (pw != WP_NOCHANGE) && (pw.SlotNumber != -1) ) pwslot = pw.SlotNumber;
Array<Weapon> wslots[10];
Array<Ammo> aslots[10];
// clear the arrays before work
for ( int i=0; i<10; i++ ) wslots[i].Clear();
// first run, populate the full array of weapons
for ( int i=0; i<10; i++ )
for ( int i=0; i<10; i++ ) aslots[i].Clear();
// we need the ammo slots array, if it isn't accessible then we're fucked
if ( !hnd ) hnd = UnrealMainHandler(EventHandler.Find("UnrealMainHandler"));
if ( hnd )
{
for ( Inv = CPlayer.mo.Inv; Inv; Inv=Inv.Inv )
// populate the array
for ( int i=0; i<hnd.AmmoSlots.Size(); i++ )
{
if ( !(Inv is 'Weapon') ) continue;
let w = Weapon(Inv);
if ( w.SlotNumber != i ) continue;
int slot = w.SlotNumber;
wslots[slot].Push(w);
}
}
// second run, sort the slot arrays
for ( int i=0; i<10; i++ )
{
int j = 1;
while ( j < wslots[i].Size() )
{
int k = j;
while ( (k > 0) && (wslots[i][k-1].SelectionOrder >= wslots[i][k].SelectionOrder) )
let a = Ammo(CPlayer.mo.FindInventory(hnd.AmmoSlots[i].AmmoType));
if ( !a ) continue;
for ( int j=0; j<10; j++ )
{
Weapon tmp = wslots[i][k];
wslots[i][k] = wslots[i][k-1];
wslots[i][k-1] = tmp;
k--;
if ( !hnd.AmmoSlots[i].UsedInSlot[j] ) continue;
aslots[j].Push(a);
}
j++;
}
}
// draw the slots
@ -338,22 +328,21 @@ Class UnrealHUD : BaseStatusBar
{
for ( int i=0; i<10; i++ )
{
if ( wslots[i].Size() <= 0 ) continue;
Font cfont = TinyFont;
if ( cwslot == i ) cfont = TinyWhiteFont;
int realslot = i?i:10;
CurX = HalfHUDX-3+realslot*6;
CurY = HalfHUDY+4;
Screen.DrawText(cfont,Font.CR_UNTRANSLATED,CurX,CurY,String.Format("%d",i),DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true);
if ( CPlayer.HasWeaponsInSlot(i) )
Screen.DrawText(cfont,Font.CR_UNTRANSLATED,CurX,CurY,String.Format("%d",i),DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true);
// Draw ammo bar(s)
int nammo = 0;
for ( int j=0; j<wslots[i].Size(); j++ ) if ( wslots[i][j].Ammo1 ) nammo++;
for ( int j=0; j<aslots[i].Size(); j++ ) if ( aslots[i][j].Amount ) nammo++;
if ( nammo <= 0 ) continue;
int cbar = 0;
for ( int j=0; j<wslots[i].Size(); j++ )
for ( int j=0; j<aslots[i].Size(); j++ )
{
let amo = wslots[i][j].Ammo1;
if ( !amo ) continue;
let amo = aslots[i][j];
AmmoBarSize = 16*min(1.0,amo.Amount/double(amo.MaxAmount));
CurX = HalfHUDX-3+realslot*6+(4./nammo)*cbar;
CurY = HalfHUDY+29-AmmoBarSize;
@ -365,7 +354,7 @@ Class UnrealHUD : BaseStatusBar
}
DrawColor = Color(0,255,0);
if ( AmmoBarSize < 8 ) DrawColor = Color(255-int(AmmoBarSize)*30,int(AmmoBarSize)*30+40,0);
if ( wslots[i][j] != cw ) DrawColor = Color(DrawColor.r/2,DrawColor.g/2,DrawColor.b/2);
if ( !cw || (cw.Ammo1 != amo) ) DrawColor = Color(DrawColor.r/2,DrawColor.g/2,DrawColor.b/2);
if ( amo.Amount > 0 )
{
Screen.DrawTexture(HudAmmo,false,CurX,CurY,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true,DTA_FillColor,BlackColor,DTA_DestWidthF,4./nammo,DTA_DestHeightF,AmmoBarSize);
@ -375,7 +364,7 @@ Class UnrealHUD : BaseStatusBar
}
}
}
// draw translator
// flash translator icon
if ( translator ) bFlashTranslator = (translator.bNewMessage || translator.bNotNewMessage);
// draw the inventory bar
if ( (HUDMode == 5) || !SelectedItem ) return;

View file

@ -166,18 +166,21 @@ Class GreenMessageBox : MessageBoxMenu
}
}
// TODO BONUS: Code input menu, like those in various oldskool SP campaigns
// except it's somewhat prettier looking and supports alphanumeric input
Class CodeEntryMenu : GenericMenu {}
// Translator display as a menu, allows for more interactivity
// TODO:
// - additional mouse input options
// - support for extended menu graphic
Class TranslatorMenu : GenericMenu
{
bool bShowHint;
UTranslator trns;
TextureID thud, scroll[4];
TextureID thud[2], scroll[4];
Font tfnt, mfnt, pfnt;
BrokenLines lines;
int th, startline[0], maxlines[2], entry;
int th, startline[2], maxlines[2], entry;
CVar ext;
bool drag;
private void SetText( String txt )
{
@ -187,7 +190,8 @@ Class TranslatorMenu : GenericMenu
th = tfnt.GetHeight();
startline[0] = 0;
startline[1] = 0;
maxlines[0] = 88/th;
maxlines[0] = 81/th;
maxlines[1] = 201/th;
}
override void Init( Menu parent )
@ -196,13 +200,15 @@ Class TranslatorMenu : GenericMenu
trns = UTranslator(players[consoleplayer].mo.FindInventory('UTranslator'));
mfnt = Font.GetFont('UMedFont');
pfnt = Font.GetFont('UOldTinyFont');
ext = CVar.GetCVar('sting_transext',players[consoleplayer]);
if ( !trns || !trns.Owner || (trns.Owner.Health <= 0) )
{
// don't do anything, will get killed in the next tick
return;
}
MenuSound("menu/activate");
thud = TexMan.CheckForTexture("TranHUD3",TexMan.Type_Any);
thud[0] = TexMan.CheckForTexture("TranHUD3",TexMan.Type_Any);
thud[1] = TexMan.CheckForTexture("TranHUDX",TexMan.Type_Any);
scroll[0] = TexMan.CheckForTexture("VSldT",TexMan.Type_Any);
scroll[1] = TexMan.CheckForTexture("VSldM",TexMan.Type_Any);
scroll[2] = TexMan.CheckForTexture("VSldB",TexMan.Type_Any);
@ -239,17 +245,99 @@ Class TranslatorMenu : GenericMenu
switch ( ev.type )
{
case UIEvent.Type_WheelUp:
if ( startline[0] > 0 ) MenuSound("menu/cursor");
startline[0] = max(0,startline[0]-3);
if ( startline[ext.GetInt()] > 0 ) MenuSound("menu/cursor");
startline[ext.GetInt()] = max(0,startline[ext.GetInt()]-1);
return true;
case UIEvent.Type_WheelDown:
if ( startline[0] < max(0,lines.Count()-maxlines[0]) ) MenuSound("menu/cursor");
startline[0] = min(max(0,lines.Count()-maxlines[0]),startline[0]+3);
if ( startline[ext.GetInt()] < max(0,lines.Count()-maxlines[ext.GetInt()]) ) MenuSound("menu/cursor");
startline[ext.GetInt()] = min(max(0,lines.Count()-maxlines[ext.GetInt()]),startline[ext.GetInt()]+1);
return true;
}
return Super.OnUIEvent(ev);
}
protected bool InBox( Vector2 p, Vector2 a, Vector2 b )
{
// pad to make input easier w/ small scales
a -= (8,8);
b += (8,8);
return ((p.x >= a.x) && (p.x < b.x) && (p.y >= a.y) && (p.y < b.y));
}
override bool MouseEvent( int type, int mx, int my )
{
bool res = Super.MouseEvent(type,mx,my);
// box locations for various elements
Vector2 validarea[2], prevmsg[2], nextmsg[2], openhint[2], closehint[2], scrollbar[2];
double ClipX, ClipY, CurX, CurY;
Vector2 vpos;
if ( StatusBar is 'UnrealHUD' )
{
ClipX = UnrealHUD(StatusBar).ClipX;
ClipY = UnrealHUD(StatusBar).ClipY;
vpos.x = mx/UnrealHUD(StatusBar).scalev.x;
vpos.y = my/UnrealHUD(StatusBar).scalev.y;
}
else
{
ClipX = CleanWidth_1;
ClipY = CleanHeight_1;
vpos.x = mx/double(CleanXFac_1);
vpos.y = my/double(CleanYFac_1);
}
if ( ext.GetBool() )
{
validarea[0] = (ClipX/2-112,ClipY/2-112);
validarea[1] = validarea[0]+(224,224);
prevmsg[0] = (ClipX/2-106,ClipY/2+100);
prevmsg[1] = prevmsg[0]+(4,6);
String pagestr = String.Format("< %d / %d ",trns.OldMessages.Size()+1-entry,trns.OldMessages.Size()+1);
int strl = pfnt.StringWidth(pagestr);
nextmsg[0] = prevmsg[0]+(strl,0);
nextmsg[1] = nextmsg[0]+(4,6);
openhint[0] = (ClipX/2+100,ClipY/2+100);
openhint[1] = openhint[0]+(8,6);
closehint[0] = (ClipX/2-106,ClipY/2+100);
closehint[1] = closehint[0]+(8,6);
scrollbar[0] = (ClipX/2+100,ClipY/2-110);
scrollbar[1] = scrollbar[0]+(7,208);
}
else
{
validarea[0] = (ClipX/2-112,ClipY/2-52);
validarea[1] = validarea[0]+(224,104);
prevmsg[0] = (ClipX/2-106,ClipY/2+40);
prevmsg[1] = prevmsg[0]+(4,6);
String pagestr = String.Format("< %d / %d ",trns.OldMessages.Size()+1-entry,trns.OldMessages.Size()+1);
int strl = pfnt.StringWidth(pagestr);
nextmsg[0] = prevmsg[0]+(strl,0);
nextmsg[1] = nextmsg[0]+(4,6);
openhint[0] = (ClipX/2+100,ClipY/2+40);
openhint[1] = openhint[0]+(8,6);
closehint[0] = (ClipX/2-106,ClipY/2+50);
closehint[1] = closehint[0]+(8,6);
scrollbar[0] = (ClipX/2+100,ClipY/2-50);
scrollbar[1] = scrollbar[0]+(7,88);
}
if ( type == MOUSE_Click )
{
if ( !InBox(vpos,validarea[0],validarea[1]) ) MenuEvent(MKEY_Back,true);
else if ( !bShowHint && InBox(vpos,prevmsg[0],prevmsg[1]) ) MenuEvent(MKEY_Left,true);
else if ( !bShowHint && InBox(vpos,nextmsg[0],nextmsg[1]) ) MenuEvent(MKEY_Right,true);
else if ( !bShowHint && InBox(vpos,openhint[0],openhint[1]) ) MenuEvent(MKEY_PageDown,true);
else if ( bShowHint && InBox(vpos,closehint[0],closehint[1]) ) MenuEvent(MKEY_PageUp,true);
else if ( InBox(vpos,scrollbar[0],scrollbar[1]) ) drag = true;
}
else if ( type == MOUSE_Release ) drag = false;
if ( drag )
{
double scl = (ext.GetInt()?192:72)/max(1,lines.Count()-maxlines[ext.GetInt()]);
int vclamp = int((clamp(vpos.y,scrollbar[0].y+4,scrollbar[1].y-4)-(scrollbar[0].y+4))/scl);
startline[ext.GetInt()] = clamp(vclamp,0,max(0,lines.Count()-maxlines[ext.GetInt()]));
}
return res;
}
override bool MenuEvent( int mkey, bool fromcontroller )
{
switch( mkey )
@ -262,12 +350,12 @@ Class TranslatorMenu : GenericMenu
Close();
return true;
case MKEY_Up:
if ( startline[0] > 0 ) MenuSound("menu/cursor");
startline[0] = max(0,startline[0]-1);
if ( startline[ext.GetInt()] > 0 ) MenuSound("menu/cursor");
startline[ext.GetInt()] = max(0,startline[ext.GetInt()]-1);
return true;
case MKEY_Down:
if ( startline[0] < max(0,lines.Count()-maxlines[0]) ) MenuSound("menu/cursor");
startline[0] = min(max(0,lines.Count()-maxlines[0]),startline[0]+1);
if ( startline[ext.GetInt()] < max(0,lines.Count()-maxlines[ext.GetInt()]) ) MenuSound("menu/cursor");
startline[ext.GetInt()] = min(max(0,lines.Count()-maxlines[ext.GetInt()]),startline[ext.GetInt()]+1);
return true;
case MKEY_PageDown:
if ( trns && (GetHint(entry).length() > 0) )
@ -310,7 +398,7 @@ Class TranslatorMenu : GenericMenu
override void Drawer()
{
Super.Drawer();
if ( trns && trns.Owner && (trns.Owner.Health > 0) ) return;
if ( !trns || !trns.Owner || (trns.Owner.Health <= 0) ) return;
double ClipX, ClipY, CurX, CurY;
if ( StatusBar is 'UnrealHUD' )
{
@ -324,13 +412,13 @@ Class TranslatorMenu : GenericMenu
}
// The translator
CurX = ClipX/2-128;
CurY = ClipY/2-68;
Screen.DrawTexture(thud,false,CurX,CurY,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true);
CurY = ClipY/2-(ext.GetInt()?128:68);
Screen.DrawTexture(thud[ext.GetInt()],false,CurX,CurY,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true);
// The message text
CurX += 22;
CurY += 22;
int l = startline[0];
for ( int i=0; i<maxlines[0]; i++ )
int l = startline[ext.GetInt()];
for ( int i=0; i<maxlines[ext.GetInt()]; i++ )
{
if ( l >= lines.Count() ) break;
Screen.DrawText(tfnt,Font.CR_UNTRANSLATED,CurX,CurY,lines.StringAt(l),DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true);
@ -339,28 +427,29 @@ Class TranslatorMenu : GenericMenu
}
// Scrollbar
CurX = ClipX/2+100;
if ( lines.Count() > maxlines[0] )
if ( lines.Count() > maxlines[ext.GetInt()] )
{
CurY = ClipY/2-54;
CurY = ClipY/2-(ext.GetInt()?114:54);
Screen.DrawTexture(scroll[0],false,CurX,CurY,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true);
CurY += 8;
for ( int i=0; i<10; i++ )
int cnt = ext.GetInt()?25:10;
for ( int i=0; i<cnt; i++ )
{
Screen.DrawTexture(scroll[1],false,CurX,CurY,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true);
CurY += 8;
}
Screen.DrawTexture(scroll[2],false,CurX,CurY,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true);
CurY = (ClipY/2-46) + ((startline[0]*72)/max(1,lines.Count()-maxlines[0]));
CurY = (ClipY/2-(ext.GetInt()?106:46)) + ((startline[ext.GetInt()]*(ext.GetInt()?192:72))/max(1,lines.Count()-maxlines[ext.GetInt()]));
Screen.DrawTexture(scroll[3],false,CurX,CurY,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true);
}
if ( !bShowHint && (GetHint(entry).length() > 0) )
{
CurY = ClipY/2+40;
Screen.DrawText(pfnt,Font.CR_GREEN,CurX,CurY,">>",DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true,DTA_Alpha,(gametic%16)/16.);
CurY = ClipY/2+(ext.GetInt()?100:40);
Screen.DrawText(pfnt,Font.CR_GREEN,CurX,CurY,">>",DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true,DTA_Alpha,(MenuTime()%16)/16.);
}
CurX = ClipX/2-106;
CurY = ClipY/2+40;
if ( bShowHint ) Screen.DrawText(pfnt,Font.CR_GREEN,CurX,CurY,"<<",DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true,DTA_Alpha,(gametic%16)/16.);
CurY = ClipY/2+(ext.GetInt()?100:40);
if ( bShowHint ) Screen.DrawText(pfnt,Font.CR_GREEN,CurX,CurY,"<<",DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true,DTA_Alpha,(MenuTime()%16)/16.);
else if ( trns.OldMessages.Size() > 0 ) Screen.DrawText(pfnt,Font.CR_GREEN,CurX,CurY,String.Format("%s %d / %d %s",(entry<trns.OldMessages.Size())?"<":" ",trns.OldMessages.Size()+1-entry,trns.OldMessages.Size()+1,(entry>0)?">":" "),DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true);
}
}