Skip to content

Commit

Permalink
Added "Raider" Behavioural characteristic (#4371)
Browse files Browse the repository at this point in the history
* Can spawns in Raid Option

* More Information in the help tips

* Improvement on the 1.19.4 code made by Goldorion (the improvement also needs to be added to 1.20.1)

Co-authored-by: Goldorion <[email protected]>

* Code Improvement made by Goldorion for 1.20.1

Co-authored-by: Goldorion <[email protected]>

* Some Fixes Part 1

* Fix

* Celebration Sound Added

* Fix

* Fix

* Fix

* Small Code Improvements

* Removed some extra code

* Some Fixes

* Fix

* Some Fixes

* Fix

* Fix

* Other Fixes

* Other minor fixes

* Fix

* Some Fixes

* Some Fixes

* Other Fixes

* Fix

* Welcome Arrays

* Updated to 1.20.4

* Deleted generator-1.19.4 gen

* Fix + Improvements

* Byte -> Int and a small change

* Some Fixes

* Some Fixes

* Fix a forgotten name

* Make ordering make more sense

* Proper way of UI, formatter

* We have enhanced for loops and array.length systems in Java to not hardcode array lengths

* Some things I asked previously but were forgotten..

* Duplicate code

* More minor changes

* Raider is not event tested in this PR properly...

* Some more fixes

* Fix NF 1.20.4

* Raiders Tag

* If empty input is allowed, it needs to be tested too

* Correct handling of empty celebration sound

* Fix Entity AI

* Bug Fix

* Fix

---------

Co-authored-by: Goldorion <[email protected]>
Co-authored-by: KlemenDEV <[email protected]>
  • Loading branch information
3 people committed May 29, 2024
1 parent ffae7a4 commit f3180cd
Show file tree
Hide file tree
Showing 11 changed files with 115 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ templates:

unmodifiable_ai_bases: [ Bat, MagmaCube, Slime ]

tags:
- tag: ENTITIES:minecraft:raiders
condition: "${data.mobBehaviourType == 'Raider'}"

localizationkeys:
- key: item.@modid.@registryname_spawn_egg
mapto: mobName
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,16 @@ public class ${name}Entity extends ${extendsClass} <#if data.ranged>implements R
}
</#if>

<#if data.mobBehaviourType == "Raider">
@Override public SoundEvent getCelebrateSound() {
<#if data.raidCelebrationSound?has_content && data.raidCelebrationSound.getMappedValue()?has_content>
return ForgeRegistries.SOUND_EVENTS.getValue(new ResourceLocation("${data.raidCelebrationSound}"));
<#else>
return SoundEvents.EMPTY;
</#if>
}
</#if>

<#if hasProcedure(data.onStruckByLightning)>
@Override public void thunderHit(ServerLevel serverWorld, LightningBolt lightningBolt) {
super.thunderHit(serverWorld, lightningBolt);
Expand Down Expand Up @@ -899,8 +909,16 @@ public class ${name}Entity extends ${extendsClass} <#if data.ranged>implements R
<#if data.spawnInDungeons>
DungeonHooks.addDungeonMob(${JavaModName}Entities.${data.getModElement().getRegistryNameUpper()}.get(), 180);
</#if>

<#if data.mobBehaviourType == "Raider">
Raid.RaiderType.create("${registryname}", ${JavaModName}Entities.${data.getModElement().getRegistryNameUpper()}.get(), new int[]{0, ${data.raidSpawnsCount[0]}, ${data.raidSpawnsCount[1]}, ${data.raidSpawnsCount[2]}, ${data.raidSpawnsCount[3]}, ${data.raidSpawnsCount[4]}, ${data.raidSpawnsCount[5]}, ${data.raidSpawnsCount[6]}});
</#if>
}

<#if data.mobBehaviourType == "Raider">
@Override public void applyRaidBuffs(int num, boolean logic) {}
</#if>

