public static void TestFunctions(MathFunctions operation)
        {
            Stopwatch sw = Stopwatch.StartNew();

            float floatResult = floatOperationValue;
            sw.Start();

            for (int i = 0; i < 1000000; i++)
            {
                switch (operation)
                {
                    case MathFunctions.Sqrt: floatResult = (float)Math.Sqrt(floatOperationValue); break;
                    case MathFunctions.Log: floatResult = (float)Math.Log(floatOperationValue); break;
                    case MathFunctions.Sin: floatResult = (float)Math.Sin(floatOperationValue); break;
                }
            }

            sw.Stop();
            Console.WriteLine("{0}  float", sw.Elapsed);
            sw.Reset();

            double doubleResult = doubleOperationValue;
            sw.Start();

            for (int i = 0; i < 1000000; i++)
            {
                switch (operation)
                {
                    case MathFunctions.Sqrt: doubleResult = Math.Sqrt(doubleOperationValue); break;
                    case MathFunctions.Log: doubleResult = Math.Log(doubleOperationValue); break;
                    case MathFunctions.Sin: doubleResult = Math.Sin(doubleOperationValue); break;
                }
            }

            sw.Stop();
            Console.WriteLine("{0}  double", sw.Elapsed);
            sw.Reset();

            decimal decimalResult = decimalOperationValue;
            sw.Start();

            for (int i = 0; i < 1000000; i++)
            {
                switch (operation)
                {
                    case MathFunctions.Sqrt: decimalResult = (decimal)Math.Sqrt((double)decimalOperationValue); break;
                    case MathFunctions.Log: decimalResult = (decimal)Math.Log((double)decimalOperationValue); break;
                    case MathFunctions.Sin: decimalResult = (decimal)Math.Sin((double)decimalOperationValue); break;
                }
            }

            sw.Stop();
            Console.WriteLine("{0}  decimal", sw.Elapsed);
            sw.Reset();
        }
예제 #2
0
        private void TickIntellect()
        {
            ShiftBooster();

            HelliOn = Intellect != null && Intellect.IsActive();
            // GUItest();

            //finding motors
            GearedMotor main = PhysicsModel.GetMotor("hellimain") as GearedMotor;
            GearedMotor back = PhysicsModel.GetMotor("helliback") as GearedMotor;

            if (HelliOn)
            {
                main.Enabled = true;
                back.Enabled = true;
            }

            //engine force + sound pitch control

            if (Intellect.IsControlKeyPressed(GameControlKeys.Forward))
            {
                force   += forceadd;
                enpitch += 0.02f;
            }
            else if (Intellect.IsControlKeyPressed(GameControlKeys.Backward))
            {
                dec      = true;
                force   -= forceadd;
                enpitch -= 0.02f;
            }
            else
            {
                dec      = false;
                enpitch -= 0.01f;
                if (force > 50)
                {
                    force -= forceadd;
                }
                if (force < 50)
                {
                    force += forceadd;
                }
            }

            MathFunctions.Clamp(ref force, 0.1f, 100 + Type.MaxForce);
            MathFunctions.Clamp(ref enpitch, 0.8f, 1.3f);

            //update helli channel position and pitch
            if (rotorSoundChannel != null)
            {
                //update channel
                rotorSoundChannel.Pitch    = enpitch;
                rotorSoundChannel.Volume   = 1;
                rotorSoundChannel.Position = Position;
                //rotorSoundChannel.MinDistance = 10;
            }

            //end of engine force + sound pitch control

            //Forces
            ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

            //start helli Pitch
            if (Intellect.IsControlKeyPressed(GameControlKeys.Arrow_Up) || Intellect.IsControlKeyPressed(GameControlKeys.Arrow_Down))
            {
                float AUp   = Intellect.GetControlKeyStrength(GameControlKeys.Arrow_Up) / 2;
                float ADown = Intellect.GetControlKeyStrength(GameControlKeys.Arrow_Down) / 2;
                Hpitch += (AUp - ADown);
                MathFunctions.Clamp(ref Hpitch, -10, 10);

                HelliBody.AddForce(ForceType.GlobalAtLocalPos, TickDelta,
                                   HelliBody.Rotation * new Vec3(0, 0, Hpitch / 2) * HelliBody.Mass, new Vec3(-2, 0, 0));
            }
            else
            {
                Hpitch = 0;
            }
            //end of helli pitch

            //start helli Z turn
            if (Intellect.IsControlKeyPressed(GameControlKeys.Right) || Intellect.IsControlKeyPressed(GameControlKeys.Left))
            {
                float right = Intellect.GetControlKeyStrength(GameControlKeys.Right) / 2;
                float left  = Intellect.GetControlKeyStrength(GameControlKeys.Left) / 2;
                TrunZ += (left - right);
                MathFunctions.Clamp(ref TrunZ, -10, 10);

                HelliBody.AddForce(ForceType.GlobalTorque, TickDelta,
                                   HelliBody.Rotation * new Vec3(0, 0, TrunZ) * HelliBody.Mass, Vec3.Zero);
            }
            else
            {
                TrunZ = 0;
            }

            //end of helli Z turn

            //start helli X turn
            if (Intellect.IsControlKeyPressed(GameControlKeys.Arrow_Right) || Intellect.IsControlKeyPressed(GameControlKeys.Arrow_Left))
            {
                float rightX = Intellect.GetControlKeyStrength(GameControlKeys.Arrow_Right) / 2;
                float leftX  = Intellect.GetControlKeyStrength(GameControlKeys.Arrow_Left) / 2;
                TrunX += (rightX - leftX);
                MathFunctions.Clamp(ref TrunX, -10, 10);

                HelliBody.AddForce(ForceType.GlobalTorque, TickDelta,
                                   HelliBody.Rotation * new Vec3(TrunX / 5, 0, 0) * HelliBody.Mass, Vec3.Zero);
            }
            else
            {
                TrunX = 0;
            }
            //end of helli X turn

            //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

            //start of adding force

            MathFunctions.Clamp(ref force, 0.1f, 100);

            //anti gravity when helli is not decending
            if (dec == false)
            {
                HelliBody.AddForce(ForceType.GlobalAtLocalPos, TickDelta,
                                   new Vec3(0, 0, 2) * HelliBody.Mass, Vec3.Zero);
            }

            //if Max Alt is not reached add helli motor force
            if (GetRealAlt() < Type.MaxAlt)
            {
                HelliBody.AddForce(ForceType.GlobalAtLocalPos, TickDelta,
                                   HelliBody.Rotation * 2 * new Vec3(0, 0, force / 7) * HelliBody.Mass, Vec3.Zero);
            }

            //dampings
            HelliBody.AngularDamping = 1.5f;
            HelliBody.LinearDamping  = 0.4f;

            //another anti gravity force
            if (HelliBody.LinearVelocity.Z < 0)
            {
                HelliBody.AddForce(ForceType.GlobalAtLocalPos, TickDelta,
                                   HelliBody.Rotation * new Vec3(0, 0, -HelliBody.LinearVelocity.Z) * HelliBody.Mass, Vec3.Zero);
            }
        }
