机制代码
录入:EvilP
作者:
翻译:
录入时间:2025-10-26 03:17:06
最后修改时间:2025-11-12 20:50:38报错页面:
传送门
Mirage - 海市蜃楼复制英雄
private static TransferSide GenTransferSideByMirage(WorldHero _hero, Party _party, bool _locatedInAlliedAreas, int _extraStat)
{
TransferHero transferHero = new TransferHero
{
configId = _hero.data.configSid,
mana = _hero.data.mana,
manaMax = _hero.currentStats.GetMaxManaPoints(),
heroMagics = _hero.logic.allMagics,
heroStat = new HeroStat(),
heroBonuses = _hero.logic.bonuses,
level = _hero.data.currentLevel,
exp = _hero.data.currentExp,
dataEnergies = _hero.data.dataEnergies,
expTolevel = _hero.logic.exp.GetMaxGradeForLevel(_hero.data.currentLevel),
nativeBiome = _hero.logic.data.config.nativeBiome
};
transferHero.heroStat.Copy(_hero.currentStats);
HeroStat heroStat = new HeroStat();
if (_extraStat == -1)
{
_extraStat = _hero.data.currentLevel;
}
heroStat.defence += _extraStat;
heroStat.offence += _extraStat;
heroStat.spellPower += _extraStat;
heroStat.intelligence += _extraStat;
transferHero.heroStat.Plus(heroStat);
transferHero.manaMax = transferHero.heroStat.GetMaxManaPoints();
transferHero.mana = transferHero.heroStat.GetMaxManaPoints();
TransferUnit[] array = new TransferUnit[_hero.data.party.units.Count];
for (int i = 0; i < array.Length; i++)
{
Hex.Session.Data.Unit unit = _party.data.units[i];
TransferUnit transferUnit = new TransferUnit(unit.sid, unit.stacks, unit.slotPos);
array[i] = transferUnit;
}
TransferSide transferSide = new TransferSide(-1, TransferSide.EType.Type_Hero, TransferSide.EControlType.AI, array, _hero.side.logic.bonuses, -1, -1, _locatedInAlliedAreas, allowMagicInAutobattle: true, null, TransferSideName.GetForMirage());
transferSide.hero = transferHero;
transferSide.SortUnitsBySlotPos();
return transferSide;
}
public void UpdateParty(DataParty _heroParty, ObjMirageConfig _config)
{
dataParty.units.Clear();
int num = _config.extraValue / _heroParty.units.Count;
for (int i = 0; i < _heroParty.units.Count; i++)
{
Unit unit = _heroParty.units[i];
UnitLogicConfig unitLogicConfig = DB.me.unitLogics.Get(unit.sid);
int num2 = num / unitLogicConfig.squadValue;
Unit item = new Unit
{
sid = unit.sid,
stacks = (int)((float)(unit.stacks + num2) * (1f + _config.squadMultiply)),
slotPos = unit.slotPos
};
dataParty.units.Add(item);
}
}
Chimerologist - 嵌合学家转化
public void Convertation(WorldHero _hero)
{
hero = _hero;
if (CanConvert())
{
int summaValue = GetSummaValue();
ResNameAndCost[] costResArray = config.costResArray;
foreach (ResNameAndCost resNameAndCost in costResArray)
{
hero.side.res.Subtract(resNameAndCost.name, resNameAndCost.cost);
}
UnitLogicConfig unitsWithRandom = UnitsSearchUtility.GetUnitsWithRandom((UnitLogicConfig x) => x.squadValue <= summaValue, (UnitLogicConfig x) => !blockedSids.Contains(x.sid));
int stacks = summaValue / unitsWithRandom.squadValue;
Unit unit = new Unit
{
sid = unitsWithRandom.sid,
stacks = stacks
};
EventsDispatcher.me.Invoke(EEvent.QuestUnitLose, new EaUnitLose
{
units = party.data.units,
indexSide = _hero.side.index
});
party.Clear();
party.AddInSlot(unit.sid, unit.stacks, 6);
}
}
Flee or Fight - 野兵战斗还是逃跑
public static void TryStartBattleVsSquad(WorldHero _hero, WorldSquad _squad)
{
if (UIGlobalMode.isFilmingMode && _hero.side.isMySide)
{
StartBattleVsSquad(_hero, _squad);
return;
}
bool flag = (double)((float)_squad.GetSumValue() / (float)_hero.GetSumValue(_battleVsSquad: true)) <= 0.5;
bool flag2 = DiplomacyUtility.CanApply(_hero, _squad);
bool flag3 = _hero.side.ai != null;
bool isMySide = _hero.side.isMySide;
if (flag3)
{
flag2 = false;
}
if (!_squad.data.isEscape)
{
flag = false;
flag2 = false;
}
if (flag2)
{
if (!flag3 && isMySide)
{
BhUIs.me.OpenDiplomacy(_squad, _hero);
}
}
else if (flag)
{
if (_hero.side.sideMapCheats.cheatWinFight)
{
StartBattleVsSquad(_hero, _squad);
}
else if (flag3)
{
StartBattleVsSquad(_hero, _squad);
}
else if (isMySide)
{
BhUIs.me.OpenSquadEscapePanel(_squad, _hero);
}
}
else
{
StartBattleVsSquad(_hero, _squad);
}
}
Diplomacy - 外交
{
"unitCostExtraCharge": 1.0,
"squadUnitsPoints": [ 25, 50, 75, 125, 225, 425, 1250 ],
"reactionTypeModifiers": [ 0, 2.0, 1.0, 0.75, 0.5, 0 ],
"heroUnitsPoints": [ 9, 13, 21, 31, 44, 64, 150 ],
"fullUnitsMatchBonus": 1.5,
"partialUnitsMatchBonus": 0.75,
"heroStatsModifier": 10,
"heroLevelModifier": 100,
"valueChancePairs":
[
{ "value": 0.00, "chance": -0.40 },
{ "value": 0.40, "chance": -0.30 },
{ "value": 0.60, "chance": -0.20 },
{ "value": 0.80, "chance": -0.10 },
{ "value": 1.00, "chance": 0.00 },
{ "value": 1.20, "chance": 0.05 },
{ "value": 1.40, "chance": 0.10 }
]
}
===========================
public static bool CanApply(WorldHero _hero, WorldSquad _squad, out string _info)
{
bool enableDiplomacy = _hero.currentStats.enableDiplomacy;
if (_squad.data.isCampaignFreeDiplomacy)
{
_info = "\nisCampaignFreeDiplomacy";
return true;
}
if (_squad.data.isCampaingDiplomacy)
{
_info = "\nisCampaignDiplomacy";
return true;
}
if (_squad.data.reactionType == ESquadReactionType.Docile)
{
_info = "\nDocile reaction type";
return true;
}
if (!enableDiplomacy)
{
_info = "\nSkill Diplomacy is not learned";
return false;
}
if (_squad.data.reactionType == ESquadReactionType.Aggressive)
{
_info = $"\nThis squad is {_squad.data.reactionType}";
return false;
}
_info = $"\nThis squad is {_squad.data.reactionType}";
DiplomacyInfoConfig diplomacyInfoConfig = DB.me.diplomacyInfoConfig;
int squadUnitsPoints = GetSquadUnitsPoints(_hero, _squad, diplomacyInfoConfig);
int heroUnitsPoints = GetHeroUnitsPoints(_hero, _squad, diplomacyInfoConfig);
bool flag = heroUnitsPoints >= squadUnitsPoints;
_info = (flag ? "\nYou can take squad units" : "\nYou need more points to take squad units");
_info += $"\nhero points: {heroUnitsPoints}, squad points: {squadUnitsPoints}";
return flag;
}
===========================
private static int GetSquadUnitsPoints(WorldHero _hero, WorldSquad _squad, DiplomacyInfoConfig _diplomacyInfoConfig)
{
float num = CalculateSquadUnitsPoints(_hero, _squad, _diplomacyInfoConfig);
float modifierForReactionType = _diplomacyInfoConfig.GetModifierForReactionType(_squad.data.reactionType);
return (int)(num * modifierForReactionType);
}
===========================
private static float CalculateSquadUnitsPoints(WorldHero _hero, WorldSquad _squad, DiplomacyInfoConfig _diplomacyInfoConfig)
{
float diplomacyFractionPerBonus = _hero.currentStats.diplomacyFractionPerBonus;
string fraction = _hero.data.config.fraction;
float num = 0f;
foreach (DataSquadUnit unit in _squad.data.units)
{
float num2 = _diplomacyInfoConfig.GetSquadUnitTierPoint(unit.logicConfig.tier) * unit.amount;
if (string.Equals(unit.logicConfig.fraction, fraction))
{
num2 *= 1f + diplomacyFractionPerBonus;
}
num += num2;
}
return num;
}
===========================
private static int GetHeroUnitsPoints(WorldHero _hero, WorldSquad _squad, DiplomacyInfoConfig _diplomacyInfoConfig)
{
float num = CalculateHeroUnitsPoints(_hero, _squad, _diplomacyInfoConfig);
float num2 = GetSumHeroStats(_hero) * _diplomacyInfoConfig.heroStatsModifier;
float num3 = (float)_hero.data.currentLevel * _diplomacyInfoConfig.heroLevelModifier;
float diplomacyEfficiencyPerBonus = _hero.currentStats.diplomacyEfficiencyPerBonus;
float valueRatio = GetValueRatio(_hero, _squad);
float chanceForValue = _diplomacyInfoConfig.GetChanceForValue(valueRatio);
return (int)((num + num2 + num3) * (1f + diplomacyEfficiencyPerBonus) * (1f + chanceForValue));
}
===========================
private static float GetValueRatio(WorldHero _hero, WorldSquad _squad)
{
int sumValue = _hero.GetSumValue(_battleVsSquad: true);
int sumValue2 = _squad.GetSumValue();
return (float)sumValue / (float)sumValue2;
}
===========================
public int GetSumValue(bool _battleVsSquad = false)
{
int tradeValue = GetTradeValue();
if (!_battleVsSquad)
{
return tradeValue;
}
return (int)((float)tradeValue * (1f + currentStats.diplomacySumValuePerBonus));
}
public int GetTradeValue()
{
return data.GetSumValue() + Mathf.RoundToInt((float)GetItemsValue() * 0.1f);
}
public int GetItemsValue()
{
int num = 0;
Items items = Hex.Session.Logic.Logic.me.items;
foreach (KeyValuePair> item2 in slots.itemsByType)
{
foreach (int item3 in item2.Value)
{
if (item3 >= 0)
{
Item item = items.ById(item3);
num += item.data.config.goodsValue;
}
}
}
return num;
}
===========================
private static float CalculateHeroUnitsPoints(WorldHero _hero, WorldSquad _squad, DiplomacyInfoConfig _diplomacyInfoConfig)
{
List units = _hero.party.data.units;
HashSet uniqueSquadUnits = GetUniqueSquadUnits(_squad);
float num = 0f;
foreach (Unit item in units)
{
UnitLogicConfig logicConfig = item.logicConfig;
int heroUnitTierPoint = _diplomacyInfoConfig.GetHeroUnitTierPoint(logicConfig.tier);
float unitsMatchModifer = GetUnitsMatchModifer(logicConfig, uniqueSquadUnits, _diplomacyInfoConfig);
float num2 = (float)(heroUnitTierPoint * item.stacks) * (1f + unitsMatchModifer);
num += num2;
}
return num;
}
===========================
private static float GetUnitsMatchModifer(UnitLogicConfig _unit, HashSet _uniqueSquadUnits, DiplomacyInfoConfig _diplomacyInfoConfig)
{
float num = 0f;
if (_uniqueSquadUnits.Contains(_unit.sid))
{
num += _diplomacyInfoConfig.fullUnitsMatchBonus;
}
if (_unit.version == EUnitVersion.Base)
{
UnitLogicConfig upgradeVersion = UnitsVersionUtility.GetUpgradeVersion(_unit);
if (upgradeVersion == null)
{
Logger.Error("No upgrade for unit " + _unit.sid);
return num;
}
UnitLogicConfig oppositeUpgradeVersion = UnitsVersionUtility.GetOppositeUpgradeVersion(upgradeVersion);
if (_uniqueSquadUnits.Contains(upgradeVersion.sid))
{
num += _diplomacyInfoConfig.partialUnitsMatchBonus;
}
if (uniqueSquadUnitsSet.Contains(oppositeUpgradeVersion.sid))
{
num += _diplomacyInfoConfig.partialUnitsMatchBonus;
}
}
else
{
UnitLogicConfig baseVersion = UnitsVersionUtility.GetBaseVersion(_unit);
UnitLogicConfig oppositeUpgradeVersion2 = UnitsVersionUtility.GetOppositeUpgradeVersion(_unit);
if (_uniqueSquadUnits.Contains(baseVersion.sid))
{
num += _diplomacyInfoConfig.partialUnitsMatchBonus;
}
if (oppositeUpgradeVersion2 == null)
{
Logger.Error("No alt upgrade for unit " + _unit.sid);
return num;
}
if (uniqueSquadUnitsSet.Contains(oppositeUpgradeVersion2.sid))
{
num += _diplomacyInfoConfig.partialUnitsMatchBonus;
}
}
return num;
}
===========================
private static float GetSumHeroStats(WorldHero _hero)
{
HeroStat currentStats = _hero.currentStats;
return currentStats.offence + currentStats.defence + currentStats.spellPower + currentStats.intelligence;
}
===========================
private static float GetValueRatio(WorldHero _hero, WorldSquad _squad)
{
int sumValue = _hero.GetSumValue(_battleVsSquad: true);
int sumValue2 = _squad.GetSumValue();
return (float)sumValue / (float)sumValue2;
}
===========================
private static HashSet GetUniqueSquadUnits(WorldSquad _squad)
{
uniqueSquadUnitsSet.Clear();
foreach (DataSquadUnit unit in _squad.data.units)
{
uniqueSquadUnitsSet.Add(unit.sid);
}
return uniqueSquadUnitsSet;
}
Get Stacks - 野怪分组原则
private static int GetStacksByValue(int _heroValue, int _squadValue)
{
float num = (float)_squadValue / (float)_heroValue;
if (num >= 1.6f)
{
return 7;
}
if (num >= 1.4f)
{
return 6;
}
if (num >= 1.2f)
{
return 5;
}
if (num >= 1f)
{
return 4;
}
if (num >= 0.8f)
{
return 3;
}
if (num >= 0.6f)
{
return 2;
}
return 1;
}
Summoning Rite - 召唤仪式数量算法
public override int EvaluateForAiUnit(ICaster caster, ICastSource castSource, Unit target, BattleAiParams aiParams, HashSet tempCanReachAlly, HashSet history, Dictionary unitsValues)
{
if (target == null)
{
return 0;
}
if (target.fieldData.isSummon)
{
return 0;
}
if (target.transferUnit == null)
{
return 0;
}
if (caster is Unit unit)
{
int num = (int)((float)target.transferUnit.stacks * percent * (float)target.stats.hp / (float)unit.logicConfig.stats.hp);
if (!unit.stats.ignoreFinalSummonBonus)
{
num = Mathf.RoundToInt((float)num * (1f + unit.stats.finalSummonBonusPercent));
}
num = Mathf.Min(num, unit.data.allStacks);
_ = target.stats.hp;
string[] mechValues = aiParams.GetMechValues(mechType);
int num2 = ConfigParserUtility.ParseFromStringArray(mechValues, 0, int.Parse, 0);
float num3 = ConfigParserUtility.ParseFromStringArray(mechValues, 1, ConfigParserUtility.ParseFloat, 0f);
return num2 + (int)(num3 * (float)num * (float)target.logicConfig.squadValue);
}
return 0;
}
public float GetSumByTags(IEnumerable tags, UnitStat unitStat)
{
float num = 1f;
foreach (string tag in tags)
{
if (!idToPosSumDict.ContainsKey(tag) && !idToNegSumDict.ContainsKey(tag))
{
continue;
}
float num2 = 1f;
if (idToPosSumDict.ContainsKey(tag))
{
float num3 = idToPosSumDict[tag];
float num4 = 0f;
if (unitStat.outDmgMultipliersSet.positiveSums.ContainsKey(tag))
{
num4 = unitStat.outDmgMultipliersSet.positiveSums[tag];
}
if (num4 < -1f)
{
num4 = -1f;
}
num2 += num3 * (1f + num4);
}
if (idToNegSumDict.ContainsKey(tag))
{
float num5 = idToNegSumDict[tag];
float num6 = 0f;
if (unitStat.outDmgMultipliersSet.negativeSums.ContainsKey(tag))
{
num6 = unitStat.outDmgMultipliersSet.negativeSums[tag];
}
if (num6 < -1f)
{
num6 = -1f;
}
num2 += num5 * (1f + num6);
}
num *= num2;
}
if (num < 0.1f)
{
num = 0.1f;
}
return num;
}
Hero Skills Randomizer - 英雄升级技能生成
public class HeroSkillsRandomizer
{
private struct SkillRollArgs
{
public bool isSkillsCountEqualToMax;
public bool haveAllSkillsMaxLevel;
public int nonMasterSkillsCount;
public SkillsRollChances openedSkillsChances;
public SkillsRollChances defaultSkillsChances;
public SkillsRollChances reserveSkillsChances;
public SkillsRollChances pseudoSkillsChances;
public SkillsRollChances specialSkillsChances;
}
private const int reserveSkillsLevel = -1;
private const int pseudoSkillsLevel = -2;
private const int skillSlotsCount = 3;
private Random random;
private Hero hero;
private SkillsRollChancesSet defaultSet;
private SkillsRollChancesSet specialSet;
private SkillsRollChancesSet replaceSet;
public void Init(Hero _hero, Random _random)
{
hero = _hero;
random = _random;
string skillsRollVariant = hero.data.skillsRollVariant;
SkillsRollChancesConfig skillsRollChancesConfig = DB.Instance().skillRollChancesConfig.Get(skillsRollVariant);
defaultSet = new SkillsRollChancesSet(skillsRollChancesConfig.defaultList);
specialSet = new SkillsRollChancesSet(skillsRollChancesConfig.specialList);
string configSid = hero.data.configSid;
if (DB.Instance().replaceSkillRollChancesConfig.TryGet(configSid, out var o))
{
replaceSet = new SkillsRollChancesSet(o.defaultList);
}
}
public void SetSkillsToPack(SkillsPack _skillsPack, int _currentLevel, bool _refreshAll, bool _applyReplace)
{
SkillsRollChances skillsRollChances = CreateOpenedSkillsRollChances();
SkillsRollChances skillsRollChances2 = defaultSet[_currentLevel];
SkillsRollChances skillsRollChances3 = defaultSet[-1];
SkillsRollChances skillsRollChances4 = defaultSet[-2];
SkillsRollChances skillsRollChances5 = specialSet[_currentLevel];
ReplaceSkillsChances(skillsRollChances2, _applyReplace, _currentLevel);
NullifyChancesForOpenedSkills(skillsRollChances2);
NullifyChancesForOpenedSkills(skillsRollChances3);
NullifyChancesForOpenedSkills(skillsRollChances5);
bool isSkillsCountEqualToMax = IsSkillsCountEqualToMax();
bool haveAllSkillsMaxLevel = HaveAllSkillsMaxLevel();
int nonMasterSkillsCount = GetNonMasterSkillsCount();
string[] array = new string[3];
bool[] array2 = new bool[3];
if (_refreshAll || _skillsPack.skillSids == null)
{
for (int i = 0; i < 3; i++)
{
array[i] = null;
array2[i] = true;
}
}
else
{
for (int j = 0; j < 3; j++)
{
string text = _skillsPack.skillSids[j];
if (!IsSkillValidForSlot(text, j, nonMasterSkillsCount, isSkillsCountEqualToMax, haveAllSkillsMaxLevel))
{
array[j] = null;
array2[j] = true;
continue;
}
array[j] = text;
array2[j] = false;
NullifyChanceForSkill(skillsRollChances, text);
NullifyChanceForSkill(skillsRollChances2, text);
NullifyChanceForSkill(skillsRollChances3, text);
NullifyChanceForSkill(skillsRollChances4, text);
NullifyChanceForSkill(skillsRollChances5, text);
}
}
string _sid = array[0];
string _sid2 = array[1];
string _sid3 = array[2];
bool flag = array2[0];
bool flag2 = array2[1];
bool num = array2[2];
SkillRollArgs _skillRollArgs = new SkillRollArgs
{
isSkillsCountEqualToMax = isSkillsCountEqualToMax,
haveAllSkillsMaxLevel = haveAllSkillsMaxLevel,
nonMasterSkillsCount = nonMasterSkillsCount,
openedSkillsChances = skillsRollChances,
defaultSkillsChances = skillsRollChances2,
reserveSkillsChances = skillsRollChances3,
pseudoSkillsChances = skillsRollChances4,
specialSkillsChances = skillsRollChances5
};
if (flag)
{
SetSkillForFirstSlot(ref _skillRollArgs, out _sid);
}
if (num)
{
SetSkillForThirdSlot(ref _skillRollArgs, out _sid3);
}
if (flag2)
{
SetSkillForSecondSlot(ref _skillRollArgs, out _sid2);
}
array[0] = _sid;
array[1] = _sid2;
array[2] = _sid3;
skillsRollChances2.ResetToDefault();
skillsRollChances3.ResetToDefault();
skillsRollChances4.ResetToDefault();
skillsRollChances5?.ResetToDefault();
_skillsPack.Set(array);
}
private SkillsRollChances CreateOpenedSkillsRollChances()
{
List currentSkills = hero.skills.currentSkills;
List list = new List();
foreach (HeroSkill item2 in currentSkills)
{
if (item2.level != item2.config.MaxLevel)
{
SkillRollChance item = new SkillRollChance(item2.sid, 100);
list.Add(item);
}
}
return new SkillsRollChances(list);
}
private void NullifyChancesForOpenedSkills(SkillsRollChances _rollChances)
{
if (_rollChances != null)
{
List currentSkills = hero.skills.currentSkills;
for (int i = 0; i < currentSkills.Count; i++)
{
HeroSkill heroSkill = currentSkills[i];
_rollChances[heroSkill.sid]?.Set(0);
}
}
}
private void NullifyChanceForSkill(SkillsRollChances _rollChances, string _sid)
{
if (_rollChances != null && !string.IsNullOrEmpty(_sid))
{
_rollChances[_sid]?.Set(0);
}
}
private void ResetChanceToDefault(SkillsRollChances _rollChances, string _sid)
{
if (_rollChances != null && !string.IsNullOrEmpty(_sid))
{
_rollChances[_sid]?.ResetToDefault();
}
}
private void ReplaceSkillsChances(SkillsRollChances _rollChances, bool _applyReplace, int _level)
{
if (_rollChances == null || !_applyReplace || replaceSet == null)
{
return;
}
SkillsRollChances skillsRollChances = replaceSet[_level];
if (skillsRollChances == null)
{
return;
}
for (int i = 0; i < _rollChances.Length; i++)
{
SkillRollChance skillRollChance = _rollChances[i];
SkillRollChance skillRollChance2 = skillsRollChances[skillRollChance.Sid];
if (skillRollChance2 != null)
{
skillRollChance.Set(skillRollChance2.Chance);
}
}
}
private bool IsSkillValidForSlot(string _skillSid, int _slotIndex, int _nonMastersSkillsCount, bool _isSkillsCountEqualToMax, bool _haveAllSkillsMaxLevel)
{
HeroSkill heroSkill = hero.skills.BySid(_skillSid);
SkillConfig skillConfig = DB.me.skills.Get(_skillSid);
bool isPseudoSkill = skillConfig.isPseudoSkill;
bool isNewSkill = heroSkill == null;
int skillLevel = heroSkill?.level ?? (-1);
int maxLevel = skillConfig.MaxLevel;
return _slotIndex switch
{
0 => IsSkillValidForFirstSlot(isNewSkill, isPseudoSkill, skillLevel, maxLevel, _nonMastersSkillsCount, _isSkillsCountEqualToMax, _haveAllSkillsMaxLevel),
1 => IsSkillValidForSecondSlot(isNewSkill, isPseudoSkill, skillLevel, maxLevel, _nonMastersSkillsCount, _isSkillsCountEqualToMax, _haveAllSkillsMaxLevel),
2 => IsSkillValidForThirdSlot(isNewSkill, isPseudoSkill, skillLevel, maxLevel, _nonMastersSkillsCount, _isSkillsCountEqualToMax, _haveAllSkillsMaxLevel),
_ => false,
};
}
private bool IsSkillValidForFirstSlot(bool _isNewSkill, bool _isPseudoSkill, int _skillLevel, int _skillMaxLevel, int _nonMastersSkillsCount, bool _isSkillsCountEqualToMax, bool _haveAllSkillsMaxLevel)
{
if (!_isSkillsCountEqualToMax)
{
return _isNewSkill;
}
if (!_haveAllSkillsMaxLevel && _nonMastersSkillsCount >= 3)
{
if (!_isNewSkill)
{
return _skillLevel < _skillMaxLevel;
}
return false;
}
return _isPseudoSkill;
}
private bool IsSkillValidForSecondSlot(bool _isNewSkill, bool _isPseudoSkill, int _skillLevel, int _skillMaxLevel, int _nonMastersSkillsCount, bool _isSkillsCountEqualToMax, bool _haveAllSkillsMaxLevel)
{
if (!_isSkillsCountEqualToMax)
{
if (_nonMastersSkillsCount >= 2)
{
if (!_isNewSkill)
{
return _skillLevel < _skillMaxLevel;
}
return true;
}
return _isNewSkill;
}
if (!_haveAllSkillsMaxLevel && _nonMastersSkillsCount >= 2)
{
if (!_isNewSkill)
{
return _skillLevel < _skillMaxLevel;
}
return false;
}
return _isPseudoSkill;
}
private bool IsSkillValidForThirdSlot(bool _isNewSkill, bool _isPseudoSkill, int _skillLevel, int _skillMaxLevel, int _nonMastersSkillsCount, bool _isSkillsCountEqualToMax, bool _haveAllSkillsMaxLevel)
{
if (!_haveAllSkillsMaxLevel)
{
if (!_isNewSkill)
{
return _skillLevel < _skillMaxLevel;
}
return false;
}
if (!_isSkillsCountEqualToMax)
{
return _isNewSkill;
}
return _isPseudoSkill;
}
private void SetSkillForFirstSlot(ref SkillRollArgs _skillRollArgs, out string _sid)
{
_sid = string.Empty;
bool isSkillsCountEqualToMax = _skillRollArgs.isSkillsCountEqualToMax;
bool haveAllSkillsMaxLevel = _skillRollArgs.haveAllSkillsMaxLevel;
int nonMasterSkillsCount = _skillRollArgs.nonMasterSkillsCount;
if (!isSkillsCountEqualToMax)
{
_sid = GetNewSkill(_skillRollArgs.defaultSkillsChances, _skillRollArgs.reserveSkillsChances, _skillRollArgs.pseudoSkillsChances);
NullifyChanceForSkill(_skillRollArgs.defaultSkillsChances, _sid);
NullifyChanceForSkill(_skillRollArgs.reserveSkillsChances, _sid);
NullifyChanceForSkill(_skillRollArgs.pseudoSkillsChances, _sid);
NullifyChanceForSkill(_skillRollArgs.specialSkillsChances, _sid);
}
else if (!haveAllSkillsMaxLevel && nonMasterSkillsCount >= 3)
{
_sid = GetSkillForLevelUp(_skillRollArgs.openedSkillsChances);
NullifyChanceForSkill(_skillRollArgs.openedSkillsChances, _sid);
}
else
{
_sid = GetPseudoSkill(_skillRollArgs.pseudoSkillsChances);
NullifyChanceForSkill(_skillRollArgs.pseudoSkillsChances, _sid);
}
}
private void SetSkillForSecondSlot(ref SkillRollArgs _skillRollArgs, out string _sid)
{
_sid = string.Empty;
bool isSkillsCountEqualToMax = _skillRollArgs.isSkillsCountEqualToMax;
bool haveAllSkillsMaxLevel = _skillRollArgs.haveAllSkillsMaxLevel;
int nonMasterSkillsCount = _skillRollArgs.nonMasterSkillsCount;
if (!isSkillsCountEqualToMax)
{
if (TryGetNewSid(_skillRollArgs.specialSkillsChances, out var _outSid))
{
_sid = _outSid;
return;
}
bool flag = true;
if (nonMasterSkillsCount >= 2 && random.Next(0, 2) == 1)
{
flag = false;
}
if (flag)
{
_sid = GetNewSkill(_skillRollArgs.defaultSkillsChances, _skillRollArgs.reserveSkillsChances, _skillRollArgs.pseudoSkillsChances);
}
else
{
_sid = GetSkillForLevelUp(_skillRollArgs.openedSkillsChances);
}
}
else if (!haveAllSkillsMaxLevel && nonMasterSkillsCount >= 2)
{
_sid = GetSkillForLevelUp(_skillRollArgs.openedSkillsChances);
}
else
{
_sid = GetPseudoSkill(_skillRollArgs.pseudoSkillsChances);
}
}
private void SetSkillForThirdSlot(ref SkillRollArgs _skillRollArgs, out string _sid)
{
_sid = string.Empty;
bool isSkillsCountEqualToMax = _skillRollArgs.isSkillsCountEqualToMax;
if (!_skillRollArgs.haveAllSkillsMaxLevel)
{
_sid = GetSkillForLevelUp(_skillRollArgs.openedSkillsChances);
NullifyChanceForSkill(_skillRollArgs.openedSkillsChances, _sid);
}
else if (!isSkillsCountEqualToMax)
{
_sid = GetNewSkill(_skillRollArgs.defaultSkillsChances, _skillRollArgs.reserveSkillsChances, _skillRollArgs.pseudoSkillsChances);
NullifyChanceForSkill(_skillRollArgs.defaultSkillsChances, _sid);
NullifyChanceForSkill(_skillRollArgs.reserveSkillsChances, _sid);
NullifyChanceForSkill(_skillRollArgs.pseudoSkillsChances, _sid);
NullifyChanceForSkill(_skillRollArgs.specialSkillsChances, _sid);
}
else
{
_sid = GetPseudoSkill(_skillRollArgs.pseudoSkillsChances);
NullifyChanceForSkill(_skillRollArgs.pseudoSkillsChances, _sid);
}
}
private bool IsSkillsCountEqualToMax()
{
return hero.skills.currentSkills.Count == 8;
}
private bool HaveAllSkillsMaxLevel()
{
foreach (HeroSkill currentSkill in hero.skills.currentSkills)
{
if (currentSkill.level < currentSkill.config.MaxLevel)
{
return false;
}
}
return true;
}
private int GetNonMasterSkillsCount()
{
int num = 0;
foreach (HeroSkill currentSkill in hero.skills.currentSkills)
{
if (currentSkill.level < currentSkill.config.MaxLevel)
{
num++;
}
}
return num;
}
private bool TryGetNewSid(SkillsRollChances _rollChances, out string _outSid)
{
_outSid = null;
if (_rollChances == null)
{
return false;
}
if (!_rollChances.CanRoll())
{
_outSid = null;
return false;
}
_outSid = _rollChances.Roll(random);
return true;
}
private string GetNewSkill(SkillsRollChances _defaultRollChances, SkillsRollChances _reserveRollChances, SkillsRollChances _pseudoRollChances)
{
if (!TryGetNewSid(_defaultRollChances, out var _outSid) && !TryGetNewSid(_reserveRollChances, out _outSid) && !TryGetNewSid(_pseudoRollChances, out _outSid))
{
return null;
}
return _outSid;
}
private string GetSkillForLevelUp(SkillsRollChances _openedRollChances)
{
if (TryGetNewSid(_openedRollChances, out var _outSid))
{
return _outSid;
}
return null;
}
private string GetPseudoSkill(SkillsRollChances _pseudoRollChances)
{
if (TryGetNewSid(_pseudoRollChances, out var _outSid))
{
return _outSid;
}
return null;
}
}
Skills Roll Chances - 技能权重算法
public class SkillsRollChances
{
private List list;
private Dictionary dictBySid;
public int Length => list.Count;
public SkillRollChance this[int _index]
{
get
{
if (_index < 0 || _index >= list.Count)
{
return null;
}
return list[_index];
}
}
public SkillRollChance this[string _sid]
{
get
{
if (!dictBySid.TryGetValue(_sid, out var value))
{
return null;
}
return value;
}
}
public SkillsRollChances(Hex.Configs.SkillRollChance[] _rollChances)
{
list = new List();
dictBySid = new Dictionary();
foreach (Hex.Configs.SkillRollChance skillRollChance in _rollChances)
{
SkillRollChance skillRollChance2 = new SkillRollChance(skillRollChance.sid, skillRollChance.chance);
list.Add(skillRollChance2);
dictBySid.Add(skillRollChance2.Sid, skillRollChance2);
}
}
public SkillsRollChances(List _rollChances)
{
list = _rollChances;
dictBySid = new Dictionary();
foreach (SkillRollChance _rollChance in _rollChances)
{
dictBySid.Add(_rollChance.Sid, _rollChance);
}
}
public void ResetToDefault()
{
foreach (SkillRollChance item in list)
{
item.ResetToDefault();
}
}
public bool CanRoll()
{
foreach (SkillRollChance item in list)
{
if (item.Chance > 0)
{
return true;
}
}
return false;
}
public string Roll(Random _random)
{
int rollIndex = GetRollIndex(_random);
return list[rollIndex].Sid;
}
private int GetRollIndex(Random _random)
{
int num = 0;
for (int i = 0; i < Length; i++)
{
num += list[i].Chance;
}
int num2 = _random.Next(0, num);
for (int num3 = Length - 1; num3 >= 0; num3--)
{
num -= list[num3].Chance;
if (num <= num2)
{
return num3;
}
}
return 0;
}
}