forked from townforge/townforge
players can now have a title
chosen among a set of predefined components
This commit is contained in:
parent
ffe4b0df3b
commit
2c378941dd
41
GameData/TB/cc/change-title.tb.txt
Normal file
41
GameData/TB/cc/change-title.tb.txt
Normal file
@ -0,0 +1,41 @@
|
||||
WindowInfo
|
||||
title Change title
|
||||
centered-relative-size: 0.6 0.4
|
||||
modal: 1
|
||||
|
||||
TBLayout: axis: y, distribution-position: "left top", distribution: "gravity"
|
||||
|
||||
TBLayout: axis: x
|
||||
TBTextField: text: "You title currently is:"
|
||||
TBTextField: id: "current-title"
|
||||
|
||||
TBSeparator
|
||||
|
||||
TBLayout: axis: x
|
||||
TBClickLabel: text: "Compound:"
|
||||
TBRadioButton: id: "style-compound", group-id: "style", data: 0, value: 1
|
||||
TBClickLabel: text: "Unique:"
|
||||
TBRadioButton: id: "style-unique", group-id: "style", data: 1, value: 0
|
||||
|
||||
TBToggleContainer: id: "toggle-style-compound", toggle: "expanded", value: 1
|
||||
TBLayout: axis: y
|
||||
TBTextField: text: "You can build your title from available components"
|
||||
TBTextField: text: "All components are optional"
|
||||
TBLayout: axis: x
|
||||
TBSelectDropdown: id: "adjectives"
|
||||
TBSelectDropdown: id: "nouns"
|
||||
TBSelectDropdown: id: "origins"
|
||||
|
||||
TBToggleContainer: id: "toggle-style-unique", toggle: "expanded", value: 0
|
||||
TBLayout: axis: x
|
||||
TBSelectDropdown: id: "uniques"
|
||||
|
||||
TBSeparator
|
||||
|
||||
TBLayout: axis: x
|
||||
TBTextField: text: "New title:"
|
||||
TBTextField: id: "new-title"
|
||||
|
||||
TBLayout: axis: x
|
||||
TBButton: text: "OK", id: "ok"
|
||||
TBButton: text: "Cancel", id: "cancel"
|
@ -16,49 +16,53 @@ TBTabContainer
|
||||
TBButton: text: "History"
|
||||
TBButton: text: "Invitations"
|
||||
|
||||
TBLayout: axis: x, distribution: "gravity"
|
||||
TBLayout: axis: y, distribution: "gravity", gravity: "top bottom", distribution-position: "left", size: "available"
|
||||
TBLayout: axis: x, distribution-position: "top", gravity: "top"
|
||||
TBLayout: axis: y, distribution-position: "top left"
|
||||
TBLayout: axis: x, distribution-position: "left top"
|
||||
TBTextField: text: "Name:"
|
||||
TBTextField: id: "name"
|
||||
TBButton: id: "select-account", text: "Select other"
|
||||
TBLayout: axis: x, distribution-position: "left top"
|
||||
TBTextField: text: "Level:"
|
||||
TBTextField: id: "level"
|
||||
TBButton: id: "level-up", text: "Level up"
|
||||
TBLayout: axis: x, distribution-position: "left top"
|
||||
TBTextField: text: "Prestige:"
|
||||
TBTextField: id: "prestige-main"
|
||||
TBLayout: axis: x, distribution-position: "left top"
|
||||
TBTextField: text: "Player ID:"
|
||||
TBTextField: id: "id"
|
||||
TBLayout: axis: x, distribution-position: "left top"
|
||||
TBTextField: text: "Public key:"
|
||||
TBEditField: id: "public_key", readonly: 1, multiline: 0, adapt-to-content: 1, skin: "TBEditField.public-key"
|
||||
font: size: 12px
|
||||
TBLayout: axis: x, distribution-position: "left top"
|
||||
TBTextField: text: "Balance:"
|
||||
TBTextField: id: "balance"
|
||||
TBLayout: axis: y, distribution-position: "top right"
|
||||
TBButton: id: "give-money", text: "Give gold"
|
||||
TBButton: id: "give-items", text: "Give items"
|
||||
TBButton: id: "give-land", text: "Give land"
|
||||
TBButton: id: "send-message", text: "Send message"
|
||||
TBSelectList: id: "attributes"
|
||||
TBClickLabel: text: "Ignore", gravity: "bottom"
|
||||
TBCheckBox: id: "ignore"
|
||||
TBLayout: axis: y, distribution: "gravity"
|
||||
TBEditField: id: "player-profile", text: "", multiline: 1, gravity: "all", placeholder: "Player profile"
|
||||
TBToggleContainer: id: "profile-error-container", toggle: "expanded", gravity: "left right"
|
||||
TBLayout: axis: x, distribution: "gravity", distribution-position: "left"
|
||||
TBImageWidget: filename: "images/warning.png"
|
||||
lp:
|
||||
width: 24
|
||||
height: 24
|
||||
TBTextField: id: "profile-error", gravity: "left right", text-align: "left", skin: "text-error"
|
||||
TBButton: id: "save-player-profile", text: "Save"
|
||||
TBLayout: axis: y, distribution: "gravity"
|
||||
TBTextField
|
||||
TBTextField: id: "title", gravity: "left right", text-align: "center", underline: 1, skin: "title-link"
|
||||
TBTextField
|
||||
TBLayout: axis: x, distribution: "gravity"
|
||||
TBLayout: axis: y, distribution: "gravity", gravity: "top bottom", distribution-position: "left", size: "available"
|
||||
TBLayout: axis: x, distribution-position: "top", gravity: "top"
|
||||
TBLayout: axis: y, distribution-position: "top left"
|
||||
TBLayout: axis: x, distribution-position: "left top"
|
||||
TBTextField: text: "Name:"
|
||||
TBTextField: id: "name"
|
||||
TBButton: id: "select-account", text: "Select other"
|
||||
TBLayout: axis: x, distribution-position: "left top"
|
||||
TBTextField: text: "Level:"
|
||||
TBTextField: id: "level"
|
||||
TBButton: id: "level-up", text: "Level up"
|
||||
TBLayout: axis: x, distribution-position: "left top"
|
||||
TBTextField: text: "Prestige:"
|
||||
TBTextField: id: "prestige-main"
|
||||
TBLayout: axis: x, distribution-position: "left top"
|
||||
TBTextField: text: "Player ID:"
|
||||
TBTextField: id: "id"
|
||||
TBLayout: axis: x, distribution-position: "left top"
|
||||
TBTextField: text: "Public key:"
|
||||
TBEditField: id: "public_key", readonly: 1, multiline: 0, adapt-to-content: 1, skin: "TBEditField.public-key"
|
||||
font: size: 12px
|
||||
TBLayout: axis: x, distribution-position: "left top"
|
||||
TBTextField: text: "Balance:"
|
||||
TBTextField: id: "balance"
|
||||
TBLayout: axis: y, distribution-position: "top right"
|
||||
TBButton: id: "give-money", text: "Give gold"
|
||||
TBButton: id: "give-items", text: "Give items"
|
||||
TBButton: id: "give-land", text: "Give land"
|
||||
TBButton: id: "send-message", text: "Send message"
|
||||
TBSelectList: id: "attributes"
|
||||
TBClickLabel: text: "Ignore", gravity: "bottom"
|
||||
TBCheckBox: id: "ignore"
|
||||
TBLayout: axis: y, distribution: "gravity"
|
||||
TBEditField: id: "player-profile", text: "", multiline: 1, gravity: "all", placeholder: "Player profile"
|
||||
TBToggleContainer: id: "profile-error-container", toggle: "expanded", gravity: "left right"
|
||||
TBLayout: axis: x, distribution: "gravity", distribution-position: "left"
|
||||
TBImageWidget: filename: "images/warning.png"
|
||||
lp:
|
||||
width: 24
|
||||
height: 24
|
||||
TBTextField: id: "profile-error", gravity: "left right", text-align: "left", skin: "text-error"
|
||||
TBButton: id: "save-player-profile", text: "Save"
|
||||
|
||||
TBLayout: axis: y, distribution-position: "left top", distribution: "gravity"
|
||||
TBLayout: axis: x, distribution: "gravity"
|
||||
|
@ -328,6 +328,9 @@ elements
|
||||
history-new-tag:
|
||||
text-color #cf3f3f
|
||||
|
||||
title-link:
|
||||
text-color: #71ebc4
|
||||
|
||||
# litehtml
|
||||
litehtml.list-marker.circle: type: Image, bitmap: litehtml/list-marker.circle.png, min-width: 3, min-height: 3
|
||||
litehtml.list-marker.disc: type: Image, bitmap: litehtml/list-marker.disc.png, min-width: 3, min-height: 3
|
||||
|
@ -799,6 +799,20 @@ bool BlockchainDB::change_cc_account_num_pearls_found(uint32_t id, int32_t delta
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BlockchainDB::set_cc_account_title(uint32_t id, int32_t adjective, int32_t noun, int32_t origin, int32_t unique, const std::string &title)
|
||||
{
|
||||
cryptonote::cc_account_data_t ad;
|
||||
if (!get_cc_account_data(id, ad))
|
||||
return false;
|
||||
ad.title_adjective = adjective;
|
||||
ad.title_noun = noun;
|
||||
ad.title_origin = origin;
|
||||
ad.title_unique = unique;
|
||||
ad.title = title;
|
||||
set_cc_account_data(id, ad);
|
||||
return true;
|
||||
}
|
||||
|
||||
void BlockchainDB::reset_stats()
|
||||
{
|
||||
num_calls = 0;
|
||||
|
@ -212,6 +212,13 @@ struct cc_account_data_t
|
||||
|
||||
std::vector<uint32_t> textures_created;
|
||||
std::vector<uint32_t> textures_licenced;
|
||||
|
||||
std::vector<std::string> unique_titles;
|
||||
int32_t title_adjective;
|
||||
int32_t title_noun;
|
||||
int32_t title_origin;
|
||||
int32_t title_unique;
|
||||
std::string title;
|
||||
};
|
||||
|
||||
struct cc_flag_data_t
|
||||
@ -2052,6 +2059,8 @@ public:
|
||||
virtual void unreserve_cc_account(uint32_t id, uint32_t account, uint64_t balance, const std::map<uint32_t, uint32_t> &items) = 0;
|
||||
virtual void set_cc_account_script_variable(uint32_t id, const std::string &name, uint64_t value, bool local) = 0;
|
||||
virtual void set_cc_account_prestige(uint32_t id, uint64_t prestige) = 0;
|
||||
virtual void grant_cc_account_unique_title(uint32_t id, const std::string &unique_title) = 0;
|
||||
virtual void rescind_cc_account_unique_title(uint32_t id, const std::string &unique_title) = 0;
|
||||
virtual bool for_all_cc_accounts(std::function<bool(const cc_account_data_t&)>) const = 0;
|
||||
|
||||
virtual uint32_t allocate_new_cc_city(uint32_t seed, uint32_t mayor, const std::string &name, const std::string &tagline) = 0;
|
||||
@ -2287,6 +2296,7 @@ public:
|
||||
bool change_cc_account_gold_smelted(uint32_t id, int64_t delta);
|
||||
bool change_cc_account_num_auctions_created(uint32_t id, int32_t delta);
|
||||
bool change_cc_account_num_pearls_found(uint32_t id, int32_t delta);
|
||||
bool set_cc_account_title(uint32_t id, int32_t adjective, int32_t noun, int32_t origin, int32_t unique, const std::string &title);
|
||||
|
||||
virtual void remove_block() = 0;
|
||||
|
||||
|
@ -661,6 +661,12 @@ typedef struct mdb_cc_account_data
|
||||
serializable_map<uint32_t, std::tuple<uint32_t, uint32_t, uint32_t, background_script_state_locals_t>> background_script_states;
|
||||
std::vector<uint32_t> textures_created;
|
||||
std::vector<uint32_t> textures_licenced;
|
||||
std::vector<std::string> unique_titles;
|
||||
int32_t title_adjective;
|
||||
int32_t title_noun;
|
||||
int32_t title_origin;
|
||||
int32_t title_unique;
|
||||
std::string title;
|
||||
|
||||
BEGIN_SERIALIZE_OBJECT()
|
||||
VERSION_FIELD(0) // do not allow going over 1 byte without changing fast balance get/set/change
|
||||
@ -702,6 +708,12 @@ typedef struct mdb_cc_account_data
|
||||
FIELD(background_script_states)
|
||||
FIELD(textures_created)
|
||||
FIELD(textures_licenced)
|
||||
FIELD(unique_titles)
|
||||
VARINT_FIELD_SIGNED(title_adjective)
|
||||
VARINT_FIELD_SIGNED(title_noun)
|
||||
VARINT_FIELD_SIGNED(title_origin)
|
||||
VARINT_FIELD_SIGNED(title_unique)
|
||||
FIELD(title)
|
||||
END_SERIALIZE()
|
||||
} mdb_cc_account_data;
|
||||
|
||||
@ -5796,6 +5808,10 @@ uint32_t BlockchainLMDB::allocate_new_cc_account(const crypto::public_key &publi
|
||||
ad.demonetized = 0;
|
||||
ad.num_auctions_created = 0;
|
||||
ad.num_pearls_found = 0;
|
||||
ad.title_adjective = -1;
|
||||
ad.title_noun = -1;
|
||||
ad.title_origin = -1;
|
||||
ad.title_unique = -1;
|
||||
|
||||
k.mv_data = (void*)&account_id;
|
||||
k.mv_size = sizeof(account_id);
|
||||
@ -5971,6 +5987,12 @@ bool BlockchainLMDB::get_cc_account_data(uint32_t id, cc_account_data_t &data) c
|
||||
}
|
||||
data.textures_created = std::move(ad.textures_created);
|
||||
data.textures_licenced = std::move(ad.textures_licenced);
|
||||
data.unique_titles = std::move(ad.unique_titles);
|
||||
data.title_adjective = ad.title_adjective;
|
||||
data.title_noun = ad.title_noun;
|
||||
data.title_origin = ad.title_origin;
|
||||
data.title_unique = ad.title_unique;
|
||||
data.title = std::move(ad.title);
|
||||
|
||||
TXN_POSTFIX_RDONLY();
|
||||
return true;
|
||||
@ -6051,6 +6073,12 @@ void BlockchainLMDB::set_cc_account_data(uint32_t id, const cc_account_data_t &a
|
||||
|
||||
cad.textures_created = ad.textures_created;
|
||||
cad.textures_licenced = ad.textures_licenced;
|
||||
cad.unique_titles = ad.unique_titles;
|
||||
cad.title_adjective = ad.title_adjective;
|
||||
cad.title_noun = ad.title_noun;
|
||||
cad.title_origin = ad.title_origin;
|
||||
cad.title_unique = ad.title_unique;
|
||||
cad.title = ad.title;
|
||||
|
||||
if (!write_account_data(v, cad))
|
||||
throw0(DB_ERROR("Failed to serialize account data"));
|
||||
@ -6837,6 +6865,69 @@ void BlockchainLMDB::set_cc_account_prestige(uint32_t id, uint64_t prestige)
|
||||
throw0(DB_ERROR(lmdb_error("Failed to add account data to db transaction: ", result).c_str()));
|
||||
}
|
||||
|
||||
void BlockchainLMDB::grant_cc_account_unique_title(uint32_t id, const std::string &unique_title)
|
||||
{
|
||||
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
||||
check_open();
|
||||
mdb_txn_cursors *m_cursors = &m_wcursors;
|
||||
|
||||
CURSOR(cc_accounts)
|
||||
|
||||
// find account id
|
||||
MDB_val_set(k, id);
|
||||
MDB_val v;
|
||||
int result = mdb_cursor_get(m_cur_cc_accounts, &k, &v, MDB_SET);
|
||||
if (result)
|
||||
throw0(DB_ERROR(lmdb_error("Account " + std::to_string(id) + " not found: ", result).c_str()));
|
||||
|
||||
mdb_cc_account_data ad;
|
||||
if (!read_account_data(v, ad))
|
||||
throw0(DB_ERROR("Failed to deserialize account data"));
|
||||
|
||||
ad.unique_titles.push_back(unique_title);
|
||||
|
||||
if (!write_account_data(v, ad))
|
||||
throw0(DB_ERROR("Failed to serialize account data"));
|
||||
|
||||
result = mdb_cursor_put(m_cur_cc_accounts, &k, &v, 0);
|
||||
if (v.mv_data) free(v.mv_data);
|
||||
if (result)
|
||||
throw0(DB_ERROR(lmdb_error("Failed to add account data to db transaction: ", result).c_str()));
|
||||
}
|
||||
|
||||
void BlockchainLMDB::rescind_cc_account_unique_title(uint32_t id, const std::string &unique_title)
|
||||
{
|
||||
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
||||
check_open();
|
||||
mdb_txn_cursors *m_cursors = &m_wcursors;
|
||||
|
||||
CURSOR(cc_accounts)
|
||||
|
||||
// find account id
|
||||
MDB_val_set(k, id);
|
||||
MDB_val v;
|
||||
int result = mdb_cursor_get(m_cur_cc_accounts, &k, &v, MDB_SET);
|
||||
if (result)
|
||||
throw0(DB_ERROR(lmdb_error("Account " + std::to_string(id) + " not found: ", result).c_str()));
|
||||
|
||||
mdb_cc_account_data ad;
|
||||
if (!read_account_data(v, ad))
|
||||
throw0(DB_ERROR("Failed to deserialize account data"));
|
||||
|
||||
if (ad.unique_titles.empty() || ad.unique_titles.back() != unique_title)
|
||||
throw0(DB_ERROR("Unexpected last unique title in account data"));
|
||||
|
||||
ad.unique_titles.pop_back();
|
||||
|
||||
if (!write_account_data(v, ad))
|
||||
throw0(DB_ERROR("Failed to serialize account data"));
|
||||
|
||||
result = mdb_cursor_put(m_cur_cc_accounts, &k, &v, 0);
|
||||
if (v.mv_data) free(v.mv_data);
|
||||
if (result)
|
||||
throw0(DB_ERROR(lmdb_error("Failed to add account data to db transaction: ", result).c_str()));
|
||||
}
|
||||
|
||||
bool BlockchainLMDB::for_all_cc_accounts(std::function<bool(const cc_account_data_t &data)> f) const
|
||||
{
|
||||
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
||||
@ -6917,6 +7008,12 @@ bool BlockchainLMDB::for_all_cc_accounts(std::function<bool(const cc_account_dat
|
||||
|
||||
data.textures_created = std::move(ad.textures_created);
|
||||
data.textures_licenced = std::move(ad.textures_licenced);
|
||||
data.unique_titles = std::move(ad.unique_titles);
|
||||
data.title_adjective = ad.title_adjective;
|
||||
data.title_noun = ad.title_noun;
|
||||
data.title_origin = ad.title_origin;
|
||||
data.title_unique = ad.title_unique;
|
||||
data.title = std::move(ad.title);
|
||||
|
||||
if (!f(data))
|
||||
{
|
||||
@ -10739,6 +10836,12 @@ bool BlockchainLMDB::get_as_cc_account(const cryptonote::blobdata &bd, cc_accoun
|
||||
}
|
||||
data.textures_created = std::move(ad.textures_created);
|
||||
data.textures_licenced = std::move(ad.textures_licenced);
|
||||
data.unique_titles = std::move(ad.unique_titles);
|
||||
data.title_adjective = ad.title_adjective;
|
||||
data.title_noun = ad.title_noun;
|
||||
data.title_origin = ad.title_origin;
|
||||
data.title_unique = ad.title_unique;
|
||||
data.title = std::move(ad.title);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -574,6 +574,8 @@ private:
|
||||
void unreserve_cc_account(uint32_t id, uint32_t account, uint64_t balance, const std::map<uint32_t, uint32_t> &items);
|
||||
void set_cc_account_script_variable(uint32_t id, const std::string &name, uint64_t value, bool local);
|
||||
void set_cc_account_prestige(uint32_t id, uint64_t prestige);
|
||||
void grant_cc_account_unique_title(uint32_t id, const std::string &unique_title);
|
||||
void rescind_cc_account_unique_title(uint32_t id, const std::string &unique_title);
|
||||
bool for_all_cc_accounts(std::function<bool(const cc_account_data_t&)>) const;
|
||||
|
||||
uint32_t allocate_new_cc_city(uint32_t seed, uint32_t mayor, const std::string &name, const std::string &tagline);
|
||||
|
@ -202,6 +202,8 @@ public:
|
||||
virtual void unreserve_cc_account(uint32_t id, uint32_t account, uint64_t balance, const std::map<uint32_t, uint32_t> &items) {}
|
||||
virtual void set_cc_account_script_variable(uint32_t id, const std::string &name, uint64_t value, bool local) {}
|
||||
virtual void set_cc_account_prestige(uint32_t id, uint64_t prestige) {}
|
||||
virtual void grant_cc_account_unique_title(uint32_t id, const std::string &unique_title) {}
|
||||
virtual void rescind_cc_account_unique_title(uint32_t id, const std::string &unique_title) {}
|
||||
virtual bool for_all_cc_accounts(std::function<bool(const cc_account_data_t&)>) const { return true; }
|
||||
|
||||
virtual uint32_t allocate_new_cc_city(uint32_t seed, uint32_t mayor, const std::string &name, const std::string &tagline) { return 0; }
|
||||
|
@ -87,6 +87,7 @@ set(cc_sources
|
||||
cc_command_handler_salt_food.cpp
|
||||
cc_command_handler_script_choice.cpp
|
||||
cc_command_handler_service.cpp
|
||||
cc_command_handler_set_title.cpp
|
||||
cc_command_handler_add_tax_break_zone.cpp
|
||||
cc_command_handler_set_merchant_ship_items.cpp
|
||||
cc_command_handler_set_script_variables.cpp
|
||||
@ -126,6 +127,7 @@ set(cc_sources
|
||||
cc_temperature.cpp
|
||||
cc_terrain.cc
|
||||
cc_terrain_features.cc
|
||||
cc_title.cc
|
||||
cc_whisper.cc
|
||||
cc.cpp
|
||||
dds.c
|
||||
@ -192,6 +194,7 @@ set(cc_headers
|
||||
cc_command_handler_salt_food.h
|
||||
cc_command_handler_script_choice.h
|
||||
cc_command_handler_service.h
|
||||
cc_command_handler_set_title.h
|
||||
cc_command_handler_add_tax_break_zone.h
|
||||
cc_command_handler_set_merchant_ship_items.h
|
||||
cc_command_handler_set_script_variables.h
|
||||
@ -232,6 +235,7 @@ set(cc_headers
|
||||
cc_temperature.h
|
||||
cc_terrain.h
|
||||
cc_terrain_features.h
|
||||
cc_title.h
|
||||
cc.h)
|
||||
|
||||
set(cc_private_headers
|
||||
|
@ -99,6 +99,7 @@
|
||||
#include "cc_command_handler_service.h"
|
||||
#include "cc_command_handler_set_merchant_ship_items.h"
|
||||
#include "cc_command_handler_set_script_variables.h"
|
||||
#include "cc_command_handler_set_title.h"
|
||||
#include "cc_command_handler_add_tax_break_zone.h"
|
||||
#include "cc_command_handler_smelt.h"
|
||||
#include "cc_command_handler_sow.h"
|
||||
@ -4245,6 +4246,7 @@ static cc_command_handler &get_cc_command_handler(const cryptonote::cc_command_t
|
||||
cc_command_handler &operator()(const cryptonote::cc_command_service_t &cmd) const { return cc_command_handler_service::instance; }
|
||||
cc_command_handler &operator()(const cryptonote::cc_command_set_merchant_ship_items_t &cmd) const { return cc_command_handler_set_merchant_ship_items::instance; }
|
||||
cc_command_handler &operator()(const cryptonote::cc_command_set_script_variables_t &cmd) const { return cc_command_handler_set_script_variables::instance; }
|
||||
cc_command_handler &operator()(const cryptonote::cc_command_set_title_t &cmd) const { return cc_command_handler_set_title::instance; }
|
||||
cc_command_handler &operator()(const cryptonote::cc_command_add_tax_break_zone_t &cmd) const { return cc_command_handler_add_tax_break_zone::instance; }
|
||||
cc_command_handler &operator()(const cryptonote::cc_command_smelt_t &cmd) const { return cc_command_handler_smelt::instance; }
|
||||
cc_command_handler &operator()(const cryptonote::cc_command_sow_t &cmd) const { return cc_command_handler_sow::instance; }
|
||||
|
@ -17,6 +17,8 @@ static const struct
|
||||
const char *desc;
|
||||
const char *icon;
|
||||
bool manual;
|
||||
const char *title_adjective;
|
||||
const char *title_noun;
|
||||
uint64_t thresholds[NUM_BADGE_LEVELS];
|
||||
const char *threshold_text[NUM_BADGE_LEVELS];
|
||||
std::string (*convert_score)(uint64_t score);
|
||||
@ -27,6 +29,7 @@ static const struct
|
||||
"Awarded to people who helped prior to launch",
|
||||
"atlas",
|
||||
true,
|
||||
NULL, NULL,
|
||||
{0, 0, 0, 0, 0},
|
||||
{"", "", "", "", ""},
|
||||
NULL
|
||||
@ -36,6 +39,7 @@ static const struct
|
||||
"Awarded for best custom item design",
|
||||
"jeweled-chalice",
|
||||
true,
|
||||
NULL, NULL,
|
||||
{0, 0, 0, 0, 0},
|
||||
{"", "", "", "", ""},
|
||||
NULL
|
||||
@ -45,6 +49,7 @@ static const struct
|
||||
"Awarded for 3D architecture prowess in agricultural buildings",
|
||||
"barn/ribbon-medal",
|
||||
true,
|
||||
NULL, NULL,
|
||||
{0, 0, 0, 0, 0},
|
||||
{"", "", "", "", ""},
|
||||
NULL
|
||||
@ -54,6 +59,7 @@ static const struct
|
||||
"Awarded for 3D architecture prowess in craft buildings",
|
||||
"sword-smithing/ribbon-medal",
|
||||
true,
|
||||
NULL, NULL,
|
||||
{0, 0, 0, 0, 0},
|
||||
{"", "", "", "", ""},
|
||||
NULL
|
||||
@ -63,6 +69,7 @@ static const struct
|
||||
"Awarded for 3D architecture prowess in industrial buildings",
|
||||
"factory/ribbon-medal",
|
||||
true,
|
||||
NULL, NULL,
|
||||
{0, 0, 0, 0, 0},
|
||||
{"", "", "", "", ""},
|
||||
NULL
|
||||
@ -72,6 +79,7 @@ static const struct
|
||||
"Awarded for 3D architecture prowess in commercial buildings",
|
||||
"hanging-sign/ribbon-medal",
|
||||
true,
|
||||
NULL, NULL,
|
||||
{0, 0, 0, 0, 0},
|
||||
{"", "", "", "", ""},
|
||||
NULL
|
||||
@ -81,6 +89,7 @@ static const struct
|
||||
"Awarded for 3D architecture prowess in basic residential buildings",
|
||||
"house/ribbon-medal",
|
||||
true,
|
||||
NULL, NULL,
|
||||
{0, 0, 0, 0, 0},
|
||||
{"", "", "", "", ""},
|
||||
NULL
|
||||
@ -90,6 +99,7 @@ static const struct
|
||||
"Awarded for 3D architecture prowess in affluent residential buildings",
|
||||
"family-house/ribbon-medal",
|
||||
true,
|
||||
NULL, NULL,
|
||||
{0, 0, 0, 0, 0},
|
||||
{"", "", "", "", ""},
|
||||
NULL
|
||||
@ -99,6 +109,7 @@ static const struct
|
||||
"Awarded for 3D architecture prowess in luxury residential buildings",
|
||||
"spooky-house-custom/ribbon-medal",
|
||||
true,
|
||||
NULL, NULL,
|
||||
{0, 0, 0, 0, 0},
|
||||
{"", "", "", "", ""},
|
||||
NULL
|
||||
@ -108,6 +119,7 @@ static const struct
|
||||
"Awarded for 3D architecture prowess in military buildings",
|
||||
"barracks/ribbon-medal",
|
||||
true,
|
||||
NULL, NULL,
|
||||
{0, 0, 0, 0, 0},
|
||||
{"", "", "", "", ""},
|
||||
NULL
|
||||
@ -117,6 +129,7 @@ static const struct
|
||||
"Awarded for 3D architecture prowess in cultural buildings",
|
||||
"egyptian-sphinx/ribbon-medal",
|
||||
true,
|
||||
NULL, NULL,
|
||||
{0, 0, 0, 0, 0},
|
||||
{"", "", "", "", ""},
|
||||
NULL
|
||||
@ -126,6 +139,7 @@ static const struct
|
||||
"Awarded for 3D architecture prowess in stonecutter buildings",
|
||||
"stone-block/ribbon-medal",
|
||||
true,
|
||||
NULL, NULL,
|
||||
{0, 0, 0, 0, 0},
|
||||
{"", "", "", "", ""},
|
||||
NULL
|
||||
@ -135,6 +149,7 @@ static const struct
|
||||
"Awarded for 3D architecture prowess in sawmill buildings",
|
||||
"wood-beam/ribbon-medal",
|
||||
true,
|
||||
NULL, NULL,
|
||||
{0, 0, 0, 0, 0},
|
||||
{"", "", "", "", ""},
|
||||
NULL
|
||||
@ -144,6 +159,7 @@ static const struct
|
||||
"Awarded for 3D architecture prowess in kiln buildings",
|
||||
"brick-pile/ribbon-medal",
|
||||
true,
|
||||
NULL, NULL,
|
||||
{0, 0, 0, 0, 0},
|
||||
{"", "", "", "", ""},
|
||||
NULL
|
||||
@ -153,6 +169,7 @@ static const struct
|
||||
"Awarded for 3D architecture prowess in smelter buildings",
|
||||
"melting-metal/ribbon-medal",
|
||||
true,
|
||||
NULL, NULL,
|
||||
{0, 0, 0, 0, 0},
|
||||
{"", "", "", "", ""},
|
||||
NULL
|
||||
@ -162,6 +179,7 @@ static const struct
|
||||
"Awarded for 3D architecture prowess in workforce buildings",
|
||||
"three-friends/ribbon-medal",
|
||||
true,
|
||||
NULL, NULL,
|
||||
{0, 0, 0, 0, 0},
|
||||
{"", "", "", "", ""},
|
||||
NULL
|
||||
@ -171,6 +189,7 @@ static const struct
|
||||
"Awarded for 3D architecture prowess in road buildings",
|
||||
"tall-bridge/ribbon-medal",
|
||||
true,
|
||||
NULL, NULL,
|
||||
{0, 0, 0, 0, 0},
|
||||
{"", "", "", "", ""},
|
||||
NULL
|
||||
@ -180,6 +199,7 @@ static const struct
|
||||
"Awarded for 3D architecture prowess in research buildings",
|
||||
"base-dome/ribbon-medal",
|
||||
true,
|
||||
NULL, NULL,
|
||||
{0, 0, 0, 0, 0},
|
||||
{"", "", "", "", ""},
|
||||
NULL
|
||||
@ -189,6 +209,7 @@ static const struct
|
||||
"Max number of buildings",
|
||||
"concrete-bag",
|
||||
false,
|
||||
NULL, NULL,
|
||||
{4, 12, 30, 75, 150},
|
||||
{NULL, NULL, NULL, NULL, NULL},
|
||||
NULL
|
||||
@ -198,6 +219,7 @@ static const struct
|
||||
"Max number of building types",
|
||||
"modern-city",
|
||||
false,
|
||||
NULL, NULL,
|
||||
{3, 5, 8, 11, 16},
|
||||
{NULL, NULL, NULL, NULL, NULL},
|
||||
NULL
|
||||
@ -207,6 +229,7 @@ static const struct
|
||||
"Number of blocks in inventory",
|
||||
"wooden-crate",
|
||||
false,
|
||||
NULL, NULL,
|
||||
{100000ull, 250000ull, 750000ull, 5000000ull, 50000000ull},
|
||||
{"100k", "250k", "750k", "5 million", "50 million"},
|
||||
NULL
|
||||
@ -216,6 +239,7 @@ static const struct
|
||||
"Overall size of military buildings",
|
||||
"guards",
|
||||
false,
|
||||
NULL, "soldier",
|
||||
{200000ull, 500000ull, 2000000ull, 5000000ull, 15000000ull},
|
||||
{NULL, NULL, NULL, NULL, NULL},
|
||||
NULL
|
||||
@ -225,6 +249,7 @@ static const struct
|
||||
"Overall size of cultural buildings",
|
||||
"book-cover",
|
||||
false,
|
||||
"cultured", NULL,
|
||||
{200000ull, 500000ull, 2000000ull, 5000000ull, 15000000ull},
|
||||
{NULL, NULL, NULL, NULL, NULL},
|
||||
NULL
|
||||
@ -234,6 +259,7 @@ static const struct
|
||||
"Number of discoveries",
|
||||
"potion-ball",
|
||||
false,
|
||||
NULL, NULL,
|
||||
{1, 3, 8, 16, 25},
|
||||
{NULL, NULL, NULL, NULL, NULL},
|
||||
NULL
|
||||
@ -243,6 +269,7 @@ static const struct
|
||||
"Monetary balance",
|
||||
"gold-stack",
|
||||
false,
|
||||
NULL, NULL,
|
||||
{500 * COIN, 1500 * COIN, 5000 * COIN, 20000 * COIN, 100000 * COIN},
|
||||
{"500", "1500", "5000", "20000", "100000" },
|
||||
[](uint64_t score) { return cryptonote::print_money(score); }
|
||||
@ -252,6 +279,7 @@ static const struct
|
||||
"City level",
|
||||
"village",
|
||||
false,
|
||||
NULL, NULL,
|
||||
{3, 5, 7, 10, 13},
|
||||
{cc::get_town_level_name(3), cc::get_town_level_name(5), cc::get_town_level_name(7), cc::get_town_level_name(10), cc::get_town_level_name(13)},
|
||||
NULL
|
||||
@ -261,6 +289,7 @@ static const struct
|
||||
"Amount of food in inventory",
|
||||
"granary",
|
||||
false,
|
||||
NULL, NULL,
|
||||
{100000, 200000, 500000, 1000000, 2000000},
|
||||
{"100k", "200k ", "500k", "1 million", "2 million"},
|
||||
NULL
|
||||
@ -270,6 +299,7 @@ static const struct
|
||||
"Stature of one residential home",
|
||||
"spooky-house-custom",
|
||||
false,
|
||||
NULL, NULL,
|
||||
{1000000ull, 0x1000000000000 | 1500000ll, 0x1000000000000 | 3000000ll, 0x2000000000000 | 5000000ll, 0x2000000000000 | 15000000ull},
|
||||
{"1 million (any type)", "1.5 million (affluent or luxury", "3 million (affluent or luxury", "5 million (luxury)", "15 million (luxury)"},
|
||||
NULL
|
||||
@ -279,6 +309,7 @@ static const struct
|
||||
"Number of patents",
|
||||
"files",
|
||||
false,
|
||||
NULL, NULL,
|
||||
{5, 10, 15, 25, 50},
|
||||
{NULL, NULL, NULL, NULL, NULL},
|
||||
NULL
|
||||
@ -288,6 +319,7 @@ static const struct
|
||||
"Number of moose killed",
|
||||
"deer-track",
|
||||
false,
|
||||
NULL, "hunter",
|
||||
{100, 250, 500, 1000, 2000},
|
||||
{NULL, NULL, NULL, NULL, NULL},
|
||||
NULL
|
||||
@ -297,6 +329,7 @@ static const struct
|
||||
"Number of bears killed",
|
||||
"polar-bear",
|
||||
false,
|
||||
NULL, "hunter",
|
||||
{20, 50, 100, 250, 1000},
|
||||
{NULL, NULL, NULL, NULL, NULL},
|
||||
NULL
|
||||
@ -306,6 +339,7 @@ static const struct
|
||||
"Number of other players' buildings linked to one's road network",
|
||||
"mesh-network",
|
||||
false,
|
||||
NULL, NULL,
|
||||
{15, 40, 85, 150, 300},
|
||||
{NULL, NULL, NULL, NULL, NULL},
|
||||
NULL
|
||||
@ -315,6 +349,7 @@ static const struct
|
||||
"Amount and quality of owned gemstones",
|
||||
"gems",
|
||||
false,
|
||||
NULL, NULL,
|
||||
{4, 11, 28, 60, 115},
|
||||
{"4 (amethyst: 1, sapphire: 3, emerald: 10, ruby: 25, diamond: 75)", NULL, NULL, NULL, NULL},
|
||||
NULL
|
||||
@ -324,6 +359,7 @@ static const struct
|
||||
"Distance between a new building and the nearest other",
|
||||
"horizon-road",
|
||||
false,
|
||||
NULL, NULL,
|
||||
{500, 1250, 3000, 10000, 30000},
|
||||
{NULL, NULL, NULL, NULL, NULL},
|
||||
NULL
|
||||
@ -333,6 +369,7 @@ static const struct
|
||||
"Date of construction of oldest building from the start of the game",
|
||||
"conqueror",
|
||||
false,
|
||||
NULL, "forebear",
|
||||
#define DAYS(x) std::numeric_limits<uint64_t>::max() - ((x) * 86400 / DIFFICULTY_TARGET_V2)
|
||||
{DAYS(366), DAYS(100), DAYS(30), DAYS(10), DAYS(3)},
|
||||
#undef DAYS
|
||||
@ -344,6 +381,7 @@ static const struct
|
||||
"Number of game ticks in a row a badge is gained",
|
||||
"upgrade",
|
||||
false,
|
||||
"relentless", NULL,
|
||||
{3, 5, 7, 9, 12},
|
||||
{NULL, NULL, NULL, NULL, NULL},
|
||||
NULL
|
||||
@ -353,6 +391,7 @@ static const struct
|
||||
"Number of others brought to the game",
|
||||
"backup",
|
||||
false,
|
||||
"rallying", NULL,
|
||||
{2, 8, 30, 100, 250},
|
||||
{NULL, NULL, NULL, NULL, NULL},
|
||||
NULL
|
||||
@ -362,6 +401,7 @@ static const struct
|
||||
"Number of fires put out",
|
||||
"arson",
|
||||
false,
|
||||
NULL, NULL,
|
||||
{3, 8, 20, 50, 150},
|
||||
{NULL, NULL, NULL, NULL, NULL},
|
||||
NULL
|
||||
@ -371,6 +411,7 @@ static const struct
|
||||
"Number of buildings demolished",
|
||||
"wrecking-ball",
|
||||
false,
|
||||
NULL, NULL,
|
||||
{3, 10, 25, 50, 100},
|
||||
{NULL, NULL, NULL, NULL, NULL},
|
||||
NULL
|
||||
@ -380,6 +421,7 @@ static const struct
|
||||
"Number of city levels lost from its highest point",
|
||||
"ancient-ruins",
|
||||
false,
|
||||
NULL, NULL,
|
||||
{1, 2, 3, 4, 5},
|
||||
{NULL, NULL, NULL, NULL, NULL},
|
||||
NULL
|
||||
@ -389,6 +431,7 @@ static const struct
|
||||
"Owns a non-road building above an elevation threshold",
|
||||
"mountain-road",
|
||||
false,
|
||||
NULL, "mountaineer",
|
||||
{3000, 3500, 3800, 3900, 4000},
|
||||
{"3000 ft", "3500 ft", "3800 ft", "3900 ft", "4000 ft"},
|
||||
[](uint64_t score) { return std::to_string(score) + " ft"; }
|
||||
@ -398,6 +441,7 @@ static const struct
|
||||
"Total field area planted with vegetables at any one time",
|
||||
"peas",
|
||||
false,
|
||||
NULL, "farmer",
|
||||
{5000, 15000, 50000, 200000, 1000000},
|
||||
{NULL, NULL, NULL, NULL, NULL},
|
||||
NULL
|
||||
@ -407,6 +451,7 @@ static const struct
|
||||
"Total field area planted with grain at any one time",
|
||||
"round-straw-bale",
|
||||
false,
|
||||
NULL, "farmer",
|
||||
{5000, 15000, 50000, 200000, 1000000},
|
||||
{NULL, NULL, NULL, NULL, NULL},
|
||||
NULL
|
||||
@ -416,6 +461,7 @@ static const struct
|
||||
"Number of different collectible coins owned",
|
||||
"crown-coin",
|
||||
false,
|
||||
NULL, "numismatist",
|
||||
{5, 10, 15, 25, 50},
|
||||
{NULL, NULL, NULL, NULL, NULL},
|
||||
NULL
|
||||
@ -425,6 +471,7 @@ static const struct
|
||||
"Oldest collectible coin owned (from the beginning of the game - excludes newbie coins)",
|
||||
"crown-coin",
|
||||
false,
|
||||
NULL, NULL,
|
||||
#define DAYS(x) std::numeric_limits<uint64_t>::max() - ((x) * 86400 / DIFFICULTY_TARGET_V2)
|
||||
{DAYS(1500), DAYS(365), DAYS(100), DAYS(30), DAYS(5)},
|
||||
#undef DAYS
|
||||
@ -436,6 +483,7 @@ static const struct
|
||||
"Number of collectible coins owned, regardless of type",
|
||||
"crown-coin",
|
||||
false,
|
||||
NULL, NULL,
|
||||
{10, 25, 75, 200, 500},
|
||||
{NULL, NULL, NULL, NULL, NULL},
|
||||
NULL
|
||||
@ -445,6 +493,7 @@ static const struct
|
||||
"Number of different custom items owned with at least 10 gold per item",
|
||||
"open-treasure-chest",
|
||||
false,
|
||||
NULL, NULL,
|
||||
{5, 10, 15, 25, 50},
|
||||
{NULL, NULL, NULL, NULL, NULL},
|
||||
NULL
|
||||
@ -454,6 +503,7 @@ static const struct
|
||||
"Number of game ticks a building was on fire before being doused still standing",
|
||||
"dice-fire",
|
||||
false,
|
||||
NULL, NULL,
|
||||
{5, 10, 15, 20, 25},
|
||||
{NULL, NULL, NULL, NULL, NULL},
|
||||
NULL
|
||||
@ -463,6 +513,7 @@ static const struct
|
||||
"Number of cities in which you have at least one building",
|
||||
"huts-village",
|
||||
false,
|
||||
NULL, NULL,
|
||||
{2, 3, 4, 5, 6},
|
||||
{NULL, NULL, NULL, NULL, NULL},
|
||||
NULL
|
||||
@ -472,6 +523,7 @@ static const struct
|
||||
"Maximum altitude difference over a single flag",
|
||||
"peaks",
|
||||
false,
|
||||
NULL, NULL,
|
||||
{200 * HEIGHT_UNITS_PER_BLOCK, 250 * HEIGHT_UNITS_PER_BLOCK, 300 * HEIGHT_UNITS_PER_BLOCK, 350 * HEIGHT_UNITS_PER_BLOCK, 400 * HEIGHT_UNITS_PER_BLOCK},
|
||||
{"200 ft", "250 ft", "300 ft", "350 ft", "400 ft"},
|
||||
[](uint64_t score) { return std::to_string(score / HEIGHT_UNITS_PER_BLOCK) + " ft"; }
|
||||
@ -481,6 +533,7 @@ static const struct
|
||||
"The road with the highest bridge potential",
|
||||
"tall-bridge",
|
||||
false,
|
||||
NULL, NULL,
|
||||
{500, 700, 800, 900, 1000},
|
||||
{NULL, NULL, NULL, NULL, NULL},
|
||||
NULL
|
||||
@ -490,6 +543,7 @@ static const struct
|
||||
"Collect all the newbie coin variants",
|
||||
"backpack",
|
||||
false,
|
||||
NULL, NULL,
|
||||
{2, 3, 4, 5, 6},
|
||||
{NULL, NULL, NULL, NULL, NULL},
|
||||
NULL
|
||||
@ -499,6 +553,7 @@ static const struct
|
||||
"Number of buildings on a single island",
|
||||
"island",
|
||||
false,
|
||||
NULL, NULL,
|
||||
{1, 2, 3, 4, 5},
|
||||
{"1 (the island must be enclosed in a single newly named rectangular area, all boundaries of which have to be wholly in water)", NULL, NULL, NULL, NULL},
|
||||
NULL
|
||||
@ -508,6 +563,7 @@ static const struct
|
||||
"Number of places named",
|
||||
"direction-sign",
|
||||
false,
|
||||
NULL, "mapmaker",
|
||||
{5, 10, 15, 25, 50},
|
||||
{NULL, NULL, NULL, NULL, NULL},
|
||||
NULL
|
||||
@ -517,6 +573,7 @@ static const struct
|
||||
"Found and named different types of terrain features",
|
||||
"treasure-map",
|
||||
false,
|
||||
NULL, NULL,
|
||||
{2, 3, 5, 7, 10},
|
||||
{"2 (open sea, sand bank, beach, peak, island, lake, plain, reef, peninsula, cove)", NULL, NULL, NULL, NULL},
|
||||
NULL
|
||||
@ -526,6 +583,7 @@ static const struct
|
||||
"Number of rare fish species discovered",
|
||||
"angler-fish",
|
||||
false,
|
||||
NULL, NULL,
|
||||
{1, 3, 5, 8, 12},
|
||||
{NULL, NULL, NULL, NULL, NULL},
|
||||
NULL
|
||||
@ -535,6 +593,7 @@ static const struct
|
||||
"Number of textures added",
|
||||
"paint-roller",
|
||||
false,
|
||||
NULL, "artist",
|
||||
{1, 2, 4, 4, 5},
|
||||
{NULL, NULL, NULL, NULL, NULL},
|
||||
NULL
|
||||
@ -544,6 +603,7 @@ static const struct
|
||||
"Number of textures licenced",
|
||||
"coinflip",
|
||||
false,
|
||||
NULL, NULL,
|
||||
{2, 5, 10, 15, 25},
|
||||
{NULL, NULL, NULL, NULL, NULL},
|
||||
NULL
|
||||
@ -553,6 +613,7 @@ static const struct
|
||||
"Number of runestones carved",
|
||||
"rune-stone",
|
||||
false,
|
||||
"erudite", NULL,
|
||||
{5, 10, 20, 50, 100},
|
||||
{NULL, NULL, NULL, NULL, NULL},
|
||||
NULL
|
||||
@ -562,6 +623,7 @@ static const struct
|
||||
"Amount of gold smelted",
|
||||
"melting-metal",
|
||||
false,
|
||||
NULL, NULL,
|
||||
{10 * COIN, 50 * COIN, 250 * COIN, 1000 * COIN, 5000 * COIN},
|
||||
{"10", "50", "250", "1000", "5000"},
|
||||
[](uint64_t score) { return cryptonote::print_money(score); }
|
||||
@ -571,6 +633,7 @@ static const struct
|
||||
"Number of auctions created",
|
||||
"hammer-drop",
|
||||
false,
|
||||
NULL, NULL,
|
||||
{3, 10, 25, 75, 250},
|
||||
{NULL, NULL, NULL, NULL, NULL},
|
||||
NULL
|
||||
@ -580,6 +643,7 @@ static const struct
|
||||
"Number of pearls found",
|
||||
"oyster-pearl",
|
||||
false,
|
||||
NULL, NULL,
|
||||
{5, 10, 20, 50, 100},
|
||||
{NULL, NULL, NULL, NULL, NULL},
|
||||
NULL
|
||||
@ -589,6 +653,7 @@ static const struct
|
||||
"Amount of fish caught",
|
||||
"boat-fishing",
|
||||
false,
|
||||
NULL, NULL,
|
||||
{500000, 1000000, 2000000, 5000000, 20000000},
|
||||
{NULL, NULL, NULL, NULL, NULL},
|
||||
NULL
|
||||
@ -598,6 +663,7 @@ static const struct
|
||||
"Awarded to encyclopedia writers",
|
||||
"book-pile",
|
||||
true,
|
||||
"erudite", NULL,
|
||||
{0, 0, 0, 0, 0},
|
||||
{"", "", "", "", ""},
|
||||
NULL
|
||||
@ -607,6 +673,7 @@ static const struct
|
||||
"Number of different quest items owned",
|
||||
"open-treasure-chest",
|
||||
false,
|
||||
NULL, "hero",
|
||||
{5, 10, 15, 25, 50},
|
||||
{NULL, NULL, NULL, NULL, NULL},
|
||||
NULL
|
||||
@ -616,6 +683,7 @@ static const struct
|
||||
"Number of epochs covered by coins owned",
|
||||
"crown-coin/time-trap",
|
||||
false,
|
||||
NULL, NULL,
|
||||
{3, 5, 7, 10, 15},
|
||||
{NULL, NULL, NULL, NULL, NULL},
|
||||
NULL
|
||||
@ -625,6 +693,7 @@ static const struct
|
||||
"Number of epochs covered by buildings owned",
|
||||
"time-trap",
|
||||
false,
|
||||
NULL, NULL,
|
||||
{3, 5, 7, 10, 15},
|
||||
{NULL, NULL, NULL, NULL, NULL},
|
||||
NULL
|
||||
@ -634,6 +703,7 @@ static const struct
|
||||
"Number of cons smelted which weren't mintable anymore (excluding newbie coins)",
|
||||
"crown-coin/melting-metal",
|
||||
false,
|
||||
NULL, NULL,
|
||||
{10, 25, 50, 100, 250},
|
||||
{NULL, NULL, NULL, NULL, NULL},
|
||||
NULL
|
||||
@ -658,6 +728,10 @@ bool get_badge_data(const cryptonote::BlockchainDB *db, cc_badge_t badge, cc_bad
|
||||
data.desc = predefined_badges_data[badge].desc;
|
||||
data.icon = predefined_badges_data[badge].icon;
|
||||
data.manual = predefined_badges_data[badge].manual;
|
||||
if (predefined_badges_data[badge].title_adjective)
|
||||
data.title_adjective = predefined_badges_data[badge].title_adjective;
|
||||
if (predefined_badges_data[badge].title_noun)
|
||||
data.title_noun = predefined_badges_data[badge].title_noun;
|
||||
data.convert_score = predefined_badges_data[badge].convert_score;
|
||||
data.thresholds.resize(NUM_BADGE_LEVELS);
|
||||
for (int i = 0; i < NUM_BADGE_LEVELS; ++i)
|
||||
|
@ -112,6 +112,8 @@ struct cc_badge_data_t
|
||||
std::string desc;
|
||||
std::string icon;
|
||||
bool manual;
|
||||
std::string title_adjective;
|
||||
std::string title_noun;
|
||||
std::vector<std::pair<uint64_t, std::string>> thresholds;
|
||||
std::string (*convert_score)(uint64_t score);
|
||||
};
|
||||
|
@ -305,4 +305,9 @@ cc::cc_epoch_t BlockchainStateProxy::get_cc_epoch(uint64_t height)
|
||||
return db.get_cc_epoch(height);
|
||||
}
|
||||
|
||||
void BlockchainStateProxy::grant_unique_title(uint32_t id, const std::string title)
|
||||
{
|
||||
unique_titles.push_back(std::make_pair(id, title));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -57,6 +57,7 @@ public:
|
||||
virtual std::pair<uint8_t, uint64_t> get_badge_level(uint32_t id, uint32_t badge);
|
||||
virtual void award_badge(uint32_t id, uint32_t badge, uint8_t dlevel, uint64_t dtimestamp);
|
||||
virtual cc::cc_epoch_t get_cc_epoch(uint64_t height);
|
||||
virtual void grant_unique_title(uint32_t id, const std::string title);
|
||||
|
||||
const std::map<std::pair<uint32_t, uint32_t>, int64_t> &get_balance_reserve_deltas() const { return balance_reserve_delta; }
|
||||
const std::map<std::tuple<uint32_t, uint32_t, uint32_t>, int32_t> &get_item_balance_reserve_deltas() const { return item_balance_reserve_delta; }
|
||||
@ -66,6 +67,7 @@ public:
|
||||
const std::map<std::pair<uint32_t, std::string>, int64_t> &get_local_variable_deltas() const { return local_variable_delta; }
|
||||
const std::map<std::pair<uint32_t, uint32_t>, std::pair<uint8_t, uint64_t>> &get_badge_deltas() const { return badge_delta; }
|
||||
const std::set<uint32_t> get_new_background_scripts() const { return new_background_scripts; }
|
||||
const std::vector<std::pair<uint32_t, std::string>> get_new_unique_titles() const { return unique_titles; }
|
||||
|
||||
private:
|
||||
const cryptonote::BlockchainDB &db;
|
||||
@ -77,6 +79,7 @@ private:
|
||||
std::map<std::pair<uint32_t, std::string>, int64_t> local_variable_delta;
|
||||
std::set<uint32_t> new_background_scripts;
|
||||
std::map<std::pair<uint32_t, uint32_t>, std::pair<uint8_t, uint64_t>> badge_delta;
|
||||
std::vector<std::pair<uint32_t, std::string>> unique_titles;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -315,6 +315,10 @@ bool cc_command_handler_script_choice::execute(cryptonote::BlockchainDB &db, con
|
||||
ad.badges[e.badge].second += e.timestamp_delta;
|
||||
db.set_cc_account_badges(e.account, ad.badges);
|
||||
}
|
||||
for (const auto &e: effects.new_unique_titles)
|
||||
{
|
||||
db.grant_cc_account_unique_title(e.first, e.second);
|
||||
}
|
||||
|
||||
if (cc::script::is_end_state(script, new_state))
|
||||
{
|
||||
@ -545,6 +549,10 @@ bool cc_command_handler_script_choice::revert(cryptonote::BlockchainDB &db, cons
|
||||
ad.badges[e.badge].second -= e.timestamp_delta;
|
||||
db.set_cc_account_badges(e.account, ad.badges);
|
||||
}
|
||||
for (const auto &e: effects.new_unique_titles)
|
||||
{
|
||||
db.rescind_cc_account_unique_title(e.first, e.second);
|
||||
}
|
||||
|
||||
// the reserves increase from execute will have been recorded in effects,
|
||||
// therefore already undone, we just have the actual balances to update
|
||||
|
135
src/cc/cc_command_handler_set_title.cpp
Normal file
135
src/cc/cc_command_handler_set_title.cpp
Normal file
@ -0,0 +1,135 @@
|
||||
// Copyright (c) 2019, Crypto City
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are
|
||||
// permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
// conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
// of conditions and the following disclaimer in the documentation and/or other
|
||||
// materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without specific
|
||||
// prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "blockchain_db/blockchain_db.h"
|
||||
#include "cc/cc_config.h"
|
||||
#include "cc/cc.h"
|
||||
#include "cc/cc_title.h"
|
||||
#include "cc_command_handler_helpers.h"
|
||||
#include "cc_command_handler_set_title.h"
|
||||
|
||||
#undef MONERO_DEFAULT_LOG_CATEGORY
|
||||
#define MONERO_DEFAULT_LOG_CATEGORY "verify"
|
||||
|
||||
static bool is_present(uint32_t value, const std::vector<std::pair<uint32_t, std::string>> &values)
|
||||
{
|
||||
for (const auto &e: values)
|
||||
if (value == e.first)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
namespace cc
|
||||
{
|
||||
|
||||
cc_command_handler_set_title cc_command_handler_set_title::instance;
|
||||
|
||||
void cc_command_handler_set_title::get_in_out(const cryptonote::cc_command_t &cmd, uint64_t &cc_in, uint64_t &cc_out) const
|
||||
{
|
||||
cc_in = 0;
|
||||
cc_out = 0;
|
||||
}
|
||||
|
||||
uint64_t cc_command_handler_set_title::get_cost(const cryptonote::cc_command_t &cmd) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool cc_command_handler_set_title::check(const cryptonote::BlockchainDB &db, const cryptonote::cc_command_t &cmd, uint8_t hf_version, cryptonote::tx_verification_context &tvc) const
|
||||
{
|
||||
const cryptonote::cc_command_set_title_t &set_title = boost::get<cryptonote::cc_command_set_title_t>(cmd);
|
||||
cryptonote::cc_account_data_t ad;
|
||||
|
||||
CHECK_COMMAND_SET(db.get_cc_account_data(set_title.cc_account, ad), tvc, m_cc_invalid_account, "Account not found");
|
||||
CHECK_COMMAND_SET(set_title.delta_adjective || set_title.delta_noun || set_title.delta_origin || set_title.delta_unique,
|
||||
tvc, m_cc_invalid_previous_state, "set_title does not change anything");
|
||||
|
||||
const int32_t adjective = ad.title_adjective + set_title.delta_adjective;
|
||||
const int32_t noun = ad.title_noun + set_title.delta_noun;
|
||||
const int32_t origin = ad.title_origin + set_title.delta_origin;
|
||||
const int32_t unique = ad.title_unique + set_title.delta_unique;
|
||||
|
||||
std::vector<std::pair<uint32_t, std::string>> adjectives, nouns, origins, uniques;
|
||||
cc::get_available_title_components(db, set_title.cc_account, adjectives, nouns, origins, uniques);
|
||||
CHECK_COMMAND_SET(adjective == -1 || is_present(adjective, adjectives), tvc, m_cc_not_allowed, "Title adjective not available to account");
|
||||
CHECK_COMMAND_SET(noun == -1 || is_present(noun, nouns), tvc, m_cc_not_allowed, "Title noun not available to account");
|
||||
CHECK_COMMAND_SET(origin == -1 || is_present(origin, origins), tvc, m_cc_not_allowed, "Title origin not available to account");
|
||||
CHECK_COMMAND_SET(unique == -1 || (uint32_t)unique < ad.unique_titles.size(), tvc, m_cc_not_allowed, "Unique title not available to account");
|
||||
|
||||
const bool has_compound = adjective >= 0 || noun >= 0 || origin >= 0;
|
||||
const bool has_unique = unique >= 0;
|
||||
CHECK_COMMAND_SET(!(has_compound && has_unique), tvc, m_cc_not_allowed, "Title must be either compound or unique, but not both at once");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cc_command_handler_set_title::execute(cryptonote::BlockchainDB &db, const cryptonote::cc_command_t &cmd, uint8_t hf_version, uint64_t tx_fee, game_events_t &events) const
|
||||
{
|
||||
const cryptonote::cc_command_set_title_t &set_title = boost::get<cryptonote::cc_command_set_title_t>(cmd);
|
||||
cryptonote::cc_account_data_t ad;
|
||||
|
||||
CHECK_AND_ASSERT_MES(db.get_cc_account_data(set_title.cc_account, ad), false, "Account not found");
|
||||
|
||||
const int32_t new_adjective = ad.title_adjective + set_title.delta_adjective;
|
||||
const int32_t new_noun = ad.title_noun + set_title.delta_noun;
|
||||
const int32_t new_origin = ad.title_origin + set_title.delta_origin;
|
||||
const int32_t new_unique = ad.title_unique + set_title.delta_unique;
|
||||
const std::string adjective = cc::get_title_adjective(db, new_adjective);
|
||||
const std::string noun = cc::get_title_noun(db, new_noun);
|
||||
const std::string origin = cc::get_title_origin(db, new_origin);
|
||||
const std::string unique = cc::get_title_unique(db, set_title.cc_account, new_unique);
|
||||
const std::string title = cc::get_title(adjective, noun, origin, unique);
|
||||
CHECK_AND_ASSERT_MES(db.set_cc_account_title(set_title.cc_account, new_adjective, new_noun, new_origin, new_unique, title), false, "Failed to set title");
|
||||
|
||||
events.add_full(cmd, set_title.cc_account, 0, 0, ITEM_NONE, 0, 0, tx_fee) << "Changed title to '" << title << "'";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cc_command_handler_set_title::revert(cryptonote::BlockchainDB &db, const cryptonote::cc_command_t &cmd, uint8_t hf_version) const
|
||||
{
|
||||
const cryptonote::cc_command_set_title_t &set_title = boost::get<cryptonote::cc_command_set_title_t>(cmd);
|
||||
cryptonote::cc_account_data_t ad;
|
||||
|
||||
CHECK_AND_ASSERT_MES(db.get_cc_account_data(set_title.cc_account, ad), false, "Account not found");
|
||||
|
||||
const int32_t old_adjective = ad.title_adjective - set_title.delta_adjective;
|
||||
const int32_t old_noun = ad.title_noun - set_title.delta_noun;
|
||||
const int32_t old_origin = ad.title_origin - set_title.delta_origin;
|
||||
const int32_t old_unique = ad.title_unique - set_title.delta_unique;
|
||||
const std::string adjective = cc::get_title_adjective(db, old_adjective);
|
||||
const std::string noun = cc::get_title_noun(db, old_noun);
|
||||
const std::string origin = cc::get_title_origin(db, old_origin);
|
||||
const std::string unique = cc::get_title_unique(db, set_title.cc_account, old_unique);
|
||||
const std::string title = cc::get_title(adjective, noun, origin, unique);
|
||||
CHECK_AND_ASSERT_MES(db.set_cc_account_title(set_title.cc_account, old_adjective, old_noun, old_origin, old_unique, title), false, "Failed to reset title");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
48
src/cc/cc_command_handler_set_title.h
Normal file
48
src/cc/cc_command_handler_set_title.h
Normal file
@ -0,0 +1,48 @@
|
||||
// Copyright (c) 2019, Crypto City
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are
|
||||
// permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
// conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
// of conditions and the following disclaimer in the documentation and/or other
|
||||
// materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without specific
|
||||
// prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cc_command_handler.h"
|
||||
|
||||
namespace cc
|
||||
{
|
||||
|
||||
class cc_command_handler_set_title: public cc_command_handler
|
||||
{
|
||||
public:
|
||||
virtual void get_in_out(const cryptonote::cc_command_t &cmd, uint64_t &cc_in, uint64_t &cc_out) const;
|
||||
virtual uint64_t get_cost(const cryptonote::cc_command_t &cmd) const;
|
||||
virtual bool check(const cryptonote::BlockchainDB &db, const cryptonote::cc_command_t &cmd, uint8_t hf_version, cryptonote::tx_verification_context &tvc) const;
|
||||
virtual bool execute(cryptonote::BlockchainDB &db, const cryptonote::cc_command_t &cmd, uint8_t hf_version, uint64_t tx_fee, game_events_t &events) const;
|
||||
virtual bool revert(cryptonote::BlockchainDB &db, const cryptonote::cc_command_t &cmd, uint8_t hf_version) const;
|
||||
|
||||
static cc_command_handler_set_title instance;
|
||||
};
|
||||
|
||||
}
|
@ -250,6 +250,10 @@ bool cc_command_handler_start_script::execute(cryptonote::BlockchainDB &db, cons
|
||||
ad.badges[e.badge].second += e.timestamp_delta;
|
||||
db.set_cc_account_badges(e.account, ad.badges);
|
||||
}
|
||||
for (const auto &e: effects.new_unique_titles)
|
||||
{
|
||||
db.grant_cc_account_unique_title(e.first, e.second);
|
||||
}
|
||||
|
||||
if (cc::script::is_end_state(script, 0))
|
||||
{
|
||||
@ -473,6 +477,10 @@ bool cc_command_handler_start_script::revert(cryptonote::BlockchainDB &db, const
|
||||
ad.badges[e.badge].second -= e.timestamp_delta;
|
||||
db.set_cc_account_badges(e.account, ad.badges);
|
||||
}
|
||||
for (const auto &e: effects.new_unique_titles)
|
||||
{
|
||||
db.rescind_cc_account_unique_title(e.first, e.second);
|
||||
}
|
||||
|
||||
const auto overrides = cc::script::get_script_overrides(script);
|
||||
cc::runestone_t runestone;
|
||||
|
@ -304,6 +304,9 @@ static void print_action_string(const Action &a, std::string &source, const std:
|
||||
CHECK_AND_ASSERT_THROW_MES(a.ops.size() == 2, "Expected two operands for action_create_item, got " << a.ops.size());
|
||||
source += I + "create item \"" + get_operand_string(a.ops[0], op_unsigned) + " " + get_operand_string(a.ops[1], op_unsigned) + "\"\n";
|
||||
break;
|
||||
case action_award_title:
|
||||
source += I + "award title \"" + escape(a.str) + "\"\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1774,6 +1777,13 @@ static bool execute(cryptonote::cc_command_t cmd, BlockchainStateProxy &proxy, g
|
||||
events.add_full(cmd, owner, account, 0, value, value_extra, -(int64_t)(gold_needed + fee_bonus), 0) << "Created " << value_extra << " " << proxy.get_item_name(value) << " in '" << get_script_name(script) << "'";
|
||||
}
|
||||
break;
|
||||
case action_award_title:
|
||||
{
|
||||
const std::string title = process_format_string(proxy, account, owner, city, seed, salt, action.str, action.ops);
|
||||
proxy.grant_unique_title(account, title);
|
||||
events.add_full(cmd, account, 0, 0, ITEM_NONE, 0, 0, 0) << "Awarded the title '" << title << "'";
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -1887,6 +1897,7 @@ void set_script_effects(const BlockchainStateProxy &proxy, script_effects_t &eff
|
||||
const std::map<std::pair<uint32_t, uint32_t>, std::pair<uint8_t, uint64_t>> &badges = proxy.get_badge_deltas();
|
||||
for (const auto &e: badges)
|
||||
effects.badges.push_back({e.first.first, e.first.second, e.second.first, e.second.second});
|
||||
effects.new_unique_titles = proxy.get_new_unique_titles();
|
||||
}
|
||||
|
||||
static void reset_local_variables(BlockchainStateProxy &proxy, uint32_t account)
|
||||
|
@ -125,6 +125,7 @@ struct script_effects_t
|
||||
std::vector<string_override_removal_t> string_override_removals;
|
||||
std::vector<uint32_t> new_background_scripts;
|
||||
std::vector<badge_delta_t> badges;
|
||||
std::vector<std::pair<uint32_t, std::string>> new_unique_titles;
|
||||
|
||||
BEGIN_SERIALIZE_OBJECT()
|
||||
FIELD(balances)
|
||||
@ -138,6 +139,7 @@ struct script_effects_t
|
||||
FIELD(string_override_removals)
|
||||
FIELD(new_background_scripts)
|
||||
FIELD(badges)
|
||||
FIELD(new_unique_titles);
|
||||
END_SERIALIZE()
|
||||
};
|
||||
|
||||
|
232
src/cc/cc_title.cc
Normal file
232
src/cc/cc_title.cc
Normal file
@ -0,0 +1,232 @@
|
||||
#include "blockchain_db/blockchain_db.h"
|
||||
#include "cc_epoch.h"
|
||||
#include "cc_badge.h"
|
||||
#include "cc_title.h"
|
||||
|
||||
#define ADJECTIVE_BADGE_FLAG 0x1000
|
||||
|
||||
#define NOUN_BADGE_FLAG 0x1000
|
||||
|
||||
#define ORIGIN_COUNTRY_FLAG 0x2000
|
||||
#define ORIGIN_CITY_FLAG 0x1000
|
||||
|
||||
static const char * const countries[] =
|
||||
{
|
||||
"Brittany",
|
||||
"Cornwall",
|
||||
"Danelaw",
|
||||
"England",
|
||||
"Finland",
|
||||
"Flanders",
|
||||
"Francia",
|
||||
"Føroyar",
|
||||
"Gőtland",
|
||||
"Hjaltland",
|
||||
"Iceland",
|
||||
"Ireland",
|
||||
"Jutland",
|
||||
"Kievan Rus",
|
||||
"Mercia",
|
||||
"Normandy",
|
||||
"Northumbria",
|
||||
"Norway",
|
||||
"Orkney",
|
||||
"Pomerania",
|
||||
"Saxony",
|
||||
"Scotland",
|
||||
"Shetland",
|
||||
"Suðreyjar",
|
||||
"Sutherland",
|
||||
"Sweden",
|
||||
"Wales",
|
||||
"Wessex",
|
||||
"York",
|
||||
};
|
||||
|
||||
struct title_component_t
|
||||
{
|
||||
const char * const string;
|
||||
bool (*allowed)(const cryptonote::BlockchainDB&, uint32_t);
|
||||
};
|
||||
|
||||
static void push(std::vector<std::pair<uint32_t, std::string>> &v, const std::pair<uint32_t, std::string> &e)
|
||||
{
|
||||
for (const auto &ve: v)
|
||||
if (ve.second == e.second)
|
||||
return;
|
||||
v.push_back(e);
|
||||
}
|
||||
|
||||
namespace cc
|
||||
{
|
||||
|
||||
#define TCIF(x) [](const cryptonote::BlockchainDB &db, uint32_t id) { x; }
|
||||
|
||||
static const title_component_t builtin_adjectives[] =
|
||||
{
|
||||
{ "ancient", TCIF( cryptonote::cc_account_data_t ad; if (!db.get_cc_account_data(id, ad)) return false; return cc::get_epoch_index(db.get_cc_epochs(), ad.creation_height) + 4 < db.get_cc_epoch(db.height() - 1).index; ) },
|
||||
};
|
||||
|
||||
static const title_component_t builtin_nouns[] =
|
||||
{
|
||||
{ "newcomer", NULL },
|
||||
{ "millionaire", TCIF( uint64_t b; return db.get_cc_account_balance(id, b) && b >= 1000000 * COIN; ) },
|
||||
};
|
||||
|
||||
#undef TCIF
|
||||
|
||||
std::string get_title(const std::string &adjective, const std::string &noun, const std::string &origin, const std::string &unique)
|
||||
{
|
||||
std::string s;
|
||||
|
||||
if (!unique.empty())
|
||||
{
|
||||
s += unique;
|
||||
return s;
|
||||
}
|
||||
|
||||
if (!adjective.empty() || !noun.empty())
|
||||
{
|
||||
s += "the";
|
||||
if (!adjective.empty())
|
||||
{
|
||||
s += " ";
|
||||
s += adjective;
|
||||
}
|
||||
if (!noun.empty())
|
||||
{
|
||||
s += " ";
|
||||
s += noun;
|
||||
}
|
||||
}
|
||||
if (!origin.empty())
|
||||
{
|
||||
if (!s.empty())
|
||||
s += " ";
|
||||
s += "of ";
|
||||
s += origin;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
void get_available_title_components(const cryptonote::BlockchainDB &db, uint32_t id, std::vector<std::pair<uint32_t, std::string>> &adjectives, std::vector<std::pair<uint32_t, std::string>> &nouns, std::vector<std::pair<uint32_t, std::string>> &origins, std::vector<std::pair<uint32_t, std::string>> &uniques)
|
||||
{
|
||||
cryptonote::cc_account_data_t ad;
|
||||
CHECK_AND_ASSERT_THROW_MES(db.get_cc_account_data(id, ad), "Account not found");
|
||||
|
||||
adjectives.clear();
|
||||
for (uint32_t i = 0; i < sizeof(builtin_adjectives) / sizeof(builtin_adjectives[0]); ++i)
|
||||
if (builtin_adjectives[i].allowed == NULL || (*builtin_adjectives[i].allowed)(db, id))
|
||||
push(adjectives, std::make_pair(i, builtin_adjectives[i].string));
|
||||
|
||||
nouns.clear();
|
||||
for (uint32_t i = 0; i < sizeof(builtin_nouns) / sizeof(builtin_nouns[0]); ++i)
|
||||
if (builtin_nouns[i].allowed == NULL || (*builtin_nouns[i].allowed)(db, id))
|
||||
push(nouns, std::make_pair(i, builtin_nouns[i].string));
|
||||
|
||||
origins.clear();
|
||||
db.for_all_cc_cities([&origins](const cryptonote::cc_city_data_t &cd){
|
||||
push(origins, std::make_pair(ORIGIN_CITY_FLAG | cd.id, cd.name));
|
||||
return true;
|
||||
});
|
||||
for (uint32_t i = 0; i < sizeof(countries) / sizeof(countries[0]); ++i)
|
||||
push(origins, std::make_pair(i | ORIGIN_COUNTRY_FLAG, countries[i]));
|
||||
|
||||
uniques.clear();
|
||||
for (uint32_t i = 0; i < ad.unique_titles.size(); ++i)
|
||||
push(uniques, std::make_pair(i, ad.unique_titles[i]));
|
||||
|
||||
for (const auto &e: ad.badges)
|
||||
{
|
||||
if (e.first < cc::NUM_PREDEFINED_BADGES && e.second.first >= 5)
|
||||
{
|
||||
cc::cc_badge_data_t data;
|
||||
if (cc::get_badge_data(&db, (cc_badge_t)e.first, data))
|
||||
{
|
||||
if (!data.title_adjective.empty())
|
||||
push(adjectives, std::make_pair(ADJECTIVE_BADGE_FLAG | e.first, data.title_adjective));
|
||||
if (!data.title_noun.empty())
|
||||
push(nouns, std::make_pair(NOUN_BADGE_FLAG | e.first, data.title_noun));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string get_title_adjective(const cryptonote::BlockchainDB &db, int32_t idx)
|
||||
{
|
||||
if (idx < 0)
|
||||
return "";
|
||||
if (idx & ADJECTIVE_BADGE_FLAG)
|
||||
{
|
||||
cc::cc_badge_data_t data;
|
||||
if (!cc::get_badge_data(&db, (cc::cc_badge_t)(idx & ~ADJECTIVE_BADGE_FLAG), data))
|
||||
{
|
||||
MERROR("Adjective badge not found: " << idx);
|
||||
return "";
|
||||
}
|
||||
if (data.title_adjective.empty())
|
||||
MERROR("Adjective badge has empty noun: " << idx);
|
||||
return data.title_adjective;
|
||||
}
|
||||
|
||||
if ((uint32_t)idx >= sizeof(builtin_adjectives) / sizeof(builtin_adjectives[0]))
|
||||
return "";
|
||||
return builtin_adjectives[idx].string;
|
||||
}
|
||||
|
||||
std::string get_title_noun(const cryptonote::BlockchainDB &db, int32_t idx)
|
||||
{
|
||||
if (idx < 0)
|
||||
return "";
|
||||
if (idx & NOUN_BADGE_FLAG)
|
||||
{
|
||||
cc::cc_badge_data_t data;
|
||||
if (!cc::get_badge_data(&db, (cc::cc_badge_t)(idx & ~NOUN_BADGE_FLAG), data))
|
||||
{
|
||||
MERROR("Noun badge not found: " << idx);
|
||||
return "";
|
||||
}
|
||||
if (data.title_noun.empty())
|
||||
MERROR("Noun badge has empty noun: " << idx);
|
||||
return data.title_noun;
|
||||
}
|
||||
|
||||
if ((uint32_t)idx >= sizeof(builtin_nouns) / sizeof(builtin_nouns[0]))
|
||||
return "";
|
||||
return builtin_nouns[idx].string;
|
||||
}
|
||||
|
||||
std::string get_title_origin(const cryptonote::BlockchainDB &db, int32_t idx)
|
||||
{
|
||||
if (idx < 0)
|
||||
return "";
|
||||
if (idx & ORIGIN_CITY_FLAG)
|
||||
{
|
||||
cryptonote::cc_city_data_t cd;
|
||||
if (!db.get_cc_city_data(idx & ~ORIGIN_CITY_FLAG, cd))
|
||||
{
|
||||
MERROR("Origin city not found: " << idx);
|
||||
return "nowhere";
|
||||
}
|
||||
return cd.name;
|
||||
}
|
||||
if (idx & ORIGIN_COUNTRY_FLAG)
|
||||
{
|
||||
if ((uint32_t)(idx & ~ORIGIN_COUNTRY_FLAG) < sizeof(countries) / sizeof(countries[0]))
|
||||
return countries[idx & ~ORIGIN_COUNTRY_FLAG];
|
||||
}
|
||||
MERROR("Bad origin idx: " << idx);
|
||||
return "nowhere";
|
||||
}
|
||||
|
||||
std::string get_title_unique(const cryptonote::BlockchainDB &db, uint32_t id, int32_t idx)
|
||||
{
|
||||
cryptonote::cc_account_data_t ad;
|
||||
CHECK_AND_ASSERT_THROW_MES(db.get_cc_account_data(id, ad), "Account not found");
|
||||
if (idx < 0 || (uint32_t)idx >= ad.unique_titles.size())
|
||||
return "";
|
||||
return ad.unique_titles[idx];
|
||||
}
|
||||
|
||||
}
|
23
src/cc/cc_title.h
Normal file
23
src/cc/cc_title.h
Normal file
@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace cryptonote
|
||||
{
|
||||
class BlockchainDB;
|
||||
}
|
||||
|
||||
namespace cc
|
||||
{
|
||||
|
||||
std::string get_title(const std::string &adjective, const std::string &noun, const std::string &origin, const std::string &unique);
|
||||
void get_available_title_components(const cryptonote::BlockchainDB &db, uint32_t id, std::vector<std::pair<uint32_t, std::string>> &adjectives, std::vector<std::pair<uint32_t, std::string>> &nouns, std::vector<std::pair<uint32_t, std::string>> &origins, std::vector<std::pair<uint32_t, std::string>> &uniques);
|
||||
|
||||
std::string get_title_adjective(const cryptonote::BlockchainDB &db, int32_t idx);
|
||||
std::string get_title_noun(const cryptonote::BlockchainDB &db, int32_t idx);
|
||||
std::string get_title_origin(const cryptonote::BlockchainDB &db, int32_t idx);
|
||||
std::string get_title_unique(const cryptonote::BlockchainDB &db, uint32_t id, int32_t idx);
|
||||
|
||||
}
|
@ -177,6 +177,7 @@ typedef enum ActionType
|
||||
action_log,
|
||||
action_call,
|
||||
action_create_item,
|
||||
action_award_title,
|
||||
} ActionType;
|
||||
static const struct
|
||||
{
|
||||
@ -201,7 +202,7 @@ static const struct
|
||||
{ "start background script", action_start_background_script },
|
||||
{ "log", action_log },
|
||||
{ "call", action_call },
|
||||
{ "create item", action_create_item },
|
||||
{ "award title", action_award_title },
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -125,6 +125,7 @@ create { return CREATE; }
|
||||
during { return DURING; }
|
||||
fees { return FEES; }
|
||||
epoch { return EPOCH; }
|
||||
title { return TITLE; }
|
||||
|
||||
\+ { return ADD; }
|
||||
- { return SUB; }
|
||||
|
@ -37,7 +37,7 @@ static script_partial_state_t *state = NULL;
|
||||
%token <number> PERCENT PAY CONSUME TEMPERATURE_NUMBER TEMPERATURE RANDOM
|
||||
%token <number> IMAGE UI CHOICES CHOICE NEXT SELECTED ENABLED ACTIONS PUBLIC IS BLOCKCHAIN BY OVERRIDES ID
|
||||
%token <number> GEMSTONE BLOCK LABOUR COIN FOOD CUSTOM IF ELSE STORYLINE RESTRICTED START BACKGROUND LOG
|
||||
%token <number> PROCEDURE CALL WITH ROLE FLAG CREATE DURING FEES EPOCH
|
||||
%token <number> PROCEDURE CALL WITH ROLE FLAG CREATE DURING FEES EPOCH TITLE
|
||||
|
||||
%type <number> script script_contents script_content choice_contents choice_content
|
||||
%type <number> name owner description icon precondition reserves state public storyline
|
||||
@ -139,6 +139,7 @@ action: action_percent
|
||||
| action_log
|
||||
| action_call
|
||||
| action_create_item
|
||||
| action_award_title
|
||||
;
|
||||
|
||||
action_percent: PERCENT operand action { set_partial_state_action_percent(state); }
|
||||
@ -207,6 +208,9 @@ action_call: CALL STRING { set_partial_state_action(state, action_call, $2, 0);
|
||||
action_create_item: CREATE ITEM operand operand { set_partial_state_action(state, action_create_item, NULL, 2); }
|
||||
;
|
||||
|
||||
action_award_title: AWARD TITLE STRING { set_partial_state_action(state, action_award_title, $3, 0); }
|
||||
;
|
||||
|
||||
action_none: NONE { set_partial_state_action(state, action_none, NULL, 0); }
|
||||
;
|
||||
|
||||
|
@ -109,6 +109,7 @@ const cc_command_basenonce_t *get_cc_command_basenonce(const cc_command_t &cmd)
|
||||
const cc_command_basenonce_t *operator()(const cryptonote::cc_command_service_t &cmd) const { return &cmd; }
|
||||
const cc_command_basenonce_t *operator()(const cryptonote::cc_command_set_merchant_ship_items_t &cmd) const { return &cmd; }
|
||||
const cc_command_basenonce_t *operator()(const cryptonote::cc_command_set_script_variables_t &cmd) const { return &cmd; }
|
||||
const cc_command_basenonce_t *operator()(const cryptonote::cc_command_set_title_t &cmd) const { return &cmd; }
|
||||
const cc_command_basenonce_t *operator()(const cryptonote::cc_command_add_tax_break_zone_t &cmd) const { return &cmd; }
|
||||
const cc_command_basenonce_t *operator()(const cryptonote::cc_command_smelt_t &cmd) const { return &cmd; }
|
||||
const cc_command_basenonce_t *operator()(const cryptonote::cc_command_sow_t &cmd) const { return &cmd; }
|
||||
@ -184,6 +185,7 @@ cc_command_basenonce_t *get_cc_command_basenonce(cc_command_t &cmd)
|
||||
cc_command_basenonce_t *operator()(cryptonote::cc_command_service_t &cmd) const { return &cmd; }
|
||||
cc_command_basenonce_t *operator()(cryptonote::cc_command_set_merchant_ship_items_t &cmd) const { return &cmd; }
|
||||
cc_command_basenonce_t *operator()(cryptonote::cc_command_set_script_variables_t &cmd) const { return &cmd; }
|
||||
cc_command_basenonce_t *operator()(cryptonote::cc_command_set_title_t &cmd) const { return &cmd; }
|
||||
cc_command_basenonce_t *operator()(cryptonote::cc_command_add_tax_break_zone_t &cmd) const { return &cmd; }
|
||||
cc_command_basenonce_t *operator()(cryptonote::cc_command_smelt_t &cmd) const { return &cmd; }
|
||||
cc_command_basenonce_t *operator()(cryptonote::cc_command_sow_t &cmd) const { return &cmd; }
|
||||
@ -259,6 +261,7 @@ const cc_command_base_t *get_cc_command_base(const cc_command_t &cmd)
|
||||
const cc_command_base_t *operator()(const cryptonote::cc_command_service_t &cmd) const { return &cmd; }
|
||||
const cc_command_base_t *operator()(const cryptonote::cc_command_set_merchant_ship_items_t &cmd) const { return &cmd; }
|
||||
const cc_command_base_t *operator()(const cryptonote::cc_command_set_script_variables_t &cmd) const { return &cmd; }
|
||||
const cc_command_base_t *operator()(const cryptonote::cc_command_set_title_t &cmd) const { return &cmd; }
|
||||
const cc_command_base_t *operator()(const cryptonote::cc_command_add_tax_break_zone_t &cmd) const { return &cmd; }
|
||||
const cc_command_base_t *operator()(const cryptonote::cc_command_smelt_t &cmd) const { return &cmd; }
|
||||
const cc_command_base_t *operator()(const cryptonote::cc_command_sow_t &cmd) const { return &cmd; }
|
||||
@ -334,6 +337,7 @@ cc_command_base_t *get_cc_command_base(cc_command_t &cmd)
|
||||
cc_command_base_t *operator()(cryptonote::cc_command_service_t &cmd) const { return &cmd; }
|
||||
cc_command_base_t *operator()(cryptonote::cc_command_set_merchant_ship_items_t &cmd) const { return &cmd; }
|
||||
cc_command_base_t *operator()(cryptonote::cc_command_set_script_variables_t &cmd) const { return &cmd; }
|
||||
cc_command_base_t *operator()(cryptonote::cc_command_set_title_t &cmd) const { return &cmd; }
|
||||
cc_command_base_t *operator()(cryptonote::cc_command_add_tax_break_zone_t &cmd) const { return &cmd; }
|
||||
cc_command_base_t *operator()(cryptonote::cc_command_smelt_t &cmd) const { return &cmd; }
|
||||
cc_command_base_t *operator()(cryptonote::cc_command_sow_t &cmd) const { return &cmd; }
|
||||
@ -409,6 +413,7 @@ bool is_cc_command_restricted(const cc_command_t &cmd)
|
||||
bool operator()(const cryptonote::cc_command_service_t &cmd) const { return false; }
|
||||
bool operator()(const cryptonote::cc_command_set_merchant_ship_items_t &cmd) const { return true; }
|
||||
bool operator()(const cryptonote::cc_command_set_script_variables_t &cmd) const { return true; }
|
||||
bool operator()(const cryptonote::cc_command_set_title_t &cmd) const { return false; }
|
||||
bool operator()(const cryptonote::cc_command_add_tax_break_zone_t &cmd) const { return false; }
|
||||
bool operator()(const cryptonote::cc_command_smelt_t &cmd) const { return false; }
|
||||
bool operator()(const cryptonote::cc_command_sow_t &cmd) const { return false; }
|
||||
@ -484,6 +489,7 @@ bool cc_command_has_signature(const cc_command_t &cmd)
|
||||
bool operator()(const cryptonote::cc_command_service_t &cmd) const { return true; }
|
||||
bool operator()(const cryptonote::cc_command_set_merchant_ship_items_t &cmd) const { return true; }
|
||||
bool operator()(const cryptonote::cc_command_set_script_variables_t &cmd) const { return true; }
|
||||
bool operator()(const cryptonote::cc_command_set_title_t &cmd) const { return true; }
|
||||
bool operator()(const cryptonote::cc_command_add_tax_break_zone_t &cmd) const { return true; }
|
||||
bool operator()(const cryptonote::cc_command_smelt_t &cmd) const { return true; }
|
||||
bool operator()(const cryptonote::cc_command_sow_t &cmd) const { return true; }
|
||||
|
@ -1462,6 +1462,22 @@ namespace cryptonote
|
||||
END_SERIALIZE()
|
||||
};
|
||||
|
||||
struct cc_command_set_title_t: public cc_command_base_t
|
||||
{
|
||||
int32_t delta_adjective;
|
||||
int32_t delta_noun;
|
||||
int32_t delta_origin;
|
||||
int32_t delta_unique;
|
||||
|
||||
BEGIN_SERIALIZE_OBJECT()
|
||||
FIELDS(*static_cast<cc_command_base_t*>(this))
|
||||
VARINT_FIELD_SIGNED(delta_adjective)
|
||||
VARINT_FIELD_SIGNED(delta_noun)
|
||||
VARINT_FIELD_SIGNED(delta_origin)
|
||||
VARINT_FIELD_SIGNED(delta_unique)
|
||||
END_SERIALIZE()
|
||||
};
|
||||
|
||||
struct cc_command_game_update_t: public cc_command_basenonce_t
|
||||
{
|
||||
struct flag_t
|
||||
@ -1868,7 +1884,8 @@ namespace cryptonote
|
||||
cc_command_salt_food_t,
|
||||
cc_command_retrieve_items_t,
|
||||
cc_command_create_runestones_t,
|
||||
cc_command_start_epoch_t
|
||||
cc_command_start_epoch_t,
|
||||
cc_command_set_title_t
|
||||
> cc_command_t;
|
||||
|
||||
cc_command_basenonce_t *get_cc_command_basenonce(cc_command_t &cmd);
|
||||
@ -2051,6 +2068,7 @@ CC_VARIANT_TAG(binary_archive, cryptonote::cc_command_salt_food_t, (uint8_t)0x3f
|
||||
CC_VARIANT_TAG(binary_archive, cryptonote::cc_command_retrieve_items_t, (uint8_t)0x40);
|
||||
CC_VARIANT_TAG(binary_archive, cryptonote::cc_command_create_runestones_t, (uint8_t)0x41);
|
||||
CC_VARIANT_TAG(binary_archive, cryptonote::cc_command_start_epoch_t, (uint8_t)0x42);
|
||||
CC_VARIANT_TAG(binary_archive, cryptonote::cc_command_set_title_t, (uint8_t)0x43);
|
||||
|
||||
CC_VARIANT_TAG(json_archive, cryptonote::cc_command_none_t, (const char*)"none");
|
||||
CC_VARIANT_TAG(json_archive, cryptonote::cc_command_create_account_t, (const char*)"create_account");
|
||||
@ -2119,6 +2137,7 @@ CC_VARIANT_TAG(json_archive, cryptonote::cc_command_salt_food_t, (const char*)"s
|
||||
CC_VARIANT_TAG(json_archive, cryptonote::cc_command_retrieve_items_t, (const char*)"retrieve_items");
|
||||
CC_VARIANT_TAG(json_archive, cryptonote::cc_command_create_runestones_t, (const char*)"create_runestones");
|
||||
CC_VARIANT_TAG(json_archive, cryptonote::cc_command_start_epoch_t, (const char*)"start_epoch");
|
||||
CC_VARIANT_TAG(json_archive, cryptonote::cc_command_set_title_t, (const char*)"set_title");
|
||||
|
||||
VARIANT_TAG(debug_archive, cryptonote::cc_command_none_t, "none");
|
||||
VARIANT_TAG(debug_archive, cryptonote::cc_command_create_account_t, "create_account");
|
||||
@ -2187,3 +2206,4 @@ VARIANT_TAG(debug_archive, cryptonote::cc_command_salt_food_t, "salt_food");
|
||||
VARIANT_TAG(debug_archive, cryptonote::cc_command_retrieve_items_t, "retrieve_items");
|
||||
VARIANT_TAG(debug_archive, cryptonote::cc_command_create_runestones_t, "create_runestones");
|
||||
VARIANT_TAG(debug_archive, cryptonote::cc_command_start_epoch_t, "start_epoch");
|
||||
VARIANT_TAG(debug_archive, cryptonote::cc_command_set_title_t, "set_title");
|
||||
|
@ -184,6 +184,7 @@ struct cc_snapshot
|
||||
{
|
||||
uint32_t id;
|
||||
std::string name;
|
||||
std::string title;
|
||||
bool ignore;
|
||||
bool autonomous;
|
||||
std::vector<uint32_t> badges;
|
||||
@ -194,6 +195,7 @@ struct cc_snapshot
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(id)
|
||||
KV_SERIALIZE(name)
|
||||
KV_SERIALIZE(title)
|
||||
KV_SERIALIZE(ignore)
|
||||
KV_SERIALIZE(autonomous)
|
||||
KV_SERIALIZE_CONTAINER_POD_AS_BLOB(badges)
|
||||
@ -205,6 +207,7 @@ struct cc_snapshot
|
||||
BEGIN_SERIALIZE_OBJECT()
|
||||
VARINT_FIELD(id)
|
||||
FIELD(name)
|
||||
FIELD(title)
|
||||
FIELD(ignore)
|
||||
FIELD(autonomous)
|
||||
FIELD(badges)
|
||||
|
@ -4057,6 +4057,9 @@ bool Blockchain::check_cc_cmd_signature(const transaction& tx) const
|
||||
|
||||
static bool is_command_allowed(const cryptonote::cc_command_t &cmd, uint8_t hf_version)
|
||||
{
|
||||
if (cmd.type() == typeid(cryptonote::cc_command_set_title_t) && hf_version < HF_VERSION_TOWNFORGE_TESTNET_UPDATE_3)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -122,6 +122,7 @@ set(game_sources
|
||||
ui-fight-fire.cc
|
||||
ui-fish.cc
|
||||
ui-file-selector.cc
|
||||
ui-change-title.cc
|
||||
ui-city-maps.cc
|
||||
ui-go-to-vista.cc
|
||||
ui-harvest.cc
|
||||
@ -240,6 +241,7 @@ set(game_headers
|
||||
ui-auctions.h
|
||||
ui-building-settings.h
|
||||
ui-carve-runestone.h
|
||||
ui-change-title.h
|
||||
ui-city-level.h
|
||||
ui-configure-script.h
|
||||
ui-console.h
|
||||
|
@ -118,7 +118,7 @@ void PlayerState::update(const std::shared_ptr<GameWallet> &wallet)
|
||||
{
|
||||
std::string pmspk, pmvpk;
|
||||
std::map<uint32_t, std::pair<uint32_t, std::map<std::string, uint64_t>>> background_script_states;
|
||||
w->get_cc_account_data(id, public_key, balance, item_balances, flags, badges, attributes, name, description, ignored, inviting_account, num_invited, first_flag, script, script_state, script_city, script_owner, reserve, script_variables, script_local_variables, background_script_states, prestige, textures_created, textures_licenced, pmspk, pmvpk);
|
||||
w->get_cc_account_data(id, public_key, balance, item_balances, flags, badges, attributes, name, title_adjective, title_noun, title_origin, title_unique, title, description, ignored, inviting_account, num_invited, first_flag, script, script_state, script_city, script_owner, reserve, script_variables, script_local_variables, background_script_states, prestige, textures_created, textures_licenced, pmspk, pmvpk);
|
||||
reserved_balance = 0;
|
||||
for (const auto &e: reserve)
|
||||
{
|
||||
@ -735,7 +735,7 @@ bool GameState::process_dice_roll(const cryptonote::cc_command_dice_roll_t &cmd,
|
||||
uint32_t bonus = 0;
|
||||
if (cmd.account)
|
||||
{
|
||||
std::string public_key, pmspk, pmvpk;
|
||||
std::string public_key, pmspk, pmvpk, title;
|
||||
uint64_t balance;
|
||||
std::map<uint32_t, uint32_t> item_balances, attributes;
|
||||
std::vector<uint32_t> flags;
|
||||
@ -751,7 +751,8 @@ bool GameState::process_dice_roll(const cryptonote::cc_command_dice_roll_t &cmd,
|
||||
uint32_t prestige;
|
||||
std::vector<uint32_t> textures_created, textures_licenced;
|
||||
std::map<uint32_t, std::pair<uint32_t, std::map<std::string, uint64_t>>> background_script_states;
|
||||
if (!w->get_cc_account_data(cmd.account, public_key, balance, item_balances, flags, badges, attributes, name, description, ignored, inviting_account, num_invited, first_flag, script, script_state, script_city, script_owner, reserve, script_variables, script_local_variables, background_script_states, prestige, textures_created, textures_licenced, pmspk, pmvpk))
|
||||
int32_t title_adjective, title_noun, title_origin, title_unique;
|
||||
if (!w->get_cc_account_data(cmd.account, public_key, balance, item_balances, flags, badges, attributes, name, title_adjective, title_noun, title_origin, title_unique, title, description, ignored, inviting_account, num_invited, first_flag, script, script_state, script_city, script_owner, reserve, script_variables, script_local_variables, background_script_states, prestige, textures_created, textures_licenced, pmspk, pmvpk))
|
||||
return true;
|
||||
bonus = attributes[cmd.attribute];
|
||||
}
|
||||
@ -1269,6 +1270,14 @@ bool GameState::process_set_script_variables(const cryptonote::cc_command_set_sc
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GameState::process_set_title(const cryptonote::cc_command_set_title_t &cmd, const std::shared_ptr<GameWallet> &w)
|
||||
{
|
||||
TRIGGER_TUTORIAL(cmd, "set-title");
|
||||
player_names.erase(cmd.cc_account); // will be fetched again
|
||||
// player auto updates at every block, nothing to do in playerState
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GameState::process_add_tax_break_zone(const cryptonote::cc_command_add_tax_break_zone_t &cmd, const std::shared_ptr<GameWallet> &w)
|
||||
{
|
||||
if (cmd.city == cityState.id)
|
||||
@ -1409,6 +1418,7 @@ bool GameState::process_command(const cryptonote::cc_command_t &cmd, const std::
|
||||
bool operator()(const cryptonote::cc_command_service_t &cmd) const { return self.process_service(cmd, w); }
|
||||
bool operator()(const cryptonote::cc_command_set_merchant_ship_items_t &cmd) const { return self.process_set_merchant_ship_items(cmd, w); }
|
||||
bool operator()(const cryptonote::cc_command_set_script_variables_t &cmd) const { return self.process_set_script_variables(cmd, w); }
|
||||
bool operator()(const cryptonote::cc_command_set_title_t &cmd) const { return self.process_set_title(cmd, w); }
|
||||
bool operator()(const cryptonote::cc_command_add_tax_break_zone_t &cmd) const { return self.process_add_tax_break_zone(cmd, w); }
|
||||
bool operator()(const cryptonote::cc_command_smelt_t &cmd) const { return self.process_smelt(cmd, w); }
|
||||
bool operator()(const cryptonote::cc_command_sow_t &cmd) const { return self.process_sow(cmd, w); }
|
||||
@ -1443,7 +1453,7 @@ void GameState::SendGameNotification(bool important, const String &s, const Stri
|
||||
bool GameState::ignore_player(uint32_t id) const
|
||||
{
|
||||
const uint32_t type = cc_ignore ? cc_ignore->type : (uint32_t)tools::cc_ignore_t::recommendations;
|
||||
std::map<uint32_t, std::tuple<std::string, bool, bool>>::const_iterator i;
|
||||
std::map<uint32_t, std::tuple<std::string, std::string, bool, bool>>::const_iterator i;
|
||||
switch (type)
|
||||
{
|
||||
default:
|
||||
@ -1451,7 +1461,7 @@ bool GameState::ignore_player(uint32_t id) const
|
||||
i = player_names.find(id);
|
||||
if (i == player_names.end())
|
||||
return false;
|
||||
return std::get<1>(i->second);
|
||||
return std::get<2>(i->second);
|
||||
case tools::cc_ignore_t::nothing:
|
||||
return false;
|
||||
case tools::cc_ignore_t::custom:
|
||||
@ -1464,7 +1474,7 @@ bool GameState::ignore_player(uint32_t id) const
|
||||
return true;
|
||||
i = player_names.find(id);
|
||||
if (i != player_names.end())
|
||||
return std::get<1>(i->second);
|
||||
return std::get<2>(i->second);
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
@ -1563,7 +1573,7 @@ bool GameState::ignore_item(uint32_t id) const
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string GameState::get_player_name(uint32_t id) const
|
||||
std::string GameState::get_player_name(uint32_t id, bool with_title) const
|
||||
{
|
||||
auto i = player_names.find(id);
|
||||
if (i == player_names.end())
|
||||
@ -1575,7 +1585,12 @@ std::string GameState::get_player_name(uint32_t id) const
|
||||
}
|
||||
i = player_names.find(id);
|
||||
if (i != player_names.end() && !ignore_player(id) && !std::get<0>(i->second).empty())
|
||||
return std::get<0>(i->second);
|
||||
{
|
||||
std::string s = std::get<0>(i->second);
|
||||
if (with_title && !std::get<1>(i->second).empty())
|
||||
s += " " + std::get<1>(i->second);
|
||||
return s;
|
||||
}
|
||||
return "Player " + std::to_string(id);
|
||||
}
|
||||
|
||||
@ -1615,7 +1630,7 @@ bool GameState::is_autonomous_player(uint32_t id) const
|
||||
}
|
||||
i = player_names.find(id);
|
||||
if (i != player_names.end())
|
||||
return std::get<2>(i->second);
|
||||
return std::get<3>(i->second);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1902,7 +1917,7 @@ bool GameState::reset(const cryptonote::cc_snapshot *snapshot)
|
||||
|
||||
for (const auto &e: snapshot->player_data)
|
||||
{
|
||||
set_player_name(e.id, e.name, e.ignore, e.autonomous);
|
||||
set_player_name(e.id, e.name, e.title, e.ignore, e.autonomous);
|
||||
if (e.autonomous)
|
||||
continue;
|
||||
const auto score_level = cc::get_badge_score(e.badges);
|
||||
|
@ -20,6 +20,7 @@ URHO3D_EVENT(E_CRYPTOCITY_REQUEST_PLAYER_DATA, RequestPlayerData)
|
||||
URHO3D_PARAM(P_PUBLIC_KEY, PublicKey);
|
||||
URHO3D_PARAM(P_BALANCE, Balance);
|
||||
URHO3D_PARAM(P_NAME, Name);
|
||||
URHO3D_PARAM(P_TITLE, Title);
|
||||
URHO3D_PARAM(P_DESCRIPTION, Description);
|
||||
URHO3D_PARAM(P_ITEM_BALANCES, ItemBalances);
|
||||
URHO3D_PARAM(P_FLAGS, Flags);
|
||||
@ -163,6 +164,8 @@ struct PlayerState
|
||||
uint32_t prestige;
|
||||
std::vector<uint32_t> textures_created;
|
||||
std::vector<uint32_t> textures_licenced;
|
||||
int32_t title_adjective, title_noun, title_origin, title_unique;
|
||||
std::string title;
|
||||
|
||||
PlayerState(): id(0), balance(0), wallet_balance(0), wallet_unlocked_balance(0), reserved_balance(0), name(""), has_wallet(false), ignored(false), inviting_account(0), num_invited(0), first_flag(0), script(0), script_state(0), script_city(0), script_owner(0), prestige(0) { }
|
||||
void update(const std::shared_ptr<GameWallet> &w);
|
||||
@ -182,7 +185,7 @@ public:
|
||||
PlayerState playerState;
|
||||
CityState cityState;
|
||||
uint64_t subsidy;
|
||||
std::map<uint32_t, std::tuple<std::string, bool, bool>> player_names;
|
||||
std::map<uint32_t, std::tuple<std::string, std::string, bool, bool>> player_names;
|
||||
std::map<uint32_t, cc::cc_custom_item_t> item_data;
|
||||
std::map<uint32_t, std::tuple<std::string, std::string, std::string>> badge_names;
|
||||
std::vector<cryptonote::city_t> cities;
|
||||
@ -211,10 +214,10 @@ public:
|
||||
void clear_dirty_flags() { dirty_flags.clear(); }
|
||||
void add_dirty_flag(const std::shared_ptr<Flag> &flag, bool changed_on_chain);
|
||||
bool reset(const cryptonote::cc_snapshot *snapshot = NULL);
|
||||
void set_player_name(uint32_t id, const std::string &name, bool ignore, bool autonomous) { player_names[id] = std::make_tuple(name, ignore, autonomous); }
|
||||
void set_player_name(uint32_t id, const std::string &name, const std::string &title, bool ignore, bool autonomous) { player_names[id] = std::make_tuple(name, title, ignore, autonomous); }
|
||||
void set_item_data(uint32_t id, const cc::cc_custom_item_t &cid) { item_data[id] = cid; }
|
||||
void set_badge_name_and_desc(uint32_t id, const std::string &name, const std::string &desc, const std::string &icon) { badge_names[id] = std::make_tuple(name, desc, icon); }
|
||||
std::string get_player_name(uint32_t id) const;
|
||||
std::string get_player_name(uint32_t id, bool with_title = false) const;
|
||||
std::string get_player_name(const crypto::public_key &pkey) const;
|
||||
uint32_t get_player_by_name(const std::string &name) const;
|
||||
bool is_autonomous_player(uint32_t id) const;
|
||||
@ -296,6 +299,7 @@ private:
|
||||
bool process_service(const cryptonote::cc_command_service_t &cmd, const std::shared_ptr<GameWallet> &w);
|
||||
bool process_set_merchant_ship_items(const cryptonote::cc_command_set_merchant_ship_items_t &cmd, const std::shared_ptr<GameWallet> &w);
|
||||
bool process_set_script_variables(const cryptonote::cc_command_set_script_variables_t &cmd, const std::shared_ptr<GameWallet> &w);
|
||||
bool process_set_title(const cryptonote::cc_command_set_title_t &cmd, const std::shared_ptr<GameWallet> &w);
|
||||
bool process_add_tax_break_zone(const cryptonote::cc_command_add_tax_break_zone_t &cmd, const std::shared_ptr<GameWallet> &w);
|
||||
bool process_smelt(const cryptonote::cc_command_smelt_t &cmd, const std::shared_ptr<GameWallet> &w);
|
||||
bool process_sow(const cryptonote::cc_command_sow_t &cmd, const std::shared_ptr<GameWallet> &w);
|
||||
|
@ -193,6 +193,7 @@ std::string get_command_string(const GameState *game, const cryptonote::cc_comma
|
||||
msg.push_back("'" + e.name + "' to " + std::to_string(e.new_value));
|
||||
return "Setting script variables " + boost::join(msg, ", ");
|
||||
}
|
||||
std::string operator()(const cryptonote::cc_command_set_title_t &cmd) const { return "Changing title"; }
|
||||
std::string operator()(const cryptonote::cc_command_add_tax_break_zone_t &cmd) const { return "Adding a tax break zone"; }
|
||||
std::string operator()(const cryptonote::cc_command_smelt_t &cmd) const { return "Smelting " + std::to_string(cmd.amount) + " collectible coins"; }
|
||||
std::string operator()(const cryptonote::cc_command_sow_t &cmd) const { return "Sowing " + std::string(cc::get_crop_name(cmd.crop)) + " in " + game_util::get_building_name(game, cmd.flag); }
|
||||
@ -436,7 +437,7 @@ std::pair<std::string, crypto::hash> get_item_info(const GameState *game, const
|
||||
ss << "Group: " << group << "\n";
|
||||
}
|
||||
ss << "Type: user defined\n";
|
||||
ss << "Creator: " << game->get_player_name(creator) << "\n";
|
||||
ss << "Creator: " << game->get_player_name(creator, true) << "\n";
|
||||
ss << "Amount: " << amount << (can_create_more ? " (more can be created)" : " (fixed)") << "\n";
|
||||
}
|
||||
}
|
||||
|
@ -361,7 +361,7 @@ public:
|
||||
uint32_t get_cc_account();
|
||||
crypto::public_key get_cc_pkey();
|
||||
bool get_cc_account_data(uint32_t id, std::string &name);
|
||||
bool get_cc_account_data(uint32_t id, std::string &public_key, uint64_t &balance, std::map<uint32_t, uint32_t> &item_balances, std::vector<uint32_t> &flags, std::map<uint32_t, std::pair<uint8_t, uint64_t>> &badges, std::map<uint32_t, uint32_t> &attributes, std::string &name, std::string &description, bool &ignore, uint32_t &inviting_account, uint32_t &num_invited, uint32_t &first_flag, uint32_t &script, uint32_t &script_state, uint32_t &script_city, uint32_t &script_owner, std::map<uint32_t, std::pair<uint64_t, std::map<uint32_t, uint32_t>>> &reserve, std::map<std::string, uint64_t> &script_variables, std::map<std::string, uint64_t> &script_local_variables, std::map<uint32_t, std::pair<uint32_t, std::map<std::string, uint64_t>>> &background_script_states, uint32_t &prestige, std::vector<uint32_t> &textures_created, std::vector<uint32_t> &textures_licenced, std::string &pmspk, std::string &pmvpk);
|
||||
bool get_cc_account_data(uint32_t id, std::string &public_key, uint64_t &balance, std::map<uint32_t, uint32_t> &item_balances, std::vector<uint32_t> &flags, std::map<uint32_t, std::pair<uint8_t, uint64_t>> &badges, std::map<uint32_t, uint32_t> &attributes, std::string &name, int32_t &title_adjective, int32_t &title_noun, int32_t &title_origin, int32_t &title_unique, std::string &title, std::string &description, bool &ignore, uint32_t &inviting_account, uint32_t &num_invited, uint32_t &first_flag, uint32_t &script, uint32_t &script_state, uint32_t &script_city, uint32_t &script_owner, std::map<uint32_t, std::pair<uint64_t, std::map<uint32_t, uint32_t>>> &reserve, std::map<std::string, uint64_t> &script_variables, std::map<std::string, uint64_t> &script_local_variables, std::map<uint32_t, std::pair<uint32_t, std::map<std::string, uint64_t>>> &background_script_states, uint32_t &prestige, std::vector<uint32_t> &textures_created, std::vector<uint32_t> &textures_licenced, std::string &pmspk, std::string &pmvpk);
|
||||
bool get_cc_account_reserve(uint32_t id, uint32_t account, uint64_t &balance, std::map<uint32_t, uint32_t> &items);
|
||||
bool get_cc_custom_item_data(uint32_t id, std::string &name);
|
||||
bool get_cc_custom_item_data(uint32_t id, uint64_t &creation_height, uint32_t &creator, uint64_t &amount, std::string &name, bool &is_group, bool &is_public, uint32_t &group, std::string &primary_description, std::string &secondary_description, bool &ignore, uint64_t &gold, std::vector<uint64_t> &user_data, crypto::hash &hash, bool &can_create_more, uint32_t &prestige_bonus, std::vector<uint32_t> &role_bonus);
|
||||
@ -436,6 +436,7 @@ public:
|
||||
void add_cc_vista(const std::string &vista, const std::string &label, const std::string &picture);
|
||||
void delete_cc_vista(const std::string &vista);
|
||||
const std::vector<std::tuple<std::string, std::string, std::string>> &get_cc_vistas();
|
||||
bool get_cc_available_title_components(uint32_t id, std::vector<std::pair<uint32_t, std::string>> &adjectives, std::vector<std::pair<uint32_t, std::string>> &nouns, std::vector<std::pair<uint32_t, std::string>> &origins, std::vector<std::pair<uint32_t, std::string>> &uniques);
|
||||
|
||||
std::shared_ptr<tools::wallet2> wallet() { boost::unique_lock<boost::mutex> lock(mutex); return internal_wallet; }
|
||||
bool is_spectator() const { return spectator; }
|
||||
@ -1662,6 +1663,13 @@ const std::vector<std::tuple<std::string, std::string, std::string>> &GameWallet
|
||||
return w->get_cc_vistas();
|
||||
}
|
||||
|
||||
bool GameWalletInternal::get_cc_available_title_components(uint32_t id, std::vector<std::pair<uint32_t, std::string>> &adjectives, std::vector<std::pair<uint32_t, std::string>> &nouns, std::vector<std::pair<uint32_t, std::string>> &origins, std::vector<std::pair<uint32_t, std::string>> &uniques)
|
||||
{
|
||||
std::shared_ptr<tools::wallet2> w = wallet();
|
||||
boost::unique_lock<boost::mutex> lock(mutex);
|
||||
return w->get_cc_available_title_components(id, adjectives, nouns, origins, uniques);
|
||||
}
|
||||
|
||||
bool GameWalletInternal::get_cc_accounts(std::vector<std::tuple<uint32_t, std::string, bool, bool>> &accounts)
|
||||
{
|
||||
std::shared_ptr<tools::wallet2> w = wallet();
|
||||
@ -1710,11 +1718,11 @@ crypto::public_key GameWalletInternal::get_cc_pkey()
|
||||
return pkey;
|
||||
}
|
||||
|
||||
bool GameWalletInternal::get_cc_account_data(uint32_t id, std::string &public_key, uint64_t &balance, std::map<uint32_t, uint32_t> &item_balances, std::vector<uint32_t> &flags, std::map<uint32_t, std::pair<uint8_t, uint64_t>> &badges, std::map<uint32_t, uint32_t> &attributes, std::string &name, std::string &description, bool &ignore, uint32_t &inviting_account, uint32_t &num_invited, uint32_t &first_flag, uint32_t &script, uint32_t &script_state, uint32_t &script_city, uint32_t &script_owner, std::map<uint32_t, std::pair<uint64_t, std::map<uint32_t, uint32_t>>> &reserve, std::map<std::string, uint64_t> &script_variables, std::map<std::string, uint64_t> &script_local_variables, std::map<uint32_t, std::pair<uint32_t, std::map<std::string, uint64_t>>> &background_script_states, uint32_t &prestige, std::vector<uint32_t> &textures_created, std::vector<uint32_t> &textures_licenced, std::string &pmspk, std::string &pmvpk)
|
||||
bool GameWalletInternal::get_cc_account_data(uint32_t id, std::string &public_key, uint64_t &balance, std::map<uint32_t, uint32_t> &item_balances, std::vector<uint32_t> &flags, std::map<uint32_t, std::pair<uint8_t, uint64_t>> &badges, std::map<uint32_t, uint32_t> &attributes, std::string &name, int32_t &title_adjective, int32_t &title_noun, int32_t &title_origin, int32_t &title_unique, std::string &title, std::string &description, bool &ignore, uint32_t &inviting_account, uint32_t &num_invited, uint32_t &first_flag, uint32_t &script, uint32_t &script_state, uint32_t &script_city, uint32_t &script_owner, std::map<uint32_t, std::pair<uint64_t, std::map<uint32_t, uint32_t>>> &reserve, std::map<std::string, uint64_t> &script_variables, std::map<std::string, uint64_t> &script_local_variables, std::map<uint32_t, std::pair<uint32_t, std::map<std::string, uint64_t>>> &background_script_states, uint32_t &prestige, std::vector<uint32_t> &textures_created, std::vector<uint32_t> &textures_licenced, std::string &pmspk, std::string &pmvpk)
|
||||
{
|
||||
std::shared_ptr<tools::wallet2> w = wallet();
|
||||
boost::unique_lock<boost::mutex> lock(mutex);
|
||||
if (!w->get_cc_account_data(id, public_key, balance, item_balances, flags, badges, attributes, name, description, ignore, inviting_account, num_invited, first_flag, script, script_state, script_city, script_owner, reserve, script_variables, script_local_variables, background_script_states, prestige, textures_created, textures_licenced, pmspk, pmvpk))
|
||||
if (!w->get_cc_account_data(id, public_key, balance, item_balances, flags, badges, attributes, name, title_adjective, title_noun, title_origin, title_unique, title, description, ignore, inviting_account, num_invited, first_flag, script, script_state, script_city, script_owner, reserve, script_variables, script_local_variables, background_script_states, prestige, textures_created, textures_licenced, pmspk, pmvpk))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
@ -1728,7 +1736,7 @@ bool GameWalletInternal::get_cc_account_reserve(uint32_t id, uint32_t account, u
|
||||
|
||||
bool GameWalletInternal::get_cc_account_data(uint32_t id, std::string &name)
|
||||
{
|
||||
std::string public_key, pmspk, pmvpk;
|
||||
std::string public_key, pmspk, pmvpk, title;
|
||||
uint64_t balance;
|
||||
std::map<uint32_t, uint32_t> item_balances;
|
||||
std::vector<uint32_t> flags;
|
||||
@ -1745,11 +1753,12 @@ bool GameWalletInternal::get_cc_account_data(uint32_t id, std::string &name)
|
||||
std::map<uint32_t, std::pair<uint32_t, std::map<std::string, uint64_t>>> background_script_states;
|
||||
uint32_t prestige;
|
||||
std::vector<uint32_t> textures_created, textures_licenced;
|
||||
int32_t title_adjective, title_noun, title_origin, title_unique;
|
||||
|
||||
std::shared_ptr<tools::wallet2> w = wallet();
|
||||
boost::unique_lock<boost::mutex> lock(mutex);
|
||||
|
||||
if (!w->get_cc_account_data(id, public_key, balance, item_balances, flags, badges, attributes, name, description, ignore, inviting_account, num_invited, first_flag, script, script_state, script_city, script_owner, reserve, script_variables, script_local_variables, background_script_states, prestige, textures_created, textures_licenced, pmspk, pmvpk))
|
||||
if (!w->get_cc_account_data(id, public_key, balance, item_balances, flags, badges, attributes, name, title_adjective, title_noun, title_origin, title_unique, title, description, ignore, inviting_account, num_invited, first_flag, script, script_state, script_city, script_owner, reserve, script_variables, script_local_variables, background_script_states, prestige, textures_created, textures_licenced, pmspk, pmvpk))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
@ -2666,6 +2675,7 @@ void GameWalletInternal::on_reorg(uint64_t height)
|
||||
bool operator()(const cryptonote::cc_command_set_script_variables_t &cmd) const { return false; }
|
||||
bool operator()(const cryptonote::cc_command_add_tax_break_zone_t &cmd) const { return false; }
|
||||
bool operator()(const cryptonote::cc_command_smelt_t &cmd) const { return false; }
|
||||
bool operator()(const cryptonote::cc_command_set_title_t &cmd) const { return false; }
|
||||
bool operator()(const cryptonote::cc_command_sow_t &cmd) const { return false; }
|
||||
bool operator()(const cryptonote::cc_command_start_epoch_t &cmd) const { return false; }
|
||||
bool operator()(const cryptonote::cc_command_start_script_t &cmd) const { return false; }
|
||||
@ -3046,6 +3056,11 @@ const std::vector<std::tuple<std::string, std::string, std::string>> &GameWallet
|
||||
return internal->get_cc_vistas();
|
||||
}
|
||||
|
||||
bool GameWallet::get_cc_available_title_components(uint32_t id, std::vector<std::pair<uint32_t, std::string>> &adjectives, std::vector<std::pair<uint32_t, std::string>> &nouns, std::vector<std::pair<uint32_t, std::string>> &origins, std::vector<std::pair<uint32_t, std::string>> &uniques)
|
||||
{
|
||||
return internal->get_cc_available_title_components(id, adjectives, nouns, origins, uniques);
|
||||
}
|
||||
|
||||
uint32_t GameWallet::get_cc_account()
|
||||
{
|
||||
return internal->get_cc_account();
|
||||
@ -3086,9 +3101,9 @@ bool GameWallet::get_cc_account_data(uint32_t id, std::string &name)
|
||||
return internal->get_cc_account_data(id, name);
|
||||
}
|
||||
|
||||
bool GameWallet::get_cc_account_data(uint32_t id, std::string &public_key, uint64_t &balance, std::map<uint32_t, uint32_t> &item_balances, std::vector<uint32_t> &flags, std::map<uint32_t, std::pair<uint8_t, uint64_t>> &badges, std::map<uint32_t, uint32_t> &attributes, std::string &name, std::string &description, bool &ignore, uint32_t &inviting_account, uint32_t &num_invited, uint32_t &first_flag, uint32_t &script, uint32_t &script_state, uint32_t &script_city, uint32_t &script_owner, std::map<uint32_t, std::pair<uint64_t, std::map<uint32_t, uint32_t>>> &reserve, std::map<std::string, uint64_t> &script_variables, std::map<std::string, uint64_t> &script_local_variables, std::map<uint32_t, std::pair<uint32_t, std::map<std::string, uint64_t>>> &background_script_states, uint32_t &prestige, std::vector<uint32_t> &textures_created, std::vector<uint32_t> &textures_licenced, std::string &pmspk, std::string &pmvpk)
|
||||
bool GameWallet::get_cc_account_data(uint32_t id, std::string &public_key, uint64_t &balance, std::map<uint32_t, uint32_t> &item_balances, std::vector<uint32_t> &flags, std::map<uint32_t, std::pair<uint8_t, uint64_t>> &badges, std::map<uint32_t, uint32_t> &attributes, std::string &name, int32_t &title_adjective, int32_t &title_noun, int32_t &title_origin, int32_t &title_unique, std::string &title, std::string &description, bool &ignore, uint32_t &inviting_account, uint32_t &num_invited, uint32_t &first_flag, uint32_t &script, uint32_t &script_state, uint32_t &script_city, uint32_t &script_owner, std::map<uint32_t, std::pair<uint64_t, std::map<uint32_t, uint32_t>>> &reserve, std::map<std::string, uint64_t> &script_variables, std::map<std::string, uint64_t> &script_local_variables, std::map<uint32_t, std::pair<uint32_t, std::map<std::string, uint64_t>>> &background_script_states, uint32_t &prestige, std::vector<uint32_t> &textures_created, std::vector<uint32_t> &textures_licenced, std::string &pmspk, std::string &pmvpk)
|
||||
{
|
||||
return internal->get_cc_account_data(id, public_key, balance, item_balances, flags, badges, attributes, name, description, ignore, inviting_account, num_invited, first_flag, script, script_state, script_city, script_owner, reserve, script_variables, script_local_variables, background_script_states, prestige, textures_created, textures_licenced, pmspk, pmvpk);
|
||||
return internal->get_cc_account_data(id, public_key, balance, item_balances, flags, badges, attributes, name, title_adjective, title_noun, title_origin, title_unique, title, description, ignore, inviting_account, num_invited, first_flag, script, script_state, script_city, script_owner, reserve, script_variables, script_local_variables, background_script_states, prestige, textures_created, textures_licenced, pmspk, pmvpk);
|
||||
}
|
||||
|
||||
bool GameWallet::get_cc_account_reserve(uint32_t id, uint32_t account, uint64_t &balance, std::map<uint32_t, uint32_t> &items)
|
||||
|
@ -77,7 +77,7 @@ public:
|
||||
uint32_t get_cc_account();
|
||||
crypto::public_key get_cc_pkey();
|
||||
bool get_cc_account_data(uint32_t id, std::string &name);
|
||||
bool get_cc_account_data(uint32_t id, std::string &public_key, uint64_t &balance, std::map<uint32_t, uint32_t> &item_balances, std::vector<uint32_t> &flags, std::map<uint32_t, std::pair<uint8_t, uint64_t>> &badges, std::map<uint32_t, uint32_t> &attributes, std::string &name, std::string &description, bool &ignore, uint32_t &inviting_account, uint32_t &num_invited, uint32_t &first_flag, uint32_t &script, uint32_t &script_state, uint32_t &script_city, uint32_t &script_owner, std::map<uint32_t, std::pair<uint64_t, std::map<uint32_t, uint32_t>>> &reserve, std::map<std::string, uint64_t> &script_variables, std::map<std::string, uint64_t> &script_local_variables, std::map<uint32_t, std::pair<uint32_t, std::map<std::string, uint64_t>>> &background_script_states, uint32_t &prestige, std::vector<uint32_t> &textures_created, std::vector<uint32_t> &textures_licenced, std::string &pmspk, std::string &pmvpk);
|
||||
bool get_cc_account_data(uint32_t id, std::string &public_key, uint64_t &balance, std::map<uint32_t, uint32_t> &item_balances, std::vector<uint32_t> &flags, std::map<uint32_t, std::pair<uint8_t, uint64_t>> &badges, std::map<uint32_t, uint32_t> &attributes, std::string &name, int32_t &title_adjective, int32_t &title_noun, int32_t &title_origin, int32_t &title_unique, std::string &title, std::string &description, bool &ignore, uint32_t &inviting_account, uint32_t &num_invited, uint32_t &first_flag, uint32_t &script, uint32_t &script_state, uint32_t &script_city, uint32_t &script_owner, std::map<uint32_t, std::pair<uint64_t, std::map<uint32_t, uint32_t>>> &reserve, std::map<std::string, uint64_t> &script_variables, std::map<std::string, uint64_t> &script_local_variables, std::map<uint32_t, std::pair<uint32_t, std::map<std::string, uint64_t>>> &background_script_states, uint32_t &prestige, std::vector<uint32_t> &textures_created, std::vector<uint32_t> &textures_licenced, std::string &pmspk, std::string &pmvpk);
|
||||
bool get_cc_account_reserve(uint32_t id, uint32_t account, uint64_t &balance, std::map<uint32_t, uint32_t> &items);
|
||||
bool get_cc_custom_item_data(uint32_t id, std::string &name);
|
||||
bool get_cc_custom_item_data(uint32_t id, uint64_t &creation_height, uint32_t &creator, uint64_t &amount, std::string &name, bool &is_group, bool &is_public, uint32_t &group, std::string &primary_description, std::string &secondary_description, bool &ignore, uint64_t &gold, std::vector<uint64_t> &user_data, crypto::hash &hash, bool &can_create_more, uint32_t &prestige_bonus, std::vector<uint32_t> &role_bonus);
|
||||
@ -145,6 +145,7 @@ public:
|
||||
void add_cc_vista(const std::string &vista, const std::string &label, const std::string &picture);
|
||||
void delete_cc_vista(const std::string &vista);
|
||||
const std::vector<std::tuple<std::string, std::string, std::string>> &get_cc_vistas();
|
||||
bool get_cc_available_title_components(uint32_t id, std::vector<std::pair<uint32_t, std::string>> &adjectives, std::vector<std::pair<uint32_t, std::string>> &nouns, std::vector<std::pair<uint32_t, std::string>> &origins, std::vector<std::pair<uint32_t, std::string>> &uniques);
|
||||
|
||||
const std::vector<cc::cc_message_t> get_cc_messages();
|
||||
size_t get_num_unread_cc_messages();
|
||||
|
@ -587,6 +587,7 @@ public:
|
||||
void HandlePlaceModel(StringHash eventType, VariantMap& eventData);
|
||||
void HandleBlockBatchStart(StringHash eventType, VariantMap& eventData);
|
||||
void HandleBlockBatchStop(StringHash eventType, VariantMap& eventData);
|
||||
void HandleChangeTitle(StringHash eventType, VariantMap& eventData);
|
||||
|
||||
void SetCameraType(TBID type);
|
||||
void MoveCamera(float timeStep);
|
||||
@ -1752,6 +1753,7 @@ void CryptoCityUrho3D::SetupUI()
|
||||
SubscribeToEvent(ui, E_CRYPTOCITY_MESSAGES_READ, URHO3D_HANDLER(CryptoCityUrho3D, HandleMessagesRead));
|
||||
SubscribeToEvent(ui, E_CRYPTOCITY_GET_ONLINE_PLAYERS, URHO3D_HANDLER(CryptoCityUrho3D, HandleGetOnlinePlayers));
|
||||
SubscribeToEvent(ui, E_CRYPTOCITY_START_NEW_EPOCH, URHO3D_HANDLER(CryptoCityUrho3D, HandleStartNewEpoch));
|
||||
SubscribeToEvent(ui, E_CRYPTOCITY_CHANGE_TITLE, URHO3D_HANDLER(CryptoCityUrho3D, HandleChangeTitle));
|
||||
SubscribeToEvent(&gameState, E_CRYPTOCITY_REQUEST_PLAYER_DATA, URHO3D_HANDLER(CryptoCityUrho3D, HandleRequestPlayerData));
|
||||
SubscribeToEvent(&gameState, E_CRYPTOCITY_REQUEST_ITEM_DATA, URHO3D_HANDLER(CryptoCityUrho3D, HandleRequestItemData));
|
||||
SubscribeToEvent(&gameState, E_CRYPTOCITY_REQUEST_SCRIPT_DATA, URHO3D_HANDLER(CryptoCityUrho3D, HandleRequestScriptData));
|
||||
@ -2033,7 +2035,7 @@ void CryptoCityUrho3D::UpdateTargetting()
|
||||
CloseBuildingTooltip();
|
||||
std::string text =
|
||||
game_util::get_building_name(&gameState, hover_flag) + "\n" +
|
||||
gameState.get_player_name(hover_flag->owner) + "\n" +
|
||||
gameState.get_player_name(hover_flag->owner, true) + "\n" +
|
||||
cc::get_role_name(hover_flag->role);
|
||||
const auto it = flags_for_sale.find(hover_flag->id);
|
||||
if (it != flags_for_sale.end())
|
||||
@ -2288,7 +2290,7 @@ void CryptoCityUrho3D::UpdateTargetting()
|
||||
const Controls::Input input = Controls::Get().Get(Controls::ACTION_OBSERVE);
|
||||
if (gameState.ignore_player(whisperer))
|
||||
message = "...";
|
||||
std::string msg = "Whisper from " + gameState.get_player_name(whisperer) + ":\n\n" + message;
|
||||
std::string msg = "Whisper from " + gameState.get_player_name(whisperer, true) + ":\n\n" + message;
|
||||
if (input != Controls::INPUT_NONE)
|
||||
msg += "\n\nPress " + std::string(Controls::Get().GetInputName(input)) + " to observe";
|
||||
whisper_tooltip->SetText(msg.c_str());
|
||||
@ -3895,7 +3897,7 @@ void CryptoCityUrho3D::HandleMessageReceived(StringHash eventType, VariantMap& e
|
||||
const uint32_t sender = message->sender;
|
||||
if (gameState.ignore_player(sender))
|
||||
return;
|
||||
const std::string player_name = gameState.get_player_name(message->sender);
|
||||
const std::string player_name = gameState.get_player_name(message->sender, true);
|
||||
const std::string msg = "Mew message from " + player_name + ":\n" + message->subject;
|
||||
ui->AddToastNotification(msg.c_str());
|
||||
}
|
||||
@ -4282,6 +4284,21 @@ void CryptoCityUrho3D::HandleStartNewEpoch(StringHash eventType, VariantMap& eve
|
||||
ui->AddToastNotification(("Starting epoch '" + cmd.name + "'").c_str());
|
||||
}
|
||||
|
||||
void CryptoCityUrho3D::HandleChangeTitle(StringHash eventType, VariantMap& eventData)
|
||||
{
|
||||
UnsetFocus();
|
||||
cryptonote::cc_command_set_title_t cmd;
|
||||
cmd.cc_account = wallet->get_cc_account();
|
||||
|
||||
cmd.delta_adjective = eventData[ChangeTitle::P_ADJECTIVE].GetInt() - gameState.playerState.title_adjective;
|
||||
cmd.delta_noun = eventData[ChangeTitle::P_NOUN].GetInt() - gameState.playerState.title_noun;
|
||||
cmd.delta_origin = eventData[ChangeTitle::P_ORIGIN].GetInt() - gameState.playerState.title_origin;
|
||||
cmd.delta_unique = eventData[ChangeTitle::P_UNIQUE].GetInt() - gameState.playerState.title_unique;
|
||||
|
||||
if (SendCommand(cmd))
|
||||
ui->AddToastNotification("Changing title");
|
||||
}
|
||||
|
||||
void CryptoCityUrho3D::HandlePlaceModel(StringHash eventType, VariantMap& eventData)
|
||||
{
|
||||
UnsetFocus();
|
||||
@ -9272,7 +9289,7 @@ void CryptoCityUrho3D::NotifyGameUpdate(const cryptonote::block *b)
|
||||
uint32_t player_id = std::get<0>(e.bids.back());
|
||||
std::string price = game_util::print_money(std::get<1>(e.bids.back()));
|
||||
game_util::reduce_amount_zeroes(price);
|
||||
msg = gameState.get_player_name(player_id) + " won the " + e.title + " auction for " + price;
|
||||
msg = gameState.get_player_name(player_id, true) + " won the " + e.title + " auction for " + price;
|
||||
}
|
||||
if (!msg.empty())
|
||||
ui->AddToastNotification(msg.c_str(), "images/auction-hammer.png");
|
||||
@ -10567,7 +10584,7 @@ void CryptoCityUrho3D::HandleRequestPlayerData(StringHash eventType, VariantMap&
|
||||
id = wallet->lookup_account(pkey.CString());
|
||||
}
|
||||
|
||||
std::string name, description;
|
||||
std::string name, description, title;
|
||||
std::string public_key, pmspk, pmvpk;
|
||||
uint64_t balance;
|
||||
std::map<uint32_t, uint32_t> item_balances;
|
||||
@ -10584,13 +10601,15 @@ void CryptoCityUrho3D::HandleRequestPlayerData(StringHash eventType, VariantMap&
|
||||
std::map<uint32_t, std::pair<uint32_t, std::map<std::string, uint64_t>>> background_script_states;
|
||||
uint32_t prestige;
|
||||
std::vector<uint32_t> textures_created, textures_licenced;
|
||||
if (wallet->get_cc_account_data(id, public_key, balance, item_balances, flags, badges, attributes, name, description, ignore, inviting_account, num_invited, first_flag, script, script_state, script_city, script_owner, reserve, script_variables, script_local_variables, background_script_states, prestige, textures_created, textures_licenced, pmspk, pmvpk))
|
||||
int32_t title_adjective, title_noun, title_origin, title_unique;
|
||||
if (wallet->get_cc_account_data(id, public_key, balance, item_balances, flags, badges, attributes, name, title_adjective, title_noun, title_origin, title_unique, title, description, ignore, inviting_account, num_invited, first_flag, script, script_state, script_city, script_owner, reserve, script_variables, script_local_variables, background_script_states, prestige, textures_created, textures_licenced, pmspk, pmvpk))
|
||||
{
|
||||
gameState.set_player_name(id, name, ignore, public_key == epee::string_tools::pod_to_hex(crypto::null_pkey));
|
||||
gameState.set_player_name(id, name, title, ignore, public_key == epee::string_tools::pod_to_hex(crypto::null_pkey));
|
||||
|
||||
eventData[RequestPlayerData::P_ACCOUNT] = id;
|
||||
eventData[RequestPlayerData::P_PUBLIC_KEY] = public_key.c_str();
|
||||
eventData[RequestPlayerData::P_NAME] = gameState.get_player_name(id).c_str();
|
||||
eventData[RequestPlayerData::P_TITLE] = title.c_str();
|
||||
eventData[RequestPlayerData::P_DESCRIPTION] = description.c_str();
|
||||
eventData[RequestPlayerData::P_BALANCE] = (unsigned long long)balance;
|
||||
eventData[RequestPlayerData::P_PRESTIGE] = prestige;
|
||||
@ -10980,7 +10999,7 @@ void CryptoCityUrho3D::HandleEventBadge(StringHash eventType, VariantMap& eventD
|
||||
const std::vector<std::pair<uint32_t, uint8_t>> *v = (const std::vector<std::pair<uint32_t, uint8_t>>*)eventData[EventBadge::P_INSTANCES].GetVoidPtr();
|
||||
for (const auto &e: *v)
|
||||
{
|
||||
std::string name, description;
|
||||
std::string name, description, title;
|
||||
std::string public_key, pmspk, pmvpk;
|
||||
uint64_t balance;
|
||||
std::map<uint32_t, uint32_t> item_balances;
|
||||
@ -10997,7 +11016,8 @@ void CryptoCityUrho3D::HandleEventBadge(StringHash eventType, VariantMap& eventD
|
||||
std::map<uint32_t, std::pair<uint32_t, std::map<std::string, uint64_t>>> background_script_states;
|
||||
uint32_t prestige;
|
||||
std::vector<uint32_t> textures_created, textures_licenced;
|
||||
if (!wallet->get_cc_account_data(e.first, public_key, balance, item_balances, flags, badges, attributes, name, description, ignore, inviting_account, num_invited, first_flag, script, script_state, script_city, script_owner, reserve, script_variables, script_local_variables, background_script_states, prestige, textures_created, textures_licenced, pmspk, pmvpk))
|
||||
int32_t title_adjective, title_noun, title_origin, title_unique;
|
||||
if (!wallet->get_cc_account_data(e.first, public_key, balance, item_balances, flags, badges, attributes, name, title_adjective, title_noun, title_origin, title_unique, title, description, ignore, inviting_account, num_invited, first_flag, script, script_state, script_city, script_owner, reserve, script_variables, script_local_variables, background_script_states, prestige, textures_created, textures_licenced, pmspk, pmvpk))
|
||||
{
|
||||
new MessageBox(context_, "Failed to get account data for recipient");
|
||||
return;
|
||||
|
@ -45,7 +45,7 @@ void RemoteAvatars::Add(uint32_t id, const Urho3D::Vector3 &pos, const Urho3D::V
|
||||
if (i == data.end())
|
||||
{
|
||||
std::shared_ptr<Avatar> avatar(new Avatar(shared_model_name, node, collidable_root));
|
||||
avatar->SetName(game->get_player_name(id));
|
||||
avatar->SetName(game->get_player_name(id, true));
|
||||
i = data.insert(std::make_pair(id, data_t{Urho3D::Vector3::ZERO, Urho3D::Vector3::ZERO, Urho3D::Vector3::ZERO, avatar})).first;
|
||||
}
|
||||
i->second.pos = pos;
|
||||
|
258
src/game/ui-change-title.cc
Normal file
258
src/game/ui-change-title.cc
Normal file
@ -0,0 +1,258 @@
|
||||
#include <memory>
|
||||
#include <Urho3D/Core/Context.h>
|
||||
#include <Urho3D/UI/UI.h>
|
||||
#include <Urho3D/UI/UIEvents.h>
|
||||
#include <tb/tb_select.h>
|
||||
#include <tb/tb_toggle_container.h>
|
||||
#include <tb/tb_widgets_reader.h>
|
||||
#include <tb/tb_font_renderer.h>
|
||||
#include "cc/cc_title.h"
|
||||
#include "game-wallet.h"
|
||||
#include "game-state.h"
|
||||
#include "ui-tb-message-box.h"
|
||||
#include "caching-source-builder.h"
|
||||
#include "ui-change-title.h"
|
||||
|
||||
using namespace Urho3D;
|
||||
using namespace tb;
|
||||
|
||||
static std::string find_string(const std::vector<std::pair<uint32_t, std::string>> &list, int32_t id)
|
||||
{
|
||||
if (id < 0)
|
||||
return "";
|
||||
for (const auto &e: list)
|
||||
if ((uint32_t)id == e.first)
|
||||
return e.second;
|
||||
return "";
|
||||
}
|
||||
|
||||
UIChangeTitleDialog::UIChangeTitleDialog(Context *ctx, const GameState *game):
|
||||
UITBWindow(ctx, "cc/change-title.tb.txt"),
|
||||
game(game)
|
||||
{
|
||||
currentTitleWidget = GetWidgetByIDAndType<TBTextField>(TBIDC("current-title"));
|
||||
newTitleWidget = GetWidgetByIDAndType<TBTextField>(TBIDC("new-title"));
|
||||
adjectivesWidget = GetWidgetByIDAndType<TBSelectDropdown>(TBIDC("adjectives"));
|
||||
nounsWidget = GetWidgetByIDAndType<TBSelectDropdown>(TBIDC("nouns"));
|
||||
originsWidget = GetWidgetByIDAndType<TBSelectDropdown>(TBIDC("origins"));
|
||||
uniquesWidget = GetWidgetByIDAndType<TBSelectDropdown>(TBIDC("uniques"));
|
||||
compoundContainer = GetWidgetByIDAndType<TBToggleContainer>(TBIDC("toggle-style-compound"));
|
||||
uniqueContainer = GetWidgetByIDAndType<TBToggleContainer>(TBIDC("toggle-style-unique"));
|
||||
|
||||
adjectivesWidget->SetSource(&adjectives_source);
|
||||
nounsWidget->SetSource(&nouns_source);
|
||||
originsWidget->SetSource(&origins_source);
|
||||
uniquesWidget->SetSource(&uniques_source);
|
||||
|
||||
ResizeToFitContent(RESIZE_FIT_PREFERRED);
|
||||
|
||||
SubscribeToEvent(this, E_TB_WIDGET_EVENT, URHO3D_HANDLER(UIChangeTitleDialog, HandleTBMessage));
|
||||
SubscribeToEvent(this, E_TB_WINDOW_CLOSED, URHO3D_HANDLER(UIChangeTitleDialog, HandleClose));
|
||||
}
|
||||
|
||||
UIChangeTitleDialog::~UIChangeTitleDialog()
|
||||
{
|
||||
adjectivesWidget->SetSource(NULL);
|
||||
nounsWidget->SetSource(NULL);
|
||||
originsWidget->SetSource(NULL);
|
||||
uniquesWidget->SetSource(NULL);
|
||||
}
|
||||
|
||||
void UIChangeTitleDialog::UpdateLists(const std::shared_ptr<GameWallet> &w)
|
||||
{
|
||||
if (!w->get_cc_available_title_components(game->playerState.id, adjectives, nouns, origins, uniques))
|
||||
return;
|
||||
|
||||
const bool has_compound = game->playerState.title_adjective >= 0 || game->playerState.title_noun >= 0 || game->playerState.title_origin >= 0;
|
||||
const bool has_unique = game->playerState.title_unique >= 0;
|
||||
if (has_compound && has_unique)
|
||||
new MessageBox(context_, "Inconsistent title, recovering");
|
||||
if (has_unique)
|
||||
style = style_unique;
|
||||
else
|
||||
style = style_compound;
|
||||
|
||||
struct
|
||||
{
|
||||
const int32_t ¤t;
|
||||
TBSelectDropdown *widget;
|
||||
TBGenericStringItemSource &source;
|
||||
const std::vector<std::pair<uint32_t, std::string>> &list;
|
||||
} data[4] =
|
||||
{
|
||||
{ game->playerState.title_adjective, adjectivesWidget, adjectives_source, adjectives },
|
||||
{ game->playerState.title_noun, nounsWidget, nouns_source, nouns },
|
||||
{ game->playerState.title_origin, originsWidget, origins_source, origins },
|
||||
{ game->playerState.title_unique, uniquesWidget, uniques_source, uniques },
|
||||
};
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
int32_t select_item = data[i].current;
|
||||
int sel = data[i].widget->GetValue();
|
||||
if (sel >= 0 && sel < data[i].source.GetNumItems())
|
||||
{
|
||||
const tb::TBGenericStringItem *item = data[i].source.GetItem(sel);
|
||||
select_item = item->tag.GetInt();
|
||||
}
|
||||
|
||||
sel = -1;
|
||||
{
|
||||
CachingSourceBuilder<TBGenericStringItem> builder(data[i].source);
|
||||
TBGenericStringItem *item = new TBGenericStringItem("");
|
||||
item->tag.SetInt(-1);
|
||||
if (select_item == -1)
|
||||
sel = 0;
|
||||
builder.AddItem(item);
|
||||
for (const auto &e: data[i].list)
|
||||
{
|
||||
TBGenericStringItem *item = new TBGenericStringItem(e.second.c_str());
|
||||
item->tag.SetInt(e.first);
|
||||
if (e.first == (uint32_t)select_item)
|
||||
sel = builder.GetNumItems();
|
||||
builder.AddItem(item);
|
||||
}
|
||||
}
|
||||
|
||||
if (sel >= 0)
|
||||
data[i].widget->SetValue(sel);
|
||||
}
|
||||
}
|
||||
|
||||
void UIChangeTitleDialog::Update(const std::shared_ptr<GameWallet> &w)
|
||||
{
|
||||
if (game->top_hash != last_refresh_stop_hash)
|
||||
{
|
||||
UpdateLists(w);
|
||||
|
||||
const std::string adjective = find_string(adjectives, game->playerState.title_adjective);
|
||||
const std::string noun = find_string(nouns, game->playerState.title_noun);
|
||||
const std::string origin = find_string(origins, game->playerState.title_origin);
|
||||
const std::string unique = find_string(uniques, game->playerState.title_unique);
|
||||
const std::string title = cc::get_title(adjective, noun, origin, unique);
|
||||
const std::string name_and_title = game->get_player_name(game->playerState.id) + (title.empty() ? "" : (" " + title));
|
||||
currentTitleWidget->SetText(name_and_title.c_str());
|
||||
|
||||
compoundContainer->SetValue(style == style_compound);
|
||||
uniqueContainer->SetValue(style == style_unique);
|
||||
|
||||
ResizeToFitContent(RESIZE_FIT_CURRENT_OR_NEEDED);
|
||||
|
||||
last_refresh_stop_hash = game->top_hash;
|
||||
}
|
||||
}
|
||||
|
||||
void UIChangeTitleDialog::HandleSetTitleStyle(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData)
|
||||
{
|
||||
TBWidgetEvent *ev = (TBWidgetEvent*)eventData[TBWidgetEventNamespace::P_WIDGET_EVENT].GetVoidPtr();
|
||||
if (!ev->target->GetValue())
|
||||
return;
|
||||
if (ev->target->data.GetInt())
|
||||
{
|
||||
// compound
|
||||
style = style_unique;
|
||||
}
|
||||
else
|
||||
{
|
||||
// unique
|
||||
style = style_compound;
|
||||
}
|
||||
|
||||
compoundContainer->SetValue(style == style_compound);
|
||||
uniqueContainer->SetValue(style == style_unique);
|
||||
|
||||
UpdateNewTitle();
|
||||
}
|
||||
|
||||
void UIChangeTitleDialog::HandleTitleChanged(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData)
|
||||
{
|
||||
UpdateNewTitle();
|
||||
}
|
||||
|
||||
void UIChangeTitleDialog::UpdateNewTitle()
|
||||
{
|
||||
std::string title;
|
||||
if (style == style_compound)
|
||||
{
|
||||
const std::string adjective = adjectivesWidget->GetValue() >= 0 ? adjectives_source.GetItem(adjectivesWidget->GetValue())->str.CStr() : "";
|
||||
const std::string noun = nounsWidget->GetValue() >= 0 ? nouns_source.GetItem(nounsWidget->GetValue())->str.CStr() : "";
|
||||
const std::string origin = originsWidget->GetValue() >= 0 ? origins_source.GetItem(originsWidget->GetValue())->str.CStr() : "";
|
||||
title = cc::get_title(adjective, noun, origin, "");
|
||||
}
|
||||
else
|
||||
{
|
||||
const std::string unique = uniquesWidget->GetValue() >= 0 ? uniques_source.GetItem(uniquesWidget->GetValue())->str.CStr() : "";
|
||||
title = cc::get_title("", "", "", unique);
|
||||
}
|
||||
const std::string name_and_title = game->get_player_name(game->playerState.id) + (title.empty() ? "" : (" " + title));;
|
||||
newTitleWidget->SetText(name_and_title.c_str());
|
||||
ResizeToFitContent(RESIZE_FIT_CURRENT_OR_NEEDED);
|
||||
}
|
||||
|
||||
void UIChangeTitleDialog::HandleCancel(StringHash eventType, VariantMap& eventData)
|
||||
{
|
||||
VariantMap& newEventData = GetEventDataMap();
|
||||
SendEvent(E_CHANGE_TITLE_CANCELLED, newEventData);
|
||||
|
||||
// Self destruct
|
||||
Close();
|
||||
}
|
||||
|
||||
void UIChangeTitleDialog::HandleOK(StringHash eventType, VariantMap& eventData)
|
||||
{
|
||||
const int32_t adjective = adjectivesWidget->GetValue() >= 0 ? adjectives_source.GetItem(adjectivesWidget->GetValue())->tag.GetInt() : -1;
|
||||
const int32_t noun = nounsWidget->GetValue() >= 0 ? nouns_source.GetItem(nounsWidget->GetValue())->tag.GetInt() : -1;
|
||||
const int32_t origin = originsWidget->GetValue() >= 0 ? origins_source.GetItem(originsWidget->GetValue())->tag.GetInt() : -1;
|
||||
const int32_t unique = uniquesWidget->GetValue() >= 0 ? uniques_source.GetItem(uniquesWidget->GetValue())->tag.GetInt() : -1;
|
||||
|
||||
VariantMap& newEventData = GetEventDataMap();
|
||||
newEventData[ChangeTitleOkayed::P_ADJECTIVE] = adjective;
|
||||
newEventData[ChangeTitleOkayed::P_NOUN] = noun;
|
||||
newEventData[ChangeTitleOkayed::P_ORIGIN] = origin;
|
||||
newEventData[ChangeTitleOkayed::P_UNIQUE] = unique;
|
||||
SendEvent(E_CHANGE_TITLE_OKAYED, newEventData);
|
||||
|
||||
// Self destruct
|
||||
Close();
|
||||
}
|
||||
|
||||
void UIChangeTitleDialog::CancelUI()
|
||||
{
|
||||
VariantMap& newEventData = GetEventDataMap();
|
||||
SendEvent(E_CHANGE_TITLE_CANCELLED, newEventData);
|
||||
|
||||
// Self destruct
|
||||
Close();
|
||||
}
|
||||
|
||||
void UIChangeTitleDialog::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)
|
||||
{
|
||||
CONNECT("ok", HandleOK);
|
||||
CONNECT("cancel", HandleCancel);
|
||||
}
|
||||
else if (ev->type == EVENT_TYPE_CHANGED)
|
||||
{
|
||||
CONNECT("adjectives", HandleTitleChanged);
|
||||
CONNECT("nouns", HandleTitleChanged);
|
||||
CONNECT("origins", HandleTitleChanged);
|
||||
CONNECT("uniques", HandleTitleChanged);
|
||||
CONNECT("style-compound", HandleSetTitleStyle);
|
||||
CONNECT("style-unique", HandleSetTitleStyle);
|
||||
}
|
||||
|
||||
#undef CONNECT
|
||||
}
|
||||
|
||||
void UIChangeTitleDialog::HandleClose(StringHash eventType, VariantMap& eventData)
|
||||
{
|
||||
VariantMap& newEventData = GetEventDataMap();
|
||||
SendEvent(E_CHANGE_TITLE_CANCELLED, newEventData);
|
||||
|
||||
// Self destruct
|
||||
Close();
|
||||
}
|
84
src/game/ui-change-title.h
Normal file
84
src/game/ui-change-title.h
Normal file
@ -0,0 +1,84 @@
|
||||
#ifndef UI_CHANGE_TITLE_H
|
||||
#define UI_CHANGE_TITLE_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 TBSelectDropdown;
|
||||
class TBToggleContainer;
|
||||
class TBLayout;
|
||||
class TBTextField;
|
||||
}
|
||||
|
||||
class GameWallet;
|
||||
class GameState;
|
||||
|
||||
URHO3D_EVENT(E_CHANGE_TITLE_OKAYED, ChangeTitleOkayed) { URHO3D_PARAM(P_ADJECTIVE, Adjective); URHO3D_PARAM(P_NOUN, Noun); URHO3D_PARAM(P_ORIGIN, Origin); URHO3D_PARAM(P_UNIQUE, Unique); }
|
||||
URHO3D_EVENT(E_CHANGE_TITLE_CANCELLED, ChangeTitleCancelled) {}
|
||||
|
||||
class UIChangeTitleDialog: public UITBWindow
|
||||
{
|
||||
public:
|
||||
UIChangeTitleDialog(Urho3D::Context *ctx, const GameState *game = NULL);
|
||||
virtual ~UIChangeTitleDialog() override;
|
||||
|
||||
void Update(const std::shared_ptr<GameWallet> &w);
|
||||
void CancelUI();
|
||||
|
||||
private:
|
||||
enum style_t
|
||||
{
|
||||
style_compound,
|
||||
style_unique
|
||||
};
|
||||
|
||||
private:
|
||||
void HandleSetTitleStyle(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData);
|
||||
void HandleTitleChanged(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData);
|
||||
void HandleOK(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData);
|
||||
void HandleCancel(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData);
|
||||
void HandleTBMessage(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData);
|
||||
void HandleClose(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData);
|
||||
|
||||
void UpdateLists(const std::shared_ptr<GameWallet> &w);
|
||||
void UpdateNewTitle();
|
||||
|
||||
private:
|
||||
const GameState *game;
|
||||
|
||||
style_t style;
|
||||
std::vector<std::pair<uint32_t, std::string>> adjectives, nouns, origins, uniques;
|
||||
|
||||
tb::TBTextField *currentTitleWidget;
|
||||
tb::TBTextField *newTitleWidget;
|
||||
|
||||
tb::TBGenericStringItemSource adjectives_source;
|
||||
tb::TBSelectDropdown *adjectivesWidget;
|
||||
|
||||
tb::TBGenericStringItemSource nouns_source;
|
||||
tb::TBSelectDropdown *nounsWidget;
|
||||
|
||||
tb::TBGenericStringItemSource origins_source;
|
||||
tb::TBSelectDropdown *originsWidget;
|
||||
|
||||
tb::TBGenericStringItemSource uniques_source;
|
||||
tb::TBSelectDropdown *uniquesWidget;
|
||||
|
||||
tb::TBToggleContainer *compoundContainer;
|
||||
tb::TBToggleContainer *uniqueContainer;
|
||||
|
||||
std::string last_refresh_stop_hash;
|
||||
};
|
||||
|
||||
#endif
|
@ -188,7 +188,7 @@ void UICityLevelDialog::Update()
|
||||
std::string mayor = "unknown";
|
||||
for (const auto &e: game->cities)
|
||||
if (e.city_id == game->cityState.id)
|
||||
mayor = game->get_player_name(e.mayor);
|
||||
mayor = game->get_player_name(e.mayor, true);
|
||||
cityMayorWidget->SetText(mayor.c_str());
|
||||
cityLevelNameWidget->SetText(level_name);
|
||||
cityLevelWidget->SetText(std::to_string(level).c_str());
|
||||
|
@ -35,7 +35,7 @@ UIItemsDialog::OwnershipWidget::OwnershipWidget(UIItemsDialog::OwnershipItem *it
|
||||
g_widgets_reader->LoadFile(GetContentRoot(), "cc/player-info-ownership-row.tb.txt");
|
||||
|
||||
TBTextField *name = GetWidgetByIDAndType<TBTextField>(TBIDC("name"));
|
||||
name->SetText(item->game->get_player_name(item->account).c_str());
|
||||
name->SetText(item->game->get_player_name(item->account, true).c_str());
|
||||
TBTextField *amount = GetWidgetByIDAndType<TBTextField>(TBIDC("amount"));
|
||||
amount->SetText(std::to_string(item->amount).c_str());
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ UIMessagesDialog::MessageWidget::MessageWidget(UIMessagesDialog::MessageItem *it
|
||||
const cc::cc_message_t &message = item->message;
|
||||
|
||||
TBTextField *tf = GetWidgetByIDAndType<TBTextField>(TBIDC("from"));
|
||||
tf->SetText(message.sender == 0 ? "<unknown>" : item->dialog->game->get_player_name(message.sender).c_str());
|
||||
tf->SetText(message.sender == 0 ? "<unknown>" : item->dialog->game->get_player_name(message.sender, true).c_str());
|
||||
|
||||
tf = GetWidgetByIDAndType<TBTextField>(TBIDC("subject"));
|
||||
std::string subject = (message.reply ? "Re: " : "") + message.subject;
|
||||
@ -88,7 +88,7 @@ bool UIMessagesDialog::MessageSource::Filter(int index, const TBStr &filter)
|
||||
return true;
|
||||
if (stristr(message.message.c_str(), filter.CStr()))
|
||||
return true;
|
||||
if (message.sender && stristr(item->dialog->game->get_player_name(message.sender).c_str(), filter.CStr()))
|
||||
if (message.sender && stristr(item->dialog->game->get_player_name(message.sender, true).c_str(), filter.CStr()))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
@ -71,7 +71,7 @@ void UINewAccountDialog::FillData(const GameState *game)
|
||||
if (is_treasury)
|
||||
continue;
|
||||
|
||||
const std::string player_name = game->get_player_name(e.first);
|
||||
const std::string player_name = game->get_player_name(e.first, true);
|
||||
TBGenericStringItem *item = new TBGenericStringItem(player_name);
|
||||
item->tag.SetInt(e.first);
|
||||
builder.AddItem(item);
|
||||
|
@ -106,7 +106,7 @@ void UINewMessageDialog::UpdateRequirements()
|
||||
|
||||
void UINewMessageDialog::HandleSelectRecipient(StringHash eventType, VariantMap& eventData)
|
||||
{
|
||||
selectAccountDialog = new UISelectAccountDialog(context_, game, [this](uint32_t id, const std::string &name, bool ignore, bool autonomous) {
|
||||
selectAccountDialog = new UISelectAccountDialog(context_, game, false, [this](uint32_t id, const std::string &name, bool ignore, bool autonomous) {
|
||||
if (id == GAME_ACCOUNT)
|
||||
return false;
|
||||
if (id == game->playerState.id)
|
||||
@ -203,8 +203,8 @@ void UINewMessageDialog::HandleSend(StringHash eventType, VariantMap& eventData)
|
||||
for (const auto &e: game->player_names)
|
||||
{
|
||||
const uint32_t id = e.first;
|
||||
const bool ignore = std::get<1>(e.second);
|
||||
const bool autonomous = std::get<2>(e.second);
|
||||
const bool ignore = std::get<2>(e.second);
|
||||
const bool autonomous = std::get<3>(e.second);
|
||||
if (id == GAME_ACCOUNT || id == game->playerState.id || ignore || autonomous)
|
||||
continue;
|
||||
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "cc/cc_discoveries.h"
|
||||
#include "cc/cc_collectible_coin.h"
|
||||
#include "cc/cc_calendar.h"
|
||||
#include "cc/cc_title.h"
|
||||
#include "wallet/wallet2.h"
|
||||
#include "game/game-state.h"
|
||||
#include "game/game-wallet.h"
|
||||
@ -47,6 +48,7 @@
|
||||
#include "ui-mint.h"
|
||||
#include "ui-smelt.h"
|
||||
#include "ui-new-message.h"
|
||||
#include "ui-change-title.h"
|
||||
#include "ui-tb-message-box.h"
|
||||
#include "caching-source-builder.h"
|
||||
#include "coin-icon.h"
|
||||
@ -215,6 +217,7 @@ static std::string get_extra_command_info(const cryptonote::cc_command_t &cmd)
|
||||
std::string operator()(const cryptonote::cc_command_service_t &cmd) const { return ""; }
|
||||
std::string operator()(const cryptonote::cc_command_set_merchant_ship_items_t &cmd) const { return ""; }
|
||||
std::string operator()(const cryptonote::cc_command_set_script_variables_t &cmd) const { return ""; }
|
||||
std::string operator()(const cryptonote::cc_command_set_title_t &cmd) const { return ""; }
|
||||
std::string operator()(const cryptonote::cc_command_add_tax_break_zone_t &cmd) const { return ""; }
|
||||
std::string operator()(const cryptonote::cc_command_smelt_t &cmd) const { return ""; }
|
||||
std::string operator()(const cryptonote::cc_command_sow_t &cmd) const { return ""; }
|
||||
@ -1294,7 +1297,7 @@ UIPlayerInfoDialog::OwnershipWidget::OwnershipWidget(UIPlayerInfoDialog::Ownersh
|
||||
g_widgets_reader->LoadFile(GetContentRoot(), "cc/player-info-ownership-row.tb.txt");
|
||||
|
||||
TBTextField *name = GetWidgetByIDAndType<TBTextField>(TBIDC("name"));
|
||||
name->SetText(item->game->get_player_name(item->account).c_str());
|
||||
name->SetText(item->game->get_player_name(item->account, true).c_str());
|
||||
TBTextField *amount = GetWidgetByIDAndType<TBTextField>(TBIDC("amount"));
|
||||
amount->SetText(std::to_string(item->amount).c_str());
|
||||
}
|
||||
@ -1454,6 +1457,7 @@ UIPlayerInfoDialog::UIPlayerInfoDialog(Context *ctx, const GameState *game, uint
|
||||
mintDialog(nullptr),
|
||||
smeltDialog(nullptr),
|
||||
selectItemsDialog(nullptr),
|
||||
changeTitleDialog(nullptr),
|
||||
tooltip(nullptr),
|
||||
tooltip_target(nullptr),
|
||||
level(0),
|
||||
@ -1471,6 +1475,7 @@ UIPlayerInfoDialog::UIPlayerInfoDialog(Context *ctx, const GameState *game, uint
|
||||
{
|
||||
tabContainerWidget = GetWidgetByIDAndType<TBTabContainer>(TBIDC("tab-container"));
|
||||
balanceWidget = GetWidgetByIDAndType<TBTextField>(TBIDC("balance"));
|
||||
titleWidget = GetWidgetByIDAndType<TBTextField>(TBIDC("title"));
|
||||
nameWidget = GetWidgetByIDAndType<TBTextField>(TBIDC("name"));
|
||||
levelWidget = GetWidgetByIDAndType<TBTextField>(TBIDC("level"));
|
||||
mainPrestigeWidget = GetWidgetByIDAndType<TBTextField>(TBIDC("prestige-main"));
|
||||
@ -1592,6 +1597,10 @@ UIPlayerInfoDialog::UIPlayerInfoDialog(Context *ctx, const GameState *game, uint
|
||||
ownershipContainer->SetValue(0);
|
||||
viewOwnershipContainer->SetValue(0);
|
||||
|
||||
tb::TBFontDescription fd = g_font_manager->GetDefaultFontDescription();
|
||||
fd.SetSize(fd.GetSize() * 2);
|
||||
titleWidget->SetFontDescription(fd);
|
||||
|
||||
const TBRect rect = rareFishList->GetParent()->GetRect();
|
||||
const int w = rect.w * 30 / 100;
|
||||
LayoutParams lp;
|
||||
@ -1688,7 +1697,7 @@ void UIPlayerInfoDialog::UpdateRareFishData(const std::shared_ptr<GameWallet> &w
|
||||
|
||||
void UIPlayerInfoDialog::FillData(const std::shared_ptr<GameWallet> &w, uint32_t player_id)
|
||||
{
|
||||
std::string description, pmspk, pmvpk;
|
||||
std::string description, pmspk, pmvpk, player_title;
|
||||
std::vector<uint32_t> flags;
|
||||
std::map<uint32_t, std::pair<uint8_t, uint64_t>> badges;
|
||||
std::map<uint32_t, uint32_t> attributes;
|
||||
@ -1699,7 +1708,8 @@ void UIPlayerInfoDialog::FillData(const std::shared_ptr<GameWallet> &w, uint32_t
|
||||
item_balances.clear();
|
||||
std::vector<uint32_t> textures_created, textures_licenced;
|
||||
std::map<uint32_t, std::pair<uint32_t, std::map<std::string, uint64_t>>> background_script_states;
|
||||
if (!w->get_cc_account_data(player_id, public_key, balance, item_balances, flags, badges, attributes, player_name, description, ignore, inviting_account, num_invited, first_flag, script, script_state, script_city, script_owner, reserve, script_variables, script_local_variables, background_script_states, prestige, textures_created, textures_licenced, pmspk, pmvpk))
|
||||
int32_t title_adjective, title_noun, title_origin, title_unique;
|
||||
if (!w->get_cc_account_data(player_id, public_key, balance, item_balances, flags, badges, attributes, player_name, title_adjective, title_noun, title_origin, title_unique, player_title, description, ignore, inviting_account, num_invited, first_flag, script, script_state, script_city, script_owner, reserve, script_variables, script_local_variables, background_script_states, prestige, textures_created, textures_licenced, pmspk, pmvpk))
|
||||
return;
|
||||
|
||||
CancelTooltip();
|
||||
@ -1724,6 +1734,10 @@ void UIPlayerInfoDialog::FillData(const std::shared_ptr<GameWallet> &w, uint32_t
|
||||
for (int i = 1; i <= 5; ++i)
|
||||
numBadgesWidget[i - 1]->SetText(std::to_string(badge_count[i - 1]).c_str());
|
||||
|
||||
std::string name_and_title = player_name;
|
||||
if (!player_title.empty())
|
||||
name_and_title += " " + player_title;
|
||||
titleWidget->SetText(name_and_title.c_str());
|
||||
nameWidget->SetText(player_name.c_str());
|
||||
if (!game->ignore_player(player_id))
|
||||
playerProfileWidget->SetText(description.c_str());
|
||||
@ -2656,6 +2670,8 @@ void UIPlayerInfoDialog::Update(const std::shared_ptr<GameWallet> &w)
|
||||
savePlayerProfileWidget->SetState(WIDGET_STATE_DISABLED, true);
|
||||
savePlayerProfileWidget->SetVisibility(can_edit ? WIDGET_VISIBILITY_VISIBLE : WIDGET_VISIBILITY_INVISIBLE);
|
||||
}
|
||||
titleWidget->SetSkinBg(game->playerState.id == player_id ? TBIDC("title-link") : TBIDC("TBTextField"));
|
||||
titleWidget->SetUnderline(game->playerState.id == player_id);
|
||||
last_refresh_stop_hash = game->top_hash;
|
||||
}
|
||||
|
||||
@ -2671,6 +2687,8 @@ void UIPlayerInfoDialog::Update(const std::shared_ptr<GameWallet> &w)
|
||||
smeltDialog->Update(w);
|
||||
if (selectItemsDialog)
|
||||
selectItemsDialog->Update(w);
|
||||
if (changeTitleDialog)
|
||||
changeTitleDialog->Update(w);
|
||||
|
||||
giveGoldWidget->SetVisibility(game->playerState.id == player_id ? WIDGET_VISIBILITY_INVISIBLE : WIDGET_VISIBILITY_VISIBLE);
|
||||
giveItemsWidget->SetVisibility(game->playerState.id == player_id ? WIDGET_VISIBILITY_INVISIBLE : WIDGET_VISIBILITY_VISIBLE);
|
||||
@ -3313,7 +3331,7 @@ void UIPlayerInfoDialog::HandleRareFishChanged(StringHash eventType, VariantMap&
|
||||
imageWidget->SetLayoutParams(lp);
|
||||
imageWidget->SetVisibility(WIDGET_VISIBILITY_VISIBLE);
|
||||
|
||||
const std::string discoverer_name = game->get_player_name(rare_fish_data[item->fish].first);
|
||||
const std::string discoverer_name = game->get_player_name(rare_fish_data[item->fish].first, true);
|
||||
std::string s = std::string("The ") + rfd->name + " was discovered by " + discoverer_name;
|
||||
std::vector<std::string> waters;
|
||||
if (rfd->close_waters)
|
||||
@ -3350,6 +3368,21 @@ void UIPlayerInfoDialog::HandleCurrentCityOnlyChanged(StringHash eventType, Vari
|
||||
last_refresh_stop_hash = "";
|
||||
}
|
||||
|
||||
void UIPlayerInfoDialog::HandleChangeTitle(StringHash eventType, VariantMap& eventData)
|
||||
{
|
||||
if (player_id != game->playerState.id)
|
||||
return;
|
||||
|
||||
if (changeTitleDialog)
|
||||
{
|
||||
new MessageBox(context_, "Dialog is already active");
|
||||
return;
|
||||
}
|
||||
changeTitleDialog = new UIChangeTitleDialog(context_, game);
|
||||
SubscribeToEvent(changeTitleDialog, E_CHANGE_TITLE_OKAYED, [this](StringHash eventType, VariantMap &eventData){ SendEvent(eventType, eventData); changeTitleDialog = NULL; });
|
||||
SubscribeToEvent(changeTitleDialog, E_CHANGE_TITLE_CANCELLED, [this](StringHash eventType, VariantMap &eventData){ changeTitleDialog = NULL; });
|
||||
}
|
||||
|
||||
void UIPlayerInfoDialog::HandleTBMessage(StringHash eventType, VariantMap& eventData)
|
||||
{
|
||||
#define CONNECT(name, function) do { if (target.Get() && target.Get()->GetID() == TBIDC(name)) function(eventType, eventData); } while(0)
|
||||
@ -3378,6 +3411,7 @@ void UIPlayerInfoDialog::HandleTBMessage(StringHash eventType, VariantMap& event
|
||||
CONNECT("export-history", HandleExportHistory);
|
||||
CONNECT("view-owners", HandleViewOwners);
|
||||
CONNECT("view-history-details", HandleViewHistoryDetails);
|
||||
CONNECT("title", HandleChangeTitle);
|
||||
|
||||
HeaderButton *hb = target.Get() ? TBSafeCast<HeaderButton>(target.Get()) : NULL;
|
||||
if (hb)
|
||||
|
@ -44,6 +44,7 @@ class BadgeWidget;
|
||||
class UITradeDialog;
|
||||
class UIMintDialog;
|
||||
class UISmeltDialog;
|
||||
class UIChangeTitleDialog;
|
||||
|
||||
URHO3D_EVENT(E_PLAYER_INFO_CLOSED, PlayerInfoClosed) {}
|
||||
URHO3D_EVENT(E_PLAYER_INFO_FLAG_SELECTED, PlayerInfoFlagSelected) { URHO3D_PARAM(P_FLAG, Flag); }
|
||||
@ -111,6 +112,7 @@ private:
|
||||
void HandleViewHistoryDetails(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData);
|
||||
void HandleRareFishChanged(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData);
|
||||
void HandleCurrentCityOnlyChanged(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData);
|
||||
void HandleChangeTitle(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData);
|
||||
|
||||
void InitColumnsList();
|
||||
void HideRareFishInfo();
|
||||
@ -420,6 +422,7 @@ private:
|
||||
const GameState *game;
|
||||
tb::TBTabContainer *tabContainerWidget;
|
||||
tb::TBTextField *balanceWidget;
|
||||
tb::TBTextField *titleWidget;
|
||||
tb::TBTextField *nameWidget;
|
||||
tb::TBTextField *levelWidget;
|
||||
tb::TBTextField *mainPrestigeWidget;
|
||||
@ -451,6 +454,7 @@ private:
|
||||
tb::TBToggleContainer *ownershipContainer;
|
||||
tb::TBToggleContainer *viewOwnershipContainer;
|
||||
tb::TBSelectList *ownershipWidget;
|
||||
tb::TBButton *changeTitleButton;
|
||||
|
||||
uint32_t player_id;
|
||||
std::string last_refresh_stop_hash;
|
||||
@ -470,6 +474,7 @@ private:
|
||||
UIMintDialog *mintDialog;
|
||||
UISmeltDialog *smeltDialog;
|
||||
UISelectItemsDialog *selectItemsDialog;
|
||||
UIChangeTitleDialog *changeTitleDialog;
|
||||
|
||||
UITooltip *tooltip;
|
||||
TooltipWidget *tooltip_target;
|
||||
|
@ -65,7 +65,7 @@ UIResearchDialog::DiscoveryWidget::DiscoveryWidget(UIResearchDialog::DiscoveryIt
|
||||
if (boost::ends_with(years, ".0"))
|
||||
years[strlen(years) - 2] = 0;
|
||||
const std::string days = std::to_string(discovery_age / (86400 / DIFFICULTY_TARGET_V2));
|
||||
status = "Discovered " + std::string(years) + " in-game years (" + days + " days) ago by " + item->dialog->game->get_player_name(d.discoverer);
|
||||
status = "Discovered " + std::string(years) + " in-game years (" + days + " days) ago by " + item->dialog->game->get_player_name(d.discoverer, true);
|
||||
color = TBColor(128, 230, 204, 255);
|
||||
}
|
||||
break;
|
||||
|
@ -15,14 +15,14 @@
|
||||
using namespace Urho3D;
|
||||
using namespace tb;
|
||||
|
||||
UISelectAccountDialog::UISelectAccountDialog(Context *ctx, const GameState *game, const std::function<bool(uint32_t, const std::string&, bool, bool)> &filter):
|
||||
UISelectAccountDialog::UISelectAccountDialog(Context *ctx, const GameState *game, bool with_title, const std::function<bool(uint32_t, const std::string&, bool, bool)> &filter):
|
||||
UITBWindow(ctx, "cc/select-account.tb.txt")
|
||||
{
|
||||
accountsWidget = GetWidgetByIDAndType<TBSelectList>(TBIDC("accounts"));
|
||||
filterWidget = GetWidgetByIDAndType<TBEditField>(TBIDC("filter"));
|
||||
|
||||
accountsWidget->SetSource(&account_source);
|
||||
FillData(game, filter);
|
||||
FillData(game, with_title, filter);
|
||||
|
||||
SubscribeToEvent(this, E_TB_WIDGET_EVENT, URHO3D_HANDLER(UISelectAccountDialog, HandleTBMessage));
|
||||
SubscribeToEvent(this, E_TB_WINDOW_CLOSED, URHO3D_HANDLER(UISelectAccountDialog, HandleClose));
|
||||
@ -37,13 +37,13 @@ void UISelectAccountDialog::Update(const GameState *gameState)
|
||||
{
|
||||
}
|
||||
|
||||
void UISelectAccountDialog::FillData(const GameState *game, const std::function<bool(uint32_t, const std::string&, bool, bool)> &filter)
|
||||
void UISelectAccountDialog::FillData(const GameState *game, bool with_title, const std::function<bool(uint32_t, const std::string&, bool, bool)> &filter)
|
||||
{
|
||||
CachingSourceBuilder<TBGenericStringItem> builder(account_source);
|
||||
|
||||
for (const auto &e: game->player_names)
|
||||
{
|
||||
const std::string player_name = game->get_player_name(e.first);
|
||||
const std::string player_name = game->get_player_name(e.first, with_title);
|
||||
if (filter && !filter(e.first, player_name, game->ignore_player(e.first), game->is_autonomous_player(e.first)))
|
||||
continue;
|
||||
TBGenericStringItem *item = new TBGenericStringItem(player_name);
|
||||
|
@ -27,7 +27,7 @@ URHO3D_EVENT(E_SELECT_ACCOUNT_CANCELLED, SelectAccountCancelled) {}
|
||||
class UISelectAccountDialog: public UITBWindow
|
||||
{
|
||||
public:
|
||||
UISelectAccountDialog(Urho3D::Context *ctx, const GameState *game, const std::function<bool(uint32_t, const std::string&, bool, bool)> &filter = NULL);
|
||||
UISelectAccountDialog(Urho3D::Context *ctx, const GameState *game, bool with_title = true, const std::function<bool(uint32_t, const std::string&, bool, bool)> &filter = NULL);
|
||||
virtual ~UISelectAccountDialog() override;
|
||||
|
||||
void Update(const GameState *gameState);
|
||||
@ -40,7 +40,7 @@ private:
|
||||
void HandleClose(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData);
|
||||
void HandleFilterChanged(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData);
|
||||
|
||||
void FillData(const GameState *game, const std::function<bool(uint32_t, const std::string&, bool, bool)> &filter);
|
||||
void FillData(const GameState *game, bool with_title, const std::function<bool(uint32_t, const std::string&, bool, bool)> &filter);
|
||||
|
||||
private:
|
||||
tb::TBSelectList *accountsWidget;
|
||||
|
@ -346,7 +346,7 @@ std::pair<std::string, crypto::hash> UITradeDialog::GetFlagDetails(const std::sh
|
||||
}
|
||||
ss << boost::format("%ux%u %s land in %s\n")
|
||||
% (flag->x1 - flag->x0 + 1) % (flag->y1 - flag->y0 + 1) % cc::get_role_name(flag->role) % game->get_city_name(flag->city);
|
||||
ss << "Owner: " << game->get_player_name(flag->owner) << "\n";
|
||||
ss << "Owner: " << game->get_player_name(flag->owner, true) << "\n";
|
||||
ss << "Repair: " << cc::print_repair_percentage(flag->repair) << "\n";
|
||||
return std::make_pair(ss.str(), crypto::null_hash);
|
||||
}
|
||||
@ -364,7 +364,7 @@ std::pair<std::string, crypto::hash> UITradeDialog::GetCityDetails(const std::sh
|
||||
{
|
||||
if (e.city_id == id)
|
||||
{
|
||||
ss << "Mayor: " << game->get_player_name(e.mayor) << "\n";
|
||||
ss << "Mayor: " << game->get_player_name(e.mayor, true) << "\n";
|
||||
ss << "Treasury: " << game_util::print_money(e.treasury_balance) << "\n";
|
||||
ss << "Level: " << cc::get_town_level_name(e.level);
|
||||
found = true;
|
||||
|
@ -41,7 +41,7 @@ UITravelToCityDialog::CityWidget::CityWidget(CityItem *item, CitySource *source,
|
||||
levelWidget->SetText(cc::get_town_level_name(item->city.level));
|
||||
|
||||
TBTextField *mayorWidget = GetWidgetByIDAndType<TBTextField>(TBIDC("mayor"));
|
||||
mayorWidget->SetText(item->dialog->game->get_player_name(item->city.mayor));
|
||||
mayorWidget->SetText(item->dialog->game->get_player_name(item->city.mayor, true));
|
||||
|
||||
std::vector<std::string> special_event_names;
|
||||
for (uint32_t special_event: item->city.special_events)
|
||||
|
@ -113,6 +113,7 @@
|
||||
#include "ui-messages.h"
|
||||
#include "ui-encyclopedia.h"
|
||||
#include "ui-select-account.h"
|
||||
#include "ui-change-title.h"
|
||||
#include "ui-urho3d.h"
|
||||
|
||||
#define WALLET_BALANCE_TEXT_SCALE .8f
|
||||
@ -3012,7 +3013,7 @@ void UIUrho3D::HandleShowOnlinePlayers(Urho3D::StringHash eventType, Urho3D::Var
|
||||
return;
|
||||
}
|
||||
|
||||
showOnlinePlayersDialog = new UISelectAccountDialog(context_, gameState, [this, &players](uint32_t id, const std::string &name, bool ignore, bool autonomous) {
|
||||
showOnlinePlayersDialog = new UISelectAccountDialog(context_, gameState, true, [this, &players](uint32_t id, const std::string &name, bool ignore, bool autonomous) {
|
||||
if (autonomous)
|
||||
return false;
|
||||
if (id == gameState->playerState.id)
|
||||
@ -4443,6 +4444,9 @@ void UIUrho3D::ShowPlayerInfo(uint32_t player_id)
|
||||
SubscribeToEvent(playerInfoDialog, E_CRYPTOCITY_SEND_MESSAGE, [this](StringHash eventType, VariantMap& eventData) {
|
||||
SendEvent(E_CRYPTOCITY_SEND_MESSAGE, eventData);
|
||||
});
|
||||
SubscribeToEvent(playerInfoDialog, E_CHANGE_TITLE_OKAYED, [this](StringHash eventType, VariantMap& eventData) {
|
||||
SendEvent(E_CRYPTOCITY_CHANGE_TITLE, eventData);
|
||||
});
|
||||
if (player_id == 0)
|
||||
playerInfoDialog->SelectAccount();
|
||||
SendTutorialTrigger("screen-player-info");
|
||||
|
@ -297,6 +297,7 @@ URHO3D_EVENT(E_CRYPTOCITY_RTAS, RTAS) { URHO3D_PARAM(P_ENABLE, Enable); URHO3D_P
|
||||
URHO3D_EVENT(E_CRYPTOCITY_MESSAGES_READ, MessagesRead) { }
|
||||
URHO3D_EVENT(E_CRYPTOCITY_GET_ONLINE_PLAYERS, GetOnlinePlayers) { URHO3D_PARAM(P_ENABLED, Enabled); URHO3D_PARAM(P_PLAYERS, Players); }
|
||||
URHO3D_EVENT(E_CRYPTOCITY_START_NEW_EPOCH, StartNewEpoch) { URHO3D_PARAM(P_NAME, Name); }
|
||||
URHO3D_EVENT(E_CRYPTOCITY_CHANGE_TITLE, ChangeTitle) { URHO3D_PARAM(P_ADJECTIVE, Adjective); URHO3D_PARAM(P_NOUN, Noun); URHO3D_PARAM(P_ORIGIN, Origin); URHO3D_PARAM(P_UNIQUE, Unique); }
|
||||
|
||||
class UIUrho3D: public Urho3D::UIElement
|
||||
{
|
||||
|
@ -81,6 +81,7 @@ using namespace epee;
|
||||
#include "cc/cc_merchant_ship.h"
|
||||
#include "cc/cc_city_specialization.h"
|
||||
#include "cc/cc_epoch.h"
|
||||
#include "cc/cc_title.h"
|
||||
#include "version.h"
|
||||
|
||||
#undef MONERO_DEFAULT_LOG_CATEGORY
|
||||
@ -4017,6 +4018,7 @@ namespace cryptonote
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
bool core_rpc_server::on_cc_get_account(const COMMAND_RPC_CC_GET_ACCOUNT::request& req, COMMAND_RPC_CC_GET_ACCOUNT::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)
|
||||
{
|
||||
BlockchainDB &db = m_core.get_blockchain_storage().get_db();
|
||||
try
|
||||
{
|
||||
cryptonote::cc_account_data_t data;
|
||||
@ -4029,7 +4031,7 @@ namespace cryptonote
|
||||
error_resp.message = "Invalid hex data";
|
||||
return false;
|
||||
}
|
||||
if (!m_core.get_blockchain_storage().get_db().get_as_cc_account(bd, data))
|
||||
if (!db.get_as_cc_account(bd, data))
|
||||
{
|
||||
error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR;
|
||||
error_resp.message = "Account could not be parsed";
|
||||
@ -4038,7 +4040,7 @@ namespace cryptonote
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!m_core.get_blockchain_storage().get_db().get_cc_account_data(req.id, data))
|
||||
if (!db.get_cc_account_data(req.id, data))
|
||||
{
|
||||
error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR;
|
||||
error_resp.message = "Account not found";
|
||||
@ -4047,6 +4049,11 @@ namespace cryptonote
|
||||
}
|
||||
res.balance = data.balance;
|
||||
res.name = std::move(data.name);
|
||||
res.title_adjective = data.title_adjective;
|
||||
res.title_noun = data.title_noun;
|
||||
res.title_origin = data.title_origin;
|
||||
res.title_unique = data.title_unique;
|
||||
res.title = std::move(data.title);
|
||||
res.description = std::move(data.description);
|
||||
res.ignore = data.ignore;
|
||||
res.moose_killed = data.moose_killed;
|
||||
@ -4098,6 +4105,7 @@ namespace cryptonote
|
||||
}
|
||||
res.textures_created = std::move(data.textures_created);
|
||||
res.textures_licenced = std::move(data.textures_licenced);
|
||||
res.unique_titles = std::move(data.unique_titles);
|
||||
|
||||
for (const auto &e: data.reserve)
|
||||
{
|
||||
@ -4508,7 +4516,7 @@ namespace cryptonote
|
||||
weekly_level_increase = new_level - old_level;
|
||||
}
|
||||
const bool autonomous = data.public_key == crypto::null_pkey;
|
||||
snapshot.player_data.push_back({account_id, std::move(data.name), data.ignore, autonomous, std::move(badges), weekly_level_increase, data.prestige, data.balance});
|
||||
snapshot.player_data.push_back({account_id, std::move(data.name), std::move(data.title), data.ignore, autonomous, std::move(badges), weekly_level_increase, data.prestige, data.balance});
|
||||
--n_accounts;
|
||||
}
|
||||
++account_id;
|
||||
@ -5226,7 +5234,7 @@ namespace cryptonote
|
||||
if (req.id.empty())
|
||||
{
|
||||
if (!db.for_all_cc_event_badges([&res](const cc::cc_badge_data_t &bd) {
|
||||
res.badges.push_back({bd.id, bd.name, bd.desc, bd.icon, bd.manual, {}});
|
||||
res.badges.push_back({bd.id, bd.name, bd.desc, bd.icon, bd.manual, bd.title_adjective, bd.title_noun, {}});
|
||||
if (bd.thresholds.size() != 0 && bd.thresholds.size() != NUM_BADGE_LEVELS)
|
||||
return false;
|
||||
if (!bd.thresholds.empty())
|
||||
@ -5247,7 +5255,7 @@ namespace cryptonote
|
||||
cc::cc_badge_data_t data;
|
||||
if (!cc::get_badge_data(&db, (cc::cc_badge_t)id, data))
|
||||
return false;
|
||||
res.badges.push_back({id, std::move(data.name), std::move(data.desc), std::move(data.icon), data.manual, {}});
|
||||
res.badges.push_back({id, std::move(data.name), std::move(data.desc), std::move(data.icon), data.manual, std::move(data.title_adjective), std::move(data.title_noun), {}});
|
||||
if (data.thresholds.size() != 0 && data.thresholds.size() != NUM_BADGE_LEVELS)
|
||||
return false;
|
||||
if (!data.thresholds.empty())
|
||||
@ -7050,6 +7058,40 @@ done:
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
bool core_rpc_server::on_cc_get_available_title_components(const COMMAND_RPC_CC_GET_AVAILABLE_TITLE_COMPONENTS::request& req, COMMAND_RPC_CC_GET_AVAILABLE_TITLE_COMPONENTS::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)
|
||||
{
|
||||
PERF_TIMER(on_cc_get_available_title_components);
|
||||
|
||||
BlockchainDB &db = m_core.get_blockchain_storage().get_db();
|
||||
try
|
||||
{
|
||||
std::vector<std::pair<uint32_t, std::string>> adjectives, nouns, origins, uniques;
|
||||
cc::get_available_title_components(db, req.account, adjectives, nouns, origins, uniques);
|
||||
|
||||
res.adjectives.reserve(adjectives.size());
|
||||
for (auto &e: adjectives)
|
||||
res.adjectives.push_back({e.first, e.second});
|
||||
res.nouns.reserve(nouns.size());
|
||||
for (auto &e: nouns)
|
||||
res.nouns.push_back({e.first, e.second});
|
||||
res.origins.reserve(origins.size());
|
||||
for (auto &e: origins)
|
||||
res.origins.push_back({e.first, e.second});
|
||||
res.uniques.reserve(uniques.size());
|
||||
for (auto &e: uniques)
|
||||
res.uniques.push_back({e.first, e.second});
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR;
|
||||
error_resp.message = "Error getting available title components";
|
||||
return false;
|
||||
}
|
||||
|
||||
res.status = CORE_RPC_STATUS_OK;
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
const command_line::arg_descriptor<std::string, false, true, 2> core_rpc_server::arg_rpc_bind_port = {
|
||||
"rpc-bind-port"
|
||||
, "Port for RPC server"
|
||||
|
@ -257,6 +257,7 @@ namespace cryptonote
|
||||
MAP_JON_RPC_WE("cc_get_building_cost", on_cc_get_building_cost, COMMAND_RPC_CC_GET_BUILDING_COST)
|
||||
MAP_JON_RPC_WE("cc_get_item_creation_fee", on_cc_get_item_creation_fee, COMMAND_RPC_CC_GET_ITEM_CREATION_FEE)
|
||||
MAP_JON_RPC_WE("cc_get_epochs", on_cc_get_epochs, COMMAND_RPC_CC_GET_EPOCHS)
|
||||
MAP_JON_RPC_WE("cc_get_available_title_components", on_cc_get_available_title_components, COMMAND_RPC_CC_GET_AVAILABLE_TITLE_COMPONENTS)
|
||||
END_JSON_RPC_MAP()
|
||||
END_URI_MAP2()
|
||||
|
||||
@ -403,6 +404,7 @@ namespace cryptonote
|
||||
bool on_cc_get_building_cost(const COMMAND_RPC_CC_GET_BUILDING_COST::request& req, COMMAND_RPC_CC_GET_BUILDING_COST::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL);
|
||||
bool on_cc_get_item_creation_fee(const COMMAND_RPC_CC_GET_ITEM_CREATION_FEE::request& req, COMMAND_RPC_CC_GET_ITEM_CREATION_FEE::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL);
|
||||
bool on_cc_get_epochs(const COMMAND_RPC_CC_GET_EPOCHS::request& req, COMMAND_RPC_CC_GET_EPOCHS::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL);
|
||||
bool on_cc_get_available_title_components(const COMMAND_RPC_CC_GET_AVAILABLE_TITLE_COMPONENTS::request& req, COMMAND_RPC_CC_GET_AVAILABLE_TITLE_COMPONENTS::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL);
|
||||
//-----------------------
|
||||
|
||||
private:
|
||||
|
@ -3092,6 +3092,11 @@ namespace cryptonote
|
||||
std::vector<badge_t> badges;
|
||||
std::vector<attribute_t> attributes;
|
||||
std::string name;
|
||||
int32_t title_adjective;
|
||||
int32_t title_noun;
|
||||
int32_t title_origin;
|
||||
int32_t title_unique;
|
||||
std::string title;
|
||||
std::string description;
|
||||
bool ignore;
|
||||
uint32_t moose_killed;
|
||||
@ -3121,6 +3126,7 @@ namespace cryptonote
|
||||
std::vector<background_script_state_t> background_script_states;
|
||||
std::vector<uint32_t> textures_created;
|
||||
std::vector<uint32_t> textures_licenced;
|
||||
std::vector<std::string> unique_titles;
|
||||
std::string status;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
@ -3134,6 +3140,11 @@ namespace cryptonote
|
||||
KV_SERIALIZE(badges)
|
||||
KV_SERIALIZE(attributes)
|
||||
KV_SERIALIZE(name)
|
||||
KV_SERIALIZE(title_adjective)
|
||||
KV_SERIALIZE(title_noun)
|
||||
KV_SERIALIZE(title_origin)
|
||||
KV_SERIALIZE(title_unique)
|
||||
KV_SERIALIZE(title)
|
||||
KV_SERIALIZE(description)
|
||||
KV_SERIALIZE(ignore)
|
||||
KV_SERIALIZE(moose_killed)
|
||||
@ -3163,6 +3174,7 @@ namespace cryptonote
|
||||
KV_SERIALIZE(background_script_states)
|
||||
KV_SERIALIZE(textures_created)
|
||||
KV_SERIALIZE(textures_licenced)
|
||||
KV_SERIALIZE(unique_titles)
|
||||
KV_SERIALIZE(status)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
@ -4261,6 +4273,8 @@ namespace cryptonote
|
||||
std::string description;
|
||||
std::string icon;
|
||||
bool manual;
|
||||
std::string title_adjective;
|
||||
std::string title_noun;
|
||||
std::vector<badge_threshold_t> thresholds;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
@ -4269,6 +4283,8 @@ namespace cryptonote
|
||||
KV_SERIALIZE(description)
|
||||
KV_SERIALIZE(icon)
|
||||
KV_SERIALIZE(manual)
|
||||
KV_SERIALIZE(title_adjective)
|
||||
KV_SERIALIZE(title_noun)
|
||||
KV_SERIALIZE(thresholds)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
@ -6274,4 +6290,48 @@ namespace cryptonote
|
||||
typedef epee::misc_utils::struct_init<response_t> response;
|
||||
};
|
||||
|
||||
struct COMMAND_RPC_CC_GET_AVAILABLE_TITLE_COMPONENTS
|
||||
{
|
||||
struct request_t
|
||||
{
|
||||
uint32_t account;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(account)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
typedef epee::misc_utils::struct_init<request_t> request;
|
||||
|
||||
struct component_t
|
||||
{
|
||||
uint32_t id;
|
||||
std::string string;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(id)
|
||||
KV_SERIALIZE(string)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
struct response_t
|
||||
{
|
||||
std::vector<component_t> adjectives;
|
||||
std::vector<component_t> nouns;
|
||||
std::vector<component_t> origins;
|
||||
std::vector<component_t> uniques;
|
||||
std::string status;
|
||||
bool untrusted;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(adjectives)
|
||||
KV_SERIALIZE(nouns)
|
||||
KV_SERIALIZE(origins)
|
||||
KV_SERIALIZE(uniques)
|
||||
KV_SERIALIZE(status)
|
||||
KV_SERIALIZE(untrusted)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
typedef epee::misc_utils::struct_init<response_t> response;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -2964,7 +2964,7 @@ bool simple_wallet::cc_status(const std::vector<std::string> &args_)
|
||||
std::vector<uint32_t> flags;
|
||||
std::map<uint32_t, std::pair<uint8_t, uint64_t>> badges;
|
||||
std::map<uint32_t, uint32_t> attributes;
|
||||
std::string name, description;
|
||||
std::string name, description, title;
|
||||
std::string public_key, pmspk, pmvpk;
|
||||
bool ignore;
|
||||
uint32_t inviting_account, num_invited, first_flag;
|
||||
@ -2974,7 +2974,8 @@ bool simple_wallet::cc_status(const std::vector<std::string> &args_)
|
||||
std::map<uint32_t, std::pair<uint32_t, std::map<std::string, uint64_t>>> background_script_states;
|
||||
uint32_t prestige;
|
||||
std::vector<uint32_t> textures_created, textures_licenced;
|
||||
m_wallet->get_cc_account_data(id, public_key, balance, item_balances, flags, badges, attributes, name, description, ignore, inviting_account, num_invited, first_flag, script, script_state, script_city, script_owner, reserve, script_variables, script_local_variables, background_script_states, prestige, textures_created, textures_licenced, pmspk, pmvpk);
|
||||
int32_t title_adjective, title_noun, title_origin, title_unique;
|
||||
m_wallet->get_cc_account_data(id, public_key, balance, item_balances, flags, badges, attributes, name, title_adjective, title_noun, title_origin, title_unique, title, description, ignore, inviting_account, num_invited, first_flag, script, script_state, script_city, script_owner, reserve, script_variables, script_local_variables, background_script_states, prestige, textures_created, textures_licenced, pmspk, pmvpk);
|
||||
|
||||
SCOPED_WALLET_UNLOCK();
|
||||
crypto::secret_key skey;
|
||||
|
@ -1206,7 +1206,7 @@ private:
|
||||
std::vector<cryptonote::public_node> get_public_nodes(bool white_only = true);
|
||||
|
||||
// CC
|
||||
bool get_cc_account_data(uint32_t id, std::string &public_key, uint64_t &balance, std::map<uint32_t, uint32_t> &item_balances, std::vector<uint32_t> &flags, std::map<uint32_t, std::pair<uint8_t, uint64_t>> &badges, std::map<uint32_t, uint32_t> &attributes, std::string &name, std::string &description, bool &ignore, uint32_t &inviting_account, uint32_t &num_invited, uint32_t &first_flag, uint32_t &script, uint32_t &script_state, uint32_t &script_city, uint32_t &script_owner, std::map<uint32_t, std::pair<uint64_t, std::map<uint32_t, uint32_t>>> &reserve, std::map<std::string, uint64_t> &script_variables, std::map<std::string, uint64_t> &script_local_variables, std::map<uint32_t, std::pair<uint32_t, std::map<std::string, uint64_t>>> &background_script_states, uint32_t &prestige, std::vector<uint32_t> &textures_created, std::vector<uint32_t> &textures_licenced, std::string &pmspk, std::string &pmvpk);
|
||||
bool get_cc_account_data(uint32_t id, std::string &public_key, uint64_t &balance, std::map<uint32_t, uint32_t> &item_balances, std::vector<uint32_t> &flags, std::map<uint32_t, std::pair<uint8_t, uint64_t>> &badges, std::map<uint32_t, uint32_t> &attributes, std::string &name, int32_t &title_adjective, int32_t &title_noun, int32_t &title_origin, int32_t &title_unique, std::string &title, std::string &description, bool &ignore, uint32_t &inviting_account, uint32_t &num_invited, uint32_t &first_flag, uint32_t &script, uint32_t &script_state, uint32_t &script_city, uint32_t &script_owner, std::map<uint32_t, std::pair<uint64_t, std::map<uint32_t, uint32_t>>> &reserve, std::map<std::string, uint64_t> &script_variables, std::map<std::string, uint64_t> &script_local_variables, std::map<uint32_t, std::pair<uint32_t, std::map<std::string, uint64_t>>> &background_script_states, uint32_t &prestige, std::vector<uint32_t> &textures_created, std::vector<uint32_t> &textures_licenced, std::string &pmspk, std::string &pmvpk);
|
||||
bool get_cc_account_name(uint32_t id, std::string &name);
|
||||
bool get_cc_account_public_key(uint32_t id, crypto::public_key &pkey);
|
||||
bool get_cc_account_pm_keys(uint32_t id, crypto::public_key &pmspk, crypto::public_key &pmvpk);
|
||||
@ -1265,6 +1265,8 @@ private:
|
||||
bool replace_cc_script_blob(uint32_t script, const std::string &blob, const std::vector<std::string> &blobs);
|
||||
bool get_cc_merchant_ship_available_items(std::vector<cc::merchant_ship_available_item_t> &items);
|
||||
bool get_cc_merchant_ships(std::vector<std::tuple<uint32_t, uint32_t, uint64_t, uint32_t, uint32_t, uint64_t, std::string, std::string, uint32_t>> &ships);
|
||||
bool get_cc_available_title_components(uint32_t id, std::vector<std::pair<uint32_t, std::string>> &adjectives, std::vector<std::pair<uint32_t, std::string>> &nouns, std::vector<std::pair<uint32_t, std::string>> &origins, std::vector<std::pair<uint32_t, std::string>> &uniques);
|
||||
|
||||
void add_cc_vista(const std::string &vista, const std::string &label, const std::string &picture);
|
||||
void delete_cc_vista(const std::string &vista);
|
||||
const std::vector<std::tuple<std::string, std::string, std::string>> &get_cc_vistas() const;
|
||||
|
@ -102,7 +102,7 @@ bool wallet2::ensure_cc_account()
|
||||
return lookup_cc_account(m_cc_account, m_cc_balance);
|
||||
}
|
||||
|
||||
bool wallet2::get_cc_account_data(uint32_t id, std::string &public_key, uint64_t &balance, std::map<uint32_t, uint32_t> &item_balances, std::vector<uint32_t> &flags, std::map<uint32_t, std::pair<uint8_t, uint64_t>> &badges, std::map<uint32_t, uint32_t> &attributes, std::string &name, std::string &description, bool &ignore, uint32_t &inviting_account, uint32_t &num_invited, uint32_t &first_flag, uint32_t &script, uint32_t &script_state, uint32_t &script_city, uint32_t &script_owner, std::map<uint32_t, std::pair<uint64_t, std::map<uint32_t, uint32_t>>> &reserve, std::map<std::string, uint64_t> &script_variables, std::map<std::string, uint64_t> &script_local_variables, std::map<uint32_t, std::pair<uint32_t, std::map<std::string, uint64_t>>> &background_script_states, uint32_t &prestige, std::vector<uint32_t> &textures_created, std::vector<uint32_t> &textures_licenced, std::string &pmspk, std::string &pmvpk)
|
||||
bool wallet2::get_cc_account_data(uint32_t id, std::string &public_key, uint64_t &balance, std::map<uint32_t, uint32_t> &item_balances, std::vector<uint32_t> &flags, std::map<uint32_t, std::pair<uint8_t, uint64_t>> &badges, std::map<uint32_t, uint32_t> &attributes, std::string &name, int32_t &title_adjective, int32_t &title_noun, int32_t &title_origin, int32_t &title_unique, std::string &title, std::string &description, bool &ignore, uint32_t &inviting_account, uint32_t &num_invited, uint32_t &first_flag, uint32_t &script, uint32_t &script_state, uint32_t &script_city, uint32_t &script_owner, std::map<uint32_t, std::pair<uint64_t, std::map<uint32_t, uint32_t>>> &reserve, std::map<std::string, uint64_t> &script_variables, std::map<std::string, uint64_t> &script_local_variables, std::map<uint32_t, std::pair<uint32_t, std::map<std::string, uint64_t>>> &background_script_states, uint32_t &prestige, std::vector<uint32_t> &textures_created, std::vector<uint32_t> &textures_licenced, std::string &pmspk, std::string &pmvpk)
|
||||
{
|
||||
cryptonote::COMMAND_RPC_CC_GET_ACCOUNT::request req = AUTO_VAL_INIT(req);
|
||||
cryptonote::COMMAND_RPC_CC_GET_ACCOUNT::response res;
|
||||
@ -128,6 +128,11 @@ bool wallet2::get_cc_account_data(uint32_t id, std::string &public_key, uint64_t
|
||||
for (const auto &e: res.attributes)
|
||||
attributes[e.type] = e.value;
|
||||
name = std::move(res.name);
|
||||
title_adjective = res.title_adjective;
|
||||
title_noun = res.title_noun;
|
||||
title_origin = res.title_origin;
|
||||
title_unique = res.title_unique;
|
||||
title = std::move(res.title);
|
||||
description = std::move(res.description);
|
||||
ignore = res.ignore;
|
||||
inviting_account = res.inviting_account;
|
||||
@ -669,7 +674,7 @@ bool wallet2::get_cc_badge_data(const std::vector<uint32_t> &id, std::vector<cc:
|
||||
std::vector<std::pair<uint64_t, std::string>> thresholds;
|
||||
for (auto &e: e.thresholds)
|
||||
thresholds.push_back(std::make_pair(e.value, std::move(e.text)));
|
||||
data.push_back({e.id, std::move(e.name), std::move(e.description), std::move(e.icon), e.manual, std::move(thresholds)});
|
||||
data.push_back({e.id, std::move(e.name), std::move(e.description), std::move(e.icon), e.manual, std::move(e.title_adjective), std::move(e.title_noun), std::move(thresholds)});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -1846,4 +1851,38 @@ const std::vector<std::tuple<std::string, std::string, std::string>> &wallet2::g
|
||||
return m_cc_vistas;
|
||||
}
|
||||
|
||||
bool wallet2::get_cc_available_title_components(uint32_t id, std::vector<std::pair<uint32_t, std::string>> &adjectives, std::vector<std::pair<uint32_t, std::string>> &nouns, std::vector<std::pair<uint32_t, std::string>> &origins, std::vector<std::pair<uint32_t, std::string>> &uniques)
|
||||
{
|
||||
cryptonote::COMMAND_RPC_CC_GET_AVAILABLE_TITLE_COMPONENTS::request req = AUTO_VAL_INIT(req);
|
||||
cryptonote::COMMAND_RPC_CC_GET_AVAILABLE_TITLE_COMPONENTS::response res;
|
||||
|
||||
req.account = id;
|
||||
|
||||
m_daemon_rpc_mutex.lock();
|
||||
bool r = invoke_http_json_rpc("/json_rpc", "cc_get_available_title_components", req, res);
|
||||
m_daemon_rpc_mutex.unlock();
|
||||
if (!r || res.status != CORE_RPC_STATUS_OK)
|
||||
return false;
|
||||
|
||||
adjectives.clear();
|
||||
nouns.clear();
|
||||
origins.clear();
|
||||
uniques.clear();
|
||||
|
||||
adjectives.reserve(res.adjectives.size());
|
||||
for (auto &e: res.adjectives)
|
||||
adjectives.push_back({e.id, e.string});
|
||||
nouns.reserve(res.nouns.size());
|
||||
for (auto &e: res.nouns)
|
||||
nouns.push_back({e.id, e.string});
|
||||
origins.reserve(res.origins.size());
|
||||
for (auto &e: res.origins)
|
||||
origins.push_back({e.id, e.string});
|
||||
uniques.reserve(res.uniques.size());
|
||||
for (auto &e: res.uniques)
|
||||
uniques.push_back({e.id, e.string});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -7891,6 +7891,49 @@ namespace tools
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
bool wallet_rpc_server::on_cc_set_title(const wallet_rpc::COMMAND_RPC_CC_SET_TITLE::request& req, wallet_rpc::COMMAND_RPC_CC_SET_TITLE::response& res, epee::json_rpc::error& er, const connection_context *ctx)
|
||||
{
|
||||
LOG_PRINT_L3("on_cc_set_title starts");
|
||||
if (!m_wallet) return not_open(er);
|
||||
if (m_restricted)
|
||||
{
|
||||
er.code = WALLET_RPC_ERROR_CODE_DENIED;
|
||||
er.message = "Command unavailable in restricted mode.";
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
cryptonote::cc_command_set_title_t cmd;
|
||||
cmd.cc_account = m_wallet->get_cc_account();
|
||||
cmd.delta_adjective = req.delta_adjective;
|
||||
cmd.delta_noun = req.delta_noun;
|
||||
cmd.delta_origin = req.delta_origin;
|
||||
cmd.delta_unique = req.delta_unique;
|
||||
|
||||
uint32_t priority = m_wallet->adjust_priority(req.priority);
|
||||
std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_cc_transactions(cmd, priority);
|
||||
if (ptx_vector.empty())
|
||||
{
|
||||
er.code = WALLET_RPC_ERROR_CODE_TX_NOT_POSSIBLE;
|
||||
er.message = "No transaction created";
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string dummy_tx_key;
|
||||
uint64_t dummy_amount;
|
||||
tools::wallet_rpc::key_image_list empty_key_images;
|
||||
return fill_response(ptx_vector, false, dummy_tx_key, dummy_amount, res.fee, res.weight, res.multisig_txset, res.unsigned_txset, req.do_not_relay,
|
||||
res.tx_hash, req.get_tx_hex, res.tx_blob, req.get_tx_metadata, res.tx_metadata, empty_key_images, er);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
class t_daemon
|
||||
|
@ -233,6 +233,7 @@ namespace tools
|
||||
MAP_JON_RPC_WE("cc_retrieve_items", on_cc_retrieve_items, wallet_rpc::COMMAND_RPC_CC_RETRIEVE_ITEMS)
|
||||
MAP_JON_RPC_WE("cc_create_runestones", on_cc_create_runestones, wallet_rpc::COMMAND_RPC_CC_CREATE_RUNESTONES)
|
||||
MAP_JON_RPC_WE("cc_start_epoch", on_cc_start_epoch, wallet_rpc::COMMAND_RPC_CC_START_EPOCH)
|
||||
MAP_JON_RPC_WE("cc_set_title", on_cc_set_title, wallet_rpc::COMMAND_RPC_CC_SET_TITLE)
|
||||
END_JSON_RPC_MAP()
|
||||
END_URI_MAP2()
|
||||
|
||||
@ -396,6 +397,7 @@ namespace tools
|
||||
bool on_cc_retrieve_items(const wallet_rpc::COMMAND_RPC_CC_RETRIEVE_ITEMS::request& req, wallet_rpc::COMMAND_RPC_CC_RETRIEVE_ITEMS::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
|
||||
bool on_cc_create_runestones(const wallet_rpc::COMMAND_RPC_CC_CREATE_RUNESTONES::request& req, wallet_rpc::COMMAND_RPC_CC_CREATE_RUNESTONES::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
|
||||
bool on_cc_start_epoch(const wallet_rpc::COMMAND_RPC_CC_START_EPOCH::request& req, wallet_rpc::COMMAND_RPC_CC_START_EPOCH::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
|
||||
bool on_cc_set_title(const wallet_rpc::COMMAND_RPC_CC_SET_TITLE::request& req, wallet_rpc::COMMAND_RPC_CC_SET_TITLE::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
|
||||
|
||||
//json rpc v2
|
||||
bool on_query_key(const wallet_rpc::COMMAND_RPC_QUERY_KEY::request& req, wallet_rpc::COMMAND_RPC_QUERY_KEY::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
|
||||
|
@ -6728,5 +6728,58 @@ namespace wallet_rpc
|
||||
typedef epee::misc_utils::struct_init<response_t> response;
|
||||
};
|
||||
|
||||
struct COMMAND_RPC_CC_SET_TITLE
|
||||
{
|
||||
struct request_t
|
||||
{
|
||||
int32_t delta_adjective;
|
||||
int32_t delta_noun;
|
||||
int32_t delta_origin;
|
||||
int32_t delta_unique;
|
||||
|
||||
uint32_t priority;
|
||||
bool do_not_relay;
|
||||
bool get_tx_keys;
|
||||
bool get_tx_hex;
|
||||
bool get_tx_metadata;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(delta_adjective)
|
||||
KV_SERIALIZE(delta_noun)
|
||||
KV_SERIALIZE(delta_origin)
|
||||
KV_SERIALIZE(delta_unique)
|
||||
|
||||
KV_SERIALIZE(priority)
|
||||
KV_SERIALIZE_OPT(do_not_relay, false)
|
||||
KV_SERIALIZE_OPT(get_tx_keys, false)
|
||||
KV_SERIALIZE_OPT(get_tx_hex, false)
|
||||
KV_SERIALIZE_OPT(get_tx_metadata, false)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
typedef epee::misc_utils::struct_init<request_t> request;
|
||||
|
||||
struct response_t
|
||||
{
|
||||
std::string tx_hash;
|
||||
uint64_t fee;
|
||||
uint64_t weight;
|
||||
std::string tx_blob;
|
||||
std::string tx_metadata;
|
||||
std::string multisig_txset;
|
||||
std::string unsigned_txset;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(tx_hash)
|
||||
KV_SERIALIZE(fee)
|
||||
KV_SERIALIZE(weight)
|
||||
KV_SERIALIZE(tx_blob)
|
||||
KV_SERIALIZE(tx_metadata)
|
||||
KV_SERIALIZE(multisig_txset)
|
||||
KV_SERIALIZE(unsigned_txset)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
typedef epee::misc_utils::struct_init<response_t> response;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -273,6 +273,7 @@ class CCTest():
|
||||
self.test_cc_transfers()
|
||||
self.check_gold_consistency()
|
||||
self.check_event_balances()
|
||||
self.test_titles()
|
||||
self.test_messages()
|
||||
self.check_gold_consistency()
|
||||
self.test_buy_land()
|
||||
@ -6045,6 +6046,64 @@ script {
|
||||
self.wallet[2].rescan_blockchain()
|
||||
self.deposits -= 100000000
|
||||
|
||||
def test_titles(self):
|
||||
daemon = self.daemon
|
||||
|
||||
print("Testing titles")
|
||||
|
||||
res = self.wallet[2].cc_get_info()
|
||||
account2_id = res.account_id
|
||||
|
||||
# the default is no title
|
||||
res = daemon.cc_get_account(account2_id)
|
||||
assert res.title == ""
|
||||
|
||||
# there should be some small default set of title compoments
|
||||
res = daemon.cc_get_available_title_components(account2_id)
|
||||
adjectives = res.adjectives if 'adjectives' in res else []
|
||||
nouns = res.nouns if 'nouns' in res else []
|
||||
origins = res.origins if 'origins' in res else []
|
||||
uniques = res.uniques if 'uniques' in res else []
|
||||
assert len(adjectives) > 0 or len(nouns) > 0
|
||||
|
||||
# at least the starting city is a valid origin, but we have no uniques yet
|
||||
assert len(origins) > 0
|
||||
assert len([x for x in origins if x.string == "Helsengaard"]) == 1
|
||||
assert len(uniques) == 0
|
||||
|
||||
# we can't set invalid components
|
||||
self.assert_exception(lambda: self.wallet[2].cc_set_title(666, 0, 0, 0))
|
||||
self.assert_exception(lambda: self.wallet[2].cc_set_title(-666, 0, 0, 0))
|
||||
self.assert_exception(lambda: self.wallet[2].cc_set_title(0, 666, 0, 0))
|
||||
self.assert_exception(lambda: self.wallet[2].cc_set_title(0, -666, 0, 0))
|
||||
self.assert_exception(lambda: self.wallet[2].cc_set_title(0, 0, 666, 0))
|
||||
self.assert_exception(lambda: self.wallet[2].cc_set_title(0, 0, -666, 0))
|
||||
self.assert_exception(lambda: self.wallet[2].cc_set_title(0, 0, 0, 666))
|
||||
self.assert_exception(lambda: self.wallet[2].cc_set_title(0, 0, 0, -666))
|
||||
|
||||
# can't set a unique, there are none
|
||||
self.assert_exception(lambda: self.wallet[2].cc_set_title(0, 0, 0, 1))
|
||||
self.assert_exception(lambda: self.wallet[2].cc_set_title(0, 0, 0, -1))
|
||||
|
||||
# we can set an origin though
|
||||
origin_id = [x for x in origins if x.string == "Helsengaard"][0].id
|
||||
res = daemon.cc_get_account(account2_id)
|
||||
res = self.wallet[2].cc_set_title(0, 0, origin_id - res.title_origin, 0)
|
||||
self.generate_blocks('TF1MM8HqWBathu8hS5mwMNHm1da3cZCzg2rkqWLKCxpUarKtPszP3MjiocrJeLvph4AghgYu1AXonCmckfEuyE8Q2FFm8jNdiz3', 1)
|
||||
res = daemon.cc_get_account(account2_id)
|
||||
assert res.title.endswith('of Helsengaard')
|
||||
|
||||
# we can add one of the small set above
|
||||
adjective = adjectives[0] if len(adjectives) > 0 else None
|
||||
noun = nouns[0] if len(nouns) > 0 else None
|
||||
res = daemon.cc_get_account(account2_id)
|
||||
res = self.wallet[2].cc_set_title((adjective.id - res.title_adjective) if adjective else 0, (noun.id - res.title_noun) if noun else 0, 0, 0)
|
||||
self.generate_blocks('TF1MM8HqWBathu8hS5mwMNHm1da3cZCzg2rkqWLKCxpUarKtPszP3MjiocrJeLvph4AghgYu1AXonCmckfEuyE8Q2FFm8jNdiz3', 1)
|
||||
res = daemon.cc_get_account(account2_id)
|
||||
assert not adjective or adjective.string in res.title
|
||||
assert not noun or noun.string in res.title
|
||||
assert res.title.endswith('of Helsengaard')
|
||||
|
||||
def test_script_variables(self):
|
||||
daemon = self.daemon
|
||||
|
||||
@ -9776,6 +9835,57 @@ script {
|
||||
res = daemon.cc_get_script(script_id)
|
||||
assert res.blob != other_blob
|
||||
|
||||
print('Testing awarding a title from a script')
|
||||
script = """
|
||||
script {
|
||||
name "title"
|
||||
state "0" {
|
||||
choice { text "done" actions { award title \"the One\" } }
|
||||
}
|
||||
}
|
||||
"""
|
||||
res = self.wallet[3].cc_create_script(source = script)
|
||||
expected_balances[3] -= res.fee
|
||||
res = self.generate_blocks('TF1MMBg4zx18SnZC6oswCRB7DzdVeUKce5NdCMSWUHNY4wNvNhzmFj4WqZY2bFj8R1REAWR3qAH5zD7sjXyHz3tVayzHSswqymx', 1)
|
||||
res = daemon.cc_get_scripts(all = True)
|
||||
assert len(res.scripts) > 1
|
||||
script_id = res.scripts[-1].index
|
||||
|
||||
res = self.wallet[1].cc_start_script(script_id, city = 0, owner = GAME_ACCOUNT)
|
||||
expected_balances[1] -= res.fee
|
||||
res = self.generate_blocks('TF1MMBg4zx18SnZC6oswCRB7DzdVeUKce5NdCMSWUHNY4wNvNhzmFj4WqZY2bFj8R1REAWR3qAH5zD7sjXyHz3tVayzHSswqymx', 1)
|
||||
res = daemon.cc_get_account(account1_id)
|
||||
assert res.script == script_id
|
||||
assert res.script_city == 0
|
||||
assert res.script_owner == GAME_ACCOUNT
|
||||
assert res.script_state == 0
|
||||
|
||||
res = self.wallet[1].cc_script_choice(script_id, state = 0, city = 0, owner = GAME_ACCOUNT, choice = 0)
|
||||
expected_balances[1] -= res.fee
|
||||
res = self.generate_blocks('TF1MMBg4zx18SnZC6oswCRB7DzdVeUKce5NdCMSWUHNY4wNvNhzmFj4WqZY2bFj8R1REAWR3qAH5zD7sjXyHz3tVayzHSswqymx', 1)
|
||||
|
||||
# the script has ended
|
||||
res = daemon.cc_get_account(account1_id)
|
||||
assert res.script == 0
|
||||
|
||||
# the player now has a title
|
||||
res = daemon.cc_get_account(account1_id)
|
||||
assert len(res.unique_titles) == 1
|
||||
assert res.unique_titles[0] == "the One"
|
||||
|
||||
# and we can use it
|
||||
res = self.wallet[1].cc_set_title(0, 0, 0, 1)
|
||||
expected_balances[1] -= res.fee
|
||||
self.generate_blocks('TF1MM8HqWBathu8hS5mwMNHm1da3cZCzg2rkqWLKCxpUarKtPszP3MjiocrJeLvph4AghgYu1AXonCmckfEuyE8Q2FFm8jNdiz3', 1)
|
||||
res = daemon.cc_get_account(account1_id)
|
||||
assert res.title.endswith('the One')
|
||||
|
||||
# check balances
|
||||
for i in range(4):
|
||||
res = daemon.cc_get_account(account_id[i])
|
||||
assert res.balance == expected_balances[i], "exp " + str(expected_balances[i]) + ', got ' + str(res.balance) + " for wallet " + str(i)
|
||||
assert (res.item_balances if 'item_balances' in res else []) == expected_item_balances[i]
|
||||
|
||||
def test_background_scripts(self):
|
||||
daemon = self.daemon
|
||||
|
||||
|
@ -3069,6 +3069,8 @@ TEST(cc, type_tags)
|
||||
ASSERT_EQ(get_cc_tag<uint8_t>(cmd), 0x41);
|
||||
cmd = cryptonote::cc_command_start_epoch_t();
|
||||
ASSERT_EQ(get_cc_tag<uint8_t>(cmd), 0x42);
|
||||
cmd = cryptonote::cc_command_set_title_t();
|
||||
ASSERT_EQ(get_cc_tag<uint8_t>(cmd), 0x43);
|
||||
}
|
||||
|
||||
TEST(cc, staff)
|
||||
|
@ -1470,3 +1470,14 @@ class Daemon(object):
|
||||
'id': '0'
|
||||
}
|
||||
return self.rpc.send_json_rpc_request(cc_get_epochs)
|
||||
|
||||
def cc_get_available_title_components(self, account):
|
||||
cc_get_available_title_components = {
|
||||
'method': 'cc_get_available_title_components',
|
||||
'params': {
|
||||
'account': account,
|
||||
},
|
||||
'jsonrpc': '2.0',
|
||||
'id': '0'
|
||||
}
|
||||
return self.rpc.send_json_rpc_request(cc_get_available_title_components)
|
||||
|
@ -2410,3 +2410,17 @@ class Wallet(object):
|
||||
'id': '0'
|
||||
}
|
||||
return self.rpc.send_json_rpc_request(cc_start_epoch)
|
||||
|
||||
def cc_set_title(self, delta_adjective, delta_noun, delta_origin, delta_unique):
|
||||
cc_set_title = {
|
||||
'method': 'cc_set_title',
|
||||
'params': {
|
||||
'delta_adjective' : delta_adjective,
|
||||
'delta_noun' : delta_noun,
|
||||
'delta_origin' : delta_origin,
|
||||
'delta_unique' : delta_unique,
|
||||
},
|
||||
'jsonrpc': '2.0',
|
||||
'id': '0'
|
||||
}
|
||||
return self.rpc.send_json_rpc_request(cc_set_title)
|
||||
|
Loading…
Reference in New Issue
Block a user