diff --git a/source/glest_game/ai/ai_interface.cpp b/source/glest_game/ai/ai_interface.cpp index 9770c03c..99a79c94 100644 --- a/source/glest_game/ai/ai_interface.cpp +++ b/source/glest_game/ai/ai_interface.cpp @@ -97,7 +97,7 @@ CommandResult AiInterface::giveCommand(int unitIndex, const CommandType *command } CommandResult AiInterface::giveCommand(int unitIndex, const CommandType *commandType, const Vec2i &pos, const UnitType *ut){ - return world->getFaction(factionIndex)->getUnit(unitIndex)->giveCommand(new Command(commandType, pos, ut)); + return world->getFaction(factionIndex)->getUnit(unitIndex)->giveCommand(new Command(commandType, pos, ut, CardinalDir::NORTH)); } CommandResult AiInterface::giveCommand(int unitIndex, const CommandType *commandType, Unit *u){ diff --git a/source/glest_game/game/commander.cpp b/source/glest_game/game/commander.cpp index 62f005c3..a5ceb5c8 100644 --- a/source/glest_game/game/commander.cpp +++ b/source/glest_game/game/commander.cpp @@ -40,8 +40,8 @@ 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(this->world,nctGiveCommand, unit->getId(), commandType->getId(), pos, unitType->getId()); +CommandResult Commander::tryGiveCommand(const Unit* unit, const CommandType *commandType, const Vec2i &pos, const UnitType* unitType, CardinalDir facing) const{ + NetworkCommand networkCommand(this->world,nctGiveCommand, unit->getId(), commandType->getId(), pos, unitType->getId(), facing); return pushNetworkCommand(&networkCommand); } @@ -362,15 +362,19 @@ Command* Commander::buildCommand(const NetworkCommand* networkCommand) const{ throw runtime_error(szBuf); } - //get target, the target might be dead due to lag, cope with it - if(networkCommand->getTargetId()!=Unit::invalidId){ + CardinalDir facing; + // get facing/target ... the target might be dead due to lag, cope with it + if (ct->getClass() == ccBuild) { + assert(networkCommand->getTargetId() >= 0 && networkCommand->getTargetId() < 4); + facing = CardinalDir(networkCommand->getTargetId()); + } else 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); + command= new Command(ct, networkCommand->getPosition(), unitType, facing); } else if(target==NULL){ command= new Command(ct, networkCommand->getPosition()); diff --git a/source/glest_game/game/commander.h b/source/glest_game/game/commander.h index 07029fda..e7eb66ee 100644 --- a/source/glest_game/game/commander.h +++ b/source/glest_game/game/commander.h @@ -47,7 +47,7 @@ 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 Unit* unit, const CommandType *commandType, const Vec2i &pos, const UnitType* unitType, CardinalDir facing) 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; diff --git a/source/glest_game/game/game_constants.h b/source/glest_game/game/game_constants.h index 04e00f2b..28d37507 100644 --- a/source/glest_game/game/game_constants.h +++ b/source/glest_game/game/game_constants.h @@ -1,6 +1,8 @@ #ifndef _GLEST_GAME_GAMECONSTANTS_H_ #define _GLEST_GAME_GAMECONSTANTS_H_ +#include + // ============================================================== // This file is part of Glest (www.glest.org) // @@ -52,7 +54,28 @@ enum PathType { ptTutorials }; +struct CardinalDir { +public: + enum Enum { NORTH, EAST, SOUTH, WEST }; + CardinalDir() : value(NORTH) {} + CardinalDir(Enum v) : value(v) {} + explicit CardinalDir(int v) { + assert(v >= 0 && v < 4); + value = static_cast(v); + } + operator Enum() { return value; } + + void operator++() { + value = static_cast(value + 1 % 4); + } + void operator--() { // mod with negative numbers is a 'grey area', hence the +3 rather than -1 + value = static_cast(value + 3 % 4); + } + +private: + Enum value; +}; }}//end namespace diff --git a/source/glest_game/graphics/renderer.cpp b/source/glest_game/graphics/renderer.cpp index 891b38e6..4e7279fd 100644 --- a/source/glest_game/graphics/renderer.cpp +++ b/source/glest_game/graphics/renderer.cpp @@ -565,18 +565,13 @@ void Renderer::renderMouse3d(){ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color.ptr()); const Model *buildingModel= building->getFirstStOfClass(scStop)->getAnimation(); - //!!! - if(allowRotateUnits == true) { - int factionIndex = game->getWorld()->getThisFactionIndex(); - char unitKey[50]=""; - sprintf(unitKey,"%d_%d",building->getId(),factionIndex); - - float rotateAmount = gui->getUnitTypeBuildRotation(unitKey); - if(rotateAmount > 0) { - //if(Socket::enableDebugText) printf("In [%s::%s] rotate unit id = %d amount = %f\n",__FILE__,__FUNCTION__,building->getId(),rotateAmount); - glRotatef(rotateAmount, 0.f, 1.f, 0.f); - } - } + if(allowRotateUnits == true) { + float rotateAmount = gui->getSelectedFacing() * 90.f; + if(rotateAmount > 0) { + //if(Socket::enableDebugText) printf("In [%s::%s] rotate unit id = %d amount = %f\n",__FILE__,__FUNCTION__,building->getId(),rotateAmount); + glRotatef(rotateAmount, 0.f, 1.f, 0.f); + } + } buildingModel->updateInterpolationData(0.f, false); modelRenderer->render(buildingModel); glDisable(GL_COLOR_MATERIAL); @@ -1368,14 +1363,6 @@ void Renderer::renderUnits(){ const Model *model= unit->getCurrentModel(); model->updateInterpolationData(unit->getAnimProgress(), unit->isAlive()); - //!!! - if(allowRotateUnits == true) { - float rotateAmount = unit->getRotateAmount(); - 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); - } - } modelRenderer->render(model); triangleCount+= model->getTriangleCount(); pointCount+= model->getVertexCount(); @@ -2354,15 +2341,6 @@ void Renderer::renderUnitsFast(){ //render const Model *model= unit->getCurrentModel(); model->updateInterpolationVertices(unit->getAnimProgress(), unit->isAlive()); - - //!!! - if(allowRotateUnits == true) { - float rotateAmount = unit->getRotateAmount(); - 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); - } - } modelRenderer->render(model); glPopMatrix(); diff --git a/source/glest_game/gui/gui.cpp b/source/glest_game/gui/gui.cpp index fb399179..eb466114 100644 --- a/source/glest_game/gui/gui.cpp +++ b/source/glest_game/gui/gui.cpp @@ -102,6 +102,7 @@ Gui::Gui(){ activeCommandType= NULL; activeCommandClass= ccStop; selectingBuilding= false; + selectedBuildingFacing = CardinalDir::NORTH; selectingPos= false; selectingMeetingPoint= false; activePos= invalidPos; @@ -149,6 +150,7 @@ void Gui::setComputeSelectionFlag(){ void Gui::resetState(){ selectingBuilding= false; + selectedBuildingFacing = CardinalDir::NORTH; selectingPos= false; selectingMeetingPoint= false; activePos= invalidPos; @@ -315,20 +317,6 @@ void Gui::groupKey(int groupIndex){ } } -void Gui::setUnitTypeBuildRotation(string unitKey, float value) { - unitTypeBuildRotation[unitKey] = value; -} - -float Gui::getUnitTypeBuildRotation(string unitKey) const { - float rotationValue = -1; - - if(unitTypeBuildRotation.find(unitKey) != unitTypeBuildRotation.end()) { - rotationValue = unitTypeBuildRotation.find(unitKey)->second; - } - - return rotationValue; -} - void Gui::hotKey(char key){ //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] key = [%c]\n",__FILE__,__FUNCTION__,key); @@ -345,40 +333,7 @@ void Gui::hotKey(char key){ 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(); - char unitKey[50]=""; - sprintf(unitKey,"%d_%d",unitType->getId(),factionIndex); - float unitTypeRotation = getUnitTypeBuildRotation(unitKey); - - SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] factionIndex = %d unitType->getId() = %d unitTypeRotation = %f\n",__FILE__,__FUNCTION__,factionIndex,unitType->getId(),unitTypeRotation); - - if(unitTypeRotation < 0) { - unitTypeRotation = 0; - } - unitTypeRotation += 90; - if(unitTypeRotation >= 360) { - unitTypeRotation = 0; - } - unitTypeBuildRotation[unitKey] = unitTypeRotation; - - //!!! - /* - //if(allowRotateUnits == true && unitRotation > 0) { - SystemFlags::OutputDebug(SystemFlags::debugSystem,"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); - - //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] after sending nctNetworkCommand RotateUnit [%d] result = %d\n",__FILE__,__FUNCTION__,builtUnit->getId(),result); - SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] after sending nctNetworkCommand RotateUnit unitTypeid = %d, factionIndex = %d, unitTypeRotation = %f\n",__FILE__,__FUNCTION__,unitType->getId(),factionIndex,unitTypeRotation); - //} - */ - - SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] unitType->getId() = %d NEW unitTypeRotation = %f\n",__FILE__,__FUNCTION__,unitType->getId(),unitTypeRotation); + ++selectedBuildingFacing; } else { selectInterestingUnit(iutProducer); @@ -474,7 +429,8 @@ void Gui::giveTwoClickOrders(int x, int y){ } else{ //selecting building - result= commander->tryGiveCommand( selection.getFrontUnit(), activeCommandType, posObjWorld, choosenBuildingType ); + result= commander->tryGiveCommand(selection.getFrontUnit(), + activeCommandType, posObjWorld, choosenBuildingType, selectedBuildingFacing ); } //graphical result @@ -623,7 +579,8 @@ void Gui::mouseDownDisplayUnitBuild(int posDisplay){ if(world->getFaction(factionIndex)->reqsOk(ut)){ choosenBuildingType= ut; assert(choosenBuildingType!=NULL); - selectingPos= true;; + selectingPos= true; + selectedBuildingFacing = CardinalDir::NORTH; activePos= posDisplay; } } diff --git a/source/glest_game/gui/gui.h b/source/glest_game/gui/gui.h index 909397e3..373b8d87 100644 --- a/source/glest_game/gui/gui.h +++ b/source/glest_game/gui/gui.h @@ -130,8 +130,8 @@ private: bool selectingPos; bool selectingMeetingPoint; + CardinalDir selectedBuildingFacing; bool allowRotateUnits; - std::map unitTypeBuildRotation; public: Gui(); @@ -146,6 +146,7 @@ public: const Display *getDisplay() const {return &display;} const Selection *getSelection() const {return &selection;} const SelectionQuad *getSelectionQuad() const {return &selectionQuad;} + CardinalDir getSelectedFacing() const {return selectedBuildingFacing;} bool isSelected(const Unit *unit) const {return selection.hasUnit(unit);} bool isValidPosObjWorld() const {return validPosObjWorld;} @@ -175,9 +176,6 @@ public: //misc void onSelectionChanged(); - float getUnitTypeBuildRotation(string unitKey) const; - void setUnitTypeBuildRotation(string unitKey, float value); - private: //orders diff --git a/source/glest_game/menu/menu_state_custom_game.cpp b/source/glest_game/menu/menu_state_custom_game.cpp index f0cc83da..140ca978 100644 --- a/source/glest_game/menu/menu_state_custom_game.cpp +++ b/source/glest_game/menu/menu_state_custom_game.cpp @@ -55,24 +55,26 @@ MenuStateCustomGame::MenuStateCustomGame(Program *program, MainMenu *mainMenu, b findAll(config.getPathListForType(ptMaps), "*.gbm", glestMaps, true, false); findAll(config.getPathListForType(ptMaps), "*.mgm", megaMaps, true, false); - mapFiles.resize(glestMaps.size() + megaMaps.size()); + // put them all in a set, to weed out duplicates (gbm & mgm with same name) + // will also ensure they are alphabetically listed (rather than how the OS provides them) + set allMaps; if (!glestMaps.empty()) { - copy(glestMaps.begin(), glestMaps.end(), mapFiles.begin()); + copy(glestMaps.begin(), glestMaps.end(), std::inserter(allMaps, allMaps.begin())); } if (!megaMaps.empty()) { - copy(megaMaps.begin(), megaMaps.end(), mapFiles.begin() + glestMaps.size()); + copy(megaMaps.begin(), megaMaps.end(), std::inserter(allMaps, allMaps.begin())); } - if(mapFiles.size()==0){ + if(allMaps.size()==0){ throw runtime_error("There are no maps"); } - vector results; - for(int i= 0; i < mapFiles.size(); ++i){ - results.push_back(formatString(mapFiles[i])); - } - listBoxMap.init(200, 260, 150); - listBoxMap.setItems(results); + std::copy(allMaps.begin(), allMaps.end(), std::back_inserter(mapFiles)); + + listBoxMap.init(200, 260, 150); + listBoxMap.setItems(mapFiles); labelMap.init(200, 290); labelMapInfo.init(200, 230, 200, 40); + + vector results; //tileset listBox findDirs(config.getPathListForType(ptTilesets), results); diff --git a/source/glest_game/network/network_types.cpp b/source/glest_game/network/network_types.cpp index 902213cd..c19e07be 100644 --- a/source/glest_game/network/network_types.cpp +++ b/source/glest_game/network/network_types.cpp @@ -27,14 +27,15 @@ namespace Glest{ namespace Game{ // class NetworkCommand // ===================================================== -NetworkCommand::NetworkCommand(World *world, 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(World *world, int networkCommandType, int unitId, int commandTypeId, const Vec2i &pos, int unitTypeId, int targetId, int facing) + : networkCommandType(networkCommandType) + , unitId(unitId) + , commandTypeId(commandTypeId) + , positionX(pos.x) + , positionY(pos.y) + , unitTypeId(unitTypeId) { + assert(targetId == -1 || facing == -1); + this->targetId = targetId >= 0 ? targetId : facing; if(this->networkCommandType == nctGiveCommand) { const Unit *unit= world->findUnitById(this->unitId); @@ -45,19 +46,7 @@ NetworkCommand::NetworkCommand(World *world, int networkCommandType, int unitId, const CommandType *ct = unit->getType()->findCommandTypeById(this->commandTypeId); if(ct != NULL && ct->getClass() == ccBuild) { SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] %s\n",__FILE__,__FUNCTION__,__LINE__,toString().c_str()); - - Game *game = world->getGame(); - Gui *gui = game->getGui(); - - int factionIndex = world->getThisFactionIndex(); - char unitKey[50]=""; - sprintf(unitKey,"%d_%d",this->unitTypeId,factionIndex); - float unitTypeRotation = gui->getUnitTypeBuildRotation(unitKey); - - if(unitTypeRotation >= 0) { - SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] attaching RotateUnit to ccBuild command for unitTypeid = %d, factionIndex = %d, unitTypeRotation = %f\n",__FILE__,__FUNCTION__,this->unitTypeId,factionIndex,unitTypeRotation); - this->targetId = unitTypeRotation; - } + assert(facing >= 0 && facing < 4 && targetId == -1); } } } @@ -72,17 +61,7 @@ void NetworkCommand::preprocessNetworkCommand(World *world) { const UnitType *unitType= world->findUnitTypeById(unit->getFaction()->getType(), unitTypeId); const CommandType *ct = unit->getType()->findCommandTypeById(commandTypeId); if(ct != NULL && ct->getClass() == ccBuild && targetId >= 0) { - Game *game = world->getGame(); - Gui *gui = game->getGui(); - - int factionIndex = unit->getFactionIndex(); - char unitKey[50]=""; - sprintf(unitKey,"%d_%d",unitTypeId,factionIndex); - gui->setUnitTypeBuildRotation(unitKey,targetId); - - SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] %s, unitKey = [%s] targetId = %d\n",__FILE__,__FUNCTION__,__LINE__,toString().c_str(),unitKey,targetId); - - targetId = Unit::invalidId; + assert(targetId < 4); } } else { diff --git a/source/glest_game/network/network_types.h b/source/glest_game/network/network_types.h index 803b0e78..adcb493f 100644 --- a/source/glest_game/network/network_types.h +++ b/source/glest_game/network/network_types.h @@ -70,7 +70,16 @@ private: public: NetworkCommand(){}; - NetworkCommand(World *world, int networkCommandType, int unitId, int commandTypeId= -1, const Vec2i &pos= Vec2i(0), int unitTypeId= -1, int targetId= -1); + NetworkCommand( + World *world, + int networkCommandType, + int unitId, + int commandTypeId= -1, + const Vec2i &pos= Vec2i(0), + int unitTypeId= -1, + int targetId= -1, + int facing= -1); + //NetworkCommand(int networkCommandType, NetworkCommandSubType ncstType, int unitId, int value1, int value2=-1); NetworkCommandType getNetworkCommandType() const {return static_cast(networkCommandType);} diff --git a/source/glest_game/type_instances/command.cpp b/source/glest_game/type_instances/command.cpp new file mode 100644 index 00000000..fe467bd9 --- /dev/null +++ b/source/glest_game/type_instances/command.cpp @@ -0,0 +1,61 @@ +// ============================================================== +// 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.h" + +#include "command_type.h" +#include "leak_dumper.h" + +namespace Glest{ namespace Game{ + +// ===================================================== +// class Command +// ===================================================== + +Command::Command(const CommandType *ct, const Vec2i &pos){ + this->commandType= ct; + this->pos= pos; + unitType= NULL; +} + +Command::Command(const CommandType *ct, Unit* unit){ + this->commandType= ct; + this->pos= Vec2i(0); + this->unitRef= unit; + unitType= NULL; + if(unit!=NULL){ + unit->resetHighlight(); + pos= unit->getCellPos(); + } +} + +Command::Command(const CommandType *ct, const Vec2i &pos, const UnitType *unitType, CardinalDir facing){ + this->commandType= ct; + this->pos= pos; + this->unitType= unitType; + this->facing = facing; +} + +// =============== set =============== + +void Command::setCommandType(const CommandType *commandType){ + this->commandType= commandType; +} + +void Command::setPos(const Vec2i &pos){ + this->pos= pos; +} + +void Command::setUnit(Unit *unit){ + this->unitRef= unit; +} + +}}//end namespace diff --git a/source/glest_game/type_instances/command.h b/source/glest_game/type_instances/command.h new file mode 100644 index 00000000..d06b6534 --- /dev/null +++ b/source/glest_game/type_instances/command.h @@ -0,0 +1,62 @@ +// ============================================================== +// 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_COMMAND_H_ +#define _GLEST_GAME_COMMAND_H_ + +#include + +#include "unit.h" +#include "vec.h" +#include "game_constants.h" + +namespace Glest{ namespace Game{ + +using Shared::Graphics::Vec2i; + +class CommandType; + +// ===================================================== +// class Command +// +/// A unit command +// ===================================================== + +class Command{ +private: + const CommandType *commandType; + Vec2i pos; + UnitReference unitRef; //target unit, used to move and attack optinally + CardinalDir facing; // facing, for build command + const UnitType *unitType; //used for build + +public: + //constructor + Command(const CommandType *ct, const Vec2i &pos=Vec2i(0)); + Command(const CommandType *ct, Unit *unit); + Command(const CommandType *ct, const Vec2i &pos, const UnitType *unitType, CardinalDir facing); + + //get + const CommandType *getCommandType() const {return commandType;} + Vec2i getPos() const {return pos;} + Unit* getUnit() const {return unitRef.getUnit();} + const UnitType* getUnitType() const {return unitType;} + CardinalDir getFacing() const {return facing;} + + //set + void setCommandType(const CommandType *commandType); + void setPos(const Vec2i &pos); + void setUnit(Unit *unit); +}; + +}}//end namespace + +#endif diff --git a/source/glest_game/type_instances/unit.cpp b/source/glest_game/type_instances/unit.cpp index 214cb607..e5c5b743 100644 --- a/source/glest_game/type_instances/unit.cpp +++ b/source/glest_game/type_instances/unit.cpp @@ -104,11 +104,11 @@ const int Unit::invalidId= -1; // ============================ Constructor & destructor ============================= -Unit::Unit(int id, const Vec2i &pos, const UnitType *type, Faction *faction, Map *map, float unitPlacementRotation) { +Unit::Unit(int id, const Vec2i &pos, const UnitType *type, Faction *faction, Map *map, CardinalDir placeFacing) { SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] START\n",__FILE__,__FUNCTION__); allowRotateUnits = Config::getInstance().getBool("AllowRotateUnits","0"); - rotateAmount= -1; + modelFacing = CardinalDir::NORTH; Random random; @@ -118,11 +118,8 @@ Unit::Unit(int id, const Vec2i &pos, const UnitType *type, Faction *faction, Map this->map= map; this->id= id; level= NULL; - cellMap= NULL; - //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] A\n",__FILE__,__FUNCTION__); - setRotateAmount(unitPlacementRotation); - //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] B unit id = %d [%s] rotate amount = %f\n",__FILE__,__FUNCTION__,getId(), getFullName().c_str(),unitPlacementRotation); + setModelFacing(placeFacing); Config &config= Config::getInstance(); showUnitParticles= config.getBool("UnitParticles"); @@ -143,14 +140,15 @@ Unit::Unit(int id, const Vec2i &pos, const UnitType *type, Faction *faction, Map meetingPos= pos; alive= true; - float rot= 0.f; - - random.init(id); - rot+= random.randRange(-5, 5); - - rotation= rot; - lastRotation= rot; - targetRotation= rot; + if (!type->hasSkillClass(scBeBuilt)) { + float rot= 0.f; + random.init(id); + rot+= random.randRange(-5, 5); + rotation= rot; + lastRotation= rot; + targetRotation= rot; + } + // else it was set appropriately in setModelFacing() if(getType()->getField(fAir)) currField=fAir; if(getType()->getField(fLand)) currField=fLand; @@ -173,13 +171,15 @@ Unit::~Unit(){ } // fade(and by this remove) all unit particle systems while(!unitParticleSystems.empty()){ - unitParticleSystems.back()->fade(); - unitParticleSystems.pop_back(); - } + unitParticleSystems.back()->fade(); + unitParticleSystems.pop_back(); + } stopDamageParticles(); +} - if(cellMap == NULL) delete [] cellMap; - cellMap = NULL; +void Unit::setModelFacing(CardinalDir value) { + modelFacing = value; + lastRotation = targetRotation = rotation = value * 90.f; } // ====================================== get ====================================== @@ -210,7 +210,7 @@ Vec2i Unit::getCellPos() const{ for(int i=0; igetSize(); ++i){ for(int j=0; jgetSize(); ++j){ - if(getCellMapCell(i, j)){ + if(type->getCellMapCell(i, j, modelFacing)){ Vec2i currPos= pos + Vec2i(i, j); float dist= currPos.dist(centeredPos); if(nearestDist==-1.f || distsetPos(getCurrVector()); } for(UnitParticleSystems::iterator it= unitParticleSystems.begin(); it!=unitParticleSystems.end(); ++it){ @@ -1116,7 +1115,7 @@ void Unit::startDamageParticles(){ } } - +#if 0 bool Unit::getCellMapCell(int x, int y) const { const UnitType *ut= getType(); @@ -1194,5 +1193,5 @@ void Unit::setRotateAmount(float value) { SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] unit id = %d rotate amount = %f\n",__FILE__,__FUNCTION__,__LINE__, getId(),rotateAmount); } } - +#endif }}//end namespace diff --git a/source/glest_game/type_instances/unit.h b/source/glest_game/type_instances/unit.h index 0e53c37a..e9dbc472 100644 --- a/source/glest_game/type_instances/unit.h +++ b/source/glest_game/type_instances/unit.h @@ -16,6 +16,7 @@ #include "upgrade_type.h" #include "particle.h" #include "skill_type.h" +#include "game_constants.h" namespace Glest{ namespace Game{ @@ -181,11 +182,10 @@ private: UnitParticleSystems damageParticleSystems; bool allowRotateUnits; - float rotateAmount; - bool *cellMap; + CardinalDir modelFacing; public: - Unit(int id, const Vec2i &pos, const UnitType *type, Faction *faction, Map *map, float unitPlacementRotation); + Unit(int id, const Vec2i &pos, const UnitType *type, Faction *faction, Map *map, CardinalDir placeFacing); ~Unit(); //queries @@ -298,10 +298,9 @@ public: CommandResult checkCommand(Command *command) const; void applyCommand(Command *command); - void setRotateAmount(float value); - float getRotateAmount() { return rotateAmount; } - bool getCellMapCell(int x, int y) const; - + void setModelFacing(CardinalDir value); + CardinalDir getModelFacing() { return modelFacing; } + private: float computeHeight(const Vec2i &pos) const; void updateTarget(); diff --git a/source/glest_game/types/unit_type.cpp b/source/glest_game/types/unit_type.cpp index d2f9f382..1c3c504c 100644 --- a/source/glest_game/types/unit_type.cpp +++ b/source/glest_game/types/unit_type.cpp @@ -411,6 +411,30 @@ const RepairCommandType *UnitType::getFirstRepairCommand(const UnitType *repaire return NULL; } +bool UnitType::getCellMapCell(int x, int y, CardinalDir facing) const { + assert(cellMap); + int tmp; + switch (facing) { + case CardinalDir::EAST: + tmp = y; + y = x; + x = size - tmp - 1; + break; + case CardinalDir::SOUTH: + x = size - x - 1; + y = size - y - 1; + break; + case CardinalDir::WEST: + tmp = x; + x = y; + y = size - tmp - 1; + break; + default: + break; + } + return cellMap[y * size + x]; +} + int UnitType::getStore(const ResourceType *rt) const{ for(int i=0; i DamageParticleSystemTypes; + +class UnitType: public ProducibleType{ +public: + enum Property{ + pBurnable, + pRotatedClimb, + + pCount + }; + + static const char *propertyNames[]; + DamageParticleSystemTypes damageParticleSystemTypes; +private: + typedef vector SkillTypes; + typedef vector CommandTypes; + typedef vector StoredResources; + typedef vector Levels; + +private: + //basic + int id; + int maxHp; + int hpRegeneration; + int maxEp; + int epRegeneration; + bool fields[fieldCount]; //fields: land, sea or air + bool properties[pCount]; //properties + int armor; //armor + const ArmorType *armorType; + bool light; + Vec3f lightColor; + bool multiSelect; + int sight; + int size; //size in cells + int height; + float rotatedBuildPos; + + //cellmap + bool *cellMap; + + //sounds + SoundContainer selectionSounds; + SoundContainer commandSounds; + + //info + SkillTypes skillTypes; + CommandTypes commandTypes; + StoredResources storedResources; + Levels levels; + + //meeting point + bool meetingPoint; + Texture2D *meetingPointImage; + + //OPTIMIZATION: store first command type and skill type of each class + const CommandType *firstCommandTypeOfClass[ccCount]; + const SkillType *firstSkillTypeOfClass[scCount]; + +public: + //creation and loading + UnitType(); + virtual ~UnitType(); + void preLoad(const string &dir); + void load(int id, const string &dir, const TechTree *techTree, const FactionType *factionType, Checksum* checksum); + + //get + int getId() const {return id;} + int getMaxHp() const {return maxHp;} + int getHpRegeneration() const {return hpRegeneration;} + int getMaxEp() const {return maxEp;} + int getEpRegeneration() const {return epRegeneration;} + bool getField(Field field) const {return fields[field];} + bool getProperty(Property property) const {return properties[property];} + int getArmor() const {return armor;} + const ArmorType *getArmorType() const {return armorType;} + const SkillType *getSkillType(int i) const {return skillTypes[i];} + const CommandType *getCommandType(int i) const {return commandTypes[i];} + const Level *getLevel(int i) const {return &levels[i];} + int getSkillTypeCount() const {return skillTypes.size();} + int getCommandTypeCount() const {return commandTypes.size();} + int getLevelCount() const {return levels.size();} + bool getLight() const {return light;} + Vec3f getLightColor() const {return lightColor;} + bool getMultiSelect() const {return multiSelect;} + int getSight() const {return sight;} + int getSize() const {return size;} + int getHeight() const {return height;} + int getStoredResourceCount() const {return storedResources.size();} + const Resource *getStoredResource(int i) const {return &storedResources[i];} + bool getCellMapCell(int x, int y, CardinalDir facing) const; + bool getMeetingPoint() const {return meetingPoint;} + Texture2D *getMeetingPointImage() const {return meetingPointImage;} + StaticSound *getSelectionSound() const {return selectionSounds.getRandSound();} + StaticSound *getCommandSound() const {return commandSounds.getRandSound();} + + int getStore(const ResourceType *rt) const; + const SkillType *getSkillType(const string &skillName, SkillClass skillClass) const; + const SkillType *getFirstStOfClass(SkillClass skillClass) const; + const CommandType *getFirstCtOfClass(CommandClass commandClass) const; + const HarvestCommandType *getFirstHarvestCommand(const ResourceType *resourceType) const; + const AttackCommandType *getFirstAttackCommand(Field field) const; + const RepairCommandType *getFirstRepairCommand(const UnitType *repaired) const; + + //get totals + int getTotalMaxHp(const TotalUpgrade *totalUpgrade) const; + int getTotalMaxEp(const TotalUpgrade *totalUpgrade) const; + int getTotalArmor(const TotalUpgrade *totalUpgrade) const; + int getTotalSight(const TotalUpgrade *totalUpgrade) const; + + //has + bool hasCommandType(const CommandType *commandType) const; + bool hasCommandClass(CommandClass commandClass) const; + bool hasSkillType(const SkillType *skillType) const; + bool hasSkillClass(SkillClass skillClass) const; + bool hasCellMap() const {return cellMap!=NULL;} + + //is + bool isOfClass(UnitClass uc) const; + + //find + const CommandType* findCommandTypeById(int id) const; + + float getRotatedBuildPos() { return rotatedBuildPos; } + float setRotatedBuildPos(float value) { rotatedBuildPos = value; } + +private: + void computeFirstStOfClass(); + void computeFirstCtOfClass(); +}; + +}}//end namespace + + +#endif diff --git a/source/glest_game/world/map.cpp b/source/glest_game/world/map.cpp index d8d72546..f7a8c20e 100644 --- a/source/glest_game/world/map.cpp +++ b/source/glest_game/world/map.cpp @@ -416,11 +416,10 @@ void Map::putUnitCells(Unit *unit, const Vec2i &pos){ for(int j=0; jgetSize(); ++j){ Vec2i currPos= pos + Vec2i(i, j); assert(isInside(currPos)); - if(!ut->hasCellMap() || unit->getCellMapCell(i, j)){ + if(!ut->hasCellMap() || ut->getCellMapCell(i, j, unit->getModelFacing())){ assert(getCell(currPos)->getUnit(unit->getCurrField())==NULL); getCell(currPos)->setUnit(unit->getCurrField(), unit); } - } } unit->setPos(pos); @@ -436,7 +435,7 @@ void Map::clearUnitCells(Unit *unit, const Vec2i &pos){ for(int j=0; jgetSize(); ++j){ Vec2i currPos= pos + Vec2i(i, j); assert(isInside(currPos)); - if(!ut->hasCellMap() || unit->getCellMapCell(i, j)){ + if(!ut->hasCellMap() || ut->getCellMapCell(i, j, unit->getModelFacing())){ assert(getCell(currPos)->getUnit(unit->getCurrField())==unit); getCell(currPos)->setUnit(unit->getCurrField(), NULL); } diff --git a/source/glest_game/world/unit_updater.cpp b/source/glest_game/world/unit_updater.cpp index dccfb753..f0995141 100644 --- a/source/glest_game/world/unit_updater.cpp +++ b/source/glest_game/world/unit_updater.cpp @@ -291,19 +291,8 @@ void UnitUpdater::updateBuild(Unit *unit){ assert(command->getUnitType()!=NULL); if(map->isFreeCells(command->getPos(), ut->getSize(), fLand)){ const UnitType *builtUnitType= command->getUnitType(); - - //!!! - float unitRotation = -1; - if(allowRotateUnits == true) { - SystemFlags::OutputDebug(SystemFlags::debugSystem,"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); - - SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] unitKey = [%s] unitRotation = %f\n",__FILE__,__FUNCTION__,__LINE__,unitKey,unitRotation); - } - Unit *builtUnit= new Unit(world->getNextUnitId(), command->getPos(), builtUnitType, unit->getFaction(), world->getMap(),unitRotation); + CardinalDir facing = command->getFacing(); + Unit *builtUnit= new Unit(world->getNextUnitId(), command->getPos(), builtUnitType, unit->getFaction(), world->getMap(), facing); builtUnit->create(); if(!builtUnitType->hasSkillClass(scBeBuilt)){ @@ -554,18 +543,7 @@ void UnitUpdater::updateProduce(Unit *unit){ if(unit->getProgress2()>pct->getProduced()->getProductionTime()){ unit->finishCommand(); unit->setCurrSkill(scStop); - - //!!! - float unitRotation = -1; - if(allowRotateUnits == true) { - char unitKey[50]=""; - sprintf(unitKey,"%d_%d",pct->getProducedUnit()->getId(),unit->getFaction()->getIndex()); - unitRotation = gui->getUnitTypeBuildRotation(unitKey); - - SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] unitKey = [%s] unitRotation = %f\n",__FILE__,__FUNCTION__,__LINE__,unitKey,unitRotation); - } - - produced= new Unit(world->getNextUnitId(), Vec2i(0), pct->getProducedUnit(), unit->getFaction(), world->getMap(),unitRotation); + produced= new Unit(world->getNextUnitId(), Vec2i(0), pct->getProducedUnit(), unit->getFaction(), world->getMap(), CardinalDir::NORTH); //place unit creates the unit if(!world->placeUnit(unit->getCenteredPos(), 10, produced)){ diff --git a/source/glest_game/world/world.cpp b/source/glest_game/world/world.cpp index f048c081..735df5f2 100644 --- a/source/glest_game/world/world.cpp +++ b/source/glest_game/world/world.cpp @@ -318,15 +318,7 @@ void World::createUnit(const string &unitName, int factionIndex, const Vec2i &po const FactionType* ft= faction->getType(); const UnitType* ut= ft->getUnitType(unitName); - //!!! - float unitRotation = -1; - if(allowRotateUnits == true) { - char unitKey[50]=""; - sprintf(unitKey,"%d_%d",ut->getId(),faction->getIndex()); - unitRotation = game->getGui()->getUnitTypeBuildRotation(unitKey); - } - - Unit* unit= new Unit(getNextUnitId(), pos, ut, faction, &map, unitRotation); + Unit* unit= new Unit(getNextUnitId(), pos, ut, faction, &map, CardinalDir::NORTH); if(placeUnit(pos, generationArea, unit, true)){ unit->create(true); @@ -583,16 +575,7 @@ void World::initUnits(){ const UnitType *ut= ft->getStartingUnit(j); int initNumber= ft->getStartingUnitAmount(j); for(int l=0; lgetId(),f->getIndex()); - unitRotation = game->getGui()->getUnitTypeBuildRotation(unitKey); - } - - Unit *unit= new Unit(getNextUnitId(), Vec2i(0), ut, f, &map, unitRotation); + Unit *unit= new Unit(getNextUnitId(), Vec2i(0), ut, f, &map, CardinalDir::NORTH); int startLocationIndex= f->getStartLocationIndex();