forked from mirror/Archipelago
Merge branch 'main' into add_dark_souls_III
This commit is contained in:
@@ -1308,6 +1308,8 @@ class ClientMessageProcessor(CommonCommandProcessor):
|
||||
can_pay = 1000
|
||||
|
||||
self.ctx.random.shuffle(not_found_hints)
|
||||
# By popular vote, make hints prefer non-local placements
|
||||
not_found_hints.sort(key=lambda hint: int(hint.receiving_player != hint.finding_player))
|
||||
|
||||
hints = found_hints
|
||||
while can_pay > 0:
|
||||
|
||||
49
docs/style.md
Normal file
49
docs/style.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# Style Guide
|
||||
|
||||
## Generic
|
||||
|
||||
* This guide can be ignored for data files that are not to be viewed in an editor.
|
||||
* 120 character per line for all source files.
|
||||
* Avoid white space errors like trailing spaces.
|
||||
|
||||
|
||||
## Python Code
|
||||
|
||||
* We mostly follow [PEP8](https://peps.python.org/pep-0008/). Read below to see the differences.
|
||||
* 120 characters per line. PyCharm does this automatically, other editors can be configured for it.
|
||||
* Strings in core code will be `"strings"`. In other words: double quote your strings.
|
||||
* Strings in worlds should use double quotes as well, but imported code may differ.
|
||||
* Prefer [format string literals](https://peps.python.org/pep-0498/) over string concatenation,
|
||||
use single quotes inside them: `f"Like {dct['key']}"`
|
||||
* Use type annotation where possible.
|
||||
|
||||
|
||||
## Markdown
|
||||
|
||||
* We almost follow [Google's styleguide](https://google.github.io/styleguide/docguide/style.html).
|
||||
Read below for differences.
|
||||
* For existing documents, try to follow its style or ask to completely reformat it.
|
||||
* 120 characters per line.
|
||||
* One space between bullet/number and text.
|
||||
* No lazy numbering.
|
||||
|
||||
|
||||
## HTML
|
||||
|
||||
* Indent with 2 spaces for new code.
|
||||
* kebab-case for ids and classes.
|
||||
|
||||
|
||||
## CSS
|
||||
|
||||
* Indent with 2 spaces for new code.
|
||||
* `{` on the same line as the selector.
|
||||
* No space between selector and `{`.
|
||||
|
||||
|
||||
## JS
|
||||
|
||||
* Indent with 2 spaces.
|
||||
* Indent `case` inside `switch ` with 2 spaces.
|
||||
* Use single quotes.
|
||||
* Semicolons are required after every statement.
|
||||
@@ -236,7 +236,7 @@ class MyGameLocation(Location):
|
||||
game: str = "My Game"
|
||||
|
||||
# override constructor to automatically mark event locations as such
|
||||
def __init__(self, player: int, name = '', code = None, parent = None):
|
||||
def __init__(self, player: int, name = "", code = None, parent = None):
|
||||
super(MyGameLocation, self).__init__(player, name, code, parent)
|
||||
self.event = code is None
|
||||
```
|
||||
@@ -487,14 +487,14 @@ def create_items(self) -> None:
|
||||
for item in map(self.create_item, mygame_items):
|
||||
if item in exclude:
|
||||
exclude.remove(item) # this is destructive. create unique list above
|
||||
self.world.itempool.append(self.create_item('nothing'))
|
||||
self.world.itempool.append(self.create_item("nothing"))
|
||||
else:
|
||||
self.world.itempool.append(item)
|
||||
|
||||
# itempool and number of locations should match up.
|
||||
# If this is not the case we want to fill the itempool with junk.
|
||||
junk = 0 # calculate this based on player settings
|
||||
self.world.itempool += [self.create_item('nothing') for _ in range(junk)]
|
||||
self.world.itempool += [self.create_item("nothing") for _ in range(junk)]
|
||||
```
|
||||
|
||||
#### create_regions
|
||||
@@ -628,7 +628,7 @@ class MyGameLogic(LogicMixin):
|
||||
def _mygame_has_key(self, world: MultiWorld, player: int):
|
||||
# Arguments above are free to choose
|
||||
# it may make sense to use World as argument instead of MultiWorld
|
||||
return self.has('key', player) # or whatever
|
||||
return self.has("key", player) # or whatever
|
||||
```
|
||||
```python
|
||||
# __init__.py
|
||||
|
||||
@@ -1 +1 @@
|
||||
factorio-rcon-py>=1.2.1
|
||||
factorio-rcon-py==1.2.1
|
||||
|
||||
@@ -6,7 +6,7 @@ class TotalLocations(Range):
|
||||
"""Number of location checks which are added to the Risk of Rain playthrough."""
|
||||
display_name = "Total Locations"
|
||||
range_start = 10
|
||||
range_end = 500
|
||||
range_end = 250
|
||||
default = 20
|
||||
|
||||
|
||||
@@ -36,10 +36,14 @@ class AllowLunarItems(DefaultOnToggle):
|
||||
class StartWithRevive(DefaultOnToggle):
|
||||
"""Start the game with a `Dio's Best Friend` item."""
|
||||
display_name = "Start with a Revive"
|
||||
|
||||
class FinalStageDeath(DefaultOnToggle):
|
||||
"""Death on the final boss stage counts as a win."""
|
||||
display_name = "Final Stage Death is Win"
|
||||
|
||||
|
||||
class GreenScrap(Range):
|
||||
"""Weight of Green Scraps in the item pool."""
|
||||
"""Weight of Green Scraps in the item pool. (Ignored unless Item Weight Presets is 'No')"""
|
||||
display_name = "Green Scraps"
|
||||
range_start = 0
|
||||
range_end = 100
|
||||
@@ -47,7 +51,7 @@ class GreenScrap(Range):
|
||||
|
||||
|
||||
class RedScrap(Range):
|
||||
"""Weight of Red Scraps in the item pool."""
|
||||
"""Weight of Red Scraps in the item pool. (Ignored unless Item Weight Presets is 'No')"""
|
||||
display_name = "Red Scraps"
|
||||
range_start = 0
|
||||
range_end = 100
|
||||
@@ -55,7 +59,7 @@ class RedScrap(Range):
|
||||
|
||||
|
||||
class YellowScrap(Range):
|
||||
"""Weight of yellow scraps in the item pool."""
|
||||
"""Weight of yellow scraps in the item pool. (Ignored unless Item Weight Presets is 'No')"""
|
||||
display_name = "Yellow Scraps"
|
||||
range_start = 0
|
||||
range_end = 100
|
||||
@@ -63,7 +67,7 @@ class YellowScrap(Range):
|
||||
|
||||
|
||||
class WhiteScrap(Range):
|
||||
"""Weight of white scraps in the item pool."""
|
||||
"""Weight of white scraps in the item pool. (Ignored unless Item Weight Presets is 'No')"""
|
||||
display_name = "White Scraps"
|
||||
range_start = 0
|
||||
range_end = 100
|
||||
@@ -71,7 +75,7 @@ class WhiteScrap(Range):
|
||||
|
||||
|
||||
class CommonItem(Range):
|
||||
"""Weight of common items in the item pool."""
|
||||
"""Weight of common items in the item pool. (Ignored unless Item Weight Presets is 'No')"""
|
||||
display_name = "Common Items"
|
||||
range_start = 0
|
||||
range_end = 100
|
||||
@@ -79,7 +83,7 @@ class CommonItem(Range):
|
||||
|
||||
|
||||
class UncommonItem(Range):
|
||||
"""Weight of uncommon items in the item pool."""
|
||||
"""Weight of uncommon items in the item pool. (Ignored unless Item Weight Presets is 'No')"""
|
||||
display_name = "Uncommon Items"
|
||||
range_start = 0
|
||||
range_end = 100
|
||||
@@ -87,7 +91,7 @@ class UncommonItem(Range):
|
||||
|
||||
|
||||
class LegendaryItem(Range):
|
||||
"""Weight of legendary items in the item pool."""
|
||||
"""Weight of legendary items in the item pool. (Ignored unless Item Weight Presets is 'No')"""
|
||||
display_name = "Legendary Items"
|
||||
range_start = 0
|
||||
range_end = 100
|
||||
@@ -95,7 +99,7 @@ class LegendaryItem(Range):
|
||||
|
||||
|
||||
class BossItem(Range):
|
||||
"""Weight of boss items in the item pool."""
|
||||
"""Weight of boss items in the item pool. (Ignored unless Item Weight Presets is 'No')"""
|
||||
display_name = "Boss Items"
|
||||
range_start = 0
|
||||
range_end = 100
|
||||
@@ -103,7 +107,7 @@ class BossItem(Range):
|
||||
|
||||
|
||||
class LunarItem(Range):
|
||||
"""Weight of lunar items in the item pool."""
|
||||
"""Weight of lunar items in the item pool. (Ignored unless Item Weight Presets is 'No')"""
|
||||
display_name = "Lunar Items"
|
||||
range_start = 0
|
||||
range_end = 100
|
||||
@@ -111,7 +115,7 @@ class LunarItem(Range):
|
||||
|
||||
|
||||
class Equipment(Range):
|
||||
"""Weight of equipment items in the item pool."""
|
||||
"""Weight of equipment items in the item pool. (Ignored unless Item Weight Presets is 'No')"""
|
||||
display_name = "Equipment"
|
||||
range_start = 0
|
||||
range_end = 100
|
||||
@@ -122,15 +126,16 @@ class ItemPoolPresetToggle(DefaultOnToggle):
|
||||
"""Will use the item weight presets when set to true, otherwise will use the custom set item pool weights."""
|
||||
display_name = "Item Weight Presets"
|
||||
|
||||
|
||||
class ItemWeights(Choice):
|
||||
"""Preset choices for determining the weights of the item pool.<br>
|
||||
New is a test for a potential adjustment to the default weights.<br>
|
||||
Uncommon puts a large number of uncommon items in the pool.<br>
|
||||
Legendary puts a large number of legendary items in the pool.<br>
|
||||
Lunartic makes everything a lunar item.<br>
|
||||
Chaos generates the pool completely at random with rarer items having a slight cap to prevent this option being too easy.<br>
|
||||
No Scraps removes all scrap items from the item pool.<br>
|
||||
Even generates the item pool with every item having an even weight.<br>
|
||||
"""Preset choices for determining the weights of the item pool.
|
||||
New is a test for a potential adjustment to the default weights.
|
||||
Uncommon puts a large number of uncommon items in the pool.
|
||||
Legendary puts a large number of legendary items in the pool.
|
||||
Lunartic makes everything a lunar item.
|
||||
Chaos generates the pool completely at random with rarer items having a slight cap to prevent this option being too easy.
|
||||
No Scraps removes all scrap items from the item pool.
|
||||
Even generates the item pool with every item having an even weight.
|
||||
Scraps Only will be only scrap items in the item pool."""
|
||||
display_name = "Item Weights"
|
||||
option_default = 0
|
||||
@@ -143,7 +148,8 @@ class ItemWeights(Choice):
|
||||
option_even = 7
|
||||
option_scraps_only = 8
|
||||
|
||||
#define a dictionary for the weights of the generated item pool.
|
||||
|
||||
# define a dictionary for the weights of the generated item pool.
|
||||
ror2_weights: typing.Dict[str, type(Option)] = {
|
||||
"green_scrap": GreenScrap,
|
||||
"red_scrap": RedScrap,
|
||||
@@ -161,6 +167,7 @@ ror2_options: typing.Dict[str, type(Option)] = {
|
||||
"total_locations": TotalLocations,
|
||||
"total_revivals": TotalRevivals,
|
||||
"start_with_revive": StartWithRevive,
|
||||
"final_stage_death": FinalStageDeath,
|
||||
"item_pickup_step": ItemPickupStep,
|
||||
"enable_lunar": AllowLunarItems,
|
||||
"item_weights": ItemWeights,
|
||||
|
||||
@@ -110,15 +110,16 @@ class RiskOfRainWorld(World):
|
||||
"seed": "".join(self.world.slot_seeds[self.player].choice(string.digits) for i in range(16)),
|
||||
"totalLocations": self.world.total_locations[self.player].value,
|
||||
"totalRevivals": self.world.total_revivals[self.player].value,
|
||||
"startWithDio": self.world.start_with_revive[self.player].value
|
||||
"startWithDio": self.world.start_with_revive[self.player].value,
|
||||
"FinalStageDeath": self.world.final_stage_death[self.player].value
|
||||
}
|
||||
|
||||
def create_item(self, name: str) -> Item:
|
||||
item_id = item_table[name]
|
||||
item = RiskOfRainItem(name, ItemClassification.filler, item_id, self.player)
|
||||
if name == 'Dio\'s Best Friend':
|
||||
if name == "Dio's Best Friend":
|
||||
item.classification = ItemClassification.progression
|
||||
elif name == 'Equipment':
|
||||
elif name in {"Equipment", "Legendary Item"}:
|
||||
item.classification = ItemClassification.useful
|
||||
return item
|
||||
|
||||
|
||||
@@ -12,6 +12,32 @@ functionality in which certain chests (made clear via a location check progress
|
||||
multiworld. The items that _would have been_ in those chests will be returned to the Risk of Rain player via grants by
|
||||
other players in other worlds.
|
||||
|
||||
## What is the goal of Risk of Rain 2 in Archipelago?
|
||||
|
||||
Just like in the original game, any way to "beat the game or obliterate" counts as a win. By default, if you die while
|
||||
on a final boss stage, that also counts as a win. (You can turn this off in your player settings.) **You do not need to
|
||||
complete all the location checks** to win; any item you don't collect is automatically sent out to the multiworld when
|
||||
you meet your goal.
|
||||
|
||||
If you die before you accomplish your goal, you can start a new run. You will start the run with any items that you
|
||||
received from other players. Any items that you picked up the "normal" way will be lost.
|
||||
|
||||
Note, you can play Simulacrum mode as part of an Archipelago, but you can't achieve any of the victory conditions in
|
||||
Simulacrum. So you could, for example, collect most of your items through a Simulacrum run, then finish a normal mode
|
||||
run while keeping the items you received via the multiworld.
|
||||
|
||||
## Can you play multiplayer?
|
||||
|
||||
Yes! You can have a single multiplayer instance as one world in the multiworld. All the players involved need to have
|
||||
the Archipelago mod, but only the host needs to configure the Archipelago settings. When someone finds an item for your
|
||||
world, all the connected players will receive a copy of the item, and the location check bar will increase whenever any
|
||||
player finds an item in Risk of Rain.
|
||||
|
||||
You cannot have players with different player slots in the same co-op game instance. Only the host's Archipelago
|
||||
settings apply, so each Risk of Rain 2 player slot in the multiworld needs to be a separate game instance. You could,
|
||||
for example, have two players trade off hosting and making progress on each other's player slot, but a single co-op
|
||||
instance can't make progress towards multiple player slots in the multiworld.
|
||||
|
||||
## What Risk of Rain items can appear in other players' worlds?
|
||||
|
||||
The Risk of Rain items are:
|
||||
@@ -31,13 +57,34 @@ in-game item of that tier will appear in the Risk of Rain player's inventory. If
|
||||
the player already has an equipment item equipped then the _item that was equipped_ will be dropped on the ground and _
|
||||
the new equipment_ will take it's place. (If you want the old one back, pick it up.)
|
||||
|
||||
### How many items are there?
|
||||
|
||||
Since a Risk of Rain 2 run can go on indefinitely, you have to configure how many collectible items (also known as
|
||||
"checks") the game has for purposes of Archipelago when you set up a multiworld. You can configure anywhere from **10
|
||||
to 250** items. The number of items will be randomized between all players, so you may want to adjust the number and
|
||||
item pickup step based on how many items the other players in the multiworld have. (Around 100 seems to be a good
|
||||
ballpark if you want to have a similar number of items to most other games.)
|
||||
|
||||
After you have completed the specified number of checks, you won't send anything else to the multiworld. You can
|
||||
receive up to the specified number of randomized items from the multiworld as the players find them. In either case,
|
||||
you can continue to collect items as normal in Risk of Rain 2 if you've already found all your location checks.
|
||||
|
||||
## What does another world's item look like in Risk of Rain?
|
||||
|
||||
When the Risk of Rain player fills up their location check bar then the next spawned item will become an item grant for
|
||||
another player's world. The item in Risk of Rain will disappear in a poof of smoke and the grant will automatically go
|
||||
out to the multiworld.
|
||||
another player's world (or possibly get sent back to yourself). The item in Risk of Rain will disappear in a poof of
|
||||
smoke and the grant will automatically go out to the multiworld.
|
||||
|
||||
## What is the item pickup step?
|
||||
|
||||
The item pickup step is a YAML setting which allows you to set how many items you need to spawn before the _next_ item
|
||||
that is spawned disappears (in a poof of smoke) and goes out to the multiworld.
|
||||
|
||||
## Is Archipelago compatible with other Risk of Rain 2 mods?
|
||||
|
||||
Mostly, yes. Not every mod will work; in particular, anything that causes items to go directly into your inventory
|
||||
rather than spawning onto the map will interfere with the way the Archipelago mod works. However, many common mods work
|
||||
just fine with Archipelago.
|
||||
|
||||
For competitive play, of course, you should only use mods that are agreed-upon by the competitors so that you don't
|
||||
have an unfair advantage.
|
||||
|
||||
Reference in New Issue
Block a user