* fix for map names (possible duplicate entries if mgm and gbm with same name) & alphabetically sorted now

* re-implemented building rotation (Note: requires particle systems that should be rotated with the building to be 'relative')
This commit is contained in:
James McCulloch 2010-03-25 12:15:10 +00:00
parent 2ce421e06c
commit 00dd0f490d
19 changed files with 463 additions and 211 deletions

View File

@ -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){

View File

@ -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());

View File

@ -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;

View File

@ -1,6 +1,8 @@
#ifndef _GLEST_GAME_GAMECONSTANTS_H_
#define _GLEST_GAME_GAMECONSTANTS_H_
#include <cassert>
// ==============================================================
// 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<Enum>(v);
}
operator Enum() { return value; }
void operator++() {
value = static_cast<Enum>(value + 1 % 4);
}
void operator--() { // mod with negative numbers is a 'grey area', hence the +3 rather than -1
value = static_cast<Enum>(value + 3 % 4);
}
private:
Enum value;
};
}}//end namespace

View File

@ -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();

View File

@ -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;
}
}

View File

@ -130,8 +130,8 @@ private:
bool selectingPos;
bool selectingMeetingPoint;
CardinalDir selectedBuildingFacing;
bool allowRotateUnits;
std::map<string, float> 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

View File

@ -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<string> 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<string> 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<string> results;
//tileset listBox
findDirs(config.getPathListForType(ptTilesets), results);

View File

@ -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 {

View File

@ -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>(networkCommandType);}

View File

@ -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

View File

@ -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 <cstdlib>
#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

View File

@ -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; i<type->getSize(); ++i){
for(int j=0; j<type->getSize(); ++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 || dist<nearestDist){
@ -685,8 +685,7 @@ bool Unit::update(){
}
}
if (fire!=NULL)
{
if (fire!=NULL) {
fire->setPos(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

View File

@ -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();

View File

@ -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<storedResources.size(); ++i){
if(storedResources[i].getType()==rt){

View File

@ -0,0 +1,197 @@
// ==============================================================
// This file is part of Glest (www.glest.org)
//
// Copyright (C) 2001-2008 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
// ==============================================================
#ifndef _GLEST_GAME_UNITTYPE_H_
#define _GLEST_GAME_UNITTYPE_H_
#include "element_type.h"
#include "command_type.h"
#include "damage_multiplier.h"
#include "sound_container.h"
#include "checksum.h"
#include "game_constants.h"
namespace Glest{ namespace Game{
using Shared::Sound::StaticSound;
using Shared::Util::Checksum;
class UpgradeType;
class UnitType;
class UnitParticleSystemType;
class ResourceType;
class TechTree;
class FactionType;
// ===============================
// class Level
// ===============================
class Level{
private:
string name;
int kills;
public:
void init(string name, int kills);
const string &getName() const {return name;}
int getKills() const {return kills;}
};
// ===============================
// class UnitType
//
/// A unit or building type
// ===============================
enum UnitClass{
ucWarrior,
ucWorker,
ucBuilding
};
typedef list<UnitParticleSystemType*> DamageParticleSystemTypes;
class UnitType: public ProducibleType{
public:
enum Property{
pBurnable,
pRotatedClimb,
pCount
};
static const char *propertyNames[];
DamageParticleSystemTypes damageParticleSystemTypes;
private:
typedef vector<SkillType*> SkillTypes;
typedef vector<CommandType*> CommandTypes;
typedef vector<Resource> StoredResources;
typedef vector<Level> 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

View File

@ -416,11 +416,10 @@ void Map::putUnitCells(Unit *unit, const Vec2i &pos){
for(int j=0; j<ut->getSize(); ++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; j<ut->getSize(); ++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);
}

View File

@ -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)){

View File

@ -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; l<initNumber; l++){
//!!!
float unitRotation = -1;
if(allowRotateUnits == true) {
char unitKey[50]="";
sprintf(unitKey,"%d_%d",ut->getId(),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();