mirror of
https://github.com/rwengine/openrw.git
synced 2024-09-15 15:02:34 +02:00
parent
85785b04e0
commit
23072a5e99
@ -18,6 +18,8 @@
|
|||||||
#include <engine/ScreenText.hpp>
|
#include <engine/ScreenText.hpp>
|
||||||
#include <objects/ObjectTypes.hpp>
|
#include <objects/ObjectTypes.hpp>
|
||||||
|
|
||||||
|
#include <script/ScriptTypes.hpp>
|
||||||
|
|
||||||
class GameWorld;
|
class GameWorld;
|
||||||
class GameObject;
|
class GameObject;
|
||||||
class ScriptMachine;
|
class ScriptMachine;
|
||||||
@ -330,7 +332,7 @@ public:
|
|||||||
* @brief Stores a pointer to script global that stores the on-mission
|
* @brief Stores a pointer to script global that stores the on-mission
|
||||||
* state.
|
* state.
|
||||||
*/
|
*/
|
||||||
int32_t* scriptOnMissionFlag;
|
ScriptInt* scriptOnMissionFlag;
|
||||||
|
|
||||||
/** Objects created by the current mission */
|
/** Objects created by the current mission */
|
||||||
std::vector<GameObject*> missionObjects;
|
std::vector<GameObject*> missionObjects;
|
||||||
@ -386,6 +388,12 @@ public:
|
|||||||
*/
|
*/
|
||||||
std::vector<TextDisplayData> texts;
|
std::vector<TextDisplayData> texts;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Script timer
|
||||||
|
*/
|
||||||
|
ScriptInt* scriptTimerVariable = nullptr;
|
||||||
|
bool scriptTimerPaused = false;
|
||||||
|
|
||||||
/** The camera near value currently set by the script */
|
/** The camera near value currently set by the script */
|
||||||
float cameraNear;
|
float cameraNear;
|
||||||
bool cameraFixed;
|
bool cameraFixed;
|
||||||
|
@ -3456,12 +3456,10 @@ void opcode_014d(const ScriptArguments& args, const ScriptString arg1, const Scr
|
|||||||
@brief start_timer_at %1d%
|
@brief start_timer_at %1d%
|
||||||
|
|
||||||
opcode 014e
|
opcode 014e
|
||||||
@arg arg1G Global timer storage
|
@arg timer
|
||||||
*/
|
*/
|
||||||
void opcode_014e(const ScriptArguments& args, ScriptInt& arg1G) {
|
void opcode_014e(const ScriptArguments& args, ScriptInt& timer) {
|
||||||
RW_UNIMPLEMENTED_OPCODE(0x014e);
|
args.getState()->scriptTimerVariable = &timer;
|
||||||
RW_UNUSED(arg1G);
|
|
||||||
RW_UNUSED(args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -3470,10 +3468,9 @@ void opcode_014e(const ScriptArguments& args, ScriptInt& arg1G) {
|
|||||||
opcode 014f
|
opcode 014f
|
||||||
@arg arg1G Global timer storage
|
@arg arg1G Global timer storage
|
||||||
*/
|
*/
|
||||||
void opcode_014f(const ScriptArguments& args, ScriptInt& arg1G) {
|
void opcode_014f(const ScriptArguments& args, ScriptInt& unused) {
|
||||||
RW_UNIMPLEMENTED_OPCODE(0x014f);
|
RW_UNUSED(unused);
|
||||||
RW_UNUSED(arg1G);
|
args.getState()->scriptTimerVariable = nullptr;
|
||||||
RW_UNUSED(args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -10413,10 +10410,8 @@ void opcode_0395(const ScriptArguments& args, ScriptVec3 coord, const ScriptFloa
|
|||||||
opcode 0396
|
opcode 0396
|
||||||
@arg arg1 Boolean true/false
|
@arg arg1 Boolean true/false
|
||||||
*/
|
*/
|
||||||
void opcode_0396(const ScriptArguments& args, const ScriptBoolean arg1) {
|
void opcode_0396(const ScriptArguments& args, const ScriptBoolean paused) {
|
||||||
RW_UNIMPLEMENTED_OPCODE(0x0396);
|
args.getState()->scriptTimerPaused = paused;
|
||||||
RW_UNUSED(arg1);
|
|
||||||
RW_UNUSED(args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
#include "DrawUI.hpp"
|
#include "DrawUI.hpp"
|
||||||
#include <ai/PlayerController.hpp>
|
#include <ai/PlayerController.hpp>
|
||||||
#include <engine/GameState.hpp>
|
|
||||||
#include <objects/CharacterObject.hpp>
|
|
||||||
#include <data/WeaponData.hpp>
|
#include <data/WeaponData.hpp>
|
||||||
#include <engine/GameData.hpp>
|
#include <engine/GameData.hpp>
|
||||||
|
#include <engine/GameState.hpp>
|
||||||
|
#include <objects/CharacterObject.hpp>
|
||||||
#include <render/GameRenderer.hpp>
|
#include <render/GameRenderer.hpp>
|
||||||
|
|
||||||
#include <glm/gtc/constants.hpp>
|
#include <glm/gtc/constants.hpp>
|
||||||
@ -12,11 +12,16 @@
|
|||||||
|
|
||||||
constexpr size_t ui_textSize = 25;
|
constexpr size_t ui_textSize = 25;
|
||||||
constexpr size_t ui_textHeight = 22;
|
constexpr size_t ui_textHeight = 22;
|
||||||
|
constexpr size_t ui_elementMargin = 3;
|
||||||
constexpr size_t ui_outerMargin = 20;
|
constexpr size_t ui_outerMargin = 20;
|
||||||
constexpr size_t ui_infoMargin = 10;
|
constexpr size_t ui_infoMargin = 10;
|
||||||
constexpr size_t ui_weaponSize = 64;
|
constexpr size_t ui_weaponSize = 64;
|
||||||
constexpr size_t ui_ammoSize = 14;
|
constexpr size_t ui_ammoSize = 14;
|
||||||
constexpr size_t ui_ammoHeight = 16;
|
constexpr size_t ui_ammoHeight = 16;
|
||||||
|
constexpr size_t ui_wantedLevelHeight =
|
||||||
|
ui_outerMargin + ui_weaponSize + ui_elementMargin;
|
||||||
|
constexpr size_t ui_scriptTimerHeight =
|
||||||
|
ui_wantedLevelHeight + ui_textHeight + ui_elementMargin;
|
||||||
constexpr size_t ui_armourOffset = ui_textSize * 3;
|
constexpr size_t ui_armourOffset = ui_textSize * 3;
|
||||||
constexpr size_t ui_maxWantedLevel = 6;
|
constexpr size_t ui_maxWantedLevel = 6;
|
||||||
constexpr size_t ui_lowHealth = 9;
|
constexpr size_t ui_lowHealth = 9;
|
||||||
@ -24,17 +29,49 @@ const glm::u8vec3 ui_timeColour(196, 165, 119);
|
|||||||
const glm::u8vec3 ui_moneyColour(89, 113, 147);
|
const glm::u8vec3 ui_moneyColour(89, 113, 147);
|
||||||
const glm::u8vec3 ui_healthColour(187, 102, 47);
|
const glm::u8vec3 ui_healthColour(187, 102, 47);
|
||||||
const glm::u8vec3 ui_armourColour(123, 136, 93);
|
const glm::u8vec3 ui_armourColour(123, 136, 93);
|
||||||
|
const glm::u8vec3 ui_scriptTimerColour(186, 101, 50);
|
||||||
const glm::u8vec3 ui_shadowColour(0, 0, 0);
|
const glm::u8vec3 ui_shadowColour(0, 0, 0);
|
||||||
constexpr float ui_mapSize = 150.f;
|
constexpr float ui_mapSize = 150.f;
|
||||||
constexpr float ui_worldSizeMin = 200.f;
|
constexpr float ui_worldSizeMin = 200.f;
|
||||||
constexpr float ui_worldSizeMax = 300.f;
|
constexpr float ui_worldSizeMax = 300.f;
|
||||||
|
|
||||||
|
void drawScriptTimer(GameWorld* world, GameRenderer* render) {
|
||||||
|
if (world->state->scriptTimerVariable) {
|
||||||
|
float scriptTimerTextX =
|
||||||
|
render->getRenderer()->getViewport().x - ui_outerMargin;
|
||||||
|
float scriptTimerTextY = ui_scriptTimerHeight;
|
||||||
|
|
||||||
|
TextRenderer::TextInfo ti;
|
||||||
|
ti.font = 1;
|
||||||
|
ti.size = ui_textSize;
|
||||||
|
ti.align = TextRenderer::TextInfo::Right;
|
||||||
|
|
||||||
|
{
|
||||||
|
int32_t seconds = *world->state->scriptTimerVariable / 1000;
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << std::setw(2) << std::setfill('0') << seconds / 60
|
||||||
|
<< std::setw(0) << ":" << std::setw(2) << seconds % 60;
|
||||||
|
|
||||||
|
ti.text = GameStringUtil::fromString(ss.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
ti.baseColour = ui_shadowColour;
|
||||||
|
ti.screenPosition =
|
||||||
|
glm::vec2(scriptTimerTextX + 1.f, scriptTimerTextY + 1.f);
|
||||||
|
render->text.renderText(ti);
|
||||||
|
|
||||||
|
ti.baseColour = ui_scriptTimerColour;
|
||||||
|
ti.screenPosition = glm::vec2(scriptTimerTextX, scriptTimerTextY);
|
||||||
|
render->text.renderText(ti);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void drawMap(ViewCamera& currentView, PlayerController* player,
|
void drawMap(ViewCamera& currentView, PlayerController* player,
|
||||||
GameWorld* world, GameRenderer* render) {
|
GameWorld* world, GameRenderer* render) {
|
||||||
MapRenderer::MapInfo map;
|
MapRenderer::MapInfo map;
|
||||||
|
|
||||||
if (world->state->hudFlash != HudFlash::FlashRadar
|
if (world->state->hudFlash != HudFlash::FlashRadar ||
|
||||||
|| std::fmod(world->getGameTime(), 0.5f) >= .25f) {
|
std::fmod(world->getGameTime(), 0.5f) >= .25f) {
|
||||||
glm::quat camRot = currentView.rotation;
|
glm::quat camRot = currentView.rotation;
|
||||||
|
|
||||||
map.rotation = glm::roll(camRot) - glm::half_pi<float>();
|
map.rotation = glm::roll(camRot) - glm::half_pi<float>();
|
||||||
@ -67,7 +104,7 @@ void drawPlayerInfo(PlayerController* player, GameWorld* world,
|
|||||||
(ui_outerMargin + ui_weaponSize);
|
(ui_outerMargin + ui_weaponSize);
|
||||||
float iconY = ui_outerMargin;
|
float iconY = ui_outerMargin;
|
||||||
float wantedX = render->getRenderer()->getViewport().x - (ui_outerMargin);
|
float wantedX = render->getRenderer()->getViewport().x - (ui_outerMargin);
|
||||||
float wantedY = ui_outerMargin + ui_weaponSize + 3.f;
|
float wantedY = ui_wantedLevelHeight;
|
||||||
|
|
||||||
TextRenderer::TextInfo ti;
|
TextRenderer::TextInfo ti;
|
||||||
ti.font = 1;
|
ti.font = 1;
|
||||||
@ -81,12 +118,14 @@ void drawPlayerInfo(PlayerController* player, GameWorld* world,
|
|||||||
|
|
||||||
ti.text = GameStringUtil::fromString(ss.str());
|
ti.text = GameStringUtil::fromString(ss.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
ti.baseColour = ui_shadowColour;
|
ti.baseColour = ui_shadowColour;
|
||||||
ti.screenPosition = glm::vec2(infoTextX + 1.f, infoTextY + 1.f);
|
ti.screenPosition = glm::vec2(infoTextX + 1.f, infoTextY + 1.f);
|
||||||
render->text.renderText(ti);
|
render->text.renderText(ti);
|
||||||
|
|
||||||
ti.baseColour = ui_timeColour;
|
ti.baseColour = ui_timeColour;
|
||||||
ti.screenPosition = glm::vec2(infoTextX, infoTextY);
|
ti.screenPosition = glm::vec2(infoTextX, infoTextY);
|
||||||
|
|
||||||
render->text.renderText(ti);
|
render->text.renderText(ti);
|
||||||
|
|
||||||
infoTextY += ui_textHeight;
|
infoTextY += ui_textHeight;
|
||||||
@ -98,25 +137,30 @@ void drawPlayerInfo(PlayerController* player, GameWorld* world,
|
|||||||
|
|
||||||
ti.text = GameSymbols::Money + GameStringUtil::fromString(ss.str());
|
ti.text = GameSymbols::Money + GameStringUtil::fromString(ss.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
ti.baseColour = ui_shadowColour;
|
ti.baseColour = ui_shadowColour;
|
||||||
ti.screenPosition = glm::vec2(infoTextX + 1.f, infoTextY + 1.f);
|
ti.screenPosition = glm::vec2(infoTextX + 1.f, infoTextY + 1.f);
|
||||||
render->text.renderText(ti);
|
render->text.renderText(ti);
|
||||||
|
|
||||||
ti.baseColour = ui_moneyColour;
|
ti.baseColour = ui_moneyColour;
|
||||||
|
|
||||||
ti.screenPosition = glm::vec2(infoTextX, infoTextY);
|
ti.screenPosition = glm::vec2(infoTextX, infoTextY);
|
||||||
render->text.renderText(ti);
|
render->text.renderText(ti);
|
||||||
|
|
||||||
infoTextY += ui_textHeight;
|
infoTextY += ui_textHeight;
|
||||||
|
|
||||||
if ((world->state->hudFlash != HudFlash::FlashHealth
|
if ((world->state->hudFlash != HudFlash::FlashHealth &&
|
||||||
&& player->getCharacter()->getCurrentState().health > ui_lowHealth)
|
player->getCharacter()->getCurrentState().health > ui_lowHealth) ||
|
||||||
|| std::fmod(world->getGameTime(), 0.5f) >= .25f) { // UI: Blinking health indicator if health is low
|
std::fmod(world->getGameTime(), 0.5f) >=
|
||||||
|
.25f) { // UI: Blinking health indicator if health is low
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << std::setw(3) << std::setfill('0')
|
ss << std::setw(3) << std::setfill('0')
|
||||||
<< (int)player->getCharacter()->getCurrentState().health;
|
<< (int)player->getCharacter()->getCurrentState().health;
|
||||||
ti.text = GameSymbols::Heart + GameStringUtil::fromString(ss.str());
|
ti.text = GameSymbols::Heart + GameStringUtil::fromString(ss.str());
|
||||||
|
|
||||||
ti.baseColour = ui_shadowColour;
|
ti.baseColour = ui_shadowColour;
|
||||||
ti.screenPosition = glm::vec2(infoTextX + 1.f, infoTextY + 1.f);
|
ti.screenPosition = glm::vec2(infoTextX + 1.f, infoTextY + 1.f);
|
||||||
|
|
||||||
render->text.renderText(ti);
|
render->text.renderText(ti);
|
||||||
|
|
||||||
ti.baseColour = ui_healthColour;
|
ti.baseColour = ui_healthColour;
|
||||||
@ -129,6 +173,7 @@ void drawPlayerInfo(PlayerController* player, GameWorld* world,
|
|||||||
ss << std::setw(3) << std::setfill('0')
|
ss << std::setw(3) << std::setfill('0')
|
||||||
<< (int)player->getCharacter()->getCurrentState().armour;
|
<< (int)player->getCharacter()->getCurrentState().armour;
|
||||||
ti.text = GameSymbols::Armour + GameStringUtil::fromString(ss.str());
|
ti.text = GameSymbols::Armour + GameStringUtil::fromString(ss.str());
|
||||||
|
|
||||||
ti.baseColour = ui_shadowColour;
|
ti.baseColour = ui_shadowColour;
|
||||||
ti.screenPosition =
|
ti.screenPosition =
|
||||||
glm::vec2(infoTextX + 1.f - ui_armourOffset, infoTextY + 1.f);
|
glm::vec2(infoTextX + 1.f - ui_armourOffset, infoTextY + 1.f);
|
||||||
@ -201,8 +246,8 @@ void drawPlayerInfo(PlayerController* player, GameWorld* world,
|
|||||||
// The clip is actually there, but it holds just one shot/charge
|
// The clip is actually there, but it holds just one shot/charge
|
||||||
displayBulletsTotal += slotInfo.bulletsClip;
|
displayBulletsTotal += slotInfo.bulletsClip;
|
||||||
|
|
||||||
ti.text = GameStringUtil::fromString(
|
ti.text =
|
||||||
std::to_string(displayBulletsTotal));
|
GameStringUtil::fromString(std::to_string(displayBulletsTotal));
|
||||||
} else {
|
} else {
|
||||||
// Limit the maximal displayed length for the total bullet count
|
// Limit the maximal displayed length for the total bullet count
|
||||||
if (slotInfo.bulletsTotal > 9999) {
|
if (slotInfo.bulletsTotal > 9999) {
|
||||||
@ -229,6 +274,7 @@ void drawHUD(ViewCamera& currentView, PlayerController* player,
|
|||||||
if (player && player->getCharacter()) {
|
if (player && player->getCharacter()) {
|
||||||
drawMap(currentView, player, world, render);
|
drawMap(currentView, player, world, render);
|
||||||
drawPlayerInfo(player, world, render);
|
drawPlayerInfo(player, world, render);
|
||||||
|
drawScriptTimer(world, render);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -485,6 +485,7 @@ void RWGame::tick(float dt) {
|
|||||||
State* currState = StateManager::get().states.back().get();
|
State* currState = StateManager::get().states.back().get();
|
||||||
|
|
||||||
static float clockAccumulator = 0.f;
|
static float clockAccumulator = 0.f;
|
||||||
|
static float scriptTimerAccumulator = 0.f;
|
||||||
if (currState->shouldWorldUpdate()) {
|
if (currState->shouldWorldUpdate()) {
|
||||||
world->chase.update(dt);
|
world->chase.update(dt);
|
||||||
|
|
||||||
@ -506,6 +507,22 @@ void RWGame::tick(float dt) {
|
|||||||
clockAccumulator -= 1.f;
|
clockAccumulator -= 1.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (state.scriptTimerVariable && !state.scriptTimerPaused) {
|
||||||
|
scriptTimerAccumulator += dt;
|
||||||
|
while (scriptTimerAccumulator >= 1.f) {
|
||||||
|
(*state.scriptTimerVariable) -= 1000;
|
||||||
|
if (*state.scriptTimerVariable <= 0) {
|
||||||
|
(*state.scriptTimerVariable) = 0;
|
||||||
|
state.scriptTimerVariable = nullptr;
|
||||||
|
}
|
||||||
|
// 11 seconds
|
||||||
|
if (*state.scriptTimerVariable <= 11000) {
|
||||||
|
// @todo beep
|
||||||
|
}
|
||||||
|
scriptTimerAccumulator -= 1.f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Clean up old VisualFX
|
// Clean up old VisualFX
|
||||||
for (int i = 0; i < static_cast<int>(world->effects.size()); ++i) {
|
for (int i = 0; i < static_cast<int>(world->effects.size()); ++i) {
|
||||||
VisualFX* effect = world->effects[i];
|
VisualFX* effect = world->effects[i];
|
||||||
|
Loading…
Reference in New Issue
Block a user