/// <summary> /// Creates a new text area. /// </summary> /// <param name="capi">The client API</param> /// <param name="bounds">The bounds of the text area.</param> /// <param name="OnTextChanged">The event fired when the text is changed.</param> /// <param name="font">The font of the text.</param> public GuiElementTextArea(ICoreClientAPI capi, ElementBounds bounds, API.Common.Action <string> OnTextChanged, CairoFont font) : base(capi, font, bounds) { highlightTexture = new LoadedTexture(capi); multilineMode = true; minHeight = bounds.fixedHeight; this.OnTextChanged = OnTextChanged; }
/// <summary> /// Adds a chat input element to the UI. /// </summary> /// <param name="capi">The client API</param> /// <param name="bounds">The bounds of the chat input.</param> /// <param name="OnTextChanged">The event fired when the text is altered.</param> public GuiElementChatInput(ICoreClientAPI capi, ElementBounds bounds, API.Common.Action <string> OnTextChanged) : base(capi, null, bounds) { highlightTexture = new LoadedTexture(capi); this.OnTextChanged = OnTextChanged; this.caretColor = new float[] { 1, 1, 1, 1 }; this.Font = CairoFont.WhiteSmallText(); }
/// <summary> /// Adds a switch to the GUI. /// </summary> /// <param name="onToggle">The event that happens when the switch is toggled.</param> /// <param name="bounds">The bounds of the switch.</param> /// <param name="key">the name of the switch. (Default: null)</param> /// <param name="size">The size of the switch (Default: 30)</param> /// <param name="padding">The padding around the switch (Default: 5)</param> public static GuiComposer AddSwitch(this GuiComposer composer, API.Common.Action <bool> onToggle, ElementBounds bounds, string key = null, double size = 30, double padding = 4) { if (!composer.composed) { composer.AddInteractiveElement(new GuiElementSwitch(composer.Api, onToggle, bounds, size, padding), key); } return(composer); }
/// <summary> /// Adds a vertical scrollbar to the GUI. /// </summary> /// <param name="onNewScrollbarValue">The action when the scrollbar changes.</param> /// <param name="bounds">The bounds of the scrollbar.</param> /// <param name="key">The name of the scrollbar.</param> public static GuiComposer AddVerticalScrollbar(this GuiComposer composer, API.Common.Action <float> onNewScrollbarValue, ElementBounds bounds, string key = null) { if (!composer.composed) { composer.AddInteractiveElement(new GuiElementScrollbar(composer.Api, onNewScrollbarValue, bounds), key); } return(composer); }
public GuiElementSwitchOld(ICoreClientAPI capi, API.Common.Action <bool> OnToggled, ElementBounds bounds) : base(capi, "", null, bounds) { Font = CairoFont.WhiteSmallText().WithFontSize((float)GuiStyle.SubNormalFontSize); handler = OnToggled; bounds.fixedWidth = unscaledWidth; bounds.fixedHeight = unscaledHeight; }
/// <summary> /// Runs given method /// </summary> /// <param name="method"></param> /// <returns></returns> public GuiComposer Execute(API.Common.Action method) { if (conditionalAdds.Count > 0 && !conditionalAdds.Peek()) { return(this); } method.Invoke(); return(this); }
public void WalkRecursive(API.Common.Action <ShapeElement> onElem) { onElem(this); if (Children != null) { for (int i = 0; i < Children.Length; i++) { Children[i].WalkRecursive(onElem); } } }
/// <summary> /// Creates a switch which can be toggled. /// </summary> /// <param name="capi">The Client API</param> /// <param name="OnToggled">The event that happens when the switch is flipped.</param> /// <param name="bounds">The bounds of the element.</param> /// <param name="size">The size of the switch. (Default: 30)</param> /// <param name="padding">The padding on the outside of the switch (Default: 5)</param> public GuiElementSwitch(ICoreClientAPI capi, API.Common.Action <bool> OnToggled, ElementBounds bounds, double size = 30, double padding = 4) : base(capi, bounds) { onTexture = new LoadedTexture(capi); bounds.fixedWidth = size; bounds.fixedHeight = size; this.unscaledPadding = padding; this.unscaledSize = size; this.handler = OnToggled; }
/// <summary> /// Creates a collection of horizontal tabs. /// </summary> /// <param name="capi">The client API</param> /// <param name="tabs">A collection of GUI tabs.</param> /// <param name="font">The font for the name of each tab.</param> /// <param name="bounds">The bounds of each tab.</param> /// <param name="onTabClicked">The event fired whenever the tab is clicked.</param> public GuiElementHorizontalTabs(ICoreClientAPI capi, GuiTab[] tabs, CairoFont font, CairoFont selectedFont, ElementBounds bounds, API.Common.Action <int> onTabClicked) : base(capi, "", font, bounds) { this.selectedFont = selectedFont; this.tabs = tabs; handler = onTabClicked; hoverTextures = new LoadedTexture[tabs.Length]; for (int i = 0; i < tabs.Length; i++) { hoverTextures[i] = new LoadedTexture(capi); } tabWidths = new int[tabs.Length]; baseTexture = new LoadedTexture(capi); }
public override void TeleportToDouble(double x, double y, double z, API.Common.Action onTeleported = null) { Teleporting = true; ICoreServerAPI sapi = this.World.Api as ICoreServerAPI; if (sapi != null) { sapi.WorldManager.LoadChunkColumnPriority((int)ServerPos.X / World.BlockAccessor.ChunkSize, (int)ServerPos.Z / World.BlockAccessor.ChunkSize, new ChunkLoadOptions() { OnLoaded = () => { Pos.SetPos(x, y, z); ServerPos.SetPos(x, y, z); PreviousServerPos.SetPos(-99, -99, -99); PositionBeforeFalling.Set(x, y, z); Pos.Motion.Set(0, 0, 0); if (this is EntityPlayer) { sapi.Network.BroadcastEntityPacket(EntityId, 1, SerializerUtil.Serialize(ServerPos.XYZ)); IServerPlayer player = this.Player as IServerPlayer; int chunksize = World.BlockAccessor.ChunkSize; player.CurrentChunkSentRadius = 0; sapi.Event.RegisterCallback((bla) => { if (player.ConnectionState == EnumClientState.Offline) { return; } if (!sapi.WorldManager.HasChunk((int)x / chunksize, (int)y / chunksize, (int)z / chunksize, player)) { sapi.WorldManager.SendChunk((int)x / chunksize, (int)y / chunksize, (int)z / chunksize, player, false); } // Oherwise we get an endlessly looping exception spam and break the server player.CurrentChunkSentRadius = 0; }, 50); } WatchedAttributes.SetInt("positionVersionNumber", WatchedAttributes.GetInt("positionVersionNumber", 0) + 1); onTeleported?.Invoke(); Teleporting = false; }, }); } }
public GuiElementHandbookList(ICoreClientAPI capi, ElementBounds bounds, API.Common.Action <int> onLeftClick, List <GuiHandbookPage> elements = null) : base(capi, bounds) { hoverOverlayTexture = new LoadedTexture(capi); insideBounds = new ElementBounds().WithFixedPadding(unscaledCellSpacing).WithEmptyParent(); insideBounds.CalcWorldBounds(); this.onLeftClick = onLeftClick; if (elements != null) { Elements = elements; } CalcTotalHeight(); }
/// <summary> /// Creates a new instance of this class. /// </summary> /// <param name="capi">The client API</param> /// <param name="inventory">The attached inventory</param> /// <param name="SendPacket">A handler that should send supplied network packet to the server, if the inventory modifications should be synced</param> /// <param name="columns">The number of columns in the GUI.</param> /// <param name="bounds">The bounds of the slot grid.</param> public GuiElementItemSlotGridBase(ICoreClientAPI capi, IInventory inventory, API.Common.Action <object> SendPacket, int columns, ElementBounds bounds) : base(capi, bounds) { slotTexture = new LoadedTexture(capi); highlightSlotTexture = new LoadedTexture(capi); crossedOutTexture = new LoadedTexture(capi); prevSlotQuantity = inventory.Count; this.inventory = inventory; cols = columns; SendPacketHandler = SendPacket; inventory.SlotNotified += OnSlotNotified; DrawIconHandler = (cr, type, x, y, w, h, rgba) => api.Gui.Icons.DrawIconInt(cr, type, x, y, w, h, rgba); }
public GuiDialogBlockEntityRecipeSelector(string DialogTitle, ItemStack[] recipeOutputs, API.Common.Action <int> onSelectedRecipe, API.Common.Action onCancelSelect, BlockPos blockEntityPos, ICoreClientAPI capi) : base(DialogTitle, capi) { this.blockEntityPos = blockEntityPos; this.onSelectedRecipe = onSelectedRecipe; this.onCancelSelect = onCancelSelect; skillItems = new List <SkillItem>(); double size = GuiElementPassiveItemSlot.unscaledSlotSize + GuiElementItemSlotGrid.unscaledSlotPadding; for (int i = 0; i < recipeOutputs.Length; i++) { ItemStack stack = recipeOutputs[i]; ItemSlot dummySlot = new DummySlot(stack); string key = GetCraftDescKey(stack); string desc = Lang.GetMatching(key); if (desc == key) { desc = ""; } skillItems.Add(new SkillItem() { Code = stack.Collectible.Code.Clone(), Name = stack.GetName(), Description = desc, RenderHandler = (AssetLocation code, float dt, double posX, double posY) => { // No idea why the weird offset and size multiplier double scsize = GuiElement.scaled(size - 5); capi.Render.RenderItemstackToGui(dummySlot, posX + scsize / 2, posY + scsize / 2, 100, (float)GuiElement.scaled(GuiElementPassiveItemSlot.unscaledItemSize), ColorUtil.WhiteArgb); } }); } SetupDialog(); }
public void WalkMatchingBlocks(IWorldAccessor world, BlockPos centerPos, API.Common.Action <Block, BlockPos> onBlock) { if (TransformedOffsets == null) { throw new InvalidOperationException("call InitForUse() first"); } BlockPos pos = new BlockPos(); for (int i = 0; i < TransformedOffsets.Count; i++) { Vec4i offset = TransformedOffsets[i]; pos.Set(centerPos.X + offset.X, centerPos.Y + offset.Y, centerPos.Z + offset.Z); Block block = world.BlockAccessor.GetBlock(pos); if (WildcardUtil.Match(BlockCodes[offset.W], block.Code)) { onBlock?.Invoke(block, pos); } } }
/// <summary> /// Adds an ItemSlotGrid with Exclusions. /// </summary> /// <param name="inventory">The attached inventory.</param> /// <param name="SendPacket">A handler that should send supplied network packet to the server, if the inventory modifications should be synced</param> /// <param name="columns">The number of columns.</param> /// <param name="excludingSlots">The slots that have been excluded from the slot grid.</param> /// <param name="bounds">The bounds of the slot grid.</param> /// <param name="key">The name of the slot grid.</param> public static GuiComposer AddItemSlotGridExcl(this GuiComposer composer, IInventory inventory, API.Common.Action <object> SendPacket, int columns, int[] excludingSlots, ElementBounds bounds, string key = null) { if (!composer.composed) { composer.AddInteractiveElement(new GuiElementItemSlotGridExcl(composer.Api, inventory, SendPacket, columns, excludingSlots, bounds), key); GuiElementItemSlotGridBase.UpdateLastSlotGridFlag(composer); } return(composer); }
/// <summary> /// Creates a new slot grid with exclusions. /// </summary> /// <param name="capi">The Client API</param> /// <param name="inventory">The attached inventory.</param> /// <param name="SendPacketHandler">A handler that should send supplied network packet to the server, if the inventory modifications should be synced</param> /// <param name="columns">The number of columns in the slot grid.</param> /// <param name="excludingSlots">The slots that have been excluded.</param> /// <param name="bounds">The bounds of the slot grid.</param> public GuiElementItemSlotGridExcl(ICoreClientAPI capi, IInventory inventory, API.Common.Action <object> SendPacketHandler, int columns, int[] excludingSlots, ElementBounds bounds) : base(capi, inventory, SendPacketHandler, columns, bounds) { this.excludingSlots = excludingSlots; InitDicts(); this.SendPacketHandler = SendPacketHandler; }
/// <summary> /// Creates a numerical input field. /// </summary> /// <param name="capi">The Client API</param> /// <param name="bounds">The bounds of the GUI.</param> /// <param name="OnTextChanged">The event fired when the number is changed.</param> /// <param name="font">The font of the numbers.</param> public GuiElementNumberInput(ICoreClientAPI capi, ElementBounds bounds, API.Common.Action <string> OnTextChanged, CairoFont font) : base(capi, bounds, OnTextChanged, font) { buttonHighlightTexture = new LoadedTexture(capi); }
/// <summary> /// Adds a numeric input for the current GUI. /// </summary> /// <param name="bounds">The bounds of the number input.</param> /// <param name="OnTextChanged">The event fired when the number is changed.</param> /// <param name="font">The font for the numbers.</param> /// <param name="key">The name for this GuiElementNumberInput</param> public static GuiComposer AddNumberInput(this GuiComposer composer, ElementBounds bounds, API.Common.Action <string> OnTextChanged, CairoFont font = null, string key = null) { if (font == null) { font = CairoFont.TextInput(); } if (!composer.composed) { composer.AddInteractiveElement(new GuiElementNumberInput(composer.Api, bounds, OnTextChanged, font), key); } return(composer); }
public GuiElementItemSlotGrid(ICoreClientAPI capi, IInventory inventory, API.Common.Action <object> SendPacketHandler, int cols, int[] visibleSlots, ElementBounds bounds) : base(capi, inventory, SendPacketHandler, cols, bounds) { DetermineAvailableSlots(visibleSlots); this.SendPacketHandler = SendPacketHandler; }
/// <summary> /// Adds multiple buttons with Text. /// </summary> /// <param name="texts">The texts on all the buttons.</param> /// <param name="font">The font for the buttons</param> /// <param name="onToggle">The event fired when the button is pressed.</param> /// <param name="bounds">The bounds of the buttons.</param> /// <param name="key">The key given to the bundle of buttons.</param> public static GuiComposer AddTextToggleButtons(this GuiComposer composer, string[] texts, CairoFont font, API.Common.Action <int> onToggle, ElementBounds[] bounds, string key = null) { if (!composer.composed) { int quantityButtons = texts.Length; for (int i = 0; i < texts.Length; i++) { int index = i; composer.AddInteractiveElement( new GuiElementToggleButton(composer.Api, "", texts[i], font, (on) => { if (on) { onToggle(index); for (int j = 0; j < quantityButtons; j++) { if (j == index) { continue; } composer.GetToggleButton(key + "-" + j).SetValue(false); } } else { composer.GetToggleButton(key + "-" + index).SetValue(true); } }, bounds[i], true), key + "-" + i ); } } return(composer); }
/// <summary> /// Adds a set of horizontal tabs to the GUI. /// </summary> /// <param name="tabs">The collection of tabs.</param> /// <param name="bounds">The bounds of the horizontal tabs.</param> /// <param name="OnTabClicked">The event fired when the tab is clicked.</param> /// <param name="font">The font of the tabs.</param> /// <param name="key">The key for the added horizontal tabs.</param> public static GuiComposer AddHorizontalTabs(this GuiComposer composer, GuiTab[] tabs, ElementBounds bounds, API.Common.Action <int> OnTabClicked, CairoFont font, CairoFont selectedFont, string key = null) { if (!composer.composed) { composer.AddInteractiveElement(new GuiElementHorizontalTabs(composer.Api, tabs, font, selectedFont, bounds, OnTabClicked), key); } return(composer); }
/// <summary> /// Creates a toggle button with the given parameters. /// </summary> /// <param name="text">The text of the button.</param> /// <param name="font">The font of the text.</param> /// <param name="onToggle">The event that happens once the button is toggled.</param> /// <param name="bounds">The bounding box of the button.</param> /// <param name="key">The name of the button for easy access.</param> public static GuiComposer AddToggleButton(this GuiComposer composer, string text, CairoFont font, API.Common.Action <bool> onToggle, ElementBounds bounds, string key = null) { if (!composer.composed) { composer.AddInteractiveElement(new GuiElementToggleButton(composer.Api, "", text, font, onToggle, bounds, true), key); } return(composer); }
/// <summary> /// Adds a chat input to the GUI. /// </summary> /// <param name="bounds">The bounds of the text.</param> /// <param name="OnTextChanged">The event fired when the text is changed.</param> /// <param name="key">The name of this chat component.</param> public static GuiComposer AddChatInput(this GuiComposer composer, ElementBounds bounds, API.Common.Action <string> OnTextChanged, string key = null) { if (!composer.composed) { composer.AddInteractiveElement(new GuiElementChatInput(composer.Api, bounds, OnTextChanged), key); } return(composer); }
/// <summary> /// Scrollbar constructor. /// </summary> /// <param name="capi">Client API</param> /// <param name="onNewScrollbarValue">Event for the changing of the scrollbar or scrolling of the mousewheel.</param> /// <param name="bounds">the bounding box of the scrollbar.</param> public GuiElementCompactScrollbar(ICoreClientAPI capi, API.Common.Action <float> onNewScrollbarValue, ElementBounds bounds) : base(capi, onNewScrollbarValue, bounds) { }
/// <summary> /// Creates a new Scrollbar. /// </summary> /// <param name="capi">The client API.</param> /// <param name="onNewScrollbarValue">The event that fires when the scrollbar is changed.</param> /// <param name="bounds">The bounds of the scrollbar.</param> public GuiElementScrollbar(ICoreClientAPI capi, API.Common.Action <float> onNewScrollbarValue, ElementBounds bounds) : base(capi, bounds) { handleTexture = new LoadedTexture(capi); this.onNewScrollbarValue = onNewScrollbarValue; }
public override bool NavigateTo(Vec3d target, float movingSpeed, float targetDistance, API.Common.Action OnGoalReached, API.Common.Action OnStuck, bool giveUpWhenNoPath = false, int searchDepth = 999, bool allowReachAlmost = false) { waypointToReachIndex = 0; var bh = entity.GetBehavior <EntityBehaviorControlledPhysics>(); float stepHeight = bh == null ? 0.6f : bh.stepHeight; bool canFallDamage = entity.Properties.FallDamage; waypoints = entity.World.Api.ModLoader.GetModSystem <PathfindSystem>().FindPathAsWaypoints(entity.ServerPos.AsBlockPos, target.AsBlockPos, canFallDamage ? 8 : 4, stepHeight, entity.CollisionBox, searchDepth, allowReachAlmost); bool nopath = false; if (waypoints == null) { waypoints = new List <Vec3d>(); nopath = true; } else { // Debug visualization /*List<BlockPos> poses = new List<BlockPos>(); * List<int> colors = new List<int>(); * int i = 0; * foreach (var node in waypoints) * { * poses.Add(node.AsBlockPos); * colors.Add(ColorUtil.ColorFromRgba(128, 128, Math.Min(255, 128 + i*8), 150)); * i++; * } * * IPlayer player = entity.World.AllOnlinePlayers[0]; * entity.World.HighlightBlocks(player, 2, poses, * colors, * API.Client.EnumHighlightBlocksMode.Absolute, EnumHighlightShape.Arbitrary * );*/ } waypoints.Add(target); bool ok = base.WalkTowards(target, movingSpeed, targetDistance, OnGoalReached, OnStuck); if (nopath && giveUpWhenNoPath) { Active = false; return(false); } return(ok); }
public static GuiComposer AddHandbookStackList(this GuiComposer composer, ElementBounds bounds, API.Common.Action <int> onleftClick = null, List <GuiHandbookPage> stacks = null, string key = null) { if (!composer.composed) { composer.AddInteractiveElement(new GuiElementHandbookList(composer.Api, bounds, onleftClick, stacks), key); } return(composer); }
/// <summary> /// Adds an icon button. /// </summary> /// <param name="icon">The name of the icon.</param> /// <param name="onToggle">The event that happens once the button is toggled.</param> /// <param name="bounds">The bounding box of the button.</param> /// <param name="key">The name of the button for easy access.</param> public static GuiComposer AddIconButton(this GuiComposer composer, string icon, API.Common.Action <bool> onToggle, ElementBounds bounds, string key = null) { if (!composer.composed) { composer.AddInteractiveElement(new GuiElementToggleButton(composer.Api, icon, "", CairoFont.WhiteDetailText(), onToggle, bounds, false), key); } return(composer); }
/// <summary> /// Same as <see cref="WalkEntities(Vec3d, double, API.Common.Action{Entity})"/> but does no exact radius distance check, walks all entities that it finds in the grid /// </summary> /// <param name="centerPos"></param> /// <param name="radius"></param> /// <param name="callback"></param> public void WalkEntityPartitions(Vec3d centerPos, double radius, API.Common.Action <Entity> callback) { int mingx = (int)((centerPos.X - radius) / gridSizeInBlocks); int maxgx = (int)((centerPos.X + radius) / gridSizeInBlocks); /*int mingy = (int)((centerPos.Y - radius) / gridSizeInBlocks); * int maxgy = (int)((centerPos.Y + radius) / gridSizeInBlocks);*/ int mincy = (int)((centerPos.Y - radius) / chunkSize); int maxcy = (int)((centerPos.Y + radius) / chunkSize); int mingz = (int)((centerPos.Z - radius) / gridSizeInBlocks); int maxgz = (int)((centerPos.Z + radius) / gridSizeInBlocks); int cxBefore = -99, cyBefore = -99, czBefore = -99; IWorldChunk chunk = null; EntityPartitionChunk partitionChunk = null; int gridXMax = api.World.BlockAccessor.MapSizeX / gridSizeInBlocks; //int gridYMax = api.World.BlockAccessor.MapSizeX / gridSizeInBlocks; int gridZMax = api.World.BlockAccessor.MapSizeX / gridSizeInBlocks; int cyTop = api.World.BlockAccessor.MapSizeY / chunkSize; for (int gridX = mingx; gridX <= maxgx; gridX++) { for (int cy = mincy; cy <= maxcy; cy++) //for (int gridY = mingy; gridY <= maxgy; gridY++) { for (int gridZ = mingz; gridZ <= maxgz; gridZ++) { if (gridX < 0 || cy < 0 || gridZ < 0 || gridX >= gridXMax || cy >= cyTop || gridZ >= gridZMax) { continue; } int cx = gridX * gridSizeInBlocks / chunkSize; //int cy = gridY * gridSizeInBlocks / chunkSize; int cz = gridZ * gridSizeInBlocks / chunkSize; long index3d = MapUtil.Index3dL(cx, cy, cz, chunkMapSizeX, chunkMapSizeZ); if (cx != cxBefore || cy != cyBefore || cz != czBefore) { chunk = api.World.BlockAccessor.GetChunk(cx, cy, cz); Partitions.TryGetValue(index3d, out partitionChunk); } if (chunk == null || chunk.Entities == null || partitionChunk == null) { continue; } cxBefore = cx; cyBefore = cy; czBefore = cz; int lgx = gridX % partitionsLength; int lgz = gridZ % partitionsLength; List <Entity> entities = partitionChunk.Entities[lgz * partitionsLength + lgx]; for (int i = 0; i < entities.Count; i++) { callback(entities[i]); } } } } }
public override bool WalkTowards(Vec3d target, float movingSpeed, float targetDistance, API.Common.Action OnGoalReached, API.Common.Action OnStuck) { waypoints = new List <Vec3d>(); waypoints.Add(target); return(base.WalkTowards(target, movingSpeed, targetDistance, OnGoalReached, OnStuck)); }