Ejemplo n.º 1
0
        public override void Register()
        {
            ModePacket     = new DetachModePacket();
            ProgressPacket = new DetachProgressPacket();

            if (Networking.IsPlayer)
            {
                Local_DetachData = new DetachData();
                Main.GrinderHandler.GrinderChanged += Local_EquippedGrinderChanged;
                DetachProgressPacket.OnReceive     += Player_DetachProgressPacketReceived;
            }

            if (MyAPIGateway.Session.IsServer)
            {
                Server_DetachData = new Dictionary <ulong, DetachData>();
                Main.GrindDamageHandler.GrindingBlock          += Server_GrindingBlock;
                DetachModePacket.OnReceive                     += Server_DetachModePacketReceived;
                MyVisualScriptLogicProvider.PlayerDisconnected += Server_PlayerDisconnected;
            }
        }
Ejemplo n.º 2
0
        void Server_DetachModePacketReceived(DetachModePacket packet)
        {
            if (packet.Mode)
            {
                DetachData data;
                if (!Server_DetachData.TryGetValue(packet.OriginalSenderSteamId, out data))
                {
                    data = new DetachData();
                    Server_DetachData[packet.OriginalSenderSteamId] = data;
                }

                data.DetachMode         = packet.Mode;
                data.GrindedBlock       = null;
                data.GrindedTimes       = 0;
                data.GrindExpiresAtTick = 0;
            }
            else
            {
                Server_DetachData.Remove(packet.OriginalSenderSteamId);
            }
        }
Ejemplo n.º 3
0
        void Server_GrindingBlock(IMySlimBlock block, ref MyDamageInformation info, IMyAngleGrinder grinder, ulong attackerSteamId)
        {
            DetachData data = Server_DetachData.GetValueOrDefault(attackerSteamId);

            if (data == null || !data.DetachMode)
            {
                return;
            }

            float grindAmount = info.Amount; // store grinder speed for later use

            info.Amount = 0;                 // prevent grinding while detach mode is enabled

            MyCubeBlockDefinition blockDef = (MyCubeBlockDefinition)block.BlockDefinition;

            if (!blockDef.IsStandAlone || !blockDef.HasPhysics)
            {
                ProgressPacket.Send(attackerSteamId, DetachState.NoStandalone);
                return;
            }

            if (grindAmount == 0)
            {
                ProgressPacket.Send(attackerSteamId, DetachState.ZeroGrindAmount);
                return;
            }

            long owner = block.OwnerId;

            if (owner == 0 && block.CubeGrid.BigOwners != null && block.CubeGrid.BigOwners.Count > 0)
            {
                owner = block.CubeGrid.BigOwners[0];
            }

            if (owner == 0)
            {
                owner = block.BuiltBy;
            }

            if (owner != 0)
            {
                MyRelationsBetweenPlayerAndBlock relation = MyIDModule.GetRelationPlayerBlock(owner, grinder.OwnerIdentityId, MyOwnershipShareModeEnum.Faction);
                if (relation == MyRelationsBetweenPlayerAndBlock.Enemies)
                {
                    ProgressPacket.Send(attackerSteamId, DetachState.EnemyBlock);
                    return;
                }
            }

            MyCubeGrid grid = (MyCubeGrid)block.CubeGrid;

            if (grid.BlocksCount <= 1)
            {
                if (grid.DisplayName.StartsWith("(Detached"))
                {
                    ProgressPacket.Send(attackerSteamId, DetachState.DetachComplete);
                }
                else
                {
                    ProgressPacket.Send(attackerSteamId, DetachState.SingleBlock);
                }
                return;
            }

            // checking safezones doesn't seem necessary, as you cannot grind to begin with...

            if (data.GrindedBlock != block)
            {
                data.GrindedBlock       = block;
                data.GrindedTimes       = 0;
                data.GrindExpiresAtTick = 0;
            }

            int tick = MyAPIGateway.Session.GameplayFrameCounter;

            if (data.GrindExpiresAtTick == 0 || data.GrindExpiresAtTick > tick)
            {
                data.GrindedTimes++;
            }
            else
            {
                data.GrindedTimes = 0;
            }

            data.GrindExpiresAtTick = tick + 30;

            // make it require as much time as it normally would to grind to critical line
            float divideBy           = (block.FatBlock != null ? block.FatBlock.DisassembleRatio : blockDef.DisassembleRatio);
            float finalDamage        = (grindAmount / divideBy) * blockDef.IntegrityPointsPerSec;
            int   grindTimesToDetach = (int)((block.MaxIntegrity * blockDef.CriticalIntegrityRatio) / finalDamage);

            grindTimesToDetach = Math.Max(grindTimesToDetach, (int)(1000 / GrinderCooldownMs)); // at least one second

            if (data.GrindedTimes >= grindTimesToDetach)
            {
                data.GrindedTimes = 0;
                ProgressPacket.Send(attackerSteamId, DetachState.DetachComplete);
                DetachBlock(block, grinder);
            }
            else
            {
                int progress = (data.GrindedTimes * 100) / grindTimesToDetach;
                ProgressPacket.Send(attackerSteamId, DetachState.Detaching, progress);
            }
        }