Implement production vertical slice foundation
This commit is contained in:
1 parent
9d4a89f355
commit
a18e82eb44
104 files changed
+10595
-268
No files matched your search
@@ -0,0 +1,27 @@
|
||||
class_name DiveAccessibilityAdjustments
|
||||
extends RefCounted
|
||||
|
||||
var oxygen_consumption_multiplier: float
|
||||
var battery_consumption_multiplier: float
|
||||
var pressure_damage_multiplier: float
|
||||
|
||||
|
||||
func _init(
|
||||
p_oxygen_consumption_multiplier: float = 1.0,
|
||||
p_battery_consumption_multiplier: float = 1.0,
|
||||
p_pressure_damage_multiplier: float = 1.0
|
||||
) -> void:
|
||||
oxygen_consumption_multiplier = p_oxygen_consumption_multiplier
|
||||
battery_consumption_multiplier = p_battery_consumption_multiplier
|
||||
pressure_damage_multiplier = p_pressure_damage_multiplier
|
||||
|
||||
|
||||
func validation_error() -> String:
|
||||
for multiplier: float in [
|
||||
oxygen_consumption_multiplier,
|
||||
battery_consumption_multiplier,
|
||||
pressure_damage_multiplier,
|
||||
]:
|
||||
if not is_finite(multiplier) or multiplier <= 0.0:
|
||||
return "accessibility multipliers must be finite and positive"
|
||||
return ""
|
||||
@@ -0,0 +1,52 @@
|
||||
class_name DiveDifficultyProfile
|
||||
extends RefCounted
|
||||
|
||||
var profile_id: StringName
|
||||
var oxygen_consumption_multiplier: float
|
||||
var battery_consumption_multiplier: float
|
||||
var collision_damage_multiplier: float
|
||||
var pressure_damage_multiplier: float
|
||||
var crush_grace_multiplier: float
|
||||
|
||||
|
||||
func _init(
|
||||
p_profile_id: StringName,
|
||||
p_oxygen_consumption_multiplier: float,
|
||||
p_battery_consumption_multiplier: float,
|
||||
p_collision_damage_multiplier: float,
|
||||
p_pressure_damage_multiplier: float,
|
||||
p_crush_grace_multiplier: float
|
||||
) -> void:
|
||||
profile_id = p_profile_id
|
||||
oxygen_consumption_multiplier = p_oxygen_consumption_multiplier
|
||||
battery_consumption_multiplier = p_battery_consumption_multiplier
|
||||
collision_damage_multiplier = p_collision_damage_multiplier
|
||||
pressure_damage_multiplier = p_pressure_damage_multiplier
|
||||
crush_grace_multiplier = p_crush_grace_multiplier
|
||||
|
||||
|
||||
static func exploration():
|
||||
return new(&"exploration", 0.75, 0.80, 0.65, 0.50, 1.50)
|
||||
|
||||
|
||||
static func standard():
|
||||
return new(&"standard", 1.0, 1.0, 1.0, 1.0, 1.0)
|
||||
|
||||
|
||||
static func expert():
|
||||
return new(&"expert", 1.20, 1.15, 1.25, 1.35, 0.75)
|
||||
|
||||
|
||||
func validation_error() -> String:
|
||||
if profile_id.is_empty():
|
||||
return "difficulty profile_id is empty"
|
||||
for value: float in [
|
||||
oxygen_consumption_multiplier,
|
||||
battery_consumption_multiplier,
|
||||
collision_damage_multiplier,
|
||||
pressure_damage_multiplier,
|
||||
crush_grace_multiplier,
|
||||
]:
|
||||
if not is_finite(value) or value <= 0.0:
|
||||
return "difficulty multipliers must be finite and positive"
|
||||
return ""
|
||||
@@ -0,0 +1,99 @@
|
||||
class_name DiveRulesResolver
|
||||
extends RefCounted
|
||||
|
||||
const DiveDifficultyProfile = preload("res://game/domain/rules/dive_difficulty_profile.gd")
|
||||
const DiveUpgradeEffects = preload("res://game/domain/rules/dive_upgrade_effects.gd")
|
||||
const DiveAccessibilityAdjustments = preload(
|
||||
"res://game/domain/rules/dive_accessibility_adjustments.gd"
|
||||
)
|
||||
const ResolvedDiveRules = preload("res://game/domain/rules/resolved_dive_rules.gd")
|
||||
|
||||
const BASE_BATTERY_CAPACITY_KWH := 100.0
|
||||
const BASE_OXYGEN_CAPACITY_L := 480.0
|
||||
const BASE_OXYGEN_CONSUMPTION_L_PER_MIN := 30.0
|
||||
const BASE_HULL_INTEGRITY := 100.0
|
||||
const BASE_CERTIFIED_DEPTH_M := 60.0
|
||||
|
||||
const BASE_LONGITUDINAL_POWER_KW := 1800.0
|
||||
const BASE_STEERING_POWER_KW := 180.0
|
||||
const BASE_VERTICAL_POWER_KW := 360.0
|
||||
const BASE_HIGH_THRUST_POWER_KW := 900.0
|
||||
const BASE_RETURN_ENERGY_KWH_PER_M := 100.0 / 1200.0
|
||||
const BASE_ASCENT_ENERGY_KWH_PER_M := 0.035
|
||||
|
||||
|
||||
func resolve(
|
||||
difficulty: DiveDifficultyProfile,
|
||||
upgrades: DiveUpgradeEffects = null,
|
||||
accessibility: DiveAccessibilityAdjustments = null
|
||||
) -> ResolvedDiveRules:
|
||||
var resolved_upgrades: DiveUpgradeEffects = (
|
||||
upgrades if upgrades != null else DiveUpgradeEffects.new()
|
||||
)
|
||||
var resolved_accessibility: DiveAccessibilityAdjustments = (
|
||||
accessibility if accessibility != null else DiveAccessibilityAdjustments.new()
|
||||
)
|
||||
if difficulty == null:
|
||||
return null
|
||||
if not difficulty.validation_error().is_empty():
|
||||
return null
|
||||
if not resolved_upgrades.validation_error().is_empty():
|
||||
return null
|
||||
if not resolved_accessibility.validation_error().is_empty():
|
||||
return null
|
||||
|
||||
# Base values, then submarine upgrades, difficulty and gameplay accessibility.
|
||||
var battery_capacity: float = (
|
||||
BASE_BATTERY_CAPACITY_KWH + resolved_upgrades.battery_capacity_bonus_kwh
|
||||
)
|
||||
var oxygen_capacity: float = (
|
||||
BASE_OXYGEN_CAPACITY_L + resolved_upgrades.oxygen_capacity_bonus_l
|
||||
)
|
||||
var hull_integrity: float = BASE_HULL_INTEGRITY + resolved_upgrades.hull_integrity_bonus
|
||||
var certified_depth: float = (
|
||||
BASE_CERTIFIED_DEPTH_M + resolved_upgrades.certified_depth_bonus_m
|
||||
)
|
||||
|
||||
var battery_multiplier: float = (
|
||||
resolved_upgrades.battery_consumption_multiplier
|
||||
* difficulty.battery_consumption_multiplier
|
||||
* resolved_accessibility.battery_consumption_multiplier
|
||||
)
|
||||
var oxygen_multiplier: float = (
|
||||
difficulty.oxygen_consumption_multiplier
|
||||
* resolved_accessibility.oxygen_consumption_multiplier
|
||||
)
|
||||
var pressure_multiplier: float = (
|
||||
resolved_upgrades.pressure_damage_multiplier
|
||||
* difficulty.pressure_damage_multiplier
|
||||
* resolved_accessibility.pressure_damage_multiplier
|
||||
)
|
||||
var collision_multiplier: float = (
|
||||
resolved_upgrades.collision_damage_multiplier
|
||||
* difficulty.collision_damage_multiplier
|
||||
)
|
||||
|
||||
var result: ResolvedDiveRules = ResolvedDiveRules.new(
|
||||
battery_capacity,
|
||||
oxygen_capacity,
|
||||
BASE_OXYGEN_CONSUMPTION_L_PER_MIN * oxygen_multiplier,
|
||||
hull_integrity,
|
||||
certified_depth,
|
||||
BASE_LONGITUDINAL_POWER_KW * battery_multiplier,
|
||||
BASE_STEERING_POWER_KW * battery_multiplier,
|
||||
BASE_VERTICAL_POWER_KW * battery_multiplier,
|
||||
BASE_HIGH_THRUST_POWER_KW * battery_multiplier,
|
||||
BASE_RETURN_ENERGY_KWH_PER_M * battery_multiplier,
|
||||
BASE_ASCENT_ENERGY_KWH_PER_M * battery_multiplier,
|
||||
pressure_multiplier,
|
||||
collision_multiplier,
|
||||
3.5,
|
||||
4.0,
|
||||
0.45,
|
||||
1.5 * difficulty.crush_grace_multiplier,
|
||||
0.30,
|
||||
0.15,
|
||||
0.05,
|
||||
3.0
|
||||
)
|
||||
return result if result.validation_error().is_empty() else null
|
||||
@@ -0,0 +1,47 @@
|
||||
class_name DiveUpgradeEffects
|
||||
extends RefCounted
|
||||
|
||||
var battery_capacity_bonus_kwh: float
|
||||
var oxygen_capacity_bonus_l: float
|
||||
var hull_integrity_bonus: float
|
||||
var certified_depth_bonus_m: float
|
||||
var battery_consumption_multiplier: float
|
||||
var collision_damage_multiplier: float
|
||||
var pressure_damage_multiplier: float
|
||||
|
||||
|
||||
func _init(
|
||||
p_battery_capacity_bonus_kwh: float = 0.0,
|
||||
p_oxygen_capacity_bonus_l: float = 0.0,
|
||||
p_hull_integrity_bonus: float = 0.0,
|
||||
p_certified_depth_bonus_m: float = 0.0,
|
||||
p_battery_consumption_multiplier: float = 1.0,
|
||||
p_collision_damage_multiplier: float = 1.0,
|
||||
p_pressure_damage_multiplier: float = 1.0
|
||||
) -> void:
|
||||
battery_capacity_bonus_kwh = p_battery_capacity_bonus_kwh
|
||||
oxygen_capacity_bonus_l = p_oxygen_capacity_bonus_l
|
||||
hull_integrity_bonus = p_hull_integrity_bonus
|
||||
certified_depth_bonus_m = p_certified_depth_bonus_m
|
||||
battery_consumption_multiplier = p_battery_consumption_multiplier
|
||||
collision_damage_multiplier = p_collision_damage_multiplier
|
||||
pressure_damage_multiplier = p_pressure_damage_multiplier
|
||||
|
||||
|
||||
func validation_error() -> String:
|
||||
for bonus: float in [
|
||||
battery_capacity_bonus_kwh,
|
||||
oxygen_capacity_bonus_l,
|
||||
hull_integrity_bonus,
|
||||
certified_depth_bonus_m,
|
||||
]:
|
||||
if not is_finite(bonus) or bonus < 0.0:
|
||||
return "upgrade bonuses must be finite and non-negative"
|
||||
for multiplier: float in [
|
||||
battery_consumption_multiplier,
|
||||
collision_damage_multiplier,
|
||||
pressure_damage_multiplier,
|
||||
]:
|
||||
if not is_finite(multiplier) or multiplier <= 0.0:
|
||||
return "upgrade multipliers must be finite and positive"
|
||||
return ""
|
||||
@@ -0,0 +1,125 @@
|
||||
class_name ResolvedDiveRules
|
||||
extends RefCounted
|
||||
|
||||
var battery_capacity_kwh: float
|
||||
var oxygen_capacity_l: float
|
||||
var oxygen_consumption_l_per_min: float
|
||||
var hull_max_integrity: float
|
||||
|
||||
var certified_depth_m: float
|
||||
var critical_depth_m: float
|
||||
var crush_depth_m: float
|
||||
var certified_pressure_bar: float
|
||||
var critical_pressure_bar: float
|
||||
var crush_pressure_bar: float
|
||||
|
||||
var longitudinal_power_kw: float
|
||||
var steering_power_kw: float
|
||||
var vertical_power_kw: float
|
||||
var high_thrust_power_kw: float
|
||||
var return_energy_kwh_per_m: float
|
||||
var ascent_energy_kwh_per_m: float
|
||||
|
||||
var pressure_damage_multiplier: float
|
||||
var collision_damage_multiplier: float
|
||||
var collision_speed_threshold_mps: float
|
||||
var collision_damage_per_excess_mps: float
|
||||
var collision_repeat_delay_seconds: float
|
||||
var crush_grace_seconds: float
|
||||
|
||||
var attention_ratio: float
|
||||
var return_ratio: float
|
||||
var critical_ratio: float
|
||||
var ejection_hold_seconds: float
|
||||
|
||||
|
||||
func _init(
|
||||
p_battery_capacity_kwh: float,
|
||||
p_oxygen_capacity_l: float,
|
||||
p_oxygen_consumption_l_per_min: float,
|
||||
p_hull_max_integrity: float,
|
||||
p_certified_depth_m: float,
|
||||
p_longitudinal_power_kw: float,
|
||||
p_steering_power_kw: float,
|
||||
p_vertical_power_kw: float,
|
||||
p_high_thrust_power_kw: float,
|
||||
p_return_energy_kwh_per_m: float,
|
||||
p_ascent_energy_kwh_per_m: float,
|
||||
p_pressure_damage_multiplier: float,
|
||||
p_collision_damage_multiplier: float,
|
||||
p_collision_speed_threshold_mps: float,
|
||||
p_collision_damage_per_excess_mps: float,
|
||||
p_collision_repeat_delay_seconds: float,
|
||||
p_crush_grace_seconds: float,
|
||||
p_attention_ratio: float,
|
||||
p_return_ratio: float,
|
||||
p_critical_ratio: float,
|
||||
p_ejection_hold_seconds: float
|
||||
) -> void:
|
||||
battery_capacity_kwh = p_battery_capacity_kwh
|
||||
oxygen_capacity_l = p_oxygen_capacity_l
|
||||
oxygen_consumption_l_per_min = p_oxygen_consumption_l_per_min
|
||||
hull_max_integrity = p_hull_max_integrity
|
||||
certified_depth_m = p_certified_depth_m
|
||||
critical_depth_m = certified_depth_m * 1.15
|
||||
crush_depth_m = certified_depth_m * 1.25
|
||||
certified_pressure_bar = _pressure_at_depth(certified_depth_m)
|
||||
critical_pressure_bar = _pressure_at_depth(critical_depth_m)
|
||||
crush_pressure_bar = _pressure_at_depth(crush_depth_m)
|
||||
longitudinal_power_kw = p_longitudinal_power_kw
|
||||
steering_power_kw = p_steering_power_kw
|
||||
vertical_power_kw = p_vertical_power_kw
|
||||
high_thrust_power_kw = p_high_thrust_power_kw
|
||||
return_energy_kwh_per_m = p_return_energy_kwh_per_m
|
||||
ascent_energy_kwh_per_m = p_ascent_energy_kwh_per_m
|
||||
pressure_damage_multiplier = p_pressure_damage_multiplier
|
||||
collision_damage_multiplier = p_collision_damage_multiplier
|
||||
collision_speed_threshold_mps = p_collision_speed_threshold_mps
|
||||
collision_damage_per_excess_mps = p_collision_damage_per_excess_mps
|
||||
collision_repeat_delay_seconds = p_collision_repeat_delay_seconds
|
||||
crush_grace_seconds = p_crush_grace_seconds
|
||||
attention_ratio = p_attention_ratio
|
||||
return_ratio = p_return_ratio
|
||||
critical_ratio = p_critical_ratio
|
||||
ejection_hold_seconds = p_ejection_hold_seconds
|
||||
|
||||
|
||||
func validation_error() -> String:
|
||||
for positive_value: float in [
|
||||
battery_capacity_kwh,
|
||||
oxygen_capacity_l,
|
||||
oxygen_consumption_l_per_min,
|
||||
hull_max_integrity,
|
||||
certified_depth_m,
|
||||
longitudinal_power_kw,
|
||||
return_energy_kwh_per_m,
|
||||
collision_speed_threshold_mps,
|
||||
collision_damage_per_excess_mps,
|
||||
collision_repeat_delay_seconds,
|
||||
crush_grace_seconds,
|
||||
ejection_hold_seconds,
|
||||
]:
|
||||
if not is_finite(positive_value) or positive_value <= 0.0:
|
||||
return "resolved positive values must be finite and greater than zero"
|
||||
for non_negative_value: float in [
|
||||
steering_power_kw,
|
||||
vertical_power_kw,
|
||||
high_thrust_power_kw,
|
||||
ascent_energy_kwh_per_m,
|
||||
]:
|
||||
if not is_finite(non_negative_value) or non_negative_value < 0.0:
|
||||
return "resolved non-negative values must be finite"
|
||||
if not (
|
||||
critical_ratio > 0.0
|
||||
and critical_ratio < return_ratio
|
||||
and return_ratio < attention_ratio
|
||||
and attention_ratio < 1.0
|
||||
):
|
||||
return "alert ratios must be ordered between zero and one"
|
||||
if pressure_damage_multiplier <= 0.0 or collision_damage_multiplier <= 0.0:
|
||||
return "damage multipliers must be positive"
|
||||
return ""
|
||||
|
||||
|
||||
static func _pressure_at_depth(depth_m: float) -> float:
|
||||
return 1.0 + depth_m / 10.0
|
||||
Reference in new issue
Block a user