From dc044a9c704bbc2ec898f18a76f6e901baf31113 Mon Sep 17 00:00:00 2001 From: joris <joris.dauphin@gmail.com> Date: Fri, 17 Feb 2012 15:57:11 +0100 Subject: [PATCH] Add DefineDefaultResourceMaxAmounts() to define max value per resource.(default value is 0, so change it in lua). Add "Storing" to UnitType to increase MaxResourceAmount Patch from cybermind. --- src/action/action_resource.cpp | 25 ++++++++------- src/action/command.cpp | 2 +- src/include/player.h | 5 +++ src/include/unittype.h | 1 + src/include/upgrade_structs.h | 5 +++ src/stratagus/player.cpp | 34 +++++++++++++++++--- src/stratagus/script.cpp | 18 +++++++++++ src/stratagus/script_player.cpp | 44 ++++++++++++++++++++++++-- src/ui/mainscr.cpp | 55 ++++++++++++++++++--------------- src/unit/script_unittype.cpp | 15 ++++++++- src/unit/unit.cpp | 46 ++++++++++++++++++++------- src/unit/unittype.cpp | 6 ++++ 12 files changed, 198 insertions(+), 58 deletions(-) diff --git a/src/action/action_resource.cpp b/src/action/action_resource.cpp index c01515c0d..42dcc26fd 100644 --- a/src/action/action_resource.cpp +++ b/src/action/action_resource.cpp @@ -628,7 +628,7 @@ static int MoveToDepot(CUnit &unit) { const ResourceInfo &resinfo = *unit.Type->ResInfo[unit.CurrentResource]; CUnit *goal = unit.CurrentOrder()->GetGoal(); - + CPlayer& player = *unit.Player; Assert(goal); switch (DoActionMove(unit)) { // reached end-point? @@ -637,7 +637,7 @@ static int MoveToDepot(CUnit &unit) case PF_REACHED: break; default: - if (unit.Anim.Unbreakable || goal->IsVisibleAsGoal(*unit.Player)) { + if (unit.Anim.Unbreakable || goal->IsVisibleAsGoal(player)) { return 0; } break; @@ -646,8 +646,8 @@ static int MoveToDepot(CUnit &unit) // // Target is dead, stop getting resources. // - if (!goal->IsVisibleAsGoal(*unit.Player)) { - DebugPrint("%d: Worker %d report: Destroyed depot\n" _C_ unit.Player->Index _C_ unit.Slot); + if (!goal->IsVisibleAsGoal(player)) { + DebugPrint("%d: Worker %d report: Destroyed depot\n" _C_ player.Index _C_ unit.Slot); unit.CurrentOrder()->ClearGoal(); @@ -655,10 +655,10 @@ static int MoveToDepot(CUnit &unit) if (depot) { UnitGotoGoal(unit, depot, SUB_MOVE_TO_DEPOT); - DebugPrint("%d: Worker %d report: Going to new deposit.\n" _C_ unit.Player->Index _C_ unit.Slot); + DebugPrint("%d: Worker %d report: Going to new deposit.\n" _C_ player.Index _C_ unit.Slot); } else { DebugPrint("%d: Worker %d report: Can't find a new resource deposit.\n" - _C_ unit.Player->Index _C_ unit.Slot); + _C_ player.Index _C_ unit.Slot); // FIXME: perhaps we should choose an alternative unit.ClearAction(); @@ -667,8 +667,7 @@ static int MoveToDepot(CUnit &unit) } // Not ready - if (unit.Player->AiEnabled && unit.CurrentOrder()->Data.Move.Cycles > 300) - { + if (player.AiEnabled && unit.CurrentOrder()->Data.Move.Cycles > 300) { AiNewDepotRequest(unit); } @@ -688,9 +687,13 @@ static int MoveToDepot(CUnit &unit) } // Update resource. - unit.Player->Resources[resinfo.FinalResource] += (unit.ResourcesHeld * unit.Player->Incomes[resinfo.FinalResource]) / 100; - unit.Player->TotalResources[resinfo.FinalResource] += (unit.ResourcesHeld * unit.Player->Incomes[resinfo.FinalResource]) / 100; - unit.ResourcesHeld = 0; + const int rindex = resinfo.FinalResource; + player.Resources[rindex] += (unit.ResourcesHeld * player.Incomes[rindex]) / 100; + if (player.MaxResources[rindex] != -1) { + player.Resources[rindex] = std::min(player.Resources[rindex], player.MaxResources[rindex]); + } + player.TotalResources[rindex] += (unit.ResourcesHeld * player.Incomes[rindex]) / 100; + unit.ResourcesHeld = 0; if (unit.Wait) { unit.Wait /= SpeedResourcesReturn[resinfo.ResourceId]; diff --git a/src/action/command.cpp b/src/action/command.cpp index 69c92ffae..6dc96d483 100644 --- a/src/action/command.cpp +++ b/src/action/command.cpp @@ -852,7 +852,7 @@ void CommandDiplomacy(int player, int state, int opponent) */ void CommandSetResource(int player, int resource, int value) { - Players[player].Resources[resource] = value; + Players[player].SetResource(resource, value); } /** diff --git a/src/include/player.h b/src/include/player.h index 7f3d8111c..4024deda8 100644 --- a/src/include/player.h +++ b/src/include/player.h @@ -133,6 +133,10 @@ ** units and structures. ** @see _costs_, TimeCost, GoldCost, WoodCost, OilCost, MaxCosts. ** +** CPlayer::MaxResources[::MaxCosts] +** +** How many resources the player can store at the moment. +** ** CPlayer::Incomes[::MaxCosts] ** ** Income of the resources, when they are delivered at a store. @@ -324,6 +328,7 @@ public: inline void SetStartView(int x, int y) { StartX = x; StartY = y; } int Resources[MaxCosts]; /// resources in store + int MaxResources[MaxCosts]; /// max resources can be stored int LastResources[MaxCosts]; /// last values for revenue int Incomes[MaxCosts]; /// income of the resources int Revenue[MaxCosts]; /// income rate of the resources diff --git a/src/include/unittype.h b/src/include/unittype.h index c127e80b8..86b3bcdf5 100644 --- a/src/include/unittype.h +++ b/src/include/unittype.h @@ -940,6 +940,7 @@ public: CConstruction *Construction; /// What is shown in construction phase int _Costs[MaxCosts]; /// How many resources needed + int _Storing[MaxCosts]; /// How many resources the unit can store int RepairHP; /// Amount of HP per repair int RepairCosts[MaxCosts]; /// How much it costs to repair diff --git a/src/include/upgrade_structs.h b/src/include/upgrade_structs.h index 87ee4c0dc..013541ffe 100644 --- a/src/include/upgrade_structs.h +++ b/src/include/upgrade_structs.h @@ -122,6 +122,11 @@ extern std::string DefaultResourceNames[MaxCosts]; */ extern int DefaultResourceAmounts[MaxCosts]; +/** +** Default max amounts for the resources. +*/ +extern int DefaultResourceMaxAmounts[MaxCosts]; + /** ** These are the current stats of a unit. Upgraded or downgraded. */ diff --git a/src/stratagus/player.cpp b/src/stratagus/player.cpp index d0bb3e1ec..a8665150c 100644 --- a/src/stratagus/player.cpp +++ b/src/stratagus/player.cpp @@ -198,6 +198,18 @@ void SavePlayers(CFile *file) } file->printf("\"%s\", %d,", DefaultResourceNames[j].c_str(), p.Resources[j]); } + // Max Resources + file->printf(" \"max-resources\", {"); + for (int j = 0; j < MaxCosts; ++j) { + if (j) { + if (j == MaxCosts / 2) { + file->printf("\n "); + } else { + file->printf(" "); + } + } + file->printf("\"%s\", %d,", DefaultResourceNames[j].c_str(), p.MaxResources[j]); + } // Last Resources file->printf("},\n \"last-resources\", {"); for (int j = 0; j < MaxCosts; ++j) { @@ -450,6 +462,13 @@ void CreatePlayer(int type) player.Incomes[i] = DefaultIncomes[i]; } + // + // Initial max resource amounts. + // + for (int i = 0; i < MaxCosts; ++i) { + player.MaxResources[i] = DefaultResourceMaxAmounts[i]; + } + memset(player.UnitTypesCount, 0, sizeof (player.UnitTypesCount)); player.Supply = 0; @@ -512,6 +531,7 @@ void CPlayer::Clear() StartX = 0; StartY = 0; memset(Resources, 0, sizeof(Resources)); + memset(MaxResources, 0, sizeof(MaxResources)); memset(LastResources, 0, sizeof(LastResources)); memset(Incomes, 0, sizeof(Incomes)); memset(Revenue, 0, sizeof(Revenue)); @@ -550,7 +570,11 @@ void CPlayer::Clear() */ void CPlayer::SetResource(int resource, int value) { - this->Resources[resource] = value; + if (this->MaxResources[resource] != -1) { + this->Resources[resource] = std::min(value, this->MaxResources[resource]); + } else { + this->Resources[resource] = value; + } } /** @@ -650,7 +674,7 @@ int CPlayer::CheckUnitType(const CUnitType &type) const void CPlayer::AddCosts(const int *costs) { for (int i = 1; i < MaxCosts; ++i) { - this->Resources[i] += costs[i]; + SetResource(i, Resources[i] + costs[i]); } } @@ -674,7 +698,7 @@ void CPlayer::AddUnitType(const CUnitType &type) void CPlayer::AddCostsFactor(const int *costs, int factor) { for (int i = 1; i < MaxCosts; ++i) { - this->Resources[i] += costs[i] * factor / 100; + SetResource(i, this->Resources[i] + costs[i] * factor / 100); } } @@ -686,7 +710,7 @@ void CPlayer::AddCostsFactor(const int *costs, int factor) void CPlayer::SubCosts(const int *costs) { for (int i = 1; i < MaxCosts; ++i) { - this->Resources[i] -= costs[i]; + SetResource(i, this->Resources[i] - costs[i]); } } @@ -709,7 +733,7 @@ void CPlayer::SubUnitType(const CUnitType &type) void CPlayer::SubCostsFactor(const int *costs, int factor) { for (int i = 1; i < MaxCosts; ++i) { - this->Resources[i] -= costs[i] * 100 / factor; + SetResource(i, this->Resources[i] - costs[i] * 100 / factor); } } diff --git a/src/stratagus/script.cpp b/src/stratagus/script.cpp index a6915aa00..d11c07557 100644 --- a/src/stratagus/script.cpp +++ b/src/stratagus/script.cpp @@ -2302,6 +2302,23 @@ static int CclDefineDefaultResourceAmounts(lua_State *l) return 0; } +/** +** Define max amounts for the resources. +** +** @param l Lua state. +*/ +static int CclDefineDefaultResourceMaxAmounts(lua_State *l) +{ + int args = std::min<int>(lua_gettop(l), MaxCosts); + + for (int i = 0; i < args; ++i) { + DefaultResourceMaxAmounts[i] = LuaToNumber(l, i + 1); + } + for (int i = args; i < MaxCosts; ++i) + DefaultResourceMaxAmounts[i] = -1; + return 0; +} + /** ** Define default extra death types. ** @@ -2434,6 +2451,7 @@ void InitCcl() lua_register(Lua, "DefineDefaultActions", CclDefineDefaultActions); lua_register(Lua, "DefineDefaultResourceNames", CclDefineDefaultResourceNames); lua_register(Lua, "DefineDefaultResourceAmounts", CclDefineDefaultResourceAmounts); + lua_register(Lua, "DefineDefaultResourceMaxAmounts", CclDefineDefaultResourceMaxAmounts); lua_register(Lua, "DefineExtraDeathTypes", CclDefineExtraDeathTypes); lua_register(Lua, "NoRandomPlacementMultiplayer", CclNoRandomPlacementMultiplayer); diff --git a/src/stratagus/script_player.cpp b/src/stratagus/script_player.cpp index c555d6fe5..e4920fb3b 100644 --- a/src/stratagus/script_player.cpp +++ b/src/stratagus/script_player.cpp @@ -199,6 +199,29 @@ static int CclPlayer(lua_State *l) LuaError(l, "Unsupported tag: %s" _C_ value); } } + } else if (!strcmp(value, "max-resources")) { + if (!lua_istable(l, j + 1)) { + LuaError(l, "incorrect argument"); + } + subargs = lua_objlen(l, j + 1); + for (k = 0; k < subargs; ++k) { + lua_rawgeti(l, j + 1, k + 1); + value = LuaToString(l, -1); + lua_pop(l, 1); + ++k; + + for (i = 0; i < MaxCosts; ++i) { + if (!strcmp(value, DefaultResourceNames[i].c_str())) { + lua_rawgeti(l, j + 1, k + 1); + player->MaxResources[i] = LuaToNumber(l, -1); + lua_pop(l, 1); + break; + } + } + if (i == MaxCosts) { + LuaError(l, "Unsupported tag: %s" _C_ value); + } + } } else if (!strcmp(value, "last-resources")) { if (!lua_istable(l, j + 1)) { LuaError(l, "incorrect argument"); @@ -350,10 +373,13 @@ static int CclPlayer(lua_State *l) lua_pop(l, 1); } } else { - LuaError(l, "Unsupported tag: %s" _C_ value); + LuaError(l, "Unsupported tag: %s" _C_ value); } } - + // Manage max + for (int i = 0; i < MaxCosts; ++i) { + player->SetResource(i, player->Resources[i]); + } return 0; } @@ -761,6 +787,18 @@ static int CclGetPlayerData(lua_State *l) } else if (!strcmp(data, "Resources")) { LuaCheckArgs(l, 3); + const std::string res = LuaToString(l, 3); + + for (int i = 0; i < MaxCosts; ++i) { + if (res == DefaultResourceNames[i]) { + lua_pushnumber(l, p->Resources[i]); + return 1; + } + } + LuaError(l, "Invalid resource \"%s\"" _C_ res.c_str()); + } else if (!strcmp(data, "MaxResources")) { + LuaCheckArgs(l, 3); + const std::string res = LuaToString(l, 3); unsigned int i; @@ -772,7 +810,7 @@ static int CclGetPlayerData(lua_State *l) if (i == MaxCosts) { LuaError(l, "Invalid resource \"%s\"" _C_ res.c_str()); } - lua_pushnumber(l, p->Resources[i]); + lua_pushnumber(l, p->MaxResources[i]); return 1; } else if (!strcmp(data, "UnitTypesCount")) { CUnitType *type; diff --git a/src/ui/mainscr.cpp b/src/ui/mainscr.cpp index 5af165481..f56db49a1 100644 --- a/src/ui/mainscr.cpp +++ b/src/ui/mainscr.cpp @@ -535,31 +535,31 @@ void CContentTypeCompleteBar::Draw(const CUnit &unit, CFont *) const //FIXME: ugly switch (this->Color) { - case 1: + case 1: color = ColorRed; break; - case 2: + case 2: color = ColorYellow; break; - case 3: + case 3: color = ColorGreen; break; - case 4: + case 4: color = ColorGray; break; - case 5: + case 5: color = ColorWhite; break; - case 6: + case 6: color = ColorOrange; break; - case 7: + case 7: color = ColorBlue; break; - case 8: + case 8: color = ColorDarkGreen; break; - case 9: + case 9: color = ColorBlack; break; default: @@ -773,23 +773,30 @@ static void DrawUnitInfo(CUnit &unit) */ void DrawResources() { - int i; - int v; CLabel label(GetGameFont()); // Draw all icons of resource. - for (i = 0; i <= ScoreCost; ++i) { + for (int i = 0; i <= ScoreCost; ++i) { if (UI.Resources[i].G) { UI.Resources[i].G->DrawFrameClip(UI.Resources[i].IconFrame, UI.Resources[i].IconX, UI.Resources[i].IconY); } } - for (i = 0; i < MaxCosts; ++i) { + for (int i = 0; i < MaxCosts; ++i) { if (UI.Resources[i].TextX != -1) { - v = ThisPlayer->Resources[i]; - label.SetFont(v > 99999 ? GetSmallFont() : GetGameFont()); - label.Draw(UI.Resources[i].TextX, - UI.Resources[i].TextY + (v > 99999) * 3, v); + const int resourceAmount = ThisPlayer->Resources[i]; + + if (ThisPlayer->MaxResources[i] != -1) { + char tmp[128]; + snprintf(tmp, sizeof(tmp), "%d/%d", resourceAmount, ThisPlayer->MaxResources[i]); + label.SetFont(GetSmallFont()); + + label.Draw(UI.Resources[i].TextX, UI.Resources[i].TextY + 3, tmp); + } else { + label.SetFont(resourceAmount > 99999 ? GetSmallFont() : GetGameFont()); + + label.Draw(UI.Resources[i].TextX, UI.Resources[i].TextY + (resourceAmount > 99999) * 3, resourceAmount); + } } } if (UI.Resources[FoodCost].TextX != -1) { @@ -797,18 +804,16 @@ void DrawResources() snprintf(tmp,sizeof(tmp), "%d/%d", ThisPlayer->Demand, ThisPlayer->Supply); label.SetFont(GetGameFont()); if (ThisPlayer->Supply < ThisPlayer->Demand) { - label.DrawReverse(UI.Resources[FoodCost].TextX, - UI.Resources[FoodCost].TextY, tmp); + label.DrawReverse(UI.Resources[FoodCost].TextX, UI.Resources[FoodCost].TextY, tmp); } else { - label.Draw(UI.Resources[FoodCost].TextX, - UI.Resources[FoodCost].TextY, tmp); + label.Draw(UI.Resources[FoodCost].TextX, UI.Resources[FoodCost].TextY, tmp); } } if (UI.Resources[ScoreCost].TextX != -1) { - v = ThisPlayer->Score; - label.SetFont(v > 99999 ? GetSmallFont() : GetGameFont()); - label.Draw(UI.Resources[ScoreCost].TextX, - UI.Resources[ScoreCost].TextY + (v > 99999) * 3, v); + const int score = ThisPlayer->Score; + + label.SetFont(score > 99999 ? GetSmallFont() : GetGameFont()); + label.Draw(UI.Resources[ScoreCost].TextX, UI.Resources[ScoreCost].TextY + (score > 99999) * 3, score); } } diff --git a/src/unit/script_unittype.cpp b/src/unit/script_unittype.cpp index d63077cfd..68d3ee245 100644 --- a/src/unit/script_unittype.cpp +++ b/src/unit/script_unittype.cpp @@ -532,6 +532,20 @@ static int CclDefineUnitType(lua_State *l) type->_Costs[res] = LuaToNumber(l, -1); lua_pop(l, 1); } + } else if (!strcmp(value, "Storing")) { + if (!lua_istable(l, -1)) { + LuaError(l, "incorrect argument"); + } + subargs = lua_objlen(l, -1); + for (k = 0; k < subargs; ++k) { + lua_rawgeti(l, -1, k + 1); + const int res = CclGetResourceByName(l); + lua_pop(l, 1); + ++k; + lua_rawgeti(l, -1, k + 1); + type->_Storing[res] = LuaToNumber(l, -1); + lua_pop(l, 1); + } } else if (!strcmp(value, "ImproveProduction")) { if (!lua_istable(l, -1)) { LuaError(l, "incorrect argument"); @@ -656,7 +670,6 @@ static int CclDefineUnitType(lua_State *l) } else { LuaError(l, "Unsupported Type: %s" _C_ value); } - } else if (!strcmp(value, "RightMouseAction")) { value = LuaToString(l, -1); if (!strcmp(value, "none")) { diff --git a/src/unit/unit.cpp b/src/unit/unit.cpp index 90f6d5fa8..2967b9213 100644 --- a/src/unit/unit.cpp +++ b/src/unit/unit.cpp @@ -488,6 +488,13 @@ CUnit *MakeUnit(CUnitType &type, CPlayer *player) unit->AssignToPlayer(player); } + // Increase the max resources limit + for (int i = 0; i < MaxCosts; ++i) { + if (type._Storing[i] && unit->Player->MaxResources[i] != -1) { + unit->Player->MaxResources[i] += type._Storing[i]; + } + } + if (type.Building) { // // fancy buildings: mirror buildings (but shadows not correct) @@ -936,10 +943,8 @@ void UnitLost(CUnit &unit) CUnit *temp; CBuildRestrictionOnTop *b; const CUnitType *type; - CPlayer *player; - int i; + CPlayer *player = unit.Player; - player = unit.Player; Assert(player); // Next code didn't support no player! // @@ -990,13 +995,21 @@ void UnitLost(CUnit &unit) // if (unit.CurrentAction() != UnitActionBuilt) { player->Supply -= type->Supply; + // Decrease resource limit + for (int i = 0; i < MaxCosts; ++i) { + if (unit.Player->MaxResources[i] != -1 && type->_Storing[i]) { + const int newMaxValue = unit.Player->MaxResources[i] - type->_Storing[i]; + unit.Player->MaxResources[i] = std::max(0, newMaxValue); + unit.Player->SetResource(i, unit.Player->Resources[i]); + } + } // // Handle income improvements, look if a player loses a building // which have given him a better income, find the next best // income. // - for (i = 1; i < MaxCosts; ++i) { + for (int i = 1; i < MaxCosts; ++i) { if (player->Incomes[i] && type->ImproveIncomes[i] == player->Incomes[i]) { int m; int j; @@ -1069,11 +1082,16 @@ void UpdateForNewUnit(const CUnit &unit, int upgrade) CPlayer *player = unit.Player; // - // Handle unit supply. (Currently only food supported.) + // Handle unit supply and max resources. // Note an upgraded unit can't give more supply. // if (!upgrade) { player->Supply += type->Supply; + for (int i = 0; i < MaxCosts; ++i) { + if (unit.Player->MaxResources[i] != -1 && type->_Storing[i]) { + unit.Player->MaxResources[i] += type->_Storing[i]; + } + } } // @@ -1557,6 +1575,12 @@ void CUnit::ChangeOwner(CPlayer &newplayer) } newplayer.Demand += Type->Demand; newplayer.Supply += Type->Supply; + // Increase resource limit + for (int i = 0; i < MaxCosts; ++i) { + if (newplayer.MaxResources[i] != -1 && Type->_Storing[i]) { + newplayer.MaxResources[i] += Type->_Storing[i]; + } + } if (Type->Building) { newplayer.NumBuildings++; } @@ -2392,10 +2416,9 @@ CUnit *UnitFindResource(const CUnit &unit, const Vec2i &startPos, int range, int if (bestw < waiting) { better = false; } else { - if (bestw == waiting && bestd < n) - { - better = false; - } + if (bestw == waiting && bestd < n) { + better = false; + } } } } else { @@ -2415,8 +2438,7 @@ CUnit *UnitFindResource(const CUnit &unit, const Vec2i &startPos, int range, int bestw = waiting; } } else { - if (bestmine != NoUnitP && bestd < n) - { + if (bestmine != NoUnitP && bestd < n) { better = false; } } @@ -3341,7 +3363,7 @@ void CleanUnits() // // Free memory for all units in unit table. // - while(NumUnits) { + while (NumUnits) { int count = NumUnits; do { CUnit *unit = Units[count - 1]; diff --git a/src/unit/unittype.cpp b/src/unit/unittype.cpp index 726917dc4..fd73acc9a 100644 --- a/src/unit/unittype.cpp +++ b/src/unit/unittype.cpp @@ -94,6 +94,11 @@ std::string DefaultResourceNames[MaxCosts]; */ int DefaultResourceAmounts[MaxCosts]; +/** +** Default max amounts for the resources. +*/ +int DefaultResourceMaxAmounts[MaxCosts]; + /** ** Default names for the resources. */ @@ -132,6 +137,7 @@ CUnitType::CUnitType() : memset(&Portrait, 0, sizeof(Portrait)); #endif memset(_Costs, 0, sizeof(_Costs)); + memset(_Storing, 0, sizeof(_Storing)); memset(RepairCosts, 0, sizeof(RepairCosts)); memset(CanStore, 0, sizeof(CanStore)); memset(ResInfo, 0, sizeof(ResInfo));