mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2026-02-05 10:45:17 -05:00
376 lines
9.7 KiB
Python
376 lines
9.7 KiB
Python
"""
|
|
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}"
|
|
|
|
|
|
# Transport Type Choices for Transportation Rides
|
|
TRANSPORT_TYPES = [
|
|
("TRAIN", "Train"),
|
|
("MONORAIL", "Monorail"),
|
|
("SKYLIFT", "Skylift / Chairlift"),
|
|
("FERRY", "Ferry / Boat"),
|
|
("PEOPLEMOVER", "PeopleMover"),
|
|
("CABLE_CAR", "Cable Car"),
|
|
("TRAM", "Tram"),
|
|
]
|
|
|
|
|
|
@pghistory.track()
|
|
class KiddieRideStats(TrackedModel):
|
|
"""
|
|
Statistics specific to kiddie rides (category=KR).
|
|
|
|
Tracks age-appropriate ride characteristics and theming.
|
|
"""
|
|
|
|
ride = models.OneToOneField(
|
|
"rides.Ride",
|
|
on_delete=models.CASCADE,
|
|
related_name="kiddie_stats",
|
|
help_text="Ride these kiddie ride statistics belong to",
|
|
)
|
|
|
|
min_age = models.PositiveIntegerField(
|
|
null=True,
|
|
blank=True,
|
|
help_text="Minimum recommended age in years",
|
|
)
|
|
|
|
max_age = models.PositiveIntegerField(
|
|
null=True,
|
|
blank=True,
|
|
help_text="Maximum recommended age in years",
|
|
)
|
|
|
|
educational_theme = models.CharField(
|
|
max_length=200,
|
|
blank=True,
|
|
help_text="Educational theme if applicable (e.g., 'Dinosaurs', 'Space')",
|
|
)
|
|
|
|
character_theme = models.CharField(
|
|
max_length=200,
|
|
blank=True,
|
|
help_text="Character theme if applicable (e.g., 'Paw Patrol', 'Peppa Pig')",
|
|
)
|
|
|
|
guardian_required = models.BooleanField(
|
|
default=False,
|
|
help_text="Whether a guardian must be present during the ride",
|
|
)
|
|
|
|
adult_ride_along = models.BooleanField(
|
|
default=True,
|
|
help_text="Whether adults can ride along with children",
|
|
)
|
|
|
|
seats_per_vehicle = models.PositiveIntegerField(
|
|
null=True,
|
|
blank=True,
|
|
help_text="Number of seats per ride vehicle",
|
|
)
|
|
|
|
class Meta(TrackedModel.Meta):
|
|
verbose_name = "Kiddie Ride Statistics"
|
|
verbose_name_plural = "Kiddie Ride Statistics"
|
|
ordering = ["ride"]
|
|
|
|
def __str__(self) -> str:
|
|
return f"Kiddie Ride Stats for {self.ride.name}"
|
|
|
|
|
|
@pghistory.track()
|
|
class TransportationStats(TrackedModel):
|
|
"""
|
|
Statistics specific to transportation rides (category=TR).
|
|
|
|
Tracks route, capacity, and vehicle information.
|
|
"""
|
|
|
|
ride = models.OneToOneField(
|
|
"rides.Ride",
|
|
on_delete=models.CASCADE,
|
|
related_name="transport_stats",
|
|
help_text="Ride these transportation statistics belong to",
|
|
)
|
|
|
|
transport_type = models.CharField(
|
|
max_length=20,
|
|
choices=TRANSPORT_TYPES,
|
|
default="TRAIN",
|
|
help_text="Type of transportation",
|
|
)
|
|
|
|
route_length_ft = models.DecimalField(
|
|
max_digits=8,
|
|
decimal_places=2,
|
|
null=True,
|
|
blank=True,
|
|
help_text="Total route length in feet",
|
|
)
|
|
|
|
stations_count = models.PositiveIntegerField(
|
|
null=True,
|
|
blank=True,
|
|
help_text="Number of stations/stops on the route",
|
|
)
|
|
|
|
vehicle_capacity = models.PositiveIntegerField(
|
|
null=True,
|
|
blank=True,
|
|
help_text="Passenger capacity per vehicle",
|
|
)
|
|
|
|
vehicles_count = models.PositiveIntegerField(
|
|
null=True,
|
|
blank=True,
|
|
help_text="Total number of vehicles in operation",
|
|
)
|
|
|
|
round_trip_duration_minutes = models.PositiveIntegerField(
|
|
null=True,
|
|
blank=True,
|
|
help_text="Duration of a complete round trip in minutes",
|
|
)
|
|
|
|
scenic_highlights = models.TextField(
|
|
blank=True,
|
|
help_text="Notable scenic views or attractions along the route",
|
|
)
|
|
|
|
is_one_way = models.BooleanField(
|
|
default=False,
|
|
help_text="Whether this is a one-way transportation (vs round-trip)",
|
|
)
|
|
|
|
class Meta(TrackedModel.Meta):
|
|
verbose_name = "Transportation Statistics"
|
|
verbose_name_plural = "Transportation Statistics"
|
|
ordering = ["ride"]
|
|
|
|
def __str__(self) -> str:
|
|
return f"Transportation Stats for {self.ride.name}"
|