示例#1
0
        private bool IsValidCharacter(IMyCharacter character)
        {
            if (character != null)
            {
                if (!TargetCharacters || character.IsDead)                 // dont target if not set or dead
                {
                    return(false);
                }

                IMyPlayer player = MyAPIGateway.Players.GetPlayerControllingEntity(character);

                if (player == null)
                {
                    return(false);
                }

                MyRelationsBetweenPlayerAndBlock relation = player.GetRelationTo(CubeBlock.OwnerId);

                if (!(relation == MyRelationsBetweenPlayerAndBlock.Enemies ||
                      TargetNeutrals && (relation == MyRelationsBetweenPlayerAndBlock.Neutral || relation == MyRelationsBetweenPlayerAndBlock.NoOwnership)))
                {
                    return(false);
                }

                return(true);
            }

            return(false);
        }
示例#2
0
        /// <summary>
        /// Handles the damage in ProtectionAreas if Protection is enabled. This method is desinged for server side use and will notify the players if they tried to damage the wrong block.
        /// </summary>
        /// <param name="target"></param>
        /// <param name="info"></param>
        private static void DamageHandler_Server(object target, ref MyDamageInformation info)
        {
            if (!Config.ProtectionEnabled)
            {
                return;
            }

            IMySlimBlock block = target as IMySlimBlock;

            if (block != null)
            {
                IMyPlayer player;
                if (CanDamageBlock(info.AttackerId, block, info.Type, out player))
                {
                    return;
                }

                info.Amount = 0;

                // notify player
                DateTime time;
                if (player != null && (!_sentFailedMessage.TryGetValue(player, out time) || DateTime.Now - time >= TimeSpan.FromMilliseconds(GrindFailedMessageInterval)))
                {
                    MessageClientNotification.SendMessage(player.SteamUserId, "You are not allowed to damage this block.", GrindFailedMessageInterval, MyFontEnum.Red);
                    _sentFailedMessage.Update(player, DateTime.Now);
                }

                return;
            }

            // disable pvp in PAs
            IMyCharacter character = target as IMyCharacter;

            if (character != null)
            {
                var players = new List <IMyPlayer>();
                MyAPIGateway.Players.GetPlayers(players, p => p != null && p.Controller.ControlledEntity != null && p.Controller.ControlledEntity.Entity != null);

                var player = players.FirstOrDefault(p => p.GetCharacter() == character);
                if (player == null)
                {
                    return;
                }

                if (!IsProtected(player.Controller.ControlledEntity.Entity))
                {
                    return;
                }

                if (info.Type == MyDamageType.LowPressure || info.Type == MyDamageType.Asphyxia ||
                    info.Type == MyDamageType.Environment || info.Type == MyDamageType.Fall ||
                    info.Type == MyDamageType.Fire || info.Type == MyDamageType.Radioactivity ||
                    info.Type == MyDamageType.Suicide || info.Type == MyDamageType.Unknown)
                {
                    return;
                }

                info.Amount = 0;
            }
        }
        private IMyPlayer FindPlayer(IMyEngineerToolBase handTool)
        {
            List <IMyPlayer> players = new List <IMyPlayer>();

            MyAPIGateway.Players.GetPlayers(players);

            foreach (IMyPlayer player in players)
            {
                IMyCharacter character = player.Controller.ControlledEntity as IMyCharacter;

                if (character == null)
                {
                    continue;
                }

                // The most inefficient way of finding which player is equiped with what tool.
                // What is needed is either MyCharacter.CurrentWeapon, or MyEngineerToolBase.Owner exposed through the appropriate interface.
                MyObjectBuilder_Character c = character.GetObjectBuilder(true) as MyObjectBuilder_Character;
                if (c != null && c.HandWeapon != null && c.HandWeapon.EntityId == handTool.EntityId)
                {
                    return(player);
                }
            }

            return(null);
        }
示例#4
0
        private IMyEntity GridStandingOn(IMyCharacter character)
        {
            var GROUND_SEARCH = 2;
            var pos           = character.PositionComp.GetPosition();
            var worldRef      = character.PositionComp.WorldMatrixRef;

            rays_cache_.Clear();
            ray_tracer_.Hits.Clear();

            var up      = pos + worldRef.Up * 0.5;
            var down    = up + worldRef.Down * GROUND_SEARCH;
            var forward = worldRef.Forward * 0.2;
            var back    = -forward;

            GenerateRays(up, down, forward, back);

            var hits = ray_tracer_.CastRays(rays_cache_);

            var validHit = hits.FirstOrDefault(h => h != null && h.HitEntity != null && h.HitEntity != ((IMyCameraController)character).Entity.Components);

            if (validHit != null)
            {
                var entity = validHit.HitEntity.GetTopMostParent();

                if (Vector3D.DistanceSquared(validHit.Position, up) < (double)GROUND_SEARCH * GROUND_SEARCH)
                {
                    return(entity);
                }
            }
            return(null);
        }
示例#5
0
        /// <summary>
        /// if necessary, builds script for an entity
        /// </summary>
        /// <param name="entity"></param>
        private void Entities_OnEntityAdd(IMyEntity entity)
        {
            IMyCubeGrid asGrid = entity as IMyCubeGrid;

            if (asGrid != null)
            {
                List <IMySlimBlock> blocksInGrid = new List <IMySlimBlock>();
                asGrid.GetBlocks(blocksInGrid, slim => slim.FatBlock != null);
                foreach (IMySlimBlock slim in blocksInGrid)
                {
                    Grid_OnBlockAdded(slim);
                }
                asGrid.OnBlockAdded += Grid_OnBlockAdded;
                asGrid.OnClosing    += Grid_OnClosing;

                foreach (var constructor in GridScriptConstructors)
                {
                    constructor.Invoke(asGrid);
                }
                return;
            }
            IMyCharacter asCharacter = entity as IMyCharacter;

            if (asCharacter != null)
            {
                foreach (var constructor in CharacterScriptConstructors)
                {
                    constructor.Invoke(asCharacter);
                }
                return;
            }
        }
示例#6
0
        /// <summary>
        /// Tries to create a radio component for an entity. Creates the radio component if the entity is a radio antenna block, beacon block, or a character.
        /// </summary>
        /// <param name="obj">Entity to create the component for.</param>
        /// <returns>A new radio component for the entity, if it can be created. Null, otherwise.</returns>
        public static ComponentRadio TryCreateRadio(IMyEntity obj)
        {
            IMyRadioAntenna radioAnt = obj as IMyRadioAntenna;

            if (radioAnt != null)
            {
                return(new CR_AntennaBlock(radioAnt));
            }

            IMyBeacon beacon = obj as IMyBeacon;

            if (beacon != null)
            {
                return(new CR_BeaconBlock(beacon));
            }

            IMyCharacter character = obj as IMyCharacter;

            if (character != null)
            {
                return(new CR_Character(character));
            }

            return(null);
        }
示例#7
0
 public Character(IMyEntity entity)
     : base(entity)
 {
     Log.ClassName = "GP.Concealment.World.Entities.Character";
     Log.Trace("New Character " + Entity.EntityId + " " + DisplayName, "ctr");
     CharacterEntity = Entity as IMyCharacter;
 }