예제 #3
0
        public override bool UpdateStats(Stats stat)
        {
            float value = GetTotalStatValue(stat);

            UpdateStatBuffMod(stat);
            float ownersBonus = 0.0f;

            Unit owner = GetOwner();
            // Handle Death Knight Glyphs and Talents
            float mod = 0.75f;

            if (IsPetGhoul() && (stat == Stats.Stamina || stat == Stats.Strength))
            {
                switch (stat)
                {
                case Stats.Stamina:
                    mod = 0.3f;
                    break;                    // Default Owner's Stamina scale

                case Stats.Strength:
                    mod = 0.7f;
                    break;                    // Default Owner's Strength scale

                default: break;
                }

                ownersBonus = owner.GetStat(stat) * mod;
                value      += ownersBonus;
            }
            else if (stat == Stats.Stamina)
            {
                ownersBonus = MathFunctions.CalculatePct(owner.GetStat(Stats.Stamina), 30);
                value      += ownersBonus;
            }
            //warlock's and mage's pets gain 30% of owner's intellect
            else if (stat == Stats.Intellect)
            {
                if (owner.GetClass() == Class.Warlock || owner.GetClass() == Class.Mage)
                {
                    ownersBonus = MathFunctions.CalculatePct(owner.GetStat(stat), 30);
                    value      += ownersBonus;
                }
            }

            SetStat(stat, (int)value);
            m_statFromOwner[(int)stat] = ownersBonus;
            UpdateStatBuffMod(stat);

            switch (stat)
            {
            case Stats.Strength:
                UpdateAttackPowerAndDamage();
                break;

            case Stats.Agility:
                UpdateArmor();
                break;

            case Stats.Stamina:
                UpdateMaxHealth();
                break;

            case Stats.Intellect:
                UpdateMaxPower(PowerType.Mana);
                break;

            default:
                break;
            }

            return(true);
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="FloatUnaryFunction"/> class.
 /// </summary>
 /// <param name="f">
 /// A function delegate that takes a float value as a parameter and returns a float value.
 /// </param>
 public FloatUnaryFunction(MathFunctions.FloatUnaryFunction f)
 {
     _function = f;
     _differentiator = null;
     _integrator = null;
 }
        protected override void OnMaterialRender(uint passId, Material material, ref bool skipPass)
        {
            base.OnMaterialRender(passId, material, ref skipPass);

            Camera camera = Owner.ViewportCamera;

            Sun  sun = null;
            Vec2 screenLightPosition = Vec2.Zero;

            if (Map.Instance != null && Map.Instance.IsPostCreated && Sun.Instances.Count > 0)
            {
                //get first sun entity on the map.
                sun = Sun.Instances[0];

                Vec3 direction;
                if (sun.BillboardOverridePosition != Vec3.Zero)
                {
                    direction = sun.BillboardOverridePosition.GetNormalize();
                }
                else
                {
                    direction = -sun.Rotation.GetForward();
                }

                Vec3 sunPosition = camera.Position + direction * 100000;

                if (!camera.ProjectToScreenCoordinates(sunPosition, out screenLightPosition))
                {
                    //don't see the sun.
                    sun = null;
                }
            }

            //calculate intensity factor by the sun position on the screen.
            float needIntensityFactor = 0;

            if (sun != null)
            {
                const float screenFadingBorder = .1f;

                float minDistance = 1;

                for (int axis = 0; axis < 2; axis++)
                {
                    if (screenLightPosition[axis] < screenFadingBorder)
                    {
                        float d = screenLightPosition[axis];
                        if (d < minDistance)
                        {
                            minDistance = d;
                        }
                    }
                    else if (screenLightPosition[axis] > 1.0f - screenFadingBorder)
                    {
                        float d = 1.0f - screenLightPosition[axis];
                        if (d < minDistance)
                        {
                            minDistance = d;
                        }
                    }
                }
                needIntensityFactor = minDistance / screenFadingBorder;
                MathFunctions.Saturate(ref needIntensityFactor);

                //clamp screenLightPosition
                if (!new Rect(0, 0, 1, 1).IsContainsPoint(screenLightPosition))
                {
                    Vec2 intersectPoint1;
                    Vec2 intersectPoint2;
                    if (MathUtils.IntersectRectangleLine(new Rect(.0001f, .0001f, .9999f, .9999f),
                                                         new Vec2(.5f, .5f), screenLightPosition, out intersectPoint1, out intersectPoint2) != 0)
                    {
                        screenLightPosition = intersectPoint1;
                    }
                }
            }

            //update smooth intensity factor
            if (sun != null)
            {
                if (smoothIntensityFactorLastUpdate != RendererWorld.Instance.FrameRenderTime)
                {
                    smoothIntensityFactorLastUpdate = RendererWorld.Instance.FrameRenderTime;

                    const float smoothSpeed = 3;
                    float       step        = RendererWorld.Instance.FrameRenderTimeStep * smoothSpeed;

                    if (needIntensityFactor > smoothIntensityFactor)
                    {
                        smoothIntensityFactor += step;
                        if (smoothIntensityFactor > needIntensityFactor)
                        {
                            smoothIntensityFactor = needIntensityFactor;
                        }
                    }
                    else
                    {
                        smoothIntensityFactor -= step;
                        if (smoothIntensityFactor < needIntensityFactor)
                        {
                            smoothIntensityFactor = needIntensityFactor;
                        }
                    }
                }
            }
            else
            {
                smoothIntensityFactor = 0;
            }

            //get result intensity
            float resultIntensity = intensity * smoothIntensityFactor;

            const int rt_scattering = 100;
            const int rt_blur       = 200;
            const int rt_final      = 300;

            //skip passes for disabled effect
            if (resultIntensity == 0)
            {
                if (passId == rt_scattering || passId == rt_blur)
                {
                    skipPass = true;
                    return;
                }
            }

            //set gpu parameters

            switch (passId)
            {
            case rt_scattering:
            {
                GpuProgramParameters parameters = material.Techniques[0].Passes[0].
                                                  FragmentProgramParameters;
                parameters.SetNamedConstant("color", new Vec4(color.Red, color.Green, color.Blue, 0));
                parameters.SetNamedConstant("screenLightPosition",
                                            new Vec4(screenLightPosition.X, screenLightPosition.Y, 0, 0));
                parameters.SetNamedConstant("decay", decay);
                parameters.SetNamedConstant("density", density);
            }
            break;

            case rt_blur:
            {
                GpuProgramParameters parameters = material.Techniques[0].Passes[0].
                                                  FragmentProgramParameters;
                parameters.SetNamedConstant("color", new Vec4(color.Red, color.Green, color.Blue, 0));
                parameters.SetNamedConstant("screenLightPosition",
                                            new Vec4(screenLightPosition.X, screenLightPosition.Y, 0, 0));
                parameters.SetNamedConstant("intensity", resultIntensity);
                parameters.SetNamedConstant("blurFactor", blurFactor);
            }
            break;

            case rt_final:
            {
                GpuProgramParameters parameters = material.Techniques[0].Passes[0].
                                                  FragmentProgramParameters;
                parameters.SetNamedConstant("intensity", resultIntensity);
            }
            break;
            }
        }
예제 #6
0
        void DoEffect()
        {
            float radius    = Type.Radius;
            float radiusInv = 1.0f / radius;

            List <MapObject>  objects     = mapObjectListAllocator.Alloc();
            List <DamageItem> damageItems = damageItemListAllocator.Alloc();

            //generate objects list
            Map.Instance.GetObjects(new Sphere(Position, radius), delegate(MapObject obj)
            {
                if (Type.IgnoreReasonObject && obj == ReasonObject)
                {
                    return;
                }
                objects.Add(obj);
            });

            //enumerate objects
            foreach (MapObject obj in objects)
            {
                if (obj.IsSetDeleted)
                {
                    continue;
                }
                if (!obj.Visible)
                {
                    continue;
                }

                PhysicsModel objPhysicsModel = obj.PhysicsModel;

                float totalObjImpulse = 0;
                float totalObjDamage  = 0;

                if (Type.Impulse != 0 && objPhysicsModel != null)
                {
                    float bodyCountInv = 1.0f / objPhysicsModel.Bodies.Length;

                    foreach (Body body in objPhysicsModel.Bodies)
                    {
                        if (body.Static)
                        {
                            continue;
                        }

                        Vec3  dir      = body.Position - Position;
                        float distance = dir.NormalizeFast();

                        if (distance < radius)
                        {
                            float objImpulse = MathFunctions.Cos((distance * radiusInv) *
                                                                 (MathFunctions.PI / 2)) * Type.Impulse * DamageCoefficient;
                            objImpulse *= bodyCountInv;

                            //forcePos for torque
                            Vec3 forcePos;
                            {
                                Vec3         gabarites = body.GetGlobalBounds().GetSize() * .05f;
                                EngineRandom random    = World.Instance.Random;
                                forcePos = new Vec3(
                                    random.NextFloatCenter() * gabarites.X,
                                    random.NextFloatCenter() * gabarites.Y,
                                    random.NextFloatCenter() * gabarites.Z);
                            }
                            body.AddForce(ForceType.GlobalAtLocalPos, 0, dir * objImpulse, forcePos);

                            totalObjImpulse += objImpulse;
                        }
                    }
                }

                if (Type.Damage != 0)
                {
                    Dynamic dynamic = obj as Dynamic;
                    if (dynamic != null)
                    {
                        //!!!!!!not true. damage calculated by center
                        float distance = (dynamic.Position - Position).LengthFast();
                        if (distance < radius)
                        {
                            float objDamage = MathFunctions.Cos((distance * radiusInv) *
                                                                (MathFunctions.PI / 2)) * Type.Damage * DamageCoefficient;

                            //add damages to cache and apply after influences (for correct influences work)
                            damageItems.Add(new DamageItem(dynamic, obj.Position, objDamage));
                            //dynamic.DoDamage( dynamic, obj.Position, objDamage, false );

                            totalObjDamage += objDamage;
                        }
                    }
                }

                //PlayerCharacter contusion
                if (totalObjDamage > 10 && totalObjImpulse > 500)
                {
                    PlayerCharacter playerCharacter = obj as PlayerCharacter;
                    if (playerCharacter != null)
                    {
                        playerCharacter.ContusionTimeRemaining += totalObjDamage * .05f;
                    }
                }

                //Influence
                if (Type.InfluenceType != null && (totalObjDamage != 0 || totalObjImpulse != 0))
                {
                    Dynamic dynamic = obj as Dynamic;
                    if (dynamic != null)
                    {
                        float coef = 0;
                        if (Type.Damage != 0)
                        {
                            coef = totalObjDamage / Type.Damage;
                        }
                        if (Type.Impulse != 0)
                        {
                            coef = Math.Max(coef, totalObjImpulse / Type.Impulse);
                        }

                        if (coef > 1)
                        {
                            coef = 1;
                        }
                        if (coef != 0)
                        {
                            dynamic.AddInfluence(Type.InfluenceType, Type.InfluenceMaxTime * coef, true);
                        }
                    }
                }
            }

            //Create splash for water
            CreateWaterPlaneSplash();

            //Apply damages
            foreach (DamageItem item in damageItems)
            {
                if (!item.dynamic.IsSetDeleted)
                {
                    item.dynamic.DoDamage(this, item.position, null, item.damage, false);
                }
            }

            mapObjectListAllocator.Free(objects);
            damageItemListAllocator.Free(damageItems);
        }
        /// <summary>
        /// Integrates a given function within the given integral.
        /// </summary>
        /// <param name="f">The function to integrate.</param>
        /// <param name="a">The lower limit.</param>
        /// <param name="b">The higher limit.</param>
        /// <returns>
        /// The integral of <paramref name="function"/> over the interval from <paramref name="a"/> to <paramref name="b"/>
        /// </returns>
        public float Integrate(MathFunctions.FloatUnaryFunction f, float a, float b)
        {
            if (a > b)  return -Integrate(f, b, a);

            float sum = 0;
            float stepSize = (float)((b-a)/_stepsNumber);
            float stepSizeDiv3 = stepSize/3.0f;
            for (int i = 0; i < _stepsNumber; i = i+2)
            {
                sum += (f(a + i*stepSize) + 4.0f*f(a+(i+1)*stepSize) + f(a+(i+2)*stepSize))*stepSizeDiv3;
            }

            return sum;
        }
예제 #8
0
		private double defaultIteration(MathFunctions.UnaryFunction<double> f, double a, double b, double estimate, int n)
		{
			double sum = 0;
			double stepSize = (b - a) / n;
			double x = a + (stepSize / 2);

			for (int i = 0; i < n; i++, x += stepSize)
				sum += f(x);

			return (estimate + (stepSize * sum)) / 2;
		}
예제 #9
0
 // Use this on startup when initializing reset times
 void InitializeResetTimeFor(uint mapid, Difficulty d, long t)
 {
     m_resetTimeByMapDifficulty[MathFunctions.MakePair64(mapid, (uint)d)] = t;
 }
예제 #10
0
 public long GetResetTimeFor(uint mapid, Difficulty d)
 {
     return(m_resetTimeByMapDifficulty.LookupByKey(MathFunctions.MakePair64(mapid, (uint)d)));
 }
예제 #11
0
        void LoadResetTimes()
        {
            long now   = Time.UnixTime;
            long today = (now / Time.Day) * Time.Day;

            // NOTE: Use DirectPExecute for tables that will be queried later

            // get the current reset times for normal instances (these may need to be updated)
            // these are only kept in memory for InstanceSaves that are loaded later
            // resettime = 0 in the DB for raid/heroic instances so those are skipped
            Dictionary <uint, Tuple <uint, long> > instResetTime = new Dictionary <uint, Tuple <uint, long> >();

            // index instance ids by map/difficulty pairs for fast reset warning send
            MultiMap <uint, uint> mapDiffResetInstances = new MultiMap <uint, uint>();

            SQLResult result = DB.Characters.Query("SELECT id, map, difficulty, resettime FROM instance ORDER BY id ASC");

            if (!result.IsEmpty())
            {
                do
                {
                    uint instanceId = result.Read <uint>(0);

                    // Instances are pulled in ascending order from db and nextInstanceId is initialized with 1,
                    // so if the instance id is used, increment until we find the first unused one for a potential new instance
                    if (Global.MapMgr.GetNextInstanceId() == instanceId)
                    {
                        Global.MapMgr.SetNextInstanceId(instanceId + 1);
                    }

                    // Mark instance id as being used
                    Global.MapMgr.RegisterInstanceId(instanceId);
                    long resettime = result.Read <uint>(3);
                    if (resettime != 0)
                    {
                        uint mapid      = result.Read <ushort>(1);
                        uint difficulty = result.Read <byte>(2);

                        instResetTime[instanceId] = Tuple.Create(MathFunctions.MakePair32(mapid, difficulty), resettime);
                        mapDiffResetInstances.Add(MathFunctions.MakePair32(mapid, difficulty), instanceId);
                    }
                }while (result.NextRow());

                // update reset time for normal instances with the max creature respawn time + X hours
                SQLResult result2 = DB.Characters.Query(DB.Characters.GetPreparedStatement(CharStatements.SEL_MAX_CREATURE_RESPAWNS));
                if (!result2.IsEmpty())
                {
                    do
                    {
                        uint instance  = result2.Read <uint>(1);
                        long resettime = result2.Read <uint>(0) + 2 * Time.Hour;
                        var  pair      = instResetTime.LookupByKey(instance);
                        if (pair != null && pair.Item2 != resettime)
                        {
                            DB.Characters.DirectExecute("UPDATE instance SET resettime = '{0}' WHERE id = '{1}'", resettime, instance);
                            instResetTime[instance] = Tuple.Create(pair.Item1, resettime);
                        }
                    }while (result2.NextRow());
                }

                // schedule the reset times
                foreach (var pair in instResetTime)
                {
                    if (pair.Value.Item2 > now)
                    {
                        ScheduleReset(true, pair.Value.Item2, new InstResetEvent(0, MathFunctions.Pair32_LoPart(pair.Value.Item1), (Difficulty)MathFunctions.Pair32_HiPart(pair.Value.Item1), pair.Key));
                    }
                }
            }

            // load the global respawn times for raid/heroic instances
            uint diff = (uint)(WorldConfig.GetIntValue(WorldCfg.InstanceResetTimeHour) * Time.Hour);

            result = DB.Characters.Query("SELECT mapid, difficulty, resettime FROM instance_reset");
            if (!result.IsEmpty())
            {
                do
                {
                    uint       mapid        = result.Read <ushort>(0);
                    Difficulty difficulty   = (Difficulty)result.Read <byte>(1);
                    ulong      oldresettime = result.Read <uint>(2);

                    MapDifficultyRecord mapDiff = Global.DB2Mgr.GetMapDifficultyData(mapid, difficulty);
                    if (mapDiff == null)
                    {
                        Log.outError(LogFilter.Server, "InstanceSaveManager.LoadResetTimes: invalid mapid({0})/difficulty({1}) pair in instance_reset!", mapid, difficulty);
                        DB.Characters.DirectExecute("DELETE FROM instance_reset WHERE mapid = '{0}' AND difficulty = '{1}'", mapid, difficulty);
                        continue;
                    }

                    // update the reset time if the hour in the configs changes
                    ulong newresettime = (oldresettime / Time.Day) * Time.Day + diff;
                    if (oldresettime != newresettime)
                    {
                        DB.Characters.DirectExecute("UPDATE instance_reset SET resettime = '{0}' WHERE mapid = '{1}' AND difficulty = '{2}'", newresettime, mapid, difficulty);
                    }

                    InitializeResetTimeFor(mapid, difficulty, (long)newresettime);
                } while (result.NextRow());
            }

            // calculate new global reset times for expired instances and those that have never been reset yet
            // add the global reset times to the priority queue
            foreach (var mapDifficultyPair in Global.DB2Mgr.GetMapDifficulties())
            {
                uint mapid = mapDifficultyPair.Key;

                foreach (var difficultyPair in mapDifficultyPair.Value)
                {
                    Difficulty          difficulty = (Difficulty)difficultyPair.Key;
                    MapDifficultyRecord mapDiff    = difficultyPair.Value;
                    if (mapDiff.GetRaidDuration() == 0)
                    {
                        continue;
                    }

                    // the reset_delay must be at least one day
                    uint period = (uint)(((mapDiff.GetRaidDuration() * WorldConfig.GetFloatValue(WorldCfg.RateInstanceResetTime)) / Time.Day) * Time.Day);
                    if (period < Time.Day)
                    {
                        period = Time.Day;
                    }

                    long t = GetResetTimeFor(mapid, difficulty);
                    if (t == 0)
                    {
                        // initialize the reset time
                        t = today + period + diff;
                        DB.Characters.DirectExecute("INSERT INTO instance_reset VALUES ('{0}', '{1}', '{2}')", mapid, (uint)difficulty, (uint)t);
                    }

                    if (t < now)
                    {
                        // assume that expired instances have already been cleaned
                        // calculate the next reset time
                        t  = (t / Time.Day) * Time.Day;
                        t += ((today - t) / period + 1) * period + diff;
                        DB.Characters.DirectExecute("UPDATE instance_reset SET resettime = '{0}' WHERE mapid = '{1}' AND difficulty= '{2}'", t, mapid, (uint)difficulty);
                    }

                    InitializeResetTimeFor(mapid, difficulty, t);

                    // schedule the global reset/warning
                    byte type;
                    for (type = 1; type < 4; ++type)
                    {
                        if (t - ResetTimeDelay[type - 1] > now)
                        {
                            break;
                        }
                    }

                    ScheduleReset(true, t - ResetTimeDelay[type - 1], new InstResetEvent(type, mapid, difficulty, 0));

                    var range = mapDiffResetInstances.LookupByKey(MathFunctions.MakePair32(mapid, (uint)difficulty));
                    foreach (var id in range)
                    {
                        ScheduleReset(true, t - ResetTimeDelay[type - 1], new InstResetEvent(type, mapid, difficulty, id));
                    }
                }
            }
        }
예제 #12
0
        public void Initialize()
        {
            foreach (GarrSiteLevelPlotInstRecord siteLevelPlotInst in CliDB.GarrSiteLevelPlotInstStorage.Values)
            {
                _garrisonPlotInstBySiteLevel.Add(siteLevelPlotInst.GarrSiteLevelID, siteLevelPlotInst);
            }

            foreach (GameObjectsRecord gameObject in CliDB.GameObjectsStorage.Values)
            {
                if (gameObject.TypeID == GameObjectTypes.GarrisonPlot)
                {
                    if (!_garrisonPlots.ContainsKey(gameObject.OwnerID))
                    {
                        _garrisonPlots[gameObject.OwnerID] = new Dictionary <uint, GameObjectsRecord>();
                    }

                    _garrisonPlots[gameObject.OwnerID][(uint)gameObject.PropValue[0]] = gameObject;
                }
            }

            foreach (GarrPlotBuildingRecord plotBuilding in CliDB.GarrPlotBuildingStorage.Values)
            {
                _garrisonBuildingsByPlot.Add(plotBuilding.GarrPlotID, plotBuilding.GarrBuildingID);
            }

            foreach (GarrBuildingPlotInstRecord buildingPlotInst in CliDB.GarrBuildingPlotInstStorage.Values)
            {
                _garrisonBuildingPlotInstances[MathFunctions.MakePair64(buildingPlotInst.GarrBuildingID, buildingPlotInst.GarrSiteLevelPlotInstID)] = buildingPlotInst.Id;
            }

            foreach (GarrBuildingRecord building in CliDB.GarrBuildingStorage.Values)
            {
                _garrisonBuildingsByType.Add(building.BuildingType, building.Id);
            }

            for (var i = 0; i < 2; ++i)
            {
                _garrisonFollowerAbilities[i] = new Dictionary <uint, GarrAbilities>();
            }

            foreach (GarrFollowerXAbilityRecord followerAbility in CliDB.GarrFollowerXAbilityStorage.Values)
            {
                GarrAbilityRecord ability = CliDB.GarrAbilityStorage.LookupByKey(followerAbility.GarrAbilityID);
                if (ability != null)
                {
                    if (ability.GarrFollowerTypeID != (uint)GarrisonFollowerType.Garrison)
                    {
                        continue;
                    }

                    if (!ability.Flags.HasAnyFlag(GarrisonAbilityFlags.CannotRoll) && ability.Flags.HasAnyFlag(GarrisonAbilityFlags.Trait))
                    {
                        _garrisonFollowerRandomTraits.Add(ability);
                    }

                    if (followerAbility.FactionIndex < 2)
                    {
                        var dic = _garrisonFollowerAbilities[followerAbility.FactionIndex];

                        if (!dic.ContainsKey(followerAbility.GarrFollowerID))
                        {
                            dic[followerAbility.GarrFollowerID] = new GarrAbilities();
                        }

                        if (ability.Flags.HasAnyFlag(GarrisonAbilityFlags.Trait))
                        {
                            dic[followerAbility.GarrFollowerID].Traits.Add(ability);
                        }
                        else
                        {
                            dic[followerAbility.GarrFollowerID].Counters.Add(ability);
                        }
                    }
                }
            }

            InitializeDbIdSequences();
            LoadPlotFinalizeGOInfo();
            LoadFollowerClassSpecAbilities();
        }
예제 #13
0
 public uint GetGarrBuildingPlotInst(uint garrBuildingId, uint garrSiteLevelPlotInstId)
 {
     return(_garrisonBuildingPlotInstances.LookupByKey(MathFunctions.MakePair64(garrBuildingId, garrSiteLevelPlotInstId)));
 }
예제 #14
0
        public uint GetAuctionCut()
        {
            int cut = (int)(MathFunctions.CalculatePct(bid, auctionHouseEntry.ConsignmentRate) * WorldConfig.GetFloatValue(WorldCfg.RateAuctionCut));

            return((uint)Math.Max(cut, 0));
        }
예제 #15
0
        private void EqualizeColumns()
        {
            if (Envoy.TraderFaction.ParentFaction.IsCorporate)
            {
                return;
            }

            if (EnvoyColumns.Valid && PlayerColumns.Valid)
            {
                var net         = ComputeNetValue();
                var envoyOut    = Envoy.ComputeValue(EnvoyColumns.SelectedResources.SelectMany(i => i.Resources).ToList()) + EnvoyColumns.TradeMoney;
                var tradeTarget = 1.0m;

                if (IsReasonableTrade(envoyOut, net))
                {
                    Root.ShowTooltip(Root.MousePosition, "This works fine.");
                    return;
                }

                var      sourceResourcesEnvoy    = EnvoyColumns.SourceResources;
                var      selectedResourcesEnvoy  = EnvoyColumns.SelectedResources;
                DwarfBux selectedMoneyEnvoy      = EnvoyColumns.TradeMoney;
                DwarfBux remainingMoneyEnvoy     = Envoy.Money - selectedMoneyEnvoy;
                var      sourceResourcesPlayer   = PlayerColumns.SourceResources;
                var      selectedResourcesPlayer = PlayerColumns.SelectedResources;
                DwarfBux selectedMoneyPlayer     = PlayerColumns.TradeMoney;
                DwarfBux remainingMoneyPlayer    = Player.Money - selectedMoneyPlayer;

                int maxIters = 1000;
                int iter     = 0;
                while (!IsReasonableTrade(envoyOut, net) && iter < maxIters)
                {
                    float t = MathFunctions.Rand();
                    if (envoyOut > net)
                    {
                        if (t < 0.05f && selectedMoneyEnvoy > 1)
                        {
                            DwarfBux movement = Math.Min((decimal)MathFunctions.RandInt(1, 5), selectedMoneyEnvoy);
                            selectedMoneyEnvoy  -= movement;
                            remainingMoneyEnvoy += movement;
                        }
                        else if (t < 0.1f)
                        {
                            MoveRandomValue(selectedResourcesEnvoy, sourceResourcesEnvoy, Player);
                        }
                        else if (t < 0.15f && remainingMoneyPlayer > 1)
                        {
                            DwarfBux movement = Math.Min((decimal)MathFunctions.RandInt(1, Math.Max((int)(envoyOut - net), 2)), remainingMoneyPlayer);
                            selectedMoneyPlayer  += movement;
                            remainingMoneyPlayer -= movement;
                        }
                        else
                        {
                            MoveRandomValue(sourceResourcesPlayer, selectedResourcesPlayer, Envoy);
                        }
                    }
                    else
                    {
                        if (t < 0.05f && selectedMoneyPlayer > 1)
                        {
                            DwarfBux movement = Math.Min((decimal)MathFunctions.RandInt(1, 5), selectedMoneyPlayer);
                            selectedMoneyPlayer  -= movement;
                            remainingMoneyPlayer += movement;
                        }
                        else if (t < 0.1f)
                        {
                            MoveRandomValue(selectedResourcesPlayer, sourceResourcesPlayer, Envoy);
                        }
                        else if (t < 0.15f && remainingMoneyEnvoy > 1)
                        {
                            DwarfBux movement = Math.Min((decimal)MathFunctions.RandInt(1, Math.Max((int)(net - envoyOut), 2)), remainingMoneyEnvoy);
                            selectedMoneyEnvoy  += movement;
                            remainingMoneyEnvoy -= movement;
                        }
                        else
                        {
                            MoveRandomValue(selectedResourcesEnvoy, sourceResourcesEnvoy, Player);
                        }
                    }
                    envoyOut    = Envoy.ComputeValue(selectedResourcesEnvoy.SelectMany(i => i.Resources).ToList()) + selectedMoneyEnvoy;
                    tradeTarget = envoyOut * 0.25;
                    net         = ComputeNetValue(selectedResourcesPlayer.SelectMany(i => i.Resources).ToList(), selectedMoneyPlayer, selectedResourcesEnvoy.SelectMany(i => i.Resources).ToList(),
                                                  selectedMoneyEnvoy);
                }

                if (IsReasonableTrade(envoyOut, net))
                {
                    Root.ShowTooltip(Root.MousePosition, "How does this work?");
                    PlayerColumns.Reconstruct(sourceResourcesPlayer, selectedResourcesPlayer, (int)selectedMoneyPlayer);
                    PlayerColumns.TradeMoney = (int)selectedMoneyPlayer;
                    EnvoyColumns.Reconstruct(sourceResourcesEnvoy, selectedResourcesEnvoy, (int)selectedMoneyEnvoy);
                    EnvoyColumns.TradeMoney = (int)selectedMoneyEnvoy;
                    Layout();
                    return;
                }
                else
                {
                    Root.ShowTooltip(Root.MousePosition, "We don't see how this could work.");
                    return;
                }
            }
        }
예제 #16
0
        public static void GenerateSurfaceLife(VoxelChunk TopChunk, ChunkGeneratorSettings Settings)
        {
            var creatureCounts = new Dictionary <string, Dictionary <string, int> >();
            var worldDepth     = Settings.WorldSizeInChunks.Y * VoxelConstants.ChunkSizeY;

            for (var x = TopChunk.Origin.X; x < TopChunk.Origin.X + VoxelConstants.ChunkSizeX; x++)
            {
                for (var z = TopChunk.Origin.Z; z < TopChunk.Origin.Z + VoxelConstants.ChunkSizeZ; z++)
                {
                    var overworldPosition = OverworldMap.WorldToOverworld(new Vector2(x, z), Settings.Overworld.InstanceSettings.Origin);

                    if (Settings.Overworld.Map.GetBiomeAt(new Vector3(x, 0, z), Settings.Overworld.InstanceSettings.Origin).HasValue(out var biome))
                    {
                        var normalizedHeight = NormalizeHeight(Settings.Overworld.Map.LinearInterpolate(overworldPosition, OverworldField.Height));
                        var height           = (int)MathFunctions.Clamp(normalizedHeight * worldDepth, 0.0f, worldDepth - 2);

                        var voxel = Settings.World.ChunkManager.CreateVoxelHandle(new GlobalVoxelCoordinate(x, height, z));

                        if (!voxel.IsValid ||
                            voxel.Coordinate.Y == 0 ||
                            voxel.Coordinate.Y >= worldDepth - Settings.TreeLine)
                        {
                            continue;
                        }

                        if (voxel.LiquidLevel != 0)
                        {
                            continue;
                        }

                        var above = VoxelHelpers.GetVoxelAbove(voxel);
                        if (above.IsValid && (above.LiquidLevel != 0 || !above.IsEmpty))
                        {
                            continue;
                        }

                        foreach (var animal in biome.Fauna)
                        {
                            if (MathFunctions.RandEvent(animal.SpawnProbability))
                            {
                                if (!creatureCounts.ContainsKey(biome.Name))
                                {
                                    creatureCounts[biome.Name] = new Dictionary <string, int>();
                                }
                                var dict = creatureCounts[biome.Name];
                                if (!dict.ContainsKey(animal.Name))
                                {
                                    dict[animal.Name] = 0;
                                }
                                if (dict[animal.Name] < animal.MaxPopulation)
                                {
                                    EntityFactory.CreateEntity <GameComponent>(animal.Name,
                                                                               voxel.WorldPosition + Vector3.Up * 1.5f);
                                }
                                break;
                            }
                        }

                        if (voxel.Type.Name != biome.SoilLayer.VoxelType)
                        {
                            continue;
                        }

                        foreach (VegetationData veg in biome.Vegetation)
                        {
                            if (voxel.GrassType == 0)
                            {
                                continue;
                            }

                            if (MathFunctions.RandEvent(veg.SpawnProbability) &&
                                Settings.NoiseGenerator.Noise(voxel.Coordinate.X / veg.ClumpSize,
                                                              veg.NoiseOffset, voxel.Coordinate.Z / veg.ClumpSize) >= veg.ClumpThreshold)
                            {
                                var treeSize   = MathFunctions.Rand() * veg.SizeVariance + veg.MeanSize;
                                var blackboard = new Blackboard();
                                blackboard.SetData("Scale", treeSize);

                                EntityFactory.CreateEntity <Plant>(veg.Name,
                                                                   voxel.WorldPosition + new Vector3(0.5f, 1.0f, 0.5f),
                                                                   blackboard);

                                break;
                            }
                        }
                    }
                }
            }
        }
예제 #17
0
        public override double GetUnnormalisedSimilarity(string firstWord, string secondWord)
        {
            if ((firstWord == null) || (secondWord == null))
            {
                return(0.0);
            }
            int length = firstWord.Length;
            int num2   = secondWord.Length;

            if (length == 0)
            {
                return((double)num2);
            }
            if (num2 == 0)
            {
                return((double)length);
            }
            double[][] numArray = new double[length][];
            for (int i = 0; i < length; i++)
            {
                numArray[i] = new double[num2];
            }
            double num4 = 0.0;

            for (int j = 0; j < length; j++)
            {
                double num6 = this.dCostFunction.GetCost(firstWord, j, secondWord, 0);
                if (j == 0)
                {
                    numArray[0][0] = Math.Max(0.0, num6);
                }
                else
                {
                    double num7 = 0.0;
                    int    num8 = j - this.windowSize;
                    if (num8 < 1)
                    {
                        num8 = 1;
                    }
                    for (int n = num8; n < j; n++)
                    {
                        num7 = Math.Max(num7, numArray[j - n][0] - this.gGapFunction.GetCost(firstWord, j - n, j));
                    }
                    numArray[j][0] = MathFunctions.MaxOf3(0.0, num7, num6);
                }
                if (numArray[j][0] > num4)
                {
                    num4 = numArray[j][0];
                }
            }
            for (int k = 0; k < num2; k++)
            {
                double num11 = this.dCostFunction.GetCost(firstWord, 0, secondWord, k);
                if (k == 0)
                {
                    numArray[0][0] = Math.Max(0.0, num11);
                }
                else
                {
                    double num12 = 0.0;
                    int    num13 = k - this.windowSize;
                    if (num13 < 1)
                    {
                        num13 = 1;
                    }
                    for (int num14 = num13; num14 < k; num14++)
                    {
                        num12 = Math.Max(num12, numArray[0][k - num14] - this.gGapFunction.GetCost(secondWord, k - num14, k));
                    }
                    numArray[0][k] = MathFunctions.MaxOf3(0.0, num12, num11);
                }
                if (numArray[0][k] > num4)
                {
                    num4 = numArray[0][k];
                }
            }
            for (int m = 1; m < length; m++)
            {
                for (int num16 = 1; num16 < num2; num16++)
                {
                    double num17 = this.dCostFunction.GetCost(firstWord, m, secondWord, num16);
                    double num18 = 0.0;
                    double num19 = 0.0;
                    int    num20 = m - this.windowSize;
                    if (num20 < 1)
                    {
                        num20 = 1;
                    }
                    for (int num21 = num20; num21 < m; num21++)
                    {
                        num18 = Math.Max(num18, numArray[m - num21][num16] - this.gGapFunction.GetCost(firstWord, m - num21, m));
                    }
                    num20 = num16 - this.windowSize;
                    if (num20 < 1)
                    {
                        num20 = 1;
                    }
                    for (int num22 = num20; num22 < num16; num22++)
                    {
                        num19 = Math.Max(num19, numArray[m][num16 - num22] - this.gGapFunction.GetCost(secondWord, num16 - num22, num16));
                    }
                    numArray[m][num16] = MathFunctions.MaxOf4(0.0, num18, num19, numArray[m - 1][num16 - 1] + num17);
                    if (numArray[m][num16] > num4)
                    {
                        num4 = numArray[m][num16];
                    }
                }
            }
            return(num4);
        }
예제 #18
0
        private List<SortedDictionary<double, double>> GetDataSet(DataSet ds)
        {

            var res = new SortedDictionary<double, List<double>>();

            if (ds.Data!=null && Enumerable.Any(ds.Data))
            foreach (var p in ds.Data)
            {
                double day = DateTimeAxis.ToDouble(p.Key);
                double groupDay = day;

                switch (ds.Grouping)
                {            
                    case GroupingOptions.none:
                        groupDay = DateTimeAxis.ToDouble(p.Key);
                        break;
                    case GroupingOptions.minutes:
                        groupDay = DateTimeAxis.ToDouble(p.Key.Date.AddHours(p.Key.Hour).AddMinutes(p.Key.Minute));
                        break;
                    case GroupingOptions.quarterly:
                        var min = 0;
                        if (p.Key.Minute < 30) min = 15;
                        if (p.Key.Minute < 45) min = 30;
                        if (p.Key.Minute < 60) min = 45;
                        groupDay = DateTimeAxis.ToDouble(p.Key.Date.AddHours(p.Key.Hour).AddMinutes(min));
                        break;
                    case GroupingOptions.hourly:
                        groupDay = DateTimeAxis.ToDouble(p.Key.Date.AddHours(p.Key.Hour));
                        break;
                    case GroupingOptions.daily:
                        groupDay = DateTimeAxis.ToDouble(p.Key.Date);
                        break;
                    case GroupingOptions.weekly:
                        groupDay = DateTimeAxis.ToDouble(p.Key.GetDateTimeForDayOfWeek(DayOfWeek.Monday));
                        break;
                    case GroupingOptions.monthly:                        
                        groupDay = DateTimeAxis.ToDouble(p.Key.GetFirstDayOfTheMonth());
                        break;
                    case GroupingOptions.yearly:
                        groupDay = DateTimeAxis.ToDouble(p.Key.GetFirstDayOfTheYear());
                        break;
                }
                
                if (!res.ContainsKey(groupDay)) res[groupDay] = new List<double>();
                res[groupDay].Add(p.Value);
            }
            else if (ds.DData != null)
            {
                return new List<SortedDictionary<double, double>>() { ds.DData };
            }
            SortedDictionary<double, double> r = new SortedDictionary<double, double>();
            switch (ds.GroupingOperation)
            {
                case GroupingOperations.count:
                    r = (from n in res select new KeyValuePair<double, double>(n.Key, n.Value.Count)).ToSortedDictionary(k => k.Key, k => k.Value);                    
                    break;
                case GroupingOperations.maximum:
                    r = (from n in res select new KeyValuePair<double, double>(n.Key, n.Value.Max())).ToSortedDictionary(k => k.Key, k => k.Value);
                    break;
                case GroupingOperations.minimum:
                    r = (from n in res select new KeyValuePair<double, double>(n.Key, n.Value.Min())).ToSortedDictionary(k => k.Key, k => k.Value);
                    break;
                case GroupingOperations.average:
                    r = (from n in res select new KeyValuePair<double, double>(n.Key, n.Value.Average())).ToSortedDictionary(k => k.Key, k => k.Value);
                    break;
                case GroupingOperations.total:
                    r = (from n in res select new KeyValuePair<double, double>(n.Key, n.Value.Sum())).ToSortedDictionary(k => k.Key, k => k.Value);
                    break;                
            }
            SortedDictionary<double, double> f = new SortedDictionary<double, double>();
            switch (ds.FunctionOperation)
            {
                case FunctionOperations.none:
                    f = r;
                    break;
                case FunctionOperations.reduction:
                    {
                        var m = new MathFunctions();
                        var temp = (from n in r select new Point(n.Key, n.Value)).ToList();
                        var euclistx = new List<double>();
                        var euclisty = new List<double>();
                        for (int i = 0; i < temp.Count - 1; i++)
                        {
                            euclistx.Add(Math.Sqrt((temp[i].X - temp[i + 1].X)*(temp[i].X - temp[i + 1].X)));
                            euclisty.Add(Math.Sqrt((temp[i].Y - temp[i + 1].Y)*(temp[i].Y - temp[i + 1].Y)));
                        }
                        var thresholdx = Convert.ToDouble(euclistx.Average());
                        var thresholdy = Convert.ToDouble(euclisty.Average());
                        var dp = m.DouglasPeuckerReduction(temp, 10*thresholdx);
                        f = (from n in dp select new KeyValuePair<double, double>(n.X, n.Y)).ToSortedDictionary(k => k.Key,
                                                                                                          k => k.Value);
                    }
                    break;
                case FunctionOperations.auto:
                    {
                        if (ds.ReducedData == null)
                            ds.ReducedData = mf.CalculateReduction(r, 0.95); ;

                        f = ds.ReducedData;


                        if (ds.AggregatedData == null)
                        {
                            ds.AggregatedData = CalculateAggregate(f);
                        }
                        var actualsize = Math.Max(_view.Plot.ActualWidth - 60, 20);
                        var v = model.Axes.FirstOrDefault(k => k.Position == AxisPosition.Bottom);
                        var points = f.Where(k => k.Key > v.Minimum && k.Key < v.Maximum).Count();

                        if (points > actualsize / 2)
                        {
                            return ds.AggregatedData;
                        }
                    }
                    break;
                case FunctionOperations.periodic:
                    {
                        var first = r.First();
                        var test = DateTimeAxis.ToDouble(new DateTime());
                        var period = DateTimeAxis.ToDouble(new DateTime() + ds.Periodic)-test;
                        var idx = 1.0;
                        var resultlist = new List<SortedDictionary<double, double>>();
                        foreach (var val in r)
                        {
                           
                            if (val.Key - first.Key > period*idx)
                            {
                                resultlist.Add(f.ToSortedDictionary(k=>k.Key,k=>k.Value));
                                while (val.Key - first.Key > period*idx)
                                    idx++;
                                f.Clear();
                            }
                            f.Add(first.Key + ((val.Key - first.Key) - period*(idx-1)),val.Value);
                        }
                        resultlist.Add(f.ToSortedDictionary(k => k.Key, k => k.Value));
                        return resultlist;
                    }
                // FIXME TODO: Unreachable code
                    // break;
            }
            return new List<SortedDictionary<double, double>>() { f };

        }
예제 #19
0
        public void intersectRay(Ray r, WorkerCallback intersectCallback, ref float maxDist, bool stopAtFirst = false)
        {
            float   intervalMin = -1.0f;
            float   intervalMax = -1.0f;
            Vector3 org         = r.Origin;
            Vector3 dir         = r.Direction;
            Vector3 invDir      = new Vector3();

            for (int i = 0; i < 3; ++i)
            {
                invDir[i] = 1.0f / dir[i];
                if (MathFunctions.fuzzyNe(dir[i], 0.0f))
                {
                    float t1 = (bounds.Lo[i] - org[i]) * invDir[i];
                    float t2 = (bounds.Hi[i] - org[i]) * invDir[i];
                    if (t1 > t2)
                    {
                        MathFunctions.Swap <float>(ref t1, ref t2);
                    }
                    if (t1 > intervalMin)
                    {
                        intervalMin = t1;
                    }
                    if (t2 < intervalMax || intervalMax < 0.0f)
                    {
                        intervalMax = t2;
                    }
                    // intervalMax can only become smaller for other axis,
                    //  and intervalMin only larger respectively, so stop early
                    if (intervalMax <= 0 || intervalMin >= maxDist)
                    {
                        return;
                    }
                }
            }

            if (intervalMin > intervalMax)
            {
                return;
            }
            intervalMin = Math.Max(intervalMin, 0.0f);
            intervalMax = Math.Min(intervalMax, maxDist);

            uint[] offsetFront  = new uint[3];
            uint[] offsetBack   = new uint[3];
            uint[] offsetFront3 = new uint[3];
            uint[] offsetBack3  = new uint[3];
            // compute custom offsets from direction sign bit

            for (int i = 0; i < 3; ++i)
            {
                offsetFront[i]  = floatToRawIntBits(dir[i]) >> 31;
                offsetBack[i]   = offsetFront[i] ^ 1;
                offsetFront3[i] = offsetFront[i] * 3;
                offsetBack3[i]  = offsetBack[i] * 3;

                // avoid always adding 1 during the inner loop
                ++offsetFront[i];
                ++offsetBack[i];
            }

            StackNode[] stack    = new StackNode[64];
            int         stackPos = 0;
            int         node     = 0;

            while (true)
            {
                while (true)
                {
                    uint tn     = tree[node];
                    uint axis   = (uint)(tn & (3 << 30)) >> 30;
                    bool BVH2   = Convert.ToBoolean(tn & (1 << 29));
                    int  offset = (int)(tn & ~(7 << 29));
                    if (!BVH2)
                    {
                        if (axis < 3)
                        {
                            // "normal" interior node
                            float tf = (intBitsToFloat(tree[(int)(node + offsetFront[axis])]) - org[axis]) * invDir[axis];
                            float tb = (intBitsToFloat(tree[(int)(node + offsetBack[axis])]) - org[axis]) * invDir[axis];
                            // ray passes between clip zones
                            if (tf < intervalMin && tb > intervalMax)
                            {
                                break;
                            }
                            int back = (int)(offset + offsetBack3[axis]);
                            node = back;
                            // ray passes through far node only
                            if (tf < intervalMin)
                            {
                                intervalMin = (tb >= intervalMin) ? tb : intervalMin;
                                continue;
                            }
                            node = offset + (int)offsetFront3[axis]; // front
                            // ray passes through near node only
                            if (tb > intervalMax)
                            {
                                intervalMax = (tf <= intervalMax) ? tf : intervalMax;
                                continue;
                            }
                            // ray passes through both nodes
                            // push back node
                            stack[stackPos].node  = (uint)back;
                            stack[stackPos].tnear = (tb >= intervalMin) ? tb : intervalMin;
                            stack[stackPos].tfar  = intervalMax;
                            stackPos++;
                            // update ray interval for front node
                            intervalMax = (tf <= intervalMax) ? tf : intervalMax;
                            continue;
                        }
                        else
                        {
                            // leaf - test some objects
                            int n = (int)tree[node + 1];
                            while (n > 0)
                            {
                                bool hit = intersectCallback.Invoke(r, objects[offset], ref maxDist, stopAtFirst);
                                if (stopAtFirst && hit)
                                {
                                    return;
                                }
                                --n;
                                ++offset;
                            }
                            break;
                        }
                    }
                    else
                    {
                        if (axis > 2)
                        {
                            return; // should not happen
                        }
                        float tf = (intBitsToFloat(tree[(int)(node + offsetFront[axis])]) - org[axis]) * invDir[axis];
                        float tb = (intBitsToFloat(tree[(int)(node + offsetBack[axis])]) - org[axis]) * invDir[axis];
                        node        = offset;
                        intervalMin = (tf >= intervalMin) ? tf : intervalMin;
                        intervalMax = (tb <= intervalMax) ? tb : intervalMax;
                        if (intervalMin > intervalMax)
                        {
                            break;
                        }
                        continue;
                    }
                } // traversal loop
                do
                {
                    // stack is empty?
                    if (stackPos == 0)
                    {
                        return;
                    }
                    // move back up the stack
                    stackPos--;
                    intervalMin = stack[stackPos].tnear;
                    if (maxDist < intervalMin)
                    {
                        continue;
                    }
                    node        = (int)stack[stackPos].node;
                    intervalMax = stack[stackPos].tfar;
                    break;
                } while (true);
            }
        }
        /**
         * Regularized lower gamma function 'P'
         * @param s
         * @param x
         * @return Value of the regularized lower gamma function 'P'.
         */
        public static double regularizedGammaLowerP(double s, double x)
        {
            if (Double.IsNaN(x))
            {
                return(Double.NaN);
            }
            if (Double.IsNaN(s))
            {
                return(Double.NaN);
            }
            if (MathFunctions.almostEqual(x, 0))
            {
                return(0);
            }
            if (MathFunctions.almostEqual(s, 0))
            {
                return(1 + SpecialFunctions.exponentialIntegralEi(-x) / MathConstants.EULER_MASCHERONI);
            }

            if (MathFunctions.almostEqual(s, 1))
            {
                return(1 - Math.Exp(-x));
            }

            if (x < 0)
            {
                return(Double.NaN);
            }

            if (s < 0)
            {
                return(regularizedGammaLowerP(s + 1, x) + (Math.Pow(x, s) * Math.Exp(-x)) / (s * gamma(s)));
            }

            const double epsilon          = 0.000000000000001;
            const double bigNumber        = 4503599627370496.0;
            const double bigNumberInverse = 2.22044604925031308085e-16;

            double ax = (s * Math.Log(x)) - x - logGamma(s);

            if (ax < -709.78271289338399)
            {
                return(1);
            }

            if (x <= 1 || x <= s)
            {
                double r2   = s;
                double c2   = 1;
                double ans2 = 1;
                do
                {
                    r2    = r2 + 1;
                    c2    = c2 * x / r2;
                    ans2 += c2;
                } while ((c2 / ans2) > epsilon);
                return(Math.Exp(ax) * ans2 / s);
            }

            int    c = 0;
            double y = 1 - s;
            double z = x + y + 1;

            double p3  = 1;
            double q3  = x;
            double p2  = x + 1;
            double q2  = z * x;
            double ans = p2 / q2;

            double error;

            do
            {
                c++;
                y += 1;
                z += 2;
                double yc = y * c;

                double p = (p2 * z) - (p3 * yc);
                double q = (q2 * z) - (q3 * yc);

                if (q != 0)
                {
                    double nextans = p / q;
                    error = Math.Abs((ans - nextans) / nextans);
                    ans   = nextans;
                }
                else
                {
                    // zero div, skip
                    error = 1;
                }

                // shift
                p3 = p2;
                p2 = p;
                q3 = q2;
                q2 = q;

                // normalize fraction when the numerator becomes large
                if (Math.Abs(p) > bigNumber)
                {
                    p3 *= bigNumberInverse;
                    p2 *= bigNumberInverse;
                    q3 *= bigNumberInverse;
                    q2 *= bigNumberInverse;
                }
            } while (error > epsilon);

            return(1 - (Math.Exp(ax) * ans));
        }
예제 #21
0
 void HandleDummy(uint effIndex)
 {
     SetHitDamage((int)MathFunctions.CalculatePct(GetCaster().GetTotalAttackPowerValue(WeaponAttackType.BaseAttack), GetEffectValue()));
 }
예제 #22
0
        public static void ExtractSet(WMODoodadData doodadData, MODF.SMMapObjDef wmo, bool isGlobalWmo, uint mapID, uint originalMapId, BinaryWriter writer, List <ADTOutputCache> dirfileCache)
        {
            if (doodadData == null)
            {
                return;
            }

            if (wmo.DoodadSet >= doodadData.Sets.Count)
            {
                return;
            }

            Vector3 wmoPosition = new(wmo.Position.Z, wmo.Position.X, wmo.Position.Y);
            Matrix3 wmoRotation = Matrix3.fromEulerAnglesZYX(MathFunctions.toRadians(wmo.Rotation.Y), MathFunctions.toRadians(wmo.Rotation.X), MathFunctions.toRadians(wmo.Rotation.Z));

            if (isGlobalWmo)
            {
                wmoPosition += new Vector3(533.33333f * 32, 533.33333f * 32, 0.0f);
            }

            ushort doodadId      = 0;
            MODS   doodadSetData = doodadData.Sets[wmo.DoodadSet];

            if (doodadData.Paths == null)
            {
                return;
            }

            using BinaryReader reader = new(new MemoryStream(doodadData.Paths));
            foreach (ushort doodadIndex in doodadData.References)
            {
                if (doodadIndex < doodadSetData.StartIndex ||
                    doodadIndex >= doodadSetData.StartIndex + doodadSetData.Count)
                {
                    continue;
                }

                MODD doodad = doodadData.Spawns[doodadIndex];

                reader.BaseStream.Position = doodad.NameIndex;
                string ModelInstName = reader.ReadCString().GetPlainName();

                if (ModelInstName.Length > 3)
                {
                    string extension = ModelInstName.Substring(ModelInstName.Length - 4);
                    if (extension == ".mdx" || extension == ".mdl")
                    {
                        ModelInstName  = ModelInstName.Remove(ModelInstName.Length - 2, 2);
                        ModelInstName += "2";
                    }
                }

                if (!File.Exists(Program.BuildingsDirectory + ModelInstName))
                {
                    continue;
                }

                using (BinaryReader binaryReader = new(File.Open(Program.BuildingsDirectory + ModelInstName, FileMode.Open, FileAccess.Read, FileShare.Read)))
                {
                    binaryReader.BaseStream.Seek(8, SeekOrigin.Begin); // get the correct no of vertices
                    int nVertices = binaryReader.ReadInt32();
                    if (nVertices == 0)
                    {
                        continue;
                    }
                }
                ++doodadId;

                Vector3 position = wmoPosition + (wmoRotation * new Vector3(doodad.Position.X, doodad.Position.Y, doodad.Position.Z));

                Vector3 rotation;
                (new Quaternion(doodad.Rotation.X, doodad.Rotation.Y, doodad.Rotation.Z, doodad.Rotation.W).ToRotationMatrix() * wmoRotation).toEulerAnglesXYZ(out rotation.Z, out rotation.X, out rotation.Y);

                rotation.Z = MathFunctions.toDegrees(rotation.Z);
                rotation.X = MathFunctions.toDegrees(rotation.X);
                rotation.Y = MathFunctions.toDegrees(rotation.Y);

                ushort nameSet  = 0;    // not used for models
                uint   uniqueId = VmapFile.GenerateUniqueObjectId(wmo.UniqueId, doodadId);
                uint   flags    = ModelFlags.M2;
                if (mapID != originalMapId)
                {
                    flags |= ModelFlags.ParentSpawn;
                }

                //write mapID, Flags, NameSet, UniqueId, Pos, Rot, Scale, name
                writer.Write(mapID);
                writer.Write(flags);
                writer.Write(nameSet);
                writer.Write(uniqueId);
                writer.WriteVector3(position);
                writer.WriteVector3(rotation);
                writer.Write(doodad.Scale);
                writer.Write(ModelInstName.GetByteCount());
                writer.WriteString(ModelInstName);

                if (dirfileCache != null)
                {
                    ADTOutputCache cacheModelData = new();
                    cacheModelData.Flags = flags & ~ModelFlags.ParentSpawn;

                    MemoryStream stream    = new();
                    BinaryWriter cacheData = new(stream);
                    cacheData.Write(nameSet);
                    cacheData.Write(uniqueId);
                    cacheData.WriteVector3(position);
                    cacheData.WriteVector3(rotation);
                    cacheData.Write(doodad.Scale);
                    cacheData.Write(ModelInstName.GetByteCount());
                    cacheData.WriteString(ModelInstName);

                    cacheModelData.Data = stream.ToArray();
                    dirfileCache.Add(cacheModelData);
                }
            }
        }
예제 #23
0
        public bool Meets(ConditionSourceInfo sourceInfo)
        {
            Contract.Assert(ConditionTarget < SharedConst.MaxConditionTargets);
            WorldObject obj = sourceInfo.mConditionTargets[ConditionTarget];

            // object not present, return false
            if (obj == null)
            {
                Log.outDebug(LogFilter.Condition, "Condition object not found for condition (Entry: {0} Type: {1} Group: {2})", SourceEntry, SourceType, SourceGroup);
                return(false);
            }
            bool condMeets = false;

            Player player = obj.ToPlayer();
            Unit   unit   = obj.ToUnit();

            switch (ConditionType)
            {
            case ConditionTypes.None:
                condMeets = true;                                        // empty condition, always met
                break;

            case ConditionTypes.Aura:
                if (unit != null)
                {
                    condMeets = unit.HasAuraEffect(ConditionValue1, (byte)ConditionValue2);
                }
                break;

            case ConditionTypes.Item:
                if (player != null)
                {
                    // don't allow 0 items (it's checked during table load)
                    Contract.Assert(ConditionValue2 != 0);
                    bool checkBank = ConditionValue3 != 0 ? true : false;
                    condMeets = player.HasItemCount(ConditionValue1, ConditionValue2, checkBank);
                }
                break;

            case ConditionTypes.ItemEquipped:
                if (player != null)
                {
                    condMeets = player.HasItemOrGemWithIdEquipped(ConditionValue1, 1);
                }
                break;

            case ConditionTypes.Zoneid:
                condMeets = obj.GetZoneId() == ConditionValue1;
                break;

            case ConditionTypes.ReputationRank:
                if (player != null)
                {
                    var faction = CliDB.FactionStorage.LookupByKey(ConditionValue1);
                    if (faction != null)
                    {
                        condMeets = Convert.ToBoolean(ConditionValue2 & (1 << (int)player.GetReputationMgr().GetRank(faction)));
                    }
                }
                break;

            case ConditionTypes.Achievement:
                if (player != null)
                {
                    condMeets = player.HasAchieved(ConditionValue1);
                }
                break;

            case ConditionTypes.Team:
                if (player != null)
                {
                    condMeets = (uint)player.GetTeam() == ConditionValue1;
                }
                break;

            case ConditionTypes.Class:
                if (unit != null)
                {
                    condMeets = Convert.ToBoolean(unit.getClassMask() & ConditionValue1);
                }
                break;

            case ConditionTypes.Race:
                if (unit != null)
                {
                    condMeets = Convert.ToBoolean(unit.getRaceMask() & ConditionValue1);
                }
                break;

            case ConditionTypes.Gender:
                if (player != null)
                {
                    condMeets = player.GetGender() == (Gender)ConditionValue1;
                }
                break;

            case ConditionTypes.Skill:
                if (player != null)
                {
                    condMeets = player.HasSkill((SkillType)ConditionValue1) && player.GetBaseSkillValue((SkillType)ConditionValue1) >= ConditionValue2;
                }
                break;

            case ConditionTypes.QuestRewarded:
                if (player != null)
                {
                    condMeets = player.GetQuestRewardStatus(ConditionValue1);
                }
                break;

            case ConditionTypes.QuestTaken:
                if (player != null)
                {
                    QuestStatus status = player.GetQuestStatus(ConditionValue1);
                    condMeets = (status == QuestStatus.Incomplete);
                }
                break;

            case ConditionTypes.QuestComplete:
                if (player != null)
                {
                    QuestStatus status = player.GetQuestStatus(ConditionValue1);
                    condMeets = (status == QuestStatus.Complete && !player.GetQuestRewardStatus(ConditionValue1));
                }
                break;

            case ConditionTypes.QuestNone:
                if (player != null)
                {
                    QuestStatus status = player.GetQuestStatus(ConditionValue1);
                    condMeets = (status == QuestStatus.None);
                }
                break;

            case ConditionTypes.ActiveEvent:
                condMeets = Global.GameEventMgr.IsActiveEvent((ushort)ConditionValue1);
                break;

            case ConditionTypes.InstanceInfo:
            {
                var map = obj.GetMap();
                if (map.IsDungeon())
                {
                    InstanceScript instance = ((InstanceMap)map).GetInstanceScript();
                    if (instance != null)
                    {
                        switch ((InstanceInfo)ConditionValue3)
                        {
                        case InstanceInfo.Data:
                            condMeets = instance.GetData(ConditionValue1) == ConditionValue2;
                            break;

                        case InstanceInfo.Data64:
                            condMeets = instance.GetData64(ConditionValue1) == ConditionValue2;
                            break;

                        case InstanceInfo.BossState:
                            condMeets = instance.GetBossState(ConditionValue1) == (EncounterState)ConditionValue2;
                            break;
                        }
                    }
                }
                break;
            }

            case ConditionTypes.Mapid:
                condMeets = obj.GetMapId() == ConditionValue1;
                break;

            case ConditionTypes.Areaid:
                condMeets = obj.GetAreaId() == ConditionValue1;
                break;

            case ConditionTypes.Spell:
                if (player != null)
                {
                    condMeets = player.HasSpell(ConditionValue1);
                }
                break;

            case ConditionTypes.Level:
                if (unit != null)
                {
                    condMeets = MathFunctions.CompareValues((ComparisionType)ConditionValue2, unit.getLevel(), ConditionValue1);
                }
                break;

            case ConditionTypes.DrunkenState:
                if (player != null)
                {
                    condMeets = (uint)Player.GetDrunkenstateByValue(player.GetDrunkValue()) >= ConditionValue1;
                }
                break;

            case ConditionTypes.NearCreature:
                condMeets = obj.FindNearestCreature(ConditionValue1, ConditionValue2, ConditionValue3 == 0 ? true : false) != null;
                break;

            case ConditionTypes.NearGameobject:
                condMeets = obj.FindNearestGameObject(ConditionValue1, ConditionValue2) != null;
                break;

            case ConditionTypes.ObjectEntryGuid:
                if ((uint)obj.GetTypeId() == ConditionValue1)
                {
                    condMeets = ConditionValue2 == 0 || (obj.GetEntry() == ConditionValue2);

                    if (ConditionValue3 != 0)
                    {
                        switch (obj.GetTypeId())
                        {
                        case TypeId.Unit:
                            condMeets &= obj.ToCreature().GetSpawnId() == ConditionValue3;
                            break;

                        case TypeId.GameObject:
                            condMeets &= obj.ToGameObject().GetSpawnId() == ConditionValue3;
                            break;
                        }
                    }
                }
                break;

            case ConditionTypes.TypeMask:
                condMeets = Convert.ToBoolean((TypeMask)ConditionValue1 & obj.objectTypeMask);
                break;

            case ConditionTypes.RelationTo:
            {
                WorldObject toObject = sourceInfo.mConditionTargets[ConditionValue1];
                if (toObject != null)
                {
                    Unit toUnit = toObject.ToUnit();
                    if (toUnit != null && unit != null)
                    {
                        switch ((RelationType)ConditionValue2)
                        {
                        case RelationType.Self:
                            condMeets = unit == toUnit;
                            break;

                        case RelationType.InParty:
                            condMeets = unit.IsInPartyWith(toUnit);
                            break;

                        case RelationType.InRaidOrParty:
                            condMeets = unit.IsInRaidWith(toUnit);
                            break;

                        case RelationType.OwnedBy:
                            condMeets = unit.GetOwnerGUID() == toUnit.GetGUID();
                            break;

                        case RelationType.PassengerOf:
                            condMeets = unit.IsOnVehicle(toUnit);
                            break;

                        case RelationType.CreatedBy:
                            condMeets = unit.GetCreatorGUID() == toUnit.GetGUID();
                            break;
                        }
                    }
                }
                break;
            }

            case ConditionTypes.ReactionTo:
            {
                WorldObject toObject = sourceInfo.mConditionTargets[ConditionValue1];
                if (toObject != null)
                {
                    Unit toUnit = toObject.ToUnit();
                    if (toUnit != null && unit != null)
                    {
                        condMeets = Convert.ToBoolean((1 << (int)unit.GetReactionTo(toUnit)) & ConditionValue2);
                    }
                }
                break;
            }

            case ConditionTypes.DistanceTo:
            {
                WorldObject toObject = sourceInfo.mConditionTargets[ConditionValue1];
                if (toObject != null)
                {
                    condMeets = MathFunctions.CompareValues((ComparisionType)ConditionValue3, obj.GetDistance(toObject), ConditionValue2);
                }
                break;
            }

            case ConditionTypes.Alive:
                if (unit != null)
                {
                    condMeets = unit.IsAlive();
                }
                break;

            case ConditionTypes.HpVal:
                if (unit != null)
                {
                    condMeets = MathFunctions.CompareValues((ComparisionType)ConditionValue2, unit.GetHealth(), ConditionValue1);
                }
                break;

            case ConditionTypes.HpPct:
                if (unit != null)
                {
                    condMeets = MathFunctions.CompareValues((ComparisionType)ConditionValue2, unit.GetHealthPct(), ConditionValue1);
                }
                break;

            case ConditionTypes.WorldState:
                condMeets = (ConditionValue2 == Global.WorldMgr.getWorldState((WorldStates)ConditionValue1));
                break;

            case ConditionTypes.PhaseId:
                condMeets = obj.GetPhaseShift().HasPhase(ConditionValue1);
                break;

            case ConditionTypes.Title:
                if (player != null)
                {
                    condMeets = player.HasTitle(ConditionValue1);
                }
                break;

            case ConditionTypes.Spawnmask:
                condMeets = Convert.ToBoolean((1ul << (int)obj.GetMap().GetSpawnMode()) & ConditionValue1);
                break;

            case ConditionTypes.UnitState:
                if (unit != null)
                {
                    condMeets = unit.HasUnitState((UnitState)ConditionValue1);
                }
                break;

            case ConditionTypes.CreatureType:
            {
                Creature creature = obj.ToCreature();
                if (creature)
                {
                    condMeets = (uint)creature.GetCreatureTemplate().CreatureType == ConditionValue1;
                }
                break;
            }

            case ConditionTypes.RealmAchievement:
            {
                AchievementRecord achievement = CliDB.AchievementStorage.LookupByKey(ConditionValue1);
                if (achievement != null && Global.AchievementMgr.IsRealmCompleted(achievement))
                {
                    condMeets = true;
                }
                break;
            }

            case ConditionTypes.InWater:
                if (unit)
                {
                    condMeets = unit.IsInWater();
                }
                break;

            case ConditionTypes.TerrainSwap:
                condMeets = obj.GetPhaseShift().HasVisibleMapId(ConditionValue1);
                break;

            case ConditionTypes.StandState:
            {
                if (unit)
                {
                    if (ConditionValue1 == 0)
                    {
                        condMeets = (unit.GetStandState() == (UnitStandStateType)ConditionValue2);
                    }
                    else if (ConditionValue2 == 0)
                    {
                        condMeets = unit.IsStandState();
                    }
                    else if (ConditionValue2 == 1)
                    {
                        condMeets = unit.IsSitState();
                    }
                }
                break;
            }

            case ConditionTypes.DailyQuestDone:
            {
                if (player)
                {
                    condMeets = player.IsDailyQuestDone(ConditionValue1);
                }
                break;
            }

            case ConditionTypes.Charmed:
            {
                if (unit)
                {
                    condMeets = unit.IsCharmed();
                }
                break;
            }

            case ConditionTypes.PetType:
            {
                if (player)
                {
                    Pet pet = player.GetPet();
                    if (pet)
                    {
                        condMeets = (((1 << (int)pet.getPetType()) & ConditionValue1) != 0);
                    }
                }
                break;
            }

            case ConditionTypes.Taxi:
            {
                if (player)
                {
                    condMeets = player.IsInFlight();
                }
                break;
            }

            case ConditionTypes.Queststate:
            {
                if (player)
                {
                    if (
                        (Convert.ToBoolean(ConditionValue2 & (1 << (int)QuestStatus.None)) && (player.GetQuestStatus(ConditionValue1) == QuestStatus.None)) ||
                        (Convert.ToBoolean(ConditionValue2 & (1 << (int)QuestStatus.Complete)) && (player.GetQuestStatus(ConditionValue1) == QuestStatus.Complete)) ||
                        (Convert.ToBoolean(ConditionValue2 & (1 << (int)QuestStatus.Incomplete)) && (player.GetQuestStatus(ConditionValue1) == QuestStatus.Incomplete)) ||
                        (Convert.ToBoolean(ConditionValue2 & (1 << (int)QuestStatus.Failed)) && (player.GetQuestStatus(ConditionValue1) == QuestStatus.Failed)) ||
                        (Convert.ToBoolean(ConditionValue2 & (1 << (int)QuestStatus.Rewarded)) && player.GetQuestRewardStatus(ConditionValue1))
                        )
                    {
                        condMeets = true;
                    }
                }
                break;
            }

            case ConditionTypes.ObjectiveComplete:
            {
                if (player)
                {
                    QuestObjective questObj = Global.ObjectMgr.GetQuestObjective(ConditionValue1);
                    if (questObj == null)
                    {
                        break;
                    }

                    condMeets = (!player.GetQuestRewardStatus(questObj.QuestID) && player.IsQuestObjectiveComplete(questObj));
                }
                break;
            }

            default:
                condMeets = false;
                break;
            }

            if (NegativeCondition)
            {
                condMeets = !condMeets;
            }

            if (!condMeets)
            {
                sourceInfo.mLastFailedCondition = this;
            }

            bool script = Global.ScriptMgr.OnConditionCheck(this, sourceInfo); // Returns true by default.

            return(condMeets && script);
        }
예제 #24
0
 public MathFunctionsSteps()
 {
     this.mathService   = new MathService();
     this.mathFunctions = new MathFunctions(this.mathService);
 }
예제 #25
0
        public bool RewardHonor(Unit victim, uint groupsize, int honor = -1, bool pvptoken = false)
        {
            // do not reward honor in arenas, but enable onkill spellproc
            if (InArena())
            {
                if (!victim || victim == this || !victim.IsTypeId(TypeId.Player))
                {
                    return(false);
                }

                if (GetBGTeam() == victim.ToPlayer().GetBGTeam())
                {
                    return(false);
                }

                return(true);
            }

            // 'Inactive' this aura prevents the player from gaining honor points and BattlegroundTokenizer
            if (HasAura(BattlegroundConst.SpellAuraPlayerInactive))
            {
                return(false);
            }

            ObjectGuid victim_guid = ObjectGuid.Empty;
            uint       victim_rank = 0;

            // need call before fields update to have chance move yesterday data to appropriate fields before today data change.
            UpdateHonorFields();

            // do not reward honor in arenas, but return true to enable onkill spellproc
            if (InBattleground() && GetBattleground() && GetBattleground().isArena())
            {
                return(true);
            }

            // Promote to float for calculations
            float honor_f = honor;

            if (honor_f <= 0)
            {
                if (!victim || victim == this || victim.HasAuraType(AuraType.NoPvpCredit))
                {
                    return(false);
                }

                victim_guid = victim.GetGUID();
                Player plrVictim = victim.ToPlayer();
                if (plrVictim)
                {
                    if (GetTeam() == plrVictim.GetTeam() && !Global.WorldMgr.IsFFAPvPRealm())
                    {
                        return(false);
                    }

                    byte k_level = (byte)getLevel();
                    byte k_grey  = (byte)Formulas.GetGrayLevel(k_level);
                    byte v_level = (byte)victim.GetLevelForTarget(this);

                    if (v_level <= k_grey)
                    {
                        return(false);
                    }

                    // PLAYER_CHOSEN_TITLE VALUES DESCRIPTION
                    //  [0]      Just name
                    //  [1..14]  Alliance honor titles and player name
                    //  [15..28] Horde honor titles and player name
                    //  [29..38] Other title and player name
                    //  [39+]    Nothing
                    // this is all wrong, should be going off PvpTitle, not PlayerTitle
                    uint victim_title = plrVictim.m_playerData.PlayerTitle;
                    // Get Killer titles, CharTitlesEntry.bit_index
                    // Ranks:
                    //  title[1..14]  . rank[5..18]
                    //  title[15..28] . rank[5..18]
                    //  title[other]  . 0
                    if (victim_title == 0)
                    {
                        victim_guid.Clear();                        // Don't show HK: <rank> message, only log.
                    }
                    else if (victim_title < 15)
                    {
                        victim_rank = victim_title + 4;
                    }
                    else if (victim_title < 29)
                    {
                        victim_rank = victim_title - 14 + 4;
                    }
                    else
                    {
                        victim_guid.Clear();                        // Don't show HK: <rank> message, only log.
                    }
                    honor_f = (float)Math.Ceiling(Formulas.hk_honor_at_level_f(k_level) * (v_level - k_grey) / (k_level - k_grey));

                    // count the number of playerkills in one day
                    ApplyModUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.TodayHonorableKills), (ushort)1, true);
                    // and those in a lifetime
                    ApplyModUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.LifetimeHonorableKills), 1u, true);
                    UpdateCriteria(CriteriaTypes.EarnHonorableKill);
                    UpdateCriteria(CriteriaTypes.HkClass, (uint)victim.GetClass());
                    UpdateCriteria(CriteriaTypes.HkRace, (uint)victim.GetRace());
                    UpdateCriteria(CriteriaTypes.HonorableKillAtArea, GetAreaId());
                    UpdateCriteria(CriteriaTypes.HonorableKill, 1, 0, 0, victim);
                }
                else
                {
                    if (!victim.ToCreature().IsRacialLeader())
                    {
                        return(false);
                    }

                    honor_f     = 100.0f;                           // ??? need more info
                    victim_rank = 19;                               // HK: Leader
                }
            }

            if (victim != null)
            {
                if (groupsize > 1)
                {
                    honor_f /= groupsize;
                }

                // apply honor multiplier from aura (not stacking-get highest)
                MathFunctions.AddPct(ref honor_f, GetMaxPositiveAuraModifier(AuraType.ModHonorGainPct));
                honor_f += _restMgr.GetRestBonusFor(RestTypes.Honor, (uint)honor_f);
            }

            honor_f *= WorldConfig.GetFloatValue(WorldCfg.RateHonor);
            // Back to int now
            honor = (int)honor_f;
            // honor - for show honor points in log
            // victim_guid - for show victim name in log
            // victim_rank [1..4]  HK: <dishonored rank>
            // victim_rank [5..19] HK: <alliance\horde rank>
            // victim_rank [0, 20+] HK: <>
            PvPCredit data = new PvPCredit();

            data.Honor         = honor;
            data.OriginalHonor = honor;
            data.Target        = victim_guid;
            data.Rank          = victim_rank;

            SendPacket(data);

            AddHonorXP((uint)honor);

            if (InBattleground() && honor > 0)
            {
                Battleground bg = GetBattleground();
                if (bg != null)
                {
                    bg.UpdatePlayerScore(this, ScoreType.BonusHonor, (uint)honor, false); //false: prevent looping
                }
            }

            if (WorldConfig.GetBoolValue(WorldCfg.PvpTokenEnable) && pvptoken)
            {
                if (!victim || victim == this || victim.HasAuraType(AuraType.NoPvpCredit))
                {
                    return(true);
                }

                if (victim.IsTypeId(TypeId.Player))
                {
                    // Check if allowed to receive it in current map
                    int MapType = WorldConfig.GetIntValue(WorldCfg.PvpTokenMapType);
                    if ((MapType == 1 && !InBattleground() && !IsFFAPvP()) ||
                        (MapType == 2 && !IsFFAPvP()) ||
                        (MapType == 3 && !InBattleground()))
                    {
                        return(true);
                    }

                    uint itemId = WorldConfig.GetUIntValue(WorldCfg.PvpTokenId);
                    uint count  = WorldConfig.GetUIntValue(WorldCfg.PvpTokenCount);

                    if (AddItem(itemId, count))
                    {
                        SendSysMessage("You have been awarded a token for slaying another player.");
                    }
                }
            }

            return(true);
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="FloatUnaryFunction"/> class.
 /// </summary>
 /// <param name="f">A function delegate that takes a float value as a parameter and returns a float value.</param>
 /// <param name="d">The <see cref="IDifferentiator"/> to use.</param>
 /// <param name="i">The <see cref="IIntegrator"/> to use.</param>
 public FloatUnaryFunction(MathFunctions.FloatUnaryFunction f, IDifferentiator d, IIntegrator i)
 {
     _function = f;
     _differentiator = d;
     _integrator = i;
 }
        /**
         * Regularized upper gamma function 'Q'
         * @param s
         * @param x
         * @return Value of the regularized upper gamma function 'Q'.
         */
        public static double regularizedGammaUpperQ(double s, double x)
        {
            if (Double.IsNaN(x))
            {
                return(Double.NaN);
            }
            if (Double.IsNaN(s))
            {
                return(Double.NaN);
            }
            if (MathFunctions.almostEqual(x, 0))
            {
                return(1);
            }

            if (MathFunctions.almostEqual(s, 0))
            {
                return(-SpecialFunctions.exponentialIntegralEi(-x) / MathConstants.EULER_MASCHERONI);
            }

            if (MathFunctions.almostEqual(s, 1))
            {
                return(Math.Exp(-x));
            }

            if (x < 0)
            {
                return(Double.NaN);
            }

            if (s < 0)
            {
                return(regularizedGammaUpperQ(s + 1, x) - (Math.Pow(x, s) * Math.Exp(-x)) / (s * gamma(s)));
            }

            double ax = s * Math.Log(x) - x - logGamma(s);

            if (ax < -709.78271289338399)
            {
                return(0);
            }
            double       t;
            const double igammaepsilon      = 0.000000000000001;
            const double igammabignumber    = 4503599627370496.0;
            const double igammabignumberinv = 2.22044604925031308085 * 0.0000000000000001;

            ax = Math.Exp(ax);
            double y    = 1 - s;
            double z    = x + y + 1;
            double c    = 0;
            double pkm2 = 1;
            double qkm2 = x;
            double pkm1 = x + 1;
            double qkm1 = z * x;
            double ans  = pkm1 / qkm1;

            do
            {
                c = c + 1;
                y = y + 1;
                z = z + 2;
                double yc = y * c;
                double pk = pkm1 * z - pkm2 * yc;
                double qk = qkm1 * z - qkm2 * yc;
                if (qk != 0)
                {
                    double r = pk / qk;
                    t   = Math.Abs((ans - r) / r);
                    ans = r;
                }
                else
                {
                    t = 1;
                }

                pkm2 = pkm1;
                pkm1 = pk;
                qkm2 = qkm1;
                qkm1 = qk;

                if (Math.Abs(pk) > igammabignumber)
                {
                    pkm2 = pkm2 * igammabignumberinv;
                    pkm1 = pkm1 * igammabignumberinv;
                    qkm2 = qkm2 * igammabignumberinv;
                    qkm1 = qkm1 * igammabignumberinv;
                }
            } while (t > igammaepsilon);
            return(ans * ax);
        }
