diff --git a/aregion.cpp b/aregion.cpp index bc73e479..74e94113 100644 --- a/aregion.cpp +++ b/aregion.cpp @@ -387,7 +387,7 @@ int ARegion::RoadDevelopmentBonus(int range, int dev) if (!r) continue; if (HasConnectingRoad(d)) bonus = r->TraceConnectedRoad(d, bonus, con, range-1, dev); } - return bonus; + return bonus; } // AS @@ -1052,7 +1052,7 @@ void ARegion::Writeout(ostream& f) f << products.size() << '\n'; for (const auto& product : products) product->write_out(f); f << markets.size() << '\n'; - for (const auto& market : markets) market->write_out(f); + for (const auto& market : markets) market->write_out(f); f << objects.Num() << '\n'; forlist ((&objects)) ((Object *) elem)->Writeout(f); @@ -1291,7 +1291,7 @@ void ARegion::build_json_report(json& j, Faction *fac, int month, ARegionList *r if (m->amount != -1) item["amount"] = m->amount; else item["unlimited"] = true; - if (m->type == Market::M_SELL) { + if (m->type == Market::MarketType::M_SELL) { if (ItemDefs[m->item].type & IT_ADVANCED) { if (!Globals->MARKETS_SHOW_ADVANCED_ITEMS) { if (!HasItem(fac, m->item)) continue; @@ -1345,7 +1345,7 @@ void ARegion::build_json_report(json& j, Faction *fac, int month, ARegionList *r j["exits"] = json::array(); for (int i=0; ibasic_region_data() } } ); @@ -1783,7 +1783,6 @@ void ARegion::AddFleet(Object * fleet) objects.Add(fleet); //Awrite(AString("Setting up fleet alias #") + fleetalias + ": " + fleet->num); newfleets.insert(make_pair(fleetalias++, fleet->num)); - } int ARegion::ResolveFleetAlias(int alias) @@ -2188,7 +2187,7 @@ void ARegionList::TownStatistics() break; case TOWN_CITY: cities++; - } + } } } int tot = villages + towns + cities; @@ -2455,7 +2454,7 @@ int ARegionList::GetPlanarDistance(ARegion *one, ARegion *two, int penalty, int r->distance = -1; r->next = 0; } - + zdist = (one->zloc - two->zloc); if (zdist < 0) zdist = -zdist; start->distance = zdist * penalty; @@ -2635,11 +2634,11 @@ int ParseTerrain(AString *token) for (int i = 0; i < R_NUM; i++) { if (*token == TerrainDefs[i].type) return i; } - + for (int i = 0; i < R_NUM; i++) { if (*token == TerrainDefs[i].name) return i; } - + return (-1); } @@ -2741,8 +2740,11 @@ bool isNearWaterBody(ARegion* reg, std::vector& list) { return false; } -void makeRivers(Map* map, ARegionArray* arr, std::vector& waterBodies, std::unordered_map& rivers, - const int w, const int h, const int maxRiverReach) { +void makeRivers( + Map* map, ARegionArray* arr, std::vector& waterBodies, + std::unordered_map& rivers, + const int w, const int h, const int maxRiverReach +) { std::cout << "Let's have RIVERS!" << std::endl; // all non-coast water regions @@ -2822,7 +2824,7 @@ void makeRivers(Map* map, ARegionArray* arr, std::vector& waterBodie if (otherWater < 0) { continue; } - + int currentDist = distances[water->name][otherWater]; if (newDist < currentDist ) { distances[water->name][otherWater] = newDist; @@ -3014,7 +3016,10 @@ void makeRivers(Map* map, ARegionArray* arr, std::vector& waterBodie } } -void cleanupIsolatedPlaces(ARegionArray* arr, std::vector& waterBodies, std::unordered_map& rivers, int w, int h) { +void cleanupIsolatedPlaces( + ARegionArray* arr, std::vector& waterBodies, + std::unordered_map& rivers, int w, int h +) { for (int x = 0; x < w; x++) { for (int y = 0; y < h; y++) { if ((x + y) % 2) { @@ -3067,7 +3072,7 @@ void cleanupIsolatedPlaces(ARegionArray* arr, std::vector& waterBodi int countNeighbors(ARegionGraph& graph, ARegion* reg, int ofType, int distance) { graphs::Location2D loc = { reg->xloc, reg->yloc }; - + int count = 0; auto result = graphs::breadthFirstSearch(graph, loc); @@ -3139,7 +3144,7 @@ std::vector getPoints(const int w, const int h, int minDist = initialMinDist; int cellSize = ceil(minDist / sqrt(2)); - + graphs::Location2D loc; do { loc = { .x = getrandom(w), .y = getrandom(h) }; @@ -3313,7 +3318,10 @@ Ethnicity getRegionEtnos(ARegion* reg) { return etnos; } -void subdivideArea(const int width, const int height, const int distance, const std::vector ®ions, std::vector> &subgraphs) { +void subdivideArea( + const int width, const int height, const int distance, + const std::vector ®ions, std::vector> &subgraphs +) { auto points = getPointsFromList(width, distance, 8, regions); std::unordered_map> centers; @@ -3343,7 +3351,10 @@ void subdivideArea(const int width, const int height, const int distance, const } } -void nameArea(int width, int height, ARegionGraph &graph, std::unordered_set &usedNames, std::vector& nameAnchors, std::vector ®ions, std::unordered_set &named) { +void nameArea( + int width, int height, ARegionGraph &graph, std::unordered_set &usedNames, + std::vector& nameAnchors, std::vector ®ions, std::unordered_set &named +) { std::string name; Ethnicity etnos = Ethnicity::NONE; @@ -3389,7 +3400,7 @@ void nameArea(int width, int height, ARegionGraph &graph, std::unordered_settype, 1, false); } usedNames.emplace(volcanoName); - + std::cout << volcanoName << std::endl; r->SetName(volcanoName.c_str()); } @@ -3401,14 +3412,19 @@ void nameArea(int width, int height, ARegionGraph &graph, std::unordered_set& waterBodies, std::unordered_map& rivers, const int w, const int h) { +void giveNames( + ARegionArray* arr, std::vector& waterBodies, std::unordered_map& rivers, + const int w, const int h +) { std::unordered_set named; std::unordered_set usedNames; // generate name areas std::vector nameAnchors; std::unordered_set usedNameSeeds; - for (auto p : getPoints(w, h, 8, 16, [](graphs::Location2D p) { return 8; }, [](graphs::Location2D p) { return true; })) { + auto onPoint = [](graphs::Location2D p) { return 8; }; + auto onIsIncluded = [](graphs::Location2D p) { return true; }; + for (auto p : getPoints(w, h, 8, 16, onPoint, onIsIncluded)) { int seed; do { seed = getrandom(w * h) + 1; @@ -3727,7 +3743,7 @@ void ARegionList::AddHistoricalBuildings(ARegionArray* arr, const int w, const i } ARegionGraph graph = ARegionGraph(arr); - + graph.setInclusion([](ARegion* current, ARegion* next) { return next->type != R_OCEAN && next->type != R_VOLCANO; }); @@ -3898,7 +3914,7 @@ void ARegionList::CreateNaturalSurfaceLevel(Map* map) { const int h = map->map.height / 2; MakeRegions(level, w, h); - + pRegionArrays[level]->SetName(0); pRegionArrays[level]->levelType = ARegionArray::LEVEL_SURFACE; @@ -3925,13 +3941,13 @@ void ARegionList::CreateNaturalSurfaceLevel(Map* map) { const int maxRiverReach = std::min(w, h) / 4; makeRivers(map, arr, waterBodies, rivers, w, h, maxRiverReach); - + cleanupIsolatedPlaces(arr, waterBodies, rivers, w, h); placeVolcanoes(arr, w, h); GrowRaces(arr); - + giveNames(arr, waterBodies, rivers, w, h); assertAllRegionsHaveName(w, h, arr); @@ -3993,13 +4009,13 @@ void ARegionList::ResourcesStatistics() { forlist(this) { ARegion* reg = (ARegion*) elem; - + for (const auto& p : reg->products) { resources[p->itemtype] += p->amount; } for (const auto& m : reg->markets) { - if (m->type == Market::M_BUY) { + if (m->type == Market::MarketType::M_BUY) { forSale[m->item] += m->amount; } else { diff --git a/basic/world.cpp b/basic/world.cpp index 15c1e852..6aba17c1 100644 --- a/basic/world.cpp +++ b/basic/world.cpp @@ -2503,9 +2503,9 @@ void ARegion::MakeStartingCity() if (!Globals->TOWNS_EXIST) return; if (Globals->GATES_EXIST) gate = -1; - + if (town) delete town; - + AddTown(TOWN_CITY); if (!Globals->START_CITIES_EXIST) return; @@ -2526,18 +2526,18 @@ void ARegion::MakeStartingCity() if ( ItemDefs[ i ].type & IT_NORMAL ) { if (i==I_SILVER || i==I_LIVESTOCK || i==I_FISH || i==I_GRAIN) continue; - m = new Market(Market::M_BUY, i, (ItemDefs[i].baseprice * 5 / 2), -1, 5000, 5000, -1, -1); + m = new Market(Market::MarketType::M_BUY, i, (ItemDefs[i].baseprice * 5 / 2), -1, 5000, 5000, -1, -1); markets.push_back(m); } } ratio = ItemDefs[race].baseprice / ((float)Globals->BASE_MAN_COST * 10); // hack: include wage factor of 10 in float calculation above - m = new Market(Market::M_BUY, race, (int)(Wages() * 4 * ratio), -1, 5000, 5000, -1, -1); + m = new Market(Market::MarketType::M_BUY, race, (int)(Wages() * 4 * ratio), -1, 5000, 5000, -1, -1); markets.push_back(m); if (Globals->LEADERS_EXIST) { ratio=ItemDefs[I_LEADERS].baseprice/((float)Globals->BASE_MAN_COST * 10); // hack: include wage factor of 10 in float calculation above - m = new Market(Market::M_BUY, I_LEADERS, (int)(Wages() * 4 * ratio), -1, 5000, 5000, -1, -1); + m = new Market(Market::MarketType::M_BUY, I_LEADERS, (int)(Wages() * 4 * ratio), -1, 5000, 5000, -1, -1); markets.push_back(m); } } else { @@ -2545,12 +2545,16 @@ void ARegion::MakeStartingCity() ratio = ItemDefs[race].baseprice / ((float)Globals->BASE_MAN_COST * 10); // hack: include wage factor of 10 in float calculation above /* Setup Recruiting */ - m = new Market(Market::M_BUY, race, (int)(Wages() * 4 * ratio), Population() / 5, 0, 10000, 0, 2000); + m = new Market( + Market::MarketType::M_BUY, race, (int)(Wages() * 4 * ratio), Population() / 5, 0, 10000, 0, 2000) + ; markets.push_back(m); if ( Globals->LEADERS_EXIST ) { ratio=ItemDefs[I_LEADERS].baseprice/((float)Globals->BASE_MAN_COST * 10); // hack: include wage factor of 10 in float calculation above - m = new Market(Market::M_BUY, I_LEADERS, (int)(Wages() * 4 * ratio), Population() / 25, 0, 10000, 0, 400); + m = new Market( + Market::MarketType::M_BUY, I_LEADERS, (int)(Wages() * 4 * ratio), Population() / 25, 0, 10000, 0, 400 + ); markets.push_back(m); } } diff --git a/economy.cpp b/economy.cpp index 271a8940..badb72ce 100644 --- a/economy.cpp +++ b/economy.cpp @@ -72,7 +72,7 @@ int ARegion::Wages() } wages *= 10; if (dv > last) - wages += 10 * (dv - last) / (level - last); + wages += 10 * (dv - last) / (level - last); return wages; } @@ -94,7 +94,7 @@ void ARegion::SetupHabitat(TerrainType* terrain) { int pop = terrain->pop; int mw = terrain->wages; - + // fix economy when MAINTENANCE_COST has been adjusted mw += Globals->MAINTENANCE_COST - 10; if (mw < 0) mw = 0; @@ -136,7 +136,7 @@ void ARegion::SetupHabitat(TerrainType* terrain) { basepopulation = habitat / 3; // hmm... somewhere not too far off equilibrium pop population = habitat * (60 + getrandom(6) + getrandom(6)) / 100; - + // Setup development int level = 1; development = 1; @@ -196,7 +196,7 @@ void ARegion::SetupEconomy() { e->baseamount = maxent / Globals->ENTERTAIN_FRACTION; // raise entertainment income by productivity factor 10 e->productivity = Globals->ENTERTAIN_INCOME * 10; - + // note: wage factor 10, population factor 5 - included as "/ 50" /* More wealth in safe Starting Cities */ if ((Globals->SAFE_START_CITIES) && (IsStartingCity())) { @@ -213,13 +213,17 @@ void ARegion::SetupEconomy() { float ratio = ItemDefs[race].baseprice / ((float)Globals->BASE_MAN_COST * 10); // hack: include wage factor of 10 in float assignment above // Setup Recruiting - Market *m = new Market(Market::M_BUY, race, (int)(Wages() * 4 * ratio), Population() / 25, 0, 10000, 0, 2000); + Market *m = new Market( + Market::MarketType::M_BUY, race, (int)(Wages() * 4 * ratio), Population() / 25, 0, 10000, 0, 2000 + ); markets.push_back(m); if (Globals->LEADERS_EXIST) { ratio = ItemDefs[I_LEADERS].baseprice / ((float)Globals->BASE_MAN_COST * 10); // hack: include wage factor of 10 in float assignment above - m = new Market(Market::M_BUY, I_LEADERS, (int)(Wages() * 4 * ratio), Population() / 125, 0, 10000, 0, 400); + m = new Market( + Market::MarketType::M_BUY, I_LEADERS, (int)(Wages() * 4 * ratio), Population() / 125, 0, 10000, 0, 400 + ); markets.push_back(m); } } @@ -276,12 +280,12 @@ void ARegion::SetIncome() if (basepopulation == 0) return; maxwages = Wages(); - + /* taxable region wealth */ wealth = (int) ((float) (Population() * (Wages() - 10 * Globals->MAINTENANCE_COST) / 50)); if (wealth < 0) wealth = 0; - + /* Wages */ // wage-relevant population (/10 wages /5 popfactor) int pp = Population(); @@ -327,7 +331,7 @@ void ARegion::SetIncome() e->skill = S_ENTERTAINMENT; // raise entertainment income by productivity factor 10 e->productivity = Globals->ENTERTAIN_INCOME * 10; - + // note: wage factor 10, population factor 5 - included as "/ 50" /* More wealth in safe Starting Cities */ if ((Globals->SAFE_START_CITIES) && (IsStartingCity())) { @@ -337,7 +341,7 @@ void ARegion::SetIncome() w->baseamount += wbonus / Globals->WORK_FRACTION; e->amount += wbonus / Globals->ENTERTAIN_FRACTION; e->baseamount += wbonus / Globals->ENTERTAIN_FRACTION; - } + } } void ARegion::DisbandInRegion(int item, int amt) @@ -393,7 +397,7 @@ void ARegion::SetupCityMarket() ManType *locals = FindRace(ItemDefs[race].abr); if (!locals) locals = FindRace("SELF"); /* compose array of possible supply & demand items */ - int supply[NITEMS]; + int supply[NITEMS]; int demand[NITEMS]; /* possible advanced and magic items */ int rare[NITEMS]; @@ -425,7 +429,7 @@ void ARegion::SetupCityMarket() break; } } - } + } // Non-raw goods else { canProduceHere = 1; @@ -454,9 +458,9 @@ void ARegion::SetupCityMarket() isUseful = locals->CanUse(i); //Normal Items if (ItemDefs[ i ].type & IT_NORMAL) { - + if (i==I_GRAIN || i==I_LIVESTOCK || i==I_FISH) { - // Add foodstuffs directly to market + // Add foodstuffs directly to market int amt = Globals->CITY_MARKET_NORMAL_AMT; int price; @@ -470,7 +474,9 @@ void ARegion::SetupCityMarket() cap = (citymax * 3/4) - 5000; if (cap < 0) cap = citymax/2; - Market * m = new Market(Market::M_SELL, i, price, amt, population, population + cap, amt, amt * 2); + Market * m = new Market( + Market::MarketType::M_SELL, i, price, amt, population, population + cap, amt, amt * 2 + ); markets.push_back(m); } else if (i == I_FOOD) { // Add foodstuffs directly to market @@ -486,7 +492,9 @@ void ARegion::SetupCityMarket() cap = (citymax * 3/4) - 5000; if (cap < 0) cap = citymax/2; - Market * m = new Market(Market::M_BUY, i, price, amt, population, population + 2 * cap, amt, amt * 5); + Market * m = new Market( + Market::MarketType::M_BUY, i, price, amt, population, population + 2 * cap, amt, amt * 5 + ); markets.push_back(m); } else if (ItemDefs[i].pInput[0].item == -1) { // Basic resource @@ -500,7 +508,7 @@ void ARegion::SetupCityMarket() } else if (isUseful) demand[i] = 4; } } else { - + // Tool, weapon or armor if (isUseful) { // Add to supply? @@ -550,7 +558,8 @@ void ARegion::SetupCityMarket() offset = citymax / 8; if (cap+offset < citymax) { Market * m = new Market( - Market::M_SELL, i, price, amt / 6, population + cap + offset, population + citymax, 0, amt + Market::MarketType::M_SELL, i, price, amt / 6, population + cap + offset, + population + citymax, 0, amt ); markets.push_back(m); } @@ -573,20 +582,21 @@ void ARegion::SetupCityMarket() if (Globals->RANDOM_ECONOMY) { amt += getrandom(amt); - price = (ItemDefs[i].baseprice * (100 + getrandom(50))) / - 100; + price = (ItemDefs[i].baseprice * (100 + getrandom(50))) / 100; } else { price = ItemDefs[ i ].baseprice; } - + cap = (citymax *3/4) - 5000; if (cap < citymax/2) cap = citymax / 2; offset = (citymax/20) + ((citymax/5) * 2); - Market * m = new Market(Market::M_SELL, i, price, amt / 6, population + cap, population + citymax, 0, amt); + Market * m = new Market( + Market::MarketType::M_SELL, i, price, amt / 6, population + cap, population + citymax, 0, amt + ); markets.push_back(m); } } - + /* Add demand (normal) items */ int num = 4; int sum = 1; @@ -601,11 +611,11 @@ void ARegion::SetupCityMarket() if (dm < sum) break; } if (dm >= sum) continue; - + int amt = Globals->CITY_MARKET_NORMAL_AMT; amt = demand[i] * amt / 4; int price; - + if (Globals->RANDOM_ECONOMY) { amt += getrandom(amt); price = (ItemDefs[i].baseprice * @@ -613,17 +623,17 @@ void ARegion::SetupCityMarket() } else { price = ItemDefs[i].baseprice; } - + cap = (citymax/4); offset = - (citymax/20) + ((5-num) * citymax * 3/40); Market * m = new Market( - Market::M_SELL, i, price, amt / 6, population + cap + offset, population + citymax, 0, amt + Market::MarketType::M_SELL, i, price, amt / 6, population + cap + offset, population + citymax, 0, amt ); markets.push_back(m); demand[i] = 0; - num--; + num--; } - + /* Add supply (normal) items */ num = 2; sum = 1; @@ -650,11 +660,13 @@ void ARegion::SetupCityMarket() } else { price = ItemDefs[ i ].baseprice; } - + cap = (citymax/4); offset = ((3-num) * citymax * 3 / 40); if (supply[i] < 4) offset += citymax / 20; - Market * m = new Market(Market::M_BUY, i, price, 0, population + cap + offset, population + citymax, 0, amt); + Market * m = new Market( + Market::MarketType::M_BUY, i, price, 0, population + cap + offset, population + citymax, 0, amt + ); markets.push_back(m); supply[i] = 0; num--; @@ -712,13 +724,14 @@ void ARegion::SetupCityMarket() } else { price = ItemDefs[ i ].baseprice; } - + cap = (citymax/2); tradesell++; offset = - (citymax/20) + tradesell * (tradesell * tradesell * citymax/40); if (cap + offset < citymax) { Market * m = new Market( - Market::M_SELL, i, price, amt / 5, cap + population + offset, citymax + population, 0, amt + Market::MarketType::M_SELL, i, price, amt / 5, cap + population + offset, + citymax + population, 0, amt ); markets.push_back(m); } @@ -743,7 +756,8 @@ void ARegion::SetupCityMarket() offset = tradebuy++ * (citymax/6); if (cap+offset < citymax) { Market * m = new Market( - Market::M_BUY, i, price, amt / 6, cap + population + offset, citymax + population, 0, amt + Market::MarketType::M_BUY, i, price, amt / 6, cap + population + offset, + citymax + population, 0, amt ); markets.push_back(m); } @@ -806,14 +820,14 @@ void ARegion::AddTown() void ARegion::AddTown(AString * tname) { int size = DetermineTownSize(); - AddTown(size, tname); + AddTown(size, tname); } /* Create a town of given Town Type */ void ARegion::AddTown(int size) { AString *tname = new AString(AGetNameString(AGetName(1, this))); - AddTown(size, tname); + AddTown(size, tname); } /* Create a town of specific type with name @@ -859,10 +873,10 @@ void ARegion::SetTownType(int level) town->hab = TownHabitat(); town->pop = town->hab * 2 / 3; town->dev = TownDevelopment(); - + // Sanity check if ((level < TOWN_VILLAGE) || (level > TOWN_CITY)) return; - + // increment values int poptown = getrandom((level -1) * (level -1) * Globals->CITY_POP/12) + level * level * Globals->CITY_POP/12; town->hab += poptown; @@ -890,7 +904,7 @@ void ARegion::SetTownType(int level) int popdecr = getrandom(Globals->CITY_POP/3) + getrandom(Globals->CITY_POP/3); // don't depopulate while ((town->pop < popdecr) || (town->hab < popdecr)) { - popdecr = popdecr / 2; + popdecr = popdecr / 2; } town->hab -= popdecr; town->pop = town->hab * 2 / 3; @@ -906,7 +920,7 @@ void ARegion::UpdateEditRegion() // redo markets and entertainment/tax income for extra people. SetIncome(); for (auto& m : markets) m->post_turn(Population(), Wages()); - + //Replace man selling markets.erase( remove_if(markets.begin(), markets.end(), [](const Market * m) { return ItemDefs[m->item].type & IT_MAN; }), @@ -915,15 +929,19 @@ void ARegion::UpdateEditRegion() float ratio = ItemDefs[race].baseprice / (float) (Globals->BASE_MAN_COST * 10); // hack: include wage factor of 10 in float calculation above - Market *m = new Market(Market::M_BUY, race, (int)(Wages() * 4 * ratio), Population()/ 25, 0, 10000, 0, 2000); + Market *m = new Market( + Market::MarketType::M_BUY, race, (int)(Wages() * 4 * ratio), Population()/ 25, 0, 10000, 0, 2000 + ); markets.push_back(m); if (Globals->LEADERS_EXIST) { ratio = ItemDefs[I_LEADERS].baseprice / (float) (Globals->BASE_MAN_COST * 10); // hack: include wage factor of 10 in float calculation above - m = new Market(Market::M_BUY, I_LEADERS, (int)(Wages() * 4 * ratio), Population() / 125, 0, 10000, 0, 400); + m = new Market( + Market::MarketType::M_BUY, I_LEADERS, (int)(Wages() * 4 * ratio), Population() / 125, 0, 10000, 0, 400 + ); markets.push_back(m); - } + } } void ARegion::SetupEditRegion() @@ -937,7 +955,7 @@ void ARegion::SetupEditRegion() int pop = typer->pop; int mw = typer->wages; - + // fix economy when MAINTENANCE_COST has been adjusted mw += Globals->MAINTENANCE_COST - 10; if (mw < 0) mw = 0; @@ -979,7 +997,7 @@ void ARegion::SetupEditRegion() basepopulation = habitat / 3; // hmm... somewhere not too far off equilibrium pop population = habitat * (60 + getrandom(6) + getrandom(6)) / 100; - + // Setup development int level = 1; development = 1; @@ -1033,13 +1051,17 @@ void ARegion::SetupEditRegion() float ratio = ItemDefs[race].baseprice / ((float)Globals->BASE_MAN_COST * 10); // hack: include wage factor of 10 in float assignment above // Setup Recruiting - Market *m = new Market(Market::M_BUY, race, (int)(Wages() * 4 * ratio), Population() / 25, 0, 10000, 0, 2000); + Market *m = new Market( + Market::MarketType::M_BUY, race, (int)(Wages() * 4 * ratio), Population() / 25, 0, 10000, 0, 2000 + ); markets.push_back(m); if (Globals->LEADERS_EXIST) { ratio = ItemDefs[I_LEADERS].baseprice / ((float)Globals->BASE_MAN_COST * 10); // hack: include wage factor of 10 in float assignment above - m = new Market(Market::M_BUY, I_LEADERS, (int)(Wages() * 4 * ratio), Population() / 125, 0, 10000, 0, 400); + m = new Market( + Market::MarketType::M_BUY, I_LEADERS, (int)(Wages() * 4 * ratio), Population() / 125, 0, 10000, 0, 400 + ); markets.push_back(m); } } @@ -1083,7 +1105,7 @@ int ARegion::BaseDev() prev = 0; } } - + basedev = (Globals->MAINTENANCE_COST + basedev) / 2; return basedev; } @@ -1131,14 +1153,14 @@ int ARegion::TownHabitat() if (temple) build++; if (caravan) build++; if (build > 2) build = 2; - + build++; hab = (build * build + 1) * hab * hab + habitat / 4 + 50; - + // Effect of town development on habitat: int totalhab = hab + (TownDevelopment() * (habitat + 800 + hab + Globals->CITY_POP / 2)) / 100; - + return totalhab; } @@ -1184,9 +1206,9 @@ int ARegion::TownDevelopment() int df = development - basedev; if (df < 0) df = 0; if (df > 100) df = 100; - + return df; -} +} // Checks the growth potential of towns // and cancels unlimited markets for Starting Cities @@ -1202,7 +1224,7 @@ int ARegion::TownGrowth() int tot = 0; for (const auto& m : markets) { if (Population() > m->minpop) { - if (m->type == Market::M_BUY) { + if (m->type == Market::MarketType::M_BUY) { if (ItemDefs[m->item].type & IT_TRADE) { amt += 5 * m->activity; tot += 5 * m->maxamt; @@ -1225,12 +1247,12 @@ int ARegion::TownGrowth() } } } - + if (amt > tot) amt = tot; if (tot) { tarpop += (Globals->CITY_POP * amt) / tot; - } + } // Let's bump tarpop up // tarpop = (tarpop * 5) / 4; if (tarpop > Globals->CITY_POP) tarpop = Globals->CITY_POP; @@ -1261,15 +1283,15 @@ void ARegion::Grow() // We don't need to grow 0 pop regions if (basepopulation == 0) return; - // growpop is the overall population growth + // growpop is the overall population growth int growpop = 0; - + // Init migration parameters - // immigrants = entering this region, + // immigrants = entering this region, // emigrants = leaving immigrants = habitat - basepopulation; emigrants = population - basepopulation; - + // First, check regional population growth // Check resource production activity int activity = 0; @@ -1280,29 +1302,29 @@ void ARegion::Grow() // bonuses for productivity are calculated from // the _baseamount_ of all resources. // because trade structures increase the produceable - // amount and not the baseamount this creates an + // amount and not the baseamount this creates an // effective advantage for trade structures amount += p->baseamount; } } - + // Now set the target population for the hex // Ant: I'm not sure why population's being subtracted here.. // Shouldn't it be something like : // tarpop = habitat + basepopulation? int tarpop = habitat - population + basepopulation; - + // Ant: Increase tarpop for any trading that's going on? // Not sure why (habitat - basepopulation) is included if (amount) tarpop += ((habitat - basepopulation) * 2 * activity) / (3 * amount); - + // diff is the amount we can grow? int diff = tarpop - population; int adiff = abs(diff); //if (adiff < 0) adiff = adiff * (- 1); - - // Adjust basepop? + + // Adjust basepop? // raise basepop depending on production // absolute basepop increase if (diff > (basepopulation / 20)) { @@ -1315,28 +1337,28 @@ void ARegion::Grow() // lower basepop for extremely low levels of population if (population < basepopulation) { int depop = (basepopulation - population) / 4; - basepopulation -= depop + getrandom(depop); + basepopulation -= depop + getrandom(depop); } - + // debug strings //Awrite(AString("immigrants = ") + immigrants); //Awrite(AString("emigrants = ") + emigrants); //Awrite(AString("adiff = ") + adiff); //Awrite(AString("diff = ") + diff); //Awrite(AString("habitat = ") + habitat); - + // Limit excessive growth at low pop / hab ratios // and avoid overflowing // What are grow2 and grow representing? Maybe these formulae // could be broken up a bit more and commented? long int grow2 = 5 * ((long int) habitat + (3 * (long int) adiff)); //Awrite(AString("grow2 = ") + (unsigned int) grow2); // debug string - + // Ant: In the following formula, dgrow is almost always 0! long int dgrow = ((long int) adiff * (long int) habitat ) / grow2; //if (diff < 0) dgrow = dgrow * (- 1); //Awrite(AString("dgrow = ") + (unsigned int) dgrow); // debug string - + // long int dgrow = ((long int) diff) * ((long int) habitat) // / (5 * (long int) ((long int) habitat + 3 * (long int) abs(diff))); if (diff < 0) growpop -= (int) dgrow; @@ -1351,7 +1373,7 @@ void ARegion::Grow() // update emigrants - only if region has a decent population level if (emigrants > 0) emigrants += diff; - + // Now check town population growth if (town) { int maxpop = TownGrowth(); @@ -1374,14 +1396,14 @@ void ARegion::Grow() // ((2 * town->hab) - town->pop) seems clearer float increase = tgrowth * (2 * town->hab - town->pop); float limitingfactor = (10 * town->hab); - + // Ant: Not sure whether we still need the typecasts here growpop += (int) (increase / limitingfactor); } // Update population AdjustPop(growpop); - + /* Initialise the migration variables */ migdev = 0; migfrom.DeleteAll(); @@ -1395,7 +1417,7 @@ void ARegion::FindMigrationDestination(int round) { // is emigration possible? if (emigrants < 0) return; - + int maxattract = 0; ARegion *target = this; // Check all hexes within 2 hexes @@ -1425,11 +1447,11 @@ void ARegion::FindMigrationDestination(int round) target = nb2; maxattract = ma; } - } + } } // do we have a target? if (target == this) return; - + // then add this region to the target's migfrom list ARegion *self = this; target->migfrom.Add(self); @@ -1441,7 +1463,7 @@ int ARegion::MigrationAttractiveness(int homedev, int range, int round) int attractiveness = 0; int mdev = development; /* Is there enough immigration capacity? */ - if (immigrants < 100) return 0; + if (immigrants < 100) return 0; /* on the second round, consider as a mid-way target */ if (round > 1) mdev = migdev; /* minimum development difference 8 x range */ @@ -1461,8 +1483,8 @@ int ARegion::MigrationAttractiveness(int homedev, int range, int round) } /* attractiveness due to development */ attractiveness += (int) (space * ((float) 100 * (mdev - homedev) / homedev + entertain)); - - return attractiveness; + + return attractiveness; } /* Performs migration for each region with a migration @@ -1479,16 +1501,16 @@ void ARegion::Migrate() totalmig += r->emigrants; } } - + // is there any migration to perform? if (totalmig == 0) return; - + // do each migration int totalimm = 0; forlist(&migfrom) { ARegion *r = (ARegion *) elem; if (!r) continue; - + // figure range int xdist = r->xloc - xloc; if (xdist < 0) xdist = - xdist; @@ -1496,7 +1518,7 @@ void ARegion::Migrate() if (ydist < 0) ydist = - ydist; ydist = (ydist - xdist) / 2; int range = xdist + ydist; - + // sanity check - huh? if (range < 1) continue; int migrants = (int) (immigrants * ((float) (r->emigrants / totalmig))); @@ -1512,7 +1534,7 @@ void ARegion::Migrate() r->emigrants -= migrants; totalimm += migrants; AString wout = AString("Migrating from ") /* + (r->name) + " in " */ + r->xloc - + "," + (r->yloc) + " to " /* + name + " in " */ + (xloc) + "," + yloc + + "," + (r->yloc) + " to " /* + name + " in " */ + (xloc) + "," + yloc + ": " + migrants + " migrants."; Awrite(wout); // set the region's mid-way migration development @@ -1532,7 +1554,7 @@ void ARegion::PostTurn(ARegionList *pRegs) if (Globals->DECAY) { DoDecayCheck(pRegs); } - + /* Development increase due to player activity */ // scale improvement float imp1 = improvement / 25; @@ -1547,7 +1569,7 @@ void ARegion::PostTurn(ARegionList *pRegs) for (int a=0; a<3; a++) if (getrandom(progress) < diff) development++; if (development > maxdevelopment) maxdevelopment = development; } - + /* Development increase for very poor regions */ int recoveryRounds = 1 + earthlore + clearskies; @@ -1555,13 +1577,13 @@ void ARegion::PostTurn(ARegionList *pRegs) while (recoveryRounds-- > 0) { if (maxdevelopment > development) { - if (getrandom(maxdevelopment) > development) development++; + if (getrandom(maxdevelopment) > development) development++; } if (maxdevelopment > development) { - if (getrandom(maxdevelopment) > development) development++; + if (getrandom(maxdevelopment) > development) development++; } if (maxdevelopment > development) { - if (getrandom(3) == 1) development++; + if (getrandom(3) == 1) development++; } } @@ -1583,13 +1605,14 @@ void ARegion::PostTurn(ARegionList *pRegs) float ratio = ItemDefs[race].baseprice / (float) (Globals->BASE_MAN_COST * 10); // Setup Recruiting Market *m = new Market( - Market::M_BUY, race, (int)(Wages() * 4 * ratio), Population() / 25, 0, 10000, 0, 2000 + Market::MarketType::M_BUY, race, (int)(Wages() * 4 * ratio), Population() / 25, 0, 10000, 0, 2000 ); markets.push_back(m); if (Globals->LEADERS_EXIST) { ratio = ItemDefs[I_LEADERS].baseprice / (float)Globals->BASE_MAN_COST; m = new Market( - Market::M_BUY, I_LEADERS, (int)(Wages() * 4 * ratio), Population() / 125, 0, 10000, 0, 400 + Market::MarketType::M_BUY, I_LEADERS, (int)(Wages() * 4 * ratio), Population() / 125, + 0, 10000, 0, 400 ); markets.push_back(m); } @@ -1600,7 +1623,7 @@ void ARegion::PostTurn(ARegionList *pRegs) if (type != R_NEXUS) { SetIncome(); } - + /* update markets */ for (auto& m : markets) m->post_turn(Population(), Wages()); diff --git a/edit.cpp b/edit.cpp index e6bd1934..11b0f636 100644 --- a/edit.cpp +++ b/edit.cpp @@ -41,7 +41,7 @@ int Game::EditGame(int *pSaveGame) } else if (*pStr == "2") { EditGameFindUnit(); } else if (*pStr == "3") { - EditGameCreateUnit(); + EditGameCreateUnit(); } else { Awrite("Select from the menu."); } @@ -120,97 +120,97 @@ void Game::EditGameFindUnit() void Game::EditGameRegion(ARegion *pReg) //copied direct from AtlantisDev 030730 post -{ +{ do { Awrite( AString("Region ") + pReg->num + ": " + - pReg->Print() ); - Awrite( " 1) Edit objects..." ); + pReg->Print() ); + Awrite( " 1) Edit objects..." ); Awrite( " 2) Edit terrain..." ); - Awrite( " q) Return to previous menu." ); + Awrite( " q) Return to previous menu." ); - int exit = 0; - AString *pStr = AGetString(); + int exit = 0; + AString *pStr = AGetString(); if ( *pStr == "1" ) { - EditGameRegionObjects( pReg ); - } + EditGameRegionObjects( pReg ); + } else if ( *pStr == "2" ) { - EditGameRegionTerrain( pReg ); - } + EditGameRegionTerrain( pReg ); + } else if ( *pStr == "q" ) { - exit = 1; - } + exit = 1; + } else { - Awrite( "Select from the menu." ); - } - if (pStr) delete pStr; + Awrite( "Select from the menu." ); + } + if (pStr) delete pStr; if ( exit ) { - break; - } - } - while( 1 ); -} + break; + } + } + while( 1 ); +} /* RegionEdit Patch 030829 BS */ -void Game::EditGameRegionObjects( ARegion *pReg ) +void Game::EditGameRegionObjects( ARegion *pReg ) //template copied from AtlantisDev 030730 post. Modified option a, added option h, m. -{ +{ do { - Awrite( AString( "Region: " ) + pReg->ShortPrint() ); - Awrite( "" ); - int i = 0; + Awrite( AString( "Region: " ) + pReg->ShortPrint() ); + Awrite( "" ); + int i = 0; AString temp = AString(""); - forlist (&(pReg->objects)) { - Object * obj = (Object *)elem; + forlist (&(pReg->objects)) { + Object * obj = (Object *)elem; temp = AString ((AString(i) + ". " + *obj->name + " : " + ObjectDefs[obj->type].name)); -// if (Globals->HEXSIDE_TERRAIN && obj->hexside>-1) temp += AString( AString(" (side:") + DirectionAbrs[obj->hexside] + ")."); +// if (Globals->HEXSIDE_TERRAIN && obj->hexside>-1) temp += AString( AString(" (side:") + DirectionAbrs[obj->hexside] + ")."); Awrite(temp); - i++; - } - Awrite( "" ); - - Awrite( " [a] [object type] [dir] to add object" ); - Awrite( " [d] [index] to delete object" ); -// if (Globals->HEXSIDE_TERRAIN) Awrite( " [h] [index] [dir] to change the hexside of an object" ); - Awrite( " [n] [index] [name] to rename object" ); + i++; + } + Awrite( "" ); + + Awrite( " [a] [object type] [dir] to add object" ); + Awrite( " [d] [index] to delete object" ); +// if (Globals->HEXSIDE_TERRAIN) Awrite( " [h] [index] [dir] to change the hexside of an object" ); + Awrite( " [n] [index] [name] to rename object" ); // if (Globals->HEXSIDE_TERRAIN) Awrite( " [m] [index] to add/delete a mirrored object" ); - Awrite( " q) Return to previous menu." ); - - int exit = 0; - AString *pStr = AGetString(); - if ( *pStr == "q" ) { - exit = 1; - } else { - AString *pToken = 0; - do { - pToken = pStr->gettoken(); - if ( !pToken ) { - Awrite( "Try again." ); - break; - } - - // add object - if (*pToken == "a") { - SAFE_DELETE( pToken ); - pToken = pStr->gettoken(); - if ( !pToken ) { - Awrite( "Try again." ); - break; - } - - int objType = ParseObject(pToken, 0); - if ( (objType == -1) || (ObjectDefs[objType].flags & ObjectType::DISABLED) ) { - Awrite( "No such object." ); - break; - } - SAFE_DELETE( pToken ); - + Awrite( " q) Return to previous menu." ); + + int exit = 0; + AString *pStr = AGetString(); + if ( *pStr == "q" ) { + exit = 1; + } else { + AString *pToken = 0; + do { + pToken = pStr->gettoken(); + if ( !pToken ) { + Awrite( "Try again." ); + break; + } + + // add object + if (*pToken == "a") { + SAFE_DELETE( pToken ); + pToken = pStr->gettoken(); + if ( !pToken ) { + Awrite( "Try again." ); + break; + } + + int objType = ParseObject(pToken, 0); + if ( (objType == -1) || (ObjectDefs[objType].flags & ObjectType::DISABLED) ) { + Awrite( "No such object." ); + break; + } + SAFE_DELETE( pToken ); + /* int dir=-1; if (ObjectDefs[objType].hexside && Globals->HEXSIDE_TERRAIN ) { if (!ObjectIsShip(objType) || !(TerrainDefs[pReg->type].similar_type == R_OCEAN) ) { - pToken = pStr->gettoken(); + pToken = pStr->gettoken(); if (!pToken) { Awrite( "Specify direction" ); break; @@ -223,91 +223,91 @@ void Game::EditGameRegionObjects( ARegion *pReg ) } } */ - - Object *o = new Object(pReg); - o->type = objType; - o->incomplete = 0; - o->inner = -1; + + Object *o = new Object(pReg); + o->type = objType; + o->incomplete = 0; + o->inner = -1; // o->hexside = dir; - if (o->IsFleet()) { - o->num = shipseq++; - o->name = new AString(AString("Fleet") + " [" + o->num + "]"); - } - else { - o->num = pReg->buildingseq++; - o->name = new AString(AString("Building") + " [" + o->num + "]"); - } - pReg->objects.Add(o); - } - // delete object - else if (*pToken == "d") { - SAFE_DELETE( pToken ); - - pToken = pStr->gettoken(); - if ( !pToken ) { - Awrite( "Try again." ); - break; - } - - int index = pToken->value(); + if (o->IsFleet()) { + o->num = shipseq++; + o->name = new AString(AString("Fleet") + " [" + o->num + "]"); + } + else { + o->num = pReg->buildingseq++; + o->name = new AString(AString("Building") + " [" + o->num + "]"); + } + pReg->objects.Add(o); + } + // delete object + else if (*pToken == "d") { + SAFE_DELETE( pToken ); + + pToken = pStr->gettoken(); + if ( !pToken ) { + Awrite( "Try again." ); + break; + } + + int index = pToken->value(); if ( (index < 0) || (index >= pReg->objects.Num()) ) { //modified minimum to <0 to allow deleting object 0. 030824 BS - Awrite( "Incorrect index." ); - break; - } - SAFE_DELETE( pToken ); - - int i = 0; - AListElem *tmp = pReg->objects.First(); - for (i = 0; i < index; i++) tmp = pReg->objects.Next(tmp); - pReg->objects.Remove(tmp); - } + Awrite( "Incorrect index." ); + break; + } + SAFE_DELETE( pToken ); + + int i = 0; + AListElem *tmp = pReg->objects.First(); + for (i = 0; i < index; i++) tmp = pReg->objects.Next(tmp); + pReg->objects.Remove(tmp); + } //hexside change - /* else if (*pToken == "h") { - SAFE_DELETE( pToken ); - - pToken = pStr->gettoken(); - if ( !pToken ) { - Awrite( "Try again." ); - break; - } - - int index = pToken->value(); - if ( (index < 1) || (index >= pReg->objects.Num()) ) { - Awrite( "Incorrect index." ); - break; - } - SAFE_DELETE( pToken ); - - int i = 0; - Object *tmp = (Object *)pReg->objects.First(); - for (i = 0; i < index; i++) tmp = (Object *)pReg->objects.Next(tmp); - + /* else if (*pToken == "h") { + SAFE_DELETE( pToken ); + + pToken = pStr->gettoken(); + if ( !pToken ) { + Awrite( "Try again." ); + break; + } + + int index = pToken->value(); + if ( (index < 1) || (index >= pReg->objects.Num()) ) { + Awrite( "Incorrect index." ); + break; + } + SAFE_DELETE( pToken ); + + int i = 0; + Object *tmp = (Object *)pReg->objects.First(); + for (i = 0; i < index; i++) tmp = (Object *)pReg->objects.Next(tmp); + if (!(ObjectDefs[tmp->type].hexside)) { Awrite("Not a hexside object."); break; } - + if (!Globals->HEXSIDE_TERRAIN) { Awrite("Hexside terrain disabled under game rules."); break; } - + pToken = pStr->gettoken(); - if ( !pToken ) { - Awrite( "Specify Direction." ); - break; - } - + if ( !pToken ) { + Awrite( "Specify Direction." ); + break; + } + int dir=-1; dir = ParseHexside(pToken); if (dir==-1) { Awrite("Incorrect direction. Use N,NE,SE,S,SW,NW"); break; } - - SAFE_DELETE(pToken); - if (dir) { - tmp->hexside = dir; + + SAFE_DELETE(pToken); + if (dir) { + tmp->hexside = dir; if (tmp->mirror) { // reset mirrors, else problems later tmp->mirror->mirror = NULL; tmp->mirror->mirrornum = -1; @@ -318,35 +318,35 @@ void Game::EditGameRegionObjects( ARegion *pReg ) } } //mirror change - else if (*pToken == "m") { - SAFE_DELETE( pToken ); - - pToken = pStr->gettoken(); - if ( !pToken ) { - Awrite( "Try again." ); - break; - } - - int index = pToken->value(); - if ( (index < 1) || (index >= pReg->objects.Num()) ) { - Awrite( "Incorrect index." ); - break; - } - SAFE_DELETE( pToken ); - - int i = 0; - Object *tmp = (Object *)pReg->objects.First(); - for (i = 0; i < index; i++) tmp = (Object *)pReg->objects.Next(tmp); - + else if (*pToken == "m") { + SAFE_DELETE( pToken ); + + pToken = pStr->gettoken(); + if ( !pToken ) { + Awrite( "Try again." ); + break; + } + + int index = pToken->value(); + if ( (index < 1) || (index >= pReg->objects.Num()) ) { + Awrite( "Incorrect index." ); + break; + } + SAFE_DELETE( pToken ); + + int i = 0; + Object *tmp = (Object *)pReg->objects.First(); + for (i = 0; i < index; i++) tmp = (Object *)pReg->objects.Next(tmp); + // if has a mirror, delete the mirror if (tmp->mirror) { // Awrite(AString(AString("Mirror ") + tmp->mirror->name + " deleted.")); Awrite("Mirror deleted"); - tmp->mirror->region->objects.Remove(tmp->mirror); + tmp->mirror->region->objects.Remove(tmp->mirror); tmp->mirror == NULL; tmp->mirrornum == -1; } - + else { if (!(ObjectDefs[tmp->type].hexside)) { Awrite("Not a hexside object."); @@ -355,21 +355,21 @@ void Game::EditGameRegionObjects( ARegion *pReg ) if (tmp->hexside < 0) { Awrite("Object not on a hexside."); break; - } + } if (tmp->IsFleet()) { Awrite("Fleets cannot be mirrored."); break; - } + } if (!Globals->HEXSIDE_TERRAIN) { Awrite("Hexside terrain disabled under game rules."); break; } - + if (!pReg->neighbors[tmp->hexside]) { Awrite("No neighbouring region."); break; } - + Object *o = new Object(pReg->neighbors[tmp->hexside]); o->num = pReg->neighbors[tmp->hexside]->buildingseq++; o->type = ObjectDefs[tmp->type].mirror; @@ -380,72 +380,72 @@ void Game::EditGameRegionObjects( ARegion *pReg ) o->mirrornum = tmp->num; o->mirror = tmp; pReg->neighbors[tmp->hexside]->objects.Add(o); - + tmp->mirrornum = o->num; - tmp->mirror = o; - Awrite("Mirror added"); + tmp->mirror = o; + Awrite("Mirror added"); } } */ - // rename object - else if (*pToken == "n") { - SAFE_DELETE( pToken ); - - pToken = pStr->gettoken(); - if ( !pToken ) { - Awrite( "Try again." ); - break; - } - - int index = pToken->value(); - if ( (index < 1) || (index >= pReg->objects.Num()) ) { - Awrite( "Incorrect index." ); - break; - } - SAFE_DELETE( pToken ); - - pToken = pStr->gettoken(); - if ( !pToken ) { - Awrite( "No name given." ); - break; - } - - int i = 0; - Object *tmp = (Object *)pReg->objects.First(); - for (i = 0; i < index; i++) tmp = (Object *)pReg->objects.Next(tmp); - - AString * newname = pToken->getlegal(); - SAFE_DELETE(pToken); - if (newname) { - delete tmp->name; - *newname += AString(" [") + tmp->num + "]"; - tmp->name = newname; - } - } - - } while( 0 ); - if (pToken) delete pToken; - } - if (pStr) delete pStr; - - if (exit) { - break; - } - } - while( 1 ); -} - -void Game::EditGameRegionTerrain( ARegion *pReg ) -{ + // rename object + else if (*pToken == "n") { + SAFE_DELETE( pToken ); + + pToken = pStr->gettoken(); + if ( !pToken ) { + Awrite( "Try again." ); + break; + } + + int index = pToken->value(); + if ( (index < 1) || (index >= pReg->objects.Num()) ) { + Awrite( "Incorrect index." ); + break; + } + SAFE_DELETE( pToken ); + + pToken = pStr->gettoken(); + if ( !pToken ) { + Awrite( "No name given." ); + break; + } + + int i = 0; + Object *tmp = (Object *)pReg->objects.First(); + for (i = 0; i < index; i++) tmp = (Object *)pReg->objects.Next(tmp); + + AString * newname = pToken->getlegal(); + SAFE_DELETE(pToken); + if (newname) { + delete tmp->name; + *newname += AString(" [") + tmp->num + "]"; + tmp->name = newname; + } + } + + } while( 0 ); + if (pToken) delete pToken; + } + if (pStr) delete pStr; + + if (exit) { + break; + } + } + while( 1 ); +} + +void Game::EditGameRegionTerrain( ARegion *pReg ) +{ do { - Awrite(""); - Awrite( AString( "Region: " ) + pReg->Print() ); - Awrite( "" ); + Awrite(""); + Awrite( AString( "Region: " ) + pReg->Print() ); + Awrite( "" ); // write pop stuff Awrite( AString("") + pReg->population + " " + ItemDefs[pReg->race].names + " basepop"); if (pReg->town) Awrite( AString("") + pReg->town->pop + " " + ItemDefs[pReg->race].names + " townpop"); Awrite( AString("") + pReg->Population() + " " + ItemDefs[pReg->race].names + " totalpop"); - + // write wages Awrite(AString("Wages: ") + pReg->WagesForReport() + "."); Awrite(AString("Maxwages: ") + pReg->maxwages + "."); @@ -480,7 +480,7 @@ void Game::EditGameRegionTerrain( ARegion *pReg ) if (has==0) temp += "none"; temp += "."; Awrite(temp); - Awrite( "" ); + Awrite( "" ); if (Globals->GATES_EXIST && pReg->gate && pReg->gate != -1) { Awrite(AString("There is a Gate here (Gate ") + pReg->gate + @@ -491,67 +491,67 @@ void Game::EditGameRegionTerrain( ARegion *pReg ) } - Awrite( " [t] [terrain type] to modify terrain type" ); + Awrite( " [t] [terrain type] to modify terrain type" ); Awrite( " [r] [race] to modify local race" ); Awrite( " (use none, None or 0 to unset)" ); Awrite( " [w] [maxwages] to modify local wages" ); - Awrite( " [p] to regenerate products according to terrain type" ); + Awrite( " [p] to regenerate products according to terrain type" ); Awrite( " [g] to regenerate all according to terrain type" ); if (pReg->gate > 0) Awrite( " [dg] to delete the gate in this region" ); else Awrite( " [ag] to add a gate to this region" ); Awrite( " [n] [name] to modify region name" ); if (pReg->town) { - Awrite( " [town] to regenerate a town" ); + Awrite( " [town] to regenerate a town" ); Awrite( " [deltown] to remove a town" ); Awrite( " [tn] [name] to rename a town" ); Awrite( " [v] to view/modify town markets" ); - } else Awrite( " [town] to add a town" ); - Awrite( " q) Return to previous menu." ); - - int exit = 0; - AString *pStr = AGetString(); - if ( *pStr == "q" ) { - exit = 1; - } else { - AString *pToken = 0; - do { - pToken = pStr->gettoken(); - if ( !pToken ) { - Awrite( "Try again." ); - break; - } + } else Awrite( " [town] to add a town" ); + Awrite( " q) Return to previous menu." ); + + int exit = 0; + AString *pStr = AGetString(); + if ( *pStr == "q" ) { + exit = 1; + } else { + AString *pToken = 0; + do { + pToken = pStr->gettoken(); + if ( !pToken ) { + Awrite( "Try again." ); + break; + } // modify terrain - if (*pToken == "t") { - SAFE_DELETE( pToken ); - pToken = pStr->gettoken(); - if ( !pToken ) { - Awrite( "Try again." ); - break; - } + if (*pToken == "t") { + SAFE_DELETE( pToken ); + pToken = pStr->gettoken(); + if ( !pToken ) { + Awrite( "Try again." ); + break; + } int terType = ParseTerrain(pToken); - if (terType == -1) { - Awrite( "No such terrain." ); - break; - } - SAFE_DELETE( pToken ); - + if (terType == -1) { + Awrite( "No such terrain." ); + break; + } + SAFE_DELETE( pToken ); + pReg->type = terType; - } - else if (*pToken == "r") { - SAFE_DELETE( pToken ); - pToken = pStr->gettoken(); - if ( !pToken ) { - Awrite( "Try again." ); - break; - } + } + else if (*pToken == "r") { + SAFE_DELETE( pToken ); + pToken = pStr->gettoken(); + if ( !pToken ) { + Awrite( "Try again." ); + break; + } int prace = 0; prace = ParseAllItems(pToken); if (!(ItemDefs[prace].type & IT_MAN) || (ItemDefs[prace].flags & ItemType::DISABLED) ) { if (!(*pToken == "none" || *pToken == "None" || *pToken == "0")) { - Awrite( "No such race." ); + Awrite( "No such race." ); break; } else { prace = -1; @@ -561,8 +561,8 @@ void Game::EditGameRegionTerrain( ARegion *pReg ) pReg->UpdateEditRegion(); SAFE_DELETE( pToken ); } - else if (*pToken == "dg") { - SAFE_DELETE( pToken ); + else if (*pToken == "dg") { + SAFE_DELETE( pToken ); if (Globals->DISPERSE_GATE_NUMBERS) { pReg->gate = 0; regions.numberofgates--; @@ -582,7 +582,7 @@ void Game::EditGameRegionTerrain( ARegion *pReg ) } } } - else if (*pToken == "ag") { + else if (*pToken == "ag") { SAFE_DELETE( pToken ); if (pReg->gate > 0) break; regions.numberofgates++; @@ -622,15 +622,15 @@ void Game::EditGameRegionTerrain( ARegion *pReg ) } pReg->gate = gatenum; } - pReg->gatemonth = getrandom(12); + pReg->gatemonth = getrandom(12); } else if (*pToken == "w") { SAFE_DELETE( pToken ); - pToken = pStr->gettoken(); - if ( !pToken ) { - Awrite( "Try again." ); - break; - } + pToken = pStr->gettoken(); + if ( !pToken ) { + Awrite( "Try again." ); + break; + } int val = pToken->value(); SAFE_DELETE( pToken ); if (val) { @@ -639,8 +639,8 @@ void Game::EditGameRegionTerrain( ARegion *pReg ) pReg->wages += change; } pReg->UpdateEditRegion(); - } - else if (*pToken == "p") { + } + else if (*pToken == "p") { SAFE_DELETE(pToken); auto removes = remove_if( pReg->products.begin(), @@ -650,8 +650,8 @@ void Game::EditGameRegionTerrain( ARegion *pReg ) for_each (removes, pReg->products.end(), [](Production *p) mutable { delete p; }); pReg->products.erase(removes, pReg->products.end()); pReg->SetupProds(1); - } - else if (*pToken == "g") { + } + else if (*pToken == "g") { SAFE_DELETE(pToken); if (pReg->town) delete pReg->town; @@ -665,35 +665,35 @@ void Game::EditGameRegionTerrain( ARegion *pReg ) pReg->markets.clear(); // empty the vector. pReg->SetupEditRegion(); - pReg->UpdateEditRegion(); + pReg->UpdateEditRegion(); } - else if (*pToken == "n") { + else if (*pToken == "n") { SAFE_DELETE(pToken); - pToken = pStr->gettoken(); - if ( !pToken ) { - Awrite( "Try again." ); - break; - } - + pToken = pStr->gettoken(); + if ( !pToken ) { + Awrite( "Try again." ); + break; + } + *pReg->name = *pToken; - SAFE_DELETE(pToken); - } - else if (*pToken == "tn") { SAFE_DELETE(pToken); - pToken = pStr->gettoken(); - if ( !pToken ) { - Awrite( "Try again." ); - break; - } - + } + else if (*pToken == "tn") { + SAFE_DELETE(pToken); + pToken = pStr->gettoken(); + if ( !pToken ) { + Awrite( "Try again." ); + break; + } + if (pReg->town) *pReg->town->name = *pToken; - SAFE_DELETE(pToken); - } - else if (*pToken == "town") { SAFE_DELETE(pToken); - + } + else if (*pToken == "town") { + SAFE_DELETE(pToken); + if (pReg->race<0) pReg->race = 9; - + AString *townname = new AString("name"); if (pReg->town) { *townname = *pReg->town->name; @@ -702,10 +702,10 @@ void Game::EditGameRegionTerrain( ARegion *pReg ) pReg->markets.clear(); // empty the vector. } pReg->AddTown(townname); - + pReg->UpdateEditRegion(); // financial stuff! Does markets } - else if (*pToken == "deltown") { + else if (*pToken == "deltown") { SAFE_DELETE(pToken); if (pReg->town) { delete pReg->town; @@ -720,34 +720,34 @@ void Game::EditGameRegionTerrain( ARegion *pReg ) if (pReg->town) EditGameRegionMarkets(pReg); } } - while( 0 ); - if (pToken) delete pToken; - } - if (pStr) delete pStr; - - if ( exit ) { - break; - } - } - while( 1 ); -} + while( 0 ); + if (pToken) delete pToken; + } + if (pStr) delete pStr; + + if ( exit ) { + break; + } + } + while( 1 ); +} void Game::EditGameRegionMarkets( ARegion *pReg ) { /* This only gets called if pReg->town exists! */ do { - Awrite(""); + Awrite(""); Awrite( AString( "Region: " ) + pReg->Print() ); - Awrite( "" ); + Awrite( "" ); // write pop stuff Awrite( AString("") + pReg->town->pop + " " + ItemDefs[pReg->race].names + " townpop"); - + //write markets Awrite(AString("Market Format: ... price(base). minpop/maxpop. minamt/maxamt.")); Awrite("Wanted: "); for (const auto &m : pReg->markets) { - if (m->type == Market::M_SELL) { + if (m->type == Market::MarketType::M_SELL) { AString temp = AString(ItemString(m->item, m->amount)) + " at $" + m->price + "(" + m->baseprice + ")."; temp += AString(" Pop: ") + m->minpop + "/" + m->maxpop + "."; temp += AString(" Amount: ") + m->minamt + "/" + m->maxamt + "."; @@ -756,7 +756,7 @@ void Game::EditGameRegionMarkets( ARegion *pReg ) } Awrite("For Sale: "); for (const auto &m : pReg->markets) { - if (m->type == Market::M_BUY) { + if (m->type == Market::MarketType::M_BUY) { AString temp = AString(ItemString(m->item, m->amount)) + " at $" + m->price + "(" + m->baseprice + ")."; temp += AString(" Pop: ") + m->minpop + "/" + m->maxpop + "."; temp += AString(" Amount: ") + m->minamt + "/" + m->maxamt + "."; @@ -764,31 +764,31 @@ void Game::EditGameRegionMarkets( ARegion *pReg ) } } - Awrite( "" ); + Awrite( "" ); - Awrite( " [g] to regenerate all markets" ); - Awrite( " [p] [item] [minpop] [maxpop] to add/modify market population" ); + Awrite( " [g] to regenerate all markets" ); + Awrite( " [p] [item] [minpop] [maxpop] to add/modify market population" ); Awrite( " [a] [item] [minamt] [maxamt] to add/modify market amounts" ); Awrite( " [c] [item] [price] [baseprice] to add/modify item prices" ); Awrite( " [s] [item] to swap an item between wanted and sold" ); Awrite( " [d] [item] to delete an item from the market" ); - Awrite( " q) Return to previous menu." ); - - int exit = 0; - AString *pStr = AGetString(); - if ( *pStr == "q" ) { - exit = 1; - } else { - AString *pToken = 0; + Awrite( " q) Return to previous menu." ); + + int exit = 0; + AString *pStr = AGetString(); + if ( *pStr == "q" ) { + exit = 1; + } else { + AString *pToken = 0; do { - pToken = pStr->gettoken(); - if ( !pToken ) { - Awrite( "Try again." ); - break; - } + pToken = pStr->gettoken(); + if ( !pToken ) { + Awrite( "Try again." ); + break; + } // regenerate markets - if (*pToken == "g") { + if (*pToken == "g") { SAFE_DELETE(pToken); for (auto& m : pReg->markets) delete m; // Free the allocated object @@ -797,14 +797,14 @@ void Game::EditGameRegionMarkets( ARegion *pReg ) pReg->SetupCityMarket(); pReg->UpdateEditRegion(); } - else if (*pToken == "p") { + else if (*pToken == "p") { SAFE_DELETE(pToken); - - pToken = pStr->gettoken(); - if ( !pToken ) { - Awrite( "Try again." ); - break; - } + + pToken = pStr->gettoken(); + if ( !pToken ) { + Awrite( "Try again." ); + break; + } int mitem = ParseEnabledItem(pToken); if (mitem<0) { Awrite("No such item"); @@ -812,23 +812,23 @@ void Game::EditGameRegionMarkets( ARegion *pReg ) } SAFE_DELETE( pToken ); - pToken = pStr->gettoken(); + pToken = pStr->gettoken(); int minimum = pToken->value(); SAFE_DELETE( pToken ); - - pToken = pStr->gettoken(); + + pToken = pStr->gettoken(); int maximum = pToken->value(); SAFE_DELETE( pToken ); int done = 0; - + if (minimum + 1 > maximum) { Awrite("Maximum must be more than minimum"); break; } int population = pReg->Population(); - + for (auto& m : pReg->markets) { if (m->item == mitem) { m->minpop = minimum; @@ -851,19 +851,19 @@ void Game::EditGameRegionMarkets( ARegion *pReg ) if (!done) { int price = (ItemDefs[mitem].baseprice * (100 + getrandom(50))) / 100; - Market *m = new Market(Market::M_SELL, mitem, price, 0, minimum, maximum, 0, 0); + Market *m = new Market(Market::MarketType::M_SELL, mitem, price, 0, minimum, maximum, 0, 0); pReg->markets.push_back(m); } } - else if (*pToken == "a") { + else if (*pToken == "a") { SAFE_DELETE(pToken); - - pToken = pStr->gettoken(); - if ( !pToken ) { - Awrite( "Try again." ); - break; - } + + pToken = pStr->gettoken(); + if ( !pToken ) { + Awrite( "Try again." ); + break; + } int mitem = ParseEnabledItem(pToken); if (mitem<0) { Awrite("No such item"); @@ -871,28 +871,28 @@ void Game::EditGameRegionMarkets( ARegion *pReg ) } SAFE_DELETE( pToken ); - pToken = pStr->gettoken(); + pToken = pStr->gettoken(); int minimum = pToken->value(); SAFE_DELETE( pToken ); - - pToken = pStr->gettoken(); + + pToken = pStr->gettoken(); int maximum = pToken->value(); SAFE_DELETE( pToken ); int done = 0; - + if (minimum + 1 > maximum) { Awrite("Maximum must be more than minimum"); break; } - + int population = pReg->Population(); - + for (auto& m: pReg->markets) { if (m->item == mitem) { m->minamt = minimum; m->maxamt = maximum; - + if (population <= m->minpop) m->amount = m->minamt; else { @@ -911,19 +911,21 @@ void Game::EditGameRegionMarkets( ARegion *pReg ) if (!done) { int price = (ItemDefs[mitem].baseprice * (100 + getrandom(50))) / 100; int mamount = minimum + (maximum * population / 5000); - Market *m = new Market(Market::M_SELL, mitem, price, mamount, 0, 5000, minimum, maximum); + Market *m = new Market( + Market::MarketType::M_SELL, mitem, price, mamount, 0, 5000, minimum, maximum + ); pReg->markets.push_back(m); } } - else if (*pToken == "c") { + else if (*pToken == "c") { SAFE_DELETE(pToken); - - pToken = pStr->gettoken(); - if ( !pToken ) { - Awrite( "Try again." ); - break; - } + + pToken = pStr->gettoken(); + if ( !pToken ) { + Awrite( "Try again." ); + break; + } int mitem = ParseEnabledItem(pToken); if (mitem<0) { Awrite("No such item"); @@ -931,11 +933,11 @@ void Game::EditGameRegionMarkets( ARegion *pReg ) } SAFE_DELETE( pToken ); - pToken = pStr->gettoken(); + pToken = pStr->gettoken(); int price = pToken->value(); SAFE_DELETE( pToken ); - - pToken = pStr->gettoken(); + + pToken = pStr->gettoken(); int baseprice = pToken->value(); SAFE_DELETE( pToken ); @@ -954,27 +956,27 @@ void Game::EditGameRegionMarkets( ARegion *pReg ) } if (!done) { - Market *m = new Market(Market::M_SELL, mitem, price, 0, 0, 5000, 0, 0); + Market *m = new Market(Market::MarketType::M_SELL, mitem, price, 0, 0, 5000, 0, 0); m->baseprice = baseprice; pReg->markets.push_back(m); } - } - else if (*pToken == "s") { + } + else if (*pToken == "s") { SAFE_DELETE(pToken); - - pToken = pStr->gettoken(); - if ( !pToken ) { - Awrite( "Try again." ); - break; - } + + pToken = pStr->gettoken(); + if ( !pToken ) { + Awrite( "Try again." ); + break; + } int mitem = ParseEnabledItem(pToken); if (mitem<0) { Awrite("No such item"); break; } SAFE_DELETE( pToken ); - + // remove all duplicate market items of the same type. std::unordered_set s; auto dupes = remove_if( @@ -990,26 +992,30 @@ void Game::EditGameRegionMarkets( ARegion *pReg ) [mitem](const Market *m) { return m->item == mitem; } ); if (m != pReg->markets.end()) { - (*m)->type = (*m)->type == Market::M_SELL ? Market::M_BUY : Market::M_SELL; + (*m)->type = ( + (*m)->type == Market::MarketType::M_SELL + ? Market::MarketType::M_BUY + : Market::MarketType::M_SELL + ); } else { - Awrite("No such market"); + Awrite("No such market"); } } - else if (*pToken == "d") { + else if (*pToken == "d") { SAFE_DELETE(pToken); - - pToken = pStr->gettoken(); - if ( !pToken ) { - Awrite( "Try again." ); - break; - } + + pToken = pStr->gettoken(); + if ( !pToken ) { + Awrite( "Try again." ); + break; + } int mitem = ParseEnabledItem(pToken); if (mitem<0) { Awrite("No such item"); break; } SAFE_DELETE( pToken ); - + auto m = find_if( pReg->markets.begin(), pReg->markets.end(), @@ -1024,20 +1030,20 @@ void Game::EditGameRegionMarkets( ARegion *pReg ) for_each (dupes, pReg->markets.end(), [](Market *m) mutable { delete m; }); pReg->markets.erase(dupes, pReg->markets.end()); } else { - Awrite("No such market"); + Awrite("No such market"); } - } + } } - while( 0 ); - if (pToken) delete pToken; - } - if (pStr) delete pStr; - - if ( exit ) { - break; - } - } - while( 1 ); + while( 0 ); + if (pToken) delete pToken; + } + if (pStr) delete pStr; + + if ( exit ) { + break; + } + } + while( 1 ); } @@ -1051,8 +1057,8 @@ void Game::EditGameUnit(Unit *pUnit) Awrite(" 1) Edit items..."); Awrite(" 2) Edit skills..."); Awrite(" 3) Move unit..."); - Awrite(" 4) Edit details..."); - + Awrite(" 4) Edit details..."); + Awrite(" q) Stop editing this unit."); int exit = 0; @@ -1064,7 +1070,7 @@ void Game::EditGameUnit(Unit *pUnit) } else if (*pStr == "3") { EditGameUnitMove(pUnit); } else if (*pStr == "4") { - EditGameUnitDetails(pUnit); + EditGameUnitDetails(pUnit); } else if (*pStr == "q") { exit = 1; } else { @@ -1205,7 +1211,7 @@ void Game::EditGameUnitDetails(Unit *pUnit) { do { int exit = 0; - Awrite(AString("Unit: ") + *(pUnit->name)); + Awrite(AString("Unit: ") + *(pUnit->name)); Awrite(AString("Unit faction: ") + *(pUnit->faction->name)); AString temp = " ("; @@ -1221,26 +1227,26 @@ void Game::EditGameUnitDetails(Unit *pUnit) break; case U_WMON: temp += "monster"; - break; + break; case U_GUARDMAGE: temp += "guardmage"; break; case U_APPRENTICE: temp += Globals->APPRENTICE_NAME; - break; + break; } temp += ")"; Awrite(AString("Unit type: ") + pUnit->type + temp); - + Awrite(""); Awrite(" [f] [num] to change the unit's faction."); - Awrite(" [t] [num] to change the unit's type."); + Awrite(" [t] [num] to change the unit's type."); Awrite(" [q] Go back one screen."); - + AString *pStr = AGetString(); if (*pStr == "q") { exit = 1; - } + } else { AString *pToken = 0; do { @@ -1250,33 +1256,33 @@ void Game::EditGameUnitDetails(Unit *pUnit) break; } // change faction - if (*pToken == "f") { - SAFE_DELETE( pToken ); - pToken = pStr->gettoken(); - if ( !pToken ) { - Awrite( "Try again." ); - break; - } + if (*pToken == "f") { + SAFE_DELETE( pToken ); + pToken = pStr->gettoken(); + if ( !pToken ) { + Awrite( "Try again." ); + break; + } int fnum = pToken->value(); - SAFE_DELETE( pToken ); + SAFE_DELETE( pToken ); if (fnum<1) { Awrite("Invalid Faction Number"); break; } - + Faction *fac = GetFaction(&factions, fnum); if (fac) pUnit->faction = fac; else Awrite("Cannot Find Faction"); } - else if (*pToken == "t") { - SAFE_DELETE( pToken ); - pToken = pStr->gettoken(); - if ( !pToken ) { - Awrite( "Try again." ); - break; - } + else if (*pToken == "t") { + SAFE_DELETE( pToken ); + pToken = pStr->gettoken(); + if ( !pToken ) { + Awrite( "Try again." ); + break; + } int newtype = pToken->value(); - SAFE_DELETE( pToken ); + SAFE_DELETE( pToken ); if (newtype<0 || newtype>NUNITTYPES-1) { Awrite("Invalid Type"); break; diff --git a/faction.cpp b/faction.cpp index 732ed3fc..91f0c0b5 100644 --- a/faction.cpp +++ b/faction.cpp @@ -104,11 +104,11 @@ Faction::Faction() { exists = 1; name = 0; - + for (auto &ft : *FactionTypes) { type[ft] = 1; } - + lastchange = -6; address = 0; password = 0; @@ -129,7 +129,7 @@ Faction::Faction(int n) { exists = 1; num = n; - + for (auto &ft : *FactionTypes) { type[ft] = 1; } @@ -211,7 +211,7 @@ void Faction::Readin(istream& f) name = new AString(tmp); AString *temp = name->stripnumber(); SetName(temp); - + f >> ws >> tmp; address = new AString(tmp); f >> ws >> tmp; @@ -675,10 +675,10 @@ int Faction::CanSee(ARegion* r, Unit* u, int practice) // penalty of 2 to stealth if assassinating and 1 if stealing // TODO: not sure about the reasoning behind the IMPROVED_AMTS part int stealpenalty = 0; - if (Globals->HARDER_ASSASSINATION && u->stealorders){ - if (u->stealorders->type == O_STEAL) { + if (Globals->HARDER_ASSASSINATION && u->stealthorders){ + if (u->stealthorders->type == O_STEAL) { stealpenalty = 1; - } else if (u->stealorders->type == O_ASSASSINATE) { + } else if (u->stealthorders->type == O_ASSASSINATE) { if (Globals->IMPROVED_AMTS){ stealpenalty = 1; } else { diff --git a/fracas/world.cpp b/fracas/world.cpp index 34cf47fc..42483843 100644 --- a/fracas/world.cpp +++ b/fracas/world.cpp @@ -2506,9 +2506,9 @@ void ARegion::MakeStartingCity() if (!Globals->TOWNS_EXIST) return; if (Globals->GATES_EXIST) gate = -1; - + if (town) delete town; - + AddTown(TOWN_CITY); if (!Globals->START_CITIES_EXIST) return; @@ -2529,18 +2529,18 @@ void ARegion::MakeStartingCity() if ( ItemDefs[ i ].type & IT_NORMAL ) { if (i==I_SILVER || i==I_LIVESTOCK || i==I_FISH || i==I_GRAIN) continue; - m = new Market(Market::M_BUY, i, (ItemDefs[i].baseprice * 5 / 2), -1, 5000, 5000, -1, -1); + m = new Market(Market::MarketType::M_BUY, i, (ItemDefs[i].baseprice * 5 / 2), -1, 5000, 5000, -1, -1); markets.push_back(m); } } ratio = ItemDefs[race].baseprice / ((float)Globals->BASE_MAN_COST * 10); // hack: include wage factor of 10 in float calculation above - m = new Market(Market::M_BUY, race, (int)(Wages() * 4 * ratio), -1, 5000, 5000, -1, -1); + m = new Market(Market::MarketType::M_BUY, race, (int)(Wages() * 4 * ratio), -1, 5000, 5000, -1, -1); markets.push_back(m); if (Globals->LEADERS_EXIST) { ratio=ItemDefs[I_LEADERS].baseprice/((float)Globals->BASE_MAN_COST * 10); // hack: include wage factor of 10 in float calculation above - m = new Market(Market::M_BUY, I_LEADERS, (int)(Wages() * 4 * ratio), -1, 5000, 5000, -1, -1); + m = new Market(Market::MarketType::M_BUY, I_LEADERS, (int)(Wages() * 4 * ratio), -1, 5000, 5000, -1, -1); markets.push_back(m); } } else { @@ -2548,12 +2548,16 @@ void ARegion::MakeStartingCity() ratio = ItemDefs[race].baseprice / ((float)Globals->BASE_MAN_COST * 10); // hack: include wage factor of 10 in float calculation above /* Setup Recruiting */ - m = new Market(Market::M_BUY, race, (int)(Wages() * 4 * ratio), Population() / 5, 0, 10000, 0, 2000); + m = new Market( + Market::MarketType::M_BUY, race, (int)(Wages() * 4 * ratio), Population() / 5, 0, 10000, 0, 2000 + ); markets.push_back(m); if ( Globals->LEADERS_EXIST ) { ratio=ItemDefs[I_LEADERS].baseprice/((float)Globals->BASE_MAN_COST * 10); // hack: include wage factor of 10 in float calculation above - m = new Market(Market::M_BUY, I_LEADERS, (int)(Wages() * 4 * ratio), Population() / 25, 0, 10000, 0, 400); + m = new Market( + Market::MarketType::M_BUY, I_LEADERS, (int)(Wages() * 4 * ratio), Population() / 25, 0, 10000, 0, 400 + ); markets.push_back(m); } } diff --git a/game.h b/game.h index d1db1dbe..a0dd31d4 100644 --- a/game.h +++ b/game.h @@ -423,7 +423,7 @@ class Game void WriteTimesArticle(AString); void DoExchangeOrders(); - void DoExchangeOrder(ARegion *, Unit *, ExchangeOrder *); + void DoExchangeOrder(ARegion *r, Unit *u, std::shared_ptr o); // // Faction limit functions. @@ -444,12 +444,12 @@ class Game // The DoGiveOrder returns 0 normally, or 1 if no more GIVE orders // should be allowed // - int DoGiveOrder(ARegion *, Unit *, GiveOrder *); + int DoGiveOrder(ARegion *r, Unit *u, std::shared_ptr o); // // The DoWithdrawOrder returns 0 normally, or 1 if no more WITHDRAW // orders should be allowed // - int DoWithdrawOrder(ARegion *, Unit *, WithdrawOrder *); + int DoWithdrawOrder(ARegion *r, Unit *u, std::shared_ptr o); // // These are game specific, and can be found in extra.cpp @@ -557,7 +557,7 @@ class Game void RunSacrificeOrders(); void CollectInterQMTransportItems(); void CheckTransportOrders(); - AList *CanSeeSteal(ARegion *, Unit *); + std::vector> CanSeeSteal(ARegion *, Unit *); void Do1Steal(ARegion *, Object *, Unit *); void Do1Assassinate(ARegion *, Object *, Unit *); void Do1Annihilate(ARegion *reg); diff --git a/havilah/world.cpp b/havilah/world.cpp index 0301ad81..c588de83 100644 --- a/havilah/world.cpp +++ b/havilah/world.cpp @@ -764,9 +764,9 @@ void ARegion::MakeStartingCity() if (!Globals->TOWNS_EXIST) return; if (Globals->GATES_EXIST) gate = -1; - + if (town) delete town; - + AddTown(TOWN_CITY); if (!Globals->START_CITIES_EXIST) return; @@ -786,18 +786,18 @@ void ARegion::MakeStartingCity() if ( ItemDefs[ i ].type & IT_NORMAL ) { if (i==I_SILVER || i==I_LIVESTOCK || i==I_FISH || i==I_GRAIN) continue; - m = new Market(Market::M_BUY, i, (ItemDefs[i].baseprice * 5 / 2), -1, 5000, 5000, -1, -1); + m = new Market(Market::MarketType::M_BUY, i, (ItemDefs[i].baseprice * 5 / 2), -1, 5000, 5000, -1, -1); markets.push_back(m); } } ratio = ItemDefs[race].baseprice / ((float)Globals->BASE_MAN_COST * 10); // hack: include wage factor of 10 in float calculation above - m = new Market(Market::M_BUY, race, (int)(Wages() * 4 * ratio), -1, 5000, 5000, -1, -1); + m = new Market(Market::MarketType::M_BUY, race, (int)(Wages() * 4 * ratio), -1, 5000, 5000, -1, -1); markets.push_back(m); if (Globals->LEADERS_EXIST) { ratio=ItemDefs[I_LEADERS].baseprice/((float)Globals->BASE_MAN_COST * 10); // hack: include wage factor of 10 in float calculation above - m = new Market(Market::M_BUY, I_LEADERS, (int)(Wages() * 4 * ratio), -1, 5000, 5000, -1, -1); + m = new Market(Market::MarketType::M_BUY, I_LEADERS, (int)(Wages() * 4 * ratio), -1, 5000, 5000, -1, -1); markets.push_back(m); } } else { @@ -805,12 +805,16 @@ void ARegion::MakeStartingCity() ratio = ItemDefs[race].baseprice / ((float)Globals->BASE_MAN_COST * 10); // hack: include wage factor of 10 in float calculation above /* Setup Recruiting */ - m = new Market(Market::M_BUY, race, (int)(Wages() * 4 * ratio), Population() / 5, 0, 10000, 0, 2000); + m = new Market( + Market::MarketType::M_BUY, race, (int)(Wages() * 4 * ratio), Population() / 5, 0, 10000, 0, 2000 + ); markets.push_back(m); if ( Globals->LEADERS_EXIST ) { ratio = ItemDefs[I_LEADERS].baseprice/((float)Globals->BASE_MAN_COST * 10); // hack: include wage factor of 10 in float calculation above - m = new Market(Market::M_BUY, I_LEADERS, (int)(Wages() * 4 * ratio), Population() / 25, 0, 10000, 0, 400); + m = new Market( + Market::MarketType::M_BUY, I_LEADERS, (int)(Wages() * 4 * ratio), Population() / 25, 0, 10000, 0, 400 + ); markets.push_back(m); } } diff --git a/kingdoms/world.cpp b/kingdoms/world.cpp index 2d4dada5..cbe524c0 100644 --- a/kingdoms/world.cpp +++ b/kingdoms/world.cpp @@ -2503,9 +2503,9 @@ void ARegion::MakeStartingCity() if (!Globals->TOWNS_EXIST) return; if (Globals->GATES_EXIST) gate = -1; - + if (town) delete town; - + AddTown(TOWN_CITY); if (!Globals->START_CITIES_EXIST) return; @@ -2526,18 +2526,18 @@ void ARegion::MakeStartingCity() if ( ItemDefs[ i ].type & IT_NORMAL ) { if (i==I_SILVER || i==I_LIVESTOCK || i==I_FISH || i==I_GRAIN) continue; - m = new Market(Market::M_BUY, i, (ItemDefs[i].baseprice * 5 / 2), -1, 5000, 5000, -1, -1); + m = new Market(Market::MarketType::M_BUY, i, (ItemDefs[i].baseprice * 5 / 2), -1, 5000, 5000, -1, -1); markets.push_back(m); } } ratio = ItemDefs[race].baseprice / ((float)Globals->BASE_MAN_COST * 10); // hack: include wage factor of 10 in float calculation above - m = new Market(Market::M_BUY, race, (int)(Wages() * 4 * ratio), -1, 5000, 5000, -1, -1); + m = new Market(Market::MarketType::M_BUY, race, (int)(Wages() * 4 * ratio), -1, 5000, 5000, -1, -1); markets.push_back(m); if (Globals->LEADERS_EXIST) { ratio=ItemDefs[I_LEADERS].baseprice/((float)Globals->BASE_MAN_COST * 10); // hack: include wage factor of 10 in float calculation above - m = new Market(Market::M_BUY, I_LEADERS, (int)(Wages() * 4 * ratio), -1, 5000, 5000, -1, -1); + m = new Market(Market::MarketType::M_BUY, I_LEADERS, (int)(Wages() * 4 * ratio), -1, 5000, 5000, -1, -1); markets.push_back(m); } } else { @@ -2545,12 +2545,16 @@ void ARegion::MakeStartingCity() ratio = ItemDefs[race].baseprice / ((float)Globals->BASE_MAN_COST * 10); // hack: include wage factor of 10 in float calculation above /* Setup Recruiting */ - m = new Market(Market::M_BUY, race, (int)(Wages() * 4 * ratio), Population() / 5, 0, 10000, 0, 2000); + m = new Market( + Market::MarketType::M_BUY, race, (int)(Wages() * 4 * ratio), Population() / 5, 0, 10000, 0, 2000 + ); markets.push_back(m); if ( Globals->LEADERS_EXIST ) { ratio=ItemDefs[I_LEADERS].baseprice/((float)Globals->BASE_MAN_COST * 10); // hack: include wage factor of 10 in float calculation above - m = new Market(Market::M_BUY, I_LEADERS, (int)(Wages() * 4 * ratio), Population() / 25, 0, 10000, 0, 400); + m = new Market( + Market::MarketType::M_BUY, I_LEADERS, (int)(Wages() * 4 * ratio), Population() / 25, 0, 10000, 0, 400 + ); markets.push_back(m); } } diff --git a/market.cpp b/market.cpp index 5d2ccb42..4a11f4a9 100644 --- a/market.cpp +++ b/market.cpp @@ -27,6 +27,7 @@ #include "items.h" #include "gameio.h" #include "gamedata.h" +#include void Market::post_turn(int population, int wages) { @@ -52,7 +53,7 @@ void Market::post_turn(int population, int wages) int tarprice = price; if (amount) { int fluctuation = (baseprice * activity)/amount; - if (type == M_BUY) + if (type == MarketType::M_BUY) tarprice = (2 * baseprice + fluctuation) / 2; else tarprice = (3 * baseprice - fluctuation) / 2; @@ -70,7 +71,7 @@ void Market::post_turn(int population, int wages) void Market::write_out(std::ostream& f) { - f << type << '\n'; + f << static_cast>(type) << '\n'; f << (item == -1 ? "NO_ITEM" : ItemDefs[item].abr) << '\n'; f << price << '\n'; f << amount << '\n'; diff --git a/market.h b/market.h index 045e2431..7a6496e0 100644 --- a/market.h +++ b/market.h @@ -29,7 +29,7 @@ class Market { public: - enum MarketType : int { + enum struct MarketType : int { M_BUY, M_SELL }; diff --git a/monthorders.cpp b/monthorders.cpp index fc3ce08f..e6723e79 100644 --- a/monthorders.cpp +++ b/monthorders.cpp @@ -31,6 +31,7 @@ #include #include +#include #include "game.h" #include "gamedata.h" @@ -45,9 +46,6 @@ void Game::RunMovementOrders() Object *o; AList locs; Location *l; - MoveOrder *mo; - SailOrder *so; - MoveDir *d; AString order, *tOrder; for (phase = 0; phase < Globals->MAX_SPEED; phase++) { @@ -103,8 +101,7 @@ void Game::RunMovementOrders() u->error("SAIL: Fleet is too damaged to sail."); break; } - delete u->monthorders; - u->monthorders = 0; + u->monthorders = nullptr; } } } @@ -158,58 +155,53 @@ void Game::RunMovementOrders() forlist(&r->objects) { o = (Object *) elem; for(auto u: o->units) { - mo = (MoveOrder *) u->monthorders; - if (!u->nomove && - u->monthorders && - (u->monthorders->type == O_MOVE || - u->monthorders->type == O_ADVANCE) && - mo->dirs.Num() > 0) { - d = (MoveDir *) mo->dirs.First(); - if (u->savedmovedir != d->dir) - u->savedmovement = 0; - u->savedmovement += u->movepoints / Globals->MAX_SPEED; - u->savedmovedir = d->dir; - } else { - u->savedmovement = 0; + if (!u->monthorders || (u->monthorders->type != O_MOVE && u->monthorders->type != O_ADVANCE)) { u->savedmovedir = -1; + u->savedmovement = 0; + continue; } - if (u->monthorders && - (u->monthorders->type == O_MOVE || - u->monthorders->type == O_ADVANCE)) { - mo = (MoveOrder *) u->monthorders; - if (mo->dirs.Num() > 0) { - string type = (mo->advancing ? "ADVANCE" : "MOVE"); - string temp = type + ": Unit has insufficient movement points; remaining moves queued."; - u->event(temp, "movement"); - tOrder = new AString(type); - forlist(&mo->dirs) { - d = (MoveDir *) elem; - *tOrder += " "; - if (d->dir < NDIRS) *tOrder += DirectionAbrs[d->dir]; - else if (d->dir == MOVE_IN) *tOrder += "IN"; - else if (d->dir == MOVE_OUT) *tOrder += "OUT"; - else if (d->dir == MOVE_PAUSE) *tOrder += "P"; - else *tOrder += d->dir - MOVE_ENTER; - } - u->oldorders.push_front(tOrder->const_str()); + + std::shared_ptr mo = std::dynamic_pointer_cast(u->monthorders); + if (mo->dirs.size() > 0) { + if (!u->nomove) { + MoveDir d = mo->dirs[0]; + if (u->savedmovedir != d.dir) + u->savedmovement = 0; + u->savedmovement += u->movepoints / Globals->MAX_SPEED; + u->savedmovedir = d.dir; + } else { + u->savedmovement = 0; + u->savedmovedir = -1; + } + + string type = (mo->advancing ? "ADVANCE" : "MOVE"); + string temp = type + ": Unit has insufficient movement points; remaining moves queued."; + u->event(temp, "movement"); + tOrder = new AString(type); + for(auto d: mo->dirs) { + *tOrder += " "; + if (d.dir < NDIRS) *tOrder += DirectionAbrs[d.dir]; + else if (d.dir == MOVE_IN) *tOrder += "IN"; + else if (d.dir == MOVE_OUT) *tOrder += "OUT"; + else if (d.dir == MOVE_PAUSE) *tOrder += "P"; + else *tOrder += d.dir - MOVE_ENTER; } + u->oldorders.push_front(tOrder->const_str()); } } + Unit *u = o->GetOwner(); - if (o->IsFleet() && u && !u->nomove && - u->monthorders && - u->monthorders->type == O_SAIL) { - so = (SailOrder *) u->monthorders; - if (so->dirs.Num() > 0) { + if (o->IsFleet() && u && !u->nomove && u->monthorders && u->monthorders->type == O_SAIL) { + std::shared_ptr so = std::dynamic_pointer_cast(u->monthorders); + if (so->dirs.size() > 0) { u->event("SAIL: Can't sail that far; remaining moves queued.", "movement"); tOrder = new AString("SAIL"); - forlist(&so->dirs) { - d = (MoveDir *) elem; + for(auto d: so->dirs) { *tOrder += " "; - if (d->dir == MOVE_PAUSE) + if (d.dir == MOVE_PAUSE) *tOrder += "P"; else - *tOrder += DirectionAbrs[d->dir]; + *tOrder += DirectionAbrs[d.dir]; } u->oldorders.push_front(tOrder->const_str()); } @@ -220,11 +212,10 @@ void Game::RunMovementOrders() Location *Game::Do1SailOrder(ARegion *reg, Object *fleet, Unit *cap) { - SailOrder *o = (SailOrder *) cap->monthorders; + std::shared_ptr o = std::dynamic_pointer_cast(cap->monthorders); int stop, wgt, slr, nomove, cost; AList facs; ARegion *newreg; - MoveDir *x; Location *loc; fleet->movepoints += fleet->GetFleetSpeed(0); @@ -257,15 +248,15 @@ Location *Game::Do1SailOrder(ARegion *reg, Object *fleet, Unit *cap) } else if (slr < fleet->GetFleetSize()) { cap->error("SAIL: Not enough sailors."); stop = 1; - } else if (!o->dirs.Num()) { + } else if (!o->dirs.size()) { // no more moves? stop = 1; } else { - x = (MoveDir *) o->dirs.First(); - if (x->dir == MOVE_PAUSE) { + MoveDir x = o->dirs[0]; + if (x.dir == MOVE_PAUSE) { newreg = reg; } else { - newreg = reg->neighbors[x->dir]; + newreg = reg->neighbors[x.dir]; } cost = 1; @@ -279,7 +270,7 @@ Location *Game::Do1SailOrder(ARegion *reg, Object *fleet, Unit *cap) !newreg->clearskies) cost = 2; } - if (x->dir == MOVE_PAUSE) { + if (x.dir == MOVE_PAUSE) { cost = 1; } // We probably shouldn't see terrain-based errors until @@ -289,7 +280,7 @@ Location *Game::Do1SailOrder(ARegion *reg, Object *fleet, Unit *cap) if (!newreg) { cap->error("SAIL: Can't sail that way."); stop = 1; - } else if (x->dir == MOVE_PAUSE) { + } else if (x.dir == MOVE_PAUSE) { // Can always do maneuvers } else if (fleet->flying < 1 && !newreg->IsCoastalOrLakeside()) { cap->error("SAIL: Can't sail inland."); @@ -299,8 +290,8 @@ Location *Game::Do1SailOrder(ARegion *reg, Object *fleet, Unit *cap) (TerrainDefs[newreg->type].similar_type != R_OCEAN)) { cap->error("SAIL: Can't sail inland."); stop = 1; - } else if (fleet->SailThroughCheck(x->dir) < 1) { - cap->error("SAIL: Could not sail " + DirectionStrs[x->dir] + " from " + + } else if (fleet->SailThroughCheck(x.dir) < 1) { + cap->error("SAIL: Could not sail " + DirectionStrs[x.dir] + " from " + reg->ShortPrint().const_str() + ". Cannot sail through land."); stop = 1; } @@ -322,7 +313,7 @@ Location *Game::Do1SailOrder(ARegion *reg, Object *fleet, Unit *cap) } } if (!has_key) { - cap->error("SAIL: Can't sail " + DirectionStrs[x->dir] + " from " + + cap->error("SAIL: Can't sail " + DirectionStrs[x.dir] + " from " + reg->ShortPrint().const_str() + " due to mystical barrier."); stop = 1; } @@ -330,9 +321,9 @@ Location *Game::Do1SailOrder(ARegion *reg, Object *fleet, Unit *cap) if (!stop) { fleet->movepoints -= cost * Globals->MAX_SPEED; - if (x->dir != MOVE_PAUSE) { + if (x.dir != MOVE_PAUSE) { fleet->MoveObject(newreg); - fleet->SetPrevDir(reg->GetRealDirComp(x->dir)); + fleet->SetPrevDir(reg->GetRealDirComp(x.dir)); } for(auto unit: fleet->units) { unit->moved += cost; @@ -344,8 +335,7 @@ Location *Game::Do1SailOrder(ARegion *reg, Object *fleet, Unit *cap) if (unit->monthorders->type == O_SAIL) unit->Practice(S_SAILING); if (unit->monthorders->type == O_MOVE) { - delete unit->monthorders; - unit->monthorders = 0; + unit->monthorders = nullptr; } } unit->DiscardUnfinishedShips(); @@ -359,15 +349,14 @@ Location *Game::Do1SailOrder(ARegion *reg, Object *fleet, Unit *cap) forlist_reuse(&facs) { Faction * f = ((FactionPtr *) elem)->ptr; string temp = fleet->name->const_str(); - temp += (x->dir == MOVE_PAUSE ? " performs maneuvers in " : " sails from ") + + temp += (x.dir == MOVE_PAUSE ? " performs maneuvers in " : " sails from ") + string(reg->ShortPrint().const_str()); - if(x->dir != MOVE_PAUSE) { + if(x.dir != MOVE_PAUSE) { temp += " to " + string(newreg->ShortPrint().const_str()); } f->event(temp, "sail"); } - if (Globals->TRANSIT_REPORT != GameDefs::REPORT_NOTHING && - x->dir != MOVE_PAUSE) { + if (Globals->TRANSIT_REPORT != GameDefs::REPORT_NOTHING && x.dir != MOVE_PAUSE) { if (!(cap->faction->is_npc)) newreg->visited = 1; for(auto unit: fleet->units) { // Everyone onboard gets to see the sights @@ -377,7 +366,7 @@ Location *Game::Do1SailOrder(ARegion *reg, Object *fleet, Unit *cap) f = (Farsight *)elem; if (f->unit == unit) { // We moved into here this turn - f->exits_used[x->dir] = 1; + f->exits_used[x.dir] = 1; } } // And mark the hex being entered @@ -385,7 +374,7 @@ Location *Game::Do1SailOrder(ARegion *reg, Object *fleet, Unit *cap) f->faction = unit->faction; f->level = 0; f->unit = unit; - f->exits_used[reg->GetRealDirComp(x->dir)] = 1; + f->exits_used[reg->GetRealDirComp(x.dir)] = 1; newreg->passers.Add(f); } } @@ -396,18 +385,15 @@ Location *Game::Do1SailOrder(ARegion *reg, Object *fleet, Unit *cap) cap->faction->event(temp, "sail"); stop = 1; } - o->dirs.Remove(x); - delete x; + std::erase(o->dirs, x); } } if (stop) { // Clear out everyone's orders for(auto unit: fleet->units) { - if (unit->monthorders && - unit->monthorders->type == O_SAIL) { - delete unit->monthorders; - unit->monthorders = 0; + if (unit->monthorders && unit->monthorders->type == O_SAIL) { + unit->monthorders = nullptr; } } } @@ -429,8 +415,7 @@ void Game::RunTeachOrders() if (u->monthorders) { if (u->monthorders->type == O_TEACH) { Do1TeachOrder(r,u); - delete u->monthorders; - u->monthorders = 0; + u->monthorders = nullptr; } } } @@ -438,7 +423,7 @@ void Game::RunTeachOrders() } } -void Game::Do1TeachOrder(ARegion * reg,Unit * unit) +void Game::Do1TeachOrder(ARegion * reg, Unit * unit) { /* First pass, find how many to teach */ if (Globals->LEADERS_EXIST && !unit->IsLeader()) { @@ -452,7 +437,7 @@ void Game::Do1TeachOrder(ARegion * reg,Unit * unit) } int students = 0; - TeachOrder * order = (TeachOrder *) unit->monthorders; + std::shared_ptr order = std::dynamic_pointer_cast(unit->monthorders); reg->deduplicate_unit_list(order->targets, unit->faction->num); for (auto unitid = order->targets.begin(); unitid != order->targets.end(); ) { Unit *target = reg->get_unit_id(*unitid, unit->faction->num); @@ -471,7 +456,8 @@ void Game::Do1TeachOrder(ARegion * reg,Unit * unit) unitid = order->targets.erase(unitid); continue; } - int sk = ((StudyOrder *) target->monthorders)->skill; + std::shared_ptr o = std::dynamic_pointer_cast(target->monthorders); + int sk = o->skill; if (unit->GetRealSkill(sk) <= target->GetRealSkill(sk)) { unit->error(string("TEACH: ") + target->name->const_str() + " is not studying a skill you can teach."); unitid = order->targets.erase(unitid); @@ -500,7 +486,7 @@ void Game::Do1TeachOrder(ARegion * reg,Unit * unit) days -= tempdays; students -= umen; - StudyOrder * o = (StudyOrder *) u->monthorders; + std::shared_ptr o = std::dynamic_pointer_cast(u->monthorders); o->days += tempdays; if (o->days > 30 * umen) { days += o->days - 30 * umen; @@ -520,8 +506,7 @@ void Game::Run1BuildOrder(ARegion *r, Object *obj, Unit *u) if (!Globals->BUILD_NO_TRADE && !ActivityCheck(r, u->faction, FactionActivity::TRADE)) { u->error("BUILD: Faction can't produce in that many regions."); - delete u->monthorders; - u->monthorders = 0; + u->monthorders = nullptr; return; } @@ -533,43 +518,38 @@ void Game::Run1BuildOrder(ARegion *r, Object *obj, Unit *u) } if (!buildobj || buildobj->type == O_DUMMY) { u->error("BUILD: Nothing to build."); - delete u->monthorders; - u->monthorders = 0; + u->monthorders = nullptr; return; } - AString skname = ObjectDefs[buildobj->type].skill; + + int type = buildobj->type; + AString skname = ObjectDefs[type].skill; int sk = LookupSkill(&skname); if (sk == -1) { - u->error("BUILD: Can't build that."); - delete u->monthorders; - u->monthorders = 0; + u->error("BUILD: Can't build " + string(ObjectDefs[type].name) + "."); + u->monthorders = nullptr; return; } int usk = u->GetSkill(sk); if (usk < ObjectDefs[buildobj->type].level) { - u->error("BUILD: Can't build that."); - delete u->monthorders; - u->monthorders = 0; + u->error("BUILD: Can't build " + string(ObjectDefs[type].name) + "."); + u->monthorders = nullptr; return; } int needed = buildobj->incomplete; - int type = buildobj->type; // AS - if (((ObjectDefs[type].flags & ObjectType::NEVERDECAY) || !Globals->DECAY) && - needed < 1) { - u->error("BUILD: Object is finished."); - delete u->monthorders; - u->monthorders = 0; + if (((ObjectDefs[type].flags & ObjectType::NEVERDECAY) || !Globals->DECAY) && needed < 1) { + u->error("BUILD: " + string(ObjectDefs[type].name) + " is finished."); + u->monthorders = nullptr; return; } // AS if (needed <= -(ObjectDefs[type].maxMaintenance)) { - u->error("BUILD: Object does not yet require maintenance."); - delete u->monthorders; - u->monthorders = 0; + u->error("BUILD: " + string(ObjectDefs[type].name) + " does not yet require maintenance."); + u->monthorders = nullptr; return; } @@ -583,8 +563,7 @@ void Game::Run1BuildOrder(ARegion *r, Object *obj, Unit *u) if (itn == 0) { u->error("BUILD: Don't have the required materials."); - delete u->monthorders; - u->monthorders = 0; + u->monthorders = nullptr; return; } @@ -648,8 +627,7 @@ void Game::Run1BuildOrder(ARegion *r, Object *obj, Unit *u) } u->Practice(sk); - delete u->monthorders; - u->monthorders = 0; + u->monthorders = nullptr; } /* Alternate processing for building item-type ship @@ -672,10 +650,9 @@ void Game::RunBuildShipOrder(ARegion * r,Object * obj,Unit * u) // get needed to complete maxbuild = 0; - if ((u->monthorders) && - (u->monthorders->type == O_BUILD)) { - BuildOrder *border = (BuildOrder *) u->monthorders; - maxbuild = border->needtocomplete; + if ((u->monthorders) && (u->monthorders->type == O_BUILD)) { + std::shared_ptr border = std::dynamic_pointer_cast(u->monthorders); + maxbuild = border->needtocomplete; } if (maxbuild < 1) { // Our helpers have already finished the hard work, so @@ -715,8 +692,7 @@ void Game::RunBuildShipOrder(ARegion * r,Object * obj,Unit * u) "%) in " + r->ShortPrint().const_str() + ".", "build", r); } - delete u->monthorders; - u->monthorders = 0; + u->monthorders = nullptr; } void Game::AddNewBuildings(ARegion *r) @@ -727,7 +703,7 @@ void Game::AddNewBuildings(ARegion *r) for(auto u: obj->units) { if (u->monthorders) { if (u->monthorders->type == O_BUILD) { - BuildOrder *o = (BuildOrder *)u->monthorders; + std::shared_ptr o = std::dynamic_pointer_cast(u->monthorders); // If BUILD order was marked for creating new building // in parse phase, it is time to create one now. @@ -769,30 +745,26 @@ void Game::RunBuildHelpers(ARegion *r) for(auto u: obj->units) { if (u->monthorders) { if (u->monthorders->type == O_BUILD) { - BuildOrder *o = (BuildOrder *)u->monthorders; + std::shared_ptr o = std::dynamic_pointer_cast(u->monthorders); Object *tarobj = NULL; if (o->target) { Unit *target = r->get_unit_id(*(o->target),u->faction->num); if (!target) { u->error("BUILD: No such unit to help."); - delete u->monthorders; - u->monthorders = 0; + u->monthorders = nullptr; continue; } // Make sure that unit is building if (!target->monthorders || target->monthorders->type != O_BUILD) { u->error("BUILD: Unit isn't building."); - delete u->monthorders; - u->monthorders = 0; + u->monthorders = nullptr; continue; } // Make sure that unit considers you friendly! if (target->faction->get_attitude(u->faction->num) < A_FRIENDLY) { - u->error("BUILD: Unit you are helping rejects " - "your help."); - delete u->monthorders; - u->monthorders = 0; + u->error("BUILD: Unit you are helping rejects your help."); + u->monthorders = nullptr; continue; } if (target->build == 0) { @@ -809,15 +781,14 @@ void Game::RunBuildHelpers(ARegion *r) int skill = LookupSkill(&skname); int level = u->GetSkill(skill); int needed = 0; - if ((target->monthorders) && - (target->monthorders->type == O_BUILD)) { - BuildOrder *border = (BuildOrder *) target->monthorders; - needed = border->needtocomplete; + if ((target->monthorders) && (target->monthorders->type == O_BUILD)) { + std::shared_ptr border = + std::dynamic_pointer_cast(target->monthorders); + needed = border->needtocomplete; } if (needed < 1) { u->error("BUILD: Construction is already complete."); - delete u->monthorders; - u->monthorders = 0; + u->monthorders = nullptr; continue; } int output = ShipConstruction(r, u, target, level, needed, ship); @@ -836,19 +807,19 @@ void Game::RunBuildHelpers(ARegion *r) if (unfinished > 0) { target->items.SetNum(ship, unfinished); - if ((target->monthorders) && - (target->monthorders->type == O_BUILD)) { - BuildOrder *border = (BuildOrder *) target->monthorders; - border->needtocomplete = unfinished; + if ((target->monthorders) && (target->monthorders->type == O_BUILD)) { + std::shared_ptr border = + std::dynamic_pointer_cast(target->monthorders); + border->needtocomplete = unfinished; } } else { // CreateShip(r, target, ship); // don't create the ship yet; leave that for the unit we're helping target->items.SetNum(ship, 1); - if ((target->monthorders) && - (target->monthorders->type == O_BUILD)) { - BuildOrder *border = (BuildOrder *) target->monthorders; - border->needtocomplete = 0; + if ((target->monthorders) && (target->monthorders->type == O_BUILD)) { + std::shared_ptr border = + std::dynamic_pointer_cast(target->monthorders); + border->needtocomplete = 0; } } int percent = 100 * output / ItemDefs[ship].pMonths; @@ -862,13 +833,9 @@ void Game::RunBuildHelpers(ARegion *r) if ((tarobj != NULL) && (u->object != tarobj)) u->MoveUnit(tarobj); } else { - Object *buildobj; if (u->build > 0) { - buildobj = r->GetObject(u->build); - if (buildobj && - buildobj != r->GetDummy() && - buildobj != u->object) - { + Object *buildobj = r->GetObject(u->build); + if (buildobj && buildobj != r->GetDummy() && buildobj != u->object) { u->MoveUnit(buildobj); } } @@ -918,15 +885,13 @@ int Game::ShipConstruction(ARegion *r, Unit *u, Unit *target, int level, int nee { if (!Globals->BUILD_NO_TRADE && !ActivityCheck(r, u->faction, FactionActivity::TRADE)) { u->error("BUILD: Faction can't produce in that many regions."); - delete u->monthorders; - u->monthorders = 0; + u->monthorders = nullptr; return 0; } if (level < ItemDefs[ship].pLevel) { u->error("BUILD: Can't build that."); - delete u->monthorders; - u->monthorders = 0; + u->monthorders = nullptr; return 0; } @@ -936,13 +901,7 @@ int Game::ShipConstruction(ARegion *r, Unit *u, Unit *target, int level, int nee int number = u->GetMen() * level + u->GetProductionBonus(ship); // find the max we can possibly produce based on man-months of labor - int maxproduced; - if (ItemDefs[ship].flags & ItemType::SKILLOUT) - maxproduced = u->GetMen(); - else - // don't adjust for pMonths - // - pMonths represents total requirement - maxproduced = number; + int maxproduced = (ItemDefs[ship].flags & ItemType::SKILLOUT) ? u->GetMen() : number; // adjust maxproduced for items needed until completion if (needed < maxproduced) maxproduced = needed; @@ -967,8 +926,7 @@ int Game::ShipConstruction(ARegion *r, Unit *u, Unit *target, int level, int nee // no required materials? if (count < 1) { u->error("BUILD: Don't have the required materials."); - delete u->monthorders; - u->monthorders = 0; + u->monthorders = nullptr; return 0; } @@ -1007,8 +965,7 @@ int Game::ShipConstruction(ARegion *r, Unit *u, Unit *target, int level, int nee // no required materials? if (maxproduced < 1) { u->error("BUILD: Don't have the required materials."); - delete u->monthorders; - u->monthorders = 0; + u->monthorders = nullptr; return 0; } @@ -1028,8 +985,7 @@ int Game::ShipConstruction(ARegion *r, Unit *u, Unit *target, int level, int nee if (ItemDefs[ship].flags & ItemType::SKILLOUT) output *= level; - delete u->monthorders; - u->monthorders = 0; + u->monthorders = nullptr; return output; } @@ -1048,7 +1004,7 @@ void Game::RunMonthOrders() void Game::RunUnitProduce(ARegion *r, Unit *u) { - ProduceOrder *o = (ProduceOrder *) u->monthorders; + std::shared_ptr o = std::dynamic_pointer_cast(u->monthorders); for (const auto& p : r->products) { // PRODUCE orders for producing goods from the land @@ -1059,33 +1015,29 @@ void Game::RunUnitProduce(ARegion *r, Unit *u) } if (o->item == I_SILVER) { - if (!o->quiet) - u->error("Can't do that in this region."); - delete u->monthorders; - u->monthorders = 0; + if (!o->quiet) u->error("Can't do that in this region."); + u->monthorders = nullptr; return; } if (o->item == -1 || ItemDefs[o->item].flags & ItemType::DISABLED) { - u->error("PRODUCE: Can't produce that."); - delete u->monthorders; - u->monthorders = 0; + string itemname = o->item == -1 ? "that" : ItemString(o->item, 1, ALWAYSPLURAL); + u->error("PRODUCE: Can't produce " + itemname + "."); + u->monthorders =nullptr; return; } int input = ItemDefs[o->item].pInput[0].item; if (input == -1) { - u->error("PRODUCE: Can't produce that."); - delete u->monthorders; - u->monthorders = 0; + u->error("PRODUCE: Can't produce " + string(ItemString(o->item, 1, ALWAYSPLURAL)) + "."); + u->monthorders = nullptr; return; } int level = u->GetSkill(o->skill); if (level < ItemDefs[o->item].pLevel) { - u->error("PRODUCE: Can't produce that."); - delete u->monthorders; - u->monthorders = 0; + u->error("PRODUCE: Can't produce " + string(ItemString(o->item, 1, ALWAYSPLURAL)) + "."); + u->monthorders = nullptr; return; } @@ -1094,8 +1046,7 @@ void Game::RunUnitProduce(ARegion *r, Unit *u) if (!ActivityCheck(r, u->faction, FactionActivity::TRADE)) { u->error("PRODUCE: Faction can't produce in that many regions."); - delete u->monthorders; - u->monthorders = 0; + u->monthorders = nullptr; return; } @@ -1183,18 +1134,13 @@ void Game::RunUnitProduce(ARegion *r, Unit *u) u->Practice(o->skill); o->target -= output; if (o->target > 0) { - TurnOrder *tOrder = new TurnOrder; - AString order; + std::shared_ptr tOrder = std::make_shared(); + string order = "PRODUCE " + to_string(o->target) + " " + ItemDefs[o->item].abr; tOrder->repeating = 0; - order = "PRODUCE "; - order += o->target; - order += " "; - order += ItemDefs[o->item].abr; - tOrder->turnOrders.push_back(order.const_str()); - u->turnorders.Insert(tOrder); - } - delete u->monthorders; - u->monthorders = 0; + tOrder->turnOrders.push_back(order); + u->turnorders.push_back(tOrder); + } + u->monthorders = nullptr; } void Game::RunProduceOrders(ARegion * r) @@ -1224,7 +1170,7 @@ int Game::ValidProd(Unit * u,ARegion * r, Production * p) { if (u->monthorders->type != O_PRODUCE) return 0; - ProduceOrder * po = (ProduceOrder *) u->monthorders; + std::shared_ptr po = std::dynamic_pointer_cast(u->monthorders); if (p->itemtype == po->item && p->skill == po->skill) { if (p->skill == -1) { /* Factor for fractional productivity: 10 */ @@ -1234,8 +1180,7 @@ int Game::ValidProd(Unit * u,ARegion * r, Production * p) int level = u->GetSkill(p->skill); if (level < ItemDefs[p->itemtype].pLevel) { u->error("PRODUCE: Unit isn't skilled enough."); - delete u->monthorders; - u->monthorders = 0; + u->monthorders = nullptr; return 0; } @@ -1245,8 +1190,7 @@ int Game::ValidProd(Unit * u,ARegion * r, Production * p) // if (p->itemtype != I_SILVER && !ActivityCheck(r, u->faction, FactionActivity::TRADE)) { u->error("PRODUCE: Faction can't produce in that many regions."); - delete u->monthorders; - u->monthorders = 0; + u->monthorders = nullptr; return 0; } @@ -1295,7 +1239,7 @@ void Game::RunAProduction(ARegion * r, Production * p) if (!u->monthorders || u->monthorders->type != O_PRODUCE) continue; - ProduceOrder * po = (ProduceOrder *) u->monthorders; + std::shared_ptr po = std::dynamic_pointer_cast(u->monthorders); if (po->skill != p->skill || po->item != p->itemtype) continue; @@ -1323,15 +1267,11 @@ void Game::RunAProduction(ARegion * r, Production * p) p->activity += ubucks; po->target -= ubucks; if (po->target > 0) { - TurnOrder *tOrder = new TurnOrder; - AString order; + std::shared_ptr tOrder = std::make_shared(); tOrder->repeating = 0; - order = "PRODUCE "; - order += po->target; - order += " "; - order += ItemDefs[po->item].abr; - tOrder->turnOrders.push_back(order.const_str()); - u->turnorders.Insert(tOrder); + string order = "PRODUCE " + to_string(po->target) + " " + ItemDefs[po->item].abr; + tOrder->turnOrders.push_back(order); + u->turnorders.push_back(tOrder); } /* Show in unit's events section */ @@ -1361,8 +1301,7 @@ void Game::RunAProduction(ARegion * r, Production * p) r->ShortPrint().const_str() + ".", "produce", r); u->Practice(po->skill); } - delete u->monthorders; - u->monthorders = 0; + u->monthorders = nullptr; if (questcomplete) { u->event("You have completed a quest! " + quest_rewards, "quest"); } @@ -1378,8 +1317,7 @@ void Game::RunStudyOrders(ARegion * r) if (u->monthorders) { if (u->monthorders->type == O_STUDY) { Do1StudyOrder(u,obj); - delete u->monthorders; - u->monthorders = 0; + u->monthorders = nullptr; } } } @@ -1393,8 +1331,7 @@ void Game::RunIdleOrders(ARegion *r) for(auto u: obj->units) { if (u->monthorders && u->monthorders->type == O_IDLE) { u->event("Sits idle.", "idle"); - delete u->monthorders; - u->monthorders = 0; + u->monthorders = nullptr; } } } @@ -1402,16 +1339,16 @@ void Game::RunIdleOrders(ARegion *r) void Game::Do1StudyOrder(Unit *u,Object *obj) { - StudyOrder * o = (StudyOrder *) u->monthorders; + std::shared_ptr o = std::dynamic_pointer_cast(u->monthorders); int sk, cost, reset_man, skmax, taughtdays, days; string str; reset_man = -1; sk = o->skill; if (sk == -1 || SkillDefs[sk].flags & SkillType::DISABLED || - (SkillDefs[sk].flags & SkillType::APPRENTICE && - !Globals->APPRENTICES_EXIST)) { - u->error("STUDY: Can't study that."); + (SkillDefs[sk].flags & SkillType::APPRENTICE && !Globals->APPRENTICES_EXIST)) { + string skname = (sk == -1) ? "that" : SkillDefs[sk].name; + u->error("STUDY: Can't study " + skname + "."); return; } @@ -1574,12 +1511,11 @@ void Game::Do1StudyOrder(Unit *u,Object *obj) // study to level order if (o->level != -1) { if (u->GetRealSkill(sk) < o->level) { - TurnOrder *tOrder = new TurnOrder; - AString order; + std::shared_ptr tOrder = std::make_shared(); tOrder->repeating = 0; - order = AString("STUDY ") + SkillDefs[sk].abbr + " " + o->level; - tOrder->turnOrders.push_back(order.const_str()); - u->turnorders.Insert(tOrder); + string order = "STUDY " + string(SkillDefs[sk].abbr) + " " + to_string(o->level); + tOrder->turnOrders.push_back(order); + u->turnorders.push_front(tOrder); } else { string msg = "Completes study to level " + to_string(o->level) + " in " + SkillDefs[sk].name + "."; u->event(msg, "study"); @@ -1595,19 +1531,15 @@ void Game::Do1StudyOrder(Unit *u,Object *obj) void Game::DoMoveEnter(Unit *unit,ARegion *region,Object **obj) { - MoveOrder * o; - if (!unit->monthorders || - ((unit->monthorders->type != O_MOVE) && - (unit->monthorders->type != O_ADVANCE))) + if (!unit->monthorders || ((unit->monthorders->type != O_MOVE) && (unit->monthorders->type != O_ADVANCE))) return; - o = (MoveOrder *) unit->monthorders; - while (o->dirs.Num()) { - MoveDir * x = (MoveDir *) o->dirs.First(); - int i = x->dir; + std::shared_ptr o = std::dynamic_pointer_cast(unit->monthorders); + while (o->dirs.size()) { + MoveDir x = o->dirs[0]; + int i = x.dir; if (i != MOVE_OUT && i < MOVE_ENTER) return; - o->dirs.Remove(x); - delete x; + std::erase(o->dirs, x); if (i >= MOVE_ENTER) { Object * to = region->GetObject(i - MOVE_ENTER); @@ -1627,8 +1559,7 @@ void Game::DoMoveEnter(Unit *unit,ARegion *region,Object **obj) continue; } - if (forbid && region->IsSafeRegion()) - { + if (forbid && region->IsSafeRegion()) { unit->error("ENTER: No battles allowed in safe regions."); continue; } @@ -1639,8 +1570,7 @@ void Game::DoMoveEnter(Unit *unit,ARegion *region,Object **obj) } int done = 0; - while (forbid) - { + while (forbid) { int result = RunBattle(region, unit, forbid, 0, 0); if (result == BATTLE_IMPOSSIBLE) { unit->error(string("ENTER: Unable to attack ") + forbid->name->const_str()); @@ -1661,8 +1591,7 @@ void Game::DoMoveEnter(Unit *unit,ARegion *region,Object **obj) } else { if (i == MOVE_OUT) { if (TerrainDefs[region->type].similar_type == R_OCEAN && - (!unit->CanSwim() || - unit->GetFlag(FLAG_NOCROSS_WATER))) + (!unit->CanSwim() || unit->GetFlag(FLAG_NOCROSS_WATER))) { unit->error("MOVE: Can't leave ship."); continue; @@ -1678,8 +1607,6 @@ void Game::DoMoveEnter(Unit *unit,ARegion *region,Object **obj) Location *Game::DoAMoveOrder(Unit *unit, ARegion *region, Object *obj) { - MoveOrder *o = (MoveOrder *) unit->monthorders; - MoveDir *x; ARegion *newreg; string road, temp; @@ -1688,15 +1615,15 @@ Location *Game::DoAMoveOrder(Unit *unit, ARegion *region, Object *obj) Location *loc; const char *prevented = nullptr; - if (!o->dirs.Num()) { - delete o; - unit->monthorders = 0; + std::shared_ptr o = std::dynamic_pointer_cast(unit->monthorders); + if (!o->dirs.size()) { + unit->monthorders = nullptr; return 0; } - x = (MoveDir *) o->dirs.First(); + MoveDir x = o->dirs[0]; - if (x->dir == MOVE_IN) { + if (x.dir == MOVE_IN) { if (obj->inner == -1) { unit->error("MOVE: Can't move IN there."); goto done_moving; @@ -1761,10 +1688,10 @@ Location *Game::DoAMoveOrder(Unit *unit, ARegion *region, Object *obj) newreg = candidates[index]; } } - } else if (x->dir == MOVE_PAUSE) { + } else if (x.dir == MOVE_PAUSE) { newreg = region; } else { - newreg = region->neighbors[x->dir]; + newreg = region->neighbors[x.dir]; } if (!newreg) { @@ -1794,8 +1721,8 @@ Location *Game::DoAMoveOrder(Unit *unit, ARegion *region, Object *obj) road = ""; startmove = 0; movetype = unit->MoveType(region); - cost = newreg->MoveCost(movetype, region, x->dir, &road); - if (x->dir == MOVE_PAUSE) + cost = newreg->MoveCost(movetype, region, x.dir, &road); + if (x.dir == MOVE_PAUSE) cost = 1; if (region->type == R_NEXUS) { cost = 1; @@ -1825,12 +1752,9 @@ Location *Game::DoAMoveOrder(Unit *unit, ARegion *region, Object *obj) // have stored movement points, then add in those stored // movement points, but make sure that these are only used // towards entering the hex we were trying to enter - if (!unit->moved && - unit->movepoints >= Globals->MAX_SPEED && - unit->movepoints < cost * Globals->MAX_SPEED && - x->dir == unit->savedmovedir) { - while (unit->savedmovement > 0 && - unit->movepoints < cost * Globals->MAX_SPEED) { + if (!unit->moved && (unit->movepoints >= Globals->MAX_SPEED) && + (unit->movepoints < cost * Globals->MAX_SPEED) && x.dir == unit->savedmovedir) { + while ((unit->savedmovement > 0) && (unit->movepoints < cost * Globals->MAX_SPEED)) { unit->movepoints += Globals->MAX_SPEED; unit->savedmovement--; } @@ -1841,19 +1765,16 @@ Location *Game::DoAMoveOrder(Unit *unit, ARegion *region, Object *obj) if (unit->movepoints < cost * Globals->MAX_SPEED) return 0; - if (x->dir == MOVE_PAUSE) { - unit->event("Pauses to admire the scenery in " + string(region->ShortPrint().const_str()) + - ".", "movement"); + if (x.dir == MOVE_PAUSE) { + unit->event("Pauses to admire the scenery in " + string(region->ShortPrint().const_str()) + ".", "movement"); unit->movepoints -= cost * Globals->MAX_SPEED; unit->moved += cost; - o->dirs.Remove(x); - delete x; + std::erase(o->dirs, x); return 0; } if ((TerrainDefs[newreg->type].similar_type == R_OCEAN) && - (!unit->CanSwim() || - unit->GetFlag(FLAG_NOCROSS_WATER))) { + (!unit->CanSwim() || unit->GetFlag(FLAG_NOCROSS_WATER))) { unit->event("Discovers that " + string(newreg->ShortPrint().const_str()) + " is " + TerrainDefs[newreg->type].name + ".", "movement"); goto done_moving; @@ -1932,8 +1853,8 @@ Location *Game::DoAMoveOrder(Unit *unit, ARegion *region, Object *obj) f = (Farsight *)elem; if (f->unit == unit) { // We moved into here this turn - if (x->dir < MOVE_IN) { - f->exits_used[x->dir] = 1; + if (x.dir < MOVE_IN) { + f->exits_used[x.dir] = 1; } } } @@ -1942,16 +1863,15 @@ Location *Game::DoAMoveOrder(Unit *unit, ARegion *region, Object *obj) f->faction = unit->faction; f->level = 0; f->unit = unit; - if (x->dir < MOVE_IN) { - f->exits_used[region->GetRealDirComp(x->dir)] = 1; + if (x.dir < MOVE_IN) { + f->exits_used[region->GetRealDirComp(x.dir)] = 1; } newreg->passers.Add(f); } region = newreg; - o->dirs.Remove(x); - delete x; + std::erase(o->dirs, x); loc = new Location; loc->unit = unit; @@ -1960,7 +1880,6 @@ Location *Game::DoAMoveOrder(Unit *unit, ARegion *region, Object *obj) return loc; done_moving: - delete o; - unit->monthorders = 0; - return 0; + unit->monthorders = nullptr; + return nullptr; } diff --git a/neworigins/world.cpp b/neworigins/world.cpp index 11feef96..dd8d828b 100644 --- a/neworigins/world.cpp +++ b/neworigins/world.cpp @@ -510,10 +510,9 @@ void Game::CreateWorld() regions.FinalSetupGates(); // do final modifications to add in the victory objects (the ritual altars and the deactivated monolith) - regions.CalcDensities(); - + regions.TownStatistics(); regions.ResourcesStatistics(); @@ -801,9 +800,9 @@ void ARegion::MakeStartingCity() if (!Globals->TOWNS_EXIST) return; if (Globals->GATES_EXIST) gate = -1; - + if (town) delete town; - + AddTown(TOWN_CITY); if (!Globals->START_CITIES_EXIST) return; @@ -824,18 +823,18 @@ void ARegion::MakeStartingCity() if ( ItemDefs[ i ].type & IT_NORMAL ) { if (i==I_SILVER || i==I_LIVESTOCK || i==I_FISH || i==I_GRAIN) continue; - m = new Market(Market::M_BUY, i, (ItemDefs[i].baseprice * 5 / 2), -1, 5000, 5000, -1, -1); + m = new Market(Market::MarketType::M_BUY, i, (ItemDefs[i].baseprice * 5 / 2), -1, 5000, 5000, -1, -1); markets.push_back(m); } } ratio = ItemDefs[race].baseprice / ((float)Globals->BASE_MAN_COST * 10); // hack: include wage factor of 10 in float calculation above - m = new Market(Market::M_BUY, race, (int)(Wages() * 4 * ratio), -1, 5000, 5000, -1, -1); + m = new Market(Market::MarketType::M_BUY, race, (int)(Wages() * 4 * ratio), -1, 5000, 5000, -1, -1); markets.push_back(m); if (Globals->LEADERS_EXIST) { ratio = ItemDefs[I_LEADERS].baseprice/((float)Globals->BASE_MAN_COST * 10); // hack: include wage factor of 10 in float calculation above - m = new Market(Market::M_BUY, I_LEADERS, (int)(Wages() * 4 * ratio), -1, 5000, 5000, -1, -1); + m = new Market(Market::MarketType::M_BUY, I_LEADERS, (int)(Wages() * 4 * ratio), -1, 5000, 5000, -1, -1); markets.push_back(m); } } else { @@ -843,12 +842,16 @@ void ARegion::MakeStartingCity() ratio = ItemDefs[race].baseprice / ((float)Globals->BASE_MAN_COST * 10); // hack: include wage factor of 10 in float calculation above /* Setup Recruiting */ - m = new Market(Market::M_BUY, race, (int)(Wages() * 4 * ratio), Population() / 5, 0, 10000, 0, 2000); + m = new Market( + Market::MarketType::M_BUY, race, (int)(Wages() * 4 * ratio), Population() / 5, 0, 10000, 0, 2000 + ); markets.push_back(m); if ( Globals->LEADERS_EXIST ) { ratio=ItemDefs[I_LEADERS].baseprice/((float)Globals->BASE_MAN_COST * 10); // hack: include wage factor of 10 in float calculation above - m = new Market(Market::M_BUY, I_LEADERS, (int)(Wages() * 4 * ratio), Population() / 25, 0, 10000, 0, 400); + m = new Market( + Market::MarketType::M_BUY, I_LEADERS, (int)(Wages() * 4 * ratio), Population() / 25, 0, 10000, 0, 400 + ); markets.push_back(m); } } diff --git a/orders.cpp b/orders.cpp index 489275c6..845456b6 100644 --- a/orders.cpp +++ b/orders.cpp @@ -23,6 +23,7 @@ // // END A3HEADER #include "orders.h" +#include "unit.h" char const *od[] = { "#atlantis", @@ -256,6 +257,14 @@ FindOrder::~FindOrder() { } +StealthOrder::StealthOrder() +{ +} + +StealthOrder::~StealthOrder() +{ +} + StealOrder::StealOrder() { type = O_STEAL; diff --git a/orders.h b/orders.h index b9fb9bab..55c8be27 100644 --- a/orders.h +++ b/orders.h @@ -25,39 +25,13 @@ #ifndef ORDERS_CLASS #define ORDERS_CLASS -class Order; -class AttackOrder; -class MoveOrder; -class WithdrawOrder; -class GiveOrder; -class StudyOrder; -class TeachOrder; -class SellOrder; -class BuyOrder; -class ProduceOrder; -class BuildOrder; -class SailOrder; -class FindOrder; -class StealOrder; -class AssassinateOrder; -class CastOrder; -class CastMindOrder; -class CastRegionOrder; -class TeleportOrder; -class ForgetOrder; -class EvictOrder; -class BankOrder; -class IdleOrder; -class TransportOrder; -class AnnihilateOrder; -class SacrificeOrder; - -#include "unit.h" #include "gamedefs.h" #include "astring.h" -#include "alist.h" #include +// Forward declarations +class UnitId; + enum { O_ATLANTIS, O_END, @@ -145,11 +119,12 @@ enum { /* Enter is MOVE_ENTER + num of object */ #define MOVE_ENTER 100 + extern char const ** OrderStrs; int Parse1Order(AString *); -class Order : public AListElem { +class Order { public: Order(); virtual ~Order(); @@ -158,9 +133,13 @@ class Order : public AListElem { int quiet; }; -class MoveDir : public AListElem { - public: - int dir; +class MoveDir { +public: + MoveDir(int d) : dir(d) {} + ~MoveDir() {} + inline int operator==(const MoveDir &d) { return dir == d.dir; } + + int dir; }; class MoveOrder : public Order { @@ -169,7 +148,7 @@ class MoveOrder : public Order { ~MoveOrder(); int advancing; - AList dirs; + std::vector dirs; }; class WithdrawOrder : public Order { @@ -266,7 +245,7 @@ class SailOrder : public Order { SailOrder(); ~SailOrder(); - AList dirs; + std::vector dirs; }; class FindOrder : public Order { @@ -277,16 +256,23 @@ class FindOrder : public Order { int find; }; -class StealOrder : public Order { +class StealthOrder : public Order { + public: + StealthOrder(); + virtual ~StealthOrder(); + + UnitId *target; +}; + +class StealOrder : public StealthOrder { public: StealOrder(); ~StealOrder(); - UnitId *target; int item; }; -class AssassinateOrder : public Order { +class AssassinateOrder : public StealthOrder { public: AssassinateOrder(); ~AssassinateOrder(); @@ -329,7 +315,7 @@ class TurnOrder : public Order { class CastOrder : public Order { public: CastOrder(); - ~CastOrder(); + virtual ~CastOrder(); int spell; int level; @@ -346,7 +332,7 @@ class CastMindOrder : public CastOrder { class CastRegionOrder : public CastOrder { public: CastRegionOrder(); - ~CastRegionOrder(); + virtual ~CastRegionOrder(); int xloc, yloc, zloc; }; @@ -411,7 +397,7 @@ class TransportOrder : public Order { int except; int distance; - enum TransportPhase { + enum class TransportPhase { SHIP_TO_QM, INTER_QM_TRANSPORT, DISTRIBUTE_FROM_QM diff --git a/parseorders.cpp b/parseorders.cpp index dab2fa5c..ee281207 100644 --- a/parseorders.cpp +++ b/parseorders.cpp @@ -24,6 +24,7 @@ // END A3HEADER #include +#include #include "game.h" #include "gameio.h" @@ -406,7 +407,6 @@ void Game::ParseOrders(int faction, istream& f, OrdersCheck *pCheck) break; case O_ENDTURN: if (unit && unit->inTurnBlock) { - if (unit->monthorders) delete unit->monthorders; unit->monthorders = unit->presentMonthOrders; unit->presentMonthOrders = 0; unit->taxing = unit->presentTaxing; @@ -921,9 +921,9 @@ void Game::ProcessForgetOrder(Unit *u, AString *o, OrdersCheck *pCheck) } if (!pCheck) { - ForgetOrder *ord = new ForgetOrder; + std::shared_ptr ord = std::make_shared(); ord->skill = sk; - u->forgetorders.Add(ord); + u->forgetorders.push_back(ord); } } @@ -936,9 +936,8 @@ void Game::ProcessEntertainOrder(Unit *unit, OrdersCheck *pCheck) string err = string("ENTERTAIN: Overwriting previous ") + (unit->inTurnBlock ? "DELAYED " : "") + "month-long order."; parse_error(pCheck, unit, 0, err); - if (unit->monthorders) delete unit->monthorders; } - ProduceOrder *o = new ProduceOrder; + std::shared_ptr o = std::make_shared(); o->item = I_SILVER; o->skill = S_ENTERTAINMENT; o->target = 0; @@ -1238,10 +1237,9 @@ void Game::ProcessAssassinateOrder(Unit *u, AString *o, OrdersCheck *pCheck) return; } if (!pCheck) { - if (u->stealorders) delete u->stealorders; - AssassinateOrder *ord = new AssassinateOrder; + std::shared_ptr ord = std::make_shared(); ord->target = id; - u->stealorders = ord; + u->stealthorders = ord; } } @@ -1272,11 +1270,10 @@ void Game::ProcessStealOrder(Unit *u, AString *o, OrdersCheck *pCheck) delete id; return; } - StealOrder *ord = new StealOrder; + std::shared_ptr ord = std::make_shared(); ord->target = id; ord->item = i; - if (u->stealorders) delete u->stealorders; - u->stealorders = ord; + u->stealthorders = ord; } } @@ -1362,9 +1359,9 @@ void Game::ProcessFindOrder(Unit *u, AString *o, OrdersCheck *pCheck) return; } if (!pCheck) { - FindOrder *f = new FindOrder; + std::shared_ptr f = std::make_shared(); f->find = n; - u->findorders.Add(f); + u->findorders.push_back(f); } } @@ -1441,8 +1438,7 @@ void Game::ProcessTaxOrder(Unit *u, OrdersCheck *pCheck) return; } if (Globals->TAX_PILLAGE_MONTH_LONG && u->monthorders) { - delete u->monthorders; - u->monthorders = NULL; + u->monthorders = nullptr; string err = string("TAX: Overwriting previous ") + (u->inTurnBlock ? "DELAYED " : "") + "month-long order."; parse_error(pCheck, u, 0, err); } @@ -1457,8 +1453,7 @@ void Game::ProcessPillageOrder(Unit *u, OrdersCheck *pCheck) return; } if (Globals->TAX_PILLAGE_MONTH_LONG && u->monthorders) { - delete u->monthorders; - u->monthorders = NULL; + u->monthorders = nullptr; string err = string("PILLAGE: Overwriting previous ") + (u->inTurnBlock ? "DELAYED " : "") + "month-long order."; parse_error(pCheck, u, 0, err); } @@ -1512,7 +1507,7 @@ void Game::ProcessEnterOrder(Unit *u, AString *o, OrdersCheck *pCheck) void Game::ProcessBuildOrder(Unit *unit, AString *o, OrdersCheck *pCheck) { AString * token = o->gettoken(); - BuildOrder * order = new BuildOrder; + std::shared_ptr order = std::make_shared(); int maxbuild; // 'incomplete' for ships: @@ -1623,12 +1618,10 @@ void Game::ProcessBuildOrder(Unit *unit, AString *o, OrdersCheck *pCheck) // Now do all of the generic bits... // Check that the unit isn't doing anything else important - if (unit->monthorders || - (Globals->TAX_PILLAGE_MONTH_LONG && - ((unit->taxing == TAX_TAX) || - (unit->taxing == TAX_PILLAGE)))) { - if (unit->monthorders) delete unit->monthorders; - string err = string("BUILD: Overwriting previous ") + (unit->inTurnBlock ? "DELAYED " : "") + "month-long order."; + if (unit->monthorders || (Globals->TAX_PILLAGE_MONTH_LONG && + ((unit->taxing == TAX_TAX) || (unit->taxing == TAX_PILLAGE)))) { + string err = string("BUILD: Overwriting previous ") + + (unit->inTurnBlock ? "DELAYED " : "") + "month-long order."; parse_error(pCheck, unit, 0, err); } @@ -1642,7 +1635,7 @@ void Game::ProcessAttackOrder(Unit *u, AString *o, OrdersCheck *pCheck) UnitId *id = ParseUnit(o); while (id && id->unitnum != -1) { if (!pCheck) { - if (!u->attackorders) u->attackorders = new AttackOrder; + if (!u->attackorders) u->attackorders = std::make_shared(); u->attackorders->targets.push_back(*id); delete id; } @@ -1677,10 +1670,10 @@ void Game::ProcessSellOrder(Unit *u, AString *o, OrdersCheck *pCheck) delete token; if (!pCheck) { - SellOrder *s = new SellOrder; + std::shared_ptr s = std::make_shared(); s->item = it; s->num = num; - u->sellorders.Add(s); + u->sellorders.push_back(s); } } @@ -1728,10 +1721,10 @@ void Game::ProcessBuyOrder(Unit *u, AString *o, OrdersCheck *pCheck) delete token; if (!pCheck) { - BuyOrder *b = new BuyOrder; + std::shared_ptr b = std::make_shared(); b->item = it; b->num = num; - u->buyorders.Add(b); + u->buyorders.push_back(b); } } @@ -1763,16 +1756,14 @@ void Game::ProcessProduceOrder(Unit *u, AString *o, OrdersCheck *pCheck) return; } - ProduceOrder *p = new ProduceOrder; + std::shared_ptr p = std::make_shared(); p->item = it; AString skname = item_def.pSkill; p->skill = LookupSkill(&skname); p->target = target; if (u->monthorders || - (Globals->TAX_PILLAGE_MONTH_LONG && - ((u->taxing == TAX_TAX) || (u->taxing == TAX_PILLAGE)))) { - if (u->monthorders) delete u->monthorders; + (Globals->TAX_PILLAGE_MONTH_LONG && ((u->taxing == TAX_TAX) || (u->taxing == TAX_PILLAGE)))) { string err = string("PRODUCE: Overwriting previous ") + (u->inTurnBlock ? "DELAYED " : "") + "month-long order."; parse_error(pCheck, u, 0, err); } @@ -1782,16 +1773,13 @@ void Game::ProcessProduceOrder(Unit *u, AString *o, OrdersCheck *pCheck) void Game::ProcessWorkOrder(Unit *u, int quiet, OrdersCheck *pCheck) { - ProduceOrder *order = new ProduceOrder; + std::shared_ptr order = std::make_shared(); order->skill = -1; order->item = I_SILVER; order->target = 0; if (quiet) order->quiet = 1; - if (u->monthorders || - (Globals->TAX_PILLAGE_MONTH_LONG && - ((u->taxing == TAX_TAX) || (u->taxing == TAX_PILLAGE)))) { - if (u->monthorders) delete u->monthorders; + if (u->monthorders || (Globals->TAX_PILLAGE_MONTH_LONG && ((u->taxing == TAX_TAX) || (u->taxing == TAX_PILLAGE)))) { string err = string("WORK: Overwriting previous ") + (u->inTurnBlock ? "DELAYED " : "") + "month-long order."; parse_error(pCheck, u, 0, err); } @@ -1801,12 +1789,12 @@ void Game::ProcessWorkOrder(Unit *u, int quiet, OrdersCheck *pCheck) void Game::ProcessTeachOrder(Unit *u, AString *o, OrdersCheck *pCheck) { - TeachOrder *order = 0; + std::shared_ptr order = nullptr; if (u->monthorders && u->monthorders->type == O_TEACH) { - order = (TeachOrder *) u->monthorders; + order = std::dynamic_pointer_cast(u->monthorders); } else { - order = new TeachOrder; + order = std::make_shared(); } int students = 0; @@ -1826,9 +1814,7 @@ void Game::ProcessTeachOrder(Unit *u, AString *o, OrdersCheck *pCheck) } if ((u->monthorders && u->monthorders->type != O_TEACH) || - (Globals->TAX_PILLAGE_MONTH_LONG && - ((u->taxing == TAX_TAX) || (u->taxing == TAX_PILLAGE)))) { - if (u->monthorders) delete u->monthorders; + (Globals->TAX_PILLAGE_MONTH_LONG && ((u->taxing == TAX_TAX) || (u->taxing == TAX_PILLAGE)))) { string err = string("TEACH: Overwriting previous ") + (u->inTurnBlock ? "DELAYED " : "") + "month-long order."; parse_error(pCheck, u, 0, err); } @@ -1846,7 +1832,7 @@ void Game::ProcessStudyOrder(Unit *u, AString *o, OrdersCheck *pCheck) int sk = ParseSkill(token); delete token; - StudyOrder *order = new StudyOrder; + std::shared_ptr order = std::make_shared(); order->skill = sk; order->days = 0; // parse study level: @@ -1858,9 +1844,7 @@ void Game::ProcessStudyOrder(Unit *u, AString *o, OrdersCheck *pCheck) order->level = -1; if (u->monthorders || - (Globals->TAX_PILLAGE_MONTH_LONG && - ((u->taxing == TAX_TAX) || (u->taxing == TAX_PILLAGE)))) { - if (u->monthorders) delete u->monthorders; + (Globals->TAX_PILLAGE_MONTH_LONG && ((u->taxing == TAX_TAX) || (u->taxing == TAX_PILLAGE)))) { string err = string("STUDY: Overwriting previous ") + (u->inTurnBlock ? "DELAYED " : "") + "month-long order."; parse_error(pCheck, u, 0, err); } @@ -1972,10 +1956,10 @@ void Game::ProcessWithdrawOrder(Unit *unit, AString *o, OrdersCheck *pCheck) } if (!pCheck) { - WithdrawOrder *order = new WithdrawOrder; + std::shared_ptr order = std::make_shared(); order->item = item; order->amount = amt; - unit->withdraworders.Add(order); + unit->withdraworders.push_back(order); } return; } @@ -1985,7 +1969,8 @@ AString *Game::ProcessTurnOrder(Unit *unit, istream& f, OrdersCheck *pCheck, int int turnDepth = 1; int turnLast = 1; int formDepth = 0; - TurnOrder *tOrder = new TurnOrder; + + std::shared_ptr tOrder = std::make_shared(); tOrder->repeating = repeat; AString order, *token; @@ -1998,7 +1983,7 @@ AString *Game::ProcessTurnOrder(Unit *unit, istream& f, OrdersCheck *pCheck, int order = AString("#end"); } - AString saveorder = order; + std::string saveorder = order.const_str(); // In order to allow @endturn to work the same as endturn we need to check for and eat the possible @ std::ignore = order.getat(); // we don't care about whether it was set or not, so just ignore the return value token = order.gettoken(); @@ -2012,7 +1997,7 @@ AString *Game::ProcessTurnOrder(Unit *unit, istream& f, OrdersCheck *pCheck, int break; } turnDepth++; - tOrder->turnOrders.push_back(saveorder.const_str()); + tOrder->turnOrders.push_back(saveorder); turnLast = 1; break; case O_FORM: @@ -2022,7 +2007,7 @@ AString *Game::ProcessTurnOrder(Unit *unit, istream& f, OrdersCheck *pCheck, int } turnLast = 0; formDepth++; - tOrder->turnOrders.push_back(saveorder.const_str()); + tOrder->turnOrders.push_back(saveorder); break; case O_ENDFORM: if (turnLast) { @@ -2032,13 +2017,13 @@ AString *Game::ProcessTurnOrder(Unit *unit, istream& f, OrdersCheck *pCheck, int } else { parse_error(pCheck, unit, 0, "TURN: without ENDTURN."); if (!--turnDepth) { - unit->turnorders.Add(tOrder); + unit->turnorders.push_back(tOrder); return new AString(saveorder); } } } formDepth--; - tOrder->turnOrders.push_back(saveorder.const_str()); + tOrder->turnOrders.push_back(saveorder); turnLast = 1; break; case O_UNIT: @@ -2050,7 +2035,7 @@ AString *Game::ProcessTurnOrder(Unit *unit, istream& f, OrdersCheck *pCheck, int parse_error(pCheck, unit, 0, "FORM: without END."); } parse_error(pCheck, unit, 0, "TURN: without ENDTURN."); - unit->turnorders.Add(tOrder); + unit->turnorders.push_back(tOrder); return new AString(saveorder); break; case O_ENDTURN: @@ -2058,21 +2043,21 @@ AString *Game::ProcessTurnOrder(Unit *unit, istream& f, OrdersCheck *pCheck, int parse_error(pCheck, unit, 0, "ENDTURN: without TURN."); } else { if (--turnDepth) - tOrder->turnOrders.push_back(saveorder.const_str()); + tOrder->turnOrders.push_back(saveorder); turnLast = 0; } break; default: - tOrder->turnOrders.push_back(saveorder.const_str()); + tOrder->turnOrders.push_back(saveorder); break; } if (!pCheck && unit->former && unit->former->format) - unit->former->oldorders.push_back(saveorder.const_str()); + unit->former->oldorders.push_back(saveorder); delete token; } } - unit->turnorders.Add(tOrder); + unit->turnorders.push_back(tOrder); return NULL; } @@ -2148,13 +2133,13 @@ void Game::ProcessExchangeOrder(Unit *unit, AString *o, OrdersCheck *pCheck) } if (!pCheck) { - ExchangeOrder *order = new ExchangeOrder; + std::shared_ptr order = std::make_shared(); order->giveItem = itemGive; order->giveAmount = amtGive; order->expectAmount = amtExpected; order->expectItem = itemExpected; order->target = t; - unit->exchangeorders.Add(order); + unit->exchangeorders.push_back(order); } } @@ -2315,14 +2300,14 @@ void Game::ProcessGiveOrder(int order, Unit *unit, AString *o, OrdersCheck *pChe } if (!pCheck) { - GiveOrder *go = new GiveOrder; + std::shared_ptr go = std::make_shared(); go->type = order; go->item = item; go->target = t; go->amount = amt; go->except = excpt; go->unfinished = unfinished; - unit->giveorders.Add(go); + unit->giveorders.push_back(go); } return; } @@ -2772,22 +2757,19 @@ void Game::ProcessAddressOrder(Unit *u, AString *o, OrdersCheck *pCheck) void Game::ProcessAdvanceOrder(Unit *u, AString *o, OrdersCheck *pCheck) { - MoveOrder *m = 0; - if ((u->monthorders && u->monthorders->type != O_ADVANCE) || - (Globals->TAX_PILLAGE_MONTH_LONG && - ((u->taxing == TAX_TAX) || (u->taxing == TAX_PILLAGE)))) { + (Globals->TAX_PILLAGE_MONTH_LONG && ((u->taxing == TAX_TAX) || (u->taxing == TAX_PILLAGE)))) { string err = string("ADVANCE: Overwriting previous ") + (u->inTurnBlock ? "DELAYED " : "") + "month-long order."; parse_error(pCheck, u, 0, err); - if (u->monthorders) delete u->monthorders; - u->monthorders = 0; + u->monthorders = nullptr; } if (Globals->TAX_PILLAGE_MONTH_LONG) u->taxing = TAX_NONE; if (!u->monthorders) { - u->monthorders = new MoveOrder; + u->monthorders = std::make_shared(); u->monthorders->type = O_ADVANCE; } - m = (MoveOrder *) u->monthorders; + + std::shared_ptr m = std::dynamic_pointer_cast(u->monthorders); m->advancing = 1; for (;;) { @@ -2797,9 +2779,8 @@ void Game::ProcessAdvanceOrder(Unit *u, AString *o, OrdersCheck *pCheck) delete t; if (d!=-1) { if (!pCheck) { - MoveDir *x = new MoveDir; - x->dir = d; - m->dirs.Add(x); + MoveDir x(d); + m->dirs.push_back(x); } } else { parse_error(pCheck, u, 0, "ADVANCE: Warning, bad direction."); @@ -2810,21 +2791,18 @@ void Game::ProcessAdvanceOrder(Unit *u, AString *o, OrdersCheck *pCheck) void Game::ProcessMoveOrder(Unit *u, AString *o, OrdersCheck *pCheck) { - MoveOrder *m = 0; - if ((u->monthorders && u->monthorders->type != O_MOVE) || - (Globals->TAX_PILLAGE_MONTH_LONG && - ((u->taxing == TAX_TAX) || (u->taxing == TAX_PILLAGE)))) { + (Globals->TAX_PILLAGE_MONTH_LONG && ((u->taxing == TAX_TAX) || (u->taxing == TAX_PILLAGE)))) { string err = string("MOVE: Overwriting previous ") + (u->inTurnBlock ? "DELAYED " : "") + "month-long order."; parse_error(pCheck, u, 0, err); - if (u->monthorders) delete u->monthorders; - u->monthorders = 0; + u->monthorders = nullptr; } if (Globals->TAX_PILLAGE_MONTH_LONG) u->taxing = TAX_NONE; if (!u->monthorders) { - u->monthorders = new MoveOrder; + u->monthorders = std::make_shared(); } - m = (MoveOrder *) u->monthorders; + + std::shared_ptr m = std::dynamic_pointer_cast(u->monthorders); m->advancing = 0; for (;;) { @@ -2834,9 +2812,8 @@ void Game::ProcessMoveOrder(Unit *u, AString *o, OrdersCheck *pCheck) delete t; if (d!=-1) { if (!pCheck) { - MoveDir *x = new MoveDir; - x->dir = d; - m->dirs.Add(x); + MoveDir x(d); + m->dirs.push_back(x); } } else { parse_error(pCheck, u, 0, "MOVE: Warning, bad direction."); @@ -2847,21 +2824,18 @@ void Game::ProcessMoveOrder(Unit *u, AString *o, OrdersCheck *pCheck) void Game::ProcessSailOrder(Unit *u, AString *o, OrdersCheck *pCheck) { - SailOrder *m = 0; - if ((u->monthorders && u->monthorders->type != O_SAIL) || - (Globals->TAX_PILLAGE_MONTH_LONG && - ((u->taxing == TAX_TAX) || (u->taxing == TAX_PILLAGE)))) { + (Globals->TAX_PILLAGE_MONTH_LONG && ((u->taxing == TAX_TAX) || (u->taxing == TAX_PILLAGE)))) { string err = string("SAIL: Overwriting previous ") + (u->inTurnBlock ? "DELAYED " : "") + "month-long order."; parse_error(pCheck, u, 0, err); - if (u->monthorders) delete u->monthorders; - u->monthorders = 0; + u->monthorders = nullptr; } if (Globals->TAX_PILLAGE_MONTH_LONG) u->taxing = TAX_NONE; if (!u->monthorders) { - u->monthorders = new SailOrder; + u->monthorders = std::make_shared(); } - m = (SailOrder *) u->monthorders; + + std::shared_ptr m = std::dynamic_pointer_cast(u->monthorders); for (;;) { AString *t = o->gettoken(); @@ -2874,9 +2848,8 @@ void Game::ProcessSailOrder(Unit *u, AString *o, OrdersCheck *pCheck) } else { if (d < NDIRS || d == MOVE_PAUSE) { if (!pCheck) { - MoveDir *x = new MoveDir; - x->dir = d; - m->dirs.Add(x); + MoveDir x(d); + m->dirs.push_back(x); } } else { parse_error(pCheck, u, 0, "SAIL: Warning, bad direction."); @@ -2891,7 +2864,7 @@ void Game::ProcessEvictOrder(Unit *u, AString *o, OrdersCheck *pCheck) UnitId *id = ParseUnit(o); while (id && id->unitnum != -1) { if (!pCheck) { - if (!u->evictorders) u->evictorders = new EvictOrder; + if (!u->evictorders) u->evictorders = std::make_shared(); u->evictorders->targets.push_back(*id); delete id; } @@ -2901,15 +2874,13 @@ void Game::ProcessEvictOrder(Unit *u, AString *o, OrdersCheck *pCheck) void Game::ProcessIdleOrder(Unit *u, AString *o, OrdersCheck *pCheck) { - if (u->monthorders || (Globals->TAX_PILLAGE_MONTH_LONG && - ((u->taxing == TAX_TAX) || (u->taxing == TAX_PILLAGE)))) { - if (u->monthorders) delete u->monthorders; + if (u->monthorders || + (Globals->TAX_PILLAGE_MONTH_LONG && ((u->taxing == TAX_TAX) || (u->taxing == TAX_PILLAGE)))) { string err = string("IDLE: Overwriting previous ") + (u->inTurnBlock ? "DELAYED " : "") + "month-long order."; parse_error(pCheck, u, 0, err); } if (Globals->TAX_PILLAGE_MONTH_LONG) u->taxing = TAX_NONE; - IdleOrder *i = new IdleOrder; - u->monthorders = i; + u->monthorders = std::make_shared(); } void Game::ProcessTransportOrder(Unit *u, AString *o, OrdersCheck *pCheck) @@ -2967,14 +2938,14 @@ void Game::ProcessTransportOrder(Unit *u, AString *o, OrdersCheck *pCheck) } if (!pCheck) { - TransportOrder *order = new TransportOrder; + std::shared_ptr order = std::make_shared(); // At this point we don't know that transport phase for the order but // we will set that later. order->item = item; order->target = tar; order->amount = amt; order->except = except; - u->transportorders.Add(order); + u->transportorders.push_back(order); } return; } @@ -3017,11 +2988,10 @@ void Game::ProcessJoinOrder(Unit *u, AString *o, OrdersCheck *pCheck) delete token; } if (!pCheck) { - JoinOrder *ord = new JoinOrder; + std::shared_ptr ord = std::make_shared(); ord->target = id; ord->overload = overload; ord->merge = merge; - if (u->joinorders) delete u->joinorders; u->joinorders = ord; } } @@ -3071,11 +3041,9 @@ void Game::ProcessSacrificeOrder(Unit *unit, AString *o, OrdersCheck *pCheck) return; } if (!pCheck) { - SacrificeOrder *order = new SacrificeOrder; - order->item = item; - order->amount = amt; - if (unit->sacrificeorders) delete unit->sacrificeorders; - unit->sacrificeorders = order; + unit->sacrificeorders = std::make_shared(); + unit->sacrificeorders->item = item; + unit->sacrificeorders->amount = amt; } return; } @@ -3134,11 +3102,9 @@ void Game::ProcessAnnihilateOrder(Unit *unit, AString *o, OrdersCheck *pCheck) } if (!pCheck) { - AnnihilateOrder *order = new AnnihilateOrder; - order->xloc = x; - order->yloc = y; - order->zloc = z; - if (unit->annihilateorders) delete unit->annihilateorders; - unit->annihilateorders = order; + unit->annihilateorders = std::make_shared(); + unit->annihilateorders->xloc = x; + unit->annihilateorders->yloc = y; + unit->annihilateorders->zloc = z; } } diff --git a/runorders.cpp b/runorders.cpp index c75349a6..ce39a161 100644 --- a/runorders.cpp +++ b/runorders.cpp @@ -26,6 +26,8 @@ #include "game.h" #include "gamedata.h" #include "quests.h" +#include +#include using namespace std; @@ -148,8 +150,7 @@ void Game::RunCastOrders() for(auto u: o->units) { if (u->castorders) { RunACastOrder(r, o, u); - delete u->castorders; - u->castorders = 0; + u->castorders = nullptr; } } } @@ -203,30 +204,27 @@ void Game::RunStealOrders() forlist(&r->objects) { Object *o = (Object *) elem; for(auto u: o->units) { - if (u->stealorders) { - if (u->stealorders->type == O_STEAL) { + if (u->stealthorders) { + if (u->stealthorders->type == O_STEAL) { Do1Steal(r, o, u); - } else if (u->stealorders->type == O_ASSASSINATE) { + } else if (u->stealthorders->type == O_ASSASSINATE) { Do1Assassinate(r, o, u); } - delete u->stealorders; - u->stealorders = 0; + u->stealthorders = nullptr; } } } } } -AList *Game::CanSeeSteal(ARegion *r, Unit *u) +std::vector>Game::CanSeeSteal(ARegion *r, Unit *u) { - AList *retval = new AList; + std::vector>retval; forlist(&factions) { Faction *f = (Faction *) elem; if (r->Present(f)) { if (f->CanSee(r, u, Globals->SKILL_PRACTICE_AMOUNT > 0)) { - FactionPtr *p = new FactionPtr; - p->ptr = f; - retval->Add(p); + retval.push_back(std::shared_ptr(f)); } } } @@ -235,7 +233,7 @@ AList *Game::CanSeeSteal(ARegion *r, Unit *u) void Game::Do1Assassinate(ARegion *r, Object *o, Unit *u) { - AssassinateOrder *so = (AssassinateOrder *) u->stealorders; + std::shared_ptr so = std::dynamic_pointer_cast(u->stealthorders); Unit *tar = r->get_unit_id(*(so->target), u->faction->num); if (!tar) { @@ -264,16 +262,14 @@ void Game::Do1Assassinate(ARegion *r, Object *o, Unit *u) return; } - // Make sure we dispose of the allocated AList properly until we get rid of ALists entirely - std::unique_ptr seers(CanSeeSteal(r, u)); + std::vector> seers(CanSeeSteal(r, u)); int succ = 1; - forlist(seers) { - Faction *f = ((FactionPtr *) elem)->ptr; - if (f == tar->faction) { + for(auto f: seers) { + if (f->num == tar->faction->num) { succ = 0; break; } - if (f->get_attitude(tar->faction->num) == A_ALLY) { + if ((f->get_attitude(tar->faction->num)) == A_ALLY) { succ = 0; break; } @@ -285,8 +281,7 @@ void Game::Do1Assassinate(ARegion *r, Object *o, Unit *u) if (!succ) { string temp = string(u->name->const_str()) + " is caught attempting to assassinate " + tar->name->const_str() + " in " + r->name->const_str() + "."; - forlist(seers) { - Faction *f = ((FactionPtr *) elem)->ptr; + for(auto f: seers) { f->event(temp, "combat"); } // One learns from one's mistakes. Surviving them is another matter! @@ -312,7 +307,7 @@ void Game::Do1Assassinate(ARegion *r, Object *o, Unit *u) void Game::Do1Steal(ARegion *r, Object *o, Unit *u) { - StealOrder *so = (StealOrder *) u->stealorders; + std::shared_ptr so = std::dynamic_pointer_cast(u->stealthorders); Unit *tar = r->get_unit_id(*so->target, u->faction->num); if (!tar) { @@ -338,12 +333,10 @@ void Game::Do1Steal(ARegion *r, Object *o, Unit *u) return; } - // Make sure we dispose of the allocated AList properly until we get rid of alists entirely. - std::unique_ptr seers(CanSeeSteal(r, u)); + std::vector> seers(CanSeeSteal(r, u)); int succ = 1; - forlist(seers) { - Faction *f = ((FactionPtr *) elem)->ptr; - if (f == tar->faction) { + for(auto f: seers) { + if (f->num == tar->faction->num) { succ = 0; break; } @@ -360,8 +353,7 @@ void Game::Do1Steal(ARegion *r, Object *o, Unit *u) if (!succ) { string temp = string(u->name->const_str()) + " is caught attempting to steal from " + tar->name->const_str() + " in " + r->name->const_str() + "."; - forlist(seers) { - Faction *f = ((FactionPtr *) elem)->ptr; + for(auto f: seers) { f->event(temp, "theft"); } // One learns from one's mistakes. Surviving them is another matter! @@ -395,13 +387,10 @@ void Game::Do1Steal(ARegion *r, Object *o, Unit *u) u->items.SetNum(so->item, u->items.GetNum(so->item) + amt); tar->items.SetNum(so->item, tar->items.GetNum(so->item) - amt); - { - string temp = string(u->name->const_str()) + " steals " + - ItemString(so->item, amt) + " from "+ tar->name->const_str() + "."; - forlist(seers) { - Faction *f = ((FactionPtr *) elem)->ptr; - f->event(temp, "theft"); - } + string temp = string(u->name->const_str()) + " steals " + + ItemString(so->item, amt) + " from "+ tar->name->const_str() + "."; + for(auto f: seers) { + f->event(temp, "theft"); } tar->event("Has " + ItemString(so->item, amt) + " stolen.", "theft"); @@ -458,12 +447,11 @@ void Game::RunForgetOrders() forlist(&r->objects) { Object *o = (Object *) elem; for(auto u: o->units) { - forlist(&u->forgetorders) { - ForgetOrder *fo = (ForgetOrder *) elem; + for(auto fo: u->forgetorders) { u->ForgetSkill(fo->skill); u->event("Forgets " + string(SkillStrs(fo->skill).const_str()) + ".", "forget"); } - u->forgetorders.DeleteAll(); + u->forgetorders.clear(); } } } @@ -544,7 +532,9 @@ void Game::Do1Destroy(ARegion *r, Object *o, Unit *u) { destroyPower = structurePoints; } else { - destroyablePoints = std::max(Globals->MIN_DESTROY_POINTS, maxStructurePoints * Globals->MAX_DESTROY_PERCENT / 100); + destroyablePoints = std::max( + Globals->MIN_DESTROY_POINTS, maxStructurePoints * Globals->MAX_DESTROY_PERCENT / 100 + ); destroyablePoints = std::max(0, std::min(structurePoints, destroyablePoints) - o->destroyed); if (Globals->DESTROY_BEHAVIOR == DestroyBehavior::PER_SKILL) { @@ -614,8 +604,7 @@ void Game::RunFindUnit(Unit *u) { int all = 0; Faction *fac; - forlist(&u->findorders) { - FindOrder *f = (FindOrder *) elem; + for(auto f: u->findorders) { if (f->find == 0) all = 1; if (!all) { fac = GetFaction(&factions, f->find); @@ -637,7 +626,7 @@ void Game::RunFindUnit(Unit *u) } } } - u->findorders.DeleteAll(); + u->findorders.clear(); } void Game::RunTaxOrders() @@ -847,7 +836,7 @@ void Game::RunPromoteOrders() if (u && u->promote) { Do1PromoteOrder(o, u); delete u->promote; - u->promote = 0; + u->promote = nullptr; } } } @@ -862,8 +851,7 @@ void Game::RunPromoteOrders() u = o->GetOwner(); if (u && u->evictorders) { Do1EvictOrder(o, u); - delete u->evictorders; - u->evictorders = 0; + u->evictorders = nullptr; } } } @@ -891,12 +879,10 @@ void Game::RunPromoteOrders() if (u->evictorders) { if (o->type != O_DUMMY) { u->error("EVICT: Must be owner"); - delete u->evictorders; - u->evictorders = 0; + u->evictorders = nullptr; } else { u->error("EVICT: Can only evict inside structures."); - delete u->evictorders; - u->evictorders = 0; + u->evictorders = nullptr; } } } @@ -925,16 +911,14 @@ void Game::Do1PromoteOrder(Object *obj, Unit *u) void Game::Do1EvictOrder(Object *obj, Unit *u) { - EvictOrder *ord = u->evictorders; - if (obj->region->type == R_NEXUS) { u->error("Evict: Evict does not work in the Nexus."); return; } - obj->region->deduplicate_unit_list(ord->targets, u->faction->num); + obj->region->deduplicate_unit_list(u->evictorders->targets, u->faction->num); - for(auto id: ord->targets) { + for(auto id: u->evictorders->targets) { Unit *tar = obj->get_unit_id(&id, u->faction->num); if (!tar) continue; if (obj->IsFleet() && @@ -948,7 +932,7 @@ void Game::Do1EvictOrder(Object *obj, Unit *u) tar->event("Evicted from " + string(obj->name->const_str()) + " by " + u->name->const_str(), "evict"); u->event("Evicted " + string(tar->name->const_str()) + " from " + obj->name->const_str(), "evict"); } - ord->targets.clear(); + u->evictorders->targets.clear(); } /* RunEnterOrders is performed in TWO phases: one in the @@ -1008,13 +992,11 @@ void Game::Do1EnterOrder(ARegion *r, Object *in, Unit *u) void Game::Do1JoinOrder(ARegion *r, Object *in, Unit *u) { - JoinOrder *jo; Unit *tar; Object *to, *from; Item *item; - jo = (JoinOrder *) u->joinorders; - tar = r->get_unit_id(*jo->target, u->faction->num); + tar = r->get_unit_id(*u->joinorders->target, u->faction->num); if (!tar) { u->error("JOIN: No such unit."); @@ -1032,9 +1014,8 @@ void Game::Do1JoinOrder(ARegion *r, Object *in, Unit *u) return; } - if (jo->merge) { - if (!u->object->IsFleet() || - u->object->GetOwner()->num != u->num) { + if (u->joinorders->merge) { + if (!u->object->IsFleet() || u->object->GetOwner()->num != u->num) { u->error("JOIN MERGE: Not fleet owner."); return; } @@ -1062,8 +1043,7 @@ void Game::Do1JoinOrder(ARegion *r, Object *in, Unit *u) go.target = &id; go.type = O_GIVE; go.merge = 1; - DoGiveOrder(r, u, &go); - go.target = NULL; + DoGiveOrder(r, u, std::make_shared(go)); } for(auto pass: u->object->units) { pass->MoveUnit(to); @@ -1087,9 +1067,7 @@ void Game::Do1JoinOrder(ARegion *r, Object *in, Unit *u) u->error("JOIN: Is refused entry."); return; } - if (to->IsFleet() && - !jo->overload && - to->FleetCapacity() < to->FleetLoad() + u->Weight()) { + if (to->IsFleet() && !u->joinorders->overload && to->FleetCapacity() < to->FleetLoad() + u->Weight()) { u->event("JOIN: Fleet would be overloaded.", "join"); return; } @@ -1394,9 +1372,8 @@ void Game::DoAttackOrders() } } else { if (u->attackorders && u->IsAlive()) { - AttackOrder *ord = u->attackorders; - r->deduplicate_unit_list(ord->targets, u->faction->num); - for (auto id: ord->targets) { + r->deduplicate_unit_list(u->attackorders->targets, u->faction->num); + for (auto id: u->attackorders->targets) { Unit *t = r->get_unit_id(id, u->faction->num); if (u->canattack && u->IsAlive()) { if (t) { @@ -1406,7 +1383,6 @@ void Game::DoAttackOrders() } } } - delete ord; u->attackorders = 0; } } @@ -1451,15 +1427,18 @@ void Game::RunSellOrders() forlist((®ions)) { ARegion *r = (ARegion *) elem; for (const auto& m : r->markets) { - if (m->type == Market::M_SELL) DoSell(r, m); + if (m->type == Market::MarketType::M_SELL) DoSell(r, m); } forlist((&r->objects)) { Object *obj = (Object *) elem; for(auto u: obj->units) { - forlist((&u->sellorders)) { - u->error("SELL: Can't sell that."); - } - u->sellorders.DeleteAll(); + std::for_each( + u->sellorders.begin(), u->sellorders.end(), + [&u](std::shared_ptr o) { + u->error("SELL: Can't sell " + ItemString(o->item, o->num, FULLNUM) + "."); + } + ); + u->sellorders.clear(); } } } @@ -1471,8 +1450,7 @@ int Game::GetSellAmount(ARegion *r, Market *m) forlist((&r->objects)) { Object *obj = (Object *) elem; for(auto u: obj->units) { - forlist ((&u->sellorders)) { - SellOrder *o = (SellOrder *) elem; + for(auto o: u->sellorders) { if (o->item == m->item) { if (o->num == -1) { o->num = u->items.CanSell(o->item); @@ -1501,8 +1479,8 @@ void Game::DoSell(ARegion *r, Market *m) forlist((&r->objects)) { Object *obj = (Object *) elem; for(auto u: obj->units) { - forlist((&u->sellorders)) { - SellOrder *o = (SellOrder *) elem; + for(auto oit = u->sellorders.begin(); oit != u->sellorders.end(); ++oit) { + std::shared_ptr o = *oit; if (o->item == m->item) { int temp = 0; if (o->num > u->GetSharedNum(o->item)) { @@ -1510,8 +1488,7 @@ void Game::DoSell(ARegion *r, Market *m) u->error("SELL: Unit attempted to sell more than it had."); } if (attempted) { - temp = (m->amount *o->num + getrandom(attempted)) - / attempted; + temp = (m->amount *o->num + getrandom(attempted)) / attempted; if (temp<0) temp = 0; } attempted -= o->num; @@ -1519,9 +1496,10 @@ void Game::DoSell(ARegion *r, Market *m) m->activity += temp; u->ConsumeShared(o->item, temp); u->SetMoney(u->GetMoney() + temp * m->price); - u->sellorders.Remove(o); + oit = u->sellorders.erase(oit); + // walk ack one step so that the for loop will put us at the right place after the delete + --oit; u->event("Sells " + ItemString(o->item, temp) + " at $" + to_string(m->price) + " each.", "sell"); - delete o; } } } @@ -1534,15 +1512,18 @@ void Game::RunBuyOrders() forlist((®ions)) { ARegion *r = (ARegion *) elem; for (const auto& m : r->markets) { - if (m->type == Market::M_BUY) DoBuy(r, m); + if (m->type == Market::MarketType::M_BUY) DoBuy(r, m); } forlist((&r->objects)) { Object *obj = (Object *) elem; for(auto u: obj->units) { - forlist((&u->buyorders)) { - u->error("BUY: Can't buy that."); - } - u->buyorders.DeleteAll(); + std::for_each( + u->buyorders.begin(), u->buyorders.end(), + [&u](std::shared_ptr o) { + u->error("BUY: Can't buy " + ItemString(o->item, o->num, FULLNUM) + "."); + } + ); + u->buyorders.clear(); } } } @@ -1554,8 +1535,8 @@ int Game::GetBuyAmount(ARegion *r, Market *m) forlist((&r->objects)) { Object *obj = (Object *) elem; for(auto u: obj->units) { - forlist ((&u->buyorders)) { - BuyOrder *o = (BuyOrder *) elem; + for(auto oit = u->buyorders.begin(); oit != u->buyorders.end(); ++oit) { + std::shared_ptr o = *oit; if (o->item == m->item) { if (ItemDefs[o->item].type & IT_MAN) { if (u->type == U_MAGE) { @@ -1601,8 +1582,9 @@ int Game::GetBuyAmount(ARegion *r, Market *m) num += o->num; } if (o->num < 1 && o->num != -1) { - u->buyorders.Remove(o); - delete o; + oit = u->buyorders.erase(oit); + // back up the iterator so that the for loop will put us at the right place after the delete + --oit; } } } @@ -1623,8 +1605,8 @@ void Game::DoBuy(ARegion *r, Market *m) forlist((&r->objects)) { Object *obj = (Object *) elem; for(auto u: obj->units) { - forlist((&u->buyorders)) { - BuyOrder *o = (BuyOrder *) elem; + for(auto oit = u->buyorders.begin(); oit != u->buyorders.end(); ++oit) { + std::shared_ptr o = *oit; if (o->item == m->item) { int temp = 0; if (m->amount == -1) { @@ -1632,8 +1614,7 @@ void Game::DoBuy(ARegion *r, Market *m) temp = o->num; } else { if (attempted) { - temp = (m->amount * o->num + - getrandom(attempted)) / attempted; + temp = (m->amount * o->num + getrandom(attempted)) / attempted; if (temp < 0) temp = 0; } attempted -= o->num; @@ -1666,9 +1647,10 @@ void Game::DoBuy(ARegion *r, Market *m) u->items.SetNum(o->item, u->items.GetNum(o->item) + temp); u->faction->DiscoverItem(o->item, 0, 1); u->ConsumeSharedMoney(temp * m->price); - u->buyorders.Remove(o); + oit = u->buyorders.erase(oit); + // back up the iterator so that the for loop will put us at the right place after the delete + --oit; u->event("Buys " + ItemString(o->item, temp) + " at $" + to_string(m->price) + " each.", "buy"); - delete o; } } } @@ -2100,17 +2082,16 @@ void Game::DoWithdrawOrders() forlist((&r->objects)) { Object *obj = (Object *)elem; for(auto u: obj->units) { - forlist((&u->withdraworders)) { - WithdrawOrder *o = (WithdrawOrder *)elem; + for(auto o: u->withdraworders) { if (DoWithdrawOrder(r, u, o)) break; } - u->withdraworders.DeleteAll(); + u->withdraworders.clear(); } } } } -int Game::DoWithdrawOrder(ARegion *r, Unit *u, WithdrawOrder *o) +int Game::DoWithdrawOrder(ARegion *r, Unit *u, std::shared_ptr o) { int itm = o->item; int amt = o->amount; @@ -2152,8 +2133,7 @@ void Game::DoGiveOrders() forlist((&r->objects)) { Object *obj = (Object *) elem; for(auto u: obj->units) { - forlist((&u->giveorders)) { - GiveOrder *o = (GiveOrder *)elem; + for(auto o: u->giveorders) { if (o->item < 0) { if (o->amount == -1) { /* do 'give X unit' command */ @@ -2185,8 +2165,7 @@ void Game::DoGiveOrders() go.item = item->type; go.target = o->target; go.type = o->type; - DoGiveOrder(r, u, &go); - go.target = NULL; + DoGiveOrder(r, u, std::make_shared(go)); } } forlist((&s->items)) { @@ -2204,18 +2183,13 @@ void Game::DoGiveOrders() if (o->item == -NITEMS) { go.unfinished = 1; } - if (go.unfinished) { - go.amount = 1; - } else { - go.amount = 0; - } + go.amount = (go.unfinished ? 1 : 0); } else if (o->unfinished) { go.amount = 0; } if (go.amount) { - DoGiveOrder(r, u, &go); + DoGiveOrder(r, u, std::make_shared(go)); } - go.target = NULL; } } } else { @@ -2228,7 +2202,7 @@ void Game::DoGiveOrders() break; } } - u->giveorders.DeleteAll(); + u->giveorders.clear(); } } } @@ -2241,47 +2215,44 @@ void Game::DoExchangeOrders() forlist((&r->objects)) { Object *obj = (Object *) elem; for(auto u: obj->units) { - forlist((&u->exchangeorders)) { - Order *o = (Order *) elem; - DoExchangeOrder(r, u, (ExchangeOrder *) o); + // Since the exchange command will remove the exchange order, we need to copy the list + std::vector> exchangeorders = u->exchangeorders; + for(auto o: exchangeorders) { + DoExchangeOrder(r, u, o); } + u->exchangeorders.clear(); } } } } -void Game::DoExchangeOrder(ARegion *r, Unit *u, ExchangeOrder *o) +void Game::DoExchangeOrder(ARegion *r, Unit *u, std::shared_ptr o) { // Check if the destination unit exists Unit *t = r->get_unit_id(*o->target, u->faction->num); if (!t) { u->error("EXCHANGE: Nonexistant target (" + o->target->Print() + ")."); - u->exchangeorders.Remove(o); return; } // Check each Item can be given if (ItemDefs[o->giveItem].flags & ItemType::CANTGIVE) { u->error(string("EXCHANGE: Can't trade ") + ItemDefs[o->giveItem].names + "."); - u->exchangeorders.Remove(o); return; } if (ItemDefs[o->expectItem].flags & ItemType::CANTGIVE) { u->error(string("EXCHANGE: Can't trade ") + ItemDefs[o->expectItem].names + "."); - u->exchangeorders.Remove(o); return; } if (ItemDefs[o->giveItem].type & IT_MAN) { u->error("EXCHANGE: Exchange aborted. Men may not be traded."); - u->exchangeorders.Remove(o); return; } if (ItemDefs[o->expectItem].type & IT_MAN) { u->error("EXCHANGE: Exchange aborted. Men may not be traded."); - u->exchangeorders.Remove(o); return; } @@ -2296,14 +2267,12 @@ void Game::DoExchangeOrder(ARegion *r, Unit *u, ExchangeOrder *o) t->error(string("EXCHANGE: Not giving enough. Expecting ") + ItemString(o->expectItem, o->expectAmount) + "."); u->error(string("EXCHANGE: Exchange aborted. Not enough recieved. Expecting ") + ItemString(o->expectItem, o->expectAmount) + "."); - o->exchangeStatus = 0; return; } int exchangeOrderFound = 0; // Check if other unit has a reciprocal exchange order - forlist ((&t->exchangeorders)) { - ExchangeOrder *tOrder = (ExchangeOrder *) elem; + for(auto tOrder: t->exchangeorders) { Unit *ptrUnitTemp = r->get_unit_id(*tOrder->target, t->faction->num); if (ptrUnitTemp == u) { if (tOrder->expectItem == o->giveItem) { @@ -2327,48 +2296,33 @@ void Game::DoExchangeOrder(ARegion *r, Unit *u, ExchangeOrder *o) } else if (tOrder->giveAmount == o->expectAmount) o->exchangeStatus = 1; - if ((o->exchangeStatus == 1) && - (tOrder->exchangeStatus == 1)) { + if ((o->exchangeStatus == 1) && (tOrder->exchangeStatus == 1)) { u->event("Exchanges " + ItemString(o->giveItem, o->giveAmount) + " with " + t->name->const_str() + " for " + ItemString(tOrder->giveItem, tOrder->giveAmount) + ".", "exchange"); t->event("Exchanges " + ItemString(tOrder->giveItem, tOrder->giveAmount) + " with " + u->name->const_str() + " for " + ItemString(o->giveItem, o->giveAmount) + ".", "exchange"); u->ConsumeShared(o->giveItem, o->giveAmount); - t->items.SetNum(o->giveItem, - t->items.GetNum(o->giveItem) + o->giveAmount); + t->items.SetNum(o->giveItem, t->items.GetNum(o->giveItem) + o->giveAmount); t->ConsumeShared(tOrder->giveItem, tOrder->giveAmount); - u->items.SetNum(tOrder->giveItem, - u->items.GetNum(tOrder->giveItem) + - tOrder->giveAmount); + u->items.SetNum(tOrder->giveItem, u->items.GetNum(tOrder->giveItem) + tOrder->giveAmount); u->faction->DiscoverItem(tOrder->giveItem, 0, 1); t->faction->DiscoverItem(o->giveItem, 0, 1); - u->exchangeorders.Remove(o); - t->exchangeorders.Remove(tOrder); + std::erase(t->exchangeorders, tOrder); // safe because we immediately return. return; - } else if ((o->exchangeStatus >= 0) && - (tOrder->exchangeStatus >= 0)) { - u->exchangeorders.Remove(o); - t->exchangeorders.Remove(tOrder); } } } } } if (!exchangeOrderFound) { - if (!u->CanSee(r, t)) { - u->error("EXCHANGE: Nonexistant target (" + o->target->Print() + ")."); - u->exchangeorders.Remove(o); - return; - } else { - u->error("EXCHANGE: target unit did not issue a matching exchange order."); - u->exchangeorders.Remove(o); - return; - } + // since we already checked ability to see above, we can only get here if the target unit didn't issue + // a matching exchange order. + u->error("EXCHANGE: target unit did not issue a matching exchange order."); } } -int Game::DoGiveOrder(ARegion *r, Unit *u, GiveOrder *o) +int Game::DoGiveOrder(ARegion *r, Unit *u, std::shared_ptr o) { int hasitem, ship, num, shipcount, amt, newfleet, cur; int notallied, newlvl, oldlvl; @@ -2787,11 +2741,12 @@ int Game::DoGiveOrder(ARegion *r, Unit *u, GiveOrder *o) u->faction = t->faction; u->event("Is given to your faction.", event_type); - if (notallied && u->monthorders && u->monthorders->type == O_MOVE && - ((MoveOrder *) u->monthorders)->advancing) { - u->error("Unit cannot advance after being given."); - delete u->monthorders; - u->monthorders = 0; + if (notallied && u->monthorders && u->monthorders->type == O_MOVE) { + std::shared_ptr mo = std::dynamic_pointer_cast(u->monthorders); + if (mo->advancing) { + u->error("Unit cannot advance after being given."); + u->monthorders = nullptr; + } } /* Check if any new skill reports have to be shown */ @@ -2971,9 +2926,8 @@ void Game::CheckTransportOrders() forlist((&r->objects)) { Object *obj = (Object *)elem; for(auto u: obj->units) { - forlist ((&u->transportorders)) { + for(auto o: u->transportorders) { // make sure target exists - TransportOrder *o = (TransportOrder *)elem; if (!o->target || o->target->unitnum == -1) { u->error("TRANSPORT: Target does not exist."); o->type = NORDERS; @@ -3019,9 +2973,9 @@ void Game::CheckTransportOrders() bool sender_is_valid_qm = sender_has_qm_skill && sender_owns_qm_building; bool target_is_valid_qm = target_has_qm_skill && target_owns_qm_building; if (sender_is_valid_qm) { - o->phase = target_is_valid_qm ? - TransportOrder::INTER_QM_TRANSPORT : // both sender and target are valid QM - TransportOrder::DISTRIBUTE_FROM_QM; // sender is a valid QM, target isn't + o->phase = target_is_valid_qm + ? TransportOrder::TransportPhase::INTER_QM_TRANSPORT // sender and target are valid QM + : TransportOrder::TransportPhase::DISTRIBUTE_FROM_QM; // sender is valid QM, target isn't } else { // sender isn't a valid QM if (!target_is_valid_qm) { // Non-qms or invalid qms can only send to valid QMs // Give a specific error message depending on why they aren't considered a quartermaster @@ -3036,11 +2990,11 @@ void Game::CheckTransportOrders() continue; } // the target is a valid QM so the send is legal - o->phase = TransportOrder::SHIP_TO_QM; + o->phase = TransportOrder::TransportPhase::SHIP_TO_QM; } int maxdist = Globals->LOCAL_TRANSPORT; - if (o->phase == TransportOrder::INTER_QM_TRANSPORT) { + if (o->phase == TransportOrder::TransportPhase::INTER_QM_TRANSPORT) { maxdist = Globals->NONLOCAL_TRANSPORT; // 0 max distance represents unlimited range if (maxdist > 0 && Globals->TRANSPORT & GameDefs::QM_AFFECT_DIST) { @@ -3062,7 +3016,9 @@ void Game::CheckTransportOrders() dist = regions.GetPlanarDistance(r, tar->region, penalty, maxdist); } if (dist > maxdist) { - u->error("TRANSPORT: Recipient " + string(tar->unit->name->const_str()) + " is too far away."); + u->error( + "TRANSPORT: Recipient " + string(tar->unit->name->const_str()) + " is too far away." + ); o->type = NORDERS; continue; } @@ -3119,13 +3075,13 @@ void Game::RunTransportOrders() { } // Send all items in to QMs from non-QMs - RunTransportPhase(TransportOrder::SHIP_TO_QM); + RunTransportPhase(TransportOrder::TransportPhase::SHIP_TO_QM); // Ship items between QMs - RunTransportPhase(TransportOrder::INTER_QM_TRANSPORT); + RunTransportPhase(TransportOrder::TransportPhase::INTER_QM_TRANSPORT); // Move items from tempororary transport storage to the QM for distribution CollectInterQMTransportItems(); // Send all items out from QMs to non-QMs - RunTransportPhase(TransportOrder::DISTRIBUTE_FROM_QM); + RunTransportPhase(TransportOrder::TransportPhase::DISTRIBUTE_FROM_QM); // erase all transport orders forlist_reuse((®ions)) { @@ -3133,7 +3089,7 @@ void Game::RunTransportOrders() { forlist((&r->objects)) { Object *obj = (Object *)elem; for(auto u: obj->units) { - u->transportorders.DeleteAll(); + u->transportorders.clear(); } } } @@ -3147,8 +3103,7 @@ void Game::RunTransportPhase(TransportOrder::TransportPhase phase) { forlist((&r->objects)) { Object *obj = (Object *)elem; for(auto u: obj->units) { - forlist ((&u->transportorders)) { - TransportOrder *t = (TransportOrder *)elem; + for (auto t: u->transportorders) { if (t->type != O_TRANSPORT) continue; if (t->phase != phase) continue; @@ -3213,7 +3168,7 @@ void Game::RunTransportPhase(TransportOrder::TransportPhase phase) { u->name->const_str() + ".", "transport"); } - if (phase == TransportOrder::INTER_QM_TRANSPORT) { + if (phase == TransportOrder::TransportPhase::INTER_QM_TRANSPORT) { tar->unit->transport_items.SetNum(t->item, amt); } else { tar->unit->items.SetNum(t->item, tar->unit->items.GetNum(t->item) + amt); @@ -3221,7 +3176,6 @@ void Game::RunTransportPhase(TransportOrder::TransportPhase phase) { tar->unit->faction->DiscoverItem(t->item, 0, 1); u->Practice(S_QUARTERMASTER); - } } } @@ -3238,8 +3192,7 @@ void Game::RunSacrificeOrders() { forlist((&r->objects)) { Object *obj = (Object *) elem; for(auto u: obj->units) { - SacrificeOrder *o = u->sacrificeorders; - if (o == nullptr) continue; + if (u->sacrificeorders == nullptr) continue; bool succeeded = false; @@ -3249,7 +3202,7 @@ void Game::RunSacrificeOrders() { Object *sacrifice_object = (Object *) elem; ObjectType sacrifice_type = ObjectDefs[sacrifice_object->type]; if (!(sacrifice_type.flags & ObjectType::SACRIFICE)) continue; - if (sacrifice_type.sacrifice_item != o->item) continue; + if (sacrifice_type.sacrifice_item != u->sacrificeorders->item) continue; if (sacrifice_object->incomplete >= 0) continue; // Make sure any sacrifice rewards are valid -- there must be at least one of an item or replaced @@ -3269,19 +3222,20 @@ void Game::RunSacrificeOrders() { // Ok this sacrifice will be valid succeeded = true; - int current = u->items.GetNum(o->item); - if (current < o->amount) { - u->error("SACRIFICE: You can only sacrifice up to " + ItemString(o->item, current) + "."); - o->amount = current; + int current = u->items.GetNum(u->sacrificeorders->item); + if (current < u->sacrificeorders->amount) { + u->error("SACRIFICE: You can only sacrifice up to " + + ItemString(u->sacrificeorders->item, current) + "."); + u->sacrificeorders->amount = current; } int required = -sacrifice_object->incomplete; - int used = min(required, o->amount); + int used = min(required, u->sacrificeorders->amount); // Okay we have a valid sacrifice. Do it. sacrifice_object->incomplete += used; - u->items.SetNum(o->item, current - used); - u->event("Sacrifices " + ItemString(o->item, used) + ".", "sacrifice"); + u->items.SetNum(u->sacrificeorders->item, current - used); + u->event("Sacrifices " + ItemString(u->sacrificeorders->item, used) + ".", "sacrifice"); // sacrifice objects store the remaining needed sacrifices as negative numbers in incomplete if (sacrifice_object->incomplete >= 0) { // was the reward an item @@ -3307,7 +3261,8 @@ void Game::RunSacrificeOrders() { if (reward_obj != -1 ) { sacrifice_object->type = reward_obj; - string name = string(ObjectDefs[reward_obj].name) + " [" + to_string(sacrifice_object->num) + "]"; + string name = string(ObjectDefs[reward_obj].name) + " [" + + to_string(sacrifice_object->num) + "]"; sacrifice_object->name = new AString(name); u->faction->objectshows.push_back({.obj = reward_obj}); } @@ -3320,7 +3275,8 @@ void Game::RunSacrificeOrders() { // If we didn't succeed, log the error if (!succeeded) { - u->error("SACRIFICE: Unable to sacrifice " + ItemString(o->item, o->amount)); + u->error("SACRIFICE: Unable to sacrifice " + + ItemString(u->sacrificeorders->item, u->sacrificeorders->amount)); } } } @@ -3407,8 +3363,7 @@ void Game::RunAnnihilateOrders() { forlist((&r->objects)) { Object *obj = (Object *) elem; for(auto u: obj->units) { - AnnihilateOrder *o = u->annihilateorders; - if (o == nullptr) continue; + if (u->annihilateorders == nullptr) continue; // Check if the unit has access to the annihilate skill if (u->GetSkill(S_ANNIHILATION) <= 0) { @@ -3417,7 +3372,9 @@ void Game::RunAnnihilateOrders() { } // Ok we have a unit doing a valid annihilate order. - ARegion *target = regions.GetRegion(o->xloc, o->yloc, o->zloc); + ARegion *target = regions.GetRegion( + u->annihilateorders->xloc, u->annihilateorders->yloc, u->annihilateorders->zloc + ); if (target == nullptr) { u->error("ANNIHILATE: Target region does not exist."); continue; diff --git a/spells.cpp b/spells.cpp index 369088df..d5ee945a 100644 --- a/spells.cpp +++ b/spells.cpp @@ -166,7 +166,7 @@ void Game::ProcessMindReading(Unit *u,AString *o, OrdersCheck *pCheck ) return; } - CastMindOrder *order = new CastMindOrder; + std::shared_ptr order = std::make_shared(); order->id = id; order->spell = S_MIND_READING; order->level = 1; @@ -185,7 +185,7 @@ void Game::ProcessBirdLore(Unit *u,AString *o, OrdersCheck *pCheck ) } if (*token == "eagle") { - CastIntOrder *order = new CastIntOrder; + std::shared_ptr order = std::make_shared(); order->spell = S_BIRD_LORE; order->level = 3; u->ClearCastOrders(); @@ -209,7 +209,7 @@ void Game::ProcessBirdLore(Unit *u,AString *o, OrdersCheck *pCheck ) return; } - CastIntOrder *order = new CastIntOrder; + std::shared_ptr order = std::make_shared(); order->spell = S_BIRD_LORE; order->level = 1; order->target = dir; @@ -233,13 +233,11 @@ void Game::ProcessInvisibility(Unit *u,AString *o, OrdersCheck *pCheck ) } delete token; - CastUnitsOrder *order; - if (u->castorders && u->castorders->type == O_CAST && - ((CastOrder *) u->castorders)->spell == S_INVISIBILITY && - ((CastOrder *) u->castorders)->level == 1) { - order = (CastUnitsOrder *) u->castorders; + std::shared_ptr order = std::make_shared(); + if (u->castorders && (u->castorders->type == O_CAST) && + (u->castorders->spell == S_INVISIBILITY) && u->castorders->level == 1) { + order = std::dynamic_pointer_cast(u->castorders); } else { - order = new CastUnitsOrder; order->spell = S_INVISIBILITY; order->level = 1; u->ClearCastOrders(); @@ -256,7 +254,7 @@ void Game::ProcessInvisibility(Unit *u,AString *o, OrdersCheck *pCheck ) void Game::ProcessPhanDemons(Unit *u,AString *o, OrdersCheck *pCheck ) { - CastIntOrder *order = new CastIntOrder; + std::shared_ptr order = std::make_shared(); order->spell = S_CREATE_PHANTASMAL_DEMONS; order->level = 0; order->target = 1; @@ -265,7 +263,6 @@ void Game::ProcessPhanDemons(Unit *u,AString *o, OrdersCheck *pCheck ) if (!token) { u->error("CAST: Illusion to summon must be given."); - delete order; return; } @@ -285,7 +282,6 @@ void Game::ProcessPhanDemons(Unit *u,AString *o, OrdersCheck *pCheck ) if (!order->level) { u->error("CAST: Can't summon that illusion."); - delete order; return; } @@ -304,7 +300,7 @@ void Game::ProcessPhanDemons(Unit *u,AString *o, OrdersCheck *pCheck ) void Game::ProcessPhanUndead(Unit *u,AString *o, OrdersCheck *pCheck) { - CastIntOrder *order = new CastIntOrder; + std::shared_ptr order = std::make_shared(); order->spell = S_CREATE_PHANTASMAL_UNDEAD; order->level = 0; order->target = 1; @@ -313,7 +309,6 @@ void Game::ProcessPhanUndead(Unit *u,AString *o, OrdersCheck *pCheck) if (!token) { u->error("CAST: Must specify which illusion to summon."); - delete order; return; } @@ -333,7 +328,6 @@ void Game::ProcessPhanUndead(Unit *u,AString *o, OrdersCheck *pCheck) if (!order->level) { u->error("CAST: Must specify which illusion to summon."); - delete order; return; } @@ -352,7 +346,7 @@ void Game::ProcessPhanUndead(Unit *u,AString *o, OrdersCheck *pCheck) void Game::ProcessPhanBeasts(Unit *u,AString *o, OrdersCheck *pCheck ) { - CastIntOrder *order = new CastIntOrder; + std::shared_ptr order = std::make_shared(); order->spell = S_CREATE_PHANTASMAL_BEASTS; order->level = 0; order->target = 1; @@ -361,7 +355,6 @@ void Game::ProcessPhanBeasts(Unit *u,AString *o, OrdersCheck *pCheck ) if (!token) { u->error("CAST: Must specify which illusion to summon."); - delete order; return; } @@ -377,7 +370,6 @@ void Game::ProcessPhanBeasts(Unit *u,AString *o, OrdersCheck *pCheck ) delete token; if (!order->level) { - delete order; u->error("CAST: Must specify which illusion to summon."); return; } @@ -392,17 +384,16 @@ void Game::ProcessPhanBeasts(Unit *u,AString *o, OrdersCheck *pCheck ) u->castorders = order; } -void Game::ProcessGenericSpell(Unit *u,int spell, OrdersCheck *pCheck ) +void Game::ProcessGenericSpell(Unit *u,int spell, OrdersCheck *pCheck) { - CastOrder *orders = new CastOrder; - orders->spell = spell; - orders->level = 1; + std::shared_ptr order = std::make_shared(); + order->spell = spell; + order->level = 1; u->ClearCastOrders(); - u->castorders = orders; + u->castorders = order; } -void Game::ProcessRegionSpell(Unit *u, AString *o, int spell, - OrdersCheck *pCheck) +void Game::ProcessRegionSpell(Unit *u, AString *o, int spell, OrdersCheck *pCheck) { AString *token = o->gettoken(); int x = -1; @@ -434,9 +425,8 @@ void Game::ProcessRegionSpell(Unit *u, AString *o, int spell, if (token) { z = token->value(); delete token; - if (z < 0 || (z >= Globals->UNDERWORLD_LEVELS + - Globals->UNDERDEEP_LEVELS + - Globals->ABYSS_LEVEL + 2)) { + if (z < 0 || + (z >= Globals->UNDERWORLD_LEVELS + Globals->UNDERDEEP_LEVELS + Globals->ABYSS_LEVEL + 2)) { u->error("CAST: Invalid Z coordinate specified."); return; } @@ -450,23 +440,22 @@ void Game::ProcessRegionSpell(Unit *u, AString *o, int spell, if (y == -1) y = u->object->region->yloc; if (z == -1) z = u->object->region->zloc; - CastRegionOrder *order; - if (spell == S_TELEPORTATION) - order = new TeleportOrder; - else - order = new CastRegionOrder; + std::shared_ptr order; + u->ClearCastOrders(); + if (spell == S_TELEPORTATION) { + std::shared_ptr tOrder = std::make_shared(); + u->teleportorders = tOrder; + order = tOrder; + } else { + order = std::make_shared(); + u->castorders = order; + } + order->spell = spell; order->level = 1; order->xloc = x; order->yloc = y; order->zloc = z; - - u->ClearCastOrders(); - /* Teleports happen late in the turn! */ - if (spell == S_TELEPORTATION) - u->teleportorders = (TeleportOrder *) order; - else - u->castorders = order; } void Game::ProcessCastPortalLore(Unit *u,AString *o, OrdersCheck *pCheck ) @@ -491,12 +480,11 @@ void Game::ProcessCastPortalLore(Unit *u,AString *o, OrdersCheck *pCheck ) return; } - TeleportOrder *order; - + std::shared_ptr order; if (u->teleportorders && u->teleportorders->spell == S_PORTAL_LORE) { order = u->teleportorders; } else { - order = new TeleportOrder; + order = std::make_shared(); u->ClearCastOrders(); u->teleportorders = order; } @@ -522,6 +510,7 @@ void Game::ProcessCastGateLore(Unit *u,AString *o, OrdersCheck *pCheck ) return; } + std::shared_ptr order = std::make_shared(); if ((*token) == "gate") { delete token; token = o->gettoken(); @@ -531,13 +520,9 @@ void Game::ProcessCastGateLore(Unit *u,AString *o, OrdersCheck *pCheck ) return; } - TeleportOrder *order; - - if (u->teleportorders && u->teleportorders->spell == S_GATE_LORE && - u->teleportorders->gate == token->value()) { + if (u->teleportorders && u->teleportorders->spell == S_GATE_LORE && u->teleportorders->gate == token->value()) { order = u->teleportorders; } else { - order = new TeleportOrder; u->ClearCastOrders(); u->teleportorders = order; } @@ -566,14 +551,9 @@ void Game::ProcessCastGateLore(Unit *u,AString *o, OrdersCheck *pCheck ) } if ((*token) == "random") { - TeleportOrder *order; - - if (u->teleportorders && - u->teleportorders->spell == S_GATE_LORE && - u->teleportorders->gate == -1 ) { + if (u->teleportorders && u->teleportorders->spell == S_GATE_LORE && u->teleportorders->gate == -1 ) { order = u->teleportorders; } else { - order = new TeleportOrder; u->ClearCastOrders(); u->teleportorders = order; } @@ -611,7 +591,7 @@ void Game::ProcessCastGateLore(Unit *u,AString *o, OrdersCheck *pCheck ) if ((*token) == "detect") { delete token; u->ClearCastOrders(); - CastOrder *to = new CastOrder; + std::shared_ptr to = std::make_shared(); to->spell = S_GATE_LORE; to->level = 2; u->castorders = to; @@ -624,10 +604,9 @@ void Game::ProcessCastGateLore(Unit *u,AString *o, OrdersCheck *pCheck ) void Game::ProcessTransmutation(Unit *u, AString *o, OrdersCheck *pCheck) { - CastTransmuteOrder *order; AString *token; - order = new CastTransmuteOrder; + std::shared_ptr order = std::make_shared(); order->spell = S_TRANSMUTATION; order->level = 0; order->item = -1; @@ -636,7 +615,6 @@ void Game::ProcessTransmutation(Unit *u, AString *o, OrdersCheck *pCheck) token = o->gettoken(); if (!token) { u->error("CAST: You must specify what you wish to create."); - delete order; return; } if (token->value() > 0) { @@ -649,7 +627,6 @@ void Game::ProcessTransmutation(Unit *u, AString *o, OrdersCheck *pCheck) delete token; if (order->item == -1) { u->error("CAST: You must specify what you wish to create."); - delete order; return; } @@ -675,7 +652,6 @@ void Game::ProcessTransmutation(Unit *u, AString *o, OrdersCheck *pCheck) break; default: u->error("CAST: Can't create that by transmutation."); - delete order; return; } @@ -931,7 +907,7 @@ int Game::GetRegionInRange(ARegion *r, ARegion *tar, Unit *u, int spell) int Game::RunMindReading(ARegion *r,Unit *u) { - CastMindOrder *order = (CastMindOrder *) u->castorders; + std::shared_ptr order = std::dynamic_pointer_cast(u->castorders); int level = u->GetSkill(S_MIND_READING); Unit *tar = r->get_unit_id(*order->id,u->faction->num); @@ -1301,7 +1277,7 @@ int Game::RunDragonLore(ARegion *r, Unit *u) int Game::RunBirdLore(ARegion *r,Unit *u) { - CastIntOrder *order = (CastIntOrder *) u->castorders; + std::shared_ptr order = std::dynamic_pointer_cast(u->castorders); int type = regions.GetRegionArray(r->zloc)->levelType; if (type != ARegionArray::LEVEL_SURFACE) { @@ -1355,13 +1331,6 @@ int Game::RunBirdLore(ARegion *r,Unit *u) int Game::RunWolfLore(ARegion *r,Unit *u) { - // if (TerrainDefs[r->type].similar_type != R_MOUNTAIN && - // TerrainDefs[r->type].similar_type != R_FOREST) { - // u->error("CAST: Can only summon wolves in mountain and " - // "forest regions."); - // return 0; - // } - int level = u->GetSkill(S_WOLF_LORE); int max = level * level * 4; @@ -1381,7 +1350,7 @@ int Game::RunWolfLore(ARegion *r,Unit *u) int Game::RunInvisibility(ARegion *r,Unit *u) { - CastUnitsOrder *order = (CastUnitsOrder *) u->castorders; + std::shared_ptr order = std::dynamic_pointer_cast(u->castorders); int max = u->GetSkill(S_INVISIBILITY); max = max * max; @@ -1417,7 +1386,7 @@ int Game::RunInvisibility(ARegion *r,Unit *u) int Game::RunPhanDemons(ARegion *r,Unit *u) { - CastIntOrder *order = (CastIntOrder *) u->castorders; + std::shared_ptr order = std::dynamic_pointer_cast(u->castorders); int level = u->GetSkill(S_CREATE_PHANTASMAL_DEMONS); int create,max; @@ -1451,7 +1420,7 @@ int Game::RunPhanDemons(ARegion *r,Unit *u) int Game::RunPhanUndead(ARegion *r,Unit *u) { - CastIntOrder *order = (CastIntOrder *) u->castorders; + std::shared_ptr order = std::dynamic_pointer_cast(u->castorders); int level = u->GetSkill(S_CREATE_PHANTASMAL_UNDEAD); int create,max; @@ -1485,7 +1454,7 @@ int Game::RunPhanUndead(ARegion *r,Unit *u) int Game::RunPhanBeasts(ARegion *r,Unit *u) { - CastIntOrder *order = (CastIntOrder *) u->castorders; + std::shared_ptr order = std::dynamic_pointer_cast(u->castorders); int level = u->GetSkill(S_CREATE_PHANTASMAL_BEASTS); int create,max; @@ -1558,8 +1527,7 @@ int Game::RunClearSkies(ARegion *r, Unit *u) string temp = "Casts Clear Skies"; int val; - CastRegionOrder *order = (CastRegionOrder *)u->castorders; - + std::shared_ptr order = std::dynamic_pointer_cast(u->castorders); RangeType *range = FindRange(SkillDefs[S_CLEAR_SKIES].range); if (range != NULL) { tar = regions.GetRegion(order->xloc, order->yloc, order->zloc); @@ -1579,8 +1547,7 @@ int Game::RunWeatherLore(ARegion *r, Unit *u) ARegion *tar; int val, i; - CastRegionOrder *order = (CastRegionOrder *)u->castorders; - + std::shared_ptr order = std::dynamic_pointer_cast(u->castorders); tar = regions.GetRegion(order->xloc, order->yloc, order->zloc); val = GetRegionInRange(r, tar, u, S_WEATHER_LORE); if (!val) return 0; @@ -1612,8 +1579,7 @@ int Game::RunFarsight(ARegion *r,Unit *u) ARegion *tar; int val; - CastRegionOrder *order = (CastRegionOrder *)u->castorders; - + std::shared_ptr order = std::dynamic_pointer_cast(u->castorders); tar = regions.GetRegion(order->xloc, order->yloc, order->zloc); val = GetRegionInRange(r, tar, u, S_FARSIGHT); if (!val) return 0; @@ -1666,8 +1632,7 @@ int Game::RunTeleport(ARegion *r,Object *o,Unit *u) ARegion *tar; int val; - CastRegionOrder *order = (CastRegionOrder *)u->teleportorders; - + std::shared_ptr order = u->teleportorders; tar = regions.GetRegion(order->xloc, order->yloc, order->zloc); val = GetRegionInRange(r, tar, u, S_TELEPORTATION); if (!val) return 0; @@ -1717,8 +1682,7 @@ int Game::RunGateJump(ARegion *r,Object *o,Unit *u) return 0; } - TeleportOrder *order = u->teleportorders; - + std::shared_ptr order = u->teleportorders; if ((order->gate > 0 && level < 2) || (order->gate == -2 && level < 2)) { u->error("CAST: Unit Doesn't know Gate Lore at that level."); @@ -1875,8 +1839,7 @@ int Game::RunGateJump(ARegion *r,Object *o,Unit *u) int Game::RunPortalLore(ARegion *r,Object *o,Unit *u) { int level = u->GetSkill(S_PORTAL_LORE); - TeleportOrder *order = u->teleportorders; - + std::shared_ptr order = u->teleportorders; if (!level) { u->error("CAST: Doesn't know Portal Lore."); return 0; @@ -1967,10 +1930,9 @@ int Game::RunPortalLore(ARegion *r,Object *o,Unit *u) int Game::RunTransmutation(ARegion *r, Unit *u) { - CastTransmuteOrder *order; int level, num, source; - order = (CastTransmuteOrder *) u->castorders; + std::shared_ptr order = std::dynamic_pointer_cast(u->castorders); level = u->GetSkill(S_TRANSMUTATION); if (!level) { u->error("CAST: Unit doesn't have that skill."); @@ -2133,8 +2095,7 @@ void Game::RunTeleportOrders() } if (val) u->Practice(u->teleportorders->spell); - delete u->teleportorders; - u->teleportorders = 0; + u->teleportorders = nullptr; break; } } diff --git a/standard/world.cpp b/standard/world.cpp index 52219f92..c7f7e59d 100644 --- a/standard/world.cpp +++ b/standard/world.cpp @@ -2142,7 +2142,7 @@ void Game::CreateWorld() SetupNames(); regions.CreateNexusLevel( 0, nx, ny, "nexus" ); - + regions.CreateSurfaceLevel(1, xx, yy, 0); // Create underworld levels @@ -2497,9 +2497,9 @@ void ARegion::MakeStartingCity() if (!Globals->TOWNS_EXIST) return; if (Globals->GATES_EXIST) gate = -1; - + if (town) delete town; - + AddTown(TOWN_CITY); if (!Globals->START_CITIES_EXIST) return; @@ -2519,18 +2519,18 @@ void ARegion::MakeStartingCity() if ( ItemDefs[ i ].type & IT_NORMAL ) { if (i==I_SILVER || i==I_LIVESTOCK || i==I_FISH || i==I_GRAIN) continue; - m = new Market(Market::M_BUY, i, (ItemDefs[i].baseprice * 5 / 2), -1, 5000, 5000, -1, -1); + m = new Market(Market::MarketType::M_BUY, i, (ItemDefs[i].baseprice * 5 / 2), -1, 5000, 5000, -1, -1); markets.push_back(m); } } ratio = ItemDefs[race].baseprice / ((float)Globals->BASE_MAN_COST * 10); // hack: include wage factor of 10 in float calculation above - m = new Market(Market::M_BUY, race, (int)(Wages() * 4 * ratio), -1, 5000, 5000, -1, -1); + m = new Market(Market::MarketType::M_BUY, race, (int)(Wages() * 4 * ratio), -1, 5000, 5000, -1, -1); markets.push_back(m); if (Globals->LEADERS_EXIST) { ratio=ItemDefs[I_LEADERS].baseprice/((float)Globals->BASE_MAN_COST * 10); // hack: include wage factor of 10 in float calculation above - m = new Market(Market::M_BUY, I_LEADERS, (int)(Wages() * 4 * ratio), -1, 5000, 5000, -1, -1); + m = new Market(Market::MarketType::M_BUY, I_LEADERS, (int)(Wages() * 4 * ratio), -1, 5000, 5000, -1, -1); markets.push_back(m); } } else { @@ -2538,12 +2538,16 @@ void ARegion::MakeStartingCity() ratio = ItemDefs[race].baseprice / ((float)Globals->BASE_MAN_COST * 10); // hack: include wage factor of 10 in float calculation above /* Setup Recruiting */ - m = new Market(Market::M_BUY, race, (int)(Wages() * 4 * ratio), Population() / 5, 0, 10000, 0, 2000); + m = new Market( + Market::MarketType::M_BUY, race, (int)(Wages() * 4 * ratio), Population() / 5, 0, 10000, 0, 2000 + ); markets.push_back(m); if ( Globals->LEADERS_EXIST ) { ratio=ItemDefs[I_LEADERS].baseprice/((float)Globals->BASE_MAN_COST * 10); // hack: include wage factor of 10 in float calculation above - m = new Market(Market::M_BUY, I_LEADERS, (int)(Wages() * 4 * ratio), Population() / 25, 0, 10000, 0, 400); + m = new Market( + Market::MarketType::M_BUY, I_LEADERS, (int)(Wages() * 4 * ratio), Population() / 25, 0, 10000, 0, 400 + ); markets.push_back(m); } } diff --git a/unit.cpp b/unit.cpp index d6413999..662fd865 100644 --- a/unit.cpp +++ b/unit.cpp @@ -73,19 +73,19 @@ Unit::Unit() } readyItem = -1; object = 0; - attackorders = NULL; - evictorders = NULL; - stealorders = NULL; - monthorders = NULL; - castorders = NULL; + attackorders = nullptr; + evictorders = nullptr; + stealthorders = nullptr; + monthorders = nullptr; + castorders = nullptr; sacrificeorders = nullptr; annihilateorders = nullptr; - teleportorders = NULL; - joinorders = NULL; + teleportorders = nullptr; + joinorders = nullptr; inTurnBlock = 0; presentTaxing = 0; - presentMonthOrders = NULL; - former = NULL; + presentMonthOrders = nullptr; + former = nullptr; format = 0; free = 0; practiced = 0; @@ -119,19 +119,19 @@ Unit::Unit(int seq, Faction *f, int a) } readyItem = -1; object = 0; - attackorders = NULL; - evictorders = NULL; - stealorders = NULL; - monthorders = NULL; - castorders = NULL; - teleportorders = NULL; - joinorders = NULL; + attackorders = nullptr; + evictorders = nullptr; + stealthorders = nullptr; + monthorders = nullptr; + castorders = nullptr; + teleportorders = nullptr; + joinorders = nullptr; sacrificeorders = nullptr; annihilateorders = nullptr; inTurnBlock = 0; presentTaxing = 0; - presentMonthOrders = NULL; - former = NULL; + presentMonthOrders = nullptr; + former = nullptr; format = 0; free = 0; practiced = 0; @@ -146,10 +146,6 @@ Unit::Unit(int seq, Faction *f, int a) Unit::~Unit() { - if (monthorders) delete monthorders; - if (presentMonthOrders) delete presentMonthOrders; - if (attackorders) delete attackorders; - if (stealorders) delete stealorders; if (name) delete name; if (describe) delete describe; } @@ -377,7 +373,7 @@ int Unit::CanGetSpoil(Item *i) return 0; load = items.Weight(); - + if (flags & FLAG_FLYSPOILS) { capacity = ItemDefs[i->type].fly; if (FlyingCapacity() + capacity < load + weight) @@ -481,10 +477,8 @@ json Unit::write_json_orders() // and then re-added to the end of the list if it was a repeating turn order. wrapping here uses the same stack as // above in the same way. bool wrap_turn_block = has_continuing_month_order; - if (turnorders.First()) { - TurnOrder *tOrder; - forlist(&turnorders) { - tOrder = (TurnOrder *)elem; + if (turnorders.size()) { + for(auto tOrder: turnorders) { if (wrap_turn_block) { container.push_back( { { "order", (tOrder->repeating ? "@TURN" : "TURN") } } ); parent_stack.push(container); @@ -521,7 +515,7 @@ json Unit::write_json_orders() wrap_turn_block = true; // All future turn blocks get wrapped. } // Now, move the container back to the end of the list if it was a repeating turn order and it got unwrapped - tOrder = (TurnOrder *) turnorders.First(); + std::shared_ptr tOrder = turnorders.front(); if (tOrder->repeating && !has_continuing_month_order) { container.push_back( { { "order", "@TURN" } } ); parent_stack.push(container); @@ -657,7 +651,7 @@ void Unit::build_json_report(json& j, int obs, int truesight, int detfac, int au } } } - + if ((type == U_MAGE || type == U_GUARDMAGE) && combat != -1) { j["combat_spell"] = { { "name", SkillDefs[combat].name }, { "tag", SkillDefs[combat].abbr } }; } @@ -692,7 +686,7 @@ void Unit::build_json_report(json& j, int obs, int truesight, int detfac, int au // For the JSON report, the best location for order information is on the unit itself. j["orders"] = write_json_orders(); - + } j["items"] = json::array(); @@ -782,35 +776,25 @@ void Unit::ClearOrders() enter = 0; build = 0; destroy = 0; - if (attackorders) delete attackorders; - attackorders = 0; - if (evictorders) delete evictorders; - evictorders = 0; - if (stealorders) delete stealorders; - stealorders = 0; - promote = 0; + attackorders = nullptr; + evictorders = nullptr; + stealthorders = nullptr; + promote = nullptr; taxing = TAX_NONE; - advancefrom = 0; - if (monthorders) delete monthorders; - monthorders = 0; + advancefrom = nullptr; + monthorders = nullptr; inTurnBlock = 0; presentTaxing = 0; - if (presentMonthOrders) delete presentMonthOrders; - presentMonthOrders = 0; - if (castorders) delete castorders; - castorders = 0; - if (teleportorders) delete teleportorders; - teleportorders = 0; - if (sacrificeorders) delete sacrificeorders; - sacrificeorders = 0; + presentMonthOrders = nullptr; + castorders = nullptr; + teleportorders = nullptr; + sacrificeorders = nullptr; } void Unit::ClearCastOrders() { - if (castorders) delete castorders; - castorders = 0; - if (teleportorders) delete teleportorders; - teleportorders = 0; + castorders = nullptr; + teleportorders = nullptr; } void Unit::DefaultOrders(Object *obj) @@ -921,16 +905,15 @@ void Unit::DefaultOrders(Object *obj) int dir = directions[dirIndex]; if (dir >= 0) { - MoveOrder *o = new MoveOrder; + std::shared_ptr o = std::make_shared(); o->advancing = 0; if (getrandom(100) < aggression) { o->advancing = 1; } - MoveDir *d = new MoveDir; - d->dir = dir; - o->dirs.Add(d); + MoveDir d(dir); + o->dirs.push_back(d); monthorders = o; } } @@ -952,7 +935,7 @@ void Unit::DefaultOrders(Object *obj) Globals->TAX_PILLAGE_MONTH_LONG && Taxers(1)) { taxing = TAX_AUTO; } else { - ProduceOrder *order = new ProduceOrder; + std::shared_ptr order = std::make_shared(); order->skill = -1; order->item = I_SILVER; order->target = 0; @@ -1104,7 +1087,7 @@ int Unit::GetSharedNum(int item) forlist((&object->region->objects)) { Object *obj = (Object *) elem; for(auto u: obj->units) { - if ((u->num == num) || + if ((u->num == num) || (u->faction == faction && u->GetFlag(FLAG_SHARING))) count += u->items.GetNum(item); } @@ -1332,7 +1315,7 @@ int Unit::GetAvailSkill(int sk) grant = ItemDefs[i->type].minGrant; if (grant > ItemDefs[i->type].maxGrant) grant = ItemDefs[i->type].maxGrant; - + if (grant > retval) retval = grant; } @@ -1401,7 +1384,7 @@ int Unit::CanStudy(int sk) if (!Globals->MAGE_NONLEADERS || !(SkillDefs[sk].flags & SkillType::MAGIC)) return 0; } - + int curlev = GetRealSkill(sk); if (SkillDefs[sk].flags & SkillType::DISABLED) return 0; @@ -1953,7 +1936,7 @@ static int ContributesToMovement(int movetype, int item) return ItemDefs[item].swim; break; } - + return 0; } @@ -2121,7 +2104,7 @@ int Unit::Taxers(int numtaxers) int basetax = 0; int weapontax = 0; int armortax = 0; - + // check out items int numMelee= 0; int numUsableMelee = 0; @@ -2211,7 +2194,7 @@ int Unit::Taxers(int numtaxers) else creatures += pItem->num; } - + if (ItemDefs[pItem->type].type & IT_ARMOR) { numArmor += pItem->num; } @@ -2230,7 +2213,7 @@ int Unit::Taxers(int numtaxers) GetSkill(S_STEALTH))) { basetax = totalMen; taxers = totalMen; - + // Weapon tax bonus if ((Globals->WHO_CAN_TAX & GameDefs::TAX_ANYONE) || ((Globals->WHO_CAN_TAX & GameDefs::TAX_COMBAT_SKILL) && @@ -2244,7 +2227,7 @@ int Unit::Taxers(int numtaxers) } weapontax += numMelee; } - + if (((Globals->WHO_CAN_TAX & GameDefs::TAX_BOW_SKILL) && (GetSkill(S_CROSSBOW) || GetSkill(S_LONGBOW)))) { weapontax += numUsableBows; @@ -2253,7 +2236,7 @@ int Unit::Taxers(int numtaxers) GetSkill(S_RIDING)) { if (weapontax < numUsableMounts) weapontax = numUsableMounts; } - + } else { if (Globals->WHO_CAN_TAX & GameDefs::TAX_USABLE_WEAPON) { @@ -2314,7 +2297,7 @@ int Unit::Taxers(int numtaxers) weapontax += numUsableBattle; taxers += numUsableBattle; } - + } // Ok, all the items categories done - check for mages taxing @@ -2366,13 +2349,13 @@ int Unit::Taxers(int numtaxers) } } } - + armortax = numArmor; - + // Check for overabundance if (weapontax > totalMen) weapontax = totalMen; if (armortax > weapontax) armortax = weapontax; - + // Adjust basetax in case of weapon taxation if (basetax < weapontax) basetax = weapontax; @@ -2389,7 +2372,7 @@ int Unit::Taxers(int numtaxers) basetax += illusions; taxers += illusions; } - + if (numtaxers) return(taxers); int taxes = Globals->TAX_BASE_INCOME * basetax @@ -2592,7 +2575,7 @@ void Unit::DiscardUnfinishedShips() { items.SetNum(i,0); } } - if (discard > 0) event("discards all unfinished ships.", "discard"); + if (discard > 0) event("discards all unfinished ships.", "discard"); } void Unit::event(const string& message, const string& category, ARegion *r) @@ -2700,7 +2683,7 @@ int Unit::GetAttribute(char const *attrib) } else base = monbase; // monster units have no men - } + } return base; } diff --git a/unit.h b/unit.h index 6ac89dae..fe645e30 100644 --- a/unit.h +++ b/unit.h @@ -269,30 +269,29 @@ class Unit int enter; int build; UnitId *promote; - AList findorders; - AList giveorders; - AList withdraworders; - AList bankorders; - AList buyorders; - AList sellorders; - AList forgetorders; - CastOrder *castorders; - TeleportOrder *teleportorders; - Order *stealorders; - Order *monthorders; - AttackOrder *attackorders; - EvictOrder *evictorders; - SacrificeOrder *sacrificeorders; - AnnihilateOrder *annihilateorders; + std::vector> findorders; + std::vector> giveorders; + std::vector> withdraworders; + std::vector> buyorders; + std::vector> sellorders; + std::vector> forgetorders; + std::shared_ptr castorders; + std::shared_ptr teleportorders; + std::shared_ptrstealthorders; + std::shared_ptr monthorders; + std::shared_ptr attackorders; + std::shared_ptr evictorders; + std::shared_ptr sacrificeorders; + std::shared_ptr annihilateorders; ARegion *advancefrom; - AList exchangeorders; - AList turnorders; + std::vector> exchangeorders; + std::list> turnorders; int inTurnBlock; - Order *presentMonthOrders; + std::shared_ptr presentMonthOrders; int presentTaxing; - AList transportorders; - Order *joinorders; + std::vector> transportorders; + std::shared_ptr joinorders; Unit *former; int format; diff --git a/unittest/quartermaster_test.cpp b/unittest/quartermaster_test.cpp index 859ec5f1..365d148c 100644 --- a/unittest/quartermaster_test.cpp +++ b/unittest/quartermaster_test.cpp @@ -48,13 +48,13 @@ ut::suite<"Quartermaster"> quartermaster_suite = [] helper.parse_orders(faction->num, ss); helper.check_transport_orders(); - helper.transport_phase(TransportOrder::SHIP_TO_QM); + helper.transport_phase(TransportOrder::TransportPhase::SHIP_TO_QM); expect(unit1->items.GetNum(I_STONE) == 50_i); expect(qm1->items.GetNum(I_STONE) == 50_i); expect(qm2->items.GetNum(I_STONE) == 0_i); expect(unit2->items.GetNum(I_STONE) == 0_i); - helper.transport_phase(TransportOrder::INTER_QM_TRANSPORT); + helper.transport_phase(TransportOrder::TransportPhase::INTER_QM_TRANSPORT); expect(unit1->items.GetNum(I_STONE) == 50_i); expect(qm1->items.GetNum(I_STONE) == 0_i); expect(qm2->transport_items.GetNum(I_STONE) == 50_i); @@ -68,7 +68,7 @@ ut::suite<"Quartermaster"> quartermaster_suite = [] expect(qm2->items.GetNum(I_STONE) == 50_i); expect(unit2->items.GetNum(I_STONE) == 0_i); - helper.transport_phase(TransportOrder::DISTRIBUTE_FROM_QM); + helper.transport_phase(TransportOrder::TransportPhase::DISTRIBUTE_FROM_QM); expect(unit1->items.GetNum(I_STONE) == 50_i); expect(qm1->items.GetNum(I_STONE) == 0_i); expect(qm2->items.GetNum(I_STONE) == 0_i); @@ -116,14 +116,14 @@ ut::suite<"Quartermaster"> quartermaster_suite = [] helper.parse_orders(faction->num, ss); helper.check_transport_orders(); - helper.transport_phase(TransportOrder::SHIP_TO_QM); + helper.transport_phase(TransportOrder::TransportPhase::SHIP_TO_QM); expect(unit1->items.GetNum(I_STONE) == 50_i); expect(qm1->items.GetNum(I_STONE) == 50_i); expect(qm2->items.GetNum(I_STONE) == 0_i); expect(qm3->items.GetNum(I_STONE) == 0_i); expect(unit2->items.GetNum(I_STONE) == 0_i); - helper.transport_phase(TransportOrder::INTER_QM_TRANSPORT); + helper.transport_phase(TransportOrder::TransportPhase::INTER_QM_TRANSPORT); expect(unit1->items.GetNum(I_STONE) == 50_i); expect(qm1->items.GetNum(I_STONE) == 0_i); expect(qm2->transport_items.GetNum(I_STONE) == 50_i); @@ -142,7 +142,7 @@ ut::suite<"Quartermaster"> quartermaster_suite = [] expect(qm3->items.GetNum(I_STONE) == 0_i); expect(unit2->items.GetNum(I_STONE) == 0_i); - helper.transport_phase(TransportOrder::DISTRIBUTE_FROM_QM); + helper.transport_phase(TransportOrder::TransportPhase::DISTRIBUTE_FROM_QM); expect(unit1->items.GetNum(I_STONE) == 50_i); expect(qm1->items.GetNum(I_STONE) == 0_i); expect(qm2->items.GetNum(I_STONE) == 50_i); diff --git a/unittest/world.cpp b/unittest/world.cpp index 3d9338d2..0d8a846f 100644 --- a/unittest/world.cpp +++ b/unittest/world.cpp @@ -35,14 +35,14 @@ char const *AGetNameString( int name ) { return (name == 0) ? "Testing Wilds" : void Game::CreateWorld() { Awrite("Creating world"); - regions.CreateLevels(1); + regions.CreateLevels(1); // because of the way regions are numbered, if you want 4 hexes you need a height of 4 and a width of 2. regions.CreateSurfaceLevel(0, 2, 4, nullptr); // Make an underworld level regions.CreateUnderworldLevel(1, 1, 2, "underworld"); // Make a shaft regions.MakeShaftLinks(0, 1, 100); - + ARegion *reg = regions.GetRegion(0,0,0); reg->MakeStartingCity(); } @@ -65,7 +65,7 @@ int ARegion::CanBeStartingCity( ARegionArray *pRA ) { return 1; } void ARegion::MakeStartingCity() { if (!Globals->TOWNS_EXIST) return; if (town) delete town; - + AddTown(TOWN_CITY); if (!Globals->START_CITIES_EXIST) return; @@ -85,18 +85,18 @@ void ARegion::MakeStartingCity() { if ( ItemDefs[ i ].type & IT_NORMAL ) { if (i==I_SILVER || i==I_LIVESTOCK || i==I_FISH || i==I_GRAIN) continue; - m = new Market(Market::M_BUY, i, (ItemDefs[i].baseprice * 5 / 2), -1, 5000, 5000, -1, -1); + m = new Market(Market::MarketType::M_BUY, i, (ItemDefs[i].baseprice * 5 / 2), -1, 5000, 5000, -1, -1); markets.push_back(m); } } ratio = ItemDefs[race].baseprice / ((float)Globals->BASE_MAN_COST * 10); // hack: include wage factor of 10 in float calculation above - m = new Market(Market::M_BUY, race, (int)(Wages() * 4 * ratio), -1, 5000, 5000, -1, -1); + m = new Market(Market::MarketType::M_BUY, race, (int)(Wages() * 4 * ratio), -1, 5000, 5000, -1, -1); markets.push_back(m); if (Globals->LEADERS_EXIST) { ratio=ItemDefs[I_LEADERS].baseprice/((float)Globals->BASE_MAN_COST * 10); // hack: include wage factor of 10 in float calculation above - m = new Market(Market::M_BUY, I_LEADERS, (int)(Wages() * 4 * ratio), -1, 5000, 5000, -1, -1); + m = new Market(Market::MarketType::M_BUY, I_LEADERS, (int)(Wages() * 4 * ratio), -1, 5000, 5000, -1, -1); markets.push_back(m); } } else { @@ -104,12 +104,16 @@ void ARegion::MakeStartingCity() { ratio = ItemDefs[race].baseprice / ((float)Globals->BASE_MAN_COST * 10); // hack: include wage factor of 10 in float calculation above /* Setup Recruiting */ - m = new Market(Market::M_BUY, race, (int)(Wages() * 4 * ratio), Population() / 5, 0, 10000, 0, 2000); + m = new Market( + Market::MarketType::M_BUY, race, (int)(Wages() * 4 * ratio), Population() / 5, 0, 10000, 0, 2000 + ); markets.push_back(m); if ( Globals->LEADERS_EXIST ) { ratio=ItemDefs[I_LEADERS].baseprice/((float)Globals->BASE_MAN_COST * 10); // hack: include wage factor of 10 in float calculation above - m = new Market(Market::M_BUY, I_LEADERS, (int)(Wages() * 4 * ratio), Population() / 25, 0, 10000, 0, 400); + m = new Market( + Market::MarketType::M_BUY, I_LEADERS, (int)(Wages() * 4 * ratio), Population() / 25, 0, 10000, 0, 400 + ); markets.push_back(m); } }