Пример #1
0
        public override void UpdateAfterSimulation()
        {
            base.UpdateAfterSimulation();
            if (!(Entity as IMyCubeBlock).IsFunctional)
            {
                return;
            }

            var angle = ((bool)SettingsStore.Get(Entity, "junction_turn", false))?-8:0;

            var sw_short = Entity.GetSubpart(swivel_short);

            sw_short.PositionComp.LocalMatrix = Matrix.CreateRotationY((float)(angle * Math.PI / 180.0)) * short_initial;
            var sw_long = Entity.GetSubpart(swivel_long);

            sw_long.PositionComp.LocalMatrix = Matrix.CreateRotationY((float)(angle * Math.PI / 180.0)) * long_initial;
        }
Пример #2
0
 public void Init()
 {
     SettingsStore.SetupNetworkHandlers();
     inited = true;
 }
Пример #3
0
        public static void InitLate()
        {
            initialized = true;

            powerSwitch         = MyAPIGateway.TerminalControls.CreateControl <IMyTerminalControlOnOffSwitch, IMyTerminalBlock>("HoverRail_OnOff");
            powerSwitch.Title   = MyStringId.GetOrCompute("Maglev Engine");
            powerSwitch.Tooltip = MyStringId.GetOrCompute("Enable to apply force to stick to the track.");
            powerSwitch.Getter  = b => (bool)SettingsStore.Get(b, "power_on", true);
            powerSwitch.Setter  = (b, v) => SettingsStore.Set(b, "power_on", v);
            powerSwitch.SupportsMultipleBlocks = true;
            powerSwitch.OnText  = MyStringId.GetOrCompute("On");
            powerSwitch.OffText = MyStringId.GetOrCompute("Off");
            powerSwitch.Visible = BlockIsEngine;
            MyAPIGateway.TerminalControls.AddControl <IMyTerminalBlock>(powerSwitch);

            forceSlider         = MyAPIGateway.TerminalControls.CreateControl <IMyTerminalControlSlider, IMyTerminalBlock>("HoverRail_ForceLimit");
            forceSlider.Title   = MyStringId.GetOrCompute("Force Limit");
            forceSlider.Tooltip = MyStringId.GetOrCompute("The amount of force applied to align this motor with the track.");
            forceSlider.SetLogLimits(10000.0f, 50000000.0f);
            forceSlider.SupportsMultipleBlocks = true;
            forceSlider.Getter  = b => (float)SettingsStore.Get(b, "force_slider", 100000.0f);
            forceSlider.Setter  = (b, v) => SettingsStore.Set(b, "force_slider", (float)LogRound(v));
            forceSlider.Writer  = (b, result) => result.Append(String.Format("{0}N", SIFormat((float)SettingsStore.Get(b, "force_slider", 100000.0f))));
            forceSlider.Visible = BlockIsEngine;
            MyAPIGateway.TerminalControls.AddControl <IMyTerminalBlock>(forceSlider);

            heightSlider         = MyAPIGateway.TerminalControls.CreateControl <IMyTerminalControlSlider, IMyTerminalBlock>("HoverRail_HeightOffset");
            heightSlider.Title   = MyStringId.GetOrCompute("Height Offset");
            heightSlider.Tooltip = MyStringId.GetOrCompute("The height we float above the track.");
            heightSlider.SetLimits(0.1f, 2.5f);
            heightSlider.SupportsMultipleBlocks = true;
            heightSlider.Getter  = b => (float)SettingsStore.Get(b, "height_offset", 1.25f);
            heightSlider.Setter  = (b, v) => SettingsStore.Set(b, "height_offset", (float)Math.Round(v, 1));
            heightSlider.Writer  = (b, result) => result.Append(String.Format("{0}m", (float)SettingsStore.Get(b, "height_offset", 1.25f)));
            heightSlider.Visible = BlockIsEngine;
            MyAPIGateway.TerminalControls.AddControl <IMyTerminalBlock>(heightSlider);

            lowerHeightAction        = MyAPIGateway.TerminalControls.CreateAction <IMyTerminalBlock>("HoverRailEngine_LowerHeight0.1");
            lowerHeightAction.Name   = new StringBuilder("Lower Height");
            lowerHeightAction.Action = LowerHeightAction;
            lowerHeightAction.Writer = (block, builder) => {
                builder.Clear();
                builder.Append(String.Format("{0} -", (float)SettingsStore.Get(block, "height_offset", 1.25f)));
            };
            MyAPIGateway.TerminalControls.AddAction <IMyTerminalBlock>(lowerHeightAction);

            raiseHeightAction        = MyAPIGateway.TerminalControls.CreateAction <IMyTerminalBlock>("HoverRailEngine_RaiseHeight0.1");
            raiseHeightAction.Name   = new StringBuilder("Raise Height");
            raiseHeightAction.Action = RaiseHeightAction;
            raiseHeightAction.Writer = (block, builder) => {
                builder.Clear();
                builder.Append(String.Format("{0} +", (float)SettingsStore.Get(block, "height_offset", 1.25f)));
            };
            MyAPIGateway.TerminalControls.AddAction <IMyTerminalBlock>(raiseHeightAction);

            turnOnAction        = MyAPIGateway.TerminalControls.CreateAction <IMyTerminalBlock>("HoverRailEngine_On");
            turnOnAction.Name   = new StringBuilder("Power On");
            turnOnAction.Action = TurnOnAction;
            turnOnAction.Writer = OnOffWriter;
            MyAPIGateway.TerminalControls.AddAction <IMyTerminalBlock>(turnOnAction);

            turnOffAction        = MyAPIGateway.TerminalControls.CreateAction <IMyTerminalBlock>("HoverRailEngine_Off");
            turnOffAction.Name   = new StringBuilder("Power Off");
            turnOffAction.Action = TurnOffAction;
            turnOffAction.Writer = OnOffWriter;
            MyAPIGateway.TerminalControls.AddAction <IMyTerminalBlock>(turnOffAction);

            turnOnOffAction        = MyAPIGateway.TerminalControls.CreateAction <IMyTerminalBlock>("HoverRailEngine_OnOff");
            turnOnOffAction.Name   = new StringBuilder("Power On/Off");
            turnOnOffAction.Action = TurnOnOffAction;
            turnOnOffAction.Writer = OnOffWriter;
            MyAPIGateway.TerminalControls.AddAction <IMyTerminalBlock>(turnOnOffAction);

            MyAPIGateway.TerminalControls.CustomActionGetter += GetEngineActions;
        }
