openspades/Sources/Client/TCProgressView.cpp

170 lines
5.0 KiB
C++
Raw Normal View History

2013-08-29 11:45:22 +09:00
/*
Copyright (c) 2013 yvt
2013-08-29 11:45:22 +09:00
This file is part of OpenSpades.
2013-08-29 11:45:22 +09:00
OpenSpades 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.
2013-08-29 11:45:22 +09:00
OpenSpades 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.
2013-08-29 11:45:22 +09:00
You should have received a copy of the GNU General Public License
along with OpenSpades. If not, see <http://www.gnu.org/licenses/>.
2013-08-29 11:45:22 +09:00
*/
2013-08-18 16:18:06 +09:00
#include "TCProgressView.h"
#include "Client.h"
#include "IFont.h"
#include "IRenderer.h"
#include "TCGameMode.h"
#include "World.h"
2014-02-14 16:20:42 +09:00
#include <Core/Strings.h>
2013-08-18 16:18:06 +09:00
namespace spades {
namespace client {
struct TCProgressState {
int team1, team2;
float progress; // 0 = team1 owns
};
TCProgressView::TCProgressView(Client *c) : client(c), renderer(c->GetRenderer()) {
2013-08-18 16:18:06 +09:00
lastTerritoryId = -1;
}
TCProgressView::~TCProgressView() {}
static TCProgressState StateForTerritory(TCGameMode::Territory *t, int myTeam) {
2013-08-18 16:18:06 +09:00
TCProgressState state;
if (t->capturingTeamId == -1) {
2013-08-18 16:18:06 +09:00
state.team1 = t->ownerTeamId;
state.team2 = 2;
state.progress = 0.f;
} else {
2013-08-18 16:18:06 +09:00
float prg = t->GetProgress();
state.team1 = t->ownerTeamId;
state.team2 = t->capturingTeamId;
state.progress = prg;
if (state.team2 == myTeam) {
2013-08-18 16:18:06 +09:00
std::swap(state.team1, state.team2);
state.progress = 1.f - state.progress;
}
}
return state;
}
2013-08-18 16:18:06 +09:00
void TCProgressView::Draw() {
World *w = client->GetWorld();
if (!w) {
2013-08-18 16:18:06 +09:00
lastTerritoryId = -1;
return;
}
IGameMode *mode = w->GetMode();
if (!mode || IGameMode::m_TC != mode->ModeType()) {
return;
}
TCGameMode *tc = static_cast<TCGameMode *>(mode);
2013-08-18 16:18:06 +09:00
float scrW = renderer->ScreenWidth();
float scrH = renderer->ScreenHeight();
Handle<IImage> prgBg = renderer->RegisterImage("Gfx/TC/ProgressBg.png");
Handle<IImage> prgBar = renderer->RegisterImage("Gfx/TC/ProgressBar.png");
2013-08-18 16:18:06 +09:00
Player *p = w->GetLocalPlayer();
if (p && p->GetTeamId() < 2 && p->IsAlive()) {
2013-08-18 16:18:06 +09:00
// show approaching territory
TCGameMode::Territory *nearTerritory = NULL;
2014-04-06 22:42:17 +09:00
int nearTerId = 0;
2013-08-18 16:18:06 +09:00
float distance = 0.f;
int myTeam = p->GetTeamId();
2013-08-18 16:18:06 +09:00
int cnt = tc->GetNumTerritories();
for (int i = 0; i < cnt; i++) {
2013-08-18 16:18:06 +09:00
TCGameMode::Territory *t = tc->GetTerritory(i);
Vector3 diff = t->pos - p->GetEye();
if (fabsf(diff.x) < 18.f && fabsf(diff.y) < 18.f && fabsf(diff.z) < 18.f) {
2013-08-18 16:18:06 +09:00
float dist = diff.GetPoweredLength();
if (nearTerritory == NULL || dist < distance) {
2013-08-18 16:18:06 +09:00
nearTerritory = t;
nearTerId = i;
distance = dist;
}
}
}
2013-08-18 16:18:06 +09:00
float fade = 1.f;
if (nearTerritory) {
2013-08-18 16:18:06 +09:00
lastTerritoryId = nearTerId;
lastTerritoryTime = w->GetTime();
} else if (lastTerritoryId != -1 && w->GetTime() < lastTerritoryTime + 2.f) {
2013-08-18 16:18:06 +09:00
fade = 1.f - (w->GetTime() - lastTerritoryTime) / 2.f;
nearTerritory = tc->GetTerritory(lastTerritoryId);
}
if (nearTerritory) {
2013-08-18 16:18:06 +09:00
TCProgressState state = StateForTerritory(nearTerritory, myTeam);
2013-08-18 16:18:06 +09:00
float x = (scrW - 256.f) * .5f;
float y = scrH * 0.7f;
if (nearTerritory->ownerTeamId == 2) {
renderer->SetColorAlphaPremultiplied(MakeVector4(fade, fade, fade, fade));
} else {
2013-08-18 16:18:06 +09:00
IntVector3 c = w->GetTeam(nearTerritory->ownerTeamId).color;
renderer->SetColorAlphaPremultiplied(
MakeVector4(c.x / 255.f, c.y / 255.f, c.z / 255.f, 1) * fade);
2013-08-18 16:18:06 +09:00
}
renderer->DrawImage(prgBg, MakeVector2(x, y));
2013-08-18 16:18:06 +09:00
// get away from border
state.progress += (.5f - state.progress) * 12.f / 256.f;
if (state.team1 != 2) {
2013-08-18 16:18:06 +09:00
IntVector3 c = w->GetTeam(state.team1).color;
renderer->SetColorAlphaPremultiplied(
MakeVector4(c.x / 255.f, c.y / 255.f, c.z / 255.f, 1) * (fade * 0.8f));
2013-08-18 16:18:06 +09:00
renderer->DrawImage(prgBar, MakeVector2(x, y),
AABB2(0, 0, (1.f - state.progress) * 256.f, 32));
2013-08-18 16:18:06 +09:00
}
if (state.team2 != 2) {
2013-08-18 16:18:06 +09:00
IntVector3 c = w->GetTeam(state.team2).color;
renderer->SetColorAlphaPremultiplied(
MakeVector4(c.x / 255.f, c.y / 255.f, c.z / 255.f, 1) * (fade * 0.8f));
renderer->DrawImage(
prgBar, MakeVector2(x + (1.f - state.progress) * 256.f, y),
AABB2((1.f - state.progress) * 256.f, 0, state.progress * 256.f, 32));
2013-08-18 16:18:06 +09:00
}
2013-08-18 16:18:06 +09:00
IFont *font = client->textFont;
std::string str;
if (nearTerritory->ownerTeamId == 2) {
2014-02-14 16:20:42 +09:00
str = _Tr("Client", "Neutral Territory");
} else {
2013-08-18 16:18:06 +09:00
str = w->GetTeam(nearTerritory->ownerTeamId).name;
2014-02-14 16:20:42 +09:00
str = _Tr("Client", "{0}'s Territory", str);
2013-08-18 16:18:06 +09:00
}
2013-08-18 16:18:06 +09:00
Vector2 size = font->Measure(str);
x = (scrW - size.x) * .5f;
y += 35.f;
font->DrawShadow(str, MakeVector2(x, y), 1.f, MakeVector4(1.f, 1.f, 1.f, fade),
MakeVector4(0, 0, 0, 0.5f * fade));
2013-08-18 16:18:06 +09:00
}
} else {
2013-08-18 16:18:06 +09:00
// unable to show nearby territory
lastTerritoryId = -1;
}
}
}
}