예제 #28
0
        void subdivide(int left, int right, List <uint> tempTree, buildData dat, AABound gridBox, AABound nodeBox, int nodeIndex, int depth, BuildStats stats)
        {
            if ((right - left + 1) <= dat.maxPrims || depth >= 64)
            {
                // write leaf node
                stats.updateLeaf(depth, right - left + 1);
                createNode(tempTree, nodeIndex, left, right);
                return;
            }
            // calculate extents
            int   axis = -1, prevAxis, rightOrig;
            float clipL = float.NaN, clipR = float.NaN, prevClip = float.NaN;
            float split = float.NaN, prevSplit;
            bool  wasLeft = true;

            while (true)
            {
                prevAxis  = axis;
                prevSplit = split;
                // perform quick consistency checks
                Vector3 d = gridBox.hi - gridBox.lo;
                for (int i = 0; i < 3; i++)
                {
                    //if (nodeBox.hi[i] < gridBox.lo[i] || nodeBox.lo[i] > gridBox.hi[i])
                    //Log.outError(LogFilter.Server, "Reached tree area in error - discarding node with: {0} objects", right - left + 1);
                }
                // find longest axis
                axis  = (int)d.primaryAxis();
                split = 0.5f * (gridBox.lo[axis] + gridBox.hi[axis]);
                // partition L/R subsets
                clipL     = float.NegativeInfinity;
                clipR     = float.PositiveInfinity;
                rightOrig = right; // save this for later
                float nodeL = float.PositiveInfinity;
                float nodeR = float.NegativeInfinity;
                for (int i = left; i <= right;)
                {
                    int   obj    = (int)dat.indices[i];
                    float minb   = dat.primBound[obj].Lo[axis];
                    float maxb   = dat.primBound[obj].Hi[axis];
                    float center = (minb + maxb) * 0.5f;
                    if (center <= split)
                    {
                        // stay left
                        i++;
                        if (clipL < maxb)
                        {
                            clipL = maxb;
                        }
                    }
                    else
                    {
                        // move to the right most
                        int t = (int)dat.indices[i];
                        dat.indices[i]     = dat.indices[right];
                        dat.indices[right] = (uint)t;
                        right--;
                        if (clipR > minb)
                        {
                            clipR = minb;
                        }
                    }
                    nodeL = Math.Min(nodeL, minb);
                    nodeR = Math.Max(nodeR, maxb);
                }
                // check for empty space
                if (nodeL > nodeBox.lo[axis] && nodeR < nodeBox.hi[axis])
                {
                    float nodeBoxW = nodeBox.hi[axis] - nodeBox.lo[axis];
                    float nodeNewW = nodeR - nodeL;
                    // node box is too big compare to space occupied by primitives?
                    if (1.3f * nodeNewW < nodeBoxW)
                    {
                        stats.updateBVH2();
                        int nextIndex1 = tempTree.Count();
                        // allocate child
                        tempTree.Add(0);
                        tempTree.Add(0);
                        tempTree.Add(0);
                        // write bvh2 clip node
                        stats.updateInner();
                        tempTree[nodeIndex + 0] = (uint)((axis << 30) | (1 << 29) | nextIndex1);
                        tempTree[nodeIndex + 1] = floatToRawIntBits(nodeL);
                        tempTree[nodeIndex + 2] = floatToRawIntBits(nodeR);
                        // update nodebox and recurse
                        nodeBox.lo[axis] = nodeL;
                        nodeBox.hi[axis] = nodeR;
                        subdivide(left, rightOrig, tempTree, dat, gridBox, nodeBox, nextIndex1, depth + 1, stats);
                        return;
                    }
                }
                // ensure we are making progress in the subdivision
                if (right == rightOrig)
                {
                    // all left
                    if (prevAxis == axis && MathFunctions.fuzzyEq(prevSplit, split))
                    {
                        // we are stuck here - create a leaf
                        stats.updateLeaf(depth, right - left + 1);
                        createNode(tempTree, nodeIndex, left, right);
                        return;
                    }
                    if (clipL <= split)
                    {
                        // keep looping on left half
                        gridBox.hi[axis] = split;
                        prevClip         = clipL;
                        wasLeft          = true;
                        continue;
                    }
                    gridBox.hi[axis] = split;
                    prevClip         = float.NaN;
                }
                else if (left > right)
                {
                    // all right
                    right = rightOrig;
                    if (prevAxis == axis && MathFunctions.fuzzyEq(prevSplit, split))
                    {
                        // we are stuck here - create a leaf
                        stats.updateLeaf(depth, right - left + 1);
                        createNode(tempTree, nodeIndex, left, right);
                        return;
                    }

                    if (clipR >= split)
                    {
                        // keep looping on right half
                        gridBox.lo[axis] = split;
                        prevClip         = clipR;
                        wasLeft          = false;
                        continue;
                    }
                    gridBox.lo[axis] = split;
                    prevClip         = float.NaN;
                }
                else
                {
                    // we are actually splitting stuff
                    if (prevAxis != -1 && !float.IsNaN(prevClip))
                    {
                        // second time through - lets create the previous split
                        // since it produced empty space
                        int nextIndex0 = tempTree.Count;
                        // allocate child node
                        tempTree.Add(0);
                        tempTree.Add(0);
                        tempTree.Add(0);
                        if (wasLeft)
                        {
                            // create a node with a left child
                            // write leaf node
                            stats.updateInner();
                            tempTree[nodeIndex + 0] = (uint)((prevAxis << 30) | nextIndex0);
                            tempTree[nodeIndex + 1] = floatToRawIntBits(prevClip);
                            tempTree[nodeIndex + 2] = floatToRawIntBits(float.PositiveInfinity);
                        }
                        else
                        {
                            // create a node with a right child
                            // write leaf node
                            stats.updateInner();
                            tempTree[nodeIndex + 0] = (uint)((prevAxis << 30) | (nextIndex0 - 3));
                            tempTree[nodeIndex + 1] = floatToRawIntBits(float.NegativeInfinity);
                            tempTree[nodeIndex + 2] = floatToRawIntBits(prevClip);
                        }
                        // count stats for the unused leaf
                        depth++;
                        stats.updateLeaf(depth, 0);
                        // now we keep going as we are, with a new nodeIndex:
                        nodeIndex = nextIndex0;
                    }
                    break;
                }
            }
            // compute index of child nodes
            int nextIndex = tempTree.Count;
            // allocate left node
            int nl = right - left + 1;
            int nr = rightOrig - (right + 1) + 1;

            if (nl > 0)
            {
                tempTree.Add(0);
                tempTree.Add(0);
                tempTree.Add(0);
            }
            else
            {
                nextIndex -= 3;
            }
            // allocate right node
            if (nr > 0)
            {
                tempTree.Add(0);
                tempTree.Add(0);
                tempTree.Add(0);
            }
            // write leaf node
            stats.updateInner();
            tempTree[nodeIndex + 0] = (uint)((axis << 30) | nextIndex);
            tempTree[nodeIndex + 1] = floatToRawIntBits(clipL);
            tempTree[nodeIndex + 2] = floatToRawIntBits(clipR);
            // prepare L/R child boxes
            AABound gridBoxL = gridBox;
            AABound gridBoxR = gridBox;
            AABound nodeBoxL = nodeBox;
            AABound nodeBoxR = nodeBox;

            gridBoxL.hi[axis] = gridBoxR.lo[axis] = split;
            nodeBoxL.hi[axis] = clipL;
            nodeBoxR.lo[axis] = clipR;
            // recurse
            if (nl > 0)
            {
                subdivide(left, right, tempTree, dat, gridBoxL, nodeBoxL, nextIndex, depth + 1, stats);
            }
            else
            {
                stats.updateLeaf(depth + 1, 0);
            }
            if (nr > 0)
            {
                subdivide(right + 1, rightOrig, tempTree, dat, gridBoxR, nodeBoxR, nextIndex + 3, depth + 1, stats);
            }
            else
            {
                stats.updateLeaf(depth + 1, 0);
            }
        }
 private static double besselJCoeff(int m, double alpha)
 {
     return(Math.Pow(-1, m) / (MathFunctions.factorial(m) * SpecialFunctions.lanchosGamma(m + alpha + 1)));
 }
