From 9252bfb61fabea1f45afacb19d805eb5fdd01599 Mon Sep 17 00:00:00 2001
From: Stijn Buys <ingar@osirion.org>
Date: Sun, 28 Sep 2008 21:34:53 +0000
Subject: intro module

---
 src/client/targets.cc      |  2 +-
 src/core/application.cc    | 33 ++++++++++++++++
 src/core/gameserver.cc     |  2 +-
 src/core/module.cc         |  1 +
 src/core/module.h          |  7 ++++
 src/game/game.cc           |  4 ++
 src/game/intro/Makefile.am |  4 +-
 src/game/intro/convoy.cc   | 85 ++++++++++++++++++++++++++++++++++++++++
 src/game/intro/convoy.h    | 51 ++++++++++++++++++++++++
 src/game/intro/intro.cc    | 98 +++++++++++++++++++++++++++++++++++++++++-----
 src/game/intro/intro.h     |  4 ++
 src/render/camera.cc       |  6 ++-
 12 files changed, 281 insertions(+), 16 deletions(-)
 create mode 100644 src/game/intro/convoy.cc
 create mode 100644 src/game/intro/convoy.h

diff --git a/src/client/targets.cc b/src/client/targets.cc
index 4764245..b533974 100644
--- a/src/client/targets.cc
+++ b/src/client/targets.cc
@@ -343,7 +343,7 @@ void render_entity_sound(core::EntityControlable *entity)
 		gain = 1.0f;
 	} else if (entity->thrust() > 0 ) {
 		pitch = 0.2f + entity->thrust() * 0.8f;
-		gain = 1.0f;
+		gain = 0.8f;
 	}
 	
 
diff --git a/src/core/application.cc b/src/core/application.cc
index f8b9a73..2b3f41f 100644
--- a/src/core/application.cc
+++ b/src/core/application.cc
@@ -12,6 +12,7 @@
 #include <sstream>
 #include <fstream>
 
+#include "auxiliary/functions.h"
 #include "sys/sys.h"
 #include "math/mathlib.h"
 #include "filesystem/filesystem.h"
@@ -80,6 +81,34 @@ void func_msg(std::string const &args)
 		con_print << "Not connected." << std::endl;
 	}
 }
+
+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;
+	}
+	
+	if (game()) {
+		con_warn << "Connected. Disconnect first.\n";
+		return;
+	}
+
+	std::string name(args);
+	aux::to_label(name);
+
+	Module::load(name.c_str());
+}
+
 // --------------- signal_handler -----------------------------------
 
 #ifndef _WIN32
@@ -224,6 +253,9 @@ void Application::init(int count, char **arguments)
 	func = Func::add("quit", func_quit);
 	func->set_info("exit the application");
 	
+	func = Func::add("load", func_load);
+	func->set_info("[str] load a game module");
+
 	func = Func::add("connect", func_connect);
 	func->set_info("[ip] without ip, create a game");
 
@@ -260,6 +292,7 @@ void Application::shutdown()
 	
 	Func::remove("connect");
 	Func::remove("disconnect");
+	Func::remove("load");
 
 #ifdef _WIN32
 	// shutdown win32 socket library
diff --git a/src/core/gameserver.cc b/src/core/gameserver.cc
index e086096..70786af 100644
--- a/src/core/gameserver.cc
+++ b/src/core/gameserver.cc
@@ -621,7 +621,7 @@ void GameServer::frame(float seconds)
 
 	}
 
-	// mark all entities as udpated
+	// mark all entities as updated
 	for (Entity::Registry::iterator it=Entity::registry().begin(); it != Entity::registry().end(); ) {
 		Entity *entity = (*it).second;
 
diff --git a/src/core/module.cc b/src/core/module.cc
index 89bc2fe..29c9eb8 100644
--- a/src/core/module.cc
+++ b/src/core/module.cc
@@ -38,6 +38,7 @@ Module *Module::add(const char *name, Module *module)
 		return 0;
 	}
 	module_registry[std::string(name)] = module;
