/// <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; }
public static Game CreateGame(int gameId) { if (Games.ContainsKey(gameId)) return Games[gameId]; var game = new Game(gameId); Games.Add(gameId, game); return game; }
/// <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; }
/// <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; }
// 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; }
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) { } }
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); }
/// <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) { }
/// <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) { }
/// <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); }
/// <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); }
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); }
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; }
/// <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) { }
/// <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) { }
/// <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); }
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++))); } }
/// <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); }
/// <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); }
public static Game CreateGame(int gameId) { var game = new Game(gameId); Games.Add(gameId, game); return game; }