- attempt to fix multi-build

This commit is contained in:
Mark Vejvoda 2010-08-31 23:14:15 +00:00
parent f727c383b2
commit ca49e0ba68
9 changed files with 202 additions and 60 deletions

View File

@ -50,33 +50,44 @@ CommandResult Commander::tryGiveCommand(const Selection *selection, const Comman
Vec2i refPos;
CommandResultContainer results;
refPos= computeRefPos(selection);
refPos = world->getMap()->computeRefPos(selection);
int builderUnitId = -1;
const Unit *builderUnit = world->getMap()->findClosestUnitToPos(selection, pos, unitType);
//Vec2i = world->getMap()->computeDestPos(refPos, builderUnit->getPos(), pos);
//std::pair<float,Vec2i> distance = world->getMap()->getUnitDistanceToPos(builderUnit,pos,unitType);
//builderUnit->setCurrentUnitTitle("Distance: " + floatToStr(distance.first) + " pos: " + distance.second.getString());
int builderUnitId = builderUnit->getId();
CommandStateType commandStateType = cst_None;
int commandStateValue = -1;
bool unitSignalledToBuild = false;
//bool unitSignalledToBuild = false;
//give orders to all selected units
for(int i=0; i<selection->getCount(); ++i) {
for(int i = 0; i < selection->getCount(); ++i) {
const Unit *unit = selection->getUnit(i);
int unitId= unit->getId();
Vec2i currPos= computeDestPos(refPos, unit->getPos(), pos);
Vec2i currPos= world->getMap()->computeDestPos(refPos, unit->getPos(), pos);
Vec2i usePos = currPos;
const CommandType *useCommandtype = commandType;
if(dynamic_cast<const BuildCommandType *>(commandType) != NULL) {
usePos = pos;
if(unitSignalledToBuild == false) {
builderUnitId = unitId;
unitSignalledToBuild = true;
}
else {
//if(unitSignalledToBuild == false) {
//if(builderUnit->getId() == unitId)
// builderUnitId = unitId;
//unitSignalledToBuild = true;
//}
//else {
if(builderUnit->getId() != unitId) {
useCommandtype = unit->getType()->getFirstRepairCommand(unitType);
commandStateType = cst_linkedUnit;
commandStateValue = builderUnitId;
//tryQueue = true;
}
else {
commandStateType = cst_None;
commandStateValue = -1;
}
}
NetworkCommand networkCommand(this->world,nctGiveCommand, unitId,
@ -124,7 +135,7 @@ CommandResult Commander::tryGiveCommand(const Selection *selection, CommandClass
Vec2i refPos, currPos;
CommandResultContainer results;
refPos= computeRefPos(selection);
refPos= world->getMap()->computeRefPos(selection);
//give orders to all selected units
for(int i=0; i<selection->getCount(); ++i){
@ -133,7 +144,7 @@ CommandResult Commander::tryGiveCommand(const Selection *selection, 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);
Vec2i currPos= world->getMap()->computeDestPos(refPos, selection->getUnit(i)->getPos(), pos);
NetworkCommand networkCommand(this->world,nctGiveCommand, unitId, ct->getId(), currPos, -1, targetId, -1, tryQueue);
//every unit is ordered to a different pos
@ -158,13 +169,13 @@ CommandResult Commander::tryGiveCommand(const Selection *selection,
Vec2i refPos;
CommandResultContainer results;
refPos= computeRefPos(selection);
refPos= world->getMap()->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);
Vec2i currPos= world->getMap()->computeDestPos(refPos, selection->getUnit(i)->getPos(), pos);
NetworkCommand networkCommand(this->world,nctGiveCommand, unitId, commandType->getId(), currPos, -1, targetId, -1, tryQueue);
//every unit is ordered to a different position
@ -193,13 +204,13 @@ CommandResult Commander::tryGiveCommand(const Selection *selection, const Vec2i
CommandResultContainer results;
//give orders to all selected units
refPos= computeRefPos(selection);
refPos= world->getMap()->computeRefPos(selection);
for(int i=0; i<selection->getCount(); ++i) {
//every unit is ordered to a different pos
const Unit *unit = selection->getUnit(i);
assert(unit != NULL);
currPos= computeDestPos(refPos, unit->getPos(), pos);
currPos= world->getMap()->computeDestPos(refPos, unit->getPos(), pos);
//get command type
const CommandType *commandType= unit->computeCommandType(pos, targetUnit);
@ -255,32 +266,6 @@ void Commander::trySetMeetingPoint(const Unit* unit, const Vec2i &pos)const{
// ==================== 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:

View File

@ -64,8 +64,6 @@ public:
//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(NetworkCommand* networkCommand) const;
Command* buildCommand(const NetworkCommand* networkCommand) const;

View File

@ -1,4 +1,3 @@
// ==============================================================
// This file is part of Glest (www.glest.org)
//
// Copyright (C) 2001-2008 Martio Figueroa
@ -1570,6 +1569,8 @@ void Renderer::renderUnits(const int renderFps, const int worldFrameCount) {
//assert
assertGl();
visibleFrameUnitList.clear();
bool modelRenderStarted = false;
for(int i=0; i<world->getFactionCount(); ++i){
@ -1633,6 +1634,8 @@ void Renderer::renderUnits(const int renderFps, const int worldFrameCount) {
glPopMatrix();
unit->setVisible(true);
unit->setScreenPos(computeScreenPosition(unit->getCurrVectorFlat()));
visibleFrameUnitList.push_back(unit);
if(allowRenderUnitTitles == true) {
// Add to the pending render unit title list
@ -1755,10 +1758,16 @@ void Renderer::renderSelectionEffects(){
currVec.y+= 0.3f;
//selection circle
if(world->getThisFactionIndex()==unit->getFactionIndex()){
glColor4f(0, unit->getHpRatio(), 0, 0.3f);
if(world->getThisFactionIndex() == unit->getFactionIndex()) {
if( showDebugUI == true && unit->getCommandSize() > 0 &&
dynamic_cast<const BuildCommandType *>(unit->getCurrCommand()->getCommandType()) != NULL) {
glColor4f(unit->getHpRatio(), unit->getHpRatio(), unit->getHpRatio(), 0.3f);
}
else {
glColor4f(0, unit->getHpRatio(), 0, 0.3f);
}
}
else if ( world->getThisTeamIndex()==unit->getTeam()){
else if ( world->getThisTeamIndex() == unit->getTeam()){
glColor4f(unit->getHpRatio(), unit->getHpRatio(), 0, 0.3f);
}
else{
@ -3392,11 +3401,28 @@ void Renderer::setAllowRenderUnitTitles(bool value) {
// This method renders titles for units
void Renderer::renderUnitTitles(Font2D *font, Vec3f color) {
std::map<int,bool> unitRenderedList;
if(visibleFrameUnitList.size() > 0) {
for(int idx = 0; idx < visibleFrameUnitList.size(); idx++) {
const Unit *unit = visibleFrameUnitList[idx];
if(unit != NULL && unit->getCurrentUnitTitle() != "") {
//get the screen coordinates
Vec3f screenPos = unit->getScreenPos();
renderText(unit->getCurrentUnitTitle(), font, color, fabs(screenPos.x) + 5, fabs(screenPos.y) + 5, false);
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] screenPos.x = %f, screenPos.y = %f, screenPos.z = %f\n",__FILE__,__FUNCTION__,__LINE__,screenPos.x,screenPos.y,screenPos.z);
unitRenderedList[unit->getId()] = true;
}
}
visibleFrameUnitList.clear();
}
if(renderUnitTitleList.size() > 0) {
for(int idx = 0; idx < renderUnitTitleList.size(); idx++) {
std::pair<Unit *,Vec3f> &unitInfo = renderUnitTitleList[idx];
Unit *unit = unitInfo.first;
if(unit != NULL) {
if(unit != NULL && unitRenderedList.find(unit->getId()) == unitRenderedList.end()) {
string str = unit->getFullName() + " - " + intToStr(unit->getId());
//get the screen coordinates
Vec3f &screenPos = unitInfo.second;

View File

@ -239,6 +239,7 @@ private:
bool allowRenderUnitTitles;
std::vector<std::pair<Unit *,Vec3f> > renderUnitTitleList;
std::vector<Unit *> visibleFrameUnitList;
bool no2DMouseRendering;
bool showDebugUI;

View File

@ -747,9 +747,10 @@ CommandResult Unit::giveCommand(Command *command, bool tryQueue) {
}
//pop front (used when order is done)
CommandResult Unit::finishCommand(){
CommandResult Unit::finishCommand() {
retryCurrCommandCount=0;
this->setCurrentUnitTitle("");
//is empty?
if(commands.empty()){
return crFailUndefined;
@ -773,9 +774,11 @@ CommandResult Unit::finishCommand(){
}
//to cancel a command
CommandResult Unit::cancelCommand(){
CommandResult Unit::cancelCommand() {
retryCurrCommandCount=0;
this->setCurrentUnitTitle("");
//is empty?
if(commands.empty()){
return crFailUndefined;
@ -1705,6 +1708,10 @@ std::string Unit::toString() const {
result += "retryCurrCommandCount = " + intToStr(retryCurrCommandCount) + "\n";
result += "screenPos = " + screenPos.getString() + "\n";
result += "currentUnitTitle = " + currentUnitTitle + "\n";
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
return result;

View File

@ -265,6 +265,9 @@ private:
int retryCurrCommandCount;
Vec3f screenPos;
string currentUnitTitle;
public:
Unit(int id, UnitPathInterface *path, const Vec2i &pos, const UnitType *type, Faction *faction, Map *map, CardinalDir placeFacing);
~Unit();
@ -394,6 +397,12 @@ public:
int getRetryCurrCommandCount() const { return retryCurrCommandCount; }
void setRetryCurrCommandCount(int value) { retryCurrCommandCount = value; }
Vec3f getScreenPos() const { return screenPos; }
void setScreenPos(Vec3f value) { screenPos = value; }
string getCurrentUnitTitle() const {return currentUnitTitle;}
void setCurrentUnitTitle(string value) { currentUnitTitle = value;}
std::string toString() const;
private:

View File

@ -439,8 +439,110 @@ bool Map::aproxCanMove(const Unit *unit, const Vec2i &pos1, const Vec2i &pos2) c
}
}
Vec2i Map::computeRefPos(const Selection *selection) const {
Vec2i total= Vec2i(0);
for(int i = 0; i < selection->getCount(); ++i) {
if(selection == NULL || selection->getUnit(i) == NULL) {
throw runtime_error("selection == NULL || selection->getUnit(i) == NULL");
}
total = total + selection->getUnit(i)->getPos();
}
return Vec2i(total.x / selection->getCount(), total.y / selection->getCount());
}
Vec2i Map::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;
clampPos(pos);
return pos;
}
std::pair<float,Vec2i> Map::getUnitDistanceToPos(const Unit *unit,Vec2i pos,const UnitType *ut) {
if(unit == NULL) {
throw runtime_error("unit == NULL");
}
std::pair<float,Vec2i> result(-1,Vec2i(0));
int unitId= unit->getId();
Vec2i unitPos= computeDestPos(unit->getPos(), unit->getPos(), pos);
Vec2i start = pos - Vec2i(1);
int unitTypeSize = 0;
if(ut != NULL) {
unitTypeSize = ut->getSize();
}
Vec2i end = pos + Vec2i(unitTypeSize);
for(int i = start.x; i <= end.x; ++i) {
for(int j = start.y; j <= end.y; ++j){
Vec2i testPos(i,j);
if(ut == NULL || isInUnitTypeCells(ut, pos,testPos) == false) {
float distance = unitPos.dist(testPos);
if(result.first < 0 || result.first > distance) {
result.first = distance;
result.second = testPos;
}
}
}
}
return result;
}
const Unit * Map::findClosestUnitToPos(const Selection *selection, Vec2i originalBuildPos,
const UnitType *ut) const {
const Unit *closestUnit = NULL;
Vec2i refPos = computeRefPos(selection);
Vec2i pos = originalBuildPos;
float bestRange = -1;
Vec2i start = pos - Vec2i(1);
int unitTypeSize = 0;
if(ut != NULL) {
unitTypeSize = ut->getSize();
}
Vec2i end = pos + Vec2i(unitTypeSize);
for(int i = 0; i < selection->getCount(); ++i) {
const Unit *unit = selection->getUnit(i);
int unitId= unit->getId();
Vec2i unitBuilderPos= computeDestPos(refPos, unit->getPos(), pos);
for(int i = start.x; i <= end.x; ++i) {
for(int j = start.y; j <= end.y; ++j){
Vec2i testPos(i,j);
if(isInUnitTypeCells(ut, originalBuildPos,testPos) == false) {
float distance = unitBuilderPos.dist(testPos);
if(bestRange < 0 || bestRange > distance) {
bestRange = distance;
pos = testPos;
closestUnit = unit;
}
}
}
}
}
return closestUnit;
}
Vec2i Map::findBestBuildApproach(Vec2i unitBuilderPos, Vec2i originalBuildPos,
const UnitType *ut) {
const UnitType *ut) const {
Vec2i pos = originalBuildPos;
float bestRange = -1;
@ -465,7 +567,7 @@ Vec2i Map::findBestBuildApproach(Vec2i unitBuilderPos, Vec2i originalBuildPos,
}
bool Map::isNextToUnitTypeCells(const UnitType *ut, const Vec2i &pos,
const Vec2i &testPos) {
const Vec2i &testPos) const {
bool isInsideDestUnitCells = isInUnitTypeCells(ut, pos,testPos);
if(isInsideDestUnitCells == false) {
Cell *testCell = getCell(testPos);
@ -488,7 +590,7 @@ bool Map::isNextToUnitTypeCells(const UnitType *ut, const Vec2i &pos,
// is testPos in the cells of unitType where unitType's position is pos
bool Map::isInUnitTypeCells(const UnitType *ut, const Vec2i &pos,
const Vec2i &testPos) {
const Vec2i &testPos) const {
assert(ut!=NULL);
Cell *testCell = getCell(testPos);

View File

@ -17,7 +17,8 @@
#include "command_type.h"
#include "logger.h"
#include "object.h"
#include "game_constants.h"
#include "game_constants.h"
#include "selection.h"
#include <cassert>
@ -214,12 +215,17 @@ public:
bool canMove(const Unit *unit, const Vec2i &pos1, const Vec2i &pos2) const;
void putUnitCells(Unit *unit, const Vec2i &pos);
void clearUnitCells(Unit *unit, const Vec2i &pos);
bool isInUnitTypeCells(const UnitType *ut, const Vec2i &pos,const Vec2i &testPos);
bool isNextToUnitTypeCells(const UnitType *ut, const Vec2i &pos,const Vec2i &testPos);
Vec2i computeRefPos(const Selection *selection) const;
Vec2i computeDestPos( const Vec2i &refUnitPos, const Vec2i &unitPos,
const Vec2i &commandPos) const;
const Unit * findClosestUnitToPos(const Selection *selection, Vec2i originalBuildPos,
const UnitType *ut) const;
bool isInUnitTypeCells(const UnitType *ut, const Vec2i &pos,const Vec2i &testPos) const;
bool isNextToUnitTypeCells(const UnitType *ut, const Vec2i &pos,const Vec2i &testPos) const;
Vec2i findBestBuildApproach(Vec2i unitBuilderPos, Vec2i originalBuildPos,
const UnitType *ut);
const UnitType *ut) const;
std::pair<float,Vec2i> getUnitDistanceToPos(const Unit *unit,Vec2i pos,const UnitType *ut);
//misc
bool isNextTo(const Vec2i &pos, const Unit *unit) const;

View File

@ -385,7 +385,7 @@ void UnitUpdater::updateAttackStopped(Unit *unit){
// ==================== updateBuild ====================
void UnitUpdater::updateBuild(Unit *unit){
void UnitUpdater::updateBuild(Unit *unit) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
Chrono chrono;
@ -394,6 +394,9 @@ void UnitUpdater::updateBuild(Unit *unit){
Command *command= unit->getCurrCommand();
const BuildCommandType *bct= static_cast<const BuildCommandType*>(command->getCommandType());
std::pair<float,Vec2i> distance = map->getUnitDistanceToPos(unit,command->getPos(),command->getUnitType());
unit->setCurrentUnitTitle("Distance: " + floatToStr(distance.first) + " build pos: " + distance.second.getString() + " current pos: " + unit->getPos().getString());
if(unit->getCurrSkill()->getClass() != scBuild) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
@ -499,6 +502,7 @@ void UnitUpdater::updateBuild(Unit *unit){
//if there are no free cells
unit->cancelCommand();
unit->setCurrSkill(scStop);
if(unit->getFactionIndex()==world->getThisFactionIndex()){
console->addStdMessage("BuildingNoPlace");
}
@ -509,6 +513,7 @@ void UnitUpdater::updateBuild(Unit *unit){
case tsBlocked:
if(unit->getPath()->isBlocked()){
unit->cancelCommand();
}
break;
}
@ -522,15 +527,18 @@ void UnitUpdater::updateBuild(Unit *unit){
//if u is killed while building then u==NULL;
if(builtUnit!=NULL && builtUnit!=command->getUnit()){
unit->setCurrSkill(scStop);
}
else if(builtUnit==NULL || builtUnit->isBuilt()){
unit->finishCommand();
unit->setCurrSkill(scStop);
}
else if(builtUnit->repair()){
//building finished
unit->finishCommand();
unit->setCurrSkill(scStop);
builtUnit->born();
scriptManager->onUnitCreated(builtUnit);
if(unit->getFactionIndex()==world->getThisFactionIndex()){