game: better city level window

This commit is contained in:
Crypto City 2020-04-21 23:24:45 +00:00
parent 9f16dc3047
commit 8995df508a
9 changed files with 332 additions and 1 deletions

View 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

View 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"

View File

@ -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)

View File

@ -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);

View File

@ -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
View 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
View 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

View File

@ -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)

View File

@ -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;