private static void Entities_OnCloseAll() { MyAPIGateway.Entities.OnCloseAll -= Entities_OnCloseAll; DoTests = null; Path = null; Timer = null; s_logger = null; }
public static MyRenderThread Start(MyGameTimer timer, InitHandler initHandler, MyRenderDeviceSettings?settingsToTry, MyRenderQualityEnum renderQuality) { var result = new MyRenderThread(timer, true); result.SystemThread.Start(new StartParams() { InitHandler = initHandler, SettingsToTry = settingsToTry, RenderQuality = renderQuality }); return(result); }
/// <summary> /// Construct Anima class. /// </summary> /// <remarks>Don't forget to call Init(MyEntity, string, string) to initialize!</remarks> public Anima() { m_entity = null; m_modelsFolder = null; m_partList = new List <AnimaPart>(); m_inRange = true; m_gameTimer = new MyGameTimer(); m_lastElapse = m_gameTimer.Elapsed.Seconds; m_instances++; }
public static MyRenderThread StartSync(MyGameTimer timer, IMyRenderWindow renderWindow, MyRenderDeviceSettings?settingsToTry, MyRenderQualityEnum renderQuality) { var result = new MyRenderThread(timer, false); result.m_renderWindow = renderWindow; result.m_settings = MyRenderProxy.CreateDevice(result, renderWindow.Handle, settingsToTry); MyRenderProxy.SendCreatedDeviceSettings(result.m_settings); result.m_currentQuality = renderQuality; result.m_form = Control.FromHandle(renderWindow.Handle); result.LoadContent(); result.UpdateSize(); return(result); }
private void init() { _playerDataStorage.Load(); mConfigDataStore.Load(); Config = mConfigDataStore.ConfigData; // Minimum of 2h dayLen = Math.Max(MyAPIGateway.Session.SessionSettings.SunRotationIntervalMinutes, 120f); mHungerPerMinute = Config.HungerPerDay / dayLen; mThirstPerMinute = Config.ThirstPerDay / dayLen; mConfigDataStore.Save(); if (Utils.isDev()) { MyAPIGateway.Utilities.ShowMessage("SERVER", "INIT"); } MyAPIGateway.Multiplayer.RegisterMessageHandler(1338, AdminCommandHandler); MyAPIGateway.Utilities.RegisterMessageHandler(1339, NeedsApiHandler); IsAutohealingOn = MyAPIGateway.Session.SessionSettings.AutoHealing; NeedsApi api = new NeedsApi(); // Register all the known foods. foreach (var food in FoodDefaults.Defaults) { api.RegisterItem(food.Key, food.Value); } // this lets other people do stuff with this, just add the appropriate tag to the food name. Use whole numbers. For example, SpacePasta!fih40 or SpaceCola!di60 or SpaceTofu!fil20 // TODO: Refactor this to handle tags more gracefully.. for (int i = 1; i <= 100; i++) { api.RegisterEdibleItem("!fil" + (i), (float)(-i)); api.RegisterEdibleItem("!fih" + (i), (float)(i)); api.RegisterDrinkableItem("!di" + (i), (float)(i)); } // Initiate the timer mTimer = new MyGameTimer(); }
private void init() { mPlayerDataStore.Load(); if (Utils.isDev()) { MyAPIGateway.Utilities.ShowMessage("SERVER", "INIT"); } MyAPIGateway.Multiplayer.RegisterMessageHandler(1338, AdminCommandHandler); MyAPIGateway.Utilities.RegisterMessageHandler(1339, NeedsApiHandler); // Minimum of 2h, because it's unplayable under.... float dayLen = Math.Max(MyAPIGateway.Session.SessionSettings.SunRotationIntervalMinutes, 120f); mHungerPerMinute = HUNGER_PER_DAY / dayLen; mThirstPerMinute = THIRST_PER_DAY / dayLen; NeedsApi api = new NeedsApi(); // Registering drinks api.RegisterDrinkableItem("WaterFood", 10f); api.RegisterDrinkableItem("CoffeeFood", 15f); //Server.RegisterBeverage("WaterFood", 10f); //Server.RegisterBeverage("CoffeeFood", 15f); // Registering foods api.RegisterEdibleItem("WarmFood", 20f); api.RegisterEdibleItem("FreshFood", 15f); api.RegisterEdibleItem("GummybearsFood", 5f); api.RegisterEdibleItem("SyntheticFood", 3f); //Server.RegisterFood("WarmFood", 20f); //Server.RegisterFood("FreshFood", 15f); //Server.RegisterFood("GummybearsFood", 5f); //Server.RegisterFood("SyntheticFood", 3f); // Initiate the timer mTimer = new MyGameTimer(); }
private MyRenderThread(MyGameTimer timer, bool separateThread) { m_timer = timer; if (separateThread) { SystemThread = new Thread(new ParameterizedThreadStart(RenderThreadStart)); //RenderThread.Priority = ThreadPriority.AboveNormal; SystemThread.IsBackground = true; // Do not prevent app from terminating SystemThread.Name = "Render thread"; SystemThread.CurrentCulture = CultureInfo.InvariantCulture; SystemThread.CurrentUICulture = CultureInfo.InvariantCulture; } else { SystemThread = Thread.CurrentThread; } }
/// <summary> /// Time an Action /// </summary> /// <param name="action">Action to perform</param> /// <param name="iterations">Number of iterations of action</param> /// <param name="ignoreFirst">Perform an extra invokation first, that will not be timed.</param> /// <returns>Results of timing</returns> /// <exception cref="ArgumentNullException">If action == null</exception> /// <exception cref="ArgumentOutOfRangeException">If iterarions < 1</exception> public static Results Time(Action action, int iterations = 1, bool extraFirst = false) { VRage.Exceptions.ThrowIf <ArgumentNullException>(action == null, "action"); VRage.Exceptions.ThrowIf <ArgumentOutOfRangeException>(iterations < 1, "iterations < 1"); if (extraFirst) { action.Invoke(); } ListSnapshots <MyTimeSpan> unsortedResults = new ListSnapshots <MyTimeSpan>(); ReadOnlyList <MyTimeSpan> mutable = unsortedResults.mutable(); for (int i = 0; i < iterations; i++) { MyGameTimer actionTimer = new MyGameTimer(); action.Invoke(); mutable.Add(actionTimer.Elapsed); } return(new Results(unsortedResults)); }
private void init() { if (Utils.isDev()) { MyAPIGateway.Utilities.ShowMessage("SERVER", "INIT"); } MyAPIGateway.Multiplayer.RegisterMessageHandler(1338, AdminCommandHandler); mTimer = new MyGameTimer(); float dayLen = MyAPIGateway.Session.SessionSettings.SunRotationIntervalMinutes; mHungerPerMinute = HUNGER_PER_DAY / dayLen; mThirstPerMinute = THIRST_PER_DAY / dayLen; updatePlayerList(); Server.RegisterBeverage(new MyDefinitionId(typeof(MyObjectBuilder_Ingot), "WaterFood"), 10f); Server.RegisterBeverage(new MyDefinitionId(typeof(MyObjectBuilder_Ingot), "CoffeeFood"), 15f); Server.RegisterFood(new MyDefinitionId(typeof(MyObjectBuilder_Ingot), "WarmFood"), 20f); Server.RegisterFood(new MyDefinitionId(typeof(MyObjectBuilder_Ingot), "FreshFood"), 15f); Server.RegisterFood(new MyDefinitionId(typeof(MyObjectBuilder_Ingot), "GummybearsFood"), 5f); Server.RegisterFood(new MyDefinitionId(typeof(MyObjectBuilder_Ingot), "SyntheticFood"), 3f); }
public void StartSync(MyGameTimer timer, IMyRenderWindow window, MyRenderDeviceSettings?settings, MyRenderQualityEnum renderQuality, float maxFrameRate) { RenderThread = MyRenderThread.StartSync(timer, window, settings, renderQuality, maxFrameRate); }
/// <summary> /// Creates and starts render thread /// </summary> public void Start(MyGameTimer timer, InitHandler windowInitializer, MyRenderDeviceSettings?settingsToTry, MyRenderQualityEnum renderQuality, float maxFrameRate) { RenderThread = MyRenderThread.Start(timer, windowInitializer, settingsToTry, renderQuality, maxFrameRate); }
internal MyStatToken(MyGameTimer timer, MyStat stat) { m_timer = timer; m_startTime = timer.Elapsed; m_stat = stat; }
private void updateFoodLogic() { float elapsedMinutes = (float)(mTimer.Elapsed.Seconds / 60); //float CurPlayerHealth = -1f; bool ChangedStance = false; MyObjectBuilder_Character character; MyCharacterMovementEnum curmove = MyCharacterMovementEnum.Sitting; foreach (var player in _players) { if (String.IsNullOrWhiteSpace(player.Controller?.ControlledEntity?.Entity?.DisplayName)) { PlayerData playerData = _playerDataStorage.Retrieve(player); Logging.Instance.WriteLine(playerData.ToString() + "Loaded to Server"); IMyEntity entity = player.Controller.ControlledEntity.Entity; entity = GetCharacterEntity(entity); // //MyAPIGateway.Utilities.ShowMessage("DEBUG", "Character: " + entity.DisplayName); // gets me player name float currentModifier = 1f; float fatigueRate = 0f; bool dead = false; bool forceEating = false; float recycleBonus = 1f; bool fatigueBonus = false; bool hungerBonus = false; bool thirstBonus = false; // if we were under the effects of a bonus, keep it until we no longer are fatigueBonus = playerData.fatigue > Config.MaxValue; thirstBonus = playerData.thirst > Config.MaxValue; hungerBonus = playerData.hunger > Config.MaxValue; if (entity is IMyCharacter) { character = entity.GetObjectBuilder() as MyObjectBuilder_Character; //MyAPIGateway.Utilities.ShowMessage("DEBUG", "State: " + character.MovementState); if (playerData.Entity == null || playerData.Entity.Closed || playerData.Entity.EntityId != entity.EntityId) { bool bReset = false; if (!playerData.loaded) { bReset = true; playerData.loaded = true; } else if ((playerData.Entity != null) && (playerData.Entity != entity)) { bReset = true; } if (bReset) { playerData.hunger = Config.StartingHunger; playerData.thirst = Config.StartingThirst; playerData.fatigue = Config.StartingFatigue; } playerData.Entity = entity; } //MyAPIGateway.Utilities.ShowMessage("DEBUG", "State: " + character.MovementState + ":" + playerData.LastMovement); ChangedStance = playerData.LastMovement != character.MovementState; curmove = character.MovementState; switch (character.MovementState) // this should be all of them.... { case MyCharacterMovementEnum.Sitting: IMyCubeBlock cb = player.Controller.ControlledEntity.Entity as IMyCubeBlock; //cb.DisplayNameText is name of individual block, cb.DefinitionDisplayNameText is name of block type currentModifier = Config.DefaultModifier; fatigueRate = Config.FatigueSitting; // special case: we may be interacting with a bed, a lunchroom seat or treadmill, so let's String seatmodel = cb.DefinitionDisplayNameText.ToLower(); String seatname = cb.DisplayNameText.ToLower(); if (seatmodel.Contains("cryo")) // you're in a cryopd not an oxygen bed { currentModifier = 0.0000125f; fatigueRate = 0.0000125f; } else if (seatmodel.Contains("treadmill")) { currentModifier = RUNNING_MODIFIER; // jog... fatigueRate = FATIGUE_RUNNING / 2.5f; // but pace yourself } else if (seatmodel.Contains("bed") || seatmodel.Contains("bunk")) { currentModifier = DEFAULT_MODIFIER / 2f; // nap time! Needs are reduced. fatigueRate = FATIGUE_SITTING * 3f; // nap time! Rest is greatly sped up. fatigueBonus |= !ChangedStance; // longer nap? OK, allow for extra resting } else if (seatmodel.Contains("toilet") && ChangedStance) { forceEating = true; // also forces defecation, so this makes sense. but use changedstance to do it only once. recycleBonus = 1.5f; } else if (seatname.Contains("noms")) { forceEating = true; // also forces crapping, fortunately the suit takes care of it. Eat continuously while sitting. hungerBonus |= playerData.hunger > Config.MaxValue * 0.99; // get to 100% first, then apply bonus. thirstBonus |= playerData.thirst > Config.MaxValue * 0.99; // get to 100% first, then apply bonus. } break; case MyCharacterMovementEnum.Flying: currentModifier = FLYING_MODIFIER; fatigueRate = FATIGUE_FLYING; // operating a jetpack is surprisingly hard break; case MyCharacterMovementEnum.Falling: currentModifier = FLYING_MODIFIER; fatigueRate = FATIGUE_WALKING; // change nothing for the first iteration (prevents jump exploit) if (!ChangedStance) { fatigueRate = FATIGUE_STANDING; // freefall is actually relaxing when you are used to it. A professional space engineer would be. } break; case MyCharacterMovementEnum.Crouching: case MyCharacterMovementEnum.CrouchRotatingLeft: case MyCharacterMovementEnum.CrouchRotatingRight: currentModifier = DEFAULT_MODIFIER; fatigueRate = FATIGUE_CROUCHING; break; case MyCharacterMovementEnum.Standing: case MyCharacterMovementEnum.RotatingLeft: case MyCharacterMovementEnum.RotatingRight: currentModifier = DEFAULT_MODIFIER; fatigueRate = FATIGUE_STANDING; break; case MyCharacterMovementEnum.CrouchWalking: case MyCharacterMovementEnum.CrouchBackWalking: case MyCharacterMovementEnum.CrouchStrafingLeft: case MyCharacterMovementEnum.CrouchStrafingRight: case MyCharacterMovementEnum.CrouchWalkingRightFront: case MyCharacterMovementEnum.CrouchWalkingRightBack: case MyCharacterMovementEnum.CrouchWalkingLeftFront: case MyCharacterMovementEnum.CrouchWalkingLeftBack: currentModifier = RUNNING_MODIFIER; fatigueRate = FATIGUE_RUNNING; // doing the duckwalk is more tiring than walking: try it if you don't believe me break; case MyCharacterMovementEnum.Walking: case MyCharacterMovementEnum.BackWalking: case MyCharacterMovementEnum.WalkStrafingLeft: case MyCharacterMovementEnum.WalkStrafingRight: case MyCharacterMovementEnum.WalkingRightFront: case MyCharacterMovementEnum.WalkingRightBack: case MyCharacterMovementEnum.WalkingLeftFront: case MyCharacterMovementEnum.WalkingLeftBack: currentModifier = DEFAULT_MODIFIER; fatigueRate = FATIGUE_WALKING; break; case MyCharacterMovementEnum.LadderUp: currentModifier = RUNNING_MODIFIER; fatigueRate = FATIGUE_RUNNING; break; case MyCharacterMovementEnum.LadderDown: currentModifier = DEFAULT_MODIFIER; fatigueRate = FATIGUE_WALKING; break; case MyCharacterMovementEnum.Running: case MyCharacterMovementEnum.Backrunning: case MyCharacterMovementEnum.RunStrafingLeft: case MyCharacterMovementEnum.RunStrafingRight: case MyCharacterMovementEnum.RunningRightFront: case MyCharacterMovementEnum.RunningRightBack: case MyCharacterMovementEnum.RunningLeftBack: case MyCharacterMovementEnum.RunningLeftFront: currentModifier = RUNNING_MODIFIER; fatigueRate = FATIGUE_RUNNING; break; case MyCharacterMovementEnum.Sprinting: case MyCharacterMovementEnum.Jump: currentModifier = SPRINTING_MODIFIER; fatigueRate = FATIGUE_SPRINTING; break; case MyCharacterMovementEnum.Died: currentModifier = DEFAULT_MODIFIER; // unused, but let's have them fatigueRate = FATIGUE_STANDING; // unused, but let's have them dead = true; // for death recovery logic break; } playerData.LastMovement = character.MovementState; // track delta } else if (playerData.Entity != null || !playerData.Entity.Closed) { entity = playerData.Entity; } // Sanity checks if (hungerBonus) { if (playerData.hunger > Config.MaxValue * FOOD_BONUS) { playerData.hunger = Config.MaxValue * FOOD_BONUS; } } else { if (playerData.hunger > Config.MaxValue) { playerData.hunger = Config.MaxValue; } } if (thirstBonus) { if (playerData.thirst > Config.MaxValue * DRINK_BONUS) { playerData.thirst = Config.MaxValue * DRINK_BONUS; } } else { if (playerData.thirst > Config.MaxValue) { playerData.thirst = Config.MaxValue; } } // Cause needs if (FATIGUE_ENABLED) { playerData.fatigue += (fatigueRate * FOOD_LOGIC_SKIP_TICKS / 60 * 20); // / 15); playerData.fatigue = Math.Max(playerData.fatigue, MIN_VALUE); if (fatigueBonus) { playerData.fatigue = Math.Min(playerData.fatigue, Config.MaxValue * REST_BONUS); } else { playerData.fatigue = Math.Min(playerData.fatigue, Config.MaxValue); } } else { playerData.fatigue = 9001f; } if (playerData.fatigue <= 0) { // fatigue consequences // at 0, start causing extra thirst // at specified, force walk instead of run (unless overriding by sprinting) // at specified, force crouch, and do damage flashes // at specified, breathing reflex / mess with helmet, and do a bit of actual damage (just in case thirst isn't already causing it) // at specified, cause heart attack if (playerData.fatigue <= (0.00f * MIN_VALUE)) { if (EXTRA_THIRST_FROM_FATIGUE > 0) { // positive: pile on to thirst, per second playerData.thirst -= (EXTRA_THIRST_FROM_FATIGUE * FOOD_LOGIC_SKIP_TICKS / 60); } else // negative: multiply modifier { currentModifier *= -EXTRA_THIRST_FROM_FATIGUE; } } if (playerData.fatigue <= (FATIGUE_LEVEL_FORCEWALK * MIN_VALUE)) { // force player to walk if they were running switch (curmove) { case MyCharacterMovementEnum.Sprinting: case MyCharacterMovementEnum.Running: case MyCharacterMovementEnum.Backrunning: case MyCharacterMovementEnum.RunStrafingLeft: case MyCharacterMovementEnum.RunStrafingRight: case MyCharacterMovementEnum.RunningRightFront: case MyCharacterMovementEnum.RunningRightBack: case MyCharacterMovementEnum.RunningLeftBack: case MyCharacterMovementEnum.RunningLeftFront: VRage.Game.ModAPI.Interfaces.IMyControllableEntity ce = player.Controller.ControlledEntity.Entity as VRage.Game.ModAPI.Interfaces.IMyControllableEntity; ce.SwitchWalk(); break; } } if (playerData.fatigue <= (FATIGUE_LEVEL_FORCECROUCH * MIN_VALUE)) { bool iscrouching = false; switch (curmove) { case MyCharacterMovementEnum.Crouching: case MyCharacterMovementEnum.CrouchWalking: case MyCharacterMovementEnum.CrouchBackWalking: case MyCharacterMovementEnum.CrouchStrafingLeft: case MyCharacterMovementEnum.CrouchStrafingRight: case MyCharacterMovementEnum.CrouchWalkingRightFront: case MyCharacterMovementEnum.CrouchWalkingRightBack: case MyCharacterMovementEnum.CrouchWalkingLeftFront: case MyCharacterMovementEnum.CrouchWalkingLeftBack: iscrouching = true; break; } if (!iscrouching) { VRage.Game.ModAPI.Interfaces.IMyControllableEntity ce = player.Controller.ControlledEntity.Entity as VRage.Game.ModAPI.Interfaces.IMyControllableEntity; ce.Crouch(); // force player to crouch } } if (playerData.fatigue <= (FATIGUE_LEVEL_HELMET * MIN_VALUE)) { VRage.Game.ModAPI.Interfaces.IMyControllableEntity ce = player.Controller.ControlledEntity.Entity as VRage.Game.ModAPI.Interfaces.IMyControllableEntity; ce.SwitchHelmet(); // force player to switch helmet, panic reaction from trying to catch breath var destroyable = entity as IMyDestroyableObject; destroyable.DoDamage(0.001f, MyStringHash.GetOrCompute("Fatigue"), true); // starting to hurt } if (playerData.fatigue <= (FATIGUE_LEVEL_NOHEALING * MIN_VALUE)) { var destroyable = entity as IMyDestroyableObject; destroyable.DoDamage(0.001f, MyStringHash.GetOrCompute("Fatigue"), true); // starting to hurt if (IsAutohealingOn) // fatigued? no autohealing, either. { const float HealthTick = 100f / 240f * FOOD_LOGIC_SKIP_TICKS / 60f; destroyable.DoDamage(HealthTick, MyStringHash.GetOrCompute("Testing"), false); } } if (playerData.fatigue <= (FATIGUE_LEVEL_HEARTATTACK * MIN_VALUE)) { var destroyable = entity as IMyDestroyableObject; destroyable.DoDamage(1000f, MyStringHash.GetOrCompute("Fatigue"), true); // sudden, but very avoidable, heart attack ;) } } if (playerData.thirst > MIN_VALUE) { playerData.thirst -= elapsedMinutes * mThirstPerMinute * currentModifier; playerData.thirst = Math.Max(playerData.thirst, MIN_VALUE); } if (playerData.hunger > MIN_VALUE) { playerData.hunger -= elapsedMinutes * mHungerPerMinute * currentModifier; playerData.hunger = Math.Max(playerData.hunger, MIN_VALUE); } // Try to meet needs if (playerData.hunger < (Config.MaxValue * HUNGRY_WHEN) || forceEating) { playerEatSomething(entity, playerData, hungerBonus?Config.MaxValue * 1.25f:Config.MaxValue, recycleBonus); } if (playerData.thirst < (Config.MaxValue * THIRSTY_WHEN) || forceEating) { playerDrinkSomething(entity, playerData, thirstBonus?Config.MaxValue * 1.25f:Config.MaxValue, recycleBonus); } // Cause damage if needs are unmet if (playerData.thirst <= 0) { var destroyable = entity as IMyDestroyableObject; if (DAMAGE_SPEED_THIRST > 0) { destroyable.DoDamage((IsAutohealingOn ? (DAMAGE_SPEED_THIRST + 1f) : DAMAGE_SPEED_THIRST), MyStringHash.GetOrCompute("Thirst"), true); } else { destroyable.DoDamage(((IsAutohealingOn ? (-DAMAGE_SPEED_THIRST + 1f) : -DAMAGE_SPEED_THIRST) + DAMAGE_SPEED_THIRST * playerData.thirst), MyStringHash.GetOrCompute("Thirst"), true); } } if (playerData.hunger <= 0) { var destroyable = entity as IMyDestroyableObject; if (DAMAGE_SPEED_HUNGER > 0) { destroyable.DoDamage((IsAutohealingOn ? (DAMAGE_SPEED_HUNGER + 1f) : DAMAGE_SPEED_HUNGER), MyStringHash.GetOrCompute("Hunger"), true); } else { destroyable.DoDamage(((IsAutohealingOn ? (-DAMAGE_SPEED_HUNGER + 1f) : -DAMAGE_SPEED_HUNGER) + DAMAGE_SPEED_HUNGER * playerData.hunger), MyStringHash.GetOrCompute("Hunger"), true); } } /* * * * character = entity.GetObjectBuilder(false) as MyObjectBuilder_Character; * if (character.Health == null) // ok, so the variable exists, but it's always null for some reason? * CurPlayerHealth = 101f; * else * CurPlayerHealth = (float) (character.Health); * * if (IsAutohealingOn && CurPlayerHealth < 70f) * { * const float HealthTick = 100f / 240f * FOOD_LOGIC_SKIP_TICKS / 60f; * var destroyable = entity as IMyDestroyableObject; * destroyable.DoDamage(HealthTick, MyStringHash.GetOrCompute("Testing"), false); * } */ if (dead && DEATH_RECOVERY > 0.0) { MyInventoryBase inventory = ((MyEntity)entity).GetInventoryBase(); if (playerData.hunger > 0) { inventory.AddItems((MyFixedPoint)((1f / Config.MaxValue) * DEATH_RECOVERY * (playerData.hunger)), new MyObjectBuilder_Ore() { SubtypeName = "Organic" }); } if (playerData.thirst > 0) { inventory.AddItems((MyFixedPoint)((1f / Config.MaxValue) * DEATH_RECOVERY * (playerData.thirst)), new MyObjectBuilder_Ingot() { SubtypeName = "GreyWater" }); } } //Sends data from Server.cs to Client.cs string message = MyAPIGateway.Utilities.SerializeToXML <PlayerData>(playerData); Logging.Instance.WriteLine(("Message sent from Server.cs to Client.cs: " + message)); MyAPIGateway.Multiplayer.SendMessageTo( 1337, Encoding.Unicode.GetBytes(message), player.SteamUserId ); } } // Reinitialize the timer mTimer = new MyGameTimer(); }
private void updateFoodLogic() { foreach (IMyPlayer player in mPlayers) { if (player.Controller != null && player.Controller.ControlledEntity != null && player.Controller.ControlledEntity.Entity != null) { PlayerData playerData = mPlayerDataStore.get(player); IMyEntity entity = GetCharacterEntity(player.Controller.ControlledEntity.Entity); //MyAPIGateway.Utilities.ShowMessage("DEBUG", "State: " + character.MovementState); //if(playerData.entity != null) { // MyAPIGateway.Utilities.ShowMessage ("DEBUG", "Entity: " + playerData.entity.Closed); //} mCurrentModifier = DEFAULT_MODIFIER; if (entity is IMyCharacter) { MyObjectBuilder_Character character = entity.GetObjectBuilder(false) as MyObjectBuilder_Character; if (playerData.entity == null || playerData.entity.Closed || playerData.entity.EntityId != entity.EntityId) { playerData.hunger = 50f; playerData.thirst = 50f; playerData.entity = entity; } switch (character.MovementState) { case MyCharacterMovementEnum.Running: case MyCharacterMovementEnum.Backrunning: case MyCharacterMovementEnum.RunStrafingLeft: case MyCharacterMovementEnum.RunStrafingRight: case MyCharacterMovementEnum.RunningRightFront: case MyCharacterMovementEnum.RunningRightBack: case MyCharacterMovementEnum.RunningLeftBack: case MyCharacterMovementEnum.RunningLeftFront: mCurrentModifier = RUNNING_MODIFIER; break; case MyCharacterMovementEnum.Sprinting: mCurrentModifier = SPRINTING_MODIFIER; break; case MyCharacterMovementEnum.Died: mCurrentModifier = 0; break; } } else if (playerData.entity != null || !playerData.entity.Closed) { entity = playerData.entity; } if (playerData.thirst <= 0 || playerData.hunger <= 0) { var destroyable = entity as Sandbox.ModAPI.Interfaces.IMyDestroyableObject; destroyable.DoDamage(DAMAGE_SPEED, MyStringHash.GetOrCompute("Hunger/Thirst"), true); } if (playerData.hunger < 100) { //Eat playerEatSomething(entity, playerData); } if (playerData.thirst < 100) { //Drink playerDrinkSomething(entity, playerData); } float elapsedMinutes = (float)(mTimer.Elapsed.Seconds / 60); if (playerData.thirst > 0) { float gain = Math.Min(elapsedMinutes * mThirstPerMinute * mCurrentModifier, playerData.thirst); playerData.thirst -= gain; //MyAPIGateway.Utilities.ShowMessage("DEBUG", "Thirst Gain: " + gain); } if (playerData.hunger > 0) { playerData.hunger -= Math.Min(elapsedMinutes * mHungerPerMinute * (mCurrentModifier / 2), playerData.hunger); } mTimer = new MyGameTimer(); string message = MyAPIGateway.Utilities.SerializeToXML <PlayerData>(playerData); MyAPIGateway.Multiplayer.SendMessageTo( 1337, Encoding.Unicode.GetBytes(message), player.SteamUserId ); } } }
private void updateFoodLogic() { float elapsedMinutes = (float)(mTimer.Elapsed.Seconds / 60); foreach (IMyPlayer player in mPlayers) { if (player.Controller != null && player.Controller.ControlledEntity != null && player.Controller.ControlledEntity.Entity != null) { PlayerData playerData = mPlayerDataStore.get(player); IMyEntity entity = GetCharacterEntity(player.Controller.ControlledEntity.Entity); //MyAPIGateway.Utilities.ShowMessage("DEBUG", "State: " + character.MovementState); //if(playerData.entity != null) { // MyAPIGateway.Utilities.ShowMessage ("DEBUG", "Entity: " + playerData.entity.Closed); //} float CurrentModifier = DEFAULT_MODIFIER; if (entity is IMyCharacter) { MyObjectBuilder_Character character = entity.GetObjectBuilder(false) as MyObjectBuilder_Character; if (playerData.entity == null || playerData.entity.Closed || playerData.entity.EntityId != entity.EntityId) { bool bReset = false; if (!playerData.loaded) { bReset = true; playerData.loaded = true; } else if ((playerData.entity != null) && (playerData.entity != entity)) { bReset = true; } if (bReset) { playerData.hunger = 100f; playerData.thirst = 100f; } playerData.entity = entity; } switch (character.MovementState) { case MyCharacterMovementEnum.Flying: CurrentModifier = FLYING_MODIFIER; break; case MyCharacterMovementEnum.Running: case MyCharacterMovementEnum.Backrunning: case MyCharacterMovementEnum.RunStrafingLeft: case MyCharacterMovementEnum.RunStrafingRight: case MyCharacterMovementEnum.RunningRightFront: case MyCharacterMovementEnum.RunningRightBack: case MyCharacterMovementEnum.RunningLeftBack: case MyCharacterMovementEnum.RunningLeftFront: CurrentModifier = RUNNING_MODIFIER; break; case MyCharacterMovementEnum.Sprinting: CurrentModifier = SPRINTING_MODIFIER; break; } } else if (playerData.entity != null || !playerData.entity.Closed) { entity = playerData.entity; } // Rise the thirst if (playerData.thirst > 0) { playerData.thirst -= elapsedMinutes * mThirstPerMinute * CurrentModifier; playerData.thirst = Math.Max(playerData.thirst, 0); } // Rise the hunger if (playerData.hunger > 0) { playerData.hunger -= elapsedMinutes * mHungerPerMinute * CurrentModifier; playerData.hunger = Math.Max(playerData.hunger, 0); } // Eat if (playerData.hunger < 30) { playerEatSomething(entity, playerData); } // Drink if (playerData.thirst < 30) { playerDrinkSomething(entity, playerData); } // Get some damages for not being well feed! if (playerData.thirst <= 0 || playerData.hunger <= 0) { var destroyable = entity as IMyDestroyableObject; destroyable.DoDamage(DAMAGE_SPEED, MyStringHash.GetOrCompute("Hunger/Thirst"), true); } string message = MyAPIGateway.Utilities.SerializeToXML <PlayerData>(playerData); MyAPIGateway.Multiplayer.SendMessageTo( 1337, Encoding.Unicode.GetBytes(message), player.SteamUserId ); } } // Reinitialize the timer mTimer = new MyGameTimer(); }