separate resource loading and unloading orders

removing fulfiled orders
This commit is contained in:
devZoGok
2025-04-26 12:11:53 +03:00
parent 22c4146ffe
commit 421efaf360
9 changed files with 173 additions and 99 deletions
+37 -30
View File
@@ -148,17 +148,17 @@ namespace battleship{
}
vector<TradeOffer*> offers = (gameObjHoveredOn && alliedGameObj ? mainPlayer->getTradeOffers(gameObjHoveredOn->getPlayer()) : vector<TradeOffer*>{});
bool tradeResource[NUM_RESOURCES][2], trade = false;
bool tradeResource[NUM_RESOURCES], trade = false;
int unloadFlag = (int)shiftPressed;
for(TradeOffer *offer : offers)
for(int i = 0; i < NUM_RESOURCES; i++)
for(int j = 0; j < 2; j++){
if(!tradeResource[i][j] && offer->tradeResources[i][j] > 0){
tradeResource[i][j] = true;
trade = true;
}
else tradeResource[i][j] = false;
}
for(int i = 0; i < NUM_RESOURCES && !offers.empty(); i++){
if(offers[0]->tradeResources[i][unloadFlag] > 0){
tradeResource[i] = true;
trade = true;
}
else
tradeResource[i] = false;
}
int objClass = (gameObjUnit ? int(((Unit*)gameObjHoveredOn)->getUnitClass()) : -1);
bool tradeCenter = ((UnitClass)objClass == UnitClass::TRADE_CENTER);
@@ -179,34 +179,30 @@ namespace battleship{
cursorState = CursorState::SUPPLY;
}
else if(roverSelected && (tradeCenter || refinery || lab) && (ownGameObj || (alliedGameObj && trade))){
bool canLoad = (rover && rover->calcTotalLoad() < rover->getCapacity());
bool tradeRes;
bool tradeRes = false;
int resId;
switch((UnitClass)objClass){
case UnitClass::TRADE_CENTER:
tradeRes = (tradeResource[(int)ResourceType::WEALTH][0] || tradeResource[(int)ResourceType::WEALTH][1]);
tradeRes = tradeResource[(int)ResourceType::WEALTH];
resId = (int)ResourceType::WEALTH;
break;
case UnitClass::REFINERY:
tradeRes = (tradeResource[(int)ResourceType::REFINEDS][0] || tradeResource[(int)ResourceType::REFINEDS][1]);
tradeRes = tradeResource[(int)ResourceType::REFINEDS];
resId = (int)ResourceType::REFINEDS;
break;
case UnitClass::LAB:
tradeRes = (tradeResource[(int)ResourceType::RESEARCH][0] || tradeResource[(int)ResourceType::RESEARCH][1]);
tradeRes = tradeResource[(int)ResourceType::RESEARCH];
resId = (int)ResourceType::RESEARCH;
break;
}
orderPossible = (
(ownGameObj && canLoad) ||
(
alliedGameObj &&
tradeRes &&
(rover->calcTotalLoad() < rover->getCapacity() || rover->getLoad(resId) > 0)
)
);
cursorState = CursorState::SUPPLY;
bool canLoad = (rover && rover->calcTotalLoad() < rover->getCapacity());
orderPossible = (unloadFlag ? rover->getLoad(resId) > 0 : canLoad);
if(alliedGameObj) orderPossible = tradeRes && orderPossible;
cursorState = (unloadFlag ? CursorState::UNLOAD : CursorState::LOAD);
}
else if(gameObjUnit && !(ownGameObj || alliedGameObj))
cursorState = CursorState::ATTACK;
@@ -216,18 +212,20 @@ namespace battleship{
else{
if(cursorState == CursorState::GARRISON)
orderPossible = (ownGameObj && gameObjTransport && canGarrison);
else if(cursorState == CursorState::SUPPLY){
bool tradeRefs = (tradeResource[(int)ResourceType::REFINEDS][0] || tradeResource[(int)ResourceType::REFINEDS][1]);
bool tradeWealth = (tradeResource[(int)ResourceType::WEALTH][0] || tradeResource[(int)ResourceType::WEALTH][1]);
bool tradeTech = (tradeResource[(int)ResourceType::RESEARCH][0] || tradeResource[(int)ResourceType::RESEARCH][1]);
else if(cursorState == CursorState::SUPPLY)
orderPossible = (roverSelected && ownExtractor);
else if(cursorState == CursorState::LOAD || cursorState == CursorState::UNLOAD){
bool tradeRefs = tradeResource[(int)ResourceType::REFINEDS];
bool tradeWealth = tradeResource[(int)ResourceType::WEALTH];
bool tradeTech = tradeResource[(int)ResourceType::RESEARCH];
bool canLoad = (rover->calcTotalLoad() < rover->getCapacity());
bool transfer = (
bool loadResource = (
(refinery && ((ownGameObj && canLoad) || (alliedGameObj && tradeRefs && rover->getLoad((int)ResourceType::REFINEDS) > 0))) ||
(tradeCenter && ((ownGameObj && canLoad) || (alliedGameObj && tradeWealth && rover->getLoad((int)ResourceType::WEALTH) > 0))) ||
(lab && ((ownGameObj && canLoad) || (alliedGameObj && tradeTech && rover->getLoad((int)ResourceType::RESEARCH) > 0)))
);
orderPossible = (roverSelected && (ownExtractor || transfer));
orderPossible = (roverSelected && loadResource);
}
else if(cursorState == CursorState::HACK)
orderPossible = (!ownGameObj && gameObjUnit && mainPlayer->getSelectedUnit(0)->getUnitClass() == UnitClass::ENGINEER);
@@ -249,6 +247,8 @@ namespace battleship{
tex = (orderPossible ? garrisonTex : noGarrisonTex);
break;
case CursorState::SUPPLY:
case CursorState::LOAD:
case CursorState::UNLOAD:
tex = (orderPossible ? supplyTex : noSupplyTex);
break;
case CursorState::HACK:
@@ -551,6 +551,7 @@ namespace battleship{
}
//TODO fix ejectable unit selection with multiple transports selected
//TODO replace shiftPressed with a dedicated buy flag
void ActiveGameState::issueOrder(Order::TYPE type, vector<Order::Target> targets, bool addOrder) {
depth = 1;
Vector3 destDir = Vector3::VEC_ZERO;
@@ -675,6 +676,12 @@ namespace battleship{
else if(cursorState == CursorState::SUPPLY){
if(orderPossible) issueOrder(Order::TYPE::SUPPLY, vector<Order::Target>{Order::Target((Unit*)gameObjHoveredOn)}, shiftPressed);
}
else if(cursorState == CursorState::LOAD){
if(orderPossible) issueOrder(Order::TYPE::LOAD, vector<Order::Target>{Order::Target((Unit*)gameObjHoveredOn)}, shiftPressed);
}
else if(cursorState == CursorState::UNLOAD){
if(orderPossible) issueOrder(Order::TYPE::UNLOAD, vector<Order::Target>{Order::Target((Unit*)gameObjHoveredOn)}, shiftPressed);
}
else if(cursorState == CursorState::ATTACK){
if(controlPressed && !gameObjHoveredOn){
castRayToTerrain();
+2
View File
@@ -29,6 +29,8 @@ namespace battleship{
ATTACK,
GARRISON,
SUPPLY,
LOAD,
UNLOAD,
HACK
};
+6
View File
@@ -45,6 +45,12 @@ namespace battleship{
case Order::TYPE::SUPPLY:
cs = ActiveGameState::CursorState::SUPPLY;
break;
case Order::TYPE::LOAD:
cs = ActiveGameState::CursorState::LOAD;
break;
case Order::TYPE::UNLOAD:
cs = ActiveGameState::CursorState::UNLOAD;
break;
case Order::TYPE::HACK:
cs = ActiveGameState::CursorState::HACK;
break;
+22 -15
View File
@@ -41,30 +41,35 @@ namespace battleship{
vector<Unit*> units = this->units;
for(Unit *u : units){
if(!u->isRemove())
u->update();
else
removeUnit(u);
if(!u->isRemove()) u->update();
else removeUnit(u);
}
vector<Projectile*> projectiles = this->projectiles;
for(Projectile *proj : projectiles){
if(!proj->isRemove())
proj->update();
else
removeProjectile(proj);
if(!proj->isRemove()) proj->update();
else removeProjectile(proj);
}
for(ResourceDeposit *rd : resourceDeposits)
rd->update();
for(ResourceDeposit *rd : resourceDeposits) rd->update();
updateTradeOffers();
for(pair<Player*, vector<TradeOffer*>> &pair : tradeOffers){
if(pair.second.empty()) continue;
bool fulfiled = true;
for(int i = 0; i < NUM_RESOURCES && fulfiled; i++){
bool b = (pair.second[0]->tradeResources[i][0] == pair.second[0]->deliveredResources[i][0]);
bool s = (pair.second[0]->tradeResources[i][1] == pair.second[0]->deliveredResources[i][1]);
if(!(b && s)) fulfiled = false;
}
if(fulfiled)
pair.second.erase(pair.second.begin());
}
}
void Player::updateTradeOffers(){
}
int Player::getOrderLineId(Order::TYPE type, Vector3 startPos, Vector3 endPos){
Vector3 color;
@@ -82,6 +87,8 @@ namespace battleship{
break;
case Order::TYPE::BUILD:
case Order::TYPE::SUPPLY:
case Order::TYPE::LOAD:
case Order::TYPE::UNLOAD:
color = Vector3(1, 1, 0);
break;
case Order::TYPE::HACK:
-1
View File
@@ -104,7 +104,6 @@ namespace battleship{
int getOrderLineId(Order::TYPE, vb01::Vector3, vb01::Vector3);
void initTradingVecs();
void updateTradeOffers();
};
}
+76 -41
View File
@@ -37,6 +37,76 @@ namespace battleship{
loadRate = unitTable["loadRate"]; loadRate += game->calcAbilFromTech(Ability::Type::LOAD_RATE, currTechs, (int)GameObject::type, id);
}
void ResourceRover::handleTransfer(Structure *targStruct, float minDist, bool loadResource){
bool closeEnough = (pos.getDistanceFrom(targStruct->getPos()) <= minDist);
if(!closeEnough) return;
ResourceType resType;
switch(targStruct->getUnitClass()){
case UnitClass::TRADE_CENTER:
resType = ResourceType::WEALTH;
break;
case UnitClass::REFINERY:
resType = ResourceType::REFINEDS;
break;
case UnitClass::LAB:
resType = ResourceType::RESEARCH;
break;
}
if(player == targStruct->getPlayer()){
if(!loadResource && canUnload((int)resType)){
player->updateResource(resType, loadSpeed, true);
cargo[(int)resType] -= loadSpeed;
lastLoadTime = getTime();
}
else if(loadResource && canLoad() && player->getResource(resType) > 0){
player->updateResource(resType, -loadSpeed, true);
cargo[(int)resType] += loadSpeed;
lastLoadTime = getTime();
}
}
else{
vector<TradeOffer*> offers = player->getTradeOffers(targStruct->getPlayer());
if(offers.empty()) return;
TradeOffer *offer = offers[0];
if(!loadResource && offer->tradeResources[(int)resType][1] > offer->deliveredResources[(int)resType][1] && canUnload((int)resType)){
targStruct->getPlayer()->updateResource(resType, loadSpeed, true);
offer->deliveredResources[(int)resType][1]++;
cargo[(int)resType] -= loadSpeed;
lastLoadTime = getTime();
}
else if(
loadResource &&
offer->tradeResources[(int)resType][0] > offer->deliveredResources[(int)resType][0] &&
targStruct->getPlayer()->getResource(resType) > 0 &&
canLoad()
)
{
targStruct->getPlayer()->updateResource(resType, -loadSpeed, true);
offer->deliveredResources[(int)resType][0]++;
cargo[(int)resType] += loadSpeed;
lastLoadTime = getTime();
}
}
}
void ResourceRover::transfer(Order order, bool loadResource){
float minDist = .5 * Map::getSingleton()->getCellSize().x;
if(!pathPoints.empty())
navigate(minDist);
else
handleTransfer((Structure*)order.targets[0].unit, minDist, loadResource);
}
void ResourceRover::load(Order order){transfer(order, true);}
void ResourceRover::unload(Order order){transfer(order, false);}
//TODO equate rover load and extractor draw rates
void ResourceRover::collectRefineds(Order order, float minDist){
vector<Unit*> units = player->getUnits();
@@ -58,7 +128,7 @@ namespace battleship{
if(canLoad() && deposit->getAmmount() > 0){
if(nearestExtractor->canDraw()){
nearestExtractor->draw();
load[(int)ResourceType::REFINEDS] += loadSpeed;
cargo[(int)ResourceType::REFINEDS] += loadSpeed;
lastLoadTime = getTime();
}
}
@@ -66,7 +136,7 @@ namespace battleship{
preparePathpoints(order, nearestRefinery->getPos(), true);
}
else if(!nearestExtractor){
if(nearestRefinery && load[(int)ResourceType::REFINEDS] > 0)
if(nearestRefinery && cargo[(int)ResourceType::REFINEDS] > 0)
preparePathpoints(order, nearestRefinery->getPos(), true);
else
removeOrder(0);
@@ -74,57 +144,22 @@ namespace battleship{
if(nearestRefinery && nearestRefinery->getPos().getDistanceFrom(pos) <= minDist){
if(canUnload((int)ResourceType::REFINEDS)){
load[(int)ResourceType::REFINEDS] -= loadSpeed;
cargo[(int)ResourceType::REFINEDS] -= loadSpeed;
player->updateResource(ResourceType::REFINEDS, loadSpeed, true);
lastLoadTime = getTime();
}
else if(load[(int)ResourceType::REFINEDS] == 0 && nearestExtractor)
else if(cargo[(int)ResourceType::REFINEDS] == 0 && nearestExtractor)
preparePathpoints(order, nearestExtractor->getPos());
}
}
void ResourceRover::transferResource(Structure *targStruct, float minDist){
bool closeEnough = (pos.getDistanceFrom(targStruct->getPos()) <= minDist);
ResourceType resType;
switch(targStruct->getUnitClass()){
case UnitClass::TRADE_CENTER:
resType = ResourceType::WEALTH;
break;
case UnitClass::REFINERY:
resType = ResourceType::REFINEDS;
break;
case UnitClass::LAB:
resType = ResourceType::RESEARCH;
break;
}
if(closeEnough){
if(player == targStruct->getPlayer() && canLoad() && player->getResource(resType) > 0){
player->updateResource(resType, -loadSpeed, true);
load[(int)resType] += loadSpeed;
lastLoadTime = getTime();
}
else if(player != targStruct->getPlayer() && canUnload((int)resType)){
targStruct->getPlayer()->updateResource(resType, loadSpeed, true);
load[(int)resType] -= loadSpeed;
lastLoadTime = getTime();
}
}
}
void ResourceRover::supply(Order order){
float minDist = .5 * Map::getSingleton()->getCellSize().x;
if(!pathPoints.empty())
navigate(minDist);
else{
Unit *targUnit = order.targets[0].unit;
if(targUnit->getUnitClass() == UnitClass::EXTRACTOR)
collectRefineds(order, minDist);
else transferResource((Structure*)targUnit, minDist);
}
else
collectRefineds(order, minDist);
}
void ResourceRover::update(){
+10 -7
View File
@@ -14,20 +14,23 @@ namespace battleship{
ResourceRover(Player*, int, vb01::Vector3, vb01::Quaternion, Unit::State = Unit::State::STAND_GROUND);
~ResourceRover();
void update();
inline int getLoad(int id){return load[id];}
inline int calcTotalLoad(){return load[0] + load[1] + load[2];}
inline int getLoad(int id){return cargo[id];}
inline int calcTotalLoad(){return cargo[0] + cargo[1] + cargo[2];}
inline int getCapacity(){return capacity;}
inline bool canLoad(){return vb01::getTime() - lastLoadTime > loadRate && calcTotalLoad() < capacity;}
inline bool canUnload(int id){return vb01::getTime() - lastLoadTime > loadRate && cargo[id] > 0;}
private:
void initProperties();
void supply(Order);
void collectRefineds(Order, float);
void transferResource(Structure*, float);
void supply(Order);
void handleTransfer(Structure*, float, bool);
void transfer(Order, bool);
void load(Order);
void unload(Order);
Unit* getClosestUnit(std::vector<Structure*>);
inline bool canLoad(){return vb01::getTime() - lastLoadTime > loadRate && calcTotalLoad() < capacity;}
inline bool canUnload(int id){return vb01::getTime() - lastLoadTime > loadRate && load[id] > 0;}
vb01::s64 lastLoadTime = 0;
int load[3]{0, 0, 0}, capacity, loadRate, loadSpeed;
int cargo[3]{0, 0, 0}, capacity, loadRate, loadSpeed;
Extractor *nearestExtractor = nullptr;
Unit *nearestRefinery = nullptr;
vb01::Node *loadBackground = nullptr, *loadForeground = nullptr;
+8
View File
@@ -629,6 +629,12 @@ namespace battleship{
case Order::TYPE::SUPPLY:
supply(order);
break;
case Order::TYPE::LOAD:
load(order);
break;
case Order::TYPE::UNLOAD:
unload(order);
break;
case Order::TYPE::HACK:
hack(order);
break;
@@ -702,6 +708,8 @@ namespace battleship{
return false;
}
case Order::TYPE::SUPPLY:
case Order::TYPE::LOAD:
case Order::TYPE::UNLOAD:
return unitClass == UnitClass::RESOURCE_ROVER;
case Order::TYPE::HACK:
{
+9 -2
View File
@@ -37,7 +37,7 @@ namespace battleship{
class Projectile;
struct Order {
enum class TYPE {ATTACK, BUILD, MOVE, GARRISON, EJECT, PATROL, LAUNCH, SUPPLY, HACK};
enum class TYPE {ATTACK, BUILD, MOVE, GARRISON, EJECT, PATROL, LAUNCH, SUPPLY, LOAD, UNLOAD, HACK};
struct Target{
Unit *unit = nullptr;
vb01::Vector3 pos;
@@ -53,7 +53,12 @@ namespace battleship{
std::vector<Target> targets;
Order(){}
Order(TYPE t, std::vector<Target> targ, vb01::Vector3 dir = vb01::Vector3::VEC_ZERO, int lid = -1, bool pa = true) : type(t), playerAssigned(pa), lineId(lid), targets(targ), direction(dir){}
Order(TYPE t, std::vector<Target> targ, vb01::Vector3 dir = vb01::Vector3::VEC_ZERO, int lid = -1, bool pa = true) :
type(t),
playerAssigned(pa),
lineId(lid),
targets(targ),
direction(dir){}
};
enum class MoveDir {LEFT, UP, FORW};
@@ -205,6 +210,8 @@ namespace battleship{
virtual void patrol(Order){}
virtual void launch(Order);
virtual void supply(Order){}
virtual void load(Order){}
virtual void unload(Order){}
virtual void hack(Order){}
float calculateRotation(vb01::Vector3, float, float);
void removeBar(vb01::Node*);