예제 #30
0
        public void SendListInventory(ObjectGuid vendorGuid)
        {
            Creature vendor = GetPlayer().GetNPCIfCanInteractWith(vendorGuid, NPCFlags.Vendor, NPCFlags2.None);

            if (vendor == null)
            {
                Log.outDebug(LogFilter.Network, "WORLD: SendListInventory - {0} not found or you can not interact with him.", vendorGuid.ToString());
                GetPlayer().SendSellError(SellResult.CantFindVendor, null, ObjectGuid.Empty);
                return;
            }

            // remove fake death
            if (GetPlayer().HasUnitState(UnitState.Died))
            {
                GetPlayer().RemoveAurasByType(AuraType.FeignDeath);
            }

            // Stop the npc if moving
            vendor.PauseMovement(WorldConfig.GetUIntValue(WorldCfg.CreatureStopForPlayer));
            vendor.SetHomePosition(vendor.GetPosition());

            VendorItemData vendorItems  = vendor.GetVendorItems();
            int            rawItemCount = vendorItems != null?vendorItems.GetItemCount() : 0;

            VendorInventory packet = new();

            packet.Vendor = vendor.GetGUID();

            float discountMod = GetPlayer().GetReputationPriceDiscount(vendor);
            byte  count       = 0;

            for (uint slot = 0; slot < rawItemCount; ++slot)
            {
                VendorItem vendorItem = vendorItems.GetItem(slot);
                if (vendorItem == null)
                {
                    continue;
                }

                VendorItemPkt item = new();

                PlayerConditionRecord playerCondition = CliDB.PlayerConditionStorage.LookupByKey(vendorItem.PlayerConditionId);
                if (playerCondition != null)
                {
                    if (!ConditionManager.IsPlayerMeetingCondition(_player, playerCondition))
                    {
                        item.PlayerConditionFailed = (int)playerCondition.Id;
                    }
                }

                if (vendorItem.Type == ItemVendorType.Item)
                {
                    ItemTemplate itemTemplate = Global.ObjectMgr.GetItemTemplate(vendorItem.item);
                    if (itemTemplate == null)
                    {
                        continue;
                    }

                    int leftInStock = vendorItem.maxcount == 0 ? -1 : (int)vendor.GetVendorItemCurrentCount(vendorItem);
                    if (!GetPlayer().IsGameMaster())
                    {
                        if (!Convert.ToBoolean(itemTemplate.GetAllowableClass() & GetPlayer().GetClassMask()) && itemTemplate.GetBonding() == ItemBondingType.OnAcquire)
                        {
                            continue;
                        }

                        if ((itemTemplate.GetFlags2().HasAnyFlag(ItemFlags2.FactionHorde) && GetPlayer().GetTeam() == Team.Alliance) ||
                            (itemTemplate.GetFlags2().HasAnyFlag(ItemFlags2.FactionAlliance) && GetPlayer().GetTeam() == Team.Horde))
                        {
                            continue;
                        }

                        if (leftInStock == 0)
                        {
                            continue;
                        }
                    }

                    if (!Global.ConditionMgr.IsObjectMeetingVendorItemConditions(vendor.GetEntry(), vendorItem.item, _player, vendor))
                    {
                        Log.outDebug(LogFilter.Condition, "SendListInventory: conditions not met for creature entry {0} item {1}", vendor.GetEntry(), vendorItem.item);
                        continue;
                    }

                    int price = (int)(vendorItem.IsGoldRequired(itemTemplate) ? Math.Floor(itemTemplate.GetBuyPrice() * discountMod) : 0);

                    int priceMod = GetPlayer().GetTotalAuraModifier(AuraType.ModVendorItemsPrices);
                    if (priceMod != 0)
                    {
                        price -= MathFunctions.CalculatePct(price, priceMod);
                    }

                    item.MuID                = (int)slot + 1;
                    item.Durability          = (int)itemTemplate.MaxDurability;
                    item.ExtendedCostID      = (int)vendorItem.ExtendedCost;
                    item.Type                = (int)vendorItem.Type;
                    item.Quantity            = leftInStock;
                    item.StackCount          = (int)itemTemplate.GetBuyCount();
                    item.Price               = (ulong)price;
                    item.DoNotFilterOnVendor = vendorItem.IgnoreFiltering;
                    item.Refundable          = (itemTemplate.GetFlags() & ItemFlags.ItemPurchaseRecord) != 0 && vendorItem.ExtendedCost != 0 && itemTemplate.GetMaxStackSize() == 1;

                    item.Item.ItemID = vendorItem.item;
                    if (!vendorItem.BonusListIDs.Empty())
                    {
                        item.Item.ItemBonus.HasValue           = true;
                        item.Item.ItemBonus.Value.BonusListIDs = vendorItem.BonusListIDs;
                    }

                    packet.Items.Add(item);
                }
                else if (vendorItem.Type == ItemVendorType.Currency)
                {
                    CurrencyTypesRecord currencyTemplate = CliDB.CurrencyTypesStorage.LookupByKey(vendorItem.item);
                    if (currencyTemplate == null)
                    {
                        continue;
                    }

                    if (vendorItem.ExtendedCost == 0)
                    {
                        continue;                             // there's no price defined for currencies, only extendedcost is used
                    }
                    item.MuID                = (int)slot + 1; // client expects counting to start at 1
                    item.ExtendedCostID      = (int)vendorItem.ExtendedCost;
                    item.Item.ItemID         = vendorItem.item;
                    item.Type                = (int)vendorItem.Type;
                    item.StackCount          = (int)vendorItem.maxcount;
                    item.DoNotFilterOnVendor = vendorItem.IgnoreFiltering;

                    packet.Items.Add(item);
                }
                else
                {
                    continue;
                }

                if (++count >= SharedConst.MaxVendorItems)
                {
                    break;
                }
            }

            SendPacket(packet);
        }
        /**
         * Calculates the inverse error function evaluated at x.
         * @param x
         * @param invert
         * @return
         */
        private static double erfImp(double z, bool invert)
        {
            if (z < 0)
            {
                if (!invert)
                {
                    return(-erfImp(-z, false));
                }
                if (z < -0.5)
                {
                    return(2 - erfImp(-z, true));
                }
                return(1 + erfImp(-z, false));
            }
            double result;

            if (z < 0.5)
            {
                if (z < 1e-10)
                {
                    result = (z * 1.125) + (z * 0.003379167095512573896158903121545171688);
                }
                else
                {
                    result = (z * 1.125) + (z * Evaluate.polynomial(z, Coefficients.erfImpAn) / Evaluate.polynomial(z, Coefficients.erfImpAd));
                }
            }
            else if ((z < 110) || ((z < 110) && invert))
            {
                invert = !invert;
                double r, b;
                if (z < 0.75)
                {
                    r = Evaluate.polynomial(z - 0.5, Coefficients.erfImpBn) / Evaluate.polynomial(z - 0.5, Coefficients.erfImpBd);
                    b = 0.3440242112F;
                }
                else if (z < 1.25)
                {
                    r = Evaluate.polynomial(z - 0.75, Coefficients.erfImpCn) / Evaluate.polynomial(z - 0.75, Coefficients.erfImpCd);
                    b = 0.419990927F;
                }
                else if (z < 2.25)
                {
                    r = Evaluate.polynomial(z - 1.25, Coefficients.erfImpDn) / Evaluate.polynomial(z - 1.25, Coefficients.erfImpDd);
                    b = 0.4898625016F;
                }
                else if (z < 3.5)
                {
                    r = Evaluate.polynomial(z - 2.25, Coefficients.erfImpEn) / Evaluate.polynomial(z - 2.25, Coefficients.erfImpEd);
                    b = 0.5317370892F;
                }
                else if (z < 5.25)
                {
                    r = Evaluate.polynomial(z - 3.5, Coefficients.erfImpFn) / Evaluate.polynomial(z - 3.5, Coefficients.erfImpFd);
                    b = 0.5489973426F;
                }
                else if (z < 8)
                {
                    r = Evaluate.polynomial(z - 5.25, Coefficients.erfImpGn) / Evaluate.polynomial(z - 5.25, Coefficients.erfImpGd);
                    b = 0.5571740866F;
                }
                else if (z < 11.5)
                {
                    r = Evaluate.polynomial(z - 8, Coefficients.erfImpHn) / Evaluate.polynomial(z - 8, Coefficients.erfImpHd);
                    b = 0.5609807968F;
                }
                else if (z < 17)
                {
                    r = Evaluate.polynomial(z - 11.5, Coefficients.erfImpIn) / Evaluate.polynomial(z - 11.5, Coefficients.erfImpId);
                    b = 0.5626493692F;
                }
                else if (z < 24)
                {
                    r = Evaluate.polynomial(z - 17, Coefficients.erfImpJn) / Evaluate.polynomial(z - 17, Coefficients.erfImpJd);
                    b = 0.5634598136F;
                }
                else if (z < 38)
                {
                    r = Evaluate.polynomial(z - 24, Coefficients.erfImpKn) / Evaluate.polynomial(z - 24, Coefficients.erfImpKd);
                    b = 0.5638477802F;
                }
                else if (z < 60)
                {
                    r = Evaluate.polynomial(z - 38, Coefficients.erfImpLn) / Evaluate.polynomial(z - 38, Coefficients.erfImpLd);
                    b = 0.5640528202F;
                }
                else if (z < 85)
                {
                    r = Evaluate.polynomial(z - 60, Coefficients.erfImpMn) / Evaluate.polynomial(z - 60, Coefficients.erfImpMd);
                    b = 0.5641309023F;
                }
                else
                {
                    r = Evaluate.polynomial(z - 85, Coefficients.erfImpNn) / Evaluate.polynomial(z - 85, Coefficients.erfImpNd);
                    b = 0.5641584396F;
                }
                double g = MathFunctions.exp(-z * z) / z;
                result = (g * b) + (g * r);
            }
            else
            {
                result = 0;
                invert = !invert;
            }
            if (invert)
            {
                result = 1 - result;
            }
            return(result);
        }
