Skip to content

Commit e4fcaaa

Browse files
authored
Merge pull request #23 from SkriptDev/dev/feature
Dev/feature - Future Feature Release
2 parents 27efc91 + c540d59 commit e4fcaaa

32 files changed

Lines changed: 956 additions & 64 deletions

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
![GitHub all releases](https://img.shields.io/github/downloads/SkriptDev/HySkript/total)
21
# Skript... but for Hytale.
32

43
![landscape](https://github.com/user-attachments/assets/2234f5ea-c2dc-4e79-b51c-4300b795e64f)

build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ dependencies {
3737
implementation("org.bstats:bstats-hytale:3.2.1")
3838

3939
// Skript-Parser
40-
implementation("com.github.SkriptDev:skript-parser:1.0.13") {
40+
implementation("com.github.SkriptDev:skript-parser:1.0.14") {
4141
isTransitive = false
4242
}
4343
implementation("com.github.Zoltus:TinyMessage:2.0.1") {

src/main/java/com/github/skriptdev/skript/api/hytale/utils/EntityReferenceUtils.java

Lines changed: 108 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@
66
import com.hypixel.hytale.component.Store;
77
import com.hypixel.hytale.component.spatial.SpatialResource;
88
import com.hypixel.hytale.math.vector.Vector3d;
9+
import com.hypixel.hytale.server.core.entity.Entity;
910
import com.hypixel.hytale.server.core.entity.entities.Player;
1011
import com.hypixel.hytale.server.core.modules.entity.EntityModule;
1112
import com.hypixel.hytale.server.core.modules.entity.item.ItemComponent;
1213
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
1314
import com.hypixel.hytale.server.npc.entities.NPCEntity;
14-
import it.unimi.dsi.fastutil.objects.ObjectList;
15+
import org.jetbrains.annotations.NotNull;
1516
import org.jetbrains.annotations.Nullable;
1617

1718
import javax.annotation.Nonnull;
@@ -44,34 +45,36 @@ public static ReferenceType<?> getType(Class<? extends Component<?>> componentCl
4445
return TYPES_MAP.get(componentClass);
4546
}
4647

48+
@SuppressWarnings("unchecked")
49+
public static @Nullable Ref<EntityStore> getRef(Object o) {
50+
if (o instanceof Ref<?> ref && ref.isValid()) {
51+
return (Ref<EntityStore>) ref;
52+
} else if (o instanceof Entity entity) {
53+
Ref<EntityStore> reference = entity.getReference();
54+
if (reference != null && reference.isValid()) return reference;
55+
}
56+
return null;
57+
}
58+
4759
public static List<Ref<EntityStore>> getRefsInSphere(@Nonnull Vector3d pos, double radius, @Nonnull Store<EntityStore> store) {
48-
ObjectList<Ref<EntityStore>> results = SpatialResource.getThreadLocalReferenceList();
60+
List<Ref<EntityStore>> results = SpatialResource.getThreadLocalReferenceList();
4961
EntityModule entityModule = EntityModule.get();
50-
SpatialResource<Ref<EntityStore>, EntityStore> entities = store.getResource(entityModule.getEntitySpatialResourceType());
62+
SpatialResource<Ref<EntityStore>, EntityStore> entities = store.getResource(entityModule.getNetworkSendableSpatialResourceType());
5163
entities.getSpatialStructure().collect(pos, (float) radius, results);
52-
SpatialResource<Ref<EntityStore>, EntityStore> players = store.getResource(entityModule.getPlayerSpatialResourceType());
53-
players.getSpatialStructure().collect(pos, (float) radius, results);
54-
SpatialResource<Ref<EntityStore>, EntityStore> items = store.getResource(entityModule.getItemSpatialResourceType());
55-
items.getSpatialStructure().collect(pos, (float) radius, results);
5664
return results;
5765
}
5866

5967
@Nonnull
6068
public static List<Ref<EntityStore>> getRefsInBox(@Nonnull Vector3d min, @Nonnull Vector3d max, @Nonnull Store<EntityStore> store) {
61-
ObjectList<Ref<EntityStore>> results = SpatialResource.getThreadLocalReferenceList();
69+
List<Ref<EntityStore>> results = SpatialResource.getThreadLocalReferenceList();
6270
EntityModule entityModule = EntityModule.get();
63-
SpatialResource<Ref<EntityStore>, EntityStore> entities = store.getResource(entityModule.getEntitySpatialResourceType());
71+
SpatialResource<Ref<EntityStore>, EntityStore> entities = store.getResource(entityModule.getNetworkSendableSpatialResourceType());
6472
entities.getSpatialStructure().collectBox(min, max, results);
65-
SpatialResource<Ref<EntityStore>, EntityStore> players = store.getResource(entityModule.getPlayerSpatialResourceType());
66-
players.getSpatialStructure().collectBox(min, max, results);
67-
SpatialResource<Ref<EntityStore>, EntityStore> items = store.getResource(entityModule.getItemSpatialResourceType());
68-
items.getSpatialStructure().collectBox(min, max, results);
6973
return results;
7074
}
7175

7276
public static class ReferenceType<E extends Component<EntityStore>> {
7377

74-
7578
private final String name;
7679
private final Class<E> componentClass;
7780
private final ComponentType<EntityStore, ?> componentType;
@@ -99,4 +102,95 @@ public Class<E> getComponentClass() {
99102
}
100103
}
101104

105+
/**
106+
* Get a component from an Object (Entity/Ref).
107+
*
108+
* @param object Object to get component from
109+
* @param type Component type to get
110+
* @param <ECS_TYPE> EntityStore Type
111+
* @param <T> Type of returned component
112+
* @return Component from entity if available otherwise null
113+
*/
114+
@SuppressWarnings("unchecked")
115+
public static <ECS_TYPE, T extends Component<ECS_TYPE>> @Nullable T getComponent(Object object, ComponentType<ECS_TYPE, T> type) {
116+
Ref<ECS_TYPE> reference = (Ref<ECS_TYPE>) getRef(object);
117+
if (reference == null) return null;
118+
119+
Store<ECS_TYPE> store = reference.getStore();
120+
return store.getComponent(reference, type);
121+
}
122+
123+
/**
124+
* Get a component from an Object (Entity/Ref) or create it if not present.
125+
*
126+
* @param object Object to get component from
127+
* @param type Component type to get
128+
* @param <ECS> EntityStore Type
129+
* @param <T> Type of returned component
130+
* @return Component from entity if available otherwise will create/add a new one
131+
*/
132+
@SuppressWarnings("unchecked")
133+
public static <ECS, T extends Component<ECS>> @NotNull T ensureAndGetComponent(Object object, ComponentType<ECS, T> type) {
134+
Ref<ECS> reference = (Ref<ECS>) getRef(object);
135+
if (reference == null) {
136+
throw new IllegalStateException("Object '" + object + "' does not have a reference");
137+
}
138+
139+
Store<ECS> store = reference.getStore();
140+
return store.ensureAndGetComponent(reference, type);
141+
}
142+
143+
/**
144+
* Add a component on an Object (Entity/Ref).
145+
*
146+
* @param object Object (Entity/Ref) to add component to
147+
* @param type Type of component to add
148+
* @param component Component to add
149+
* @param <ECS> EntityStore Type
150+
* @param <T> Type of component
151+
*/
152+
@SuppressWarnings("unchecked")
153+
public static <ECS, T extends Component<ECS>> void addComponent(Object object, ComponentType<ECS, T> type, Component<ECS> component) {
154+
Ref<ECS> reference = (Ref<ECS>) getRef(object);
155+
if (reference == null) {
156+
throw new IllegalStateException("Object '" + object + "' does not have a reference");
157+
}
158+
reference.getStore().addComponent(reference, type, (T) component);
159+
}
160+
161+
/**
162+
* Put a component on an Object (Entity/Ref).
163+
*
164+
* @param object Object (Entity/Ref) to put component on
165+
* @param type Type of component to put
166+
* @param component Component to put
167+
* @param <ECS> EntityStore Type
168+
* @param <T> Type of component
169+
*/
170+
@SuppressWarnings("unchecked")
171+
public static <ECS, T extends Component<ECS>> void putComponent(Object object, ComponentType<ECS, T> type, Component<ECS> component) {
172+
Ref<ECS> reference = (Ref<ECS>) getRef(object);
173+
if (reference == null) {
174+
throw new IllegalStateException("Object '" + object + "' does not have a reference");
175+
}
176+
reference.getStore().putComponent(reference, type, (T) component);
177+
}
178+
179+
/**
180+
* Try to remove a component from an Object (Entity/Ref).
181+
*
182+
* @param object Object (Entity/Ref) to remove component from
183+
* @param type Type of component to remove
184+
* @param <ECS> Store type
185+
* @param <T> Component type
186+
*/
187+
@SuppressWarnings("unchecked")
188+
public static <ECS, T extends Component<ECS>> void tryRemoveComponent(Object object, ComponentType<ECS, T> type) {
189+
Ref<ECS> reference = (Ref<ECS>) getRef(object);
190+
if (reference == null) {
191+
throw new IllegalStateException("Object '" + object + "' does not have a reference");
192+
}
193+
reference.getStore().tryRemoveComponent(reference, type);
194+
}
195+
102196
}

src/main/java/com/github/skriptdev/skript/api/hytale/utils/EntityUtils.java

Lines changed: 132 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,30 @@
1010
import com.hypixel.hytale.math.vector.Location;
1111
import com.hypixel.hytale.math.vector.Vector3d;
1212
import com.hypixel.hytale.math.vector.Vector3f;
13+
import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType;
14+
import com.hypixel.hytale.server.core.asset.type.item.config.Item;
15+
import com.hypixel.hytale.server.core.asset.type.model.config.Model;
16+
import com.hypixel.hytale.server.core.asset.type.model.config.ModelAsset;
1317
import com.hypixel.hytale.server.core.entity.Entity;
1418
import com.hypixel.hytale.server.core.entity.LivingEntity;
1519
import com.hypixel.hytale.server.core.entity.UUIDComponent;
20+
import com.hypixel.hytale.server.core.entity.entities.BlockEntity;
1621
import com.hypixel.hytale.server.core.entity.movement.MovementStatesComponent;
1722
import com.hypixel.hytale.server.core.entity.nameplate.Nameplate;
1823
import com.hypixel.hytale.server.core.inventory.ItemStack;
24+
import com.hypixel.hytale.server.core.modules.entity.component.EntityScaleComponent;
25+
import com.hypixel.hytale.server.core.modules.entity.component.HeadRotation;
26+
import com.hypixel.hytale.server.core.modules.entity.component.ModelComponent;
27+
import com.hypixel.hytale.server.core.modules.entity.component.PersistentModel;
28+
import com.hypixel.hytale.server.core.modules.entity.component.PropComponent;
29+
import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
1930
import com.hypixel.hytale.server.core.modules.entity.item.ItemComponent;
31+
import com.hypixel.hytale.server.core.modules.entity.item.PreventItemMerging;
32+
import com.hypixel.hytale.server.core.modules.entity.item.PreventPickup;
33+
import com.hypixel.hytale.server.core.modules.entity.tracker.NetworkId;
2034
import com.hypixel.hytale.server.core.modules.entitystats.EntityStatMap;
2135
import com.hypixel.hytale.server.core.modules.entitystats.EntityStatsModule;
36+
import com.hypixel.hytale.server.core.universe.Universe;
2237
import com.hypixel.hytale.server.core.universe.world.World;
2338
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
2439
import com.hypixel.hytale.server.npc.entities.NPCEntity;
@@ -29,6 +44,7 @@
2944
import org.jetbrains.annotations.NotNull;
3045
import org.jetbrains.annotations.Nullable;
3146

47+
import javax.annotation.Nonnull;
3248
import java.util.UUID;
3349

3450
/**
@@ -227,7 +243,7 @@ public static <ECS, T extends Component<ECS>> void tryRemoveComponent(Entity ent
227243

228244
@SuppressWarnings({"DataFlowIssue"})
229245
public static @NotNull Pair<Ref<EntityStore>, ItemComponent> dropItem(Store<EntityStore> store, ItemStack itemStack,
230-
Location location, Vector3f velocity, float pickupDelay) {
246+
Location location, Vector3f velocity, float pickupDelay) {
231247
if (itemStack.isEmpty() || !itemStack.isValid()) {
232248
return new Pair<>(null, null);
233249
}
@@ -324,4 +340,119 @@ public static void clearMarkedEntity(NPCEntity npcEntity, @Nullable Entity targe
324340
}
325341
}
326342

343+
private static String getItemModelId(@Nonnull Item item) {
344+
String modelId = item.getModel();
345+
346+
if (modelId == null && item.hasBlockType()) {
347+
BlockType blockType = BlockType.getAssetMap().getAsset(item.getId());
348+
349+
if (blockType != null && blockType.getCustomModel() != null) {
350+
modelId = blockType.getCustomModel();
351+
}
352+
}
353+
354+
return modelId;
355+
}
356+
357+
private static Model getItemModel(@Nonnull Item item) {
358+
String modelId = getItemModelId(item);
359+
360+
if (modelId == null) {
361+
return null;
362+
} else {
363+
ModelAsset modelAsset = ModelAsset.getAssetMap().getAsset(modelId);
364+
365+
return modelAsset != null ? Model.createStaticScaledModel(modelAsset, 1.0f) : null;
366+
}
367+
}
368+
369+
public static Ref<EntityStore> spawnModel(@NotNull Object object, @NotNull Location location) {
370+
return switch (object) {
371+
case Item item -> spawnItem(item, location);
372+
case BlockType blockType -> spawnBlock(null, blockType, location);
373+
case ModelAsset modelAsset -> spawnModel(null, Model.createStaticScaledModel(modelAsset, 1.0f), location);
374+
default -> null;
375+
};
376+
}
377+
378+
public static Ref<EntityStore> spawnModel(@Nullable Item item, @NotNull Model model, @NotNull Location location) {
379+
World world = Universe.get().getWorld(location.getWorld());
380+
if (world == null) return null;
381+
382+
Store<EntityStore> store = world.getEntityStore().getStore();
383+
Holder<EntityStore> holder = store.getRegistry().newHolder();
384+
385+
holder.addComponent(NetworkId.getComponentType(), new NetworkId(store.getExternalData().takeNextNetworkId()));
386+
holder.addComponent(TransformComponent.getComponentType(), new TransformComponent(location.getPosition(), location.getRotation()));
387+
holder.addComponent(ModelComponent.getComponentType(), new ModelComponent(model));
388+
holder.addComponent(PersistentModel.getComponentType(),
389+
new PersistentModel(
390+
new Model.ModelReference(model.getModelAssetId(), 1.0f, null, true)));
391+
if (item != null) {
392+
ItemStack itemStack = new ItemStack(item.getId(), 1);
393+
itemStack.setOverrideDroppedItemAnimation(true);
394+
holder.addComponent(ItemComponent.getComponentType(), new ItemComponent(itemStack));
395+
}
396+
holder.addComponent(EntityScaleComponent.getComponentType(), new EntityScaleComponent(1.0f));
397+
holder.addComponent(PreventPickup.getComponentType(), PreventPickup.INSTANCE);
398+
holder.addComponent(PreventItemMerging.getComponentType(), PreventItemMerging.INSTANCE);
399+
holder.addComponent(HeadRotation.getComponentType(), new HeadRotation(location.getRotation()));
400+
holder.addComponent(PropComponent.getComponentType(), PropComponent.get());
401+
holder.ensureComponent(UUIDComponent.getComponentType());
402+
return store.addEntity(holder, AddReason.SPAWN);
403+
}
404+
405+
public static Ref<EntityStore> spawnItem(@NotNull Item item, @NotNull Location location) {
406+
Model model = getItemModel(item);
407+
if (model != null) {
408+
return spawnModel(item, model, location);
409+
}
410+
if (item.hasBlockType()) {
411+
BlockType blockType = BlockType.getAssetMap().getAsset(item.getId());
412+
if (blockType != null) {
413+
return spawnBlock(item, blockType, location);
414+
}
415+
}
416+
World world = Universe.get().getWorld(location.getWorld());
417+
if (world == null) return null;
418+
419+
Store<EntityStore> store = world.getEntityStore().getStore();
420+
Holder<EntityStore> holder = store.getRegistry().newHolder();
421+
422+
holder.addComponent(NetworkId.getComponentType(), new NetworkId(store.getExternalData().takeNextNetworkId()));
423+
holder.addComponent(TransformComponent.getComponentType(), new TransformComponent(location.getPosition(), location.getRotation()));
424+
ItemStack itemStack = new ItemStack(item.getId(), 1);
425+
itemStack.setOverrideDroppedItemAnimation(true);
426+
holder.addComponent(ItemComponent.getComponentType(), new ItemComponent(itemStack));
427+
holder.addComponent(EntityScaleComponent.getComponentType(), new EntityScaleComponent(1.0f));
428+
holder.addComponent(PreventPickup.getComponentType(), PreventPickup.INSTANCE);
429+
holder.addComponent(PreventItemMerging.getComponentType(), PreventItemMerging.INSTANCE);
430+
holder.addComponent(HeadRotation.getComponentType(), new HeadRotation(location.getRotation()));
431+
holder.addComponent(PropComponent.getComponentType(), PropComponent.get());
432+
return store.addEntity(holder, AddReason.SPAWN);
433+
}
434+
435+
public static Ref<EntityStore> spawnBlock(@Nullable Item item, @NotNull BlockType blockType, @NotNull Location location) {
436+
World world = Universe.get().getWorld(location.getWorld());
437+
if (world == null) return null;
438+
439+
Store<EntityStore> store = world.getEntityStore().getStore();
440+
Holder<EntityStore> holder = store.getRegistry().newHolder();
441+
442+
holder.addComponent(BlockEntity.getComponentType(), new BlockEntity(blockType.getId()));
443+
holder.addComponent(TransformComponent.getComponentType(), new TransformComponent(location.getPosition(), location.getRotation()));
444+
holder.addComponent(EntityScaleComponent.getComponentType(), new EntityScaleComponent(1.0F));
445+
if (item != null) {
446+
ItemStack itemStack = new ItemStack(item.getId(), 1);
447+
itemStack.setOverrideDroppedItemAnimation(true);
448+
holder.addComponent(ItemComponent.getComponentType(), new ItemComponent(itemStack));
449+
}
450+
holder.addComponent(PreventPickup.getComponentType(), PreventPickup.INSTANCE);
451+
holder.addComponent(PreventItemMerging.getComponentType(), PreventItemMerging.INSTANCE);
452+
holder.addComponent(HeadRotation.getComponentType(), new HeadRotation(location.getRotation()));
453+
holder.addComponent(PropComponent.getComponentType(), PropComponent.get());
454+
holder.ensureComponent(UUIDComponent.getComponentType());
455+
return store.addEntity(holder, AddReason.SPAWN);
456+
}
457+
327458
}

src/main/java/com/github/skriptdev/skript/api/skript/docs/JsonDocPrinter.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ public class JsonDocPrinter {
5050
private final SkriptAddon addon;
5151
private final String addonKey;
5252
private final boolean includeSkriptParser;
53+
private final List<String> ids = new ArrayList<>();
5354

5455
public JsonDocPrinter(CommandSender sender, SkriptAddon addon) {
5556
this.sender = sender;
@@ -593,7 +594,12 @@ private BsonString getId(String type, String syntaxId) {
593594
addonName = "HySkript";
594595
}
595596
String s = type + ":" + addonName + ":" + syntaxId;
596-
return new BsonString(s.toLowerCase(Locale.ROOT).replace(" ", "_"));
597+
String id = s.toLowerCase(Locale.ROOT).replace(" ", "_");
598+
if (this.ids.contains(id)) {
599+
Utils.error("Duplicate ID: " + id);
600+
}
601+
this.ids.add(id);
602+
return new BsonString(id);
597603

598604
}
599605

0 commit comments

Comments
 (0)