Beispiel #1
0
        public bool HandleMouseInput(MouseInput mi)
        {
            // Exclusively uses mouse wheel and both mouse buttons, but nothing else
            // Mouse move events are important for tooltips, so we always allow these through
            if ((mi.Button != MouseButton.Left && mi.Button != MouseButton.Right &&
                 mi.Event != MouseInputEvent.Move && mi.Event != MouseInputEvent.Scroll) ||
                mi.Event == MouseInputEvent.Down)
            {
                return(false);
            }

            worldPixel = worldRenderer.Viewport.ViewToWorldPx(mi.Location);
            var cell = worldRenderer.Viewport.ViewToWorld(mi.Location);

            var underCursor         = editorLayer.PreviewsAt(worldPixel).MinByOrDefault(CalculateActorSelectionPriority);
            var resourceUnderCursor = resourceLayer?.GetResource(cell).Type;

            if (underCursor != null)
            {
                editorWidget.SetTooltip(underCursor.Tooltip);
            }
            else if (resourceUnderCursor != null)
            {
                editorWidget.SetTooltip(resourceUnderCursor);
            }
            else
            {
                editorWidget.SetTooltip(null);
            }

            // Finished with mouse move events, so let them bubble up the widget tree
            if (mi.Event == MouseInputEvent.Move)
            {
                return(false);
            }

            if (mi.Button == MouseButton.Left)
            {
                editorWidget.SetTooltip(null);
                SelectedActor = underCursor;
            }

            if (mi.Button == MouseButton.Right)
            {
                editorWidget.SetTooltip(null);

                if (underCursor != null && underCursor != SelectedActor)
                {
                    editorActionManager.Add(new RemoveActorAction(editorLayer, underCursor));
                }

                if (resourceUnderCursor != null)
                {
                    editorActionManager.Add(new RemoveResourceAction(resourceLayer, cell, resourceUnderCursor));
                }
            }

            return(true);
        }
Beispiel #2
0
        public bool HandleMouseInput(MouseInput mi)
        {
            // Exclusively uses left and right mouse buttons, but nothing else
            if (mi.Button != MouseButton.Left && mi.Button != MouseButton.Right)
            {
                return(false);
            }

            if (mi.Button == MouseButton.Right)
            {
                if (mi.Event == MouseInputEvent.Up)
                {
                    editorWidget.ClearBrush();
                    return(true);
                }

                return(false);
            }

            if (editorCursor.CurrentToken != cursorToken)
            {
                return(false);
            }

            var cell = worldRenderer.Viewport.ViewToWorld(mi.Location);

            if (mi.Button == MouseButton.Left && mi.Event != MouseInputEvent.Up && resourceLayer.CanAddResource(ResourceType, cell))
            {
                action.Add(new CellResource(cell, resourceLayer.GetResource(cell), ResourceType));
                resourceAdded = true;
            }
            else if (resourceAdded && mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Up)
            {
                editorActionManager.Add(action);
                action        = new AddResourcesEditorAction(world.Map, ResourceType, resourceLayer);
                resourceAdded = false;
            }

            return(true);
        }
        void ITick.Tick(Actor self)
        {
            if (delay < 0)
            {
                return;
            }

            var adjacent = 0;

            foreach (var direction in CVec.Directions)
            {
                var location = self.Location + direction;

                var resource = resourceLayer.GetResource(location);
                if (resource.Type == null || resource.Type != info.Type)
                {
                    continue;
                }

                if (resource.Density < info.Density)
                {
                    continue;
                }

                if (++adjacent < info.Adjacency)
                {
                    continue;
                }

                delay--;
                break;
            }

            if (delay < 0)
            {
                Transform(self);
            }
        }