示例#8
0
        void DrawPaletteHUD()
        {
            PlayerInfo localInfo = Main.Palette.LocalInfo;

            if (localInfo == null)
            {
                return;
            }

            if (Main.LocalToolHandler.LocalTool != null && !MyAPIGateway.Gui.IsCursorVisible && !(Main.Settings.hidePaletteWithHUD && Main.GameConfig.HudState == HudState.OFF))
            {
                MatrixD camMatrix = MyAPIGateway.Session.Camera.WorldMatrix;

                float scaleFOV = (Main.DrawUtils.ScaleFOV * Main.Settings.paletteScale);

                IMyCharacter character = MyAPIGateway.Session.Player.Character;
                if (Utils.IsAimingDownSights(character))
                {
                    MyTransparentGeometry.AddPointBillboard(MATERIAL_DOT, Color.Lime, camMatrix.Translation + camMatrix.Forward * LocalToolHandler.PAINT_AIM_START_OFFSET, 0.005f, 0, blendType: AIM_DOT_BLEND_TYPE);
                }

                Vector3D worldPos = Main.DrawUtils.HUDtoWorld(Main.Settings.paletteScreenPos);
                float    bgAlpha  = (Main.Settings.paletteBackgroundOpacity < 0 ? Main.GameConfig.HudBackgroundOpacity : Main.Settings.paletteBackgroundOpacity);

                DrawColorSelector(camMatrix, worldPos, scaleFOV, bgAlpha);
                DrawSkinSelector(camMatrix, worldPos, scaleFOV, bgAlpha);
            }
        }
示例#9
0
        public static byte[] SerializeAndSign(IMyCubeGrid grid, IMyPlayer player, Vector3I block)
        {
            var          c     = grid.GetCubeBlock(block)?.FatBlock as IMyCockpit;
            IMyCharacter pilot = c?.Pilot;

            c?.RemovePilot();

            var ob = (MyObjectBuilder_CubeGrid)grid.GetObjectBuilder();

            if (pilot != null)
            {
                c.AttachPilot(pilot);
            }

            IMyFaction fac  = MyAPIGateway.Session.Factions.TryGetPlayerFaction(player.IdentityId);
            var        data = new ClientData(ob, fac, block, Settings.Instance.HubIP);

            string obStr    = MyAPIGateway.Utilities.SerializeToXML(data);
            string totalStr = DateTime.UtcNow.Ticks + obStr;
            string evalStr  = totalStr + Settings.Instance.Password;

            var m = new MD5();

            m.Value   = evalStr;
            totalStr += m.FingerPrint;

            return(Encoding.UTF8.GetBytes(totalStr));
        }
示例#10
0
        /// <summary>
        /// if necessary, builds script for an entity
        /// </summary>
        /// <param name="entity"></param>
        private void AddEntity(IMyEntity entity)
        {
            // the save flag is often on initially and disabled after
            if (!(entity.Save || entity is IMyCharacter))
            {
                return;
            }

            IMyCubeGrid asGrid = entity as IMyCubeGrid;

            if (asGrid != null)
            {
                List <IMySlimBlock> blocksInGrid = new List <IMySlimBlock>();
                asGrid.GetBlocks(blocksInGrid, slim => slim.FatBlock != null);
                foreach (IMySlimBlock slim in blocksInGrid)
                {
                    AddBlock(slim);
                }
                asGrid.OnBlockAdded += Grid_OnBlockAdded;
                asGrid.OnClosing    += Grid_OnClosing;

                foreach (var constructor in GridScriptConstructors)
                {
                    try { constructor.Invoke(asGrid); }
                    catch (Exception ex)
                    {
                        Log.AlwaysLog("Exception in grid constructor: " + ex, Logger.severity.ERROR);
                        Logger.DebugNotify("Exception in grid constructor", 10000, Logger.severity.ERROR);
                    }
                }
                return;
            }
            IMyCharacter asCharacter = entity as IMyCharacter;

            if (asCharacter != null)
            {
                if (!Characters.Add(entity.EntityId))
                {
                    return;
                }
                entity.OnClosing += alsoChar => {
                    if (Characters != null)
                    {
                        Characters.Remove(alsoChar.EntityId);
                    }
                };

                Log.DebugLog("adding character: " + entity.getBestName());
                foreach (var constructor in CharacterScriptConstructors)
                {
                    try { constructor.Invoke(asCharacter); }
                    catch (Exception ex)
                    {
                        Log.AlwaysLog("Exception in character constructor: " + ex, Logger.severity.ERROR);
                        Logger.DebugNotify("Exception in character constructor", 10000, Logger.severity.ERROR);
                    }
                }
                return;
            }
        }
        public void FixShipModLookedAt()
        {
            if (Context.Player == null)
            {
                Context.Respond("Console has no Character so cannot use this command. Use !fixshipmod <Gridname> instead!");
                return;
            }

            IMyCharacter character = Context.Player.Character;

            if (character == null)
            {
                Context.Respond("You have no Character currently. Make sure to spawn and be out of cockpit!");
                return;
            }

            var steamId = new SteamIdCooldownKey(PlayerUtils.GetSteamId(Context.Player));

            if (!CheckConformation(steamId, 0, "nogrid", character))
            {
                return;
            }

            try {
                var result = ShipFixerCore.Instance.FixShip(character, 0);
                WriteResponse(result);
            } catch (Exception e) {
                Log.Error(e, "Error on fixing ship");
            }
        }
示例#12
0
 /// <summary>
 ///     Register character events.
 /// </summary>
 /// <param name="character">The character.</param>
 private void RegisterEvents(IMyCharacter character)
 {
     if (character != null)
     {
         character.MovementStateChanged += OnMovementStateChanged;
     }
 }
示例#13
0
        public bool Confirm(long cost, ulong steamid)
        {
            IMyPlayer player = Context.Player;

            long playerId;

            if (player == null)
            {
                Context.Respond("Console cannot use this command!");
                return(false);
            }
            else
            {
                playerId = player.IdentityId;
            }

            IMyCharacter character = player.Character;

            if (character == null)
            {
                Context.Respond("You have no Character currently. Make sure to spawn and be out of cockpit!");
                return(false);
            }

            var currentCooldownMap = Plugin.CurrentCooldownMapCommand;

            if (currentCooldownMap.TryGetValue(steamid, out CurrentCooldown currentCooldown))
            {
                long remainingSeconds = currentCooldown.GetRemainingSeconds(null);

                if (remainingSeconds > 0)
                {
                    Log.Info("Cooldown for Player " + player.DisplayName + " still running! " + remainingSeconds + " seconds remaining!");
                    Context.Respond("Command is still on cooldown for " + remainingSeconds + " seconds.");
                    return(false);
                }

                currentCooldown = CreateNewCooldown(currentCooldownMap, steamid, Plugin.Cooldown);
            }
            else
            {
                currentCooldown = CreateNewCooldown(currentCooldownMap, steamid, Plugin.Cooldown);
            }

            if (!CheckConformation(cost, steamid, Context.Player.DisplayName))
            {
                return(false);
            }

            try {
                Log.Info("Cooldown for Player " + player.DisplayName + " started!");
                currentCooldown.StartCooldown(null);
                return(true);
            }
            catch (Exception e) {
                Log.Error(e);
                return(false);
            }
        }
