Inheritance: IMessageConsumer
Beispiel #1
0
 /// <summary>
 /// Creates a new tick timer that can fire a completition action timeout.
 /// </summary>
 /// <param name="game">The game timer belongs to</param>
 /// <param name="timeoutTick">Exact tick value to timeout</param>
 /// <param name="completionCallback">The completition action to be called on timeout</param>
 public TickTimer(Game game, int timeoutTick, Action<int> completionCallback = null)
 {
     if (timeoutTick <= game.TickCounter)
         throw new ArgumentOutOfRangeException("timeoutTick", string.Format("timeoutTick value {0} can not be equal or less then timer's belonging game's current TickCounter value {1}.", timeoutTick, game.TickCounter));
                                                   
     this.Game = game;
     this.TimeoutTick = timeoutTick;
     this.CompletionAction = completionCallback;
 }
Beispiel #2
0
        public static Game CreateGame(int gameId)
        {
            if (Games.ContainsKey(gameId))
                return Games[gameId];

            var game = new Game(gameId);
            Games.Add(gameId, game);
            return game;
        }
Beispiel #3
0
        /// <summary>
        /// Creates a new stepped tick timer.
        /// </summary>
        /// <param name="game">The game timer belongs to.</param>
        /// <param name="ticksPerStep">Ticks taken per step.</param>
        /// <param name="timeoutTick">Exact tick value to timeout.</param>
        /// <param name="stepCallback">The action to be called on each step.</param>
        /// <param name="completionCallback">The completition action to be called on timeout.</param>
        public SteppedTickTimer(Game game, int ticksPerStep, int timeoutTick, Action<int> stepCallback, Action<int> completionCallback = null)
            : base(game, timeoutTick, completionCallback)
        {
            if (ticksPerStep < game.TickRate)
                throw new ArgumentOutOfRangeException("ticksPerStep", string.Format("ticksPerStep value ({0}) can not be less then timer's belonging game's TickRate ({1}).", ticksPerStep, game.TickRate));

            this.TicksPerStep = ticksPerStep;
            this.StepAction = stepCallback;
            this.LastStepTick = game.TickCounter;
        }
Beispiel #4
0
 /// <summary>
 /// Creates a new tick timer that can fire a completition action timeout.
 /// </summary>
 /// <param name="game">The game timer belongs to</param>
 /// <param name="timeoutTick">Exact tick value to timeout</param>
 /// <param name="completionCallback">The completition action to be called on timeout</param>
 public TickTimer(Game game, int timeoutTick, Action<int> completionCallback = null)
 {
     // Some code that was calculating movement ticks was rounding the tick difference to 0 for really small
     // movements sometimes and thus would cause this exception. Enforcing every timer created to not 
     // already be timed out doesn't seem necessary and having to worry about it just complicates things. /mdz
     //if (timeoutTick <= game.TickCounter)
     //    throw new ArgumentOutOfRangeException("timeoutTick", string.Format("timeoutTick value {0} can not be equal or less then timer's belonging game's current TickCounter value {1}.", timeoutTick, game.TickCounter));
                                                   
     this.Game = game;
     this.TimeoutTick = timeoutTick;
     this.CompletionAction = completionCallback;
 }
