Beispiel #1
0
def gather_stat_data(
        dcsc_props: PrimalDinoStatusComponent,
        meta_props: PrimalDinoStatusComponent, is_flyer: bool,
        statIndexes: Tuple[int, ...]) -> List[Optional[List[float]]]:
    statsArray = list()

    iw_values: List[float] = [0] * len(statIndexes)
    for _, ark_index in enumerate(statIndexes):
        can_level = (ark_index == 2) or meta_props.CanLevelUpValue[ark_index]
        dont_use = meta_props.DontUseValue[ark_index]

        # Creates a null value in the JSON for stats that are unused
        if dont_use and not can_level:
            stat_data: Optional[List[float]] = None

        else:
            add_one = 1 if IS_PERCENT_STAT[ark_index] else 0

            # Zero-out stats that can't level
            wild_mult = 1 if can_level else 0

            # Also zero-out domestic stats that can't level, adding exception for flyer speed :(
            dom_mult = 1 if ark_index == 9 and is_flyer else wild_mult

            ETHM = dcsc_props.ExtraTamedHealthMultiplier[
                0].rounded_value if ark_index == 0 else 1

            # Overrides the IW value for Torpor. While this hasn't been seen before, a species may allow torpor
            #   to be leveled in the wild. Unsure how Ark would handle this.
            if ark_index == 2:
                iw_values[
                    ark_index] = dcsc_props.TheMaxTorporIncreasePerBaseLevel[
                        0].rounded_value
            else:
                iw_values[
                    ark_index] = dcsc_props.AmountMaxGainedPerLevelUpValue[
                        ark_index].rounded_value

            stat_data = [
                cd(dcsc_props.MaxStatusValues[ark_index].rounded_value +
                   add_one),
                cd(iw_values[ark_index] * wild_mult),
                cd(dcsc_props.AmountMaxGainedPerLevelUpValueTamed[ark_index].
                   rounded_value * ETHM * dom_mult),
                cf(dcsc_props.TamingMaxStatAdditions[ark_index].rounded_value),
                cf(dcsc_props.TamingMaxStatMultipliers[ark_index].rounded_value
                   ),
            ]

        statsArray.append(stat_data)

    return statsArray
Beispiel #2
0
def gather_stat_data(props, statIndexes):
    statsArray = list()

    # Create a temporary set of Iw defaults, overriding torpor with TheMaxTorporIncreasePerBaseLevel or 0.06
    iw_values = list(IW_VALUES)
    iw_values[2] = stat_value(props, 'TheMaxTorporIncreasePerBaseLevel', 0,
                              0.06)

    for _, ark_index in enumerate(statIndexes):
        can_level = (ark_index == 2) or stat_value(
            props, 'CanLevelUpValue', ark_index, CANLEVELUP_VALUES)
        add_one = 1 if IS_PERCENT_STAT[ark_index] else 0
        zero_mult = 1 if can_level else 0
        ETHM = stat_value(props, 'ExtraTamedHealthMultiplier', ark_index,
                          EXTRA_MULTS_VALUES)

        stat_data = [
            cd(
                stat_value(props, 'MaxStatusValues', ark_index, BASE_VALUES) +
                add_one),
            cd(
                stat_value(props, 'AmountMaxGainedPerLevelUpValue', ark_index,
                           iw_values) * zero_mult),
            cd(
                stat_value(props, 'AmountMaxGainedPerLevelUpValueTamed',
                           ark_index, 0.0) * ETHM * zero_mult),
            cf(stat_value(props, 'TamingMaxStatAdditions', ark_index, 0.0)),
            cf(stat_value(props, 'TamingMaxStatMultipliers', ark_index, 0.0)),
        ]

        # Creates a null value in the JSON for stats that are unused
        dont_use = stat_value(props, 'DontUseValue', ark_index,
                              DONTUSESTAT_VALUES)
        if dont_use and not can_level:
            stat_data = None

        statsArray.append(stat_data)

    return statsArray