Beispiel #4
0
        IEnumerable <IRenderable> IOrderGenerator.RenderAboveShroud(WorldRenderer wr, World world)
        {
            var topLeft       = TopLeft;
            var footprint     = new Dictionary <CPos, PlaceBuildingCellType>();
            var activeVariant = variants[variant];
            var actorInfo     = activeVariant.ActorInfo;
            var buildingInfo  = activeVariant.BuildingInfo;
            var plugInfo      = activeVariant.PlugInfo;
            var lineBuildInfo = activeVariant.LineBuildInfo;
            var preview       = activeVariant.Preview;
            var owner         = Queue.Actor.Owner;

            if (plugInfo != null)
            {
                if (buildingInfo.Dimensions.X != 1 || buildingInfo.Dimensions.Y != 1)
                {
                    throw new InvalidOperationException("Plug requires a 1x1 sized Building");
                }

                footprint.Add(topLeft, MakeCellType(AcceptsPlug(topLeft, plugInfo)));
            }
            else if (lineBuildInfo != null && owner.Shroud.IsExplored(topLeft))
            {
                // Linebuild for walls.
                if (buildingInfo.Dimensions.X != 1 || buildingInfo.Dimensions.Y != 1)
                {
                    throw new InvalidOperationException("LineBuild requires a 1x1 sized Building");
                }

                if (!Game.GetModifierKeys().HasModifier(Modifiers.Shift))
                {
                    var segmentInfo         = actorInfo;
                    var segmentBuildingInfo = buildingInfo;
                    if (!string.IsNullOrEmpty(lineBuildInfo.SegmentType))
                    {
                        segmentInfo         = world.Map.Rules.Actors[lineBuildInfo.SegmentType];
                        segmentBuildingInfo = segmentInfo.TraitInfo <BuildingInfo>();
                    }

                    foreach (var t in BuildingUtils.GetLineBuildCells(world, topLeft, actorInfo, buildingInfo, owner))
                    {
                        var lineBuildable   = world.IsCellBuildable(t.Cell, segmentInfo, segmentBuildingInfo);
                        var lineCloseEnough = segmentBuildingInfo.IsCloseEnoughToBase(world, world.LocalPlayer, segmentInfo, t.Cell);
                        footprint.Add(t.Cell, MakeCellType(lineBuildable && lineCloseEnough, true));
                    }
                }

                var buildable   = world.IsCellBuildable(topLeft, actorInfo, buildingInfo);
                var closeEnough = buildingInfo.IsCloseEnoughToBase(world, world.LocalPlayer, actorInfo, topLeft);
                footprint[topLeft] = MakeCellType(buildable && closeEnough);
            }
            else
            {
                var isCloseEnough = buildingInfo.IsCloseEnoughToBase(world, world.LocalPlayer, actorInfo, topLeft);
                foreach (var t in buildingInfo.Tiles(topLeft))
                {
                    footprint.Add(t, MakeCellType(isCloseEnough && world.IsCellBuildable(t, actorInfo, buildingInfo) && (resourceLayer == null || resourceLayer.GetResource(t).Type == null)));
                }
            }

            return(preview?.Render(wr, topLeft, footprint) ?? Enumerable.Empty <IRenderable>());
        }
