From 862f1dc0ae63b476b620a817bb2ea73d9b35ef3f Mon Sep 17 00:00:00 2001
From: Stijn Buys <ingar@osirion.org>
Date: Fri, 15 Oct 2010 13:01:44 +0000
Subject: added 'eject cargo' game command

---
 src/game/base/Makefile.am |  4 +--
 src/game/base/cargo.cc    | 85 +++++++++++++++++++++++++++++++++++++++++++----
 src/game/base/cargo.h     |  2 ++
 src/game/base/cargopod.cc | 28 ++++++++++++++++
 src/game/base/cargopod.h  | 24 +++++++++++++
 src/game/base/game.cc     | 67 ++++++++++++++++++++++++++++++++++---
 src/game/base/game.h      |  6 ++--
 7 files changed, 201 insertions(+), 15 deletions(-)
 create mode 100644 src/game/base/cargopod.cc
 create mode 100644 src/game/base/cargopod.h

(limited to 'src/game')

diff --git a/src/game/base/Makefile.am b/src/game/base/Makefile.am
index 8e58bd8..2dcea93 100644
--- a/src/game/base/Makefile.am
+++ b/src/game/base/Makefile.am
@@ -2,7 +2,7 @@ INCLUDES = -I$(top_srcdir)/src -I$(top_srcdir)/src/game
 METASOURCES = AUTO
 libbase_la_LDFLAGS = -avoid-version
 noinst_LTLIBRARIES = libbase.la
-libbase_la_SOURCES = cargo.cc game.cc jumppoint.cc navpoint.cc planet.cc \
+libbase_la_SOURCES = cargo.cc cargopod.cc game.cc jumppoint.cc navpoint.cc planet.cc \
 	racetrack.cc ship.cc shipmodel.cc star.cc station.cc
-noinst_HEADERS = cargo.h game.h jumppoint.h navpoint.h planet.h \
+noinst_HEADERS = cargo.h cargopod.h game.h jumppoint.h navpoint.h planet.h \
 	racetrack.h ship.h shipmodel.h star.h station.h
diff --git a/src/game/base/cargo.cc b/src/game/base/cargo.cc
index 668c3a4..cc358f6 100644
--- a/src/game/base/cargo.cc
+++ b/src/game/base/cargo.cc
@@ -9,6 +9,7 @@
 
 #include "base/game.h"
 #include "base/cargo.h"
+#include "base/cargopod.h"
 #include "filesystem/inifile.h"
 #include "auxiliary/functions.h"
 #include "sys/sys.h"
