public virtual void onGain(Animon target) { if (target.bufflist.Find(x => x.name == this.name) != null) { AdditionalEffect ae = target.bufflist.Find(x => x.name == this.name); ae.duration = duration; return; } switch (Mod) { case stats.Agi: target.agi = (target.agi + StatMod) * multMod; break; case stats.Str: target.str = (target.str + StatMod) * multMod; break; } AdditionalEffect temp = target.gameObject.AddComponent <AdditionalEffect>(); temp.duration = duration; temp.StatMod = StatMod; temp.Mod = Mod; temp.multMod = multMod; temp.name = name; target.bufflist.Add(temp); }
public void IncreaseStats(AdditionalEffect effect) { if (effect.LevelMetadata?.Status?.Stats != null) { foreach ((StatAttribute stat, EffectStatMetadata statValue) in effect.LevelMetadata.Status.Stats) { Stats[stat].Add(statValue.Flat, statValue.Rate); } } }
public static IAdditionalEffect ToDomainObject(this AdditionalEffect additionalEffect) { return(new AdditionalEffect { ID = additionalEffect.ID, Name = additionalEffect.Name, Description = additionalEffect.Description, PrimaryParameter = additionalEffect.PrimaryParameter, SecondaryParameter = additionalEffect.SecondaryParameter, IsOnSelf = additionalEffect.IsOnSelf }); }
public static int GetDamage(WarUnit doer, WarUnit taker, int power, AttackType type, out AdditionalEffect effect) { Contract.Requires(AttackTypes.Attack.Contains(type)); // 状態異常の結果を初期化 effect = AdditionalEffect.なし; if (!IsHit(doer, taker)) return 0; // Attack=(攻撃力+30+random(8))*攻撃値/80 var atk = (doer.Status.Atk + 30 + WarGlobal.Random.Next(8)) * power / 80; // Defense=防御力+30 var def = taker.Status.Def + 30; // 状態異常の判定 var resType = taker.Resistivity[type]; if (AttackTypes.AbnormalCondition.Contains(type)) { if (resType == ResistivityType.弱い || (resType == ResistivityType.普通 && IsHit(doer, taker))) { effect = type - AttackType.毒 + AdditionalEffect.毒; } else if (resType == ResistivityType.強い || resType == ResistivityType.吸収) { // ダメージの処理は通常攻撃扱い resType = taker.Resistivity[AttackType.物理]; } } else if (type == AttackType.吸収) { // 吸収属性の吸収はミス if (resType == ResistivityType.吸収) return 0; // 吸収属性があれば、ここでマイナスに反転。 effect = AdditionalEffect.吸収; } // 相手に「強い」属性が有る場合はここでDefense*2、「弱い」の場合はAttack*2。 if (resType == ResistivityType.弱い) atk *= 2; else if (resType == ResistivityType.強い) def *= 2; // ダメージ期待値=Attack^0.7*Attack/(Defense+10+random(10))*(20+random(5))/35 var point = (int)(Math.Pow(atk, 0.7) * atk / (def + 10 + WarGlobal.Random.Next(10)) * (20 + WarGlobal.Random.Next(5)) / 35); // ダメージが1以下なら1、999以上なら999。 point = XMath.Center(point, 1, 999); return point; }
public bool TryGet(int id, int level, out AdditionalEffect effect, out int index) { effect = null; for (index = 0; index < Effects.Count; ++index) { if (Effects[index].Matches(id)) { effect = Effects[index]; return(true); } } return(false); }
public static int GetMagicDamage(WarUnit doer, WarUnit taker, int power, AttackType type, out AdditionalEffect effect) { // Attack=((魔力*0.8+Random(8)+60)*(魔法威力+30))/40 var atk = (doer.Status.Mag * 0.8 + WarGlobal.Random.Next(8) + 60) * (power + 30) / 40; // Defense=抵抗*0.8+70 var def = taker.Status.Res * 0.8 + 70; // 状態異常の結果を初期化 effect = AdditionalEffect.なし; // 状態異常の判定 var resType = taker.Resistivity[type]; if (AttackTypes.AbnormalCondition.Contains(type)) { if (resType == ResistivityType.弱い || (resType == ResistivityType.普通 && IsMagicConditionHit(doer, taker))) { effect = type - AttackType.毒 + AdditionalEffect.毒; } else if (resType == ResistivityType.強い || resType == ResistivityType.吸収) { // ダメージの処理は通常攻撃扱い resType = taker.Resistivity[AttackType.物理]; } } else if (type == AttackType.吸収) { // 吸収属性の吸収はミス if (resType == ResistivityType.吸収) return 0; // 吸収属性があれば、ここでマイナスに反転。 effect = AdditionalEffect.吸収; } // 相手に弱い属性が有ればAttack*2、強い属性ならばDefense*2。 if (resType == ResistivityType.弱い) atk *= 2; else if (resType == ResistivityType.強い) def *= 2; // ダメージ期待値=(Attack^0.4)*(Attack/(Defense+random(10))+.6)*(30+random(5))/35 var point = (int)(Math.Pow(atk, 0.4) * (atk / (def + WarGlobal.Random.Next(10)) + 0.6) * (30 + WarGlobal.Random.Next(5)) / 35); // ダメージが1以下なら1、999以上なら999。 point = XMath.Center(point, 1, 999); return point; }
protected override List <ItemMetadata> Parse() { // Item breaking ingredients Dictionary <int, List <ItemBreakReward> > rewards = ParseItemBreakingIngredients(); // Item rarity Dictionary <int, int> rarities = ParseItemRarities(); // Items List <ItemMetadata> items = new(); Filter.Load(Resources.XmlReader, "NA", "Live"); Maple2.File.Parser.ItemParser parser = new(Resources.XmlReader); foreach ((int id, string name, ItemData data) in parser.Parse()) { Limit limit = data.limit; Skill skill = data.skill; Fusion fusion = data.fusion; Property property = data.property; Function function = data.function; Install install = data.install; MusicScore musicScore = data.MusicScore; Life life = data.life; Housing housing = data.housing; AdditionalEffect additionalEffect = data.AdditionalEffect; ItemMetadata metadata = new() { Id = id, Name = name, Tab = GetTab(property.type, property.subtype, property.skin), Gem = new() { Gem = (GemSlot)data.gem.system }, UGC = new() { Mesh = data.ucc.mesh }, Life = new() { DurationPeriod = life.usePeriod, ExpirationType = (ItemExpirationType)life.expirationType, ExpirationTypeDuration = life.numberOfWeeksMonths }, Pet = new() { PetId = data.pet?.petID ?? 0, }, Basic = new() { Tag = data.basic.stringTag }, Limit = new() { JobRequirements = limit.jobLimit.ToList(), JobRecommendations = limit.recommendJobs.ToList(), LevelLimitMin = limit.levelLimit, LevelLimitMax = limit.levelLimitMax, Gender = (Gender)limit.genderLimit, TransferType = (TransferType)limit.transferType, Sellable = limit.shopSell, Breakable = limit.enableBreak, MeretMarketListable = limit.enableRegisterMeratMarket, DisableEnchant = limit.exceptEnchant, TradeLimitByRarity = limit.tradeLimitRank, VipOnly = limit.vip }, Skill = new() { SkillId = skill.skillID, SkillLevel = skill.skillLevel }, Fusion = new() { Fusionable = fusion.fusionable == 1, }, Install = new() { IsCubeSolid = install.cubeProp == 1, ObjectId = install.objCode, }, Property = new() { StackLimit = property.slotMax, SkinType = (ItemSkinType)property.skinType, Category = property.category, BlackMarketCategory = property.blackMarketCategory, DisableAttributeChange = property.remakeDisable, GearScoreFactor = property.gearScore, TradeableCount = (byte)property.tradableCount, RepackageCount = (byte)property.rePackingLimitCount, RepackageItemConsumeCount = (byte)property.rePackingItemConsumeCount, DisableTradeWithinAccount = property.moveDisable == 1, DisableDrop = property.disableDrop, SocketDataId = property.socketDataId, Sell = new() { SellPrice = property.sell.price.ToList(), SellPriceCustom = property.sell.priceCustom.ToList(), } }, Customize = new() { ColorIndex = data.customize.defaultColorIndex, ColorPalette = data.customize.colorPalette, }, Function = new() { Name = function.name }, Option = new() { Static = data.option.@static, Random = data.option.random, Constant = data.option.constant, OptionLevelFactor = data.option.optionLevelFactor, OptionId = data.option.optionID, }, Music = new() { PlayCount = musicScore.playCount, MasteryValue = musicScore.masteryValue, MasteryValueMax = musicScore.masteryValueMax, IsCustomScore = musicScore.isCustomNote, FileName = musicScore.fileName, PlayTime = musicScore.playTime }, Housing = new() { TrophyId = housing.trophyID, TrophyLevel = housing.trophyLevel }, Shop = new() { ShopId = data.Shop?.systemShopID ?? 0 }, AdditionalEffect = new() { Id = additionalEffect.id, Level = additionalEffect.level } }; // Parse expiration time if (life.expirationPeriod.Length > 0) { metadata.Life.ExpirationTime = new(life.expirationPeriod[0], life.expirationPeriod[1], life.expirationPeriod[2], life.expirationPeriod[3], life.expirationPeriod[4], life.expirationPeriod[5]); } // if globalOptionLevelFactor is present, override with these values if (data.option.globalOptionLevelFactor is not null) { metadata.Option.OptionLevelFactor = (float)data.option.globalOptionLevelFactor; } // if globalTransferType is present, override with these values if (limit.globalTransferType is not null) { metadata.Limit.TransferType = (TransferType)limit.globalTransferType; } // if globalTransferTypeNA is present, override with these values if (limit.globalTransferTypeNA is not null) { metadata.Limit.TransferType = (TransferType)limit.globalTransferTypeNA; } // if globalRePackingLimit is present, override repacking with these values if (property.globalRePackingLimitCount is not null) { metadata.Property.RepackageCount = (byte)property.globalRePackingLimitCount; metadata.Property.RepackageItemConsumeCount = (byte)property.globalRePackingItemConsumeCount; } // Item functions ParseFunctions(function, metadata); Slot firstSlot = data.slots.slot.First(); bool slotResult = Enum.TryParse(firstSlot.name, out metadata.Slot); if (!slotResult && !string.IsNullOrEmpty(firstSlot.name)) { Console.WriteLine($"Failed to parse item slot for {id}: {firstSlot.name}"); } if (data.slots.slot.Count > 1) { switch (metadata.Slot) { case ItemSlot.CL or ItemSlot.PA: metadata.IsDress = true; break; case ItemSlot.RH or ItemSlot.LH: metadata.IsTwoHand = true; break; } } if (metadata.Slot is ItemSlot.HR) { ParseHair(firstSlot, metadata); } if (!string.IsNullOrEmpty(housing.categoryTag)) { string[] tags = housing.categoryTag.Split(','); _ = short.TryParse(tags[0], out short category); metadata.Housing.HousingCategory = (ItemHousingCategory)category; } // Item breaking ingredients if (rewards.ContainsKey(id)) { metadata.BreakRewards = rewards[id]; } // Item rarities if (rarities.ContainsKey(id)) { metadata.Rarity = rarities[id]; } items.Add(metadata); } return(items); }
public bool TryGet(int id, int level, out AdditionalEffect effect) { int index = 0; return(TryGet(id, level, out effect, out index)); }
public virtual void EffectRemoved(AdditionalEffect effect) { ComputeStats(); }
public static void RunAttackRoutine(ActionArguments args, WarUnit doer, WarUnit taker, int value, AdditionalEffect effect, Action finishAnimation) { switch (effect) { case AdditionalEffect.なし: break; case AdditionalEffect.毒: taker.Conditions.Add(new PoisonCondition(), args.Situation); break; case AdditionalEffect.石化: taker.Conditions.Add(new PetrifactionCondition(), args.Situation); break; case AdditionalEffect.麻痺: taker.Conditions.Add(new ParalysisCondition(), args.Situation); break; case AdditionalEffect.眠り: taker.Conditions.Add(new SleepCondition(), args.Situation); break; case AdditionalEffect.幻想: // TODO: 実装 break; case AdditionalEffect.死: taker.Die(args.Situation, doer); break; case AdditionalEffect.吸収: // 回復値の表示 doer.HealHP(args.Situation, doer, value); args.Model.SetHealAnimationOnMap(value, doer.Location, null); break; default: throw new ArgumentOutOfRangeException("effect"); } // ダメージの表示要請 taker.DamageHP(args.Situation, doer, value); args.Model.SetDamageAnimationOnMap(value, taker.Location, finishAnimation); }
public static int GetSkillValue(WarUnit doer, WarUnit taker, int power, AttackType type, AttackDependency atkDep, DefenseDependency defDep, out AdditionalEffect effect) { // 状態異常の結果を初期化 effect = AdditionalEffect.なし; // 防御ステータスの決定 int defStatus = 0; if (defDep == DefenseDependency.Defense) { if (!IsHit(taker, doer)) return 0; defStatus = taker.Status.Def; } else if (defDep == DefenseDependency.Resistivity) { defStatus = taker.Status.Res; } // 攻撃ステータスの決定 int atkStatus = 0; if (atkDep == AttackDependency.Attack) atkStatus = (int)(doer.Status.Atk * 0.8); else if (atkDep == AttackDependency.Magic) atkStatus = doer.Status.Mag; // Attack=(Attack+random(8)+30)*技威力/100 var atk = (atkStatus + WarGlobal.Random.Next(8) + 30) * power / 100; // Defense=Defense+30 var def = defStatus + 30; if (AttackTypes.Attack.Contains(type)) { // 状態異常の判定 var resType = taker.Resistivity[type]; if (AttackTypes.AbnormalCondition.Contains(type)) { if (resType == ResistivityType.弱い || (resType == ResistivityType.普通 && IsMagicConditionHit(doer, taker))) { effect = type - AttackType.毒 + AdditionalEffect.毒; } else if (resType == ResistivityType.強い || resType == ResistivityType.吸収) { // ダメージの処理は通常攻撃扱い resType = taker.Resistivity[AttackType.物理]; } } else if (type == AttackType.吸収) { // 吸収属性の吸収はミス if (resType == ResistivityType.吸収) return 0; // 吸収属性があれば、ここでマイナスに反転。 effect = AdditionalEffect.吸収; } // ここで弱い属性が有る場合、Attackは二倍。強い属性があった場合、Defenseは3倍。 if (resType == ResistivityType.弱い) atk *= 2; else if (resType == ResistivityType.強い) def *= 3; } //Attack^0.7*(Attack/(Defense+10+random(10)+0.5)*(20+random(5))/35 var point = (int)(Math.Pow(atk, 0.7) * atk / (def + 10 + WarGlobal.Random.Next(10) + 0.5) * (20 + WarGlobal.Random.Next(5)) / 35); // ダメージが1以下なら1、999以上なら999。 point = XMath.Center(point, 1, 999); return point; }
public static IAdditionalEffect CreateAdditionalEffect(AdditionalEffect additionalEffectRow) { IAdditionalEffect additionalEffect = null; int id = additionalEffectRow.ID; switch (id) { case (int)AdditionalEffectEnum.SameDamageLow: additionalEffect = new AlwaysSameDamage(); break; case (int)AdditionalEffectEnum.SameDamageHigh: additionalEffect = new AlwaysSameDamage(); break; case (int)AdditionalEffectEnum.SameDamageLevel: additionalEffect = new AlwaysSameDamage(); break; case (int)AdditionalEffectEnum.DrainLife: additionalEffect = new AdditionalEffect(); break; case (int)AdditionalEffectEnum.LeechLife: additionalEffect = new AdditionalEffect(); break; case (int)AdditionalEffectEnum.Fast: additionalEffect = new FastAttack(); break; case (int)AdditionalEffectEnum.AlwaysHits: additionalEffect = new AlwaysHits(); break; case (int)AdditionalEffectEnum.HighCriticalChance: additionalEffect = new HighCriticalRatio(); break; case (int)AdditionalEffectEnum.BoostCriticalSelf: additionalEffect = new CritBoosting(); break; case (int)AdditionalEffectEnum.BoostCriticalTarget: additionalEffect = new CritBoosting(); break; case (int)AdditionalEffectEnum.ChargeLow: additionalEffect = new AdditionalEffect(); break; case (int)AdditionalEffectEnum.ChargeHigh: additionalEffect = new AdditionalEffect(); break; case (int)AdditionalEffectEnum.RechargeLow: additionalEffect = new AdditionalEffect(); break; case (int)AdditionalEffectEnum.RechargeHigh: additionalEffect = new AdditionalEffect(); break; case (int)AdditionalEffectEnum.TwoToFiveHits: additionalEffect = new AdditionalEffect(); break; case (int)AdditionalEffectEnum.SwapPokemonMax: additionalEffect = new AdditionalEffect(); break; case (int)AdditionalEffectEnum.PoisonWeak: additionalEffect = new StatusChanger(); break; case (int)AdditionalEffectEnum.PoisonMid: additionalEffect = new StatusChanger(); break; case (int)AdditionalEffectEnum.PoisonHigh: additionalEffect = new StatusChanger(); break; case (int)AdditionalEffectEnum.PoisonMax: additionalEffect = new StatusChanger(); break; case (int)AdditionalEffectEnum.BurnWeak: additionalEffect = new StatusChanger(); break; case (int)AdditionalEffectEnum.BurnMaxSelf: additionalEffect = new StatusChanger(); break; case (int)AdditionalEffectEnum.ParalysisWeak: additionalEffect = new StatusChanger(); break; case (int)AdditionalEffectEnum.ParalysisMax: additionalEffect = new StatusChanger(); break; case (int)AdditionalEffectEnum.ParalysisMaxWeak: additionalEffect = new StatusChanger(); break; case (int)AdditionalEffectEnum.ParalysisMaxSelf: additionalEffect = new StatusChanger(); break; case (int)AdditionalEffectEnum.SleepMax: additionalEffect = new StatusChanger(); break; case (int)AdditionalEffectEnum.SleepMaxSelf: additionalEffect = new StatusChanger(); break; case (int)AdditionalEffectEnum.FlinchWeak: additionalEffect = new StatusChanger(); break; case (int)AdditionalEffectEnum.ConfusionWeak: additionalEffect = new StatusChanger(); break; case (int)AdditionalEffectEnum.ConfusionMax: additionalEffect = new StatusChanger(); break; default: additionalEffect = new AdditionalEffect(); break; } additionalEffect.SetAdditionalEffectProperties(additionalEffectRow); return(additionalEffect); }