Added code for the following:

a) Complete Unit Rotation for multi-player
b) Added support for user defined data folders
This commit is contained in:
Mark Vejvoda 2010-03-18 21:26:40 +00:00
parent 3580e13468
commit f838293632
35 changed files with 4517 additions and 77 deletions

View File

@ -0,0 +1,83 @@
// ==============================================================
// This file is part of Glest (www.glest.org)
//
// Copyright (C) 2001-2009 Martiño Figueroa
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version
// ==============================================================
#include "auto_test.h"
#include "program.h"
#include "main_menu.h"
#include "menu_state_new_game.h"
#include "menu_state_scenario.h"
#include "game.h"
#include "leak_dumper.h"
#include "config.h"
namespace Glest{ namespace Game{
// =====================================================
// class AutoTest
// =====================================================
const time_t AutoTest::invalidTime = -1;
const time_t AutoTest::gameTime = 60*20;
// ===================== PUBLIC ========================
AutoTest::AutoTest(){
gameStartTime = invalidTime;
random.init(time(NULL));
}
AutoTest & AutoTest::getInstance(){
static AutoTest autoTest;
return autoTest;
}
void AutoTest::updateIntro(Program *program){
program->setState(new MainMenu(program));
}
void AutoTest::updateRoot(Program *program, MainMenu *mainMenu){
mainMenu->setState(new MenuStateNewGame(program, mainMenu));
}
void AutoTest::updateNewGame(Program *program, MainMenu *mainMenu){
mainMenu->setState(new MenuStateScenario(program, mainMenu, Config::getInstance().getPathListForType(ptScenarios)));
}
void AutoTest::updateScenario(MenuStateScenario *menuStateScenario){
gameStartTime = invalidTime;
int scenarioIndex = random.randRange(0, menuStateScenario->getScenarioCount()-1);
menuStateScenario->setScenario(scenarioIndex);
menuStateScenario->launchGame();
}
void AutoTest::updateGame(Game *game){
// record start time
if(gameStartTime==invalidTime)
{
gameStartTime = time(NULL);
}
// quit if we've espend enough time in the game
if(time(NULL)-gameStartTime>gameTime){
game->quitGame();
}
}
void AutoTest::updateBattleEnd(Program *program){
program->setState(new MainMenu(program));
}
}}//end namespace

View File

@ -0,0 +1,380 @@
// ==============================================================
// This file is part of Glest (www.glest.org)
//
// Copyright (C) 2001-2008 Martiño Figueroa
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version
// ==============================================================
#include "commander.h"
#include "world.h"
#include "unit.h"
#include "conversion.h"
#include "upgrade.h"
#include "command.h"
#include "command_type.h"
#include "network_manager.h"
#include "console.h"
#include "config.h"
#include "platform_util.h"
#include "leak_dumper.h"
#include "game.h"
using namespace Shared::Graphics;
using namespace Shared::Util;
using namespace Shared::Platform;
namespace Glest{ namespace Game{
// =====================================================
// class Commander
// =====================================================
// ===================== PUBLIC ========================
void Commander::init(World *world){
this->world= world;
}
CommandResult Commander::tryGiveCommand(const Unit* unit, const CommandType *commandType, const Vec2i &pos, const UnitType* unitType) const{
NetworkCommand networkCommand(nctGiveCommand, unit->getId(), commandType->getId(), pos, unitType->getId());
return pushNetworkCommand(&networkCommand);
}
CommandResult Commander::tryGiveCommand(const Selection *selection, CommandClass commandClass, const Vec2i &pos, const Unit *targetUnit) const{
if(!selection->isEmpty()){
Vec2i refPos, currPos;
CommandResultContainer results;
refPos= computeRefPos(selection);
//give orders to all selected units
for(int i=0; i<selection->getCount(); ++i){
const Unit *unit= selection->getUnit(i);
const CommandType *ct= unit->getType()->getFirstCtOfClass(commandClass);
if(ct!=NULL){
int targetId= targetUnit==NULL? Unit::invalidId: targetUnit->getId();
int unitId= selection->getUnit(i)->getId();
Vec2i currPos= computeDestPos(refPos, selection->getUnit(i)->getPos(), pos);
NetworkCommand networkCommand(nctGiveCommand, unitId, ct->getId(), currPos, -1, targetId);
//every unit is ordered to a different pos
CommandResult result= pushNetworkCommand(&networkCommand);
results.push_back(result);
}
else{
results.push_back(crFailUndefined);
}
}
return computeResult(results);
}
else{
return crFailUndefined;
}
}
CommandResult Commander::tryGiveCommand(const Selection *selection, const CommandType *commandType, const Vec2i &pos, const Unit *targetUnit) const{
if(!selection->isEmpty() && commandType!=NULL){
Vec2i refPos;
CommandResultContainer results;
refPos= computeRefPos(selection);
//give orders to all selected units
for(int i=0; i<selection->getCount(); ++i){
int targetId= targetUnit==NULL? Unit::invalidId: targetUnit->getId();
int unitId= selection->getUnit(i)->getId();
Vec2i currPos= computeDestPos(refPos, selection->getUnit(i)->getPos(), pos);
NetworkCommand networkCommand(nctGiveCommand, unitId, commandType->getId(), currPos, -1, targetId);
//every unit is ordered to a different position
CommandResult result= pushNetworkCommand(&networkCommand);
results.push_back(result);
}
return computeResult(results);
}
else{
return crFailUndefined;
}
}
//auto command
CommandResult Commander::tryGiveCommand(const Selection *selection, const Vec2i &pos, const Unit *targetUnit) const{
if(!selection->isEmpty()){
Vec2i refPos, currPos;
CommandResultContainer results;
//give orders to all selected units
refPos= computeRefPos(selection);
for(int i=0; i<selection->getCount(); ++i){
//every unit is ordered to a different pos
currPos= computeDestPos(refPos, selection->getUnit(i)->getPos(), pos);
//get command type
const CommandType *commandType= selection->getUnit(i)->computeCommandType(pos, targetUnit);
//give commands
if(commandType!=NULL){
int targetId= targetUnit==NULL? Unit::invalidId: targetUnit->getId();
int unitId= selection->getUnit(i)->getId();
NetworkCommand networkCommand(nctGiveCommand, unitId, commandType->getId(), currPos, -1, targetId);
CommandResult result= pushNetworkCommand(&networkCommand);
results.push_back(result);
}
else{
results.push_back(crFailUndefined);
}
}
return computeResult(results);
}
else{
return crFailUndefined;
}
}
CommandResult Commander::tryCancelCommand(const Selection *selection) const{
for(int i=0; i<selection->getCount(); ++i){
NetworkCommand command(nctCancelCommand, selection->getUnit(i)->getId());
pushNetworkCommand(&command);
}
return crSuccess;
}
void Commander::trySetMeetingPoint(const Unit* unit, const Vec2i &pos)const{
NetworkCommand command(nctSetMeetingPoint, unit->getId(), -1, pos);
pushNetworkCommand(&command);
}
// ==================== PRIVATE ====================
Vec2i Commander::computeRefPos(const Selection *selection) const{
Vec2i total= Vec2i(0);
for(int i=0; i<selection->getCount(); ++i){
total= total+selection->getUnit(i)->getPos();
}
return Vec2i(total.x/ selection->getCount(), total.y/ selection->getCount());
}
Vec2i Commander::computeDestPos(const Vec2i &refUnitPos, const Vec2i &unitPos, const Vec2i &commandPos) const{
Vec2i pos;
Vec2i posDiff= unitPos-refUnitPos;
if(abs(posDiff.x)>=3){
posDiff.x= posDiff.x % 3;
}
if(abs(posDiff.y)>=3){
posDiff.y= posDiff.y % 3;
}
pos= commandPos+posDiff;
world->getMap()->clampPos(pos);
return pos;
}
CommandResult Commander::computeResult(const CommandResultContainer &results) const{
switch(results.size()){
case 0:
return crFailUndefined;
case 1:
return results.front();
default:
for(int i=0; i<results.size(); ++i){
if(results[i]!=crSuccess){
return crSomeFailed;
}
}
return crSuccess;
}
}
CommandResult Commander::pushNetworkCommand(const NetworkCommand* networkCommand) const{
GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface();
const Unit* unit= world->findUnitById(networkCommand->getUnitId());
CommandResult cr= crSuccess;
//validate unit
if(unit==NULL){
char szBuf[1024]="";
sprintf(szBuf,"In [%s::%s - %d] Command refers to non existant unit id = %d. Game out of synch.",
__FILE__,__FUNCTION__,__LINE__,networkCommand->getUnitId());
throw runtime_error(szBuf);
}
//add the command to the interface
gameNetworkInterface->requestCommand(networkCommand);
//calculate the result of the command
if(networkCommand->getNetworkCommandType()==nctGiveCommand){
Command* command= buildCommand(networkCommand);
cr= unit->checkCommand(command);
delete command;
}
return cr;
}
void Commander::updateNetwork(){
NetworkManager &networkManager= NetworkManager::getInstance();
//chech that this is a keyframe
if( !networkManager.isNetworkGame() || (world->getFrameCount() % GameConstants::networkFramePeriod)==0){
GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface();
//update the keyframe
gameNetworkInterface->updateKeyframe(world->getFrameCount());
//give pending commands
for(int i= 0; i < gameNetworkInterface->getPendingCommandCount(); ++i){
giveNetworkCommand(gameNetworkInterface->getPendingCommand(i));
}
gameNetworkInterface->clearPendingCommands();
}
}
void Commander::giveNetworkCommandSpecial(const NetworkCommand* networkCommand) const {
switch(networkCommand->getNetworkCommandType()) {
case nctNetworkCommand: {
if(Socket::enableDebugText) printf("In [%s::%s Line: %d] found nctNetworkCommand\n",__FILE__,__FUNCTION__,__LINE__);
switch(networkCommand->getCommandTypeId()) {
case ncstRotateUnit: {
if(Socket::enableDebugText) printf("In [%s::%s Line: %d] found ncstRotateUnit [%d]\n",__FILE__,__FUNCTION__,__LINE__,networkCommand->getTargetId());
//!!!
int unitTypeId = networkCommand->getUnitId();
int factionIndex = networkCommand->getUnitTypeId();
int rotateAmount = networkCommand->getTargetId();
//const Faction *faction = world->getFaction(factionIndex);
//const UnitType* unitType= world->findUnitTypeById(faction->getType(), factionIndex);
char unitKey[50]="";
sprintf(unitKey,"%d_%d",unitTypeId,factionIndex);
if(Socket::enableDebugText) printf("In [%s::%s Line: %d] unitKey = [%s]\n",__FILE__,__FUNCTION__,__LINE__,unitKey);
Game *game = this->world->getGame();
Gui *gui = game->getGui();
gui->setUnitTypeBuildRotation(unitKey,rotateAmount);
//unit->setRotateAmount(networkCommand->getTargetId());
if(Socket::enableDebugText) printf("In [%s::%s Line: %d] found ncstRotateUnit [%d]\n",__FILE__,__FUNCTION__,__LINE__,networkCommand->getTargetId());
}
break;
}
if(Socket::enableDebugText) printf("In [%s::%s Line: %d] found nctNetworkCommand\n",__FILE__,__FUNCTION__,__LINE__);
}
break;
default:
assert(false);
}
}
void Commander::giveNetworkCommand(const NetworkCommand* networkCommand) const {
if(networkCommand->getNetworkCommandType() == nctNetworkCommand) {
giveNetworkCommandSpecial(networkCommand);
}
else {
Unit* unit= world->findUnitById(networkCommand->getUnitId());
//exec ute command, if unit is still alive
if(unit!=NULL) {
switch(networkCommand->getNetworkCommandType()){
case nctGiveCommand:{
assert(networkCommand->getCommandTypeId()!=CommandType::invalidId);
if(Socket::enableDebugText) printf("In [%s::%s Line: %d] found nctGiveCommand networkCommand->getUnitId() = %d\n",__FILE__,__FUNCTION__,__LINE__,networkCommand->getUnitId());
Command* command= buildCommand(networkCommand);
unit->giveCommand(command);
if(Socket::enableDebugText) printf("In [%s::%s Line: %d] found nctGiveCommand networkCommand->getUnitId() = %d\n",__FILE__,__FUNCTION__,__LINE__,networkCommand->getUnitId());
}
break;
case nctCancelCommand: {
if(Socket::enableDebugText) printf("In [%s::%s Line: %d] found nctCancelCommand\n",__FILE__,__FUNCTION__,__LINE__);
unit->cancelCommand();
if(Socket::enableDebugText) printf("In [%s::%s Line: %d] found nctCancelCommand\n",__FILE__,__FUNCTION__,__LINE__);
}
break;
case nctSetMeetingPoint: {
if(Socket::enableDebugText) printf("In [%s::%s Line: %d] found nctSetMeetingPoint\n",__FILE__,__FUNCTION__,__LINE__);
unit->setMeetingPos(networkCommand->getPosition());
if(Socket::enableDebugText) printf("In [%s::%s Line: %d] found nctSetMeetingPoint\n",__FILE__,__FUNCTION__,__LINE__);
}
break;
default:
assert(false);
}
}
else {
if(Socket::enableDebugText) printf("In [%s::%s Line: %d] NULL Unit for id = %d, networkCommand->getNetworkCommandType() = %d\n",__FILE__,__FUNCTION__,__LINE__,networkCommand->getUnitId(),networkCommand->getNetworkCommandType());
}
}
}
Command* Commander::buildCommand(const NetworkCommand* networkCommand) const{
assert(networkCommand->getNetworkCommandType()==nctGiveCommand);
Unit* target= NULL;
const CommandType* ct= NULL;
const Unit* unit= world->findUnitById(networkCommand->getUnitId());
//validate unit
if(unit == NULL) {
char szBuf[1024]="";
sprintf(szBuf,"In [%s::%s - %d] Can not find unit with id: %d. Game out of synch.",
__FILE__,__FUNCTION__,__LINE__,networkCommand->getUnitId());
throw runtime_error(szBuf);
}
const UnitType* unitType= world->findUnitTypeById(unit->getFaction()->getType(), networkCommand->getUnitTypeId());
ct= unit->getType()->findCommandTypeById(networkCommand->getCommandTypeId());
//validate command type
if(ct == NULL) {
char szBuf[1024]="";
sprintf(szBuf,"In [%s::%s - %d] Can not find command type with id = %d in unit = %d [%s]. Game out of synch.",
__FILE__,__FUNCTION__,__LINE__,networkCommand->getCommandTypeId(),unit->getId(), unit->getDesc().c_str());
throw runtime_error(szBuf);
}
//get target, the target might be dead due to lag, cope with it
if(networkCommand->getTargetId()!=Unit::invalidId){
target= world->findUnitById(networkCommand->getTargetId());
}
//create command
Command *command= NULL;
if(unitType!=NULL){
command= new Command(ct, networkCommand->getPosition(), unitType);
}
else if(target==NULL){
command= new Command(ct, networkCommand->getPosition());
}
else{
command= new Command(ct, target);
}
//issue command
return command;
}
}}//end namespace

View File

@ -0,0 +1,69 @@
// ==============================================================
// This file is part of Glest (www.glest.org)
//
// Copyright (C) 2001-2008 Martiño Figueroa
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version
// ==============================================================
#ifndef _GLEST_GAME_COMMANDER_H_
#define _GLEST_GAME_COMMANDER_H_
#include <vector>
#include "vec.h"
#include "selection.h"
#include "command_type.h"
using std::vector;
namespace Glest{ namespace Game{
using Shared::Graphics::Vec2i;
class World;
class Unit;
class Command;
class CommandType;
class NetworkCommand;
// =====================================================
// class Commander
//
/// Gives commands to the units
// =====================================================
class Commander{
private:
typedef vector<CommandResult> CommandResultContainer;
private:
World *world;
public:
void init(World *world);
void updateNetwork();
CommandResult tryGiveCommand(const Unit* unit, const CommandType *commandType, const Vec2i &pos, const UnitType* unitType) const;
CommandResult tryGiveCommand(const Selection *selection, CommandClass commandClass, const Vec2i &pos= Vec2i(0), const Unit *targetUnit= NULL) const;
CommandResult tryGiveCommand(const Selection *selection, const CommandType *commandType, const Vec2i &pos= Vec2i(0), const Unit *targetUnit= NULL) const;
CommandResult tryGiveCommand(const Selection *selection, const Vec2i &pos, const Unit *targetUnit= NULL) const;
CommandResult tryCancelCommand(const Selection *selection) const;
void trySetMeetingPoint(const Unit* unit, const Vec2i &pos) const;
CommandResult pushNetworkCommand(const NetworkCommand* networkCommand) const;
void giveNetworkCommandSpecial(const NetworkCommand* networkCommand) const;
private:
Vec2i computeRefPos(const Selection *selection) const;
Vec2i computeDestPos(const Vec2i &refUnitPos, const Vec2i &unitPos, const Vec2i &commandPos) const;
CommandResult computeResult(const CommandResultContainer &results) const;
void giveNetworkCommand(const NetworkCommand* networkCommand) const;
Command* buildCommand(const NetworkCommand* networkCommand) const;
};
}} //end namespace
#endif

View File

