diff options
| author | Stijn Buys <ingar@osirion.org> | 2008-09-28 15:05:13 +0000 | 
|---|---|---|
| committer | Stijn Buys <ingar@osirion.org> | 2008-09-28 15:05:13 +0000 | 
| commit | fd778219e40c5fbb4d0af1839cbc313caaf10d9d (patch) | |
| tree | b6e413f4c1a5ba4091503ba97c784278485d3933 /src/game/base/base.cc | |
| parent | bedcff956d253621ec00aa7d2919c22a4c88b0b2 (diff) | |
move base game module to new subdirectory
Diffstat (limited to 'src/game/base/base.cc')
| -rw-r--r-- | src/game/base/base.cc | 661 | 
1 files changed, 661 insertions, 0 deletions
| diff --git a/src/game/base/base.cc b/src/game/base/base.cc new file mode 100644 index 0000000..70d9335 --- /dev/null +++ b/src/game/base/base.cc @@ -0,0 +1,661 @@ +/* +   base/base.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 <string> + +#include "auxiliary/functions.h" +#include "core/gameserver.h" +#include "filesystem/filesystem.h" +#include "filesystem/inifile.h" +#include "base/base.h" +#include "base/navpoint.h" +#include "base/jumppoint.h" +#include "base/planet.h" +#include "base/racetrack.h" +#include "base/ship.h" +#include "base/star.h" +#include "math/mathlib.h" +#include "sys/sys.h" + +namespace base +{ + +ShipModel		*default_shipmodel = 0; +core::Zone		*default_zone = 0; + +/*----- engine game functions ------------------------------------- */ + +/// list the ship model registry +void func_list_ship(std::string const &args) +{ +	ShipModel::list(); +} + +/// a player joins the game +void func_join(core::Player *player, std::string const &args) +{ +	if (player->control()) +		return; + +	player->set_zone(default_zone); +	Ship *ship = new Ship(player, default_shipmodel); +	ship->set_zone(default_zone); +	player->set_control(ship); + +	core::server()->send_sound(player, "game/buy-ship"); +	 +	std::string message("^B"); +	message.append(player->name()); +	message.append("^B joins the game."); +	core::server()->broadcast(message); + +	player->player_dirty = true; +} + +/// a player joins the spectators +void func_spectate(core::Player *player, std::string const &args) +{ +	if (!player->control()) +		return; + +	std::string message("^B"); +	message.append(player->name()); +	message.append("^B spectates."); +	core::server()->broadcast(message); + +	if (player->control()) { +		player->remove_asset(player->control()); +	} +} + +/// a player buys a ship +void func_buy(core::Player *player, std::string const &args) +{ +	 +	std::string shipname; +	std::string helpstr; +	std::istringstream is(args); +	is >> shipname; +	aux::to_lowercase(shipname); + +	ShipModel *shipmodel = 0; +	for (ShipModel::iterator smit = ShipModel::registry.begin(); smit != ShipModel::registry.end(); smit++) { +		if (shipname == (*smit).first) { +			shipmodel = (*smit).second; +			break; +		} + +		if (helpstr.size()) +			helpstr.append("^N|^B"); +		helpstr.append((*smit).second->label()); +	} + +	if (shipmodel) { +		// player has only ship for now +		if (player->control()) { +			player->remove_asset(player->control()); +		} + +		Ship * ship = new Ship(player, shipmodel); +		if (player->zone()) { +			ship->set_zone(player->zone()); +		} else { +			ship->set_zone(default_zone); +		} +		player->set_control(ship); +		 +		core::server()->broadcast("^B" + player->name() + " ^Bpurchased " + aux::article(shipmodel->name())); +		core::server()->send_sound(player, "game/buy-ship"); + +	} else { +		core::server()->send(player, "Usage: buy [^B" + helpstr + "^N]"); +	} +} + +/// a player sends standard hails +void func_hail(core::Player *player, std::string const &args) +{ +	std::string  target; +	std::istringstream is(args); +	if (!(is >> target)) { +		core::server()->send(player, "Usage: hail [player]"); +		return; +	} + +	core::Player *targetplayer = core::server()->find_player(target); +	if (!targetplayer) { +		core::server()->send(player, "^BPlayer " + target + "^B not found."); +		return; +	} + +	core::server()->send(player, "^BYou hail " + targetplayer->name() + "^B."); +	core::server()->send_sound(player, "com/hail"); + +	core::server()->send(targetplayer, "^B" + player->name() + "^B hails you!"); +	core::server()->send_sound(targetplayer, "com/hail"); +} + +/// a player actives the hyperspace jump drive on his ship +void func_jump(core::Player *player, std::string const &args) +{ +	if (!player->control()) +		return; +	if (!player->control()->moduletype() == ship_enttype) +		return; +	Ship * ship = static_cast<Ship *>(player->control()); +	ship->jump(args); +} + +/// a player actives the kinetic impulse drive on his ship +void func_impulse(core::Player *player, std::string const &args) +{ +	if (!player->control()) +		return; +	if (!player->control()->moduletype() == ship_enttype) +		return; +	Ship * ship = static_cast<Ship *>(player->control()); +	ship->impulse(); +} + +/* ---- The Game class --------------------------------------------- */ + +Base 			*Base::game_instance = 0; + +Base::Base() : core::Module("Project::OSiRiON") +{ +	game_instance = this; +	g_impulsespeed = 0; +} + +Base::~Base() +{ +	game_instance = 0; +} + +void Base::init() +{ +	module_running = false; + +	ShipModel::clear(); + +	if (!load_world()) { +		abort(); +		return; +	} +		 +	if (!load_ships()) { +		abort(); +		return; +	} + +	// add engine game functions +	core::Func *func = 0; +	 +	func = core::Func::add("join", (core::GameFuncPtr) func_join); +	func->set_info("join the game"); +	func = core::Func::add("hail", (core::GameFuncPtr) func_hail); +	func->set_info("send a standard hail"); +	func = core::Func::add("spectate", (core::GameFuncPtr) func_spectate); +	func->set_info("leave the game and spectate"); + +	func = core::Func::add("buy", (core::GameFuncPtr) func_buy); +	func->set_info("buy a ship"); + +	func = core::Func::add("jump", (core::GameFuncPtr) func_jump); +	func->set_info("[string] activate or deactivate hyperspace jump drive"); + +	func = core::Func::add("impulse", (core::GameFuncPtr) func_impulse); +	func->set_info("activate are deactive kinetic impulse drive"); + +	// add engine core functions +	func = core::Func::add("list_ship", (core::FuncPtr) func_list_ship); +	func->set_info("list ship statistics"); + +	g_impulsespeed = core::Cvar::get("g_impulsespeed", "15", core::Cvar::Game | core::Cvar::Archive); +	g_impulsespeed->set_info("[float] speed of the impulse drive"); + +	g_impulseacceleration = core::Cvar::get("g_impulseacceleration", "5", core::Cvar::Game | core::Cvar::Archive); +	g_impulseacceleration->set_info("[float] acceleration of the impulse drive"); + +	g_strafespeed = core::Cvar::get("g_strafespeed", "0.003", core::Cvar::Game | core::Cvar::Archive); +	g_strafespeed->set_info("[float] strafe speed"); + +	g_jumppointrange = core::Cvar::get("g_jumppointrange", "512", core::Cvar::Game | core::Cvar::Archive); +	g_jumppointrange->set_info("[float] jumppoint range"); + +	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() +{ +	g_impulsespeed = 0; +	// game functions are automaticly removed + +	// remove engine core functions +	core::Func::remove("list_ship"); + +	ShipModel::clear(); +	module_running = false; +} + +bool Base::load_world() +{ +	std::string inifilename("world"); + +	filesystem::IniFile worldini; +	worldini.open(inifilename); + +	if (!worldini.is_open()) { +		con_error << "Could not open " << worldini.name() << std::endl; +		return false; +	} + +	core::Zone *zone = 0; +	std::string label; + +	while (worldini.getline()) { + +		if (worldini.got_section()) { + +			if (worldini.got_section("world")) { +				continue; +			} else { +				con_warn << worldini.name() << "  unknown section '" << worldini.section() << "' at line " << worldini.line() << std::endl; +			} + +		} else if (worldini.section().compare("world") == 0 ) { +			if (worldini.got_key_string("zone", label)) { +				aux::to_label(label); +				zone = new core::Zone(label); +				core::Zone::add(zone); +			} +		} +	} +	worldini.close(); + +	if (!core::Zone::registry().size()) { +		con_error << "No zones found!" << std::endl; +		return false; +	} + +	con_debug << "  " << worldini.name() << " " << core::Zone::registry().size() << " zones" << std::endl; + +	for (core::Zone::Registry::iterator it = core::Zone::registry().begin(); it != core::Zone::registry().end(); it++) { +		if (!load_zone((*it).second)) { +			return false; +		} +	} + +	for (core::Zone::Registry::iterator it = core::Zone::registry().begin(); it != core::Zone::registry().end(); it++) { +		if (!validate_zone((*it).second)) { +			return false; +		} +	} + +	if (!default_zone) { +		con_error << "No default zone found!" << std::endl; +		return false; +	} + +	return true; +} + +bool Base::got_entity_key(filesystem::IniFile &inifile, core::Entity *entity) +{ +	std::string shapename; +	std::string strval; +	float direction; +	float pitch; +	float roll; + +	if (inifile.got_key_string("shape", shapename)) { + +		if (shapename.compare("axis") == 0) { +			entity->entity_shape = core::Entity::Axis; +			return true; +		} else if (shapename.compare("cube") == 0) { +			entity->entity_shape = core::Entity::Cube; +			return true; +		} else if (shapename.compare("diamond") == 0) { +			entity->entity_shape = core::Entity::Diamond; +			return true; +		} else if (shapename.compare("sphere") == 0) { +			entity->entity_shape = core::Entity::Sphere; +			return true; +		} else { +			con_warn << inifile.name() << " unknown shape '" << shapename << "' at line " << inifile.line() << std::endl; +			return false; +		} + +	} else if (inifile.got_key_string("label", strval)) { +		aux::to_label(strval); +		entity->entity_label.assign(strval);		 +		return true; +	} else if (inifile.got_key_string("name", strval)) { +		aux::strip_quotes(strval); +		entity->entity_name.assign(strval); +		return true; +	} else if (inifile.got_key_string("model", entity->entity_modelname)) { +		return true; +	} else if (inifile.got_key_angle("direction", direction)) { +		entity->axis().change_direction(direction); +		return true; +	} else if (inifile.got_key_angle("pitch", pitch)) { +		entity->axis().change_pitch(pitch); +		return true; +	} else if (inifile.got_key_angle("roll", roll)) { +		entity->axis().change_roll(roll); +		return true; +	} else if (inifile.got_key_angle("radius", entity->entity_radius)) { +		return true; +	} else if (inifile.got_key_vector3f("location", entity->entity_location)) { +		return true; +	} else if (inifile.got_key_color("color", entity->entity_color)) { +		return true; +	} else if (inifile.got_key_color("colorsecond", entity->entity_color_second)) { +		return true; +	} + +	return false; +} + +bool Base::load_zone(core::Zone *zone) +{ +	using math::Vector3f; +	using math::Color; + +	std::string inifilename("zones/"); +	inifilename.append(zone->label()); + +	filesystem::IniFile zoneini; +	zoneini.open(inifilename); + +	if (!zoneini.is_open()) { +		con_error << "Could not open " << zoneini.name() << std::endl; +		return false; +	} + +	size_t count = 0; + +	Planet *planet = 0; +	Star *star = 0; +	NavPoint *navpoint = 0; +	JumpPoint *jumppoint = 0; +	RaceTrack *racetrack = 0; +	CheckPoint *checkpoint = 0; +	core::Entity *entity = 0; + +	bool b; + +	std::string strval; + +	// set th default sky +	zone->set_sky("sky"); + +	while (zoneini.getline()) { +		if (zoneini.got_key()) { +			if (zoneini.section().compare("zone") == 0) { +				if (zoneini.got_key_string("name", strval)) { +					aux::strip_quotes(strval); +					zone->set_name(strval); +					continue; +				} else if (zoneini.got_key_string("sky", strval)) { +					zone->set_sky(strval); +					continue; +				} else if (zoneini.got_key_bool("default", b)) { +					if (b) default_zone = zone; +					continue; +				} else { +					con_warn << zoneini.name() << " unknown key '" << zoneini.key() << "' at line " << zoneini.line() << std::endl; +				} +			} else if (zoneini.section().compare("star") == 0) { +				if (got_entity_key(zoneini, star)) { +					continue; +				} else if (zoneini.got_key_string("texture", star->entity_texture)) { +					 continue; +				} else { +					con_warn << zoneini.name() << " unknown key '" << zoneini.key() << "' at line " << zoneini.line() << std::endl; +				} +			} else if (zoneini.section().compare("navpoint") == 0) { +				if (got_entity_key(zoneini, navpoint)) { +					continue; +				} else { +					con_warn << zoneini.name() << " unknown key '" << zoneini.key() << "' at line " << zoneini.line() << std::endl; +				} +			} else if (zoneini.section().compare("jumppoint") == 0) { +				if (got_entity_key(zoneini, jumppoint)) { +					continue; +				} else if (zoneini.got_key_string("target", jumppoint->jumppoint_targetlabel)) { +					continue; +				} else { +					con_warn << zoneini.name() << " unknown key '" << zoneini.key() << "' at line " << zoneini.line() << std::endl; +				} +			} else if (zoneini.section().compare("planet") == 0) { +				if (got_entity_key(zoneini, planet)) { +					continue; +				} else if (zoneini.got_key_string("texture", planet->entity_texture)) { +					 continue; +				} else if (zoneini.got_key_float("rotationspeed", planet->entity_rotationspeed)) { +					continue; +				} else { +					con_warn << zoneini.name() << " unknown key '" << zoneini.key() << "' at line " << zoneini.line() << std::endl; +				} + +			} else if (zoneini.section().compare("racetrack") == 0) { +				if (got_entity_key(zoneini, racetrack)) { +					continue; +				} else { +					con_warn << zoneini.name() << " unknown key '" << zoneini.key() << "' at line " << zoneini.line() << std::endl; +				} + +			} else if (zoneini.section().compare("checkpoint") == 0) { +				if (got_entity_key(zoneini, checkpoint)) { +					continue; +				} else { +					con_warn << zoneini.name() << " unknown key '" << zoneini.key() << "' at line " << zoneini.line() << std::endl; +				} + +			} else if (zoneini.section().compare("entity") == 0) { +				if (got_entity_key(zoneini, entity)) { +					continue; +				} else { +					con_warn << zoneini.name() << " unknown key '" << zoneini.key() << "' at line " << zoneini.line() << std::endl; +				} +			} +		} else if (zoneini.got_section("zone")) { +			continue; + +		} else if (zoneini.got_section("star")) { +			star = new Star(); +			star->set_zone(zone); +			count ++; + +		} else if (zoneini.got_section("navpoint")) { +			navpoint = new NavPoint(); +			navpoint->set_zone(zone); +			count ++; +		 +		} else if (zoneini.got_section("jumppoint")) { +			jumppoint = new JumpPoint(); +			jumppoint->set_zone(zone); +			count ++; + +		} else if(zoneini.got_section("racetrack")) { +			racetrack = new RaceTrack(); +			racetrack->set_zone(zone); + +		} else if(zoneini.got_section("checkpoint")) { +			checkpoint = new CheckPoint(racetrack); +			if (!racetrack) { +				con_warn << zoneini.name() << " checkpoint without racetrack at line " << zoneini.line() << std::endl; +			} + +		} else if (zoneini.got_section("planet")) { +			planet = new Planet(); +			planet->set_zone(zone); +			count ++; + +		} else if (zoneini.got_section("entity")) { +			entity = new core::Entity(); +			entity->entity_flags += core::Entity::Static; +			entity->set_zone(zone); +			count ++; + +		} else if (zoneini.got_section()) { +			con_warn << zoneini.name() << " unknown section '" << zoneini.section() << "' at line " << zoneini.line() << std::endl; +		} +	} +	zoneini.close(); + +	con_debug << "  " << zoneini.name() << " " << zone->content().size() << " entities" << std::endl; + + +	return true; +} + +bool Base::validate_zone(core::Zone *zone) +{ +	con_debug << "  validating " << zone->name() << std::endl; + +	for (core::Zone::Content::iterator it = zone->content().begin(); it != zone->content().end(); it++) { +		core::Entity *entity = (*it); + +		if (entity->entity_moduletypeid == jumppoint_enttype) { +			JumpPoint *jumppoint = static_cast<JumpPoint *>(entity); +			 +			if (jumppoint->targetlabel().size() < 3) { +				con_warn << "  Jumppoint with invalid target label '" << jumppoint->targetlabel() << "'\n"; +				continue; +			} +			size_t pos = jumppoint->targetlabel().find(':'); +			if ((pos < 1 ) || (pos >= (jumppoint->targetlabel().size()-1))) { +				con_warn << "  Jumppoint with invalid target label '" << jumppoint->targetlabel() << "'\n"; +				continue; +			} + +			std::string zonelabel(jumppoint->targetlabel().substr(0, pos)); +			std::string entitylabel(jumppoint->targetlabel().substr(pos+1, jumppoint->targetlabel().size()-pos)); + +			core::Zone *targetzone = core::Zone::find(zonelabel); +			if (!targetzone) { +				con_warn << "  Jumppoint with invalid target zone '" << zonelabel << "'\n"; +				continue; +			} + +			core::Entity *targetentity = targetzone->find_entity(entitylabel); +			if (!targetentity) { +				con_warn << "  Could not find target jumppoint '" << entitylabel << "'\n"; +				continue; +			} + +			if (targetentity->moduletype() != jumppoint_enttype) { +				con_warn << "  Jumppoint with invalid target jumppoint '" << entitylabel << "'\n"; +				continue; +			} + +			jumppoint->jumppoint_target = static_cast<JumpPoint *>(targetentity); + +			//con_debug << "  Jumppoint " << zone->label() << ":" << jumppoint->label() << " with target " << jumppoint->targetlabel() << std::endl; +		} +	} + +	return true; +} + +// read ship model specifications +bool Base::load_ships() +{ +	using math::Vector3f; +	using math::Color; + +	default_shipmodel = 0; + +	filesystem::IniFile shipsini; +	shipsini.open("ships"); +	if (!shipsini.is_open()) { +		con_error << "Could not open ini/ships.ini!" << std::endl; +		return false; +	} + +	ShipModel *shipmodel = 0; +	std::string label; +	bool b; + +	while (shipsini.getline()) { +		if (shipsini.got_key()) { +			if (shipsini.section().compare("ship") == 0) { +				if (shipsini.got_key_string("label", label)) { +					aux::to_label(label); +					shipmodel->shipmodel_label.assign(label); +					ShipModel::add(shipmodel); +					continue; +				} else if (shipsini.got_key_string("name",shipmodel->shipmodel_name)) { +					 continue; +				} else if (shipsini.got_key_string("model", shipmodel->shipmodel_modelname)) { +					continue; +				} else if (shipsini.got_key_bool("default", b)) { +					if (b) default_shipmodel = shipmodel; +					continue; +				} else if (shipsini.got_key_bool("jumpdrive", shipmodel->shipmodel_jumpdrive)) { +					continue; +				} else if (shipsini.got_key_float("acceleration", shipmodel->shipmodel_acceleration)) { +					continue; +				} else if (shipsini.got_key_float("maxspeed", shipmodel->shipmodel_maxspeed)) { +					continue; +				} else if (shipsini.got_key_float("turnspeed", shipmodel->shipmodel_turnspeed)) { +					math::clamp(shipmodel->shipmodel_turnspeed, 0.0f, 90.0f); +					continue; +				} else { +					con_warn << shipsini.name() << " unknown key '" << shipsini.key() << "' at line " << shipsini.line() << std::endl; +				} +			} +		} else if (shipsini.got_section("ship")) { +			shipmodel = new ShipModel(); + +			if (!default_shipmodel) +				default_shipmodel = shipmodel;  + +		} else if (shipsini.got_section()) { +			con_warn << shipsini.name() << " unknown section '" << shipsini.section() << "' at line " << shipsini.line() << std::endl; +		} +	} +	shipsini.close(); + +	con_debug << "  " << shipsini.name() << " " << ShipModel::registry.size() << " ship models" << std::endl; + +	if (!default_shipmodel) { +		con_error << "No default ship model found!\n"; +		return false; +	} + +	return true; +} + +void Base::frame(float seconds) +{ +	if (!running()) +		return; +} + +void Base::player_connect(core::Player *player) +{ +	std::string args; +	player->set_zone(default_zone); +	func_spectate(player, args); +} + +void Base::player_disconnect(core::Player *player) +{ +	player->remove_asset(player->control()); +} + +} // namespace game + | 
