diff options
author | Stijn Buys <ingar@osirion.org> | 2012-11-25 12:06:13 +0000 |
---|---|---|
committer | Stijn Buys <ingar@osirion.org> | 2012-11-25 12:06:13 +0000 |
commit | d8be908233fd7b85492d7a9e87f07bb207173990 (patch) | |
tree | 70d9103a867688838fc517290bb370366c69fedb /src | |
parent | edc5ddce817244111b302e449c28a052f2746cc4 (diff) |
Moved core::EntityGlobe into a separate file,
added various methods to core::Item and core::Slot,
added r_slots cvar to draw entity slots and docks,
added game methods for mounting and umounting of weapons,
added playerlist to chat window.
Diffstat (limited to 'src')
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); |