diff --git a/OpenRCT2.xcodeproj/project.pbxproj b/OpenRCT2.xcodeproj/project.pbxproj index 82b726f9ed..5b071a34fb 100644 --- a/OpenRCT2.xcodeproj/project.pbxproj +++ b/OpenRCT2.xcodeproj/project.pbxproj @@ -344,23 +344,11 @@ 93DFD02E24521BA0001FCBAF /* FileWatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 93DFD02C24521B9F001FCBAF /* FileWatcher.h */; }; 93DFD02F24521BA0001FCBAF /* FileWatcher.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93DFD02D24521BA0001FCBAF /* FileWatcher.cpp */; }; 93DFD04424521C1A001FCBAF /* Plugin.h in Headers */ = {isa = PBXBuildFile; fileRef = 93DFD03124521C19001FCBAF /* Plugin.h */; }; - 93DFD04524521C1A001FCBAF /* ScObject.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 93DFD03224521C19001FCBAF /* ScObject.hpp */; }; 93DFD04624521C1A001FCBAF /* HookEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 93DFD03324521C19001FCBAF /* HookEngine.h */; }; - 93DFD04724521C1A001FCBAF /* ScNetwork.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 93DFD03424521C19001FCBAF /* ScNetwork.hpp */; }; 93DFD04824521C1A001FCBAF /* HookEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93DFD03524521C19001FCBAF /* HookEngine.cpp */; }; - 93DFD04924521C1A001FCBAF /* ScTile.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 93DFD03624521C19001FCBAF /* ScTile.hpp */; }; - 93DFD04A24521C1A001FCBAF /* ScConfiguration.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 93DFD03724521C19001FCBAF /* ScConfiguration.hpp */; }; 93DFD04B24521C1A001FCBAF /* ScriptEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93DFD03824521C19001FCBAF /* ScriptEngine.cpp */; }; - 93DFD04C24521C1A001FCBAF /* ScDisposable.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 93DFD03924521C19001FCBAF /* ScDisposable.hpp */; }; - 93DFD04D24521C1A001FCBAF /* ScEntity.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 93DFD03A24521C19001FCBAF /* ScEntity.hpp */; }; 93DFD04E24521C1A001FCBAF /* Duktape.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 93DFD03B24521C19001FCBAF /* Duktape.hpp */; }; - 93DFD04F24521C1A001FCBAF /* ScConsole.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 93DFD03C24521C19001FCBAF /* ScConsole.hpp */; }; - 93DFD05024521C1A001FCBAF /* ScPark.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 93DFD03D24521C19001FCBAF /* ScPark.hpp */; }; - 93DFD05124521C1A001FCBAF /* ScContext.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 93DFD03E24521C19001FCBAF /* ScContext.hpp */; }; 93DFD05224521C1A001FCBAF /* Plugin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93DFD03F24521C19001FCBAF /* Plugin.cpp */; }; - 93DFD05324521C1A001FCBAF /* ScRide.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 93DFD04024521C19001FCBAF /* ScRide.hpp */; }; - 93DFD05424521C1A001FCBAF /* ScDate.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 93DFD04124521C19001FCBAF /* ScDate.hpp */; }; - 93DFD05524521C1A001FCBAF /* ScMap.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 93DFD04224521C19001FCBAF /* ScMap.hpp */; }; 93DFD05624521C1A001FCBAF /* ScriptEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 93DFD04324521C19001FCBAF /* ScriptEngine.h */; }; 93F6004C213DD7DD00EEB83E /* TerrainSurfaceObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93F60049213DD7DC00EEB83E /* TerrainSurfaceObject.cpp */; }; 93F6004D213DD7DD00EEB83E /* TerrainEdgeObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93F6004A213DD7DC00EEB83E /* TerrainEdgeObject.cpp */; }; @@ -768,6 +756,46 @@ 0746674FA0794ABF86E406A1 /* Litter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9D3DD6CD73F5421880280D9D /* Litter.cpp */; }; B9B6F97CE24E4A559C7BBA0A /* RideConstruction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6BCCA2EF0F5A40D5B83A83AC /* RideConstruction.cpp */; }; 317B766A750D4365B22A1682 /* EnumMap.hpp in Headers */ = {isa = PBXBuildFile; fileRef = BA2317BF6FB54E328DEB7055 /* EnumMap.hpp */; }; + 8C801369C7E44292A5348DFB /* ScEntity.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 6DF61461D47C40CF92019B24 /* ScEntity.hpp */; }; + BCCE3EDC711F4F0587F1C359 /* ScCheats.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 3F68EA974AF941BCAD28A04F /* ScCheats.hpp */; }; + F396A397541149D6ACA290D2 /* ScConfiguration.hpp in Headers */ = {isa = PBXBuildFile; fileRef = FD736DB2EE1C4C888977BCAF /* ScConfiguration.hpp */; }; + 2EEDD899BAF94706ACED5F6D /* ScConsole.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E4B39FC3EB9C4EFDA82F42D7 /* ScConsole.hpp */; }; + 74E3377F2FC04316959F1AED /* ScContext.hpp in Headers */ = {isa = PBXBuildFile; fileRef = DAF78631DD8D45E3B3C2FDD1 /* ScContext.hpp */; }; + A10C0EE3C2614B53AFB6ED35 /* ScDisposable.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 8865B46C60FD434CAD50A2F4 /* ScDisposable.hpp */; }; + 05F6EF4AAFEC4BA4A454046B /* ScNetwork.hpp in Headers */ = {isa = PBXBuildFile; fileRef = BDEB01D4A8144819A82E3CB4 /* ScNetwork.hpp */; }; + AC4C9184C93A4113A6BEEC60 /* ScSocket.hpp in Headers */ = {isa = PBXBuildFile; fileRef = D4DD54E62DAE4E4889E26DF6 /* ScSocket.hpp */; }; + A962C2EF5FA6429C92318441 /* ScObject.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 24F9DF02868247738D05CC40 /* ScObject.hpp */; }; + E09450B2440E465CBCE62DEB /* ScRide.hpp in Headers */ = {isa = PBXBuildFile; fileRef = AD97B712FDF7454CADC7A328 /* ScRide.hpp */; }; + A2EC8BBCB8AD49ECB1C22F9D /* ScClimate.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 0C2031084A4E462EB6E5BDE4 /* ScClimate.hpp */; }; + 2AE59B9E2E4D496286970915 /* ScDate.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 613ADB50EF0F4D73A66E4538 /* ScDate.hpp */; }; + 7930E9462549403181C5D164 /* ScMap.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 74CDED6B7EF041458032681A /* ScMap.hpp */; }; + 43D56A4FA1734F25995F4968 /* ScPark.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 9AB8D336AB654D0280549A89 /* ScPark.hpp */; }; + 0AFABA9549854247A5C61D52 /* ScScenario.hpp in Headers */ = {isa = PBXBuildFile; fileRef = A9F55F2291284217BA0E4E51 /* ScScenario.hpp */; }; + F8A3BFA6806D448B86F1FF6A /* ScTile.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 22D7DD798F054A068273739B /* ScTile.hpp */; }; + 73FB2E7C254144D9BAE4925A /* ScVehicle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B734D45D6B1D45E89AD2E6CE /* ScVehicle.cpp */; }; + D274ADAB9B644AC581EA2299 /* ScVehicle.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 8E2C4C07B668487DA3493122 /* ScVehicle.hpp */; }; + BC39D70B9A2249E4B14E99FA /* ScGuest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DB792F5A06849BDAF95B28F /* ScGuest.cpp */; }; + 428B1DADD66C4829894AD0A1 /* ScGuest.hpp in Headers */ = {isa = PBXBuildFile; fileRef = CAFBD63A702F42F2BDB53A39 /* ScGuest.hpp */; }; + D7B575F07C4D4E42887C72AA /* ScPeep.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 2B63F2F751A3427C9CE9B214 /* ScPeep.hpp */; }; + 7A06F880718F49CA9FB71F52 /* ScStaff.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3EFAF58A62B44C4B887559B7 /* ScStaff.cpp */; }; + 9DF65BAE250C4307AE5794DB /* ScStaff.hpp in Headers */ = {isa = PBXBuildFile; fileRef = C30AB6C640464647ABE90EC4 /* ScStaff.hpp */; }; + 8E6484F6C43644F4B644D361 /* ScLitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 36C67B84754D4FEFA3678AA9 /* ScLitter.cpp */; }; + 359328A3A65D49578912CA40 /* ScLitter.hpp in Headers */ = {isa = PBXBuildFile; fileRef = C30388F4F6D34DF59EF7072C /* ScLitter.hpp */; }; + 149D1ACFD5FA42938364C843 /* ScPlayerGroup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DA49170D35604E6A986D09D9 /* ScPlayerGroup.cpp */; }; + 97C222A2A4F543E9AEC3912B /* ScPlayerGroup.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 887EBCE57E4A48C88191346E /* ScPlayerGroup.hpp */; }; + E436DE7807A74621B7BF2276 /* ScPlayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E2A4181A243F4B77BA36ACE2 /* ScPlayer.cpp */; }; + 2D0A43F28D5747C9B617F342 /* ScPlayer.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 7A08C451885D4D419FB4820D /* ScPlayer.hpp */; }; + F08623EA69E7456DB79F3E06 /* ScNetwork.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 200F0E6CAD3B41499A3CFC36 /* ScNetwork.cpp */; }; + CDC72A71A28542F4AD73A91C /* ScRideStation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 522FE124ED4F4E18BCF79042 /* ScRideStation.cpp */; }; + 63858E295E3F451283987982 /* ScRideStation.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 1260386710BF4EA4B4FC31D3 /* ScRideStation.hpp */; }; + 705A4B342C7D4F38B26BAFA4 /* ScRide.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F3B00C9900ED42AFA72764ED /* ScRide.cpp */; }; + 2B8F76B32C944D3C97F0FFAF /* ScMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4BE60702D7549488A32CC0B /* ScMap.cpp */; }; + BE55C1C86BFE4A0DA61260E2 /* ScParkMessage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1939C9C3CFDB4FB6BA5DE47E /* ScParkMessage.cpp */; }; + AD5EC8B5EBF240B3874BC581 /* ScParkMessage.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 56E37ADCDBD440BD8AC35446 /* ScParkMessage.hpp */; }; + 887B0043454440BAB322A9E8 /* ScPark.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E9C4DE37309A4B5F965D7718 /* ScPark.cpp */; }; + 5B6E418A2F264952BA0CC2F2 /* ScTileElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43D18154E96444749737E3F6 /* ScTileElement.cpp */; }; + DEC539DE402F4B8993E4C357 /* ScTileElement.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F4C26E211F1D44C9ADA70740 /* ScTileElement.hpp */; }; + 6C90BE01D190493295071B23 /* ScTile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5B67E36A8620400CA70FBA49 /* ScTile.cpp */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -1462,23 +1490,11 @@ 93DFD02C24521B9F001FCBAF /* FileWatcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileWatcher.h; sourceTree = ""; }; 93DFD02D24521BA0001FCBAF /* FileWatcher.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileWatcher.cpp; sourceTree = ""; }; 93DFD03124521C19001FCBAF /* Plugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Plugin.h; sourceTree = ""; }; - 93DFD03224521C19001FCBAF /* ScObject.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ScObject.hpp; sourceTree = ""; }; 93DFD03324521C19001FCBAF /* HookEngine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HookEngine.h; sourceTree = ""; }; - 93DFD03424521C19001FCBAF /* ScNetwork.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ScNetwork.hpp; sourceTree = ""; }; 93DFD03524521C19001FCBAF /* HookEngine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HookEngine.cpp; sourceTree = ""; }; - 93DFD03624521C19001FCBAF /* ScTile.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ScTile.hpp; sourceTree = ""; }; - 93DFD03724521C19001FCBAF /* ScConfiguration.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ScConfiguration.hpp; sourceTree = ""; }; 93DFD03824521C19001FCBAF /* ScriptEngine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScriptEngine.cpp; sourceTree = ""; }; - 93DFD03924521C19001FCBAF /* ScDisposable.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ScDisposable.hpp; sourceTree = ""; }; - 93DFD03A24521C19001FCBAF /* ScEntity.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ScEntity.hpp; sourceTree = ""; }; 93DFD03B24521C19001FCBAF /* Duktape.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Duktape.hpp; sourceTree = ""; }; - 93DFD03C24521C19001FCBAF /* ScConsole.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ScConsole.hpp; sourceTree = ""; }; - 93DFD03D24521C19001FCBAF /* ScPark.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ScPark.hpp; sourceTree = ""; }; - 93DFD03E24521C19001FCBAF /* ScContext.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ScContext.hpp; sourceTree = ""; }; 93DFD03F24521C19001FCBAF /* Plugin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Plugin.cpp; sourceTree = ""; }; - 93DFD04024521C19001FCBAF /* ScRide.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ScRide.hpp; sourceTree = ""; }; - 93DFD04124521C19001FCBAF /* ScDate.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ScDate.hpp; sourceTree = ""; }; - 93DFD04224521C19001FCBAF /* ScMap.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ScMap.hpp; sourceTree = ""; }; 93DFD04324521C19001FCBAF /* ScriptEngine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptEngine.h; sourceTree = ""; }; 93F60048213DD7DC00EEB83E /* TerrainSurfaceObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TerrainSurfaceObject.h; sourceTree = ""; }; 93F60049213DD7DC00EEB83E /* TerrainSurfaceObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TerrainSurfaceObject.cpp; sourceTree = ""; }; @@ -1838,6 +1854,46 @@ 9D3DD6CD73F5421880280D9D /* Litter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Litter.cpp; path = src/openrct2/world/Litter.cpp; sourceTree = SOURCE_ROOT; }; 6BCCA2EF0F5A40D5B83A83AC /* RideConstruction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RideConstruction.cpp; path = src/openrct2/ride/RideConstruction.cpp; sourceTree = SOURCE_ROOT; }; BA2317BF6FB54E328DEB7055 /* EnumMap.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = EnumMap.hpp; path = src/openrct2/core/EnumMap.hpp; sourceTree = SOURCE_ROOT; }; + 6DF61461D47C40CF92019B24 /* ScEntity.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ScEntity.hpp; path = src/openrct2/scripting/bindings/entity/ScEntity.hpp; sourceTree = SOURCE_ROOT; }; + 3F68EA974AF941BCAD28A04F /* ScCheats.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ScCheats.hpp; path = src/openrct2/scripting/bindings/game/ScCheats.hpp; sourceTree = SOURCE_ROOT; }; + FD736DB2EE1C4C888977BCAF /* ScConfiguration.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ScConfiguration.hpp; path = src/openrct2/scripting/bindings/game/ScConfiguration.hpp; sourceTree = SOURCE_ROOT; }; + E4B39FC3EB9C4EFDA82F42D7 /* ScConsole.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ScConsole.hpp; path = src/openrct2/scripting/bindings/game/ScConsole.hpp; sourceTree = SOURCE_ROOT; }; + DAF78631DD8D45E3B3C2FDD1 /* ScContext.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ScContext.hpp; path = src/openrct2/scripting/bindings/game/ScContext.hpp; sourceTree = SOURCE_ROOT; }; + 8865B46C60FD434CAD50A2F4 /* ScDisposable.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ScDisposable.hpp; path = src/openrct2/scripting/bindings/game/ScDisposable.hpp; sourceTree = SOURCE_ROOT; }; + BDEB01D4A8144819A82E3CB4 /* ScNetwork.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ScNetwork.hpp; path = src/openrct2/scripting/bindings/network/ScNetwork.hpp; sourceTree = SOURCE_ROOT; }; + D4DD54E62DAE4E4889E26DF6 /* ScSocket.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ScSocket.hpp; path = src/openrct2/scripting/bindings/network/ScSocket.hpp; sourceTree = SOURCE_ROOT; }; + 24F9DF02868247738D05CC40 /* ScObject.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ScObject.hpp; path = src/openrct2/scripting/bindings/object/ScObject.hpp; sourceTree = SOURCE_ROOT; }; + AD97B712FDF7454CADC7A328 /* ScRide.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ScRide.hpp; path = src/openrct2/scripting/bindings/ride/ScRide.hpp; sourceTree = SOURCE_ROOT; }; + 0C2031084A4E462EB6E5BDE4 /* ScClimate.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ScClimate.hpp; path = src/openrct2/scripting/bindings/world/ScClimate.hpp; sourceTree = SOURCE_ROOT; }; + 613ADB50EF0F4D73A66E4538 /* ScDate.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ScDate.hpp; path = src/openrct2/scripting/bindings/world/ScDate.hpp; sourceTree = SOURCE_ROOT; }; + 74CDED6B7EF041458032681A /* ScMap.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ScMap.hpp; path = src/openrct2/scripting/bindings/world/ScMap.hpp; sourceTree = SOURCE_ROOT; }; + 9AB8D336AB654D0280549A89 /* ScPark.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ScPark.hpp; path = src/openrct2/scripting/bindings/world/ScPark.hpp; sourceTree = SOURCE_ROOT; }; + A9F55F2291284217BA0E4E51 /* ScScenario.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ScScenario.hpp; path = src/openrct2/scripting/bindings/world/ScScenario.hpp; sourceTree = SOURCE_ROOT; }; + 22D7DD798F054A068273739B /* ScTile.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ScTile.hpp; path = src/openrct2/scripting/bindings/world/ScTile.hpp; sourceTree = SOURCE_ROOT; }; + B734D45D6B1D45E89AD2E6CE /* ScVehicle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ScVehicle.cpp; path = src/openrct2/scripting/bindings/entity/ScVehicle.cpp; sourceTree = SOURCE_ROOT; }; + 8E2C4C07B668487DA3493122 /* ScVehicle.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ScVehicle.hpp; path = src/openrct2/scripting/bindings/entity/ScVehicle.hpp; sourceTree = SOURCE_ROOT; }; + 5DB792F5A06849BDAF95B28F /* ScGuest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ScGuest.cpp; path = src/openrct2/scripting/bindings/entity/ScGuest.cpp; sourceTree = SOURCE_ROOT; }; + CAFBD63A702F42F2BDB53A39 /* ScGuest.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ScGuest.hpp; path = src/openrct2/scripting/bindings/entity/ScGuest.hpp; sourceTree = SOURCE_ROOT; }; + 2B63F2F751A3427C9CE9B214 /* ScPeep.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ScPeep.hpp; path = src/openrct2/scripting/bindings/entity/ScPeep.hpp; sourceTree = SOURCE_ROOT; }; + 3EFAF58A62B44C4B887559B7 /* ScStaff.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ScStaff.cpp; path = src/openrct2/scripting/bindings/entity/ScStaff.cpp; sourceTree = SOURCE_ROOT; }; + C30AB6C640464647ABE90EC4 /* ScStaff.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ScStaff.hpp; path = src/openrct2/scripting/bindings/entity/ScStaff.hpp; sourceTree = SOURCE_ROOT; }; + 36C67B84754D4FEFA3678AA9 /* ScLitter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ScLitter.cpp; path = src/openrct2/scripting/bindings/entity/ScLitter.cpp; sourceTree = SOURCE_ROOT; }; + C30388F4F6D34DF59EF7072C /* ScLitter.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ScLitter.hpp; path = src/openrct2/scripting/bindings/entity/ScLitter.hpp; sourceTree = SOURCE_ROOT; }; + DA49170D35604E6A986D09D9 /* ScPlayerGroup.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ScPlayerGroup.cpp; path = src/openrct2/scripting/bindings/network/ScPlayerGroup.cpp; sourceTree = SOURCE_ROOT; }; + 887EBCE57E4A48C88191346E /* ScPlayerGroup.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ScPlayerGroup.hpp; path = src/openrct2/scripting/bindings/network/ScPlayerGroup.hpp; sourceTree = SOURCE_ROOT; }; + E2A4181A243F4B77BA36ACE2 /* ScPlayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ScPlayer.cpp; path = src/openrct2/scripting/bindings/network/ScPlayer.cpp; sourceTree = SOURCE_ROOT; }; + 7A08C451885D4D419FB4820D /* ScPlayer.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ScPlayer.hpp; path = src/openrct2/scripting/bindings/network/ScPlayer.hpp; sourceTree = SOURCE_ROOT; }; + 200F0E6CAD3B41499A3CFC36 /* ScNetwork.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ScNetwork.cpp; path = src/openrct2/scripting/bindings/network/ScNetwork.cpp; sourceTree = SOURCE_ROOT; }; + 522FE124ED4F4E18BCF79042 /* ScRideStation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ScRideStation.cpp; path = src/openrct2/scripting/bindings/ride/ScRideStation.cpp; sourceTree = SOURCE_ROOT; }; + 1260386710BF4EA4B4FC31D3 /* ScRideStation.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ScRideStation.hpp; path = src/openrct2/scripting/bindings/ride/ScRideStation.hpp; sourceTree = SOURCE_ROOT; }; + F3B00C9900ED42AFA72764ED /* ScRide.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ScRide.cpp; path = src/openrct2/scripting/bindings/ride/ScRide.cpp; sourceTree = SOURCE_ROOT; }; + E4BE60702D7549488A32CC0B /* ScMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ScMap.cpp; path = src/openrct2/scripting/bindings/world/ScMap.cpp; sourceTree = SOURCE_ROOT; }; + 1939C9C3CFDB4FB6BA5DE47E /* ScParkMessage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ScParkMessage.cpp; path = src/openrct2/scripting/bindings/world/ScParkMessage.cpp; sourceTree = SOURCE_ROOT; }; + 56E37ADCDBD440BD8AC35446 /* ScParkMessage.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ScParkMessage.hpp; path = src/openrct2/scripting/bindings/world/ScParkMessage.hpp; sourceTree = SOURCE_ROOT; }; + E9C4DE37309A4B5F965D7718 /* ScPark.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ScPark.cpp; path = src/openrct2/scripting/bindings/world/ScPark.cpp; sourceTree = SOURCE_ROOT; }; + 43D18154E96444749737E3F6 /* ScTileElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ScTileElement.cpp; path = src/openrct2/scripting/bindings/world/ScTileElement.cpp; sourceTree = SOURCE_ROOT; }; + F4C26E211F1D44C9ADA70740 /* ScTileElement.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ScTileElement.hpp; path = src/openrct2/scripting/bindings/world/ScTileElement.hpp; sourceTree = SOURCE_ROOT; }; + 5B67E36A8620400CA70FBA49 /* ScTile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ScTile.cpp; path = src/openrct2/scripting/bindings/world/ScTile.cpp; sourceTree = SOURCE_ROOT; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -1963,25 +2019,26 @@ 93DFD03024521C19001FCBAF /* scripting */ = { isa = PBXGroup; children = ( + 59B0CA75A27A4C5EB9EF6CA7 /* bindings */, 93DFD03B24521C19001FCBAF /* Duktape.hpp */, 93DFD03524521C19001FCBAF /* HookEngine.cpp */, 93DFD03324521C19001FCBAF /* HookEngine.h */, 93DFD03F24521C19001FCBAF /* Plugin.cpp */, 93DFD03124521C19001FCBAF /* Plugin.h */, - 93DFD03724521C19001FCBAF /* ScConfiguration.hpp */, - 93DFD03C24521C19001FCBAF /* ScConsole.hpp */, - 93DFD03E24521C19001FCBAF /* ScContext.hpp */, - 93DFD04124521C19001FCBAF /* ScDate.hpp */, - 93DFD03924521C19001FCBAF /* ScDisposable.hpp */, - 93DFD03A24521C19001FCBAF /* ScEntity.hpp */, - 93DFD04224521C19001FCBAF /* ScMap.hpp */, - 93DFD03424521C19001FCBAF /* ScNetwork.hpp */, - 93DFD03224521C19001FCBAF /* ScObject.hpp */, - 93DFD03D24521C19001FCBAF /* ScPark.hpp */, - 93DFD04024521C19001FCBAF /* ScRide.hpp */, + 93DFD03724521C19001FCBAF, + 93DFD03C24521C19001FCBAF, + 93DFD03E24521C19001FCBAF, + 93DFD04124521C19001FCBAF, + 93DFD03924521C19001FCBAF, + 93DFD03A24521C19001FCBAF, + 93DFD04224521C19001FCBAF, + 93DFD03424521C19001FCBAF, + 93DFD03224521C19001FCBAF, + 93DFD03D24521C19001FCBAF, + 93DFD04024521C19001FCBAF, 93DFD03824521C19001FCBAF /* ScriptEngine.cpp */, 93DFD04324521C19001FCBAF /* ScriptEngine.h */, - 93DFD03624521C19001FCBAF /* ScTile.hpp */, + 93DFD03624521C19001FCBAF, ); path = scripting; sourceTree = ""; @@ -3333,6 +3390,101 @@ path = input; sourceTree = ""; }; + 59B0CA75A27A4C5EB9EF6CA7 /* bindings */ = { + isa = PBXGroup; + children = ( + EDFE9D20A43646C7981E7254 /* entity */, + C1C271EB7D2B4A3AA23CE0E6 /* game */, + 9192A7EACCF44110BF1B89BC /* network */, + CCCD0912DE2D444FA8DA7222 /* object */, + 0B69C59376EB45E58BA6ADF5 /* ride */, + 281760CC5B1249CBA8E771D7 /* world */, + ); + name = bindings; + sourceTree = ""; + }; + EDFE9D20A43646C7981E7254 /* entity */ = { + isa = PBXGroup; + children = ( + 6DF61461D47C40CF92019B24 /* ScEntity.hpp */, + B734D45D6B1D45E89AD2E6CE /* ScVehicle.cpp */, + 8E2C4C07B668487DA3493122 /* ScVehicle.hpp */, + 5DB792F5A06849BDAF95B28F /* ScGuest.cpp */, + CAFBD63A702F42F2BDB53A39 /* ScGuest.hpp */, + 2B63F2F751A3427C9CE9B214 /* ScPeep.hpp */, + 3EFAF58A62B44C4B887559B7 /* ScStaff.cpp */, + C30AB6C640464647ABE90EC4 /* ScStaff.hpp */, + 36C67B84754D4FEFA3678AA9 /* ScLitter.cpp */, + C30388F4F6D34DF59EF7072C /* ScLitter.hpp */, + ); + name = entity; + sourceTree = ""; + }; + C1C271EB7D2B4A3AA23CE0E6 /* game */ = { + isa = PBXGroup; + children = ( + 3F68EA974AF941BCAD28A04F /* ScCheats.hpp */, + FD736DB2EE1C4C888977BCAF /* ScConfiguration.hpp */, + E4B39FC3EB9C4EFDA82F42D7 /* ScConsole.hpp */, + DAF78631DD8D45E3B3C2FDD1 /* ScContext.hpp */, + 8865B46C60FD434CAD50A2F4 /* ScDisposable.hpp */, + ); + name = game; + sourceTree = ""; + }; + 9192A7EACCF44110BF1B89BC /* network */ = { + isa = PBXGroup; + children = ( + BDEB01D4A8144819A82E3CB4 /* ScNetwork.hpp */, + D4DD54E62DAE4E4889E26DF6 /* ScSocket.hpp */, + DA49170D35604E6A986D09D9 /* ScPlayerGroup.cpp */, + 887EBCE57E4A48C88191346E /* ScPlayerGroup.hpp */, + E2A4181A243F4B77BA36ACE2 /* ScPlayer.cpp */, + 7A08C451885D4D419FB4820D /* ScPlayer.hpp */, + 200F0E6CAD3B41499A3CFC36 /* ScNetwork.cpp */, + ); + name = network; + sourceTree = ""; + }; + CCCD0912DE2D444FA8DA7222 /* object */ = { + isa = PBXGroup; + children = ( + 24F9DF02868247738D05CC40 /* ScObject.hpp */, + ); + name = object; + sourceTree = ""; + }; + 0B69C59376EB45E58BA6ADF5 /* ride */ = { + isa = PBXGroup; + children = ( + AD97B712FDF7454CADC7A328 /* ScRide.hpp */, + 522FE124ED4F4E18BCF79042 /* ScRideStation.cpp */, + 1260386710BF4EA4B4FC31D3 /* ScRideStation.hpp */, + F3B00C9900ED42AFA72764ED /* ScRide.cpp */, + ); + name = ride; + sourceTree = ""; + }; + 281760CC5B1249CBA8E771D7 /* world */ = { + isa = PBXGroup; + children = ( + 0C2031084A4E462EB6E5BDE4 /* ScClimate.hpp */, + 613ADB50EF0F4D73A66E4538 /* ScDate.hpp */, + 74CDED6B7EF041458032681A /* ScMap.hpp */, + 9AB8D336AB654D0280549A89 /* ScPark.hpp */, + A9F55F2291284217BA0E4E51 /* ScScenario.hpp */, + 22D7DD798F054A068273739B /* ScTile.hpp */, + E4BE60702D7549488A32CC0B /* ScMap.cpp */, + 1939C9C3CFDB4FB6BA5DE47E /* ScParkMessage.cpp */, + 56E37ADCDBD440BD8AC35446 /* ScParkMessage.hpp */, + E9C4DE37309A4B5F965D7718 /* ScPark.cpp */, + 43D18154E96444749737E3F6 /* ScTileElement.cpp */, + F4C26E211F1D44C9ADA70740 /* ScTileElement.hpp */, + 5B67E36A8620400CA70FBA49 /* ScTile.cpp */, + ); + name = world; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -3357,7 +3509,6 @@ 66A10F8D257F1E1800DD651A /* GuestSetFlagsAction.h in Headers */, 66A10FA7257F1E1800DD651A /* PeepPickupAction.h in Headers */, 939A359C20C12FC800630B3F /* Paint.Sprite.h in Headers */, - 93DFD05524521C1A001FCBAF /* ScMap.hpp in Headers */, 9308DA04209908090079EE96 /* TileElement.h in Headers */, C67B28152002D67A00109C93 /* Widget.h in Headers */, 66A10F99257F1E1800DD651A /* LargeScenerySetColourAction.h in Headers */, @@ -3370,7 +3521,6 @@ C6352B851F477022006CCEE3 /* DataSerialiserTraits.h in Headers */, 66A10F50257F1E1700DD651A /* ParkEntranceRemoveAction.h in Headers */, 66A10F4D257F1E1700DD651A /* StaffSetNameAction.h in Headers */, - 93DFD05124521C1A001FCBAF /* ScContext.hpp in Headers */, 66A10FD6257F1E3000DD651A /* WallRemoveAction.h in Headers */, 939A359F20C12FDE00630B3F /* Paint.Surface.h in Headers */, 66A10F7B257F1E1800DD651A /* MazeSetTrackAction.h in Headers */, @@ -3378,14 +3528,12 @@ 66A10F53257F1E1700DD651A /* LandLowerAction.h in Headers */, 66A10F5E257F1E1700DD651A /* LargeSceneryRemoveAction.h in Headers */, 66A10F5D257F1E1700DD651A /* RideSetStatusAction.h in Headers */, - 93DFD05024521C1A001FCBAF /* ScPark.hpp in Headers */, 93B4DC1625487CDF008D63FF /* Formatting.h in Headers */, 66A10F86257F1E1800DD651A /* LoadOrQuitAction.h in Headers */, 93DFD02E24521BA0001FCBAF /* FileWatcher.h in Headers */, 2ADE2F28224418B2002598AF /* DataSerialiserTag.h in Headers */, 66A10F74257F1E1800DD651A /* RideEntranceExitRemoveAction.h in Headers */, 66A10F9A257F1E1800DD651A /* StaffFireAction.h in Headers */, - 93DFD04C24521C1A001FCBAF /* ScDisposable.hpp in Headers */, 66A10FAC257F1E1800DD651A /* RideSetSettingAction.h in Headers */, 2ADE2F2E224418E7002598AF /* ConversionTables.h in Headers */, 933F2CBB20935668001B33FD /* LocalisationService.h in Headers */, @@ -3399,7 +3547,6 @@ 66A10F77257F1E1800DD651A /* StaffSetOrdersAction.h in Headers */, 2ADE2F2C224418B2002598AF /* FileIndex.hpp in Headers */, 66A10FAF257F1E1800DD651A /* RideSetNameAction.h in Headers */, - 93DFD04A24521C1A001FCBAF /* ScConfiguration.hpp in Headers */, 93CBA4CC20A7504500867D56 /* ImageImporter.h in Headers */, 66A10F62257F1E1700DD651A /* SurfaceSetStyleAction.h in Headers */, 66A10EC1257F1DF800DD651A /* FootpathAdditionRemoveAction.h in Headers */, @@ -3408,11 +3555,9 @@ 66A10F96257F1E1800DD651A /* SignSetStyleAction.h in Headers */, 2ADE2F29224418B2002598AF /* Numerics.hpp in Headers */, 66A10FD5257F1E3000DD651A /* WaterRaiseAction.h in Headers */, - 93DFD04924521C1A001FCBAF /* ScTile.hpp in Headers */, 936F412B24CE030F00E07BCF /* NetworkBase.h in Headers */, 66A10EC2257F1DF800DD651A /* FootpathRemoveAction.h in Headers */, 66A10EA3257F1DE100DD651A /* BalloonPressAction.h in Headers */, - 93DFD04524521C1A001FCBAF /* ScObject.hpp in Headers */, 2ADE2F382244198B002598AF /* SpriteBase.h in Headers */, 66A10EC8257F1DF800DD651A /* BannerPlaceAction.h in Headers */, C62D838B1FD36D6F008C04F1 /* EditorObjectSelectionSession.h in Headers */, @@ -3422,17 +3567,13 @@ 66A10FD7257F1E3000DD651A /* WaterLowerAction.h in Headers */, 939A35A220C12FFD00630B3F /* InteractiveConsole.h in Headers */, 93CBA4C320A7502E00867D56 /* Imaging.h in Headers */, - 93DFD04D24521C1A001FCBAF /* ScEntity.hpp in Headers */, 66A10F4E257F1E1700DD651A /* PauseToggleAction.h in Headers */, 93DFD04E24521C1A001FCBAF /* Duktape.hpp in Headers */, 66A10FA2257F1E1800DD651A /* LargeSceneryPlaceAction.h in Headers */, 2ADE2F3622441960002598AF /* RideTypes.h in Headers */, 66A10F68257F1E1800DD651A /* NetworkModifyGroupAction.h in Headers */, - 93DFD05324521C1A001FCBAF /* ScRide.hpp in Headers */, 66A10F88257F1E1800DD651A /* SignSetNameAction.h in Headers */, 93AE2389252F948A00CD03C3 /* Formatter.h in Headers */, - 93DFD05424521C1A001FCBAF /* ScDate.hpp in Headers */, - 93DFD04F24521C1A001FCBAF /* ScConsole.hpp in Headers */, 66A10F91257F1E1800DD651A /* StaffHireNewAction.h in Headers */, 9308DA05209908090079EE96 /* Surface.h in Headers */, 66A10F9F257F1E1800DD651A /* LandBuyRightsAction.h in Headers */, @@ -3455,7 +3596,6 @@ 66A10F84257F1E1800DD651A /* StaffSetPatrolAreaAction.h in Headers */, 66A10F56257F1E1700DD651A /* SmallSceneryRemoveAction.h in Headers */, 66A10F5C257F1E1700DD651A /* SetParkEntranceFeeAction.h in Headers */, - 93DFD04724521C1A001FCBAF /* ScNetwork.hpp in Headers */, 66A10F8F257F1E1800DD651A /* StaffSetCostumeAction.h in Headers */, 66A10ED5257F1DF800DD651A /* BannerSetStyleAction.h in Headers */, 66A10F97257F1E1800DD651A /* SetCheatAction.h in Headers */, @@ -3472,6 +3612,32 @@ 66A10F8B257F1E1800DD651A /* LandSmoothAction.h in Headers */, F42186C5840D4196981ADD16 /* EntityTweener.h in Headers */, 317B766A750D4365B22A1682 /* EnumMap.hpp in Headers */, + 8C801369C7E44292A5348DFB /* ScEntity.hpp in Headers */, + BCCE3EDC711F4F0587F1C359 /* ScCheats.hpp in Headers */, + F396A397541149D6ACA290D2 /* ScConfiguration.hpp in Headers */, + 2EEDD899BAF94706ACED5F6D /* ScConsole.hpp in Headers */, + 74E3377F2FC04316959F1AED /* ScContext.hpp in Headers */, + A10C0EE3C2614B53AFB6ED35 /* ScDisposable.hpp in Headers */, + 05F6EF4AAFEC4BA4A454046B /* ScNetwork.hpp in Headers */, + AC4C9184C93A4113A6BEEC60 /* ScSocket.hpp in Headers */, + A962C2EF5FA6429C92318441 /* ScObject.hpp in Headers */, + E09450B2440E465CBCE62DEB /* ScRide.hpp in Headers */, + A2EC8BBCB8AD49ECB1C22F9D /* ScClimate.hpp in Headers */, + 2AE59B9E2E4D496286970915 /* ScDate.hpp in Headers */, + 7930E9462549403181C5D164 /* ScMap.hpp in Headers */, + 43D56A4FA1734F25995F4968 /* ScPark.hpp in Headers */, + 0AFABA9549854247A5C61D52 /* ScScenario.hpp in Headers */, + F8A3BFA6806D448B86F1FF6A /* ScTile.hpp in Headers */, + D274ADAB9B644AC581EA2299 /* ScVehicle.hpp in Headers */, + 428B1DADD66C4829894AD0A1 /* ScGuest.hpp in Headers */, + D7B575F07C4D4E42887C72AA /* ScPeep.hpp in Headers */, + 9DF65BAE250C4307AE5794DB /* ScStaff.hpp in Headers */, + 359328A3A65D49578912CA40 /* ScLitter.hpp in Headers */, + 97C222A2A4F543E9AEC3912B /* ScPlayerGroup.hpp in Headers */, + 2D0A43F28D5747C9B617F342 /* ScPlayer.hpp in Headers */, + 63858E295E3F451283987982 /* ScRideStation.hpp in Headers */, + AD5EC8B5EBF240B3874BC581 /* ScParkMessage.hpp in Headers */, + DEC539DE402F4B8993E4C357 /* ScTileElement.hpp in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -4277,6 +4443,20 @@ E73A781EBC3C440A99D59821 /* EntityTweener.cpp in Sources */, 0746674FA0794ABF86E406A1 /* Litter.cpp in Sources */, B9B6F97CE24E4A559C7BBA0A /* RideConstruction.cpp in Sources */, + 73FB2E7C254144D9BAE4925A /* ScVehicle.cpp in Sources */, + BC39D70B9A2249E4B14E99FA /* ScGuest.cpp in Sources */, + 7A06F880718F49CA9FB71F52 /* ScStaff.cpp in Sources */, + 8E6484F6C43644F4B644D361 /* ScLitter.cpp in Sources */, + 149D1ACFD5FA42938364C843 /* ScPlayerGroup.cpp in Sources */, + E436DE7807A74621B7BF2276 /* ScPlayer.cpp in Sources */, + F08623EA69E7456DB79F3E06 /* ScNetwork.cpp in Sources */, + CDC72A71A28542F4AD73A91C /* ScRideStation.cpp in Sources */, + 705A4B342C7D4F38B26BAFA4 /* ScRide.cpp in Sources */, + 2B8F76B32C944D3C97F0FFAF /* ScMap.cpp in Sources */, + BE55C1C86BFE4A0DA61260E2 /* ScParkMessage.cpp in Sources */, + 887B0043454440BAB322A9E8 /* ScPark.cpp in Sources */, + 5B6E418A2F264952BA0CC2F2 /* ScTileElement.cpp in Sources */, + 6C90BE01D190493295071B23 /* ScTile.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/src/openrct2/libopenrct2.vcxproj b/src/openrct2/libopenrct2.vcxproj index 8a82280aee..7029514897 100644 --- a/src/openrct2/libopenrct2.vcxproj +++ b/src/openrct2/libopenrct2.vcxproj @@ -405,26 +405,36 @@ + + + + + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + - - - + + + @@ -849,6 +859,20 @@ + + + + + + + + + + + + + + diff --git a/src/openrct2/scripting/ScEntity.hpp b/src/openrct2/scripting/ScEntity.hpp deleted file mode 100644 index a94b74f883..0000000000 --- a/src/openrct2/scripting/ScEntity.hpp +++ /dev/null @@ -1,1345 +0,0 @@ -/***************************************************************************** - * Copyright (c) 2014-2020 OpenRCT2 developers - * - * For a complete list of all authors, please refer to contributors.md - * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 - * - * OpenRCT2 is licensed under the GNU General Public License version 3. - *****************************************************************************/ - -#pragma once - -#ifdef ENABLE_SCRIPTING - -# include "../Context.h" -# include "../common.h" -# include "../peep/Peep.h" -# include "../peep/Staff.h" -# include "../util/Util.h" -# include "../world/EntityList.h" -# include "../world/Litter.h" -# include "../world/Sprite.h" -# include "Duktape.hpp" -# include "ScRide.hpp" -# include "ScriptEngine.h" - -# include -# include -# include - -namespace OpenRCT2::Scripting -{ - class ScEntity - { - protected: - uint16_t _id = SPRITE_INDEX_NULL; - - public: - ScEntity(uint16_t id) - : _id(id) - { - } - - private: - int32_t id_get() const - { - auto entity = GetEntity(); - return entity != nullptr ? entity->sprite_index : 0; - } - - std::string type_get() const - { - const auto targetApiVersion = GetTargetAPIVersion(); - - auto entity = GetEntity(); - if (entity != nullptr) - { - switch (entity->Type) - { - case EntityType::Vehicle: - return "car"; - case EntityType::Guest: - if (targetApiVersion <= API_VERSION_33_PEEP_DEPRECATION) - return "peep"; - else - return "guest"; - case EntityType::Staff: - if (targetApiVersion <= API_VERSION_33_PEEP_DEPRECATION) - return "peep"; - else - return "staff"; - case EntityType::SteamParticle: - return "steam_particle"; - case EntityType::MoneyEffect: - return "money_effect"; - case EntityType::CrashedVehicleParticle: - return "crashed_vehicle_particle"; - case EntityType::ExplosionCloud: - return "explosion_cloud"; - case EntityType::CrashSplash: - return "crash_splash"; - case EntityType::ExplosionFlare: - return "explosion_flare"; - case EntityType::Balloon: - return "balloon"; - case EntityType::Duck: - return "duck"; - case EntityType::JumpingFountain: - return "jumping_fountain"; - case EntityType::Litter: - return "litter"; - case EntityType::Null: - return "unknown"; - default: - break; - } - } - return "unknown"; - } - - // x getter and setter - int32_t x_get() const - { - auto entity = GetEntity(); - return entity != nullptr ? entity->x : 0; - } - void x_set(int32_t value) - { - ThrowIfGameStateNotMutable(); - auto entity = GetEntity(); - if (entity != nullptr) - { - entity->MoveTo({ value, entity->y, entity->z }); - } - } - - // y getter and setter - int32_t y_get() const - { - auto entity = GetEntity(); - return entity != nullptr ? entity->y : 0; - } - void y_set(int32_t value) - { - ThrowIfGameStateNotMutable(); - auto entity = GetEntity(); - if (entity != nullptr) - { - entity->MoveTo({ entity->x, value, entity->z }); - } - } - - // z getter and setter - int16_t z_get() const - { - auto entity = GetEntity(); - return entity != nullptr ? entity->z : 0; - } - void z_set(int16_t value) - { - ThrowIfGameStateNotMutable(); - auto entity = GetEntity(); - if (entity != nullptr) - { - entity->MoveTo({ entity->x, entity->y, value }); - } - } - - void remove() - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto entity = GetEntity(); - if (entity != nullptr) - { - entity->Invalidate(); - switch (entity->Type) - { - case EntityType::Vehicle: - duk_error(ctx, DUK_ERR_ERROR, "Removing a vehicle is currently unsupported."); - break; - case EntityType::Guest: - case EntityType::Staff: - { - auto peep = entity->As(); - // We can't remove a single peep from a ride at the moment as this can cause complications with the - // vehicle car having an unsupported peep capacity. - if (peep == nullptr || peep->State == PeepState::OnRide || peep->State == PeepState::EnteringRide) - { - duk_error(ctx, DUK_ERR_ERROR, "Removing a peep that is on a ride is currently unsupported."); - } - else - { - peep->Remove(); - } - break; - } - case EntityType::SteamParticle: - case EntityType::MoneyEffect: - case EntityType::CrashedVehicleParticle: - case EntityType::ExplosionCloud: - case EntityType::CrashSplash: - case EntityType::ExplosionFlare: - case EntityType::JumpingFountain: - case EntityType::Balloon: - case EntityType::Duck: - case EntityType::Litter: - sprite_remove(entity); - break; - case EntityType::Null: - break; - default: - break; - } - } - } - - SpriteBase* GetEntity() const - { - return ::GetEntity(_id); - } - - public: - static void Register(duk_context* ctx) - { - dukglue_register_property(ctx, &ScEntity::id_get, nullptr, "id"); - dukglue_register_property(ctx, &ScEntity::type_get, nullptr, "type"); - dukglue_register_property(ctx, &ScEntity::x_get, &ScEntity::x_set, "x"); - dukglue_register_property(ctx, &ScEntity::y_get, &ScEntity::y_set, "y"); - dukglue_register_property(ctx, &ScEntity::z_get, &ScEntity::z_set, "z"); - dukglue_register_method(ctx, &ScEntity::remove, "remove"); - } - }; - - static const DukEnumMap VehicleStatusMap({ - { "moving_to_end_of_station", Vehicle::Status::MovingToEndOfStation }, - { "waiting_for_passengers", Vehicle::Status::WaitingForPassengers }, - { "waiting_to_depart", Vehicle::Status::WaitingToDepart }, - { "departing", Vehicle::Status::Departing }, - { "travelling", Vehicle::Status::Travelling }, - { "arriving", Vehicle::Status::Arriving }, - { "unloading_passengers", Vehicle::Status::UnloadingPassengers }, - { "travelling_boat", Vehicle::Status::TravellingBoat }, - { "crashing", Vehicle::Status::Crashing }, - { "crashed", Vehicle::Status::Crashed }, - { "travelling_dodgems", Vehicle::Status::TravellingDodgems }, - { "swinging", Vehicle::Status::Swinging }, - { "rotating", Vehicle::Status::Rotating }, - { "ferris_wheel_rotating", Vehicle::Status::FerrisWheelRotating }, - { "simulator_operating", Vehicle::Status::SimulatorOperating }, - { "showing_film", Vehicle::Status::ShowingFilm }, - { "space_rings_operating", Vehicle::Status::SpaceRingsOperating }, - { "top_spin_operating", Vehicle::Status::TopSpinOperating }, - { "haunted_house_operating", Vehicle::Status::HauntedHouseOperating }, - { "doing_circus_show", Vehicle::Status::DoingCircusShow }, - { "crooked_house_operating", Vehicle::Status::CrookedHouseOperating }, - { "waiting_for_cable_lift", Vehicle::Status::WaitingForCableLift }, - { "travelling_cable_lift", Vehicle::Status::TravellingCableLift }, - { "stopping", Vehicle::Status::Stopping }, - { "waiting_for_passengers_17", Vehicle::Status::WaitingForPassengers17 }, - { "waiting_to_start", Vehicle::Status::WaitingToStart }, - { "starting", Vehicle::Status::Starting }, - { "operating_1a", Vehicle::Status::Operating1A }, - { "stopping_1b", Vehicle::Status::Stopping1B }, - { "unloading_passengers_1c", Vehicle::Status::UnloadingPassengers1C }, - { "stopped_by_block_brake", Vehicle::Status::StoppedByBlockBrakes }, - }); - - class ScVehicle : public ScEntity - { - public: - ScVehicle(uint16_t id) - : ScEntity(id) - { - } - - static void Register(duk_context* ctx) - { - dukglue_set_base_class(ctx); - dukglue_register_property(ctx, &ScVehicle::ride_get, &ScVehicle::ride_set, "ride"); - dukglue_register_property(ctx, &ScVehicle::rideObject_get, &ScVehicle::rideObject_set, "rideObject"); - dukglue_register_property(ctx, &ScVehicle::vehicleObject_get, &ScVehicle::vehicleObject_set, "vehicleObject"); - dukglue_register_property(ctx, &ScVehicle::spriteType_get, &ScVehicle::spriteType_set, "spriteType"); - dukglue_register_property(ctx, &ScVehicle::numSeats_get, &ScVehicle::numSeats_set, "numSeats"); - dukglue_register_property(ctx, &ScVehicle::nextCarOnTrain_get, &ScVehicle::nextCarOnTrain_set, "nextCarOnTrain"); - dukglue_register_property( - ctx, &ScVehicle::previousCarOnRide_get, &ScVehicle::previousCarOnRide_set, "previousCarOnRide"); - dukglue_register_property(ctx, &ScVehicle::nextCarOnRide_get, &ScVehicle::nextCarOnRide_set, "nextCarOnRide"); - dukglue_register_property(ctx, &ScVehicle::currentStation_get, &ScVehicle::currentStation_set, "currentStation"); - dukglue_register_property(ctx, &ScVehicle::mass_get, &ScVehicle::mass_set, "mass"); - dukglue_register_property(ctx, &ScVehicle::acceleration_get, &ScVehicle::acceleration_set, "acceleration"); - dukglue_register_property(ctx, &ScVehicle::velocity_get, &ScVehicle::velocity_set, "velocity"); - dukglue_register_property(ctx, &ScVehicle::bankRotation_get, &ScVehicle::bankRotation_set, "bankRotation"); - dukglue_register_property(ctx, &ScVehicle::colours_get, &ScVehicle::colours_set, "colours"); - dukglue_register_property(ctx, &ScVehicle::trackLocation_get, &ScVehicle::trackLocation_set, "trackLocation"); - dukglue_register_property(ctx, &ScVehicle::trackProgress_get, nullptr, "trackProgress"); - dukglue_register_property(ctx, &ScVehicle::remainingDistance_get, nullptr, "remainingDistance"); - dukglue_register_property( - ctx, &ScVehicle::poweredAcceleration_get, &ScVehicle::poweredAcceleration_set, "poweredAcceleration"); - dukglue_register_property(ctx, &ScVehicle::poweredMaxSpeed_get, &ScVehicle::poweredMaxSpeed_set, "poweredMaxSpeed"); - dukglue_register_property(ctx, &ScVehicle::status_get, &ScVehicle::status_set, "status"); - dukglue_register_property(ctx, &ScVehicle::guests_get, nullptr, "peeps"); - dukglue_register_property(ctx, &ScVehicle::guests_get, nullptr, "guests"); - dukglue_register_property(ctx, &ScVehicle::gForces_get, nullptr, "gForces"); - dukglue_register_method(ctx, &ScVehicle::travelBy, "travelBy"); - } - - private: - Vehicle* GetVehicle() const - { - return ::GetEntity(_id); - } - - uint8_t rideObject_get() const - { - auto vehicle = GetVehicle(); - return vehicle != nullptr ? vehicle->ride_subtype : 0; - } - void rideObject_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto vehicle = GetVehicle(); - if (vehicle != nullptr) - { - vehicle->ride_subtype = value; - } - } - - uint8_t vehicleObject_get() const - { - auto vehicle = GetVehicle(); - return vehicle != nullptr ? vehicle->vehicle_type : 0; - } - void vehicleObject_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto vehicle = GetVehicle(); - if (vehicle != nullptr) - { - vehicle->vehicle_type = value; - } - } - - uint8_t spriteType_get() const - { - auto vehicle = GetVehicle(); - return vehicle != nullptr ? vehicle->Pitch : 0; - } - void spriteType_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto vehicle = GetVehicle(); - if (vehicle != nullptr) - { - vehicle->Pitch = value; - } - } - - ride_id_t ride_get() const - { - auto vehicle = GetVehicle(); - return vehicle != nullptr ? vehicle->ride : 0; - } - void ride_set(ride_id_t value) - { - ThrowIfGameStateNotMutable(); - auto vehicle = GetVehicle(); - if (vehicle != nullptr) - { - vehicle->ride = value; - } - } - - uint8_t numSeats_get() const - { - auto vehicle = GetVehicle(); - return vehicle != nullptr ? vehicle->num_seats & VEHICLE_SEAT_NUM_MASK : 0; - } - void numSeats_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto vehicle = GetVehicle(); - if (vehicle != nullptr) - { - vehicle->num_seats &= ~VEHICLE_SEAT_NUM_MASK; - vehicle->num_seats |= value & VEHICLE_SEAT_NUM_MASK; - } - } - - DukValue nextCarOnTrain_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto vehicle = GetVehicle(); - if (vehicle != nullptr) - { - if (vehicle->next_vehicle_on_train != SPRITE_INDEX_NULL) - { - return ToDuk(ctx, vehicle->next_vehicle_on_train); - } - } - return ToDuk(ctx, nullptr); - } - void nextCarOnTrain_set(DukValue value) - { - ThrowIfGameStateNotMutable(); - auto vehicle = GetVehicle(); - if (vehicle != nullptr) - { - if (value.type() == DukValue::Type::NUMBER) - { - vehicle->next_vehicle_on_train = static_cast(value.as_int()); - } - else - { - vehicle->next_vehicle_on_train = SPRITE_INDEX_NULL; - } - } - } - - uint16_t previousCarOnRide_get() const - { - auto vehicle = GetVehicle(); - return vehicle != nullptr ? vehicle->prev_vehicle_on_ride : 0; - } - void previousCarOnRide_set(uint16_t value) - { - ThrowIfGameStateNotMutable(); - auto vehicle = GetVehicle(); - if (vehicle != nullptr) - { - vehicle->prev_vehicle_on_ride = value; - } - } - - uint16_t nextCarOnRide_get() const - { - auto vehicle = GetVehicle(); - return vehicle != nullptr ? vehicle->next_vehicle_on_ride : 0; - } - void nextCarOnRide_set(uint16_t value) - { - ThrowIfGameStateNotMutable(); - auto vehicle = GetVehicle(); - if (vehicle != nullptr) - { - vehicle->next_vehicle_on_ride = value; - } - } - - StationIndex currentStation_get() const - { - auto vehicle = GetVehicle(); - return vehicle != nullptr ? vehicle->current_station : 0; - } - void currentStation_set(StationIndex value) - { - ThrowIfGameStateNotMutable(); - auto vehicle = GetVehicle(); - if (vehicle != nullptr) - { - vehicle->current_station = value; - } - } - - uint16_t mass_get() const - { - auto vehicle = GetVehicle(); - return vehicle != nullptr ? vehicle->mass : 0; - } - void mass_set(uint16_t value) - { - ThrowIfGameStateNotMutable(); - auto vehicle = GetVehicle(); - if (vehicle != nullptr) - { - vehicle->mass = value; - } - } - - int32_t acceleration_get() const - { - auto vehicle = GetVehicle(); - return vehicle != nullptr ? vehicle->acceleration : 0; - } - void acceleration_set(int32_t value) - { - ThrowIfGameStateNotMutable(); - auto vehicle = GetVehicle(); - if (vehicle != nullptr) - { - vehicle->acceleration = value; - } - } - - int32_t velocity_get() const - { - auto vehicle = GetVehicle(); - return vehicle != nullptr ? vehicle->velocity : 0; - } - void velocity_set(int32_t value) - { - ThrowIfGameStateNotMutable(); - auto vehicle = GetVehicle(); - if (vehicle != nullptr) - { - vehicle->velocity = value; - } - } - - uint8_t bankRotation_get() const - { - auto vehicle = GetVehicle(); - return vehicle != nullptr ? vehicle->bank_rotation : 0; - } - void bankRotation_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto vehicle = GetVehicle(); - if (vehicle != nullptr) - { - vehicle->bank_rotation = value; - } - } - - DukValue colours_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto vehicle = GetVehicle(); - if (vehicle != nullptr) - { - VehicleColour colours; - colours.Body = vehicle->colours.body_colour; - colours.Trim = vehicle->colours.trim_colour; - colours.Ternary = vehicle->colours_extended; - return ToDuk(ctx, colours); - } - return ToDuk(ctx, nullptr); - } - void colours_set(const DukValue& value) - { - ThrowIfGameStateNotMutable(); - auto vehicle = GetVehicle(); - if (vehicle != nullptr) - { - auto colours = FromDuk(value); - vehicle->colours.body_colour = colours.Body; - vehicle->colours.trim_colour = colours.Trim; - vehicle->colours_extended = colours.Ternary; - } - } - - DukValue trackLocation_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto vehicle = GetVehicle(); - if (vehicle != nullptr) - { - auto coords = CoordsXYZD(vehicle->TrackLocation, vehicle->GetTrackDirection()); - return ToDuk(ctx, coords); - } - return ToDuk(ctx, nullptr); - } - void trackLocation_set(const DukValue& value) - { - ThrowIfGameStateNotMutable(); - auto vehicle = GetVehicle(); - if (vehicle != nullptr) - { - auto coords = FromDuk(value); - vehicle->TrackLocation = CoordsXYZ(coords.x, coords.y, coords.z); - vehicle->SetTrackDirection(coords.direction); - } - } - - uint16_t trackProgress_get() const - { - auto vehicle = GetVehicle(); - return vehicle != nullptr ? vehicle->track_progress : 0; - } - - int32_t remainingDistance_get() const - { - auto vehicle = GetVehicle(); - return vehicle != nullptr ? vehicle->remaining_distance : 0; - } - - uint8_t poweredAcceleration_get() const - { - auto vehicle = GetVehicle(); - return vehicle != nullptr ? vehicle->powered_acceleration : 0; - } - void poweredAcceleration_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto vehicle = GetVehicle(); - if (vehicle != nullptr) - { - vehicle->powered_acceleration = value; - } - } - - uint8_t poweredMaxSpeed_get() const - { - auto vehicle = GetVehicle(); - return vehicle != nullptr ? vehicle->speed : 0; - } - void poweredMaxSpeed_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto vehicle = GetVehicle(); - if (vehicle != nullptr) - { - vehicle->speed = value; - } - } - - std::string status_get() const - { - auto vehicle = GetVehicle(); - if (vehicle != nullptr) - { - return std::string(VehicleStatusMap[vehicle->status]); - } - return {}; - } - void status_set(const std::string& value) - { - ThrowIfGameStateNotMutable(); - auto vehicle = GetVehicle(); - if (vehicle != nullptr) - { - vehicle->status = VehicleStatusMap[value]; - } - } - - std::vector guests_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - std::vector result; - auto vehicle = GetVehicle(); - if (vehicle != nullptr) - { - size_t len = 0; - for (size_t i = 0; i < std::size(vehicle->peep); i++) - { - auto peep = vehicle->peep[i]; - if (peep == SPRITE_INDEX_NULL) - { - result.push_back(ToDuk(ctx, nullptr)); - } - else - { - result.push_back(ToDuk(ctx, peep)); - len = i + 1; - } - } - result.resize(len); - } - return result; - } - - DukValue gForces_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto vehicle = GetVehicle(); - if (vehicle != nullptr) - { - GForces gForces = vehicle->GetGForces(); - return ToDuk(ctx, gForces); - } - return ToDuk(ctx, nullptr); - } - - void travelBy(int32_t value) - { - ThrowIfGameStateNotMutable(); - auto vehicle = GetVehicle(); - if (vehicle != nullptr) - { - vehicle->MoveRelativeDistance(value); - } - } - }; - - static const DukEnumMap PeepFlagMap({ - { "leavingPark", PEEP_FLAGS_LEAVING_PARK }, - { "slowWalk", PEEP_FLAGS_SLOW_WALK }, - { "tracking", PEEP_FLAGS_TRACKING }, - { "waving", PEEP_FLAGS_WAVING }, - { "hasPaidForParkEntry", PEEP_FLAGS_HAS_PAID_FOR_PARK_ENTRY }, - { "photo", PEEP_FLAGS_PHOTO }, - { "painting", PEEP_FLAGS_PAINTING }, - { "wow", PEEP_FLAGS_WOW }, - { "litter", PEEP_FLAGS_LITTER }, - { "lost", PEEP_FLAGS_LOST }, - { "hunger", PEEP_FLAGS_HUNGER }, - { "toilet", PEEP_FLAGS_TOILET }, - { "crowded", PEEP_FLAGS_CROWDED }, - { "happiness", PEEP_FLAGS_HAPPINESS }, - { "nausea", PEEP_FLAGS_NAUSEA }, - { "purple", PEEP_FLAGS_PURPLE }, - { "pizza", PEEP_FLAGS_PIZZA }, - { "explode", PEEP_FLAGS_EXPLODE }, - { "rideShouldBeMarkedAsFavourite", PEEP_FLAGS_RIDE_SHOULD_BE_MARKED_AS_FAVOURITE }, - { "parkEntranceChosen", PEEP_FLAGS_PARK_ENTRANCE_CHOSEN }, - { "contagious", PEEP_FLAGS_CONTAGIOUS }, - { "joy", PEEP_FLAGS_JOY }, - { "angry", PEEP_FLAGS_ANGRY }, - { "iceCream", PEEP_FLAGS_ICE_CREAM }, - { "hereWeAre", PEEP_FLAGS_HERE_WE_ARE }, - }); - - class ScPeep : public ScEntity - { - public: - ScPeep(uint16_t id) - : ScEntity(id) - { - } - - static void Register(duk_context* ctx) - { - dukglue_set_base_class(ctx); - dukglue_register_property(ctx, &ScPeep::peepType_get, nullptr, "peepType"); - dukglue_register_property(ctx, &ScPeep::name_get, &ScPeep::name_set, "name"); - dukglue_register_property(ctx, &ScPeep::destination_get, &ScPeep::destination_set, "destination"); - dukglue_register_property(ctx, &ScPeep::energy_get, &ScPeep::energy_set, "energy"); - dukglue_register_property(ctx, &ScPeep::energyTarget_get, &ScPeep::energyTarget_set, "energyTarget"); - dukglue_register_method(ctx, &ScPeep::getFlag, "getFlag"); - dukglue_register_method(ctx, &ScPeep::setFlag, "setFlag"); - } - - private: - std::string peepType_get() const - { - auto peep = GetPeep(); - if (peep != nullptr) - { - return peep->Is() ? "staff" : "guest"; - } - return ""; - } - - std::string name_get() const - { - auto peep = GetPeep(); - return peep != nullptr ? peep->GetName() : std::string(); - } - void name_set(const std::string& value) - { - ThrowIfGameStateNotMutable(); - auto peep = GetPeep(); - if (peep != nullptr) - { - peep->SetName(value); - } - } - - bool getFlag(const std::string& key) const - { - auto peep = GetPeep(); - if (peep != nullptr) - { - auto mask = PeepFlagMap[key]; - return (peep->PeepFlags & mask) != 0; - } - return false; - } - - void setFlag(const std::string& key, bool value) - { - ThrowIfGameStateNotMutable(); - auto peep = GetPeep(); - if (peep != nullptr) - { - auto mask = PeepFlagMap[key]; - if (value) - peep->PeepFlags |= mask; - else - peep->PeepFlags &= ~mask; - peep->Invalidate(); - } - } - - DukValue destination_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto peep = GetPeep(); - if (peep != nullptr) - { - return ToDuk(ctx, peep->GetDestination()); - } - return ToDuk(ctx, nullptr); - } - - void destination_set(const DukValue& value) - { - ThrowIfGameStateNotMutable(); - auto peep = GetPeep(); - if (peep != nullptr) - { - auto pos = FromDuk(value); - peep->SetDestination(pos); - peep->Invalidate(); - } - } - - uint8_t energy_get() const - { - auto peep = GetPeep(); - return peep != nullptr ? peep->Energy : 0; - } - void energy_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto peep = GetPeep(); - if (peep != nullptr) - { - peep->Energy = value; - } - } - - uint8_t energyTarget_get() const - { - auto peep = GetPeep(); - return peep != nullptr ? peep->EnergyTarget : 0; - } - void energyTarget_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto peep = GetPeep(); - if (peep != nullptr) - { - peep->EnergyTarget = value; - } - } - - protected: - Peep* GetPeep() const - { - return ::GetEntity(_id); - } - }; - - class ScGuest : public ScPeep - { - public: - ScGuest(uint16_t id) - : ScPeep(id) - { - } - - static void Register(duk_context* ctx) - { - dukglue_set_base_class(ctx); - dukglue_register_property(ctx, &ScGuest::tshirtColour_get, &ScGuest::tshirtColour_set, "tshirtColour"); - dukglue_register_property(ctx, &ScGuest::trousersColour_get, &ScGuest::trousersColour_set, "trousersColour"); - dukglue_register_property(ctx, &ScGuest::balloonColour_get, &ScGuest::balloonColour_set, "balloonColour"); - dukglue_register_property(ctx, &ScGuest::hatColour_get, &ScGuest::hatColour_set, "hatColour"); - dukglue_register_property(ctx, &ScGuest::umbrellaColour_get, &ScGuest::umbrellaColour_set, "umbrellaColour"); - dukglue_register_property(ctx, &ScGuest::happiness_get, &ScGuest::happiness_set, "happiness"); - dukglue_register_property(ctx, &ScGuest::happinessTarget_get, &ScGuest::happinessTarget_set, "happinessTarget"); - dukglue_register_property(ctx, &ScGuest::nausea_get, &ScGuest::nausea_set, "nausea"); - dukglue_register_property(ctx, &ScGuest::nauseaTarget_get, &ScGuest::nauseaTarget_set, "nauseaTarget"); - dukglue_register_property(ctx, &ScGuest::hunger_get, &ScGuest::hunger_set, "hunger"); - dukglue_register_property(ctx, &ScGuest::thirst_get, &ScGuest::thirst_set, "thirst"); - dukglue_register_property(ctx, &ScGuest::toilet_get, &ScGuest::toilet_set, "toilet"); - dukglue_register_property(ctx, &ScGuest::mass_get, &ScGuest::mass_set, "mass"); - dukglue_register_property(ctx, &ScGuest::minIntensity_get, &ScGuest::minIntensity_set, "minIntensity"); - dukglue_register_property(ctx, &ScGuest::maxIntensity_get, &ScGuest::maxIntensity_set, "maxIntensity"); - dukglue_register_property(ctx, &ScGuest::nauseaTolerance_get, &ScGuest::nauseaTolerance_set, "nauseaTolerance"); - dukglue_register_property(ctx, &ScGuest::cash_get, &ScGuest::cash_set, "cash"); - dukglue_register_property(ctx, &ScGuest::isInPark_get, nullptr, "isInPark"); - dukglue_register_property(ctx, &ScGuest::isLost_get, nullptr, "isLost"); - dukglue_register_property(ctx, &ScGuest::lostCountdown_get, &ScGuest::lostCountdown_set, "lostCountdown"); - } - - private: - Guest* GetGuest() const - { - return ::GetEntity(_id); - } - - uint8_t tshirtColour_get() const - { - auto peep = GetGuest(); - return peep != nullptr ? peep->TshirtColour : 0; - } - void tshirtColour_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto peep = GetGuest(); - if (peep != nullptr) - { - peep->TshirtColour = value; - peep->Invalidate(); - } - } - - uint8_t trousersColour_get() const - { - auto peep = GetGuest(); - return peep != nullptr ? peep->TrousersColour : 0; - } - void trousersColour_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto peep = GetGuest(); - if (peep != nullptr) - { - peep->TrousersColour = value; - peep->Invalidate(); - } - } - - uint8_t balloonColour_get() const - { - auto peep = GetGuest(); - return peep != nullptr ? peep->BalloonColour : 0; - } - void balloonColour_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto peep = GetGuest(); - if (peep != nullptr) - { - peep->BalloonColour = value; - peep->Invalidate(); - } - } - - uint8_t hatColour_get() const - { - auto peep = GetGuest(); - return peep != nullptr ? peep->HatColour : 0; - } - void hatColour_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto peep = GetGuest(); - if (peep != nullptr) - { - peep->HatColour = value; - peep->Invalidate(); - } - } - - uint8_t umbrellaColour_get() const - { - auto peep = GetGuest(); - return peep != nullptr ? peep->UmbrellaColour : 0; - } - void umbrellaColour_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto peep = GetGuest(); - if (peep != nullptr) - { - peep->UmbrellaColour = value; - peep->Invalidate(); - } - } - - uint8_t happiness_get() const - { - auto peep = GetGuest(); - return peep != nullptr ? peep->Happiness : 0; - } - void happiness_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto peep = GetGuest(); - if (peep != nullptr) - { - peep->Happiness = value; - } - } - - uint8_t happinessTarget_get() const - { - auto peep = GetGuest(); - return peep != nullptr ? peep->HappinessTarget : 0; - } - void happinessTarget_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto peep = GetGuest(); - if (peep != nullptr) - { - peep->HappinessTarget = value; - } - } - - uint8_t nausea_get() const - { - auto peep = GetGuest(); - return peep != nullptr ? peep->Nausea : 0; - } - void nausea_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto peep = GetGuest(); - if (peep != nullptr) - { - peep->Nausea = value; - } - } - - uint8_t nauseaTarget_get() const - { - auto peep = GetGuest(); - return peep != nullptr ? peep->NauseaTarget : 0; - } - void nauseaTarget_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto peep = GetGuest(); - if (peep != nullptr) - { - peep->NauseaTarget = value; - } - } - - uint8_t hunger_get() const - { - auto peep = GetGuest(); - return peep != nullptr ? peep->Hunger : 0; - } - void hunger_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto peep = GetGuest(); - if (peep != nullptr) - { - peep->Hunger = value; - } - } - - uint8_t thirst_get() const - { - auto peep = GetGuest(); - return peep != nullptr ? peep->Thirst : 0; - } - void thirst_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto peep = GetGuest(); - if (peep != nullptr) - { - peep->Thirst = value; - } - } - - uint8_t toilet_get() const - { - auto peep = GetGuest(); - return peep != nullptr ? peep->Toilet : 0; - } - void toilet_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto peep = GetGuest(); - if (peep != nullptr) - { - peep->Toilet = value; - } - } - - uint8_t mass_get() const - { - auto peep = GetGuest(); - return peep != nullptr ? peep->Mass : 0; - } - void mass_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto peep = GetGuest(); - if (peep != nullptr) - { - peep->Mass = value; - } - } - - uint8_t minIntensity_get() const - { - auto peep = GetGuest(); - return peep != nullptr ? peep->Intensity.GetMinimum() : 0; - } - void minIntensity_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto peep = GetGuest(); - if (peep != nullptr) - { - peep->Intensity = peep->Intensity.WithMinimum(value); - } - } - - uint8_t maxIntensity_get() const - { - auto peep = GetGuest(); - return peep != nullptr ? peep->Intensity.GetMaximum() : 0; - } - void maxIntensity_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto peep = GetGuest(); - if (peep != nullptr) - { - peep->Intensity = peep->Intensity.WithMaximum(value); - } - } - - uint8_t nauseaTolerance_get() const - { - auto peep = GetGuest(); - return peep != nullptr ? EnumValue(peep->NauseaTolerance) : 0; - } - void nauseaTolerance_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto peep = GetGuest(); - if (peep != nullptr) - { - peep->NauseaTolerance = static_cast(std::min(value, 3)); - } - } - - int32_t cash_get() const - { - auto peep = GetGuest(); - return peep != nullptr ? peep->CashInPocket : 0; - } - void cash_set(int32_t value) - { - ThrowIfGameStateNotMutable(); - auto peep = GetGuest(); - if (peep != nullptr) - { - peep->CashInPocket = std::max(0, value); - } - } - - bool isInPark_get() const - { - auto peep = GetGuest(); - return (peep != nullptr && !peep->OutsideOfPark); - } - - bool isLost_get() const - { - auto peep = GetGuest(); - return (peep != nullptr && peep->GuestIsLostCountdown < 90); - } - - uint8_t lostCountdown_get() const - { - auto peep = GetGuest(); - return peep != nullptr ? peep->GuestIsLostCountdown : 0; - } - void lostCountdown_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto peep = GetGuest(); - if (peep != nullptr) - { - peep->GuestIsLostCountdown = value; - } - } - }; - - class ScStaff : public ScPeep - { - public: - ScStaff(uint16_t Id) - : ScPeep(Id) - { - } - - static void Register(duk_context* ctx) - { - dukglue_set_base_class(ctx); - dukglue_register_property(ctx, &ScStaff::staffType_get, &ScStaff::staffType_set, "staffType"); - dukglue_register_property(ctx, &ScStaff::colour_get, &ScStaff::colour_set, "colour"); - dukglue_register_property(ctx, &ScStaff::costume_get, &ScStaff::costume_set, "costume"); - dukglue_register_property(ctx, &ScStaff::orders_get, &ScStaff::orders_set, "orders"); - } - - private: - Staff* GetStaff() const - { - return ::GetEntity(_id); - } - - std::string staffType_get() const - { - auto peep = GetStaff(); - if (peep != nullptr) - { - switch (peep->AssignedStaffType) - { - case StaffType::Handyman: - return "handyman"; - case StaffType::Mechanic: - return "mechanic"; - case StaffType::Security: - return "security"; - case StaffType::Entertainer: - return "entertainer"; - case StaffType::Count: - break; - } - } - return ""; - } - - void staffType_set(const std::string& value) - { - ThrowIfGameStateNotMutable(); - auto peep = GetStaff(); - if (peep != nullptr) - { - if (value == "handyman" && peep->AssignedStaffType != StaffType::Handyman) - { - peep->AssignedStaffType = StaffType::Handyman; - peep->SpriteType = PeepSpriteType::Handyman; - } - else if (value == "mechanic" && peep->AssignedStaffType != StaffType::Mechanic) - { - peep->AssignedStaffType = StaffType::Mechanic; - peep->SpriteType = PeepSpriteType::Mechanic; - } - else if (value == "security" && peep->AssignedStaffType != StaffType::Security) - { - peep->AssignedStaffType = StaffType::Security; - peep->SpriteType = PeepSpriteType::Security; - } - else if (value == "entertainer" && peep->AssignedStaffType != StaffType::Entertainer) - { - peep->AssignedStaffType = StaffType::Entertainer; - peep->SpriteType = PeepSpriteType::EntertainerPanda; - } - } - } - - uint8_t colour_get() const - { - auto peep = GetStaff(); - return peep != nullptr ? peep->TshirtColour : 0; - } - - void colour_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto peep = GetStaff(); - if (peep != nullptr) - { - peep->TshirtColour = value; - peep->TrousersColour = value; - } - } - - uint8_t costume_get() const - { - auto peep = GetStaff(); - if (peep != nullptr && peep->AssignedStaffType == StaffType::Entertainer) - { - return peep->GetCostume(); - } - return 0; - } - - void costume_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto peep = GetStaff(); - if (peep != nullptr) - { - peep->SetCostume(value); - } - } - - uint8_t orders_get() const - { - auto peep = GetStaff(); - return peep != nullptr ? peep->StaffOrders : 0; - } - - void orders_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto peep = GetStaff(); - if (peep != nullptr) - { - peep->StaffOrders = value; - } - } - }; - - static const DukEnumMap LitterTypeMap({ - { "vomit", Litter::Type::Vomit }, - { "vomit_alt", Litter::Type::VomitAlt }, - { "empty_can", Litter::Type::EmptyCan }, - { "rubbish", Litter::Type::Rubbish }, - { "burger_box", Litter::Type::BurgerBox }, - { "empty_cup", Litter::Type::EmptyCup }, - { "empty_box", Litter::Type::EmptyBox }, - { "empty_bottle", Litter::Type::EmptyBottle }, - { "empty_bowl_red", Litter::Type::EmptyBowlRed }, - { "empty_drink_carton", Litter::Type::EmptyDrinkCarton }, - { "empty_juice_cup", Litter::Type::EmptyJuiceCup }, - { "empty_bowl_blue", Litter::Type::EmptyBowlBlue }, - }); - - class ScLitter : public ScEntity - { - public: - ScLitter(uint16_t Id) - : ScEntity(Id) - { - } - - static void Register(duk_context* ctx) - { - dukglue_set_base_class(ctx); - dukglue_register_property(ctx, &ScLitter::litterType_get, &ScLitter::litterType_set, "litterType"); - dukglue_register_property(ctx, &ScLitter::creationTick_get, nullptr, "creationTick"); - } - - private: - Litter* GetLitter() const - { - return ::GetEntity(_id); - } - - std::string litterType_get() const - { - auto* litter = GetLitter(); - auto it = LitterTypeMap.find(litter->SubType); - if (it == LitterTypeMap.end()) - return ""; - return std::string{ it->first }; - } - - void litterType_set(const std::string& litterType) - { - ThrowIfGameStateNotMutable(); - - auto it = LitterTypeMap.find(litterType); - if (it == LitterTypeMap.end()) - return; - auto* litter = GetLitter(); - litter->SubType = it->second; - } - - uint32_t creationTick_get() const - { - auto* litter = GetLitter(); - if (litter == nullptr) - return 0; - return litter->creationTick; - } - }; - -} // namespace OpenRCT2::Scripting - -#endif diff --git a/src/openrct2/scripting/ScMap.hpp b/src/openrct2/scripting/ScMap.hpp deleted file mode 100644 index 10c3e10242..0000000000 --- a/src/openrct2/scripting/ScMap.hpp +++ /dev/null @@ -1,277 +0,0 @@ -/***************************************************************************** - * Copyright (c) 2014-2020 OpenRCT2 developers - * - * For a complete list of all authors, please refer to contributors.md - * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 - * - * OpenRCT2 is licensed under the GNU General Public License version 3. - *****************************************************************************/ - -#pragma once - -#ifdef ENABLE_SCRIPTING - -# include "../common.h" -# include "../ride/Ride.h" -# include "../ride/TrainManager.h" -# include "../world/Balloon.h" -# include "../world/Duck.h" -# include "../world/EntityList.h" -# include "../world/Fountain.h" -# include "../world/Litter.h" -# include "../world/Map.h" -# include "../world/MoneyEffect.h" -# include "../world/Particle.h" -# include "Duktape.hpp" -# include "ScEntity.hpp" -# include "ScRide.hpp" -# include "ScTile.hpp" - -namespace OpenRCT2::Scripting -{ - class ScMap - { - private: - duk_context* _context; - - public: - ScMap(duk_context* ctx) - : _context(ctx) - { - } - - DukValue size_get() const - { - return ToDuk(_context, CoordsXY{ gMapSize, gMapSize }); - } - - int32_t numRides_get() const - { - return static_cast(GetRideManager().size()); - } - - int32_t numEntities_get() const - { - return MAX_ENTITIES; - } - - std::vector> rides_get() const - { - std::vector> result; - auto rideManager = GetRideManager(); - for (const auto& ride : rideManager) - { - result.push_back(std::make_shared(ride.id)); - } - return result; - } - - std::shared_ptr getRide(int32_t id) const - { - auto rideManager = GetRideManager(); - auto ride = rideManager[static_cast(id)]; - if (ride != nullptr) - { - return std::make_shared(ride->id); - } - return {}; - } - - std::shared_ptr getTile(int32_t x, int32_t y) const - { - auto coords = TileCoordsXY(x, y).ToCoordsXY(); - return std::make_shared(coords); - } - - DukValue getEntity(int32_t id) const - { - if (id >= 0 && id < MAX_ENTITIES) - { - auto spriteId = static_cast(id); - auto sprite = GetEntity(spriteId); - if (sprite != nullptr && sprite->Type != EntityType::Null) - { - return GetEntityAsDukValue(sprite); - } - } - duk_push_null(_context); - return DukValue::take_from_stack(_context); - } - - std::vector getAllEntities(const std::string& type) const - { - std::vector result; - if (type == "balloon") - { - for (auto sprite : EntityList()) - { - result.push_back(GetObjectAsDukValue(_context, std::make_shared(sprite->sprite_index))); - } - } - else if (type == "car") - { - for (auto trainHead : TrainManager::View()) - { - for (auto carId = trainHead->sprite_index; carId != SPRITE_INDEX_NULL;) - { - auto car = GetEntity(carId); - result.push_back(GetObjectAsDukValue(_context, std::make_shared(carId))); - carId = car->next_vehicle_on_train; - } - } - } - else if (type == "litter") - { - for (auto sprite : EntityList()) - { - result.push_back(GetObjectAsDukValue(_context, std::make_shared(sprite->sprite_index))); - } - } - else if (type == "duck") - { - for (auto sprite : EntityList()) - { - result.push_back(GetObjectAsDukValue(_context, std::make_shared(sprite->sprite_index))); - } - } - else if (type == "peep") - { - for (auto sprite : EntityList()) - { - result.push_back(GetObjectAsDukValue(_context, std::make_shared(sprite->sprite_index))); - } - for (auto sprite : EntityList()) - { - result.push_back(GetObjectAsDukValue(_context, std::make_shared(sprite->sprite_index))); - } - } - else if (type == "guest") - { - for (auto sprite : EntityList()) - { - result.push_back(GetObjectAsDukValue(_context, std::make_shared(sprite->sprite_index))); - } - } - else if (type == "staff") - { - for (auto sprite : EntityList()) - { - result.push_back(GetObjectAsDukValue(_context, std::make_shared(sprite->sprite_index))); - } - } - else - { - duk_error(_context, DUK_ERR_ERROR, "Invalid entity type."); - } - - return result; - } - - template DukValue createEntityType(const DukValue& initializer) - { - TEntityType* entity = CreateEntity(); - - auto entityPos = CoordsXYZ{ AsOrDefault(initializer["x"], 0), AsOrDefault(initializer["y"], 0), - AsOrDefault(initializer["z"], 0) }; - entity->MoveTo(entityPos); - - return GetObjectAsDukValue(_context, std::make_shared(entity->sprite_index)); - } - - DukValue createEntity(const std::string& type, const DukValue& initializer) - { - if (type == "car") - { - return createEntityType(initializer); - } - else if (type == "staff") - { - return createEntityType(initializer); - } - else if (type == "guest") - { - return createEntityType(initializer); - } - else if (type == "steam_particle") - { - return createEntityType(initializer); - } - else if (type == "money_effect") - { - return createEntityType(initializer); - } - else if (type == "crashed_vehicle_particle") - { - return createEntityType(initializer); - } - else if (type == "explosion_cloud") - { - return createEntityType(initializer); - } - else if (type == "crash_splash") - { - return createEntityType(initializer); - } - else if (type == "explosion_flare") - { - return createEntityType(initializer); - } - else if (type == "balloon") - { - return createEntityType(initializer); - } - else if (type == "duck") - { - return createEntityType(initializer); - } - else if (type == "jumping_fountain") - { - return createEntityType(initializer); - } - else if (type == "litter") - { - return createEntityType(initializer); - } - else - { - duk_error(_context, DUK_ERR_ERROR, "Invalid entity type."); - } - - return DukValue(); - } - - static void Register(duk_context* ctx) - { - dukglue_register_property(ctx, &ScMap::size_get, nullptr, "size"); - dukglue_register_property(ctx, &ScMap::numRides_get, nullptr, "numRides"); - dukglue_register_property(ctx, &ScMap::numEntities_get, nullptr, "numEntities"); - dukglue_register_property(ctx, &ScMap::rides_get, nullptr, "rides"); - dukglue_register_method(ctx, &ScMap::getRide, "getRide"); - dukglue_register_method(ctx, &ScMap::getTile, "getTile"); - dukglue_register_method(ctx, &ScMap::getEntity, "getEntity"); - dukglue_register_method(ctx, &ScMap::getAllEntities, "getAllEntities"); - dukglue_register_method(ctx, &ScMap::createEntity, "createEntity"); - } - - private: - DukValue GetEntityAsDukValue(const SpriteBase* sprite) const - { - auto spriteId = sprite->sprite_index; - switch (sprite->Type) - { - case EntityType::Vehicle: - return GetObjectAsDukValue(_context, std::make_shared(spriteId)); - case EntityType::Staff: - return GetObjectAsDukValue(_context, std::make_shared(spriteId)); - case EntityType::Guest: - return GetObjectAsDukValue(_context, std::make_shared(spriteId)); - case EntityType::Litter: - return GetObjectAsDukValue(_context, std::make_shared(spriteId)); - default: - return GetObjectAsDukValue(_context, std::make_shared(spriteId)); - } - } - }; -} // namespace OpenRCT2::Scripting - -#endif diff --git a/src/openrct2/scripting/ScNetwork.hpp b/src/openrct2/scripting/ScNetwork.hpp deleted file mode 100644 index ae8ddec4b1..0000000000 --- a/src/openrct2/scripting/ScNetwork.hpp +++ /dev/null @@ -1,540 +0,0 @@ -/***************************************************************************** - * Copyright (c) 2014-2020 OpenRCT2 developers - * - * For a complete list of all authors, please refer to contributors.md - * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 - * - * OpenRCT2 is licensed under the GNU General Public License version 3. - *****************************************************************************/ - -#pragma once - -#ifdef ENABLE_SCRIPTING - -# include "../Context.h" -# include "../actions/NetworkModifyGroupAction.h" -# include "../actions/PlayerKickAction.h" -# include "../actions/PlayerSetGroupAction.h" -# include "../network/NetworkAction.h" -# include "../network/network.h" -# include "Duktape.hpp" -# include "ScSocket.hpp" - -namespace OpenRCT2::Scripting -{ - class ScPlayerGroup - { - private: - int32_t _id; - - public: - ScPlayerGroup(int32_t id) - : _id(id) - { - } - - int32_t id_get() - { - return _id; - } - - std::string name_get() const - { -# ifndef DISABLE_NETWORK - auto index = network_get_group_index(_id); - if (index == -1) - return {}; - return network_get_group_name(index); -# else - return {}; -# endif - } - void name_set(std::string value) - { -# ifndef DISABLE_NETWORK - auto action = NetworkModifyGroupAction(ModifyGroupType::SetName, _id, value); - GameActions::Execute(&action); -# endif - } - - std::vector permissions_get() const - { -# ifndef DISABLE_NETWORK - auto index = network_get_group_index(_id); - if (index == -1) - return {}; - - // Create array of permissions - std::vector result; - auto permissionIndex = 0; - for (const auto& action : NetworkActions::Actions) - { - if (network_can_perform_action(index, static_cast(permissionIndex))) - { - result.push_back(TransformPermissionKeyToJS(action.PermissionName)); - } - permissionIndex++; - } - return result; -# else - return {}; -# endif - } - void permissions_set(std::vector value) - { -# ifndef DISABLE_NETWORK - auto groupIndex = network_get_group_index(_id); - if (groupIndex == -1) - return; - - // First clear all permissions - auto networkAction = NetworkModifyGroupAction( - ModifyGroupType::SetPermissions, _id, "", 0, PermissionState::ClearAll); - GameActions::Execute(&networkAction); - - std::vector enabledPermissions; - enabledPermissions.resize(NetworkActions::Actions.size()); - for (const auto& p : value) - { - auto permissionName = TransformPermissionKeyToInternal(p); - - auto permissionIndex = 0; - for (const auto& action : NetworkActions::Actions) - { - if (action.PermissionName == permissionName) - { - enabledPermissions[permissionIndex] = true; - } - permissionIndex++; - } - } - - for (size_t i = 0; i < enabledPermissions.size(); i++) - { - auto toggle - = (enabledPermissions[i] - != (network_can_perform_action(groupIndex, static_cast(i)) != 0)); - if (toggle) - { - auto networkAction2 = NetworkModifyGroupAction( - ModifyGroupType::SetPermissions, _id, "", static_cast(i), PermissionState::Toggle); - GameActions::Execute(&networkAction2); - } - } -# endif - } - - static void Register(duk_context* ctx) - { - dukglue_register_property(ctx, &ScPlayerGroup::id_get, nullptr, "id"); - dukglue_register_property(ctx, &ScPlayerGroup::name_get, &ScPlayerGroup::name_set, "name"); - dukglue_register_property(ctx, &ScPlayerGroup::permissions_get, &ScPlayerGroup::permissions_set, "permissions"); - } - - private: - static std::string TransformPermissionKeyToJS(const std::string& s) - { - auto result = s.substr(sizeof("PERMISSION_") - 1); - for (auto& c : result) - { - c = std::tolower(c); - } - return result; - } - - static std::string TransformPermissionKeyToInternal(const std::string& s) - { - auto result = "PERMISSION_" + s; - for (auto& c : result) - { - c = std::toupper(c); - } - return result; - } - }; - - class ScPlayer - { - private: - int32_t _id; - - public: - ScPlayer(int32_t id) - : _id(id) - { - } - - int32_t id_get() const - { - return _id; - } - - std::string name_get() const - { -# ifndef DISABLE_NETWORK - auto index = network_get_player_index(_id); - if (index == -1) - return {}; - return network_get_player_name(index); -# else - return {}; -# endif - } - - int32_t group_get() const - { -# ifndef DISABLE_NETWORK - auto index = network_get_player_index(_id); - if (index == -1) - return {}; - return network_get_player_group(index); -# else - return 0; -# endif - } - void group_set(int32_t value) - { -# ifndef DISABLE_NETWORK - auto playerSetGroupAction = PlayerSetGroupAction(_id, value); - GameActions::Execute(&playerSetGroupAction); -# endif - } - - int32_t ping_get() const - { -# ifndef DISABLE_NETWORK - auto index = network_get_player_index(_id); - if (index == -1) - return {}; - return network_get_player_ping(index); -# else - return 0; -# endif - } - - int32_t commandsRan_get() const - { -# ifndef DISABLE_NETWORK - auto index = network_get_player_index(_id); - if (index == -1) - return {}; - return network_get_player_commands_ran(index); -# else - return 0; -# endif - } - - int32_t moneySpent_get() const - { -# ifndef DISABLE_NETWORK - auto index = network_get_player_index(_id); - if (index == -1) - return {}; - return network_get_player_money_spent(index); -# else - return 0; -# endif - } - - std::string ipAddress_get() const - { - return network_get_player_ip_address(_id); - } - - std::string publicKeyHash_get() const - { - return network_get_player_public_key_hash(_id); - } - - static void Register(duk_context* ctx) - { - dukglue_register_property(ctx, &ScPlayer::id_get, nullptr, "id"); - dukglue_register_property(ctx, &ScPlayer::name_get, nullptr, "name"); - dukglue_register_property(ctx, &ScPlayer::group_get, &ScPlayer::group_set, "group"); - dukglue_register_property(ctx, &ScPlayer::ping_get, nullptr, "ping"); - dukglue_register_property(ctx, &ScPlayer::commandsRan_get, nullptr, "commandsRan"); - dukglue_register_property(ctx, &ScPlayer::moneySpent_get, nullptr, "moneySpent"); - dukglue_register_property(ctx, &ScPlayer::ipAddress_get, nullptr, "ipAddress"); - dukglue_register_property(ctx, &ScPlayer::publicKeyHash_get, nullptr, "publicKeyHash"); - } - }; - - class ScNetwork - { - private: -# ifdef __clang__ - [[maybe_unused]] -# endif - duk_context* _context; - - public: - ScNetwork(duk_context* ctx) - : _context(ctx) - { - } - - std::string mode_get() const - { -# ifndef DISABLE_NETWORK - switch (network_get_mode()) - { - case NETWORK_MODE_SERVER: - return "server"; - case NETWORK_MODE_CLIENT: - return "client"; - } -# endif - return "none"; - } - int32_t numPlayers_get() const - { -# ifndef DISABLE_NETWORK - return network_get_num_players(); -# else - return 0; -# endif - } - int32_t numGroups_get() const - { -# ifndef DISABLE_NETWORK - return network_get_num_groups(); -# else - return 0; -# endif - } - int32_t defaultGroup_get() const - { -# ifndef DISABLE_NETWORK - return network_get_default_group(); -# else - return 0; -# endif - } - void defaultGroup_set(int32_t value) - { -# ifndef DISABLE_NETWORK - auto action = NetworkModifyGroupAction(ModifyGroupType::SetDefault, value); - GameActions::Execute(&action); -# endif - } - - std::vector> groups_get() const - { - std::vector> groups; -# ifndef DISABLE_NETWORK - auto numGroups = network_get_num_groups(); - for (int32_t i = 0; i < numGroups; i++) - { - auto groupId = network_get_group_id(i); - groups.push_back(std::make_shared(groupId)); - } -# endif - return groups; - } - - std::vector> players_get() const - { - std::vector> players; -# ifndef DISABLE_NETWORK - auto numPlayers = network_get_num_players(); - for (int32_t i = 0; i < numPlayers; i++) - { - auto playerId = network_get_player_id(i); - players.push_back(std::make_shared(playerId)); - } -# endif - return players; - } - - std::shared_ptr currentPlayer_get() const - { - std::shared_ptr player; -# ifndef DISABLE_NETWORK - auto playerId = network_get_current_player_id(); - player = std::make_shared(playerId); -# endif - return player; - } - - std::shared_ptr getPlayer(int32_t index) const - { -# ifndef DISABLE_NETWORK - auto numPlayers = network_get_num_players(); - if (index < numPlayers) - { - auto playerId = network_get_player_id(index); - return std::make_shared(playerId); - } -# endif - return nullptr; - } - - DukValue stats_get() const - { -# ifndef DISABLE_NETWORK - auto obj = OpenRCT2::Scripting::DukObject(_context); - auto networkStats = network_get_stats(); - { - duk_push_array(_context); - duk_uarridx_t index = 0; - for (auto v : networkStats.bytesReceived) - { - duk_push_number(_context, v); - duk_put_prop_index(_context, -2, index); - index++; - } - obj.Set("bytesReceived", DukValue::take_from_stack(_context)); - } - { - duk_push_array(_context); - duk_uarridx_t index = 0; - for (auto v : networkStats.bytesSent) - { - duk_push_number(_context, v); - duk_put_prop_index(_context, -2, index); - index++; - } - obj.Set("bytesSent", DukValue::take_from_stack(_context)); - } - return obj.Take(); -# else - return ToDuk(_context, nullptr); -# endif - } - - std::shared_ptr getGroup(int32_t index) const - { -# ifndef DISABLE_NETWORK - auto numGroups = network_get_num_groups(); - if (index < numGroups) - { - auto groupId = network_get_group_id(index); - return std::make_shared(groupId); - } -# endif - return nullptr; - } - - void addGroup() - { -# ifndef DISABLE_NETWORK - auto networkModifyGroup = NetworkModifyGroupAction(ModifyGroupType::AddGroup); - GameActions::Execute(&networkModifyGroup); -# endif - } - - void removeGroup(int32_t index) - { -# ifndef DISABLE_NETWORK - auto numGroups = network_get_num_groups(); - if (index < numGroups) - { - auto groupId = network_get_group_id(index); - auto networkAction = NetworkModifyGroupAction(ModifyGroupType::RemoveGroup, groupId); - GameActions::Execute(&networkAction); - } -# endif - } - - void kickPlayer(int32_t index) - { -# ifndef DISABLE_NETWORK - auto numPlayers = network_get_num_players(); - if (index < numPlayers) - { - auto playerId = network_get_player_id(index); - auto kickPlayerAction = PlayerKickAction(playerId); - GameActions::Execute(&kickPlayerAction); - } -# endif - } - - void sendMessage(std::string message, DukValue players) - { -# ifndef DISABLE_NETWORK - if (players.is_array()) - { - if (network_get_mode() == NETWORK_MODE_SERVER) - { - std::vector playerIds; - auto playerArray = players.as_array(); - for (const auto& item : playerArray) - { - if (item.type() == DukValue::Type::NUMBER) - { - playerIds.push_back(static_cast(item.as_int())); - } - } - if (!playerArray.empty()) - { - network_send_chat(message.c_str(), playerIds); - } - } - else - { - duk_error(players.context(), DUK_ERR_ERROR, "Only servers can send private messages."); - } - } - else - { - network_send_chat(message.c_str()); - } -# endif - } - -# ifndef DISABLE_NETWORK - std::shared_ptr createListener() - { - auto& scriptEngine = GetContext()->GetScriptEngine(); - auto plugin = scriptEngine.GetExecInfo().GetCurrentPlugin(); - auto socket = std::make_shared(plugin); - scriptEngine.AddSocket(socket); - return socket; - } -# else - void createListener() - { - duk_error(_context, DUK_ERR_ERROR, "Networking has been disabled."); - } -# endif - -# ifndef DISABLE_NETWORK - std::shared_ptr createSocket() - { - auto& scriptEngine = GetContext()->GetScriptEngine(); - auto plugin = scriptEngine.GetExecInfo().GetCurrentPlugin(); - auto socket = std::make_shared(plugin); - scriptEngine.AddSocket(socket); - return socket; - } -# else - void createSocket() - { - duk_error(_context, DUK_ERR_ERROR, "Networking has been disabled."); - } -# endif - - static void Register(duk_context* ctx) - { - dukglue_register_property(ctx, &ScNetwork::mode_get, nullptr, "mode"); - dukglue_register_property(ctx, &ScNetwork::numGroups_get, nullptr, "numGroups"); - dukglue_register_property(ctx, &ScNetwork::numPlayers_get, nullptr, "numPlayers"); - dukglue_register_property(ctx, &ScNetwork::groups_get, nullptr, "groups"); - dukglue_register_property(ctx, &ScNetwork::players_get, nullptr, "players"); - dukglue_register_property(ctx, &ScNetwork::currentPlayer_get, nullptr, "currentPlayer"); - dukglue_register_property(ctx, &ScNetwork::defaultGroup_get, &ScNetwork::defaultGroup_set, "defaultGroup"); - dukglue_register_property(ctx, &ScNetwork::stats_get, nullptr, "stats"); - dukglue_register_method(ctx, &ScNetwork::addGroup, "addGroup"); - dukglue_register_method(ctx, &ScNetwork::getGroup, "getGroup"); - dukglue_register_method(ctx, &ScNetwork::removeGroup, "removeGroup"); - dukglue_register_method(ctx, &ScNetwork::getPlayer, "getPlayer"); - dukglue_register_method(ctx, &ScNetwork::kickPlayer, "kickPlayer"); - dukglue_register_method(ctx, &ScNetwork::sendMessage, "sendMessage"); - - dukglue_register_method(ctx, &ScNetwork::createListener, "createListener"); - dukglue_register_method(ctx, &ScNetwork::createSocket, "createSocket"); - } - }; -} // namespace OpenRCT2::Scripting - -#endif diff --git a/src/openrct2/scripting/ScPark.hpp b/src/openrct2/scripting/ScPark.hpp deleted file mode 100644 index ec6269f4d7..0000000000 --- a/src/openrct2/scripting/ScPark.hpp +++ /dev/null @@ -1,621 +0,0 @@ -/***************************************************************************** - * Copyright (c) 2014-2020 OpenRCT2 developers - * - * For a complete list of all authors, please refer to contributors.md - * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 - * - * OpenRCT2 is licensed under the GNU General Public License version 3. - *****************************************************************************/ - -#pragma once - -#ifdef ENABLE_SCRIPTING - -# include "../Context.h" -# include "../GameState.h" -# include "../common.h" -# include "../core/String.hpp" -# include "../management/Finance.h" -# include "../management/NewsItem.h" -# include "../peep/Peep.h" -# include "../windows/Intent.h" -# include "../world/Park.h" -# include "Duktape.hpp" -# include "ScriptEngine.h" - -# include - -namespace OpenRCT2::Scripting -{ - static constexpr const char* ParkMessageTypeStrings[] = { - "attraction", "peep_on_attraction", "peep", "money", "blank", "research", "guests", "award", "chart", - }; - - inline News::ItemType GetParkMessageType(const std::string& key) - { - // Get the first ItemType that appears in ParkMessageTypeStrings that isn't Null - auto firstType = static_cast(News::ItemType::Ride); - - auto begin = std::begin(ParkMessageTypeStrings); - auto end = std::end(ParkMessageTypeStrings); - - auto it = std::find(begin, end, key); - return it != end ? static_cast(firstType + std::distance(begin, it)) : News::ItemType::Blank; - } - - inline std::string GetParkMessageType(News::ItemType type) - { - // Decrement 1 as ParkMessageTypeStrings doesn't contain the null type - auto scriptType = static_cast(type) - 1; - - if (scriptType < std::size(ParkMessageTypeStrings)) - { - return ParkMessageTypeStrings[scriptType]; - } - return {}; - } - - template<> inline News::Item FromDuk(const DukValue& value) - { - News::Item result{}; - result.Type = GetParkMessageType(value["type"].as_string()); - result.Assoc = value["subject"].as_int(); - result.Ticks = value["tickCount"].as_int(); - result.MonthYear = value["month"].as_int(); - result.Day = value["day"].as_int(); - result.Text = value["text"].as_string(); - return result; - } - - class ScParkMessage - { - private: - size_t _index{}; - - public: - ScParkMessage(size_t index) - : _index(index) - { - } - - static void Register(duk_context* ctx) - { - dukglue_register_property(ctx, &ScParkMessage::isArchived_get, nullptr, "isArchived"); - dukglue_register_property(ctx, &ScParkMessage::month_get, &ScParkMessage::month_set, "month"); - dukglue_register_property(ctx, &ScParkMessage::day_get, &ScParkMessage::day_set, "day"); - dukglue_register_property(ctx, &ScParkMessage::tickCount_get, &ScParkMessage::tickCount_set, "tickCount"); - dukglue_register_property(ctx, &ScParkMessage::type_get, &ScParkMessage::type_set, "type"); - dukglue_register_property(ctx, &ScParkMessage::subject_get, &ScParkMessage::subject_set, "subject"); - dukglue_register_property(ctx, &ScParkMessage::text_get, &ScParkMessage::text_set, "text"); - dukglue_register_method(ctx, &ScParkMessage::remove, "remove"); - } - - private: - News::Item* GetMessage() const - { - return &gNewsItems[_index]; - } - - bool isArchived_get() const - { - return _index >= News::ItemHistoryStart; - } - - uint16_t month_get() const - { - auto msg = GetMessage(); - if (msg != nullptr) - { - return msg->MonthYear; - } - return 0; - } - - void month_set(uint16_t value) - { - ThrowIfGameStateNotMutable(); - auto msg = GetMessage(); - if (msg != nullptr) - { - msg->MonthYear = value; - } - } - - uint8_t day_get() const - { - auto msg = GetMessage(); - if (msg != nullptr) - { - return msg->Day; - } - return 0; - } - - void day_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto msg = GetMessage(); - if (msg != nullptr) - { - msg->Day = value; - } - } - - uint16_t tickCount_get() const - { - auto msg = GetMessage(); - if (msg != nullptr) - { - return msg->Ticks; - } - return 0; - } - - void tickCount_set(uint16_t value) - { - ThrowIfGameStateNotMutable(); - auto msg = GetMessage(); - if (msg != nullptr) - { - msg->Ticks = value; - } - } - - std::string type_get() const - { - auto msg = GetMessage(); - if (msg != nullptr) - { - return GetParkMessageType(msg->Type); - } - return {}; - } - - void type_set(const std::string& value) - { - ThrowIfGameStateNotMutable(); - auto msg = GetMessage(); - if (msg != nullptr) - { - msg->Type = GetParkMessageType(value); - } - } - - uint32_t subject_get() const - { - auto msg = GetMessage(); - if (msg != nullptr) - { - return msg->Assoc; - } - return 0; - } - - void subject_set(uint32_t value) - { - ThrowIfGameStateNotMutable(); - auto msg = GetMessage(); - if (msg != nullptr) - { - msg->Assoc = value; - } - } - - std::string text_get() const - { - auto msg = GetMessage(); - if (msg != nullptr) - { - return msg->Text; - } - return {}; - } - - void text_set(const std::string& value) - { - ThrowIfGameStateNotMutable(); - auto msg = GetMessage(); - if (msg != nullptr) - { - msg->Text = value; - } - } - - void remove() - { - News::RemoveItem(static_cast(_index)); - } - }; - - static const DukEnumMap ParkFlagMap({ - { "open", PARK_FLAGS_PARK_OPEN }, - { "scenarioCompleteNameInput", PARK_FLAGS_SCENARIO_COMPLETE_NAME_INPUT }, - { "forbidLandscapeChanges", PARK_FLAGS_FORBID_LANDSCAPE_CHANGES }, - { "forbidTreeRemoval", PARK_FLAGS_FORBID_TREE_REMOVAL }, - { "forbidHighConstruction", PARK_FLAGS_FORBID_HIGH_CONSTRUCTION }, - { "preferLessIntenseRides", PARK_FLAGS_PREF_LESS_INTENSE_RIDES }, - { "forbidMarketingCampaigns", PARK_FLAGS_FORBID_MARKETING_CAMPAIGN }, - { "preferMoreIntenseRides", PARK_FLAGS_PREF_MORE_INTENSE_RIDES }, - { "noMoney", PARK_FLAGS_NO_MONEY }, - { "difficultGuestGeneration", PARK_FLAGS_DIFFICULT_GUEST_GENERATION }, - { "freeParkEntry", PARK_FLAGS_PARK_FREE_ENTRY }, - { "difficultParkRating", PARK_FLAGS_DIFFICULT_PARK_RATING }, - { "noMoney", PARK_FLAGS_NO_MONEY_SCENARIO }, - { "unlockAllPrices", PARK_FLAGS_UNLOCK_ALL_PRICES }, - }); - - class ScPark - { - public: - money64 cash_get() const - { - return gCash; - } - void cash_set(money64 value) - { - ThrowIfGameStateNotMutable(); - - if (gCash != value) - { - gCash = value; - auto intent = Intent(INTENT_ACTION_UPDATE_CASH); - context_broadcast_intent(&intent); - } - } - - int32_t rating_get() const - { - return gParkRating; - } - void rating_set(int32_t value) - { - ThrowIfGameStateNotMutable(); - - auto valueClamped = std::min(std::max(0, value), 999); - if (gParkRating != valueClamped) - { - gParkRating = std::min(std::max(0, value), 999); - auto intent = Intent(INTENT_ACTION_UPDATE_PARK_RATING); - context_broadcast_intent(&intent); - } - } - - money64 bankLoan_get() const - { - return gBankLoan; - } - void bankLoan_set(money64 value) - { - ThrowIfGameStateNotMutable(); - - if (gBankLoan != value) - { - gBankLoan = value; - auto intent = Intent(INTENT_ACTION_UPDATE_CASH); - context_broadcast_intent(&intent); - } - } - - money64 maxBankLoan_get() const - { - return gMaxBankLoan; - } - void maxBankLoan_set(money64 value) - { - ThrowIfGameStateNotMutable(); - - if (gMaxBankLoan != value) - { - gMaxBankLoan = value; - auto intent = Intent(INTENT_ACTION_UPDATE_CASH); - context_broadcast_intent(&intent); - } - } - - money16 entranceFee_get() const - { - return gParkEntranceFee; - } - void entranceFee_set(money16 value) - { - ThrowIfGameStateNotMutable(); - - if (gParkEntranceFee != value) - { - gParkEntranceFee = value; - window_invalidate_by_class(WC_PARK_INFORMATION); - } - } - - uint32_t guests_get() const - { - return gNumGuestsInPark; - } - - uint32_t suggestedGuestMaximum_get() const - { - return _suggestedGuestMaximum; - } - - int32_t guestGenerationProbability_get() const - { - return _guestGenerationProbability; - } - - money16 guestInitialCash_get() const - { - return gGuestInitialCash; - } - - uint8_t guestInitialHappiness_get() const - { - return gGuestInitialHappiness; - } - - uint8_t guestInitialHunger_get() const - { - return gGuestInitialHunger; - } - - uint8_t guestInitialThirst_get() const - { - return gGuestInitialThirst; - } - - money64 value_get() const - { - return gParkValue; - } - void value_set(money64 value) - { - ThrowIfGameStateNotMutable(); - - if (gParkValue != value) - { - gParkValue = value; - auto intent = Intent(INTENT_ACTION_UPDATE_CASH); - context_broadcast_intent(&intent); - } - } - - money64 companyValue_get() const - { - return gCompanyValue; - } - void companyValue_set(money64 value) - { - ThrowIfGameStateNotMutable(); - - if (gCompanyValue != value) - { - gCompanyValue = value; - auto intent = Intent(INTENT_ACTION_UPDATE_CASH); - context_broadcast_intent(&intent); - } - } - - money16 totalRideValueForMoney_get() const - { - return gTotalRideValueForMoney; - } - - uint32_t totalAdmissions_get() const - { - return gTotalAdmissions; - } - void totalAdmissions_set(uint32_t value) - { - ThrowIfGameStateNotMutable(); - - if (gTotalAdmissions != value) - { - gTotalAdmissions = value; - window_invalidate_by_class(WC_PARK_INFORMATION); - } - } - - money64 totalIncomeFromAdmissions_get() const - { - return gTotalIncomeFromAdmissions; - } - void totalIncomeFromAdmissions_set(money64 value) - { - ThrowIfGameStateNotMutable(); - - if (gTotalIncomeFromAdmissions != value) - { - gTotalIncomeFromAdmissions = value; - window_invalidate_by_class(WC_PARK_INFORMATION); - } - } - - money32 landPrice_get() const - { - return gLandPrice; - } - void landPrice_set(money32 value) - { - ThrowIfGameStateNotMutable(); - gLandPrice = value; - } - - money32 constructionRightsPrice_get() const - { - return gConstructionRightsPrice; - } - void constructionRightsPrice_set(money32 value) - { - ThrowIfGameStateNotMutable(); - gConstructionRightsPrice = value; - } - - int16_t casualtyPenalty_get() const - { - return gParkRatingCasualtyPenalty; - } - void casualtyPenalty_set(int16_t value) - { - ThrowIfGameStateNotMutable(); - gParkRatingCasualtyPenalty = value; - } - - uint16_t parkSize_get() const - { - return gParkSize; - } - - std::string name_get() const - { - return GetContext()->GetGameState()->GetPark().Name; - } - void name_set(std::string value) - { - ThrowIfGameStateNotMutable(); - - auto& park = GetContext()->GetGameState()->GetPark(); - if (park.Name != value) - { - park.Name = value; - gfx_invalidate_screen(); - } - } - - bool getFlag(const std::string& key) const - { - auto mask = ParkFlagMap[key]; - return (gParkFlags & mask) != 0; - } - - void setFlag(const std::string& key, bool value) - { - ThrowIfGameStateNotMutable(); - auto mask = ParkFlagMap[key]; - if (value) - gParkFlags |= mask; - else - gParkFlags &= ~mask; - gfx_invalidate_screen(); - } - - std::vector> messages_get() const - { - std::vector> result; - for (size_t i = 0, newsSize = gNewsItems.GetRecent().size(); i < newsSize; i++) - { - result.push_back(std::make_shared(i)); - } - for (size_t i = 0, newsSize = gNewsItems.GetArchived().size(); i < newsSize; i++) - { - result.push_back(std::make_shared(i + News::ItemHistoryStart)); - } - return result; - } - - void messages_set(const std::vector& value) - { - int32_t index = 0; - int32_t archiveIndex = News::ItemHistoryStart; - for (const auto& item : value) - { - auto isArchived = item["isArchived"].as_bool(); - auto newsItem = FromDuk(item); - if (isArchived) - { - if (archiveIndex < News::MaxItems) - { - gNewsItems[archiveIndex] = newsItem; - archiveIndex++; - } - } - else - { - if (index < News::ItemHistoryStart) - { - gNewsItems[index] = newsItem; - index++; - } - } - } - - // End the lists by setting next item to null - if (index < News::ItemHistoryStart) - { - gNewsItems[index].Type = News::ItemType::Null; - } - if (archiveIndex < News::MaxItems) - { - gNewsItems[archiveIndex].Type = News::ItemType::Null; - } - } - - void postMessage(DukValue message) - { - ThrowIfGameStateNotMutable(); - try - { - uint32_t assoc = std::numeric_limits::max(); - auto type = News::ItemType::Blank; - std::string text; - if (message.type() == DukValue::Type::STRING) - { - text = message.as_string(); - } - else - { - type = GetParkMessageType(message["type"].as_string()); - text = message["text"].as_string(); - if (type == News::ItemType::Blank) - { - assoc = static_cast(((COORDS_NULL & 0xFFFF) << 16) | (COORDS_NULL & 0xFFFF)); - } - - auto dukSubject = message["subject"]; - if (dukSubject.type() == DukValue::Type::NUMBER) - { - assoc = static_cast(dukSubject.as_int()); - } - } - News::AddItemToQueue(type, text.c_str(), assoc); - } - catch (const DukException&) - { - duk_error(message.context(), DUK_ERR_ERROR, "Invalid message argument."); - } - } - - static void Register(duk_context* ctx) - { - dukglue_register_property(ctx, &ScPark::cash_get, &ScPark::cash_set, "cash"); - dukglue_register_property(ctx, &ScPark::rating_get, &ScPark::rating_set, "rating"); - dukglue_register_property(ctx, &ScPark::bankLoan_get, &ScPark::bankLoan_set, "bankLoan"); - dukglue_register_property(ctx, &ScPark::maxBankLoan_get, &ScPark::maxBankLoan_set, "maxBankLoan"); - dukglue_register_property(ctx, &ScPark::entranceFee_get, &ScPark::entranceFee_set, "entranceFee"); - dukglue_register_property(ctx, &ScPark::guests_get, nullptr, "guests"); - dukglue_register_property(ctx, &ScPark::suggestedGuestMaximum_get, nullptr, "suggestedGuestMaximum"); - dukglue_register_property(ctx, &ScPark::guestGenerationProbability_get, nullptr, "guestGenerationProbability"); - dukglue_register_property(ctx, &ScPark::guestInitialCash_get, nullptr, "guestInitialCash"); - dukglue_register_property(ctx, &ScPark::guestInitialHappiness_get, nullptr, "guestInitialHappiness"); - dukglue_register_property(ctx, &ScPark::guestInitialHunger_get, nullptr, "guestInitialHunger"); - dukglue_register_property(ctx, &ScPark::guestInitialThirst_get, nullptr, "guestInitialThirst"); - dukglue_register_property(ctx, &ScPark::value_get, &ScPark::value_set, "value"); - dukglue_register_property(ctx, &ScPark::companyValue_get, &ScPark::companyValue_set, "companyValue"); - dukglue_register_property(ctx, &ScPark::totalRideValueForMoney_get, nullptr, "totalRideValueForMoney"); - dukglue_register_property(ctx, &ScPark::totalAdmissions_get, &ScPark::totalAdmissions_set, "totalAdmissions"); - dukglue_register_property( - ctx, &ScPark::totalIncomeFromAdmissions_get, &ScPark::totalIncomeFromAdmissions_set, - "totalIncomeFromAdmissions"); - dukglue_register_property(ctx, &ScPark::landPrice_get, &ScPark::landPrice_set, "landPrice"); - dukglue_register_property( - ctx, &ScPark::constructionRightsPrice_get, &ScPark::constructionRightsPrice_set, "constructionRightsPrice"); - dukglue_register_property(ctx, &ScPark::parkSize_get, nullptr, "parkSize"); - dukglue_register_property(ctx, &ScPark::name_get, &ScPark::name_set, "name"); - dukglue_register_property(ctx, &ScPark::messages_get, &ScPark::messages_set, "messages"); - dukglue_register_property(ctx, &ScPark::casualtyPenalty_get, &ScPark::casualtyPenalty_set, "casualtyPenalty"); - dukglue_register_method(ctx, &ScPark::getFlag, "getFlag"); - dukglue_register_method(ctx, &ScPark::setFlag, "setFlag"); - dukglue_register_method(ctx, &ScPark::postMessage, "postMessage"); - } - }; -} // namespace OpenRCT2::Scripting - -#endif diff --git a/src/openrct2/scripting/ScRide.hpp b/src/openrct2/scripting/ScRide.hpp deleted file mode 100644 index 96043482da..0000000000 --- a/src/openrct2/scripting/ScRide.hpp +++ /dev/null @@ -1,695 +0,0 @@ -/***************************************************************************** - * Copyright (c) 2020 OpenRCT2 developers - * - * For a complete list of all authors, please refer to contributors.md - * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 - * - * OpenRCT2 is licensed under the GNU General Public License version 3. - *****************************************************************************/ - -#pragma once - -#ifdef ENABLE_SCRIPTING - -# include "../Context.h" -# include "../common.h" -# include "../ride/Ride.h" -# include "Duktape.hpp" -# include "ScObject.hpp" -# include "ScriptEngine.h" - -namespace OpenRCT2::Scripting -{ - template<> inline DukValue ToDuk(duk_context* ctx, const TrackColour& value) - { - DukObject obj(ctx); - obj.Set("main", value.main); - obj.Set("additional", value.additional); - obj.Set("supports", value.supports); - return obj.Take(); - } - - template<> TrackColour FromDuk(const DukValue& s) - { - TrackColour result{}; - result.main = AsOrDefault(s["main"], 0); - result.additional = AsOrDefault(s["additional"], 0); - result.supports = AsOrDefault(s["supports"], 0); - return result; - } - - template<> inline DukValue ToDuk(duk_context* ctx, const VehicleColour& value) - { - DukObject obj(ctx); - obj.Set("body", value.Body); - obj.Set("trim", value.Trim); - obj.Set("ternary", value.Ternary); - return obj.Take(); - } - - template<> VehicleColour FromDuk(const DukValue& s) - { - VehicleColour result{}; - result.Body = AsOrDefault(s["body"], 0); - result.Trim = AsOrDefault(s["trim"], 0); - result.Ternary = AsOrDefault(s["ternary"], 0); - return result; - } - - class ScRideStation - { - private: - ride_id_t _rideId = RIDE_ID_NULL; - StationIndex _stationIndex{}; - - public: - ScRideStation(ride_id_t rideId, StationIndex stationIndex) - : _rideId(rideId) - , _stationIndex(stationIndex) - { - } - - static void Register(duk_context* ctx) - { - dukglue_register_property(ctx, &ScRideStation::start_get, &ScRideStation::start_set, "start"); - dukglue_register_property(ctx, &ScRideStation::length_get, &ScRideStation::length_set, "length"); - dukglue_register_property(ctx, &ScRideStation::entrance_get, &ScRideStation::entrance_set, "entrance"); - dukglue_register_property(ctx, &ScRideStation::exit_get, &ScRideStation::exit_set, "exit"); - } - - private: - DukValue start_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto station = GetRideStation(); - if (station != nullptr) - { - auto start = CoordsXYZ(station->Start, station->GetBaseZ()); - return ToDuk(ctx, start); - } - return ToDuk(ctx, nullptr); - } - - void start_set(const DukValue& value) - { - auto station = GetRideStation(); - if (station != nullptr) - { - auto start = FromDuk(value); - station->Start = { start.x, start.y }; - station->SetBaseZ(start.z); - } - } - - int32_t length_get() const - { - auto station = GetRideStation(); - if (station != nullptr) - { - return station->Length; - } - return 0; - } - - void length_set(int32_t value) - { - auto station = GetRideStation(); - if (station != nullptr) - { - station->Length = value; - } - } - - DukValue entrance_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto station = GetRideStation(); - if (station != nullptr) - { - return ToDuk(ctx, station->Entrance.ToCoordsXYZD()); - } - return ToDuk(ctx, nullptr); - } - - void entrance_set(const DukValue& value) - { - auto station = GetRideStation(); - if (station != nullptr) - { - station->Entrance = FromDuk(value); - } - } - - DukValue exit_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto station = GetRideStation(); - if (station != nullptr) - { - return ToDuk(ctx, station->Exit.ToCoordsXYZD()); - } - return ToDuk(ctx, nullptr); - } - - void exit_set(const DukValue& value) - { - auto station = GetRideStation(); - if (station != nullptr) - { - station->Exit = FromDuk(value); - } - } - - RideStation* GetRideStation() const - { - auto ride = get_ride(_rideId); - if (ride != nullptr) - { - if (_stationIndex < std::size(ride->stations)) - { - return &ride->stations[_stationIndex]; - } - } - return nullptr; - } - }; - - class ScRide - { - private: - ride_id_t _rideId = RIDE_ID_NULL; - - public: - ScRide(ride_id_t rideId) - : _rideId(rideId) - { - } - - private: - int32_t id_get() const - { - return _rideId; - } - - std::shared_ptr object_get() - { - auto ride = GetRide(); - if (ride != nullptr) - { - auto rideObject = GetContext()->GetObjectManager().GetLoadedObject(ObjectType::Ride, ride->subtype); - if (rideObject != nullptr) - { - return std::make_shared(ObjectType::Ride, ride->subtype); - } - } - return nullptr; - } - - int32_t type_get() const - { - auto ride = GetRide(); - return ride != nullptr ? ride->type : 0; - } - - std::string classification_get() const - { - auto ride = GetRide(); - if (ride != nullptr) - { - switch (ride->GetClassification()) - { - case RideClassification::Ride: - return "ride"; - case RideClassification::ShopOrStall: - return "stall"; - case RideClassification::KioskOrFacility: - return "facility"; - } - } - return ""; - } - - std::string name_get() const - { - auto ride = GetRide(); - return ride != nullptr ? ride->GetName() : std::string(); - } - void name_set(std::string value) - { - ThrowIfGameStateNotMutable(); - auto ride = GetRide(); - if (ride != nullptr) - { - ride->custom_name = value; - } - } - - std::string status_get() const - { - auto ride = GetRide(); - if (ride != nullptr) - { - switch (ride->status) - { - case RideStatus::Closed: - return "closed"; - case RideStatus::Open: - return "open"; - case RideStatus::Testing: - return "testing"; - case RideStatus::Simulating: - return "simulating"; - case RideStatus::Count: // Meaningless but necessary to satisfy -Wswitch - return "count"; - } - } - return ""; - } - - uint32_t lifecycleFlags_get() const - { - auto ride = GetRide(); - return ride != nullptr ? ride->lifecycle_flags : 0; - } - - void lifecycleFlags_set(uint32_t value) - { - ThrowIfGameStateNotMutable(); - auto ride = GetRide(); - if (ride != nullptr) - { - ride->lifecycle_flags = value; - } - } - - uint8_t mode_get() const - { - auto ride = GetRide(); - return ride != nullptr ? static_cast(ride->mode) : 0; - } - - void mode_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto ride = GetRide(); - if (ride != nullptr) - { - ride->mode = static_cast(value); - } - } - - uint8_t departFlags_get() const - { - auto ride = GetRide(); - return ride != nullptr ? ride->depart_flags : 0; - } - - void departFlags_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto ride = GetRide(); - if (ride != nullptr) - { - ride->depart_flags = value; - } - } - - uint8_t minimumWaitingTime_get() const - { - auto ride = GetRide(); - return ride != nullptr ? ride->min_waiting_time : 0; - } - - void minimumWaitingTime_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto ride = GetRide(); - if (ride != nullptr) - { - ride->min_waiting_time = value; - } - } - - uint8_t maximumWaitingTime_get() const - { - auto ride = GetRide(); - return ride != nullptr ? ride->max_waiting_time : 0; - } - - void maximumWaitingTime_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto ride = GetRide(); - if (ride != nullptr) - { - ride->max_waiting_time = value; - } - } - - std::vector vehicles_get() const - { - std::vector result; - auto ride = GetRide(); - if (ride != nullptr) - { - result.insert(result.begin(), std::begin(ride->vehicles), std::begin(ride->vehicles) + ride->num_vehicles); - } - return result; - } - - std::vector vehicleColours_get() const - { - std::vector result; - auto ride = GetRide(); - if (ride != nullptr) - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - for (const auto& vehicleColour : ride->vehicle_colours) - { - result.push_back(ToDuk(ctx, vehicleColour)); - } - } - return result; - } - - void vehicleColours_set(const std::vector& value) - { - auto ride = GetRide(); - if (ride != nullptr) - { - auto count = std::min(value.size(), std::size(ride->vehicle_colours)); - for (size_t i = 0; i < count; i++) - { - ride->vehicle_colours[i] = FromDuk(value[i]); - } - } - } - - std::vector colourSchemes_get() const - { - std::vector result; - auto ride = GetRide(); - if (ride != nullptr) - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - for (const auto& trackColour : ride->track_colour) - { - result.push_back(ToDuk(ctx, trackColour)); - } - } - return result; - } - - void colourSchemes_set(const std::vector& value) - { - auto ride = GetRide(); - if (ride != nullptr) - { - auto count = std::min(value.size(), std::size(ride->track_colour)); - for (size_t i = 0; i < count; i++) - { - ride->track_colour[i] = FromDuk(value[i]); - } - } - } - - uint8_t stationStyle_get() const - { - auto ride = GetRide(); - return ride != nullptr ? ride->entrance_style : 0; - } - - void stationStyle_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto ride = GetRide(); - if (ride != nullptr) - { - ride->entrance_style = value; - } - } - - uint8_t music_get() const - { - auto ride = GetRide(); - return ride != nullptr ? ride->music : 0; - } - - void music_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto ride = GetRide(); - if (ride != nullptr) - { - ride->music = value; - } - } - - std::vector> stations_get() const - { - std::vector> result; - auto ride = GetRide(); - if (ride != nullptr) - { - for (size_t i = 0; i < std::size(ride->stations); i++) - { - result.push_back(std::make_shared(ride->id, static_cast(i))); - } - } - return result; - } - - std::vector price_get() const - { - std::vector result; - auto ride = GetRide(); - if (ride != nullptr) - { - auto numPrices = ride->GetNumPrices(); - for (size_t i = 0; i < numPrices; i++) - { - result.push_back(ride->price[i]); - }; - } - return result; - } - - void price_set(const std::vector& value) - { - ThrowIfGameStateNotMutable(); - auto ride = GetRide(); - if (ride != nullptr) - { - auto numPrices = std::min(value.size(), ride->GetNumPrices()); - for (size_t i = 0; i < numPrices; i++) - { - ride->price[i] = static_cast(value[i]); - } - } - } - - int32_t excitement_get() const - { - auto ride = GetRide(); - return ride != nullptr ? ride->excitement : 0; - } - void excitement_set(int32_t value) - { - ThrowIfGameStateNotMutable(); - auto ride = GetRide(); - if (ride != nullptr) - { - ride->excitement = value; - } - } - - int32_t intensity_get() const - { - auto ride = GetRide(); - return ride != nullptr ? ride->intensity : 0; - } - void intensity_set(int32_t value) - { - ThrowIfGameStateNotMutable(); - auto ride = GetRide(); - if (ride != nullptr) - { - ride->intensity = value; - } - } - - int32_t nausea_get() const - { - auto ride = GetRide(); - return ride != nullptr ? ride->nausea : 0; - } - void nausea_set(int32_t value) - { - ThrowIfGameStateNotMutable(); - auto ride = GetRide(); - if (ride != nullptr) - { - ride->nausea = value; - } - } - - int32_t totalCustomers_get() const - { - auto ride = GetRide(); - return ride != nullptr ? ride->total_customers : 0; - } - void totalCustomers_set(int32_t value) - { - ThrowIfGameStateNotMutable(); - auto ride = GetRide(); - if (ride != nullptr) - { - ride->total_customers = value; - } - } - - int32_t buildDate_get() const - { - auto ride = GetRide(); - return ride != nullptr ? ride->build_date : 0; - } - void buildDate_set(int32_t value) - { - ThrowIfGameStateNotMutable(); - auto ride = GetRide(); - if (ride != nullptr) - { - ride->build_date = value; - } - } - - int32_t age_get() const - { - auto ride = GetRide(); - return ride != nullptr ? ride->GetAge() : 0; - } - - int16_t runningCost_get() const - { - auto ride = GetRide(); - return ride != nullptr ? ride->upkeep_cost : 0; - } - void runningCost_set(int16_t value) - { - ThrowIfGameStateNotMutable(); - auto ride = GetRide(); - if (ride != nullptr) - { - ride->upkeep_cost = value; - } - } - - int32_t totalProfit_get() const - { - auto ride = GetRide(); - return ride != nullptr ? ride->total_profit : 0; - } - void totalProfit_set(int32_t value) - { - ThrowIfGameStateNotMutable(); - auto ride = GetRide(); - if (ride != nullptr) - { - ride->total_profit = value; - } - } - - uint8_t inspectionInterval_get() const - { - auto ride = GetRide(); - return ride != nullptr ? ride->inspection_interval : 0; - } - void inspectionInterval_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto ride = GetRide(); - if (ride != nullptr) - { - ride->inspection_interval = std::clamp(value, RIDE_INSPECTION_EVERY_10_MINUTES, RIDE_INSPECTION_NEVER); - } - } - - DukValue value_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto ride = GetRide(); - if (ride != nullptr && ride->value != RIDE_VALUE_UNDEFINED) - { - return ToDuk(ctx, ride->value); - } - return ToDuk(ctx, nullptr); - } - - void value_set(const DukValue& value) - { - ThrowIfGameStateNotMutable(); - auto ride = GetRide(); - if (ride != nullptr) - { - if (value.type() == DukValue::Type::NUMBER) - { - ride->value = value.as_int(); - } - else - { - ride->value = RIDE_VALUE_UNDEFINED; - } - } - } - - uint8_t downtime_get() const - { - auto ride = GetRide(); - return ride != nullptr ? ride->downtime : 0; - } - - Ride* GetRide() const - { - return get_ride(_rideId); - } - - public: - static void Register(duk_context* ctx) - { - dukglue_register_property(ctx, &ScRide::id_get, nullptr, "id"); - dukglue_register_property(ctx, &ScRide::object_get, nullptr, "object"); - dukglue_register_property(ctx, &ScRide::type_get, nullptr, "type"); - dukglue_register_property(ctx, &ScRide::classification_get, nullptr, "classification"); - dukglue_register_property(ctx, &ScRide::name_get, &ScRide::name_set, "name"); - dukglue_register_property(ctx, &ScRide::status_get, nullptr, "status"); - dukglue_register_property(ctx, &ScRide::lifecycleFlags_get, &ScRide::lifecycleFlags_set, "lifecycleFlags"); - dukglue_register_property(ctx, &ScRide::mode_get, &ScRide::mode_set, "mode"); - dukglue_register_property(ctx, &ScRide::departFlags_get, &ScRide::departFlags_set, "departFlags"); - dukglue_register_property( - ctx, &ScRide::minimumWaitingTime_get, &ScRide::minimumWaitingTime_set, "minimumWaitingTime"); - dukglue_register_property( - ctx, &ScRide::maximumWaitingTime_get, &ScRide::maximumWaitingTime_set, "maximumWaitingTime"); - dukglue_register_property(ctx, &ScRide::vehicles_get, nullptr, "vehicles"); - dukglue_register_property(ctx, &ScRide::vehicleColours_get, &ScRide::vehicleColours_set, "vehicleColours"); - dukglue_register_property(ctx, &ScRide::colourSchemes_get, &ScRide::colourSchemes_set, "colourSchemes"); - dukglue_register_property(ctx, &ScRide::stationStyle_get, &ScRide::stationStyle_set, "stationStyle"); - dukglue_register_property(ctx, &ScRide::music_get, &ScRide::music_set, "music"); - dukglue_register_property(ctx, &ScRide::stations_get, nullptr, "stations"); - dukglue_register_property(ctx, &ScRide::price_get, &ScRide::price_set, "price"); - dukglue_register_property(ctx, &ScRide::excitement_get, &ScRide::excitement_set, "excitement"); - dukglue_register_property(ctx, &ScRide::intensity_get, &ScRide::intensity_set, "intensity"); - dukglue_register_property(ctx, &ScRide::nausea_get, &ScRide::nausea_set, "nausea"); - dukglue_register_property(ctx, &ScRide::totalCustomers_get, &ScRide::totalCustomers_set, "totalCustomers"); - dukglue_register_property(ctx, &ScRide::buildDate_get, &ScRide::buildDate_set, "buildDate"); - dukglue_register_property(ctx, &ScRide::age_get, nullptr, "age"); - dukglue_register_property(ctx, &ScRide::runningCost_get, &ScRide::runningCost_set, "runningCost"); - dukglue_register_property(ctx, &ScRide::totalProfit_get, &ScRide::totalProfit_set, "totalProfit"); - dukglue_register_property( - ctx, &ScRide::inspectionInterval_get, &ScRide::inspectionInterval_set, "inspectionInterval"); - dukglue_register_property(ctx, &ScRide::value_get, &ScRide::value_set, "value"); - dukglue_register_property(ctx, &ScRide::downtime_get, nullptr, "downtime"); - } - }; -} // namespace OpenRCT2::Scripting - -#endif diff --git a/src/openrct2/scripting/ScTile.hpp b/src/openrct2/scripting/ScTile.hpp deleted file mode 100644 index e4dad4855b..0000000000 --- a/src/openrct2/scripting/ScTile.hpp +++ /dev/null @@ -1,1800 +0,0 @@ -/***************************************************************************** - * Copyright (c) 2014-2020 OpenRCT2 developers - * - * For a complete list of all authors, please refer to contributors.md - * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 - * - * OpenRCT2 is licensed under the GNU General Public License version 3. - *****************************************************************************/ - -#pragma once - -#ifdef ENABLE_SCRIPTING - -# include "../Context.h" -# include "../common.h" -# include "../core/Guard.hpp" -# include "../ride/Track.h" -# include "../world/Footpath.h" -# include "../world/Scenery.h" -# include "../world/Sprite.h" -# include "../world/Surface.h" -# include "Duktape.hpp" -# include "ScriptEngine.h" - -# include -# include -# include - -namespace OpenRCT2::Scripting -{ - class ScSurfaceElement; - - class ScTileElement - { - protected: - CoordsXY _coords; - TileElement* _element; - - public: - ScTileElement(const CoordsXY& coords, TileElement* element) - : _coords(coords) - , _element(element) - { - } - - private: - std::string type_get() const - { - switch (_element->GetType()) - { - case TILE_ELEMENT_TYPE_SURFACE: - return "surface"; - case TILE_ELEMENT_TYPE_PATH: - return "footpath"; - case TILE_ELEMENT_TYPE_TRACK: - return "track"; - case TILE_ELEMENT_TYPE_SMALL_SCENERY: - return "small_scenery"; - case TILE_ELEMENT_TYPE_ENTRANCE: - return "entrance"; - case TILE_ELEMENT_TYPE_WALL: - return "wall"; - case TILE_ELEMENT_TYPE_LARGE_SCENERY: - return "large_scenery"; - case TILE_ELEMENT_TYPE_BANNER: - return "banner"; - case TILE_ELEMENT_TYPE_CORRUPT: - return "openrct2_corrupt_deprecated"; - default: - return "unknown"; - } - } - - void type_set(std::string value) - { - auto type = _element->type; - if (value == "surface") - type = TILE_ELEMENT_TYPE_SURFACE; - else if (value == "footpath") - type = TILE_ELEMENT_TYPE_PATH; - else if (value == "track") - type = TILE_ELEMENT_TYPE_TRACK; - else if (value == "small_scenery") - type = TILE_ELEMENT_TYPE_SMALL_SCENERY; - else if (value == "entrance") - type = TILE_ELEMENT_TYPE_ENTRANCE; - else if (value == "wall") - type = TILE_ELEMENT_TYPE_WALL; - else if (value == "large_scenery") - type = TILE_ELEMENT_TYPE_LARGE_SCENERY; - else if (value == "banner") - type = TILE_ELEMENT_TYPE_BANNER; - else - { - if (value == "openrct2_corrupt_deprecated") - std::puts( - "Creation of new corrupt elements is deprecated. To hide elements, use the 'hidden' property instead."); - return; - } - - _element->type = type; - Invalidate(); - } - - uint8_t baseHeight_get() const - { - return _element->base_height; - } - void baseHeight_set(uint8_t newBaseHeight) - { - ThrowIfGameStateNotMutable(); - _element->base_height = newBaseHeight; - Invalidate(); - } - - uint16_t baseZ_get() const - { - return _element->GetBaseZ(); - } - void baseZ_set(uint16_t value) - { - ThrowIfGameStateNotMutable(); - _element->SetBaseZ(value); - Invalidate(); - } - - uint8_t clearanceHeight_get() const - { - return _element->clearance_height; - } - void clearanceHeight_set(uint8_t newClearanceHeight) - { - ThrowIfGameStateNotMutable(); - _element->clearance_height = newClearanceHeight; - Invalidate(); - } - - uint16_t clearanceZ_get() const - { - return _element->GetClearanceZ(); - } - void clearanceZ_set(uint16_t value) - { - ThrowIfGameStateNotMutable(); - _element->SetClearanceZ(value); - Invalidate(); - } - - DukValue slope_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - switch (_element->GetType()) - { - case TILE_ELEMENT_TYPE_SURFACE: - { - auto el = _element->AsSurface(); - duk_push_int(ctx, el->GetSlope()); - break; - } - case TILE_ELEMENT_TYPE_WALL: - { - auto el = _element->AsWall(); - duk_push_int(ctx, el->GetSlope()); - break; - } - default: - { - duk_push_null(ctx); - break; - } - } - return DukValue::take_from_stack(ctx); - } - void slope_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - switch (_element->GetType()) - { - case TILE_ELEMENT_TYPE_SURFACE: - { - auto el = _element->AsSurface(); - el->SetSlope(value); - Invalidate(); - break; - } - case TILE_ELEMENT_TYPE_WALL: - { - auto el = _element->AsWall(); - el->SetSlope(value); - Invalidate(); - break; - } - } - } - - DukValue waterHeight_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsSurface(); - if (el != nullptr) - duk_push_int(ctx, el->GetWaterHeight()); - else - duk_push_null(ctx); - return DukValue::take_from_stack(ctx); - } - void waterHeight_set(int32_t value) - { - ThrowIfGameStateNotMutable(); - auto el = _element->AsSurface(); - if (el != nullptr) - { - el->SetWaterHeight(value); - Invalidate(); - } - } - - DukValue surfaceStyle_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsSurface(); - if (el != nullptr) - duk_push_int(ctx, el->GetSurfaceStyle()); - else - duk_push_null(ctx); - return DukValue::take_from_stack(ctx); - } - void surfaceStyle_set(uint32_t value) - { - ThrowIfGameStateNotMutable(); - auto el = _element->AsSurface(); - if (el != nullptr) - { - el->SetSurfaceStyle(value); - Invalidate(); - } - } - - DukValue edgeStyle_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsSurface(); - if (el != nullptr) - duk_push_int(ctx, el->GetEdgeStyle()); - else - duk_push_null(ctx); - return DukValue::take_from_stack(ctx); - } - void edgeStyle_set(uint32_t value) - { - ThrowIfGameStateNotMutable(); - auto el = _element->AsSurface(); - if (el != nullptr) - { - el->SetEdgeStyle(value); - Invalidate(); - } - } - - DukValue grassLength_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsSurface(); - if (el != nullptr) - duk_push_int(ctx, el->GetGrassLength()); - else - duk_push_null(ctx); - return DukValue::take_from_stack(ctx); - } - void grassLength_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto el = _element->AsSurface(); - if (el != nullptr) - { - // TODO: Give warning when value > GRASS_LENGTH_CLUMPS_2 - el->SetGrassLengthAndInvalidate(value, _coords); - Invalidate(); - } - } - - DukValue hasOwnership_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsSurface(); - if (el != nullptr) - duk_push_boolean(ctx, el->GetOwnership() & OWNERSHIP_OWNED); - else - duk_push_null(ctx); - return DukValue::take_from_stack(ctx); - } - - DukValue hasConstructionRights_get() - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsSurface(); - if (el != nullptr) - { - auto ownership = el->GetOwnership(); - duk_push_boolean(ctx, (ownership & OWNERSHIP_OWNED) || (ownership & OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED)); - } - else - duk_push_null(ctx); - return DukValue::take_from_stack(ctx); - } - - DukValue ownership_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsSurface(); - if (el != nullptr) - duk_push_int(ctx, el->GetOwnership()); - else - duk_push_null(ctx); - return DukValue::take_from_stack(ctx); - } - void ownership_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto el = _element->AsSurface(); - if (el != nullptr) - { - el->SetOwnership(value); - Invalidate(); - } - } - - DukValue parkFences_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsSurface(); - if (el != nullptr) - duk_push_int(ctx, el->GetParkFences()); - else - duk_push_null(ctx); - return DukValue::take_from_stack(ctx); - } - void parkFences_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto el = _element->AsSurface(); - if (el != nullptr) - { - el->SetParkFences(value); - Invalidate(); - } - } - - DukValue trackType_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsTrack(); - if (el != nullptr) - duk_push_int(ctx, el->GetTrackType()); - else - duk_push_null(ctx); - return DukValue::take_from_stack(ctx); - } - void trackType_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto el = _element->AsTrack(); - if (el != nullptr) - { - el->SetTrackType(value); - Invalidate(); - } - } - - DukValue sequence_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - switch (_element->GetType()) - { - case TILE_ELEMENT_TYPE_LARGE_SCENERY: - { - auto el = _element->AsLargeScenery(); - duk_push_int(ctx, el->GetSequenceIndex()); - break; - } - case TILE_ELEMENT_TYPE_TRACK: - { - auto el = _element->AsTrack(); - if (get_ride(el->GetRideIndex())->type != RIDE_TYPE_MAZE) - duk_push_int(ctx, el->GetSequenceIndex()); - else - duk_push_null(ctx); - break; - } - case TILE_ELEMENT_TYPE_ENTRANCE: - { - auto el = _element->AsEntrance(); - duk_push_int(ctx, el->GetSequenceIndex()); - break; - } - default: - { - duk_push_null(ctx); - break; - } - } - return DukValue::take_from_stack(ctx); - } - void sequence_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - switch (_element->GetType()) - { - case TILE_ELEMENT_TYPE_LARGE_SCENERY: - { - auto el = _element->AsLargeScenery(); - el->SetSequenceIndex(value); - Invalidate(); - break; - } - case TILE_ELEMENT_TYPE_TRACK: - { - auto el = _element->AsTrack(); - if (get_ride(el->GetRideIndex())->type != RIDE_TYPE_MAZE) - { - el->SetSequenceIndex(value); - Invalidate(); - } - break; - } - case TILE_ELEMENT_TYPE_ENTRANCE: - { - auto el = _element->AsEntrance(); - el->SetSequenceIndex(value); - Invalidate(); - break; - } - } - } - - DukValue ride_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - switch (_element->GetType()) - { - case TILE_ELEMENT_TYPE_PATH: - { - auto el = _element->AsPath(); - if (el->IsQueue() && el->GetRideIndex() != RIDE_ID_NULL) - duk_push_int(ctx, el->GetRideIndex()); - else - duk_push_null(ctx); - break; - } - case TILE_ELEMENT_TYPE_TRACK: - { - auto el = _element->AsTrack(); - duk_push_int(ctx, el->GetRideIndex()); - break; - } - case TILE_ELEMENT_TYPE_ENTRANCE: - { - auto el = _element->AsEntrance(); - duk_push_int(ctx, el->GetRideIndex()); - break; - } - default: - { - duk_push_null(ctx); - break; - } - } - return DukValue::take_from_stack(ctx); - } - void ride_set(ride_id_t value) - { - ThrowIfGameStateNotMutable(); - switch (_element->GetType()) - { - case TILE_ELEMENT_TYPE_PATH: - { - auto el = _element->AsPath(); - if (!el->HasAddition()) - { - el->SetRideIndex(value); - Invalidate(); - } - break; - } - case TILE_ELEMENT_TYPE_TRACK: - { - auto el = _element->AsTrack(); - el->SetRideIndex(value); - Invalidate(); - break; - } - case TILE_ELEMENT_TYPE_ENTRANCE: - { - auto el = _element->AsEntrance(); - el->SetRideIndex(value); - Invalidate(); - break; - } - } - } - - DukValue station_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - switch (_element->GetType()) - { - case TILE_ELEMENT_TYPE_PATH: - { - auto el = _element->AsPath(); - if (el->IsQueue() && el->GetRideIndex() != RIDE_ID_NULL) - duk_push_int(ctx, el->GetStationIndex()); - else - duk_push_null(ctx); - break; - } - case TILE_ELEMENT_TYPE_TRACK: - { - auto el = _element->AsTrack(); - if (el->IsStation()) - duk_push_int(ctx, el->GetStationIndex()); - else - duk_push_null(ctx); - break; - } - case TILE_ELEMENT_TYPE_ENTRANCE: - { - auto el = _element->AsEntrance(); - duk_push_int(ctx, el->GetStationIndex()); - break; - } - default: - { - duk_push_null(ctx); - break; - } - } - return DukValue::take_from_stack(ctx); - } - void station_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - switch (_element->GetType()) - { - case TILE_ELEMENT_TYPE_PATH: - { - auto el = _element->AsPath(); - el->SetStationIndex(value); - Invalidate(); - break; - } - case TILE_ELEMENT_TYPE_TRACK: - { - auto el = _element->AsTrack(); - el->SetStationIndex(value); - Invalidate(); - break; - } - case TILE_ELEMENT_TYPE_ENTRANCE: - { - auto el = _element->AsEntrance(); - el->SetStationIndex(value); - Invalidate(); - break; - } - } - } - - DukValue hasChainLift_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsTrack(); - if (el != nullptr) - duk_push_boolean(ctx, el->HasChain()); - else - duk_push_null(ctx); - return DukValue::take_from_stack(ctx); - } - void hasChainLift_set(bool value) - { - ThrowIfGameStateNotMutable(); - auto el = _element->AsTrack(); - if (el != nullptr) - { - el->SetHasChain(value); - Invalidate(); - } - } - - DukValue mazeEntry_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsTrack(); - if (el != nullptr && get_ride(el->GetRideIndex())->type == RIDE_TYPE_MAZE) - duk_push_int(ctx, el->GetMazeEntry()); - else - duk_push_null(ctx); - return DukValue::take_from_stack(ctx); - } - void mazeEntry_set(uint16_t value) - { - ThrowIfGameStateNotMutable(); - auto el = _element->AsTrack(); - if (el != nullptr) - if (get_ride(el->GetRideIndex())->type == RIDE_TYPE_MAZE) - { - el->SetMazeEntry(value); - Invalidate(); - } - } - - DukValue colourScheme_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsTrack(); - if (el != nullptr && get_ride(el->GetRideIndex())->type != RIDE_TYPE_MAZE) - duk_push_int(ctx, el->GetColourScheme()); - else - duk_push_null(ctx); - return DukValue::take_from_stack(ctx); - } - void colourScheme_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto el = _element->AsTrack(); - if (el != nullptr) - if (get_ride(el->GetRideIndex())->type != RIDE_TYPE_MAZE) - { - el->SetColourScheme(value); - Invalidate(); - } - } - - DukValue seatRotation_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsTrack(); - if (el != nullptr && get_ride(el->GetRideIndex())->type != RIDE_TYPE_MAZE) - duk_push_int(ctx, el->GetSeatRotation()); - else - duk_push_null(ctx); - return DukValue::take_from_stack(ctx); - } - void seatRotation_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto el = _element->AsTrack(); - if (el != nullptr) - if (get_ride(el->GetRideIndex())->type != RIDE_TYPE_MAZE) - { - el->SetSeatRotation(value); - Invalidate(); - } - } - - DukValue brakeBoosterSpeed_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsTrack(); - if (el != nullptr && TrackTypeHasSpeedSetting(el->GetTrackType())) - duk_push_int(ctx, el->GetBrakeBoosterSpeed()); - else - duk_push_null(ctx); - return DukValue::take_from_stack(ctx); - } - void brakeBoosterSpeed_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto el = _element->AsTrack(); - if (el != nullptr) - if (TrackTypeHasSpeedSetting(el->GetTrackType())) - { - el->SetBrakeBoosterSpeed(value); - Invalidate(); - } - } - - DukValue isInverted_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsTrack(); - if (el != nullptr) - duk_push_boolean(ctx, el->IsInverted()); - else - duk_push_null(ctx); - return DukValue::take_from_stack(ctx); - } - void isInverted_set(bool value) - { - ThrowIfGameStateNotMutable(); - auto el = _element->AsTrack(); - if (el != nullptr) - { - el->SetInverted(value); - Invalidate(); - } - } - - DukValue hasCableLift_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsTrack(); - if (el != nullptr) - duk_push_boolean(ctx, el->HasCableLift()); - else - duk_push_null(ctx); - return DukValue::take_from_stack(ctx); - } - void hasCableLift_set(bool value) - { - ThrowIfGameStateNotMutable(); - auto el = _element->AsTrack(); - if (el != nullptr) - { - el->SetHasCableLift(value); - Invalidate(); - } - } - - DukValue object_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - switch (_element->GetType()) - { - case TILE_ELEMENT_TYPE_PATH: - { - auto el = _element->AsPath(); - duk_push_int(ctx, el->GetSurfaceEntryIndex()); - break; - } - case TILE_ELEMENT_TYPE_SMALL_SCENERY: - { - auto el = _element->AsSmallScenery(); - duk_push_int(ctx, el->GetEntryIndex()); - break; - } - case TILE_ELEMENT_TYPE_LARGE_SCENERY: - { - auto el = _element->AsLargeScenery(); - duk_push_int(ctx, el->GetEntryIndex()); - break; - } - case TILE_ELEMENT_TYPE_WALL: - { - auto el = _element->AsWall(); - duk_push_int(ctx, el->GetEntryIndex()); - break; - } - case TILE_ELEMENT_TYPE_ENTRANCE: - { - auto el = _element->AsEntrance(); - duk_push_int(ctx, el->GetEntranceType()); - break; - } - default: - { - duk_push_null(ctx); - break; - } - } - return DukValue::take_from_stack(ctx); - } - void object_set(uint32_t value) - { - ThrowIfGameStateNotMutable(); - switch (_element->GetType()) - { - case TILE_ELEMENT_TYPE_PATH: - { - auto el = _element->AsPath(); - el->SetSurfaceEntryIndex(value & 0xFF); - Invalidate(); - break; - } - case TILE_ELEMENT_TYPE_SMALL_SCENERY: - { - auto el = _element->AsSmallScenery(); - el->SetEntryIndex(value & 0xFF); - Invalidate(); - break; - } - case TILE_ELEMENT_TYPE_LARGE_SCENERY: - { - auto el = _element->AsLargeScenery(); - el->SetEntryIndex(value); - Invalidate(); - break; - } - case TILE_ELEMENT_TYPE_WALL: - { - auto el = _element->AsWall(); - el->SetEntryIndex(value & 0xFFFF); - Invalidate(); - break; - } - case TILE_ELEMENT_TYPE_ENTRANCE: - { - auto el = _element->AsEntrance(); - el->SetEntranceType(value & 0xFF); - Invalidate(); - break; - } - } - } - - bool isHidden_get() const - { - // TODO: Simply return the 'hidden' field once corrupt elements are superseded. - const TileElement* element = map_get_first_element_at(_coords); - bool previousElementWasUsefulCorrupt = false; - do - { - if (element == _element) - return previousElementWasUsefulCorrupt; - - if (element->GetType() == TILE_ELEMENT_TYPE_CORRUPT) - previousElementWasUsefulCorrupt = !previousElementWasUsefulCorrupt; - else - previousElementWasUsefulCorrupt = false; - } while (!(element++)->IsLastForTile()); - - Guard::Assert(false); - return false; - } - void isHidden_set(bool hide) - { - // TODO: Simply update the 'hidden' field once corrupt elements are superseded. - ThrowIfGameStateNotMutable(); - const bool isHidden = isHidden_get(); - if (hide == isHidden) - return; - - if (hide) - { - // Get index of our current element (has to be done now before inserting the corrupt element) - const auto elementIndex = _element - map_get_first_element_at(_coords); - - // Insert corrupt element at the end of the list for this tile - // Note: Z = MAX_ELEMENT_HEIGHT to guarantee this - TileElement* insertedElement = tile_element_insert( - { _coords, MAX_ELEMENT_HEIGHT * COORDS_Z_STEP }, 0, TileElementType::Corrupt); - if (insertedElement == nullptr) - { - // TODO: Show error - return; - } - - // Since inserting a new element may move the tile elements in memory, we have to update the local pointer - _element = map_get_first_element_at(_coords) + elementIndex; - - // Move the corrupt element down in the list until it's right under our element - while (insertedElement > _element) - { - std::swap(*insertedElement, *(insertedElement - 1)); - insertedElement--; - - // Un-swap the last-for-tile flag - if (insertedElement->IsLastForTile()) - { - insertedElement->SetLastForTile(false); - (insertedElement + 1)->SetLastForTile(true); - } - } - - // Now the corrupt element took the hidden element's place, increment it by one - _element++; - - // Update base and clearance heights of inserted corrupt element to match the element to hide - insertedElement->base_height = insertedElement->clearance_height = _element->base_height; - } - else - { - TileElement* const elementToRemove = _element - 1; - Guard::Assert(elementToRemove->GetType() == TILE_ELEMENT_TYPE_CORRUPT); - tile_element_remove(elementToRemove); - _element--; - } - - Invalidate(); - } - - DukValue age_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsSmallScenery(); - if (el != nullptr) - duk_push_int(ctx, el->GetAge()); - else - duk_push_null(ctx); - return DukValue::take_from_stack(ctx); - } - void age_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto el = _element->AsSmallScenery(); - if (el != nullptr) - { - el->SetAge(value); - Invalidate(); - } - } - - DukValue quadrant_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsSmallScenery(); - if (el != nullptr) - duk_push_int(ctx, el->GetSceneryQuadrant()); - else - duk_push_null(ctx); - return DukValue::take_from_stack(ctx); - } - void quadrant_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto el = _element->AsSmallScenery(); - if (el != nullptr) - { - el->SetSceneryQuadrant(value); - Invalidate(); - } - } - - uint8_t occupiedQuadrants_get() const - { - return _element->GetOccupiedQuadrants(); - } - void occupiedQuadrants_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - _element->SetOccupiedQuadrants(value); - Invalidate(); - } - - bool isGhost_get() const - { - return _element->IsGhost(); - } - void isGhost_set(bool value) - { - ThrowIfGameStateNotMutable(); - _element->SetGhost(value); - Invalidate(); - } - - DukValue primaryColour_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - switch (_element->GetType()) - { - case TILE_ELEMENT_TYPE_SMALL_SCENERY: - { - auto el = _element->AsSmallScenery(); - duk_push_int(ctx, el->GetPrimaryColour()); - break; - } - case TILE_ELEMENT_TYPE_LARGE_SCENERY: - { - auto el = _element->AsLargeScenery(); - duk_push_int(ctx, el->GetPrimaryColour()); - break; - } - case TILE_ELEMENT_TYPE_WALL: - { - auto el = _element->AsWall(); - duk_push_int(ctx, el->GetPrimaryColour()); - break; - } - default: - { - duk_push_null(ctx); - break; - } - } - return DukValue::take_from_stack(ctx); - } - void primaryColour_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - switch (_element->GetType()) - { - case TILE_ELEMENT_TYPE_SMALL_SCENERY: - { - auto el = _element->AsSmallScenery(); - el->SetPrimaryColour(value); - Invalidate(); - break; - } - case TILE_ELEMENT_TYPE_LARGE_SCENERY: - { - auto el = _element->AsLargeScenery(); - el->SetPrimaryColour(value); - Invalidate(); - break; - } - case TILE_ELEMENT_TYPE_WALL: - { - auto el = _element->AsWall(); - el->SetPrimaryColour(value); - Invalidate(); - break; - } - } - } - - DukValue secondaryColour_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - switch (_element->GetType()) - { - case TILE_ELEMENT_TYPE_SMALL_SCENERY: - { - auto el = _element->AsSmallScenery(); - duk_push_int(ctx, el->GetSecondaryColour()); - break; - } - case TILE_ELEMENT_TYPE_LARGE_SCENERY: - { - auto el = _element->AsLargeScenery(); - duk_push_int(ctx, el->GetSecondaryColour()); - break; - } - case TILE_ELEMENT_TYPE_WALL: - { - auto el = _element->AsWall(); - duk_push_int(ctx, el->GetSecondaryColour()); - break; - } - default: - { - duk_push_null(ctx); - break; - } - } - return DukValue::take_from_stack(ctx); - } - void secondaryColour_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - switch (_element->GetType()) - { - case TILE_ELEMENT_TYPE_SMALL_SCENERY: - { - auto el = _element->AsSmallScenery(); - el->SetSecondaryColour(value); - Invalidate(); - break; - } - case TILE_ELEMENT_TYPE_LARGE_SCENERY: - { - auto el = _element->AsLargeScenery(); - el->SetSecondaryColour(value); - Invalidate(); - break; - } - case TILE_ELEMENT_TYPE_WALL: - { - auto el = _element->AsWall(); - el->SetSecondaryColour(value); - Invalidate(); - break; - } - } - } - - DukValue tertiaryColour_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsWall(); - if (el != nullptr) - duk_push_int(ctx, el->GetTertiaryColour()); - else - duk_push_null(ctx); - return DukValue::take_from_stack(ctx); - } - void tertiaryColour_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto el = _element->AsWall(); - if (el != nullptr) - { - el->SetTertiaryColour(value); - Invalidate(); - } - } - - DukValue bannerIndex_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - BannerIndex idx = _element->GetBannerIndex(); - if (idx == BANNER_INDEX_NULL) - duk_push_null(ctx); - else - duk_push_int(ctx, idx); - return DukValue::take_from_stack(ctx); - } - void bannerIndex_set(uint16_t value) - { - ThrowIfGameStateNotMutable(); - switch (_element->GetType()) - { - case TILE_ELEMENT_TYPE_LARGE_SCENERY: - { - auto el = _element->AsLargeScenery(); - el->SetBannerIndex(value); - Invalidate(); - break; - } - case TILE_ELEMENT_TYPE_WALL: - { - auto el = _element->AsWall(); - el->SetBannerIndex(value); - Invalidate(); - break; - } - case TILE_ELEMENT_TYPE_BANNER: - { - auto el = _element->AsBanner(); - el->SetIndex(value); - Invalidate(); - break; - } - } - } - - // Deprecated in favor of seperate 'edges' and 'corners' properties, - // left here to maintain compatibility with older plugins. - /** @deprecated */ - uint8_t edgesAndCorners_get() const - { - auto el = _element->AsPath(); - return el != nullptr ? el->GetEdgesAndCorners() : 0; - } - /** @deprecated */ - void edgesAndCorners_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto el = _element->AsPath(); - if (el != nullptr) - { - el->SetEdgesAndCorners(value); - Invalidate(); - } - } - - DukValue edges_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsPath(); - if (el != nullptr) - duk_push_int(ctx, el->GetEdges()); - else - duk_push_null(ctx); - return DukValue::take_from_stack(ctx); - } - void edges_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto el = _element->AsPath(); - if (el != nullptr) - { - el->SetEdges(value); - Invalidate(); - } - } - - DukValue corners_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsPath(); - if (el != nullptr) - duk_push_int(ctx, el->GetCorners()); - else - duk_push_null(ctx); - return DukValue::take_from_stack(ctx); - } - void corners_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto el = _element->AsPath(); - if (el != nullptr) - { - el->SetCorners(value); - Invalidate(); - } - } - - DukValue slopeDirection_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsPath(); - if (el != nullptr && el->IsSloped()) - duk_push_int(ctx, el->GetSlopeDirection()); - else - duk_push_null(ctx); - return DukValue::take_from_stack(ctx); - } - void slopeDirection_set(const DukValue& value) - { - ThrowIfGameStateNotMutable(); - auto el = _element->AsPath(); - if (el != nullptr) - { - if (value.type() == DukValue::Type::NUMBER) - { - el->SetSloped(true); - el->SetSlopeDirection(value.as_int()); - } - else - { - el->SetSloped(false); - el->SetSlopeDirection(0); - } - Invalidate(); - } - } - - DukValue isQueue_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsPath(); - if (el != nullptr) - duk_push_boolean(ctx, el->IsQueue()); - else - duk_push_null(ctx); - return DukValue::take_from_stack(ctx); - } - void isQueue_set(bool value) - { - ThrowIfGameStateNotMutable(); - auto el = _element->AsPath(); - if (el != nullptr) - { - el->SetIsQueue(value); - Invalidate(); - } - } - - DukValue queueBannerDirection_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsPath(); - if (el != nullptr && el->HasQueueBanner()) - duk_push_int(ctx, el->GetQueueBannerDirection()); - else - duk_push_null(ctx); - return DukValue::take_from_stack(ctx); - } - void queueBannerDirection_set(const DukValue& value) - { - ThrowIfGameStateNotMutable(); - auto el = _element->AsPath(); - if (el != nullptr) - { - if (value.type() == DukValue::Type::NUMBER) - { - el->SetHasQueueBanner(true); - el->SetQueueBannerDirection(value.as_int()); - } - else - { - el->SetHasQueueBanner(false); - el->SetQueueBannerDirection(0); - } - Invalidate(); - } - } - - DukValue isBlockedByVehicle_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsPath(); - if (el != nullptr) - duk_push_boolean(ctx, el->IsBlockedByVehicle()); - else - duk_push_null(ctx); - return DukValue::take_from_stack(ctx); - } - void isBlockedByVehicle_set(bool value) - { - ThrowIfGameStateNotMutable(); - auto el = _element->AsPath(); - if (el != nullptr) - { - el->SetIsBlockedByVehicle(value); - Invalidate(); - } - } - - DukValue isWide_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsPath(); - if (el != nullptr) - duk_push_boolean(ctx, el->IsWide()); - else - duk_push_null(ctx); - return DukValue::take_from_stack(ctx); - } - void isWide_set(bool value) - { - ThrowIfGameStateNotMutable(); - auto el = _element->AsPath(); - if (el != nullptr) - { - el->SetWide(value); - Invalidate(); - } - } - - DukValue addition_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsPath(); - if (el != nullptr && el->HasAddition()) - duk_push_int(ctx, el->GetAddition() - 1); - else - duk_push_null(ctx); - return DukValue::take_from_stack(ctx); - } - void addition_set(const DukValue& value) - { - ThrowIfGameStateNotMutable(); - auto el = _element->AsPath(); - if (el != nullptr) - { - if (value.type() == DukValue::Type::NUMBER) - { - auto addition = value.as_int(); - if (addition >= 0 && addition <= 254) - { - el->SetAddition(addition + 1); - } - } - else - { - el->SetAddition(0); - } - Invalidate(); - } - } - - DukValue additionStatus_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsPath(); - if (el != nullptr && el->HasAddition()) - duk_push_int(ctx, el->GetAdditionStatus()); - else - duk_push_null(ctx); - return DukValue::take_from_stack(ctx); - } - void additionStatus_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto el = _element->AsPath(); - if (el != nullptr) - if (el->HasAddition()) - { - el->SetAdditionStatus(value); - Invalidate(); - } - } - - DukValue isAdditionBroken_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsPath(); - if (el != nullptr && el->HasAddition()) - duk_push_boolean(ctx, el->IsBroken()); - else - duk_push_null(ctx); - return DukValue::take_from_stack(ctx); - } - void isAdditionBroken_set(bool value) - { - ThrowIfGameStateNotMutable(); - auto el = _element->AsPath(); - if (el != nullptr) - { - el->SetIsBroken(value); - Invalidate(); - } - } - - DukValue isAdditionGhost_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsPath(); - if (el != nullptr && el->HasAddition()) - duk_push_boolean(ctx, el->AdditionIsGhost()); - else - duk_push_null(ctx); - return DukValue::take_from_stack(ctx); - } - void isAdditionGhost_set(bool value) - { - ThrowIfGameStateNotMutable(); - auto el = _element->AsPath(); - if (el != nullptr) - { - el->SetAdditionIsGhost(value); - Invalidate(); - } - } - - DukValue footpathObject_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsEntrance(); - if (el != nullptr) - duk_push_int(ctx, el->GetPathType()); - else - duk_push_null(ctx); - return DukValue::take_from_stack(ctx); - } - void footpathObject_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - auto el = _element->AsEntrance(); - if (el != nullptr) - { - el->SetPathType(value); - Invalidate(); - } - } - - DukValue direction_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - switch (_element->GetType()) - { - case TILE_ELEMENT_TYPE_BANNER: - { - auto el = _element->AsBanner(); - duk_push_int(ctx, el->GetPosition()); - break; - } - case TILE_ELEMENT_TYPE_PATH: - case TILE_ELEMENT_TYPE_SURFACE: - { - duk_push_null(ctx); - break; - } - default: - { - duk_push_int(ctx, _element->GetDirection()); - break; - } - } - return DukValue::take_from_stack(ctx); - } - void direction_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - switch (_element->GetType()) - { - case TILE_ELEMENT_TYPE_BANNER: - { - auto el = _element->AsBanner(); - el->SetPosition(value); - Invalidate(); - break; - } - case TILE_ELEMENT_TYPE_PATH: - case TILE_ELEMENT_TYPE_SURFACE: - { - break; - } - default: - { - _element->SetDirection(value); - Invalidate(); - } - } - } - - void Invalidate() - { - map_invalidate_tile_full(_coords); - } - - public: - static void Register(duk_context* ctx) - { - // All - dukglue_register_property(ctx, &ScTileElement::type_get, &ScTileElement::type_set, "type"); - dukglue_register_property(ctx, &ScTileElement::baseHeight_get, &ScTileElement::baseHeight_set, "baseHeight"); - dukglue_register_property(ctx, &ScTileElement::baseZ_get, &ScTileElement::baseZ_set, "baseZ"); - dukglue_register_property( - ctx, &ScTileElement::clearanceHeight_get, &ScTileElement::clearanceHeight_set, "clearanceHeight"); - dukglue_register_property(ctx, &ScTileElement::clearanceZ_get, &ScTileElement::clearanceZ_set, "clearanceZ"); - dukglue_register_property( - ctx, &ScTileElement::occupiedQuadrants_get, &ScTileElement::occupiedQuadrants_set, "occupiedQuadrants"); - dukglue_register_property(ctx, &ScTileElement::isGhost_get, &ScTileElement::isGhost_set, "isGhost"); - dukglue_register_property(ctx, &ScTileElement::isHidden_get, &ScTileElement::isHidden_set, "isHidden"); - - // Track | Small Scenery | Wall | Entrance | Large Scenery | Banner - dukglue_register_property(ctx, &ScTileElement::direction_get, &ScTileElement::direction_set, "direction"); - - // Path | Small Scenery | Wall | Entrance | Large Scenery - dukglue_register_property(ctx, &ScTileElement::object_get, &ScTileElement::object_set, "object"); - - // Small Scenery | Wall | Large Scenery - dukglue_register_property( - ctx, &ScTileElement::primaryColour_get, &ScTileElement::primaryColour_set, "primaryColour"); - dukglue_register_property( - ctx, &ScTileElement::secondaryColour_get, &ScTileElement::secondaryColour_set, "secondaryColour"); - - // Wall | Large Scenery | Banner - dukglue_register_property(ctx, &ScTileElement::bannerIndex_get, &ScTileElement::bannerIndex_set, "bannerIndex"); - - // Path | Track | Entrance - dukglue_register_property(ctx, &ScTileElement::ride_get, &ScTileElement::ride_set, "ride"); - dukglue_register_property(ctx, &ScTileElement::station_get, &ScTileElement::station_set, "station"); - - // Track | Entrance | Large Scenery - dukglue_register_property(ctx, &ScTileElement::sequence_get, &ScTileElement::sequence_set, "sequence"); - - // Surface | Wall - dukglue_register_property(ctx, &ScTileElement::slope_get, &ScTileElement::slope_set, "slope"); - - // Surface only - dukglue_register_property(ctx, &ScTileElement::waterHeight_get, &ScTileElement::waterHeight_set, "waterHeight"); - dukglue_register_property(ctx, &ScTileElement::surfaceStyle_get, &ScTileElement::surfaceStyle_set, "surfaceStyle"); - dukglue_register_property(ctx, &ScTileElement::edgeStyle_get, &ScTileElement::edgeStyle_set, "edgeStyle"); - dukglue_register_property(ctx, &ScTileElement::grassLength_get, &ScTileElement::grassLength_set, "grassLength"); - dukglue_register_property(ctx, &ScTileElement::hasOwnership_get, nullptr, "hasOwnership"); - dukglue_register_property(ctx, &ScTileElement::hasConstructionRights_get, nullptr, "hasConstructionRights"); - dukglue_register_property(ctx, &ScTileElement::ownership_get, &ScTileElement::ownership_set, "ownership"); - dukglue_register_property(ctx, &ScTileElement::parkFences_get, &ScTileElement::parkFences_set, "parkFences"); - - // Footpath only - dukglue_register_property( - ctx, &ScTileElement::edgesAndCorners_get, &ScTileElement::edgesAndCorners_set, "edgesAndCorners"); - dukglue_register_property(ctx, &ScTileElement::edges_get, &ScTileElement::edges_set, "edges"); - dukglue_register_property(ctx, &ScTileElement::corners_get, &ScTileElement::corners_set, "corners"); - dukglue_register_property( - ctx, &ScTileElement::slopeDirection_get, &ScTileElement::slopeDirection_set, "slopeDirection"); - dukglue_register_property(ctx, &ScTileElement::isQueue_get, &ScTileElement::isQueue_set, "isQueue"); - dukglue_register_property( - ctx, &ScTileElement::queueBannerDirection_get, &ScTileElement::queueBannerDirection_set, - "queueBannerDirection"); - dukglue_register_property(ctx, &ScTileElement::queueBannerDirection_get, &ScTileElement::edges_set, "test"); - - dukglue_register_property( - ctx, &ScTileElement::isBlockedByVehicle_get, &ScTileElement::isBlockedByVehicle_set, "isBlockedByVehicle"); - dukglue_register_property(ctx, &ScTileElement::isWide_get, &ScTileElement::isWide_set, "isWide"); - - dukglue_register_property(ctx, &ScTileElement::addition_get, &ScTileElement::addition_set, "addition"); - dukglue_register_property( - ctx, &ScTileElement::additionStatus_get, &ScTileElement::additionStatus_set, "additionStatus"); - dukglue_register_property( - ctx, &ScTileElement::isAdditionBroken_get, &ScTileElement::isAdditionBroken_set, "isAdditionBroken"); - dukglue_register_property( - ctx, &ScTileElement::isAdditionGhost_get, &ScTileElement::isAdditionGhost_set, "isAdditionGhost"); - - // Track only - dukglue_register_property(ctx, &ScTileElement::trackType_get, &ScTileElement::trackType_set, "trackType"); - dukglue_register_property(ctx, &ScTileElement::mazeEntry_get, &ScTileElement::mazeEntry_set, "mazeEntry"); - dukglue_register_property(ctx, &ScTileElement::colourScheme_get, &ScTileElement::colourScheme_set, "colourScheme"); - dukglue_register_property(ctx, &ScTileElement::seatRotation_get, &ScTileElement::seatRotation_set, "seatRotation"); - dukglue_register_property( - ctx, &ScTileElement::brakeBoosterSpeed_get, &ScTileElement::brakeBoosterSpeed_set, "brakeBoosterSpeed"); - dukglue_register_property(ctx, &ScTileElement::hasChainLift_get, &ScTileElement::hasChainLift_set, "hasChainLift"); - dukglue_register_property(ctx, &ScTileElement::isInverted_get, &ScTileElement::isInverted_set, "isInverted"); - dukglue_register_property(ctx, &ScTileElement::hasCableLift_get, &ScTileElement::hasCableLift_set, "hasCableLift"); - - // Small Scenery only - dukglue_register_property(ctx, &ScTileElement::age_get, &ScTileElement::age_set, "age"); - dukglue_register_property(ctx, &ScTileElement::quadrant_get, &ScTileElement::quadrant_set, "quadrant"); - - // Wall only - dukglue_register_property( - ctx, &ScTileElement::tertiaryColour_get, &ScTileElement::tertiaryColour_set, "tertiaryColour"); - - // Entrance only - dukglue_register_property( - ctx, &ScTileElement::footpathObject_get, &ScTileElement::footpathObject_set, "footpathObject"); - } - }; - - class ScTile - { - private: - CoordsXY _coords; - - public: - ScTile(const CoordsXY& coords) - : _coords(coords) - { - } - - private: - int32_t x_get() const - { - return _coords.x / COORDS_XY_STEP; - } - - int32_t y_get() const - { - return _coords.y / COORDS_XY_STEP; - } - - uint32_t numElements_get() const - { - auto first = GetFirstElement(); - return static_cast(GetNumElements(first)); - } - - std::vector> elements_get() const - { - std::vector> result; - auto first = GetFirstElement(); - auto currentNumElements = GetNumElements(first); - if (currentNumElements != 0) - { - result.reserve(currentNumElements); - for (size_t i = 0; i < currentNumElements; i++) - { - result.push_back(std::make_shared(_coords, &first[i])); - } - } - return result; - } - - DukValue data_get() const - { - auto ctx = GetDukContext(); - auto first = map_get_first_element_at(_coords); - auto dataLen = GetNumElements(first) * sizeof(TileElement); - auto data = duk_push_fixed_buffer(ctx, dataLen); - if (first != nullptr) - { - std::memcpy(data, first, dataLen); - } - duk_push_buffer_object(ctx, -1, 0, dataLen, DUK_BUFOBJ_UINT8ARRAY); - return DukValue::take_from_stack(ctx); - } - - void data_set(DukValue value) - { - ThrowIfGameStateNotMutable(); - auto ctx = value.context(); - value.push(); - if (duk_is_buffer_data(ctx, -1)) - { - duk_size_t dataLen{}; - auto data = duk_get_buffer_data(ctx, -1, &dataLen); - auto numElements = dataLen / sizeof(TileElement); - if (numElements == 0) - { - map_set_tile_element(TileCoordsXY(_coords), nullptr); - } - else - { - auto first = GetFirstElement(); - auto currentNumElements = GetNumElements(first); - if (numElements > currentNumElements) - { - // Allocate space for the extra tile elements (inefficient but works) - auto pos = TileCoordsXYZ(TileCoordsXY(_coords), 0).ToCoordsXYZ(); - auto numToInsert = numElements - currentNumElements; - for (size_t i = 0; i < numToInsert; i++) - { - tile_element_insert(pos, 0, TileElementType::Surface); - } - - // Copy data to element span - first = map_get_first_element_at(_coords); - currentNumElements = GetNumElements(first); - if (currentNumElements != 0) - { - std::memcpy(first, data, currentNumElements * sizeof(TileElement)); - // Safely force last tile flag for last element to avoid read overrun - first[numElements - 1].SetLastForTile(true); - } - } - else - { - std::memcpy(first, data, numElements * sizeof(TileElement)); - // Safely force last tile flag for last element to avoid read overrun - first[numElements - 1].SetLastForTile(true); - } - } - map_invalidate_tile_full(_coords); - } - } - - std::shared_ptr getElement(uint32_t index) const - { - auto first = GetFirstElement(); - if (static_cast(index) < GetNumElements(first)) - { - return std::make_shared(_coords, &first[index]); - } - return {}; - } - - std::shared_ptr insertElement(uint32_t index) - { - ThrowIfGameStateNotMutable(); - std::shared_ptr result; - auto first = GetFirstElement(); - auto origNumElements = GetNumElements(first); - if (index <= origNumElements) - { - std::vector data(first, first + origNumElements); - - auto pos = TileCoordsXYZ(TileCoordsXY(_coords), 0).ToCoordsXYZ(); - auto newElement = tile_element_insert(pos, 0, TileElementType::Surface); - if (newElement == nullptr) - { - auto ctx = GetDukContext(); - duk_error(ctx, DUK_ERR_ERROR, "Unable to allocate element."); - } - else - { - // Inefficient, requires a dedicated method in tile element manager - first = GetFirstElement(); - // Copy elements before index - if (index > 0) - { - std::memcpy(first, &data[0], index * sizeof(TileElement)); - } - // Zero new element - std::memset(first + index, 0, sizeof(TileElement)); - // Copy elements after index - if (index < origNumElements) - { - std::memcpy(first + index + 1, &data[index], (origNumElements - index) * sizeof(TileElement)); - } - for (size_t i = 0; i < origNumElements; i++) - { - first[i].SetLastForTile(false); - } - first[origNumElements].SetLastForTile(true); - map_invalidate_tile_full(_coords); - result = std::make_shared(_coords, &first[index]); - } - } - else - { - auto ctx = GetDukContext(); - duk_error(ctx, DUK_ERR_RANGE_ERROR, "Index must be between zero and the number of elements on the tile."); - } - return result; - } - - void removeElement(uint32_t index) - { - ThrowIfGameStateNotMutable(); - auto first = GetFirstElement(); - if (index < GetNumElements(first)) - { - tile_element_remove(&first[index]); - map_invalidate_tile_full(_coords); - } - } - - TileElement* GetFirstElement() const - { - return map_get_first_element_at(_coords); - } - - static size_t GetNumElements(const TileElement* first) - { - size_t count = 0; - if (first != nullptr) - { - auto element = first; - do - { - count++; - } while (!(element++)->IsLastForTile()); - } - return count; - } - - duk_context* GetDukContext() const - { - auto& scriptEngine = GetContext()->GetScriptEngine(); - auto ctx = scriptEngine.GetContext(); - return ctx; - } - - public: - static void Register(duk_context* ctx) - { - dukglue_register_property(ctx, &ScTile::x_get, nullptr, "x"); - dukglue_register_property(ctx, &ScTile::y_get, nullptr, "y"); - dukglue_register_property(ctx, &ScTile::elements_get, nullptr, "elements"); - dukglue_register_property(ctx, &ScTile::numElements_get, nullptr, "numElements"); - dukglue_register_property(ctx, &ScTile::data_get, &ScTile::data_set, "data"); - dukglue_register_method(ctx, &ScTile::getElement, "getElement"); - dukglue_register_method(ctx, &ScTile::insertElement, "insertElement"); - dukglue_register_method(ctx, &ScTile::removeElement, "removeElement"); - } - }; -} // namespace OpenRCT2::Scripting - -#endif diff --git a/src/openrct2/scripting/ScriptEngine.cpp b/src/openrct2/scripting/ScriptEngine.cpp index e3478a84d9..e5e132ceb1 100644 --- a/src/openrct2/scripting/ScriptEngine.cpp +++ b/src/openrct2/scripting/ScriptEngine.cpp @@ -24,21 +24,31 @@ # include "../interface/InteractiveConsole.h" # include "../platform/Platform2.h" # include "Duktape.hpp" -# include "ScCheats.hpp" -# include "ScClimate.hpp" -# include "ScConsole.hpp" -# include "ScContext.hpp" -# include "ScDate.hpp" -# include "ScDisposable.hpp" -# include "ScEntity.hpp" -# include "ScMap.hpp" -# include "ScNetwork.hpp" -# include "ScObject.hpp" -# include "ScPark.hpp" -# include "ScRide.hpp" -# include "ScScenario.hpp" -# include "ScSocket.hpp" -# include "ScTile.hpp" +# include "bindings/entity/ScEntity.hpp" +# include "bindings/entity/ScGuest.hpp" +# include "bindings/entity/ScLitter.hpp" +# include "bindings/entity/ScPeep.hpp" +# include "bindings/entity/ScStaff.hpp" +# include "bindings/entity/ScVehicle.hpp" +# include "bindings/game/ScCheats.hpp" +# include "bindings/game/ScConsole.hpp" +# include "bindings/game/ScContext.hpp" +# include "bindings/game/ScDisposable.hpp" +# include "bindings/network/ScNetwork.hpp" +# include "bindings/network/ScPlayer.hpp" +# include "bindings/network/ScPlayerGroup.hpp" +# include "bindings/network/ScSocket.hpp" +# include "bindings/object/ScObject.hpp" +# include "bindings/ride/ScRide.hpp" +# include "bindings/ride/ScRideStation.hpp" +# include "bindings/world/ScClimate.hpp" +# include "bindings/world/ScDate.hpp" +# include "bindings/world/ScMap.hpp" +# include "bindings/world/ScPark.hpp" +# include "bindings/world/ScParkMessage.hpp" +# include "bindings/world/ScScenario.hpp" +# include "bindings/world/ScTile.hpp" +# include "bindings/world/ScTileElement.hpp" # include # include diff --git a/src/openrct2/scripting/bindings/entity/ScEntity.hpp b/src/openrct2/scripting/bindings/entity/ScEntity.hpp new file mode 100644 index 0000000000..6531862fdf --- /dev/null +++ b/src/openrct2/scripting/bindings/entity/ScEntity.hpp @@ -0,0 +1,212 @@ +/***************************************************************************** + * Copyright (c) 2014-2020 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#pragma once + +#ifdef ENABLE_SCRIPTING + +# include "../../../Context.h" +# include "../../../common.h" +# include "../../../peep/Peep.h" +# include "../../../util/Util.h" +# include "../../../world/EntityList.h" +# include "../../../world/Sprite.h" +# include "../../Duktape.hpp" +# include "../../ScriptEngine.h" + +# include +# include +# include + +namespace OpenRCT2::Scripting +{ + class ScEntity + { + protected: + uint16_t _id = SPRITE_INDEX_NULL; + + public: + ScEntity(uint16_t id) + : _id(id) + { + } + + private: + int32_t id_get() const + { + auto entity = GetEntity(); + return entity != nullptr ? entity->sprite_index : 0; + } + + std::string type_get() const + { + const auto targetApiVersion = GetTargetAPIVersion(); + + auto entity = GetEntity(); + if (entity != nullptr) + { + switch (entity->Type) + { + case EntityType::Vehicle: + return "car"; + case EntityType::Guest: + if (targetApiVersion <= API_VERSION_33_PEEP_DEPRECATION) + return "peep"; + else + return "guest"; + case EntityType::Staff: + if (targetApiVersion <= API_VERSION_33_PEEP_DEPRECATION) + return "peep"; + else + return "staff"; + case EntityType::SteamParticle: + return "steam_particle"; + case EntityType::MoneyEffect: + return "money_effect"; + case EntityType::CrashedVehicleParticle: + return "crashed_vehicle_particle"; + case EntityType::ExplosionCloud: + return "explosion_cloud"; + case EntityType::CrashSplash: + return "crash_splash"; + case EntityType::ExplosionFlare: + return "explosion_flare"; + case EntityType::Balloon: + return "balloon"; + case EntityType::Duck: + return "duck"; + case EntityType::JumpingFountain: + return "jumping_fountain"; + case EntityType::Litter: + return "litter"; + case EntityType::Null: + return "unknown"; + default: + break; + } + } + return "unknown"; + } + + // x getter and setter + int32_t x_get() const + { + auto entity = GetEntity(); + return entity != nullptr ? entity->x : 0; + } + void x_set(int32_t value) + { + ThrowIfGameStateNotMutable(); + auto entity = GetEntity(); + if (entity != nullptr) + { + entity->MoveTo({ value, entity->y, entity->z }); + } + } + + // y getter and setter + int32_t y_get() const + { + auto entity = GetEntity(); + return entity != nullptr ? entity->y : 0; + } + void y_set(int32_t value) + { + ThrowIfGameStateNotMutable(); + auto entity = GetEntity(); + if (entity != nullptr) + { + entity->MoveTo({ entity->x, value, entity->z }); + } + } + + // z getter and setter + int16_t z_get() const + { + auto entity = GetEntity(); + return entity != nullptr ? entity->z : 0; + } + void z_set(int16_t value) + { + ThrowIfGameStateNotMutable(); + auto entity = GetEntity(); + if (entity != nullptr) + { + entity->MoveTo({ entity->x, entity->y, value }); + } + } + + void remove() + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto entity = GetEntity(); + if (entity != nullptr) + { + entity->Invalidate(); + switch (entity->Type) + { + case EntityType::Vehicle: + duk_error(ctx, DUK_ERR_ERROR, "Removing a vehicle is currently unsupported."); + break; + case EntityType::Guest: + case EntityType::Staff: + { + auto peep = entity->As(); + // We can't remove a single peep from a ride at the moment as this can cause complications with the + // vehicle car having an unsupported peep capacity. + if (peep == nullptr || peep->State == PeepState::OnRide || peep->State == PeepState::EnteringRide) + { + duk_error(ctx, DUK_ERR_ERROR, "Removing a peep that is on a ride is currently unsupported."); + } + else + { + peep->Remove(); + } + break; + } + case EntityType::SteamParticle: + case EntityType::MoneyEffect: + case EntityType::CrashedVehicleParticle: + case EntityType::ExplosionCloud: + case EntityType::CrashSplash: + case EntityType::ExplosionFlare: + case EntityType::JumpingFountain: + case EntityType::Balloon: + case EntityType::Duck: + case EntityType::Litter: + sprite_remove(entity); + break; + case EntityType::Null: + break; + default: + break; + } + } + } + + SpriteBase* GetEntity() const + { + return ::GetEntity(_id); + } + + public: + static void Register(duk_context* ctx) + { + dukglue_register_property(ctx, &ScEntity::id_get, nullptr, "id"); + dukglue_register_property(ctx, &ScEntity::type_get, nullptr, "type"); + dukglue_register_property(ctx, &ScEntity::x_get, &ScEntity::x_set, "x"); + dukglue_register_property(ctx, &ScEntity::y_get, &ScEntity::y_set, "y"); + dukglue_register_property(ctx, &ScEntity::z_get, &ScEntity::z_set, "z"); + dukglue_register_method(ctx, &ScEntity::remove, "remove"); + } + }; + +} // namespace OpenRCT2::Scripting + +#endif diff --git a/src/openrct2/scripting/bindings/entity/ScGuest.cpp b/src/openrct2/scripting/bindings/entity/ScGuest.cpp new file mode 100644 index 0000000000..ea85c8efa6 --- /dev/null +++ b/src/openrct2/scripting/bindings/entity/ScGuest.cpp @@ -0,0 +1,340 @@ +/***************************************************************************** + * Copyright (c) 2014-2021 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#ifdef ENABLE_SCRIPTING + +# include "ScGuest.hpp" + +namespace OpenRCT2::Scripting +{ + ScGuest::ScGuest(uint16_t id) + : ScPeep(id) + { + } + + void ScGuest::Register(duk_context* ctx) + { + dukglue_set_base_class(ctx); + dukglue_register_property(ctx, &ScGuest::tshirtColour_get, &ScGuest::tshirtColour_set, "tshirtColour"); + dukglue_register_property(ctx, &ScGuest::trousersColour_get, &ScGuest::trousersColour_set, "trousersColour"); + dukglue_register_property(ctx, &ScGuest::balloonColour_get, &ScGuest::balloonColour_set, "balloonColour"); + dukglue_register_property(ctx, &ScGuest::hatColour_get, &ScGuest::hatColour_set, "hatColour"); + dukglue_register_property(ctx, &ScGuest::umbrellaColour_get, &ScGuest::umbrellaColour_set, "umbrellaColour"); + dukglue_register_property(ctx, &ScGuest::happiness_get, &ScGuest::happiness_set, "happiness"); + dukglue_register_property(ctx, &ScGuest::happinessTarget_get, &ScGuest::happinessTarget_set, "happinessTarget"); + dukglue_register_property(ctx, &ScGuest::nausea_get, &ScGuest::nausea_set, "nausea"); + dukglue_register_property(ctx, &ScGuest::nauseaTarget_get, &ScGuest::nauseaTarget_set, "nauseaTarget"); + dukglue_register_property(ctx, &ScGuest::hunger_get, &ScGuest::hunger_set, "hunger"); + dukglue_register_property(ctx, &ScGuest::thirst_get, &ScGuest::thirst_set, "thirst"); + dukglue_register_property(ctx, &ScGuest::toilet_get, &ScGuest::toilet_set, "toilet"); + dukglue_register_property(ctx, &ScGuest::mass_get, &ScGuest::mass_set, "mass"); + dukglue_register_property(ctx, &ScGuest::minIntensity_get, &ScGuest::minIntensity_set, "minIntensity"); + dukglue_register_property(ctx, &ScGuest::maxIntensity_get, &ScGuest::maxIntensity_set, "maxIntensity"); + dukglue_register_property(ctx, &ScGuest::nauseaTolerance_get, &ScGuest::nauseaTolerance_set, "nauseaTolerance"); + dukglue_register_property(ctx, &ScGuest::cash_get, &ScGuest::cash_set, "cash"); + dukglue_register_property(ctx, &ScGuest::isInPark_get, nullptr, "isInPark"); + dukglue_register_property(ctx, &ScGuest::isLost_get, nullptr, "isLost"); + dukglue_register_property(ctx, &ScGuest::lostCountdown_get, &ScGuest::lostCountdown_set, "lostCountdown"); + } + + Guest* ScGuest::GetGuest() const + { + return ::GetEntity(_id); + } + + uint8_t ScGuest::tshirtColour_get() const + { + auto peep = GetGuest(); + return peep != nullptr ? peep->TshirtColour : 0; + } + void ScGuest::tshirtColour_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto peep = GetGuest(); + if (peep != nullptr) + { + peep->TshirtColour = value; + peep->Invalidate(); + } + } + + uint8_t ScGuest::trousersColour_get() const + { + auto peep = GetGuest(); + return peep != nullptr ? peep->TrousersColour : 0; + } + void ScGuest::trousersColour_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto peep = GetGuest(); + if (peep != nullptr) + { + peep->TrousersColour = value; + peep->Invalidate(); + } + } + + uint8_t ScGuest::balloonColour_get() const + { + auto peep = GetGuest(); + return peep != nullptr ? peep->BalloonColour : 0; + } + void ScGuest::balloonColour_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto peep = GetGuest(); + if (peep != nullptr) + { + peep->BalloonColour = value; + peep->Invalidate(); + } + } + + uint8_t ScGuest::hatColour_get() const + { + auto peep = GetGuest(); + return peep != nullptr ? peep->HatColour : 0; + } + void ScGuest::hatColour_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto peep = GetGuest(); + if (peep != nullptr) + { + peep->HatColour = value; + peep->Invalidate(); + } + } + + uint8_t ScGuest::umbrellaColour_get() const + { + auto peep = GetGuest(); + return peep != nullptr ? peep->UmbrellaColour : 0; + } + void ScGuest::umbrellaColour_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto peep = GetGuest(); + if (peep != nullptr) + { + peep->UmbrellaColour = value; + peep->Invalidate(); + } + } + + uint8_t ScGuest::happiness_get() const + { + auto peep = GetGuest(); + return peep != nullptr ? peep->Happiness : 0; + } + void ScGuest::happiness_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto peep = GetGuest(); + if (peep != nullptr) + { + peep->Happiness = value; + } + } + + uint8_t ScGuest::happinessTarget_get() const + { + auto peep = GetGuest(); + return peep != nullptr ? peep->HappinessTarget : 0; + } + void ScGuest::happinessTarget_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto peep = GetGuest(); + if (peep != nullptr) + { + peep->HappinessTarget = value; + } + } + + uint8_t ScGuest::nausea_get() const + { + auto peep = GetGuest(); + return peep != nullptr ? peep->Nausea : 0; + } + void ScGuest::nausea_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto peep = GetGuest(); + if (peep != nullptr) + { + peep->Nausea = value; + } + } + + uint8_t ScGuest::nauseaTarget_get() const + { + auto peep = GetGuest(); + return peep != nullptr ? peep->NauseaTarget : 0; + } + void ScGuest::nauseaTarget_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto peep = GetGuest(); + if (peep != nullptr) + { + peep->NauseaTarget = value; + } + } + + uint8_t ScGuest::hunger_get() const + { + auto peep = GetGuest(); + return peep != nullptr ? peep->Hunger : 0; + } + void ScGuest::hunger_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto peep = GetGuest(); + if (peep != nullptr) + { + peep->Hunger = value; + } + } + + uint8_t ScGuest::thirst_get() const + { + auto peep = GetGuest(); + return peep != nullptr ? peep->Thirst : 0; + } + void ScGuest::thirst_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto peep = GetGuest(); + if (peep != nullptr) + { + peep->Thirst = value; + } + } + + uint8_t ScGuest::toilet_get() const + { + auto peep = GetGuest(); + return peep != nullptr ? peep->Toilet : 0; + } + void ScGuest::toilet_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto peep = GetGuest(); + if (peep != nullptr) + { + peep->Toilet = value; + } + } + + uint8_t ScGuest::mass_get() const + { + auto peep = GetGuest(); + return peep != nullptr ? peep->Mass : 0; + } + void ScGuest::mass_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto peep = GetGuest(); + if (peep != nullptr) + { + peep->Mass = value; + } + } + + uint8_t ScGuest::minIntensity_get() const + { + auto peep = GetGuest(); + return peep != nullptr ? peep->Intensity.GetMinimum() : 0; + } + void ScGuest::minIntensity_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto peep = GetGuest(); + if (peep != nullptr) + { + peep->Intensity = peep->Intensity.WithMinimum(value); + } + } + + uint8_t ScGuest::maxIntensity_get() const + { + auto peep = GetGuest(); + return peep != nullptr ? peep->Intensity.GetMaximum() : 0; + } + void ScGuest::maxIntensity_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto peep = GetGuest(); + if (peep != nullptr) + { + peep->Intensity = peep->Intensity.WithMaximum(value); + } + } + + uint8_t ScGuest::nauseaTolerance_get() const + { + auto peep = GetGuest(); + return peep != nullptr ? EnumValue(peep->NauseaTolerance) : 0; + } + void ScGuest::nauseaTolerance_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto peep = GetGuest(); + if (peep != nullptr) + { + peep->NauseaTolerance = static_cast(std::min(value, 3)); + } + } + + int32_t ScGuest::cash_get() const + { + auto peep = GetGuest(); + return peep != nullptr ? peep->CashInPocket : 0; + } + void ScGuest::cash_set(int32_t value) + { + ThrowIfGameStateNotMutable(); + auto peep = GetGuest(); + if (peep != nullptr) + { + peep->CashInPocket = std::max(0, value); + } + } + + bool ScGuest::isInPark_get() const + { + auto peep = GetGuest(); + return (peep != nullptr && !peep->OutsideOfPark); + } + + bool ScGuest::isLost_get() const + { + auto peep = GetGuest(); + return (peep != nullptr && peep->GuestIsLostCountdown < 90); + } + + uint8_t ScGuest::lostCountdown_get() const + { + auto peep = GetGuest(); + return peep != nullptr ? peep->GuestIsLostCountdown : 0; + } + void ScGuest::lostCountdown_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto peep = GetGuest(); + if (peep != nullptr) + { + peep->GuestIsLostCountdown = value; + } + } + +} // namespace OpenRCT2::Scripting + +#endif diff --git a/src/openrct2/scripting/bindings/entity/ScGuest.hpp b/src/openrct2/scripting/bindings/entity/ScGuest.hpp new file mode 100644 index 0000000000..e387cb22d9 --- /dev/null +++ b/src/openrct2/scripting/bindings/entity/ScGuest.hpp @@ -0,0 +1,89 @@ +/***************************************************************************** + * Copyright (c) 2014-2021 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#pragma once + +#ifdef ENABLE_SCRIPTING + +# include "ScPeep.hpp" + +namespace OpenRCT2::Scripting +{ + class ScGuest : public ScPeep + { + public: + ScGuest(uint16_t id); + + static void Register(duk_context* ctx); + + private: + Guest* GetGuest() const; + + uint8_t tshirtColour_get() const; + void tshirtColour_set(uint8_t value); + + uint8_t trousersColour_get() const; + void trousersColour_set(uint8_t value); + + uint8_t balloonColour_get() const; + void balloonColour_set(uint8_t value); + + uint8_t hatColour_get() const; + void hatColour_set(uint8_t value); + + uint8_t umbrellaColour_get() const; + void umbrellaColour_set(uint8_t value); + + uint8_t happiness_get() const; + void happiness_set(uint8_t value); + + uint8_t happinessTarget_get() const; + void happinessTarget_set(uint8_t value); + + uint8_t nausea_get() const; + void nausea_set(uint8_t value); + + uint8_t nauseaTarget_get() const; + void nauseaTarget_set(uint8_t value); + + uint8_t hunger_get() const; + void hunger_set(uint8_t value); + + uint8_t thirst_get() const; + void thirst_set(uint8_t value); + + uint8_t toilet_get() const; + void toilet_set(uint8_t value); + + uint8_t mass_get() const; + void mass_set(uint8_t value); + + uint8_t minIntensity_get() const; + void minIntensity_set(uint8_t value); + + uint8_t maxIntensity_get() const; + void maxIntensity_set(uint8_t value); + + uint8_t nauseaTolerance_get() const; + void nauseaTolerance_set(uint8_t value); + + int32_t cash_get() const; + void cash_set(int32_t value); + + bool isInPark_get() const; + + bool isLost_get() const; + + uint8_t lostCountdown_get() const; + void lostCountdown_set(uint8_t value); + }; + +} // namespace OpenRCT2::Scripting + +#endif diff --git a/src/openrct2/scripting/bindings/entity/ScLitter.cpp b/src/openrct2/scripting/bindings/entity/ScLitter.cpp new file mode 100644 index 0000000000..df59a9b7fe --- /dev/null +++ b/src/openrct2/scripting/bindings/entity/ScLitter.cpp @@ -0,0 +1,78 @@ +/***************************************************************************** + * Copyright (c) 2014-2021 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#ifdef ENABLE_SCRIPTING + +# include "ScLitter.hpp" + +namespace OpenRCT2::Scripting +{ + static const DukEnumMap LitterTypeMap({ + { "vomit", Litter::Type::Vomit }, + { "vomit_alt", Litter::Type::VomitAlt }, + { "empty_can", Litter::Type::EmptyCan }, + { "rubbish", Litter::Type::Rubbish }, + { "burger_box", Litter::Type::BurgerBox }, + { "empty_cup", Litter::Type::EmptyCup }, + { "empty_box", Litter::Type::EmptyBox }, + { "empty_bottle", Litter::Type::EmptyBottle }, + { "empty_bowl_red", Litter::Type::EmptyBowlRed }, + { "empty_drink_carton", Litter::Type::EmptyDrinkCarton }, + { "empty_juice_cup", Litter::Type::EmptyJuiceCup }, + { "empty_bowl_blue", Litter::Type::EmptyBowlBlue }, + }); + + ScLitter::ScLitter(uint16_t Id) + : ScEntity(Id) + { + } + + void ScLitter::Register(duk_context* ctx) + { + dukglue_set_base_class(ctx); + dukglue_register_property(ctx, &ScLitter::litterType_get, &ScLitter::litterType_set, "litterType"); + dukglue_register_property(ctx, &ScLitter::creationTick_get, nullptr, "creationTick"); + } + + Litter* ScLitter::GetLitter() const + { + return ::GetEntity(_id); + } + + std::string ScLitter::litterType_get() const + { + auto* litter = GetLitter(); + auto it = LitterTypeMap.find(litter->SubType); + if (it == LitterTypeMap.end()) + return ""; + return std::string{ it->first }; + } + + void ScLitter::litterType_set(const std::string& litterType) + { + ThrowIfGameStateNotMutable(); + + auto it = LitterTypeMap.find(litterType); + if (it == LitterTypeMap.end()) + return; + auto* litter = GetLitter(); + litter->SubType = it->second; + } + + uint32_t ScLitter::creationTick_get() const + { + auto* litter = GetLitter(); + if (litter == nullptr) + return 0; + return litter->creationTick; + } + +} // namespace OpenRCT2::Scripting + +#endif diff --git a/src/openrct2/scripting/bindings/entity/ScLitter.hpp b/src/openrct2/scripting/bindings/entity/ScLitter.hpp new file mode 100644 index 0000000000..d2184b1075 --- /dev/null +++ b/src/openrct2/scripting/bindings/entity/ScLitter.hpp @@ -0,0 +1,36 @@ +/***************************************************************************** + * Copyright (c) 2014-2021 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#pragma once + +#ifdef ENABLE_SCRIPTING + +# include "ScEntity.hpp" + +namespace OpenRCT2::Scripting +{ + class ScLitter : public ScEntity + { + public: + ScLitter(uint16_t Id); + + static void Register(duk_context* ctx); + + private: + Litter* GetLitter() const; + + std::string litterType_get() const; + void litterType_set(const std::string& litterType); + + uint32_t creationTick_get() const; + }; + +} // namespace OpenRCT2::Scripting + +#endif diff --git a/src/openrct2/scripting/bindings/entity/ScPeep.hpp b/src/openrct2/scripting/bindings/entity/ScPeep.hpp new file mode 100644 index 0000000000..96173a3a29 --- /dev/null +++ b/src/openrct2/scripting/bindings/entity/ScPeep.hpp @@ -0,0 +1,180 @@ +/***************************************************************************** + * Copyright (c) 2014-2021 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#pragma once + +#ifdef ENABLE_SCRIPTING + +# include "ScEntity.hpp" + +namespace OpenRCT2::Scripting +{ + static const DukEnumMap PeepFlagMap({ + { "leavingPark", PEEP_FLAGS_LEAVING_PARK }, + { "slowWalk", PEEP_FLAGS_SLOW_WALK }, + { "tracking", PEEP_FLAGS_TRACKING }, + { "waving", PEEP_FLAGS_WAVING }, + { "hasPaidForParkEntry", PEEP_FLAGS_HAS_PAID_FOR_PARK_ENTRY }, + { "photo", PEEP_FLAGS_PHOTO }, + { "painting", PEEP_FLAGS_PAINTING }, + { "wow", PEEP_FLAGS_WOW }, + { "litter", PEEP_FLAGS_LITTER }, + { "lost", PEEP_FLAGS_LOST }, + { "hunger", PEEP_FLAGS_HUNGER }, + { "toilet", PEEP_FLAGS_TOILET }, + { "crowded", PEEP_FLAGS_CROWDED }, + { "happiness", PEEP_FLAGS_HAPPINESS }, + { "nausea", PEEP_FLAGS_NAUSEA }, + { "purple", PEEP_FLAGS_PURPLE }, + { "pizza", PEEP_FLAGS_PIZZA }, + { "explode", PEEP_FLAGS_EXPLODE }, + { "rideShouldBeMarkedAsFavourite", PEEP_FLAGS_RIDE_SHOULD_BE_MARKED_AS_FAVOURITE }, + { "parkEntranceChosen", PEEP_FLAGS_PARK_ENTRANCE_CHOSEN }, + { "contagious", PEEP_FLAGS_CONTAGIOUS }, + { "joy", PEEP_FLAGS_JOY }, + { "angry", PEEP_FLAGS_ANGRY }, + { "iceCream", PEEP_FLAGS_ICE_CREAM }, + { "hereWeAre", PEEP_FLAGS_HERE_WE_ARE }, + }); + + class ScPeep : public ScEntity + { + public: + ScPeep(uint16_t id) + : ScEntity(id) + { + } + + static void Register(duk_context* ctx) + { + dukglue_set_base_class(ctx); + dukglue_register_property(ctx, &ScPeep::peepType_get, nullptr, "peepType"); + dukglue_register_property(ctx, &ScPeep::name_get, &ScPeep::name_set, "name"); + dukglue_register_property(ctx, &ScPeep::destination_get, &ScPeep::destination_set, "destination"); + dukglue_register_property(ctx, &ScPeep::energy_get, &ScPeep::energy_set, "energy"); + dukglue_register_property(ctx, &ScPeep::energyTarget_get, &ScPeep::energyTarget_set, "energyTarget"); + dukglue_register_method(ctx, &ScPeep::getFlag, "getFlag"); + dukglue_register_method(ctx, &ScPeep::setFlag, "setFlag"); + } + + private: + std::string peepType_get() const + { + auto peep = GetPeep(); + if (peep != nullptr) + { + return peep->Is() ? "staff" : "guest"; + } + return ""; + } + + std::string name_get() const + { + auto peep = GetPeep(); + return peep != nullptr ? peep->GetName() : std::string(); + } + void name_set(const std::string& value) + { + ThrowIfGameStateNotMutable(); + auto peep = GetPeep(); + if (peep != nullptr) + { + peep->SetName(value); + } + } + + bool getFlag(const std::string& key) const + { + auto peep = GetPeep(); + if (peep != nullptr) + { + auto mask = PeepFlagMap[key]; + return (peep->PeepFlags & mask) != 0; + } + return false; + } + + void setFlag(const std::string& key, bool value) + { + ThrowIfGameStateNotMutable(); + auto peep = GetPeep(); + if (peep != nullptr) + { + auto mask = PeepFlagMap[key]; + if (value) + peep->PeepFlags |= mask; + else + peep->PeepFlags &= ~mask; + peep->Invalidate(); + } + } + + DukValue destination_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto peep = GetPeep(); + if (peep != nullptr) + { + return ToDuk(ctx, peep->GetDestination()); + } + return ToDuk(ctx, nullptr); + } + + void destination_set(const DukValue& value) + { + ThrowIfGameStateNotMutable(); + auto peep = GetPeep(); + if (peep != nullptr) + { + auto pos = FromDuk(value); + peep->SetDestination(pos); + peep->Invalidate(); + } + } + + uint8_t energy_get() const + { + auto peep = GetPeep(); + return peep != nullptr ? peep->Energy : 0; + } + void energy_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto peep = GetPeep(); + if (peep != nullptr) + { + peep->Energy = value; + } + } + + uint8_t energyTarget_get() const + { + auto peep = GetPeep(); + return peep != nullptr ? peep->EnergyTarget : 0; + } + void energyTarget_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto peep = GetPeep(); + if (peep != nullptr) + { + peep->EnergyTarget = value; + } + } + + protected: + Peep* GetPeep() const + { + return ::GetEntity(_id); + } + }; + +} // namespace OpenRCT2::Scripting + +#endif diff --git a/src/openrct2/scripting/bindings/entity/ScStaff.cpp b/src/openrct2/scripting/bindings/entity/ScStaff.cpp new file mode 100644 index 0000000000..1d92e4cf29 --- /dev/null +++ b/src/openrct2/scripting/bindings/entity/ScStaff.cpp @@ -0,0 +1,141 @@ +/***************************************************************************** + * Copyright (c) 2014-2021 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#ifdef ENABLE_SCRIPTING + +# include "ScStaff.hpp" + +namespace OpenRCT2::Scripting +{ + ScStaff::ScStaff(uint16_t Id) + : ScPeep(Id) + { + } + + void ScStaff::Register(duk_context* ctx) + { + dukglue_set_base_class(ctx); + dukglue_register_property(ctx, &ScStaff::staffType_get, &ScStaff::staffType_set, "staffType"); + dukglue_register_property(ctx, &ScStaff::colour_get, &ScStaff::colour_set, "colour"); + dukglue_register_property(ctx, &ScStaff::costume_get, &ScStaff::costume_set, "costume"); + dukglue_register_property(ctx, &ScStaff::orders_get, &ScStaff::orders_set, "orders"); + } + + Staff* ScStaff::GetStaff() const + { + return ::GetEntity(_id); + } + + std::string ScStaff::staffType_get() const + { + auto peep = GetStaff(); + if (peep != nullptr) + { + switch (peep->AssignedStaffType) + { + case StaffType::Handyman: + return "handyman"; + case StaffType::Mechanic: + return "mechanic"; + case StaffType::Security: + return "security"; + case StaffType::Entertainer: + return "entertainer"; + case StaffType::Count: + break; + } + } + return ""; + } + + void ScStaff::staffType_set(const std::string& value) + { + ThrowIfGameStateNotMutable(); + auto peep = GetStaff(); + if (peep != nullptr) + { + if (value == "handyman" && peep->AssignedStaffType != StaffType::Handyman) + { + peep->AssignedStaffType = StaffType::Handyman; + peep->SpriteType = PeepSpriteType::Handyman; + } + else if (value == "mechanic" && peep->AssignedStaffType != StaffType::Mechanic) + { + peep->AssignedStaffType = StaffType::Mechanic; + peep->SpriteType = PeepSpriteType::Mechanic; + } + else if (value == "security" && peep->AssignedStaffType != StaffType::Security) + { + peep->AssignedStaffType = StaffType::Security; + peep->SpriteType = PeepSpriteType::Security; + } + else if (value == "entertainer" && peep->AssignedStaffType != StaffType::Entertainer) + { + peep->AssignedStaffType = StaffType::Entertainer; + peep->SpriteType = PeepSpriteType::EntertainerPanda; + } + } + } + + uint8_t ScStaff::colour_get() const + { + auto peep = GetStaff(); + return peep != nullptr ? peep->TshirtColour : 0; + } + + void ScStaff::colour_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto peep = GetStaff(); + if (peep != nullptr) + { + peep->TshirtColour = value; + peep->TrousersColour = value; + } + } + + uint8_t ScStaff::costume_get() const + { + auto peep = GetStaff(); + if (peep != nullptr && peep->AssignedStaffType == StaffType::Entertainer) + { + return peep->GetCostume(); + } + return 0; + } + + void ScStaff::costume_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto peep = GetStaff(); + if (peep != nullptr) + { + peep->SetCostume(value); + } + } + + uint8_t ScStaff::orders_get() const + { + auto peep = GetStaff(); + return peep != nullptr ? peep->StaffOrders : 0; + } + + void ScStaff::orders_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto peep = GetStaff(); + if (peep != nullptr) + { + peep->StaffOrders = value; + } + } + +} // namespace OpenRCT2::Scripting + +#endif diff --git a/src/openrct2/scripting/bindings/entity/ScStaff.hpp b/src/openrct2/scripting/bindings/entity/ScStaff.hpp new file mode 100644 index 0000000000..0102144075 --- /dev/null +++ b/src/openrct2/scripting/bindings/entity/ScStaff.hpp @@ -0,0 +1,43 @@ +/***************************************************************************** + * Copyright (c) 2014-2021 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#pragma once + +#ifdef ENABLE_SCRIPTING + +# include "ScPeep.hpp" + +namespace OpenRCT2::Scripting +{ + class ScStaff : public ScPeep + { + public: + ScStaff(uint16_t Id); + + static void Register(duk_context* ctx); + + private: + Staff* GetStaff() const; + + std::string staffType_get() const; + void staffType_set(const std::string& value); + + uint8_t colour_get() const; + void colour_set(uint8_t value); + + uint8_t costume_get() const; + void costume_set(uint8_t value); + + uint8_t orders_get() const; + void orders_set(uint8_t value); + }; + +} // namespace OpenRCT2::Scripting + +#endif diff --git a/src/openrct2/scripting/bindings/entity/ScVehicle.cpp b/src/openrct2/scripting/bindings/entity/ScVehicle.cpp new file mode 100644 index 0000000000..90389d7157 --- /dev/null +++ b/src/openrct2/scripting/bindings/entity/ScVehicle.cpp @@ -0,0 +1,465 @@ +/***************************************************************************** + * Copyright (c) 2014-2021 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#include "ScVehicle.hpp" + +#include "../ride/ScRide.hpp" + +#ifdef ENABLE_SCRIPTING + +namespace OpenRCT2::Scripting +{ + static const DukEnumMap VehicleStatusMap({ + { "moving_to_end_of_station", Vehicle::Status::MovingToEndOfStation }, + { "waiting_for_passengers", Vehicle::Status::WaitingForPassengers }, + { "waiting_to_depart", Vehicle::Status::WaitingToDepart }, + { "departing", Vehicle::Status::Departing }, + { "travelling", Vehicle::Status::Travelling }, + { "arriving", Vehicle::Status::Arriving }, + { "unloading_passengers", Vehicle::Status::UnloadingPassengers }, + { "travelling_boat", Vehicle::Status::TravellingBoat }, + { "crashing", Vehicle::Status::Crashing }, + { "crashed", Vehicle::Status::Crashed }, + { "travelling_dodgems", Vehicle::Status::TravellingDodgems }, + { "swinging", Vehicle::Status::Swinging }, + { "rotating", Vehicle::Status::Rotating }, + { "ferris_wheel_rotating", Vehicle::Status::FerrisWheelRotating }, + { "simulator_operating", Vehicle::Status::SimulatorOperating }, + { "showing_film", Vehicle::Status::ShowingFilm }, + { "space_rings_operating", Vehicle::Status::SpaceRingsOperating }, + { "top_spin_operating", Vehicle::Status::TopSpinOperating }, + { "haunted_house_operating", Vehicle::Status::HauntedHouseOperating }, + { "doing_circus_show", Vehicle::Status::DoingCircusShow }, + { "crooked_house_operating", Vehicle::Status::CrookedHouseOperating }, + { "waiting_for_cable_lift", Vehicle::Status::WaitingForCableLift }, + { "travelling_cable_lift", Vehicle::Status::TravellingCableLift }, + { "stopping", Vehicle::Status::Stopping }, + { "waiting_for_passengers_17", Vehicle::Status::WaitingForPassengers17 }, + { "waiting_to_start", Vehicle::Status::WaitingToStart }, + { "starting", Vehicle::Status::Starting }, + { "operating_1a", Vehicle::Status::Operating1A }, + { "stopping_1b", Vehicle::Status::Stopping1B }, + { "unloading_passengers_1c", Vehicle::Status::UnloadingPassengers1C }, + { "stopped_by_block_brake", Vehicle::Status::StoppedByBlockBrakes }, + }); + + ScVehicle::ScVehicle(uint16_t id) + : ScEntity(id) + { + } + + void ScVehicle::Register(duk_context* ctx) + { + dukglue_set_base_class(ctx); + dukglue_register_property(ctx, &ScVehicle::ride_get, &ScVehicle::ride_set, "ride"); + dukglue_register_property(ctx, &ScVehicle::rideObject_get, &ScVehicle::rideObject_set, "rideObject"); + dukglue_register_property(ctx, &ScVehicle::vehicleObject_get, &ScVehicle::vehicleObject_set, "vehicleObject"); + dukglue_register_property(ctx, &ScVehicle::spriteType_get, &ScVehicle::spriteType_set, "spriteType"); + dukglue_register_property(ctx, &ScVehicle::numSeats_get, &ScVehicle::numSeats_set, "numSeats"); + dukglue_register_property(ctx, &ScVehicle::nextCarOnTrain_get, &ScVehicle::nextCarOnTrain_set, "nextCarOnTrain"); + dukglue_register_property( + ctx, &ScVehicle::previousCarOnRide_get, &ScVehicle::previousCarOnRide_set, "previousCarOnRide"); + dukglue_register_property(ctx, &ScVehicle::nextCarOnRide_get, &ScVehicle::nextCarOnRide_set, "nextCarOnRide"); + dukglue_register_property(ctx, &ScVehicle::currentStation_get, &ScVehicle::currentStation_set, "currentStation"); + dukglue_register_property(ctx, &ScVehicle::mass_get, &ScVehicle::mass_set, "mass"); + dukglue_register_property(ctx, &ScVehicle::acceleration_get, &ScVehicle::acceleration_set, "acceleration"); + dukglue_register_property(ctx, &ScVehicle::velocity_get, &ScVehicle::velocity_set, "velocity"); + dukglue_register_property(ctx, &ScVehicle::bankRotation_get, &ScVehicle::bankRotation_set, "bankRotation"); + dukglue_register_property(ctx, &ScVehicle::colours_get, &ScVehicle::colours_set, "colours"); + dukglue_register_property(ctx, &ScVehicle::trackLocation_get, &ScVehicle::trackLocation_set, "trackLocation"); + dukglue_register_property(ctx, &ScVehicle::trackProgress_get, nullptr, "trackProgress"); + dukglue_register_property(ctx, &ScVehicle::remainingDistance_get, nullptr, "remainingDistance"); + dukglue_register_property( + ctx, &ScVehicle::poweredAcceleration_get, &ScVehicle::poweredAcceleration_set, "poweredAcceleration"); + dukglue_register_property(ctx, &ScVehicle::poweredMaxSpeed_get, &ScVehicle::poweredMaxSpeed_set, "poweredMaxSpeed"); + dukglue_register_property(ctx, &ScVehicle::status_get, &ScVehicle::status_set, "status"); + dukglue_register_property(ctx, &ScVehicle::guests_get, nullptr, "peeps"); + dukglue_register_property(ctx, &ScVehicle::guests_get, nullptr, "guests"); + dukglue_register_property(ctx, &ScVehicle::gForces_get, nullptr, "gForces"); + dukglue_register_method(ctx, &ScVehicle::travelBy, "travelBy"); + } + + Vehicle* ScVehicle::GetVehicle() const + { + return ::GetEntity(_id); + } + + uint8_t ScVehicle::rideObject_get() const + { + auto vehicle = GetVehicle(); + return vehicle != nullptr ? vehicle->ride_subtype : 0; + } + void ScVehicle::rideObject_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto vehicle = GetVehicle(); + if (vehicle != nullptr) + { + vehicle->ride_subtype = value; + } + } + + uint8_t ScVehicle::vehicleObject_get() const + { + auto vehicle = GetVehicle(); + return vehicle != nullptr ? vehicle->vehicle_type : 0; + } + void ScVehicle::vehicleObject_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto vehicle = GetVehicle(); + if (vehicle != nullptr) + { + vehicle->vehicle_type = value; + } + } + + uint8_t ScVehicle::spriteType_get() const + { + auto vehicle = GetVehicle(); + return vehicle != nullptr ? vehicle->Pitch : 0; + } + void ScVehicle::spriteType_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto vehicle = GetVehicle(); + if (vehicle != nullptr) + { + vehicle->Pitch = value; + } + } + + ride_id_t ScVehicle::ride_get() const + { + auto vehicle = GetVehicle(); + return vehicle != nullptr ? vehicle->ride : 0; + } + void ScVehicle::ride_set(ride_id_t value) + { + ThrowIfGameStateNotMutable(); + auto vehicle = GetVehicle(); + if (vehicle != nullptr) + { + vehicle->ride = value; + } + } + + uint8_t ScVehicle::numSeats_get() const + { + auto vehicle = GetVehicle(); + return vehicle != nullptr ? vehicle->num_seats & VEHICLE_SEAT_NUM_MASK : 0; + } + void ScVehicle::numSeats_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto vehicle = GetVehicle(); + if (vehicle != nullptr) + { + vehicle->num_seats &= ~VEHICLE_SEAT_NUM_MASK; + vehicle->num_seats |= value & VEHICLE_SEAT_NUM_MASK; + } + } + + DukValue ScVehicle::nextCarOnTrain_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto vehicle = GetVehicle(); + if (vehicle != nullptr) + { + if (vehicle->next_vehicle_on_train != SPRITE_INDEX_NULL) + { + return ToDuk(ctx, vehicle->next_vehicle_on_train); + } + } + return ToDuk(ctx, nullptr); + } + void ScVehicle::nextCarOnTrain_set(DukValue value) + { + ThrowIfGameStateNotMutable(); + auto vehicle = GetVehicle(); + if (vehicle != nullptr) + { + if (value.type() == DukValue::Type::NUMBER) + { + vehicle->next_vehicle_on_train = static_cast(value.as_int()); + } + else + { + vehicle->next_vehicle_on_train = SPRITE_INDEX_NULL; + } + } + } + + uint16_t ScVehicle::previousCarOnRide_get() const + { + auto vehicle = GetVehicle(); + return vehicle != nullptr ? vehicle->prev_vehicle_on_ride : 0; + } + void ScVehicle::previousCarOnRide_set(uint16_t value) + { + ThrowIfGameStateNotMutable(); + auto vehicle = GetVehicle(); + if (vehicle != nullptr) + { + vehicle->prev_vehicle_on_ride = value; + } + } + + uint16_t ScVehicle::nextCarOnRide_get() const + { + auto vehicle = GetVehicle(); + return vehicle != nullptr ? vehicle->next_vehicle_on_ride : 0; + } + void ScVehicle::nextCarOnRide_set(uint16_t value) + { + ThrowIfGameStateNotMutable(); + auto vehicle = GetVehicle(); + if (vehicle != nullptr) + { + vehicle->next_vehicle_on_ride = value; + } + } + + StationIndex ScVehicle::currentStation_get() const + { + auto vehicle = GetVehicle(); + return vehicle != nullptr ? vehicle->current_station : 0; + } + void ScVehicle::currentStation_set(StationIndex value) + { + ThrowIfGameStateNotMutable(); + auto vehicle = GetVehicle(); + if (vehicle != nullptr) + { + vehicle->current_station = value; + } + } + + uint16_t ScVehicle::mass_get() const + { + auto vehicle = GetVehicle(); + return vehicle != nullptr ? vehicle->mass : 0; + } + void ScVehicle::mass_set(uint16_t value) + { + ThrowIfGameStateNotMutable(); + auto vehicle = GetVehicle(); + if (vehicle != nullptr) + { + vehicle->mass = value; + } + } + + int32_t ScVehicle::acceleration_get() const + { + auto vehicle = GetVehicle(); + return vehicle != nullptr ? vehicle->acceleration : 0; + } + void ScVehicle::acceleration_set(int32_t value) + { + ThrowIfGameStateNotMutable(); + auto vehicle = GetVehicle(); + if (vehicle != nullptr) + { + vehicle->acceleration = value; + } + } + + int32_t ScVehicle::velocity_get() const + { + auto vehicle = GetVehicle(); + return vehicle != nullptr ? vehicle->velocity : 0; + } + void ScVehicle::velocity_set(int32_t value) + { + ThrowIfGameStateNotMutable(); + auto vehicle = GetVehicle(); + if (vehicle != nullptr) + { + vehicle->velocity = value; + } + } + + uint8_t ScVehicle::bankRotation_get() const + { + auto vehicle = GetVehicle(); + return vehicle != nullptr ? vehicle->bank_rotation : 0; + } + void ScVehicle::bankRotation_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto vehicle = GetVehicle(); + if (vehicle != nullptr) + { + vehicle->bank_rotation = value; + } + } + + DukValue ScVehicle::colours_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto vehicle = GetVehicle(); + if (vehicle != nullptr) + { + VehicleColour colours; + colours.Body = vehicle->colours.body_colour; + colours.Trim = vehicle->colours.trim_colour; + colours.Ternary = vehicle->colours_extended; + return ToDuk(ctx, colours); + } + return ToDuk(ctx, nullptr); + } + void ScVehicle::colours_set(const DukValue& value) + { + ThrowIfGameStateNotMutable(); + auto vehicle = GetVehicle(); + if (vehicle != nullptr) + { + auto colours = FromDuk(value); + vehicle->colours.body_colour = colours.Body; + vehicle->colours.trim_colour = colours.Trim; + vehicle->colours_extended = colours.Ternary; + } + } + + DukValue ScVehicle::trackLocation_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto vehicle = GetVehicle(); + if (vehicle != nullptr) + { + auto coords = CoordsXYZD(vehicle->TrackLocation, vehicle->GetTrackDirection()); + return ToDuk(ctx, coords); + } + return ToDuk(ctx, nullptr); + } + void ScVehicle::trackLocation_set(const DukValue& value) + { + ThrowIfGameStateNotMutable(); + auto vehicle = GetVehicle(); + if (vehicle != nullptr) + { + auto coords = FromDuk(value); + vehicle->TrackLocation = CoordsXYZ(coords.x, coords.y, coords.z); + vehicle->SetTrackDirection(coords.direction); + } + } + + uint16_t ScVehicle::trackProgress_get() const + { + auto vehicle = GetVehicle(); + return vehicle != nullptr ? vehicle->track_progress : 0; + } + + int32_t ScVehicle::remainingDistance_get() const + { + auto vehicle = GetVehicle(); + return vehicle != nullptr ? vehicle->remaining_distance : 0; + } + + uint8_t ScVehicle::poweredAcceleration_get() const + { + auto vehicle = GetVehicle(); + return vehicle != nullptr ? vehicle->powered_acceleration : 0; + } + void ScVehicle::poweredAcceleration_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto vehicle = GetVehicle(); + if (vehicle != nullptr) + { + vehicle->powered_acceleration = value; + } + } + + uint8_t ScVehicle::poweredMaxSpeed_get() const + { + auto vehicle = GetVehicle(); + return vehicle != nullptr ? vehicle->speed : 0; + } + void ScVehicle::poweredMaxSpeed_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto vehicle = GetVehicle(); + if (vehicle != nullptr) + { + vehicle->speed = value; + } + } + + std::string ScVehicle::status_get() const + { + auto vehicle = GetVehicle(); + if (vehicle != nullptr) + { + return std::string(VehicleStatusMap[vehicle->status]); + } + return {}; + } + void ScVehicle::status_set(const std::string& value) + { + ThrowIfGameStateNotMutable(); + auto vehicle = GetVehicle(); + if (vehicle != nullptr) + { + vehicle->status = VehicleStatusMap[value]; + } + } + + std::vector ScVehicle::guests_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + std::vector result; + auto vehicle = GetVehicle(); + if (vehicle != nullptr) + { + size_t len = 0; + for (size_t i = 0; i < std::size(vehicle->peep); i++) + { + auto peep = vehicle->peep[i]; + if (peep == SPRITE_INDEX_NULL) + { + result.push_back(ToDuk(ctx, nullptr)); + } + else + { + result.push_back(ToDuk(ctx, peep)); + len = i + 1; + } + } + result.resize(len); + } + return result; + } + + DukValue ScVehicle::gForces_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto vehicle = GetVehicle(); + if (vehicle != nullptr) + { + GForces gForces = vehicle->GetGForces(); + return ToDuk(ctx, gForces); + } + return ToDuk(ctx, nullptr); + } + + void ScVehicle::travelBy(int32_t value) + { + ThrowIfGameStateNotMutable(); + auto vehicle = GetVehicle(); + if (vehicle != nullptr) + { + vehicle->MoveRelativeDistance(value); + } + } + +} // namespace OpenRCT2::Scripting + +#endif diff --git a/src/openrct2/scripting/bindings/entity/ScVehicle.hpp b/src/openrct2/scripting/bindings/entity/ScVehicle.hpp new file mode 100644 index 0000000000..57d29c6194 --- /dev/null +++ b/src/openrct2/scripting/bindings/entity/ScVehicle.hpp @@ -0,0 +1,96 @@ +/***************************************************************************** + * Copyright (c) 2014-2021 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#pragma once + +#ifdef ENABLE_SCRIPTING + +# include "../../../ride/Ride.h" +# include "ScEntity.hpp" + +namespace OpenRCT2::Scripting +{ + class ScVehicle : public ScEntity + { + public: + ScVehicle(uint16_t id); + + static void Register(duk_context* ctx); + + private: + Vehicle* GetVehicle() const; + + uint8_t rideObject_get() const; + void rideObject_set(uint8_t value); + + uint8_t vehicleObject_get() const; + void vehicleObject_set(uint8_t value); + + uint8_t spriteType_get() const; + void spriteType_set(uint8_t value); + + ride_id_t ride_get() const; + void ride_set(ride_id_t value); + + uint8_t numSeats_get() const; + void numSeats_set(uint8_t value); + + DukValue nextCarOnTrain_get() const; + void nextCarOnTrain_set(DukValue value); + + uint16_t previousCarOnRide_get() const; + void previousCarOnRide_set(uint16_t value); + + uint16_t nextCarOnRide_get() const; + void nextCarOnRide_set(uint16_t value); + + StationIndex currentStation_get() const; + void currentStation_set(StationIndex value); + + uint16_t mass_get() const; + void mass_set(uint16_t value); + + int32_t acceleration_get() const; + void acceleration_set(int32_t value); + + int32_t velocity_get() const; + void velocity_set(int32_t value); + + uint8_t bankRotation_get() const; + void bankRotation_set(uint8_t value); + + DukValue colours_get() const; + void colours_set(const DukValue& value); + + DukValue trackLocation_get() const; + void trackLocation_set(const DukValue& value); + + uint16_t trackProgress_get() const; + + int32_t remainingDistance_get() const; + + uint8_t poweredAcceleration_get() const; + void poweredAcceleration_set(uint8_t value); + + uint8_t poweredMaxSpeed_get() const; + void poweredMaxSpeed_set(uint8_t value); + + std::string status_get() const; + void status_set(const std::string& value); + + std::vector guests_get() const; + + DukValue gForces_get() const; + + void travelBy(int32_t value); + }; + +} // namespace OpenRCT2::Scripting + +#endif diff --git a/src/openrct2/scripting/ScCheats.hpp b/src/openrct2/scripting/bindings/game/ScCheats.hpp similarity index 99% rename from src/openrct2/scripting/ScCheats.hpp rename to src/openrct2/scripting/bindings/game/ScCheats.hpp index fdcb606955..6c56554417 100644 --- a/src/openrct2/scripting/ScCheats.hpp +++ b/src/openrct2/scripting/bindings/game/ScCheats.hpp @@ -11,9 +11,9 @@ #ifdef ENABLE_SCRIPTING -# include "../Cheats.h" -# include "Duktape.hpp" -# include "ScriptEngine.h" +# include "../../../Cheats.h" +# include "../../Duktape.hpp" +# include "../../ScriptEngine.h" namespace OpenRCT2::Scripting { diff --git a/src/openrct2/scripting/ScConfiguration.hpp b/src/openrct2/scripting/bindings/game/ScConfiguration.hpp similarity index 97% rename from src/openrct2/scripting/ScConfiguration.hpp rename to src/openrct2/scripting/bindings/game/ScConfiguration.hpp index 69fb3ab8d8..0a63b35065 100644 --- a/src/openrct2/scripting/ScConfiguration.hpp +++ b/src/openrct2/scripting/bindings/game/ScConfiguration.hpp @@ -11,11 +11,11 @@ #ifdef ENABLE_SCRIPTING -# include "../Context.h" -# include "../config/Config.h" -# include "../localisation/LocalisationService.h" -# include "Duktape.hpp" -# include "ScriptEngine.h" +# include "../../../Context.h" +# include "../../../config/Config.h" +# include "../../../localisation/LocalisationService.h" +# include "../../Duktape.hpp" +# include "../../ScriptEngine.h" namespace OpenRCT2::Scripting { diff --git a/src/openrct2/scripting/ScConsole.hpp b/src/openrct2/scripting/bindings/game/ScConsole.hpp similarity index 93% rename from src/openrct2/scripting/ScConsole.hpp rename to src/openrct2/scripting/bindings/game/ScConsole.hpp index 6d15102512..1ab39af85d 100644 --- a/src/openrct2/scripting/ScConsole.hpp +++ b/src/openrct2/scripting/bindings/game/ScConsole.hpp @@ -11,9 +11,9 @@ #ifdef ENABLE_SCRIPTING -# include "../interface/InteractiveConsole.h" -# include "Duktape.hpp" -# include "ScriptEngine.h" +# include "../../../interface/InteractiveConsole.h" +# include "../../Duktape.hpp" +# include "../../ScriptEngine.h" namespace OpenRCT2::Scripting { diff --git a/src/openrct2/scripting/ScContext.hpp b/src/openrct2/scripting/bindings/game/ScContext.hpp similarity index 96% rename from src/openrct2/scripting/ScContext.hpp rename to src/openrct2/scripting/bindings/game/ScContext.hpp index 049e37963e..1005d9299b 100644 --- a/src/openrct2/scripting/ScContext.hpp +++ b/src/openrct2/scripting/bindings/game/ScContext.hpp @@ -11,17 +11,17 @@ #ifdef ENABLE_SCRIPTING -# include "../actions/GameAction.h" -# include "../interface/Screenshot.h" -# include "../localisation/Formatting.h" -# include "../object/ObjectManager.h" -# include "../scenario/Scenario.h" -# include "Duktape.hpp" -# include "HookEngine.h" -# include "ScConfiguration.hpp" -# include "ScDisposable.hpp" -# include "ScObject.hpp" -# include "ScriptEngine.h" +# include "../../../actions/GameAction.h" +# include "../../../interface/Screenshot.h" +# include "../../../localisation/Formatting.h" +# include "../../../object/ObjectManager.h" +# include "../../../scenario/Scenario.h" +# include "../../Duktape.hpp" +# include "../../HookEngine.h" +# include "../../ScriptEngine.h" +# include "../game/ScConfiguration.hpp" +# include "../game/ScDisposable.hpp" +# include "../object/ScObject.hpp" # include # include diff --git a/src/openrct2/scripting/ScDisposable.hpp b/src/openrct2/scripting/bindings/game/ScDisposable.hpp similarity index 97% rename from src/openrct2/scripting/ScDisposable.hpp rename to src/openrct2/scripting/bindings/game/ScDisposable.hpp index c3c11450c9..c3033295b5 100644 --- a/src/openrct2/scripting/ScDisposable.hpp +++ b/src/openrct2/scripting/bindings/game/ScDisposable.hpp @@ -11,7 +11,7 @@ #ifdef ENABLE_SCRIPTING -# include "Duktape.hpp" +# include "../../Duktape.hpp" # include diff --git a/src/openrct2/scripting/bindings/network/ScNetwork.cpp b/src/openrct2/scripting/bindings/network/ScNetwork.cpp new file mode 100644 index 0000000000..7b10801034 --- /dev/null +++ b/src/openrct2/scripting/bindings/network/ScNetwork.cpp @@ -0,0 +1,295 @@ +/***************************************************************************** + * Copyright (c) 2014-2020 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#ifdef ENABLE_SCRIPTING + +# include "ScNetwork.hpp" + +# include "../../../Context.h" +# include "../../../actions/NetworkModifyGroupAction.h" +# include "../../../actions/PlayerKickAction.h" +# include "../../../network/NetworkAction.h" +# include "../../../network/network.h" + +namespace OpenRCT2::Scripting +{ + ScNetwork::ScNetwork(duk_context* ctx) + : _context(ctx) + { + } + + std::string ScNetwork::mode_get() const + { +# ifndef DISABLE_NETWORK + switch (network_get_mode()) + { + case NETWORK_MODE_SERVER: + return "server"; + case NETWORK_MODE_CLIENT: + return "client"; + } +# endif + return "none"; + } + + int32_t ScNetwork::numPlayers_get() const + { +# ifndef DISABLE_NETWORK + return network_get_num_players(); +# else + return 0; +# endif + } + + int32_t ScNetwork::numGroups_get() const + { +# ifndef DISABLE_NETWORK + return network_get_num_groups(); +# else + return 0; +# endif + } + + int32_t ScNetwork::defaultGroup_get() const + { +# ifndef DISABLE_NETWORK + return network_get_default_group(); +# else + return 0; +# endif + } + + void ScNetwork::defaultGroup_set(int32_t value) + { +# ifndef DISABLE_NETWORK + auto action = NetworkModifyGroupAction(ModifyGroupType::SetDefault, value); + GameActions::Execute(&action); +# endif + } + + std::vector> ScNetwork::groups_get() const + { + std::vector> groups; +# ifndef DISABLE_NETWORK + auto numGroups = network_get_num_groups(); + for (int32_t i = 0; i < numGroups; i++) + { + auto groupId = network_get_group_id(i); + groups.push_back(std::make_shared(groupId)); + } +# endif + return groups; + } + + std::vector> ScNetwork::players_get() const + { + std::vector> players; +# ifndef DISABLE_NETWORK + auto numPlayers = network_get_num_players(); + for (int32_t i = 0; i < numPlayers; i++) + { + auto playerId = network_get_player_id(i); + players.push_back(std::make_shared(playerId)); + } +# endif + return players; + } + + std::shared_ptr ScNetwork::currentPlayer_get() const + { + std::shared_ptr player; +# ifndef DISABLE_NETWORK + auto playerId = network_get_current_player_id(); + player = std::make_shared(playerId); +# endif + return player; + } + + std::shared_ptr ScNetwork::getPlayer(int32_t index) const + { +# ifndef DISABLE_NETWORK + auto numPlayers = network_get_num_players(); + if (index < numPlayers) + { + auto playerId = network_get_player_id(index); + return std::make_shared(playerId); + } +# endif + return nullptr; + } + + DukValue ScNetwork::stats_get() const + { +# ifndef DISABLE_NETWORK + auto obj = OpenRCT2::Scripting::DukObject(_context); + auto networkStats = network_get_stats(); + { + duk_push_array(_context); + duk_uarridx_t index = 0; + for (auto v : networkStats.bytesReceived) + { + duk_push_number(_context, v); + duk_put_prop_index(_context, -2, index); + index++; + } + obj.Set("bytesReceived", DukValue::take_from_stack(_context)); + } + { + duk_push_array(_context); + duk_uarridx_t index = 0; + for (auto v : networkStats.bytesSent) + { + duk_push_number(_context, v); + duk_put_prop_index(_context, -2, index); + index++; + } + obj.Set("bytesSent", DukValue::take_from_stack(_context)); + } + return obj.Take(); +# else + return ToDuk(_context, nullptr); +# endif + } + + std::shared_ptr ScNetwork::getGroup(int32_t index) const + { +# ifndef DISABLE_NETWORK + auto numGroups = network_get_num_groups(); + if (index < numGroups) + { + auto groupId = network_get_group_id(index); + return std::make_shared(groupId); + } +# endif + return nullptr; + } + + void ScNetwork::addGroup() + { +# ifndef DISABLE_NETWORK + auto networkModifyGroup = NetworkModifyGroupAction(ModifyGroupType::AddGroup); + GameActions::Execute(&networkModifyGroup); +# endif + } + + void ScNetwork::removeGroup(int32_t index) + { +# ifndef DISABLE_NETWORK + auto numGroups = network_get_num_groups(); + if (index < numGroups) + { + auto groupId = network_get_group_id(index); + auto networkAction = NetworkModifyGroupAction(ModifyGroupType::RemoveGroup, groupId); + GameActions::Execute(&networkAction); + } +# endif + } + + void ScNetwork::kickPlayer(int32_t index) + { +# ifndef DISABLE_NETWORK + auto numPlayers = network_get_num_players(); + if (index < numPlayers) + { + auto playerId = network_get_player_id(index); + auto kickPlayerAction = PlayerKickAction(playerId); + GameActions::Execute(&kickPlayerAction); + } +# endif + } + + void ScNetwork::sendMessage(std::string message, DukValue players) + { +# ifndef DISABLE_NETWORK + if (players.is_array()) + { + if (network_get_mode() == NETWORK_MODE_SERVER) + { + std::vector playerIds; + auto playerArray = players.as_array(); + for (const auto& item : playerArray) + { + if (item.type() == DukValue::Type::NUMBER) + { + playerIds.push_back(static_cast(item.as_int())); + } + } + if (!playerArray.empty()) + { + network_send_chat(message.c_str(), playerIds); + } + } + else + { + duk_error(players.context(), DUK_ERR_ERROR, "Only servers can send private messages."); + } + } + else + { + network_send_chat(message.c_str()); + } +# endif + } + +# ifndef DISABLE_NETWORK + std::shared_ptr ScNetwork::createListener() + { + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto plugin = scriptEngine.GetExecInfo().GetCurrentPlugin(); + auto socket = std::make_shared(plugin); + scriptEngine.AddSocket(socket); + return socket; + } +# else + void ScNetwork::createListener() + { + duk_error(_context, DUK_ERR_ERROR, "Networking has been disabled."); + } +# endif + +# ifndef DISABLE_NETWORK + std::shared_ptr ScNetwork::createSocket() + { + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto plugin = scriptEngine.GetExecInfo().GetCurrentPlugin(); + auto socket = std::make_shared(plugin); + scriptEngine.AddSocket(socket); + return socket; + } +# else + void ScNetwork::createSocket() + { + duk_error(_context, DUK_ERR_ERROR, "Networking has been disabled."); + } +# endif + + void ScNetwork::Register(duk_context* ctx) + { + dukglue_register_property(ctx, &ScNetwork::mode_get, nullptr, "mode"); + dukglue_register_property(ctx, &ScNetwork::numGroups_get, nullptr, "numGroups"); + dukglue_register_property(ctx, &ScNetwork::numPlayers_get, nullptr, "numPlayers"); + dukglue_register_property(ctx, &ScNetwork::groups_get, nullptr, "groups"); + dukglue_register_property(ctx, &ScNetwork::players_get, nullptr, "players"); + dukglue_register_property(ctx, &ScNetwork::currentPlayer_get, nullptr, "currentPlayer"); + dukglue_register_property(ctx, &ScNetwork::defaultGroup_get, &ScNetwork::defaultGroup_set, "defaultGroup"); + dukglue_register_property(ctx, &ScNetwork::stats_get, nullptr, "stats"); + dukglue_register_method(ctx, &ScNetwork::addGroup, "addGroup"); + dukglue_register_method(ctx, &ScNetwork::getGroup, "getGroup"); + dukglue_register_method(ctx, &ScNetwork::removeGroup, "removeGroup"); + dukglue_register_method(ctx, &ScNetwork::getPlayer, "getPlayer"); + dukglue_register_method(ctx, &ScNetwork::kickPlayer, "kickPlayer"); + dukglue_register_method(ctx, &ScNetwork::sendMessage, "sendMessage"); + + dukglue_register_method(ctx, &ScNetwork::createListener, "createListener"); + dukglue_register_method(ctx, &ScNetwork::createSocket, "createSocket"); + } + +} // namespace OpenRCT2::Scripting + +#endif diff --git a/src/openrct2/scripting/bindings/network/ScNetwork.hpp b/src/openrct2/scripting/bindings/network/ScNetwork.hpp new file mode 100644 index 0000000000..e659b110d5 --- /dev/null +++ b/src/openrct2/scripting/bindings/network/ScNetwork.hpp @@ -0,0 +1,74 @@ +/***************************************************************************** + * Copyright (c) 2014-2020 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#pragma once + +#ifdef ENABLE_SCRIPTING + +# include "../../Duktape.hpp" +# include "ScPlayer.hpp" +# include "ScPlayerGroup.hpp" +# include "ScSocket.hpp" + +namespace OpenRCT2::Scripting +{ + class ScNetwork + { + private: +# ifdef __clang__ + [[maybe_unused]] +# endif + duk_context* _context; + + public: + ScNetwork(duk_context* ctx); + + std::string mode_get() const; + int32_t numPlayers_get() const; + int32_t numGroups_get() const; + int32_t defaultGroup_get() const; + void defaultGroup_set(int32_t value); + + std::vector> groups_get() const; + + std::vector> players_get() const; + + std::shared_ptr currentPlayer_get() const; + + std::shared_ptr getPlayer(int32_t index) const; + + DukValue stats_get() const; + + std::shared_ptr getGroup(int32_t index) const; + + void addGroup(); + + void removeGroup(int32_t index); + + void kickPlayer(int32_t index); + + void sendMessage(std::string message, DukValue players); + +# ifndef DISABLE_NETWORK + std::shared_ptr createListener(); +# else + void createListener(); +# endif + +# ifndef DISABLE_NETWORK + std::shared_ptr createSocket(); +# else + void createSocket(); +# endif + + static void Register(duk_context* ctx); + }; +} // namespace OpenRCT2::Scripting + +#endif diff --git a/src/openrct2/scripting/bindings/network/ScPlayer.cpp b/src/openrct2/scripting/bindings/network/ScPlayer.cpp new file mode 100644 index 0000000000..86fd493ba6 --- /dev/null +++ b/src/openrct2/scripting/bindings/network/ScPlayer.cpp @@ -0,0 +1,122 @@ +/***************************************************************************** + * Copyright (c) 2014-2021 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#ifdef ENABLE_SCRIPTING + +# include "ScPlayer.hpp" + +# include "../../../Context.h" +# include "../../../actions/PlayerSetGroupAction.h" +# include "../../../network/NetworkAction.h" +# include "../../../network/network.h" + +namespace OpenRCT2::Scripting +{ + ScPlayer::ScPlayer(int32_t id) + : _id(id) + { + } + + int32_t ScPlayer::id_get() const + { + return _id; + } + + std::string ScPlayer::name_get() const + { +# ifndef DISABLE_NETWORK + auto index = network_get_player_index(_id); + if (index == -1) + return {}; + return network_get_player_name(index); +# else + return {}; +# endif + } + + int32_t ScPlayer::group_get() const + { +# ifndef DISABLE_NETWORK + auto index = network_get_player_index(_id); + if (index == -1) + return {}; + return network_get_player_group(index); +# else + return 0; +# endif + } + void ScPlayer::group_set(int32_t value) + { +# ifndef DISABLE_NETWORK + auto playerSetGroupAction = PlayerSetGroupAction(_id, value); + GameActions::Execute(&playerSetGroupAction); +# endif + } + + int32_t ScPlayer::ping_get() const + { +# ifndef DISABLE_NETWORK + auto index = network_get_player_index(_id); + if (index == -1) + return {}; + return network_get_player_ping(index); +# else + return 0; +# endif + } + + int32_t ScPlayer::commandsRan_get() const + { +# ifndef DISABLE_NETWORK + auto index = network_get_player_index(_id); + if (index == -1) + return {}; + return network_get_player_commands_ran(index); +# else + return 0; +# endif + } + + int32_t ScPlayer::moneySpent_get() const + { +# ifndef DISABLE_NETWORK + auto index = network_get_player_index(_id); + if (index == -1) + return {}; + return network_get_player_money_spent(index); +# else + return 0; +# endif + } + + std::string ScPlayer::ipAddress_get() const + { + return network_get_player_ip_address(_id); + } + + std::string ScPlayer::publicKeyHash_get() const + { + return network_get_player_public_key_hash(_id); + } + + void ScPlayer::Register(duk_context* ctx) + { + dukglue_register_property(ctx, &ScPlayer::id_get, nullptr, "id"); + dukglue_register_property(ctx, &ScPlayer::name_get, nullptr, "name"); + dukglue_register_property(ctx, &ScPlayer::group_get, &ScPlayer::group_set, "group"); + dukglue_register_property(ctx, &ScPlayer::ping_get, nullptr, "ping"); + dukglue_register_property(ctx, &ScPlayer::commandsRan_get, nullptr, "commandsRan"); + dukglue_register_property(ctx, &ScPlayer::moneySpent_get, nullptr, "moneySpent"); + dukglue_register_property(ctx, &ScPlayer::ipAddress_get, nullptr, "ipAddress"); + dukglue_register_property(ctx, &ScPlayer::publicKeyHash_get, nullptr, "publicKeyHash"); + } + +} // namespace OpenRCT2::Scripting + +#endif diff --git a/src/openrct2/scripting/bindings/network/ScPlayer.hpp b/src/openrct2/scripting/bindings/network/ScPlayer.hpp new file mode 100644 index 0000000000..fec0f9de4d --- /dev/null +++ b/src/openrct2/scripting/bindings/network/ScPlayer.hpp @@ -0,0 +1,50 @@ +/***************************************************************************** + * Copyright (c) 2014-2021 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#pragma once + +#ifdef ENABLE_SCRIPTING + +# include "../../Duktape.hpp" + +# include + +namespace OpenRCT2::Scripting +{ + class ScPlayer + { + private: + int32_t _id; + + public: + ScPlayer(int32_t id); + + int32_t id_get() const; + + std::string name_get() const; + + int32_t group_get() const; + void group_set(int32_t value); + + int32_t ping_get() const; + + int32_t commandsRan_get() const; + + int32_t moneySpent_get() const; + + std::string ipAddress_get() const; + + std::string publicKeyHash_get() const; + + static void Register(duk_context* ctx); + }; + +} // namespace OpenRCT2::Scripting + +#endif diff --git a/src/openrct2/scripting/bindings/network/ScPlayerGroup.cpp b/src/openrct2/scripting/bindings/network/ScPlayerGroup.cpp new file mode 100644 index 0000000000..697712f5ba --- /dev/null +++ b/src/openrct2/scripting/bindings/network/ScPlayerGroup.cpp @@ -0,0 +1,150 @@ +/***************************************************************************** + * Copyright (c) 2014-2021 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#ifdef ENABLE_SCRIPTING + +# include "ScPlayerGroup.hpp" + +# include "../../../Context.h" +# include "../../../actions/NetworkModifyGroupAction.h" +# include "../../../actions/PlayerSetGroupAction.h" +# include "../../../network/NetworkAction.h" +# include "../../../network/network.h" +# include "../../Duktape.hpp" + +namespace OpenRCT2::Scripting +{ + ScPlayerGroup::ScPlayerGroup(int32_t id) + : _id(id) + { + } + + int32_t ScPlayerGroup::id_get() + { + return _id; + } + + std::string ScPlayerGroup::name_get() const + { +# ifndef DISABLE_NETWORK + auto index = network_get_group_index(_id); + if (index == -1) + return {}; + return network_get_group_name(index); +# else + return {}; +# endif + } + + void ScPlayerGroup::name_set(std::string value) + { +# ifndef DISABLE_NETWORK + auto action = NetworkModifyGroupAction(ModifyGroupType::SetName, _id, value); + GameActions::Execute(&action); +# endif + } + +# ifndef DISABLE_NETWORK + static std::string TransformPermissionKeyToJS(const std::string& s) + { + auto result = s.substr(sizeof("PERMISSION_") - 1); + for (auto& c : result) + { + c = std::tolower(c); + } + return result; + } + + static std::string TransformPermissionKeyToInternal(const std::string& s) + { + auto result = "PERMISSION_" + s; + for (auto& c : result) + { + c = std::toupper(c); + } + return result; + } +# endif + + std::vector ScPlayerGroup::permissions_get() const + { +# ifndef DISABLE_NETWORK + auto index = network_get_group_index(_id); + if (index == -1) + return {}; + + // Create array of permissions + std::vector result; + auto permissionIndex = 0; + for (const auto& action : NetworkActions::Actions) + { + if (network_can_perform_action(index, static_cast(permissionIndex))) + { + result.push_back(TransformPermissionKeyToJS(action.PermissionName)); + } + permissionIndex++; + } + return result; +# else + return {}; +# endif + } + + void ScPlayerGroup::permissions_set(std::vector value) + { +# ifndef DISABLE_NETWORK + auto groupIndex = network_get_group_index(_id); + if (groupIndex == -1) + return; + + // First clear all permissions + auto networkAction = NetworkModifyGroupAction(ModifyGroupType::SetPermissions, _id, "", 0, PermissionState::ClearAll); + GameActions::Execute(&networkAction); + + std::vector enabledPermissions; + enabledPermissions.resize(NetworkActions::Actions.size()); + for (const auto& p : value) + { + auto permissionName = TransformPermissionKeyToInternal(p); + + auto permissionIndex = 0; + for (const auto& action : NetworkActions::Actions) + { + if (action.PermissionName == permissionName) + { + enabledPermissions[permissionIndex] = true; + } + permissionIndex++; + } + } + + for (size_t i = 0; i < enabledPermissions.size(); i++) + { + auto toggle + = (enabledPermissions[i] != (network_can_perform_action(groupIndex, static_cast(i)) != 0)); + if (toggle) + { + auto networkAction2 = NetworkModifyGroupAction( + ModifyGroupType::SetPermissions, _id, "", static_cast(i), PermissionState::Toggle); + GameActions::Execute(&networkAction2); + } + } +# endif + } + + void ScPlayerGroup::Register(duk_context* ctx) + { + dukglue_register_property(ctx, &ScPlayerGroup::id_get, nullptr, "id"); + dukglue_register_property(ctx, &ScPlayerGroup::name_get, &ScPlayerGroup::name_set, "name"); + dukglue_register_property(ctx, &ScPlayerGroup::permissions_get, &ScPlayerGroup::permissions_set, "permissions"); + } + +} // namespace OpenRCT2::Scripting + +#endif diff --git a/src/openrct2/scripting/bindings/network/ScPlayerGroup.hpp b/src/openrct2/scripting/bindings/network/ScPlayerGroup.hpp new file mode 100644 index 0000000000..757fbda24a --- /dev/null +++ b/src/openrct2/scripting/bindings/network/ScPlayerGroup.hpp @@ -0,0 +1,41 @@ +/***************************************************************************** + * Copyright (c) 2014-2021 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#pragma once + +#ifdef ENABLE_SCRIPTING + +# include "../../Duktape.hpp" + +# include +# include + +namespace OpenRCT2::Scripting +{ + class ScPlayerGroup + { + int32_t _id; + + public: + ScPlayerGroup(int32_t id); + + int32_t id_get(); + + std::string name_get() const; + void name_set(std::string value); + + std::vector permissions_get() const; + void permissions_set(std::vector value); + + static void Register(duk_context* ctx); + }; + +} // namespace OpenRCT2::Scripting + +#endif diff --git a/src/openrct2/scripting/ScSocket.hpp b/src/openrct2/scripting/bindings/network/ScSocket.hpp similarity index 98% rename from src/openrct2/scripting/ScSocket.hpp rename to src/openrct2/scripting/bindings/network/ScSocket.hpp index 804759b66f..add92f5ac1 100644 --- a/src/openrct2/scripting/ScSocket.hpp +++ b/src/openrct2/scripting/bindings/network/ScSocket.hpp @@ -12,11 +12,11 @@ #ifdef ENABLE_SCRIPTING # ifndef DISABLE_NETWORK -# include "../Context.h" -# include "../config/Config.h" -# include "../network/Socket.h" -# include "Duktape.hpp" -# include "ScriptEngine.h" +# include "../../../Context.h" +# include "../../../config/Config.h" +# include "../../../network/Socket.h" +# include "../../Duktape.hpp" +# include "../../ScriptEngine.h" # include # include diff --git a/src/openrct2/scripting/ScObject.hpp b/src/openrct2/scripting/bindings/object/ScObject.hpp similarity index 99% rename from src/openrct2/scripting/ScObject.hpp rename to src/openrct2/scripting/bindings/object/ScObject.hpp index dfa3e0c457..a2d1938ae9 100644 --- a/src/openrct2/scripting/ScObject.hpp +++ b/src/openrct2/scripting/bindings/object/ScObject.hpp @@ -11,13 +11,13 @@ #ifdef ENABLE_SCRIPTING -# include "../Context.h" -# include "../common.h" -# include "../object/ObjectManager.h" -# include "../object/RideObject.h" -# include "../object/SmallSceneryObject.h" -# include "Duktape.hpp" -# include "ScriptEngine.h" +# include "../../../Context.h" +# include "../../../common.h" +# include "../../../object/ObjectManager.h" +# include "../../../object/RideObject.h" +# include "../../../object/SmallSceneryObject.h" +# include "../../Duktape.hpp" +# include "../../ScriptEngine.h" # include diff --git a/src/openrct2/scripting/bindings/ride/ScRide.cpp b/src/openrct2/scripting/bindings/ride/ScRide.cpp new file mode 100644 index 0000000000..9e81db6ce2 --- /dev/null +++ b/src/openrct2/scripting/bindings/ride/ScRide.cpp @@ -0,0 +1,530 @@ +/***************************************************************************** + * Copyright (c) 2020 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#ifdef ENABLE_SCRIPTING + +# include "ScRide.hpp" + +# include "../../../Context.h" +# include "../../../common.h" +# include "../../../ride/Ride.h" +# include "../../Duktape.hpp" +# include "../../ScriptEngine.h" +# include "../object/ScObject.hpp" + +namespace OpenRCT2::Scripting +{ + ScRide::ScRide(ride_id_t rideId) + : _rideId(rideId) + { + } + + int32_t ScRide::id_get() const + { + return _rideId; + } + + std::shared_ptr ScRide::object_get() + { + auto ride = GetRide(); + if (ride != nullptr) + { + auto rideObject = GetContext()->GetObjectManager().GetLoadedObject(ObjectType::Ride, ride->subtype); + if (rideObject != nullptr) + { + return std::make_shared(ObjectType::Ride, ride->subtype); + } + } + return nullptr; + } + + int32_t ScRide::type_get() const + { + auto ride = GetRide(); + return ride != nullptr ? ride->type : 0; + } + + std::string ScRide::classification_get() const + { + auto ride = GetRide(); + if (ride != nullptr) + { + switch (ride->GetClassification()) + { + case RideClassification::Ride: + return "ride"; + case RideClassification::ShopOrStall: + return "stall"; + case RideClassification::KioskOrFacility: + return "facility"; + } + } + return ""; + } + + std::string ScRide::name_get() const + { + auto ride = GetRide(); + return ride != nullptr ? ride->GetName() : std::string(); + } + void ScRide::name_set(std::string value) + { + ThrowIfGameStateNotMutable(); + auto ride = GetRide(); + if (ride != nullptr) + { + ride->custom_name = value; + } + } + + std::string ScRide::status_get() const + { + auto ride = GetRide(); + if (ride != nullptr) + { + switch (ride->status) + { + case RideStatus::Closed: + return "closed"; + case RideStatus::Open: + return "open"; + case RideStatus::Testing: + return "testing"; + case RideStatus::Simulating: + return "simulating"; + case RideStatus::Count: // Meaningless but necessary to satisfy -Wswitch + return "count"; + } + } + return ""; + } + + uint32_t ScRide::lifecycleFlags_get() const + { + auto ride = GetRide(); + return ride != nullptr ? ride->lifecycle_flags : 0; + } + + void ScRide::lifecycleFlags_set(uint32_t value) + { + ThrowIfGameStateNotMutable(); + auto ride = GetRide(); + if (ride != nullptr) + { + ride->lifecycle_flags = value; + } + } + + uint8_t ScRide::mode_get() const + { + auto ride = GetRide(); + return ride != nullptr ? static_cast(ride->mode) : 0; + } + + void ScRide::mode_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto ride = GetRide(); + if (ride != nullptr) + { + ride->mode = static_cast(value); + } + } + + uint8_t ScRide::departFlags_get() const + { + auto ride = GetRide(); + return ride != nullptr ? ride->depart_flags : 0; + } + + void ScRide::departFlags_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto ride = GetRide(); + if (ride != nullptr) + { + ride->depart_flags = value; + } + } + + uint8_t ScRide::minimumWaitingTime_get() const + { + auto ride = GetRide(); + return ride != nullptr ? ride->min_waiting_time : 0; + } + + void ScRide::minimumWaitingTime_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto ride = GetRide(); + if (ride != nullptr) + { + ride->min_waiting_time = value; + } + } + + uint8_t ScRide::maximumWaitingTime_get() const + { + auto ride = GetRide(); + return ride != nullptr ? ride->max_waiting_time : 0; + } + + void ScRide::maximumWaitingTime_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto ride = GetRide(); + if (ride != nullptr) + { + ride->max_waiting_time = value; + } + } + + std::vector ScRide::vehicles_get() const + { + std::vector result; + auto ride = GetRide(); + if (ride != nullptr) + { + result.insert(result.begin(), std::begin(ride->vehicles), std::begin(ride->vehicles) + ride->num_vehicles); + } + return result; + } + + std::vector ScRide::vehicleColours_get() const + { + std::vector result; + auto ride = GetRide(); + if (ride != nullptr) + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + for (const auto& vehicleColour : ride->vehicle_colours) + { + result.push_back(ToDuk(ctx, vehicleColour)); + } + } + return result; + } + + void ScRide::vehicleColours_set(const std::vector& value) + { + auto ride = GetRide(); + if (ride != nullptr) + { + auto count = std::min(value.size(), std::size(ride->vehicle_colours)); + for (size_t i = 0; i < count; i++) + { + ride->vehicle_colours[i] = FromDuk(value[i]); + } + } + } + + std::vector ScRide::colourSchemes_get() const + { + std::vector result; + auto ride = GetRide(); + if (ride != nullptr) + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + for (const auto& trackColour : ride->track_colour) + { + result.push_back(ToDuk(ctx, trackColour)); + } + } + return result; + } + + void ScRide::colourSchemes_set(const std::vector& value) + { + auto ride = GetRide(); + if (ride != nullptr) + { + auto count = std::min(value.size(), std::size(ride->track_colour)); + for (size_t i = 0; i < count; i++) + { + ride->track_colour[i] = FromDuk(value[i]); + } + } + } + + uint8_t ScRide::stationStyle_get() const + { + auto ride = GetRide(); + return ride != nullptr ? ride->entrance_style : 0; + } + + void ScRide::stationStyle_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto ride = GetRide(); + if (ride != nullptr) + { + ride->entrance_style = value; + } + } + + uint8_t ScRide::music_get() const + { + auto ride = GetRide(); + return ride != nullptr ? ride->music : 0; + } + + void ScRide::music_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto ride = GetRide(); + if (ride != nullptr) + { + ride->music = value; + } + } + + std::vector> ScRide::stations_get() const + { + std::vector> result; + auto ride = GetRide(); + if (ride != nullptr) + { + for (size_t i = 0; i < std::size(ride->stations); i++) + { + result.push_back(std::make_shared(ride->id, static_cast(i))); + } + } + return result; + } + + std::vector ScRide::price_get() const + { + std::vector result; + auto ride = GetRide(); + if (ride != nullptr) + { + auto numPrices = ride->GetNumPrices(); + for (size_t i = 0; i < numPrices; i++) + { + result.push_back(ride->price[i]); + }; + } + return result; + } + + void ScRide::price_set(const std::vector& value) + { + ThrowIfGameStateNotMutable(); + auto ride = GetRide(); + if (ride != nullptr) + { + auto numPrices = std::min(value.size(), ride->GetNumPrices()); + for (size_t i = 0; i < numPrices; i++) + { + ride->price[i] = static_cast(value[i]); + } + } + } + + int32_t ScRide::excitement_get() const + { + auto ride = GetRide(); + return ride != nullptr ? ride->excitement : 0; + } + void ScRide::excitement_set(int32_t value) + { + ThrowIfGameStateNotMutable(); + auto ride = GetRide(); + if (ride != nullptr) + { + ride->excitement = value; + } + } + + int32_t ScRide::intensity_get() const + { + auto ride = GetRide(); + return ride != nullptr ? ride->intensity : 0; + } + void ScRide::intensity_set(int32_t value) + { + ThrowIfGameStateNotMutable(); + auto ride = GetRide(); + if (ride != nullptr) + { + ride->intensity = value; + } + } + + int32_t ScRide::nausea_get() const + { + auto ride = GetRide(); + return ride != nullptr ? ride->nausea : 0; + } + void ScRide::nausea_set(int32_t value) + { + ThrowIfGameStateNotMutable(); + auto ride = GetRide(); + if (ride != nullptr) + { + ride->nausea = value; + } + } + + int32_t ScRide::totalCustomers_get() const + { + auto ride = GetRide(); + return ride != nullptr ? ride->total_customers : 0; + } + void ScRide::totalCustomers_set(int32_t value) + { + ThrowIfGameStateNotMutable(); + auto ride = GetRide(); + if (ride != nullptr) + { + ride->total_customers = value; + } + } + + int32_t ScRide::buildDate_get() const + { + auto ride = GetRide(); + return ride != nullptr ? ride->build_date : 0; + } + void ScRide::buildDate_set(int32_t value) + { + ThrowIfGameStateNotMutable(); + auto ride = GetRide(); + if (ride != nullptr) + { + ride->build_date = value; + } + } + + int32_t ScRide::age_get() const + { + auto ride = GetRide(); + return ride != nullptr ? ride->GetAge() : 0; + } + + int16_t ScRide::runningCost_get() const + { + auto ride = GetRide(); + return ride != nullptr ? ride->upkeep_cost : 0; + } + void ScRide::runningCost_set(int16_t value) + { + ThrowIfGameStateNotMutable(); + auto ride = GetRide(); + if (ride != nullptr) + { + ride->upkeep_cost = value; + } + } + + int32_t ScRide::totalProfit_get() const + { + auto ride = GetRide(); + return ride != nullptr ? ride->total_profit : 0; + } + void ScRide::totalProfit_set(int32_t value) + { + ThrowIfGameStateNotMutable(); + auto ride = GetRide(); + if (ride != nullptr) + { + ride->total_profit = value; + } + } + + uint8_t ScRide::inspectionInterval_get() const + { + auto ride = GetRide(); + return ride != nullptr ? ride->inspection_interval : 0; + } + void ScRide::inspectionInterval_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto ride = GetRide(); + if (ride != nullptr) + { + ride->inspection_interval = std::clamp(value, RIDE_INSPECTION_EVERY_10_MINUTES, RIDE_INSPECTION_NEVER); + } + } + + DukValue ScRide::value_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto ride = GetRide(); + if (ride != nullptr && ride->value != RIDE_VALUE_UNDEFINED) + { + return ToDuk(ctx, ride->value); + } + return ToDuk(ctx, nullptr); + } + + void ScRide::value_set(const DukValue& value) + { + ThrowIfGameStateNotMutable(); + auto ride = GetRide(); + if (ride != nullptr) + { + if (value.type() == DukValue::Type::NUMBER) + { + ride->value = value.as_int(); + } + else + { + ride->value = RIDE_VALUE_UNDEFINED; + } + } + } + + Ride* ScRide::GetRide() const + { + return get_ride(_rideId); + } + + uint8_t ScRide::downtime_get() const + { + auto ride = GetRide(); + return ride != nullptr ? ride->downtime : 0; + } + + void ScRide::Register(duk_context* ctx) + { + dukglue_register_property(ctx, &ScRide::id_get, nullptr, "id"); + dukglue_register_property(ctx, &ScRide::object_get, nullptr, "object"); + dukglue_register_property(ctx, &ScRide::type_get, nullptr, "type"); + dukglue_register_property(ctx, &ScRide::classification_get, nullptr, "classification"); + dukglue_register_property(ctx, &ScRide::name_get, &ScRide::name_set, "name"); + dukglue_register_property(ctx, &ScRide::status_get, nullptr, "status"); + dukglue_register_property(ctx, &ScRide::lifecycleFlags_get, &ScRide::lifecycleFlags_set, "lifecycleFlags"); + dukglue_register_property(ctx, &ScRide::mode_get, &ScRide::mode_set, "mode"); + dukglue_register_property(ctx, &ScRide::departFlags_get, &ScRide::departFlags_set, "departFlags"); + dukglue_register_property(ctx, &ScRide::minimumWaitingTime_get, &ScRide::minimumWaitingTime_set, "minimumWaitingTime"); + dukglue_register_property(ctx, &ScRide::maximumWaitingTime_get, &ScRide::maximumWaitingTime_set, "maximumWaitingTime"); + dukglue_register_property(ctx, &ScRide::vehicles_get, nullptr, "vehicles"); + dukglue_register_property(ctx, &ScRide::vehicleColours_get, &ScRide::vehicleColours_set, "vehicleColours"); + dukglue_register_property(ctx, &ScRide::colourSchemes_get, &ScRide::colourSchemes_set, "colourSchemes"); + dukglue_register_property(ctx, &ScRide::stationStyle_get, &ScRide::stationStyle_set, "stationStyle"); + dukglue_register_property(ctx, &ScRide::music_get, &ScRide::music_set, "music"); + dukglue_register_property(ctx, &ScRide::stations_get, nullptr, "stations"); + dukglue_register_property(ctx, &ScRide::price_get, &ScRide::price_set, "price"); + dukglue_register_property(ctx, &ScRide::excitement_get, &ScRide::excitement_set, "excitement"); + dukglue_register_property(ctx, &ScRide::intensity_get, &ScRide::intensity_set, "intensity"); + dukglue_register_property(ctx, &ScRide::nausea_get, &ScRide::nausea_set, "nausea"); + dukglue_register_property(ctx, &ScRide::totalCustomers_get, &ScRide::totalCustomers_set, "totalCustomers"); + dukglue_register_property(ctx, &ScRide::buildDate_get, &ScRide::buildDate_set, "buildDate"); + dukglue_register_property(ctx, &ScRide::age_get, nullptr, "age"); + dukglue_register_property(ctx, &ScRide::runningCost_get, &ScRide::runningCost_set, "runningCost"); + dukglue_register_property(ctx, &ScRide::totalProfit_get, &ScRide::totalProfit_set, "totalProfit"); + dukglue_register_property(ctx, &ScRide::inspectionInterval_get, &ScRide::inspectionInterval_set, "inspectionInterval"); + dukglue_register_property(ctx, &ScRide::value_get, &ScRide::value_set, "value"); + dukglue_register_property(ctx, &ScRide::downtime_get, nullptr, "downtime"); + } + +} // namespace OpenRCT2::Scripting + +#endif diff --git a/src/openrct2/scripting/bindings/ride/ScRide.hpp b/src/openrct2/scripting/bindings/ride/ScRide.hpp new file mode 100644 index 0000000000..4b05584f3c --- /dev/null +++ b/src/openrct2/scripting/bindings/ride/ScRide.hpp @@ -0,0 +1,165 @@ +/***************************************************************************** + * Copyright (c) 2020 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#pragma once + +#ifdef ENABLE_SCRIPTING + +# include "../../../Context.h" +# include "../../../common.h" +# include "../../../ride/Ride.h" +# include "../../Duktape.hpp" +# include "../../ScriptEngine.h" +# include "../object/ScObject.hpp" +# include "ScRideStation.hpp" + +namespace OpenRCT2::Scripting +{ + template<> inline DukValue ToDuk(duk_context* ctx, const TrackColour& value) + { + DukObject obj(ctx); + obj.Set("main", value.main); + obj.Set("additional", value.additional); + obj.Set("supports", value.supports); + return obj.Take(); + } + + template<> inline TrackColour FromDuk(const DukValue& s) + { + TrackColour result{}; + result.main = AsOrDefault(s["main"], 0); + result.additional = AsOrDefault(s["additional"], 0); + result.supports = AsOrDefault(s["supports"], 0); + return result; + } + + template<> inline DukValue ToDuk(duk_context* ctx, const VehicleColour& value) + { + DukObject obj(ctx); + obj.Set("body", value.Body); + obj.Set("trim", value.Trim); + obj.Set("ternary", value.Ternary); + return obj.Take(); + } + + template<> inline VehicleColour FromDuk(const DukValue& s) + { + VehicleColour result{}; + result.Body = AsOrDefault(s["body"], 0); + result.Trim = AsOrDefault(s["trim"], 0); + result.Ternary = AsOrDefault(s["ternary"], 0); + return result; + } + + class ScRide + { + private: + ride_id_t _rideId = RIDE_ID_NULL; + + public: + ScRide(ride_id_t rideId); + + private: + int32_t id_get() const; + + std::shared_ptr object_get(); + + int32_t type_get() const; + + std::string classification_get() const; + + std::string name_get() const; + void name_set(std::string value); + + std::string status_get() const; + + uint32_t lifecycleFlags_get() const; + + void lifecycleFlags_set(uint32_t value); + + uint8_t mode_get() const; + + void mode_set(uint8_t value); + + uint8_t departFlags_get() const; + + void departFlags_set(uint8_t value); + + uint8_t minimumWaitingTime_get() const; + + void minimumWaitingTime_set(uint8_t value); + + uint8_t maximumWaitingTime_get() const; + + void maximumWaitingTime_set(uint8_t value); + + std::vector vehicles_get() const; + + std::vector vehicleColours_get() const; + + void vehicleColours_set(const std::vector& value); + + std::vector colourSchemes_get() const; + + void colourSchemes_set(const std::vector& value); + + uint8_t stationStyle_get() const; + + void stationStyle_set(uint8_t value); + + uint8_t music_get() const; + + void music_set(uint8_t value); + + std::vector> stations_get() const; + + std::vector price_get() const; + + void price_set(const std::vector& value); + + int32_t excitement_get() const; + void excitement_set(int32_t value); + + int32_t intensity_get() const; + void intensity_set(int32_t value); + + int32_t nausea_get() const; + void nausea_set(int32_t value); + + int32_t totalCustomers_get() const; + void totalCustomers_set(int32_t value); + + int32_t buildDate_get() const; + void buildDate_set(int32_t value); + + int32_t age_get() const; + + int16_t runningCost_get() const; + void runningCost_set(int16_t value); + + int32_t totalProfit_get() const; + void totalProfit_set(int32_t value); + + uint8_t inspectionInterval_get() const; + void inspectionInterval_set(uint8_t value); + + DukValue value_get() const; + + void value_set(const DukValue& value); + + uint8_t downtime_get() const; + + Ride* GetRide() const; + + public: + static void Register(duk_context* ctx); + }; +} // namespace OpenRCT2::Scripting + +#endif diff --git a/src/openrct2/scripting/bindings/ride/ScRideStation.cpp b/src/openrct2/scripting/bindings/ride/ScRideStation.cpp new file mode 100644 index 0000000000..1168d96060 --- /dev/null +++ b/src/openrct2/scripting/bindings/ride/ScRideStation.cpp @@ -0,0 +1,134 @@ +/***************************************************************************** + * Copyright (c) 2021 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#ifdef ENABLE_SCRIPTING + +# include "ScRideStation.hpp" + +# include "../../../Context.h" +# include "../../../common.h" +# include "../../../ride/Ride.h" +# include "../../Duktape.hpp" +# include "../../ScriptEngine.h" +# include "../object/ScObject.hpp" + +namespace OpenRCT2::Scripting +{ + ScRideStation::ScRideStation(ride_id_t rideId, StationIndex stationIndex) + : _rideId(rideId) + , _stationIndex(stationIndex) + { + } + + void ScRideStation::Register(duk_context* ctx) + { + dukglue_register_property(ctx, &ScRideStation::start_get, &ScRideStation::start_set, "start"); + dukglue_register_property(ctx, &ScRideStation::length_get, &ScRideStation::length_set, "length"); + dukglue_register_property(ctx, &ScRideStation::entrance_get, &ScRideStation::entrance_set, "entrance"); + dukglue_register_property(ctx, &ScRideStation::exit_get, &ScRideStation::exit_set, "exit"); + } + + DukValue ScRideStation::start_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto station = GetRideStation(); + if (station != nullptr) + { + auto start = CoordsXYZ(station->Start, station->GetBaseZ()); + return ToDuk(ctx, start); + } + return ToDuk(ctx, nullptr); + } + + void ScRideStation::start_set(const DukValue& value) + { + auto station = GetRideStation(); + if (station != nullptr) + { + auto start = FromDuk(value); + station->Start = { start.x, start.y }; + station->SetBaseZ(start.z); + } + } + + int32_t ScRideStation::length_get() const + { + auto station = GetRideStation(); + if (station != nullptr) + { + return station->Length; + } + return 0; + } + + void ScRideStation::length_set(int32_t value) + { + auto station = GetRideStation(); + if (station != nullptr) + { + station->Length = value; + } + } + + DukValue ScRideStation::entrance_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto station = GetRideStation(); + if (station != nullptr) + { + return ToDuk(ctx, station->Entrance.ToCoordsXYZD()); + } + return ToDuk(ctx, nullptr); + } + + void ScRideStation::entrance_set(const DukValue& value) + { + auto station = GetRideStation(); + if (station != nullptr) + { + station->Entrance = FromDuk(value); + } + } + + DukValue ScRideStation::exit_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto station = GetRideStation(); + if (station != nullptr) + { + return ToDuk(ctx, station->Exit.ToCoordsXYZD()); + } + return ToDuk(ctx, nullptr); + } + + void ScRideStation::exit_set(const DukValue& value) + { + auto station = GetRideStation(); + if (station != nullptr) + { + station->Exit = FromDuk(value); + } + } + + RideStation* ScRideStation::GetRideStation() const + { + auto ride = get_ride(_rideId); + if (ride != nullptr) + { + if (_stationIndex < std::size(ride->stations)) + { + return &ride->stations[_stationIndex]; + } + } + return nullptr; + } + +} // namespace OpenRCT2::Scripting + +#endif diff --git a/src/openrct2/scripting/bindings/ride/ScRideStation.hpp b/src/openrct2/scripting/bindings/ride/ScRideStation.hpp new file mode 100644 index 0000000000..7b8c1804b9 --- /dev/null +++ b/src/openrct2/scripting/bindings/ride/ScRideStation.hpp @@ -0,0 +1,54 @@ +/***************************************************************************** + * Copyright (c) 2021 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#pragma once + +#ifdef ENABLE_SCRIPTING + +# include "../../../Context.h" +# include "../../../common.h" +# include "../../../ride/Ride.h" +# include "../../Duktape.hpp" + +namespace OpenRCT2::Scripting +{ + class ScRideStation + { + private: + ride_id_t _rideId = RIDE_ID_NULL; + StationIndex _stationIndex{}; + + public: + ScRideStation(ride_id_t rideId, StationIndex stationIndex); + + static void Register(duk_context* ctx); + + private: + DukValue start_get() const; + + void start_set(const DukValue& value); + + int32_t length_get() const; + + void length_set(int32_t value); + + DukValue entrance_get() const; + + void entrance_set(const DukValue& value); + + DukValue exit_get() const; + + void exit_set(const DukValue& value); + + RideStation* GetRideStation() const; + }; + +} // namespace OpenRCT2::Scripting + +#endif diff --git a/src/openrct2/scripting/ScClimate.hpp b/src/openrct2/scripting/bindings/world/ScClimate.hpp similarity index 94% rename from src/openrct2/scripting/ScClimate.hpp rename to src/openrct2/scripting/bindings/world/ScClimate.hpp index 779d22ada2..272c24ae45 100644 --- a/src/openrct2/scripting/ScClimate.hpp +++ b/src/openrct2/scripting/bindings/world/ScClimate.hpp @@ -11,12 +11,12 @@ #ifdef ENABLE_SCRIPTING -# include "../Context.h" -# include "../common.h" -# include "../core/String.hpp" -# include "../world/Climate.h" -# include "Duktape.hpp" -# include "ScriptEngine.h" +# include "../../../Context.h" +# include "../../../common.h" +# include "../../../core/String.hpp" +# include "../../../world/Climate.h" +# include "../../Duktape.hpp" +# include "../../ScriptEngine.h" namespace OpenRCT2::Scripting { diff --git a/src/openrct2/scripting/ScDate.hpp b/src/openrct2/scripting/bindings/world/ScDate.hpp similarity index 90% rename from src/openrct2/scripting/ScDate.hpp rename to src/openrct2/scripting/bindings/world/ScDate.hpp index 227ec5ad75..a2a08e7012 100644 --- a/src/openrct2/scripting/ScDate.hpp +++ b/src/openrct2/scripting/bindings/world/ScDate.hpp @@ -11,14 +11,14 @@ #ifdef ENABLE_SCRIPTING -# include "../Context.h" -# include "../Date.h" -# include "../Game.h" -# include "../GameState.h" -# include "../common.h" -# include "../localisation/Date.h" -# include "Duktape.hpp" -# include "ScriptEngine.h" +# include "../../../Context.h" +# include "../../../Date.h" +# include "../../../Game.h" +# include "../../../GameState.h" +# include "../../../common.h" +# include "../../../localisation/Date.h" +# include "../../Duktape.hpp" +# include "../../ScriptEngine.h" namespace OpenRCT2::Scripting { diff --git a/src/openrct2/scripting/bindings/world/ScMap.cpp b/src/openrct2/scripting/bindings/world/ScMap.cpp new file mode 100644 index 0000000000..6e68adc6ef --- /dev/null +++ b/src/openrct2/scripting/bindings/world/ScMap.cpp @@ -0,0 +1,272 @@ +/***************************************************************************** + * Copyright (c) 2014-2021 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#ifdef ENABLE_SCRIPTING + +# include "ScMap.hpp" + +# include "../../../common.h" +# include "../../../ride/Ride.h" +# include "../../../ride/TrainManager.h" +# include "../../../world/Balloon.h" +# include "../../../world/Duck.h" +# include "../../../world/EntityList.h" +# include "../../../world/Fountain.h" +# include "../../../world/Litter.h" +# include "../../../world/Map.h" +# include "../../../world/MoneyEffect.h" +# include "../../../world/Particle.h" +# include "../../Duktape.hpp" +# include "../entity/ScEntity.hpp" +# include "../entity/ScGuest.hpp" +# include "../entity/ScLitter.hpp" +# include "../entity/ScStaff.hpp" +# include "../entity/ScVehicle.hpp" +# include "../ride/ScRide.hpp" +# include "../world/ScTile.hpp" + +namespace OpenRCT2::Scripting +{ + ScMap::ScMap(duk_context* ctx) + : _context(ctx) + { + } + + DukValue ScMap::size_get() const + { + return ToDuk(_context, CoordsXY{ gMapSize, gMapSize }); + } + + int32_t ScMap::numRides_get() const + { + return static_cast(GetRideManager().size()); + } + + int32_t ScMap::numEntities_get() const + { + return MAX_ENTITIES; + } + + std::vector> ScMap::rides_get() const + { + std::vector> result; + auto rideManager = GetRideManager(); + for (const auto& ride : rideManager) + { + result.push_back(std::make_shared(ride.id)); + } + return result; + } + + std::shared_ptr ScMap::getRide(int32_t id) const + { + auto rideManager = GetRideManager(); + auto ride = rideManager[static_cast(id)]; + if (ride != nullptr) + { + return std::make_shared(ride->id); + } + return {}; + } + + std::shared_ptr ScMap::getTile(int32_t x, int32_t y) const + { + auto coords = TileCoordsXY(x, y).ToCoordsXY(); + return std::make_shared(coords); + } + + DukValue ScMap::getEntity(int32_t id) const + { + if (id >= 0 && id < MAX_ENTITIES) + { + auto spriteId = static_cast(id); + auto sprite = GetEntity(spriteId); + if (sprite != nullptr && sprite->Type != EntityType::Null) + { + return GetEntityAsDukValue(sprite); + } + } + duk_push_null(_context); + return DukValue::take_from_stack(_context); + } + + std::vector ScMap::getAllEntities(const std::string& type) const + { + std::vector result; + if (type == "balloon") + { + for (auto sprite : EntityList()) + { + result.push_back(GetObjectAsDukValue(_context, std::make_shared(sprite->sprite_index))); + } + } + else if (type == "car") + { + for (auto trainHead : TrainManager::View()) + { + for (auto carId = trainHead->sprite_index; carId != SPRITE_INDEX_NULL;) + { + auto car = GetEntity(carId); + result.push_back(GetObjectAsDukValue(_context, std::make_shared(carId))); + carId = car->next_vehicle_on_train; + } + } + } + else if (type == "litter") + { + for (auto sprite : EntityList()) + { + result.push_back(GetObjectAsDukValue(_context, std::make_shared(sprite->sprite_index))); + } + } + else if (type == "duck") + { + for (auto sprite : EntityList()) + { + result.push_back(GetObjectAsDukValue(_context, std::make_shared(sprite->sprite_index))); + } + } + else if (type == "peep") + { + for (auto sprite : EntityList()) + { + result.push_back(GetObjectAsDukValue(_context, std::make_shared(sprite->sprite_index))); + } + for (auto sprite : EntityList()) + { + result.push_back(GetObjectAsDukValue(_context, std::make_shared(sprite->sprite_index))); + } + } + else if (type == "guest") + { + for (auto sprite : EntityList()) + { + result.push_back(GetObjectAsDukValue(_context, std::make_shared(sprite->sprite_index))); + } + } + else if (type == "staff") + { + for (auto sprite : EntityList()) + { + result.push_back(GetObjectAsDukValue(_context, std::make_shared(sprite->sprite_index))); + } + } + else + { + duk_error(_context, DUK_ERR_ERROR, "Invalid entity type."); + } + + return result; + } + + template + DukValue createEntityType(duk_context* ctx, const DukValue& initializer) + { + TEntityType* entity = CreateEntity(); + + auto entityPos = CoordsXYZ{ AsOrDefault(initializer["x"], 0), AsOrDefault(initializer["y"], 0), + AsOrDefault(initializer["z"], 0) }; + entity->MoveTo(entityPos); + + return GetObjectAsDukValue(ctx, std::make_shared(entity->sprite_index)); + } + + DukValue ScMap::createEntity(const std::string& type, const DukValue& initializer) + { + if (type == "car") + { + return createEntityType(_context, initializer); + } + else if (type == "staff") + { + return createEntityType(_context, initializer); + } + else if (type == "guest") + { + return createEntityType(_context, initializer); + } + else if (type == "steam_particle") + { + return createEntityType(_context, initializer); + } + else if (type == "money_effect") + { + return createEntityType(_context, initializer); + } + else if (type == "crashed_vehicle_particle") + { + return createEntityType(_context, initializer); + } + else if (type == "explosion_cloud") + { + return createEntityType(_context, initializer); + } + else if (type == "crash_splash") + { + return createEntityType(_context, initializer); + } + else if (type == "explosion_flare") + { + return createEntityType(_context, initializer); + } + else if (type == "balloon") + { + return createEntityType(_context, initializer); + } + else if (type == "duck") + { + return createEntityType(_context, initializer); + } + else if (type == "jumping_fountain") + { + return createEntityType(_context, initializer); + } + else if (type == "litter") + { + return createEntityType(_context, initializer); + } + + duk_error(_context, DUK_ERR_ERROR, "Invalid entity type."); + return DukValue{}; + } + + void ScMap::Register(duk_context* ctx) + { + dukglue_register_property(ctx, &ScMap::size_get, nullptr, "size"); + dukglue_register_property(ctx, &ScMap::numRides_get, nullptr, "numRides"); + dukglue_register_property(ctx, &ScMap::numEntities_get, nullptr, "numEntities"); + dukglue_register_property(ctx, &ScMap::rides_get, nullptr, "rides"); + dukglue_register_method(ctx, &ScMap::getRide, "getRide"); + dukglue_register_method(ctx, &ScMap::getTile, "getTile"); + dukglue_register_method(ctx, &ScMap::getEntity, "getEntity"); + dukglue_register_method(ctx, &ScMap::getAllEntities, "getAllEntities"); + dukglue_register_method(ctx, &ScMap::createEntity, "createEntity"); + } + + DukValue ScMap::GetEntityAsDukValue(const SpriteBase* sprite) const + { + auto spriteId = sprite->sprite_index; + switch (sprite->Type) + { + case EntityType::Vehicle: + return GetObjectAsDukValue(_context, std::make_shared(spriteId)); + case EntityType::Staff: + return GetObjectAsDukValue(_context, std::make_shared(spriteId)); + case EntityType::Guest: + return GetObjectAsDukValue(_context, std::make_shared(spriteId)); + case EntityType::Litter: + return GetObjectAsDukValue(_context, std::make_shared(spriteId)); + default: + return GetObjectAsDukValue(_context, std::make_shared(spriteId)); + } + } + +} // namespace OpenRCT2::Scripting + +#endif diff --git a/src/openrct2/scripting/bindings/world/ScMap.hpp b/src/openrct2/scripting/bindings/world/ScMap.hpp new file mode 100644 index 0000000000..a2994fd04b --- /dev/null +++ b/src/openrct2/scripting/bindings/world/ScMap.hpp @@ -0,0 +1,55 @@ +/***************************************************************************** + * Copyright (c) 2014-2021 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#pragma once + +#ifdef ENABLE_SCRIPTING + +# include "../../../common.h" +# include "../../Duktape.hpp" +# include "../ride/ScRide.hpp" +# include "../world/ScTile.hpp" + +namespace OpenRCT2::Scripting +{ + class ScMap + { + private: + duk_context* _context; + + public: + ScMap(duk_context* ctx); + + DukValue size_get() const; + + int32_t numRides_get() const; + + int32_t numEntities_get() const; + + std::vector> rides_get() const; + + std::shared_ptr getRide(int32_t id) const; + + std::shared_ptr getTile(int32_t x, int32_t y) const; + + DukValue getEntity(int32_t id) const; + + std::vector getAllEntities(const std::string& type) const; + + DukValue createEntity(const std::string& type, const DukValue& initializer); + + static void Register(duk_context* ctx); + + private: + DukValue GetEntityAsDukValue(const SpriteBase* sprite) const; + }; + +} // namespace OpenRCT2::Scripting + +#endif diff --git a/src/openrct2/scripting/bindings/world/ScPark.cpp b/src/openrct2/scripting/bindings/world/ScPark.cpp new file mode 100644 index 0000000000..0ff6063fa3 --- /dev/null +++ b/src/openrct2/scripting/bindings/world/ScPark.cpp @@ -0,0 +1,418 @@ +/***************************************************************************** + * Copyright (c) 2014-2021 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#ifdef ENABLE_SCRIPTING + +# include "ScPark.hpp" + +# include "../../../Context.h" +# include "../../../GameState.h" +# include "../../../common.h" +# include "../../../core/String.hpp" +# include "../../../management/Finance.h" +# include "../../../management/NewsItem.h" +# include "../../../peep/Peep.h" +# include "../../../windows/Intent.h" +# include "../../../world/Park.h" +# include "../../Duktape.hpp" +# include "../../ScriptEngine.h" +# include "ScParkMessage.hpp" + +# include + +namespace OpenRCT2::Scripting +{ + static const DukEnumMap ParkFlagMap({ + { "open", PARK_FLAGS_PARK_OPEN }, + { "scenarioCompleteNameInput", PARK_FLAGS_SCENARIO_COMPLETE_NAME_INPUT }, + { "forbidLandscapeChanges", PARK_FLAGS_FORBID_LANDSCAPE_CHANGES }, + { "forbidTreeRemoval", PARK_FLAGS_FORBID_TREE_REMOVAL }, + { "forbidHighConstruction", PARK_FLAGS_FORBID_HIGH_CONSTRUCTION }, + { "preferLessIntenseRides", PARK_FLAGS_PREF_LESS_INTENSE_RIDES }, + { "forbidMarketingCampaigns", PARK_FLAGS_FORBID_MARKETING_CAMPAIGN }, + { "preferMoreIntenseRides", PARK_FLAGS_PREF_MORE_INTENSE_RIDES }, + { "noMoney", PARK_FLAGS_NO_MONEY }, + { "difficultGuestGeneration", PARK_FLAGS_DIFFICULT_GUEST_GENERATION }, + { "freeParkEntry", PARK_FLAGS_PARK_FREE_ENTRY }, + { "difficultParkRating", PARK_FLAGS_DIFFICULT_PARK_RATING }, + { "noMoney", PARK_FLAGS_NO_MONEY_SCENARIO }, + { "unlockAllPrices", PARK_FLAGS_UNLOCK_ALL_PRICES }, + }); + + money64 ScPark::cash_get() const + { + return gCash; + } + void ScPark::cash_set(money64 value) + { + ThrowIfGameStateNotMutable(); + + if (gCash != value) + { + gCash = value; + auto intent = Intent(INTENT_ACTION_UPDATE_CASH); + context_broadcast_intent(&intent); + } + } + + int32_t ScPark::rating_get() const + { + return gParkRating; + } + void ScPark::rating_set(int32_t value) + { + ThrowIfGameStateNotMutable(); + + auto valueClamped = std::min(std::max(0, value), 999); + if (gParkRating != valueClamped) + { + gParkRating = std::min(std::max(0, value), 999); + auto intent = Intent(INTENT_ACTION_UPDATE_PARK_RATING); + context_broadcast_intent(&intent); + } + } + + money64 ScPark::bankLoan_get() const + { + return gBankLoan; + } + void ScPark::bankLoan_set(money64 value) + { + ThrowIfGameStateNotMutable(); + + if (gBankLoan != value) + { + gBankLoan = value; + auto intent = Intent(INTENT_ACTION_UPDATE_CASH); + context_broadcast_intent(&intent); + } + } + + money64 ScPark::maxBankLoan_get() const + { + return gMaxBankLoan; + } + void ScPark::maxBankLoan_set(money64 value) + { + ThrowIfGameStateNotMutable(); + + if (gMaxBankLoan != value) + { + gMaxBankLoan = value; + auto intent = Intent(INTENT_ACTION_UPDATE_CASH); + context_broadcast_intent(&intent); + } + } + + money16 ScPark::entranceFee_get() const + { + return gParkEntranceFee; + } + void ScPark::entranceFee_set(money16 value) + { + ThrowIfGameStateNotMutable(); + + if (gParkEntranceFee != value) + { + gParkEntranceFee = value; + window_invalidate_by_class(WC_PARK_INFORMATION); + } + } + + uint32_t ScPark::guests_get() const + { + return gNumGuestsInPark; + } + + uint32_t ScPark::suggestedGuestMaximum_get() const + { + return _suggestedGuestMaximum; + } + + int32_t ScPark::guestGenerationProbability_get() const + { + return _guestGenerationProbability; + } + + money16 ScPark::guestInitialCash_get() const + { + return gGuestInitialCash; + } + + uint8_t ScPark::guestInitialHappiness_get() const + { + return gGuestInitialHappiness; + } + + uint8_t ScPark::guestInitialHunger_get() const + { + return gGuestInitialHunger; + } + + uint8_t ScPark::guestInitialThirst_get() const + { + return gGuestInitialThirst; + } + + money64 ScPark::value_get() const + { + return gParkValue; + } + void ScPark::value_set(money64 value) + { + ThrowIfGameStateNotMutable(); + + if (gParkValue != value) + { + gParkValue = value; + auto intent = Intent(INTENT_ACTION_UPDATE_CASH); + context_broadcast_intent(&intent); + } + } + + money64 ScPark::companyValue_get() const + { + return gCompanyValue; + } + void ScPark::companyValue_set(money64 value) + { + ThrowIfGameStateNotMutable(); + + if (gCompanyValue != value) + { + gCompanyValue = value; + auto intent = Intent(INTENT_ACTION_UPDATE_CASH); + context_broadcast_intent(&intent); + } + } + + money16 ScPark::totalRideValueForMoney_get() const + { + return gTotalRideValueForMoney; + } + + uint32_t ScPark::totalAdmissions_get() const + { + return gTotalAdmissions; + } + void ScPark::totalAdmissions_set(uint32_t value) + { + ThrowIfGameStateNotMutable(); + + if (gTotalAdmissions != value) + { + gTotalAdmissions = value; + window_invalidate_by_class(WC_PARK_INFORMATION); + } + } + + money64 ScPark::totalIncomeFromAdmissions_get() const + { + return gTotalIncomeFromAdmissions; + } + void ScPark::totalIncomeFromAdmissions_set(money64 value) + { + ThrowIfGameStateNotMutable(); + + if (gTotalIncomeFromAdmissions != value) + { + gTotalIncomeFromAdmissions = value; + window_invalidate_by_class(WC_PARK_INFORMATION); + } + } + + money32 ScPark::landPrice_get() const + { + return gLandPrice; + } + void ScPark::landPrice_set(money32 value) + { + ThrowIfGameStateNotMutable(); + gLandPrice = value; + } + + money32 ScPark::constructionRightsPrice_get() const + { + return gConstructionRightsPrice; + } + void ScPark::constructionRightsPrice_set(money32 value) + { + ThrowIfGameStateNotMutable(); + gConstructionRightsPrice = value; + } + + int16_t ScPark::casualtyPenalty_get() const + { + return gParkRatingCasualtyPenalty; + } + void ScPark::casualtyPenalty_set(int16_t value) + { + ThrowIfGameStateNotMutable(); + gParkRatingCasualtyPenalty = value; + } + + uint16_t ScPark::parkSize_get() const + { + return gParkSize; + } + + std::string ScPark::name_get() const + { + return GetContext()->GetGameState()->GetPark().Name; + } + void ScPark::name_set(std::string value) + { + ThrowIfGameStateNotMutable(); + + auto& park = GetContext()->GetGameState()->GetPark(); + if (park.Name != value) + { + park.Name = value; + gfx_invalidate_screen(); + } + } + + bool ScPark::getFlag(const std::string& key) const + { + auto mask = ParkFlagMap[key]; + return (gParkFlags & mask) != 0; + } + + void ScPark::setFlag(const std::string& key, bool value) + { + ThrowIfGameStateNotMutable(); + auto mask = ParkFlagMap[key]; + if (value) + gParkFlags |= mask; + else + gParkFlags &= ~mask; + gfx_invalidate_screen(); + } + + std::vector> ScPark::messages_get() const + { + std::vector> result; + for (size_t i = 0, newsSize = gNewsItems.GetRecent().size(); i < newsSize; i++) + { + result.push_back(std::make_shared(i)); + } + for (size_t i = 0, newsSize = gNewsItems.GetArchived().size(); i < newsSize; i++) + { + result.push_back(std::make_shared(i + News::ItemHistoryStart)); + } + return result; + } + + void ScPark::messages_set(const std::vector& value) + { + int32_t index = 0; + int32_t archiveIndex = News::ItemHistoryStart; + for (const auto& item : value) + { + auto isArchived = item["isArchived"].as_bool(); + auto newsItem = FromDuk(item); + if (isArchived) + { + if (archiveIndex < News::MaxItems) + { + gNewsItems[archiveIndex] = newsItem; + archiveIndex++; + } + } + else + { + if (index < News::ItemHistoryStart) + { + gNewsItems[index] = newsItem; + index++; + } + } + } + + // End the lists by setting next item to null + if (index < News::ItemHistoryStart) + { + gNewsItems[index].Type = News::ItemType::Null; + } + if (archiveIndex < News::MaxItems) + { + gNewsItems[archiveIndex].Type = News::ItemType::Null; + } + } + + void ScPark::postMessage(DukValue message) + { + ThrowIfGameStateNotMutable(); + try + { + uint32_t assoc = std::numeric_limits::max(); + auto type = News::ItemType::Blank; + std::string text; + if (message.type() == DukValue::Type::STRING) + { + text = message.as_string(); + } + else + { + type = GetParkMessageType(message["type"].as_string()); + text = message["text"].as_string(); + if (type == News::ItemType::Blank) + { + assoc = static_cast(((COORDS_NULL & 0xFFFF) << 16) | (COORDS_NULL & 0xFFFF)); + } + + auto dukSubject = message["subject"]; + if (dukSubject.type() == DukValue::Type::NUMBER) + { + assoc = static_cast(dukSubject.as_int()); + } + } + News::AddItemToQueue(type, text.c_str(), assoc); + } + catch (const DukException&) + { + duk_error(message.context(), DUK_ERR_ERROR, "Invalid message argument."); + } + } + + void ScPark::Register(duk_context* ctx) + { + dukglue_register_property(ctx, &ScPark::cash_get, &ScPark::cash_set, "cash"); + dukglue_register_property(ctx, &ScPark::rating_get, &ScPark::rating_set, "rating"); + dukglue_register_property(ctx, &ScPark::bankLoan_get, &ScPark::bankLoan_set, "bankLoan"); + dukglue_register_property(ctx, &ScPark::maxBankLoan_get, &ScPark::maxBankLoan_set, "maxBankLoan"); + dukglue_register_property(ctx, &ScPark::entranceFee_get, &ScPark::entranceFee_set, "entranceFee"); + dukglue_register_property(ctx, &ScPark::guests_get, nullptr, "guests"); + dukglue_register_property(ctx, &ScPark::suggestedGuestMaximum_get, nullptr, "suggestedGuestMaximum"); + dukglue_register_property(ctx, &ScPark::guestGenerationProbability_get, nullptr, "guestGenerationProbability"); + dukglue_register_property(ctx, &ScPark::guestInitialCash_get, nullptr, "guestInitialCash"); + dukglue_register_property(ctx, &ScPark::guestInitialHappiness_get, nullptr, "guestInitialHappiness"); + dukglue_register_property(ctx, &ScPark::guestInitialHunger_get, nullptr, "guestInitialHunger"); + dukglue_register_property(ctx, &ScPark::guestInitialThirst_get, nullptr, "guestInitialThirst"); + dukglue_register_property(ctx, &ScPark::value_get, &ScPark::value_set, "value"); + dukglue_register_property(ctx, &ScPark::companyValue_get, &ScPark::companyValue_set, "companyValue"); + dukglue_register_property(ctx, &ScPark::totalRideValueForMoney_get, nullptr, "totalRideValueForMoney"); + dukglue_register_property(ctx, &ScPark::totalAdmissions_get, &ScPark::totalAdmissions_set, "totalAdmissions"); + dukglue_register_property( + ctx, &ScPark::totalIncomeFromAdmissions_get, &ScPark::totalIncomeFromAdmissions_set, "totalIncomeFromAdmissions"); + dukglue_register_property(ctx, &ScPark::landPrice_get, &ScPark::landPrice_set, "landPrice"); + dukglue_register_property( + ctx, &ScPark::constructionRightsPrice_get, &ScPark::constructionRightsPrice_set, "constructionRightsPrice"); + dukglue_register_property(ctx, &ScPark::parkSize_get, nullptr, "parkSize"); + dukglue_register_property(ctx, &ScPark::name_get, &ScPark::name_set, "name"); + dukglue_register_property(ctx, &ScPark::messages_get, &ScPark::messages_set, "messages"); + dukglue_register_property(ctx, &ScPark::casualtyPenalty_get, &ScPark::casualtyPenalty_set, "casualtyPenalty"); + dukglue_register_method(ctx, &ScPark::getFlag, "getFlag"); + dukglue_register_method(ctx, &ScPark::setFlag, "setFlag"); + dukglue_register_method(ctx, &ScPark::postMessage, "postMessage"); + } + +} // namespace OpenRCT2::Scripting + +#endif diff --git a/src/openrct2/scripting/bindings/world/ScPark.hpp b/src/openrct2/scripting/bindings/world/ScPark.hpp new file mode 100644 index 0000000000..10fb765abb --- /dev/null +++ b/src/openrct2/scripting/bindings/world/ScPark.hpp @@ -0,0 +1,98 @@ +/***************************************************************************** + * Copyright (c) 2014-2021 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#pragma once + +#ifdef ENABLE_SCRIPTING + +# include "../../../Context.h" +# include "../../../common.h" +# include "../../Duktape.hpp" +# include "ScParkMessage.hpp" + +# include +# include + +namespace OpenRCT2::Scripting +{ + class ScPark + { + public: + money64 cash_get() const; + void cash_set(money64 value); + + int32_t rating_get() const; + void rating_set(int32_t value); + + money64 bankLoan_get() const; + void bankLoan_set(money64 value); + + money64 maxBankLoan_get() const; + void maxBankLoan_set(money64 value); + + money16 entranceFee_get() const; + void entranceFee_set(money16 value); + + uint32_t guests_get() const; + + uint32_t suggestedGuestMaximum_get() const; + + int32_t guestGenerationProbability_get() const; + + money16 guestInitialCash_get() const; + + uint8_t guestInitialHappiness_get() const; + + uint8_t guestInitialHunger_get() const; + + uint8_t guestInitialThirst_get() const; + + money64 value_get() const; + void value_set(money64 value); + + money64 companyValue_get() const; + void companyValue_set(money64 value); + + money16 totalRideValueForMoney_get() const; + + uint32_t totalAdmissions_get() const; + void totalAdmissions_set(uint32_t value); + + money64 totalIncomeFromAdmissions_get() const; + void totalIncomeFromAdmissions_set(money64 value); + + money32 landPrice_get() const; + void landPrice_set(money32 value); + + money32 constructionRightsPrice_get() const; + void constructionRightsPrice_set(money32 value); + + int16_t casualtyPenalty_get() const; + void casualtyPenalty_set(int16_t value); + + uint16_t parkSize_get() const; + + std::string name_get() const; + void name_set(std::string value); + + bool getFlag(const std::string& key) const; + + void setFlag(const std::string& key, bool value); + + std::vector> messages_get() const; + + void messages_set(const std::vector& value); + + void postMessage(DukValue message); + + static void Register(duk_context* ctx); + }; +} // namespace OpenRCT2::Scripting + +#endif diff --git a/src/openrct2/scripting/bindings/world/ScParkMessage.cpp b/src/openrct2/scripting/bindings/world/ScParkMessage.cpp new file mode 100644 index 0000000000..0df7790750 --- /dev/null +++ b/src/openrct2/scripting/bindings/world/ScParkMessage.cpp @@ -0,0 +1,184 @@ +/***************************************************************************** + * Copyright (c) 2014-2021 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#ifdef ENABLE_SCRIPTING + +# include "ScParkMessage.hpp" + +# include "../../../Context.h" +# include "../../../GameState.h" +# include "../../../common.h" +# include "../../../core/String.hpp" +# include "../../../management/Finance.h" +# include "../../../management/NewsItem.h" +# include "../../../peep/Peep.h" +# include "../../../windows/Intent.h" +# include "../../../world/Park.h" +# include "../../Duktape.hpp" +# include "../../ScriptEngine.h" + +# include + +namespace OpenRCT2::Scripting +{ + ScParkMessage::ScParkMessage(size_t index) + : _index(index) + { + } + + void ScParkMessage::Register(duk_context* ctx) + { + dukglue_register_property(ctx, &ScParkMessage::isArchived_get, nullptr, "isArchived"); + dukglue_register_property(ctx, &ScParkMessage::month_get, &ScParkMessage::month_set, "month"); + dukglue_register_property(ctx, &ScParkMessage::day_get, &ScParkMessage::day_set, "day"); + dukglue_register_property(ctx, &ScParkMessage::tickCount_get, &ScParkMessage::tickCount_set, "tickCount"); + dukglue_register_property(ctx, &ScParkMessage::type_get, &ScParkMessage::type_set, "type"); + dukglue_register_property(ctx, &ScParkMessage::subject_get, &ScParkMessage::subject_set, "subject"); + dukglue_register_property(ctx, &ScParkMessage::text_get, &ScParkMessage::text_set, "text"); + dukglue_register_method(ctx, &ScParkMessage::remove, "remove"); + } + + News::Item* ScParkMessage::GetMessage() const + { + return &gNewsItems[_index]; + } + + bool ScParkMessage::isArchived_get() const + { + return _index >= News::ItemHistoryStart; + } + + uint16_t ScParkMessage::month_get() const + { + auto msg = GetMessage(); + if (msg != nullptr) + { + return msg->MonthYear; + } + return 0; + } + + void ScParkMessage::month_set(uint16_t value) + { + ThrowIfGameStateNotMutable(); + auto msg = GetMessage(); + if (msg != nullptr) + { + msg->MonthYear = value; + } + } + + uint8_t ScParkMessage::day_get() const + { + auto msg = GetMessage(); + if (msg != nullptr) + { + return msg->Day; + } + return 0; + } + + void ScParkMessage::day_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto msg = GetMessage(); + if (msg != nullptr) + { + msg->Day = value; + } + } + + uint16_t ScParkMessage::tickCount_get() const + { + auto msg = GetMessage(); + if (msg != nullptr) + { + return msg->Ticks; + } + return 0; + } + + void ScParkMessage::tickCount_set(uint16_t value) + { + ThrowIfGameStateNotMutable(); + auto msg = GetMessage(); + if (msg != nullptr) + { + msg->Ticks = value; + } + } + + std::string ScParkMessage::type_get() const + { + auto msg = GetMessage(); + if (msg != nullptr) + { + return GetParkMessageType(msg->Type); + } + return {}; + } + + void ScParkMessage::type_set(const std::string& value) + { + ThrowIfGameStateNotMutable(); + auto msg = GetMessage(); + if (msg != nullptr) + { + msg->Type = GetParkMessageType(value); + } + } + + uint32_t ScParkMessage::subject_get() const + { + auto msg = GetMessage(); + if (msg != nullptr) + { + return msg->Assoc; + } + return 0; + } + + void ScParkMessage::subject_set(uint32_t value) + { + ThrowIfGameStateNotMutable(); + auto msg = GetMessage(); + if (msg != nullptr) + { + msg->Assoc = value; + } + } + + std::string ScParkMessage::text_get() const + { + auto msg = GetMessage(); + if (msg != nullptr) + { + return msg->Text; + } + return {}; + } + + void ScParkMessage::text_set(const std::string& value) + { + ThrowIfGameStateNotMutable(); + auto msg = GetMessage(); + if (msg != nullptr) + { + msg->Text = value; + } + } + + void ScParkMessage::remove() + { + News::RemoveItem(static_cast(_index)); + } + +} // namespace OpenRCT2::Scripting + +#endif diff --git a/src/openrct2/scripting/bindings/world/ScParkMessage.hpp b/src/openrct2/scripting/bindings/world/ScParkMessage.hpp new file mode 100644 index 0000000000..48801a50a3 --- /dev/null +++ b/src/openrct2/scripting/bindings/world/ScParkMessage.hpp @@ -0,0 +1,103 @@ +/***************************************************************************** + * Copyright (c) 2014-2020 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#pragma once + +#ifdef ENABLE_SCRIPTING + +# include "../../../Context.h" +# include "../../../common.h" +# include "../../../management/NewsItem.h" +# include "../../Duktape.hpp" +# include "../../ScriptEngine.h" + +# include +# include + +namespace OpenRCT2::Scripting +{ + static constexpr const char* ParkMessageTypeStrings[] = { + "attraction", "peep_on_attraction", "peep", "money", "blank", "research", "guests", "award", "chart", + }; + + inline News::ItemType GetParkMessageType(const std::string& key) + { + // Get the first ItemType that appears in ParkMessageTypeStrings that isn't Null + auto firstType = static_cast(News::ItemType::Ride); + + auto begin = std::begin(ParkMessageTypeStrings); + auto end = std::end(ParkMessageTypeStrings); + + auto it = std::find(begin, end, key); + return it != end ? static_cast(firstType + std::distance(begin, it)) : News::ItemType::Blank; + } + + inline std::string GetParkMessageType(News::ItemType type) + { + // Decrement 1 as ParkMessageTypeStrings doesn't contain the null type + auto scriptType = static_cast(type) - 1; + + if (scriptType < std::size(ParkMessageTypeStrings)) + { + return ParkMessageTypeStrings[scriptType]; + } + return {}; + } + + template<> inline News::Item FromDuk(const DukValue& value) + { + News::Item result{}; + result.Type = GetParkMessageType(value["type"].as_string()); + result.Assoc = value["subject"].as_int(); + result.Ticks = value["tickCount"].as_int(); + result.MonthYear = value["month"].as_int(); + result.Day = value["day"].as_int(); + result.Text = value["text"].as_string(); + return result; + } + + class ScParkMessage + { + private: + size_t _index{}; + + public: + ScParkMessage(size_t index); + + static void Register(duk_context* ctx); + + private: + News::Item* GetMessage() const; + + bool isArchived_get() const; + + uint16_t month_get() const; + void month_set(uint16_t value); + + uint8_t day_get() const; + void day_set(uint8_t value); + + uint16_t tickCount_get() const; + void tickCount_set(uint16_t value); + + std::string type_get() const; + void type_set(const std::string& value); + + uint32_t subject_get() const; + void subject_set(uint32_t value); + + std::string text_get() const; + void text_set(const std::string& value); + + void remove(); + }; + +} // namespace OpenRCT2::Scripting + +#endif diff --git a/src/openrct2/scripting/ScScenario.hpp b/src/openrct2/scripting/bindings/world/ScScenario.hpp similarity index 97% rename from src/openrct2/scripting/ScScenario.hpp rename to src/openrct2/scripting/bindings/world/ScScenario.hpp index 4d47ea3403..944f7a47b9 100644 --- a/src/openrct2/scripting/ScScenario.hpp +++ b/src/openrct2/scripting/bindings/world/ScScenario.hpp @@ -11,14 +11,14 @@ #ifdef ENABLE_SCRIPTING -# include "../Context.h" -# include "../GameState.h" -# include "../common.h" -# include "../core/String.hpp" -# include "../scenario/Scenario.h" -# include "../world/Park.h" -# include "Duktape.hpp" -# include "ScriptEngine.h" +# include "../../../Context.h" +# include "../../../GameState.h" +# include "../../../common.h" +# include "../../../core/String.hpp" +# include "../../../scenario/Scenario.h" +# include "../../../world/Park.h" +# include "../../Duktape.hpp" +# include "../../ScriptEngine.h" # include diff --git a/src/openrct2/scripting/bindings/world/ScTile.cpp b/src/openrct2/scripting/bindings/world/ScTile.cpp new file mode 100644 index 0000000000..28d4d2751b --- /dev/null +++ b/src/openrct2/scripting/bindings/world/ScTile.cpp @@ -0,0 +1,243 @@ +/***************************************************************************** + * Copyright (c) 2014-2021 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#ifdef ENABLE_SCRIPTING + +# include "ScTile.hpp" + +# include "../../../Context.h" +# include "../../../common.h" +# include "../../../core/Guard.hpp" +# include "../../../ride/Track.h" +# include "../../../world/Footpath.h" +# include "../../../world/Scenery.h" +# include "../../../world/Sprite.h" +# include "../../../world/Surface.h" +# include "../../Duktape.hpp" +# include "../../ScriptEngine.h" +# include "ScTileElement.hpp" + +# include +# include +# include + +namespace OpenRCT2::Scripting +{ + ScTile::ScTile(const CoordsXY& coords) + : _coords(coords) + { + } + + int32_t ScTile::x_get() const + { + return _coords.x / COORDS_XY_STEP; + } + + int32_t ScTile::y_get() const + { + return _coords.y / COORDS_XY_STEP; + } + + uint32_t ScTile::numElements_get() const + { + auto first = GetFirstElement(); + return static_cast(GetNumElements(first)); + } + + std::vector> ScTile::elements_get() const + { + std::vector> result; + auto first = GetFirstElement(); + auto currentNumElements = GetNumElements(first); + if (currentNumElements != 0) + { + result.reserve(currentNumElements); + for (size_t i = 0; i < currentNumElements; i++) + { + result.push_back(std::make_shared(_coords, &first[i])); + } + } + return result; + } + + DukValue ScTile::data_get() const + { + auto ctx = GetDukContext(); + auto first = map_get_first_element_at(_coords); + auto dataLen = GetNumElements(first) * sizeof(TileElement); + auto data = duk_push_fixed_buffer(ctx, dataLen); + if (first != nullptr) + { + std::memcpy(data, first, dataLen); + } + duk_push_buffer_object(ctx, -1, 0, dataLen, DUK_BUFOBJ_UINT8ARRAY); + return DukValue::take_from_stack(ctx); + } + + void ScTile::data_set(DukValue value) + { + ThrowIfGameStateNotMutable(); + auto ctx = value.context(); + value.push(); + if (duk_is_buffer_data(ctx, -1)) + { + duk_size_t dataLen{}; + auto data = duk_get_buffer_data(ctx, -1, &dataLen); + auto numElements = dataLen / sizeof(TileElement); + if (numElements == 0) + { + map_set_tile_element(TileCoordsXY(_coords), nullptr); + } + else + { + auto first = GetFirstElement(); + auto currentNumElements = GetNumElements(first); + if (numElements > currentNumElements) + { + // Allocate space for the extra tile elements (inefficient but works) + auto pos = TileCoordsXYZ(TileCoordsXY(_coords), 0).ToCoordsXYZ(); + auto numToInsert = numElements - currentNumElements; + for (size_t i = 0; i < numToInsert; i++) + { + tile_element_insert(pos, 0, TileElementType::Surface); + } + + // Copy data to element span + first = map_get_first_element_at(_coords); + currentNumElements = GetNumElements(first); + if (currentNumElements != 0) + { + std::memcpy(first, data, currentNumElements * sizeof(TileElement)); + // Safely force last tile flag for last element to avoid read overrun + first[numElements - 1].SetLastForTile(true); + } + } + else + { + std::memcpy(first, data, numElements * sizeof(TileElement)); + // Safely force last tile flag for last element to avoid read overrun + first[numElements - 1].SetLastForTile(true); + } + } + map_invalidate_tile_full(_coords); + } + } + + std::shared_ptr ScTile::getElement(uint32_t index) const + { + auto first = GetFirstElement(); + if (static_cast(index) < GetNumElements(first)) + { + return std::make_shared(_coords, &first[index]); + } + return {}; + } + + std::shared_ptr ScTile::insertElement(uint32_t index) + { + ThrowIfGameStateNotMutable(); + std::shared_ptr result; + auto first = GetFirstElement(); + auto origNumElements = GetNumElements(first); + if (index <= origNumElements) + { + std::vector data(first, first + origNumElements); + + auto pos = TileCoordsXYZ(TileCoordsXY(_coords), 0).ToCoordsXYZ(); + auto newElement = tile_element_insert(pos, 0, TileElementType::Surface); + if (newElement == nullptr) + { + auto ctx = GetDukContext(); + duk_error(ctx, DUK_ERR_ERROR, "Unable to allocate element."); + } + else + { + // Inefficient, requires a dedicated method in tile element manager + first = GetFirstElement(); + // Copy elements before index + if (index > 0) + { + std::memcpy(first, &data[0], index * sizeof(TileElement)); + } + // Zero new element + std::memset(first + index, 0, sizeof(TileElement)); + // Copy elements after index + if (index < origNumElements) + { + std::memcpy(first + index + 1, &data[index], (origNumElements - index) * sizeof(TileElement)); + } + for (size_t i = 0; i < origNumElements; i++) + { + first[i].SetLastForTile(false); + } + first[origNumElements].SetLastForTile(true); + map_invalidate_tile_full(_coords); + result = std::make_shared(_coords, &first[index]); + } + } + else + { + auto ctx = GetDukContext(); + duk_error(ctx, DUK_ERR_RANGE_ERROR, "Index must be between zero and the number of elements on the tile."); + } + return result; + } + + void ScTile::removeElement(uint32_t index) + { + ThrowIfGameStateNotMutable(); + auto first = GetFirstElement(); + if (index < GetNumElements(first)) + { + tile_element_remove(&first[index]); + map_invalidate_tile_full(_coords); + } + } + + TileElement* ScTile::GetFirstElement() const + { + return map_get_first_element_at(_coords); + } + + size_t ScTile::GetNumElements(const TileElement* first) + { + size_t count = 0; + if (first != nullptr) + { + auto element = first; + do + { + count++; + } while (!(element++)->IsLastForTile()); + } + return count; + } + + duk_context* ScTile::GetDukContext() const + { + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto ctx = scriptEngine.GetContext(); + return ctx; + } + + void ScTile::Register(duk_context* ctx) + { + dukglue_register_property(ctx, &ScTile::x_get, nullptr, "x"); + dukglue_register_property(ctx, &ScTile::y_get, nullptr, "y"); + dukglue_register_property(ctx, &ScTile::elements_get, nullptr, "elements"); + dukglue_register_property(ctx, &ScTile::numElements_get, nullptr, "numElements"); + dukglue_register_property(ctx, &ScTile::data_get, &ScTile::data_set, "data"); + dukglue_register_method(ctx, &ScTile::getElement, "getElement"); + dukglue_register_method(ctx, &ScTile::insertElement, "insertElement"); + dukglue_register_method(ctx, &ScTile::removeElement, "removeElement"); + } + +} // namespace OpenRCT2::Scripting + +#endif diff --git a/src/openrct2/scripting/bindings/world/ScTile.hpp b/src/openrct2/scripting/bindings/world/ScTile.hpp new file mode 100644 index 0000000000..1698377c42 --- /dev/null +++ b/src/openrct2/scripting/bindings/world/ScTile.hpp @@ -0,0 +1,61 @@ +/***************************************************************************** + * Copyright (c) 2014-2021 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#pragma once + +#ifdef ENABLE_SCRIPTING + +# include "../../../common.h" +# include "../../Duktape.hpp" +# include "ScTileElement.hpp" + +# include +# include +# include +# include + +namespace OpenRCT2::Scripting +{ + class ScTile + { + private: + CoordsXY _coords; + + public: + ScTile(const CoordsXY& coords); + + private: + int32_t x_get() const; + + int32_t y_get() const; + + uint32_t numElements_get() const; + + std::vector> elements_get() const; + + DukValue data_get() const; + void data_set(DukValue value); + + std::shared_ptr getElement(uint32_t index) const; + std::shared_ptr insertElement(uint32_t index); + + void removeElement(uint32_t index); + + TileElement* GetFirstElement() const; + + static size_t GetNumElements(const TileElement* first); + + duk_context* GetDukContext() const; + + public: + static void Register(duk_context* ctx); + }; +} // namespace OpenRCT2::Scripting + +#endif diff --git a/src/openrct2/scripting/bindings/world/ScTileElement.cpp b/src/openrct2/scripting/bindings/world/ScTileElement.cpp new file mode 100644 index 0000000000..40251c55a4 --- /dev/null +++ b/src/openrct2/scripting/bindings/world/ScTileElement.cpp @@ -0,0 +1,1569 @@ +/***************************************************************************** + * Copyright (c) 2014-2021 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#ifdef ENABLE_SCRIPTING + +# include "ScTileElement.hpp" + +# include "../../../Context.h" +# include "../../../common.h" +# include "../../../core/Guard.hpp" +# include "../../../ride/Track.h" +# include "../../../world/Footpath.h" +# include "../../../world/Scenery.h" +# include "../../../world/Sprite.h" +# include "../../../world/Surface.h" +# include "../../Duktape.hpp" +# include "../../ScriptEngine.h" + +# include +# include +# include + +namespace OpenRCT2::Scripting +{ + ScTileElement::ScTileElement(const CoordsXY& coords, TileElement* element) + : _coords(coords) + , _element(element) + { + } + + std::string ScTileElement::type_get() const + { + switch (_element->GetType()) + { + case TILE_ELEMENT_TYPE_SURFACE: + return "surface"; + case TILE_ELEMENT_TYPE_PATH: + return "footpath"; + case TILE_ELEMENT_TYPE_TRACK: + return "track"; + case TILE_ELEMENT_TYPE_SMALL_SCENERY: + return "small_scenery"; + case TILE_ELEMENT_TYPE_ENTRANCE: + return "entrance"; + case TILE_ELEMENT_TYPE_WALL: + return "wall"; + case TILE_ELEMENT_TYPE_LARGE_SCENERY: + return "large_scenery"; + case TILE_ELEMENT_TYPE_BANNER: + return "banner"; + case TILE_ELEMENT_TYPE_CORRUPT: + return "openrct2_corrupt_deprecated"; + default: + return "unknown"; + } + } + + void ScTileElement::type_set(std::string value) + { + auto type = _element->type; + if (value == "surface") + type = TILE_ELEMENT_TYPE_SURFACE; + else if (value == "footpath") + type = TILE_ELEMENT_TYPE_PATH; + else if (value == "track") + type = TILE_ELEMENT_TYPE_TRACK; + else if (value == "small_scenery") + type = TILE_ELEMENT_TYPE_SMALL_SCENERY; + else if (value == "entrance") + type = TILE_ELEMENT_TYPE_ENTRANCE; + else if (value == "wall") + type = TILE_ELEMENT_TYPE_WALL; + else if (value == "large_scenery") + type = TILE_ELEMENT_TYPE_LARGE_SCENERY; + else if (value == "banner") + type = TILE_ELEMENT_TYPE_BANNER; + else + { + if (value == "openrct2_corrupt_deprecated") + std::puts( + "Creation of new corrupt elements is deprecated. To hide elements, use the 'hidden' property instead."); + return; + } + + _element->type = type; + Invalidate(); + } + + uint8_t ScTileElement::baseHeight_get() const + { + return _element->base_height; + } + void ScTileElement::baseHeight_set(uint8_t newBaseHeight) + { + ThrowIfGameStateNotMutable(); + _element->base_height = newBaseHeight; + Invalidate(); + } + + uint16_t ScTileElement::baseZ_get() const + { + return _element->GetBaseZ(); + } + void ScTileElement::baseZ_set(uint16_t value) + { + ThrowIfGameStateNotMutable(); + _element->SetBaseZ(value); + Invalidate(); + } + + uint8_t ScTileElement::clearanceHeight_get() const + { + return _element->clearance_height; + } + void ScTileElement::clearanceHeight_set(uint8_t newClearanceHeight) + { + ThrowIfGameStateNotMutable(); + _element->clearance_height = newClearanceHeight; + Invalidate(); + } + + uint16_t ScTileElement::clearanceZ_get() const + { + return _element->GetClearanceZ(); + } + void ScTileElement::clearanceZ_set(uint16_t value) + { + ThrowIfGameStateNotMutable(); + _element->SetClearanceZ(value); + Invalidate(); + } + + DukValue ScTileElement::slope_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + switch (_element->GetType()) + { + case TILE_ELEMENT_TYPE_SURFACE: + { + auto el = _element->AsSurface(); + duk_push_int(ctx, el->GetSlope()); + break; + } + case TILE_ELEMENT_TYPE_WALL: + { + auto el = _element->AsWall(); + duk_push_int(ctx, el->GetSlope()); + break; + } + default: + { + duk_push_null(ctx); + break; + } + } + return DukValue::take_from_stack(ctx); + } + void ScTileElement::slope_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + switch (_element->GetType()) + { + case TILE_ELEMENT_TYPE_SURFACE: + { + auto el = _element->AsSurface(); + el->SetSlope(value); + Invalidate(); + break; + } + case TILE_ELEMENT_TYPE_WALL: + { + auto el = _element->AsWall(); + el->SetSlope(value); + Invalidate(); + break; + } + } + } + + DukValue ScTileElement::waterHeight_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto el = _element->AsSurface(); + if (el != nullptr) + duk_push_int(ctx, el->GetWaterHeight()); + else + duk_push_null(ctx); + return DukValue::take_from_stack(ctx); + } + void ScTileElement::waterHeight_set(int32_t value) + { + ThrowIfGameStateNotMutable(); + auto el = _element->AsSurface(); + if (el != nullptr) + { + el->SetWaterHeight(value); + Invalidate(); + } + } + + DukValue ScTileElement::surfaceStyle_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto el = _element->AsSurface(); + if (el != nullptr) + duk_push_int(ctx, el->GetSurfaceStyle()); + else + duk_push_null(ctx); + return DukValue::take_from_stack(ctx); + } + void ScTileElement::surfaceStyle_set(uint32_t value) + { + ThrowIfGameStateNotMutable(); + auto el = _element->AsSurface(); + if (el != nullptr) + { + el->SetSurfaceStyle(value); + Invalidate(); + } + } + + DukValue ScTileElement::edgeStyle_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto el = _element->AsSurface(); + if (el != nullptr) + duk_push_int(ctx, el->GetEdgeStyle()); + else + duk_push_null(ctx); + return DukValue::take_from_stack(ctx); + } + void ScTileElement::edgeStyle_set(uint32_t value) + { + ThrowIfGameStateNotMutable(); + auto el = _element->AsSurface(); + if (el != nullptr) + { + el->SetEdgeStyle(value); + Invalidate(); + } + } + + DukValue ScTileElement::grassLength_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto el = _element->AsSurface(); + if (el != nullptr) + duk_push_int(ctx, el->GetGrassLength()); + else + duk_push_null(ctx); + return DukValue::take_from_stack(ctx); + } + void ScTileElement::grassLength_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto el = _element->AsSurface(); + if (el != nullptr) + { + // TODO: Give warning when value > GRASS_LENGTH_CLUMPS_2 + el->SetGrassLengthAndInvalidate(value, _coords); + Invalidate(); + } + } + + DukValue ScTileElement::hasOwnership_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto el = _element->AsSurface(); + if (el != nullptr) + duk_push_boolean(ctx, el->GetOwnership() & OWNERSHIP_OWNED); + else + duk_push_null(ctx); + return DukValue::take_from_stack(ctx); + } + + DukValue ScTileElement::hasConstructionRights_get() + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto el = _element->AsSurface(); + if (el != nullptr) + { + auto ownership = el->GetOwnership(); + duk_push_boolean(ctx, (ownership & OWNERSHIP_OWNED) || (ownership & OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED)); + } + else + duk_push_null(ctx); + return DukValue::take_from_stack(ctx); + } + + DukValue ScTileElement::ownership_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto el = _element->AsSurface(); + if (el != nullptr) + duk_push_int(ctx, el->GetOwnership()); + else + duk_push_null(ctx); + return DukValue::take_from_stack(ctx); + } + void ScTileElement::ownership_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto el = _element->AsSurface(); + if (el != nullptr) + { + el->SetOwnership(value); + Invalidate(); + } + } + + DukValue ScTileElement::parkFences_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto el = _element->AsSurface(); + if (el != nullptr) + duk_push_int(ctx, el->GetParkFences()); + else + duk_push_null(ctx); + return DukValue::take_from_stack(ctx); + } + void ScTileElement::parkFences_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto el = _element->AsSurface(); + if (el != nullptr) + { + el->SetParkFences(value); + Invalidate(); + } + } + + DukValue ScTileElement::trackType_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto el = _element->AsTrack(); + if (el != nullptr) + duk_push_int(ctx, el->GetTrackType()); + else + duk_push_null(ctx); + return DukValue::take_from_stack(ctx); + } + void ScTileElement::trackType_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto el = _element->AsTrack(); + if (el != nullptr) + { + el->SetTrackType(value); + Invalidate(); + } + } + + DukValue ScTileElement::sequence_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + switch (_element->GetType()) + { + case TILE_ELEMENT_TYPE_LARGE_SCENERY: + { + auto el = _element->AsLargeScenery(); + duk_push_int(ctx, el->GetSequenceIndex()); + break; + } + case TILE_ELEMENT_TYPE_TRACK: + { + auto el = _element->AsTrack(); + if (get_ride(el->GetRideIndex())->type != RIDE_TYPE_MAZE) + duk_push_int(ctx, el->GetSequenceIndex()); + else + duk_push_null(ctx); + break; + } + case TILE_ELEMENT_TYPE_ENTRANCE: + { + auto el = _element->AsEntrance(); + duk_push_int(ctx, el->GetSequenceIndex()); + break; + } + default: + { + duk_push_null(ctx); + break; + } + } + return DukValue::take_from_stack(ctx); + } + void ScTileElement::sequence_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + switch (_element->GetType()) + { + case TILE_ELEMENT_TYPE_LARGE_SCENERY: + { + auto el = _element->AsLargeScenery(); + el->SetSequenceIndex(value); + Invalidate(); + break; + } + case TILE_ELEMENT_TYPE_TRACK: + { + auto el = _element->AsTrack(); + if (get_ride(el->GetRideIndex())->type != RIDE_TYPE_MAZE) + { + el->SetSequenceIndex(value); + Invalidate(); + } + break; + } + case TILE_ELEMENT_TYPE_ENTRANCE: + { + auto el = _element->AsEntrance(); + el->SetSequenceIndex(value); + Invalidate(); + break; + } + } + } + + DukValue ScTileElement::ride_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + switch (_element->GetType()) + { + case TILE_ELEMENT_TYPE_PATH: + { + auto el = _element->AsPath(); + if (el->IsQueue() && el->GetRideIndex() != RIDE_ID_NULL) + duk_push_int(ctx, el->GetRideIndex()); + else + duk_push_null(ctx); + break; + } + case TILE_ELEMENT_TYPE_TRACK: + { + auto el = _element->AsTrack(); + duk_push_int(ctx, el->GetRideIndex()); + break; + } + case TILE_ELEMENT_TYPE_ENTRANCE: + { + auto el = _element->AsEntrance(); + duk_push_int(ctx, el->GetRideIndex()); + break; + } + default: + { + duk_push_null(ctx); + break; + } + } + return DukValue::take_from_stack(ctx); + } + void ScTileElement::ride_set(ride_id_t value) + { + ThrowIfGameStateNotMutable(); + switch (_element->GetType()) + { + case TILE_ELEMENT_TYPE_PATH: + { + auto el = _element->AsPath(); + if (!el->HasAddition()) + { + el->SetRideIndex(value); + Invalidate(); + } + break; + } + case TILE_ELEMENT_TYPE_TRACK: + { + auto el = _element->AsTrack(); + el->SetRideIndex(value); + Invalidate(); + break; + } + case TILE_ELEMENT_TYPE_ENTRANCE: + { + auto el = _element->AsEntrance(); + el->SetRideIndex(value); + Invalidate(); + break; + } + } + } + + DukValue ScTileElement::station_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + switch (_element->GetType()) + { + case TILE_ELEMENT_TYPE_PATH: + { + auto el = _element->AsPath(); + if (el->IsQueue() && el->GetRideIndex() != RIDE_ID_NULL) + duk_push_int(ctx, el->GetStationIndex()); + else + duk_push_null(ctx); + break; + } + case TILE_ELEMENT_TYPE_TRACK: + { + auto el = _element->AsTrack(); + if (el->IsStation()) + duk_push_int(ctx, el->GetStationIndex()); + else + duk_push_null(ctx); + break; + } + case TILE_ELEMENT_TYPE_ENTRANCE: + { + auto el = _element->AsEntrance(); + duk_push_int(ctx, el->GetStationIndex()); + break; + } + default: + { + duk_push_null(ctx); + break; + } + } + return DukValue::take_from_stack(ctx); + } + void ScTileElement::station_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + switch (_element->GetType()) + { + case TILE_ELEMENT_TYPE_PATH: + { + auto el = _element->AsPath(); + el->SetStationIndex(value); + Invalidate(); + break; + } + case TILE_ELEMENT_TYPE_TRACK: + { + auto el = _element->AsTrack(); + el->SetStationIndex(value); + Invalidate(); + break; + } + case TILE_ELEMENT_TYPE_ENTRANCE: + { + auto el = _element->AsEntrance(); + el->SetStationIndex(value); + Invalidate(); + break; + } + } + } + + DukValue ScTileElement::hasChainLift_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto el = _element->AsTrack(); + if (el != nullptr) + duk_push_boolean(ctx, el->HasChain()); + else + duk_push_null(ctx); + return DukValue::take_from_stack(ctx); + } + void ScTileElement::hasChainLift_set(bool value) + { + ThrowIfGameStateNotMutable(); + auto el = _element->AsTrack(); + if (el != nullptr) + { + el->SetHasChain(value); + Invalidate(); + } + } + + DukValue ScTileElement::mazeEntry_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto el = _element->AsTrack(); + if (el != nullptr && get_ride(el->GetRideIndex())->type == RIDE_TYPE_MAZE) + duk_push_int(ctx, el->GetMazeEntry()); + else + duk_push_null(ctx); + return DukValue::take_from_stack(ctx); + } + void ScTileElement::mazeEntry_set(uint16_t value) + { + ThrowIfGameStateNotMutable(); + auto el = _element->AsTrack(); + if (el != nullptr) + if (get_ride(el->GetRideIndex())->type == RIDE_TYPE_MAZE) + { + el->SetMazeEntry(value); + Invalidate(); + } + } + + DukValue ScTileElement::colourScheme_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto el = _element->AsTrack(); + if (el != nullptr && get_ride(el->GetRideIndex())->type != RIDE_TYPE_MAZE) + duk_push_int(ctx, el->GetColourScheme()); + else + duk_push_null(ctx); + return DukValue::take_from_stack(ctx); + } + void ScTileElement::colourScheme_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto el = _element->AsTrack(); + if (el != nullptr) + if (get_ride(el->GetRideIndex())->type != RIDE_TYPE_MAZE) + { + el->SetColourScheme(value); + Invalidate(); + } + } + + DukValue ScTileElement::seatRotation_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto el = _element->AsTrack(); + if (el != nullptr && get_ride(el->GetRideIndex())->type != RIDE_TYPE_MAZE) + duk_push_int(ctx, el->GetSeatRotation()); + else + duk_push_null(ctx); + return DukValue::take_from_stack(ctx); + } + void ScTileElement::seatRotation_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto el = _element->AsTrack(); + if (el != nullptr) + if (get_ride(el->GetRideIndex())->type != RIDE_TYPE_MAZE) + { + el->SetSeatRotation(value); + Invalidate(); + } + } + + DukValue ScTileElement::brakeBoosterSpeed_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto el = _element->AsTrack(); + if (el != nullptr && TrackTypeHasSpeedSetting(el->GetTrackType())) + duk_push_int(ctx, el->GetBrakeBoosterSpeed()); + else + duk_push_null(ctx); + return DukValue::take_from_stack(ctx); + } + void ScTileElement::brakeBoosterSpeed_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto el = _element->AsTrack(); + if (el != nullptr) + if (TrackTypeHasSpeedSetting(el->GetTrackType())) + { + el->SetBrakeBoosterSpeed(value); + Invalidate(); + } + } + + DukValue ScTileElement::isInverted_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto el = _element->AsTrack(); + if (el != nullptr) + duk_push_boolean(ctx, el->IsInverted()); + else + duk_push_null(ctx); + return DukValue::take_from_stack(ctx); + } + void ScTileElement::isInverted_set(bool value) + { + ThrowIfGameStateNotMutable(); + auto el = _element->AsTrack(); + if (el != nullptr) + { + el->SetInverted(value); + Invalidate(); + } + } + + DukValue ScTileElement::hasCableLift_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto el = _element->AsTrack(); + if (el != nullptr) + duk_push_boolean(ctx, el->HasCableLift()); + else + duk_push_null(ctx); + return DukValue::take_from_stack(ctx); + } + void ScTileElement::hasCableLift_set(bool value) + { + ThrowIfGameStateNotMutable(); + auto el = _element->AsTrack(); + if (el != nullptr) + { + el->SetHasCableLift(value); + Invalidate(); + } + } + + DukValue ScTileElement::object_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + switch (_element->GetType()) + { + case TILE_ELEMENT_TYPE_PATH: + { + auto el = _element->AsPath(); + duk_push_int(ctx, el->GetSurfaceEntryIndex()); + break; + } + case TILE_ELEMENT_TYPE_SMALL_SCENERY: + { + auto el = _element->AsSmallScenery(); + duk_push_int(ctx, el->GetEntryIndex()); + break; + } + case TILE_ELEMENT_TYPE_LARGE_SCENERY: + { + auto el = _element->AsLargeScenery(); + duk_push_int(ctx, el->GetEntryIndex()); + break; + } + case TILE_ELEMENT_TYPE_WALL: + { + auto el = _element->AsWall(); + duk_push_int(ctx, el->GetEntryIndex()); + break; + } + case TILE_ELEMENT_TYPE_ENTRANCE: + { + auto el = _element->AsEntrance(); + duk_push_int(ctx, el->GetEntranceType()); + break; + } + default: + { + duk_push_null(ctx); + break; + } + } + return DukValue::take_from_stack(ctx); + } + void ScTileElement::object_set(uint32_t value) + { + ThrowIfGameStateNotMutable(); + switch (_element->GetType()) + { + case TILE_ELEMENT_TYPE_PATH: + { + auto el = _element->AsPath(); + el->SetSurfaceEntryIndex(value & 0xFF); + Invalidate(); + break; + } + case TILE_ELEMENT_TYPE_SMALL_SCENERY: + { + auto el = _element->AsSmallScenery(); + el->SetEntryIndex(value & 0xFF); + Invalidate(); + break; + } + case TILE_ELEMENT_TYPE_LARGE_SCENERY: + { + auto el = _element->AsLargeScenery(); + el->SetEntryIndex(value); + Invalidate(); + break; + } + case TILE_ELEMENT_TYPE_WALL: + { + auto el = _element->AsWall(); + el->SetEntryIndex(value & 0xFFFF); + Invalidate(); + break; + } + case TILE_ELEMENT_TYPE_ENTRANCE: + { + auto el = _element->AsEntrance(); + el->SetEntranceType(value & 0xFF); + Invalidate(); + break; + } + } + } + + bool ScTileElement::isHidden_get() const + { + // TODO: Simply return the 'hidden' field once corrupt elements are superseded. + const TileElement* element = map_get_first_element_at(_coords); + bool previousElementWasUsefulCorrupt = false; + do + { + if (element == _element) + return previousElementWasUsefulCorrupt; + + if (element->GetType() == TILE_ELEMENT_TYPE_CORRUPT) + previousElementWasUsefulCorrupt = !previousElementWasUsefulCorrupt; + else + previousElementWasUsefulCorrupt = false; + } while (!(element++)->IsLastForTile()); + + Guard::Assert(false); + return false; + } + void ScTileElement::isHidden_set(bool hide) + { + // TODO: Simply update the 'hidden' field once corrupt elements are superseded. + ThrowIfGameStateNotMutable(); + const bool isHidden = isHidden_get(); + if (hide == isHidden) + return; + + if (hide) + { + // Get index of our current element (has to be done now before inserting the corrupt element) + const auto elementIndex = _element - map_get_first_element_at(_coords); + + // Insert corrupt element at the end of the list for this tile + // Note: Z = MAX_ELEMENT_HEIGHT to guarantee this + TileElement* insertedElement = tile_element_insert( + { _coords, MAX_ELEMENT_HEIGHT * COORDS_Z_STEP }, 0, TileElementType::Corrupt); + if (insertedElement == nullptr) + { + // TODO: Show error + return; + } + + // Since inserting a new element may move the tile elements in memory, we have to update the local pointer + _element = map_get_first_element_at(_coords) + elementIndex; + + // Move the corrupt element down in the list until it's right under our element + while (insertedElement > _element) + { + std::swap(*insertedElement, *(insertedElement - 1)); + insertedElement--; + + // Un-swap the last-for-tile flag + if (insertedElement->IsLastForTile()) + { + insertedElement->SetLastForTile(false); + (insertedElement + 1)->SetLastForTile(true); + } + } + + // Now the corrupt element took the hidden element's place, increment it by one + _element++; + + // Update base and clearance heights of inserted corrupt element to match the element to hide + insertedElement->base_height = insertedElement->clearance_height = _element->base_height; + } + else + { + TileElement* const elementToRemove = _element - 1; + Guard::Assert(elementToRemove->GetType() == TILE_ELEMENT_TYPE_CORRUPT); + tile_element_remove(elementToRemove); + _element--; + } + + Invalidate(); + } + + DukValue ScTileElement::age_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto el = _element->AsSmallScenery(); + if (el != nullptr) + duk_push_int(ctx, el->GetAge()); + else + duk_push_null(ctx); + return DukValue::take_from_stack(ctx); + } + void ScTileElement::age_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto el = _element->AsSmallScenery(); + if (el != nullptr) + { + el->SetAge(value); + Invalidate(); + } + } + + DukValue ScTileElement::quadrant_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto el = _element->AsSmallScenery(); + if (el != nullptr) + duk_push_int(ctx, el->GetSceneryQuadrant()); + else + duk_push_null(ctx); + return DukValue::take_from_stack(ctx); + } + void ScTileElement::quadrant_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto el = _element->AsSmallScenery(); + if (el != nullptr) + { + el->SetSceneryQuadrant(value); + Invalidate(); + } + } + + uint8_t ScTileElement::occupiedQuadrants_get() const + { + return _element->GetOccupiedQuadrants(); + } + void ScTileElement::occupiedQuadrants_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + _element->SetOccupiedQuadrants(value); + Invalidate(); + } + + bool ScTileElement::isGhost_get() const + { + return _element->IsGhost(); + } + void ScTileElement::isGhost_set(bool value) + { + ThrowIfGameStateNotMutable(); + _element->SetGhost(value); + Invalidate(); + } + + DukValue ScTileElement::primaryColour_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + switch (_element->GetType()) + { + case TILE_ELEMENT_TYPE_SMALL_SCENERY: + { + auto el = _element->AsSmallScenery(); + duk_push_int(ctx, el->GetPrimaryColour()); + break; + } + case TILE_ELEMENT_TYPE_LARGE_SCENERY: + { + auto el = _element->AsLargeScenery(); + duk_push_int(ctx, el->GetPrimaryColour()); + break; + } + case TILE_ELEMENT_TYPE_WALL: + { + auto el = _element->AsWall(); + duk_push_int(ctx, el->GetPrimaryColour()); + break; + } + default: + { + duk_push_null(ctx); + break; + } + } + return DukValue::take_from_stack(ctx); + } + void ScTileElement::primaryColour_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + switch (_element->GetType()) + { + case TILE_ELEMENT_TYPE_SMALL_SCENERY: + { + auto el = _element->AsSmallScenery(); + el->SetPrimaryColour(value); + Invalidate(); + break; + } + case TILE_ELEMENT_TYPE_LARGE_SCENERY: + { + auto el = _element->AsLargeScenery(); + el->SetPrimaryColour(value); + Invalidate(); + break; + } + case TILE_ELEMENT_TYPE_WALL: + { + auto el = _element->AsWall(); + el->SetPrimaryColour(value); + Invalidate(); + break; + } + } + } + + DukValue ScTileElement::secondaryColour_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + switch (_element->GetType()) + { + case TILE_ELEMENT_TYPE_SMALL_SCENERY: + { + auto el = _element->AsSmallScenery(); + duk_push_int(ctx, el->GetSecondaryColour()); + break; + } + case TILE_ELEMENT_TYPE_LARGE_SCENERY: + { + auto el = _element->AsLargeScenery(); + duk_push_int(ctx, el->GetSecondaryColour()); + break; + } + case TILE_ELEMENT_TYPE_WALL: + { + auto el = _element->AsWall(); + duk_push_int(ctx, el->GetSecondaryColour()); + break; + } + default: + { + duk_push_null(ctx); + break; + } + } + return DukValue::take_from_stack(ctx); + } + void ScTileElement::secondaryColour_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + switch (_element->GetType()) + { + case TILE_ELEMENT_TYPE_SMALL_SCENERY: + { + auto el = _element->AsSmallScenery(); + el->SetSecondaryColour(value); + Invalidate(); + break; + } + case TILE_ELEMENT_TYPE_LARGE_SCENERY: + { + auto el = _element->AsLargeScenery(); + el->SetSecondaryColour(value); + Invalidate(); + break; + } + case TILE_ELEMENT_TYPE_WALL: + { + auto el = _element->AsWall(); + el->SetSecondaryColour(value); + Invalidate(); + break; + } + } + } + + DukValue ScTileElement::tertiaryColour_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto el = _element->AsWall(); + if (el != nullptr) + duk_push_int(ctx, el->GetTertiaryColour()); + else + duk_push_null(ctx); + return DukValue::take_from_stack(ctx); + } + void ScTileElement::tertiaryColour_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto el = _element->AsWall(); + if (el != nullptr) + { + el->SetTertiaryColour(value); + Invalidate(); + } + } + + DukValue ScTileElement::bannerIndex_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + BannerIndex idx = _element->GetBannerIndex(); + if (idx == BANNER_INDEX_NULL) + duk_push_null(ctx); + else + duk_push_int(ctx, idx); + return DukValue::take_from_stack(ctx); + } + void ScTileElement::bannerIndex_set(uint16_t value) + { + ThrowIfGameStateNotMutable(); + switch (_element->GetType()) + { + case TILE_ELEMENT_TYPE_LARGE_SCENERY: + { + auto el = _element->AsLargeScenery(); + el->SetBannerIndex(value); + Invalidate(); + break; + } + case TILE_ELEMENT_TYPE_WALL: + { + auto el = _element->AsWall(); + el->SetBannerIndex(value); + Invalidate(); + break; + } + case TILE_ELEMENT_TYPE_BANNER: + { + auto el = _element->AsBanner(); + el->SetIndex(value); + Invalidate(); + break; + } + } + } + + // Deprecated in favor of seperate 'edges' and 'corners' properties, + // left here to maintain compatibility with older plugins. + /** @deprecated */ + uint8_t ScTileElement::edgesAndCorners_get() const + { + auto el = _element->AsPath(); + return el != nullptr ? el->GetEdgesAndCorners() : 0; + } + /** @deprecated */ + void ScTileElement::edgesAndCorners_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto el = _element->AsPath(); + if (el != nullptr) + { + el->SetEdgesAndCorners(value); + Invalidate(); + } + } + + DukValue ScTileElement::edges_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto el = _element->AsPath(); + if (el != nullptr) + duk_push_int(ctx, el->GetEdges()); + else + duk_push_null(ctx); + return DukValue::take_from_stack(ctx); + } + void ScTileElement::edges_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto el = _element->AsPath(); + if (el != nullptr) + { + el->SetEdges(value); + Invalidate(); + } + } + + DukValue ScTileElement::corners_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto el = _element->AsPath(); + if (el != nullptr) + duk_push_int(ctx, el->GetCorners()); + else + duk_push_null(ctx); + return DukValue::take_from_stack(ctx); + } + void ScTileElement::corners_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto el = _element->AsPath(); + if (el != nullptr) + { + el->SetCorners(value); + Invalidate(); + } + } + + DukValue ScTileElement::slopeDirection_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto el = _element->AsPath(); + if (el != nullptr && el->IsSloped()) + duk_push_int(ctx, el->GetSlopeDirection()); + else + duk_push_null(ctx); + return DukValue::take_from_stack(ctx); + } + void ScTileElement::slopeDirection_set(const DukValue& value) + { + ThrowIfGameStateNotMutable(); + auto el = _element->AsPath(); + if (el != nullptr) + { + if (value.type() == DukValue::Type::NUMBER) + { + el->SetSloped(true); + el->SetSlopeDirection(value.as_int()); + } + else + { + el->SetSloped(false); + el->SetSlopeDirection(0); + } + Invalidate(); + } + } + + DukValue ScTileElement::isQueue_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto el = _element->AsPath(); + if (el != nullptr) + duk_push_boolean(ctx, el->IsQueue()); + else + duk_push_null(ctx); + return DukValue::take_from_stack(ctx); + } + void ScTileElement::isQueue_set(bool value) + { + ThrowIfGameStateNotMutable(); + auto el = _element->AsPath(); + if (el != nullptr) + { + el->SetIsQueue(value); + Invalidate(); + } + } + + DukValue ScTileElement::queueBannerDirection_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto el = _element->AsPath(); + if (el != nullptr && el->HasQueueBanner()) + duk_push_int(ctx, el->GetQueueBannerDirection()); + else + duk_push_null(ctx); + return DukValue::take_from_stack(ctx); + } + void ScTileElement::queueBannerDirection_set(const DukValue& value) + { + ThrowIfGameStateNotMutable(); + auto el = _element->AsPath(); + if (el != nullptr) + { + if (value.type() == DukValue::Type::NUMBER) + { + el->SetHasQueueBanner(true); + el->SetQueueBannerDirection(value.as_int()); + } + else + { + el->SetHasQueueBanner(false); + el->SetQueueBannerDirection(0); + } + Invalidate(); + } + } + + DukValue ScTileElement::isBlockedByVehicle_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto el = _element->AsPath(); + if (el != nullptr) + duk_push_boolean(ctx, el->IsBlockedByVehicle()); + else + duk_push_null(ctx); + return DukValue::take_from_stack(ctx); + } + void ScTileElement::isBlockedByVehicle_set(bool value) + { + ThrowIfGameStateNotMutable(); + auto el = _element->AsPath(); + if (el != nullptr) + { + el->SetIsBlockedByVehicle(value); + Invalidate(); + } + } + + DukValue ScTileElement::isWide_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto el = _element->AsPath(); + if (el != nullptr) + duk_push_boolean(ctx, el->IsWide()); + else + duk_push_null(ctx); + return DukValue::take_from_stack(ctx); + } + void ScTileElement::isWide_set(bool value) + { + ThrowIfGameStateNotMutable(); + auto el = _element->AsPath(); + if (el != nullptr) + { + el->SetWide(value); + Invalidate(); + } + } + + DukValue ScTileElement::addition_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto el = _element->AsPath(); + if (el != nullptr && el->HasAddition()) + duk_push_int(ctx, el->GetAddition() - 1); + else + duk_push_null(ctx); + return DukValue::take_from_stack(ctx); + } + void ScTileElement::addition_set(const DukValue& value) + { + ThrowIfGameStateNotMutable(); + auto el = _element->AsPath(); + if (el != nullptr) + { + if (value.type() == DukValue::Type::NUMBER) + { + auto addition = value.as_int(); + if (addition >= 0 && addition <= 254) + { + el->SetAddition(addition + 1); + } + } + else + { + el->SetAddition(0); + } + Invalidate(); + } + } + + DukValue ScTileElement::additionStatus_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto el = _element->AsPath(); + if (el != nullptr && el->HasAddition()) + duk_push_int(ctx, el->GetAdditionStatus()); + else + duk_push_null(ctx); + return DukValue::take_from_stack(ctx); + } + void ScTileElement::additionStatus_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto el = _element->AsPath(); + if (el != nullptr) + if (el->HasAddition()) + { + el->SetAdditionStatus(value); + Invalidate(); + } + } + + DukValue ScTileElement::isAdditionBroken_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto el = _element->AsPath(); + if (el != nullptr && el->HasAddition()) + duk_push_boolean(ctx, el->IsBroken()); + else + duk_push_null(ctx); + return DukValue::take_from_stack(ctx); + } + void ScTileElement::isAdditionBroken_set(bool value) + { + ThrowIfGameStateNotMutable(); + auto el = _element->AsPath(); + if (el != nullptr) + { + el->SetIsBroken(value); + Invalidate(); + } + } + + DukValue ScTileElement::isAdditionGhost_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto el = _element->AsPath(); + if (el != nullptr && el->HasAddition()) + duk_push_boolean(ctx, el->AdditionIsGhost()); + else + duk_push_null(ctx); + return DukValue::take_from_stack(ctx); + } + void ScTileElement::isAdditionGhost_set(bool value) + { + ThrowIfGameStateNotMutable(); + auto el = _element->AsPath(); + if (el != nullptr) + { + el->SetAdditionIsGhost(value); + Invalidate(); + } + } + + DukValue ScTileElement::footpathObject_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto el = _element->AsEntrance(); + if (el != nullptr) + duk_push_int(ctx, el->GetPathType()); + else + duk_push_null(ctx); + return DukValue::take_from_stack(ctx); + } + void ScTileElement::footpathObject_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto el = _element->AsEntrance(); + if (el != nullptr) + { + el->SetPathType(value); + Invalidate(); + } + } + + DukValue ScTileElement::direction_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + switch (_element->GetType()) + { + case TILE_ELEMENT_TYPE_BANNER: + { + auto el = _element->AsBanner(); + duk_push_int(ctx, el->GetPosition()); + break; + } + case TILE_ELEMENT_TYPE_PATH: + case TILE_ELEMENT_TYPE_SURFACE: + { + duk_push_null(ctx); + break; + } + default: + { + duk_push_int(ctx, _element->GetDirection()); + break; + } + } + return DukValue::take_from_stack(ctx); + } + void ScTileElement::direction_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + switch (_element->GetType()) + { + case TILE_ELEMENT_TYPE_BANNER: + { + auto el = _element->AsBanner(); + el->SetPosition(value); + Invalidate(); + break; + } + case TILE_ELEMENT_TYPE_PATH: + case TILE_ELEMENT_TYPE_SURFACE: + { + break; + } + default: + { + _element->SetDirection(value); + Invalidate(); + } + } + } + + void ScTileElement::Invalidate() + { + map_invalidate_tile_full(_coords); + } + + void ScTileElement::Register(duk_context* ctx) + { + // All + dukglue_register_property(ctx, &ScTileElement::type_get, &ScTileElement::type_set, "type"); + dukglue_register_property(ctx, &ScTileElement::baseHeight_get, &ScTileElement::baseHeight_set, "baseHeight"); + dukglue_register_property(ctx, &ScTileElement::baseZ_get, &ScTileElement::baseZ_set, "baseZ"); + dukglue_register_property( + ctx, &ScTileElement::clearanceHeight_get, &ScTileElement::clearanceHeight_set, "clearanceHeight"); + dukglue_register_property(ctx, &ScTileElement::clearanceZ_get, &ScTileElement::clearanceZ_set, "clearanceZ"); + dukglue_register_property( + ctx, &ScTileElement::occupiedQuadrants_get, &ScTileElement::occupiedQuadrants_set, "occupiedQuadrants"); + dukglue_register_property(ctx, &ScTileElement::isGhost_get, &ScTileElement::isGhost_set, "isGhost"); + dukglue_register_property(ctx, &ScTileElement::isHidden_get, &ScTileElement::isHidden_set, "isHidden"); + + // Track | Small Scenery | Wall | Entrance | Large Scenery | Banner + dukglue_register_property(ctx, &ScTileElement::direction_get, &ScTileElement::direction_set, "direction"); + + // Path | Small Scenery | Wall | Entrance | Large Scenery + dukglue_register_property(ctx, &ScTileElement::object_get, &ScTileElement::object_set, "object"); + + // Small Scenery | Wall | Large Scenery + dukglue_register_property(ctx, &ScTileElement::primaryColour_get, &ScTileElement::primaryColour_set, "primaryColour"); + dukglue_register_property( + ctx, &ScTileElement::secondaryColour_get, &ScTileElement::secondaryColour_set, "secondaryColour"); + + // Wall | Large Scenery | Banner + dukglue_register_property(ctx, &ScTileElement::bannerIndex_get, &ScTileElement::bannerIndex_set, "bannerIndex"); + + // Path | Track | Entrance + dukglue_register_property(ctx, &ScTileElement::ride_get, &ScTileElement::ride_set, "ride"); + dukglue_register_property(ctx, &ScTileElement::station_get, &ScTileElement::station_set, "station"); + + // Track | Entrance | Large Scenery + dukglue_register_property(ctx, &ScTileElement::sequence_get, &ScTileElement::sequence_set, "sequence"); + + // Surface | Wall + dukglue_register_property(ctx, &ScTileElement::slope_get, &ScTileElement::slope_set, "slope"); + + // Surface only + dukglue_register_property(ctx, &ScTileElement::waterHeight_get, &ScTileElement::waterHeight_set, "waterHeight"); + dukglue_register_property(ctx, &ScTileElement::surfaceStyle_get, &ScTileElement::surfaceStyle_set, "surfaceStyle"); + dukglue_register_property(ctx, &ScTileElement::edgeStyle_get, &ScTileElement::edgeStyle_set, "edgeStyle"); + dukglue_register_property(ctx, &ScTileElement::grassLength_get, &ScTileElement::grassLength_set, "grassLength"); + dukglue_register_property(ctx, &ScTileElement::hasOwnership_get, nullptr, "hasOwnership"); + dukglue_register_property(ctx, &ScTileElement::hasConstructionRights_get, nullptr, "hasConstructionRights"); + dukglue_register_property(ctx, &ScTileElement::ownership_get, &ScTileElement::ownership_set, "ownership"); + dukglue_register_property(ctx, &ScTileElement::parkFences_get, &ScTileElement::parkFences_set, "parkFences"); + + // Footpath only + dukglue_register_property( + ctx, &ScTileElement::edgesAndCorners_get, &ScTileElement::edgesAndCorners_set, "edgesAndCorners"); + dukglue_register_property(ctx, &ScTileElement::edges_get, &ScTileElement::edges_set, "edges"); + dukglue_register_property(ctx, &ScTileElement::corners_get, &ScTileElement::corners_set, "corners"); + dukglue_register_property( + ctx, &ScTileElement::slopeDirection_get, &ScTileElement::slopeDirection_set, "slopeDirection"); + dukglue_register_property(ctx, &ScTileElement::isQueue_get, &ScTileElement::isQueue_set, "isQueue"); + dukglue_register_property( + ctx, &ScTileElement::queueBannerDirection_get, &ScTileElement::queueBannerDirection_set, "queueBannerDirection"); + dukglue_register_property(ctx, &ScTileElement::queueBannerDirection_get, &ScTileElement::edges_set, "test"); + + dukglue_register_property( + ctx, &ScTileElement::isBlockedByVehicle_get, &ScTileElement::isBlockedByVehicle_set, "isBlockedByVehicle"); + dukglue_register_property(ctx, &ScTileElement::isWide_get, &ScTileElement::isWide_set, "isWide"); + + dukglue_register_property(ctx, &ScTileElement::addition_get, &ScTileElement::addition_set, "addition"); + dukglue_register_property( + ctx, &ScTileElement::additionStatus_get, &ScTileElement::additionStatus_set, "additionStatus"); + dukglue_register_property( + ctx, &ScTileElement::isAdditionBroken_get, &ScTileElement::isAdditionBroken_set, "isAdditionBroken"); + dukglue_register_property( + ctx, &ScTileElement::isAdditionGhost_get, &ScTileElement::isAdditionGhost_set, "isAdditionGhost"); + + // Track only + dukglue_register_property(ctx, &ScTileElement::trackType_get, &ScTileElement::trackType_set, "trackType"); + dukglue_register_property(ctx, &ScTileElement::mazeEntry_get, &ScTileElement::mazeEntry_set, "mazeEntry"); + dukglue_register_property(ctx, &ScTileElement::colourScheme_get, &ScTileElement::colourScheme_set, "colourScheme"); + dukglue_register_property(ctx, &ScTileElement::seatRotation_get, &ScTileElement::seatRotation_set, "seatRotation"); + dukglue_register_property( + ctx, &ScTileElement::brakeBoosterSpeed_get, &ScTileElement::brakeBoosterSpeed_set, "brakeBoosterSpeed"); + dukglue_register_property(ctx, &ScTileElement::hasChainLift_get, &ScTileElement::hasChainLift_set, "hasChainLift"); + dukglue_register_property(ctx, &ScTileElement::isInverted_get, &ScTileElement::isInverted_set, "isInverted"); + dukglue_register_property(ctx, &ScTileElement::hasCableLift_get, &ScTileElement::hasCableLift_set, "hasCableLift"); + + // Small Scenery only + dukglue_register_property(ctx, &ScTileElement::age_get, &ScTileElement::age_set, "age"); + dukglue_register_property(ctx, &ScTileElement::quadrant_get, &ScTileElement::quadrant_set, "quadrant"); + + // Wall only + dukglue_register_property( + ctx, &ScTileElement::tertiaryColour_get, &ScTileElement::tertiaryColour_set, "tertiaryColour"); + + // Entrance only + dukglue_register_property( + ctx, &ScTileElement::footpathObject_get, &ScTileElement::footpathObject_set, "footpathObject"); + } + +} // namespace OpenRCT2::Scripting + +#endif diff --git a/src/openrct2/scripting/bindings/world/ScTileElement.hpp b/src/openrct2/scripting/bindings/world/ScTileElement.hpp new file mode 100644 index 0000000000..9b0fcd7060 --- /dev/null +++ b/src/openrct2/scripting/bindings/world/ScTileElement.hpp @@ -0,0 +1,198 @@ +/***************************************************************************** + * Copyright (c) 2014-2021 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#pragma once + +#ifdef ENABLE_SCRIPTING + +# include "../../../Context.h" +# include "../../../common.h" +# include "../../../core/Guard.hpp" +# include "../../../ride/Track.h" +# include "../../../world/Footpath.h" +# include "../../../world/Scenery.h" +# include "../../../world/Sprite.h" +# include "../../../world/Surface.h" +# include "../../Duktape.hpp" +# include "../../ScriptEngine.h" + +# include +# include +# include + +namespace OpenRCT2::Scripting +{ + class ScTileElement + { + protected: + CoordsXY _coords; + TileElement* _element; + + public: + ScTileElement(const CoordsXY& coords, TileElement* element); + + private: + std::string type_get() const; + void type_set(std::string value); + + uint8_t baseHeight_get() const; + void baseHeight_set(uint8_t newBaseHeight); + + uint16_t baseZ_get() const; + void baseZ_set(uint16_t value); + + uint8_t clearanceHeight_get() const; + void clearanceHeight_set(uint8_t newClearanceHeight); + + uint16_t clearanceZ_get() const; + void clearanceZ_set(uint16_t value); + + DukValue slope_get() const; + void slope_set(uint8_t value); + + DukValue waterHeight_get() const; + void waterHeight_set(int32_t value); + + DukValue surfaceStyle_get() const; + void surfaceStyle_set(uint32_t value); + + DukValue edgeStyle_get() const; + void edgeStyle_set(uint32_t value); + + DukValue grassLength_get() const; + void grassLength_set(uint8_t value); + + DukValue hasOwnership_get() const; + + DukValue hasConstructionRights_get(); + + DukValue ownership_get() const; + void ownership_set(uint8_t value); + + DukValue parkFences_get() const; + void parkFences_set(uint8_t value); + + DukValue trackType_get() const; + void trackType_set(uint8_t value); + + DukValue sequence_get() const; + void sequence_set(uint8_t value); + + DukValue ride_get() const; + void ride_set(ride_id_t value); + + DukValue station_get() const; + void station_set(uint8_t value); + + DukValue hasChainLift_get() const; + void hasChainLift_set(bool value); + + DukValue mazeEntry_get() const; + void mazeEntry_set(uint16_t value); + + DukValue colourScheme_get() const; + void colourScheme_set(uint8_t value); + + DukValue seatRotation_get() const; + void seatRotation_set(uint8_t value); + + DukValue brakeBoosterSpeed_get() const; + void brakeBoosterSpeed_set(uint8_t value); + + DukValue isInverted_get() const; + void isInverted_set(bool value); + + DukValue hasCableLift_get() const; + void hasCableLift_set(bool value); + + DukValue object_get() const; + void object_set(uint32_t value); + + bool isHidden_get() const; + void isHidden_set(bool hide); + + DukValue age_get() const; + void age_set(uint8_t value); + + DukValue quadrant_get() const; + void quadrant_set(uint8_t value); + + uint8_t occupiedQuadrants_get() const; + void occupiedQuadrants_set(uint8_t value); + + bool isGhost_get() const; + void isGhost_set(bool value); + + DukValue primaryColour_get() const; + void primaryColour_set(uint8_t value); + + DukValue secondaryColour_get() const; + void secondaryColour_set(uint8_t value); + + DukValue tertiaryColour_get() const; + void tertiaryColour_set(uint8_t value); + + DukValue bannerIndex_get() const; + void bannerIndex_set(uint16_t value); + + // Deprecated in favor of seperate 'edges' and 'corners' properties, + // left here to maintain compatibility with older plugins. + /** @deprecated */ + uint8_t edgesAndCorners_get() const; + /** @deprecated */ + void edgesAndCorners_set(uint8_t value); + + DukValue edges_get() const; + void edges_set(uint8_t value); + + DukValue corners_get() const; + void corners_set(uint8_t value); + + DukValue slopeDirection_get() const; + void slopeDirection_set(const DukValue& value); + + DukValue isQueue_get() const; + void isQueue_set(bool value); + + DukValue queueBannerDirection_get() const; + void queueBannerDirection_set(const DukValue& value); + + DukValue isBlockedByVehicle_get() const; + void isBlockedByVehicle_set(bool value); + + DukValue isWide_get() const; + void isWide_set(bool value); + + DukValue addition_get() const; + void addition_set(const DukValue& value); + + DukValue additionStatus_get() const; + void additionStatus_set(uint8_t value); + + DukValue isAdditionBroken_get() const; + void isAdditionBroken_set(bool value); + + DukValue isAdditionGhost_get() const; + void isAdditionGhost_set(bool value); + + DukValue footpathObject_get() const; + void footpathObject_set(uint8_t value); + + DukValue direction_get() const; + void direction_set(uint8_t value); + + void Invalidate(); + + public: + static void Register(duk_context* ctx); + }; + +} // namespace OpenRCT2::Scripting + +#endif