예제 #32
0
        /// <summary>
        /// the sum of outbid is (1% from current bid)*5, if bid is very small, it is 1c
        /// </summary>
        /// <returns></returns>
        public uint GetAuctionOutBid()
        {
            uint outbid = MathFunctions.CalculatePct(bid, 5);

            return(outbid != 0 ? outbid : 1);
        }
 /**
  * Gamma function for the integers
  * @param n Integer number
  * @return  Returns Gamma function for the integers.
  */
 private static double gammaInt(long n)
 {
     if (n == 0)
     {
         return(MathConstants.EULER_MASCHERONI);
     }
     if (n == 1)
     {
         return(1);
     }
     if (n == 2)
     {
         return(1);
     }
     if (n == 3)
     {
         return(1.0 * 2.0);
     }
     if (n == 4)
     {
         return(1.0 * 2.0 * 3.0);
     }
     if (n == 5)
     {
         return(1.0 * 2.0 * 3.0 * 4.0);
     }
     if (n == 6)
     {
         return(1.0 * 2.0 * 3.0 * 4.0 * 5.0);
     }
     if (n == 7)
     {
         return(1.0 * 2.0 * 3.0 * 4.0 * 5.0 * 6.0);
     }
     if (n == 8)
     {
         return(1.0 * 2.0 * 3.0 * 4.0 * 5.0 * 6.0 * 7.0);
     }
     if (n == 9)
     {
         return(1.0 * 2.0 * 3.0 * 4.0 * 5.0 * 6.0 * 7.0 * 8.0);
     }
     if (n == 10)
     {
         return(1.0 * 2.0 * 3.0 * 4.0 * 5.0 * 6.0 * 7.0 * 8.0 * 9.0);
     }
     if (n >= 11)
     {
         return(MathFunctions.factorial(n - 1));
     }
     //if (n == -1) return MathConstants.EULER_MASCHERONI - 1;
     if (n <= -1)
     {
         long   r     = -n;
         double factr = MathFunctions.factorial(r);
         double sign  = -1;
         if (r % 2 == 0)
         {
             sign = 1;
         }
         return(sign / (r * factr) - (1.0 / r) * gammaInt(n + 1));
     }
     return(Double.NaN);
 }
