{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
  "title": "Questionable V1",
  "description": "A series of quest sequences",
  "type": "object",
  "properties": {
    "$schema": {
      "type": "string",
      "const": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json"
    },
    "Author": {
      "description": "Author of the quest sequence",
      "type": [
        "string",
        "array"
      ],
      "items": {
        "type": "string"
      }
    },
    "Disabled": {
      "type": "boolean"
    },
    "Comment": {
      "type": "string"
    },
    "$": {
      "type": "string",
      "description": "Dev Comment (not visible in-game)"
    },
    "TerritoryBlacklist": {
      "type": "array",
      "items": {
        "type": "integer"
      }
    },
    "QuestSequence": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "Sequence": {
            "type": "integer",
            "minimum": 0,
            "maximum": 255
          },
          "Steps": {
            "type": "array",
            "items": {
              "$ref": "#/$defs/Step"
            }
          },
          "Comment": {
            "type": "string"
          }
        },
        "required": [
          "Sequence"
        ],
        "additionalProperties": false
      }
    }
  },
  "required": [
    "$schema",
    "QuestSequence",
    "Author"
  ],
  "additionalProperties": false,
  "$defs": {
    "Step": {
      "type": "object",
      "properties": {
        "DataId": {
          "type": "integer",
          "description": "The data id of the NPC/Object/Aetheryte/Aether Current",
          "exclusiveMinimum": 0
        },
        "Position": {
          "$ref": "https://git.carvel.li/liza/Questionable/raw/branch/master/Questionable.Model/common-schema.json#/$defs/Vector3"
        },
        "StopDistance": {
          "type": [
            "number",
            "null"
          ],
          "description": "Set if pathfinding should stop closer or further away from the default stop distance",
          "exclusiveMinimum": 0
        },
        "IgnoreDistanceToObject": {
          "type": "boolean",
          "description": "Most interactions with objects are checked for a Y (height) difference of 2 in-game units. If set to true, the game won't attempt to get any closer if the height difference is larger than this."
        },
        "RestartNavigationIfCancelled": {
          "type": "boolean",
          "description": "For some specific loading screen transitions (e.g. when entering/leaving the water through the portals in the ruby sea), setting this to 'false' means it won't re-attempt to move to the portal after the loading animation"
        },
        "TerritoryId": {
          "type": "integer",
          "description": "The territory id associated with the location",
          "exclusiveMinimum": 0
        },
        "TargetTerritoryId": {
          "type": "integer",
          "description": "If set, this step is complete (movement-wise) if this territory id is reached",
          "exclusiveMinimum": 0
        },
        "InteractionType": {
          "type": "string",
          "description": "What to do at the position",
          "enum": [
            "None",
            "Interact",
            "WalkTo",
            "AttuneAethernetShard",
            "AttuneAetheryte",
            "AttuneAetherCurrent",
            "Combat",
            "UseItem",
            "EquipItem",
            "EquipRecommended",
            "Say",
            "Emote",
            "Action",
            "WaitForNpcAtPosition",
            "WaitForManualProgress",
            "Duty",
            "SinglePlayerDuty",
            "Jump",
            "Dive",
            "Craft",
            "Instruction",
            "AcceptQuest",
            "CompleteQuest",
            "InitiateLeve"
          ]
        },
        "Disabled": {
          "description": "Whether this step is disabled (see SkipIf for more control)",
          "type": "boolean"
        },
        "DisableNavmesh": {
          "description": "If true, will go to the position in a straight line instead of using pathfinding",
          "type": "boolean"
        },
        "Mount": {
          "type": [
            "boolean",
            "null"
          ],
          "description": "If true, will mount regardless of distance to position. If false, will unmount."
        },
        "Fly": {
          "type": "boolean",
          "description": "If true and flying is unlocked in a zone, will use a flight path"
        },
        "Land": {
          "type": "boolean",
          "description": "If true and flying, will attempt to land on the ground"
        },
        "Sprint": {
          "type": [
            "boolean",
            "null"
          ]
        },
        "AetheryteShortcut": {
          "description": "The Aetheryte to teleport to (before moving)",
          "$ref": "https://git.carvel.li/liza/Questionable/raw/branch/master/Questionable.Model/common-schema.json#/$defs/Aetheryte"
        },
        "AethernetShortcut": {
          "type": "array",
          "description": "A pair of aethernet locations (from + to) to use as a shortcut",
          "minItems": 2,
          "maxItems": 2,
          "items": {
            "$ref": "https://git.carvel.li/liza/Questionable/raw/branch/master/Questionable.Model/common-schema.json#/$defs/AethernetShard"
          }
        },
        "ItemId": {
          "type": [
            "number",
            "null"
          ],
          "description": "The Item to use",
          "exclusiveMinimum": 0
        },
        "SkipConditions": {
          "type": "object",
          "properties": {
            "StepIf": {
              "type": "object",
              "properties": {
                "Never": {
                  "type": "boolean"
                },
                "CompletionQuestVariablesFlags": {
                  "$ref": "https://git.carvel.li/liza/Questionable/raw/branch/master/Questionable.Model/common-schema.json#/$defs/CompletionFlags"
                },
                "Flying": {
                  "type": "string",
                  "enum": [
                    "Locked",
                    "Unlocked"
                  ]
                },
                "Chocobo": {
                  "type": "string",
                  "enum": [
                    "Locked",
                    "Unlocked"
                  ]
                },
                "NotTargetable": {
                  "type": "boolean"
                },
                "InTerritory": {
                  "type": "array",
                  "items": {
                    "type": "integer"
                  }
                },
                "NotInTerritory": {
                  "type": "array",
                  "items": {
                    "type": "integer"
                  }
                },
                "Item": {
                  "type": "object",
                  "properties": {
                    "NotInInventory": {
                      "type": "boolean"
                    }
                  }
                },
                "QuestsAccepted": {
                  "type": "array",
                  "items": {
                    "type": ["number", "string"]
                  }
                },
                "QuestsCompleted": {
                  "type": "array",
                  "items": {
                    "type": ["number", "string"]
                  }
                },
                "AetheryteLocked": {
                  "$ref": "https://git.carvel.li/liza/Questionable/raw/branch/master/Questionable.Model/common-schema.json#/$defs/Aetheryte"
                },
                "AetheryteUnlocked": {
                  "$ref": "https://git.carvel.li/liza/Questionable/raw/branch/master/Questionable.Model/common-schema.json#/$defs/Aetheryte"
                },
                "NearPosition": {
                  "type": "object",
                  "properties": {
                    "Position": {
                      "$ref": "https://git.carvel.li/liza/Questionable/raw/branch/master/Questionable.Model/common-schema.json#/$defs/Vector3"
                    },
                    "MaximumDistance": {
                      "type": "number"
                    },
                    "TerritoryId": {
                      "type": "number"
                    }
                  },
                  "required": [
                    "Position",
                    "MaximumDistance",
                    "TerritoryId"
                  ],
                  "additionalProperties": false
                },
                "ExtraCondition": {
                  "type": "string",
                  "enum": [
                    "WakingSandsMainArea",
                    "RisingStonesSolar"
                  ]
                }
              },
              "additionalProperties": false
            },
            "AetheryteShortcutIf": {
              "type": "object",
              "properties": {
                "Never": {
                  "type": "boolean"
                },
                "InSameTerritory": {
                  "type": "boolean"
                },
                "InTerritory": {
                  "type": "array",
                  "items": {
                    "type": "integer"
                  }
                },
                "QuestsAccepted": {
                  "type": "array",
                  "items": {
                    "type": ["number", "string"]
                  }
                },
                "QuestsCompleted": {
                  "type": "array",
                  "items": {
                    "type": ["number", "string"]
                  }
                },
                "AetheryteLocked": {
                  "$ref": "https://git.carvel.li/liza/Questionable/raw/branch/master/Questionable.Model/common-schema.json#/$defs/Aetheryte"
                },
                "AetheryteUnlocked": {
                  "$ref": "https://git.carvel.li/liza/Questionable/raw/branch/master/Questionable.Model/common-schema.json#/$defs/Aetheryte"
                },
                "RequiredQuestVariablesNotMet": {
                  "type": "boolean"
                },
                "NearPosition": {
                  "type": "object",
                  "properties": {
                    "Position": {
                      "$ref": "https://git.carvel.li/liza/Questionable/raw/branch/master/Questionable.Model/common-schema.json#/$defs/Vector3"
                    },
                    "MaximumDistance": {
                      "type": "number"
                    },
                    "TerritoryId": {
                      "type": "number"
                    }
                  },
                  "required": [
                    "Position",
                    "MaximumDistance",
                    "TerritoryId"
                  ],
                  "additionalProperties": false
                }
              },
              "additionalProperties": false
            },
            "AethernetShortcutIf": {
              "type": "object",
              "properties": {
                "Never": {
                  "type": "boolean"
                },
                "InSameTerritory": {
                  "type": "boolean"
                },
                "AetheryteLocked": {
                  "$ref": "https://git.carvel.li/liza/Questionable/raw/branch/master/Questionable.Model/common-schema.json#/$defs/Aetheryte"
                },
                "AetheryteUnlocked": {
                  "$ref": "https://git.carvel.li/liza/Questionable/raw/branch/master/Questionable.Model/common-schema.json#/$defs/Aetheryte"
                }
              },
              "additionalProperties": false
            }
          },
          "additionalProperties": false
        },
        "CompletionQuestVariablesFlags": {
          "$ref": "https://git.carvel.li/liza/Questionable/raw/branch/master/Questionable.Model/common-schema.json#/$defs/CompletionFlags"
        },
        "RequiredQuestVariables": {
          "type": "array",
          "description": "Certain quests (primarily beast tribes/allied societies) have a RNG element to spawning targets, and the step should be skipped in its entirety if none of the sets below match",
          "minItems": 6,
          "maxItems": 6,
          "items": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": [
                "number",
                "object"
              ],
              "properties": {
                "High": {
                  "type": [
                    "number",
                    "null"
                  ],
                  "minimum": 0,
                  "maximum": 15
                },
                "Low": {
                  "type": [
                    "number",
                    "null"
                  ],
                  "minimum": 0,
                  "maximum": 15
                }
              },
              "minimum": 0,
              "maximum": 255
            }
          }
        },
        "RequiredGatheredItems": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "ItemId": {
                "type": "number"
              },
              "AlternativeItemId": {
                "description": "For leves that allow you to gather two items with different chance percentage, this is the preferred item if the gathering chance is 100% (after buffs)",
                "type": "number"
              },
              "ItemCount": {
                "type": "number",
                "exclusiveMinimum": 0
              },
              "Collectability": {
                "type": "number",
                "minimum": 0,
                "maximum": 1000
              },
              "QuestAcceptedAsClass": {
                "type": "string",
                "enum": [
                  "Miner",
                  "Botanist"
                ]
              }
            },
            "required": [
              "ItemId",
              "ItemCount"
            ]
          }
        },
        "DelaySecondsAtStart": {
          "description": "Time to wait before starting",
          "type": [
            "number",
            "null"
          ]
        },
        "Comment": {
          "type": "string"
        }
      },
      "required": [
        "TerritoryId",
        "InteractionType"
      ],
      "allOf": [
        {
          "if": {
            "properties": {
              "InteractionType": {
                "const": "Interact"
              }
            }
          },
          "then": {
            "properties": {
              "PickUpItemId": {
                "type": "number"
              }
            },
            "required": [
              "DataId"
            ]
          }
        },
        {
          "if": {
            "properties": {
              "InteractionType": {
                "const": "WalkTo"
              }
            }
          },
          "then": {
            "required": [
              "Position"
            ]
          }
        },
        {
          "if": {
            "properties": {
              "InteractionType": {
                "const": "AttuneAetheryte"
              }
            }
          },
          "then": {
            "properties": {
              "Aetheryte": {
                "$ref": "https://git.carvel.li/liza/Questionable/raw/branch/master/Questionable.Model/common-schema.json#/$defs/Aetheryte"
              },
              "DataId": {
                "type": "null"
              },
              "Position": {
                "type": "null"
              }
            },
            "required": [
              "Aetheryte"
            ]
          },
          "else": {
            "properties": {
              "Aetheryte": {
                "type": "null"
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "InteractionType": {
                "const": "AttuneAethernetShard"
              }
            }
          },
          "then": {
            "properties": {
              "AethernetShard": {
                "$ref": "https://git.carvel.li/liza/Questionable/raw/branch/master/Questionable.Model/common-schema.json#/$defs/AethernetShard"
              },
              "DataId": {
                "type": "null"
              },
              "Position": {
                "type": "null"
              }
            },
            "required": [
              "AethernetShard"
            ]
          },
          "else": {
            "properties": {
              "AethernetShard": {
                "type": "null"
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "InteractionType": {
                "const": "AttuneAetherCurrent"
              }
            }
          },
          "then": {
            "properties": {
              "AetherCurrentId": {
                "type": "integer",
                "description": "The aether current id, used to check if a given aetheryte is unlocked",
                "exclusiveMinimum": 0
              }
            },
            "required": [
              "DataId",
              "Position",
              "AetherCurrentId"
            ]
          }
        },
        {
          "if": {
            "properties": {
              "InteractionType": {
                "const": "Combat"
              }
            }
          },
          "then": {
            "properties": {
              "EnemySpawnType": {
                "type": "string",
                "description": "Determines how enemy spawning is handled in combat locations",
                "enum": [
                  "AutoOnEnterArea",
                  "AfterInteraction",
                  "AfterItemUse",
                  "AfterAction",
                  "OverworldEnemies"
                ]
              },
              "KillEnemyDataIds": {
                "description": "The enemy data ids which are supposed to be killed",
                "type": "array",
                "items": {
                  "type": "integer"
                }
              },
              "ComplexCombatData": {
                "description": "If multiple different enemies are supposed to be killed in a single quest step, this typically is handled via items",
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "DataId": {
                      "description": "The enemy data id which is supposed to be killed",
                      "type": "integer"
                    },
                    "MinimumKillCount": {
                      "description": "Overworld mobs: If this number of mobs has been killed, will wait a bit before attempting to pull another mob to see if the quest progresses",
                      "type": "integer"
                    },
                    "RewardItemId": {
                      "type": "integer"
                    },
                    "RewardItemCount": {
                      "type": "integer"
                    },
                    "CompletionQuestVariablesFlags": {
                      "$ref": "https://git.carvel.li/liza/Questionable/raw/branch/master/Questionable.Model/common-schema.json#/$defs/CompletionFlags"
                    },
                    "IgnoreQuestMarker": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "DataId"
                  ]
                }
              },
              "CombatDelaySecondsAtStart": {
                "type": "number"
              }
            },
            "required": [
              "Position",
              "EnemySpawnType"
            ],
            "oneOf": [
              {
                "required": [
                  "KillEnemyDataIds"
                ]
              },
              {
                "required": [
                  "ComplexCombatData"
                ]
              }
            ]
          }
        },
        {
          "if": {
            "properties": {
              "InteractionType": {
                "const": "UseItem"
              },
              "ItemId": {
                "not": {
                  "const": 30362
                }
              }
            }
          },
          "then": {
            "required": [
              "Position"
            ]
          }
        },
        {
          "if": {
            "anyOf": [
              {
                "properties": {
                  "InteractionType": {
                    "const": "UseItem"
                  }
                }
              },
              {
                "properties": {
                  "InteractionType": {
                    "const": "Combat"
                  },
                  "EnemySpawnType": {
                    "const": "AfterItemUse"
                  }
                }
              }
            ]
          },
          "then": {
            "properties": {
              "GroundTarget": {
                "type": [
                  "boolean",
                  "null"
                ],
                "default": false
              }
            },
            "required": [
              "ItemId"
            ]
          }
        },
        {
          "if": {
            "properties": {
              "InteractionType": {
                "const": "EquipItem"
              }
            }
          },
          "then": {
            "required": [
              "ItemId"
            ]
          }
        },
        {
          "if": {
            "properties": {
              "InteractionType": {
                "anyOf": [
                  {
                    "const": "Emote"
                  },
                  {
                    "const": "AcceptQuest"
                  },
                  {
                    "const": "CompleteQuest"
                  },
                  {
                    "const": "SinglePlayerDuty"
                  }
                ]
              }
            }
          },
          "then": {
            "properties": {
              "Emote": {
                "type": "string",
                "description": "The emote to use",
                "enum": [
                  "stretch",
                  "wave",
                  "rally",
                  "deny",
                  "pray",
                  "slap",
                  "doubt",
                  "psych",
                  "cheer",
                  "happy",
                  "poke",
                  "flex",
                  "soothe",
                  "me",
                  "welcome",
                  "imperialsalute",
                  "pet",
                  "dance",
                  "respect",
                  "lookout",
                  "kneel",
                  "bow",
                  "uchiwasshoi",
                  "clap",
                  "victorypose",
                  "comfort"
                ]
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "InteractionType": {
                "const": "Emote"
              }
            }
          },
          "then": {
            "required": [
              "Position",
              "Emote"
            ]
          }
        },
        {
          "if": {
            "properties": {
              "InteractionType": {
                "anyOf": [
                  {
                    "const": "Say"
                  },
                  {
                    "const": "CompleteQuest"
                  }
                ]
              }
            }
          },
          "then": {
            "properties": {
              "ChatMessage": {
                "type": "object",
                "description": "The text to use with /say",
                "properties": {
                  "ExcelSheet": {
                    "type": "string"
                  },
                  "Key": {
                    "type": "string"
                  }
                },
                "required": [
                  "Key"
                ]
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "InteractionType": {
                "const": "Say"
              }
            }
          },
          "then": {
            "required": [
              "ChatMessage"
            ]
          }
        },
        {
          "if": {
            "properties": {
              "InteractionType": {
                "const": "Action"
              }
            }
          },
          "then": {
            "properties": {
              "Action": {
                "type": "string",
                "description": "The action to use",
                "enum": [
                  "Heavy Swing",
                  "Heavy Shot",
                  "Cure",
                  "Cure II",
                  "Esuna",
                  "Physick",
                  "Buffet (Sanuwa)",
                  "Buffet (Griffin)",
                  "Fumigate",
                  "Siphon Snout",
                  "Cannonfire",
                  "Red Gulal",
                  "Yellow Gulal",
                  "Blue Gulal",
                  "Electric Flux",
                  "Hop-step"
                ]
              }
            },
            "required": [
              "Action"
            ]
          }
        },
        {
          "if": {
            "properties": {
              "InteractionType": {
                "const": "Jump"
              }
            }
          },
          "then": {
            "properties": {
              "JumpDestination": {
                "type": "object",
                "properties": {
                  "Position": {
                    "$ref": "https://git.carvel.li/liza/Questionable/raw/branch/master/Questionable.Model/common-schema.json#/$defs/Vector3"
                  },
                  "StopDistance": {
                    "type": [
                      "number",
                      "null"
                    ],
                    "description": "Set if pathfinding should stop closer or further away from the default stop distance",
                    "exclusiveMinimum": 0
                  },
                  "DelaySeconds": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "Type": {
                    "type": "string",
                    "enum": [
                      "SingleJump",
                      "RepeatedJumps"
                    ],
                    "default": "SingleJump"
                  }
                },
                "required": [
                  "Position"
                ]
              }
            },
            "required": [
              "Position",
              "JumpDestination"
            ]
          }
        },
        {
          "if": {
            "properties": {
              "InteractionType": {
                "anyOf": [
                  {
                    "const": "Interact"
                  },
                  {
                    "const": "SinglePlayerDuty"
                  },
                  {
                    "const": "WaitForManualProgress"
                  },
                  {
                    "const": "AcceptQuest"
                  },
                  {
                    "const": "CompleteQuest"
                  },
                  {
                    "const": "Instruction"
                  },
                  {
                    "const": "Say"
                  },
                  {
                    "const": "Emote"
                  },
                  {
                    "const": "UseItem"
                  }
                ]
              }
            }
          },
          "then": {
            "properties": {
              "DialogueChoices": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "Type": {
                      "type": "string",
                      "enum": [
                        "YesNo",
                        "List"
                      ]
                    },
                    "ExcelSheet": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "Type"
                  ],
                  "allOf": [
                    {
                      "if": {
                        "properties": {
                          "Type": {
                            "const": "YesNo"
                          }
                        }
                      },
                      "then": {
                        "properties": {
                          "Prompt": {
                            "type": [
                              "string",
                              "integer"
                            ]
                          },
                          "Yes": {
                            "type": "boolean",
                            "default": true
                          }
                        },
                        "required": [
                          "Prompt",
                          "Yes"
                        ]
                      }
                    },
                    {
                      "if": {
                        "properties": {
                          "Type": {
                            "const": "List"
                          }
                        }
                      },
                      "then": {
                        "properties": {
                          "Prompt": {
                            "type": [
                              "string",
                              "integer",
                              "null"
                            ]
                          },
                          "Answer": {
                            "type": [
                              "string",
                              "integer"
                            ]
                          }
                        },
                        "required": [
                          "Prompt",
                          "Answer"
                        ]
                      }
                    }
                  ]
                }
              },
              "PointMenuChoices": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "minimum": 0
                }
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "InteractionType": {
                "const": "Duty"
              }
            }
          },
          "then": {
            "properties": {
              "ContentFinderConditionId": {
                "type": "integer",
                "exclusiveMinimum": 0,
                "exclusiveMaximum": 3000
              },
              "DataId": {
                "type": "null"
              },
              "Position": {
                "type": "null"
              }
            },
            "required": [
              "ContentFinderConditionId"
            ]
          }
        },
        {
          "if": {
            "properties": {
              "InteractionType": {
                "const": "WaitForNpcAtPosition"
              }
            }
          },
          "then": {
            "properties": {
              "NpcWaitDistance": {
                "type": "number",
                "exclusiveMinimum": 0
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "InteractionType": {
                "const": "AcceptQuest"
              }
            }
          },
          "then": {
            "properties": {
              "PickUpQuestId": {
                "type": [
                  "null",
                  "number",
                  "string"
                ],
                "description": "Determines the quest which should be accepted. If empty/null, accepts the quest corresponding to the file name."
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "InteractionType": {
                "const": "CompleteQuest"
              }
            }
          },
          "then": {
            "properties": {
              "TurnInQuestId": {
                "type": [
                  "null",
                  "number",
                  "string"
                ],
                "description": "Determines the quest which should be turned in. If empty/null, turns in the quest corresponding to the file name."
              },
              "NextQuestId": {
                "type": [
                  "null",
                  "number",
                  "string"
                ],
                "description": "For quest chains (e.g. DT healer role quests) Which quest to do next, given that you meet the required level."
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "InteractionType": {
                "const": "Craft"
              }
            }
          },
          "then": {
            "properties": {
              "ItemCount": {
                "type": "number"
              }
            },
            "required": [
              "ItemId",
              "ItemCount"
            ]
          }
        }
      ],
      "not": {
        "anyOf": [
          {
            "required": [
              "SkipIf"
            ]
          }
        ]
      }
    }
  }
}