@@ -121,7 +122,7 @@ void Cargo::sell(core::EntityControlable *seller, core::Entity *buyer, const int
 	
 	// can only sell at planets and stations
 	if ((buyer->moduletype() != station_enttype) && (buyer->moduletype() != planet_enttype)) {
-		seller->owner()->send("^BCan not sell here");
+		seller->owner()->send("^WCan not sell here");
 		return;
 	}
 	
@@ -129,7 +130,7 @@ void Cargo::sell(core::EntityControlable *seller, core::Entity *buyer, const int
 		return;
 	
 	if (!buyer->inventory() || !seller->inventory()) {
-		seller->owner()->send("^BCan not sell here");
+		seller->owner()->send("^WCan not sell here");
 		return;
 	}
 	
@@ -141,7 +142,7 @@ void Cargo::sell(core::EntityControlable *seller, core::Entity *buyer, const int
 	core::Item *seller_item = seller->inventory()->find(this);
 	if (!seller_item) {
 		if (seller->owner()) {
-			seller->owner()->send("^BYou do not own any " + name());
+			seller->owner()->send("^WYou do not own any " + name());
 		}
 		return;	
 	}
@@ -149,7 +150,7 @@ void Cargo::sell(core::EntityControlable *seller, core::Entity *buyer, const int
 	// buyer is the station or planer
 	core::Item *buyer_item = buyer->inventory()->find(this);
 	if (!buyer_item) {
-		seller->owner()->send("^B" + buyer->name() + " ^Bdoes not buy " + name());
+		seller->owner()->send("^W" + buyer->name() + " ^Bdoes not buy " + name());
 		return;
 	}
 
@@ -188,7 +189,7 @@ void Cargo::buy(core::EntityControlable *buyer, core::Entity *seller, const int
 
 	// can only buy at planets and stations
 	if ((seller->moduletype() != station_enttype) && (seller->moduletype() != planet_enttype)) {
-		buyer->owner()->send("^BCan not buy here");
+		buyer->owner()->send("^WCan not buy here");
 		return;
 	}
 	
@@ -196,7 +197,7 @@ void Cargo::buy(core::EntityControlable *buyer, core::Entity *seller, const int
 		return;
 	
 	if (!buyer->inventory() || !seller->inventory()) {
-		buyer->owner()->send("^BCan not buy here");
+		buyer->owner()->send("^WCan not buy here");
 		return;
 	}
 	
@@ -208,7 +209,7 @@ void Cargo::buy(core::EntityControlable *buyer, core::Entity *seller, const int
 	core::Item *seller_item = seller->inventory()->find(this);	
 	if (!seller_item) {
 		if (buyer->owner()) {
-			buyer->owner()->send("^B" + seller->name() + " ^Bdoes not sell " + name());
+			buyer->owner()->send("^W" + seller->name() + " ^Bdoes not sell " + name());
 		}
 		return;	
 	} else {
@@ -294,6 +295,76 @@ void Cargo::buy(core::EntityControlable *buyer, core::Entity *seller, const int
 	buyer->owner()->sound("game/buy");
 }
 
+// main 'eject cargo' function
+void Cargo::eject(core::EntityControlable *ejector, const int amount)
+{
+	if (!ejector->inventory()) {
+		return;
+	}
+	
+	if (!amount) {
+		return;
+	}
+	
+	// find the cargo in the inventory
+	core::Item *item = ejector->inventory()->find(this);	
+	if (!item || !item->amount()) {
+		if (ejector->owner()) {
+			ejector->owner()->send("^WYou do not own any " + name());
+		}
+		return;	
+	} else {
+		assert(item->info() == this);
+	}	
+	
+	int negotiated_amount = amount;
+	if (negotiated_amount < 0) {
+		negotiated_amount = item->amount();
+	} else if (negotiated_amount > item->amount()) {
+		if (ejector->owner()) {
+			std::stringstream msgstr;
+			msgstr << "^WYou only own " << item->amount() << " " << aux::plural("unit", negotiated_amount) << " of " << name();
+			ejector->owner()->send(msgstr.str());
+		}
+		return;	
+	}
+	
+	item->dec_amount(negotiated_amount);
+	ejector->owner()->set_dirty();
+	
+	if (!ejector->state() == core::Entity::Docked) {
+		std::stringstream msgstr;
+		if (ejector->owner()) {
+			msgstr << "^BDestroyed " << negotiated_amount << " " << aux::plural("unit", negotiated_amount) << " of " << name();
+			ejector->owner()->send(msgstr.str());
+			ejector->owner()->sound("game/eject");
+		}
+		return;
+	}
+	
+	// create cargo pod
+	
+	CargoPod *pod = new CargoPod();
+	
+	pod->set_color(ejector->color());
+	pod->set_color_second(ejector->color_second());
+	pod->set_zone(ejector->zone());
+	pod->set_location(ejector->location() + ejector->axis().up() * ejector->radius());
+	pod->set_axis(ejector->axis());
+		
+	pod->set_inventory(new core::Inventory());
+	pod->inventory()->set_capacity(item->info()->volume() * negotiated_amount);
+	pod->inventory()->add(new core::Item(*item));
+	pod->inventory()->set_dirty();
+	
+	if (ejector->owner()) {
+		std::stringstream msgstr;
+		msgstr << "^BEjected " << negotiated_amount << " " << aux::plural("unit", negotiated_amount) << " of " << name();
+		ejector->owner()->send(msgstr.str());
+		ejector->owner()->sound("game/eject");
+	}
+}
+
 void Cargo::list()
 {
 	core::Info::list(cargo_infotype);
diff --git a/src/game/base/cargo.h b/src/game/base/cargo.h
index 25b8739..3a42c74 100644
--- a/src/game/base/cargo.h
+++ b/src/game/base/cargo.h
@@ -21,6 +21,8 @@ public:
 	
 	void sell(core::EntityControlable *seller, core::Entity *buyer, const int amount);
 	
+	void eject(core::EntityControlable *ejector, const int amount);
+	
 	/* -- static functions -- */
 	static core::InfoType *cargo_infotype;
 	
diff --git a/src/game/base/cargopod.cc b/src/game/base/cargopod.cc
new file mode 100644
index 0000000..a3b44bf
--- /dev/null
+++ b/src/game/base/cargopod.cc
@@ -0,0 +1,28 @@
+/*
+   base/cargopod.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 "base/cargopod.h"
+#include "base/game.h"
+
+namespace game
+{
+	
+CargoPod::CargoPod() : EntityDynamic()
+{
+	entity_moduletypeid = cargopod_enttype;
+	set_name("Cargo pod");
+	set_label("cargopod");
+	
+	// FIXME hardcoded modelname
+	set_modelname("maps/cargo/pod");
+}
+
+CargoPod::~CargoPod()
+{
+
+}
+
+} // namespace game
\ No newline at end of file
diff --git a/src/game/base/cargopod.h b/src/game/base/cargopod.h
new file mode 100644
index 0000000..c843efb
--- /dev/null
+++ b/src/game/base/cargopod.h
@@ -0,0 +1,24 @@
+/*
+   base/cargopod.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_BASE_CARGOPOD_H__
+#define __INCLUDED_BASE_CARGOPOD_H__
+
+#include "core/entity.h"
+
+namespace game
+{
+
+class CargoPod : public core::EntityDynamic
+{
+public:
+	CargoPod();
+	virtual ~CargoPod();
+};
+
+} // namespace game
+
+#endif // __INCLUDED_BASE_CARGOPOD_H__
\ No newline at end of file
diff --git a/src/game/base/game.cc b/src/game/base/game.cc
index 19b3968..b426989 100644
--- a/src/game/base/game.cc
+++ b/src/game/base/game.cc
@@ -200,7 +200,7 @@ void Game::func_give(core::Player *player, const std::string &args)
 		std::string labelstr;
 		
 		if (!player->control()) {
-			player->send("^WNeed a ship to swap with!");
+			player->send("^WYou need to join the game first!");
 			return;
 		}
 		
@@ -346,6 +346,11 @@ void Game::func_give(core::Player *player, const std::string &args)
 // sell request from a player
 void Game::func_sell(core::Player *player, const std::string &args)
 {
+	if (!player->control()) {
+		player->send("^WYou need to join the game first!");
+		return;
+	}
+	
 	std::istringstream is(args);
 	std::string typestr;
 	std::string labelstr;
@@ -384,6 +389,11 @@ void Game::func_sell(core::Player *player, const std::string &args)
 // buy request from a player
 void Game::func_buy(core::Player *player, const std::string &args)
 {
+	if (!player->control()) {
+		player->send("^WYou need to join the game first!");
+		return;
+	}
+	
 	std::istringstream is(args);
 	std::string typestr;
 	std::string labelstr;
@@ -426,11 +436,55 @@ void Game::func_buy(core::Player *player, const std::string &args)
 	return;
 }
 
+// eject cargo request
+void Game::func_eject(core::Player *player, const std::string &args)
+{
+	if (!player->control()) {
+		player->send("^WYou need to join the game first!");
+		return;
+	}
+		
+	std::istringstream is(args);
+	std::string typestr;
+	std::string labelstr;
+
+	if (!(is >> typestr)) {
+		player->send("Usage: eject [string] [string] [int] eject an item: specify type, label and amount");
+		return;
+	} else {
+		aux::to_label(typestr);
+	}
+
+	if (!(is >> labelstr)) {
+		player->send("Usage: eject [string] [string] [int] eject an item: specify type, label and amount");
+		return;
+	} else {
+		aux::to_label(labelstr);
+	}
+
+	int amount = 0;
+	if (!(is >> amount)) 
+		amount = 0;
+	
+	if (typestr.compare("cargo") == 0) {
+		Cargo *cargo = Cargo::find(labelstr);
+		if (cargo) {
+			cargo->eject(player->control(), amount);			
+		} else {
+			player->send("Unkown cargo type '" + labelstr + "'");
+		}	
+	} else {
+		player->send("Unkown item type '" + typestr + "'");
+	}
+}
+
 // launch request
 void Game::func_launch(core::Player *player, std::string const &args)
 {
-	if (!player->control())
+	if (!player->control()) {
+		player->send("^WYou need to join the game first!");
 		return;
+	}
 
 	if (!player->view())
 		return;
@@ -494,8 +548,10 @@ void Game::func_launch(core::Player *player, std::string const &args)
 // respawn
 void Game::func_respawn(core::Player *player, std::string const &args)
 {
-	if (!player->control())
+	if (!player->control()) {
+		func_join(player, args);
 		return;
+	}
 
 	if (!(player->view() == player->control()))
 		return;
@@ -606,7 +662,10 @@ Game::Game() : core::Module("Project::OSiRiON", true)
 
 	func = core::Func::add("sell", Game::func_sell);
 	func->set_info("[string] [string] [int] sell an item: specify type, label and amount");
-	
+
+	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 = core::Func::add("give", Game::func_give);
 	func->set_info("cheat functions");
 		
diff --git a/src/game/base/game.h b/src/game/base/game.h
index 1aaba51..f4ce8c0 100644
--- a/src/game/base/game.h
+++ b/src/game/base/game.h
@@ -33,10 +33,11 @@ const unsigned int navpoint_enttype = 259;
 const unsigned int jumppoint_enttype = 260;
 const unsigned int jumpgate_enttype = 261;
 const unsigned int station_enttype = 262;
+const unsigned int cargopod_enttype = 263;
 
 // info class type constants
-const unsigned int shipmodel_class_id = 1;
-const unsigned int commodity_class_id = 2;
+//const unsigned int shipmodel_class_id = 1;
+//const unsigned int commodity_class_id = 2;
 
 /// default player settings
 class Default
@@ -109,6 +110,7 @@ private:
 	static void func_buy(core::Player *player, std::string const &args);
 	static void func_sell(core::Player *player, const std::string &args);
 	static void func_give(core::Player *player, const std::string &args);
+	static void func_eject(core::Player *player, const std::string &args);
 };
 
 /// factory function
-- 
cgit v1.2.3