Skip to content

Commit

Permalink
Implement new data points for entities
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexProgrammerDE committed Nov 19, 2024
1 parent 47dbd17 commit 0a029fe
Show file tree
Hide file tree
Showing 10 changed files with 1,734 additions and 164 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public class DataGenerators {
new EffectsJavaGenerator(),
new EntitiesJsonGenerator(),
new EntitiesJavaGenerator(),
new NamedEntityDataJavaGenerator(),
new ItemsJsonGenerator(),
new ItemsJavaGenerator(),
new AttributesJsonGenerator(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@

import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.soulfiremc.generator.util.FieldGenerationHelper;
import com.soulfiremc.generator.util.MCHelper;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntitySpawnReason;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.level.GameType;

import java.util.Locale;

public class EntitiesJsonGenerator implements IDataGenerator {

Expand All @@ -51,20 +51,19 @@ public static JsonObject generateEntity(EntityType<?> entityType) {
entityDesc.addProperty("summonable", true);
}

var defaultEntity = createEntity(entityType);
var defaultEntity = MCHelper.createEntity(entityType);
if (defaultEntity.isAttackable()) {
entityDesc.addProperty("attackable", true);
}

return entityDesc;
}

private static <T extends Entity> T createEntity(EntityType<T> entityType) {
if (entityType == EntityType.PLAYER) {
return entityType.tryCast(MCHelper.getGameTestHelper().makeMockPlayer(GameType.DEFAULT_MODE));
}
var inheritedClasses = new JsonArray();
Class<?> clazz = defaultEntity.getClass();
do {
inheritedClasses.add(FieldGenerationHelper.toSnakeCase(clazz.getSimpleName()).toLowerCase(Locale.ROOT));
} while ((clazz = clazz.getSuperclass()) != null && clazz != Object.class);
entityDesc.add("inheritedClasses", inheritedClasses);

return entityType.create(MCHelper.getLevel(), EntitySpawnReason.COMMAND);
return entityDesc;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* SoulFire
* Copyright (C) 2024 AlexProgrammerDE
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.soulfiremc.generator.generators;

import com.soulfiremc.generator.util.FieldGenerationHelper;
import com.soulfiremc.generator.util.GeneratorConstants;
import com.soulfiremc.generator.util.MCHelper;
import com.soulfiremc.generator.util.ResourceHelper;
import lombok.SneakyThrows;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.world.entity.EntityType;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.stream.Stream;

public class NamedEntityDataJavaGenerator implements IDataGenerator {
@Override
public String getDataName() {
return "java/NamedEntityData.java";
}

@Override
@SuppressWarnings("unchecked")
public String generateDataJson() {
var base = ResourceHelper.getResourceAsString("/templates/NamedEntityData.java");
return base.replace(
GeneratorConstants.VALUES_REPLACE,
String.join("\n ",
FieldGenerationHelper.mapFields(EntityType.class, EntityType.class)
.flatMap(f -> {
var defaultEntity = MCHelper.createEntity(f.value());
Class<?> clazz = defaultEntity.getClass();
Stream<String> fields = Stream.empty();

do {
fields = Stream.concat(fields, generateFields(clazz));
} while ((clazz = clazz.getSuperclass()) != null);

return fields;
})
.distinct()
.sorted()
.toArray(String[]::new)));
}

@SneakyThrows
private Stream<String> generateFields(Class<?> clazz) {
var className = FieldGenerationHelper.toSnakeCase(clazz.getSimpleName());

List<String> fields = new ArrayList<>();
for (var field : clazz.getDeclaredFields()) {
if (!EntityDataAccessor.class.isAssignableFrom(field.getType())) {
continue;
}

var dataName = field.getName();
var fieldPrefix = "DATA_";
if (dataName.startsWith(fieldPrefix)) {
dataName = dataName.substring(fieldPrefix.length());
}

field.setAccessible(true);
var dataValue = (EntityDataAccessor<?>) field.get(null);
fields.add("public static final NamedEntityData %s = register(\"%s\", %d, \"%s\");".formatted(
className + "__" + dataName,
dataName.toLowerCase(Locale.ROOT),
dataValue.id(),
className.toLowerCase(Locale.ROOT)
));
}

return fields.stream();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Locale;
import java.util.function.Function;
import java.util.stream.Stream;

Expand Down Expand Up @@ -54,4 +55,10 @@ public static <F, C> Stream<FieldNameValuePair<C>> mapFields(Class<?> clazz, Cla

public record FieldNameValuePair<T>(String name, T value) {
}

public static String toSnakeCase(String camelCase) {
return camelCase
.replaceAll("([a-z])([A-Z]+)", "$1_$2")
.toUpperCase(Locale.ROOT);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@
import net.minecraft.gametest.framework.GameTestHelper;
import net.minecraft.server.dedicated.DedicatedServer;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntitySpawnReason;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.level.GameType;
import org.jetbrains.annotations.NotNull;

public class MCHelper {
Expand All @@ -44,4 +48,12 @@ public static GameTestHelper getGameTestHelper() {
}
};
}

public static <T extends Entity> T createEntity(EntityType<T> entityType) {
if (entityType == EntityType.PLAYER) {
return entityType.tryCast(MCHelper.getGameTestHelper().makeMockPlayer(GameType.DEFAULT_MODE));
}

return entityType.create(MCHelper.getLevel(), EntitySpawnReason.COMMAND);
}
}
5 changes: 4 additions & 1 deletion data-generator/src/main/resources/templates/EntityType.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

import net.kyori.adventure.key.Key;

import java.util.List;

@SuppressWarnings("unused")
public record EntityType(
int id,
Expand All @@ -30,7 +32,8 @@ public record EntityType(
String category,
boolean friendly,
boolean summonable,
boolean attackable) implements RegistryValue<EntityType> {
boolean attackable,
List<String> inheritedClasses) implements RegistryValue<EntityType> {
public static final Registry<EntityType> REGISTRY = new Registry<>(RegistryKeys.ENTITY_TYPE);

//@formatter:off
Expand Down
52 changes: 52 additions & 0 deletions data-generator/src/main/resources/templates/NamedEntityData.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* SoulFire
* Copyright (C) 2024 AlexProgrammerDE
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.soulfiremc.data;

import java.util.ArrayList;
import java.util.List;

@SuppressWarnings("unused")
public record NamedEntityData(String key, int networkId, String entityClass) {
public static final List<NamedEntityData> VALUES = new ArrayList<>();

//@formatter:off
// VALUES REPLACE
//@formatter:on

public static NamedEntityData register(String key, int networkId, String entityClass) {
var instance = new NamedEntityData(key, networkId, entityClass);
VALUES.add(instance);
return instance;
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof NamedEntityData other)) {
return false;
}
return key.equals(other.key) && entityClass.equals(other.entityClass);
}

@Override
public int hashCode() {
return key.hashCode() + entityClass.hashCode();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

import net.kyori.adventure.key.Key;

import java.util.List;

@SuppressWarnings("unused")
public record EntityType(
int id,
Expand All @@ -30,7 +32,8 @@ public record EntityType(
String category,
boolean friendly,
boolean summonable,
boolean attackable) implements RegistryValue<EntityType> {
boolean attackable,
List<String> inheritedClasses) implements RegistryValue<EntityType> {
public static final Registry<EntityType> REGISTRY = new Registry<>(RegistryKeys.ENTITY_TYPE);

//@formatter:off
Expand Down
Loading

0 comments on commit 0a029fe

Please sign in to comment.