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

Feature: Random stock for outfitters and shipyards #10676

Open
wants to merge 53 commits into
base: master
Choose a base branch
from

Conversation

TheGiraffe3
Copy link
Contributor

@TheGiraffe3 TheGiraffe3 commented Oct 23, 2024

Feature

This PR addresses the features described in issue #5590 Used/stolen ships so capping isn't nigh-mandatory

Summary

You can now specify that individual outfits and ships can randomly be in stock on planets. This is handled through the existing system for things being in stock, which has been extended to also cover ships.

The new information is handled through shipyard stock and outfitter stock entries in the game data. If this PR is merged, the follow-up work is create content for it.

This is a re-PR of #10265.
Thanks to @TomGoodIdea for helping with this.

Screenshots

screenshot
Composite screenshot of a variant ship in stock from the example plugin.

Usage examples

Example data adding a 50% chance of heavily discounted nukes and a 50% chance of heavily discounted Palavrets to New Boston. Note that this is a quick, intentionally silly example that is easy to test. The actual use for this feature is to have the occasional chance of variant ships and rare outfits.

ship "Palavret" "Recovered Palavret"
	outfits
		"nGVF-AA Fuel Cell"
		"LP036a Battery Pack"		
		"X2700 Ion Thruster"
		"X2200 Ion Steering"
		"Hyperdrive"
	description `There appears to be a massive alien warship on sale for cheap.`
	description `	A shifty individual, who identifies himself as "Dash Riprock", explains: "It's one of them alien raiders, innit? Found it floatin' in space full of dead lizards. Cleaned it out, fixed it up, and now it can be yours. For a special price."`

"outfitter stock" "Random Nukes"
	"Nuclear Missile"
		probability 50
		quantity 3
		depreciation 100

"shipyard stock" "Random Palavrets"
	"Recovered Palavret"
		probability 50
		discount 70

planet "New Boston"
	add "outfitter stock" "Random Nukes"
	add "shipyard stock" "Random Palavrets"

Note that you can specify the depreciation of items in stock using depreciation, which uses the number of days the items are old, or discount, which uses a target percentage discount.

Testing Done

  • Code style checks pass
  • Integration checks pass
  • In-stock ships and outfits are generated on landing
  • Stock is cleared when departing
  • Can buy in-stock ships and outfits
  • Can still buy and sell ships and outfits normally
  • If a ship would be in stock but is also just available normally, the normal availability overrides it being in stock
  • Save/load persists in-stock and depreciation values
  • Ship and outfit stocks can be attached to and removed from planets using events
  • Ship and outfit stocks can be modified using events
  • Can specify depreciation both as a value of days with depreciation and a value of percentage with discount.

Test Mod

Packaged up mod of the usage example above, plus events that modify stocks. You can test the changes by starting a new run and going into the New Boston shipyard and outfitter:
random-nukes-and-palavrets-4.zip

Wiki Update

endless-sky/endless-sky-wiki#24

Performance Impact

Should be minimal, as the new stock data is simple, and only evaluated when you land.

Zarkonnen and others added 17 commits June 23, 2024 17:06
…ly be in stock when you go into the outfitter or shipyard.
Whitespace fixes that the python static code analysis doesn't catch.

Co-authored-by: Loymdayddaud <[email protected]>
Code cleanup.

Co-authored-by: TomGoodIdea <[email protected]>
…itter stock'. Moved stock probability from being after the item name to its own child named 'probability'.
… Amount of depreciation for stock can be given in days of depreciation or in target percentage discount.
@TomGoodIdea TomGoodIdea added enhancement Issues asking for or PRs making code changes that add new capabilities to the engine mechanics Issues and PRs about changing how the game works labels Oct 23, 2024
source/OutfitterPanel.cpp Outdated Show resolved Hide resolved
source/Planet.h Outdated Show resolved Hide resolved
source/PlayerInfo.cpp Outdated Show resolved Hide resolved
source/PlayerInfo.cpp Outdated Show resolved Hide resolved
source/RandomStock.h Outdated Show resolved Hide resolved
source/RandomStock.h Outdated Show resolved Hide resolved
@TheGiraffe3
Copy link
Contributor Author

Sorry for the mess of commits.

@TheGiraffe3 TheGiraffe3 requested a review from Hurleveur October 30, 2024 17:35
Copy link
Member

@tibetiroka tibetiroka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probability 50

This PR introduces a new probability keyword. It seems to function the same as the existing random; probability 50 is the same as random < 50.

