Skip to content

Commit 38378cb

Browse files
committed
feat: 0.3.0 release
1 parent 8420cc8 commit 38378cb

File tree

23 files changed

+626
-27
lines changed

23 files changed

+626
-27
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
# 0.3.0
2+
## Features
3+
- Add **Hiyori Boss**, which can be summoned by striking Hiyori with lightning. Hiyori Boss has 3 ultimate moves: summon **Swarm Drones**, summon **Gymbags**, and summon lightning bolts.
4+
- Iron Cow has cooldown of 5 minutes, because Iron Milk is too overpowered.
5+
16
# 0.2.4
27
## Features
38
- [Neuro-sama's house](https://cdn.discordapp.com/attachments/1072697081443131476/1153341266331975760/image.png) can generate in the world

common/src/main/java/jimenezli/neuro21/client/renderer/entity/GymbagRenderer.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,42 @@
11
package jimenezli.neuro21.client.renderer.entity;
22

3+
import com.mojang.blaze3d.vertex.PoseStack;
34
import jimenezli.neuro21.client.model.GymbagModel;
45
import jimenezli.neuro21.client.model.geom.Neuro21ModelLayers;
56
import jimenezli.neuro21.entity.boss.hiyori.GymbagEntity;
67
import net.minecraft.client.renderer.entity.EntityRendererProvider;
78
import net.minecraft.client.renderer.entity.MobRenderer;
89
import net.minecraft.resources.ResourceLocation;
10+
import net.minecraft.util.Mth;
911

1012
import static jimenezli.neuro21.Neuro21Mod.prefix;
1113

14+
/**
15+
* Most of the code is copied from Creeper.
16+
*/
1217
public class GymbagRenderer extends MobRenderer<GymbagEntity, GymbagModel<GymbagEntity>> {
1318
private static final ResourceLocation GYMBAG = prefix("textures/entity/gymbag.png");
1419

1520
public GymbagRenderer(EntityRendererProvider.Context context) {
1621
super(context, new GymbagModel<>(context.bakeLayer(Neuro21ModelLayers.GYMBAG)), 0.5f);
1722
}
1823

24+
protected void scale(GymbagEntity gymbag, PoseStack poseStack, float f) {
25+
float g = gymbag.getSwelling(f);
26+
float h = 1.0F + Mth.sin(g * 100.0F) * g * 0.01F;
27+
g = Mth.clamp(g, 0.0F, 1.0F);
28+
g *= g;
29+
g *= g;
30+
float i = (1.0F + g * 0.4F) * h;
31+
float j = (1.0F + g * 0.1F) / h;
32+
poseStack.scale(i, j, i);
33+
}
34+
35+
protected float getWhiteOverlayProgress(GymbagEntity gymbag, float f) {
36+
float g = gymbag.getSwelling(f);
37+
return (int)(g * 10.0F) % 2 == 0 ? 0.0F : Mth.clamp(g, 0.5F, 1.0F);
38+
}
39+
1940
@Override
2041
public ResourceLocation getTextureLocation(GymbagEntity entity) {
2142
return GYMBAG;

common/src/main/java/jimenezli/neuro21/client/renderer/entity/HiyoriBossRenderer.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import net.minecraft.client.model.HumanoidModel;
77
import net.minecraft.client.model.PlayerModel;
88
import net.minecraft.client.model.geom.ModelLayers;
9-
import net.minecraft.client.renderer.MultiBufferSource;
109
import net.minecraft.client.renderer.entity.EntityRendererProvider;
1110
import net.minecraft.client.renderer.entity.HumanoidMobRenderer;
1211
import net.minecraft.client.renderer.entity.layers.HumanoidArmorLayer;
@@ -29,10 +28,6 @@ protected void scale(HiyoriBossEntity livingEntity, PoseStack poseStack, float f
2928
poseStack.scale(hiyoriBossScale, hiyoriBossScale, hiyoriBossScale);
3029
}
3130

32-
public void render(HiyoriBossEntity hiyoriBoss, float f, float g, PoseStack poseStack, MultiBufferSource multiBufferSource, int i) {
33-
super.render(hiyoriBoss, f, g, poseStack, multiBufferSource, i);
34-
}
35-
3631
public ResourceLocation getTextureLocation(HiyoriBossEntity hiyoriBoss) {
3732
return HIYORI_BOSS;
3833
}

common/src/main/java/jimenezli/neuro21/entity/HiyoriEntity.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
package jimenezli.neuro21.entity;
22

3+
import jimenezli.neuro21.entity.boss.hiyori.HiyoriBossEntity;
4+
import jimenezli.neuro21.handler.EntityHandler;
35
import jimenezli.neuro21.util.NeurosamaType;
6+
import net.minecraft.server.level.ServerLevel;
7+
import net.minecraft.world.Difficulty;
48
import net.minecraft.world.entity.EntityType;
9+
import net.minecraft.world.entity.LightningBolt;
510
import net.minecraft.world.entity.Mob;
11+
import net.minecraft.world.entity.MobSpawnType;
612
import net.minecraft.world.entity.ai.attributes.AttributeSupplier;
713
import net.minecraft.world.entity.ai.attributes.Attributes;
814
import net.minecraft.world.entity.animal.Animal;
@@ -21,4 +27,23 @@ public boolean isAbandoned() {
2127
public static AttributeSupplier.Builder createAttributes() {
2228
return Mob.createMobAttributes().add(Attributes.ATTACK_DAMAGE, 0.5D).add(Attributes.MOVEMENT_SPEED, 0.4).add(Attributes.MAX_HEALTH, 20.0);
2329
}
30+
31+
public void thunderHit(ServerLevel serverLevel, LightningBolt lightningBolt) {
32+
if (serverLevel.getDifficulty() != Difficulty.PEACEFUL) {
33+
HiyoriBossEntity hiyoriBossEntity = EntityHandler.HIYORI_BOSS.get().create(serverLevel);
34+
assert hiyoriBossEntity != null;
35+
hiyoriBossEntity.moveTo(this.getX(), this.getY(), this.getZ(), this.getYRot(), this.getXRot());
36+
hiyoriBossEntity.finalizeSpawn(serverLevel, serverLevel.getCurrentDifficultyAt(hiyoriBossEntity.blockPosition()), MobSpawnType.CONVERSION, null, null);
37+
hiyoriBossEntity.setNoAi(this.isNoAi());
38+
if (this.hasCustomName()) {
39+
hiyoriBossEntity.setCustomName(this.getCustomName());
40+
hiyoriBossEntity.setCustomNameVisible(this.isCustomNameVisible());
41+
}
42+
hiyoriBossEntity.setPersistenceRequired();
43+
serverLevel.addFreshEntityWithPassengers(hiyoriBossEntity);
44+
this.discard();
45+
} else {
46+
super.thunderHit(serverLevel, lightningBolt);
47+
}
48+
}
2449
}

common/src/main/java/jimenezli/neuro21/entity/IronCowEntity.java

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
import jimenezli.neuro21.entity.ai.goal.NeurosamaFamilyHurtByTargetGoal;
44
import jimenezli.neuro21.handler.ItemHandler;
5+
import net.minecraft.nbt.CompoundTag;
6+
import net.minecraft.network.chat.Component;
7+
import net.minecraft.network.syncher.EntityDataAccessor;
8+
import net.minecraft.network.syncher.EntityDataSerializers;
9+
import net.minecraft.network.syncher.SynchedEntityData;
510
import net.minecraft.sounds.SoundEvent;
611
import net.minecraft.sounds.SoundEvents;
712
import net.minecraft.world.InteractionHand;
@@ -19,11 +24,24 @@
1924
import net.minecraft.world.level.Level;
2025

2126
public class IronCowEntity extends Cow {
27+
private int nextMilkTicks;
28+
private static final EntityDataAccessor<Integer> DATA_NEXT_MILK_TICKS;
29+
2230
/**
2331
* I didn't override the breed method so iron cow's offsprings are normal cows.
2432
*/
2533
public IronCowEntity(EntityType<? extends Cow> entityType, Level level) {
2634
super(entityType, level);
35+
this.nextMilkTicks = 0;
36+
}
37+
38+
protected void defineSynchedData() {
39+
super.defineSynchedData();
40+
this.entityData.define(DATA_NEXT_MILK_TICKS, 0);
41+
}
42+
43+
static {
44+
DATA_NEXT_MILK_TICKS = SynchedEntityData.defineId(IronCowEntity.class, EntityDataSerializers.INT);
2745
}
2846

2947
public static AttributeSupplier.Builder createAttributes() {
@@ -34,9 +52,22 @@ public static AttributeSupplier.Builder createAttributes() {
3452
* Warning! if you attack the cow, the Neuro-sama family will attack you!
3553
*/
3654
public void registerGoals() {
55+
super.registerGoals();
3756
this.targetSelector.addGoal(1, new NeurosamaFamilyHurtByTargetGoal(this));
3857
}
3958

59+
public void readAdditionalSaveData(CompoundTag compoundTag) {
60+
super.readAdditionalSaveData(compoundTag);
61+
if (compoundTag.contains("NextMilkTicks")) {
62+
this.nextMilkTicks = compoundTag.getInt("NextMilkTicks");
63+
}
64+
}
65+
66+
public void addAdditionalSaveData(CompoundTag compoundTag) {
67+
super.addAdditionalSaveData(compoundTag);
68+
compoundTag.putInt("NextMilkTicks", this.nextMilkTicks);
69+
}
70+
4071
@Override
4172
protected SoundEvent getHurtSound(DamageSource damageSource) {
4273
return SoundEvents.IRON_GOLEM_HURT;
@@ -47,15 +78,31 @@ protected SoundEvent getDeathSound() {
4778
return SoundEvents.IRON_GOLEM_DEATH;
4879
}
4980

81+
public void aiStep() {
82+
super.aiStep();
83+
if (!this.level.isClientSide && this.isAlive() && !this.isBaby()) {
84+
this.entityData.set(DATA_NEXT_MILK_TICKS, --nextMilkTicks);
85+
}
86+
}
87+
5088
public InteractionResult mobInteract(Player player, InteractionHand interactionHand) {
5189
ItemStack itemStack = player.getItemInHand(interactionHand);
5290
if (itemStack.is(Items.BUCKET) && !this.isBaby()) {
53-
player.playSound(SoundEvents.COW_MILK, 1.0F, 1.0F);
54-
ItemStack itemStack2 = ItemUtils.createFilledResult(itemStack, player, new ItemStack(ItemHandler.IRONMILK.get()));
55-
player.setItemInHand(interactionHand, itemStack2);
56-
return InteractionResult.sidedSuccess(this.level.isClientSide);
57-
} else {
58-
return super.mobInteract(player, interactionHand);
91+
if (this.entityData.get(DATA_NEXT_MILK_TICKS) < 0) {
92+
if (!this.level.isClientSide) {
93+
nextMilkTicks = 6000;
94+
} else {
95+
this.entityData.set(DATA_NEXT_MILK_TICKS, 6000);
96+
}
97+
player.playSound(SoundEvents.COW_MILK, 1.0F, 1.0F);
98+
ItemStack itemStack2 = ItemUtils.createFilledResult(itemStack, player, new ItemStack(ItemHandler.IRONMILK.get()));
99+
player.setItemInHand(interactionHand, itemStack2);
100+
return InteractionResult.sidedSuccess(this.level.isClientSide);
101+
} else {
102+
player.displayClientMessage(Component.translatable("entity.neuro21.iron_cow.cooldown", Integer.valueOf(this.entityData.get(DATA_NEXT_MILK_TICKS) / 1200 + 1).toString()), true);
103+
return InteractionResult.PASS;
104+
}
59105
}
106+
return super.mobInteract(player, interactionHand);
60107
}
61108
}

0 commit comments

Comments
 (0)