- type: entity
  id: BaseGameRule
  abstract: true
  components:
  - type: GameRule

- type: entity
  parent: BaseGameRule
  id: BaseRoundstartAntagRule
  abstract: true
  components:
  - type: AntagSelection
    selectionTime: PrePlayerSpawn

- type: entity
  parent: BaseGameRule
  id: RespawnDeadRule
  components:
  - type: RespawnDeadRule
    alwaysRespawnDead: true
  - type: RespawnTracker
    respawnDelay: 10
    deleteBody: false

- type: entity
  parent: BaseGameRule
  id: SubGamemodesRule
  components:
  - type: SubGamemodes
    rules:
    - id: Thief
      prob: 0.5
    - id: SubWizard
      prob: 0.05
    - id: SubXenoborgs
      prob: 0.05
    - id: Changeling
      prob: 0.25

- type: entity
  parent: BaseGameRule
  id: SubGamemodesRuleNoWizard
  components:
  - type: SubGamemodes
    rules:
    - id: Thief
      prob: 0.5
    - id: SubXenoborgs
      prob: 0.05
    - id: Changeling
      prob: 0.25

- type: entity
  parent: BaseGameRule
  id: SubGamemodesRuleNoXenoborg
  components:
  - type: SubGamemodes
    rules:
    - id: Thief
      prob: 0.5
    - id: SubWizard
      prob: 0.05
    - id: Changeling
      prob: 0.25

- type: entity
  parent: BaseGameRule
  id: SubGamemodesRuleNoWizardNoXenoborg
  components:
  - type: SubGamemodes
    rules:
    - id: Thief
      prob: 0.5
    - id: Changeling
      prob: 0.25

- type: entity
  parent: BaseGameRule
  id: DummyNonAntagChance
  components:
  - type: SubGamemodes
    rules:
    - id: DummyNonAntag
      prob: 0.3

- type: entity
  id: DeathMatch31
  parent: BaseGameRule
  components:
  - type: DeathMatchRule
    rewardSpawns: !type:AllSelector
      children:
      - id: HealingToolbox
      - !type:GroupSelector
        children:
        - id: ClothingOuterArmorBasicSlim
        - id: ClothingHeadHelmetBasic
        - id: SoapNT
        - id: Bola
        - id: Spear
        - id: ClothingShoesGaloshes
        - id: FoodPieBananaCream
        - id: Stimpack
  - type: KillCalloutRule
  - type: PointManager
  - type: RespawnDeadRule
  - type: RespawnTracker
    respawnDelay: 5

- type: entity
  id: InactivityTimeRestart
  parent: BaseGameRule
  components:
  - type: InactivityRule
    inactivityMaxTime: 600
    roundEndDelay: 10

- type: entity
  id: MaxTimeRestart
  parent: BaseGameRule
  components:
  - type: MaxTimeRestartRule
    roundMaxTime: 300
    roundEndDelay: 10

- type: entity
  abstract: true
  parent: BaseGameRule
  id: BaseNukeopsRule
  components:
  - type: RandomMetadata #this generates the random operation name cuz it's cool.
    nameSegments:
    - NamesOperationPrefix
    - NamesOperationSuffix
    nameFormat: name-format-nuclear-operation
  - type: NukeopsRule
  - type: RuleGrids
  - type: AntagSelection
  - type: AntagLoadProfileRule
    speciesOverride: Human
    speciesOverrideBlacklist:
    #Species that do not work with nukies should be included in this list.
    #Once the issues are fixed the species should be removed from this list to be enabled.
    #Balance concerns are not a valid reason to disable a species, except for high-impact Nukie-specific exploits.
    #- Vox

- type: entity
  parent: [ BaseNukeopsRule, BaseRoundstartAntagRule ]
  id: Nukeops
  components:
  - type: GameRule
    minPlayers: 20
  - type: LoadMapRule
    mapPath: /Maps/Nonstations/nukieplanet.yml
  - type: AntagSelection
    antags:
    - !type:FixedAntagCount
      proto: NukeopsCommander
    - !type:FixedAntagCount
      proto: NukeopsMedic
    - !type:LinearAntagCount
      proto: NukeopsOperative
      range:
        min: 1
        max: 3
  - type: DynamicRuleCost
    cost: 200

- type: entity
  abstract: true
  parent: BaseGameRule
  id: BaseTraitorRule
  components:
  - type: TraitorRule
  # TODO: codewords in yml
  # TODO: uplink in yml
  - type: AntagRandomObjectives
    sets:
    - groups: TraitorObjectiveGroups
    maxDifficulty: 5
  - type: AntagSelection
    agentName: traitor-round-end-agent-name
  - type: DynamicRuleCost
    cost: 100