If we use conditions for checking whether the item should show up in the outfitter, we can reproduce the functionality of probability with the established random syntax, and we can customize the availability to a much greater extent, such as locking it behind a mission's completion, or increasing the chance while a mission is active.

For that end, something like a to stock node (not sure about the name) could replace the probability node like this:

"outfitter stock" "Random Nukes"
	"Nuclear Missile"
		"to stock" random < 50

And it could support multiple conditions, as usual:

"outfitter stock" "Random Nukes"
	"Nuclear Missile"
		"to stock"
			random < 50
			has "main story completed"

I see that you are adding the random outfits to specific planets. We could take the above approach a step further, and add the random stock to the shipyard itself, instead of to the planet.

"outfitter stock" "Syndicate Advanced"
	"Nuclear Missile"
		"to stock"
			random < 50
			has "main story completed"
		"stock on"
			near Almach 1 3

For better reusability, maybe it could accept more than one outfitter name in its definition. I do see an issue with plugins not being able to modify this list of outfitters the stock is added to, though.

These options cover a somewhat different use case for this feature. It should be able to replicate any behaviour from the current version, but might be more cumbersome in some cases, as a per-planet setup would require an extra shipyard or outfit stock definition. I would love to hear how people want to use this feature - customized per-planet random stocks, or blanket setups that can be easily applied to larger areas and toggled without needing to mess with custom events.

Some use cases I can think of for this syntax:

  • Adding random Korath outfits as stock to Remnant planets
  • Adding cheap medium warships to FW planets for a period after the war is over
  • Adding random stock to pirate planets based on region (south pirates all get the same outfits, but different ones than the northern ones)

These are all possible using any version of the syntax, but I think they would be easier with the suggested changes.

return 0;

// Unfortunately, solving the depreciation function for age gives a horrible formula involving
// the Lambert W function. So instead, just increase age by 1 until the depreciation is right.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The normal max is reached after one year, but you can make the price go lower past the max in the code if you want.

Why? We don't want to be selling random stock for too cheap lest it becomes overpowered.

Even the 25% cost that is the current limit, you can get some amazing (perhaps too amazing) deals. I don't see why we would want them to be even cheaper. (And if they do get cheaper, can you sell them for under 25% of the price? Some other code might cap the value back to that preset limit.)

Precalculating the costs for this range shouldn't be too difficult. It might even be doable in compile-time, assuming the depreciation gamerules don't mess that up.

(At the very least, we could make use of the fact that depreciation only ever decreases the value, so we could search through it in logarithmic time - which, in this case, is a substantial difference, as this is an expensive operation.)

source/Depreciation.h Show resolved Hide resolved
else if(grandToken == "depreciation")
rs.depreciation = grand.Value(1);
else if(grandToken == "discount")
rs.depreciation = Depreciation::AgeForDepreciation(1 - grand.Value(1) / 100.0);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I unresolved this conversation, as it is not addressed yet. There should be warning when multiple conflicting options are defined, such as "depreciation" and "discount".

Though I'm not sure about the entire "discount" option, to be honest. Especially about how it behaves when people set their "depreciation daily" and "depreciation min" gamerules to 1., as that would never actually reach a depreciated value lower than the original cost. I have a feeling that would cause the game to hang.

source/Depreciation.cpp Outdated Show resolved Hide resolved
@TheGiraffe3
Copy link
Contributor Author

I see that you are adding the random outfits to specific planets. We could take the above approach a step further, and add the random stock to the shipyard itself, instead of to the planet.

One side about doing this is it changes it for all outfitters.
But if I say I want the Syndicate Advanced outfitter on Polaris to sometimes sell looted Korath technology (which isn't unfeasible), that will also have the Syndicate selling the technology on Hephaestus, which is a study location where it makes no sense to be sold at.

These options cover a somewhat different use case for this feature. It should be able to replicate any behaviour from the current version, but might be more cumbersome in some cases, as a per-planet setup would require an extra shipyard or outfit stock definition. I would love to hear how people want to use this feature - customized per-planet random stocks, or blanket setups that can be easily applied to larger areas and toggled without needing to mess with custom events.

So I think per-planet would be more useful, even if it leads to needing to define a few more lines.

@TomGoodIdea TomGoodIdea added the waiting on OP The OP needs to provide something, e.g, making requested changes, posting assets, etc. label Dec 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Issues asking for or PRs making code changes that add new capabilities to the engine mechanics Issues and PRs about changing how the game works waiting on OP The OP needs to provide something, e.g, making requested changes, posting assets, etc.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants