// Use this for initialization void Start () { player = GameObject.FindGameObjectWithTag ("Player").GetComponent<Player> (); displays = GameObject.FindGameObjectWithTag ("Background").GetComponent<UIScripts> (); foeData = GameObject.FindGameObjectWithTag ("Database").GetComponent<FoeDatabase> (); attributes = gameObject.GetComponent<Physical> (); bossIsActive = true; }
public void GetPersonSummarizedInfo() { Physical person = new Physical() { Id = Guid.NewGuid(), Name = "Name for Person 1", BornDate = DateTime.Parse("01/01/2000") }; Assert.IsNotNull(person); Assert.AreEqual("Name: Name for Person 1, Born Date: 01/01/2000", person.GetSummarizedInfo()); }
public void CreateNewPhysical() { Physical person = new Physical() { Id = Guid.NewGuid(), Name = "Name for Person 1", BornDate = DateTime.Parse("01/01/2000") }; Assert.IsNotNull(person); Assert.AreEqual(DateTime.Parse("01/01/2000"), person.BornDate); }
public static bool IsPhysical(this GameObject tar) { var gameObject = tar as Character; return(gameObject != null && Physical.Contains(gameObject.CurrentJob)); }
public void Unregister(IModifiable source) { Physical.Unregister(source); Magical.Unregister(source); }
public void Initialize(IArmorableData data) { Physical.Initialize(data.Physical); Magical.Initialize(data.Magical); }
/// <summary> /// Returns the max Y position of the islands voxels (absolute coords) /// </summary> /// <returns></returns> public float GetMaxY() { return(Physical.LocalBoundingBox.Transform(Physical.GetWorldMatrix()).Maximum.Y); }
/// <summary> /// Gets a read-only span of data from GPU mapped memory, up to the entire range specified, /// or the last mapped page if the range is not fully mapped. /// </summary> /// <param name="va">GPU virtual address where the data is located</param> /// <param name="size">Size of the data</param> /// <param name="tracked">True if read tracking is triggered on the span</param> /// <returns>The span of the data at the specified memory location</returns> public ReadOnlySpan <byte> GetSpanMapped(ulong va, int size, bool tracked = false) { bool isContiguous = true; int mappedSize; if (ValidateAddress(va) && GetPte(va) != PteUnmapped && Physical.IsMapped(Translate(va))) { ulong endVa = va + (ulong)size; ulong endVaAligned = (endVa + PageMask) & ~PageMask; ulong currentVa = va & ~PageMask; int pages = (int)((endVaAligned - currentVa) / PageSize); for (int page = 0; page < pages - 1; page++) { ulong nextVa = currentVa + PageSize; ulong nextPa = Translate(nextVa); if (!ValidateAddress(nextVa) || GetPte(nextVa) == PteUnmapped || !Physical.IsMapped(nextPa)) { break; } if (Translate(currentVa) + PageSize != nextPa) { isContiguous = false; } currentVa += PageSize; } currentVa += PageSize; if (currentVa > endVa) { currentVa = endVa; } mappedSize = (int)(currentVa - va); } else { return(ReadOnlySpan <byte> .Empty); } if (isContiguous) { return(Physical.GetSpan(Translate(va), mappedSize, tracked)); } else { Span <byte> data = new byte[mappedSize]; ReadImpl(va, data, tracked); return(data); } }
private GivenStatCollection CreateCollection() => new GivenStatCollection(_modifierBuilder, ValueFactory) { // pools { BaseSet, EnergyShield.Recharge, 20 }, { BaseSet, Life.RecoveryRate, 1 }, { BaseSet, Mana.RecoveryRate, 1 }, { BaseSet, EnergyShield.RecoveryRate, 1 }, { BaseSet, Life.Regen.TargetPool, (int)Pool.Life }, { BaseSet, Mana.Regen.TargetPool, (int)Pool.Mana }, { BaseSet, EnergyShield.Regen.TargetPool, (int)Pool.EnergyShield }, { BaseSet, EnergyShield.Recharge.Start, 1 }, { BaseSet, AllSkills.ReservationPool, (int)Pool.Mana }, // flasks { BaseSet, Flask.Effect, 1 }, { BaseSet, Flask.RecoverySpeed, 1 }, // Damage Multiplier { BaseSet, AnyDamageType.DamageMultiplier, 100 }, // speed { BaseSet, Stat.ActionSpeed, 1 }, { BaseSet, Stat.MovementSpeed, 1 }, // crit { BaseSet, CriticalStrike.Chance.Maximum, 100 }, { BaseSet, CriticalStrike.Chance.Minimum, 0 }, // projectiles { BaseSet, Projectile.Count, 1 }, // evasion { BaseSet, Evasion.Chance.Maximum, 95 }, { BaseSet, Evasion.Chance.Minimum, 5 }, { BaseSet, Stat.ChanceToHit.Maximum, 95 }, { BaseSet, Stat.ChanceToHit.Minimum, 5 }, // block { BaseSet, Block.AttackChance.Maximum, 75 }, { BaseSet, Block.SpellChance.Maximum, 75 }, // dodge { BaseSet, Stat.Dodge.AttackChance.Maximum, 75 }, { BaseSet, Stat.Dodge.SpellChance.Maximum, 75 }, // charges { BaseSet, Charge.Endurance.Amount.Maximum, 3 }, { BaseSet, Charge.Frenzy.Amount.Maximum, 3 }, { BaseSet, Charge.Power.Amount.Maximum, 3 }, { BaseSet, Charge.From(ChargeType.GhostShroud).Amount.Maximum, 3 }, { BaseSet, Charge.From(ChargeType.Intensity).Amount.Maximum, 4 }, { BaseSet, Charge.Endurance.Amount.Minimum, 0 }, { BaseSet, Charge.Frenzy.Amount.Minimum, 0 }, { BaseSet, Charge.Power.Amount.Minimum, 0 }, { BaseSet, Charge.Endurance.Duration, 10 }, { BaseSet, Charge.Frenzy.Duration, 10 }, { BaseSet, Charge.Power.Duration, 10 }, // Rampage { BaseSet, Stat.RampageStacks.Maximum, 1000 }, // leech { BaseSet, Life.Leech.RateLimit, 20 }, { BaseSet, Mana.Leech.RateLimit, 20 }, { BaseSet, EnergyShield.Leech.RateLimit, 10 }, { BaseSet, Life.Leech.Rate, 2 }, { BaseSet, Mana.Leech.Rate, 2 }, { BaseSet, EnergyShield.Leech.Rate, 2 }, { BaseSet, Life.Leech.MaximumRecoveryPerInstance, 10 }, { BaseSet, Mana.Leech.MaximumRecoveryPerInstance, 10 }, { BaseSet, EnergyShield.Leech.MaximumRecoveryPerInstance, 10 }, // resistances { BaseSet, Elemental.Resistance.Maximum, 75 }, { BaseSet, Chaos.Resistance.Maximum, 75 }, { BaseSet, Elemental.Resistance.Maximum.Maximum, 90 }, { BaseSet, Chaos.Resistance.Maximum.Maximum, 90 }, { BaseSet, Damage.Taken, 1 }, // ailments { BaseSet, Ailment.Ignite.InstancesOn(Self).Maximum, 1 }, { BaseSet, Ailment.Ignite.Source(Fire), 1 }, { BaseSet, Ailment.Ignite.Duration, 4 }, { TotalOverride, Ailment.Ignite.CriticalStrikesAlwaysInflict, 1 }, { PercentLess, Damage.With(Ailment.Ignite), 50 }, { BaseSet, Ailment.Shock.InstancesOn(Self).Maximum, 1 }, { BaseSet, Ailment.Shock.Source(Lightning), 1 }, { BaseSet, Ailment.Shock.Duration, 2 }, { TotalOverride, Ailment.Shock.CriticalStrikesAlwaysInflict, 1 }, { BaseSet, Ailment.ShockEffect, 1 }, { BaseSet, Ailment.Chill.InstancesOn(Self).Maximum, 1 }, { BaseSet, Ailment.Chill.Source(Cold), 1 }, { BaseSet, Ailment.Chill.Duration, 2 }, { BaseAdd, Ailment.Chill.Chance, 100 }, { BaseSet, Ailment.ChillEffect, 1 }, { BaseSet, Ailment.Freeze.InstancesOn(Self).Maximum, 1 }, { BaseSet, Ailment.Freeze.Source(Cold), 1 }, { BaseSet, Ailment.Freeze.Duration, 0.06 }, { TotalOverride, Ailment.Freeze.CriticalStrikesAlwaysInflict, 1 }, { BaseSet, Ailment.Bleed.InstancesOn(Self).Maximum, 1 }, { BaseSet, Ailment.Bleed.Source(Physical), 1 }, { BaseSet, Ailment.Bleed.Duration, 5 }, { TotalOverride, Ailment.Bleed.Chance.With(DamageSource.Spell), 0 }, { TotalOverride, Ailment.Bleed.Chance.With(DamageSource.Secondary), 0 }, { PercentLess, Damage.With(Ailment.Bleed), 30 }, { PercentMore, Damage.With(Ailment.Bleed), 100, Enemy.IsMoving }, { BaseSet, Ailment.Poison.Source(Physical.And(Chaos)), 1 }, { BaseSet, Ailment.Poison.Duration, 2 }, { PercentLess, Damage.With(Ailment.Poison), 80 }, // buffs { BaseSet, Buff.CurseLimit, 1 }, { BaseSet, Buffs(Self).Effect, 1 }, { BaseSet, Buff.Fortify.Duration, 4 }, { BaseSet, Buff.Maim.Duration, 4 }, { BaseSet, Buff.Taunt.Duration, 3 }, { BaseSet, Buff.ArcaneSurge.Duration, 4 }, { TotalOverride, Buff.Maim.Chance.With(DamageSource.Spell), 0 }, { TotalOverride, Buff.Maim.Chance.With(DamageSource.Secondary), 0 }, { BaseSet, Buff.Impale.StackCount.Maximum, 5 }, // stun { BaseSet, Effect.Stun.Threshold, 1 }, { BaseSet, Effect.Stun.Recovery, 1 }, { BaseSet, Effect.Stun.Duration, 0.35 }, // other { TotalOverride, Stat.Level.Minimum, 1 }, { TotalOverride, Stat.Level.Maximum, 100 }, { BaseSet, Stat.AreaOfEffect, 1 }, { BaseSet, Stat.CooldownRecoverySpeed, 1 }, { BaseSet, Stat.SkillStage.Minimum, 0 }, { BaseSet, Stat.AttachedBrands.Maximum, 1 }, { BaseSet, Stat.BannerStage.Maximum, 50 }, };
public BridgePart(Physical ph, BridgeMeshBuilder meshBuilder) { this.ph = ph; this.meshBuilder = meshBuilder; }
public void Initialise() { Simulations basicFile = Utilities.GetRunnableSim(); IModel simulation = basicFile.FindInScope <Simulation>(); IModel paddock = basicFile.FindInScope <Zone>(); // Add a weather component. Models.Climate.Weather weather = new Models.Climate.Weather(); weather.Name = "Weather"; weather.FileName = "asdf.met"; Structure.Add(weather, simulation); // Add a second weather component. Models.Climate.Weather weather2 = new Models.Climate.Weather(); weather2.FileName = "asdf.met"; weather2.Name = "Weather2"; Structure.Add(weather2, simulation); // Add a third weather component. Models.Climate.Weather weather3 = new Models.Climate.Weather(); weather3.FileName = "asdf.met"; weather3.Name = "Weather3"; Structure.Add(weather3, simulation); // Add a third weather component. Models.Climate.Weather weather4 = new Models.Climate.Weather(); weather4.FileName = "asdf.met"; weather4.Name = "Weather4"; Structure.Add(weather4, simulation); // Add a report. Models.Report report = new Models.Report(); report.Name = "Report"; Structure.Add(report, paddock); // Add the wheat model. string json = ReflectionUtilities.GetResourceAsString(typeof(IModel).Assembly, "Models.Resources.Wheat.json"); Plant wheat = FileFormat.ReadFromString <IModel>(json, out _).Children[0] as Plant; wheat.ResourceName = "Wheat"; Structure.Add(wheat, paddock); Manager manager = new Manager(); manager.Code = @"using Models.PMF; using Models.Core; using System; namespace Models { [Serializable] public class Script : Model { [Description(""an amount"")] public double Amount { get; set; } } }"; Structure.Add(manager, paddock); Physical physical = new Physical(); physical.BD = new double[5]; physical.AirDry = new double[5]; physical.LL15 = new double[5]; Structure.Add(physical, paddock); basicFile.Write(basicFile.FileName); fileName = basicFile.FileName; // Create a new .apsimx file containing two weather nodes. Simulations test = Utilities.GetRunnableSim(); IModel sim = test.FindInScope <Simulation>(); Models.Climate.Weather w1 = new Models.Climate.Weather(); w1.FileName = "w1.met"; w1.Name = "w1"; Structure.Add(w1, sim); Models.Climate.Weather w2 = new Models.Climate.Weather(); w2.Name = "w2"; w2.FileName = "w2.met"; Structure.Add(w2, sim); extFile = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".apsimx"); test.Write(extFile); }
/// <summary> /// Call this method to initialize the room after all games and modules have been added. This resets all games and time counters, /// (re)opens the physical computing interface and clears and commissions the diagnostics report. If any failures are detected, /// the report is given to the affected games for failure compensation. If this is not possible, the room enters the state /// <see cref="RoomState.Error"/>. Otherwise the method concludes with the room being in the state <see cref="RoomState.Initialized"/>. /// </summary> /// <exception cref="InvalidOperationException">if there are no games registered with the room</exception> /// <exception cref="IllegalRoomStateTransitionException">if initializing the room is not allowed at this time</exception> public void Initialize() { if (gamesInRegisteredOrder.Count == 0) { throw new InvalidOperationException("Please register at least one game before initializing the room."); } Log.Verbose("Initializing room..."); InitializationTime = DateTime.Now; StartTime = null; State = RoomState.Uninitialized; // precondition if (!State.CanTransition(RoomState.Initialized)) { throw new IllegalRoomStateTransitionException(State, RoomState.Initialized); } foreach (Game <TPhysicalInterface> game in gamesInRegisteredOrder) { Debug.Assert(game.State != GameState.Running, "EscapeRoom.ResetRoom: game is running"); } Log.Verbose("Resetting games..."); ElapsedTime = 0f; foreach (Game <TPhysicalInterface> game in gamesInRegisteredOrder) { game.Reset(); } Log.Verbose("(Re)starting physical interface..."); if (Physical.IsOpen) { Physical.Close(); } try { Physical.Open(); } catch (Exception e) { Log.Error(e); Log.Error("Error on opening physical interface. Room initialization discontinued."); State = RoomState.Error; return; } DiagnosticsReport.Clear(); Physical.RunDiagnostics(DiagnosticsReport); if (DiagnosticsReport.FailuresDetected) { List <string> affectedGames = DiagnosticsReport.GetAffectedGames(); foreach (string gameId in affectedGames) { Game <TPhysicalInterface> game = gamesById[gameId]; if (DiagnosticsReport.IsAffected(game)) { if (game.CompensateTechnicalFailures(DiagnosticsReport, DiagnosticsReport.GetAffectedComponents(game))) { DiagnosticsReport.GameCompensated(game); } } } OnDiagnosticsReportCreated?.Invoke(Physical, new DiagnosticsReportCreatedEventArgs(DiagnosticsReport)); if (!DiagnosticsReport.CanContinue()) { Log.Error("Physical interface has reported {0} technical failures, some critical. Room initialization discontinued.", DiagnosticsReport.AffectedComponentsCount); State = RoomState.Error; return; } else { Log.Warn("Physical interface has reported {0} technical failures, none critical. Room initialization continues.", DiagnosticsReport.AffectedComponentsCount); } } Log.Info("Room initialized."); State = RoomState.Initialized; }
public override void Render <TSurface, TSource>(ScreenRenderer <TSurface, TSource> r) { foreach (PlayerAnimation player in WatchedComponents) { Renderable renderable = player.Owner.Components.Get <Renderable>(); Vector2D[] srcOffsets = new Vector2D[5]; srcOffsets[Legs] = new Vector2D(0, Origins[Legs]); srcOffsets[Torso] = new Vector2D(0, Origins[Torso]); srcOffsets[Head] = new Vector2D(0, Origins[Head]); srcOffsets[Woofer] = new Vector2D(0, Origins[Woofer]); srcOffsets[Arms] = new Vector2D(0, Origins[Arms]); Vector2D[] destOffsets = new Vector2D[5]; destOffsets[Legs] = destOffsets[Torso] = destOffsets[Head] = destOffsets[Woofer] = destOffsets[Arms] = Vector2D.Empty; if (!player.Initialized) { renderable.Sprites = new List <Sprite>() { new Sprite(player.SpritesheetName, Destination, new Rectangle(srcOffsets[Legs], 32, 32)), new Sprite(player.SpritesheetName, Destination, new Rectangle(srcOffsets[Torso], 32, 32)), new Sprite(player.SpritesheetName, Destination, new Rectangle(srcOffsets[Head], 32, 32)), new Sprite("woofer", Destination, new Rectangle(srcOffsets[Woofer], 0, 0)), new Sprite(player.SpritesheetName, Destination, new Rectangle(srcOffsets[Arms], 32, 32)) }; player.Initialized = true; } Physical physical = player.Owner.Components.Get <Physical>(); PlayerMovementComponent movement = player.Owner.Components.Get <PlayerMovementComponent>(); PlayerOrientation orientation = player.Owner.Components.Get <PlayerOrientation>(); if (physical == null || movement == null || orientation == null) { continue; } PulseAbility pulse = player.Owner.Components.Get <PulseAbility>(); bool handsFree = pulse == null; if (orientation.Unit.X > 0 || player.LastLookedRight) { for (int i = Legs; i <= Arms; i++) { srcOffsets[i] += OrientationOffset; } } bool forceLook = handsFree && !movement.OnGround; if (orientation.Unit.Y >= Math.Sin(Math.PI / 9)) { if (!forceLook) { srcOffsets[Head].X += 32; } srcOffsets[Woofer].X += 32; if (!handsFree) { srcOffsets[Arms].X += 32; } if (orientation.Unit.Y >= Math.Sin(2 * Math.PI / 6)) { srcOffsets[Woofer].X += 32; if (!handsFree) { srcOffsets[Arms].X += 32; } } } else if (orientation.Unit.Y <= Math.Sin(-Math.PI / 9)) { if (!forceLook) { srcOffsets[Head].X += 64; } srcOffsets[Woofer].X += 96; if (!handsFree) { srcOffsets[Arms].X += 96; } if (orientation.Unit.Y <= Math.Sin(-2 * Math.PI / 6)) { srcOffsets[Woofer].X += 32; destOffsets[Woofer] += new Vector2D(0, -3); //Offset woofer down since it goes out of the spritesheet grid if (!handsFree) { srcOffsets[Arms].X += 32; } } } if (forceLook) { srcOffsets[Head].X += physical.Velocity.Y <= 0 ? 64 : 32; } if (orientation.Unit.X != 0) { player.LastLookedRight = orientation.Unit.X > 0; } if (pulse != null) { srcOffsets[Woofer].Y = 256; srcOffsets[Woofer].Y -= 32 * Math.Round(pulse.EnergyMeter / 20); if (pulse.EnergyMeter == 0 && player.WooferBlinkingTime >= 0.375) { srcOffsets[Woofer].Y += 32; } } if (handsFree) { srcOffsets[Arms].Y += 32; } if (!movement.OnGround || Math.Abs(physical.Velocity.X) <= 1e-2) /*player.WalkAnimationProgress = 0;*/ } {
static void Main(string[] args) { PatientPod Pod = new PatientPod(); #region SetupPatient Blood bs = new Blood(new BloodType() { ABO = BloodABO.AB, Rhesus = BloodRhesus.Positive }); BloodSystem blood = new BloodSystem(bs); Abdomen abs = new Abdomen(reproductives: new Reproductive_Male()); Anthropometrics metrics = new Anthropometrics(21, 181, 120); Physical body = new Physical(blood: blood, abdomen: abs); Patient pt = new Patient(body: body); #endregion //This sucks Pod.TryAddPatient(pt); pt.Body.VascularSystem.OxygenatedVessels["LeftCoronary"].Patency = 0.25f; Pod.PerformProceedure(new ExamineHeartCoronaryAngiogram(), out bool _); //VascularSystem vs = new VascularSystem(); //vs.OxygenatedVessels["AscendingAorta"].Patency = 0.35f; //vs.OxygenatedVessels["LeftCoronary"].Patency = 0.25f; //System.Console.WriteLine(vs.GetSupply(new Heart())); //Vessel restrictionPoint = vs.OxygenatedVessels["LeftAnteriorDescending"].GetLowestPatencyVessel(); //System.Console.WriteLine($"{restrictionPoint.Name}: {restrictionPoint.Patency}"); //Console.WriteLine(pt.Body.Anthropometrics.BMI); //LeftLung left = new LeftLung(); //RightLung right = new RightLung(); //RespiratorySystem respiratorySystem = new RespiratorySystem(left, right); ////respiratorySystem.RemoveLung(true, out Lung temp); ////respiratorySystem.InsertLung(left); //PatientExamination exam = new ExamineLungsAuscultateLungs(); //Pod.PerformProceedure(exam, out bool _); //exam = new ExamineLungsPrecussLungs(); //Pod.PerformProceedure(exam, out bool _); //var t = pt.Body.Infections.Chest.GetInfections(); //System.Console.WriteLine(Pod.PatientResults.RespiratorySystem.LeftLung.BreathSounds[LungLobeLocation.Upper]); //System.Console.WriteLine(Pod.TotalWasteProduced); //PatientProceedure intervention = new PerformLumbarPuncture(); //Pod.PerformProceedure(intervention, out bool _); //System.Console.WriteLine(Pod.TotalWasteProduced); //Lung test = new RightLung(); //test.Lobes[LungLobeLocation.Upper]._organHealth = 0.045f; //test.Lobes[LungLobeLocation.Lower]._organHealth = 0.065f; //OrganState t = test.OrganState; //System.Console.WriteLine( test.OxygenRequirement); System.Console.WriteLine("FOR DEBUGGING"); }
//TODO: Actually load from file public static State Load(string fileName, Fader fader) { fader.Timestep = 0.1f; fader.FadeIn(); //disabled because otherwise it gets annoying to run the game while listening to music and stuff //Resource<Sound>.Get("BGM/HonorForAll", "mp3").IsLooped = true; //Resource<Sound>.Get("BGM/HonorForAll", "mp3").Play(); string file = Path.Combine("Content/Maps/", fileName); var level = new LoadedLevel(new FileStream(file, FileMode.Open)); var chunk = new Chunk(level.Width, level.Height); var camera = new Camera(); var layers = level.Layers; var objectgroups = level.ObjectGroups; foreach (var layer in layers) { int[] tiles = layer.Value.Tiles; int z = int.Parse(layer.Key); for (int x = 0; x < chunk.Width; x++) for (int y = 0; y < chunk.Height; y++) { Texture2D tex = Resource<Texture2D>.Get(level.Tileset.Image); int id = tiles[x + y * chunk.Width]; //Texture coordinates int tx = (int)(id * 32 / 1.5); //why does this work int ty = 0; //int tx = (id % (tex.Width / 32)) * 32; //int ty = (id / (tex.Width / 32)) * 32; int tw = 32; int th = 32; var tile = new Chunk.Tile(tex, tx, ty, tw, th); Dictionary<string, string> properties; if (level.Tileset.TileData.TryGetValue(id, out properties)) //If id isn't found, that means the tile id has no properties defined foreach (var property in properties) tile.AddProperty(property.Key, property.Value); //If id IS found, set all properties tile.AddProperty("FrictionMultiplier", 1); chunk.Set(x, y, z, tile); } } Physical player = null; //This gets set down here foreach (var objectgroup in objectgroups) { var objects = objectgroup.Value.Entities; int z = int.Parse(objectgroup.Key); //TODO: Does this even work too? foreach (var obj in objects) { string name = obj.Name; bool isPassable = false; bool isRamp = false; if (obj.Properties != null) { isRamp = bool.Parse(obj.Properties["IsRamp"]); isPassable = bool.Parse(obj.Properties["IsPassable"]); } int x = (int)(obj.Position.X / 32f) - 0; //This is... int y = (int)(obj.Position.Y / 32f) - 1; //Pretty wonky. if (isRamp) //If it's a ramp, we don't create an entity at all, but a tile! { Texture2D tex = Resource<Texture2D>.Get(level.Tileset.Image); int id = obj.GID; //Texture coordinates int tx = (int)(id * 16); //why does this work int ty = 0; int tw = 32; int th = 32; var tile = new Chunk.Tile(tex, tx, ty, tw, th); foreach (var property in obj.Properties) tile.AddProperty(property.Key, property.Value); chunk.Set(x, y, z, tile); } else { Physical entity; if (name == "player.Start") //TODO: Maybe make these "hardcoded" entities a lookup table of prefabs? { entity = new Physical(Resource<Texture2D>.Get("debug-entity"), x, y, z); player = entity; } else entity = new Physical(Resource<Texture2D>.Get("debug-entity"), //TODO: Read texture from entity x, y, z, isPassable); //TODO: For now, entities don't seem to have a way to set properties... chunk.Add(entity); } } } for (int i = 0; i < 0; i++) //LOOK AT ALL THOSE DUDES HAVING FUN { var otherDude = new Physical(Resource<Texture2D>.Get("debug-entity"), RandomHelper.Range(3, 16-3), RandomHelper.Range(3, 16-3), 0); float time = RandomHelper.Range(); otherDude.Tick += f => { time += f * 0.25f; otherDude.Move((int)Math.Round(Math.Cos(time * Math.PI * 2)), (int)Math.Round(Math.Sin(time * Math.PI * 2)), 100 * f); }; chunk.Add(otherDude); } if (player == null) throw new Exception("Well, well, well. Looks like SOMEONE forgot to put a player.Start in the level. Have fun with all your NullReferenceExceptions down here."); player.Tick += dt => { var k = Keyboard.GetState(); var move = Vector2.Zero; foreach (var i in k.GetPressedKeys()) { switch (i) { case Keys.W: move.Y = -1; break; case Keys.S: move.Y = 1; break; case Keys.A: move.X = -1; break; case Keys.D: move.X = 1; break; case Keys.LeftShift: Console.WriteLine(player.Depth); break; } } if (move != Vector2.Zero) player.Move((int)move.X, (int)move.Y, 200 * dt); camera.Position = player.CenterPosition + Vector2.One / 2; //Add (0.5, 0.5) to player position so we don't get shakyness (it works trust me DON'T REMOVE IT) }; chunk.Add(player); return new State(chunk, camera) { Player = player }; }
public void TestEditing() { string configFile = Path.GetTempFileName(); File.WriteAllLines(configFile, new[] { // Modify an array "[Report].VariableNames = x,y,z", // Modify a date - try a few different formats. "[Clock].StartDate = 2000-01-01", "[Clock].EndDate = 2000-01-10T00:00:00", // Modify a string "[Weather].FileName = fdsa.met", @"[Weather2].FullFileName = jkl.met", // Replace a model with a model from another file. $"[Weather3] = {extFile}", $"[Weather4] = {extFile};[w2]", // Change a property of a resource model. "[Wheat].Leaf.Photosynthesis.RUE.FixedValue = 0.4", // Change a property of a manager script. "[Manager].Script.Amount = 1234", // Set an entire array. "[Physical].BD = 1, 2, 3, 4, 5", // Modify a single element of an array. "[Physical].AirDry[2] = 6", // Modify multiple elements of an array. "[Physical].LL15[3:4] = 7", }); Simulations file = EditFile.Do(fileName, configFile); var report = file.FindInScope <Models.Report>(); string[] variableNames = new[] { "x", "y", "z" }; Assert.AreEqual(variableNames, report.VariableNames); IModel sim = file.FindChild <Simulation>(); // Use an index-based lookup to locate child models. // When we replace an entire model, we want to ensure // that the replacement is inserted at the correct index. Clock clock = sim.Children[0] as Clock; Assert.AreEqual(new DateTime(2000, 1, 1), clock.StartDate); Assert.AreEqual(new DateTime(2000, 1, 10), clock.EndDate); var weather = sim.Children[3] as Models.Climate.Weather; Assert.NotNull(weather); Assert.AreEqual("Weather", weather.Name); Assert.AreEqual("fdsa.met", weather.FileName); var weather2 = sim.Children[4] as Models.Climate.Weather; Assert.NotNull(weather2); Assert.AreEqual("Weather2", weather2.Name); Assert.AreEqual(@"jkl.met", weather2.FileName); // Weather3 and Weather4 should have been // renamed to w1 and w2, respectively. var weather3 = sim.Children[5] as Models.Climate.Weather; Assert.NotNull(weather3); Assert.AreEqual("w1", weather3.Name); Assert.AreEqual("w1.met", weather3.FileName); var weather4 = sim.Children[6] as Models.Climate.Weather; Assert.NotNull(weather4); Assert.AreEqual("w2", weather4.Name); Assert.AreEqual("w2.met", weather4.FileName); // The edit file operation should have changed RUE value to 0.4. var wheat = sim.Children[2].Children[2] as Plant; var rue = wheat.Children[6].Children[4].Children[0] as Constant; Assert.AreEqual(0.4, rue.FixedValue); double amount = (double)sim.FindByPath("[Manager].Script.Amount")?.Value; Assert.AreEqual(1234, amount); Physical physical = sim.Children[2].Children[4] as Physical; Assert.AreEqual(new double[5] { 1, 2, 3, 4, 5 }, physical.BD); Assert.AreEqual(new double[5] { 0, 6, 0, 0, 0 }, physical.AirDry); Assert.AreEqual(new double[5] { 0, 0, 7, 7, 0 }, physical.LL15); }
public override void Input() { IInputMap inputMap = Woofer.Controller.InputManager.ActiveInputMap; foreach (PlayerMovementComponent pmc in WatchedComponents) { if (!pmc.Owner.Active) { continue; } if ((pmc.Owner.Components.Get <Health>()?.InvincibilityTimer ?? 0) > 40) { continue; } if ((pmc.Owner.Components.Get <Health>()?.CurrentHealth ?? 1) <= 0) { continue; } Physical phys = pmc.Owner.Components.Get <Physical>(); if (phys == null) { continue; } ButtonInput jumpButton = inputMap.Jump; //Jump logic if (pmc.OnGround) { if (jumpButton.Consume()) { phys.Velocity.Y = pmc.JumpSpeed; Owner.Events.InvokeEvent(new PlayerJumpEvent(pmc)); } } //Walking logic double xMovement = inputMap.Movement.X * pmc.CurrentSpeed; double xMovementCap = pmc.CurrentMaxSpeed; if (xMovement > 0) { if (phys.Velocity.X <= xMovementCap) { phys.Velocity.X = Math.Min(phys.Velocity.X + xMovement, xMovementCap); } } else if (xMovement < 0) { if (phys.Velocity.X >= -xMovementCap) { phys.Velocity.X = Math.Max(phys.Velocity.X + xMovement, -xMovementCap); } } //For smoothly walking down slopes if (phys.Velocity.Y <= 0) { //Raycast down under the player's feet up to a distance of 4 pixels RaycastEvent raycast = new RaycastEvent(pmc, new FreeVector2D(phys.Position, phys.Position - 8 * Vector2D.UnitJ)); Owner.Events.InvokeEvent(raycast); if (raycast.Intersected != null) { foreach (RaycastIntersection intersection in raycast.Intersected) { if (intersection.Component.Owner != pmc.Owner) { if (intersection.FaceProperties.Snap) //If the intersected face has the 'snap' property enabled (for slopes) { phys.Position = intersection.Point; //Move the player down to the point of intersection, assuming the player's origin is at their feet } } } } } } }
public void TestEditing() { string configFile = Path.GetTempFileName(); File.WriteAllLines(configFile, new[] { // Modify an array "[Report].VariableNames = x,y,z", // Modify a date - try a few different formats. "[Clock].StartDate = 2000-01-01", "[Clock].EndDate = 2000-01-10T00:00:00", // Modify a string "[Weather].FileName = fdsa.met", @"[Weather2].FullFileName = jkl.met", // Replace a model with a model from another file. $"[Weather3] = {extFile}", $"[Weather4] = {extFile};[w2]", // Change a property of a resource model. "[Wheat].Leaf.Photosynthesis.RUE.FixedValue = 0.4", // Change a property of a manager script. "[Manager].Script.Amount = 1234", // Set an entire array. "[Physical].BD = 1, 2, 3, 4, 5", // Modify a single element of an array. "[Physical].AirDry[2] = 6", // Modify multiple elements of an array. "[Physical].LL15[3:4] = 7", }); string models = typeof(IModel).Assembly.Location; string args = $"{fileName} /Edit {configFile}"; var proc = new ProcessUtilities.ProcessWithRedirectedOutput(); proc.Start(models, args, Path.GetTempPath(), true, writeToConsole: true); proc.WaitForExit(); // Children of simulation are, in order: // Clock, summary, zone, Weather, Weather2, w1, w2 Assert.AreEqual(null, proc.StdOut); Assert.AreEqual(null, proc.StdErr); Simulations file = FileFormat.ReadFromFile <Simulations>(fileName, out List <Exception> errors); if (errors != null && errors.Count > 0) { throw errors[0]; } var report = file.FindInScope <Models.Report>(); string[] variableNames = new[] { "x", "y", "z" }; Assert.AreEqual(variableNames, report.VariableNames); IModel sim = file.FindChild <Simulation>(); // Use an index-based lookup to locate child models. // When we replace an entire model, we want to ensure // that the replacement is inserted at the correct index. Clock clock = sim.Children[0] as Clock; Assert.AreEqual(new DateTime(2000, 1, 1), clock.StartDate); Assert.AreEqual(new DateTime(2000, 1, 10), clock.EndDate); var weather = sim.Children[3] as Models.Climate.Weather; Assert.NotNull(weather); Assert.AreEqual("Weather", weather.Name); Assert.AreEqual("fdsa.met", weather.FileName); var weather2 = sim.Children[4] as Models.Climate.Weather; Assert.NotNull(weather2); Assert.AreEqual("Weather2", weather2.Name); Assert.AreEqual(@"jkl.met", weather2.FileName); // Weather3 and Weather4 should have been // renamed to w1 and w2, respectively. var weather3 = sim.Children[5] as Models.Climate.Weather; Assert.NotNull(weather3); Assert.AreEqual("w1", weather3.Name); Assert.AreEqual("w1.met", weather3.FileName); var weather4 = sim.Children[6] as Models.Climate.Weather; Assert.NotNull(weather4); Assert.AreEqual("w2", weather4.Name); Assert.AreEqual("w2.met", weather4.FileName); // The edit file operation should have changed RUE value to 0.4. var wheat = sim.Children[2].Children[2] as Plant; var rue = wheat.Children[6].Children[4].Children[0] as Constant; Assert.AreEqual(0.4, rue.FixedValue); double amount = (double)sim.FindByPath("[Manager].Script.Amount")?.Value; Assert.AreEqual(1234, amount); Physical physical = sim.Children[2].Children[4] as Physical; Assert.AreEqual(new double[5] { 1, 2, 3, 4, 5 }, physical.BD); Assert.AreEqual(new double[5] { 0, 6, 0, 0, 0 }, physical.AirDry); Assert.AreEqual(new double[5] { 0, 0, 7, 7, 0 }, physical.LL15); }
public override void Update() { Entity player = WatchedComponents.OfType <PlayerComponent>().FirstOrDefault()?.Owner; foreach (Boss boss in WatchedComponents.OfType <Boss>()) { if (boss.Health <= 0) { continue; } Spatial sp = boss.Owner.GetComponent <Spatial>(); Physical phys = boss.Owner.GetComponent <Physical>(); Spatial playerSp = player?.GetComponent <Spatial>(); if (sp == null || phys == null) { continue; } phys.GravityMultiplier = 1; phys.Velocity = new Vector2D(0, 362) * Owner.DeltaTime; Vector2D?flyTo = null; float flySpeed = 1; bool showParticles = true; boss.Difficulty = boss.Health > 20 ? 0 : 1; if (boss.State == Boss.Circling) { if (boss.Transitioning) { if ((sp.Position - new Vector2D(0, boss.Difficulty >= 1 ? 192 : 128)).Magnitude < 1) { boss.Transitioning = false; boss.StateData = 0; } else { flyTo = new Vector2D(0, boss.Difficulty >= 1 ? 192 : 128); flySpeed = 2; } } if (!boss.Transitioning) { boss.StateData += Owner.DeltaTime; if (boss.StateData > 16) { boss.ChangeState(Owner.Random.Next(4) == 0 ? Boss.Drop : Boss.Laser); } else { phys.Velocity += new Vector2D(125.6 * Math.Cos(Math.PI * boss.StateData / 4), 0); Vector2D hoverVelocity = new Vector2D(0, 48 * Math.Cos(Math.PI * boss.StateData)); phys.Velocity += hoverVelocity; if (boss.Difficulty >= 1 && Math.Round(boss.StateData, 3) % 4 == 0) { Owner.Entities.Add(new BossProjectileEntity(sp.Position + new Vector2D(0, -48))); } } } } else if (boss.State == Boss.Laser) { if (boss.Transitioning) { if ((sp.Position - new Vector2D(boss.Difficulty >= 1 ? 160 : 0, 256)).Magnitude < 1) { boss.Transitioning = false; boss.StateData = 0; } else { flyTo = new Vector2D(boss.Difficulty >= 1 ? 160 : 0, 256); flySpeed = 2; } } if (!boss.Transitioning) { boss.StateData += Owner.DeltaTime; if (boss.Difficulty < 1 && boss.StateData < 1.5) { if (playerSp != null) { flyTo = new Vector2D(playerSp.Position.X, sp.Position.Y); } } else { if (boss.FlameEntity != 0) { Entity entity = Owner.Entities[boss.FlameEntity]; if (entity != null) { entity.Active = false; } } var laser1 = new BossLaser(sp.Position + new Vector2D(0, -44), true); var laser2 = new BossLaser(sp.Position + new Vector2D(-88, -76), false); var laser3 = new BossLaser(sp.Position + new Vector2D(88, -76), false); laser1.Components.Add(new FollowingComponent(boss.Owner.Id) { Offset = new Vector2D(0, -44) }); laser2.Components.Add(new FollowingComponent(boss.Owner.Id) { Offset = new Vector2D(-88, -76) }); laser3.Components.Add(new FollowingComponent(boss.Owner.Id) { Offset = new Vector2D(88, -76) }); Owner.Entities.Add(laser1); Owner.Entities.Add(laser2); Owner.Entities.Add(laser3); boss.ChangeState(Boss.LaserIdle); showParticles = false; } } } else if (boss.State == Boss.LaserIdle) { boss.Transitioning = false; boss.StateData += Owner.DeltaTime; if (boss.StateData >= 5) { if (boss.FlameEntity != 0) { Entity entity = Owner.Entities[boss.FlameEntity]; if (entity != null) { entity.Active = true; } } boss.ChangeState(Boss.Circling); } else { if (boss.Difficulty >= 1) { phys.Velocity += new Vector2D(-64, 0); } showParticles = false; } } else if (boss.State == Boss.Drop) { if (boss.Transitioning) { if ((sp.Position - new Vector2D(-160, 256)).Magnitude < 1) { boss.Transitioning = false; boss.StateData = 0; } else { flyTo = new Vector2D(-160, 256); flySpeed = 2; } } if (!boss.Transitioning) { if (sp.Position.X >= 160) { boss.ChangeState(Boss.Circling); } else { boss.StateData += Owner.DeltaTime; phys.Velocity += new Vector2D(96, 0); if (boss.StateData >= 1) { boss.StateData = 0; if (boss.SentrySpawnerEntity != 0) { Entity spawner = Owner.Entities[boss.SentrySpawnerEntity]; if (spawner != null) { Owner.Events.InvokeEvent(new ActivationEvent(boss, spawner, null)); } } } } } } //Functions if (flyTo != null) { phys.Velocity += flySpeed * (flyTo.Value - sp.Position); } //Particles if (showParticles && (boss.FlameParticleProgress == 0 || boss.FlameParticleProgress == 5 * 3 || boss.FlameParticleProgress == 5 * 5 || boss.FlameParticleProgress == 2 * 5 || boss.FlameParticleProgress == 7 * 5)) { int variant = boss.FlameParticleProgress == 0 ? 0 : boss.FlameParticleProgress == 3 * 5 ? 1 : boss.FlameParticleProgress == 5 * 5 ? 2 : boss.FlameParticleProgress == 2 * 5 ? 3 : 4; var particle = new BossFlameParticle(sp.Position + phys.Velocity * Owner.DeltaTime + new Vector2D(0, -40), variant); particle.GetComponent <Physical>().Velocity = phys.Velocity * 0.35; Owner.Entities.Add(particle); } boss.FlameParticleProgress++; if (boss.FlameParticleProgress >= 5 * 8) { boss.FlameParticleProgress = 0; } } }
/// This alternative approach for obtaining ISRIC soil data need a little bit more work, but is largely complete /// There are still bits of the soil organic matter initialisation that should be enhanced. /// We probably don't really need two different ways to get to ISRIC data, but it may be interesting to see how the /// two compare. The initial motiviation was what appears to be an order-of-magnitude problem with soil carbon /// in the World Modellers version. /// <summary> /// Gets and ISRIC soil description directly from SoilGrids /// </summary> /// <returns>True if successful</returns> private IEnumerable <SoilFromDataSource> GetISRICSoils() { var soils = new List <SoilFromDataSource>(); string url = "https://rest.soilgrids.org/query?lon=" + longitudeEditBox.Text + "&lat=" + latitudeEditBox.Text; try { double[] bd = new double[7]; double[] coarse = new double[7]; double[] clay = new double[7]; double[] silt = new double[7]; double[] sand = new double[7]; double[] thetaSat = new double[7]; double[] awc20 = new double[7]; double[] awc23 = new double[7]; double[] awc25 = new double[7]; double[] thetaWwp = new double[7]; double[] ocdrc = new double[7]; double[] phWater = new double[7]; double[] cationEC = new double[7]; double[] texture = new double[7]; string soilType = String.Empty; double maxTemp = 0.0; double minTemp = 0.0; double ppt = 0.0; double bedrock = 2500.0; string[] textureClasses = new string[] { "Clay", "Silty Clay", "Sandy Clay", "Clay Loam", "Silty Clay Loam", "Sandy Clay Loam", "Loam", "Silty Loam", "Sandy Loam", "Silt", "Loamy Sand", "Sand", "NO DATA" }; double[] textureToAlb = new double[] { 0.12, 0.12, 0.13, 0.13, 0.12, 0.13, 0.13, 0.14, 0.13, 0.13, 0.16, 0.19, 0.13 }; double[] textureToCN2 = new double[] { 73.0, 73.0, 73.0, 73.0, 73.0, 73.0, 73.0, 73.0, 68.0, 73.0, 68.0, 68.0, 73.0 }; double[] textureToSwcon = new double[] { 0.25, 0.3, 0.3, 0.4, 0.5, 0.5, 0.5, 0.5, 0.6, 0.5, 0.6, 0.75, 0.5 }; MemoryStream stream = WebUtilities.ExtractDataFromURL(url); stream.Position = 0; JsonTextReader reader = new JsonTextReader(new StreamReader(stream)); while (reader.Read()) { if (reader.TokenType == JsonToken.PropertyName && reader.Value.Equals("properties") && reader.Depth == 1) { reader.Read(); // Read the "start object" token while (reader.Read()) { if (reader.TokenType == JsonToken.PropertyName) { string propName = reader.Value.ToString(); double[] dest = null; double multiplier = 1.0; if (propName == "TAXNWRBMajor") { soilType = reader.ReadAsString(); } else if (propName == "TMDMOD_2011") { maxTemp = 0.0; reader.Read(); while (reader.Read() && reader.TokenType != JsonToken.EndObject) { if (reader.TokenType == JsonToken.PropertyName && reader.Value.Equals("M")) { reader.Read(); // Read start of object token for (int i = 0; i < 12; i++) { reader.Read(); // Read a month name maxTemp += (double)reader.ReadAsDouble(); } maxTemp /= 12.0; } } } else if (propName == "TMNMOD_2011") { minTemp = 0.0; reader.Read(); while (reader.Read() && reader.TokenType != JsonToken.EndObject) { if (reader.TokenType == JsonToken.PropertyName && reader.Value.Equals("M")) { reader.Read(); // Read start of object token for (int i = 0; i < 12; i++) { reader.Read(); // Read a month name minTemp += (double)reader.ReadAsDouble(); } minTemp /= 12.0; } } } else if (propName == "PREMRG") { ppt = 0.0; reader.Read(); while (reader.Read() && reader.TokenType != JsonToken.EndObject) { if (reader.TokenType == JsonToken.PropertyName && reader.Value.Equals("M")) { reader.Read(); // Read start of object token for (int i = 0; i < 12; i++) { reader.Read(); // Read a month name ppt += (double)reader.ReadAsDouble(); } } } } else if (propName == "BDTICM") // Is this the best metric to use for find the "bottom" of the soil? { reader.Read(); while (reader.Read() && reader.TokenType != JsonToken.EndObject) { if (reader.TokenType == JsonToken.PropertyName && reader.Value.Equals("M")) { reader.Read(); // Read start of object token reader.Read(); // Read property name (which ought to be BDTICM_M) bedrock = 10.0 * (double)reader.ReadAsDouble(); reader.Skip(); } } } else if (propName == "AWCh1") { dest = awc20; multiplier = 0.01; } else if (propName == "AWCh2") { dest = awc23; multiplier = 0.01; } else if (propName == "AWCh3") { dest = awc25; multiplier = 0.01; } else if (propName == "AWCtS") { dest = thetaSat; multiplier = 0.01; } else if (propName == "BLDFIE") { dest = bd; multiplier = 0.001; } else if (propName == "CECSOL") { dest = cationEC; multiplier = 1.0; } else if (propName == "CLYPPT") { dest = clay; multiplier = 1.0; } else if (propName == "CRFVOL") { dest = coarse; multiplier = 1.0; } else if (propName == "ORCDRC") { dest = ocdrc; multiplier = 0.1; } else if (propName == "PHIHOX") { dest = phWater; multiplier = 0.1; } else if (propName == "SLTPPT") { dest = silt; multiplier = 1.0; } else if (propName == "SNDPPT") { dest = sand; multiplier = 1.0; } else if (propName == "TEXMHT") { dest = texture; multiplier = 1.0; } else if (propName == "WWP") { dest = thetaWwp; multiplier = 0.01; } if (dest != null) { reader.Read(); while (reader.Read() && reader.TokenType != JsonToken.EndObject) { if (reader.TokenType == JsonToken.PropertyName && reader.Value.Equals("M")) { while (reader.Read() && reader.TokenType != JsonToken.EndObject) { if (reader.TokenType == JsonToken.PropertyName) { string tokenName = reader.Value.ToString(); if (tokenName.StartsWith("sl")) { int index = Int32.Parse(tokenName.Substring(2)) - 1; dest[index] = (double)reader.ReadAsDouble() * multiplier; } } } } } } else { reader.Skip(); } } } } } var newSoil = new Soil(); Chemical analysis = new Chemical(); Physical waterNode = new Physical(); Organic organicMatter = new Organic(); WaterBalance soilWater = new WaterBalance(); InitialWater initialWater = new InitialWater(); Sample initialNitrogen = new Sample(); Nutrient nutrient = new Nutrient(); nutrient.ResourceName = "Nutrient"; SoilCrop wheat = new SoilCrop(); waterNode.Children.Add(wheat); wheat.Name = "WheatSoil"; waterNode.ParentAllDescendants(); newSoil.Children.Add(waterNode); newSoil.Children.Add(soilWater); newSoil.Children.Add(nutrient); newSoil.Children.Add(organicMatter); newSoil.Children.Add(analysis); newSoil.Children.Add(initialWater); newSoil.Children.Add(initialNitrogen); newSoil.Children.Add(new CERESSoilTemperature()); newSoil.ParentAllDescendants(); newSoil.OnCreated(); newSoil.Name = "Synthetic soil derived from ISRIC SoilGrids REST API"; newSoil.DataSource = "ISRIC SoilGrids"; newSoil.SoilType = soilType; newSoil.Latitude = Convert.ToDouble(latitudeEditBox.Text, System.Globalization.CultureInfo.InvariantCulture); newSoil.Longitude = Convert.ToDouble(longitudeEditBox.Text, System.Globalization.CultureInfo.InvariantCulture); // ISRIC values are for "levels", not "intervals", so we need to convert to layers // Following Andrew Moore's lead on layer thickness and weightings. double[] thickness = new double[] { 150.0, 150.0, 150.0, 150.0, 200.0, 200.0, 200.0, 200.0, 300.0, 300.0 }; double[] depth = new double[thickness.Length]; int layerCount = thickness.Length; for (int i = 0; i < thickness.Length; i++) { depth[i] = thickness[i] + (i > 0 ? depth[i - 1] : 0.0); if ((i > 0) && (layerCount == thickness.Length) && (bedrock < depth[i] + 20.0)) { layerCount = i + 1; thickness[i] = Math.Min(thickness[i], Math.Max(0.0, bedrock - (depth[i] - thickness[i]))); if (i == 1) { thickness[i] = Math.Max(50.0, thickness[i]); } Array.Resize(ref thickness, layerCount); } } analysis.Thickness = thickness; waterNode.Thickness = thickness; soilWater.Thickness = thickness; organicMatter.Thickness = thickness; initialWater.Name = "Initial water"; initialWater.PercentMethod = InitialWater.PercentMethodEnum.FilledFromTop; initialWater.FractionFull = 0.0; // Initialise nitrogen to 0.0 initialNitrogen.Name = "Initial nitrogen"; initialNitrogen.NH4 = new double[layerCount]; initialNitrogen.NO3 = new double[layerCount]; double tAvg = (maxTemp + minTemp) / 2.0; soilWater.CNCov = 0.0; soilWater.CNRed = 20.0; soilWater.SummerDate = newSoil.Latitude <= 0.0 ? "1-nov" : "1-may"; soilWater.WinterDate = newSoil.Latitude <= 0.0 ? "1-apr" : "1-oct"; soilWater.SummerCona = 6.0; soilWater.SummerU = 6.0; soilWater.WinterCona = tAvg < 21.0 ? 2.5 : 6.0; soilWater.WinterU = tAvg < 21.0 ? 4.0 : 6.0; soilWater.Salb = textureToAlb[(int)Math.Round(texture[0] - 1)]; soilWater.CN2Bare = textureToCN2[(int)Math.Round(texture[0] - 1)]; double[] swcon = new double[7]; for (int i = 0; i < 7; i++) { swcon[i] = textureToSwcon[(int)Math.Round(texture[i] - 1)]; } soilWater.SWCON = ConvertLayers(swcon, layerCount); waterNode.BD = ConvertLayers(bd, layerCount); waterNode.LL15 = ConvertLayers(thetaWwp, layerCount); waterNode.SAT = ConvertLayers(thetaSat, layerCount); waterNode.AirDry = ConvertLayers(MathUtilities.Divide_Value(thetaWwp, 3.0), layerCount); double[] dul = new double[7]; for (int i = 0; i < 7; i++) { dul[i] = thetaWwp[i] + awc20[i]; // This could be made Moore complex } waterNode.DUL = ConvertLayers(dul, layerCount); waterNode.ParticleSizeSand = ConvertLayers(sand, layerCount); waterNode.ParticleSizeSilt = ConvertLayers(silt, layerCount); waterNode.ParticleSizeClay = ConvertLayers(clay, layerCount); // waterNode.Rocks = ConvertLayers(coarse, layerCount); analysis.PH = ConvertLayers(phWater, layerCount); // Obviously using the averaging in "ConvertLayers" for texture classes is not really correct, but should be OK as a first pass if we don't have sharply contrasting layers double[] classes = ConvertLayers(texture, layerCount); string[] textures = new string[layerCount]; for (int i = 0; i < layerCount; i++) { textures[i] = textureClasses[(int)Math.Round(classes[i]) - 1]; } double[] xf = new double[layerCount]; double[] kl = new double[layerCount]; double[] ll = new double[layerCount]; double p1 = 1.4; double p2 = 1.60 - p1; double p3 = 1.80 - p1; double topEffDepth = 0.0; double klMax = 0.06; double depthKl = 900.0; double depthRoot = 1900.0; for (int i = 0; i < layerCount; i++) { xf[i] = 1.0 - (waterNode.BD[i] - (p1 + p2 * 0.01 * waterNode.ParticleSizeSand[i])) / p3; xf[i] = Math.Max(0.1, Math.Min(1.0, xf[i])); double effectiveThickness = thickness[i] * xf[i]; double bottomEffDepth = topEffDepth + effectiveThickness; double propMaxKl = Math.Max(0.0, Math.Min(bottomEffDepth, depthKl) - topEffDepth) / effectiveThickness; double propDecrKl = Math.Max(Math.Max(0.0, Math.Min(bottomEffDepth, depthRoot) - topEffDepth) / effectiveThickness - propMaxKl, 0.0); double propZeroKl = 1.0 - propMaxKl - propDecrKl; double ratioTopDepth = Math.Max(0.0, Math.Min((depthRoot - topEffDepth) / (depthRoot - depthKl), 1.0)); double ratioBottomDepth = Math.Max(0.0, Math.Min((depthRoot - bottomEffDepth) / (depthRoot - depthKl), 1.0)); double meanDecrRatio = 0.5 * (ratioTopDepth + ratioBottomDepth); double weightedRatio = propMaxKl * 1.0 + propDecrKl * meanDecrRatio + propZeroKl * 0.0; kl[i] = klMax * weightedRatio; ll[i] = waterNode.LL15[i] + (waterNode.DUL[i] - waterNode.LL15[i]) * (1.0 - weightedRatio); if (kl[i] <= 0.0) { xf[i] = 0.0; } topEffDepth = bottomEffDepth; } wheat.XF = xf; wheat.KL = kl; wheat.LL = ll; organicMatter.Carbon = ConvertLayers(ocdrc, layerCount); double rootWt = Math.Max(0.0, Math.Min(3000.0, 2.5 * (ppt - 100.0))); // For AosimX, root wt needs to be distributed across layers. This conversion logic is adapted from that used in UpgradeToVersion52 double[] rootWtFraction = new double[layerCount]; double profileDepth = depth[layerCount - 1]; double cumDepth = 0.0; for (int layer = 0; layer < layerCount; layer++) { double fracLayer = Math.Min(1.0, MathUtilities.Divide(profileDepth - cumDepth, thickness[layer], 0.0)); cumDepth += thickness[layer]; rootWtFraction[layer] = fracLayer * Math.Exp(-3.0 * Math.Min(1.0, MathUtilities.Divide(cumDepth, profileDepth, 0.0))); } // get the actuall FOM distribution through layers (adds up to one) double totFOMfraction = MathUtilities.Sum(rootWtFraction); for (int layer = 0; layer < thickness.Length; layer++) { rootWtFraction[layer] /= totFOMfraction; } organicMatter.FOM = MathUtilities.Multiply_Value(rootWtFraction, rootWt); double[] fBiom = { 0.04, 0.04 - 0.03 * (225.0 - 150.0) / (400.0 - 150.0), (400.0 - 300.0) / (450.0 - 300.0) * (0.04 - 0.03 * (350.0 - 150.0) / (400.0 - 150.0)) + (450.0 - 400.0) / (450.0 - 300.0) * 0.01, 0.01, 0.01,0.01, 0.01, 0.01, 0.01, 0.01 }; Array.Resize(ref fBiom, layerCount); double inert_c = 0.95 * ocdrc[4]; double[] fInert = new double[7]; for (int layer = 0; layer < 7; layer++) { fInert[layer] = Math.Min(0.99, inert_c / ocdrc[layer]); } organicMatter.FInert = ConvertLayers(fInert, layerCount); // Not perfect, but should be good enough organicMatter.FBiom = fBiom; organicMatter.FOMCNRatio = 40.0; organicMatter.SoilCNRatio = Enumerable.Repeat(11.0, layerCount).ToArray(); // Is there any good way to estimate this? ISRIC provides no N data newSoil.Children.Add(new CERESSoilTemperature()); newSoil.OnCreated(); soils.Add(new SoilFromDataSource() { DataSource = "ISRIC", Soil = newSoil }); } catch (Exception err) { explorerPresenter.MainPresenter.ShowError(err); } return(soils); }
public override void EventFired(object sender, Event evt) { PulseEmitterComponent pem; if (evt is PulseEvent pe) { foreach (PulsePushable pp in WatchedComponents.Where(c => c is PulsePushable)) { if (!pp.Owner.Active) { continue; } if (pp.Owner == evt.Sender.Owner) { continue; } if (!pp.Owner.Components.Has <Transform>() || !pp.Owner.Components.Has <Physical>()) { continue; } Physical ph = pp.Owner.Components.Get <Physical>(); Vector2D center = pp.Owner.Components.Has <SoftBody>() ? pp.Owner.Components.Get <SoftBody>().Bounds.Offset(ph.Position).Center : ph.Position; double distance = (center - pe.Source).Magnitude; if (distance > pe.Reach) { continue; } if (pe.Direction.Magnitude == 0 || GeneralUtil.SubtractAngles((center - pe.Source).Angle, pe.Direction.Angle) <= Math.Atan(1 / pe.Direction.Magnitude)) { double mass = 1; if (pp.Owner.Components.Has <SoftBody>()) { mass = pp.Owner.Components.Get <SoftBody>().Mass; } double factor = 1 - (distance / pe.Reach); ph.Velocity += ((center - pe.Source).Normalize() * (factor * pe.Strength) / mass); if (pp.Owner.Components.Get <ProjectileComponent>() is ProjectileComponent projectile && projectile.Deflectable && pp.Owner.Components.Get <DamageOnContactComponent>() is DamageOnContactComponent damager) { if (pe.Sender != null) { projectile.Thrower = pe.Sender.Owner.Id; if (pe.Sender.Owner.Components.Has <PlayerComponent>()) { damager.Filter = DamageFilter.DamageEnemies; } else if (pe.Sender.Owner.Components.Has <EnemyComponent>()) { damager.Filter = DamageFilter.DamageAllies; } } } } } if (pe.Direction.Magnitude > 0) { List <Entity> hit = new List <Entity>(); List <Entity> damaged = new List <Entity>(); for (int i = -1; i <= 1; i++) { RaycastEvent raycast = new RaycastEvent(evt.Sender, new FreeVector2D(pe.Source, pe.Source + pe.Direction.Rotate(i * (Math.PI / 4)) * pe.Reach)); Owner.Events.InvokeEvent(raycast); if (raycast.Intersected != null) { foreach (RaycastIntersection intersection in raycast.Intersected) { if (intersection.Component.Owner != pe.Sender.Owner && intersection.Component.Owner.Components.Has <PulseReceiverPhysical>() && !hit.Contains(intersection.Component.Owner)) { hit.Add(intersection.Component.Owner); } else if (intersection.Component.Owner != pe.Sender.Owner && intersection.Component.Owner.Components.Has <PulseDamaged>() && !damaged.Contains(intersection.Component.Owner)) { damaged.Add(intersection.Component.Owner); } } } } hit.ForEach(e => Owner.Events.InvokeEvent(new ActivationEvent(pe.Sender, e, pe))); damaged.ForEach(e => Owner.Events.InvokeEvent(new DamageEvent(e, 1, pe.Sender))); } foreach (PulseReceiver pr in WatchedComponents.Where(c => c is PulseReceiver)) { if (!pr.Owner.Active) { return; } if (pr.Owner == evt.Sender.Owner) { continue; } Vector2D point = pr.Offset; if (pr.Owner.Components.Get <Transform>() is Transform sp) { point += sp.Position; } if (pe.Direction.Magnitude == 0 || GeneralUtil.SubtractAngles((point - pe.Source).Angle, pe.Direction.Angle) <= Math.PI / 4) { double distance = (point - pe.Source).Magnitude; if (distance <= pe.Reach * pr.Sensitivity) { Owner.Events.InvokeEvent(new ActivationEvent(pe.Sender, pr.Owner, pe)); } } } if (!pe.Sender.Owner.Components.Has <PlayerAnimation>()) { for (int i = 0; i < 5 * Math.Pow(pe.Strength / 16384, 2); i++) { SoundParticle particle = new SoundParticle(pe.Source + pe.Direction * 12, i * 8); Owner.Entities.Add(particle); } } } else if (evt is ActivationEvent e && (pem = e.Affected.Components.Get <PulseEmitterComponent>()) != null) { Vector2D source = pem.Offset; if (pem.Owner.Components.Get <Transform>() is Transform sp) { source += sp.Position; } Owner.Events.InvokeEvent(new PulseEvent(pem, source, pem.Direction, pem.Strength, pem.Reach)); } }
protected internal override void OnEnter(Engine.CoreEngine engine) { Chrome.Attach(engine.Form); var menu = new Interface.Menu() { Position = new Vector2(), Size = new Vector2(9000, 40) }; menu.Items.AddRange("File", "Edit", "View", "Window", "Help"); menu.Items[0].Children.AddRange("New", "Open", "Save", "Exit"); menu.Items[0].Children[3].Clicked += (s, e) => engine.Form.Close(); menu.Items[1].Children.AddRange("Cut", "Copy", "Paste"); menu.Items[4].Children.AddRange("About"); Chrome.Controls.Add(menu); var entityTree = new Interface.Custom.EntityComponentTree(Scene) { Position = new Vector2(10, 100), Size = new Vector2(200, 400), }; Chrome.Controls.Add(entityTree); var skyBox = Texture2D.FromFile(Engine.Device, "../../skybox/right.jpg", "../../skybox/left.jpg", "../../skybox/top.jpg", "../../skybox/bottom.jpg", "../../skybox/front.jpg", "../../skybox/back.jpg"); pbr.skybox = skyBox; sbr.skybox = skyBox; var material = new Material() { Albedo = Texture2D.FromFile(Engine.Device, "../../pbr/albedo.jpg"), Normal = Texture2D.FromFile(Engine.Device, "../../pbr/normal.jpg"), Roughness = Texture2D.FromFile(Engine.Device, "../../pbr/roughness.jpg"), Height = Texture2D.FromFile(Engine.Device, "../../pbr/height.jpg"), Specular = Texture2D.FromFile(Engine.Device, "../../pbr/metallic.jpg"), Alpha = Texture2D.FromFile(Engine.Device, "../../pbr/alpha.jpg"), Occlusion = Texture2D.FromFile(Engine.Device, "../../pbr/ambientocclusion.jpg"), }; material.Roughness = material.Height; //material.Specular = material.Normal; Color red = Color.Red; Color green = Color.Green; var aMaterial = new Material() { //Albedo = Texture2D.FromColor(Engine.Device, Color.Red), Albedo = Texture2D.FromColor(Engine.Device, new Color(0.7038f, 0.27048f, 0.0828f, 1f)), Normal = Texture2D.FromColor(Engine.Device, new Color(0.5f, 1f, 0.5f)), Roughness = Texture2D.FromColor(Engine.Device, new Color(0.2f)), Specular = Texture2D.FromColor(Engine.Device, new Color(0.256777f, 0.137622f, 0.086014f, 1)), Occlusion = Texture2D.FromColor(Engine.Device, Color.White), }; var shipModel = Model.FromMesh(Engine.Device, Mathematics.Geometry.WavefrontObj.Load("../../Model.obj")); shipModel.Materials.Add(material); var missileModel = Model.FromMesh(Engine.Device, Mathematics.Geometry.WavefrontObj.Load("../../Missile.obj")); missileModel.Materials.Add(material); var boxModel = Model.FromMesh(Engine.Device, Mathematics.Geometry.Mesh.CreateCube().Invert()); var rock1 = Model.FromMesh(Engine.Device, Mathematics.Geometry.WavefrontObj.Load("../../Rock1.obj")); rock1.Materials.Add(aMaterial); var rock2 = Model.FromMesh(Engine.Device, Mathematics.Geometry.WavefrontObj.Load("../../Rock2.obj")); rock2.Materials.Add(aMaterial); Scene.Entities.Add(new Entity("Camera") .Add(camera = new Camera { View = view, Projection = projection, }) .Add(new Renderable { Model = boxModel, Renderer = sbr, })); Scene.Entities.Add(new Entity("Ship 1", new Transform { Scaling = new Axiverse.Vector3(5), }) .Add(new Renderable() { Model = rock2, Renderer = pbr, }) .Add(new Physical())); Scene.Entities.Add(new Entity("Point Light", new Transform { Translation = new Axiverse.Vector3(4, 50, 6), }) .Add(new Light() { Color = Color.White, Intensity = 1, })); for (int i = 0; i < 100; i++) { Physical p; Scene.Entities.Add(new Entity("Missile " + (i + 1), new Transform { Scaling = new Axiverse.Vector3(0.2f, 1, 0.2f), }) .Add(new Renderable() { Model = missileModel, Renderer = pbr, }) .Add(new Agent()) .Add(p = new Physical())); p.Body.AngularPosition = Functions.Random.NextQuaternion(); } }
protected override IReadOnlyList <MatcherData> CreateCollection() => new FormAndStatMatcherCollection(_modifierBuilder, ValueFactory) { // attributes // offense // - damage { @"adds # to # ({DamageTypeMatchers}) damage", BaseAdd, ValueFactory.FromMinAndMax(Values[0], Values[1]), Reference.AsDamageType.Damage.WithHits }, { @"# to # added ({DamageTypeMatchers}) damage", BaseAdd, ValueFactory.FromMinAndMax(Values[0], Values[1]), Reference.AsDamageType.Damage.WithHits }, { "# to # ({DamageTypeMatchers}) damage", BaseAdd, ValueFactory.FromMinAndMax(Values[0], Values[1]), Reference.AsDamageType.Damage.WithHits }, { @"adds # to # ({DamageTypeMatchers}) damage to attacks", BaseAdd, ValueFactory.FromMinAndMax(Values[0], Values[1]), Reference.AsDamageType.Damage.WithSkills(DamageSource.Attack) }, { @"adds # to # ({DamageTypeMatchers}) damage to unarmed attacks", BaseAdd, ValueFactory.FromMinAndMax(Values[0], Values[1]), Reference.AsDamageType.Damage.WithSkills(DamageSource.Attack).With(Keyword.Melee), Not(MainHand.HasItem) }, { @"adds # to # ({DamageTypeMatchers}) damage to bow attacks", BaseAdd, ValueFactory.FromMinAndMax(Values[0], Values[1]), Reference.AsDamageType.Damage.WithSkills(DamageSource.Attack).With(Keyword.Melee), MainHand.Has(Tags.Bow) }, { @"adds # to # ({DamageTypeMatchers}) damage to spells", BaseAdd, ValueFactory.FromMinAndMax(Values[0], Values[1]), Reference.AsDamageType.Damage.WithSkills(DamageSource.Spell) }, { @"adds # to # ({DamageTypeMatchers}) damage to spells and attacks", BaseAdd, ValueFactory.FromMinAndMax(Values[0], Values[1]), Reference.AsDamageType.Damage.WithSkills(DamageSource.Spell), Reference.AsDamageType.Damage.WithSkills(DamageSource.Attack) }, { @"# to # additional ({DamageTypeMatchers}) damage", BaseAdd, ValueFactory.FromMinAndMax(Values[0], Values[1]), Reference.AsDamageType.Damage.WithHits }, { @"adds # maximum ({DamageTypeMatchers}) damage", BaseAdd, Value.MaximumOnly, Reference.AsDamageType.Damage.WithHits }, { "deal no ({DamageTypeMatchers}) damage", TotalOverride, 0, Reference.AsDamageType.Damage }, { @"explosion deals (base )?({DamageTypeMatchers}) damage equal to #% of the (corpse|monster)'s maximum life", BaseSet, Value.AsPercentage *Life.For(Enemy).Value, Reference.AsDamageType.Damage.WithSkills(DamageSource.Secondary) }, { @"explosion deals # to # base ({DamageTypeMatchers}) damage", BaseSet, ValueFactory.FromMinAndMax(Values[0], Values[1]), Reference.AsDamageType.Damage.WithSkills(DamageSource.Secondary) }, { "deals # to # base ({DamageTypeMatchers}) damage", BaseSet, ValueFactory.FromMinAndMax(Values[0], Values[1]), Reference.AsDamageType.Damage.WithSkills(DamageSource.Spell) }, // - damage taken { "cold damage taken increased by chill effect", PercentIncrease, 100 * (Ailment.ChillEffect.Value - 1), Cold.Damage.Taken.With(DamageSource.OverTime) }, // - damage taken as // - conversion and gain { "(gain )?#% of ({DamageTypeMatchers}) damage (gained |added )?as (extra )?({DamageTypeMatchers}) damage", BaseAdd, Value, References[0].AsDamageType.Damage.WithHitsAndAilments .GainAs(References[1].AsDamageType.Damage.WithHitsAndAilments) }, { "gain #% of ({DamageTypeMatchers}) damage as extra damage of a random element", BaseAdd, Value, Reference.AsDamageType.Damage.WithHitsAndAilments .GainAs(RandomElement.Damage.WithHitsAndAilments) }, { "gain #% of wand ({DamageTypeMatchers}) damage as extra ({DamageTypeMatchers}) damage", BaseAdd, Value, References[0].AsDamageType.Damage.With(AttackDamageHand.MainHand) .GainAs(References[1].AsDamageType.Damage.With(AttackDamageHand.MainHand)) .WithCondition(MainHand.Has(Tags.Wand)), References[0].AsDamageType.Damage.With(AttackDamageHand.OffHand) .GainAs(References[1].AsDamageType.Damage.With(AttackDamageHand.OffHand)) .WithCondition(OffHand.Has(Tags.Wand)) }, { "#% of ({DamageTypeMatchers}) damage converted to ({DamageTypeMatchers}) damage", BaseAdd, Value, References[0].AsDamageType.Damage.WithHitsAndAilments .ConvertTo(References[1].AsDamageType.Damage.WithHitsAndAilments) }, { "({DamageTypeMatchers}) spells have #% of ({DamageTypeMatchers}) damage converted to ({DamageTypeMatchers}) damage", BaseAdd, Value, References[1].AsDamageType.Damage.With(DamageSource.Spell) .ConvertTo(References[2].AsDamageType.Damage.With(DamageSource.Spell)), With(References[0].AsDamageType) }, // - penetration { "damage penetrates #% (of enemy )?({DamageTypeMatchers}) resistances?", BaseAdd, Value, Reference.AsDamageType.Penetration }, { "damage (?<inner>with .*|dealt by .*) penetrates #% ({DamageTypeMatchers}) resistances?", BaseAdd, Value, Reference.AsDamageType.Penetration, "${inner}" }, { "penetrates? #% ({DamageTypeMatchers}) resistances?", BaseAdd, Value, Reference.AsDamageType.Penetration }, { "({KeywordMatchers}) damage penetrates #% ({DamageTypeMatchers}) resistances?", BaseAdd, Value, References[1].AsDamageType.Penetration.With(References[0].AsKeyword) }, { "({KeywordMatchers}) damage (?<inner>with .*|dealt by .*) penetrates #% ({DamageTypeMatchers}) resistances?", BaseAdd, Value, References[1].AsDamageType.Penetration.With(References[1].AsKeyword), "${inner}" }, { "hits ignore enemy monster ({DamageTypeMatchers}) resistance", TotalOverride, 1, Reference.AsDamageType.IgnoreResistance }, // - exposure { @"(?<damageType>({DamageTypeMatchers})) exposure applies #% to \k<damageType> resistance", BaseSet, Value, Reference.AsDamageType.Exposure }, // - crit { @"\+#% critical strike chance", BaseAdd, Value, CriticalStrike.Chance }, { "no critical strike multiplier, no damage multiplier for ailments from critical strikes", TotalOverride, 0, CriticalStrike.Multiplier }, { "never deal critical strikes", TotalOverride, 0, CriticalStrike.Chance }, // - speed { "actions are #% slower", PercentLess, Value, Stat.ActionSpeed }, { @"\+# seconds to attack time", BaseAdd, Value, Stat.BaseCastTime.With(DamageSource.Attack) }, // - projectiles { "fires # additional projectiles", BaseAdd, Value, Projectile.Count }, { "fires # additional arrows", BaseAdd, Value, Projectile.Count, With(Keyword.Attack) }, { "fires an additional projectile", BaseAdd, 1, Projectile.Count }, { "fires an additional arrow", BaseAdd, 1, Projectile.Count, With(Keyword.Attack) }, { "skills fire an additional projectile", BaseAdd, 1, Projectile.Count }, { "skills fire # additional projectiles", BaseAdd, Value, Projectile.Count }, { "supported skills fire # additional projectiles", BaseAdd, Value, Projectile.Count }, { "pierces # additional targets", BaseAdd, Value, Projectile.PierceCount }, { "projectiles pierce an additional target", BaseAdd, 1, Projectile.PierceCount }, { "arrows pierce an additional target", BaseAdd, 1, Projectile.PierceCount, With(Keyword.Attack) }, { "projectiles pierce # (additional )?targets", BaseAdd, Value, Projectile.PierceCount }, { "arrows pierce # (additional )?targets", BaseAdd, Value, Projectile.PierceCount, With(Keyword.Attack) }, { "projectiles from supported skills pierce # additional targets", BaseAdd, Value, Projectile.PierceCount }, { "projectiles pierce all nearby targets", TotalOverride, double.PositiveInfinity, Projectile.PierceCount, Enemy.IsNearby }, { "projectiles pierce all targets", TotalOverride, double.PositiveInfinity, Projectile.PierceCount }, { @"chains \+# times", BaseAdd, Value, Projectile.ChainCount }, { @"(supported )?skills chain \+# times", BaseAdd, Value, Projectile.ChainCount }, // - other { "your hits can't be evaded", TotalOverride, 100, Stat.ChanceToHit }, { "can't be evaded", TotalOverride, 100, Stat.ChanceToHit }, // defense // - life, mana, defences { "maximum life becomes #", TotalOverride, Value, Life }, { "removes all mana", TotalOverride, 0, Mana }, { "converts all evasion rating to armour", TotalOverride, 100, Evasion.ConvertTo(Armour) }, { "cannot evade enemy attacks", TotalOverride, 0, Evasion.Chance }, { @"\+# evasion rating", BaseAdd, Value, Evasion }, // - resistances { "immune to ({DamageTypeMatchers}) damage", TotalOverride, 100, Reference.AsDamageType.Resistance }, { @"\+#% elemental resistances", BaseAdd, Value, Elemental.Resistance }, { @"\+?#% physical damage reduction", BaseAdd, Value, Physical.Resistance }, // - leech { "leech energy shield instead of life", TotalOverride, 100, Life.Leech.Of(Damage).ConvertTo(EnergyShield.Leech.Of(Damage)) }, { "gain life from leech instantly", TotalOverride, 1, Life.Leech.IsInstant }, { "leech #% of damage as life", BaseAdd, Value, Life.Leech.Of(Damage) }, { "cannot leech mana", TotalOverride, 0, Mana.Leech.Of(Damage) }, // - block { "#% of block chance applied to spells", BaseAdd, Value.PercentOf(Block.AttackChance), Block.SpellChance }, // - other { "chaos damage does not bypass energy shield", TotalOverride, 100, Chaos.DamageTakenFrom(EnergyShield).Before(Life) }, { "#% of chaos damage does not bypass energy shield", BaseAdd, Value, Chaos.DamageTakenFrom(EnergyShield).Before(Life) }, { "#% of physical damage bypasses energy shield", BaseSubtract, Value, Physical.DamageTakenFrom(EnergyShield).Before(Life) }, { "you take #% reduced extra damage from critical strikes", PercentReduce, Value, CriticalStrike.ExtraDamageTaken }, { "you take no extra damage from critical strikes", PercentLess, 100, CriticalStrike.ExtraDamageTaken }, // regen and recharge // (need to be FormAndStatMatcher because they also exist with flat values) { "#%( of)? ({PoolStatMatchers}) regenerated per second", BaseAdd, Value, Reference.AsPoolStat.Regen.Percent }, { "#% of ({PoolStatMatchers}) and ({PoolStatMatchers}) regenerated per second", BaseAdd, Value, References[0].AsPoolStat.Regen.Percent, References[1].AsPoolStat.Regen.Percent }, { "regenerate #%( of)?( their| your)? ({PoolStatMatchers}) per second", BaseAdd, Value, Reference.AsPoolStat.Regen.Percent }, { "# ({PoolStatMatchers}) regenerated per second", BaseAdd, Value, Reference.AsPoolStat.Regen }, { "#% faster start of energy shield recharge", PercentIncrease, Value, EnergyShield.Recharge.Start }, { "life regeneration has no effect", PercentLess, 100, Life.Regen }, { "life regeneration is applied to energy shield instead", TotalOverride, (int)Pool.EnergyShield, Life.Regen.TargetPool }, // gain (need to be FormAndStatMatcher because they also exist with flat values) { "#% of ({PoolStatMatchers}) gained", BaseAdd, Value.PercentOf(Reference.AsStat), Reference.AsPoolStat.Gain }, { "recover #% of( their)? ({PoolStatMatchers})", BaseAdd, Value.PercentOf(Reference.AsStat), Reference.AsPoolStat.Gain }, { "removes #% of ({PoolStatMatchers})", BaseSubtract, Value.PercentOf(Reference.AsStat), Reference.AsPoolStat.Gain }, { @"\+# ({PoolStatMatchers}) gained", BaseAdd, Value, Reference.AsPoolStat.Gain }, { @"gain \+# ({PoolStatMatchers})", BaseAdd, Value, Reference.AsPoolStat.Gain }, { "replenishes energy shield by #% of armour", BaseAdd, Value.PercentOf(Armour), EnergyShield.Gain }, { "recover ({PoolStatMatchers}) equal to #% of your evasion rating", BaseAdd, Value.PercentOf(Evasion), Reference.AsPoolStat.Gain }, // charges { "#% chance to gain a power, frenzy or endurance charge", BaseAdd, Value / 3, Charge.Power.ChanceToGain, Charge.Frenzy.ChanceToGain, Charge.Endurance.ChanceToGain }, { "(?<!chance to |when you )gain an? ({ChargeTypeMatchers})", BaseAdd, 100, Reference.AsChargeType.ChanceToGain }, { "(?<!chance to |when you )gain a power or frenzy charge", BaseAdd, 50, Charge.Power.ChanceToGain, Charge.Frenzy.ChanceToGain }, // skills { "base duration is # seconds", BaseSet, Value, Stat.Duration }, { @"\+# seconds to base duration", BaseAdd, Value, Stat.Duration }, { "base secondary duration is # seconds", BaseSet, Value, Stat.SecondaryDuration }, { "#% increased duration(?! of)", PercentIncrease, Value, ApplyOnce(Stat.Duration, Stat.SecondaryDuration) }, { "#% reduced duration(?! of)", PercentReduce, Value, ApplyOnce(Stat.Duration, Stat.SecondaryDuration) }, { "skills cost no mana", TotalOverride, 0, Mana.Cost }, { "you can cast an additional brand", BaseAdd, 1, Skills[Keyword.Brand].CombinedInstances }, // traps, mines, totems { "trap lasts # seconds", BaseSet, Value, Stat.Trap.Duration }, { "mine lasts # seconds", BaseSet, Value, Stat.Mine.Duration }, { "totem lasts # seconds", BaseSet, Value, Stat.Totem.Duration }, { "detonating mines is instant", TotalOverride, 0, Stat.BaseCastTime, With(Skills.DetonateMines) }, // minions { "can summon up to # golem at a time", BaseSet, Value, Golems.CombinedInstances.Maximum }, // buffs { "(?<!while |chance to )you have ({BuffMatchers})", TotalOverride, 1, Reference.AsBuff.NotAsBuffOn(Self) }, { "(?<!while |chance to )gain ({BuffMatchers})", TotalOverride, 1, Reference.AsBuff.On(Self) }, { "you can have one additional curse", BaseAdd, 1, Buff.CurseLimit }, { "enemies can have # additional curse", BaseAdd, Value, Buff.CurseLimit.For(Enemy) }, { "you can apply an additional curse", BaseAdd, 1, Buff.CurseLimit.For(Enemy) }, { "unaffected by curses", PercentLess, 100, Buffs(targets: Self).With(Keyword.Curse).Effect }, { "unaffected by ({SkillMatchers})", PercentLess, 100, Reference.AsSkill.Buff.EffectOn(Self).For(Entity.Any) }, { "immun(e|ity) to curses", TotalOverride, 0, Buffs(targets: Self).With(Keyword.Curse).On }, { "monsters are hexproof", TotalOverride, 0, Buffs(Self, Enemy).With(Keyword.Curse).On, Flag.IgnoreHexproof.IsSet.Not }, { "grants? fortify", TotalOverride, 1, Buff.Fortify.On(Self) }, { "gain elemental conflux", TotalOverride, 1, Buff.Conflux.Elemental.On(Self) }, { "creates consecrated ground", TotalOverride, 1, Buff.Conflux.Elemental.On(Self) }, { "(?<!chance to )impale enemies", TotalOverride, 100, Buff.Impale.Chance }, { "({BuffMatchers}) lasts # seconds", BaseSet, Value, Reference.AsBuff.Duration }, { "supported auras do not affect you", TotalOverride, 0, Skills.ModifierSourceSkill.Buff.EffectOn(Self) }, { "totems cannot gain ({BuffMatchers})", TotalOverride, 0, Reference.AsBuff.On(Entity.Totem) }, // flags // ailments { "causes bleeding", TotalOverride, 100, Ailment.Bleed.Chance }, { "bleed is applied", TotalOverride, 100, Ailment.Bleed.Chance }, { "always poison", TotalOverride, 100, Ailment.Poison.Chance }, { "always ({AilmentMatchers}) enemies", TotalOverride, 100, Reference.AsAilment.Chance }, { "cannot cause bleeding", TotalOverride, 0, Ailment.Bleed.Chance }, { "cannot ignite", TotalOverride, 0, Ailment.Ignite.Chance }, { "cannot (apply|inflict) shock", TotalOverride, 0, Ailment.Shock.Chance }, { "cannot inflict elemental ailments", TotalOverride, 0, Ailment.Elemental.Select(s => s.Chance) }, { "(you )?can afflict an additional ignite on an enemy", BaseAdd, 1, Ailment.Ignite.InstancesOn(Enemy).Maximum }, { "(you are )?immune to ({AilmentMatchers})", TotalOverride, 100, Reference.AsAilment.Avoidance }, { "cannot be ({AilmentMatchers})", TotalOverride, 100, Reference.AsAilment.Avoidance }, { "cannot be ({AilmentMatchers}) or ({AilmentMatchers})", TotalOverride, 100, References[0].AsAilment.Avoidance, References[1].AsAilment.Avoidance }, { "(immune to|cannot be affected by|immunity to) elemental ailments", TotalOverride, 100, Ailment.Elemental.Select(a => a.Avoidance) }, { "poison you inflict with critical strikes deals #% more damage", PercentMore, Value, CriticalStrike.Multiplier.With(Ailment.Poison) }, // stun { "(you )?cannot be stunned", TotalOverride, 100, Effect.Stun.Avoidance }, { "additional #% chance to be stunned", BaseAdd, Value, Effect.Stun.Chance.For(Entity.OpponentOfSelf) }, // item quantity/quality // range and area of effect // other { "knocks back enemies", TotalOverride, 100, Effect.Knockback.Chance }, { "knocks enemies back", TotalOverride, 100, Effect.Knockback.Chance }, { "knockback(?! distance)", TotalOverride, 100, Effect.Knockback.Chance }, };
public static Object GetNominalDatumValue(DatumType datum) { Object value = null; if (datum is binary) value = ((binary)datum).value; else if (datum is boolean) value = ((boolean)datum).value; else if (datum is dateTime) value = ((dateTime)datum).value; else if (datum is @double || datum is integer || datum is @long || datum is unsignedInteger || datum is unsignedLong ) { Physical physical = new Physical(datum.ToString()); value = physical.Magnitude.AnyQuantity.NominalValue; } else if (datum is hexadecimal) value = ((hexadecimal)datum).value; else if (datum is octal) value = ((octal)datum).value; else if (datum is @string) value = ((@string)datum).Value; return value; }
public Stream CreateReadStream() => Physical.CreateReadStream();