Beispiel #1
0
        public void DebugVeinMaps(ICoreServerAPI api, IMapRegion mapRegion, int regionX, int regionZ)
        {
            TyronThreadPool.QueueTask(() =>
            {
                DirectoryInfo path = Directory.CreateDirectory(Path.Combine(GamePaths.DataPath, "VeinMaps", api.World.Seed.ToString()));
                Dictionary <string, IntDataMap2D> veinMaps = mapRegion.GetModdata <Dictionary <string, IntDataMap2D> >("veinmaps");

                foreach (var vein in veinMaps)
                {
                    IntDataMap2D veinMap = vein.Value;

                    Bitmap bmp = new Bitmap(veinMap.Size, veinMap.Size);
                    for (int x = 0; x < veinMap.Size; x++)
                    {
                        for (int y = 0; y < veinMap.Size; y++)
                        {
                            Argb8 test = new Argb8(veinMap.GetInt(x, y));
                            bmp.SetPixel(x, y, Color.FromArgb(test.Value));
                        }
                    }
                    Directory.CreateDirectory(Path.Combine(path.FullName, vein.Key.UcFirst()));

                    string pt = Path.Combine(path.FullName, vein.Key.UcFirst(), string.Format("{0}, {1}.png", regionX, regionZ));

                    bmp.Save(pt, ImageFormat.Png);
                }
            });
        }
Beispiel #2
0
        /// <summary>
        /// Recomposes the element for lines.
        /// </summary>
        public void RecomposeText(bool async = false)
        {
            if (autoHeight)
            {
                AutoHeight();
            }

            if (async)
            {
                TyronThreadPool.QueueTask(() =>
                {
                    ImageSurface surface = new ImageSurface(Format.Argb32, (int)Bounds.InnerWidth, (int)Bounds.InnerHeight);
                    Context ctx          = genContext(surface);
                    DrawMultilineTextAt(ctx, 0, 0, orientation);

                    api.Event.EnqueueMainThreadTask(() =>
                    {
                        generateTexture(surface, ref textTexture);
                        ctx.Dispose();
                        surface.Dispose();
                    }, "recompstatbar");
                });
            }
            else
            {
                ImageSurface surface = new ImageSurface(Format.Argb32, (int)Bounds.InnerWidth, (int)Bounds.InnerHeight);
                Context      ctx     = genContext(surface);
                DrawMultilineTextAt(ctx, 0, 0, orientation);

                generateTexture(surface, ref textTexture);
                ctx.Dispose();
                surface.Dispose();
            }
        }
        // For some reason, this won't work as an extension method.
        private void PurgeWaypoints(System.Func <Waypoint, bool> comparer)
        {
            TyronThreadPool.QueueTask(() => {
                var wpLayer   = _mapManager.WaypointMapLayer();
                var waypoints = new List <int>();
                for (var i = 0; i < wpLayer.ownWaypoints.Count; i++)
                {
                    if (comparer(wpLayer.ownWaypoints[i]))
                    {
                        waypoints.Add(i);
                    }
                }
                waypoints.Sort((a, b) => b.CompareTo(a));

                foreach (var num in waypoints)
                {
                    Api.Event.EnqueueMainThreadTask(() => Api.SendChatMessage($"/waypoint remove {num}"), "");
                }

                Api.Event.EnqueueMainThreadTask(() =>
                                                Api.Event.RegisterCallback(dt =>
                                                                           _mapManager.GetField <IClientNetworkChannel>("clientChannel")
                                                                           .SendPacket(new OnViewChangedPacket()), 500), "");
            });
        }
Beispiel #4
0
 void PrepareForLoading(int threadsCount)
 {
     // JSON parsing is slooowww, so let's multithread the **** out of it :)
     for (int i = 0; i < threadsCount; i++)
     {
         TyronThreadPool.QueueTask(GatherAllTypes_Async);
     }
 }
Beispiel #5
0
        void recomposeOverlays()
        {
            TyronThreadPool.QueueTask(() =>
            {
                ComposeValueOverlay();
                ComposeFlashOverlay();
            });

            if (ShowValueOnHover)
            {
                api.Gui.TextTexture.GenOrUpdateTextTexture(onGetStatbarValue(), valueFont, ref valueTexture, new TextBackground()
                {
                    FillColor   = GuiStyle.DialogStrongBgColor,
                    Padding     = 5,
                    BorderWidth = 2
                });
            }
        }