示例#14
0
        public List <RayCastResult> CastRaysAroundPlayer(IMyCharacter character, double distance, int raysCount)
        {
            var position    = character.GetPosition();
            var orientation = character.PositionComp.GetOrientation();
            var forward     = orientation.Forward;

            return(CastRaysAroundPosition(position + orientation.Up, forward, distance, raysCount));
        }
示例#15
0
		public virtual void Init(IMyCharacter character, Dictionary<MyStringHash, MyEntityStat> stats, string scriptName)
		{
			m_scriptName = scriptName;
			Character = character;
			m_stats = stats;

			InitSettings();
		}
示例#16
0
        public virtual void Init(IMyCharacter character, Dictionary <MyStringHash, MyEntityStat> stats, string scriptName)
        {
            m_scriptName = scriptName;
            Character    = character;
            m_stats      = stats;

            InitSettings();
        }
示例#17
0
 public static IMyInventory GetPlayerInventory(this IMyCharacter character)
 {
     if (character == null)
     {
         return(null);
     }
     return(((MyEntity)character).GetInventory());
 }
示例#18
0
        /// <summary>
        /// Gets a name for an entity that can be shown to players. Assumes the entity has been detected in a fair way.
        /// </summary>
        /// <param name="entity">The entity to get the name for.</param>
        /// <param name="playerId">Who wants to know?</param>
        /// <returns>A name that can be shown to players.</returns>
        public static string GetNameForDisplay(this IMyEntity entity, long playerId)
        {
            IMyCubeGrid asGrid = entity as IMyCubeGrid;

            if (asGrid != null)
            {
                if (playerId.canConsiderFriendly(asGrid))
                {
                    return(asGrid.DisplayName);
                }
                else
                {
                    return(asGrid.SimpleName());
                }
            }

            IMyCubeBlock asBlock = entity as IMyCubeBlock;

            if (asBlock != null)
            {
                if (playerId.canConsiderFriendly(asBlock.OwnerId))
                {
                    return(asBlock.DisplayNameText + " on " + GetNameForDisplay(asBlock.CubeGrid, playerId));
                }
                else
                {
                    return(asBlock.DefinitionDisplayNameText + " on " + GetNameForDisplay(asBlock.CubeGrid, playerId));
                }
            }

            IMyCharacter asChar = entity as IMyCharacter;

            if (asChar != null)
            {
                if (string.IsNullOrEmpty(entity.DisplayName))
                {
                    return("Creature");
                }
                return(entity.DisplayName);
            }

            if (entity is IMyVoxelMap)
            {
                return("Asteroid");
            }

            if (entity is MyPlanet)
            {
                return("Planet");
            }

            if (entity.IsMissile())
            {
                return("Missile");
            }

            return(entity.getBestName());
        }
示例#19
0
        public static Relations getRelationsTo(this long identityId, IMyEntity target, Relations breakOn = Relations.NoOwner)
        {
            if (identityId == 0L)
            {
                return(Relations.NoOwner);
            }

            IMyCubeBlock asBlock = target as IMyCubeBlock;

            if (asBlock != null)
            {
                return(getRelationsTo(identityId, asBlock.OwnerId));
            }

            IMyCubeGrid asGrid = target as IMyCubeGrid;

            if (asGrid != null)
            {
                return(getRelationsTo(identityId, asGrid, breakOn));
            }

            IMyCharacter asChar = target as IMyCharacter;

            if (asChar != null)
            {
                if (asChar.IsBot)
                {
                    return(Relations.Enemy);
                }
                IMyPlayer player = asChar.GetPlayer_Safe();
                if (player != null)
                {
                    return(getRelationsTo(identityId, player.IdentityId));
                }

                Logger.DebugLog("character not found, treating as enemy: " + target.getBestName(), Logger.severity.WARNING);
                return(Relations.Enemy);
            }

            if (target is IMyMeteor)
            {
                return(Relations.Enemy);
            }

            if (target.IsMissile())
            {
                long missileOwner;
                if (GuidedMissile.TryGetOwnerId(target.EntityId, out missileOwner))
                {
                    return(getRelationsTo(identityId, missileOwner));
                }
                return(Relations.Enemy);
            }

            Logger.DebugLog("unknown entity, treating as enemy: " + target.getBestName(), Logger.severity.WARNING);
            return(Relations.Enemy);
        }
示例#20
0
        /// <summary>
        ///     Show a 'fuel low' warning.
        /// </summary>
        private static void ShowFuelLowWarningNotification(IMyCharacter character)
        {
            var soundEmitter = new MyEntity3DSoundEmitter((MyEntity)character);
            var pair         = new MySoundPair("ArcHudVocFuelLow");

            soundEmitter.PlaySingleSound(pair);

            MyAPIGateway.Utilities.ShowNotification(MyTexts.GetString(MySpaceTexts.NotificationFuelLow), 2500, "Red");
        }
示例#21
0
        public static float GetH2Level(this IMyCharacter character)
        {
            MyCharacterOxygenComponent comp;

            if (!character.Components.TryGet(out comp))
            {
                return(0);
            }
            return(comp.GetGasFillLevel(MyCharacterOxygenComponent.HydrogenId));
        }
示例#22
0
        public static float GetO2Level(this IMyCharacter character)
        {
            MyCharacterOxygenComponent comp;

            if (!character.Components.TryGet(out comp))
            {
                return(0);
            }
            return(comp.SuitOxygenLevel);
        }
示例#23
0
        /// <summary>
        ///     Calculates alignment to given gravity.
        /// </summary>
        /// <param name="character">The character for which this is calculated.</param>
        /// <param name="gravity">The gravity vector.</param>
        /// <param name="up">The up vector.</param>
        /// <param name="forward">The forward vector.</param>
        private static void CalculateAlignment(IMyCharacter character, ref Vector3 gravity, ref Vector3 up, ref Vector3 forward)
        {
            var invertedNormalizedGravity = -Vector3.Normalize(gravity);
            var direction = invertedNormalizedGravity;

            if (character.Physics != null)
            {
                var supportNormal = character.Physics.SupportNormal;
                var definition    = character.Definition as MyCharacterDefinition;
                if (definition != null)
                {
                    if (definition.RotationToSupport == MyEnumCharacterRotationToSupport.OneAxis)
                    {
                        var num1 = invertedNormalizedGravity.Dot(ref supportNormal);
                        if (!MyUtils.IsZero(num1 - 1f) && !MyUtils.IsZero(num1 + 1f))
                        {
                            var cross = invertedNormalizedGravity.Cross(supportNormal);
                            cross.Normalize();
                            direction = Vector3.Lerp(supportNormal, invertedNormalizedGravity, Math.Abs(cross.Dot(character.WorldMatrix.Forward)));
                        }
                    }
                    else if (definition.RotationToSupport == MyEnumCharacterRotationToSupport.Full)
                    {
                        direction = supportNormal;
                    }
                }
            }

            var dot = Vector3.Dot(up, direction) / (up.Length() * direction.Length());

            if (float.IsNaN(dot) || float.IsNegativeInfinity(dot) || float.IsPositiveInfinity(dot))
            {
                dot = 1f;
            }

            dot = MathHelper.Clamp(dot, -1f, 1f);
            if (MyUtils.IsZero(dot - 1f, 1E-08f))
            {
                return;
            }

            var angle = !MyUtils.IsZero(dot + 1f, 1E-08f) ? (float)Math.Acos(dot) : 0.1f;

            angle = Math.Min(Math.Abs(angle), 0.04f) * Math.Sign(angle);
            var axis = Vector3.Cross(up, direction);

            if (axis.LengthSquared() <= 0.0)
            {
                return;
            }

            axis    = Vector3.Normalize(axis);
            up      = Vector3.TransformNormal(up, Matrix.CreateFromAxisAngle(axis, angle));
            forward = Vector3.TransformNormal(forward, Matrix.CreateFromAxisAngle(axis, angle));
        }
