""" Ride-Specific Statistics Models This module contains specialized statistics models for different ride categories: - WaterRideStats: For water rides (WR) - DarkRideStats: For dark rides (DR) - FlatRideStats: For flat rides (FR) These complement the existing RollerCoasterStats model in rides.py. """ import pghistory from django.db import models from apps.core.history import TrackedModel # Wetness Level Choices for Water Rides WETNESS_LEVELS = [ ("DRY", "Dry - No water contact"), ("MILD", "Mild - Light misting"), ("MODERATE", "Moderate - Some splashing"), ("SOAKING", "Soaking - Prepare to get drenched"), ] # Motion Type Choices for Flat Rides MOTION_TYPES = [ ("SPINNING", "Spinning"), ("SWINGING", "Swinging"), ("BOUNCING", "Bouncing"), ("ROTATING", "Rotating"), ("DROPPING", "Dropping"), ("MIXED", "Mixed Motion"), ] @pghistory.track() class WaterRideStats(TrackedModel): """ Statistics specific to water rides (category=WR). Tracks water-related attributes like wetness level and splash characteristics. """ ride = models.OneToOneField( "rides.Ride", on_delete=models.CASCADE, related_name="water_stats", help_text="Ride these water statistics belong to", ) wetness_level = models.CharField( max_length=10, choices=WETNESS_LEVELS, default="MODERATE", help_text="How wet riders typically get", ) splash_height_ft = models.DecimalField( max_digits=5, decimal_places=2, null=True, blank=True, help_text="Maximum splash height in feet", ) has_splash_zone = models.BooleanField( default=False, help_text="Whether there is a designated splash zone for spectators", ) boat_capacity = models.PositiveIntegerField( null=True, blank=True, help_text="Number of riders per boat/raft", ) uses_flume = models.BooleanField( default=False, help_text="Whether the ride uses a flume/log system", ) rapids_sections = models.PositiveIntegerField( default=0, help_text="Number of rapids/whitewater sections", ) class Meta(TrackedModel.Meta): verbose_name = "Water Ride Statistics" verbose_name_plural = "Water Ride Statistics" ordering = ["ride"] def __str__(self) -> str: return f"Water Stats for {self.ride.name}" @pghistory.track() class DarkRideStats(TrackedModel): """ Statistics specific to dark rides (category=DR). Tracks theming elements like scenes, animatronics, and technology. """ ride = models.OneToOneField( "rides.Ride", on_delete=models.CASCADE, related_name="dark_stats", help_text="Ride these dark ride statistics belong to", ) scene_count = models.PositiveIntegerField( default=0, help_text="Number of themed scenes", ) animatronic_count = models.PositiveIntegerField( default=0, help_text="Number of animatronic figures", ) has_projection_technology = models.BooleanField( default=False, help_text="Whether the ride uses projection mapping or screens", ) is_interactive = models.BooleanField( default=False, help_text="Whether riders can interact with elements (shooting, etc.)", ) ride_system = models.CharField( max_length=100, blank=True, help_text="Type of ride system (Omnimover, Trackless, Classic Track, etc.)", ) uses_practical_effects = models.BooleanField( default=True, help_text="Whether the ride uses practical/physical effects", ) uses_motion_base = models.BooleanField( default=False, help_text="Whether vehicles have motion simulation capability", ) class Meta(TrackedModel.Meta): verbose_name = "Dark Ride Statistics" verbose_name_plural = "Dark Ride Statistics" ordering = ["ride"] def __str__(self) -> str: return f"Dark Ride Stats for {self.ride.name}" @pghistory.track() class FlatRideStats(TrackedModel): """ Statistics specific to flat rides (category=FR). Tracks motion characteristics like rotation, swing angles, and height. """ ride = models.OneToOneField( "rides.Ride", on_delete=models.CASCADE, related_name="flat_stats", help_text="Ride these flat ride statistics belong to", ) max_height_ft = models.DecimalField( max_digits=6, decimal_places=2, null=True, blank=True, help_text="Maximum ride height in feet", ) rotation_speed_rpm = models.DecimalField( max_digits=5, decimal_places=2, null=True, blank=True, help_text="Maximum rotation speed in RPM", ) swing_angle_degrees = models.PositiveIntegerField( null=True, blank=True, help_text="Maximum swing angle in degrees (for swinging rides)", ) motion_type = models.CharField( max_length=20, choices=MOTION_TYPES, default="SPINNING", help_text="Primary type of motion", ) arm_count = models.PositiveIntegerField( null=True, blank=True, help_text="Number of arms/gondolas", ) seats_per_gondola = models.PositiveIntegerField( null=True, blank=True, help_text="Number of seats per gondola/arm", ) max_g_force = models.DecimalField( max_digits=4, decimal_places=2, null=True, blank=True, help_text="Maximum G-force experienced", ) class Meta(TrackedModel.Meta): verbose_name = "Flat Ride Statistics" verbose_name_plural = "Flat Ride Statistics" ordering = ["ride"] def __str__(self) -> str: return f"Flat Ride Stats for {self.ride.name}"