+	module->module_label.assign(name);
 	if (!module_preload) {
 		module_preload = module;
 		con_debug << "  " << name << " " << module->name() << std::endl;
diff --git a/src/core/module.h b/src/core/module.h
index bd99034..b46c296 100644
--- a/src/core/module.h
+++ b/src/core/module.h
@@ -30,6 +30,9 @@ public:
 	/// return the name of the module
 	inline std::string const & name() const { return module_name; }
 
+	/// label of the module
+	inline std::string const & label() const { return module_label; }
+
 /*----- mutators -------------------------------------------------- */
 
 	/// initialize the game module
@@ -69,6 +72,9 @@ public:
 	/// currently loaded module
 	static inline Module *current() { return module_preload; }
 
+	/// module registry
+	static inline Registry & registry() { return module_registry; }
+
 protected:
 	/// set the disconnected state
 	void abort();
@@ -77,6 +83,7 @@ protected:
 
 private:
 	std::string		module_name;
+	std::string		module_label;
 
 	static Module 		*module_preload;
 
diff --git a/src/game/game.cc b/src/game/game.cc
index febb830..5e7c826 100644
--- a/src/game/game.cc
+++ b/src/game/game.cc
@@ -6,6 +6,7 @@
 
 #include "game/game.h"
 #include "base/base.h"
+#include "intro/intro.h"
 #include "core/core.h"
 #include "sys/sys.h"
 
@@ -18,6 +19,9 @@ void register_modules(bool register_client_modules)
 	con_print << "^BRegistering game modules..." << std::endl;
 	core::Module::add("base", new base::Base());
 
+	if (register_client_modules) {
+		core::Module::add("intro", new intro::Intro());
+	}
 }
 
 }
diff --git a/src/game/intro/Makefile.am b/src/game/intro/Makefile.am
index fc5b019..eeb6f9d 100644
--- a/src/game/intro/Makefile.am
+++ b/src/game/intro/Makefile.am
@@ -2,5 +2,5 @@ INCLUDES = -I$(top_srcdir)/src -I$(top_srcdir)/src/game
 METASOURCES = AUTO
 libintro_la_LDFLAGS = -avoid-version
 noinst_LTLIBRARIES = libintro.la