Beispiel #3
0
def gather_taming_data(char_props: PrimalDinoCharacter, dcsc_props: PrimalDinoStatusComponent,
                       overrides: OverrideSettings) -> Dict[str, Any]:
    data: Dict[str, Any] = dict()

    # Currently unable to gather the foods list
    eats: Optional[List[str]] = None
    special_food_values: Optional[List[Dict[str, Dict[str, List[int]]]]] = None

    if overrides.taming_method:
        can_tame = overrides.taming_method != TamingMethod.none
        data['nonViolent'] = overrides.taming_method == TamingMethod.awake
        data['violent'] = overrides.taming_method == TamingMethod.knockout
    else:
        can_tame = bool(char_props.bCanBeTamed[0])
        can_knockout = char_props.bCanBeTorpid[0]
        can_basket_tame = char_props.bAllowTrapping[0] and not char_props.bPreventWildTrapping[0] and char_props.bIsTrapTamed[0]
        data['nonViolent'] = (char_props.bSupportWakingTame[0] and can_tame) or can_basket_tame
        data['violent'] = not char_props.bPreventSleepingTame[0] and can_tame and can_knockout

    if can_tame or True:
        data['tamingIneffectiveness'] = cf(char_props.TameIneffectivenessByAffinity[0].rounded_value)
        data['affinityNeeded0'] = cf(char_props.RequiredTameAffinity[0].rounded_value)
        data['affinityIncreasePL'] = cf(char_props.RequiredTameAffinityPerBaseLevel[0].rounded_value)

        torpor_depletion = dcsc_props.KnockedOutTorpidityRecoveryRateMultiplier[0].rounded_value \
            * dcsc_props.RecoveryRateStatusValue[2].rounded_value

        if data['violent']:
            data['torporDepletionPS0'] = cd(-torpor_depletion)
        if data['nonViolent']:
            data['wakeAffinityMult'] = cf(char_props.WakingTameFoodAffinityMultiplier[0].rounded_value)
            data['wakeFoodDeplMult'] = cf(dcsc_props.WakingTameFoodConsumptionRateMultiplier[0].rounded_value)

        data['foodConsumptionBase'] = cf(-dcsc_props.BaseFoodConsumptionRate[0].rounded_value)
        data['foodConsumptionMult'] = cf(dcsc_props.ProneWaterFoodConsumptionMultiplier[0].rounded_value)
        data['babyFoodConsumptionMult'] = cf(dcsc_props.BabyDinoConsumingFoodRateMultiplier[0].rounded_value *
                                             dcsc_props.ExtraBabyDinoConsumingFoodRateMultiplier[0].rounded_value)

        if eats is not None:
            data['eats'] = eats
        if special_food_values is not None:
            data['specialFoodValues'] = special_food_values

    return data
Beispiel #4
0
def gather_taming_data(
        char_props: PrimalDinoCharacter,
        dcsc_props: PrimalDinoStatusComponent) -> Dict[str, Any]:
    data: Dict[str, Any] = dict()

    # Currently unable to gather the foods list
    eats: Optional[List[str]] = None
    favorite_kibble: Optional[str] = None
    special_food_values: Optional[List[Dict[str, Dict[str, List[int]]]]] = None

    can_tame = char_props.bCanBeTamed[0]
    can_knockout = char_props.bCanBeTorpid[0]
    data['nonViolent'] = char_props.bSupportWakingTame[0] and can_tame
    data['violent'] = not char_props.bPreventSleepingTame[
        0] and can_tame and can_knockout

    if can_tame or True:
        data['tamingIneffectiveness'] = cf(
            char_props.TameIneffectivenessByAffinity[0].rounded_value)
        data['affinityNeeded0'] = cf(
            char_props.RequiredTameAffinity[0].rounded_value)
        data['affinityIncreasePL'] = cf(
            char_props.RequiredTameAffinityPerBaseLevel[0].rounded_value)

        torpor_depletion = dcsc_props.KnockedOutTorpidityRecoveryRateMultiplier[0].rounded_value \
            * dcsc_props.RecoveryRateStatusValue[2].rounded_value

        if data['violent']:
            data['torporDepletionPS0'] = cd(-torpor_depletion)
        if data['nonViolent']:
            data['wakeAffinityMult'] = cf(
                char_props.WakingTameFoodAffinityMultiplier[0].rounded_value)
            data['wakeFoodDeplMult'] = cf(
                dcsc_props.WakingTameFoodConsumptionRateMultiplier[0].
                rounded_value)

        data['foodConsumptionBase'] = cf(
            -dcsc_props.BaseFoodConsumptionRate[0].rounded_value)
        data['foodConsumptionMult'] = cf(
            dcsc_props.ProneWaterFoodConsumptionMultiplier[0].rounded_value)

        if eats is not None:
            data['eats'] = eats
        if favorite_kibble is not None:
            data['favoriteKibble'] = favorite_kibble
        if special_food_values is not None:
            data['specialFoodValues'] = special_food_values

    return data
