Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2008-10-18 17:58:45 +0000
committerStijn Buys <ingar@osirion.org>2008-10-18 17:58:45 +0000
commit35613f0860a2d8cb643ca8de006de08503e48e53 (patch)
tree8a5436de643e818e68a82df2e5cb2df2145f5062 /src
parentdb287e4a5133125bb6f25ba21ea97c47b19ac67f (diff)
example module
Diffstat (limited to 'src')
-rw-r--r--src/core/application.cc55
-rw-r--r--src/core/entity.cc83
-rw-r--r--src/core/entity.h21
-rw-r--r--src/core/gameserver.cc6
-rw-r--r--src/core/module.cc24
-rw-r--r--src/core/module.h34
-rw-r--r--src/core/net.h2
-rw-r--r--src/core/player.h2
-rw-r--r--src/game/Makefile.am4
-rw-r--r--src/game/base/base.cc8
-rw-r--r--src/game/base/base.h13
-rw-r--r--src/game/example/Makefile.am7
-rw-r--r--src/game/example/example.cc125
-rw-r--r--src/game/example/example.h65
-rw-r--r--src/game/example/spectator.cc65
-rw-r--r--src/game/example/spectator.h32
-rw-r--r--src/game/game.cc4
-rw-r--r--src/game/intro/intro.cc5
-rw-r--r--src/game/intro/intro.h12
-rw-r--r--src/render/draw.cc9
20 files changed, 480 insertions, 96 deletions
diff --git a/src/core/application.cc b/src/core/application.cc
index 0d52b76..71d739f 100644
--- a/src/core/application.cc
+++ b/src/core/application.cc
@@ -84,20 +84,6 @@ void func_msg(std::string const &args)
void func_load(std::string const &args)
{
- if (!args.size()) {
- if (Module::current()) {
- con_print << " currently loaded: " << Module::current()->label() << " " << Module::current()->name() << std::endl;
- }
-
- std::string helpstr(" available modules:");
- for(Module::Registry::iterator it = Module::registry().begin(); it != Module::registry().end(); it++) {
- helpstr += ' ';
- helpstr += (*it).first;
- }
- con_print << helpstr << std::endl;
- return;
- }
-
std::string name(args);
aux::to_label(name);
application()->load(name);
@@ -311,13 +297,32 @@ void Application::quit(int status)
Module *Application::load(std::string const &module_label)
{
- if (game() && Module::current()->interactive()) {
+ if (!module_label.size()) {
+ if (Module::active()) {
+ con_print << " active module: " << Module::active()->label() << " " << Module::active()->name() << std::endl;
+ }
+ if (Module::loaded()) {
+ con_print << " loaded module: " << Module::loaded()->label() << " " << Module::loaded()->name() << std::endl;
+ }
+ if (module_interactive) {
+ con_print << " fallback module: " << module_interactive->label() << " " << module_interactive->name() << std::endl;
+ }
+ std::string helpstr(" available modules:");
+ for(Module::Registry::iterator it = Module::registry().begin(); it != Module::registry().end(); it++) {
+ helpstr += ' ';
+ helpstr += (*it).first;
+ }
+ con_print << helpstr << std::endl;
+ return 0;
+ }
+/*
+ if (Module::active() && Module::active()->interactive()) {
con_warn << "Connected. Disconnect first.\n";
return 0;
}
-
- if (Module::current() && Module::current()->interactive()) {
- module_interactive = Module::current();
+*/
+ if (Module::loaded() && Module::loaded()->interactive()) {
+ module_interactive = Module::loaded();
}
return Module::load(module_label.c_str());
}
@@ -325,13 +330,13 @@ Module *Application::load(std::string const &module_label)
void Application::connect(std::string const &host)
{
if (connected()) {
- if (!Module::current()->interactive() && module_interactive) {
- /* if the current running module is non-interactive,
- disconnect, and load the last interactive module_interactive
- */
- disconnect();
- Module::load(module_interactive->label().c_str());
-
+ if (!Module::active()->interactive()) {
+ if ((Module::loaded() == Module::active()) && (module_interactive)) {
+ disconnect();
+ Module::load(module_interactive->label().c_str());
+ } else {
+ disconnect();
+ }
} else {
con_warn << "Connected. Disconnect first.\n";
return;
diff --git a/src/core/entity.cc b/src/core/entity.cc
index e74b8b5..27190a0 100644
--- a/src/core/entity.cc
+++ b/src/core/entity.cc
@@ -177,7 +177,7 @@ void Entity::set_label(char const *label)
aux::to_label(entity_label);
}
-void Entity::set_label(std::string const &label)
+void Entity::set_label(const std::string &label)
{
entity_label.assign(label);
aux::to_label(entity_label);
@@ -189,16 +189,35 @@ void Entity::set_name(char const *name)
aux::strip_quotes(entity_name);
}
-void Entity::set_name(std::string const &name)
+void Entity::set_name(const std::string &name)
{
entity_name.assign(name);
aux::strip_quotes(entity_name);
}
+void Entity::set_visible(bool visible)
+{
+ if (visible)
+ show();
+ else
+ hide();
+}
+
+void Entity::show()
+{
+ entity_visible = false;
+}
+
+void Entity::hide()
+{
+ entity_visible = false;
+}
+
void Entity::serialize_server_create(std::ostream & os) const
{
os << entity_moduletypeid << " "
<< entity_flags << " "
+ << (entity_visible ? 1 : 0) << " "
<< (entity_zone ? entity_zone->id() : 0) << " "
<< std::setprecision(8) << entity_location << " "
<< entity_color << " "
@@ -216,10 +235,18 @@ void Entity::receive_server_create(std::istream &is)
{
unsigned int s;
unsigned int zo;
+ unsigned int o = 0;
std::string n;
is >> entity_moduletypeid;
is >> entity_flags;
+
+ is >> o;
+ if (o)
+ entity_visible = true;
+ else
+ entity_visible = false;
+
is >> zo;
set_zone(Zone::find(zo));
@@ -363,33 +390,43 @@ void EntityDynamic::receive_client_update(std::istream &is)
void EntityDynamic::serialize_server_update(std::ostream & os) const
{
- os << std::setprecision(8)
- << entity_location << " "
- << entity_axis.forward() << " "
- << entity_axis.left() << " "
- << roundf(entity_speed * 100.0f) << " "
- << entity_eventstate << " ";
-
- if (entity_eventstate != Normal) {
- os << entity_timer << " ";
+ os << (visible() ? 1 : 0 ) << " ";
+ if (visible()) {
+ os << std::setprecision(8)
+ << entity_location << " "
+ << entity_axis.forward() << " "
+ << entity_axis.left() << " "
+ << roundf(entity_speed * 100.0f) << " "
+ << entity_eventstate << " ";
+
+ if (entity_eventstate != Normal) {
+ os << entity_timer << " ";
+ }
}
}
void EntityDynamic::receive_server_update(std::istream &is)
{
- is >> entity_location;
- // axis up vector is the crossproduct of forward and left
- is >> entity_axis[0];
- is >> entity_axis[1];
- entity_axis[2] = math::crossproduct(entity_axis.forward(), entity_axis.left());
- is >> entity_speed;
- entity_speed /= 100.0f;
- is >> entity_eventstate;
-
- if (entity_eventstate != Normal) {
- is >> entity_timer;
+ unsigned int o;
+ is >> o; // visibility
+ if (o) {
+ entity_visible = true;
+ is >> entity_location;
+ // axis up vector is the crossproduct of forward and left
+ is >> entity_axis[0];
+ is >> entity_axis[1];
+ entity_axis[2] = math::crossproduct(entity_axis.forward(), entity_axis.left());
+ is >> entity_speed;
+ entity_speed /= 100.0f;
+ is >> entity_eventstate;
+
+ if (entity_eventstate != Normal) {
+ is >> entity_timer;
+ } else {
+ entity_timer = 0;
+ }
} else {
- entity_timer = 0;
+ entity_visible = false;
}
}
diff --git a/src/core/entity.h b/src/core/entity.h
index 4861b07..2c4814e 100644
--- a/src/core/entity.h
+++ b/src/core/entity.h
@@ -117,6 +117,9 @@ public:
/// indicates a server-side entity
inline bool serverside() const { return entity_serverside; }
+ /// general visibility
+ inline bool visible() const { return entity_visible; }
+
/*----- serializers ----------------------------------------------- */
/// serialize the entity to a stream
@@ -148,6 +151,9 @@ public:
*/
virtual void frame(float seconds);
+ /// set dirty flag
+ inline void set_dirty() { entity_dirty = true; }
+
/// set the zone the entity is currently in
/**
* this fuction removes the entity from its previous zone
@@ -159,13 +165,22 @@ public:
void set_label(char const *label);
/// set the label
- void set_label(std::string const &label);
+ void set_label(const std::string &label);
/// set the name
void set_name(char const *name);
/// set the name
- void set_name(std::string const &name);
+ void set_name(const std::string &name);
+
+ /// set visibility
+ void set_visible(bool visible = true);
+
+ /// show the entity, make it visible
+ virtual void show();
+
+ /// hide the entity, make it invisible
+ virtual void hide();
/// clear all update flags
virtual void clear_updates();
@@ -218,6 +233,7 @@ protected:
// the previous zone the entity belonged too
Zone *entity_oldzone;
+ bool entity_visible;
bool entity_serverside;
std::string entity_name;
@@ -232,7 +248,6 @@ private:
// the entity registry
static Registry entity_registry;
-
static size_t entity_nextid;
};
diff --git a/src/core/gameserver.cc b/src/core/gameserver.cc
index 4fc3924..e73c6ce 100644
--- a/src/core/gameserver.cc
+++ b/src/core/gameserver.cc
@@ -125,7 +125,7 @@ GameServer::GameServer() : GameInterface()
server_maxplayerid = 1;
server_startup = application()->timestamp();
- server_module = Module::current();
+ server_module = Module::loaded();
if (!server_module) {
con_error << "No module loaded.\n";
abort();
@@ -137,7 +137,7 @@ GameServer::GameServer() : GameInterface()
// set the name of the game
core::Cvar::set("g_name", server_module->name().c_str(), core::Cvar::Game | core::Cvar::ReadOnly);
- server_module->init();
+ server_module->run();
if (!server_module->running()) {
con_error << "Could not initialize module '" << server_module->name() << "'\n";
abort();
@@ -209,7 +209,7 @@ GameServer::~GameServer()
if (server_module->running() && !Cvar::sv_dedicated->value())
player_disconnect(localplayer());
- server_module->shutdown();
+ server_module->terminate();
}
Func::remove("kick");
diff --git a/src/core/module.cc b/src/core/module.cc
index 319d651..eec250e 100644
--- a/src/core/module.cc
+++ b/src/core/module.cc
@@ -14,6 +14,8 @@ namespace core
/*-- static functions ----------------------------------------------*/
Module *Module::module_preload = 0;
+Module *Module::module_active = 0;
+
Module::Registry Module::module_registry;
Module *Module::find(const std::string &label)
@@ -60,7 +62,7 @@ Module *Module::load(const char *label)
return 0;
}
- con_print << " module" << module->label() << " " << module->name() << std::endl;
+ con_print << " module " << module->label() << " " << module->name() << std::endl;
module_preload = module;
return module;
}
@@ -88,11 +90,11 @@ void Module::list()
/*-- instance functions --------------------------------------------*/
-Module::Module(const char *label, const char *name) :
+Module::Module(const char *label, const char *name, bool interactive) :
module_label(label), module_name(name)
{
module_running = false;
- module_interactive = true;
+ module_interactive = interactive;
}
Module::~Module()
@@ -101,9 +103,25 @@ Module::~Module()
module_name.clear();
}
+void Module::run()
+{
+ module_active = this;
+ module_running = true;
+
+ init();
+}
+
+void Module::terminate()
+{
+ shutdown();
+ module_running = false;
+ module_active = 0;
+}
+
void Module::abort()
{
module_running = false;
+ module_active = 0;
}
}
diff --git a/src/core/module.h b/src/core/module.h
index bc4f765..64b41bd 100644
--- a/src/core/module.h
+++ b/src/core/module.h
@@ -17,7 +17,7 @@ namespace core
class Module
{
public:
- Module(const char *label, const char *name);
+ Module(const char *label, const char *name, bool interactive=true);
virtual ~Module();
/*----- inspectors ------------------------------------------------ */
@@ -38,11 +38,11 @@ public:
/*----- mutators -------------------------------------------------- */
- /// initialize the game module
- virtual void init() = 0;
+ /// run the game module
+ void run();
- /// shutdown the game module
- virtual void shutdown() = 0;
+ /// terminate a running game module
+ void terminate();
/// run one timeframe
virtual void frame(float seconds) = 0;
@@ -75,27 +75,39 @@ public:
/// unload all modules
static void clear();
+ /// currently active module
+ static inline Module *active() { return module_active; }
+
/// currently loaded module
- static inline Module *current() { return module_preload; }
+ static inline Module *loaded() { return module_preload; }
/// module registry
static inline Registry & registry() { return module_registry; }
protected:
- /// set the disconnected state
+ /// initialize the game module
+ virtual void init() = 0;
+
+ /// shutdown the game module
+ virtual void shutdown() = 0;
+
+ /// abort a running module
void abort();
- bool module_running;
+private:
+
bool module_interactive;
+ bool module_running;
-private:
std::string module_label;
std::string module_name;
- static Module *module_preload;
-
static Registry module_registry;
+
+ static Module *module_preload;
+ static Module *module_active;
+
};
}
diff --git a/src/core/net.h b/src/core/net.h
index c724f85..92a17c5 100644
--- a/src/core/net.h
+++ b/src/core/net.h
@@ -11,7 +11,7 @@ namespace core
{
/// network protocol version
-const unsigned int PROTOCOLVERSION = 11;
+const unsigned int PROTOCOLVERSION = 12;
/// maximum lenght of a (compressed) network message block
const unsigned int FRAMESIZE = 1152;
diff --git a/src/core/player.h b/src/core/player.h
index aa31a35..c527433 100644
--- a/src/core/player.h
+++ b/src/core/player.h
@@ -104,6 +104,8 @@ public:
void set_mission_target(Entity *new_mission_target);
+ inline void set_dirty() { player_dirty = true; }
+
/* -- should actually not be public --*/
/// dirty state
diff --git a/src/game/Makefile.am b/src/game/Makefile.am
index a6a5290..47ca032 100644
--- a/src/game/Makefile.am
+++ b/src/game/Makefile.am
@@ -6,6 +6,6 @@ libgame_la_SOURCES = game.cc
noinst_LTLIBRARIES = libgame.la
noinst_HEADERS = game.h
-SUBDIRS = base intro
+SUBDIRS = base example intro
libgame_la_LIBADD = $(top_builddir)/src/game/base/libbase.la \
- $(top_builddir)/src/game/intro/libintro.la
+ $(top_builddir)/src/game/intro/libintro.la $(top_builddir)/src/game/example/libexample.la
diff --git a/src/game/base/base.cc b/src/game/base/base.cc
index f27d013..530e520 100644
--- a/src/game/base/base.cc
+++ b/src/game/base/base.cc
@@ -166,7 +166,7 @@ void func_impulse(core::Player *player, std::string const &args)
Base *Base::game_instance = 0;
-Base::Base() : core::Module("base", "Project::OSiRiON")
+Base::Base() : core::Module("base", "Project::OSiRiON", true)
{
game_instance = this;
g_impulsespeed = 0;
@@ -179,8 +179,6 @@ Base::~Base()
void Base::init()
{
- module_running = false;
-
ShipModel::clear();
if (!load_world()) {
@@ -231,9 +229,6 @@ void Base::init()
g_devel = core::Cvar::get("g_devel", "0", core::Cvar::Archive);
g_devel->set_info("[bool] enable or disable developer mode");
-
- // indicate the module is ready to run frames
- module_running = true;
}
void Base::shutdown()
@@ -245,7 +240,6 @@ void Base::shutdown()
core::Func::remove("list_ship");
ShipModel::clear();
- module_running = false;
}
bool Base::load_world()
diff --git a/src/game/base/base.h b/src/game/base/base.h
index db3e7d9..2393a2e 100644
--- a/src/game/base/base.h
+++ b/src/game/base/base.h
@@ -34,12 +34,6 @@ public:
Base();
~Base();
- /// initialize the game
- void init();
-
- /// shutdown the game
- void shutdown();
-
/// run one time frame
void frame(float seconds);
@@ -57,6 +51,13 @@ public:
core::Cvar *g_jumppointrange;
core::Cvar *g_devel;
+protected:
+ /// initialize the game
+ void init();
+
+ /// shutdown the game
+ void shutdown();
+
private:
bool got_entity_key(filesystem::IniFile &inifile, core::Entity *entity);
diff --git a/src/game/example/Makefile.am b/src/game/example/Makefile.am
new file mode 100644
index 0000000..81fb507
--- /dev/null
+++ b/src/game/example/Makefile.am
@@ -0,0 +1,7 @@
+INCLUDES = -I$(top_srcdir)/src -I$(top_srcdir)/src/game
+METASOURCES = AUTO
+libexample_la_LDFLAGS = -avoid-version
+noinst_LTLIBRARIES = libexample.la
+noinst_HEADERS = example.h
+libexample_la_SOURCES = example.cc spectator.cc
+_SOURCES = spectator.h
diff --git a/src/game/example/example.cc b/src/game/example/example.cc
new file mode 100644
index 0000000..d8e18ea
--- /dev/null
+++ b/src/game/example/example.cc
@@ -0,0 +1,125 @@
+/*
+ intro/intro.cc
+ This file is part of the Osirion project and is distributed under
+ the terms of the GNU General Public License version 2
+*/
+
+#include "core/gameserver.h"
+#include "example/example.h"
+#include "example/spectator.h"
+
+namespace example {
+
+Example::Example() : core::Module("example", "The Osirion Project Example", true)
+{
+}
+
+Example::~Example()
+{
+}
+
+void Example::init()
+{
+ /*
+ Initialize engine game variables
+ */
+ Spectator::g_spectatorspeed = core::Cvar::get("g_spectatorspeed", "4", core::Cvar::Game | core::Cvar::Archive);
+ Spectator::g_spectatorspeed->set_info("[float] speed of the spectator");
+
+ Spectator::g_spectatorrotation = core::Cvar::get("g_spectatorrotation", "45", core::Cvar::Game | core::Cvar::Archive);
+ Spectator::g_spectatorrotation->set_info("[float] rotation speed of the spectator in degrees per second");
+
+ /*
+ The Osirion world consists of Zones. Zones are different
+ areas in the game. The example has only one zone.
+ */
+ zone = new core::Zone("example"); // create a Zone object
+ zone->set_name("Example Zone"); // set the zone name
+ core::Zone::add(zone); // add the zone to the world
+
+ /*
+ Every object in the Osirion world is derived from core::Entity.
+ We create a few basic entities
+ */
+
+ core::Entity *cube = new core::Entity(); // a new entity
+ cube->set_label("cube");
+ cube->set_name("The Red Cube");
+ cube->entity_shape = core::Entity::Cube; // set the shape to cube
+ cube->entity_location.assign(16, -8, 0); // set location
+ cube->entity_color.assign(1, 0, 0); // set RGB color red
+ cube->entity_radius = 0.25f; // set radius, in game units
+ cube->set_zone(zone); // add the entity to the zone
+
+ core::Entity *sphere = new core::Entity(); // a new entity
+ sphere->set_label("sphere");
+ sphere->set_name("The Green Sphere");
+ sphere->entity_shape = core::Entity::Sphere; // set the shape to sphere
+ sphere->entity_location.assign(16, 0, 0); // set location
+ sphere->entity_color.assign(0, 1, 0); // set RGB color green
+ sphere->entity_radius = 0.25f; // set radius, in game units
+ sphere->set_zone(zone); // add the entity to the zone
+
+ core::Entity *diamond = new core::Entity(); // a new entity
+ diamond->set_label("diamond");
+ diamond->set_name("The Blue Diamond");
+ diamond->entity_shape = core::Entity::Diamond; // set the shape to cube
+ diamond->entity_location.assign(16, 8, 0); // set location
+ diamond->entity_color.assign(0, 0, 1); // set RGB color blue
+ diamond->entity_radius = 0.25f; // set radius, in game units
+ diamond->set_zone(zone); // add the entity to the zone
+
+ core::Entity *axis = new core::Entity(); // a new entity
+ axis->set_label("origin");
+ axis->set_name("The Origin");
+ axis->entity_shape = core::Entity::Axis; // set the shape to axis
+ axis->entity_location.assign(0, 0, 0); // set location
+ axis->entity_color.assign(1); // set greyscale color white
+ axis->entity_color_second.assign(0.5f, 0.0f, 0.5f); // set RGB secondary color
+ axis->entity_radius = 0.25f; // set radius, in game units
+ axis->set_zone(zone); // add the entity to the zone
+
+}
+
+
+void Example::player_connect(core::Player *player)
+{
+ // add a spectator object for the new player
+ Spectator *spectator;
+ spectator = new Spectator(player);
+ spectator->set_zone(zone);
+ spectator->set_dirty();
+
+ // set the player's control to the spectator object
+ player->set_zone(zone);
+ player->set_control(spectator);
+ player->set_dirty();
+
+ // send a message to the player
+ core::server()->send(player, "Welcome to " + name());
+
+ // broadcast a message to all players
+ core::server()->broadcast("^B" + player->name() + " entered.");
+}
+
+void Example::player_disconnect(core::Player *player)
+{
+ // broadcast a message to all players
+ core::server()->broadcast("^B" + player->name() + " has left.");
+}
+
+void Example::frame(float elapsed)
+{
+
+}
+
+void Example::shutdown()
+{
+ /*
+ The world is automaticly deleted on shutdown,
+ but local variables have to be cleaned up
+ */
+ zone = 0;
+}
+
+}
diff --git a/src/game/example/example.h b/src/game/example/example.h
new file mode 100644
index 0000000..ba8aa72
--- /dev/null
+++ b/src/game/example/example.h
@@ -0,0 +1,65 @@
+/*
+ intro/example.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_EXAMPLE_H__
+#define __INCLUDED_EXAMPLE_H__
+
+// import core functionality
+#include "core/core.h"
+
+// console functions
+#include "sys/sys.h"
+
+/// example game module
+/** This is the osirion Project example module. It describes
+ * how to create custom modules and how to use the engine functionality.
+ */
+namespace example
+{
+
+/// example game module
+/** Every game module derives from core::Module and has to implement a
+ * number of virtual functions
+ */
+class Example : public core::Module
+{
+public:
+ /// constructor, called on module load
+ /** Modules are loaded at the start of the program,
+ * the constructor is only called once.
+ */
+ Example();
+
+ /// desctructor, called on module unload
+ ~Example();
+
+ /// called once every server frame
+ /** @param elapsed time elapsed since the precious server frame, in seconds
+ */
+ void frame(float elapsed);
+
+ /// called when a player connects
+ void player_connect(core::Player *player);
+
+ /// called when a player disconnects
+ void player_disconnect(core::Player *player);
+
+protected:
+ /// called when the game starts
+ void init();
+
+ /// called when the game is shut down
+ void shutdown();
+
+
+private:
+ core::Zone *zone;
+};
+
+}
+
+#endif // __INCLUDED_EXAMPLE_H__
+
diff --git a/src/game/example/spectator.cc b/src/game/example/spectator.cc
new file mode 100644
index 0000000..7b3a165
--- /dev/null
+++ b/src/game/example/spectator.cc
@@ -0,0 +1,65 @@
+/*
+ base/spectator.cc
+ This file is part of the Osirion project and is distributed under
+ the terms and conditions of the GNU General Public License version 2
+*/
+
+#include "example/spectator.h"
+
+namespace example {
+
+core::Cvar *Spectator::g_spectatorspeed = 0;
+core::Cvar *Spectator::g_spectatorrotation = 0;
+
+Spectator::Spectator(core::Player *owner) : core::EntityControlable(owner)
+{
+ // default properties
+ entity_shape = core::Entity::Diamond;
+ entity_radius = 0.25f;
+
+ // the spectator gets player color
+ entity_color.assign(owner->color());
+ entity_color_second.assign(owner->color_second());
+
+ // set dirty flag
+ set_dirty();
+}
+
+Spectator::~Spectator()
+{
+}
+
+void Spectator::frame(float elapsed)
+{
+ // only update if necessary
+ if (!entity_speed && ! target_thrust && !target_direction && !target_pitch && !target_roll)
+ return;
+
+ // assign thrust value from input
+ entity_thrust = target_thrust;
+
+ // rotate according to input
+ float rotation = g_spectatorrotation->value() * elapsed;
+ entity_axis.change_direction(target_direction * rotation);
+ entity_axis.change_pitch(target_pitch * rotation);
+ entity_axis.change_roll(target_roll * rotation);
+
+ // assign speed from thruster
+ float maxspeed = g_spectatorspeed->value();
+ entity_speed = entity_thrust * maxspeed;
+
+ // assign new location
+ if (entity_speed)
+ entity_location += entity_axis.forward() * entity_speed * elapsed;
+
+ if (target_afterburner)
+ entity_location += entity_axis.forward() * maxspeed * target_afterburner * elapsed;
+
+ if (target_strafe)
+ entity_location += entity_axis.left() * maxspeed * target_strafe * elapsed;
+
+ // set dirty flag
+ set_dirty();
+}
+
+}
diff --git a/src/game/example/spectator.h b/src/game/example/spectator.h
new file mode 100644
index 0000000..435c45c
--- /dev/null
+++ b/src/game/example/spectator.h
@@ -0,0 +1,32 @@
+/*
+ base/spectator.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
+*/
+
+#ifndef __INCLUDED_EXAMPLE_SPECTATOR_H__
+#define __INCLUDED_EXAMPLE_SPECTATOR_H__
+
+#include "core/entity.h"
+#include "core/cvar.h"
+
+namespace example {
+
+/// A spectator entity
+class Spectator : public core::EntityControlable
+{
+public:
+ Spectator(core::Player *owner);
+ ~Spectator();
+
+ /// update the ship state
+ virtual void frame(float elapsed);
+
+ static core::Cvar *g_spectatorspeed;
+ static core::Cvar *g_spectatorrotation;
+};
+
+}
+
+#endif // __INCLUDED_EXAMPLE_SPECTATOR_H__
+
diff --git a/src/game/game.cc b/src/game/game.cc
index 9f5b395..01a2574 100644
--- a/src/game/game.cc
+++ b/src/game/game.cc
@@ -5,8 +5,11 @@
*/
#include "game/game.h"
+
#include "base/base.h"
+#include "example/example.h"
#include "intro/intro.h"
+
#include "core/core.h"
#include "sys/sys.h"
@@ -20,6 +23,7 @@ void register_modules(bool register_noninteractive_modules)
// non-interactive modules
core::Module::add(new base::Base());
+ core::Module::add(new example::Example());
// interactive modules
if (register_noninteractive_modules) {
diff --git a/src/game/intro/intro.cc b/src/game/intro/intro.cc
index abb3ba8..95d003a 100644
--- a/src/game/intro/intro.cc
+++ b/src/game/intro/intro.cc
@@ -14,9 +14,8 @@
namespace intro {
-Intro::Intro() : core::Module("intro", "Introduction")
+Intro::Intro() : core::Module("intro", "Introduction", false)
{
- module_interactive = false;
intro_zone = 0;
intro_convoy = 0;
}
@@ -39,8 +38,6 @@ void Intro::init()
abort();
return;
}
-
- module_running = true;
}
bool Intro::load_world()
diff --git a/src/game/intro/intro.h b/src/game/intro/intro.h
index 748432c..da6fb80 100644
--- a/src/game/intro/intro.h
+++ b/src/game/intro/intro.h
@@ -23,12 +23,6 @@ public:
/// delete an introduction game module
~Intro();
- /// run the introduction
- void init();
-
- /// shutdown the introduction
- void shutdown();
-
/// run one frame
void frame(float seconds);
@@ -38,6 +32,12 @@ public:
/// is called when a player disconnects
void player_disconnect(core::Player *player);
+protected:
+ /// run the introduction
+ void init();
+
+ /// shutdown the introduction
+ void shutdown();
private:
core::Zone *intro_zone;
Convoy *intro_convoy;
diff --git a/src/render/draw.cc b/src/render/draw.cc
index 17c6fac..69dcecb 100644
--- a/src/render/draw.cc
+++ b/src/render/draw.cc
@@ -214,14 +214,19 @@ void draw_pass_sky()
if (!core::localplayer()->zone())
return;
- if (!core::localplayer()->zone()->sky_texture() && core::localplayer()->zone()->sky().size()) {
+ if (!core::localplayer()->zone()->sky().size())
+ return;
+
+ if (!core::localplayer()->zone()->sky_texture()) {
std::string texture_name("textures/env/");
texture_name.append(core::localplayer()->zone()->sky());
core::localplayer()->zone()->set_sky_texture(Textures::load(texture_name));
- if (!core::localplayer()->zone()->sky_texture())
+ if (!core::localplayer()->zone()->sky_texture()) {
core::localplayer()->zone()->set_sky("");
+ return;
+ }
}
Textures::bind(core::localplayer()->zone()->sky_texture());