3221 lines
97 KiB
C++
3221 lines
97 KiB
C++
/*
|
|
** Command & Conquer Renegade(tm)
|
|
** Copyright 2025 Electronic Arts Inc.
|
|
**
|
|
** This program is free software: you can redistribute it and/or modify
|
|
** it under the terms of the GNU General Public License as published by
|
|
** the Free Software Foundation, either version 3 of the License, or
|
|
** (at your option) any later version.
|
|
**
|
|
** This program is distributed in the hope that it will be useful,
|
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
** GNU General Public License for more details.
|
|
**
|
|
** You should have received a copy of the GNU General Public License
|
|
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
/***********************************************************************************************
|
|
*** Confidential - Westwood Studios ***
|
|
***********************************************************************************************
|
|
* *
|
|
* Project Name : Commando *
|
|
* *
|
|
* $Archive:: /Commando/Code/Combat/hud.cpp $*
|
|
* *
|
|
* $Author:: Byon_g $*
|
|
* *
|
|
* $Modtime:: 2/11/02 2:27p $*
|
|
* *
|
|
* $Revision:: 228 $*
|
|
* *
|
|
*---------------------------------------------------------------------------------------------*
|
|
* Functions: *
|
|
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
|
|
|
#include "hud.h"
|
|
|
|
#include <stdio.h>
|
|
|
|
#include "wwprofile.h"
|
|
#include "assets.h"
|
|
#include "font3d.h"
|
|
#include "combat.h"
|
|
#include "soldier.h"
|
|
#include "debug.h"
|
|
#include "ccamera.h"
|
|
#include "vehicle.h"
|
|
#include "weapons.h"
|
|
#include "radar.h"
|
|
#include "texture.h"
|
|
#include "phys.h"
|
|
#include "render2d.h"
|
|
#include "hudinfo.h"
|
|
#include "globalsettings.h"
|
|
#include "translatedb.h"
|
|
#include "playerdata.h"
|
|
#include "playertype.h"
|
|
#include "sniper.h"
|
|
#include "render2dsentence.h"
|
|
#include "input.h"
|
|
#include "building.h"
|
|
#include "objectives.h"
|
|
#include "weaponbag.h"
|
|
#include "string_ids.h"
|
|
#include "gametype.h"
|
|
#include "stylemgr.h"
|
|
|
|
|
|
static void Generate_WChar_Text_From_Number(WCHAR* text,int digits,int min_digits,int value)
|
|
{
|
|
text[digits]=0;
|
|
while (digits) {
|
|
digits--;
|
|
text[digits]=value%10+'0';
|
|
value/=10;
|
|
min_digits--;
|
|
if (value==0 && (min_digits == 0)) break;
|
|
}
|
|
if ((min_digits==0) && digits) {
|
|
int i=0;
|
|
while (WCHAR c=text[digits++]) {
|
|
text[i++]=c;
|
|
}
|
|
text[i]=0;
|
|
}
|
|
}
|
|
|
|
/*
|
|
**
|
|
*/
|
|
Vector2 INFO_UV_SCALE( 1.0f/256.0f, 1.0f/256.0f );
|
|
|
|
Vector2 INFO_OFFSET( 7, -179 );
|
|
Vector2 FRAME_1_UV_UL( 96, 105 );
|
|
Vector2 FRAME_1_UV_LR( 214, 255 );
|
|
Vector2 FRAME_1_OFFSET( -3, -1 );
|
|
Vector2 FRAME_2_UV_UL( 215, 125 );
|
|
Vector2 FRAME_2_UV_LR( 255, 192 );
|
|
Vector2 FRAME_2_OFFSET( 114, 57 );
|
|
Vector2 FRAME_3_UV_UL( 218, 192 );
|
|
Vector2 FRAME_3_UV_LR( 255, 201 );
|
|
Vector2 FRAME_3_OFFSET( 154, 115 );
|
|
Vector2 FRAME_4_UV_UL( 216, 200 );
|
|
Vector2 FRAME_4_UV_LR( 255, 255 );
|
|
Vector2 FRAME_4_OFFSET( 191, 115 );
|
|
Vector2 FRAME_5_UV_UL( 80, 203 );
|
|
Vector2 FRAME_5_UV_LR( 100, 258 );
|
|
Vector2 FRAME_5_OFFSET( 230, 116 );
|
|
Vector2 FRAME_6_UV_UL( 216, 101 );
|
|
Vector2 FRAME_6_UV_LR( 240, 125 );
|
|
Vector2 FRAME_6_OFFSET( 74, 149 );
|
|
Vector2 HEALTH_BACK_UV_UL( 183, 241 );
|
|
Vector2 HEALTH_BACK_UV_LR( 186, 248 );
|
|
Vector2 HEALTH_BACK_UL( 98, 122 );
|
|
Vector2 HEALTH_BACK_LR( 224, 168 );
|
|
Vector2 GRADIENT_BLACK_UV_UL( 3, 135 );
|
|
Vector2 GRADIENT_BLACK_UV_LR( 44, 144 );
|
|
Vector2 HEALTH_TEXT_BACK_UL( 77, 124 );
|
|
Vector2 HEALTH_TEXT_BACK_LR( 163, 150 );
|
|
Vector2 HEALTH_UV_UL( 94, 52 );
|
|
Vector2 HEALTH_UV_LR( 249, 100 );
|
|
Vector2 HEALTH_OFFSET( 73, 121 );
|
|
Vector2 SHIELD_UV_UL( 66, 97 );
|
|
Vector2 SHIELD_UV_LR( 96, 132 );
|
|
Vector2 SHIELD_OFFSET( 211, 140 );
|
|
Vector2 KEY_1_UV_UL( 30, 180 );
|
|
Vector2 KEY_1_UV_LR( 57, 197 );
|
|
Vector2 KEY_1_OFFSET( 32, 134 );
|
|
Vector2 KEY_2_UV_UL( 0, 181 );
|
|
Vector2 KEY_2_UV_LR( 30, 197 );
|
|
Vector2 KEY_2_OFFSET( 41, 140 );
|
|
Vector2 KEY_3_UV_UL( 69, 133 );
|
|
Vector2 KEY_3_UV_LR( 97, 149 );
|
|
Vector2 KEY_3_OFFSET( 50, 148 );
|
|
Vector2 HEALTH_CROSS_1_UV_UL( 33, 199 );
|
|
Vector2 HEALTH_CROSS_1_UV_LR( 63, 226 );
|
|
Vector2 HEALTH_CROSS_1_OFFSET( 77, 124 );
|
|
Vector2 HEALTH_CROSS_2_UV_UL( 33, 228 );
|
|
Vector2 HEALTH_CROSS_2_UV_LR( 63, 258 );
|
|
Vector2 HEALTH_CROSS_2_OFFSET( 77, 124 );
|
|
Vector2 TIME_BACK_UL( 150, 97 );
|
|
Vector2 TIME_BACK_LR( 213, 116 );
|
|
Vector2 TIME_CLOCK_UV_UL( 46, 125 );
|
|
Vector2 TIME_CLOCK_UV_LR( 66, 148 );
|
|
Vector2 TIME_CLOCK_OFFSET( 186, 94 );
|
|
Vector2 WEAPON_BOX_UV_UL( 0, 0 );
|
|
Vector2 WEAPON_BOX_UV_LR( 95, 95 );
|
|
Vector2 WEAPON_BOX_OFFSET( 195, -53 );
|
|
Vector2 POWER_OUT_ICON_UV_UL( 0, 95 );
|
|
Vector2 POWER_OUT_ICON_UV_LR( 30, 129 );
|
|
Vector2 POWER_OUT_ICON_OFFSET( 143, 41 );
|
|
Vector2 REPAIR_ICON_UV_UL( 31, 97 );
|
|
Vector2 REPAIR_ICON_UV_LR( 61, 126 );
|
|
Vector2 REPAIR_ICON_OFFSET( 181, 43 );
|
|
Vector2 GDI_ICON_UV_UL( 14, 222 );
|
|
Vector2 GDI_ICON_UV_LR( 34, 238 );
|
|
Vector2 GDI_ICON_OFFSET( 217, 77 );
|
|
Vector2 NOD_ICON_UV_UL( 14, 205 );
|
|
Vector2 NOD_ICON_UV_LR( 34, 221 );
|
|
Vector2 NOD_ICON_OFFSET( 238, 76 );
|
|
Vector2 NEUTRAL_ICON_UV_UL( 14, 238 );
|
|
Vector2 NEUTRAL_ICON_UV_LR( 33, 257 );
|
|
Vector2 NEUTRAL_ICON_OFFSET( 260, 77 );
|
|
Vector2 BULLET_ICON_UV_UL( 2, 211 );
|
|
Vector2 BULLET_ICON_UV_LR( 13, 255 );
|
|
Vector2 BULLET_ICON_OFFSET( -20, -30 );
|
|
Vector2 RADAR_CENTER_OFFSET( 55, 78 );
|
|
Vector2 DAMAGE_1_UV_UL( 65, 184 );
|
|
Vector2 DAMAGE_1_UV_LR( 78, 255 );
|
|
Vector2 DAMAGE_2_UV_UL( 200, 3 );
|
|
Vector2 DAMAGE_2_UV_LR( 248, 51 );
|
|
Vector2 HORIZ_DAMAGE_SIZE( 81, 14 );
|
|
Vector2 VERT_DAMAGE_SIZE( 15, 78 );
|
|
Vector2 DIAG_DAMAGE_SIZE( 53, 59 );
|
|
Vector2 HV_DAMAGE_OFFSET( 170, 168 );
|
|
Vector2 DIAG_DAMAGE_OFFSET( 119, 117 );
|
|
//Vector2 POWERUP_BOX_UV_UL( 48, 0 );
|
|
//Vector2 POWERUP_BOX_UV_LR( 129, 54 );
|
|
Vector2 POWERUP_BOX_UV_UL( 50, 1 );
|
|
Vector2 POWERUP_BOX_UV_LR( 127, 52 );
|
|
Vector2 RADAR_RINGS_UV_UL( 95, 0 );
|
|
Vector2 RADAR_RINGS_UV_LR( 197, 53 );
|
|
Vector2 RADAR_RINGS_L_OFFSET( -51, -50 );
|
|
Vector2 RADAR_RINGS_R_OFFSET( 0, -50 );
|
|
Vector2 RADAR_STAR_UV_UL( 241, 103 );
|
|
Vector2 RADAR_STAR_UV_LR( 249, 111 );
|
|
Vector2 RADAR_STAR_OFFSET( 280, 50 );
|
|
Vector2 RADAR_SQUARE_UV_UL( 247, 85 );
|
|
Vector2 RADAR_SQUARE_UV_LR( 255, 93 );
|
|
Vector2 RADAR_SQUARE_OFFSET( 290, 50 );
|
|
Vector2 RADAR_TRIANGLE_UV_UL( 247, 93 );
|
|
Vector2 RADAR_TRIANGLE_UV_LR( 255, 101 );
|
|
Vector2 RADAR_TRIANGLE_OFFSET( 300, 50 );
|
|
Vector2 RADAR_CIRCLE_UV_UL( 247, 77 );
|
|
Vector2 RADAR_CIRCLE_UV_LR( 255, 85 );
|
|
Vector2 RADAR_CIRCLE_OFFSET( 310, 50 );
|
|
Vector2 RADAR_BRACKET_UV_UL( 241, 114 );
|
|
Vector2 RADAR_BRACKET_UV_LR( 249, 122 );
|
|
Vector2 RADAR_BRACKET_OFFSET( 320, 50 );
|
|
Vector2 RADAR_SWEEP_UV_UL( 80, 182 );
|
|
Vector2 RADAR_SWEEP_UV_LR( 95, 191 );
|
|
Vector2 RADAR_SWEEP_OFFSET( 330, 50 );
|
|
|
|
Vector2 TARGET_HEALTH_L_UV_UL( 0, 165 );
|
|
Vector2 TARGET_HEALTH_L_UV_LR( 20, 181 );
|
|
Vector2 TARGET_HEALTH_R_UV_UL( 20, 165 );
|
|
//Vector2 TARGET_HEALTH_R_UV_LR( 96, 181 );
|
|
Vector2 TARGET_HEALTH_R_UV_LR( 96, 173 );
|
|
Vector2 TARGET_HEALTH_OFFSET( 123, 5 );
|
|
Vector2 TARGET_NAME_UV_UL( 1, 149 );
|
|
Vector2 TARGET_NAME_UV_LR( 91, 164 );
|
|
Vector2 TARGET_NAME_OFFSET( 125, 24 );
|
|
|
|
|
|
// Reticle
|
|
#define RETICLE_WIDTH (64.0f/640.0f)
|
|
#define RETICLE_HEIGHT (64.0f/480.0f)
|
|
|
|
|
|
//
|
|
|
|
Vector2 TARGET_ENTERABLE_UV_UL( 45, 209 );
|
|
Vector2 TARGET_ENTERABLE_UV_LR( 51, 215 );
|
|
Vector2 TARGET_ENTERABLE_SIZE( 32, 32 );
|
|
float TARGET_ENTERABLE_BOUNCE = 4;
|
|
|
|
/*
|
|
**
|
|
*/
|
|
//#define LARGE_FONT "FONT24x36.TGA"
|
|
#define LARGE_FONT "FONT12x16.TGA"
|
|
#define MEDIUM_FONT "FONT12x16.TGA"
|
|
#define SMALL_FONT "FONT6x8.TGA"
|
|
|
|
enum
|
|
{
|
|
HUD_HELP_TEXT_DISPLAYING = 0,
|
|
HUD_HELP_TEXT_FADING,
|
|
HUD_HELP_TEXT_DONE
|
|
};
|
|
|
|
/*
|
|
**
|
|
*/
|
|
#define HUD_MAIN_TEXTURE "HUD_MAIN.TGA"
|
|
#define HUD_CHATPBOX_TEXTURE "HUD_CHATPBOX.TGA"
|
|
#define HUD_WEAPONS_TEXTURE "hud_TibRVoltR.tga" /* This should be removed */
|
|
Render2DClass * InfoRenderer;
|
|
Render2DSentenceClass * HUDHelpTextRenderer;
|
|
Vector2 HUDHelpTextExtents (0, 0);
|
|
float HUDHelpTextTimer = 0;
|
|
int HUDHelpTextState = HUD_HELP_TEXT_DISPLAYING;
|
|
|
|
|
|
/*
|
|
**
|
|
*/
|
|
unsigned long COLOR( float alpha, unsigned long color = 0x00FFFFFF )
|
|
{
|
|
alpha = WWMath::Clamp( alpha, 0, 1 ) * 255.0f;
|
|
color &= 0x00FFFFFF;
|
|
color |= ((int)alpha) << 24;
|
|
return color;
|
|
}
|
|
|
|
unsigned long Get_Health_Color( float percent )
|
|
{
|
|
Vector3 color = HUDGlobalSettingsDef::Get_Instance()->Get_Health_High_Color();
|
|
if ( percent <= 0.5f ) {
|
|
color = HUDGlobalSettingsDef::Get_Instance()->Get_Health_Med_Color();
|
|
}
|
|
if ( percent <= 0.25f ) {
|
|
color = HUDGlobalSettingsDef::Get_Instance()->Get_Health_Low_Color();
|
|
}
|
|
|
|
return color.Convert_To_ARGB();
|
|
}
|
|
|
|
/*
|
|
** Powerup Display
|
|
*/
|
|
struct PowerupIconStruct {
|
|
|
|
PowerupIconStruct( void ) : Renderer( NULL ), Number( 0 ) {}
|
|
|
|
~PowerupIconStruct( void ) {
|
|
if ( Renderer != NULL ) {
|
|
delete Renderer;
|
|
Renderer = NULL;
|
|
}
|
|
}
|
|
|
|
WideStringClass Name;
|
|
int Number;
|
|
Render2DClass * Renderer;
|
|
RectClass UV;
|
|
RectClass IconBox;
|
|
float Timer;
|
|
};
|
|
|
|
// Two lists. A right one for weapons, health, and armor
|
|
static DynamicVectorClass<PowerupIconStruct*> RightPowerupIconList;
|
|
// and a left one for keys
|
|
static DynamicVectorClass<PowerupIconStruct*> LeftPowerupIconList;
|
|
|
|
Render2DClass * PowerupBoxRenderer;
|
|
Render2DSentenceClass * PowerupTextRenderer;
|
|
|
|
#define MAX_ICONS 5
|
|
#define POWERUP_TIME 6
|
|
|
|
static void Powerup_Init( void )
|
|
{
|
|
PowerupBoxRenderer = new Render2DClass();
|
|
PowerupBoxRenderer->Set_Texture( HUD_CHATPBOX_TEXTURE );
|
|
PowerupBoxRenderer->Set_Coordinate_Range( Render2DClass::Get_Screen_Resolution() );
|
|
PowerupBoxRenderer->Enable_Additive( true );
|
|
|
|
FontCharsClass * font = StyleMgrClass::Peek_Font( StyleMgrClass::FONT_INGAME_TXT );
|
|
PowerupTextRenderer = new Render2DSentenceClass();
|
|
PowerupTextRenderer->Set_Font( font );
|
|
|
|
WWASSERT( LeftPowerupIconList.Count() == 0 );
|
|
WWASSERT( RightPowerupIconList.Count() == 0 );
|
|
}
|
|
|
|
static void Powerup_Shutdown( void )
|
|
{
|
|
delete PowerupBoxRenderer;
|
|
PowerupBoxRenderer = NULL;
|
|
|
|
delete PowerupTextRenderer;
|
|
PowerupTextRenderer = NULL;
|
|
|
|
int i;
|
|
for ( i = 0; i < LeftPowerupIconList.Count(); i++ ) {
|
|
delete LeftPowerupIconList[i];
|
|
}
|
|
LeftPowerupIconList.Delete_All();
|
|
for ( i = 0; i < RightPowerupIconList.Count(); i++ ) {
|
|
delete RightPowerupIconList[i];
|
|
}
|
|
RightPowerupIconList.Delete_All();
|
|
}
|
|
|
|
static void Powerup_Add( const WCHAR * name, int number, const char * texture_name, const RectClass & uv, const Vector2 & offset, bool right_list = true )
|
|
{
|
|
PowerupIconStruct * data = new PowerupIconStruct();
|
|
data->Renderer = new Render2DClass();
|
|
StringClass new_name(true);
|
|
Strip_Path_From_Filename( new_name, texture_name );
|
|
data->Renderer->Set_Texture( new_name );
|
|
data->Renderer->Set_Coordinate_Range( Render2DClass::Get_Screen_Resolution() );
|
|
// data->Renderer->Enable_Additive( true );
|
|
|
|
// SurfaceClass::SurfaceDescription surface_desc;
|
|
// data->Renderer->Peek_Texture()->Get_Level_Description( surface_desc );
|
|
// float size = surface_desc.Width; // Assume square
|
|
float size = data->Renderer->Peek_Texture()->Get_Width(); // Assume square
|
|
data->UV = uv;
|
|
if ( size > 0 ) {
|
|
data->UV.Scale( Vector2( 1/size, 1/size ) );
|
|
}
|
|
data->IconBox = uv;
|
|
data->IconBox += offset + Vector2( 0, -40.0f ) - data->IconBox.Upper_Left();
|
|
data->Name = name;
|
|
data->Number = number;
|
|
data->Timer = POWERUP_TIME;
|
|
|
|
if ( right_list ) {
|
|
RightPowerupIconList.Add( data );
|
|
} else {
|
|
LeftPowerupIconList.Add( data );
|
|
}
|
|
}
|
|
|
|
void Powerup_Reset( void )
|
|
{
|
|
while ( LeftPowerupIconList.Count() ) {
|
|
delete LeftPowerupIconList[0];
|
|
LeftPowerupIconList.Delete(0);
|
|
}
|
|
while ( RightPowerupIconList.Count() ) {
|
|
delete RightPowerupIconList[0];
|
|
RightPowerupIconList.Delete(0);
|
|
}
|
|
}
|
|
|
|
#define POWERUP_BOX_BASE POWERUP_BOX_WIDTH + 6, 112
|
|
#define POWERUP_BOX_WIDTH 80
|
|
#define POWERUP_BOX_HEIGHT 55
|
|
#define POWERUP_BOX_SPACING (POWERUP_BOX_HEIGHT + 10)
|
|
#define POWERUP_BOX_UV 127,0,207,55
|
|
|
|
static void Powerup_Update( void )
|
|
{
|
|
PowerupBoxRenderer->Reset();
|
|
PowerupTextRenderer->Reset();
|
|
|
|
RectClass box_uv( POWERUP_BOX_UV_UL, POWERUP_BOX_UV_LR );
|
|
box_uv.Scale( Vector2( 1.0f/128.0f, 1.0f/128.0f ) );
|
|
|
|
#define ANIMATE_TIME 1.0f
|
|
|
|
// Two timers
|
|
static float LeftAnimateTimer = 0;
|
|
static float RightAnimateTimer = 0;
|
|
|
|
if ( LeftPowerupIconList.Count() > 0 && LeftPowerupIconList[0]->Timer < 0 ) {
|
|
LeftAnimateTimer += TimeManager::Get_Frame_Seconds();
|
|
if ( LeftAnimateTimer > ANIMATE_TIME ) {
|
|
LeftAnimateTimer = 0;
|
|
if ( LeftPowerupIconList.Count() ) {
|
|
delete LeftPowerupIconList[0];
|
|
LeftPowerupIconList.Delete(0);
|
|
}
|
|
}
|
|
} else {
|
|
LeftAnimateTimer = 0;
|
|
}
|
|
|
|
if ( RightPowerupIconList.Count() > 0 && RightPowerupIconList[0]->Timer < 0 ) {
|
|
RightAnimateTimer += TimeManager::Get_Frame_Seconds();
|
|
if ( RightAnimateTimer > ANIMATE_TIME ) {
|
|
RightAnimateTimer = 0;
|
|
if ( RightPowerupIconList.Count() ) {
|
|
delete RightPowerupIconList[0];
|
|
RightPowerupIconList.Delete(0);
|
|
}
|
|
}
|
|
} else {
|
|
RightAnimateTimer = 0;
|
|
}
|
|
|
|
RectClass box( POWERUP_BOX_UV_UL, POWERUP_BOX_UV_LR );
|
|
Vector2 start = Render2DClass::Get_Screen_Resolution().Lower_Right() - Vector2( POWERUP_BOX_BASE );
|
|
box += start - box.Lower_Left();
|
|
box -= Vector2( box.Left - 6, +75 );
|
|
|
|
int i;
|
|
for ( i = 0; i < MAX_ICONS && i < LeftPowerupIconList.Count(); i++ ) {
|
|
|
|
LeftPowerupIconList[i]->Timer -= TimeManager::Get_Frame_Seconds();
|
|
|
|
RectClass draw_box = box;
|
|
|
|
int green = 0xFF00FF00;
|
|
int white = 0xFFFFFFFF;
|
|
|
|
// Slide the bottom (first) icon away
|
|
if ( i == 0 && LeftAnimateTimer > 0.0f ) {
|
|
green = COLOR( WWMath::Clamp( 1.0f - (LeftAnimateTimer/ANIMATE_TIME), 0, 1 ), green ) ;
|
|
white = COLOR( WWMath::Clamp( 1.0f - (LeftAnimateTimer/ANIMATE_TIME), 0, 1 ), white ) ;
|
|
}
|
|
|
|
#if 0 // No boxes
|
|
// The box is drawn additive, so his color is green alpha
|
|
int box_color = (white & 0xFF000000) | ((white >> 16) & 0x0000FF00);
|
|
PowerupBoxRenderer->Add_Quad( draw_box, box_uv, box_color );
|
|
#endif
|
|
|
|
// Draw powerup name
|
|
PowerupTextRenderer->Build_Sentence( LeftPowerupIconList[i]->Name );
|
|
PowerupTextRenderer->Set_Location( Vector2( draw_box.Left + 1, draw_box.Top + POWERUP_BOX_HEIGHT - 15 ) );
|
|
PowerupTextRenderer->Draw_Sentence( white );
|
|
|
|
#if 0
|
|
// Draw powerup count
|
|
if ( LeftPowerupIconList[i]->Number != 0 ) {
|
|
WideStringClass num(0,true);
|
|
num.Format( L"%d", LeftPowerupIconList[i]->Number );
|
|
PowerupTextRenderer->Build_Sentence( num );
|
|
PowerupTextRenderer->Set_Location( Vector2( draw_box.Right - 12, draw_box.Top + 1 ) );
|
|
PowerupTextRenderer->Draw_Sentence( white );
|
|
}
|
|
#endif
|
|
|
|
RectClass icon_box = LeftPowerupIconList[i]->IconBox;
|
|
icon_box += draw_box.Upper_Left();
|
|
|
|
LeftPowerupIconList[i]->Renderer->Reset();
|
|
LeftPowerupIconList[i]->Renderer->Add_Quad( icon_box, LeftPowerupIconList[i]->UV, white );
|
|
|
|
// Drop the remaining icons down
|
|
if ( i == 0 && LeftAnimateTimer > ANIMATE_TIME * 0.5f ) {
|
|
box += Vector2( 0, ((2*LeftAnimateTimer/ANIMATE_TIME)-1) * POWERUP_BOX_SPACING );
|
|
}
|
|
|
|
box -= Vector2( 0, POWERUP_BOX_SPACING );
|
|
}
|
|
|
|
// Setup box for right
|
|
box = RectClass( POWERUP_BOX_UV_UL, POWERUP_BOX_UV_LR );
|
|
start = Render2DClass::Get_Screen_Resolution().Lower_Right() - Vector2( POWERUP_BOX_BASE );
|
|
box += start - box.Lower_Left();
|
|
|
|
for ( i = 0; i < MAX_ICONS && i < RightPowerupIconList.Count(); i++ ) {
|
|
|
|
RightPowerupIconList[i]->Timer -= TimeManager::Get_Frame_Seconds();
|
|
|
|
RectClass draw_box = box;
|
|
|
|
int green = 0xFF00FF00;
|
|
int white = 0xFFFFFFFF;
|
|
|
|
// Slide the bottom (first) icon away
|
|
if ( i == 0 && RightAnimateTimer > 0.0f ) {
|
|
green = COLOR( WWMath::Clamp( 1.0f - (RightAnimateTimer/ANIMATE_TIME), 0, 1 ), green ) ;
|
|
white = COLOR( WWMath::Clamp( 1.0f - (RightAnimateTimer/ANIMATE_TIME), 0, 1 ), white ) ;
|
|
}
|
|
|
|
#if 0 // No boxes
|
|
// The box is drawn additive, so his color is green alpha
|
|
int box_color = (white & 0xFF000000) | ((white >> 16) & 0x0000FF00);
|
|
PowerupBoxRenderer->Add_Quad( draw_box, box_uv, box_color );
|
|
#endif
|
|
|
|
// Draw powerup name
|
|
PowerupTextRenderer->Build_Sentence( RightPowerupIconList[i]->Name );
|
|
float left_edge = draw_box.Left + 1;
|
|
Vector2 extents = PowerupTextRenderer->Get_Text_Extents( RightPowerupIconList[i]->Name );
|
|
if ( left_edge + extents.X + 1> Render2DClass::Get_Screen_Resolution().Right ) {
|
|
left_edge = Render2DClass::Get_Screen_Resolution().Right - extents.X - 1;
|
|
}
|
|
PowerupTextRenderer->Set_Location( Vector2( left_edge, draw_box.Top + POWERUP_BOX_HEIGHT - 15 ) );
|
|
PowerupTextRenderer->Draw_Sentence( white );
|
|
|
|
// Draw powerup count
|
|
if ( RightPowerupIconList[i]->Number != 0 ) {
|
|
WideStringClass num(0,true);
|
|
num.Format( L"%d", RightPowerupIconList[i]->Number );
|
|
PowerupTextRenderer->Build_Sentence( num );
|
|
PowerupTextRenderer->Set_Location( Vector2( draw_box.Right - 12, draw_box.Top + 1 ) );
|
|
PowerupTextRenderer->Draw_Sentence( white );
|
|
}
|
|
|
|
RectClass icon_box = RightPowerupIconList[i]->IconBox;
|
|
icon_box += draw_box.Upper_Left();
|
|
|
|
RightPowerupIconList[i]->Renderer->Reset();
|
|
RightPowerupIconList[i]->Renderer->Add_Quad( icon_box, RightPowerupIconList[i]->UV, green );
|
|
|
|
// Drop the remaining icons down
|
|
if ( i == 0 && RightAnimateTimer > ANIMATE_TIME * 0.5f ) {
|
|
box += Vector2( 0, ((2*RightAnimateTimer/ANIMATE_TIME)-1) * POWERUP_BOX_SPACING );
|
|
}
|
|
|
|
box -= Vector2( 0, POWERUP_BOX_SPACING );
|
|
}
|
|
|
|
}
|
|
|
|
static void Powerup_Render( void )
|
|
{
|
|
#if 0 // No boxes
|
|
PowerupBoxRenderer->Render();
|
|
#endif
|
|
|
|
int i;
|
|
for ( i = 0; i < MAX_ICONS && i < LeftPowerupIconList.Count(); i++ ) {
|
|
LeftPowerupIconList[i]->Renderer->Render();
|
|
}
|
|
for ( i = 0; i < MAX_ICONS && i < RightPowerupIconList.Count(); i++ ) {
|
|
RightPowerupIconList[i]->Renderer->Render();
|
|
}
|
|
|
|
PowerupTextRenderer->Render();
|
|
}
|
|
|
|
|
|
/*
|
|
** Weapon Display
|
|
*/
|
|
Render2DClass * WeaponBoxRenderer;
|
|
Render2DClass * WeaponImageRenderer;
|
|
Render2DTextClass * WeaponClipCountRenderer;
|
|
Render2DTextClass * WeaponTotalCountRenderer;
|
|
Render2DSentenceClass * WeaponNameRenderer;
|
|
Vector2 WeaponBase;
|
|
|
|
WeaponClass * _LastHUDWeapon = NULL;
|
|
int _LastVehicleSeat = -1;
|
|
|
|
|
|
#define WEAPON_OFFSET 100, 110
|
|
//#define WEAPON_BOX_UV 0,0,95,95
|
|
|
|
#define SNIPER_UV 90,0,255,53
|
|
#define SNIPER_OFFSET -80,-4
|
|
|
|
|
|
static void HUD_Help_Text_Init( void )
|
|
{
|
|
//
|
|
// Load the font...
|
|
//
|
|
FontCharsClass *font = StyleMgrClass::Peek_Font( StyleMgrClass::FONT_INGAME_BIG_TXT );
|
|
WWASSERT (font != NULL);
|
|
|
|
//
|
|
// Configure the renderer
|
|
//
|
|
HUDHelpTextRenderer = new Render2DSentenceClass;
|
|
HUDHelpTextRenderer->Set_Font( font );
|
|
HUDHelpTextExtents.Set (0, 0);
|
|
HUDHelpTextTimer = 0;
|
|
HUDHelpTextState = HUD_HELP_TEXT_DISPLAYING;
|
|
return ;
|
|
}
|
|
|
|
static void HUD_Help_Text_Render( void )
|
|
{
|
|
const float HUD_HELP_TEXT_FADE_TIME = 2.0F;
|
|
const float HUD_HELP_TEXT_DISPLAY_TIME = 2.0F;
|
|
|
|
const WideStringClass &string = HUDInfo::Get_HUD_Help_Text();
|
|
bool is_empty = string.Is_Empty();
|
|
|
|
//
|
|
// Rebuild the renderer (if necessary)
|
|
//
|
|
if (HUDInfo::Is_HUD_Help_Text_Dirty()) {
|
|
HUDHelpTextState = HUD_HELP_TEXT_DISPLAYING;
|
|
HUDInfo::Set_Is_HUD_Help_Text_Dirty( false );
|
|
HUDHelpTextRenderer->Reset();
|
|
if (is_empty == false) {
|
|
HUDHelpTextRenderer->Build_Sentence( string );
|
|
HUDHelpTextTimer = HUD_HELP_TEXT_DISPLAY_TIME;
|
|
}
|
|
HUDHelpTextExtents = HUDHelpTextRenderer->Get_Text_Extents (string);
|
|
}
|
|
|
|
//
|
|
// Draw the text if there's something to draw
|
|
//
|
|
if ( is_empty == false ) {
|
|
HUDHelpTextRenderer->Reset_Polys();
|
|
|
|
//
|
|
// Render the text above the reticle
|
|
//
|
|
Vector2 reticle_offset = COMBAT_CAMERA->Get_Camera_Target_2D_Offset();
|
|
|
|
const RectClass &screen_rect = Render2DClass::Get_Screen_Resolution();
|
|
float x_pos = screen_rect.Center ().X - (HUDHelpTextExtents.X * 0.5F);
|
|
float y_pos = screen_rect.Center ().Y - (HUDHelpTextExtents.Y);
|
|
y_pos -= (RETICLE_HEIGHT * screen_rect.Height () * 0.25F);
|
|
|
|
HUDHelpTextRenderer->Set_Location( Vector2( x_pos, y_pos ) );
|
|
HUDHelpTextRenderer->Draw_Sentence( RGB_TO_INT32 (0, 0, 0) );
|
|
HUDHelpTextRenderer->Set_Location( Vector2( x_pos-1, y_pos-1 ) );
|
|
HUDHelpTextRenderer->Draw_Sentence( VRGB_TO_INT32 (HUDInfo::Get_HUD_Help_Text_Color ()) );
|
|
|
|
//
|
|
// Fade the text out (if necessary)
|
|
//
|
|
if (HUDHelpTextState == HUD_HELP_TEXT_FADING) {
|
|
float percent = WWMath::Clamp ((HUDHelpTextTimer / HUD_HELP_TEXT_FADE_TIME), 0.0F, 1.0F);
|
|
HUDHelpTextRenderer->Force_Alpha (percent * 0.5F);
|
|
} else {
|
|
HUDHelpTextRenderer->Force_Alpha (0.5F);
|
|
}
|
|
|
|
//
|
|
// Render the quads
|
|
//
|
|
HUDHelpTextRenderer->Render();
|
|
|
|
//
|
|
// Advance to the next state
|
|
//
|
|
HUDHelpTextTimer -= TimeManager::Get_Frame_Seconds ();
|
|
if (HUDHelpTextTimer <= 0) {
|
|
HUDHelpTextState ++;
|
|
|
|
//
|
|
// Clear the text if necessary
|
|
//
|
|
if (HUDHelpTextState >= HUD_HELP_TEXT_DONE) {
|
|
HUDInfo::Set_HUD_Help_Text( L"" );
|
|
HUDHelpTextRenderer->Reset();
|
|
} else if (HUDHelpTextState == HUD_HELP_TEXT_FADING) {
|
|
HUDHelpTextTimer = HUD_HELP_TEXT_FADE_TIME;
|
|
}
|
|
}
|
|
}
|
|
|
|
return ;
|
|
}
|
|
|
|
static void HUD_Help_Text_Shutdown( void )
|
|
{
|
|
delete HUDHelpTextRenderer;
|
|
HUDHelpTextRenderer = NULL;
|
|
return ;
|
|
}
|
|
|
|
static void Weapon_Init( void )
|
|
{
|
|
WeaponBoxRenderer = new Render2DClass();
|
|
WeaponBoxRenderer->Set_Texture( HUD_MAIN_TEXTURE );
|
|
WeaponBoxRenderer->Set_Coordinate_Range( Render2DClass::Get_Screen_Resolution() );
|
|
RectClass box_uv( WEAPON_BOX_UV_UL, WEAPON_BOX_UV_LR );
|
|
RectClass draw_box = box_uv;
|
|
box_uv.Scale( Vector2( 1.0f/256.0f, 1.0f/256.0f ) );
|
|
draw_box += Render2DClass::Get_Screen_Resolution().Lower_Right() - Vector2( WEAPON_OFFSET ) - draw_box.Upper_Left();
|
|
WeaponBoxRenderer->Add_Quad( draw_box, box_uv );
|
|
WeaponBase = draw_box.Upper_Left();
|
|
|
|
WeaponImageRenderer = new Render2DClass();
|
|
WeaponImageRenderer->Set_Coordinate_Range( Render2DClass::Get_Screen_Resolution() );
|
|
|
|
FontCharsClass *chars_font = StyleMgrClass::Peek_Font( StyleMgrClass::FONT_INGAME_TXT );
|
|
WeaponNameRenderer = new Render2DSentenceClass();
|
|
WeaponNameRenderer->Set_Font( chars_font );
|
|
// WeaponNameRenderer->Set_Coordinate_Range( Render2DClass::Get_Screen_Resolution() );
|
|
|
|
Font3DInstanceClass * font = WW3DAssetManager::Get_Instance()->Get_Font3DInstance( LARGE_FONT );
|
|
SET_REF_OWNER( font );
|
|
WeaponClipCountRenderer = new Render2DTextClass( font );
|
|
WeaponClipCountRenderer->Set_Coordinate_Range( Render2DClass::Get_Screen_Resolution() );
|
|
font->Release_Ref();
|
|
|
|
font = WW3DAssetManager::Get_Instance()->Get_Font3DInstance( SMALL_FONT );
|
|
SET_REF_OWNER( font );
|
|
WeaponTotalCountRenderer = new Render2DTextClass( font );
|
|
WeaponTotalCountRenderer->Set_Coordinate_Range( Render2DClass::Get_Screen_Resolution() );
|
|
font->Release_Ref();
|
|
|
|
_LastHUDWeapon = NULL;
|
|
_LastVehicleSeat = -1;
|
|
|
|
|
|
}
|
|
|
|
static void Weapon_Shutdown( void )
|
|
{
|
|
delete WeaponBoxRenderer;
|
|
WeaponBoxRenderer = NULL;
|
|
|
|
delete WeaponImageRenderer;
|
|
WeaponImageRenderer = NULL;
|
|
|
|
delete WeaponNameRenderer;
|
|
WeaponNameRenderer = NULL;
|
|
|
|
delete WeaponClipCountRenderer;
|
|
WeaponClipCountRenderer = NULL;
|
|
|
|
delete WeaponTotalCountRenderer;
|
|
WeaponTotalCountRenderer = NULL;
|
|
}
|
|
|
|
#define CLIP_ROUNDS_OFFSET 15,27
|
|
#define TOTAL_ROUNDS_OFFSET 65,34
|
|
#define WEAPON_NAME_OFFSET -10, 95
|
|
|
|
float LastClipCount = 0;
|
|
float CenterClipCountTimer = 0;
|
|
const float CENTER_CLIP_COUNT_TIME = 2.0f;
|
|
|
|
enum {
|
|
SEAT_DRIVER = 0,
|
|
SEAT_GUNNER,
|
|
SEAT_PASENGER,
|
|
};
|
|
|
|
const char * _Seat_Textures[3] = {
|
|
"hud_driverseat.tga", // SEAT_DRIVER = 0,
|
|
"hud_gunseat.tga", // SEAT_GUNNER,
|
|
"hud_passseat.tga", // SEAT_PASENGER,
|
|
};
|
|
|
|
static void Weapon_Reset( void )
|
|
{
|
|
_LastHUDWeapon = (WeaponClass *)0xFFFFFFFF; // force weapon to re-draw next
|
|
_LastVehicleSeat = -1; // force vehicle seat to re-draw next
|
|
}
|
|
|
|
static void Weapon_Update( void )
|
|
{
|
|
WeaponClass * weapon = NULL;
|
|
if ( COMBAT_STAR ) {
|
|
weapon = COMBAT_STAR->Get_Weapon();
|
|
|
|
if ( COMBAT_STAR->Get_Vehicle() ) {
|
|
weapon = COMBAT_STAR->Get_Vehicle()->Get_Weapon();
|
|
}
|
|
|
|
}
|
|
|
|
WeaponClipCountRenderer->Reset();
|
|
WeaponTotalCountRenderer->Reset();
|
|
|
|
if ( weapon != NULL ) {
|
|
// StringClass text;
|
|
// text.Format( "%03d", weapon->Get_Clip_Rounds() );
|
|
WCHAR tmp_text[5];
|
|
if ( weapon->Get_Clip_Rounds() == -1 ) {
|
|
//text.Format( "999", weapon->Get_Total_Rounds() );
|
|
tmp_text[0]='9';
|
|
tmp_text[1]='9';
|
|
tmp_text[2]='9';
|
|
tmp_text[3]=0;
|
|
} else {
|
|
Generate_WChar_Text_From_Number(tmp_text,3,3,weapon->Get_Clip_Rounds());
|
|
}
|
|
|
|
WeaponClipCountRenderer->Set_Location( WeaponBase + Vector2( CLIP_ROUNDS_OFFSET ) );
|
|
WeaponClipCountRenderer->Draw_Text( tmp_text );
|
|
|
|
if ( LastClipCount != weapon->Get_Clip_Rounds() ) {
|
|
LastClipCount = weapon->Get_Clip_Rounds();
|
|
CenterClipCountTimer = CENTER_CLIP_COUNT_TIME;
|
|
}
|
|
|
|
if ( CenterClipCountTimer > 0 ) {
|
|
// Also draw the above at the center
|
|
|
|
Vector2 center_clip_count_offset = Render2DClass::Get_Screen_Resolution().Center();
|
|
center_clip_count_offset.X *= 1.5;
|
|
|
|
float fade = WWMath::Clamp( CenterClipCountTimer, 0, 1 );
|
|
|
|
RectClass uv;
|
|
uv.Set( BULLET_ICON_UV_UL, BULLET_ICON_UV_LR );
|
|
RectClass draw = uv;
|
|
uv.Scale( INFO_UV_SCALE );
|
|
draw += center_clip_count_offset + BULLET_ICON_OFFSET - draw.Upper_Left();
|
|
InfoRenderer->Add_Quad( draw, uv, COLOR( fade ) );
|
|
|
|
WeaponClipCountRenderer->Set_Location( draw.Upper_Right() + Vector2( 4, 15 ) );
|
|
WeaponClipCountRenderer->Draw_Text( tmp_text, COLOR( fade ) );
|
|
|
|
CenterClipCountTimer -= TimeManager::Get_Frame_Seconds();
|
|
}
|
|
|
|
|
|
if ( weapon->Get_Total_Rounds() == -1 ) {
|
|
//text.Format( "999", weapon->Get_Total_Rounds() );
|
|
tmp_text[0]='9';
|
|
tmp_text[1]='9';
|
|
tmp_text[2]='9';
|
|
tmp_text[3]=0;
|
|
} else {
|
|
// text.Format( "%03d", weapon->Get_Total_Rounds() - weapon->Get_Clip_Rounds() );
|
|
Generate_WChar_Text_From_Number(tmp_text,3,3,weapon->Get_Total_Rounds() - weapon->Get_Clip_Rounds());
|
|
}
|
|
WeaponTotalCountRenderer->Set_Location( WeaponBase + Vector2( TOTAL_ROUNDS_OFFSET ) );
|
|
WeaponTotalCountRenderer->Draw_Text( tmp_text );
|
|
}
|
|
|
|
// If in vehicle, don't draw the weapon icon and name,
|
|
// draw a seat icon and the vehicle name
|
|
if ( COMBAT_STAR->Get_Vehicle() ) {
|
|
int seat = SEAT_PASENGER;
|
|
|
|
if ( COMBAT_STAR->Get_Vehicle()->Get_Driver() == COMBAT_STAR ) {
|
|
seat = SEAT_DRIVER;
|
|
} else if ( COMBAT_STAR->Get_Vehicle()->Get_Gunner() == COMBAT_STAR ) {
|
|
seat = SEAT_GUNNER;
|
|
}
|
|
|
|
if ( _LastVehicleSeat != seat ) {
|
|
_LastVehicleSeat = seat;
|
|
_LastHUDWeapon = (WeaponClass *)0xFFFFFFFF; // force weapon to re-draw next
|
|
|
|
WeaponImageRenderer->Reset();
|
|
StringClass filename = _Seat_Textures[seat];
|
|
WeaponImageRenderer->Set_Texture( filename );
|
|
Vector2 offset( 16, 34 );
|
|
RectClass icon_box( 0,0,64,64 );
|
|
icon_box += WeaponBase + offset - icon_box.Upper_Left();
|
|
WeaponImageRenderer->Add_Quad( icon_box );
|
|
|
|
// Draw Name Backdrop
|
|
WeaponNameRenderer->Reset();
|
|
WideStringClass name(COMBAT_STAR->Get_Vehicle()->Get_Vehicle_Name(),true);
|
|
WeaponNameRenderer->Build_Sentence( name );
|
|
Vector2 text_size = WeaponNameRenderer->Get_Text_Extents( name );
|
|
WeaponNameRenderer->Set_Location( Render2DClass::Get_Screen_Resolution().Lower_Right() - text_size );
|
|
WeaponNameRenderer->Draw_Sentence();
|
|
|
|
}
|
|
|
|
} else if ( _LastHUDWeapon != weapon ) { // Update the weapon icon
|
|
WWPROFILE( "Weapon Change" );
|
|
_LastHUDWeapon = weapon;
|
|
_LastVehicleSeat = -1; // force vehicle seat to re-draw next
|
|
|
|
|
|
WeaponImageRenderer->Reset();
|
|
WeaponNameRenderer->Reset();
|
|
|
|
if ( weapon != NULL ) {
|
|
|
|
StringClass filename( HUD_WEAPONS_TEXTURE, true );
|
|
RectClass uv( 0,64,128,128 );
|
|
Vector2 offset( -24, 38 );
|
|
|
|
const WeaponDefinitionClass * def = weapon->Get_Definition();
|
|
if ( !def->IconTextureName.Is_Empty() ) {
|
|
Strip_Path_From_Filename( filename, def->IconTextureName );
|
|
uv = def->IconTextureUV;
|
|
offset = def->IconOffset;
|
|
|
|
#if 0 // Used to find offsets
|
|
static Vector2 tweak_add(0,0);
|
|
Vector2 add(0,0);
|
|
add.X += Input::Get_Amount( INPUT_FUNCTION_MOVE_LEFT ) - Input::Get_Amount( INPUT_FUNCTION_MOVE_RIGHT );
|
|
add.Y += Input::Get_Amount( INPUT_FUNCTION_MOVE_FORWARD ) - Input::Get_Amount( INPUT_FUNCTION_MOVE_BACKWARD );
|
|
tweak_add -= add;
|
|
offset += tweak_add;
|
|
_LastHUDWeapon = NULL;
|
|
if ( add.Length() != 0 ) {
|
|
Debug_Say(( "%s offset %f %f\n", def->Get_Name(), offset.X, offset.Y ));
|
|
}
|
|
#endif
|
|
}
|
|
|
|
RectClass icon_box = uv;
|
|
icon_box += WeaponBase + offset - icon_box.Upper_Left();
|
|
|
|
{
|
|
StringClass new_name(true);
|
|
Strip_Path_From_Filename( new_name, filename );
|
|
WeaponImageRenderer->Set_Texture( new_name );
|
|
}
|
|
|
|
// SurfaceClass::SurfaceDescription surface_desc;
|
|
// WeaponImageRenderer->Peek_Texture()->Get_Level_Description( surface_desc );
|
|
// float size = surface_desc.Width; // Assume square
|
|
float size = WeaponImageRenderer->Peek_Texture()->Get_Width(); // Assume square
|
|
if ( size > 0 ) {
|
|
uv.Scale( Vector2( 1/size, 1/size ) );
|
|
}
|
|
|
|
int color = 0xFF00FF00; // green
|
|
WeaponImageRenderer->Add_Quad( icon_box, uv, color );
|
|
|
|
// Draw Name Backdrop
|
|
|
|
// Right justify Name
|
|
|
|
WideStringClass name(0,true); // = L"Rocket Launcher";
|
|
name = TranslateDBClass::Get_String( def->IconNameID );
|
|
WeaponNameRenderer->Build_Sentence( name );
|
|
Vector2 text_size = WeaponNameRenderer->Get_Text_Extents( name ) + Vector2( 1, 0 );
|
|
WeaponNameRenderer->Set_Location( Render2DClass::Get_Screen_Resolution().Lower_Right() - text_size );
|
|
WeaponNameRenderer->Draw_Sentence();
|
|
}
|
|
}
|
|
}
|
|
|
|
static void Weapon_Render( void )
|
|
{
|
|
WeaponBoxRenderer->Render();
|
|
WeaponImageRenderer->Render();
|
|
WeaponNameRenderer->Render();
|
|
WeaponClipCountRenderer->Render();
|
|
WeaponTotalCountRenderer->Render();
|
|
}
|
|
|
|
|
|
/*
|
|
** Weapon Chart Display
|
|
*/
|
|
Render2DClass * WeaponChartBoxRenderer;
|
|
static DynamicVectorClass<Render2DClass *> WeaponChartIcons;
|
|
Render2DSentenceClass * WeaponChartKeynameRenderer;
|
|
float WeaponChartTimer;
|
|
#define WEAPON_CHART_TIME 3.0f
|
|
|
|
static void Weapon_Chart_Init( void )
|
|
{
|
|
WeaponChartBoxRenderer = new Render2DClass();
|
|
WeaponChartBoxRenderer->Enable_Texturing( false );
|
|
WeaponChartBoxRenderer->Set_Coordinate_Range( Render2DClass::Get_Screen_Resolution() );
|
|
|
|
FontCharsClass *chars_font = StyleMgrClass::Peek_Font( StyleMgrClass::FONT_INGAME_TXT );
|
|
WeaponChartKeynameRenderer = new Render2DSentenceClass();
|
|
WeaponChartKeynameRenderer->Set_Font( chars_font );
|
|
}
|
|
|
|
static void Weapon_Chart_Shutdown( void )
|
|
{
|
|
delete WeaponChartBoxRenderer;
|
|
WeaponChartBoxRenderer = NULL;
|
|
|
|
for ( int i = 0; i < WeaponChartIcons.Count(); i++) {
|
|
delete WeaponChartIcons[i];
|
|
WeaponChartIcons[i] = NULL;
|
|
}
|
|
WeaponChartIcons.Delete_All();
|
|
|
|
delete WeaponChartKeynameRenderer;
|
|
WeaponChartKeynameRenderer = NULL;
|
|
}
|
|
|
|
Vector2 WeaponChartBase( 0.11f, 0.05f );
|
|
Vector2 WeaponChartSpacing( 0.075f, 0.05f );
|
|
float WeaponChartIconScale = 0.45f / 640.0f;
|
|
|
|
static void Clear_Weapon_Chart_Icons( void )
|
|
{
|
|
if ( WeaponChartIcons.Count != 0 ) {
|
|
int i;
|
|
for ( i = 0; i < WeaponChartIcons.Count(); i++) {
|
|
delete WeaponChartIcons[i];
|
|
WeaponChartIcons[i] = NULL;
|
|
}
|
|
WeaponChartIcons.Delete_All();
|
|
WeaponChartKeynameRenderer->Reset();
|
|
}
|
|
}
|
|
|
|
static void Build_Weapon_Chart_Icons( void )
|
|
{
|
|
WeaponBagClass * weapon_bag = COMBAT_STAR->Get_Weapon_Bag();
|
|
|
|
Clear_Weapon_Chart_Icons();
|
|
|
|
float screen_scale = Render2DClass::Get_Screen_Resolution().Width();
|
|
Vector2 pos = WeaponChartBase * screen_scale;
|
|
|
|
// For each column...
|
|
for ( int column = 1; column <= 10; column++ ) {
|
|
|
|
// Add column header
|
|
int key = Input::Get_Primary_Key_For_Function(INPUT_FUNCTION_SELECT_WEAPON_0 + (column%10) );
|
|
WideStringClass name(0,true);
|
|
Input::Get_Translated_Key_Name( key, name );
|
|
WeaponChartKeynameRenderer->Build_Sentence( name );
|
|
Vector2 text_size = WeaponChartKeynameRenderer->Get_Text_Extents( name );
|
|
Vector2 text_offset = pos - text_size/2 - Vector2( 0, WeaponChartSpacing.Y * screen_scale * 0.75f );
|
|
text_offset.X = (int)text_offset.X;
|
|
text_offset.Y = (int)text_offset.Y;
|
|
WeaponChartKeynameRenderer->Set_Location( text_offset );
|
|
WeaponChartKeynameRenderer->Draw_Sentence();
|
|
|
|
// Draw weapons in that column
|
|
for ( int i = 0; i < weapon_bag->Get_Count(); i++ ) {
|
|
WeaponClass * weapon = weapon_bag->Peek_Weapon( i );
|
|
if ( weapon != NULL ) {
|
|
|
|
if ( (int)weapon->Get_Key_Number() != (column%10) ) {
|
|
continue;
|
|
}
|
|
|
|
StringClass filename( HUD_WEAPONS_TEXTURE, true );
|
|
RectClass uv( 0,64,128,128 );
|
|
Vector2 offset( -40, 40 );
|
|
|
|
const WeaponDefinitionClass * def = weapon->Get_Definition();
|
|
if ( !def->IconTextureName.Is_Empty() ) {
|
|
Strip_Path_From_Filename( filename, def->IconTextureName );
|
|
uv = def->IconTextureUV;
|
|
offset = def->IconOffset;
|
|
}
|
|
|
|
RectClass icon_box = uv;
|
|
// icon_box += pos - icon_box.Upper_Left();
|
|
// icon_box += offset - icon_box.Upper_Left() + pos;
|
|
icon_box += pos - icon_box.Center();
|
|
icon_box.Scale_Relative_Center( WeaponChartIconScale * screen_scale );
|
|
pos.Y += WeaponChartSpacing.Y * screen_scale;
|
|
|
|
// Draw Icon
|
|
Render2DClass * renderer = new Render2DClass();
|
|
WeaponChartIcons.Add( renderer );
|
|
renderer->Set_Coordinate_Range( Render2DClass::Get_Screen_Resolution() );
|
|
StringClass new_name(true);
|
|
Strip_Path_From_Filename( new_name, filename );
|
|
renderer->Set_Texture( new_name );
|
|
if ( renderer->Peek_Texture() != NULL ) {
|
|
// SurfaceClass::SurfaceDescription surface_desc;
|
|
// renderer->Peek_Texture()->Get_Level_Description( surface_desc );
|
|
// float size = surface_desc.Width; // Assume square
|
|
float size = renderer->Peek_Texture()->Get_Width(); // Assume square
|
|
if ( size > 0 ) {
|
|
uv.Scale( Vector2( 1/size, 1/size ) );
|
|
}
|
|
}
|
|
renderer->Add_Quad( icon_box, uv );
|
|
}
|
|
}
|
|
|
|
// Goto next column
|
|
pos.Y = WeaponChartBase.Y * screen_scale;
|
|
pos.X += WeaponChartSpacing.X * screen_scale;
|
|
}
|
|
|
|
}
|
|
|
|
bool ForceChartRebuild = false;
|
|
|
|
void HUDClass::Force_Weapon_Chart_Update( void )
|
|
{
|
|
ForceChartRebuild = true;
|
|
}
|
|
|
|
void HUDClass::Force_Weapon_Chart_Display( void )
|
|
{
|
|
WeaponChartTimer = WEAPON_CHART_TIME;
|
|
}
|
|
|
|
static void Weapon_Chart_Update( void )
|
|
{
|
|
if ( COMBAT_STAR == NULL || COMBAT_STAR->Get_Weapon_Bag() == NULL || COMBAT_STAR->Get_Vehicle() != NULL ) {
|
|
Clear_Weapon_Chart_Icons();
|
|
return;
|
|
}
|
|
|
|
int i;
|
|
WeaponBagClass * weapon_bag = COMBAT_STAR->Get_Weapon_Bag();
|
|
if ( weapon_bag->HUD_Is_Changed() ) {
|
|
weapon_bag->HUD_Reset_Changed();
|
|
WeaponChartTimer = WEAPON_CHART_TIME;
|
|
}
|
|
|
|
WeaponChartTimer -= TimeManager::Get_Frame_Seconds();
|
|
|
|
if ( WeaponChartTimer <= 0 ) {
|
|
return;
|
|
}
|
|
|
|
// Rebuild the icons if necessary
|
|
// subtract 1 because the first is always null
|
|
if ( ForceChartRebuild || (weapon_bag->Get_Count()-1 != WeaponChartIcons.Count()) ) {
|
|
ForceChartRebuild = false;
|
|
Debug_Say(( "Build icons\n" ));
|
|
Build_Weapon_Chart_Icons();
|
|
}
|
|
|
|
float alpha = WWMath::Clamp( WeaponChartTimer, 0, 1 );
|
|
|
|
WeaponChartBoxRenderer->Reset();
|
|
|
|
// For each column...
|
|
int index = 0;
|
|
for ( int column = 1; column <= 10; column++ ) {
|
|
|
|
// Update intensities in that column
|
|
for ( i = 0; i < weapon_bag->Get_Count(); i++ ) {
|
|
WeaponClass * weapon = weapon_bag->Peek_Weapon( i );
|
|
if ( weapon != NULL ) {
|
|
|
|
if ( (int)weapon->Get_Key_Number() != (column%10) ) {
|
|
continue;
|
|
}
|
|
|
|
long color = 0x000FF00; // Dim
|
|
if ( weapon_bag->Get_Index() == i ) {
|
|
color = 0x0000FF00; // Bright
|
|
}
|
|
|
|
// Draw yellow if empty or reloading
|
|
// if ( weapon->Is_Reloading() || weapon->Is_Switching() || weapon->Get_Total_Rounds() == 0 ) {
|
|
// if ( weapon->Is_Switching() || weapon->Get_Total_Rounds() == 0 ) {
|
|
if ( weapon->Get_Total_Rounds() == 0 ) {
|
|
color = 0x00FFFF00; // Dim yellow
|
|
if ( weapon_bag->Get_Index() == i ) {
|
|
color = 0x00FFFF00; // Bright yellow
|
|
}
|
|
}
|
|
|
|
#if 01
|
|
if ( weapon_bag->Get_Index() == i ) {
|
|
color = COLOR( alpha, color );
|
|
} else {
|
|
color = COLOR( alpha * 0.5f, color );
|
|
}
|
|
#endif
|
|
|
|
|
|
WeaponChartIcons[index]->Force_Color( color );
|
|
index++;
|
|
}
|
|
}
|
|
}
|
|
|
|
WeaponChartKeynameRenderer->Force_Alpha( alpha );
|
|
}
|
|
|
|
static void Weapon_Chart_Render( void )
|
|
{
|
|
if ( WeaponChartTimer <= 0 ) {
|
|
return;
|
|
}
|
|
|
|
WeaponChartBoxRenderer->Render();
|
|
for ( int i = 0; i < WeaponChartIcons.Count(); i++) {
|
|
WeaponChartIcons[i]->Render();
|
|
}
|
|
WeaponChartKeynameRenderer->Render();
|
|
}
|
|
|
|
/*
|
|
** Damage Display
|
|
*/
|
|
Render2DClass * DamageRenderer;
|
|
|
|
const int NUM_DAMAGE_INDICATORS = 8;
|
|
float DamageIndicatorIntensity[ NUM_DAMAGE_INDICATORS ];
|
|
bool DamageIndicatorIntensityChanging;
|
|
bool DamageIndicatorOrientation;
|
|
|
|
static void Damage_Reset( void )
|
|
{
|
|
for ( int i = 0; i < NUM_DAMAGE_INDICATORS; i++ ) {
|
|
DamageIndicatorIntensity[ i ] = 0;
|
|
}
|
|
DamageIndicatorIntensityChanging = true;
|
|
CombatManager::Clear_Star_Damage_Direction();
|
|
}
|
|
|
|
static void Damage_Init( void )
|
|
{
|
|
DamageRenderer = new Render2DClass();
|
|
DamageRenderer->Set_Texture( HUD_MAIN_TEXTURE );
|
|
DamageRenderer->Set_Coordinate_Range( Render2DClass::Get_Screen_Resolution() );
|
|
DamageRenderer->Enable_Additive( true );
|
|
|
|
Damage_Reset();
|
|
}
|
|
|
|
static void Damage_Shutdown( void )
|
|
{
|
|
delete DamageRenderer;
|
|
DamageRenderer = NULL;
|
|
}
|
|
|
|
static void Damage_Add_Indicator( int index, float start_x, float start_y, float end_x, float end_y )
|
|
{
|
|
Vector2 vert[4];
|
|
vert[0] = Vector2( start_x, start_y );
|
|
vert[1] = Vector2( start_x, end_y );
|
|
vert[2] = Vector2( end_x, start_y );
|
|
vert[3] = Vector2( end_x, end_y );
|
|
|
|
if ( !CombatManager::Is_First_Person() ) {
|
|
for ( int i = 0; i < 4; i++ ) {
|
|
vert[i].X *= WWMath::Fabs(1 + vert[i].Y); // Skew
|
|
vert[i].Y /= 2; // Squash vertical
|
|
vert[i].Y += 0.25f; // Lower
|
|
}
|
|
}
|
|
|
|
for ( int i = 0; i < 4; i++ ) {
|
|
// Numbers are -0.5 to 0.5, switch them to pixels, to match the info_renderer mode
|
|
vert[i].X = (vert[i].X + 0.5f) * Render2DClass::Get_Screen_Resolution().Width();
|
|
vert[i].Y = (vert[i].Y + 0.5f) * Render2DClass::Get_Screen_Resolution().Height();
|
|
}
|
|
|
|
RectClass uv( DAMAGE_1_UV_UL, DAMAGE_1_UV_LR );
|
|
if ( index & 1 ) {
|
|
uv = RectClass( DAMAGE_2_UV_UL, DAMAGE_2_UV_LR );
|
|
}
|
|
uv.Scale( INFO_UV_SCALE );
|
|
|
|
unsigned long color_bits = (int)(DamageIndicatorIntensity[index] * 255) & 0x000000FF;
|
|
unsigned long color = color_bits | color_bits<<8 | color_bits<<16;
|
|
|
|
switch (index) {
|
|
case 3:
|
|
case 4: DamageRenderer->Add_Quad( vert[1], vert[3], vert[0], vert[2], uv, color );
|
|
break;
|
|
case 5:
|
|
case 6: DamageRenderer->Add_Quad( vert[0], vert[1], vert[2], vert[3], uv, color );
|
|
break;
|
|
case 7:
|
|
case 0: DamageRenderer->Add_Quad( vert[2], vert[0], vert[3], vert[1], uv, color );
|
|
break;
|
|
case 1:
|
|
case 2: DamageRenderer->Add_Quad( vert[3], vert[2], vert[1], vert[0], uv, color );
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
static void Damage_Update( void )
|
|
{
|
|
DamageRenderer->Reset();
|
|
|
|
if (Input::Are_Damage_Indicators_Enabled () == false) {
|
|
return ;
|
|
}
|
|
|
|
int new_damage = CombatManager::Get_Star_Damage_Direction();
|
|
//new_damage = 0xFF;
|
|
|
|
if ( new_damage != 0 ) {
|
|
DamageIndicatorIntensityChanging = true;
|
|
}
|
|
|
|
if ( !DamageIndicatorIntensityChanging &&
|
|
DamageIndicatorOrientation == CombatManager::Is_First_Person() ) {
|
|
return;
|
|
}
|
|
|
|
// DamageRenderer->Reset();
|
|
|
|
DamageIndicatorOrientation = CombatManager::Is_First_Person();
|
|
DamageIndicatorIntensityChanging = false;
|
|
|
|
// Update the intensities
|
|
CombatManager::Clear_Star_Damage_Direction();
|
|
for ( int i = 0; i < NUM_DAMAGE_INDICATORS; i++ ) {
|
|
if ( new_damage & (1<<i) ) { // Apply new damage
|
|
DamageIndicatorIntensity[ i ] = 1;
|
|
DamageIndicatorIntensityChanging = true;
|
|
} else {
|
|
if ( DamageIndicatorIntensity[ i ] > 0 ) {
|
|
DamageIndicatorIntensity[ i ] -= TimeManager::Get_Frame_Seconds(); // and fade it away
|
|
DamageIndicatorIntensity[ i ] = WWMath::Clamp( DamageIndicatorIntensity[ i ], 0, 1 );
|
|
DamageIndicatorIntensityChanging = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Redraw the indicators
|
|
|
|
#if 0
|
|
const float HORIZ_WIDTH = 58.0f/640.0f;
|
|
const float HORIZ_HEIGHT = 20.0f/480.0f;
|
|
const float VERT_WIDTH = 20.0f/640.0f;
|
|
const float VERT_HEIGHT = 58.0f/480.0f;
|
|
const float OFFSET_X = 220.0f/640.0f;
|
|
const float OFFSET_Y = 190.0f/480.0f;
|
|
|
|
const float DIAG_WIDTH = 46.0f/640.0f;
|
|
const float DIAG_HEIGHT = 46.0f/480.0f;
|
|
const float DIAG_OFFSET_X = 160.0f/640.0f;
|
|
const float DIAG_OFFSET_Y = 130.0f/480.0f;
|
|
#else
|
|
float HORIZ_WIDTH = HORIZ_DAMAGE_SIZE.U/640.0f;
|
|
float HORIZ_HEIGHT = HORIZ_DAMAGE_SIZE.V/480.0f;
|
|
float VERT_WIDTH = VERT_DAMAGE_SIZE.U/640.0f;
|
|
float VERT_HEIGHT = VERT_DAMAGE_SIZE.V/480.0f;
|
|
float OFFSET_X = HV_DAMAGE_OFFSET.U/640.0f;
|
|
float OFFSET_Y = HV_DAMAGE_OFFSET.V/480.0f;
|
|
|
|
float DIAG_WIDTH = DIAG_DAMAGE_SIZE.U/640.0f;
|
|
float DIAG_HEIGHT = DIAG_DAMAGE_SIZE.V/480.0f;
|
|
float DIAG_OFFSET_X = DIAG_DAMAGE_OFFSET.U/640.0f;
|
|
float DIAG_OFFSET_Y = DIAG_DAMAGE_OFFSET.V/480.0f;
|
|
#endif
|
|
|
|
Damage_Add_Indicator( 0, -HORIZ_WIDTH/2, -OFFSET_Y-HORIZ_HEIGHT/2, HORIZ_WIDTH/2, -OFFSET_Y+HORIZ_HEIGHT/2 );
|
|
Damage_Add_Indicator( 2, OFFSET_X-VERT_WIDTH/2, -VERT_HEIGHT/2, OFFSET_X+VERT_WIDTH/2, VERT_HEIGHT/2 );
|
|
Damage_Add_Indicator( 4, -HORIZ_WIDTH/2, OFFSET_Y-HORIZ_HEIGHT/2, HORIZ_WIDTH/2, OFFSET_Y+HORIZ_HEIGHT/2 );
|
|
Damage_Add_Indicator( 6, -OFFSET_X-VERT_WIDTH/2, -VERT_HEIGHT/2, -OFFSET_X+VERT_WIDTH/2, VERT_HEIGHT/2 );
|
|
Damage_Add_Indicator( 1, DIAG_OFFSET_X-DIAG_WIDTH/2, -DIAG_OFFSET_Y-DIAG_HEIGHT/2, DIAG_OFFSET_X+DIAG_WIDTH/2, -DIAG_OFFSET_Y+DIAG_HEIGHT/2 );
|
|
Damage_Add_Indicator( 3, DIAG_OFFSET_X-DIAG_WIDTH/2, DIAG_OFFSET_Y-DIAG_HEIGHT/2, DIAG_OFFSET_X+DIAG_WIDTH/2, DIAG_OFFSET_Y+DIAG_HEIGHT/2 );
|
|
Damage_Add_Indicator( 5, -DIAG_OFFSET_X-DIAG_WIDTH/2, DIAG_OFFSET_Y-DIAG_HEIGHT/2, -DIAG_OFFSET_X+DIAG_WIDTH/2, DIAG_OFFSET_Y+DIAG_HEIGHT/2 );
|
|
Damage_Add_Indicator( 7, -DIAG_OFFSET_X-DIAG_WIDTH/2, -DIAG_OFFSET_Y-DIAG_HEIGHT/2, -DIAG_OFFSET_X+DIAG_WIDTH/2, -DIAG_OFFSET_Y+DIAG_HEIGHT/2 );
|
|
}
|
|
|
|
void HUDClass::Damage_Render( void )
|
|
{
|
|
DamageRenderer->Render();
|
|
}
|
|
|
|
/*
|
|
** Target Display
|
|
*/
|
|
Render2DClass * TargetRenderer;
|
|
Render2DClass * TargetBoxRenderer;
|
|
Render2DSentenceClass * TargetNameRenderer;
|
|
Render2DSentenceClass * InfoDebugRenderer;
|
|
WideStringClass TargetNameString; // Cache the current target name string so that we know when the string changes
|
|
Vector2 TargetNameLocation; // Cache the name location as well
|
|
|
|
static void Target_Init( void )
|
|
{
|
|
TargetRenderer = new Render2DClass();
|
|
TargetRenderer->Set_Texture( HUD_MAIN_TEXTURE );
|
|
TargetRenderer->Set_Coordinate_Range( Render2DClass::Get_Screen_Resolution() );
|
|
|
|
TargetBoxRenderer = new Render2DClass();
|
|
TargetBoxRenderer->Enable_Texturing( false );
|
|
TargetBoxRenderer->Set_Coordinate_Range( Render2DClass::Get_Screen_Resolution() );
|
|
|
|
FontCharsClass *chars_font = StyleMgrClass::Peek_Font( StyleMgrClass::FONT_INGAME_TXT );
|
|
TargetNameRenderer = new Render2DSentenceClass();
|
|
TargetNameRenderer->Set_Font( chars_font );
|
|
InfoDebugRenderer = new Render2DSentenceClass();
|
|
InfoDebugRenderer->Set_Font( chars_font );
|
|
// TargetNameRenderer->Set_Coordinate_Range( Render2DClass::Get_Screen_Resolution() );
|
|
}
|
|
|
|
|
|
static void Target_Shutdown( void )
|
|
{
|
|
delete TargetRenderer;
|
|
TargetRenderer = NULL;
|
|
|
|
delete TargetBoxRenderer;
|
|
TargetBoxRenderer = NULL;
|
|
|
|
delete TargetNameRenderer;
|
|
TargetNameRenderer = NULL;
|
|
TargetNameString="";
|
|
|
|
delete InfoDebugRenderer;
|
|
InfoDebugRenderer = NULL;
|
|
|
|
}
|
|
|
|
bool InfoDebug = false;
|
|
|
|
static RectClass Get_Target_Box( PhysicalGameObj * obj );
|
|
static void Target_Box_Edge( const Vector2 & a, const Vector2 & b, unsigned int color );
|
|
|
|
static void Target_Update( void )
|
|
{
|
|
TargetRenderer->Reset();
|
|
TargetBoxRenderer->Reset();
|
|
// TargetNameRenderer->Reset();
|
|
InfoDebugRenderer->Reset();
|
|
|
|
HUDInfo::Update_Info_Object();
|
|
|
|
static float box_zoom_size = 0;
|
|
|
|
DamageableGameObj * d_obj = HUDInfo::Get_Info_Object();
|
|
if ( d_obj != NULL ) {
|
|
|
|
PhysicalGameObj * p_obj = d_obj->As_PhysicalGameObj();
|
|
BuildingGameObj * building = d_obj->As_BuildingGameObj();
|
|
|
|
DamageableGameObj * obj = d_obj;
|
|
|
|
if ( obj && COMBAT_STAR ) {
|
|
|
|
box_zoom_size += TimeManager::Get_Frame_Seconds() * 4;
|
|
box_zoom_size = WWMath::Clamp( box_zoom_size, 0, 1 );
|
|
|
|
int color = HUDGlobalSettingsDef::Get_Instance()->Get_No_Relation_Color().Convert_To_ARGB();
|
|
if ( p_obj != NULL ) {
|
|
if ( COMBAT_STAR->Is_Teammate(p_obj) ) {
|
|
color = HUDGlobalSettingsDef::Get_Instance()->Get_Friendly_Color().Convert_To_ARGB();
|
|
} else if ( COMBAT_STAR->Is_Enemy(p_obj) ) {
|
|
color = HUDGlobalSettingsDef::Get_Instance()->Get_Enemy_Color().Convert_To_ARGB();
|
|
}
|
|
}
|
|
|
|
if ( building != NULL ) {
|
|
// if ( building->Is_GDI() ) {
|
|
if ( COMBAT_STAR->Is_Teammate(building) ) {
|
|
color = HUDGlobalSettingsDef::Get_Instance()->Get_Friendly_Color().Convert_To_ARGB();
|
|
// } else if ( building->Is_Nod() ) {
|
|
} else if ( COMBAT_STAR->Is_Enemy(building) ) {
|
|
color = HUDGlobalSettingsDef::Get_Instance()->Get_Enemy_Color().Convert_To_ARGB();
|
|
}
|
|
}
|
|
|
|
RectClass box = Render2DClass::Get_Screen_Resolution();
|
|
|
|
if ( obj->As_PhysicalGameObj() ) {
|
|
box = Get_Target_Box( obj->As_PhysicalGameObj() );
|
|
} else {
|
|
// Build a box for the buildings
|
|
box.Scale_Relative_Center( 0.3f );
|
|
// center on cursor reticle
|
|
Vector2 new_center = (COMBAT_CAMERA->Get_Camera_Target_2D_Offset() * 0.5f );
|
|
new_center.Y *= -1.0f;
|
|
new_center += Vector2( 0.5f, 0.5f );
|
|
new_center.X *= Render2DClass::Get_Screen_Resolution().Right;
|
|
new_center.Y *= Render2DClass::Get_Screen_Resolution().Bottom;
|
|
box += new_center - box.Center();
|
|
}
|
|
|
|
// Scale the box to let it zoom in
|
|
if ( box_zoom_size < 1 ) {
|
|
box.Scale_Relative_Center( 1 + ((1-box_zoom_size) * 0.3f) );
|
|
}
|
|
box.Snap_To_Units( Vector2( 1, 1 ) );
|
|
|
|
// Clamp box to fit on screen;
|
|
RectClass res = Render2DClass::Get_Screen_Resolution();
|
|
if ( box.Top < 0 ) {
|
|
box.Top = 0;
|
|
}
|
|
if ( box.Left < 0 ) {
|
|
box.Left = 0;
|
|
}
|
|
if ( box.Right > res.Right-1 ) {
|
|
box.Right = res.Right-1;
|
|
}
|
|
// Leave room for info at the bottom
|
|
if ( box.Bottom > res.Bottom - 26 ) {
|
|
box.Bottom = res.Bottom - 26;
|
|
}
|
|
|
|
Target_Box_Edge( box.Upper_Left(), box.Upper_Right(), color );
|
|
Target_Box_Edge( box.Upper_Left(), box.Lower_Left(), color );
|
|
Target_Box_Edge( box.Lower_Right(), box.Upper_Right(), color );
|
|
Target_Box_Edge( box.Lower_Right(), box.Lower_Left(), color );
|
|
|
|
RectClass uv( TARGET_HEALTH_R_UV_UL, TARGET_HEALTH_R_UV_LR );
|
|
RectClass draw = uv;
|
|
RectClass draw2;
|
|
bool draw_health = obj->Is_Health_Bar_Displayed();
|
|
if ( draw_health ) {
|
|
float health_percent = 0;
|
|
// float health = 0;
|
|
const DefenseObjectClass * def = obj->Get_Defense_Object();
|
|
if ( def ) {
|
|
// health = def->Get_Health();
|
|
// health_percent = WWMath::Clamp( def->Get_Health() / def->Get_Health_Max(), 0, 1 );
|
|
|
|
float health_max = def->Get_Health_Max();
|
|
float shield_max = def->Get_Shield_Strength_Max();
|
|
float max = health_max + shield_max;
|
|
float health = def->Get_Health();
|
|
float shield = def->Get_Shield_Strength();
|
|
// if ( health_max && ((health/health_max) < 0.25) ) {
|
|
// shield *= ((health/health_max) / 0.25f);
|
|
// }
|
|
// Display less shield as health drops
|
|
if ( health_max ) {
|
|
shield *= (health/health_max);
|
|
}
|
|
float total = health + shield;
|
|
if ( max != 0 ) {
|
|
health_percent = total / max;
|
|
health_percent = WWMath::Clamp( health_percent, 0, 1 );
|
|
}
|
|
}
|
|
int health_color = Get_Health_Color( health_percent );
|
|
|
|
// Draw Health
|
|
static float power_flash = 0;
|
|
power_flash += TimeManager::Get_Frame_Seconds();
|
|
power_flash = WWMath::Wrap( power_flash, 0, 2 );
|
|
|
|
RectClass uv3( POWER_OUT_ICON_UV_UL, POWER_OUT_ICON_UV_LR );
|
|
RectClass draw3 = uv3;
|
|
uv3.Scale( INFO_UV_SCALE );
|
|
|
|
RectClass black( HEALTH_BACK_UV_UL, HEALTH_BACK_UV_LR );
|
|
black.Scale( INFO_UV_SCALE );
|
|
|
|
uv.Scale( INFO_UV_SCALE );
|
|
// draw += box.Upper_Left() - draw.Lower_Left() - Vector2( 0, 1 );
|
|
draw += box.Lower_Left() - draw.Upper_Left() + Vector2( 0, 18 );
|
|
// draw += Vector2( (box.Width() - draw.Width())/2 + 10, 0 ); // Center
|
|
draw += Vector2( (box.Width() - draw.Width())/2 + 2, 0 ); // Center
|
|
draw3 += draw.Center() - draw3.Center();
|
|
|
|
// Draw background
|
|
draw.Inflate( Vector2( 1, 1 ) );
|
|
TargetRenderer->Add_Quad( draw, black );
|
|
draw.Inflate( Vector2( -1, -1 ) );
|
|
|
|
draw.Right = draw.Left + draw.Width() * health_percent;
|
|
uv.Right = uv.Left + uv.Width() * health_percent;
|
|
TargetRenderer->Add_Quad( draw, uv, health_color );
|
|
// power out
|
|
if ( power_flash < 1 ) {
|
|
// TargetRenderer->Add_Quad( draw3, uv3 );
|
|
}
|
|
|
|
uv.Set( TARGET_HEALTH_L_UV_UL, TARGET_HEALTH_L_UV_LR );
|
|
draw2 = uv;
|
|
#if 0
|
|
uv.Scale( INFO_UV_SCALE );
|
|
draw2 += draw.Upper_Left() - draw2.Upper_Right();
|
|
TargetRenderer->Add_Quad( draw2, uv, health_color );
|
|
|
|
WideStringClass num(0,true);
|
|
if ( health < 1 && health > 0 ) {
|
|
health = 1;
|
|
}
|
|
num.Format( L"%d", (int)health );
|
|
TargetNameRenderer->Build_Sentence( num );
|
|
Vector2 text_size = TargetNameRenderer->Get_Text_Extents( num );
|
|
text_size.U -= 1;
|
|
text_size.V = -1;
|
|
draw -= text_size;
|
|
draw.Snap_To_Units( Vector2( 1, 1 ) );
|
|
TargetNameRenderer->Set_Location( draw.Upper_Left() );
|
|
TargetNameRenderer->Draw_Sentence( health_color );
|
|
#endif
|
|
}
|
|
|
|
// Draw Name
|
|
uv.Set( TARGET_NAME_UV_UL, TARGET_NAME_UV_LR );
|
|
draw = uv;
|
|
uv.Scale( INFO_UV_SCALE );
|
|
draw += box.Lower_Left() - draw.Upper_Left() + Vector2( 0, 1 );
|
|
draw += Vector2( (box.Width() - draw.Width())/2 + 10, 0 );
|
|
draw.Snap_To_Units( Vector2( 1, 1 ) );
|
|
TargetRenderer->Add_Quad( draw, uv, color );
|
|
|
|
if ( obj->Get_Translated_Name_ID() != 0 ) {
|
|
TDBObjClass *translate_obj = TranslateDBClass::Find_Object( obj->Get_Translated_Name_ID() );
|
|
if ( translate_obj ) {
|
|
WideStringClass translate_string=translate_obj->Get_String();
|
|
|
|
if ( building != NULL && HUDInfo::Get_Info_Object_Is_MCT() ) {
|
|
translate_string=TRANSLATE( IDS_Enc_Struct_Nod_MCT_Name );
|
|
}
|
|
|
|
Vector2 string_loc=draw.Upper_Left() + Vector2( 3.0f,1.0f );
|
|
if (translate_string!=TargetNameString) {
|
|
TargetNameRenderer->Reset();
|
|
TargetNameString=translate_string;
|
|
TargetNameLocation = string_loc;
|
|
TargetNameRenderer->Build_Sentence( TargetNameString );
|
|
TargetNameRenderer->Set_Location( TargetNameLocation );
|
|
TargetNameRenderer->Set_Base_Location( TargetNameLocation );
|
|
TargetNameRenderer->Draw_Sentence( color );
|
|
}
|
|
if (string_loc!=TargetNameLocation) {
|
|
TargetNameLocation=string_loc;
|
|
TargetNameRenderer->Set_Base_Location( TargetNameLocation );
|
|
}
|
|
}
|
|
else {
|
|
TargetNameRenderer->Reset();
|
|
TargetNameString="";
|
|
TargetNameLocation = Vector2(0.0f,0.0f);
|
|
}
|
|
}
|
|
else {
|
|
TargetNameRenderer->Reset();
|
|
TargetNameString="";
|
|
TargetNameLocation = Vector2(0.0f,0.0f);
|
|
}
|
|
|
|
// Draw Team Icon
|
|
int team = PLAYERTYPE_GDI;
|
|
if ( p_obj != NULL ) {
|
|
team = p_obj->Get_Player_Type();
|
|
}
|
|
|
|
if ( building != NULL ) {
|
|
if ( building->Is_GDI() ) {
|
|
team = PLAYERTYPE_GDI;
|
|
} else if ( building->Is_Nod() ) {
|
|
team = PLAYERTYPE_NOD;
|
|
} else {
|
|
team = PLAYERTYPE_NEUTRAL;
|
|
}
|
|
}
|
|
|
|
if ( team == PLAYERTYPE_NOD ) {
|
|
uv.Set( NOD_ICON_UV_UL, NOD_ICON_UV_LR );
|
|
} else if ( team == PLAYERTYPE_GDI ) {
|
|
uv.Set( GDI_ICON_UV_UL, GDI_ICON_UV_LR );
|
|
} else {
|
|
uv.Set( NEUTRAL_ICON_UV_UL, NEUTRAL_ICON_UV_LR );
|
|
}
|
|
draw2 = uv;
|
|
uv.Scale( INFO_UV_SCALE );
|
|
draw2 += draw.Upper_Left() - draw2.Upper_Right();
|
|
TargetRenderer->Add_Quad( draw2, uv );
|
|
|
|
// Draw chevrons
|
|
bool draw_chevrons = false;
|
|
if ( p_obj != NULL && p_obj->Is_HUD_Pokable_Indicator_Enabled() ) {
|
|
draw_chevrons = true;
|
|
}
|
|
if ( obj->As_SmartGameObj() != NULL &&
|
|
obj->As_SmartGameObj()->As_VehicleGameObj() != NULL &&
|
|
COMBAT_STAR->Is_Permitted_To_Enter_Vehicle() &&
|
|
obj->As_SmartGameObj()->As_VehicleGameObj()->Is_Entry_Permitted( COMBAT_STAR ) ) {
|
|
draw_chevrons = true;
|
|
}
|
|
if ( draw_chevrons ) {
|
|
RectClass enterable_box( Vector2(0,0), TARGET_ENTERABLE_SIZE );
|
|
enterable_box += Vector2( box.Center().X - enterable_box.Center().X ,
|
|
box.Top - enterable_box.Bottom );
|
|
static float enterable_bounce = 0;
|
|
enterable_bounce += TimeManager::Get_Frame_Seconds() * 5;
|
|
enterable_bounce = WWMath::Wrap( enterable_bounce, 0, DEG_TO_RADF( 360 ) );
|
|
enterable_box += Vector2( 0, TARGET_ENTERABLE_BOUNCE * (WWMath::Sin( enterable_bounce ) - 1) );
|
|
|
|
uv.Set( TARGET_ENTERABLE_UV_UL, TARGET_ENTERABLE_UV_LR );
|
|
uv.Scale( INFO_UV_SCALE );
|
|
|
|
color = Get_Health_Color( 1 );
|
|
|
|
// TargetRenderer->Add_Quad( enterable_box, uv );
|
|
enterable_box -= Vector2( 0, enterable_box.Height() * 0.6f );
|
|
TargetRenderer->Add_Tri( enterable_box.Upper_Right(), enterable_box.Upper_Left(), enterable_box.Center(),
|
|
uv.Upper_Right(), uv.Upper_Left(), uv.Center(), color );
|
|
enterable_box += Vector2( 0, enterable_box.Height() * 0.6f );
|
|
TargetRenderer->Add_Tri( enterable_box.Upper_Right(), enterable_box.Upper_Left(), enterable_box.Center(),
|
|
uv.Upper_Right(), uv.Upper_Left(), uv.Center(), color );
|
|
enterable_box += Vector2( 0, enterable_box.Height() * 0.6f );
|
|
TargetRenderer->Add_Tri( enterable_box.Upper_Right(), enterable_box.Upper_Left(), enterable_box.Center(),
|
|
uv.Upper_Right(), uv.Upper_Left(), uv.Center(), color );
|
|
}
|
|
}
|
|
|
|
if ( InfoDebug ) {
|
|
StringClass info(0,true);
|
|
obj->Get_Information( info );
|
|
|
|
WideStringClass str(0,true);
|
|
str.Convert_From( info );
|
|
InfoDebugRenderer->Build_Sentence( str );
|
|
InfoDebugRenderer->Set_Location( Vector2( 520, 240 ) );
|
|
// InfoDebugRenderer->Set_Base_Location( Vector2( 520, 240 ) );
|
|
InfoDebugRenderer->Draw_Sentence();
|
|
}
|
|
|
|
} else {
|
|
TargetNameRenderer->Reset();
|
|
TargetNameString="";
|
|
TargetNameLocation = Vector2(0.0f,0.0f);
|
|
|
|
box_zoom_size = 0;
|
|
HUDInfo::Clear_Info_Object();
|
|
}
|
|
}
|
|
|
|
static void Target_Render( void )
|
|
{
|
|
TargetRenderer->Render();
|
|
TargetBoxRenderer->Render();
|
|
TargetNameRenderer->Render();
|
|
InfoDebugRenderer->Render();
|
|
}
|
|
|
|
static RectClass Get_Target_Box( PhysicalGameObj * obj )
|
|
{
|
|
// Lets draw a box around the target
|
|
WWASSERT( obj );
|
|
PhysClass * po = obj->Peek_Physical_Object();
|
|
|
|
Vector2 top(0,0);
|
|
Vector2 bottom(0,0);
|
|
|
|
if ( po != NULL ) {
|
|
// Get the Obj AABox in Camera Space
|
|
AABoxClass obj_box;
|
|
po->Get_Shadow_Blob_Box( &obj_box );
|
|
Matrix3D obj_tm = po->Get_Transform();
|
|
|
|
Matrix3D boxview_tm;
|
|
Matrix3D boxview_inv_tm;
|
|
boxview_tm.Look_At(COMBAT_CAMERA->Get_Transform().Get_Translation(),obj_tm * obj_box.Center,0.0f);
|
|
boxview_tm.Get_Orthogonal_Inverse(boxview_inv_tm);
|
|
Matrix3D obj_to_boxview_tm = boxview_inv_tm * obj_tm;
|
|
|
|
AABoxClass boxview_box;
|
|
obj_to_boxview_tm.Transform_Center_Extent_AABox( obj_box.Center, obj_box.Extent, &boxview_box.Center, &boxview_box.Extent );
|
|
|
|
Matrix3D camera_tm = COMBAT_CAMERA->Get_Transform();
|
|
Matrix3D camera_inv_tm;
|
|
camera_tm.Get_Orthogonal_Inverse(camera_inv_tm);
|
|
Matrix3D boxview_to_camera_tm = camera_inv_tm * boxview_tm;
|
|
|
|
AABoxClass camera_box;
|
|
boxview_to_camera_tm.Transform_Center_Extent_AABox( boxview_box.Center, boxview_box.Extent, &camera_box.Center, &camera_box.Extent);
|
|
|
|
camera_box.Extent.Z = 0.0f;
|
|
Vector3 ctop = camera_box.Center - camera_box.Extent;
|
|
Vector3 cbottom = camera_box.Center + camera_box.Extent;
|
|
|
|
Vector3 temp;
|
|
COMBAT_CAMERA->Project_Camera_Space_Point( temp, ctop );
|
|
top.X = temp.X;
|
|
top.Y = temp.Y;
|
|
COMBAT_CAMERA->Project_Camera_Space_Point( temp, cbottom );
|
|
bottom.X = temp.X;
|
|
bottom.Y = temp.Y;
|
|
}
|
|
|
|
// Get Box in proper convention
|
|
RectClass screen = Render2DClass::Get_Screen_Resolution();
|
|
top.X = top.X * 0.5f + 0.5f;
|
|
top.Y = top.Y * -0.5f + 0.5f;
|
|
bottom.X = bottom.X * 0.5f + 0.5f;
|
|
bottom.Y = bottom.Y * -0.5f + 0.5f;
|
|
float temp = top.Y;
|
|
top.Y = bottom.Y;
|
|
bottom.Y = temp;
|
|
static RectClass info_box;
|
|
info_box.Set( top.X * screen.Right, top.Y * screen.Bottom, bottom.X * screen.Right, bottom.Y * screen.Bottom ); // convention 0,0 - 1,1
|
|
|
|
return info_box;
|
|
}
|
|
|
|
static void Target_Box_Edge( const Vector2 & a, const Vector2 & b, unsigned int color )
|
|
{
|
|
float percent = 0.2f;
|
|
Vector2 a_ = b - a;
|
|
a_ *= percent;
|
|
a_ += a;
|
|
TargetBoxRenderer->Add_Line( a, a_, 2, color );
|
|
Vector2 b_ = a - b;
|
|
b_ *= percent;
|
|
b_ += b;
|
|
TargetBoxRenderer->Add_Line( b, b_, 2, color );
|
|
}
|
|
|
|
/*
|
|
** Score Display
|
|
*/
|
|
/*
|
|
Render2DTextClass * ScoreRenderer;
|
|
|
|
static void Score_Init( void )
|
|
{
|
|
Font3DInstanceClass * font = WW3DAssetManager::Get_Instance()->Get_Font3DInstance( LARGE_FONT );
|
|
SET_REF_OWNER( font );
|
|
ScoreRenderer = new Render2DTextClass( font );
|
|
ScoreRenderer->Set_Coordinate_Range( Render2DClass::Get_Screen_Resolution() );
|
|
font->Release_Ref();
|
|
}
|
|
|
|
static void Score_Shutdown( void )
|
|
{
|
|
delete ScoreRenderer;
|
|
ScoreRenderer = NULL;
|
|
}
|
|
|
|
static void Score_Update( void )
|
|
{
|
|
ScoreRenderer->Reset();
|
|
|
|
//TSS2001e if ( COMBAT_STAR ) {
|
|
if ( COMBAT_STAR && COMBAT_STAR->Get_Player_Data() ) {
|
|
int score = COMBAT_STAR->Get_Player_Data()->Get_Score();
|
|
// WideStringClass scorestring;
|
|
// scorestring.Format( L"%d", score );
|
|
WCHAR score_string[12]; // 12 digits ought to be enough...
|
|
Generate_WChar_Text_From_Number(score_string,sizeof(score_string),false,score);
|
|
|
|
Vector2 position = Render2DClass::Get_Screen_Resolution().Center();
|
|
position.Y = Render2DClass::Get_Screen_Resolution().Bottom;
|
|
Vector2 size = ScoreRenderer->Get_Text_Extents( score_string );
|
|
size.X *= 0.5f;
|
|
position -= size;
|
|
ScoreRenderer->Set_Location( position );
|
|
ScoreRenderer->Draw_Text( score_string );
|
|
}
|
|
|
|
}
|
|
|
|
static void Score_Render( void )
|
|
{
|
|
ScoreRenderer->Render();
|
|
}
|
|
*/
|
|
|
|
/*
|
|
** Objective Display
|
|
*/
|
|
DynamicVectorClass<Render2DClass *> ObjectivePogRenderers;
|
|
Render2DClass * ObjectiveArrowRenderer;
|
|
Render2DSentenceClass * ObjectiveTextRenderer;
|
|
|
|
int CurrentObjectiveIndex = 0;
|
|
void * CurrentObjective = NULL;
|
|
static int CachedObjectiveIndex=-1;
|
|
int CachedRange=0;
|
|
|
|
#define OBJECTIVE_ARROW_TEXTURE "HUD_obje_arrow.TGA"
|
|
|
|
static void Objective_Init( void )
|
|
{
|
|
ObjectiveArrowRenderer = new Render2DClass();
|
|
ObjectiveArrowRenderer->Set_Texture( OBJECTIVE_ARROW_TEXTURE );
|
|
ObjectiveArrowRenderer->Set_Coordinate_Range( Render2DClass::Get_Screen_Resolution() );
|
|
|
|
FontCharsClass *font = StyleMgrClass::Peek_Font( StyleMgrClass::FONT_INGAME_TXT );
|
|
ObjectiveTextRenderer = new Render2DSentenceClass();
|
|
ObjectiveTextRenderer->Set_Font( font );
|
|
|
|
CurrentObjectiveIndex=0;
|
|
CurrentObjective=NULL;
|
|
CachedObjectiveIndex=-1;
|
|
CachedRange=0;
|
|
}
|
|
|
|
static void Objective_Release_Pogs( void )
|
|
{
|
|
for ( int i = 0; i < ObjectivePogRenderers.Count(); i++ ) {
|
|
delete ObjectivePogRenderers[i];
|
|
ObjectivePogRenderers[i] = NULL;
|
|
}
|
|
ObjectivePogRenderers.Delete_All();
|
|
}
|
|
|
|
static void Objective_Shutdown( void )
|
|
{
|
|
Objective_Release_Pogs();
|
|
|
|
delete ObjectiveArrowRenderer;
|
|
ObjectiveArrowRenderer = NULL;
|
|
|
|
delete ObjectiveTextRenderer;
|
|
ObjectiveTextRenderer = NULL;
|
|
}
|
|
|
|
#define POG_FLY_TIME 2.0f
|
|
|
|
static void Objective_Update( void )
|
|
{
|
|
RectClass pog_box( 0, 0, 64, 64 );
|
|
pog_box += Render2DClass::Get_Screen_Resolution().Upper_Right() - pog_box.Upper_Right();
|
|
pog_box += Vector2( -16, 8 );
|
|
|
|
#define POG_SPACING Vector2( 10, 0 )
|
|
|
|
bool rebuild = false;
|
|
|
|
int objective_count = ObjectiveManager::Get_Num_HUD_Objectives();
|
|
if ( objective_count > 0 ) {
|
|
// maintain the index
|
|
if ( CurrentObjective != ObjectiveManager::Get_Objective( CurrentObjectiveIndex ) ) {
|
|
CurrentObjectiveIndex = 0;
|
|
rebuild = true;
|
|
#if 0 // no, just go for the first
|
|
// Try to find the last objective
|
|
for ( int i = 0; i < objective_count; i++ ) {
|
|
if ( CurrentObjective == ObjectiveManager::Get_Objective( i ) ) {
|
|
CurrentObjectiveIndex = i;
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
if ( IS_MISSION && Input::Get_State( INPUT_FUNCTION_CYCLE_POG ) ) {
|
|
rebuild = true;
|
|
CurrentObjectiveIndex++;
|
|
if ( CurrentObjectiveIndex >= objective_count ) {
|
|
CurrentObjectiveIndex = 0;
|
|
}
|
|
}
|
|
|
|
CurrentObjective = ObjectiveManager::Get_Objective( CurrentObjectiveIndex );
|
|
} else {
|
|
if (CurrentObjectiveIndex!=0 || CurrentObjective!=NULL) {
|
|
rebuild=true;
|
|
}
|
|
CurrentObjectiveIndex = 0;
|
|
CurrentObjective = NULL;
|
|
}
|
|
|
|
// re-Create the Pogs, if needed
|
|
if ( rebuild || ObjectiveManager::Are_HUD_Objectives_Changed() )
|
|
{
|
|
// Debug_Say(( "Rebuild Hud Pogs\n" ));
|
|
|
|
Objective_Release_Pogs();
|
|
// Reset text
|
|
ObjectiveTextRenderer->Reset();
|
|
CachedRange=0;
|
|
CachedObjectiveIndex=-1;
|
|
|
|
int count = objective_count;
|
|
pog_box += POG_SPACING * (float)count;
|
|
|
|
bool dont_clear = false;
|
|
|
|
for ( int i = count - 1; i >= 0; i-- ) {
|
|
int index = (i + CurrentObjectiveIndex) % objective_count;
|
|
pog_box -= POG_SPACING;
|
|
// Add Pog
|
|
Render2DClass * renderer = new Render2DClass();
|
|
if ( renderer ) {
|
|
renderer->Set_Texture( ObjectiveManager::Get_HUD_Objectives_Pog_Texture_Name( index ) );
|
|
renderer->Set_Coordinate_Range( Render2DClass::Get_Screen_Resolution() );
|
|
float age = ObjectiveManager::Get_HUD_Objectives_Age( index );
|
|
if ( age < POG_FLY_TIME ) {
|
|
Vector2 offset = Render2DClass::Get_Screen_Resolution().Center() - Render2DClass::Get_Screen_Resolution().Upper_Right();
|
|
offset.X *= 0.75f;
|
|
float fly = WWMath::Clamp( (2.0f-(2.0f*age/POG_FLY_TIME)), 0, 1 );
|
|
offset *= fly;
|
|
pog_box += offset;
|
|
renderer->Add_Quad( pog_box );
|
|
pog_box -= offset;
|
|
dont_clear = true;
|
|
|
|
// AND, make an extra renderer for the radar star
|
|
Render2DClass * renderer = new Render2DClass();
|
|
if ( renderer ) {
|
|
renderer->Set_Texture( "HUD_STAR.TGA" );
|
|
renderer->Set_Coordinate_Range( Render2DClass::Get_Screen_Resolution() );
|
|
|
|
RectClass star_box( -32, -32, 32, 32 );
|
|
star_box.Scale( fly );
|
|
|
|
Vector2 star_fly_start = Render2DClass::Get_Screen_Resolution().Center();
|
|
Vector2 star_fly_end = Render2DClass::Get_Screen_Resolution().Lower_Left();
|
|
star_fly_start.X *= 0.85f;
|
|
star_fly_start.Y *= 1.175f;
|
|
star_fly_end.X += 40.0f;
|
|
star_fly_end.Y *= 0.8f;
|
|
|
|
star_box += star_fly_end;
|
|
Vector2 offset = star_fly_start - star_fly_end;
|
|
offset *= fly;
|
|
star_box += offset;
|
|
|
|
Vector3 color3( 0,1,0 );
|
|
if ( ObjectiveManager::Get_Objective(index) != NULL ) {
|
|
color3 = ObjectiveManager::Get_Objective(index)->Type_To_Color();
|
|
}
|
|
unsigned int color = color3.Convert_To_ARGB();
|
|
renderer->Add_Quad( star_box, color );
|
|
ObjectivePogRenderers.Add( renderer );
|
|
}
|
|
|
|
} else {
|
|
renderer->Add_Quad( pog_box );
|
|
}
|
|
ObjectivePogRenderers.Add( renderer );
|
|
}
|
|
}
|
|
if ( !dont_clear ) {
|
|
ObjectiveManager::Clear_HUD_Objectives_Changed();
|
|
}
|
|
}
|
|
|
|
ObjectiveArrowRenderer->Reset();
|
|
|
|
float range = 0;
|
|
int count = objective_count;
|
|
if ( count > 0 ) {
|
|
// Create Arrow
|
|
float angle = 0;
|
|
Vector3 objective_pos = ObjectiveManager::Get_HUD_Objectives_Location( CurrentObjectiveIndex );
|
|
|
|
if ( COMBAT_STAR ) {
|
|
Vector3 rel_pos;
|
|
Matrix3D::Inverse_Transform_Vector( COMBAT_STAR->Get_Transform(), objective_pos, &rel_pos );
|
|
angle = ::atan2( rel_pos.Y, rel_pos.X );
|
|
range = rel_pos.Length();
|
|
}
|
|
|
|
Vector2 arrow_vertex;
|
|
arrow_vertex.X = WWMath::Fast_Sin( angle + DEG_TO_RAD( 180 + 45 ) );
|
|
arrow_vertex.Y = WWMath::Fast_Cos( angle + DEG_TO_RAD( 180 + 45 ) );
|
|
Vector2 verts[4];
|
|
verts[0] = Vector2( arrow_vertex.X, arrow_vertex.Y );
|
|
verts[1] = Vector2( arrow_vertex.Y, -arrow_vertex.X );
|
|
verts[2] = Vector2( -arrow_vertex.Y, arrow_vertex.X );
|
|
verts[3] = Vector2( -arrow_vertex.X, -arrow_vertex.Y );
|
|
Vector2 offset;
|
|
offset.Y = WWMath::Fast_Sin( -angle + DEG_TO_RAD( -90 ) );
|
|
offset.X = WWMath::Fast_Cos( -angle + DEG_TO_RAD( -90 ) );
|
|
offset *= 35;
|
|
offset += pog_box.Center();
|
|
|
|
const float SIN_45=0.70710678118654752440084436210485f;
|
|
for ( int i = 0; i < 4; i++ ) {
|
|
verts[i] *= 0.5f * 16 / SIN_45;//::sin( DEG_TO_RAD( 45 ) );
|
|
verts[i] += offset;
|
|
}
|
|
ObjectiveArrowRenderer->Add_Quad( verts[0], verts[1], verts[2], verts[3] );
|
|
}
|
|
|
|
int irange=(int)(range);
|
|
irange=(irange/10)*10;
|
|
if (CachedObjectiveIndex!=CurrentObjectiveIndex || irange!=CachedRange) {
|
|
ObjectiveTextRenderer->Reset();
|
|
|
|
if (objective_count>0) {
|
|
CachedRange=irange;
|
|
CachedObjectiveIndex=CurrentObjectiveIndex;
|
|
|
|
// Draw message
|
|
Vector2 position = pog_box.Lower_Left();
|
|
position += Vector2( 0, -15 );
|
|
WideStringClass str(ObjectiveManager::Get_HUD_Objectives_Message( CurrentObjectiveIndex ),true);
|
|
ObjectiveTextRenderer->Build_Sentence( str );
|
|
Vector2 text_size = ObjectiveTextRenderer->Get_Text_Extents( str );
|
|
position.X = (int)(pog_box.Center().X - (text_size.X/2));
|
|
ObjectiveTextRenderer->Set_Location( position );
|
|
ObjectiveTextRenderer->Draw_Sentence();
|
|
|
|
// Draw range
|
|
position = pog_box.Lower_Left();
|
|
str.Format( TRANSLATE(IDS_HUD_RANGE), irange );
|
|
ObjectiveTextRenderer->Build_Sentence( str );
|
|
text_size = ObjectiveTextRenderer->Get_Text_Extents( str );
|
|
position.X = (int)(pog_box.Center().X - (text_size.X/2));
|
|
ObjectiveTextRenderer->Set_Location( position );
|
|
ObjectiveTextRenderer->Draw_Sentence();
|
|
}
|
|
else {
|
|
CachedRange=0;
|
|
CachedObjectiveIndex=-1;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void Objective_Render( void )
|
|
{
|
|
for ( int i = 0; i < ObjectivePogRenderers.Count(); i++ ) {
|
|
ObjectivePogRenderers[i]->Render();
|
|
}
|
|
ObjectiveArrowRenderer->Render();
|
|
ObjectiveTextRenderer->Render();
|
|
}
|
|
|
|
/*
|
|
** Info Display
|
|
*/
|
|
struct InfoEditorField {
|
|
const char * Name;
|
|
Vector2 * Value;
|
|
bool operator == (InfoEditorField const & rec) const { return false; }
|
|
bool operator != (InfoEditorField const & rec) const { return true; }
|
|
};
|
|
|
|
static DynamicVectorClass<InfoEditorField> InfoEditorFieldList;
|
|
|
|
#define INFO_EDITOR_ADD(x) field.Name = #x; field.Value = &x; InfoEditorFieldList.Add( field );
|
|
|
|
static void Info_Editor_Init( void )
|
|
{
|
|
#if 0
|
|
InfoEditorField field;
|
|
|
|
INFO_EDITOR_ADD( INFO_OFFSET );
|
|
INFO_EDITOR_ADD( FRAME_1_UV_UL );
|
|
INFO_EDITOR_ADD( FRAME_1_UV_LR );
|
|
INFO_EDITOR_ADD( FRAME_1_OFFSET );
|
|
INFO_EDITOR_ADD( FRAME_2_UV_UL );
|
|
INFO_EDITOR_ADD( FRAME_2_UV_LR );
|
|
INFO_EDITOR_ADD( FRAME_2_OFFSET );
|
|
INFO_EDITOR_ADD( FRAME_3_UV_UL );
|
|
INFO_EDITOR_ADD( FRAME_3_UV_LR );
|
|
INFO_EDITOR_ADD( FRAME_3_OFFSET );
|
|
INFO_EDITOR_ADD( FRAME_4_UV_UL );
|
|
INFO_EDITOR_ADD( FRAME_4_UV_LR );
|
|
INFO_EDITOR_ADD( FRAME_4_OFFSET );
|
|
INFO_EDITOR_ADD( FRAME_5_UV_UL );
|
|
INFO_EDITOR_ADD( FRAME_5_UV_LR );
|
|
INFO_EDITOR_ADD( FRAME_5_OFFSET );
|
|
INFO_EDITOR_ADD( FRAME_6_UV_UL );
|
|
INFO_EDITOR_ADD( FRAME_6_UV_LR );
|
|
INFO_EDITOR_ADD( FRAME_6_OFFSET );
|
|
INFO_EDITOR_ADD( HEALTH_BACK_UV_UL );
|
|
INFO_EDITOR_ADD( HEALTH_BACK_UV_LR );
|
|
INFO_EDITOR_ADD( HEALTH_BACK_UL );
|
|
INFO_EDITOR_ADD( HEALTH_BACK_LR );
|
|
INFO_EDITOR_ADD( GRADIENT_BLACK_UV_UL );
|
|
INFO_EDITOR_ADD( GRADIENT_BLACK_UV_LR );
|
|
INFO_EDITOR_ADD( HEALTH_TEXT_BACK_UL );
|
|
INFO_EDITOR_ADD( HEALTH_TEXT_BACK_LR );
|
|
INFO_EDITOR_ADD( HEALTH_UV_UL );
|
|
INFO_EDITOR_ADD( HEALTH_UV_LR );
|
|
INFO_EDITOR_ADD( HEALTH_OFFSET );
|
|
INFO_EDITOR_ADD( SHIELD_UV_UL );
|
|
INFO_EDITOR_ADD( SHIELD_UV_LR );
|
|
INFO_EDITOR_ADD( SHIELD_OFFSET );
|
|
INFO_EDITOR_ADD( KEY_1_UV_UL );
|
|
INFO_EDITOR_ADD( KEY_1_UV_LR );
|
|
INFO_EDITOR_ADD( KEY_1_OFFSET );
|
|
INFO_EDITOR_ADD( KEY_2_UV_UL );
|
|
INFO_EDITOR_ADD( KEY_2_UV_LR );
|
|
INFO_EDITOR_ADD( KEY_2_OFFSET );
|
|
INFO_EDITOR_ADD( KEY_3_UV_UL );
|
|
INFO_EDITOR_ADD( KEY_3_UV_LR );
|
|
INFO_EDITOR_ADD( KEY_3_OFFSET );
|
|
INFO_EDITOR_ADD( HEALTH_CROSS_1_UV_UL );
|
|
INFO_EDITOR_ADD( HEALTH_CROSS_1_UV_LR );
|
|
INFO_EDITOR_ADD( HEALTH_CROSS_1_OFFSET );
|
|
INFO_EDITOR_ADD( HEALTH_CROSS_2_UV_UL );
|
|
INFO_EDITOR_ADD( HEALTH_CROSS_2_UV_LR );
|
|
INFO_EDITOR_ADD( HEALTH_CROSS_2_OFFSET );
|
|
INFO_EDITOR_ADD( TIME_BACK_UL );
|
|
INFO_EDITOR_ADD( TIME_BACK_LR );
|
|
INFO_EDITOR_ADD( TIME_CLOCK_UV_UL );
|
|
INFO_EDITOR_ADD( TIME_CLOCK_UV_LR );
|
|
INFO_EDITOR_ADD( TIME_CLOCK_OFFSET );
|
|
INFO_EDITOR_ADD( WEAPON_BOX_UV_UL );
|
|
INFO_EDITOR_ADD( WEAPON_BOX_UV_LR );
|
|
INFO_EDITOR_ADD( WEAPON_BOX_OFFSET );
|
|
INFO_EDITOR_ADD( POWER_OUT_ICON_UV_UL );
|
|
INFO_EDITOR_ADD( POWER_OUT_ICON_UV_LR );
|
|
INFO_EDITOR_ADD( POWER_OUT_ICON_OFFSET );
|
|
INFO_EDITOR_ADD( REPAIR_ICON_UV_UL );
|
|
INFO_EDITOR_ADD( REPAIR_ICON_UV_LR );
|
|
INFO_EDITOR_ADD( REPAIR_ICON_OFFSET );
|
|
INFO_EDITOR_ADD( GDI_ICON_UV_UL );
|
|
INFO_EDITOR_ADD( GDI_ICON_UV_LR );
|
|
INFO_EDITOR_ADD( GDI_ICON_OFFSET );
|
|
INFO_EDITOR_ADD( NOD_ICON_UV_UL );
|
|
INFO_EDITOR_ADD( NOD_ICON_UV_LR );
|
|
INFO_EDITOR_ADD( NOD_ICON_OFFSET );
|
|
INFO_EDITOR_ADD( NEUTRAL_ICON_UV_UL );
|
|
INFO_EDITOR_ADD( NEUTRAL_ICON_UV_LR );
|
|
INFO_EDITOR_ADD( NEUTRAL_ICON_OFFSET );
|
|
INFO_EDITOR_ADD( BULLET_ICON_UV_UL );
|
|
INFO_EDITOR_ADD( BULLET_ICON_UV_LR );
|
|
INFO_EDITOR_ADD( BULLET_ICON_OFFSET );
|
|
INFO_EDITOR_ADD( RADAR_CENTER_OFFSET );
|
|
INFO_EDITOR_ADD( DAMAGE_1_UV_UL );
|
|
INFO_EDITOR_ADD( DAMAGE_1_UV_LR );
|
|
INFO_EDITOR_ADD( DAMAGE_2_UV_UL );
|
|
INFO_EDITOR_ADD( DAMAGE_2_UV_LR );
|
|
INFO_EDITOR_ADD( HORIZ_DAMAGE_SIZE );
|
|
INFO_EDITOR_ADD( VERT_DAMAGE_SIZE );
|
|
INFO_EDITOR_ADD( DIAG_DAMAGE_SIZE );
|
|
INFO_EDITOR_ADD( HV_DAMAGE_OFFSET );
|
|
INFO_EDITOR_ADD( DIAG_DAMAGE_OFFSET );
|
|
INFO_EDITOR_ADD( POWERUP_BOX_UV_UL );
|
|
INFO_EDITOR_ADD( POWERUP_BOX_UV_LR );
|
|
INFO_EDITOR_ADD( RADAR_RINGS_UV_UL );
|
|
INFO_EDITOR_ADD( RADAR_RINGS_UV_LR );
|
|
INFO_EDITOR_ADD( RADAR_RINGS_L_OFFSET );
|
|
INFO_EDITOR_ADD( RADAR_RINGS_R_OFFSET );
|
|
INFO_EDITOR_ADD( RADAR_STAR_UV_UL );
|
|
INFO_EDITOR_ADD( RADAR_STAR_UV_LR );
|
|
INFO_EDITOR_ADD( RADAR_STAR_OFFSET );
|
|
INFO_EDITOR_ADD( RADAR_SQUARE_UV_UL );
|
|
INFO_EDITOR_ADD( RADAR_SQUARE_UV_LR );
|
|
INFO_EDITOR_ADD( RADAR_SQUARE_OFFSET);
|
|
INFO_EDITOR_ADD( RADAR_TRIANGLE_UV_UL);
|
|
INFO_EDITOR_ADD( RADAR_TRIANGLE_UV_LR);
|
|
INFO_EDITOR_ADD( RADAR_TRIANGLE_OFFSET );
|
|
INFO_EDITOR_ADD( RADAR_CIRCLE_UV_UL );
|
|
INFO_EDITOR_ADD( RADAR_CIRCLE_UV_LR );
|
|
INFO_EDITOR_ADD( RADAR_CIRCLE_OFFSET );
|
|
INFO_EDITOR_ADD( RADAR_BRACKET_UV_UL );
|
|
INFO_EDITOR_ADD( RADAR_BRACKET_UV_LR );
|
|
INFO_EDITOR_ADD( RADAR_BRACKET_OFFSET );
|
|
INFO_EDITOR_ADD( RADAR_SWEEP_UV_UL );
|
|
INFO_EDITOR_ADD( RADAR_SWEEP_UV_LR );
|
|
INFO_EDITOR_ADD( RADAR_SWEEP_OFFSET );
|
|
INFO_EDITOR_ADD( TARGET_HEALTH_L_UV_UL );
|
|
INFO_EDITOR_ADD( TARGET_HEALTH_L_UV_LR );
|
|
INFO_EDITOR_ADD( TARGET_HEALTH_R_UV_UL );
|
|
INFO_EDITOR_ADD( TARGET_HEALTH_R_UV_LR );
|
|
INFO_EDITOR_ADD( TARGET_HEALTH_OFFSET );
|
|
INFO_EDITOR_ADD( TARGET_NAME_UV_UL );
|
|
INFO_EDITOR_ADD( TARGET_NAME_UV_LR );
|
|
INFO_EDITOR_ADD( TARGET_NAME_OFFSET );
|
|
#endif
|
|
}
|
|
|
|
static void Info_Editor_Update( void )
|
|
{
|
|
return;
|
|
bool changed = false;
|
|
static int index = 0;
|
|
|
|
static float _move = 0;
|
|
float move = Input::Get_Amount( INPUT_FUNCTION_MOVE_LEFT ) - Input::Get_Amount( INPUT_FUNCTION_MOVE_RIGHT );
|
|
if ( _move != move ) {
|
|
_move = move;
|
|
index += (int)-move;
|
|
index = (int)WWMath::Wrap( index, (float)0, (float)(InfoEditorFieldList.Count()) );
|
|
if ( move != 0 ) {
|
|
changed = true;
|
|
}
|
|
}
|
|
|
|
float _forward = 0;
|
|
float forward = Input::Get_Amount( INPUT_FUNCTION_MOVE_FORWARD ) - Input::Get_Amount( INPUT_FUNCTION_MOVE_BACKWARD );
|
|
forward *= 10;
|
|
forward = WWMath::Clamp( forward, -1, 1 );
|
|
if ( _forward != forward ) {
|
|
_forward = forward;
|
|
InfoEditorFieldList[index].Value->V += forward;
|
|
if ( forward != 0 ) {
|
|
changed = true;
|
|
}
|
|
}
|
|
|
|
float _left = 0;
|
|
float left = Input::Get_Amount( INPUT_FUNCTION_TURN_LEFT ) - Input::Get_Amount( INPUT_FUNCTION_TURN_RIGHT );
|
|
left *= 10;
|
|
left = WWMath::Clamp( left, -1, 1 );
|
|
if ( _left != left ) {
|
|
_left = left;
|
|
InfoEditorFieldList[index].Value->U += left;
|
|
if ( left != 0 ) {
|
|
changed = true;
|
|
}
|
|
}
|
|
|
|
if ( changed ) {
|
|
Debug_Say(( "Vector2 %s( %d, %d );\n", InfoEditorFieldList[index].Name, (int)InfoEditorFieldList[index].Value->U, (int)InfoEditorFieldList[index].Value->V ));
|
|
}
|
|
|
|
}
|
|
|
|
static void Info_Editor_Shutdown( void )
|
|
{
|
|
while ( InfoEditorFieldList.Count() > 0 ) {
|
|
Debug_Say(( "Vector2 %s( %d, %d );\n", InfoEditorFieldList[0].Name, (int)InfoEditorFieldList[0].Value->U, (int)InfoEditorFieldList[0].Value->V ));
|
|
InfoEditorFieldList.Delete(0);
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
**
|
|
*/
|
|
Render2DTextClass * InfoHealthCountRenderer;
|
|
Render2DTextClass * InfoShieldCountRenderer;
|
|
|
|
Vector2 InfoBase(0,0);
|
|
|
|
float LastHealth = 0;
|
|
float CenterHealthTimer = 0;
|
|
const float CENTER_HEALTH_TIME = 2.0f;
|
|
|
|
static void Info_Init( void )
|
|
{
|
|
Info_Editor_Init();
|
|
|
|
InfoRenderer = new Render2DClass();
|
|
InfoRenderer->Set_Texture( HUD_MAIN_TEXTURE );
|
|
InfoRenderer->Set_Coordinate_Range( Render2DClass::Get_Screen_Resolution() );
|
|
|
|
Font3DInstanceClass * font = WW3DAssetManager::Get_Instance()->Get_Font3DInstance( LARGE_FONT );
|
|
SET_REF_OWNER( font );
|
|
InfoHealthCountRenderer = new Render2DTextClass( font );
|
|
InfoHealthCountRenderer->Set_Coordinate_Range( Render2DClass::Get_Screen_Resolution() );
|
|
font->Release_Ref();
|
|
|
|
font = WW3DAssetManager::Get_Instance()->Get_Font3DInstance( SMALL_FONT );
|
|
SET_REF_OWNER( font );
|
|
InfoShieldCountRenderer = new Render2DTextClass( font );
|
|
InfoShieldCountRenderer->Set_Coordinate_Range( Render2DClass::Get_Screen_Resolution() );
|
|
font->Release_Ref();
|
|
|
|
InfoBase = Render2DClass::Get_Screen_Resolution().Lower_Left() + Vector2( INFO_OFFSET );
|
|
}
|
|
|
|
static void Info_Shutdown( void )
|
|
{
|
|
Info_Editor_Shutdown() ;
|
|
|
|
delete InfoRenderer;
|
|
InfoRenderer = NULL;
|
|
|
|
delete InfoHealthCountRenderer;
|
|
InfoHealthCountRenderer = NULL;
|
|
|
|
delete InfoShieldCountRenderer;
|
|
InfoShieldCountRenderer = NULL;
|
|
}
|
|
|
|
static void Info_Update_Health_Shield( void )
|
|
{
|
|
// Draw Health
|
|
float health = 0;
|
|
float health_percent = 0;
|
|
float shield = 0;
|
|
float shield_percent = 0;
|
|
|
|
if ( COMBAT_STAR ) {
|
|
const DefenseObjectClass * def = COMBAT_STAR->Get_Defense_Object();
|
|
if ( COMBAT_STAR->Get_Vehicle() ) {
|
|
def = COMBAT_STAR->Get_Vehicle()->Get_Defense_Object();
|
|
}
|
|
if ( def && def->Get_Health_Max() ) {
|
|
health = def->Get_Health();
|
|
health_percent = WWMath::Clamp( def->Get_Health() / def->Get_Health_Max(), 0, 1 );
|
|
}
|
|
if ( def && def->Get_Shield_Strength_Max() ) {
|
|
shield = def->Get_Shield_Strength();
|
|
shield_percent = WWMath::Clamp( def->Get_Shield_Strength() / def->Get_Shield_Strength_Max(), 0, 1 );
|
|
}
|
|
}
|
|
|
|
RectClass uv;
|
|
RectClass draw;
|
|
|
|
// Draw Health Bar
|
|
uv.Set( HEALTH_UV_UL, HEALTH_UV_LR );
|
|
draw = uv;
|
|
uv.Scale( INFO_UV_SCALE );
|
|
draw += InfoBase + HEALTH_OFFSET - draw.Upper_Left();
|
|
|
|
// Scale bars
|
|
static float _last_health_percent = 0;
|
|
float diff = health_percent - _last_health_percent;
|
|
float max_change = TimeManager::Get_Frame_Seconds();
|
|
_last_health_percent += WWMath::Clamp( diff, -max_change, max_change );
|
|
uv.Right = uv.Left + uv.Width() * _last_health_percent;
|
|
draw.Right = draw.Left + draw.Width() * _last_health_percent;
|
|
|
|
// Get bar color
|
|
float color_percent = MAX( _last_health_percent, health_percent );
|
|
InfoRenderer->Add_Quad( draw, uv, Get_Health_Color( color_percent ) );
|
|
|
|
uv.Set( GRADIENT_BLACK_UV_UL, GRADIENT_BLACK_UV_LR );
|
|
uv.Scale( INFO_UV_SCALE );
|
|
draw.Set( HEALTH_TEXT_BACK_UL, HEALTH_TEXT_BACK_LR );
|
|
draw += InfoBase;
|
|
InfoRenderer->Add_Quad( draw, uv );
|
|
|
|
// Draw Cross
|
|
static float flash = 0;
|
|
flash += TimeManager::Get_Frame_Seconds() * 4;
|
|
if ( flash > 2 ) {
|
|
flash -= 2;
|
|
}
|
|
if ( health_percent > 0.25f ) {
|
|
flash = 0;
|
|
}
|
|
float intensity = flash;
|
|
if ( flash > 1 ) {
|
|
intensity = 2 - flash;
|
|
}
|
|
|
|
int health_color = Get_Health_Color( color_percent );
|
|
|
|
uv.Set( HEALTH_CROSS_1_UV_UL, HEALTH_CROSS_1_UV_LR );
|
|
draw = uv;
|
|
uv.Scale( INFO_UV_SCALE );
|
|
draw += InfoBase + HEALTH_CROSS_1_OFFSET - draw.Upper_Left();
|
|
InfoRenderer->Add_Quad( draw, uv, COLOR( intensity, health_color ) );
|
|
|
|
RectClass uv2;
|
|
uv2.Set( HEALTH_CROSS_2_UV_UL, HEALTH_CROSS_2_UV_LR );
|
|
uv2.Scale( INFO_UV_SCALE );
|
|
InfoRenderer->Add_Quad( draw, uv2, COLOR( 1-intensity, health_color ) );
|
|
|
|
// Draw Health Number
|
|
InfoHealthCountRenderer->Reset();
|
|
// StringClass text;
|
|
if ( health < 1 && health > 0 ) {
|
|
health = 1;
|
|
}
|
|
//text.Format( "%03d", (int)health );
|
|
long lhealth=WWMath::Float_To_Long(health);
|
|
WCHAR tmp_text[5];
|
|
Generate_WChar_Text_From_Number(tmp_text,4,3,lhealth);
|
|
|
|
InfoHealthCountRenderer->Set_Location( draw.Upper_Right() + Vector2( 4,4) );
|
|
InfoHealthCountRenderer->Draw_Text( tmp_text, health_color );
|
|
|
|
if ( health != LastHealth || health_percent <= 0.25f ) {
|
|
LastHealth = health;
|
|
CenterHealthTimer = CENTER_HEALTH_TIME;
|
|
}
|
|
|
|
if ( CenterHealthTimer > 0 ) {
|
|
// Also draw the above at the center
|
|
|
|
Vector2 health_center_offset = Render2DClass::Get_Screen_Resolution().Center();
|
|
health_center_offset.X *= 0.5;
|
|
health_center_offset.Y -= draw.Height() / 2;
|
|
|
|
health_center_offset -= HEALTH_CROSS_1_OFFSET;
|
|
|
|
float fade = WWMath::Clamp( CenterHealthTimer, 0, 1 );
|
|
|
|
uv.Set( GRADIENT_BLACK_UV_UL, GRADIENT_BLACK_UV_LR );
|
|
uv.Scale( INFO_UV_SCALE );
|
|
draw.Set( HEALTH_TEXT_BACK_UL, HEALTH_TEXT_BACK_LR );
|
|
draw += health_center_offset;
|
|
InfoRenderer->Add_Quad( draw, uv, COLOR( fade ) );
|
|
|
|
uv.Set( HEALTH_CROSS_1_UV_UL, HEALTH_CROSS_1_UV_LR );
|
|
draw = uv;
|
|
uv.Scale( INFO_UV_SCALE );
|
|
draw += health_center_offset + HEALTH_CROSS_1_OFFSET - draw.Upper_Left();
|
|
InfoRenderer->Add_Quad( draw, uv, COLOR( fade * intensity, health_color ) );
|
|
InfoRenderer->Add_Quad( draw, uv2, COLOR( fade * (1-intensity), health_color ) );
|
|
|
|
InfoHealthCountRenderer->Set_Location( draw.Upper_Right() + Vector2( 4,4) );
|
|
InfoHealthCountRenderer->Draw_Text( tmp_text, COLOR( fade, health_color ) );
|
|
CenterHealthTimer -= TimeManager::Get_Frame_Seconds();
|
|
}
|
|
|
|
// Draw Shield
|
|
static float _last_shield_percent = 0;
|
|
diff = shield_percent - _last_shield_percent;
|
|
max_change = TimeManager::Get_Frame_Seconds();
|
|
_last_shield_percent += WWMath::Clamp( diff, -max_change, max_change );
|
|
shield_percent = _last_shield_percent;
|
|
uv.Right = uv.Left + uv.Width() * shield_percent;
|
|
draw.Right = draw.Left + draw.Width() * shield_percent;
|
|
|
|
if ( shield_percent > 0 ) {
|
|
#define TOTAL_SHIELD_MOVEMENT 80
|
|
for ( float percent = 0; percent < shield_percent; percent += 0.1f ) {
|
|
uv.Set( SHIELD_UV_UL, SHIELD_UV_LR );
|
|
draw = uv;
|
|
uv.Scale( INFO_UV_SCALE );
|
|
draw += InfoBase + SHIELD_OFFSET - draw.Upper_Left();
|
|
draw += Vector2( (int)(-percent * TOTAL_SHIELD_MOVEMENT), 0 );
|
|
InfoRenderer->Add_Quad( draw, uv );
|
|
}
|
|
|
|
uv.Set( SHIELD_UV_UL, SHIELD_UV_LR );
|
|
draw = uv;
|
|
uv.Scale( INFO_UV_SCALE );
|
|
draw += InfoBase + SHIELD_OFFSET - draw.Upper_Left();
|
|
draw += Vector2( (int)(-shield_percent * TOTAL_SHIELD_MOVEMENT), 0 );
|
|
InfoRenderer->Add_Quad( draw, uv );
|
|
|
|
// Draw Shield Number
|
|
InfoShieldCountRenderer->Reset();
|
|
// StringClass text;
|
|
// text.Format( "%03d", (int)shield );
|
|
long lshield=WWMath::Float_To_Long(shield);
|
|
WCHAR tmp_text[5];
|
|
Generate_WChar_Text_From_Number(tmp_text,4,3,lshield);
|
|
InfoShieldCountRenderer->Set_Location( draw.Upper_Left() + Vector2( 4,4) );
|
|
InfoShieldCountRenderer->Draw_Text( tmp_text );
|
|
} else {
|
|
InfoShieldCountRenderer->Reset();
|
|
}
|
|
}
|
|
|
|
static void Info_Update( void )
|
|
{
|
|
// Info_Editor_Update();
|
|
|
|
// Clear the renderer
|
|
InfoRenderer->Reset();
|
|
|
|
// Draw the Frame
|
|
RectClass uv;
|
|
uv.Set( FRAME_1_UV_UL, FRAME_1_UV_LR );
|
|
RectClass draw = uv;
|
|
uv.Scale( INFO_UV_SCALE );
|
|
draw += InfoBase + FRAME_1_OFFSET - draw.Upper_Left();
|
|
InfoRenderer->Add_Quad( draw, uv );
|
|
|
|
uv.Set( FRAME_2_UV_UL, FRAME_2_UV_LR );
|
|
draw = uv;
|
|
uv.Scale( INFO_UV_SCALE );
|
|
draw += InfoBase + FRAME_2_OFFSET - draw.Upper_Left();
|
|
InfoRenderer->Add_Quad( draw, uv );
|
|
|
|
uv.Set( FRAME_3_UV_UL, FRAME_3_UV_LR );
|
|
draw = uv;
|
|
uv.Scale( INFO_UV_SCALE );
|
|
draw += InfoBase + FRAME_3_OFFSET - draw.Upper_Left();
|
|
InfoRenderer->Add_Quad( draw, uv );
|
|
|
|
uv.Set( FRAME_4_UV_UL, FRAME_4_UV_LR );
|
|
draw = uv;
|
|
uv.Scale( INFO_UV_SCALE );
|
|
draw += InfoBase + FRAME_4_OFFSET - draw.Upper_Left();
|
|
InfoRenderer->Add_Quad( draw, uv );
|
|
|
|
uv.Set( FRAME_5_UV_UL, FRAME_5_UV_LR );
|
|
draw = uv;
|
|
uv.Scale( INFO_UV_SCALE );
|
|
draw += InfoBase + FRAME_5_OFFSET - draw.Upper_Left();
|
|
InfoRenderer->Add_Quad( draw, uv );
|
|
|
|
uv.Set( FRAME_6_UV_UL, FRAME_6_UV_LR );
|
|
draw = uv;
|
|
uv.Scale( INFO_UV_SCALE );
|
|
draw += InfoBase + FRAME_6_OFFSET - draw.Upper_Left();
|
|
InfoRenderer->Add_Quad( draw, uv );
|
|
|
|
uv.Set( HEALTH_BACK_UV_UL, HEALTH_BACK_UV_LR );
|
|
uv.Scale( INFO_UV_SCALE );
|
|
draw.Set( HEALTH_BACK_UL, HEALTH_BACK_LR );
|
|
draw += InfoBase;
|
|
InfoRenderer->Add_Quad( draw, uv );
|
|
|
|
// Draw Health and Shield
|
|
Info_Update_Health_Shield();
|
|
|
|
if ( COMBAT_STAR ) {
|
|
|
|
if ( COMBAT_STAR->Has_Key( 1 ) ) {
|
|
uv.Set( KEY_1_UV_UL, KEY_1_UV_LR );
|
|
draw = uv;
|
|
uv.Scale( INFO_UV_SCALE );
|
|
draw += InfoBase + KEY_1_OFFSET - draw.Upper_Left();
|
|
InfoRenderer->Add_Quad( draw, uv );
|
|
}
|
|
|
|
if ( COMBAT_STAR->Has_Key( 2 ) ) {
|
|
uv.Set( KEY_2_UV_UL, KEY_2_UV_LR );
|
|
draw = uv;
|
|
uv.Scale( INFO_UV_SCALE );
|
|
draw += InfoBase + KEY_2_OFFSET - draw.Upper_Left();
|
|
InfoRenderer->Add_Quad( draw, uv );
|
|
}
|
|
|
|
if ( COMBAT_STAR->Has_Key( 3 ) ) {
|
|
uv.Set( KEY_3_UV_UL, KEY_3_UV_LR );
|
|
draw = uv;
|
|
uv.Scale( INFO_UV_SCALE );
|
|
draw += InfoBase + KEY_3_OFFSET - draw.Upper_Left();
|
|
InfoRenderer->Add_Quad( draw, uv );
|
|
}
|
|
}
|
|
|
|
#if 0
|
|
return;
|
|
|
|
uv.Set( TARGET_HEALTH_L_UV_UL, TARGET_HEALTH_L_UV_LR );
|
|
draw = uv;
|
|
uv.Scale( INFO_UV_SCALE );
|
|
draw += InfoBase + TARGET_HEALTH_OFFSET - draw.Upper_Left();
|
|
InfoRenderer->Add_Quad( draw, uv );
|
|
|
|
uv.Set( TARGET_HEALTH_R_UV_UL, TARGET_HEALTH_R_UV_LR );
|
|
draw = uv;
|
|
uv.Scale( INFO_UV_SCALE );
|
|
draw += InfoBase + TARGET_HEALTH_OFFSET - draw.Upper_Left() + Vector2( 0, 20 );
|
|
InfoRenderer->Add_Quad( draw, uv );
|
|
|
|
uv.Set( TARGET_NAME_UV_UL, TARGET_NAME_UV_LR );
|
|
draw = uv;
|
|
uv.Scale( INFO_UV_SCALE );
|
|
draw += InfoBase + TARGET_NAME_OFFSET - draw.Upper_Left();
|
|
InfoRenderer->Add_Quad( draw, uv );
|
|
|
|
|
|
uv.Set( GRADIENT_BLACK_UV_UL, GRADIENT_BLACK_UV_LR );
|
|
uv.Scale( INFO_UV_SCALE );
|
|
draw.Set( TIME_BACK_UL, TIME_BACK_LR );
|
|
draw += InfoBase;
|
|
InfoRenderer->Add_Quad( draw, uv );
|
|
|
|
uv.Set( TIME_CLOCK_UV_UL, TIME_CLOCK_UV_LR );
|
|
draw = uv;
|
|
uv.Scale( INFO_UV_SCALE );
|
|
draw += InfoBase + TIME_CLOCK_OFFSET - draw.Upper_Left();
|
|
InfoRenderer->Add_Quad( draw, uv );
|
|
|
|
uv.Set( WEAPON_BOX_UV_UL, WEAPON_BOX_UV_LR );
|
|
draw = uv;
|
|
uv.Scale( INFO_UV_SCALE );
|
|
draw += InfoBase + WEAPON_BOX_OFFSET - draw.Upper_Left();
|
|
InfoRenderer->Add_Quad( draw, uv );
|
|
|
|
uv.Set( POWER_OUT_ICON_UV_UL, POWER_OUT_ICON_UV_LR );
|
|
draw = uv;
|
|
uv.Scale( INFO_UV_SCALE );
|
|
draw += InfoBase + POWER_OUT_ICON_OFFSET - draw.Upper_Left();
|
|
InfoRenderer->Add_Quad( draw, uv );
|
|
|
|
uv.Set( REPAIR_ICON_UV_UL, REPAIR_ICON_UV_LR );
|
|
draw = uv;
|
|
uv.Scale( INFO_UV_SCALE );
|
|
draw += InfoBase + REPAIR_ICON_OFFSET - draw.Upper_Left();
|
|
InfoRenderer->Add_Quad( draw, uv );
|
|
|
|
uv.Set( GDI_ICON_UV_UL, GDI_ICON_UV_LR );
|
|
draw = uv;
|
|
uv.Scale( INFO_UV_SCALE );
|
|
draw += InfoBase + GDI_ICON_OFFSET - draw.Upper_Left();
|
|
InfoRenderer->Add_Quad( draw, uv );
|
|
|
|
uv.Set( NOD_ICON_UV_UL, NOD_ICON_UV_LR );
|
|
draw = uv;
|
|
uv.Scale( INFO_UV_SCALE );
|
|
draw += InfoBase + NOD_ICON_OFFSET - draw.Upper_Left();
|
|
InfoRenderer->Add_Quad( draw, uv );
|
|
|
|
uv.Set( NEUTRAL_ICON_UV_UL, NEUTRAL_ICON_UV_LR );
|
|
draw = uv;
|
|
uv.Scale( INFO_UV_SCALE );
|
|
draw += InfoBase + NEUTRAL_ICON_OFFSET - draw.Upper_Left();
|
|
InfoRenderer->Add_Quad( draw, uv );
|
|
|
|
// Radar
|
|
uv.Set( RADAR_STAR_UV_UL, RADAR_STAR_UV_LR );
|
|
draw = uv;
|
|
uv.Scale( INFO_UV_SCALE );
|
|
draw += InfoBase + RADAR_STAR_OFFSET - draw.Upper_Left();
|
|
InfoRenderer->Add_Quad( draw, uv );
|
|
|
|
uv.Set( RADAR_STAR_UV_UL, RADAR_STAR_UV_LR );
|
|
draw = uv;
|
|
uv.Scale( INFO_UV_SCALE );
|
|
draw += InfoBase + RADAR_STAR_OFFSET - draw.Upper_Left();
|
|
InfoRenderer->Add_Quad( draw, uv );
|
|
|
|
uv.Set( RADAR_SQUARE_UV_UL, RADAR_SQUARE_UV_LR );
|
|
draw = uv;
|
|
uv.Scale( INFO_UV_SCALE );
|
|
draw += InfoBase + RADAR_SQUARE_OFFSET - draw.Upper_Left();
|
|
InfoRenderer->Add_Quad( draw, uv );
|
|
|
|
uv.Set( RADAR_TRIANGLE_UV_UL, RADAR_TRIANGLE_UV_LR );
|
|
draw = uv;
|
|
uv.Scale( INFO_UV_SCALE );
|
|
draw += InfoBase + RADAR_TRIANGLE_OFFSET - draw.Upper_Left();
|
|
InfoRenderer->Add_Quad( draw, uv );
|
|
|
|
uv.Set( RADAR_CIRCLE_UV_UL, RADAR_CIRCLE_UV_LR );
|
|
draw = uv;
|
|
uv.Scale( INFO_UV_SCALE );
|
|
draw += InfoBase + RADAR_CIRCLE_OFFSET - draw.Upper_Left();
|
|
InfoRenderer->Add_Quad( draw, uv );
|
|
|
|
uv.Set( RADAR_BRACKET_UV_UL, RADAR_BRACKET_UV_LR );
|
|
draw = uv;
|
|
uv.Scale( INFO_UV_SCALE );
|
|
draw += InfoBase + RADAR_BRACKET_OFFSET - draw.Upper_Left();
|
|
InfoRenderer->Add_Quad( draw, uv );
|
|
|
|
uv.Set( RADAR_SWEEP_UV_UL, RADAR_SWEEP_UV_LR );
|
|
draw = uv;
|
|
uv.Scale( INFO_UV_SCALE );
|
|
draw += InfoBase + RADAR_SWEEP_OFFSET - draw.Upper_Left();
|
|
InfoRenderer->Add_Quad( draw, uv );
|
|
#endif
|
|
}
|
|
|
|
static void Info_Render( void )
|
|
{
|
|
InfoRenderer->Render();
|
|
InfoHealthCountRenderer->Render();
|
|
InfoShieldCountRenderer->Render();
|
|
}
|
|
|
|
|
|
/*
|
|
** OLD HUD STUFF
|
|
*/
|
|
static bool _HUDEnabled = true;
|
|
static bool _HUDInited = false;
|
|
|
|
#ifdef ATI_DEMO_HACK
|
|
typedef enum {
|
|
DEMO_HUD_IMAGE=0,
|
|
DEMO_HUD_IMAGE2,
|
|
NUM_RENDER_IMAGES,
|
|
};
|
|
#else
|
|
typedef enum {
|
|
RETICLE = 0,
|
|
RETICLE_HIT,
|
|
ACTION_STATUSBAR_RENDERER,
|
|
DEMO_HUD_IMAGE,
|
|
DEMO_HUD_IMAGE2,
|
|
NUM_RENDER_IMAGES,
|
|
};
|
|
#endif
|
|
Render2DClass * RenderImages[ NUM_RENDER_IMAGES ];
|
|
|
|
/*
|
|
**
|
|
*/
|
|
static bool Is_HUD_Displayed( void );
|
|
|
|
/*
|
|
**
|
|
*/
|
|
void HUDClass::Init(bool render_available)
|
|
{
|
|
for( int i = 0; i < NUM_RENDER_IMAGES; i++ ) {
|
|
RenderImages[i] = NULL;
|
|
}
|
|
|
|
// Reticles
|
|
#ifndef ATI_DEMO_HACK
|
|
RenderImages[RETICLE] = new Render2DClass();
|
|
RenderImages[RETICLE]->Set_Texture( "HD_reticle.tga" );
|
|
RenderImages[RETICLE]->Set_Hidden( true );
|
|
RenderImages[RETICLE_HIT] = new Render2DClass();
|
|
RenderImages[RETICLE_HIT]->Set_Texture( "HD_reticle_hit.tga" );
|
|
RenderImages[RETICLE_HIT]->Set_Hidden( true );
|
|
// Action Status Bar (arming/disarming explosives, etc)
|
|
RenderImages[ACTION_STATUSBAR_RENDERER] = new Render2DClass();
|
|
RenderImages[ACTION_STATUSBAR_RENDERER]->Set_Coordinate_Range( Render2DClass::Get_Screen_Resolution() );
|
|
#else
|
|
RectClass rect=Render2DClass::Get_Screen_Resolution();
|
|
|
|
RenderImages[DEMO_HUD_IMAGE] = new Render2DClass();
|
|
RenderImages[DEMO_HUD_IMAGE]->Reset();
|
|
RenderImages[DEMO_HUD_IMAGE]->Set_Texture( "renegade_demo.tga" );
|
|
RenderImages[DEMO_HUD_IMAGE]->Set_Hidden( false );
|
|
RenderImages[DEMO_HUD_IMAGE]->Set_Coordinate_Range( Render2DClass::Get_Screen_Resolution() );
|
|
RenderImages[DEMO_HUD_IMAGE]->Add_Quad( RectClass( float(8),float(-8),float(256+8),float(128-8)), RectClass(0.0f,0.0f,1.0f,0.5f),0xffffffff);
|
|
RenderImages[DEMO_HUD_IMAGE2] = new Render2DClass();
|
|
RenderImages[DEMO_HUD_IMAGE2]->Reset();
|
|
RenderImages[DEMO_HUD_IMAGE2]->Set_Texture( "renegade_demo.tga" );
|
|
RenderImages[DEMO_HUD_IMAGE2]->Set_Hidden( false );
|
|
RenderImages[DEMO_HUD_IMAGE2]->Set_Coordinate_Range( Render2DClass::Get_Screen_Resolution() );
|
|
RenderImages[DEMO_HUD_IMAGE2]->Add_Quad( RectClass( rect.Right+float(-256-8),rect.Bottom+float(-128+8),rect.Right+float(-8),rect.Bottom+float(8)), RectClass(0.0f,0.5f,1.0f,1.0f),0xffffffff);
|
|
#endif
|
|
|
|
if (render_available) {
|
|
_HUDEnabled = true;
|
|
|
|
SniperHUDClass::Init();
|
|
Powerup_Init();
|
|
Weapon_Init();
|
|
Weapon_Chart_Init();
|
|
Info_Init();
|
|
Damage_Init();
|
|
Target_Init();
|
|
//Score_Init();
|
|
Objective_Init();
|
|
|
|
HUD_Help_Text_Init();
|
|
|
|
_HUDInited = true;
|
|
}
|
|
}
|
|
|
|
/*
|
|
**
|
|
*/
|
|
void HUDClass::Shutdown()
|
|
{
|
|
if (_HUDInited) {
|
|
|
|
Objective_Shutdown();
|
|
//Score_Shutdown();
|
|
Target_Shutdown();
|
|
Damage_Shutdown();
|
|
Info_Shutdown();
|
|
Weapon_Chart_Shutdown();
|
|
Weapon_Shutdown();
|
|
Powerup_Shutdown();
|
|
HUD_Help_Text_Shutdown();
|
|
SniperHUDClass::Shutdown();
|
|
|
|
for( int i = 0; i < NUM_RENDER_IMAGES; i++ ) {
|
|
if ( RenderImages[i] ) {
|
|
delete RenderImages[i];
|
|
RenderImages[i] = NULL;
|
|
}
|
|
}
|
|
|
|
_HUDInited = false;
|
|
}
|
|
}
|
|
|
|
void HUDClass::Reset( void )
|
|
{
|
|
Powerup_Reset();
|
|
Damage_Reset();
|
|
Weapon_Reset();
|
|
}
|
|
|
|
void HUDClass::Render()
|
|
{
|
|
WWPROFILE( "HUD Render" );
|
|
|
|
#ifdef ATI_DEMO_HACK
|
|
RenderImages[DEMO_HUD_IMAGE]->Render();
|
|
RenderImages[DEMO_HUD_IMAGE2]->Render();
|
|
#else
|
|
if ( COMBAT_CAMERA && COMBAT_CAMERA->Draw_Sniper() ) {
|
|
SniperHUDClass::Render();
|
|
}
|
|
|
|
// Only render if Combat is active, and Menu is not, and we have a star who is not sniping
|
|
if ( Is_HUD_Displayed() ) {
|
|
|
|
Powerup_Render();
|
|
Weapon_Render();
|
|
Weapon_Chart_Render();
|
|
Info_Render();
|
|
Damage_Render();
|
|
Target_Render();
|
|
//Score_Render();
|
|
HUD_Help_Text_Render();
|
|
Objective_Render();
|
|
RadarManager::Render();
|
|
|
|
for( int i = 0; i < NUM_RENDER_IMAGES; i++ ) {
|
|
if ( RenderImages[i] ) {
|
|
RenderImages[i]->Render();
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
static bool Is_HUD_Displayed( void )
|
|
{
|
|
return ( _HUDEnabled &&
|
|
COMBAT_STAR &&
|
|
!COMBAT_STAR->Is_Dead() &&
|
|
!COMBAT_STAR->Is_Destroyed() );
|
|
}
|
|
|
|
/*
|
|
** called each time through the main loop
|
|
*/
|
|
void HUDClass::Think()
|
|
{
|
|
WWPROFILE( "HUD Think" );
|
|
|
|
#ifndef ATI_DEMO_HACK
|
|
if ( COMBAT_CAMERA && COMBAT_CAMERA->Draw_Sniper() ) {
|
|
SniperHUDClass::Update();
|
|
}
|
|
|
|
if ( !Is_HUD_Displayed() ) {
|
|
return;
|
|
}
|
|
|
|
if ( HUDInfo::Display_Action_Status_Bar() ) {
|
|
|
|
RenderImages[ACTION_STATUSBAR_RENDERER]->Set_Hidden( false );
|
|
RenderImages[ACTION_STATUSBAR_RENDERER]->Reset();
|
|
RenderImages[ACTION_STATUSBAR_RENDERER]->Enable_Texturing( false );
|
|
|
|
//
|
|
// Plot the rectangle
|
|
//
|
|
const RectClass &screen_rect = Render2DClass::Get_Screen_Resolution();
|
|
RectClass status_bar_rect (0.4F, 0.95F, 0.6F, 0.98F);
|
|
status_bar_rect.Left = int(status_bar_rect.Left * screen_rect.Width());
|
|
status_bar_rect.Right = int(status_bar_rect.Right * screen_rect.Width());
|
|
status_bar_rect.Top = int(status_bar_rect.Top * screen_rect.Height());
|
|
status_bar_rect.Bottom = int(status_bar_rect.Bottom * screen_rect.Height());
|
|
RenderImages[ACTION_STATUSBAR_RENDERER]->Add_Line( status_bar_rect.Upper_Left (), status_bar_rect.Upper_Right (), 1, 0xFFFFFFFF );
|
|
RenderImages[ACTION_STATUSBAR_RENDERER]->Add_Line( status_bar_rect.Upper_Right (), status_bar_rect.Lower_Right (), 1, 0xFFFFFFFF );
|
|
RenderImages[ACTION_STATUSBAR_RENDERER]->Add_Line( status_bar_rect.Lower_Right (), status_bar_rect.Lower_Left (), 1, 0xFFFFFFFF );
|
|
RenderImages[ACTION_STATUSBAR_RENDERER]->Add_Line( status_bar_rect.Lower_Left (), status_bar_rect.Upper_Left (), 1, 0xFFFFFFFF );
|
|
|
|
//
|
|
// Deflate the rectangle
|
|
//
|
|
status_bar_rect.Right -= 1.0F;
|
|
status_bar_rect.Bottom -= 1.0F;
|
|
|
|
//
|
|
// Plot the status rectangle
|
|
//
|
|
float width = status_bar_rect.Width() * HUDInfo::Get_Action_Status_Value();
|
|
status_bar_rect.Right = status_bar_rect.Left + int(width);
|
|
DWORD color = VRGB_TO_INT32( Vector3( 1.0F, 0.25F, 0 ) );
|
|
RenderImages[ACTION_STATUSBAR_RENDERER]->Add_Quad( status_bar_rect, color );
|
|
|
|
} else {
|
|
RenderImages[ACTION_STATUSBAR_RENDERER]->Set_Hidden( true );
|
|
}
|
|
|
|
SmartGameObj * star = COMBAT_STAR;
|
|
if ( COMBAT_STAR->Get_Vehicle() ) {
|
|
star = COMBAT_STAR->Get_Vehicle();
|
|
}
|
|
|
|
Info_Update();
|
|
Powerup_Update();
|
|
Weapon_Update();
|
|
Weapon_Chart_Update();
|
|
Damage_Update();
|
|
Target_Update();
|
|
//Score_Update();
|
|
Objective_Update();
|
|
|
|
// Radar
|
|
Matrix3D tm;
|
|
star->Get_Transform().Get_Inverse( tm );
|
|
if ( star->As_VehicleGameObj() && COMBAT_CAMERA && !COMBAT_CAMERA->Is_2D_Targeting() ) {
|
|
// Make a tm facing target
|
|
Matrix3D gun;
|
|
gun.Obj_Look_At( star->Get_Transform().Get_Translation(), star->Get_Targeting_Pos(), 0 );
|
|
gun.Get_Inverse( tm );
|
|
}
|
|
|
|
PhysicalGameObj * obj = NULL;
|
|
if ( HUDInfo::Get_Info_Object() ) {
|
|
obj = HUDInfo::Get_Info_Object()->As_PhysicalGameObj();
|
|
}
|
|
RadarManager::Set_Bracket_Object( obj );
|
|
Vector2 radar_center = InfoBase + RADAR_CENTER_OFFSET;
|
|
RadarManager::Update( tm, radar_center );
|
|
|
|
unsigned long reticle_color = HUDGlobalSettingsDef::Get_Instance()->Get_No_Relation_Color().Convert_To_ARGB();
|
|
|
|
if ( HUDInfo::Get_Weapon_Target_Object() != NULL ) {
|
|
reticle_color = HUDGlobalSettingsDef::Get_Instance()->Get_Friendly_Color().Convert_To_ARGB();
|
|
PhysicalGameObj * pgo = HUDInfo::Get_Weapon_Target_Object()->As_PhysicalGameObj();
|
|
if ( pgo && pgo->Is_Enemy( star ) ) {
|
|
reticle_color = HUDGlobalSettingsDef::Get_Instance()->Get_Enemy_Color().Convert_To_ARGB();
|
|
}
|
|
}
|
|
|
|
WeaponClass * weapon = star->Get_Weapon();
|
|
if ( weapon ) {
|
|
if ( weapon->Is_Reloading() || weapon->Is_Switching() || !weapon->Is_Loaded() ) {
|
|
reticle_color = 0xFFFFFF00; // yellow
|
|
}
|
|
}
|
|
|
|
Vector2 reticle_offset = COMBAT_CAMERA->Get_Camera_Target_2D_Offset();
|
|
RenderImages[RETICLE]->Reset();
|
|
RenderImages[RETICLE]->Add_Quad( RectClass( reticle_offset.X - RETICLE_WIDTH/2, reticle_offset.Y - RETICLE_HEIGHT/2, reticle_offset.X + RETICLE_WIDTH/2, reticle_offset.Y + RETICLE_HEIGHT/2 ), reticle_color);
|
|
|
|
//RenderImages[RETICLE]->Set_Hidden( false );
|
|
//TSS092401
|
|
if ( CombatManager::Is_Gameplay_Permitted() ) {
|
|
RenderImages[RETICLE]->Set_Hidden( false );
|
|
} else {
|
|
RenderImages[RETICLE]->Set_Hidden( true );
|
|
}
|
|
|
|
//TSS092401 if ( weapon ) {
|
|
if ( CombatManager::Is_Gameplay_Permitted() && (weapon != NULL) && CombatManager::Is_Hit_Reticle_Enabled() ) {
|
|
WWPROFILE( "Reticle" );
|
|
Vector3 pos3d = HUDInfo::Get_Weapon_Target_Position();
|
|
Vector3 reticle_hit_offset;
|
|
COMBAT_CAMERA->Project( reticle_hit_offset, pos3d );
|
|
// weapon_hitting = HUDInfo::Get_Weapon_Target_Object() != NULL;
|
|
RenderImages[RETICLE_HIT]->Reset();
|
|
RenderImages[RETICLE_HIT]->Add_Quad( RectClass( reticle_hit_offset.X - RETICLE_WIDTH/2, reticle_hit_offset.Y - RETICLE_HEIGHT/2, reticle_hit_offset.X + RETICLE_WIDTH/2, reticle_hit_offset.Y + RETICLE_HEIGHT/2 ), reticle_color);
|
|
RenderImages[RETICLE_HIT]->Set_Hidden( false );
|
|
} else {
|
|
RenderImages[RETICLE_HIT]->Set_Hidden( true );
|
|
}
|
|
|
|
|
|
#if 0
|
|
// Display points
|
|
if ( _HUDTimer > 0 ) {
|
|
WWPROFILE( "Points" );
|
|
_HUDTimer -= TimeManager::Get_Frame_Seconds();
|
|
|
|
StringClass pointstring;
|
|
int points = _HUDPoints;
|
|
if ( points ) {
|
|
Vector2 position = Render2DClass::Get_Screen_Resolution().Lower_Right();
|
|
position /= 2;
|
|
float scale = WWMath::Clamp( 2 * _HUDTimer / HUD_POINTS_TIME, 0, 1 );
|
|
position.Y *= 0.3f + (scale/2);
|
|
pointstring.Format( "%d", points );
|
|
((Render2DTextClass *)RenderImages[TEXT_RENDERER])->Set_Location( position );
|
|
|
|
Font3DInstanceClass * font = ((Render2DTextClass *)RenderImages[TEXT_RENDERER])->Peek_Font();
|
|
if ( font ) {
|
|
font->Set_Scale( 2 + (scale * 3) );
|
|
position.X -= font->String_Width( pointstring ) / 2;
|
|
position.Y -= font->Char_Height() / 2;
|
|
((Render2DTextClass *)RenderImages[TEXT_RENDERER])->Set_Location( position );
|
|
((Render2DTextClass *)RenderImages[TEXT_RENDERER])->Draw_Text( pointstring, COLOR( scale ) );
|
|
font->Set_Scale( 1 );
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
#endif // ATI_DEMO_HACK
|
|
}
|
|
|
|
void HUDClass::Toggle_Hide_Points( void )
|
|
{
|
|
// _HUDHidePoints = !_HUDHidePoints;
|
|
}
|
|
|
|
void HUDClass::Display_Points( float points )
|
|
{
|
|
/* if ( !_HUDHidePoints ) {
|
|
_HUDPoints = points;
|
|
_HUDTimer = HUD_POINTS_TIME;
|
|
}*/
|
|
}
|
|
|
|
bool HUDClass::Is_Enabled( void )
|
|
{
|
|
return _HUDEnabled;
|
|
}
|
|
|
|
void HUDClass::Enable( bool enable )
|
|
{
|
|
_HUDEnabled = enable;
|
|
}
|
|
|
|
#define SNIPER_AMMO_UV 3, 139,79,191
|
|
#define SNIPER_AMMO_OFFSET -10,-4
|
|
#define NUKE_UV 193,187,244,246
|
|
#define NUKE_OFFSET 10,-4
|
|
#define ION_UV 101,196,164,246
|
|
#define ION_OFFSET 10,-4
|
|
|
|
void HUDClass::Add_Powerup_Weapon( int id, int rounds )
|
|
{
|
|
const WeaponDefinitionClass * def = WeaponManager::Find_Weapon_Definition( id );
|
|
if ( def ) {
|
|
if ( !def->IconTextureName.Is_Empty() ) {
|
|
Powerup_Add( TranslateDBClass::Get_String( def->IconNameID ), rounds,
|
|
def->IconTextureName, def->IconTextureUV, def->IconOffset );
|
|
}
|
|
}
|
|
}
|
|
|
|
void HUDClass::Add_Powerup_Ammo( int id, int rounds )
|
|
{
|
|
Add_Powerup_Weapon( id, rounds );
|
|
#if 0
|
|
const WeaponDefinitionClass * wdef = WeaponManager::Find_Weapon_Definition( id );
|
|
if ( wdef ) {
|
|
const AmmoDefinitionClass * def = WeaponManager::Find_Ammo_Definition( wdef->PrimaryAmmoDefID );
|
|
if ( def ) {
|
|
if ( !def->IconTextureName.Is_Empty() ) {
|
|
Powerup_Add( TranslateDBClass::Get_String( def->IconNameID ), rounds,
|
|
def->IconTextureName, def->IconTextureUV, def->IconOffset );
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void HUDClass::Add_Shield_Grant( float strength )
|
|
{
|
|
const char * texture_name = "hud_armor3.tga";
|
|
if ( strength > 75 ) {
|
|
texture_name = "hud_armor1.tga";
|
|
} else if ( strength > 30 ) {
|
|
texture_name = "hud_armor2.tga";
|
|
}
|
|
Powerup_Add( TranslateDBClass::Get_String(IDS_Power_up_Armor_00), (int)strength, texture_name, RectClass( 0,0,64,64 ), Vector2( 10,40 ) );
|
|
}
|
|
|
|
void HUDClass::Add_Health_Grant( float amount )
|
|
{
|
|
const char * texture_name = "hud_health1.tga";
|
|
if ( amount > 75 ) {
|
|
texture_name = "hud_health3.tga";
|
|
} else if ( amount > 30 ) {
|
|
texture_name = "hud_health2.tga";
|
|
}
|
|
Powerup_Add( TranslateDBClass::Get_String(IDS_Power_up_Health_00), (int)amount, texture_name, RectClass( 0,0,64,64 ), Vector2( 10,40 ) );
|
|
}
|
|
|
|
void HUDClass::Add_Shield_Upgrade_Grant( float strength )
|
|
{
|
|
Powerup_Add( TranslateDBClass::Get_String(IDS_Power_up_Armor_Upgrade), (int)strength, "hud_armedal.tga", RectClass( 0,0,64,64 ), Vector2( 10,40 ), false );
|
|
}
|
|
|
|
void HUDClass::Add_Health_Upgrade_Grant( float amount )
|
|
{
|
|
Powerup_Add( TranslateDBClass::Get_String(IDS_Power_up_Health_Upgrade), (int)amount, "hud_hemedal.tga", RectClass( 0,0,64,64 ), Vector2( 10,40 ), false );
|
|
}
|
|
|
|
void HUDClass::Add_Key_Grant( int key )
|
|
{
|
|
const char * texture_name = "hud_keycard_green.tga";
|
|
if ( key == 3 ) {
|
|
texture_name = "hud_keycard_red.tga";
|
|
} else if ( key == 2 ) {
|
|
texture_name = "hud_keycard_yellow.tga";
|
|
}
|
|
Powerup_Add( TranslateDBClass::Get_String(IDS_Power_up_SecurityCard), 0, texture_name, RectClass( 0,0,64,64 ), Vector2( 10,40 ), false );
|
|
}
|
|
|
|
void HUDClass::Add_Objective( int type )
|
|
{
|
|
if ( type == ObjectiveManager::TYPE_PRIMARY ) {
|
|
Powerup_Add( TranslateDBClass::Get_String(IDS_Enc_Obj_Priority_0_Primary), 0, "p_eva1.tga", RectClass( 0,0,64,64 ), Vector2( 10,40 ), false );
|
|
} else if ( type == ObjectiveManager::TYPE_SECONDARY ) {
|
|
Powerup_Add( TranslateDBClass::Get_String(IDS_Enc_Obj_Priority_0_Secondary), 0, "p_eva2.tga", RectClass( 0,0,64,64 ), Vector2( 10,40 ), false );
|
|
}
|
|
}
|
|
|
|
void HUDClass::Add_Data_Link( void )
|
|
{
|
|
int cur = TimeManager::Get_Total_Seconds() * 2.0f;
|
|
static int last = 0;
|
|
// Don't accept too fast;
|
|
if ( cur == last ) {
|
|
return;
|
|
}
|
|
last = cur;
|
|
Powerup_Add( TranslateDBClass::Get_String(IDS_Power_up_DataDisc_01), 0, "hud_cd_rom.tga", RectClass( 0,0,64,64 ), Vector2( 10,40 ), false );
|
|
}
|
|
|
|
void HUDClass::Add_Map_Reveal( void )
|
|
{
|
|
Add_Data_Link();
|
|
// Powerup_Add( TranslateDBClass::Get_String(IDS_Power_up_DataDisc_01), 0, "hud_cd_rom.tga", RectClass( 0,0,64,64 ), Vector2( 10,40 ), false );
|
|
// Powerup_Add( TranslateDBClass::Get_String(IDS_Enc_Pow_Bonus_Map_Name), 0, "hud_cd_rom.tga", RectClass( 0,0,64,64 ), Vector2( 10,40 ), false );
|
|
}
|
|
|
|
/*
|
|
**
|
|
*/
|
|
enum {
|
|
CHUNKID_VARIABLES = 1117011622,
|
|
CHUNKID_MARKER_ENTRY,
|
|
|
|
MICROCHUNKID_ENABLED = 1,
|
|
};
|
|
|
|
/*
|
|
**
|
|
*/
|
|
bool HUDClass::Save( ChunkSaveClass &csave )
|
|
{
|
|
csave.Begin_Chunk( CHUNKID_VARIABLES );
|
|
WRITE_MICRO_CHUNK( csave, MICROCHUNKID_ENABLED, _HUDEnabled );
|
|
csave.End_Chunk();
|
|
|
|
return true;
|
|
}
|
|
|
|
bool HUDClass::Load( ChunkLoadClass &cload )
|
|
{
|
|
while (cload.Open_Chunk()) {
|
|
switch(cload.Cur_Chunk_ID()) {
|
|
|
|
case CHUNKID_VARIABLES:
|
|
while (cload.Open_Micro_Chunk()) {
|
|
switch(cload.Cur_Micro_Chunk_ID()) {
|
|
READ_MICRO_CHUNK( cload, MICROCHUNKID_ENABLED, _HUDEnabled );
|
|
default:
|
|
Debug_Say(("Unhandled Chunk:%d File:%s Line:%d\r\n",cload.Cur_Chunk_ID(),__FILE__,__LINE__));
|
|
break;
|
|
}
|
|
cload.Close_Micro_Chunk();
|
|
}
|
|
break;
|
|
|
|
default:
|
|
Debug_Say(("Unhandled Chunk:%d File:%s Line:%d\r\n",cload.Cur_Chunk_ID(),__FILE__,__LINE__));
|
|
break;
|
|
|
|
}
|
|
cload.Close_Chunk();
|
|
}
|
|
return true;
|
|
}
|