Beispiel #5
0
        CPos?ChooseBuildLocation(string actorType, bool distanceToBaseIsImportant, BuildingType type)
        {
            var actorInfo    = world.Map.Rules.Actors[actorType];
            var buildingInfo = actorInfo.TraitInfoOrDefault <BuildingInfo>();

            if (buildingInfo == null)
            {
                return(null);
            }

            // Find the buildable cell that is closest to pos and centered around center
            Func <CPos, CPos, int, int, CPos?> findPos = (center, target, minRange, maxRange) =>
            {
                var cells = world.Map.FindTilesInAnnulus(center, minRange, maxRange);

                // Sort by distance to target if we have one
                if (center != target)
                {
                    cells = cells.OrderBy(c => (c - target).LengthSquared);
                }
                else
                {
                    cells = cells.Shuffle(world.LocalRandom);
                }

                foreach (var cell in cells)
                {
                    if (!world.CanPlaceBuilding(cell, actorInfo, buildingInfo, null))
                    {
                        continue;
                    }

                    foreach (var adjacent in CVec.Directions)
                    {
                        var adjacentCell = cell + adjacent;

                        // Don't clutter the base
                        if (buildingInfluence.AnyBuildingAt(adjacentCell))
                        {
                            continue;
                        }

                        // Don't block of resources
                        if (resourceLayer.GetResource(adjacentCell).Density > 0)
                        {
                            continue;
                        }
                    }

                    if (distanceToBaseIsImportant && !buildingInfo.IsCloseEnoughToBase(world, player, actorInfo, cell))
                    {
                        continue;
                    }

                    return(cell);
                }

                return(null);
            };

            var baseCenter = baseBuilder.GetRandomBaseCenter();

            switch (type)
            {
            case BuildingType.Defense:

                // Build near the closest enemy structure
                var closestEnemy = world.ActorsHavingTrait <Building>().Where(a => !a.Disposed && player.RelationshipWith(a.Owner) == PlayerRelationship.Enemy)
                                   .ClosestTo(world.Map.CenterOfCell(baseBuilder.DefenseCenter));

                var targetCell = closestEnemy != null ? closestEnemy.Location : baseCenter;
                return(findPos(baseBuilder.DefenseCenter, targetCell, baseBuilder.Info.MinimumDefenseRadius, baseBuilder.Info.MaximumDefenseRadius));

            case BuildingType.Refinery:
            case BuildingType.Building:
                return(findPos(baseCenter, baseCenter, baseBuilder.Info.MinBaseRadius,
                               distanceToBaseIsImportant ? baseBuilder.Info.MaxBaseRadius : world.Map.Grid.MaximumTileSearchRange));
            }

            // Can't find a build location
            return(null);
        }
Beispiel #6
0
 public void Do()
 {
     resourceContents = resourceLayer.GetResource(cell);
     resourceLayer.ClearResources(cell);
 }
Beispiel #7
0
        void SeedResources(Actor self)
        {
            var pieces = self.World.SharedRandom.Next(info.Pieces[0], info.Pieces[1]) * ticks / growTicks;

            if (pieces < info.Pieces[0])
            {
                pieces = info.Pieces[0];
            }

            var cells = self.World.Map.FindTilesInAnnulus(self.Location, 1, info.Range);

            for (var i = 0; i < pieces; i++)
            {
                var cell = cells
                           .SkipWhile(p => resourceLayer.GetResource(p).Type == info.ResourceType && !resourceLayer.CanAddResource(info.ResourceType, p))
                           .Cast <CPos?>()
                           .RandomOrDefault(self.World.SharedRandom);

                if (cell == null)
                {
                    cell = cells.Random(self.World.SharedRandom);
                }

                var args = new ProjectileArgs
                {
                    Weapon = self.World.Map.Rules.Weapons[info.Weapon.ToLowerInvariant()],
                    Facing = WAngle.Zero,
                    CurrentMuzzleFacing = () => WAngle.Zero,

                    DamageModifiers = self.TraitsImplementing <IFirepowerModifier>()
                                      .Select(a => a.GetFirepowerModifier()).ToArray(),

                    InaccuracyModifiers = self.TraitsImplementing <IInaccuracyModifier>()
                                          .Select(a => a.GetInaccuracyModifier()).ToArray(),

                    RangeModifiers = self.TraitsImplementing <IRangeModifier>()
                                     .Select(a => a.GetRangeModifier()).ToArray(),

                    Source        = self.CenterPosition,
                    CurrentSource = () => self.CenterPosition,
                    SourceActor   = self,
                    PassiveTarget = self.World.Map.CenterOfCell(cell.Value)
                };

                self.World.AddFrameEndTask(_ =>
                {
                    if (args.Weapon.Projectile != null)
                    {
                        var projectile = args.Weapon.Projectile.Create(args);
                        if (projectile != null)
                        {
                            self.World.Add(projectile);
                        }

                        if (args.Weapon.Report != null && args.Weapon.Report.Any())
                        {
                            Game.Sound.Play(SoundType.World, args.Weapon.Report, self.World, self.CenterPosition);
                        }
                    }
                });
            }
        }