Implement updateSnowLine (#954)

* Implement initialiseSnowLine and updateSnowLine

* Name ClimateObject variables

* Refactor out common code
This commit is contained in:
Aaron van Geffen 2021-04-30 09:15:45 +02:00 committed by GitHub
parent a026d75b13
commit 86268bd3d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 125 additions and 19 deletions

View File

@ -491,7 +491,7 @@ namespace OpenLoco::Map::MapGenerator
updateProgress(5);
Scenario::initialiseDate(options.scenarioStartYear);
call(0x00496A18);
Scenario::initialiseSnowLine();
TileManager::initialise();
updateProgress(10);

View File

@ -0,0 +1,17 @@
#pragma once
#include "../Types.hpp"
namespace OpenLoco
{
#pragma pack(push, 1)
struct ClimateObject
{
string_id name; // 0x00
uint8_t firstSeason; // 0x02
uint8_t seasonLength[4]; // 0x03
uint8_t winterSnowLine; // 0x07
uint8_t summerSnowLine; // 0x08
};
#pragma pack(pop)
}

View File

@ -54,7 +54,7 @@ namespace OpenLoco::ObjectManager
loco_global<VehicleObject* [224], 0x0050C9E4> _vehicleObjects;
loco_global<TreeObject* [64], 0x0050CD64> _treeObjects;
loco_global<SnowObject* [1], 0x0050CE64> _snowObjects;
loco_global<climate_object* [1], 0x0050CE68> _climateObjects;
loco_global<ClimateObject* [1], 0x0050CE68> _climateObjects;
loco_global<HillShapesObject* [1], 0x0050CE6C> _hillShapeObjects;
loco_global<BuildingObject* [128], 0x0050CE70> _buildingObjects;
loco_global<ScaffoldingObject* [1], 0x0050D070> _scaffoldingObjects;
@ -282,6 +282,17 @@ namespace OpenLoco::ObjectManager
return _competitorObjects[id];
}
template<>
ClimateObject* get()
{
if (_climateObjects[0] == (void*)-1)
{
return nullptr;
}
return _climateObjects[0];
}
template<>
ScenarioTextObject* get()
{

View File

@ -83,7 +83,7 @@ namespace OpenLoco
struct VehicleObject;
struct TreeObject;
struct SnowObject;
struct climate_object;
struct ClimateObject;
struct HillShapesObject;
struct BuildingObject;
struct ScaffoldingObject;

View File

@ -48,6 +48,7 @@
#include "OpenLoco.h"
#include "Platform/Platform.h"
#include "S5/S5.h"
#include "Scenario.h"
#include "ScenarioManager.h"
#include "StationManager.h"
#include "Title.h"
@ -857,14 +858,6 @@ namespace OpenLoco
}
}
static void sub_496A84(int32_t edx)
{
// This is responsible for updating the snow line
registers regs;
regs.edx = edx;
call(0x00496A84, regs);
}
static void autosaveReset()
{
_monthsSinceLastAutosave = 0;
@ -983,7 +976,7 @@ namespace OpenLoco
auto yesterday = calcDate(getCurrentDay() - 1);
auto today = calcDate(getCurrentDay());
setDate(today);
sub_496A84(today.day_of_olympiad);
Scenario::updateSnowLine(today.day_of_olympiad);
if (today.month != yesterday.month)
{
// End of every month

View File

@ -9,6 +9,7 @@
#include "Map/MapGenerator.h"
#include "Map/TileManager.h"
#include "Objects/CargoObject.h"
#include "Objects/ClimateObject.h"
#include "S5/S5.h"
#include "StationManager.h"
#include "Title.h"
@ -25,7 +26,10 @@ namespace OpenLoco::Scenario
static loco_global<CargoObject*, 0x0050D15C> _50D15C;
static loco_global<uint32_t, 0x00525F5E> _scenario_ticks;
static loco_global<uint8_t, 0x00525FB5> _525FB5;
static loco_global<uint8_t, 0x00525FB4> _currentSnowLine;
static loco_global<Season, 0x00525FB5> _currentSeason;
static loco_global<uint16_t, 0x0052622E> _52622E; // tick-related?
static loco_global<uint8_t, 0x00526230> objectiveType;
@ -50,10 +54,81 @@ namespace OpenLoco::Scenario
call(0x004C4BC0);
}
// 0x00496A18
static void sub_496A18()
Season nextSeason(Season season)
{
call(0x00496A18);
switch (season)
{
case Season::autumn:
return Season::winter;
case Season::winter:
return Season::spring;
case Season::spring:
return Season::summer;
case Season::summer:
default:
return Season::autumn;
}
}
// 0x00496A18, 0x00496A84 (adapted)
static void updateSeason(int32_t currentDayOfYear, const ClimateObject* climateObj)
{
Season season = static_cast<Season>(climateObj->firstSeason);
int32_t dayOffset = currentDayOfYear;
for (size_t i = 0; i < std::size(climateObj->seasonLength); i++)
{
dayOffset -= climateObj->seasonLength[i];
if (dayOffset < 0)
break;
season = nextSeason(season);
}
_currentSeason = season;
}
// 0x00496A18
void initialiseSnowLine()
{
auto today = calcDate(getCurrentDay());
int32_t currentDayOfYear = today.day_of_olympiad;
auto* climateObj = ObjectManager::get<ClimateObject>();
if (climateObj == nullptr)
return;
updateSeason(currentDayOfYear, climateObj);
if (_currentSeason == Season::winter)
{
_currentSnowLine = climateObj->winterSnowLine;
}
else
{
_currentSnowLine = climateObj->summerSnowLine;
}
}
// 0x00496A84
void updateSnowLine(int32_t currentDayOfYear)
{
auto* climateObj = ObjectManager::get<ClimateObject>();
if (climateObj == nullptr)
return;
updateSeason(currentDayOfYear, climateObj);
if (_currentSeason == Season::winter)
{
if (_currentSnowLine != climateObj->winterSnowLine)
_currentSnowLine--;
}
else
{
if (_currentSnowLine != climateObj->summerSnowLine)
_currentSnowLine++;
}
}
// 0x00475988
@ -105,8 +180,7 @@ namespace OpenLoco::Scenario
sub_4C4BC0();
initialiseDate(1900);
sub_496A18();
initialiseSnowLine();
sub_475988();
TownManager::reset();
IndustryManager::reset();
@ -164,7 +238,7 @@ namespace OpenLoco::Scenario
_scenario_ticks = 0;
_52622E = 0;
_525FB5 = 1;
_currentSeason = Season::winter;
CompanyManager::determineAvailableVehicles();

View File

@ -34,6 +34,14 @@ namespace OpenLoco::Scenario
cargo_delivery,
};
enum class Season : uint8_t
{
autumn = 0,
winter = 1,
spring = 2,
summer = 3,
};
// NB: min_year has been changed to 1800 in OpenLoco; Locomotion uses 1900.
constexpr uint16_t min_year = 1800;
constexpr uint16_t max_year = 2100;
@ -92,6 +100,9 @@ namespace OpenLoco::Scenario
constexpr uint8_t min_altitude_trees = 0;
constexpr uint8_t max_altitude_trees = 40;
Season nextSeason(Season season);
void initialiseSnowLine();
void updateSnowLine(int32_t currentDayOfYear);
void reset();
void sub_4748D4();
void eraseLandscape();