2008-03-22 09:26:59 +00:00
|
|
|
/*
|
|
|
|
** sbarinfo_display.cpp
|
|
|
|
**
|
|
|
|
** Contains all functions required for the display of custom statusbars.
|
|
|
|
**
|
|
|
|
**---------------------------------------------------------------------------
|
|
|
|
** Copyright 2008 Braden Obrzut
|
|
|
|
** All rights reserved.
|
|
|
|
**
|
|
|
|
** Redistribution and use in source and binary forms, with or without
|
|
|
|
** modification, are permitted provided that the following conditions
|
|
|
|
** are met:
|
|
|
|
**
|
|
|
|
** 1. Redistributions of source code must retain the above copyright
|
|
|
|
** notice, this list of conditions and the following disclaimer.
|
|
|
|
** 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
** notice, this list of conditions and the following disclaimer in the
|
|
|
|
** documentation and/or other materials provided with the distribution.
|
|
|
|
** 3. The name of the author may not be used to endorse or promote products
|
|
|
|
** derived from this software without specific prior written permission.
|
|
|
|
**
|
|
|
|
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
|
|
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
|
|
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
|
|
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
|
|
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
|
|
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
|
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
|
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
|
|
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
**---------------------------------------------------------------------------
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
|
2008-03-19 09:53:23 +00:00
|
|
|
#include "doomtype.h"
|
|
|
|
#include "doomstat.h"
|
|
|
|
#include "v_font.h"
|
|
|
|
#include "v_video.h"
|
|
|
|
#include "sbar.h"
|
|
|
|
#include "r_defs.h"
|
|
|
|
#include "w_wad.h"
|
|
|
|
#include "m_random.h"
|
|
|
|
#include "d_player.h"
|
|
|
|
#include "st_stuff.h"
|
|
|
|
#include "r_local.h"
|
|
|
|
#include "m_swap.h"
|
|
|
|
#include "a_keys.h"
|
|
|
|
#include "templates.h"
|
|
|
|
#include "i_system.h"
|
|
|
|
#include "sbarinfo.h"
|
|
|
|
#include "gi.h"
|
|
|
|
#include "r_translate.h"
|
|
|
|
#include "r_main.h"
|
2008-05-18 15:48:03 +00:00
|
|
|
#include "a_weaponpiece.h"
|
2008-05-19 23:07:08 +00:00
|
|
|
#include "a_strifeglobal.h"
|
2008-03-19 09:53:23 +00:00
|
|
|
|
|
|
|
static FRandom pr_chainwiggle; //use the same method of chain wiggling as heretic.
|
|
|
|
|
|
|
|
#define ST_RAMPAGETIME (TICRATE*2)
|
|
|
|
#define ARTIFLASH_OFFSET (invBarOffset+6)
|
|
|
|
|
|
|
|
EXTERN_CVAR(Int, fraglimit)
|
|
|
|
EXTERN_CVAR(Int, screenblocks)
|
2008-08-09 03:43:29 +00:00
|
|
|
EXTERN_CVAR(Bool, vid_fps)
|
2008-03-19 09:53:23 +00:00
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
imgARTIBOX,
|
|
|
|
imgSELECTBOX,
|
2008-05-19 23:07:08 +00:00
|
|
|
imgCURSOR,
|
2008-03-19 09:53:23 +00:00
|
|
|
imgINVLFGEM1,
|
|
|
|
imgINVLFGEM2,
|
|
|
|
imgINVRTGEM1,
|
|
|
|
imgINVRTGEM2,
|
|
|
|
};
|
|
|
|
|
|
|
|
//Used for shading
|
|
|
|
FBarShader::FBarShader(bool vertical, bool reverse) //make an alpha map
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
Width = vertical ? 2 : 256;
|
|
|
|
Height = vertical ? 256 : 2;
|
|
|
|
CalcBitSize();
|
|
|
|
|
|
|
|
// Fill the column/row with shading values.
|
|
|
|
// Vertical shaders have have minimum alpha at the top
|
|
|
|
// and maximum alpha at the bottom, unless flipped by
|
|
|
|
// setting reverse to true. Horizontal shaders are just
|
|
|
|
// the opposite.
|
|
|
|
if (vertical)
|
|
|
|
{
|
|
|
|
if (!reverse)
|
|
|
|
{
|
|
|
|
for (i = 0; i < 256; ++i)
|
|
|
|
{
|
|
|
|
Pixels[i] = i;
|
|
|
|
Pixels[256+i] = i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (i = 0; i < 256; ++i)
|
|
|
|
{
|
|
|
|
Pixels[i] = 255 - i;
|
|
|
|
Pixels[256+i] = 255 -i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!reverse)
|
|
|
|
{
|
|
|
|
for (i = 0; i < 256; ++i)
|
|
|
|
{
|
|
|
|
Pixels[i*2] = 255 - i;
|
|
|
|
Pixels[i*2+1] = 255 - i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (i = 0; i < 256; ++i)
|
|
|
|
{
|
|
|
|
Pixels[i*2] = i;
|
|
|
|
Pixels[i*2+1] = i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
DummySpan[0].TopOffset = 0;
|
2008-05-14 23:39:40 +00:00
|
|
|
DummySpan[0].Length = vertical ? 256 : 2;
|
2008-03-19 09:53:23 +00:00
|
|
|
DummySpan[1].TopOffset = 0;
|
|
|
|
DummySpan[1].Length = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
const BYTE *FBarShader::GetColumn(unsigned int column, const Span **spans_out)
|
|
|
|
{
|
|
|
|
if (spans_out != NULL)
|
|
|
|
{
|
|
|
|
*spans_out = DummySpan;
|
|
|
|
}
|
2008-05-14 23:39:40 +00:00
|
|
|
return Pixels + ((column & WidthMask) << HeightBits);
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const BYTE *FBarShader::GetPixels()
|
|
|
|
{
|
|
|
|
return Pixels;
|
|
|
|
}
|
|
|
|
|
|
|
|
void FBarShader::Unload()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
//SBarInfo Display
|
|
|
|
DSBarInfo::DSBarInfo () : DBaseStatusBar (SBarInfoScript->height),
|
|
|
|
shader_horz_normal(false, false),
|
|
|
|
shader_horz_reverse(false, true),
|
|
|
|
shader_vert_normal(true, false),
|
|
|
|
shader_vert_reverse(true, true)
|
|
|
|
{
|
|
|
|
static const char *InventoryBarLumps[] =
|
|
|
|
{
|
2008-05-19 23:07:08 +00:00
|
|
|
"ARTIBOX", "SELECTBO", "INVCURS", "INVGEML1",
|
2008-03-19 09:53:23 +00:00
|
|
|
"INVGEML2", "INVGEMR1", "INVGEMR2",
|
|
|
|
"USEARTIA", "USEARTIB", "USEARTIC", "USEARTID",
|
|
|
|
};
|
|
|
|
TArray<const char *> patchnames;
|
|
|
|
patchnames.Resize(SBarInfoScript->Images.Size()+10);
|
|
|
|
unsigned int i = 0;
|
|
|
|
for(i = 0;i < SBarInfoScript->Images.Size();i++)
|
|
|
|
{
|
|
|
|
patchnames[i] = SBarInfoScript->Images[i];
|
|
|
|
}
|
|
|
|
for(i = 0;i < 10;i++)
|
|
|
|
{
|
|
|
|
patchnames[i+SBarInfoScript->Images.Size()] = InventoryBarLumps[i];
|
|
|
|
}
|
2008-03-26 08:50:54 +00:00
|
|
|
for (i = 0;i < numskins;i++)
|
|
|
|
{
|
|
|
|
AddFaceToImageCollection (&skins[i], &Images);
|
|
|
|
}
|
2008-03-19 09:53:23 +00:00
|
|
|
invBarOffset = SBarInfoScript->Images.Size();
|
|
|
|
Images.Init(&patchnames[0], patchnames.Size());
|
|
|
|
drawingFont = V_GetFont("ConFont");
|
|
|
|
oldHealth = 0;
|
|
|
|
oldArmor = 0;
|
|
|
|
chainWiggle = 0;
|
|
|
|
artiflash = 4;
|
2008-04-09 07:32:33 +00:00
|
|
|
currentPopup = POP_None;
|
|
|
|
pendingPopup = POP_None;
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
DSBarInfo::~DSBarInfo ()
|
|
|
|
{
|
|
|
|
Images.Uninit();
|
|
|
|
}
|
|
|
|
|
|
|
|
void DSBarInfo::Draw (EHudState state)
|
|
|
|
{
|
|
|
|
DBaseStatusBar::Draw(state);
|
2008-03-22 09:26:59 +00:00
|
|
|
int hud = STBAR_NORMAL;
|
2008-03-19 09:53:23 +00:00
|
|
|
if(state == HUD_StatusBar)
|
|
|
|
{
|
|
|
|
if(SBarInfoScript->completeBorder) //Fill the statusbar with the border before we draw.
|
|
|
|
{
|
|
|
|
FTexture *b = TexMan[gameinfo.border->b];
|
- Ported vlinetallasm4 to AMD64 assembly. Even with the increased number of
registers AMD64 provides, this routine still needs to be written as self-
modifying code for maximum performance. The additional registers do allow
for further optimization over the x86 version by allowing all four pixels
to be in flight at the same time. The end result is that AMD64 ASM is about
2.18 times faster than AMD64 C and about 1.06 times faster than x86 ASM.
(For further comparison, AMD64 C and x86 C are practically the same for
this function.) Should I port any more assembly to AMD64, mvlineasm4 is the
most likely candidate, but it's not used enough at this point to bother.
Also, this may or may not work with Linux at the moment, since it doesn't
have the eh_handler metadata. Win64 is easier, since I just need to
structure the function prologue and epilogue properly and use some
assembler directives/macros to automatically generate the metadata. And
that brings up another point: You need YASM to assemble the AMD64 code,
because NASM doesn't support the Win64 metadata directives.
- Added an SSE version of DoBlending. This is strictly C intrinsics.
VC++ still throws around unneccessary register moves. GCC seems to be
pretty close to optimal, requiring only about 2 cycles/color. They're
both faster than my hand-written MMX routine, so I don't need to feel
bad about not hand-optimizing this for x64 builds.
- Removed an extra instruction from DoBlending_MMX, transposed two
instructions, and unrolled it once, shaving off about 80 cycles from the
time required to blend 256 palette entries. Why? Because I tried writing
a C version of the routine using compiler intrinsics and was appalled by
all the extra movq's VC++ added to the code. GCC was better, but still
generated extra instructions. I only wanted a C version because I can't
use inline assembly with VC++'s x64 compiler, and x64 assembly is a bit
of a pain. (It's a pain because Linux and Windows have different calling
conventions, and you need to maintain extra metadata for functions.) So,
the assembly version stays and the C version stays out.
- Removed all the pixel doubling r_detail modes, since the one platform they
were intended to assist (486) actually sees very little benefit from them.
- Rewrote CheckMMX in C and renamed it to CheckCPU.
- Fixed: CPUID function 0x80000005 is specified to return detailed L1 cache
only for AMD processors, so we must not use it on other architectures, or
we end up overwriting the L1 cache line size with 0 or some other number
we don't actually understand.
SVN r1134 (trunk)
2008-08-09 03:13:43 +00:00
|
|
|
R_DrawBorder(viewwindowx, viewwindowy + viewheight + b->GetHeight(), viewwindowx + viewwidth, SCREENHEIGHT);
|
2008-03-19 09:53:23 +00:00
|
|
|
if(screenblocks == 10)
|
- Ported vlinetallasm4 to AMD64 assembly. Even with the increased number of
registers AMD64 provides, this routine still needs to be written as self-
modifying code for maximum performance. The additional registers do allow
for further optimization over the x86 version by allowing all four pixels
to be in flight at the same time. The end result is that AMD64 ASM is about
2.18 times faster than AMD64 C and about 1.06 times faster than x86 ASM.
(For further comparison, AMD64 C and x86 C are practically the same for
this function.) Should I port any more assembly to AMD64, mvlineasm4 is the
most likely candidate, but it's not used enough at this point to bother.
Also, this may or may not work with Linux at the moment, since it doesn't
have the eh_handler metadata. Win64 is easier, since I just need to
structure the function prologue and epilogue properly and use some
assembler directives/macros to automatically generate the metadata. And
that brings up another point: You need YASM to assemble the AMD64 code,
because NASM doesn't support the Win64 metadata directives.
- Added an SSE version of DoBlending. This is strictly C intrinsics.
VC++ still throws around unneccessary register moves. GCC seems to be
pretty close to optimal, requiring only about 2 cycles/color. They're
both faster than my hand-written MMX routine, so I don't need to feel
bad about not hand-optimizing this for x64 builds.
- Removed an extra instruction from DoBlending_MMX, transposed two
instructions, and unrolled it once, shaving off about 80 cycles from the
time required to blend 256 palette entries. Why? Because I tried writing
a C version of the routine using compiler intrinsics and was appalled by
all the extra movq's VC++ added to the code. GCC was better, but still
generated extra instructions. I only wanted a C version because I can't
use inline assembly with VC++'s x64 compiler, and x64 assembly is a bit
of a pain. (It's a pain because Linux and Windows have different calling
conventions, and you need to maintain extra metadata for functions.) So,
the assembly version stays and the C version stays out.
- Removed all the pixel doubling r_detail modes, since the one platform they
were intended to assist (486) actually sees very little benefit from them.
- Rewrote CheckMMX in C and renamed it to CheckCPU.
- Fixed: CPUID function 0x80000005 is specified to return detailed L1 cache
only for AMD processors, so we must not use it on other architectures, or
we end up overwriting the L1 cache line size with 0 or some other number
we don't actually understand.
SVN r1134 (trunk)
2008-08-09 03:13:43 +00:00
|
|
|
screen->FlatFill(viewwindowx, viewwindowy + viewheight, viewwindowx + viewwidth, viewwindowy + viewheight + b->GetHeight(), b, true);
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
|
|
|
if(SBarInfoScript->automapbar && automapactive)
|
|
|
|
{
|
2008-03-22 09:26:59 +00:00
|
|
|
hud = STBAR_AUTOMAP;
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-03-22 09:26:59 +00:00
|
|
|
hud = STBAR_NORMAL;
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(state == HUD_Fullscreen)
|
|
|
|
{
|
2008-03-22 09:26:59 +00:00
|
|
|
hud = STBAR_FULLSCREEN;
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-03-22 09:26:59 +00:00
|
|
|
hud = STBAR_NONE;
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
|
|
|
if(SBarInfoScript->huds[hud].forceScaled) //scale the statusbar
|
|
|
|
{
|
2008-08-06 07:38:21 +00:00
|
|
|
SetScaled(true, true);
|
2008-03-19 09:53:23 +00:00
|
|
|
setsizeneeded = true;
|
|
|
|
}
|
2008-04-25 09:40:08 +00:00
|
|
|
doCommands(SBarInfoScript->huds[hud], 0, 0, SBarInfoScript->huds[hud].alpha);
|
2008-03-19 09:53:23 +00:00
|
|
|
if(CPlayer->inventorytics > 0 && !(level.flags & LEVEL_NOINVENTORYBAR))
|
|
|
|
{
|
|
|
|
if(state == HUD_StatusBar)
|
2008-08-06 07:38:21 +00:00
|
|
|
{
|
|
|
|
// No overlay? Lets cancel it.
|
|
|
|
if(SBarInfoScript->huds[STBAR_INVENTORY].commands.Size() == 0)
|
|
|
|
CPlayer->inventorytics = 0;
|
|
|
|
else
|
|
|
|
doCommands(SBarInfoScript->huds[STBAR_INVENTORY], 0, 0, SBarInfoScript->huds[STBAR_INVENTORY].alpha);
|
|
|
|
}
|
2008-03-19 09:53:23 +00:00
|
|
|
else if(state == HUD_Fullscreen)
|
2008-08-06 07:38:21 +00:00
|
|
|
{
|
|
|
|
if(SBarInfoScript->huds[STBAR_INVENTORYFULLSCREEN].commands.Size() == 0)
|
|
|
|
CPlayer->inventorytics = 0;
|
|
|
|
else
|
|
|
|
doCommands(SBarInfoScript->huds[STBAR_INVENTORYFULLSCREEN], 0, 0, SBarInfoScript->huds[STBAR_INVENTORYFULLSCREEN].alpha);
|
|
|
|
}
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
2008-03-24 17:48:55 +00:00
|
|
|
if(currentPopup != POP_None)
|
|
|
|
{
|
2008-04-25 09:40:08 +00:00
|
|
|
int popbar = 0;
|
2008-03-24 17:48:55 +00:00
|
|
|
if(currentPopup == POP_Log)
|
2008-04-25 09:40:08 +00:00
|
|
|
popbar = STBAR_POPUPLOG;
|
2008-03-24 17:48:55 +00:00
|
|
|
else if(currentPopup == POP_Keys)
|
2008-04-25 09:40:08 +00:00
|
|
|
popbar = STBAR_POPUPKEYS;
|
2008-03-24 17:48:55 +00:00
|
|
|
else if(currentPopup == POP_Status)
|
2008-04-25 09:40:08 +00:00
|
|
|
popbar = STBAR_POPUPSTATUS;
|
2008-06-11 23:12:27 +00:00
|
|
|
doCommands(SBarInfoScript->huds[popbar], SBarInfoScript->popups[currentPopup-1].getXOffset(), SBarInfoScript->popups[currentPopup-1].getYOffset(),
|
|
|
|
SBarInfoScript->popups[currentPopup-1].getAlpha(SBarInfoScript->huds[popbar].alpha));
|
2008-03-24 17:48:55 +00:00
|
|
|
}
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void DSBarInfo::NewGame ()
|
|
|
|
{
|
|
|
|
if (CPlayer != NULL)
|
|
|
|
{
|
|
|
|
AttachToPlayer (CPlayer);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void DSBarInfo::AttachToPlayer (player_t *player)
|
|
|
|
{
|
|
|
|
DBaseStatusBar::AttachToPlayer(player);
|
2008-06-01 03:35:47 +00:00
|
|
|
MugShot.CurrentState = NULL;
|
|
|
|
}
|
|
|
|
|
2008-06-01 22:41:46 +00:00
|
|
|
void DSBarInfo::SetMugShotState (const char *state_name, bool wait_till_done, bool reset)
|
2008-06-01 03:35:47 +00:00
|
|
|
{
|
2008-06-01 22:41:46 +00:00
|
|
|
MugShot.SetState(state_name, wait_till_done, reset);
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void DSBarInfo::Tick ()
|
|
|
|
{
|
|
|
|
DBaseStatusBar::Tick();
|
|
|
|
if(level.time & 1)
|
|
|
|
chainWiggle = pr_chainwiggle() & 1;
|
|
|
|
if(!SBarInfoScript->interpolateHealth)
|
|
|
|
{
|
|
|
|
oldHealth = CPlayer->health;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if(oldHealth > CPlayer->health)
|
|
|
|
{
|
|
|
|
oldHealth -= clamp((oldHealth - CPlayer->health) >> 2, 1, SBarInfoScript->interpolationSpeed);
|
|
|
|
}
|
|
|
|
else if(oldHealth < CPlayer->health)
|
|
|
|
{
|
|
|
|
oldHealth += clamp((CPlayer->health - oldHealth) >> 2, 1, SBarInfoScript->interpolationSpeed);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
AInventory *armor = CPlayer->mo->FindInventory<ABasicArmor>();
|
|
|
|
if(armor == NULL)
|
|
|
|
{
|
|
|
|
oldArmor = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if(!SBarInfoScript->interpolateArmor)
|
|
|
|
{
|
|
|
|
oldArmor = armor->Amount;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if(oldArmor > armor->Amount)
|
|
|
|
{
|
|
|
|
oldArmor -= clamp((oldArmor - armor->Amount) >> 2, 1, SBarInfoScript->armorInterpolationSpeed);
|
|
|
|
}
|
|
|
|
else if(oldArmor < armor->Amount)
|
|
|
|
{
|
|
|
|
oldArmor += clamp((armor->Amount - oldArmor) >> 2, 1, SBarInfoScript->armorInterpolationSpeed);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(artiflash)
|
|
|
|
{
|
|
|
|
artiflash--;
|
|
|
|
}
|
|
|
|
|
2008-06-01 03:35:47 +00:00
|
|
|
MugShot.Tick(CPlayer);
|
2008-04-09 07:32:33 +00:00
|
|
|
if(currentPopup != POP_None)
|
|
|
|
{
|
2008-06-11 23:12:27 +00:00
|
|
|
SBarInfoScript->popups[currentPopup-1].tick();
|
|
|
|
if(SBarInfoScript->popups[currentPopup-1].opened == false && SBarInfoScript->popups[currentPopup-1].isDoneMoving())
|
2008-04-09 07:32:33 +00:00
|
|
|
{
|
|
|
|
currentPopup = pendingPopup;
|
|
|
|
if(currentPopup != POP_None)
|
2008-06-11 23:12:27 +00:00
|
|
|
SBarInfoScript->popups[currentPopup-1].open();
|
2008-04-09 07:32:33 +00:00
|
|
|
}
|
|
|
|
}
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
|
|
|
|
2008-06-01 03:35:47 +00:00
|
|
|
void DSBarInfo::ReceivedWeapon(AWeapon *weapon)
|
2008-03-19 09:53:23 +00:00
|
|
|
{
|
2008-06-01 03:35:47 +00:00
|
|
|
MugShot.bEvilGrin = true;
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void DSBarInfo::FlashItem(const PClass *itemtype)
|
|
|
|
{
|
|
|
|
artiflash = 4;
|
|
|
|
}
|
|
|
|
|
2008-03-24 17:48:55 +00:00
|
|
|
void DSBarInfo::ShowPop(int popnum)
|
|
|
|
{
|
|
|
|
DBaseStatusBar::ShowPop(popnum);
|
|
|
|
if(popnum != currentPopup)
|
2008-04-09 07:32:33 +00:00
|
|
|
{
|
|
|
|
pendingPopup = popnum;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
pendingPopup = POP_None;
|
|
|
|
if(currentPopup != POP_None)
|
2008-06-11 23:12:27 +00:00
|
|
|
SBarInfoScript->popups[currentPopup-1].close();
|
2008-03-24 17:48:55 +00:00
|
|
|
else
|
2008-04-09 07:32:33 +00:00
|
|
|
{
|
|
|
|
currentPopup = pendingPopup;
|
|
|
|
pendingPopup = POP_None;
|
|
|
|
if(currentPopup != POP_None)
|
2008-06-11 23:12:27 +00:00
|
|
|
SBarInfoScript->popups[currentPopup-1].open();
|
2008-04-09 07:32:33 +00:00
|
|
|
}
|
2008-03-24 17:48:55 +00:00
|
|
|
}
|
|
|
|
|
2008-04-25 09:40:08 +00:00
|
|
|
void DSBarInfo::doCommands(SBarInfoBlock &block, int xOffset, int yOffset, int alpha)
|
2008-03-19 09:53:23 +00:00
|
|
|
{
|
|
|
|
//prepare ammo counts
|
|
|
|
AAmmo *ammo1, *ammo2;
|
|
|
|
int ammocount1, ammocount2;
|
|
|
|
GetCurrentAmmo(ammo1, ammo2, ammocount1, ammocount2);
|
|
|
|
ABasicArmor *armor = CPlayer->mo->FindInventory<ABasicArmor>();
|
|
|
|
int health = CPlayer->mo->health;
|
|
|
|
int armorAmount = armor != NULL ? armor->Amount : 0;
|
|
|
|
if(SBarInfoScript->interpolateHealth)
|
|
|
|
{
|
|
|
|
health = oldHealth;
|
|
|
|
}
|
|
|
|
if(SBarInfoScript->interpolateArmor)
|
|
|
|
{
|
|
|
|
armorAmount = oldArmor;
|
|
|
|
}
|
|
|
|
for(unsigned int i = 0;i < block.commands.Size();i++)
|
|
|
|
{
|
|
|
|
SBarInfoCommand& cmd = block.commands[i];
|
|
|
|
switch(cmd.type) //read and execute all the commands
|
|
|
|
{
|
|
|
|
case SBARINFO_DRAWSWITCHABLEIMAGE: //draw the alt image if we don't have the item else this is like a normal drawimage
|
|
|
|
{
|
2008-08-06 07:38:21 +00:00
|
|
|
// DrawSwitchable image allows 2 or 4 images to be supplied.
|
|
|
|
// drawAlt toggles these:
|
|
|
|
// 1 = first image
|
|
|
|
// 2 = second image
|
|
|
|
// 3 = thrid image
|
|
|
|
// 0 = last image
|
2008-03-19 09:53:23 +00:00
|
|
|
int drawAlt = 0;
|
|
|
|
if((cmd.flags & DRAWIMAGE_WEAPONSLOT)) //weaponslots
|
|
|
|
{
|
|
|
|
drawAlt = 1; //draw off state until we know we have something.
|
|
|
|
for (int i = 0; i < MAX_WEAPONS_PER_SLOT; i++)
|
|
|
|
{
|
|
|
|
const PClass *weap = LocalWeapons.Slots[cmd.value].GetWeapon(i);
|
|
|
|
if(weap == NULL)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
else if(CPlayer->mo->FindInventory(weap) != NULL)
|
|
|
|
{
|
|
|
|
drawAlt = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if((cmd.flags & DRAWIMAGE_INVULNERABILITY))
|
|
|
|
{
|
|
|
|
if(CPlayer->cheats&CF_GODMODE)
|
|
|
|
{
|
|
|
|
drawAlt = 1;
|
|
|
|
}
|
|
|
|
}
|
2008-08-06 07:38:21 +00:00
|
|
|
else if(cmd.flags & DRAWIMAGE_KEYSLOT)
|
|
|
|
{
|
|
|
|
bool found1 = false;
|
|
|
|
bool found2 = false;
|
|
|
|
drawAlt = 1;
|
|
|
|
|
|
|
|
for(AInventory *item = CPlayer->mo->Inventory;item != NULL;item = item->Inventory)
|
|
|
|
{
|
|
|
|
if(item->IsKindOf(RUNTIME_CLASS(AKey)))
|
|
|
|
{
|
|
|
|
int keynum = static_cast<AKey *>(item)->KeyNumber;
|
|
|
|
|
|
|
|
if(keynum == cmd.value)
|
|
|
|
found1 = true;
|
|
|
|
if(cmd.flags & DRAWIMAGE_SWITCHABLE_AND && keynum == cmd.special4) // two keys
|
|
|
|
found2 = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(cmd.flags & DRAWIMAGE_SWITCHABLE_AND)
|
|
|
|
{
|
|
|
|
if(found1 && found2)
|
|
|
|
drawAlt = 0;
|
|
|
|
else if(found1)
|
|
|
|
drawAlt = 2;
|
|
|
|
else if(found2)
|
|
|
|
drawAlt = 3;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if(found1)
|
|
|
|
drawAlt = 0;
|
|
|
|
}
|
|
|
|
}
|
2008-03-19 09:53:23 +00:00
|
|
|
else //check the inventory items and draw selected sprite
|
|
|
|
{
|
|
|
|
AInventory* item = CPlayer->mo->FindInventory(PClass::FindClass(cmd.string[0]));
|
|
|
|
if(item == NULL || item->Amount == 0)
|
|
|
|
drawAlt = 1;
|
|
|
|
if((cmd.flags & DRAWIMAGE_SWITCHABLE_AND))
|
|
|
|
{
|
|
|
|
item = CPlayer->mo->FindInventory(PClass::FindClass(cmd.string[1]));
|
|
|
|
if((item != NULL && item->Amount != 0) && drawAlt == 0) //both
|
|
|
|
{
|
|
|
|
drawAlt = 0;
|
|
|
|
}
|
|
|
|
else if((item != NULL && item->Amount != 0) && drawAlt == 1) //2nd
|
|
|
|
{
|
|
|
|
drawAlt = 3;
|
|
|
|
}
|
|
|
|
else if((item == NULL || item->Amount == 0) && drawAlt == 0) //1st
|
|
|
|
{
|
|
|
|
drawAlt = 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(drawAlt != 0) //draw 'off' image
|
|
|
|
{
|
|
|
|
if(cmd.special != -1 && drawAlt == 1)
|
2008-08-09 03:43:29 +00:00
|
|
|
DrawGraphic(Images[cmd.special], cmd.x, cmd.y, xOffset, yOffset, alpha, block.fullScreenOffsets, !!(cmd.flags & DRAWIMAGE_TRANSLATABLE), false, !!(cmd.flags & (DRAWIMAGE_OFFSET_CENTER|DRAWIMAGE_OFFSET_CENTERBOTTOM)));
|
2008-03-19 09:53:23 +00:00
|
|
|
else if(cmd.special2 != -1 && drawAlt == 2)
|
2008-08-09 03:43:29 +00:00
|
|
|
DrawGraphic(Images[cmd.special2], cmd.x, cmd.y, xOffset, yOffset, alpha, block.fullScreenOffsets, !!(cmd.flags & DRAWIMAGE_TRANSLATABLE), false, !!(cmd.flags & (DRAWIMAGE_OFFSET_CENTER|DRAWIMAGE_OFFSET_CENTERBOTTOM)));
|
2008-03-19 09:53:23 +00:00
|
|
|
else if(cmd.special3 != -1 && drawAlt == 3)
|
2008-08-09 03:43:29 +00:00
|
|
|
DrawGraphic(Images[cmd.special3], cmd.x, cmd.y, xOffset, yOffset, alpha, block.fullScreenOffsets, !!(cmd.flags & DRAWIMAGE_TRANSLATABLE), false,(cmd.flags & (DRAWIMAGE_OFFSET_CENTER|DRAWIMAGE_OFFSET_CENTERBOTTOM)));
|
2008-03-19 09:53:23 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case SBARINFO_DRAWIMAGE:
|
2008-04-25 09:40:08 +00:00
|
|
|
{
|
|
|
|
FTexture *texture = NULL;
|
2008-03-19 09:53:23 +00:00
|
|
|
if((cmd.flags & DRAWIMAGE_PLAYERICON))
|
2008-04-25 09:40:08 +00:00
|
|
|
texture = TexMan[CPlayer->mo->ScoreIcon];
|
2008-03-19 09:53:23 +00:00
|
|
|
else if((cmd.flags & DRAWIMAGE_AMMO1))
|
|
|
|
{
|
|
|
|
if(ammo1 != NULL)
|
2008-04-25 09:40:08 +00:00
|
|
|
texture = TexMan[ammo1->Icon];
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
|
|
|
else if((cmd.flags & DRAWIMAGE_AMMO2))
|
|
|
|
{
|
|
|
|
if(ammo2 != NULL)
|
2008-04-25 09:40:08 +00:00
|
|
|
texture = TexMan[ammo2->Icon];
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
|
|
|
else if((cmd.flags & DRAWIMAGE_ARMOR))
|
|
|
|
{
|
|
|
|
if(armor != NULL && armor->Amount != 0)
|
2008-04-25 09:40:08 +00:00
|
|
|
texture = TexMan(armor->Icon);
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
|
|
|
else if((cmd.flags & DRAWIMAGE_WEAPONICON))
|
|
|
|
{
|
|
|
|
AWeapon *weapon = CPlayer->ReadyWeapon;
|
2008-06-15 18:36:26 +00:00
|
|
|
if(weapon != NULL && weapon->Icon.isValid())
|
2008-03-19 09:53:23 +00:00
|
|
|
{
|
2008-04-25 09:40:08 +00:00
|
|
|
texture = TexMan[weapon->Icon];
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
|
|
|
}
|
2008-05-19 23:07:08 +00:00
|
|
|
else if(cmd.flags & DRAWIMAGE_SIGIL)
|
|
|
|
{
|
|
|
|
AInventory *item = CPlayer->mo->FindInventory<ASigil>();
|
|
|
|
if (item != NULL)
|
|
|
|
texture = TexMan[item->Icon];
|
|
|
|
}
|
2008-08-09 03:43:29 +00:00
|
|
|
else if(cmd.flags & DRAWIMAGE_HEXENARMOR)
|
|
|
|
{
|
|
|
|
AHexenArmor *harmor = CPlayer->mo->FindInventory<AHexenArmor>();
|
|
|
|
if (harmor != NULL)
|
|
|
|
{
|
|
|
|
if (harmor->Slots[cmd.value] > 0 && harmor->SlotsIncrement[cmd.value] > 0)
|
|
|
|
{
|
|
|
|
//combine the alpha values
|
|
|
|
alpha = fixed_t(((double) alpha / (double) FRACUNIT) * ((double) MIN<fixed_t> (OPAQUE, Scale(harmor->Slots[cmd.value], OPAQUE, harmor->SlotsIncrement[cmd.value])) / (double) OPAQUE) * FRACUNIT);
|
|
|
|
texture = Images[cmd.image_index];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2008-03-19 09:53:23 +00:00
|
|
|
else if((cmd.flags & DRAWIMAGE_INVENTORYICON))
|
2008-06-15 18:36:26 +00:00
|
|
|
texture = TexMan[cmd.sprite_index];
|
2008-06-22 09:13:19 +00:00
|
|
|
else if(cmd.image_index >= 0)
|
2008-06-15 18:36:26 +00:00
|
|
|
texture = Images[cmd.image_index];
|
2008-04-25 09:40:08 +00:00
|
|
|
|
2008-08-09 03:43:29 +00:00
|
|
|
// if we reach here with DRAWIMAGE_HEXENARMOR set we know we want it to be dim.
|
|
|
|
DrawGraphic(texture, cmd.x, cmd.y, xOffset, yOffset, alpha, block.fullScreenOffsets, !!(cmd.flags & DRAWIMAGE_TRANSLATABLE), false, (cmd.flags & (DRAWIMAGE_OFFSET_CENTER|DRAWIMAGE_OFFSET_CENTERBOTTOM)));
|
2008-03-19 09:53:23 +00:00
|
|
|
break;
|
2008-04-25 09:40:08 +00:00
|
|
|
}
|
2008-03-19 09:53:23 +00:00
|
|
|
case SBARINFO_DRAWNUMBER:
|
2008-03-24 17:48:55 +00:00
|
|
|
{
|
|
|
|
int value = cmd.value;
|
2008-03-19 09:53:23 +00:00
|
|
|
if(drawingFont != cmd.font)
|
|
|
|
{
|
|
|
|
drawingFont = cmd.font;
|
|
|
|
}
|
2008-04-05 07:06:26 +00:00
|
|
|
if(cmd.flags & DRAWNUMBER_HEALTH)
|
2008-03-19 09:53:23 +00:00
|
|
|
{
|
2008-03-24 17:48:55 +00:00
|
|
|
value = health;
|
2008-08-07 07:17:29 +00:00
|
|
|
if(SBarInfoScript->lowerHealthCap && value < 0) //health shouldn't display negatives
|
2008-03-19 09:53:23 +00:00
|
|
|
{
|
2008-03-24 17:48:55 +00:00
|
|
|
value = 0;
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
|
|
|
}
|
2008-04-05 07:06:26 +00:00
|
|
|
else if(cmd.flags & DRAWNUMBER_ARMOR)
|
2008-03-19 09:53:23 +00:00
|
|
|
{
|
2008-03-24 17:48:55 +00:00
|
|
|
value = armorAmount;
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
2008-04-05 07:06:26 +00:00
|
|
|
else if(cmd.flags & DRAWNUMBER_AMMO1)
|
2008-03-19 09:53:23 +00:00
|
|
|
{
|
2008-03-24 17:48:55 +00:00
|
|
|
value = ammocount1;
|
2008-03-19 09:53:23 +00:00
|
|
|
if(ammo1 == NULL) //no ammo, do not draw
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
2008-04-05 07:06:26 +00:00
|
|
|
else if(cmd.flags & DRAWNUMBER_AMMO2)
|
2008-03-19 09:53:23 +00:00
|
|
|
{
|
2008-03-24 17:48:55 +00:00
|
|
|
value = ammocount2;
|
2008-03-19 09:53:23 +00:00
|
|
|
if(ammo2 == NULL) //no ammo, do not draw
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
2008-04-05 07:06:26 +00:00
|
|
|
else if(cmd.flags & DRAWNUMBER_AMMO)
|
2008-03-19 09:53:23 +00:00
|
|
|
{
|
|
|
|
const PClass* ammo = PClass::FindClass(cmd.string[0]);
|
|
|
|
AInventory* item = CPlayer->mo->FindInventory(ammo);
|
|
|
|
if(item != NULL)
|
|
|
|
{
|
2008-03-24 17:48:55 +00:00
|
|
|
value = item->Amount;
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-03-24 17:48:55 +00:00
|
|
|
value = 0;
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
|
|
|
}
|
2008-04-05 07:06:26 +00:00
|
|
|
else if(cmd.flags & DRAWNUMBER_AMMOCAPACITY)
|
2008-03-19 09:53:23 +00:00
|
|
|
{
|
|
|
|
const PClass* ammo = PClass::FindClass(cmd.string[0]);
|
|
|
|
AInventory* item = CPlayer->mo->FindInventory(ammo);
|
|
|
|
if(item != NULL)
|
|
|
|
{
|
2008-03-24 17:48:55 +00:00
|
|
|
value = item->MaxAmount;
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-03-24 17:48:55 +00:00
|
|
|
value = ((AInventory *)GetDefaultByType(ammo))->MaxAmount;
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
|
|
|
}
|
2008-04-05 07:06:26 +00:00
|
|
|
else if(cmd.flags & DRAWNUMBER_FRAGS)
|
2008-03-24 17:48:55 +00:00
|
|
|
value = CPlayer->fragcount;
|
2008-04-05 07:06:26 +00:00
|
|
|
else if(cmd.flags & DRAWNUMBER_KILLS)
|
2008-03-24 17:48:55 +00:00
|
|
|
value = level.killed_monsters;
|
2008-04-05 07:06:26 +00:00
|
|
|
else if(cmd.flags & DRAWNUMBER_MONSTERS)
|
2008-03-24 17:48:55 +00:00
|
|
|
value = level.total_monsters;
|
2008-04-05 07:06:26 +00:00
|
|
|
else if(cmd.flags & DRAWNUMBER_ITEMS)
|
2008-03-24 17:48:55 +00:00
|
|
|
value = level.found_items;
|
2008-04-05 07:06:26 +00:00
|
|
|
else if(cmd.flags & DRAWNUMBER_TOTALITEMS)
|
2008-03-24 17:48:55 +00:00
|
|
|
value = level.total_items;
|
2008-04-05 07:06:26 +00:00
|
|
|
else if(cmd.flags & DRAWNUMBER_SECRETS)
|
2008-03-24 17:48:55 +00:00
|
|
|
value = level.found_secrets;
|
2008-04-05 07:06:26 +00:00
|
|
|
else if(cmd.flags & DRAWNUMBER_TOTALSECRETS)
|
2008-03-24 17:48:55 +00:00
|
|
|
value = level.total_secrets;
|
2008-04-05 07:06:26 +00:00
|
|
|
else if(cmd.flags & DRAWNUMBER_ARMORCLASS)
|
2008-03-19 09:53:23 +00:00
|
|
|
{
|
|
|
|
AHexenArmor *harmor = CPlayer->mo->FindInventory<AHexenArmor>();
|
|
|
|
if(harmor != NULL)
|
|
|
|
{
|
2008-05-18 15:48:03 +00:00
|
|
|
value = harmor->Slots[0] + harmor->Slots[1] +
|
2008-03-19 09:53:23 +00:00
|
|
|
harmor->Slots[2] + harmor->Slots[3] + harmor->Slots[4];
|
|
|
|
}
|
|
|
|
//Hexen counts basic armor also so we should too.
|
|
|
|
if(armor != NULL)
|
|
|
|
{
|
2008-03-24 17:48:55 +00:00
|
|
|
value += armor->SavePercent;
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
2008-03-24 17:48:55 +00:00
|
|
|
value /= (5*FRACUNIT);
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
2008-04-05 07:06:26 +00:00
|
|
|
else if(cmd.flags & DRAWNUMBER_GLOBALVAR)
|
2008-03-24 17:48:55 +00:00
|
|
|
value = ACS_GlobalVars[cmd.value];
|
2008-04-05 07:06:26 +00:00
|
|
|
else if(cmd.flags & DRAWNUMBER_GLOBALARRAY)
|
|
|
|
value = ACS_GlobalArrays[cmd.value][consoleplayer];
|
2008-06-03 07:21:11 +00:00
|
|
|
else if(cmd.flags & DRAWNUMBER_POWERUPTIME)
|
|
|
|
{
|
|
|
|
//Get the PowerupType and check to see if the player has any in inventory.
|
|
|
|
const PClass* powerupType = ((APowerupGiver*) GetDefaultByType(PClass::FindClass(cmd.string[0])))->PowerupType;
|
|
|
|
APowerup* powerup = (APowerup*) CPlayer->mo->FindInventory(powerupType);
|
|
|
|
if(powerup != NULL)
|
|
|
|
{
|
|
|
|
value = powerup->EffectTics / TICRATE + 1;
|
|
|
|
}
|
|
|
|
}
|
2008-04-05 07:06:26 +00:00
|
|
|
else if(cmd.flags & DRAWNUMBER_INVENTORY)
|
2008-03-19 09:53:23 +00:00
|
|
|
{
|
|
|
|
AInventory* item = CPlayer->mo->FindInventory(PClass::FindClass(cmd.string[0]));
|
|
|
|
if(item != NULL)
|
|
|
|
{
|
2008-03-24 17:48:55 +00:00
|
|
|
value = item->Amount;
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-03-24 17:48:55 +00:00
|
|
|
value = 0;
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
|
|
|
}
|
2008-04-05 07:06:26 +00:00
|
|
|
bool fillzeros = !!(cmd.flags & DRAWNUMBER_FILLZEROS);
|
2008-08-09 03:43:29 +00:00
|
|
|
bool drawshadow = !!(cmd.flags & DRAWNUMBER_DRAWSHADOW);
|
2008-04-25 09:40:08 +00:00
|
|
|
EColorRange translation = cmd.translation;
|
2008-04-05 07:06:26 +00:00
|
|
|
if(cmd.special3 != -1 && value <= cmd.special3) //low
|
2008-04-25 09:40:08 +00:00
|
|
|
translation = cmd.translation2;
|
2008-04-05 07:06:26 +00:00
|
|
|
else if(cmd.special4 != -1 && value >= cmd.special4) //high
|
2008-04-25 09:40:08 +00:00
|
|
|
translation = cmd.translation3;
|
2008-05-19 23:07:08 +00:00
|
|
|
if((cmd.flags & DRAWNUMBER_WHENNOTZERO) && value == 0)
|
|
|
|
break;
|
2008-08-09 03:43:29 +00:00
|
|
|
DrawNumber(value, cmd.special, cmd.x, cmd.y, xOffset, yOffset, alpha, block.fullScreenOffsets, translation, cmd.special2, fillzeros, drawshadow);
|
2008-03-19 09:53:23 +00:00
|
|
|
break;
|
2008-03-24 17:48:55 +00:00
|
|
|
}
|
2008-03-19 09:53:23 +00:00
|
|
|
case SBARINFO_DRAWMUGSHOT:
|
|
|
|
{
|
|
|
|
bool xdth = false;
|
|
|
|
bool animatedgodmode = false;
|
|
|
|
if(cmd.flags & DRAWMUGSHOT_XDEATHFACE)
|
|
|
|
xdth = true;
|
|
|
|
if(cmd.flags & DRAWMUGSHOT_ANIMATEDGODMODE)
|
|
|
|
animatedgodmode = true;
|
2008-08-07 07:17:29 +00:00
|
|
|
int stateflags = cmd.flags & (DRAWMUGSHOT_XDEATHFACE | DRAWMUGSHOT_ANIMATEDGODMODE | DRAWMUGSHOT_DISABLEGRIN | DRAWMUGSHOT_DISABLEOUCH | DRAWMUGSHOT_DISABLEPAIN | DRAWMUGSHOT_DISABLERAMPAGE);
|
|
|
|
DrawFace(cmd.string[0], cmd.special, stateflags, cmd.x, cmd.y, xOffset, yOffset, alpha, block.fullScreenOffsets);
|
2008-03-19 09:53:23 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case SBARINFO_DRAWSELECTEDINVENTORY:
|
|
|
|
if(CPlayer->mo->InvSel != NULL && !(level.flags & LEVEL_NOINVENTORYBAR))
|
|
|
|
{
|
|
|
|
if((cmd.flags & DRAWSELECTEDINVENTORY_ARTIFLASH) && artiflash)
|
|
|
|
{
|
2008-08-06 07:38:21 +00:00
|
|
|
DrawGraphic(Images[ARTIFLASH_OFFSET+(4-artiflash)], cmd.x, cmd.y, xOffset, yOffset, alpha, block.fullScreenOffsets, false, CPlayer->mo->InvSel->Amount <= 0);
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-08-06 07:38:21 +00:00
|
|
|
DrawGraphic(TexMan(CPlayer->mo->InvSel->Icon), cmd.x, cmd.y, xOffset, yOffset, alpha, block.fullScreenOffsets, false, CPlayer->mo->InvSel->Amount <= 0);
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
|
|
|
if((cmd.flags & DRAWSELECTEDINVENTORY_ALWAYSSHOWCOUNTER) || CPlayer->mo->InvSel->Amount != 1)
|
|
|
|
{
|
|
|
|
if(drawingFont != cmd.font)
|
|
|
|
{
|
|
|
|
drawingFont = cmd.font;
|
|
|
|
}
|
2008-08-06 07:38:21 +00:00
|
|
|
DrawNumber(CPlayer->mo->InvSel->Amount, 3, cmd.special2, cmd.special3, xOffset, yOffset, alpha, block.fullScreenOffsets, cmd.translation, cmd.special4);
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if((cmd.flags & DRAWSELECTEDINVENTORY_ALTERNATEONEMPTY))
|
|
|
|
{
|
2008-04-25 09:40:08 +00:00
|
|
|
doCommands(cmd.subBlock, xOffset, yOffset, alpha);
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SBARINFO_DRAWINVENTORYBAR:
|
|
|
|
{
|
|
|
|
bool alwaysshow = false;
|
|
|
|
bool artibox = true;
|
|
|
|
bool noarrows = false;
|
|
|
|
bool alwaysshowcounter = false;
|
|
|
|
if((cmd.flags & DRAWINVENTORYBAR_ALWAYSSHOW))
|
|
|
|
alwaysshow = true;
|
|
|
|
if((cmd.flags & DRAWINVENTORYBAR_NOARTIBOX))
|
|
|
|
artibox = false;
|
|
|
|
if((cmd.flags & DRAWINVENTORYBAR_NOARROWS))
|
|
|
|
noarrows = true;
|
|
|
|
if((cmd.flags & DRAWINVENTORYBAR_ALWAYSSHOWCOUNTER))
|
|
|
|
alwaysshowcounter = true;
|
2008-08-09 03:43:29 +00:00
|
|
|
if(cmd.flags & DRAWINVENTORYBAR_TRANSLUCENT)
|
|
|
|
alpha = fixed_t((((double) alpha / (double) FRACUNIT) * ((double) HX_SHADOW / (double) FRACUNIT)) * FRACUNIT);
|
2008-03-19 09:53:23 +00:00
|
|
|
if(drawingFont != cmd.font)
|
|
|
|
{
|
|
|
|
drawingFont = cmd.font;
|
|
|
|
}
|
2008-08-06 07:38:21 +00:00
|
|
|
DrawInventoryBar(cmd.special, cmd.value, cmd.x, cmd.y, xOffset, yOffset, alpha, block.fullScreenOffsets, alwaysshow, cmd.special2, cmd.special3, cmd.translation, artibox, noarrows, alwaysshowcounter);
|
2008-03-19 09:53:23 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case SBARINFO_DRAWBAR:
|
|
|
|
{
|
2008-06-15 18:36:26 +00:00
|
|
|
if(cmd.image_index == -1 || Images[cmd.image_index] == NULL)
|
2008-03-19 09:53:23 +00:00
|
|
|
break; //don't draw anything.
|
|
|
|
bool horizontal = !!((cmd.special2 & DRAWBAR_HORIZONTAL));
|
|
|
|
bool reverse = !!((cmd.special2 & DRAWBAR_REVERSE));
|
|
|
|
fixed_t value = 0;
|
|
|
|
int max = 0;
|
|
|
|
if(cmd.flags == DRAWNUMBER_HEALTH)
|
|
|
|
{
|
|
|
|
value = health;
|
|
|
|
if(value < 0) //health shouldn't display negatives
|
|
|
|
{
|
|
|
|
value = 0;
|
|
|
|
}
|
|
|
|
if(!(cmd.special2 & DRAWBAR_COMPAREDEFAULTS))
|
|
|
|
{
|
|
|
|
AInventory* item = CPlayer->mo->FindInventory(PClass::FindClass(cmd.string[0])); //max comparer
|
|
|
|
if(item != NULL)
|
|
|
|
{
|
|
|
|
max = item->Amount;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
max = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else //default to the class's health
|
|
|
|
{
|
2008-07-19 12:40:10 +00:00
|
|
|
max = CPlayer->mo->GetMaxHealth() + CPlayer->stamina;
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(cmd.flags == DRAWNUMBER_ARMOR)
|
|
|
|
{
|
|
|
|
value = armorAmount;
|
|
|
|
if(!((cmd.special2 & DRAWBAR_COMPAREDEFAULTS) == DRAWBAR_COMPAREDEFAULTS))
|
|
|
|
{
|
|
|
|
AInventory* item = CPlayer->mo->FindInventory(PClass::FindClass(cmd.string[0])); //max comparer
|
|
|
|
if(item != NULL)
|
|
|
|
{
|
|
|
|
max = item->Amount;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
max = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else //default to 100
|
|
|
|
{
|
|
|
|
max = 100;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(cmd.flags == DRAWNUMBER_AMMO1)
|
|
|
|
{
|
|
|
|
value = ammocount1;
|
|
|
|
if(ammo1 == NULL) //no ammo, draw as empty
|
|
|
|
{
|
|
|
|
value = 0;
|
|
|
|
max = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
max = ammo1->MaxAmount;
|
|
|
|
}
|
|
|
|
else if(cmd.flags == DRAWNUMBER_AMMO2)
|
|
|
|
{
|
|
|
|
value = ammocount2;
|
|
|
|
if(ammo2 == NULL) //no ammo, draw as empty
|
|
|
|
{
|
|
|
|
value = 0;
|
|
|
|
max = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
max = ammo2->MaxAmount;
|
|
|
|
}
|
|
|
|
else if(cmd.flags == DRAWNUMBER_AMMO)
|
|
|
|
{
|
|
|
|
const PClass* ammo = PClass::FindClass(cmd.string[0]);
|
|
|
|
AInventory* item = CPlayer->mo->FindInventory(ammo);
|
|
|
|
if(item != NULL)
|
|
|
|
{
|
|
|
|
value = item->Amount;
|
|
|
|
max = item->MaxAmount;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
value = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(cmd.flags == DRAWNUMBER_FRAGS)
|
|
|
|
{
|
|
|
|
value = CPlayer->fragcount;
|
|
|
|
max = fraglimit;
|
|
|
|
}
|
|
|
|
else if(cmd.flags == DRAWNUMBER_KILLS)
|
|
|
|
{
|
|
|
|
value = level.killed_monsters;
|
|
|
|
max = level.total_monsters;
|
|
|
|
}
|
|
|
|
else if(cmd.flags == DRAWNUMBER_ITEMS)
|
|
|
|
{
|
|
|
|
value = level.found_items;
|
|
|
|
max = level.total_items;
|
|
|
|
}
|
|
|
|
else if(cmd.flags == DRAWNUMBER_SECRETS)
|
|
|
|
{
|
|
|
|
value = level.found_secrets;
|
|
|
|
max = level.total_secrets;
|
|
|
|
}
|
|
|
|
else if(cmd.flags == DRAWNUMBER_INVENTORY)
|
|
|
|
{
|
|
|
|
AInventory* item = CPlayer->mo->FindInventory(PClass::FindClass(cmd.string[0]));
|
|
|
|
if(item != NULL)
|
|
|
|
{
|
|
|
|
value = item->Amount;
|
|
|
|
max = item->MaxAmount;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
value = 0;
|
|
|
|
}
|
|
|
|
}
|
2008-06-03 07:21:11 +00:00
|
|
|
else if(cmd.flags & DRAWNUMBER_POWERUPTIME)
|
|
|
|
{
|
|
|
|
//Get the PowerupType and check to see if the player has any in inventory.
|
|
|
|
APowerupGiver* powerupGiver = (APowerupGiver*) GetDefaultByType(PClass::FindClass(cmd.string[0]));
|
|
|
|
const PClass* powerupType = powerupGiver->PowerupType;
|
|
|
|
APowerup* powerup = (APowerup*) CPlayer->mo->FindInventory(powerupType);
|
|
|
|
if(powerup != NULL && powerupType != NULL && powerupGiver != NULL)
|
|
|
|
{
|
|
|
|
value = powerup->EffectTics + 1;
|
|
|
|
if(powerupGiver->EffectTics == 0) //if 0 we need to get the default from the powerup
|
|
|
|
max = ((APowerup*) GetDefaultByType(powerupType))->EffectTics + 1;
|
|
|
|
else
|
|
|
|
max = powerupGiver->EffectTics + 1;
|
|
|
|
}
|
|
|
|
}
|
2008-03-19 09:53:23 +00:00
|
|
|
if(cmd.special3 != 0)
|
|
|
|
value = max - value; //invert since the new drawing method requires drawing the bg on the fg.
|
|
|
|
if(max != 0 && value > 0)
|
|
|
|
{
|
|
|
|
value = (value << FRACBITS) / max;
|
|
|
|
if(value > FRACUNIT)
|
|
|
|
value = FRACUNIT;
|
|
|
|
}
|
|
|
|
else if(cmd.special3 != 0 && max == 0 && value <= 0)
|
|
|
|
{
|
|
|
|
value = FRACUNIT;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
value = 0;
|
|
|
|
}
|
2008-06-15 18:36:26 +00:00
|
|
|
assert(Images[cmd.image_index] != NULL);
|
2008-03-19 09:53:23 +00:00
|
|
|
|
2008-06-15 18:36:26 +00:00
|
|
|
FTexture *fg = Images[cmd.image_index];
|
2008-03-19 09:53:23 +00:00
|
|
|
FTexture *bg = (cmd.special != -1) ? Images[cmd.special] : NULL;
|
|
|
|
int x, y, w, h;
|
|
|
|
int cx, cy, cw, ch, cr, cb;
|
|
|
|
|
2008-08-12 03:19:35 +00:00
|
|
|
// These still need to be caclulated for the clear call.
|
|
|
|
if(bg == NULL)
|
2008-03-19 09:53:23 +00:00
|
|
|
{
|
2008-08-12 03:19:35 +00:00
|
|
|
if(!block.fullScreenOffsets)
|
2008-08-07 07:17:29 +00:00
|
|
|
{
|
2008-08-12 03:19:35 +00:00
|
|
|
// Calc real screen coordinates for bar
|
|
|
|
x = cmd.x + ST_X + xOffset;
|
|
|
|
y = cmd.y + ST_Y + yOffset;
|
|
|
|
w = fg->GetScaledWidth();
|
|
|
|
h = fg->GetScaledHeight();
|
|
|
|
if (Scaled)
|
|
|
|
{
|
|
|
|
screen->VirtualToRealCoordsInt(x, y, w, h, 320, 200, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
x = cmd.x + xOffset;
|
|
|
|
y = cmd.y + yOffset;
|
|
|
|
w = fg->GetScaledWidth();
|
|
|
|
h = fg->GetScaledHeight();
|
|
|
|
if(vid_fps && x < 0 && y >= 0)
|
|
|
|
y += 10;
|
2008-08-07 07:17:29 +00:00
|
|
|
}
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if(cmd.special3 != 0)
|
|
|
|
{
|
|
|
|
//Draw the whole foreground
|
2008-08-12 03:19:35 +00:00
|
|
|
DrawGraphic(fg, cmd.x, cmd.y, xOffset, yOffset, alpha, block.fullScreenOffsets);
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Draw background
|
|
|
|
if (bg != NULL && bg->GetScaledWidth() == fg->GetScaledWidth() && bg->GetScaledHeight() == fg->GetScaledHeight())
|
|
|
|
{
|
2008-08-12 03:19:35 +00:00
|
|
|
DrawGraphic(bg, cmd.x, cmd.y, xOffset, yOffset, alpha, block.fullScreenOffsets);
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
screen->Clear(x, y, x + w, y + h, GPalette.BlackIndex, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-08-07 07:17:29 +00:00
|
|
|
if(!block.fullScreenOffsets)
|
2008-03-19 09:53:23 +00:00
|
|
|
{
|
2008-08-07 07:17:29 +00:00
|
|
|
// Calc clipping rect for background
|
|
|
|
cx = cmd.x + ST_X + cmd.special3 + xOffset;
|
|
|
|
cy = cmd.y + ST_Y + cmd.special3 + yOffset;
|
|
|
|
cw = fg->GetScaledWidth() - fg->GetScaledLeftOffset() - cmd.special3 * 2;
|
|
|
|
ch = fg->GetScaledHeight() - fg->GetScaledTopOffset() - cmd.special3 * 2;
|
|
|
|
if (Scaled)
|
|
|
|
{
|
|
|
|
screen->VirtualToRealCoordsInt(cx, cy, cw, ch, 320, 200, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
cx = cmd.x + cmd.special3 + xOffset;
|
|
|
|
cy = cmd.y + cmd.special3 + yOffset;
|
|
|
|
cw = fg->GetScaledWidth() - fg->GetScaledLeftOffset() - cmd.special3 * 2;
|
|
|
|
ch = fg->GetScaledHeight() - fg->GetScaledTopOffset() - cmd.special3 * 2;
|
2008-08-09 03:43:29 +00:00
|
|
|
if(vid_fps && x < 0 && y >= 0)
|
|
|
|
y += 10;
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
2008-03-22 09:26:59 +00:00
|
|
|
|
2008-03-19 09:53:23 +00:00
|
|
|
if (horizontal)
|
|
|
|
{
|
|
|
|
if ((cmd.special3 != 0 && reverse) || (cmd.special3 == 0 && !reverse))
|
|
|
|
{ // left to right
|
|
|
|
cr = cx + FixedMul(cw, value);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // right to left
|
|
|
|
cr = cx + cw;
|
|
|
|
cx += FixedMul(cw, FRACUNIT - value);
|
|
|
|
}
|
|
|
|
cb = cy + ch;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ((cmd.special3 != 0 && reverse) || (cmd.special3 == 0 && !reverse))
|
|
|
|
{ // bottom to top
|
|
|
|
cb = cy + ch;
|
|
|
|
cy += FixedMul(ch, FRACUNIT - value);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // top to bottom
|
|
|
|
cb = cy + FixedMul(ch, value);
|
|
|
|
}
|
|
|
|
cr = cx + cw;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Draw background
|
|
|
|
if(cmd.special3 != 0)
|
|
|
|
{
|
|
|
|
if (bg != NULL && bg->GetScaledWidth() == fg->GetScaledWidth() && bg->GetScaledHeight() == fg->GetScaledHeight())
|
|
|
|
{
|
2008-08-12 03:19:35 +00:00
|
|
|
if(!block.fullScreenOffsets)
|
|
|
|
{
|
|
|
|
screen->DrawTexture(bg, x, y,
|
|
|
|
DTA_DestWidth, w,
|
|
|
|
DTA_DestHeight, h,
|
|
|
|
DTA_ClipLeft, cx,
|
|
|
|
DTA_ClipTop, cy,
|
|
|
|
DTA_ClipRight, cr,
|
|
|
|
DTA_ClipBottom, cb,
|
|
|
|
DTA_Alpha, alpha,
|
|
|
|
TAG_DONE);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
screen->DrawTexture(bg, x, y,
|
|
|
|
DTA_DestWidth, w,
|
|
|
|
DTA_DestHeight, h,
|
|
|
|
DTA_ClipLeft, cx,
|
|
|
|
DTA_ClipTop, cy,
|
|
|
|
DTA_ClipRight, cr,
|
|
|
|
DTA_ClipBottom, cb,
|
|
|
|
DTA_Alpha, alpha,
|
|
|
|
DTA_HUDRules, HUD_Normal,
|
|
|
|
TAG_DONE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
screen->Clear(cx, cy, cr, cb, GPalette.BlackIndex, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if(!block.fullScreenOffsets)
|
|
|
|
{
|
|
|
|
screen->DrawTexture(fg, x, y,
|
2008-03-19 09:53:23 +00:00
|
|
|
DTA_DestWidth, w,
|
|
|
|
DTA_DestHeight, h,
|
|
|
|
DTA_ClipLeft, cx,
|
|
|
|
DTA_ClipTop, cy,
|
|
|
|
DTA_ClipRight, cr,
|
|
|
|
DTA_ClipBottom, cb,
|
2008-04-25 09:40:08 +00:00
|
|
|
DTA_Alpha, alpha,
|
2008-03-19 09:53:23 +00:00
|
|
|
TAG_DONE);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-08-12 03:19:35 +00:00
|
|
|
screen->DrawTexture(fg, x, y,
|
|
|
|
DTA_DestWidth, w,
|
|
|
|
DTA_DestHeight, h,
|
|
|
|
DTA_ClipLeft, cx,
|
|
|
|
DTA_ClipTop, cy,
|
|
|
|
DTA_ClipRight, cr,
|
|
|
|
DTA_ClipBottom, cb,
|
|
|
|
DTA_Alpha, alpha,
|
|
|
|
DTA_HUDRules, HUD_Normal,
|
|
|
|
TAG_DONE);
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case SBARINFO_DRAWGEM:
|
|
|
|
{
|
|
|
|
int value = (cmd.flags & DRAWGEM_ARMOR) ? armorAmount : health;
|
2008-07-19 12:40:10 +00:00
|
|
|
int max = (cmd.flags & DRAWGEM_ARMOR) ? 100 : CPlayer->mo->GetMaxHealth() + CPlayer->stamina;
|
2008-03-19 09:53:23 +00:00
|
|
|
bool wiggle = false;
|
|
|
|
bool translate = !!(cmd.flags & DRAWGEM_TRANSLATABLE);
|
|
|
|
if(max != 0 || value < 0)
|
|
|
|
{
|
|
|
|
value = (value*100)/max;
|
|
|
|
if(value > 100)
|
|
|
|
value = 100;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
value = 0;
|
|
|
|
}
|
|
|
|
value = (cmd.flags & DRAWGEM_REVERSE) ? 100 - value : value;
|
|
|
|
if(health != CPlayer->health)
|
|
|
|
{
|
|
|
|
wiggle = !!(cmd.flags & DRAWGEM_WIGGLE);
|
|
|
|
}
|
2008-08-06 07:38:21 +00:00
|
|
|
DrawGem(Images[cmd.special], Images[cmd.image_index], value, cmd.x, cmd.y, xOffset, yOffset, alpha, block.fullScreenOffsets, cmd.special2, cmd.special3, cmd.special4+1, wiggle, translate);
|
2008-03-19 09:53:23 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case SBARINFO_DRAWSHADER:
|
|
|
|
{
|
|
|
|
FBarShader *const shaders[4] =
|
|
|
|
{
|
|
|
|
&shader_horz_normal, &shader_horz_reverse,
|
|
|
|
&shader_vert_normal, &shader_vert_reverse
|
|
|
|
};
|
|
|
|
bool vertical = !!(cmd.flags & DRAWSHADER_VERTICAL);
|
|
|
|
bool reverse = !!(cmd.flags & DRAWSHADER_REVERSE);
|
2008-08-07 07:17:29 +00:00
|
|
|
int x = cmd.x + xOffset;
|
|
|
|
int y = cmd.y + yOffset;
|
|
|
|
int w = cmd.special;
|
|
|
|
int h = cmd.special2;
|
|
|
|
if(!block.fullScreenOffsets)
|
|
|
|
{
|
|
|
|
x += ST_X;
|
|
|
|
y += ST_Y;
|
|
|
|
if(Scaled)
|
|
|
|
screen->VirtualToRealCoordsInt(x, y, w, h, 320, 200, true);
|
|
|
|
}
|
2008-08-09 03:43:29 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
if(vid_fps && x < 0 && y >= 0)
|
|
|
|
y += 10;
|
|
|
|
}
|
2008-08-12 03:19:35 +00:00
|
|
|
if(!block.fullScreenOffsets)
|
|
|
|
{
|
|
|
|
screen->DrawTexture (shaders[(vertical << 1) + reverse], x, y,
|
|
|
|
DTA_DestWidth, w,
|
|
|
|
DTA_DestHeight, h,
|
|
|
|
DTA_Alpha, alpha,
|
|
|
|
DTA_AlphaChannel, true,
|
|
|
|
DTA_FillColor, 0,
|
|
|
|
TAG_DONE);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
screen->DrawTexture (shaders[(vertical << 1) + reverse], x, y,
|
|
|
|
DTA_DestWidth, w,
|
|
|
|
DTA_DestHeight, h,
|
|
|
|
DTA_Alpha, alpha,
|
|
|
|
DTA_AlphaChannel, true,
|
|
|
|
DTA_FillColor, 0,
|
|
|
|
DTA_HUDRules, HUD_Normal,
|
|
|
|
TAG_DONE);
|
|
|
|
}
|
2008-03-19 09:53:23 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case SBARINFO_DRAWSTRING:
|
|
|
|
if(drawingFont != cmd.font)
|
|
|
|
{
|
|
|
|
drawingFont = cmd.font;
|
|
|
|
}
|
2008-08-06 07:38:21 +00:00
|
|
|
DrawString(cmd.string[0], cmd.x - drawingFont->StringWidth(cmd.string[0]), cmd.y, xOffset, yOffset, alpha, block.fullScreenOffsets, cmd.translation, cmd.special);
|
2008-03-19 09:53:23 +00:00
|
|
|
break;
|
|
|
|
case SBARINFO_DRAWKEYBAR:
|
|
|
|
{
|
|
|
|
bool vertical = !!(cmd.flags & DRAWKEYBAR_VERTICAL);
|
|
|
|
AInventory *item = CPlayer->mo->Inventory;
|
|
|
|
if(item == NULL)
|
|
|
|
break;
|
2008-08-09 03:43:29 +00:00
|
|
|
int slotOffset = 0;
|
|
|
|
int rowOffset = 0;
|
|
|
|
int rowWidth = 0;
|
|
|
|
for(int i = 0;i < cmd.value+cmd.special2;i++)
|
2008-03-19 09:53:23 +00:00
|
|
|
{
|
2008-06-15 18:36:26 +00:00
|
|
|
while(!item->Icon.isValid() || !item->IsKindOf(RUNTIME_CLASS(AKey)))
|
2008-03-19 09:53:23 +00:00
|
|
|
{
|
|
|
|
item = item->Inventory;
|
|
|
|
if(item == NULL)
|
|
|
|
goto FinishDrawKeyBar;
|
|
|
|
}
|
2008-08-09 03:43:29 +00:00
|
|
|
if(i >= cmd.special2) //Should we start drawing?
|
|
|
|
{
|
|
|
|
if(!vertical)
|
|
|
|
{
|
|
|
|
DrawGraphic(TexMan[item->Icon], cmd.x+slotOffset, cmd.y+rowOffset, xOffset, yOffset, alpha, block.fullScreenOffsets);
|
|
|
|
rowWidth = cmd.special4 == -1 ? TexMan[item->Icon]->GetScaledHeight()+2 : cmd.special4;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DrawGraphic(TexMan[item->Icon], cmd.x+rowOffset, cmd.y+slotOffset, xOffset, yOffset, alpha, block.fullScreenOffsets);
|
|
|
|
rowWidth = cmd.special4 == -1 ? TexMan[item->Icon]->GetScaledWidth()+2 : cmd.special4;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If cmd.special is -1 then the slot size is auto detected
|
|
|
|
if(cmd.special == -1)
|
|
|
|
{
|
|
|
|
if(!vertical)
|
|
|
|
slotOffset += TexMan[item->Icon]->GetScaledWidth() + 2;
|
|
|
|
else
|
|
|
|
slotOffset += TexMan[item->Icon]->GetScaledHeight() + 2;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
slotOffset += cmd.special;
|
|
|
|
|
|
|
|
if(cmd.special3 > 0 && (i % cmd.special3 == cmd.special3-1))
|
|
|
|
{
|
|
|
|
if(cmd.flags & DRAWKEYBAR_REVERSEROWS)
|
|
|
|
rowOffset -= rowWidth;
|
|
|
|
else
|
|
|
|
rowOffset += rowWidth;
|
|
|
|
rowWidth = 0;
|
|
|
|
slotOffset = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-03-19 09:53:23 +00:00
|
|
|
item = item->Inventory;
|
|
|
|
if(item == NULL)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
FinishDrawKeyBar:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case SBARINFO_GAMEMODE:
|
|
|
|
if(((cmd.flags & GAMETYPE_SINGLEPLAYER) && !multiplayer) ||
|
|
|
|
((cmd.flags & GAMETYPE_DEATHMATCH) && deathmatch) ||
|
|
|
|
((cmd.flags & GAMETYPE_COOPERATIVE) && multiplayer && !deathmatch) ||
|
|
|
|
((cmd.flags & GAMETYPE_TEAMGAME) && teamplay))
|
|
|
|
{
|
2008-04-25 09:40:08 +00:00
|
|
|
doCommands(cmd.subBlock, xOffset, yOffset, alpha);
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SBARINFO_PLAYERCLASS:
|
|
|
|
{
|
2008-03-22 09:26:59 +00:00
|
|
|
if(CPlayer->cls == NULL) break; //No class so we can not continue
|
2008-03-19 09:53:23 +00:00
|
|
|
int spawnClass = CPlayer->cls->ClassIndex;
|
|
|
|
if(cmd.special == spawnClass || cmd.special2 == spawnClass || cmd.special3 == spawnClass)
|
|
|
|
{
|
2008-04-25 09:40:08 +00:00
|
|
|
doCommands(cmd.subBlock, xOffset, yOffset, alpha);
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2008-03-24 17:48:55 +00:00
|
|
|
case SBARINFO_ASPECTRATIO:
|
|
|
|
if(CheckRatio(screen->GetWidth(), screen->GetHeight()) == cmd.value)
|
|
|
|
{
|
2008-04-25 09:40:08 +00:00
|
|
|
doCommands(cmd.subBlock, xOffset, yOffset, alpha);
|
2008-03-24 17:48:55 +00:00
|
|
|
}
|
|
|
|
break;
|
2008-04-05 07:06:26 +00:00
|
|
|
case SBARINFO_ISSELECTED:
|
|
|
|
if(CPlayer->ReadyWeapon != NULL)
|
|
|
|
{
|
|
|
|
const PClass *weapon1 = PClass::FindClass(cmd.string[0]);
|
|
|
|
const PClass *weapon2 = PClass::FindClass(cmd.string[1]);
|
|
|
|
if(weapon2 != NULL)
|
|
|
|
{
|
|
|
|
if((cmd.flags & SBARINFOEVENT_NOT) && (weapon1 != CPlayer->ReadyWeapon->GetSpecies() && weapon2 != CPlayer->ReadyWeapon->GetSpecies()))
|
2008-04-25 09:40:08 +00:00
|
|
|
doCommands(cmd.subBlock, xOffset, yOffset, alpha);
|
2008-04-05 07:06:26 +00:00
|
|
|
else if(!(cmd.flags & SBARINFOEVENT_NOT) && (weapon1 == CPlayer->ReadyWeapon->GetSpecies() || weapon2 == CPlayer->ReadyWeapon->GetSpecies()))
|
2008-04-25 09:40:08 +00:00
|
|
|
doCommands(cmd.subBlock, xOffset, yOffset, alpha);
|
2008-04-05 07:06:26 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if(!(cmd.flags & SBARINFOEVENT_NOT) && weapon1 == CPlayer->ReadyWeapon->GetSpecies())
|
2008-04-25 09:40:08 +00:00
|
|
|
doCommands(cmd.subBlock, xOffset, yOffset, alpha);
|
2008-04-05 07:06:26 +00:00
|
|
|
else if((cmd.flags & SBARINFOEVENT_NOT) && weapon1 != CPlayer->ReadyWeapon->GetSpecies())
|
2008-04-25 09:40:08 +00:00
|
|
|
doCommands(cmd.subBlock, xOffset, yOffset, alpha);
|
2008-04-05 07:06:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2008-05-18 15:48:03 +00:00
|
|
|
case SBARINFO_USESSECONDARYAMMO:
|
|
|
|
if((CPlayer->ReadyWeapon->AmmoType2 != NULL && !(cmd.flags & SBARINFOEVENT_NOT)) ||
|
|
|
|
(CPlayer->ReadyWeapon->AmmoType2 == NULL && cmd.flags & SBARINFOEVENT_NOT))
|
|
|
|
{
|
|
|
|
doCommands(cmd.subBlock, xOffset, yOffset, alpha);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SBARINFO_HASWEAPONPIECE:
|
|
|
|
{
|
|
|
|
AInventory *inv;
|
|
|
|
AWeaponHolder *hold;
|
|
|
|
const PClass *weapon = PClass::FindClass(cmd.string[0]);
|
|
|
|
for(inv = CPlayer->mo->Inventory;inv != NULL;inv=inv->Inventory)
|
|
|
|
{
|
|
|
|
if(inv->IsKindOf(RUNTIME_CLASS(AWeaponHolder)))
|
|
|
|
{
|
|
|
|
hold = static_cast<AWeaponHolder*>(inv);
|
|
|
|
if(hold->PieceWeapon == weapon)
|
|
|
|
{
|
|
|
|
if(hold->PieceMask & (1 << (cmd.value-1)))
|
|
|
|
doCommands(cmd.subBlock, xOffset, yOffset, alpha);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2008-03-19 09:53:23 +00:00
|
|
|
case SBARINFO_WEAPONAMMO:
|
|
|
|
if(CPlayer->ReadyWeapon != NULL)
|
|
|
|
{
|
|
|
|
const PClass *AmmoType1 = CPlayer->ReadyWeapon->AmmoType1;
|
|
|
|
const PClass *AmmoType2 = CPlayer->ReadyWeapon->AmmoType2;
|
|
|
|
const PClass *IfAmmo1 = PClass::FindClass(cmd.string[0]);
|
|
|
|
const PClass *IfAmmo2 = (cmd.flags & SBARINFOEVENT_OR) || (cmd.flags & SBARINFOEVENT_AND) ?
|
|
|
|
PClass::FindClass(cmd.string[1]) : NULL;
|
|
|
|
bool usesammo1 = (AmmoType1 != NULL);
|
|
|
|
bool usesammo2 = (AmmoType2 != NULL);
|
|
|
|
if(!(cmd.flags & SBARINFOEVENT_NOT) && !usesammo1 && !usesammo2) //if the weapon doesn't use ammo don't go though the trouble.
|
|
|
|
{
|
2008-05-18 15:48:03 +00:00
|
|
|
doCommands(cmd.subBlock, xOffset, yOffset, alpha);
|
2008-03-19 09:53:23 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
//Or means only 1 ammo type needs to match and means both need to match.
|
|
|
|
if((cmd.flags & SBARINFOEVENT_OR) || (cmd.flags & SBARINFOEVENT_AND))
|
|
|
|
{
|
|
|
|
bool match1 = ((usesammo1 && (AmmoType1 == IfAmmo1 || AmmoType1 == IfAmmo2)) || !usesammo1);
|
|
|
|
bool match2 = ((usesammo2 && (AmmoType2 == IfAmmo1 || AmmoType2 == IfAmmo2)) || !usesammo2);
|
|
|
|
if(((cmd.flags & SBARINFOEVENT_OR) && (match1 || match2)) || ((cmd.flags & SBARINFOEVENT_AND) && (match1 && match2)))
|
|
|
|
{
|
|
|
|
if(!(cmd.flags & SBARINFOEVENT_NOT))
|
2008-04-25 09:40:08 +00:00
|
|
|
doCommands(cmd.subBlock, xOffset, yOffset, alpha);
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
|
|
|
else if(cmd.flags & SBARINFOEVENT_NOT)
|
|
|
|
{
|
2008-04-25 09:40:08 +00:00
|
|
|
doCommands(cmd.subBlock, xOffset, yOffset, alpha);
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else //Every thing here could probably be one long if statement but then it would be more confusing.
|
|
|
|
{
|
|
|
|
if((usesammo1 && (AmmoType1 == IfAmmo1)) || (usesammo2 && (AmmoType2 == IfAmmo1)))
|
|
|
|
{
|
|
|
|
if(!(cmd.flags & SBARINFOEVENT_NOT))
|
2008-04-25 09:40:08 +00:00
|
|
|
doCommands(cmd.subBlock, xOffset, yOffset, alpha);
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
|
|
|
else if(cmd.flags & SBARINFOEVENT_NOT)
|
|
|
|
{
|
2008-04-25 09:40:08 +00:00
|
|
|
doCommands(cmd.subBlock, xOffset, yOffset, alpha);
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2008-03-24 17:48:55 +00:00
|
|
|
case SBARINFO_ININVENTORY:
|
|
|
|
{
|
|
|
|
AInventory *item1 = CPlayer->mo->FindInventory(PClass::FindClass(cmd.string[0]));
|
|
|
|
AInventory *item2 = CPlayer->mo->FindInventory(PClass::FindClass(cmd.string[1]));
|
|
|
|
if(cmd.flags & SBARINFOEVENT_AND)
|
|
|
|
{
|
|
|
|
if((item1 != NULL && item2 != NULL) && !(cmd.flags & SBARINFOEVENT_NOT))
|
2008-04-25 09:40:08 +00:00
|
|
|
doCommands(cmd.subBlock, xOffset, yOffset, alpha);
|
2008-03-24 17:48:55 +00:00
|
|
|
else if((item1 == NULL || item2 == NULL) && (cmd.flags & SBARINFOEVENT_NOT))
|
2008-04-25 09:40:08 +00:00
|
|
|
doCommands(cmd.subBlock, xOffset, yOffset, alpha);
|
2008-03-24 17:48:55 +00:00
|
|
|
}
|
|
|
|
else if(cmd.flags & SBARINFOEVENT_OR)
|
|
|
|
{
|
|
|
|
if((item1 != NULL || item2 != NULL) && !(cmd.flags & SBARINFOEVENT_NOT))
|
2008-04-25 09:40:08 +00:00
|
|
|
doCommands(cmd.subBlock, xOffset, yOffset, alpha);
|
2008-03-24 17:48:55 +00:00
|
|
|
else if((item1 == NULL && item2 == NULL) && (cmd.flags & SBARINFOEVENT_NOT))
|
2008-04-25 09:40:08 +00:00
|
|
|
doCommands(cmd.subBlock, xOffset, yOffset, alpha);
|
2008-03-24 17:48:55 +00:00
|
|
|
}
|
|
|
|
else if((item1 != NULL) && !(cmd.flags & SBARINFOEVENT_NOT))
|
2008-04-25 09:40:08 +00:00
|
|
|
doCommands(cmd.subBlock, xOffset, yOffset, alpha);
|
2008-03-24 17:48:55 +00:00
|
|
|
else if((item1 == NULL) && (cmd.flags & SBARINFOEVENT_NOT))
|
2008-04-25 09:40:08 +00:00
|
|
|
doCommands(cmd.subBlock, xOffset, yOffset, alpha);
|
2008-03-24 17:48:55 +00:00
|
|
|
break;
|
|
|
|
}
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//draws an image with the specified flags
|
2008-08-06 07:38:21 +00:00
|
|
|
void DSBarInfo::DrawGraphic(FTexture* texture, int x, int y, int xOffset, int yOffset, int alpha, bool fullScreenOffsets,
|
2008-08-09 03:43:29 +00:00
|
|
|
bool translate, bool dim, int offsetflags) //flags
|
2008-03-19 09:53:23 +00:00
|
|
|
{
|
2008-04-05 12:14:33 +00:00
|
|
|
if (texture == NULL)
|
|
|
|
return;
|
2008-04-25 09:40:08 +00:00
|
|
|
|
2008-08-09 03:43:29 +00:00
|
|
|
if(offsetflags & DRAWIMAGE_OFFSET_CENTER)
|
2008-03-19 09:53:23 +00:00
|
|
|
{
|
|
|
|
x -= (texture->GetWidth()/2)-texture->LeftOffset;
|
|
|
|
y -= (texture->GetHeight()/2)-texture->TopOffset;
|
|
|
|
}
|
2008-04-25 09:40:08 +00:00
|
|
|
|
2008-08-07 07:17:29 +00:00
|
|
|
x += xOffset;
|
|
|
|
y += yOffset;
|
|
|
|
int w, h;
|
2008-08-06 07:38:21 +00:00
|
|
|
if(!fullScreenOffsets)
|
|
|
|
{
|
|
|
|
// I'll handle the conversion from fixed to int myself for more control
|
2008-08-07 07:17:29 +00:00
|
|
|
fixed_t fx = (x + ST_X) << FRACBITS;
|
|
|
|
fixed_t fy = (y + ST_Y) << FRACBITS;
|
2008-08-06 07:38:21 +00:00
|
|
|
fixed_t fw = texture->GetScaledWidth() << FRACBITS;
|
|
|
|
fixed_t fh = texture->GetScaledHeight() << FRACBITS;
|
|
|
|
if(Scaled)
|
|
|
|
screen->VirtualToRealCoords(fx, fy, fw, fh, 320, 200, true);
|
|
|
|
x = fx >> FRACBITS;
|
|
|
|
y = fy >> FRACBITS;
|
|
|
|
// Round to nearest
|
2008-08-07 07:17:29 +00:00
|
|
|
w = (fw + (FRACUNIT>>1)) >> FRACBITS;
|
|
|
|
h = (fh + (FRACUNIT>>1)) >> FRACBITS;
|
2008-08-12 03:19:35 +00:00
|
|
|
screen->DrawTexture(texture, x, y,
|
|
|
|
DTA_DestWidth, w,
|
|
|
|
DTA_DestHeight, h,
|
|
|
|
DTA_Translation, translate ? getTranslation() : 0,
|
|
|
|
DTA_ColorOverlay, dim ? DIM_OVERLAY : 0,
|
|
|
|
DTA_CenterBottomOffset, (offsetflags & DRAWIMAGE_OFFSET_CENTERBOTTOM),
|
|
|
|
DTA_Alpha, alpha,
|
|
|
|
TAG_DONE);
|
2008-08-06 07:38:21 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-08-07 07:17:29 +00:00
|
|
|
w = texture->GetScaledWidth();
|
|
|
|
h = texture->GetScaledHeight();
|
2008-08-09 03:43:29 +00:00
|
|
|
if(vid_fps && x < 0 && y >= 0)
|
|
|
|
y += 10;
|
2008-08-12 03:19:35 +00:00
|
|
|
screen->DrawTexture(texture, x, y,
|
|
|
|
DTA_DestWidth, w,
|
|
|
|
DTA_DestHeight, h,
|
|
|
|
DTA_Translation, translate ? getTranslation() : 0,
|
|
|
|
DTA_ColorOverlay, dim ? DIM_OVERLAY : 0,
|
|
|
|
DTA_CenterBottomOffset, (offsetflags & DRAWIMAGE_OFFSET_CENTERBOTTOM),
|
|
|
|
DTA_HUDRules, HUD_Normal,
|
|
|
|
DTA_Alpha, alpha,
|
|
|
|
TAG_DONE);
|
2008-08-06 07:38:21 +00:00
|
|
|
}
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
|
|
|
|
2008-08-09 03:43:29 +00:00
|
|
|
void DSBarInfo::DrawString(const char* str, int x, int y, int xOffset, int yOffset, int alpha, bool fullScreenOffsets, EColorRange translation, int spacing, bool drawshadow)
|
2008-03-19 09:53:23 +00:00
|
|
|
{
|
|
|
|
x += spacing;
|
|
|
|
while(*str != '\0')
|
|
|
|
{
|
|
|
|
if(*str == ' ')
|
|
|
|
{
|
|
|
|
x += drawingFont->GetSpaceWidth();
|
|
|
|
str++;
|
|
|
|
continue;
|
|
|
|
}
|
2008-03-22 09:26:59 +00:00
|
|
|
int width;
|
|
|
|
if(SBarInfoScript->spacingCharacter == '\0') //No monospace?
|
|
|
|
width = drawingFont->GetCharWidth((int) *str);
|
|
|
|
else
|
|
|
|
width = drawingFont->GetCharWidth((int) SBarInfoScript->spacingCharacter);
|
2008-03-19 09:53:23 +00:00
|
|
|
FTexture* character = drawingFont->GetChar((int) *str, &width);
|
|
|
|
if(character == NULL) //missing character.
|
|
|
|
{
|
|
|
|
str++;
|
|
|
|
continue;
|
|
|
|
}
|
2008-03-22 09:26:59 +00:00
|
|
|
if(SBarInfoScript->spacingCharacter == '\0') //If we are monospaced lets use the offset
|
|
|
|
x += (character->LeftOffset+1); //ignore x offsets since we adapt to character size
|
2008-08-07 07:17:29 +00:00
|
|
|
|
|
|
|
int rx, ry, rw, rh;
|
|
|
|
rx = x + xOffset;
|
|
|
|
ry = y + yOffset;
|
|
|
|
rw = character->GetScaledWidth();
|
|
|
|
rh = character->GetScaledHeight();
|
2008-08-06 07:38:21 +00:00
|
|
|
if(!fullScreenOffsets)
|
|
|
|
{
|
2008-08-07 07:17:29 +00:00
|
|
|
rx += ST_X;
|
|
|
|
ry += ST_Y;
|
2008-08-06 07:38:21 +00:00
|
|
|
if(Scaled)
|
|
|
|
screen->VirtualToRealCoordsInt(rx, ry, rw, rh, 320, 200, true);
|
|
|
|
}
|
2008-08-09 03:43:29 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
if(vid_fps && x < 0 && y >= 0)
|
|
|
|
y += 10;
|
|
|
|
}
|
|
|
|
if(drawshadow)
|
|
|
|
{
|
|
|
|
int salpha = fixed_t(((double) alpha / (double) FRACUNIT) * ((double) HR_SHADOW / (double) FRACUNIT) * FRACUNIT);
|
2008-08-12 03:19:35 +00:00
|
|
|
if(!fullScreenOffsets)
|
|
|
|
{
|
|
|
|
screen->DrawTexture(character, rx+2, ry+2,
|
|
|
|
DTA_DestWidth, rw,
|
|
|
|
DTA_DestHeight, rh,
|
|
|
|
DTA_Alpha, salpha,
|
|
|
|
DTA_FillColor, 0,
|
|
|
|
TAG_DONE);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
screen->DrawTexture(character, rx+2, ry+2,
|
|
|
|
DTA_DestWidth, rw,
|
|
|
|
DTA_DestHeight, rh,
|
|
|
|
DTA_Alpha, salpha,
|
|
|
|
DTA_HUDRules, HUD_Normal,
|
|
|
|
DTA_FillColor, 0,
|
|
|
|
TAG_DONE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(!fullScreenOffsets)
|
|
|
|
{
|
|
|
|
screen->DrawTexture(character, rx, ry,
|
|
|
|
DTA_DestWidth, rw,
|
|
|
|
DTA_DestHeight, rh,
|
|
|
|
DTA_Translation, drawingFont->GetColorTranslation(translation),
|
|
|
|
DTA_Alpha, alpha,
|
|
|
|
TAG_DONE);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
screen->DrawTexture(character, rx, ry,
|
|
|
|
DTA_DestWidth, rw,
|
|
|
|
DTA_DestHeight, rh,
|
|
|
|
DTA_Translation, drawingFont->GetColorTranslation(translation),
|
|
|
|
DTA_Alpha, alpha,
|
|
|
|
DTA_HUDRules, HUD_Normal,
|
|
|
|
TAG_DONE);
|
2008-08-09 03:43:29 +00:00
|
|
|
}
|
2008-03-22 09:26:59 +00:00
|
|
|
if(SBarInfoScript->spacingCharacter == '\0')
|
2008-03-24 17:48:55 +00:00
|
|
|
x += width + spacing - (character->LeftOffset+1);
|
|
|
|
else //width gets changed at the call to GetChar()
|
|
|
|
x += drawingFont->GetCharWidth((int) SBarInfoScript->spacingCharacter) + spacing;
|
2008-03-19 09:53:23 +00:00
|
|
|
str++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//draws the specified number up to len digits
|
2008-08-09 03:43:29 +00:00
|
|
|
void DSBarInfo::DrawNumber(int num, int len, int x, int y, int xOffset, int yOffset, int alpha, bool fullScreenOffsets, EColorRange translation, int spacing, bool fillzeros, bool drawshadow)
|
2008-03-19 09:53:23 +00:00
|
|
|
{
|
|
|
|
FString value;
|
|
|
|
int maxval = (int) ceil(pow(10., len))-1;
|
2008-04-05 07:06:26 +00:00
|
|
|
if(!fillzeros || len == 1)
|
|
|
|
num = clamp(num, -maxval, maxval);
|
|
|
|
else //The community wanted negatives to take the last digit, but we can only do this if there is room
|
|
|
|
num = clamp(num, (int) -(ceil(pow(10., len-1))-1), maxval);
|
2008-03-19 09:53:23 +00:00
|
|
|
value.Format("%d", num);
|
2008-04-05 07:06:26 +00:00
|
|
|
if(fillzeros)
|
|
|
|
{
|
|
|
|
if(num < 0) //We don't want the negative just yet
|
|
|
|
value.Format("%d", -num);
|
|
|
|
while(fillzeros && value.Len() < (unsigned int) len)
|
|
|
|
{
|
|
|
|
if(num < 0 && value.Len() == (unsigned int) (len-1))
|
|
|
|
value.Insert(0, "-");
|
|
|
|
else
|
|
|
|
value.Insert(0, "0");
|
|
|
|
}
|
|
|
|
}
|
2008-03-22 09:26:59 +00:00
|
|
|
if(SBarInfoScript->spacingCharacter == '\0')
|
|
|
|
x -= int(drawingFont->StringWidth(value)+(spacing * value.Len()));
|
2008-06-01 03:35:47 +00:00
|
|
|
else //monospaced, so just multiplay the character size
|
2008-03-22 09:26:59 +00:00
|
|
|
x -= int((drawingFont->GetCharWidth((int) SBarInfoScript->spacingCharacter) + spacing) * value.Len());
|
2008-08-09 03:43:29 +00:00
|
|
|
DrawString(value, x, y, xOffset, yOffset, alpha, fullScreenOffsets, translation, spacing, drawshadow);
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//draws the mug shot
|
2008-08-07 07:17:29 +00:00
|
|
|
void DSBarInfo::DrawFace(const char *defaultFace, int accuracy, int stateflags, int x, int y, int xOffset, int yOffset, int alpha, bool fullScreenOffsets)
|
2008-03-19 09:53:23 +00:00
|
|
|
{
|
2008-08-07 07:17:29 +00:00
|
|
|
FTexture *face = MugShot.GetFace(CPlayer, defaultFace, accuracy, stateflags);
|
2008-06-01 03:35:47 +00:00
|
|
|
if (face != NULL)
|
2008-05-31 01:30:53 +00:00
|
|
|
{
|
2008-08-06 07:38:21 +00:00
|
|
|
DrawGraphic(face, x, y, xOffset, yOffset, alpha, fullScreenOffsets);
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-08-06 07:38:21 +00:00
|
|
|
void DSBarInfo::DrawInventoryBar(int type, int num, int x, int y, int xOffset, int yOffset, int alpha, bool fullScreenOffsets, bool alwaysshow,
|
2008-03-19 09:53:23 +00:00
|
|
|
int counterx, int countery, EColorRange translation, bool drawArtiboxes, bool noArrows, bool alwaysshowcounter)
|
|
|
|
{ //yes, there is some Copy & Paste here too
|
|
|
|
AInventory *item;
|
|
|
|
int i;
|
2008-08-06 07:38:21 +00:00
|
|
|
int spacing = (type != GAME_Strife) ? Images[invBarOffset + imgARTIBOX]->GetScaledWidth() + 1 : Images[invBarOffset + imgCURSOR]->GetScaledWidth() - 1;
|
2008-03-19 09:53:23 +00:00
|
|
|
|
|
|
|
// If the player has no artifacts, don't draw the bar
|
|
|
|
CPlayer->mo->InvFirst = ValidateInvFirst(num);
|
|
|
|
if(CPlayer->mo->InvFirst != NULL || alwaysshow)
|
|
|
|
{
|
|
|
|
for(item = CPlayer->mo->InvFirst, i = 0; item != NULL && i < num; item = item->NextInv(), ++i)
|
|
|
|
{
|
|
|
|
if(drawArtiboxes)
|
|
|
|
{
|
2008-08-06 07:38:21 +00:00
|
|
|
DrawGraphic(Images[invBarOffset + imgARTIBOX], x+i*spacing, y, xOffset, yOffset, alpha, fullScreenOffsets);
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
2008-05-19 23:07:08 +00:00
|
|
|
if(type != GAME_Strife) //Strife draws the cursor before the icons
|
|
|
|
DrawGraphic(TexMan(item->Icon), x+i*spacing, y, xOffset, yOffset, alpha, false, item->Amount <= 0);
|
2008-03-19 09:53:23 +00:00
|
|
|
if(item == CPlayer->mo->InvSel)
|
|
|
|
{
|
|
|
|
if(type == GAME_Heretic)
|
|
|
|
{
|
2008-08-06 07:38:21 +00:00
|
|
|
DrawGraphic(Images[invBarOffset + imgSELECTBOX], x+i*spacing, y+29, xOffset, yOffset, alpha, fullScreenOffsets);
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
2008-05-18 15:48:03 +00:00
|
|
|
else if(type == GAME_Hexen)
|
|
|
|
{
|
2008-08-06 07:38:21 +00:00
|
|
|
DrawGraphic(Images[invBarOffset + imgSELECTBOX], x+i*spacing, y-1, xOffset, yOffset, alpha, fullScreenOffsets);
|
2008-05-18 15:48:03 +00:00
|
|
|
}
|
2008-05-19 23:07:08 +00:00
|
|
|
else if(type == GAME_Strife)
|
|
|
|
{
|
2008-08-06 07:38:21 +00:00
|
|
|
DrawGraphic(Images[invBarOffset + imgCURSOR], x+i*spacing-6, y-2, xOffset, yOffset, alpha, fullScreenOffsets);
|
2008-05-19 23:07:08 +00:00
|
|
|
}
|
2008-03-19 09:53:23 +00:00
|
|
|
else
|
|
|
|
{
|
2008-08-06 07:38:21 +00:00
|
|
|
DrawGraphic(Images[invBarOffset + imgSELECTBOX], x+i*spacing, y, xOffset, yOffset, alpha, fullScreenOffsets);
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
|
|
|
}
|
2008-05-19 23:07:08 +00:00
|
|
|
if(type == GAME_Strife)
|
2008-08-06 07:38:21 +00:00
|
|
|
DrawGraphic(TexMan(item->Icon), x+i*spacing, y, xOffset, yOffset, alpha, fullScreenOffsets, false, item->Amount <= 0);
|
2008-05-19 23:07:08 +00:00
|
|
|
if(alwaysshowcounter || item->Amount != 1)
|
|
|
|
{
|
2008-08-06 07:38:21 +00:00
|
|
|
DrawNumber(item->Amount, 3, counterx+i*spacing, countery, xOffset, yOffset, alpha, fullScreenOffsets, translation);
|
2008-05-19 23:07:08 +00:00
|
|
|
}
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
|
|
|
for (; i < num && drawArtiboxes; ++i)
|
|
|
|
{
|
2008-08-06 07:38:21 +00:00
|
|
|
DrawGraphic(Images[invBarOffset + imgARTIBOX], x+i*spacing, y, xOffset, yOffset, alpha, fullScreenOffsets);
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
|
|
|
// Is there something to the left?
|
|
|
|
if (!noArrows && CPlayer->mo->FirstInv() != CPlayer->mo->InvFirst)
|
|
|
|
{
|
2008-04-05 07:06:26 +00:00
|
|
|
DrawGraphic(Images[!(gametic & 4) ?
|
2008-08-06 07:38:21 +00:00
|
|
|
invBarOffset + imgINVLFGEM1 : invBarOffset + imgINVLFGEM2], (type != GAME_Strife) ? x-12 : x-14, y, xOffset, yOffset, alpha, fullScreenOffsets);
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
|
|
|
// Is there something to the right?
|
|
|
|
if (!noArrows && item != NULL)
|
|
|
|
{
|
2008-04-05 07:06:26 +00:00
|
|
|
DrawGraphic(Images[!(gametic & 4) ?
|
2008-08-06 07:38:21 +00:00
|
|
|
invBarOffset + imgINVRTGEM1 : invBarOffset + imgINVRTGEM2], (type != GAME_Strife) ? x+num*31+2 : x+num*35-4, y, xOffset, yOffset, alpha, fullScreenOffsets);
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//draws heretic/hexen style life gems
|
2008-08-06 07:38:21 +00:00
|
|
|
void DSBarInfo::DrawGem(FTexture* chain, FTexture* gem, int value, int x, int y, int xOffset, int yOffset, int alpha, bool fullScreenOffsets, int padleft, int padright, int chainsize,
|
2008-03-19 09:53:23 +00:00
|
|
|
bool wiggle, bool translate)
|
|
|
|
{
|
2008-04-20 00:23:07 +00:00
|
|
|
if(chain == NULL)
|
|
|
|
return;
|
2008-03-19 09:53:23 +00:00
|
|
|
if(value > 100)
|
|
|
|
value = 100;
|
|
|
|
else if(value < 0)
|
|
|
|
value = 0;
|
|
|
|
if(wiggle)
|
|
|
|
y += chainWiggle;
|
|
|
|
int chainWidth = chain->GetWidth();
|
|
|
|
int offset = (int) (((double) (chainWidth-padleft-padright)/100)*value);
|
2008-08-06 07:38:21 +00:00
|
|
|
DrawGraphic(chain, x+(offset%chainsize), y, xOffset, yOffset, alpha, fullScreenOffsets);
|
2008-03-19 09:53:23 +00:00
|
|
|
if(gem != NULL)
|
2008-08-06 07:38:21 +00:00
|
|
|
DrawGraphic(gem, x+padleft+offset, y, xOffset, yOffset, alpha, fullScreenOffsets, translate);
|
2008-03-19 09:53:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
FRemapTable* DSBarInfo::getTranslation()
|
|
|
|
{
|
|
|
|
if(gameinfo.gametype & GAME_Raven)
|
|
|
|
return translationtables[TRANSLATION_PlayersExtra][int(CPlayer - players)];
|
|
|
|
return translationtables[TRANSLATION_Players][int(CPlayer - players)];
|
|
|
|
}
|
|
|
|
|
|
|
|
IMPLEMENT_CLASS(DSBarInfo);
|
|
|
|
|
|
|
|
DBaseStatusBar *CreateCustomStatusBar ()
|
|
|
|
{
|
|
|
|
return new DSBarInfo;
|
|
|
|
}
|