Beispiel #5
0
def gather_taming_data(props) -> Dict[str, Any]:
    data: Dict[str, Any] = dict()

    # Currently unable to gather the foods list
    eats: Optional[List[str]] = None
    favorite_kibble: Optional[str] = None
    special_food_values: Optional[List[Dict[str, Dict[str, List[int]]]]] = None

    can_tame = stat_value(props, 'bCanBeTamed', 0, True)
    can_knockout = stat_value(props, 'bCanBeTorpid', 0, True)
    data['nonViolent'] = stat_value(props, 'bSupportWakingTame', 0,
                                    False) and can_tame
    data['violent'] = not stat_value(props, 'bPreventSleepingTame', 0,
                                     False) and can_tame and can_knockout

    if can_tame or True:
        data['tamingIneffectiveness'] = cf(
            stat_value(props, 'TameIneffectivenessByAffinity', 0, 20.0))
        data['affinityNeeded0'] = cf(
            stat_value(props, 'RequiredTameAffinity', 0, 100))
        data['affinityIncreasePL'] = cf(
            stat_value(props, 'RequiredTameAffinityPerBaseLevel', 0, 5.0))

        torpor_depletion = stat_value(props, 'KnockedOutTorpidityRecoveryRateMultiplier', 0, 3.0) \
            * stat_value(props, 'RecoveryRateStatusValue', 2, 0.00)

        if data['violent']:
            data['torporDepletionPS0'] = cd(-torpor_depletion)
        if data['nonViolent']:
            data['wakeAffinityMult'] = cf(
                stat_value(props, 'WakingTameFoodAffinityMultiplier', 0, 1.6))
            data['wakeFoodDeplMult'] = cf(
                stat_value(props, 'WakingTameFoodConsumptionRateMultiplier', 0,
                           2.0))

        data['foodConsumptionBase'] = cf(
            -stat_value(props, 'BaseFoodConsumptionRate', 0, -0.025000))  # pylint: disable=invalid-unary-operand-type
        data['foodConsumptionMult'] = cf(
            stat_value(props, 'ProneWaterFoodConsumptionMultiplier', 0, 1.00))

        if eats is not None:
            data['eats'] = eats
        if favorite_kibble is not None:
            data['favoriteKibble'] = favorite_kibble
        if special_food_values is not None:
            data['specialFoodValues'] = special_food_values

    return data