Beispiel #5
0
        // Hardcoded world generate to load first scene in new tristram on top of hill
        public static World Generate(Game game)
        {
            var world = new World(game, 71150);

            var scene = new Scene(world, new Vector3D(0, 0, 0), 33349, null)
            {
                MiniMapVisibility = true,
                SceneGroupSNO = -1,
                Specification = new SceneSpecification
                {
                    CellZ = 0,
                    Cell = new Vector2D{ X = 51, Y = 46 },
                    SNOLevelAreas = new int[] { 0x00004DEB, 0x00026186, -1, -1 },
                    SNOPrevWorld = -1,
                    Unknown1 = 0,
                    SNOPrevLevelArea = -1,
                    SNONextWorld = -1,
                    Unknown2 = 0,
                    SNONextLevelArea = -1,
                    SNOMusic = 0x000206F8,
                    SNOCombatMusic = -1,
                    SNOAmbient = 0x0002734F,
                    SNOReverb = 0x000375D0,
                    SNOWeather = 0x00013220,
                    SNOPresetWorld = 0x000115EE,
                    Unknown3 = -1,
                    Unknown4 = -1,
                    Unknown5 = 0,
                    ClusterID = -1,
                    SceneCachedValues = new SceneCachedValues
                    {
                        Unknown1 = 63,
                        Unknown2 = 96,
                        Unknown3 = 96,
                        Unknown4 = new int[] { 0, 0x4C8, 0, 0 },
                        Unknown5 = 9,
                        AABB1 = new Common.Types.Collision.AABB { Max = new Vector3D { X = 115.9387f, Y = 125.2578f, Z = 43.82879f }, Min = new Vector3D { X = 124.0615f, Y = 131.6655f, Z = 57.26923f } },
                        AABB2 = new Common.Types.Collision.AABB { Max = new Vector3D { X = 115.9387f, Y = 125.2578f, Z = 43.82879f }, Min = new Vector3D { X = 124.0615f, Y = 131.6655f, Z = 57.26923f } },
                    },
                },
                RotationAxis = new Vector3D{ X = 0.0f, Y = 0.0f, Z = 0.0f },
                RotationW = 1.0f,
                Position = new Vector3D { X = 3060.0f, Y = 2760.0f, Z = 0.0f },
            };

            scene.LoadMarkers();

            return world;
        }
Beispiel #6
0
                public QuestObjective(Game game, Mooege.Common.MPQ.FileFormats.QuestStepObjective objective, QuestStep questStep, int id)
                {
                    ID = id;
                    this.objective = objective;
                    this.questStep = questStep;
                    this.game = game;

                    //TODO: Rewrite all this as quests should subscribe to events and not objects notify quests
                    if (this.objective.ObjectiveType == Mooege.Common.MPQ.FileFormats.QuestStepObjectiveType.KillGroup)
                    {
                        logger.Debug("KillGroup objective");
                        foreach( var world in game._worlds.Values)
                        {
                            //subscribe to each actor in group destroy/kill event
                            var spawnerGroupActors = world.GetActorsInGroup(this.objective.Group1Name);
                            //
                            foreach (var actor in spawnerGroupActors)
                            {
                                if (actor is Spawner)
                                {
                                    (actor as Spawner).Spawn();
                                }

                            }

                            var groupActors = world.GetActorsInGroup(this.objective.Group1Name);
                            foreach (var actor in groupActors)
                            {
                                actor.ActorKilled += new EventHandler(actor_ActorKilled);
                            }
                        }                        
                    }
                    if (this.objective.ObjectiveType == Mooege.Common.MPQ.FileFormats.QuestStepObjectiveType.KillMonster)
                    {
                    }
                }
Beispiel #7
0
        private List<int> completedSteps = new List<int>();           // this list has to be saved if quest progress should be saved. It is required to keep track of questranges

        public Quest(Game game, int SNOQuest)
        {
            this.game = game;
            //SNOId = SNOQuest;
            SNOName = new SNOName() { SNOId = SNOQuest, Group = SNOGroup.Quest };
            asset = MPQStorage.Data.Assets[Common.Types.SNO.SNOGroup.Quest][SNOQuest].Data as Mooege.Common.MPQ.FileFormats.Quest;
            CurrentStep = new QuestStep(asset.QuestUnassignedStep, this);
        }
Beispiel #8
0
 /// <summary>
 /// Creates a new mili-seconds based tick timer.
 /// </summary>
 /// <param name="game">The game timer belongs to.</param>
 /// <param name="miliSeconds">MiliSeconds taken to timeout.</param>
 /// <param name="completionCallback">The completition action to be called on timeout.</param>
 /// <returns><see cref="SteppedTickTimer"/></returns>
 public MiliSecondsTickTimer(Game game, float miliSeconds, Action<int> completionCallback = null)
     : base(game, (int)((1000f / game.UpdateFrequency * game.TickRate) / 1000f * miliSeconds), completionCallback)
 { }
