forked from townforge/townforge
game: better city level window
This commit is contained in:
parent
9f16dc3047
commit
8995df508a
11
GameData/TB/cc/city-level-row.tb.txt
Normal file
11
GameData/TB/cc/city-level-row.tb.txt
Normal file
@ -0,0 +1,11 @@
|
||||
WindowInfo
|
||||
|
||||
TBLayout: axis: y
|
||||
TBLayout: axis: x, gravity: "left"
|
||||
TBTextField: id: "level"
|
||||
TBTextField: id: "level-name"
|
||||
TBTextField: id: "shares"
|
||||
TBToggleContainer: id: "unlocks-container", toggle: expanded
|
||||
TBLayout: axis: y
|
||||
TBTextField: id: "unlocks", text: ""
|
||||
TBSeparator
|
37
GameData/TB/cc/city-level.tb.txt
Normal file
37
GameData/TB/cc/city-level.tb.txt
Normal file
@ -0,0 +1,37 @@
|
||||
WindowInfo
|
||||
title City level
|
||||
centered-relative-size: 0.5 0.8
|
||||
modal: 1
|
||||
|
||||
TBLayout: axis: y, distribution-position: "left top", distribution: "available"
|
||||
|
||||
TBLayout: axis: x, distribution-position: "left"
|
||||
TBTextField: id: "city-name"
|
||||
TBTextField: text: "is currently a"
|
||||
TBTextField: id: "city-level-name"
|
||||
TBTextField: text: " ("
|
||||
TBTextField: id: "city-level"
|
||||
TBTextField: text: ")"
|
||||
TBLayout: axis: x, distribution-position: "left"
|
||||
TBTextField: text: "Size score: "
|
||||
TBTextField: id: "city-size-score"
|
||||
|
||||
TBTextField
|
||||
|
||||
TBToggleContainer: id: "next-level-container", gravity: "left right", position: "left", toggle: expanded
|
||||
TBLayout: axis: y, distribution-position: "left top", distribution: "gravity"
|
||||
TBLayout: axis: x, distribution-position: "left"
|
||||
TBTextField: text: "Next level: "
|
||||
TBTextField: id: "next-level-name"
|
||||
TBTextField: text: " ("
|
||||
TBTextField: id: "next-level"
|
||||
TBTextField: text: ")"
|
||||
TBLayout: axis: x, distribution-position: "left"
|
||||
TBTextField: text: "Upon reaching size score: "
|
||||
TBTextField: id: "next-size-score"
|
||||
|
||||
TBTextField
|
||||
|
||||
TBLayout: axis: x, distribution-position: "left"
|
||||
TBTextField: text: "Levels:"
|
||||
TBSelectList: id: "levels", gravity: "all"
|
@ -1619,6 +1619,23 @@ const char *get_town_level_name(uint32_t level)
|
||||
}
|
||||
}
|
||||
|
||||
std::string get_town_level_unlocks(uint32_t level)
|
||||
{
|
||||
if (level == 0)
|
||||
return "";
|
||||
std::string s;
|
||||
for (int role = 0; role < NUM_ROLES; ++role)
|
||||
{
|
||||
if (!is_role_enabled(role, 0, level-1) && is_role_enabled(role, 0, level))
|
||||
{
|
||||
if (!s.empty())
|
||||
s += ", ";
|
||||
s += cc::get_role_name(role);
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
uint32_t get_food_needs(uint8_t role)
|
||||
{
|
||||
switch (role)
|
||||
|
@ -95,6 +95,7 @@ uint64_t get_building_activity_score(uint32_t x0, uint32_t y0, uint32_t x1, uint
|
||||
bool is_town_square(uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1, uint8_t role, uint32_t ox, uint32_t oy);
|
||||
uint32_t get_town_level(uint64_t shares);
|
||||
const char *get_town_level_name(uint32_t level);
|
||||
std::string get_town_level_unlocks(uint32_t level);
|
||||
uint32_t get_food_needs(uint8_t role);
|
||||
uint32_t get_food_needs(uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1, uint8_t role, uint32_t economic_power);
|
||||
uint32_t get_heating_needs(uint8_t role);
|
||||
|
@ -67,6 +67,7 @@ set(game_sources
|
||||
shade-button.cc
|
||||
shares.cc
|
||||
ui-building-settings.cc
|
||||
ui-city-level.cc
|
||||
ui-console.cc
|
||||
ui-credits.cc
|
||||
ui-define-attribute.cc
|
||||
@ -119,6 +120,7 @@ set(game_headers
|
||||
shade-button.h
|
||||
shares.h
|
||||
ui-building-settings.h
|
||||
ui-city-level.h
|
||||
ui-console.h
|
||||
ui-credits.h
|
||||
ui-define-attribute.h
|
||||
|
164
src/game/ui-city-level.cc
Normal file
164
src/game/ui-city-level.cc
Normal file
@ -0,0 +1,164 @@
|
||||
#include <Urho3D/Resource/ResourceCache.h>
|
||||
#include <Urho3D/Core/Context.h>
|
||||
#include <Urho3D/UI/UI.h>
|
||||
#include <Urho3D/UI/UIEvents.h>
|
||||
#include <Urho3D/Graphics/Graphics.h>
|
||||
#include <tb/tb_toggle_container.h>
|
||||
#include <tb/tb_select.h>
|
||||
#include <tb/tb_widgets_reader.h>
|
||||
#include "cc/cc_config.h"
|
||||
#include "cc/cc.h"
|
||||
#include "game-state.h"
|
||||
#include "ui-city-level.h"
|
||||
|
||||
using namespace Urho3D;
|
||||
using namespace tb;
|
||||
|
||||
static std::string get_shares_string(uint64_t shares)
|
||||
{
|
||||
std::string s = std::to_string(shares);
|
||||
for (int idx = s.size() - 3; idx > 0; idx -= 3)
|
||||
s.insert(idx, ",");
|
||||
return s;
|
||||
}
|
||||
|
||||
UICityLevelDialog::LevelWidget::LevelWidget(UICityLevelDialog::LevelItem *item, LevelSource *source, tb::TBSelectItemViewer *source_viewer, int index):
|
||||
m_source(source),
|
||||
m_source_viewer(source_viewer),
|
||||
m_index(index)
|
||||
{
|
||||
SetSkinBg(TBIDC("TBSelectItem"));
|
||||
SetLayoutDistribution(LAYOUT_DISTRIBUTION_GRAVITY);
|
||||
SetLayoutDistributionPosition(LAYOUT_DISTRIBUTION_POSITION_LEFT_TOP);
|
||||
SetPaintOverflowFadeout(false);
|
||||
|
||||
g_widgets_reader->LoadFile(GetContentRoot(), "cc/city-level-row.tb.txt");
|
||||
|
||||
TBTextField *levelWidget = GetWidgetByIDAndType<TBTextField>(TBIDC("level"));
|
||||
levelWidget->SetText(String(item->level).CString());
|
||||
|
||||
TBTextField *levelNameWidget = GetWidgetByIDAndType<TBTextField>(TBIDC("level-name"));
|
||||
levelNameWidget->SetText(item->name.c_str());
|
||||
|
||||
TBTextField *sharesWidget = GetWidgetByIDAndType<TBTextField>(TBIDC("shares"));
|
||||
sharesWidget->SetText(get_shares_string(item->shares).c_str());
|
||||
|
||||
TBTextField *unlocksWidget = GetWidgetByIDAndType<TBTextField>(TBIDC("unlocks"));
|
||||
const std::string unlocks = cc::get_town_level_unlocks(item->level);
|
||||
unlocksWidget->SetText(("Unlocks: " + unlocks).c_str());
|
||||
unlocksWidget->SetItalic(true);
|
||||
|
||||
TBToggleContainer *unlocksContainer = GetWidgetByIDAndType<TBToggleContainer>(TBIDC("unlocks-container"));
|
||||
unlocksContainer->SetValue(!unlocks.empty());
|
||||
}
|
||||
|
||||
TBWidget *UICityLevelDialog::LevelSource::CreateItemWidget(int index, TBSelectItemViewer *viewer)
|
||||
{
|
||||
LevelItem *item = GetItem(index);
|
||||
return new UICityLevelDialog::LevelWidget(item, this, viewer, index);
|
||||
}
|
||||
|
||||
UICityLevelDialog::UICityLevelDialog(Context *ctx, const GameState *game):
|
||||
UITBWindow(ctx, "cc/city-level.tb.txt"),
|
||||
game(game)
|
||||
{
|
||||
auto* graphics = GetSubsystem<Graphics>();
|
||||
|
||||
cityNameWidget = GetWidgetByIDAndType<TBTextField>(TBIDC("city-name"));
|
||||
cityLevelNameWidget = GetWidgetByIDAndType<TBTextField>(TBIDC("city-level-name"));
|
||||
cityLevelWidget = GetWidgetByIDAndType<TBTextField>(TBIDC("city-level"));
|
||||
citySizeScoreWidget = GetWidgetByIDAndType<TBTextField>(TBIDC("city-size-score"));
|
||||
nextLevelContainer = GetWidgetByIDAndType<TBToggleContainer>(TBIDC("next-level-container"));
|
||||
nextLevelNameWidget = GetWidgetByIDAndType<TBTextField>(TBIDC("next-level-name"));
|
||||
nextLevelWidget = GetWidgetByIDAndType<TBTextField>(TBIDC("next-level"));
|
||||
nextSizeScoreWidget = GetWidgetByIDAndType<TBTextField>(TBIDC("next-size-score"));
|
||||
listWidget = GetWidgetByIDAndType<TBSelectList>(TBIDC("levels"));
|
||||
|
||||
listWidget->SetSource(&level_source);
|
||||
|
||||
SubscribeToEvent(this, E_TB_WIDGET_EVENT, URHO3D_HANDLER(UICityLevelDialog, HandleTBMessage));
|
||||
SubscribeToEvent(this, E_TB_WINDOW_CLOSED, URHO3D_HANDLER(UICityLevelDialog, HandleClose));
|
||||
}
|
||||
|
||||
UICityLevelDialog::~UICityLevelDialog()
|
||||
{
|
||||
listWidget->SetSource(NULL);
|
||||
}
|
||||
|
||||
void UICityLevelDialog::Update()
|
||||
{
|
||||
if (game->top_hash == last_refresh_stop_hash)
|
||||
return;
|
||||
|
||||
uint64_t shares = 0;
|
||||
for (int role = 0; role < NUM_ROLES; ++role)
|
||||
shares += game->cityState.last_payout_shares[role] * cc::get_weight_for_city_growth(role) / 100;
|
||||
const uint32_t level = cc::get_town_level(shares);
|
||||
const char *level_name = cc::get_town_level_name(level);
|
||||
const char *next_level_name = cc::get_town_level_name(level + 1);
|
||||
|
||||
cityNameWidget->SetText(game->get_city_name(game->cityState.id).c_str());
|
||||
cityLevelNameWidget->SetText(level_name);
|
||||
cityLevelWidget->SetText(std::to_string(level).c_str());
|
||||
citySizeScoreWidget->SetText(get_shares_string(shares).c_str());
|
||||
|
||||
const bool is_last_level = level_name == next_level_name;
|
||||
nextLevelContainer->SetValue(!is_last_level);
|
||||
if (!is_last_level)
|
||||
{
|
||||
uint64_t next_level_shares = CITY_LEVEL_SHARE_SCALE;
|
||||
while (next_level_shares <= shares)
|
||||
next_level_shares *= 10;
|
||||
|
||||
nextLevelNameWidget->SetText(next_level_name);
|
||||
nextLevelWidget->SetText(std::to_string(level + 1).c_str());
|
||||
nextSizeScoreWidget->SetText(get_shares_string(next_level_shares).c_str());
|
||||
}
|
||||
|
||||
level_source.DeleteAllItems();
|
||||
uint64_t level_shares = CITY_LEVEL_SHARE_SCALE;
|
||||
level_source.AddItem(new LevelItem(0, cc::get_town_level_name(0), 0));
|
||||
for (int level = 1; ; ++level)
|
||||
{
|
||||
const char *level_name = cc::get_town_level_name(level);
|
||||
const char *next_level_name = cc::get_town_level_name(level + 1);
|
||||
LevelItem *item = new LevelItem(level, level_name, level_shares);
|
||||
level_source.AddItem(item);
|
||||
level_shares *= 10;
|
||||
if (level_name == next_level_name)
|
||||
break;
|
||||
}
|
||||
|
||||
last_refresh_stop_hash = game->top_hash;
|
||||
}
|
||||
|
||||
void UICityLevelDialog::CancelUI()
|
||||
{
|
||||
VariantMap& newEventData = GetEventDataMap();
|
||||
SendEvent(E_CITY_LEVEL_CLOSED, newEventData);
|
||||
|
||||
// Self destruct
|
||||
Close();
|
||||
}
|
||||
|
||||
void UICityLevelDialog::HandleTBMessage(StringHash eventType, VariantMap& eventData)
|
||||
{
|
||||
#define CONNECT(name, function) do { if (ev->target->GetID() == TBIDC(name)) function(eventType, eventData); } while(0)
|
||||
using namespace TBWidgetEventNamespace;
|
||||
|
||||
TBWidgetEvent *ev = (TBWidgetEvent*)eventData[P_WIDGET_EVENT].GetVoidPtr();
|
||||
if (ev->type == EVENT_TYPE_CLICK)
|
||||
{
|
||||
}
|
||||
|
||||
#undef CONNECT
|
||||
}
|
||||
|
||||
void UICityLevelDialog::HandleClose(StringHash eventType, VariantMap& eventData)
|
||||
{
|
||||
VariantMap& newEventData = GetEventDataMap();
|
||||
SendEvent(E_CITY_LEVEL_CLOSED, newEventData);
|
||||
|
||||
// Self destruct
|
||||
Close();
|
||||
}
|
81
src/game/ui-city-level.h
Normal file
81
src/game/ui-city-level.h
Normal file
@ -0,0 +1,81 @@
|
||||
#ifndef UI_CITY_LEVEL_H
|
||||
#define UI_CITY_LEVEL_H
|
||||
|
||||
#include <Urho3D/Core/Object.h>
|
||||
#include <Urho3D/Container/Str.h>
|
||||
#include <Urho3D/Container/Ptr.h>
|
||||
#include <Urho3D/Math/StringHash.h>
|
||||
#include <tb/tb_select_item.h>
|
||||
#include "ui-tb-window.h"
|
||||
|
||||
namespace Urho3D
|
||||
{
|
||||
class Context;
|
||||
}
|
||||
|
||||
namespace tb
|
||||
{
|
||||
class TBEditField;
|
||||
class TBToggleContainer;
|
||||
class TBSelectList;
|
||||
}
|
||||
|
||||
URHO3D_EVENT(E_CITY_LEVEL_CLOSED, CityLevelClosed) {}
|
||||
|
||||
class UICityLevelDialog: public UITBWindow
|
||||
{
|
||||
public:
|
||||
UICityLevelDialog(Urho3D::Context *ctx, const GameState *game = NULL);
|
||||
virtual ~UICityLevelDialog() override;
|
||||
|
||||
void Update();
|
||||
void CancelUI();
|
||||
|
||||
private:
|
||||
void HandleTBMessage(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData);
|
||||
void HandleClose(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData);
|
||||
|
||||
private:
|
||||
const GameState *game;
|
||||
|
||||
tb::TBTextField *cityNameWidget;
|
||||
tb::TBTextField *cityLevelNameWidget;
|
||||
tb::TBTextField *cityLevelWidget;
|
||||
tb::TBTextField *citySizeScoreWidget;
|
||||
tb::TBToggleContainer *nextLevelContainer;
|
||||
tb::TBTextField *nextLevelNameWidget;
|
||||
tb::TBTextField *nextLevelWidget;
|
||||
tb::TBTextField *nextSizeScoreWidget;
|
||||
tb::TBSelectList *listWidget;
|
||||
|
||||
class LevelItem: public tb::TBGenericStringItem
|
||||
{
|
||||
public:
|
||||
LevelItem(uint32_t level, const std::string &name, uint64_t shares): TBGenericStringItem(name.c_str()), level(level), name(name), shares(shares) {}
|
||||
uint32_t level;
|
||||
std::string name;
|
||||
uint64_t shares;
|
||||
};
|
||||
|
||||
class LevelSource: public tb::TBSelectItemSourceList<LevelItem>
|
||||
{
|
||||
public:
|
||||
virtual tb::TBWidget *CreateItemWidget(int index, tb::TBSelectItemViewer *viewer);
|
||||
};
|
||||
|
||||
class LevelWidget: public tb::TBLayout
|
||||
{
|
||||
public:
|
||||
LevelWidget(LevelItem *item, LevelSource *source, tb::TBSelectItemViewer *source_viewer, int index);
|
||||
private:
|
||||
LevelSource *m_source;
|
||||
tb::TBSelectItemViewer *m_source_viewer;
|
||||
int m_index;
|
||||
};
|
||||
|
||||
LevelSource level_source;
|
||||
|
||||
std::string last_refresh_stop_hash;
|
||||
};
|
||||
|
||||
#endif
|
@ -29,6 +29,7 @@
|
||||
#include "ui-dice-roll.h"
|
||||
#include "ui-hunt.h"
|
||||
#include "ui-queued-commands.h"
|
||||
#include "ui-city-level.h"
|
||||
#include "cc/cc_config.h"
|
||||
#include "cc/cc.h"
|
||||
#include "cc/cc_calendar.h"
|
||||
@ -83,7 +84,8 @@ UIUrho3D::UIUrho3D(Context *ctx, const GameState *gameState):
|
||||
defineAttributeDialog(nullptr),
|
||||
diceRollDialog(nullptr),
|
||||
huntDialog(nullptr),
|
||||
queuedCommandsDialog(nullptr)
|
||||
queuedCommandsDialog(nullptr),
|
||||
cityLevelDialog(nullptr)
|
||||
{
|
||||
auto root = ctx->GetSubsystem<UI>()->GetRoot();
|
||||
auto* cache = ctx->GetSubsystem<ResourceCache>();
|
||||
@ -417,6 +419,8 @@ void UIUrho3D::Update(uint32_t mouse_x, uint32_t mouse_y, uint32_t sx0, uint32_t
|
||||
huntDialog->Update(w);
|
||||
if (queuedCommandsDialog)
|
||||
queuedCommandsDialog->Update(queued_commands);
|
||||
if (cityLevelDialog)
|
||||
cityLevelDialog->Update();
|
||||
}
|
||||
|
||||
void UIUrho3D::NewTradeCommand()
|
||||
@ -1219,6 +1223,17 @@ void UIUrho3D::HandleCityLevelHelp(StringHash eventType, VariantMap& eventData)
|
||||
if (city->treasury == 0)
|
||||
return;
|
||||
|
||||
#if 1
|
||||
if (cityLevelDialog)
|
||||
{
|
||||
new MessageBox(context_, "Dialog is already active");
|
||||
return;
|
||||
}
|
||||
cityLevelDialog = new UICityLevelDialog(context_, gameState);
|
||||
SubscribeToEvent(cityLevelDialog, E_CITY_LEVEL_CLOSED, [this](StringHash eventType, VariantMap& eventData) {
|
||||
cityLevelDialog = NULL;
|
||||
});
|
||||
#else
|
||||
std::stringstream ss;
|
||||
uint64_t shares = 0;
|
||||
for (int role = 0; role < NUM_ROLES; ++role)
|
||||
@ -1240,6 +1255,7 @@ void UIUrho3D::HandleCityLevelHelp(StringHash eventType, VariantMap& eventData)
|
||||
auto *d = new MessageBox(context_, ss.str().c_str(), "City level", TBID(0u));
|
||||
d->SetSize(600, 288);
|
||||
d->SetRect(d->GetRect().CenterIn(UTBRendererBatcher::Singleton().Root().GetRect()));
|
||||
#endif
|
||||
}
|
||||
|
||||
void UIUrho3D::HandleFoundCity(StringHash eventType, VariantMap& eventData)
|
||||
|
@ -43,6 +43,7 @@ class UIDefineAttributeDialog;
|
||||
class UIDiceRollDialog;
|
||||
class UIHuntDialog;
|
||||
class UIQueuedCommandsDialog;
|
||||
class UICityLevelDialog;
|
||||
|
||||
namespace tb
|
||||
{
|
||||
@ -311,6 +312,7 @@ private:
|
||||
UIDefineAttributeDialog *defineAttributeDialog;
|
||||
UIDiceRollDialog *diceRollDialog;
|
||||
UIHuntDialog *huntDialog;
|
||||
UICityLevelDialog *cityLevelDialog;
|
||||
|
||||
UITBWindow *command_window;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user