Beispiel #6
0
        public override void AssetsLoaded(ICoreAPI coreApi)
        {
            if (!(coreApi is ICoreServerAPI api))
            {
                return;
            }
            this.api = api;

            api.Logger.VerboseDebug("Starting to gather blocktypes, itemtypes and entities");
            LoadWorldProperties();
            int threads = Math.Max(1, Environment.ProcessorCount / 2 - 2);

            itemTypes   = new Dictionary <AssetLocation, RegistryObjectType>();
            blockTypes  = new Dictionary <AssetLocation, RegistryObjectType>();
            entityTypes = new Dictionary <AssetLocation, RegistryObjectType>();

            foreach (KeyValuePair <AssetLocation, JObject> entry in api.Assets.GetMany <JObject>(api.Server.Logger, "itemtypes/"))
            {
                try
                {
                    ItemType et = new ItemType();
                    et.CreateBasetype(entry.Key.Domain, entry.Value);
                    itemTypes.Add(entry.Key, et);
                }
                catch (Exception e)
                {
                    api.World.Logger.Error("Item type {0} could not be loaded. Will ignore. Exception thrown: {1}", entry.Key, e);
                    continue;
                }
            }
            itemVariants = new List <RegistryObjectType> [itemTypes.Count];
            api.Logger.VerboseDebug("Starting parsing ItemTypes in " + threads + " threads");
            PrepareForLoading(threads);

            foreach (KeyValuePair <AssetLocation, JObject> entry in api.Assets.GetMany <JObject>(api.Server.Logger, "entities/"))
            {
                try
                {
                    EntityType et = new EntityType();
                    et.CreateBasetype(entry.Key.Domain, entry.Value);
                    entityTypes.Add(entry.Key, et);
                }
                catch (Exception e)
                {
                    api.World.Logger.Error("Entity type {0} could not be loaded. Will ignore. Exception thrown: {1}", entry.Key, e);
                    continue;
                }
            }
            entityVariants = new List <RegistryObjectType> [entityTypes.Count];

            foreach (KeyValuePair <AssetLocation, JObject> entry in api.Assets.GetMany <JObject>(api.Server.Logger, "blocktypes/"))
            {
                try
                {
                    BlockType et = new BlockType();
                    et.CreateBasetype(entry.Key.Domain, entry.Value);
                    blockTypes.Add(entry.Key, et);
                }
                catch (Exception e)
                {
                    api.World.Logger.Error("Block type {0} could not be loaded. Will ignore. Exception thrown: {1}", entry.Key, e);
                    continue;
                }
            }
            blockVariants = new List <RegistryObjectType> [blockTypes.Count];

            TyronThreadPool.QueueTask(GatherAllTypes_Async);   // Now we've loaded everything, let's add one more gathering thread :)

            api.Logger.StoryEvent(Lang.Get("It remembers..."));
            api.Logger.VerboseDebug("Gathered all types, starting to load items");

            LoadItems(itemVariants);
            api.Logger.VerboseDebug("Parsed and loaded items");

            api.Logger.StoryEvent(Lang.Get("...all that came before"));

            LoadBlocks(blockVariants);
            api.Logger.VerboseDebug("Parsed and loaded blocks");

            LoadEntities(entityVariants);
            api.Logger.VerboseDebug("Parsed and loaded entities");

            api.Server.LogNotification("BlockLoader: Entities, Blocks and Items loaded");

            FreeRam();

            api.TriggerOnAssetsFirstLoaded();
        }