Beispiel #9
0
 /// <summary>
 /// Creates a new relative tick timer.
 /// </summary>
 /// <param name="game">The game timer belongs to.</param>
 /// <param name="ticks">Relative tick amount taken to timeout.</param>
 /// <param name="completionCallback">The completition action to be called on timeout.</param>
 public RelativeTickTimer(Game game, int ticks, Action<int> completionCallback = null)
     : base(game, game.TickCounter + ticks, completionCallback)
 { }
Beispiel #10
0
 /// <summary>
 /// Creates a new mili-seconds based tick timer.
 /// </summary>
 /// <param name="game">The game timer belongs to.</param>
 /// <param name="miliSeconds">MiliSeconds taken to timeout.</param>
 /// <param name="completionCallback">The completition action to be called on timeout.</param>
 /// <returns><see cref="SteppedTickTimer"/></returns>
 public static TickTimer WaitMiliSeconds(Game game, float miliSeconds, Action<int> completionCallback = null)
 {
     return new MiliSecondsTickTimer(game, miliSeconds, completionCallback);
 }
Beispiel #11
0
 /// <summary>
 /// Creates a new tick timer.
 /// </summary>
 /// <param name="game">The game timer belongs to.</param>
 /// <param name="ticks">Relative tick amount taken to timeout.</param>
 /// <param name="completionCallback">The completition action to be called on timeout.</param>
 /// <returns><see cref="SteppedTickTimer"/></returns>
 public static TickTimer WaitTicks(Game game, int ticks, Action<int> completionCallback = null)
 {
     return new RelativeTickTimer(game, ticks, completionCallback);
 }
Beispiel #12
0
        public Quest(Game game, int SNOQuest)
        {
            this.game = game;
            SNOHandle = new SNOHandle(SNOGroup.Quest, SNOQuest);
            asset = SNOHandle.Target as Mooege.Common.MPQ.FileFormats.Quest;
            CurrentStep = new QuestStep(asset.QuestUnassignedStep, this);

            //erekose
            foreach (var QCSasset in asset.QuestCompletionSteps)
            {
                if (QCSasset != null)
                {
                    var nQCS = new QuestCompletionStep(QCSasset);
                    QuestCompletionSteps.Add(nQCS);
                    // Logger.Debug(" (quest ctor)  adding a completion step {0}, {1}, {2} ", nQCS.Name, nQCS.StepId, nQCS.I2);
                }
                else
                {
                    // Logger.Debug(" (quest ctor)  asset null problem in QCS ");
                }

            }

            //foreach (var aQuestStep in asset.QuestSteps)
            //{
            //     Logger.Debug(" (quest ctor) steps ID contained in quest is : {0} ", aQuestStep.ID);
            //}


            // Logger.Debug(" (quest ctor)  SNOHandle ID {0} Name {1}  Group {2} isValid ?{3} ", SNOHandle.Id, SNOHandle.Name, SNOHandle.Group, SNOHandle.IsValid);
            // Logger.Debug(" (quest ctor)  from assets  numSteps {0}, SNO ID {1} num od completion step  ", asset.NumberOfSteps, asset.Header.SNOId, asset.NumberOfCompletionSteps);
            // Logger.Debug(" (quest ctor)  CurrentStep ID ", CurrentStep.QuestStepID);
            
        }
