예제 #1
0
파일: Drone.cs 프로젝트: ESearcy/SE_MOD
        public Drone(IMyEntity ent)
        {
            var ship = (IMyCubeGrid)ent;

            Ship = ship;
            var lstSlimBlock = new List <IMySlimBlock>();

            GridTerminalSystem = MyAPIGateway.TerminalActionsHelper.GetTerminalSystemForGrid(ship);

            //If it has any type of cockipt
            ship.GetBlocks(lstSlimBlock, (x) => x.FatBlock is Sandbox.ModAPI.IMyRemoteControl);
            FindWeapons();
            SetupActions();

            //If no cockpit the ship is either no ship or is broken.
            if (lstSlimBlock.Count != 0)
            {
                //Make the controls be the cockpit
                ShipControls = lstSlimBlock[0].FatBlock as IMyControllableEntity;

                #region Activate Beacons && Antennas


                //Maximise radius on antennas and beacons.
                lstSlimBlock.Clear();
                ship.GetBlocks(lstSlimBlock, (x) => x.FatBlock is Sandbox.ModAPI.IMyRadioAntenna);
                foreach (var block in lstSlimBlock)
                {
                    Sandbox.ModAPI.IMyRadioAntenna antenna =
                        (Sandbox.ModAPI.IMyRadioAntenna)block.FatBlock;
                    if (antenna != null)
                    {
                        //antenna.GetActionWithName("SetCustomName").Apply(antenna, new ListReader<TerminalActionParameter>(new List<TerminalActionParameter>() { TerminalActionParameter.Get("Combat Drone " + _manualGats.Count) }));
                        antenna.SetValueFloat("Radius", 10000);//antenna.GetMaximum<float>("Radius"));
                        _blockOn.Apply(antenna);
                    }
                }

                lstSlimBlock = new List <IMySlimBlock>();
                ship.GetBlocks(lstSlimBlock, (x) => x.FatBlock is Sandbox.ModAPI.IMyBeacon);
                foreach (var block in lstSlimBlock)
                {
                    Sandbox.ModAPI.IMyBeacon beacon = (Sandbox.ModAPI.IMyBeacon)block.FatBlock;
                    if (beacon != null)
                    {
                        beacon.SetValueFloat("Radius", 10000);//beacon.GetMaximum<float>("Radius"));
                        _blockOn.Apply(beacon);
                    }
                }

                #endregion

                //SetWeaponPower(true);
                //AmmoManager.ReloadReactors(_allReactors);
                //AmmoManager.ReloadGuns(_manualGats);
                ship.GetBlocks(lstSlimBlock, x => x is IMyEntity);


                List <IMyTerminalBlock> allTerminalBlocks = new List <IMyTerminalBlock>();
                GridTerminalSystem.GetBlocksOfType <IMyCubeBlock>(allTerminalBlocks);
                HealthBlockBase = allTerminalBlocks.Count;


                if (ShipControls != null)
                {
                    navigation = new ThrusterGyroControls(ship, ShipControls);
                    _ownerId   = ((Sandbox.ModAPI.IMyTerminalBlock)ShipControls).OwnerId;
                    tc         = new TargetingControls(Ship, _ownerId);
                }
            }

            Ship.OnBlockAdded += RecalcMaxHp;
            myNumber           = numDrones;
            numDrones++;
        }
예제 #2
0
        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();
        }