@ -93,8 +93,10 @@ void Game::load(){
logger.setSubtitle(formatString(scenarioName));
}
Config &config = Config::getInstance();
//tileset
world.loadTileset("tilesets/"+tilesetName, &checksum);
world.loadTileset(config.getPathListForType(ptTilesets), tilesetName, &checksum);
set<string> factions;
for ( int i=0; i < gameSettings.getFactionCount(); ++i ) {
@ -102,7 +104,7 @@ void Game::load(){
}
//tech, load before map because of resources
world.loadTech("techs/"+techName, factions, &checksum);
world.loadTech(config.getPathListForType(ptTechs), techName, factions, &checksum);
//map
world.loadMap(Map::getMapPath(mapName), &checksum);
@ -110,7 +112,7 @@ void Game::load(){
//scenario
if(!scenarioName.empty()){
Lang::getInstance().loadScenarioStrings(gameSettings.getScenarioDir(), scenarioName);
world.loadScenario(Scenario::getScenarioPath(gameSettings.getScenarioDir(), scenarioName), &checksum);
world.loadScenario(gameSettings.getScenarioDir(), &checksum);
}
}

View File

@ -1369,7 +1369,7 @@ void Renderer::renderUnits(){
//!!!
if(allowRotateUnits == true) {
float rotateAmount = unit->getRotateAmount();
if(rotateAmount >= 0) {
if(rotateAmount > 0) {
//if(Socket::enableDebugText) printf("In [%s::%s] rotate unit id = %d amount = %f\n",__FILE__,__FUNCTION__,unit->getId(),rotateAmount);
glRotatef(rotateAmount, 0.f, 1.f, 0.f);
}

View File

@ -28,6 +28,10 @@
#include "faction.h"
#include "leak_dumper.h"
#include "network_types.h"
#include "network_manager.h"
using namespace Shared::Graphics;
using namespace Shared::Util;
@ -311,6 +315,10 @@ void Gui::groupKey(int groupIndex){
}
}
void Gui::setUnitTypeBuildRotation(string unitKey, float value) {
unitTypeBuildRotation[unitKey] = value;
}
float Gui::getUnitTypeBuildRotation(string unitKey) const {
float rotationValue = -1;
@ -335,7 +343,7 @@ void Gui::hotKey(char key){
selectInterestingUnit(iutBuiltBuilding);
}
else if(key=='R'){
//!!!
// Here the user triggers a unit rotation while placing a unit
if(allowRotateUnits == true && isPlacingBuilding()) {
const UnitType *unitType = getBuilding();
int factionIndex = world->getThisFactionIndex();
@ -354,6 +362,20 @@ void Gui::hotKey(char key){
}
unitTypeBuildRotation[unitKey] = unitTypeRotation;
//!!!
//if(allowRotateUnits == true && unitRotation > 0) {
if(Socket::enableDebugText) printf("In [%s::%s] before sending nctNetworkCommand RotateUnit unitTypeid = %d, factionIndex = %d, unitTypeRotation = %f\n",__FILE__,__FUNCTION__,unitType->getId(),factionIndex,unitTypeRotation);
//unitRotation = 0;
NetworkCommand networkCommand(nctNetworkCommand, ncstRotateUnit, unitType->getId(), factionIndex, (int)unitTypeRotation);
//CommandResult result= game->getCommander()->pushNetworkCommand(&networkCommand);
GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface();
gameNetworkInterface->requestCommand(&networkCommand);
//if(Socket::enableDebugText) printf("In [%s::%s] after sending nctNetworkCommand RotateUnit [%d] result = %d\n",__FILE__,__FUNCTION__,builtUnit->getId(),result);
if(Socket::enableDebugText) printf("In [%s::%s] after sending nctNetworkCommand RotateUnit unitTypeid = %d, factionIndex = %d, unitTypeRotation = %f\n",__FILE__,__FUNCTION__,unitType->getId(),factionIndex,unitTypeRotation);
//}
if(Socket::enableDebugText) printf("In [%s::%s] unitType->getId() = %d NEW unitTypeRotation = %f\n",__FILE__,__FUNCTION__,unitType->getId(),unitTypeRotation);
}
else {

View File

@ -176,6 +176,7 @@ public:
void onSelectionChanged();
float getUnitTypeBuildRotation(string unitKey) const;
void setUnitTypeBuildRotation(string unitKey, float value);
private:

View File

@ -51,8 +51,9 @@ MenuStateCustomGame::MenuStateCustomGame(Program *program, MainMenu *mainMenu, b
buttonPlayNow.init(525, 180, 125);
//map listBox
findAll("maps/*.gbm", glestMaps, true, true);
findAll("maps/*.mgm", megaMaps, true, false);
Config &config = Config::getInstance();
findAll(config.getPathListForType(ptMaps), "*.gbm", glestMaps, true, false);
findAll(config.getPathListForType(ptMaps), "*.mgm", megaMaps, true, false);
mapFiles.resize(glestMaps.size() + megaMaps.size());
if (!glestMaps.empty()) {
@ -74,8 +75,8 @@ MenuStateCustomGame::MenuStateCustomGame(Program *program, MainMenu *mainMenu, b
labelMapInfo.init(200, 230, 200, 40);
//tileset listBox
findAll("tilesets/*.", results);
if(results.size()==0){
findDirs(config.getPathListForType(ptTilesets), results);
if(results.size() == 0) {
throw runtime_error("There is no tile set");
}
tilesetFiles= results;
@ -87,9 +88,9 @@ MenuStateCustomGame::MenuStateCustomGame(Program *program, MainMenu *mainMenu, b
labelTileset.init(400, 290);
//tech Tree listBox
findAll("techs/*.", results);
if(results.size()==0){
throw runtime_error("There is no tech tree");
findDirs(config.getPathListForType(ptTechs), results);
if(results.size() == 0) {
throw runtime_error("There are no tech trees");
}
techTreeFiles= results;
for(int i= 0; i<results.size(); ++i){
@ -134,10 +135,19 @@ MenuStateCustomGame::MenuStateCustomGame(Program *program, MainMenu *mainMenu, b
reloadFactions();
findAll("techs/"+techTreeFiles[listBoxTechTree.getSelectedItemIndex()]+"/factions/*.", results);
if(results.size()==0){
vector<string> techPaths = config.getPathListForType(ptTechs);
for(int idx = 0; idx < techPaths.size(); idx++) {
string &techPath = techPaths[idx];
findAll(techPath + "/" + techTreeFiles[listBoxTechTree.getSelectedItemIndex()] + "/factions/*.", results, false, false);
if(results.size() > 0) {
break;
}
}
if(results.size() == 0) {
throw runtime_error("There is no factions for this tech tree");
}
}
for(int i=0; i<GameConstants::maxPlayers; ++i){
labelPlayers[i].setText(lang.get("Player")+" "+intToStr(i));
@ -570,18 +580,32 @@ void MenuStateCustomGame::reloadFactions(){
vector<string> results;
findAll("techs/"+techTreeFiles[listBoxTechTree.getSelectedItemIndex()]+"/factions/*.", results);
if(results.size()==0){
throw runtime_error("There is no factions for this tech tree");
}
factionFiles= results;
for(int i= 0; i<results.size(); ++i){
results[i]= formatString(results[i]);
}
for(int i=0; i<GameConstants::maxPlayers; ++i){
listBoxFactions[i].setItems(results);
listBoxFactions[i].setSelectedItemIndex(i % results.size());
Config &config = Config::getInstance();
vector<string> techPaths = config.getPathListForType(ptTechs);
for(int idx = 0; idx < techPaths.size(); idx++) {
string &techPath = techPaths[idx];
findAll(techPath + "/" + techTreeFiles[listBoxTechTree.getSelectedItemIndex()] + "/factions/*.", results, false, false);
if(results.size() > 0) {
break;
}
}
if(results.size() == 0) {
throw runtime_error("There is no factions for this tech tree");
}
factionFiles= results;
for(int i= 0; i<results.size(); ++i){
results[i]= formatString(results[i]);
printf("Tech [%s] has faction [%s]\n",techTreeFiles[listBoxTechTree.getSelectedItemIndex()].c_str(),results[i].c_str());
}
for(int i=0; i<GameConstants::maxPlayers; ++i){
listBoxFactions[i].setItems(results);
listBoxFactions[i].setSelectedItemIndex(i % results.size());
}
}
void MenuStateCustomGame::updateControlers(){

View File

@ -0,0 +1,98 @@
// ==============================================================
// This file is part of Glest (www.glest.org)
//
// Copyright (C) 2001-2005 Martiño Figueroa
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version
// ==============================================================
#include "menu_state_new_game.h"
#include "renderer.h"
#include "sound_renderer.h"
#include "core_data.h"
#include "config.h"
#include "menu_state_custom_game.h"
#include "menu_state_scenario.h"
#include "menu_state_root.h"
#include "metrics.h"
#include "network_manager.h"
#include "network_message.h"
#include "auto_test.h"
#include "socket.h"
#include "leak_dumper.h"
namespace Glest{ namespace Game{
// =====================================================
// class MenuStateNewGame
// =====================================================
MenuStateNewGame::MenuStateNewGame(Program *program, MainMenu *mainMenu):
MenuState(program, mainMenu, "root")
{
Lang &lang= Lang::getInstance();
buttonCustomGame.init(425, 350, 150);
buttonScenario.init(425, 310, 150);
buttonTutorial.init(425, 270, 150);
buttonReturn.init(425, 230, 150);
buttonCustomGame.setText(lang.get("CustomGame"));
buttonScenario.setText(lang.get("Scenario"));
buttonTutorial.setText(lang.get("Tutorial"));
buttonReturn.setText(lang.get("Return"));
NetworkManager::getInstance().end();
}
void MenuStateNewGame::mouseClick(int x, int y, MouseButton mouseButton){
CoreData &coreData= CoreData::getInstance();
SoundRenderer &soundRenderer= SoundRenderer::getInstance();
if(buttonCustomGame.mouseClick(x, y)){
soundRenderer.playFx(coreData.getClickSoundB());
mainMenu->setState(new MenuStateCustomGame(program, mainMenu));
}
else if(buttonScenario.mouseClick(x, y)){
soundRenderer.playFx(coreData.getClickSoundB());
mainMenu->setState(new MenuStateScenario(program, mainMenu, Config::getInstance().getPathListForType(ptScenarios)));
}
else if(buttonTutorial.mouseClick(x, y)){
soundRenderer.playFx(coreData.getClickSoundB());
mainMenu->setState(new MenuStateScenario(program, mainMenu, Config::getInstance().getPathListForType(ptTutorials)));
}
else if(buttonReturn.mouseClick(x, y)){
soundRenderer.playFx(coreData.getClickSoundB());
mainMenu->setState(new MenuStateRoot(program, mainMenu));
}
}
void MenuStateNewGame::mouseMove(int x, int y, const MouseState *ms){
buttonCustomGame.mouseMove(x, y);
buttonScenario.mouseMove(x, y);
buttonTutorial.mouseMove(x, y);
buttonReturn.mouseMove(x, y);
}
void MenuStateNewGame::render(){
Renderer &renderer= Renderer::getInstance();
renderer.renderButton(&buttonCustomGame);
renderer.renderButton(&buttonScenario);
renderer.renderButton(&buttonTutorial);
renderer.renderButton(&buttonReturn);
}
void MenuStateNewGame::update(){
if(Config::getInstance().getBool("AutoTest")){
AutoTest::getInstance().updateNewGame(program, mainMenu);
}
}
}}//end namespace

View File

@ -0,0 +1,257 @@
// ==============================================================
// This file is part of Glest (www.glest.org)
//
// Copyright (C) 2001-2005 Marti<74>o Figueroa
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version
// ==============================================================
#include "menu_state_scenario.h"
#include "renderer.h"
#include "menu_state_new_game.h"
#include "sound_renderer.h"
#include "core_data.h"
#include "menu_state_options.h"
#include "network_manager.h"
#include "config.h"
#include "auto_test.h"
#include "game.h"
#include "leak_dumper.h"
namespace Glest{ namespace Game{
using namespace Shared::Xml;
// =====================================================
// class MenuStateScenario
// =====================================================
MenuStateScenario::MenuStateScenario(Program *program, MainMenu *mainMenu, const vector<string> &dirList):
MenuState(program, mainMenu, "scenario")
{
Lang &lang= Lang::getInstance();
NetworkManager &networkManager= NetworkManager::getInstance();
vector<string> results;
this->dirList = dirList;
labelInfo.init(350, 350);
labelInfo.setFont(CoreData::getInstance().getMenuFontNormal());
buttonReturn.init(350, 200, 125);
buttonPlayNow.init(525, 200, 125);
listBoxScenario.init(350, 400, 190);
labelScenario.init(350, 430);
buttonReturn.setText(lang.get("Return"));
buttonPlayNow.setText(lang.get("PlayNow"));
labelScenario.setText(lang.get("Scenario"));
//scenario listbox
findDirs(dirList, results);
scenarioFiles = results;
if(results.size() == 0) {
throw runtime_error("There are no scenarios");
}
for(int i= 0; i<results.size(); ++i){
results[i]= formatString(results[i]);
}
listBoxScenario.setItems(results);
loadScenarioInfo(Scenario::getScenarioPath(dirList, scenarioFiles[listBoxScenario.getSelectedItemIndex()]), &scenarioInfo );
labelInfo.setText(scenarioInfo.desc);
networkManager.init(nrServer);
}
void MenuStateScenario::mouseClick(int x, int y, MouseButton mouseButton){
CoreData &coreData= CoreData::getInstance();
SoundRenderer &soundRenderer= SoundRenderer::getInstance();
if(buttonReturn.mouseClick(x,y)){
soundRenderer.playFx(coreData.getClickSoundA());
mainMenu->setState(new MenuStateNewGame(program, mainMenu));
}
else if(buttonPlayNow.mouseClick(x,y)){
soundRenderer.playFx(coreData.getClickSoundC());
launchGame();
}
else if(listBoxScenario.mouseClick(x, y)){
loadScenarioInfo(Scenario::getScenarioPath(dirList, scenarioFiles[listBoxScenario.getSelectedItemIndex()]), &scenarioInfo);
labelInfo.setText(scenarioInfo.desc);
}
}
void MenuStateScenario::mouseMove(int x, int y, const MouseState *ms){
listBoxScenario.mouseMove(x, y);
buttonReturn.mouseMove(x, y);
buttonPlayNow.mouseMove(x, y);
}
void MenuStateScenario::render(){
Renderer &renderer= Renderer::getInstance();
renderer.renderLabel(&labelInfo);
renderer.renderLabel(&labelScenario);
renderer.renderListBox(&listBoxScenario);
renderer.renderButton(&buttonReturn);
renderer.renderButton(&buttonPlayNow);
}
void MenuStateScenario::update(){
if(Config::getInstance().getBool("AutoTest")){
AutoTest::getInstance().updateScenario(this);
}
}
void MenuStateScenario::launchGame(){
GameSettings gameSettings;
loadGameSettings(&scenarioInfo, &gameSettings);
program->setState(new Game(program, &gameSettings));
}
void MenuStateScenario::setScenario(int i){
listBoxScenario.setSelectedItemIndex(i);
loadScenarioInfo(Scenario::getScenarioPath(dirList, scenarioFiles[listBoxScenario.getSelectedItemIndex()]), &scenarioInfo);
}
void MenuStateScenario::loadScenarioInfo(string file, ScenarioInfo *scenarioInfo){
Lang &lang= Lang::getInstance();
XmlTree xmlTree;
xmlTree.load(file);
const XmlNode *scenarioNode= xmlTree.getRootNode();
const XmlNode *difficultyNode= scenarioNode->getChild("difficulty");
scenarioInfo->difficulty = difficultyNode->getAttribute("value")->getIntValue();
if( scenarioInfo->difficulty < dVeryEasy || scenarioInfo->difficulty > dInsane )
{
throw std::runtime_error("Invalid difficulty");
}
const XmlNode *playersNode= scenarioNode->getChild("players");
for(int i= 0; i<GameConstants::maxPlayers; ++i){
XmlNode* playerNode;
string factionTypeName;
ControlType factionControl;
if(playersNode->hasChildAtIndex("player",i)){
playerNode = playersNode->getChild("player", i);
factionControl = strToControllerType( playerNode->getAttribute("control")->getValue() );
}
else{
factionControl=ctClosed;
}
scenarioInfo->factionControls[i] = factionControl;
if(factionControl != ctClosed){
int teamIndex = playerNode->getAttribute("team")->getIntValue();
if( teamIndex < 1 || teamIndex > GameConstants::maxPlayers )
{
throw runtime_error("Team out of range: " + intToStr(teamIndex) );
}
scenarioInfo->teams[i]= playerNode->getAttribute("team")->getIntValue();
scenarioInfo->factionTypeNames[i]= playerNode->getAttribute("faction")->getValue();
}
scenarioInfo->mapName = scenarioNode->getChild("map")->getAttribute("value")->getValue();
scenarioInfo->tilesetName = scenarioNode->getChild("tileset")->getAttribute("value")->getValue();
scenarioInfo->techTreeName = scenarioNode->getChild("tech-tree")->getAttribute("value")->getValue();
scenarioInfo->defaultUnits = scenarioNode->getChild("default-units")->getAttribute("value")->getBoolValue();
scenarioInfo->defaultResources = scenarioNode->getChild("default-resources")->getAttribute("value")->getBoolValue();
scenarioInfo->defaultVictoryConditions = scenarioNode->getChild("default-victory-conditions")->getAttribute("value")->getBoolValue();
}
//add player info
scenarioInfo->desc= lang.get("Player") + ": ";
for(int i=0; i<GameConstants::maxPlayers; ++i )
{
if(scenarioInfo->factionControls[i] == ctHuman )
{
scenarioInfo->desc+= formatString(scenarioInfo->factionTypeNames[i]);
break;
}
}
//add misc info
string difficultyString = "Difficulty" + intToStr(scenarioInfo->difficulty);
scenarioInfo->desc+= "\n";
scenarioInfo->desc+= lang.get("Difficulty") + ": " + lang.get(difficultyString) +"\n";
scenarioInfo->desc+= lang.get("Map") + ": " + formatString(scenarioInfo->mapName) + "\n";
scenarioInfo->desc+= lang.get("Tileset") + ": " + formatString(scenarioInfo->tilesetName) + "\n";
scenarioInfo->desc+= lang.get("TechTree") + ": " + formatString(scenarioInfo->techTreeName) + "\n";
}
void MenuStateScenario::loadGameSettings(const ScenarioInfo *scenarioInfo, GameSettings *gameSettings){
int factionCount= 0;
gameSettings->setDescription(formatString(scenarioFiles[listBoxScenario.getSelectedItemIndex()]));
gameSettings->setMap(scenarioInfo->mapName);
gameSettings->setTileset(scenarioInfo->tilesetName);
gameSettings->setTech(scenarioInfo->techTreeName);
gameSettings->setScenario(scenarioFiles[listBoxScenario.getSelectedItemIndex()]);
gameSettings->setScenarioDir(Scenario::getScenarioPath(dirList, scenarioFiles[listBoxScenario.getSelectedItemIndex()]));
gameSettings->setDefaultUnits(scenarioInfo->defaultUnits);
gameSettings->setDefaultResources(scenarioInfo->defaultResources);
gameSettings->setDefaultVictoryConditions(scenarioInfo->defaultVictoryConditions);
for(int i=0; i<GameConstants::maxPlayers; ++i){
ControlType ct= static_cast<ControlType>(scenarioInfo->factionControls[i]);
if(ct!=ctClosed){
if(ct==ctHuman){
gameSettings->setThisFactionIndex(factionCount);
}
gameSettings->setFactionControl(factionCount, ct);
gameSettings->setTeam(factionCount, scenarioInfo->teams[i]-1);
gameSettings->setStartLocationIndex(factionCount, i);
gameSettings->setFactionTypeName(factionCount, scenarioInfo->factionTypeNames[i]);
factionCount++;
}
}
gameSettings->setFactionCount(factionCount);
}
ControlType MenuStateScenario::strToControllerType(const string &str){
if(str=="closed"){
return ctClosed;
}
else if(str=="cpu-easy"){
return ctCpuEasy;
}
else if(str=="cpu"){
return ctCpu;
}
else if(str=="cpu-ultra"){
return ctCpuUltra;
}
else if(str=="cpu-mega"){
return ctCpuMega;
}
else if(str=="human"){
return ctHuman;
}
throw std::runtime_error("Unknown controller type: " + str);
}
}}//end namespace

View File

@ -0,0 +1,69 @@
// ==============================================================
// This file is part of Glest (www.glest.org)
//
// Copyright (C) 2001-2005 Martiño Figueroa
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version
// ==============================================================
#ifndef _GLEST_GAME_MENUSTATESCENARIO_H_
#define _GLEST_GAME_MENUSTATESCENARIO_H_
#include "main_menu.h"
namespace Glest{ namespace Game{
// ===============================
// class MenuStateScenario
// ===============================
class MenuStateScenario: public MenuState{
private:
enum Difficulty{
dVeryEasy,
dEasy,
dMedium,
dHard,
dVeryHard,
dInsane
};
GraphicButton buttonReturn;
GraphicButton buttonPlayNow;
GraphicLabel labelInfo;
GraphicLabel labelScenario;
GraphicListBox listBoxScenario;
vector<string> scenarioFiles;
ScenarioInfo scenarioInfo;
vector<string> dirList;
public:
MenuStateScenario(Program *program, MainMenu *mainMenu, const vector<string> &dirList);
void mouseClick(int x, int y, MouseButton mouseButton);
void mouseMove(int x, int y, const MouseState *mouseState);
void render();
void update();
void launchGame();
void setScenario(int i);
int getScenarioCount() const { return listBoxScenario.getItemCount(); }
private:
void loadScenarioInfo(string file, ScenarioInfo *scenarioInfo);
void loadGameSettings(const ScenarioInfo *scenarioInfo, GameSettings *gameSettings);
Difficulty computeDifficulty(const ScenarioInfo *scenarioInfo);
ControlType strToControllerType(const string &str);
};
}}//end namespace
#endif

View File

@ -116,6 +116,15 @@ GameNetworkInterface::GameNetworkInterface(){
quit= false;
}
void GameNetworkInterface::requestCommand(const NetworkCommand *networkCommand, bool insertAtStart) {
if(insertAtStart == false) {
requestedCommands.push_back(*networkCommand);
}
else {
requestedCommands.insert(requestedCommands.begin(),*networkCommand);
}
}
// =====================================================
// class FileTransferSocketThread
// =====================================================

View File

@ -135,7 +135,7 @@ public:
virtual string getNetworkStatus() const= 0;
//access functions
void requestCommand(const NetworkCommand *networkCommand) {requestedCommands.push_back(*networkCommand);}
void requestCommand(const NetworkCommand *networkCommand, bool insertAtStart=false);
int getPendingCommandCount() const {return pendingCommands.size();}
const NetworkCommand* getPendingCommand(int i) const {return &pendingCommands[i];}
void clearPendingCommands() {pendingCommands.clear();}

View File

@ -0,0 +1,42 @@
// ==============================================================
// This file is part of Glest (www.glest.org)
//
// Copyright (C) 2001-2008 Martiño Figueroa
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version
// ==============================================================
#include "network_types.h"
#include "leak_dumper.h"
namespace Glest{ namespace Game{
// =====================================================
// class NetworkCommand
// =====================================================
NetworkCommand::NetworkCommand(int networkCommandType, int unitId, int commandTypeId, const Vec2i &pos, int unitTypeId, int targetId){
this->networkCommandType= networkCommandType;
this->unitId= unitId;
this->commandTypeId= commandTypeId;
this->positionX= pos.x;
this->positionY= pos.y;
this->unitTypeId= unitTypeId;
this->targetId= targetId;
}
NetworkCommand::NetworkCommand(int networkCommandType, NetworkCommandSubType ncstType, int unitId, int value1, int value2) {
this->networkCommandType= networkCommandType;
this->unitId= unitId;
this->commandTypeId= ncstType;
this->positionX= -1;
this->positionY= -1;
this->unitTypeId= value1;
this->targetId= value2;
}
}}//end namespace

View File

@ -0,0 +1,85 @@
// ==============================================================
// This file is part of Glest (www.glest.org)
//
// Copyright (C) 2001-2008 Martiño Figueroa
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version
// ==============================================================
#ifndef _GLEST_GAME_NETWORKTYPES_H_
#define _GLEST_GAME_NETWORKTYPES_H_
#include <string>
#include "types.h"
#include "vec.h"
using std::string;
using Shared::Platform::int8;
using Shared::Platform::int16;
using Shared::Platform::int32;
using Shared::Graphics::Vec2i;
namespace Glest{ namespace Game{
// =====================================================
// class NetworkString
// =====================================================
template<int S>
class NetworkString{
private:
char buffer[S];
public:
NetworkString() {memset(buffer, 0, S);}
void operator=(const string& str) {strncpy(buffer, str.c_str(), S-1);}
string getString() const {return buffer;}
};
// =====================================================
// class NetworkCommand
// =====================================================
enum NetworkCommandType {
nctGiveCommand,
nctCancelCommand,
nctSetMeetingPoint,
nctNetworkCommand
};
enum NetworkCommandSubType {
ncstRotateUnit
};
#pragma pack(push, 2)
class NetworkCommand{
private:
int16 networkCommandType;
int16 unitId;
int16 commandTypeId;
int16 positionX;
int16 positionY;
int16 unitTypeId;
int16 targetId;
public:
NetworkCommand(){};
NetworkCommand(int networkCommandType, int unitId, int commandTypeId= -1, const Vec2i &pos= Vec2i(0), int unitTypeId= -1, int targetId= -1);
NetworkCommand(int networkCommandType, NetworkCommandSubType ncstType, int unitId, int value1, int value2=-1);
NetworkCommandType getNetworkCommandType() const {return static_cast<NetworkCommandType>(networkCommandType);}
int getUnitId() const {return unitId;}
int getCommandTypeId() const {return commandTypeId;}
Vec2i getPosition() const {return Vec2i(positionX, positionY);}
int getUnitTypeId() const {return unitTypeId;}
int getTargetId() const {return targetId;}
};
#pragma pack(pop)
}}//end namespace
#endif

View File

@ -24,7 +24,7 @@
#include "core_data.h"
#include "renderer.h"
#include "leak_dumper.h"
//#include "socket.h"
#include "socket.h"
using namespace Shared::Graphics;
using namespace Shared::Util;
@ -106,8 +106,9 @@ const int Unit::invalidId= -1;
Unit::Unit(int id, const Vec2i &pos, const UnitType *type, Faction *faction, Map *map, float unitPlacementRotation) {
//if(Socket::enableDebugText) printf("In [%s::%s] START\n",__FILE__,__FUNCTION__);
if(Socket::enableDebugText) printf("In [%s::%s] START\n",__FILE__,__FUNCTION__);
allowRotateUnits = Config::getInstance().getBool("AllowRotateUnits","0");
rotateAmount= -1;
Random random;
@ -177,7 +178,7 @@ Unit::~Unit(){
}
stopDamageParticles();
delete [] cellMap;
if(cellMap == NULL) delete [] cellMap;
cellMap = NULL;
}
@ -454,16 +455,20 @@ unsigned int Unit::getCommandSize() const{
//give one command (clear, and push back)
CommandResult Unit::giveCommand(Command *command){
//if(Socket::enableDebugText) printf("In [%s::%s] START\n",__FILE__,__FUNCTION__);
if(Socket::enableDebugText) printf("In [%s::%s] START\n",__FILE__,__FUNCTION__);
if(command->getCommandType()->isQueuable()){
//cancel current command if it is not queuable
if(Socket::enableDebugText) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
if(!commands.empty() && !commands.front()->getCommandType()->isQueuable()){
if(Socket::enableDebugText) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
cancelCommand();
}
}
else{
//empty command queue
if(Socket::enableDebugText) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
clearCommands();
unitPath.clear();
}
@ -471,8 +476,10 @@ CommandResult Unit::giveCommand(Command *command){
//if(Socket::enableDebugText) printf("In [%s::%s] A\n",__FILE__,__FUNCTION__);
//check command
if(Socket::enableDebugText) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
CommandResult result= checkCommand(command);
if(result==crSuccess){
if(Socket::enableDebugText) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
applyCommand(command);
}
@ -480,13 +487,15 @@ CommandResult Unit::giveCommand(Command *command){
//push back command
if(result== crSuccess){
if(Socket::enableDebugText) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
commands.push_back(command);
}
else{
if(Socket::enableDebugText) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
delete command;
}
//if(Socket::enableDebugText) printf("In [%s::%s] END\n",__FILE__,__FUNCTION__);
if(Socket::enableDebugText) printf("In [%s::%s] END\n",__FILE__,__FUNCTION__);
return result;
}
@ -693,24 +702,25 @@ bool Unit::update(){
animProgress= currSkill->getClass()==scDie? 1.f: 0.f;
}
bool return_value = false;
//checks
if(progress>=1.f){
lastRotation= targetRotation;
if(currSkill->getClass()!=scDie){
progress= 0.f;
return true;
return_value = true;
}
else{
progress= 1.f;
deadCount++;
if(deadCount>=maxDeadCount){
toBeUndertaken= true;
return false;
return_value = false;
}
}
}
return false;
return return_value;
}
void Unit::tick(){
@ -1124,7 +1134,8 @@ bool Unit::getCellMapCell(int x, int y) const {
void Unit::setRotateAmount(float value) {
if(allowRotateUnits == true) {
rotateAmount = value;
//if(Socket::enableDebugText) printf("In [%s::%s] unit id = %d [%s] rotate amount = %f\n",__FILE__,__FUNCTION__,getId(), getFullName().c_str(),rotateAmount);
//if(Socket::enableDebugText && rotateAmount > 0) printf("In [%s::%s Line: %d] unit id = %d [%s] rotate amount = %f\n",__FILE__,__FUNCTION__,__LINE__, getId(), getFullName().c_str(),rotateAmount);
if(Socket::enableDebugText ) printf("In [%s::%s Line: %d] unit id = %d rotate amount = %f cellMap = %s\n",__FILE__,__FUNCTION__,__LINE__, getId(), rotateAmount,(cellMap == NULL ? "NULL" : "Valid"));
const UnitType *ut= getType();
if(ut != NULL && ut->hasCellMap() == true) {
@ -1132,7 +1143,7 @@ void Unit::setRotateAmount(float value) {
if(rotateAmount > 0) {
delete [] cellMap;
if(cellMap == NULL) delete [] cellMap;
cellMap = new bool[matrixSize * matrixSize];
for(int iRow = 0; iRow < matrixSize; ++iRow) {
@ -1180,6 +1191,9 @@ void Unit::setRotateAmount(float value) {
}
*/
}
//if(Socket::enableDebugText && rotateAmount > 0) printf("In [%s::%s Line: %d] unit id = %d [%s] rotate amount = %f\n",__FILE__,__FUNCTION__,__LINE__, getId(), getFullName().c_str(),rotateAmount);
if(Socket::enableDebugText ) printf("In [%s::%s Line: %d] unit id = %d rotate amount = %f\n",__FILE__,__FUNCTION__,__LINE__, getId(),rotateAmount);
}
}

View File

@ -0,0 +1,745 @@
// ==============================================================
// This file is part of Glest (www.glest.org)
//
// Copyright (C) 2001-2008 Martiño Figueroa
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version
// ==============================================================
#include "command_type.h"
#include <algorithm>
#include <cassert>
#include "upgrade_type.h"
#include "unit_type.h"
#include "sound.h"
#include "util.h"
#include "leak_dumper.h"
#include "graphics_interface.h"
#include "tech_tree.h"
#include "faction_type.h"
#include "unit_updater.h"
#include "renderer.h"
#include "leak_dumper.h"
#include "socket.h"
using namespace Shared::Util;
namespace Glest{ namespace Game{
// =====================================================
// class CommandType
// =====================================================
//get
CommandClass CommandType::getClass() const{
assert(this!=NULL);
return commandTypeClass;
}
void CommandType::load(int id, const XmlNode *n, const string &dir, const TechTree *tt, const FactionType *ft, const UnitType &ut){
this->id= id;
name= n->getChild("name")->getAttribute("value")->getRestrictedValue();
//image
const XmlNode *imageNode= n->getChild("image");
image= Renderer::getInstance().newTexture2D(rsGame);
image->load(dir+"/"+imageNode->getAttribute("path")->getRestrictedValue());
//unit requirements
const XmlNode *unitRequirementsNode= n->getChild("unit-requirements");
for(int i=0; i<unitRequirementsNode->getChildCount(); ++i){
const XmlNode *unitNode= unitRequirementsNode->getChild("unit", i);
string name= unitNode->getAttribute("name")->getRestrictedValue();
unitReqs.push_back(ft->getUnitType(name));
}
//upgrade requirements
const XmlNode *upgradeRequirementsNode= n->getChild("upgrade-requirements");
for(int i=0; i<upgradeRequirementsNode->getChildCount(); ++i){
const XmlNode *upgradeReqNode= upgradeRequirementsNode->getChild("upgrade", i);
string name= upgradeReqNode->getAttribute("name")->getRestrictedValue();
upgradeReqs.push_back(ft->getUpgradeType(name));
}
}
// =====================================================
// class StopCommandType
// =====================================================
//varios
StopCommandType::StopCommandType(){
commandTypeClass= ccStop;
clicks= cOne;
}
void StopCommandType::update(UnitUpdater *unitUpdater, Unit *unit) const{
unitUpdater->updateStop(unit);
}
string StopCommandType::getDesc(const TotalUpgrade *totalUpgrade) const{
string str;
Lang &lang= Lang::getInstance();
str= name+"\n";
str+= lang.get("ReactionSpeed")+": "+ intToStr(stopSkillType->getSpeed())+"\n";
if(stopSkillType->getEpCost()!=0)
str+= lang.get("EpCost")+": "+intToStr(stopSkillType->getEpCost())+"\n";
return str;
}
string StopCommandType::toString() const{
Lang &lang= Lang::getInstance();
return lang.get("Stop");
}
void StopCommandType::load(int id, const XmlNode *n, const string &dir, const TechTree *tt, const FactionType *ft, const UnitType &ut){
CommandType::load(id, n, dir, tt, ft, ut);
//stop
string skillName= n->getChild("stop-skill")->getAttribute("value")->getRestrictedValue();
stopSkillType= static_cast<const StopSkillType*>(ut.getSkillType(skillName, scStop));
}
// =====================================================
// class MoveCommandType
// =====================================================
//varios
MoveCommandType::MoveCommandType(){
commandTypeClass= ccMove;
clicks= cTwo;
}
void MoveCommandType::update(UnitUpdater *unitUpdater, Unit *unit) const{
unitUpdater->updateMove(unit);
}
void MoveCommandType::load(int id, const XmlNode *n, const string &dir, const TechTree *tt, const FactionType *ft, const UnitType &ut){
CommandType::load(id, n, dir, tt, ft, ut);
//move
string skillName= n->getChild("move-skill")->getAttribute("value")->getRestrictedValue();
moveSkillType= static_cast<const MoveSkillType*>(ut.getSkillType(skillName, scMove));
}
string MoveCommandType::getDesc(const TotalUpgrade *totalUpgrade) const{
string str;
Lang &lang= Lang::getInstance();
str= name+"\n";
str+= lang.get("WalkSpeed")+": "+ intToStr(moveSkillType->getSpeed());
if(totalUpgrade->getMoveSpeed()!=0){
str+= "+" + intToStr(totalUpgrade->getMoveSpeed());
}
str+="\n";
if(moveSkillType->getEpCost()!=0){
str+= lang.get("EpCost")+": "+intToStr(moveSkillType->getEpCost())+"\n";
}
return str;
}
string MoveCommandType::toString() const{
Lang &lang= Lang::getInstance();
return lang.get("Move");
}
// =====================================================
// class AttackCommandType
// =====================================================
//varios
AttackCommandType::AttackCommandType(){
commandTypeClass= ccAttack;
clicks= cTwo;
}
void AttackCommandType::update(UnitUpdater *unitUpdater, Unit *unit) const{
unitUpdater->updateAttack(unit);
}
void AttackCommandType::load(int id, const XmlNode *n, const string &dir, const TechTree *tt, const FactionType *ft, const UnitType &ut){
CommandType::load(id, n, dir, tt, ft, ut);
//move
string skillName= n->getChild("move-skill")->getAttribute("value")->getRestrictedValue();
moveSkillType= static_cast<const MoveSkillType*>(ut.getSkillType(skillName, scMove));
//attack
skillName= n->getChild("attack-skill")->getAttribute("value")->getRestrictedValue();
attackSkillType= static_cast<const AttackSkillType*>(ut.getSkillType(skillName, scAttack));
}
string AttackCommandType::getDesc(const TotalUpgrade *totalUpgrade) const{
string str;
Lang &lang= Lang::getInstance();
str= name+"\n";
if(attackSkillType->getEpCost()!=0){
str+= lang.get("EpCost") + ": " + intToStr(attackSkillType->getEpCost()) + "\n";
}
//attack strength
str+= lang.get("AttackStrenght")+": ";
str+= intToStr(attackSkillType->getAttackStrength()-attackSkillType->getAttackVar());
str+= "...";
str+= intToStr(attackSkillType->getAttackStrength()+attackSkillType->getAttackVar());
if(totalUpgrade->getAttackStrength()!=0){
str+= "+"+intToStr(totalUpgrade->getAttackStrength());
}
str+= " ("+ attackSkillType->getAttackType()->getName() +")";
str+= "\n";
//splash radius
if(attackSkillType->getSplashRadius()!=0){
str+= lang.get("SplashRadius")+": "+intToStr(attackSkillType->getSplashRadius())+"\n";
}
//attack distance
str+= lang.get("AttackDistance")+": "+intToStr(attackSkillType->getAttackRange());
if(totalUpgrade->getAttackRange()!=0){
str+= "+"+intToStr(totalUpgrade->getAttackRange()!=0);
}
str+="\n";
//attack fields
str+= lang.get("Fields") + ": ";
for(int i= 0; i < fieldCount; i++){
Field field = static_cast<Field>(i);
if( attackSkillType->getAttackField(field) )
{
str+= SkillType::fieldToStr(field) + " ";
}
}
str+="\n";
//movement speed
str+= lang.get("WalkSpeed")+": "+ intToStr(moveSkillType->getSpeed()) ;
if(totalUpgrade->getMoveSpeed()!=0){
str+= "+"+intToStr(totalUpgrade->getMoveSpeed());
}
str+="\n";
str+= lang.get("AttackSpeed")+": "+ intToStr(attackSkillType->getSpeed()) +"\n";
return str;
}
string AttackCommandType::toString() const{
Lang &lang= Lang::getInstance();
return lang.get("Attack");
}
// =====================================================
// class AttackStoppedCommandType
// =====================================================
//varios
AttackStoppedCommandType::AttackStoppedCommandType(){
commandTypeClass= ccAttackStopped;
clicks= cOne;
}
void AttackStoppedCommandType::update(UnitUpdater *unitUpdater, Unit *unit) const{
unitUpdater->updateAttackStopped(unit);
}
void AttackStoppedCommandType::load(int id, const XmlNode *n, const string &dir, const TechTree *tt, const FactionType *ft, const UnitType &ut){
CommandType::load(id, n, dir, tt, ft, ut);
//stop
string skillName= n->getChild("stop-skill")->getAttribute("value")->getRestrictedValue();
stopSkillType= static_cast<const StopSkillType*>(ut.getSkillType(skillName, scStop));
//attack
skillName= n->getChild("attack-skill")->getAttribute("value")->getRestrictedValue();
attackSkillType= static_cast<const AttackSkillType*>(ut.getSkillType(skillName, scAttack));
}
string AttackStoppedCommandType::getDesc(const TotalUpgrade *totalUpgrade) const{
Lang &lang= Lang::getInstance();
string str;
str= name+"\n";
if(attackSkillType->getEpCost()!=0){
str+= lang.get("EpCost")+": "+intToStr(attackSkillType->getEpCost())+"\n";
}
//attack strength
str+= lang.get("AttackStrenght")+": ";
str+= intToStr(attackSkillType->getAttackStrength()-attackSkillType->getAttackVar());
str+="...";
str+= intToStr(attackSkillType->getAttackStrength()+attackSkillType->getAttackVar());
if(totalUpgrade->getAttackStrength()!=0)
str+= "+"+intToStr(totalUpgrade->getAttackStrength());
str+= " ("+ attackSkillType->getAttackType()->getName() +")";
str+="\n";
//splash radius
if(attackSkillType->getSplashRadius()!=0){
str+= lang.get("SplashRadius")+": "+intToStr(attackSkillType->getSplashRadius())+"\n";
}
//attack distance
str+= lang.get("AttackDistance")+": "+floatToStr(attackSkillType->getAttackRange());
if(totalUpgrade->getAttackRange()!=0){
str+= "+"+intToStr(totalUpgrade->getAttackRange()!=0);
}
str+="\n";
//attack fields
str+= lang.get("Fields") + ": ";
for(int i= 0; i < fieldCount; i++){
Field field = static_cast<Field>(i);
if( attackSkillType->getAttackField(field) )
{
str+= SkillType::fieldToStr(field) + " ";
}
}
str+="\n";
return str;
}
string AttackStoppedCommandType::toString() const{
Lang &lang= Lang::getInstance();
return lang.get("AttackStopped");
}
// =====================================================
// class BuildCommandType
// =====================================================
//varios
BuildCommandType::BuildCommandType(){
commandTypeClass= ccBuild;
clicks= cTwo;
}
BuildCommandType::~BuildCommandType(){
deleteValues(builtSounds.getSounds().begin(), builtSounds.getSounds().end());
deleteValues(startSounds.getSounds().begin(), startSounds.getSounds().end());
}
void BuildCommandType::update(UnitUpdater *unitUpdater, Unit *unit) const{
unitUpdater->updateBuild(unit);
}
void BuildCommandType::load(int id, const XmlNode *n, const string &dir, const TechTree *tt, const FactionType *ft, const UnitType &ut){
CommandType::load(id, n, dir, tt, ft, ut);
//move
string skillName= n->getChild("move-skill")->getAttribute("value")->getRestrictedValue();
moveSkillType= static_cast<const MoveSkillType*>(ut.getSkillType(skillName, scMove));
//build
skillName= n->getChild("build-skill")->getAttribute("value")->getRestrictedValue();
buildSkillType= static_cast<const BuildSkillType*>(ut.getSkillType(skillName, scBuild));
//buildings built
const XmlNode *buildingsNode= n->getChild("buildings");
for(int i=0; i<buildingsNode->getChildCount(); ++i){
const XmlNode *buildingNode= buildingsNode->getChild("building", i);
string name= buildingNode->getAttribute("name")->getRestrictedValue();
buildings.push_back(ft->getUnitType(name));
}
//start sound
const XmlNode *startSoundNode= n->getChild("start-sound");
if(startSoundNode->getAttribute("enabled")->getBoolValue()){
startSounds.resize(startSoundNode->getChildCount());
for(int i=0; i<startSoundNode->getChildCount(); ++i){
const XmlNode *soundFileNode= startSoundNode->getChild("sound-file", i);
string path= soundFileNode->getAttribute("path")->getRestrictedValue();
StaticSound *sound= new StaticSound();
sound->load(dir + "/" + path);
startSounds[i]= sound;
}
}
//built sound
const XmlNode *builtSoundNode= n->getChild("built-sound");
if(builtSoundNode->getAttribute("enabled")->getBoolValue()){
builtSounds.resize(builtSoundNode->getChildCount());
for(int i=0; i<builtSoundNode->getChildCount(); ++i){
const XmlNode *soundFileNode= builtSoundNode->getChild("sound-file", i);
string path= soundFileNode->getAttribute("path")->getRestrictedValue();
StaticSound *sound= new StaticSound();
sound->load(dir + "/" + path);
builtSounds[i]= sound;
}
}
}
string BuildCommandType::getDesc(const TotalUpgrade *totalUpgrade) const{
string str;
Lang &lang= Lang::getInstance();
str= name+"\n";
str+= lang.get("BuildSpeed")+": "+ intToStr(buildSkillType->getSpeed())+"\n";
if(buildSkillType->getEpCost()!=0){
str+= lang.get("EpCost")+": "+intToStr(buildSkillType->getEpCost())+"\n";
}
return str;
}
string BuildCommandType::toString() const{
Lang &lang= Lang::getInstance();
return lang.get("Build");
}
// =====================================================
// class HarvestCommandType
// =====================================================
//varios
HarvestCommandType::HarvestCommandType(){
commandTypeClass= ccHarvest;
clicks= cTwo;
}
void HarvestCommandType::update(UnitUpdater *unitUpdater, Unit *unit) const{
unitUpdater->updateHarvest(unit);
}
void HarvestCommandType::load(int id, const XmlNode *n, const string &dir, const TechTree *tt, const FactionType *ft, const UnitType &ut){
CommandType::load(id, n, dir, tt, ft, ut);
//move
string skillName= n->getChild("move-skill")->getAttribute("value")->getRestrictedValue();
moveSkillType= static_cast<const MoveSkillType*>(ut.getSkillType(skillName, scMove));
//harvest
skillName= n->getChild("harvest-skill")->getAttribute("value")->getRestrictedValue();
harvestSkillType= static_cast<const HarvestSkillType*>(ut.getSkillType(skillName, scHarvest));
//stop loaded
skillName= n->getChild("stop-loaded-skill")->getAttribute("value")->getRestrictedValue();
stopLoadedSkillType= static_cast<const StopSkillType*>(ut.getSkillType(skillName, scStop));
//move loaded
skillName= n->getChild("move-loaded-skill")->getAttribute("value")->getRestrictedValue();
moveLoadedSkillType= static_cast<const MoveSkillType*>(ut.getSkillType(skillName, scMove));
//resources can harvest
const XmlNode *resourcesNode= n->getChild("harvested-resources");
for(int i=0; i<resourcesNode->getChildCount(); ++i){
const XmlNode *resourceNode= resourcesNode->getChild("resource", i);
harvestedResources.push_back(tt->getResourceType(resourceNode->getAttribute("name")->getRestrictedValue()));
}
maxLoad= n->getChild("max-load")->getAttribute("value")->getIntValue();
hitsPerUnit= n->getChild("hits-per-unit")->getAttribute("value")->getIntValue();
}
string HarvestCommandType::getDesc(const TotalUpgrade *totalUpgrade) const{
Lang &lang= Lang::getInstance();
string str;
str= name+"\n";
str+= lang.get("HarvestSpeed")+": "+ intToStr(harvestSkillType->getSpeed()/hitsPerUnit)+"\n";
str+= lang.get("MaxLoad")+": "+ intToStr(maxLoad)+"\n";
str+= lang.get("LoadedSpeed")+": "+ intToStr(moveLoadedSkillType->getSpeed())+"\n";
if(harvestSkillType->getEpCost()!=0){
str+= lang.get("EpCost")+": "+intToStr(harvestSkillType->getEpCost())+"\n";
}
str+=lang.get("Resources")+":\n";
for(int i=0; i<getHarvestedResourceCount(); ++i){
str+= getHarvestedResource(i)->getName()+"\n";
}
return str;
}
string HarvestCommandType::toString() const{
Lang &lang= Lang::getInstance();
return lang.get("Harvest");
}
bool HarvestCommandType::canHarvest(const ResourceType *resourceType) const{
return find(harvestedResources.begin(), harvestedResources.end(), resourceType) != harvestedResources.end();
}
// =====================================================
// class RepairCommandType
// =====================================================
//varios
RepairCommandType::RepairCommandType(){
commandTypeClass= ccRepair;
clicks= cTwo;
}
RepairCommandType::~RepairCommandType(){
}
void RepairCommandType::update(UnitUpdater *unitUpdater, Unit *unit) const{
unitUpdater->updateRepair(unit);
}
void RepairCommandType::load(int id, const XmlNode *n, const string &dir, const TechTree *tt, const FactionType *ft, const UnitType &ut){
CommandType::load(id, n, dir, tt, ft, ut);
//move
string skillName= n->getChild("move-skill")->getAttribute("value")->getRestrictedValue();
moveSkillType= static_cast<const MoveSkillType*>(ut.getSkillType(skillName, scMove));
//repair
skillName= n->getChild("repair-skill")->getAttribute("value")->getRestrictedValue();
repairSkillType= static_cast<const RepairSkillType*>(ut.getSkillType(skillName, scRepair));
//repaired units
const XmlNode *unitsNode= n->getChild("repaired-units");
for(int i=0; i<unitsNode->getChildCount(); ++i){
const XmlNode *unitNode= unitsNode->getChild("unit", i);
repairableUnits.push_back(ft->getUnitType(unitNode->getAttribute("name")->getRestrictedValue()));
}
}
string RepairCommandType::getDesc(const TotalUpgrade *totalUpgrade) const{
Lang &lang= Lang::getInstance();
string str;
str= name+"\n";
str+= lang.get("RepairSpeed")+": "+ intToStr(repairSkillType->getSpeed())+"\n";
if(repairSkillType->getEpCost()!=0){
str+= lang.get("EpCost")+": "+intToStr(repairSkillType->getEpCost())+"\n";
}
str+="\n"+lang.get("CanRepair")+":\n";
for(int i=0; i<repairableUnits.size(); ++i){
str+= (static_cast<const UnitType*>(repairableUnits[i]))->getName()+"\n";
}
return str;
}
string RepairCommandType::toString() const{
Lang &lang= Lang::getInstance();
return lang.get("Repair");
}
//get
bool RepairCommandType::isRepairableUnitType(const UnitType *unitType) const{
for(int i=0; i<repairableUnits.size(); ++i){
if(static_cast<const UnitType*>(repairableUnits[i])==unitType){
return true;
}
}
return false;
}
// =====================================================
// class ProduceCommandType
// =====================================================
//varios
ProduceCommandType::ProduceCommandType(){
commandTypeClass= ccProduce;
clicks= cOne;
}
void ProduceCommandType::update(UnitUpdater *unitUpdater, Unit *unit) const{
unitUpdater->updateProduce(unit);
}
void ProduceCommandType::load(int id, const XmlNode *n, const string &dir, const TechTree *tt, const FactionType *ft, const UnitType &ut){
CommandType::load(id, n, dir, tt, ft, ut);
//produce
string skillName= n->getChild("produce-skill")->getAttribute("value")->getRestrictedValue();
produceSkillType= static_cast<const ProduceSkillType*>(ut.getSkillType(skillName, scProduce));
string producedUnitName= n->getChild("produced-unit")->getAttribute("name")->getRestrictedValue();
producedUnit= ft->getUnitType(producedUnitName);
}
string ProduceCommandType::getDesc(const TotalUpgrade *totalUpgrade) const{
string str= name+"\n";
Lang &lang= Lang::getInstance();
//prod speed
str+= lang.get("ProductionSpeed")+": "+ intToStr(produceSkillType->getSpeed());
if(totalUpgrade->getProdSpeed()!=0){
str+="+" + intToStr(totalUpgrade->getProdSpeed());
}
str+="\n";
//mpcost
if(produceSkillType->getEpCost()!=0){
str+= lang.get("EpCost")+": "+intToStr(produceSkillType->getEpCost())+"\n";
}
str+= "\n" + getProducedUnit()->getReqDesc();
return str;
}
string ProduceCommandType::toString() const{
Lang &lang= Lang::getInstance();
return lang.get("Produce");
}
string ProduceCommandType::getReqDesc() const{
return RequirableType::getReqDesc()+"\n"+getProducedUnit()->getReqDesc();
}
const ProducibleType *ProduceCommandType::getProduced() const{
return producedUnit;
}
// =====================================================
// class UpgradeCommandType
// =====================================================
//varios
UpgradeCommandType::UpgradeCommandType(){
commandTypeClass= ccUpgrade;
clicks= cOne;
}
void UpgradeCommandType::update(UnitUpdater *unitUpdater, Unit *unit) const{
unitUpdater->updateUpgrade(unit);
}
void UpgradeCommandType::load(int id, const XmlNode *n, const string &dir, const TechTree *tt, const FactionType *ft, const UnitType &ut){
CommandType::load(id, n, dir, tt, ft, ut);
//upgrade
string skillName= n->getChild("upgrade-skill")->getAttribute("value")->getRestrictedValue();
upgradeSkillType= static_cast<const UpgradeSkillType*>(ut.getSkillType(skillName, scUpgrade));
string producedUpgradeName= n->getChild("produced-upgrade")->getAttribute("name")->getRestrictedValue();
producedUpgrade= ft->getUpgradeType(producedUpgradeName);
}
string UpgradeCommandType::getDesc(const TotalUpgrade *totalUpgrade) const{
string str;
Lang &lang= Lang::getInstance();
str= name+"\n";
str+= lang.get("UpgradeSpeed")+": "+ intToStr(upgradeSkillType->getSpeed())+"\n";
if(upgradeSkillType->getEpCost()!=0)
str+= lang.get("EpCost")+": "+intToStr(upgradeSkillType->getEpCost())+"\n";
str+= "\n"+getProducedUpgrade()->getReqDesc();
return str;
}
string UpgradeCommandType::toString() const{
Lang &lang= Lang::getInstance();
return lang.get("Upgrade");
}
string UpgradeCommandType::getReqDesc() const{
return RequirableType::getReqDesc()+"\n"+getProducedUpgrade()->getReqDesc();
}
const ProducibleType *UpgradeCommandType::getProduced() const{
return producedUpgrade;
}
// =====================================================
// class MorphCommandType
// =====================================================
//varios
MorphCommandType::MorphCommandType(){
commandTypeClass= ccMorph;
clicks= cOne;
}
void MorphCommandType::update(UnitUpdater *unitUpdater, Unit *unit) const{
unitUpdater->updateMorph(unit);
}
void MorphCommandType::load(int id, const XmlNode *n, const string &dir, const TechTree *tt, const FactionType *ft, const UnitType &ut){
CommandType::load(id, n, dir, tt, ft, ut);
//morph skill
string skillName= n->getChild("morph-skill")->getAttribute("value")->getRestrictedValue();
morphSkillType= static_cast<const MorphSkillType*>(ut.getSkillType(skillName, scMorph));
//morph unit
string morphUnitName= n->getChild("morph-unit")->getAttribute("name")->getRestrictedValue();
morphUnit= ft->getUnitType(morphUnitName);
//discount
discount= n->getChild("discount")->getAttribute("value")->getIntValue();
}
string MorphCommandType::getDesc(const TotalUpgrade *totalUpgrade) const{
string str= name+"\n";
Lang &lang= Lang::getInstance();
//prod speed
str+= lang.get("MorphSpeed")+": "+ intToStr(morphSkillType->getSpeed())+"\n";
//mpcost
if(morphSkillType->getEpCost()!=0){
str+= lang.get("EpCost")+": "+intToStr(morphSkillType->getEpCost())+"\n";
}
//discount
if(discount!=0){
str+= lang.get("Discount")+": "+intToStr(discount)+"%\n";
}
str+= "\n"+getProduced()->getReqDesc();
return str;
}
string MorphCommandType::toString() const{
Lang &lang= Lang::getInstance();
return lang.get("Morph");
}
string MorphCommandType::getReqDesc() const{
return RequirableType::getReqDesc() + "\n" + getProduced()->getReqDesc();
}
const ProducibleType *MorphCommandType::getProduced() const{
return morphUnit;
}
// =====================================================
// class CommandFactory
// =====================================================
CommandTypeFactory::CommandTypeFactory(){
registerClass<StopCommandType>("stop");
registerClass<MoveCommandType>("move");
registerClass<AttackCommandType>("attack");
registerClass<AttackStoppedCommandType>("attack_stopped");
registerClass<BuildCommandType>("build");
registerClass<HarvestCommandType>("harvest");
registerClass<RepairCommandType>("repair");
registerClass<ProduceCommandType>("produce");
registerClass<UpgradeCommandType>("upgrade");
registerClass<MorphCommandType>("morph");
}
CommandTypeFactory &CommandTypeFactory::getInstance(){
static CommandTypeFactory ctf;
return ctf;
}
}}//end namespace

View File

@ -0,0 +1,343 @@
// ==============================================================
// This file is part of Glest (www.glest.org)
//
// Copyright (C) 2001-2008 Martiño Figueroa
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version
// ==============================================================
#ifndef _GLEST_GAME_COMMANDTYPE_H_
#define _GLEST_GAME_COMMANDTYPE_H_
#include "element_type.h"
#include "resource_type.h"
#include "lang.h"
#include "skill_type.h"
#include "factory.h"
#include "xml_parser.h"
#include "sound_container.h"
namespace Glest{ namespace Game{
using Shared::Util::MultiFactory;
class UnitUpdater;
class Unit;
class UnitType;
class TechTree;
class FactionType;
enum CommandClass{
ccStop,
ccMove,
ccAttack,
ccAttackStopped,
ccBuild,
ccHarvest,
ccRepair,
ccProduce,
ccUpgrade,
ccMorph,
ccCount,
ccNull
};
enum Clicks{
cOne,
cTwo
};
// =====================================================
// class CommandType
//
/// A complex action performed by a unit, composed by skills
// =====================================================
class CommandType: public RequirableType{
protected:
CommandClass commandTypeClass;
Clicks clicks;
int id;
public:
static const int invalidId= -1;
public:
virtual void update(UnitUpdater *unitUpdater, Unit *unit) const= 0;
virtual void load(int id, const XmlNode *n, const string &dir, const TechTree *tt, const FactionType *ft, const UnitType &ut);
virtual string getDesc(const TotalUpgrade *totalUpgrade) const= 0;
virtual string toString() const= 0;
virtual const ProducibleType *getProduced() const {return NULL;}
virtual bool isQueuable() const {return false;}
//get
CommandClass getClass() const;
Clicks getClicks() const {return clicks;}
int getId() const {return id;}
};
// ===============================
// class StopCommandType
// ===============================
class StopCommandType: public CommandType{
private:
const StopSkillType* stopSkillType;
public:
StopCommandType();
virtual void update(UnitUpdater *unitUpdater, Unit *unit) const;
virtual void load(int id, const XmlNode *n, const string &dir, const TechTree *tt, const FactionType *ft, const UnitType &ut);
virtual string getDesc(const TotalUpgrade *totalUpgrade) const;
virtual string toString() const;
//get
const StopSkillType *getStopSkillType() const {return stopSkillType;};
};
// ===============================
// class MoveCommandType
// ===============================
class MoveCommandType: public CommandType{
private:
const MoveSkillType *moveSkillType;
public:
MoveCommandType();
virtual void update(UnitUpdater *unitUpdater, Unit *unit) const;
virtual void load(int id, const XmlNode *n, const string &dir, const TechTree *tt, const FactionType *ft, const UnitType &ut);
virtual string getDesc(const TotalUpgrade *totalUpgrade) const;
virtual string toString() const;
//get
const MoveSkillType *getMoveSkillType() const {return moveSkillType;};
};
// ===============================
// class AttackCommandType
// ===============================
class AttackCommandType: public CommandType{
private:
const MoveSkillType* moveSkillType;
const AttackSkillType* attackSkillType;
public:
AttackCommandType();
virtual void update(UnitUpdater *unitUpdater, Unit *unit) const;
virtual void load(int id, const XmlNode *n, const string &dir, const TechTree *tt, const FactionType *ft, const UnitType &ut);
virtual string getDesc(const TotalUpgrade *totalUpgrade) const;
virtual string toString() const;
//get
const MoveSkillType * getMoveSkillType() const {return moveSkillType;}
const AttackSkillType * getAttackSkillType() const {return attackSkillType;}
};
// =======================================
// class AttackStoppedCommandType
// =======================================
class AttackStoppedCommandType: public CommandType{
private:
const StopSkillType* stopSkillType;
const AttackSkillType* attackSkillType;
public:
AttackStoppedCommandType();
virtual void update(UnitUpdater *unitUpdater, Unit *unit) const;
virtual void load(int id, const XmlNode *n, const string &dir, const TechTree *tt, const FactionType *ft, const UnitType &ut);
virtual string getDesc(const TotalUpgrade *totalUpgrade) const;
virtual string toString() const;
//get
const StopSkillType * getStopSkillType() const {return stopSkillType;}
const AttackSkillType * getAttackSkillType() const {return attackSkillType;}
};
// ===============================
// class BuildCommandType
// ===============================
class BuildCommandType: public CommandType{
private:
const MoveSkillType* moveSkillType;
const BuildSkillType* buildSkillType;
vector<const UnitType*> buildings;
SoundContainer startSounds;
SoundContainer builtSounds;
public:
BuildCommandType();
~BuildCommandType();
virtual void update(UnitUpdater *unitUpdater, Unit *unit) const;
virtual void load(int id, const XmlNode *n, const string &dir, const TechTree *tt, const FactionType *ft, const UnitType &ut);
virtual string getDesc(const TotalUpgrade *totalUpgrade) const;
virtual string toString() const;
//get
const MoveSkillType *getMoveSkillType() const {return moveSkillType;}
const BuildSkillType *getBuildSkillType() const {return buildSkillType;}
int getBuildingCount() const {return buildings.size();}
const UnitType * getBuilding(int i) const {return buildings[i];}
StaticSound *getStartSound() const {return startSounds.getRandSound();}
StaticSound *getBuiltSound() const {return builtSounds.getRandSound();}
};
// ===============================
// class HarvestCommandType
// ===============================
class HarvestCommandType: public CommandType{
private:
const MoveSkillType *moveSkillType;
const MoveSkillType *moveLoadedSkillType;
const HarvestSkillType *harvestSkillType;
const StopSkillType *stopLoadedSkillType;
vector<const ResourceType*> harvestedResources;
int maxLoad;
int hitsPerUnit;
public:
HarvestCommandType();
virtual void update(UnitUpdater *unitUpdater, Unit *unit) const;
virtual void load(int id, const XmlNode *n, const string &dir, const TechTree *tt, const FactionType *ft, const UnitType &ut);
virtual string getDesc(const TotalUpgrade *totalUpgrade) const;
virtual string toString() const;
//get
const MoveSkillType *getMoveSkillType() const {return moveSkillType;}
const MoveSkillType *getMoveLoadedSkillType() const {return moveLoadedSkillType;}
const HarvestSkillType *getHarvestSkillType() const {return harvestSkillType;}
const StopSkillType *getStopLoadedSkillType() const {return stopLoadedSkillType;}
int getMaxLoad() const {return maxLoad;}
int getHitsPerUnit() const {return hitsPerUnit;}
int getHarvestedResourceCount() const {return harvestedResources.size();}
const ResourceType* getHarvestedResource(int i) const {return harvestedResources[i];}
bool canHarvest(const ResourceType *resourceType) const;
};
// ===============================
// class RepairCommandType
// ===============================
class RepairCommandType: public CommandType{
private:
const MoveSkillType* moveSkillType;
const RepairSkillType* repairSkillType;
vector<const UnitType*> repairableUnits;
public:
RepairCommandType();
~RepairCommandType();
virtual void update(UnitUpdater *unitUpdater, Unit *unit) const;
virtual void load(int id, const XmlNode *n, const string &dir, const TechTree *tt, const FactionType *ft, const UnitType &ut);
virtual string getDesc(const TotalUpgrade *totalUpgrade) const;
virtual string toString() const;
//get
const MoveSkillType *getMoveSkillType() const {return moveSkillType;};
const RepairSkillType *getRepairSkillType() const {return repairSkillType;};
bool isRepairableUnitType(const UnitType *unitType) const;
};
// ===============================
// class ProduceCommandType
// ===============================
class ProduceCommandType: public CommandType{
private:
const ProduceSkillType* produceSkillType;
const UnitType *producedUnit;
public:
ProduceCommandType();
virtual void update(UnitUpdater *unitUpdater, Unit *unit) const;
virtual void load(int id, const XmlNode *n, const string &dir, const TechTree *tt, const FactionType *ft, const UnitType &ut);
virtual string getDesc(const TotalUpgrade *totalUpgrade) const;
virtual string getReqDesc() const;
virtual string toString() const;
virtual const ProducibleType *getProduced() const;
virtual bool isQueuable() const {return true;}
//get
const ProduceSkillType *getProduceSkillType() const {return produceSkillType;}
const UnitType *getProducedUnit() const {return producedUnit;}
};
// ===============================
// class UpgradeCommandType
// ===============================
class UpgradeCommandType: public CommandType{
private:
const UpgradeSkillType* upgradeSkillType;
const UpgradeType* producedUpgrade;
public:
UpgradeCommandType();
virtual void update(UnitUpdater *unitUpdater, Unit *unit) const;
virtual void load(int id, const XmlNode *n, const string &dir, const TechTree *tt, const FactionType *ft, const UnitType &ut);
virtual string getDesc(const TotalUpgrade *totalUpgrade) const;
virtual string toString() const;
virtual string getReqDesc() const;
virtual const ProducibleType *getProduced() const;
virtual bool isQueuable() const {return true;}
//get
const UpgradeSkillType *getUpgradeSkillType() const {return upgradeSkillType;}
const UpgradeType *getProducedUpgrade() const {return producedUpgrade;}
};
// ===============================
// class MorphCommandType
// ===============================
class MorphCommandType: public CommandType{
private:
const MorphSkillType* morphSkillType;
const UnitType* morphUnit;
int discount;
public:
MorphCommandType();
virtual void update(UnitUpdater *unitUpdater, Unit *unit) const;
virtual void load(int id, const XmlNode *n, const string &dir, const TechTree *tt, const FactionType *ft, const UnitType &ut);
virtual string getDesc(const TotalUpgrade *totalUpgrade) const;
virtual string toString() const;
virtual string getReqDesc() const;
virtual const ProducibleType *getProduced() const;
//get
const MorphSkillType *getMorphSkillType() const {return morphSkillType;}
const UnitType *getMorphUnit() const {return morphUnit;}
int getDiscount() const {return discount;}
};
// ===============================
// class CommandFactory
// ===============================
class CommandTypeFactory: public MultiFactory<CommandType>{
private:
CommandTypeFactory();
public:
static CommandTypeFactory &getInstance();
};
}}//end namespace
#endif

View File

@ -0,0 +1,214 @@
// ==============================================================
// This file is part of Glest (www.glest.org)
//
// Copyright (C) 2001-2008 Martiño Figueroa
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version
// ==============================================================
#include "tech_tree.h"
#include <cassert>
#include "util.h"
#include "resource.h"
#include "faction_type.h"
#include "logger.h"
#include "xml_parser.h"
#include "platform_util.h"
#include "game_util.h"
#include "leak_dumper.h"
using namespace Shared::Util;
using namespace Shared::Xml;
namespace Glest{ namespace Game{
// =====================================================
// class TechTree
// =====================================================
void TechTree::loadTech(const vector<string> pathList, const string &techName, set<string> &factions, Checksum* checksum) {
for(int idx = 0; idx < pathList.size(); idx++) {
string path = pathList[idx] + "/" + techName;
if(isdir(path.c_str()) == true) {
load(path, factions, checksum);
break;
}
}
}
void TechTree::load(const string &dir, set<string> &factions, Checksum* checksum) {
string str;
vector<string> filenames;
string name= lastDir(dir);
Logger::getInstance().add("TechTree: "+ formatString(name), true);
//load resources
str= dir+"/resources/*.";
try{
findAll(str, filenames);
resourceTypes.resize(filenames.size());
for(int i=0; i<filenames.size(); ++i){
str=dir+"/resources/"+filenames[i];
resourceTypes[i].load(str, checksum);
}
}
catch(const exception &e){
throw runtime_error("Error loading Resource Types: "+ dir + "\n" + e.what());
}
//load tech tree xml info
try{
XmlTree xmlTree;
string path= dir+"/"+lastDir(dir)+".xml";
bool bCanProcessFile = true;
#ifdef _WINDOWS
DWORD fileAttributes = GetFileAttributes(path.c_str());
if( (fileAttributes & FILE_ATTRIBUTE_HIDDEN) == FILE_ATTRIBUTE_HIDDEN)
{
bCanProcessFile = false;
}
#endif
if(bCanProcessFile == true)
{
checksum->addFile(path);
xmlTree.load(path);
const XmlNode *techTreeNode= xmlTree.getRootNode();
//attack types
const XmlNode *attackTypesNode= techTreeNode->getChild("attack-types");
attackTypes.resize(attackTypesNode->getChildCount());
for(int i=0; i<attackTypes.size(); ++i){
const XmlNode *attackTypeNode= attackTypesNode->getChild("attack-type", i);
attackTypes[i].setName(attackTypeNode->getAttribute("name")->getRestrictedValue());
attackTypes[i].setId(i);
}
//armor types
const XmlNode *armorTypesNode= techTreeNode->getChild("armor-types");
armorTypes.resize(armorTypesNode->getChildCount());
for(int i=0; i<armorTypes.size(); ++i){
const XmlNode *armorTypeNode= armorTypesNode->getChild("armor-type", i);
armorTypes[i].setName(armorTypeNode->getAttribute("name")->getRestrictedValue());
armorTypes[i].setId(i);
}
//damage multipliers
damageMultiplierTable.init(attackTypes.size(), armorTypes.size());
const XmlNode *damageMultipliersNode= techTreeNode->getChild("damage-multipliers");
for(int i=0; i<damageMultipliersNode->getChildCount(); ++i){
const XmlNode *damageMultiplierNode= damageMultipliersNode->getChild("damage-multiplier", i);
const AttackType *attackType= getAttackType(damageMultiplierNode->getAttribute("attack")->getRestrictedValue());
const ArmorType *armorType= getArmorType(damageMultiplierNode->getAttribute("armor")->getRestrictedValue());
float multiplier= damageMultiplierNode->getAttribute("value")->getFloatValue();
damageMultiplierTable.setDamageMultiplier(attackType, armorType, multiplier);
}
}
}
catch(const exception &e){
throw runtime_error("Error loading Tech Tree: "+ dir + "\n" + e.what());
}
//load factions
str= dir+"/factions/*.";
try{
factionTypes.resize(factions.size());
int i=0;
for ( set<string>::iterator it = factions.begin(); it != factions.end(); ++it ) {
str=dir+"/factions/" + *it;
factionTypes[i++].load(str, this, checksum);
}
}
catch(const exception &e){
throw runtime_error("Error loading Faction Types: "+ dir + "\n" + e.what());
}
}
TechTree::~TechTree(){
Logger::getInstance().add("Tech tree", true);
}
// ==================== get ====================
const FactionType *TechTree::getType(const string &name) const{
for(int i=0; i<factionTypes.size(); ++i){
if(factionTypes[i].getName()==name){
return &factionTypes[i];
}
}
throw runtime_error("Faction not found: "+name);
}
const ResourceType *TechTree::getTechResourceType(int i) const{
for(int j=0; j<getResourceTypeCount(); ++j){
const ResourceType *rt= getResourceType(j);
if(rt->getResourceNumber()==i && rt->getClass()==rcTech)
return getResourceType(j);
}
return getFirstTechResourceType();
}
const ResourceType *TechTree::getFirstTechResourceType() const{
for(int i=0; i<getResourceTypeCount(); ++i){
const ResourceType *rt= getResourceType(i);
if(rt->getResourceNumber()==1 && rt->getClass()==rcTech)
return getResourceType(i);
}
throw runtime_error("This tech tree has not tech resources, one at least is required");
}
const ResourceType *TechTree::getResourceType(const string &name) const{
for(int i=0; i<resourceTypes.size(); ++i){
if(resourceTypes[i].getName()==name){
return &resourceTypes[i];
}
}
throw runtime_error("Resource Type not found: "+name);
}
const ArmorType *TechTree::getArmorType(const string &name) const{
for(int i=0; i<armorTypes.size(); ++i){
if(armorTypes[i].getName()==name){
return &armorTypes[i];
}
}
throw runtime_error("Armor Type not found: "+name);
}
const AttackType *TechTree::getAttackType(const string &name) const{
for(int i=0; i<attackTypes.size(); ++i){
if(attackTypes[i].getName()==name){
return &attackTypes[i];
}
}
throw runtime_error("Attack Type not found: "+name);
}
float TechTree::getDamageMultiplier(const AttackType *att, const ArmorType *art) const{
return damageMultiplierTable.getDamageMultiplier(att, art);
}
}}//end namespace

View File

@ -0,0 +1,67 @@
// ==============================================================
// This file is part of Glest (www.glest.org)
//
// Copyright (C) 2001-2008 Martiño Figueroa
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version
// ==============================================================
#ifndef _GLEST_GAME_TECHTREE_H_
#define _GLEST_GAME_TECHTREE_H_
#include <set>
#include "util.h"
#include "resource_type.h"
#include "faction_type.h"
#include "damage_multiplier.h"
namespace Glest{ namespace Game{
// =====================================================
// class TechTree
//
/// A set of factions and resources
// =====================================================
class TechTree{
private:
typedef vector<ResourceType> ResourceTypes;
typedef vector<FactionType> FactionTypes;
typedef vector<ArmorType> ArmorTypes;
typedef vector<AttackType> AttackTypes;
private:
string desc;
ResourceTypes resourceTypes;
FactionTypes factionTypes;
ArmorTypes armorTypes;
AttackTypes attackTypes;
DamageMultiplierTable damageMultiplierTable;
public:
void loadTech(const vector<string> pathList, const string &techName, set<string> &factions, Checksum* checksum);
void load(const string &dir, set<string> &factions, Checksum* checksum);
~TechTree();
//get
int getResourceTypeCount() const {return resourceTypes.size();}
int getTypeCount() const {return factionTypes.size();}
const FactionType *getType(int i) const {return &factionTypes[i];}
const ResourceType *getResourceType(int i) const {return &resourceTypes[i];}
const string &getDesc() const {return desc;}
const FactionType *getType(const string &name) const;
const ResourceType *getResourceType(const string &name) const;
const ResourceType *getTechResourceType(int i) const;
const ResourceType *getFirstTechResourceType() const;
const ArmorType *getArmorType(const string &name) const;
const AttackType *getAttackType(const string &name) const;
float getDamageMultiplier(const AttackType *att, const ArmorType *art) const;
};
}} //end namespace
#endif

View File

@ -521,7 +521,9 @@ void UnitType::computeFirstStOfClass(){
}
}
void UnitType::computeFirstCtOfClass(){
void UnitType::computeFirstCtOfClass(){
printf("In [%s::%s Line: %d] \n",__FILE__,__FUNCTION__,__LINE__);
for(int j=0; j<ccCount; ++j){
firstCommandTypeOfClass[j]= NULL;
for(int i=0; i<commandTypes.size(); ++i){

View File

@ -614,16 +614,23 @@ void Map::computeCellColors(){
}
// static
string Map::getMapPath(const string &mapName) {
string mega = "maps/" + mapName + ".mgm";
string glest = "maps/" + mapName + ".gbm";
if (fileExists(mega)) {
return mega;
} else if (fileExists(glest)) {
return glest;
} else {
throw runtime_error("Map " + mapName + " not found.");
}
string Map::getMapPath(const string &mapName) {
Config &config = Config::getInstance();
vector<string> pathList = config.getPathListForType(ptMaps);
for(int idx = 0; idx < pathList.size(); idx++) {
const string &map_path = pathList[idx];
const string mega = map_path + "/" + mapName + ".mgm";
const string glest = map_path + "/" + mapName + ".gbm";
if (fileExists(mega)) {
return mega;
}
else if (fileExists(glest)) {
return glest;
}
}
throw runtime_error("Map " + mapName + " not found.");
}
// =====================================================

View File

@ -0,0 +1,101 @@
// ==============================================================
// This file is part of Glest (www.glest.org)
//
// Copyright (C) 2001-2005 Martiño Figueroa
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version
// ==============================================================
#include "scenario.h"
#include <stdexcept>
#include "logger.h"
#include "xml_parser.h"
#include "util.h"
#include "game_util.h"
#include "leak_dumper.h"
#include <stdio.h>
using namespace Shared::Xml;
using namespace Shared::Util;
using namespace std;
namespace Glest{ namespace Game{
// =====================================================
// class Scenario
// =====================================================
Scenario::~Scenario(){
}
void Scenario::load(const string &path){
try{
string name= cutLastExt(lastDir(path));
Logger::getInstance().add("Scenario: "+formatString(name), true);
//parse xml
XmlTree xmlTree;
xmlTree.load(path);
const XmlNode *scenarioNode= xmlTree.getRootNode();
const XmlNode *scriptsNode= scenarioNode->getChild("scripts");
for(int i= 0; i<scriptsNode->getChildCount(); ++i){
const XmlNode *scriptNode = scriptsNode->getChild(i);
scripts.push_back(Script(getFunctionName(scriptNode), scriptNode->getText()));
}
}
//Exception handling (conversions and so on);
catch(const exception &e){
throw runtime_error("Error: " + path + "\n" + e.what());
}
}
int Scenario::getScenarioPathIndex(const vector<string> dirList, const string &scenarioName) {
int iIndex = 0;
for(int idx = 0; idx < dirList.size(); idx++) {
string scenarioFile = dirList[idx] + "/" + scenarioName + "/" + scenarioName + ".xml";
if(fileExists(scenarioFile) == true) {
iIndex = idx;
break;
}
}
return iIndex;
}
string Scenario::getScenarioPath(const vector<string> dirList, const string &scenarioName){
string scenarioFile = "";
for(int idx = 0; idx < dirList.size(); idx++) {
scenarioFile = dirList[idx] + "/" + scenarioName + "/" + scenarioName + ".xml";
if(fileExists(scenarioFile) == true) {
break;
}
}
return scenarioFile;
}
string Scenario::getScenarioPath(const string &dir, const string &scenarioName){
string scenarioFile = dir + "/" + scenarioName + "/" + scenarioName + ".xml";
//printf("dir [%s] scenarioName [%s] scenarioFile [%s]\n",dir.c_str(),scenarioName.c_str(),scenarioFile.c_str());
return scenarioFile;
}
string Scenario::getFunctionName(const XmlNode *scriptNode){
string name= scriptNode->getName();
for(int i= 0; i<scriptNode->getAttributeCount(); ++i){
name+= "_" + scriptNode->getAttribute(i)->getValue();
}
return name;
}
}}//end namespace

View File

@ -0,0 +1,72 @@
// ==============================================================
// This file is part of Glest (www.glest.org)
//
// Copyright (C) 2001-2005 Martiño Figueroa
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version
// ==============================================================
#ifndef _GLEST_GAME_SCENARIO_H_
#define _GLEST_GAME_SCENARIO_H_
#include <string>
#include <vector>
#include "xml_parser.h"
using std::string;
using std::vector;
using std::pair;
using Shared::Xml::XmlNode;
namespace Glest{ namespace Game{
// =====================================================
// class Script
// =====================================================
class Script{
private:
string name;
string code;
public:
Script(const string &name, const string &code) {this->name= name; this->code= code;}
const string &getName() const {return name;}
const string &getCode() const {return code;}
};
// =====================================================
// class Scenario
// =====================================================
class Scenario{
private:
typedef pair<string, string> NameScriptPair;
typedef vector<Script> Scripts;
Scripts scripts;
public:
~Scenario();
void load(const string &path);
int getScriptCount() const {return scripts.size();}
const Script* getScript(int i) const {return &scripts[i];}
static string getScenarioPath(const vector<string> dir, const string &scenarioName);
static string getScenarioPath(const string &dir, const string &scenarioName);
static int getScenarioPathIndex(const vector<string> dirList, const string &scenarioName);
private:
string getFunctionName(const XmlNode *scriptNode);
};
}}//end namespace
#endif

View File

@ -0,0 +1,274 @@
// ==============================================================
// This file is part of Glest (www.glest.org)
//
// Copyright (C) 2001-2008 Martiño Figueroa
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version
// ==============================================================
#include "tileset.h"
#include <cassert>
#include <ctime>
#include "logger.h"
#include "util.h"
#include "renderer.h"
#include "game_util.h"
#include "leak_dumper.h"
#include "platform_util.h"
using namespace Shared::Util;
using namespace Shared::Xml;
using namespace Shared::Graphics;
namespace Glest{ namespace Game{
// =====================================================
// class AmbientSounds
// =====================================================
void AmbientSounds::load(const string &dir, const XmlNode *xmlNode){
string path;
//day
const XmlNode *dayNode= xmlNode->getChild("day-sound");
enabledDay= dayNode->getAttribute("enabled")->getBoolValue();
if(enabledDay){
path= dayNode->getAttribute("path")->getRestrictedValue();
day.open(dir + "/" + path);
alwaysPlayDay= dayNode->getAttribute("play-always")->getBoolValue();
}
//night
const XmlNode *nightNode= xmlNode->getChild("night-sound");
enabledNight= nightNode->getAttribute("enabled")->getBoolValue();
if(enabledNight){
path= nightNode->getAttribute("path")->getRestrictedValue();
night.open(dir + "/" + path);
alwaysPlayNight= nightNode->getAttribute("play-always")->getBoolValue();
}
//rain
const XmlNode *rainNode= xmlNode->getChild("rain-sound");
enabledRain= rainNode->getAttribute("enabled")->getBoolValue();
if(enabledRain){
path= rainNode->getAttribute("path")->getRestrictedValue();
rain.open(dir + "/" + path);
}
//snow
const XmlNode *snowNode= xmlNode->getChild("snow-sound");
enabledSnow= snowNode->getAttribute("enabled")->getBoolValue();
if(enabledSnow){
path= snowNode->getAttribute("path")->getRestrictedValue();
snow.open(dir + "/" + path);
}
//dayStart
const XmlNode *dayStartNode= xmlNode->getChild("day-start-sound");
enabledDayStart= dayStartNode->getAttribute("enabled")->getBoolValue();
if(enabledDayStart){
path= dayStartNode->getAttribute("path")->getRestrictedValue();
dayStart.load(dir + "/" + path);
}
//nightStart
const XmlNode *nightStartNode= xmlNode->getChild("night-start-sound");
enabledNightStart= nightStartNode->getAttribute("enabled")->getBoolValue();
if(enabledNightStart){
path= nightStartNode->getAttribute("path")->getRestrictedValue();
nightStart.load(dir + "/" + path);
}
}
// =====================================================
// class Tileset
// =====================================================
void Tileset::loadTileset(const vector<string> pathList, const string &tilesetName, Checksum* checksum) {
for(int idx = 0; idx < pathList.size(); idx++) {
const string path = pathList[idx] + "/" + tilesetName;
if(isdir(path.c_str()) == true) {
load(path, checksum);
break;
}
}
}
void Tileset::load(const string &dir, Checksum *checksum){
random.init(time(NULL));
string name= lastDir(dir);
string path= dir+"/"+name+".xml";
#ifdef _WINDOWS
DWORD fileAttributes = GetFileAttributes(path.c_str());
if( (fileAttributes & FILE_ATTRIBUTE_HIDDEN) == FILE_ATTRIBUTE_HIDDEN)
{
return;
}
#endif
checksum->addFile(path);
try{
Logger::getInstance().add("Tileset: "+formatString(name), true);
Renderer &renderer= Renderer::getInstance();
//parse xml
XmlTree xmlTree;
xmlTree.load(path);
const XmlNode *tilesetNode= xmlTree.getRootNode();
//surfaces
const XmlNode *surfacesNode= tilesetNode->getChild("surfaces");
for(int i=0; i<surfCount; ++i){
const XmlNode *surfaceNode= surfacesNode->getChild("surface", i);
int childCount= surfaceNode->getChildCount();
surfPixmaps[i].resize(childCount);
surfProbs[i].resize(childCount);
for(int j=0; j<childCount; ++j){
const XmlNode *textureNode= surfaceNode->getChild("texture", j);
surfPixmaps[i][j].init(3);
surfPixmaps[i][j].load(dir +"/"+textureNode->getAttribute("path")->getRestrictedValue());
surfProbs[i][j]= textureNode->getAttribute("prob")->getFloatValue();
}
}
//object models
const XmlNode *objectsNode= tilesetNode->getChild("objects");
for(int i=0; i<objCount; ++i){
const XmlNode *objectNode= objectsNode->getChild("object", i);
int childCount= objectNode->getChildCount();
objectTypes[i].init(childCount, i, objectNode->getAttribute("walkable")->getBoolValue());
for(int j=0; j<childCount; ++j){
const XmlNode *modelNode= objectNode->getChild("model", j);
const XmlAttribute *pathAttribute= modelNode->getAttribute("path");
objectTypes[i].loadModel(dir +"/"+ pathAttribute->getRestrictedValue());
}
}
//ambient sounds
ambientSounds.load(dir, tilesetNode->getChild("ambient-sounds"));
//parameters
const XmlNode *parametersNode= tilesetNode->getChild("parameters");
//water
const XmlNode *waterNode= parametersNode->getChild("water");
waterTex= renderer.newTexture3D(rsGame);
waterTex->setMipmap(false);
waterTex->setWrapMode(Texture::wmRepeat);
waterEffects= waterNode->getAttribute("effects")->getBoolValue();
int waterFrameCount= waterNode->getChildCount();
waterTex->getPixmap()->init(waterFrameCount, 4);
for(int i=0; i<waterFrameCount; ++i){
const XmlNode *waterFrameNode= waterNode->getChild("texture", i);
waterTex->getPixmap()->loadSlice(dir +"/"+ waterFrameNode->getAttribute("path")->getRestrictedValue(), i);
}
//fog
const XmlNode *fogNode= parametersNode->getChild("fog");
fog= fogNode->getAttribute("enabled")->getBoolValue();
if(fog){
fogMode= fogNode->getAttribute("mode")->getIntValue(1, 2);
fogDensity= fogNode->getAttribute("density")->getFloatValue();
fogColor.x= fogNode->getAttribute("color-red")->getFloatValue(0.f, 1.f);
fogColor.y= fogNode->getAttribute("color-green")->getFloatValue(0.f, 1.f);
fogColor.z= fogNode->getAttribute("color-blue")->getFloatValue(0.f, 1.f);
}
//sun and moon light colors
const XmlNode *sunLightColorNode= parametersNode->getChild("sun-light");
sunLightColor.x= sunLightColorNode->getAttribute("red")->getFloatValue();
sunLightColor.y= sunLightColorNode->getAttribute("green")->getFloatValue();
sunLightColor.z= sunLightColorNode->getAttribute("blue")->getFloatValue();
const XmlNode *moonLightColorNode= parametersNode->getChild("moon-light");
moonLightColor.x= moonLightColorNode->getAttribute("red")->getFloatValue();
moonLightColor.y= moonLightColorNode->getAttribute("green")->getFloatValue();
moonLightColor.z= moonLightColorNode->getAttribute("blue")->getFloatValue();
//weather
const XmlNode *weatherNode= parametersNode->getChild("weather");
float sunnyProb= weatherNode->getAttribute("sun")->getFloatValue(0.f, 1.f);
float rainyProb= weatherNode->getAttribute("rain")->getFloatValue(0.f, 1.f) + sunnyProb;
float rnd= fabs(random.randRange(-1.f, 1.f));
if(rnd<sunnyProb){
weather= wSunny;
}
else if(rnd<rainyProb){
weather= wRainy;
}
else{
weather= wSnowy;
}
}
//Exception handling (conversions and so on);
catch(const exception &e){
throw runtime_error("Error: " + path + "\n" + e.what());
}
}
Tileset::~Tileset(){
Logger::getInstance().add("Tileset", true);
}
const Pixmap2D *Tileset::getSurfPixmap(int type, int var) const{
int vars= surfPixmaps[type].size();
return &surfPixmaps[type][var % vars];
}
void Tileset::addSurfTex(int leftUp, int rightUp, int leftDown, int rightDown, Vec2f &coord, const Texture2D *&texture){
//center textures
if(leftUp==rightUp && leftUp==leftDown && leftUp==rightDown){
//texture variation according to probability
float r= random.randRange(0.f, 1.f);
int var= 0;
float max= 0.f;
for(int i=0; i<surfProbs[leftUp].size(); ++i){
max+= surfProbs[leftUp][i];
if(r<=max){
var= i;
break;
}
}
SurfaceInfo si(getSurfPixmap(leftUp, var));
surfaceAtlas.addSurface(&si);
coord= si.getCoord();
texture= si.getTexture();
}
//spatted textures
else{
int var= random.randRange(0, transitionVars);
SurfaceInfo si(
getSurfPixmap(leftUp, var),
getSurfPixmap(rightUp, var),
getSurfPixmap(leftDown, var),
getSurfPixmap(rightDown, var));
surfaceAtlas.addSurface(&si);
coord= si.getCoord();
texture= si.getTexture();
}
}
}}// end namespace

View File

@ -0,0 +1,160 @@
// ==============================================================
// This file is part of Glest (www.glest.org)
//
// Copyright (C) 2001-2008 Martiño Figueroa
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version
// ==============================================================
#ifndef _GLEST_GAME_TILESET_H_
#define _GLEST_GAME_TILESET_H_
#include <map>
#include "graphics_interface.h"
#include "xml_parser.h"
#include "object_type.h"
#include "sound.h"
#include "random.h"
#include "surface_atlas.h"
#include "checksum.h"
namespace Glest{ namespace Game{
using Shared::Xml::XmlNode;
using Shared::Sound::StaticSound;
using Shared::Sound::StrSound;
using Shared::Graphics::Model;
using Shared::Graphics::Vec3f;
using Shared::Graphics::Texture2D;
using Shared::Graphics::Texture3D;
using Shared::Util::Random;
using Shared::Util::Checksum;
using std::map;
enum FogMode{
fmExp,
fmExp2
};
enum Weather{
wSunny,
wRainy,
wSnowy
};
class Renderer;
class SurfaceCell;
// =====================================================
// class AmbientSounds
// =====================================================
class AmbientSounds{
private:
bool enabledDay;
bool enabledNight;
bool enabledRain;
bool enabledSnow;
bool enabledDayStart;
bool enabledNightStart;
bool alwaysPlayDay;
bool alwaysPlayNight;
StrSound day;
StrSound night;
StrSound rain;
StrSound snow;
StaticSound dayStart;
StaticSound nightStart;
public:
bool isEnabledDay() const {return enabledDay;}
bool isEnabledNight() const {return enabledNight;}
bool isEnabledRain() const {return enabledRain;}
bool isEnabledSnow() const {return enabledSnow;}
bool isEnabledDayStart() const {return enabledDayStart;}
bool isEnabledNightStart() const {return enabledNightStart;}
bool getAlwaysPlayDay() const {return alwaysPlayDay;}
bool getAlwaysPlayNight() const {return alwaysPlayNight;}
StrSound *getDay() {return &day;}
StrSound *getNight() {return &night;}
StrSound *getRain() {return &rain;}
StrSound *getSnow() {return &snow;}
StaticSound *getDayStart() {return &dayStart;}
StaticSound *getNightStart() {return &nightStart;}
void load(const string &dir, const XmlNode *xmlNode);
};
// =====================================================
// class Tileset
//
/// Containt textures, models and parameters for a tileset
// =====================================================
class Tileset{
public:
static const int waterTexCount= 1;
static const int surfCount= 5;
static const int objCount= 10;
static const int transitionVars= 2; //number or different transition textures
public:
typedef vector<float> SurfProbs;
typedef vector<Pixmap2D> SurfPixmaps;
private:
SurfaceAtlas surfaceAtlas;
ObjectType objectTypes[objCount];
SurfProbs surfProbs[surfCount];
SurfPixmaps surfPixmaps[surfCount];
Random random;
Texture3D *waterTex;
bool waterEffects;
bool fog;
int fogMode;
float fogDensity;
Vec3f fogColor;
Vec3f sunLightColor;
Vec3f moonLightColor;
Weather weather;
AmbientSounds ambientSounds;
public:
~Tileset();
void loadTileset(const vector<string> pathList, const string &tilesetName, Checksum* checksum);
void load(const string &dir, Checksum *checksum);
//get
const SurfaceAtlas *getSurfaceAtlas() const {return &surfaceAtlas;}
ObjectType *getObjectType(int i) {return &objectTypes[i];}
float getSurfProb(int surf, int var) const {return surfProbs[surf][var];}
Texture3D *getWaterTex() const {return waterTex;}
bool getWaterEffects() const {return waterEffects;}
bool getFog() const {return fog;}
int getFogMode() const {return fogMode;}
float getFogDensity() const {return fogDensity;}
const Vec3f &getFogColor() const {return fogColor;}
const Vec3f &getSunLightColor() const {return sunLightColor;}
const Vec3f &getMoonLightColor() const {return moonLightColor;}
Weather getWeather() const {return weather;}
//surface textures
const Pixmap2D *getSurfPixmap(int type, int var) const;
void addSurfTex(int leftUp, int rightUp, int leftDown, int rightDown, Vec2f &coord, const Texture2D *&texture);
//sounds
AmbientSounds *getAmbientSounds() {return &ambientSounds;}
};
}} //end namespace
#endif

View File

@ -42,6 +42,7 @@ namespace Glest{ namespace Game{
void UnitUpdater::init(Game *game){
this->game= game;
this->gui= game->getGui();
this->gameCamera= game->getGameCamera();
this->world= game->getWorld();
@ -83,6 +84,7 @@ void UnitUpdater::updateUnit(Unit *unit){
//update unit
if(unit->update()){
//if(Socket::enableDebugText) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
updateUnitCommand(unit);
@ -122,8 +124,10 @@ void UnitUpdater::updateUnitCommand(Unit *unit){
//if no commands stop and add stop command
if(!unit->anyCommand() && unit->isOperative()){
//if(Socket::enableDebugText) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
unit->setCurrSkill(scStop);
if(unit->getType()->hasCommandClass(ccStop)){
if(Socket::enableDebugText) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
unit->giveCommand(new Command(unit->getType()->getFirstCtOfClass(ccStop)));
}
}
@ -156,6 +160,7 @@ void UnitUpdater::updateStop(Unit *unit){
//use it to attack
if(ast!=NULL){
if(attackableOnSight(unit, &sighted, ast)){
if(Socket::enableDebugText) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
unit->giveCommand(new Command(ct, sighted->getPos()));
break;
}
@ -167,6 +172,7 @@ void UnitUpdater::updateStop(Unit *unit){
else if(unit->getType()->hasCommandClass(ccMove)){
if(attackerOnSight(unit, &sighted)){
Vec2i escapePos= unit->getPos()*2-sighted->getPos();
if(Socket::enableDebugText) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
unit->giveCommand(new Command(unit->getType()->getFirstCtOfClass(ccMove), escapePos));
}
}
@ -174,7 +180,6 @@ void UnitUpdater::updateStop(Unit *unit){
// ==================== updateMove ====================
void UnitUpdater::updateMove(Unit *unit){
Command *command= unit->getCurrCommand();
@ -290,9 +295,13 @@ void UnitUpdater::updateBuild(Unit *unit){
//!!!
float unitRotation = -1;
if(allowRotateUnits == true) {
if(Socket::enableDebugText) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
char unitKey[50]="";
sprintf(unitKey,"%d_%d",builtUnitType->getId(),unit->getFaction()->getIndex());
unitRotation = gui->getUnitTypeBuildRotation(unitKey);
if(Socket::enableDebugText) printf("In [%s::%s Line: %d] builtUnitType->getId() = %d unitRotation = %f\n",__FILE__,__FUNCTION__,__LINE__,builtUnitType->getId(),unitRotation);
}
Unit *builtUnit= new Unit(world->getNextUnitId(), command->getPos(), builtUnitType, unit->getFaction(), world->getMap(),unitRotation);
builtUnit->create();
@ -314,25 +323,6 @@ void UnitUpdater::updateBuild(Unit *unit){
unit->getCurrVector(),
gameCamera->getPos());
}
//!!!
/*
if(unitRotation > 0) {
if(Socket::enableDebugText) printf("In [%s::%s] before sending ccRotateUnit...\n",__FILE__,__FUNCTION__);
RotateUnitCommandType *rotateCmdType = new RotateUnitCommandType();
rotateCmdType->setRotateAmount(unitRotation);
Command *rotateUnitCmd = new Command(rotateCmdType);
rotateUnitCmd->setUnit(builtUnit);
if(Socket::enableDebugText) printf("In [%s::%s] in sending ccRotateUnit...\n",__FILE__,__FUNCTION__);
builtUnit->giveCommand(rotateUnitCmd);
if(Socket::enableDebugText) printf("In [%s::%s] after sending ccRotateUnit...\n",__FILE__,__FUNCTION__);
}
*/
}
else{
//if there are no free cells
@ -585,6 +575,7 @@ void UnitUpdater::updateProduce(Unit *unit){
world->getStats()->produce(unit->getFactionIndex());
const CommandType *ct= produced->computeCommandType(unit->getMeetingPos());
if(ct!=NULL){
if(Socket::enableDebugText) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
produced->giveCommand(new Command(ct, unit->getMeetingPos()));
}
scriptManager->onUnitCreated(produced);

View File

@ -53,7 +53,8 @@ private:
World *world;
Console *console;
ScriptManager *scriptManager;
PathFinder pathFinder;
PathFinder pathFinder;
Game *game;
Random random;
bool allowRotateUnits;
@ -74,7 +75,7 @@ public:
void updateRepair(Unit *unit);
void updateProduce(Unit *unit);
void updateUpgrade(Unit *unit);
void updateMorph(Unit *unit);
void updateMorph(Unit *unit);
private:
//attack

View File

@ -85,14 +85,19 @@ void World::init(Game *game, bool createUnits){
}
//load tileset
void World::loadTileset(const vector<string> pathList, const string &tilesetName, Checksum* checksum) {
tileset.loadTileset(pathList, tilesetName, checksum);
timeFlow.init(&tileset);
}
void World::loadTileset(const string &dir, Checksum *checksum){
tileset.load(dir, checksum);
timeFlow.init(&tileset);
}
//load tech
void World::loadTech(const string &dir, set<string> &factions, Checksum *checksum){
techTree.load(dir, factions, checksum);
void World::loadTech(const vector<string> pathList, const string &techName, set<string> &factions, Checksum *checksum){
techTree.loadTech(pathList, techName, factions, checksum);
}
//load map

View File

@ -117,9 +117,10 @@ public:
int getFrameCount() const {return frameCount;}
//init & load
void init(Game *game, bool createUnits);
void init(Game *game, bool createUnits);
void loadTileset(const vector<string> pathList, const string &tilesetName, Checksum* checksum);
void loadTileset(const string &dir, Checksum* checksum);
void loadTech(const string &dir, set<string> &factions, Checksum* checksum);
void loadTech(const vector<string> pathList, const string &techName, set<string> &factions, Checksum* checksum);
void loadMap(const string &path, Checksum* checksum);
void loadScenario(const string &path, Checksum* checksum);
@ -144,7 +145,9 @@ public:
Vec2i getUnitPosition(int unitId);
int getUnitFactionIndex(int unitId);
int getUnitCount(int factionIndex);
int getUnitCountOfType(int factionIndex, const string &typeName);
int getUnitCountOfType(int factionIndex, const string &typeName);
Game * getGame() { return game; }
private:

View File

@ -0,0 +1,118 @@
// ==============================================================
// This file is part of Glest Shared Library (www.glest.org)
//
// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version
// ==============================================================
#ifndef _SHARED_PLATFORM_PLATFORMUTIL_H_
#define _SHARED_PLATFORM_PLATFORMUTIL_H_
#include <string>
#include <vector>
#include <stdexcept>
#include <SDL.h>
#include "types.h"
#include "checksum.h"
#include <utility>
using std::string;
using std::vector;
using std::exception;
using Shared::Platform::int64;
using Shared::Util::Checksum;
namespace Shared{ namespace Platform{
// =====================================================
// class PerformanceTimer
// =====================================================
class PerformanceTimer{
private:
Uint32 lastTicks;
Uint32 updateTicks;
int times; // number of consecutive times
int maxTimes; // maximum number consecutive times
public:
void init(float fps, int maxTimes= -1);
bool isTime();
void reset();
};
// =====================================================
// class Chrono
// =====================================================
class Chrono {
private:
Uint32 startCount;
Uint32 accumCount;
Uint32 freq;
bool stopped;
public:
Chrono();
void start();
void stop();
int64 getMicros() const;
int64 getMillis() const;
int64 getSeconds() const;
private:
int64 queryCounter(int multiplier) const;
};
// =====================================================
// class PlatformExceptionHandler
// =====================================================
class PlatformExceptionHandler {
public:
virtual ~PlatformExceptionHandler() {}
void install(string dumpFileName) {}
virtual void handle()=0;
};
// =====================================================
// Misc
// =====================================================
int MessageBox(int handle, const char *msg, const char *title, int buttons);
bool isdir(const char *path);
void findDirs(const vector<string> &paths, vector<string> &results, bool errorOnNotFound=false);
void findAll(const vector<string> &paths, const string &fileFilter, vector<string> &results, bool cutExtension=false, bool errorOnNotFound=true);
void findAll(const string &path, vector<string> &results, bool cutExtension=false, bool errorOnNotFound=true);
int32 getFolderTreeContentsCheckSumRecursively(const string &path, const string &filterFileExt, Checksum *recursiveChecksum);
vector<std::pair<string,int32> > getFolderTreeContentsCheckSumListRecursively(const string &path, const string &filterFileExt, vector<std::pair<string,int32> > *recursiveMap);
void createDirectoryPaths(string Path);
string extractDirectoryPathFromFile(string filename);
bool changeVideoMode(int resH, int resW, int colorBits, int refreshFrequency);
void restoreVideoMode();
void message(string message);
bool ask(string message);
void exceptionMessage(const exception &excp);
int getScreenW();
int getScreenH();
void sleep(int millis);
void showCursor(bool b);
bool isKeyDown(int virtualKey);
string getCommandLine();
}}//end namespace
#endif

View File

@ -0,0 +1,127 @@
// ==============================================================
// This file is part of Glest Shared Library (www.glest.org)
//
// Copyright (C) 2001-2008 Martiño Figueroa
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version
// ==============================================================
#ifndef _SHARED_PLATFORM_PLATFORMUTIL_H_
#define _SHARED_PLATFORM_PLATFORMUTIL_H_
#include <windows.h>
#include <string>
#include <vector>
#include <stdexcept>
#include "types.h"
#include "checksum.h"
#include <utility>
using std::string;
using std::vector;
using std::exception;
using Shared::Platform::int64;
using Shared::Util::Checksum;
namespace Shared{ namespace Platform{
// =====================================================
// class PerformanceTimer
// =====================================================
class PerformanceTimer{
private:
int64 thisTicks;
int64 lastTicks;
int64 updateTicks;
int times; // number of consecutive times
int maxTimes; // maximum number consecutive times
public:
void init(int fps, int maxTimes= -1);
bool isTime();
void reset();
};
// =====================================================
// class Chrono
// =====================================================
class Chrono{
private:
int64 startCount;
int64 accumCount;
int64 freq;
bool stopped;
public:
Chrono();
void start();
void stop();
int64 getMicros() const;
int64 getMillis() const;
int64 getSeconds() const;
private:
int64 queryCounter(int multiplier) const;
};
// =====================================================
// class PlatformExceptionHandler
// =====================================================
LONG WINAPI UnhandledExceptionFilter2(struct _EXCEPTION_POINTERS *ExceptionInfo);
class PlatformExceptionHandler{
private:
static PlatformExceptionHandler *thisPointer;
private:
static LONG WINAPI handler(LPEXCEPTION_POINTERS pointers);
string dumpFileName;
public:
void install(string dumpFileName);
virtual void handle()=0;
static string codeToStr(DWORD code);
};
// =====================================================
// Misc
// =====================================================
bool isdir(const char *path);
void findDirs(const vector<string> &paths, vector<string> &results, bool errorOnNotFound=false);
void findAll(const vector<string> &paths, const string &fileFilter, vector<string> &results, bool cutExtension=false, bool errorOnNotFound=true);
void findAll(const string &path, vector<string> &results, bool cutExtension=false, bool errorOnNotFound=true);
int32 getFolderTreeContentsCheckSumRecursively(const string &path, const string &filterFileExt, Checksum *recursiveChecksum);
vector<std::pair<string,int32> > getFolderTreeContentsCheckSumListRecursively(const string &path, const string &filterFileExt, vector<std::pair<string,int32> > *recursiveMap);
void createDirectoryPaths(string Path);
string extractDirectoryPathFromFile(string filename);
bool changeVideoMode(int resH, int resW, int colorBits, int refreshFrequency);
void restoreVideoMode();
void message(string message);
bool ask(string message);
void exceptionMessage(const exception &excp);
int getScreenW();
int getScreenH();
void sleep(int millis);
void showCursor(bool b);
bool isKeyDown(int virtualKey);
string getCommandLine();
}}//end namespace
#endif

View File

@ -0,0 +1,524 @@
//This file is part of Glest Shared Library (www.glest.org)
//Copyright (C) 2005 Matthias Braun <matze@braunis.de>
//You can redistribute this code and/or modify it under
//the terms of the GNU General Public License as published by the Free Software
//Foundation; either version 2 of the License, or (at your option) any later
//version.
#include "platform_util.h"
#include <iostream>
#include <sstream>
#include <cassert>
#include <glob.h>
#include <errno.h>
#include <string.h>
#include <SDL.h>
#include "util.h"
#include "conversion.h"
#include "leak_dumper.h"
#include "sdl_private.h"
#include "window.h"
#include "noimpl.h"
#include "checksum.h"
#include "socket.h"
#include <algorithm>
#include <unistd.h>
using namespace Shared::Util;
using namespace std;
namespace Shared{ namespace Platform{
namespace Private{
bool shouldBeFullscreen = false;
int ScreenWidth;
int ScreenHeight;
}
// =====================================
// PerformanceTimer
// =====================================
void PerformanceTimer::init(float fps, int maxTimes){
times= 0;
this->maxTimes= maxTimes;
lastTicks= SDL_GetTicks();
updateTicks= static_cast<int>(1000./fps);
}
bool PerformanceTimer::isTime(){
Uint32 thisTicks = SDL_GetTicks();
if((thisTicks-lastTicks)>=updateTicks && times<maxTimes){
lastTicks+= updateTicks;
times++;
return true;
}
times= 0;
return false;
}
void PerformanceTimer::reset(){
lastTicks= SDL_GetTicks();
}
// =====================================
// Chrono
// =====================================
Chrono::Chrono() {
freq = 1000;
stopped= true;
accumCount= 0;
}
void Chrono::start() {
stopped= false;
startCount = SDL_GetTicks();
}
void Chrono::stop() {
Uint32 endCount;
endCount = SDL_GetTicks();
accumCount += endCount-startCount;
stopped= true;
}
int64 Chrono::getMicros() const {
return queryCounter(1000000);
}
int64 Chrono::getMillis() const {
return queryCounter(1000);
}
int64 Chrono::getSeconds() const {
return queryCounter(1);
}
int64 Chrono::queryCounter(int multiplier) const {
if(stopped) {
return multiplier*accumCount/freq;
} else {
Uint32 endCount;
endCount = SDL_GetTicks();
return multiplier*(accumCount+endCount-startCount)/freq;
}
}
// =====================================
// Misc
// =====================================
// This was the simplest, most portable solution i could find in 5 mins for linux
int MessageBox(int handle, const char *msg, const char *title, int buttons) {
char cmd[1024]="";
//sprintf(cmd, "xmessage -center \"%s\"", msg);
sprintf(cmd, "gdialog --title \"%s\" --msgbox \"%s\"", title, msg);
//if(fork()==0){
//close(1); close(2);
int ret = system(cmd);
//exit(0);
//}
}
void findDirs(const vector<string> &paths, vector<string> &results, bool errorOnNotFound) {
results.clear();
int pathCount = paths.size();
for(int idx = 0; idx < pathCount; idx++) {
string path = paths[idx] + "/*.";
vector<string> current_results;
findAll(path, current_results, false, errorOnNotFound);
if(current_results.size() > 0) {
for(int folder_index = 0; folder_index < current_results.size(); folder_index++) {
const string current_folder = current_results[folder_index];
const string current_folder_path = paths[idx] + "/" + current_folder;
//printf("current_folder = [%s]\n",current_folder_path.c_str());
if(isdir(current_folder_path.c_str()) == true) {
//printf("%s is a folder.\n",current_folder_path.c_str());
if(std::find(results.begin(),results.end(),current_folder) == results.end()) {
results.push_back(current_folder);
}
}
}
}
}
std::sort(results.begin(),results.end());
}
void findAll(const vector<string> &paths, const string &fileFilter, vector<string> &results, bool cutExtension, bool errorOnNotFound) {
results.clear();
int pathCount = paths.size();
for(int idx = 0; idx < pathCount; idx++) {
string path = paths[idx] + "/" + fileFilter;
vector<string> current_results;
findAll(path, current_results, cutExtension, errorOnNotFound);
if(current_results.size() > 0) {
for(int folder_index = 0; folder_index < current_results.size(); folder_index++) {
string &current_file = current_results[folder_index];
if(std::find(results.begin(),results.end(),current_file) == results.end()) {
results.push_back(current_file);
}
}
}
}
std::sort(results.begin(),results.end());
}
//finds all filenames like path and stores them in resultys
void findAll(const string &path, vector<string> &results, bool cutExtension, bool errorOnNotFound) {
results.clear();
std::string mypath = path;
/** Stupid win32 is searching for all files without extension when *. is
* specified as wildcard
*/
if(mypath.compare(mypath.size() - 2, 2, "*.") == 0) {
mypath = mypath.substr(0, mypath.size() - 2);
mypath += "*";
}
if(Socket::enableDebugText) printf("In [%s::%s] scanning [%s]\n",__FILE__,__FUNCTION__,mypath.c_str());
glob_t globbuf;
int res = glob(mypath.c_str(), 0, 0, &globbuf);
if(res < 0) {
std::stringstream msg;
msg << "Couldn't scan directory '" << mypath << "': " << strerror(errno);
throw runtime_error(msg.str());
}
for(size_t i = 0; i < globbuf.gl_pathc; ++i) {
const char* p = globbuf.gl_pathv[i];
const char* begin = p;
for( ; *p != 0; ++p) {
// strip the path component
if(*p == '/')
begin = p+1;
}
results.push_back(begin);
}
globfree(&globbuf);
if(results.size() == 0 && errorOnNotFound == true) {
throw runtime_error("No files found in: " + mypath);
}
if(cutExtension) {
for (size_t i=0; i<results.size(); ++i){
results.at(i)=cutLastExt(results.at(i));
}
}
}
bool isdir(const char *path)
{
struct stat stats;
bool ret = stat (path, &stats) == 0 && S_ISDIR (stats.st_mode);
return ret;
}
bool EndsWith(const string &str, const string& key)
{
size_t keylen = key.length();
size_t strlen = str.length();
if(keylen <= strlen)
return string::npos != str.rfind(key.c_str(),strlen - keylen, keylen);
else
return false;
}
//finds all filenames like path and gets their checksum of all files combined
int32 getFolderTreeContentsCheckSumRecursively(const string &path, const string &filterFileExt, Checksum *recursiveChecksum) {
Checksum checksum = (recursiveChecksum == NULL ? Checksum() : *recursiveChecksum);
//if(Socket::enableDebugText) printf("In [%s::%s] scanning [%s]\n",__FILE__,__FUNCTION__,path.c_str());
std::string mypath = path;
/** Stupid win32 is searching for all files without extension when *. is
* specified as wildcard
*/
if(mypath.compare(mypath.size() - 2, 2, "*.") == 0) {
mypath = mypath.substr(0, mypath.size() - 2);
mypath += "*";
}
glob_t globbuf;
int res = glob(mypath.c_str(), 0, 0, &globbuf);
if(res < 0) {
std::stringstream msg;
msg << "Couldn't scan directory '" << mypath << "': " << strerror(errno);
throw runtime_error(msg.str());
}
for(size_t i = 0; i < globbuf.gl_pathc; ++i) {
const char* p = globbuf.gl_pathv[i];
/*
const char* begin = p;
for( ; *p != 0; ++p) {
// strip the path component
if(*p == '/')
begin = p+1;
}
*/
if(isdir(p) == false)
{
bool addFile = true;
if(filterFileExt != "")
{
addFile = EndsWith(p, filterFileExt);
}
if(addFile)
{
//if(Socket::enableDebugText) printf("In [%s::%s] adding file [%s]\n",__FILE__,__FUNCTION__,p);
checksum.addFile(p);
}
}
}
globfree(&globbuf);
// Look recursively for sub-folders
res = glob(mypath.c_str(), GLOB_ONLYDIR, 0, &globbuf);
if(res < 0) {
std::stringstream msg;
msg << "Couldn't scan directory '" << mypath << "': " << strerror(errno);
throw runtime_error(msg.str());
}
for(size_t i = 0; i < globbuf.gl_pathc; ++i) {
const char* p = globbuf.gl_pathv[i];
/*
const char* begin = p;
for( ; *p != 0; ++p) {
// strip the path component
if(*p == '/')
begin = p+1;
}
*/
getFolderTreeContentsCheckSumRecursively(string(p) + "/*", filterFileExt, &checksum);
}
globfree(&globbuf);
return checksum.getSum();
}
//finds all filenames like path and gets the checksum of each file
vector<std::pair<string,int32> > getFolderTreeContentsCheckSumListRecursively(const string &path, const string &filterFileExt, vector<std::pair<string,int32> > *recursiveMap) {
vector<std::pair<string,int32> > checksumFiles = (recursiveMap == NULL ? vector<std::pair<string,int32> >() : *recursiveMap);
//if(Socket::enableDebugText) printf("In [%s::%s] scanning [%s]\n",__FILE__,__FUNCTION__,path.c_str());
std::string mypath = path;
/** Stupid win32 is searching for all files without extension when *. is
* specified as wildcard
*/
if(mypath.compare(mypath.size() - 2, 2, "*.") == 0) {
mypath = mypath.substr(0, mypath.size() - 2);
mypath += "*";
}
glob_t globbuf;
int res = glob(mypath.c_str(), 0, 0, &globbuf);
if(res < 0) {
std::stringstream msg;
msg << "Couldn't scan directory '" << mypath << "': " << strerror(errno);
throw runtime_error(msg.str());
}
for(size_t i = 0; i < globbuf.gl_pathc; ++i) {
const char* p = globbuf.gl_pathv[i];
/*
const char* begin = p;
for( ; *p != 0; ++p) {
// strip the path component
if(*p == '/')
begin = p+1;
}
*/
if(isdir(p) == false)
{
bool addFile = true;
if(filterFileExt != "")
{
addFile = EndsWith(p, filterFileExt);
}
if(addFile)
{
//if(Socket::enableDebugText) printf("In [%s::%s] adding file [%s]\n",__FILE__,__FUNCTION__,p);
Checksum checksum;
checksum.addFile(p);
checksumFiles.push_back(std::pair<string,int32>(p,checksum.getSum()));
}
}
}
globfree(&globbuf);
// Look recursively for sub-folders
res = glob(mypath.c_str(), GLOB_ONLYDIR, 0, &globbuf);
if(res < 0) {
std::stringstream msg;
msg << "Couldn't scan directory '" << mypath << "': " << strerror(errno);
throw runtime_error(msg.str());
}
for(size_t i = 0; i < globbuf.gl_pathc; ++i) {
const char* p = globbuf.gl_pathv[i];
/*
const char* begin = p;
for( ; *p != 0; ++p) {
// strip the path component
if(*p == '/')
begin = p+1;
}
*/
checksumFiles = getFolderTreeContentsCheckSumListRecursively(string(p) + "/*", filterFileExt, &checksumFiles);
}
globfree(&globbuf);
return checksumFiles;
}
string extractDirectoryPathFromFile(string filename)
{
return filename.substr( 0, filename.rfind("/")+1 );
}
void createDirectoryPaths(string Path)
{
char DirName[256]="";
const char *path = Path.c_str();
char *dirName = DirName;
while(*path)
{
//if (('\\' == *path) || ('/' == *path))
if ('/' == *path)
{
//if (':' != *(path-1))
{
mkdir(DirName, S_IRWXO);
}
}
*dirName++ = *path++;
*dirName = '\0';
}
mkdir(DirName, S_IRWXO);
}
bool changeVideoMode(int resW, int resH, int colorBits, int ) {
Private::shouldBeFullscreen = true;
return true;
}
void restoreVideoMode() {
}
void message(string message) {
std::cerr << "******************************************************\n";
std::cerr << " " << message << "\n";
std::cerr << "******************************************************\n";
}
bool ask(string message) {
std::cerr << "Confirmation: " << message << "\n";
int res;
std::cin >> res;
return res != 0;
}
void exceptionMessage(const exception &excp) {
std::cerr << "Exception: " << excp.what() << std::endl;
//int result = MessageBox(NULL, excp.what(), "Error", 0);
}
int getScreenW() {
return SDL_GetVideoSurface()->w;
}
int getScreenH() {
return SDL_GetVideoSurface()->h;
}
void sleep(int millis) {
SDL_Delay(millis);
}
void showCursor(bool b) {
SDL_ShowCursor(b ? SDL_ENABLE : SDL_DISABLE);
}
bool isKeyDown(int virtualKey) {
char key = static_cast<char> (virtualKey);
const Uint8* keystate = SDL_GetKeyState(0);
// kinda hack and wrong...
if(key >= 0) {
return keystate[key];
}
switch(key) {
case vkAdd:
return keystate[SDLK_PLUS] | keystate[SDLK_KP_PLUS];
case vkSubtract:
return keystate[SDLK_MINUS] | keystate[SDLK_KP_MINUS];
case vkAlt:
return keystate[SDLK_LALT] | keystate[SDLK_RALT];
case vkControl:
return keystate[SDLK_LCTRL] | keystate[SDLK_RCTRL];
case vkShift:
return keystate[SDLK_LSHIFT] | keystate[SDLK_RSHIFT];
case vkEscape:
return keystate[SDLK_ESCAPE];
case vkUp:
return keystate[SDLK_UP];
case vkLeft:
return keystate[SDLK_LEFT];
case vkRight:
return keystate[SDLK_RIGHT];
case vkDown:
return keystate[SDLK_DOWN];
case vkReturn:
return keystate[SDLK_RETURN] | keystate[SDLK_KP_ENTER];
case vkBack:
return keystate[SDLK_BACKSPACE];
default:
std::cerr << "isKeyDown called with unknown key.\n";
break;
}
return false;
}
}}//end namespace

View File

@ -0,0 +1,529 @@
// ==============================================================
// This file is part of Glest Shared Library (www.glest.org)
//
// Copyright (C) 2001-2008 Martiño Figueroa
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version
// ==============================================================
#include "platform_util.h"
#include <io.h>
#include <DbgHelp.h>
#include <cassert>
#include "util.h"
#include "conversion.h"
#include "leak_dumper.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <direct.h>
#define S_ISDIR(mode) ((mode) & _S_IFDIR)
using namespace Shared::Util;
using namespace std;
namespace Shared{ namespace Platform{
// =====================================================
// class PerformanceTimer
// =====================================================
void PerformanceTimer::init(int fps, int maxTimes){
int64 freq;
if(QueryPerformanceFrequency((LARGE_INTEGER*) &freq)==0){
throw runtime_error("Performance counters not supported");
}
times= 0;
this->maxTimes= maxTimes;
QueryPerformanceCounter((LARGE_INTEGER*) &lastTicks);
updateTicks= freq/fps;
}
bool PerformanceTimer::isTime(){
QueryPerformanceCounter((LARGE_INTEGER*) &thisTicks);
if((thisTicks-lastTicks)>=updateTicks && times<maxTimes){
lastTicks+= updateTicks;
times++;
return true;
}
times= 0;
return false;
}
void PerformanceTimer::reset(){
QueryPerformanceCounter((LARGE_INTEGER*) &thisTicks);
lastTicks= thisTicks;
}
// =====================================================
// class Chrono
// =====================================================
Chrono::Chrono(){
if(!QueryPerformanceFrequency((LARGE_INTEGER*) &freq)){
throw runtime_error("Performance counters not supported");
}
stopped= true;
accumCount= 0;
}
void Chrono::start(){
stopped= false;
QueryPerformanceCounter((LARGE_INTEGER*) &startCount);
}
void Chrono::stop(){
int64 endCount;
QueryPerformanceCounter((LARGE_INTEGER*) &endCount);
accumCount+= endCount-startCount;
stopped= true;
}
int64 Chrono::getMicros() const{
return queryCounter(1000000);
}
int64 Chrono::getMillis() const{
return queryCounter(1000);
}
int64 Chrono::getSeconds() const{
return queryCounter(1);
}
int64 Chrono::queryCounter(int multiplier) const{
if(stopped){
return multiplier*accumCount/freq;
}
else{
int64 endCount;
QueryPerformanceCounter((LARGE_INTEGER*) &endCount);
return multiplier*(accumCount+endCount-startCount)/freq;
}
}
// =====================================================
// class PlatformExceptionHandler
// =====================================================
PlatformExceptionHandler *PlatformExceptionHandler::thisPointer= NULL;
LONG WINAPI PlatformExceptionHandler::handler(LPEXCEPTION_POINTERS pointers){
HANDLE hFile = CreateFile(
thisPointer->dumpFileName.c_str(),
GENERIC_WRITE,
FILE_SHARE_WRITE,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
0);
MINIDUMP_EXCEPTION_INFORMATION lExceptionInformation;
lExceptionInformation.ThreadId= GetCurrentThreadId();
lExceptionInformation.ExceptionPointers= pointers;
lExceptionInformation.ClientPointers= false;
MiniDumpWriteDump(
GetCurrentProcess(),
GetCurrentProcessId(),
hFile,
MiniDumpNormal,
&lExceptionInformation,
NULL,
NULL );
thisPointer->handle();
return EXCEPTION_EXECUTE_HANDLER;
}
void PlatformExceptionHandler::install(string dumpFileName){
thisPointer= this;
this->dumpFileName= dumpFileName;
SetUnhandledExceptionFilter(handler);
}
// =====================================================
// class Misc
// =====================================================
void findDirs(const vector<string> &paths, vector<string> &results, bool errorOnNotFound) {
results.clear();
int pathCount = paths.size();
for(int idx = 0; idx < pathCount; idx++) {
string path = paths[idx] + "/*.";
vector<string> current_results;
findAll(path, current_results, false, errorOnNotFound);
if(current_results.size() > 0) {
for(int folder_index = 0; folder_index < current_results.size(); folder_index++) {
const string current_folder = current_results[folder_index];
const string current_folder_path = paths[idx] + "/" + current_folder;
//printf("current_folder = [%s]\n",current_folder_path.c_str());
if(isdir(current_folder_path.c_str()) == true) {
//printf("%s is a folder.\n",current_folder_path.c_str());
if(std::find(results.begin(),results.end(),current_folder) == results.end()) {
results.push_back(current_folder);
}
}
}
}
}
std::sort(results.begin(),results.end());
}
void findAll(const vector<string> &paths, const string &fileFilter, vector<string> &results, bool cutExtension, bool errorOnNotFound) {
results.clear();
int pathCount = paths.size();
for(int idx = 0; idx < pathCount; idx++) {
string path = paths[idx] + "/" + fileFilter;
vector<string> current_results;
findAll(path, current_results, cutExtension, errorOnNotFound);
if(current_results.size() > 0) {
for(int folder_index = 0; folder_index < current_results.size(); folder_index++) {
string &current_file = current_results[folder_index];
if(std::find(results.begin(),results.end(),current_file) == results.end()) {
results.push_back(current_file);
}
}
}
}
std::sort(results.begin(),results.end());
}
//finds all filenames like path and stores them in resultys
void findAll(const string &path, vector<string> &results, bool cutExtension, bool errorOnNotFound){
int i= 0;
struct _finddata_t fi;
intptr_t handle;
char *cstr;
results.clear();
cstr= new char[path.length()+1];
strcpy(cstr, path.c_str());
if((handle=_findfirst(cstr,&fi))!=-1){
do{
if(!(strcmp(".", fi.name)==0 || strcmp("..", fi.name)==0)){
i++;
results.push_back(fi.name);
}
}
while(_findnext(handle, &fi)==0);
}
else if(errorOnNotFound == true){
throw runtime_error("Error opening files: "+ path);
}
if(i==0 && errorOnNotFound == true){
throw runtime_error("No files found: "+ path);
}
if(cutExtension){
for (int i=0; i<results.size(); ++i){
results.at(i)=cutLastExt(results.at(i));
}
}
delete [] cstr;
}
bool isdir(const char *path)
{
struct stat stats;
bool ret = stat (path, &stats) == 0 && S_ISDIR (stats.st_mode);
return ret;
}
bool EndsWith(const string &str, const string& key)
{
size_t keylen = key.length();
size_t strlen = str.length();
if(keylen <= strlen)
return string::npos != str.rfind(key.c_str(),strlen - keylen, keylen);
else
return false;
}
//finds all filenames like path and gets their checksum of all files combined
int32 getFolderTreeContentsCheckSumRecursively(const string &path, const string &filterFileExt, Checksum *recursiveChecksum) {
Checksum checksum = (recursiveChecksum == NULL ? Checksum() : *recursiveChecksum);
/* MV - PORT THIS to win32
//if(Socket::enableDebugText) printf("In [%s::%s] scanning [%s]\n",__FILE__,__FUNCTION__,path.c_str());
std::string mypath = path;
// Stupid win32 is searching for all files without extension when *. is specified as wildcard
if(mypath.compare(mypath.size() - 2, 2, "*.") == 0) {
mypath = mypath.substr(0, mypath.size() - 2);
mypath += "*";
}
glob_t globbuf;
int res = glob(mypath.c_str(), 0, 0, &globbuf);
if(res < 0) {
std::stringstream msg;
msg << "Couldn't scan directory '" << mypath << "': " << strerror(errno);
throw runtime_error(msg.str());
}
for(size_t i = 0; i < globbuf.gl_pathc; ++i) {
const char* p = globbuf.gl_pathv[i];
//
//const char* begin = p;
//for( ; *p != 0; ++p) {
// // strip the path component
// if(*p == '/')
// begin = p+1;
//}
if(isdir(p) == false)
{
bool addFile = true;
if(filterFileExt != "")
{
addFile = EndsWith(p, filterFileExt);
}
if(addFile)
{
//if(Socket::enableDebugText) printf("In [%s::%s] adding file [%s]\n",__FILE__,__FUNCTION__,p);
checksum.addFile(p);
}
}
}
globfree(&globbuf);
// Look recursively for sub-folders
res = glob(mypath.c_str(), GLOB_ONLYDIR, 0, &globbuf);
if(res < 0) {
std::stringstream msg;
msg << "Couldn't scan directory '" << mypath << "': " << strerror(errno);
throw runtime_error(msg.str());
}
for(size_t i = 0; i < globbuf.gl_pathc; ++i) {
const char* p = globbuf.gl_pathv[i];
//
//const char* begin = p;
//for( ; *p != 0; ++p) {
// strip the path component
// if(*p == '/')
// begin = p+1;
//}
getFolderTreeContentsCheckSumRecursively(string(p) + "/*", filterFileExt, &checksum);
}
globfree(&globbuf);
*/
return checksum.getSum();
}
//finds all filenames like path and gets the checksum of each file
vector<std::pair<string,int32> > getFolderTreeContentsCheckSumListRecursively(const string &path, const string &filterFileExt, vector<std::pair<string,int32> > *recursiveMap) {
vector<std::pair<string,int32> > checksumFiles = (recursiveMap == NULL ? vector<std::pair<string,int32> >() : *recursiveMap);
/* MV - PORT THIS to win32
//if(Socket::enableDebugText) printf("In [%s::%s] scanning [%s]\n",__FILE__,__FUNCTION__,path.c_str());
std::string mypath = path;
// Stupid win32 is searching for all files without extension when *. is specified as wildcard
if(mypath.compare(mypath.size() - 2, 2, "*.") == 0) {
mypath = mypath.substr(0, mypath.size() - 2);
mypath += "*";
}
glob_t globbuf;
int res = glob(mypath.c_str(), 0, 0, &globbuf);
if(res < 0) {
std::stringstream msg;
msg << "Couldn't scan directory '" << mypath << "': " << strerror(errno);
throw runtime_error(msg.str());
}
for(size_t i = 0; i < globbuf.gl_pathc; ++i) {
const char* p = globbuf.gl_pathv[i];
//
//const char* begin = p;
//for( ; *p != 0; ++p) {
// strip the path component
// if(*p == '/')
// begin = p+1;
//}
if(isdir(p) == false)
{
bool addFile = true;
if(filterFileExt != "")
{
addFile = EndsWith(p, filterFileExt);
}
if(addFile)
{
//if(Socket::enableDebugText) printf("In [%s::%s] adding file [%s]\n",__FILE__,__FUNCTION__,p);
Checksum checksum;
checksum.addFile(p);
checksumFiles.push_back(std::pair<string,int32>(p,checksum.getSum()));
}
}
}
globfree(&globbuf);
// Look recursively for sub-folders
res = glob(mypath.c_str(), GLOB_ONLYDIR, 0, &globbuf);
if(res < 0) {
std::stringstream msg;
msg << "Couldn't scan directory '" << mypath << "': " << strerror(errno);
throw runtime_error(msg.str());
}
for(size_t i = 0; i < globbuf.gl_pathc; ++i) {
const char* p = globbuf.gl_pathv[i];
//
//const char* begin = p;
//for( ; *p != 0; ++p) {
// strip the path component
// if(*p == '/')
// begin = p+1;
//}
checksumFiles = getFolderTreeContentsCheckSumListRecursively(string(p) + "/*", filterFileExt, &checksumFiles);
}
globfree(&globbuf);
*/
return checksumFiles;
}
string extractDirectoryPathFromFile(string filename)
{
return filename.substr( 0, filename.rfind("/")+1 );
}
void createDirectoryPaths(string Path)
{
char DirName[256]="";
const char *path = Path.c_str();
char *dirName = DirName;
while(*path)
{
//if (('\\' == *path) || ('/' == *path))
if ('/' == *path)
{
//if (':' != *(path-1))
{
_mkdir(DirName);
}
}
*dirName++ = *path++;
*dirName = '\0';
}
_mkdir(DirName);
}
bool changeVideoMode(int resW, int resH, int colorBits, int refreshFrequency){
DEVMODE devMode;
for (int i=0; EnumDisplaySettings(NULL, i, &devMode) ;i++){
if (devMode.dmPelsWidth== resW &&
devMode.dmPelsHeight== resH &&
devMode.dmBitsPerPel== colorBits){
devMode.dmDisplayFrequency=refreshFrequency;
LONG result= ChangeDisplaySettings(&devMode, 0);
if(result == DISP_CHANGE_SUCCESSFUL){
return true;
}
else{
return false;
}
}
}
return false;
}
void restoreVideoMode(){
int dispChangeErr= ChangeDisplaySettings(NULL, 0);
assert(dispChangeErr==DISP_CHANGE_SUCCESSFUL);
}
void message(string message){
MessageBox(NULL, message.c_str(), "Message", MB_OK);
}
bool ask(string message){
return MessageBox(NULL, message.c_str(), "Confirmation", MB_YESNO)==IDYES;
}
void exceptionMessage(const exception &excp){
string message, title;
showCursor(true);
message+= "ERROR(S):\n\n";
message+= excp.what();
title= "Error: Unhandled Exception";
printf("Error detected with text: %s\n",message.c_str());
MessageBox(NULL, message.c_str(), title.c_str(), MB_ICONSTOP | MB_OK | MB_TASKMODAL);
}
int getScreenW(){
return GetSystemMetrics(SM_CXSCREEN);
}
int getScreenH(){
return GetSystemMetrics(SM_CYSCREEN);
}
void sleep(int millis){
Sleep(millis);
}
void showCursor(bool b){
ShowCursor(b);
}
bool isKeyDown(int virtualKey){
return (GetKeyState(virtualKey) & 0x8000) != 0;
}
}}//end namespace

View File

@ -137,6 +137,7 @@ const string Properties::getString(const string &key, const char *defaultValueIf
it= propertyMap.find(key);
if(it==propertyMap.end()){
if(defaultValueIfNotFound != NULL) {
//printf("In [%s::%s - %d]defaultValueIfNotFound = [%s]\n",__FILE__,__FUNCTION__,__LINE__,defaultValueIfNotFound);
return string(defaultValueIfNotFound);
}
else {
@ -144,7 +145,7 @@ const string Properties::getString(const string &key, const char *defaultValueIf
}
}
else{
return it->second;
return (it->second != "" ? it->second : (defaultValueIfNotFound != NULL ? defaultValueIfNotFound : it->second));
}
}
@ -209,6 +210,7 @@ const string Properties::getString(const char *key, const char *defaultValueIfNo
it= propertyMap.find(key);
if(it==propertyMap.end()){
if(defaultValueIfNotFound != NULL) {
//printf("In [%s::%s - %d]defaultValueIfNotFound = [%s]\n",__FILE__,__FUNCTION__,__LINE__,defaultValueIfNotFound);
return string(defaultValueIfNotFound);
}
else {
@ -216,7 +218,7 @@ const string Properties::getString(const char *key, const char *defaultValueIfNo
}
}
else{
return it->second;
return (it->second != "" ? it->second : (defaultValueIfNotFound != NULL ? defaultValueIfNotFound : it->second));
}
}