Beispiel #13
0
        private List<int> completedSteps = new List<int>();           // this list has to be saved if quest progress should be saved. It is required to keep track of questranges

        public Quest(Game game, int SNOQuest)
        {
            this.game = game;
            SNOHandle = new SNOHandle(SNOGroup.Quest, SNOQuest);
            asset = SNOHandle.Target as Mooege.Common.MPQ.FileFormats.Quest;
            CurrentStep = new QuestStep(asset.QuestUnassignedStep, this);
        }
        public static World Generate(Game game, int worldSNO)
        {
            if (!MPQStorage.Data.Assets[SNOGroup.Worlds].ContainsKey(worldSNO))
            {
                Logger.Error("Can't find a valid world definition for sno: {0}", worldSNO);
                return null;
            }

            var worldAsset = MPQStorage.Data.Assets[SNOGroup.Worlds][worldSNO];
            var worldData = (Mooege.Common.MPQ.FileFormats.World)worldAsset.Data;


            if (worldData.IsGenerated)
            {
                Logger.Error("World {0} [{1}] is a dynamic world! Can't generate proper dynamic worlds yet!", worldAsset.Name, worldAsset.SNOId);

                GenerateRandomDungeon(worldSNO, worldData);
            }

            var world = new World(game, worldSNO);
            var levelAreas = new Dictionary<int, List<Scene>>();

            // Create a clusterID => Cluster Dictionary
            var clusters = new Dictionary<int, Mooege.Common.MPQ.FileFormats.SceneCluster>();
            foreach (var cluster in worldData.SceneClusterSet.SceneClusters)
                clusters[cluster.ClusterId] = cluster;

            // Scenes are not aligned to (0, 0) but apparently need to be -farmy
            float minX = worldData.SceneParams.SceneChunks.Min(x => x.PRTransform.Vector3D.X);
            float minY = worldData.SceneParams.SceneChunks.Min(x => x.PRTransform.Vector3D.Y);

            // Count all occurences of each cluster /fasbat
            var clusterCount = new Dictionary<int, int>();

            foreach (var sceneChunk in worldData.SceneParams.SceneChunks)
            {
                var cID = sceneChunk.SceneSpecification.ClusterID;
                if (cID != -1 && clusters.ContainsKey(cID)) // Check for wrong clusters /fasbat
                {
                    if (!clusterCount.ContainsKey(cID))
                        clusterCount[cID] = 0;
                    clusterCount[cID]++;
                }
            }

            // For each cluster generate a list of randomly selected subcenes /fasbat
            var clusterSelected = new Dictionary<int, List<Mooege.Common.MPQ.FileFormats.SubSceneEntry>>();
            foreach (var cID in clusterCount.Keys)
            {
                var selected = new List<Mooege.Common.MPQ.FileFormats.SubSceneEntry>();
                clusterSelected[cID] = selected;
                var count = clusterCount[cID];
                foreach (var group in clusters[cID].SubSceneGroups) // First select from each subscene group /fasbat
                {
                    for (int i = 0; i < group.I0 && count > 0; i++, count--) //TODO Rename I0 to requiredCount? /fasbat
                    {
                        var subSceneEntry = RandomHelper.RandomItem(group.Entries, entry => entry.Probability);
                        selected.Add(subSceneEntry);
                    }

                    if (count == 0)
                        break;
                }

                while (count > 0) // Fill the rest with defaults /fasbat
                {
                    var subSceneEntry = RandomHelper.RandomItem(clusters[cID].Default.Entries, entry => entry.Probability);
                    selected.Add(subSceneEntry);
                    count--;
                }
            }

            foreach (var sceneChunk in worldData.SceneParams.SceneChunks)
            {
                var position = sceneChunk.PRTransform.Vector3D - new Vector3D(minX, minY, 0);
                var scene = new Scene(world, position, sceneChunk.SNOHandle.Id, null)
                {
                    MiniMapVisibility = true,
                    RotationW = sceneChunk.PRTransform.Quaternion.W,
                    RotationAxis = sceneChunk.PRTransform.Quaternion.Vector3D,
                    SceneGroupSNO = -1
                };

                // If the scene has a subscene (cluster ID is set), choose a random subscenes from the cluster load it and attach it to parent scene /farmy
                if (sceneChunk.SceneSpecification.ClusterID != -1)
                {
                    if (!clusters.ContainsKey(sceneChunk.SceneSpecification.ClusterID))
                    {
                        Logger.Warn("Referenced clusterID {0} not found for chunk {1} in world {2}", sceneChunk.SceneSpecification.ClusterID, sceneChunk.SNOHandle.Id, worldSNO);
                    }
                    else
                    {
                        var entries = clusterSelected[sceneChunk.SceneSpecification.ClusterID]; // Select from our generated list /fasbat
                        Mooege.Common.MPQ.FileFormats.SubSceneEntry subSceneEntry = null;

                        if (entries.Count > 0)
                        {
                            //subSceneEntry = entries[RandomHelper.Next(entries.Count - 1)];

                            subSceneEntry = RandomHelper.RandomItem<Mooege.Common.MPQ.FileFormats.SubSceneEntry>(entries, entry => 1); // TODO Just shuffle the list, dont random every time. /fasbat
                            entries.Remove(subSceneEntry);
                        }
                        else
                            Logger.Error("No SubScenes defined for cluster {0} in world {1}", sceneChunk.SceneSpecification.ClusterID, world.DynamicID);

                        Vector3D pos = FindSubScenePosition(sceneChunk); // TODO According to BoyC, scenes can have more than one subscene, so better enumerate over all subscenepositions /farmy

                        if (pos == null)
                        {
                            Logger.Error("No scene position marker for SubScenes of Scene {0} found", sceneChunk.SNOHandle.Id);
                        }
                        else
                        {
                            // HACK: avoid trying to create scenes with SNOs that aren't valid
                            if (MPQStorage.Data.Assets[SNOGroup.Scene].ContainsKey(subSceneEntry.SNOScene))
                            {
                                var subScenePosition = scene.Position + pos;
                                var subscene = new Scene(world, subScenePosition, subSceneEntry.SNOScene, scene)
                                {
                                    MiniMapVisibility = true,
                                    RotationW = sceneChunk.PRTransform.Quaternion.W,
                                    RotationAxis = sceneChunk.PRTransform.Quaternion.Vector3D,
                                    Specification = sceneChunk.SceneSpecification
                                };
                                scene.Subscenes.Add(subscene);
                                subscene.LoadMarkers();
                            }
                            else
                            {
                                Logger.Error("Scene not found in mpq storage: {0}", subSceneEntry.SNOScene);
                            }
                        }
                    }

                }
                scene.Specification = sceneChunk.SceneSpecification;
                scene.LoadMarkers();

                // add scene to level area dictionary
                foreach (var levelArea in scene.Specification.SNOLevelAreas)
                {
                    if (levelArea != -1)
                    {
                        if (!levelAreas.ContainsKey(levelArea))
                            levelAreas.Add(levelArea, new List<Scene>());

                        levelAreas[levelArea].Add(scene);
                    }
                }
            }

            loadLevelAreas(levelAreas, world);
            return world;
        }
