public static AttackData CreateAttackDataFromAttackProperty(BaseActor from, ConfigEntityAttackProperty attackProperty, ConfigEntityAttackEffect attackEffect, ConfigEntityCameraShake cameraShake) { AttackData data = new AttackData(); if (from is AvatarActor) { AvatarActor actor = (AvatarActor)from; data.attackCategoryTag = attackProperty.CategoryTagCombined; data.attackerClass = actor.config.CommonArguments.Class; data.attackerNature = (EntityNature)actor.avatarDataItem.Attribute; data.attackerCategory = 3; data.attackerAniDamageRatio = attackProperty.AniDamageRatio; data.frameHalt = attackProperty.FrameHalt; data.hitType = attackProperty.HitType; data.hitEffect = attackProperty.HitEffect; data.hitEffectAux = attackProperty.HitEffectAux; data.attackerLevel = (int)actor.level; data.retreatVelocity = attackProperty.RetreatVelocity; data.attackerCritChance = ((actor.critical + actor.GetProperty("Actor_CriticalDelta")) * (1f + actor.GetProperty("Actor_CriticalRatio"))) / ((float)(0x4b + (actor.level * 5))); data.attackerCritDamageRatio = 2f; data.attackerAttackValue = (float)actor.attack; data.attackerAttackPercentage = attackProperty.DamagePercentage; data.attackerAddedAttackValue = attackProperty.AddedDamageValue; data.attackerNormalDamage = attackProperty.NormalDamage; data.attackerNormalDamagePercentage = attackProperty.NormalDamagePercentage; data.addedAttackerNormalDamageRatio = actor.GetProperty("Actor_NormalAttackRatio"); data.attackerFireDamage = attackProperty.FireDamage; data.attackerFireDamagePercentage = attackProperty.FireDamagePercentage; data.addedAttackerFireDamageRatio = actor.GetProperty("Actor_FireAttackRatio"); data.attackerThunderDamage = attackProperty.ThunderDamage; data.attackerThunderDamagePercentage = attackProperty.ThunderDamagePercentage; data.addedAttackerThunderDamageRatio = actor.GetProperty("Actor_ThunderAttackRatio"); data.attackerIceDamage = attackProperty.IceDamage; data.attackerIceDamagePercentage = attackProperty.IceDamagePercentage; data.addedAttackerIceDamageRatio = actor.GetProperty("Actor_IceAttackRatio"); data.attackerAlienDamage = attackProperty.AlienDamage; data.attackerAlienDamagePercentage = attackProperty.AlienDamagePercentage; data.addedAttackerAlienDamageRatio = actor.GetProperty("Actor_AllienAttackRatio"); data.killEffect = attackProperty.KillEffect; data.hitEffectPattern = AttackResult.HitEffectPattern.Normal; data.isInComboCount = attackProperty.IsInComboCount; data.isAnimEventAttack = attackProperty.IsAnimEventAttack; data.noBreakFrameHaltAdd = attackProperty.NoBreakFrameHaltAdd; data.attackEffectPattern = attackEffect; if (data.attackEffectPattern == null) { data.attackEffectPattern = (data.attackerAniDamageRatio < 0.8f) ? InLevelData.InLevelMiscData.DefaultAvatarAttackSmallEffect : InLevelData.InLevelMiscData.DefaultAvatarAttackBigEffect; } if (Singleton <AvatarManager> .Instance.IsLocalAvatar(actor.runtimeID)) { data.attackCameraShake = cameraShake; } data.attackerAniDamageRatio += actor.GetProperty("Actor_AniDamageDelta"); data.attackerCritChance += actor.GetProperty("Actor_CriticalChanceDelta"); data.attackerCritDamageRatio += actor.GetProperty("Actor_CriticalDamageRatio"); data.attackerAttackValue = (data.attackerAttackValue + actor.GetProperty("Actor_AttackDelta")) * (1f + actor.GetProperty("Actor_AttackRatio")); data.addedDamageRatio = actor.GetProperty("Actor_AddedDamageRatio"); data.addedAttackRatio = actor.GetProperty("Actor_AddedAttackRatio"); data.attackerShieldDamageRatio = 1f + actor.GetProperty("Actor_ShieldDamageRatio"); data.attackerShieldDamageDelta = actor.GetProperty("Actor_ShieldDamageDelta"); data.retreatVelocity *= 1f + actor.GetProperty("Actor_RetreatRatio"); } else if (from is MonsterActor) { MonsterActor actor2 = (MonsterActor)from; data.attackCategoryTag = attackProperty.CategoryTagCombined; data.attackerClass = actor2.config.CommonArguments.Class; data.attackerNature = (EntityNature)actor2.metaConfig.nature; data.attackerCategory = 4; data.attackerAniDamageRatio = attackProperty.AniDamageRatio; data.frameHalt = attackProperty.FrameHalt; data.hitType = attackProperty.HitType; data.hitEffect = attackProperty.HitEffect; data.hitEffectAux = attackProperty.HitEffectAux; data.hitEffectPattern = AttackResult.HitEffectPattern.Normal; data.retreatVelocity = attackProperty.RetreatVelocity; data.attackerLevel = (int)actor2.level; data.attackerAttackValue = (float)actor2.attack; data.attackerAttackPercentage = attackProperty.DamagePercentage; data.attackerAddedAttackValue = attackProperty.AddedDamageValue; data.attackerNormalDamage = attackProperty.NormalDamage; data.attackerNormalDamagePercentage = attackProperty.NormalDamagePercentage; data.addedAttackerNormalDamageRatio = actor2.GetProperty("Actor_NormalAttackRatio"); data.attackerFireDamage = attackProperty.FireDamage; data.attackerFireDamagePercentage = attackProperty.FireDamagePercentage; data.addedAttackerFireDamageRatio = actor2.GetProperty("Actor_FireAttackRatio"); data.attackerThunderDamage = attackProperty.ThunderDamage; data.attackerThunderDamagePercentage = attackProperty.ThunderDamagePercentage; data.addedAttackerThunderDamageRatio = actor2.GetProperty("Actor_ThunderAttackRatio"); data.attackerIceDamage = attackProperty.IceDamage; data.attackerIceDamagePercentage = attackProperty.IceDamagePercentage; data.addedAttackerIceDamageRatio = actor2.GetProperty("Actor_IceAttackRatio"); data.attackerAlienDamage = attackProperty.AlienDamage; data.attackerAlienDamagePercentage = attackProperty.AlienDamagePercentage; data.addedAttackerAlienDamageRatio = actor2.GetProperty("Actor_AllienAttackRatio"); data.noTriggerEvadeAndDefend = attackProperty.NoTriggerEvadeAndDefend; data.attackEffectPattern = attackEffect; if (data.attackEffectPattern == null) { data.attackEffectPattern = InLevelData.InLevelMiscData.DefaultMonsterAttackEffect; } data.attackCameraShake = cameraShake; data.isAnimEventAttack = attackProperty.IsAnimEventAttack; data.attackerAniDamageRatio += actor2.GetProperty("Actor_AniDamageDelta"); data.attackerAttackValue = (data.attackerAttackValue + actor2.GetProperty("Actor_AttackDelta")) * (1f + actor2.GetProperty("Actor_AttackRatio")); data.addedAttackRatio = actor2.GetProperty("Actor_AddedAttackRatio"); data.attackerShieldDamageRatio = 1f + actor2.GetProperty("Actor_ShieldDamageRatio"); data.attackerShieldDamageDelta = actor2.GetProperty("Actor_ShieldDamageDelta"); data.retreatVelocity *= 1f + actor2.GetProperty("Actor_RetreatRatio"); } else if (from is BaseAbilityActor) { BaseAbilityActor actor3 = (BaseAbilityActor)from; data.attackCategoryTag = attackProperty.CategoryTagCombined; data.attackerClass = EntityClass.Default; data.attackerNature = EntityNature.Pure; data.attackerCategory = 7; data.attackerAniDamageRatio = attackProperty.AniDamageRatio; data.frameHalt = attackProperty.FrameHalt; data.hitType = attackProperty.HitType; data.hitEffect = attackProperty.HitEffect; data.hitEffectAux = attackProperty.HitEffectAux; data.retreatVelocity = attackProperty.RetreatVelocity; data.attackerLevel = 0; data.attackerAttackPercentage = attackProperty.DamagePercentage; data.attackerAttackValue = (float)actor3.attack; data.attackerAttackPercentage = attackProperty.DamagePercentage; data.attackerAddedAttackValue = attackProperty.AddedDamageValue; data.attackerNormalDamage = attackProperty.NormalDamage; data.attackerNormalDamagePercentage = attackProperty.NormalDamagePercentage; data.addedAttackerNormalDamageRatio = actor3.GetProperty("Actor_NormalAttackRatio"); data.attackerFireDamage = attackProperty.FireDamage; data.attackerFireDamagePercentage = attackProperty.FireDamagePercentage; data.addedAttackerFireDamageRatio = actor3.GetProperty("Actor_FireAttackRatio"); data.attackerThunderDamage = attackProperty.ThunderDamage; data.attackerThunderDamagePercentage = attackProperty.ThunderDamagePercentage; data.addedAttackerThunderDamageRatio = actor3.GetProperty("Actor_ThunderAttackRatio"); data.attackerIceDamage = attackProperty.IceDamage; data.attackerIceDamagePercentage = attackProperty.IceDamagePercentage; data.addedAttackerIceDamageRatio = actor3.GetProperty("Actor_IceAttackRatio"); data.attackerAlienDamage = attackProperty.AlienDamage; data.attackerAlienDamagePercentage = attackProperty.AlienDamagePercentage; data.addedAttackerAlienDamageRatio = actor3.GetProperty("Actor_AllienAttackRatio"); data.attackEffectPattern = attackEffect; if (data.attackEffectPattern == null) { data.attackEffectPattern = InLevelData.InLevelMiscData.DefaultMonsterAttackEffect; } data.attackCameraShake = cameraShake; data.isAnimEventAttack = attackProperty.IsAnimEventAttack; data.attackerAniDamageRatio += actor3.GetProperty("Actor_AniDamageDelta"); data.attackerAttackValue = (data.attackerAttackValue + actor3.GetProperty("Actor_AttackDelta")) * (1f + actor3.GetProperty("Actor_AttackRatio")); data.addedAttackRatio = actor3.GetProperty("Actor_AddedAttackRatio"); data.attackerShieldDamageRatio = 1f + actor3.GetProperty("Actor_ShieldDamageRatio"); data.attackerShieldDamageDelta = actor3.GetProperty("Actor_ShieldDamageDelta"); data.retreatVelocity *= 1f + actor3.GetProperty("Actor_RetreatRatio"); } data.resolveStep = AttackData.AttackDataStep.AttackerResolved; return(data); }
public static void ResolveAttackDataByAttackee(BaseActor to, AttackData attackData) { if (!attackData.rejected) { if (to is AvatarActor) { AvatarActor actor = (AvatarActor)to; bool flag = Singleton <LevelScoreManager> .Instance.IsAllowLevelPunish(); int levelDifference = Mathf.Clamp(attackData.attackerLevel - Singleton <PlayerModule> .Instance.playerData.teamLevel, 0, 10); if ((attackData.attackerCategory == 4) && flag) { attackData.attackerAniDamageRatio *= 1f + AvatarDefencePunishMetaDataReader.GetAvatarDefencePunishMetaDataByKey(levelDifference).AttackRatioIncrease; } attackData.attackeeAniDefenceRatio = GetAnimDefenceRatio(actor); attackData.damage = (((attackData.attackerAttackValue * attackData.attackerAttackPercentage) + attackData.attackerAddedAttackValue) * (1f + attackData.addedAttackRatio)) * (1f + attackData.addedDamageRatio); float defence = (actor.defense + actor.GetProperty("Actor_DefenceDelta")) * (1f + actor.GetProperty("Actor_DefenceRatio")); float defenceRatio = GetDefenceRatio(defence, attackData.attackerLevel); float num4 = (1f - defenceRatio) * actor.GetProperty("Actor_DamageReduceRatio"); attackData.attackeeAddedDamageTakeRatio += actor.GetProperty("Actor_DamageTakeRatio"); attackData.damage = (attackData.damage * num4) * (1f + attackData.attackeeAddedDamageTakeRatio); attackData.plainDamage = (((((attackData.attackerNormalDamage + (attackData.attackerAttackValue * attackData.attackerNormalDamagePercentage)) * (1f + attackData.addedAttackerNormalDamageRatio)) * (1f + attackData.addedDamageRatio)) * actor.GetProperty("Actor_ResistAllElementAttackRatio")) * actor.GetProperty("Actor_ResistNormalAttackRatio")) * (1f + actor.GetProperty("Actor_NormalAttackTakeRatio")); attackData.fireDamage = (((((attackData.attackerFireDamage + (attackData.attackerAttackValue * attackData.attackerFireDamagePercentage)) * (1f + attackData.addedAttackerFireDamageRatio)) * (1f + attackData.addedDamageRatio)) * actor.GetProperty("Actor_ResistAllElementAttackRatio")) * actor.GetProperty("Actor_ResistFireAttackRatio")) * (1f + actor.GetProperty("Actor_FireAttackTakeRatio")); attackData.thunderDamage = (((((attackData.attackerThunderDamage + (attackData.attackerAttackValue * attackData.attackerThunderDamagePercentage)) * (1f + attackData.addedAttackerThunderDamageRatio)) * (1f + attackData.addedDamageRatio)) * actor.GetProperty("Actor_ResistAllElementAttackRatio")) * actor.GetProperty("Actor_ResistThunderAttackRatio")) * (1f + actor.GetProperty("Actor_ThunderAttackTakeRatio")); attackData.iceDamage = (((((attackData.attackerIceDamage + (attackData.attackerAttackValue * attackData.attackerIceDamagePercentage)) * (1f + attackData.addedAttackerIceDamageRatio)) * (1f + attackData.addedDamageRatio)) * actor.GetProperty("Actor_ResistAllElementAttackRatio")) * actor.GetProperty("Actor_ResistIceAttackRatio")) * (1f + actor.GetProperty("Actor_IceAttackTakeRatio")); attackData.alienDamage = (((((attackData.attackerAlienDamage + (attackData.attackerAttackValue * attackData.attackerAlienDamagePercentage)) * (1f + attackData.addedAttackerAlienDamageRatio)) * (1f + attackData.addedDamageRatio)) * actor.GetProperty("Actor_ResistAllElementAttackRatio")) * actor.GetProperty("Actor_ResistAllienAttackRatio")) * (1f + actor.GetProperty("Actor_AllienAttackTakeRatio")); attackData.attackeeNature = (EntityNature)actor.avatarDataItem.Attribute; attackData.attackeeClass = actor.config.CommonArguments.Class; float num5 = GetNatureDamageBonusRatio(attackData.attackerNature, attackData.attackeeNature, actor); float damageIncreaseRate = 0f; if ((attackData.attackerCategory == 4) && flag) { damageIncreaseRate = AvatarDefencePunishMetaDataReader.GetAvatarDefencePunishMetaDataByKey(levelDifference).DamageIncreaseRate; } float num7 = Mathf.Clamp((float)(1f - attackData.attackerAddedAllDamageReduceRatio), (float)0f, (float)1f); attackData.damage *= (num5 * (1f + damageIncreaseRate)) * num7; attackData.plainDamage *= (num5 * (1f + damageIncreaseRate)) * num7; attackData.fireDamage *= (num5 * (1f + damageIncreaseRate)) * num7; attackData.thunderDamage *= (num5 * (1f + damageIncreaseRate)) * num7; attackData.iceDamage *= (num5 * (1f + damageIncreaseRate)) * num7; attackData.alienDamage *= (num5 * (1f + damageIncreaseRate)) * num7; attackData.natureDamageRatio = num5; if (!Singleton <AvatarManager> .Instance.IsLocalAvatar(actor.runtimeID)) { attackData.attackCameraShake = null; } attackData.attackeeAniDefenceRatio += actor.GetProperty("Actor_AniDefenceDelta"); } else if (to is MonsterActor) { MonsterActor actor2 = (MonsterActor)to; int num8 = Mathf.Clamp(((int)actor2.level) - Singleton <PlayerModule> .Instance.playerData.teamLevel, 0, 10); if ((attackData.attackerCategory == 3) && Singleton <LevelScoreManager> .Instance.IsAllowLevelPunish()) { attackData.attackerAniDamageRatio *= 1f - AvatarAttackPunishMetaDataReader.GetAvatarAttackPunishMetaDataByKey(num8).AttackRatioReduce; } attackData.attackeeAniDefenceRatio = GetAnimDefenceRatio(actor2); attackData.damage = (((attackData.attackerAttackValue * attackData.attackerAttackPercentage) + attackData.attackerAddedAttackValue) * (1f + attackData.addedAttackRatio)) * (1f + attackData.addedDamageRatio); float num9 = (actor2.defense + actor2.GetProperty("Actor_DefenceDelta")) * (1f + actor2.GetProperty("Actor_DefenceRatio")); float num10 = GetDefenceRatio(num9, attackData.attackerLevel); float num11 = (1f - num10) * actor2.GetProperty("Actor_DamageReduceRatio"); attackData.attackeeAddedDamageTakeRatio += actor2.GetProperty("Actor_DamageTakeRatio"); attackData.damage = (attackData.damage * num11) * (1f + attackData.attackeeAddedDamageTakeRatio); attackData.plainDamage = (((((attackData.attackerNormalDamage + (attackData.attackerAttackValue * attackData.attackerNormalDamagePercentage)) * (1f + attackData.addedAttackerNormalDamageRatio)) * (1f + attackData.addedDamageRatio)) * actor2.GetProperty("Actor_ResistAllElementAttackRatio")) * actor2.GetProperty("Actor_ResistNormalAttackRatio")) * (1f + actor2.GetProperty("Actor_NormalAttackTakeRatio")); attackData.fireDamage = (((((attackData.attackerFireDamage + (attackData.attackerAttackValue * attackData.attackerFireDamagePercentage)) * (1f + attackData.addedAttackerFireDamageRatio)) * (1f + attackData.addedDamageRatio)) * actor2.GetProperty("Actor_ResistAllElementAttackRatio")) * actor2.GetProperty("Actor_ResistFireAttackRatio")) * (1f + actor2.GetProperty("Actor_FireAttackTakeRatio")); attackData.thunderDamage = (((((attackData.attackerThunderDamage + (attackData.attackerAttackValue * attackData.attackerThunderDamagePercentage)) * (1f + attackData.addedAttackerThunderDamageRatio)) * (1f + attackData.addedDamageRatio)) * actor2.GetProperty("Actor_ResistAllElementAttackRatio")) * actor2.GetProperty("Actor_ResistThunderAttackRatio")) * (1f + actor2.GetProperty("Actor_ThunderAttackTakeRatio")); attackData.iceDamage = (((((attackData.attackerIceDamage + (attackData.attackerAttackValue * attackData.attackerIceDamagePercentage)) * (1f + attackData.addedAttackerIceDamageRatio)) * (1f + attackData.addedDamageRatio)) * actor2.GetProperty("Actor_ResistAllElementAttackRatio")) * actor2.GetProperty("Actor_ResistIceAttackRatio")) * (1f + actor2.GetProperty("Actor_IceAttackTakeRatio")); attackData.alienDamage = (((((attackData.attackerAlienDamage + (attackData.attackerAttackValue * attackData.attackerAlienDamagePercentage)) * (1f + attackData.addedAttackerAlienDamageRatio)) * (1f + attackData.addedDamageRatio)) * actor2.GetProperty("Actor_ResistAllElementAttackRatio")) * actor2.GetProperty("Actor_ResistAllienAttackRatio")) * (1f + actor2.GetProperty("Actor_AllienAttackTakeRatio")); attackData.attackeeNature = (EntityNature)actor2.metaConfig.nature; attackData.attackeeClass = actor2.config.CommonArguments.Class; float num12 = GetNatureDamageBonusRatio(attackData.attackerNature, attackData.attackeeNature, actor2); float damageReduceRate = 0f; if ((attackData.attackerCategory == 3) && Singleton <LevelScoreManager> .Instance.IsAllowLevelPunish()) { damageReduceRate = AvatarAttackPunishMetaDataReader.GetAvatarAttackPunishMetaDataByKey(num8).DamageReduceRate; } float num14 = Mathf.Clamp((float)(1f - attackData.attackerAddedAllDamageReduceRatio), (float)0f, (float)1f); attackData.damage *= (num12 * (1f - damageReduceRate)) * num14; attackData.plainDamage *= (num12 * (1f - damageReduceRate)) * num14; attackData.fireDamage *= (num12 * (1f - damageReduceRate)) * num14; attackData.thunderDamage *= (num12 * (1f - damageReduceRate)) * num14; attackData.iceDamage *= (num12 * (1f - damageReduceRate)) * num14; attackData.alienDamage *= (num12 * (1f - damageReduceRate)) * num14; attackData.natureDamageRatio = num12; if (actor2.monster.IsAnimatorInTag(MonsterData.MonsterTagGroup.Throw)) { attackData.retreatVelocity *= actor2.config.CommonArguments.BePushedSpeedRatioThrow; } else { attackData.retreatVelocity *= actor2.config.CommonArguments.BePushedSpeedRatio; } attackData.retreatVelocity *= 1f + actor2.GetProperty("Actor_BeRetreatRatio"); if (attackData.isAnimEventAttack && (UnityEngine.Random.value < attackData.attackerCritChance)) { attackData.damage *= attackData.attackerCritDamageRatio; attackData.hitLevel = AttackResult.ActorHitLevel.Critical; } attackData.attackeeAniDefenceRatio += actor2.GetProperty("Actor_AniDefenceDelta"); if (attackData.frameHalt > 1) { attackData.frameHalt += 2; } if ((attackData.attackeeAniDefenceRatio > attackData.attackerAniDamageRatio) && (attackData.frameHalt > 1)) { attackData.frameHalt += attackData.noBreakFrameHaltAdd; } } else if (to is PropObjectActor) { PropObjectActor actor3 = (PropObjectActor)to; attackData.attackeeAniDefenceRatio = 0f; attackData.beHitEffectPattern = actor3.config.BeHitEffect; attackData.damage = (((attackData.attackerAttackValue * attackData.attackerAttackPercentage) + attackData.attackerAddedAttackValue) * (1f + attackData.addedAttackRatio)) * (1f + attackData.addedDamageRatio); attackData.plainDamage = (((((attackData.attackerNormalDamage + (attackData.attackerAttackValue * attackData.attackerNormalDamagePercentage)) * (1f + attackData.addedAttackerNormalDamageRatio)) * (1f + attackData.addedDamageRatio)) * actor3.GetProperty("Actor_ResistAllElementAttackRatio")) * actor3.GetProperty("Actor_ResistNormalAttackRatio")) * (1f + actor3.GetProperty("Actor_NormalAttackTakeRatio")); attackData.fireDamage = (((((attackData.attackerFireDamage + (attackData.attackerAttackValue * attackData.attackerFireDamagePercentage)) * (1f + attackData.addedAttackerFireDamageRatio)) * (1f + attackData.addedDamageRatio)) * actor3.GetProperty("Actor_ResistAllElementAttackRatio")) * actor3.GetProperty("Actor_ResistFireAttackRatio")) * (1f + actor3.GetProperty("Actor_FireAttackTakeRatio")); attackData.thunderDamage = (((((attackData.attackerThunderDamage + (attackData.attackerAttackValue * attackData.attackerThunderDamagePercentage)) * (1f + attackData.addedAttackerThunderDamageRatio)) * (1f + attackData.addedDamageRatio)) * actor3.GetProperty("Actor_ResistAllElementAttackRatio")) * actor3.GetProperty("Actor_ResistThunderAttackRatio")) * (1f + actor3.GetProperty("Actor_ThunderAttackTakeRatio")); attackData.iceDamage = (((((attackData.attackerIceDamage + (attackData.attackerAttackValue * attackData.attackerIceDamagePercentage)) * (1f + attackData.addedAttackerIceDamageRatio)) * (1f + attackData.addedDamageRatio)) * actor3.GetProperty("Actor_ResistAllElementAttackRatio")) * actor3.GetProperty("Actor_ResistIceAttackRatio")) * (1f + actor3.GetProperty("Actor_IceAttackTakeRatio")); attackData.alienDamage = (((((attackData.attackerAlienDamage + (attackData.attackerAttackValue * attackData.attackerAlienDamagePercentage)) * (1f + attackData.addedAttackerAlienDamageRatio)) * (1f + attackData.addedDamageRatio)) * actor3.GetProperty("Actor_ResistAllElementAttackRatio")) * actor3.GetProperty("Actor_ResistAllienAttackRatio")) * (1f + actor3.GetProperty("Actor_AllienAttackTakeRatio")); attackData.attackeeAniDefenceRatio += actor3.GetProperty("Actor_AniDefenceDelta"); if (attackData.frameHalt > 1) { attackData.frameHalt += 2; } } attackData.resolveStep = AttackData.AttackDataStep.AttackeeResolved; } }