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

- 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

- type: entity
  parent: BaseGameRule
  id: SubGamemodesRuleNoWizard
  components:
  - type: SubGamemodes
    rules:
    - id: Thief
      prob: 0.5

- 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:
    - id: HealingToolbox
    - id: ClothingOuterArmorBasicSlim
      orGroup: loot
    - id: ClothingHeadHelmetBasic
      orGroup: loot
    - id: SoapNT
      orGroup: loot
    - id: Bola
      orGroup: loot
    - id: Spear
      orGroup: loot
    - id: ClothingShoesGaloshes
      orGroup: loot
    - id: FoodPieBananaCream
      orGroup: loot
    - id: Stimpack
      orGroup: loot
  - 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
  id: Nukeops
  components:
  - type: GameRule
    minPlayers: 20
  - type: LoadMapRule
    mapPath: /Maps/Nonstations/nukieplanet.yml
  - type: AntagSelection
    selectionTime: PrePlayerSpawn
    definitions:
    - prefRoles: [ NukeopsCommander ]
      fallbackRoles: [ Nukeops, NukeopsMedic ]
      spawnerPrototype: SpawnPointNukeopsCommander
      startingGear: SyndicateCommanderGearFull
      roleLoadout:
      - RoleSurvivalNukie
      components:
      - type: NukeOperative
      - type: RandomMetadata
        nameSegments:
        - NamesSyndicateElite
        nameFormat: name-format-nukie-commander
      - type: NpcFactionMember
        factions:
        - Syndicate
      mindRoles:
      - MindRoleNukeopsCommander
    - prefRoles: [ NukeopsMedic ]
      fallbackRoles: [ Nukeops, NukeopsCommander ]
      spawnerPrototype: SpawnPointNukeopsMedic
      startingGear: SyndicateOperativeMedicFull
      roleLoadout:
      - RoleSurvivalNukie
      components:
      - type: NukeOperative
      - type: RandomMetadata
        nameSegments:
        - NamesSyndicateNormal
        nameFormat: name-format-nukie-agent
      - type: NpcFactionMember
        factions:
        - Syndicate
      mindRoles:
      - MindRoleNukeopsMedic
    - prefRoles: [ Nukeops ]
      fallbackRoles: [ NukeopsCommander, NukeopsMedic ]
      spawnerPrototype: SpawnPointNukeopsOperative
      max: 3
      playerRatio: 10
      startingGear: SyndicateOperativeGearFull
      roleLoadout:
      - RoleSurvivalNukie
      components:
      - type: NukeOperative
      - type: RandomMetadata
        nameSegments:
        - NamesSyndicateNormal
        nameFormat: name-format-nukie-operator
      - type: NpcFactionMember
        factions:
        - Syndicate
      mindRoles:
      - MindRoleNukeops
  - 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
  id: Traitor
  components:
  - type: GameRule
    minPlayers: 5
    delay:
      min: 240
      max: 420
  - type: AntagSelection
    selectionTime: IntraPlayerSpawn
    definitions:
    - prefRoles: [ Traitor ]
      max: 8
      playerRatio: 10
      blacklist:
        components:
        - AntagImmune
      lateJoinAdditional: false
      mindRoles:
      - MindRoleTraitor

- type: entity
  id: TraitorReinforcement
  parent: BaseTraitorRule
  components:
  - type: TraitorRule
    giveUplink: false
    giveCodewords: false # It would actually give them a different set of codewords than the regular traitors, anyway
    giveBriefing: false
  - type: AntagSelection
    definitions:
    - prefRoles: [ Traitor ]
      mindRoles:
      - MindRoleTraitorReinforcement

- type: entity
  id: Changeling
  parent: BaseGameRule
  components:
  - type: GameRule
    minPlayers: 25
  - type: AntagSelection
    agentName: changeling-round-end-agent-name
    selectionTime: IntraPlayerSpawn
    definitions:
    - prefRoles: [ Changeling ]
      max: 3
      playerRatio: 15
      briefing:
        text: changeling-role-greeting
        color: Red
        sound: /Audio/Ambience/Antag/changeling_start.ogg
      components:
      - type: ChangelingDevour
      - type: ChangelingIdentity
      - type: ChangelingTransform
      - type: ActionGrant
        actions:
        - ActionRetractableItemArmBlade # Temporary addition, will inevitably be a purchasable in the bio-store
      mindRoles:
      - MindRoleChangeling
  - type: AntagObjectives
    objectives:
    - ChangelingSurviveObjective

