Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2012-11-25 12:06:13 +0000
committerStijn Buys <ingar@osirion.org>2012-11-25 12:06:13 +0000
commitd8be908233fd7b85492d7a9e87f07bb207173990 (patch)
tree70d9103a867688838fc517290bb370366c69fedb
parentedc5ddce817244111b302e449c28a052f2746cc4 (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.
-rw-r--r--src/client/chat.cc28
-rw-r--r--src/client/chat.h2
-rw-r--r--src/client/inventorywindow.cc25
-rw-r--r--src/client/inventorywindow.h4
-rw-r--r--src/client/mapwindow.cc2
-rw-r--r--src/client/video.cc3
-rw-r--r--src/core/Makefile.am2
-rw-r--r--src/core/entity.cc72
-rw-r--r--src/core/entity.h89
-rw-r--r--src/core/entityglobe.cc68
-rw-r--r--src/core/entityglobe.h96
-rw-r--r--src/core/netconnection.cc2
-rw-r--r--src/core/parser.cc2
-rw-r--r--src/core/slot.cc12
-rw-r--r--src/core/slot.h36
-rw-r--r--src/game/base/game.cc155
-rw-r--r--src/game/base/game.h2
-rw-r--r--src/game/base/planet.h2
-rw-r--r--src/game/base/projectile.cc115
-rw-r--r--src/game/base/projectile.h13
-rw-r--r--src/game/base/ship.cc17
-rw-r--r--src/game/base/shipmodel.cc7
-rw-r--r--src/game/base/star.h2
-rw-r--r--src/game/base/weapon.h8
-rw-r--r--src/game/intro/intro.cc2
-rw-r--r--src/model/mapfile.cc16
-rw-r--r--src/model/model.cc50
-rw-r--r--src/model/model.h20
-rw-r--r--src/render/draw.cc135
-rw-r--r--src/render/draw.h6
-rw-r--r--src/render/render.cc6
-rw-r--r--src/render/render.h2
-rw-r--r--src/render/renderext.cc2
-rw-r--r--src/render/state.cc32
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);