예제 #34
0
        public JsonResult Forecast(DateTime?date, string forecastMethod, string spikesPreprocessMethod, double spikesThreshold,
                                   string forecastModel, string timeHorizon, double confidence, string MathModel, string exogenousVariables)
        {
            var dt  = date.HasValue ? date.Value : DateTime.Today;
            var ths = GetUnionCaseNames <Types.TimeHorizon>();

            var forecastHorizon   = Array.IndexOf(ths, timeHorizon);
            var forecastingMethod = GetUnionCaseFromName <ForecastMethod>(forecastMethod);

            if (forecastHorizon < 0)
            {
                throw new ArgumentException("Wrong argument");
            }

            //naive hardcoded for now...
            //data to estimate on is not an input parameter...
            var d = AppData.GetHistoricalSeries(_timeSeries);

            var data = d.Where(x => x.DateTime < dt)
                       .Select(x => x.Value != null ? (double)x.Value : 0) //0 for now, when interpolation is done... etc..
                       .ToArray();

            var spikesPreprocess = GetUnionCaseFromName <SpikePreprocess>(spikesPreprocessMethod);

            if (spikesPreprocess.IsSimilarDay)
            {
                //First deseasonalize data at larger lags, all >= weekly, a stable series is need since spikes are at lengths <= day
                var desezonalizedData = Desezonalize(data, 168);

                //Then perform the spike estimation
                var spikeIndices = EstimateSpikesOnMovSDs(desezonalizedData, 24, 2, spikesThreshold);

                //go ahead and pre process the d series... yeah...
                data = ReplaceSingularSpikes(data, spikeIndices, spikesPreprocess, 0.95);
            }

            var horizon = GetTimeHorizonValue(forecastHorizon);

            var rlzd = d.Where(x => x.DateTime >= dt)
                       .Take(horizon)
                       .Select(x => x.Value != null ? (double)x.Value : 0) //0 for now, when interpolation is done... etc..
                       .ToArray();

            ForecastResult forecast;

            double[] forecasted;
            object   model;

            var oneYear  = (int)Math.Floor((dt - dt.AddMonths(-12)).TotalHours);
            var halfYear = (int)Math.Floor((dt - dt.AddMonths(-6)).TotalHours);

            var seasons = new int[] { oneYear, halfYear, 24 * 7 * 4 * 3, 24 * 7 * 4, 24 * 7, 24 };

            //we need always seasonalities >= forecast horizon
            var relevantSeasons = seasons.Where(s => s >= horizon).ToArray();

            double[] estimationData = null;

            //add naive with exogenous variables next...
            if (forecastingMethod == ForecastMethod.Naive)
            {
                forecast = Naive(data, relevantSeasons, horizon, confidence);

                forecasted = forecast.Forecast.Take(rlzd.Length).ToArray();

                model = new object();
            }
            else if (forecastingMethod == ForecastMethod.HoltWinters)
            {
                estimationData = data.Reverse().Take(24 * 7 * 2).Reverse().ToArray();

                var hwparams = JsonConvert.DeserializeObject <HoltWinters.HoltWintersParams>(MathModel);

                //optimize if all seem to be wrong
                if (hwparams.alpha == 0 || hwparams.beta == 0 || hwparams.gamma == 0)
                {
                    hwparams = HoltWinters.OptimizeTripleHWT(estimationData, 24, horizon);
                }

                forecast = HoltWinters.TripleHWTWithPIs(estimationData, 24, horizon, hwparams, confidence);

                forecasted = forecast.Forecast.Take(rlzd.Length).ToArray();

                model = hwparams;
            }
            else if (forecastingMethod == ForecastMethod.ARMA)
            {
                var exogenousVariablesJs = JObject.Parse(exogenousVariables); //alternative...?

                //always take next 2 highest seasons...
                var maSes = seasons.Where(s => s >= horizon).OrderBy(x => x).Take(2).ToArray();
                var arSes = new int[] { 1, 2, 24, 25 };

                //twice as the highest season estimation data
                var estimationDataLength = maSes.Last() * 2;
                estimationData = data.Reverse().Take(estimationDataLength).Reverse().ToArray();

                var isUnivariate = exogenousVariablesJs.Properties().Where(p => p.Value.ToString() == "True").Count() == 0;

                if (isUnivariate)
                {
                    var arma = JsonConvert.DeserializeObject <ARMAResult>(MathModel);

                    //problem: when changing param for ARMA, provide forecast, when changed date or horizon, re-estimate...yes...
                    //fix it later
                    if (arma.AR == null || arma.AR.Coefficients == null)
                    {
                    }

                    arma = ARMASimple2(estimationData, arSes, maSes);

                    var inSampleRes = Infer(arma, estimationData);

                    forecast = MarketModels.TimeSeries.Forecast(estimationData, inSampleRes, arma, horizon, confidence);

                    //when done out of sample, matches the realized and forecasted lengths to compute fit...
                    //if no available data, no fit can be done...
                    forecasted = forecast.Forecast.Take(rlzd.Length).ToArray();

                    //allow only AR and MA coefficients to be changed
                    //model = new { AR = arma.AR, MA = arma.MA };
                    model = null;
                }
                else
                {
                    var arxma = JsonConvert.DeserializeObject <ARXMAModel>(MathModel);

                    var vars = exogenousVariablesJs.Properties()
                               .Where(p => p.Value.ToString() == "True")
                               .Select(p => p.Name)
                               .ToList();

                    var specialDaysSelected = vars.Remove("SpecialWeekDays");

                    var exData = vars
                                 .Select(p =>
                                         AppData.GetHistoricalSeries(_exVarsPre + p + "_Hourly_All.json")
                                         .Where(x => x.DateTime < dt)
                                         .Select(x => x.Value != null ? (double)x.Value : 0) //0 for now, when interpolation is done... etc..
                                         .Reverse().Take(estimationDataLength + horizon).Reverse().ToArray()
                                         .ToList()
                                         ).ToList().ColumnsToRectangularArray();

                    //append indicators for special data...
                    if (specialDaysSelected)
                    {
                        //Friday, Saturday and Sunday
                        var ivars = MathFunctions.IndicatorVariablesMatrix(estimationDataLength + horizon, 168, 24, new int[] { 0, 5, 6 });

                        //concatenate matrices to columns
                        if (exData.GetLength(1) > 0)
                        {
                            exData = MathFunctions.concat2D(exData, ivars, false);
                        }
                        else
                        {
                            exData = ivars;
                        }
                    }

                    var exDataEst = MathFunctions.firstRows2D(exData, estimationDataLength);

                    arxma = ARXMASimple2(estimationData, exDataEst, arSes, maSes);

                    var inSampleRes = arxma.Infer(estimationData, exDataEst);

                    forecast = arxma.Forecast(estimationData, inSampleRes, exData, horizon, confidence);

                    //when done out of sample, matches the realized and forecasted lengths to compute fit...
                    //if no available data, no fit can be done...
                    forecasted = forecast.Forecast.Take(rlzd.Length).ToArray();

                    //allow only AR and MA coefficients to be changed
                    //model = new { AR = arma.AR, MA = arma.MA };
                    model = null;
                }
            }
            else
            {
                throw new ArgumentException("Unsupported argument passed");
            }

            var log = "";

            if (forecast.Forecast.Any(x => x > 500))
            {
                log += "Some data is wrong...";
            }

            if (forecast.Forecast.HasInvalidData() || forecast.Confidence.HasInvalidData())
            {
                throw new Exception("Abnormal results generated");
            }

            /* Post processing */
            //cap all values above a reasonable limit, e.g. 500
            CapSeries(forecast.Forecast, 500, -100);
            CapMultipleSeries(forecast.Confidence, 500, -100);

            FitStatistics eFit = null, eBFit = null, ePFit = null, fit = null, bfit = null, pfit = null;

            if (rlzd.Length > 0)
            {
                fit  = ForecastFit(forecasted, rlzd);
                pfit = ForecastFit(
                    GetSubPeriodsFrom(forecasted, 24, DAY_PEAK_HOURS),
                    GetSubPeriodsFrom(rlzd, 24, DAY_PEAK_HOURS));
                bfit = ForecastFit(
                    GetSubPeriodsFrom(forecasted, 24, DAY_BASE_HOURS),
                    GetSubPeriodsFrom(rlzd, 24, DAY_BASE_HOURS));
            }

            if (estimationData != null && forecast.Backcast.Length > 0)
            {
                //model with estimation, that is: the model is different than naive
                eFit  = ForecastFit(forecast.Backcast, estimationData);
                ePFit = ForecastFit(
                    GetSubPeriodsFrom(forecast.Backcast, 24, DAY_PEAK_HOURS),
                    GetSubPeriodsFrom(estimationData, 24, DAY_PEAK_HOURS));
                eBFit = ForecastFit(
                    GetSubPeriodsFrom(forecast.Backcast, 24, DAY_BASE_HOURS),
                    GetSubPeriodsFrom(estimationData, 24, DAY_BASE_HOURS));
            }
            var obj = new
            {
                Result    = forecast,
                MathModel = model,
                DaysAhead = horizon / 24,
                //in sample fit for all hours
                EstimationFit     = eFit,
                BaseEstimationFit = eBFit,
                PeakEstimationFit = ePFit,
                Fit     = fit,
                BaseFit = bfit, //refine later...
                PeakFit = pfit,
                //additional remarks about the resulting data...
                Log = log
            };

            return(Json(obj, JsonRequestBehavior.AllowGet));
        }
        /**
         * Gamma function implementation based on
         * Lanchos approximation algorithm
         *
         * @param x    Function parameter
         * @return     Gamma function value (Lanchos approx).
         */
        public static double lanchosGamma(double x)
        {
            if (Double.IsNaN(x))
            {
                return(Double.NaN);
            }

            double xabs = MathFunctions.abs(x);
            double xint = Math.Round(xabs);

            if (x > BinaryRelations.DEFAULT_COMPARISON_EPSILON)
            {
                if (MathFunctions.abs(xabs - xint) <= BinaryRelations.DEFAULT_COMPARISON_EPSILON)
                {
                    return(MathFunctions.factorial(xint - 1));
                }
            }
            else if (x < -BinaryRelations.DEFAULT_COMPARISON_EPSILON)
            {
                if (MathFunctions.abs(xabs - xint) <= BinaryRelations.DEFAULT_COMPARISON_EPSILON)
                {
                    return(Double.NaN);
                }
            }
            else
            {
                return(Double.NaN);
            }
            if (x < 0.5)
            {
                return(MathConstants.PI / (MathFunctions.sin(MathConstants.PI * x) * lanchosGamma(1 - x)));
            }
            int g = 7;

            x -= 1;
            double a = Coefficients.lanchosGamma[0];
            double t = x + g + 0.5;

            for (int i = 1; i < Coefficients.lanchosGamma.Length; i++)
            {
                a += Coefficients.lanchosGamma[i] / (x + i);
            }
            return(MathFunctions.sqrt(2 * MathConstants.PI) * MathFunctions.power(t, x + 0.5) * MathFunctions.exp(-t) * a);
        }
