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); }
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); } }
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>()); }
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); }
public void Do() { resourceContents = resourceLayer.GetResource(cell); resourceLayer.ClearResources(cell); }
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); } } }); } }