Skip to content

Commit

Permalink
Fixed defect 222.
Browse files Browse the repository at this point in the history
The workaround approach is used till the save file format is updated.
See defect 185.
  • Loading branch information
klei1984 committed Sep 22, 2024
1 parent 168c236 commit 5cd41e9
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 7 deletions.
33 changes: 33 additions & 0 deletions src/aiplayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2118,6 +2118,15 @@ void AiPlayer::UpgradeUnitType() {
auto upgrade_level =
TeamUnits_UpgradeOffsetFactor(player_team, build_order.unit_type, build_order.primary_attribute);

if (build_order.primary_attribute == RESEARCH_TOPIC_HITS ||
build_order.primary_attribute == RESEARCH_TOPIC_SPEED) {
auto current_level = unit_values->GetAttribute(build_order.primary_attribute);

if (current_level + upgrade_level > UINT8_MAX) {
upgrade_level = UINT8_MAX - current_level;
}
}

unit_values = new (std::nothrow) UnitValues(*unit_values);

unit_values->UpdateVersion();
Expand Down Expand Up @@ -4644,6 +4653,18 @@ void AiPlayer::ChooseUpgrade(SmartObjectArray<BuildOrder> build_orders1, SmartOb
build_order.unit_type = INVALID_ID;

for (int32_t i = 0; i < build_orders1.GetCount(); ++i) {
if (build_orders1[i]->primary_attribute == RESEARCH_TOPIC_HITS ||
build_orders1[i]->primary_attribute == RESEARCH_TOPIC_SPEED) {
SmartPointer<UnitValues> unit_values =
UnitsManager_TeamInfo[player_team].team_units->GetCurrentUnitValues(build_orders1[i]->unit_type);

auto current_level = unit_values->GetAttribute(build_orders1[i]->primary_attribute);

if (current_level == UINT8_MAX) {
continue;
}
}

int32_t new_upgrade_cost =
TeamUnits_GetUpgradeCost(player_team, build_orders1[i]->unit_type, build_orders1[i]->primary_attribute);

Expand All @@ -4656,6 +4677,18 @@ void AiPlayer::ChooseUpgrade(SmartObjectArray<BuildOrder> build_orders1, SmartOb
int32_t factor = 2;

for (int32_t i = 0; i < build_orders2.GetCount(); ++i) {
if (build_orders2[i]->primary_attribute == RESEARCH_TOPIC_HITS ||
build_orders2[i]->primary_attribute == RESEARCH_TOPIC_SPEED) {
SmartPointer<UnitValues> unit_values =
UnitsManager_TeamInfo[player_team].team_units->GetCurrentUnitValues(build_orders2[i]->unit_type);

auto current_level = unit_values->GetAttribute(build_orders2[i]->primary_attribute);

if (current_level == UINT8_MAX) {
continue;
}
}

int32_t new_upgrade_cost =
TeamUnits_GetUpgradeCost(player_team, build_orders2[i]->unit_type, build_orders2[i]->primary_attribute);

Expand Down
7 changes: 4 additions & 3 deletions src/game_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3095,7 +3095,8 @@ void GameManager_ProcessCheatCodes() {

if (new_unit_values->GetAttribute(ATTRIB_HITS) <
2 * selected_unit_values->GetAttribute(ATTRIB_HITS)) {
new_unit_values->SetAttribute(ATTRIB_HITS, 2 * selected_unit_values->GetAttribute(ATTRIB_HITS));
new_unit_values->SetAttribute(
ATTRIB_HITS, std::min(2 * selected_unit_values->GetAttribute(ATTRIB_HITS), UINT8_MAX));
}

if (new_unit_values->GetAttribute(ATTRIB_SCAN) <
Expand All @@ -3111,8 +3112,8 @@ void GameManager_ProcessCheatCodes() {

if (new_unit_values->GetAttribute(ATTRIB_SPEED) <
2 * selected_unit_values->GetAttribute(ATTRIB_SPEED)) {
new_unit_values->SetAttribute(ATTRIB_SPEED,
2 * selected_unit_values->GetAttribute(ATTRIB_SPEED));
new_unit_values->SetAttribute(
ATTRIB_SPEED, std::min(2 * selected_unit_values->GetAttribute(ATTRIB_SPEED), UINT8_MAX));
}

if (new_unit_values->GetAttribute(ATTRIB_ROUNDS) <
Expand Down
5 changes: 5 additions & 0 deletions src/researchmenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,11 @@ void ResearchMenu_ApplyUpgrades(uint16_t team, uint8_t research_topic) {
new_value = (research_level * value1) / 10;
}

if (research_topic == RESEARCH_TOPIC_HITS || research_topic == RESEARCH_TOPIC_SPEED) {
old_value = std::min(old_value, UINT8_MAX);
new_value = std::min(new_value, UINT8_MAX);
}

if (new_value != old_value) {
*value2 += new_value - old_value;

Expand Down
4 changes: 2 additions & 2 deletions src/teamunits.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,11 +158,11 @@ void TeamUnits::Init() {

position = 0;
unitvalues->SetAttribute(ATTRIB_TURNS, GetParam(buffer, &position));
unitvalues->SetAttribute(ATTRIB_HITS, GetParam(buffer, &position));
unitvalues->SetAttribute(ATTRIB_HITS, std::min(GetParam(buffer, &position), UINT8_MAX));
unitvalues->SetAttribute(ATTRIB_ARMOR, GetParam(buffer, &position));
unitvalues->SetAttribute(ATTRIB_ATTACK, GetParam(buffer, &position));
unitvalues->SetAttribute(ATTRIB_MOVE_AND_FIRE, GetParam(buffer, &position));
unitvalues->SetAttribute(ATTRIB_SPEED, GetParam(buffer, &position));
unitvalues->SetAttribute(ATTRIB_SPEED, std::min(GetParam(buffer, &position), UINT8_MAX));
unitvalues->SetAttribute(ATTRIB_FUEL, GetParam(buffer, &position));
unitvalues->SetAttribute(ATTRIB_RANGE, GetParam(buffer, &position));
unitvalues->SetAttribute(ATTRIB_ROUNDS, GetParam(buffer, &position));
Expand Down
25 changes: 23 additions & 2 deletions src/unitinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2088,6 +2088,7 @@ void UnitInfo::GainExperience(int32_t experience) {
if (storage >= 15) {
int32_t upgrade_topic;
int32_t upgrade_cost;
int32_t upgrade_level;
bool is_upgraded;

SmartPointer<UnitValues> unit_values =
Expand All @@ -2101,17 +2102,37 @@ void UnitInfo::GainExperience(int32_t experience) {
upgrade_cost = TeamUnits_GetUpgradeCost(team, unit_type, upgrade_topic);

while (upgrade_cost <= storage) {
upgrade_level = TeamUnits_UpgradeOffsetFactor(team, unit_type, upgrade_topic);

if (upgrade_topic == RESEARCH_TOPIC_HITS || upgrade_topic == RESEARCH_TOPIC_SPEED) {
auto current_level = base_values->GetAttribute(upgrade_topic);

if (current_level == UINT8_MAX) {
upgrade_topic = ExpResearchTopics[(dos_rand() * sizeof(ExpResearchTopics)) >> 15];
upgrade_cost = TeamUnits_GetUpgradeCost(team, unit_type, upgrade_topic);

continue;
}

if (current_level + upgrade_level > UINT8_MAX) {
upgrade_cost = static_cast<float>(upgrade_cost) * static_cast<float>(upgrade_level) /
(UINT8_MAX - current_level) +
0.5f;
upgrade_level = UINT8_MAX - current_level;
}
}

storage -= upgrade_cost;

if (!is_upgraded) {
base_values = new UnitValues(*base_values);
is_upgraded = true;
}

base_values->AddAttribute(upgrade_topic, TeamUnits_UpgradeOffsetFactor(team, unit_type, upgrade_topic));
base_values->AddAttribute(upgrade_topic, upgrade_level);

upgrade_topic = ExpResearchTopics[(dos_rand() * sizeof(ExpResearchTopics)) >> 15];
upgrade_cost = TeamUnits_GetUpgradeCost(team, unit_type, upgrade_topic);
is_upgraded = true;
}

if (is_upgraded) {
Expand Down
6 changes: 6 additions & 0 deletions src/unitvalues.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,15 @@ void UnitValues::FileLoad(SmartFileReader& file) noexcept {
file.Read(agent_adjust);
file.Read(version);
file.Read(units_built);

hits = std::min<uint16_t>(hits, UINT8_MAX);
speed = std::min<uint16_t>(speed, UINT8_MAX);
}

void UnitValues::FileSave(SmartFileWriter& file) noexcept {
hits = std::min<uint16_t>(hits, UINT8_MAX);
speed = std::min<uint16_t>(speed, UINT8_MAX);

file.Write(turns);
file.Write(hits);
file.Write(armor);
Expand Down
14 changes: 14 additions & 0 deletions src/upgradecontrol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ void UpgradeControl::Init(int32_t id, int32_t team_base_value, int32_t control_b

if (this->id == UPGRADE_CONTROL_9) {
upgrade_amount = 1;

} else if (team_base_value >= 10) {
if (team_base_value >= 25) {
if (team_base_value >= 50) {
Expand All @@ -119,6 +120,12 @@ void UpgradeControl::Init(int32_t id, int32_t team_base_value, int32_t control_b
} else {
upgrade_amount = 1;
}

if (id == UPGRADE_CONTROL_6 || id == UPGRADE_CONTROL_8) {
if (*control_actual_value + upgrade_amount > UINT8_MAX) {
upgrade_amount = UINT8_MAX - *control_actual_value;
}
}
}

void UpgradeControl::Increase() {
Expand Down Expand Up @@ -177,6 +184,13 @@ void UpgradeControl::UpdateControlState() {

if (cost <= *team_gold && cost < UPGRADECONTROL_UPGRADE_COST_LIMIT) {
upgrade_right->Enable();

if (id == UPGRADE_CONTROL_6 || id == UPGRADE_CONTROL_8) {
if (*control_actual_value >= UINT8_MAX) {
upgrade_right->Disable();
}
}

} else {
upgrade_right->Disable();
}
Expand Down

0 comments on commit 5cd41e9

Please sign in to comment.