public override void Initialize(EntityProperties properties, JsonObject typeAttributes) { stepHeight = typeAttributes["stepHeight"].AsFloat(0.6f); for (int i = 0; i < Locomotors.Count; i++) { Locomotors[i].Initialize(properties); } smallerCollisionBox = entity.CollisionBox.Clone().OmniNotDownGrowBy(-0.1f); if (entity.World.Side == EnumAppSide.Client) { capi = (entity.World.Api as ICoreClientAPI); duringRenderFrame = true; capi.Event.RegisterRenderer(this, EnumRenderStage.Before, "controlledphysics"); } accumulator = (float)entity.World.Rand.NextDouble() * GlobalConstants.PhysicsFrameTime; }
public static bool LoadConfig(ICoreClientAPI capi) { try { if ((capi.LoadModConfig <VSHUDConfig>("vshud.json") ?? capi.LoadModConfig <VSHUDConfig>("waypointutils.json")) == null) { SaveConfig(capi); return(true); } Config = capi.LoadModConfig <VSHUDConfig>("vshud.json") ?? capi.LoadModConfig <VSHUDConfig>("waypointutils.json"); SaveConfig(capi); return(true); } catch (Exception) { capi.World.Logger.Notification("Error while parsing VSHUD configuration file, will use fallback settings. All changes to configuration in game will not be saved!"); capi.World.Logger.Notification("Use .vshudforcesave to fix."); return(false); } }
/// <summary> /// Gets a surface pattern from a named file. /// </summary> /// <param name="capi">The Client API</param> /// <param name="texFileName">The name of the file.</param> /// <param name="doCache">Do we cache the file?</param> /// <returns>The resulting surface pattern.</returns> public static SurfacePattern getPattern(ICoreClientAPI capi, string texFileName, bool doCache = true) { if (cachedPatterns.ContainsKey(texFileName) && cachedPatterns[texFileName].Key.HandleValid) { return(cachedPatterns[texFileName].Key); } ImageSurface patternSurface = getImageSurfaceFromAsset(capi, texFileName); SurfacePattern pattern = new SurfacePattern(patternSurface); pattern.Extend = Extend.Repeat; if (doCache) { cachedPatterns[texFileName] = new KeyValuePair <SurfacePattern, ImageSurface>(pattern, patternSurface); } return(pattern); }
public override void OnMouseDownOnElement(ICoreClientAPI api, MouseEvent args) { if (Bounds.InnerHeight <= currentHandleHeight + 0.001) { return; } if (Bounds.PointInside(args.X, args.Y)) { mouseDownOnScrollbarHandle = true; mouseDownStartY = GameMath.Max(0, args.Y - (int)Bounds.renderY, 0); if (mouseDownStartY > currentHandleHeight) { mouseDownStartY = (int)currentHandleHeight / 2; } UpdateHandlePositionAbs(args.Y - (int)Bounds.renderY - mouseDownStartY); args.Handled = true; } }
protected AdvancedOptionsDialog(ICoreClientAPI capi) : base(capi) { RegisterOption(new ConfigOption { SwitchKey = null, Text = null, ApplyText = "Reset To Default", Tooltip = "Resets settings to default preset.", ApplyAction = ToggleResetToDefault }); RegisterOption(new ConfigOption { SwitchKey = null, Text = null, ApplyText = "Apply Settings", Tooltip = "Applies user settings.", ApplyAction = ToggleApply }); }
ModelDataPoolLocation TrySqueezeInbetween(ICoreClientAPI capi, MeshData modeldata, Vec3i modelOrigin, Sphere frustumCullSphere) { int curVertexPos = 0; int curIndexPos = 0; for (int i = 0; i < poolLocations.Count; i++) { ModelDataPoolLocation location = poolLocations[i]; if (location.indicesStart - curIndexPos > modeldata.IndicesCount && location.verticesStart - curVertexPos > modeldata.VerticesCount) { return(InsertAt(capi, modeldata, modelOrigin, frustumCullSphere, curIndexPos, curVertexPos, i)); } curIndexPos = location.indicesEnd + 1; curVertexPos = location.verticesEnd + 1; } return(null); }
public override void OnBeforeRender(ICoreClientAPI capi, ItemStack itemstack, EnumItemRenderTarget target, ref ItemRenderInfo renderinfo) { if (meshCache == null) { meshCache = capi.ModLoader.GetModSystem <MealMeshCache>(); } CookingRecipe recipe = GetCookingRecipe(capi.World, itemstack); ItemStack[] contents = GetNonEmptyContents(capi.World, itemstack); float yoff = 2.5f; MeshRef meshref = meshCache.GetOrCreateMealInContainerMeshRef(this, recipe, contents, new Vec3f(0, yoff / 16f, 0)); if (meshref != null) { renderinfo.ModelRef = meshref; } }
public WireClass(ICoreAPI api, BlockEntity block1, BlockEntity block2) { this.block1 = block1; this.block2 = block2; if (api is ICoreClientAPI) { this.api = (ICoreClientAPI)api; loadMesh(); } ((IWirePoint)block1).AddWire(block2.Pos, this); ((IWirePoint)block2).AddWire(block1.Pos, this); if (block1 is IEnergyPoint) { ((IEnergyPoint)block1).InitializeEnergyPoint(api); } if (block2 is IEnergyPoint) { ((IEnergyPoint)block2).InitializeEnergyPoint(api); } }
public override void OnKeyDown(ICoreClientAPI api, KeyEvent args) { base.OnKeyDown(api, args); // Centers the map around the players position if (args.KeyCode == (int)GlKeys.Space) { CenterMapTo(api.World.Player.Entity.Pos.AsBlockPos); } if (api.Input.KeyboardKeyStateRaw[(int)GlKeys.Up] || //args.KeyCode == api.Input.HotKeys["walkforward"].CurrentMapping.KeyCode || api.Input.KeyboardKeyStateRaw[(int)GlKeys.Down] || //args.KeyCode == api.Input.HotKeys["walkbackward"].CurrentMapping.KeyCode || api.Input.KeyboardKeyStateRaw[(int)GlKeys.Left] || //args.KeyCode == api.Input.HotKeys["walkleft"].CurrentMapping.KeyCode || api.Input.KeyboardKeyStateRaw[(int)GlKeys.Right] //args.KeyCode == api.Input.HotKeys["walkright"].CurrentMapping.KeyCode ) { args.Handled = true; } }
public CampfireContentsRenderer(ICoreClientAPI api, BlockPos pos) { this.api = api; this.pos = pos; transform = new ModelTransform().EnsureDefaultValues(); transform.Origin.X = 8 / 16f; transform.Origin.Y = 1 / 16f; transform.Origin.Z = 8 / 16f; transform.Rotation.X = 90; transform.Rotation.Y = 90; transform.Rotation.Z = 0; transform.Translation.X = 0 / 32f; transform.Translation.Y = 4f / 16f; transform.Translation.Z = 0 / 32f; transform.ScaleXYZ.X = 0.25f; transform.ScaleXYZ.Y = 0.25f; transform.ScaleXYZ.Z = 0.25f; defaultTransform = transform; }
/// <summary> /// Initialize the track. /// </summary> /// <param name="assetManager">the global Asset Manager</param> /// <param name="capi">The Core Client API</param> /// <param name="musicEngine"></param> public void Initialize(IAssetManager assetManager, ICoreClientAPI capi, IMusicEngine musicEngine) { this.capi = capi; this.musicEngine = musicEngine; selectMinMaxHour(); Location.Path = "music/" + Location.Path.ToLowerInvariant() + ".ogg"; if (!initialized) { globalCooldownUntilMs = (long)(1000 * (AnySongCoolDowns[MusicFrequency][0] / 4 + rand.NextDouble() * AnySongCoolDowns[MusicFrequency][1] / 2)); capi.Settings.Int.AddWatcher("musicFrequency", (newval) => { FrequencyChanged(newval, capi); }); initialized = true; prevFrequency = MusicFrequency; } }
public override void OnLoaded(ICoreAPI api) { if (api.Side != EnumAppSide.Client) { return; } ICoreClientAPI capi = api as ICoreClientAPI; interactions = ObjectCacheUtil.GetOrCreate(api, "toolrackBlockInteractions", () => { List <ItemStack> rackableStacklist = new List <ItemStack>(); foreach (CollectibleObject obj in api.World.Collectibles) { if (obj.Tool != null) { List <ItemStack> stacks = obj.GetHandBookStacks(capi); if (stacks != null) { rackableStacklist.AddRange(stacks); } } } return(new WorldInteraction[] { new WorldInteraction() { ActionLangCode = "blockhelp-toolrack-place", HotKeyCode = null, MouseButton = EnumMouseButton.Right, Itemstacks = rackableStacklist.ToArray() }, new WorldInteraction() { ActionLangCode = "blockhelp-toolrack-take", HotKeyCode = null, MouseButton = EnumMouseButton.Right, } }); }); }
public override void StartClientSide(ICoreClientAPI api) { _api = api; api.Event.RegisterGameTickListener(OnGameTick, 20); if (Environment.OSVersion.Platform == PlatformID.Unix) { var fileName = $"/dev/shm/MumbleLink.{getuid()}"; void OnCreated(object sender, FileSystemEventArgs e) { Mod.Logger.Notification("Link established"); _mappedFile = MemoryMappedFile.CreateFromFile(fileName); _stream = _mappedFile.CreateViewStream(0, MumbleLinkData.Size); } void OnDeleted(object sender, FileSystemEventArgs e) { Mod.Logger.Notification("Link lost"); _stream.Dispose(); _mappedFile.Dispose(); _stream = null; _mappedFile = null; } if (File.Exists(fileName)) { OnCreated(null, null); } _watcher = new FileSystemWatcher(Path.GetDirectoryName(fileName), Path.GetFileName(fileName)); _watcher.Created += OnCreated; _watcher.Deleted += OnDeleted; _watcher.EnableRaisingEvents = true; } else { _mappedFile = MemoryMappedFile.CreateOrOpen("MumbleLink", MumbleLinkData.Size); _stream = _mappedFile.CreateViewStream(0, MumbleLinkData.Size); } }
public override int GetColor(ICoreClientAPI capi, BlockPos pos) { string grasscover = LastCodePart(); if (grasscover == "none") { return(base.GetColorWithoutTint(capi, pos)); } CompositeTexture tex; if (Textures == null || !Textures.TryGetValue("specialSecondTexture", out tex)) { tex = Textures?.First().Value; } int?textureSubId = tex?.Baked.TextureSubId; if (textureSubId == null) { return(ColorUtil.WhiteArgb); } int grassColor = capi.BlockTextureAtlas.GetAverageColor((int)textureSubId); if (ClimateColorMap != null) { grassColor = capi.World.ApplyColorMapOnRgba(ClimateColorMap, SeasonColorMap, grassColor, pos.X, pos.Y, pos.Z, false); } if (grasscover == "normal") { return(grassColor); } else { int soilColor = capi.BlockTextureAtlas.GetAverageColor((int)Textures["up"].Baked.TextureSubId); return(ColorUtil.ColorOverlay(soilColor, grassColor, grasscover == "verysparse" ? 0.5f : 0.75f)); } }
public override void OnMouseDownOnElement(ICoreClientAPI api, MouseEvent args) { base.OnMouseDownOnElement(api, args); rightSpacing = scaled(17); int mouseX = args.X; int mouseY = args.Y; float size = Interval; if (api.Input.KeyboardKeyStateRaw[(int)GlKeys.LShift]) { size /= 10; } if (api.Input.KeyboardKeyStateRaw[(int)GlKeys.ControlLeft]) { size /= 100; } if (mouseX >= Bounds.absX + Bounds.OuterWidth - rightSpacing && mouseX <= Bounds.absX + Bounds.OuterWidth && mouseY >= Bounds.absY && mouseY <= Bounds.absY + Bounds.OuterHeight) { double heightHalf = Bounds.OuterHeight / 2 - 1; if (mouseY > Bounds.absY + heightHalf + 1) { double val; double.TryParse(lines[0], out val); val -= size; lines[0] = "" + Math.Round(val, 4); SetValue(lines[0]); } else { double val; double.TryParse(lines[0], out val); val += size; lines[0] = "" + Math.Round(val, 4); SetValue(lines[0]); } } }
public override void Initialize(ICoreAPI api) { base.Initialize(api); RegisterGameTickListener(TestHarvestable, 3000); RegisterGameTickListener(OnScanForEmptySkep, api.World.Rand.Next(5000) + 30000); roomreg = Api.ModLoader.GetModSystem <RoomRegistry>(); if (api.Side == EnumAppSide.Client) { RegisterGameTickListener(SpawnBeeParticles, 300); } if (wasPlaced) { harvestableAtTotalHours = api.World.Calendar.TotalHours + 24 / 2 * (3 + api.World.Rand.NextDouble() * 8); } orientation = Block.LastCodePart(); isWildHive = Block.FirstCodePart() != "skep"; if (!isWildHive && api.Side == EnumAppSide.Client) { ICoreClientAPI capi = api as ICoreClientAPI; Block fullSkep = api.World.GetBlock(new AssetLocation("skep-populated-east")); MeshData mesh; capi.Tesselator.TesselateShape( fullSkep, api.Assets.TryGet("shapes/block/beehive/skep-harvestable.json").ToObject <Shape>(), out mesh, new Vec3f(0, BlockFacing.FromCode(orientation).HorizontalAngleIndex * 90 - 90, 0) ); api.ObjectCache["beehive-harvestablemesh-" + orientation] = mesh; } if (!isWildHive && api.Side == EnumAppSide.Server) { api.ModLoader.GetModSystem <POIRegistry>().AddPOI(this); } }
public void OpenDialog(IClientWorldAccessor world, BlockPos pos, ItemStack ingredient) { if (ingredient.Collectible is ItemWorkItem) { ingredient = new ItemStack(world.GetItem(new AssetLocation("clay-" + ingredient.Collectible.LastCodePart()))); } List <ClayFormingRecipe> recipes = world.ClayFormingRecipes .Where(r => r.Ingredient.SatisfiesAsIngredient(ingredient)) .OrderBy(r => r.Output.ResolvedItemstack.Collectible.Code) // Cannot sort by name, thats language dependent! .ToList(); ; List <ItemStack> stacks = recipes .Select(r => r.Output.ResolvedItemstack) .ToList() ; ICoreClientAPI capi = Api as ICoreClientAPI; dlg = new GuiDialogBlockEntityRecipeSelector( Lang.Get("Select recipe"), stacks.ToArray(), (selectedIndex) => { capi.Logger.VerboseDebug("Select clay from recipe {0}, have {1} recipes.", selectedIndex, recipes.Count); selectedRecipeId = recipes[selectedIndex].RecipeId; capi.Network.SendBlockEntityPacket(pos.X, pos.Y, pos.Z, (int)EnumClayFormingPacket.SelectRecipe, SerializerUtil.Serialize(recipes[selectedIndex].RecipeId)); }, () => { capi.Network.SendBlockEntityPacket(pos.X, pos.Y, pos.Z, (int)EnumClayFormingPacket.CancelSelect); }, pos, Api as ICoreClientAPI ); dlg.OnClosed += dlg.Dispose; dlg.TryOpen(); }
public override int GetColor(ICoreClientAPI capi, BlockPos pos) { string grasscover = LastCodePart(); if (grasscover == "none") { return(base.GetColor(capi, pos)); } CompositeTexture tex; if (Textures == null || !Textures.TryGetValue("specialSecondTexture", out tex)) { tex = Textures?.First().Value; } int?textureSubId = tex?.Baked.TextureSubId; if (textureSubId == null) { return(ColorUtil.WhiteArgb); } int grassColor = ColorUtil.ReverseColorBytes(capi.BlockTextureAtlas.GetPixelAt((int)textureSubId, 0.5f, 0.5f)); if (TintIndex > 0) { grassColor = capi.ApplyColorTintOnRgba(TintIndex, grassColor, pos.X, pos.Y, pos.Z, false); } if (grasscover == "normal") { return(grassColor); } else { int soilColor = ColorUtil.ReverseColorBytes(capi.BlockTextureAtlas.GetPixelAt((int)Textures["up"].Baked.TextureSubId, 0.5f, 0.5f)); return(ColorUtil.ColorOverlay(soilColor, grassColor, grasscover == "verysparse" ? 0.5f : 0.75f)); } }
public override void OnBeforeRender(ICoreClientAPI capi, ItemStack itemstack, EnumItemRenderTarget target, ref ItemRenderInfo renderinfo) { if (Code.Path.Contains("clay")) { return; } Dictionary <string, MeshRef> meshrefs = null; object obj; if (capi.ObjectCache.TryGetValue(meshRefsCacheKey, out obj)) { meshrefs = obj as Dictionary <string, MeshRef>; } else { capi.ObjectCache[meshRefsCacheKey] = meshrefs = new Dictionary <string, MeshRef>(); } ItemStack contentStack = GetContent(itemstack); if (contentStack == null) { return; } MeshRef meshRef = null; if (!meshrefs.TryGetValue(contentStack.Collectible.Code.Path + Code.Path + contentStack.StackSize, out meshRef)) { MeshData meshdata = GenMesh(capi, contentStack); if (meshdata == null) { return; } meshrefs[contentStack.Collectible.Code.Path + Code.Path + contentStack.StackSize] = meshRef = capi.Render.UploadMesh(meshdata); } renderinfo.ModelRef = meshRef; }
public override void OnLoaded(ICoreAPI api) { if (api.Side != EnumAppSide.Client) { return; } ICoreClientAPI capi = api as ICoreClientAPI; interactions = ObjectCacheUtil.GetOrCreate(api, "cookedContainerBlockInteractions", () => { List <ItemStack> fillableStacklist = new List <ItemStack>(); foreach (CollectibleObject obj in api.World.Collectibles) { if (obj.Attributes?["mealContainer"].AsBool() == true) { List <ItemStack> stacks = obj.GetHandBookStacks(capi); if (stacks != null) { fillableStacklist.AddRange(stacks); } } } return(new WorldInteraction[] { new WorldInteraction() { ActionLangCode = "blockhelp-cookedcontainer-takefood", HotKeyCode = null, MouseButton = EnumMouseButton.Right, Itemstacks = fillableStacklist.ToArray() }, new WorldInteraction() { ActionLangCode = "blockhelp-cookedcontainer-pickup", HotKeyCode = null, MouseButton = EnumMouseButton.Right } }); }); }
public override void OnLoaded(ICoreAPI api) { if (Attributes?["capacityLitres"].Exists == true) { capacityLitresFromAttributes = Attributes["capacityLitres"].AsInt(50); } if (api.Side != EnumAppSide.Client) { return; } ICoreClientAPI capi = api as ICoreClientAPI; interactions = ObjectCacheUtil.GetOrCreate(api, "liquidContainerBase", () => { List <ItemStack> liquidContainerStacks = new List <ItemStack>(); foreach (CollectibleObject obj in api.World.Collectibles) { if ((obj is BlockBowl && obj.LastCodePart() != "raw") || obj is ILiquidSource || obj is ILiquidSink || obj is BlockWateringCan) { List <ItemStack> stacks = obj.GetHandBookStacks(capi); if (stacks != null) { liquidContainerStacks.AddRange(stacks); } } } ItemStack[] lstacks = liquidContainerStacks.ToArray(); return(new WorldInteraction[] { new WorldInteraction() { ActionLangCode = "blockhelp-bucket-rightclick", MouseButton = EnumMouseButton.Right, Itemstacks = liquidContainerStacks.ToArray() } }); }); }
public override void Initialize(ICoreAPI api) { base.Initialize(api); if (api.Side == EnumAppSide.Client) { ICoreClientAPI capi = api as ICoreClientAPI; Block ownBlock = api.World.BlockAccessor.GetBlock(Pos); // Loads the mesh from a model created by VS Model Creator, but you could just as well create a mesh in code, e.g. via QuadMeshUtil.GetCustomQuad(); Shape shape = capi.Assets.TryGet(new AssetLocation("customshapeblock", "shapes/customshapes/plane.json")).ToObject <Shape>(); texPosition = capi.BlockTextureAtlas.GetPosition(ownBlock, "north"); capi.Tesselator.TesselateShape("customshape", shape, out plane, this); // Alternatively you can also use the block itself as texture souce and not implement ITexPositionSource //capi.Tesselator.TesselateShape(ownBlock, shape, out plane); // Move the model up by half a block. Alternatively move it up by half a block in the VSMC model plane.Translate(0, 0.5f, 0); } }
public override void StartClientSide(ICoreClientAPI api) { capi = api; api.Input.RegisterHotKey("sortinv", "Sort Inventory", GlKeys.Y, HotkeyType.GUIOrOtherControls); api.Input.SetHotKeyHandler("sortinv", (keycomb) => { inv = api.World.Player.InventoryManager.CurrentHoveredSlot?.Inventory; if (inv == null || inv.ClassName == GlobalConstants.creativeInvClassName || inv.ClassName == GlobalConstants.hotBarInvClassName) { return(true); } sortingIterator = IterateOnReturned(); inv.SlotModified += SortFunc; SortFunc(0); return(true); }); }
public void OpenStatusGUI() { ICoreClientAPI capi = Api as ICoreClientAPI; if (capi != null) { if (gas == null) { gas = new GUIAssemblerStatus("Assembler Status", Pos, capi); gas.TryOpen(); gas.SetupDialog(this); } else { gas.TryClose(); gas.TryOpen(); gas.SetupDialog(this); } } }
/// <summary> /// Converts the color to RGBA. /// </summary> /// <param name="capi">The Core Client API.</param> /// <returns>The set RGBA color.</returns> public int GetRgbaColor(ICoreClientAPI capi) { if (HsvaColor == null) { return(Color); } int color = ColorUtil.HsvToRgba( (byte)GameMath.Clamp(HsvaColor[0].nextFloat(), 0, 255), (byte)GameMath.Clamp(HsvaColor[1].nextFloat(), 0, 255), (byte)GameMath.Clamp(HsvaColor[2].nextFloat(), 0, 255), (byte)GameMath.Clamp(HsvaColor[3].nextFloat(), 0, 255) ); int r = color & 0xff; int g = (color >> 8) & 0xff; int b = (color >> 16) & 0xff; int a = (color >> 24) & 0xff; return((r << 16) | (g << 8) | (b << 0) | (a << 24)); }
private void OnLoadedClientSide(ICoreClientAPI capi) { meshrefs = new MeshRef[MAX_ANGLED_MESHES]; string key = Code.ToString() + "-meshes"; var baseShape = capi.Assets.TryGet("compass:shapes/block/compass/base.json")?.ToObject <Shape>(); var needleShape = capi.Assets.TryGet("compass:shapes/block/compass/needle.json")?.ToObject <Shape>(); capi.Tesselator.TesselateShape(this, baseShape, out MeshData compassBaseMeshData, new Vec3f(0, 0, 0)); meshrefs = ObjectCacheUtil.GetOrCreate(capi, key, () => { for (var angleIndex = 0; angleIndex < MAX_ANGLED_MESHES; angleIndex += 1) { float angle = (float)((double)angleIndex / MAX_ANGLED_MESHES * 360); capi.Tesselator.TesselateShape(this, needleShape, out MeshData meshData, new Vec3f(0, angle, 0)); meshData.AddMeshData(compassBaseMeshData); meshrefs[angleIndex] = capi.Render.UploadMesh(meshData); }
public override void OnMouseDownOnElement(ICoreClientAPI api, MouseEvent args) { base.OnMouseDownOnElement(api, args); double spacing = scaled(unscaledTabSpacing); double xpos = spacing; int mouseRelX = api.Input.MouseX - (int)Bounds.absX; int mouseRelY = api.Input.MouseY - (int)Bounds.absY; for (int i = 0; i < tabs.Length; i++) { if (mouseRelX > xpos && mouseRelX < xpos + tabWidths[i] && mouseRelY > 0 && mouseRelY < Bounds.InnerHeight) { SetValue(i); break; } xpos += tabWidths[i] + spacing; } }
public EntityBlockFallingRenderer(Entity entity, ICoreClientAPI api) : base(entity, api) { this.blockFallingEntity = (EntityBlockFalling)entity; this.block = blockFallingEntity.Block; if (blockFallingEntity.removedBlockentity is IBlockShapeSupplier) { (blockFallingEntity.removedBlockentity as IBlockShapeSupplier).OnTesselation(this, capi.Tesselator); } if (this.meshRef == null) { this.meshRef = api.Render.UploadMesh(api.TesselatorManager.GetDefaultBlockMesh(block)); } int textureSubId = block.FirstTextureInventory.Baked.TextureSubId; this.atlasTextureId = api.BlockTextureAtlas.Positions[textureSubId].atlasTextureId; }
public override void OnMouseDownOnElement(ICoreClientAPI api, MouseEvent args) { base.OnMouseDownOnElement(api, args); int dx = api.Input.MouseX - (int)Bounds.absX; int dy = api.Input.MouseY - (int)Bounds.absY; double slotPadding = scaled(GuiElementItemSlotGrid.unscaledSlotPadding); double slotWidth = scaled(GuiElementPassiveItemSlot.unscaledSlotSize); double slotHeight = scaled(GuiElementPassiveItemSlot.unscaledSlotSize); int row = (int)(dy / (slotHeight + slotPadding)); int col = (int)(dx / (slotWidth + slotPadding)); int index = row * cols + col; if (index >= 0 && index < skillItems.Count) { OnSlotClick?.Invoke(index); } }
public IngotMoldRenderer(BlockPos pos, ICoreClientAPI api) { this.pos = pos; this.api = api; MeshData modeldata = QuadMeshUtil.GetQuad(); modeldata.Uv = new float[] { 3 / 16f, 7 / 16f, 0, 7 / 16f, 0, 0, 3 / 16f, 0 }; modeldata.Rgba = new byte[4 * 4]; modeldata.Rgba.Fill((byte)255); modeldata.Flags = new int[4 * 4]; quadModelRef = api.Render.UploadMesh(modeldata); }