Jump to content

Orjanek

Vintarian
  • Posts

    2
  • Joined

  • Last visited

Everything posted by Orjanek

  1. Hi, I'm freshly learning the modding and haven't touched entities so far yet, but wanted to join discussion if you or someone figures this out. I haven't used Harmony (and honestly I'm trying to avoid it as it seems it's quite delicate and would require higher level of maintenance between releases) - but perhaps using it would be the easiest way of doing this... It depends on what you mean by If there is additional logic to be added I think there is no way other than modifying AiTaskFleeEntity functions (as the logic of other AI stuff calls the flee behavior), but if just changing default parameters would be enough I did some digging: The behavior/aitasks/fleeentity from json has some params. Unfortunately it seems that these are loaded as JSon objects per entity type (and that is read-only) and can't be modified on the fly. With this code in ModSystem I was able to get the list of all entities with flee behavior: public override void AssetsFinalize(ICoreAPI api) { if (api.Side != EnumAppSide.Server)return; foreach (EntityProperties ep in api.World.EntityTypes) { if(ep.Server.BehaviorsAsJsonObj != null) { for (int i = 0; i < ep.Server.BehaviorsAsJsonObj.Length; i++) { JsonObject jobj = ep.Server.BehaviorsAsJsonObj[i]; string code = jobj["code"].AsString(); if("taskai" == code) { if (null == jobj["aitasks"]) break; // I don't think this should happen, but guard just in case JsonObject[] aitasks = jobj["aitasks"].AsArray(); Mod.Logger.Notification("Entity: {0}", ep.Code.ToString()); foreach (JsonObject _j in aitasks) { if ("fleeentity" == _j["code"].AsString()) { Mod.Logger.Notification("Entity {0}", ep.Code.ToString()); Mod.Logger.Notification("Flee move speed: {0}", _j["movespeed"].AsFloat()); // _j is read-only and we can't "patch" it's default value :( } } } } } } } It seems that each the entity behavior has JSON-loaded default config. When entity spawns, this config is loaded and behavior list gets populated. This is problematic for modding without interference with original class, as it'd mean that we'd have to overwrite these values per entity per spawn in real time in game. The performance loss might be inconsequential, but it seems fishy. Patching every single json as you mentioned also feels like a wrong approach. I'll continue to look at different angles for it, feel free to share any findings. EDIT: Following on the just-existing-attributes topic, it seems quite simple with harmony to do the following: [HarmonyPostfix] [HarmonyPatch(typeof(AiTaskFleeEntity), nameof(AiTaskFleeEntity.LoadConfig))] public static void AfterLoadConfig(ref float ___moveSpeed) { ___moveSpeed = 2.0f; } This does not solve the issue of saving additional data within the class (not sure if this is possible), but it really depends on what you want to do. Existing fields seem to be easily accessible through postfix onLoadConfig harmony patch, and any change to behavior can be probably done by pre/postfixing appropriate methods within the behavior class. Also, another approach that might be possible to experiment with is to just add additional custom behavior to entity from your own class, and harmony-patch functions that actually call the Flee behavior, to instead call your class instead.
  2. Hi everyone, I want to create block that can hold different kind of items, and to render these items on it (similar to toolrack). I've seen multiple ways of doing this in the survival mod and I'm still a bit lost. Please correct me if any of the info I'm providing is wrong. The Forge has it's own content renderer and uses already existing shapes (ForgeContentsRenderer -> RegenMesh). The Toolrack implements the ITexPositionSource for locating texture atlas position for tools (with some dictionary magic for getting ToolTextureSubIds ), but it seems limited to only tools. The GroundStorage seems closest to what I need, it uses also it's own renderer, but is also most complex one. Going through where do we get meshes I finally land in getOrCreateMesh within BEContainerDisplay. There is this code pattern I keep seeing in different places: IContainedMeshSource meshSource = stack.Collectible?.GetCollectibleInterface<IContainedMeshSource>(); if (meshSource != null) { toolMeshes[i] = meshSource.GenMesh(stack, capi.BlockTextureAtlas, Pos); } else { if (stack.Class == EnumItemClass.Item) { capi.Tesselator.TesselateItem(stack.Item, out toolMeshes[i], this); } else { capi.Tesselator.TesselateBlock(stack.Block, out toolMeshes[i]); } } Just to compare with what's in BEContainerDisplay: IContainedMeshSource meshSource = stack.Collectible?.GetCollectibleInterface<IContainedMeshSource>(); if (meshSource != null) { mesh = meshSource.GenMesh(stack, capi.BlockTextureAtlas, Pos); } if (mesh == null) { ICoreClientAPI capi = Api as ICoreClientAPI; if (stack.Class == EnumItemClass.Block) { mesh = capi.TesselatorManager.GetDefaultBlockMesh(stack.Block).Clone(); } else { nowTesselatingObj = stack.Collectible; nowTesselatingShape = null; if (stack.Item.Shape?.Base != null) { nowTesselatingShape = capi.TesselatorManager.GetCachedShape(stack.Item.Shape.Base); } capi.Tesselator.TesselateItem(stack.Item, out mesh, this); mesh.RenderPassesAndExtraBits.Fill((short)EnumChunkRenderPass.BlendNoCull); } } Basically I see that it follows pattern of: Take "contained mesh source" if possible first. If that fails, in no particular order handle Blocks/Items meshes. - What is the use case of handling these "contained mesh sources" first? What types of items/blocks have this and when I can rely on it? - Should block that stores & displays contained items inherit the BEContainerDisplays and play around with rotation/scale and col/sel boxes? Why the toolrack/forge are not using this? Cheers EDIT: Writing the question was an excellent rubber duck. I achieved what I wanted by inheriting my BE from BlockEntityDisplay and setting up offsets for inventory elements within the genTransformationMatrices override. If someone is familiar with the topic, I'd still love to know the answers to the questions above - and if this solution actually sounds ok (maybe it's highly bad for performance or multiplayer? No idea as for now.)
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.