public static AttributeSupplier.Builder createAttributes() {
AttributeSupplier.Builder builder = Mob.createMobAttributes();
builder = builder.add(Attributes.MOVEMENT_SPEED, ${data.movementSpeed});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ templates:

unmodifiable_ai_bases: [ Bat, MagmaCube, Slime ]

tags:
- tag: ENTITIES:minecraft:raiders
condition: "${data.mobBehaviourType == 'Raider'}"

localizationkeys:
- key: item.@modid.@registryname_spawn_egg
mapto: mobName
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,16 @@ public class ${name}Entity extends ${extendsClass} <#if data.ranged>implements R
}
</#if>

<#if data.mobBehaviourType == "Raider">
@Override public SoundEvent getCelebrateSound() {
<#if data.raidCelebrationSound?has_content && data.raidCelebrationSound.getMappedValue()?has_content>
return BuiltInRegistries.SOUND_EVENT.get(new ResourceLocation("${data.raidCelebrationSound}"));
<#else>
return SoundEvents.EMPTY;
</#if>
}
</#if>

<#if hasProcedure(data.onStruckByLightning)>
@Override public void thunderHit(ServerLevel serverWorld, LightningBolt lightningBolt) {
super.thunderHit(serverWorld, lightningBolt);
Expand Down Expand Up @@ -889,8 +899,16 @@ public class ${name}Entity extends ${extendsClass} <#if data.ranged>implements R
<#if data.spawnInDungeons>
DungeonHooks.addDungeonMob(${JavaModName}Entities.${data.getModElement().getRegistryNameUpper()}.get(), 180);
</#if>

<#if data.mobBehaviourType == "Raider">
Raid.RaiderType.create("${registryname}", ${JavaModName}Entities.${data.getModElement().getRegistryNameUpper()}.get(), new int[]{0, ${data.raidSpawnsCount[0]}, ${data.raidSpawnsCount[1]}, ${data.raidSpawnsCount[2]}, ${data.raidSpawnsCount[3]}, ${data.raidSpawnsCount[4]}, ${data.raidSpawnsCount[5]}, ${data.raidSpawnsCount[6]}});
</#if>
}

<#if data.mobBehaviourType == "Raider">
@Override public void applyRaidBuffs(int num, boolean logic) {}
</#if>

