 8541c87c97
			
		
	
	8541c87c97
	
	
	
		
			
			* Paint: Implement New Game * Add docstring * Remove unnecessary self.multiworld references * Implement start_inventory_from_pool * Convert logic to use LogicMixin * Add location_exists_with_options function to deduplicate code * Simplify starting tool creation * Add Paint to supported games list * Increment version to 0.4.1 * Update docs to include color selection features * Fix world attribute definitions * Fix linting errors * De-duplicate lists of traps * Move LogicMixin to __init__.py * 0.5.0 features - adjustable canvas size increment, updated similarity metric * Fix OptionError formatting * Create OptionError when generating single-player game with error-prone settings * Increment version to 0.5.1 * Update CODEOWNERS * Update documentation for 0.5.2 client changes * Simplify region creation * Add comments describing logic * Remove unnecessary f-strings * Remove unused import * Refactor rules to location class * Remove unnecessary self.multiworld references * Update logic to correctly match client-side item caps --------- Co-authored-by: Fabian Dill <Berserker66@users.noreply.github.com>
		
			
				
	
	
		
			41 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			41 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| from math import sqrt
 | |
| 
 | |
| from BaseClasses import CollectionState
 | |
| from . import PaintWorld
 | |
| 
 | |
| 
 | |
| def paint_percent_available(state: CollectionState, world: PaintWorld, player: int) -> bool:
 | |
|     if state.paint_percent_stale[player]:
 | |
|         state.paint_percent_available[player] = calculate_paint_percent_available(state, world, player)
 | |
|         state.paint_percent_stale[player] = False
 | |
|     return state.paint_percent_available[player]
 | |
| 
 | |
| 
 | |
| def calculate_paint_percent_available(state: CollectionState, world: PaintWorld, player: int) -> float:
 | |
|     p = state.has("Pick Color", player)
 | |
|     r = min(state.count("Progressive Color Depth (Red)", player), 7)
 | |
|     g = min(state.count("Progressive Color Depth (Green)", player), 7)
 | |
|     b = min(state.count("Progressive Color Depth (Blue)", player), 7)
 | |
|     if not p:
 | |
|         r = min(r, 2)
 | |
|         g = min(g, 2)
 | |
|         b = min(b, 2)
 | |
|     w = state.count("Progressive Canvas Width", player)
 | |
|     h = state.count("Progressive Canvas Height", player)
 | |
|     # This code looks a little messy but it's a mathematical formula derived from the similarity calculations in the
 | |
|     # client. The first line calculates the maximum score achievable for a single pixel with the current items in the
 | |
|     # worst possible case. This per-pixel score is then multiplied by the number of pixels currently available (the
 | |
|     # starting canvas is 400x300) over the total number of pixels with everything unlocked (800x600) to get the
 | |
|     # total score achievable assuming the worst possible target image. Finally, this is multiplied by the logic percent
 | |
|     # option which restricts the logic so as to not require pixel perfection.
 | |
|     return ((1 - ((sqrt(((2 ** (7 - r) - 1) ** 2 + (2 ** (7 - g) - 1) ** 2 + (2 ** (7 - b) - 1) ** 2) * 12)) / 765)) *
 | |
|             min(400 + w * world.options.canvas_size_increment, 800) *
 | |
|             min(300 + h * world.options.canvas_size_increment, 600) *
 | |
|             world.options.logic_percent / 480000)
 | |
| 
 | |
| 
 | |
| def set_completion_rules(world: PaintWorld, player: int) -> None:
 | |
|     world.multiworld.completion_condition[player] = \
 | |
|         lambda state: (paint_percent_available(state, world, player) >=
 | |
|                        min(world.options.logic_percent, world.options.goal_percent))
 |