mirror of
https://github.com/eaglerforge/EaglerForgeInjector
synced 2025-07-23 06:01:38 -09:00
progress on custom entities
This commit is contained in:
parent
c8664c7a5b
commit
9555af5b1a
@ -1,8 +1,10 @@
|
||||
## ModAPI.keygen
|
||||
ModAPI.keygen contains the API for getting item and block IDs from a string. It looks at the registries for items and blocks to derive the IDs, so IDs will not be automatically reserved until a block/item is actually registered. Ideally, you'd want to call a keygen method just before registering your block.
|
||||
ModAPI.keygen contains the API for getting numerical item, block and entity IDs from a string. It looks at registries to derive the IDs, so IDs will not be automatically reserved until a block/item is actually registered into the game. Ideally, you'd want to call a keygen method just before registering your block.
|
||||
|
||||
Methods:
|
||||
- `ModAPI.keygen.item(itemId: String) : number`
|
||||
- Example usage is: `var id = ModAPI.keygen.item("my_example_item");`
|
||||
- `ModAPI.keygen.block(blockId: String) : number`
|
||||
- Example usage is: `var id = ModAPI.keygen.block("my_example_block");`
|
||||
- Example usage is: `var id = ModAPI.keygen.block("my_example_block");`
|
||||
- `ModAPI.keygen.entity(entityId: String) : number`
|
||||
- Example usage is: `var id = ModAPI.keygen.entity("my_example_entity");`
|
@ -16,9 +16,10 @@ Methods:
|
||||
- This method is used to find a class by its id.
|
||||
- For example, to get the `Minecraft` class, you can use `ModAPI.reflect.getClassById("Minecraft")`
|
||||
- This runs slower than `getClassById` because it has to filter through all classes. Make sure to cache the result rather than calling it over and over again.
|
||||
- `ModAPI.reflect.getSuper(rClass: ReflectClass, filter: Function) : Function`
|
||||
- `ModAPI.reflect.getSuper(rClass: ReflectClass, filter: Function?) : Function`
|
||||
- Gets a super function from a reflect class. This is used to extend built in classes, like `Block`.
|
||||
- For an example, see lines [29](https://github.com/eaglerforge/EaglerForgeInjector/blob/6e8598c180f96a65c0c101be72e6d0fa53195404/examplemods/unlucky_blocks.js#L29) and [33](https://github.com/eaglerforge/EaglerForgeInjector/blob/6e8598c180f96a65c0c101be72e6d0fa53195404/examplemods/unlucky_blocks.js#L33) in unlucky_blocks.js
|
||||
- For an example, see lines [29](https://github.com/eaglerforge/EaglerForgeInjector/blob/6e8598c180f96a65c0c101be72e6d0fa53195404/examplemods/unlucky_blocks.js#L29) and [33](https://github.com/eaglerforge/EaglerForgeInjector/blob/6e8598c180f96a65c0c101be72e6d0fa53195404/examplemods/unlucky_blocks.js#L33) in `unlucky_blocks.js`
|
||||
- When called without a filter function, the filter defaults to `(fn)=>fn.length === 1`
|
||||
- `ModAPI.reflect.prototypeStack(rClass: ReflectClass, target: Class/ConstructorFunction) : void`
|
||||
- Copies methods from a reflect class and it's parents onto a target native JavaScript class. This allows TeaVM to use these objects normally, without you having to manually reimplement every method. In other words, this is the equivalent of extending a class.
|
||||
- [Example usage](https://github.com/eaglerforge/EaglerForgeInjector/blob/6e8598c180f96a65c0c101be72e6d0fa53195404/examplemods/unlucky_blocks.js#L37)
|
||||
|
@ -5,12 +5,87 @@
|
||||
ModAPI.meta.credits("By ZXMushroom64");
|
||||
|
||||
function registerEntity() {
|
||||
|
||||
// Utils
|
||||
const ResourceLocation = ModAPI.reflect.getClassByName("ResourceLocation").constructors.find(x=>x.length===1);
|
||||
const GlStateManager = Object.fromEntries(Object.values(ModAPI.reflect.getClassByName("GlStateManager").staticMethods).map(x=>[x.methodNameShort, x.method]));
|
||||
|
||||
// START CUSTOM ENTITY
|
||||
var entityClass = ModAPI.reflect.getClassById("net.minecraft.entity.Entity");
|
||||
var entitySuper = ModAPI.reflect.getSuper(entityClass, (x) => x.length === 2);
|
||||
var nme_EntityCube = function nme_EntityCube($worldIn) {
|
||||
entitySuper(this, $worldIn);
|
||||
this.$setCreativeTab(creativeMiscTab);
|
||||
this.$preventEntitySpawning = 1;
|
||||
this.$setSize(1, 1);
|
||||
}
|
||||
ModAPI.reflect.prototypeStack(entityClass, nme_EntityCube);
|
||||
nme_EntityCube.prototype.$canTriggerWalking = function () { return 0 };
|
||||
nme_EntityCube.prototype.$canBePushed = function () { return 0 };
|
||||
nme_EntityCube.prototype.$getCollisionBox = function () { return this.$getEntityBoundingBox() };
|
||||
nme_EntityCube.prototype.$getCollisionBoundingBox = function () { return this.$getEntityBoundingBox() };
|
||||
// END CUSTOM ENTITY
|
||||
|
||||
|
||||
// START CUSTOM MODEL
|
||||
var ModelRenderer = ModAPI.reflect.getClassById("net.minecraft.client.model.ModelRenderer").constructors.find(x => x.length === 1);
|
||||
var modelBaseClass = ModAPI.reflect.getClassById("net.minecraft.client.model.ModelBase");
|
||||
var modelBaseSuper = ModAPI.reflect.getSuper(entityClass); //while super isn't used when extending this class, java implies the call.
|
||||
var nmcm_ModelCube = function nmcm_ModelCube() {
|
||||
modelBaseSuper(this);
|
||||
this.$textureWidth = 64;
|
||||
this.$textureHeight = 64;
|
||||
this.$cubeRenderer = ModelRenderer(this).$setTextureOffset(0, 0);
|
||||
this.$cubeRenderer.$addBox0(0, 0, 0, 1, 1, 1);
|
||||
this.$cubeRenderer.$setRotationPoint(0, 0, 0);
|
||||
}
|
||||
ModAPI.reflect.prototypeStack(modelBaseClass, nmcm_ModelCube);
|
||||
nmcm_ModelCube.prototype.$render = function ($entity, useless1, useless2, partialTicks, useless3, useless4, f) {
|
||||
this.$cubeRenderer.$render(f);
|
||||
}
|
||||
// END CUSTOM MODEL
|
||||
|
||||
|
||||
// START CUSTOM RENDERER
|
||||
var renderClass = ModAPI.reflect.getClassById("net.minecraft.client.renderer.entity.Render");
|
||||
var renderSuper = ModAPI.reflect.getSuper(entityClass, (x)=>x.length === 2);
|
||||
const cubeTextures = ResourceLocation(ModAPI.util.str("textures/entity/cube.png"));
|
||||
var nmcre_RenderCube = function nmcre_RenderCube(renderManager) {
|
||||
renderSuper(this, renderManager);
|
||||
this.$modelCube = new nmcm_ModelCube();
|
||||
this.$shadowSize = 0.5;
|
||||
}
|
||||
ModAPI.reflect.prototypeStack(renderClass, nmcre_RenderCube);
|
||||
nmcre_RenderCube.prototype.$getEntityTexture = function (entity) {
|
||||
return cubeTextures;
|
||||
}
|
||||
const parentDoRender = nmcre_RenderCube.prototype.$doRender;
|
||||
nmcre_RenderCube.prototype.$doRender = function (entity, x, y, z, yaw, pitch) {
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translate(x, y + 0.25, z);
|
||||
GlStateManager.rotate(180 - yaw, 0, 1, 0);
|
||||
this.$bindEntityTexture(entity);
|
||||
this.$modelCube.$render(entity, 0, 0, -0.1, 0, 0, 0.0625);
|
||||
GlStateManager.popMatrix();
|
||||
parentDoRender.apply(this, [entity, x, y, z, yaw, pitch]);
|
||||
}
|
||||
|
||||
ModAPI.reflect.getClassById("net.minecraft.entity.EntityList").staticMethods.addMapping0(
|
||||
ModAPI.util.asClass(nme_EntityCube),
|
||||
{
|
||||
$createEntity: nme_EntityCube
|
||||
},
|
||||
ModAPI.util.str("Cube"),
|
||||
ModAPI.keygen.entity("cube"),
|
||||
0x000000, //egg base
|
||||
0x00FF00 //egg spots
|
||||
);
|
||||
ModAPI.mc.renderManager.entityRenderMap.put(ModAPI.util.asClass(nme_EntityCube), new nmcre_RenderCube(ModAPI.mc.renderManager.getRef()));
|
||||
|
||||
return {
|
||||
EntityCube: null,
|
||||
ModelCube: null,
|
||||
RenderCube: null
|
||||
EntityCube: nme_EntityCube,
|
||||
ModelCube: nmcm_ModelCube,
|
||||
RenderCube: nmcre_RenderCube,
|
||||
cubeTexture: cubeTextures
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,7 +93,9 @@
|
||||
var data = registerEntity();
|
||||
|
||||
ModAPI.addEventListener("lib:asyncsink", async () => {
|
||||
//ModAPI.mc.renderManager.entityRenderMap.put(ModAPI.util.asClass(wellGetThere), new data.RenderCube(ModAPI.mc.renderManager.getRef()))
|
||||
AsyncSink.L10N.set("entity.Cube.name", "Cube (TM)");
|
||||
AsyncSink.setFile("resourcepacks/AsyncSinkLib/assets/minecraft/textures/entity/cube.png", await (await fetch(
|
||||
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAAAQBJREFUeF7l0BFzAmAAgOGvKxgMgiAYDIJgEARBEASDQTAIgiAYBEEQBN0NBkEQBEEQBIMgCAZBEAwGgyAIgiAIgiConxE88PJ790RCCNdYCOGeRe/4j4SYDvCgAzzqAHEdIKEDJHWAJx3gWQdI6QBpHeBFB8joAFkdIKcD5HWAgg5Q1AFedYA3HaCkA7zrAGUdoKIDVHWAmg7woQPUdYCGDtDUAVo6QFsH6OgAnzrAlw7Q1QF6OkBfBxjoAEMdYKQDjHWAiQ7wrQNMdYCZDjDXAX50gIUOsNQBVjrArw7wpwP86wBrHWCjA2x1gJ0OsNcBDjrAUQc46QBnHeBiA9wALSueIjTE4PwAAAAASUVORK5CYII="
|
||||
)).arrayBuffer());
|
||||
});
|
||||
})();
|
@ -166,7 +166,7 @@ globalThis.modapi_postinit = "(" + (() => {
|
||||
return name;
|
||||
}
|
||||
|
||||
ModAPI.util.asClass = ModAPI.util.asClass = ModAPI.hooks._teavm.$rt_cls;
|
||||
ModAPI.util.asClass = ModAPI.hooks._teavm.$rt_cls;
|
||||
|
||||
ModAPI.util.wrap = function (outputValue, target, corrective, disableFunctions) {
|
||||
target ||= {};
|
||||
@ -413,7 +413,7 @@ globalThis.modapi_postinit = "(" + (() => {
|
||||
|
||||
//Magical function for making a subclass with a custom constructor that you can easily use super(...) on.
|
||||
ModAPI.reflect.getSuper = function getSuper(reflectClass, filter) {
|
||||
filter ||= () => true;
|
||||
filter ||= (x) => x.length === 1;
|
||||
var initialiser = reflectClass.internalConstructors.find(filter);
|
||||
return function superFunction(thisArg, ...extra_args) {
|
||||
reflectClass.class.call(thisArg);
|
||||
|
Loading…
x
Reference in New Issue
Block a user