Beispiel #15
0
 /// <summary>
 /// Creates a new mili-seconds based stepped tick timer.
 /// </summary>
 /// <param name="game">The game timer belongs to.</param>
 /// <param name="miliSecondsPerStep">MiliSeconds taken per step.</param>
 /// <param name="miliSeconds">MiliSeconds taken to timeout.</param>
 /// <param name="stepCallback">The action to be called on each step.</param>
 /// <param name="completionCallback">The completition action to be called on timeout.</param>
 public SteppedMiliSecondsTickTimer(Game game, float miliSecondsPerStep, float miliSeconds, Action<int> stepCallback, Action<int> completionCallback)
     : base(game, (int)((1000f / game.UpdateFrequency * game.TickRate) / 1000f * miliSecondsPerStep), (int)((1000f / game.UpdateFrequency * game.TickRate) / 1000f * miliSeconds), stepCallback, completionCallback)
 { }
Beispiel #16
0
 /// <summary>
 /// Creates a new stepped tick timer.
 /// </summary>
 /// <param name="game">The game timer belongs to.</param>
 /// <param name="ticksPerStep">Ticks taken per step.</param>
 /// <param name="ticks">Relative tick amount taken to timeout.</param>
 /// <param name="stepCallback">The action to be called on each step.</param>
 /// <param name="completionCallback">The completition action to be called on timeout.</param>
 public SteppedRelativeTickTimer(Game game, int ticksPerStep, int ticks, Action<int> stepCallback, Action<int> completionCallback)
     :base(game, ticksPerStep, game.TickCounter + ticks, stepCallback, completionCallback)
 { }