Beispiel #6
0
def values_for_species(asset: UAsset,
                       proxy: PrimalDinoCharacter) -> Optional[Dict[str, Any]]:
    assert asset.loader and asset.default_export and asset.default_class and asset.default_class.fullname

    char_props: PrimalDinoCharacter = ue.gathering.gather_properties(
        asset.default_export)
    dcsc_props: PrimalDinoStatusComponent = ark.gathering.gather_dcsc_properties(
        asset.default_export)
    dcsc_alt_props: PrimalDinoStatusComponent = ark.gathering.gather_dcsc_properties(
        asset.default_export, alt=True)

    # Having no name or tag is an indication that this is an intermediate class, not a spawnable species
    name = (str(char_props.DescriptiveName[0])
            or str(char_props.DinoNameTag[0])).strip()
    if not name:
        logger.debug(
            f"Species {asset.assetname} has no DescriptiveName or DinoNameTag - skipping"
        )
        return None

    # Also consider anything that doesn't override any base status value as non-spawnable
    if not any(
            dcsc_props.has_override('MaxStatusValues', n)
            for n in ARK_STAT_INDEXES):
        logger.debug(
            f"Species {asset.assetname} has no overridden stats - skipping")
        return None

    assert asset.assetname and asset.default_export and asset.default_class and asset.default_class.fullname

    modid: str = asset.loader.get_mod_id(asset.assetname) or ''
    overrides = get_overrides_for_species(asset.assetname, modid)

    if overrides.skip_export:
        return None

    bp: str = asset.default_class.fullname
    if bp.endswith('_C'):
        bp = bp[:-2]

    # Replace names to match ASB's hardcoding of specific species
    name = overrides.descriptive_name or name

    # Variant information
    variants = get_variants_from_assetname(
        asset.assetname, overrides) | get_variants_from_species(
            proxy, overrides)
    if variants:
        if should_skip_from_variants(variants, overrides):
            return None
        name = adjust_name_from_variants(name, variants, overrides)

    species: Dict[str, Any] = dict(name=name, blueprintPath=bp)
    if variants:
        species['variants'] = tuple(sorted(variants))

    # Stat data
    is_flyer = bool(char_props.bIsFlyerDino[0])
    if is_flyer:
        species['isFlyer'] = True
    normal_stats = gather_stat_data(dcsc_props, dcsc_props, is_flyer,
                                    ARK_STAT_INDEXES)
    alt_stats = gather_stat_data(dcsc_alt_props, dcsc_props, is_flyer,
                                 ARK_STAT_INDEXES)
    alt_stats = reduce_alt_stats(normal_stats, alt_stats)
    species['fullStatsRaw'] = normal_stats
    if alt_stats:
        species['altBaseStats'] = alt_stats

    # Set imprint multipliers
    stat_imprint_mults: List[float] = list()
    unique_mults = False
    for stat_index in ARK_STAT_INDEXES:
        imprint_mult = dcsc_props.DinoMaxStatAddMultiplierImprinting[
            stat_index]
        stat_imprint_mults.append(imprint_mult.rounded_value)

        # TODO: Optimize: Too many property look ups
        if DCSC_DEFAULTS.DinoMaxStatAddMultiplierImprinting[
                stat_index] != imprint_mult:
            unique_mults = True

    if unique_mults:
        species['statImprintMult'] = stat_imprint_mults

    # ImmobilizedBy format data
    immobilization_data = None
    try:
        immobilization_data = gather_immobilization_data(
            char_props, asset.loader)
    except (AssetNotFound, ModNotFound) as ex:
        logger.warning(
            f'Failure while gathering immobilization data for {asset.assetname}:\n\t{ex}'
        )
    if immobilization_data is not None:
        species['immobilizedBy'] = immobilization_data

    if not char_props.bUsesGender[0]:
        species['noGender'] = True

    # Breeding data
    if char_props.bCanHaveBaby[0]:  # TODO: Consider always including this data
        breeding_data = None
        try:
            breeding_data = gather_breeding_data(char_props, asset.loader)
        except (AssetNotFound, ModNotFound) as ex:
            logger.warning(
                f'Failure while gathering breeding data for {asset.assetname}:\n\t{ex}'
            )
        if breeding_data:
            species['breeding'] = breeding_data

    # Color data
    if char_props.bUseColorization[0]:
        colors = None
        try:
            colors = gather_color_data(char_props, overrides)
        except (AssetNotFound, ModNotFound) as ex:
            logger.warning(
                f'Failure while gathering color data for {asset.assetname}:\n\t{ex}'
            )
        if colors is not None:
            species['colors'] = colors

    # Taming data
    if char_props.bCanBeTamed[
            0] or True:  # ASB currently requires all species to have taming data
        taming = None
        try:
            taming = gather_taming_data(char_props, dcsc_props, overrides)
        except (AssetNotFound, ModNotFound) as ex:
            logger.warning(
                f'Failure while gathering taming data for {asset.assetname}:\n\t{ex}'
            )
        if taming:
            species['taming'] = taming

    # Bone damage multipliers
    dmg_mults = None
    try:
        dmg_mults = gather_damage_mults(char_props)
    except (AssetNotFound, ModNotFound) as ex:
        logger.warning(
            f'Failure while gathering bone damage data for {asset.assetname}:\n\t{ex}'
        )
    if dmg_mults:
        species['boneDamageAdjusters'] = dmg_mults

    # Misc data
    usesOxyWild = dcsc_props.bCanSuffocate[0]
    usesOxyTamed = True if usesOxyWild else dcsc_props.bCanSuffocateIfTamed[0]
    forceOxy = dcsc_props.bForceGainOxygen[0]
    doesntUseOxygen = not (usesOxyTamed or forceOxy)

    ETBHM = char_props.ExtraTamedBaseHealthMultiplier[0]
    TBHM = dcsc_props.TamedBaseHealthMultiplier[0] * ETBHM

    displayed_stats: int = 0

    for i in ARK_STAT_INDEXES:
        use_stat = not dcsc_props.DontUseValue[i]
        if use_stat and not (i == 3 and doesntUseOxygen):
            displayed_stats |= (1 << i)

    species['TamedBaseHealthMultiplier'] = cf(TBHM)
    species['displayedStats'] = displayed_stats

    stat_name_overrides = get_stat_name_overrides(dcsc_props)
    if stat_name_overrides:
        species['statNames'] = stat_name_overrides

    return species
