From a993d31910b63a1f897e470842934e6ffefad32c Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Fri, 13 Nov 2009 22:25:09 +0000 Subject: added core::InfoType, refactored game::ShipModel as core::Info subclass, introduced core::Label --- src/client/buymenu.cc | 8 +- src/core/Makefile.am | 2 +- src/core/gameconnection.cc | 12 +- src/core/gameconnection.h | 2 +- src/core/gameinterface.h | 2 +- src/core/gameserver.cc | 9 +- src/core/gameserver.h | 2 +- src/core/info.cc | 285 ++++++++++++++++++++++++++++++++++---------- src/core/info.h | 148 +++++++++++++++++------ src/core/label.h | 78 ++++++++++++ src/filesystem/inifile.cc | 4 + src/game/base/commodity.cc | 4 + src/game/base/commodity.h | 2 + src/game/base/game.cc | 100 +++++++++------- src/game/base/ship.cc | 4 +- src/game/base/shipdealer.cc | 9 +- src/game/base/shipmodel.cc | 168 +++++++------------------- src/game/base/shipmodel.h | 105 +++++----------- src/ui/Makefile.am | 2 +- 19 files changed, 578 insertions(+), 368 deletions(-) create mode 100644 src/core/label.h diff --git a/src/client/buymenu.cc b/src/client/buymenu.cc index d12f23e..7fad916 100644 --- a/src/client/buymenu.cc +++ b/src/client/buymenu.cc @@ -34,7 +34,7 @@ BuyMenu::BuyMenu(ui::Widget *parent, const char * label) : ui::Window(parent) menu_modelview->set_background(false); menu_modelview->set_border(false); - menu_closebutton = new ui::Button(menu_modelpane, "Close", "view hide"); + menu_closebutton = new ui::Button(menu_modelpane, "Return", "view hide"); // text pane (right) menu_textpane = new ui::Window(this); @@ -76,14 +76,14 @@ void BuyMenu::set_item(std::string const & itemtype, std::string const & itemnam menu_itemname.assign(itemname); aux::to_label(menu_itemname); - menu_buybutton->set_command("remote buy " + itemtype + ' ' + itemname + "; view hide"); - menu_buybutton->set_label("buy " + itemname); + menu_buybutton->set_command("remote buy " + menu_itemtype + ' ' + menu_itemname + "; view hide"); + menu_buybutton->set_label("buy " + menu_itemname); menu_infotext.clear(); menu_namelabel->set_text(0); menu_modelview->set_modelname(0); - core::Info *info = core::game()->info(itemtype + '/' + itemname); + core::Info *info = core::game()->info(menu_itemtype, menu_itemname); if (info) { menu_namelabel->set_text(info->name()); menu_modelview->set_modelname(info->modelname()); diff --git a/src/core/Makefile.am b/src/core/Makefile.am index fce79a6..421dd59 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -14,4 +14,4 @@ noinst_LTLIBRARIES = libcore.la noinst_HEADERS = application.h commandbuffer.h core.h cvar.h entity.h func.h \ gameconnection.h gameinterface.h gameserver.h message.h module.h net.h netclient.h \ netconnection.h netserver.h player.h range.h stats.h timer.h parser.h descriptions.h \ - extension.h loader.h info.h item.h inventory.h + extension.h loader.h info.h item.h inventory.h label.h diff --git a/src/core/gameconnection.cc b/src/core/gameconnection.cc index c0a769c..064974c 100644 --- a/src/core/gameconnection.cc +++ b/src/core/gameconnection.cc @@ -90,15 +90,21 @@ bool GameConnection::interactive() const return true; } -Info *GameConnection::info(const std::string &label) +Info *GameConnection::info(const std::string &type, const std::string &label) { + // find the class + InfoType *infotype = InfoType::find(type); + if (!infotype) + return 0; + // check if we already have the info record - Info *info = Info::find(label); + Info *info = Info::find(infotype, label); if (info) return info; // create a new information record and set the label - info = new Info(label); + info = new Info(0); + info->set_label(label); info->text().push_back("Requesting information..."); // send an information request to the server diff --git a/src/core/gameconnection.h b/src/core/gameconnection.h index 52885f4..9c0b5a9 100644 --- a/src/core/gameconnection.h +++ b/src/core/gameconnection.h @@ -59,7 +59,7 @@ public: void private_message(std::string const &args); /// returns an info record - Info *info(const std::string &label); + virtual Info *info(const std::string &type, const std::string &label); /*----- static ---------------------------------------------------- */ diff --git a/src/core/gameinterface.h b/src/core/gameinterface.h index 44b4230..ef479b1 100644 --- a/src/core/gameinterface.h +++ b/src/core/gameinterface.h @@ -63,7 +63,7 @@ public: virtual unsigned long timestamp() const = 0; /// returns an info record - virtual Info *info(const std::string &label) = 0; + virtual Info *info(const std::string &type, const std::string &label) = 0; /*----- mutators ------------------------------------------------- */ diff --git a/src/core/gameserver.cc b/src/core/gameserver.cc index e170a4d..c0d7382 100644 --- a/src/core/gameserver.cc +++ b/src/core/gameserver.cc @@ -237,9 +237,14 @@ float GameServer::time() const return ((float)(server_timestamp) / 1000.0f); } -Info *GameServer::info(const std::string &label) +Info *GameServer::info(const std::string &type, const std::string &label) { - return Info::find(label); + // find the class + InfoType *infotype = InfoType::find(type); + if (!infotype) + return 0; + + return Info::find(infotype, label); } void GameServer::abort() diff --git a/src/core/gameserver.h b/src/core/gameserver.h index 57feac1..2c82870 100644 --- a/src/core/gameserver.h +++ b/src/core/gameserver.h @@ -89,7 +89,7 @@ public: } /// returns an info record - Info *info(const std::string &label); + virtual Info *info(const std::string &type, const std::string &label); /*----- static ---------------------------------------------------- */ diff --git a/src/core/info.cc b/src/core/info.cc index 4e5399a..8f843c4 100644 --- a/src/core/info.cc +++ b/src/core/info.cc @@ -9,78 +9,121 @@ #include "sys/sys.h" #include "core/info.h" +#include + namespace core { -/* ---- class Info ------------------------------------------------- */ +/* ---- class InfoType --------------------------------------------- */ -// default constructor -Info::Info() +// server-side constructor, assigns id +InfoType::InfoType(const char *label) { - static_info_id_counter++; - info_id = static_info_id_counter; - - info_model = 0; - info_timestamp = 0; + infotype_id_counter++; + infotype_id = infotype_id_counter; + if (label) + set_label(label); + + infotype_registry.push_back(this); +} + +// client-side constructor, receives id +InfoType::InfoType(const unsigned int id) +{ + infotype_id = id; + infotype_registry.push_back(this); +} + +InfoType::~InfoType() +{ + infotype_id = 0; +} - add(this); +/* ---- static InfoType registry ----------------------------------- */ + +InfoType::Registry InfoType::infotype_registry; +unsigned int InfoType::infotype_id_counter = 0; + +void InfoType::clear() +{ + for (Registry::iterator it = infotype_registry.begin(); it != infotype_registry.end(); it++) { + InfoType *infotype = (*it); + delete infotype; + } + infotype_registry.clear(); + infotype_id_counter = 0; + +} + +InfoType *InfoType::find(const std::string & label) +{ + if (!label.size()) + return 0; + + for (Registry::iterator it = infotype_registry.begin(); it != infotype_registry.end(); it++) { + InfoType *infotype = (*it); + if (infotype->label().compare(label) == 0) { + return infotype; + } + } + return 0; +} + +InfoType *InfoType::find(const unsigned int id) +{ + if (!id) + return 0; + + for (Registry::iterator it = infotype_registry.begin(); it != infotype_registry.end(); it++) { + InfoType *infotype = (*it); + if (infotype->id() == id) { + return infotype; + } + } + return 0; } -Info::Info(const std::string & label) +/* ---- class Info ------------------------------------------------- */ + +// server-side constructor, assigns id +Info::Info() { - static_info_id_counter++; - info_id = static_info_id_counter; + info_id_counter++; + info_id = info_id_counter; + info_type = 0; - info_timestamp = 0; info_model = 0; - - info_label.assign(label); - aux::to_lowercase(info_label); - aux::strip_quotes(info_label); - - add(this); + info_timestamp = 0; + info_price = 0; + + info_registry.push_back(this); } +// client-side constructor, receives id Info::Info(const unsigned int id) { info_id = id; + info_type = 0; info_timestamp = 0; info_model = 0; + info_price = 0; - add(this); + info_registry.push_back(this); } Info::~Info() { info_text.clear(); - info_label.clear(); info_modelname.clear(); info_text.clear(); info_timestamp = 0; info_model = 0; } -void Info::set_label(const std::string & label) +void Info::set_type(const InfoType *type) { - info_label.assign(label); - aux::to_label(info_label); -} - -void Info::set_label(const char *label) -{ - info_label.assign(label); - aux::to_label(info_label); -} - -void Info::set_name(const std::string & name) -{ - info_name.assign(name); -} - -void Info::set_name(const char *name) -{ - info_name.assign(name); + info_type = type; } void Info::set_modelname(const std::string & modelname) @@ -98,6 +141,11 @@ void Info::set_model(const model::Model *model) info_model = model; } +void Info::set_price(const long price) +{ + info_price = price; +} + void Info::set_timestamp(const unsigned long timestamp) { info_timestamp = timestamp; @@ -127,7 +175,7 @@ void Info::clear_text() void Info::serialize_server_update(std::ostream & os) const { - os << '"' << label() << "\" \"" << name() << "\" \"" << modelname() << "\" " << info_text.size() << " "; + os << " \"" << label() << "\" \"" << name() << "\" \"" << modelname() << "\" " << info_text.size() << " "; for (Text::const_iterator it = info_text.begin(); it != info_text.end(); it++) { if (it != info_text.begin()) @@ -146,13 +194,13 @@ void Info::receive_server_update(std::istream &is) while ((is.get(c)) && (c != '"')); while ((is.get(c)) && (c != '"')) n += c; - info_label.assign(n); + set_label(n); // read name while ((is.get(c)) && (c != '"')); while ((is.get(c)) && (c != '"')) n += c; - info_name.assign(n); + set_name(n); // read model name n.clear(); @@ -160,11 +208,11 @@ void Info::receive_server_update(std::istream &is) while ((is.get(c)) && (c != '"')) n += c; - info_modelname.assign(n); + set_modelname(n); // read info text - size_t s; - info_text.clear(); + clear_text(); + size_t s; is >> s; for (size_t i = 0; (i < s) && is.good(); i++) { n.clear(); @@ -172,29 +220,25 @@ void Info::receive_server_update(std::istream &is) while ((is.get(c)) && (c != '"')) n += c; - info_text.push_back(n); + add_text(n); } } void Info::print() const { - con_print << "label: ^B" << label() << " ^Nname: ^B" << name() << " ^Nmodel: ^B" << modelname() << "^N" << std::endl; - - for (Text::const_iterator it = info_text.begin(); it != info_text.end(); it++) { - con_print << " " << (*it) << std::endl; + if (info_text.size()) { + for (Text::const_iterator it = info_text.begin(); it != info_text.end(); it++) { + con_print << " " << (*it) << std::endl; + } + } else { + con_print << " label: ^B" << label() << " ^Nname: ^B" << name() << " ^Nmodel: ^B" << modelname() << "^N" << std::endl; } } - /* ---- static info registry --------------------------------------- */ Info::Registry Info::info_registry; -unsigned int Info::static_info_id_counter = 0; - -void Info::add(Info *info) -{ - info_registry.push_back(info); -} +unsigned int Info::info_id_counter = 0; Info *Info::find(const char *label) { @@ -238,6 +282,104 @@ Info *Info::find(const unsigned int id) return 0; } +Info *Info::search(const std::string & searchstr) +{ + if (!searchstr.size()) + return 0; + + std::string strsearchkey(aux::lowercase(searchstr)); + if (strsearchkey.size() < 3) { + return 0; + } + + for (Registry::iterator it = info_registry.begin(); it != info_registry.end(); it++) { + Info *info = *(it); + + std::string labelstr(info->label()); + if (labelstr.size() && (labelstr.find(strsearchkey) != std::string::npos)) { + return info; + } + + std::string namestr(aux::lowercase(info->name())); + if (namestr.size() && (namestr.find(strsearchkey) != std::string::npos)) { + return info; + } + } + + return 0; +} + +Info *Info::find(const InfoType *type, const char *label) +{ + if (!label) + return 0; + + for (Registry::iterator it = info_registry.begin(); it != info_registry.end(); it++) { + Info *info = (*it); + if ((info->type() == type) && (info->label().compare(label) == 0)) { + return info; + } + } + return 0; +} + +Info *Info::find(const InfoType *type, const std::string & label) +{ + if (!label.size()) + return 0; + + for (Registry::iterator it = info_registry.begin(); it != info_registry.end(); it++) { + Info *info = (*it); + if ((info->type() == type) && (info->label().compare(label) == 0)) { + return info; + } + } + return 0; +} + +Info *Info::find(const InfoType *type, const unsigned int id) +{ + if (!id) + return 0; + + for (Registry::iterator it = info_registry.begin(); it != info_registry.end(); it++) { + Info *info = (*it); + if ((info->type() == type) && (info->id() == id)) { + return info; + } + } + return 0; +} + +Info *Info::search(const InfoType *type, const std::string & searchstr) +{ + if (!searchstr.size()) + return 0; + + std::string strsearchkey(aux::lowercase(searchstr)); + if (strsearchkey.size() < 3) { + return 0; + } + + for (Registry::iterator it = info_registry.begin(); it != info_registry.end(); it++) { + Info *info = *(it); + + if (info->type() == type) { + std::string labelstr(info->label()); + if (labelstr.size() && (labelstr.find(strsearchkey) != std::string::npos)) { + return info; + } + + std::string namestr(aux::lowercase(info->name())); + if (namestr.size() && (namestr.find(strsearchkey) != std::string::npos)) { + return info; + } + } + } + + return 0; +} + void Info::clear() { for (Registry::iterator it = info_registry.begin(); it != info_registry.end(); it++) { @@ -245,16 +387,37 @@ void Info::clear() delete info; } info_registry.clear(); - static_info_id_counter = 0; + info_id_counter = 0; + + InfoType::clear(); } void Info::list() { for (Registry::iterator it = info_registry.begin(); it != info_registry.end(); it++) { Info *info = (*it); - con_print << info->label() << std::endl; + con_print << " " + << "^B" << aux::pad_right(info->type()->label(), 8) << "^N " + << "^B" << aux::pad_right(info->label(), 12) << "^N " + << info->name() << "^N" << std::endl; + } + con_print << info_registry.size() << " info " << aux::plural("record", info_registry.size()) << std::endl; +} + +void Info::list_class(const InfoType *type) +{ + size_t count = 0; + for (Registry::iterator it = info_registry.begin(); it != info_registry.end(); it++) { + core::Info *info = (*it); + if (info->type() == type) { + count++; + + con_print << " " + << "^B" << aux::pad_right(info->label(), 12) << "^N " + << info->name() << "^N" << std::endl; + } } - con_print << info_registry.size() << " registered info " << aux::plural("record", info_registry.size()) << std::endl; + con_print << count << " info " << aux::plural("record", count) << std::endl; } } diff --git a/src/core/info.h b/src/core/info.h index 9f1fab8..13f38f8 100644 --- a/src/core/info.h +++ b/src/core/info.h @@ -12,48 +12,101 @@ #include #include +#include "core/label.h" #include "model/model.h" namespace core { +/** + * @brief an object class information record + * Describes a class of object + */ +class InfoType : public Label +{ +public: + /** + * @brief create a server side object class information record + */ + InfoType(const char* label); + + /** + * @brief create a client side object class information record + */ + InfoType(const unsigned int id); + + virtual ~InfoType(); + + /* ---- inspectors ------------------------------------------------- */ + + inline const unsigned int id() const { + return infotype_id; + } + +private: + + unsigned int infotype_id; + + + /* ---- static infoclass registry ---------------------------------- */ + +public: + /// clear infotype registry + static void clear(); + + /// search the infotype registry for a label + static InfoType *find(const std::string & label); + + /// search the infotype registry for an id + static InfoType *find(const unsigned int id); + + +private: + /// info registry type definition + typedef std::vector Registry; + + static Registry infotype_registry; + static unsigned int infotype_id_counter; + +}; // class InfoType + /** * @brief an information record * An information record holds extended information about a specific entity or item class. * This information isexchanged between server and the client, and can be used to build * HUD widgets/ */ -class Info +class Info : public Label { public: /// type definition for the text description typedef std::deque Text; - /// create a new labeled information record + /** + * @brief create a new server-side information record + * This is a server-side constructor and assigns an id + */ Info(); - /// create a new labeled information record - Info(const std::string & label); - + /** + * @brief create a new client-side information record + * This is a client-side constructor + */ Info(const unsigned int id); /// delete the information record - ~Info(); + virtual ~Info(); /* ---- inspectors ------------------------------------------------- */ inline const unsigned int id() const { return info_id; } - - inline const std::string & label() const { - return info_label; - } - inline const std::string & name() const { - return info_name; + inline const InfoType* type() const { + return info_type; } - + inline const std::string & modelname() const { return info_modelname; } @@ -62,6 +115,10 @@ public: return info_model; } + inline const long price() const { + return info_price; + } + inline const unsigned long ×tamp() const { return info_timestamp; } @@ -73,38 +130,38 @@ public: /* ---- mutators --------------------------------------------------- */ - void set_label(const std::string & name); - - void set_label(const char *name); - - void set_name(const std::string & name); - - void set_name(const char *name); - void set_modelname(const std::string & modelname); void set_modelname(const char *modelname); void set_model(const model::Model *model); + void set_price(const long price); + /// set the timestamp void set_timestamp(const unsigned long timestamp); /// add a line of info text void add_text(const std::string & text); + /// add a line of info text + void add_text(const char *text); + /// clear the info text void clear_text(); - /// print info to sys::con_out - void print() const; + /// print info to the system console + virtual void print() const; /// clear the timestamp void clear_timestamp(); - /// add a line of info text - void add_text(const char *text); +protected: + + /// set the info class id + void set_type(const InfoType *type); +public: /* ---- serializers ------------------------------------------------ */ /// serialize a server-to-client update on a stream @@ -114,17 +171,14 @@ public: void receive_server_update(std::istream &is); private: - - unsigned int info_id; + const InfoType* info_type; - std::string info_label; - std::string info_name; + unsigned int info_id; + long info_price; + unsigned long info_timestamp; std::string info_modelname; - + const model::Model* info_model; - - long info_credits; - unsigned long info_timestamp; Text info_text; @@ -133,12 +187,13 @@ private: public: /// info registry type definition typedef std::vector Registry; - + /// the info registry static inline Registry & registry() { return info_registry; } - /// search the info registry for a labeled item + + /// search the info registry for a labeled item static Info *find(const char * label); /// search the info registry for a label @@ -147,18 +202,33 @@ public: /// search the info registry for an id static Info *find(const unsigned int id); + /// search the info registry for a record with a matching label or name + static Info *search(const std::string & searchstr); + + /// search the info registry for a labeled item, belonging to a specific class + static Info *find(const InfoType *type, const char * label); + + /// search the info registry for a label, belonging to a specific class + static Info *find(const InfoType *type, const std::string & label); + + /// search the info registry for an id, belonging to a specific class + static Info *find(const InfoType *type, const unsigned int id); + + /// search the info registry for a record with a matching label or name and belonging to a specific class + static Info *search(const InfoType *type, const std::string & searchstr); + /// clear the info registry static void clear(); /// list the info registry static void list(); -private: - /// add a record to the info registry - static void add(Info *info); + /// list a single class in the info registry + static void list_class(const InfoType *type); +private: static Registry info_registry; - static unsigned int static_info_id_counter; + static unsigned int info_id_counter; }; } diff --git a/src/core/label.h b/src/core/label.h new file mode 100644 index 0000000..e772277 --- /dev/null +++ b/src/core/label.h @@ -0,0 +1,78 @@ +/* + core/label.h + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2 +*/ + +#ifndef __INCLUDED_CORE_LABEL_H__ +#define __INCLUDED_CORE_LABEL_H__ + +#include + +#include "auxiliary/functions.h" + +namespace core { + +/** + * @brief baseclass for objects with a name and a label + */ +class Label { +public: + inline Label() { + } + + inline ~Label() { + labelstr.clear(); + namestr.clear(); + } + + /* --- inspectors ------------------------------------------------- */ + + inline const std::string & label() const { + return labelstr; + } + + inline const std::string & name() const { + return namestr; + } + + /* --- mutators --------------------------------------------------- */ + + inline void set_label(const std::string & label) + { + labelstr.assign(label); + aux::to_label(labelstr); + } + + inline void set_label(const char *label) + { + if (label) { + labelstr.assign(label); + aux::to_label(labelstr); + } else { + labelstr.clear(); + } + } + + inline void set_name(const std::string & name) + { + namestr.assign(name); + } + + inline void set_name(const char *name) + { + if (name) + namestr.assign(name); + else + namestr.clear(); + } + +private: + std::string labelstr; + std::string namestr; + +}; // class Label + +} // namespace core + +#endif // __INCLUDED_CORE_LABEL_H__ diff --git a/src/filesystem/inifile.cc b/src/filesystem/inifile.cc index 52bf36d..e9ab283 100644 --- a/src/filesystem/inifile.cc +++ b/src/filesystem/inifile.cc @@ -101,6 +101,10 @@ bool IniFile::getline() if (s.size() == 0) { // empty line } else + // strip trailing EOL / FF characters + if ( (s[s.size() -1] == 0x0a) || (s[s.size() -1] == 0x0d)) + s.erase(s.size() -1); + // comment if (s[0] == '#' || s[0] == ';') { // condebug << "IniFile got comment " << s << std::endl; diff --git a/src/game/base/commodity.cc b/src/game/base/commodity.cc index a9eb8c8..d41d370 100644 --- a/src/game/base/commodity.cc +++ b/src/game/base/commodity.cc @@ -4,6 +4,7 @@ the terms and conditions of the GNU General Public License version 2 */ +#include "base/game.h" #include "base/commodity.h" #include "auxiliary/functions.h" #include "sys/sys.h" @@ -13,8 +14,11 @@ namespace game /* ---- class Commodity -------------------------------------------- */ +core::InfoType *Commodity::commodity_infotype = 0; + Commodity::Commodity() : core::Info() { + set_type(commodity_infotype); } Commodity::~Commodity() diff --git a/src/game/base/commodity.h b/src/game/base/commodity.h index e226505..b889749 100644 --- a/src/game/base/commodity.h +++ b/src/game/base/commodity.h @@ -16,6 +16,8 @@ class Commodity : public core::Info { public: Commodity(); ~Commodity(); + + static core::InfoType *commodity_infotype; }; } // namespace game diff --git a/src/game/base/game.cc b/src/game/base/game.cc index fa02857..c20e42a 100644 --- a/src/game/base/game.cc +++ b/src/game/base/game.cc @@ -823,68 +823,73 @@ bool Game::load_menus(core::Entity *entity, const std::string &menufilename) // read commodities bool Game::load_commodities() { - filesystem::IniFile commoditiesini; - commoditiesini.open("commodities"); - if (!commoditiesini.is_open()) { - con_error << "Could not open " << commoditiesini.name() << "!" << std::endl; + // initialize commodities InfoType + Commodity::commodity_infotype = new core::InfoType("cargo"); + + filesystem::IniFile cargoini; + cargoini.open("cargo"); + if (!cargoini.is_open()) { + con_error << "Could not open " << cargoini.name() << "!" << std::endl; return false; } - con_print << "^BLoading commodities..." << std::endl; + con_print << "^BLoading cargo..." << std::endl; size_t count = 0; Commodity *commodity = 0; std::string str; - while (commoditiesini.getline()) { - if (commoditiesini.got_key()) { + while (cargoini.getline()) { + if (cargoini.got_key()) { - if (commoditiesini.section().compare("commodity") == 0) { - if (commoditiesini.got_key_string("label", str)) { - commodity->set_label(std::string("cargo/" + str)); + if (cargoini.section().compare("cargo") == 0) { + if (cargoini.got_key_string("label", str)) { + commodity->set_label(std::string(str)); count++; continue; - } else if (commoditiesini.got_key_string("name", str)) { - con_debug << " " << str << std::endl; + } else if (cargoini.got_key_string("name", str)) { commodity->set_name(str); continue; - } else if (commoditiesini.got_key_string("info", str)) { + } else if (cargoini.got_key_string("info", str)) { commodity->add_text(str); continue; - } else if (commoditiesini.got_key_string("model", str)) { + } else if (cargoini.got_key_string("model", str)) { commodity->set_modelname(str); continue; } else { - commoditiesini.unkown_key(); + cargoini.unkown_key(); } } - } else if (commoditiesini.got_section()) { + } else if (cargoini.got_section()) { - if (commoditiesini.got_section("commodity")) { + if (cargoini.got_section("cargo")) { commodity = new Commodity(); - } else if (commoditiesini.got_section()) { - commoditiesini.unknown_section(); + } else if (cargoini.got_section()) { + cargoini.unknown_section(); } } } - // add commodity infos - con_debug << " " << commoditiesini.name() << " " << count << " commodities" << std::endl; + // add cargo infos + con_debug << " " << cargoini.name() << " " << count << " cargo types" << std::endl; - commoditiesini.close(); + cargoini.close(); return true; } // read ship model specifications bool Game::load_ships() { + // initialize shipmodel InfoType + ShipModel::shipmodel_infotype = new core::InfoType("ship"); + using math::Vector3f; using math::Color; @@ -896,28 +901,29 @@ bool Game::load_ships() } con_print << "^BLoading ships..." << std::endl; - - unsigned int type_id = 0; + + size_t count = 0; ShipModel *shipmodel = 0; - std::string label; - std::string infostr; + std::string str; long l; float f; + bool b; while (shipsini.getline()) { if (shipsini.got_key()) { if (shipsini.section().compare("ship") == 0) { - if (shipsini.got_key_string("label", label)) { - aux::to_label(label); - shipmodel->shipmodel_label.assign(label); - ShipModel::add(shipmodel); + if (shipsini.got_key_string("label", str)) { + shipmodel->set_label(str); + count++; continue; - } else if (shipsini.got_key_string("name", shipmodel->shipmodel_name)) { + } else if (shipsini.got_key_string("name", str)) { + shipmodel->set_name(str); continue; - } else if (shipsini.got_key_string("info", infostr)) { - shipmodel->shipmodel_infotext.push_back(infostr); + } else if (shipsini.got_key_string("info", str)) { + shipmodel->add_text(str); continue; - } else if (shipsini.got_key_string("model", shipmodel->shipmodel_modelname)) { + } else if (shipsini.got_key_string("model", str)) { + shipmodel->set_modelname(str); continue; } else if (shipsini.got_key_long("price", l)) { shipmodel->set_price(l); @@ -925,7 +931,8 @@ bool Game::load_ships() } else if (shipsini.got_key_float("cargo", f)) { shipmodel->set_maxcargo(f); continue; - } else if (shipsini.got_key_bool("jumpdrive", shipmodel->shipmodel_jumpdrive)) { + } else if (shipsini.got_key_bool("jumpdrive", b)) { + shipmodel->set_jumpdrive(b); continue; } else if (shipsini.got_key_float("acceleration", f)) { shipmodel->set_acceleration(f); @@ -942,22 +949,29 @@ bool Game::load_ships() } } } else if (shipsini.got_section("ship")) { - if (shipmodel && !ShipModel::find(shipmodel)) delete shipmodel; - type_id++; - shipmodel = new ShipModel(type_id); - if (!Default::shipmodel) + // generate info for the last loaded ship model + if (shipmodel) { + shipmodel->generate_info(); + } + + // add a new shipmodel + shipmodel = new ShipModel(); + + if (!Default::shipmodel) { Default::shipmodel = shipmodel; + } } else if (shipsini.got_section()) { shipsini.unknown_section(); } } - if (shipmodel && !ShipModel::find(shipmodel)) delete shipmodel; + // generate info for the last loaded ship model + if (shipmodel) { + shipmodel->generate_info(); + } - // add shipmodel infos - ShipModel::generate_info(); - con_debug << " " << shipsini.name() << " " << ShipModel::registry.size() << " ship models" << std::endl; + con_debug << " " << shipsini.name() << " " << count << " ship types" << std::endl; shipsini.close(); diff --git a/src/game/base/ship.cc b/src/game/base/ship.cc index 2c42ca8..7cdf2ca 100644 --- a/src/game/base/ship.cc +++ b/src/game/base/ship.cc @@ -41,7 +41,7 @@ Ship::Ship(core::Player *owner, ShipModel *shipmodel) : get_color_second().assign(owner->color_second()); ship_shipmodel = shipmodel; - ship_jumpdrive = shipmodel->shipmodel_jumpdrive; + ship_jumpdrive = shipmodel->jumpdrive(); ship_impulsedrive_timer = 0; ship_jumpdrive_timer = 0; @@ -68,7 +68,7 @@ void Ship::func_impulse() if (entity_state == core::Entity::Impulse) { entity_state = core::Entity::Normal; target_thrust = 1.0f; - entity_thrust = 1.0f; + entity_thrust = 0.0f; } else if (entity_state == core::Entity::ImpulseInitiate) { entity_state = core::Entity::Normal; diff --git a/src/game/base/shipdealer.cc b/src/game/base/shipdealer.cc index 54d3e90..69b4543 100644 --- a/src/game/base/shipdealer.cc +++ b/src/game/base/shipdealer.cc @@ -83,13 +83,8 @@ void ShipDealer::func_buy(core::Player *player, const std::string &args) } if (!shipmodel) { - std::string helpstr; - for (ShipModel::iterator smit = ShipModel::registry.begin(); smit != ShipModel::registry.end(); smit++) { - if (helpstr.size()) - helpstr.append("^N|^B"); - helpstr.append((*smit).second->label()); - } - player->send("Usage: buy ship [^B" + helpstr + "^N]"); + ShipModel::list(); + player->send("Usage: buy ship model"); return; } diff --git a/src/game/base/shipmodel.cc b/src/game/base/shipmodel.cc index fe1c88c..9bd7573 100644 --- a/src/game/base/shipmodel.cc +++ b/src/game/base/shipmodel.cc @@ -8,169 +8,83 @@ #include "auxiliary/functions.h" #include "base/shipmodel.h" +#include "base/game.h" #include "sys/sys.h" namespace game { -// the ship model registry -ShipModel::Registry ShipModel::registry; +core::InfoType *ShipModel::shipmodel_infotype = 0; -ShipModel::ShipModel(const unsigned int type_id) +ShipModel::ShipModel() { + set_type(shipmodel_infotype); + //default specifications shipmodel_acceleration = 1.0f; // thruster acceleration in game untits/second^2 shipmodel_maxspeed = 3.0f; // maximum thruster speed in game units/second shipmodel_turnspeed = 45.0f; // 45 degrees per second - shipmodel_price = 0; // the ship is for free by default shipmodel_maxcargo = 0; - shipmodel_jumpdrive = false; - shipmodel_type_id = type_id; + shipmodel_jumpdrive = false; // no jumpdrive capability } ShipModel::~ShipModel() -{} - - -// clear the ship model registry -void ShipModel::clear() -{ - for (iterator smit = registry.begin(); smit != registry.end(); smit++) { - delete(*smit).second; - } - registry.clear(); -} - -void ShipModel::print() { - con_print << "label: ^B" << label() << " ^Nname: ^B" << name() << std::endl; - con_print << " price: ^B" << price() << std::endl; - con_print << " acceleration: ^B" << acceleration() << std::endl; - con_print << " turnspeed: ^B" << turnspeed() << std::endl; - con_print << " max speed: ^B" << maxspeed() << std::endl; - con_print << " cargo: ^B" << maxcargo() << std::endl; } void ShipModel::generate_info() { - for (iterator it = registry.begin(); it != registry.end(); it++) { - ShipModel *shipmodel = (*it).second; - core::Info *info = new core::Info("ship/" + shipmodel->label()); - - info->clear_text(); - info->set_name(shipmodel->name()); - info->set_modelname(shipmodel->modelname()); - - // info text form ships.ini - for (core::Info::Text::iterator tit = shipmodel->shipmodel_infotext.begin(); - tit != shipmodel->shipmodel_infotext.end(); tit++) { - - info->add_text((*tit)); - } - - info->add_text(""); - info->add_text("^BSpecifications:^N"); - std::stringstream str; - str << "price: ^B" << shipmodel->price() << " ^Ncredits"; - info->add_text(str.str()); - str.str(""); - - str << "cargo hold: ^B" << 0.1f * shipmodel->maxcargo() << " ^Nmetric tonnes"; - info->add_text(str.str()); + clear_text(); + + add_text(""); + add_text("^B" + name() + " specifications:^N"); + std::stringstream str; + str << "price: ^B" << price() << " ^Ncredits"; + add_text(str.str()); + str.str(""); + + str << "cargo hold: ^B" << 0.1f * maxcargo() << " ^Nmetric tonnes"; + add_text(str.str()); + str.str(""); + + str << "top speed: ^B" << 100.0f * maxspeed() << " ^Nmps"; + add_text(str.str()); + str.str(""); + + str << "response: ^B" << turnspeed() << " ^Ndps"; + add_text(str.str()); + str.str(""); + + str << "acceleration: ^B" << acceleration() << " ^Nstandard"; + add_text(str.str()); + str.str(""); + + if (jumpdrive()) { + str << "hyperspace jump drive capable"; + add_text(str.str()); str.str(""); - - str << "top speed: ^B" << 100.0f * shipmodel->maxspeed() << " ^Nmps"; - info->add_text(str.str()); - str.str(""); - - str << "response: ^B" << shipmodel->turnspeed() << " ^Ndps"; - info->add_text(str.str()); - str.str(""); - - str << "acceleration: ^B" << shipmodel->acceleration() << " ^Nstandard"; - info->add_text(str.str()); - str.str(""); - - if (shipmodel->shipmodel_jumpdrive) { - str << "hyperspace jump drive capable"; - info->add_text(str.str()); - str.str(""); - } } } void ShipModel::list() { - for (iterator smit = registry.begin(); smit != registry.end(); smit++) { - con_print << std::setw(24) << (*smit).second->label() - << " ^B" << (*smit).second->name() << "\n"; - } - con_print << registry.size() << " registered ship models\n"; + core::Info::list_class(shipmodel_infotype); } -ShipModel *ShipModel::find(ShipModel *shipmodel) +ShipModel *ShipModel::find(const unsigned int id) { - for (iterator smit = registry.begin(); smit != registry.end(); smit++) { - if ((*smit).second == shipmodel) - return shipmodel; - } - - return 0; + return (ShipModel *) core::Info::find(shipmodel_infotype, id); } -ShipModel *ShipModel::find(const std::string label) +ShipModel *ShipModel::find(const std::string & label) { - if (!label.size()) - return 0; - - std::map::iterator it = registry.find(label); - if (it == registry.end()) - return 0; - else - return (*it).second; + return (ShipModel *) core::Info::find(shipmodel_infotype, label); } -ShipModel *ShipModel::search(const std::string searchname) +ShipModel *ShipModel::search(const std::string searchstr) { - if (!searchname.size()) - return 0; - - std::string strsearchkey(aux::lowercase(searchname)); - if (strsearchkey.size() < 3) { - return 0; - } - - std::string label; - std::string name; - - for (iterator smit = registry.begin(); smit != registry.end(); smit++) { - ShipModel *shipmodel = (*smit).second; - - label.assign(shipmodel->label()); - if (label.size() && (label.find(strsearchkey) != std::string::npos)) { - return shipmodel; - } - - name.assign(aux::lowercase(shipmodel->name())); - if (name.size() && (name.find(strsearchkey) != std::string::npos)) { - return shipmodel; - } - } - - return 0; -} - -// add a ship model -void ShipModel::add(ShipModel *shipmodel) -{ - ShipModel *m = find(shipmodel->label()); - if (m) { - con_warn << "Duplicate ship model " << shipmodel->label() << "!\n"; - delete m; - } - - registry[shipmodel->label()] = shipmodel; + return (ShipModel *) core::Info::search(shipmodel_infotype, searchstr); } } diff --git a/src/game/base/shipmodel.h b/src/game/base/shipmodel.h index d3048b2..19b2a77 100644 --- a/src/game/base/shipmodel.h +++ b/src/game/base/shipmodel.h @@ -7,7 +7,6 @@ #ifndef __INCLUDED_BASE_SHIPMODEL_H__ #define __INCLUDED_BASE_SHIPMODEL_H__ -#include #include #include "core/info.h" @@ -15,15 +14,23 @@ namespace game { -/// ship model specifications -class ShipModel +/// ship model specification +class ShipModel : public core::Info { public: - ShipModel(const unsigned int type_id); - ~ShipModel(); + /// default constructor + ShipModel(); - void print(); + /// default destructor + virtual ~ShipModel(); + /* ---- inspectors ------------------------------------------------ */ + + /// indicates if this model can be equiped with a jump drive + inline const bool jumpdrive() const { + return shipmodel_jumpdrive; + } + /// acceleration inline const float acceleration() const { return shipmodel_acceleration; @@ -39,36 +46,13 @@ public: return shipmodel_turnspeed; } - /// label of the ship model - inline const std::string &label() const { - return shipmodel_label; - } - - /// name of the ship model - inline const std::string & name() const { - return shipmodel_name; - } - - /// name of the model of the ship - inline const std::string & modelname() const { - return shipmodel_modelname; - } - - /// type id - inline unsigned int type_id() { - return shipmodel_type_id; - } - - /// price of the ship - inline const long price() const { - return shipmodel_price; - } - /// size of the cargo hold inline const float maxcargo() const { return shipmodel_maxcargo; } + /* ---- mutators -------------------------------------------------- */ + /// set acceleration inline void set_acceleration(const float acceleration) { shipmodel_acceleration = acceleration; @@ -84,66 +68,37 @@ public: shipmodel_turnspeed = turnspeed; } - /// set price - inline void set_price(const long price) { - shipmodel_price = price; - } - /// set size of the cargo hold inline void set_maxcargo(const float maxcargo) { shipmodel_maxcargo = maxcargo; } - /// indicates of this model can be equiped with a jump drive - bool shipmodel_jumpdrive; - - std::string shipmodel_label; - std::string shipmodel_name; - std::string shipmodel_modelname; - - /// info text - core::Info::Text shipmodel_infotext; - - /* ---- static registry ------------------------------------ */ + /// set jumpdrive capability + inline void set_jumpdrive(const bool jumpdrive) { + shipmodel_jumpdrive = jumpdrive; + } - typedef std::map Registry; + void generate_info(); - typedef std::map::iterator iterator; - - /// find an exact match - static ShipModel *find(ShipModel *shipmodel); - - /// find an exact match - static ShipModel *find(const std::string label); - - /// search the registry - static ShipModel *search(const std::string label); - - /// the ship model registry - static std::map registry; + /* --- static registry functions ---------------------------------- */ + + static void list(); + + static ShipModel *find(const unsigned int id); - /// clear the ship model registry - static void clear(); + static ShipModel *find(const std::string & label); - /// list the ship model registry - static void list(); + static ShipModel *search(const std::string searchstr); - /// add a new ship model - static void add(ShipModel *shipmodel); - - /// generate info records - static void generate_info(); + static core::InfoType *shipmodel_infotype; private: - + bool shipmodel_jumpdrive; + float shipmodel_acceleration; float shipmodel_maxspeed; float shipmodel_turnspeed; float shipmodel_maxcargo; - - long shipmodel_price; - - unsigned int shipmodel_type_id; }; } diff --git a/src/ui/Makefile.am b/src/ui/Makefile.am index 3b4bcd1..561935c 100644 --- a/src/ui/Makefile.am +++ b/src/ui/Makefile.am @@ -11,7 +11,7 @@ noinst_HEADERS = bitmap.h button.h console.h container.h definitions.h font.h \ iconbutton.h inputbox.h label.h menu.h modelview.h paint.h palette.h scrollpane.h toolbar.h ui.h widget.h \ window.h -libui_la_SOURCES = bitmap.cc button.cc console.cc console.h container.cc \ +libui_la_SOURCES = bitmap.cc button.cc console.cc container.cc \ font.cc iconbutton.cc inputbox.cc label.cc menu.cc modelview.cc paint.cc palette.cc scrollpane.cc \ toolbar.cc ui.cc widget.cc window.cc libui_la_LDFLAGS = -avoid-version -no-undefined -- cgit v1.2.3