Beispiel #17
0
 /// <summary>
 /// Creates a new mili-seconds based stepped tick timer.
 /// </summary>
 /// <param name="game">The game timer belongs to.</param>
 /// <param name="miliSecondsPerStep">MiliSeconds taken per step.</param>
 /// <param name="miliSeconds">MiliSeconds taken to timeout.</param>
 /// <param name="stepCallback">The action to be called on each step.</param>
 /// <param name="completionCallback">The completition action to be called on timeout.</param>
 /// <returns><see cref="SteppedTickTimer"/></returns>
 public static SteppedTickTimer WaitMiliSecondsStepped(Game game, float miliSecondsPerStep, float miliSeconds, Action<int> stepCallback, Action<int> completionCallback)
 {
     return new SteppedMiliSecondsTickTimer(game, miliSecondsPerStep, miliSeconds, stepCallback, completionCallback);
 }
Beispiel #18
0
            public QuestStep(Game game, Mooege.Common.MPQ.FileFormats.IQuestStep assetQuestStep, Quest quest)
            {
                _questStep = assetQuestStep;
                _quest = quest;
                int c = 0;

                foreach (var objectiveSet in assetQuestStep.StepObjectiveSets)
                    ObjectivesSets.Add(new ObjectiveSet()
                    {
                        FollowUpStepID = objectiveSet.FollowUpStepID,
                        Objectives = new List<QuestObjective>(from objective in objectiveSet.StepObjectives select new QuestObjective(game, objective, this, c++))
                    });
                c = 0;

                if (assetQuestStep is Mooege.Common.MPQ.FileFormats.QuestStep)
                {
                    var step = assetQuestStep as Mooege.Common.MPQ.FileFormats.QuestStep;

                    if (step.StepBonusObjectiveSets != null)
                        foreach (var objectiveSet in step.StepBonusObjectiveSets)
                            bonusObjectives.Add(new List<QuestObjective>(from objective in objectiveSet.StepBonusObjectives select new QuestObjective(game, objective, this, c++)));
                }
            }
Beispiel #19
0
 /// <summary>
 /// Creates a new world for the given game with given snoId.
 /// </summary>
 /// <param name="game">The parent game.</param>
 /// <param name="snoId">The snoId for the world.</param>
 public World(Game game, int snoId)
     : base(game.NewWorldID)
 {
     this.Game = game;
     this.SNOId = snoId; // NOTE: WorldSNO must be valid before adding it to the game
     this.Game.StartTracking(this); // start tracking the dynamicId for the world.            
     this.Scenes = new ConcurrentDictionary<uint, Scene>();
     this.Actors = new ConcurrentDictionary<uint, Actor>();
     this.Players = new ConcurrentDictionary<uint, Player>();
     this.QuadTree = new QuadTree(new Size(60, 60), 0);
     this.Game.AddWorld(this); 
 }
Beispiel #20
0
 /// <summary>
 /// Creates a new stepped tick timer.
 /// </summary>
 /// <param name="game">The game timer belongs to.</param>
 /// <param name="ticksPerStep">Ticks taken per step.</param>
 /// <param name="ticks">Relative tick amount taken to timeout.</param>
 /// <param name="stepCallback">The action to be called on each step.</param>
 /// <param name="completionCallback">The completition action to be called on timeout.</param>
 /// <returns><see cref="SteppedTickTimer"/></returns>
 public static SteppedTickTimer WaitTicksStepped(Game game, int ticksPerStep, int ticks, Action<int> stepCallback, Action<int> completionCallback)
 {
     return new SteppedRelativeTickTimer(game, ticksPerStep, ticks, stepCallback, completionCallback);
 }
Beispiel #21
0
 public static Game CreateGame(int gameId)
 {
     var game = new Game(gameId);
     Games.Add(gameId, game);
     return game;
 }