示例#24
0
        public static ulong GetPlayerSteamId(IMyCharacter character)
        {
            IMyPlayer player = MyAPIGateway.Players.GetPlayerControllingEntity(character);

            if (player == null)
            {
                player = MyAPIGateway.Players.GetPlayerControllingEntity(character.Parent);
            }

            return(player != null ? player.SteamUserId : ulong.MinValue);
        }
示例#25
0
        public static long GetPlayerIdentityId(IMyCharacter character)
        {
            IMyPlayer player = MyAPIGateway.Players.GetPlayerControllingEntity(character);

            if (player == null)
            {
                player = MyAPIGateway.Players.GetPlayerControllingEntity(character.Parent);
            }

            return(player != null ? player.IdentityId : 0);
        }
示例#26
0
        public static IMyPlayer GetPlayer(IMyCharacter character)
        {
            IMyPlayer player = MyAPIGateway.Players.GetPlayerControllingEntity(character);

            if (player == null)
            {
                player = MyAPIGateway.Players.GetPlayerControllingEntity(character.Parent);
            }

            return(player);
        }
示例#27
0
        bool IsHoldingPaintGun()
        {
            if (!OwnerIsLocalPlayer)
            {
                return(false);
            }

            IMyCharacter chr = MyAPIGateway.Session.ControlledObject as IMyCharacter;

            return(chr != null && chr.EquippedTool == Rifle);
        }
示例#28
0
 /// <summary>
 ///     Will enable dampeners when grid is not moving or planetary gravity is detected and no ground is in range.
 /// </summary>
 private void ToggleDampenersIfNeeded(IMyCharacter character, bool isNotMoving, bool hasGravity, bool isGroundInRange, bool lastDampenerState)
 {
     if (Mod.Static.Settings.DisableAutoDampener != DisableAutoDampenerOption.Mod)
     {
         var dampenersRequired = Mod.Static.Settings.DisableAutoDampener == DisableAutoDampenerOption.All ? lastDampenerState : isNotMoving || hasGravity && !isGroundInRange;
         if (character.EnabledDamping != dampenersRequired)
         {
             character.SwitchDamping();
         }
     }
 }
示例#29
0
        void IUpdatable.Update()
        {
            IMyCharacter    chr     = MyAPIGateway.Session?.ControlledObject as IMyCharacter;
            IMyAngleGrinder grinder = chr?.EquippedTool as IMyAngleGrinder;

            if (EquippedGrinder != grinder)
            {
                EquippedGrinder = grinder;
                GrinderChanged?.Invoke(grinder);
            }
        }
		public override void Init(IMyCharacter character, Dictionary<MyStringHash, MyEntityStat> stats, string scriptName)
		{
			base.Init(character, stats, scriptName);

			InitPermanentEffects();
			InitActions();

			var health = Health;
			if (health != null)
				health.OnStatChanged += OnHealthChanged;
		}
        public void FixShipPlayerLookAt()
        {
            IMyPlayer player = Context.Player;

            long playerId;

            if (player == null)
            {
                Context.Respond("Console has no Grids so cannot use this command. Use !fixshipmod <Gridname> instead!");
                return;
            }
            else
            {
                playerId = player.IdentityId;
            }

            IMyCharacter character = player.Character;

            if (character == null)
            {
                Context.Respond("You have no Character currently. Make sure to spawn and be out of cockpit!");
                return;
            }

            CooldownManager cooldownManager = Plugin.CommandCooldownManager;

            var steamId = new SteamIdCooldownKey(PlayerUtils.GetSteamId(Context.Player));

            if (!cooldownManager.CheckCooldown(steamId, null, out long remainingSeconds))
            {
                Log.Info("Cooldown for Player " + player.DisplayName + " still running! " + remainingSeconds + " seconds remaining!");
                Context.Respond("Command is still on cooldown for " + remainingSeconds + " seconds.");
                return;
            }

            if (!CheckConformation(steamId, playerId, "nogrid", character))
            {
                return;
            }

            try {
                var result = Plugin.FixShip(character, playerId);
                WriteResponse(result);

                if (result == CheckResult.SHIP_FIXED)
                {
                    Log.Info("Cooldown for Player " + player.DisplayName + " started!");
                    cooldownManager.StartCooldown(steamId, null, Plugin.Cooldown);
                }
            } catch (Exception e) {
                Log.Error(e, "Error on fixing ship");
            }
        }
示例#32
0
文件: RelayNode.cs 项目: zrisher/ARMS
        /// <summary>
        /// Creates a NetworkNode for a character, checking radio communication.
        /// </summary>
        /// <param name="character">The character to create the NetworkNode for.</param>
        public RelayNode(IMyCharacter character)
        {
            IMyPlayer player = character.GetPlayer_Safe();

            this.m_debugName  = () => player.DisplayName;
            this.m_ownerId    = () => player.IdentityId;
            this.m_entity     = character as IMyEntity;
            this.m_player     = player;
            this.m_comp_radio = ComponentRadio.CreateRadio(character);

            Registrar.Add(character as IMyEntity, this);
        }
示例#33
0
        protected override void StartEffect(IMyCubeBlock block)
        {
            IMyCharacter pilot = (block as MyCockpit).Pilot as IMyCharacter;

            if (pilot == null)
            {
                return;
            }

            Logger.DebugLog("Killing: " + pilot + ", in " + block.DisplayNameText);
            pilot.Kill();
        }
示例#34
0
        /// <summary>
        /// Creates a NetworkNode for a character, checking radio communication.
        /// </summary>
        /// <param name="character">The character to create the NetworkNode for.</param>
        public RelayNode(IMyCharacter character)
        {
            IMyPlayer player = character.GetPlayer_Safe();

            this.m_loggingName = () => player.DisplayName;
            this.m_logger = new Logger(GetType().Name, this.m_loggingName) { MinimumLevel = Logger.severity.INFO };
            this.m_ownerId = () => player.PlayerID;
            this.m_entity = character as IMyEntity;
            this.m_player = player;
            this.m_comp_radio = ComponentRadio.CreateRadio(character);

            Registrar.Add(character as IMyEntity, this);
        }
示例#35
0
文件: Ladder.cs 项目: THDigi/Ladder
        private void SetCharacterReference(IMyEntity ent)
        {
            if(character == ent || !(ent is IMyCharacter))
                return;

            if(character != null)
                character.OnMovementStateChanged -= CharacterMovementStateChanged;

            character = ent as IMyCharacter;

            if(character == null)
                return;

            characterDefinition = GetCharacterDefinitionFrom(ent);
            character.OnMovementStateChanged += CharacterMovementStateChanged;
        }