-libintro_la_SOURCES = intro.cc
-noinst_HEADERS = intro.h
+libintro_la_SOURCES = convoy.cc intro.cc
+noinst_HEADERS = convoy.h intro.h
diff --git a/src/game/intro/convoy.cc b/src/game/intro/convoy.cc
new file mode 100644
index 0000000..ea71a27
--- /dev/null
+++ b/src/game/intro/convoy.cc
@@ -0,0 +1,85 @@
+/*
+   intro/convoy.h
+   This file is part of the Osirion project and is distributed under 
+   the terms of the GNU General Public License version 2 
+*/
+
+#include "intro/convoy.h"
+
+namespace intro {
+
+Member::Member(std::string const &model) : core::EntityControlable(0, 1)
+{
+	set_name("Convoy member");
+	set_label(model);
+
+	entity_modelname = "ships/" + model;
+
+	entity_thrust = 1.0f;
+	entity_speed = 1.0f;
+
+	entity_location.x = -16.0f;
+	entity_location.y = -math::randomf(8.0f);
+	entity_location.z = math::randomf(8.0f) - 6.0f;
+
+	entity_axis.change_direction(15.0f);
+}
+
+Member::~Member()
+{
+}
+
+void Member::frame(float seconds)
+{
+	entity_location += entity_axis.forward() * speed() * thrust() * seconds;
+}
+
+Convoy::Convoy(core::Zone *zone)
+{
+	convoy_zone = zone;
+}
+
+Convoy::~Convoy()
+{
+	convoy_members.clear();
+}
+
+void Convoy::set_color(math::Color const &color)
+{
+	convoy_color.assign(color);
+}
+void Convoy::set_color_second(math::Color const &color)
+{
+	convoy_color_second.assign(color);
+}
+
+void Convoy::add(const char *model)
+{
+	add(std::string(model));
+}
+
+void Convoy::add(std::string const &model)
+{
+	Member *member = new Member(model);
+	convoy_members.push_back(member);
+	member->set_zone(convoy_zone);
+	member->entity_color.assign(convoy_color);
+	member->entity_color_second.assign(convoy_color_second);
+}
+
+void Convoy::frame(float seconds)
+{
+	for (Members::iterator it = convoy_members.begin(); it != convoy_members.end(); ) {
+		Member *member = (*it);
+		if (member->location().length() > 64.0f) {
+			std::string model(member->label());
+ 			member->die();
+			convoy_members.erase(it++);
+			add(model);
+		} else {
+			++it;
+		}
+	}
+}
+
+}
\ No newline at end of file
diff --git a/src/game/intro/convoy.h b/src/game/intro/convoy.h
new file mode 100644
index 0000000..8f8a64d
--- /dev/null
+++ b/src/game/intro/convoy.h
@@ -0,0 +1,51 @@
+/*
+   intro/convoy.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_INTRO_CONVOY_H__
+#define __INCLUDED_INTRO_CONVOY_H__
+
+#include <list>
+
+#include "core/core.h"
+#include "math/color.h"
+
+namespace intro {
+
+class Member : public core::EntityControlable
+{
+public:
+	Member(std::string const &model);
+	~Member();
+
+	void frame(float seconds);
+};
+
+class Convoy 
+{
+public:
+	Convoy(core::Zone *zone);
+	~Convoy();
+
+	void add(const char *model);
+	void add(std::string const &model);
+
+	void frame(float seconds);
+
+	void set_color(math::Color const &color);
+	void set_color_second(math::Color const &color);
+
+private:
+	typedef std::list<Member *> Members;
+	Members		convoy_members;
+	core::Zone	*convoy_zone;
+	math::Color	convoy_color;
+	math::Color	convoy_color_second;
+};
+
+}
+
+#endif // __INCLUDED_INTRO_CONVOY_H__
+
diff --git a/src/game/intro/intro.cc b/src/game/intro/intro.cc
index c0ae6da..f5b4e2f 100644
--- a/src/game/intro/intro.cc
+++ b/src/game/intro/intro.cc
@@ -5,6 +5,11 @@
 */
 
 #include "intro/intro.h"