예제 #36
0
		private double midPointIteration(MathFunctions.UnaryFunction<double> f, double a, double b, double estimate, int n)
		{
			double sum = 0;
			double stepSize = (b - a) / n;
			double stepSizeMid = stepSize * (2/3);
			double x = a + (stepSize / 6);

			for (int i = 0; i < n; i++, x += stepSize)
			{
				sum += f(x) + f(x + stepSizeMid);
			}

			return (estimate + (stepSize*sum))/3;
		}
        /**
         * Real valued log gamma function.
         * @param x
         * @return  Returns log value from gamma function.
         */
        public static double logGamma(double x)
        {
            if (Double.IsNaN(x))
            {
                return(Double.NaN);
            }
            if (Double.IsPositiveInfinity(x))
            {
                return(Double.PositiveInfinity);
            }
            if (Double.IsNegativeInfinity(x))
            {
                return(Double.NaN);
            }
            if (MathFunctions.isInteger(x))
            {
                if (x >= 0)
                {
                    return(MathFunctions.ln(Math.Abs(gammaInt((long)(Math.Round(x))))));
                }
                else
                {
                    return(MathFunctions.ln(Math.Abs(gammaInt(-(long)(Math.Round(-x))))));
                }
            }
            double p, q, w, z;

            if (x < -34.0)
            {
                q = -x;
                w = logGamma(q);
                p = Math.Floor(q);
                if (p == q)
                {
                    return(Double.NaN);
                }
                z = q - p;
                if (z > 0.5)
                {
                    p += 1.0;
                    z  = p - q;
                }
                z = q * Math.Sin(Math.PI * z);
                if (z == 0.0)
                {
                    return(Double.NaN);
                }
                z = MathConstants.LNPI - Math.Log(z) - w;
                return(z);
            }
            if (x < 13.0)
            {
                z = 1.0;
                while (x >= 3.0)
                {
                    x -= 1.0;
                    z *= x;
                }
                while (x < 2.0)
                {
                    if (x == 0.0)
                    {
                        return(Double.NaN);
                    }
                    z /= x;
                    x += 1.0;
                }
                if (z < 0.0)
                {
                    z = -z;
                }
                if (x == 2.0)
                {
                    return(Math.Log(z));
                }
                x -= 2.0;
                p  = x * Evaluate.polevl(x, Coefficients.logGammaB, 5) / Evaluate.p1evl(x, Coefficients.logGammaC, 6);
                return(Math.Log(z) + p);
            }
            if (x > 2.556348e305)
            {
                return(Double.NaN);
            }
            q = (x - 0.5) * Math.Log(x) - x + 0.91893853320467274178;
            if (x > 1.0e8)
            {
                return(q);
            }
            p = 1.0 / (x * x);
            if (x >= 1000.0)
            {
                q += ((7.9365079365079365079365e-4 * p - 2.7777777777777777777778e-3) * p + 0.0833333333333333333333) / x;
            }
            else
            {
                q += Evaluate.polevl(p, Coefficients.logGammaA, 4) / x;
            }
            return(q);
        }
        /// <summary>
        /// Integrates a given function within the given integral.
        /// </summary>
        /// <param name="f">The function to integrate.</param>
        /// <param name="a">The lower limit.</param>
        /// <param name="b">The higher limit.</param>
        /// <returns>
        /// The integral of <paramref name="function"/> over the interval from <paramref name="a"/> to <paramref name="b"/>
        /// </returns>
        public float Integrate(MathFunctions.FloatUnaryFunction f, float a, float b)
        {
            // Check the _romD field is initialized correctly.
            if ((_romF == null) || (_romF.GetLength(1) == _order))
            {
                _romF = new float[1, _order];
            }

            if (a > b) return Integrate(f, b, a);

            float h = (b-a);

            _romF[0,0] = 0.5f*h*(f(a) + f(b));
            for (int i = 2, ipower = 1; i <= _order; i++, ipower *= 2, h /= 2)
            {
                // Approximation using the trapezoid rule.
                float sum = 0;
                for (int j = 1; j <= ipower; j++)
                {
                    sum += f(a + h*(j-0.5f));
                }

                // Richardson extrapolation
                _romF[1,0] = 0.5f * (_romF[0,0] + (h*sum));
                for (int k = 1, kpower = 4; i < i; k++, kpower *= 4)
                {
                    _romF[1,k] = (kpower*_romF[1, k-1] - _romF[0,k-1]) / (kpower-1);
                }

                // Save the extrapolated values for the next iteration
                for (int j = 0; j < i; j++)
                {
                    _romF[0, j] = _romF[1, j];
                }
            }

            return _romF[0,_order-1];
        }
        /// <summary>
        /// Integrates a given function within the given integral.
        /// </summary>
        /// <param name="f">The function to integrate.</param>
        /// <param name="a">The lower limit.</param>
        /// <param name="b">The higher limit.</param>
        /// <returns>
        /// The integral of <paramref name="function"/> over the interval from <paramref name="a"/> to <paramref name="b"/>
        /// </returns>
        public double Integrate(MathFunctions.DoubleUnaryFunction f, double a, double b)
        {
            if (a > b)  return -Integrate(f, b, a);

            double sum = 0;
            double stepSize = (b-a)/_stepsNumber;
            double stepSizeDiv3 = stepSize/3;
            for (int i = 0; i < _stepsNumber; i = i+2)
            {
                sum += (f(a + i*stepSize) + 4*f(a+(i+1)*stepSize) + f(a+(i+2)*stepSize))*stepSizeDiv3;
            }

            return sum;
        }