Пример #4
0
 public static void OnOffWriter(IMyTerminalBlock block, StringBuilder builder)
 {
     builder.Clear();
     builder.Append(((bool)SettingsStore.Get(block, "power_on", true))?"On":"Off");
 }
Пример #5
0
 public static void TurnOnOffAction(IMyTerminalBlock block)
 {
     SettingsStore.Set(block, "power_on", !SettingsStore.Get(block, "power_on", true));
 }
Пример #6
0
 public static void TurnOffAction(IMyTerminalBlock block)
 {
     SettingsStore.Set(block, "power_on", false);
 }
Пример #7
0
        public override void UpdateBeforeSimulation()
        {
            if (!block_initialized)
            {
                InitLate();
            }

            frame++;

            if (frame % 10 == 0)
            {
                (Entity as IMyTerminalBlock).RefreshCustomInfo();
            }

            if (!(bool)SettingsStore.Get(Entity, "power_on", true))
            {
                UpdatePowerUsage(0);
                UpdatePowerState(false);
                return;
            }

            // this will be one frame late ... but close enough??
            // power requested that can be satisfied by the network * power required that can be requested given our max
            float power_ratio = sinkComp.SuppliedRatioByType(MyResourceDistributorComponent.ElectricityId) * power_ratio_available;

            if (!sinkComp.IsPoweredByType(MyResourceDistributorComponent.ElectricityId))
            {
                power_ratio = 0;
            }
            // MyLog.Default.WriteLine(String.Format("power ratio is {0}", power_ratio));

            float height = (float)SettingsStore.Get(Entity, "height_offset", 1.25f);

            double forceLimit = (double)(float)SettingsStore.Get(Entity, "force_slider", 100000.0f);

            var hoverCenter  = Entity.WorldMatrix.Translation;
            var searchCenter = Entity.WorldMatrix.Translation + Entity.WorldMatrix.Down * 2.499;
            // DebugDraw.Sphere(searchCenter, 2.5f, Color.Green);

            var rail_pos   = new Vector3D(0, 0, 0);
            var weight_sum = 0.0f;
            HashSet <RailGuide> lostGuides   = new HashSet <RailGuide>();
            RailGuide           anyRailGuide = null;

            foreach (var guide in activeRailGuides)
            {
                if (!guide.getGuidance(hoverCenter, ref rail_pos, ref weight_sum, height))
                {
                    // lost rail lock
                    lostGuides.Add(guide);
                    continue;
                }
                anyRailGuide = guide;
            }

            foreach (var guide in lostGuides)
            {
                activeRailGuides.Remove(guide);
            }
            lostGuides.Clear();

            if (weight_sum < 0.9f)
            {
                // not confident in our rail lock, look for possible new rails
                var area  = new BoundingSphereD(searchCenter, 2.5);
                var items = MyAPIGateway.Entities.GetEntitiesInSphere(ref area);
                rail_pos   = Vector3D.Zero;
                weight_sum = 0.0f;
                foreach (var ent in items)
                {
                    var guide = RailGuide.fromEntity(ent);
                    if (guide != null)
                    {
                        var test = guide.getGuidance(hoverCenter, ref rail_pos, ref weight_sum, height);
                        if (test)
                        {
                            activeRailGuides.Add(guide);
                            anyRailGuide = guide;
                        }
                    }
                }
            }

            // MyLog.Default.WriteLine(String.Format("{0}:- hovering at {1}", Entity.EntityId, hoverCenter));
            if (activeRailGuides.Count == 0)
            {
                UpdatePowerUsage(0);
                UpdatePowerState(true);                 // powered but idle
                return;
            }

            // average by weight
            rail_pos /= weight_sum;

            var guidance = rail_pos - hoverCenter;

            // MyLog.Default.WriteLine(String.Format("{0}: rail pos is {1}, due to weight correction by {2}; guidance {3}", Entity.EntityId, rail_pos, weight_sum, guidance));
            DebugDraw.Sphere(rail_pos, 0.15f, Color.Blue);
            DebugDraw.Sphere(rail_pos * 0.5 + hoverCenter * 0.5, 0.1f, Color.Blue);
            DebugDraw.Sphere(hoverCenter, 0.1f, Color.Blue);

            // DebugDraw.Sphere(searchCenter, 0.1f, Color.Green);

            float force_magnitude = 0;
            // correction force, pushes engine towards rail guide
            {
                var len = guidance.Length() / 2.5;                 // 0 .. 1
                if (len > 0.001)
                {
                    var weight = len;
                    if (weight > 0.99)
                    {
                        weight = 0.99;                                    // always some force
                    }
                    const double splitPoint = 0.5;
                    if (weight > splitPoint)
                    {
                        weight = 1.0 - (weight - splitPoint) / (1.0 - splitPoint);
                    }
                    else
                    {
                        weight = weight / splitPoint;
                    }
                    var factor        = Math.Pow(weight, 2.0);              // spiken
                    var guidanceForce = forceLimit * Vector3D.Normalize(guidance) * factor;
                    this.avgCorrectF.update(guidanceForce);
                    DebugDraw.Sphere(searchCenter, 0.1f, Color.Yellow);
                    anyRailGuide.applyForces(Entity, this.avgCorrectF.value * power_ratio);
                    force_magnitude += (float)this.avgCorrectF.value.Length();
                }
            }
            // dampening force, reduces oscillation over time
            var dF = guidance - this.avgGuidance.value;

            {
                // var len = guidance.Length() / 2.5;
                // if (len > 0.99) len = 0.99;
                // var factor = Math.Pow(len, 0.3);
                var factor      = 1.0;
                var dampenForce = forceLimit * 0.5 * dF * factor;                 // separate slider?
                this.avgDampenF.update(dampenForce);
                DebugDraw.Sphere(searchCenter + this.avgDampenF.value * 0.000001f, 0.1f, Color.Red);
                anyRailGuide.applyForces(Entity, this.avgDampenF.value * power_ratio);
                force_magnitude += (float)this.avgDampenF.value.Length();
            }
            this.avgGuidance.update(guidance);
            UpdatePowerUsage(force_magnitude * FORCE_POWER_COST_MW_N);
            UpdatePowerState(true);
        }