Beispiel #7
0
        public virtual void TesselateShape()
        {
            if (!loaded)
            {
                return;
            }

            shapeFresh = true;
            CompositeShape compositeShape = OverrideCompositeShape != null ? OverrideCompositeShape : entity.Properties.Client.Shape;

            Shape entityShape = OverrideEntityShape != null ? OverrideEntityShape : entity.Properties.Client.LoadedShapeForEntity;

            if (entityShape == null)
            {
                return;
            }

            OnTesselation?.Invoke(ref entityShape, compositeShape.Base.ToString());
            entity.OnTesselation(ref entityShape, compositeShape.Base.ToString());

            defaultTexSource = GetTextureSource();

            TyronThreadPool.QueueTask(() =>
            {
                MeshData meshdata;

                if (entity.Properties.Client.Shape.VoxelizeTexture)
                {
                    int altTexNumber = entity.WatchedAttributes.GetInt("textureIndex", 0);

                    TextureAtlasPosition pos      = defaultTexSource["all"];
                    CompositeTexture[] Alternates = entity.Properties.Client.FirstTexture.Alternates;

                    CompositeTexture tex = altTexNumber == 0 ? entity.Properties.Client.FirstTexture : Alternates[altTexNumber % Alternates.Length];
                    meshdata             = capi.Tesselator.VoxelizeTexture(tex, capi.EntityTextureAtlas.Size, pos);
                    for (int i = 0; i < meshdata.xyz.Length; i += 3)
                    {
                        meshdata.xyz[i]     -= 0.125f;
                        meshdata.xyz[i + 1] -= 0.5f;
                        meshdata.xyz[i + 2] += 0.125f / 2;
                    }
                }
                else
                {
                    try
                    {
                        TesselationMetaData meta = new TesselationMetaData()
                        {
                            quantityElements  = compositeShape.QuantityElements,
                            selectiveElements = compositeShape.SelectiveElements,
                            texSource         = this,
                            withJointIds      = true,
                            withDamageEffect  = true,
                            typeForLogging    = "entity"
                        };

                        capi.Tesselator.TesselateShape(meta, entityShape, out meshdata, new Vec3f(compositeShape.rotateX, compositeShape.rotateY, compositeShape.rotateZ));

                        meshdata.Translate(compositeShape.offsetX, compositeShape.offsetY, compositeShape.offsetZ);
                    }
                    catch (Exception e)
                    {
                        capi.World.Logger.Fatal("Failed tesselating entity {0} with id {1}. Entity will probably be invisible!. The teselator threw {2}", entity.Code, entity.EntityId, e);
                        return;
                    }
                }

                MeshData opaqueMesh = meshdata.Clone().Clear();
                MeshData oitMesh    = meshdata.Clone().Clear();
                opaqueMesh.AddMeshData(meshdata, EnumChunkRenderPass.Opaque);
                oitMesh.AddMeshData(meshdata, EnumChunkRenderPass.Transparent);

                capi.Event.EnqueueMainThreadTask(() =>
                {
                    if (meshRefOpaque != null)
                    {
                        meshRefOpaque.Dispose();
                        meshRefOpaque = null;
                    }
                    if (meshRefOit != null)
                    {
                        meshRefOit.Dispose();
                        meshRefOit = null;
                    }

                    if (capi.IsShuttingDown)
                    {
                        return;
                    }

                    if (opaqueMesh.VerticesCount > 0)
                    {
                        meshRefOpaque = capi.Render.UploadMesh(opaqueMesh);
                    }

                    if (oitMesh.VerticesCount > 0)
                    {
                        meshRefOit = capi.Render.UploadMesh(oitMesh);
                    }
                }, "uploadentitymesh");

                capi.TesselatorManager.ThreadDispose();
            });
        }
        void Recompose()
        {
            if (curSlot?.Itemstack == null)
            {
                return;
            }

            readyToRender = false;

            string title = curSlot.GetStackName();
            string desc  = OnRequireInfoText(curSlot);

            desc.TrimEnd();


            titleElement.SetNewText(title, titleFont);
            descriptionElement.SetNewText(desc, Font);

            RecalcBounds(title, desc);


            Bounds.CalcWorldBounds();

            ElementBounds textBounds = Bounds.CopyOnlySize();

            textBounds.CalcWorldBounds();

            TyronThreadPool.QueueTask(() =>
            {
                /*int i = 0;
                 * while (i < 5 && titleElement.HalfComposed) System.Threading.Thread.Sleep(5);*/

                ImageSurface surface = new ImageSurface(Format.Argb32, Bounds.OuterWidthInt, Bounds.OuterHeightInt);
                Context ctx          = genContext(surface);

                ctx.SetSourceRGBA(0, 0, 0, 0);
                ctx.Paint();

                ctx.SetSourceRGBA(backTint[0], backTint[1], backTint[2], backTint[3]);
                RoundRectangle(ctx, textBounds.bgDrawX, textBounds.bgDrawY, textBounds.OuterWidthInt, textBounds.OuterHeightInt, GuiStyle.DialogBGRadius);
                ctx.FillPreserve();

                ctx.SetSourceRGBA(GuiStyle.DialogLightBgColor[0] * 1.4, GuiStyle.DialogStrongBgColor[1] * 1.4, GuiStyle.DialogStrongBgColor[2] * 1.4, 1);
                ctx.LineWidth = 3 * 1.75;
                ctx.StrokePreserve();
                surface.Blur(8.2);

                ctx.SetSourceRGBA(backTint[0] / 2, backTint[1] / 2, backTint[2] / 2, backTint[3]);
                ctx.Stroke();


                int w = (int)(scaled(ItemStackSize) + scaled(40));
                int h = (int)(scaled(ItemStackSize) + scaled(40));

                ImageSurface shSurface = new ImageSurface(Format.Argb32, w, h);
                Context shCtx          = genContext(shSurface);

                shCtx.SetSourceRGBA(GuiStyle.DialogSlotBackColor);
                RoundRectangle(shCtx, 0, 0, w, h, 0);
                shCtx.FillPreserve();

                shCtx.SetSourceRGBA(GuiStyle.DialogSlotFrontColor);
                shCtx.LineWidth = 5;
                shCtx.Stroke();
                shSurface.Blur(7);
                shSurface.Blur(7);
                shSurface.Blur(7);
                EmbossRoundRectangleElement(shCtx, 0, 0, w, h, true);


                ctx.SetSourceSurface(shSurface, (int)(textBounds.drawX), (int)(textBounds.drawY + scaled(MarginTop)));
                ctx.Rectangle(textBounds.drawX, textBounds.drawY + scaled(MarginTop), w, h);
                ctx.Fill();

                shCtx.Dispose();
                shSurface.Dispose();


                api.Event.EnqueueMainThreadTask(() =>
                {
                    //titleElement.genTexture();
                    //descriptionElement.genTexture();

                    titleElement.Compose(false);
                    descriptionElement.Compose(false);

                    generateTexture(surface, ref texture);

                    ctx.Dispose();
                    surface.Dispose();

                    double offset = (int)(30 + ItemStackSize / 2);
                    scissorBounds = ElementBounds.Fixed(4 + offset - ItemStackSize, 2 + offset + MarginTop - ItemStackSize, ItemStackSize + 38, ItemStackSize + 38).WithParent(Bounds);
                    scissorBounds.CalcWorldBounds();

                    readyToRender = true;
                }, "genstackinfotexture");
            });
        }
