Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make Multiplayer intentional instead of a hackjob. Also fix bugs. #114

Merged
merged 8 commits into from
Apr 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 30 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Your troubles are long gone with ***Ride Price Manager***!

## Using the Plugin
- First, follow the installation instructions below
- Once installed, the plugin should work automatically in game. It will _automagically_ update the prices of all your rides.
- Once installed, the plugin should work automatically in game. It will _automagically_ update the prices of all your rides every in-game day.
- By default, the plugin chooses the highest price that guests are willing to pay for a ride.
- That number is determined by ride rating, ride age, and other factors.
- You can configure the plugin via the "Ride Price Manager" _control panel_, which is available **under the Map Dropdown** on the top bar. There, you can:
Expand All @@ -18,6 +18,9 @@ Your troubles are long gone with ***Ride Price Manager***!
- add a "Lazy Tax" to decrease ride prices. This is for people that think this plugin is overpowered or just want to re-balance the game a little bit.
- allow prices greater than $20.00 for high value rides.
- Guests are willing to pay more than $20 for some rides, but you can't set a price to more than $20 via the UI. This allows the plugin to bypass that check.
- There are also two buttons in the _control panel_:
- "Make ALL Rides FREE" which does just that. This may be useful in conjunction with the "Ignore free rides" option.
- "Force Recalculate ALL Prices Now" also does what it says on the tin. Note that it doesn't use the "Ignore free rides" option, and recalculates free rides.