示例#36
0
文件: Ladder.cs 项目: THDigi/Ladder
        private void PlayerUpdate()
        {
            var playerControlled = MyAPIGateway.Session.ControlledObject;

            if(playerControlled != null)
            {
                if(playerControlled.Entity is IMyCharacter)
                {
                    SetCharacterReference(playerControlled.Entity);
                }
                else if(playerControlled.Entity is IMyCockpit) // in a seat, certainly not gonna climb ladders
                {
                    SetCharacterReference(null);
                }
                // other cases depend on having the character controlled for a bit to get the reference
                else if(character != null && character.Closed)
                {
                    SetCharacterReference(null);
                }
            }
            else
            {
                character = null;
            }

            if(character != null)
            {
                var cb = MyCubeBuilder.Static;

                // Dynamically enable/disable UseModelIntersection on ladder blocks that you hold to have the useful effect
                // of being able the block when another entity is blocking the grid space but not the blocks's physical shape.
                // This will still have the side effect issue if you aim at a ladder block with the same ladder block.
                if(cb.IsActivated && cb.CubeBuilderState != null && cb.CubeBuilderState.CurrentBlockDefinition != null && LadderLogic.ladderIds.Contains(cb.CubeBuilderState.CurrentBlockDefinition.Id.SubtypeName))
                {
                    if(prevCubeBuilderDefinition == null || prevCubeBuilderDefinition.Id != cb.CubeBuilderState.CurrentBlockDefinition.Id)
                    {
                        if(prevCubeBuilderDefinition != null)
                            prevCubeBuilderDefinition.UseModelIntersection = false;

                        prevCubeBuilderDefinition = cb.CubeBuilderState.CurrentBlockDefinition;
                        cb.CubeBuilderState.CurrentBlockDefinition.UseModelIntersection = true;
                    }
                }
                else if(prevCubeBuilderDefinition != null)
                {
                    prevCubeBuilderDefinition.UseModelIntersection = false;
                    prevCubeBuilderDefinition = null;
                }

                var charCtrl = character as IMyControllableEntity;
                bool controllingCharacter = (playerControlled != null && playerControlled.Entity is IMyCharacter);
                IMyTerminalBlock ladder = null;
                MyCubeBlock ladderInternal = null;

                MatrixD ladderMatrix = character.WorldMatrix; // temporarily using it for character matrix, then used for ladder matrix
                var charPos = ladderMatrix.Translation + ladderMatrix.Up * 0.05;
                var charPos2 = ladderMatrix.Translation + ladderMatrix.Up * RAY_HEIGHT;
                var charRay = new RayD(charPos, ladderMatrix.Up);

                if(dismounting <= 1) // relative top dismount sequence
                {
                    if(usingLadder == null)
                    {
                        dismounting = 2;
                        return;
                    }

                    ladder = usingLadder;
                    ladderInternal = ladder as MyCubeBlock;
                    dismounting *= ALIGN_MUL;

                    if(settings.clientPrediction)
                    {
                        ladderMatrix = ladder.WorldMatrix;
                        var charOnLadder = ladderMatrix.Translation + ladderMatrix.Forward * (ladderInternal.BlockDefinition.ModelOffset.Z + EXTRA_OFFSET_Z);

                        if(ladder.CubeGrid.GridSizeEnum == MyCubeSize.Large)
                            charOnLadder += ladderMatrix.Backward;

                        var topDir = Vector3D.Dot(character.WorldMatrix.Up, ladderMatrix.Up);
                        var matrix = character.WorldMatrix;
                        var halfY = ((ladderInternal.BlockDefinition.Size.Y * ladder.CubeGrid.GridSize) / 2);
                        matrix.Translation = charOnLadder + (topDir > 0 ? ladderMatrix.Up : ladderMatrix.Down) * (halfY + 0.1f) + ladderMatrix.Backward * 0.75;

                        character.SetWorldMatrix(MatrixD.SlerpScale(character.WorldMatrix, matrix, MathHelper.Clamp(dismounting, 0.0f, 1.0f)));

                        character.Physics.LinearVelocity = ladder.CubeGrid.Physics.GetVelocityAtPoint(character.WorldMatrix.Translation); // sync velocity with the ladder
                    }

                    SetLadderStatus("Dismounting ladder...", MyFontEnum.White);

                    if(dismounting > 1f)
                        ExitLadder(false);

                    return;
                }

                // UNDONE DEBUG
                //{
                //    var c = Color.Blue.ToVector4();
                //    MySimpleObjectDraw.DrawLine(charPos, charPos2, "WeaponLaserIgnoreDepth", ref c, 0.5f);
                //}

                // find a ladder
                foreach(var l in ladders.Values)
                {
                    if(l.Closed || l.MarkedForClose || !l.IsFunctional)
                        continue;

                    if(Vector3D.DistanceSquared(l.WorldMatrix.Translation, charPos) <= UPDATE_RADIUS)
                    {
                        ladderInternal = l as MyCubeBlock;
                        ladderMatrix = l.WorldMatrix;

                        // update ladder oriented box to find character in it accurately
                        Quaternion.CreateFromRotationMatrix(ref ladderMatrix, out ladderBox.Orientation);

                        if(l is MyAdvancedDoor && !(l as MyAdvancedDoor).FullyOpen)
                        {
                            ladderBox.HalfExtent = (ladderInternal.BlockDefinition.Size * l.CubeGrid.GridSize) / 2;

                            var offset = ladderInternal.BlockDefinition.ModelOffset;
                            ladderBox.Center = ladderMatrix.Translation + ladderMatrix.Up * 1.125f + ladderMatrix.Forward * (offset.Z + EXTRA_OFFSET_Z);

                            ladderBox.HalfExtent.Y = 0.25 + 0.06; // 6mm offset to avoid some inaccuracies
                            ladderBox.HalfExtent.Z = 0.5;

                            if(l.CubeGrid.GridSizeEnum == MyCubeSize.Large)
                                ladderBox.Center += ladderMatrix.Backward;
                        }
                        else
                        {
                            ladderBox.HalfExtent = (ladderInternal.BlockDefinition.Size * l.CubeGrid.GridSize) / 2;
                            ladderBox.HalfExtent.Y += 0.06; // 6mm offset to avoid some inaccuracies
                            ladderBox.HalfExtent.Z = 0.5;

                            var offset = ladderInternal.BlockDefinition.ModelOffset;
                            ladderBox.Center = ladderMatrix.Translation + ladderMatrix.Forward * (offset.Z + EXTRA_OFFSET_Z);

                            if(l.CubeGrid.GridSizeEnum == MyCubeSize.Large)
                                ladderBox.Center += ladderMatrix.Backward;
                        }

                        if(!ladderBox.Contains(ref charPos) && !ladderBox.Contains(ref charPos2))
                        {
                            var intersect = ladderBox.Intersects(ref charRay);

                            if(!intersect.HasValue || intersect.Value < 0 || intersect.Value > RAY_HEIGHT)
                                continue;
                        }

                        // UNDONE DEBUG
                        //{
                        //    {
                        //        var c = Color.Red.ToVector4();
                        //        MySimpleObjectDraw.DrawLine(ladderBox.Center + ladderMatrix.Down * ladderBox.HalfExtent.Y, ladderBox.Center + ladderMatrix.Up * ladderBox.HalfExtent.Y, "WeaponLaserIgnoreDepth", ref c, 0.01f);
                        //    }
                        //
                        //    if(debugBox == null)
                        //    {
                        //        debugBox = new MyEntity();
                        //        debugBox.Init(null, @"Models\Debug\Error.mwm", null, null, null);
                        //        debugBox.PositionComp.LocalMatrix = Matrix.Identity;
                        //        debugBox.Flags = EntityFlags.Visible | EntityFlags.NeedsDraw | EntityFlags.NeedsDrawFromParent | EntityFlags.InvalidateOnMove;
                        //        debugBox.OnAddedToScene(null);
                        //        debugBox.Render.Transparency = 0.5f;
                        //        debugBox.Render.RemoveRenderObjects();
                        //        debugBox.Render.AddRenderObjects();
                        //    }
                        //    var matrix = MatrixD.CreateWorld(ladderBox.Center, ladderMatrix.Forward, ladderMatrix.Up);
                        //    var scale = ladderBox.HalfExtent * 2;
                        //    MatrixD.Rescale(ref matrix, ref scale);
                        //    debugBox.PositionComp.SetWorldMatrix(matrix);
                        //}

                        ladder = l;
                        ladderInternal = l as MyCubeBlock;
                        break;
                    }
                }

                if(ladder != null)
                {
                    var offset = ladderInternal.BlockDefinition.ModelOffset;
                    var charOnLadder = ladderMatrix.Translation + ladderMatrix.Forward * (offset.Z + EXTRA_OFFSET_Z);

                    if(ladder.CubeGrid.GridSizeEnum == MyCubeSize.Large)
                        charOnLadder += ladderMatrix.Backward;

                    if(++skipRetryGravity >= GRAVITY_UPDATERATE)
                    {
                        skipRetryGravity = 0;
                        alignedToGravity = true;
                        var gravity = MyParticlesManager.CalculateGravityInPoint(character.WorldMatrix.Translation);
                        var gravityLength = gravity.Normalize();

                        if(gravityLength > 0)
                        {
                            float gravDot = Vector3.Dot(gravity, ladderMatrix.Down);

                            if(!(gravDot >= 0.9f || gravDot <= -0.9f))
                            {
                                alignedToGravity = false;
                            }
                        }
                    }

                    //bool readInput = InputHandler.IsInputReadable(); // HACK use before GetPressedOr() once ActiveGameplayScreen's NRE is resolved

                    if(!alignedToGravity)
                    {
                        bool pressed = InputHandler.GetPressedOr(settings.useLadder1, settings.useLadder2, false, false) && InputHandler.IsInputReadable(); // needs to support hold-press, so don't set JustPressed to true!

                        if(pressed)
                            SetLadderStatus("Gravity not parallel to ladder!", MyFontEnum.Red, 1000);

                        if(usingLadder != null)
                            ExitLadder(false);

                        return;
                    }

                    if(usingLadder == null) // first ladder interaction
                    {
                        //var controlUse = MyAPIGateway.Input.GetGameControl(MyControlsSpace.USE);
                        //
                        //if(!controlUse.IsPressed())
                        //{
                        //    string assigned = (controlUse.GetKeyboardControl() != MyKeys.None ? MyAPIGateway.Input.GetKeyName(controlUse.GetKeyboardControl()) : (controlUse.GetMouseControl() != MyMouseButtonsEnum.None ? MyAPIGateway.Input.GetName(controlUse.GetMouseControl()) : "(NONE)")) + (controlUse.GetSecondKeyboardControl() != MyKeys.None ? " or " + MyAPIGateway.Input.GetKeyName(controlUse.GetSecondKeyboardControl()) : null);
                        //    SetLadderStatus("Press "+assigned+" to use the ladder.", MyFontEnum.White);
                        //    return;
                        //}

                        if(grabOnLoad)
                        {
                            grabOnLoad = false;
                        }
                        else
                        {
                            aimingAtLadder = true;

                            if(settings.useLadder1 == null && settings.useLadder2 == null)
                            {
                                SetLadderStatus("Ladder interaction is unassigned, edit the settings.cfg file!\nFor now you can use the USE key.", MyFontEnum.Red);

                                if(!MyAPIGateway.Input.IsGameControlPressed(MyControlsSpace.USE))
                                    return;
                            }
                            else
                            {
                                bool pressed = InputHandler.GetPressedOr(settings.useLadder1, settings.useLadder2, false, false) && InputHandler.IsInputReadable(); // needs to support hold-press, so don't set JustPressed to true!

                                if(!pressed)
                                {
#if !STABLE // STABLE CONDITION
                                    if(!highlightedLadders.Contains(ladder.EntityId))
                                    {
                                        if(highlightedLadders.Count > 0)
                                        {
                                            foreach(var id in highlightedLadders)
                                            {
                                                MyVisualScriptLogicProvider.SetHighlight(LADDER_NAME_PREFIX + id, false);
                                            }

                                            highlightedLadders.Clear();
                                        }

                                        var envDef = MyDefinitionManager.Static.EnvironmentDefinition;
                                        var color = envDef.ContourHighlightColor;
                                        var thick = (int)envDef.ContourHighlightThickness;

                                        highlightedLadders.Add(ladder.EntityId);
                                        MyVisualScriptLogicProvider.SetHighlight(ladder.Name, true, thick, LADDER_HIGHLIGHT_PULSE, color);

                                        var ladderGrid = ladder.CubeGrid;

                                        for(int i = 1; i <= 10; i++)
                                        {
                                            var slim = ladderGrid.GetCubeBlock(ladderGrid.WorldToGridInteger(ladderMatrix.Translation + ladderMatrix.Up * i * ladderGrid.GridSize));

                                            if(slim?.FatBlock?.GameLogic?.GetAs<LadderLogic>() == null)
                                                break;

                                            var id = slim.FatBlock.EntityId;
                                            highlightedLadders.Add(id);
                                            MyVisualScriptLogicProvider.SetHighlight(LADDER_NAME_PREFIX + id, true, thick, LADDER_HIGHLIGHT_PULSE, color);
                                        }

                                        for(int i = 1; i <= 10; i++)
                                        {
                                            var slim = ladderGrid.GetCubeBlock(ladderGrid.WorldToGridInteger(ladderMatrix.Translation + ladderMatrix.Down * i * ladderGrid.GridSize));

                                            if(slim?.FatBlock?.GameLogic?.GetAs<LadderLogic>() == null)
                                                break;

                                            var id = slim.FatBlock.EntityId;
                                            highlightedLadders.Add(id);
                                            MyVisualScriptLogicProvider.SetHighlight(LADDER_NAME_PREFIX + id, true, thick, LADDER_HIGHLIGHT_PULSE, color);
                                        }
                                    }
#endif

                                    SetLadderStatus("Press " + InputHandler.GetFriendlyStringOr(settings.useLadder1, settings.useLadder2) + " to use the ladder.", MyFontEnum.White);
                                    return;
                                }
                            }
                        }

                        skipRefreshAnim = 60;
                        mounting = (controllingCharacter ? ALIGN_STEP : 2);
                        usingLadder = ladder;
                        SendLadderData(LadderAction.MOUNT, entId: ladder.EntityId);
                        LadderAnim(character, LadderAnimation.MOUNTING);
                    }

                    if(usingLadder != ladder)
                    {
                        usingLadder = ladder;
                        SendLadderData(LadderAction.CHANGE_LADDER, entId: ladder.EntityId);
                    }

                    if(charCtrl.Entity.Physics == null)
                    {
                        ExitLadder(false);
                        return;
                    }

                    if(settings.clientPrediction)
                        character.Physics.LinearVelocity = ladder.CubeGrid.Physics.GetVelocityAtPoint(character.WorldMatrix.Translation); // sync velocity with the ladder

                    if(skipRefreshAnim > 0 && --skipRefreshAnim == 0) // force refresh animation after mounting due to an issue
                    {
                        var anim = lastLadderAnim;
                        lastLadderAnim = LadderAnimation.NONE;
                        LadderAnim(character, anim);
                    }

                    if(mounting <= 1) // mounting on ladder sequence
                    {
                        mounting *= ALIGN_MUL;

                        if(settings.clientPrediction)
                        {
                            float align = Vector3.Dot(ladderMatrix.Up, character.WorldMatrix.Up);

                            var matrix = MatrixD.CreateFromDir(ladderMatrix.Backward, (align > 0 ? ladderMatrix.Up : ladderMatrix.Down));
                            var halfY = ((ladderInternal.BlockDefinition.Size.Y * ladder.CubeGrid.GridSize) / 2);
                            var diff = Vector3D.Dot(character.WorldMatrix.Translation, ladderMatrix.Up) - Vector3D.Dot(charOnLadder, ladderMatrix.Up);
                            matrix.Translation = charOnLadder + ladderMatrix.Up * MathHelper.Clamp(diff, -halfY, halfY);

                            character.SetWorldMatrix(MatrixD.SlerpScale(character.WorldMatrix, matrix, MathHelper.Clamp(mounting, 0.0f, 1.0f)));
                        }

                        if(mounting >= 0.75f && charCtrl.EnabledThrusts) // delayed turning off thrusts because gravity aligns you faster and can make you fail to attach to the ladder
                            charCtrl.SwitchThrusts();

                        SetLadderStatus("Mounting ladder...", MyFontEnum.White);
                        return;
                    }

                    // TODO jetpack assited climb/descend ? / gravity assisted descend ?

                    if(charCtrl.EnabledThrusts)
                    {
                        if(!learned[4])
                            learned[4] = true;

                        ExitLadder(false); // leave ladder if jetpack is turned on
                        return;
                    }

                    // HACK use once input reading NRE is fixed
                    //if(!controllingCharacter) // disable ladder control if not controlling character
                    //    readInput = false;

                    bool movingSideways = false;
                    var analogInput = MyAPIGateway.Input.GetPositionDelta();

                    // HACK use in-line once NRE is fixed
                    if(!controllingCharacter)
                        analogInput = Vector3.Zero;
                    else if(analogInput.LengthSquared() > 0 && !InputHandler.IsInputReadable())
                        analogInput = Vector3.Zero;

                    if(analogInput.Y < 0) // crouch
                    {
                        if(!learned[4])
                            learned[4] = true;

                        ExitLadder(false);
                        return;
                    }

                    float move = MathHelper.Clamp((float)Math.Round(-analogInput.Z, 1), -1, 1); // forward/backward
                    float side = MathHelper.Clamp((float)Math.Round(analogInput.X, 1), -1, 1); // left/right

                    //float move = readInput ? MathHelper.Clamp(MyAPIGateway.Input.GetGameControlAnalogState(MyControlsSpace.FORWARD) - MyAPIGateway.Input.GetGameControlAnalogState(MyControlsSpace.BACKWARD), -1, 1) : 0;
                    //float side = readInput ? MathHelper.Clamp(MyAPIGateway.Input.GetGameControlAnalogState(MyControlsSpace.STRAFE_RIGHT) - MyAPIGateway.Input.GetGameControlAnalogState(MyControlsSpace.STRAFE_LEFT), -1, 1) : 0;
                    var alignVertical = ladderMatrix.Up.Dot(character.WorldMatrix.Up);

                    if(!loadedAllLearned)
                    {
                        bool allLearned = (learned[0] && learned[1] && learned[2] && learned[3] && learned[4]);

                        for(int i = 0; i < learned.Length; i++)
                        {
                            if(learnNotify[i] == null)
                                learnNotify[i] = MyAPIGateway.Utilities.CreateNotification("");

                            learnNotify[i].Text = (learned[i] ? LEARN_CHECK : LEARN_UNCHECK) + learnText[i];
                            learnNotify[i].Font = (learned[i] ? MyFontEnum.White : MyFontEnum.DarkBlue);
                            learnNotify[i].AliveTime = (allLearned ? 1000 : 100);
                            learnNotify[i].Show();
                        }

                        if(allLearned)
                        {
                            SaveLearn();
                            loadedAllLearned = true;
                        }
                    }

                    var view = MyAPIGateway.Session.ControlledObject.GetHeadMatrix(false, true);
                    float lookVertical = Vector3.Dot(character.WorldMatrix.Up, view.Forward);

                    if(settings.relativeControls) // climbing relative to camera
                    {
                        float verticalModifier = MathHelper.Clamp((lookVertical + 0.65f) / 0.5f, -0.5f, 1.0f);

                        if(verticalModifier < 0)
                            verticalModifier *= 2;

                        move = (float)Math.Round(move * verticalModifier, 1);
                    }

                    if(analogInput.Y > 0) // jump
                    {
                        if(characterMovementState == MyCharacterMovementEnum.Jump) // this is still fine for avoiding jump as the character still is able to jump without needing feet on the ground
                        {
                            ExitLadder(false); // only release if on the floor as the character will jump regardless
                            return;
                        }

                        if(settings.clientPrediction)
                            character.Physics.LinearVelocity += view.Forward * (characterDefinition == null ? VEL_JUMP : 200 * characterDefinition.JumpForce) * TICKRATE;

                        SendLadderData(LadderAction.JUMP_OFF, vec: view.Forward);
                        LadderAnim(character, LadderAnimation.JUMP_OFF);

                        if(!learned[3])
                            learned[3] = true;

                        ExitLadder(false);
                        return;
                    }

                    bool sprint = (characterDefinition != null && characterDefinition.Jetpack != null && MyAPIGateway.Input.IsGameControlPressed(MyControlsSpace.SPRINT));

                    if(Math.Abs(side) > 0.0001f)
                    {
                        if(settings.relativeControls) // side dismounting relative to camera
                        {
                            var alignForward = ladderMatrix.Backward.Dot(character.WorldMatrix.Forward);

                            if(alignForward < 0)
                                side = -side;
                        }

                        float speed = (characterDefinition == null ? (sprint ? VEL_SIDE : VEL_CLIMB) : CHAR_SPEED_MUL * (sprint ? characterDefinition.MaxSprintSpeed : characterDefinition.MaxRunStrafingSpeed));

                        if(settings.clientPrediction)
                            character.Physics.LinearVelocity += side * (alignVertical > 0 ? ladderMatrix.Left : ladderMatrix.Right) * speed * TICKRATE;

                        LadderAnim(character, (side > 0 ? LadderAnimation.DISMOUNT_LEFT : LadderAnimation.DISMOUNT_RIGHT));
                        movingSideways = true;

                        if(!learned[2])
                            learned[2] = true;
                    }
                    else
                    {
                        // aligning player to ladder

                        if(settings.clientPrediction)
                        {
                            Vector3 dir = charOnLadder - charPos;
                            Vector3 vel = dir - (ladderMatrix.Up * Vector3D.Dot(dir, ladderMatrix.Up)); // projecting up/down direction to ignore it
                            float len = vel.Normalize();

                            if(len >= ALIGN_ACCURACY)
                            {
                                float speed = (characterDefinition == null ? (sprint ? VEL_SIDE : VEL_CLIMB) : CHAR_SPEED_MUL * (sprint ? characterDefinition.MaxRunStrafingSpeed : characterDefinition.MaxWalkStrafingSpeed));
                                len = MathHelper.Clamp(len, 0.1f, 1);
                                character.Physics.LinearVelocity += vel * len * speed * TICKRATE;
                            }
                        }
                    }

                    // TODO find a way to control view
                    {
                        //var ctrl2 = (Sandbox.Game.Entities.IMyControllableEntity)character;
                        //
                        //ctrl2.HeadLocalYAngle = 0;
                        //ctrl2.HeadLocalXAngle = 0;
                        //
                        // or MoveAndRotate() ?
                        // or... angularvelocity ?
                        // or I dunno!
                    }

                    if(Math.Abs(move) > 0.0001f)
                    {
                        if(!learned[0])
                            learned[0] = true;

                        var halfY = ((ladderInternal.BlockDefinition.Size.Y * ladder.CubeGrid.GridSize) / 2);
                        var edge = charOnLadder + ((alignVertical > 0 ? ladderMatrix.Up : ladderMatrix.Down) * halfY);

                        // climb over at the end when climbing up
                        if(move > 0 && Vector3D.DistanceSquared(charPos, edge) <= 0.0625) // 0.25 squared
                        {
                            var nextBlockWorldPos = ladderMatrix.Translation + ladderMatrix.Forward * offset.Z + ((alignVertical > 0 ? ladderMatrix.Up : ladderMatrix.Down) * (halfY + 0.1f));
                            var nextBlockPos = ladder.CubeGrid.WorldToGridInteger(nextBlockWorldPos);
                            var slim = ladder.CubeGrid.GetCubeBlock(nextBlockPos);

                            // if the next block is not a ladder, dismount
                            if(slim == null || !(slim.FatBlock is IMyTerminalBlock) || !LadderLogic.ladderIds.Contains(slim.FatBlock.BlockDefinition.SubtypeId))
                            {
                                dismounting = ALIGN_STEP;
                                SendLadderData(LadderAction.DISMOUNT);
                                return;
                            }
                        }

                        // on the floor and moving backwards makes you dismount
                        if(move < 0)
                        {
                            var feetStart = character.WorldMatrix.Translation + character.WorldMatrix.Up * 0.2; // a bit higher because the floor might clip through the character
                            var feetTarget = feetStart + character.WorldMatrix.Down * 0.3;
                            IHitInfo hit;

                            if(MyAPIGateway.Physics.CastRay(feetStart, feetTarget, out hit, COLLISSIONLAYER_NOCHARACTER))
                            {
                                // need to check the block under the ladder if it's anything but a ladder because "standing" stance occurs when character rests on its chest-sphere collision mesh too
                                var prevBlockWorldPos = ladderMatrix.Translation + ladderMatrix.Forward * offset.Z + (alignVertical > 0 ? ladderMatrix.Down : ladderMatrix.Up) * (halfY + 0.1f);
                                var prevBlockPos = ladder.CubeGrid.WorldToGridInteger(prevBlockWorldPos);
                                var slim = ladder.CubeGrid.GetCubeBlock(prevBlockPos);

                                // if it's not a ladder, check the distance and confirm your feet are close to its edge
                                if(slim == null || !(slim.FatBlock is IMyTerminalBlock) || !LadderLogic.ladderIds.Contains(slim.FatBlock.BlockDefinition.SubtypeId))
                                {
                                    // get the block's edge and the character feet position only along the ladder's up/down axis
                                    var blockPosProjectedUp = ladderMatrix.Up * Vector3D.Dot(prevBlockWorldPos, ladderMatrix.Up);
                                    var charPosProjectedUp = ladderMatrix.Up * Vector3D.Dot(character.WorldMatrix.Translation, ladderMatrix.Up);

                                    if(Vector3D.DistanceSquared(blockPosProjectedUp, charPosProjectedUp) <= 0.04) // 0.2 squared
                                    {
                                        ExitLadder(false); // to recap: if you're moving char-relative down and in "standing" stance and the block below is not a ladder and you're closer than 0.1m to its edge, then let go of the ladder.
                                        return;
                                    }
                                }
                            }
                        }

                        // climbing on the ladder

                        if(!learned[1] && sprint)
                            learned[1] = true;

                        float speed = (characterDefinition == null ? (sprint ? VEL_SPRINT : VEL_CLIMB) : CHAR_SPEED_MUL * (sprint ? characterDefinition.MaxSprintSpeed : characterDefinition.MaxRunSpeed));

                        if(settings.clientPrediction)
                            character.Physics.LinearVelocity += (alignVertical > 0 ? ladderMatrix.Up : ladderMatrix.Down) * move * speed * TICKRATE;

                        if(!movingSideways)
                            LadderAnim(character, (move > 0 ? LadderAnimation.UP : LadderAnimation.DOWN));
                    }
                    else if(!movingSideways)
                    {
                        LadderAnim(character, LadderAnimation.IDLE);
                    }

                    SendLadderData(LadderAction.CLIMB,
                                   climb: (alignVertical > 0 ? move : -move),
                                   side: (alignVertical > 0 ? side : -side),
                                   sprint: sprint);

                    return;
                }
            }

            ExitLadder();
        }
示例#37
0
 public Character(VRage.ByteStream stream)
     : base(stream)
 {
     CharacterEntity = Entity as IMyCharacter;
 }
示例#38
0
 public CharacterStateTracker(IMyCharacter character)
 {
     Registrar.Add((IMyEntity)character, this);
     character.OnMovementStateChanged += character_OnMovementStateChanged;
 }
示例#39
0
		public virtual void Init(IMyCharacter character, Dictionary<MyStringHash, MyEntityStat> stats)
		{
			m_character = character;
			m_stats = stats;
		}
		public override void Init(IMyCharacter character, Dictionary<MyStringHash, MyEntityStat> stats)
		{
			base.Init(character, stats);

			InitPermanentEffects();
		}
示例#41
0
 public CR_Character(IMyCharacter character)
 {
     this.m_character = character;
     this.m_identity = character.GetIdentity_Safe();
 }
示例#42
0
		protected virtual void OnCharacterChanged(IMyCharacter oldCharacter) {}
示例#43
0
 /// <summary>
 /// Creates a radio component for a character.
 /// </summary>
 public static ComponentRadio CreateRadio(IMyCharacter character)
 {
     return new CR_Character(character);
 }