Пример #8
0
 public static void JunctionSwitchSideAction(IMyTerminalBlock block)
 {
     SettingsStore.Set(block, "junction_turn", true);
 }
Пример #9
0
 public static void JunctionSwitchStraightAction(IMyTerminalBlock block)
 {
     SettingsStore.Set(block, "junction_turn", false);
 }
Пример #10
0
        public static void InitLate()
        {
            initialized = true;

            turnLeftSwitch         = MyAPIGateway.TerminalControls.CreateControl <IMyTerminalControlOnOffSwitch, IMyTerminalBlock>("LeftJunction_TurnOnOff");
            turnLeftSwitch.Title   = MyStringId.GetOrCompute("Junction Direction");
            turnLeftSwitch.Tooltip = MyStringId.GetOrCompute("Which way should a train go?");
            turnLeftSwitch.Getter  = b => (bool)SettingsStore.Get(b, "junction_turn", false);
            turnLeftSwitch.Setter  = (b, v) => SettingsStore.Set(b, "junction_turn", v);
            turnLeftSwitch.OnText  = MyStringId.GetOrCompute("Left");
            turnLeftSwitch.OffText = MyStringId.GetOrCompute("Fwd");
            turnLeftSwitch.Visible = BlockIsLeftJunction;
            MyAPIGateway.TerminalControls.AddControl <IMyTerminalBlock>(turnLeftSwitch);

            turnRightSwitch         = MyAPIGateway.TerminalControls.CreateControl <IMyTerminalControlOnOffSwitch, IMyTerminalBlock>("RightJunction_TurnOnOff");
            turnRightSwitch.Title   = MyStringId.GetOrCompute("Junction Direction");
            turnRightSwitch.Tooltip = MyStringId.GetOrCompute("Which way should a train go?");
            // meaning flipped relative to switch, so that we can
            // swap the labels and have [Fwd] [Right], which is more pleasing
            turnRightSwitch.Getter  = b => !(bool)SettingsStore.Get(b, "junction_turn", false);
            turnRightSwitch.Setter  = (b, v) => SettingsStore.Set(b, "junction_turn", !v);
            turnRightSwitch.OnText  = MyStringId.GetOrCompute("Fwd");
            turnRightSwitch.OffText = MyStringId.GetOrCompute("Right");
            turnRightSwitch.Visible = BlockIsRightJunction;
            MyAPIGateway.TerminalControls.AddControl <IMyTerminalBlock>(turnRightSwitch);

            leftSwitchAction        = MyAPIGateway.TerminalControls.CreateAction <IMyTerminalBlock>("HoverRailLeftJunction_Switch");
            leftSwitchAction.Name   = new StringBuilder("Switch Direction");
            leftSwitchAction.Writer = LeftJunctionText;
            leftSwitchAction.Action = JunctionSwitchAction;
            // TODO figure out why doesn't work
            leftSwitchAction.Icon = @"Textures\Icons\HoverRail\HoverRail_Junction_Left_10x-12x_OnOff.dds";
            MyAPIGateway.TerminalControls.AddAction <IMyTerminalBlock>(leftSwitchAction);

            leftSwitchLeftAction        = MyAPIGateway.TerminalControls.CreateAction <IMyTerminalBlock>("HoverRailLeftJunction_Left");
            leftSwitchLeftAction.Name   = new StringBuilder("Go Left");
            leftSwitchLeftAction.Writer = LeftJunctionText;
            leftSwitchLeftAction.Action = JunctionSwitchSideAction;
            leftSwitchLeftAction.Icon   = @"Textures\Icons\HoverRail\HoverRail_Junction_Left_10x-12x_On.dds";
            MyAPIGateway.TerminalControls.AddAction <IMyTerminalBlock>(leftSwitchLeftAction);

            leftSwitchStraightAction        = MyAPIGateway.TerminalControls.CreateAction <IMyTerminalBlock>("HoverRailLeftJunction_Straight");
            leftSwitchStraightAction.Name   = new StringBuilder("Go Fwd");
            leftSwitchStraightAction.Writer = LeftJunctionText;
            leftSwitchStraightAction.Action = JunctionSwitchStraightAction;
            leftSwitchStraightAction.Icon   = @"Textures\Icons\HoverRail\HoverRail_Junction_Left_10x-12x_Off.dds";
            MyAPIGateway.TerminalControls.AddAction <IMyTerminalBlock>(leftSwitchStraightAction);

            rightSwitchAction        = MyAPIGateway.TerminalControls.CreateAction <IMyTerminalBlock>("HoverRailRightJunction_Switch");
            rightSwitchAction.Name   = new StringBuilder("Switch Direction");
            rightSwitchAction.Writer = RightJunctionText;
            rightSwitchAction.Action = JunctionSwitchAction;
            // rightSwitchAction.Icon = @"Textures\Icons\HoverRail\HoverRail_Junction_Right_10x-12x_OnOff.dds";
            MyAPIGateway.TerminalControls.AddAction <IMyTerminalBlock>(rightSwitchAction);

            rightSwitchStraightAction        = MyAPIGateway.TerminalControls.CreateAction <IMyTerminalBlock>("HoverRailRightJunction_Straight");
            rightSwitchStraightAction.Name   = new StringBuilder("Go Fwd");
            rightSwitchStraightAction.Writer = RightJunctionText;
            rightSwitchStraightAction.Action = JunctionSwitchStraightAction;
            // rightSwitchStraightAction.Icon = @"Textures\Icons\HoverRail\HoverRail_Junction_Right_10x-12x_Off.dds";
            MyAPIGateway.TerminalControls.AddAction <IMyTerminalBlock>(rightSwitchStraightAction);

            rightSwitchRightAction        = MyAPIGateway.TerminalControls.CreateAction <IMyTerminalBlock>("HoverRailRightJunction_Right");
            rightSwitchRightAction.Name   = new StringBuilder("Go Right");
            rightSwitchRightAction.Writer = RightJunctionText;
            rightSwitchRightAction.Action = JunctionSwitchSideAction;
            // rightSwitchRightAction.Icon = @"Textures\Icons\HoverRail\HoverRail_Junction_Right_10x-12x_On.dds";
            MyAPIGateway.TerminalControls.AddAction <IMyTerminalBlock>(rightSwitchRightAction);

            MyAPIGateway.TerminalControls.CustomActionGetter += GetSwitchActions;
        }