## Installation
1. Install a compatible version of OpenRCT2 (requires [`0.3.0-develop-bc33ef3`](https://openrct2.org/downloads/develop/v0.3.0-bc33ef3) released 2020/09/03 or [newer](https://openrct2.org/downloads/develop/latest))
Expand All @@ -29,9 +32,30 @@ Your troubles are long gone with ***Ride Price Manager***!
4. Run OpenRCT2!
5. Once in a scenario, open the options window via the Map dropdown to configure the plugin.

## Multiplayer
This plugin is now updated to work in Multiplayer! However, there are some things to know...

- The plugin must be installed on the server to automatically update prices every in-game day.
- When the prices are updated daily, only the config on the server is used.
- Any player with the plugin can still use the "Force recalculate" and "Make rides free" buttons. There are no permissions. File an issue if you are dealing with griefers.
- For the recalculate button, the client's config is used, but will be bulldozed when server recalculates prices on the next in-game day.

To set the server config, you will need to edit the `plugin.store.json` file (typically in `C:\Users\{User}\Documents\OpenRCT2`). If that file doesn't exist, use the following as the file contents. If some keys already exist, just add the `RidePriceManager` block to what's already there. And don't mess up the commas!

```
{
"RidePriceManager": {
"pluginEnabled": true,
"ignoreFreeRidesEnabled": true,
"goodValueEnabled": false,
"lazyTaxFactor": 0,
"unboundPriceEnabled": false
}
}
```

## Possible Future Plans
- Check if this works with server play
- And make it work with server play
- Have better tools for managing the price of transport rides.
- Automatically set park prices & allow configuration of a max admission price.
- This would help early-game ramp-up.
- Manage shop prices
Expand All @@ -52,14 +76,15 @@ If you want to request a feature or find a bug, open an issue on GitHub (as long
- Run a Command Prompt as Administrator
- `cd` to the repository
- `mklink .\lib\openrct2.d.ts "C:\Program Files\OpenRCT2\openrct2.d.ts"`
- Edit `ride-price-manager\rollup.config.dev.js` so that it puts the build in your plugin folder.
- Edit `ride-price-manager\rollup.config.dev.js` so that it puts the build in your plugin folder. Sorry that this is custom to me :O
- Run `npm run watch`
- Make your changes.
- Make sure to update the version number in `package.json` and in `index.js`.
- Commit your changes (without including the rollup config) and Make a Pull Request.

## Thanks
- Thanks to [OpenRCT2](https://github.com/OpenRCT2/OpenRCT2) for revitalizing a sweet game & releasing the plugin API.
- Thanks to **oli414** for the [boilerplate template](https://github.com/oli414/openrct2-plugin-boilerplate). I adapted it to fit TypeScript for this project initally, before **wisnia74** came out with [a very well made and comprehensive TypeScript plugin template](https://github.com/wisnia74/openrct2-typescript-mod-template), which I now use for this plugin. You should definitely use that one if you want to make your own plugin.
- This plugin is powered by **wisnia74**'s [very well made and comprehensive TypeScript plugin template](https://github.com/wisnia74/openrct2-typescript-mod-template). I highly recommend you use that one if you want to make your own plugin. So thank you, wisnia!
- Originally, this plugin was powered by **oli414**'s [boilerplate template](https://github.com/oli414/openrct2-plugin-boilerplate) (which I adapted to support TypeScript, but it still wasn't as nice as the new plugin template). Thanks oli for helping me get the ball rolling :)
- Thanks to [Marcel Vos](https://www.youtube.com/channel/UCBlXovStrlQkVA2xJEROUNg) for getting me back into RCT2.
- And many many thanks to [IntelOrca](https://github.com/IntelOrca) for all of the Plugin support. The Plugin API is super fun, and I can't wait to see what all people make for it.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ride-price-manager",
"version": "1.3.0",
"version": "1.3.1",
"description": "Ride Price Manager is a plugin for OpenRCT2 that automagically updates the prices of all your rides",
"main": "app.js",
"scripts": {
Expand Down
84 changes: 84 additions & 0 deletions src/RidePrices.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/// <reference path="../lib/openrct2.d.ts" />

import config from './config';

export default class RidePrices {
public static updateRidePrices(): void {
if (!config.getPluginEnabled()) {
return;
}
map.rides.map((ride: Ride) => { // eslint-disable-line array-callback-return
if (ride.price[0] === 0 && config.getIgnoreFreeRidesEnabled()) {
// Ignore free rides.
return;
}
RidePrices.setRidePrice(ride);
});
}

public static forceUpdateRidePrices(): void {
map.rides.map((ride: Ride) => RidePrices.setRidePrice(ride));
}

public static makeRidesFree(): void {
map.rides.map((ride: Ride) => RidePrices.setRidePrice(ride, 0));
}

private static setRidePrice(ride: Ride, priceInDimes?: number): void {
if (!RidePrices.isOpenAndRatedRide(ride)) {
return;
}

if (priceInDimes === undefined) {
priceInDimes = RidePrices.calculateRidePrice(ride);
}

// Set the price via an action (so it works in multiplayer)
context.executeAction(
'ridesetprice',
{
ride: ride.id,
price: priceInDimes,
isPrimaryPrice: true,
},
() => { },
);
}

private static isOpenAndRatedRide(ride: Ride): boolean {
// Ignore shops & facilites.
return ride.classification === 'ride'
// Ignore closed/testing rides.
&& ride.status === 'open'
// Ignore unrated rides.
&& ride.excitement !== -1;
}

private static calculateRidePrice(ride: Ride): number {
// See /src/openrct2/peep/Guest.cpp for logic.
// if (peep_flags & PEEP_FLAGS_HAS_PAID_FOR_PARK_ENTRY) value /= 4;
const value = park.entranceFee > 0 && !park.getFlag('freeParkEntry')
? Math.floor(ride.value / 4)
: ride.value;

// See /src/openrct2/peep/Guest.cpp for logic.
// if (ridePrice > value * 2) ChoseNotToGoOnRide
// if (ridePrice <= value / 2) InsertNewThought(PEEP_THOUGHT_TYPE_GOOD_VALUE)
let priceInDimes = config.getGoodValueEnabled()
? Math.floor(value / 2)
: value * 2;

if (config.getLazyTaxFactor() > 0) {
priceInDimes *= (1 - config.getLazyTaxFactor());
priceInDimes = Math.floor(priceInDimes);
}

if (!config.getUnboundPriceEnabled()) {
// Max price is $20 via the UI.
priceInDimes = Math.min(priceInDimes, 200);
}

return priceInDimes;
}
};

22 changes: 14 additions & 8 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
/// <reference path="../lib/openrct2.d.ts" />

import { updateRidePrices } from './ridePriceFunctions';
import RidePrices from './RidePrices';
import showWindow from './window';

function main(): void {
ui.registerMenuItem('Ride Price Manager', () => {
showWindow();
});
// Headless server homies don't need to register UI, you feel me?
if (ui) {
ui.registerMenuItem('Ride Price Manager', () => {
showWindow();
});
}

context.subscribe('interval.day', () => {
updateRidePrices();
});
// Only the server/singleplayer automatically triggers prices updates.
if (network.mode !== 'client') {
context.subscribe('interval.day', () => {
RidePrices.updateRidePrices();
});

updateRidePrices();
RidePrices.updateRidePrices();
}
}

export default main;
2 changes: 1 addition & 1 deletion src/registerPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import main from './main';

registerPlugin({
name: 'Ride Price Manager',
version: '1.3.0',
version: '1.3.1',
authors: ['mgovea', 'Sadret'],
type: 'remote',
licence: 'MIT',
Expand Down
82 changes: 0 additions & 82 deletions src/ridePriceFunctions.ts

This file was deleted.

6 changes: 3 additions & 3 deletions src/window.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/// <reference path="../lib/openrct2.d.ts" />

import config, { LazyTaxOption, lazyTaxOptions } from './config'; // eslint-disable-line no-unused-vars
import { forceUpdateRidePrices, makeRidesFree } from './ridePriceFunctions';
import RidePrices from './RidePrices';

const windowTag = 'ride_management';
const lQuote = decodeURI('%E2%80%9C');
Expand Down Expand Up @@ -157,7 +157,7 @@ function makeRecalculateButton(y: number): ButtonWidget {
y,
'Immediately set the price for all rides, overriding the "Ignore Free" preference',
'Force Recalculate ALL Prices Now',
forceUpdateRidePrices,
RidePrices.forceUpdateRidePrices,
);
}

Expand All @@ -166,7 +166,7 @@ function makeAllRidesFreeButton(y: number): ButtonWidget {
y,
'Immediately make all rides free.',
'Make ALL Rides FREE',
makeRidesFree,
RidePrices.makeRidesFree,
);
}

Expand Down