Skip to content

Commit

Permalink
Add species data to wiki export
Browse files Browse the repository at this point in the history
* First-pass currently extracts:
  * Basic info (name, blueprint, tags)
  * Drag weight and mass
  * Fall damage + speed
  * Walking and sprinting speeds

This change also extends json formatting for neater attack info, but see #75 as this needs improving.
  • Loading branch information
coldino committed Jan 31, 2020
1 parent 595386c commit a0f2e7b
Show file tree
Hide file tree
Showing 8 changed files with 155 additions and 0 deletions.
17 changes: 17 additions & 0 deletions ark/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,23 @@ class PrimalDinoCharacter(UEProxyStructure, uetype='/Script/ShooterGame.PrimalDi
BoneDamageAdjusters: Mapping[int, ArrayProperty] # = []

# DevKit Unverified
MeleeDamageAmount = ueints(0)
MeleeSwingRadius = uefloats(0.0)
AttackInfos: Mapping[int, ArrayProperty]

FallDamageMultiplier = uefloats(165.0)
MaxFallSpeed = uefloats(1200.0)

Mass = uefloats(100.0)
DragWeight = uefloats(35.0)

TargetingTeamNameOverride = uestrings('')

MaxWalkSpeed = uefloats(600.0)
MaxWalkSpeedCrouched = uefloats(300.0)
MaxWalkSpeedProne = uefloats(100.0)
RunningSpeedModifier = uefloats(1.5)
bCanRun = uebools(False)


class ShooterCharacterMovement(UEProxyStructure, uetype='/Script/ShooterGame.ShooterCharacterMovement'):
Expand Down
1 change: 1 addition & 0 deletions automate/config/sections.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ class ExportWikiSection(ExportSection):
ExportItems: bool = True
ExportDrops: bool = True
ExportLootCrates: bool = True
ExportSpecies: bool = True

class Config:
extra = Extra.forbid
Expand Down
1 change: 1 addition & 0 deletions automate/jsonutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ def _calculate_digest(values: Dict[str, Any]) -> Tuple[Optional[str], str]:
JOIN_LINE_FIELDS = (
'x|y|z',
'lat|long?',
'name|interval|dmg|radius|stamina',
)


Expand Down
3 changes: 3 additions & 0 deletions automate/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ def create_parser() -> argparse.ArgumentParser:
parser.add_argument('--skip-wiki-items', action='store_true', help='skip extracting items for the wiki')
parser.add_argument('--skip-wiki-drops', action='store_true', help='skip extracting drops for the wiki')
parser.add_argument('--skip-wiki-loot-crates', action='store_true', help='skip extracting loot crates for the wiki')
parser.add_argument('--skip-wiki-species', action='store_true', help='skip extracting species for the wiki')

parser.add_argument('--skip-commit', action='store_true', help='skip git commit of the output repo (use dry-run mode)')
parser.add_argument('--skip-pull', action='store_true', help='skip git pull or reset of the output repo')
Expand Down Expand Up @@ -146,6 +147,8 @@ def handle_args(args: Any) -> ConfigFile:
config.export_wiki.ExportDrops = False
if args.skip_wiki_loot_crates:
config.export_wiki.ExportLootCrates = False
if args.skip_wiki_species:
config.export_wiki.ExportSpecies = False

# Git actions
if args.skip_pull:
Expand Down
2 changes: 2 additions & 0 deletions export/wiki/root.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from .stage_loot_crates import LootCratesStage
from .stage_maps import MapStage
from .stage_spawn_groups import SpawnGroupStage
from .stage_species import SpeciesStage

__all__ = [
'WikiRoot',
Expand Down Expand Up @@ -38,4 +39,5 @@ def __init__(self):
ItemsStage(),
DropsStage(),
LootCratesStage(),
SpeciesStage(),
]
Empty file added export/wiki/species/__init__.py
Empty file.
36 changes: 36 additions & 0 deletions export/wiki/species/attacks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from typing import *

from ark.types import PrimalDinoCharacter
from ue.properties import StructProperty


def gather_attack_data(char: PrimalDinoCharacter):
result: Dict[str, Any] = dict()

result['defaultDmg'] = char.MeleeDamageAmount[0]
result['defaultSwingRadius'] = char.MeleeSwingRadius[0]

if 'AttackInfos' in char:
attacks = [_convert_attack(cast(StructProperty, attack)) for attack in char.AttackInfos[0].values]
if attacks:
result['attacks'] = attacks

return dict(attack=result)


def _convert_attack(attack: StructProperty):
d: Dict[str, Any] = attack.as_dict()

v = dict(
name=d['AttackName'] or None,
interval=d['AttackInterval'],
dmg=d['MeleeDamageAmount'],
radius=d['MeleeSwingRadius'],
stamina=d['StaminaCost'],
)

proj = d['ProjectileClass']
if proj:
v['isProjectile'] = True

return v
95 changes: 95 additions & 0 deletions export/wiki/stage_species.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
from logging import NullHandler, getLogger
from pathlib import PurePosixPath
from typing import *
from typing import cast

from ark.asset import find_dcsc
from ark.overrides import OverrideSettings, get_overrides_for_species
from ark.types import DCSC, PrimalDinoCharacter
from automate.hierarchy_exporter import JsonHierarchyExportStage
from ue.asset import UAsset
from ue.gathering import gather_properties
from ue.proxy import UEProxyStructure
from ue.utils import clean_double as cd

from .species.attacks import gather_attack_data

__all__ = [
'SpeciesStage',
]

logger = getLogger(__name__)
logger.addHandler(NullHandler())


class SpeciesStage(JsonHierarchyExportStage):
def get_skip(self) -> bool:
return not self.manager.config.export_wiki.ExportSpecies

def get_field(self):
return 'species'

def get_use_pretty(self) -> bool:
return bool(self.manager.config.export_wiki.PrettyJson)

def get_format_version(self):
return "1"

def get_ue_type(self):
return PrimalDinoCharacter.get_ue_type()

def extract(self, proxy: UEProxyStructure) -> Any:
species: PrimalDinoCharacter = cast(PrimalDinoCharacter, proxy)

asset: UAsset = proxy.get_source().asset
assert asset.assetname and asset.default_class
modid: Optional[str] = self.manager.loader.get_mod_id(asset.assetname)
overrides = get_overrides_for_species(asset.assetname, modid)

if _should_skip_species(species, overrides):
return None

results: Dict[str, Any] = dict(
name=species.DescriptiveName[0],
blueprintPath=asset.default_class.fullname,
dinoNameTag=species.DinoNameTag[0],
customTag=species.CustomTag[0],
targetingTeamName=species.TargetingTeamNameOverride[0],
mass=species.Mass[0],
dragWeight=species.DragWeight[0],
)

results['falling'] = dict(
dmgMult=species.FallDamageMultiplier[0],
maxSpeed=species.MaxFallSpeed[0],
)

results['speed'] = species.MaxWalkSpeed[0]
if species.bCanRun[0]:
results['speedSprint'] = cd(species.MaxWalkSpeed[0] * species.RunningSpeedModifier[0])
else:
results['speedSprint'] = None

results.update(gather_attack_data(species))

return results


def _should_skip_species(species: PrimalDinoCharacter, overrides: OverrideSettings):
if overrides.skip_export:
return True

if not species.has_override('DescriptiveName'):
return True

# Check the local DCSC
dcsc_export = find_dcsc(species.get_source().asset)
if not dcsc_export:
return None

# Check if there no overrides of MaxStatusValues
dcsc: DCSC = gather_properties(dcsc_export) # does not respect prioritising DCSCs, but that's okay here
if not any((not dcsc.has_override('MaxStatusValues', i)) for i in range(12)):
return True

return False

0 comments on commit a0f2e7b

Please sign in to comment.