- type: entity
  parent: [ BaseTraitorRule, BaseRoundstartAntagRule ]
  id: Traitor
  components:
  - type: GameRule
    minPlayers: 5
    delay:
      min: 240
      max: 420
  - type: AntagSelection
    lateJoinAdditional: true
    antags:
    - !type:LinearAntagCount
      proto: Traitor
      range:
        min: 1
        max: 8

- type: entity
  id: TraitorReinforcement # This shouldn't be in here but I'm not sure where to put it :(
  parent: BaseTraitorRule
  components:
  - type: TraitorRule
    giveUplink: false
    giveBriefing: false
  - type: AntagSelection
    antags:
    - !type:FixedAntagCount
      proto: TraitorReinforcement

- type: entity
  id: Changeling
  parent: [BaseGameRule, BaseRoundstartAntagRule]
  components:
  - type: ChangelingRule
  - type: GameRule
    minPlayers: 20
    delay:
      min: 240
      max: 420
    cancelPresetOnTooFewPlayers: false
  - type: AntagSelection
    agentName: changeling-round-end-agent-name
    antags:
    - !type:LinearAntagCount
      proto: Changeling
      playerRatio: 15
      range:
        min: 1
        max: 3
  - type: AntagRandomObjectives
    sets:
    - groups: ChangelingObjectiveGroupDevourDummy
      maxPicks: 1
    - groups: ChangelingObjectiveGroupEscapeDummy
      maxPicks: 1
    - groups: ChangelingObjectiveGroupKillDummy
      maxPicks: 1
    maxDifficulty: 8
  - type: DynamicRuleCost
    cost: 75

- type: entity
  id: Revolutionary
  parent: [BaseGameRule, BaseRoundstartAntagRule]
  components:
  - type: GameRule
    minPlayers: 15
  - type: RevolutionaryRule
  - type: AntagSelection
    selectionTime: PrePlayerSpawn
    antags:
    - !type:LinearAntagCount
      proto: HeadRev
      playerRatio: 15
      range:
        min: 1
        max: 3
  - type: DynamicRuleCost
    cost: 200

- type: entity
  id: Sandbox
  parent: BaseGameRule
  components:
  - type: SandboxRule

- type: entity
  id: Secret
  parent: BaseGameRule
  components:
  - type: SecretRule

- type: entity
  abstract: true
  parent: BaseGameRule
  id: BaseWizardRule
  components:
  - type: AntagObjectives
    objectives:
    - WizardSurviveObjective
    - WizardDemonstrateObjective
  - type: LoadMapRule
    mapPath: /Maps/Nonstations/wizardsden.yml
  - type: RuleGrids
  - type: AntagSelection
    agentName: wizard-round-end-name
    antags:
    - !type:FixedAntagCount
      proto: Wizard
  - type: AntagLoadProfileRule
    speciesOverride: Human

- type: entity
  parent: [ BaseWizardRule, BaseRoundstartAntagRule ]
  id: Wizard
  components:
  - type: GameRule
    minPlayers: 10
  - type: DynamicRuleCost
    cost: 150

- type: entity
  id: Zombie
  parent: [ BaseGameRule, BaseRoundstartAntagRule]
  components:
  - type: GameRule
    minPlayers: 20
    delay:
      min: 600
      max: 900
  - type: ZombieRule
  - type: AntagSelection
    antags:
    - !type:LinearAntagCount
      proto: InitialInfected
      range:
        min: 1
        max: 6
  - type: DynamicRuleCost
    cost: 200

- type: entity
  abstract: true
  parent: BaseGameRule
  id: BaseXenoborgsRule
  components:
  - type: XenoborgsRule
  - type: RuleGrids
  - type: LoadMapRule
    gridPath: /Maps/Shuttles/mothership.yml
  - type: AntagMultipleRoleSpawner
    antagRoleToPrototypes:
      MothershipCore: [ MothershipCore ]
      Xenoborg: [ XenoborgEngi, XenoborgHeavy, XenoborgScout, XenoborgStealth ]
    pickAndTake: true
  - type: AntagSelection
    selectionTime: PrePlayerSpawn
    antags:
    - !type:FixedAntagCount
      proto: MothershipCore
    - !type:FixedAntagCount
      proto: Xenoborg
      count: 4
  - type: DynamicRuleCost
    cost: 200

- type: entity
  parent: [ BaseXenoborgsRule, BaseRoundstartAntagRule]
  id: Xenoborgs
  components:
  - type: GameRule
    minPlayers: 30

