diff options
34 files changed, 774 insertions, 261 deletions
diff --git a/src/client/chat.cc b/src/client/chat.cc index c49550e..25b437c 100644 --- a/src/client/chat.cc +++ b/src/client/chat.cc @@ -213,23 +213,37 @@ void Chat::set_prompt() void Chat::draw() { if (!chat_small && (chat_playerlist_timestamp != core::game()->playerlist_timestamp())) { - update_player_list(); + refresh(); } set_prompt(); ui::Window::draw(); } -void Chat::update_player_list() +void Chat::refresh() { chat_playerlist->clear(); + ui::ListItem *listitem = 0; + /* + listitem = new ui::ListItem(chat_playerlist, "Shout"); + listitem->set_height(listitem->font()->height() * 2.0f); + listitem->set_sortkey(" 0"); + + listitem = new ui::ListItem(chat_playerlist, "Say"); + listitem->set_height(listitem->font()->height() * 2.0f); + listitem->set_sortkey(" 1"); + */ for (core::GameInterface::Players::const_iterator it = core::game()->players().begin(); it != core::game()->players().end(); it++) { - ui::ListItem *listitem = new ui::ListItem(chat_playerlist, (*it)->name().c_str()); - listitem->set_height(listitem->font()->height() * 1.5f); + std::string descr(aux::text_strip((*it)->name().c_str())); + if ((*it)->zone()) { + descr.append("\n^N"); + descr.append(aux::pad_left((*it)->zone()->name(), 20)); + } + listitem = new ui::ListItem(chat_playerlist, descr.c_str()); + listitem->set_height(listitem->font()->height() * 3.0f); listitem->set_sortkey(aux::text_strip_lowercase((*it)->name())); - } - + } chat_playerlist->sort(); chat_playerlist_timestamp = core::game()->playerlist_timestamp(); @@ -259,7 +273,7 @@ void Chat::resize() // resize player names listview chat_playerlist->set_location(padding, chat_titlelabel->bottom() + padding); - chat_playerlist->set_size(ui::UI::elementsize.width() * 1.5f, height() - chat_playerlist->top() - padding * 2.0f); + chat_playerlist->set_size(ui::UI::elementsize.width(), height() - chat_playerlist->top() - padding * 2.0f); // resize chat text pane chat_scrollpane->set_location(chat_playerlist->right() + padding, chat_titlelabel->bottom() + padding); diff --git a/src/client/chat.h b/src/client/chat.h index 9b64297..eaaed10 100644 --- a/src/client/chat.h +++ b/src/client/chat.h @@ -54,7 +54,7 @@ protected: private: - void update_player_list(); + void refresh(); bool chat_small; ui::Text chat_log; diff --git a/src/client/inventorywindow.cc b/src/client/inventorywindow.cc index 7912d0d..9539061 100644 --- a/src/client/inventorywindow.cc +++ b/src/client/inventorywindow.cc @@ -68,6 +68,7 @@ InventoryWindow::InventoryWindow(ui::Widget *parent) : ui::Window(parent) inventorywindow_shipbutton = new ui::IconButton(this, "bitmaps/icons/button_ship"); inventorywindow_ejectbutton = new ui::IconButton(this, "bitmaps/icons/button_eject"); + inventorywindow_mountbutton = new ui::IconButton(this, "bitmaps/icons/button_mount"); // eject dialog inventorywindow_ejectconfirmbutton = new ui::Button(inventorywindow_scrollpane, "Eject"); @@ -209,6 +210,9 @@ void InventoryWindow::resize() inventorywindow_ejectbutton->set_size(icon_size, icon_size); inventorywindow_ejectbutton->set_location(inventorywindow_inventorytext->right() - icon_size, height() - icon_size - padding); + inventorywindow_mountbutton->set_size(icon_size, icon_size); + inventorywindow_mountbutton->set_location(inventorywindow_ejectbutton->left() - icon_size - padding, height() - icon_size - padding); + // resize modelview inventorywindow_modelview->set_size( width() - inventorywindow_listview->right() - padding * 2.0f ,ui::UI::elementsize.width()); inventorywindow_modelview->set_location(inventorywindow_listview->right() + padding, padding * 3.0f); @@ -335,12 +339,29 @@ void InventoryWindow::act_eject() show_item_info(0); } +void InventoryWindow::act_mount() +{ + if (!inventorywindow_listview->selected()) { + return; + } + if (!inventorywindow_listview->selected()->item()) { + return; + } + + std::ostringstream cmdstr; + + cmdstr << "remote mount "; + cmdstr << inventorywindow_listview->selected()->item()->id(); + core::CommandBuffer::exec(cmdstr.str()); +} + void InventoryWindow::show_item_info(const ui::ListItem *listitem) { if (listitem) { set_info(listitem->info(), listitem->item()->amount()); if (listitem->item()->amount()) { inventorywindow_ejectbutton->enable(); + inventorywindow_mountbutton->enable(); } } else { set_info(0, 0); @@ -353,6 +374,7 @@ void InventoryWindow::set_info(const core::Info *info, const int amount) inventorywindow_infotext.clear(); inventorywindow_amount = amount; inventorywindow_ejectbutton->disable(); + inventorywindow_mountbutton->disable(); inventorywindow_ejectconfirmbutton->hide(); inventorywindow_ejectcancelbutton->hide(); @@ -393,8 +415,9 @@ bool InventoryWindow::on_emit(Widget *sender, const Event event, void *data) } else if (sender == inventorywindow_ejectcancelbutton) { show_item_info(inventorywindow_listview->selected()); } else if (sender == inventorywindow_ejectconfirmbutton) { - // TODO do actual eject act_eject(); + } else if (sender == inventorywindow_mountbutton) { + act_mount(); } else if (sender == inventorywindow_closebutton) { hide(); } diff --git a/src/client/inventorywindow.h b/src/client/inventorywindow.h index e32bf44..239ff11 100644 --- a/src/client/inventorywindow.h +++ b/src/client/inventorywindow.h @@ -57,6 +57,8 @@ private: void act_eject(); + void act_mount(); + void show_item_info(const ui::ListItem *listitem); bool verify() const; @@ -83,6 +85,8 @@ private: ui::ScrollPane *inventorywindow_scrollpane; ui::IconButton *inventorywindow_shipbutton; + ui::IconButton *inventorywindow_mountbutton; + ui::IconButton *inventorywindow_ejectbutton; ui::Button *inventorywindow_ejectconfirmbutton; ui::Button *inventorywindow_ejectcancelbutton; diff --git a/src/client/mapwindow.cc b/src/client/mapwindow.cc index e6bc5bb..c8ebaa8 100644 --- a/src/client/mapwindow.cc +++ b/src/client/mapwindow.cc @@ -7,6 +7,8 @@ #include "audio/audio.h" #include "core/application.h" +#include "core/entity.h" +#include "core/entityglobe.h" #include "client/mapwindow.h" #include "client/targets.h" #include "ui/ui.h" diff --git a/src/client/video.cc b/src/client/video.cc index 7f15eea..a75089f 100644 --- a/src/client/video.cc +++ b/src/client/video.cc @@ -363,9 +363,10 @@ void frame(float elapsed) render::draw(elapsed); // draw the world targets::frame(); // validate current target, render sound + /* if (!core::localplayer()->view() && targets::current()) // draw target docks etc render::draw_target(targets::current()); - + */ render::Camera::ortho(); client()->mainwindow()->show(); diff --git a/src/core/Makefile.am b/src/core/Makefile.am index d198cc4..6f2a505 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -10,6 +10,7 @@ noinst_HEADERS = \ cvar.h \ descriptions.h \ entity.h \ + entityglobe.h \ extension.h \ func.h \ gameconnection.h \ @@ -44,6 +45,7 @@ libcore_la_SOURCES = \ cvar.cc \ descriptions.cc \ entity.cc \ + entityglobe.cc \ extension.cc \ func.cc \ gameconnection.cc \ diff --git a/src/core/entity.cc b/src/core/entity.cc index 462a46d..64546a7 100644 --- a/src/core/entity.cc +++ b/src/core/entity.cc @@ -278,7 +278,7 @@ void Entity::print_inventory() const return; } - con_print << " ^Nitem info infotype amount" << std::endl; + con_print << " ^Nitem infotype info amount flags" << std::endl; for (Inventory::Items::const_iterator it = entity_inventory->items().begin(); it != entity_inventory->items().end(); it++) { Item *item = (*it); // TODO item flags @@ -286,7 +286,20 @@ void Entity::print_inventory() const << " ^B" << std::setw(4) << item->id() << " ^N" << aux::pad_right((item->info()->type() ? item->info()->type()->label() : "NULL"), 8) << " ^N" << aux::pad_right(item->info()->label(), 24) - << std::setw(5) << item->amount() << std::endl; + << std::setw(5) << item->amount(); + if (item->has_flag(core::Item::Tradeable)) { + con_print << " tradeable"; + } + if (item->has_flag(core::Item::Unique)) { + con_print << " unique"; + } + if (item->has_flag(core::Item::Unrestricted)) { + con_print << " unrestricted"; + } + if (item->has_flag(core::Item::Mounted)) { + con_print << " mounted"; + } + con_print<< std::endl; } con_print << "^B " << entity_inventory->items().size() << " inventory items" << std::endl; } @@ -1460,58 +1473,5 @@ void EntityControlable::frame(const unsigned long elapsed) } } - -/*----- EntityGlobe ------------------------------------------------ */ - -EntityGlobe::EntityGlobe() : Entity() -{ - entity_texture_id = 0; - entity_corona_id = 0; - entity_rotationspeed = 0; - set_shape(Sphere); -} - -EntityGlobe::EntityGlobe(std::istream & is) : Entity(is) -{ - entity_texture_id = 0; - entity_corona_id = 0; - entity_rotationspeed = 0; - set_shape(Sphere); -} - -EntityGlobe::~EntityGlobe() -{ -} - -void EntityGlobe::serialize_server_create(std::ostream & os) const -{ - Entity::serialize_server_create(os); - os << entity_rotationspeed << " \"" << texturename() << "\" \"" << coronaname() << "\" "; -} - -void EntityGlobe::receive_server_create(std::istream &is) -{ - Entity::receive_server_create(is); - - is >> entity_rotationspeed; - - std::string n; - char c; - - // read texture name - while ((is.get(c)) && (c != '"')); - while ((is.get(c)) && (c != '"')) - n += c; - - entity_texturename.assign(n); - - // read corona name - n.clear(); - while ((is.get(c)) && (c != '"')); - while ((is.get(c)) && (c != '"')) - n += c; - entity_coronaname.assign(n); -} - -} +} //namespace core diff --git a/src/core/entity.h b/src/core/entity.h index d3c8522..31ed67b 100644 --- a/src/core/entity.h +++ b/src/core/entity.h @@ -50,16 +50,16 @@ public: * ShowOnMap will make the entity appear on the map * KeepAlive is used by EntityDynamic and marks the entity as deletable in the keepalive run * */ - enum Flags {NonSolid = 2, Bright = 4, Dockable = 8, ShowOnMap = 16, KeepAlive = 32}; + enum Flags { NonSolid = 2, Bright = 4, Dockable = 8, ShowOnMap = 16, KeepAlive = 32 }; /// Entity type constants - enum Type {Default = 0, Dynamic = 1, Controlable = 2, Globe = 3}; + enum Type { Default = 0, Dynamic = 1, Controlable = 2, Globe = 3, Projectile = 4 }; /// Entity shape constants - enum Shape {Diamond = 0, Sphere = 1, Cube = 2, Axis = 3}; + enum Shape { Diamond = 0, Sphere = 1, Cube = 2, Axis = 3 }; /// EntityDynamic State constants - enum State {Normal = 0, NoPower = 1, ImpulseInitiate = 2, Impulse = 3, JumpInitiate = 4, Jump = 5, Docked = 6, Destroyed = 7}; + enum State { Normal = 0, NoPower = 1, ImpulseInitiate = 2, Impulse = 3, JumpInitiate = 4, Jump = 5, Docked = 6, Destroyed = 7 }; /// entity menus collection typedef typedef std::list<MenuDescription *> Menus; @@ -854,86 +854,7 @@ private: }; -/// a Globe entity -class EntityGlobe : public Entity -{ -public: - /// server-side constructor - EntityGlobe(); - EntityGlobe(std::istream & is); - - virtual ~EntityGlobe(); - - /*----- inspectors ----------------------------------------------- */ - /// core type id - virtual inline const unsigned int type() const { - return Entity::Globe; - } - - /// texture name - inline const std::string &texturename() const { - return entity_texturename; - } - - /// texture render id - inline size_t texture_id() const { - return entity_texture_id; - } - - /// corona texture name - inline const std::string &coronaname() const { - return entity_coronaname; - } - - /// corona texture id - inline size_t corona_id() const { - return entity_corona_id; - } - - /// rotation speed in degrees per second - inline float rotationspeed() const { - return entity_rotationspeed; - } - - /*----- mutators -------------------------------------------------- */ - - inline void set_rotationspeed(const float rotationspeed) { - entity_rotationspeed = rotationspeed; - } - - inline void set_texture_id(size_t texture_id) { - entity_texture_id = texture_id; - } - - inline void set_corona_id(size_t texture_id) { - entity_corona_id = texture_id; - } - - inline void set_texturename(const std::string & texturename) { - entity_texturename.assign(texturename); - } - - inline void set_coronaname(const std::string & texturename) { - entity_coronaname.assign(texturename); - } - - /*----- serializers ----------------------------------------------- */ - - /// serialize the entity to a stream - virtual void serialize_server_create(std::ostream & os) const; - - /// receive a server-to-client create from a stream - virtual void receive_server_create(std::istream &is); - -private: - float entity_rotationspeed; - size_t entity_texture_id; - size_t entity_corona_id; - std::string entity_texturename; - std::string entity_coronaname; -}; - -} +} // namespace core #endif // __INCLUDED_CORE_ENTITY_H__ diff --git a/src/core/entityglobe.cc b/src/core/entityglobe.cc new file mode 100644 index 0000000..c27e05c --- /dev/null +++ b/src/core/entityglobe.cc @@ -0,0 +1,68 @@ +/* + core/entityglobe.cc + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2. +*/ + +#include <vector> +#include <iomanip> +#include <cstring> + +#include "core/entityglobe.h" + +namespace core +{ + +/*----- EntityGlobe ------------------------------------------------ */ + +EntityGlobe::EntityGlobe() : Entity() +{ + entity_texture_id = 0; + entity_corona_id = 0; + entity_rotationspeed = 0; + set_shape(Sphere); +} + +EntityGlobe::EntityGlobe(std::istream & is) : Entity(is) +{ + entity_texture_id = 0; + entity_corona_id = 0; + entity_rotationspeed = 0; + set_shape(Sphere); +} + +EntityGlobe::~EntityGlobe() +{ +} + +void EntityGlobe::serialize_server_create(std::ostream & os) const +{ + Entity::serialize_server_create(os); + os << entity_rotationspeed << " \"" << texturename() << "\" \"" << coronaname() << "\" "; +} + +void EntityGlobe::receive_server_create(std::istream &is) +{ + Entity::receive_server_create(is); + + is >> entity_rotationspeed; + + std::string n; + char c; + + // read texture name + while ((is.get(c)) && (c != '"')); + while ((is.get(c)) && (c != '"')) + n += c; + + entity_texturename.assign(n); + + // read corona name + n.clear(); + while ((is.get(c)) && (c != '"')); + while ((is.get(c)) && (c != '"')) + n += c; + entity_coronaname.assign(n); +} + +} // namespace core diff --git a/src/core/entityglobe.h b/src/core/entityglobe.h new file mode 100644 index 0000000..e60f61a --- /dev/null +++ b/src/core/entityglobe.h @@ -0,0 +1,96 @@ +/* + core/entityglobe.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_ENTITYGLOBE_H__ +#define __INCLUDED_CORE_ENTITYGLOBE_H__ + +#include "core/entity.h" + +namespace core +{ + +/// a Globe entity +class EntityGlobe : public Entity +{ +public: + /// server-side constructor + EntityGlobe(); + EntityGlobe(std::istream & is); + + virtual ~EntityGlobe(); + + /*----- inspectors ----------------------------------------------- */ + /// core type id + virtual inline const unsigned int type() const { + return Entity::Globe; + } + + /// texture name + inline const std::string &texturename() const { + return entity_texturename; + } + + /// texture render id + inline size_t texture_id() const { + return entity_texture_id; + } + + /// corona texture name + inline const std::string &coronaname() const { + return entity_coronaname; + } + + /// corona texture id + inline size_t corona_id() const { + return entity_corona_id; + } + + /// rotation speed in degrees per second + inline float rotationspeed() const { + return entity_rotationspeed; + } + + /*----- mutators -------------------------------------------------- */ + + inline void set_rotationspeed(const float rotationspeed) { + entity_rotationspeed = rotationspeed; + } + + inline void set_texture_id(size_t texture_id) { + entity_texture_id = texture_id; + } + + inline void set_corona_id(size_t texture_id) { + entity_corona_id = texture_id; + } + + inline void set_texturename(const std::string & texturename) { + entity_texturename.assign(texturename); + } + + inline void set_coronaname(const std::string & texturename) { + entity_coronaname.assign(texturename); + } + + /*----- serializers ----------------------------------------------- */ + + /// serialize the entity to a stream + virtual void serialize_server_create(std::ostream & os) const; + + /// receive a server-to-client create from a stream + virtual void receive_server_create(std::istream &is); + +private: + float entity_rotationspeed; + size_t entity_texture_id; + size_t entity_corona_id; + std::string entity_texturename; + std::string entity_coronaname; +}; + +} + +#endif // __INCLUDED_CORE_ENTITYGLOBE_H__ diff --git a/src/core/netconnection.cc b/src/core/netconnection.cc index 24f6a3d..ce8fc8c 100644 --- a/src/core/netconnection.cc +++ b/src/core/netconnection.cc @@ -11,6 +11,8 @@ #include "sys/sys.h" #include "core/application.h" +#include "core/entity.h" +#include "core/entityglobe.h" #include "core/gameconnection.h" #include "core/netconnection.h" #include "core/player.h" diff --git a/src/core/parser.cc b/src/core/parser.cc index 01d4dba..1c66888 100644 --- a/src/core/parser.cc +++ b/src/core/parser.cc @@ -5,6 +5,8 @@ */ #include "auxiliary/functions.h" +#include "core/entity.h" +#include "core/entityglobe.h" #include "core/parser.h" #include "sys/sys.h" diff --git a/src/core/slot.cc b/src/core/slot.cc index bb7b622..e1ccd05 100644 --- a/src/core/slot.cc +++ b/src/core/slot.cc @@ -28,6 +28,18 @@ Slot::~Slot() { } +void Slot::set_flag(const Flags flag) +{ + slot_flags = (slot_flags | (unsigned int) flag); + set_timestamp(game() ? game()->timestamp() : 1); +} + +void Slot::unset_flag(const Flags flag) +{ + slot_flags = slot_flags & ~((unsigned int) flag); + set_timestamp(game() ? game()->timestamp() : 1); +} + void Slot::set_projectile_speed(const float projectile_speed) { slot_projectile_speed = projectile_speed; diff --git a/src/core/slot.h b/src/core/slot.h index 2d636b3..5cfeb3e 100644 --- a/src/core/slot.h +++ b/src/core/slot.h @@ -22,7 +22,7 @@ namespace core * */ class Slot { public: - enum Flags {Active = 1}; + enum Flags {Mounted = 1, Active = 2}; /** * @brief default constructor @@ -52,6 +52,30 @@ public: } /** + * @brief slot flags + * */ + inline const unsigned int flags() const + { + return slot_flags; + } + + /** + * @brief return true if a specified flag is set + * */ + inline const bool has_flag(const Flags flag) + { + return ( (slot_flags & flag) == flag ); + } + + /** + * @brief the item this slot is holding + * */ + inline core::Item *item() + { + return slot_item; + } + + /** * @brief timestamp indicating when the slot was last fired,server-side * This is a server-side property * */ @@ -128,6 +152,16 @@ public: } /** + * @brief set a specified flags + * */ + void set_flag(const Flags flag); + + /** + * @brief unset a specified flags + * */ + void unset_flag(const Flags flag); + + /** * @brief set the slot's timestamp * The timestamp indicates when the slot's configuration was last changed. * */ diff --git a/src/game/base/game.cc b/src/game/base/game.cc index 2355a9e..1020fa8 100644 --- a/src/game/base/game.cc +++ b/src/game/base/game.cc @@ -340,9 +340,10 @@ void Game::func_give(core::Player *player, const std::string &args) } // transfer inventory - for (core::Inventory::Items::iterator it = player->control()->inventory()->items().begin(); - it != player->control()->inventory()->items().end(); it++) { - ship->inventory()->add(new core::Item(*(*it))); + for (core::Inventory::Items::iterator it = player->control()->inventory()->items().begin(); it != player->control()->inventory()->items().end(); it++) { + core::Item *item = new core::Item(*(*it)); + item->unset_flag(core::Item::Mounted); + ship->inventory()->add(item); } ship->inventory()->set_dirty(); @@ -973,7 +974,7 @@ void Game::func_drop(core::Player *player, const std::string &args) // cannot drop items while jumping if ((ship->state() == core::Entity::Jump) || (ship->state() == core::Entity::JumpInitiate)) { - player->send("^WCan not eject while hyperspace jump drive is active"); + player->send("^WCan not drop items while hyperspace jump drive is active"); return; } @@ -1112,9 +1113,10 @@ void Game::func_eject(core::Player *player, const std::string &args) pod->add_inventory(); pod->inventory()->set_capacity(item->info()->volume() * amount); - core::Item *loot = new core::Item(item->info()); + core::Item *loot = new core::Item(item->info()); loot->set_amount(amount); loot->set_flags(item->flags()); + loot->unset_flag(core::Item::Mounted); pod->inventory()->add(loot); pod->inventory()->set_dirty(); @@ -1134,11 +1136,147 @@ void Game::func_eject(core::Player *player, const std::string &args) } if (item->amount() == 0) { + if (item->has_flag(core::Item::Mounted)) { + // unmount + core::Slot *slot = 0; + + for(core::Slots::iterator it = ejector->slots()->begin(); (!slot) && (it != ejector->slots()->end()); ++it) { + if ((*it)->item() == item) { + slot = (*it); + } + } + + if (slot) { + slot->set_item(0); + slot->unset_flag(core::Slot::Active); + slot->unset_flag(core::Slot::Mounted); + item->unset_flag(core::Item::Mounted); + } + + } ejector->inventory()->erase(item->id()); } ejector->inventory()->set_dirty(); } +// mount weapons into slots +void Game::func_mount(core::Player *player, const std::string &args) +{ + if (!player->control()) { + return; + } + + Ship *ship = static_cast<Ship *>(player->control()); + + if (!ship->slots()) { + return; + } + + std::istringstream is(args); + unsigned int id = 0; + + if (!(is >> id)) { + ship->owner()->send("Usage: mount [id] mount weapon with id into the first available slot"); + return; + } + + // find item to be mounted + core::Item *item = ship->inventory()->find(id); + if (!item) { + if (ship->owner()) { + std::stringstream msgstr; + msgstr << "^WItem " << id << " not in inventory"; + ship->owner()->send(msgstr.str()); + } + return; + } + + // verify item is mountable + if (item->info()->type() != Weapon::infotype()) { + if (ship->owner()) { + std::stringstream msgstr; + msgstr << "^WItem " << id << " can not be mounted"; + ship->owner()->send(msgstr.str()); + } + return; + } + const Weapon *weapon = static_cast<const Weapon *>(item->info()); + + if (!item->unique() || (weapon->subtype() != Weapon::Cannon)) { + if (ship->owner()) { + std::stringstream msgstr; + msgstr << "^WItem " << id << " can not be mounted"; + ship->owner()->send(msgstr.str()); + } + return; + } + + if (item->has_flag(core::Item::Mounted)) { + // unmount + core::Slot *slot = 0; + + for(core::Slots::iterator it = ship->slots()->begin(); (!slot) && (it != ship->slots()->end()); ++it) { + if ((*it)->item() == item) { + slot = (*it); + } + } + + if (slot) { + slot->set_item(0); + slot->unset_flag(core::Slot::Active); + slot->unset_flag(core::Slot::Mounted); + item->unset_flag(core::Item::Mounted); + + if (ship->owner()) { + std::stringstream msgstr; + msgstr << "^BUnmounted " << weapon->name(); + ship->owner()->send(msgstr.str()); + } + } + + } else { + // mount + core::Slot *slot = 0; + + for(core::Slots::iterator it = ship->slots()->begin(); (!slot) && (it != ship->slots()->end()); ++it) { + if (!(*it)->has_flag(core::Slot::Mounted)) { + slot = (*it); + } + } + + if (!slot) { + if (ship->owner()) { + std::stringstream msgstr; + msgstr << "^WNo slot available to mount item " << id; + ship->owner()->send(msgstr.str()); + } + return; + } else { + slot->set_item(item); + slot->set_flag(core::Slot::Active); + slot->set_flag(core::Slot::Mounted); + item->set_flag(core::Item::Mounted); + + slot->set_projectile_damage(weapon->damage()); + slot->set_projectile_speed(weapon->projectile_speed()); + slot->set_projectile_lifespan(weapon->projectile_lifespan()); + slot->set_projectile_interval(weapon->projectile_interval()); + slot->set_projectile_modelname(weapon->projectile_modelname()); + + if (ship->owner()) { + std::stringstream msgstr; + msgstr << "^BMounted " << weapon->name(); + ship->owner()->send(msgstr.str()); + } + } + } +} + +// unmount weapons from slots +void Game::func_unmount(core::Player *player, const std::string &args) +{ +} + // beam in nearby cargo pods void Game::func_beam(core::Player *player, const std::string &args) { @@ -1180,6 +1318,8 @@ void Game::func_beam(core::Player *player, const std::string &args) } if (!iteminv) { iteminv = new core::Item(item->info()); + iteminv->set_flags(item->flags()); + iteminv->unset_flag(core::Item::Mounted); inventory->add(iteminv); } item->dec_amount(negotiated_amount); @@ -1424,7 +1564,10 @@ Game::Game() : core::Module("Project::OSiRiON", true) func->set_info("[label] drop an item and activate it"); func = core::Func::add("eject", Game::func_eject); - func->set_info("[string] [string] [int] eject an item from inventory: specify type, label and amount"); + func->set_info("[int] eject item with id from inventory"); + + func = core::Func::add("mount", Game::func_mount); + func->set_info("[int] mount a weapon into the first available slot"); func = core::Func::add("beam", Game::func_beam); func->set_info("beam nearby cargo pods in"); diff --git a/src/game/base/game.h b/src/game/base/game.h index d030367..f535ec9 100644 --- a/src/game/base/game.h +++ b/src/game/base/game.h @@ -133,6 +133,8 @@ private: static void func_specs(core::Player *player, const std::string &args); static void func_eject(core::Player *player, const std::string &args); static void func_drop(core::Player *player, std::string const &args); + static void func_mount(core::Player *player, const std::string &args); + static void func_unmount(core::Player *player, const std::string &args); static void func_beam(core::Player *player, const std::string &args); /* ---- target functions ----------------------------------- */ diff --git a/src/game/base/planet.h b/src/game/base/planet.h index 337bab2..6b97d40 100644 --- a/src/game/base/planet.h +++ b/src/game/base/planet.h @@ -7,7 +7,7 @@ #ifndef __INCLUDED_BASE_PLANET_H__ #define __INCLUDED_BASE_PLANET_H__ -#include "core/entity.h" +#include "core/entityglobe.h" #include "math/mathlib.h" #include <string> diff --git a/src/game/base/projectile.cc b/src/game/base/projectile.cc index 6bcbad9..4dd483d 100644 --- a/src/game/base/projectile.cc +++ b/src/game/base/projectile.cc @@ -13,16 +13,16 @@ namespace game { -Projectile::Projectile(unsigned long lifespan) : EntityDynamic() +EntityProjectile::EntityProjectile(unsigned long lifespan) : EntityDynamic() { entity_moduletypeid = projectile_enttype; //set_name(""); - //set_label(""); + set_label("projectile"); //set_serverside(true); set_flag(core::Entity::KeepAlive); set_shape(core::Entity::Sphere); - set_radius(0.02f); + set_radius(0.01f); set_mass(radius()); //reset(); @@ -36,17 +36,17 @@ Projectile::Projectile(unsigned long lifespan) : EntityDynamic() projectile_ownerid = 0; } -Projectile::~Projectile() +EntityProjectile::~EntityProjectile() { } -void Projectile::upkeep(const unsigned long timestamp) +void EntityProjectile::upkeep(const unsigned long timestamp) { die(); } -void Projectile::collision(core::Entity *other) +void EntityProjectile::collision(core::Entity *other) { if (state() == core::Entity::Destroyed) { return; @@ -56,7 +56,7 @@ void Projectile::collision(core::Entity *other) // this method is a bullet callback, we can not reset() here } -void Projectile::frame(const unsigned long elapsed) +void EntityProjectile::frame(const unsigned long elapsed) { EntityDynamic::frame(elapsed); @@ -69,5 +69,106 @@ void Projectile::frame(const unsigned long elapsed) } } +void EntityProjectile::reset() +{ + // no bullet physics on NonSolid entities + if (!radius() || has_flag(NonSolid)) { + return; + } + + // remove Docked and Destroyed entities from the physics simulation + if (destroyed() || (state() == core::Entity::Docked) || (state() == core::Entity::Destroyed)) { + + if (entity_body) { + + if (entity_motionstate) { + delete entity_motionstate; + entity_motionstate = 0; + } + + if (zone() && zone()->physics()) { + entity_zone->physics()->removeRigidBody(body()); + } + + if (entity_collision_shape) { + delete entity_collision_shape; + entity_collision_shape = 0; + } + + for (CollisionShapes::iterator sit = entity_collision_child_shapes.begin(); sit != entity_collision_child_shapes.end(); sit++) { + delete (*sit); + (*sit) = 0; + } + entity_collision_child_shapes.clear(); + + if (entity_body) { + delete entity_body; + entity_body = 0; + } + + if (entity_body_info) { + delete entity_body_info; + entity_body_info = 0; + } + } + + return; + } + + // location and orientation + btTransform t; + t.setIdentity(); + t.setOrigin(to_btVector3(location())); + t.setBasis(to_btMatrix3x3(axis())); + + // construct physics body if necessary + if (!entity_body) { + // use a sphere with a radius matching the entity + btSphereShape *sphereshape = new btSphereShape(radius()); + entity_collision_shape = sphereshape; + + // set margin + //entity_collision_shape->setMargin(core::Cvar::sv_collisionmargin->value()); + + // calculate inertia + btVector3 inertia(0, 0, 0); + if (entity_mass) + entity_collision_shape->calculateLocalInertia(entity_mass, inertia); + + // create motion state + entity_motionstate = new btDefaultMotionState(t); + + // create physics body + entity_body_info = new btRigidBody::btRigidBodyConstructionInfo(entity_mass, entity_motionstate, entity_collision_shape, inertia); + entity_body = new btRigidBody(*entity_body_info); + // point the bullet user pointer to the entity + entity_body->setUserPointer((void *) this); + // enable custom collision callback + entity_body->setCollisionFlags(entity_body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); + //entity_body->setCollisionFlags(entity_body->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE); + + if (entity_mass) { + entity_body->setActivationState(DISABLE_DEACTIVATION); + } else { + entity_body->setActivationState(ISLAND_SLEEPING); + } + + if (zone()) + zone()->physics()->addRigidBody(entity_body); + } + + // transfer entity location to motion state + body()->setLinearVelocity(btVector3(0.0f, 0.0f, 0.0f)); + body()->setAngularVelocity(btVector3(0.0f, 0.0f, 0.0f)); + body()->setWorldTransform(t); + body()->clearForces(); + + if (motionstate()) { + motionstate()->setWorldTransform(t); + } + + set_dirty(); +} + } // namespace game diff --git a/src/game/base/projectile.h b/src/game/base/projectile.h index f9cda64..2513901 100644 --- a/src/game/base/projectile.h +++ b/src/game/base/projectile.h @@ -1,5 +1,5 @@ /* - base/spacemine.h + base/projectile.h This file is part of the Osirion project and is distributed under the terms and conditions of the GNU General Public License version 2 */ @@ -12,11 +12,11 @@ namespace game { -class Projectile : public core::EntityDynamic +class EntityProjectile : public core::EntityDynamic { public: - Projectile(unsigned long lifespan); - virtual ~Projectile(); + EntityProjectile(unsigned long lifespan); + virtual ~EntityProjectile(); virtual void upkeep(const unsigned long timestamp); @@ -58,6 +58,11 @@ public: /* --- mutators -------------------------------------------- */ /** + * @brief reset physics state + * */ + virtual void reset(); + + /** * @brief set the amount of damage this projectile inflicts * */ inline void set_damage(const float damage) diff --git a/src/game/base/ship.cc b/src/game/base/ship.cc index 7282fe1..fc01b5c 100644 --- a/src/game/base/ship.cc +++ b/src/game/base/ship.cc @@ -9,13 +9,15 @@ #include <iostream> #include "auxiliary/functions.h" +#include "math/functions.h" + #include "core/gameserver.h" #include "core/entity.h" + #include "base/game.h" #include "base/ship.h" #include "base/projectile.h" #include "base/spacemine.h" -#include "math/functions.h" using math::degrees360f; using math::degrees180f; @@ -85,14 +87,16 @@ Ship::Ship(core::Player *owner, const ShipModel *shipmodel) : core::EntityContro if (model()) { add_slots(); slots()->load(model()); - +/* for (core::Slots::iterator it = slots()->begin(); it != slots()->end(); it++) { // default fire rate: 1 projectile / second (*it)->set_projectile_interval(1000); (*it)->set_projectile_lifespan(5000); (*it)->set_projectile_speed(5.0f); (*it)->set_projectile_damage(10.0f); + (*it)->set_projectile_modelname("laser1"); } +*/ } // menus for docked players @@ -529,7 +533,7 @@ void Ship::collision(core::Entity *other) } else if (other->moduletype() == projectile_enttype) { // hit by projectile - Projectile * projectile = static_cast<Projectile *>(other); + game::EntityProjectile *projectile = static_cast<EntityProjectile *>(other); if (projectile->state() != core::Entity::Destroyed) { ship_armor -= projectile->damage(); } @@ -877,10 +881,10 @@ void Ship::frame(const unsigned long elapsed) for (core::Slots::iterator it = slots()->begin(); it != slots()->end(); it++) { // create projectiles - if ((*it)->projectile_interval() > 0) { + if ( ((*it)->projectile_interval() > 0) && ((*it)->has_flag(core::Slot::Mounted)) && ((*it)->has_flag(core::Slot::Active))) { if ((*it)->last_fired() + (*it)->projectile_interval() <= core::server()->timestamp()) { (*it)->set_last_fired(core::server()->timestamp()); - Projectile * projectile = new Projectile((*it)->projectile_lifespan()); + EntityProjectile * projectile = new EntityProjectile((*it)->projectile_lifespan()); projectile->set_damage((*it)->projectile_damage()); projectile->set_color(color()); if (owner()) { @@ -889,7 +893,8 @@ void Ship::frame(const unsigned long elapsed) projectile->set_zone(zone()); projectile->set_axis(axis() * (*it)->axis()); projectile->set_location(location() + (axis() * (*it)->location() * modelscale) + projectile->axis().forward() * projectile->radius()); - + projectile->set_modelname("maps/projectiles/" + (*it)->projectile_modelname()); + projectile->reset(); projectile->body()->setDamping(0.0f, 0.0f); projectile->body()->setLinearVelocity(math::to_btVector3(projectile->axis().forward() * (*it)->projectile_speed())); diff --git a/src/game/base/shipmodel.cc b/src/game/base/shipmodel.cc index fe8889d..ba01765 100644 --- a/src/game/base/shipmodel.cc +++ b/src/game/base/shipmodel.cc @@ -337,9 +337,10 @@ void ShipModel::buy(core::EntityControlable *buyer, core::Entity *seller) //ship->reset(); // reset() is done by set_dock() // transfer inventory - for (core::Inventory::Items::iterator it = player->control()->inventory()->items().begin(); - it != player->control()->inventory()->items().end(); it++) { - ship->inventory()->add(new core::Item(*(*it))); + for (core::Inventory::Items::iterator it = player->control()->inventory()->items().begin(); it != player->control()->inventory()->items().end(); it++) { + core::Item *item = new core::Item(*(*it)); + item->unset_flag(core::Item::Mounted); + ship->inventory()->add(item); } ship->inventory()->set_dirty(); diff --git a/src/game/base/star.h b/src/game/base/star.h index 12bec07..1e45dbb 100644 --- a/src/game/base/star.h +++ b/src/game/base/star.h @@ -8,7 +8,7 @@ #define __INCLUDED_BASE_STAR_H__ // project headers -#include "core/entity.h" +#include "core/entityglobe.h" #include "math/mathlib.h" // C++ headers diff --git a/src/game/base/weapon.h b/src/game/base/weapon.h index 94fdce6..b4a790c 100644 --- a/src/game/base/weapon.h +++ b/src/game/base/weapon.h @@ -45,6 +45,14 @@ public: } /** + * @brief lifespan of projectiles generated by this weapon, in milliseconds + * */ + inline const unsigned long projectile_lifespan() const + { + return weapon_projectile_lifespan; + } + + /** * @brief speed of projectiles generated by this weapon * */ inline const float projectile_speed() const diff --git a/src/game/intro/intro.cc b/src/game/intro/intro.cc index f5f7ab2..028a134 100644 --- a/src/game/intro/intro.cc +++ b/src/game/intro/intro.cc @@ -6,6 +6,8 @@ #include "intro/intro.h" #include "core/core.h" +#include "core/entity.h" +#include "core/entityglobe.h" #include "core/parser.h" #include "filesystem/filesystem.h" #include "filesystem/inifile.h" diff --git a/src/model/mapfile.cc b/src/model/mapfile.cc index fd82036..9badc9b 100644 --- a/src/model/mapfile.cc +++ b/src/model/mapfile.cc @@ -2045,11 +2045,25 @@ Model * MapFile::load(std::string const &name) model->set_origin(map_center * -1.0f); // translate transformed vertex groups + size_t frags = 0; for (Model::Groups::iterator git = model->groups().begin(); git != model->groups().end(); git++) { FragmentGroup *fragmentgroup = (*git); fragmentgroup->set_location(fragmentgroup->location() - map_center); + frags += fragmentgroup->size(); } + // set a sane radius if the mapfile is empty + if (frags == 0) { + const float r = SCALE; + model->model_box.assign( + math::Vector3f(-r, -r, -r), + math::Vector3f(r, r, r) + + ); + model->set_radius(model->box().max().length()); + } + + // translate tags for (Model::Lights::iterator lit = model->lights().begin(); lit != model->lights().end(); lit++) { (*lit)->get_location() -= map_center; @@ -2074,7 +2088,7 @@ Model * MapFile::load(std::string const &name) for (Model::Weapons::iterator wit = model->weapons().begin(); wit != model->weapons().end(); wit++) { (*wit)->get_location() -= map_center; } - + if (mapfile.warning_q2brush) con_warn << mapfile.name() << " quake2 style brushes detected" << std::endl; diff --git a/src/model/model.cc b/src/model/model.cc index f29350f..304e151 100644 --- a/src/model/model.cc +++ b/src/model/model.cc @@ -5,6 +5,7 @@ */ #include "sys/sys.h" +#include "auxiliary/functions.h" #include "model/model.h" #include "model/asefile.h" #include "model/mapfile.h" @@ -129,6 +130,10 @@ void Model::add_weapon(Weapon *weapon) model_weapons.push_back(weapon); } +void Model::print() const +{ +} + Model *Model::find(const std::string & name) { Registry::iterator it = model_registry.find(name); @@ -138,6 +143,27 @@ Model *Model::find(const std::string & name) return (*it).second; } +Model *Model::search(const std::string & searchname) +{ + std::string strsearchkey(aux::lowercase(searchname)); + std::stringstream str(strsearchkey); + + if (strsearchkey.size() < 3) { + return 0; + } + + for (Registry::iterator it = model_registry.begin(); it != model_registry.end(); it++) { + std::string label((*it).first); + Model *model= (*it).second; + + if (label.size() && (label.find(strsearchkey) != std::string::npos)) { + return model; + } + } + + return 0; +} + Model *Model::load(const std::string & name) { Model *model = find(name); @@ -178,22 +204,20 @@ void Model::clear() VertexArray::instance()->clear(); } -void Model::list_model(Model *model) -{ - size_t frags = 0; - for (Groups::iterator git = model->groups().begin(); git != model->groups().end(); git++) { - frags += (*git)->size(); - } - - con_print << " " << model->name() << " " << frags << " frags " << - model->model_tris_detail_count << "/" << model->model_tris_count << " detail/tris " << - model->model_quad_detail_count << "/" << model->model_quad_count << " detail/quads" << std::endl; -} - void Model::list() { for (Registry::iterator mit = model_registry.begin(); mit != model_registry.end(); mit++) { - list_model((*mit).second); + Model *model = (*mit).second; + size_t frags = 0; + + for (Groups::iterator git = model->groups().begin(); git != model->groups().end(); git++) { + frags += (*git)->size(); + } + + con_print << " " << model->name() << " " << frags << " frags " << + model->model_tris_detail_count << "/" << model->model_tris_count << " detail/tris " << + model->model_quad_detail_count << "/" << model->model_quad_count << " detail/quads " << + "radius " << model->radius() << std::endl; } diff --git a/src/model/model.h b/src/model/model.h index a33e365..3c94ad6 100644 --- a/src/model/model.h +++ b/src/model/model.h @@ -74,11 +74,15 @@ public: return model_radius; } - /// additional model fragment groups + /// print information about the model to console + void print() const; + + /// model fragment groups inline Groups & groups() { return model_groups; } + /// associated collisionmodel inline CollisionModel *collisionmodel() { return model_collisionmodel; } @@ -191,10 +195,16 @@ public: return model_registry; } - /// get name model, returns 0 if not found + /// search the model registry static Model *find(const std::string & name); + + /// search the model registry for a partial name + static Model *search(const std::string & searchname); - /// get named model from the registry and load it if necessary + /** + * @brief load a model + * If the model has already been loaded, a pointer to the existing instance will be returned + * */ static Model *load(const std::string & name); /// clear the model registry @@ -203,10 +213,6 @@ public: /// list the content of the model registry static void list(); - /// list one model - static void list_model(Model *model); - - private: std::string model_name; Docks model_docks; diff --git a/src/render/draw.cc b/src/render/draw.cc index 12a64ad..dea0c6b 100644 --- a/src/render/draw.cc +++ b/src/render/draw.cc @@ -8,6 +8,8 @@ #include <iomanip> #include "core/application.h" +#include "core/entity.h" +#include "core/entityglobe.h" #include "core/gameinterface.h" #include "core/range.h" @@ -727,7 +729,9 @@ void draw_model_axis(const core::Entity *entity) void draw_pass_model_fragments() { /* - * FIXME + * FIXME + * fragmentgroups with movement tied to engine activity can not be synchronized with server-side collision + * * For moving and rotating fragmentgroups, the enginetime must match * the time used by core:: to calculate the rotation or movement * of the asssociated collision models. @@ -756,8 +760,9 @@ void draw_pass_model_fragments() ext_render(entity)->thrust() ); - if (entity->slots()) + if (r_slots && r_slots->value()) { draw_slots(entity); + } if (r_bbox->value()) { gl::color(entity->color()); @@ -979,7 +984,6 @@ void draw_pass_model_fx(float elapsed) ); } - // draw particle systems if (draw_particles && ext_render(entity)->particles().size()) { gl::disable(GL_CULL_FACE); @@ -1227,60 +1231,106 @@ void draw(float seconds) globes_list.clear(); } -// draw weapon slots -// weapons are drawn in model space coordinate, model transformations +// draw model slots: weapon slots and docking ports void draw_slots(const core::Entity *entity) { - assert(entity->slots() && entity->model()); - - gl::disable(GL_DEPTH_TEST); + if (!entity->model()) { + return; + } + gl::disable(GL_DEPTH_TEST); //const float modelscale = entity->radius() / entity->model()->radius(); + + // draw docks + if (entity->model()->docks().size()) { + gl::color(0, 1.0f, 1.0f, 1.0f); + + for (model::Model::Docks::iterator dit = entity->model()->docks().begin(); dit != entity->model()->docks().end(); dit++) { + model::Dock *dock = (*dit); + math::Vector3f maxbox(dock->location()); + math::Vector3f minbox(dock->location()); + + for (size_t i = 0; i < 3; i++) { + maxbox[i] += 0.025; + minbox[i] -= 0.025; + } - gl::color(1.0f, 0.0f, 0.0f, 1.0f); + // top + gl::begin(gl::LineLoop); + gl::vertex(maxbox.x(), maxbox.y(), maxbox.z()); + gl::vertex(minbox.x(), maxbox.y(), maxbox.z()); + gl::vertex(minbox.x(), minbox.y(), maxbox.z()); + gl::vertex(maxbox.x(), minbox.y(), maxbox.z()); + gl::end(); - for(core::Slots::iterator it = entity->slots()->begin(); it != entity->slots()->end(); ++it) { - core::Slot *slot = (*it); - - math::Vector3f maxbox(slot->location()); - math::Vector3f minbox(slot->location()); + // bottom + gl::begin(gl::LineLoop); + gl::vertex(maxbox.x(), maxbox.y(), minbox.z()); + gl::vertex(minbox.x(), maxbox.y(), minbox.z()); + gl::vertex(minbox.x(), minbox.y(), minbox.z()); + gl::vertex(maxbox.x(), minbox.y(), minbox.z()); + gl::end(); - for (size_t i = 0; i < 3; i++) { - maxbox[i] += 0.025; - minbox[i] -= 0.025; + gl::begin(gl::Lines); + gl::vertex(maxbox.x(), maxbox.y(), maxbox.z()); + gl::vertex(maxbox.x(), maxbox.y(), minbox.z()); + gl::vertex(minbox.x(), maxbox.y(), maxbox.z()); + gl::vertex(minbox.x(), maxbox.y(), minbox.z()); + gl::vertex(minbox.x(), minbox.y(), maxbox.z()); + gl::vertex(minbox.x(), minbox.y(), minbox.z()); + gl::vertex(maxbox.x(), minbox.y(), maxbox.z()); + gl::vertex(maxbox.x(), minbox.y(), minbox.z()); + gl::end(); } + } + + // draw weapon slots + if (entity->slots()) { + gl::color(1.0f, 0.0f, 0.0f); + + for(core::Slots::iterator it = entity->slots()->begin(); it != entity->slots()->end(); ++it) { + core::Slot *slot = (*it); + + math::Vector3f maxbox(slot->location()); + math::Vector3f minbox(slot->location()); - // top - gl::begin(gl::LineLoop); - gl::vertex(maxbox.x(), maxbox.y(), maxbox.z()); - gl::vertex(minbox.x(), maxbox.y(), maxbox.z()); - gl::vertex(minbox.x(), minbox.y(), maxbox.z()); - gl::vertex(maxbox.x(), minbox.y(), maxbox.z()); - gl::end(); + for (size_t i = 0; i < 3; i++) { + maxbox[i] += 0.025; + minbox[i] -= 0.025; + } - // bottom - gl::begin(gl::LineLoop); - gl::vertex(maxbox.x(), maxbox.y(), minbox.z()); - gl::vertex(minbox.x(), maxbox.y(), minbox.z()); - gl::vertex(minbox.x(), minbox.y(), minbox.z()); - gl::vertex(maxbox.x(), minbox.y(), minbox.z()); - gl::end(); + // top + gl::begin(gl::LineLoop); + gl::vertex(maxbox.x(), maxbox.y(), maxbox.z()); + gl::vertex(minbox.x(), maxbox.y(), maxbox.z()); + gl::vertex(minbox.x(), minbox.y(), maxbox.z()); + gl::vertex(maxbox.x(), minbox.y(), maxbox.z()); + gl::end(); - gl::begin(gl::Lines); - gl::vertex(maxbox.x(), maxbox.y(), maxbox.z()); - gl::vertex(maxbox.x(), maxbox.y(), minbox.z()); - gl::vertex(minbox.x(), maxbox.y(), maxbox.z()); - gl::vertex(minbox.x(), maxbox.y(), minbox.z()); - gl::vertex(minbox.x(), minbox.y(), maxbox.z()); - gl::vertex(minbox.x(), minbox.y(), minbox.z()); - gl::vertex(maxbox.x(), minbox.y(), maxbox.z()); - gl::vertex(maxbox.x(), minbox.y(), minbox.z()); - gl::end(); + // bottom + gl::begin(gl::LineLoop); + gl::vertex(maxbox.x(), maxbox.y(), minbox.z()); + gl::vertex(minbox.x(), maxbox.y(), minbox.z()); + gl::vertex(minbox.x(), minbox.y(), minbox.z()); + gl::vertex(maxbox.x(), minbox.y(), minbox.z()); + gl::end(); + + gl::begin(gl::Lines); + gl::vertex(maxbox.x(), maxbox.y(), maxbox.z()); + gl::vertex(maxbox.x(), maxbox.y(), minbox.z()); + gl::vertex(minbox.x(), maxbox.y(), maxbox.z()); + gl::vertex(minbox.x(), maxbox.y(), minbox.z()); + gl::vertex(minbox.x(), minbox.y(), maxbox.z()); + gl::vertex(minbox.x(), minbox.y(), minbox.z()); + gl::vertex(maxbox.x(), minbox.y(), maxbox.z()); + gl::vertex(maxbox.x(), minbox.y(), minbox.z()); + gl::end(); + } } gl::enable(GL_DEPTH_TEST); } - +/* // draw HUD target world space geometry, like dock indicators void draw_target(const core::Entity *entity) { @@ -1344,5 +1394,6 @@ void draw_target(const core::Entity *entity) gl::pop(); gl::disable(GL_DEPTH_TEST); } +*/ } diff --git a/src/render/draw.h b/src/render/draw.h index 71321c5..21145c2 100644 --- a/src/render/draw.h +++ b/src/render/draw.h @@ -17,11 +17,11 @@ namespace render /// draw the world void draw(float seconds); - +/* /// draws model docks, used when targetting an entity void draw_target(const core::Entity *entity); - -/// draws entity weapon slots +*/ +/// draws entity slots void draw_slots(const core::Entity *entity); /// reset diff --git a/src/render/render.cc b/src/render/render.cc index 45d3fda..794d777 100644 --- a/src/render/render.cc +++ b/src/render/render.cc @@ -11,6 +11,8 @@ #include "auxiliary/functions.h" #include "core/application.h" +#include "core/entity.h" +#include "core/entityglobe.h" #include "core/gameinterface.h" #include "filesystem/filesystem.h" #include "model/model.h" @@ -40,6 +42,7 @@ core::Cvar *r_mipmap = 0; core::Cvar *r_physics = 0; core::Cvar *r_normals = 0; core::Cvar *r_normalize = 0; +core::Cvar *r_slots = 0; void func_list_textures(std::string const &args) { @@ -100,6 +103,9 @@ void init(int width, int height) r_physics = core::Cvar::get("r_physics", "0", core::Cvar::Archive); r_physics->set_info("[bool] render physics (local game only)"); + + r_slots = core::Cvar::get("r_slots", "0", core::Cvar::Archive); + r_slots->set_info("[bool] render model slots"); Screenshot::screenshotformat = core::Cvar::get("screenshot_format", "jpg", core::Cvar::Archive); Screenshot::screenshotformat->set_info("[string] screenshot format: jpg png tga"); diff --git a/src/render/render.h b/src/render/render.h index 2162457..71d05df 100644 --- a/src/render/render.h +++ b/src/render/render.h @@ -67,6 +67,8 @@ extern core::Cvar *r_physics; extern core::Cvar *r_mipmap; /// use GL_NORMALIZE instead of GL_RESCALE_NORMAL extern core::Cvar *r_normalize; +/// render model slots (debug) +extern core::Cvar *r_slots; inline RenderExt *ext_render(const core::Entity *entity) { diff --git a/src/render/renderext.cc b/src/render/renderext.cc index b96bdfe..f8fd453 100644 --- a/src/render/renderext.cc +++ b/src/render/renderext.cc @@ -9,6 +9,8 @@ #include "math/functions.h" #include "core/application.h" +#include "core/entity.h" +#include "core/entityglobe.h" #include "core/range.h" #include "model/model.h" #include "render/camera.h" diff --git a/src/render/state.cc b/src/render/state.cc index 5f026f0..ce3a0ab 100644 --- a/src/render/state.cc +++ b/src/render/state.cc @@ -299,23 +299,23 @@ void State::use_material(const model::Material * material) { } } else { - // envmapped without texture: use the skybox as envmap - if (material->flags() & model::Material::Environment) { - if (core::localplayer()->zone()->sky().size()) { - gl::enable(GL_TEXTURE_CUBE_MAP); - - glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); - glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); - glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); - - gl::enable(GL_TEXTURE_GEN_S); - gl::enable(GL_TEXTURE_GEN_T); - gl::enable(GL_TEXTURE_GEN_R); - } else { - color.assign(0.0f, 0.0f, 0.0f); - } - glMateriali(GL_FRONT, GL_SHININESS, 4); + // envmapped without texture: use the skybox as envmap + if (material->flags() & model::Material::Environment) { + if (core::localplayer()->zone()->sky().size()) { + gl::enable(GL_TEXTURE_CUBE_MAP); + + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); + glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); + + gl::enable(GL_TEXTURE_GEN_S); + gl::enable(GL_TEXTURE_GEN_T); + gl::enable(GL_TEXTURE_GEN_R); + } else { + color.assign(0.0f, 0.0f, 0.0f); } + glMateriali(GL_FRONT, GL_SHININESS, 4); + } } gl::color(color); |