Killfeed with images (placeholders for now)
@ -10,7 +10,7 @@ if(RESDIR_DEFINED)
|
||||
${RESDIR}pak999-References.pak
|
||||
DESTINATION bin/Resources)
|
||||
|
||||
file(GLOB_RECURSE RESOURCES Shaders/* Scripts/*)
|
||||
file(GLOB_RECURSE RESOURCES Shaders/* Scripts/* Icons/* Killfeed/*)
|
||||
foreach(FILE ${RESOURCES})
|
||||
string(REPLACE ${CMAKE_CURRENT_SOURCE_DIR} ${RESDIR} TARGETFILE ${FILE})
|
||||
get_filename_component(TARGETDIR ${TARGETFILE} PATH)
|
||||
@ -21,3 +21,5 @@ endif()
|
||||
|
||||
install(DIRECTORY "Scripts" DESTINATION bin/Resources)
|
||||
install(DIRECTORY "Shaders" DESTINATION bin/Resources)
|
||||
install(DIRECTORY "Killfeed" DESTINATION bin/Resources)
|
||||
install(DIRECTORY "Icons" DESTINATION bin/Resources)
|
||||
|
BIN
Resources/Killfeed/a-Rifle.png
Normal file
After Width: | Height: | Size: 469 B |
BIN
Resources/Killfeed/b-SMG.png
Normal file
After Width: | Height: | Size: 596 B |
BIN
Resources/Killfeed/c-Shotgun.png
Normal file
After Width: | Height: | Size: 639 B |
BIN
Resources/Killfeed/d-Headshot.png
Normal file
After Width: | Height: | Size: 712 B |
BIN
Resources/Killfeed/e-Melee.png
Normal file
After Width: | Height: | Size: 567 B |
BIN
Resources/Killfeed/f-Grenade.png
Normal file
After Width: | Height: | Size: 575 B |
BIN
Resources/Killfeed/g-Falling.png
Normal file
After Width: | Height: | Size: 523 B |
BIN
Resources/Killfeed/h-Teamchange.png
Normal file
After Width: | Height: | Size: 715 B |
BIN
Resources/Killfeed/i-Classchange.png
Normal file
After Width: | Height: | Size: 735 B |
@ -35,6 +35,20 @@ namespace spades {
|
||||
client(cli), renderer(rend),
|
||||
font(fnt), killfeed(killfeed){
|
||||
firstY = 0.f;
|
||||
mKillImages.push_back( renderer->RegisterImage("Killfeed/a-Rifle.png") );
|
||||
mKillImages.push_back( renderer->RegisterImage("Killfeed/b-SMG.png") );
|
||||
mKillImages.push_back( renderer->RegisterImage("Killfeed/c-Shotgun.png") );
|
||||
mKillImages.push_back( renderer->RegisterImage("Killfeed/d-Headshot.png") );
|
||||
mKillImages.push_back( renderer->RegisterImage("Killfeed/e-Melee.png") );
|
||||
mKillImages.push_back( renderer->RegisterImage("Killfeed/f-Grenade.png") );
|
||||
mKillImages.push_back( renderer->RegisterImage("Killfeed/g-Falling.png") );
|
||||
mKillImages.push_back( renderer->RegisterImage("Killfeed/h-Teamchange.png") );
|
||||
mKillImages.push_back( renderer->RegisterImage("Killfeed/i-Classchange.png") );
|
||||
for( size_t n = 0; n < mKillImages.size(); ++n ) {
|
||||
if( mKillImages[n]->GetHeight() > GetLineHeight() ) {
|
||||
SPRaise( "Kill image (%d) height too big ", n );
|
||||
}
|
||||
}
|
||||
}
|
||||
ChatWindow::~ChatWindow(){}
|
||||
|
||||
@ -53,7 +67,30 @@ namespace spades {
|
||||
static bool isWordChar(char c){
|
||||
return isalnum(c) || c == '\'';
|
||||
}
|
||||
|
||||
|
||||
std::string ChatWindow::killImage( int type, int weapon )
|
||||
{
|
||||
std::string tmp = "xx";
|
||||
tmp[0] = 7;
|
||||
switch( type ) {
|
||||
case KillTypeWeapon:
|
||||
switch( weapon ) {
|
||||
case 0: case 1: case 2:
|
||||
tmp[1] = 'a' + weapon;
|
||||
break;
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
case KillTypeHeadshot: case KillTypeMelee: case KillTypeGrenade:
|
||||
case KillTypeFall: case KillTypeTeamChange: case KillTypeClassChange:
|
||||
tmp[1] = 'a' + 2 + type;
|
||||
break;
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void ChatWindow::AddMessage(const std::string &msg){
|
||||
SPADES_MARK_FUNCTION();
|
||||
|
||||
@ -81,12 +118,10 @@ namespace spades {
|
||||
if(wordStart != std::string::npos && wordStart != str.size()){
|
||||
// adding a part of word.
|
||||
// do word wrapping
|
||||
|
||||
std::string s = msg.substr(wordStart, i - wordStart + 1);
|
||||
float nw = font->Measure(s).x;
|
||||
if(nw <= maxW){
|
||||
// word wrap succeeds
|
||||
|
||||
w = nw;
|
||||
x = w;
|
||||
h += lh;
|
||||
@ -201,7 +236,14 @@ namespace spades {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
IImage* ChatWindow::imageForIndex( char index )
|
||||
{
|
||||
int real = index - 'a';
|
||||
if( real >= 0 && real < mKillImages.size() ) {
|
||||
return mKillImages[real];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ChatWindow::Draw() {
|
||||
SPADES_MARK_FUNCTION();
|
||||
@ -232,8 +274,19 @@ namespace spades {
|
||||
if(msg[i] == 13 || msg[i] == 10){
|
||||
tx = 0.f; ty += lHeight;
|
||||
}else if(msg[i] <= MsgColorMax){
|
||||
color = GetColor(msg[i]);
|
||||
color.w *= fade;
|
||||
if( msg[i] == MsgImage ) {
|
||||
IImage* kill = NULL;
|
||||
if( i+1 < msg.size() && (kill = imageForIndex(msg[i+1])) ) {
|
||||
renderer->DrawImage( kill, MakeVector2( tx + winX, ty + winY ) );
|
||||
tx += kill->GetWidth();
|
||||
++i;
|
||||
} else {
|
||||
SPRaise( "Invalid killfeed image index" );
|
||||
}
|
||||
} else {
|
||||
color = GetColor(msg[i]);
|
||||
color.w *= fade;
|
||||
}
|
||||
}else{
|
||||
ch[0] = msg[i];
|
||||
font->DrawShadow(ch, MakeVector2(tx + winX, ty + winY), 1.f, color, shadowColor);
|
||||
|
@ -22,12 +22,13 @@
|
||||
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include "../Core/Math.h"
|
||||
#include <Core/Math.h>
|
||||
|
||||
namespace spades {
|
||||
namespace client {
|
||||
class IRenderer;
|
||||
class IFont;
|
||||
class IImage;
|
||||
class Client;
|
||||
|
||||
static const char MsgColorTeam1 = 1;
|
||||
@ -38,6 +39,7 @@ namespace spades {
|
||||
static const char MsgColorGreen = 5;
|
||||
static const char MsgColorSysInfo = MsgColorGreen;
|
||||
static const char MsgColorRestore = 6;
|
||||
static const char MsgImage = 7;
|
||||
static const char MsgColorMax = 9;
|
||||
|
||||
class ChatWindow {
|
||||
@ -64,7 +66,8 @@ namespace spades {
|
||||
float GetLineHeight();
|
||||
|
||||
Vector4 GetColor(char);
|
||||
|
||||
std::vector<IImage*> mKillImages;
|
||||
IImage* imageForIndex( char index );
|
||||
public:
|
||||
ChatWindow(Client *, IRenderer* rend, IFont *font, bool killfeed);
|
||||
~ChatWindow();
|
||||
@ -72,6 +75,7 @@ namespace spades {
|
||||
void AddMessage(const std::string&);
|
||||
static std::string ColoredMessage(const std::string&, char);
|
||||
static std::string TeamColorMessage(const std::string&, int);
|
||||
static std::string killImage( int killType, int weapon );
|
||||
|
||||
void Update(float dt);
|
||||
void Draw();
|
||||
|
@ -3610,29 +3610,8 @@ namespace spades {
|
||||
ff = false;
|
||||
|
||||
cause = " [";
|
||||
switch(kt){
|
||||
case KillTypeClassChange:
|
||||
cause += "Weapon Change";
|
||||
break;
|
||||
case KillTypeFall:
|
||||
cause += "Fall";
|
||||
break;
|
||||
case KillTypeGrenade:
|
||||
cause += "Grenade";
|
||||
break;
|
||||
case KillTypeHeadshot:
|
||||
cause += "Headshot";
|
||||
break;
|
||||
case KillTypeMelee:
|
||||
cause += "Spade";
|
||||
break;
|
||||
case KillTypeTeamChange:
|
||||
cause += "Team Change";
|
||||
break;
|
||||
case KillTypeWeapon:
|
||||
cause += killer->GetWeapon()->GetName();
|
||||
break;
|
||||
}
|
||||
Weapon* w = killer ? killer->GetWeapon() : NULL; //only used in case of KillTypeWeapon
|
||||
cause += ChatWindow::killImage( kt, w ? w->GetWeaponType() : RIFLE_WEAPON );
|
||||
cause += "] ";
|
||||
|
||||
if(ff)
|
||||
|
@ -1,10 +1,14 @@
|
||||
#include <OpenSpades.h>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <Client/IRenderer.h>
|
||||
#include <Client/IImage.h>
|
||||
#include <Client/IFont.h>
|
||||
#include <Client/FontData.h>
|
||||
#include <Core/Settings.h>
|
||||
#include <Client/ChatWindow.h>
|
||||
#include <Client/PhysicsConstants.h>
|
||||
#include <Imports/SDL.h>
|
||||
|
||||
|
||||
SPADES_SETTING(cg_fov, "68");
|
||||
@ -15,7 +19,79 @@ spades::client::Quake3Font* bigTextFont = NULL;
|
||||
spades::client::Quake3Font* orbitronFont = NULL;
|
||||
|
||||
spades::Handle<spades::client::IImage> whiteImage;
|
||||
spades::client::ChatWindow* chatWindow;
|
||||
spades::client::ChatWindow* killfeedWindow;
|
||||
|
||||
const char* weapName( int idx )
|
||||
{
|
||||
switch( idx ) {
|
||||
case RIFLE_WEAPON: return "Rifle";
|
||||
case SMG_WEAPON: return "SMG";
|
||||
case SHOTGUN_WEAPON: return "Shotgun";
|
||||
default: return "-";
|
||||
}
|
||||
}
|
||||
|
||||
const char* playName( int idx )
|
||||
{
|
||||
switch( idx ) {
|
||||
case 0: return "PlayerGreen";
|
||||
case 1: return "PlayerBlue";
|
||||
case 2: return "PlayerYellow";
|
||||
default: return "-";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void addKill()
|
||||
{
|
||||
int team1 = rand() % 3;
|
||||
int team2 = rand() % 3;
|
||||
std::stringstream ss;
|
||||
ss << spades::client::ChatWindow::TeamColorMessage(playName(team1), team1);
|
||||
bool ff = team1 == team2;
|
||||
bool wasSelf = !(rand() % 10);
|
||||
if( wasSelf ) {
|
||||
ff = false;
|
||||
}
|
||||
|
||||
std::string cause = " [";
|
||||
int killNum = rand() % 8;
|
||||
killNum = killNum > KillTypeClassChange ? 0 : killNum; //we want 2 extra, because we have 3 weapons.
|
||||
cause += spades::client::ChatWindow::killImage( (KillType)killNum, rand() % 3 );
|
||||
cause += "] ";
|
||||
ss << (ff ? spades::client::ChatWindow::ColoredMessage(cause, spades::client::MsgColorRed) : cause);
|
||||
|
||||
if(!wasSelf){
|
||||
ss << spades::client::ChatWindow::TeamColorMessage(playName(team2), team2);
|
||||
}
|
||||
killfeedWindow->AddMessage(ss.str());
|
||||
killNum++;
|
||||
}
|
||||
|
||||
void addChat()
|
||||
{
|
||||
std::stringstream ss;
|
||||
int idx = rand() % 5;
|
||||
switch( idx )
|
||||
{
|
||||
case 0: case 1: case 2:
|
||||
ss << "[Global] " << spades::client::ChatWindow::TeamColorMessage( "Deuce", idx) << ": Some chat";
|
||||
break;
|
||||
case 3:
|
||||
ss << spades::client::ChatWindow::ColoredMessage("Screenshot saved: ", spades::client::MsgColorSysInfo);
|
||||
break;
|
||||
case 4:
|
||||
ss << spades::client::ChatWindow::ColoredMessage("Screenshot failed: ", spades::client::MsgColorRed);
|
||||
break;
|
||||
}
|
||||
chatWindow->AddMessage( ss.str() );
|
||||
}
|
||||
|
||||
|
||||
Uint32 ot = 0;
|
||||
Uint32 nextChat = 0;
|
||||
Uint32 nextKill = 0;
|
||||
void drawFrame( spades::client::IRenderer& renderer )
|
||||
{
|
||||
if( !designFont ) {
|
||||
@ -25,6 +101,10 @@ void drawFrame( spades::client::IRenderer& renderer )
|
||||
bigTextFont = new spades::client::Quake3Font(&renderer, renderer.RegisterImage("Gfx/Fonts/UbuntuCondensedBig.tga"), (const int*)UbuntuCondensedBigMap, 48, 8);
|
||||
orbitronFont = new spades::client::Quake3Font(&renderer, renderer.RegisterImage("Gfx/Fonts/Orbitron.tga"), (const int*)OrbitronMap, 30, 18);
|
||||
whiteImage = renderer.RegisterImage("Gfx/White.tga");
|
||||
chatWindow = new spades::client::ChatWindow( NULL, &renderer, textFont, false );
|
||||
killfeedWindow = new spades::client::ChatWindow( NULL, &renderer, textFont, true );
|
||||
ot = SDL_GetTicks();
|
||||
srand( ot );
|
||||
}
|
||||
spades::client::SceneDefinition sceneDef;
|
||||
sceneDef.viewOrigin = spades::MakeVector3(0, 0, 0);
|
||||
@ -42,18 +122,29 @@ void drawFrame( spades::client::IRenderer& renderer )
|
||||
renderer.EndScene();
|
||||
|
||||
spades::Vector2 scrSize = { renderer.ScreenWidth(), renderer.ScreenHeight() };
|
||||
renderer.SetColor( spades::MakeVector4( 0.5f, 0.5f, 0.5f, 1 ) );
|
||||
renderer.DrawImage( whiteImage, spades::AABB2(0, 0, scrSize.x, scrSize.y) );
|
||||
|
||||
spades::Vector2 pos = spades::MakeVector2( 10, 10 );
|
||||
for( int n = 0; n < 4; ++n ) {
|
||||
spades::client::IFont *font = n == 0 ? designFont : ( n == 1 ? textFont : (n == 2 ? bigTextFont : orbitronFont) );
|
||||
std::string str = "THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG\nthe quick brown fox jumps over the lazy dog\n0123456789";
|
||||
font->Draw(str, pos + spades::MakeVector2(1,1), 1.f, spades::MakeVector4(0,0,0,0.5));
|
||||
font->Draw(str, pos, 1.f, spades::MakeVector4(1,0,0,1));
|
||||
spades::Vector2 size = font->Measure(str);
|
||||
pos.y += size.y;
|
||||
|
||||
Uint32 dt = SDL_GetTicks() - ot;
|
||||
float fdt = (float)dt / 1000.f;
|
||||
chatWindow->Update( fdt );
|
||||
killfeedWindow->Update( fdt );
|
||||
ot += dt;
|
||||
|
||||
if( !nextChat || ot >= nextChat ) {
|
||||
nextChat = ot + 1000 + (rand() % 2000);
|
||||
addChat();
|
||||
}
|
||||
|
||||
if( !nextKill || ot >= nextKill ) {
|
||||
nextKill = ot + 200 + (rand() % 1000);
|
||||
addKill();
|
||||
}
|
||||
|
||||
chatWindow->Draw();
|
||||
killfeedWindow->Draw();
|
||||
|
||||
renderer.FrameDone();
|
||||
renderer.Flip();
|
||||
}
|
||||
|