# This rule makes the chosen players unable to get other antag rules, as a way to prevent metagaming job rolls.
# Put this before antags assigned to station jobs, but after non-job antags (NukeOps/Wiz).
- type: entity
  id: DummyNonAntag
  parent: BaseGameRule
  components:
  - type: GameRule
    minPlayers: 5
  - type: AntagSelection
    selectionTime: PrePlayerSpawn # Pre-selection before jobs; assignment doesn't really matter though, we only care about the pre-selection to block other antags.
    removeUponFailedSpawn: false
    antags:
    - !type:LinearAntagCount
      proto: DummyAntag
      playerRatio: 30
      range:
        min: 1
        max: 2

- type: antagSpecifier
  parent: RestrictedAntag
  id: DummyAntag
  prefRoles: # Only Station bound roles.
  - InitialInfected
  - Traitor
  - Thief
  - HeadRev

# event schedulers

- type: entityTable
  id: BasicGameRulesTable
  table: !type:AllSelector # we need to pass a list of rules, since rules have further restrictions to consider via StationEventComp
    children:
      - !type:NestedSelector
        tableId: BasicCalmEventsTable
      - !type:NestedSelector
        tableId: BasicAntagEventsTable
      - !type:NestedSelector
        tableId: ModerateAntagEventsTable
      - !type:NestedSelector
        tableId: CargoGiftsTable
      - !type:NestedSelector
        tableId: CalmPestEventsTable
      - !type:NestedSelector
        tableId: SpicyPestEventsTable

- type: entityTable
  id: DynamicGameRulesTable
  table: !type:AllSelector # we need to pass a list of rules, since rules have further restrictions to consider via StationEventComp
    children:
    - !type:NestedSelector
      tableId: BasicCalmEventsTable
    - !type:NestedSelector
      tableId: BasicAntagEventsTable
    - !type:NestedSelector
      tableId: CargoGiftsTable
    - !type:NestedSelector
      tableId: CalmPestEventsTable
    - !type:NestedSelector
      tableId: SpicyPestEventsTable

- type: entityTable
  id: SpaceTrafficControlTable
  table: !type:NestedSelector # we need to pass a list of rules, since rules have further restrictions to consider via StationEventComp
    tableId: UnknownShuttlesHostileTable

- type: entity
  id: BasicStationEventScheduler
  parent: BaseGameRule
  components:
  - type: BasicStationEventScheduler
    scheduledGameRules: !type:NestedSelector
      tableId: BasicGameRulesTable

- type: entity
  id: DynamicStationEventScheduler # this isn't the dynamic mode, but rather the station event scheduler used for dynamic
  parent: BaseGameRule
  components:
  - type: BasicStationEventScheduler
    scheduledGameRules: !type:NestedSelector
      tableId: DynamicGameRulesTable

- type: entity
  id: RampingStationEventScheduler
  parent: BaseGameRule
  components:
  - type: RampingStationEventScheduler
    scheduledGameRules: !type:NestedSelector
      tableId: BasicGameRulesTable

- type: entity
  id: SpaceTrafficControlEventScheduler # iff we make a selector for EntityTables that can respect StationEventComp restrictions, or somehow impliment them otherwise in said tables,
  parent: BaseGameRule                  # we can remerge this with the other schedulers, but it will silently fail due to that limitation without a separate scheduler to balance atm.
  components:
  - type: BasicStationEventScheduler
    minimumTimeUntilFirstEvent: 2700 # 45 mins #shows up like half way through shift.
    maximumSpanUntilFirstEvent: 900 # At longest takes an hour to show up.
    minMaxEventTiming:
      min: 1200 # 20 mins
      max: 7200 # 120 mins # you probably arent getting a second visitor shuttle in one round, but it is possible.
    scheduledGameRules: !type:NestedSelector
      prob: 0.05 # Only 1 in 20 rounds...
      tableId: SpaceTrafficControlTable

# variation passes
- type: entity
  id: BasicRoundstartVariation
  parent: BaseGameRule
  components:
  - type: RoundstartStationVariationRule
    rules:
    - id: BasicPoweredLightVariationPass
    - id: BasicTrashVariationPass
    - id: SolidWallRustingVariationPass
    - id: ReinforcedWallRustingVariationPass
    - id: CutWireVariationPass
    - id: BasicPuddleMessVariationPass
      prob: 0.99
      orGroup: puddleMess
    - id: BloodbathPuddleMessVariationPass
      prob: 0.01
      orGroup: puddleMess
    - id: SmugglerStashVariationPass
      prob: 0.90
    - id: SolarPanelDamageVariationPass
    - id: SolarPanelEmptyVariationPass
    - id: BasicDecalDirtVariationPass
    - id: BasicDecalGraffitiVariationPass
    - id: BasicDecalBurnsVariationPass
      prob: 0.50
      orGroup: monospaceDecals
    - id: BasicDecalDirtMonospaceVariationPass
      prob: 0.50
      orGroup: monospaceDecals