Beispiel #9
0
        private void updateSounds(float dt)
        {
            float targetRainVolumeLeafy    = 0;
            float targetRainVolumeLeafless = 0;
            float targetHailVolume         = 0;
            float targetTrembleVolume      = 0;

            float targetRainPitch = 1;
            float targetHailPitch = 1;

            WeatherDataSnapshot weatherData = weatherSys.BlendedWeatherData;

            if (searchComplete)
            {
                EntityPlayer eplr = capi.World.Player.Entity;
                plrPos.Set((int)eplr.Pos.X, (int)eplr.Pos.Y, (int)eplr.Pos.Z);
                searchComplete = false;

                TyronThreadPool.QueueTask(() =>
                {
                    float val           = (float)Math.Pow(Math.Max(0, (capi.World.BlockAccessor.GetDistanceToRainFall(plrPos, 12, 4) - 2) / 10f), 2);
                    roomVolumePitchLoss = GameMath.Clamp(val, 0, 1);
                    searchComplete      = true;
                });
            }

            EnumPrecipitationType precType = weatherData.BlendedPrecType;

            if (precType == EnumPrecipitationType.Auto)
            {
                precType = weatherSys.clientClimateCond?.Temperature < weatherData.snowThresholdTemp ? EnumPrecipitationType.Snow : EnumPrecipitationType.Rain;
            }

            float nearbyLeaviness = GameMath.Clamp(GlobalConstants.CurrentNearbyRelLeavesCountClient * 60, 0, 1);

            ClimateCondition conds = weatherSys.clientClimateCond;

            if (conds.Rainfall > 0)
            {
                if (precType == EnumPrecipitationType.Rain || weatherSys.clientClimateCond.Temperature < weatherData.snowThresholdTemp)
                {
                    targetRainVolumeLeafy = nearbyLeaviness * GameMath.Clamp(conds.Rainfall * 2f - Math.Max(0, 2f * (weatherData.snowThresholdTemp - weatherSys.clientClimateCond.Temperature)), 0, 1);
                    targetRainVolumeLeafy = GameMath.Max(0, targetRainVolumeLeafy - roomVolumePitchLoss);

                    targetRainVolumeLeafless = Math.Max(0.3f, 1 - nearbyLeaviness) * GameMath.Clamp(conds.Rainfall * 2f - Math.Max(0, 2f * (weatherData.snowThresholdTemp - weatherSys.clientClimateCond.Temperature)), 0, 1);
                    targetRainVolumeLeafless = GameMath.Max(0, targetRainVolumeLeafless - roomVolumePitchLoss);

                    targetRainPitch = Math.Max(0.7f, 1.25f - conds.Rainfall * 0.7f);
                    targetRainPitch = Math.Max(0, targetRainPitch - roomVolumePitchLoss / 4f);

                    targetTrembleVolume = GameMath.Clamp(conds.Rainfall * 1.6f - 0.8f - roomVolumePitchLoss * 0.25f, 0, 1);

                    if (!rainSoundsOn && (targetRainVolumeLeafy > 0.01 || targetRainVolumeLeafless > 0.01))
                    {
                        for (int i = 0; i < rainSoundsLeafless.Length; i++)
                        {
                            rainSoundsLeafless[i]?.Start();
                        }
                        for (int i = 0; i < rainSoundsLeafy.Length; i++)
                        {
                            rainSoundsLeafy[i]?.Start();
                        }

                        lowTrembleSound?.Start();
                        rainSoundsOn = true;

                        curRainPitch = targetRainPitch;
                    }

                    if (capi.World.Player.Entity.IsEyesSubmerged())
                    {
                        curRainPitch              = targetRainPitch / 2;
                        targetRainVolumeLeafy    *= 0.75f;
                        targetRainVolumeLeafless *= 0.75f;
                    }
                }

                if (precType == EnumPrecipitationType.Hail)
                {
                    targetHailVolume = GameMath.Clamp(conds.Rainfall * 2f - roomVolumePitchLoss, 0, 1);
                    targetHailVolume = GameMath.Max(0, targetHailVolume - roomVolumePitchLoss);

                    targetHailPitch = Math.Max(0.7f, 1.25f - conds.Rainfall * 0.7f);
                    targetHailPitch = Math.Max(0, targetHailPitch - roomVolumePitchLoss / 4f);

                    if (!hailSoundsOn && targetHailVolume > 0.01)
                    {
                        hailSound?.Start();
                        hailSoundsOn = true;
                        curHailPitch = targetHailPitch;
                    }
                }
            }


            curRainVolumeLeafy    += (targetRainVolumeLeafy - curRainVolumeLeafy) * dt / 2;
            curRainVolumeLeafless += (targetRainVolumeLeafless - curRainVolumeLeafless) * dt / 2;

            curTrembleVolume += (targetTrembleVolume - curTrembleVolume) * dt;
            curHailVolume    += (targetHailVolume - curHailVolume) * dt;

            curHailPitch += (targetHailPitch - curHailPitch) * dt;
            curRainPitch += (targetRainPitch - curRainPitch) * dt;



            if (rainSoundsOn)
            {
                for (int i = 0; i < rainSoundsLeafless.Length; i++)
                {
                    rainSoundsLeafless[i]?.SetVolume(curRainVolumeLeafless);
                    rainSoundsLeafless[i]?.SetPitch(curRainPitch);
                }
                for (int i = 0; i < rainSoundsLeafy.Length; i++)
                {
                    rainSoundsLeafy[i]?.SetVolume(curRainVolumeLeafy);
                    rainSoundsLeafy[i]?.SetPitch(curRainPitch);
                }

                lowTrembleSound?.SetVolume(curTrembleVolume);
            }
            if (hailSoundsOn)
            {
                hailSound?.SetVolume(curHailVolume);
                hailSound?.SetPitch(curHailPitch);
            }


            if (curRainVolumeLeafless < 0.01 && curRainVolumeLeafy < 0.01)
            {
                for (int i = 0; i < rainSoundsLeafless.Length; i++)
                {
                    rainSoundsLeafless[i]?.Stop();
                }
                for (int i = 0; i < rainSoundsLeafy.Length; i++)
                {
                    rainSoundsLeafy[i]?.Stop();
                }
                rainSoundsOn = false;
            }

            if (curHailVolume < 0.01)
            {
                hailSound?.Stop();
                hailSoundsOn = false;
            }



            float wstr = (1 - roomVolumePitchLoss) * weatherData.curWindSpeed.X - 0.3f;

            if (wstr > 0.03f || curWindVolumeLeafy > 0.01f || curWindVolumeLeafless > 0.01f)
            {
                if (!windSoundsOn)
                {
                    windSoundLeafy?.Start();
                    windSoundLeafless?.Start();
                    windSoundsOn = true;
                }

                float targetVolumeLeafy    = nearbyLeaviness * 1.2f * wstr;
                float targetVolumeLeafless = (1 - nearbyLeaviness) * 1.2f * wstr;

                curWindVolumeLeafy    += (targetVolumeLeafy - curWindVolumeLeafy) * dt;
                curWindVolumeLeafless += (targetVolumeLeafless - curWindVolumeLeafless) * dt;

                windSoundLeafy?.SetVolume(curWindVolumeLeafy);
                windSoundLeafless?.SetVolume(curWindVolumeLeafless);
            }
            else
            {
                if (windSoundsOn)
                {
                    windSoundLeafy?.Stop();
                    windSoundLeafless?.Stop();
                    windSoundsOn = false;
                }
            }
        }