diff --git a/cmake/FindMySQL.cmake b/cmake/FindMySQL.cmake index e629b8ae3..d15f7abde 100644 --- a/cmake/FindMySQL.cmake +++ b/cmake/FindMySQL.cmake @@ -18,28 +18,39 @@ if( UNIX ) "preferred path to MySQL (mysql_config)" ) - find_program(MYSQL_CONFIG mysql_config + # try mariadb first + find_program(MYSQL_CONFIG mariadb_config ${MYSQL_CONFIG_PREFER_PATH} /usr/local/mysql/bin/ /usr/local/bin/ /usr/bin/ ) + if( NOT MYSQL_CONFIG ) + # fallback to mysql + find_program(MYSQL_CONFIG mysql_config + ${MYSQL_CONFIG_PREFER_PATH} + /usr/local/mysql/bin/ + /usr/local/bin/ + /usr/bin/ + ) + endif() + if( MYSQL_CONFIG ) message(STATUS "Using mysql-config: ${MYSQL_CONFIG}") # set INCLUDE_DIR - exec_program(${MYSQL_CONFIG} - ARGS --include + execute_process(COMMAND ${MYSQL_CONFIG} --include OUTPUT_VARIABLE MY_TMP + OUTPUT_STRIP_TRAILING_WHITESPACE ) string(REGEX REPLACE "-I([^ ]*)( .*)?" "\\1" MY_TMP "${MY_TMP}") set(MYSQL_ADD_INCLUDE_PATH ${MY_TMP} CACHE FILEPATH INTERNAL) #message("[DEBUG] MYSQL ADD_INCLUDE_PATH : ${MYSQL_ADD_INCLUDE_PATH}") # set LIBRARY_DIR - exec_program(${MYSQL_CONFIG} - ARGS --libs_r + execute_process(COMMAND ${MYSQL_CONFIG} --libs_r OUTPUT_VARIABLE MY_TMP + OUTPUT_STRIP_TRAILING_WHITESPACE ) set(MYSQL_ADD_LIBRARIES "") string(REGEX MATCHALL "-l[^ ]*" MYSQL_LIB_LIST "${MY_TMP}") diff --git a/data/EncounterTimelines/IfritNormal.json b/data/EncounterTimelines/IfritNormal.json new file mode 100644 index 000000000..f78401f86 --- /dev/null +++ b/data/EncounterTimelines/IfritNormal.json @@ -0,0 +1,1082 @@ +{ + "actors": [ + { + "hp": 13884, + "id": 1, + "layoutId": 4126276, + "name": "Ifrit", + "phases": [ + { + "description": "", + "id": 1, + "name": "Auto-attack", + "timepoints": [ + { + "data": { + "actionId": 872, + "selectorIndex": 0, + "selectorName": "", + "snapshot": false, + "snapshotTime": 0, + "sourceActor": "Ifrit", + "targetType": "target" + }, + "description": "Auto attack", + "duration": 2500, + "type": "castAction" + } + ] + }, + { + "description": "", + "id": 2, + "name": "Phase 1", + "timepoints": [ + { + "data": { + "actionId": 453, + "selectorIndex": 0, + "selectorName": "", + "snapshot": false, + "snapshotTime": 0, + "sourceActor": "Ifrit", + "targetType": "target" + }, + "description": "Incinerate > VB > Incinerate > Incinerate", + "duration": 8000, + "type": "castAction" + }, + { + "data": { + "actionId": 454, + "selectorIndex": 0, + "selectorName": "Vulcan Burst", + "snapshot": false, + "snapshotTime": 0, + "sourceActor": "Ifrit", + "targetType": "self" + }, + "description": "VB", + "duration": 8000, + "type": "castAction" + }, + { + "data": { + "actionId": 453, + "selectorIndex": 0, + "selectorName": "", + "snapshot": false, + "snapshotTime": 0, + "sourceActor": "Ifrit", + "targetType": "target" + }, + "description": "Incinerate", + "duration": 8000, + "type": "castAction" + }, + { + "data": { + "actionId": 453, + "selectorIndex": 0, + "selectorName": "", + "snapshot": false, + "snapshotTime": 0, + "sourceActor": "Ifrit", + "targetType": "target" + }, + "description": "Incinerate", + "duration": 8000, + "type": "castAction" + } + ] + }, + { + "description": "", + "id": 3, + "name": "Phase 2 Start", + "timepoints": [ + { + "data": { + "bgmId": 163 + }, + "description": "", + "duration": 0, + "type": "setBGM" + }, + { + "data": { + "battleTalkId": 2939, + "handlerActorName": "Ifrit", + "kind": 1, + "nameId": 2961, + "params": [ + 0 + ], + "talkerActorName": "Ifrit" + }, + "description": "Succumb to the inferno", + "duration": 1500, + "type": "battleTalk" + }, + { + "data": { + "actionId": 453, + "selectorIndex": 0, + "selectorName": "", + "snapshot": false, + "snapshotTime": 0, + "sourceActor": "Ifrit", + "targetType": "target" + }, + "description": "Incinerate", + "duration": 8000, + "type": "castAction" + }, + { + "data": { + "actionId": 454, + "selectorIndex": 0, + "selectorName": "", + "snapshot": false, + "snapshotTime": 0, + "sourceActor": "Ifrit", + "targetType": "self" + }, + "description": "Vulcan Burst", + "duration": 8000, + "type": "castAction" + }, + { + "data": { + "conditionId": 4, + "conditionStr": "If Ifrit has 51% < HP < 70%, loop Ifrit->Phase 2 Main", + "enabled": true + }, + "description": "", + "duration": 5000, + "type": "setCondition" + } + ] + }, + { + "description": "", + "id": 4, + "name": "Phase 2 Main", + "timepoints": [ + { + "data": { + "actionId": 453, + "selectorIndex": 0, + "selectorName": "", + "snapshot": false, + "snapshotTime": 0, + "sourceActor": "Ifrit", + "targetType": "target" + }, + "description": "Incinerate", + "duration": 8000, + "type": "castAction" + }, + { + "data": { + "selectorName": "Eruption", + "sourceActor": "Ifrit" + }, + "description": "", + "duration": 0, + "type": "snapshot" + }, + { + "data": { + "actionId": 455, + "selectorIndex": 0, + "selectorName": "Eruption", + "snapshot": false, + "snapshotTime": 0, + "sourceActor": "Ifrit", + "targetType": "self" + }, + "description": "Eruption", + "duration": 0, + "type": "castAction" + }, + { + "data": { + "conditionId": 11, + "conditionStr": "If Ifrit casts Action#455, loop Ifrit Control->Eruption", + "enabled": true + }, + "description": "", + "duration": 8000, + "type": "setCondition" + } + ] + }, + { + "description": "", + "id": 5, + "name": "Nail Spawn", + "timepoints": [ + { + "data": { + "battleTalkId": 2939, + "handlerActorName": "Ifrit", + "kind": 1, + "nameId": 2961, + "params": [ + 0 + ], + "talkerActorName": "Ifrit" + }, + "description": "Surrender thyself to the fires of judgment", + "duration": 5000, + "type": "battleTalk" + }, + { + "data": { + "flags": 19, + "hateSource": { + "hateType": "", + "source": "" + }, + "spawnActor": "Ifrit Nail 1" + }, + "description": "", + "duration": 1500, + "type": "bNpcSpawn" + }, + { + "data": { + "conditionId": 6, + "conditionStr": "If Ifrit state is Combat, loop Ifrit->Phase 1", + "enabled": true + }, + "description": "", + "duration": 0, + "type": "setCondition" + }, + { + "data": {}, + "description": "", + "duration": 36000, + "type": "idle" + }, + { + "data": { + "conditionId": 8, + "conditionStr": "If Ifrit state is Combat, push Ifrit->Hellfire", + "enabled": true + }, + "description": "", + "duration": 0, + "type": "setCondition" + } + ] + }, + { + "description": "", + "id": 7, + "name": "Hellfire", + "timepoints": [ + { + "data": { + "despawnActor": "Ifrit Nail 1" + }, + "description": "Despawn nail if up", + "duration": 0, + "type": "bNpcDespawn" + }, + { + "data": { + "conditionId": 7, + "conditionStr": "If Ifrit Nail 1 state is Dead, push Ifrit->Hellfire", + "enabled": false + }, + "description": "", + "duration": 0, + "type": "setCondition" + }, + { + "data": { + "conditionId": 6, + "conditionStr": "If Ifrit state is Combat, loop Ifrit->Phase 1", + "enabled": false + }, + "description": "", + "duration": 0, + "type": "setCondition" + }, + { + "data": { + "actorName": "Ifrit", + "pos": [ + 0, + 0, + 0 + ], + "rot": 0 + }, + "description": "", + "duration": 2000, + "type": "setPos" + }, + { + "data": { + "flags": 119, + "targetActor": "" + }, + "description": "", + "duration": 3000, + "type": "bNpcFlags" + }, + { + "data": { + "actionId": 458, + "selectorIndex": 0, + "selectorName": "", + "snapshot": false, + "snapshotTime": 0, + "sourceActor": "Ifrit", + "targetType": "self" + }, + "description": "", + "duration": 2500, + "type": "castAction" + }, + { + "data": { + "actorName": "Ifrit", + "pos": [ + 0, + -10, + 0 + ], + "rot": 0 + }, + "description": "", + "duration": 8000, + "type": "setPos" + }, + { + "data": { + "flags": 16, + "targetActor": "" + }, + "description": "", + "duration": 0, + "type": "bNpcFlags" + }, + { + "data": { + "conditionId": 9, + "conditionStr": "If Ifrit state is Combat, loop Ifrit->Final Phase", + "enabled": true + }, + "description": "Enable final phase", + "duration": 0, + "type": "setCondition" + } + ] + }, + { + "description": "", + "id": 6, + "name": "Final Phase", + "timepoints": [ + { + "data": { + "actionId": 455, + "selectorIndex": 0, + "selectorName": "", + "snapshot": false, + "snapshotTime": 0, + "sourceActor": "Ifrit", + "targetType": "self" + }, + "description": "Eruption telegraph", + "duration": 8000, + "type": "castAction" + }, + { + "data": { + "actionId": 453, + "selectorIndex": 0, + "selectorName": "", + "snapshot": false, + "snapshotTime": 0, + "sourceActor": "Ifrit", + "targetType": "target" + }, + "description": "Incinerate Final Phase", + "duration": 8000, + "type": "castAction" + }, + { + "data": { + "actionId": 456, + "selectorIndex": 0, + "selectorName": "", + "snapshot": false, + "snapshotTime": 0, + "sourceActor": "Ifrit", + "targetType": "self" + }, + "description": "Plumes telegraph", + "duration": 0, + "type": "castAction" + }, + { + "data": { + "conditionId": 12, + "conditionStr": "If Ifrit->Final Phase is active, push Ifrit Control->Plumes Loop", + "enabled": true + }, + "description": "", + "duration": 16000, + "type": "setCondition" + } + ] + }, + { + "description": "", + "id": 8, + "name": "Reset", + "timepoints": [ + { + "data": { + "flags": 16, + "targetActor": "" + }, + "description": "", + "duration": 0, + "type": "bNpcFlags" + }, + { + "data": {}, + "description": "todo: despawn subactors and anything else spawned in phases", + "duration": 5000, + "type": "idle" + } + ] + } + ], + "subactors": [], + "type": "bnpc" + }, + { + "hp": 445, + "id": 2, + "layoutId": 4126284, + "name": "Ifrit Control", + "phases": [ + { + "description": "", + "id": 1, + "name": "Eruption", + "timepoints": [ + { + "data": { + "selectorName": "Eruption", + "sourceActor": "Ifrit Control " + }, + "description": "", + "duration": 0, + "type": "snapshot" + }, + { + "data": { + "actionId": 733, + "selectorIndex": 0, + "selectorName": "Eruption", + "snapshot": false, + "snapshotTime": 0, + "sourceActor": "Ifrit Control ", + "targetType": "selector" + }, + "description": "Subactor 1 Eruption", + "duration": 8000, + "type": "castAction" + } + ] + }, + { + "description": "", + "id": 2, + "name": "Plumes Loop", + "timepoints": [ + { + "data": { + "actorName": "Ifrit Control ", + "pos": [ + -10, + 0, + 10 + ], + "rot": 0 + }, + "description": "Move plumes", + "duration": 0, + "type": "setPos" + }, + { + "data": { + "actorName": "Ifrit Control ", + "pos": [ + -10, + 0, + -10 + ], + "rot": 0 + }, + "description": "", + "duration": 0, + "type": "setPos" + }, + { + "data": { + "actorName": "Ifrit Control ", + "pos": [ + 10, + 0, + 10 + ], + "rot": 0 + }, + "description": "", + "duration": 0, + "type": "setPos" + }, + { + "data": { + "actorName": "Ifrit Control ", + "pos": [ + 10, + 0, + -10 + ], + "rot": 0 + }, + "description": "", + "duration": 0, + "type": "setPos" + }, + { + "data": { + "actionId": 734, + "selectorIndex": 0, + "selectorName": "", + "snapshot": false, + "snapshotTime": 0, + "sourceActor": "Ifrit Control ", + "targetType": "self" + }, + "description": "Cast plumes", + "duration": 0, + "type": "castAction" + }, + { + "data": { + "actionId": 734, + "selectorIndex": 0, + "selectorName": "", + "snapshot": false, + "snapshotTime": 0, + "sourceActor": "Ifrit Control ", + "targetType": "self" + }, + "description": "", + "duration": 0, + "type": "castAction" + }, + { + "data": { + "actionId": 734, + "selectorIndex": 0, + "selectorName": "", + "snapshot": false, + "snapshotTime": 0, + "sourceActor": "Ifrit Control ", + "targetType": "self" + }, + "description": "", + "duration": 0, + "type": "castAction" + }, + { + "data": { + "actionId": 734, + "selectorIndex": 0, + "selectorName": "", + "snapshot": false, + "snapshotTime": 0, + "sourceActor": "Ifrit Control ", + "targetType": "self" + }, + "description": "", + "duration": 4000, + "type": "castAction" + }, + { + "data": { + "actorName": "Ifrit Control ", + "pos": [ + 0, + 0, + -20 + ], + "rot": 0 + }, + "description": "Move plumes out", + "duration": 0, + "type": "setPos" + }, + { + "data": { + "actorName": "Ifrit Control ", + "pos": [ + 0, + 0, + 20 + ], + "rot": 0 + }, + "description": "", + "duration": 0, + "type": "setPos" + }, + { + "data": { + "actorName": "Ifrit Control ", + "pos": [ + -20, + 0, + 0 + ], + "rot": 0 + }, + "description": "", + "duration": 0, + "type": "setPos" + }, + { + "data": { + "actorName": "Ifrit Control ", + "pos": [ + -20, + 0, + 20 + ], + "rot": 0 + }, + "description": "", + "duration": 0, + "type": "setPos" + }, + { + "data": { + "actorName": "Ifrit Control ", + "pos": [ + -15, + 0, + 15 + ], + "rot": 0 + }, + "description": "", + "duration": 0, + "type": "setPos" + }, + { + "data": { + "actorName": "Ifrit Control ", + "pos": [ + -15, + 0, + -15 + ], + "rot": 0 + }, + "description": "", + "duration": 0, + "type": "setPos" + }, + { + "data": { + "actorName": "Ifrit Control ", + "pos": [ + 15, + 0, + -15 + ], + "rot": 0 + }, + "description": "", + "duration": 0, + "type": "setPos" + }, + { + "data": { + "actorName": "Ifrit Control ", + "pos": [ + 15, + 0, + 15 + ], + "rot": 0 + }, + "description": "", + "duration": 200, + "type": "setPos" + }, + { + "data": { + "actionId": 734, + "selectorIndex": 0, + "selectorName": "", + "snapshot": false, + "snapshotTime": 0, + "sourceActor": "Ifrit Control ", + "targetType": "self" + }, + "description": "Cast plumes out", + "duration": 0, + "type": "castAction" + }, + { + "data": { + "actionId": 734, + "selectorIndex": 0, + "selectorName": "", + "snapshot": false, + "snapshotTime": 0, + "sourceActor": "Ifrit Control ", + "targetType": "self" + }, + "description": "", + "duration": 0, + "type": "castAction" + }, + { + "data": { + "actionId": 734, + "selectorIndex": 0, + "selectorName": "", + "snapshot": false, + "snapshotTime": 0, + "sourceActor": "Ifrit Control ", + "targetType": "self" + }, + "description": "", + "duration": 0, + "type": "castAction" + }, + { + "data": { + "actionId": 734, + "selectorIndex": 0, + "selectorName": "", + "snapshot": false, + "snapshotTime": 0, + "sourceActor": "Ifrit Control ", + "targetType": "self" + }, + "description": "", + "duration": 0, + "type": "castAction" + }, + { + "data": { + "actionId": 734, + "selectorIndex": 0, + "selectorName": "", + "snapshot": false, + "snapshotTime": 0, + "sourceActor": "Ifrit Control ", + "targetType": "self" + }, + "description": "", + "duration": 0, + "type": "castAction" + }, + { + "data": { + "actionId": 734, + "selectorIndex": 0, + "selectorName": "", + "snapshot": false, + "snapshotTime": 0, + "sourceActor": "Ifrit Control ", + "targetType": "self" + }, + "description": "", + "duration": 0, + "type": "castAction" + }, + { + "data": { + "actionId": 734, + "selectorIndex": 0, + "selectorName": "", + "snapshot": false, + "snapshotTime": 0, + "sourceActor": "Ifrit Control ", + "targetType": "self" + }, + "description": "", + "duration": 0, + "type": "castAction" + }, + { + "data": { + "actionId": 734, + "selectorIndex": 0, + "selectorName": "", + "snapshot": false, + "snapshotTime": 0, + "sourceActor": "Ifrit Control ", + "targetType": "self" + }, + "description": "", + "duration": 0, + "type": "castAction" + } + ] + }, + { + "description": "", + "id": 3, + "name": "Setup", + "timepoints": [ + { + "data": {}, + "description": "", + "duration": 5000, + "type": "idle" + } + ] + } + ], + "subactors": [ + "Ifrit Control ", + "Ifrit Control ", + "Ifrit Control ", + "Ifrit Control ", + "Ifrit Control ", + "Ifrit Control ", + "Ifrit Control ", + "Ifrit Control " + ], + "type": "bnpc" + }, + { + "hp": 445, + "id": 3, + "layoutId": 4126281, + "name": "Ifrit Nail 1", + "phases": [ + { + "description": "", + "id": 1, + "name": "Phase 1", + "timepoints": [] + } + ], + "subactors": [], + "type": "bnpc" + } + ], + "conditions": [ + { + "condition": "combatState", + "description": "", + "enabled": true, + "id": 10, + "loop": false, + "paramData": { + "combatState": 0, + "sourceActor": "Ifrit" + }, + "targetActor": "Ifrit", + "targetPhase": "Reset" + }, + { + "condition": "combatState", + "description": "", + "enabled": false, + "id": 1, + "loop": true, + "paramData": { + "combatState": 1, + "sourceActor": "Ifrit" + }, + "targetActor": "Ifrit", + "targetPhase": "Auto-attack" + }, + { + "condition": "hpPctBetween", + "description": "", + "enabled": true, + "id": 2, + "loop": true, + "paramData": { + "hpMax": 100, + "hpMin": 71, + "sourceActor": "Ifrit" + }, + "targetActor": "Ifrit", + "targetPhase": "Phase 1" + }, + { + "condition": "hpPctBetween", + "description": "", + "enabled": true, + "id": 3, + "loop": false, + "paramData": { + "hpMax": 71, + "hpMin": 50, + "sourceActor": "Ifrit" + }, + "targetActor": "Ifrit", + "targetPhase": "Phase 2 Start" + }, + { + "condition": "hpPctBetween", + "description": "", + "enabled": false, + "id": 4, + "loop": true, + "paramData": { + "hpMax": 70, + "hpMin": 50, + "sourceActor": "Ifrit" + }, + "targetActor": "Ifrit", + "targetPhase": "Phase 2 Main" + }, + { + "condition": "hpPctBetween", + "description": "", + "enabled": true, + "id": 5, + "loop": false, + "paramData": { + "hpMax": 50, + "hpMin": 0, + "sourceActor": "Ifrit" + }, + "targetActor": "Ifrit", + "targetPhase": "Nail Spawn" + }, + { + "condition": "combatState", + "description": "", + "enabled": false, + "id": 6, + "loop": true, + "paramData": { + "combatState": 1, + "sourceActor": "Ifrit" + }, + "targetActor": "Ifrit", + "targetPhase": "Phase 1" + }, + { + "condition": "combatState", + "description": "", + "enabled": true, + "id": 7, + "loop": false, + "paramData": { + "combatState": 5, + "sourceActor": "Ifrit Nail 1" + }, + "targetActor": "Ifrit", + "targetPhase": "Hellfire" + }, + { + "condition": "combatState", + "description": "", + "enabled": false, + "id": 8, + "loop": false, + "paramData": { + "combatState": 1, + "sourceActor": "Ifrit" + }, + "targetActor": "Ifrit", + "targetPhase": "Hellfire" + }, + { + "condition": "combatState", + "description": "", + "enabled": false, + "id": 9, + "loop": true, + "paramData": { + "combatState": 1, + "sourceActor": "Ifrit" + }, + "targetActor": "Ifrit", + "targetPhase": "Final Phase" + }, + { + "condition": "getAction", + "description": "", + "enabled": true, + "id": 11, + "loop": true, + "paramData": { + "actionId": 455, + "sourceActor": "Ifrit" + }, + "targetActor": "Ifrit Control", + "targetPhase": "Eruption" + }, + { + "condition": "phaseActive", + "description": "", + "enabled": false, + "id": 12, + "loop": false, + "paramData": { + "phaseName": "Final Phase", + "sourceActor": "Ifrit" + }, + "targetActor": "Ifrit Control", + "targetPhase": "Plumes Loop" + }, + { + "condition": "combatState", + "description": "", + "enabled": true, + "id": 13, + "loop": false, + "paramData": { + "combatState": 1, + "sourceActor": "Ifrit" + }, + "targetActor": "Ifrit Control", + "targetPhase": "Setup" + } + ], + "name": "Brand new timeline", + "selectors": [ + { + "count": 1, + "description": "", + "excludeSelectorName": "", + "fillRandomEntries": true, + "filters": [ + { + "negate": true, + "param": 0, + "type": "topAggro" + } + ], + "id": 1, + "name": "Eruption" + } + ], + "version": 8 +} \ No newline at end of file diff --git a/data/actions/IfritNormal.json b/data/actions/IfritNormal.json new file mode 100644 index 000000000..c611f6596 --- /dev/null +++ b/data/actions/IfritNormal.json @@ -0,0 +1,104 @@ +{ + "872": { + "name": "Auto Attack", + "potency": 100, + "comboPotency": 0, + "flankPotency": 0, + "frontPotency": 0, + "rearPotency": 0, + "curePotency": 0, + "restorePercentage": 0, + "nextCombo": [], + "statuses": { + "caster": [], + "target": [] + } + }, + "453": { + "name": "Incinerate", + "potency": 100, + "comboPotency": 0, + "flankPotency": 0, + "frontPotency": 0, + "rearPotency": 0, + "curePotency": 0, + "restorePercentage": 0, + "nextCombo": [], + "statuses": { + "caster": [], + "target": [] + } + }, + "454": { + "name": "Vulcan Burst", + "potency": 100, + "comboPotency": 0, + "flankPotency": 0, + "frontPotency": 0, + "rearPotency": 0, + "curePotency": 0, + "restorePercentage": 0, + "nextCombo": [], + "statuses": { + "caster": [], + "target": [] + } + }, + "458": { + "name": "Hellfire", + "potency": 400, + "comboPotency": 0, + "flankPotency": 0, + "frontPotency": 0, + "rearPotency": 0, + "curePotency": 0, + "restorePercentage": 0, + "nextCombo": [], + "statuses": { + "caster": [ + { + "id": 394, + "duration": 8000, + "modifiers": [ + { + "modifier": "DamageTakenPercent", + "value": -100 + } + ] + } + ], + "target": [] + } + }, + "733": { + "name": "Eruption", + "potency": 200, + "comboPotency": 0, + "flankPotency": 0, + "frontPotency": 0, + "rearPotency": 0, + "curePotency": 0, + "restorePercentage": 0, + "nextCombo": [], + "statuses": { + "caster": [], + "target": [] + } + }, + "734": { + "name": "Radiant Plume", + "potency": 200, + "comboPotency": 0, + "flankPotency": 0, + "frontPotency": 0, + "rearPotency": 0, + "curePotency": 0, + "restorePercentage": 0, + "nextCombo": [], + "statuses": { + "caster": [], + "target": [] + } + } + +} \ No newline at end of file diff --git a/data/actions/player.json b/data/actions/player.json index 149d05aae..c266e805b 100644 --- a/data/actions/player.json +++ b/data/actions/player.json @@ -1,7 +1,7 @@ { "7": { "name": "Attack", - "potency": 0, + "potency": 110, "comboPotency": 0, "flankPotency": 0, "frontPotency": 0, @@ -16,7 +16,7 @@ }, "8": { "name": "Shot", - "potency": 0, + "potency": 100, "comboPotency": 0, "flankPotency": 0, "frontPotency": 0, @@ -398,7 +398,18 @@ "restorePercentage": 0, "nextCombo": [], "statuses": { - "caster": [], + "caster": [ + { + "id": 83, + "duration": 20000, + "modifiers": [ + { + "modifier": "DefensePercent", + "value": 20 + } + ] + } + ], "target": [] } }, @@ -414,7 +425,18 @@ "nextCombo": [], "statuses": { "caster": [], - "target": [] + "target": [ + { + "id": 244, + "duration": 30000, + "modifiers": [ + { + "modifier": "TickDamage", + "value": 20 + } + ] + } + ] } }, "34": { @@ -478,7 +500,18 @@ 45 ], "statuses": { - "caster": [], + "caster": [ + { + "id": 85, + "duration": 24000, + "modifiers": [ + { + "modifier": "DamageDealtPercent", + "value": 20 + } + ] + } + ], "target": [] } }, @@ -493,7 +526,18 @@ "restorePercentage": 0, "nextCombo": [], "statuses": { - "caster": [], + "caster": [ + { + "id": 86, + "duration": 20000, + "modifiers": [ + { + "modifier": "AttackPowerPercent", + "value": 50 + } + ] + } + ], "target": [] } }, @@ -523,7 +567,18 @@ "restorePercentage": 0, "nextCombo": [], "statuses": { - "caster": [], + "caster": [ + { + "id": 87, + "duration": 20000, + "modifiers": [ + { + "modifier": "HPPercent", + "value": 20 + } + ] + } + ], "target": [] } }, @@ -574,7 +629,7 @@ }, "44": { "name": "Vengeance", - "potency": 50, + "potency": 0, "comboPotency": 0, "flankPotency": 0, "frontPotency": 0, @@ -583,7 +638,18 @@ "restorePercentage": 0, "nextCombo": [], "statuses": { - "caster": [], + "caster": [ + { + "id": 89, + "duration": 20000, + "modifiers": [ + { + "modifier": "ReflectPhysical", + "value": 50 + } + ] + } + ], "target": [] } }, @@ -643,7 +709,34 @@ "restorePercentage": 0, "nextCombo": [], "statuses": { - "caster": [], + "caster": [ + { + "id": 91, + "duration": 0, + "modifiers": [ + { + "modifier": "HPPercent", + "value": 25 + }, + { + "modifier": "DamageDealtPercent", + "value": -25 + }, + { + "modifier": "HealingMagicRecoveryPercent", + "value": 20 + }, + { + "modifier": "AccuracyPercent", + "value": 5 + }, + { + "modifier": "EnmityPercent", + "value": 20 + } + ] + } + ], "target": [] } }, @@ -703,7 +796,12 @@ "restorePercentage": 0, "nextCombo": [], "statuses": { - "caster": [], + "caster": [ + { + "id": 97, + "duration": 30000 + } + ], "target": [] } }, @@ -1176,7 +1274,19 @@ "restorePercentage": 0, "nextCombo": [], "statuses": { - "caster": [], + "caster": [ + { + "id": 116, + "duration": 10000, + "flag": 4096, + "modifiers": [ + { + "modifier": "CriticalHitPercent", + "value": 100 + } + ] + } + ], "target": [] } }, @@ -2454,7 +2564,38 @@ "nextCombo": [], "statuses": { "caster": [], - "target": [] + "target": [ + { + "id": 180, + "duration": 24000, + "modifiers": [ + { + "modifier": "TickDamage", + "value": 35 + } + ] + }, + { + "id": 191, + "duration": 24000, + "modifiers": [ + { + "modifier": "HealingRecoveryPercent", + "value": -20 + } + ] + }, + { + "id": 240, + "duration": 24000, + "modifiers": [ + { + "modifier": "HeavyPercent", + "value": 40 + } + ] + } + ] } }, "169": { diff --git a/deps/datReader/DatCategories/bg/lgb.h b/deps/datReader/DatCategories/bg/lgb.h index c5c99f11f..d0c3f29bd 100644 --- a/deps/datReader/DatCategories/bg/lgb.h +++ b/deps/datReader/DatCategories/bg/lgb.h @@ -227,6 +227,8 @@ struct LGB_GROUP memcpy( (char*)&refs[0], buf + offset + header.LayerSetRef + layerSetReferencedList.LayerSets, layerSetReferencedList.LayerSetCount * sizeof( LayerSetReferenced ) ); } + entries.reserve( header.entryCount ); + const auto entriesOffset = offset + header.entriesOffset; for( auto i = 0; i < header.entryCount; ++i ) { @@ -235,41 +237,53 @@ struct LGB_GROUP try { const auto type = *reinterpret_cast< LgbEntryType* >( buf + entryOffset ); - if( type == LgbEntryType::BgParts ) - { - entries.push_back( std::make_shared< LGB_BGPARTS_ENTRY >( buf, entryOffset ) ); - } - else if( type == LgbEntryType::Gimmick ) - { - entries.push_back( std::make_shared< LGB_GIMMICK_ENTRY >( buf, entryOffset ) ); - } - else if( type == LgbEntryType::EventNpc ) - { - entries.push_back( std::make_shared< LGB_ENPC_ENTRY >( buf, entryOffset ) ); - } - else if( type == LgbEntryType::EventObject ) - { - entries.push_back( std::make_shared< LGB_EOBJ_ENTRY >( buf, entryOffset ) ); - } - else if( type == LgbEntryType::ExitRange ) - { - entries.push_back( std::make_shared< LGB_EXIT_RANGE_ENTRY >( buf, entryOffset ) ); - } - else if( type == LgbEntryType::EventRange ) - { - entries.push_back( std::make_shared< LGB_EVENT_RANGE_ENTRY >( buf, entryOffset ) ); - } - else if( type == LgbEntryType::PopRange ) - { - entries.push_back( std::make_shared< LGB_POP_RANGE_ENTRY >( buf, entryOffset ) ); - } - else if( type == LgbEntryType::MapRange ) - { - entries.push_back( std::make_shared< LGB_MAP_RANGE_ENTRY >( buf, entryOffset ) ); - } - else + switch( type ) { - entries.push_back( std::make_shared< LgbEntry >( buf, entryOffset ) ); + case LgbEntryType::BgParts: + { + entries.emplace_back( std::make_shared< LGB_BGPARTS_ENTRY >( buf, entryOffset ) ); + break; + } + case LgbEntryType::Gimmick: + { + entries.emplace_back( std::make_shared< LGB_GIMMICK_ENTRY >( buf, entryOffset ) ); + break; + } + case LgbEntryType::EventNpc: + { + entries.emplace_back( std::make_shared< LGB_ENPC_ENTRY >( buf, entryOffset ) ); + break; + } + case LgbEntryType::EventObject: + { + entries.emplace_back( std::make_shared< LGB_EOBJ_ENTRY >( buf, entryOffset ) ); + break; + } + case LgbEntryType::ExitRange: + { + entries.emplace_back( std::make_shared< LGB_EXIT_RANGE_ENTRY >( buf, entryOffset ) ); + break; + } + case LgbEntryType::EventRange: + { + entries.emplace_back( std::make_shared< LGB_EVENT_RANGE_ENTRY >( buf, entryOffset ) ); + break; + } + case LgbEntryType::PopRange: + { + entries.emplace_back( std::make_shared< LGB_POP_RANGE_ENTRY >( buf, entryOffset ) ); + break; + } + case LgbEntryType::MapRange: + { + entries.emplace_back( std::make_shared< LGB_MAP_RANGE_ENTRY >( buf, entryOffset ) ); + break; + } + default: + { + entries.emplace_back( std::make_shared< LgbEntry >( buf, entryOffset ) ); + break; + } } } catch( std::exception& e ) diff --git a/deps/datReader/Exd.cpp b/deps/datReader/Exd.cpp index 74aae36e0..b1a2a2b5f 100644 --- a/deps/datReader/Exd.cpp +++ b/deps/datReader/Exd.cpp @@ -7,50 +7,6 @@ using xiv::utils::bparse::extract; - -namespace xiv::exd -{ - struct ExdHeader - { - char magic[0x4]; - uint16_t unknown; - uint16_t unknown2; - uint32_t index_size; - }; - - struct ExdRecordIndex - { - uint32_t id; - uint32_t offset; - }; -} - -namespace xiv::utils::bparse { -template<> - inline void reorder< xiv::exd::ExdHeader >( xiv::exd::ExdHeader& i_struct ) - { - for( int32_t i = 0; i < 0x4; ++i ) - { - xiv::utils::bparse::reorder( i_struct.magic[ i ] ); - } - i_struct.unknown = xiv::utils::bparse::byteswap( i_struct.unknown ); - xiv::utils::bparse::reorder( i_struct.unknown ); - i_struct.unknown2 = xiv::utils::bparse::byteswap( i_struct.unknown2 ); - xiv::utils::bparse::reorder( i_struct.unknown2 ); - i_struct.index_size = xiv::utils::bparse::byteswap( i_struct.index_size ); - xiv::utils::bparse::reorder( i_struct.index_size ); - } - - template<> - inline void reorder< xiv::exd::ExdRecordIndex >( xiv::exd::ExdRecordIndex& i_struct ) - { - i_struct.id = xiv::utils::bparse::byteswap( i_struct.id ); - xiv::utils::bparse::reorder( i_struct.id ); - i_struct.offset = xiv::utils::bparse::byteswap( i_struct.offset ); - xiv::utils::bparse::reorder( i_struct.offset ); - } -}; - namespace xiv::exd { Exd::Exd( std::shared_ptr< Exh > i_exh, const std::vector< std::shared_ptr< dat::File>>& i_files ) @@ -68,16 +24,16 @@ namespace xiv::exd std::istringstream iss( std::string( dataCpy.begin(), dataCpy.end() ) ); // Extract the header and skip to the record indices - auto exd_header = extract< ExdHeader >( iss ); + auto exd_header = extract< ExdHeaderMinimal >( iss ); iss.seekg( 0x20 ); // Preallocate and extract the record_indices - const uint32_t record_count = exd_header.index_size / sizeof( ExdRecordIndex ); - std::vector< ExdRecordIndex > record_indices; + const uint32_t record_count = exd_header.index_size / sizeof( ExdRecordIndexData ); + std::vector< ExdRecordIndexData > record_indices; record_indices.reserve( record_count ); for( uint32_t i = 0; i < record_count; ++i ) { - auto recordIndex = extract< ExdRecordIndex >( iss ); + auto recordIndex = extract< ExdRecordIndexData >( iss ); _idCache[ recordIndex.id ] = ExdCacheEntry{ file_ptr, recordIndex.offset }; } } @@ -290,16 +246,16 @@ namespace xiv::exd std::istringstream iss( std::string( dataCpy.begin(), dataCpy.end() ) ); // Extract the header and skip to the record indices - auto exd_header = extract< ExdHeader >( iss ); + auto exd_header = extract< ExdHeaderMinimal >( iss ); iss.seekg( 0x20 ); // Preallocate and extract the record_indices - const uint32_t record_count = exd_header.index_size / sizeof( ExdRecordIndex ); - std::vector< ExdRecordIndex > record_indices; + const uint32_t record_count = exd_header.index_size / sizeof( ExdRecordIndexData ); + std::vector< ExdRecordIndexData > record_indices; record_indices.reserve( record_count ); for( uint32_t i = 0; i < record_count; ++i ) { - record_indices.emplace_back( extract< ExdRecordIndex >( iss ) ); + record_indices.emplace_back( extract< ExdRecordIndexData >( iss ) ); } for( auto& record_index : record_indices ) diff --git a/deps/datReader/Exd.h b/deps/datReader/Exd.h index 8cf406589..e08f6e54b 100644 --- a/deps/datReader/Exd.h +++ b/deps/datReader/Exd.h @@ -2,6 +2,7 @@ #include #include +#include #include @@ -12,6 +13,49 @@ #include #include "Exh.h" #include "bparse.h" + +namespace xiv::exd +{ + struct ExdHeaderMinimal { + char magic[ 0x4 ]; + uint16_t unknown; + uint16_t unknown2; + uint32_t index_size; + }; + + struct ExdRecordIndexData { + uint32_t id; + uint32_t offset; + }; +} + +namespace xiv::utils::bparse +{ + template<> + inline void reorder< xiv::exd::ExdHeaderMinimal >( xiv::exd::ExdHeaderMinimal& i_struct ) + { + for( int32_t i = 0; i < 0x4; ++i ) + { + xiv::utils::bparse::reorder( i_struct.magic[ i ] ); + } + i_struct.unknown = xiv::utils::bparse::byteswap( i_struct.unknown ); + xiv::utils::bparse::reorder( i_struct.unknown ); + i_struct.unknown2 = xiv::utils::bparse::byteswap( i_struct.unknown2 ); + xiv::utils::bparse::reorder( i_struct.unknown2 ); + i_struct.index_size = xiv::utils::bparse::byteswap( i_struct.index_size ); + xiv::utils::bparse::reorder( i_struct.index_size ); + } + + template<> + inline void reorder< xiv::exd::ExdRecordIndexData >( xiv::exd::ExdRecordIndexData& i_struct ) + { + i_struct.id = xiv::utils::bparse::byteswap( i_struct.id ); + xiv::utils::bparse::reorder( i_struct.id ); + i_struct.offset = xiv::utils::bparse::byteswap( i_struct.offset ); + xiv::utils::bparse::reorder( i_struct.offset ); + } +};// namespace xiv::utils::bparse + namespace xiv::exd { @@ -184,12 +228,153 @@ namespace xiv::exd const std::vector< Field > get_row( uint32_t id, uint32_t subRow ); // Get all rows - const std::map< uint32_t, std::vector< Field>>& get_rows(); + const std::map< uint32_t, std::vector< Field > >& get_rows(); + + // Get all rows + template< typename T > + const std::unordered_map< uint32_t, std::shared_ptr< Excel::ExcelStruct< T > > > get_sheet_rows() + { + std::unordered_map< uint32_t, std::shared_ptr< Excel::ExcelStruct< T > > > sheets; + + // Iterates over all the files + const uint32_t member_count = static_cast< uint32_t >( _exh->get_members().size() ); + for( auto& file_ptr : _files ) + { + // Get a stream + std::vector< char > dataCpy = file_ptr->get_data_sections().front(); + std::istringstream iss( std::string( dataCpy.begin(), dataCpy.end() ) ); + + // Extract the header and skip to the record indices + auto exd_header = xiv::utils::bparse::extract< ExdHeaderMinimal >( iss ); + iss.seekg( 0x20 ); + + // Preallocate and extract the record_indices + const uint32_t record_count = exd_header.index_size / sizeof( ExdRecordIndexData ); + std::vector< ExdRecordIndexData > record_indices; + record_indices.reserve( record_count ); + for( uint32_t i = 0; i < record_count; ++i ) + { + record_indices.emplace_back( xiv::utils::bparse::extract< ExdRecordIndexData >( iss ) ); + } + + for( auto& record_index : record_indices ) + { + auto cacheEntryIt = _idCache.find( record_index.id ); + if( cacheEntryIt == _idCache.end() ) + throw std::out_of_range( "Id not found: " + std::to_string( record_index.id ) ); + + auto pSheet = std::make_shared< Excel::ExcelStruct< T > >(); + + // Get the vector fields for the given record and preallocate it + auto fields = _data[ record_index.id ]; + fields.reserve( member_count ); + iss.seekg( cacheEntryIt->second.offset + 6 ); + + iss.read( reinterpret_cast( &pSheet.get()->_data ), sizeof( T ) ); + + int stringCount = 0; + for( auto& member_entry : _exh->get_exh_members() ) + { + + // Seek to the position of the member to extract. + // 6 is because we have uint32_t/uint16_t at the start of each record + iss.seekg( cacheEntryIt->second.offset + 6 + member_entry.offset ); + + // Switch depending on the type to extract + switch( member_entry.type ) + { + case DataType::string: + // Extract the offset to the actual string + // Seek to it then extract the actual string + { + auto string_offset = xiv::utils::bparse::extract< uint32_t >( iss, "string_offset", false ); + iss.seekg( cacheEntryIt->second.offset + 6 + _exh->get_header().data_offset + string_offset ); + std::string value = xiv::utils::bparse::extract_cstring( iss, "string" ); + auto it = pSheet->_strings.insert( pSheet->_strings.end(), value ); + *reinterpret_cast< uint32_t* >( pSheet->ptr() + member_entry.offset ) = + static_cast< uint32_t >( std::distance( pSheet->_strings.begin(), it ) ); + } + break; + + case DataType::boolean: + xiv::utils::bparse::extract< bool >( iss, "bool" ); + break; + + case DataType::int8: + xiv::utils::bparse::extract< int8_t >( iss, "int8_t" ); + break; + + case DataType::uint8: + xiv::utils::bparse::extract< uint8_t >( iss, "uint8_t" ); + break; + + + case DataType::int16: + { + int16_t value = xiv::utils::bparse::extract< int16_t >( iss, "int16_t", false ); + *reinterpret_cast< int16_t* >( pSheet->ptr() + member_entry.offset ) = value; + } + break; + + case DataType::uint16: + { + uint16_t value = xiv::utils::bparse::extract< uint16_t >( iss, "uint16_t", false ); + *reinterpret_cast< uint16_t* >( pSheet->ptr() + member_entry.offset ) = value; + } + break; + + case DataType::int32: + { + int32_t value = xiv::utils::bparse::extract< int32_t >( iss, "int32_t", false ); + *reinterpret_cast< int32_t* >( pSheet->ptr() + member_entry.offset ) = value; + } + break; + + case DataType::uint32: + { + uint32_t value = xiv::utils::bparse::extract< uint32_t >( iss, "uint32_t", false ); + *reinterpret_cast< uint32_t* >( pSheet->ptr() + member_entry.offset ) = value; + } + break; + + case DataType::float32: + { + float value = xiv::utils::bparse::extract< float >( iss, "float", false ); + *reinterpret_cast< float* >( pSheet->ptr() + member_entry.offset ) = value; + } + break; + + case DataType::uint64: + { + uint64_t value = xiv::utils::bparse::extract< uint64_t >( iss, "uint64_t", false ); + *reinterpret_cast< uint64_t* >( pSheet->ptr() + member_entry.offset ) = value; + } + break; + + default: + auto type = static_cast< uint16_t >( member_entry.type ); + if( type < 0x19 || type > 0x20 ) + throw std::runtime_error( "Unknown DataType: " + std::to_string( type ) ); + uint64_t val = xiv::utils::bparse::extract< uint64_t >( iss, "bool" ); + int32_t shift = type - 0x19; + int32_t i = 1 << shift; + val &= i; + fields.emplace_back( ( val & i ) == i ); + break; + } + } + + sheets[ record_index.id ] = pSheet; + } + } + + return sheets; + } protected: // Data indexed by the ID of the row, the vector is field with the same order as exh.members - std::map< uint32_t, std::vector< Field>> _data; - std::vector< std::shared_ptr< dat::File>> _files; + std::map< uint32_t, std::vector< Field > > _data; + std::vector< std::shared_ptr< dat::File > > _files; std::shared_ptr< Exh > _exh; std::map< uint32_t, ExdCacheEntry > _idCache; }; diff --git a/deps/datReader/Exd/Structs.h b/deps/datReader/Exd/Structs.h index 078d26fa4..e8a9b1ad7 100644 --- a/deps/datReader/Exd/Structs.h +++ b/deps/datReader/Exd/Structs.h @@ -302,18 +302,18 @@ namespace Excel uint16_t LimitBreakAction[3]; uint16_t PvpLimitBreakAction[3]; uint8_t Kind; - uint8_t UIPriority; uint8_t Unknown6; + uint8_t JobIndex; uint8_t MainClass; uint8_t Role; uint8_t Town; - int8_t MonsterNote; + int8_t UIPriority; int8_t StartingLevel; uint8_t PartyBuff; int8_t WorkIndex; int8_t BattleClassIndex; int8_t CraftingClassIndex; - int8_t Unknown7; + int8_t MonsterNote; }; /* 63507 */ @@ -392,12 +392,13 @@ namespace Excel uint8_t CostType; uint8_t Cond; uint8_t RecastGroup; - uint8_t Element; uint8_t ProcStatus; - uint8_t UseClassJob; + uint8_t Unknown1; // todo: possibly cost type? tp etc? + uint8_t ClassJobCategory; // recastgroup uint8_t Init; uint8_t Omen; - int8_t Learn; + uint8_t Learn; + int8_t UseClassJob; int8_t SelectRange; int8_t SelectCorpse; int8_t AttackType; @@ -429,7 +430,7 @@ namespace Excel uint8_t HideCastBar : 1; uint8_t IsTargetLine : 1; - int8_t padding0; + int8_t unknown; }; /* 75653 */ @@ -2053,7 +2054,8 @@ namespace Excel uint8_t NotControl : 1; uint8_t NotAction : 1; uint8_t NotMove : 1; - uint8_t padding0 : 6; + uint8_t padding0 : 5; + uint8_t CanOff : 1; uint8_t SemiTransparent : 1; uint8_t FcAction : 1; int8_t padding1[2]; diff --git a/deps/datReader/bparse.h b/deps/datReader/bparse.h index 6c722126d..8d3be519f 100644 --- a/deps/datReader/bparse.h +++ b/deps/datReader/bparse.h @@ -3,6 +3,7 @@ #include #include #include +#include namespace xiv::utils::bparse { diff --git a/deps/datReaderPs3/bparse.h b/deps/datReaderPs3/bparse.h index 71535263f..398638955 100644 --- a/deps/datReaderPs3/bparse.h +++ b/deps/datReaderPs3/bparse.h @@ -5,6 +5,7 @@ #include #include #include +#include namespace xivps3::utils::bparse { diff --git a/deps/mysqlConnector/ResultSetBase.h b/deps/mysqlConnector/ResultSetBase.h index 235d85117..210924e09 100644 --- a/deps/mysqlConnector/ResultSetBase.h +++ b/deps/mysqlConnector/ResultSetBase.h @@ -4,6 +4,7 @@ #include #include #include +#include namespace Mysql { diff --git a/deps/mysqlConnector/mysql_util.h b/deps/mysqlConnector/mysql_util.h index e43a373bb..028cf1eef 100644 --- a/deps/mysqlConnector/mysql_util.h +++ b/deps/mysqlConnector/mysql_util.h @@ -27,6 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include +#include #include //using MYSQL_FIELD = st_mysql_field; diff --git a/deps/watchdog/Watchdog.h b/deps/watchdog/Watchdog.h index 08cc06788..7d5e98037 100644 --- a/deps/watchdog/Watchdog.h +++ b/deps/watchdog/Watchdog.h @@ -32,14 +32,8 @@ #include - // fucking filesystem -#if _MSC_VER >= 1925 #include namespace ci { namespace fs = std::filesystem; } -#else -#include -namespace ci { namespace fs = std::experimental::filesystem; } -#endif //! Exception for when Watchdog can't locate a file or parse the wildcard class WatchedFileSystemExc : public std::exception { diff --git a/sql/migrations/20230309164293_AddBorrowAction.sql b/sql/migrations/20230309164293_AddBorrowAction.sql new file mode 100644 index 000000000..1cdc3f22a --- /dev/null +++ b/sql/migrations/20230309164293_AddBorrowAction.sql @@ -0,0 +1 @@ +ALTER TABLE `characlass` ADD `BorrowAction` binary(40) DEFAULT NULL NULL AFTER `Lvl`; \ No newline at end of file diff --git a/src/api/PlayerMinimal.cpp b/src/api/PlayerMinimal.cpp index c761ac043..f383a96d1 100644 --- a/src/api/PlayerMinimal.cpp +++ b/src/api/PlayerMinimal.cpp @@ -256,12 +256,14 @@ void PlayerMinimal::saveAsNew() break; } - // CharacterId, ClassIdx, Exp, Lvl + // CharacterId, ClassIdx, Exp, Lvl, BorrowAction auto stmtClass = g_charaDb.getPreparedStatement( Db::ZoneDbStatements::CHARA_CLASS_INS ); stmtClass->setUInt64( 1, m_characterId ); stmtClass->setInt( 2, g_exdData.getRow< Excel::ClassJob >( m_class )->data().WorkIndex ); stmtClass->setInt( 3, 0 ); stmtClass->setInt( 4, 1 ); + std::vector< uint8_t > borrowActionVec( Common::ARRSIZE_BORROWACTION * 4 ); + stmtClass->setBinary( 5, borrowActionVec ); g_charaDb.directExecute( stmtClass ); auto stmtSearchInfo = g_charaDb.getPreparedStatement( Db::ZoneDbStatements::CHARA_SEARCHINFO_INS ); diff --git a/src/api/main.cpp b/src/api/main.cpp index d0c231ce0..c1697b23b 100644 --- a/src/api/main.cpp +++ b/src/api/main.cpp @@ -31,14 +31,8 @@ #include -// fucking filesystem -#if _MSC_VER >= 1925 #include namespace fs = std::filesystem; -#else -#include -namespace fs = std::experimental::filesystem; -#endif Sapphire::Common::Util::CrashHandler crashHandler; @@ -244,12 +238,14 @@ void createAccount( shared_ptr< HttpServer::Response > response, shared_ptr< Htt std::string sId; if( g_sapphireAPI.createAccount( user, pass, sId ) ) { - // todo: construct proper json object here - std::string json_string = "{\"sId\":\"" + sId + - "\", \"lobbyHost\":\"" + - m_config.global.network.lobbyHost + - "\", \"frontierHost\":\"" + - m_config.global.network.restHost + "\"}"; + nlohmann::json response_json = { + {"sId", sId}, + {"lobbyHost", m_config.global.network.lobbyHost}, + {"frontierHost", m_config.global.network.restHost}, + {"lobbyPort", m_config.global.network.lobbyPort} + }; + + std::string json_string = response_json.dump(); *response << buildHttpResponse( 200, json_string, JSON ); } else @@ -277,12 +273,15 @@ void login( shared_ptr< HttpServer::Response > response, shared_ptr< HttpServer: // reloadConfig(); if( g_sapphireAPI.login( user, pass, sId ) ) { - // todo: build proper json object and stringify it - std::string json_string = "{\"sId\":\"" + sId + - "\", \"lobbyHost\":\"" + - m_config.global.network.lobbyHost + - "\", \"frontierHost\":\"" + - m_config.global.network.restHost + "\"}"; + nlohmann::json response_json = { + {"sId", sId}, + {"lobbyHost", m_config.global.network.lobbyHost}, + {"frontierHost", m_config.global.network.restHost}, + {"lobbyPort", m_config.global.network.lobbyPort} + }; + + std::string json_string = response_json.dump(); + *response << buildHttpResponse( 200, json_string, JSON ); } else @@ -294,7 +293,6 @@ void login( shared_ptr< HttpServer::Response > response, shared_ptr< HttpServer: *response << buildHttpResponse( 500 ); Logger::error( e.what() ); } - } void deleteCharacter( shared_ptr< HttpServer::Response > response, shared_ptr< HttpServer::Request > request ) diff --git a/src/common/Common.h b/src/common/Common.h index 72e14d21f..32d29b7a2 100644 --- a/src/common/Common.h +++ b/src/common/Common.h @@ -37,6 +37,8 @@ namespace Sapphire::Common const uint16_t ARRSIZE_UNLOCKS = 64u; const uint16_t ARRSIZE_ORCHESTRION = 40u; const uint16_t ARRSIZE_MONSTERNOTE = 12u; + const uint16_t ARRSIZE_BORROWACTION = 10u; + const uint16_t ARRSIZE_CONDITION = 12u; const uint8_t TOWN_COUNT = 6; @@ -887,22 +889,55 @@ namespace Sapphire::Common Perception = 73, // Unique modifiers - HPPercent = 1000, - MPPercent = 1001, - TPPercent = 1002, - GPPercent = 1003, - CPPercent = 1004, - PhysicalDamagePercent = 1005, - MagicDamagePercent = 1006, - AttackPowerPercent = 1007, - DefensePercent = 1008, - AccuracyPercent = 1009, - EvasionPercent = 1010, - MagicDefensePercent = 1011, - CriticalHitPowerPercent = 1012, - CriticalHitResiliencePercent = 1013, - CriticalHitPercent = 1014, - EnmityPercent = 1015 + TickHeal = 1000, + TickDamage = 1001, + StrengthPercent = 1002, + DexterityPercent = 1003, + VitalityPercent = 1004, + IntelligencePercent = 1005, + MindPercent = 1006, + PietyPercent = 1007, + HPPercent = 1008, + MPPercent = 1009, + TPPercent = 1010, + GPPercent = 1011, + CPPercent = 1012, + PhysicalDamagePercent = 1013, + MagicDamagePercent = 1014, + AttackPowerPercent = 1015, + DefensePercent = 1016, + AccuracyPercent = 1017, + EvasionPercent = 1018, + MagicDefensePercent = 1019, + CriticalHitPowerPercent = 1020, + CriticalHitResiliencePercent = 1021, + CriticalHitPercent = 1022, + EnmityPercent = 1023, + DamageDealtPercent = 1024, + DamageTakenPercent = 1025, + HealingMagicRecoveryPercent = 1026, + SlashingResistancePercent = 1027, + PiercingResistancePercent = 1028, + BluntResistancePercent = 1029, + ProjectileResistancePercent = 1030, + ParryPercent = 1031 + }; + + enum class StatusEffectFlag : uint32_t + { + BuffCategory = 1, + DebuffCategory = 2, + Permanent = 4, + IsGaze = 8, + Transfiguration = 16, + CanDispel = 32, + LockActions = 64, + LockControl = 128, + LockMovement = 256, + Invisibilty = 512, + CanStatusOff = 1024, + FcBuff = 2048, + RemoveOnSuccessfulHit = 4096 }; enum struct ActionAspect : uint8_t @@ -923,6 +958,7 @@ namespace Sapphire::Common MagicPoints = 3, TacticsPoints = 5, TacticsPoints1 = 6, + StatusEffect = 10, Sprint = 18, // WARGauge = 22, // DRKGauge = 25, @@ -948,77 +984,67 @@ namespace Sapphire::Common LimitBreak = 8, }; - enum ActionEffectType : uint8_t - { - CALC_RESULT_TYPE_NONE = 0x0, - CALC_RESULT_TYPE_MISS = 0x1, - CALC_RESULT_TYPE_RESIST = 0x2, - CALC_RESULT_TYPE_DAMAGE_HP = 0x3, - CALC_RESULT_TYPE_RECOVER_HP = 0x4, - CALC_RESULT_TYPE_CRITICAL_DAMAGE_HP = 0x5, - CALC_RESULT_TYPE_CRITICAL_RECOVER_HP = 0x6, - CALC_RESULT_TYPE_GUARD = 0x7, - CALC_RESULT_TYPE_PARRY = 0x8, - CALC_RESULT_TYPE_INVALID = 0x9, - CALC_RESULT_TYPE_UNEFFECTIVE = 0xA, - CALC_RESULT_TYPE_NEGLECT = 0xB, - CALC_RESULT_TYPE_DAMAGE_MP = 0xC, - CALC_RESULT_TYPE_RECOVER_MP = 0xD, - CALC_RESULT_TYPE_DAMAGE_TP = 0xE, - CALC_RESULT_TYPE_RECOVER_TP = 0xF, - CALC_RESULT_TYPE_RECOVER_GP = 0x10, - CALC_RESULT_TYPE_SET_STATUS = 0x11, - CALC_RESULT_TYPE_SET_STATUS_ME = 0x12, - CALC_RESULT_TYPE_RESET_STATUS = 0x13, - CALC_RESULT_TYPE_RESET_STATUS_ME = 0x14, - CALC_RESULT_TYPE_RESET_BAD_STATUS = 0x15, - CALC_RESULT_TYPE_UNEFFECTIVE_STATUS = 0x16, - CALC_RESULT_TYPE_HALF_GOOD_STATUS = 0x17, - CALC_RESULT_TYPE_HATE_DIRECT = 0x18, - CALC_RESULT_TYPE_HATE_INDIRECTION = 0x19, - CALC_RESULT_TYPE_HATE_TOP = 0x1A, - CALC_RESULT_TYPE_HATE_ADD = 0x1B, - CALC_RESULT_TYPE_HATE_MULT = 0x1C, - CALC_RESULT_TYPE_COMBO = 0x1D, - CALC_RESULT_TYPE_COMBO_HIT = 0x1E, - CALC_RESULT_TYPE_COUNTER = 0x1F, - CALC_RESULT_TYPE_DESTRUCT = 0x20, - CALC_RESULT_TYPE_PARALYSIS = 0x21, - CALC_RESULT_TYPE_KNOCK_BACK = 0x22, - CALC_RESULT_TYPE_DRAW_UP_CHAIRS = 0x23, - CALC_RESULT_TYPE_SUCKED = 0x24, - CALC_RESULT_TYPE_CT_DRAW_UP_CHAIRS = 0x25, - CALC_RESULT_TYPE_LIVE_CALLBACK = 0x26, - CALC_RESULT_TYPE_MOUNT = 0x27, - CALC_RESULT_ARCHER_DOT = 0x28, - CALC_RESULT_MASTER_DOT = 0x29, - CALC_RESULT_BLESSINGS_OF_GODDESS = 0x2A, - CALC_RESULT_BAD_BREATH = 0x2B, - CALC_RESULT_REVIVAL = 0x2C, - CALC_RESULT_PET = 0x2D, - CALC_RESULT_TYPE_BLOW = 0x2E, - CALC_RESULT_TYPE_STATUS_RESIST = 0x2F, - CALC_RESULT_TYPE_CLEAR_PHYSICAL = 0x30, - CALC_RESULT_BNPC_STATE = 0x31, - CALC_RESULT_TYPE_VFX = 0x32, - CALC_RESULT_TYPE_HARD_CODE = 0x33, - CALC_RESULT_CALC_ID = 0x34, - CALC_RESULT_TYPE_CLEAR_PVP_POINT = 0x35, - CALC_RESULT_TYPE_CHECK_BARRIER = 0x36, - CALC_RESULT_TYPE_REFLEC = 0x37, - }; - - enum class ActionHitSeverityType : uint8_t - { - NormalDamage = 0, - CritHeal = 0, - CritDamage = 1, - NormalHeal = 1, - DirectHitDamage = 2, - CritDirectHitDamage = 3 - }; - - enum class ActionEffectResultFlag : uint8_t + enum CalcResultType : uint8_t + { + TypeNone = 0x0, + TypeMiss = 0x1, + TypeResist = 0x2, + TypeDamageHp = 0x3, + TypeRecoverHp = 0x4, + TypeCriticalDamageHp = 0x5, + TypeCriticalRecoverHp = 0x6, + TypeGuard = 0x7, + TypeParry = 0x8, + TypeInvalid = 0x9, + TypeUneffective = 0xA, + TypeNeglect = 0xB, + TypeDamageMp = 0xC, + TypeRecoverMp = 0xD, + TypeDamageTp = 0xE, + TypeRecoverTp = 0xF, + TypeRecoverGp = 0x10, + TypeSetStatus = 0x11, + TypeSetStatusMe = 0x12, + TypeResetStatus = 0x13, + TypeResetStatusMe = 0x14, + TypeResetBadStatus = 0x15, + TypeUneffectiveStatus = 0x16, + TypeHalfGoodStatus = 0x17, + TypeHateDirect = 0x18, + TypeHateIndirection = 0x19, + TypeHateTop = 0x1A, + TypeHateAdd = 0x1B, + TypeHateMult = 0x1C, + TypeCombo = 0x1D, + TypeComboHit = 0x1E, + TypeCounter = 0x1F, + TypeDestruct = 0x20, + TypeParalysis = 0x21, + TypeKnockBack = 0x22, + TypeDrawUpChairs = 0x23, + TypeSucked = 0x24, + TypeCtDrawUpChairs = 0x25, + TypeLiveCallback = 0x26, + TypeMount = 0x27, + TypeArcherDot = 0x28, + TypeMasterDot = 0x29, + TypeBlessingOfGoddess = 0x2A, + TypeBadBreath = 0x2B, + TypeRevival = 0x2C, + TypePet = 0x2D, + TypeBlow = 0x2E, + TypeStatusResist = 0x2F, + TypeClearPhysical = 0x30, + TypeBNpcState = 0x31, + TypeVfx = 0x32, + TypeHardCode = 0x33, + TypeCalcId = 0x34, + TypeClearPvpPoint = 0x35, + TypeCheckBarrier = 0x36, + TypeReflect = 0x37, + }; + + enum class ActionResultFlag : uint8_t { None = 0, Absorbed = 0x04, @@ -1033,6 +1059,7 @@ namespace Sapphire::Common ItemActionCompanion = 853, ItemActionVFX2 = 944, ItemActionMount = 1322, + ItemActionSong = 5845, }; enum ActionEffectDisplayType : uint8_t @@ -1383,9 +1410,10 @@ namespace Sapphire::Common { None1 = 0, HideUILockChar = 1, // as the name suggests, hides the ui and logs the char... - InCombat = 2, // in Combat, locks gearchange/return/teleport - Casting = 3, - InNpcEvent = 6, // when talking to an npc, locks ui giving "occupied" message + InCombat = 18, // in Combat, locks gearchange/return/teleport + Casting = 19, + EventAction = 22, + InNpcEvent = 24, // when talking to an npc, locks ui giving "occupied" message // InNpcEvent1 = 10, // Sent together with InNpcEvent, when waiting for input? just a guess... @@ -1798,6 +1826,7 @@ namespace Sapphire::Common { uint16_t targetAetheryte; uint16_t cost; + bool useAetheryteTicket{ false }; }; enum EventSceneError : uint8_t @@ -1833,12 +1862,13 @@ namespace Sapphire::Common THREAT }; + // todo: fill this out (Action.exd EffectType) enum CastType : uint8_t { SingleTarget = 1, CircularAOE = 2, - Type3 = 3, // another single target? no idea how to call it - RectangularAOE = 4, + RectangularAOE = 3, + ConeAOE = 4, CircularAoEPlaced = 7 }; @@ -1856,6 +1886,7 @@ namespace Sapphire::Common using PlayerStateFlagList = std::vector< PlayerCondition >; + // todo: load BNpcBase and other exd data into this struct struct BNPCInstanceObject { uint16_t territoryType; diff --git a/src/common/Config/ConfigMgr.cpp b/src/common/Config/ConfigMgr.cpp index 5d95e17f7..52808aac8 100644 --- a/src/common/Config/ConfigMgr.cpp +++ b/src/common/Config/ConfigMgr.cpp @@ -2,13 +2,8 @@ #include #include -#if _MSC_VER >= 1925 #include namespace fs = std::filesystem; -#else -#include -namespace fs = std::experimental::filesystem; -#endif using namespace Sapphire; using namespace Sapphire::Common; @@ -94,4 +89,4 @@ bool ConfigMgr::copyDefaultConfig( const std::string& configName ) fs::copy_file( configPath.string() + m_configDefaultSuffix, configPath ); return true; -} \ No newline at end of file +} diff --git a/src/common/Crypt/base64.h b/src/common/Crypt/base64.h index a627067e7..94d86c3bc 100644 --- a/src/common/Crypt/base64.h +++ b/src/common/Crypt/base64.h @@ -1,6 +1,7 @@ #pragma once #include +#include namespace Sapphire::Common::Util { diff --git a/src/common/Database/ZoneDbConnection.cpp b/src/common/Database/ZoneDbConnection.cpp index 10f9f854e..6a0f79a0a 100644 --- a/src/common/Database/ZoneDbConnection.cpp +++ b/src/common/Database/ZoneDbConnection.cpp @@ -161,11 +161,11 @@ void Sapphire::Db::ZoneDbConnection::doPrepareStatements() prepareStatement( CHARA_SEL_QUEST, "SELECT * FROM charaquest WHERE CharacterId = ?;", CONNECTION_SYNC ); /// CLASS INFO - prepareStatement( CHARA_CLASS_SEL, "SELECT ClassIdx, Exp, Lvl FROM characlass WHERE CharacterId = ?;", + prepareStatement( CHARA_CLASS_SEL, "SELECT ClassIdx, Exp, Lvl, BorrowAction FROM characlass WHERE CharacterId = ?;", CONNECTION_SYNC ); - prepareStatement( CHARA_CLASS_INS, "INSERT INTO characlass ( CharacterId, ClassIdx, Exp, Lvl ) VALUES( ?,?,?,? );", + prepareStatement( CHARA_CLASS_INS, "INSERT INTO characlass ( CharacterId, ClassIdx, Exp, Lvl, BorrowAction ) VALUES( ?,?,?,?,? );", CONNECTION_BOTH ); - prepareStatement( CHARA_CLASS_UP, "UPDATE characlass SET Exp = ?, Lvl = ? WHERE CharacterId = ? AND ClassIdx = ?;", + prepareStatement( CHARA_CLASS_UP, "UPDATE characlass SET Exp = ?, Lvl = ?, BorrowAction = ? WHERE CharacterId = ? AND ClassIdx = ?;", CONNECTION_ASYNC ); prepareStatement( CHARA_CLASS_DEL, "DELETE FROM characlass WHERE CharacterId = ?;", CONNECTION_ASYNC ); diff --git a/src/common/Exd/ExdData.h b/src/common/Exd/ExdData.h index 5ba553e5e..a4be91569 100644 --- a/src/common/Exd/ExdData.h +++ b/src/common/Exd/ExdData.h @@ -91,6 +91,27 @@ namespace Sapphire::Data return ids; } + template< typename T > + std::unordered_map< uint32_t, std::shared_ptr< Excel::ExcelStruct< T > > > getRows() + { + xiv::exd::Exd sheet; + auto needle = m_sheets.find( typeid( T ) ); + if( needle == m_sheets.end() ) + { + auto sheetName = getSheetName< T >(); + + // load sheet + auto& cat = m_exd_data->get_category( sheetName ); + m_sheets[ typeid( T ) ] = sheet = static_cast< xiv::exd::Exd >( cat.get_data( xiv::exd::Language::en ) ); + } + else + { + sheet = needle->second; + } + + return sheet.get_sheet_rows< T >(); + } + std::shared_ptr< xiv::dat::GameData > getGameData() { return m_data; diff --git a/src/common/Logging/Logger.cpp b/src/common/Logging/Logger.cpp index 828671992..9fc6b37bc 100644 --- a/src/common/Logging/Logger.cpp +++ b/src/common/Logging/Logger.cpp @@ -8,13 +8,8 @@ #include // #include -#if _MSC_VER >= 1925 #include namespace fs = std::filesystem; -#else -#include -namespace fs = std::experimental::filesystem; -#endif void Sapphire::Logger::init( const std::string& logPath ) diff --git a/src/common/Util/UtilMath.cpp b/src/common/Util/UtilMath.cpp index 6a162d64f..516c00c7b 100644 --- a/src/common/Util/UtilMath.cpp +++ b/src/common/Util/UtilMath.cpp @@ -39,8 +39,12 @@ float Util::distance2D( float x, float y, float x1, float y1 ) float Util::calcAngTo( float x, float y, float x1, float y1 ) { - float dx = x - x1; - float dy = y - y1; + float dx = x1 - x; + float dy = y1 - y; + + if( dx == 0.0f && dy == 0.0f ) + return 0.0f; + if( dy != 0.0f ) { return atan2( dy, dx ); @@ -55,6 +59,10 @@ float Util::calcAngFrom( float x, float y, float x1, float y1 ) { float dx = x - x1; float dy = y - y1; + + if( dx == 0.0f && dy == 0.0f ) + return 0.0f; + if( dy != 0.0f ) { return atan2( dy, dx ); @@ -80,6 +88,39 @@ uint8_t Util::floatToUInt8Rot( float val ) return static_cast< uint8_t >( 0x80 * ( ( val + PI ) ) / PI ); } +FFXIVARR_POSITION3 Util::getOffsettedPosition( const FFXIVARR_POSITION3& pos, float rot, float right, float up, float forward ) +{ + FFXIVARR_POSITION3 ret{ pos }; + + // height + ret.y += up; + + // forward + float angle = rot + ( PI / 2 ); + ret.x -= forward * cos( angle ); + ret.z += forward * sin( angle ); + + // side + ret.x -= right * cos( rot ); + ret.z += right * sin( rot ); + + return ret; +} + +FFXIVARR_POSITION3 Util::getKnockbackPosition( const FFXIVARR_POSITION3& origin, const FFXIVARR_POSITION3& pos, float distance ) +{ + FFXIVARR_POSITION3 ret{ pos }; + + float from = Common::Util::calcAngFrom( origin.x, origin.z, pos.x, pos.z ); + float angle = PI - from + ( PI / 2 ); + + angle = angle + ( PI / 2 ); + ret.x -= distance * cos( angle ); + ret.z += distance * sin( angle ); + + return ret; +} + FFXIVARR_POSITION3 Util::transform( const FFXIVARR_POSITION3& vector, const Matrix33& matrix ) { FFXIVARR_POSITION3 dst{}; @@ -143,3 +184,23 @@ float Util::trunc( float value, uint8_t digitsToRemain ) return std::floor( value * factor ) / factor; } + +float Util::length( const FFXIVARR_POSITION3& vec ) { + return std::sqrt( vec.x * vec.x + vec.y * vec.y + vec.z * vec.z ); +} + +FFXIVARR_POSITION3 Util::normalize( const FFXIVARR_POSITION3& vec ) { + float len = length( vec ); + if( len == 0 ) return FFXIVARR_POSITION3(); + return FFXIVARR_POSITION3{ vec.x / len, vec.y / len, vec.z / len }; +} + +float Util::dot( const FFXIVARR_POSITION3& vec1, const FFXIVARR_POSITION3& vec2 ) +{ + return vec1.x * vec2.x + vec1.y * vec2.y + vec1.z * vec2.z; +} + +FFXIVARR_POSITION3 Util::projectY( const FFXIVARR_POSITION3& vec ) +{ + return FFXIVARR_POSITION3{ vec.x, 0, vec.z }; +} \ No newline at end of file diff --git a/src/common/Util/UtilMath.h b/src/common/Util/UtilMath.h index 1f6ddd504..9e5f4adca 100644 --- a/src/common/Util/UtilMath.h +++ b/src/common/Util/UtilMath.h @@ -29,6 +29,10 @@ namespace Sapphire::Common::Util uint8_t floatToUInt8Rot( float val ); + FFXIVARR_POSITION3 getOffsettedPosition( const FFXIVARR_POSITION3& pos, float rotation, float right, float up, float forward ); + + FFXIVARR_POSITION3 getKnockbackPosition( const FFXIVARR_POSITION3& origin, const FFXIVARR_POSITION3& pos, float distance ); + template < typename T > T clamp( T val, T minimum, T maximum ) { @@ -44,6 +48,14 @@ namespace Sapphire::Common::Util FFXIVARR_POSITION3 transform( const FFXIVARR_POSITION3& vector, const Matrix33& matrix ); float eulerToDirection( const FFXIVARR_POSITION3& euler ); + + float length( const FFXIVARR_POSITION3& vec ); + + FFXIVARR_POSITION3 normalize( const FFXIVARR_POSITION3& vec ); + + float dot( const FFXIVARR_POSITION3& vec1, const FFXIVARR_POSITION3& vec2 ); + + FFXIVARR_POSITION3 projectY( const FFXIVARR_POSITION3& vec ); } #endif diff --git a/src/common/Vector3.cpp b/src/common/Vector3.cpp index a98c4fdeb..7f2bb3940 100644 --- a/src/common/Vector3.cpp +++ b/src/common/Vector3.cpp @@ -7,8 +7,17 @@ inline bool FFXIVARR_POSITION3::operator == ( const FFXIVARR_POSITION3& target ) return x == target.x && y == target.y && z == target.z; } +FFXIVARR_POSITION3 FFXIVARR_POSITION3::operator - ( const FFXIVARR_POSITION3& target ) const +{ + return FFXIVARR_POSITION3{ x - target.x, y - target.y, z - target.z }; +} inline bool Vector3::operator == ( const Vector3& target ) const { return x == target.x && y == target.y && z == target.z && reserve == target.reserve; -} \ No newline at end of file +} + +Vector3 Vector3::operator - ( const Vector3& target ) const +{ + return Vector3{ x - target.x, y - target.y, z - target.z }; +} diff --git a/src/common/Vector3.h b/src/common/Vector3.h index 1658aa76c..539c4e032 100644 --- a/src/common/Vector3.h +++ b/src/common/Vector3.h @@ -2,12 +2,14 @@ namespace Sapphire::Common { + // todo: get rid of this struct and use an actual vector 3 class struct FFXIVARR_POSITION3 { float x; float y; float z; inline bool operator == ( const FFXIVARR_POSITION3& target ) const; + FFXIVARR_POSITION3 operator - ( const FFXIVARR_POSITION3& target ) const; }; struct Vector3 @@ -17,6 +19,8 @@ namespace Sapphire::Common float z; float reserve; inline bool operator == ( const Vector3& target ) const; + inline bool operator == ( const FFXIVARR_POSITION3& target ) const; + Vector3 operator - ( const Vector3& target ) const; }; struct Matrix33 diff --git a/src/dbm/DbManager.cpp b/src/dbm/DbManager.cpp index 0f7062127..31ef313c3 100644 --- a/src/dbm/DbManager.cpp +++ b/src/dbm/DbManager.cpp @@ -11,14 +11,8 @@ using namespace Sapphire; using namespace Sapphire::Common; -// fucking filesystem -#if _MSC_VER >= 1925 #include namespace fs = std::filesystem; -#else -#include -namespace fs = std::experimental::filesystem; -#endif DbManager::DbManager( const std::string& host, const std::string& database, const std::string& user, const std::string& pw, uint16_t port ) : diff --git a/src/dbm/main.cpp b/src/dbm/main.cpp index 7eaff9031..dd28ef9f0 100644 --- a/src/dbm/main.cpp +++ b/src/dbm/main.cpp @@ -9,14 +9,8 @@ Sapphire::Common::Util::CrashHandler crashHandler; -// fucking filesystem -#if _MSC_VER >= 1925 #include namespace filesys = std::filesystem; -#else -#include -namespace filesys = std::experimental::filesystem; -#endif #include #include diff --git a/src/scripts/action/common/ActionSprint3.cpp b/src/scripts/action/common/ActionSprint3.cpp index 82bf80fba..929487f93 100644 --- a/src/scripts/action/common/ActionSprint3.cpp +++ b/src/scripts/action/common/ActionSprint3.cpp @@ -17,10 +17,7 @@ class ActionSprint3 : public Sapphire::ScriptAPI::ActionScript return; uint32_t duration = ( sourceChara->getAsPlayer()->getTp() / 50 ) * 1000; - - action.getEffectbuilder()->applyStatusEffect( sourceChara, 50, 30 ); - - sourceChara->getAsPlayer()->addStatusEffectByIdIfNotExist( 50, duration, *sourceChara, 30 ); + action.getActionResultBuilder()->applyStatusEffectSelf( 50, duration, 30, false ); sourceChara->getAsPlayer()->setTp( 0 ); } }; diff --git a/src/scripts/action/common/ActionTeleport5.cpp b/src/scripts/action/common/ActionTeleport5.cpp index 954ab7465..cbd52078b 100644 --- a/src/scripts/action/common/ActionTeleport5.cpp +++ b/src/scripts/action/common/ActionTeleport5.cpp @@ -22,6 +22,7 @@ class ActionTeleport5 : public Sapphire::ScriptAPI::ActionScript auto teleportQuery = pPlayer->getTeleportQuery(); if( pPlayer->getCurrency( Common::CurrencyType::Gil ) < teleportQuery.cost || + teleportQuery.useAetheryteTicket && !pPlayer->removeItem( 7569 ) || teleportQuery.targetAetheryte == 0 ) { action.interrupt(); diff --git a/src/scripts/action/war/ActionInnerBeast.cpp b/src/scripts/action/war/ActionInnerBeast.cpp new file mode 100644 index 000000000..d4193e4d4 --- /dev/null +++ b/src/scripts/action/war/ActionInnerBeast.cpp @@ -0,0 +1,47 @@ +#include