public static AttributeSupplier.Builder createAttributes() {
AttributeSupplier.Builder builder = Mob.createMobAttributes();
builder = builder.add(Attributes.MOVEMENT_SPEED, ${data.movementSpeed});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
Living entity set to Mob will be able to attack, while a living entity set to Creature will be passive.

A Raider is a monster that spawns in a raid.

This parameter is overridden by the AI base when used.

Keep in mind that if you select Creature type here, attack AI types will make the entity crash the game in most cases.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
This sound will be played if the entity wins the raid.

Each Raider will play their own celebratory sound at the end of the raid.

The sound is selectable if the entity is a raider type.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Here you can set how many times the entity will spawn in each raid wave.

Depending on the difficulty there will be a certain number of waves:

* Peaceful: 0
* Easy: 3
* Normal: 5
* Hard: 7

The number of entities generated per raid wave are selectable if the entity is a raider type.
4 changes: 3 additions & 1 deletion plugins/mcreator-localization/lang/texts.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2551,7 +2551,7 @@ elementgui.living_entity.event_initial_spawn=On initial entity spawn
elementgui.living_entity.condition_natural_spawn=Natural entity spawning condition
elementgui.living_entity.condition_is_model_transparent=Is entity model transparent?
elementgui.living_entity.condition_is_shaking=Is entity model shaking?
elementgui.living_entity.behaviour=<html>Behavioral characteristics (Mob is aggressive, Creature is passive):
elementgui.living_entity.behaviour=<html>Behavioral characteristics:
elementgui.living_entity.creature_type=<html>Creature type (defines some special entity attributes):
elementgui.living_entity.drop_health_xp_amount=Optional drop, health value, experience amount:
elementgui.living_entity.model_layers=Model layers list
Expand Down Expand Up @@ -2613,6 +2613,8 @@ elementgui.living_entity.page_behaviour=Behavior
elementgui.living_entity.page_entity_data=Synced data
elementgui.living_entity.page_ai_and_goals=AI and goals
elementgui.living_entity.page_spawning=Spawning
elementgui.living_entity.raid_celebration_sound=Raider celebration sound:
elementgui.living_entity.raid_spawns_counts=<html>Number of entities generated per raid wave:<br><small>First, Second, Third, Fourth, Fifth, Sixth, Seventh wave<br>
elementgui.loot_table.registry_name=<html>Loot table registry name:<br><small>Use prefix such as blocks/ to specify category
elementgui.loot_table.namespace=<html>Loot table namespace:<br><small>Use minecraft namespace to alter vanilla loot tables
elementgui.loot_table.type=Loot table type:
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/net/mcreator/element/types/LivingEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@
public Sound hurtSound;
public Sound deathSound;
public Sound stepSound;
public Sound raidCelebrationSound;

public List<PropertyDataWithValue<?>> entityDataEntries;

Expand Down Expand Up @@ -175,6 +176,7 @@
public int maxNumberOfMobsPerGroup;
@ModElementReference public List<BiomeEntry> restrictionBiomes;
public boolean spawnInDungeons;
public int[] raidSpawnsCount;

private LivingEntity() {
this(null);
Expand All @@ -197,6 +199,8 @@ public LivingEntity(ModElement element) {

this.entityDataEntries = new ArrayList<>();
this.modelLayers = new ArrayList<>();

this.raidSpawnsCount = new int[] {4, 3, 3, 4, 4, 4, 2};
}

@Override @Nullable public Model getEntityModel() {
Expand Down
44 changes: 41 additions & 3 deletions src/main/java/net/mcreator/ui/modgui/LivingEntityGUI.java
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ public class LivingEntityGUI extends ModElementGUI<LivingEntity> implements IBlo
private final SoundSelector hurtSound = new SoundSelector(mcreator);
private final SoundSelector deathSound = new SoundSelector(mcreator);
private final SoundSelector stepSound = new SoundSelector(mcreator);
private final SoundSelector raidCelebrationSound = new SoundSelector(mcreator);

private final VTextField mobName = new VTextField();

Expand Down Expand Up @@ -209,7 +210,7 @@ public class LivingEntityGUI extends ModElementGUI<LivingEntity> implements IBlo
"Pig", "Villager", "Wolf", "Cow", "Bat", "Chicken", "Ocelot", "Squid", "Horse", "Spider",
"IronGolem").sorted().toArray(String[]::new));

private final JComboBox<String> mobBehaviourType = new JComboBox<>(new String[] { "Mob", "Creature" });
private final JComboBox<String> mobBehaviourType = new JComboBox<>(new String[] { "Mob", "Creature", "Raider" });
private final JComboBox<String> mobCreatureType = new JComboBox<>(
new String[] { "UNDEFINED", "UNDEAD", "ARTHROPOD", "ILLAGER", "WATER" });
private final JComboBox<String> bossBarColor = new JComboBox<>(
Expand All @@ -233,6 +234,11 @@ public class LivingEntityGUI extends ModElementGUI<LivingEntity> implements IBlo
private final JCheckBox spawnThisMob = new JCheckBox();
private final JCheckBox doesDespawnWhenIdle = new JCheckBox();

private final JSpinner[] raidSpawnsCount = new JSpinner[] { new JSpinner(new SpinnerNumberModel(4, 0, 1000, 1)),
new JSpinner(new SpinnerNumberModel(3, 0, 1000, 1)), new JSpinner(new SpinnerNumberModel(3, 0, 1000, 1)),
new JSpinner(new SpinnerNumberModel(4, 0, 1000, 1)), new JSpinner(new SpinnerNumberModel(4, 0, 1000, 1)),
new JSpinner(new SpinnerNumberModel(4, 0, 1000, 1)), new JSpinner(new SpinnerNumberModel(2, 0, 1000, 1)) };

private BiomeListField restrictionBiomes;

private BlocklyPanel blocklyPanel;
Expand Down Expand Up @@ -675,7 +681,7 @@ private synchronized void regenerateAITasks() {
pane8.setOpaque(false);
pane8.add(layerList);

JPanel spo6 = new JPanel(new GridLayout(4, 2, 2, 2));
JPanel spo6 = new JPanel(new GridLayout(5, 2, 2, 2));
spo6.setOpaque(false);

spo6.add(HelpUtils.wrapWithHelpButton(this.withEntry("entity/sound"),
Expand All @@ -694,6 +700,10 @@ private synchronized void regenerateAITasks() {
L10N.label("elementgui.living_entity.death_sound")));
spo6.add(deathSound);

spo6.add(HelpUtils.wrapWithHelpButton(this.withEntry("entity/raid_celebration_sound"),
L10N.label("elementgui.living_entity.raid_celebration_sound")));
spo6.add(raidCelebrationSound);

pane6.setOpaque(false);
pane6.add("Center", PanelUtils.totalCenterInPanel(spo6));

Expand Down Expand Up @@ -779,6 +789,7 @@ private synchronized void regenerateAITasks() {

hasAI.setSelected(true);

mobBehaviourType.addActionListener(actionEvent -> enableOrDisableFields());
breedable.addActionListener(actionEvent -> enableOrDisableFields());
isBoss.addActionListener(e -> enableOrDisableFields());

Expand All @@ -801,7 +812,7 @@ private synchronized void regenerateAITasks() {

pane4.setOpaque(false);

JPanel selp = new JPanel(new GridLayout(7, 2, 30, 2));
JPanel selp = new JPanel(new GridLayout(8, 2, 30, 2));
selp.setOpaque(false);

ComponentUtils.deriveFont(mobName, 16);
Expand Down Expand Up @@ -842,6 +853,14 @@ private synchronized void regenerateAITasks() {
L10N.label("elementgui.living_entity.does_spawn_in_dungeons")));
selp.add(spawnInDungeons);

selp.add(HelpUtils.wrapWithHelpButton(this.withEntry("entity/raid_spawns_counts"),
L10N.label("elementgui.living_entity.raid_spawns_counts")));
selp.add(PanelUtils.gridElements(1, -1, 2, 2, raidSpawnsCount[0], raidSpawnsCount[1], raidSpawnsCount[2],
raidSpawnsCount[3], raidSpawnsCount[4], raidSpawnsCount[5], raidSpawnsCount[6]));

for (JSpinner spinner : raidSpawnsCount)
spinner.setPreferredSize(new Dimension(40, 0));

JComponent selpcont = PanelUtils.northAndCenterElement(selp, PanelUtils.gridElements(1, 2, 30, 2,
PanelUtils.join(FlowLayout.LEFT, 5, 0, L10N.label("elementgui.living_entity.spawn_general_condition")),
spawningCondition), 5, 5);
Expand Down Expand Up @@ -957,6 +976,19 @@ private synchronized void regenerateAITasks() {
}

private void enableOrDisableFields() {
boolean isRaider = "Raider".equals(mobBehaviourType.getSelectedItem());
if (isRaider) {
breedable.setSelected(false);
aiBase.setSelectedItem("(none)");
}

raidCelebrationSound.setEnabled(isRaider);
for (JSpinner spinner : raidSpawnsCount)
spinner.setEnabled(isRaider);
breedable.setEnabled(!isRaider);
aiBase.setEnabled(!isRaider);
tameable.setEnabled(!isRaider);

if (breedable.isSelected()) {
hasAI.setSelected(true);
hasAI.setEnabled(false);
Expand Down Expand Up @@ -1033,6 +1065,7 @@ private void enableOrDisableFields() {
hurtSound.setSound(livingEntity.hurtSound);
deathSound.setSound(livingEntity.deathSound);
stepSound.setSound(livingEntity.stepSound);
raidCelebrationSound.setSound(livingEntity.raidCelebrationSound);
hasAI.setSelected(livingEntity.hasAI);
isBoss.setSelected(livingEntity.isBoss);
hasSpawnEgg.setSelected(livingEntity.hasSpawnEgg);
Expand Down Expand Up @@ -1071,6 +1104,8 @@ private void enableOrDisableFields() {
guiBoundTo.setSelectedItem(livingEntity.guiBoundTo);
inventorySize.setValue(livingEntity.inventorySize);
inventoryStackSize.setValue(livingEntity.inventoryStackSize);
for (int i = 0; i < livingEntity.raidSpawnsCount.length; i++)
raidSpawnsCount[i].setValue(livingEntity.raidSpawnsCount[i]);
modelLayers.setEntries(livingEntity.modelLayers);

entityDataList.setEntries(livingEntity.entityDataEntries);
Expand Down Expand Up @@ -1145,6 +1180,7 @@ private void enableOrDisableFields() {
livingEntity.hurtSound = hurtSound.getSound();
livingEntity.deathSound = deathSound.getSound();
livingEntity.stepSound = stepSound.getSound();
livingEntity.raidCelebrationSound = raidCelebrationSound.getSound();
livingEntity.spawningCondition = spawningCondition.getSelectedProcedure();
livingEntity.onStruckByLightning = onStruckByLightning.getSelectedProcedure();
livingEntity.whenMobFalls = whenMobFalls.getSelectedProcedure();
Expand Down Expand Up @@ -1189,6 +1225,8 @@ private void enableOrDisableFields() {
livingEntity.inventoryStackSize = (int) inventoryStackSize.getValue();
livingEntity.guiBoundTo = guiBoundTo.getSelectedItem();
livingEntity.entityDataEntries = entityDataList.getEntries();
for (int i = 0; i < livingEntity.raidSpawnsCount.length; i++)
livingEntity.raidSpawnsCount[i] = (int) raidSpawnsCount[i].getValue();
livingEntity.modelLayers = modelLayers.getEntries();
return livingEntity;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1621,7 +1621,7 @@ public static LivingEntity getLivingEntity(ModElement modElement, Random random,
getRandomMCItem(random, blocksAndItems).getName());
livingEntity.equipmentBoots = new MItemBlock(modElement.getWorkspace(),
getRandomMCItem(random, blocksAndItems).getName());
livingEntity.mobBehaviourType = _true ? "Creature" : "Mob";
livingEntity.mobBehaviourType = getRandomString(random, List.of("Creature", "Mob", "Raider"));
livingEntity.mobCreatureType = getRandomItem(random,
new String[] { "UNDEFINED", "UNDEAD", "ARTHROPOD", "ILLAGER", "WATER" });
livingEntity.attackStrength = 4;
Expand Down Expand Up @@ -1672,6 +1672,8 @@ public static LivingEntity getLivingEntity(ModElement modElement, Random random,
getRandomItem(random, ElementUtil.getAllSounds(modElement.getWorkspace())));
livingEntity.stepSound = new Sound(modElement.getWorkspace(),
emptyLists ? "" : getRandomItem(random, ElementUtil.getAllSounds(modElement.getWorkspace())));
livingEntity.raidCelebrationSound = new Sound(modElement.getWorkspace(),
emptyLists ? "" : getRandomItem(random, ElementUtil.getAllSounds(modElement.getWorkspace())));
livingEntity.rangedItemType = "Default item";
if (!emptyLists) {
livingEntity.spawningCondition = new Procedure("condition3");
Expand All @@ -1688,7 +1690,7 @@ public static LivingEntity getLivingEntity(ModElement modElement, Random random,
livingEntity.hasAI = _true;
livingEntity.aiBase = "(none)";
livingEntity.aixml = "<xml xmlns=\"https://developers.google.com/blockly/xml\"><block type=\"aitasks_container\" deletable=\"false\" x=\"40\" y=\"40\"></block></xml>";
livingEntity.breedable = _true;
livingEntity.breedable = _true && !livingEntity.mobBehaviourType.equals("Raider");
livingEntity.tameable = _true;
livingEntity.breedTriggerItems = new ArrayList<>();
if (!emptyLists) {
Expand Down Expand Up @@ -1728,6 +1730,8 @@ public static LivingEntity getLivingEntity(ModElement modElement, Random random,
livingEntity.modelHeight = 1.3;
livingEntity.mountedYOffset = -3.1;
livingEntity.modelShadowSize = 1.8;
for (int i = 0; i < livingEntity.raidSpawnsCount.length; i++)
livingEntity.raidSpawnsCount[i] = (4 + i);
livingEntity.modelLayers = new ArrayList<>();
if (!emptyLists) {
livingEntity.entityDataEntries.add(new PropertyDataWithValue<>(new PropertyData.LogicType("Logic"), _true));
Expand Down

0 comments on commit f3180cd

Please sign in to comment.