mirror of https://github.com/OpenRCT2/OpenRCT2.git
Merge branch 'develop' into vehicle-update
This commit is contained in:
commit
133096cd64
18
.travis.yml
18
.travis.yml
|
@ -16,16 +16,20 @@ cache:
|
|||
apt: true
|
||||
|
||||
env:
|
||||
- OPENRCT2_CMAKE_OPTS="-DDISABLE_NETWORK=ON -DDISABLE_HTTP_TWITCH=ON -DCMAKE_C_COMPILER=gcc-4.8 -DCMAKE_CXX_COMPILER=g++-4.8"
|
||||
- OPENRCT2_CMAKE_OPTS="-DDISABLE_NETWORK=ON -DDISABLE_HTTP_TWITCH=ON -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++"
|
||||
- OPENRCT2_CMAKE_OPTS="-DDISABLE_NETWORK=OFF -DDISABLE_HTTP_TWITCH=ON -DCMAKE_C_COMPILER=gcc-4.8 -DCMAKE_CXX_COMPILER=g++-4.8"
|
||||
- OPENRCT2_CMAKE_OPTS="-DDISABLE_NETWORK=OFF -DDISABLE_HTTP_TWITCH=OFF -DCMAKE_C_COMPILER=gcc-4.8 -DCMAKE_CXX_COMPILER=g++-4.8"
|
||||
- OPENRCT2_CMAKE_OPTS="-DCMAKE_C_COMPILER=gcc-4.8 -DCMAKE_CXX_COMPILER=g++-4.8"
|
||||
- OPENRCT2_CMAKE_OPTS="-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++"
|
||||
- OPENRCT2_CMAKE_OPTS="-DCMAKE_TOOLCHAIN_FILE=../CMakeLists_mingw.txt" TARGET=windows
|
||||
- OPENRCT2_CMAKE_OPTS="-DDISABLE_NETWORK=ON -DCMAKE_TOOLCHAIN_FILE=../CMakeLists_mingw.txt" TARGET=windows
|
||||
- OPENRCT2_CMAKE_OPTS="-DDISABLE_NETWORK=ON -DDISABLE_HTTP_TWITCH=ON -DCMAKE_TOOLCHAIN_FILE=../CMakeLists_mingw.txt" TARGET=windows
|
||||
- OPENRCT2_CMAKE_OPTS="-DDISABLE_HTTP_TWITCH=ON -DCMAKE_TOOLCHAIN_FILE=../CMakeLists_mingw.txt" TARGET=windows
|
||||
- TARGET=docker32
|
||||
- OPENRCT2_CMAKE_OPTS="-DDISABLE_NETWORK=ON -DDISABLE_HTTP_TWITCH=ON" TARGET=docker32
|
||||
# Following entries used to be included in testing, but they only proved useful while changing things in CMake setup.
|
||||
# They are meant to be used when there are changes to CMakeLists.txt
|
||||
# - OPENRCT2_CMAKE_OPTS="-DDISABLE_NETWORK=ON -DDISABLE_HTTP_TWITCH=ON -DCMAKE_C_COMPILER=gcc-4.8 -DCMAKE_CXX_COMPILER=g++-4.8"
|
||||
# - OPENRCT2_CMAKE_OPTS="-DDISABLE_NETWORK=ON -DDISABLE_HTTP_TWITCH=ON -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++"
|
||||
# - OPENRCT2_CMAKE_OPTS="-DDISABLE_NETWORK=OFF -DDISABLE_HTTP_TWITCH=ON -DCMAKE_C_COMPILER=gcc-4.8 -DCMAKE_CXX_COMPILER=g++-4.8"
|
||||
# - OPENRCT2_CMAKE_OPTS="-DDISABLE_NETWORK=OFF -DDISABLE_HTTP_TWITCH=OFF -DCMAKE_C_COMPILER=gcc-4.8 -DCMAKE_CXX_COMPILER=g++-4.8"
|
||||
# - OPENRCT2_CMAKE_OPTS="-DDISABLE_NETWORK=ON -DCMAKE_TOOLCHAIN_FILE=../CMakeLists_mingw.txt" TARGET=windows
|
||||
# - OPENRCT2_CMAKE_OPTS="-DDISABLE_NETWORK=ON -DDISABLE_HTTP_TWITCH=ON -DCMAKE_TOOLCHAIN_FILE=../CMakeLists_mingw.txt" TARGET=windows
|
||||
# - OPENRCT2_CMAKE_OPTS="-DDISABLE_HTTP_TWITCH=ON -DCMAKE_TOOLCHAIN_FILE=../CMakeLists_mingw.txt" TARGET=windows
|
||||
|
||||
sudo: required
|
||||
dist: trusty
|
||||
|
|
|
@ -125,8 +125,8 @@ if (APPLE)
|
|||
endif (APPLE)
|
||||
|
||||
# force 32bit build for now and set necessary flags to compile code as is
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32 -std=gnu99 -fno-omit-frame-pointer -fno-pie")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32 -std=gnu++11 -fno-omit-frame-pointer -fno-pie")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32 -std=gnu99 -fno-omit-frame-pointer -fno-pie -fstrict-aliasing -Werror=strict-aliasing")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32 -std=gnu++11 -fno-omit-frame-pointer -fno-pie -fstrict-aliasing -Werror=strict-aliasing")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -m32")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${CMAKE_SHARED_LINKER_FLAGS}")
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
D41B74731C2125E50080A7B9 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D41B74721C2125E50080A7B9 /* Assets.xcassets */; };
|
||||
D435325F1C3472E500BA219B /* libpng.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D435325E1C3472E500BA219B /* libpng.dylib */; };
|
||||
D43532601C34730200BA219B /* libpng.dylib in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D435325E1C3472E500BA219B /* libpng.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
D46105CE1C38828D00DB1EE3 /* scenario_sources.c in Sources */ = {isa = PBXBuildFile; fileRef = D46105CD1C38828D00DB1EE3 /* scenario_sources.c */; };
|
||||
D4ABAB061C2F812B0080CAD9 /* news_options.c in Sources */ = {isa = PBXBuildFile; fileRef = D4ABAB051C2F812B0080CAD9 /* news_options.c */; };
|
||||
D4D4DF141C34697B0048BE43 /* image_io.c in Sources */ = {isa = PBXBuildFile; fileRef = D4D4DF121C34697B0048BE43 /* image_io.c */; };
|
||||
D4EC47DF1C26342F0024B507 /* addresses.c in Sources */ = {isa = PBXBuildFile; fileRef = D4EC46D61C26342F0024B507 /* addresses.c */; };
|
||||
|
@ -90,7 +91,6 @@
|
|||
D4EC48281C26342F0024B507 /* scenario_list.c in Sources */ = {isa = PBXBuildFile; fileRef = D4EC476D1C26342F0024B507 /* scenario_list.c */; };
|
||||
D4EC48291C26342F0024B507 /* scenario.c in Sources */ = {isa = PBXBuildFile; fileRef = D4EC476E1C26342F0024B507 /* scenario.c */; };
|
||||
D4EC482A1C26342F0024B507 /* title.c in Sources */ = {isa = PBXBuildFile; fileRef = D4EC47711C26342F0024B507 /* title.c */; };
|
||||
D4EC482B1C26342F0024B507 /* tutorial.c in Sources */ = {isa = PBXBuildFile; fileRef = D4EC47731C26342F0024B507 /* tutorial.c */; };
|
||||
D4EC482C1C26342F0024B507 /* sawyercoding.c in Sources */ = {isa = PBXBuildFile; fileRef = D4EC47761C26342F0024B507 /* sawyercoding.c */; };
|
||||
D4EC482D1C26342F0024B507 /* util.c in Sources */ = {isa = PBXBuildFile; fileRef = D4EC47781C26342F0024B507 /* util.c */; };
|
||||
D4EC482E1C26342F0024B507 /* about.c in Sources */ = {isa = PBXBuildFile; fileRef = D4EC477B1C26342F0024B507 /* about.c */; };
|
||||
|
@ -219,6 +219,7 @@
|
|||
D41B741C1C210A7A0080A7B9 /* libiconv.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libiconv.tbd; path = usr/lib/libiconv.tbd; sourceTree = SDKROOT; };
|
||||
D41B74721C2125E50080A7B9 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = distribution/osx/Assets.xcassets; sourceTree = SOURCE_ROOT; };
|
||||
D435325E1C3472E500BA219B /* libpng.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libpng.dylib; sourceTree = "<group>"; };
|
||||
D46105CD1C38828D00DB1EE3 /* scenario_sources.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = scenario_sources.c; path = src/scenario_sources.c; sourceTree = "<group>"; };
|
||||
D4895D321C23EFDD000CD788 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = distribution/osx/Info.plist; sourceTree = SOURCE_ROOT; };
|
||||
D497D0781C20FD52002BF46A /* OpenRCT2.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = OpenRCT2.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
D4ABAB051C2F812B0080CAD9 /* news_options.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = news_options.c; sourceTree = "<group>"; };
|
||||
|
@ -370,8 +371,6 @@
|
|||
D4EC47701C26342F0024B507 /* sprites.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sprites.h; path = src/sprites.h; sourceTree = "<group>"; };
|
||||
D4EC47711C26342F0024B507 /* title.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = title.c; path = src/title.c; sourceTree = "<group>"; };
|
||||
D4EC47721C26342F0024B507 /* title.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = title.h; path = src/title.h; sourceTree = "<group>"; };
|
||||
D4EC47731C26342F0024B507 /* tutorial.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = tutorial.c; path = src/tutorial.c; sourceTree = "<group>"; };
|
||||
D4EC47741C26342F0024B507 /* tutorial.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = tutorial.h; path = src/tutorial.h; sourceTree = "<group>"; };
|
||||
D4EC47761C26342F0024B507 /* sawyercoding.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sawyercoding.c; sourceTree = "<group>"; };
|
||||
D4EC47771C26342F0024B507 /* sawyercoding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sawyercoding.h; sourceTree = "<group>"; };
|
||||
D4EC47781C26342F0024B507 /* util.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = util.c; sourceTree = "<group>"; };
|
||||
|
@ -626,13 +625,12 @@
|
|||
D4EC47591C26342F0024B507 /* rct2.c */,
|
||||
D4EC475A1C26342F0024B507 /* rct2.h */,
|
||||
D4EC476D1C26342F0024B507 /* scenario_list.c */,
|
||||
D46105CD1C38828D00DB1EE3 /* scenario_sources.c */,
|
||||
D4EC476E1C26342F0024B507 /* scenario.c */,
|
||||
D4EC476F1C26342F0024B507 /* scenario.h */,
|
||||
D4EC47701C26342F0024B507 /* sprites.h */,
|
||||
D4EC47711C26342F0024B507 /* title.c */,
|
||||
D4EC47721C26342F0024B507 /* title.h */,
|
||||
D4EC47731C26342F0024B507 /* tutorial.c */,
|
||||
D4EC47741C26342F0024B507 /* tutorial.h */,
|
||||
D4163F671C2A044D00B83136 /* version.h */,
|
||||
);
|
||||
name = Sources;
|
||||
|
@ -1312,7 +1310,7 @@
|
|||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "cachedir=\".cache\"\nliburl=\"https://openrct2.website/files/orctlibs-osx.zip\"\n# keep in sync with version in build.sh\nsha256sum=\"02ebc8e7fd8b9b02b7144721784c5d96202a17398bc8652da163c8c85b66a7db\"\n\n[[ ! -e \"${SRCROOT}/libversion\" || $(head -n 1 \"${SRCROOT}/libversion\") != $sha256sum ]]\noutdated=$?\n\nif [[ $outdated -eq 0 ]] || [[ ! -f \"${SRCROOT}/$cachedir/orctlibs.zip\" ]]; then\n if [[ ! -d \"${SRCROOT}/$cachedir\" ]]; then mkdir \"${SRCROOT}/$cachedir\"; fi\n if [[ -f \"${SRCROOT}/$cachedir/orctlibs.zip\" ]]; then rm \"${SRCROOT}/$cachedir/orctlibs.zip\"; fi\n curl -L -o \"${SRCROOT}/$cachedir/orctlibs.zip\" \"$liburl\"\n if [[ -d \"${SRCROOT}/$cachedir/orctlibs\" ]]; then rm -rf \"${SRCROOT}/$cachedir/orctlibs\"; fi\n mkdir \"${SRCROOT}/$cachedir/orctlibs\"\n unzip -uaq -d \"${SRCROOT}/$cachedir/orctlibs\" \"${SRCROOT}/$cachedir/orctlibs.zip\"\nfi\n\nif [[ $outdated -eq 0 ]] || [[ ! -d \"${SRCROOT}/lib\" ]]; then\n if [[ -d \"${SRCROOT}/lib\" ]]; then rm -r \"${SRCROOT}/lib\"; fi\n cp -Rf \"${SRCROOT}/$cachedir/orctlibs/local\" \"${SRCROOT}/lib\"\nfi\nif [[ $outdated -eq 0 ]] || [[ ! -d \"${SRCROOT}/libxc\" ]]; then\n if [[ -d \"${SRCROOT}/libxc\" ]]; then rm -r \"${SRCROOT}/libxc\"; fi\n cp -Rf \"${SRCROOT}/$cachedir/orctlibs/glob\" \"${SRCROOT}/libxc\"\nfi\n\nif [[ $outdated -eq 0 ]]; then\n newsha=$(shasum -a 256 \"${SRCROOT}/$cachedir/orctlibs.zip\" | cut -f1 -d\" \")\n echo $newsha > \"${SRCROOT}/libversion\"\n [[ \"$newsha\" == \"$sha256sum\" ]]\nfi";
|
||||
shellScript = "cachedir=\".cache\"\nliburl=\"https://openrct2.website/files/orctlibs-osx.zip\"\n# keep in sync with version in build.sh\nsha256sum=\"6562ce9e1f37f125e3345bfd8b961777800436bf607b30dc7c964e0e6991ad2c\"\n\n[[ ! -e \"${SRCROOT}/libversion\" || $(head -n 1 \"${SRCROOT}/libversion\") != $sha256sum ]]\noutdated=$?\n\nif [[ $outdated -eq 0 ]] || [[ ! -f \"${SRCROOT}/$cachedir/orctlibs.zip\" ]]; then\n if [[ ! -d \"${SRCROOT}/$cachedir\" ]]; then mkdir \"${SRCROOT}/$cachedir\"; fi\n if [[ -f \"${SRCROOT}/$cachedir/orctlibs.zip\" ]]; then rm \"${SRCROOT}/$cachedir/orctlibs.zip\"; fi\n curl -L -o \"${SRCROOT}/$cachedir/orctlibs.zip\" \"$liburl\"\n if [[ -d \"${SRCROOT}/$cachedir/orctlibs\" ]]; then rm -rf \"${SRCROOT}/$cachedir/orctlibs\"; fi\n mkdir \"${SRCROOT}/$cachedir/orctlibs\"\n unzip -uaq -d \"${SRCROOT}/$cachedir/orctlibs\" \"${SRCROOT}/$cachedir/orctlibs.zip\"\nfi\n\nif [[ $outdated -eq 0 ]] || [[ ! -d \"${SRCROOT}/lib\" ]]; then\n if [[ -d \"${SRCROOT}/lib\" ]]; then rm -r \"${SRCROOT}/lib\"; fi\n cp -Rf \"${SRCROOT}/$cachedir/orctlibs/local\" \"${SRCROOT}/lib\"\nfi\nif [[ $outdated -eq 0 ]] || [[ ! -d \"${SRCROOT}/libxc\" ]]; then\n if [[ -d \"${SRCROOT}/libxc\" ]]; then rm -r \"${SRCROOT}/libxc\"; fi\n cp -Rf \"${SRCROOT}/$cachedir/orctlibs/glob\" \"${SRCROOT}/libxc\"\nfi\n\nif [[ $outdated -eq 0 ]]; then\n newsha=$(shasum -a 256 \"${SRCROOT}/$cachedir/orctlibs.zip\" | cut -f1 -d\" \")\n echo $newsha > \"${SRCROOT}/libversion\"\n [[ \"$newsha\" == \"$sha256sum\" ]]\nfi";
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
|
@ -1382,7 +1380,6 @@
|
|||
D4EC48231C26342F0024B507 /* station.c in Sources */,
|
||||
D4EC484D1C26342F0024B507 /* new_ride.c in Sources */,
|
||||
D4EC484A1C26342F0024B507 /* music_credits.c in Sources */,
|
||||
D4EC482B1C26342F0024B507 /* tutorial.c in Sources */,
|
||||
D4EC48241C26342F0024B507 /* track.c in Sources */,
|
||||
D4EC47DF1C26342F0024B507 /* addresses.c in Sources */,
|
||||
D4EC484B1C26342F0024B507 /* network_status.c in Sources */,
|
||||
|
@ -1450,6 +1447,7 @@
|
|||
D4EC482D1C26342F0024B507 /* util.c in Sources */,
|
||||
D4EC47EA1C26342F0024B507 /* line.c in Sources */,
|
||||
D4EC48271C26342F0024B507 /* vehicle.c in Sources */,
|
||||
D46105CE1C38828D00DB1EE3 /* scenario_sources.c in Sources */,
|
||||
D4EC48281C26342F0024B507 /* scenario_list.c in Sources */,
|
||||
D4EC48581C26342F0024B507 /* scenery.c in Sources */,
|
||||
D4EC48061C26342F0024B507 /* LanguagePack.cpp in Sources */,
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
version: 0.0.4.{build}
|
||||
os: Previous Visual Studio 2015
|
||||
build_script:
|
||||
- ps: >-
|
||||
.\setenv.ps1
|
||||
|
|
|
@ -3946,6 +3946,32 @@ STR_5603 :遊客已離開遊樂設施
|
|||
STR_5604 :遊客已購買物品
|
||||
STR_5605 :遊客已使用設施
|
||||
STR_5606 :遊客已死亡
|
||||
STR_5607 :{SMALLFONT}{BLACK}強制移除選中的地圖元素.
|
||||
STR_5608 :BH
|
||||
STR_5609 :CH
|
||||
STR_5610 :{SMALLFONT}{BLACK}移除選中的地圖元素. 使用時請注意. 因為強制移除地圖元素並不會對遊戲中的現金做成影響.
|
||||
STR_5611 :G
|
||||
STR_5612 :{SMALLFONT}{BLACK}Ghost flag
|
||||
STR_5613 :B
|
||||
STR_5614 :{SMALLFONT}{BLACK}Broken flag
|
||||
STR_5615 :L
|
||||
STR_5616 :{SMALLFONT}{BLACK}Last element for tile flag
|
||||
STR_5617 :{SMALLFONT}{BLACK}將選中的元素移到上面.
|
||||
STR_5618 :{SMALLFONT}{BLACK}將選中的元素移到下面.
|
||||
STR_5619 :夢幻遊樂園
|
||||
STR_5620 :夢幻遊樂園: 資料片1
|
||||
STR_5621 :夢幻遊樂園: 資料片2
|
||||
STR_5622 :模擬樂園2
|
||||
STR_5623 :瘋狂世界
|
||||
STR_5624 :時空歷險
|
||||
STR_5625 :{OPENQUOTES}真實的{ENDQUOTES}樂園
|
||||
STR_5626 :其他樂園
|
||||
STR_5627 :樂園列表的排序方式:
|
||||
STR_5628 :出處的遊戲
|
||||
STR_5629 :困難程度
|
||||
STR_5630 :允許劇情解鎖
|
||||
STR_5631 :額外下載的官方樂園
|
||||
STR_5632 :建設你的..
|
||||
|
||||
|
||||
#####################
|
||||
|
|
|
@ -3677,8 +3677,8 @@ STR_5335 :Ride entrance
|
|||
STR_5336 :Ride exit
|
||||
STR_5337 :Park entrance
|
||||
STR_5338 :Element type
|
||||
STR_5339 :Base height
|
||||
STR_5340 :Clearance height
|
||||
STR_5339 :{SMALLFONT}{BLACK}Base height
|
||||
STR_5340 :{SMALLFONT}{BLACK}Clearance height
|
||||
STR_5341 :Flags
|
||||
STR_5342 :Choose a map tile
|
||||
STR_5343 :Automatically place staff
|
||||
|
@ -3945,6 +3945,474 @@ STR_5603 :Guest has left ride
|
|||
STR_5604 :Guest has bought item
|
||||
STR_5605 :Guest has used facility
|
||||
STR_5606 :Guest has died
|
||||
STR_5607 :{SMALLFONT}{BLACK}Forcefully remove selected map element.
|
||||
STR_5608 :BH
|
||||
STR_5609 :CH
|
||||
STR_5610 :{SMALLFONT}{BLACK}Remove the currently selected map element. This will forcefully remove it, so no cash will be used/gained. Use with caution.
|
||||
STR_5611 :G
|
||||
STR_5612 :{SMALLFONT}{BLACK}Ghost flag
|
||||
STR_5613 :B
|
||||
STR_5614 :{SMALLFONT}{BLACK}Broken flag
|
||||
STR_5615 :L
|
||||
STR_5616 :{SMALLFONT}{BLACK}Last element for tile flag
|
||||
STR_5617 :{SMALLFONT}{BLACK}Move selected element up.
|
||||
STR_5618 :{SMALLFONT}{BLACK}Move selected element down.
|
||||
STR_5619 :RollerCoaster Tycoon
|
||||
STR_5620 :Added Attractions
|
||||
STR_5621 :Loopy Landscapes
|
||||
STR_5622 :RollerCoaster Tycoon 2
|
||||
STR_5623 :Wacky Worlds
|
||||
STR_5624 :Time Twister
|
||||
STR_5625 :{OPENQUOTES}Real{ENDQUOTES} Parks
|
||||
STR_5626 :Other Parks
|
||||
STR_5627 :Group scenario list by:
|
||||
STR_5628 :Source game
|
||||
STR_5629 :Difficulty level
|
||||
STR_5630 :Enable unlocking of scenarios
|
||||
STR_5631 :Original DLC Parks
|
||||
STR_5632 :Build your own...
|
||||
|
||||
#############
|
||||
# Scenarios #
|
||||
################
|
||||
# RCT Original #
|
||||
################
|
||||
<Forest Frontiers>
|
||||
STR_SCNR :Forest Frontiers
|
||||
STR_PARK :Forest Frontiers
|
||||
STR_DTLS :Deep in the forest, build a thriving theme park in a large cleared area
|
||||
|
||||
<Dynamite Dunes>
|
||||
STR_SCNR :Dynamite Dunes
|
||||
STR_PARK :Dynamite Dunes
|
||||
STR_DTLS :Built in the middle of the desert, this theme park contains just one roller coaster but has space for expansion
|
||||
|
||||
<Leafy Lake>
|
||||
STR_SCNR :Leafy Lake
|
||||
STR_PARK :Leafy Lake
|
||||
STR_DTLS :Starting from scratch, build a theme park around a large lake
|
||||
|
||||
<Diamond Heights>
|
||||
STR_SCNR :Diamond Heights
|
||||
STR_PARK :Diamond Heights
|
||||
STR_DTLS :Diamond Heights is already a successful theme park with great rides - develop it to double its value
|
||||
|
||||
<Evergreen Gardens>
|
||||
STR_SCNR :Evergreen Gardens
|
||||
STR_PARK :Evergreen Gardens
|
||||
STR_DTLS :Convert the beautiful Evergreen Gardens into a thriving theme park
|
||||
|
||||
<Bumbly Beach>
|
||||
STR_SCNR :Bumbly Beach
|
||||
STR_PARK :Bumbly Beach
|
||||
STR_DTLS :Develop Bumbly Beach's small amusement park into a thriving theme park
|
||||
|
||||
<Trinity Islands>
|
||||
STR_SCNR :Trinity Islands
|
||||
STR_PARK :Trinity Islands
|
||||
STR_DTLS :Several islands form the basis for this new park
|
||||
|
||||
<Katie's Dreamland>
|
||||
STR_SCNR :Katie's Dreamland
|
||||
STR_PARK :Katie's Dreamland
|
||||
STR_DTLS :A small theme park with a few rides and room for expansion - Your aim is to double the park value
|
||||
|
||||
<Pokey Park>
|
||||
STR_SCNR :Pokey Park
|
||||
STR_PARK :Pokey Park
|
||||
STR_DTLS :A small, cramped amusement park which requires major expansion
|
||||
|
||||
<White Water Park>
|
||||
STR_SCNR :White Water Park
|
||||
STR_PARK :White Water Park
|
||||
STR_DTLS :A park with some excellent water-based rides requires expansion
|
||||
|
||||
<Millennium Mines>
|
||||
STR_SCNR :Millennium Mines
|
||||
STR_PARK :Millennium Mines
|
||||
STR_DTLS :Convert a large abandoned mine from a tourist attraction into a theme park
|
||||
|
||||
<Karts & Coasters>
|
||||
STR_SCNR :Karts & Coasters
|
||||
STR_PARK :Karts & Coasters
|
||||
STR_DTLS :A large park hidden in the forest, with only go-kart tracks and wooden roller coasters
|
||||
|
||||
<Mel's World>
|
||||
STR_SCNR :Mel's World
|
||||
STR_PARK :Mel's World
|
||||
STR_DTLS :This theme park has some well-designed modern rides, but plenty of space for expansion
|
||||
|
||||
<Mystic Mountain>
|
||||
STR_SCNR :Mystic Mountain
|
||||
STR_PARK :Mystic Mountain
|
||||
STR_DTLS :In the hilly forests of Mystic Mountain, build a theme park from scratch
|
||||
|
||||
<Pacific Pyramids>
|
||||
STR_SCNR :Pacific Pyramids
|
||||
STR_PARK :Pacific Pyramids
|
||||
STR_DTLS :Convert the Egyptian Ruins tourist attraction into a thriving theme park
|
||||
|
||||
<Crumbly Woods>
|
||||
STR_SCNR :Crumbly Woods
|
||||
STR_PARK :Crumbly Woods
|
||||
STR_DTLS :A large park with well-designed but rather old rides - Replace the old rides or add new rides to make the park more popular
|
||||
|
||||
<Paradise Pier>
|
||||
STR_SCNR :Paradise Pier
|
||||
STR_PARK :Paradise Pier
|
||||
STR_DTLS :Convert this sleepy town's pier into a thriving attraction
|
||||
|
||||
<Lightning Peaks>
|
||||
STR_SCNR :Lightning Peaks
|
||||
STR_PARK :Lightning Peaks
|
||||
STR_DTLS :The beautiful mountains of Lightning Peaks are popular with walkers and sightseers - Use the available land to attract a new thrill-seeking clientele
|
||||
|
||||
<Ivory Towers>
|
||||
STR_SCNR :Ivory Towers
|
||||
STR_PARK :Ivory Towers
|
||||
STR_DTLS :A well-established park, which has a few problems
|
||||
|
||||
<Rainbow Valley>
|
||||
STR_SCNR :Rainbow Valley
|
||||
STR_PARK :Rainbow Valley
|
||||
STR_DTLS :Rainbow Valley's local authority won't allow any landscape changes or large tree removal, but you must develop the area into a large theme park
|
||||
|
||||
<Thunder Rock>
|
||||
STR_SCNR :Thunder Rock
|
||||
STR_PARK :Thunder Rock
|
||||
STR_DTLS :Thunder Rock stands in the middle of a desert and attracts many tourists - Use the available space to build rides to attract more people
|
||||
|
||||
<Mega Park>
|
||||
STR_SCNR :Mega Park
|
||||
STR_PARK :Mega Park
|
||||
STR_DTLS :Just for fun!
|
||||
|
||||
## Added Attractions
|
||||
<Whispering Cliffs>
|
||||
STR_SCNR :Whispering Cliffs
|
||||
STR_PARK :Whispering Cliffs
|
||||
STR_DTLS :Develop the seaside cliffs into a thriving amusement park
|
||||
|
||||
<Three Monkeys Park>
|
||||
STR_SCNR :Three Monkeys Park
|
||||
STR_PARK :Three Monkeys Park
|
||||
STR_DTLS :Central to this large developing park is a giant triple-track racing/duelling steel coaster
|
||||
|
||||
<Canary Mines>
|
||||
STR_SCNR :Canary Mines
|
||||
STR_PARK :Canary Mines
|
||||
STR_DTLS :This abandoned mine already has the makings of a tourist attraction with its minature railway and a pair of vertical drop roller coasters
|
||||
|
||||
<Barony Bridge>
|
||||
STR_SCNR :Barony Bridge
|
||||
STR_PARK :Barony Bridge
|
||||
STR_DTLS :An old redundant bridge is yours to develop into an amusement park
|
||||
|
||||
<Funtopia>
|
||||
STR_SCNR :Funtopia
|
||||
STR_PARK :Funtopia
|
||||
STR_DTLS :Covering land both sides of a highway, this park has several rides already operating
|
||||
|
||||
<Haunted Harbor>
|
||||
STR_SCNR :Haunted Harbor
|
||||
STR_PARK :Haunted Harbor
|
||||
STR_DTLS :The local authority has agreed to sell nearby land cheaply to this small seaside park, on the condition that certain rides are preserved
|
||||
|
||||
<Fun Fortress>
|
||||
STR_SCNR :Fun Fortress
|
||||
STR_PARK :Fun Fortress
|
||||
STR_DTLS :This castle is all yours to turn into a theme park
|
||||
|
||||
<Future World>
|
||||
STR_SCNR :Future World
|
||||
STR_PARK :Future World
|
||||
STR_DTLS :This futuristic park has plenty of space for new rides on its alien landscape
|
||||
|
||||
<Gentle Glen>
|
||||
STR_SCNR :Gentle Glen
|
||||
STR_PARK :Gentle Glen
|
||||
STR_DTLS :The local population prefer gentle and relaxing rides, so it is your job to expand this park to suit their tastes
|
||||
|
||||
<Jolly Jungle>
|
||||
STR_SCNR :Jolly Jungle
|
||||
STR_PARK :Jolly Jungle
|
||||
STR_DTLS :Deep in the jungle lies a large area of land ready to be turned into a theme park
|
||||
|
||||
<Hydro Hills>
|
||||
STR_SCNR :Hydro Hills
|
||||
STR_PARK :Hydro Hills
|
||||
STR_DTLS :A series of stepped lakes form the basis for this new park
|
||||
|
||||
<Sprightly Park>
|
||||
STR_SCNR :Sprightly Park
|
||||
STR_PARK :Sprightly Park
|
||||
STR_DTLS :This elderly park has many historical rides but is badly in debt
|
||||
|
||||
<Magic Quarters>
|
||||
STR_SCNR :Magic Quarters
|
||||
STR_PARK :Magic Quarters
|
||||
STR_DTLS :A large area of land has been cleared and partially themed ready for you to develop into a landscaped theme park
|
||||
|
||||
<Fruit Farm>
|
||||
STR_SCNR :Fruit Farm
|
||||
STR_PARK :Fruit Farm
|
||||
STR_DTLS :A thriving fruit farm has built a railroad to boost its income, your job is to develop it into a full-blown amusement park
|
||||
|
||||
<Butterfly Dam>
|
||||
STR_SCNR :Butterfly Dam
|
||||
STR_PARK :Butterfly Dam
|
||||
STR_DTLS :The area around a dam is available for you to develop into an amusement park
|
||||
|
||||
<Coaster Canyon>
|
||||
STR_SCNR :Coaster Canyon
|
||||
STR_PARK :Coaster Canyon
|
||||
STR_DTLS :A vast canyon is yours to turn into a theme park
|
||||
|
||||
<Thunderstorm Park>
|
||||
STR_SCNR :Thunderstorm Park
|
||||
STR_PARK :Thunderstorm Park
|
||||
STR_DTLS :The weather is so wet here that a giant pyramid has been built to allow some rides to be built under cover
|
||||
|
||||
<Harmonic Hills>
|
||||
STR_SCNR :Harmonic Hills
|
||||
STR_PARK :Harmonic Hills
|
||||
STR_DTLS :The local authority won't allow you to build above tree height in this park
|
||||
|
||||
<Roman Village>
|
||||
STR_SCNR :Roman Village
|
||||
STR_PARK :Roman Village
|
||||
STR_DTLS :Develop this Roman-themed park by adding rides and roller coasters
|
||||
|
||||
<Swamp Cove>
|
||||
STR_SCNR :Swamp Cove
|
||||
STR_PARK :Swamp Cove
|
||||
STR_DTLS :Built partly on a series of small islands, this park already has a pair of large roller coasters as its centerpiece
|
||||
|
||||
<Adrenaline Heights>
|
||||
STR_SCNR :Adrenaline Heights
|
||||
STR_PARK :Adrenaline Heights
|
||||
STR_DTLS :Build a park to appeal to the high-intensity thrill-seeking local people
|
||||
|
||||
<Utopia Park>
|
||||
STR_SCNR :Utopia Park
|
||||
STR_PARK :Utopia Park
|
||||
STR_DTLS :An oasis in the middle of the desert provides an unusual opportunity to build an amusement park
|
||||
|
||||
<Rotting Heights>
|
||||
STR_SCNR :Rotting Heights
|
||||
STR_PARK :Rotting Heights
|
||||
STR_DTLS :Overgrown and dilapidated, can you resurrect this once-great amusement park?
|
||||
|
||||
<Fiasco Forest>
|
||||
STR_SCNR :Fiasco Forest
|
||||
STR_PARK :Fiasco Forest
|
||||
STR_DTLS :Full of badly designed and dangerous rides, you have a very limited budget and time to fix the problems and turn the park around
|
||||
|
||||
<Pickle Park>
|
||||
STR_SCNR :Pickle Park
|
||||
STR_PARK :Pickle Park
|
||||
STR_DTLS :The local authority will not allow any kind of advertising or promotion, so this park must succeed by reputation only
|
||||
|
||||
<Giggle Downs>
|
||||
STR_SCNR :Giggle Downs
|
||||
STR_PARK :Giggle Downs
|
||||
STR_DTLS :A four lane steeplechase ride is the centerpiece of this expanding park
|
||||
|
||||
<Mineral Park>
|
||||
STR_SCNR :Mineral Park
|
||||
STR_PARK :Mineral Park
|
||||
STR_DTLS :Turn this abandoned stone quarry into a place to attract thrill-seeking tourists
|
||||
|
||||
<Coaster Crazy>
|
||||
STR_SCNR :Coaster Crazy
|
||||
STR_PARK :Coaster Crazy
|
||||
STR_DTLS :You have limited funds but unlimited time to turn this mountainside area into a vast roller coaster park
|
||||
|
||||
<Urban Park>
|
||||
STR_SCNR :Urban Park
|
||||
STR_PARK :Urban Park
|
||||
STR_DTLS :A tiny park has done a deal with the nearby town to allow expansion through the town itself
|
||||
|
||||
<Geoffrey Gardens>
|
||||
STR_SCNR :Geoffrey Gardens
|
||||
STR_PARK :Geoffrey Gardens
|
||||
STR_DTLS :A large garden park needs turning into a thriving theme park
|
||||
|
||||
|
||||
## Loopy Landscapes
|
||||
<Iceberg Islands>
|
||||
STR_SCNR :Iceberg Islands
|
||||
STR_PARK :Iceberg Islands
|
||||
STR_DTLS :A collection of icebergs make a cold setting for this ambitious theme park
|
||||
|
||||
<Volcania>
|
||||
STR_SCNR :Volcania
|
||||
STR_PARK :Volcania
|
||||
STR_DTLS :A dormant volcano is the setting of this coaster-building challenge
|
||||
|
||||
<Arid Heights>
|
||||
STR_SCNR :Arid Heights
|
||||
STR_PARK :Arid Heights
|
||||
STR_DTLS :Free of any financial limits, your challenge is to develop this desert park while keeping the guests happy
|
||||
|
||||
<Razor Rocks>
|
||||
STR_SCNR :Razor Rocks
|
||||
STR_PARK :Razor Rocks
|
||||
STR_DTLS :Your task is to build a massive coaster-filled park in amongst Razor Rocks
|
||||
|
||||
<Crater Lake>
|
||||
STR_SCNR :Crater Lake
|
||||
STR_PARK :Crater Lake
|
||||
STR_DTLS :A large lake in an ancient crater is the setting for this park
|
||||
|
||||
<Vertigo Views>
|
||||
STR_SCNR :Vertigo Views
|
||||
STR_PARK :Vertigo Views
|
||||
STR_DTLS :This large park already has an excellent hyper-coaster, but your task is to massively increase its profit
|
||||
|
||||
<Paradise Pier 2>
|
||||
STR_SCNR :Paradise Pier 2
|
||||
STR_PARK :Paradise Pier 2
|
||||
STR_DTLS :Paradise Pier has expanded its network of walkways over the sea, and your task is to expand the park to use the extra space
|
||||
|
||||
<Dragon's Cove>
|
||||
STR_SCNR :Dragon's Cove
|
||||
STR_PARK :Dragon's Cove
|
||||
STR_DTLS :This sea-side cove is the setting for this coaster-building challenge
|
||||
|
||||
<Good Knight Park>
|
||||
STR_SCNR :Good Knight Park
|
||||
STR_PARK :Good Knight Park
|
||||
STR_DTLS :A castle with a pair of roller coasters needs developing into a larger theme park
|
||||
|
||||
<Wacky Warren>
|
||||
STR_SCNR :Wacky Warren
|
||||
STR_PARK :Wacky Warren
|
||||
STR_DTLS :A park which has much of its footpaths and coasters underground
|
||||
|
||||
<Grand Glacier>
|
||||
STR_SCNR :Grand Glacier
|
||||
STR_PARK :Grand Glacier
|
||||
STR_DTLS :A glacier-filled valley is yours to develop into a theme park
|
||||
|
||||
<Crazy Craters>
|
||||
STR_SCNR :Crazy Craters
|
||||
STR_PARK :Crazy Craters
|
||||
STR_DTLS :In a far-off world where money is not needed, you must build an entertainment centre to keep the people happy
|
||||
|
||||
<Dusty Desert>
|
||||
STR_SCNR :Dusty Desert
|
||||
STR_PARK :Dusty Desert
|
||||
STR_DTLS :Five coasters require completion in this desert park
|
||||
|
||||
<Woodworm Park>
|
||||
STR_SCNR :Woodworm Park
|
||||
STR_PARK :Woodworm Park
|
||||
STR_DTLS :This historical park is only allowed to build older-styled rides
|
||||
|
||||
<Icarus Park>
|
||||
STR_SCNR :Icarus Park
|
||||
STR_PARK :Icarus Park
|
||||
STR_DTLS :Develop this alien park to maximize its profit
|
||||
|
||||
<Sunny Swamps>
|
||||
STR_SCNR :Sunny Swamps
|
||||
STR_PARK :Sunny Swamps
|
||||
STR_DTLS :This well-themed amusement park already has several rides, but has plenty of space for expansion
|
||||
|
||||
<Frightmare Hills>
|
||||
STR_SCNR :Frightmare Hills
|
||||
STR_PARK :Frightmare Hills
|
||||
STR_DTLS :A scary park with a giant centrepiece coaster
|
||||
|
||||
<Thunder Rocks>
|
||||
STR_SCNR :Thunder Rocks
|
||||
STR_PARK :Thunder Rocks
|
||||
STR_DTLS :Two large hunks of rock stick out of the sand, upon which the beginnings of a theme park are constructed
|
||||
|
||||
<Octagon Park>
|
||||
STR_SCNR :Octagon Park
|
||||
STR_PARK :Octagon Park
|
||||
STR_DTLS :In this large park you must design and build ten large coasters
|
||||
|
||||
<Pleasure Island>
|
||||
STR_SCNR :Pleasure Island
|
||||
STR_PARK :Pleasure Island
|
||||
STR_DTLS :A long thin island makes a challenging setting to build a selection of coasters
|
||||
|
||||
<Icicle Worlds>
|
||||
STR_SCNR :Icicle Worlds
|
||||
STR_PARK :Icicle Worlds
|
||||
STR_DTLS :An icy landscape needs turning into a thriving theme park
|
||||
|
||||
<Southern Sands>
|
||||
STR_SCNR :Southern Sands
|
||||
STR_PARK :Southern Sands
|
||||
STR_DTLS :A desert park with some cleverly designed coasters is yours to expand
|
||||
|
||||
<Tiny Towers>
|
||||
STR_SCNR :Tiny Towers
|
||||
STR_PARK :Tiny Towers
|
||||
STR_DTLS :In this tiny park you must finish building the five existing coasters
|
||||
|
||||
<Nevermore Park>
|
||||
STR_SCNR :Nevermore Park
|
||||
STR_PARK :Nevermore Park
|
||||
STR_DTLS :A large park with a novel transporation system around its edge
|
||||
|
||||
<Pacifica>
|
||||
STR_SCNR :Pacifica
|
||||
STR_PARK :Pacifica
|
||||
STR_DTLS :This large island is all yours to develop as an amusement park
|
||||
|
||||
<Urban Jungle>
|
||||
STR_SCNR :Urban Jungle
|
||||
STR_PARK :Urban Jungle
|
||||
STR_DTLS :A giant abandoned skyscraper is a unique opportunity for a theme park developer
|
||||
|
||||
<Terror Town>
|
||||
STR_SCNR :Terror Town
|
||||
STR_PARK :Terror Town
|
||||
STR_DTLS :This urban area is all yours to develop into as an amusement park
|
||||
|
||||
<Megaworld Park>
|
||||
STR_SCNR :Megaworld Park
|
||||
STR_PARK :Megaworld Park
|
||||
STR_DTLS :A giant park already packed full of rides needs improving
|
||||
|
||||
<Venus Ponds>
|
||||
STR_SCNR :Venus Ponds
|
||||
STR_PARK :Venus Ponds
|
||||
STR_DTLS :On a far-away planet this area of land needs turning into a theme park
|
||||
|
||||
<Micro Park>
|
||||
STR_SCNR :Micro Park
|
||||
STR_PARK :Micro Park
|
||||
STR_DTLS :Try to create the world's smallest profitable park
|
||||
|
||||
## Real Parks from RCT1
|
||||
# None of them had details
|
||||
<Alton Towers>
|
||||
STR_SCNR :Alton Towers
|
||||
STR_PARK :Alton Towers
|
||||
STR_DTLS :
|
||||
|
||||
<Heide-Park>
|
||||
STR_SCNR :Heide-Park
|
||||
STR_PARK :Heide-Park
|
||||
STR_DTLS :
|
||||
|
||||
<Blackpool Pleasure Beach>
|
||||
STR_SCNR :Blackpool Pleasure Beach
|
||||
STR_PARK :Blackpool Pleasure Beach
|
||||
STR_DTLS :
|
||||
|
||||
## Misc parks from RCT1
|
||||
# Had no details
|
||||
<Fort Anachronism>
|
||||
STR_SCNR :Fort Anachronism
|
||||
STR_PARK :Fort Anachronism
|
||||
STR_DTLS :
|
||||
|
||||
#####################
|
||||
# Rides/attractions #
|
||||
|
|
|
@ -3646,8 +3646,8 @@ STR_5302 :Clear loan
|
|||
STR_5303 :Allow building in pause mode
|
||||
STR_5304 :Title Sequence:
|
||||
STR_5305 :RollerCoaster Tycoon 1
|
||||
STR_5306 :RollerCoaster Tycoon 1 (AA)
|
||||
STR_5307 :RollerCoaster Tycoon 1 (AA + LL)
|
||||
STR_5306 :RollerCoaster Tycoon 1 (CF)
|
||||
STR_5307 :RollerCoaster Tycoon 1 (CF + LL)
|
||||
STR_5308 :RollerCoaster Tycoon 2
|
||||
STR_5309 :OpenRCT2
|
||||
STR_5310 :Random
|
||||
|
@ -3679,8 +3679,8 @@ STR_5335 :Ride entrance
|
|||
STR_5336 :Ride exit
|
||||
STR_5337 :Park entrance
|
||||
STR_5338 :Element type
|
||||
STR_5339 :Base height
|
||||
STR_5340 :Clearance height
|
||||
STR_5339 :{SMALLFONT}{BLACK}Base height
|
||||
STR_5340 :{SMALLFONT}{BLACK}Clearance height
|
||||
STR_5341 :Flags
|
||||
STR_5342 :Choose a map tile
|
||||
STR_5343 :Automatically place staff
|
||||
|
@ -3926,6 +3926,494 @@ STR_5582 :Trap mouse cursor in window
|
|||
STR_5583 :{COMMA1DP16}ms{POWERNEGATIVEONE}
|
||||
STR_5584 :SI
|
||||
STR_5585 :{SMALLFONT}{BLACK}Unlocks ride operation limits, allowing for things like {VELOCITY} lift hills
|
||||
STR_5586 :Automatically open shops and stalls
|
||||
STR_5587 :{SMALLFONT}{BLACK}When enabled, shops and stalls will be automatically opened after building them
|
||||
STR_5588 :{SMALLFONT}{BLACK}Play with other players
|
||||
STR_5589 :Notification Settings
|
||||
STR_5590 :Park awards
|
||||
STR_5591 :Marketing campaign has finished
|
||||
STR_5592 :Park warnings
|
||||
STR_5593 :Park rating warnings
|
||||
STR_5594 :Ride has broken down
|
||||
STR_5595 :Ride has crashed
|
||||
STR_5596 :Ride warnings
|
||||
STR_5597 :Ride / scenery researched
|
||||
STR_5598 :Guest warnings
|
||||
STR_5599 :Guest is lost
|
||||
STR_5600 :Guest has left the park
|
||||
STR_5601 :Guest is queuing for ride
|
||||
STR_5602 :Guest is on ride
|
||||
STR_5603 :Guest has left ride
|
||||
STR_5604 :Guest has bought item
|
||||
STR_5605 :Guest has used facility
|
||||
STR_5606 :Guest has died
|
||||
STR_5607 :{SMALLFONT}{BLACK}Forcefully remove selected map element.
|
||||
STR_5608 :BH
|
||||
STR_5609 :CH
|
||||
STR_5610 :{SMALLFONT}{BLACK}Remove the currently selected map element. This will forcefully remove it, so no cash will be used/gained. Use with caution.
|
||||
STR_5611 :G
|
||||
STR_5612 :{SMALLFONT}{BLACK}Ghost flag
|
||||
STR_5613 :B
|
||||
STR_5614 :{SMALLFONT}{BLACK}Broken flag
|
||||
STR_5615 :L
|
||||
STR_5616 :{SMALLFONT}{BLACK}Last element for tile flag
|
||||
STR_5617 :{SMALLFONT}{BLACK}Move selected element up.
|
||||
STR_5618 :{SMALLFONT}{BLACK}Move selected element down.
|
||||
STR_5619 :RollerCoaster Tycoon
|
||||
STR_5620 :Corkscrew Follies
|
||||
STR_5621 :Loopy Landscapes
|
||||
STR_5622 :RollerCoaster Tycoon 2
|
||||
STR_5623 :Wacky Worlds
|
||||
STR_5624 :Time Twister
|
||||
STR_5625 :{OPENQUOTES}Real{ENDQUOTES} Parks
|
||||
STR_5626 :Other Parks
|
||||
STR_5627 :Group scenario list by:
|
||||
STR_5628 :Source game
|
||||
STR_5629 :Difficulty level
|
||||
STR_5630 :Enable unlocking of scenarios
|
||||
STR_5631 :Original DLC Parks
|
||||
STR_5632 :Build your own...
|
||||
|
||||
#############
|
||||
# Scenarios #
|
||||
#############
|
||||
|
||||
## RCT Original
|
||||
<Forest Frontiers>
|
||||
STR_SCNR :Forest Frontiers
|
||||
STR_PARK :Forest Frontiers
|
||||
STR_DTLS :Deep in the forest, build a thriving theme park in a large cleared area
|
||||
|
||||
<Dynamite Dunes>
|
||||
STR_SCNR :Dynamite Dunes
|
||||
STR_PARK :Dynamite Dunes
|
||||
STR_DTLS :Built in the middle of the desert, this theme park contains just one roller coaster but has space for expansion
|
||||
|
||||
<Leafy Lake>
|
||||
STR_SCNR :Leafy Lake
|
||||
STR_PARK :Leafy Lake
|
||||
STR_DTLS :Starting from scratch, build a theme park around a large lake
|
||||
|
||||
<Diamond Heights>
|
||||
STR_SCNR :Diamond Heights
|
||||
STR_PARK :Diamond Heights
|
||||
STR_DTLS :Diamond Heights is already a successful theme park with great rides - develop it to double its value
|
||||
|
||||
<Evergreen Gardens>
|
||||
STR_SCNR :Evergreen Gardens
|
||||
STR_PARK :Evergreen Gardens
|
||||
STR_DTLS :Convert the beautiful Evergreen Gardens into a thriving theme park
|
||||
|
||||
<Bumbly Beach>
|
||||
STR_SCNR :Bumbly Beach
|
||||
STR_PARK :Bumbly Beach
|
||||
STR_DTLS :Develop Bumbly Beach's small amusement park into a thriving theme park
|
||||
|
||||
<Trinity Islands>
|
||||
STR_SCNR :Trinity Islands
|
||||
STR_PARK :Trinity Islands
|
||||
STR_DTLS :Several islands form the basis for this new park
|
||||
|
||||
<Katie's Dreamland>
|
||||
STR_SCNR :Katie's World
|
||||
STR_PARK :Katie's World
|
||||
STR_DTLS :A small theme park with a few rides and room for expansion - Your aim is to double the park value
|
||||
|
||||
<Pokey Park>
|
||||
STR_SCNR :Dinky Park
|
||||
STR_PARK :Dinky Park
|
||||
STR_DTLS :A small, cramped amusement park which requires major expansion
|
||||
|
||||
<White Water Park>
|
||||
STR_SCNR :Aqua Park
|
||||
STR_PARK :Aqua Park
|
||||
STR_DTLS :A park with some excellent water-based rides requires expansion
|
||||
|
||||
<Millennium Mines>
|
||||
STR_SCNR :Millennium Mines
|
||||
STR_PARK :Millennium Mines
|
||||
STR_DTLS :Convert a large abandoned mine from a tourist attraction into a theme park
|
||||
|
||||
<Karts & Coasters>
|
||||
STR_SCNR :Karts & Coasters
|
||||
STR_PARK :Karts & Coasters
|
||||
STR_DTLS :A large park hidden in the forest, with only go-kart tracks and wooden roller coasters
|
||||
|
||||
<Mel's World>
|
||||
STR_SCNR :Mel's World
|
||||
STR_PARK :Mel's World
|
||||
STR_DTLS :This theme park has some well-designed modern rides, but plenty of space for expansion
|
||||
|
||||
<Mystic Mountain>
|
||||
STR_SCNR :Mothball Mountain
|
||||
STR_PARK :Mothball Mountain
|
||||
STR_DTLS :In the hilly forests of Mothball Mountain, build a theme park from scratch
|
||||
|
||||
<Pacific Pyramids>
|
||||
STR_SCNR :Pacific Pyramids
|
||||
STR_PARK :Pacific Pyramids
|
||||
STR_DTLS :Convert the Egyptian Ruins tourist attraction into a thriving theme park
|
||||
|
||||
<Crumbly Woods>
|
||||
STR_SCNR :Crumbly Woods
|
||||
STR_PARK :Crumbly Woods
|
||||
STR_DTLS :A large park with well-designed but rather old rides - Replace the old rides or add new rides to make the park more popular
|
||||
|
||||
<Paradise Pier>
|
||||
STR_SCNR :Big Pier
|
||||
STR_PARK :Big Pier
|
||||
STR_DTLS :Convert this sleepy town's pier into a thriving attraction
|
||||
|
||||
<Lightning Peaks>
|
||||
STR_SCNR :Lightning Peaks
|
||||
STR_PARK :Lightning Peaks
|
||||
STR_DTLS :The beautiful mountains of Lightning Peaks are popular with walkers and sightseers - Use the available land to attract a new thrill-seeking clientele
|
||||
|
||||
<Ivory Towers>
|
||||
STR_SCNR :Ivory Towers
|
||||
STR_PARK :Ivory Towers
|
||||
STR_DTLS :A well-established park, which has a few problems
|
||||
|
||||
<Rainbow Valley>
|
||||
STR_SCNR :Rainbow Valley
|
||||
STR_PARK :Rainbow Valley
|
||||
STR_DTLS :Rainbow Valley's local authority won't allow any landscape changes or large tree removal, but you must develop the area into a large theme park
|
||||
|
||||
<Thunder Rock>
|
||||
STR_SCNR :Thunder Rock
|
||||
STR_PARK :Thunder Rock
|
||||
STR_DTLS :Thunder Rock stands in the middle of a desert and attracts many tourists - Use the available space to build rides to attract more people
|
||||
|
||||
<Mega Park>
|
||||
STR_SCNR :Mega Park
|
||||
STR_PARK :Mega Park
|
||||
STR_DTLS :Just for fun!
|
||||
|
||||
## Corkscrew Follies
|
||||
<Whispering Cliffs>
|
||||
STR_SCNR :Whispering Cliffs
|
||||
STR_PARK :Whispering Cliffs
|
||||
STR_DTLS :Develop the seaside cliffs into a thriving amusement park
|
||||
|
||||
<Three Monkeys Park>
|
||||
STR_SCNR :Three Monkeys Park
|
||||
STR_PARK :Three Monkeys Park
|
||||
STR_DTLS :Central to this large developing park is a giant triple-track racing/duelling steel coaster
|
||||
|
||||
<Canary Mines>
|
||||
STR_SCNR :Canary Mines
|
||||
STR_PARK :Canary Mines
|
||||
STR_DTLS :This abandoned mine already has the makings of a tourist attraction with its minature railway and a pair of vertical drop roller coasters
|
||||
|
||||
<Barony Bridge>
|
||||
STR_SCNR :Barony Bridge
|
||||
STR_PARK :Barony Bridge
|
||||
STR_DTLS :An old redundant bridge is yours to develop into an amusement park
|
||||
|
||||
<Funtopia>
|
||||
STR_SCNR :Funtopia
|
||||
STR_PARK :Funtopia
|
||||
STR_DTLS :Covering land both sides of a highway, this park has several rides already operating
|
||||
|
||||
<Haunted Harbor>
|
||||
STR_SCNR :Haunted Harbor
|
||||
STR_PARK :Haunted Harbor
|
||||
STR_DTLS :The local authority has agreed to sell nearby land cheaply to this small seaside park, on the condition that certain rides are preserved
|
||||
|
||||
<Fun Fortress>
|
||||
STR_SCNR :Fun Fortress
|
||||
STR_PARK :Fun Fortress
|
||||
STR_DTLS :This castle is all yours to turn into a theme park
|
||||
|
||||
<Future World>
|
||||
STR_SCNR :Future World
|
||||
STR_PARK :Future World
|
||||
STR_DTLS :This futuristic park has plenty of space for new rides on its alien landscape
|
||||
|
||||
<Gentle Glen>
|
||||
STR_SCNR :Gentle Glen
|
||||
STR_PARK :Gentle Glen
|
||||
STR_DTLS :The local population prefer gentle and relaxing rides, so it is your job to expand this park to suit their tastes
|
||||
|
||||
<Jolly Jungle>
|
||||
STR_SCNR :Jolly Jungle
|
||||
STR_PARK :Jolly Jungle
|
||||
STR_DTLS :Deep in the jungle lies a large area of land ready to be turned into a theme park
|
||||
|
||||
<Hydro Hills>
|
||||
STR_SCNR :Hydro Hills
|
||||
STR_PARK :Hydro Hills
|
||||
STR_DTLS :A series of stepped lakes form the basis for this new park
|
||||
|
||||
<Sprightly Park>
|
||||
STR_SCNR :Sprightly Park
|
||||
STR_PARK :Sprightly Park
|
||||
STR_DTLS :This elderly park has many historical rides but is badly in debt
|
||||
|
||||
<Magic Quarters>
|
||||
STR_SCNR :Magic Quarters
|
||||
STR_PARK :Magic Quarters
|
||||
STR_DTLS :A large area of land has been cleared and partially themed ready for you to develop into a landscaped theme park
|
||||
|
||||
<Fruit Farm>
|
||||
STR_SCNR :Fruit Farm
|
||||
STR_PARK :Fruit Farm
|
||||
STR_DTLS :A thriving fruit farm has built a railroad to boost its income, your job is to develop it into a full-blown amusement park
|
||||
|
||||
<Butterfly Dam>
|
||||
STR_SCNR :Butterfly Dam
|
||||
STR_PARK :Butterfly Dam
|
||||
STR_DTLS :The area around a dam is available for you to develop into an amusement park
|
||||
|
||||
<Coaster Canyon>
|
||||
STR_SCNR :Coaster Canyon
|
||||
STR_PARK :Coaster Canyon
|
||||
STR_DTLS :A vast canyon is yours to turn into a theme park
|
||||
|
||||
<Thunderstorm Park>
|
||||
STR_SCNR :Thunderstorm Park
|
||||
STR_PARK :Thunderstorm Park
|
||||
STR_DTLS :The weather is so wet here that a giant pyramid has been built to allow some rides to be built under cover
|
||||
|
||||
<Harmonic Hills>
|
||||
STR_SCNR :Harmonic Hills
|
||||
STR_PARK :Harmonic Hills
|
||||
STR_DTLS :The local authority won't allow you to build above tree height in this park
|
||||
|
||||
<Roman Village>
|
||||
STR_SCNR :Roman Village
|
||||
STR_PARK :Roman Village
|
||||
STR_DTLS :Develop this Roman-themed park by adding rides and roller coasters
|
||||
|
||||
<Swamp Cove>
|
||||
STR_SCNR :Swamp Cove
|
||||
STR_PARK :Swamp Cove
|
||||
STR_DTLS :Built partly on a series of small islands, this park already has a pair of large roller coasters as its centerpiece
|
||||
|
||||
<Adrenaline Heights>
|
||||
STR_SCNR :Adrenaline Heights
|
||||
STR_PARK :Adrenaline Heights
|
||||
STR_DTLS :Build a park to appeal to the high-intensity thrill-seeking local people
|
||||
|
||||
<Utopia Park>
|
||||
STR_SCNR :Utopia Park
|
||||
STR_PARK :Utopia Park
|
||||
STR_DTLS :An oasis in the middle of the desert provides an unusual opportunity to build an amusement park
|
||||
|
||||
<Rotting Heights>
|
||||
STR_SCNR :Rotting Heights
|
||||
STR_PARK :Rotting Heights
|
||||
STR_DTLS :Overgrown and dilapidated, can you resurrect this once-great amusement park?
|
||||
|
||||
<Fiasco Forest>
|
||||
STR_SCNR :Fiasco Forest
|
||||
STR_PARK :Fiasco Forest
|
||||
STR_DTLS :Full of badly designed and dangerous rides, you have a very limited budget and time to fix the problems and turn the park around
|
||||
|
||||
<Pickle Park>
|
||||
STR_SCNR :Pickle Park
|
||||
STR_PARK :Pickle Park
|
||||
STR_DTLS :The local authority will not allow any kind of advertising or promotion, so this park must succeed by reputation only
|
||||
|
||||
<Giggle Downs>
|
||||
STR_SCNR :Giggle Downs
|
||||
STR_PARK :Giggle Downs
|
||||
STR_DTLS :A four lane steeplechase ride is the centerpiece of this expanding park
|
||||
|
||||
<Mineral Park>
|
||||
STR_SCNR :Mineral Park
|
||||
STR_PARK :Mineral Park
|
||||
STR_DTLS :Turn this abandoned stone quarry into a place to attract thrill-seeking tourists
|
||||
|
||||
<Coaster Crazy>
|
||||
STR_SCNR :Coaster Crazy
|
||||
STR_PARK :Coaster Crazy
|
||||
STR_DTLS :You have limited funds but unlimited time to turn this mountainside area into a vast roller coaster park
|
||||
|
||||
<Urban Park>
|
||||
STR_SCNR :Urban Park
|
||||
STR_PARK :Urban Park
|
||||
STR_DTLS :A tiny park has done a deal with the nearby town to allow expansion through the town itself
|
||||
|
||||
<Geoffrey Gardens>
|
||||
STR_SCNR :Geoffrey Gardens
|
||||
STR_PARK :Geoffrey Gardens
|
||||
STR_DTLS :A large garden park needs turning into a thriving theme park
|
||||
|
||||
## Loopy Landscapes
|
||||
<Iceberg Islands>
|
||||
STR_SCNR :Iceberg Islands
|
||||
STR_PARK :Iceberg Islands
|
||||
STR_DTLS :A collection of icebergs make a cold setting for this ambitious theme park
|
||||
|
||||
<Volcania>
|
||||
STR_SCNR :Volcania
|
||||
STR_PARK :Volcania
|
||||
STR_DTLS :A dormant volcano is the setting of this coaster-building challenge
|
||||
|
||||
<Arid Heights>
|
||||
STR_SCNR :Arid Heights
|
||||
STR_PARK :Arid Heights
|
||||
STR_DTLS :Free of any financial limits, your challenge is to develop this desert park while keeping the guests happy
|
||||
|
||||
<Razor Rocks>
|
||||
STR_SCNR :Razor Rocks
|
||||
STR_PARK :Razor Rocks
|
||||
STR_DTLS :Your task is to build a massive coaster-filled park in amongst Razor Rocks
|
||||
|
||||
<Crater Lake>
|
||||
STR_SCNR :Crater Lake
|
||||
STR_PARK :Crater Lake
|
||||
STR_DTLS :A large lake in an ancient crater is the setting for this park
|
||||
|
||||
<Vertigo Views>
|
||||
STR_SCNR :Vertigo Views
|
||||
STR_PARK :Vertigo Views
|
||||
STR_DTLS :This large park already has an excellent hyper-coaster, but your task is to massively increase its profit
|
||||
|
||||
<Paradise Pier 2>
|
||||
STR_SCNR :Big Pier 2
|
||||
STR_PARK :Big Pier 2
|
||||
STR_DTLS :Big Pier has expanded its network of walkways over the sea, and your task is to expand the park to use the extra space
|
||||
|
||||
<Dragon's Cove>
|
||||
STR_SCNR :Dragon's Cove
|
||||
STR_PARK :Dragon's Cove
|
||||
STR_DTLS :This sea-side cove is the setting for this coaster-building challenge
|
||||
|
||||
<Good Knight Park>
|
||||
STR_SCNR :Good Knight Park
|
||||
STR_PARK :Good Knight Park
|
||||
STR_DTLS :A castle with a pair of roller coasters needs developing into a larger theme park
|
||||
|
||||
<Wacky Warren>
|
||||
STR_SCNR :Wacky Warren
|
||||
STR_PARK :Wacky Warren
|
||||
STR_DTLS :A park which has much of its footpaths and coasters underground
|
||||
|
||||
<Grand Glacier>
|
||||
STR_SCNR :Grand Glacier
|
||||
STR_PARK :Grand Glacier
|
||||
STR_DTLS :A glacier-filled valley is yours to develop into a theme park
|
||||
|
||||
<Crazy Craters>
|
||||
STR_SCNR :Crazy Craters
|
||||
STR_PARK :Crazy Craters
|
||||
STR_DTLS :In a far-off world where money is not needed, you must build an entertainment centre to keep the people happy
|
||||
|
||||
<Dusty Desert>
|
||||
STR_SCNR :Dusty Desert
|
||||
STR_PARK :Dusty Desert
|
||||
STR_DTLS :Five coasters require completion in this desert park
|
||||
|
||||
<Woodworm Park>
|
||||
STR_SCNR :Woodworm Park
|
||||
STR_PARK :Woodworm Park
|
||||
STR_DTLS :This historical park is only allowed to build older-styled rides
|
||||
|
||||
<Icarus Park>
|
||||
STR_SCNR :Icarus Park
|
||||
STR_PARK :Icarus Park
|
||||
STR_DTLS :Develop this alien park to maximize its profit
|
||||
|
||||
<Sunny Swamps>
|
||||
STR_SCNR :Sunny Swamps
|
||||
STR_PARK :Sunny Swamps
|
||||
STR_DTLS :This well-themed amusement park already has several rides, but has plenty of space for expansion
|
||||
|
||||
<Frightmare Hills>
|
||||
STR_SCNR :Frightmare Hills
|
||||
STR_PARK :Frightmare Hills
|
||||
STR_DTLS :A scary park with a giant centrepiece coaster
|
||||
|
||||
<Thunder Rocks>
|
||||
STR_SCNR :Thunder Rocks
|
||||
STR_PARK :Thunder Rocks
|
||||
STR_DTLS :Two large hunks of rock stick out of the sand, upon which the beginnings of a theme park are constructed
|
||||
|
||||
<Octagon Park>
|
||||
STR_SCNR :Octagon Park
|
||||
STR_PARK :Octagon Park
|
||||
STR_DTLS :In this large park you must design and build ten large coasters
|
||||
|
||||
<Pleasure Island>
|
||||
STR_SCNR :Pleasure Island
|
||||
STR_PARK :Pleasure Island
|
||||
STR_DTLS :A long thin island makes a challenging setting to build a selection of coasters
|
||||
|
||||
<Icicle Worlds>
|
||||
STR_SCNR :Icicle Worlds
|
||||
STR_PARK :Icicle Worlds
|
||||
STR_DTLS :An icy landscape needs turning into a thriving theme park
|
||||
|
||||
<Southern Sands>
|
||||
STR_SCNR :Southern Sands
|
||||
STR_PARK :Southern Sands
|
||||
STR_DTLS :A desert park with some cleverly designed coasters is yours to expand
|
||||
|
||||
<Tiny Towers>
|
||||
STR_SCNR :Tiny Towers
|
||||
STR_PARK :Tiny Towers
|
||||
STR_DTLS :In this tiny park you must finish building the five existing coasters
|
||||
|
||||
<Nevermore Park>
|
||||
STR_SCNR :Nevermore Park
|
||||
STR_PARK :Nevermore Park
|
||||
STR_DTLS :A large park with a novel transporation system around its edge
|
||||
|
||||
<Pacifica>
|
||||
STR_SCNR :Pacifica
|
||||
STR_PARK :Pacifica
|
||||
STR_DTLS :This large island is all yours to develop as an amusement park
|
||||
|
||||
<Urban Jungle>
|
||||
STR_SCNR :Urban Jungle
|
||||
STR_PARK :Urban Jungle
|
||||
STR_DTLS :A giant abandoned skyscraper is a unique opportunity for a theme park developer
|
||||
|
||||
<Terror Town>
|
||||
STR_SCNR :Terror Town
|
||||
STR_PARK :Terror Town
|
||||
STR_DTLS :This urban area is all yours to develop into as an amusement park
|
||||
|
||||
<Megaworld Park>
|
||||
STR_SCNR :Megaworld Park
|
||||
STR_PARK :Megaworld Park
|
||||
STR_DTLS :A giant park already packed full of rides needs improving
|
||||
|
||||
<Venus Ponds>
|
||||
STR_SCNR :Venus Ponds
|
||||
STR_PARK :Venus Ponds
|
||||
STR_DTLS :On a far-away planet this area of land needs turning into a theme park
|
||||
|
||||
<Micro Park>
|
||||
STR_SCNR :Micro Park
|
||||
STR_PARK :Micro Park
|
||||
STR_DTLS :Try to create the world's smallest profitable park
|
||||
|
||||
## Real Parks from RCT1
|
||||
# None of them had details
|
||||
<Alton Towers>
|
||||
STR_SCNR :Alton Towers
|
||||
STR_PARK :Alton Towers
|
||||
STR_DTLS :
|
||||
|
||||
<Heide-Park>
|
||||
STR_SCNR :Heide-Park
|
||||
STR_PARK :Heide-Park
|
||||
STR_DTLS :
|
||||
|
||||
<Blackpool Pleasure Beach>
|
||||
STR_SCNR :Blackpool Pleasure Beach
|
||||
STR_PARK :Blackpool Pleasure Beach
|
||||
STR_DTLS :
|
||||
|
||||
## Misc parks from RCT1
|
||||
# Had no details
|
||||
<Fort Anachronism>
|
||||
STR_SCNR :Fort Anachronism
|
||||
STR_PARK :Fort Anachronism
|
||||
STR_DTLS :
|
||||
|
||||
#########
|
||||
# Rides #
|
||||
|
|
|
@ -3278,9 +3278,9 @@ STR_3269 :Landschaftsänderungen verbieten
|
|||
STR_3270 :{SMALLFONT}{BLACK}Jegliche Änderungen an der{NEWLINE}Landschaft verbieten
|
||||
STR_3271 :Hohe Bauten verbieten
|
||||
STR_3272 :{SMALLFONT}{BLACK}Jegliche hohe Bauten verbieten
|
||||
STR_3273 :Höhere Schwierigkeitsstufe für Parkbewertung
|
||||
STR_3273 :Höhere Schwierigkeitsgrad für Parkbewertung
|
||||
STR_3274 :{SMALLFONT}{BLACK}Machen Sie die Parkbewertung schwieriger
|
||||
STR_3275 :Höhere Schwierigkeitsstufe für Besuchergewinnung
|
||||
STR_3275 :Höhere Schwierigkeitsgrad für Besuchergewinnung
|
||||
STR_3276 :{SMALLFONT}{BLACK}Machen Sie das Anlocken von{NEWLINE}Besuchern schwieriger
|
||||
STR_3277 :{WINDOW_COLOUR_2}Kosten für Landkauf:
|
||||
STR_3278 :{WINDOW_COLOUR_2}Kosten für Erwerb v. Baurechten:
|
||||
|
@ -3672,8 +3672,8 @@ STR_5335 :Attraktionseingang
|
|||
STR_5336 :Attraktionsausgang
|
||||
STR_5337 :Parkeingang
|
||||
STR_5338 :Elementtyp
|
||||
STR_5339 :Basishöhe
|
||||
STR_5340 :Lichte Höhe
|
||||
STR_5339 :{SMALLFONT}{BLACK}Basishöhe
|
||||
STR_5340 :{SMALLFONT}{BLACK}Lichte Höhe
|
||||
STR_5341 :Kennzeichen
|
||||
STR_5342 :Eine Kachel auf der Karte auswählen
|
||||
STR_5343 :Personal automatisch platzieren
|
||||
|
@ -3898,7 +3898,7 @@ STR_5561 :Sprache konnte nicht geladen werden
|
|||
STR_5562 :WARNUNG!
|
||||
STR_5563 :Diese Funktion ist derzeit instabil und mit erhöhter Vorsicht zu verwenden.
|
||||
STR_5564 :Fehlerhaftes Element einf.
|
||||
STR_5565 :{SMALLFONT}{BLACK}Fügt ein fehlerhaftes Kartenelement auf der Kachel ein, dadurch werden alle Elemente darüber versteckt.
|
||||
STR_5565 :{SMALLFONT}{BLACK}Fügt ein fehlerhaftes Kartenelement auf{NEWLINE}der Kachel ein, dadurch werden alle Elemente darüber versteckt.
|
||||
STR_5566 :Passwort:
|
||||
STR_5567 :Veröffentlichen
|
||||
STR_5568 :Passwort benötigt
|
||||
|
@ -3919,6 +3919,495 @@ STR_5582 :Mauszeiger im Fenster fangen
|
|||
STR_5583 :{COMMA1DP16}ms{POWERNEGATIVEONE}
|
||||
STR_5584 :SI
|
||||
STR_5585 :{SMALLFONT}{BLACK}Hebt Beschränkungen von Attraktionen auf, um Dinge wie {VELOCITY} schnelle Lifthügel zu erlauben
|
||||
STR_5586 :Läden und Stände automatisch öffnen
|
||||
STR_5587 :{SMALLFONT}{BLACK}Wenn aktiviert, werden Läden und Stände nach dem Bauen automatisch geöffnet
|
||||
STR_5588 :{SMALLFONT}{BLACK}Mit anderen Spielern spielen
|
||||
STR_5589 :Benachrichtigungseinstellungen
|
||||
STR_5590 :Parkauszeichnungen
|
||||
STR_5591 :Marketingkampage wurde beendet
|
||||
STR_5592 :Parkwarnungen
|
||||
STR_5593 :Parkbewertungswarnungen
|
||||
STR_5594 :Attraktion ist ausgefallen
|
||||
STR_5595 :Attraktion ist verunglückt
|
||||
STR_5596 :Attraktionswarnungen
|
||||
STR_5597 :Attraktion / Szenerie erforscht
|
||||
STR_5598 :Besucherwarnungen
|
||||
STR_5599 :Besucher hat sich verirrt
|
||||
STR_5600 :Besucher hat den Park verlassen
|
||||
STR_5601 :Besucher steht für eine Attraktion schlange
|
||||
STR_5602 :Besucher ist auf einer Attraktion
|
||||
STR_5603 :Besucher hat eine Attraktion verlassen
|
||||
STR_5604 :Besucher hat einen Gegenstand gekauft
|
||||
STR_5605 :Besucher hat eine Einrichtung benutzt
|
||||
STR_5606 :Besucher ist gestorben
|
||||
STR_5607 :{SMALLFONT}{BLACK}Erzwingt das Löschen des{NEWLINE}ausgewählten Elements
|
||||
STR_5608 :BH
|
||||
STR_5609 :LH
|
||||
STR_5610 :{SMALLFONT}{BLACK}Entfernt das ausgewählte Kartenelement. Das Löschen wird erzwungen und dadurch kein Geld verwendet/gutgeschrieben. Mit Vorsicht zu verwenden.
|
||||
STR_5611 :G
|
||||
STR_5612 :{SMALLFONT}{BLACK}Flag für Ghost-Element
|
||||
STR_5613 :D
|
||||
STR_5614 :{SMALLFONT}{BLACK}Flag für defektes Element
|
||||
STR_5615 :L
|
||||
STR_5616 :{SMALLFONT}{BLACK}Flag für letztes Element der Kachel
|
||||
STR_5617 :{SMALLFONT}{BLACK}Ausgewähltes Element nach oben bewegen
|
||||
STR_5618 :{SMALLFONT}{BLACK}Ausgewähltes Element nach unten bewegen
|
||||
STR_5619 :RollerCoaster Tycoon
|
||||
STR_5620 :Added Attractions
|
||||
STR_5621 :Loopy Landscapes
|
||||
STR_5622 :RollerCoaster Tycoon 2
|
||||
STR_5623 :Wacky Worlds
|
||||
STR_5624 :Time Twister
|
||||
STR_5625 :{OPENQUOTES}Reale{ENDQUOTES} Parks
|
||||
STR_5626 :Sonstige Parks
|
||||
STR_5627 :Szenarioliste ordnen nach:
|
||||
STR_5628 :Spielherkunft
|
||||
STR_5629 :Schwierigkeitsgrad
|
||||
STR_5630 :Freispielen der Szenarios aktivieren
|
||||
STR_5631 :Originale DLC Parks
|
||||
STR_5632 :Bauen Sie Ihren eigenen...
|
||||
|
||||
#############
|
||||
# Scenarios #
|
||||
################
|
||||
# RCT Original #
|
||||
################
|
||||
<Forest Frontiers>
|
||||
STR_SCNR :Forest Frontiers
|
||||
STR_PARK :Forest Frontiers
|
||||
STR_DTLS :Bauen Sie tief im Wald auf einem großen freigelegten Gelände einen erfolgreichen Freizeitpark.
|
||||
|
||||
<Dynamite Dunes>
|
||||
STR_SCNR :Dynamite Dunes
|
||||
STR_PARK :Dynamite Dunes
|
||||
STR_DTLS :Dieser Freizeitpark inmitten der Wüste besitzt nur eine Achterbahn, hat aber genug Platz für Erweiterungen.
|
||||
|
||||
<Leafy Lake>
|
||||
STR_SCNR :Leafy Lake
|
||||
STR_PARK :Leafy Lake
|
||||
STR_DTLS :Fangen Sie bei Null an und bauen Sie einen Freizeitpark um einen großen See herum.
|
||||
|
||||
<Diamond Heights>
|
||||
STR_SCNR :Diamond Heights
|
||||
STR_PARK :Diamond Heights
|
||||
STR_DTLS :Diamond Heights ist bereits ein erfolgreicher Freizeitpark mit tollen Attraktionen. Entwickeln Sie ihn weiter und verdoppeln Sie seinen Verkehrswert.
|
||||
|
||||
<Evergreen Gardens>
|
||||
STR_SCNR :Evergreen Gardens
|
||||
STR_PARK :Evergreen Gardens
|
||||
STR_DTLS :Wandeln Sie die schönen Evergreen Gardens in einen gut besuchten Freizeitpark um.
|
||||
|
||||
<Bumbly Beach>
|
||||
STR_SCNR :Bumbly Beach
|
||||
STR_PARK :Bumbly Beach
|
||||
STR_DTLS :Machen Sie aus dem kleinen Vergnügungspark Bumbly Beach einen florierenden Freizeitpark.
|
||||
|
||||
<Trinity Islands>
|
||||
STR_SCNR :Trinity Islands
|
||||
STR_PARK :Trinity Islands
|
||||
STR_DTLS :Mehrere Inseln bilden den Ausgangspunkt für diesen neuen Park.
|
||||
|
||||
<Katie's Dreamland>
|
||||
STR_SCNR :Katie's Dreamland
|
||||
STR_PARK :Katie's Dreamland
|
||||
STR_DTLS :Ein kleiner Freizeitpark mit wenigen Attraktionen, aber genug Gelände zur Erweiterung. Ihr Ziel ist es, den Verkehrswert des Parks zu verdoppeln.
|
||||
|
||||
<Pokey Park>
|
||||
STR_SCNR :Pokey Park
|
||||
STR_PARK :Pokey Park
|
||||
STR_DTLS :Ein kleiner, eng zusammengedrängter Vergnügungspark, bei dem eine Erweiterung in großem Ausmaß erforderlich ist.
|
||||
|
||||
<White Water Park>
|
||||
STR_SCNR :White Water Park
|
||||
STR_PARK :White Water Park
|
||||
STR_DTLS :Dieser Park mit verschiedenen hervorragenden Wasser-Attraktionen hat einen Ausbau nötig.
|
||||
|
||||
<Millennium Mines>
|
||||
STR_SCNR :Millennium Mines
|
||||
STR_PARK :Millennium Mines
|
||||
STR_DTLS :Machen Sie einen Freizeitpark aus dieser weitläufigen, verlassenen Mine, die zur Zeit nur von Touristen besichtigt wird.
|
||||
|
||||
<Karts & Coasters>
|
||||
STR_SCNR :Karts & Coasters
|
||||
STR_PARK :Karts & Coasters
|
||||
STR_DTLS :Ein großer Park, versteckt im Wald gelegen, der nur Gokartbahnen und Holzachterbahnen aufzuweisen hat.
|
||||
|
||||
<Mel's World>
|
||||
STR_SCNR :Mel's World
|
||||
STR_PARK :Mel's World
|
||||
STR_DTLS :Dieser Freizeitpark verfügt über ein paar ausgezeichnete moderne Attraktionen und jede Menge Platz für Erweiterungen.
|
||||
|
||||
<Mystic Mountain>
|
||||
STR_SCNR :Mystic Mountain
|
||||
STR_PARK :Mystic Mountain
|
||||
STR_DTLS :Bauen Sie in den bergigen Wäldern der Mystic Mountains einen neuen Freizeitpark.
|
||||
|
||||
<Pacific Pyramids>
|
||||
STR_SCNR :Pacific Pyramids
|
||||
STR_PARK :Pacific Pyramids
|
||||
STR_DTLS :Verwandeln Sie die Touristenattraktion mit ägyptischen Ruinen in einen erfolgreichen Freizeitpark.
|
||||
|
||||
<Crumbly Woods>
|
||||
STR_SCNR :Crumbly Woods
|
||||
STR_PARK :Crumbly Woods
|
||||
STR_DTLS :Ein großer Park mit guten, aber ziemlich alten Attraktionen. Ersetzen Sie die alten Attraktionen oder fügen Sie neue hinzu, damit der Park mehr Leute anzieht.
|
||||
|
||||
<Paradise Pier>
|
||||
STR_SCNR :Paradise Pier
|
||||
STR_PARK :Paradise Pier
|
||||
STR_DTLS :Verwandeln Sie die Anlegestelle dieser verschlafenen Stadt in einen wohlbekannten und gutgehenden Anziehungspunkt.
|
||||
|
||||
<Lightning Peaks>
|
||||
STR_SCNR :Lightning Peaks
|
||||
STR_PARK :Lightning Peaks
|
||||
STR_DTLS :Die herrlichen Berge von Lightning Peaks sind beliebt bei Wanderern und Leuten, die gern interessante Orte besichtigen. Nutzen Sie das zur Verfügung stehende Gelände, um jene Besucher anzulocken, die auf der Suche nach einem aufregenden Kick sind.
|
||||
|
||||
<Ivory Towers>
|
||||
STR_SCNR :Ivory Towers
|
||||
STR_PARK :Ivory Towers
|
||||
STR_DTLS :Ein gut geführter Park, der jedoch ein paar Probleme hat.
|
||||
|
||||
<Rainbow Valley>
|
||||
STR_SCNR :Rainbow Valley
|
||||
STR_PARK :Rainbow Valley
|
||||
STR_DTLS :Die örtlichen Behörden von Rainbow Valley werden landschaftliche Veränderungen oder größere Baumrodungen nicht erlauben, aber Sie sollen in dem Gebiet einen großen Freizeitpark entstehen lassen.
|
||||
|
||||
<Thunder Rock>
|
||||
STR_SCNR :Thunder Rock
|
||||
STR_PARK :Thunder Rock
|
||||
STR_DTLS :Thunder Rock befindet sich mitten in einer Wüste und zieht viele Touristen an. Bauen Sie auf dem verfügbaren Platz Attraktionen, die noch mehr Leute herlocken.
|
||||
|
||||
<Mega Park>
|
||||
STR_SCNR :Mega Park
|
||||
STR_PARK :Mega Park
|
||||
STR_DTLS :Nur zum Spaß!
|
||||
|
||||
## Added Attractions
|
||||
<Whispering Cliffs>
|
||||
STR_SCNR :Whispering Cliffs
|
||||
STR_PARK :Whispering Cliffs
|
||||
STR_DTLS :Lassen Sie in diesen Klippen am Meer einen florierenden Vergnügungspark entstehen.
|
||||
|
||||
<Three Monkeys Park>
|
||||
STR_SCNR :Three Monkeys Park
|
||||
STR_PARK :Three Monkeys Park
|
||||
STR_DTLS :Mitten in diesem großen, aufstrebenden Park steht eine riesige Dreispur-Achterbahn, in der die Fahrt wie ein Kopf-an-Kopf-Rennen abläuft.
|
||||
|
||||
<Canary Mines>
|
||||
STR_SCNR :Canary Mines
|
||||
STR_PARK :Canary Mines
|
||||
STR_DTLS :Dieses verlassene Bergwerk bietet mit der Miniatureisenbahn und den Sturzachterbahnen bereits gute Voraussetzungen, eine Touristenattraktion zu werden.
|
||||
|
||||
<Barony Bridge>
|
||||
STR_SCNR :Barony Bridge
|
||||
STR_PARK :Barony Bridge
|
||||
STR_DTLS :Wandeln Sie eine alte, nicht mehr benutzte Brücke in einen attraktiven Park um.
|
||||
|
||||
<Funtopia>
|
||||
STR_SCNR :Funtopia
|
||||
STR_PARK :Funtopia
|
||||
STR_DTLS :In diesem Park zu beiden Seiten einer Autobahn sind bereits verschiedene Attraktionen in Betrieb.
|
||||
|
||||
<Haunted Harbor>
|
||||
STR_SCNR :Haunted Harbor
|
||||
STR_PARK :Haunted Harbor
|
||||
STR_DTLS :Die örtlichen Behörden haben zugestimmt, dem kleinen Park an der Küste umliegendes Gelände günstig zu verkaufen, unter der Bedingung, dass bestimmte Attraktionen erhalten werden.
|
||||
|
||||
<Fun Fortress>
|
||||
STR_SCNR :Fun Fortress
|
||||
STR_PARK :Fun Fortress
|
||||
STR_DTLS :Sie können Ihrer Fantasie freien Lauf lassen, damit ein Themenpark aus diesem Schloss entsteht.
|
||||
|
||||
<Future World>
|
||||
STR_SCNR :Future World
|
||||
STR_PARK :Future World
|
||||
STR_DTLS :Dieser futuristische Park bietet auf seinem fremdartigen Gelände viel Platz für neue Attraktionen.
|
||||
|
||||
<Gentle Glen>
|
||||
STR_SCNR :Gentle Glen
|
||||
STR_PARK :Gentle Glen
|
||||
STR_DTLS :Die Bevölkerung in der Umgebung bevorzugt gemäßigte Attraktionen, auf denen man sich erholen kann. Ihre Aufgabe ist es, diesen Ansprüchen gerecht zu werden.
|
||||
|
||||
<Jolly Jungle>
|
||||
STR_SCNR :Jolly Jungle
|
||||
STR_PARK :Jolly Jungle
|
||||
STR_DTLS :Ein riesiges Gelände tief im Dschungel wartet darauf, von Ihnen in einen Themenpark umgewandelt zu werden.
|
||||
|
||||
<Hydro Hills>
|
||||
STR_SCNR :Hydro Hills
|
||||
STR_PARK :Hydro Hills
|
||||
STR_DTLS :Eine Reihe terrassenförmig angeordneter Seen sind der Ausgangsort für den neuen Park.
|
||||
|
||||
<Sprightly Park>
|
||||
STR_SCNR :Sprightly Park
|
||||
STR_PARK :Sprightly Park
|
||||
STR_DTLS :Dieser ältere Park besitzt viele historisch interessante Attraktionen, ist aber hoch verschuldet.
|
||||
|
||||
<Magic Quarters>
|
||||
STR_SCNR :Magic Quarters
|
||||
STR_PARK :Magic Quarters
|
||||
STR_DTLS :Ein großes Gelände wurde freigeräumt und teilweise thematisch gestaltet. Sie sollen daraus einen interessante Themenlandschaft machen.
|
||||
|
||||
<Fruit Farm>
|
||||
STR_SCNR :Fruit Farm
|
||||
STR_PARK :Fruit Farm
|
||||
STR_DTLS :Eine gutgehende Obstplantage hat eine Miniatureisenbahn bauen lassen, um die Einnahmen zu steigern. Entwickeln Sie jetzt daraus einen Vergnügungspark mit allem Drum und Dran.
|
||||
|
||||
<Butterfly Dam>
|
||||
STR_SCNR :Butterfly Dam
|
||||
STR_PARK :Butterfly Dam
|
||||
STR_DTLS :Das Gebiet rings um einen Damm steht Ihnen zur Verfügung, damit daraus ein Vergnügungspark entsteht.
|
||||
|
||||
<Coaster Canyon>
|
||||
STR_SCNR :Coaster Canyon
|
||||
STR_PARK :Coaster Canyon
|
||||
STR_DTLS :Ein weitläufiger Canyon steht Ihnen zur Verfügung, um in einen Themenpark verwandelt zu werden.
|
||||
|
||||
<Thunderstorm Park>
|
||||
STR_SCNR :Thunderstorm Park
|
||||
STR_PARK :Thunderstorm Park
|
||||
STR_DTLS :Das Wetter in dieser Gegend ist so feucht, dass bereits eine riesengroße Pyramide gebaut wurde, damit wenigstens einige Attraktionen überdacht sind.
|
||||
|
||||
<Harmonic Hills>
|
||||
STR_SCNR :Harmonic Hills
|
||||
STR_PARK :Harmonic Hills
|
||||
STR_DTLS :Die Baubehörde dieser Gegend erlaubt in diesem Park keine Konstruktionen über Baumhöhe.
|
||||
|
||||
<Roman Village>
|
||||
STR_SCNR :Roman Village
|
||||
STR_PARK :Roman Village
|
||||
STR_DTLS :Entwickeln Sie diesen römisch gestalteten Park weiter, indem Sie Achterbahnen und andere Attraktionen hinzufügen.
|
||||
|
||||
<Swamp Cove>
|
||||
STR_SCNR :Swamp Cove
|
||||
STR_PARK :Swamp Cove
|
||||
STR_DTLS :Dieser Park, der sich über eine Reihe kleiner Inseln erstreckt, besitzt ein Paar einer großen Achterbahn als Hauptattraktion.
|
||||
|
||||
<Adrenaline Heights>
|
||||
STR_SCNR :Adrenaline Heights
|
||||
STR_PARK :Adrenaline Heights
|
||||
STR_DTLS :Bauen Sie einen Park für die Menschen dieser Gegend, die hohe Intensität und Nervenkitzel bevorzugen.
|
||||
|
||||
<Utopia Park>
|
||||
STR_SCNR :Utopia Park
|
||||
STR_PARK :Utopia Park
|
||||
STR_DTLS :Eine Oase inmitten der Wüste ist sicher eine ungewöhnliche Herausforderung für Planer eines Vergnügungsparks.
|
||||
|
||||
<Rotting Heights>
|
||||
STR_SCNR :Rotting Heights
|
||||
STR_PARK :Rotting Heights
|
||||
STR_DTLS :Überwuchert und verfallen. Können Sie diesen einst großartigen Vergnügungspark wieder zum Leben erwecken?
|
||||
|
||||
<Fiasco Forest>
|
||||
STR_SCNR :Fiasco Forest
|
||||
STR_PARK :Fiasco Forest
|
||||
STR_DTLS :Hier gibt es fast nur gefährliche und schlecht geplante Attraktionen. Sie haben nur sehr begrenzte finanzielle Mittel und wenig Zeit, die Probleme zu beheben und den Park umzukrempeln.
|
||||
|
||||
<Pickle Park>
|
||||
STR_SCNR :Pickle Park
|
||||
STR_PARK :Pickle Park
|
||||
STR_DTLS :Die strengen örtlichen Ämter erlauben keinerlei Werbung oder Propaganda. Dieser Park kann also nur durch seinen Ruf zum Erfolg gelangen.
|
||||
|
||||
<Giggle Downs>
|
||||
STR_SCNR :Giggle Downs
|
||||
STR_PARK :Giggle Downs
|
||||
STR_DTLS :Eine vierspurige Bahn mit Renncharakter ist das Herzstück dieses aufstrebenden Parks.
|
||||
|
||||
<Mineral Park>
|
||||
STR_SCNR :Mineral Park
|
||||
STR_PARK :Mineral Park
|
||||
STR_DTLS :Verwandeln Sie diesen verlassenen Steinbruch in einen Ort, der Touristen anzieht, die den besonderen Kick suchen.
|
||||
|
||||
<Coaster Crazy>
|
||||
STR_SCNR :Coaster Crazy
|
||||
STR_PARK :Coaster Crazy
|
||||
STR_DTLS :Sie haben nur begrenzt Geld, aber jede Menge Zeit, aus diesem Berggelände einen riesigen Achterbahn-Park zu machen.
|
||||
|
||||
<Urban Park>
|
||||
STR_SCNR :Urban Park
|
||||
STR_PARK :Urban Park
|
||||
STR_DTLS :Ein winzig kleiner Park hat mit der nahe gelegenen Stadt vereinbart, dass er sich durch die Stadt hindurch ausbreiten darf.
|
||||
|
||||
<Geoffrey Gardens>
|
||||
STR_SCNR :Geoffrey Gardens
|
||||
STR_PARK :Geoffrey Gardens
|
||||
STR_DTLS :Eine große gepflegte Parkanlage soll in einen erfolgreichen Themenpark umgestaltet werden.
|
||||
|
||||
|
||||
## Loopy Landscapes
|
||||
<Iceberg Islands>
|
||||
STR_SCNR :Iceberg Islands
|
||||
STR_PARK :Iceberg Islands
|
||||
STR_DTLS :Eine Anzahl Eisberge bilden die kalte Umgebung dieses anspruchsvollen Parkprojekts.
|
||||
|
||||
<Volcania>
|
||||
STR_SCNR :Volcania
|
||||
STR_PARK :Volcania
|
||||
STR_DTLS :Ein untätiger Vulkan fordert geradezu heraus, an ihm eine Achterbahnanlage zu bauen.
|
||||
|
||||
<Arid Heights>
|
||||
STR_SCNR :Arid Heights
|
||||
STR_PARK :Arid Heights
|
||||
STR_DTLS :Ohne jegliche finanzielle Einschränkungen sollen Sie diesen Wüstenpark ausbauen und dabei die Besucher bei Laune halten.
|
||||
|
||||
<Razor Rocks>
|
||||
STR_SCNR :Razor Rocks
|
||||
STR_PARK :Razor Rocks
|
||||
STR_DTLS :Ihre Aufgabe ist es, zwischen den zerklüfteten Felsen einen Park mit dicht gedrängten Achterbahnen zu bauen.
|
||||
|
||||
<Crater Lake>
|
||||
STR_SCNR :Crater Lake
|
||||
STR_PARK :Crater Lake
|
||||
STR_DTLS :Ein großer See in einem alten Krater ist Ausgangspunkt für diesen Park.
|
||||
|
||||
<Vertigo Views>
|
||||
STR_SCNR :Vertigo Views
|
||||
STR_PARK :Vertigo Views
|
||||
STR_DTLS :Dieser große Park besitzt bereits eine ausgezeichnete Hyper-Achterbahn, aber Ihre Aufgabe ist es, die Erträge beträchtlich zu steigern.
|
||||
|
||||
<Paradise Pier 2>
|
||||
STR_SCNR :Paradise Pier 2
|
||||
STR_PARK :Paradise Pier 2
|
||||
STR_DTLS :Paradise Pier hat sein Netz von Spazierwegen über dem Meer erweitert. Sie sollen den Park erweitern, indem Sie den neu gewonnenen Platz nutzen.
|
||||
|
||||
<Dragon's Cove>
|
||||
STR_SCNR :Dragon's Cove
|
||||
STR_PARK :Dragon's Cove
|
||||
STR_DTLS :Eine Meeresbucht ist der Rahmen für dieses anspruchsvolle Achterbahn-Bauvorhaben.
|
||||
|
||||
<Good Knight Park>
|
||||
STR_SCNR :Good Knight Park
|
||||
STR_PARK :Good Knight Park
|
||||
STR_DTLS :Ein Schloss mit ein paar Achterbahnen soll zu einem großen Vergnügungspark entwickelt werden.
|
||||
|
||||
<Wacky Warren>
|
||||
STR_SCNR :Wacky Warren
|
||||
STR_PARK :Wacky Warren
|
||||
STR_DTLS :Ein Park, dessen Gehwege und Achterbahnen größtenteils unterirdisch angelegt sind.
|
||||
|
||||
<Grand Glacier>
|
||||
STR_SCNR :Grand Glacier
|
||||
STR_PARK :Grand Glacier
|
||||
STR_DTLS :Es steht Ihnen ein Gletschertal zur Verfügung, das in einen Vergnügungspark zu verwandeln ist.
|
||||
|
||||
<Crazy Craters>
|
||||
STR_SCNR :Crazy Craters
|
||||
STR_PARK :Crazy Craters
|
||||
STR_DTLS :In einer weit entfernten Welt, wo man Geld nicht braucht, sollen Sie ein Unterhaltungszentrum bauen, damit die Leute glücklich und zufrieden bleiben.
|
||||
|
||||
<Dusty Desert>
|
||||
STR_SCNR :Dusty Desert
|
||||
STR_PARK :Dusty Desert
|
||||
STR_DTLS :Fünf Achterbahnen müssen in diesem Wüstenpark fertiggestellt werden.
|
||||
|
||||
<Woodworm Park>
|
||||
STR_SCNR :Woodworm Park
|
||||
STR_PARK :Woodworm Park
|
||||
STR_DTLS :In diesem historischen Park dürfen nur Attraktionen im altmodischen Stil gebaut werden.
|
||||
|
||||
<Icarus Park>
|
||||
STR_SCNR :Icarus Park
|
||||
STR_PARK :Icarus Park
|
||||
STR_DTLS :Verbessern Sie diesen außerirdischen Park, damit höchste Erträge erzielt werden.
|
||||
|
||||
<Sunny Swamps>
|
||||
STR_SCNR :Sunny Swamps
|
||||
STR_PARK :Sunny Swamps
|
||||
STR_DTLS :In diesem nach Themen angelegten Park gibt es zwar verschiedene Attraktionen, aber noch viel Platz für Erweiterungen.
|
||||
|
||||
<Frightmare Hills>
|
||||
STR_SCNR :Frightmare Hills
|
||||
STR_PARK :Frightmare Hills
|
||||
STR_DTLS :Ein Gruselpark mit einer Riesenachterbahn als Herzstück.
|
||||
|
||||
<Thunder Rocks>
|
||||
STR_SCNR :Thunder Rocks
|
||||
STR_PARK :Thunder Rocks
|
||||
STR_DTLS :Zwei enorme Gesteinsbrocken ragen aus dem Wüstensand, auf denen mit den ersten Bauten für einen Vergnügungspark bereits begonnen wurde.
|
||||
|
||||
<Octagon Park>
|
||||
STR_SCNR :Octagon Park
|
||||
STR_PARK :Octagon Park
|
||||
STR_DTLS :In diesem weitläufigen Park sollen Sie zehn große Achterbahnen entwerfen und konstruieren.
|
||||
|
||||
<Pleasure Island>
|
||||
STR_SCNR :Pleasure Island
|
||||
STR_PARK :Pleasure Island
|
||||
STR_DTLS :Diese lange, schmale Insel ist Anreiz genug, eine Auswahl an Achterbahnen zu errichten.
|
||||
|
||||
<Icicle Worlds>
|
||||
STR_SCNR :Icicle Worlds
|
||||
STR_PARK :Icicle Worlds
|
||||
STR_DTLS :Eine Eislandschaft soll in einen florierenden Vergnügungspark verwandelt werden.
|
||||
|
||||
<Southern Sands>
|
||||
STR_SCNR :Southern Sands
|
||||
STR_PARK :Southern Sands
|
||||
STR_DTLS :Ein Park in der Wüste mit ein paar durchdachten Achterbahnen steht Ihnen zur Verfügung und soll erweitert werden.
|
||||
|
||||
<Tiny Towers>
|
||||
STR_SCNR :Tiny Towers
|
||||
STR_PARK :Tiny Towers
|
||||
STR_DTLS :In diesem winzigen Park sollten Sie die fünf angefangenen Achterbahnen fertigstellen.
|
||||
|
||||
<Nevermore Park>
|
||||
STR_SCNR :Nevermore Park
|
||||
STR_PARK :Nevermore Park
|
||||
STR_DTLS :Ein großer Park mit einem neuartigen Transportsystem, das durch die Randbereiche führt.
|
||||
|
||||
<Pacifica>
|
||||
STR_SCNR :Pacifica
|
||||
STR_PARK :Pacifica
|
||||
STR_DTLS :Diese große Insel steht zu Ihrer Verfügung, machen Sie einen Vergnügungspark daraus.
|
||||
|
||||
<Urban Jungle>
|
||||
STR_SCNR :Urban Jungle
|
||||
STR_PARK :Urban Jungle
|
||||
STR_DTLS :Ein gigantischer, verlassener Wolkenkratzer ist eine einmalige Gelegenheit für einen Vergnügungsparkbetreiber.
|
||||
|
||||
<Terror Town>
|
||||
STR_SCNR :Terror Town
|
||||
STR_PARK :Terror Town
|
||||
STR_DTLS :Aus diesem Stadtgebiet können Sie einen Vergnügungspark zaubern.
|
||||
|
||||
<Megaworld Park>
|
||||
STR_SCNR :Megaworld Park
|
||||
STR_PARK :Megaworld Park
|
||||
STR_DTLS :Ein ausgedehnter Park, der bereits mit Attraktionen vollgepackt ist, bedarf der Verbesserung.
|
||||
|
||||
<Venus Ponds>
|
||||
STR_SCNR :Venus Ponds
|
||||
STR_PARK :Venus Ponds
|
||||
STR_DTLS :Auf einem weit entfernten Planeten soll dieses Stück Land in einen Vergnügungspark umgewandelt werden.
|
||||
|
||||
<Micro Park>
|
||||
STR_SCNR :Micro Park
|
||||
STR_PARK :Micro Park
|
||||
STR_DTLS :Versuchen Sie, den kleinsten Park der Welt anzulegen und dabei möglichst viel Gewinn zu erzielen.
|
||||
|
||||
## Real Parks from RCT1
|
||||
# None of them had details
|
||||
<Alton Towers>
|
||||
STR_SCNR :Alton Towers
|
||||
STR_PARK :Alton Towers
|
||||
STR_DTLS :
|
||||
|
||||
<Heide-Park>
|
||||
STR_SCNR :Heide-Park
|
||||
STR_PARK :Heide-Park
|
||||
STR_DTLS :
|
||||
|
||||
<Blackpool Pleasure Beach>
|
||||
STR_SCNR :Blackpool Pleasure Beach
|
||||
STR_PARK :Blackpool Pleasure Beach
|
||||
STR_DTLS :
|
||||
|
||||
## Misc parks from RCT1
|
||||
# Had no details
|
||||
<Fort Anachronism>
|
||||
STR_SCNR :Fort Anachronism
|
||||
STR_PARK :Fort Anachronism
|
||||
STR_DTLS :
|
||||
|
||||
#######################
|
||||
# Bahnen/Attraktionen #
|
||||
|
|
|
@ -604,172 +604,172 @@ STR_0599 :A compact roller coaster with individual cars and smooth twisting d
|
|||
STR_0600 :Powered mine trains career along a smooth and twisted track layout
|
||||
STR_0601 :
|
||||
STR_0602 :Roller coaster trains are accelerated out of the station by linear induction motors to speed through twisting inversions
|
||||
STR_0603 :Guest {INT32}
|
||||
STR_0604 :Guest {INT32}
|
||||
STR_0605 :Guest {INT32}
|
||||
STR_0606 :Guest {INT32}
|
||||
STR_0607 :Guest {INT32}
|
||||
STR_0608 :Guest {INT32}
|
||||
STR_0609 :Guest {INT32}
|
||||
STR_0610 :Guest {INT32}
|
||||
STR_0611 :Guest {INT32}
|
||||
STR_0612 :Guest {INT32}
|
||||
STR_0613 :Guest {INT32}
|
||||
STR_0614 :Guest {INT32}
|
||||
STR_0615 :Guest {INT32}
|
||||
STR_0616 :Guest {INT32}
|
||||
STR_0617 :Guest {INT32}
|
||||
STR_0618 :Guest {INT32}
|
||||
STR_0619 :Guest {INT32}
|
||||
STR_0620 :Guest {INT32}
|
||||
STR_0621 :Guest {INT32}
|
||||
STR_0622 :Guest {INT32}
|
||||
STR_0623 :Guest {INT32}
|
||||
STR_0624 :Guest {INT32}
|
||||
STR_0625 :Guest {INT32}
|
||||
STR_0626 :Guest {INT32}
|
||||
STR_0627 :Guest {INT32}
|
||||
STR_0628 :Guest {INT32}
|
||||
STR_0629 :Guest {INT32}
|
||||
STR_0630 :Guest {INT32}
|
||||
STR_0631 :Guest {INT32}
|
||||
STR_0632 :Guest {INT32}
|
||||
STR_0633 :Guest {INT32}
|
||||
STR_0634 :Guest {INT32}
|
||||
STR_0635 :Guest {INT32}
|
||||
STR_0636 :Guest {INT32}
|
||||
STR_0637 :Guest {INT32}
|
||||
STR_0638 :Guest {INT32}
|
||||
STR_0639 :Guest {INT32}
|
||||
STR_0640 :Guest {INT32}
|
||||
STR_0641 :Guest {INT32}
|
||||
STR_0642 :Guest {INT32}
|
||||
STR_0643 :Guest {INT32}
|
||||
STR_0644 :Guest {INT32}
|
||||
STR_0645 :Guest {INT32}
|
||||
STR_0646 :Guest {INT32}
|
||||
STR_0647 :Guest {INT32}
|
||||
STR_0648 :Guest {INT32}
|
||||
STR_0649 :Guest {INT32}
|
||||
STR_0650 :Guest {INT32}
|
||||
STR_0651 :Guest {INT32}
|
||||
STR_0652 :Guest {INT32}
|
||||
STR_0653 :Guest {INT32}
|
||||
STR_0654 :Guest {INT32}
|
||||
STR_0655 :Guest {INT32}
|
||||
STR_0656 :Guest {INT32}
|
||||
STR_0657 :Guest {INT32}
|
||||
STR_0658 :Guest {INT32}
|
||||
STR_0659 :Guest {INT32}
|
||||
STR_0660 :Guest {INT32}
|
||||
STR_0661 :Guest {INT32}
|
||||
STR_0662 :Guest {INT32}
|
||||
STR_0663 :Guest {INT32}
|
||||
STR_0664 :Guest {INT32}
|
||||
STR_0665 :Guest {INT32}
|
||||
STR_0666 :Guest {INT32}
|
||||
STR_0667 :Guest {INT32}
|
||||
STR_0668 :Guest {INT32}
|
||||
STR_0669 :Guest {INT32}
|
||||
STR_0670 :Guest {INT32}
|
||||
STR_0671 :Guest {INT32}
|
||||
STR_0672 :Guest {INT32}
|
||||
STR_0673 :Guest {INT32}
|
||||
STR_0674 :Guest {INT32}
|
||||
STR_0675 :Guest {INT32}
|
||||
STR_0676 :Guest {INT32}
|
||||
STR_0677 :Guest {INT32}
|
||||
STR_0678 :Guest {INT32}
|
||||
STR_0679 :Guest {INT32}
|
||||
STR_0680 :Guest {INT32}
|
||||
STR_0681 :Guest {INT32}
|
||||
STR_0682 :Guest {INT32}
|
||||
STR_0683 :Guest {INT32}
|
||||
STR_0684 :Guest {INT32}
|
||||
STR_0685 :Guest {INT32}
|
||||
STR_0686 :Guest {INT32}
|
||||
STR_0687 :Guest {INT32}
|
||||
STR_0688 :Guest {INT32}
|
||||
STR_0689 :Guest {INT32}
|
||||
STR_0690 :Guest {INT32}
|
||||
STR_0691 :Guest {INT32}
|
||||
STR_0692 :Guest {INT32}
|
||||
STR_0693 :Guest {INT32}
|
||||
STR_0694 :Guest {INT32}
|
||||
STR_0695 :Guest {INT32}
|
||||
STR_0696 :Guest {INT32}
|
||||
STR_0697 :Guest {INT32}
|
||||
STR_0698 :Guest {INT32}
|
||||
STR_0699 :Guest {INT32}
|
||||
STR_0700 :Guest {INT32}
|
||||
STR_0701 :Guest {INT32}
|
||||
STR_0702 :Guest {INT32}
|
||||
STR_0703 :Guest {INT32}
|
||||
STR_0704 :Guest {INT32}
|
||||
STR_0705 :Guest {INT32}
|
||||
STR_0706 :Guest {INT32}
|
||||
STR_0707 :Guest {INT32}
|
||||
STR_0708 :Guest {INT32}
|
||||
STR_0709 :Guest {INT32}
|
||||
STR_0710 :Guest {INT32}
|
||||
STR_0711 :Guest {INT32}
|
||||
STR_0712 :Guest {INT32}
|
||||
STR_0713 :Guest {INT32}
|
||||
STR_0714 :Guest {INT32}
|
||||
STR_0715 :Guest {INT32}
|
||||
STR_0716 :Guest {INT32}
|
||||
STR_0717 :Guest {INT32}
|
||||
STR_0718 :Guest {INT32}
|
||||
STR_0719 :Guest {INT32}
|
||||
STR_0720 :Guest {INT32}
|
||||
STR_0721 :Guest {INT32}
|
||||
STR_0722 :Guest {INT32}
|
||||
STR_0723 :Guest {INT32}
|
||||
STR_0724 :Guest {INT32}
|
||||
STR_0725 :Guest {INT32}
|
||||
STR_0726 :Guest {INT32}
|
||||
STR_0727 :Guest {INT32}
|
||||
STR_0728 :Guest {INT32}
|
||||
STR_0729 :Guest {INT32}
|
||||
STR_0730 :Guest {INT32}
|
||||
STR_0731 :Guest {INT32}
|
||||
STR_0732 :Guest {INT32}
|
||||
STR_0733 :Guest {INT32}
|
||||
STR_0734 :Guest {INT32}
|
||||
STR_0735 :Guest {INT32}
|
||||
STR_0736 :Guest {INT32}
|
||||
STR_0737 :Guest {INT32}
|
||||
STR_0738 :Guest {INT32}
|
||||
STR_0739 :Guest {INT32}
|
||||
STR_0740 :Guest {INT32}
|
||||
STR_0741 :Guest {INT32}
|
||||
STR_0742 :Guest {INT32}
|
||||
STR_0743 :Guest {INT32}
|
||||
STR_0744 :Guest {INT32}
|
||||
STR_0745 :Guest {INT32}
|
||||
STR_0746 :Guest {INT32}
|
||||
STR_0747 :Guest {INT32}
|
||||
STR_0748 :Guest {INT32}
|
||||
STR_0749 :Guest {INT32}
|
||||
STR_0750 :Guest {INT32}
|
||||
STR_0751 :Guest {INT32}
|
||||
STR_0752 :Guest {INT32}
|
||||
STR_0753 :Guest {INT32}
|
||||
STR_0754 :Guest {INT32}
|
||||
STR_0755 :Guest {INT32}
|
||||
STR_0756 :Guest {INT32}
|
||||
STR_0757 :Guest {INT32}
|
||||
STR_0758 :Guest {INT32}
|
||||
STR_0759 :Guest {INT32}
|
||||
STR_0760 :Guest {INT32}
|
||||
STR_0761 :Guest {INT32}
|
||||
STR_0762 :Guest {INT32}
|
||||
STR_0763 :Guest {INT32}
|
||||
STR_0764 :Guest {INT32}
|
||||
STR_0765 :Guest {INT32}
|
||||
STR_0766 :Guest {INT32}
|
||||
STR_0767 :Guest {INT32}
|
||||
STR_0768 :Handyman {INT32}
|
||||
STR_0603 :来客{INT32}
|
||||
STR_0604 :来客{INT32}
|
||||
STR_0605 :来客{INT32}
|
||||
STR_0606 :来客{INT32}
|
||||
STR_0607 :来客{INT32}
|
||||
STR_0608 :来客{INT32}
|
||||
STR_0609 :来客{INT32}
|
||||
STR_0610 :来客{INT32}
|
||||
STR_0611 :来客{INT32}
|
||||
STR_0612 :来客{INT32}
|
||||
STR_0613 :来客{INT32}
|
||||
STR_0614 :来客{INT32}
|
||||
STR_0615 :来客{INT32}
|
||||
STR_0616 :来客{INT32}
|
||||
STR_0617 :来客{INT32}
|
||||
STR_0618 :来客{INT32}
|
||||
STR_0619 :来客{INT32}
|
||||
STR_0620 :来客{INT32}
|
||||
STR_0621 :来客{INT32}
|
||||
STR_0622 :来客{INT32}
|
||||
STR_0623 :来客{INT32}
|
||||
STR_0624 :来客{INT32}
|
||||
STR_0625 :来客{INT32}
|
||||
STR_0626 :来客{INT32}
|
||||
STR_0627 :来客{INT32}
|
||||
STR_0628 :来客{INT32}
|
||||
STR_0629 :来客{INT32}
|
||||
STR_0630 :来客{INT32}
|
||||
STR_0631 :来客{INT32}
|
||||
STR_0632 :来客{INT32}
|
||||
STR_0633 :来客{INT32}
|
||||
STR_0634 :来客{INT32}
|
||||
STR_0635 :来客{INT32}
|
||||
STR_0636 :来客{INT32}
|
||||
STR_0637 :来客{INT32}
|
||||
STR_0638 :来客{INT32}
|
||||
STR_0639 :来客{INT32}
|
||||
STR_0640 :来客{INT32}
|
||||
STR_0641 :来客{INT32}
|
||||
STR_0642 :来客{INT32}
|
||||
STR_0643 :来客{INT32}
|
||||
STR_0644 :来客{INT32}
|
||||
STR_0645 :来客{INT32}
|
||||
STR_0646 :来客{INT32}
|
||||
STR_0647 :来客{INT32}
|
||||
STR_0648 :来客{INT32}
|
||||
STR_0649 :来客{INT32}
|
||||
STR_0650 :来客{INT32}
|
||||
STR_0651 :来客{INT32}
|
||||
STR_0652 :来客{INT32}
|
||||
STR_0653 :来客{INT32}
|
||||
STR_0654 :来客{INT32}
|
||||
STR_0655 :来客{INT32}
|
||||
STR_0656 :来客{INT32}
|
||||
STR_0657 :来客{INT32}
|
||||
STR_0658 :来客{INT32}
|
||||
STR_0659 :来客{INT32}
|
||||
STR_0660 :来客{INT32}
|
||||
STR_0661 :来客{INT32}
|
||||
STR_0662 :来客{INT32}
|
||||
STR_0663 :来客{INT32}
|
||||
STR_0664 :来客{INT32}
|
||||
STR_0665 :来客{INT32}
|
||||
STR_0666 :来客{INT32}
|
||||
STR_0667 :来客{INT32}
|
||||
STR_0668 :来客{INT32}
|
||||
STR_0669 :来客{INT32}
|
||||
STR_0670 :来客{INT32}
|
||||
STR_0671 :来客{INT32}
|
||||
STR_0672 :来客{INT32}
|
||||
STR_0673 :来客{INT32}
|
||||
STR_0674 :来客{INT32}
|
||||
STR_0675 :来客{INT32}
|
||||
STR_0676 :来客{INT32}
|
||||
STR_0677 :来客{INT32}
|
||||
STR_0678 :来客{INT32}
|
||||
STR_0679 :来客{INT32}
|
||||
STR_0680 :来客{INT32}
|
||||
STR_0681 :来客{INT32}
|
||||
STR_0682 :来客{INT32}
|
||||
STR_0683 :来客{INT32}
|
||||
STR_0684 :来客{INT32}
|
||||
STR_0685 :来客{INT32}
|
||||
STR_0686 :来客{INT32}
|
||||
STR_0687 :来客{INT32}
|
||||
STR_0688 :来客{INT32}
|
||||
STR_0689 :来客{INT32}
|
||||
STR_0690 :来客{INT32}
|
||||
STR_0691 :来客{INT32}
|
||||
STR_0692 :来客{INT32}
|
||||
STR_0693 :来客{INT32}
|
||||
STR_0694 :来客{INT32}
|
||||
STR_0695 :来客{INT32}
|
||||
STR_0696 :来客{INT32}
|
||||
STR_0697 :来客{INT32}
|
||||
STR_0698 :来客{INT32}
|
||||
STR_0699 :来客{INT32}
|
||||
STR_0700 :来客{INT32}
|
||||
STR_0701 :来客{INT32}
|
||||
STR_0702 :来客{INT32}
|
||||
STR_0703 :来客{INT32}
|
||||
STR_0704 :来客{INT32}
|
||||
STR_0705 :来客{INT32}
|
||||
STR_0706 :来客{INT32}
|
||||
STR_0707 :来客{INT32}
|
||||
STR_0708 :来客{INT32}
|
||||
STR_0709 :来客{INT32}
|
||||
STR_0710 :来客{INT32}
|
||||
STR_0711 :来客{INT32}
|
||||
STR_0712 :来客{INT32}
|
||||
STR_0713 :来客{INT32}
|
||||
STR_0714 :来客{INT32}
|
||||
STR_0715 :来客{INT32}
|
||||
STR_0716 :来客{INT32}
|
||||
STR_0717 :来客{INT32}
|
||||
STR_0718 :来客{INT32}
|
||||
STR_0719 :来客{INT32}
|
||||
STR_0720 :来客{INT32}
|
||||
STR_0721 :来客{INT32}
|
||||
STR_0722 :来客{INT32}
|
||||
STR_0723 :来客{INT32}
|
||||
STR_0724 :来客{INT32}
|
||||
STR_0725 :来客{INT32}
|
||||
STR_0726 :来客{INT32}
|
||||
STR_0727 :来客{INT32}
|
||||
STR_0728 :来客{INT32}
|
||||
STR_0729 :来客{INT32}
|
||||
STR_0730 :来客{INT32}
|
||||
STR_0731 :来客{INT32}
|
||||
STR_0732 :来客{INT32}
|
||||
STR_0733 :来客{INT32}
|
||||
STR_0734 :来客{INT32}
|
||||
STR_0735 :来客{INT32}
|
||||
STR_0736 :来客{INT32}
|
||||
STR_0737 :来客{INT32}
|
||||
STR_0738 :来客{INT32}
|
||||
STR_0739 :来客{INT32}
|
||||
STR_0740 :来客{INT32}
|
||||
STR_0741 :来客{INT32}
|
||||
STR_0742 :来客{INT32}
|
||||
STR_0743 :来客{INT32}
|
||||
STR_0744 :来客{INT32}
|
||||
STR_0745 :来客{INT32}
|
||||
STR_0746 :来客{INT32}
|
||||
STR_0747 :来客{INT32}
|
||||
STR_0748 :来客{INT32}
|
||||
STR_0749 :来客{INT32}
|
||||
STR_0750 :来客{INT32}
|
||||
STR_0751 :来客{INT32}
|
||||
STR_0752 :来客{INT32}
|
||||
STR_0753 :来客{INT32}
|
||||
STR_0754 :来客{INT32}
|
||||
STR_0755 :来客{INT32}
|
||||
STR_0756 :来客{INT32}
|
||||
STR_0757 :来客{INT32}
|
||||
STR_0758 :来客{INT32}
|
||||
STR_0759 :来客{INT32}
|
||||
STR_0760 :来客{INT32}
|
||||
STR_0761 :来客{INT32}
|
||||
STR_0762 :来客{INT32}
|
||||
STR_0763 :来客{INT32}
|
||||
STR_0764 :来客{INT32}
|
||||
STR_0765 :来客{INT32}
|
||||
STR_0766 :来客{INT32}
|
||||
STR_0767 :来客{INT32}
|
||||
STR_0768 :便利屋 {INT32}
|
||||
STR_0769 :Mechanic {INT32}
|
||||
STR_0770 :Security Guard {INT32}
|
||||
STR_0771 :Entertainer {INT32}
|
||||
|
@ -779,7 +779,7 @@ STR_0774 :Unnamed park{POP16}{POP16}
|
|||
STR_0775 :Unnamed park{POP16}{POP16}
|
||||
STR_0776 :Unnamed park{POP16}{POP16}
|
||||
STR_0777 :Unnamed park{POP16}{POP16}
|
||||
STR_0778 :Sign
|
||||
STR_0778 :バナー
|
||||
STR_0779 :1日
|
||||
STR_0780 :2日
|
||||
STR_0781 :3日
|
||||
|
@ -829,12 +829,12 @@ STR_0824 :{BLACK}{CROSS}
|
|||
STR_0825 :Chosen name in use already
|
||||
STR_0826 :Too many names defined
|
||||
STR_0827 :Not enough cash - requires {CURRENCY2DP}
|
||||
STR_0828 :{SMALLFONT}{BLACK}Close window
|
||||
STR_0829 :{SMALLFONT}{BLACK}Window title - Drag this to move window
|
||||
STR_0830 :{SMALLFONT}{BLACK}Zoom view in
|
||||
STR_0831 :{SMALLFONT}{BLACK}Zoom view out
|
||||
STR_0832 :{SMALLFONT}{BLACK}Rotate view 90{DEGREE} clockwise
|
||||
STR_0833 :{SMALLFONT}{BLACK}Pause game
|
||||
STR_0828 :{SMALLFONT}{BLACK}ウィンドウを閉める
|
||||
STR_0829 :{SMALLFONT}{BLACK}ウィンドウのタイトル - これをドラッグさせる
|
||||
STR_0830 :{SMALLFONT}{BLACK}ズームアウト
|
||||
STR_0831 :{SMALLFONT}{BLACK}ズームイン
|
||||
STR_0832 :{SMALLFONT}{BLACK}時計回90{DEGREE}りに移動させる
|
||||
STR_0833 :{SMALLFONT}{BLACK}ゲームをポーズする
|
||||
STR_0834 :{SMALLFONT}{BLACK}Disk and game options
|
||||
STR_0835 :Game initialisation failed
|
||||
STR_0836 :Unable to start game in a minimised state
|
||||
|
@ -884,16 +884,16 @@ STR_0878 :高すぎる!
|
|||
STR_0879 :Can't lower land here...
|
||||
STR_0880 :Can't raise land here...
|
||||
STR_0881 :Object in the way
|
||||
STR_0882 :Load Game
|
||||
STR_0883 :Save Game
|
||||
STR_0884 :Load Landscape
|
||||
STR_0885 :Save Landscape
|
||||
STR_0886 :Quit Game
|
||||
STR_0887 :Quit Scenario Editor
|
||||
STR_0888 :Quit Roller Coaster Designer
|
||||
STR_0889 :Quit Track Designs Manager
|
||||
STR_0882 :ゲームを再更新する
|
||||
STR_0883 :ゲームをセーブする
|
||||
STR_0884 :景色を再更新する
|
||||
STR_0885 :景色をセーブする
|
||||
STR_0886 :ゲームを閉じる
|
||||
STR_0887 :Scenario Editorを閉じる
|
||||
STR_0888 :Roller Coaster Designerを閉じる
|
||||
STR_0889 :Track Designs Managerを閉じる
|
||||
STR_0890 :SCR{COMMA16}.BMP
|
||||
STR_0891 :Screenshot
|
||||
STR_0891 :スクリーンショット
|
||||
STR_0892 :Screenshot saved to disk as '{STRINGID}'
|
||||
STR_0893 :Screenshot failed !
|
||||
STR_0894 :Landscape data area full !
|
||||
|
@ -952,9 +952,9 @@ STR_0946 :Cancel
|
|||
STR_0947 :Save this before loading ?
|
||||
STR_0948 :Save this before quitting ?
|
||||
STR_0949 :Save this before quitting ?
|
||||
STR_0950 :Load Game
|
||||
STR_0951 :Quit Game
|
||||
STR_0952 :Quit Game
|
||||
STR_0950 :ゲームを再更新する
|
||||
STR_0951 :ゲームを閉じる
|
||||
STR_0952 :ゲームを閉じる
|
||||
STR_0953 :Load Landscape
|
||||
STR_0954 :
|
||||
STR_0955 :{SMALLFONT}{BLACK}Select seat rotation angle for this track section
|
||||
|
@ -974,7 +974,7 @@ STR_0968 :+360{DEGREE}
|
|||
STR_0969 :+405{DEGREE}
|
||||
STR_0970 :+450{DEGREE}
|
||||
STR_0971 :+495{DEGREE}
|
||||
STR_0972 :Cancel
|
||||
STR_0972 :キャンセル
|
||||
STR_0973 :OK
|
||||
STR_0974 :Rides
|
||||
STR_0975 :Shops and Stalls
|
||||
|
@ -1112,11 +1112,11 @@ STR_1106 :Crashing!
|
|||
STR_1107 :Crashed!
|
||||
STR_1108 :Travelling at {VELOCITY}
|
||||
STR_1109 :Swinging
|
||||
STR_1110 :Rotating
|
||||
STR_1111 :Rotating
|
||||
STR_1110 :回転させる
|
||||
STR_1111 :回転させる
|
||||
STR_1112 :Operating
|
||||
STR_1113 :Showing film
|
||||
STR_1114 :Rotating
|
||||
STR_1114 :回転させる
|
||||
STR_1115 :Operating
|
||||
STR_1116 :Operating
|
||||
STR_1117 :Doing circus show
|
||||
|
@ -1170,7 +1170,7 @@ STR_1164 :{STRINGID}{NEWLINE}(Right-Click to Remove)
|
|||
STR_1165 :{STRINGID} - {STRINGID} {COMMA16}
|
||||
STR_1166 :Can't lower water level here...
|
||||
STR_1167 :Can't raise water level here...
|
||||
STR_1168 :Options
|
||||
STR_1168 :設定
|
||||
STR_1169 :(None)
|
||||
STR_1170 :{STRING}
|
||||
STR_1171 :{RED}Closed - -
|
||||
|
@ -1465,7 +1465,7 @@ STR_1459 :Track style
|
|||
STR_1460 :{SMALLFONT}{BLACK}'U' shaped open track
|
||||
STR_1461 :{SMALLFONT}{BLACK}'O' shaped enclosed track
|
||||
STR_1462 :Too steep for lift hill
|
||||
STR_1463 :Guests
|
||||
STR_1463 :来客
|
||||
STR_1464 :Helix up (small)
|
||||
STR_1465 :Helix up (large)
|
||||
STR_1466 :Helix down (small)
|
||||
|
@ -1695,14 +1695,14 @@ STR_1689 :Block brakes
|
|||
STR_1690 :{WINDOW_COLOUR_2}{STRINGID}{NEWLINE}{BLACK}{STRINGID}
|
||||
STR_1691 :{WINDOW_COLOUR_2} Cost: {BLACK}{CURRENCY}
|
||||
STR_1692 :{WINDOW_COLOUR_2} Cost: {BLACK}from {CURRENCY}
|
||||
STR_1693 :{SMALLFONT}{BLACK}Guests
|
||||
STR_1693 :{SMALLFONT}{BLACK}来客
|
||||
STR_1694 :{SMALLFONT}{BLACK}Staff
|
||||
STR_1695 :{SMALLFONT}{BLACK}Income and costs
|
||||
STR_1696 :{SMALLFONT}{BLACK}Customer information
|
||||
STR_1697 :Cannot place these on queue line area
|
||||
STR_1698 :Can only place these on queue area
|
||||
STR_1699 :Too many people in game
|
||||
STR_1700 :Hire new Handyman
|
||||
STR_1700 :便利屋を雇います
|
||||
STR_1701 :Hire new Mechanic
|
||||
STR_1702 :Hire new Security Guard
|
||||
STR_1703 :Hire new Entertainer
|
||||
|
@ -1756,8 +1756,8 @@ STR_1750 :{DURATION}
|
|||
STR_1751 :Can't change time limit for ride...
|
||||
STR_1752 :{SMALLFONT}{BLACK}Show list of individual guests in park
|
||||
STR_1753 :{SMALLFONT}{BLACK}Show summarised list of guests in park
|
||||
STR_1754 :{BLACK}{COMMA16} guests
|
||||
STR_1755 :{BLACK}{COMMA16} guest
|
||||
STR_1754 :{BLACK}{COMMA16} 来客
|
||||
STR_1755 :{BLACK}{COMMA16} 来客
|
||||
STR_1756 :{WINDOW_COLOUR_2}Admission price:
|
||||
STR_1757 :{WINDOW_COLOUR_2}Reliability: {MOVE_X}{255}{BLACK}{COMMA16}%
|
||||
STR_1758 :{SMALLFONT}{BLACK}Build mode
|
||||
|
@ -1848,9 +1848,9 @@ STR_1842 :Favourite of: {COMMA16} guest
|
|||
STR_1843 :Favourite of: {COMMA16} guests
|
||||
STR_1844 :{SMALLFONT}{BLACK}Select information type to show in ride/attraction list
|
||||
STR_1845 :{MONTHYEAR}
|
||||
STR_1846 :{COMMA16} guests
|
||||
STR_1847 :{INLINE_SPRITE}{11}{20}{00}{00}{COMMA16} guests
|
||||
STR_1848 :{INLINE_SPRITE}{10}{20}{00}{00}{COMMA16} guests
|
||||
STR_1846 :{COMMA16}人の来客
|
||||
STR_1847 :{INLINE_SPRITE}{11}{20}{00}{00}{COMMA16}人の来客
|
||||
STR_1848 :{INLINE_SPRITE}{10}{20}{00}{00}{COMMA16}人の来客
|
||||
STR_1849 :{WINDOW_COLOUR_2}Play music
|
||||
STR_1850 :{SMALLFONT}{BLACK}Select whether music should be played for this ride
|
||||
STR_1851 :{WINDOW_COLOUR_2}Running cost: {BLACK}{CURRENCY2DP} per hour
|
||||
|
@ -1861,11 +1861,11 @@ STR_1855 :{WINDOW_COLOUR_2}Built: {BLACK}{COMMA16} Years Ago
|
|||
STR_1856 :{WINDOW_COLOUR_2}Profit per item sold: {BLACK}{CURRENCY2DP}
|
||||
STR_1857 :{WINDOW_COLOUR_2}Loss per item sold: {BLACK}{CURRENCY2DP}
|
||||
STR_1858 :{WINDOW_COLOUR_2}Cost: {BLACK}{CURRENCY2DP} per month
|
||||
STR_1859 :Handymen
|
||||
STR_1859 :便利屋
|
||||
STR_1860 :Mechanics
|
||||
STR_1861 :Security Guards
|
||||
STR_1862 :Entertainers
|
||||
STR_1863 :Handyman
|
||||
STR_1863 :便利屋
|
||||
STR_1864 :Mechanic
|
||||
STR_1865 :Security Guard
|
||||
STR_1866 :Entertainer
|
||||
|
@ -1880,15 +1880,15 @@ STR_1874 :{WINDOW_COLOUR_2}Profit: {BLACK}{CURRENCY2DP} per hour
|
|||
STR_1875 :{BLACK} {SPRITE}{BLACK} {STRINGID}
|
||||
STR_1876 :{WINDOW_COLOUR_2}{INLINE_SPRITE}{251}{19}{00}{00}Inspect Rides
|
||||
STR_1877 :{WINDOW_COLOUR_2}{INLINE_SPRITE}{252}{19}{00}{00}Fix Rides
|
||||
STR_1878 :{WINDOW_COLOUR_2}Inspection:
|
||||
STR_1879 :Every 10 minutes
|
||||
STR_1880 :Every 20 minutes
|
||||
STR_1881 :Every 30 minutes
|
||||
STR_1882 :Every 45 minutes
|
||||
STR_1883 :Every hour
|
||||
STR_1884 :Every 2 hours
|
||||
STR_1885 :Never
|
||||
STR_1886 :Inspecting {STRINGID}
|
||||
STR_1878 :{WINDOW_COLOUR_2}改めるの:
|
||||
STR_1879 :毎10分
|
||||
STR_1880 :毎20分
|
||||
STR_1881 :毎30分
|
||||
STR_1882 :毎45分
|
||||
STR_1883 :毎1時間
|
||||
STR_1884 :毎2時間
|
||||
STR_1885 :改めない
|
||||
STR_1886 :{STRINGID}を改めります
|
||||
STR_1887 :{WINDOW_COLOUR_2}Time since last inspection: {BLACK}{COMMA16} minutes
|
||||
STR_1888 :{WINDOW_COLOUR_2}Time since last inspection: {BLACK}more than 4 hours
|
||||
STR_1889 :{WINDOW_COLOUR_2}Down-Time: {MOVE_X}{255}{BLACK}{COMMA16}%
|
||||
|
@ -2025,24 +2025,24 @@ STR_2017 :Cuddly Toys
|
|||
STR_2018 :Park Maps
|
||||
STR_2019 :On-Ride Photos
|
||||
STR_2020 :Umbrellas
|
||||
STR_2021 :Drinks
|
||||
STR_2022 :Burgers
|
||||
STR_2023 :Chips
|
||||
STR_2024 :Ice Creams
|
||||
STR_2025 :Candyfloss
|
||||
STR_2026 :Empty Cans
|
||||
STR_2027 :Rubbish
|
||||
STR_2021 :ドリンク
|
||||
STR_2022 :バーガー
|
||||
STR_2023 :フライ
|
||||
STR_2024 :ソフトクリーム
|
||||
STR_2025 :綿菓子
|
||||
STR_2026 :空き缶
|
||||
STR_2027 :ごみ
|
||||
STR_2028 :Empty Burger Boxes
|
||||
STR_2029 :Pizzas
|
||||
STR_2029 :ピザ
|
||||
STR_2030 :Vouchers
|
||||
STR_2031 :Popcorn
|
||||
STR_2032 :Hot Dogs
|
||||
STR_2031 :ポップコーン
|
||||
STR_2032 :ホットドッグ
|
||||
STR_2033 :Tentacles
|
||||
STR_2034 :Hats
|
||||
STR_2034 :帽子
|
||||
STR_2035 :Toffee Apples
|
||||
STR_2036 :T-Shirts
|
||||
STR_2037 :Doughnuts
|
||||
STR_2038 :Coffees
|
||||
STR_2036 :ティーシャツ
|
||||
STR_2037 :ドーナツ
|
||||
STR_2038 :コーヒー
|
||||
STR_2039 :Empty Cups
|
||||
STR_2040 :Fried Chicken
|
||||
STR_2041 :Lemonade
|
||||
|
@ -2331,13 +2331,13 @@ STR_2323 :{WINDOW_COLOUR_2}Park size: {BLACK}{COMMA32}m{SQUARED}
|
|||
STR_2324 :{WINDOW_COLOUR_2}Park size: {BLACK}{COMMA32}sq.ft.
|
||||
STR_2325 :{SMALLFONT}{BLACK}Buy land to extend park
|
||||
STR_2326 :{SMALLFONT}{BLACK}Buy construction rights to allow construction above or below land outside the park
|
||||
STR_2327 :Options
|
||||
STR_2328 :{WINDOW_COLOUR_2}Currency:
|
||||
STR_2329 :{WINDOW_COLOUR_2}Distance and Speed:
|
||||
STR_2330 :{WINDOW_COLOUR_2}Temperature:
|
||||
STR_2331 :{WINDOW_COLOUR_2}Height Labels:
|
||||
STR_2332 :Units
|
||||
STR_2333 :Sound
|
||||
STR_2327 :設定
|
||||
STR_2328 :{WINDOW_COLOUR_2}通貨:
|
||||
STR_2329 :{WINDOW_COLOUR_2}距離と速力:
|
||||
STR_2330 :{WINDOW_COLOUR_2}温度:
|
||||
STR_2331 :{WINDOW_COLOUR_2}高さのマーカー:
|
||||
STR_2332 :単位
|
||||
STR_2333 :効果音
|
||||
STR_2334 :パウンド ({POUND})
|
||||
STR_2335 :ドル ($)
|
||||
STR_2336 :フラン (F)
|
||||
|
@ -2345,7 +2345,7 @@ STR_2337 :ドイツマルク (DM)
|
|||
STR_2338 :円 ({YEN})
|
||||
STR_2339 :ペセタ (Pts)
|
||||
STR_2340 :リラ (L)
|
||||
STR_2341 :Guilders (fl.)
|
||||
STR_2341 :フローリン (fl.)
|
||||
STR_2342 :クローナ (kr)
|
||||
STR_2343 :ユーロ ({EURO})
|
||||
STR_2344 :Imperial
|
||||
|
@ -2440,7 +2440,7 @@ STR_2432 :{BLACK}Vouchers for half-price entry to {STRINGID}
|
|||
STR_2433 :{BLACK}Vouchers for free {STRINGID}
|
||||
STR_2434 :{BLACK}Advertising campaign for {STRINGID}
|
||||
STR_2435 :{BLACK}Advertising campaign for {STRINGID}
|
||||
STR_2436 :1 week
|
||||
STR_2436 :1週間
|
||||
STR_2437 :<not used anymore>
|
||||
STR_2438 :<not used anymore>
|
||||
STR_2439 :<not used anymore>
|
||||
|
@ -2727,26 +2727,26 @@ STR_2718 :Up
|
|||
STR_2719 :New file
|
||||
STR_2720 :{UINT16}秒
|
||||
STR_2721 :{UINT16}秒
|
||||
STR_2722 :{UINT16}分:{UINT16}sec
|
||||
STR_2723 :{UINT16}分:{UINT16}secs
|
||||
STR_2724 :{UINT16}分:{UINT16}sec
|
||||
STR_2725 :{UINT16}分:{UINT16}secs
|
||||
STR_2722 :{UINT16}分{UINT16}秒
|
||||
STR_2723 :{UINT16}分{UINT16}秒
|
||||
STR_2724 :{UINT16}分{UINT16}秒
|
||||
STR_2725 :{UINT16}分{UINT16}秒
|
||||
STR_2726 :{UINT16}分
|
||||
STR_2727 :{UINT16}分
|
||||
STR_2728 :{UINT16}時間:{UINT16}min
|
||||
STR_2729 :{UINT16}時間:{UINT16}mins
|
||||
STR_2730 :{UINT16}時間:{UINT16}min
|
||||
STR_2731 :{UINT16}時間:{UINT16}mins
|
||||
STR_2728 :{UINT16}時{UINT16}分
|
||||
STR_2729 :{UINT16}時{UINT16}分
|
||||
STR_2730 :{UINT16}時{UINT16}分
|
||||
STR_2731 :{UINT16}時{UINT16}分
|
||||
STR_2732 :{COMMA16}ft
|
||||
STR_2733 :{COMMA16}m
|
||||
STR_2734 :{COMMA16}mph
|
||||
STR_2735 :{COMMA16}km/h
|
||||
STR_2736 :{MONTH}, 第{COMMA16}年
|
||||
STR_2737 :{STRINGID} {MONTH}, 第{COMMA16}年
|
||||
STR_2736 :{MONTH}月 {COMMA16}年
|
||||
STR_2737 :{STRINGID} {MONTH}月 {COMMA16}年
|
||||
STR_2738 :Title screen music:
|
||||
STR_2739 :None
|
||||
STR_2740 :ローラーコースター タイクーン 1
|
||||
STR_2741 :ローラーコースター タイクーン 2
|
||||
STR_2740 :RollerCoaster Tycoon 1
|
||||
STR_2741 :RollerCoaster Tycoon 2
|
||||
STR_2742 :css50.dat not found
|
||||
STR_2743 :Copy data\css17.dat from your RCT1 installation to data\css50.dat in your RCT2 installation.
|
||||
STR_2744 :[
|
||||
|
@ -2782,7 +2782,7 @@ STR_2772 :Faster Gamespeed
|
|||
STR_2773 :Windowed
|
||||
STR_2774 :Fullscreen
|
||||
STR_2775 :Fullscreen (desktop)
|
||||
STR_2776 :Language:
|
||||
STR_2776 :言語:
|
||||
STR_2777 :{MOVE_X}{SMALLFONT}{STRING}
|
||||
STR_2778 :{RIGHTGUILLEMET}{MOVE_X}{SMALLFONT}{STRING}
|
||||
STR_2779 :Viewport #{COMMA16}
|
||||
|
@ -2998,7 +2998,7 @@ STR_2987 :{SMALLFONT}{BLACK}Set this banner as a 'no-entry' sign for guests
|
|||
STR_2988 :{SMALLFONT}{BLACK}Demolish this banner
|
||||
STR_2989 :{SMALLFONT}{BLACK}Select main colour
|
||||
STR_2990 :{SMALLFONT}{BLACK}Select text colour
|
||||
STR_2991 :Sign
|
||||
STR_2991 :バナー
|
||||
STR_2992 :Sign text
|
||||
STR_2993 :Enter new text for this sign:
|
||||
STR_2994 :{SMALLFONT}{BLACK}Change text on sign
|
||||
|
@ -3138,7 +3138,7 @@ STR_3127 :{WINDOW_COLOUR_2}Nausea Factor: {BLACK}+{COMMA16}%
|
|||
STR_3128 :Save Track Design
|
||||
STR_3129 :Save Track Design with Scenery
|
||||
STR_3130 :Save
|
||||
STR_3131 :Cancel
|
||||
STR_3131 :キャンセル
|
||||
STR_3132 :{BLACK}Click items of scenery to select them to be saved with track design...
|
||||
STR_3133 :Unable to build this on a slope
|
||||
STR_3134 :{RED}(Design includes scenery which is unavailable)
|
||||
|
@ -3449,11 +3449,11 @@ STR_3436 :{SMALLFONT}{BLACK}While waiting for our first riders, we could cust
|
|||
STR_3437 :{SMALLFONT}{BLACK}Clear large areas of scenery from landscape
|
||||
STR_3438 :Unable to remove all scenery from here...
|
||||
STR_3439 :Clear Scenery
|
||||
STR_3440 :Page 1
|
||||
STR_3441 :Page 2
|
||||
STR_3442 :Page 3
|
||||
STR_3443 :Page 4
|
||||
STR_3444 :Page 5
|
||||
STR_3440 :1ページ目
|
||||
STR_3441 :2ページ目
|
||||
STR_3442 :3ページ目
|
||||
STR_3443 :4ページ目
|
||||
STR_3444 :5ページ目
|
||||
STR_3445 :Set Patrol Area
|
||||
STR_3446 :Cancel Patrol Area
|
||||
|
||||
|
@ -3498,10 +3498,10 @@ STR_5156 :{SMALLFONT}{BLACK}Allows testing of most ride types even when the t
|
|||
STR_5157 :Unlock all prices
|
||||
STR_5158 :Quit to menu
|
||||
STR_5159 :Exit OpenRCT2
|
||||
STR_5160 :{POP16}{MONTH} {PUSH16}{PUSH16}{STRINGID}, Year {POP16}{COMMA16}
|
||||
STR_5160 :{POP16}{MONTH} {PUSH16}{PUSH16}{STRINGID} {POP16}{COMMA16}年
|
||||
STR_5161 :Date Format:
|
||||
STR_5162 :Day/Month/Year
|
||||
STR_5163 :Month/Day/Year
|
||||
STR_5162 :日月年
|
||||
STR_5163 :月日年
|
||||
STR_5164 :Twitch Channel name
|
||||
STR_5165 :Name peeps after followers
|
||||
STR_5166 :{SMALLFONT}{BLACK}Will name peeps after channel's Twitch followers
|
||||
|
@ -3634,8 +3634,8 @@ STR_5292 :{SMALLFONT}{BLACK}Force a breakdown
|
|||
STR_5293 :{SMALLFONT}{BLACK}Close ride/attraction
|
||||
STR_5294 :{SMALLFONT}{BLACK}Test ride/attraction
|
||||
STR_5295 :{SMALLFONT}{BLACK}Open ride/attraction
|
||||
STR_5296 :{SMALLFONT}{BLACK}Close park
|
||||
STR_5297 :{SMALLFONT}{BLACK}Open park
|
||||
STR_5296 :{SMALLFONT}{BLACK}遊園地を閉める
|
||||
STR_5297 :{SMALLFONT}{BLACK}遊園地を開ける
|
||||
STR_5298 :{RED}{STRINGID}
|
||||
STR_5299 :{LIGHTPINK}{STRINGID}
|
||||
STR_5300 :{SMALLFONT}{BLACK}Quick fire staff
|
||||
|
@ -3643,10 +3643,10 @@ STR_5301 :{MEDIUMFONT}{BLACK}Clear your loan
|
|||
STR_5302 :Clear loan
|
||||
STR_5303 :Allow building in pause mode
|
||||
STR_5304 :Title Sequence:
|
||||
STR_5305 :ローラーコースター タイクーン 1
|
||||
STR_5306 :ローラーコースター タイクーン 1 (AA)
|
||||
STR_5307 :ローラーコースター タイクーン 1 (AA + 遊園地再生計画)
|
||||
STR_5308 :ローラーコースター タイクーン 2
|
||||
STR_5305 :RollerCoaster Tycoon 1
|
||||
STR_5306 :RollerCoaster Tycoon 1 (AA)
|
||||
STR_5307 :RollerCoaster Tycoon 1 (AA + LL)
|
||||
STR_5308 :RollerCoaster Tycoon 2
|
||||
STR_5309 :OpenRCT2
|
||||
STR_5310 :ランダム
|
||||
STR_5311 :{SMALLFONT}{BLACK}デバグツール
|
||||
|
@ -3819,7 +3819,7 @@ STR_5477 :Map rendering
|
|||
STR_5478 :Controls
|
||||
STR_5479 :Toolbar
|
||||
STR_5480 :Show toolbar buttons for:
|
||||
STR_5481 :Themes
|
||||
STR_5481 :スタイル
|
||||
STR_5482 :{WINDOW_COLOUR_2}Time since last inspection: {BLACK}1 minute
|
||||
STR_5483 :{BLACK}({COMMA16} weeks remaining)
|
||||
STR_5484 :{BLACK}({COMMA16} week remaining)
|
||||
|
@ -3850,7 +3850,7 @@ STR_5508 :Allow loading files with incorrect checksums
|
|||
STR_5509 :{SMALLFONT}{BLACK}Allows loading scenarios and saves that have an incorrect checksum, like the scenarios from the demo or damaged saves.
|
||||
STR_5510 :Default sound device
|
||||
STR_5511 :(UNKNOWN)
|
||||
STR_5512 :Save Game As
|
||||
STR_5512 :名前を保存
|
||||
STR_5513 :(Quick) save game
|
||||
STR_5514 :Disable vandalism
|
||||
STR_5515 :{SMALLFONT}{BLACK}Stops guests from vandalising your park when they're angry
|
||||
|
@ -3888,9 +3888,9 @@ STR_5546 :{SMALLFONT}{BLACK}Bright pink
|
|||
STR_5547 :{SMALLFONT}{BLACK}Light pink
|
||||
STR_5548 :Show all operating modes
|
||||
STR_5549 :年月日
|
||||
STR_5550 :{POP16}{POP16}第{COMMA16}年, {PUSH16}{PUSH16}{MONTH} {PUSH16}{PUSH16}{STRINGID}
|
||||
STR_5551 :Year/Day/Month
|
||||
STR_5552 :{POP16}{POP16}第{COMMA16}年, {PUSH16}{PUSH16}{PUSH16}{STRINGID} {MONTH}
|
||||
STR_5550 :{POP16}{POP16}{COMMA16}年 {PUSH16}{PUSH16}{MONTH} {PUSH16}{PUSH16}{STRINGID}
|
||||
STR_5551 :年日月
|
||||
STR_5552 :{POP16}{POP16}{COMMA16}年 {PUSH16}{PUSH16}{PUSH16}{STRINGID} {MONTH}
|
||||
STR_5553 :Pause game when Steam overlay is open
|
||||
STR_5554 :{SMALLFONT}{BLACK}Enable mountain tool
|
||||
STR_5555 :Show vehicles from other track types
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,98 @@
|
|||
# RollerCoaster Tycoon 1 Title Sequence
|
||||
|
||||
##############################
|
||||
# RollerCoaster Tycoon 1 #
|
||||
##############################
|
||||
# SC_DIAMOND_HEIGHTS
|
||||
LOADRCT1 3
|
||||
ROTATE 2
|
||||
LOCATION 47, 99
|
||||
WAIT 15
|
||||
ROTATE 2
|
||||
LOCATION 90, 48
|
||||
WAIT 15
|
||||
ROTATE 1
|
||||
LOCATION 86, 43
|
||||
WAIT 15
|
||||
ROTATE 3
|
||||
LOCATION 57, 50
|
||||
WAIT 15
|
||||
ROTATE 2
|
||||
LOCATION 86, 64
|
||||
WAIT 15
|
||||
|
||||
# SC_KATIES_DREAMLAND
|
||||
LOADRCT1 7
|
||||
LOCATION 48, 44
|
||||
WAIT 15
|
||||
LOCATION 64, 41
|
||||
WAIT 15
|
||||
|
||||
# SC_POKEY_PARK,
|
||||
LOADRCT1 8
|
||||
ROTATE 2
|
||||
LOCATION 56, 64
|
||||
WAIT 15
|
||||
|
||||
# SC_WHITE_WATER_PARK
|
||||
LOADRCT1 9
|
||||
ROTATE 3
|
||||
LOCATION 96, 88
|
||||
WAIT 15
|
||||
LOCATION 84, 95
|
||||
WAIT 15
|
||||
|
||||
# SC_MILLENNIUM_MINES
|
||||
LOADRCT1 10
|
||||
ROTATE 1
|
||||
ROTATE 1
|
||||
LOCATION 64, 37
|
||||
WAIT 15
|
||||
|
||||
# SC_KARTS_COASTERS
|
||||
LOADRCT1 11
|
||||
LOCATION 84, 56
|
||||
WAIT 15
|
||||
LOCATION 34, 36
|
||||
WAIT 15
|
||||
LOCATION 33, 65
|
||||
WAIT 15
|
||||
|
||||
# SC_MELS_WORLD
|
||||
LOADRCT1 12
|
||||
ROTATE 3
|
||||
LOCATION 50, 50
|
||||
WAIT 15
|
||||
LOCATION 35, 39
|
||||
WAIT 15
|
||||
ROTATE 3
|
||||
LOCATION 62, 39
|
||||
WAIT 15
|
||||
|
||||
# SC_CRUMBLY_WOODS
|
||||
LOADRCT1 15
|
||||
ROTATE 3
|
||||
LOCATION 57, 94
|
||||
WAIT 15
|
||||
LOCATION 44, 84
|
||||
WAIT 15
|
||||
ROTATE 1
|
||||
LOCATION 76, 59
|
||||
WAIT 15
|
||||
LOCATION 76, 48
|
||||
WAIT 15
|
||||
|
||||
# SC_LIGHTNING_PEAKS
|
||||
LOADRCT1 17
|
||||
LOCATION 80, 49
|
||||
WAIT 15
|
||||
LOCATION 60, 62
|
||||
WAIT 15
|
||||
|
||||
# SC_IVORY_TOWERS
|
||||
LOADRCT1 18
|
||||
ROTATE 3
|
||||
LOCATION 50, 77
|
||||
WAIT 15
|
||||
|
||||
RESTART
|
|
@ -0,0 +1,187 @@
|
|||
# RollerCoaster Tycoon 1 Title Sequence
|
||||
|
||||
##############################
|
||||
# Added Attractions #
|
||||
##############################
|
||||
# SC_HAUNTED_HARBOR
|
||||
LOADRCT1 45
|
||||
LOCATION 62, 53
|
||||
WAIT 11
|
||||
ROTATE 3
|
||||
LOCATION 78, 45
|
||||
WAIT 16
|
||||
|
||||
# SC_CANARY_MINES
|
||||
LOADRCT1 42
|
||||
LOCATION 52, 28
|
||||
WAIT 15
|
||||
|
||||
# SC_GENTLE_GLEN
|
||||
LOADRCT1 48
|
||||
LOCATION 68, 45
|
||||
WAIT 11
|
||||
|
||||
# SC_FUNTOPIA
|
||||
LOADRCT1 44
|
||||
LOCATION 69, 93
|
||||
WAIT 17
|
||||
|
||||
# SC_SPRIGHTLY_PARK
|
||||
LOADRCT1 51
|
||||
ROTATE 3
|
||||
LOCATION 97, 72
|
||||
WAIT 12
|
||||
ROTATE 2
|
||||
LOCATION 74, 71
|
||||
WAIT 12
|
||||
ROTATE 2
|
||||
LOCATION 67, 90
|
||||
WAIT 12
|
||||
|
||||
# SC_GIGGLE_DOWNS
|
||||
LOADRCT1 65
|
||||
LOCATION 94, 64
|
||||
WAIT 10
|
||||
|
||||
# SC_SWAMP_COVE
|
||||
LOADRCT1 59
|
||||
LOCATION 96, 22
|
||||
WAIT 10
|
||||
ROTATE 3
|
||||
LOCATION 90, 29
|
||||
WAIT 10
|
||||
|
||||
# SC_FRUIT_FARM
|
||||
LOADRCT1 53
|
||||
LOCATION 47, 52
|
||||
WAIT 12
|
||||
|
||||
# SC_FUTURE_WORLD
|
||||
LOADRCT1 47
|
||||
LOCATION 67, 59
|
||||
WAIT 19
|
||||
|
||||
# SC_THREE_MONKEYS_PARK
|
||||
LOADRCT1 41
|
||||
ROTATE 2
|
||||
LOCATION 72, 61
|
||||
WAIT 8
|
||||
ROTATE 2
|
||||
LOCATION 68, 70
|
||||
WAIT 8
|
||||
LOCATION 58, 56
|
||||
WAIT 8
|
||||
ROTATE 1
|
||||
LOCATION 44, 70
|
||||
WAIT 8
|
||||
ROTATE 3
|
||||
LOCATION 43, 90
|
||||
WAIT 10
|
||||
|
||||
# SC_ROMAN_VILLAGE
|
||||
LOADRCT1 58
|
||||
LOCATION 49, 46
|
||||
WAIT 15
|
||||
|
||||
# SC_ADRENALINE_HEIGHTS
|
||||
LOADRCT1 60
|
||||
ROTATE 3
|
||||
LOCATION 38, 57
|
||||
WAIT 15
|
||||
|
||||
##############################
|
||||
# RollerCoaster Tycoon 1 #
|
||||
##############################
|
||||
# SC_DIAMOND_HEIGHTS
|
||||
LOADRCT1 3
|
||||
ROTATE 2
|
||||
LOCATION 47, 99
|
||||
WAIT 15
|
||||
ROTATE 2
|
||||
LOCATION 90, 48
|
||||
WAIT 15
|
||||
ROTATE 1
|
||||
LOCATION 86, 43
|
||||
WAIT 15
|
||||
ROTATE 3
|
||||
LOCATION 57, 50
|
||||
WAIT 15
|
||||
ROTATE 2
|
||||
LOCATION 86, 64
|
||||
WAIT 15
|
||||
|
||||
# SC_KATIES_DREAMLAND
|
||||
LOADRCT1 7
|
||||
LOCATION 48, 44
|
||||
WAIT 15
|
||||
LOCATION 64, 41
|
||||
WAIT 15
|
||||
|
||||
# SC_POKEY_PARK,
|
||||
LOADRCT1 8
|
||||
ROTATE 2
|
||||
LOCATION 56, 64
|
||||
WAIT 15
|
||||
|
||||
# SC_WHITE_WATER_PARK
|
||||
LOADRCT1 9
|
||||
ROTATE 3
|
||||
LOCATION 96, 88
|
||||
WAIT 15
|
||||
LOCATION 84, 95
|
||||
WAIT 15
|
||||
|
||||
# SC_MILLENNIUM_MINES
|
||||
LOADRCT1 10
|
||||
ROTATE 1
|
||||
ROTATE 1
|
||||
LOCATION 64, 37
|
||||
WAIT 15
|
||||
|
||||
# SC_KARTS_COASTERS
|
||||
LOADRCT1 11
|
||||
LOCATION 84, 56
|
||||
WAIT 15
|
||||
LOCATION 34, 36
|
||||
WAIT 15
|
||||
LOCATION 33, 65
|
||||
WAIT 15
|
||||
|
||||
# SC_MELS_WORLD
|
||||
LOADRCT1 12
|
||||
ROTATE 3
|
||||
LOCATION 50, 50
|
||||
WAIT 15
|
||||
LOCATION 35, 39
|
||||
WAIT 15
|
||||
ROTATE 3
|
||||
LOCATION 62, 39
|
||||
WAIT 15
|
||||
|
||||
# SC_CRUMBLY_WOODS
|
||||
LOADRCT1 15
|
||||
ROTATE 3
|
||||
LOCATION 57, 94
|
||||
WAIT 15
|
||||
LOCATION 44, 84
|
||||
WAIT 15
|
||||
ROTATE 1
|
||||
LOCATION 76, 59
|
||||
WAIT 15
|
||||
LOCATION 76, 48
|
||||
WAIT 15
|
||||
|
||||
# SC_LIGHTNING_PEAKS
|
||||
LOADRCT1 17
|
||||
LOCATION 80, 49
|
||||
WAIT 15
|
||||
LOCATION 60, 62
|
||||
WAIT 15
|
||||
|
||||
# SC_IVORY_TOWERS
|
||||
LOADRCT1 18
|
||||
ROTATE 3
|
||||
LOCATION 50, 77
|
||||
WAIT 15
|
||||
|
||||
RESTART
|
|
@ -0,0 +1,233 @@
|
|||
# RollerCoaster Tycoon 1 Title Sequence
|
||||
|
||||
##############################
|
||||
# Added Attractions (part 1) #
|
||||
##############################
|
||||
# SC_HAUNTED_HARBOR
|
||||
LOADRCT1 45
|
||||
LOCATION 62, 53
|
||||
WAIT 11
|
||||
ROTATE 3
|
||||
LOCATION 78, 45
|
||||
WAIT 16
|
||||
|
||||
# SC_CANARY_MINES
|
||||
LOADRCT1 42
|
||||
LOCATION 52, 28
|
||||
WAIT 15
|
||||
|
||||
# SC_GENTLE_GLEN
|
||||
LOADRCT1 48
|
||||
LOCATION 68, 45
|
||||
WAIT 11
|
||||
|
||||
# SC_FUNTOPIA
|
||||
LOADRCT1 44
|
||||
LOCATION 69, 93
|
||||
WAIT 17
|
||||
|
||||
##############################
|
||||
# Loopy Landscapes #
|
||||
##############################
|
||||
# SC_FRIGHTMARE_HILLS
|
||||
LOADRCT1 86
|
||||
LOCATION 46, 47
|
||||
WAIT 5
|
||||
|
||||
# SC_GOOD_KNIGHT_PARK
|
||||
LOADRCT1 30
|
||||
ROTATE 2
|
||||
LOCATION 60, 62
|
||||
WAIT 5
|
||||
|
||||
# SC_ICEBERG_ISLANDS
|
||||
LOADRCT1 22
|
||||
ROTATE 3
|
||||
LOCATION 36, 52
|
||||
WAIT 4
|
||||
|
||||
# SC_SOUTHERN_SANDS
|
||||
LOADRCT1 91
|
||||
ROTATE 2
|
||||
LOCATION 51, 47
|
||||
WAIT 4
|
||||
|
||||
# SC_SUNNY_SWAMPS
|
||||
LOADRCT1 85
|
||||
ROTATE 3
|
||||
LOCATION 77, 82
|
||||
WAIT 4
|
||||
|
||||
# SC_VERTIGO_VIEWS
|
||||
LOADRCT1 27
|
||||
LOCATION 22, 56
|
||||
WAIT 3
|
||||
|
||||
# SC_WACKY_WARREN
|
||||
LOADRCT1 31
|
||||
ROTATE 3
|
||||
LOCATION 72, 80
|
||||
WAIT 4
|
||||
|
||||
##############################
|
||||
# Added Attractions (part 2) #
|
||||
##############################
|
||||
# SC_SPRIGHTLY_PARK
|
||||
LOADRCT1 51
|
||||
ROTATE 3
|
||||
LOCATION 97, 72
|
||||
WAIT 12
|
||||
ROTATE 2
|
||||
LOCATION 74, 71
|
||||
WAIT 12
|
||||
ROTATE 2
|
||||
LOCATION 67, 90
|
||||
WAIT 12
|
||||
|
||||
# SC_GIGGLE_DOWNS
|
||||
LOADRCT1 65
|
||||
LOCATION 94, 64
|
||||
WAIT 10
|
||||
|
||||
# SC_SWAMP_COVE
|
||||
LOADRCT1 59
|
||||
LOCATION 96, 22
|
||||
WAIT 10
|
||||
ROTATE 3
|
||||
LOCATION 90, 29
|
||||
WAIT 10
|
||||
|
||||
# SC_FRUIT_FARM
|
||||
LOADRCT1 53
|
||||
LOCATION 47, 52
|
||||
WAIT 12
|
||||
|
||||
# SC_FUTURE_WORLD
|
||||
LOADRCT1 47
|
||||
LOCATION 67, 59
|
||||
WAIT 19
|
||||
|
||||
# SC_THREE_MONKEYS_PARK
|
||||
LOADRCT1 41
|
||||
ROTATE 2
|
||||
LOCATION 72, 61
|
||||
WAIT 8
|
||||
ROTATE 2
|
||||
LOCATION 68, 70
|
||||
WAIT 8
|
||||
LOCATION 58, 56
|
||||
WAIT 8
|
||||
ROTATE 1
|
||||
LOCATION 44, 70
|
||||
WAIT 8
|
||||
ROTATE 3
|
||||
LOCATION 43, 90
|
||||
WAIT 10
|
||||
|
||||
# SC_ROMAN_VILLAGE
|
||||
LOADRCT1 58
|
||||
LOCATION 49, 46
|
||||
WAIT 15
|
||||
|
||||
# SC_ADRENALINE_HEIGHTS
|
||||
LOADRCT1 60
|
||||
ROTATE 3
|
||||
LOCATION 38, 57
|
||||
WAIT 15
|
||||
|
||||
##############################
|
||||
# RollerCoaster Tycoon 1 #
|
||||
##############################
|
||||
# SC_DIAMOND_HEIGHTS
|
||||
LOADRCT1 3
|
||||
ROTATE 2
|
||||
LOCATION 47, 99
|
||||
WAIT 15
|
||||
ROTATE 2
|
||||
LOCATION 90, 48
|
||||
WAIT 15
|
||||
ROTATE 1
|
||||
LOCATION 86, 43
|
||||
WAIT 15
|
||||
ROTATE 3
|
||||
LOCATION 57, 50
|
||||
WAIT 15
|
||||
ROTATE 2
|
||||
LOCATION 86, 64
|
||||
WAIT 15
|
||||
|
||||
# SC_KATIES_DREAMLAND
|
||||
LOADRCT1 7
|
||||
LOCATION 48, 44
|
||||
WAIT 15
|
||||
LOCATION 64, 41
|
||||
WAIT 15
|
||||
|
||||
# SC_POKEY_PARK,
|
||||
LOADRCT1 8
|
||||
ROTATE 2
|
||||
LOCATION 56, 64
|
||||
WAIT 15
|
||||
|
||||
# SC_WHITE_WATER_PARK
|
||||
LOADRCT1 9
|
||||
ROTATE 3
|
||||
LOCATION 96, 88
|
||||
WAIT 15
|
||||
LOCATION 84, 95
|
||||
WAIT 15
|
||||
|
||||
# SC_MILLENNIUM_MINES
|
||||
LOADRCT1 10
|
||||
ROTATE 1
|
||||
ROTATE 1
|
||||
LOCATION 64, 37
|
||||
WAIT 15
|
||||
|
||||
# SC_KARTS_COASTERS
|
||||
LOADRCT1 11
|
||||
LOCATION 84, 56
|
||||
WAIT 15
|
||||
LOCATION 34, 36
|
||||
WAIT 15
|
||||
LOCATION 33, 65
|
||||
WAIT 15
|
||||
|
||||
# SC_MELS_WORLD
|
||||
LOADRCT1 12
|
||||
ROTATE 3
|
||||
LOCATION 50, 50
|
||||
WAIT 15
|
||||
LOCATION 35, 39
|
||||
WAIT 15
|
||||
ROTATE 3
|
||||
LOCATION 62, 39
|
||||
WAIT 15
|
||||
|
||||
# SC_CRUMBLY_WOODS
|
||||
LOADRCT1 15
|
||||
ROTATE 3
|
||||
LOCATION 57, 94
|
||||
WAIT 15
|
||||
LOCATION 44, 84
|
||||
WAIT 15
|
||||
ROTATE 1
|
||||
LOCATION 76, 59
|
||||
WAIT 15
|
||||
LOCATION 76, 48
|
||||
WAIT 15
|
||||
|
||||
# SC_LIGHTNING_PEAKS
|
||||
LOADRCT1 17
|
||||
LOCATION 80, 49
|
||||
WAIT 15
|
||||
LOCATION 60, 62
|
||||
WAIT 15
|
||||
|
||||
# SC_IVORY_TOWERS
|
||||
LOADRCT1 18
|
||||
ROTATE 3
|
||||
LOCATION 50, 77
|
||||
WAIT 15
|
||||
|
||||
RESTART
|
|
@ -5,6 +5,8 @@
|
|||
- Feature: Add SI units as a new measurement system for distance / speed.
|
||||
- Feature: Update alternative font selection mechanism for all platforms.
|
||||
- Feature: Allow enabling / disabling of different notifications.
|
||||
- Feature: Improved tile inspector.
|
||||
- Feature: Integrate RCT1 style scenario select with optional unlock progression.
|
||||
- Fix: [#2126] Ferris Wheels set to "backward rotation" stop working (original bug)
|
||||
- Fix: [#2449] Turning off Day/Night Circle while it is night doesn't reset back to day
|
||||
|
||||
|
|
|
@ -120,7 +120,6 @@
|
|||
<ClCompile Include="test\ride\ride_ratings_test.c" />
|
||||
<ClCompile Include="test\tests.c" />
|
||||
<ClCompile Include="src\title.c" />
|
||||
<ClCompile Include="src\tutorial.c" />
|
||||
<ClCompile Include="src\util\sawyercoding.c" />
|
||||
<ClCompile Include="src\util\util.c" />
|
||||
<ClCompile Include="src\windows\about.c" />
|
||||
|
@ -266,13 +265,13 @@
|
|||
<ClInclude Include="src\ride\track_paint.h" />
|
||||
<ClInclude Include="src\ride\vehicle.h" />
|
||||
<ClInclude Include="src\scenario.h" />
|
||||
<ClCompile Include="src\scenario_sources.c" />
|
||||
<ClInclude Include="src\sprites.h" />
|
||||
<ClInclude Include="src\version.h" />
|
||||
<ClInclude Include="test\management\finance_test.h" />
|
||||
<ClInclude Include="test\ride\ride_ratings_test.h" />
|
||||
<ClInclude Include="test\tests.h" />
|
||||
<ClInclude Include="src\title.h" />
|
||||
<ClInclude Include="src\tutorial.h" />
|
||||
<ClInclude Include="src\util\sawyercoding.h" />
|
||||
<ClInclude Include="src\util\util.h" />
|
||||
<ClInclude Include="src\windows\dropdown.h" />
|
||||
|
|
|
@ -270,9 +270,6 @@
|
|||
<ClCompile Include="src\title.c">
|
||||
<Filter>Source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\tutorial.c">
|
||||
<Filter>Source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\localisation\date.c">
|
||||
<Filter>Source\Localisation</Filter>
|
||||
</ClCompile>
|
||||
|
@ -564,6 +561,9 @@
|
|||
<ClCompile Include="src\image_io.c">
|
||||
<Filter>Source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\scenario_sources.c">
|
||||
<Filter>Source</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\management\award.h">
|
||||
|
@ -692,9 +692,6 @@
|
|||
<ClInclude Include="src\title.h">
|
||||
<Filter>Source</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\tutorial.h">
|
||||
<Filter>Source</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\localisation\date.h">
|
||||
<Filter>Source\Localisation</Filter>
|
||||
</ClInclude>
|
||||
|
|
|
@ -15,7 +15,7 @@ fi
|
|||
# keep in sync with version in install.sh
|
||||
if [[ $(uname -s) == "Darwin" ]]; then
|
||||
# keep in sync with version in Xcode project
|
||||
sha256sum=02ebc8e7fd8b9b02b7144721784c5d96202a17398bc8652da163c8c85b66a7db
|
||||
sha256sum=6562ce9e1f37f125e3345bfd8b961777800436bf607b30dc7c964e0e6991ad2c
|
||||
else
|
||||
sha256sum=31c5e19d9f794bd5f0e75f20c2b4c3c4664d736b0a4d50c8cde14a9a9007b62d
|
||||
fi
|
||||
|
|
|
@ -63,6 +63,7 @@
|
|||
// are implemented in C. Sometimes memory locations are still used even if
|
||||
// they aren't directly referenced, for example when a game is saved and
|
||||
// loaded, large chunks of data is read and written to.
|
||||
#define RCT2_ADDRESS_SPRITE_ENTRIES 0x00982708
|
||||
|
||||
#define RCT2_ADDRESS_EASTEREGG_NAMES 0x00988C20
|
||||
|
||||
|
@ -191,7 +192,7 @@
|
|||
|
||||
#define RCT2_ADDRESS_TICKS_SINCE_DRAG_START 0x009DE540
|
||||
|
||||
#define RCT2_ADDRESS_PICKEDUP_PEEP_SPRITE 0x009DE550
|
||||
#define RCT2_ADDRESS_PICKEDUP_PEEP_IMAGE 0x009DE550
|
||||
#define RCT2_ADDRESS_PICKEDUP_PEEP_X 0x009DE554
|
||||
#define RCT2_ADDRESS_PICKEDUP_PEEP_Y 0x009DE556
|
||||
|
||||
|
|
36
src/config.c
36
src/config.c
|
@ -203,6 +203,10 @@ config_property_definition _generalDefinitions[] = {
|
|||
{ offsetof(general_configuration, show_fps), "show_fps", CONFIG_VALUE_TYPE_BOOLEAN, false, NULL },
|
||||
{ offsetof(general_configuration, trap_cursor), "trap_cursor", CONFIG_VALUE_TYPE_BOOLEAN, false, NULL },
|
||||
{ offsetof(general_configuration, auto_open_shops), "auto_open_shops", CONFIG_VALUE_TYPE_BOOLEAN, false, NULL },
|
||||
{ offsetof(general_configuration, scenario_select_mode), "scenario_select_mode", CONFIG_VALUE_TYPE_UINT8, SCENARIO_SELECT_MODE_ORIGIN, NULL },
|
||||
{ offsetof(general_configuration, scenario_unlocking_enabled), "scenario_unlocking_enabled", CONFIG_VALUE_TYPE_BOOLEAN, true, NULL },
|
||||
{ offsetof(general_configuration, scenario_hide_mega_park), "scenario_hide_mega_park", CONFIG_VALUE_TYPE_BOOLEAN, true, NULL },
|
||||
|
||||
};
|
||||
|
||||
config_property_definition _interfaceDefinitions[] = {
|
||||
|
@ -1404,11 +1408,23 @@ void title_sequences_set_default()
|
|||
|
||||
platform_get_openrct_data_path(dataPath);
|
||||
|
||||
// Load OpenRCT2 title sequence
|
||||
// RCT1 title sequence
|
||||
sprintf(path, "%s%c%s%c%s%c", dataPath, sep, "title", sep, "rct1", sep);
|
||||
title_sequence_open(path, language_get_string(5305));
|
||||
|
||||
// RCT1 (AA) title sequence
|
||||
sprintf(path, "%s%c%s%c%s%c", dataPath, sep, "title", sep, "rct1aa", sep);
|
||||
title_sequence_open(path, language_get_string(5306));
|
||||
|
||||
// RCT1 (AA + LL) title sequence
|
||||
sprintf(path, "%s%c%s%c%s%c", dataPath, sep, "title", sep, "rct1aall", sep);
|
||||
title_sequence_open(path, language_get_string(5307));
|
||||
|
||||
// RCT2 title sequence
|
||||
sprintf(path, "%s%c%s%c%s%c", dataPath, sep, "title", sep, "rct2", sep);
|
||||
title_sequence_open(path, language_get_string(5308));
|
||||
|
||||
// Load OpenRCT2 title sequence
|
||||
// OpenRCT2 title sequence
|
||||
sprintf(path, "%s%c%s%c%s%c", dataPath, sep, "title", sep, "openrct2", sep);
|
||||
title_sequence_open(path, language_get_string(5309));
|
||||
}
|
||||
|
@ -1429,12 +1445,21 @@ void title_sequences_load_presets()
|
|||
platform_enumerate_directories_end(dirEnumHandle);
|
||||
|
||||
// Check which title sequence is the current one
|
||||
if (_stricmp(gConfigInterface.current_title_sequence_preset, "*RCT2") == 0) {
|
||||
if (_stricmp(gConfigInterface.current_title_sequence_preset, "*RCT1") == 0) {
|
||||
gCurrentTitleSequence = 0;
|
||||
}
|
||||
else if (_stricmp(gConfigInterface.current_title_sequence_preset, "*OPENRCT2") == 0) {
|
||||
else if (_stricmp(gConfigInterface.current_title_sequence_preset, "*RCT1AA") == 0) {
|
||||
gCurrentTitleSequence = 1;
|
||||
}
|
||||
else if (_stricmp(gConfigInterface.current_title_sequence_preset, "*RCT1AALL") == 0) {
|
||||
gCurrentTitleSequence = 2;
|
||||
}
|
||||
else if (_stricmp(gConfigInterface.current_title_sequence_preset, "*RCT2") == 0) {
|
||||
gCurrentTitleSequence = 3;
|
||||
}
|
||||
else if (_stricmp(gConfigInterface.current_title_sequence_preset, "*OPENRCT2") == 0) {
|
||||
gCurrentTitleSequence = 4;
|
||||
}
|
||||
else {
|
||||
for (i = TITLE_SEQUENCE_DEFAULT_PRESETS; i < gConfigTitleSequences.num_presets; i++) {
|
||||
if (_stricmp(gConfigInterface.current_title_sequence_preset, gConfigTitleSequences.presets[i].name) == 0) {
|
||||
|
@ -1564,6 +1589,9 @@ static void title_sequence_open(const char *path, const char *customName)
|
|||
command.command = TITLE_SCRIPT_END;
|
||||
} else if (_stricmp(token, "LOADMM") == 0) {
|
||||
command.command = TITLE_SCRIPT_LOADMM;
|
||||
} else if (_stricmp(token, "LOADRCT1") == 0) {
|
||||
command.command = TITLE_SCRIPT_LOADRCT1;
|
||||
command.saveIndex = atoi(part1) & 0xFF;
|
||||
}
|
||||
}
|
||||
if (command.command != 0xFF) {
|
||||
|
|
|
@ -128,6 +128,11 @@ enum {
|
|||
SORT_DATE_DESCENDING,
|
||||
};
|
||||
|
||||
enum {
|
||||
SCENARIO_SELECT_MODE_DIFFICULTY,
|
||||
SCENARIO_SELECT_MODE_ORIGIN,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
uint8 play_intro;
|
||||
uint8 confirmation_prompt;
|
||||
|
@ -172,6 +177,9 @@ typedef struct {
|
|||
uint8 show_fps;
|
||||
uint8 trap_cursor;
|
||||
uint8 auto_open_shops;
|
||||
uint8 scenario_select_mode;
|
||||
uint8 scenario_unlocking_enabled;
|
||||
uint8 scenario_hide_mega_park;
|
||||
} general_configuration;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -485,7 +485,7 @@ void redraw_rain()
|
|||
void gfx_invalidate_pickedup_peep()
|
||||
{
|
||||
if (RCT2_GLOBAL(0x009ABDF2, uint32) != 0) {
|
||||
int sprite = RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_SPRITE, sint32);
|
||||
int sprite = RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_IMAGE, sint32);
|
||||
if (sprite != -1) {
|
||||
sprite = sprite & 0x7FFFF;
|
||||
|
||||
|
@ -506,10 +506,10 @@ void gfx_draw_pickedup_peep()
|
|||
return;
|
||||
|
||||
// Draw picked-up peep
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_SPRITE, uint32) != 0xFFFFFFFF) {
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_IMAGE, uint32) != 0xFFFFFFFF) {
|
||||
gfx_draw_sprite(
|
||||
(rct_drawpixelinfo*)RCT2_ADDRESS_SCREEN_DPI,
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_SPRITE, uint32),
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_IMAGE, uint32),
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_X, sint16),
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_Y, sint16), 0
|
||||
);
|
||||
|
|
|
@ -149,6 +149,7 @@ int string_get_height_raw(char *buffer);
|
|||
void gfx_draw_string_centred_wrapped_partial(rct_drawpixelinfo *dpi, int x, int y, int width, int colour, rct_string_id format, void *args, int ticks);
|
||||
void gfx_draw_string_with_y_offsets(rct_drawpixelinfo *dpi, const utf8 *text, int colour, int x, int y, const sint8 *yOffsets, bool forceSpriteFont);
|
||||
int gfx_clip_string(char* buffer, int width);
|
||||
void shorten_path(utf8 *buffer, size_t bufferSize, const utf8 *path, int availableWidth);
|
||||
|
||||
bool ttf_initialise();
|
||||
void ttf_dispose();
|
||||
|
|
|
@ -21,9 +21,10 @@
|
|||
#include "../addresses.h"
|
||||
#include "../interface/colour.h"
|
||||
#include "../localisation/localisation.h"
|
||||
#include "../sprites.h"
|
||||
#include "../world/map.h"
|
||||
#include "../platform/platform.h"
|
||||
#include "../sprites.h"
|
||||
#include "../util/util.h"
|
||||
#include "../world/map.h"
|
||||
#include "drawing.h"
|
||||
|
||||
static int ttf_get_string_width(const utf8 *text);
|
||||
|
@ -1355,3 +1356,40 @@ void gfx_draw_string_with_y_offsets(rct_drawpixelinfo *dpi, const utf8 *text, in
|
|||
gLastDrawStringX = info.x;
|
||||
gLastDrawStringY = info.y;
|
||||
}
|
||||
|
||||
void shorten_path(utf8 *buffer, size_t bufferSize, const utf8 *path, int availableWidth)
|
||||
{
|
||||
int length = strlen(path);
|
||||
|
||||
// Return full string if it fits
|
||||
if (gfx_get_string_width((char*)path) <= availableWidth) {
|
||||
safe_strncpy(buffer, path, bufferSize);
|
||||
return;
|
||||
}
|
||||
|
||||
// Count path separators
|
||||
int path_separators = 0;
|
||||
for (int x = 0; x < length; x++) {
|
||||
if (path[x] == platform_get_path_separator()) {
|
||||
path_separators++;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Replace with unicode ellipsis when supported
|
||||
safe_strncpy(buffer, "...", bufferSize);
|
||||
|
||||
// Abreviate beginning with xth separator
|
||||
int begin = -1;
|
||||
for (int x = 0; x < path_separators; x++){
|
||||
do {
|
||||
begin++;
|
||||
} while (path[begin] != platform_get_path_separator());
|
||||
|
||||
safe_strncpy(buffer + 3, path + begin, bufferSize - 3);
|
||||
if (gfx_get_string_width(buffer) <= availableWidth) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
safe_strncpy(buffer, path, bufferSize);
|
||||
}
|
||||
|
|
|
@ -138,7 +138,7 @@ void editor_convert_save_to_scenario_callback(int result)
|
|||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) = SCREEN_FLAGS_SCENARIO_EDITOR;
|
||||
s6Info->editor_step = EDITOR_STEP_OBJECTIVE_SELECTION;
|
||||
s6Info->category = SCENARIO_CATEGORY_BUILDYOUROWN;
|
||||
s6Info->category = SCENARIO_CATEGORY_OTHER;
|
||||
viewport_init_all();
|
||||
news_item_init_queue();
|
||||
window_editor_main_open();
|
||||
|
@ -328,7 +328,7 @@ static int editor_read_s6(const char *path)
|
|||
s6Info->editor_step = EDITOR_STEP_LANDSCAPE_EDITOR;
|
||||
} else {
|
||||
s6Info->editor_step = EDITOR_STEP_LANDSCAPE_EDITOR;
|
||||
s6Info->category = SCENARIO_CATEGORY_BUILDYOUROWN;
|
||||
s6Info->category = SCENARIO_CATEGORY_OTHER;
|
||||
format_string(s6Info->details, STR_NO_DETAILS_YET, NULL);
|
||||
}
|
||||
|
||||
|
|
111
src/game.c
111
src/game.c
|
@ -46,7 +46,6 @@
|
|||
#include "ride/track.h"
|
||||
#include "scenario.h"
|
||||
#include "title.h"
|
||||
#include "tutorial.h"
|
||||
#include "util/sawyercoding.h"
|
||||
#include "util/util.h"
|
||||
#include "windows/error.h"
|
||||
|
@ -57,6 +56,9 @@
|
|||
#include "world/scenery.h"
|
||||
#include "world/sprite.h"
|
||||
#include "world/water.h"
|
||||
#include <time.h>
|
||||
|
||||
#define NUMBER_OF_AUTOSAVES_TO_KEEP 9
|
||||
|
||||
int gGameSpeed = 1;
|
||||
float gDayNightCycle = 0;
|
||||
|
@ -288,11 +290,11 @@ void game_update()
|
|||
RCT2_GLOBAL(0x009E2D74, uint32) = 0;
|
||||
break;
|
||||
} else {
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) == INPUT_STATE_RESET ||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) == INPUT_STATE_NORMAL
|
||||
if (gInputState == INPUT_STATE_RESET ||
|
||||
gInputState == INPUT_STATE_NORMAL
|
||||
) {
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_VIEWPORT_SCROLLING) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) &= ~INPUT_FLAG_VIEWPORT_SCROLLING;
|
||||
if (gInputFlags & INPUT_FLAG_VIEWPORT_SCROLLING) {
|
||||
gInputFlags &= ~INPUT_FLAG_VIEWPORT_SCROLLING;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
|
@ -310,7 +312,7 @@ void game_update()
|
|||
|
||||
RCT2_GLOBAL(0x009A8C28, uint8) = 0;
|
||||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) &= ~INPUT_FLAG_VIEWPORT_SCROLLING;
|
||||
gInputFlags &= ~INPUT_FLAG_VIEWPORT_SCROLLING;
|
||||
|
||||
// the flickering frequency is reduced by 4, compared to the original
|
||||
// it was done due to inability to reproduce original frequency
|
||||
|
@ -770,10 +772,10 @@ int game_load_sv6(SDL_RWops* rw)
|
|||
|
||||
if (!load_success){
|
||||
set_load_objects_fail_reason();
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_5){
|
||||
if (gInputFlags & INPUT_FLAG_5){
|
||||
//call 0x0040705E Sets cursor position and something else. Calls maybe wind func 8 probably pointless
|
||||
RCT2_GLOBAL(0x14241BC, uint32) = 0;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) &= ~INPUT_FLAG_5;
|
||||
gInputFlags &= ~INPUT_FLAG_5;
|
||||
}
|
||||
|
||||
return 0;//This never gets called
|
||||
|
@ -864,10 +866,10 @@ int game_load_network(SDL_RWops* rw)
|
|||
|
||||
if (!load_success){
|
||||
set_load_objects_fail_reason();
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_5){
|
||||
if (gInputFlags & INPUT_FLAG_5){
|
||||
//call 0x0040705E Sets cursor position and something else. Calls maybe wind func 8 probably pointless
|
||||
RCT2_GLOBAL(0x14241BC, uint32) = 0;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) &= ~INPUT_FLAG_5;
|
||||
gInputFlags &= ~INPUT_FLAG_5;
|
||||
}
|
||||
|
||||
return 0;//This never gets called
|
||||
|
@ -1059,16 +1061,99 @@ void save_game_as()
|
|||
window_loadsave_open(LOADSAVETYPE_SAVE | LOADSAVETYPE_GAME, (char*)path_get_filename(gScenarioSavePath));
|
||||
}
|
||||
|
||||
int compare_autosave_file_paths (const void * a, const void * b ) {
|
||||
return strcmp(*(char **)a, *(char **)b);
|
||||
}
|
||||
|
||||
void limit_autosave_count(const size_t numberOfFilesToKeep)
|
||||
{
|
||||
int fileEnumHandle = 0;
|
||||
|
||||
size_t autosavesCount = 0;
|
||||
size_t numAutosavesToDelete = 0;
|
||||
|
||||
file_info fileInfo;
|
||||
|
||||
utf8 filter[MAX_PATH];
|
||||
|
||||
utf8 **autosaveFiles = NULL;
|
||||
|
||||
size_t i=0;
|
||||
|
||||
platform_get_user_directory(filter, "save");
|
||||
strncat(filter, "autosave_*.sv6", sizeof(filter) - strnlen(filter, MAX_PATH) - 1);
|
||||
|
||||
// At first, count how many autosaves there are
|
||||
fileEnumHandle = platform_enumerate_files_begin(filter);
|
||||
while (platform_enumerate_files_next(fileEnumHandle, &fileInfo)) {
|
||||
autosavesCount++;
|
||||
}
|
||||
platform_enumerate_files_end(fileEnumHandle);
|
||||
|
||||
// If there are fewer autosaves than the number of files to keep we don't need to delete anything
|
||||
if(autosavesCount <= numberOfFilesToKeep) {
|
||||
return;
|
||||
}
|
||||
|
||||
autosaveFiles = (utf8**) malloc(sizeof(utf8*) * autosavesCount);
|
||||
|
||||
fileEnumHandle = platform_enumerate_files_begin(filter);
|
||||
for(i = 0; i < autosavesCount; i++) {
|
||||
autosaveFiles[i] = (utf8*)malloc(sizeof(utf8) * MAX_PATH);
|
||||
memset(autosaveFiles[i], 0, sizeof(utf8) * MAX_PATH);
|
||||
|
||||
if(platform_enumerate_files_next(fileEnumHandle, &fileInfo)) {
|
||||
platform_get_user_directory(autosaveFiles[i], "save");
|
||||
strcat(autosaveFiles[i], fileInfo.path);
|
||||
}
|
||||
}
|
||||
platform_enumerate_files_end(fileEnumHandle);
|
||||
|
||||
qsort (autosaveFiles, autosavesCount, sizeof (char*), compare_autosave_file_paths);
|
||||
|
||||
// calculate how many saves we need to delete.
|
||||
numAutosavesToDelete = autosavesCount - numberOfFilesToKeep;
|
||||
|
||||
i=0;
|
||||
while (numAutosavesToDelete > 0) {
|
||||
platform_file_delete(autosaveFiles[i]);
|
||||
|
||||
i++;
|
||||
numAutosavesToDelete--;
|
||||
}
|
||||
|
||||
|
||||
for(i = 0; i < autosavesCount; i++) {
|
||||
free(autosaveFiles[i]);
|
||||
}
|
||||
|
||||
free(autosaveFiles);
|
||||
}
|
||||
|
||||
void game_autosave()
|
||||
{
|
||||
utf8 path[MAX_PATH];
|
||||
utf8 backupPath[MAX_PATH];
|
||||
utf8 timeString[21]="";
|
||||
|
||||
time_t rawtime;
|
||||
struct tm * timeinfo;
|
||||
|
||||
time ( &rawtime );
|
||||
timeinfo = localtime ( &rawtime );
|
||||
|
||||
limit_autosave_count(NUMBER_OF_AUTOSAVES_TO_KEEP);
|
||||
|
||||
snprintf(timeString, 20, "%d-%02d-%02d_%02d-%02d-%02d", 1900+timeinfo->tm_year, 1+timeinfo->tm_mon, timeinfo->tm_mday, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
|
||||
|
||||
|
||||
platform_get_user_directory(path, "save");
|
||||
safe_strncpy(backupPath, path, MAX_PATH);
|
||||
|
||||
strcat(path, "autosave.sv6");
|
||||
strcat(path, "autosave_");
|
||||
strcat(path, timeString);
|
||||
strcat(path, ".sv6");
|
||||
|
||||
strcat(backupPath, "autosave.sv6.bak");
|
||||
|
||||
if (platform_file_exists(path)) {
|
||||
|
@ -1129,8 +1214,8 @@ void game_load_or_quit_no_save_prompt()
|
|||
} else if (RCT2_GLOBAL(RCT2_ADDRESS_SAVE_PROMPT_MODE, uint16) == 1) {
|
||||
game_do_command(0, 1, 0, 1, GAME_COMMAND_LOAD_OR_QUIT, 0, 0);
|
||||
tool_cancel();
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_5) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) &= ~INPUT_FLAG_5;
|
||||
if (gInputFlags & INPUT_FLAG_5) {
|
||||
gInputFlags &= ~INPUT_FLAG_5;
|
||||
}
|
||||
gGameSpeed = 1;
|
||||
title_load();
|
||||
|
|
17
src/hook.c
17
src/hook.c
|
@ -30,6 +30,14 @@ void* g_hooktableaddress = 0;
|
|||
int g_hooktableoffset = 0;
|
||||
int g_maxhooks = 1000;
|
||||
|
||||
// This macro writes a little-endian 4-byte long value into *data
|
||||
// It is used to avoid type punning.
|
||||
#define write_address_strictalias(data, addr) \
|
||||
*(data + 0) = ((addr) & 0x000000ff) >> 0; \
|
||||
*(data + 1) = ((addr) & 0x0000ff00) >> 8; \
|
||||
*(data + 2) = ((addr) & 0x00ff0000) >> 16; \
|
||||
*(data + 3) = ((addr) & 0xff000000) >> 24;
|
||||
|
||||
void hookfunc(int address, int newaddress, int stacksize, int registerargs[], int registersreturned, int eaxDestinationRegister)
|
||||
{
|
||||
int i = 0;
|
||||
|
@ -118,7 +126,9 @@ void hookfunc(int address, int newaddress, int stacksize, int registerargs[], in
|
|||
}
|
||||
|
||||
data[i++] = 0xE8; // call
|
||||
*((int *)&data[i]) = (newaddress - address - i - 4); i += 4;
|
||||
|
||||
write_address_strictalias(&data[i], newaddress - address - i - 4);
|
||||
i += 4;
|
||||
|
||||
// returnlocation:
|
||||
|
||||
|
@ -220,7 +230,10 @@ void addhook(int address, int newaddress, int stacksize, int registerargs[], int
|
|||
char data[9];
|
||||
int i = 0;
|
||||
data[i++] = 0xE9; // jmp
|
||||
*((int *)&data[i]) = hookaddress - address - i - 4; i += 4;
|
||||
|
||||
write_address_strictalias(&data[i], hookaddress - address - i - 4);
|
||||
i += 4;
|
||||
|
||||
data[i++] = 0xC3; // retn
|
||||
#ifdef _WIN32
|
||||
WriteProcessMemory(GetCurrentProcess(), (LPVOID)address, data, i, 0);
|
||||
|
|
280
src/input.c
280
src/input.c
|
@ -35,7 +35,6 @@
|
|||
#include "platform/platform.h"
|
||||
#include "ride/ride_data.h"
|
||||
#include "scenario.h"
|
||||
#include "tutorial.h"
|
||||
#include "windows/tooltip.h"
|
||||
#include "windows/dropdown.h"
|
||||
#include "world/banner.h"
|
||||
|
@ -44,11 +43,21 @@
|
|||
#include "world/scenery.h"
|
||||
#include "openrct2.h"
|
||||
|
||||
static int _dragX, _dragY;
|
||||
static rct_windowclass _dragWindowClass;
|
||||
static rct_windownumber _dragWindowNumber;
|
||||
static int _dragWidgetIndex, _dragScrollIndex;
|
||||
static int _originalWindowWidth, _originalWindowHeight;
|
||||
static sint32 _dragX;
|
||||
static sint32 _dragY;
|
||||
static widget_ref _dragWidget;
|
||||
static uint8 _dragScrollIndex;
|
||||
static sint32 _originalWindowWidth;
|
||||
static sint32 _originalWindowHeight;
|
||||
|
||||
uint8 gInputState;
|
||||
uint8 gInputFlags;
|
||||
|
||||
uint16 gTooltipNotShownTicks;
|
||||
uint16 gTooltipTimeout;
|
||||
widget_ref gTooltipWidget;
|
||||
sint32 gTooltipCursorX;
|
||||
sint32 gTooltipCursorY;
|
||||
|
||||
typedef struct {
|
||||
uint32 x, y;
|
||||
|
@ -92,7 +101,6 @@ static void input_scroll_part_update_vthumb(rct_window *w, int widgetIndex, int
|
|||
static void input_scroll_part_update_vtop(rct_window *w, int widgetIndex, int scroll_id);
|
||||
static void input_scroll_part_update_vbottom(rct_window *w, int widgetIndex, int scroll_id);
|
||||
static void input_update_tooltip(rct_window *w, int widgetIndex, int x, int y);
|
||||
static void update_cursor_position();
|
||||
|
||||
#pragma region Mouse input
|
||||
|
||||
|
@ -115,7 +123,6 @@ void game_handle_input()
|
|||
window_event_unknown_07_call(w);
|
||||
|
||||
sub_6EA73F();
|
||||
update_cursor_position();
|
||||
|
||||
for (;;) {
|
||||
game_get_next_input(&x, &y, &state);
|
||||
|
@ -125,7 +132,7 @@ void game_handle_input()
|
|||
game_handle_input_mouse(x, y, state & 0xFF);
|
||||
}
|
||||
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_5) {
|
||||
if (gInputFlags & INPUT_FLAG_5) {
|
||||
game_handle_input_mouse(x, y, state);
|
||||
}
|
||||
else if (x != 0x80000000) {
|
||||
|
@ -159,8 +166,6 @@ static void game_get_next_input(int *x, int *y, int *state)
|
|||
*x = eax->x;
|
||||
*y = eax->y;
|
||||
*state = eax->state;
|
||||
|
||||
// NOTE this function lacks tutorial logic
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -184,12 +189,12 @@ static rct_mouse_data* get_mouse_input()
|
|||
* rct2: 0x006E957F
|
||||
*/
|
||||
static void input_scroll_drag_begin(int x, int y, rct_window* w, rct_widget* widget, int widgetIndex) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = INPUT_STATE_SCROLL_RIGHT;
|
||||
gInputState = INPUT_STATE_SCROLL_RIGHT;
|
||||
_dragX = x;
|
||||
_dragY = y;
|
||||
_dragWindowClass = w->classification;
|
||||
_dragWindowNumber = w->number;
|
||||
_dragWidgetIndex = widgetIndex;
|
||||
_dragWidget.window_classification = w->classification;
|
||||
_dragWidget.window_number = w->number;
|
||||
_dragWidget.widget_index = widgetIndex;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TICKS_SINCE_DRAG_START, sint16) = 0;
|
||||
|
||||
_dragScrollIndex = window_get_scroll_data_index(w, widgetIndex);
|
||||
|
@ -200,8 +205,9 @@ static void input_scroll_drag_begin(int x, int y, rct_window* w, rct_widget* wid
|
|||
* Based on (heavily changed)
|
||||
* rct2: 0x006E9E0E, 0x006E9ED0
|
||||
*/
|
||||
static void input_scroll_drag_continue(int x, int y, rct_window* w) {
|
||||
uint8 widgetIndex = _dragWidgetIndex;
|
||||
static void input_scroll_drag_continue(int x, int y, rct_window* w)
|
||||
{
|
||||
uint8 widgetIndex = _dragWidget.widget_index;
|
||||
uint8 scrollIndex = _dragScrollIndex;
|
||||
|
||||
rct_widget* widget = &w->widgets[widgetIndex];
|
||||
|
@ -238,13 +244,13 @@ static void input_scroll_drag_continue(int x, int y, rct_window* w) {
|
|||
*/
|
||||
static void input_scroll_right(int x, int y, int state) {
|
||||
rct_window* w = window_find_by_number(
|
||||
_dragWindowClass,
|
||||
_dragWindowNumber
|
||||
);
|
||||
_dragWidget.window_classification,
|
||||
_dragWidget.window_number
|
||||
);
|
||||
|
||||
if (w == NULL) {
|
||||
platform_show_cursor();
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = INPUT_STATE_RESET;
|
||||
gInputState = INPUT_STATE_RESET;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -258,7 +264,7 @@ static void input_scroll_right(int x, int y, int state) {
|
|||
input_scroll_drag_continue(x, y, w);
|
||||
break;
|
||||
case 4:
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = INPUT_STATE_RESET;
|
||||
gInputState = INPUT_STATE_RESET;
|
||||
platform_show_cursor();
|
||||
break;
|
||||
}
|
||||
|
@ -279,7 +285,7 @@ static void game_handle_input_mouse(int x, int y, int state)
|
|||
widgetIndex = w == NULL ? -1 : window_find_widget_from_point(w, x, y);
|
||||
widget = widgetIndex == -1 ? 0 : &w->widgets[widgetIndex];
|
||||
|
||||
switch (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8)) {
|
||||
switch (gInputState) {
|
||||
case INPUT_STATE_RESET:
|
||||
window_tooltip_reset(x, y);
|
||||
// fall-through
|
||||
|
@ -315,9 +321,9 @@ static void game_handle_input_mouse(int x, int y, int state)
|
|||
input_state_widget_pressed(x, y, state, widgetIndex, w, widget);
|
||||
break;
|
||||
case INPUT_STATE_POSITIONING_WINDOW:
|
||||
w = window_find_by_number(_dragWindowClass, _dragWindowNumber);
|
||||
w = window_find_by_number(_dragWidget.window_classification, _dragWidget.window_number);
|
||||
if (w == NULL) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = INPUT_STATE_RESET;
|
||||
gInputState = INPUT_STATE_RESET;
|
||||
}
|
||||
else {
|
||||
input_window_position_continue(w, _dragX, _dragY, x, y);
|
||||
|
@ -346,19 +352,19 @@ static void game_handle_input_mouse(int x, int y, int state)
|
|||
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_WINDOWNUMBER, rct_windownumber)
|
||||
);
|
||||
if (!w){
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = 0;
|
||||
gInputState = INPUT_STATE_RESET;
|
||||
break;
|
||||
}
|
||||
|
||||
if (state == 0){
|
||||
if (!w->viewport){
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = 0;
|
||||
gInputState = INPUT_STATE_RESET;
|
||||
break;
|
||||
}
|
||||
|
||||
if (w->classification != RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_WINDOWCLASS, rct_windowclass) ||
|
||||
w->number != RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_WINDOWNUMBER, rct_windownumber) ||
|
||||
!(RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE)) break;
|
||||
!(gInputFlags & INPUT_FLAG_TOOL_ACTIVE)) break;
|
||||
|
||||
w = window_find_by_number(
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass),
|
||||
|
@ -371,9 +377,9 @@ static void game_handle_input_mouse(int x, int y, int state)
|
|||
}
|
||||
else if (state == 2){
|
||||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = 0;
|
||||
gInputState = INPUT_STATE_RESET;
|
||||
if (RCT2_GLOBAL(0x9DE52E, rct_windownumber) != w->number)break;
|
||||
if ((RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE)){
|
||||
if ((gInputFlags & INPUT_FLAG_TOOL_ACTIVE)){
|
||||
w = window_find_by_number(
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass),
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber)
|
||||
|
@ -383,7 +389,7 @@ static void game_handle_input_mouse(int x, int y, int state)
|
|||
window_event_tool_up_call(w, RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16), x, y);
|
||||
}
|
||||
else{
|
||||
if ((RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_4))
|
||||
if ((gInputFlags & INPUT_FLAG_4))
|
||||
break;
|
||||
|
||||
viewport_interaction_left_click(x, y);
|
||||
|
@ -397,9 +403,9 @@ static void game_handle_input_mouse(int x, int y, int state)
|
|||
input_scroll_end();
|
||||
break;
|
||||
case INPUT_STATE_RESIZING:
|
||||
w = window_find_by_number(_dragWindowClass, _dragWindowNumber);
|
||||
w = window_find_by_number(_dragWidget.window_classification, _dragWidget.window_number);
|
||||
if (w == NULL) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = INPUT_STATE_RESET;
|
||||
gInputState = INPUT_STATE_RESET;
|
||||
}
|
||||
else {
|
||||
if (state == 2)
|
||||
|
@ -419,12 +425,12 @@ static void game_handle_input_mouse(int x, int y, int state)
|
|||
|
||||
void input_window_position_begin(rct_window *w, int widgetIndex, int x, int y)
|
||||
{
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = INPUT_STATE_POSITIONING_WINDOW;
|
||||
gInputState = INPUT_STATE_POSITIONING_WINDOW;
|
||||
_dragX = x - w->x;
|
||||
_dragY = y - w->y;
|
||||
_dragWindowClass = w->classification;
|
||||
_dragWindowNumber = w->number;
|
||||
_dragWidgetIndex = widgetIndex;
|
||||
_dragWidget.window_classification = w->classification;
|
||||
_dragWidget.window_number = w->number;
|
||||
_dragWidget.widget_index = widgetIndex;
|
||||
}
|
||||
|
||||
static void input_window_position_continue(rct_window *w, int wdx, int wdy, int x, int y)
|
||||
|
@ -437,22 +443,20 @@ static void input_window_position_continue(rct_window *w, int wdx, int wdy, int
|
|||
|
||||
static void input_window_position_end(rct_window *w, int x, int y)
|
||||
{
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = INPUT_STATE_NORMAL;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_TIMEOUT, uint8) = 0;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_WINDOW_CLASS, rct_windowclass) = _dragWindowClass;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_WINDOW_NUMBER, rct_windownumber) = _dragWindowNumber;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_WIDGET_INDEX, uint16) = _dragWidgetIndex;
|
||||
gInputState = INPUT_STATE_NORMAL;
|
||||
gTooltipTimeout = 0;
|
||||
gTooltipWidget = _dragWidget;
|
||||
window_event_moved_call(w, x, y);
|
||||
}
|
||||
|
||||
static void input_window_resize_begin(rct_window *w, int widgetIndex, int x, int y)
|
||||
{
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = INPUT_STATE_RESIZING;
|
||||
gInputState = INPUT_STATE_RESIZING;
|
||||
_dragX = x;
|
||||
_dragY = y;
|
||||
_dragWindowClass = w->classification;
|
||||
_dragWindowNumber = w->number;
|
||||
_dragWidgetIndex = widgetIndex;
|
||||
_dragWidget.window_classification = w->classification;
|
||||
_dragWidget.window_number = w->number;
|
||||
_dragWidget.widget_index = widgetIndex;
|
||||
_originalWindowWidth = w->width;
|
||||
_originalWindowHeight = w->height;
|
||||
}
|
||||
|
@ -477,11 +481,9 @@ static void input_window_resize_continue(rct_window *w, int x, int y)
|
|||
|
||||
static void input_window_resize_end()
|
||||
{
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = INPUT_STATE_NORMAL;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_TIMEOUT, uint8) = 0;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_WINDOW_CLASS, rct_windowclass) = _dragWindowClass;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_WINDOW_NUMBER, rct_windownumber) = _dragWindowNumber;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_WIDGET_INDEX, uint16) = _dragWidgetIndex;
|
||||
gInputState = INPUT_STATE_NORMAL;
|
||||
gTooltipTimeout = 0;
|
||||
gTooltipWidget = _dragWidget;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
@ -491,14 +493,14 @@ static void input_window_resize_end()
|
|||
static void input_viewport_drag_begin(rct_window *w, int x, int y)
|
||||
{
|
||||
w->flags &= ~WF_SCROLLING_TO_LOCATION;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = INPUT_STATE_VIEWPORT_RIGHT;
|
||||
_dragWindowClass = w->classification;
|
||||
_dragWindowNumber = w->number;
|
||||
gInputState = INPUT_STATE_VIEWPORT_RIGHT;
|
||||
_dragWidget.window_classification = w->classification;
|
||||
_dragWidget.window_number = w->number;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TICKS_SINCE_DRAG_START, sint16) = 0;
|
||||
platform_get_cursor_position(&_dragX, &_dragY);
|
||||
platform_hide_cursor();
|
||||
|
||||
// RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_5;
|
||||
// gInputFlags |= INPUT_FLAG_5;
|
||||
}
|
||||
|
||||
static void input_viewport_drag_continue()
|
||||
|
@ -511,14 +513,14 @@ static void input_viewport_drag_continue()
|
|||
|
||||
dx = newDragX - _dragX;
|
||||
dy = newDragY - _dragY;
|
||||
w = window_find_by_number(_dragWindowClass, _dragWindowNumber);
|
||||
w = window_find_by_number(_dragWidget.window_classification, _dragWidget.window_number);
|
||||
assert(w != NULL);
|
||||
|
||||
viewport = w->viewport;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TICKS_SINCE_DRAG_START, sint16) += RCT2_GLOBAL(RCT2_ADDRESS_TICKS_SINCE_LAST_UPDATE, sint16);
|
||||
if (viewport == NULL) {
|
||||
platform_show_cursor();
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = INPUT_STATE_RESET;
|
||||
gInputState = INPUT_STATE_RESET;
|
||||
} else if (dx != 0 || dy != 0) {
|
||||
if (!(w->flags & WF_NO_SCROLLING)) {
|
||||
// User dragged a scrollable viewport
|
||||
|
@ -544,7 +546,7 @@ static void input_viewport_drag_continue()
|
|||
|
||||
static void input_viewport_drag_end()
|
||||
{
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = INPUT_STATE_RESET;
|
||||
gInputState = INPUT_STATE_RESET;
|
||||
platform_show_cursor();
|
||||
}
|
||||
|
||||
|
@ -558,12 +560,12 @@ static void input_scroll_begin(rct_window *w, int widgetIndex, int x, int y)
|
|||
|
||||
widget = &w->widgets[widgetIndex];
|
||||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = INPUT_STATE_SCROLL_LEFT;
|
||||
gInputState = INPUT_STATE_SCROLL_LEFT;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WIDGETINDEX, uint16) = widgetIndex;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWCLASS, rct_windowclass) = w->classification;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWNUMBER, rct_windownumber) = w->number;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_CURSOR_X, uint16) = x;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_CURSOR_Y, uint16) = y;
|
||||
gTooltipCursorX = x;
|
||||
gTooltipCursorY = y;
|
||||
|
||||
int eax, ebx, scroll_area, scroll_id;
|
||||
scroll_id = 0; // safety
|
||||
|
@ -647,9 +649,7 @@ static void input_scroll_continue(rct_window *w, int widgetIndex, int state, int
|
|||
widget_scroll_get_part(w, widget, x, y, &x2, &y2, &scroll_part, &scroll_id);
|
||||
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SCROLL_AREA, uint16) == SCROLL_PART_HSCROLLBAR_THUMB){
|
||||
int temp_x = x;
|
||||
x -= RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_CURSOR_X, uint16);
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_CURSOR_X, uint16) = temp_x;
|
||||
gTooltipCursorX = x - gTooltipCursorX;
|
||||
input_scroll_part_update_hthumb(w, widgetIndex, x, scroll_id);
|
||||
return;
|
||||
}
|
||||
|
@ -702,7 +702,7 @@ static void input_scroll_continue(rct_window *w, int widgetIndex, int state, int
|
|||
|
||||
static void input_scroll_end()
|
||||
{
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = INPUT_STATE_RESET;
|
||||
gInputState = INPUT_STATE_RESET;
|
||||
invalidate_scroll();
|
||||
}
|
||||
|
||||
|
@ -904,9 +904,9 @@ static void input_widget_over(int x, int y, rct_window *w, int widgetIndex)
|
|||
input_update_tooltip(w, widgetIndex, x, y);
|
||||
}
|
||||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_TIMEOUT, uint16) = 0;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_CURSOR_X, sint16) = x;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_CURSOR_Y, sint16) = y;
|
||||
gTooltipTimeout = 0;
|
||||
gTooltipCursorX = x;
|
||||
gTooltipCursorY = y;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1004,19 +1004,19 @@ static void input_widget_left(int x, int y, rct_window *w, int widgetIndex)
|
|||
input_window_resize_begin(w, widgetIndex, x, y);
|
||||
break;
|
||||
case WWT_VIEWPORT:
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = INPUT_STATE_VIEWPORT_LEFT;
|
||||
gInputState = INPUT_STATE_VIEWPORT_LEFT;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_LAST_X, uint16) = x;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_LAST_Y, uint16) = y;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_WINDOWCLASS, rct_windowclass) = windowClass;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_WINDOWNUMBER, rct_windownumber) = windowNumber;
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE) {
|
||||
if (gInputFlags & INPUT_FLAG_TOOL_ACTIVE) {
|
||||
w = window_find_by_number(
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass),
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber)
|
||||
);
|
||||
if (w != NULL) {
|
||||
window_event_tool_down_call(w, RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16), x, y);
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_4;
|
||||
gInputFlags |= INPUT_FLAG_4;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -1034,8 +1034,8 @@ static void input_widget_left(int x, int y, rct_window *w, int widgetIndex)
|
|||
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWCLASS, rct_windowclass) = windowClass;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWNUMBER, rct_windownumber) = windowNumber;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WIDGETINDEX, uint16) = widgetIndex;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_WIDGET_PRESSED;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = INPUT_STATE_WIDGET_PRESSED;
|
||||
gInputFlags |= INPUT_FLAG_WIDGET_PRESSED;
|
||||
gInputState = INPUT_STATE_WIDGET_PRESSED;
|
||||
RCT2_GLOBAL(0x009DE528, uint16) = 1;
|
||||
|
||||
widget_invalidate_by_number(windowClass, windowNumber, widgetIndex);
|
||||
|
@ -1071,7 +1071,7 @@ void process_mouse_over(int x, int y)
|
|||
switch (window->widgets[widgetId].type){
|
||||
|
||||
case WWT_VIEWPORT:
|
||||
if ((RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, int) & INPUT_FLAG_TOOL_ACTIVE) == 0) {
|
||||
if (!(gInputFlags & INPUT_FLAG_TOOL_ACTIVE)) {
|
||||
if (viewport_interaction_left_over(x, y)) {
|
||||
sub_6ED990(CURSOR_HAND_POINT);
|
||||
return;
|
||||
|
@ -1153,7 +1153,7 @@ void process_mouse_over(int x, int y)
|
|||
*/
|
||||
void process_mouse_tool(int x, int y)
|
||||
{
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE)
|
||||
if (gInputFlags & INPUT_FLAG_TOOL_ACTIVE)
|
||||
{
|
||||
rct_window* w = window_find_by_number(
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass),
|
||||
|
@ -1185,7 +1185,7 @@ void input_state_widget_pressed(int x, int y, int state, int widgetIndex, rct_wi
|
|||
|
||||
rct_window *cursor_w = window_find_by_number(cursor_w_class, cursor_w_number);
|
||||
if (cursor_w == NULL) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = 0;
|
||||
gInputState = INPUT_STATE_RESET;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1207,14 +1207,14 @@ void input_state_widget_pressed(int x, int y, int state, int widgetIndex, rct_wi
|
|||
window_event_mouse_down_call(w, widgetIndex);
|
||||
}
|
||||
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_WIDGET_PRESSED) return;
|
||||
if (gInputFlags & INPUT_FLAG_WIDGET_PRESSED) return;
|
||||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_WIDGET_PRESSED;
|
||||
gInputFlags |= INPUT_FLAG_WIDGET_PRESSED;
|
||||
widget_invalidate_by_number(cursor_w_class, cursor_w_number, widgetIndex);
|
||||
return;
|
||||
case 3:
|
||||
case 2:
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) == 5) {
|
||||
if (gInputState == INPUT_STATE_DROPDOWN_ACTIVE) {
|
||||
if (w) {
|
||||
int dropdown_index = 0;
|
||||
|
||||
|
@ -1236,9 +1236,9 @@ void input_state_widget_pressed(int x, int y, int state, int widgetIndex, rct_wi
|
|||
if (cursor_w_class != w->classification || cursor_w_number != w->number || widgetIndex != cursor_widgetIndex)
|
||||
goto dropdown_cleanup;
|
||||
dropdown_index = -1;
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_DROPDOWN_STAY_OPEN){
|
||||
if (!(RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_DROPDOWN_MOUSE_UP)){
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_DROPDOWN_MOUSE_UP;
|
||||
if (gInputFlags & INPUT_FLAG_DROPDOWN_STAY_OPEN){
|
||||
if (!(gInputFlags & INPUT_FLAG_DROPDOWN_MOUSE_UP)){
|
||||
gInputFlags |= INPUT_FLAG_DROPDOWN_MOUSE_UP;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1246,16 +1246,16 @@ void input_state_widget_pressed(int x, int y, int state, int widgetIndex, rct_wi
|
|||
|
||||
window_close_by_class(WC_DROPDOWN);
|
||||
cursor_w = window_find_by_number(cursor_w_class, cursor_w_number);
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_WIDGET_PRESSED) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) &= 0xFFFE;
|
||||
if (gInputFlags & INPUT_FLAG_WIDGET_PRESSED) {
|
||||
gInputFlags &= ~INPUT_FLAG_WIDGET_PRESSED;
|
||||
widget_invalidate_by_number(cursor_w_class, cursor_w_number, cursor_widgetIndex);
|
||||
}
|
||||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = 1;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_TIMEOUT, uint16) = 0;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_WIDGET_INDEX, uint16) = cursor_widgetIndex;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_WINDOW_CLASS, rct_windowclass) = cursor_w_class;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_WINDOW_NUMBER, rct_windownumber) = cursor_w_number;
|
||||
gInputState = INPUT_STATE_NORMAL;
|
||||
gTooltipTimeout = 0;
|
||||
gTooltipWidget.widget_index = cursor_widgetIndex;
|
||||
gTooltipWidget.window_classification = cursor_w_class;
|
||||
gTooltipWidget.window_number = cursor_w_number;
|
||||
window_event_dropdown_call(cursor_w, cursor_widgetIndex, dropdown_index);
|
||||
}
|
||||
dropdown_cleanup:
|
||||
|
@ -1263,9 +1263,9 @@ void input_state_widget_pressed(int x, int y, int state, int widgetIndex, rct_wi
|
|||
}
|
||||
if (state == 3) return;
|
||||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = 1;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_TIMEOUT, uint16) = 0;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_WIDGET_INDEX, uint16) = cursor_widgetIndex;
|
||||
gInputState = INPUT_STATE_NORMAL;
|
||||
gTooltipTimeout = 0;
|
||||
gTooltipWidget.widget_index = cursor_widgetIndex;
|
||||
|
||||
if (!w)
|
||||
break;
|
||||
|
@ -1288,10 +1288,10 @@ void input_state_widget_pressed(int x, int y, int state, int widgetIndex, rct_wi
|
|||
}
|
||||
|
||||
RCT2_GLOBAL(0x9DE528, uint16) = 0;
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) != 5){
|
||||
if (gInputState != INPUT_STATE_DROPDOWN_ACTIVE){
|
||||
// Hold down widget and drag outside of area??
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_WIDGET_PRESSED){
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) &= 0xFFFE;
|
||||
if (gInputFlags & INPUT_FLAG_WIDGET_PRESSED){
|
||||
gInputFlags &= ~INPUT_FLAG_WIDGET_PRESSED;
|
||||
widget_invalidate_by_number(cursor_w_class, cursor_w_number, cursor_widgetIndex);
|
||||
}
|
||||
return;
|
||||
|
@ -1328,36 +1328,34 @@ void input_state_widget_pressed(int x, int y, int state, int widgetIndex, rct_wi
|
|||
|
||||
static void input_update_tooltip(rct_window *w, int widgetIndex, int x, int y)
|
||||
{
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_WINDOW_CLASS, rct_windowclass) == 255) {
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_NOT_SHOWN_TICKS, uint16) < 500 ||
|
||||
(RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_CURSOR_X, sint16) == x &&
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_CURSOR_Y, sint16) == y)
|
||||
) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_TIMEOUT, uint16) = RCT2_GLOBAL(RCT2_ADDRESS_TICKS_SINCE_LAST_UPDATE, uint16);
|
||||
if (gTooltipWidget.window_classification == 255) {
|
||||
if (gTooltipNotShownTicks < 500 || (gTooltipCursorX == x && gTooltipCursorY == y)) {
|
||||
gTooltipTimeout = RCT2_GLOBAL(RCT2_ADDRESS_TICKS_SINCE_LAST_UPDATE, uint16);
|
||||
|
||||
int bp = 2000;
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_NOT_SHOWN_TICKS, uint16) >= 1)
|
||||
bp = 0;
|
||||
if (bp > RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_TIMEOUT, uint16)) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_NOT_SHOWN_TICKS, sint16)++;
|
||||
int time = 2000;
|
||||
if (gTooltipNotShownTicks >= 1) {
|
||||
time = 0;
|
||||
}
|
||||
if (time > gTooltipTimeout) {
|
||||
gTooltipNotShownTicks++;
|
||||
return;
|
||||
}
|
||||
|
||||
window_tooltip_open(w, widgetIndex, x, y);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (((w != NULL) &&
|
||||
(RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_WINDOW_CLASS, rct_windowclass) != w->classification ||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_WINDOW_NUMBER, rct_windownumber) != w->number)) ||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_WIDGET_INDEX, uint16) != widgetIndex
|
||||
) {
|
||||
} else {
|
||||
if ((
|
||||
(w != NULL) &&
|
||||
(gTooltipWidget.window_classification != w->classification || gTooltipWidget.window_number != w->number)
|
||||
) ||
|
||||
gTooltipWidget.widget_index != widgetIndex
|
||||
) {
|
||||
window_tooltip_close();
|
||||
}
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_TIMEOUT, uint16) += RCT2_GLOBAL(RCT2_ADDRESS_TICKS_SINCE_LAST_UPDATE, uint16);
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_TIMEOUT, uint16) < 8000)
|
||||
return;
|
||||
window_close_by_class(WC_TOOLTIP);
|
||||
gTooltipTimeout += RCT2_GLOBAL(RCT2_ADDRESS_TICKS_SINCE_LAST_UPDATE, uint16);
|
||||
if (gTooltipTimeout >= 8000) {
|
||||
window_close_by_class(WC_TOOLTIP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1432,11 +1430,10 @@ void game_handle_keyboard_input()
|
|||
|
||||
if (!gConsoleOpen) {
|
||||
// Handle mouse scrolling
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_ON_TUTORIAL, uint8) == 0)
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_EDGE_SCROLLING, uint8) != 0)
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) == 1)
|
||||
if (!(RCT2_GLOBAL(RCT2_ADDRESS_PLACE_OBJECT_MODIFIER, uint8) & 3))
|
||||
game_handle_edge_scroll();
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_EDGE_SCROLLING, uint8) != 0)
|
||||
if (gInputState == INPUT_STATE_NORMAL)
|
||||
if (!(RCT2_GLOBAL(RCT2_ADDRESS_PLACE_OBJECT_MODIFIER, uint8) & 3))
|
||||
game_handle_edge_scroll();
|
||||
|
||||
// Handle modifier keys and key scrolling
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PLACE_OBJECT_MODIFIER, uint8) = 0;
|
||||
|
@ -1447,8 +1444,7 @@ void game_handle_keyboard_input()
|
|||
RCT2_GLOBAL(RCT2_ADDRESS_PLACE_OBJECT_MODIFIER, uint8) |= 2;
|
||||
if (gKeysState[SDL_SCANCODE_LALT] || gKeysState[SDL_SCANCODE_RALT])
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PLACE_OBJECT_MODIFIER, uint8) |= 4;
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_ON_TUTORIAL, uint8) == 0)
|
||||
game_handle_key_scroll();
|
||||
game_handle_key_scroll();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1478,8 +1474,6 @@ void game_handle_keyboard_input()
|
|||
w = window_find_by_class(WC_CHANGE_KEYBOARD_SHORTCUT);
|
||||
if (w != NULL) {
|
||||
keyboard_shortcut_set(key);
|
||||
} else if (RCT2_GLOBAL(RCT2_ADDRESS_ON_TUTORIAL, uint8) == 1) {
|
||||
tutorial_stop();
|
||||
} else {
|
||||
w = window_find_by_class(WC_TEXTINPUT);
|
||||
if (w != NULL) {
|
||||
|
@ -1489,10 +1483,6 @@ void game_handle_keyboard_input()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_ON_TUTORIAL, uint8) != 0) {
|
||||
game_handle_keyboard_input_for_tutorial();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1519,7 +1509,7 @@ int get_next_key()
|
|||
* rct2: 0x006ED990
|
||||
*/
|
||||
void sub_6ED990(char cursor_id){
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) == INPUT_STATE_RESIZING)
|
||||
if (gInputState == INPUT_STATE_RESIZING)
|
||||
{
|
||||
cursor_id = CURSOR_DIAGONAL_ARROWS; //resize icon
|
||||
}
|
||||
|
@ -1613,11 +1603,11 @@ void game_handle_edge_scroll()
|
|||
// Scroll viewport
|
||||
if (scrollX != 0) {
|
||||
mainWindow->saved_view_x += scrollX * (12 << mainWindow->viewport->zoom);
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_VIEWPORT_SCROLLING;
|
||||
gInputFlags |= INPUT_FLAG_VIEWPORT_SCROLLING;
|
||||
}
|
||||
if (scrollY != 0) {
|
||||
mainWindow->saved_view_y += scrollY * (12 << mainWindow->viewport->zoom);
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_VIEWPORT_SCROLLING;
|
||||
gInputFlags |= INPUT_FLAG_VIEWPORT_SCROLLING;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1682,30 +1672,10 @@ void game_handle_key_scroll()
|
|||
// Scroll viewport
|
||||
if (scrollX != 0) {
|
||||
mainWindow->saved_view_x += scrollX * (12 << mainWindow->viewport->zoom);
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_VIEWPORT_SCROLLING;
|
||||
gInputFlags |= INPUT_FLAG_VIEWPORT_SCROLLING;
|
||||
}
|
||||
if (scrollY != 0) {
|
||||
mainWindow->saved_view_y += scrollY * (12 << mainWindow->viewport->zoom);
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_VIEWPORT_SCROLLING;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006E8346
|
||||
*/
|
||||
static void update_cursor_position()
|
||||
{
|
||||
switch (RCT2_GLOBAL(RCT2_ADDRESS_ON_TUTORIAL, uint8)) {
|
||||
case 0:
|
||||
// RCT2_GLOBAL(0x0142004C, sint32) = RCT2_GLOBAL(0x0142406C, sint32);
|
||||
// RCT2_GLOBAL(0x01420050, sint32) = RCT2_GLOBAL(0x01424070, sint32);
|
||||
break;
|
||||
case 1:
|
||||
// read tutorial cursor position
|
||||
break;
|
||||
case 2:
|
||||
// write tutorial cursor position
|
||||
break;
|
||||
gInputFlags |= INPUT_FLAG_VIEWPORT_SCROLLING;
|
||||
}
|
||||
}
|
||||
|
|
29
src/input.h
29
src/input.h
|
@ -23,6 +23,19 @@
|
|||
|
||||
#include "interface/window.h"
|
||||
|
||||
enum {
|
||||
INPUT_STATE_RESET,
|
||||
INPUT_STATE_NORMAL,
|
||||
INPUT_STATE_WIDGET_PRESSED,
|
||||
INPUT_STATE_POSITIONING_WINDOW,
|
||||
INPUT_STATE_VIEWPORT_RIGHT,
|
||||
INPUT_STATE_DROPDOWN_ACTIVE,
|
||||
INPUT_STATE_VIEWPORT_LEFT,
|
||||
INPUT_STATE_SCROLL_LEFT,
|
||||
INPUT_STATE_RESIZING,
|
||||
INPUT_STATE_SCROLL_RIGHT
|
||||
};
|
||||
|
||||
enum {
|
||||
INPUT_FLAG_WIDGET_PRESSED = (1 << 0),
|
||||
|
||||
|
@ -47,10 +60,24 @@ enum {
|
|||
INPUT_FLAG_VIEWPORT_SCROLLING = (1 << 7)
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
rct_windowclass window_classification;
|
||||
rct_windownumber window_number;
|
||||
uint8 widget_index;
|
||||
} widget_ref;
|
||||
|
||||
extern uint8 gInputState;
|
||||
extern uint8 gInputFlags;
|
||||
|
||||
extern uint16 gTooltipNotShownTicks;
|
||||
extern uint16 gTooltipTimeout;
|
||||
extern widget_ref gTooltipWidget;
|
||||
extern sint32 gTooltipCursorX;
|
||||
extern sint32 gTooltipCursorY;
|
||||
|
||||
void title_handle_keyboard_input();
|
||||
void game_handle_input();
|
||||
void game_handle_keyboard_input();
|
||||
void game_handle_keyboard_input_for_tutorial();
|
||||
|
||||
void store_mouse_input(int state);
|
||||
|
||||
|
|
|
@ -136,7 +136,7 @@ static void shortcut_cancel_construction_mode()
|
|||
window = window_find_by_class(WC_ERROR);
|
||||
if (window != NULL)
|
||||
window_close(window);
|
||||
else if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE)
|
||||
else if (gInputFlags & INPUT_FLAG_TOOL_ACTIVE)
|
||||
tool_cancel();
|
||||
}
|
||||
|
||||
|
@ -472,12 +472,14 @@ static void shortcut_screenshot()
|
|||
|
||||
static void shortcut_reduce_game_speed()
|
||||
{
|
||||
game_reduce_game_speed();
|
||||
if (network_get_mode() == NETWORK_MODE_NONE)
|
||||
game_reduce_game_speed();
|
||||
}
|
||||
|
||||
static void shortcut_increase_game_speed()
|
||||
{
|
||||
game_increase_game_speed();
|
||||
if (network_get_mode() == NETWORK_MODE_NONE)
|
||||
game_increase_game_speed();
|
||||
}
|
||||
|
||||
static void shortcut_open_cheat_window()
|
||||
|
|
|
@ -63,9 +63,18 @@ void title_sequence_change_preset(int preset)
|
|||
if (preset >= 0 && preset < gConfigTitleSequences.num_presets) {
|
||||
switch (preset) {
|
||||
case 0:
|
||||
gConfigInterface.current_title_sequence_preset = "*RCT2";
|
||||
gConfigInterface.current_title_sequence_preset = "*RCT1";
|
||||
break;
|
||||
case 1:
|
||||
gConfigInterface.current_title_sequence_preset = "*RCT1AA";
|
||||
break;
|
||||
case 2:
|
||||
gConfigInterface.current_title_sequence_preset = "*RCT1AALL";
|
||||
break;
|
||||
case 3:
|
||||
gConfigInterface.current_title_sequence_preset = "*RCT2";
|
||||
break;
|
||||
case 4:
|
||||
gConfigInterface.current_title_sequence_preset = "*OPENRCT2";
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "../config.h"
|
||||
#include "../drawing/drawing.h"
|
||||
#include "../drawing/supports.h"
|
||||
#include "../input.h"
|
||||
#include "../localisation/localisation.h"
|
||||
#include "../ride/ride_data.h"
|
||||
#include "../ride/track_data.h"
|
||||
|
@ -101,11 +102,11 @@ void viewport_init_all()
|
|||
RCT2_GLOBAL(RCT2_ADDRESS_ACTIVE_VIEWPORT_PTR_ARRAY, rct_viewport*) = NULL;
|
||||
|
||||
// ?
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) = 0;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, sint8) = INPUT_STATE_RESET;
|
||||
gInputFlags = 0;
|
||||
gInputState = INPUT_STATE_RESET;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWCLASS, rct_windowclass) = -1;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_SPRITE, sint32) = -1;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_NOT_SHOWN_TICKS, sint16) = -1;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_IMAGE, sint32) = -1;
|
||||
gTooltipNotShownTicks = -1;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, sint16) = 0;
|
||||
RCT2_GLOBAL(0x009DEA50, sint16) = -1;
|
||||
textinput_cancel();
|
||||
|
|
|
@ -272,7 +272,7 @@ int viewport_interaction_get_item_right(int x, int y, viewport_interaction_info
|
|||
return info->type;
|
||||
}
|
||||
|
||||
if ((RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & (INPUT_FLAG_6 | INPUT_FLAG_TOOL_ACTIVE)) != (INPUT_FLAG_6 | INPUT_FLAG_TOOL_ACTIVE))
|
||||
if ((gInputFlags & INPUT_FLAG_6) && (gInputFlags & INPUT_FLAG_TOOL_ACTIVE))
|
||||
if (window_find_by_class(WC_RIDE_CONSTRUCTION) == NULL && window_find_by_class(WC_FOOTPATH) == NULL)
|
||||
return info->type = VIEWPORT_INTERACTION_ITEM_NONE;
|
||||
|
||||
|
@ -291,7 +291,7 @@ int viewport_interaction_get_item_right(int x, int y, viewport_interaction_info
|
|||
return info->type;
|
||||
|
||||
case VIEWPORT_INTERACTION_ITEM_FOOTPATH_ITEM:
|
||||
sceneryEntry = g_pathBitSceneryEntries[(mapElement->properties.path.additions & 0x0F) - 1];
|
||||
sceneryEntry = g_pathBitSceneryEntries[footpath_element_get_path_scenery_index(mapElement)];
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 0, uint16) = 1164;
|
||||
if (mapElement->flags & 0x20) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 2, uint16) = 3124;
|
||||
|
|
|
@ -978,7 +978,7 @@ int widget_is_disabled(rct_window *w, int widgetIndex)
|
|||
|
||||
int widget_is_pressed(rct_window *w, int widgetIndex)
|
||||
{
|
||||
int inputState = RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8);
|
||||
int inputState = gInputState;
|
||||
|
||||
if (w->pressed_widgets & (1LL << widgetIndex))
|
||||
return 1;
|
||||
|
@ -987,7 +987,7 @@ int widget_is_pressed(rct_window *w, int widgetIndex)
|
|||
return 0;
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWNUMBER, rct_windownumber) != w->number)
|
||||
return 0;
|
||||
if (!(RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_WIDGET_PRESSED))
|
||||
if (!(gInputFlags & INPUT_FLAG_WIDGET_PRESSED))
|
||||
return 0;
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WIDGETINDEX, sint32) == widgetIndex)
|
||||
return 1;
|
||||
|
@ -1008,7 +1008,7 @@ int widget_is_highlighted(rct_window *w, int widgetIndex)
|
|||
|
||||
int widget_is_active_tool(rct_window *w, int widgetIndex)
|
||||
{
|
||||
if (!(RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE))
|
||||
if (!(gInputFlags & INPUT_FLAG_TOOL_ACTIVE))
|
||||
return 0;
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) != w->classification)
|
||||
return 0;
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
|
||||
rct_window* g_window_list = RCT2_ADDRESS(RCT2_ADDRESS_WINDOW_LIST, rct_window);
|
||||
|
||||
uint8 TextInputDescriptionArgs[8];
|
||||
uint16 TextInputDescriptionArgs[4];
|
||||
widget_identifier gCurrentTextBox = { { 255, 0 }, 0 };
|
||||
char gTextBoxInput[512] = { 0 };
|
||||
int gMaxTextBoxInputLength = 0;
|
||||
|
@ -150,7 +150,7 @@ void window_dispatch_update_all()
|
|||
rct_window *w;
|
||||
|
||||
RCT2_GLOBAL(0x01423604, sint32)++;
|
||||
//RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_NOT_SHOWN_TICKS, sint16)++;
|
||||
// gTooltipNotShownTicks++;
|
||||
for (w = RCT2_LAST_WINDOW; w >= g_window_list; w--)
|
||||
window_event_update_call(w);
|
||||
}
|
||||
|
@ -306,7 +306,7 @@ static void window_all_wheel_input()
|
|||
return;
|
||||
|
||||
// Check window cursor is over
|
||||
if (!(RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_5)) {
|
||||
if (!(gInputFlags & INPUT_FLAG_5)) {
|
||||
w = window_find_from_point(gCursorState.x, gCursorState.y);
|
||||
if (w != NULL) {
|
||||
// Check if main window
|
||||
|
@ -1727,7 +1727,7 @@ void window_set_resize(rct_window *w, int minWidth, int minHeight, int maxWidth,
|
|||
*/
|
||||
int tool_set(rct_window *w, int widgetIndex, int tool)
|
||||
{
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE) {
|
||||
if (gInputFlags & INPUT_FLAG_TOOL_ACTIVE) {
|
||||
if (
|
||||
w->classification == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) &&
|
||||
w->number == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber) &&
|
||||
|
@ -1740,8 +1740,8 @@ int tool_set(rct_window *w, int widgetIndex, int tool)
|
|||
}
|
||||
}
|
||||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_TOOL_ACTIVE;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) &= ~INPUT_FLAG_6;
|
||||
gInputFlags |= INPUT_FLAG_TOOL_ACTIVE;
|
||||
gInputFlags &= ~INPUT_FLAG_6;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TOOL, uint8) = tool;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) = w->classification;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber) = w->number;
|
||||
|
@ -1757,8 +1757,8 @@ void tool_cancel()
|
|||
{
|
||||
rct_window *w;
|
||||
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) &= ~INPUT_FLAG_TOOL_ACTIVE;
|
||||
if (gInputFlags & INPUT_FLAG_TOOL_ACTIVE) {
|
||||
gInputFlags &= ~INPUT_FLAG_TOOL_ACTIVE;
|
||||
|
||||
map_invalidate_selection_rect();
|
||||
map_invalidate_map_selection_tiles();
|
||||
|
|
|
@ -27,11 +27,13 @@
|
|||
#include "../ride/ride.h"
|
||||
#include "../ride/vehicle.h"
|
||||
#include "../world/park.h"
|
||||
#include "../management/research.h"
|
||||
#include "../scenario.h"
|
||||
#include "colour.h"
|
||||
|
||||
struct rct_window;
|
||||
union rct_window_event;
|
||||
extern uint8 TextInputDescriptionArgs[8];
|
||||
extern uint16 TextInputDescriptionArgs[4];
|
||||
extern char gTextBoxInput[512];
|
||||
extern int gMaxTextBoxInputLength;
|
||||
extern int gTextBoxFrameNo;
|
||||
|
@ -260,11 +262,23 @@ typedef struct rct_window {
|
|||
error_variables error;
|
||||
};
|
||||
sint16 page; // 0x48A
|
||||
sint16 var_48C;
|
||||
union {
|
||||
sint16 picked_peep_old_x; // 0x48C staff/guest window: peep x gets set to 0x8000 on pickup, this is the old value
|
||||
sint16 var_48C;
|
||||
};
|
||||
uint16 frame_no; // 0x48E updated every tic for motion in windows sprites
|
||||
uint16 list_information_type; // 0x490 0 for none, Used as current position of marquee in window_peep
|
||||
sint16 var_492;
|
||||
uint32 highlighted_item; // 0x494
|
||||
union {
|
||||
sint16 picked_peep_frame; // 0x492 Animation frame of picked peep in staff window and guest window
|
||||
sint16 var_492;
|
||||
};
|
||||
union { // 0x494
|
||||
uint32 highlighted_item;
|
||||
uint16 ride_colour;
|
||||
rct_research_item* research_item;
|
||||
rct_object_entry* object_entry;
|
||||
scenario_index_entry* highlighted_scenario;
|
||||
};
|
||||
uint8 var_498[0x14];
|
||||
sint16 selected_tab; // 0x4AC
|
||||
sint16 var_4AE;
|
||||
|
@ -372,19 +386,6 @@ enum {
|
|||
SCROLL_PART_VSCROLLBAR_THUMB = 10,
|
||||
};
|
||||
|
||||
enum {
|
||||
INPUT_STATE_RESET = 0,
|
||||
INPUT_STATE_NORMAL = 1,
|
||||
INPUT_STATE_WIDGET_PRESSED = 2,
|
||||
INPUT_STATE_POSITIONING_WINDOW = 3,
|
||||
INPUT_STATE_VIEWPORT_RIGHT = 4,
|
||||
INPUT_STATE_DROPDOWN_ACTIVE = 5,
|
||||
INPUT_STATE_VIEWPORT_LEFT = 6,
|
||||
INPUT_STATE_SCROLL_LEFT = 7,
|
||||
INPUT_STATE_RESIZING = 8,
|
||||
INPUT_STATE_SCROLL_RIGHT = 9
|
||||
};
|
||||
|
||||
enum {
|
||||
WC_MAIN_WINDOW = 0,
|
||||
WC_TOP_TOOLBAR = 1,
|
||||
|
|
|
@ -47,6 +47,13 @@ enum {
|
|||
RCT2_LANGUAGE_ID_END = 255
|
||||
};
|
||||
|
||||
static TTFFontSetDescriptor TTFFontMSGothic = {{
|
||||
{ "msgothic_02.ttf", "MS PGothic", 9, 1, 0, 15, nullptr },
|
||||
{ "msgothic_02.ttf", "MS PGothic", 12, 1, 0, 17, nullptr },
|
||||
{ "msgothic_02.ttf", "MS PGothic", 12, 1, 0, 17, nullptr },
|
||||
{ "msgothic_02.ttf", "MS PGothic", 13, 1, 0, 20, nullptr },
|
||||
}};
|
||||
|
||||
static TTFFontSetDescriptor TTFFontMingLiu = {{
|
||||
{ "msjh.ttc", "JhengHei", 9, -1, -3, 6, nullptr },
|
||||
{ "mingliu.ttc", "MingLiU", 11, 1, 1, 12, nullptr },
|
||||
|
@ -94,6 +101,7 @@ const language_descriptor LanguagesDescriptors[LANGUAGE_COUNT] = {
|
|||
{ "ko", "Korean", "Korean", "korean", &TTFFontGulim, RCT2_LANGUAGE_ID_KOREAN }, // LANGUAGE_KOREAN
|
||||
{ "ru-RU", "Russian", "Russian", "russian", &TTFFontArial, RCT2_LANGUAGE_ID_ENGLISH_UK }, // LANGUAGE_RUSSIAN
|
||||
{ "cz-CZ", "Czech", "Czech", "czech", &TTFFontArial, RCT2_LANGUAGE_ID_ENGLISH_UK }, // LANGUAGE_CZECH
|
||||
{ "jp-JP", "Japanese", "Japanese", "japanese", &TTFFontMSGothic, RCT2_LANGUAGE_ID_ENGLISH_UK }, // LANGUAGE_JAPANESE
|
||||
};
|
||||
|
||||
int gCurrentLanguage = LANGUAGE_UNDEFINED;
|
||||
|
|
|
@ -43,6 +43,7 @@ enum {
|
|||
LANGUAGE_KOREAN,
|
||||
LANGUAGE_RUSSIAN,
|
||||
LANGUAGE_CZECH,
|
||||
LANGUAGE_JAPANESE,
|
||||
LANGUAGE_COUNT
|
||||
};
|
||||
|
||||
|
|
|
@ -1527,8 +1527,6 @@ enum {
|
|||
STR_ENTRANCE_NOT_CONNECTED = 2854,
|
||||
STR_EXIT_NOT_CONNECTED = 2855,
|
||||
|
||||
STR_TUTORIAL = 2856,
|
||||
STR_PRESS_KEY_OR_MOUSE_BUTTON_FOR_CONTROL = 2857,
|
||||
STR_CANT_START_MARKETING_CAMPAIGN = 2858,
|
||||
|
||||
STR_INFOGRAMES_INTERACTIVE_CREDITS = 2860,
|
||||
|
@ -1878,10 +1876,6 @@ enum {
|
|||
STR_INSTALL_NEW_TRACK_DESIGN = 3376,
|
||||
STR_INSTALL_NEW_TRACK_DESIGN_TIP = 3377,
|
||||
|
||||
STR_TUTORIAL_BEGINNERS = 3385,
|
||||
STR_TUTORIAL_CUSTOM_RIDES = 3386,
|
||||
STR_TUTORIAL_ROLLER_COASTER = 3387,
|
||||
|
||||
STR_SAVE_TRACK_SCENERY_UNABLE_TO_SELECT_ADDITIONAL_ITEM_OF_SCENERY = 3389,
|
||||
STR_SAVE_TRACK_SCENERY_TOO_MANY_ITEMS_SELECTED = 3390,
|
||||
|
||||
|
@ -2004,9 +1998,17 @@ enum {
|
|||
STR_TILE_INSPECTOR_ENTRANCE_START = 5335,
|
||||
STR_TILE_INSPECTOR_ELEMENT_TYPE = 5338,
|
||||
STR_TILE_INSPECTOR_BASE_HEIGHT = 5339,
|
||||
STR_TILE_INSPECTOR_CLEARANGE_HEIGHT = 5340,
|
||||
STR_TILE_INSPECTOR_BASE_HEIGHT_SHORT = 5608,
|
||||
STR_TILE_INSPECTOR_CLEARANCE_HEIGHT = 5340,
|
||||
STR_TILE_INSPECTOR_CLEARANGE_HEIGHT_SHORT = 5609,
|
||||
STR_TILE_INSPECTOR_FLAGS = 5341,
|
||||
STR_TILE_INSPECTOR_CHOOSE_MSG = 5342,
|
||||
STR_TILE_INSPECTOR_FLAG_GHOST_SHORT = 5611,
|
||||
STR_TILE_INSPECTOR_FLAG_GHOST = 5612,
|
||||
STR_TILE_INSPECTOR_FLAG_BROKEN_SHORT = 5613,
|
||||
STR_TILE_INSPECTOR_FLAG_BROKEN = 5614,
|
||||
STR_TILE_INSPECTOR_FLAG_LAST_SHORT = 5615,
|
||||
STR_TILE_INSPECTOR_FLAG_LAST = 5616,
|
||||
|
||||
STR_AUTO_STAFF_PLACEMENT = 5343,
|
||||
|
||||
|
@ -2232,6 +2234,23 @@ enum {
|
|||
STR_NOTIFICATION_GUEST_USED_FACILITY = 5605,
|
||||
STR_NOTIFICATION_GUEST_DIED = 5606,
|
||||
|
||||
STR_SCENARIO_CATEGORY_RCT1 = 5619,
|
||||
STR_SCENARIO_CATEGORY_RCT1_AA = 5620,
|
||||
STR_SCENARIO_CATEGORY_RCT1_LL = 5621,
|
||||
STR_SCENARIO_CATEGORY_RCT2 = 5622,
|
||||
STR_SCENARIO_CATEGORY_RCT2_WW = 5623,
|
||||
STR_SCENARIO_CATEGORY_RCT2_TT = 5624,
|
||||
STR_SCENARIO_CATEGORY_REAL_PARKS = 5625,
|
||||
STR_SCENARIO_CATEGORY_OTHER_PARKS = 5626,
|
||||
|
||||
STR_OPTIONS_SCENARIO_GROUPING = 5627,
|
||||
STR_OPTIONS_SCENARIO_ORIGIN = 5628,
|
||||
STR_OPTIONS_SCENARIO_DIFFICULTY = 5629,
|
||||
STR_OPTIONS_SCENARIO_UNLOCKING = 5630,
|
||||
|
||||
STR_DLC_PARKS = 5631,
|
||||
STR_BUILD_YOUR_OWN_PARKS = 5632,
|
||||
|
||||
// Have to include resource strings (from scenarios and objects) for the time being now that language is partially working
|
||||
STR_COUNT = 32768
|
||||
};
|
||||
|
|
|
@ -155,6 +155,13 @@ void game_command_start_campaign(int* eax, int* ebx, int* ecx, int* edx, int* es
|
|||
int rideOrItem = (*edx >> 8) & 0xFF;
|
||||
int numWeeks = (*ebx >> 8) & 0xFF;
|
||||
|
||||
if (type < 0 || type >= countof(AdvertisingCampaignPricePerWeek))
|
||||
{
|
||||
log_warning("Invalid game command, type = %d", type);
|
||||
*ebx = MONEY32_UNDEFINED;
|
||||
return;
|
||||
}
|
||||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_NEXT_EXPENDITURE_TYPE, uint8) = RCT_EXPENDITURE_TYPE_MARKETING * 4;
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_FORBID_MARKETING_CAMPAIGN) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = 3048;
|
||||
|
|
|
@ -379,7 +379,7 @@ void news_item_open_subject(int type, int subject)
|
|||
if (window != NULL) {
|
||||
window_invalidate(window);
|
||||
if (!tool_set(window, 9, 0)) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_6;
|
||||
gInputFlags |= INPUT_FLAG_6;
|
||||
window_scenery_open();
|
||||
}
|
||||
}
|
||||
|
|
10
src/object.c
10
src/object.c
|
@ -358,17 +358,15 @@ int object_entry_compare(const rct_object_entry *a, const rct_object_entry *b)
|
|||
if (a->flags & 0xF0) {
|
||||
if ((a->flags & 0x0F) != (b->flags & 0x0F))
|
||||
return 0;
|
||||
if (*((uint32*)a->name) != *((uint32*)b->name))
|
||||
return 0;
|
||||
if (*((uint32*)(&a->name[4])) != *((uint32*)(&b->name[4])))
|
||||
int match = memcmp(a->name, b->name, 8);
|
||||
if (match)
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
if (a->flags != b->flags)
|
||||
return 0;
|
||||
if (*((uint32*)a->name) != *((uint32*)b->name))
|
||||
return 0;
|
||||
if (*((uint32*)(&a->name[4])) != *((uint32*)(&b->name[4])))
|
||||
int match = memcmp(a->name, b->name, 8);
|
||||
if (match)
|
||||
return 0;
|
||||
if (a->checksum != b->checksum)
|
||||
return 0;
|
||||
|
|
|
@ -203,7 +203,7 @@ bool openrct2_initialise()
|
|||
gOpenRCT2ShowChangelog = true;
|
||||
if (gConfigGeneral.last_run_version != NULL && (strcmp(gConfigGeneral.last_run_version, OPENRCT2_VERSION) == 0))
|
||||
gOpenRCT2ShowChangelog = false;
|
||||
gConfigGeneral.last_run_version = OPENRCT2_VERSION;
|
||||
gConfigGeneral.last_run_version = strndup(OPENRCT2_VERSION, strlen(OPENRCT2_VERSION));
|
||||
config_save_default();
|
||||
|
||||
// TODO add configuration option to allow multiple instances
|
||||
|
|
185
src/peep/peep.c
185
src/peep/peep.c
|
@ -200,11 +200,11 @@ static uint8 peep_assess_surroundings(sint16 center_x, sint16 center_y, sint16 c
|
|||
|
||||
switch (map_element_get_type(mapElement)){
|
||||
case MAP_ELEMENT_TYPE_PATH:
|
||||
if ((mapElement->properties.path.additions & 0xF) == 0)
|
||||
if (!footpath_element_has_path_scenery(mapElement))
|
||||
break;
|
||||
|
||||
scenery = g_pathBitSceneryEntries[(mapElement->properties.path.additions & 0x0F) - 1];
|
||||
if (mapElement->properties.path.additions & (1 << 7))
|
||||
scenery = g_pathBitSceneryEntries[footpath_element_get_path_scenery_index(mapElement)];
|
||||
if (footpath_element_path_scenery_is_ghost(mapElement))
|
||||
break;
|
||||
|
||||
if (scenery->path_bit.var_06 &
|
||||
|
@ -620,9 +620,10 @@ static void sub_68F41A(rct_peep *peep, int index)
|
|||
if (mapElement->base_height != peep->next_z)
|
||||
continue;
|
||||
|
||||
uint8 additions = mapElement->properties.path.additions & 0xF;
|
||||
if (additions != 0 && mapElement->properties.path.additions & (1 << 7)){
|
||||
rct_scenery_entry *sceneryEntry = g_pathBitSceneryEntries[additions - 1];
|
||||
// Check if the footpath has ghost path scenery on it
|
||||
if (footpath_element_has_path_scenery(mapElement) && footpath_element_path_scenery_is_ghost(mapElement)){
|
||||
uint8 pathSceneryIndex = footpath_element_get_path_scenery_index(mapElement);
|
||||
rct_scenery_entry *sceneryEntry = g_pathBitSceneryEntries[pathSceneryIndex];
|
||||
if (sceneryEntry->path_bit.var_06 & (1 << 8)){
|
||||
found = 1;
|
||||
}
|
||||
|
@ -803,10 +804,17 @@ static void sub_68F41A(rct_peep *peep, int index)
|
|||
}
|
||||
}
|
||||
|
||||
/* some sort of check to see if peep is connected to the ground?? */
|
||||
int sub_68F3AE(rct_peep* peep){
|
||||
/*
|
||||
* rct2: 0x68F3AE
|
||||
* Set peep state to falling if path below has gone missing, return 1 if current path is valid, 0 if peep starts falling
|
||||
*/
|
||||
int checkForPath(rct_peep *peep){
|
||||
peep->var_C4++;
|
||||
if ((peep->var_C4 & 0xF) != (peep->sprite_index & 0xF))return 1;
|
||||
if ((peep->var_C4 & 0xF) != (peep->sprite_index & 0xF)){
|
||||
// This condition makes the check happen less often so the peeps hover for a short,
|
||||
// random time when a path below them has been deleted
|
||||
return 1;
|
||||
}
|
||||
|
||||
rct_map_element* map_element = map_get_first_element_at(peep->next_x / 32, peep->next_y / 32);
|
||||
|
||||
|
@ -819,10 +827,14 @@ int sub_68F3AE(rct_peep* peep){
|
|||
|
||||
do {
|
||||
if (map_element_get_type(map_element) == map_type){
|
||||
if (z == map_element->base_height)return 1;
|
||||
if (z == map_element->base_height) {
|
||||
// Found a suitable path
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
} while (!map_element_is_last_for_tile(map_element++));
|
||||
|
||||
// Found no suitable path
|
||||
peep_decrement_num_riders(peep);
|
||||
peep->state = PEEP_STATE_FALLING;
|
||||
peep_window_state_update(peep);
|
||||
|
@ -830,31 +842,31 @@ int sub_68F3AE(rct_peep* peep){
|
|||
}
|
||||
|
||||
void sub_693B58(rct_peep* peep){
|
||||
int ebx;
|
||||
if (peep->action >= 0xFE){
|
||||
ebx = RCT2_ADDRESS(0x981D8C, uint8)[peep->var_6D];
|
||||
uint8 action_sprite_type;
|
||||
if (peep->action >= PEEP_ACTION_NONE_1){ // PEEP_ACTION_NONE_1 or PEEP_ACTION_NONE_2
|
||||
action_sprite_type = RCT2_ADDRESS(0x981D8C, uint8)[peep->special_sprite];
|
||||
}
|
||||
else{
|
||||
ebx = RCT2_ADDRESS(0x981D8F, uint8)[peep->action];
|
||||
action_sprite_type = RCT2_ADDRESS(0x981D8F, uint8)[peep->action];
|
||||
}
|
||||
if (ebx == peep->action_sprite_type)return;
|
||||
if (action_sprite_type == peep->action_sprite_type)return;
|
||||
|
||||
invalidate_sprite_2((rct_sprite*)peep);
|
||||
peep->action_sprite_type = ebx;
|
||||
peep->action_sprite_type = action_sprite_type;
|
||||
|
||||
uint8* edx = RCT2_ADDRESS(0x98270C, uint8*)[peep->sprite_type * 2];
|
||||
peep->sprite_width = edx[ebx * 4];
|
||||
peep->sprite_height_negative = edx[ebx * 4 + 1];
|
||||
peep->sprite_height_positive = edx[ebx * 4 + 2];
|
||||
rct_sprite_bounds* spriteBounds = g_sprite_entries[peep->sprite_type].sprite_bounds;
|
||||
peep->sprite_width = spriteBounds[action_sprite_type].sprite_width;
|
||||
peep->sprite_height_negative = spriteBounds[action_sprite_type].sprite_height_negative;
|
||||
peep->sprite_height_positive = spriteBounds[action_sprite_type].sprite_height_positive;
|
||||
// This is pointless as nothing will have changed.
|
||||
invalidate_sprite_2((rct_sprite*)peep);
|
||||
}
|
||||
|
||||
/* 0x00693BE5 */
|
||||
void sub_693BE5(rct_peep* peep, uint8 al){
|
||||
if (al == peep->var_6D)return;
|
||||
if (al == peep->special_sprite)return;
|
||||
|
||||
peep->var_6D = al;
|
||||
peep->special_sprite = al;
|
||||
|
||||
// If NONE_1 or NONE_2
|
||||
if (peep->action >= PEEP_ACTION_NONE_1){
|
||||
|
@ -998,8 +1010,8 @@ int peep_update_action(sint16* x, sint16* y, sint16* xy_distance, rct_peep* peep
|
|||
*x = peep->x + RCT2_ADDRESS(0x981D7C, uint16)[direction / 4];
|
||||
*y = peep->y + RCT2_ADDRESS(0x981D7E, uint16)[direction / 4];
|
||||
peep->no_action_frame_no++;
|
||||
uint32* edi = RCT2_ADDRESS(0x982708, uint32*)[peep->sprite_type * 2];
|
||||
uint8* _edi = (uint8*)(edi[peep->action_sprite_type * 2 + 1]);
|
||||
rct_sprite_image * edi = g_sprite_entries[peep->sprite_type].sprite_image;
|
||||
uint8* _edi = (edi[peep->action_sprite_type]).unkn_04;
|
||||
if (peep->no_action_frame_no >= *_edi){
|
||||
peep->no_action_frame_no = 0;
|
||||
}
|
||||
|
@ -1007,8 +1019,8 @@ int peep_update_action(sint16* x, sint16* y, sint16* xy_distance, rct_peep* peep
|
|||
return 1;
|
||||
}
|
||||
|
||||
uint32* edi = RCT2_ADDRESS(0x982708, uint32*)[peep->sprite_type * 2];
|
||||
uint8* _edi = (uint8*)(edi[peep->action_sprite_type * 2 + 1]);
|
||||
rct_sprite_image * edi = g_sprite_entries[peep->sprite_type].sprite_image;
|
||||
uint8* _edi = (edi[peep->action_sprite_type]).unkn_04;
|
||||
peep->action_frame++;
|
||||
int ebx = _edi[peep->action_frame + 1];
|
||||
|
||||
|
@ -1090,12 +1102,12 @@ void set_sprite_type(rct_peep* peep, uint8 type){
|
|||
|
||||
if (peep->state == PEEP_STATE_SITTING){
|
||||
peep->action = PEEP_ACTION_NONE_1;
|
||||
peep->var_6F = 7;
|
||||
peep->next_action_sprite_type = 7;
|
||||
sub_693BAB(peep);
|
||||
}
|
||||
if (peep->state == PEEP_STATE_WATCHING){
|
||||
peep->action = PEEP_ACTION_NONE_1;
|
||||
peep->var_6F = 2;
|
||||
peep->next_action_sprite_type = 2;
|
||||
sub_693BAB(peep);
|
||||
}
|
||||
}
|
||||
|
@ -1458,7 +1470,7 @@ void peep_try_get_up_from_sitting(rct_peep* peep){
|
|||
*/
|
||||
void peep_update_sitting(rct_peep* peep){
|
||||
if (peep->sub_state == 0){
|
||||
if (!sub_68F3AE(peep))return;
|
||||
if (!checkForPath(peep))return;
|
||||
//691541
|
||||
|
||||
sub_693C9E(peep);
|
||||
|
@ -1475,7 +1487,7 @@ void peep_update_sitting(rct_peep* peep){
|
|||
peep->sprite_direction = ((peep->var_37 + 2) & 3) * 8;
|
||||
invalidate_sprite_2((rct_sprite*)peep);
|
||||
peep->action = 254;
|
||||
peep->var_6F = 7;
|
||||
peep->next_action_sprite_type = 7;
|
||||
sub_693BAB(peep);
|
||||
|
||||
peep->sub_state++;
|
||||
|
@ -3414,7 +3426,7 @@ static void peep_update_fixing(int steps, rct_peep* peep){
|
|||
* rct2: 0x69185D
|
||||
*/
|
||||
static void peep_update_queuing(rct_peep* peep){
|
||||
if (!sub_68F3AE(peep)){
|
||||
if (!checkForPath(peep)){
|
||||
remove_peep_from_queue(peep);
|
||||
return;
|
||||
}
|
||||
|
@ -3465,7 +3477,7 @@ static void peep_update_queuing(rct_peep* peep){
|
|||
}
|
||||
}
|
||||
else{
|
||||
if (!(peep->time_in_queue & 0x3F) && peep->action == 0xFE && peep->var_6F == 2){
|
||||
if (!(peep->time_in_queue & 0x3F) && peep->action == 0xFE && peep->next_action_sprite_type == 2){
|
||||
switch (peep->sprite_type){
|
||||
case 0xF:
|
||||
case 0x10:
|
||||
|
@ -3518,7 +3530,7 @@ static void peep_update_queuing(rct_peep* peep){
|
|||
*/
|
||||
static void peep_update_mowing(rct_peep* peep){
|
||||
peep->var_E2 = 0;
|
||||
if (!sub_68F3AE(peep))return;
|
||||
if (!checkForPath(peep))return;
|
||||
|
||||
invalidate_sprite_2((rct_sprite*)peep);
|
||||
while (1){
|
||||
|
@ -3566,7 +3578,7 @@ static void peep_update_mowing(rct_peep* peep){
|
|||
static void peep_update_watering(rct_peep* peep){
|
||||
peep->var_E2 = 0;
|
||||
if (peep->sub_state == 0){
|
||||
if (!sub_68F3AE(peep))return;
|
||||
if (!checkForPath(peep))return;
|
||||
|
||||
sub_693C9E(peep);
|
||||
if (!(RCT2_GLOBAL(0xF1EE18, uint16) & 1))return;
|
||||
|
@ -3622,7 +3634,7 @@ static void peep_update_emptying_bin(rct_peep* peep){
|
|||
peep->var_E2 = 0;
|
||||
|
||||
if (peep->sub_state == 0){
|
||||
if (!sub_68F3AE(peep))return;
|
||||
if (!checkForPath(peep))return;
|
||||
|
||||
sub_693C9E(peep);
|
||||
if (!(RCT2_GLOBAL(0xF1EE18, uint16) & 1))return;
|
||||
|
@ -3661,16 +3673,16 @@ static void peep_update_emptying_bin(rct_peep* peep){
|
|||
}
|
||||
}
|
||||
|
||||
if ((map_element->properties.path.additions & 0x0F) == 0) {
|
||||
if (!footpath_element_has_path_scenery(map_element)) {
|
||||
peep_state_reset(peep);
|
||||
return;
|
||||
}
|
||||
|
||||
rct_scenery_entry* scenery_entry = g_pathBitSceneryEntries[(map_element->properties.path.additions & 0xF) - 1];
|
||||
rct_scenery_entry* scenery_entry = g_pathBitSceneryEntries[footpath_element_get_path_scenery_index(map_element)];
|
||||
if (
|
||||
!(scenery_entry->path_bit.var_06 & 1)
|
||||
|| map_element->flags & (1 << 5)
|
||||
|| map_element->properties.path.additions & (1 << 7)
|
||||
|| footpath_element_path_scenery_is_ghost(map_element)
|
||||
) {
|
||||
peep_state_reset(peep);
|
||||
return;
|
||||
|
@ -3691,7 +3703,7 @@ static void peep_update_emptying_bin(rct_peep* peep){
|
|||
*/
|
||||
static void peep_update_sweeping(rct_peep* peep){
|
||||
peep->var_E2 = 0;
|
||||
if (!sub_68F3AE(peep))return;
|
||||
if (!checkForPath(peep))return;
|
||||
|
||||
invalidate_sprite_2((rct_sprite*)peep);
|
||||
|
||||
|
@ -3726,7 +3738,7 @@ static void peep_update_sweeping(rct_peep* peep){
|
|||
* rct2: 0x6902A2
|
||||
*/
|
||||
static void peep_update_1(rct_peep* peep){
|
||||
if (!sub_68F3AE(peep))return;
|
||||
if (!checkForPath(peep))return;
|
||||
|
||||
peep_decrement_num_riders(peep);
|
||||
|
||||
|
@ -3795,7 +3807,7 @@ static void peep_update_leaving_park(rct_peep* peep){
|
|||
*/
|
||||
static void peep_update_watching(rct_peep* peep){
|
||||
if (peep->sub_state == 0){
|
||||
if (!sub_68F3AE(peep))return;
|
||||
if (!checkForPath(peep))return;
|
||||
|
||||
sub_693C9E(peep);
|
||||
if (!(RCT2_GLOBAL(0xF1EE18, uint16) & 1))return;
|
||||
|
@ -3807,7 +3819,7 @@ static void peep_update_watching(rct_peep* peep){
|
|||
invalidate_sprite_2((rct_sprite*)peep);
|
||||
|
||||
peep->action = 0xFE;
|
||||
peep->var_6F = 2;
|
||||
peep->next_action_sprite_type = 2;
|
||||
|
||||
sub_693BAB(peep);
|
||||
|
||||
|
@ -3925,16 +3937,14 @@ static int peep_update_walking_find_bench(rct_peep* peep){
|
|||
}
|
||||
}
|
||||
|
||||
uint8 additions = map_element->properties.path.additions & 0xF;
|
||||
|
||||
if (!additions) return 0;
|
||||
rct_scenery_entry* sceneryEntry = g_pathBitSceneryEntries[additions - 1];
|
||||
if (!footpath_element_has_path_scenery(map_element)) return 0;
|
||||
rct_scenery_entry* sceneryEntry = g_pathBitSceneryEntries[footpath_element_get_path_scenery_index(map_element)];
|
||||
|
||||
if (!(sceneryEntry->path_bit.var_06 & 0x2))return 0;
|
||||
|
||||
if (map_element->flags & MAP_ELEMENT_FLAG_BROKEN)return 0;
|
||||
|
||||
if (map_element->properties.path.additions & 0x80)return 0;
|
||||
if (footpath_element_path_scenery_is_ghost(map_element)) return 0;
|
||||
|
||||
int edges = (map_element->properties.path.edges & 0xF) ^ 0xF;
|
||||
if (edges == 0) return 0;
|
||||
|
@ -4002,16 +4012,14 @@ static int peep_update_walking_find_bin(rct_peep* peep){
|
|||
}
|
||||
}
|
||||
|
||||
uint8 additions = map_element->properties.path.additions & 0xF;
|
||||
|
||||
if (!additions) return 0;
|
||||
rct_scenery_entry* sceneryEntry = g_pathBitSceneryEntries[additions - 1];
|
||||
if (!footpath_element_has_path_scenery(map_element)) return 0;
|
||||
rct_scenery_entry* sceneryEntry = g_pathBitSceneryEntries[footpath_element_get_path_scenery_index(map_element)];
|
||||
|
||||
if (!(sceneryEntry->path_bit.var_06 & 0x1))return 0;
|
||||
|
||||
if (map_element->flags & MAP_ELEMENT_FLAG_BROKEN)return 0;
|
||||
|
||||
if (map_element->properties.path.additions & 0x80)return 0;
|
||||
if (footpath_element_path_scenery_is_ghost(map_element)) return 0;
|
||||
|
||||
int edges = (map_element->properties.path.edges & 0xF) ^ 0xF;
|
||||
if (edges == 0) return 0;
|
||||
|
@ -4085,16 +4093,14 @@ static void peep_update_walking_break_scenery(rct_peep* peep){
|
|||
}
|
||||
}
|
||||
|
||||
uint8 additions = map_element->properties.path.additions & 0xF;
|
||||
|
||||
if (!additions) return;
|
||||
rct_scenery_entry* sceneryEntry = g_pathBitSceneryEntries[additions - 1];
|
||||
if (!footpath_element_has_path_scenery(map_element)) return;
|
||||
rct_scenery_entry* sceneryEntry = g_pathBitSceneryEntries[footpath_element_get_path_scenery_index(map_element)];
|
||||
|
||||
if (!(sceneryEntry->path_bit.var_06 & 0x4))return;
|
||||
|
||||
if (map_element->flags & MAP_ELEMENT_FLAG_BROKEN)return;
|
||||
|
||||
if (map_element->properties.path.additions & 0x80)return;
|
||||
if (footpath_element_path_scenery_is_ghost(map_element))return;
|
||||
|
||||
int edges = map_element->properties.path.edges & 0xF;
|
||||
if (edges == 0xF) return;
|
||||
|
@ -4132,7 +4138,7 @@ static void peep_update_walking_break_scenery(rct_peep* peep){
|
|||
*/
|
||||
static void peep_update_buying(rct_peep* peep)
|
||||
{
|
||||
if (!sub_68F3AE(peep))return;
|
||||
if (!checkForPath(peep))return;
|
||||
|
||||
rct_ride* ride = GET_RIDE(peep->current_ride);
|
||||
if (ride->type == RIDE_TYPE_NULL || ride->status != RIDE_STATUS_OPEN){
|
||||
|
@ -4225,7 +4231,7 @@ static void peep_update_buying(rct_peep* peep)
|
|||
*/
|
||||
static void peep_update_using_bin(rct_peep* peep){
|
||||
if (peep->sub_state == 0){
|
||||
if (!sub_68F3AE(peep))return;
|
||||
if (!checkForPath(peep))return;
|
||||
|
||||
sub_693C9E(peep);
|
||||
if (!(RCT2_GLOBAL(0xF1EE18, uint16) & 1))return;
|
||||
|
@ -4255,13 +4261,12 @@ static void peep_update_using_bin(rct_peep* peep){
|
|||
}
|
||||
}
|
||||
|
||||
uint8 additions = map_element->properties.path.additions & 0x0F;
|
||||
if (!additions){
|
||||
if (!footpath_element_has_path_scenery(map_element)){
|
||||
peep_state_reset(peep);
|
||||
return;
|
||||
}
|
||||
|
||||
rct_scenery_entry* sceneryEntry = g_pathBitSceneryEntries[additions - 1];
|
||||
rct_scenery_entry* sceneryEntry = g_pathBitSceneryEntries[footpath_element_get_path_scenery_index(map_element)];
|
||||
if (!(sceneryEntry->path_bit.var_06 & 1)){
|
||||
peep_state_reset(peep);
|
||||
return;
|
||||
|
@ -4272,7 +4277,7 @@ static void peep_update_using_bin(rct_peep* peep){
|
|||
return;
|
||||
}
|
||||
|
||||
if (map_element->properties.path.additions & 0x80){
|
||||
if (footpath_element_path_scenery_is_ghost(map_element)){
|
||||
peep_state_reset(peep);
|
||||
return;
|
||||
}
|
||||
|
@ -4400,7 +4405,7 @@ static void peep_update_heading_to_inspect(rct_peep* peep){
|
|||
return;
|
||||
}
|
||||
|
||||
if (!sub_68F3AE(peep))return;
|
||||
if (!checkForPath(peep))return;
|
||||
|
||||
sub_693C9E(peep);
|
||||
|
||||
|
@ -4513,7 +4518,7 @@ static void peep_update_answering(rct_peep* peep){
|
|||
return;
|
||||
}
|
||||
|
||||
if (!sub_68F3AE(peep))return;
|
||||
if (!checkForPath(peep))return;
|
||||
|
||||
sub_693C9E(peep);
|
||||
|
||||
|
@ -4656,11 +4661,8 @@ static int peep_update_patrolling_find_bin(rct_peep* peep){
|
|||
return 0;
|
||||
}
|
||||
|
||||
uint8 additions = map_element->properties.path.additions & 0xF;
|
||||
|
||||
if (additions == 0)return 0;
|
||||
|
||||
rct_scenery_entry* sceneryEntry = g_pathBitSceneryEntries[additions - 1];
|
||||
if (!footpath_element_has_path_scenery(map_element)) return 0;
|
||||
rct_scenery_entry* sceneryEntry = g_pathBitSceneryEntries[footpath_element_get_path_scenery_index(map_element)];
|
||||
|
||||
if (!(sceneryEntry->path_bit.var_06 & 1))
|
||||
return 0;
|
||||
|
@ -4668,7 +4670,7 @@ static int peep_update_patrolling_find_bin(rct_peep* peep){
|
|||
if (map_element->flags & MAP_ELEMENT_FLAG_BROKEN)
|
||||
return 0;
|
||||
|
||||
if (map_element->properties.path.additions & 0x80)
|
||||
if (footpath_element_path_scenery_is_ghost(map_element))
|
||||
return 0;
|
||||
|
||||
uint8 bin_positions = map_element->properties.path.edges & 0xF;
|
||||
|
@ -4768,7 +4770,7 @@ static int peep_update_patrolling_find_sweeping(rct_peep* peep){
|
|||
*/
|
||||
static void peep_update_patrolling(rct_peep* peep){
|
||||
|
||||
if (!sub_68F3AE(peep))return;
|
||||
if (!checkForPath(peep))return;
|
||||
|
||||
sub_693C9E(peep);
|
||||
if (!(RCT2_GLOBAL(0xF1EE18, uint16) & 1))return;
|
||||
|
@ -4808,7 +4810,7 @@ static void peep_update_patrolling(rct_peep* peep){
|
|||
* rct2: 0x0069030A
|
||||
*/
|
||||
static void peep_update_walking(rct_peep* peep){
|
||||
if (!sub_68F3AE(peep))return;
|
||||
if (!checkForPath(peep))return;
|
||||
|
||||
if (peep->flags & PEEP_FLAGS_WAVING){
|
||||
if (peep->action >= PEEP_ACTION_NONE_1){
|
||||
|
@ -4958,13 +4960,11 @@ static void peep_update_walking(rct_peep* peep){
|
|||
}
|
||||
}
|
||||
|
||||
uint8 additions = map_element->properties.path.additions & 0xF;
|
||||
|
||||
int ebp = 15;
|
||||
|
||||
if (additions){
|
||||
if (!(map_element->properties.path.additions & 0x80)){
|
||||
rct_scenery_entry* sceneryEntry = g_pathBitSceneryEntries[additions - 1];
|
||||
if (footpath_element_has_path_scenery(map_element)) {
|
||||
if (!footpath_element_path_scenery_is_ghost(map_element)) {
|
||||
rct_scenery_entry* sceneryEntry = g_pathBitSceneryEntries[footpath_element_get_path_scenery_index(map_element)];
|
||||
|
||||
if (!(sceneryEntry->path_bit.var_06 & 0x2)) ebp = 9;
|
||||
}
|
||||
|
@ -5484,7 +5484,7 @@ rct_peep *peep_generate(int x, int y, int z)
|
|||
peep->outside_of_park = 1;
|
||||
peep->state = PEEP_STATE_FALLING;
|
||||
peep->action = PEEP_ACTION_NONE_2;
|
||||
peep->var_6D = 0;
|
||||
peep->special_sprite = 0;
|
||||
peep->action_sprite_image_offset = 0;
|
||||
peep->no_action_frame_no = 0;
|
||||
peep->action_sprite_type = 0;
|
||||
|
@ -5492,10 +5492,10 @@ rct_peep *peep_generate(int x, int y, int z)
|
|||
peep->favourite_ride = 0xFF;
|
||||
peep->favourite_ride_rating = 0;
|
||||
|
||||
uint8* edx = RCT2_ADDRESS(0x98270C, uint8*)[peep->sprite_type * 2];
|
||||
peep->sprite_width = edx[peep->action_sprite_type * 4];
|
||||
peep->sprite_height_negative = edx[peep->action_sprite_type * 4 + 1];
|
||||
peep->sprite_height_positive = edx[peep->action_sprite_type * 4 + 2];
|
||||
rct_sprite_bounds* spriteBounds = g_sprite_entries[peep->sprite_type].sprite_bounds;
|
||||
peep->sprite_width = spriteBounds[peep->action_sprite_type].sprite_width;
|
||||
peep->sprite_height_negative = spriteBounds[peep->action_sprite_type].sprite_height_negative;
|
||||
peep->sprite_height_positive = spriteBounds[peep->action_sprite_type].sprite_height_positive;
|
||||
|
||||
peep->sprite_direction = 0;
|
||||
|
||||
|
@ -6160,14 +6160,15 @@ void peep_set_map_tooltip(rct_peep *peep)
|
|||
|
||||
|
||||
void sub_693BAB(rct_peep* peep) {
|
||||
uint8 bl = peep->var_6F;
|
||||
if (bl != peep->action_sprite_type) {
|
||||
// TBD: Add nextActionSpriteType as function parameter and make peep->next_action_sprite_type obsolete?
|
||||
uint8 nextActionSpriteType = peep->next_action_sprite_type;
|
||||
if (nextActionSpriteType != peep->action_sprite_type) {
|
||||
invalidate_sprite_2((rct_sprite*)peep);
|
||||
peep->action_sprite_type = bl;
|
||||
uint8* edx = RCT2_ADDRESS(0x98270C, uint8*)[peep->sprite_type * 2];
|
||||
peep->sprite_width = edx[bl * 4];
|
||||
peep->sprite_height_negative = edx[bl * 4 + 1];
|
||||
peep->sprite_height_positive = edx[bl * 4 + 2];
|
||||
peep->action_sprite_type = nextActionSpriteType;
|
||||
rct_sprite_bounds* spriteBounds = g_sprite_entries[peep->sprite_type].sprite_bounds;
|
||||
peep->sprite_width = spriteBounds[nextActionSpriteType].sprite_width;
|
||||
peep->sprite_height_negative = spriteBounds[nextActionSpriteType].sprite_height_negative;
|
||||
peep->sprite_height_positive = spriteBounds[nextActionSpriteType].sprite_height_positive;
|
||||
invalidate_sprite_2((rct_sprite*)peep);
|
||||
}
|
||||
}
|
||||
|
@ -6235,7 +6236,7 @@ static int peep_update_queue_position(rct_peep* peep){
|
|||
return 1;
|
||||
|
||||
peep->action = PEEP_ACTION_NONE_1;
|
||||
peep->var_6F = 2;
|
||||
peep->next_action_sprite_type = 2;
|
||||
if (RCT2_GLOBAL(0x00F1AEF1, uint8) != 0xFE)
|
||||
invalidate_sprite_2((rct_sprite*)peep);
|
||||
return 1;
|
||||
|
@ -6629,7 +6630,7 @@ static int peep_interact_with_path(rct_peep* peep, sint16 x, sint16 y, rct_map_e
|
|||
|
||||
// 0x00F1AEE2
|
||||
bool vandalism_present = false;
|
||||
if ((map_element->properties.path.additions & 0xF) != 0 &&
|
||||
if (footpath_element_has_path_scenery(map_element) &&
|
||||
(map_element->flags & MAP_ELEMENT_FLAG_BROKEN) &&
|
||||
(map_element->properties.path.edges & 0xF) != 0xF){
|
||||
vandalism_present = 1;
|
||||
|
|
|
@ -372,6 +372,12 @@ enum {
|
|||
PEEP_RIDE_DECISION_THINKING = 1 << 2
|
||||
};
|
||||
|
||||
// Flags used by peep->list_flags
|
||||
enum {
|
||||
PEEP_LIST_FLAGS_VISIBLE = 1 << 8, // Peep is eligible to show in summarized guest list window (is inside park?)
|
||||
PEEP_LIST_FLAGS_FLASHING = 1 << 9, // Peep belongs to highlighted group (flashes red on map)
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
uint8 type; //0
|
||||
uint8 item; //1
|
||||
|
@ -389,7 +395,7 @@ typedef struct {
|
|||
// Height from center of sprite to bottom
|
||||
uint8 sprite_height_negative; // 0x09
|
||||
uint16 sprite_index; // 0x0A
|
||||
uint16 var_0C;
|
||||
uint16 list_flags; // 0x0C Used for highlighting peeps on map with staff list or guest list open
|
||||
sint16 x; // 0x0E
|
||||
sint16 y; // 0x10
|
||||
sint16 z; // 0x12
|
||||
|
@ -458,9 +464,11 @@ typedef struct {
|
|||
uint8 standing_flags; //0x6C
|
||||
};
|
||||
};
|
||||
uint8 var_6D; // 0x6D
|
||||
// Normally 0, 1 for carrying sliding board on spiral slide ride, 2 for carrying lawn mower
|
||||
uint8 special_sprite; // 0x6D
|
||||
uint8 action_sprite_type; // 0x6E
|
||||
uint8 var_6F;
|
||||
// Seems to be used like a local variable, as it's always set before calling sub_693BAB, which reads this again
|
||||
uint8 next_action_sprite_type; // 0x6F
|
||||
uint8 action_sprite_image_offset; // 0x70
|
||||
uint8 action; // 0x71
|
||||
uint8 action_frame; // 0x72
|
||||
|
@ -488,7 +496,7 @@ typedef struct {
|
|||
uint8 previous_ride; // 0xAD
|
||||
uint16 previous_ride_time_out; // 0xAE
|
||||
rct_peep_thought thoughts[PEEP_MAX_THOUGHTS]; // 0xB0
|
||||
uint8 var_C4; // 0xC4
|
||||
uint8 var_C4; // 0xC4 has something to do with peep falling, see peep.checkForPath
|
||||
union {
|
||||
uint8 staff_id; // 0xC5
|
||||
uint8 guest_heading_to_ride_id; // 0xC5
|
||||
|
|
|
@ -109,7 +109,8 @@ void game_command_hire_new_staff_member(int* eax, int* ebx, int* ecx, int* edx,
|
|||
|
||||
int newStaffId = i;
|
||||
|
||||
int _eax, _ebx, _ecx = _cx, _edx;
|
||||
int _eax, _ebx, _ecx = _cx;
|
||||
rct_sprite_bounds *spriteBounds;
|
||||
_ebx = _bl;
|
||||
|
||||
rct_peep* newPeep = &(create_sprite(_bl)->peep);
|
||||
|
@ -129,7 +130,7 @@ void game_command_hire_new_staff_member(int* eax, int* ebx, int* ecx, int* edx,
|
|||
newPeep->sprite_identifier = 1;
|
||||
newPeep->window_invalidate_flags = 0;
|
||||
newPeep->action = PEEP_ACTION_NONE_2;
|
||||
newPeep->var_6D = 0;
|
||||
newPeep->special_sprite = 0;
|
||||
newPeep->action_sprite_image_offset = 0;
|
||||
newPeep->no_action_frame_no = 0;
|
||||
newPeep->action_sprite_type = 0;
|
||||
|
@ -181,10 +182,10 @@ void game_command_hire_new_staff_member(int* eax, int* ebx, int* ecx, int* edx,
|
|||
newPeep->name_string_idx = staff_type + 0x300;
|
||||
newPeep->sprite_type = _eax;
|
||||
|
||||
_edx = RCT2_ADDRESS(0x0098270C, uint32)[_eax * 2];
|
||||
newPeep->sprite_width = *((uint8*)_edx);
|
||||
newPeep->sprite_height_negative = *((uint8*)(_edx + 1));
|
||||
newPeep->sprite_height_positive = *((uint8*)(_edx + 2));
|
||||
spriteBounds = g_sprite_entries[_eax].sprite_bounds;
|
||||
newPeep->sprite_width = spriteBounds->sprite_width;
|
||||
newPeep->sprite_height_negative = spriteBounds->sprite_height_negative;
|
||||
newPeep->sprite_height_positive = spriteBounds->sprite_height_positive;
|
||||
|
||||
if ((gConfigGeneral.auto_staff_placement != 0) != ((SDL_GetModState() & KMOD_SHIFT) != 0)) {
|
||||
newPeep->state = PEEP_STATE_FALLING;
|
||||
|
@ -292,7 +293,13 @@ void game_command_set_staff_order(int *eax, int *ebx, int *ecx, int *edx, int *e
|
|||
RCT2_GLOBAL(RCT2_ADDRESS_NEXT_EXPENDITURE_TYPE, uint8) = RCT_EXPENDITURE_TYPE_WAGES * 4;
|
||||
uint8 order_id = *ebx >> 8;
|
||||
uint16 sprite_id = *edx;
|
||||
if(*ebx & GAME_COMMAND_FLAG_APPLY){
|
||||
if (sprite_id >= MAX_SPRITES)
|
||||
{
|
||||
log_warning("Invalid game command, sprite_id = %u", sprite_id);
|
||||
*ebx = MONEY32_UNDEFINED;
|
||||
return;
|
||||
}
|
||||
if (*ebx & GAME_COMMAND_FLAG_APPLY) {
|
||||
rct_peep *peep = &g_sprite_list[sprite_id].peep;
|
||||
if(order_id & 0x80){ // change costume
|
||||
uint8 sprite_type = order_id & ~0x80;
|
||||
|
@ -365,7 +372,19 @@ void game_command_fire_staff_member(int *eax, int *ebx, int *ecx, int *edx, int
|
|||
if(*ebx & GAME_COMMAND_FLAG_APPLY){
|
||||
window_close_by_class(WC_FIRE_PROMPT);
|
||||
uint16 sprite_id = *edx;
|
||||
if (sprite_id >= MAX_SPRITES)
|
||||
{
|
||||
log_warning("Invalid game command, sprite_id = %u", sprite_id);
|
||||
*ebx = MONEY32_UNDEFINED;
|
||||
return;
|
||||
}
|
||||
rct_peep *peep = &g_sprite_list[sprite_id].peep;
|
||||
if (peep->sprite_identifier != SPRITE_IDENTIFIER_PEEP || peep->type != PEEP_TYPE_STAFF)
|
||||
{
|
||||
log_warning("Invalid game command, peep->sprite_identifier = %u, peep->type = %u", peep->sprite_identifier, peep->type);
|
||||
*ebx = MONEY32_UNDEFINED;
|
||||
return;
|
||||
}
|
||||
remove_peep_from_ride(peep);
|
||||
peep_sprite_remove(peep);
|
||||
}
|
||||
|
|
|
@ -166,6 +166,8 @@ bool platform_get_font_path(TTFFontDescriptor *font, utf8 *buffer);
|
|||
|
||||
bool platform_check_steam_overlay_attached();
|
||||
|
||||
datetime64 platform_get_datetime_now_utc();
|
||||
|
||||
// BSD and OS X has MAP_ANON instead of MAP_ANONYMOUS
|
||||
#ifndef MAP_ANONYMOUS
|
||||
#define MAP_ANONYMOUS MAP_ANON
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include <dirent.h>
|
||||
#include <fnmatch.h>
|
||||
#include <locale.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
|
||||
// The name of the mutex used to prevent multiple instances of the game from running
|
||||
|
@ -499,8 +500,8 @@ bool platform_file_move(const utf8 *srcPath, const utf8 *dstPath)
|
|||
|
||||
bool platform_file_delete(const utf8 *path)
|
||||
{
|
||||
STUB();
|
||||
return 0;
|
||||
int ret = unlink(path);
|
||||
return ret == 0;
|
||||
}
|
||||
|
||||
wchar_t *regular_to_wchar(const char* src)
|
||||
|
@ -753,4 +754,20 @@ uint8 platform_get_locale_temperature_format(){
|
|||
return TEMPERATURE_FORMAT_C;
|
||||
}
|
||||
|
||||
datetime64 platform_get_datetime_now_utc()
|
||||
{
|
||||
const datetime64 epochAsTicks = 621355968000000000;
|
||||
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
uint64 utcEpoch = tv.tv_sec;
|
||||
|
||||
// Epoch starts from: 1970-01-01T00:00:00Z
|
||||
// Convert to ticks from 0001-01-01T00:00:00Z
|
||||
uint64 utcEpochTicks = (uint64)tv.tv_sec * 10000000ULL + tv.tv_usec * 10;
|
||||
datetime64 utcNow = epochAsTicks + utcEpochTicks;
|
||||
return utcNow;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -242,7 +242,11 @@ void platform_draw()
|
|||
if (pitch == (width * 2) + padding) {
|
||||
uint16 *dst = pixels;
|
||||
for (int y = height; y > 0; y--) {
|
||||
for (int x = width; x > 0; x--) { *dst++ = *(uint16 *)(&gPaletteHWMapped[*src++]); }
|
||||
for (int x = width; x > 0; x--) {
|
||||
const uint8 lower = *(uint8 *)(&gPaletteHWMapped[*src++]);
|
||||
const uint8 upper = *(uint8 *)(&gPaletteHWMapped[*src++]);
|
||||
*dst++ = (lower << 8) | upper;
|
||||
}
|
||||
dst = (uint16*)(((uint8 *)dst) + padding);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -262,6 +262,48 @@ int platform_enumerate_files_begin(const utf8 *pattern)
|
|||
return INVALID_HANDLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Due to FindFirstFile / FindNextFile searching for DOS names as well, *.doc also matches *.docx which isn't what the pattern
|
||||
* specified. This will verify if a filename does indeed match the pattern we asked for.
|
||||
* @remarks Based on algorithm (http://xoomer.virgilio.it/acantato/dev/wildcard/wildmatch.html)
|
||||
*/
|
||||
static bool match_wildcard(const wchar_t *fileName, const wchar_t *pattern)
|
||||
{
|
||||
while (*fileName != '\0') {
|
||||
switch (*pattern) {
|
||||
case '?':
|
||||
if (*fileName == '.') {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case '*':
|
||||
do {
|
||||
pattern++;
|
||||
} while (*pattern == '*');
|
||||
if (*pattern == '\0') {
|
||||
return false;
|
||||
}
|
||||
while (*fileName != '\0') {
|
||||
if (match_wildcard(fileName++, pattern)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
default:
|
||||
if (toupper(*fileName) != toupper(*pattern)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
pattern++;
|
||||
fileName++;
|
||||
}
|
||||
while (*pattern == '*') {
|
||||
++fileName;
|
||||
}
|
||||
return *pattern == '\0';
|
||||
}
|
||||
|
||||
bool platform_enumerate_files_next(int handle, file_info *outFileInfo)
|
||||
{
|
||||
bool result;
|
||||
|
@ -270,18 +312,28 @@ bool platform_enumerate_files_next(int handle, file_info *outFileInfo)
|
|||
|
||||
enumFileInfo = &_enumerateFileInfoList[handle];
|
||||
|
||||
if (enumFileInfo->handle == NULL) {
|
||||
findFileHandle = FindFirstFileW(enumFileInfo->pattern, &enumFileInfo->data);
|
||||
if (findFileHandle != INVALID_HANDLE_VALUE) {
|
||||
enumFileInfo->handle = findFileHandle;
|
||||
result = true;
|
||||
} else {
|
||||
result = false;
|
||||
}
|
||||
// Get pattern (just filename part)
|
||||
const wchar_t *patternWithoutDirectory = wcsrchr(enumFileInfo->pattern, '\\');
|
||||
if (patternWithoutDirectory == NULL) {
|
||||
patternWithoutDirectory = enumFileInfo->pattern;
|
||||
} else {
|
||||
result = FindNextFileW(enumFileInfo->handle, &enumFileInfo->data);
|
||||
patternWithoutDirectory++;
|
||||
}
|
||||
|
||||
do {
|
||||
if (enumFileInfo->handle == NULL) {
|
||||
findFileHandle = FindFirstFileW(enumFileInfo->pattern, &enumFileInfo->data);
|
||||
if (findFileHandle != INVALID_HANDLE_VALUE) {
|
||||
enumFileInfo->handle = findFileHandle;
|
||||
result = true;
|
||||
} else {
|
||||
result = false;
|
||||
}
|
||||
} else {
|
||||
result = FindNextFileW(enumFileInfo->handle, &enumFileInfo->data);
|
||||
}
|
||||
} while (result && !match_wildcard(enumFileInfo->data.cFileName, patternWithoutDirectory));
|
||||
|
||||
if (result) {
|
||||
outFileInfo->path = enumFileInfo->outFilename = widechar_to_utf8(enumFileInfo->data.cFileName);
|
||||
outFileInfo->size = ((uint64)enumFileInfo->data.nFileSizeHigh << 32ULL) | (uint64)enumFileInfo->data.nFileSizeLow;
|
||||
|
@ -935,4 +987,17 @@ bool platform_get_font_path(TTFFontDescriptor *font, utf8 *buffer)
|
|||
#endif
|
||||
}
|
||||
|
||||
datetime64 platform_get_datetime_now_utc()
|
||||
{
|
||||
// Get file time
|
||||
FILETIME fileTime;
|
||||
GetSystemTimeAsFileTime(&fileTime);
|
||||
uint64 fileTime64 = ((uint64)fileTime.dwHighDateTime << 32ULL) | ((uint64)fileTime.dwLowDateTime);
|
||||
|
||||
// File time starts from: 1601-01-01T00:00:00Z
|
||||
// Convert to start from: 0001-01-01T00:00:00Z
|
||||
datetime64 utcNow = fileTime64 - 504911232000000000ULL;
|
||||
return utcNow;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
13
src/rct1.c
13
src/rct1.c
|
@ -776,23 +776,22 @@ static void rct1_fix_paths()
|
|||
mapElement->type &= 0xFC;
|
||||
mapElement->flags &= ~0x60;
|
||||
mapElement->properties.path.type &= 0x0F;
|
||||
mapElement->properties.path.additions &= 0x7F;
|
||||
footpath_scenery_set_is_ghost(mapElement, false);
|
||||
if (pathType & 0x80) {
|
||||
mapElement->type |= 1;
|
||||
}
|
||||
mapElement->properties.path.type |= pathType << 4;
|
||||
|
||||
// Additions
|
||||
additions = mapElement->properties.path.additions & 0x0F;
|
||||
additions = RCT1PathAdditionConversionTable[additions];
|
||||
if (additions & 0x80) {
|
||||
additions &= ~0x80;
|
||||
additions = RCT1PathAdditionConversionTable[footpath_element_get_path_scenery(mapElement)];
|
||||
if (footpath_element_path_scenery_is_ghost(mapElement)) {
|
||||
footpath_scenery_set_is_ghost(mapElement, false);
|
||||
mapElement->flags |= MAP_ELEMENT_FLAG_BROKEN;
|
||||
} else {
|
||||
mapElement->flags &= ~MAP_ELEMENT_FLAG_BROKEN;
|
||||
}
|
||||
mapElement->properties.path.additions &= 0xF0;
|
||||
mapElement->properties.path.additions |= additions;
|
||||
|
||||
footpath_element_set_path_scenery(mapElement, additions);
|
||||
break;
|
||||
case MAP_ELEMENT_TYPE_ENTRANCE:
|
||||
if (mapElement->properties.entrance.type == ENTRANCE_TYPE_PARK_ENTRANCE) {
|
||||
|
|
|
@ -438,9 +438,6 @@ void rct2_update_2()
|
|||
if (RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint8) == 0)
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PALETTE_EFFECT_FRAME_NO, sint32) += tick2;
|
||||
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_ON_TUTORIAL, uint8) != 0)
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TICKS_SINCE_LAST_UPDATE, sint16) = 31;
|
||||
|
||||
// TODO: screenshot countdown process
|
||||
|
||||
network_update();
|
||||
|
|
|
@ -115,6 +115,11 @@ typedef utf16* utf16string;
|
|||
|
||||
#define OPENRCT2_MASTER_SERVER_URL "https://servers.openrct2.website"
|
||||
|
||||
// Time (represented as number of 100-nanosecond intervals since 0001-01-01T00:00:00Z)
|
||||
typedef uint64 datetime64;
|
||||
|
||||
#define DATETIME64_MIN ((datetime64)0)
|
||||
|
||||
// Represent fixed point numbers. dp = decimal point
|
||||
typedef uint8 fixed8_1dp;
|
||||
typedef uint8 fixed8_2dp;
|
||||
|
|
149
src/ride/ride.c
149
src/ride/ride.c
|
@ -1592,7 +1592,7 @@ static int ride_modify_entrance_or_exit(rct_map_element *mapElement, int x, int
|
|||
sub_6C9627();
|
||||
if (
|
||||
_rideConstructionState != RIDE_CONSTRUCTION_STATE_ENTRANCE_EXIT ||
|
||||
!(RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE) ||
|
||||
!(gInputFlags & INPUT_FLAG_TOOL_ACTIVE) ||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) != WC_RIDE_CONSTRUCTION
|
||||
) {
|
||||
// Replace entrance / exit
|
||||
|
@ -1600,7 +1600,7 @@ static int ride_modify_entrance_or_exit(rct_map_element *mapElement, int x, int
|
|||
RCT2_GLOBAL(0x00F44191, uint8) = entranceType;
|
||||
RCT2_GLOBAL(0x00F44192, uint8) = rideIndex;
|
||||
RCT2_GLOBAL(0x00F44193, uint8) = bl;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_6;
|
||||
gInputFlags |= INPUT_FLAG_6;
|
||||
if (_rideConstructionState != RIDE_CONSTRUCTION_STATE_ENTRANCE_EXIT) {
|
||||
RCT2_GLOBAL(0x00F440CC, uint8) = _rideConstructionState;
|
||||
_rideConstructionState = RIDE_CONSTRUCTION_STATE_ENTRANCE_EXIT;
|
||||
|
@ -1755,7 +1755,7 @@ int sub_6CC3FB(int rideIndex)
|
|||
w = ride_create_or_find_construction_window(rideIndex);
|
||||
|
||||
tool_set(w, 23, 12);
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_6;
|
||||
gInputFlags |= INPUT_FLAG_6;
|
||||
|
||||
ride = GET_RIDE(_currentRideIndex);
|
||||
|
||||
|
@ -2467,7 +2467,7 @@ rct_peep *find_closest_mechanic(int x, int y, int forInspection)
|
|||
uint16 spriteIndex;
|
||||
rct_peep *peep, *closestMechanic = NULL;
|
||||
|
||||
closestDistance = -1;
|
||||
closestDistance = UINT_MAX;
|
||||
FOR_ALL_STAFF(spriteIndex, peep) {
|
||||
if (peep->staff_type != STAFF_TYPE_MECHANIC)
|
||||
continue;
|
||||
|
@ -2494,15 +2494,15 @@ rct_peep *find_closest_mechanic(int x, int y, int forInspection)
|
|||
if (peep->x == (sint16)0x8000)
|
||||
continue;
|
||||
|
||||
// Should probably be euclidean or manhattan distance, this seems a bit naive
|
||||
distance = max(abs(peep->x - x), abs(peep->y - y));
|
||||
// manhattan distance
|
||||
distance = abs(peep->x - x) + abs(peep->y - y);
|
||||
if (distance < closestDistance) {
|
||||
closestDistance = distance;
|
||||
closestMechanic = peep;
|
||||
}
|
||||
}
|
||||
|
||||
return closestDistance == -1 ? NULL : closestMechanic;
|
||||
return closestMechanic;
|
||||
}
|
||||
|
||||
rct_peep *ride_get_assigned_mechanic(rct_ride *ride)
|
||||
|
@ -2920,7 +2920,15 @@ static bool ride_does_vehicle_colour_exist(uint8 ride_sub_type, vehicle_colour *
|
|||
|
||||
static int ride_get_unused_preset_vehicle_colour(uint8 ride_type, uint8 ride_sub_type)
|
||||
{
|
||||
if (ride_sub_type >= 128)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
rct_ride_type *rideEntry = GET_RIDE_ENTRY(ride_sub_type);
|
||||
if (rideEntry == (rct_ride_type *)0xFFFFFFFF)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
vehicle_colour_preset_list *presetList = rideEntry->vehicle_preset_list;
|
||||
if (presetList->count == 255)
|
||||
return 255;
|
||||
|
@ -3594,6 +3602,12 @@ void game_command_set_ride_setting(int *eax, int *ebx, int *ecx, int *edx, int *
|
|||
|
||||
uint8 ride_id = *edx & 0xFF;
|
||||
rct_ride* ride = GET_RIDE(ride_id);
|
||||
if (ride->type == RIDE_TYPE_NULL)
|
||||
{
|
||||
log_warning("Invalid game command.");
|
||||
*ebx = MONEY32_UNDEFINED;
|
||||
return;
|
||||
}
|
||||
|
||||
uint8 flags = *ebx & 0xFF;
|
||||
uint8 new_value = (*ebx >> 8) & 0xFF;
|
||||
|
@ -4612,6 +4626,11 @@ int ride_is_valid_for_test(int rideIndex, int goingToBeOpen, int isApplying)
|
|||
rct_xy_element trackElement, problematicTrackElement;
|
||||
|
||||
ride = GET_RIDE(rideIndex);
|
||||
if (ride->type == RIDE_TYPE_NULL)
|
||||
{
|
||||
log_warning("Invalid ride type for ride %u", rideIndex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
window_close_by_number(WC_RIDE_CONSTRUCTION, rideIndex);
|
||||
|
||||
|
@ -4870,6 +4889,12 @@ void game_command_set_ride_status(int *eax, int *ebx, int *ecx, int *edx, int *e
|
|||
RCT2_GLOBAL(RCT2_ADDRESS_NEXT_EXPENDITURE_TYPE, uint8) = RCT_EXPENDITURE_TYPE_RIDE_RUNNING_COSTS * 4;
|
||||
|
||||
ride = GET_RIDE(rideIndex);
|
||||
if (ride->type == RIDE_TYPE_NULL)
|
||||
{
|
||||
log_warning("Invalid game command for ride %u", rideIndex);
|
||||
*ebx = MONEY32_UNDEFINED;
|
||||
return;
|
||||
}
|
||||
RCT2_GLOBAL(0x00F43484, uint32) = RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + (ride->type * 8), uint32);
|
||||
|
||||
switch (targetStatus) {
|
||||
|
@ -4950,6 +4975,7 @@ void game_command_set_ride_name(int *eax, int *ebx, int *ecx, int *edx, int *esi
|
|||
if (nameChunkOffset < 0)
|
||||
nameChunkOffset = 2;
|
||||
nameChunkOffset *= 12;
|
||||
nameChunkOffset = min(nameChunkOffset, countof(newName) - 12);
|
||||
RCT2_GLOBAL(newName + nameChunkOffset + 0, uint32) = *edx;
|
||||
RCT2_GLOBAL(newName + nameChunkOffset + 4, uint32) = *ebp;
|
||||
RCT2_GLOBAL(newName + nameChunkOffset + 8, uint32) = *edi;
|
||||
|
@ -5168,6 +5194,10 @@ static int ride_get_random_colour_preset_index(uint8 ride_type)
|
|||
{
|
||||
const track_colour_preset_list *colourPresets;
|
||||
const track_colour *colours;
|
||||
if (ride_type >= 128)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
colourPresets = RCT2_ADDRESS(0x0097D934, track_colour_preset_list*)[ride_type];
|
||||
|
||||
|
@ -5271,6 +5301,11 @@ money32 ride_create(int type, int subType, int flags, int *outRideIndex, int *ou
|
|||
foundRideEntry:
|
||||
rideEntryIndex = subType;
|
||||
rideIndex = ride_get_empty_slot();
|
||||
if (subType >= 128)
|
||||
{
|
||||
log_warning("Invalid request for ride type %u", subType);
|
||||
return MONEY32_UNDEFINED;
|
||||
}
|
||||
if (rideIndex == -1) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, rct_string_id) = STR_TOO_MANY_RIDES;
|
||||
return MONEY32_UNDEFINED;
|
||||
|
@ -5293,6 +5328,11 @@ foundRideEntry:
|
|||
|
||||
ride = GET_RIDE(rideIndex);
|
||||
rideEntry = GET_RIDE_ENTRY(rideEntryIndex);
|
||||
if (rideEntry == (rct_ride_type *)0xFFFFFFFF)
|
||||
{
|
||||
log_warning("Invalid request for ride %u", rideIndex);
|
||||
return MONEY32_UNDEFINED;
|
||||
}
|
||||
ride->type = type;
|
||||
ride->subtype = rideEntryIndex;
|
||||
ride_set_colour_preset(ride, *outRideColour & 0xFF);
|
||||
|
@ -5602,7 +5642,13 @@ void game_command_demolish_ride(int *eax, int *ebx, int *ecx, int *edx, int *esi
|
|||
RCT2_GLOBAL(RCT2_ADDRESS_COMMAND_MAP_X, uint16) = 0;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_COMMAND_MAP_Y, uint16) = 0;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_COMMAND_MAP_Z, uint16) = 0;
|
||||
rct_ride *ride = &g_ride_list[ride_id];
|
||||
rct_ride *ride = GET_RIDE(ride_id);
|
||||
if (ride->type == RIDE_TYPE_NULL)
|
||||
{
|
||||
log_warning("Invalid game command for ride %u", ride_id);
|
||||
*ebx = MONEY32_UNDEFINED;
|
||||
return;
|
||||
}
|
||||
int x = 0, y = 0, z = 0;
|
||||
if(ride->overall_view != (uint16)-1){
|
||||
x = ((ride->overall_view & 0xFF) * 32) + 16;
|
||||
|
@ -5730,25 +5776,61 @@ void game_command_set_ride_appearance(int *eax, int *ebx, int *ecx, int *edx, in
|
|||
uint8 type = *ebx >> 8;
|
||||
uint8 value = *edx >> 8;
|
||||
int index = *edi;
|
||||
rct_ride *ride = &g_ride_list[ride_id];
|
||||
if (index < 0) {
|
||||
log_warning("Invalid game command, index %d out of bounds", index);
|
||||
*ebx = MONEY32_UNDEFINED;
|
||||
return;
|
||||
}
|
||||
rct_ride *ride = GET_RIDE(ride_id);
|
||||
if (ride->type == RIDE_TYPE_NULL) {
|
||||
log_warning("Invalid game command, ride_id = %u", ride_id);
|
||||
*ebx = MONEY32_UNDEFINED;
|
||||
return;
|
||||
}
|
||||
*ebx = 0;
|
||||
switch(type){
|
||||
case 0:
|
||||
if (index >= countof(ride->track_colour_main)) {
|
||||
log_warning("Invalid game command, index %d out of bounds", index);
|
||||
*ebx = MONEY32_UNDEFINED;
|
||||
break;
|
||||
}
|
||||
ride->track_colour_main[index] = value;
|
||||
gfx_invalidate_screen();
|
||||
break;
|
||||
case 1:
|
||||
if (index >= countof(ride->track_colour_additional)) {
|
||||
log_warning("Invalid game command, index %d out of bounds", index);
|
||||
*ebx = MONEY32_UNDEFINED;
|
||||
break;
|
||||
}
|
||||
ride->track_colour_additional[index] = value;
|
||||
gfx_invalidate_screen();
|
||||
break;
|
||||
case 2:
|
||||
if (index >= countof(ride->vehicle_colours)) {
|
||||
log_warning("Invalid game command, index %d out of bounds", index);
|
||||
*ebx = MONEY32_UNDEFINED;
|
||||
break;
|
||||
}
|
||||
*((uint8*)(&ride->vehicle_colours[index])) = value;
|
||||
ride_update_vehicle_colours(ride_id);
|
||||
break;
|
||||
case 3:
|
||||
if (index >= countof(ride->vehicle_colours)) {
|
||||
log_warning("Invalid game command, index %d out of bounds", index);
|
||||
*ebx = MONEY32_UNDEFINED;
|
||||
break;
|
||||
}
|
||||
*((uint8*)(&ride->vehicle_colours[index]) + 1) = value;
|
||||
ride_update_vehicle_colours(ride_id);
|
||||
break;
|
||||
case 4:
|
||||
if (index >= countof(ride->track_colour_supports)) {
|
||||
log_warning("Invalid game command, index %d out of bounds", index);
|
||||
*ebx = MONEY32_UNDEFINED;
|
||||
break;
|
||||
}
|
||||
ride->track_colour_supports[index] = value;
|
||||
gfx_invalidate_screen();
|
||||
break;
|
||||
|
@ -5767,13 +5849,17 @@ void game_command_set_ride_appearance(int *eax, int *ebx, int *ecx, int *edx, in
|
|||
gfx_invalidate_screen();
|
||||
break;
|
||||
case 7:
|
||||
if (index >= countof(ride->vehicle_colours_extended)) {
|
||||
log_warning("Invalid game command, index %d out of bounds", index);
|
||||
*ebx = MONEY32_UNDEFINED;
|
||||
break;
|
||||
}
|
||||
ride->vehicle_colours_extended[index] = value;
|
||||
ride_update_vehicle_colours(ride_id);
|
||||
break;
|
||||
}
|
||||
window_invalidate_by_number(WC_RIDE, ride_id);
|
||||
}
|
||||
*ebx = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -5786,21 +5872,28 @@ void game_command_set_ride_price(int *eax, int *ebx, int *ecx, int *edx, int *es
|
|||
uint8 ride_number;
|
||||
money16 price;
|
||||
rct_ride *ride;
|
||||
rct_ride_type *ride_type;
|
||||
rct_ride_type *rideEntry;
|
||||
bool secondary_price;
|
||||
|
||||
flags = *ebx;
|
||||
ride_number = (*edx & 0xFF);
|
||||
ride = GET_RIDE(ride_number);
|
||||
ride_type = gRideTypeList[ride->subtype];
|
||||
rideEntry = GET_RIDE_ENTRY(ride->subtype);
|
||||
price = *edi;
|
||||
secondary_price = (*edx >> 8);
|
||||
|
||||
if (rideEntry == (rct_ride_type *)0xFFFFFFFF)
|
||||
{
|
||||
log_warning("Invalid game command for ride %u", ride_number);
|
||||
*ebx = MONEY32_UNDEFINED;
|
||||
return;
|
||||
}
|
||||
|
||||
//eax
|
||||
//ebx flags
|
||||
//ecx ecx
|
||||
//edx ride_number
|
||||
//ebp ride_type
|
||||
//ebp rideEntry
|
||||
|
||||
*ebx = 0; // for cost check - changing ride price does not cost anything
|
||||
|
||||
|
@ -5809,7 +5902,7 @@ void game_command_set_ride_price(int *eax, int *ebx, int *ecx, int *edx, int *es
|
|||
if (!secondary_price) {
|
||||
shop_item = 0x1F;
|
||||
if (ride->type != RIDE_TYPE_TOILETS) {
|
||||
shop_item = ride_type->shop_item;
|
||||
shop_item = rideEntry->shop_item;
|
||||
if (shop_item == 0xFF) {
|
||||
ride->price = price;
|
||||
window_invalidate_by_class(WC_RIDE);
|
||||
|
@ -5824,7 +5917,7 @@ void game_command_set_ride_price(int *eax, int *ebx, int *ecx, int *edx, int *es
|
|||
}
|
||||
}
|
||||
else {
|
||||
shop_item = ride_type->shop_item_secondary;
|
||||
shop_item = rideEntry->shop_item_secondary;
|
||||
if (shop_item == 0xFF) {
|
||||
shop_item = RCT2_GLOBAL(0x0097D7CB + (ride->type * 4), uint8);
|
||||
if ((ride->lifecycle_flags & RIDE_LIFECYCLE_ON_RIDE_PHOTO) == 0) {
|
||||
|
@ -5841,12 +5934,12 @@ void game_command_set_ride_price(int *eax, int *ebx, int *ecx, int *edx, int *es
|
|||
}
|
||||
}
|
||||
ride = GET_RIDE(0);
|
||||
ride_type = gRideTypeList[ride->subtype];
|
||||
rideEntry = GET_RIDE_ENTRY(ride->subtype);
|
||||
uint8 count = 0;
|
||||
while (count < 0xFF) {
|
||||
if (ride->type != 0xFF) {
|
||||
if (ride->type != RIDE_TYPE_TOILETS || shop_item != 0x1F) {
|
||||
if (ride_type->shop_item == shop_item) {
|
||||
if (rideEntry->shop_item == shop_item) {
|
||||
ride->price = price;
|
||||
window_invalidate_by_number(WC_RIDE, count);
|
||||
}
|
||||
|
@ -5856,8 +5949,8 @@ void game_command_set_ride_price(int *eax, int *ebx, int *ecx, int *edx, int *es
|
|||
window_invalidate_by_number(WC_RIDE, count);
|
||||
}
|
||||
// If the shop item is the same or an on-ride photo
|
||||
if (ride_type->shop_item_secondary == shop_item ||
|
||||
(ride_type->shop_item_secondary == 0xFF &&
|
||||
if (rideEntry->shop_item_secondary == shop_item ||
|
||||
(rideEntry->shop_item_secondary == 0xFF &&
|
||||
(shop_item == 0x3 || shop_item == 0x20 || shop_item == 0x21 || shop_item == 0x22))) {
|
||||
|
||||
ride->price_secondary = price;
|
||||
|
@ -5866,7 +5959,7 @@ void game_command_set_ride_price(int *eax, int *ebx, int *ecx, int *edx, int *es
|
|||
}
|
||||
count++;
|
||||
ride++;
|
||||
ride_type = gRideTypeList[ride->subtype];
|
||||
rideEntry = GET_RIDE_ENTRY(ride->subtype);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6884,6 +6977,12 @@ void game_command_set_ride_vehicles(int *eax, int *ebx, int *ecx, int *edx, int
|
|||
value = (*edx >> 8) & 0xFF;
|
||||
|
||||
ride = GET_RIDE(rideIndex);
|
||||
if (ride->type == RIDE_TYPE_NULL)
|
||||
{
|
||||
log_warning("Invalid game command for ride %u", rideIndex);
|
||||
*ebx = MONEY32_UNDEFINED;
|
||||
return;
|
||||
}
|
||||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_NEXT_EXPENDITURE_TYPE, uint8) = RCT_EXPENDITURE_TYPE_RIDE_RUNNING_COSTS * 4;
|
||||
|
||||
|
@ -7225,6 +7324,11 @@ void game_command_place_ride_entrance_or_exit(int *eax, int *ebx, int *ecx, int
|
|||
|
||||
money32 remove_ride_entrance_or_exit(sint16 x, sint16 y, uint8 rideIndex, uint8 station_num, uint8 flags){
|
||||
rct_ride* ride = GET_RIDE(rideIndex);
|
||||
if (ride->type == RIDE_TYPE_NULL)
|
||||
{
|
||||
log_warning("Invalide ride id %u for entrance/exit removal", rideIndex);
|
||||
return MONEY32_UNDEFINED;
|
||||
}
|
||||
|
||||
if (!(flags & GAME_COMMAND_FLAG_GHOST)){
|
||||
if (!(flags & GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED) && RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint8) != 0 && !gConfigCheat.build_in_pause_mode){
|
||||
|
@ -7245,6 +7349,11 @@ money32 remove_ride_entrance_or_exit(sint16 x, sint16 y, uint8 rideIndex, uint8
|
|||
|
||||
uint8 found = 0;
|
||||
rct_map_element* mapElement = map_get_first_element_at(x / 32, y / 32);
|
||||
if (mapElement == NULL)
|
||||
{
|
||||
log_warning("Invalid coordinates for entrance/exit removal x = %d, y = %d", x, y);
|
||||
return MONEY32_UNDEFINED;
|
||||
}
|
||||
do{
|
||||
if (map_element_get_type(mapElement) != MAP_ELEMENT_TYPE_ENTRANCE)
|
||||
continue;
|
||||
|
|
|
@ -3099,7 +3099,7 @@ int save_track_design(uint8 rideIndex){
|
|||
return 1;
|
||||
}
|
||||
|
||||
path_set_extension(path, "TD6");
|
||||
path_append_extension(path, "TD6");
|
||||
|
||||
save_track_to_file(RCT2_ADDRESS(0x009D8178, rct_track_td6), path);
|
||||
|
||||
|
@ -3292,6 +3292,14 @@ void game_command_place_track_design(int* eax, int* ebx, int* ecx, int* edx, int
|
|||
rideIndex = _edi & 0xFF;
|
||||
}
|
||||
|
||||
rct_ride* ride = GET_RIDE(rideIndex);
|
||||
if (ride->type == RIDE_TYPE_NULL)
|
||||
{
|
||||
log_warning("Invalid game command for track placement, ride id = %d", rideIndex);
|
||||
*ebx = MONEY32_UNDEFINED;
|
||||
return;
|
||||
}
|
||||
|
||||
money32 cost = 0;
|
||||
if (!(flags & GAME_COMMAND_FLAG_APPLY)){
|
||||
RCT2_GLOBAL(0x00F44150, uint8) = 0;
|
||||
|
@ -3348,7 +3356,6 @@ void game_command_place_track_design(int* eax, int* ebx, int* ecx, int* edx, int
|
|||
if (num_circuits == 0) num_circuits = 1;
|
||||
game_do_command(0, GAME_COMMAND_FLAG_APPLY | (num_circuits << 8), 0, rideIndex | (9 << 8), GAME_COMMAND_SET_RIDE_SETTING, 0, 0);
|
||||
|
||||
rct_ride* ride = GET_RIDE(rideIndex);
|
||||
|
||||
ride->lifecycle_flags |= RIDE_LIFECYCLE_NOT_CUSTOM_DESIGN;
|
||||
|
||||
|
@ -4494,6 +4501,11 @@ money32 track_remove(uint8 type, uint8 sequence, sint16 originX, sint16 originY,
|
|||
|
||||
uint8 found = 0;
|
||||
rct_map_element* mapElement = map_get_first_element_at(originX / 32, originY / 32);
|
||||
if (mapElement == NULL)
|
||||
{
|
||||
log_warning("Invalid coordinates for track removal. x = %d, y = %d", originX, originY);
|
||||
return MONEY32_UNDEFINED;
|
||||
}
|
||||
do{
|
||||
if (mapElement->base_height * 8 != originZ)
|
||||
continue;
|
||||
|
@ -4781,6 +4793,12 @@ void game_command_set_brakes_speed(int *eax, int *ebx, int *ecx, int *edx, int *
|
|||
}
|
||||
|
||||
mapElement = map_get_first_element_at(x >> 5, y >> 5);
|
||||
if (mapElement == NULL)
|
||||
{
|
||||
log_warning("Invalid game command for setting brakes speed. x = %d, y = %d", x, y);
|
||||
*ebx = MONEY32_UNDEFINED;
|
||||
return;
|
||||
}
|
||||
do {
|
||||
if (mapElement->base_height * 8 != z)
|
||||
continue;
|
||||
|
|
140
src/scenario.c
140
src/scenario.c
|
@ -45,6 +45,17 @@
|
|||
#include "world/sprite.h"
|
||||
#include "world/water.h"
|
||||
|
||||
const rct_string_id ScenarioCategoryStringIds[SCENARIO_CATEGORY_COUNT] = {
|
||||
STR_BEGINNER_PARKS,
|
||||
STR_CHALLENGING_PARKS,
|
||||
STR_EXPERT_PARKS,
|
||||
STR_REAL_PARKS,
|
||||
STR_OTHER_PARKS,
|
||||
|
||||
STR_DLC_PARKS,
|
||||
STR_BUILD_YOUR_OWN_PARKS,
|
||||
};
|
||||
|
||||
static char _scenarioPath[MAX_PATH];
|
||||
static const char *_scenarioFileName = "";
|
||||
|
||||
|
@ -58,13 +69,11 @@ static void scenario_objective_check();
|
|||
* Loads only the basic information from a scenario.
|
||||
* rct2: 0x006761D6
|
||||
*/
|
||||
int scenario_load_basic(const char *path, rct_s6_header *header, rct_s6_info *info)
|
||||
bool scenario_load_basic(const char *path, rct_s6_header *header, rct_s6_info *info)
|
||||
{
|
||||
SDL_RWops* rw;
|
||||
|
||||
log_verbose("loading scenario details, %s", path);
|
||||
|
||||
rw = SDL_RWFromFile(path, "rb");
|
||||
SDL_RWops* rw = SDL_RWFromFile(path, "rb");
|
||||
if (rw != NULL) {
|
||||
// Read first chunk
|
||||
sawyercoding_read_chunk(rw, (uint8*)header);
|
||||
|
@ -72,49 +81,16 @@ int scenario_load_basic(const char *path, rct_s6_header *header, rct_s6_info *in
|
|||
// Read second chunk
|
||||
sawyercoding_read_chunk(rw, (uint8*)info);
|
||||
SDL_RWclose(rw);
|
||||
RCT2_GLOBAL(0x009AA00C, uint8) = 0;
|
||||
|
||||
// Get filename
|
||||
utf8 filename[MAX_PATH];
|
||||
const char *temp_filename = path_get_filename(path);
|
||||
int len = strnlen(temp_filename, MAX_PATH);
|
||||
safe_strncpy(filename, temp_filename, MAX_PATH);
|
||||
if (len == MAX_PATH)
|
||||
{
|
||||
filename[MAX_PATH - 1] = '\0';
|
||||
log_warning("truncated string %s", filename);
|
||||
}
|
||||
path_remove_extension(filename);
|
||||
|
||||
rct_string_id localisedStringIds[3];
|
||||
if (language_get_localised_scenario_strings(filename, localisedStringIds)) {
|
||||
if (localisedStringIds[0] != (rct_string_id)STR_NONE) {
|
||||
safe_strncpy(info->name, language_get_string(localisedStringIds[0]), 64);
|
||||
}
|
||||
if (localisedStringIds[2] != (rct_string_id)STR_NONE) {
|
||||
safe_strncpy(info->details, language_get_string(localisedStringIds[2]), 256);
|
||||
}
|
||||
} else {
|
||||
// Checks for a scenario string object (possibly for localisation)
|
||||
if ((info->entry.flags & 0xFF) != 255) {
|
||||
if (object_get_scenario_text(&info->entry)) {
|
||||
rct_stex_entry* stex_entry = RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TEXT_TEMP_CHUNK, rct_stex_entry*);
|
||||
format_string(info->name, stex_entry->scenario_name, NULL);
|
||||
format_string(info->details, stex_entry->details, NULL);
|
||||
RCT2_GLOBAL(0x009AA00C, uint8) = stex_entry->var_06;
|
||||
object_free_scenario_text();
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
return true;
|
||||
} else {
|
||||
log_error("invalid scenario, %s", path);
|
||||
SDL_RWclose(rw);
|
||||
return false;
|
||||
}
|
||||
SDL_RWclose(rw);
|
||||
}
|
||||
|
||||
log_error("invalid scenario, %s", path);
|
||||
// RCT2_GLOBAL(RCT2_ADDRESS_ERROR_TYPE, sint8) = -1;
|
||||
// RCT2_GLOBAL(RCT2_ADDRESS_ERROR_STRING_ID, sint16) = 3011;
|
||||
return 0;
|
||||
log_error("unable to open scenario, %s", path);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -219,19 +195,6 @@ int scenario_load(const char *path)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x00678282
|
||||
* scenario (ebx)
|
||||
*/
|
||||
int scenario_load_and_play(const rct_scenario_basic *scenario)
|
||||
{
|
||||
char path[MAX_PATH];
|
||||
|
||||
substitute_path(path, RCT2_ADDRESS(RCT2_ADDRESS_SCENARIOS_PATH, char), scenario->path);
|
||||
return scenario_load_and_play_from_path(path);
|
||||
}
|
||||
|
||||
int scenario_load_and_play_from_path(const char *path)
|
||||
{
|
||||
window_close_construction_windows();
|
||||
|
@ -316,13 +279,12 @@ void scenario_begin()
|
|||
safe_strncpy((char*)RCT2_ADDRESS_SCENARIO_NAME, s6Info->name, 64);
|
||||
|
||||
{
|
||||
// Get filename
|
||||
utf8 filename[MAX_PATH];
|
||||
safe_strncpy(filename, _scenarioFileName, sizeof(filename));
|
||||
path_remove_extension(filename);
|
||||
utf8 normalisedName[64];
|
||||
safe_strncpy(normalisedName, s6Info->name, sizeof(normalisedName));
|
||||
scenario_normalise_name(normalisedName);
|
||||
|
||||
rct_string_id localisedStringIds[3];
|
||||
if (language_get_localised_scenario_strings(filename, localisedStringIds)) {
|
||||
if (language_get_localised_scenario_strings(normalisedName, localisedStringIds)) {
|
||||
if (localisedStringIds[0] != (rct_string_id)STR_NONE) {
|
||||
safe_strncpy((char*)RCT2_ADDRESS_SCENARIO_NAME, language_get_string(localisedStringIds[0]), 32);
|
||||
}
|
||||
|
@ -437,29 +399,29 @@ void scenario_failure()
|
|||
*/
|
||||
void scenario_success()
|
||||
{
|
||||
int i;
|
||||
rct_scenario_basic* scenario;
|
||||
uint32 current_val = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_COMPANY_VALUE, uint32);
|
||||
const money32 companyValue = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_COMPANY_VALUE, money32);
|
||||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_COMPLETED_COMPANY_VALUE, uint32) = current_val;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_COMPLETED_COMPANY_VALUE, uint32) = companyValue;
|
||||
peep_applause();
|
||||
|
||||
for (i = 0; i < gScenarioListCount; i++) {
|
||||
scenario = &gScenarioList[i];
|
||||
|
||||
if (strequals(scenario->path, _scenarioFileName, 256, true)) {
|
||||
// Check if record company value has been broken
|
||||
if ((scenario->flags & SCENARIO_FLAGS_COMPLETED) && scenario->company_value >= current_val)
|
||||
break;
|
||||
scenario_index_entry *scenario = scenario_list_find_by_filename(_scenarioFileName);
|
||||
if (scenario != NULL) {
|
||||
// Check if record company value has been broken
|
||||
if (scenario->highscore == NULL || scenario->highscore->company_value < companyValue) {
|
||||
if (scenario->highscore == NULL) {
|
||||
scenario->highscore = scenario_highscore_insert();
|
||||
} else {
|
||||
scenario_highscore_free(scenario->highscore);
|
||||
}
|
||||
scenario->highscore->fileName = _strdup(path_get_filename(scenario->path));
|
||||
scenario->highscore->name = NULL;
|
||||
scenario->highscore->company_value = companyValue;
|
||||
scenario->highscore->timestamp = platform_get_datetime_now_utc();
|
||||
|
||||
// Allow name entry
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) |= PARK_FLAGS_SCENARIO_COMPLETE_NAME_INPUT;
|
||||
scenario->company_value = current_val;
|
||||
scenario->flags |= SCENARIO_FLAGS_COMPLETED;
|
||||
scenario->completed_by[0] = 0;
|
||||
RCT2_GLOBAL(0x013587C0, uint32) = current_val;
|
||||
RCT2_GLOBAL(0x013587C0, money32) = companyValue;
|
||||
scenario_scores_save();
|
||||
break;
|
||||
}
|
||||
}
|
||||
scenario_end();
|
||||
|
@ -471,21 +433,13 @@ void scenario_success()
|
|||
*/
|
||||
void scenario_success_submit_name(const char *name)
|
||||
{
|
||||
int i;
|
||||
rct_scenario_basic* scenario;
|
||||
uint32 scenarioWinCompanyValue;
|
||||
|
||||
for (i = 0; i < gScenarioListCount; i++) {
|
||||
scenario = &gScenarioList[i];
|
||||
|
||||
if (strequals(scenario->path, _scenarioFileName, 256, true)) {
|
||||
scenarioWinCompanyValue = RCT2_GLOBAL(0x013587C0, uint32);
|
||||
if (scenario->company_value == scenarioWinCompanyValue) {
|
||||
safe_strncpy(scenario->completed_by, name, 64);
|
||||
safe_strncpy((char*)0x013587D8, name, 32);
|
||||
scenario_scores_save();
|
||||
}
|
||||
break;
|
||||
scenario_index_entry *scenario = scenario_list_find_by_filename(_scenarioFileName);
|
||||
if (scenario != NULL) {
|
||||
money32 scenarioWinCompanyValue = RCT2_GLOBAL(0x013587C0, money32);
|
||||
if (scenario->highscore->company_value == scenarioWinCompanyValue) {
|
||||
scenario->highscore->name = _strdup(name);
|
||||
safe_strncpy((char*)0x013587D8, name, 32);
|
||||
scenario_scores_save();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
183
src/scenario.h
183
src/scenario.h
|
@ -72,6 +72,17 @@ typedef struct {
|
|||
uint32 scenario_count; // 0x0C
|
||||
} rct_scenario_scores_header;
|
||||
|
||||
typedef enum {
|
||||
SCENARIO_SOURCE_RCT1,
|
||||
SCENARIO_SOURCE_RCT1_AA,
|
||||
SCENARIO_SOURCE_RCT1_LL,
|
||||
SCENARIO_SOURCE_RCT2,
|
||||
SCENARIO_SOURCE_RCT2_WW,
|
||||
SCENARIO_SOURCE_RCT2_TT,
|
||||
SCENARIO_SOURCE_REAL,
|
||||
SCENARIO_SOURCE_OTHER
|
||||
} scenario_source;
|
||||
|
||||
/**
|
||||
* Scenario basic structure, mainly for scenario select
|
||||
* size: 0x02B0
|
||||
|
@ -89,6 +100,8 @@ typedef struct {
|
|||
sint32 flags; // 0x0268
|
||||
uint32 company_value; // 0x026C
|
||||
char completed_by[64]; // 0x0270
|
||||
// uint8 source_game; // new in OpenRCT2
|
||||
// sint16 source_index; // new in OpenRCT2
|
||||
} rct_scenario_basic;
|
||||
|
||||
typedef struct {
|
||||
|
@ -385,11 +398,18 @@ enum {
|
|||
#define S6_MAGIC_NUMBER 0x00031144
|
||||
|
||||
enum {
|
||||
// RCT2 categories (keep order)
|
||||
SCENARIO_CATEGORY_BEGINNER,
|
||||
SCENARIO_CATEGORY_CHALLENGING,
|
||||
SCENARIO_CATEGORY_EXPERT,
|
||||
SCENARIO_CATEGORY_REAL,
|
||||
SCENARIO_CATEGORY_BUILDYOUROWN
|
||||
SCENARIO_CATEGORY_OTHER,
|
||||
|
||||
// OpenRCT2 categories
|
||||
SCENARIO_CATEGORY_DLC,
|
||||
SCENARIO_CATEGORY_BUILD_YOUR_OWN,
|
||||
|
||||
SCENARIO_CATEGORY_COUNT
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -407,20 +427,61 @@ enum {
|
|||
OBJECTIVE_MONTHLY_FOOD_INCOME
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
utf8 *fileName;
|
||||
utf8 *name;
|
||||
money32 company_value;
|
||||
datetime64 timestamp;
|
||||
} scenario_highscore_entry;
|
||||
|
||||
typedef struct {
|
||||
utf8 path[MAX_PATH];
|
||||
uint64 timestamp;
|
||||
|
||||
// Category / sequence
|
||||
uint8 category;
|
||||
uint8 source_game;
|
||||
sint16 source_index;
|
||||
uint16 sc_id;
|
||||
|
||||
// Objective
|
||||
uint8 objective_type;
|
||||
uint8 objective_arg_1;
|
||||
sint32 objective_arg_2;
|
||||
sint16 objective_arg_3;
|
||||
scenario_highscore_entry *highscore;
|
||||
|
||||
utf8 name[64];
|
||||
utf8 details[256];
|
||||
} scenario_index_entry;
|
||||
|
||||
typedef struct {
|
||||
const utf8 *title;
|
||||
uint8 id;
|
||||
uint8 source;
|
||||
sint32 index;
|
||||
uint8 category;
|
||||
} source_desc;
|
||||
|
||||
extern const rct_string_id ScenarioCategoryStringIds[SCENARIO_CATEGORY_COUNT];
|
||||
|
||||
// Scenario list
|
||||
extern int gScenarioListCount;
|
||||
extern int gScenarioListCapacity;
|
||||
extern rct_scenario_basic *gScenarioList;
|
||||
extern scenario_index_entry *gScenarioList;
|
||||
|
||||
extern char gScenarioSavePath[MAX_PATH];
|
||||
extern int gFirstTimeSave;
|
||||
|
||||
int scenario_scores_save();
|
||||
bool scenario_scores_save();
|
||||
void scenario_load_list();
|
||||
rct_scenario_basic *get_scenario_by_filename(const char *filename);
|
||||
int scenario_load_basic(const char *path, rct_s6_header *header, rct_s6_info *info);
|
||||
void scenario_list_dispose();
|
||||
scenario_index_entry *scenario_list_find_by_filename(const utf8 *filename);
|
||||
scenario_index_entry *scenario_list_find_by_path(const utf8 *path);
|
||||
scenario_highscore_entry *scenario_highscore_insert();
|
||||
void scenario_highscore_free(scenario_highscore_entry *highscore);
|
||||
bool scenario_load_basic(const char *path, rct_s6_header *header, rct_s6_info *info);
|
||||
int scenario_load(const char *path);
|
||||
int scenario_load_and_play(const rct_scenario_basic *scenario);
|
||||
int scenario_load_and_play_from_path(const char *path);
|
||||
void scenario_begin();
|
||||
void scenario_update();
|
||||
|
@ -436,4 +497,114 @@ void scenario_success();
|
|||
void scenario_success_submit_name(const char *name);
|
||||
void scenario_autosave_check();
|
||||
|
||||
bool scenario_get_source_desc(const utf8 *name, source_desc *outDesc);
|
||||
bool scenario_get_source_desc_by_id(uint8 id, source_desc *outDesc);
|
||||
void scenario_normalise_name(utf8 *name);
|
||||
|
||||
// RCT1 scenario index map
|
||||
enum {
|
||||
SC_UNIDENTIFIED = 255,
|
||||
|
||||
// RCT
|
||||
SC_FOREST_FRONTIERS = 0,
|
||||
SC_DYNAMITE_DUNES,
|
||||
SC_LEAFY_LAKES,
|
||||
SC_DIAMOND_HEIGHTS,
|
||||
SC_EVERGREEN_GARDENS,
|
||||
SC_BUMBLY_BEACH,
|
||||
SC_TRINITY_ISLANDS,
|
||||
SC_KATIES_DREAMLAND,
|
||||
SC_POKEY_PARK,
|
||||
SC_WHITE_WATER_PARK,
|
||||
SC_MILLENNIUM_MINES,
|
||||
SC_KARTS_COASTERS,
|
||||
SC_MELS_WORLD,
|
||||
SC_MYSTIC_MOUNTAIN,
|
||||
SC_PACIFIC_PYRAMIDS,
|
||||
SC_CRUMBLY_WOODS,
|
||||
SC_PARADISE_PIER,
|
||||
SC_LIGHTNING_PEAKS,
|
||||
SC_IVORY_TOWERS,
|
||||
SC_RAINBOW_VALLEY,
|
||||
SC_THUNDER_ROCK,
|
||||
SC_MEGA_PARK,
|
||||
|
||||
// Loopy Landscapes
|
||||
SC_ICEBERG_ISLANDS,
|
||||
SC_VOLCANIA,
|
||||
SC_ARID_HEIGHTS,
|
||||
SC_RAZOR_ROCKS,
|
||||
SC_CRATER_LAKE,
|
||||
SC_VERTIGO_VIEWS,
|
||||
SC_PARADISE_PIER_2,
|
||||
SC_DRAGONS_COVE,
|
||||
SC_GOOD_KNIGHT_PARK,
|
||||
SC_WACKY_WARREN,
|
||||
|
||||
// Special
|
||||
ALTON_TOWERS,
|
||||
FORT_ANACHRONISM,
|
||||
|
||||
// Added Attractions
|
||||
SC_WHISPERING_CLIFFS = 40,
|
||||
SC_THREE_MONKEYS_PARK,
|
||||
SC_CANARY_MINES,
|
||||
SC_BARONY_BRIDGE,
|
||||
SC_FUNTOPIA,
|
||||
SC_HAUNTED_HARBOR,
|
||||
SC_FUN_FORTRESS,
|
||||
SC_FUTURE_WORLD,
|
||||
SC_GENTLE_GLEN,
|
||||
SC_JOLLY_JUNGLE,
|
||||
SC_HYDRO_HILLS,
|
||||
SC_SPRIGHTLY_PARK,
|
||||
SC_MAGIC_QUARTERS,
|
||||
SC_FRUIT_FARM,
|
||||
SC_BUTTERFLY_DAM,
|
||||
SC_COASTER_CANYON,
|
||||
SC_THUNDERSTORM_PARK,
|
||||
SC_HARMONIC_HILLS,
|
||||
SC_ROMAN_VILLAGE,
|
||||
SC_SWAMP_COVE,
|
||||
SC_ADRENALINE_HEIGHTS,
|
||||
SC_UTOPIA,
|
||||
SC_ROTTING_HEIGHTS,
|
||||
SC_FIASCO_FOREST,
|
||||
SC_PICKLE_PARK,
|
||||
SC_GIGGLE_DOWNS,
|
||||
SC_MINERAL_PARK,
|
||||
SC_COASTER_CRAZY,
|
||||
SC_URBAN_PARK,
|
||||
SC_GEOFFREY_GARDENS,
|
||||
|
||||
// Special
|
||||
SC_HEIDE_PARK,
|
||||
SC_PCPLAYER,
|
||||
SC_PCGW,
|
||||
SC_GAMEPLAY,
|
||||
SC_BLACKPOOL_PLEASURE_BEACH,
|
||||
|
||||
// Loopy Landscapes
|
||||
SC_GRAND_GLACIER = 80,
|
||||
SC_CRAZY_CRATERS,
|
||||
SC_DUSTY_DESERT,
|
||||
SC_WOODWORM_PARK,
|
||||
SC_ICARUS_PARK,
|
||||
SC_SUNNY_SWAMPS,
|
||||
SC_FRIGHTMARE_HILLS,
|
||||
SC_THUNDER_ROCKS,
|
||||
SC_OCTAGON_PARK,
|
||||
SC_PLEASURE_ISLAND,
|
||||
SC_ICICLE_WORLDS,
|
||||
SC_SOUTHERN_SANDS,
|
||||
SC_TINY_TOWERS,
|
||||
SC_NEVERMORE_PARK,
|
||||
SC_PACIFICA,
|
||||
SC_URBAN_JUNGLE,
|
||||
SC_TERROR_TOWN,
|
||||
SC_MEGAWORLD_PARK,
|
||||
SC_VENUS_PONDS,
|
||||
SC_MICRO_PARK,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -19,228 +19,535 @@
|
|||
*****************************************************************************/
|
||||
|
||||
#include "addresses.h"
|
||||
#include "config.h"
|
||||
#include "localisation/localisation.h"
|
||||
#include "platform/platform.h"
|
||||
#include "util/util.h"
|
||||
#include "scenario.h"
|
||||
#include "util/util.h"
|
||||
|
||||
// Scenario list
|
||||
int gScenarioListCount = 0;
|
||||
int gScenarioListCapacity = 0;
|
||||
rct_scenario_basic *gScenarioList = NULL;
|
||||
scenario_index_entry *gScenarioList = NULL;
|
||||
|
||||
static void scenario_list_add(const char *path);
|
||||
int gScenarioHighscoreListCount = 0;
|
||||
int gScenarioHighscoreListCapacity = 0;
|
||||
scenario_highscore_entry *gScenarioHighscoreList = NULL;
|
||||
|
||||
static void scenario_list_include(const utf8 *directory);
|
||||
static void scenario_list_add(const utf8 *path, uint64 timestamp);
|
||||
static void scenario_list_sort();
|
||||
static int scenario_list_sort_compare(const void *a, const void *b);
|
||||
static int scenario_scores_load();
|
||||
static int scenario_list_sort_by_category(const void *a, const void *b);
|
||||
static int scenario_list_sort_by_index(const void *a, const void *b);
|
||||
static void scenario_translate(scenario_index_entry *scenarioEntry, const rct_object_entry *stexObjectEntry);
|
||||
|
||||
rct_scenario_basic *get_scenario_by_filename(const char *filename)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < gScenarioListCount; i++)
|
||||
if (strcmp(gScenarioList[i].path, filename) == 0)
|
||||
return &gScenarioList[i];
|
||||
|
||||
return NULL;
|
||||
}
|
||||
static bool scenario_scores_load();
|
||||
static void scenario_scores_legacy_get_path(utf8 *outPath);
|
||||
static bool scenario_scores_legacy_load(const utf8 *path);
|
||||
static void scenario_highscore_remove(scenario_highscore_entry *higscore);
|
||||
static void scenario_highscore_list_dispose();
|
||||
static utf8 *io_read_string(SDL_RWops *file);
|
||||
static void io_write_string(SDL_RWops *file, utf8 *source);
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006775A8
|
||||
* Searches and grabs the metadata for all the scenarios.
|
||||
*/
|
||||
void scenario_load_list()
|
||||
{
|
||||
int i, enumFileHandle;
|
||||
file_info enumFileInfo;
|
||||
utf8 directory[MAX_PATH];
|
||||
|
||||
// Load scores
|
||||
// Clear scenario list
|
||||
gScenarioListCount = 0;
|
||||
|
||||
// Get scenario directory from RCT2
|
||||
safe_strncpy(directory, gConfigGeneral.game_path, sizeof(directory));
|
||||
safe_strcat_path(directory, "Scenarios", sizeof(directory));
|
||||
scenario_list_include(directory);
|
||||
|
||||
// Get scenario directory from user directory
|
||||
platform_get_user_directory(directory, "scenario");
|
||||
scenario_list_include(directory);
|
||||
|
||||
scenario_list_sort();
|
||||
scenario_scores_load();
|
||||
|
||||
// Set all scenarios to be invisible
|
||||
for (i = 0; i < gScenarioListCount; i++)
|
||||
gScenarioList[i].flags &= ~SCENARIO_FLAGS_VISIBLE;
|
||||
|
||||
// Enumerate through each scenario in the directory
|
||||
enumFileHandle = platform_enumerate_files_begin(RCT2_ADDRESS(RCT2_ADDRESS_SCENARIOS_PATH, char));
|
||||
if (enumFileHandle != INVALID_HANDLE) {
|
||||
while (platform_enumerate_files_next(enumFileHandle, &enumFileInfo)) {
|
||||
scenario_list_add(enumFileInfo.path);
|
||||
}
|
||||
platform_enumerate_files_end(enumFileHandle);
|
||||
}
|
||||
|
||||
// Sort alphabetically
|
||||
scenario_list_sort();
|
||||
|
||||
// Save the scores
|
||||
scenario_scores_save();
|
||||
utf8 scoresPath[MAX_PATH];
|
||||
scenario_scores_legacy_get_path(scoresPath);
|
||||
scenario_scores_legacy_load(scoresPath);
|
||||
scenario_scores_legacy_load(get_file_path(PATH_ID_SCORES));
|
||||
}
|
||||
|
||||
static void scenario_list_add(const char *path)
|
||||
static void scenario_list_include(const utf8 *directory)
|
||||
{
|
||||
char scenarioPath[MAX_PATH];
|
||||
rct_scenario_basic *scenario;
|
||||
int handle;
|
||||
file_info fileInfo;
|
||||
|
||||
// Scenarios in this directory
|
||||
utf8 pattern[MAX_PATH];
|
||||
safe_strncpy(pattern, directory, sizeof(pattern));
|
||||
safe_strcat_path(pattern, "*.sc6", sizeof(pattern));
|
||||
|
||||
handle = platform_enumerate_files_begin(pattern);
|
||||
while (platform_enumerate_files_next(handle, &fileInfo)) {
|
||||
utf8 path[MAX_PATH];
|
||||
safe_strncpy(path, directory, sizeof(pattern));
|
||||
safe_strcat_path(path, fileInfo.path, sizeof(pattern));
|
||||
scenario_list_add(path, fileInfo.last_modified);
|
||||
}
|
||||
platform_enumerate_files_end(handle);
|
||||
|
||||
// Include sub-directories
|
||||
utf8 subDirectory[MAX_PATH];
|
||||
handle = platform_enumerate_directories_begin(directory);
|
||||
while (platform_enumerate_directories_next(handle, subDirectory)) {
|
||||
utf8 path[MAX_PATH];
|
||||
safe_strncpy(path, directory, sizeof(pattern));
|
||||
safe_strcat_path(path, subDirectory, sizeof(pattern));
|
||||
scenario_list_include(path);
|
||||
}
|
||||
platform_enumerate_directories_end(handle);
|
||||
}
|
||||
|
||||
static void scenario_list_add(const utf8 *path, uint64 timestamp)
|
||||
{
|
||||
// Load the basic scenario information
|
||||
rct_s6_header s6Header;
|
||||
rct_s6_info s6Info;
|
||||
|
||||
// Get absolute path
|
||||
substitute_path(scenarioPath, RCT2_ADDRESS(RCT2_ADDRESS_SCENARIOS_PATH, char), path);
|
||||
|
||||
// Load the basic scenario information
|
||||
if (!scenario_load_basic(scenarioPath, &s6Header, &s6Info))
|
||||
if (!scenario_load_basic(path, &s6Header, &s6Info)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Ignore scenarios where first header byte is not 255
|
||||
if (s6Info.editor_step != 255)
|
||||
return;
|
||||
scenario_index_entry *newEntry = NULL;
|
||||
|
||||
// Check if scenario already exists in list, likely if in scores
|
||||
scenario = get_scenario_by_filename(path);
|
||||
if (scenario != NULL) {
|
||||
// Update the scenario information
|
||||
scenario->flags |= SCENARIO_FLAGS_VISIBLE;
|
||||
scenario->category = s6Info.category;
|
||||
scenario->objective_type = s6Info.objective_type;
|
||||
scenario->objective_arg_1 = s6Info.objective_arg_1;
|
||||
scenario->objective_arg_2 = s6Info.objective_arg_2;
|
||||
scenario->objective_arg_3 = s6Info.objective_arg_3;
|
||||
safe_strncpy(scenario->name, s6Info.name, 64);
|
||||
safe_strncpy(scenario->details, s6Info.details, 256);
|
||||
} else {
|
||||
// Check if the scenario list buffer has room for another scenario
|
||||
if (gScenarioListCount >= gScenarioListCapacity) {
|
||||
// Allocate more room
|
||||
gScenarioListCapacity += 16;
|
||||
gScenarioList = realloc(gScenarioList, gScenarioListCapacity * sizeof(rct_scenario_basic));
|
||||
const utf8 *filename = path_get_filename(path);
|
||||
scenario_index_entry *existingEntry = scenario_list_find_by_filename(filename);
|
||||
if (existingEntry != NULL) {
|
||||
bool bail = false;
|
||||
const utf8 *conflictPath;
|
||||
if (existingEntry->timestamp > timestamp) {
|
||||
// Existing entry is more recent
|
||||
conflictPath = existingEntry->path;
|
||||
|
||||
// Overwrite existing entry with this one
|
||||
newEntry = existingEntry;
|
||||
} else {
|
||||
// This entry is more recent
|
||||
conflictPath = path;
|
||||
bail = true;
|
||||
}
|
||||
printf("Scenario conflict: '%s' ignored because it is newer.\n", conflictPath);
|
||||
if (bail) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Increment the number of scenarios
|
||||
scenario = &gScenarioList[gScenarioListCount];
|
||||
if (newEntry == NULL) {
|
||||
// Increase list size
|
||||
if (gScenarioListCount == gScenarioListCapacity) {
|
||||
gScenarioListCapacity = max(8, gScenarioListCapacity * 2);
|
||||
gScenarioList = (scenario_index_entry*)realloc(gScenarioList, gScenarioListCapacity * sizeof(scenario_index_entry));
|
||||
}
|
||||
newEntry = &gScenarioList[gScenarioListCount];
|
||||
gScenarioListCount++;
|
||||
}
|
||||
|
||||
// Add this new scenario to the list
|
||||
safe_strncpy(scenario->path, path, 256);
|
||||
scenario->flags = SCENARIO_FLAGS_VISIBLE;
|
||||
if (RCT2_GLOBAL(0x009AA00C, uint8) & 1)
|
||||
scenario->flags |= SCENARIO_FLAGS_SIXFLAGS;
|
||||
scenario->category = s6Info.category;
|
||||
scenario->objective_type = s6Info.objective_type;
|
||||
scenario->objective_arg_1 = s6Info.objective_arg_1;
|
||||
scenario->objective_arg_2 = s6Info.objective_arg_2;
|
||||
scenario->objective_arg_3 = s6Info.objective_arg_3;
|
||||
safe_strncpy(scenario->name, s6Info.name, 64);
|
||||
safe_strncpy(scenario->details, s6Info.details, 256);
|
||||
// Set new entry
|
||||
safe_strncpy(newEntry->path, path, sizeof(newEntry->path));
|
||||
newEntry->timestamp = timestamp;
|
||||
newEntry->category = s6Info.category;
|
||||
newEntry->objective_type = s6Info.objective_type;
|
||||
newEntry->objective_arg_1 = s6Info.objective_arg_1;
|
||||
newEntry->objective_arg_2 = s6Info.objective_arg_2;
|
||||
newEntry->objective_arg_3 = s6Info.objective_arg_3;
|
||||
newEntry->highscore = NULL;
|
||||
safe_strncpy(newEntry->name, s6Info.name, sizeof(newEntry->name));
|
||||
safe_strncpy(newEntry->details, s6Info.details, sizeof(newEntry->details));
|
||||
|
||||
// Normalise the name to make the scenario as recognisable as possible.
|
||||
scenario_normalise_name(newEntry->name);
|
||||
|
||||
// Look up and store information regarding the origins of this scenario.
|
||||
source_desc desc;
|
||||
if (scenario_get_source_desc(newEntry->name, &desc)) {
|
||||
newEntry->sc_id = desc.id;
|
||||
newEntry->source_index = desc.index;
|
||||
newEntry->source_game = desc.source;
|
||||
newEntry->category = desc.category;
|
||||
} else {
|
||||
newEntry->sc_id = SC_UNIDENTIFIED;
|
||||
newEntry->source_index = -1;
|
||||
if (newEntry->category == SCENARIO_CATEGORY_REAL) {
|
||||
newEntry->source_game = SCENARIO_SOURCE_REAL;
|
||||
} else {
|
||||
newEntry->source_game = SCENARIO_SOURCE_OTHER;
|
||||
}
|
||||
}
|
||||
|
||||
scenario_translate(newEntry, &s6Info.entry);
|
||||
}
|
||||
|
||||
static void scenario_translate(scenario_index_entry *scenarioEntry, const rct_object_entry *stexObjectEntry)
|
||||
{
|
||||
rct_string_id localisedStringIds[3];
|
||||
if (language_get_localised_scenario_strings(scenarioEntry->name, localisedStringIds)) {
|
||||
if (localisedStringIds[0] != (rct_string_id)STR_NONE) {
|
||||
safe_strncpy(scenarioEntry->name, language_get_string(localisedStringIds[0]), 64);
|
||||
}
|
||||
if (localisedStringIds[2] != (rct_string_id)STR_NONE) {
|
||||
safe_strncpy(scenarioEntry->details, language_get_string(localisedStringIds[2]), 256);
|
||||
}
|
||||
} else {
|
||||
// Checks for a scenario string object (possibly for localisation)
|
||||
if ((stexObjectEntry->flags & 0xFF) != 255) {
|
||||
if (object_get_scenario_text((rct_object_entry*)stexObjectEntry)) {
|
||||
rct_stex_entry* stex_entry = RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TEXT_TEMP_CHUNK, rct_stex_entry*);
|
||||
format_string(scenarioEntry->name, stex_entry->scenario_name, NULL);
|
||||
format_string(scenarioEntry->details, stex_entry->details, NULL);
|
||||
object_free_scenario_text();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort the list of scenarios. This used to be an insertion sort which took
|
||||
* place as each scenario loaded. It has now been changed to a quicksort which
|
||||
* takes place after all the scenarios have been loaded in.
|
||||
* rct2: 0x00677C3B
|
||||
*/
|
||||
static void scenario_list_sort()
|
||||
void scenario_list_dispose()
|
||||
{
|
||||
qsort(gScenarioList, gScenarioListCount, sizeof(rct_scenario_basic), scenario_list_sort_compare);
|
||||
gScenarioListCapacity = 0;
|
||||
gScenarioListCount = 0;
|
||||
SafeFree(gScenarioList);
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic scenario information compare function for sorting.
|
||||
* rct2: 0x00677C08
|
||||
*/
|
||||
static int scenario_list_sort_compare(const void *a, const void *b)
|
||||
static void scenario_list_sort()
|
||||
{
|
||||
return strcmp(((rct_scenario_basic*)a)->name, ((rct_scenario_basic*)b)->name);
|
||||
int(*compareFunc)(void const*, void const*);
|
||||
|
||||
compareFunc = gConfigGeneral.scenario_select_mode == SCENARIO_SELECT_MODE_ORIGIN ?
|
||||
scenario_list_sort_by_index :
|
||||
scenario_list_sort_by_category;
|
||||
|
||||
qsort(gScenarioList, gScenarioListCount, sizeof(scenario_index_entry), compareFunc);
|
||||
}
|
||||
|
||||
static int scenario_list_category_compare(int categoryA, int categoryB)
|
||||
{
|
||||
if (categoryA == categoryB) return 0;
|
||||
if (categoryA == SCENARIO_CATEGORY_DLC) return -1;
|
||||
if (categoryB == SCENARIO_CATEGORY_DLC) return 1;
|
||||
if (categoryA == SCENARIO_CATEGORY_BUILD_YOUR_OWN) return -1;
|
||||
if (categoryB == SCENARIO_CATEGORY_BUILD_YOUR_OWN) return 1;
|
||||
return sgn(categoryA - categoryB);
|
||||
}
|
||||
|
||||
static int scenario_list_sort_by_category(const void *a, const void *b)
|
||||
{
|
||||
const scenario_index_entry *entryA = (const scenario_index_entry*)a;
|
||||
const scenario_index_entry *entryB = (const scenario_index_entry*)b;
|
||||
|
||||
// Order by category
|
||||
if (entryA->category != entryB->category) {
|
||||
return scenario_list_category_compare(entryA->category, entryB->category);
|
||||
}
|
||||
|
||||
// Then by source game / name
|
||||
switch (entryA->category) {
|
||||
default:
|
||||
if (entryA->source_game != entryB->source_game) {
|
||||
return entryA->source_game - entryB->source_game;
|
||||
}
|
||||
return strcmp(entryA->name, entryB->name);
|
||||
case SCENARIO_CATEGORY_REAL:
|
||||
case SCENARIO_CATEGORY_OTHER:
|
||||
return strcmp(entryA->name, entryB->name);
|
||||
}
|
||||
}
|
||||
|
||||
static int scenario_list_sort_by_index(const void *a, const void *b)
|
||||
{
|
||||
const scenario_index_entry *entryA = (const scenario_index_entry*)a;
|
||||
const scenario_index_entry *entryB = (const scenario_index_entry*)b;
|
||||
|
||||
// Order by source game
|
||||
if (entryA->source_game != entryB->source_game) {
|
||||
return entryA->source_game - entryB->source_game;
|
||||
}
|
||||
|
||||
// Then by index / category / name
|
||||
uint8 sourceGame = entryA->source_game;
|
||||
switch (sourceGame) {
|
||||
default:
|
||||
if (entryA->source_index == -1 && entryB->source_index == -1) {
|
||||
if (entryA->category == entryB->category) {
|
||||
return scenario_list_sort_by_category(a, b);
|
||||
} else {
|
||||
return scenario_list_category_compare(entryA->category, entryB->category);
|
||||
}
|
||||
} else if (entryA->source_index == -1) {
|
||||
return 1;
|
||||
} else if (entryB->source_index == -1) {
|
||||
return -1;
|
||||
} else {
|
||||
return entryA->source_index - entryB->source_index;
|
||||
}
|
||||
case SCENARIO_SOURCE_REAL:
|
||||
return scenario_list_sort_by_category(a, b);
|
||||
}
|
||||
}
|
||||
|
||||
scenario_index_entry *scenario_list_find_by_filename(const utf8 *filename)
|
||||
{
|
||||
for (int i = 0; i < gScenarioListCount; i++) {
|
||||
const utf8 *scenarioFilename = path_get_filename(gScenarioList[i].path);
|
||||
if (_strcmpi(filename, scenarioFilename) == 0) {
|
||||
return &gScenarioList[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
scenario_index_entry *scenario_list_find_by_path(const utf8 *path)
|
||||
{
|
||||
for (int i = 0; i < gScenarioListCount; i++) {
|
||||
if (_strcmpi(path, gScenarioList[i].path) == 0) {
|
||||
return &gScenarioList[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the path for the scenario scores path.
|
||||
*/
|
||||
static void scenario_scores_get_path(utf8 *outPath)
|
||||
{
|
||||
platform_get_user_directory(outPath, NULL);
|
||||
strcat(outPath, "highscores.dat");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the path for the scenario scores path.
|
||||
*/
|
||||
static void scenario_scores_legacy_get_path(utf8 *outPath)
|
||||
{
|
||||
platform_get_user_directory(outPath, NULL);
|
||||
strcat(outPath, "scores.dat");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006775A8
|
||||
* Loads the original scores.dat file and replaces any highscores that
|
||||
* are better for matching scenarios.
|
||||
*/
|
||||
static int scenario_scores_load()
|
||||
static bool scenario_scores_legacy_load(const utf8 *path)
|
||||
{
|
||||
SDL_RWops *file;
|
||||
char scoresPath[MAX_PATH];
|
||||
|
||||
scenario_scores_get_path(scoresPath);
|
||||
|
||||
// Free scenario list if already allocated
|
||||
if (gScenarioList != NULL) {
|
||||
free(gScenarioList);
|
||||
gScenarioList = NULL;
|
||||
}
|
||||
|
||||
// Try and load the scores file
|
||||
|
||||
// First check user folder and then fallback to install directory
|
||||
file = SDL_RWFromFile(scoresPath, "rb");
|
||||
SDL_RWops *file = SDL_RWFromFile(path, "rb");
|
||||
if (file == NULL) {
|
||||
file = SDL_RWFromFile(get_file_path(PATH_ID_SCORES), "rb");
|
||||
if (file == NULL) {
|
||||
log_error("Unable to load scenario scores.");
|
||||
return 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Load header
|
||||
rct_scenario_scores_header header;
|
||||
if (SDL_RWread(file, &header, 16, 1) != 1) {
|
||||
SDL_RWclose(file);
|
||||
log_error("Invalid header in scenario scores file.");
|
||||
return 0;
|
||||
}
|
||||
gScenarioListCount = header.scenario_count;
|
||||
|
||||
// Load scenario information with scores
|
||||
int scenarioListBufferSize = gScenarioListCount * sizeof(rct_scenario_basic);
|
||||
gScenarioListCapacity = gScenarioListCount;
|
||||
gScenarioList = malloc(scenarioListBufferSize);
|
||||
if (SDL_RWread(file, gScenarioList, scenarioListBufferSize, 1) == 1) {
|
||||
SDL_RWclose(file);
|
||||
return 1;
|
||||
log_error("Invalid header in legacy scenario scores file.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Unable to load scores, free scenario list
|
||||
// Read scenarios
|
||||
bool highscoresDirty = false;
|
||||
for (uint32 i = 0; i < header.scenario_count; i++) {
|
||||
// Read legacy entry
|
||||
rct_scenario_basic scBasic;
|
||||
if (SDL_RWread(file, &scBasic, sizeof(rct_scenario_basic), 1) != 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Ignore non-completed scenarios
|
||||
if (!(scBasic.flags & SCENARIO_FLAGS_COMPLETED)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Find matching scenario entry
|
||||
scenario_index_entry *scenarioIndexEntry = scenario_list_find_by_filename(scBasic.path);
|
||||
if (scenarioIndexEntry != NULL) {
|
||||
// Check if legacy highscore is better
|
||||
scenario_highscore_entry *highscore = scenarioIndexEntry->highscore;
|
||||
if (highscore == NULL) {
|
||||
highscore = scenario_highscore_insert();
|
||||
scenarioIndexEntry->highscore = highscore;
|
||||
} else if (highscore->company_value < (money32)scBasic.company_value) {
|
||||
scenario_highscore_free(highscore);
|
||||
// Re-use highscore entry
|
||||
} else {
|
||||
highscore = NULL;
|
||||
}
|
||||
|
||||
// Set new highscore
|
||||
if (highscore != NULL) {
|
||||
highscore->fileName = _strdup(scBasic.path);
|
||||
highscore->name = _strdup(scBasic.completed_by);
|
||||
highscore->company_value = (money32)scBasic.company_value;
|
||||
highscore->timestamp = DATETIME64_MIN;
|
||||
highscoresDirty = true;
|
||||
}
|
||||
|
||||
// Exit loop
|
||||
break;
|
||||
}
|
||||
}
|
||||
SDL_RWclose(file);
|
||||
gScenarioListCount = 0;
|
||||
gScenarioListCapacity = 0;
|
||||
free(gScenarioList);
|
||||
gScenarioList = NULL;
|
||||
return 0;
|
||||
|
||||
if (highscoresDirty) {
|
||||
scenario_scores_save();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool scenario_scores_load()
|
||||
{
|
||||
utf8 scoresPath[MAX_PATH];
|
||||
scenario_scores_get_path(scoresPath);
|
||||
|
||||
// Load scores file
|
||||
SDL_RWops *file = SDL_RWFromFile(scoresPath, "rb");
|
||||
if (file == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check file version
|
||||
uint32 fileVersion;
|
||||
SDL_RWread(file, &fileVersion, sizeof(fileVersion), 1);
|
||||
if (fileVersion != 1) {
|
||||
log_error("Invalid or incompatible highscores file.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read and allocate the highscore list
|
||||
scenario_highscore_list_dispose();
|
||||
SDL_RWread(file, &gScenarioHighscoreListCount, sizeof(gScenarioHighscoreListCount), 1);
|
||||
gScenarioHighscoreListCapacity = gScenarioHighscoreListCount;
|
||||
gScenarioHighscoreList = malloc(gScenarioHighscoreListCapacity * sizeof(scenario_highscore_entry));
|
||||
|
||||
// Read highscores
|
||||
for (int i = 0; i < gScenarioHighscoreListCount; i++) {
|
||||
scenario_highscore_entry *highscore = &gScenarioHighscoreList[i];
|
||||
highscore->fileName = io_read_string(file);
|
||||
highscore->name = io_read_string(file);
|
||||
SDL_RWread(file, &highscore->company_value, sizeof(highscore->company_value), 1);
|
||||
SDL_RWread(file, &highscore->timestamp, sizeof(highscore->timestamp), 1);
|
||||
|
||||
// Attach highscore to correct scenario entry
|
||||
scenario_index_entry *scenarioIndexEntry = scenario_list_find_by_filename(highscore->fileName);
|
||||
if (scenarioIndexEntry != NULL) {
|
||||
scenarioIndexEntry->highscore = highscore;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_RWclose(file);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x00677B50
|
||||
*/
|
||||
int scenario_scores_save()
|
||||
bool scenario_scores_save()
|
||||
{
|
||||
SDL_RWops *file;
|
||||
utf8 scoresPath[MAX_PATH];
|
||||
|
||||
scenario_scores_get_path(scoresPath);
|
||||
|
||||
file = SDL_RWFromFile(scoresPath, "wb");
|
||||
SDL_RWops *file = SDL_RWFromFile(scoresPath, "wb");
|
||||
if (file == NULL) {
|
||||
log_error("Unable to save scenario scores.");
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
rct_scenario_scores_header header;
|
||||
header.scenario_count = gScenarioListCount;
|
||||
|
||||
SDL_RWwrite(file, &header, sizeof(header), 1);
|
||||
if (gScenarioListCount > 0)
|
||||
SDL_RWwrite(file, gScenarioList, gScenarioListCount * sizeof(rct_scenario_basic), 1);
|
||||
const uint32 fileVersion = 1;
|
||||
|
||||
SDL_RWwrite(file, &fileVersion, sizeof(fileVersion), 1);
|
||||
SDL_RWwrite(file, &gScenarioHighscoreListCount, sizeof(gScenarioHighscoreListCount), 1);
|
||||
for (int i = 0; i < gScenarioHighscoreListCount; i++) {
|
||||
scenario_highscore_entry *highscore = &gScenarioHighscoreList[i];
|
||||
io_write_string(file, highscore->fileName);
|
||||
io_write_string(file, highscore->name);
|
||||
SDL_RWwrite(file, &highscore->company_value, sizeof(highscore->company_value), 1);
|
||||
SDL_RWwrite(file, &highscore->timestamp, sizeof(highscore->timestamp), 1);
|
||||
}
|
||||
SDL_RWclose(file);
|
||||
return 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
scenario_highscore_entry *scenario_highscore_insert()
|
||||
{
|
||||
if (gScenarioHighscoreListCount >= gScenarioHighscoreListCapacity) {
|
||||
gScenarioHighscoreListCapacity = max(8, gScenarioHighscoreListCapacity * 2);
|
||||
gScenarioHighscoreList = realloc(gScenarioHighscoreList, gScenarioHighscoreListCapacity * sizeof(scenario_highscore_entry));
|
||||
}
|
||||
return &gScenarioHighscoreList[gScenarioHighscoreListCount++];
|
||||
}
|
||||
|
||||
static void scenario_highscore_remove(scenario_highscore_entry *highscore)
|
||||
{
|
||||
for (int i = 0; i < gScenarioHighscoreListCount; i++) {
|
||||
if (&gScenarioHighscoreList[i] == highscore) {
|
||||
size_t moveSize = (gScenarioHighscoreListCount - i - 1) * sizeof(scenario_highscore_entry);
|
||||
if (moveSize > 0) {
|
||||
memmove(&gScenarioHighscoreList[i], &gScenarioHighscoreList[i + 1], moveSize);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void scenario_highscore_free(scenario_highscore_entry *highscore)
|
||||
{
|
||||
SafeFree(highscore->fileName);
|
||||
SafeFree(highscore->name);
|
||||
}
|
||||
|
||||
static void scenario_highscore_list_dispose()
|
||||
{
|
||||
for (int i = 0; i < gScenarioHighscoreListCount; i++) {
|
||||
scenario_highscore_free(&gScenarioHighscoreList[i]);
|
||||
}
|
||||
gScenarioHighscoreListCapacity = 0;
|
||||
gScenarioHighscoreListCount = 0;
|
||||
SafeFree(gScenarioHighscoreList);
|
||||
}
|
||||
|
||||
static utf8 *io_read_string(SDL_RWops *file)
|
||||
{
|
||||
size_t bufferCount = 0;
|
||||
size_t bufferCapacity = 0;
|
||||
utf8 *buffer = NULL;
|
||||
|
||||
utf8 ch;
|
||||
do {
|
||||
SDL_RWread(file, &ch, sizeof(ch), 1);
|
||||
if (ch == '\0' && buffer == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (bufferCount >= bufferCapacity) {
|
||||
bufferCapacity = max(32, bufferCapacity * 2);
|
||||
buffer = realloc(buffer, bufferCapacity * sizeof(uint8));
|
||||
}
|
||||
|
||||
buffer[bufferCount] = ch;
|
||||
bufferCount++;
|
||||
} while (ch != '\0');
|
||||
|
||||
if (bufferCount < bufferCapacity) {
|
||||
buffer = realloc(buffer, bufferCount);
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static void io_write_string(SDL_RWops *file, utf8 *source)
|
||||
{
|
||||
if (source == NULL) {
|
||||
utf8 empty = 0;
|
||||
SDL_RWwrite(file, &empty, sizeof(utf8), 1);
|
||||
} else {
|
||||
SDL_RWwrite(file, source, strlen(source) + 1, 1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,306 @@
|
|||
#include "scenario.h"
|
||||
#include "util/util.h"
|
||||
|
||||
typedef struct {
|
||||
const utf8 *original;
|
||||
const utf8 *alternative;
|
||||
} scenario_alias;
|
||||
|
||||
const scenario_alias ScenarioAliases[] = {
|
||||
// UK - US differences:
|
||||
{ "Katie's Dreamland", "Katie's World" },
|
||||
{ "Pokey Park", "Dinky Park" },
|
||||
{ "White Water Park", "Aqua Park" },
|
||||
{ "Mystic Mountain", "Mothball Mountain" },
|
||||
{ "Paradise Pier", "Big Pier" },
|
||||
{ "Paradise Pier 2", "Big Pier 2" },
|
||||
{ "Mythological - Cradle of Civilisation", "Mythological - Cradle of Civilization" },
|
||||
|
||||
// RCT1 pack by RCTScenarioLover has a mistake:
|
||||
{ "Geoffrey Gardens", "Geoffery Gardens" },
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
const uint8 id;
|
||||
const utf8 *title;
|
||||
const uint8 category;
|
||||
} scenario_title_desc;
|
||||
|
||||
// RCT
|
||||
const scenario_title_desc ScenarioTitlesRCT1[] = {
|
||||
{ SC_FOREST_FRONTIERS, "Forest Frontiers", SCENARIO_CATEGORY_BEGINNER },
|
||||
{ SC_DYNAMITE_DUNES, "Dynamite Dunes", SCENARIO_CATEGORY_BEGINNER },
|
||||
{ SC_LEAFY_LAKES, "Leafy Lake", SCENARIO_CATEGORY_BEGINNER },
|
||||
{ SC_DIAMOND_HEIGHTS, "Diamond Heights", SCENARIO_CATEGORY_BEGINNER },
|
||||
{ SC_EVERGREEN_GARDENS, "Evergreen Gardens", SCENARIO_CATEGORY_BEGINNER },
|
||||
{ SC_BUMBLY_BEACH, "Bumbly Beach", SCENARIO_CATEGORY_BEGINNER },
|
||||
{ SC_TRINITY_ISLANDS, "Trinity Islands", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_KATIES_DREAMLAND, "Katie's Dreamland", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_POKEY_PARK, "Pokey Park", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_WHITE_WATER_PARK, "White Water Park", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_MILLENNIUM_MINES, "Millennium Mines", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_KARTS_COASTERS, "Karts & Coasters", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_MELS_WORLD, "Mel's World", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_MYSTIC_MOUNTAIN, "Mystic Mountain", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_PACIFIC_PYRAMIDS, "Pacific Pyramids", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_CRUMBLY_WOODS, "Crumbly Woods", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_PARADISE_PIER, "Paradise Pier", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_LIGHTNING_PEAKS, "Lightning Peaks", SCENARIO_CATEGORY_EXPERT },
|
||||
{ SC_IVORY_TOWERS, "Ivory Towers", SCENARIO_CATEGORY_EXPERT },
|
||||
{ SC_RAINBOW_VALLEY, "Rainbow Valley", SCENARIO_CATEGORY_EXPERT },
|
||||
{ SC_THUNDER_ROCK, "Thunder Rock", SCENARIO_CATEGORY_EXPERT },
|
||||
{ SC_MEGA_PARK, "Mega Park", SCENARIO_CATEGORY_OTHER },
|
||||
};
|
||||
|
||||
// RCT: Added Attractions
|
||||
const scenario_title_desc ScenarioTitlesRCT1AA[] = {
|
||||
{ SC_WHISPERING_CLIFFS, "Whispering Cliffs", SCENARIO_CATEGORY_BEGINNER },
|
||||
{ SC_THREE_MONKEYS_PARK, "Three Monkeys Park", SCENARIO_CATEGORY_BEGINNER },
|
||||
{ SC_CANARY_MINES, "Canary Mines", SCENARIO_CATEGORY_BEGINNER },
|
||||
{ SC_BARONY_BRIDGE, "Barony Bridge", SCENARIO_CATEGORY_BEGINNER },
|
||||
{ SC_FUNTOPIA, "Funtopia", SCENARIO_CATEGORY_BEGINNER },
|
||||
{ SC_HAUNTED_HARBOR, "Haunted Harbor", SCENARIO_CATEGORY_BEGINNER },
|
||||
{ SC_FUN_FORTRESS, "Fun Fortress", SCENARIO_CATEGORY_BEGINNER },
|
||||
{ SC_FUTURE_WORLD, "Future World", SCENARIO_CATEGORY_BEGINNER },
|
||||
{ SC_GENTLE_GLEN, "Gentle Glen", SCENARIO_CATEGORY_BEGINNER },
|
||||
{ SC_JOLLY_JUNGLE, "Jolly Jungle", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_HYDRO_HILLS, "Hydro Hills", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_SPRIGHTLY_PARK, "Sprightly Park", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_MAGIC_QUARTERS, "Magic Quarters", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_FRUIT_FARM, "Fruit Farm", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_BUTTERFLY_DAM, "Butterfly Dam", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_COASTER_CANYON, "Coaster Canyon", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_THUNDERSTORM_PARK, "Thunderstorm Park", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_HARMONIC_HILLS, "Harmonic Hills", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_ROMAN_VILLAGE, "Roman Village", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_SWAMP_COVE, "Swamp Cove", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_ADRENALINE_HEIGHTS, "Adrenaline Heights", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_UTOPIA, "Utopia", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_ROTTING_HEIGHTS, "Rotting Heights", SCENARIO_CATEGORY_EXPERT },
|
||||
{ SC_FIASCO_FOREST, "Fiasco Forest", SCENARIO_CATEGORY_EXPERT },
|
||||
{ SC_PICKLE_PARK, "Pickle Park", SCENARIO_CATEGORY_EXPERT },
|
||||
{ SC_GIGGLE_DOWNS, "Giggle Downs", SCENARIO_CATEGORY_EXPERT },
|
||||
{ SC_MINERAL_PARK, "Mineral Park", SCENARIO_CATEGORY_EXPERT },
|
||||
{ SC_COASTER_CRAZY, "Coaster Crazy", SCENARIO_CATEGORY_EXPERT },
|
||||
{ SC_URBAN_PARK, "Urban Park", SCENARIO_CATEGORY_EXPERT },
|
||||
{ SC_GEOFFREY_GARDENS, "Geoffrey Gardens", SCENARIO_CATEGORY_EXPERT },
|
||||
};
|
||||
|
||||
// RCT: Loopy Landscapes
|
||||
const scenario_title_desc ScenarioTitlesRCT1LL[] = {
|
||||
{ SC_ICEBERG_ISLANDS, "Iceberg Islands", SCENARIO_CATEGORY_BEGINNER },
|
||||
{ SC_VOLCANIA, "Volcania", SCENARIO_CATEGORY_BEGINNER },
|
||||
{ SC_ARID_HEIGHTS, "Arid Heights", SCENARIO_CATEGORY_BEGINNER },
|
||||
{ SC_RAZOR_ROCKS, "Razor Rocks", SCENARIO_CATEGORY_BEGINNER },
|
||||
{ SC_CRATER_LAKE, "Crater Lake", SCENARIO_CATEGORY_BEGINNER },
|
||||
{ SC_VERTIGO_VIEWS, "Vertigo Views", SCENARIO_CATEGORY_BEGINNER },
|
||||
{ SC_PARADISE_PIER_2, "Paradise Pier 2", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_DRAGONS_COVE, "Dragon's Cove", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_GOOD_KNIGHT_PARK, "Good Knight Park", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_WACKY_WARREN, "Wacky Warren", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_GRAND_GLACIER, "Grand Glacier", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_CRAZY_CRATERS, "Crazy Craters", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_DUSTY_DESERT, "Dusty Desert", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_WOODWORM_PARK, "Woodworm Park", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_ICARUS_PARK, "Icarus Park", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_SUNNY_SWAMPS, "Sunny Swamps", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_FRIGHTMARE_HILLS, "Frightmare Hills", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_THUNDER_ROCKS, "Thunder Rocks", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_OCTAGON_PARK, "Octagon Park", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_PLEASURE_ISLAND, "Pleasure Island", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_ICICLE_WORLDS, "Icicle Worlds", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_SOUTHERN_SANDS, "Southern Sands", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_TINY_TOWERS, "Tiny Towers", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_NEVERMORE_PARK, "Nevermore Park", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_PACIFICA, "Pacifica", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_URBAN_JUNGLE, "Urban Jungle", SCENARIO_CATEGORY_EXPERT },
|
||||
{ SC_TERROR_TOWN, "Terror Town", SCENARIO_CATEGORY_EXPERT },
|
||||
{ SC_MEGAWORLD_PARK, "Megaworld Park", SCENARIO_CATEGORY_EXPERT },
|
||||
{ SC_VENUS_PONDS, "Venus Ponds", SCENARIO_CATEGORY_EXPERT },
|
||||
{ SC_MICRO_PARK, "Micro Park", SCENARIO_CATEGORY_EXPERT },
|
||||
};
|
||||
|
||||
// RCT2
|
||||
const scenario_title_desc ScenarioTitlesRCT2[] = {
|
||||
{ SC_UNIDENTIFIED, "Crazy Castle", SCENARIO_CATEGORY_BEGINNER },
|
||||
{ SC_UNIDENTIFIED, "Electric Fields", SCENARIO_CATEGORY_BEGINNER },
|
||||
{ SC_UNIDENTIFIED, "Factory Capers", SCENARIO_CATEGORY_BEGINNER },
|
||||
{ SC_UNIDENTIFIED, "Amity Airfield", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_UNIDENTIFIED, "Botany Breakers", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_UNIDENTIFIED, "Bumbly Bazaar", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_UNIDENTIFIED, "Dusty Greens", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_UNIDENTIFIED, "Fungus Woods", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_UNIDENTIFIED, "Gravity Gardens", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_UNIDENTIFIED, "Infernal Views", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_UNIDENTIFIED, "Alpine Adventures", SCENARIO_CATEGORY_EXPERT },
|
||||
{ SC_UNIDENTIFIED, "Extreme Heights", SCENARIO_CATEGORY_EXPERT },
|
||||
{ SC_UNIDENTIFIED, "Ghost Town", SCENARIO_CATEGORY_EXPERT },
|
||||
{ SC_UNIDENTIFIED, "Lucky Lake", SCENARIO_CATEGORY_EXPERT },
|
||||
{ SC_UNIDENTIFIED, "Rainbow Summit", SCENARIO_CATEGORY_EXPERT },
|
||||
};
|
||||
|
||||
// RCT2: Wacky Worlds
|
||||
const scenario_title_desc ScenarioTitlesRCT2WW[] = {
|
||||
{ SC_UNIDENTIFIED, "Africa - Victoria Falls", SCENARIO_CATEGORY_BEGINNER },
|
||||
{ SC_UNIDENTIFIED, "Asia - Great Wall of China Tourism Enhancement", SCENARIO_CATEGORY_BEGINNER },
|
||||
{ SC_UNIDENTIFIED, "North America - Grand Canyon", SCENARIO_CATEGORY_BEGINNER },
|
||||
{ SC_UNIDENTIFIED, "South America - Rio Carnival", SCENARIO_CATEGORY_BEGINNER },
|
||||
{ SC_UNIDENTIFIED, "Africa - African Diamond Mine", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_UNIDENTIFIED, "Asia - Maharaja Palace", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_UNIDENTIFIED, "Australasia - Ayers Rock", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_UNIDENTIFIED, "Europe - European Cultural Festival", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_UNIDENTIFIED, "North America - Rollercoaster Heaven", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_UNIDENTIFIED, "South America - Inca Lost City", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_UNIDENTIFIED, "Africa - Oasis", SCENARIO_CATEGORY_EXPERT },
|
||||
{ SC_UNIDENTIFIED, "Antarctic - Ecological Salvage", SCENARIO_CATEGORY_EXPERT },
|
||||
{ SC_UNIDENTIFIED, "Asia - Japanese Coastal Reclaim", SCENARIO_CATEGORY_EXPERT },
|
||||
{ SC_UNIDENTIFIED, "Australasia - Fun at the Beach", SCENARIO_CATEGORY_EXPERT },
|
||||
{ SC_UNIDENTIFIED, "Europe - Renovation", SCENARIO_CATEGORY_EXPERT },
|
||||
{ SC_UNIDENTIFIED, "N. America - Extreme Hawaiian Island", SCENARIO_CATEGORY_EXPERT },
|
||||
{ SC_UNIDENTIFIED, "South America - Rain Forest Plateau", SCENARIO_CATEGORY_EXPERT },
|
||||
};
|
||||
|
||||
// RCT2: Time Twister
|
||||
const scenario_title_desc ScenarioTitlesRCT2TT[] = {
|
||||
{ SC_UNIDENTIFIED, "Dark Age - Robin Hood", SCENARIO_CATEGORY_BEGINNER },
|
||||
{ SC_UNIDENTIFIED, "Prehistoric - After the Asteroid", SCENARIO_CATEGORY_BEGINNER },
|
||||
{ SC_UNIDENTIFIED, "Roaring Twenties - Prison Island", SCENARIO_CATEGORY_BEGINNER },
|
||||
{ SC_UNIDENTIFIED, "Rock 'n' Roll - Flower Power", SCENARIO_CATEGORY_BEGINNER },
|
||||
{ SC_UNIDENTIFIED, "Dark Age - Castle", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_UNIDENTIFIED, "Future - First Encounters", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_UNIDENTIFIED, "Mythological - Animatronic Film Set", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_UNIDENTIFIED, "Prehistoric - Jurassic Safari", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_UNIDENTIFIED, "Roaring Twenties - Schneider Cup", SCENARIO_CATEGORY_CHALLENGING },
|
||||
{ SC_UNIDENTIFIED, "Future - Future World", SCENARIO_CATEGORY_EXPERT },
|
||||
{ SC_UNIDENTIFIED, "Mythological - Cradle of Civilisation", SCENARIO_CATEGORY_EXPERT },
|
||||
{ SC_UNIDENTIFIED, "Prehistoric - Stone Age", SCENARIO_CATEGORY_EXPERT },
|
||||
{ SC_UNIDENTIFIED, "Roaring Twenties - Skyscrapers", SCENARIO_CATEGORY_EXPERT },
|
||||
{ SC_UNIDENTIFIED, "Rock 'n' Roll - Rock 'n' Roll", SCENARIO_CATEGORY_EXPERT },
|
||||
};
|
||||
|
||||
// Real parks
|
||||
const scenario_title_desc ScenarioTitlesRealParks[] = {
|
||||
{ SC_UNIDENTIFIED, "Alton Towers", SCENARIO_CATEGORY_REAL },
|
||||
{ SC_UNIDENTIFIED, "Heide-Park", SCENARIO_CATEGORY_REAL },
|
||||
{ SC_UNIDENTIFIED, "Blackpool Pleasure Beach", SCENARIO_CATEGORY_REAL },
|
||||
{ SC_UNIDENTIFIED, "Six Flags Belgium", SCENARIO_CATEGORY_REAL },
|
||||
{ SC_UNIDENTIFIED, "Six Flags Great Adventure", SCENARIO_CATEGORY_REAL },
|
||||
{ SC_UNIDENTIFIED, "Six Flags Holland", SCENARIO_CATEGORY_REAL },
|
||||
{ SC_UNIDENTIFIED, "Six Flags Magic Mountain", SCENARIO_CATEGORY_REAL },
|
||||
{ SC_UNIDENTIFIED, "Six Flags over Texas", SCENARIO_CATEGORY_REAL },
|
||||
};
|
||||
|
||||
// Other parks
|
||||
const scenario_title_desc ScenarioTitlesOtherParks[] = {
|
||||
{ SC_UNIDENTIFIED, "Fort Anachronism", SCENARIO_CATEGORY_DLC },
|
||||
{ SC_UNIDENTIFIED, "PC Player", SCENARIO_CATEGORY_DLC },
|
||||
{ SC_UNIDENTIFIED, "PC Gaming World", SCENARIO_CATEGORY_DLC },
|
||||
{ SC_UNIDENTIFIED, "gameplay", SCENARIO_CATEGORY_DLC },
|
||||
{ SC_UNIDENTIFIED, "Panda World", SCENARIO_CATEGORY_DLC },
|
||||
{ SC_UNIDENTIFIED, "Competition Land 1", SCENARIO_CATEGORY_DLC },
|
||||
{ SC_UNIDENTIFIED, "Competition Land 2", SCENARIO_CATEGORY_DLC },
|
||||
{ SC_UNIDENTIFIED, "Build your own Six Flags Belgium", SCENARIO_CATEGORY_BUILD_YOUR_OWN },
|
||||
{ SC_UNIDENTIFIED, "Build your own Six Flags Great Adventure", SCENARIO_CATEGORY_BUILD_YOUR_OWN },
|
||||
{ SC_UNIDENTIFIED, "Build your own Six Flags Holland", SCENARIO_CATEGORY_BUILD_YOUR_OWN },
|
||||
{ SC_UNIDENTIFIED, "Build your own Six Flags Magic Mountain", SCENARIO_CATEGORY_BUILD_YOUR_OWN },
|
||||
{ SC_UNIDENTIFIED, "Build your own Six Flags Park", SCENARIO_CATEGORY_BUILD_YOUR_OWN },
|
||||
{ SC_UNIDENTIFIED, "Build your own Six Flags over Texas", SCENARIO_CATEGORY_BUILD_YOUR_OWN },
|
||||
};
|
||||
|
||||
#define DEFINE_SCENARIO_TITLE_DESC_GROUP(x) { countof(x), x }
|
||||
const struct {
|
||||
int count;
|
||||
const scenario_title_desc * const titles;
|
||||
} ScenarioTitlesBySource[] = {
|
||||
DEFINE_SCENARIO_TITLE_DESC_GROUP(ScenarioTitlesRCT1),
|
||||
DEFINE_SCENARIO_TITLE_DESC_GROUP(ScenarioTitlesRCT1AA),
|
||||
DEFINE_SCENARIO_TITLE_DESC_GROUP(ScenarioTitlesRCT1LL),
|
||||
DEFINE_SCENARIO_TITLE_DESC_GROUP(ScenarioTitlesRCT2),
|
||||
DEFINE_SCENARIO_TITLE_DESC_GROUP(ScenarioTitlesRCT2WW),
|
||||
DEFINE_SCENARIO_TITLE_DESC_GROUP(ScenarioTitlesRCT2TT),
|
||||
DEFINE_SCENARIO_TITLE_DESC_GROUP(ScenarioTitlesRealParks),
|
||||
DEFINE_SCENARIO_TITLE_DESC_GROUP(ScenarioTitlesOtherParks),
|
||||
};
|
||||
|
||||
bool scenario_get_source_desc(const utf8 *name, source_desc *outDesc)
|
||||
{
|
||||
assert(outDesc != NULL);
|
||||
|
||||
sint32 currentIndex = 0;
|
||||
for (int i = 0; i < countof(ScenarioTitlesBySource); i++) {
|
||||
for (int j = 0; j < ScenarioTitlesBySource[i].count; j++) {
|
||||
const scenario_title_desc *desc = &ScenarioTitlesBySource[i].titles[j];
|
||||
if (_strcmpi(name, desc->title) == 0) {
|
||||
outDesc->title = desc->title;
|
||||
outDesc->id = desc->id;
|
||||
outDesc->source = i;
|
||||
outDesc->index = currentIndex;
|
||||
outDesc->category = desc->category;
|
||||
return true;
|
||||
}
|
||||
currentIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
outDesc->title = NULL;
|
||||
outDesc->id = SC_UNIDENTIFIED;
|
||||
outDesc->source = SCENARIO_SOURCE_OTHER;
|
||||
outDesc->index = -1;
|
||||
outDesc->category = SCENARIO_CATEGORY_OTHER;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool scenario_get_source_desc_by_id(uint8 id, source_desc *outDesc)
|
||||
{
|
||||
assert(outDesc != NULL);
|
||||
|
||||
sint32 currentIndex = 0;
|
||||
for (int i = 0; i < countof(ScenarioTitlesBySource); i++) {
|
||||
for (int j = 0; j < ScenarioTitlesBySource[i].count; j++) {
|
||||
const scenario_title_desc *desc = &ScenarioTitlesBySource[i].titles[j];
|
||||
if (id == desc->id) {
|
||||
outDesc->title = desc->title;
|
||||
outDesc->id = desc->id;
|
||||
outDesc->source = i;
|
||||
outDesc->index = currentIndex;
|
||||
outDesc->category = desc->category;
|
||||
return true;
|
||||
}
|
||||
currentIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
outDesc->title = NULL;
|
||||
outDesc->id = SC_UNIDENTIFIED;
|
||||
outDesc->source = SCENARIO_SOURCE_OTHER;
|
||||
outDesc->index = -1;
|
||||
outDesc->category = SCENARIO_CATEGORY_OTHER;
|
||||
return false;
|
||||
}
|
||||
|
||||
void scenario_normalise_name(utf8 *name)
|
||||
{
|
||||
size_t nameLength = strlen(name);
|
||||
|
||||
// Strip "RCT(1|2)?" prefix off scenario names.
|
||||
if (nameLength >= 3 && (name[0] == 'R' && name[1] == 'C' && name[2] == 'T')) {
|
||||
if (nameLength >= 4 && (name[3] == '1' || name[3] == '2')) {
|
||||
log_verbose("Stripping RCT/1/2 from name: %s", name);
|
||||
safe_strncpy(name, name + 4, 64);
|
||||
} else {
|
||||
safe_strncpy(name, name + 3, 64);
|
||||
}
|
||||
}
|
||||
|
||||
// Trim (for the sake of the above and WW / TT scenarios
|
||||
safe_strtrimleft(name, name, 64);
|
||||
|
||||
// American scenario titles should be converted to British name
|
||||
// Don't worry, names will be translated using language packs later
|
||||
for (int i = 0; i < countof(ScenarioAliases); i++) {
|
||||
if (strcmp(ScenarioAliases[i].alternative, name) == 0) {
|
||||
log_verbose("Found alias: %s; will treat as: %s", name, ScenarioAliases[i].original);
|
||||
safe_strncpy(name, ScenarioAliases[i].original, 64);
|
||||
}
|
||||
}
|
||||
}
|
46
src/title.c
46
src/title.c
|
@ -64,6 +64,7 @@ rct_xy16 _titleScriptCurrentCentralPosition = { -1, -1 };
|
|||
#define ZOOM(d) TITLE_SCRIPT_ZOOM, d
|
||||
#define RESTART() TITLE_SCRIPT_RESTART
|
||||
#define LOAD(i) TITLE_SCRIPT_LOAD, i
|
||||
#define LOADRCT1(i) TITLE_SCRIPT_LOADRCT1, i
|
||||
|
||||
static const uint8 _magicMountainScript[] = {
|
||||
LOADMM(),
|
||||
|
@ -298,10 +299,7 @@ static void title_do_next_script_opcode()
|
|||
uint8 script_opcode, script_operand;
|
||||
rct_window* w;
|
||||
gTitleScriptCommand++;
|
||||
if (gTitleScriptCommand <= 1 || *(_currentScript - 1) != TITLE_SCRIPT_END)
|
||||
script_opcode = *_currentScript++;
|
||||
else
|
||||
script_opcode = *_currentScript;
|
||||
script_opcode = *_currentScript++;
|
||||
if (gTitleScriptSkipTo != -1) {
|
||||
if (gTitleScriptSkipTo == gTitleScriptCommand) {
|
||||
gTitleScriptSkipTo = -1;
|
||||
|
@ -422,6 +420,38 @@ static void title_do_next_script_opcode()
|
|||
}
|
||||
}
|
||||
break;
|
||||
case TITLE_SCRIPT_LOADRCT1:
|
||||
script_operand = (*_currentScript++);
|
||||
|
||||
source_desc sourceDesc;
|
||||
if (!scenario_get_source_desc_by_id(script_operand, &sourceDesc) || sourceDesc.index == -1) {
|
||||
log_fatal("Invalid scenario id.");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
const utf8 *path = NULL;
|
||||
for (int i = 0; i < gScenarioListCount; i++) {
|
||||
if (gScenarioList[i].source_index == sourceDesc.index) {
|
||||
path = gScenarioList[i].path;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (path == NULL || !title_load_park(path)) {
|
||||
script_opcode = *_currentScript;
|
||||
while (script_opcode != TITLE_SCRIPT_LOADRCT1 && script_opcode != TITLE_SCRIPT_RESTART && script_opcode != TITLE_SCRIPT_END) {
|
||||
title_skip_opcode();
|
||||
script_opcode = *_currentScript;
|
||||
}
|
||||
if (script_opcode == TITLE_SCRIPT_RESTART) {
|
||||
title_sequence_change_preset(4);
|
||||
title_refresh_sequence();
|
||||
config_save_default();
|
||||
return;
|
||||
}
|
||||
}
|
||||
gTitleScriptSave = 0xFF;
|
||||
break;
|
||||
}
|
||||
window_invalidate_by_class(WC_TITLE_EDITOR);
|
||||
}
|
||||
|
@ -508,7 +538,7 @@ void title_update()
|
|||
audio_start_title_music();
|
||||
}
|
||||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) &= ~0x80;
|
||||
gInputFlags &= ~INPUT_FLAG_VIEWPORT_SCROLLING;
|
||||
|
||||
window_map_tooltip_update_visibility();
|
||||
window_dispatch_update_all();
|
||||
|
@ -688,6 +718,9 @@ bool title_refresh_sequence()
|
|||
hasInvalidSave = true;
|
||||
hasLoad = true;
|
||||
}
|
||||
else if (title->commands[i].command == TITLE_SCRIPT_LOADRCT1) {
|
||||
hasLoad = true;
|
||||
}
|
||||
else if (title->commands[i].command == TITLE_SCRIPT_LOADMM) {
|
||||
hasLoad = true;
|
||||
}
|
||||
|
@ -711,6 +744,9 @@ bool title_refresh_sequence()
|
|||
for (int i = 0; i < title->num_commands; i++) {
|
||||
*scriptPtr++ = title->commands[i].command;
|
||||
switch (title->commands[i].command) {
|
||||
case TITLE_SCRIPT_LOADRCT1:
|
||||
*scriptPtr++ = title->commands[i].saveIndex;
|
||||
break;
|
||||
case TITLE_SCRIPT_LOAD:
|
||||
src = title->saves[title->commands[i].saveIndex];
|
||||
do {
|
||||
|
|
|
@ -34,7 +34,8 @@ enum {
|
|||
TITLE_SCRIPT_END,
|
||||
TITLE_SCRIPT_SPEED,
|
||||
TITLE_SCRIPT_LOOP,
|
||||
TITLE_SCRIPT_ENDLOOP
|
||||
TITLE_SCRIPT_ENDLOOP,
|
||||
TITLE_SCRIPT_LOADRCT1,
|
||||
};
|
||||
|
||||
extern sint32 gTitleScriptCommand;
|
||||
|
|
132
src/tutorial.c
132
src/tutorial.c
|
@ -1,132 +0,0 @@
|
|||
/*****************************************************************************
|
||||
* Copyright (c) 2014 Ted John
|
||||
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
|
||||
*
|
||||
* This file is part of OpenRCT2.
|
||||
*
|
||||
* OpenRCT2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "addresses.h"
|
||||
#include "interface/window.h"
|
||||
#include "localisation/localisation.h"
|
||||
#include "tutorial.h"
|
||||
#include "windows/error.h"
|
||||
#include "windows/tooltip.h"
|
||||
|
||||
static void sub_6EA2AA(rct_window *w, int widgetIndex, int x, int y, int edi);
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x0066ECC1
|
||||
*/
|
||||
void tutorial_start(int type)
|
||||
{
|
||||
strcpy((char*)0x009BC677, "Tutorial not implemented.");
|
||||
window_error_open(3165, STR_NONE);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x0066EE25
|
||||
*/
|
||||
void tutorial_stop()
|
||||
{
|
||||
// RCT2_CALLPROC_EBPSAFE(0x0066EE25);
|
||||
}
|
||||
|
||||
void game_handle_keyboard_input_for_tutorial()
|
||||
{
|
||||
#ifdef ENABLE_TUTORIAL
|
||||
rct_window *w;
|
||||
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_ON_TUTORIAL, uint8) == 1) {
|
||||
int eax, ebx, ecx, edx, esi, edi, ebp;
|
||||
RCT2_CALLFUNC_X(0x0066EEB4, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
||||
eax &= 0xFF;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PLACE_OBJECT_MODIFIER, uint8) = eax;
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_PLACE_OBJECT_MODIFIER, uint8) & 4) {
|
||||
window_tooltip_close();
|
||||
if ((w = window_get_main()) != NULL) {
|
||||
RCT2_CALLPROC_X(0x006EA2AA, 0, 0, 0, 0, (int)w, RCT2_GLOBAL(0x009DEA72, uint16), 0);
|
||||
RCT2_GLOBAL(0x009DEA72, uint16)++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!(RCT2_GLOBAL(RCT2_ADDRESS_PLACE_OBJECT_MODIFIER, uint8) & 4)) {
|
||||
window_tooltip_close();
|
||||
if ((w = window_get_main()) != NULL) {
|
||||
sub_6EA2AA(w, 0, 0, 0, RCT2_GLOBAL(0x009DEA72, uint16));
|
||||
RCT2_GLOBAL(0x009DEA72, uint16)++;
|
||||
}
|
||||
}
|
||||
|
||||
// Write tutorial input
|
||||
RCT2_CALLPROC_X(0x0066EEE1, RCT2_GLOBAL(RCT2_ADDRESS_PLACE_OBJECT_MODIFIER, uint8), 0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void sub_6EA2AA(rct_window *w, int widgetIndex, int x, int y, int edi)
|
||||
{
|
||||
#ifdef ENABLE_TUTORIAL
|
||||
RCT2_CALLPROC_X(0x006EA2AA, 0, 0, 0, 0, (int)w, RCT2_GLOBAL(0x009DEA72, uint16), 0);
|
||||
return;
|
||||
|
||||
rct_window *tooltipWindow;
|
||||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_WINDOW_CLASS, rct_windowclass) = w->classification;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_WINDOW_NUMBER, rct_windownumber) = w->number;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_WIDGET_INDEX, uint16) = widgetIndex;
|
||||
|
||||
rct_string_id stringId = window_event_tooltip_call(w, widgetIndex);
|
||||
if (stringId == (rct_string_id)STR_NONE)
|
||||
return;
|
||||
|
||||
tooltipWindow = window_find_by_class(WC_TOOLTIP);
|
||||
if (tooltipWindow == NULL)
|
||||
return;
|
||||
|
||||
char *buffer = (char*)RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER;
|
||||
|
||||
RCT2_GLOBAL(0x0142006C, uint32) = edi;
|
||||
format_string(buffer, edi, (void*)RCT2_ADDRESS_COMMON_FORMAT_ARGS);
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = 224;
|
||||
int width = gfx_get_string_width_new_lined(buffer);
|
||||
width = min(width, 196);
|
||||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = 224;
|
||||
|
||||
int numLines, fontHeight;
|
||||
gfx_wrap_string(buffer, width + 1, &numLines, &fontHeight);
|
||||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_TEXT_HEIGHT, uint16) = numLines;
|
||||
tooltipWindow->widgets[0].right = width + 3;
|
||||
tooltipWindow->widgets[0].bottom = ((numLines + 1) * 10) + 4;
|
||||
|
||||
char *tooltipBuffer = (char*)RCT2_ADDRESS_TOOLTIP_TEXT_BUFFER;
|
||||
memcpy(tooltipBuffer, buffer, 512);
|
||||
|
||||
window_tooltip_open(w, widgetIndex, x, y);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x0066EE54
|
||||
*/
|
||||
void sub_66EE54()
|
||||
{
|
||||
// RCT2_CALLPROC_EBPSAFE(0x0066EE54);
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
/*****************************************************************************
|
||||
* Copyright (c) 2014 Ted John
|
||||
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
|
||||
*
|
||||
* This file is part of OpenRCT2.
|
||||
*
|
||||
* OpenRCT2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef _TUTORIAL_H_
|
||||
#define _TUTORIAL_H_
|
||||
|
||||
void tutorial_start(int type);
|
||||
void tutorial_stop();
|
||||
void sub_66EE54();
|
||||
|
||||
#endif
|
|
@ -67,7 +67,6 @@ const char *path_get_filename(const utf8 *path)
|
|||
// Checks if the path is valid (e.g. not just a file name)
|
||||
if (filename == NULL)
|
||||
{
|
||||
log_warning("Invalid path given: %s", path);
|
||||
// Return the input string to keep things working
|
||||
return path;
|
||||
}
|
||||
|
@ -78,6 +77,8 @@ const char *path_get_filename(const utf8 *path)
|
|||
return filename;
|
||||
}
|
||||
|
||||
// Returns the extension (dot inclusive) from the given path, or the end of the
|
||||
// string when no extension was found.
|
||||
const char *path_get_extension(const utf8 *path)
|
||||
{
|
||||
// Get the filename from the path
|
||||
|
@ -94,6 +95,15 @@ const char *path_get_extension(const utf8 *path)
|
|||
}
|
||||
|
||||
void path_set_extension(utf8 *path, const utf8 *newExtension)
|
||||
{
|
||||
// Remove existing extension (check first if there is one)
|
||||
if (path_get_extension(path) < strrchr(path, '\0'))
|
||||
path_remove_extension(path);
|
||||
// Append new extension
|
||||
path_append_extension(path, newExtension);
|
||||
}
|
||||
|
||||
void path_append_extension(utf8 *path, const utf8 *newExtension)
|
||||
{
|
||||
// Append a dot to the filename if the new extension doesn't start with it
|
||||
char *endOfString = strrchr(path, '\0');
|
||||
|
@ -101,15 +111,17 @@ void path_set_extension(utf8 *path, const utf8 *newExtension)
|
|||
*endOfString++ = '.';
|
||||
|
||||
// Append the extension to the path
|
||||
// No existing extensions should be removed ("ride.TD6" -> "ride.TD6.TD6")
|
||||
safe_strncpy(endOfString, newExtension, MAX_PATH - (endOfString - path) - 1);
|
||||
}
|
||||
|
||||
void path_remove_extension(utf8 *path)
|
||||
{
|
||||
// Find last dot in filename, and replace it with a null-terminator
|
||||
char *lastDot = strrchr(path, '.');
|
||||
if (*lastDot) *lastDot = '\0';
|
||||
char *lastDot = strrchr(path_get_filename(path), '.');
|
||||
if (lastDot != NULL)
|
||||
*lastDot = '\0';
|
||||
else
|
||||
log_warning("No extension found. (path = %s)", path);
|
||||
}
|
||||
|
||||
bool readentirefile(const utf8 *path, void **outBuffer, int *outLength)
|
||||
|
@ -210,6 +222,70 @@ char *safe_strncpy(char * destination, const char * source, size_t size)
|
|||
return result;
|
||||
}
|
||||
|
||||
char *safe_strcat(char *destination, const char *source, size_t size)
|
||||
{
|
||||
assert(destination != NULL);
|
||||
assert(source != NULL);
|
||||
|
||||
if (size == 0) {
|
||||
return destination;
|
||||
}
|
||||
|
||||
char *result = destination;
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < size; i++) {
|
||||
if (*destination == '\0') {
|
||||
break;
|
||||
} else {
|
||||
destination++;
|
||||
}
|
||||
}
|
||||
|
||||
bool terminated = false;
|
||||
for (; i < size; i++) {
|
||||
if (*source != '\0') {
|
||||
*destination++ = *source++;
|
||||
} else {
|
||||
*destination = *source;
|
||||
terminated = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!terminated) {
|
||||
result[size - 1] = '\0';
|
||||
log_warning("Truncating string \"%s\" to %d bytes.", result, size);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
char *safe_strcat_path(char *destination, const char *source, size_t size)
|
||||
{
|
||||
const char pathSeparator = platform_get_path_separator();
|
||||
|
||||
size_t length = strlen(destination);
|
||||
if (length >= size - 1) {
|
||||
return destination;
|
||||
}
|
||||
|
||||
if (destination[length - 1] != pathSeparator) {
|
||||
destination[length] = pathSeparator;
|
||||
destination[length + 1] = '\0';
|
||||
}
|
||||
|
||||
return safe_strcat(destination, source, size);
|
||||
}
|
||||
|
||||
char *safe_strtrimleft(char *destination, const char *source, size_t size)
|
||||
{
|
||||
while (*source == ' ' && *source != '\0') {
|
||||
source++;
|
||||
}
|
||||
return safe_strncpy(destination, source, size);
|
||||
}
|
||||
|
||||
bool utf8_is_bom(const char *str)
|
||||
{
|
||||
return str[0] == (char)0xEF && str[1] == (char)0xBB && str[2] == (char)0xBF;
|
||||
|
|
|
@ -33,6 +33,7 @@ bool filename_valid_characters(const utf8 *filename);
|
|||
const char *path_get_filename(const utf8 *path);
|
||||
const char *path_get_extension(const utf8 *path);
|
||||
void path_set_extension(utf8 *path, const utf8 *newExtension);
|
||||
void path_append_extension(utf8 *path, const utf8 *newExtension);
|
||||
void path_remove_extension(utf8 *path);
|
||||
bool readentirefile(const utf8 *path, void **outBuffer, int *outLength);
|
||||
|
||||
|
@ -41,6 +42,9 @@ int bitcount(int source);
|
|||
bool strequals(const char *a, const char *b, int length, bool caseInsensitive);
|
||||
int strcicmp(char const *a, char const *b);
|
||||
char *safe_strncpy(char * destination, const char * source, size_t num);
|
||||
char *safe_strcat(char *destination, const char *source, size_t size);
|
||||
char *safe_strcat_path(char *destination, const char *source, size_t size);
|
||||
char *safe_strtrimleft(char *destination, const char *source, size_t size);
|
||||
|
||||
bool utf8_is_bom(const char *str);
|
||||
bool str_is_null_or_empty(const char *str);
|
||||
|
|
|
@ -483,7 +483,7 @@ static void cheat_fix_vandalism()
|
|||
if (map_element_get_type(it.element) != MAP_ELEMENT_TYPE_PATH)
|
||||
continue;
|
||||
|
||||
if ((it.element->properties.path.additions & 0x0F) == 0)
|
||||
if (!footpath_element_has_path_scenery(it.element))
|
||||
continue;
|
||||
|
||||
it.element->flags &= ~MAP_ELEMENT_FLAG_BROKEN;
|
||||
|
@ -511,10 +511,10 @@ static void cheat_remove_litter()
|
|||
if (map_element_get_type(it.element) != MAP_ELEMENT_TYPE_PATH)
|
||||
continue;
|
||||
|
||||
if ((it.element->properties.path.additions & 0x0F) == 0)
|
||||
if (!footpath_element_has_path_scenery(it.element))
|
||||
continue;
|
||||
|
||||
sceneryEntry = g_pathBitSceneryEntries[(it.element->properties.path.additions & 0xF) - 1];
|
||||
sceneryEntry = g_pathBitSceneryEntries[footpath_element_get_path_scenery_index(it.element)];
|
||||
if(sceneryEntry->path_bit.var_06 & (1 << 0))
|
||||
it.element->properties.path.addition_status = 0xFF;
|
||||
|
||||
|
|
|
@ -194,8 +194,8 @@ static void window_clear_scenery_textinput(rct_window *w, int widgetIndex, char
|
|||
|
||||
static void window_clear_scenery_inputsize(rct_window *w)
|
||||
{
|
||||
((uint16*)TextInputDescriptionArgs)[0] = MINIMUM_TOOL_SIZE;
|
||||
((uint16*)TextInputDescriptionArgs)[1] = MAXIMUM_TOOL_SIZE;
|
||||
TextInputDescriptionArgs[0] = MINIMUM_TOOL_SIZE;
|
||||
TextInputDescriptionArgs[1] = MAXIMUM_TOOL_SIZE;
|
||||
window_text_input_open(w, WIDX_PREVIEW, 5128, 5129, STR_NONE, STR_NONE, 3);
|
||||
}
|
||||
|
||||
|
@ -259,7 +259,7 @@ static void window_clear_scenery_paint(rct_window *w, rct_drawpixelinfo *dpi)
|
|||
*/
|
||||
static int window_clear_scenery_should_close()
|
||||
{
|
||||
if (!(RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE))
|
||||
if (!(gInputFlags & INPUT_FLAG_TOOL_ACTIVE))
|
||||
return 1;
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) != WC_TOP_TOOLBAR)
|
||||
return 1;
|
||||
|
|
|
@ -160,9 +160,9 @@ void window_dropdown_show_text_custom_width(int x, int y, int extray, uint8 colo
|
|||
memcpy((void*)0x009DEBA4, gDropdownItemsFormat, 40 * 2);
|
||||
memcpy((void*)0x009DEBF4, gDropdownItemsArgs, 40 * 8);
|
||||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) &= ~(INPUT_FLAG_DROPDOWN_STAY_OPEN | INPUT_FLAG_DROPDOWN_MOUSE_UP);
|
||||
gInputFlags &= ~(INPUT_FLAG_DROPDOWN_STAY_OPEN | INPUT_FLAG_DROPDOWN_MOUSE_UP);
|
||||
if (flags & DROPDOWN_FLAG_STAY_OPEN)
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_DROPDOWN_STAY_OPEN;
|
||||
gInputFlags |= INPUT_FLAG_DROPDOWN_STAY_OPEN;
|
||||
|
||||
window_dropdown_close();
|
||||
_dropdown_num_columns = 1;
|
||||
|
@ -204,7 +204,7 @@ void window_dropdown_show_text_custom_width(int x, int y, int extray, uint8 colo
|
|||
gDropdownItemsDisabled = 0;
|
||||
gDropdownItemsChecked = 0;
|
||||
gDropdownIsColour = false;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, sint8) = INPUT_STATE_DROPDOWN_ACTIVE;
|
||||
gInputState = INPUT_STATE_DROPDOWN_ACTIVE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -230,9 +230,9 @@ void window_dropdown_show_image(int x, int y, int extray, uint8 colour, uint8 fl
|
|||
memcpy((void*)0x009DEBA4, gDropdownItemsFormat, 40 * 2);
|
||||
memcpy((void*)0x009DEBF4, gDropdownItemsArgs, 40 * 8);
|
||||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) &= ~(INPUT_FLAG_DROPDOWN_STAY_OPEN | INPUT_FLAG_DROPDOWN_MOUSE_UP);
|
||||
gInputFlags &= ~(INPUT_FLAG_DROPDOWN_STAY_OPEN | INPUT_FLAG_DROPDOWN_MOUSE_UP);
|
||||
if (flags & DROPDOWN_FLAG_STAY_OPEN)
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_DROPDOWN_STAY_OPEN;
|
||||
gInputFlags |= INPUT_FLAG_DROPDOWN_STAY_OPEN;
|
||||
|
||||
// Close existing dropdown
|
||||
window_dropdown_close();
|
||||
|
@ -274,7 +274,7 @@ void window_dropdown_show_image(int x, int y, int extray, uint8 colour, uint8 fl
|
|||
gDropdownHighlightedIndex = -1;
|
||||
gDropdownItemsDisabled = 0;
|
||||
gDropdownItemsChecked = 0;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, sint8) = INPUT_STATE_DROPDOWN_ACTIVE;
|
||||
gInputState = INPUT_STATE_DROPDOWN_ACTIVE;
|
||||
|
||||
// Copy the following properties until all use of it is decompiled
|
||||
gDropdownHighlightedIndex = gDropdownHighlightedIndex;
|
||||
|
@ -324,7 +324,7 @@ static void window_dropdown_paint(rct_window *w, rct_drawpixelinfo *dpi)
|
|||
item = gDropdownItemsFormat[i];
|
||||
if (item == (uint16)-1 || item == (uint16)-2) {
|
||||
// Image item
|
||||
image = *((uint32*)&gDropdownItemsArgs[i]);
|
||||
image = (uint32)gDropdownItemsArgs[i];
|
||||
if (item == (uint16)-2 && gDropdownHighlightedIndex == i)
|
||||
image++;
|
||||
|
||||
|
|
|
@ -375,7 +375,7 @@ void window_editor_bottom_toolbar_jump_forward_to_save_scenario()
|
|||
s6Info->editor_step = 255;
|
||||
|
||||
// Ensure path has .SC6 extension
|
||||
path_set_extension(path, ".SC6");
|
||||
path_append_extension(path, ".SC6");
|
||||
|
||||
// Save the scenario
|
||||
parkFlagsBackup = RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32);
|
||||
|
|
|
@ -155,8 +155,6 @@ static rct_window_event_list window_editor_inventions_list_drag_events = {
|
|||
|
||||
rct_research_item *_editorInventionsListDraggedItem;
|
||||
|
||||
#define WindowHighlightedItem(w) *((rct_research_item**)&(w->highlighted_item))
|
||||
|
||||
static void window_editor_inventions_list_drag_open(rct_research_item *researchItem);
|
||||
static void move_research_item(rct_research_item *beforeItem);
|
||||
|
||||
|
@ -437,7 +435,7 @@ static void move_research_item(rct_research_item *beforeItem)
|
|||
|
||||
w = window_find_by_class(WC_EDITOR_INVENTION_LIST);
|
||||
if (w != NULL) {
|
||||
WindowHighlightedItem(w) = NULL;
|
||||
w->research_item = NULL;
|
||||
window_invalidate(w);
|
||||
}
|
||||
}
|
||||
|
@ -549,7 +547,7 @@ void window_editor_inventions_list_open()
|
|||
window_init_scroll_widgets(w);
|
||||
w->var_4AE = 0;
|
||||
w->selected_tab = 0;
|
||||
WindowHighlightedItem(w) = NULL;
|
||||
w->research_item = NULL;
|
||||
_editorInventionsListDraggedItem = NULL;
|
||||
}
|
||||
|
||||
|
@ -668,8 +666,8 @@ static void window_editor_inventions_list_scrollmouseover(rct_window *w, int scr
|
|||
rct_research_item *researchItem;
|
||||
|
||||
researchItem = window_editor_inventions_list_get_item_from_scroll_y(scrollIndex, y);
|
||||
if (researchItem != WindowHighlightedItem(w)) {
|
||||
WindowHighlightedItem(w) = researchItem;
|
||||
if (researchItem != w->research_item) {
|
||||
w->research_item = researchItem;
|
||||
window_invalidate(w);
|
||||
}
|
||||
}
|
||||
|
@ -770,7 +768,7 @@ static void window_editor_inventions_list_paint(rct_window *w, rct_drawpixelinfo
|
|||
|
||||
researchItem = _editorInventionsListDraggedItem;
|
||||
if (researchItem == NULL)
|
||||
researchItem = WindowHighlightedItem(w);
|
||||
researchItem = w->research_item;
|
||||
// If the research item is null or a list separator.
|
||||
if (researchItem == NULL || researchItem->entryIndex < 0)
|
||||
return;
|
||||
|
@ -842,7 +840,7 @@ static void window_editor_inventions_list_scrollpaint(rct_window *w, rct_drawpix
|
|||
continue;
|
||||
|
||||
colour = 142;
|
||||
if (WindowHighlightedItem(w) == researchItem) {
|
||||
if (w->research_item == researchItem) {
|
||||
if (_editorInventionsListDraggedItem == NULL) {
|
||||
// Highlight
|
||||
top = itemY;
|
||||
|
@ -912,8 +910,8 @@ static void window_editor_inventions_list_drag_open(rct_research_item *researchI
|
|||
window_editor_inventions_list_drag_widgets[0].right = stringWidth;
|
||||
|
||||
w = window_create(
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_CURSOR_X, uint16) - (stringWidth / 2),
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_CURSOR_Y, uint16) - 7,
|
||||
gTooltipCursorX - (stringWidth / 2),
|
||||
gTooltipCursorY - 7,
|
||||
stringWidth,
|
||||
14,
|
||||
&window_editor_inventions_list_drag_events,
|
||||
|
@ -922,9 +920,7 @@ static void window_editor_inventions_list_drag_open(rct_research_item *researchI
|
|||
);
|
||||
w->widgets = window_editor_inventions_list_drag_widgets;
|
||||
w->colours[1] = 2;
|
||||
input_window_position_begin(
|
||||
w, 0, RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_CURSOR_X, uint16), RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_CURSOR_Y, uint16)
|
||||
);
|
||||
input_window_position_begin(w, 0, gTooltipCursorX, gTooltipCursorY);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -939,8 +935,8 @@ static void window_editor_inventions_list_drag_cursor(rct_window *w, int widgetI
|
|||
inventionListWindow = window_find_by_class(WC_EDITOR_INVENTION_LIST);
|
||||
if (inventionListWindow != NULL) {
|
||||
researchItem = get_research_item_at(x, y);
|
||||
if (researchItem != WindowHighlightedItem(inventionListWindow)) {
|
||||
WindowHighlightedItem(inventionListWindow) = researchItem;
|
||||
if (researchItem != inventionListWindow->research_item) {
|
||||
inventionListWindow = (rct_window *)researchItem;
|
||||
window_invalidate(inventionListWindow);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "dropdown.h"
|
||||
#include "error.h"
|
||||
#include "../util/util.h"
|
||||
#include "../world/footpath.h"
|
||||
|
||||
|
||||
enum {
|
||||
|
@ -419,7 +420,7 @@ void window_editor_object_selection_open()
|
|||
window->var_4AE = 0;
|
||||
window->selected_tab = 0;
|
||||
window->selected_list_item = -1;
|
||||
window->highlighted_item = 0xFFFFFFFF;
|
||||
window->object_entry = (rct_object_entry *) 0xFFFFFFFF;
|
||||
window->min_width = 600;
|
||||
window->min_height = 400;
|
||||
window->max_width = 1200;
|
||||
|
@ -577,7 +578,6 @@ static void setup_in_use_selection_flags(){
|
|||
map_element_iterator_begin(&iter);
|
||||
do {
|
||||
uint16 type;
|
||||
uint8 path_additions;
|
||||
rct_banner* banner;
|
||||
|
||||
switch (map_element_get_type(iter.element)) {
|
||||
|
@ -591,10 +591,9 @@ static void setup_in_use_selection_flags(){
|
|||
assert(type < object_entry_group_counts[OBJECT_TYPE_PATHS]);
|
||||
RCT2_ADDRESS(0x0098DA38, uint8*)[OBJECT_TYPE_PATHS][type] |= (1 << 0);
|
||||
|
||||
path_additions = iter.element->properties.path.additions & 0xF;
|
||||
if (path_additions){
|
||||
path_additions--;
|
||||
RCT2_ADDRESS(0x0098DA38, uint8*)[OBJECT_TYPE_PATH_BITS][path_additions] |= (1 << 0);
|
||||
if (footpath_element_has_path_scenery(iter.element)) {
|
||||
uint8 path_additions = footpath_element_get_path_scenery_index(iter.element);
|
||||
RCT2_ADDRESS(0x0098DA38, uint8*)[OBJECT_TYPE_PATH_BITS][path_additions] |= 1;
|
||||
}
|
||||
break;
|
||||
case MAP_ELEMENT_TYPE_SCENERY:
|
||||
|
@ -836,7 +835,7 @@ static void window_editor_object_selection_mouseup(rct_window *w, int widgetInde
|
|||
visible_list_refresh(w);
|
||||
|
||||
w->selected_list_item = -1;
|
||||
w->highlighted_item = 0xFFFFFFFF;
|
||||
w->object_entry = (rct_object_entry *) 0xFFFFFFFF;
|
||||
w->scrolls[0].v_top = 0;
|
||||
object_free_scenario_text();
|
||||
window_invalidate(w);
|
||||
|
@ -856,7 +855,7 @@ static void window_editor_object_selection_mouseup(rct_window *w, int widgetInde
|
|||
visible_list_refresh(w);
|
||||
|
||||
w->selected_list_item = -1;
|
||||
w->highlighted_item = 0xFFFFFFFF;
|
||||
w->object_entry = (rct_object_entry *) 0xFFFFFFFF;
|
||||
w->scrolls[0].v_top = 0;
|
||||
object_free_scenario_text();
|
||||
window_invalidate(w);
|
||||
|
@ -1051,7 +1050,7 @@ static void window_editor_object_selection_scroll_mouseover(rct_window *w, int s
|
|||
return;
|
||||
|
||||
w->selected_list_item = selectedObject;
|
||||
w->highlighted_item = (uint32)installedEntry;
|
||||
w->object_entry = installedEntry;
|
||||
object_free_scenario_text();
|
||||
if (selectedObject != -1)
|
||||
object_get_scenario_text(installedEntry);
|
||||
|
@ -1342,7 +1341,7 @@ static void window_editor_object_selection_paint(rct_window *w, rct_drawpixelinf
|
|||
if (w->selected_list_item == -1 || stex_entry == NULL)
|
||||
return;
|
||||
|
||||
highlightedEntry = (rct_object_entry*)w->highlighted_item;
|
||||
highlightedEntry = w->object_entry;
|
||||
type = highlightedEntry->flags & 0x0F;
|
||||
|
||||
// Draw preview
|
||||
|
@ -1458,7 +1457,7 @@ static void window_editor_object_selection_scrollpaint(rct_window *w, rct_drawpi
|
|||
|
||||
// Highlight background
|
||||
colour = 142;
|
||||
if (listItem->entry == (rct_object_entry*)w->highlighted_item && !(*listItem->flags & OBJECT_SELECTION_FLAG_6)) {
|
||||
if (listItem->entry == w->object_entry && !(*listItem->flags & OBJECT_SELECTION_FLAG_6)) {
|
||||
gfx_fill_rect(dpi, 0, y, w->width, y + 11, 0x2000031);
|
||||
colour = 14;
|
||||
}
|
||||
|
@ -1515,7 +1514,7 @@ static void window_editor_object_set_page(rct_window *w, int page)
|
|||
|
||||
w->selected_tab = page;
|
||||
w->selected_list_item = -1;
|
||||
w->highlighted_item = 0xFFFFFFFF;
|
||||
w->object_entry = (rct_object_entry *)0xFFFFFFFF;
|
||||
w->scrolls[0].v_top = 0;
|
||||
object_free_scenario_text();
|
||||
|
||||
|
|
|
@ -534,9 +534,9 @@ static void window_editor_objective_options_show_category_dropdown(rct_window *w
|
|||
|
||||
dropdownWidget = &w->widgets[WIDX_CATEGORY];
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
for (i = SCENARIO_CATEGORY_BEGINNER; i <= SCENARIO_CATEGORY_OTHER; i++) {
|
||||
gDropdownItemsFormat[i] = 1142;
|
||||
gDropdownItemsArgs[i] = STR_BEGINNER_PARKS + i;
|
||||
gDropdownItemsArgs[i] = ScenarioCategoryStringIds[i];
|
||||
}
|
||||
window_dropdown_show_text_custom_width(
|
||||
w->x + dropdownWidget->left,
|
||||
|
@ -1036,7 +1036,7 @@ static void window_editor_objective_options_main_paint(rct_window *w, rct_drawpi
|
|||
// Scenario category value
|
||||
x = w->x + w->widgets[WIDX_CATEGORY].left + 1;
|
||||
y = w->y + w->widgets[WIDX_CATEGORY].top;
|
||||
stringId = STR_BEGINNER_PARKS + s6Info->category;
|
||||
stringId = ScenarioCategoryStringIds[s6Info->category];
|
||||
gfx_draw_string_left(dpi, 1193, &stringId, 0, x, y);
|
||||
}
|
||||
|
||||
|
|
|
@ -217,7 +217,7 @@ void window_footpath_open()
|
|||
tool_cancel();
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PATH_CONSTRUCTION_MODE, uint8) = PATH_CONSTRUCTION_MODE_LAND;
|
||||
tool_set(window, WIDX_CONSTRUCT_ON_LAND, 17);
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_6;
|
||||
gInputFlags |= INPUT_FLAG_6;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PATH_ERROR_OCCURED, uint8) = 0;
|
||||
window_footpath_set_enabled_and_pressed_widgets();
|
||||
}
|
||||
|
@ -263,7 +263,7 @@ static void window_footpath_mouseup(rct_window *w, int widgetIndex)
|
|||
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~2;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PATH_CONSTRUCTION_MODE, uint8) = PATH_CONSTRUCTION_MODE_LAND;
|
||||
tool_set(w, WIDX_CONSTRUCT_ON_LAND, 17);
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_6;
|
||||
gInputFlags |= INPUT_FLAG_6;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PATH_ERROR_OCCURED, uint8) = 0;
|
||||
window_footpath_set_enabled_and_pressed_widgets();
|
||||
break;
|
||||
|
@ -278,7 +278,7 @@ static void window_footpath_mouseup(rct_window *w, int widgetIndex)
|
|||
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~2;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PATH_CONSTRUCTION_MODE, uint8) = PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL_TOOL;
|
||||
tool_set(w, WIDX_CONSTRUCT_BRIDGE_OR_TUNNEL, 12);
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_6;
|
||||
gInputFlags |= INPUT_FLAG_6;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PATH_ERROR_OCCURED, uint8) = 0;
|
||||
window_footpath_set_enabled_and_pressed_widgets();
|
||||
break;
|
||||
|
@ -479,14 +479,14 @@ static void window_footpath_update(rct_window *w)
|
|||
|
||||
// Check tool
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_PATH_CONSTRUCTION_MODE, uint8) == PATH_CONSTRUCTION_MODE_LAND) {
|
||||
if (!(RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE))
|
||||
if (!(gInputFlags & INPUT_FLAG_TOOL_ACTIVE))
|
||||
window_close(w);
|
||||
else if (RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) != WC_FOOTPATH)
|
||||
window_close(w);
|
||||
else if (RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16) != WIDX_CONSTRUCT_ON_LAND)
|
||||
window_close(w);
|
||||
} else if (RCT2_GLOBAL(RCT2_ADDRESS_PATH_CONSTRUCTION_MODE, uint8) == PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL_TOOL) {
|
||||
if (!(RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE))
|
||||
if (!(gInputFlags & INPUT_FLAG_TOOL_ACTIVE))
|
||||
window_close(w);
|
||||
else if (RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) != WC_FOOTPATH)
|
||||
window_close(w);
|
||||
|
|
|
@ -20,10 +20,12 @@
|
|||
|
||||
#include "../addresses.h"
|
||||
#include "../config.h"
|
||||
#include "../localisation/date.h"
|
||||
#include "../localisation/localisation.h"
|
||||
#include "../input.h"
|
||||
#include "../interface/themes.h"
|
||||
#include "../interface/widget.h"
|
||||
#include "../interface/window.h"
|
||||
#include "../localisation/date.h"
|
||||
#include "../localisation/localisation.h"
|
||||
#include "../management/news_item.h"
|
||||
#include "../peep/peep.h"
|
||||
#include "../peep/staff.h"
|
||||
|
@ -31,7 +33,6 @@
|
|||
#include "../world/climate.h"
|
||||
#include "../world/park.h"
|
||||
#include "../world/sprite.h"
|
||||
#include "../interface/themes.h"
|
||||
|
||||
enum WINDOW_GAME_BOTTOM_TOOLBAR_WIDGET_IDX {
|
||||
WIDX_LEFT_OUTSET,
|
||||
|
@ -85,7 +86,6 @@ static void window_game_bottom_toolbar_draw_left_panel(rct_drawpixelinfo *dpi, r
|
|||
static void window_game_bottom_toolbar_draw_park_rating(rct_drawpixelinfo *dpi, rct_window *w, int colour, int x, int y, uint8 factor);
|
||||
static void window_game_bottom_toolbar_draw_right_panel(rct_drawpixelinfo *dpi, rct_window *w);
|
||||
static void window_game_bottom_toolbar_draw_news_item(rct_drawpixelinfo *dpi, rct_window *w);
|
||||
static void window_game_bottom_toolbar_draw_tutorial_text(rct_drawpixelinfo *dpi, rct_window *w);
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -358,8 +358,6 @@ static void window_game_bottom_toolbar_paint(rct_window *w, rct_drawpixelinfo *d
|
|||
|
||||
if (!news_item_is_queue_empty())
|
||||
window_game_bottom_toolbar_draw_news_item(dpi, w);
|
||||
else if (RCT2_GLOBAL(RCT2_ADDRESS_ON_TUTORIAL, uint8))
|
||||
window_game_bottom_toolbar_draw_tutorial_text(dpi, w);
|
||||
}
|
||||
|
||||
static void window_game_bottom_toolbar_draw_left_panel(rct_drawpixelinfo *dpi, rct_window *w)
|
||||
|
@ -551,7 +549,7 @@ static void window_game_bottom_toolbar_draw_news_item(rct_drawpixelinfo *dpi, rc
|
|||
}
|
||||
}
|
||||
|
||||
uint32 image_id_base = *RCT2_ADDRESS(0x00982708, uint32*)[peep->sprite_type * 2];
|
||||
uint32 image_id_base = g_sprite_entries[peep->sprite_type].sprite_image->base_image;
|
||||
image_id_base += w->frame_no & 0xFFFFFFFC;
|
||||
image_id_base++;
|
||||
|
||||
|
@ -599,16 +597,6 @@ static void window_game_bottom_toolbar_draw_news_item(rct_drawpixelinfo *dpi, rc
|
|||
}
|
||||
}
|
||||
|
||||
static void window_game_bottom_toolbar_draw_tutorial_text(rct_drawpixelinfo *dpi, rct_window *w)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
x = (window_game_bottom_toolbar_widgets[WIDX_MIDDLE_OUTSET].left + window_game_bottom_toolbar_widgets[WIDX_MIDDLE_OUTSET].right) / 2 + w->x;
|
||||
y = window_game_bottom_toolbar_widgets[WIDX_MIDDLE_OUTSET].top + w->y + 2;
|
||||
gfx_draw_string_centred(dpi, STR_TUTORIAL, x, y, 32, 0);
|
||||
gfx_draw_string_centred(dpi, STR_PRESS_KEY_OR_MOUSE_BUTTON_FOR_CONTROL, x, y + 10, 32, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x0066C6D8
|
||||
|
@ -633,7 +621,7 @@ static void window_game_bottom_toolbar_cursor(rct_window *w, int widgetIndex, in
|
|||
case WIDX_GUESTS:
|
||||
case WIDX_PARK_RATING:
|
||||
case WIDX_DATE:
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_TIMEOUT, uint16) = 2000;
|
||||
gTooltipTimeout = 2000;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -503,7 +503,7 @@ void window_guest_open(rct_peep* peep){
|
|||
window->viewport_focus_coordinates.y = 0;
|
||||
window->frame_no = 0;
|
||||
window->list_information_type = 0;
|
||||
window->var_492 = 0;
|
||||
window->picked_peep_frame = 0;
|
||||
window->highlighted_item = 0;
|
||||
window_guest_disable_widgets(window);
|
||||
window->min_width = 192;
|
||||
|
@ -560,7 +560,7 @@ void window_guest_disable_widgets(rct_window* w){
|
|||
*/
|
||||
void window_guest_overview_close(rct_window *w)
|
||||
{
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE){
|
||||
if (gInputFlags & INPUT_FLAG_TOOL_ACTIVE){
|
||||
if (w->classification == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS,rct_windowclass) &&
|
||||
w->number == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER,rct_windownumber))
|
||||
tool_cancel();
|
||||
|
@ -625,7 +625,7 @@ void window_guest_overview_mouse_up(rct_window *w, int widgetIndex)
|
|||
return;
|
||||
}
|
||||
|
||||
w->var_48C = peep->x;
|
||||
w->picked_peep_old_x = peep->x;
|
||||
|
||||
remove_peep_from_ride(peep);
|
||||
invalidate_sprite_2((rct_sprite*)peep);
|
||||
|
@ -653,7 +653,7 @@ void window_guest_overview_mouse_up(rct_window *w, int widgetIndex)
|
|||
* rct2: 0x696AA0
|
||||
*/
|
||||
void window_guest_set_page(rct_window* w, int page){
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE)
|
||||
if (gInputFlags & INPUT_FLAG_TOOL_ACTIVE)
|
||||
{
|
||||
if(w->number == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber) &&
|
||||
w->classification == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass))
|
||||
|
@ -830,7 +830,7 @@ void window_guest_overview_tab_paint(rct_window* w, rct_drawpixelinfo* dpi){
|
|||
if (peep->type == PEEP_TYPE_STAFF && peep->staff_type == STAFF_TYPE_ENTERTAINER)
|
||||
y++;
|
||||
|
||||
int ebx = *(RCT2_ADDRESS(0x982708, uint32*)[peep->sprite_type * 2]) + 1;
|
||||
int ebx = g_sprite_entries[peep->sprite_type].sprite_image->base_image + 1;
|
||||
|
||||
int eax = 0;
|
||||
|
||||
|
@ -1182,7 +1182,7 @@ void window_guest_overview_tool_update(rct_window* w, int widgetIndex, int x, in
|
|||
map_invalidate_selection_rect();
|
||||
}
|
||||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_SPRITE, sint32) = -1;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_IMAGE, sint32) = -1;
|
||||
|
||||
int interactionType;
|
||||
get_map_coordinates_from_pos(x, y, VIEWPORT_INTERACTION_MASK_NONE, NULL, NULL, &interactionType, NULL, NULL);
|
||||
|
@ -1193,19 +1193,21 @@ void window_guest_overview_tool_update(rct_window* w, int widgetIndex, int x, in
|
|||
y += 16;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_X, uint16) = x;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_Y, uint16) = y;
|
||||
w->var_492++;
|
||||
if (w->var_492 >= 48)w->var_492 = 0;
|
||||
w->picked_peep_frame++;
|
||||
if (w->picked_peep_frame >= 48) {
|
||||
w->picked_peep_frame = 0;
|
||||
}
|
||||
|
||||
rct_peep* peep;
|
||||
peep = GET_PEEP(w->number);
|
||||
int ebx = (RCT2_ADDRESS(0x982708, uint32*)[peep->sprite_type * 2])[22];
|
||||
ebx += w->var_492 >> 2;
|
||||
uint32 imageId = g_sprite_entries[peep->sprite_type].sprite_image[11].base_image;
|
||||
imageId += w->picked_peep_frame >> 2;
|
||||
|
||||
int ebp = peep->tshirt_colour << 19;
|
||||
int ecx = peep->trousers_colour << 24;
|
||||
|
||||
ebx |= ebp | ecx | 0xA0000000;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_SPRITE, uint32) = ebx;
|
||||
imageId |= ebp | ecx | 0xA0000000;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_IMAGE, uint32) = imageId;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1254,7 +1256,7 @@ void window_guest_overview_tool_down(rct_window* w, int widgetIndex, int x, int
|
|||
peep->state = 0;
|
||||
peep_window_state_update(peep);
|
||||
peep->action = 0xFF;
|
||||
peep->var_6D = 0;
|
||||
peep->special_sprite = 0;
|
||||
peep->action_sprite_image_offset = 0;
|
||||
peep->action_sprite_type = 0xFF;
|
||||
peep->var_C4 = 0;
|
||||
|
@ -1279,7 +1281,7 @@ void window_guest_overview_tool_abort(rct_window *w, int widgetIndex)
|
|||
if (peep->state != PEEP_STATE_PICKED)
|
||||
return;
|
||||
|
||||
sprite_move( w->var_48C, peep->y, peep->z + 8, (rct_sprite*)peep);
|
||||
sprite_move(w->picked_peep_old_x, peep->y, peep->z + 8, (rct_sprite*)peep);
|
||||
invalidate_sprite_2((rct_sprite*)peep);
|
||||
|
||||
if (peep->x != (sint16)0x8000){
|
||||
|
@ -1287,13 +1289,13 @@ void window_guest_overview_tool_abort(rct_window *w, int widgetIndex)
|
|||
peep->state = 0;
|
||||
peep_window_state_update(peep);
|
||||
peep->action = 0xFF;
|
||||
peep->var_6D = 0;
|
||||
peep->special_sprite = 0;
|
||||
peep->action_sprite_image_offset = 0;
|
||||
peep->action_sprite_type = 0;
|
||||
peep->var_C4 = 0;
|
||||
}
|
||||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_SPRITE, sint32) = -1;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_IMAGE, sint32) = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -590,7 +590,7 @@ static void window_guest_list_paint(rct_window *w, rct_drawpixelinfo *dpi)
|
|||
window_draw_widgets(w, dpi);
|
||||
// Tab 1 image
|
||||
i = (_window_guest_list_selected_tab == 0 ? w->list_information_type & 0x0FFFFFFFC : 0);
|
||||
i += RCT2_ADDRESS(RCT2_GLOBAL(0x00982708, int), int)[0] + 1;
|
||||
i += g_sprite_entries[0].sprite_image->base_image + 1;
|
||||
i |= 0xA1600000;
|
||||
gfx_draw_sprite(
|
||||
dpi,
|
||||
|
@ -655,14 +655,14 @@ static void window_guest_list_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi,
|
|||
|
||||
// For each guest
|
||||
FOR_ALL_GUESTS(spriteIndex, peep) {
|
||||
peep->var_0C &= ~0x200;
|
||||
peep->list_flags &= ~(PEEP_LIST_FLAGS_FLASHING);
|
||||
if (peep->outside_of_park != 0)
|
||||
continue;
|
||||
if (_window_guest_list_selected_filter != -1) {
|
||||
if (window_guest_list_is_peep_in_filter(peep))
|
||||
continue;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_WINDOW_MAP_FLASHING_FLAGS, uint16) |= (1 << 0);
|
||||
peep->var_0C |= 0x200;
|
||||
peep->list_flags |= PEEP_LIST_FLAGS_FLASHING;
|
||||
}
|
||||
if (_window_guest_list_tracking_only && !(peep->flags & PEEP_FLAGS_TRACKING))
|
||||
continue;
|
||||
|
@ -841,11 +841,11 @@ static void window_guest_list_find_groups()
|
|||
// Set all guests to unassigned
|
||||
FOR_ALL_GUESTS(spriteIndex, peep)
|
||||
if (peep->outside_of_park == 0)
|
||||
peep->var_0C |= (1 << 8);
|
||||
peep->list_flags |= PEEP_LIST_FLAGS_VISIBLE;
|
||||
|
||||
// For each guest / group
|
||||
FOR_ALL_GUESTS(spriteIndex, peep) {
|
||||
if (peep->outside_of_park != 0 || !(peep->var_0C & (1 << 8)))
|
||||
if (peep->outside_of_park != 0 || !(peep->list_flags & PEEP_LIST_FLAGS_VISIBLE))
|
||||
continue;
|
||||
|
||||
// New group, cap at 240 though
|
||||
|
@ -856,7 +856,7 @@ static void window_guest_list_find_groups()
|
|||
int ax = peep->sprite_index;
|
||||
_window_guest_list_num_groups++;
|
||||
_window_guest_list_groups_num_guests[groupIndex] = 1;
|
||||
peep->var_0C &= ~(1 << 8);
|
||||
peep->list_flags &= ~(PEEP_LIST_FLAGS_VISIBLE);
|
||||
|
||||
get_arguments_from_peep( peep, &_window_guest_list_groups_argument_1[groupIndex], &_window_guest_list_groups_argument_2[groupIndex]);
|
||||
RCT2_GLOBAL(0x00F1EDF6, uint32) = _window_guest_list_groups_argument_1[groupIndex];
|
||||
|
@ -868,7 +868,7 @@ static void window_guest_list_find_groups()
|
|||
|
||||
// Find more peeps that belong to same group
|
||||
FOR_ALL_GUESTS(spriteIndex2, peep2) {
|
||||
if (peep2->outside_of_park != 0 || !(peep2->var_0C & (1 << 8)))
|
||||
if (peep2->outside_of_park != 0 || !(peep2->list_flags & PEEP_LIST_FLAGS_VISIBLE))
|
||||
continue;
|
||||
|
||||
uint32 argument1, argument2;
|
||||
|
@ -879,7 +879,7 @@ static void window_guest_list_find_groups()
|
|||
|
||||
// Assign guest
|
||||
_window_guest_list_groups_num_guests[groupIndex]++;
|
||||
peep2->var_0C &= ~(1 << 8);
|
||||
peep2->list_flags &= ~(PEEP_LIST_FLAGS_VISIBLE);
|
||||
|
||||
// Add face sprite, cap at 56 though
|
||||
if (_window_guest_list_groups_num_guests[groupIndex] >= 56)
|
||||
|
|
|
@ -272,7 +272,7 @@ static void window_land_dropdown(rct_window *w, int widgetIndex, int dropdownInd
|
|||
|
||||
type = (dropdownIndex == -1) ?
|
||||
_selectedFloorTexture :
|
||||
*((uint32*)&gDropdownItemsArgs[dropdownIndex]) - SPR_FLOOR_TEXTURE_GRASS;
|
||||
(uint32)gDropdownItemsArgs[dropdownIndex] - SPR_FLOOR_TEXTURE_GRASS;
|
||||
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_TERRAIN_SURFACE, uint8) == type) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_TERRAIN_SURFACE, uint8) = 255;
|
||||
|
@ -288,7 +288,7 @@ static void window_land_dropdown(rct_window *w, int widgetIndex, int dropdownInd
|
|||
|
||||
type = (dropdownIndex == -1) ?
|
||||
_selectedWallTexture :
|
||||
*((uint32*)&gDropdownItemsArgs[dropdownIndex]) - SPR_WALL_TEXTURE_ROCK;
|
||||
(uint32)gDropdownItemsArgs[dropdownIndex] - SPR_WALL_TEXTURE_ROCK;
|
||||
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_TERRAIN_EDGE, uint8) == type) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_TERRAIN_EDGE, uint8) = 255;
|
||||
|
@ -321,8 +321,8 @@ static void window_land_textinput(rct_window *w, int widgetIndex, char *text)
|
|||
|
||||
static void window_land_inputsize(rct_window *w)
|
||||
{
|
||||
((uint16*)TextInputDescriptionArgs)[0] = MINIMUM_TOOL_SIZE;
|
||||
((uint16*)TextInputDescriptionArgs)[1] = MAXIMUM_TOOL_SIZE;
|
||||
TextInputDescriptionArgs[0] = MINIMUM_TOOL_SIZE;
|
||||
TextInputDescriptionArgs[1] = MAXIMUM_TOOL_SIZE;
|
||||
window_text_input_open(w, WIDX_PREVIEW, 5128, 5129, STR_NONE, STR_NONE, 3);
|
||||
}
|
||||
|
||||
|
|
|
@ -188,8 +188,8 @@ static void window_land_rights_textinput(rct_window *w, int widgetIndex, char *t
|
|||
|
||||
static void window_land_rights_inputsize(rct_window *w)
|
||||
{
|
||||
((uint16*)TextInputDescriptionArgs)[0] = MINIMUM_TOOL_SIZE;
|
||||
((uint16*)TextInputDescriptionArgs)[1] = MAXIMUM_TOOL_SIZE;
|
||||
TextInputDescriptionArgs[0] = MINIMUM_TOOL_SIZE;
|
||||
TextInputDescriptionArgs[1] = MAXIMUM_TOOL_SIZE;
|
||||
window_text_input_open(w, WIDX_PREVIEW, 5128, 5129, STR_NONE, STR_NONE, 3);
|
||||
}
|
||||
|
||||
|
@ -237,7 +237,7 @@ static void window_land_rights_paint(rct_window *w, rct_drawpixelinfo *dpi)
|
|||
|
||||
static int window_land_rights_should_close()
|
||||
{
|
||||
if (!(RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE))
|
||||
if (!(gInputFlags & INPUT_FLAG_TOOL_ACTIVE))
|
||||
return 1;
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) != WC_PARK_INFORMATION)
|
||||
return 1;
|
||||
|
|
|
@ -144,8 +144,6 @@ static void window_loadsave_sort_list(int index, int endIndex);
|
|||
|
||||
static int has_extension(char *path, char *extension);
|
||||
|
||||
static void shorten_path(char* path, char* buffer, int available_width);
|
||||
|
||||
static rct_window *window_overwrite_prompt_open(const char *name, const char *path);
|
||||
|
||||
rct_window *window_loadsave_open(int type, char *defaultName)
|
||||
|
@ -160,7 +158,6 @@ rct_window *window_loadsave_open(int type, char *defaultName)
|
|||
|
||||
if (!str_is_null_or_empty(defaultName)) {
|
||||
safe_strncpy(_defaultName, defaultName, sizeof(_defaultName));
|
||||
path_remove_extension(_defaultName);
|
||||
}
|
||||
|
||||
w = window_bring_to_front_by_class(WC_LOADSAVE);
|
||||
|
@ -221,21 +218,12 @@ rct_window *window_loadsave_open(int type, char *defaultName)
|
|||
window_loadsave_populate_list(w, includeNewItem, path, ".sc6");
|
||||
break;
|
||||
case LOADSAVETYPE_SCENARIO:
|
||||
/*
|
||||
Uncomment when user scenarios are separated
|
||||
|
||||
platform_get_user_directory(path, "scenario");
|
||||
if (!platform_ensure_directory_exists(path)) {
|
||||
log_error("Unable to create scenarios directory.");
|
||||
window_close(w);
|
||||
return NULL;
|
||||
log_error("Unable to create scenarios directory.");
|
||||
window_close(w);
|
||||
return NULL;
|
||||
}
|
||||
*/
|
||||
|
||||
safe_strncpy(path, RCT2_ADDRESS(RCT2_ADDRESS_SCENARIOS_PATH, char), MAX_PATH);
|
||||
ch = strchr(path, '*');
|
||||
if (ch != NULL)
|
||||
*ch = 0;
|
||||
|
||||
window_loadsave_populate_list(w, includeNewItem, path, ".sc6");
|
||||
break;
|
||||
|
@ -306,12 +294,13 @@ static void window_loadsave_mouseup(rct_window *w, int widgetIndex)
|
|||
}
|
||||
case WIDX_BROWSE:
|
||||
safe_strncpy(path, _directory, MAX_PATH);
|
||||
if (_type & LOADSAVETYPE_SAVE)
|
||||
strcat(path, (char*)RCT2_ADDRESS_SCENARIO_NAME);
|
||||
if (_type & LOADSAVETYPE_SAVE) {
|
||||
strcat(path, _defaultName);
|
||||
}
|
||||
|
||||
memset(filter, '\0', MAX_PATH);
|
||||
safe_strncpy(filter, "*", MAX_PATH);
|
||||
strncat(filter, _extension, MAX_PATH);
|
||||
strncat(filter, _extension, MAX_PATH - strnlen(filter, MAX_PATH) - 1);
|
||||
|
||||
switch (_type) {
|
||||
case (LOADSAVETYPE_LOAD | LOADSAVETYPE_GAME) :
|
||||
|
@ -336,7 +325,7 @@ static void window_loadsave_mouseup(rct_window *w, int widgetIndex)
|
|||
|
||||
if (result) {
|
||||
if (!has_extension(path, _extension)) {
|
||||
strncat(path, _extension, MAX_PATH);
|
||||
strncat(path, _extension, sizeof(path) - strnlen(path, sizeof(path)) - 1);
|
||||
}
|
||||
window_loadsave_select(w, path);
|
||||
}
|
||||
|
@ -480,8 +469,9 @@ static void window_loadsave_paint(rct_window *w, rct_drawpixelinfo *dpi)
|
|||
{
|
||||
window_draw_widgets(w, dpi);
|
||||
|
||||
if (_shortenedDirectory[0] == '\0')
|
||||
shorten_path(_directory, _shortenedDirectory, w->width - 8);
|
||||
if (_shortenedDirectory[0] == '\0') {
|
||||
shorten_path(_shortenedDirectory, sizeof(_shortenedDirectory), _directory, w->width - 8);
|
||||
}
|
||||
|
||||
utf8 buffer[256];
|
||||
|
||||
|
@ -510,41 +500,6 @@ static void window_loadsave_paint(rct_window *w, rct_drawpixelinfo *dpi)
|
|||
gfx_draw_string_centred_clipped(dpi, STR_DATE, &id, 1, w->x + 4 + (w->width - 8) * 3 / 4, w->y + 50, (w->width - 8) / 2);
|
||||
}
|
||||
|
||||
static void shorten_path(char* path, char* buffer, int available_width){
|
||||
int length = strlen(path);
|
||||
|
||||
// Return full string if it fits
|
||||
if (gfx_get_string_width(path) <= available_width){
|
||||
strcpy(buffer, path);
|
||||
return;
|
||||
}
|
||||
|
||||
// Count path separators
|
||||
int path_separators = 0;
|
||||
for (int x = 0; x < length; x++)
|
||||
if (path[x] == platform_get_path_separator())
|
||||
path_separators++;
|
||||
|
||||
// TODO: Replace with unicode ellipsis when supported
|
||||
strcpy(buffer, "...");
|
||||
|
||||
// Abreviate beginning with xth separator
|
||||
|
||||
int begin = -1;
|
||||
for (int x = 0; x < path_separators; x++){
|
||||
do {
|
||||
begin++;
|
||||
} while (path[begin] != platform_get_path_separator());
|
||||
|
||||
strcpy(buffer + 3, path + begin);
|
||||
if (gfx_get_string_width(buffer) <= available_width)
|
||||
return;
|
||||
}
|
||||
|
||||
strcpy(buffer, path);
|
||||
return;
|
||||
}
|
||||
|
||||
static void window_loadsave_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, int scrollIndex)
|
||||
{
|
||||
int i, y;
|
||||
|
@ -684,7 +639,7 @@ static void window_loadsave_populate_list(rct_window *w, int includeNewItem, con
|
|||
listItem = &_listItems[_listItemsCount];
|
||||
memset(listItem->path, '\0', MAX_PATH);
|
||||
safe_strncpy(listItem->path, directory, MAX_PATH);
|
||||
strncat(listItem->path, subDir, MAX_PATH);
|
||||
strncat(listItem->path, subDir, MAX_PATH - strnlen(listItem->path, MAX_PATH) - 1);
|
||||
safe_strncpy(listItem->name, subDir, sizeof(listItem->name));
|
||||
listItem->type = TYPE_DIRECTORY;
|
||||
_listItemsCount++;
|
||||
|
@ -700,7 +655,7 @@ static void window_loadsave_populate_list(rct_window *w, int includeNewItem, con
|
|||
|
||||
listItem = &_listItems[_listItemsCount];
|
||||
safe_strncpy(listItem->path, directory, sizeof(listItem->path));
|
||||
strncat(listItem->path, fileInfo.path, sizeof(listItem->path));
|
||||
strncat(listItem->path, fileInfo.path, sizeof(listItem->path) - strnlen(listItem->path, MAX_PATH) - 1);
|
||||
listItem->type = TYPE_FILE;
|
||||
listItem->date_modified = platform_file_get_modified_time(listItem->path);
|
||||
|
||||
|
|
|
@ -241,7 +241,7 @@ void window_map_open()
|
|||
static void window_map_close(rct_window *w)
|
||||
{
|
||||
free(RCT2_GLOBAL(RCT2_ADDRESS_MAP_IMAGE_DATA, uint32*));
|
||||
if ((RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE) &&
|
||||
if ((gInputFlags & INPUT_FLAG_TOOL_ACTIVE) &&
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, uint8) == w->classification &&
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, uint16) == w->number) {
|
||||
tool_cancel();
|
||||
|
@ -319,7 +319,7 @@ static void window_map_mouseup(rct_window *w, int widgetIndex)
|
|||
break;
|
||||
|
||||
RCT2_GLOBAL(0x9E32D2, sint8) = 0;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_6;
|
||||
gInputFlags |= INPUT_FLAG_6;
|
||||
|
||||
show_gridlines();
|
||||
show_land_rights();
|
||||
|
@ -740,7 +740,7 @@ static void window_map_invalidate(rct_window *w)
|
|||
if ((RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_SCENARIO_EDITOR) || gCheatsSandboxMode) {
|
||||
// scenario editor: build park entrance selected, show rotate button
|
||||
if (
|
||||
(RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE) &&
|
||||
(gInputFlags & INPUT_FLAG_TOOL_ACTIVE) &&
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) == WC_MAP &&
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16) == WIDX_BUILD_PARK_ENTRANCE
|
||||
) {
|
||||
|
@ -752,7 +752,7 @@ static void window_map_invalidate(rct_window *w)
|
|||
|
||||
// If any tool is active
|
||||
if (
|
||||
(RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE) &&
|
||||
(gInputFlags & INPUT_FLAG_TOOL_ACTIVE) &&
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, uint8) == WC_MAP
|
||||
) {
|
||||
// if not in set land rights mode: show the default scenario editor buttons
|
||||
|
@ -935,15 +935,15 @@ static void window_map_show_default_scenario_editor_buttons(rct_window *w) {
|
|||
|
||||
static void window_map_inputsize_land(rct_window *w)
|
||||
{
|
||||
((uint16*)TextInputDescriptionArgs)[0] = MINIMUM_TOOL_SIZE;
|
||||
((uint16*)TextInputDescriptionArgs)[1] = MAXIMUM_TOOL_SIZE;
|
||||
TextInputDescriptionArgs[0] = MINIMUM_TOOL_SIZE;
|
||||
TextInputDescriptionArgs[1] = MAXIMUM_TOOL_SIZE;
|
||||
window_text_input_open(w, WIDX_LAND_TOOL, 5128, 5129, STR_NONE, STR_NONE, 3);
|
||||
}
|
||||
|
||||
static void window_map_inputsize_map(rct_window *w)
|
||||
{
|
||||
((uint16*)TextInputDescriptionArgs)[0] = MINIMUM_MAP_SIZE_PRACTICAL;
|
||||
((uint16*)TextInputDescriptionArgs)[1] = MAXIMUM_MAP_SIZE_PRACTICAL;
|
||||
TextInputDescriptionArgs[0] = MINIMUM_MAP_SIZE_PRACTICAL;
|
||||
TextInputDescriptionArgs[1] = MAXIMUM_MAP_SIZE_PRACTICAL;
|
||||
window_text_input_open(w, WIDX_MAP_SIZE_SPINNER, 5130, 5131, STR_NONE, STR_NONE, 4);
|
||||
}
|
||||
|
||||
|
@ -1028,7 +1028,7 @@ static void window_map_paint_peep_overlay(rct_drawpixelinfo *dpi)
|
|||
|
||||
color = 0x14;
|
||||
|
||||
if ((peep->var_0C & 0x200) != 0) {
|
||||
if ((peep->list_flags & PEEP_LIST_FLAGS_FLASHING) != 0) {
|
||||
if (peep->type == PEEP_TYPE_STAFF) {
|
||||
if ((RCT2_GLOBAL(RCT2_ADDRESS_WINDOW_MAP_FLASHING_FLAGS, uint16) & (1 << 3)) != 0) {
|
||||
color = 0x8A;
|
||||
|
|
|
@ -81,7 +81,7 @@ void window_map_tooltip_update_visibility()
|
|||
|
||||
cursorX = RCT2_GLOBAL(0x0142406C, sint32);
|
||||
cursorY = RCT2_GLOBAL(0x01424070, sint32);
|
||||
inputFlags = RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32);
|
||||
inputFlags = gInputFlags;
|
||||
|
||||
// Check for cursor movement
|
||||
_cursorHoldDuration++;
|
||||
|
|
|
@ -488,19 +488,19 @@ static void window_mapgen_base_mouseup(rct_window *w, int widgetIndex)
|
|||
gfx_invalidate_screen();
|
||||
break;
|
||||
case WIDX_MAP_SIZE:
|
||||
((uint16*)TextInputDescriptionArgs)[0] = MINIMUM_MAP_SIZE_PRACTICAL;
|
||||
((uint16*)TextInputDescriptionArgs)[1] = MAXIMUM_MAP_SIZE_PRACTICAL;
|
||||
TextInputDescriptionArgs[0] = MINIMUM_MAP_SIZE_PRACTICAL;
|
||||
TextInputDescriptionArgs[1] = MAXIMUM_MAP_SIZE_PRACTICAL;
|
||||
// Practical map size is 2 lower than the technical map size
|
||||
window_text_input_open(w, WIDX_MAP_SIZE, 5130, 5131, 5182, _mapSize - 2, 4);
|
||||
break;
|
||||
case WIDX_BASE_HEIGHT:
|
||||
((uint16*)TextInputDescriptionArgs)[0] = (BASESIZE_MIN - 12) / 2;
|
||||
((uint16*)TextInputDescriptionArgs)[1] = (BASESIZE_MAX - 12) / 2;
|
||||
TextInputDescriptionArgs[0] = (BASESIZE_MIN - 12) / 2;
|
||||
TextInputDescriptionArgs[1] = (BASESIZE_MAX - 12) / 2;
|
||||
window_text_input_open(w, WIDX_BASE_HEIGHT, 5183, 5184, 5182, (_baseHeight - 12) / 2, 3);
|
||||
break;
|
||||
case WIDX_WATER_LEVEL:
|
||||
((uint16*)TextInputDescriptionArgs)[0] = (WATERLEVEL_MIN - 12) / 2;
|
||||
((uint16*)TextInputDescriptionArgs)[1] = (WATERLEVEL_MAX - 12) / 2;
|
||||
TextInputDescriptionArgs[0] = (WATERLEVEL_MIN - 12) / 2;
|
||||
TextInputDescriptionArgs[1] = (WATERLEVEL_MAX - 12) / 2;
|
||||
window_text_input_open(w, WIDX_WATER_LEVEL, 5185, 5186, 5182, (_waterLevel - 12) / 2, 3);
|
||||
break;
|
||||
}
|
||||
|
@ -583,7 +583,7 @@ static void window_mapgen_base_dropdown(rct_window *w, int widgetIndex, int drop
|
|||
|
||||
type = (dropdownIndex == -1) ?
|
||||
_floorTexture :
|
||||
*((uint32*)&gDropdownItemsArgs[dropdownIndex]) - SPR_FLOOR_TEXTURE_GRASS;
|
||||
(uint32)gDropdownItemsArgs[dropdownIndex] - SPR_FLOOR_TEXTURE_GRASS;
|
||||
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_TERRAIN_SURFACE, uint8) == type) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_TERRAIN_SURFACE, uint8) = 255;
|
||||
|
@ -599,7 +599,7 @@ static void window_mapgen_base_dropdown(rct_window *w, int widgetIndex, int drop
|
|||
|
||||
type = (dropdownIndex == -1) ?
|
||||
_wallTexture :
|
||||
*((uint32*)&gDropdownItemsArgs[dropdownIndex]) - SPR_WALL_TEXTURE_ROCK;
|
||||
(uint32)gDropdownItemsArgs[dropdownIndex] - SPR_WALL_TEXTURE_ROCK;
|
||||
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_TERRAIN_EDGE, uint8) == type) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_TERRAIN_EDGE, uint8) = 255;
|
||||
|
@ -790,8 +790,8 @@ static void window_mapgen_simplex_mouseup(rct_window *w, int widgetIndex)
|
|||
window_mapgen_set_page(w, widgetIndex - WIDX_TAB_1);
|
||||
break;
|
||||
case WIDX_SIMPLEX_MAP_SIZE:
|
||||
((uint16*)TextInputDescriptionArgs)[0] = MINIMUM_MAP_SIZE_PRACTICAL;
|
||||
((uint16*)TextInputDescriptionArgs)[1] = MAXIMUM_MAP_SIZE_PRACTICAL;
|
||||
TextInputDescriptionArgs[0] = MINIMUM_MAP_SIZE_PRACTICAL;
|
||||
TextInputDescriptionArgs[1] = MAXIMUM_MAP_SIZE_PRACTICAL;
|
||||
// Practical map size is 2 lower than the technical map size
|
||||
window_text_input_open(w, WIDX_SIMPLEX_MAP_SIZE, 5130, 5131, 5182, _mapSize - 2, 4);
|
||||
break;
|
||||
|
@ -916,7 +916,7 @@ static void window_mapgen_simplex_dropdown(rct_window *w, int widgetIndex, int d
|
|||
|
||||
type = (dropdownIndex == -1) ?
|
||||
_floorTexture :
|
||||
*((uint32*)&gDropdownItemsArgs[dropdownIndex]) - SPR_FLOOR_TEXTURE_GRASS;
|
||||
(uint32)gDropdownItemsArgs[dropdownIndex] - SPR_FLOOR_TEXTURE_GRASS;
|
||||
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_TERRAIN_SURFACE, uint8) == type) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_TERRAIN_SURFACE, uint8) = 255;
|
||||
|
@ -933,7 +933,7 @@ static void window_mapgen_simplex_dropdown(rct_window *w, int widgetIndex, int d
|
|||
|
||||
type = (dropdownIndex == -1) ?
|
||||
_wallTexture :
|
||||
*((uint32*)&gDropdownItemsArgs[dropdownIndex]) - SPR_WALL_TEXTURE_ROCK;
|
||||
(uint32)gDropdownItemsArgs[dropdownIndex] - SPR_WALL_TEXTURE_ROCK;
|
||||
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_TERRAIN_EDGE, uint8) == type) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_TERRAIN_EDGE, uint8) = 255;
|
||||
|
|
|
@ -194,7 +194,7 @@ static void window_maze_construction_entrance_mouseup(rct_window *w, int widgetI
|
|||
RCT2_GLOBAL(0x00F44191, uint8) = widgetIndex == WIDX_MAZE_ENTRANCE ? 0 : 1;
|
||||
RCT2_GLOBAL(0x00F44192, uint8) = (uint8)w->number;
|
||||
RCT2_GLOBAL(0x00F44193, uint8) = 0;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_6;
|
||||
gInputFlags |= INPUT_FLAG_6;
|
||||
|
||||
sub_6C9627();
|
||||
|
||||
|
@ -311,7 +311,7 @@ static void window_maze_construction_update(rct_window *w)
|
|||
case RIDE_CONSTRUCTION_STATE_BACK:
|
||||
case RIDE_CONSTRUCTION_STATE_SELECTED:
|
||||
if (
|
||||
(RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE) &&
|
||||
(gInputFlags & INPUT_FLAG_TOOL_ACTIVE) &&
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) == WC_RIDE_CONSTRUCTION
|
||||
) {
|
||||
tool_cancel();
|
||||
|
|
|
@ -344,7 +344,7 @@ static void window_news_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, int s
|
|||
}
|
||||
}
|
||||
|
||||
uint32 image_id = *RCT2_ADDRESS(0x00982708, uint32*)[sprite_type * 2];
|
||||
uint32 image_id = g_sprite_entries[sprite_type].sprite_image->base_image;
|
||||
image_id += 0xA0000001;
|
||||
image_id |= (peep->tshirt_colour << 19) | (peep->trousers_colour << 24);
|
||||
|
||||
|
|
|
@ -135,6 +135,9 @@ enum WINDOW_OPTIONS_WIDGET_IDX {
|
|||
WIDX_TOOLBAR_SHOW_CHEATS,
|
||||
WIDX_TOOLBAR_SHOW_NEWS,
|
||||
WIDX_SELECT_BY_TRACK_TYPE,
|
||||
WIDX_SCENARIO_GROUPING,
|
||||
WIDX_SCENARIO_GROUPING_DROPDOWN,
|
||||
WIDX_SCENARIO_UNLOCKING,
|
||||
|
||||
// Misc
|
||||
WIDX_REAL_NAME_CHECKBOX = WIDX_PAGE_START,
|
||||
|
@ -162,7 +165,7 @@ enum WINDOW_OPTIONS_WIDGET_IDX {
|
|||
};
|
||||
|
||||
#define WW 310
|
||||
#define WH 280
|
||||
#define WH 302
|
||||
|
||||
#define MAIN_OPTIONS_WIDGETS \
|
||||
{ WWT_FRAME, 0, 0, WW-1, 0, WH-1, STR_NONE, STR_NONE }, \
|
||||
|
@ -253,6 +256,9 @@ static rct_widget window_options_controls_and_interface_widgets[] = {
|
|||
{ WWT_CHECKBOX, 2, 155, 299, 229, 240, STR_SHOW_RECENT_MESSAGES_ON_TOOLBAR, STR_NONE }, // Recent messages
|
||||
|
||||
{ WWT_CHECKBOX, 2, 10, 299, 254, 265, STR_SELECT_BY_TRACK_TYPE, STR_SELECT_BY_TRACK_TYPE_TIP }, // Select by track type
|
||||
{ WWT_DROPDOWN, 2, 155, 299, 269, 280, STR_NONE, STR_NONE }, // Scenario select mode
|
||||
{ WWT_DROPDOWN_BUTTON, 2, 288, 298, 270, 279, STR_DROPDOWN_GLYPH, STR_NONE },
|
||||
{ WWT_CHECKBOX, 2, 18, 299, 284, 295, STR_OPTIONS_SCENARIO_UNLOCKING, STR_NONE }, // Unlocking of scenarios
|
||||
{ WIDGETS_END },
|
||||
};
|
||||
|
||||
|
@ -418,7 +424,10 @@ static uint32 window_options_page_enabled_widgets[] = {
|
|||
(1 << WIDX_THEMES) |
|
||||
(1 << WIDX_THEMES_DROPDOWN) |
|
||||
(1 << WIDX_THEMES_BUTTON) |
|
||||
(1 << WIDX_SELECT_BY_TRACK_TYPE),
|
||||
(1 << WIDX_SELECT_BY_TRACK_TYPE) |
|
||||
(1 << WIDX_SCENARIO_GROUPING) |
|
||||
(1 << WIDX_SCENARIO_GROUPING_DROPDOWN) |
|
||||
(1 << WIDX_SCENARIO_UNLOCKING),
|
||||
|
||||
MAIN_OPTIONS_ENABLED_WIDGETS |
|
||||
(1 << WIDX_REAL_NAME_CHECKBOX) |
|
||||
|
@ -642,6 +651,11 @@ static void window_options_mouseup(rct_window *w, int widgetIndex)
|
|||
window_invalidate_by_class(WC_RIDE);
|
||||
window_invalidate_by_class(WC_CONSTRUCT_RIDE);
|
||||
break;
|
||||
case WIDX_SCENARIO_UNLOCKING:
|
||||
gConfigGeneral.scenario_unlocking_enabled ^= 1;
|
||||
config_save_default();
|
||||
window_close_by_class(WC_SCENARIO_SELECT);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -650,8 +664,7 @@ static void window_options_mouseup(rct_window *w, int widgetIndex)
|
|||
case WIDX_DEBUGGING_TOOLS:
|
||||
gConfigGeneral.debugging_tools ^= 1;
|
||||
config_save_default();
|
||||
window_invalidate(w);
|
||||
window_invalidate_by_class(WC_TOP_TOOLBAR);
|
||||
gfx_invalidate_screen();
|
||||
break;
|
||||
case WIDX_TEST_UNFINISHED_TRACKS:
|
||||
gConfigGeneral.test_unfinished_tracks ^= 1;
|
||||
|
@ -940,6 +953,27 @@ static void window_options_mousedown(int widgetIndex, rct_window*w, rct_widget*
|
|||
dropdown_set_checked(gCurrentTheme, true);
|
||||
}
|
||||
break;
|
||||
|
||||
case WIDX_SCENARIO_GROUPING_DROPDOWN:
|
||||
num_items = 2;
|
||||
|
||||
gDropdownItemsFormat[0] = 1142;
|
||||
gDropdownItemsArgs[0] = STR_OPTIONS_SCENARIO_DIFFICULTY;
|
||||
gDropdownItemsFormat[1] = 1142;
|
||||
gDropdownItemsArgs[1] = STR_OPTIONS_SCENARIO_ORIGIN;
|
||||
|
||||
window_dropdown_show_text_custom_width(
|
||||
w->x + widget->left,
|
||||
w->y + widget->top,
|
||||
widget->bottom - widget->top + 1,
|
||||
w->colours[1],
|
||||
DROPDOWN_FLAG_STAY_OPEN,
|
||||
num_items,
|
||||
widget->right - widget->left - 3
|
||||
);
|
||||
|
||||
dropdown_set_checked(gConfigGeneral.scenario_select_mode, true);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -962,15 +996,14 @@ static void window_options_mousedown(int widgetIndex, rct_window*w, rct_widget*
|
|||
gDropdownItemsArgs[i] = (uint32)&gConfigTitleSequences.presets[i].name;
|
||||
}
|
||||
|
||||
window_dropdown_show_text_custom_width(
|
||||
window_dropdown_show_text(
|
||||
w->x + widget->left,
|
||||
w->y + widget->top,
|
||||
widget->bottom - widget->top + 1,
|
||||
w->colours[1],
|
||||
DROPDOWN_FLAG_STAY_OPEN,
|
||||
num_items,
|
||||
widget->right - widget->left - 3
|
||||
);
|
||||
num_items
|
||||
);
|
||||
|
||||
dropdown_set_checked(gCurrentPreviewTitleSequence, true);
|
||||
break;
|
||||
|
@ -1139,6 +1172,14 @@ static void window_options_dropdown(rct_window *w, int widgetIndex, int dropdown
|
|||
}
|
||||
config_save_default();
|
||||
break;
|
||||
case WIDX_SCENARIO_GROUPING_DROPDOWN:
|
||||
if (dropdownIndex != gConfigGeneral.scenario_select_mode) {
|
||||
gConfigGeneral.scenario_select_mode = dropdownIndex;
|
||||
config_save_default();
|
||||
window_invalidate(w);
|
||||
window_close_by_class(WC_SCENARIO_SELECT);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1320,6 +1361,13 @@ static void window_options_invalidate(rct_window *w)
|
|||
widget_set_checkbox_value(w, WIDX_TOOLBAR_SHOW_CHEATS, gConfigInterface.toolbar_show_cheats);
|
||||
widget_set_checkbox_value(w, WIDX_TOOLBAR_SHOW_NEWS, gConfigInterface.toolbar_show_news);
|
||||
widget_set_checkbox_value(w, WIDX_SELECT_BY_TRACK_TYPE, gConfigInterface.select_by_track_type);
|
||||
widget_set_checkbox_value(w, WIDX_SCENARIO_UNLOCKING, gConfigGeneral.scenario_unlocking_enabled);
|
||||
|
||||
if (gConfigGeneral.scenario_select_mode == SCENARIO_SELECT_MODE_ORIGIN) {
|
||||
w->disabled_widgets &= ~(1ULL << WIDX_SCENARIO_UNLOCKING);
|
||||
} else {
|
||||
w->disabled_widgets |= (1ULL << WIDX_SCENARIO_UNLOCKING);
|
||||
}
|
||||
|
||||
window_options_controls_and_interface_widgets[WIDX_THEMES].type = WWT_DROPDOWN;
|
||||
window_options_controls_and_interface_widgets[WIDX_THEMES_DROPDOWN].type = WWT_DROPDOWN_BUTTON;
|
||||
|
@ -1332,6 +1380,8 @@ static void window_options_invalidate(rct_window *w)
|
|||
window_options_controls_and_interface_widgets[WIDX_TOOLBAR_SHOW_CHEATS].type = WWT_CHECKBOX;
|
||||
window_options_controls_and_interface_widgets[WIDX_TOOLBAR_SHOW_NEWS].type = WWT_CHECKBOX;
|
||||
window_options_controls_and_interface_widgets[WIDX_SELECT_BY_TRACK_TYPE].type = WWT_CHECKBOX;
|
||||
window_options_controls_and_interface_widgets[WIDX_SCENARIO_GROUPING].type = WWT_DROPDOWN;
|
||||
window_options_controls_and_interface_widgets[WIDX_SCENARIO_UNLOCKING].type = WWT_CHECKBOX;
|
||||
break;
|
||||
|
||||
case WINDOW_OPTIONS_PAGE_MISC:
|
||||
|
@ -1386,6 +1436,15 @@ static void window_options_invalidate(rct_window *w)
|
|||
window_options_twitch_widgets[WIDX_NEWS_CHECKBOX].type = WWT_CHECKBOX;
|
||||
break;
|
||||
}
|
||||
|
||||
// Automatically adjust window height to fit widgets
|
||||
int y = 0;
|
||||
for (widget = &w->widgets[WIDX_PAGE_START]; widget->type != WWT_LAST; widget++) {
|
||||
y = max(y, widget->bottom);
|
||||
}
|
||||
w->height = y + 6;
|
||||
w->widgets[WIDX_BACKGROUND].bottom = w->height - 1;
|
||||
w->widgets[WIDX_PAGE_BACKGROUND].bottom = w->height - 1;
|
||||
}
|
||||
|
||||
static void window_options_update(rct_window *w)
|
||||
|
@ -1481,7 +1540,19 @@ static void window_options_paint(rct_window *w, rct_drawpixelinfo *dpi)
|
|||
w->x + window_options_controls_and_interface_widgets[WIDX_THEMES].left + 1,
|
||||
w->y + window_options_controls_and_interface_widgets[WIDX_THEMES].top,
|
||||
window_options_controls_and_interface_widgets[WIDX_THEMES_DROPDOWN].left - window_options_controls_and_interface_widgets[WIDX_THEMES].left - 4
|
||||
);
|
||||
);
|
||||
gfx_draw_string_left(dpi, STR_OPTIONS_SCENARIO_GROUPING, NULL, w->colours[1], w->x + 10, w->y + window_options_controls_and_interface_widgets[WIDX_SCENARIO_GROUPING].top + 1);
|
||||
gfx_draw_string_left_clipped(
|
||||
dpi,
|
||||
gConfigGeneral.scenario_select_mode == SCENARIO_SELECT_MODE_DIFFICULTY ?
|
||||
STR_OPTIONS_SCENARIO_DIFFICULTY :
|
||||
STR_OPTIONS_SCENARIO_ORIGIN,
|
||||
NULL,
|
||||
w->colours[1],
|
||||
w->x + window_options_controls_and_interface_widgets[WIDX_SCENARIO_GROUPING].left + 1,
|
||||
w->y + window_options_controls_and_interface_widgets[WIDX_SCENARIO_GROUPING].top,
|
||||
window_options_controls_and_interface_widgets[WIDX_SCENARIO_GROUPING_DROPDOWN].left - window_options_controls_and_interface_widgets[WIDX_SCENARIO_GROUPING].left - 4
|
||||
);
|
||||
break;
|
||||
case WINDOW_OPTIONS_PAGE_MISC:
|
||||
gfx_draw_string_left(dpi, 2700, w, w->colours[1], w->x + 10, w->y + window_options_misc_widgets[WIDX_AUTOSAVE].top + 1);
|
||||
|
|
|
@ -612,7 +612,7 @@ void window_park_entrance_open()
|
|||
*/
|
||||
static void window_park_entrance_close(rct_window *w)
|
||||
{
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE)
|
||||
if (gInputFlags & INPUT_FLAG_TOOL_ACTIVE)
|
||||
if (w->classification == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) && w->number == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber))
|
||||
tool_cancel();
|
||||
}
|
||||
|
@ -1124,14 +1124,14 @@ static void window_park_init_viewport(rct_window *w)
|
|||
|
||||
void toggle_land_rights_window(rct_window *parkWindow, int widgetIndex)
|
||||
{
|
||||
if ((RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE) && RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, uint8) == WC_PARK_INFORMATION &&
|
||||
if ((gInputFlags & INPUT_FLAG_TOOL_ACTIVE) && RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, uint8) == WC_PARK_INFORMATION &&
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16) == WIDX_BUY_LAND_RIGHTS) {
|
||||
tool_cancel();
|
||||
}
|
||||
else {
|
||||
show_gridlines();
|
||||
tool_set(parkWindow, widgetIndex, 2);
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_6;
|
||||
gInputFlags |= INPUT_FLAG_6;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_LAND_TOOL_SIZE, sint16) = 1;
|
||||
window_land_rights_open();
|
||||
}
|
||||
|
@ -1156,7 +1156,7 @@ void window_park_rating_open()
|
|||
window->viewport_focus_coordinates.y = -1;
|
||||
}
|
||||
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE)
|
||||
if (gInputFlags & INPUT_FLAG_TOOL_ACTIVE)
|
||||
if (window->classification == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) && window->number == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber))
|
||||
tool_cancel();
|
||||
|
||||
|
@ -1272,7 +1272,7 @@ void window_park_guests_open()
|
|||
window->viewport_focus_coordinates.y = -1;
|
||||
}
|
||||
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE)
|
||||
if (gInputFlags & INPUT_FLAG_TOOL_ACTIVE)
|
||||
if (window->classification == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) && window->number == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber))
|
||||
tool_cancel();
|
||||
|
||||
|
@ -1630,7 +1630,7 @@ void window_park_objective_open()
|
|||
window->viewport_focus_coordinates.y = -1;
|
||||
}
|
||||
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE)
|
||||
if (gInputFlags & INPUT_FLAG_TOOL_ACTIVE)
|
||||
if (window->classification == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) && window->number == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber))
|
||||
tool_cancel();
|
||||
|
||||
|
@ -1795,7 +1795,7 @@ void window_park_awards_open()
|
|||
window->viewport_focus_coordinates.y = -1;
|
||||
}
|
||||
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE)
|
||||
if (gInputFlags & INPUT_FLAG_TOOL_ACTIVE)
|
||||
if (window->classification == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) && window->number == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber))
|
||||
tool_cancel();
|
||||
|
||||
|
@ -1907,7 +1907,7 @@ static void window_park_set_page(rct_window *w, int page)
|
|||
{
|
||||
int listen;
|
||||
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE)
|
||||
if (gInputFlags & INPUT_FLAG_TOOL_ACTIVE)
|
||||
if (w->classification == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) && w->number == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber))
|
||||
tool_cancel();
|
||||
|
||||
|
@ -1982,7 +1982,7 @@ static void window_park_draw_tab_images(rct_drawpixelinfo *dpi, rct_window *w)
|
|||
sprite_idx += (w->frame_no / 8) % 8;
|
||||
gfx_draw_sprite(dpi, sprite_idx, w->x + w->widgets[WIDX_TAB_3].left, w->y + w->widgets[WIDX_TAB_3].top, 0);
|
||||
|
||||
sprite_idx = *RCT2_GLOBAL(0x00982708, sint32*) + 1;
|
||||
sprite_idx = g_sprite_entries[0].sprite_image->base_image + 1;
|
||||
if (w->page == WINDOW_PARK_PAGE_GUESTS)
|
||||
sprite_idx += w->var_492 & 0xFFFFFFFC;
|
||||
|
||||
|
|
|
@ -1086,7 +1086,7 @@ static void window_ride_draw_tab_customer(rct_drawpixelinfo *dpi, rct_window *w)
|
|||
if (w->page == WINDOW_RIDE_PAGE_CUSTOMER)
|
||||
spriteIndex = w->var_492 & ~3;
|
||||
|
||||
spriteIndex += RCT2_GLOBAL(RCT2_GLOBAL(0x00982708, uint32), uint32);
|
||||
spriteIndex += g_sprite_entries[0].sprite_image->base_image;
|
||||
spriteIndex += 1;
|
||||
spriteIndex |= 0xA9E00000;
|
||||
|
||||
|
@ -1183,7 +1183,7 @@ rct_window *window_ride_open(int rideIndex)
|
|||
w->frame_no = 0;
|
||||
w->list_information_type = 0;
|
||||
w->var_492 = 0;
|
||||
w->highlighted_item = 0;
|
||||
w->ride_colour = 0;
|
||||
window_ride_disable_tabs(w);
|
||||
w->min_width = 316;
|
||||
w->min_height = 180;
|
||||
|
@ -1219,7 +1219,7 @@ rct_window *window_ride_main_open(int rideIndex)
|
|||
w->ride.var_482 = -1;
|
||||
}
|
||||
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE) {
|
||||
if (gInputFlags & INPUT_FLAG_TOOL_ACTIVE) {
|
||||
if (w->classification == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) &&
|
||||
w->number == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber)
|
||||
) {
|
||||
|
@ -1266,7 +1266,7 @@ rct_window *window_ride_open_station(int rideIndex, int stationIndex)
|
|||
}
|
||||
|
||||
if (
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE &&
|
||||
gInputFlags & INPUT_FLAG_TOOL_ACTIVE &&
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) == w->classification &&
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber) == w->number
|
||||
) {
|
||||
|
@ -1345,7 +1345,7 @@ rct_window *window_ride_open_vehicle(rct_vehicle *vehicle)
|
|||
window_invalidate(w);
|
||||
|
||||
if (
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE &&
|
||||
gInputFlags & INPUT_FLAG_TOOL_ACTIVE &&
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) == w->classification &&
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber) == w->number
|
||||
) {
|
||||
|
@ -1410,7 +1410,7 @@ static void window_ride_set_page(rct_window *w, int page)
|
|||
{
|
||||
int listen;
|
||||
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE)
|
||||
if (gInputFlags & INPUT_FLAG_TOOL_ACTIVE)
|
||||
if (w->classification == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) && w->number == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber))
|
||||
tool_cancel();
|
||||
|
||||
|
@ -3727,7 +3727,7 @@ static void window_ride_set_track_colour_scheme(rct_window *w, int x, int y)
|
|||
uint8 newColourScheme;
|
||||
int interactionType, z, direction;
|
||||
|
||||
newColourScheme = (uint8)(*((uint16*)&w->highlighted_item));
|
||||
newColourScheme = (uint8)w->ride_colour;
|
||||
|
||||
rct_xy16 mapCoord = { 0 };
|
||||
get_map_coordinates_from_pos(x, y, VIEWPORT_INTERACTION_MASK_RIDE, &mapCoord.x, &mapCoord.y, &interactionType, &mapElement, NULL);
|
||||
|
@ -3752,7 +3752,7 @@ static void window_ride_set_track_colour_scheme(rct_window *w, int x, int y)
|
|||
*/
|
||||
static void window_ride_colour_close(rct_window *w)
|
||||
{
|
||||
if (!(RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE))
|
||||
if (!(gInputFlags & INPUT_FLAG_TOOL_ACTIVE))
|
||||
return;
|
||||
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) != w->classification)
|
||||
|
@ -3817,7 +3817,7 @@ static void window_ride_colour_mousedown(int widgetIndex, rct_window *w, rct_wid
|
|||
|
||||
ride = GET_RIDE(w->number);
|
||||
rideEntry = ride_get_entry(ride);
|
||||
colourSchemeIndex = *((uint16*)&w->highlighted_item);
|
||||
colourSchemeIndex = w->ride_colour;
|
||||
dropdownWidget = widget - 1;
|
||||
|
||||
switch (widgetIndex) {
|
||||
|
@ -3957,20 +3957,20 @@ static void window_ride_colour_dropdown(rct_window *w, int widgetIndex, int drop
|
|||
|
||||
switch (widgetIndex) {
|
||||
case WIDX_TRACK_COLOUR_SCHEME_DROPDOWN:
|
||||
*((uint16*)&w->highlighted_item) = dropdownIndex;
|
||||
w->ride_colour = (uint16)dropdownIndex;
|
||||
window_invalidate(w);
|
||||
break;
|
||||
case WIDX_TRACK_MAIN_COLOUR:
|
||||
game_do_command(0, (0 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_SET_RIDE_APPEARANCE, *((uint16*)&w->highlighted_item), 0);
|
||||
game_do_command(0, (0 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_SET_RIDE_APPEARANCE, w->ride_colour, 0);
|
||||
break;
|
||||
case WIDX_TRACK_ADDITIONAL_COLOUR:
|
||||
game_do_command(0, (1 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_SET_RIDE_APPEARANCE, *((uint16*)&w->highlighted_item), 0);
|
||||
game_do_command(0, (1 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_SET_RIDE_APPEARANCE, w->ride_colour, 0);
|
||||
break;
|
||||
case WIDX_TRACK_SUPPORT_COLOUR:
|
||||
game_do_command(0, (4 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_SET_RIDE_APPEARANCE, *((uint16*)&w->highlighted_item), 0);
|
||||
game_do_command(0, (4 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_SET_RIDE_APPEARANCE, w->ride_colour, 0);
|
||||
break;
|
||||
case WIDX_MAZE_STYLE_DROPDOWN:
|
||||
game_do_command(0, (4 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_SET_RIDE_APPEARANCE, *((uint16*)&w->highlighted_item), 0);
|
||||
game_do_command(0, (4 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_SET_RIDE_APPEARANCE, w->ride_colour, 0);
|
||||
break;
|
||||
case WIDX_ENTRANCE_STYLE_DROPDOWN:
|
||||
game_do_command(0, (6 << 8) | 1, 0, (window_ride_entrance_style_list[dropdownIndex] << 8) | w->number, GAME_COMMAND_SET_RIDE_APPEARANCE, 0, 0);
|
||||
|
@ -4057,7 +4057,7 @@ static void window_ride_colour_invalidate(rct_window *w)
|
|||
RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 2, uint32) = ride->name_arguments;
|
||||
|
||||
// Track colours
|
||||
int colourScheme = *((uint16*)&w->highlighted_item);
|
||||
int colourScheme = w->ride_colour;
|
||||
trackColour = ride_get_track_colour(ride, colourScheme);
|
||||
|
||||
// Maze style
|
||||
|
@ -4226,7 +4226,7 @@ static void window_ride_colour_paint(rct_window *w, rct_drawpixelinfo *dpi)
|
|||
if (widget->type != WWT_EMPTY)
|
||||
gfx_fill_rect(dpi, w->x + widget->left + 1, w->y + widget->top + 1, w->x + widget->right - 1, w->y + widget->bottom - 1, 12);
|
||||
|
||||
trackColour = ride_get_track_colour(ride, *((uint16*)&w->highlighted_item));
|
||||
trackColour = ride_get_track_colour(ride, w->ride_colour);
|
||||
|
||||
//
|
||||
if (rideEntry->shop_item == 0xFF) {
|
||||
|
|
|
@ -1873,7 +1873,7 @@ static void window_ride_construction_entrance_click(rct_window *w)
|
|||
RCT2_GLOBAL(0x00F44191, uint8) = 0;
|
||||
RCT2_GLOBAL(0x00F44192, uint8) = w->number & 0xFF;
|
||||
RCT2_GLOBAL(0x00F44193, uint8) = 0;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_6;
|
||||
gInputFlags |= INPUT_FLAG_6;
|
||||
sub_6C9627();
|
||||
if (_rideConstructionState != RIDE_CONSTRUCTION_STATE_ENTRANCE_EXIT) {
|
||||
RCT2_GLOBAL(0x00F440CC, uint8) = _rideConstructionState;
|
||||
|
@ -1897,7 +1897,7 @@ static void window_ride_construction_exit_click(rct_window *w)
|
|||
RCT2_GLOBAL(0x00F44191, uint8) = 1;
|
||||
RCT2_GLOBAL(0x00F44192, uint8) = w->number & 0xFF;
|
||||
RCT2_GLOBAL(0x00F44193, uint8) = 0;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_6;
|
||||
gInputFlags |= INPUT_FLAG_6;
|
||||
sub_6C9627();
|
||||
if (_rideConstructionState != RIDE_CONSTRUCTION_STATE_ENTRANCE_EXIT) {
|
||||
RCT2_GLOBAL(0x00F440CC, uint8) = _rideConstructionState;
|
||||
|
@ -1941,7 +1941,7 @@ static void window_ride_construction_update(rct_window *w)
|
|||
case RIDE_CONSTRUCTION_STATE_BACK:
|
||||
case RIDE_CONSTRUCTION_STATE_SELECTED:
|
||||
if (
|
||||
(RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE) &&
|
||||
(gInputFlags & INPUT_FLAG_TOOL_ACTIVE) &&
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) == WC_RIDE_CONSTRUCTION
|
||||
) {
|
||||
tool_cancel();
|
||||
|
@ -3569,7 +3569,7 @@ void ride_construction_tooldown_construct(int screenX, int screenY)
|
|||
w = window_find_by_class(WC_RIDE_CONSTRUCTION);
|
||||
if (w != NULL){
|
||||
tool_set(w, 23, 12);
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= (1 << 6);
|
||||
gInputFlags |= INPUT_FLAG_6;
|
||||
RCT2_GLOBAL(0x00F44159, uint8) = 0;
|
||||
RCT2_GLOBAL(0x00F4415C, uint8) = 0;
|
||||
}
|
||||
|
|
|
@ -286,7 +286,7 @@ static void window_ride_list_dropdown(rct_window *w, int widgetIndex, int dropdo
|
|||
if (dropdownIndex == -1)
|
||||
return;
|
||||
|
||||
_window_ride_list_information_type = *((uint32*)&gDropdownItemsArgs[dropdownIndex]) - STR_STATUS;
|
||||
_window_ride_list_information_type = (uint32)gDropdownItemsArgs[dropdownIndex] - STR_STATUS;
|
||||
window_invalidate(w);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#include "../interface/window.h"
|
||||
#include "../openrct2.h"
|
||||
#include "../sprites.h"
|
||||
#include "../tutorial.h"
|
||||
|
||||
enum WINDOW_SAVE_PROMPT_WIDGET_IDX {
|
||||
WIDX_BACKGROUND,
|
||||
|
@ -134,19 +133,6 @@ void window_save_prompt_open()
|
|||
* and game_load_or_quit() are not called by the original binary anymore.
|
||||
*/
|
||||
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_ON_TUTORIAL, uint8) != 0) {
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_ON_TUTORIAL, uint8) != 1) {
|
||||
sub_66EE54();
|
||||
game_load_or_quit_no_save_prompt();
|
||||
return;
|
||||
}
|
||||
else {
|
||||
tutorial_stop();
|
||||
game_load_or_quit_no_save_prompt();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_AGE, uint16) < 3840) {
|
||||
game_load_or_quit_no_save_prompt();
|
||||
return;
|
||||
|
@ -249,18 +235,6 @@ static void window_save_prompt_mouseup(rct_window *w, int widgetIndex)
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_ON_TUTORIAL, uint8) != 0) {
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_ON_TUTORIAL, uint8) != 1) {
|
||||
sub_66EE54();
|
||||
game_load_or_quit_no_save_prompt();
|
||||
return;
|
||||
} else {
|
||||
tutorial_stop();
|
||||
game_load_or_quit_no_save_prompt();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void window_save_prompt_invalidate(rct_window *w)
|
||||
|
|
|
@ -490,7 +490,7 @@ bool window_scenery_is_scenery_tool_active() {
|
|||
int toolWindowClassification = RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass);
|
||||
int toolWidgetIndex = RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16);
|
||||
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE)
|
||||
if (gInputFlags & INPUT_FLAG_TOOL_ACTIVE)
|
||||
if (toolWindowClassification == WC_TOP_TOOLBAR && toolWidgetIndex == 9) // 9 is WIDX_SCENERY
|
||||
return true;
|
||||
|
||||
|
@ -693,7 +693,7 @@ static void window_scenery_update(rct_window *w)
|
|||
if (widgetIndex >= WIDX_SCENERY_TAB_CONTENT_PANEL) {
|
||||
w->scenery.hover_counter++;
|
||||
if (w->scenery.hover_counter < 8) {
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, sint8) != INPUT_STATE_SCROLL_LEFT) {
|
||||
if (gInputState != INPUT_STATE_SCROLL_LEFT) {
|
||||
w->min_width = WINDOW_SCENERY_WIDTH;
|
||||
w->max_width = WINDOW_SCENERY_WIDTH;
|
||||
w->min_height = WINDOW_SCENERY_HEIGHT;
|
||||
|
@ -713,7 +713,7 @@ static void window_scenery_update(rct_window *w)
|
|||
}
|
||||
} else {
|
||||
w->scenery.hover_counter = 0;
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, sint8) != INPUT_STATE_SCROLL_LEFT) {
|
||||
if (gInputState != INPUT_STATE_SCROLL_LEFT) {
|
||||
w->min_width = WINDOW_SCENERY_WIDTH;
|
||||
w->max_width = WINDOW_SCENERY_WIDTH;
|
||||
w->min_height = WINDOW_SCENERY_HEIGHT;
|
||||
|
|
|
@ -369,7 +369,7 @@ void window_staff_disable_widgets(rct_window* w)
|
|||
*/
|
||||
void window_staff_overview_close(rct_window *w)
|
||||
{
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE){
|
||||
if (gInputFlags & INPUT_FLAG_TOOL_ACTIVE){
|
||||
if (w->classification == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) &&
|
||||
w->number == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber))
|
||||
tool_cancel();
|
||||
|
@ -382,7 +382,7 @@ void window_staff_overview_close(rct_window *w)
|
|||
*/
|
||||
void window_staff_set_page(rct_window* w, int page)
|
||||
{
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE)
|
||||
if (gInputFlags & INPUT_FLAG_TOOL_ACTIVE)
|
||||
{
|
||||
if(w->number == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber) &&
|
||||
w->classification == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass))
|
||||
|
@ -449,7 +449,7 @@ void window_staff_overview_mouseup(rct_window *w, int widgetIndex)
|
|||
return;
|
||||
}
|
||||
|
||||
w->var_48C = peep->x;
|
||||
w->picked_peep_old_x = peep->x;
|
||||
|
||||
remove_peep_from_ride(peep);
|
||||
invalidate_sprite_2((rct_sprite*)peep);
|
||||
|
@ -987,7 +987,7 @@ void window_staff_overview_tab_paint(rct_window* w, rct_drawpixelinfo* dpi)
|
|||
if (peep->type == PEEP_TYPE_STAFF && peep->staff_type == STAFF_TYPE_ENTERTAINER)
|
||||
y++;
|
||||
|
||||
int ebx = *(RCT2_ADDRESS(0x982708, uint32*)[peep->sprite_type * 2]) + 1;
|
||||
int ebx = g_sprite_entries[peep->sprite_type].sprite_image->base_image + 1;
|
||||
|
||||
int eax = 0;
|
||||
|
||||
|
@ -1096,7 +1096,7 @@ void window_staff_overview_tool_update(rct_window* w, int widgetIndex, int x, in
|
|||
if (widgetIndex != WIDX_PICKUP)
|
||||
return;
|
||||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_SPRITE, sint32) = -1;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_IMAGE, sint32) = -1;
|
||||
|
||||
int interactionType;
|
||||
get_map_coordinates_from_pos(x, y, VIEWPORT_INTERACTION_MASK_NONE, NULL, NULL, &interactionType, NULL, NULL);
|
||||
|
@ -1107,16 +1107,19 @@ void window_staff_overview_tool_update(rct_window* w, int widgetIndex, int x, in
|
|||
y += 16;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_X, uint16) = x;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_Y, uint16) = y;
|
||||
w->var_492++;
|
||||
if (w->var_492 >= 48)w->var_492 = 0;
|
||||
w->picked_peep_frame++;
|
||||
if (w->picked_peep_frame >= 48) {
|
||||
w->picked_peep_frame = 0;
|
||||
}
|
||||
|
||||
rct_peep* peep;
|
||||
peep = GET_PEEP(w->number);
|
||||
int sprite_idx = (RCT2_ADDRESS(0x982708, uint32*)[peep->sprite_type * 2])[22];
|
||||
sprite_idx += w->var_492 >> 2;
|
||||
|
||||
sprite_idx |= (peep->tshirt_colour << 19) | (peep->trousers_colour << 24) | 0xA0000000;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_SPRITE, uint32) = sprite_idx;
|
||||
uint32 imageId = g_sprite_entries[peep->sprite_type].sprite_image[11].base_image;
|
||||
imageId += w->picked_peep_frame >> 2;
|
||||
|
||||
imageId |= (peep->tshirt_colour << 19) | (peep->trousers_colour << 24) | 0xA0000000;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_IMAGE, uint32) = imageId;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1163,7 +1166,7 @@ void window_staff_overview_tool_down(rct_window* w, int widgetIndex, int x, int
|
|||
peep->state = PEEP_STATE_FALLING;
|
||||
peep_window_state_update(peep);
|
||||
peep->action = 0xFF;
|
||||
peep->var_6D = 0;
|
||||
peep->special_sprite = 0;
|
||||
peep->action_sprite_image_offset = 0;
|
||||
peep->action_sprite_type = 0;
|
||||
peep->var_C4 = 0;
|
||||
|
@ -1191,7 +1194,7 @@ void window_staff_overview_tool_abort(rct_window *w, int widgetIndex)
|
|||
rct_peep* peep = GET_PEEP(w->number);
|
||||
if (peep->state != PEEP_STATE_PICKED) return;
|
||||
|
||||
sprite_move(w->var_48C, peep->y, peep->z + 8, (rct_sprite*)peep);
|
||||
sprite_move(w->picked_peep_old_x, peep->y, peep->z + 8, (rct_sprite*)peep);
|
||||
invalidate_sprite_2((rct_sprite*)peep);
|
||||
|
||||
if (peep->x != (sint16)0x8000){
|
||||
|
@ -1199,13 +1202,13 @@ void window_staff_overview_tool_abort(rct_window *w, int widgetIndex)
|
|||
peep->state = PEEP_STATE_FALLING;
|
||||
peep_window_state_update(peep);
|
||||
peep->action = 0xFF;
|
||||
peep->var_6D = 0;
|
||||
peep->special_sprite = 0;
|
||||
peep->action_sprite_image_offset = 0;
|
||||
peep->action_sprite_type = 0;
|
||||
peep->var_C4 = 0;
|
||||
}
|
||||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_SPRITE, sint32) = -1;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_IMAGE, sint32) = -1;
|
||||
}
|
||||
else if (widgetIndex == WIDX_PATROL){
|
||||
hide_gridlines();
|
||||
|
|
|
@ -181,7 +181,7 @@ void window_staff_list_open()
|
|||
void window_staff_list_cancel_tools(rct_window *w) {
|
||||
int toolWindowClassification = RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass);
|
||||
int toolWindowNumber = RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber);
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE)
|
||||
if (gInputFlags & INPUT_FLAG_TOOL_ACTIVE)
|
||||
if (w->classification == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) && w->number == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber))
|
||||
tool_cancel();
|
||||
}
|
||||
|
@ -310,10 +310,10 @@ void window_staff_list_update(rct_window *w)
|
|||
RCT2_GLOBAL(RCT2_ADDRESS_WINDOW_MAP_FLASHING_FLAGS, uint16) |= (1 << 2);
|
||||
FOR_ALL_PEEPS(spriteIndex, peep) {
|
||||
if (peep->type == PEEP_TYPE_STAFF) {
|
||||
peep->var_0C &= ~0x200;
|
||||
peep->list_flags &= ~(PEEP_LIST_FLAGS_FLASHING);
|
||||
|
||||
if (peep->staff_type == RCT2_GLOBAL(RCT2_ADDRESS_WINDOW_STAFF_LIST_SELECTED_TAB, uint8)) {
|
||||
peep->var_0C |= 0x200;
|
||||
peep->list_flags |= PEEP_LIST_FLAGS_FLASHING;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,31 +26,76 @@
|
|||
#include "../world/scenery.h"
|
||||
#include "../world/map.h"
|
||||
#include "../world/footpath.h"
|
||||
#include "../sprites.h"
|
||||
|
||||
enum WINDOW_TILE_INSPECTOR_WIDGET_IDX {
|
||||
WIDX_BACKGROUND,
|
||||
WIDX_TITLE,
|
||||
WIDX_CLOSE,
|
||||
WIDX_LIST,
|
||||
WIDX_CORRUPT,
|
||||
WIDX_CONTENT_PANEL,
|
||||
WIDX_SCROLL
|
||||
WIDX_REMOVE,
|
||||
WIDX_MOVE_DOWN,
|
||||
WIDX_MOVE_UP,
|
||||
WIDX_COLUMN_TYPE,
|
||||
WIDX_COLUMN_BASEHEIGHT,
|
||||
WIDX_COLUMN_CLEARANCEHEIGHT,
|
||||
WIDX_COLUMN_GHOSTFLAG,
|
||||
WIDX_COLUMN_BROKENFLAG,
|
||||
WIDX_COLUMN_LASTFLAG,
|
||||
};
|
||||
|
||||
#define WW 500
|
||||
#define WH 400
|
||||
#define WW 400
|
||||
#define WH 200
|
||||
#define MIN_WW WW
|
||||
#define MAX_WW WW
|
||||
#define MIN_WH 150
|
||||
#define MAX_WH 800
|
||||
|
||||
#define BW (WW - 5) // Button's right side
|
||||
#define BX (BW - 23) // Button's left side
|
||||
#define BY 17 // Button's Top
|
||||
#define BH (BY + 23) // Button's Bottom
|
||||
#define BS 24
|
||||
|
||||
#define SCROLL_BOTTOM_OFFSET 15
|
||||
#define LIST_ITEM_HEIGHT 11
|
||||
|
||||
// Column offsets
|
||||
#define COL_X_TYPE 3 // Type
|
||||
#define COL_X_BH (COL_X_TYPE + 300) // Base height
|
||||
#define COL_X_CH (COL_X_BH + 20) // Clearance height
|
||||
#define COL_X_GF (COL_X_CH + 20) // Ghost flag
|
||||
#define COL_X_BF (COL_X_GF + 12) // Broken flag
|
||||
#define COL_X_LF (COL_X_BF + 12) // Last for tile flag
|
||||
|
||||
rct_widget window_tile_inspector_widgets[] = {
|
||||
{ WWT_FRAME, 0, 0, WW - 1, 0, WH - 1, 0x0FFFFFFFF, STR_NONE }, // panel / background
|
||||
{ WWT_CAPTION, 0, 1, WW - 2, 1, 14, STR_TILE_INSPECTOR_TITLE, STR_WINDOW_TITLE_TIP }, // title bar
|
||||
{ WWT_CLOSEBOX, 0, WW - 13, WW - 3, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP }, // close x button
|
||||
{ WWT_CLOSEBOX, 1, WW - 150, WW - 3, 18, 39, STR_INSERT_CORRUPT, STR_INSERT_CORRUPT_TIP },
|
||||
{ WWT_RESIZE, 1, 0, WW - 1, 43, WH - 1, 0x0FFFFFFFF, STR_NONE }, // content panel
|
||||
{ WWT_SCROLL, 1, 3, WW - 3, 65, WH - 30, 2, STR_NONE }, // scroll area
|
||||
{ WWT_FRAME, 0, 0, WW - 1, 0, WH - 1, 0x0FFFFFFFF, STR_NONE }, // panel / background
|
||||
{ WWT_CAPTION, 0, 1, WW - 2, 1, 14, STR_TILE_INSPECTOR_TITLE, STR_WINDOW_TITLE_TIP }, // title bar
|
||||
{ WWT_CLOSEBOX, 0, WW - 13, WW - 3, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP }, // close x button
|
||||
|
||||
// Map element list
|
||||
{ WWT_SCROLL, 1, 3, WW - 4, 57, WH - SCROLL_BOTTOM_OFFSET, 2, STR_NONE }, // scroll area
|
||||
|
||||
// Buttons
|
||||
{ WWT_FLATBTN, 1, BX, BW, BY, BH, SPR_MAP, STR_INSERT_CORRUPT_TIP }, // Insert corrupt button
|
||||
{ WWT_FLATBTN, 1, BX - BS * 1, BW - BS * 1, BY, BH, SPR_DEMOLISH, 5607 }, // Remove button
|
||||
{ WWT_CLOSEBOX, 1, BX - BS * 2, BW - BS * 2, BY, BY + 11, 5375, 5617 }, // Move down
|
||||
{ WWT_CLOSEBOX, 1, BX - BS * 2, BW - BS * 2, BH - 11, BH, 5376, 5618 }, // Move up
|
||||
|
||||
// Column headers
|
||||
{ WWT_13, 1, COL_X_TYPE, COL_X_BH - 1, 42, 42 + 13, STR_NONE, STR_NONE }, // Type
|
||||
{ WWT_13, 1, COL_X_BH, COL_X_CH - 1, 42, 42 + 13, STR_NONE, STR_TILE_INSPECTOR_BASE_HEIGHT }, // Base height
|
||||
{ WWT_13, 1, COL_X_CH, COL_X_GF - 1, 42, 42 + 13, STR_NONE, STR_TILE_INSPECTOR_CLEARANCE_HEIGHT }, // Clearance height
|
||||
{ WWT_13, 1, COL_X_GF, COL_X_BF - 1, 42, 42 + 13, STR_NONE, STR_TILE_INSPECTOR_FLAG_GHOST }, // Ghost flag
|
||||
{ WWT_13, 1, COL_X_BF, COL_X_LF - 1, 42, 42 + 13, STR_NONE, STR_TILE_INSPECTOR_FLAG_BROKEN }, // Broken flag
|
||||
{ WWT_13, 1, COL_X_LF, WW - 3, 42, 42 + 13, STR_NONE, STR_TILE_INSPECTOR_FLAG_LAST }, // Last of tile flag
|
||||
|
||||
{ WIDGETS_END },
|
||||
};
|
||||
|
||||
static sint16 window_tile_inspector_highlighted_index = -1;
|
||||
|
||||
static int window_tile_inspector_tile_x;
|
||||
static int window_tile_inspector_tile_y;
|
||||
static int window_tile_inspector_item_count;
|
||||
|
@ -58,15 +103,19 @@ static int window_tile_inspector_item_count;
|
|||
static void window_tile_inspector_close(rct_window *w);
|
||||
static void window_tile_inspector_mouseup(rct_window *w, int widgetIndex);
|
||||
static void window_tile_inspector_resize(rct_window *w);
|
||||
static void window_title_editor_update(rct_window *w);
|
||||
static void window_tile_inspector_tool_update(rct_window* w, int widgetIndex, int x, int y);
|
||||
static void window_tile_inspector_tool_down(rct_window* w, int widgetIndex, int x, int y);
|
||||
static void window_tile_inspector_tool_abort(rct_window *w, int widgetIndex);
|
||||
static void window_tile_inspector_scrollgetsize(rct_window *w, int scrollIndex, int *width, int *height);
|
||||
static void window_tile_inspector_scrollmousedown(rct_window *w, int scrollIndex, int x, int y);
|
||||
static void window_tile_inspector_scrollmouseover(rct_window *w, int scrollIndex, int x, int y);
|
||||
static void window_tile_inspector_invalidate(rct_window *w);
|
||||
static void window_tile_inspector_paint(rct_window *w, rct_drawpixelinfo *dpi);
|
||||
static void window_tile_inspector_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, int scrollIndex);
|
||||
|
||||
static void window_tile_inspector_auto_set_buttons(rct_window *w);
|
||||
|
||||
static rct_window_event_list window_tile_inspector_events = {
|
||||
window_tile_inspector_close,
|
||||
window_tile_inspector_mouseup,
|
||||
|
@ -74,7 +123,7 @@ static rct_window_event_list window_tile_inspector_events = {
|
|||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
window_title_editor_update,
|
||||
NULL,
|
||||
NULL,
|
||||
window_tile_inspector_tool_update,
|
||||
|
@ -84,7 +133,7 @@ static rct_window_event_list window_tile_inspector_events = {
|
|||
window_tile_inspector_tool_abort,
|
||||
NULL,
|
||||
window_tile_inspector_scrollgetsize,
|
||||
NULL,
|
||||
window_tile_inspector_scrollmousedown,
|
||||
NULL,
|
||||
window_tile_inspector_scrollmouseover,
|
||||
NULL,
|
||||
|
@ -118,16 +167,17 @@ void window_tile_inspector_open()
|
|||
);
|
||||
window->widgets = window_tile_inspector_widgets;
|
||||
window->enabled_widgets = (1 << WIDX_CLOSE);
|
||||
window->disabled_widgets = (1 << WIDX_CORRUPT);
|
||||
window->disabled_widgets = (1 << WIDX_CORRUPT) | (1 << WIDX_MOVE_UP) | (1 << WIDX_MOVE_DOWN) | (1 << WIDX_REMOVE);
|
||||
|
||||
window_init_scroll_widgets(window);
|
||||
window->colours[0] = 7;
|
||||
window->colours[1] = 7;
|
||||
window->colours[2] = 7;
|
||||
window->min_width = WW;
|
||||
window->min_width = MIN_WW;
|
||||
window->min_height = MIN_WH;
|
||||
window->max_width = WW;
|
||||
window->max_width = MAX_WW;
|
||||
window->max_height = MAX_WH;
|
||||
window->selected_list_item = -1;
|
||||
|
||||
window_tile_inspector_tile_x = -1;
|
||||
window_tile_inspector_tile_y = -1;
|
||||
|
@ -151,6 +201,50 @@ void corrupt_element(int x, int y) {
|
|||
mapElement->type = (8 << 2);
|
||||
}
|
||||
|
||||
void remove_element(int index)
|
||||
{
|
||||
assert(index < window_tile_inspector_item_count);
|
||||
rct_map_element *mapElement = map_get_first_element_at(window_tile_inspector_tile_x, window_tile_inspector_tile_y);
|
||||
mapElement += index;
|
||||
map_element_remove(mapElement);
|
||||
window_tile_inspector_item_count--;
|
||||
}
|
||||
|
||||
// Swap element with its parent
|
||||
void swap_elements(sint16 first, sint16 second)
|
||||
{
|
||||
rct_map_element *mapElement;
|
||||
rct_map_element *firstElement = NULL;
|
||||
rct_map_element *secondElement = NULL;
|
||||
mapElement = map_get_first_element_at(window_tile_inspector_tile_x, window_tile_inspector_tile_y);
|
||||
|
||||
// swap_elements shouldn't be called when there is only one element on the tile
|
||||
assert(!map_element_is_last_for_tile(mapElement));
|
||||
|
||||
// Search for the elements
|
||||
sint16 i = 0;
|
||||
do {
|
||||
if (i == first) firstElement = mapElement;
|
||||
if (i == second) secondElement = mapElement;
|
||||
i++;
|
||||
|
||||
// Check if both elements have been found
|
||||
if (firstElement != NULL && secondElement != NULL)
|
||||
break;
|
||||
} while (!map_element_is_last_for_tile(mapElement++));
|
||||
|
||||
// Swap their memory
|
||||
rct_map_element temp = *firstElement;
|
||||
*firstElement = *secondElement;
|
||||
*secondElement = temp;
|
||||
|
||||
// Swap the 'last map element for tile' flag if either one of them was last
|
||||
if (map_element_is_last_for_tile(firstElement) || map_element_is_last_for_tile(secondElement)) {
|
||||
firstElement->flags ^= MAP_ELEMENT_FLAG_LAST_TILE;
|
||||
secondElement->flags ^= MAP_ELEMENT_FLAG_LAST_TILE;
|
||||
}
|
||||
}
|
||||
|
||||
static void window_tile_inspector_mouseup(rct_window *w, int widgetIndex)
|
||||
{
|
||||
switch (widgetIndex) {
|
||||
|
@ -159,9 +253,28 @@ static void window_tile_inspector_mouseup(rct_window *w, int widgetIndex)
|
|||
break;
|
||||
case WIDX_CORRUPT:
|
||||
corrupt_element(window_tile_inspector_tile_x, window_tile_inspector_tile_y);
|
||||
window_tile_inspector_item_count++;
|
||||
w->scrolls[0].v_top = 0;
|
||||
window_invalidate(w);
|
||||
w->selected_list_item = window_tile_inspector_item_count++;
|
||||
window_tile_inspector_auto_set_buttons(w);
|
||||
widget_invalidate(w, WIDX_LIST);
|
||||
break;
|
||||
case WIDX_REMOVE:
|
||||
remove_element(w->selected_list_item);
|
||||
w->selected_list_item = -1;
|
||||
window_tile_inspector_auto_set_buttons(w);
|
||||
widget_invalidate(w, WIDX_LIST);
|
||||
break;
|
||||
case WIDX_MOVE_DOWN:
|
||||
swap_elements(w->selected_list_item, w->selected_list_item + 1);
|
||||
w->selected_list_item++;
|
||||
window_tile_inspector_auto_set_buttons(w);
|
||||
widget_invalidate(w, WIDX_LIST);
|
||||
break;
|
||||
case WIDX_MOVE_UP:
|
||||
swap_elements(w->selected_list_item - 1, w->selected_list_item);
|
||||
w->selected_list_item--;
|
||||
window_tile_inspector_auto_set_buttons(w);
|
||||
widget_invalidate(w, WIDX_LIST);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -180,6 +293,16 @@ static void window_tile_inspector_resize(rct_window *w)
|
|||
}
|
||||
}
|
||||
|
||||
static void window_title_editor_update(rct_window *w)
|
||||
{
|
||||
// Check if the mouse is hovering over the list
|
||||
if (!widget_is_highlighted(w, WIDX_LIST))
|
||||
{
|
||||
window_tile_inspector_highlighted_index = -1;
|
||||
widget_invalidate(w, WIDX_LIST);
|
||||
}
|
||||
}
|
||||
|
||||
static void window_tile_inspector_tool_update(rct_window* w, int widgetIndex, int x, int y)
|
||||
{
|
||||
int direction;
|
||||
|
@ -229,8 +352,13 @@ static void window_tile_inspector_tool_down(rct_window* w, int widgetIndex, int
|
|||
|
||||
window_tile_inspector_item_count = numItems;
|
||||
|
||||
// Enable 'insert corrupt element' button
|
||||
w->enabled_widgets |= (1 << WIDX_CORRUPT);
|
||||
w->disabled_widgets &= ~(1ULL << WIDX_CORRUPT);
|
||||
// undo selection and buttons affecting it
|
||||
w->selected_list_item = -1;
|
||||
w->disabled_widgets |= (1ULL << WIDX_MOVE_UP) | (1ULL << WIDX_MOVE_DOWN) | (1ULL << WIDX_REMOVE);
|
||||
w->enabled_widgets &= ~((1ULL << WIDX_MOVE_UP) | (1ULL << WIDX_MOVE_DOWN) | (1ULL << WIDX_REMOVE));
|
||||
|
||||
w->scrolls[0].v_top = 0;
|
||||
window_invalidate(w);
|
||||
|
@ -244,12 +372,63 @@ static void window_tile_inspector_tool_abort(rct_window *w, int widgetIndex)
|
|||
static void window_tile_inspector_scrollgetsize(rct_window *w, int scrollIndex, int *width, int *height)
|
||||
{
|
||||
*width = WW - 30;
|
||||
*height = window_tile_inspector_item_count * 11;
|
||||
*height = window_tile_inspector_item_count * LIST_ITEM_HEIGHT;
|
||||
}
|
||||
|
||||
static void window_tile_inspector_auto_set_buttons(rct_window *w)
|
||||
{
|
||||
// Remove button
|
||||
if (w->selected_list_item == -1) { // Check if anything is selected
|
||||
w->disabled_widgets |= (1ULL << WIDX_REMOVE);
|
||||
w->enabled_widgets &= ~(1ULL << WIDX_REMOVE);
|
||||
} else { // Nothing is selected
|
||||
w->disabled_widgets &= ~(1ULL << WIDX_REMOVE);
|
||||
w->enabled_widgets |= (1ULL << WIDX_REMOVE);
|
||||
}
|
||||
widget_invalidate(w, WIDX_REMOVE);
|
||||
|
||||
// Move Up button
|
||||
if (w->selected_list_item <= 0) { // Top element in list, or -1
|
||||
w->disabled_widgets |= (1ULL << WIDX_MOVE_UP);
|
||||
w->enabled_widgets &= ~(1ULL << WIDX_MOVE_UP);
|
||||
} else { // Not the top element in the list
|
||||
w->enabled_widgets |= (1ULL << WIDX_MOVE_UP);
|
||||
w->disabled_widgets &= ~(1ULL << WIDX_MOVE_UP);
|
||||
}
|
||||
widget_invalidate(w, WIDX_MOVE_UP);
|
||||
|
||||
// Move Down button
|
||||
if (w->selected_list_item == window_tile_inspector_item_count - 1 || w->selected_list_item == -1) { // Bottom element in list, or -1
|
||||
w->disabled_widgets |= (1ULL << WIDX_MOVE_DOWN);
|
||||
w->enabled_widgets &= ~(1ULL << WIDX_MOVE_DOWN);
|
||||
} else { // Not the bottom element in the list
|
||||
w->enabled_widgets |= (1ULL << WIDX_MOVE_DOWN);
|
||||
w->disabled_widgets &= ~(1ULL << WIDX_MOVE_DOWN);
|
||||
}
|
||||
widget_invalidate(w, WIDX_MOVE_DOWN);
|
||||
}
|
||||
|
||||
static void window_tile_inspector_scrollmousedown(rct_window *w, int scrollIndex, int x, int y)
|
||||
{
|
||||
// Because the list items are displayed in reverse order, subtract the number from the amount of elements
|
||||
sint16 index = window_tile_inspector_item_count - (y - 1) / LIST_ITEM_HEIGHT - 1;
|
||||
if (index < 0 || index >= window_tile_inspector_item_count)
|
||||
return;
|
||||
w->selected_list_item = index;
|
||||
|
||||
// Enable/disable buttons
|
||||
window_tile_inspector_auto_set_buttons(w);
|
||||
}
|
||||
|
||||
static void window_tile_inspector_scrollmouseover(rct_window *w, int scrollIndex, int x, int y)
|
||||
{
|
||||
window_invalidate(w);
|
||||
sint16 index = window_tile_inspector_item_count - (y - 1) / LIST_ITEM_HEIGHT - 1;
|
||||
if (index < 0 || index >= window_tile_inspector_item_count)
|
||||
window_tile_inspector_highlighted_index = -1;
|
||||
else
|
||||
window_tile_inspector_highlighted_index = index;
|
||||
|
||||
widget_invalidate(w, WIDX_LIST);
|
||||
}
|
||||
|
||||
static void window_tile_inspector_invalidate(rct_window *w)
|
||||
|
@ -258,28 +437,53 @@ static void window_tile_inspector_invalidate(rct_window *w)
|
|||
window_tile_inspector_widgets[WIDX_BACKGROUND].bottom = w->height - 1;
|
||||
window_tile_inspector_widgets[WIDX_CLOSE].left = w->width - 13;
|
||||
window_tile_inspector_widgets[WIDX_CLOSE].right = w->width - 3;
|
||||
window_tile_inspector_widgets[WIDX_CONTENT_PANEL].right = w->width - 1;
|
||||
window_tile_inspector_widgets[WIDX_CONTENT_PANEL].bottom = w->height - 1;
|
||||
window_tile_inspector_widgets[WIDX_SCROLL].bottom = w->height - 30;
|
||||
window_tile_inspector_widgets[WIDX_TITLE].right = w->width - 2;
|
||||
window_tile_inspector_widgets[WIDX_LIST].right = w->width - 4;
|
||||
window_tile_inspector_widgets[WIDX_LIST].bottom = w->height - SCROLL_BOTTOM_OFFSET;
|
||||
window_tile_inspector_widgets[WIDX_COLUMN_LASTFLAG].right = w->width - 3;
|
||||
}
|
||||
|
||||
static void window_tile_inspector_paint(rct_window *w, rct_drawpixelinfo *dpi)
|
||||
{
|
||||
int x, y;
|
||||
char buffer[256];
|
||||
|
||||
window_draw_widgets(w, dpi);
|
||||
|
||||
x = w->x + 20;
|
||||
y = w->y + 25;
|
||||
char buffer[256];
|
||||
int x = w->x /*+ w->widgets[WIDX_LIST].left*/ + 3;
|
||||
int y = w->y + w->height - 13;
|
||||
|
||||
if (window_tile_inspector_tile_x == -1) {
|
||||
// Set medium font size
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = FONT_SPRITE_BASE_MEDIUM;
|
||||
|
||||
// No tile selected
|
||||
// Draw column headers
|
||||
rct_widget *widget;
|
||||
if ((widget= &w->widgets[WIDX_COLUMN_TYPE])->type != WWT_EMPTY) {
|
||||
gfx_draw_string_left_clipped(dpi, STR_TILE_INSPECTOR_ELEMENT_TYPE, (void*)RCT2_ADDRESS_COMMON_FORMAT_ARGS, w->colours[1], w->x + widget->left + 1, w->y + widget->top + 1, widget->right - widget->left);
|
||||
}
|
||||
if ((widget = &w->widgets[WIDX_COLUMN_BASEHEIGHT])->type != WWT_EMPTY)
|
||||
{
|
||||
gfx_draw_string_left_clipped(dpi, STR_TILE_INSPECTOR_BASE_HEIGHT_SHORT, (void*)RCT2_ADDRESS_COMMON_FORMAT_ARGS, w->colours[1], w->x + widget->left + 1, w->y + widget->top + 1, widget->right - widget->left);
|
||||
}
|
||||
if ((widget = &w->widgets[WIDX_COLUMN_CLEARANCEHEIGHT])->type != WWT_EMPTY)
|
||||
{
|
||||
gfx_draw_string_left_clipped(dpi, STR_TILE_INSPECTOR_CLEARANGE_HEIGHT_SHORT, (void*)RCT2_ADDRESS_COMMON_FORMAT_ARGS, w->colours[1], w->x + widget->left + 1, w->y + widget->top + 1, widget->right - widget->left);
|
||||
}
|
||||
if ((widget = &w->widgets[WIDX_COLUMN_GHOSTFLAG])->type != WWT_EMPTY)
|
||||
{
|
||||
gfx_draw_string_left_clipped(dpi, STR_TILE_INSPECTOR_FLAG_GHOST_SHORT, (void*)RCT2_ADDRESS_COMMON_FORMAT_ARGS, w->colours[1], w->x + widget->left + 1, w->y + widget->top + 1, widget->right - widget->left);
|
||||
}
|
||||
if ((widget = &w->widgets[WIDX_COLUMN_BROKENFLAG])->type != WWT_EMPTY)
|
||||
{
|
||||
gfx_draw_string_left_clipped(dpi, STR_TILE_INSPECTOR_FLAG_BROKEN_SHORT, (void*)RCT2_ADDRESS_COMMON_FORMAT_ARGS, w->colours[1], w->x + widget->left + 1, w->y + widget->top + 1, widget->right - widget->left);
|
||||
}
|
||||
if ((widget = &w->widgets[WIDX_COLUMN_LASTFLAG])->type != WWT_EMPTY)
|
||||
{
|
||||
gfx_draw_string_left_clipped(dpi, STR_TILE_INSPECTOR_FLAG_LAST_SHORT, (void*)RCT2_ADDRESS_COMMON_FORMAT_ARGS, w->colours[1], w->x + widget->left + 1, w->y + widget->top + 1, widget->right - widget->left);
|
||||
}
|
||||
|
||||
// Draw coordinates
|
||||
if (window_tile_inspector_tile_x == -1) { // No tile selected
|
||||
gfx_draw_string_left(dpi, STR_TILE_INSPECTOR_CHOOSE_MSG, NULL, 12, x, y);
|
||||
|
||||
} else {
|
||||
|
||||
sprintf(
|
||||
buffer,
|
||||
"X: %d, Y: %d",
|
||||
|
@ -288,21 +492,14 @@ static void window_tile_inspector_paint(rct_window *w, rct_drawpixelinfo *dpi)
|
|||
);
|
||||
|
||||
gfx_draw_string(dpi, buffer, 12, x, y);
|
||||
|
||||
}
|
||||
|
||||
y += 25;
|
||||
|
||||
draw_string_left_underline(dpi, STR_TILE_INSPECTOR_ELEMENT_TYPE, NULL, 12, x, y);
|
||||
draw_string_left_underline(dpi, STR_TILE_INSPECTOR_BASE_HEIGHT, NULL, 12, x + 200, y);
|
||||
draw_string_left_underline(dpi, STR_TILE_INSPECTOR_CLEARANGE_HEIGHT, NULL, 12, x + 280, y);
|
||||
draw_string_left_underline(dpi, STR_TILE_INSPECTOR_FLAGS, NULL, 12, x + 390, y);
|
||||
|
||||
}
|
||||
|
||||
static void window_tile_inspector_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, int scrollIndex)
|
||||
{
|
||||
int x = 15, y = 11 * (window_tile_inspector_item_count - 1), i = 0;
|
||||
int x = 3;
|
||||
int y = LIST_ITEM_HEIGHT * (window_tile_inspector_item_count - 1);
|
||||
int i = 0;
|
||||
char buffer[256];
|
||||
|
||||
if (window_tile_inspector_tile_x == -1)
|
||||
|
@ -310,15 +507,21 @@ static void window_tile_inspector_scrollpaint(rct_window *w, rct_drawpixelinfo *
|
|||
|
||||
rct_map_element *element = map_get_first_element_at(window_tile_inspector_tile_x, window_tile_inspector_tile_y);
|
||||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = FONT_SPRITE_BASE_MEDIUM;
|
||||
do {
|
||||
|
||||
int type = map_element_get_type(element);
|
||||
char *type_name;
|
||||
int base_height = element->base_height;
|
||||
int clearance_height = element->clearance_height;
|
||||
|
||||
if ((i & 1) != 0)
|
||||
gfx_fill_rect(dpi, x - 15, y, x + WW - 20, y + 11, ColourMapA[w->colours[1]].lighter | 0x1000000);
|
||||
// Fill colour for current list element
|
||||
const int list_width = w->widgets[WIDX_LIST].right - w->widgets[WIDX_LIST].left;
|
||||
if (i == w->selected_list_item) // Currently selected element
|
||||
gfx_fill_rect(dpi, 0, y, list_width, y + LIST_ITEM_HEIGHT - 1, ColourMapA[w->colours[1]].darker | 0x1000000);
|
||||
else if (i == window_tile_inspector_highlighted_index) // Hovering
|
||||
gfx_fill_rect(dpi, 0, y, list_width, y + LIST_ITEM_HEIGHT - 1, ColourMapA[w->colours[1]].mid_dark | 0x1000000);
|
||||
else if ((i & 1) != 0) // odd / even check
|
||||
gfx_fill_rect(dpi, 0, y, list_width, y + LIST_ITEM_HEIGHT - 1, ColourMapA[w->colours[1]].lighter | 0x1000000);
|
||||
|
||||
switch (type) {
|
||||
case MAP_ELEMENT_TYPE_SURFACE:
|
||||
|
@ -332,28 +535,35 @@ static void window_tile_inspector_scrollpaint(rct_window *w, rct_drawpixelinfo *
|
|||
break;
|
||||
case MAP_ELEMENT_TYPE_PATH:
|
||||
{
|
||||
// TODO: use these
|
||||
uint8 pathType, pathDirection;
|
||||
pathType = element->properties.path.type >> 2;
|
||||
pathDirection = element->properties.path.type & 3;
|
||||
const uint8 pathType = footpath_element_get_type(element);
|
||||
const uint8 pathHasScenery = footpath_element_has_path_scenery(element);
|
||||
const uint8 pathAdditionType = footpath_element_get_path_scenery_index(element);
|
||||
if (footpath_element_is_queue(element)) {
|
||||
sprintf(
|
||||
buffer,
|
||||
"Queue for (%d)",
|
||||
element->properties.path.ride_index
|
||||
buffer, "Queue (%s)%s%s for (%d)",
|
||||
language_get_string(g_pathSceneryEntries[pathType]->name), // Path name
|
||||
pathHasScenery ? " with " : "", // Adds " with " when there is something on the path
|
||||
pathHasScenery ? language_get_string(g_pathBitSceneryEntries[pathAdditionType]->name) : "", // Path addition name
|
||||
element->properties.path.ride_index // Ride index for queue
|
||||
);
|
||||
} else {
|
||||
sprintf(
|
||||
buffer,
|
||||
"Path (%s)",
|
||||
"" // TODO: queue? has bins? has benches? e.t.c.
|
||||
buffer, "Path (%s)%s%s",
|
||||
language_get_string(g_pathSceneryEntries[pathType]->name), // Path name
|
||||
pathHasScenery ? " with " : "", // Adds " with " when there is something on the path
|
||||
pathHasScenery ? language_get_string(g_pathBitSceneryEntries[pathAdditionType]->name) : "" // Path addition name
|
||||
);
|
||||
}
|
||||
}
|
||||
type_name = buffer;
|
||||
break;
|
||||
case MAP_ELEMENT_TYPE_TRACK:
|
||||
type_name = "Track"; // TODO: show type?
|
||||
sprintf(
|
||||
buffer,
|
||||
"Track (%s)",
|
||||
language_get_string(2 + GET_RIDE(element->properties.track.ride_index)->type)
|
||||
);
|
||||
type_name = buffer;
|
||||
break;
|
||||
case MAP_ELEMENT_TYPE_SCENERY:
|
||||
sprintf(
|
||||
|
@ -397,24 +607,19 @@ static void window_tile_inspector_scrollpaint(rct_window *w, rct_drawpixelinfo *
|
|||
type_name = buffer;
|
||||
}
|
||||
|
||||
gfx_draw_string(dpi, type_name, 12, x, y);
|
||||
gfx_draw_string_left(dpi, 5182, &base_height, 12, x + 200, y);
|
||||
gfx_draw_string_left(dpi, 5182, &clearance_height, 12, x + 280, y);
|
||||
// Undo relative scroll offset, but keep the 3 pixel padding
|
||||
x = -w->widgets[WIDX_LIST].left;
|
||||
const bool ghost = (element->flags & MAP_ELEMENT_FLAG_GHOST) != 0;
|
||||
const bool broken = (element->flags & MAP_ELEMENT_FLAG_BROKEN) != 0;
|
||||
const bool last = (element->flags & MAP_ELEMENT_FLAG_LAST_TILE) != 0;
|
||||
gfx_draw_string(dpi, type_name, 12, x + COL_X_TYPE + 3, y); // 3px padding
|
||||
gfx_draw_string_left(dpi, 5182, &base_height, 12, x + COL_X_BH, y);
|
||||
gfx_draw_string_left(dpi, 5182, &clearance_height, 12, x + COL_X_CH, y);
|
||||
if (ghost) gfx_draw_string(dpi, (char*)CheckBoxMarkString, w->colours[1], x + COL_X_GF, y);
|
||||
if (broken) gfx_draw_string(dpi, (char*)CheckBoxMarkString, w->colours[1], x + COL_X_BF, y);
|
||||
if (last) gfx_draw_string(dpi, (char*)CheckBoxMarkString, w->colours[1], x + COL_X_LF, y);
|
||||
|
||||
uint8 flags = element->flags;
|
||||
char j;
|
||||
|
||||
buffer[8] = '\0';
|
||||
|
||||
for (j = 7; j >= 0; j--, flags >>= 1) {
|
||||
buffer[j] = flags & 1 ? '1' : '0';
|
||||
}
|
||||
|
||||
gfx_draw_string(dpi, buffer, 12, x + 390, y);
|
||||
|
||||
y -= 11;
|
||||
y -= LIST_ITEM_HEIGHT;
|
||||
i++;
|
||||
|
||||
} while (!map_element_is_last_for_tile(element++));
|
||||
|
||||
}
|
||||
|
|
|
@ -22,13 +22,13 @@
|
|||
#include "../config.h"
|
||||
#include "../editor.h"
|
||||
#include "../game.h"
|
||||
#include "../input.h"
|
||||
#include "../interface/themes.h"
|
||||
#include "../interface/widget.h"
|
||||
#include "../interface/window.h"
|
||||
#include "../localisation/localisation.h"
|
||||
#include "../sprites.h"
|
||||
#include "../tutorial.h"
|
||||
#include "dropdown.h"
|
||||
#include "../interface/themes.h"
|
||||
|
||||
enum {
|
||||
WIDX_START_NEW_GAME,
|
||||
|
@ -148,19 +148,7 @@ static void window_title_menu_mouseup(rct_window *w, int widgetIndex)
|
|||
|
||||
static void window_title_menu_mousedown(int widgetIndex, rct_window*w, rct_widget* widget)
|
||||
{
|
||||
if (widgetIndex == WIDX_SHOW_TUTORIAL) {
|
||||
gDropdownItemsFormat[0] = STR_TUTORIAL_BEGINNERS;
|
||||
gDropdownItemsFormat[1] = STR_TUTORIAL_CUSTOM_RIDES;
|
||||
gDropdownItemsFormat[2] = STR_TUTORIAL_ROLLER_COASTER;
|
||||
window_dropdown_show_text(
|
||||
w->x + widget->left,
|
||||
w->y + widget->top,
|
||||
widget->bottom - widget->top + 1,
|
||||
w->colours[0] | 0x80,
|
||||
DROPDOWN_FLAG_STAY_OPEN,
|
||||
3
|
||||
);
|
||||
} else if (widgetIndex == WIDX_GAME_TOOLS) {
|
||||
if (widgetIndex == WIDX_GAME_TOOLS) {
|
||||
gDropdownItemsFormat[0] = STR_SCENARIO_EDITOR;
|
||||
gDropdownItemsFormat[1] = STR_CONVERT_SAVED_GAME_TO_SCENARIO;
|
||||
gDropdownItemsFormat[2] = STR_ROLLER_COASTER_DESIGNER;
|
||||
|
@ -178,9 +166,7 @@ static void window_title_menu_mousedown(int widgetIndex, rct_window*w, rct_widge
|
|||
|
||||
static void window_title_menu_dropdown(rct_window *w, int widgetIndex, int dropdownIndex)
|
||||
{
|
||||
if (widgetIndex == WIDX_SHOW_TUTORIAL) {
|
||||
tutorial_start(dropdownIndex);
|
||||
} else if (widgetIndex == WIDX_GAME_TOOLS) {
|
||||
if (widgetIndex == WIDX_GAME_TOOLS) {
|
||||
switch (dropdownIndex) {
|
||||
case 0:
|
||||
editor_load();
|
||||
|
@ -200,7 +186,7 @@ static void window_title_menu_dropdown(rct_window *w, int widgetIndex, int dropd
|
|||
|
||||
static void window_title_menu_cursor(rct_window *w, int widgetIndex, int x, int y, int *cursorId)
|
||||
{
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_TIMEOUT, sint16) = 2000;
|
||||
gTooltipTimeout = 2000;
|
||||
}
|
||||
|
||||
static void window_title_menu_paint(rct_window *w, rct_drawpixelinfo *dpi)
|
||||
|
|
|
@ -30,6 +30,29 @@
|
|||
#include "../interface/themes.h"
|
||||
#include "../util/util.h"
|
||||
|
||||
#define INITIAL_NUM_UNLOCKED_SCENARIOS 5
|
||||
|
||||
enum {
|
||||
LIST_ITEM_TYPE_HEADING,
|
||||
LIST_ITEM_TYPE_SCENARIO,
|
||||
LIST_ITEM_TYPE_END,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
uint8 type;
|
||||
union {
|
||||
struct {
|
||||
rct_string_id string_id;
|
||||
} heading;
|
||||
struct {
|
||||
scenario_index_entry *scenario;
|
||||
bool is_locked;
|
||||
} scenario;
|
||||
};
|
||||
} sc_list_item;
|
||||
|
||||
static sc_list_item *_listItems = NULL;
|
||||
|
||||
enum {
|
||||
WIDX_BACKGROUND,
|
||||
WIDX_TITLEBAR,
|
||||
|
@ -40,25 +63,32 @@ enum {
|
|||
WIDX_TAB3,
|
||||
WIDX_TAB4,
|
||||
WIDX_TAB5,
|
||||
WIDX_TAB6,
|
||||
WIDX_TAB7,
|
||||
WIDX_TAB8,
|
||||
WIDX_SCENARIOLIST
|
||||
};
|
||||
|
||||
static rct_widget window_scenarioselect_widgets[] = {
|
||||
{ WWT_FRAME, 0, 0, 609, 0, 333, -1, STR_NONE }, // panel / background
|
||||
{ WWT_CAPTION, 0, 1, 608, 1, 14, STR_SELECT_SCENARIO, STR_WINDOW_TITLE_TIP }, // title bar
|
||||
{ WWT_CLOSEBOX, 0, 597, 607, 2, 13, 824, STR_CLOSE_WINDOW_TIP }, // close x button
|
||||
{ WWT_IMGBTN, 1, 0, 609, 50, 333, -1, STR_NONE }, // tab content panel
|
||||
{ WWT_FRAME, 0, 0, 733, 0, 333, -1, STR_NONE }, // panel / background
|
||||
{ WWT_CAPTION, 0, 1, 732, 1, 14, STR_SELECT_SCENARIO, STR_WINDOW_TITLE_TIP }, // title bar
|
||||
{ WWT_CLOSEBOX, 0, 721, 731, 2, 13, 824, STR_CLOSE_WINDOW_TIP }, // close x button
|
||||
{ WWT_IMGBTN, 1, 0, 733, 50, 333, -1, STR_NONE }, // tab content panel
|
||||
{ WWT_TAB, 1, 3, 93, 17, 50, 0x200015BC, STR_NONE }, // tab 1
|
||||
{ WWT_TAB, 1, 94, 184, 17, 50, 0x200015BC, STR_NONE }, // tab 2
|
||||
{ WWT_TAB, 1, 185, 275, 17, 50, 0x200015BC, STR_NONE }, // tab 3
|
||||
{ WWT_TAB, 1, 276, 366, 17, 50, 0x200015BC, STR_NONE }, // tab 4
|
||||
{ WWT_TAB, 1, 367, 457, 17, 50, 0x200015BC, STR_NONE }, // tab 5
|
||||
{ WWT_SCROLL, 1, 3, 433, 54, 329, 2, STR_NONE }, // level list
|
||||
{ WWT_TAB, 1, 458, 593, 17, 50, 0x200015BC, STR_NONE }, // tab 6
|
||||
{ WWT_TAB, 1, 594, 684, 17, 50, 0x200015BC, STR_NONE }, // tab 7
|
||||
{ WWT_TAB, 1, 685, 775, 17, 50, 0x200015BC, STR_NONE }, // tab 8
|
||||
{ WWT_SCROLL, 1, 3, 555, 54, 329, 2, STR_NONE }, // level list
|
||||
{ WIDGETS_END },
|
||||
};
|
||||
|
||||
static void window_scenarioselect_init_tabs();
|
||||
static void window_scenarioselect_init_tabs(rct_window *w);
|
||||
|
||||
static void window_scenarioselect_close(rct_window *w);
|
||||
static void window_scenarioselect_mouseup(rct_window *w, int widgetIndex);
|
||||
static void window_scenarioselect_mousedown(int widgetIndex, rct_window*w, rct_widget* widget);
|
||||
static void window_scenarioselect_scrollgetsize(rct_window *w, int scrollIndex, int *width, int *height);
|
||||
|
@ -69,7 +99,7 @@ static void window_scenarioselect_paint(rct_window *w, rct_drawpixelinfo *dpi);
|
|||
static void window_scenarioselect_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, int scrollIndex);
|
||||
|
||||
static rct_window_event_list window_scenarioselect_events = {
|
||||
NULL,
|
||||
window_scenarioselect_close,
|
||||
window_scenarioselect_mouseup,
|
||||
NULL,
|
||||
window_scenarioselect_mousedown,
|
||||
|
@ -99,6 +129,11 @@ static rct_window_event_list window_scenarioselect_events = {
|
|||
window_scenarioselect_scrollpaint
|
||||
};
|
||||
|
||||
static void draw_category_heading(rct_window *w, rct_drawpixelinfo *dpi, int left, int right, int y, rct_string_id stringId);
|
||||
static void initialise_list_items(rct_window *w);
|
||||
static bool is_scenario_visible(rct_window *w, scenario_index_entry *scenario);
|
||||
static bool is_locking_enabled(rct_window *w);
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006781B5
|
||||
|
@ -106,6 +141,8 @@ static rct_window_event_list window_scenarioselect_events = {
|
|||
void window_scenarioselect_open()
|
||||
{
|
||||
rct_window* window;
|
||||
int windowWidth;
|
||||
int windowHeight = 334;
|
||||
|
||||
if (window_bring_to_front_by_class(WC_SCENARIO_SELECT) != NULL)
|
||||
return;
|
||||
|
@ -113,48 +150,62 @@ void window_scenarioselect_open()
|
|||
// Load scenario list
|
||||
scenario_load_list();
|
||||
|
||||
// Shrink the window if we're showing scenarios by difficulty level.
|
||||
if (gConfigGeneral.scenario_select_mode == SCENARIO_SELECT_MODE_DIFFICULTY) {
|
||||
windowWidth = 610;
|
||||
} else {
|
||||
windowWidth = 733;
|
||||
}
|
||||
|
||||
window = window_create_centred(
|
||||
610,
|
||||
334,
|
||||
windowWidth,
|
||||
windowHeight,
|
||||
&window_scenarioselect_events,
|
||||
WC_SCENARIO_SELECT,
|
||||
WF_10
|
||||
);
|
||||
window->widgets = window_scenarioselect_widgets;
|
||||
|
||||
window->enabled_widgets = (1 << WIDX_CLOSE) | (1 << WIDX_TAB1) | (1 << WIDX_TAB2)
|
||||
| (1 << WIDX_TAB3) | (1 << WIDX_TAB4) | (1 << WIDX_TAB5);
|
||||
| (1 << WIDX_TAB3) | (1 << WIDX_TAB4) | (1 << WIDX_TAB5)
|
||||
| (1 << WIDX_TAB6) | (1 << WIDX_TAB7) | (1 << WIDX_TAB8);
|
||||
|
||||
window_scenarioselect_init_tabs(window);
|
||||
initialise_list_items(window);
|
||||
|
||||
window_init_scroll_widgets(window);
|
||||
window->viewport_focus_coordinates.var_480 = -1;
|
||||
window->highlighted_item = 0;
|
||||
|
||||
window_scenarioselect_init_tabs();
|
||||
|
||||
window->selected_tab = 0;
|
||||
window->highlighted_scenario = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x00677C8A
|
||||
*/
|
||||
static void window_scenarioselect_init_tabs()
|
||||
static void window_scenarioselect_init_tabs(rct_window *w)
|
||||
{
|
||||
int i, x, show_pages;
|
||||
rct_widget* widget;
|
||||
rct_scenario_basic* scenario;
|
||||
int showPages = 0;
|
||||
for (int i = 0; i < gScenarioListCount; i++) {
|
||||
scenario_index_entry *scenario = &gScenarioList[i];
|
||||
if (gConfigGeneral.scenario_select_mode == SCENARIO_SELECT_MODE_ORIGIN) {
|
||||
showPages |= 1 << scenario->source_game;
|
||||
} else {
|
||||
int category = scenario->category;
|
||||
if (category > SCENARIO_CATEGORY_OTHER) {
|
||||
category = SCENARIO_CATEGORY_OTHER;
|
||||
}
|
||||
showPages |= 1 << category;
|
||||
}
|
||||
}
|
||||
|
||||
show_pages = 0;
|
||||
for (i = 0; i < gScenarioListCount; i++) {
|
||||
scenario = &gScenarioList[i];
|
||||
if (scenario->flags & SCENARIO_FLAGS_VISIBLE)
|
||||
show_pages |= 1 << scenario->category;
|
||||
int firstPage = bitscanforward(showPages);
|
||||
if (firstPage != -1) {
|
||||
w->selected_tab = firstPage;
|
||||
}
|
||||
|
||||
x = 3;
|
||||
for (i = 0; i < 5; i++) {
|
||||
widget = &window_scenarioselect_widgets[i + 4];
|
||||
if (!(show_pages & (1 << i))) {
|
||||
int x = 3;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
rct_widget* widget = &w->widgets[i + 4];
|
||||
if (!(showPages & (1 << i))) {
|
||||
widget->type = WWT_EMPTY;
|
||||
continue;
|
||||
}
|
||||
|
@ -166,17 +217,24 @@ static void window_scenarioselect_init_tabs()
|
|||
}
|
||||
}
|
||||
|
||||
static void window_scenarioselect_close(rct_window *w)
|
||||
{
|
||||
SafeFree(_listItems);
|
||||
}
|
||||
|
||||
static void window_scenarioselect_mouseup(rct_window *w, int widgetIndex)
|
||||
{
|
||||
if (widgetIndex == WIDX_CLOSE)
|
||||
if (widgetIndex == WIDX_CLOSE) {
|
||||
window_close(w);
|
||||
}
|
||||
}
|
||||
|
||||
static void window_scenarioselect_mousedown(int widgetIndex, rct_window*w, rct_widget* widget)
|
||||
{
|
||||
if (widgetIndex >= WIDX_TAB1 && widgetIndex <= WIDX_TAB5) {
|
||||
if (widgetIndex >= WIDX_TAB1 && widgetIndex <= WIDX_TAB8) {
|
||||
w->selected_tab = widgetIndex - 4;
|
||||
w->highlighted_item = 0;
|
||||
w->highlighted_scenario = NULL;
|
||||
initialise_list_items(w);
|
||||
window_invalidate(w);
|
||||
window_event_resize_call(w);
|
||||
window_event_invalidate_call(w);
|
||||
|
@ -187,17 +245,18 @@ static void window_scenarioselect_mousedown(int widgetIndex, rct_window*w, rct_w
|
|||
|
||||
static void window_scenarioselect_scrollgetsize(rct_window *w, int scrollIndex, int *width, int *height)
|
||||
{
|
||||
int i;
|
||||
rct_scenario_basic *scenario;
|
||||
|
||||
*height = 0;
|
||||
for (i = 0; i < gScenarioListCount; i++) {
|
||||
scenario = &gScenarioList[i];
|
||||
if (scenario->category != w->selected_tab)
|
||||
continue;
|
||||
if (scenario->flags & SCENARIO_FLAGS_VISIBLE)
|
||||
*height += 24;
|
||||
int y = 0;
|
||||
for (sc_list_item *listItem = _listItems; listItem->type != LIST_ITEM_TYPE_END; listItem++) {
|
||||
switch (listItem->type) {
|
||||
case LIST_ITEM_TYPE_HEADING:
|
||||
y += 18;
|
||||
break;
|
||||
case LIST_ITEM_TYPE_SCENARIO:
|
||||
y += 24;
|
||||
break;
|
||||
}
|
||||
}
|
||||
*height = y;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -206,23 +265,22 @@ static void window_scenarioselect_scrollgetsize(rct_window *w, int scrollIndex,
|
|||
*/
|
||||
static void window_scenarioselect_scrollmousedown(rct_window *w, int scrollIndex, int x, int y)
|
||||
{
|
||||
int i;
|
||||
rct_scenario_basic *scenario;
|
||||
|
||||
for (i = 0; i < gScenarioListCount; i++) {
|
||||
scenario = &gScenarioList[i];
|
||||
if (scenario->category != w->selected_tab)
|
||||
continue;
|
||||
if (!(scenario->flags & SCENARIO_FLAGS_VISIBLE))
|
||||
continue;
|
||||
|
||||
y -= 24;
|
||||
if (y >= 0)
|
||||
continue;
|
||||
|
||||
audio_play_sound_panned(SOUND_CLICK_1, w->width / 2 + w->x, 0, 0, 0);
|
||||
scenario_load_and_play(scenario);
|
||||
break;
|
||||
for (sc_list_item *listItem = _listItems; listItem->type != LIST_ITEM_TYPE_END; listItem++) {
|
||||
switch (listItem->type) {
|
||||
case LIST_ITEM_TYPE_HEADING:
|
||||
y -= 18;
|
||||
break;
|
||||
case LIST_ITEM_TYPE_SCENARIO:
|
||||
y -= 24;
|
||||
if (y < 0 && !listItem->scenario.is_locked) {
|
||||
audio_play_sound_panned(SOUND_CLICK_1, w->width / 2 + w->x, 0, 0, 0);
|
||||
scenario_load_and_play_from_path(listItem->scenario.scenario->path);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (y < 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -232,26 +290,26 @@ static void window_scenarioselect_scrollmousedown(rct_window *w, int scrollIndex
|
|||
*/
|
||||
static void window_scenarioselect_scrollmouseover(rct_window *w, int scrollIndex, int x, int y)
|
||||
{
|
||||
int i;
|
||||
rct_scenario_basic *scenario, *selected;
|
||||
|
||||
selected = NULL;
|
||||
for (i = 0; i < gScenarioListCount; i++) {
|
||||
scenario = &gScenarioList[i];
|
||||
if (scenario->category != w->selected_tab)
|
||||
continue;
|
||||
if (!(scenario->flags & SCENARIO_FLAGS_VISIBLE))
|
||||
continue;
|
||||
|
||||
y -= 24;
|
||||
if (y >= 0)
|
||||
continue;
|
||||
|
||||
selected = scenario;
|
||||
break;
|
||||
scenario_index_entry *selected = NULL;
|
||||
for (sc_list_item *listItem = _listItems; listItem->type != LIST_ITEM_TYPE_END; listItem++) {
|
||||
switch (listItem->type) {
|
||||
case LIST_ITEM_TYPE_HEADING:
|
||||
y -= 18;
|
||||
break;
|
||||
case LIST_ITEM_TYPE_SCENARIO:
|
||||
y -= 24;
|
||||
if (y < 0 && !listItem->scenario.is_locked) {
|
||||
selected = listItem->scenario.scenario;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (y < 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (w->highlighted_item != (uint32)selected) {
|
||||
w->highlighted_item = (uint32)selected;
|
||||
|
||||
if (w->highlighted_scenario != selected) {
|
||||
w->highlighted_scenario = selected;
|
||||
window_invalidate(w);
|
||||
}
|
||||
}
|
||||
|
@ -261,113 +319,341 @@ static void window_scenarioselect_invalidate(rct_window *w)
|
|||
colour_scheme_update(w);
|
||||
|
||||
w->pressed_widgets &= ~( (1 << WIDX_CLOSE) | (1 << WIDX_TAB1) | (1 << WIDX_TAB2)
|
||||
| (1 << WIDX_TAB3) | (1 << WIDX_TAB4) | (1 << WIDX_TAB5) );
|
||||
| (1 << WIDX_TAB3) | (1 << WIDX_TAB4) | (1 << WIDX_TAB5)
|
||||
| (1 << WIDX_TAB6) | (1 << WIDX_TAB7) | (1 << WIDX_TAB8) );
|
||||
|
||||
w->pressed_widgets |= 1LL << (w->selected_tab + 4);
|
||||
|
||||
int windowWidth = w->width;
|
||||
window_scenarioselect_widgets[WIDX_BACKGROUND].right = windowWidth - 1;
|
||||
window_scenarioselect_widgets[WIDX_TITLEBAR].right = windowWidth - 2;
|
||||
window_scenarioselect_widgets[WIDX_CLOSE].left = windowWidth - 13;
|
||||
window_scenarioselect_widgets[WIDX_CLOSE].right = windowWidth - 3;
|
||||
window_scenarioselect_widgets[WIDX_TABCONTENT].right = windowWidth - 1;
|
||||
window_scenarioselect_widgets[WIDX_SCENARIOLIST].right = windowWidth - 179;
|
||||
|
||||
int windowHeight = w->height;
|
||||
window_scenarioselect_widgets[WIDX_BACKGROUND].bottom = windowHeight - 1;
|
||||
window_scenarioselect_widgets[WIDX_TABCONTENT].bottom = windowHeight - 1;
|
||||
|
||||
const int bottomMargin = gConfigGeneral.debugging_tools ? 17 : 5;
|
||||
window_scenarioselect_widgets[WIDX_SCENARIOLIST].bottom = windowHeight - bottomMargin;
|
||||
}
|
||||
|
||||
static void window_scenarioselect_paint(rct_window *w, rct_drawpixelinfo *dpi)
|
||||
{
|
||||
int i, x, y, format;
|
||||
rct_widget *widget;
|
||||
rct_scenario_basic *scenario;
|
||||
scenario_index_entry *scenario;
|
||||
|
||||
window_draw_widgets(w, dpi);
|
||||
|
||||
format = (theme_get_preset()->features.rct1_scenario_font) ? 5138 : 1193;
|
||||
|
||||
// Text for each tab
|
||||
for (i = 0; i < 5; i++) {
|
||||
for (i = 0; i < 8; i++) {
|
||||
widget = &window_scenarioselect_widgets[WIDX_TAB1 + i];
|
||||
if (widget->type == WWT_EMPTY)
|
||||
continue;
|
||||
|
||||
x = (widget->left + widget->right) / 2 + w->x;
|
||||
y = (widget->top + widget->bottom) / 2 + w->y - 3;
|
||||
RCT2_GLOBAL(0x013CE952 + 0, short) = STR_BEGINNER_PARKS + i;
|
||||
gfx_draw_string_centred_wrapped(dpi, (void*)0x013CE952, x, y, 87, format, 10);
|
||||
|
||||
if (gConfigGeneral.scenario_select_mode == SCENARIO_SELECT_MODE_ORIGIN) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 0, short) = STR_SCENARIO_CATEGORY_RCT1 + i;
|
||||
} else { // old-style
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 0, short) = ScenarioCategoryStringIds[i];
|
||||
}
|
||||
gfx_draw_string_centred_wrapped(dpi, (void*)RCT2_ADDRESS_COMMON_FORMAT_ARGS, x, y, 87, format, 10);
|
||||
}
|
||||
|
||||
// Return if no scenario highlighted
|
||||
scenario = (rct_scenario_basic*)w->highlighted_item;
|
||||
if (scenario == NULL)
|
||||
scenario = w->highlighted_scenario;
|
||||
if (scenario == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Scenario path
|
||||
if (gConfigGeneral.debugging_tools) {
|
||||
utf8 path[MAX_PATH];
|
||||
shorten_path(path, sizeof(path), scenario->path, w->width - 6);
|
||||
|
||||
const utf8 *pathPtr = path;
|
||||
gfx_draw_string_left(dpi, 1170, (void*)&pathPtr, w->colours[1], w->x + 3, w->y + w->height - 3 - 11);
|
||||
}
|
||||
|
||||
// Scenario name
|
||||
x = w->x + window_scenarioselect_widgets[WIDX_SCENARIOLIST].right + 4;
|
||||
y = w->y + window_scenarioselect_widgets[WIDX_TABCONTENT].top + 5;
|
||||
safe_strncpy((char*)0x009BC677, scenario->name, 64);
|
||||
RCT2_GLOBAL(0x013CE952 + 0, short) = 3165;
|
||||
gfx_draw_string_centred_clipped(dpi, 1193, (void*)0x013CE952, 0, x + 85, y, 170);
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 0, short) = 3165; // empty string
|
||||
gfx_draw_string_centred_clipped(dpi, 1193, (void*)RCT2_ADDRESS_COMMON_FORMAT_ARGS, 0, x + 85, y, 170);
|
||||
y += 15;
|
||||
|
||||
// Scenario details
|
||||
safe_strncpy((char*)0x009BC677, scenario->details, 256);
|
||||
RCT2_GLOBAL(0x013CE952 + 0, short) = 3165;
|
||||
y += gfx_draw_string_left_wrapped(dpi, (void*)0x013CE952, x, y, 170, 1191, 0) + 5;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 0, short) = 3165; // empty string
|
||||
y += gfx_draw_string_left_wrapped(dpi, (void*)RCT2_ADDRESS_COMMON_FORMAT_ARGS, x, y, 170, 1191, 0) + 5;
|
||||
|
||||
// Scenario objective
|
||||
RCT2_GLOBAL(0x013CE952 + 0, short) = scenario->objective_type + STR_OBJECTIVE_NONE;
|
||||
RCT2_GLOBAL(0x013CE952 + 2, short) = scenario->objective_arg_3;
|
||||
RCT2_GLOBAL(0x013CE952 + 4, short) = date_get_total_months(MONTH_OCTOBER, scenario->objective_arg_1);
|
||||
RCT2_GLOBAL(0x013CE952 + 6, int) = scenario->objective_arg_2;
|
||||
y += gfx_draw_string_left_wrapped(dpi, (void*)0x013CE952, x, y, 170, STR_OBJECTIVE, 0) + 5;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 0, short) = scenario->objective_type + STR_OBJECTIVE_NONE;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 2, short) = scenario->objective_arg_3;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 4, short) = date_get_total_months(MONTH_OCTOBER, scenario->objective_arg_1);
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 6, int) = scenario->objective_arg_2;
|
||||
y += gfx_draw_string_left_wrapped(dpi, (void*)RCT2_ADDRESS_COMMON_FORMAT_ARGS, x, y, 170, STR_OBJECTIVE, 0) + 5;
|
||||
|
||||
// Scenario score
|
||||
if (scenario->flags & SCENARIO_FLAGS_COMPLETED) {
|
||||
safe_strncpy((char*)0x009BC677, scenario->completed_by, 64);
|
||||
RCT2_GLOBAL(0x013CE952 + 0, short) = 3165;
|
||||
RCT2_GLOBAL(0x013CE952 + 2, int) = scenario->company_value;
|
||||
y += gfx_draw_string_left_wrapped(dpi, (void*)0x013CE952, x, y, 170, STR_COMPLETED_BY_WITH_COMPANY_VALUE, 0);
|
||||
if (scenario->highscore != NULL) {
|
||||
const utf8 *completedByName = "???";
|
||||
if (!str_is_null_or_empty(scenario->highscore->name)) {
|
||||
completedByName = scenario->highscore->name;
|
||||
}
|
||||
safe_strncpy((char*)0x009BC677, completedByName, 64);
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 0, short) = 3165; // empty string
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 2, int) = scenario->highscore->company_value;
|
||||
y += gfx_draw_string_left_wrapped(dpi, (void*)RCT2_ADDRESS_COMMON_FORMAT_ARGS, x, y, 170, STR_COMPLETED_BY_WITH_COMPANY_VALUE, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void window_scenarioselect_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, int scrollIndex)
|
||||
{
|
||||
int i, y, colour, highlighted, highlighted_format, unhighlighted_format;
|
||||
rct_scenario_basic *scenario;
|
||||
|
||||
colour = ColourMapA[w->colours[1]].mid_light;
|
||||
int colour = ColourMapA[w->colours[1]].mid_light;
|
||||
colour = (colour << 24) | (colour << 16) | (colour << 8) | colour;
|
||||
gfx_clear(dpi, colour);
|
||||
|
||||
highlighted_format = (theme_get_preset()->features.rct1_scenario_font) ? 5139 : 1193;
|
||||
unhighlighted_format = (theme_get_preset()->features.rct1_scenario_font) ? 5139 : 1191;
|
||||
int highlighted_format = (theme_get_preset()->features.rct1_scenario_font) ? 5139 : 1193;
|
||||
int unhighlighted_format = (theme_get_preset()->features.rct1_scenario_font) ? 5139 : 1191;
|
||||
|
||||
y = 0;
|
||||
for (i = 0; i < gScenarioListCount; i++) {
|
||||
scenario = &gScenarioList[i];
|
||||
if (scenario->category != w->selected_tab)
|
||||
bool wide = gConfigGeneral.scenario_select_mode == SCENARIO_SELECT_MODE_ORIGIN;
|
||||
|
||||
rct_widget *listWidget = &w->widgets[WIDX_SCENARIOLIST];
|
||||
int listWidth = listWidget->right - listWidget->left - 12;
|
||||
|
||||
int y = 0;
|
||||
for (sc_list_item *listItem = _listItems; listItem->type != LIST_ITEM_TYPE_END; listItem++) {
|
||||
if (y > dpi->y + dpi->height) {
|
||||
continue;
|
||||
if (!(scenario->flags & SCENARIO_FLAGS_VISIBLE))
|
||||
continue;
|
||||
|
||||
if (y > dpi->y + dpi->height)
|
||||
continue;
|
||||
|
||||
highlighted = w->highlighted_item == (int)scenario;
|
||||
|
||||
// Draw hover highlight
|
||||
if (highlighted)
|
||||
gfx_fill_rect(dpi, 0, y, w->width, y + 23, 0x02000031);
|
||||
|
||||
// Draw scenario name
|
||||
safe_strncpy((char*)0x009BC677, scenario->name, 64);
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS, short) = 3165;
|
||||
gfx_draw_string_centred(dpi, highlighted ? highlighted_format : unhighlighted_format, 210, y + 1, 0, (void*)0x013CE952);
|
||||
|
||||
// Check if scenario is completed
|
||||
if (scenario->flags & SCENARIO_FLAGS_COMPLETED) {
|
||||
// Draw completion tick
|
||||
gfx_draw_sprite(dpi, 0x5A9F, 395, y + 1, 0);
|
||||
|
||||
// Draw completion score
|
||||
safe_strncpy((char*)0x009BC677, scenario->completed_by, 64);
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS, short) = 2793;
|
||||
RCT2_GLOBAL(0x013CE954, short) = 3165;
|
||||
gfx_draw_string_centred(dpi, highlighted ? 1193 : 1191, 210, y + 11, 0, (void*)0x013CE952);
|
||||
}
|
||||
|
||||
y += 24;
|
||||
switch (listItem->type) {
|
||||
case LIST_ITEM_TYPE_HEADING:;
|
||||
const int horizontalRuleMargin = 4;
|
||||
draw_category_heading(w, dpi, horizontalRuleMargin, listWidth - horizontalRuleMargin, y + 2, listItem->heading.string_id);
|
||||
y += 18;
|
||||
break;
|
||||
case LIST_ITEM_TYPE_SCENARIO:;
|
||||
// Draw hover highlight
|
||||
scenario_index_entry *scenario = listItem->scenario.scenario;
|
||||
bool isHighlighted = w->highlighted_scenario == scenario;
|
||||
if (isHighlighted) {
|
||||
gfx_fill_rect(dpi, 0, y, w->width, y + 23, 0x02000031);
|
||||
}
|
||||
|
||||
bool isCompleted = scenario->highscore != NULL;
|
||||
bool isDisabled = listItem->scenario.is_locked;
|
||||
|
||||
// Draw scenario name
|
||||
rct_string_id placeholderStringId = 3165;
|
||||
safe_strncpy((char*)language_get_string(placeholderStringId), scenario->name, 64);
|
||||
int format = isDisabled ? 865 : (isHighlighted ? highlighted_format : unhighlighted_format);
|
||||
colour = isDisabled ? w->colours[1] | 0x40 : COLOUR_BLACK;
|
||||
gfx_draw_string_centred(dpi, format, wide ? 270 : 210, y + 1, colour, &placeholderStringId);
|
||||
|
||||
// Check if scenario is completed
|
||||
if (isCompleted) {
|
||||
// Draw completion tick
|
||||
gfx_draw_sprite(dpi, 0x5A9F, wide ? 500 : 395, y + 1, 0);
|
||||
|
||||
// Draw completion score
|
||||
const utf8 *completedByName = "???";
|
||||
if (!str_is_null_or_empty(scenario->highscore->name)) {
|
||||
completedByName = scenario->highscore->name;
|
||||
}
|
||||
safe_strncpy((char*)language_get_string(placeholderStringId), completedByName, 64);
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 0, rct_string_id) = 2793;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 2, rct_string_id) = placeholderStringId;
|
||||
gfx_draw_string_centred(dpi, format, wide ? 270 : 210, y + 11, 0, (void*)RCT2_ADDRESS_COMMON_FORMAT_ARGS);
|
||||
}
|
||||
|
||||
y += 24;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_category_heading(rct_window *w, rct_drawpixelinfo *dpi, int left, int right, int y, rct_string_id stringId)
|
||||
{
|
||||
uint8 baseColour = w->colours[1];
|
||||
uint8 lightColour = ColourMapA[baseColour].lighter;
|
||||
uint8 darkColour = ColourMapA[baseColour].mid_dark;
|
||||
|
||||
// Draw string
|
||||
int centreX = (left + right) / 2;
|
||||
gfx_draw_string_centred(dpi, stringId, centreX, y, baseColour, NULL);
|
||||
|
||||
// Get string dimensions
|
||||
utf8 *buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, utf8);
|
||||
format_string(buffer, stringId, NULL);
|
||||
int categoryStringHalfWidth = (gfx_get_string_width(buffer) / 2) + 4;
|
||||
int strLeft = centreX - categoryStringHalfWidth;
|
||||
int strRight = centreX + categoryStringHalfWidth;
|
||||
|
||||
// Draw light horizontal rule
|
||||
int lineY = y + 4;
|
||||
gfx_draw_line(dpi, left, lineY, strLeft, lineY, lightColour);
|
||||
gfx_draw_line(dpi, strRight, lineY, right, lineY, lightColour);
|
||||
|
||||
// Draw dark horizontal rule
|
||||
lineY++;
|
||||
gfx_draw_line(dpi, left, lineY, strLeft, lineY, darkColour);
|
||||
gfx_draw_line(dpi, strRight, lineY, right, lineY, darkColour);
|
||||
}
|
||||
|
||||
static void initialise_list_items(rct_window *w)
|
||||
{
|
||||
SafeFree(_listItems);
|
||||
|
||||
int capacity = gScenarioListCount + 16;
|
||||
int length = 0;
|
||||
_listItems = malloc(capacity * sizeof(sc_list_item));
|
||||
|
||||
// Mega park unlock
|
||||
const uint32 rct1RequiredCompletedScenarios = (1 << SC_MEGA_PARK) - 1;
|
||||
uint32 rct1CompletedScenarios = 0;
|
||||
int megaParkListItemIndex = -1;
|
||||
|
||||
int numUnlocks = INITIAL_NUM_UNLOCKED_SCENARIOS;
|
||||
uint8 currentHeading = UINT8_MAX;
|
||||
for (int i = 0; i < gScenarioListCount; i++) {
|
||||
scenario_index_entry *scenario = &gScenarioList[i];
|
||||
if (!is_scenario_visible(w, scenario)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
sc_list_item *listItem;
|
||||
|
||||
// Category heading
|
||||
rct_string_id headingStringId = STR_NONE;
|
||||
if (gConfigGeneral.scenario_select_mode == SCENARIO_SELECT_MODE_ORIGIN) {
|
||||
if (w->selected_tab != SCENARIO_SOURCE_REAL && currentHeading != scenario->category) {
|
||||
currentHeading = scenario->category;
|
||||
headingStringId = ScenarioCategoryStringIds[currentHeading];
|
||||
}
|
||||
} else {
|
||||
if (w->selected_tab <= SCENARIO_CATEGORY_EXPERT) {
|
||||
if (currentHeading != scenario->source_game) {
|
||||
currentHeading = scenario->source_game;
|
||||
headingStringId = STR_SCENARIO_CATEGORY_RCT1 + currentHeading;
|
||||
}
|
||||
} else if (w->selected_tab == SCENARIO_CATEGORY_OTHER) {
|
||||
int category = scenario->category;
|
||||
if (category <= SCENARIO_CATEGORY_REAL) {
|
||||
category = SCENARIO_CATEGORY_OTHER;
|
||||
}
|
||||
if (currentHeading != category) {
|
||||
currentHeading = category;
|
||||
headingStringId = ScenarioCategoryStringIds[category];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (headingStringId != (rct_string_id)STR_NONE) {
|
||||
// Ensure list capacity
|
||||
if (length == capacity) {
|
||||
capacity += 32;
|
||||
_listItems = realloc(_listItems, capacity * sizeof(sc_list_item));
|
||||
}
|
||||
listItem = &_listItems[length++];
|
||||
|
||||
listItem->type = LIST_ITEM_TYPE_HEADING;
|
||||
listItem->heading.string_id = headingStringId;
|
||||
}
|
||||
|
||||
// Ensure list capacity
|
||||
if (length == capacity) {
|
||||
capacity += 32;
|
||||
_listItems = realloc(_listItems, capacity * sizeof(sc_list_item));
|
||||
}
|
||||
listItem = &_listItems[length++];
|
||||
|
||||
// Scenario
|
||||
listItem->type = LIST_ITEM_TYPE_SCENARIO;
|
||||
listItem->scenario.scenario = scenario;
|
||||
if (is_locking_enabled(w)) {
|
||||
listItem->scenario.is_locked = numUnlocks <= 0;
|
||||
if (scenario->highscore == NULL) {
|
||||
numUnlocks--;
|
||||
} else {
|
||||
// Mark RCT1 scenario as completed
|
||||
if (scenario->sc_id < SC_MEGA_PARK) {
|
||||
rct1CompletedScenarios |= 1 << scenario->sc_id;
|
||||
}
|
||||
}
|
||||
|
||||
// If scenario is Mega Park, keep a reference to it
|
||||
if (scenario->sc_id == SC_MEGA_PARK) {
|
||||
megaParkListItemIndex = length - 1;
|
||||
}
|
||||
} else {
|
||||
listItem->scenario.is_locked = false;
|
||||
}
|
||||
}
|
||||
|
||||
length++;
|
||||
_listItems = realloc(_listItems, length * sizeof(sc_list_item));
|
||||
_listItems[length - 1].type = LIST_ITEM_TYPE_END;
|
||||
|
||||
// Mega park handling
|
||||
if (megaParkListItemIndex != -1) {
|
||||
bool megaParkLocked = (rct1CompletedScenarios & rct1RequiredCompletedScenarios) != rct1RequiredCompletedScenarios;
|
||||
_listItems[megaParkListItemIndex].scenario.is_locked = megaParkLocked;
|
||||
if (megaParkLocked && gConfigGeneral.scenario_hide_mega_park) {
|
||||
// Remove mega park
|
||||
int remainingItems = length - megaParkListItemIndex - 1;
|
||||
memmove(&_listItems[megaParkListItemIndex], &_listItems[megaParkListItemIndex + 1], remainingItems);
|
||||
|
||||
// Remove empty headings
|
||||
int i = 0;
|
||||
for (sc_list_item *listItem = _listItems; listItem->type != LIST_ITEM_TYPE_END; listItem++) {
|
||||
if (listItem->type == LIST_ITEM_TYPE_HEADING && (listItem + 1)->type != LIST_ITEM_TYPE_SCENARIO) {
|
||||
remainingItems = length - i - 1;
|
||||
memmove(&_listItems[i], &_listItems[i + 1], remainingItems);
|
||||
listItem--;
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool is_scenario_visible(rct_window *w, scenario_index_entry *scenario)
|
||||
{
|
||||
if (gConfigGeneral.scenario_select_mode == SCENARIO_SELECT_MODE_ORIGIN) {
|
||||
if (scenario->source_game != w->selected_tab) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
int category = scenario->category;
|
||||
if (category > SCENARIO_CATEGORY_OTHER) {
|
||||
category = SCENARIO_CATEGORY_OTHER;
|
||||
}
|
||||
if (category != w->selected_tab) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool is_locking_enabled(rct_window *w)
|
||||
{
|
||||
if (gConfigGeneral.scenario_select_mode != SCENARIO_SELECT_MODE_ORIGIN) {
|
||||
return false;
|
||||
}
|
||||
if (!gConfigGeneral.scenario_unlocking_enabled) {
|
||||
return false;
|
||||
}
|
||||
if (w->selected_tab >= 6) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "../addresses.h"
|
||||
#include "../drawing/drawing.h"
|
||||
#include "../localisation/localisation.h"
|
||||
#include "../input.h"
|
||||
#include "../interface/widget.h"
|
||||
#include "../interface/window.h"
|
||||
|
||||
|
@ -70,12 +71,12 @@ static rct_window_event_list window_tooltip_events = {
|
|||
|
||||
void window_tooltip_reset(int x, int y)
|
||||
{
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_CURSOR_X, uint16) = x;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_CURSOR_Y, uint16) = y;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_TIMEOUT, uint16) = 0;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_WINDOW_CLASS, uint8) = 255;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = 1;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) &= ~(1 << 4);
|
||||
gTooltipCursorX = x;
|
||||
gTooltipCursorY = y;
|
||||
gTooltipTimeout = 0;
|
||||
gTooltipWidget.window_classification = 255;
|
||||
gInputState = INPUT_STATE_NORMAL;
|
||||
gInputFlags &= ~INPUT_FLAG_4;
|
||||
}
|
||||
|
||||
uint8* gTooltip_text_buffer = RCT2_ADDRESS(RCT2_ADDRESS_TOOLTIP_TEXT_BUFFER, uint8);
|
||||
|
@ -134,7 +135,7 @@ void window_tooltip_show(rct_string_id id, int x, int y)
|
|||
);
|
||||
w->widgets = window_tooltip_widgets;
|
||||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_NOT_SHOWN_TICKS, uint16) = 0;
|
||||
gTooltipNotShownTicks = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -153,9 +154,9 @@ void window_tooltip_open(rct_window *widgetWindow, int widgetIndex, int x, int y
|
|||
if (widget->tooltip == 0xFFFF)
|
||||
return;
|
||||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_WINDOW_CLASS, rct_windowclass) = widgetWindow->classification;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_WINDOW_NUMBER, rct_windownumber) = widgetWindow->number;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_WIDGET_INDEX, uint16) = widgetIndex;
|
||||
gTooltipWidget.window_classification = widgetWindow->classification;
|
||||
gTooltipWidget.window_number = widgetWindow->number;
|
||||
gTooltipWidget.widget_index = widgetIndex;
|
||||
|
||||
if (window_event_tooltip_call(widgetWindow, widgetIndex) == (rct_string_id)STR_NONE)
|
||||
return;
|
||||
|
@ -170,8 +171,8 @@ void window_tooltip_open(rct_window *widgetWindow, int widgetIndex, int x, int y
|
|||
void window_tooltip_close()
|
||||
{
|
||||
window_close_by_class(WC_TOOLTIP);
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_TIMEOUT, uint16) = 0;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_WINDOW_CLASS, rct_windowclass) = 255;
|
||||
gTooltipTimeout = 0;
|
||||
gTooltipWidget.window_classification = 255;
|
||||
RCT2_GLOBAL(0x0142006C, sint32) = -1;
|
||||
RCT2_GLOBAL(0x009DE51E, uint8) = 0;
|
||||
}
|
||||
|
@ -192,7 +193,7 @@ static void window_tooltip_onclose(rct_window *w)
|
|||
static void window_tooltip_update(rct_window *w)
|
||||
{
|
||||
if (RCT2_GLOBAL(0x009DE51E, uint8) == 0)
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_NOT_SHOWN_TICKS, uint16) = 0;
|
||||
gTooltipNotShownTicks = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -310,7 +310,7 @@ static void window_top_toolbar_mouseup(rct_window *w, int widgetIndex)
|
|||
break;
|
||||
case WIDX_SCENERY:
|
||||
if (!tool_set(w, WIDX_SCENERY, 0)) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_6;
|
||||
gInputFlags |= INPUT_FLAG_6;
|
||||
window_scenery_open();
|
||||
}
|
||||
break;
|
||||
|
@ -3117,12 +3117,12 @@ void toggle_footpath_window()
|
|||
*/
|
||||
void toggle_land_window(rct_window *topToolbar, int widgetIndex)
|
||||
{
|
||||
if ((RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE) && RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) == 1 && RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16) == 7) {
|
||||
if ((gInputFlags & INPUT_FLAG_TOOL_ACTIVE) && RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) == WC_TOP_TOOLBAR && RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16) == 7) {
|
||||
tool_cancel();
|
||||
} else {
|
||||
show_gridlines();
|
||||
tool_set(topToolbar, widgetIndex, 18);
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_6;
|
||||
gInputFlags |= INPUT_FLAG_6;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_LAND_TOOL_SIZE, sint16) = 1;
|
||||
window_land_open();
|
||||
}
|
||||
|
@ -3134,12 +3134,12 @@ void toggle_land_window(rct_window *topToolbar, int widgetIndex)
|
|||
*/
|
||||
void toggle_clear_scenery_window(rct_window *topToolbar, int widgetIndex)
|
||||
{
|
||||
if ((RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE) && RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) == 1 && RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16) == 16) {
|
||||
if ((gInputFlags & INPUT_FLAG_TOOL_ACTIVE) && RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) == WC_TOP_TOOLBAR && RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16) == 16) {
|
||||
tool_cancel();
|
||||
} else {
|
||||
show_gridlines();
|
||||
tool_set(topToolbar, widgetIndex, 12);
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_6;
|
||||
gInputFlags |= INPUT_FLAG_6;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_LAND_TOOL_SIZE, sint16) = 2;
|
||||
window_clear_scenery_open();
|
||||
}
|
||||
|
@ -3151,12 +3151,12 @@ void toggle_clear_scenery_window(rct_window *topToolbar, int widgetIndex)
|
|||
*/
|
||||
void toggle_water_window(rct_window *topToolbar, int widgetIndex)
|
||||
{
|
||||
if ((RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE) && RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) == 1 && RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16) == 8) {
|
||||
if ((gInputFlags & INPUT_FLAG_TOOL_ACTIVE) && RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) == WC_TOP_TOOLBAR && RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16) == 8) {
|
||||
tool_cancel();
|
||||
} else {
|
||||
show_gridlines();
|
||||
tool_set(topToolbar, widgetIndex, 19);
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_6;
|
||||
gInputFlags |= INPUT_FLAG_6;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_LAND_TOOL_SIZE, sint16) = 1;
|
||||
window_water_open();
|
||||
}
|
||||
|
@ -3168,7 +3168,7 @@ void toggle_water_window(rct_window *topToolbar, int widgetIndex)
|
|||
*/
|
||||
bool land_tool_is_active()
|
||||
{
|
||||
if (!(RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE))
|
||||
if (!(gInputFlags & INPUT_FLAG_TOOL_ACTIVE))
|
||||
return false;
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) != WC_TOP_TOOLBAR)
|
||||
return false;
|
||||
|
|
|
@ -389,7 +389,7 @@ void window_track_place_open()
|
|||
w->enabled_widgets = 4 | 8 | 0x10 | 0x20;
|
||||
window_init_scroll_widgets(w);
|
||||
tool_set(w, 6, 12);
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_6;
|
||||
gInputFlags |= INPUT_FLAG_6;
|
||||
window_push_others_right(w);
|
||||
show_gridlines();
|
||||
_window_track_place_last_cost = MONEY32_UNDEFINED;
|
||||
|
@ -449,7 +449,7 @@ static void window_track_place_mouseup(rct_window *w, int widgetIndex)
|
|||
*/
|
||||
static void window_track_place_update(rct_window *w)
|
||||
{
|
||||
if (!(RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE))
|
||||
if (!(gInputFlags & INPUT_FLAG_TOOL_ACTIVE))
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) != WC_TRACK_DESIGN_PLACE)
|
||||
window_close(w);
|
||||
}
|
||||
|
|
|
@ -181,8 +181,8 @@ static void window_water_textinput(rct_window *w, int widgetIndex, char *text)
|
|||
|
||||
static void window_water_inputsize(rct_window *w)
|
||||
{
|
||||
((uint16*)TextInputDescriptionArgs)[0] = MINIMUM_TOOL_SIZE;
|
||||
((uint16*)TextInputDescriptionArgs)[1] = MAXIMUM_TOOL_SIZE;
|
||||
TextInputDescriptionArgs[0] = MINIMUM_TOOL_SIZE;
|
||||
TextInputDescriptionArgs[1] = MAXIMUM_TOOL_SIZE;
|
||||
window_text_input_open(w, WIDX_PREVIEW, 5128, 5129, STR_NONE, STR_NONE, 3);
|
||||
}
|
||||
|
||||
|
@ -256,7 +256,7 @@ static void window_water_paint(rct_window *w, rct_drawpixelinfo *dpi)
|
|||
*/
|
||||
static int window_water_should_close()
|
||||
{
|
||||
if (!(RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE))
|
||||
if (!(gInputFlags & INPUT_FLAG_TOOL_ACTIVE))
|
||||
return 1;
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) != WC_TOP_TOOLBAR)
|
||||
return 1;
|
||||
|
|
|
@ -210,7 +210,7 @@ static money32 footpath_element_update(int x, int y, rct_map_element *mapElement
|
|||
} else if (pathItemType != 0) {
|
||||
if (
|
||||
!(flags & GAME_COMMAND_FLAG_GHOST) &&
|
||||
(mapElement->properties.path.additions & 0x0F) == pathItemType &&
|
||||
footpath_element_get_path_scenery(mapElement) == pathItemType &&
|
||||
!(mapElement->flags & MAP_ELEMENT_FLAG_BROKEN)
|
||||
) {
|
||||
if (flags & GAME_COMMAND_FLAG_4)
|
||||
|
@ -249,14 +249,17 @@ static money32 footpath_element_update(int x, int y, rct_map_element *mapElement
|
|||
if (flags & GAME_COMMAND_FLAG_4)
|
||||
return MONEY32_UNDEFINED;
|
||||
|
||||
// Should place a ghost?
|
||||
if (flags & GAME_COMMAND_FLAG_GHOST) {
|
||||
if (mapElement->properties.path.additions & 0x0F) {
|
||||
// Check if there is something on the path already
|
||||
if (footpath_element_has_path_scenery(mapElement)) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, rct_string_id) = STR_NONE;
|
||||
return MONEY32_UNDEFINED;
|
||||
}
|
||||
|
||||
// There is nothing yet - check if we should place a ghost
|
||||
if (flags & GAME_COMMAND_FLAG_APPLY)
|
||||
mapElement->properties.path.additions |= 0x80;
|
||||
footpath_scenery_set_is_ghost(mapElement, true);
|
||||
}
|
||||
|
||||
if (!(flags & GAME_COMMAND_FLAG_APPLY))
|
||||
|
@ -264,12 +267,12 @@ static money32 footpath_element_update(int x, int y, rct_map_element *mapElement
|
|||
|
||||
if (
|
||||
(pathItemType != 0 && !(flags & GAME_COMMAND_FLAG_GHOST)) ||
|
||||
(pathItemType == 0 && (mapElement->properties.path.additions & 0x80))
|
||||
(pathItemType == 0 && footpath_element_path_scenery_is_ghost(mapElement))
|
||||
) {
|
||||
mapElement->properties.path.additions &= ~0x80;
|
||||
footpath_scenery_set_is_ghost(mapElement, false);
|
||||
}
|
||||
|
||||
mapElement->properties.path.additions = (mapElement->properties.path.additions & 0xF0) | pathItemType;
|
||||
footpath_element_set_path_scenery(mapElement, pathItemType);
|
||||
mapElement->flags &= ~MAP_ELEMENT_FLAG_BROKEN;
|
||||
if (pathItemType != 0) {
|
||||
rct_scenery_entry* scenery_entry = g_pathBitSceneryEntries[pathItemType - 1];
|
||||
|
@ -292,7 +295,7 @@ static money32 footpath_element_update(int x, int y, rct_map_element *mapElement
|
|||
|
||||
mapElement->properties.path.type = (mapElement->properties.path.type & 0x0F) | (type << 4);
|
||||
mapElement->type = (mapElement->type & 0xFE) | (type >> 7);
|
||||
mapElement->properties.path.additions = (mapElement->properties.path.additions & 0xF0) | pathItemType;
|
||||
footpath_element_set_path_scenery(mapElement, pathItemType);
|
||||
mapElement->flags &= ~MAP_ELEMENT_FLAG_BROKEN;
|
||||
|
||||
loc_6A6620(flags, x, y, mapElement);
|
||||
|
@ -1579,7 +1582,7 @@ bool footpath_element_is_sloped(rct_map_element *mapElement)
|
|||
return mapElement->properties.path.type & 4;
|
||||
}
|
||||
|
||||
int footpath_element_get_slope_direction(rct_map_element *mapElement)
|
||||
uint8 footpath_element_get_slope_direction(rct_map_element *mapElement)
|
||||
{
|
||||
return mapElement->properties.path.type & 3;
|
||||
}
|
||||
|
@ -1594,6 +1597,45 @@ bool footpath_element_is_wide(rct_map_element *mapElement)
|
|||
return mapElement->type & 2;
|
||||
}
|
||||
|
||||
bool footpath_element_has_path_scenery(rct_map_element *mapElement)
|
||||
{
|
||||
return (mapElement->properties.path.additions & 0xF) > 0;
|
||||
}
|
||||
|
||||
uint8 footpath_element_get_path_scenery(rct_map_element *mapElement)
|
||||
{
|
||||
return mapElement->properties.path.additions & 0xF;
|
||||
}
|
||||
|
||||
void footpath_element_set_path_scenery(rct_map_element *mapElement, uint8 pathSceneryType)
|
||||
{
|
||||
mapElement->properties.path.additions = (mapElement->properties.path.additions & 0xF0) | pathSceneryType;
|
||||
}
|
||||
|
||||
uint8 footpath_element_get_path_scenery_index(rct_map_element *mapElement)
|
||||
{
|
||||
return footpath_element_get_path_scenery(mapElement) - 1;
|
||||
}
|
||||
|
||||
bool footpath_element_path_scenery_is_ghost(rct_map_element *mapElement)
|
||||
{
|
||||
return (mapElement->properties.path.additions & 0x80) == 0x80;
|
||||
}
|
||||
|
||||
void footpath_scenery_set_is_ghost(rct_map_element *mapElement, bool isGhost)
|
||||
{
|
||||
// Remove ghost flag
|
||||
mapElement->properties.path.additions &= ~0x80;
|
||||
// Set flag if it should be a ghost
|
||||
if (isGhost)
|
||||
mapElement->properties.path.additions |= 0x80;
|
||||
}
|
||||
|
||||
uint8 footpath_element_get_type(rct_map_element *mapElement)
|
||||
{
|
||||
return mapElement->properties.path.type >> 4;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006A8B12
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue