Compare commits
No commits in common. "4fc7bc62aeba7b50b5f285d54d27f2c48adfdea6" and "c323f70a978047c310daa14cb36669743ca8207b" have entirely different histories.
4fc7bc62ae
...
c323f70a97
@ -11,7 +11,6 @@ Minecraft tech-oriented mod with science fiction style, about matter, and energy
|
|||||||
|
|
||||||
* [Ferrite Core](https://www.curseforge.com/minecraft/mc-mods/ferritecore), reduces memory usage
|
* [Ferrite Core](https://www.curseforge.com/minecraft/mc-mods/ferritecore), reduces memory usage
|
||||||
* In case of Overdrive That Matters, ***greatly*** reduces JVM heap bloat caused by model data being duplicated
|
* In case of Overdrive That Matters, ***greatly*** reduces JVM heap bloat caused by model data being duplicated
|
||||||
* Better Random
|
|
||||||
|
|
||||||
### Mods with special compatibility code
|
### Mods with special compatibility code
|
||||||
|
|
||||||
|
File diff suppressed because one or more lines are too long
@ -1 +0,0 @@
|
|||||||
{"meta":{"format_version":"4.10","model_format":"modded_entity","box_uv":true},"name":"missile","model_identifier":"","modded_entity_entity_class":"","modded_entity_version":"1.17","modded_entity_flip_y":true,"visible_box":[1,1,0],"variable_placeholders":"","variable_placeholder_buttons":[],"timeline_setups":[],"unhandled_root_fields":{},"resolution":{"width":32,"height":16},"elements":[{"name":"cube","box_uv":true,"rescale":false,"locked":false,"light_emission":0,"render_order":"default","allow_mirror_modeling":true,"from":[-2,0,-6],"to":[2,4,6],"autouv":0,"color":1,"origin":[0,0,0],"faces":{"north":{"uv":[12,12,16,16],"texture":0},"east":{"uv":[0,12,12,16],"texture":0},"south":{"uv":[28,12,32,16],"texture":0},"west":{"uv":[16,12,28,16],"texture":0},"up":{"uv":[16,12,12,0],"texture":0},"down":{"uv":[20,0,16,12],"texture":0}},"type":"cube","uuid":"05bb825d-c347-164b-64cf-b73e046e8741"}],"outliner":["05bb825d-c347-164b-64cf-b73e046e8741"],"textures":[{"path":"L:\\overdrive_that_matters\\src\\main\\resources\\assets\\overdrive_that_matters\\textures\\entity\\missile.png","name":"missile.png","folder":"block","namespace":"","id":"0","group":"","width":32,"height":16,"uv_width":32,"uv_height":16,"particle":false,"use_as_default":false,"layers_enabled":false,"sync_to_project":"","render_mode":"default","render_sides":"auto","pbr_channel":"color","frame_time":1,"frame_order_type":"loop","frame_order":"","frame_interpolate":false,"visible":true,"internal":true,"saved":true,"uuid":"46c03cb1-173a-a2a3-6e4d-ef2bed629caf","relative_path":"../main/resources/assets/overdrive_that_matters/textures/entity/missile.png","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAQCAYAAAB3AH1ZAAAAAXNSR0IArs4c6QAAAK9JREFUSEtjZCARBAUF/cenZd26dYykGEmSYpDBNjY2eB1w5MgRkswkSfGoA0AhEJ4gizcKVi54TFKokqR41AGjITAaAthCYIqUE0rJK9q2kKScxQgq21+9egU3RFrlId6ifMX8RwwRiXJgNchsXJqe3pGHS4mJiTEs61ZAUUqyA0ipaEBqsTmAXVodbMzPpzcZiHYALKhznu1jwMXG5jiqOQBkOHp8wywEOYrcKAAALrttKeKPrtQAAAAASUVORK5CYII="}]}
|
|
@ -127,7 +127,6 @@ fun addItemModels(provider: MatteryItemModelProvider) {
|
|||||||
|
|
||||||
provider.generated(MItems.BREAD_MONSTER_SPAWN_EGG, modLocation("item/egg/bread_monster"))
|
provider.generated(MItems.BREAD_MONSTER_SPAWN_EGG, modLocation("item/egg/bread_monster"))
|
||||||
provider.generated(MItems.LOADER_SPAWN_EGG, modLocation("item/egg/loader"))
|
provider.generated(MItems.LOADER_SPAWN_EGG, modLocation("item/egg/loader"))
|
||||||
provider.generated(MItems.CLEANER_DRONE_KIT, modLocation("item/egg/cleaner"))
|
|
||||||
provider.generated(MItems.ANDROID_MELEE_SPAWN_EGG, modLocation("item/egg/android_melee"))
|
provider.generated(MItems.ANDROID_MELEE_SPAWN_EGG, modLocation("item/egg/android_melee"))
|
||||||
|
|
||||||
provider.generatedTiered(MItems.BATTERIES, "battery_tier")
|
provider.generatedTiered(MItems.BATTERIES, "battery_tier")
|
||||||
|
@ -381,7 +381,7 @@ private fun misc(provider: MatteryLanguageProvider) {
|
|||||||
misc("pill.oblivion", "Items and Experience spent on research is fully refunded.")
|
misc("pill.oblivion", "Items and Experience spent on research is fully refunded.")
|
||||||
misc("pill.message_oblivion", "All android features are removed and all research refunded.")
|
misc("pill.message_oblivion", "All android features are removed and all research refunded.")
|
||||||
|
|
||||||
misc("pill.heal", "Provides 8 seconds of Regeneration III.")
|
misc("pill.heal", "Instantly restores 4 hearts upon ingestion, provides 2 min Absorption V and 8 seconds Regeneration III.")
|
||||||
misc("pill.heal_android", "Does nothing to androids.")
|
misc("pill.heal_android", "Does nothing to androids.")
|
||||||
|
|
||||||
misc("pill.not_normal", "Instantly kills fleshy creatures upon ingestion")
|
misc("pill.not_normal", "Instantly kills fleshy creatures upon ingestion")
|
||||||
@ -952,9 +952,6 @@ private fun items(provider: MatteryLanguageProvider) {
|
|||||||
add(MItems.LOADER_SPAWN_EGG, "Loader Spawn Egg")
|
add(MItems.LOADER_SPAWN_EGG, "Loader Spawn Egg")
|
||||||
add(MEntityTypes.LOADER, "Loader")
|
add(MEntityTypes.LOADER, "Loader")
|
||||||
|
|
||||||
add(MItems.CLEANER_DRONE_KIT, "Cleaner Drone Kit")
|
|
||||||
add(MEntityTypes.CLEANER, "Cleaner Drone")
|
|
||||||
|
|
||||||
add(MItems.ANDROID_MELEE_SPAWN_EGG, "Melee Android Spawn Egg")
|
add(MItems.ANDROID_MELEE_SPAWN_EGG, "Melee Android Spawn Egg")
|
||||||
add(MEntityTypes.ANDROID_MELEE, "Melee Android")
|
add(MEntityTypes.ANDROID_MELEE, "Melee Android")
|
||||||
}
|
}
|
||||||
|
@ -390,7 +390,7 @@ private fun misc(provider: MatteryLanguageProvider) {
|
|||||||
misc("pill.oblivion", "Предметы и Очки опыта, потраченные на исследования полностью возвращаются.")
|
misc("pill.oblivion", "Предметы и Очки опыта, потраченные на исследования полностью возвращаются.")
|
||||||
misc("pill.message_oblivion", "Все возможности андроида были удалены, а потраченные на исследования предметы и опыт возвращены.")
|
misc("pill.message_oblivion", "Все возможности андроида были удалены, а потраченные на исследования предметы и опыт возвращены.")
|
||||||
|
|
||||||
misc("pill.heal", "Даёт регенерацию III на 8 секунд.")
|
misc("pill.heal", "Мгновенно восполняет 4 сердца при употреблении, а так же даёт на 2 минуты поглощение V и на 8 секунд регенерацию III.")
|
||||||
misc("pill.heal_android", "Не действует на андроидов.")
|
misc("pill.heal_android", "Не действует на андроидов.")
|
||||||
|
|
||||||
misc("pill.not_normal", "Мгновенно убивает существ из плоти")
|
misc("pill.not_normal", "Мгновенно убивает существ из плоти")
|
||||||
@ -945,9 +945,6 @@ private fun items(provider: MatteryLanguageProvider) {
|
|||||||
add(MItems.LOADER_SPAWN_EGG, "Яйцо призыва погрузчика")
|
add(MItems.LOADER_SPAWN_EGG, "Яйцо призыва погрузчика")
|
||||||
add(MEntityTypes.LOADER, "Погрузчик")
|
add(MEntityTypes.LOADER, "Погрузчик")
|
||||||
|
|
||||||
add(MItems.CLEANER_DRONE_KIT, "Набор Дрона-уборщика")
|
|
||||||
add(MEntityTypes.CLEANER, "Дрон-уборщик")
|
|
||||||
|
|
||||||
add(MItems.ANDROID_MELEE_SPAWN_EGG, "Яйцо призыва андроида ближнего боя")
|
add(MItems.ANDROID_MELEE_SPAWN_EGG, "Яйцо призыва андроида ближнего боя")
|
||||||
add(MEntityTypes.ANDROID_MELEE, "Андроид ближнего боя")
|
add(MEntityTypes.ANDROID_MELEE, "Андроид ближнего боя")
|
||||||
}
|
}
|
||||||
|
@ -1,41 +0,0 @@
|
|||||||
package ru.dbotthepony.mc.otm.client.animation;
|
|
||||||
|
|
||||||
import net.minecraft.client.animation.AnimationChannel;
|
|
||||||
import net.minecraft.client.animation.AnimationDefinition;
|
|
||||||
import net.minecraft.client.animation.Keyframe;
|
|
||||||
import net.minecraft.client.animation.KeyframeAnimations;
|
|
||||||
|
|
||||||
public class EnforcerAnimation {
|
|
||||||
public static final AnimationDefinition CHARGE = AnimationDefinition.Builder.withLength(0.12F).looping()
|
|
||||||
.addAnimation("root", new AnimationChannel(AnimationChannel.Targets.POSITION,
|
|
||||||
new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, -1.0F, 0.0F), AnimationChannel.Interpolations.LINEAR),
|
|
||||||
new Keyframe(0.12F, KeyframeAnimations.posVec(0.0F, -1.1F, 0.0F), AnimationChannel.Interpolations.LINEAR)
|
|
||||||
))
|
|
||||||
.addAnimation("Body", new AnimationChannel(AnimationChannel.Targets.ROTATION,
|
|
||||||
new Keyframe(0.0F, KeyframeAnimations.degreeVec(7.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR)
|
|
||||||
))
|
|
||||||
.addAnimation("leg_FL", new AnimationChannel(AnimationChannel.Targets.ROTATION,
|
|
||||||
new Keyframe(0.0F, KeyframeAnimations.degreeVec(-0.0089F, 24.7408F, -0.0342F), AnimationChannel.Interpolations.LINEAR),
|
|
||||||
new Keyframe(0.12F, KeyframeAnimations.degreeVec(-0.8438F, 24.7408F, -0.0342F), AnimationChannel.Interpolations.LINEAR)
|
|
||||||
))
|
|
||||||
.addAnimation("leg_FR", new AnimationChannel(AnimationChannel.Targets.ROTATION,
|
|
||||||
new Keyframe(0.0F, KeyframeAnimations.degreeVec(-0.0452F, -24.7102F, -0.3574F), AnimationChannel.Interpolations.LINEAR),
|
|
||||||
new Keyframe(0.12F, KeyframeAnimations.degreeVec(-0.8765F, -24.7156F, -0.3213F), AnimationChannel.Interpolations.LINEAR)
|
|
||||||
))
|
|
||||||
.addAnimation("leg_BR", new AnimationChannel(AnimationChannel.Targets.ROTATION,
|
|
||||||
new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0089F, 24.7408F, 0.0342F), AnimationChannel.Interpolations.LINEAR),
|
|
||||||
new Keyframe(0.12F, KeyframeAnimations.degreeVec(0.9506F, 24.7408F, 0.0342F), AnimationChannel.Interpolations.LINEAR)
|
|
||||||
))
|
|
||||||
.addAnimation("leg_BL", new AnimationChannel(AnimationChannel.Targets.ROTATION,
|
|
||||||
new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0089F, -24.7408F, -0.0342F), AnimationChannel.Interpolations.LINEAR),
|
|
||||||
new Keyframe(0.12F, KeyframeAnimations.degreeVec(0.9506F, -24.7408F, -0.0342F), AnimationChannel.Interpolations.LINEAR)
|
|
||||||
))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
public static final AnimationDefinition IDLE = AnimationDefinition.Builder.withLength(0.12F).looping()
|
|
||||||
.addAnimation("Body", new AnimationChannel(AnimationChannel.Targets.POSITION,
|
|
||||||
new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR),
|
|
||||||
new Keyframe(0.12F, KeyframeAnimations.posVec(0.0F, -0.2F, 0.0F), AnimationChannel.Interpolations.LINEAR)
|
|
||||||
))
|
|
||||||
.build();
|
|
||||||
}
|
|
@ -1,133 +0,0 @@
|
|||||||
package ru.dbotthepony.mc.otm.client.model.entity;
|
|
||||||
|
|
||||||
import net.minecraft.client.model.HierarchicalModel;
|
|
||||||
import net.minecraft.client.model.geom.ModelLayerLocation;
|
|
||||||
import net.minecraft.client.model.geom.ModelPart;
|
|
||||||
import net.minecraft.client.model.geom.PartPose;
|
|
||||||
import net.minecraft.client.model.geom.builders.*;
|
|
||||||
import net.neoforged.neoforge.client.event.EntityRenderersEvent;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import ru.dbotthepony.mc.otm.client.animation.EnforcerAnimation;
|
|
||||||
import ru.dbotthepony.mc.otm.client.animation.LoaderAnimation;
|
|
||||||
import ru.dbotthepony.mc.otm.entity.Enforcer;
|
|
||||||
import ru.dbotthepony.mc.otm.registry.MNames;
|
|
||||||
|
|
||||||
import static ru.dbotthepony.mc.otm.OverdriveThatMatters.loc;
|
|
||||||
|
|
||||||
public class EnforcerModel {
|
|
||||||
public static final ModelLayerLocation LAYER_LOCATION = new ModelLayerLocation(loc(MNames.ENFORCER), "main");
|
|
||||||
|
|
||||||
private static HierarchicalModel<Enforcer> model;
|
|
||||||
private static LayerDefinition def;
|
|
||||||
|
|
||||||
public static HierarchicalModel<Enforcer> getModel() {
|
|
||||||
if (def == null) {
|
|
||||||
def = createBodyLayer();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (model == null) {
|
|
||||||
return model = new EnforcerHierarchicalModel<>(def.bakeRoot());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return model;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static LayerDefinition createBodyLayer() {
|
|
||||||
MeshDefinition meshdefinition = new MeshDefinition();
|
|
||||||
PartDefinition partdefinition = meshdefinition.getRoot();
|
|
||||||
|
|
||||||
PartDefinition root = partdefinition.addOrReplaceChild("root", CubeListBuilder.create(), PartPose.offset(0.0F, 24.0F, 0.0F));
|
|
||||||
|
|
||||||
PartDefinition base = root.addOrReplaceChild("base", CubeListBuilder.create().texOffs(140, 104).addBox(-8.0F, -4.0F, -7.0F, 16.0F, 5.0F, 14.0F, new CubeDeformation(0.0F))
|
|
||||||
.texOffs(92, 33).addBox(-5.0F, -2.0F, -10.0F, 10.0F, 14.0F, 20.0F, new CubeDeformation(0.0F))
|
|
||||||
.texOffs(70, 0).addBox(-8.0F, -1.0F, -11.0F, 3.0F, 3.0F, 2.0F, new CubeDeformation(0.0F))
|
|
||||||
.texOffs(70, 5).addBox(5.0F, -1.0F, -11.0F, 3.0F, 3.0F, 2.0F, new CubeDeformation(0.0F)), PartPose.offset(0.0F, -22.0F, 0.0F));
|
|
||||||
|
|
||||||
PartDefinition Body = base.addOrReplaceChild("Body", CubeListBuilder.create().texOffs(70, 0).addBox(-9.0F, -18.4F, -8.1F, 3.0F, 3.0F, 2.0F, new CubeDeformation(0.0F))
|
|
||||||
.texOffs(70, 5).addBox(-5.0F, -18.4F, -8.1F, 3.0F, 3.0F, 2.0F, new CubeDeformation(0.0F))
|
|
||||||
.texOffs(80, 76).addBox(-11.0F, -17.4F, 10.9F, 22.0F, 14.0F, 14.0F, new CubeDeformation(0.0F))
|
|
||||||
.texOffs(0, 0).addBox(-12.0F, -15.4F, -11.1F, 24.0F, 16.0F, 22.0F, new CubeDeformation(0.0F))
|
|
||||||
.texOffs(0, 38).addBox(-12.0F, -15.4F, -11.1F, 24.0F, 16.0F, 22.0F, new CubeDeformation(0.5F))
|
|
||||||
.texOffs(122, 168).addBox(12.0F, -13.4F, -6.1F, 2.0F, 12.0F, 12.0F, new CubeDeformation(0.0F))
|
|
||||||
.texOffs(150, 168).addBox(-14.0F, -13.4F, -6.1F, 2.0F, 12.0F, 12.0F, new CubeDeformation(0.0F))
|
|
||||||
.texOffs(140, 123).addBox(-7.0F, -2.0F, 10.0F, 15.0F, 5.0F, 5.0F, new CubeDeformation(0.0F)), PartPose.offset(0.0F, -4.6F, 0.1F));
|
|
||||||
|
|
||||||
PartDefinition cube_r1 = Body.addOrReplaceChild("cube_r1", CubeListBuilder.create().texOffs(178, 168).addBox(0.0F, -18.5F, -1.0F, 0.0F, 19.0F, 2.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(8.0F, -14.9F, 7.9F, -0.1745F, 0.0F, 0.0F));
|
|
||||||
|
|
||||||
PartDefinition Head = Body.addOrReplaceChild("Head", CubeListBuilder.create().texOffs(92, 67).addBox(-4.0F, -3.0F, -1.0F, 7.0F, 3.0F, 3.0F, new CubeDeformation(0.0F)), PartPose.offset(-4.0F, 1.6F, -11.1F));
|
|
||||||
|
|
||||||
PartDefinition rocket = Body.addOrReplaceChild("rocket", CubeListBuilder.create().texOffs(0, 76).addBox(-12.0F, -10.5F, -14.0F, 12.0F, 21.0F, 28.0F, new CubeDeformation(0.0F)), PartPose.offset(-14.0F, -7.9F, -0.1F));
|
|
||||||
|
|
||||||
PartDefinition flamethrower = Body.addOrReplaceChild("flamethrower", CubeListBuilder.create().texOffs(44, 168).addBox(-0.25F, -5.2654F, -4.9728F, 10.0F, 10.0F, 10.0F, new CubeDeformation(0.0F))
|
|
||||||
.texOffs(92, 0).addBox(2.75F, 1.7346F, -13.9728F, 10.0F, 10.0F, 23.0F, new CubeDeformation(0.0F))
|
|
||||||
.texOffs(84, 168).addBox(4.75F, 3.7346F, -26.9728F, 6.0F, 6.0F, 13.0F, new CubeDeformation(0.0F)), PartPose.offset(14.25F, -7.1346F, -0.1272F));
|
|
||||||
|
|
||||||
PartDefinition cube_r2 = flamethrower.addOrReplaceChild("cube_r2", CubeListBuilder.create().texOffs(152, 33).addBox(-4.0F, -4.0F, 0.5F, 8.0F, 8.0F, 15.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(7.75F, 5.7346F, 6.5272F, 0.5236F, 0.0F, 0.0F));
|
|
||||||
|
|
||||||
PartDefinition leg_FL = root.addOrReplaceChild("leg_FL", CubeListBuilder.create().texOffs(80, 104).addBox(-5.5F, -2.5F, -24.5F, 11.0F, 13.0F, 19.0F, new CubeDeformation(0.0F))
|
|
||||||
.texOffs(158, 0).addBox(-4.5F, -5.5F, -9.5F, 9.0F, 11.0F, 13.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(9.5F, -13.5F, -6.5F, 0.1571F, -0.5061F, -0.0349F));
|
|
||||||
|
|
||||||
PartDefinition leg_FR = root.addOrReplaceChild("leg_FR", CubeListBuilder.create().texOffs(0, 125).addBox(-5.5F, -2.5F, -24.5F, 11.0F, 13.0F, 19.0F, new CubeDeformation(0.0F))
|
|
||||||
.texOffs(152, 80).addBox(-4.5F, -5.5F, -9.5F, 9.0F, 11.0F, 13.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-9.5F, -13.5F, -6.5F, 0.1571F, 0.5061F, 0.0349F));
|
|
||||||
|
|
||||||
PartDefinition leg_BL = root.addOrReplaceChild("leg_BL", CubeListBuilder.create().texOffs(60, 136).addBox(-5.5F, -2.1667F, 5.1667F, 11.0F, 13.0F, 19.0F, new CubeDeformation(0.0F))
|
|
||||||
.texOffs(199, 24).addBox(-4.5F, -7.1667F, 13.1667F, 9.0F, 11.0F, 13.0F, new CubeDeformation(0.0F))
|
|
||||||
.texOffs(0, 157).addBox(-4.5F, -5.1667F, -3.8333F, 9.0F, 11.0F, 13.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(9.5F, -13.8333F, 6.8333F, -0.1571F, 0.5061F, -0.0349F));
|
|
||||||
|
|
||||||
PartDefinition leg_BR = root.addOrReplaceChild("leg_BR", CubeListBuilder.create().texOffs(152, 56).addBox(-4.5F, -5.1667F, -3.1667F, 9.0F, 11.0F, 13.0F, new CubeDeformation(0.0F))
|
|
||||||
.texOffs(120, 136).addBox(-5.5F, -2.1667F, 5.8333F, 11.0F, 13.0F, 19.0F, new CubeDeformation(0.0F))
|
|
||||||
.texOffs(202, 0).addBox(-4.5F, -7.1667F, 13.8333F, 9.0F, 11.0F, 13.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-9.5F, -13.8333F, 6.1667F, -0.1571F, -0.5061F, 0.0349F));
|
|
||||||
|
|
||||||
model = null;
|
|
||||||
return def = LayerDefinition.create(meshdefinition, 256, 256);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class EnforcerHierarchicalModel<T extends Enforcer> extends HierarchicalModel<T> {
|
|
||||||
private final ModelPart root;
|
|
||||||
private final ModelPart base;
|
|
||||||
private final ModelPart Body;
|
|
||||||
private final ModelPart Head;
|
|
||||||
private final ModelPart rocket;
|
|
||||||
private final ModelPart flamethrower;
|
|
||||||
public EnforcerHierarchicalModel(ModelPart root) {
|
|
||||||
this.root = root.getChild("root");
|
|
||||||
this.base = this.root.getChild("base");
|
|
||||||
this.Body = this.base.getChild("Body");
|
|
||||||
this.Head = this.Body.getChild("Head");
|
|
||||||
this.rocket = this.Body.getChild("rocket");
|
|
||||||
this.flamethrower = this.Body.getChild("flamethrower");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setupAnim(@NotNull T entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch) {
|
|
||||||
this.root().getAllParts().forEach(ModelPart::resetPose);
|
|
||||||
|
|
||||||
this.Body.getChild("Head").xRot = headPitch * ((float) Math.PI / 180F);
|
|
||||||
this.base.getChild("Body").yRot = netHeadYaw * ((float) Math.PI / 180F);
|
|
||||||
|
|
||||||
this.Body.getChild("rocket").xRot = headPitch * ((float) Math.PI / 180F);
|
|
||||||
this.Body.getChild("flamethrower").xRot = headPitch * ((float) Math.PI / 180F);
|
|
||||||
|
|
||||||
|
|
||||||
//this.animate(entity.getChargeState(), EnforcerAnimation.CHARGE, ageInTicks, 1.0F);
|
|
||||||
this.animateWalk(EnforcerAnimation.CHARGE, limbSwing, limbSwingAmount, 0.8F, 2.5F);
|
|
||||||
this.animate(entity.getIdleState(), EnforcerAnimation.IDLE, ageInTicks, 1.0F);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public ModelPart getHead() {
|
|
||||||
return this.Body.getChild("Head");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull ModelPart root() {
|
|
||||||
return this.root;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void register(EntityRenderersEvent.RegisterLayerDefinitions event) {
|
|
||||||
event.registerLayerDefinition(LAYER_LOCATION, EnforcerModel::createBodyLayer);
|
|
||||||
}
|
|
||||||
}
|
|
18
src/main/java/ru/dbotthepony/mc/otm/mixin/LevelMixin.java
Normal file
18
src/main/java/ru/dbotthepony/mc/otm/mixin/LevelMixin.java
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.mixin;
|
||||||
|
|
||||||
|
import net.minecraft.util.RandomSource;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import ru.dbotthepony.mc.otm.core.IMatteryLevel;
|
||||||
|
import ru.dbotthepony.mc.otm.core.util.GJRAND64RandomSource;
|
||||||
|
|
||||||
|
@Mixin(Level.class)
|
||||||
|
public abstract class LevelMixin implements IMatteryLevel {
|
||||||
|
public final RandomSource otm_random = new GJRAND64RandomSource();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull RandomSource getOtmRandom() {
|
||||||
|
return otm_random;
|
||||||
|
}
|
||||||
|
}
|
@ -8,6 +8,7 @@ import org.spongepowered.asm.mixin.injection.At;
|
|||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
import ru.dbotthepony.mc.otm.capability.IMatteryPlayer;
|
import ru.dbotthepony.mc.otm.capability.IMatteryPlayer;
|
||||||
|
import ru.dbotthepony.mc.otm.core.IMatteryLevel;
|
||||||
import ru.dbotthepony.mc.otm.registry.game.MSoundEvents;
|
import ru.dbotthepony.mc.otm.registry.game.MSoundEvents;
|
||||||
|
|
||||||
@Mixin(AbstractHurtingProjectile.class)
|
@Mixin(AbstractHurtingProjectile.class)
|
||||||
@ -24,7 +25,7 @@ public class MixinAbstractHurtingProjectile {
|
|||||||
AbstractHurtingProjectile proj = (AbstractHurtingProjectile)(Object)this;
|
AbstractHurtingProjectile proj = (AbstractHurtingProjectile)(Object)this;
|
||||||
|
|
||||||
if (cap.isAndroid() && proj.getOwner() != entity) {
|
if (cap.isAndroid() && proj.getOwner() != entity) {
|
||||||
entity.level().playSound(entity, proj.blockPosition(), MSoundEvents.INSTANCE.getANDROID_PROJ_PARRY(), SoundSource.PLAYERS, 1.0f, 0.95f + entity.level().getRandom().nextFloat() * 0.1f);
|
entity.level().playSound(entity, proj.blockPosition(), MSoundEvents.INSTANCE.getANDROID_PROJ_PARRY(), SoundSource.PLAYERS, 1.0f, 0.95f + ((IMatteryLevel) entity.level()).getOtmRandom().nextFloat() * 0.1f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ import ru.dbotthepony.mc.otm.core.math.rotateXDegrees
|
|||||||
import ru.dbotthepony.mc.otm.core.math.rotateYDegrees
|
import ru.dbotthepony.mc.otm.core.math.rotateYDegrees
|
||||||
import ru.dbotthepony.mc.otm.core.math.shortestDistanceBetween
|
import ru.dbotthepony.mc.otm.core.math.shortestDistanceBetween
|
||||||
import ru.dbotthepony.mc.otm.core.math.times
|
import ru.dbotthepony.mc.otm.core.math.times
|
||||||
import ru.dbotthepony.mc.otm.core.random
|
import ru.dbotthepony.mc.otm.core.otmRandom
|
||||||
import ru.dbotthepony.mc.otm.milliTime
|
import ru.dbotthepony.mc.otm.milliTime
|
||||||
import ru.dbotthepony.mc.otm.registry.game.AndroidFeatures
|
import ru.dbotthepony.mc.otm.registry.game.AndroidFeatures
|
||||||
import ru.dbotthepony.mc.otm.triggers.EnderTeleporterFallDeathTrigger
|
import ru.dbotthepony.mc.otm.triggers.EnderTeleporterFallDeathTrigger
|
||||||
@ -303,7 +303,7 @@ class EnderTeleporterFeature(capability: MatteryPlayer) : AndroidActiveFeature(A
|
|||||||
val event = EventHooks.onEnderTeleport(ply, blockPos.x + 0.5, blockPos.y.toDouble(), blockPos.z + 0.5)
|
val event = EventHooks.onEnderTeleport(ply, blockPos.x + 0.5, blockPos.y.toDouble(), blockPos.z + 0.5)
|
||||||
|
|
||||||
if (event.isCanceled) {
|
if (event.isCanceled) {
|
||||||
(ply as ServerPlayer).connection.send(ClientboundSoundEntityPacket(SoundEvents.ITEM_BREAK.holder, SoundSource.PLAYERS, ply, 0.3f, 0.5f, ply.level().random.nextLong()))
|
(ply as ServerPlayer).connection.send(ClientboundSoundEntityPacket(SoundEvents.ITEM_BREAK.holder, SoundSource.PLAYERS, ply, 0.3f, 0.5f, ply.level().otmRandom.nextLong()))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -311,9 +311,9 @@ class EnderTeleporterFeature(capability: MatteryPlayer) : AndroidActiveFeature(A
|
|||||||
lastTeleport = ply.server!!.tickCount
|
lastTeleport = ply.server!!.tickCount
|
||||||
android.androidEnergy.extractEnergy(AndroidConfig.EnderTeleporter.ENERGY_COST, false)
|
android.androidEnergy.extractEnergy(AndroidConfig.EnderTeleporter.ENERGY_COST, false)
|
||||||
|
|
||||||
ply.level().playSound(null, ply, SoundEvents.ENDERMAN_TELEPORT, SoundSource.PLAYERS, 0.3f, 0.8f + ply.level().random.nextFloat() * 0.4f)
|
ply.level().playSound(null, ply, SoundEvents.ENDERMAN_TELEPORT, SoundSource.PLAYERS, 0.3f, 0.8f + ply.level().otmRandom.nextFloat() * 0.4f)
|
||||||
ply.teleportTo(event.targetX, event.targetY, event.targetZ)
|
ply.teleportTo(event.targetX, event.targetY, event.targetZ)
|
||||||
ply.level().playSound(null, ply, SoundEvents.ENDERMAN_TELEPORT, SoundSource.PLAYERS, 1f, 0.8f + ply.level().random.nextFloat() * 0.4f)
|
ply.level().playSound(null, ply, SoundEvents.ENDERMAN_TELEPORT, SoundSource.PLAYERS, 1f, 0.8f + ply.level().otmRandom.nextFloat() * 0.4f)
|
||||||
|
|
||||||
ply.deltaMovement = Vector(0.0, 0.0, 0.0)
|
ply.deltaMovement = Vector(0.0, 0.0, 0.0)
|
||||||
ply.resetFallDistance()
|
ply.resetFallDistance()
|
||||||
|
@ -46,7 +46,7 @@ import ru.dbotthepony.mc.otm.core.math.getSphericalBlockPositions
|
|||||||
import ru.dbotthepony.mc.otm.core.math.times
|
import ru.dbotthepony.mc.otm.core.math.times
|
||||||
import ru.dbotthepony.mc.otm.core.nbt.map
|
import ru.dbotthepony.mc.otm.core.nbt.map
|
||||||
import ru.dbotthepony.mc.otm.core.nbt.set
|
import ru.dbotthepony.mc.otm.core.nbt.set
|
||||||
import ru.dbotthepony.mc.otm.core.random
|
import ru.dbotthepony.mc.otm.core.otmRandom
|
||||||
import ru.dbotthepony.mc.otm.isClient
|
import ru.dbotthepony.mc.otm.isClient
|
||||||
import ru.dbotthepony.mc.otm.matter.MatterManager
|
import ru.dbotthepony.mc.otm.matter.MatterManager
|
||||||
import ru.dbotthepony.mc.otm.registry.MDamageTypes
|
import ru.dbotthepony.mc.otm.registry.MDamageTypes
|
||||||
@ -298,7 +298,7 @@ class BlackHoleBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mattery
|
|||||||
}
|
}
|
||||||
|
|
||||||
// шанс 1% что черная дыра потеряет 0.1 MtU каждую секунду * силу гравитации дыры ^ -1
|
// шанс 1% что черная дыра потеряет 0.1 MtU каждую секунду * силу гравитации дыры ^ -1
|
||||||
if (level.random.nextDouble() < 0.01 * 0.05 * (1 / gravitationStrength)) {
|
if (level.otmRandom.nextDouble() < 0.01 * 0.05 * (1 / gravitationStrength)) {
|
||||||
this.mass += HAWKING_MASS_LOSE_STEP
|
this.mass += HAWKING_MASS_LOSE_STEP
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ import ru.dbotthepony.mc.otm.core.math.times
|
|||||||
import ru.dbotthepony.mc.otm.core.multiblock.BlockEntityTag
|
import ru.dbotthepony.mc.otm.core.multiblock.BlockEntityTag
|
||||||
import ru.dbotthepony.mc.otm.core.multiblock.MultiblockStatus
|
import ru.dbotthepony.mc.otm.core.multiblock.MultiblockStatus
|
||||||
import ru.dbotthepony.mc.otm.core.multiblock.shapedMultiblock
|
import ru.dbotthepony.mc.otm.core.multiblock.shapedMultiblock
|
||||||
import ru.dbotthepony.mc.otm.core.random
|
import ru.dbotthepony.mc.otm.core.otmRandom
|
||||||
import ru.dbotthepony.mc.otm.core.util.InvalidableLazy
|
import ru.dbotthepony.mc.otm.core.util.InvalidableLazy
|
||||||
import ru.dbotthepony.mc.otm.menu.tech.BlackHoleGeneratorMenu
|
import ru.dbotthepony.mc.otm.menu.tech.BlackHoleGeneratorMenu
|
||||||
import ru.dbotthepony.mc.otm.registry.game.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.game.MBlockEntities
|
||||||
@ -86,8 +86,8 @@ class BlackHoleGeneratorBlockEntity(blockPos: BlockPos, blockState: BlockState)
|
|||||||
multiblock?.blockEntities(MatterHatchBlockEntity.INPUT_TAG)?.iterator()?.map { it.matter }?.toList() ?: listOf()
|
multiblock?.blockEntities(MatterHatchBlockEntity.INPUT_TAG)?.iterator()?.map { it.matter }?.toList() ?: listOf()
|
||||||
}
|
}
|
||||||
|
|
||||||
val energy = CombinedProfiledEnergyStorage(FlowDirection.NONE, energyTarget::value, { level?.random })
|
val energy = CombinedProfiledEnergyStorage(FlowDirection.NONE, energyTarget::value, { level?.otmRandom })
|
||||||
val matter = CombinedProfiledMatterStorage(FlowDirection.NONE, matterTarget::value, { level?.random })
|
val matter = CombinedProfiledMatterStorage(FlowDirection.NONE, matterTarget::value, { level?.otmRandom })
|
||||||
|
|
||||||
enum class Mode(val label: Component, val tooltip: Component) {
|
enum class Mode(val label: Component, val tooltip: Component) {
|
||||||
TARGET_MASS(TranslatableComponent("otm.gui.black_hole_generator.sustain.mode"), TranslatableComponent("otm.gui.black_hole_generator.sustain.desc")),
|
TARGET_MASS(TranslatableComponent("otm.gui.black_hole_generator.sustain.mode"), TranslatableComponent("otm.gui.black_hole_generator.sustain.desc")),
|
||||||
|
@ -14,7 +14,7 @@ import ru.dbotthepony.mc.otm.core.collect.map
|
|||||||
import ru.dbotthepony.mc.otm.core.collect.reduce
|
import ru.dbotthepony.mc.otm.core.collect.reduce
|
||||||
import ru.dbotthepony.mc.otm.core.math.Decimal
|
import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||||
import ru.dbotthepony.mc.otm.core.math.RelativeSide
|
import ru.dbotthepony.mc.otm.core.math.RelativeSide
|
||||||
import ru.dbotthepony.mc.otm.core.random
|
import ru.dbotthepony.mc.otm.core.otmRandom
|
||||||
import ru.dbotthepony.mc.otm.core.shuffle
|
import ru.dbotthepony.mc.otm.core.shuffle
|
||||||
import ru.dbotthepony.mc.otm.graph.GraphNodeList
|
import ru.dbotthepony.mc.otm.graph.GraphNodeList
|
||||||
import ru.dbotthepony.mc.otm.onceServer
|
import ru.dbotthepony.mc.otm.onceServer
|
||||||
@ -627,7 +627,7 @@ class EnergyCableGraph : GraphNodeList<EnergyCableBlockEntity.Node, EnergyCableG
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun receiveEnergy(howMuch: Decimal, simulate: Boolean, fromNode: EnergyCableBlockEntity.Node, fromSide: RelativeSide): Decimal {
|
fun receiveEnergy(howMuch: Decimal, simulate: Boolean, fromNode: EnergyCableBlockEntity.Node, fromSide: RelativeSide): Decimal {
|
||||||
livelyNodesList.shuffle(fromNode.blockEntity.level!!.random)
|
livelyNodesList.shuffle(fromNode.blockEntity.level!!.otmRandom)
|
||||||
|
|
||||||
val itr = livelyNodesList.iterator()
|
val itr = livelyNodesList.iterator()
|
||||||
var received = Decimal.ZERO
|
var received = Decimal.ZERO
|
||||||
|
@ -32,7 +32,7 @@ import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity
|
|||||||
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||||
import ru.dbotthepony.mc.otm.container.HandlerFilter
|
import ru.dbotthepony.mc.otm.container.HandlerFilter
|
||||||
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||||
import ru.dbotthepony.mc.otm.core.random
|
import ru.dbotthepony.mc.otm.core.otmRandom
|
||||||
import ru.dbotthepony.mc.otm.menu.decorative.CargoCrateMenu
|
import ru.dbotthepony.mc.otm.menu.decorative.CargoCrateMenu
|
||||||
import ru.dbotthepony.mc.otm.registry.game.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.game.MBlockEntities
|
||||||
import ru.dbotthepony.mc.otm.registry.game.MSoundEvents
|
import ru.dbotthepony.mc.otm.registry.game.MSoundEvents
|
||||||
@ -71,7 +71,7 @@ class CargoCrateBlockEntity(
|
|||||||
|
|
||||||
if (interactingPlayers++ == 0 && level != null && !isRemoved && level.getBlockState(blockPos).block is CargoCrateBlock) {
|
if (interactingPlayers++ == 0 && level != null && !isRemoved && level.getBlockState(blockPos).block is CargoCrateBlock) {
|
||||||
level.setBlock(blockPos, blockState.setValue(CargoCrateBlock.IS_OPEN, true), Block.UPDATE_CLIENTS)
|
level.setBlock(blockPos, blockState.setValue(CargoCrateBlock.IS_OPEN, true), Block.UPDATE_CLIENTS)
|
||||||
level.playSound(null, blockPos, MSoundEvents.CARGO_CRATE_OPEN, SoundSource.BLOCKS, 1f, 0.8f + level.random.nextFloat() * 0.2f)
|
level.playSound(null, blockPos, MSoundEvents.CARGO_CRATE_OPEN, SoundSource.BLOCKS, 1f, 0.8f + level.otmRandom.nextFloat() * 0.2f)
|
||||||
level.gameEvent(GameEvent.CONTAINER_OPEN, blockPos, GameEvent.Context.of(blockState))
|
level.gameEvent(GameEvent.CONTAINER_OPEN, blockPos, GameEvent.Context.of(blockState))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ import ru.dbotthepony.mc.otm.config.MachinesConfig
|
|||||||
import ru.dbotthepony.mc.otm.container.HandlerFilter
|
import ru.dbotthepony.mc.otm.container.HandlerFilter
|
||||||
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||||
import ru.dbotthepony.mc.otm.core.math.Decimal
|
import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||||
import ru.dbotthepony.mc.otm.core.random
|
import ru.dbotthepony.mc.otm.core.otmRandom
|
||||||
import ru.dbotthepony.mc.otm.data.codec.DecimalCodec
|
import ru.dbotthepony.mc.otm.data.codec.DecimalCodec
|
||||||
import ru.dbotthepony.mc.otm.data.codec.minRange
|
import ru.dbotthepony.mc.otm.data.codec.minRange
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.SimpleMatterNode
|
import ru.dbotthepony.mc.otm.graph.matter.SimpleMatterNode
|
||||||
@ -126,7 +126,7 @@ class MatterDecomposerBlockEntity(pos: BlockPos, state: BlockState)
|
|||||||
|
|
||||||
return JobContainer.success(
|
return JobContainer.success(
|
||||||
DecomposerJob(
|
DecomposerJob(
|
||||||
(level?.random?.nextDouble() ?: 1.0) <= 0.2 * upgrades.failureMultiplier,
|
(level?.otmRandom?.nextDouble() ?: 1.0) <= 0.2 * upgrades.failureMultiplier,
|
||||||
matter.matter,
|
matter.matter,
|
||||||
matter.complexity * MachinesConfig.MATTER_DECOMPOSER.workTimeMultiplier
|
matter.complexity * MachinesConfig.MATTER_DECOMPOSER.workTimeMultiplier
|
||||||
)
|
)
|
||||||
|
@ -28,7 +28,7 @@ import ru.dbotthepony.mc.otm.container.HandlerFilter
|
|||||||
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||||
import ru.dbotthepony.mc.otm.container.UpgradeContainer
|
import ru.dbotthepony.mc.otm.container.UpgradeContainer
|
||||||
import ru.dbotthepony.mc.otm.core.math.Decimal
|
import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||||
import ru.dbotthepony.mc.otm.core.random
|
import ru.dbotthepony.mc.otm.core.otmRandom
|
||||||
import ru.dbotthepony.mc.otm.core.registryName
|
import ru.dbotthepony.mc.otm.core.registryName
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.MatterNode
|
import ru.dbotthepony.mc.otm.graph.matter.MatterNode
|
||||||
import ru.dbotthepony.mc.otm.matter.IMatterValue
|
import ru.dbotthepony.mc.otm.matter.IMatterValue
|
||||||
@ -264,7 +264,7 @@ class MatterReconstructorBlockEntity(blockPos: BlockPos, blockState: BlockState)
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (failureChance * upgrades.failureMultiplier <= 0.0 || level!!.random.nextDouble() >= failureChance * upgrades.failureMultiplier)
|
if (failureChance * upgrades.failureMultiplier <= 0.0 || level!!.otmRandom.nextDouble() >= failureChance * upgrades.failureMultiplier)
|
||||||
repairProgress += progressPerTick
|
repairProgress += progressPerTick
|
||||||
|
|
||||||
energy.extractEnergy(energyConsumption * (progressPerTick / thisProgressPerTick), false)
|
energy.extractEnergy(energyConsumption * (progressPerTick / thisProgressPerTick), false)
|
||||||
|
@ -24,7 +24,7 @@ import ru.dbotthepony.mc.otm.config.MachinesConfig
|
|||||||
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||||
import ru.dbotthepony.mc.otm.container.HandlerFilter
|
import ru.dbotthepony.mc.otm.container.HandlerFilter
|
||||||
import ru.dbotthepony.mc.otm.core.math.Decimal
|
import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||||
import ru.dbotthepony.mc.otm.core.random
|
import ru.dbotthepony.mc.otm.core.otmRandom
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.MatterGraph
|
import ru.dbotthepony.mc.otm.graph.matter.MatterGraph
|
||||||
import ru.dbotthepony.mc.otm.item.matter.MatterDustItem
|
import ru.dbotthepony.mc.otm.item.matter.MatterDustItem
|
||||||
import ru.dbotthepony.mc.otm.menu.matter.MatterRecyclerMenu
|
import ru.dbotthepony.mc.otm.menu.matter.MatterRecyclerMenu
|
||||||
@ -117,7 +117,7 @@ class MatterRecyclerBlockEntity(blockPos: BlockPos, blockState: BlockState)
|
|||||||
stack.shrink(1)
|
stack.shrink(1)
|
||||||
container.setChanged(0)
|
container.setChanged(0)
|
||||||
|
|
||||||
val actualMatter = dustMatter.matter * (0.4 + level!!.random.nextDouble() * 0.6)
|
val actualMatter = dustMatter.matter * (0.4 + level!!.otmRandom.nextDouble() * 0.6)
|
||||||
|
|
||||||
return JobContainer.success(
|
return JobContainer.success(
|
||||||
RecyclerJob(
|
RecyclerJob(
|
||||||
|
@ -28,7 +28,7 @@ import ru.dbotthepony.mc.otm.config.MachinesConfig
|
|||||||
import ru.dbotthepony.mc.otm.container.HandlerFilter
|
import ru.dbotthepony.mc.otm.container.HandlerFilter
|
||||||
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||||
import ru.dbotthepony.mc.otm.core.math.Decimal
|
import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||||
import ru.dbotthepony.mc.otm.core.random
|
import ru.dbotthepony.mc.otm.core.otmRandom
|
||||||
import ru.dbotthepony.mc.otm.data.codec.DecimalCodec
|
import ru.dbotthepony.mc.otm.data.codec.DecimalCodec
|
||||||
import ru.dbotthepony.mc.otm.data.codec.minRange
|
import ru.dbotthepony.mc.otm.data.codec.minRange
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.MatterNode
|
import ru.dbotthepony.mc.otm.graph.matter.MatterNode
|
||||||
@ -184,7 +184,7 @@ class MatterReplicatorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
task = allocation.task.id,
|
task = allocation.task.id,
|
||||||
matterValue = matter.matter,
|
matterValue = matter.matter,
|
||||||
pattern = Optional.ofNullable(allocation.pattern),
|
pattern = Optional.ofNullable(allocation.pattern),
|
||||||
asDust = (level?.random?.nextDouble() ?: 1.0) * upgrades.failureMultiplier > (allocation.pattern?.researchPercent ?: 2.0),
|
asDust = (level?.otmRandom?.nextDouble() ?: 1.0) * upgrades.failureMultiplier > (allocation.pattern?.researchPercent ?: 2.0),
|
||||||
ticks = ticks,
|
ticks = ticks,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ import ru.dbotthepony.mc.otm.container.balance
|
|||||||
import ru.dbotthepony.mc.otm.core.collect.filter
|
import ru.dbotthepony.mc.otm.core.collect.filter
|
||||||
import ru.dbotthepony.mc.otm.core.collect.maybe
|
import ru.dbotthepony.mc.otm.core.collect.maybe
|
||||||
import ru.dbotthepony.mc.otm.core.immutableList
|
import ru.dbotthepony.mc.otm.core.immutableList
|
||||||
import ru.dbotthepony.mc.otm.core.random
|
import ru.dbotthepony.mc.otm.core.otmRandom
|
||||||
import ru.dbotthepony.mc.otm.menu.tech.PoweredFurnaceMenu
|
import ru.dbotthepony.mc.otm.menu.tech.PoweredFurnaceMenu
|
||||||
import ru.dbotthepony.mc.otm.recipe.MatteryCookingRecipe
|
import ru.dbotthepony.mc.otm.recipe.MatteryCookingRecipe
|
||||||
import ru.dbotthepony.mc.otm.recipe.MicrowaveRecipe
|
import ru.dbotthepony.mc.otm.recipe.MicrowaveRecipe
|
||||||
@ -153,7 +153,7 @@ sealed class AbstractPoweredFurnaceBlockEntity<P : AbstractCookingRecipe, S : Ma
|
|||||||
recipe.getResultItem(level.registryAccess()).copyWithCount(toProcess),
|
recipe.getResultItem(level.registryAccess()).copyWithCount(toProcess),
|
||||||
recipe.workTime * config.workTimeMultiplier,
|
recipe.workTime * config.workTimeMultiplier,
|
||||||
config.energyConsumption * toProcess,
|
config.energyConsumption * toProcess,
|
||||||
experience = recipe.experience.sample(level.random) * toProcess))
|
experience = recipe.experience.sample(level.otmRandom) * toProcess))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ import ru.dbotthepony.mc.otm.capability.energy.WorkerEnergyStorage
|
|||||||
import ru.dbotthepony.mc.otm.capability.matteryPlayer
|
import ru.dbotthepony.mc.otm.capability.matteryPlayer
|
||||||
import ru.dbotthepony.mc.otm.config.MachinesConfig
|
import ru.dbotthepony.mc.otm.config.MachinesConfig
|
||||||
import ru.dbotthepony.mc.otm.core.getEntitiesInEllipsoid
|
import ru.dbotthepony.mc.otm.core.getEntitiesInEllipsoid
|
||||||
import ru.dbotthepony.mc.otm.core.random
|
import ru.dbotthepony.mc.otm.core.otmRandom
|
||||||
import ru.dbotthepony.mc.otm.core.shuffle
|
import ru.dbotthepony.mc.otm.core.shuffle
|
||||||
import ru.dbotthepony.mc.otm.menu.tech.AndroidChargerMenu
|
import ru.dbotthepony.mc.otm.menu.tech.AndroidChargerMenu
|
||||||
import ru.dbotthepony.mc.otm.registry.game.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.game.MBlockEntities
|
||||||
@ -58,7 +58,7 @@ class AndroidChargerBlockEntity(blockPos: BlockPos, blockState: BlockState) : Ma
|
|||||||
|
|
||||||
val ents = level.getEntitiesInEllipsoid(blockPos.center, Vec3(MachinesConfig.AndroidCharger.RADIUS_WIDTH, MachinesConfig.AndroidCharger.RADIUS_HEIGHT, MachinesConfig.AndroidCharger.RADIUS_WIDTH)) { it is Player }
|
val ents = level.getEntitiesInEllipsoid(blockPos.center, Vec3(MachinesConfig.AndroidCharger.RADIUS_WIDTH, MachinesConfig.AndroidCharger.RADIUS_HEIGHT, MachinesConfig.AndroidCharger.RADIUS_WIDTH)) { it is Player }
|
||||||
|
|
||||||
ents.shuffle(level.random)
|
ents.shuffle(level.otmRandom)
|
||||||
|
|
||||||
for ((ent) in ents) {
|
for ((ent) in ents) {
|
||||||
val ply = (ent as Player).matteryPlayer
|
val ply = (ent as Player).matteryPlayer
|
||||||
|
@ -17,7 +17,7 @@ import ru.dbotthepony.mc.otm.capability.matteryPlayer
|
|||||||
import ru.dbotthepony.mc.otm.capability.moveEnergy
|
import ru.dbotthepony.mc.otm.capability.moveEnergy
|
||||||
import ru.dbotthepony.mc.otm.config.MachinesConfig
|
import ru.dbotthepony.mc.otm.config.MachinesConfig
|
||||||
import ru.dbotthepony.mc.otm.core.math.Decimal
|
import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||||
import ru.dbotthepony.mc.otm.core.random
|
import ru.dbotthepony.mc.otm.core.otmRandom
|
||||||
import ru.dbotthepony.mc.otm.core.shuffle
|
import ru.dbotthepony.mc.otm.core.shuffle
|
||||||
import ru.dbotthepony.mc.otm.core.util.countingLazy
|
import ru.dbotthepony.mc.otm.core.util.countingLazy
|
||||||
import ru.dbotthepony.mc.otm.menu.tech.AndroidStationMenu
|
import ru.dbotthepony.mc.otm.menu.tech.AndroidStationMenu
|
||||||
@ -90,7 +90,7 @@ class AndroidStationBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Ma
|
|||||||
val y = blockPos.y.toDouble()
|
val y = blockPos.y.toDouble()
|
||||||
val z = blockPos.z.toDouble()
|
val z = blockPos.z.toDouble()
|
||||||
|
|
||||||
for (ent in level.getEntitiesOfClass(ServerPlayer::class.java, AABB(x, y, z, x + 1.0, y + 2.0, z + 1.0)).shuffle(level.random)) {
|
for (ent in level.getEntitiesOfClass(ServerPlayer::class.java, AABB(x, y, z, x + 1.0, y + 2.0, z + 1.0)).shuffle(level.otmRandom)) {
|
||||||
if (ent.matteryPlayer.isAndroid)
|
if (ent.matteryPlayer.isAndroid)
|
||||||
moveEnergy(energy, ent.matteryPlayer.androidEnergy, amount = energy.batteryLevel, simulate = false, ignoreFlowRestrictions = true)
|
moveEnergy(energy, ent.matteryPlayer.androidEnergy, amount = energy.batteryLevel, simulate = false, ignoreFlowRestrictions = true)
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ import ru.dbotthepony.mc.otm.container.HandlerFilter
|
|||||||
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||||
import ru.dbotthepony.mc.otm.core.immutableList
|
import ru.dbotthepony.mc.otm.core.immutableList
|
||||||
import ru.dbotthepony.mc.otm.core.math.Decimal
|
import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||||
import ru.dbotthepony.mc.otm.core.random
|
import ru.dbotthepony.mc.otm.core.otmRandom
|
||||||
import ru.dbotthepony.mc.otm.core.shuffle
|
import ru.dbotthepony.mc.otm.core.shuffle
|
||||||
import ru.dbotthepony.mc.otm.menu.tech.BatteryBankMenu
|
import ru.dbotthepony.mc.otm.menu.tech.BatteryBankMenu
|
||||||
import ru.dbotthepony.mc.otm.registry.game.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.game.MBlockEntities
|
||||||
@ -60,7 +60,7 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
|
|||||||
if (!howMuch.isPositive)
|
if (!howMuch.isPositive)
|
||||||
return Decimal.ZERO
|
return Decimal.ZERO
|
||||||
|
|
||||||
containerSlotIndices.shuffle(level!!.random)
|
containerSlotIndices.shuffle(level!!.otmRandom)
|
||||||
var summ = Decimal.ZERO
|
var summ = Decimal.ZERO
|
||||||
var remaining = howMuch
|
var remaining = howMuch
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ import ru.dbotthepony.mc.otm.core.math.RelativeSide
|
|||||||
import ru.dbotthepony.mc.otm.core.multiblock.BlockEntityTag
|
import ru.dbotthepony.mc.otm.core.multiblock.BlockEntityTag
|
||||||
import ru.dbotthepony.mc.otm.core.multiblock.IMultiblockAccess
|
import ru.dbotthepony.mc.otm.core.multiblock.IMultiblockAccess
|
||||||
import ru.dbotthepony.mc.otm.core.multiblock.IMultiblockListener
|
import ru.dbotthepony.mc.otm.core.multiblock.IMultiblockListener
|
||||||
import ru.dbotthepony.mc.otm.core.random
|
import ru.dbotthepony.mc.otm.core.otmRandom
|
||||||
import ru.dbotthepony.mc.otm.core.util.InvalidableLazy
|
import ru.dbotthepony.mc.otm.core.util.InvalidableLazy
|
||||||
import ru.dbotthepony.mc.otm.registry.game.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.game.MBlockEntities
|
||||||
|
|
||||||
@ -43,7 +43,7 @@ class EnergyInterfaceBlockEntity(
|
|||||||
multiblocks.keys.iterator().flatMap { it.blockEntities(TARGET).iterator() }.map { it.energyInterfaceTarget }.toList()
|
multiblocks.keys.iterator().flatMap { it.blockEntities(TARGET).iterator() }.map { it.energyInterfaceTarget }.toList()
|
||||||
}
|
}
|
||||||
|
|
||||||
val energy = CombinedProfiledEnergyStorage(FlowDirection.input(isInput), targets::value, { level?.random })
|
val energy = CombinedProfiledEnergyStorage(FlowDirection.input(isInput), targets::value, { level?.otmRandom })
|
||||||
|
|
||||||
override fun onAddedToMultiblock(multiblock: IMultiblockAccess) {
|
override fun onAddedToMultiblock(multiblock: IMultiblockAccess) {
|
||||||
check(!isRemoved) { "Block was removed" }
|
check(!isRemoved) { "Block was removed" }
|
||||||
|
@ -28,7 +28,7 @@ import ru.dbotthepony.mc.otm.container.MatteryContainer
|
|||||||
import ru.dbotthepony.mc.otm.core.getEntitiesInEllipsoid
|
import ru.dbotthepony.mc.otm.core.getEntitiesInEllipsoid
|
||||||
import ru.dbotthepony.mc.otm.core.lookupOrThrow
|
import ru.dbotthepony.mc.otm.core.lookupOrThrow
|
||||||
import ru.dbotthepony.mc.otm.core.math.Vector
|
import ru.dbotthepony.mc.otm.core.math.Vector
|
||||||
import ru.dbotthepony.mc.otm.core.random
|
import ru.dbotthepony.mc.otm.core.otmRandom
|
||||||
import ru.dbotthepony.mc.otm.core.util.countingLazy
|
import ru.dbotthepony.mc.otm.core.util.countingLazy
|
||||||
import ru.dbotthepony.mc.otm.item.consumables.EssenceCapsuleItem
|
import ru.dbotthepony.mc.otm.item.consumables.EssenceCapsuleItem
|
||||||
import ru.dbotthepony.mc.otm.item.EssenceServoItem
|
import ru.dbotthepony.mc.otm.item.EssenceServoItem
|
||||||
@ -173,7 +173,7 @@ class EssenceStorageBlockEntity(blockPos: BlockPos, blockState: BlockState) : Ma
|
|||||||
|
|
||||||
val diff = dmgPerExp - repairPoints.toFloat()
|
val diff = dmgPerExp - repairPoints.toFloat()
|
||||||
if (diff > 0f) {
|
if (diff > 0f) {
|
||||||
repairPoints += if ((level?.random?.nextFloat() ?: 1f) <= diff) 1 else 0
|
repairPoints += if ((level?.otmRandom?.nextFloat() ?: 1f) <= diff) 1 else 0
|
||||||
}
|
}
|
||||||
|
|
||||||
experienceStored -= 1
|
experienceStored -= 1
|
||||||
@ -202,7 +202,7 @@ class EssenceStorageBlockEntity(blockPos: BlockPos, blockState: BlockState) : Ma
|
|||||||
|
|
||||||
level!!.playSound(null, ent.x, ent.y, ent.z,
|
level!!.playSound(null, ent.x, ent.y, ent.z,
|
||||||
SoundEvents.EXPERIENCE_ORB_PICKUP, SoundSource.BLOCKS,
|
SoundEvents.EXPERIENCE_ORB_PICKUP, SoundSource.BLOCKS,
|
||||||
0.1F, 0.5F + level!!.random.nextFloat() * 0.25F
|
0.1F, 0.5F + level!!.otmRandom.nextFloat() * 0.25F
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ import ru.dbotthepony.mc.otm.container.HandlerFilter
|
|||||||
import ru.dbotthepony.mc.otm.container.balance
|
import ru.dbotthepony.mc.otm.container.balance
|
||||||
import ru.dbotthepony.mc.otm.core.collect.filter
|
import ru.dbotthepony.mc.otm.core.collect.filter
|
||||||
import ru.dbotthepony.mc.otm.core.collect.maybe
|
import ru.dbotthepony.mc.otm.core.collect.maybe
|
||||||
import ru.dbotthepony.mc.otm.core.random
|
import ru.dbotthepony.mc.otm.core.otmRandom
|
||||||
import ru.dbotthepony.mc.otm.menu.tech.PlatePressMenu
|
import ru.dbotthepony.mc.otm.menu.tech.PlatePressMenu
|
||||||
import ru.dbotthepony.mc.otm.registry.game.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.game.MBlockEntities
|
||||||
import ru.dbotthepony.mc.otm.registry.game.MRecipes
|
import ru.dbotthepony.mc.otm.registry.game.MRecipes
|
||||||
@ -90,7 +90,7 @@ class PlatePressBlockEntity(
|
|||||||
recipe.getResultItem(level.registryAccess()).copyWithCount(toProcess),
|
recipe.getResultItem(level.registryAccess()).copyWithCount(toProcess),
|
||||||
recipe.workTime * MachinesConfig.PLATE_PRESS.workTimeMultiplier,
|
recipe.workTime * MachinesConfig.PLATE_PRESS.workTimeMultiplier,
|
||||||
MachinesConfig.PLATE_PRESS.energyConsumption * toProcess,
|
MachinesConfig.PLATE_PRESS.energyConsumption * toProcess,
|
||||||
experience = recipe.experience.sample(level.random) * toProcess))
|
experience = recipe.experience.sample(level.otmRandom) * toProcess))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun tick() {
|
override fun tick() {
|
||||||
|
@ -532,7 +532,7 @@ class MatteryPlayer(val ply: Player) {
|
|||||||
override fun onJobTick(status: JobStatus<ItemJob>) {
|
override fun onJobTick(status: JobStatus<ItemJob>) {
|
||||||
super.onJobTick(status)
|
super.onJobTick(status)
|
||||||
|
|
||||||
if (isExopackVisible && ply.level().random.nextFloat() <= 0.05f) {
|
if (isExopackVisible && ply.level().otmRandom.nextFloat() <= 0.05f) {
|
||||||
PacketDistributor.sendToPlayersTrackingEntityAndSelf(ply, ExopackSmokePacket(ply.uuid))
|
PacketDistributor.sendToPlayersTrackingEntityAndSelf(ply, ExopackSmokePacket(ply.uuid))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1397,7 +1397,7 @@ class MatteryPlayer(val ply: Player) {
|
|||||||
|
|
||||||
pos.mul(RenderSystem.getProjectionMatrix())
|
pos.mul(RenderSystem.getProjectionMatrix())
|
||||||
pos.mul(poseStack.last().pose())
|
pos.mul(poseStack.last().pose())
|
||||||
makeSmoke(cam.x + pos.x, cam.y + pos.y, cam.z + pos.z, ply.level().random, ply.level())
|
makeSmoke(cam.x + pos.x, cam.y + pos.y, cam.z + pos.z, ply.level().otmRandom, ply.level())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,58 +0,0 @@
|
|||||||
package ru.dbotthepony.mc.otm.client.render.entity
|
|
||||||
|
|
||||||
import com.mojang.blaze3d.vertex.PoseStack
|
|
||||||
import net.minecraft.client.model.HierarchicalModel
|
|
||||||
import net.minecraft.client.renderer.MultiBufferSource
|
|
||||||
import net.minecraft.client.renderer.RenderType
|
|
||||||
import net.minecraft.client.renderer.entity.EntityRendererProvider
|
|
||||||
import net.minecraft.client.renderer.entity.MobRenderer
|
|
||||||
import net.minecraft.client.renderer.entity.layers.RenderLayer
|
|
||||||
import net.minecraft.client.renderer.texture.OverlayTexture
|
|
||||||
import net.minecraft.resources.ResourceLocation
|
|
||||||
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
|
||||||
import ru.dbotthepony.mc.otm.OverdriveThatMatters.loc
|
|
||||||
import ru.dbotthepony.mc.otm.client.model.entity.EnforcerModel
|
|
||||||
import ru.dbotthepony.mc.otm.entity.Enforcer
|
|
||||||
|
|
||||||
class EnforcerRenderer(context: EntityRendererProvider.Context)
|
|
||||||
: MobRenderer<Enforcer, HierarchicalModel<Enforcer>>(context, EnforcerModel.getModel(), 2.2f) {
|
|
||||||
override fun getTextureLocation(entity: Enforcer): ResourceLocation = TEXTURE_LOCATION
|
|
||||||
|
|
||||||
init {
|
|
||||||
this.addLayer(EnforcerEmissiveLayer(this, model))
|
|
||||||
}
|
|
||||||
companion object {
|
|
||||||
private val TEXTURE_LOCATION = loc("textures/entity/enforcer.png")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class EnforcerEmissiveLayer(
|
|
||||||
entityRenderer: EnforcerRenderer,
|
|
||||||
model: HierarchicalModel<Enforcer>
|
|
||||||
) : RenderLayer<Enforcer, HierarchicalModel<Enforcer>>(entityRenderer) {
|
|
||||||
|
|
||||||
private val emissive = loc("textures/entity/enforcer_emissive.png")
|
|
||||||
|
|
||||||
|
|
||||||
override fun render(
|
|
||||||
poseStack: PoseStack,
|
|
||||||
bufferSource: MultiBufferSource,
|
|
||||||
packedLight: Int,
|
|
||||||
entity: Enforcer,
|
|
||||||
limbSwing: Float,
|
|
||||||
limbSwingAmount: Float,
|
|
||||||
partialTicks: Float,
|
|
||||||
ageInTicks: Float,
|
|
||||||
netHeadYaw: Float,
|
|
||||||
headPitch: Float
|
|
||||||
) {
|
|
||||||
val buffer = bufferSource.getBuffer(RenderType.eyes(emissive))
|
|
||||||
|
|
||||||
this.parentModel.renderToBuffer(
|
|
||||||
poseStack,
|
|
||||||
buffer,
|
|
||||||
15728640,
|
|
||||||
OverlayTexture.NO_OVERLAY
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
16
src/main/kotlin/ru/dbotthepony/mc/otm/core/IMatteryLevel.kt
Normal file
16
src/main/kotlin/ru/dbotthepony/mc/otm/core/IMatteryLevel.kt
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.core
|
||||||
|
|
||||||
|
import net.minecraft.util.RandomSource
|
||||||
|
import net.minecraft.world.level.Level
|
||||||
|
|
||||||
|
interface IMatteryLevel {
|
||||||
|
/**
|
||||||
|
* OTM provided [RandomSource], which has better statistical parameters
|
||||||
|
*
|
||||||
|
* Original Minecraft use LCG, which may show bad behavior when repeatedly sampled *a lot*,
|
||||||
|
* which is what [Level]'s random is used for. OTM provided PRNG should behave better in this scenario.
|
||||||
|
*/
|
||||||
|
val otmRandom: RandomSource
|
||||||
|
}
|
||||||
|
|
||||||
|
val Level.otmRandom: RandomSource get() = (this as IMatteryLevel).otmRandom
|
117
src/main/kotlin/ru/dbotthepony/mc/otm/core/util/CMWCRandom.kt
Normal file
117
src/main/kotlin/ru/dbotthepony/mc/otm/core/util/CMWCRandom.kt
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.core.util
|
||||||
|
|
||||||
|
import net.minecraft.util.Mth
|
||||||
|
import net.minecraft.util.RandomSource
|
||||||
|
import net.minecraft.world.level.levelgen.MarsagliaPolarGaussian
|
||||||
|
import net.minecraft.world.level.levelgen.PositionalRandomFactory
|
||||||
|
import net.minecraft.world.level.levelgen.RandomSupport
|
||||||
|
import ru.dbotthepony.kommons.random.PCG32Random
|
||||||
|
import java.lang.StringBuilder
|
||||||
|
import java.util.random.RandomGenerator
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Random number generator with insane period of at least 2^511
|
||||||
|
*/
|
||||||
|
class CMWCRandom(seed: Long = RandomSupport.generateUniqueSeed()) : RandomGenerator, RandomSource {
|
||||||
|
private val state = IntArray(CMWC_STATE_SIZE)
|
||||||
|
private var carry = 0
|
||||||
|
private var stateIndex = 0
|
||||||
|
private val gaussian = MarsagliaPolarGaussian(this)
|
||||||
|
|
||||||
|
init {
|
||||||
|
setSeed(seed)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setSeed(seed: Long) {
|
||||||
|
val rng = PCG32Random(seed)
|
||||||
|
|
||||||
|
// init state with regular LCG produced values
|
||||||
|
for (i in 1 until state.size) {
|
||||||
|
state[i] = rng.nextInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
carry = rng.nextInt()
|
||||||
|
} while(carry !in 0 until CMWC_CARRY_MAX)
|
||||||
|
|
||||||
|
stateIndex = state.size - 1
|
||||||
|
gaussian.reset()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun nextInt(): Int {
|
||||||
|
stateIndex = (stateIndex + 1).and(CMWC_STATE_SIZE - 1)
|
||||||
|
val t = 18782L * state[stateIndex] + carry
|
||||||
|
|
||||||
|
carry = t.ushr(32).toInt()
|
||||||
|
var x = t.toInt() + carry
|
||||||
|
|
||||||
|
if (x < carry) {
|
||||||
|
x++
|
||||||
|
carry++
|
||||||
|
}
|
||||||
|
|
||||||
|
state[stateIndex] = 0xfffffffe.toInt() - x
|
||||||
|
return state[stateIndex]
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun nextLong(): Long {
|
||||||
|
val a = nextInt().toLong() and 0xFFFFFFFFL
|
||||||
|
val b = nextInt().toLong() and 0xFFFFFFFFL
|
||||||
|
return a.shl(32) or b
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun nextInt(bound: Int): Int {
|
||||||
|
return super<RandomGenerator>.nextInt(bound)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun nextInt(origin: Int, bound: Int): Int {
|
||||||
|
return super<RandomGenerator>.nextInt(origin, bound)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun nextBoolean(): Boolean {
|
||||||
|
return super.nextBoolean()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun nextFloat(): Float {
|
||||||
|
return super.nextFloat()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun nextDouble(): Double {
|
||||||
|
return super.nextDouble()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun nextGaussian(): Double {
|
||||||
|
return gaussian.nextGaussian()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun fork(): RandomSource {
|
||||||
|
return CMWCRandom(nextLong())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun forkPositional(): PositionalRandomFactory {
|
||||||
|
return Positional(nextLong())
|
||||||
|
}
|
||||||
|
|
||||||
|
class Positional(private val seed: Long) : PositionalRandomFactory {
|
||||||
|
override fun at(x: Int, y: Int, z: Int): RandomSource {
|
||||||
|
return CMWCRandom(Mth.getSeed(x, y, z).xor(seed))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun fromHashOf(name: String): RandomSource {
|
||||||
|
return CMWCRandom(name.hashCode().toLong().xor(seed))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun fromSeed(seed: Long): RandomSource {
|
||||||
|
return CMWCRandom(seed)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun parityConfigString(builder: StringBuilder) {
|
||||||
|
throw UnsupportedOperationException()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val CMWC_STATE_SIZE = 32 // 4096
|
||||||
|
const val CMWC_CARRY_MAX = 809430660
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.core.util
|
||||||
|
|
||||||
|
import net.minecraft.util.Mth
|
||||||
|
import net.minecraft.util.RandomSource
|
||||||
|
import net.minecraft.world.level.levelgen.LegacyRandomSource
|
||||||
|
import net.minecraft.world.level.levelgen.MarsagliaPolarGaussian
|
||||||
|
import net.minecraft.world.level.levelgen.PositionalRandomFactory
|
||||||
|
import net.minecraft.world.level.levelgen.RandomSupport
|
||||||
|
import ru.dbotthepony.kommons.random.LCG64Random
|
||||||
|
import java.lang.StringBuilder
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple and insanely fast random number generator, which can be used for seeding (initializing internal state) of other number generators.
|
||||||
|
*
|
||||||
|
* While can be used on its own, it probably shouldn't.
|
||||||
|
*
|
||||||
|
* Differs from [LegacyRandomSource] (also LCG, created by [RandomSource.create]) Minecraft uses in:
|
||||||
|
* * Different constants (with supposedly/expected better statistical properties)
|
||||||
|
* * Always use upper 32 bits instead of implementing BitRandomSource and sampling some upper bits
|
||||||
|
* * Uses all bits from provided seed
|
||||||
|
*/
|
||||||
|
class LCG64RandomSource(seed: Long = RandomSupport.generateUniqueSeed()) : LCG64Random(seed), IRandomSourceGenerator {
|
||||||
|
private val gaussian = MarsagliaPolarGaussian(this)
|
||||||
|
|
||||||
|
override fun setSeed(seed: Long) {
|
||||||
|
this.seed = seed
|
||||||
|
gaussian.reset()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun nextGaussian(): Double {
|
||||||
|
return gaussian.nextGaussian()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun fork(): RandomSource {
|
||||||
|
return LCG64RandomSource(nextLong())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun forkPositional(): PositionalRandomFactory {
|
||||||
|
return Positional(nextLong())
|
||||||
|
}
|
||||||
|
|
||||||
|
class Positional(private val seed: Long) : PositionalRandomFactory {
|
||||||
|
override fun at(x: Int, y: Int, z: Int): RandomSource {
|
||||||
|
return LCG64RandomSource(Mth.getSeed(x, y, z).xor(seed))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun fromHashOf(name: String): RandomSource {
|
||||||
|
return LCG64RandomSource(name.hashCode().toLong().xor(seed))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun fromSeed(seed: Long): RandomSource {
|
||||||
|
return LCG64RandomSource(seed)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun parityConfigString(builder: StringBuilder) {
|
||||||
|
throw UnsupportedOperationException()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.core.util
|
||||||
|
|
||||||
|
import net.minecraft.util.Mth
|
||||||
|
import net.minecraft.util.RandomSource
|
||||||
|
import net.minecraft.world.level.levelgen.MarsagliaPolarGaussian
|
||||||
|
import net.minecraft.world.level.levelgen.PositionalRandomFactory
|
||||||
|
import net.minecraft.world.level.levelgen.RandomSupport
|
||||||
|
import ru.dbotthepony.kommons.random.PCG32Random
|
||||||
|
import java.lang.StringBuilder
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see PCG32Random
|
||||||
|
*/
|
||||||
|
class PCG32RandomSource(seed: Long = RandomSupport.generateUniqueSeed()) : PCG32Random(seed), IRandomSourceGenerator {
|
||||||
|
private val gaussian = MarsagliaPolarGaussian(this)
|
||||||
|
|
||||||
|
override fun setSeed(seed: Long) {
|
||||||
|
this.seed = seed
|
||||||
|
gaussian.reset()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun nextGaussian(): Double {
|
||||||
|
return gaussian.nextGaussian()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun fork(): RandomSource {
|
||||||
|
return PCG32RandomSource(nextLong())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun forkPositional(): PositionalRandomFactory {
|
||||||
|
return Positional(nextLong())
|
||||||
|
}
|
||||||
|
|
||||||
|
class Positional(private val seed: Long) : PositionalRandomFactory {
|
||||||
|
override fun at(x: Int, y: Int, z: Int): RandomSource {
|
||||||
|
return PCG32RandomSource(Mth.getSeed(x, y, z).xor(seed))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun fromHashOf(name: String): RandomSource {
|
||||||
|
return PCG32RandomSource(name.hashCode().toLong().xor(seed))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun fromSeed(seed: Long): RandomSource {
|
||||||
|
return PCG32RandomSource(seed)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun parityConfigString(builder: StringBuilder) {
|
||||||
|
throw UnsupportedOperationException()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,93 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.core.util
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.HashCommon
|
||||||
|
import net.minecraft.util.Mth
|
||||||
|
import net.minecraft.util.RandomSource
|
||||||
|
import net.minecraft.world.level.levelgen.MarsagliaPolarGaussian
|
||||||
|
import net.minecraft.world.level.levelgen.PositionalRandomFactory
|
||||||
|
import net.minecraft.world.level.levelgen.RandomSupport
|
||||||
|
import ru.dbotthepony.kommons.random.LCG64Random
|
||||||
|
import ru.dbotthepony.kommons.random.Xoshiro256StarStarRandom
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Excellent number generator with guaranteed period of 2^255
|
||||||
|
*/
|
||||||
|
class Xoshiro256Random : Xoshiro256StarStarRandom, IRandomSourceGenerator {
|
||||||
|
private val gaussian = MarsagliaPolarGaussian(this)
|
||||||
|
|
||||||
|
// raw
|
||||||
|
private constructor(s0: Long, s1: Long, s2: Long, s3: Long, marker: Nothing?): super(s0, s1, s2, s3, null)
|
||||||
|
// normal
|
||||||
|
constructor(s0: Long, s1: Long, s2: Long, s3: Long) : super(s0, s1, s2, s3)
|
||||||
|
|
||||||
|
// 64-bit seeded
|
||||||
|
constructor(seed: Long) : super(1L, 2L, 3L, 4L, null) {
|
||||||
|
setSeed(seed)
|
||||||
|
}
|
||||||
|
|
||||||
|
// completely random
|
||||||
|
constructor() : super(RandomSupport.generateUniqueSeed(), RandomSupport.generateUniqueSeed(), RandomSupport.generateUniqueSeed(), RandomSupport.generateUniqueSeed(), null)
|
||||||
|
|
||||||
|
override fun setSeed(seed: Long) {
|
||||||
|
val rng = LCG64Random(seed)
|
||||||
|
s0 = rng.nextLong()
|
||||||
|
s1 = rng.nextLong()
|
||||||
|
s2 = rng.nextLong()
|
||||||
|
s3 = rng.nextLong()
|
||||||
|
gaussian.reset()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun nextInt(): Int {
|
||||||
|
// sample upper bits
|
||||||
|
return nextLong().ushr(32).toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun nextGaussian(): Double {
|
||||||
|
return gaussian.nextGaussian()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun fork(): RandomSource {
|
||||||
|
return Xoshiro256Random(nextLong(), nextLong(), nextLong(), nextLong(), null)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun forkPositional(): PositionalRandomFactory {
|
||||||
|
return Positional(nextLong(), nextLong(), nextLong(), nextLong())
|
||||||
|
}
|
||||||
|
|
||||||
|
class Positional(
|
||||||
|
private val s0: Long,
|
||||||
|
private val s1: Long,
|
||||||
|
private val s2: Long,
|
||||||
|
private val s3: Long,
|
||||||
|
) : PositionalRandomFactory {
|
||||||
|
override fun at(x: Int, y: Int, z: Int): RandomSource {
|
||||||
|
val rng = LCG64RandomSource(Mth.getSeed(x, y, z))
|
||||||
|
|
||||||
|
return Xoshiro256Random(
|
||||||
|
s0.rotateLeft(11).xor(rng.nextLong()),
|
||||||
|
s1.rotateLeft(22).xor(rng.nextLong()),
|
||||||
|
s2.rotateLeft(33).xor(rng.nextLong()),
|
||||||
|
s3.rotateLeft(44).xor(rng.nextLong()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun fromHashOf(name: String): RandomSource {
|
||||||
|
return Xoshiro256Random(s0, HashCommon.murmurHash3(name.hashCode().toLong()).xor(s1), s2, s3)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun fromSeed(seed: Long): RandomSource {
|
||||||
|
return Xoshiro256Random(seed)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun parityConfigString(builder: StringBuilder) {
|
||||||
|
throw UnsupportedOperationException()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmStatic
|
||||||
|
fun raw(s0: Long, s1: Long, s2: Long, s3: Long): Xoshiro256Random {
|
||||||
|
return Xoshiro256Random(s0, s1, s2, s3, null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,5 @@
|
|||||||
package ru.dbotthepony.mc.otm.entity
|
package ru.dbotthepony.mc.otm.entity
|
||||||
|
|
||||||
import net.minecraft.sounds.SoundEvent
|
|
||||||
import net.minecraft.sounds.SoundEvents
|
|
||||||
import net.minecraft.world.InteractionHand
|
import net.minecraft.world.InteractionHand
|
||||||
import net.minecraft.world.InteractionResult
|
import net.minecraft.world.InteractionResult
|
||||||
import net.minecraft.world.entity.AnimationState
|
import net.minecraft.world.entity.AnimationState
|
||||||
@ -9,7 +7,6 @@ import net.minecraft.world.entity.EntityType
|
|||||||
import net.minecraft.world.entity.LivingEntity
|
import net.minecraft.world.entity.LivingEntity
|
||||||
import net.minecraft.world.entity.ai.attributes.AttributeSupplier
|
import net.minecraft.world.entity.ai.attributes.AttributeSupplier
|
||||||
import net.minecraft.world.entity.ai.attributes.Attributes
|
import net.minecraft.world.entity.ai.attributes.Attributes
|
||||||
import net.minecraft.world.entity.ai.goal.RandomLookAroundGoal
|
|
||||||
import net.minecraft.world.entity.ai.goal.WaterAvoidingRandomStrollGoal
|
import net.minecraft.world.entity.ai.goal.WaterAvoidingRandomStrollGoal
|
||||||
import net.minecraft.world.entity.ai.navigation.GroundPathNavigation
|
import net.minecraft.world.entity.ai.navigation.GroundPathNavigation
|
||||||
import net.minecraft.world.entity.ai.navigation.PathNavigation
|
import net.minecraft.world.entity.ai.navigation.PathNavigation
|
||||||
@ -24,7 +21,6 @@ class Cleaner(type: EntityType<Cleaner>, level: Level) : Monster(type, level) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun registerGoals() {
|
override fun registerGoals() {
|
||||||
goalSelector.addGoal(8, RandomLookAroundGoal(this))
|
|
||||||
goalSelector.addGoal(7, WaterAvoidingRandomStrollGoal(this, 0.8))
|
goalSelector.addGoal(7, WaterAvoidingRandomStrollGoal(this, 0.8))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,14 +38,6 @@ class Cleaner(type: EntityType<Cleaner>, level: Level) : Monster(type, level) {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getHurtSound(damageSource: net.minecraft.world.damagesource.DamageSource): SoundEvent {
|
|
||||||
return SoundEvents.HEAVY_CORE_BREAK
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getDeathSound(): SoundEvent {
|
|
||||||
return SoundEvents.VAULT_BREAK
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun mobInteract(player: Player, hand: InteractionHand): InteractionResult {
|
override fun mobInteract(player: Player, hand: InteractionHand): InteractionResult {
|
||||||
if (!this.level().isClientSide) {
|
if (!this.level().isClientSide) {
|
||||||
player.startRiding(this)
|
player.startRiding(this)
|
||||||
|
@ -1,194 +0,0 @@
|
|||||||
package ru.dbotthepony.mc.otm.entity
|
|
||||||
|
|
||||||
import net.minecraft.server.level.ServerBossEvent
|
|
||||||
import net.minecraft.sounds.SoundEvent
|
|
||||||
import net.minecraft.sounds.SoundEvents
|
|
||||||
import net.minecraft.sounds.SoundSource
|
|
||||||
import net.minecraft.util.Mth
|
|
||||||
import net.minecraft.world.BossEvent
|
|
||||||
import net.minecraft.world.phys.Vec3
|
|
||||||
import net.minecraft.world.entity.AnimationState
|
|
||||||
import net.minecraft.world.entity.EntityType
|
|
||||||
import net.minecraft.world.entity.LivingEntity
|
|
||||||
import net.minecraft.world.entity.ai.attributes.AttributeSupplier
|
|
||||||
import net.minecraft.world.entity.ai.attributes.Attributes
|
|
||||||
import net.minecraft.world.entity.ai.goal.*
|
|
||||||
import net.minecraft.world.entity.ai.goal.target.HurtByTargetGoal
|
|
||||||
import net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal
|
|
||||||
import net.minecraft.world.entity.ai.navigation.GroundPathNavigation
|
|
||||||
import net.minecraft.world.entity.ai.navigation.PathNavigation
|
|
||||||
import net.minecraft.world.entity.monster.*
|
|
||||||
import net.minecraft.world.entity.npc.Villager
|
|
||||||
import net.minecraft.world.entity.player.Player
|
|
||||||
import net.minecraft.world.level.Level
|
|
||||||
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
|
||||||
import ru.dbotthepony.mc.otm.registry.MNames
|
|
||||||
import ru.dbotthepony.mc.otm.registry.game.MSoundEvents
|
|
||||||
|
|
||||||
class Enforcer(type: EntityType<Enforcer>, level: Level) : Monster(type,level) {
|
|
||||||
val idleState = AnimationState()
|
|
||||||
val chargeState = AnimationState()
|
|
||||||
init {
|
|
||||||
idleState.start(tickCount)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun registerGoals() {
|
|
||||||
goalSelector.addGoal(7, LookAtPlayerGoal(this, Player::class.java, 8f))
|
|
||||||
goalSelector.addGoal(3, NearestAttackableTargetGoal(this, LivingEntity::class.java, 10, true, true) { entity ->
|
|
||||||
entity is Player ||
|
|
||||||
entity is Villager ||
|
|
||||||
entity is AbstractIllager ||
|
|
||||||
entity is Zombie ||
|
|
||||||
entity is AbstractSkeleton
|
|
||||||
})
|
|
||||||
goalSelector.addGoal(2, RammingGoal(this))
|
|
||||||
targetSelector.addGoal(1, HurtByTargetGoal(this))
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun createNavigation(level: Level): PathNavigation = GroundPathNavigation(this, level)
|
|
||||||
|
|
||||||
override fun isPushable(): Boolean {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getHurtSound(damageSource: net.minecraft.world.damagesource.DamageSource): SoundEvent {
|
|
||||||
return SoundEvents.HEAVY_CORE_BREAK
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getDeathSound(): SoundEvent {
|
|
||||||
return SoundEvents.VAULT_BREAK
|
|
||||||
}
|
|
||||||
|
|
||||||
private val bossEvent: ServerBossEvent =
|
|
||||||
ServerBossEvent(TranslatableComponent(MNames.ENFORCER), BossEvent.BossBarColor.RED, BossEvent.BossBarOverlay.PROGRESS)
|
|
||||||
|
|
||||||
override fun startSeenByPlayer(player: net.minecraft.server.level.ServerPlayer) {
|
|
||||||
super.startSeenByPlayer(player)
|
|
||||||
bossEvent.addPlayer(player)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun stopSeenByPlayer(player: net.minecraft.server.level.ServerPlayer) {
|
|
||||||
super.stopSeenByPlayer(player)
|
|
||||||
bossEvent.removePlayer(player)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun aiStep() {
|
|
||||||
super.aiStep()
|
|
||||||
bossEvent.progress = this.health / this.maxHealth
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun die(cause: net.minecraft.world.damagesource.DamageSource) {
|
|
||||||
super.die(cause)
|
|
||||||
bossEvent.removeAllPlayers()
|
|
||||||
}
|
|
||||||
|
|
||||||
//charge attack, could possibly leave a smoke trail too idk
|
|
||||||
class RammingGoal(private val mob: Enforcer) : Goal() {
|
|
||||||
private var target: LivingEntity? = null
|
|
||||||
|
|
||||||
private var chargeTime = 0
|
|
||||||
private val windupTime = 20
|
|
||||||
private val maxChargeTime = 40
|
|
||||||
private var chargeDir: Vec3? = null
|
|
||||||
private var cooldown = 0
|
|
||||||
private val minCooldown = 20
|
|
||||||
private val maxCooldown = 60
|
|
||||||
private var isCharging = false
|
|
||||||
|
|
||||||
override fun canUse(): Boolean {
|
|
||||||
if (cooldown > 0) {
|
|
||||||
cooldown--
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
target = mob.target
|
|
||||||
return target != null
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun canContinueToUse(): Boolean {
|
|
||||||
return isCharging && chargeTime < maxChargeTime
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun start() {
|
|
||||||
mob.playSound(MSoundEvents.PLASMA_WEAPON_OVERHEAT, 1.0f, 1.0f)
|
|
||||||
chargeTime = 0
|
|
||||||
mob.navigation.stop()
|
|
||||||
cooldown = minCooldown + mob.random.nextInt(maxCooldown - minCooldown)
|
|
||||||
isCharging = true
|
|
||||||
|
|
||||||
mob.chargeState.start(mob.tickCount)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun tick() {
|
|
||||||
if (!isCharging) return
|
|
||||||
|
|
||||||
chargeTime++
|
|
||||||
val target = mob.target ?: return
|
|
||||||
|
|
||||||
if (chargeTime < windupTime) {
|
|
||||||
chargeDir = Vec3(target.x - mob.x, 0.0, target.z - mob.z).normalize()
|
|
||||||
|
|
||||||
mob.lookControl.setLookAt(target, 30.0f, 30.0f)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (chargeTime == windupTime) {
|
|
||||||
if (chargeDir == null || chargeDir!!.length() < 0.1) {
|
|
||||||
stop()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
mob.playSound(MSoundEvents.ANDROID_JUMP_BOOST, 1.0f, 1.0f)
|
|
||||||
}
|
|
||||||
|
|
||||||
val dir = chargeDir ?: return
|
|
||||||
mob.yRot = (-Mth.atan2(dir.x, dir.z) * (180f / Math.PI)).toFloat()
|
|
||||||
mob.yHeadRot = mob.yRot
|
|
||||||
|
|
||||||
mob.move(net.minecraft.world.entity.MoverType.SELF, dir.scale(1.8))
|
|
||||||
|
|
||||||
|
|
||||||
if (mob.horizontalCollision) {
|
|
||||||
mob.level().playSound(
|
|
||||||
null,
|
|
||||||
mob.x, mob.y, mob.z,
|
|
||||||
SoundEvents.GENERIC_EXPLODE,
|
|
||||||
SoundSource.HOSTILE,
|
|
||||||
1.0f,
|
|
||||||
1.0f
|
|
||||||
)
|
|
||||||
stop()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mob.boundingBox.intersects(target.boundingBox)) {
|
|
||||||
val knockbackStrength = 1.5
|
|
||||||
val knockback = dir.scale(knockbackStrength)
|
|
||||||
target.push(knockback.x, 0.5, knockback.z)
|
|
||||||
|
|
||||||
val damageAmount = 6.0f
|
|
||||||
target.hurt(mob.damageSources().mobAttack(mob), damageAmount)
|
|
||||||
|
|
||||||
stop()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun stop() {
|
|
||||||
mob.setDeltaMovement(Vec3.ZERO)
|
|
||||||
chargeTime = 0
|
|
||||||
chargeDir = null
|
|
||||||
isCharging = false
|
|
||||||
mob.chargeState.stop()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
fun createAttributes() : AttributeSupplier.Builder {
|
|
||||||
return createMonsterAttributes()
|
|
||||||
.add(Attributes.MAX_HEALTH, 300.0)
|
|
||||||
.add(Attributes.ARMOR, 20.0)
|
|
||||||
.add(Attributes.MOVEMENT_SPEED, 0.3)
|
|
||||||
.add(Attributes.STEP_HEIGHT, 1.0)
|
|
||||||
.add(Attributes.KNOCKBACK_RESISTANCE, 1.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -19,7 +19,7 @@ import net.minecraft.world.level.block.state.BlockState
|
|||||||
import net.minecraft.world.level.gameevent.GameEvent
|
import net.minecraft.world.level.gameevent.GameEvent
|
||||||
import ru.dbotthepony.mc.otm.block.decorative.CargoCrateBlock
|
import ru.dbotthepony.mc.otm.block.decorative.CargoCrateBlock
|
||||||
import ru.dbotthepony.mc.otm.block.entity.decorative.CargoCrateBlockEntity
|
import ru.dbotthepony.mc.otm.block.entity.decorative.CargoCrateBlockEntity
|
||||||
import ru.dbotthepony.mc.otm.core.random
|
import ru.dbotthepony.mc.otm.core.otmRandom
|
||||||
import ru.dbotthepony.mc.otm.core.position
|
import ru.dbotthepony.mc.otm.core.position
|
||||||
import ru.dbotthepony.mc.otm.menu.decorative.MinecartCargoCrateMenu
|
import ru.dbotthepony.mc.otm.menu.decorative.MinecartCargoCrateMenu
|
||||||
import ru.dbotthepony.mc.otm.registry.game.MItems
|
import ru.dbotthepony.mc.otm.registry.game.MItems
|
||||||
@ -90,7 +90,7 @@ class MinecartCargoCrate(
|
|||||||
|
|
||||||
if (interactingPlayers++ == 0) {
|
if (interactingPlayers++ == 0) {
|
||||||
if (!isRemoved) {
|
if (!isRemoved) {
|
||||||
level().playSound(null, this, MSoundEvents.CARGO_CRATE_OPEN, SoundSource.BLOCKS, 1f, 0.8f + level().random.nextFloat() * 0.2f)
|
level().playSound(null, this, MSoundEvents.CARGO_CRATE_OPEN, SoundSource.BLOCKS, 1f, 0.8f + level().otmRandom.nextFloat() * 0.2f)
|
||||||
this.gameEvent(GameEvent.CONTAINER_OPEN, player)
|
this.gameEvent(GameEvent.CONTAINER_OPEN, player)
|
||||||
PiglinAi.angerNearbyPiglins(player, true)
|
PiglinAi.angerNearbyPiglins(player, true)
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ import net.minecraft.world.item.Items
|
|||||||
import net.neoforged.bus.api.SubscribeEvent
|
import net.neoforged.bus.api.SubscribeEvent
|
||||||
import net.neoforged.neoforge.event.entity.EntityJoinLevelEvent
|
import net.neoforged.neoforge.event.entity.EntityJoinLevelEvent
|
||||||
import ru.dbotthepony.mc.otm.config.ServerConfig
|
import ru.dbotthepony.mc.otm.config.ServerConfig
|
||||||
import ru.dbotthepony.mc.otm.core.random
|
import ru.dbotthepony.mc.otm.core.otmRandom
|
||||||
import ru.dbotthepony.mc.otm.registry.game.MItems
|
import ru.dbotthepony.mc.otm.registry.game.MItems
|
||||||
|
|
||||||
|
|
||||||
@ -17,8 +17,8 @@ object WitheredSkeletonSpawnHandler {
|
|||||||
val entity = event.entity
|
val entity = event.entity
|
||||||
|
|
||||||
if (entity is WitherSkeleton) {
|
if (entity is WitherSkeleton) {
|
||||||
val giveHelmet = event.level.random.nextFloat() < ServerConfig.WITHER_SKELETON_HELMET_CHANCE
|
val giveHelmet = event.level.otmRandom.nextFloat() < ServerConfig.WITHER_SKELETON_HELMET_CHANCE
|
||||||
val giveSword = event.level.random.nextFloat() < ServerConfig.WITHER_SKELETON_SWORD_CHANCE
|
val giveSword = event.level.otmRandom.nextFloat() < ServerConfig.WITHER_SKELETON_SWORD_CHANCE
|
||||||
|
|
||||||
if (giveHelmet) {
|
if (giveHelmet) {
|
||||||
if (!entity.hasItemInSlot(EquipmentSlot.HEAD))
|
if (!entity.hasItemInSlot(EquipmentSlot.HEAD))
|
||||||
|
@ -184,7 +184,7 @@ class CrudeBatteryItem : BatteryItem(ItemsConfig.Batteries.CRUDE) {
|
|||||||
if (player is ServerPlayer) {
|
if (player is ServerPlayer) {
|
||||||
if (!mattery.androidEnergy.item.isEmpty) {
|
if (!mattery.androidEnergy.item.isEmpty) {
|
||||||
mattery.androidEnergy.item.getCapability(Capabilities.EnergyStorage.ITEM)?.let {
|
mattery.androidEnergy.item.getCapability(Capabilities.EnergyStorage.ITEM)?.let {
|
||||||
it.extractEnergy((it.maxEnergyStored * level.random.nextFloat() * .2f).roundToInt(), false)
|
it.extractEnergy((it.maxEnergyStored * level.otmRandom.nextFloat() * .2f).roundToInt(), false)
|
||||||
}
|
}
|
||||||
|
|
||||||
mattery.dropBattery()
|
mattery.dropBattery()
|
||||||
@ -194,7 +194,7 @@ class CrudeBatteryItem : BatteryItem(ItemsConfig.Batteries.CRUDE) {
|
|||||||
copyStack.count = 1
|
copyStack.count = 1
|
||||||
mattery.androidEnergy.item = copyStack
|
mattery.androidEnergy.item = copyStack
|
||||||
|
|
||||||
val extraDamageMult = level.random.nextFloat()
|
val extraDamageMult = level.otmRandom.nextFloat()
|
||||||
player.hurt(MatteryDamageSource(level.registryAccess().damageType(MDamageTypes.EMP), inflictor = itemStack), 1.5f + extraDamageMult * 3.5f)
|
player.hurt(MatteryDamageSource(level.registryAccess().damageType(MDamageTypes.EMP), inflictor = itemStack), 1.5f + extraDamageMult * 3.5f)
|
||||||
|
|
||||||
val debuffDuration = 100 + (100 * (1f - extraDamageMult)).roundToInt()
|
val debuffDuration = 100 + (100 * (1f - extraDamageMult)).roundToInt()
|
||||||
|
@ -17,7 +17,7 @@ import ru.dbotthepony.mc.otm.capability.matteryPlayer
|
|||||||
import ru.dbotthepony.mc.otm.client.isShiftDown
|
import ru.dbotthepony.mc.otm.client.isShiftDown
|
||||||
import ru.dbotthepony.mc.otm.client.minecraft
|
import ru.dbotthepony.mc.otm.client.minecraft
|
||||||
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||||
import ru.dbotthepony.mc.otm.core.random
|
import ru.dbotthepony.mc.otm.core.otmRandom
|
||||||
import ru.dbotthepony.mc.otm.core.util.getLevelFromXp
|
import ru.dbotthepony.mc.otm.core.util.getLevelFromXp
|
||||||
import ru.dbotthepony.mc.otm.item.MatteryItem
|
import ru.dbotthepony.mc.otm.item.MatteryItem
|
||||||
import ru.dbotthepony.mc.otm.registry.game.MDataComponentTypes
|
import ru.dbotthepony.mc.otm.registry.game.MDataComponentTypes
|
||||||
@ -81,7 +81,7 @@ class EssenceCapsuleItem(private val digital: Boolean) : MatteryItem(Properties(
|
|||||||
} else {
|
} else {
|
||||||
if (level is ServerLevel) {
|
if (level is ServerLevel) {
|
||||||
level.levelEvent(2002, player.blockPosition(), PotionContents.getColor(Potions.WATER))
|
level.levelEvent(2002, player.blockPosition(), PotionContents.getColor(Potions.WATER))
|
||||||
ExperienceOrb.award(level, player.position(), (exp * (.5 + level.random.nextFloat() * .25)).toInt())
|
ExperienceOrb.award(level, player.position(), (exp * (.5 + level.otmRandom.nextFloat() * .25)).toInt())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +38,9 @@ class HealPillItem : MatteryItem(Properties().stacksTo(64).rarity(Rarity.UNCOMMO
|
|||||||
return super.finishUsingItem(stack, level, ent)
|
return super.finishUsingItem(stack, level, ent)
|
||||||
|
|
||||||
stack.shrink(1)
|
stack.shrink(1)
|
||||||
|
ent.addEffect(MobEffectInstance(MobEffects.ABSORPTION, 20 * 60 * 2, 4))
|
||||||
ent.addEffect(MobEffectInstance(MobEffects.REGENERATION, 20 * 8, 2))
|
ent.addEffect(MobEffectInstance(MobEffects.REGENERATION, 20 * 8, 2))
|
||||||
|
ent.heal(8f)
|
||||||
return stack
|
return stack
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ import net.minecraft.world.entity.item.ItemEntity
|
|||||||
import net.minecraft.world.item.ItemStack
|
import net.minecraft.world.item.ItemStack
|
||||||
import net.minecraft.world.level.Level
|
import net.minecraft.world.level.Level
|
||||||
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||||
import ru.dbotthepony.mc.otm.core.random
|
import ru.dbotthepony.mc.otm.core.otmRandom
|
||||||
import ru.dbotthepony.mc.otm.core.position
|
import ru.dbotthepony.mc.otm.core.position
|
||||||
import ru.dbotthepony.mc.otm.entity.BreadMonster
|
import ru.dbotthepony.mc.otm.entity.BreadMonster
|
||||||
import ru.dbotthepony.mc.otm.item.MatteryItem
|
import ru.dbotthepony.mc.otm.item.MatteryItem
|
||||||
@ -39,7 +39,7 @@ class ImperfectBreadItem(properties: Properties) : MatteryItem(properties) {
|
|||||||
// roll multiple times so multiple bread monsters can spawn on tick
|
// roll multiple times so multiple bread monsters can spawn on tick
|
||||||
// and also chance be less biased
|
// and also chance be less biased
|
||||||
for (i in 0 until stack.count.coerceAtMost(16)) {
|
for (i in 0 until stack.count.coerceAtMost(16)) {
|
||||||
if (entity.level().random.nextFloat() < 0.001f) {
|
if (entity.level().otmRandom.nextFloat() < 0.001f) {
|
||||||
val ent = BreadMonster(entity.level())
|
val ent = BreadMonster(entity.level())
|
||||||
ent.position = entity.position
|
ent.position = entity.position
|
||||||
entity.level().addFreshEntity(ent)
|
entity.level().addFreshEntity(ent)
|
||||||
|
@ -84,7 +84,7 @@ class ExplosiveHammerItem(durability: Int = 512) : Item(Properties().stacksTo(1)
|
|||||||
itemStack.hurtAndBreak(8, level, player) {}
|
itemStack.hurtAndBreak(8, level, player) {}
|
||||||
|
|
||||||
if (isPrimed(itemStack)) {
|
if (isPrimed(itemStack)) {
|
||||||
itemStack.hurtAndBreak(level.random.nextInt(1, 20), level, player) {}
|
itemStack.hurtAndBreak(level.otmRandom.nextInt(1, 20), level, player) {}
|
||||||
unprime(itemStack)
|
unprime(itemStack)
|
||||||
|
|
||||||
val (ex, ey, ez) = Vector.atCenterOf(player.blockPosition())
|
val (ex, ey, ez) = Vector.atCenterOf(player.blockPosition())
|
||||||
@ -226,7 +226,7 @@ class ExplosiveHammerItem(durability: Int = 512) : Item(Properties().stacksTo(1)
|
|||||||
|
|
||||||
val copy = itemStack.copy()
|
val copy = itemStack.copy()
|
||||||
|
|
||||||
itemStack.hurtAndBreak(level.random.nextInt(1, 20), attacker, EquipmentSlot.MAINHAND)
|
itemStack.hurtAndBreak(level.otmRandom.nextInt(1, 20), attacker, EquipmentSlot.MAINHAND)
|
||||||
|
|
||||||
if (!itemStack.isEmpty && attacker.random.nextDouble() <= ToolsConfig.ExplosiveHammer.FLY_OFF_CHANCE) {
|
if (!itemStack.isEmpty && attacker.random.nextDouble() <= ToolsConfig.ExplosiveHammer.FLY_OFF_CHANCE) {
|
||||||
attacker.setItemInHand(hand, ItemStack.EMPTY)
|
attacker.setItemInHand(hand, ItemStack.EMPTY)
|
||||||
|
@ -33,7 +33,7 @@ import ru.dbotthepony.mc.otm.core.math.Decimal
|
|||||||
import ru.dbotthepony.mc.otm.core.math.DecimalConfigValue
|
import ru.dbotthepony.mc.otm.core.math.DecimalConfigValue
|
||||||
import ru.dbotthepony.mc.otm.core.math.defineDecimal
|
import ru.dbotthepony.mc.otm.core.math.defineDecimal
|
||||||
import ru.dbotthepony.mc.otm.core.math.nextVariance
|
import ru.dbotthepony.mc.otm.core.math.nextVariance
|
||||||
import ru.dbotthepony.mc.otm.core.random
|
import ru.dbotthepony.mc.otm.core.otmRandom
|
||||||
import ru.dbotthepony.mc.otm.core.util.WriteOnce
|
import ru.dbotthepony.mc.otm.core.util.WriteOnce
|
||||||
import ru.dbotthepony.mc.otm.item.MatteryItem
|
import ru.dbotthepony.mc.otm.item.MatteryItem
|
||||||
import ru.dbotthepony.mc.otm.item.addSimpleDescription
|
import ru.dbotthepony.mc.otm.item.addSimpleDescription
|
||||||
@ -98,10 +98,10 @@ class EnergySwordItem : MatteryItem(Properties().stacksTo(1).rarity(Rarity.RARE)
|
|||||||
|
|
||||||
itemStack.getCapability(MatteryCapability.ITEM_ENERGY)?.let {
|
itemStack.getCapability(MatteryCapability.ITEM_ENERGY)?.let {
|
||||||
if (it.extractEnergyExact(ENERGY_PER_SWING, false)) {
|
if (it.extractEnergyExact(ENERGY_PER_SWING, false)) {
|
||||||
it.extractEnergy(attacker.level().random.nextVariance(ENERGY_PER_SWING_VARIANCE), false)
|
it.extractEnergy(attacker.level().otmRandom.nextVariance(ENERGY_PER_SWING_VARIANCE), false)
|
||||||
victim.matteryPlayer?.let {
|
victim.matteryPlayer?.let {
|
||||||
if (it.isAndroid && it.androidEnergy.extractEnergyExact(ENERGY_ZAP, false)) {
|
if (it.isAndroid && it.androidEnergy.extractEnergyExact(ENERGY_ZAP, false)) {
|
||||||
it.androidEnergy.extractEnergy(attacker.level().random.nextVariance(ENERGY_ZAP_VARIANCE), false)
|
it.androidEnergy.extractEnergy(attacker.level().otmRandom.nextVariance(ENERGY_ZAP_VARIANCE), false)
|
||||||
victim.hurt(MatteryDamageSource(attacker.level().registryAccess().damageType(MDamageTypes.EMP), attacker, itemStack), 8f)
|
victim.hurt(MatteryDamageSource(attacker.level().registryAccess().damageType(MDamageTypes.EMP), attacker, itemStack), 8f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -144,12 +144,12 @@ class EnergySwordItem : MatteryItem(Properties().stacksTo(1).rarity(Rarity.RARE)
|
|||||||
|
|
||||||
if (blockState.`is`(BlockTags.SWORD_EFFICIENT)) {
|
if (blockState.`is`(BlockTags.SWORD_EFFICIENT)) {
|
||||||
if (energy?.extractEnergyExact(PLANT_POWER_COST, false) == true)
|
if (energy?.extractEnergyExact(PLANT_POWER_COST, false) == true)
|
||||||
energy.extractEnergyExact(user.level().random.nextVariance(PLANT_POWER_COST_VARIANCE), false)
|
energy.extractEnergyExact(user.level().otmRandom.nextVariance(PLANT_POWER_COST_VARIANCE), false)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (blockState.`is`(Blocks.COBWEB)) {
|
if (blockState.`is`(Blocks.COBWEB)) {
|
||||||
if (energy?.extractEnergyExact(COBWEB_POWER_COST, false) == true)
|
if (energy?.extractEnergyExact(COBWEB_POWER_COST, false) == true)
|
||||||
energy.extractEnergyExact(user.level().random.nextVariance(COBWEB_POWER_COST_VARIANCE), false)
|
energy.extractEnergyExact(user.level().otmRandom.nextVariance(COBWEB_POWER_COST_VARIANCE), false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ import ru.dbotthepony.mc.otm.core.math.Decimal
|
|||||||
import ru.dbotthepony.mc.otm.core.math.DecimalConfigValue
|
import ru.dbotthepony.mc.otm.core.math.DecimalConfigValue
|
||||||
import ru.dbotthepony.mc.otm.core.math.defineDecimal
|
import ru.dbotthepony.mc.otm.core.math.defineDecimal
|
||||||
import ru.dbotthepony.mc.otm.core.math.nextVariance
|
import ru.dbotthepony.mc.otm.core.math.nextVariance
|
||||||
import ru.dbotthepony.mc.otm.core.random
|
import ru.dbotthepony.mc.otm.core.otmRandom
|
||||||
import ru.dbotthepony.mc.otm.core.util.WriteOnce
|
import ru.dbotthepony.mc.otm.core.util.WriteOnce
|
||||||
import ru.dbotthepony.mc.otm.item.MatteryItem
|
import ru.dbotthepony.mc.otm.item.MatteryItem
|
||||||
import ru.dbotthepony.mc.otm.item.addSimpleDescription
|
import ru.dbotthepony.mc.otm.item.addSimpleDescription
|
||||||
@ -99,10 +99,10 @@ class FallingSunItem : MatteryItem(Properties().stacksTo(1).rarity(Rarity.EPIC))
|
|||||||
|
|
||||||
itemStack.getCapability(MatteryCapability.ITEM_ENERGY)?.let {
|
itemStack.getCapability(MatteryCapability.ITEM_ENERGY)?.let {
|
||||||
if (it.extractEnergyExact(ENERGY_PER_SWING, false)) {
|
if (it.extractEnergyExact(ENERGY_PER_SWING, false)) {
|
||||||
it.extractEnergy(attacker.level().random.nextVariance(ENERGY_PER_SWING_VARIANCE), false)
|
it.extractEnergy(attacker.level().otmRandom.nextVariance(ENERGY_PER_SWING_VARIANCE), false)
|
||||||
victim.matteryPlayer?.let {
|
victim.matteryPlayer?.let {
|
||||||
if (it.isAndroid && it.androidEnergy.extractEnergyExact(ENERGY_ZAP, false)) {
|
if (it.isAndroid && it.androidEnergy.extractEnergyExact(ENERGY_ZAP, false)) {
|
||||||
it.androidEnergy.extractEnergy(attacker.level().random.nextVariance(ENERGY_ZAP_VARIANCE), false)
|
it.androidEnergy.extractEnergy(attacker.level().otmRandom.nextVariance(ENERGY_ZAP_VARIANCE), false)
|
||||||
victim.hurt(MatteryDamageSource(attacker.level().registryAccess().damageType(MDamageTypes.EMP), attacker, itemStack), 8f)
|
victim.hurt(MatteryDamageSource(attacker.level().registryAccess().damageType(MDamageTypes.EMP), attacker, itemStack), 8f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -146,12 +146,12 @@ class FallingSunItem : MatteryItem(Properties().stacksTo(1).rarity(Rarity.EPIC))
|
|||||||
|
|
||||||
if (blockState.`is`(BlockTags.SWORD_EFFICIENT)) {
|
if (blockState.`is`(BlockTags.SWORD_EFFICIENT)) {
|
||||||
if (energy?.extractEnergyExact(PLANT_POWER_COST, false) == true)
|
if (energy?.extractEnergyExact(PLANT_POWER_COST, false) == true)
|
||||||
energy.extractEnergyExact(user.level().random.nextVariance(PLANT_POWER_COST_VARIANCE), false)
|
energy.extractEnergyExact(user.level().otmRandom.nextVariance(PLANT_POWER_COST_VARIANCE), false)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (blockState.`is`(Blocks.COBWEB)) {
|
if (blockState.`is`(Blocks.COBWEB)) {
|
||||||
if (energy?.extractEnergyExact(COBWEB_POWER_COST, false) == true)
|
if (energy?.extractEnergyExact(COBWEB_POWER_COST, false) == true)
|
||||||
energy.extractEnergyExact(user.level().random.nextVariance(COBWEB_POWER_COST_VARIANCE), false)
|
energy.extractEnergyExact(user.level().otmRandom.nextVariance(COBWEB_POWER_COST_VARIANCE), false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ import ru.dbotthepony.mc.otm.core.math.component1
|
|||||||
import ru.dbotthepony.mc.otm.core.math.component2
|
import ru.dbotthepony.mc.otm.core.math.component2
|
||||||
import ru.dbotthepony.mc.otm.core.math.component3
|
import ru.dbotthepony.mc.otm.core.math.component3
|
||||||
import ru.dbotthepony.mc.otm.core.math.toRadians
|
import ru.dbotthepony.mc.otm.core.math.toRadians
|
||||||
import ru.dbotthepony.mc.otm.core.random
|
import ru.dbotthepony.mc.otm.core.otmRandom
|
||||||
import ru.dbotthepony.mc.otm.core.position
|
import ru.dbotthepony.mc.otm.core.position
|
||||||
import ru.dbotthepony.mc.otm.core.readItem
|
import ru.dbotthepony.mc.otm.core.readItem
|
||||||
import ru.dbotthepony.mc.otm.core.writeItem
|
import ru.dbotthepony.mc.otm.core.writeItem
|
||||||
@ -446,7 +446,7 @@ class ExopackSmokePacket(val player: UUID) : CustomPacketPayload {
|
|||||||
z += kotlin.math.sin(deg) * -0.4
|
z += kotlin.math.sin(deg) * -0.4
|
||||||
|
|
||||||
val level = ply.level()
|
val level = ply.level()
|
||||||
val random = level.random
|
val random = level.otmRandom
|
||||||
|
|
||||||
for (i in 0 .. random.nextInt(2, 4))
|
for (i in 0 .. random.nextInt(2, 4))
|
||||||
level.addParticle(
|
level.addParticle(
|
||||||
|
@ -13,7 +13,7 @@ import net.neoforged.neoforge.network.handling.IPayloadContext
|
|||||||
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
||||||
import ru.dbotthepony.mc.otm.client.minecraft
|
import ru.dbotthepony.mc.otm.client.minecraft
|
||||||
import ru.dbotthepony.mc.otm.core.ResourceLocation
|
import ru.dbotthepony.mc.otm.core.ResourceLocation
|
||||||
import ru.dbotthepony.mc.otm.core.random
|
import ru.dbotthepony.mc.otm.core.otmRandom
|
||||||
|
|
||||||
class SmokeParticlesPacket(val x: Double, val y: Double, val z: Double) : CustomPacketPayload {
|
class SmokeParticlesPacket(val x: Double, val y: Double, val z: Double) : CustomPacketPayload {
|
||||||
fun write(buff: FriendlyByteBuf) {
|
fun write(buff: FriendlyByteBuf) {
|
||||||
@ -24,7 +24,7 @@ class SmokeParticlesPacket(val x: Double, val y: Double, val z: Double) : Custom
|
|||||||
|
|
||||||
fun play(context: IPayloadContext) {
|
fun play(context: IPayloadContext) {
|
||||||
minecraft.player?.level()?.let {
|
minecraft.player?.level()?.let {
|
||||||
makeSmoke(x, y, z, it.random, it)
|
makeSmoke(x, y, z, it.otmRandom, it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,8 +208,6 @@ object MNames {
|
|||||||
const val BREAD_MONSTER_SPAWN_EGG = "bead_monster_spawn_egg"
|
const val BREAD_MONSTER_SPAWN_EGG = "bead_monster_spawn_egg"
|
||||||
const val LOADER_SPAWN_EGG = "loader_spawn_egg"
|
const val LOADER_SPAWN_EGG = "loader_spawn_egg"
|
||||||
|
|
||||||
const val CLEANER_DRONE_KIT = "cleaner_drone_kit"
|
|
||||||
|
|
||||||
const val ANDROID_MELEE_SPAWN_EGG = "android_melee_spawn_egg"
|
const val ANDROID_MELEE_SPAWN_EGG = "android_melee_spawn_egg"
|
||||||
|
|
||||||
// items: crafting components
|
// items: crafting components
|
||||||
@ -342,8 +340,6 @@ object MNames {
|
|||||||
const val ANDROID_RANGED = "android_ranged"
|
const val ANDROID_RANGED = "android_ranged"
|
||||||
const val ANDROID_OVERSEER = "android_overseer"
|
const val ANDROID_OVERSEER = "android_overseer"
|
||||||
|
|
||||||
const val ENFORCER = "enforcer"
|
|
||||||
|
|
||||||
const val PHANTOM_ATTRACTOR = "phantom_attractor"
|
const val PHANTOM_ATTRACTOR = "phantom_attractor"
|
||||||
const val JUMP_BOOST = "jump_boost"
|
const val JUMP_BOOST = "jump_boost"
|
||||||
const val ENDER_TELEPORTER = "ender_teleporter"
|
const val ENDER_TELEPORTER = "ender_teleporter"
|
||||||
|
@ -13,7 +13,11 @@ import net.minecraft.world.item.DyeColor
|
|||||||
import net.neoforged.bus.api.IEventBus
|
import net.neoforged.bus.api.IEventBus
|
||||||
import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent
|
import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent
|
||||||
import net.neoforged.neoforge.event.entity.EntityAttributeCreationEvent
|
import net.neoforged.neoforge.event.entity.EntityAttributeCreationEvent
|
||||||
import ru.dbotthepony.mc.otm.client.render.entity.*
|
import ru.dbotthepony.mc.otm.client.render.entity.BreadMonsterRenderer
|
||||||
|
import ru.dbotthepony.mc.otm.client.render.entity.LoaderRenderer
|
||||||
|
import ru.dbotthepony.mc.otm.client.render.entity.CleanerRenderer
|
||||||
|
import ru.dbotthepony.mc.otm.client.render.entity.PlasmaProjectileRenderer
|
||||||
|
import ru.dbotthepony.mc.otm.client.render.entity.RogueAndroidRenderer
|
||||||
import ru.dbotthepony.mc.otm.entity.*
|
import ru.dbotthepony.mc.otm.entity.*
|
||||||
import ru.dbotthepony.mc.otm.registry.MDeferredRegister
|
import ru.dbotthepony.mc.otm.registry.MDeferredRegister
|
||||||
import ru.dbotthepony.mc.otm.registry.MNames
|
import ru.dbotthepony.mc.otm.registry.MNames
|
||||||
@ -25,7 +29,6 @@ object MEntityTypes {
|
|||||||
EntityType.Builder.of({ _, level -> PlasmaProjectile(level) }, MobCategory.MISC).sized(0.4f, 0.4f).build(MNames.PLASMA)
|
EntityType.Builder.of({ _, level -> PlasmaProjectile(level) }, MobCategory.MISC).sized(0.4f, 0.4f).build(MNames.PLASMA)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
val CARGO_CRATE_MINECARTS: Map<DyeColor?, EntityType<MinecartCargoCrate>> = registry.coloredWithBase(MNames.MINECART_CARGO_CRATE) { color ->
|
val CARGO_CRATE_MINECARTS: Map<DyeColor?, EntityType<MinecartCargoCrate>> = registry.coloredWithBase(MNames.MINECART_CARGO_CRATE) { color ->
|
||||||
EntityType.Builder.of({ it, level -> MinecartCargoCrate(it, color, level)}, MobCategory.MISC).sized(0.98F, 0.7F).clientTrackingRange(8).build("dfu doesn't works ✅")
|
EntityType.Builder.of({ it, level -> MinecartCargoCrate(it, color, level)}, MobCategory.MISC).sized(0.98F, 0.7F).clientTrackingRange(8).build("dfu doesn't works ✅")
|
||||||
}
|
}
|
||||||
@ -74,14 +77,6 @@ object MEntityTypes {
|
|||||||
.build(MNames.ANDROID_MELEE)
|
.build(MNames.ANDROID_MELEE)
|
||||||
}
|
}
|
||||||
|
|
||||||
val ENFORCER: EntityType<Enforcer> by registry.register(MNames.ENFORCER) {
|
|
||||||
EntityType.Builder.of(::Enforcer, MobCategory.MONSTER)
|
|
||||||
.sized(2.4f, 2.5f)
|
|
||||||
.eyeHeight(2.0f)
|
|
||||||
.passengerAttachments(2.5f)
|
|
||||||
.clientTrackingRange(12)
|
|
||||||
.build(MNames.ENFORCER)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun register(bus: IEventBus) {
|
fun register(bus: IEventBus) {
|
||||||
registry.register(bus)
|
registry.register(bus)
|
||||||
@ -95,8 +90,6 @@ object MEntityTypes {
|
|||||||
|
|
||||||
event.put(ANDROID_MELEE, AndroidMelee.createAttributes().build())
|
event.put(ANDROID_MELEE, AndroidMelee.createAttributes().build())
|
||||||
|
|
||||||
event.put(ENFORCER, Enforcer.createAttributes().build())
|
|
||||||
|
|
||||||
event.put(CLEANER, Cleaner.createAttributes().build())
|
event.put(CLEANER, Cleaner.createAttributes().build())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,8 +108,6 @@ object MEntityTypes {
|
|||||||
|
|
||||||
EntityRenderers.register(CLEANER, ::CleanerRenderer)
|
EntityRenderers.register(CLEANER, ::CleanerRenderer)
|
||||||
|
|
||||||
EntityRenderers.register(ENFORCER, ::EnforcerRenderer)
|
|
||||||
|
|
||||||
EntityRenderers.register(ANDROID_MELEE) { context ->
|
EntityRenderers.register(ANDROID_MELEE) { context ->
|
||||||
RogueAndroidRenderer(context, ANDROID_MELEE, "melee",context.modelManager)
|
RogueAndroidRenderer(context, ANDROID_MELEE, "melee",context.modelManager)
|
||||||
}
|
}
|
||||||
|
@ -678,9 +678,6 @@ object MItems {
|
|||||||
|
|
||||||
val BREAD_MONSTER_SPAWN_EGG: Item by registry.register(MNames.BREAD_MONSTER_SPAWN_EGG){ SpawnEggItem(MEntityTypes.BREAD_MONSTER, 0xFFFFFF, 0xFFFFFF, Item.Properties())}
|
val BREAD_MONSTER_SPAWN_EGG: Item by registry.register(MNames.BREAD_MONSTER_SPAWN_EGG){ SpawnEggItem(MEntityTypes.BREAD_MONSTER, 0xFFFFFF, 0xFFFFFF, Item.Properties())}
|
||||||
val LOADER_SPAWN_EGG: Item by registry.register(MNames.LOADER_SPAWN_EGG){ SpawnEggItem(MEntityTypes.LOADER, 0xFFFFFF, 0xFFFFFF, Item.Properties())}
|
val LOADER_SPAWN_EGG: Item by registry.register(MNames.LOADER_SPAWN_EGG){ SpawnEggItem(MEntityTypes.LOADER, 0xFFFFFF, 0xFFFFFF, Item.Properties())}
|
||||||
|
|
||||||
val CLEANER_DRONE_KIT: Item by registry.register(MNames.CLEANER_DRONE_KIT){ SpawnEggItem(MEntityTypes.CLEANER, 0xFFFFFF, 0xFFFFFF, Item.Properties())}
|
|
||||||
|
|
||||||
val ANDROID_MELEE_SPAWN_EGG: Item by registry.register(MNames.ANDROID_MELEE_SPAWN_EGG){ SpawnEggItem(MEntityTypes.ANDROID_MELEE, 0xFFFFFF, 0xFFFFFF, Item.Properties())}
|
val ANDROID_MELEE_SPAWN_EGG: Item by registry.register(MNames.ANDROID_MELEE_SPAWN_EGG){ SpawnEggItem(MEntityTypes.ANDROID_MELEE, 0xFFFFFF, 0xFFFFFF, Item.Properties())}
|
||||||
|
|
||||||
val ROFLITE_ALLOY_INGOT: Item by registry.register(MNames.ROFLITE_ALLOY_INGOT) { Item(DEFAULT_PROPERTIES) }
|
val ROFLITE_ALLOY_INGOT: Item by registry.register(MNames.ROFLITE_ALLOY_INGOT) { Item(DEFAULT_PROPERTIES) }
|
||||||
|
75
src/main/resources/assets/overdrive_that_matters/loader.java
Normal file
75
src/main/resources/assets/overdrive_that_matters/loader.java
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
// Made with Blockbench 4.12.3
|
||||||
|
// Exported for Minecraft version 1.17 or later with Mojang mappings
|
||||||
|
// Paste this class into your mod and generate all required imports
|
||||||
|
|
||||||
|
|
||||||
|
public class loader<T extends Entity> extends EntityModel<T> {
|
||||||
|
// This layer location should be baked with EntityRendererProvider.Context in the entity renderer and passed into this model's constructor
|
||||||
|
public static final ModelLayerLocation LAYER_LOCATION = new ModelLayerLocation(new ResourceLocation("modid", "loader"), "main");
|
||||||
|
private final ModelPart root;
|
||||||
|
private final ModelPart Head;
|
||||||
|
private final ModelPart Body;
|
||||||
|
private final ModelPart LeftLeg;
|
||||||
|
private final ModelPart RightLeg;
|
||||||
|
private final ModelPart LeftArm;
|
||||||
|
private final ModelPart ElbowL;
|
||||||
|
private final ModelPart RightArm;
|
||||||
|
private final ModelPart ElbowR;
|
||||||
|
|
||||||
|
public loader(ModelPart root) {
|
||||||
|
this.root = root.getChild("root");
|
||||||
|
this.Head = this.root.getChild("Head");
|
||||||
|
this.Body = this.root.getChild("Body");
|
||||||
|
this.LeftLeg = this.root.getChild("LeftLeg");
|
||||||
|
this.RightLeg = this.root.getChild("RightLeg");
|
||||||
|
this.LeftArm = this.root.getChild("LeftArm");
|
||||||
|
this.ElbowL = this.LeftArm.getChild("ElbowL");
|
||||||
|
this.RightArm = this.root.getChild("RightArm");
|
||||||
|
this.ElbowR = this.RightArm.getChild("ElbowR");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LayerDefinition createBodyLayer() {
|
||||||
|
MeshDefinition meshdefinition = new MeshDefinition();
|
||||||
|
PartDefinition partdefinition = meshdefinition.getRoot();
|
||||||
|
|
||||||
|
PartDefinition root = partdefinition.addOrReplaceChild("root", CubeListBuilder.create(), PartPose.offset(0.0F, 24.0F, 0.0F));
|
||||||
|
|
||||||
|
PartDefinition Head = root.addOrReplaceChild("Head", CubeListBuilder.create().texOffs(48, 23).addBox(-3.0F, -1.0F, -2.0F, 6.0F, 3.0F, 3.0F, new CubeDeformation(0.0F)), PartPose.offset(-4.0F, -32.0F, -5.0F));
|
||||||
|
|
||||||
|
PartDefinition Body = root.addOrReplaceChild("Body", CubeListBuilder.create().texOffs(0, 0).addBox(-10.0F, -16.0F, -5.0F, 20.0F, 10.0F, 13.0F, new CubeDeformation(0.0F))
|
||||||
|
.texOffs(0, 50).addBox(-3.0F, -3.0F, -4.0F, 6.0F, 5.0F, 8.0F, new CubeDeformation(0.0F))
|
||||||
|
.texOffs(112, 52).addBox(10.0F, -13.0F, 0.0F, 2.0F, 6.0F, 6.0F, new CubeDeformation(0.0F))
|
||||||
|
.texOffs(96, 52).addBox(-12.0F, -13.0F, -1.0F, 2.0F, 6.0F, 6.0F, new CubeDeformation(0.0F))
|
||||||
|
.texOffs(53, 0).addBox(-5.0F, -1.0F, 4.0F, 10.0F, 4.0F, 4.0F, new CubeDeformation(0.0F)), PartPose.offset(0.0F, -26.0F, -1.0F));
|
||||||
|
|
||||||
|
PartDefinition antenna_r1 = Body.addOrReplaceChild("antenna_r1", CubeListBuilder.create().texOffs(76, 6).addBox(0.0F, -7.0F, -1.0F, 0.0F, 14.0F, 2.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(8.0F, -22.0F, 8.0F, -0.2618F, 0.0F, 0.0F));
|
||||||
|
|
||||||
|
PartDefinition waist_r1 = Body.addOrReplaceChild("waist_r1", CubeListBuilder.create().texOffs(28, 50).addBox(-2.0F, -5.0F, -4.0F, 4.0F, 7.0F, 7.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(0.0F, -3.0F, 2.0F, -0.2618F, 0.0F, 0.0F));
|
||||||
|
|
||||||
|
PartDefinition LeftLeg = root.addOrReplaceChild("LeftLeg", CubeListBuilder.create().texOffs(106, 24).addBox(0.0F, 10.0F, -2.0F, 4.0F, 16.0F, 7.0F, new CubeDeformation(0.0F))
|
||||||
|
.texOffs(66, 46).addBox(-1.0F, -2.0F, -3.0F, 6.0F, 12.0F, 6.0F, new CubeDeformation(0.0F)), PartPose.offset(4.0F, -26.0F, -1.0F));
|
||||||
|
|
||||||
|
PartDefinition RightLeg = root.addOrReplaceChild("RightLeg", CubeListBuilder.create().texOffs(84, 24).addBox(-4.0F, 10.0F, -2.0F, 4.0F, 16.0F, 7.0F, new CubeDeformation(0.0F))
|
||||||
|
.texOffs(48, 34).addBox(-5.0F, -2.0F, -3.0F, 6.0F, 12.0F, 6.0F, new CubeDeformation(0.0F)), PartPose.offset(-4.0F, -26.0F, -1.0F));
|
||||||
|
|
||||||
|
PartDefinition LeftArm = root.addOrReplaceChild("LeftArm", CubeListBuilder.create().texOffs(104, 0).addBox(-1.0F, -7.0F, -4.0F, 4.0F, 16.0F, 8.0F, new CubeDeformation(0.0F)), PartPose.offset(13.0F, -36.0F, 2.0F));
|
||||||
|
|
||||||
|
PartDefinition ElbowL = LeftArm.addOrReplaceChild("ElbowL", CubeListBuilder.create().texOffs(24, 23).addBox(-2.0F, -0.2F, -2.0F, 4.0F, 19.0F, 8.0F, new CubeDeformation(-0.1F)), PartPose.offset(1.0F, 9.0F, -1.0F));
|
||||||
|
|
||||||
|
PartDefinition RightArm = root.addOrReplaceChild("RightArm", CubeListBuilder.create().texOffs(80, 0).addBox(-3.0F, -7.0F, -4.0F, 4.0F, 16.0F, 8.0F, new CubeDeformation(0.0F)), PartPose.offset(-13.0F, -36.0F, 1.0F));
|
||||||
|
|
||||||
|
PartDefinition ElbowR = RightArm.addOrReplaceChild("ElbowR", CubeListBuilder.create().texOffs(0, 23).addBox(-2.0F, -0.2F, -2.0F, 4.0F, 19.0F, 8.0F, new CubeDeformation(-0.1F)), PartPose.offset(-1.0F, 9.0F, -1.0F));
|
||||||
|
|
||||||
|
return LayerDefinition.create(meshdefinition, 128, 64);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setupAnim(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void renderToBuffer(PoseStack poseStack, VertexConsumer vertexConsumer, int packedLight, int packedOverlay, float red, float green, float blue, float alpha) {
|
||||||
|
root.render(poseStack, vertexConsumer, packedLight, packedOverlay, red, green, blue, alpha);
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
Before Width: | Height: | Size: 6.1 KiB |
Binary file not shown.
Before Width: | Height: | Size: 711 B |
Binary file not shown.
Before Width: | Height: | Size: 241 B |
Binary file not shown.
Before Width: | Height: | Size: 513 B |
@ -17,14 +17,7 @@
|
|||||||
"spawn_overrides": {
|
"spawn_overrides": {
|
||||||
"ambient": {
|
"ambient": {
|
||||||
"bounding_box": "piece",
|
"bounding_box": "piece",
|
||||||
"spawns": [
|
"spawns": []
|
||||||
{
|
|
||||||
"type": "overdrive_that_matters:cleaner",
|
|
||||||
"maxCount": 1,
|
|
||||||
"minCount": 1,
|
|
||||||
"weight": 1
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"monster": {
|
"monster": {
|
||||||
"bounding_box": "piece",
|
"bounding_box": "piece",
|
||||||
|
@ -18,7 +18,8 @@
|
|||||||
"HopperBlockEntityMixin",
|
"HopperBlockEntityMixin",
|
||||||
"DispenserBlockEntityMixin",
|
"DispenserBlockEntityMixin",
|
||||||
"GuiGraphicsMixin",
|
"GuiGraphicsMixin",
|
||||||
"BlockStateBaseMixin"
|
"BlockStateBaseMixin",
|
||||||
|
"LevelMixin"
|
||||||
],
|
],
|
||||||
"client": [
|
"client": [
|
||||||
"MixinGameRenderer",
|
"MixinGameRenderer",
|
||||||
|
Loading…
Reference in New Issue
Block a user