+#include "core/core.h"
+#include "core/parser.h"
+#include "filesystem/filesystem.h"
+#include "filesystem/inifile.h"
+#include "math/color.h"
 #include "sys/sys.h"
 
 namespace intro {
@@ -12,6 +17,7 @@ namespace intro {
 Intro::Intro() : core::Module("Introduction")
 {
 	intro_zone = 0;
+	intro_convoy = 0;
 }
 
 Intro::~Intro()
@@ -23,21 +29,84 @@ void Intro::init()
 	/// intialize a single zone for the introduction
 	intro_zone = new core::Zone("intro");
 	intro_zone->set_name("Introduction");
+	intro_zone->set_sky("sky");
 	core::Zone::add(intro_zone);
-	
-	/// add a planet
-	core::EntityGlobe *planet = new core::EntityGlobe();
-	planet->set_zone(intro_zone);
-	planet->set_name("Planet");
-	planet->set_label("planet");
-	planet->entity_texture.assign("planets/seymour");
-	planet->entity_location.assign(0, -32.0f, 0.0f);
-	planet->entity_radius = 64.0f;
-	planet->entity_rotationspeed = 1.0f;
+
+	intro_convoy = new Convoy(intro_zone);
+
+	if (!load_world()) {
+		abort();
+		return;
+	}
 
 	module_running = true;
 }
 
+bool Intro::load_world()
+{
+	std::string filename("intro");
+
+	filesystem::IniFile ini;
+	ini.open(filename);
+
+	if (!ini.is_open()) {
+		con_error << "Could not open " << ini.name() << std::endl;
+		return false;
+	}
+
+	std::string strval;
+	core::EntityGlobe *globe = 0;
+	math::Color color;
+	bool b;
+	
+	while (ini.getline()) {
+		if (ini.got_key()) {
+
+			if (ini.section().compare("intro") == 0) {
+				if (ini.got_key_string("sky", strval)) {
+					intro_zone->set_sky(strval);
+					continue;
+				}
+			} else if (ini.section().compare("convoy") == 0) {
+				if (ini.got_key_color("color", color)) {
+					intro_convoy->set_color(color);
+
+				} else if (ini.got_key_color("colorsecond", color)) {
+					intro_convoy->set_color_second(color);
+
+				} else if (ini.got_key_string("ship", strval)) {
+					intro_convoy->add(strval);
+				}
+
+			} else if (ini.section().compare("globe") == 0) {
+				if (core::Parser::got_entity_key(ini, globe)) {
+					continue;
+				} else if (ini.got_key_string("texture", globe->entity_texture)) {
+					continue;
+				} else if (ini.got_key_float("rotationspeed", globe->entity_rotationspeed)) {
+					continue;
+				} else if (ini.got_key_bool("bright", b)) {
+					if (b) { globe->entity_flags |= core::Entity::Bright; }
+				} else {
+					con_warn << ini.name() << " unknown key '" << ini.key() << "' at line " << ini.line() << std::endl;
+				}
+			}
+			
+		} else if (ini.got_section("intro")) {
+			continue;
+
+		} else if (ini.got_section("globe")) {
+			globe = new core::EntityGlobe();
+			globe->set_zone(intro_zone);
+
+		} else if (ini.got_section()) {
+			con_warn << ini.name() << " unknown section '" << ini.section() << "' at line " << ini.line() << std::endl;
+		}
+	}
+
+	return true;
+}
+
 void Intro::player_connect(core::Player *player)
 {
 	player->set_zone(intro_zone);
@@ -49,10 +118,19 @@ void Intro::player_disconnect(core::Player *player)
 
 void Intro::frame(float seconds)
 {
+	if (intro_convoy) {
+		intro_convoy->frame(seconds);
+	}
 }
 
 void Intro::shutdown()
 {
+	intro_zone = 0;
+
+	if (intro_convoy) {
+		delete intro_convoy;
+		intro_convoy = 0;
+	}
 }
 
 }
diff --git a/src/game/intro/intro.h b/src/game/intro/intro.h
index 21dc604..748432c 100644
--- a/src/game/intro/intro.h
+++ b/src/game/intro/intro.h
@@ -8,6 +8,7 @@
 #define __INCLUDED_INTRO_H__
 
 #include "core/core.h"
+#include "intro/convoy.h"
 
 /// introduction game module
 namespace intro
@@ -39,6 +40,9 @@ public:
 
 private:
 	core::Zone	*intro_zone;
+	Convoy		*intro_convoy;
+
+	bool load_world();
 };
 
 }
diff --git a/src/render/camera.cc b/src/render/camera.cc
index 53d27f7..ae7cd43 100644
--- a/src/render/camera.cc
+++ b/src/render/camera.cc
@@ -20,7 +20,7 @@ namespace render
 const float 		MIN_DELTA = 10e-10;
 
 const float 		pitch_track = -15.0f;
-const float 		pitch_overview = -75.0f;
+const float 		pitch_overview = -5.0f;
 
 float 			Camera::camera_aspect = 1.0f;
 float			Camera::camera_frustum_size = 0.5f;
@@ -206,13 +206,15 @@ void Camera::frame(float seconds)
 			set_mode(Overview);
 		}
 		
+		// TODO read Zone overview positions
 		camera_eye.clear();
 		camera_target.clear();
 		camera_axis.clear();
 		pitch_current = pitch_overview;
 		camera_axis.change_pitch(pitch_current);
 
-		distance = 20.0f;
+		//distance = 20.0f;
+		distance = 8.0f;
 
 	} else {
 		if (mode() == Overview)
-- 
cgit v1.2.3