- type: entity
  id: Revolutionary
  parent: BaseGameRule
  components:
  - type: GameRule
    minPlayers: 15
  - type: RevolutionaryRule
  - type: AntagSelection
    selectionTime: IntraPlayerSpawn
    definitions:
    - prefRoles: [ HeadRev ]
      max: 3
      playerRatio: 15
      briefing:
        text: head-rev-role-greeting
        color: CornflowerBlue
        sound: "/Audio/Ambience/Antag/headrev_start.ogg"
      startingGear: HeadRevGear
      components:
      - type: Revolutionary
      - type: HeadRevolutionary
      mindRoles:
      - MindRoleHeadRevolutionary
  - 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
  - type: AntagLoadProfileRule
    speciesOverride: Human

- type: entity
  parent: BaseWizardRule
  id: Wizard
  components:
  - type: GameRule
    minPlayers: 10
  - type: AntagSelection
    agentName: wizard-round-end-name
    selectionTime: PrePlayerSpawn
    definitions:
    - prefRoles: [ Wizard ]
      max: 1
      playerRatio: 1
      spawnerPrototype: SpawnPointGhostWizard
      roleLoadout:
       - RoleSurvivalExtended
      briefing:
        text: wizard-role-greeting
        color: Turquoise
        # TODO: Need Wizard Start sound
        #sound: "/Audio/Ambience/Antag/wizard_start.ogg"
      startingGear: WizardBlueGear
      # TODO: WizardComp as needed
      components:
      - type: NpcFactionMember
        factions:
        - Wizard
      - type: RandomMetadata
        nameSegments:
        - NamesWizardFirst
        - NamesWizardLast
        nameFormat: name-format-wizard
      mindRoles:
      - MindRoleWizard
  - type: DynamicRuleCost
    cost: 150

- type: entity
  id: Zombie
  parent: BaseGameRule
  components:
  - type: GameRule
    minPlayers: 20
    delay:
      min: 600
      max: 900
  - type: ZombieRule
  - type: AntagSelection
    selectionTime: IntraPlayerSpawn
    definitions:
    - prefRoles: [ InitialInfected ]
      max: 6
      playerRatio: 10
      blacklist:
        components:
        - ZombieImmune
        - AntagImmune
      briefing:
        text: zombie-patientzero-role-greeting
        color: Plum
        sound: "/Audio/Ambience/Antag/zombie_start.ogg"
      components:
      - type: PendingZombie
      - type: ZombifyOnDeath
      - type: IncurableZombie
      - type: InitialInfected
      mindRoles:
      - MindRoleInitialInfected
  - type: DynamicRuleCost
    cost: 200

# 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: IntraPlayerSpawn # Pre-selection before jobs; assignment doesn't really matter though, we only care about the pre-selection to block other antags.
    removeUponFailedSpawn: false
    definitions:
    - prefRoles: [ InitialInfected, Traitor, Thief, HeadRev ]
      max: 2
      playerRatio: 30

# 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:AllSelector # we need to pass a list of rules, since rules have further restrictions to consider via StationEventComp
    children:
      - !type:NestedSelector
        tableId: UnknownShuttlesFriendlyTable
      - !type:NestedSelector
        tableId: UnknownShuttlesFreelanceTable
      - !type:NestedSelector
        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.
    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
      tableId: SpaceTrafficControlTable

- type: entity
  id: SpaceTrafficControlFriendlyEventScheduler
  parent: BaseGameRule
  components:
  - type: BasicStationEventScheduler
    minimumTimeUntilFirstEvent: 1200 # 20 mins
    minMaxEventTiming:
      min: 600 # 10 mins
      max: 1800 # 30 mins
    scheduledGameRules: !type:NestedSelector
      tableId: UnknownShuttlesFriendlyTable

# variation passes
- type: entity
  id: BasicRoundstartVariation
  parent: BaseGameRule
  components:
  - type: RoundstartStationVariationRule
    rules:
    - id: BasicPoweredLightVariationPass
    - id: BasicTrashVariationPass
#    - id: SolidWallRustingVariationPass # Frontier - disabled becuase mismatched types and sprites
#    - id: ReinforcedWallRustingVariationPass # Frontier
    - id: BasicPuddleMessVariationPass
      prob: 0.99
      orGroup: puddleMess
#    - id: BloodbathPuddleMessVariationPass # Frontier
#      prob: 0.01 # Frontier
#      orGroup: puddleMess # Frontier
#    - id: SmugglerStashVariationPass # Frontier
#      prob: 0.90 # Frontier
    - id: SolarPanelDamageVariationPass
    - id: SolarPanelEmptyVariationPass
    - id: BasicDecalDirtVariationPass
    - id: BasicDecalGraffitiVariationPass
    - id: BasicDecalBrunsVariationPass
      prob: 0.50
      orGroup: monospaceDecals
    - id: BasicDecalDirtMonospaceVariationPass
      prob: 0.50
      orGroup: monospaceDecals