Beispiel #7
0
def gather_breeding_data(props, loader: AssetLoader) -> Dict[str, Any]:
    data: Dict[str, Any] = dict(gestationTime=0, incubationTime=0)

    gestation_breeding = stat_value(props, 'bUseBabyGestation', 0, False)
    has_eggs = False

    if props['FertilizedEggItemsToSpawn'][0] and props[
            'FertilizedEggItemsToSpawn'][0][-1].values:
        # eggs = list(filter(lambda v: v and str(v) != 'None', props['FertilizedEggItemsToSpawn'][0][-1].values))
        eggs = [
            egg for egg in props['FertilizedEggItemsToSpawn'][0][-1].values
            if str(egg) != 'None'
        ]
        has_eggs = bool(eggs)

    if gestation_breeding:
        gestation_speed = stat_value(props, 'BabyGestationSpeed', 0,
                                     BABYGESTATIONSPEED_DEFAULT)
        extra_gestation_speed_m = stat_value(
            props, 'ExtraBabyGestationSpeedMultiplier', 0, 1.0)

        # TODO: Verify if these should really default to 1 - seems odd
        gestation_speed = gestation_speed or 1
        extra_gestation_speed_m = extra_gestation_speed_m or 1
        # 'gestationTime' = 1 / (Baby Gestation Speed × Extra Baby Gestation Speed Multiplier)
        data['gestationTime'] = cd((
            1 / gestation_speed / extra_gestation_speed_m
        ) if gestation_speed and extra_gestation_speed_m else None)

    elif has_eggs:
        fert_egg_asset = loader.load_related(eggs[0])
        fert_egg_props = ark.mod.gather_properties(fert_egg_asset)
        egg_decay = stat_value(fert_egg_props, 'EggLoseDurabilityPerSecond', 0,
                               1)
        extra_egg_decay_m = stat_value(
            fert_egg_props, 'ExtraEggLoseDurabilityPerSecondMultiplier', 0, 1)

        # 'incubationTime' = 100 / (Egg Lose Durability Per Second × Extra Egg Lose Durability Per Second Multiplier)
        data['incubationTime'] = cd((
            100 / egg_decay /
            extra_egg_decay_m) if egg_decay and extra_egg_decay_m else None)
        data['eggTempMin'] = cf(
            stat_value(fert_egg_props, 'EggMinTemperature', 0))
        data['eggTempMax'] = cf(
            stat_value(fert_egg_props, 'EggMaxTemperature', 0))

    # 'maturationTime' = 1 / (Baby Age Speed × Extra Baby Age Speed Multiplier)
    baby_age_speed = stat_value(props, 'BabyAgeSpeed', 0, 1)
    extra_baby_age_speed_m = stat_value(props, 'ExtraBabyAgeSpeedMultiplier',
                                        0, 1)

    data['maturationTime'] = cd((
        1 / baby_age_speed / extra_baby_age_speed_m
    ) if baby_age_speed and extra_baby_age_speed_m else None)
    data['matingCooldownMin'] = cf(
        stat_value(props, 'NewFemaleMinTimeBetweenMating', 0,
                   FEMALE_MINTIMEBETWEENMATING_DEFAULT))
    data['matingCooldownMax'] = cf(
        stat_value(props, 'NewFemaleMaxTimeBetweenMating', 0,
                   FEMALE_MAXTIMEBETWEENMATING_DEFAULT))

    return data