/// <summary> /// Creates map /// </summary> /// <param name="width">Width of the map</param> /// <param name="height">Height of the map</param> /// <returns>Array of tiles</returns> public static WorldTile[] GenerateMap(int width, int height) { bool[,] cells = new bool[width, height]; // Fill map with 1 or 0 randomly UH.Loops(width, height, (x, y) => cells[x, y] = x == 0 || y == 0 || x == width - 1 || y == height - 1 || RandomService.GetRandomBool(_generatorWallRoomRation)); // Simulation for (int i = 0; i < _generatorSteps; i++) { cells = SimulationStep(cells); } // Set map WorldTile[] map = new WorldTile[width * height]; UH.Loops(width, height, (x, y) => map[y * width + x] = new WorldTile(y * width + x, x, y, cells[x, y], new CollisionType[0])); // Set walls' collisions UH.Loops(width, height, (x, y) => { WorldTile tile = map[y * width + x]; if (!tile.IsWall) { return; } List <CollisionType> collision = new List <CollisionType>( ); if (x - 1 < 0 || !map[y * width + x - 1].IsWall) { collision.Add(CollisionType.Left); } if (x + 1 >= width || !map[y * width + x + 1].IsWall) { collision.Add(CollisionType.Right); } if (y - 1 < 0 || !map[(y - 1) * width + x].IsWall) { collision.Add(CollisionType.Top); } if (y + 1 >= height || !map[(y + 1) * width + x].IsWall) { collision.Add(CollisionType.Bottom); } tile.Collisions = collision.ToArray( ); }); return(map); }
// Heal Formula: // Power = floor(WIS÷2) + floor(CHA÷4) + ((Force Support Skill+Item Potency)÷2) // Base = floor((Power - Power Floor) ÷ Rate ) + Base Potency // Completely stolen from: https://www.bg-wiki.com/index.php?title=Cure_Formula&oldid=537717 and tweaked. private void HealTarget(NWPlayer oPC, NWObject oTarget, int perkLevel, int skillRank, CustomFeatType spellFeat) { var effectiveStats = PlayerStatService.GetPlayerItemEffectiveStats(oPC); int itemPotency = effectiveStats.ForcePotency + effectiveStats.LightPotency; int power = (oPC.Wisdom / 2) + (oPC.Charisma / 4) + ((skillRank + itemPotency) / 2); ForceHealPotency potencyStats = null; // The same rules are used for each Force Heal tier. // However, using a lower tier ability will cap out regardless of your perk level. // I.E: If you are on perk level 8 and you use Force Heal I, the recovery amount will cap as if you were level 3. // Ranks 1-3: Force Heal I if (spellFeat == CustomFeatType.ForceHeal) { if (perkLevel > 3) { perkLevel = 3; } switch (perkLevel) { case 1: // Rank 1, Tier 1: if (power < 20) { potencyStats = _potencyLookup[1]; } // Rank 1, Tier 2: else { potencyStats = _potencyLookup[2]; } break; case 2: // Rank 2, Tier 1: if (power < 125) { potencyStats = _potencyLookup[3]; } // Rank 2, Tier 2: else { potencyStats = _potencyLookup[4]; } break; case 3: // Rank 3, Tier 1: if (power < 600) { potencyStats = _potencyLookup[5]; } // Rank 3, Tier 2: else { potencyStats = _potencyLookup[6]; } break; } } // Ranks 4-6: Force Heal II else if (spellFeat == CustomFeatType.ForceHeal2) { if (perkLevel > 6) { perkLevel = 6; } switch (perkLevel) { case 4: // Rank 4, Tier 1: if (power < 70) { potencyStats = _potencyLookup[7]; } // Rank 4, Tier 2: else { potencyStats = _potencyLookup[8]; } break; case 5: // Rank 5, Tier 1: if (power < 200) { potencyStats = _potencyLookup[9]; } // Rank 5, Tier 2: else { potencyStats = _potencyLookup[10]; } break; case 6: // Rank 6, Tier 1: if (power < 700) { potencyStats = _potencyLookup[11]; } // Rank 6, Tier 2: else { potencyStats = _potencyLookup[12]; } break; } } // Ranks 7-8: Force Heal III else if (spellFeat == CustomFeatType.ForceHeal3) { if (perkLevel > 8) { perkLevel = 8; } switch (perkLevel) { case 7: // Rank 7, Tier 1: if (power < 125) { potencyStats = _potencyLookup[13]; } // Rank 7, Tier 2: else { potencyStats = _potencyLookup[14]; } break; case 8: // Rank 8, Tier 1: if (power < 300) { potencyStats = _potencyLookup[15]; } // Rank 8, Tier 2: else if (power < 700) { potencyStats = _potencyLookup[16]; } // Rank 8, Tier 3: else { potencyStats = _potencyLookup[17]; } break; } } // Ranks 9-10: Force Heal IV else if (spellFeat == CustomFeatType.ForceHeal4) { if (perkLevel > 10) { perkLevel = 10; } switch (perkLevel) { case 9: // Rank 9, Tier 1: if (power < 200) { potencyStats = _potencyLookup[18]; } // Rank 9, Tier 2: else { potencyStats = _potencyLookup[19]; } break; case 10: // Rank 10, Tier 1: if (power < 400) { potencyStats = _potencyLookup[20]; } // Rank 10, Tier 2: else { potencyStats = _potencyLookup[21]; } break; } } if (potencyStats == null) { throw new Exception("Unable to identify Force Heal rules."); } // Calculate the amount based on the level and tier values int amount = (int)((power - potencyStats.PowerFloor) / potencyStats.Rate) + potencyStats.BasePotency; // Don't go over the hard cap, if there is one. if (potencyStats.HardCap > 0 && amount > potencyStats.HardCap) { amount = potencyStats.HardCap; } // Do a lucky check. Increases damage by 50% if successful. int luck = PerkService.GetPCPerkLevel(oPC, PerkType.Lucky) + effectiveStats.Luck; if (RandomService.Random(100) + 1 <= luck) { amount = (int)(amount * 1.5f); oPC.SendMessage("Lucky heal!"); } // Apply the heal. oPC.AssignCommand(() => { Effect heal = _.EffectHeal(amount); _.ApplyEffectToObject(DURATION_TYPE_INSTANT, heal, oTarget); Effect vfx = _.EffectVisualEffect(VFX_IMP_HEALING_M); _.ApplyEffectToObject(DURATION_TYPE_INSTANT, vfx, oTarget.Object); }); SkillService.RegisterPCToAllCombatTargetsForSkill(oPC, SkillType.ForceSupport, null); }
public void ApplyEffects(NWCreature user, NWItem item, NWObject target, Location targetLocation, CustomData customData) { DateTime now = DateTime.UtcNow; DateTime unlockDateTime = now; if (string.IsNullOrWhiteSpace(GetLocalString(user, "GRENADE_UNLOCKTIME"))) { unlockDateTime = unlockDateTime.AddSeconds(-1); } else { unlockDateTime = DateTime.ParseExact(GetLocalString(user, "GRENADE_UNLOCKTIME"), "yyyy-MM-dd hh:mm:ss", CultureInfo.InvariantCulture); } //Console.WriteLine("IsValidTarget - Current Time = " + now.ToString("yyyy-MM-dd hh:mm:ss", CultureInfo.InvariantCulture)); //Console.WriteLine("IsValidTarget - Unlocktime = " + unlockDateTime.ToString("yyyy-MM-dd hh:mm:ss", CultureInfo.InvariantCulture)); //Console.WriteLine("IsValidTarget - DateTime.Compare = " + DateTime.Compare(unlockDateTime, now)); // Check if we've passed the unlock date. Exit early if we have not. if (DateTime.Compare(unlockDateTime, now) > 0 || unlockDateTime > now) { string timeToWait = TimeService.GetTimeToWaitLongIntervals(now, unlockDateTime, false); //Console.WriteLine("IsValidTarget - That ability can be used in " + timeToWait + "."); SendMessageToPC(user, "That ability can be used in " + timeToWait + "."); return; } Effect impactEffect = null; var spellId = Spell.Invalid; string soundName = null; int perkLevel = 1 + PerkService.GetCreaturePerkLevel(user, PerkType.GrenadeProficiency); int skillLevel = 5 + SkillService.GetPCSkillRank((NWPlayer)user, SkillType.Throwing); if (perkLevel == 0) { perkLevel += 1; } if (GetIsObjectValid(target) == true) { targetLocation = GetLocation(target); } string grenadeType = item.GetLocalString("TYPE"); //Console.WriteLine("Throwing " + grenadeType + " grenade at perk level " + perkLevel); Location originalLocation = targetLocation; int roll = RandomService.D100(1); SendMessageToPC(user, roll + " vs. DC " + (100 - skillLevel)); if (roll < (100 - skillLevel)) { if (RandomService.D20(1) == 1) { SendMessageToPC(user, "You threw... poorly."); //targetLocation = VectorService.MoveLocation(targetLocation, GetFacing(user), (RandomService.D6(4) - 10) * 1.0f, targetLocation = VectorService.MoveLocation(user.Location, RandomService.D100(1) + RandomService.D100(1) + RandomService.D100(1) + 60, RandomService.D4(2) * 1.0f, RandomService.D100(1) + RandomService.D100(1) + RandomService.D100(1)); int count = 0; while ((GetSurfaceMaterial(targetLocation) == 0 || LineOfSightVector(GetPositionFromLocation(targetLocation), GetPosition(user)) == false) && count < 10) { count += 1; targetLocation = VectorService.MoveLocation(user.Location, RandomService.D100(1) + RandomService.D100(1) + RandomService.D100(1) + 60, RandomService.D4(2) * 1.0f, RandomService.D100(1) + RandomService.D100(1) + RandomService.D100(1)); } } else { SendMessageToPC(user, "Your throw was a bit off the mark."); //targetLocation = VectorService.MoveLocation(targetLocation, GetFacing(user), (RandomService.D6(4) - 10) * 1.0f, targetLocation = VectorService.MoveLocation(targetLocation, RandomService.D100(1) + RandomService.D100(1) + RandomService.D100(1) + 60, RandomService.D4(2) /*(RandomService.D6(4) - 10) */ * 1.0f, RandomService.D100(1) + RandomService.D100(1) + RandomService.D100(1)); int count = 0; while ((GetSurfaceMaterial(targetLocation) == 0 || LineOfSightVector(GetPositionFromLocation(targetLocation), GetPosition(user)) == false) && count < 10) { count += 1; targetLocation = VectorService.MoveLocation(targetLocation, RandomService.D100(1) + RandomService.D100(1) + RandomService.D100(1) + 60, RandomService.D4(2) /*(RandomService.D6(4) - 10) */ * 1.0f, RandomService.D100(1) + RandomService.D100(1) + RandomService.D100(1)); } } if (GetSurfaceMaterial(targetLocation) == 0 || LineOfSightVector(GetPositionFromLocation(targetLocation), GetPosition(user)) == false) { targetLocation = originalLocation; } } switch (grenadeType) { case "FRAG": impactEffect = EffectVisualEffect(VisualEffect.Fnf_Fireball); // force a specific spell id (for projectile model) for this grenade. spellId = Spell.Grenade10; soundName = "explosion2"; break; case "CONCUSSION": impactEffect = EffectVisualEffect(VisualEffect.Vfx_Fnf_Sound_Burst_Silent); impactEffect = EffectLinkEffects(EffectVisualEffect(VisualEffect.Vfx_Fnf_Screen_Shake), impactEffect); spellId = Spell.Grenade10; soundName = "explosion1"; break; case "FLASHBANG": impactEffect = EffectVisualEffect(VisualEffect.Vfx_Fnf_Mystical_Explosion); spellId = Spell.Grenade10; soundName = "explosion1"; break; case "ION": impactEffect = EffectVisualEffect(VisualEffect.Vfx_Fnf_Electric_Explosion); spellId = Spell.Grenade10; soundName = "explosion1"; break; case "BACTA": impactEffect = EffectVisualEffect(VisualEffect.Vfx_Fnf_Gas_Explosion_Nature); spellId = Spell.Grenade10; //soundName = "explosion1"; break; case "ADHESIVE": impactEffect = EffectVisualEffect(VisualEffect.Fnf_Dispel_Greater); spellId = Spell.Grenade10; //soundName = "explosion1"; break; case "SMOKE": impactEffect = null; spellId = Spell.Grenade10; //soundName = "explosion1"; break; case "BACTABOMB": impactEffect = null; spellId = Spell.Grenade10; //soundName = "explosion1"; break; case "INCENDIARY": impactEffect = null; spellId = Spell.Grenade10; //soundName = "explosion1"; break; case "GAS": impactEffect = null; spellId = Spell.Grenade10; //soundName = "explosion1"; break; default: throw new ArgumentOutOfRangeException(nameof(grenadeType)); } if (spellId == 0) { // start 974 through 979 in spells.2da for grenades // lets randomly assign a projectile appearance for flavor? spellId = (Spell)(RandomService.D6(1) + 973); } float delay = GetDistanceBetweenLocations(user.Location, targetLocation) / 18.0f + 0.75f; delay += 0.4f; // added for animation user.ClearAllActions(); //user.AssignCommand(() => _.ActionPlayAnimation(32)); //user.DelayAssignCommand(() => _.ActionPlayAnimation(32), 0.0f); user.AssignCommand(() => { ActionPlayAnimation(Animation.LoopingCustom12); ActionCastSpellAtLocation(spellId, targetLocation, MetaMagic.Any, true, ProjectilePathType.Ballistic, true); //ActionCastFakeSpellAtLocation(spellId, targetLocation, PROJECTILE_PATH_TYPE_BALLISTIC); }); if (soundName != null) { user.DelayAssignCommand(() => { PlaySound(soundName); }, delay); } if (impactEffect != null) { user.DelayAssignCommand(() => { ApplyEffectAtLocation(DurationType.Instant, impactEffect, targetLocation); }, delay); } user.DelayAssignCommand( () => { DoImpact(user, targetLocation, grenadeType, perkLevel, RadiusSize.Large, ObjectType.Creature); }, delay + 0.75f); perkLevel = PerkService.GetCreaturePerkLevel(user, PerkType.GrenadeProficiency); now = DateTime.UtcNow; DateTime unlockTime = now; if (perkLevel < 5) { unlockTime = unlockTime.AddSeconds(6); } else if (perkLevel < 10) { unlockTime = unlockTime.AddSeconds(3); } else { unlockTime = unlockTime.AddSeconds(2); } SetLocalString(user, "GRENADE_UNLOCKTIME", unlockTime.ToString("yyyy-MM-dd hh:mm:ss", CultureInfo.InvariantCulture)); //Console.WriteLine("StartUseItem - Current Time = " + now.ToString("yyyy-MM-dd hh:mm:ss", CultureInfo.InvariantCulture)); //Console.WriteLine("StartUseItem - Unlocktime Set To = " + unlockTime.ToString("yyyy-MM-dd hh:mm:ss", CultureInfo.InvariantCulture)); if (user.IsCreature) { DurabilityService.RunItemDecay((NWPlayer)user, item, 1.0f); } }
public void Run(NWObject target, params object[] args) { int roll = RandomService.Random(0, 100); ResourceQuality quality = ResourceQuality.Low; string qualityName = "Low Quality"; var dbArea = DataService.Single <Area>(x => x.Resref == target.Area.Resref); int tier = dbArea.ResourceQuality; int maxTier = dbArea.MaxResourceQuality; if (tier <= 0) { Console.WriteLine("WARNING: Area '" + target.Area.Name + "' has resources but the RESOURCE_QUALITY variable is not set. Edit the area properties and add this value to set up resources."); return; } int NormalQualityChance; int HighQualityChance; int VeryHighQualityChance; switch (tier) { case 1: NormalQualityChance = 20; HighQualityChance = 0; VeryHighQualityChance = 0; break; case 2: NormalQualityChance = 20; HighQualityChance = 2; VeryHighQualityChance = 0; break; case 3: case 4: case 5: NormalQualityChance = 20; HighQualityChance = 2; VeryHighQualityChance = 1; break; case 6: case 7: case 8: NormalQualityChance = 20; HighQualityChance = 10; VeryHighQualityChance = 3; break; case 9: case 10: NormalQualityChance = 20; HighQualityChance = 12; VeryHighQualityChance = 5; break; default: NormalQualityChance = 0; HighQualityChance = 0; VeryHighQualityChance = 0; break; } if (roll <= VeryHighQualityChance) { quality = ResourceQuality.VeryHigh; qualityName = "Very High Quality"; } else if (roll <= HighQualityChance) { quality = ResourceQuality.High; qualityName = "High Quality"; } else if (roll <= NormalQualityChance) { quality = ResourceQuality.Normal; qualityName = "Normal Quality"; } roll = RandomService.Random(0, 100); if (roll <= 3) { tier++; } if (tier > 10) { tier = 10; } if (tier > maxTier) { tier = maxTier; } target.SetLocalInt("RESOURCE_QUALITY", (int)quality); target.SetLocalInt("RESOURCE_TIER", tier); target.SetLocalInt("RESOURCE_COUNT", RandomService.Random(3, 10)); target.SetLocalString("RESOURCE_RESREF", GetResourceResref(tier)); target.SetLocalString("RESOURCE_QUALITY_NAME", qualityName); }
public NekoNsfwCommand(DiscordShardedClient client, MiscService misc, ImageService img, RandomService rand) { _client = client; _misc = misc; _img = img; _rand = rand; }
private Tuple <int, float> RunComponentBonusAttempt(NWPlayer player, NWItem component, float equipmentBonus, float chance, List <NWItem> itemSet) { int successAmount = 0; // Note - this line MUST be outside the foreach loop, as inspecting component properties will reset the component.ItemProperties counter. int componentLevel = component.LevelIncrease > 0 ? component.LevelIncrease : component.RecommendedLevel; if (componentLevel < 1) { componentLevel = 1; } foreach (var ip in component.ItemProperties) { int ipType = _.GetItemPropertyType(ip); if (ipType != (int)CustomItemPropertyType.ComponentBonus) { continue; } int bonusTypeID = _.GetItemPropertySubType(ip); int tlkID = Convert.ToInt32(_.Get2DAString("iprp_compbon", "Name", bonusTypeID)); int amount = _.GetItemPropertyCostTableValue(ip); string bonusName = _.GetStringByStrRef(tlkID) + " " + amount; float random = RandomService.RandomFloat() * 100.0f; float modifiedEquipmentBonus = equipmentBonus * 0.25f; if (random <= chance + modifiedEquipmentBonus) { foreach (var item in itemSet) { // If the target item is a component itself, we want to add the component bonuses instead of the // actual item property bonuses. // In other words, we want the custom item property "Component Bonus: AC UP" instead of the "AC Bonus" item property. var componentIP = item.ItemProperties.FirstOrDefault(x => _.GetItemPropertyType(x) == (int)CustomItemPropertyType.ComponentType); if (componentIP == null) { ComponentBonusService.ApplyComponentBonus(item, ip); } else { BiowareXP2.IPSafeAddItemProperty(item, ip, 0.0f, AddItemPropertyPolicy.IgnoreExisting, false, false); } } player.SendMessage(ColorTokenService.Green("Successfully applied component property: " + bonusName)); ComponentBonusType bonusType = (ComponentBonusType)_.GetItemPropertySubType(ip); if (bonusType != ComponentBonusType.DurabilityUp) { // Durability bonuses don't increase the penalty. Higher level components transfer multiple // properties more easily (to balance the fact that you can fit fewer of them on an item). int penalty; switch (componentLevel) { case 1: penalty = RandomService.Random(1, 19); break; case 2: penalty = RandomService.Random(1, 9); break; case 3: penalty = RandomService.Random(1, 6); break; case 4: penalty = RandomService.Random(1, 4); break; default: penalty = RandomService.Random(1, 3); break; } chance -= penalty; if (chance < 1) { chance = 1; } } successAmount++; } else { player.SendMessage(ColorTokenService.Red("Failed to apply component property: " + bonusName)); } } return(new Tuple <int, float>(successAmount, chance)); }
public override Vector3 Random(Vector3 origin) { var randomPoint = new Vector3(X0 + (RandomService.Nextfloat() * (X1 - X0)), K, Z0 + (RandomService.Nextfloat() * (Z1 - Z0))); return(randomPoint - origin); }
public override async Task ExecuteAsync(MainRepository repo, Character character, IEnumerable <CharacterCommandParameter> options, CommandSystemData game) { var trainingTypeOptional = options.FirstOrDefault(p => p.Type == 1).ToOptional(); var system = await repo.System.GetAsync(); if (!trainingTypeOptional.HasData) { await game.CharacterLogAsync("能力強化のパラメータが不正です。<emerge>管理者にお問い合わせください</emerge>"); } else if (character.Money < 50) { await game.CharacterLogAsync("能力強化の金が足りません"); } else { var trainingType = (TrainingType)trainingTypeOptional.Data.NumberValue; var name = string.Empty; var isError = false; if (trainingType == TrainingType.SkillPoint) { if (character.CountryId != 0) { await game.CharacterLogAsync("国に仕官している人は技能ポイントを強化できません"); isError = true; } if (system.GameDateTime.Year >= Config.UpdateStartYear + Config.CountryBattleStopDuring / 12) { await game.CharacterLogAsync("戦闘解除後は技能ポイントを強化できません"); isError = true; } } if (isError) { return; } if (trainingType == TrainingType.Any) { if (character.Strong > character.Intellect && character.Strong > character.Leadership && character.Strong > character.Popularity) { trainingType = TrainingType.Strong; } else if (character.Intellect > character.Leadership && character.Intellect > character.Popularity) { trainingType = TrainingType.Intellect; } else if (character.Leadership > character.Popularity) { trainingType = TrainingType.Leadership; } else { trainingType = TrainingType.Popularity; } } var skillPoint = RandomService.Next(0, 3) == 0 ? 2 : 1; switch (trainingType) { case TrainingType.Strong: character.AddStrongEx(100); name = "武力"; break; case TrainingType.Intellect: character.AddIntellectEx(100); name = "知力"; break; case TrainingType.Leadership: character.AddLeadershipEx(100); name = "統率"; break; case TrainingType.Popularity: character.AddPopularityEx(100); name = "人望"; break; case TrainingType.SkillPoint: character.SkillPoint += skillPoint; name = "技能ポイント"; break; default: await game.CharacterLogAsync("能力強化のパラメータが不正です。<emerge>管理者にお問い合わせください</emerge>"); isError = true; break; } if (!isError) { character.Money -= 50; if (trainingType == TrainingType.SkillPoint) { await game.CharacterLogAsync(name + " を <num>+" + skillPoint + "</num> 強化しました"); } else { await game.CharacterLogAsync(name + "経験値 を <num>+100</num> 強化しました"); } } if (RandomService.Next(0, 700) == 0) { var info = await ItemService.PickTownHiddenItemAsync(repo, character.TownId, character); if (info.HasData) { var town = await repo.Town.GetByIdAsync(character.TownId); if (town.HasData) { await game.CharacterLogAsync($"<town>{town.Data.Name}</town> に隠されたアイテム {info.Data.Name} を手に入れました"); } } } } }
public void OnImpact(NWCreature player, NWObject target, int perkLevel, int spellTier) { NWItem weapon = player.RightHand; int iDamage; int iRange = 15; int iCount = 1; float fDelay = 0; int iPheno = _.GetPhenoType(player); if (weapon.CustomItemType == CustomItemType.Lightsaber || weapon.CustomItemType == CustomItemType.Saberstaff) { iDamage = player.RightHand.DamageBonus + RandomService.D6(2) + player.IntelligenceModifier + player.StrengthModifier; } else { iDamage = (int)weapon.Weight + player.StrengthModifier; } NWObject oObject; // If player is in stealth mode, force them out of stealth mode. if (_.GetActionMode(player.Object, ACTION_MODE_STEALTH) == 1) { _.SetActionMode(player.Object, ACTION_MODE_STEALTH, 0); } // Make the player face their target. _.ClearAllActions(); BiowarePosition.TurnToFaceObject(target, player); player.AssignCommand(() => _.ActionPlayAnimation(30, 2)); // reset phenotype player.DelayAssignCommand(() => { _.SetPhenoType(4, player); }, 2.0f); player.DelayAssignCommand(() => { _.SetPhenoType(iPheno, player); }, 2.5f); // Handle effects for differing spellTier values switch (spellTier) { case 1: iDamage = (int)(iDamage * 1.0); fDelay = _.GetDistanceBetween(player, target) / 10.0f; player.DelayAssignCommand(() => { _.ApplyEffectToObject(_.DURATION_TYPE_INSTANT, _.EffectLinkEffects(_.EffectVisualEffect(VFX_IMP_SONIC), _.EffectDamage(iDamage, _.DAMAGE_TYPE_BASE_WEAPON)), target); }, fDelay); if (player.IsPlayer) { SkillService.RegisterPCToNPCForSkill(player.Object, target, SkillType.ForceAlter); } break; case 2: iDamage = (int)(iDamage * 1.25); fDelay = _.GetDistanceBetween(player, target) / 10.0f; player.DelayAssignCommand(() => { _.ApplyEffectToObject(_.DURATION_TYPE_INSTANT, _.EffectLinkEffects(_.EffectVisualEffect(VFX_IMP_SONIC), _.EffectDamage(iDamage, _.DAMAGE_TYPE_BASE_WEAPON)), target); }, fDelay); if (player.IsPlayer) { SkillService.RegisterPCToNPCForSkill(player.Object, target, SkillType.ForceAlter); } break; case 3: iDamage = (int)(iDamage * 1.6); fDelay = _.GetDistanceBetween(player, target) / 10.0f; player.DelayAssignCommand(() => { _.ApplyEffectToObject(_.DURATION_TYPE_INSTANT, _.EffectLinkEffects(_.EffectVisualEffect(VFX_IMP_SONIC), _.EffectDamage(iDamage, _.DAMAGE_TYPE_BASE_WEAPON)), target); }, fDelay); if (player.IsPlayer) { SkillService.RegisterPCToNPCForSkill(player.Object, target, SkillType.ForceAlter); } break; case 4: iDamage = (int)(iDamage * 2.0); // apply to target fDelay = _.GetDistanceBetween(player, target) / 10.0f; player.DelayAssignCommand(() => { _.ApplyEffectToObject(_.DURATION_TYPE_INSTANT, _.EffectLinkEffects(_.EffectVisualEffect(VFX_IMP_SONIC), _.EffectDamage(iDamage, _.DAMAGE_TYPE_BASE_WEAPON)), target); }, fDelay); if (player.IsPlayer) { SkillService.RegisterPCToNPCForSkill(player.Object, target, SkillType.ForceAlter); } iCount += 1; // apply to next nearest creature in the spellcylinder oObject = _.GetFirstObjectInShape(_.SHAPE_SPELLCONE, iRange, target.Location, 1, _.OBJECT_TYPE_CREATURE, _.GetPosition(player)); while (oObject.IsValid && iCount < 3) { if (oObject != target && oObject != player) { fDelay = _.GetDistanceBetween(player, oObject) / 10.0f; var creature = oObject; player.DelayAssignCommand(() => { _.ApplyEffectToObject(_.DURATION_TYPE_INSTANT, _.EffectLinkEffects(_.EffectVisualEffect(VFX_IMP_SONIC), _.EffectDamage(iDamage, _.DAMAGE_TYPE_BASE_WEAPON)), creature); }, fDelay); if (player.IsPlayer) { SkillService.RegisterPCToNPCForSkill(player.Object, oObject, SkillType.ForceAlter); } iCount += 1; } oObject = _.GetNextObjectInShape(_.SHAPE_SPELLCONE, iRange, target.Location, 1, _.OBJECT_TYPE_CREATURE, _.GetPosition(player)); } break; case 5: iDamage = (int)(iDamage * 2.5); // apply to target fDelay = _.GetDistanceBetween(player, target) / 10.0f; player.DelayAssignCommand(() => { _.ApplyEffectToObject(_.DURATION_TYPE_INSTANT, _.EffectLinkEffects(_.EffectVisualEffect(VFX_IMP_SONIC), _.EffectDamage(iDamage, _.DAMAGE_TYPE_BASE_WEAPON)), target); }, fDelay); if (player.IsPlayer) { SkillService.RegisterPCToNPCForSkill(player.Object, target, SkillType.ForceAlter); } iCount += 1; // apply to next nearest creature in the spellcylinder oObject = _.GetFirstObjectInShape(_.SHAPE_SPELLCYLINDER, iRange, target.Location, 1, _.OBJECT_TYPE_CREATURE, _.GetPosition(player)); while (oObject.IsValid && iCount < 4) { if (oObject != target && oObject != player) { fDelay = _.GetDistanceBetween(player, oObject) / 10.0f; var creature = oObject; player.DelayAssignCommand(() => { _.ApplyEffectToObject(_.DURATION_TYPE_INSTANT, _.EffectLinkEffects(_.EffectVisualEffect(VFX_IMP_SONIC), _.EffectDamage(iDamage, _.DAMAGE_TYPE_BASE_WEAPON)), creature); }, fDelay); if (player.IsPlayer) { SkillService.RegisterPCToNPCForSkill(player.Object, oObject, SkillType.ForceAlter); } iCount += 1; } oObject = _.GetNextObjectInShape(_.SHAPE_SPELLCYLINDER, iRange, target.Location, 1, _.OBJECT_TYPE_CREATURE, _.GetPosition(player)); } break; default: throw new ArgumentOutOfRangeException(nameof(spellTier)); } }
public override async Task ExecuteAsync(MainRepository repo, Character character, IEnumerable <CharacterCommandParameter> options, CommandSystemData game) { if (character.Money < 50) { await game.CharacterLogAsync($"金が足りません。<num>50</num> 必要です"); return; } var townOptional = await repo.Town.GetByIdAsync(character.TownId); if (townOptional.HasData) { var countryOptional = await repo.Country.GetAliveByIdAsync(character.CountryId); if (!countryOptional.HasData) { await game.CharacterLogAsync($"政策開発しようとしましたが、無所属は実行できません"); return; } var country = countryOptional.Data; var town = townOptional.Data; var isWandering = false; if (town.CountryId != character.CountryId) { var townsCount = await repo.Town.CountByCountryIdAsync(character.CountryId); if (townsCount > 0) { await game.CharacterLogAsync("<town>" + town.Name + "</town>で政策開発しようとしましたが、自国の都市ではありません"); return; } else { // 放浪軍による政策開発 isWandering = true; } } var skills = await repo.Character.GetSkillsAsync(character.Id); // 内政値に加算する // $kgat += int($klea/6 + rand($klea/6)); var current = country.PolicyPoint; var attribute = Math.Max(character.Strong, character.Intellect); var add = (int)(attribute / 20.0f + RandomService.Next(0, attribute / 40)); if (add < 1) { add = 1; } country.PolicyPoint += add; // 政策ブースト if (RandomService.Next(0, 1000) <= skills.GetSumOfValues(CharacterSkillEffectType.PolicyBoostProbabilityThousandth)) { var policies = await repo.Country.GetPoliciesAsync(country.Id); var allPolicies = CountryPolicyTypeInfoes.GetAll(); var notPolicies = allPolicies.Where(pi => pi.CanBoost && !policies.Any(p => p.Status != CountryPolicyStatus.Unadopted && p.Status != CountryPolicyStatus.Boosting && p.Type == pi.Type)); if (notPolicies.Any()) { var info = RandomService.Next(notPolicies); await CountryService.SetPolicyAndSaveAsync(repo, country, info.Type, CountryPolicyStatus.Boosted, false); await game.CharacterLogAsync($"<country>{country.Name}</country> の政策 {info.Name} について新しい知見を得、政策をブーストしました"); } } // 経験値、金の増減 character.Contribution += 30; character.SkillPoint++; character.Money -= 50; if (character.Strong > character.Intellect) { character.AddStrongEx(50); } else { character.AddIntellectEx(50); } if (isWandering) { await game.CharacterLogAsync($"<country>{country.Name}</country> の政策ポイントを <num>+{add}</num> 上げました。合計: <num>{country.PolicyPoint}</num>"); } else { await game.CharacterLogAsync($"<country>{country.Name}</country> の政策ポイントを <num>+{add}</num> 上げました"); } if (RandomService.Next(0, 256) == 0) { var info = await ItemService.PickTownHiddenItemAsync(repo, character.TownId, character); if (info.HasData) { await game.CharacterLogAsync($"<town>{town.Name}</town> に隠されたアイテム {info.Data.Name} を手に入れました"); } } await StatusStreaming.Default.SendCountryAsync(ApiData.From(country), country.Id); } else { await game.CharacterLogAsync("ID:" + character.TownId + " の都市は存在しません。<emerge>管理者にお問い合わせください</emerge>"); } }
public PersonService(RandomService randomService, BreedingService breedingService) { RandomService = randomService; BreedingService = breedingService; }
public override async Task ExecuteAsync(MainRepository repo, Character character, IEnumerable <CharacterCommandParameter> options, CommandSystemData game) { if (this.GetCharacterAssets(character) < this.UseAssetsLength()) { await game.CharacterLogAsync(this.GetCharacterAssetName() + $"が足りません。<num>{this.UseAssetsLength()}</num> 必要です"); return; } if (character.CountryId == 0) { await game.CharacterLogAsync($"無所属は内政を実行できません"); return; } var countryOptional = await repo.Country.GetAliveByIdAsync(character.CountryId); if (!countryOptional.HasData) { await game.CharacterLogAsync($"ID: {character.CountryId} の国は存在しません。<emerge>管理者にお問い合わせください</emerge>"); return; } var country = countryOptional.Data; var townOptional = await repo.Town.GetByIdAsync(character.TownId); if (townOptional.HasData) { var town = townOptional.Data; if (town.CountryId != character.CountryId) { await game.CharacterLogAsync("<town>" + town.Name + "</town>で内政しようとしましたが、自国の都市ではありません"); return; } this.Policies = await repo.Country.GetPoliciesAsync(character.CountryId); var skills = await repo.Character.GetSkillsAsync(character.Id); this.Skills = skills; // 内政値に加算する // $znouadd = int(($kint+$kprodmg)/20 + rand(($kint+$kprodmg)) / 40); var current = this.GetCurrentValue(town); var max = this.GetMaxValue(town); var add = (int)(this.GetCharacterAttribute(character) / 20.0f + RandomService.Next(0, this.GetCharacterAttribute(character)) / 40.0f); if (add < 1) { add = 1; } add = (int)(add * (1 + skills.GetSumOfValues(CharacterSkillEffectType.DomesticAffairMulPercentage) / 100.0f)); if (this is SecurityCommand || this is SuperSecurityCommand) { add = (int)(add * (1 + skills.GetSumOfValues(CharacterSkillEffectType.SecurityCommandMulPercentage) / 100.0f)); if (country.AiType == CountryAiType.Terrorists || country.AiType == CountryAiType.TerroristsEnemy) { town.People = Math.Min(town.PeopleMax, town.People + 1600); } } if (country.Religion != ReligionType.Any && country.Religion != ReligionType.None && country.Religion == town.Religion) { add = (int)(add * (1 + skills.GetSumOfValues(CharacterSkillEffectType.DomesticAffairAtSameMissionaryPercentage) / 100.0f)); } if (skills.GetSumOfValues(CharacterSkillEffectType.DomesticAffairMulPercentageInWar) > 0 || skills.GetSumOfValues(CharacterSkillEffectType.DomesticAffairMulPercentageInNotWar) > 0) { var system = await repo.System.GetAsync(); var wars = await repo.CountryDiplomacies.GetAllWarsAsync(); var isWar = wars.Any(w => (w.Status == CountryWarStatus.Available || w.Status == CountryWarStatus.StopRequesting) && w.IsJoin(character.CountryId)); if (isWar || system.IsBattleRoyaleMode) { add = (int)(add * (1 + skills.GetSumOfValues(CharacterSkillEffectType.DomesticAffairMulPercentageInWar) / 100.0f)); } else { add = (int)(add * (1 + skills.GetSumOfValues(CharacterSkillEffectType.DomesticAffairMulPercentageInNotWar) / 100.0f)); } } if (!this.IsMinus()) { if (current + add >= max) { this.SetValue(town, max); } else { this.SetValue(town, current + add); } } else { if (current - add < 0) { this.SetValue(town, 0); } else { this.SetValue(town, current - add); } } // 経験値、金の増減 this.SetCharacterAssets(character, this.GetCharacterAssets(character) - this.UseAssetsLength()); character.Contribution += this.Contributes(); character.SkillPoint++; this.AddCharacterAttributeEx(character, this.Experiences()); await game.CharacterLogAsync("<town>" + town.Name + "</town> の " + this.GetValueName() + " を <num>+" + add + "</num> " + this.GetValueAddingText() + "しました"); if (RandomService.Next(0, (int)(256.0f * (1 - skills.GetSumOfValues(CharacterSkillEffectType.ItemAppearOnDomesticAffairThousandth) / 1000.0f))) == 0) { var info = await ItemService.PickTownHiddenItemAsync(repo, character.TownId, character); if (info.HasData) { await game.CharacterLogAsync($"<town>{town.Name}</town> に隠されたアイテム {info.Data.Name} を手に入れました"); } } } else { await game.CharacterLogAsync("ID:" + character.TownId + " の都市は存在しません。<emerge>管理者にお問い合わせください</emerge>"); } }
private static void ProcessPerkFeats(NWCreature self) { // Bail early if any of the following is true: // - Creature has a weapon skill queued. // - Creature does not have a PerkFeat cache. // - There are no perk feats in the cache. // - Creature has no target. if (self.GetLocalInt("ACTIVE_WEAPON_SKILL") > 0) { return; } if (!self.Data.ContainsKey("PERK_FEATS")) { return; } Dictionary <int, AIPerkDetails> cache = self.Data["PERK_FEATS"]; if (cache.Count <= 0) { return; } NWObject target = _.GetAttackTarget(self); if (!target.IsValid) { return; } // todo: GetEffectType() returns EFFECT_TYPE_INVALIDEFFECT for knockdown effects. // todo: The following code is causing a segfault crash... look into other solutions or figure out what's causing that. // target.Effects.Any(x => NWNXEffect.UnpackEffect(x).Type == (int)EffectTypeEngine.Knockdown) || // Potential workaround: if (target.GetLocalBool("KNOCKDOWN")) return; if (target.GetLocalBool("KNOCKDOWN")) { return; } if (target.Effects.Any(x => _.GetEffectTag(x) == "TRANQUILIZER_EFFECT")) { return; } // Pull back whatever concentration effect is currently active, if any. var concentration = AbilityService.GetActiveConcentrationEffect(self); // Exclude any concentration effects, if necessary, then randomize potential feats to use. var randomizedFeatIDs = concentration.Type == PerkType.Unknown ? cache.Values // No concentration exclusions : cache.Values.Where(x => x.ExecutionType != PerkExecutionType.ConcentrationAbility); // Exclude concentration abilities randomizedFeatIDs = randomizedFeatIDs.OrderBy(o => RandomService.Random()); foreach (var perkDetails in randomizedFeatIDs) { // Move to next feat if this creature cannot use this one. if (!AbilityService.CanUsePerkFeat(self, target, (Feat)perkDetails.FeatID)) { continue; } self.AssignCommand(() => { _.ActionUseFeat((Feat)perkDetails.FeatID, target); }); break; } }
public void Setup() { service = new RandomService(); }
public void OnImpact(NWCreature creature, NWObject target, int perkLevel, int spellTier) { int damage; float duration; switch (perkLevel) { case 1: damage = RandomService.D8(1); duration = 3; break; case 2: damage = RandomService.D8(2); duration = 3; break; case 3: damage = RandomService.D8(3); duration = 3; break; case 4: damage = RandomService.D8(3); duration = 6; break; case 5: damage = RandomService.D8(4); duration = 6; break; case 6: damage = RandomService.D8(5); duration = 6; break; case 7: damage = RandomService.D8(6); duration = 6; break; case 8: damage = RandomService.D8(7); duration = 6; break; case 9: damage = RandomService.D8(7); duration = 9; break; case 10: damage = RandomService.D8(8); duration = 9; break; default: return; } _.ApplyEffectToObject(DurationType.Temporary, _.EffectStunned(), target, duration); _.ApplyEffectToObject(DurationType.Instant, _.EffectDamage(damage, DamageType.Electrical), target); _.ApplyEffectToObject(DurationType.Instant, _.EffectVisualEffect(VisualEffect.Vfx_Imp_Sunstrike), target); }
public void ApplyEffects(NWCreature user, NWItem item, NWObject target, Location targetLocation, CustomData customData) { SkillType skillType = GetSkillType(item); NWItem targetitem = (target.Object); int tech = item.GetLocalInt("TECH_LEVEL"); float maxDurabilityReductionPenalty = item.GetLocalFloat("MAX_DURABILITY_REDUCTION_PENALTY"); int repairAmount = tech * 2; int skillRank; int level = targetitem.RecommendedLevel; int delta = 0; int baseXP = 0; if (skillType == SkillType.Armorsmith) { skillRank = (SkillService.GetPCSkillRank(user.Object, skillType)); repairAmount += item.CraftBonusArmorsmith + (PerkService.GetCreaturePerkLevel(user.Object, PerkType.ArmorRepair) * 2); delta = level - skillRank; } else if (skillType == SkillType.Weaponsmith) { skillRank = (SkillService.GetPCSkillRank(user.Object, skillType)); repairAmount += item.CraftBonusWeaponsmith + (PerkService.GetCreaturePerkLevel(user.Object, PerkType.WeaponRepair) * 2); delta = level - skillRank; } else if (skillType == SkillType.Engineering) { skillRank = (SkillService.GetPCSkillRank(user.Object, skillType)); repairAmount += item.CraftBonusEngineering + (PerkService.GetCreaturePerkLevel(user.Object, PerkType.ElectronicRepair) * 2); delta = level - skillRank; } float minReduction = 0.05f * tech; float maxReduction = 0.15f * tech; float reductionAmount = RandomService.RandomFloat(minReduction, maxReduction); if (delta >= 6) { baseXP = 400; } else if (delta == 5) { baseXP = 350; } else if (delta == 4) { baseXP = 325; } else if (delta == 3) { baseXP = 300; } else if (delta == 2) { baseXP = 250; } else if (delta == 1) { baseXP = 225; } else if (delta == 0) { baseXP = 200; } else if (delta == -1) { baseXP = 150; } else if (delta == -2) { baseXP = 100; } else if (delta == -3) { baseXP = 50; } else if (delta == -4) { baseXP = 25; } SkillService.GiveSkillXP(user.Object, skillType, baseXP); DurabilityService.RunItemRepair(user.Object, target.Object, repairAmount, reductionAmount + maxDurabilityReductionPenalty); }
public void OnImpact(NWPlayer player, NWObject target, int level, int spellFeatID) { int length; int dotAmount; int basePotency; const float Tier1Modifier = 1.0f; const float Tier2Modifier = 1.6f; const float Tier3Modifier = 2.2f; const float Tier4Modifier = 0; switch (level) { case 1: basePotency = 15; length = 0; dotAmount = 0; break; case 2: basePotency = 20; length = 6; dotAmount = 4; break; case 3: basePotency = 25; length = 6; dotAmount = 6; break; case 4: basePotency = 40; length = 12; dotAmount = 6; break; case 5: basePotency = 50; length = 12; dotAmount = 6; break; case 6: basePotency = 60; length = 12; dotAmount = 6; break; case 7: basePotency = 70; length = 12; dotAmount = 6; break; case 8: basePotency = 80; length = 12; dotAmount = 8; break; case 9: basePotency = 90; length = 12; dotAmount = 8; break; case 10: basePotency = 100; length = 12; dotAmount = 10; break; default: return; } var effectiveStats = PlayerStatService.GetPlayerItemEffectiveStats(player); int luck = PerkService.GetPCPerkLevel(player, PerkType.Lucky) + effectiveStats.Luck; if (RandomService.Random(100) + 1 <= luck) { length = length * 2; player.SendMessage("Lucky force lightning!"); } var calc = CombatService.CalculateForceDamage( player, target.Object, ForceAbilityType.Electrical, basePotency, Tier1Modifier, Tier2Modifier, Tier3Modifier, Tier4Modifier); player.AssignCommand(() => { Effect damage = _.EffectDamage(calc.Damage, DAMAGE_TYPE_ELECTRICAL); _.ApplyEffectToObject(DURATION_TYPE_INSTANT, damage, target); }); if (length > 0.0f && dotAmount > 0) { CustomEffectService.ApplyCustomEffect(player, target.Object, CustomEffectType.ForceShock, length, level, dotAmount.ToString()); } SkillService.RegisterPCToAllCombatTargetsForSkill(player, SkillType.ForceCombat, target.Object); player.AssignCommand(() => { _.ApplyEffectToObject(DURATION_TYPE_TEMPORARY, _.EffectVisualEffect(VFX_BEAM_LIGHTNING), target, 1.0f); }); _.PlaySound("v_pro_lightning"); CombatService.AddTemporaryForceDefense(target.Object, ForceAbilityType.Electrical); }
public override async Task ExecuteAsync(MainRepository repo, Character character, IEnumerable <CharacterCommandParameter> options, CommandSystemData game) { if (character.Money < 100) { await game.CharacterLogAsync($"金が足りません。<num>100</num> 必要です"); return; } var religion = ReligionType.Any; var countryOptional = await repo.Country.GetAliveByIdAsync(character.CountryId); if (!countryOptional.HasData) { await game.CharacterLogAsync("弾圧しようとしましたが、国に仕官しないと弾圧できません"); return; } else { var country = countryOptional.Data; religion = country.Religion; if (religion == ReligionType.Any) { religion = character.Religion; } } var townOptional = await repo.Town.GetByIdAsync(character.TownId); if (townOptional.HasData) { var town = townOptional.Data; if (character.CountryId != town.CountryId) { await game.CharacterLogAsync("弾圧しようとしましたが、他国の都市は弾圧できません"); return; } // 内政値に加算する // $kgat += int($klea/6 + rand($klea/6)); var current = character.Proficiency; var attribute = Math.Max(character.Intellect, character.Popularity); var add = (int)(attribute / 18.0f + RandomService.Next(0, attribute) / 36.0f); if (add < 1) { add = 1; } var skills = await repo.Character.GetSkillsAsync(character.Id); add = (int)(add * (1 + skills.GetSumOfValues(CharacterSkillEffectType.MissionaryPercentage) / 100.0f)); var oldReligion = town.Religion; string religionName = string.Empty; if (religion != ReligionType.Confucianism) { town.Confucianism = Math.Max(0, town.Confucianism - add); religionName += "儒教,"; } if (religion != ReligionType.Buddhism) { town.Buddhism = Math.Max(0, town.Buddhism - add); religionName += "仏教,"; } if (religion != ReligionType.Taoism) { town.Taoism = Math.Max(0, town.Taoism - add); religionName += "道教,"; } if (religion == ReligionType.Confucianism) { town.Confucianism += add; } if (religion == ReligionType.Buddhism) { town.Buddhism += add; } if (religion == ReligionType.Taoism) { town.Taoism += add; } // 経験値、金の増減 if (countryOptional.HasData) { character.Contribution += 30; } if (character.Intellect > character.Popularity) { character.AddIntellectEx(50); } else { character.AddPopularityEx(50); } character.SkillPoint++; character.Money -= 100; await game.CharacterLogAsync($"<town>{town.Name}</town> の {religionName.Substring(0, religionName.Length - 1)}信仰 を <num>-{add}</num> 弾圧し、{religion.GetString()} を <num>+{add}</num> 布教しました"); var ranking = await repo.Character.GetCharacterRankingAsync(character.Id); ranking.MissionaryCount += add; if (town.Religion != oldReligion) { if (town.Religion == ReligionType.Any) { await game.MapLogAsync(EventType.StopReligion, $"<town>{town.Name}</town> は宗教の信仰をやめました", false); } else { var newReligionName = town.Religion.GetString(); await game.MapLogAsync(EventType.ChangeReligion, $"<town>{town.Name}</town> は {oldReligion.GetString()} から {newReligionName} に改宗しました", false); ranking.MissionaryChangeReligionCount++; } await StatusStreaming.Default.SendTownToAllAsync(ApiData.From(town), repo); } } else { await game.CharacterLogAsync("ID:" + character.TownId + " の都市は存在しません。<emerge>管理者にお問い合わせください</emerge>"); } }
private void RunCreateItem(NWPlayer player) { foreach (var effect in player.Effects) { if (_.GetEffectTag(effect) == "CRAFTING_IMMOBILIZATION") { _.RemoveEffect(player, effect); } } var model = CraftService.GetPlayerCraftingData(player); CraftBlueprint blueprint = DataService.Single <CraftBlueprint>(x => x.ID == model.BlueprintID); BaseStructure baseStructure = blueprint.BaseStructureID == null ? null : DataService.Get <BaseStructure>(blueprint.BaseStructureID); PCSkill pcSkill = SkillService.GetPCSkill(player, blueprint.SkillID); int pcEffectiveLevel = CraftService.CalculatePCEffectiveLevel(player, pcSkill.Rank, (SkillType)blueprint.SkillID); int itemLevel = model.AdjustedLevel; int atmosphereBonus = CraftService.CalculateAreaAtmosphereBonus(player.Area); float chance = CalculateBaseChanceToAddProperty(pcEffectiveLevel, itemLevel, atmosphereBonus); float equipmentBonus = CalculateEquipmentBonus(player, (SkillType)blueprint.SkillID); if (chance <= 1.0f) { player.FloatingText(ColorTokenService.Red("Critical failure! You don't have enough skill to create that item. All components were lost.")); CraftService.ClearPlayerCraftingData(player, true); return; } int luckyBonus = PerkService.GetPCPerkLevel(player, PerkType.Lucky); var craftedItems = new List <NWItem>(); NWItem craftedItem = (_.CreateItemOnObject(blueprint.ItemResref, player.Object, blueprint.Quantity)); craftedItem.IsIdentified = true; craftedItems.Add(craftedItem); // If item isn't stackable, loop through and create as many as necessary. if (craftedItem.StackSize < blueprint.Quantity) { for (int x = 2; x <= blueprint.Quantity; x++) { craftedItem = (_.CreateItemOnObject(blueprint.ItemResref, player.Object)); craftedItem.IsIdentified = true; craftedItems.Add(craftedItem); } } // Recommended level gets set regardless if all item properties make it on the final product. // Also mark who crafted the item. This is later used for display on the item's examination event. foreach (var item in craftedItems) { item.RecommendedLevel = itemLevel < 0 ? 0 : itemLevel; item.SetLocalString("CRAFTER_PLAYER_ID", player.GlobalID.ToString()); BaseService.ApplyCraftedItemLocalVariables(item, baseStructure); } if (RandomService.Random(1, 100) <= luckyBonus) { chance += RandomService.Random(1, luckyBonus); } int successAmount = 0; foreach (var component in model.MainComponents) { var result = RunComponentBonusAttempt(player, component, equipmentBonus, chance, craftedItems); successAmount += result.Item1; chance = result.Item2; } foreach (var component in model.SecondaryComponents) { var result = RunComponentBonusAttempt(player, component, equipmentBonus, chance, craftedItems); successAmount += result.Item1; chance = result.Item2; } foreach (var component in model.TertiaryComponents) { var result = RunComponentBonusAttempt(player, component, equipmentBonus, chance, craftedItems); successAmount += result.Item1; chance = result.Item2; } foreach (var component in model.EnhancementComponents) { var result = RunComponentBonusAttempt(player, component, equipmentBonus, chance, craftedItems); successAmount += result.Item1; chance = result.Item2; } // Structures gain increased durability based on the blueprint if (baseStructure != null) { foreach (var item in craftedItems) { var maxDur = DurabilityService.GetMaxDurability(item); maxDur += (float)baseStructure.Durability; DurabilityService.SetMaxDurability(item, maxDur); DurabilityService.SetDurability(item, maxDur); } } player.SendMessage("You created " + blueprint.Quantity + "x " + blueprint.ItemName + "!"); int baseXP = 250 + successAmount * RandomService.Random(1, 50); float xp = SkillService.CalculateRegisteredSkillLevelAdjustedXP(baseXP, model.AdjustedLevel, pcSkill.Rank); var pcCraftedBlueprint = DataService.SingleOrDefault <PCCraftedBlueprint>(x => x.PlayerID == player.GlobalID && x.CraftBlueprintID == blueprint.ID); if (pcCraftedBlueprint == null) { xp = xp * 1.25f; player.SendMessage("You receive an XP bonus for crafting this item for the first time."); pcCraftedBlueprint = new PCCraftedBlueprint { CraftBlueprintID = blueprint.ID, DateFirstCrafted = DateTime.UtcNow, PlayerID = player.GlobalID }; DataService.SubmitDataChange(pcCraftedBlueprint, DatabaseActionType.Insert); } SkillService.GiveSkillXP(player, blueprint.SkillID, (int)xp); CraftService.ClearPlayerCraftingData(player, true); player.SetLocalInt("LAST_CRAFTED_BLUEPRINT_ID_" + blueprint.CraftDeviceID, blueprint.ID); }
public void GenerateRandomValueTest(int min, int max, int actual, [Frozen] Mock <IRandomExecutor> executor, RandomService sut) { //arrange executor.Setup(service => service.Next(min - 500, max - 500)).Returns(actual); //act var expected = sut.GenerateRandomValue(min, max); //assert executor.Verify(service => service.Next(min - 500, max - 500), Times.AtLeastOnce); Assert.Equal(expected, actual); }
private void SetupTest(ContactModel contactModelToDo, CultureInfo culture, string actionStr) { LanguageEnum languageEnum = (culture.TwoLetterISOLanguageName == "fr" ? LanguageEnum.fr : LanguageEnum.en); if (contactModelToDo == null) { user = null; } else { user = new GenericPrincipal(new GenericIdentity(contactModelToDo.LoginEmail, "Forms"), null); } routeData = new RouteData(); routeData.Values.Add("culture", culture); routeData.Values.Add("controller", controllerName); routeData.Values.Add("action", actionStr); stubHttpContext = new StubHttpContextBase(); stubHttpRequestBase = new StubHttpRequestBase(); stubHttpContext.RequestGet = () => stubHttpRequestBase; requestContext = new RequestContext(stubHttpContext, routeData); controller = new EmailController(); controller.Url = new UrlHelper(requestContext); controller.ControllerContext = new ControllerContext(stubHttpContext, routeData, controller); stubHttpContext.UserGet = () => user; controller.SetRequestContext(requestContext); // Assert // BaseController Asserts Assert.IsNotNull(controller); Assert.AreEqual(2, controller.CultureListAllowable.Count); Assert.AreEqual("en-CA", controller.CultureListAllowable[0]); Assert.AreEqual("fr-CA", controller.CultureListAllowable[1]); Assert.IsNotNull(controller._ContactService); Assert.IsNotNull(controller._RequestContext); Assert.IsNotNull(controller._TVItemService); Assert.IsNotNull(controller._TVItemStatService); Assert.IsNotNull(culture.Name, controller._RequestContext.RouteData.Values["culture"].ToString()); Assert.IsNotNull(controllerName, controller._RequestContext.RouteData.Values["controller"].ToString()); Assert.IsNotNull(actionStr, controller._RequestContext.RouteData.Values["action"].ToString()); Assert.AreEqual((culture.TwoLetterISOLanguageName == "fr" ? LanguageEnum.fr : LanguageEnum.en), controller.LanguageRequest); Assert.AreEqual((culture.TwoLetterISOLanguageName == "fr" ? LanguageEnum.fr : LanguageEnum.en), controller.ViewBag.Language); Assert.AreEqual(culture.Name, controller.CultureRequest); Assert.AreEqual(culture.Name, controller.ViewBag.Culture); Assert.AreEqual(Thread.CurrentThread.CurrentCulture, culture); Assert.AreEqual(Thread.CurrentThread.CurrentUICulture, culture); if (contactModelToDo != null) { Assert.AreEqual(contactModelToDo.IsAdmin, controller.IsAdmin); Assert.AreEqual(contactModelToDo.IsAdmin, controller.ViewBag.IsAdmin); } Assert.AreEqual(true, controller.Debug); Assert.AreEqual(true, controller.ViewBag.Debug); // EmailController Asserts Assert.IsNotNull(controller._EmailController); Assert.IsNotNull(controller._EmailService); Assert.IsNotNull(controller._TVItemLinkService); // variables for testing randomService = new RandomService(languageEnum, user); emailService = new EmailService(languageEnum, user); }
public bool ReducesItemCharge(NWCreature user, NWItem item, NWObject target, Location targetLocation, CustomData customData) { int consumeChance = PerkService.GetCreaturePerkLevel(user.Object, PerkType.FrugalMedic) * 10; return(RandomService.Random(100) + 1 > consumeChance); }
public Vector3 Generate() { return(RandomService.Nextfloat() < 0.5f ? P0.Generate() : P1.Generate()); }
public void ApplyEffects(NWCreature user, NWItem item, NWObject target, Location targetLocation, CustomData customData) { NWPlayer player = user.Object; ResourceQuality quality = (ResourceQuality)target.GetLocalInt("RESOURCE_QUALITY"); int tier = target.GetLocalInt("RESOURCE_TIER"); int remaining = target.GetLocalInt("RESOURCE_COUNT") - 1; string itemResref = target.GetLocalString("RESOURCE_RESREF"); int ipBonusChance = ResourceService.CalculateChanceForComponentBonus(player, tier, quality); int roll = RandomService.Random(1, 100); int rank = SkillService.GetPCSkillRank(player, SkillType.Harvesting); if (item.RecommendedLevel < rank) { rank = item.RecommendedLevel; } int difficulty = (tier - 1) * 10 + ResourceService.GetDifficultyAdjustment(quality); int delta = difficulty - rank; int baseXP = 0; if (delta >= 6) { baseXP = 400; } else if (delta == 5) { baseXP = 350; } else if (delta == 4) { baseXP = 325; } else if (delta == 3) { baseXP = 300; } else if (delta == 2) { baseXP = 250; } else if (delta == 1) { baseXP = 225; } else if (delta == 0) { baseXP = 200; } else if (delta == -1) { baseXP = 150; } else if (delta == -2) { baseXP = 100; } else if (delta == -3) { baseXP = 50; } else if (delta == -4) { baseXP = 25; } int itemHarvestBonus = item.HarvestingBonus; int scanningBonus = user.GetLocalInt(target.GlobalID.ToString()); ipBonusChance += itemHarvestBonus * 2 + scanningBonus * 2; baseXP = baseXP + scanningBonus * 5; NWItem resource = _.CreateItemOnObject(itemResref, player.Object); if (roll <= ipBonusChance) { var ip = ResourceService.GetRandomComponentBonusIP(quality); BiowareXP2.IPSafeAddItemProperty(resource, ip.Item1, 0.0f, AddItemPropertyPolicy.IgnoreExisting, true, true); switch (ip.Item2) { case 0: resource.Name = ColorTokenService.Green(resource.Name); break; case 1: resource.Name = ColorTokenService.Blue(resource.Name); break; case 2: resource.Name = ColorTokenService.Purple(resource.Name); break; case 3: resource.Name = ColorTokenService.Orange(resource.Name); break; } } float decayMinimum = 0.03f; float decayMaximum = 0.07f; if (delta > 0) { decayMinimum += delta * 0.1f; decayMaximum += delta * 0.1f; } user.SendMessage("You harvest " + resource.Name + "."); DurabilityService.RunItemDecay(player, item, RandomService.RandomFloat(decayMinimum, decayMaximum)); int xp = baseXP; SkillService.GiveSkillXP(player, SkillType.Harvesting, xp); if (remaining <= 0) { NWPlaceable prop = target.GetLocalObject("RESOURCE_PROP_OBJ"); if (prop.IsValid) { prop.Destroy(); } target.Destroy(); user.DeleteLocalInt(target.GlobalID.ToString()); } else { target.SetLocalInt("RESOURCE_COUNT", remaining); } _.ApplyEffectAtLocation(DURATION_TYPE_INSTANT, _.EffectVisualEffect(VFX_FNF_SUMMON_MONSTER_3), target.Location); }
public static async Task <bool> ResultAsync(MainRepository repo, SystemData system, DelayEffect delay, Func <uint, string, Task> logAsync) { if (delay.IntAppearGameDateTime + 36 <= system.IntGameDateTime) { var chara = await repo.Character.GetByIdAsync(delay.CharacterId); var town = await repo.Town.GetByIdAsync(delay.TownId); if (chara.HasData && town.HasData) { var results = new List <string>(); var skills = await repo.Character.GetSkillsAsync(chara.Data.Id); var currentItems = await repo.Character.GetItemsAsync(chara.Data.Id); var items = (await repo.Town.GetItemsAsync(chara.Data.TownId)).Where(i => i.Status == CharacterItemStatus.TownHidden); if (RandomService.Next(0, 10) < items.Count()) { var item = RandomService.Next(items); var info = CharacterItemInfoes.Get(item.Type); if (info.HasData && (info.Data.DiscoverFroms == null || info.Data.DiscoverFroms.Contains(chara.Data.From))) { await ItemService.SetCharacterPendingAsync(repo, item, chara.Data); results.Add($"アイテム {info.Data.Name}"); } } var money = RandomService.Next(chara.Data.Intellect * 32, Math.Max(chara.Data.Intellect * 48, system.GameDateTime.Year * 650 + 10000)); chara.Data.Money += money; results.Add($"金 <num>{money}</num>"); var country = await repo.Country.GetByIdAsync(chara.Data.CountryId); if (country.HasData) { var name = string.Empty; var add = RandomService.Next(20, 60); var target = RandomService.Next(0, 5); if (target == 0) { name = "農業"; town.Data.Agriculture = Math.Min(town.Data.AgricultureMax, town.Data.Agriculture + add); } else if (target == 1) { name = "商業"; town.Data.Commercial = Math.Min(town.Data.CommercialMax, town.Data.Commercial + add); } else if (target == 2) { name = "技術"; town.Data.Technology = Math.Min(town.Data.TechnologyMax, town.Data.Technology + add); } else if (target == 3) { name = "城壁"; town.Data.Wall = Math.Min(town.Data.WallMax, town.Data.Wall + add); } else if (target == 4) { name = "都市施設"; town.Data.TownBuildingValue = Math.Min(Config.TownBuildingMax, town.Data.TownBuildingValue + add); } await logAsync(chara.Data.Id, $"<town>{town.Data.Name}</town> に投資し、{name} の開発に <num>+{add}</num> 貢献し、{string.Join("と", results)}を得ました"); } else { await logAsync(chara.Data.Id, $"<town>{town.Data.Name}</town> に投資し、{string.Join("と", results)}を得ました"); } return(true); } } return(false); }
public ScavengeCommand(BotCredentials botCredentials, GamesService gamesService, RandomService randomService) : base(botCredentials, gamesService, randomService) { }
public override async Task ExecuteAsync(MainRepository repo, Character character, IEnumerable <CharacterCommandParameter> options, CommandSystemData game) { var typeParameter = options.FirstOrDefault(p => p.Type == 1); var assetsParameter = options.FirstOrDefault(p => p.Type == 2); var resultParameter = options.FirstOrDefault(p => p.Type == 3); if (typeParameter == null || assetsParameter == null || resultParameter == null) { await game.CharacterLogAsync($"米売買に必要なパラメータ <num>{string.Join(",", Enumerable.Range(1, 3).Concat(options.Select(p => p.Type)).Distinct())}</num> が足りません。<emerge>管理者にお問い合わせください</emerge>"); return; } var type = (RiceCommandType)typeParameter.NumberValue; var assets = (int)assetsParameter.NumberValue; var result = (int)resultParameter.NumberValue; var skills = await repo.Character.GetSkillsAsync(character.Id); if (type == RiceCommandType.MoneyToRice) { if (character.Money < assets) { await game.CharacterLogAsync($"<num>{assets}</num> の金を米に交換しようとしましたが、金が足りませんでした"); return; } character.Money -= assets; character.Rice += result; await game.CharacterLogAsync($"<num>{assets}</num> の金を <num>{result}</num> の米に交換しました"); } else if (type == RiceCommandType.RiceToMoney) { if (character.Rice < assets) { await game.CharacterLogAsync($"<num>{assets}</num> の米を金に交換しようとしましたが、米が足りませんでした"); return; } character.Rice -= assets; character.Money += result; await game.CharacterLogAsync($"<num>{assets}</num> の米を <num>{result}</num> の金に交換しました"); } var contributon = skills.GetSumOfValues(CharacterSkillEffectType.RiceBuyContribution); if (contributon > 0 && (await repo.Country.GetAliveByIdAsync(character.CountryId)).HasData) { character.Contribution += contributon; character.SkillPoint++; var townOptional = await repo.Town.GetByIdAsync(character.TownId); if (townOptional.HasData) { var town = townOptional.Data; if (RandomService.Next(0, (int)(256.0f * (1 - skills.GetSumOfValues(CharacterSkillEffectType.ItemAppearOnDomesticAffairThousandth) / 1000.0f))) == 0) { var info = await ItemService.PickTownHiddenItemAsync(repo, character.TownId, character); if (info.HasData) { await game.CharacterLogAsync($"<town>{town.Name}</town> に隠されたアイテム {info.Data.Name} を手に入れました"); } } } } character.AddIntellectEx(50); }
private int ProcessProperty(int amount, int maxBonuses, ComponentBonusType bonus, float levelsPerBonus = 1.0f) { string resref = _componentType.ReassembledResref; int penalty = 0; int luck = PerkService.GetCreaturePerkLevel(_player, PerkType.Lucky) + (_playerItemStats.Luck / 3); int xp = 0; ItemPropertyUnpacked bonusIP = new ItemPropertyUnpacked { Property = (int)ItemPropertyType.ComponentBonus, SubType = (int)bonus, CostTable = 62, CostTableValue = 0, Param1 = 255, Param1Value = 0, UsesPerDay = 255, ChanceToAppear = 100, IsUseable = true, SpellID = -1 }; while (amount > 0) { int chanceToTransfer = CraftService.CalculateReassemblyChance(_player, penalty); // Roll to see if the item can be created. bool success = RandomService.Random(0, 100) <= chanceToTransfer; // Do a lucky roll if we failed the first time. if (!success && luck > 0 && RandomService.Random(0, 100) <= luck) { _player.SendMessage("Lucky reassemble!"); success = true; } if (amount >= maxBonuses) { if (success) { int levelIncrease = (int)(maxBonuses * levelsPerBonus); // Roll succeeded. Create item. bonusIP.CostTableValue = maxBonuses; ItemProperty bonusIPPacked = NWNXItemProperty.PackIP(bonusIP); NWItem item = _.CreateItemOnObject(resref, _player); item.RecommendedLevel = levelIncrease; BiowareXP2.IPSafeAddItemProperty(item, bonusIPPacked, 0.0f, AddItemPropertyPolicy.ReplaceExisting, true, false); xp += (150 * maxBonuses + RandomService.Random(0, 5)); } else { _player.SendMessage(ColorTokenService.Red("You failed to create a component. (+" + maxBonuses + ")")); xp += (50 + RandomService.Random(0, 5)); } // Penalty to chance increases regardless if item was created or not. penalty += (maxBonuses * 5); amount -= maxBonuses; } else { if (success) { int levelIncrease = (int)(amount * levelsPerBonus); bonusIP.CostTableValue = amount; ItemProperty bonusIPPacked = NWNXItemProperty.PackIP(bonusIP); NWItem item = _.CreateItemOnObject(resref, _player); item.RecommendedLevel = levelIncrease; BiowareXP2.IPSafeAddItemProperty(item, bonusIPPacked, 0.0f, AddItemPropertyPolicy.ReplaceExisting, true, false); xp += (150 * amount + RandomService.Random(0, 5)); } else { _player.SendMessage(ColorTokenService.Red("You failed to create a component. (+" + amount + ")")); xp += (50 + RandomService.Random(0, 5)); } break; } } return(xp); }
public void DoImpact(NWCreature user, Location targetLocation, string grenadeType, int perkLevel, float fExplosionRadius, ObjectType nObjectFilter) { Effect damageEffect = EffectDamage(0, DamageType.Negative); Effect durationEffect = null; int duration = perkLevel + 1; switch (grenadeType) { case "SMOKE": durationEffect = EffectAreaOfEffect(AreaOfEffect.FogOfBewilderment, "grenade_smoke_en", "grenade_smoke_hb", ""); break; case "BACTABOMB": durationEffect = EffectAreaOfEffect(AreaOfEffect.FogMind, "grenade_bbomb_en", "grenade_bbomb_hb", ""); break; case "INCENDIARY": durationEffect = EffectAreaOfEffect(AreaOfEffect.FogFire, "grenade_incen_en", "grenade_incen_hb", ""); break; case "GAS": durationEffect = EffectAreaOfEffect(AreaOfEffect.FogGhoul, "grenade_gas_en", "grenade_gas_hb", ""); break; default: break; } if (durationEffect != null) { //Apply AOE ApplyEffectAtLocation(DurationType.Temporary, durationEffect, targetLocation, duration * 6.0f); } else { //Apply impact // Target the next nearest creature and do the same thing. NWObject targetCreature = GetFirstObjectInShape(Shape.Sphere, fExplosionRadius, targetLocation, true, nObjectFilter); while (targetCreature.IsValid) { //Console.WriteLine("Grenade hit on " + targetCreature.Name); switch (grenadeType) { case "FRAG": damageEffect = EffectDamage(RandomService.D6(perkLevel), DamageType.Fire); damageEffect = EffectLinkEffects(EffectDamage(RandomService.D6(perkLevel), DamageType.Piercing), damageEffect); if (RandomService.D6(1) > 4) { //Console.WriteLine("grenade effect bleeding - frag"); CustomEffectService.ApplyCustomEffect(user, targetCreature.Object, CustomEffectType.Bleeding, duration * 6, perkLevel, Convert.ToString(perkLevel)); } if (RandomService.D6(1) > 4) { //Console.WriteLine("grenade effects burning - frag"); CustomEffectService.ApplyCustomEffect(user, targetCreature.Object, CustomEffectType.Burning, duration * 6, perkLevel, Convert.ToString(perkLevel)); } //Console.WriteLine("grenade effects set - frag"); break; case "CONCUSSION": damageEffect = EffectDamage(RandomService.D12(perkLevel), DamageType.Sonic); durationEffect = EffectDeaf(); if (RandomService.D6(1) > 4) { FloatingTextStringOnCreature("Your ears ring and your body shakes.", targetCreature); durationEffect = EffectLinkEffects(AbilityService.EffectKnockdown(targetCreature, duration), durationEffect); } break; case "FLASHBANG": duration = RandomService.D4(1); durationEffect = EffectDeaf(); if (RandomService.D6(1) > 4) { FloatingTextStringOnCreature("Your vision blurs and blacks out.", targetCreature); durationEffect = EffectLinkEffects(EffectBlindness(), durationEffect); } break; case "ION": duration = RandomService.D4(1); damageEffect = EffectDamage(RandomService.D6(perkLevel), DamageType.Electrical); if (GetRacialType(targetCreature) == RacialType.Robot || (RandomService.D6(1) > 4 && GetRacialType(targetCreature) == RacialType.Cyborg)) { FloatingTextStringOnCreature("Your circuits are overloaded.", targetCreature); durationEffect = EffectStunned(); } break; case "BACTA": damageEffect = null; durationEffect = EffectRegenerate(perkLevel, 6.0f); break; case "ADHESIVE": durationEffect = EffectSlow(); if (RandomService.D6(1) > 4) { FloatingTextStringOnCreature("You are slowed by the adhesive explosion.", targetCreature); durationEffect = EffectLinkEffects(EffectCutsceneImmobilize(), durationEffect); } break; default: throw new ArgumentOutOfRangeException(nameof(grenadeType)); } //Console.WriteLine("applying effects to " + GetName(targetCreature)); if (damageEffect != null) { ApplyEffectToObject(DurationType.Instant, damageEffect, targetCreature); } if (durationEffect != null) { ApplyEffectToObject(DurationType.Temporary, durationEffect, targetCreature, duration * 6.0f); } if (!targetCreature.IsPlayer) { SkillService.RegisterPCToNPCForSkill(user.Object, targetCreature, SkillType.Throwing); } targetCreature = GetNextObjectInShape(Shape.Sphere, fExplosionRadius, targetLocation, true, nObjectFilter); } } }
public void Run(NWObject target, params object[] args) { int roll = RandomService.Random(0, 100); ResourceQuality quality = ResourceQuality.Low; string qualityName = "Sparse"; const int NormalQualityChance = 20; const int HighQualityChance = 10; const int VeryHighQualityChance = 2; var dbArea = DataService.Single <Area>(x => x.Resref == target.Area.Resref); int tier = dbArea.ResourceQuality; int maxTier = dbArea.MaxResourceQuality; if (tier <= 0) { Console.WriteLine("WARNING: Area '" + target.Area.Name + "' has resources but the RESOURCE_QUALITY variable is not set. Edit the area properties and add this value to set up resources."); return; } if (roll <= VeryHighQualityChance) { quality = ResourceQuality.VeryHigh; qualityName = "Very Dense"; } else if (roll <= HighQualityChance) { quality = ResourceQuality.High; qualityName = "Dense"; } else if (roll <= NormalQualityChance) { quality = ResourceQuality.Normal; qualityName = "Thick"; } roll = RandomService.Random(0, 100); if (roll <= 3) { tier++; } if (tier > 10) { tier = 10; } if (tier > maxTier) { tier = maxTier; } string resref = GetResourceResref(tier); int quantity = RandomService.Random(3, 10); roll = RandomService.Random(0, 100); if (roll <= 2) { string[] coloredResrefs = { "p_crystal_red", "p_crystal_green", "p_crystal_blue", "p_crystal_yellow" }; roll = RandomService.Random(0, 3); resref = coloredResrefs[roll]; } target.SetLocalInt("RESOURCE_QUALITY", (int)quality); target.SetLocalInt("RESOURCE_TIER", tier); target.SetLocalInt("RESOURCE_COUNT", quantity); target.SetLocalString("RESOURCE_RESREF", resref); target.SetLocalString("RESOURCE_QUALITY_NAME", qualityName); }