Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
6a4f9a3
build.gradle.kts - update hytale again... stupid github
ShaneBeee Mar 7, 2026
9bde2e5
build.gradle.kts - undo --- wrong branch, sorry github for calling yo…
ShaneBeee Mar 7, 2026
b4d1dfc
ExprCast - parse at parse time
ShaneBeee Mar 7, 2026
5cc2bcf
ExprEntityFallDistance - add
ShaneBeee Mar 7, 2026
f0fcf5f
Inventory Events - fix naming
ShaneBeee Mar 8, 2026
6d531e3
JsonDocPrinter - add ID checker
ShaneBeee Mar 8, 2026
b55d2e5
ExprEntityScale - allow setting the scale of a ref
ShaneBeee Mar 8, 2026
18d7ba8
SecSpawnDisplay - add
ShaneBeee Mar 8, 2026
cae39c9
ExprEntityScale - fix not using ensure
ShaneBeee Mar 8, 2026
ed97014
TypesWorld - don't allow deleting players when deleting refs
ShaneBeee Mar 8, 2026
6cb52e8
CondCanBePickedUp - new
ShaneBeee Mar 8, 2026
98fc685
ExprWorldTimeDurations - add changers
ShaneBeee Mar 8, 2026
3cad004
Checkstyle fixes
ShaneBeee Mar 8, 2026
d7f15fc
Fix some events firing too many triggers
ShaneBeee Mar 8, 2026
068e3af
Add some animation stuff
ShaneBeee Mar 9, 2026
267d246
Trigger GitHub Actions
ShaneBeee Mar 9, 2026
24532f5
SecExecuteInWorld - fix context issue
ShaneBeee Mar 9, 2026
fb9c6c1
ExprEntityComponents - add refs
ShaneBeee Mar 9, 2026
71623b3
EntityReferenceUtils - copy methods from entity utils
ShaneBeee Mar 9, 2026
55da32a
ExprLocationDirection - remove bug notice, issue is fixed
ShaneBeee Mar 10, 2026
914fee8
README.md - remove github release count
ShaneBeee Mar 10, 2026
10d35f6
Add bounding box stuff
ShaneBeee Mar 10, 2026
012001e
EntityReferenceUtils - make this perform better
ShaneBeee Mar 13, 2026
54103ad
ExprName - add support for Ref
ShaneBeee Mar 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
![GitHub all releases](https://img.shields.io/github/downloads/SkriptDev/HySkript/total)
# Skript... but for Hytale.

![landscape](https://github.com/user-attachments/assets/2234f5ea-c2dc-4e79-b51c-4300b795e64f)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.component.spatial.SpatialResource;
import com.hypixel.hytale.math.vector.Vector3d;
import com.hypixel.hytale.server.core.entity.Entity;
import com.hypixel.hytale.server.core.entity.entities.Player;
import com.hypixel.hytale.server.core.modules.entity.EntityModule;
import com.hypixel.hytale.server.core.modules.entity.item.ItemComponent;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.server.npc.entities.NPCEntity;
import it.unimi.dsi.fastutil.objects.ObjectList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

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

@SuppressWarnings("unchecked")
public static @Nullable Ref<EntityStore> getRef(Object o) {
if (o instanceof Ref<?> ref && ref.isValid()) {
return (Ref<EntityStore>) ref;
} else if (o instanceof Entity entity) {
Ref<EntityStore> reference = entity.getReference();
if (reference != null && reference.isValid()) return reference;
}
return null;
}

public static List<Ref<EntityStore>> getRefsInSphere(@Nonnull Vector3d pos, double radius, @Nonnull Store<EntityStore> store) {
ObjectList<Ref<EntityStore>> results = SpatialResource.getThreadLocalReferenceList();
List<Ref<EntityStore>> results = SpatialResource.getThreadLocalReferenceList();
EntityModule entityModule = EntityModule.get();
SpatialResource<Ref<EntityStore>, EntityStore> entities = store.getResource(entityModule.getEntitySpatialResourceType());
SpatialResource<Ref<EntityStore>, EntityStore> entities = store.getResource(entityModule.getNetworkSendableSpatialResourceType());
entities.getSpatialStructure().collect(pos, (float) radius, results);
SpatialResource<Ref<EntityStore>, EntityStore> players = store.getResource(entityModule.getPlayerSpatialResourceType());
players.getSpatialStructure().collect(pos, (float) radius, results);
SpatialResource<Ref<EntityStore>, EntityStore> items = store.getResource(entityModule.getItemSpatialResourceType());
items.getSpatialStructure().collect(pos, (float) radius, results);
return results;
}

@Nonnull
public static List<Ref<EntityStore>> getRefsInBox(@Nonnull Vector3d min, @Nonnull Vector3d max, @Nonnull Store<EntityStore> store) {
ObjectList<Ref<EntityStore>> results = SpatialResource.getThreadLocalReferenceList();
List<Ref<EntityStore>> results = SpatialResource.getThreadLocalReferenceList();
EntityModule entityModule = EntityModule.get();
SpatialResource<Ref<EntityStore>, EntityStore> entities = store.getResource(entityModule.getEntitySpatialResourceType());
SpatialResource<Ref<EntityStore>, EntityStore> entities = store.getResource(entityModule.getNetworkSendableSpatialResourceType());
entities.getSpatialStructure().collectBox(min, max, results);
SpatialResource<Ref<EntityStore>, EntityStore> players = store.getResource(entityModule.getPlayerSpatialResourceType());
players.getSpatialStructure().collectBox(min, max, results);
SpatialResource<Ref<EntityStore>, EntityStore> items = store.getResource(entityModule.getItemSpatialResourceType());
items.getSpatialStructure().collectBox(min, max, results);
return results;
}

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


private final String name;
private final Class<E> componentClass;
private final ComponentType<EntityStore, ?> componentType;
Expand Down Expand Up @@ -99,4 +102,95 @@ public Class<E> getComponentClass() {
}
}

/**
* Get a component from an Object (Entity/Ref).
*
* @param object Object to get component from
* @param type Component type to get
* @param <ECS_TYPE> EntityStore Type
* @param <T> Type of returned component
* @return Component from entity if available otherwise null
*/
@SuppressWarnings("unchecked")
public static <ECS_TYPE, T extends Component<ECS_TYPE>> @Nullable T getComponent(Object object, ComponentType<ECS_TYPE, T> type) {
Ref<ECS_TYPE> reference = (Ref<ECS_TYPE>) getRef(object);
if (reference == null) return null;

Store<ECS_TYPE> store = reference.getStore();
return store.getComponent(reference, type);
}

/**
* Get a component from an Object (Entity/Ref) or create it if not present.
*
* @param object Object to get component from
* @param type Component type to get
* @param <ECS> EntityStore Type
* @param <T> Type of returned component
* @return Component from entity if available otherwise will create/add a new one
*/
@SuppressWarnings("unchecked")
public static <ECS, T extends Component<ECS>> @NotNull T ensureAndGetComponent(Object object, ComponentType<ECS, T> type) {
Ref<ECS> reference = (Ref<ECS>) getRef(object);
if (reference == null) {
throw new IllegalStateException("Object '" + object + "' does not have a reference");
}

Store<ECS> store = reference.getStore();
return store.ensureAndGetComponent(reference, type);
}

/**
* Add a component on an Object (Entity/Ref).
*
* @param object Object (Entity/Ref) to add component to
* @param type Type of component to add
* @param component Component to add
* @param <ECS> EntityStore Type
* @param <T> Type of component
*/
@SuppressWarnings("unchecked")
public static <ECS, T extends Component<ECS>> void addComponent(Object object, ComponentType<ECS, T> type, Component<ECS> component) {
Ref<ECS> reference = (Ref<ECS>) getRef(object);
if (reference == null) {
throw new IllegalStateException("Object '" + object + "' does not have a reference");
}
reference.getStore().addComponent(reference, type, (T) component);
}

/**
* Put a component on an Object (Entity/Ref).
*
* @param object Object (Entity/Ref) to put component on
* @param type Type of component to put
* @param component Component to put
* @param <ECS> EntityStore Type
* @param <T> Type of component
*/
@SuppressWarnings("unchecked")
public static <ECS, T extends Component<ECS>> void putComponent(Object object, ComponentType<ECS, T> type, Component<ECS> component) {
Ref<ECS> reference = (Ref<ECS>) getRef(object);
if (reference == null) {
throw new IllegalStateException("Object '" + object + "' does not have a reference");
}
reference.getStore().putComponent(reference, type, (T) component);
}

/**
* Try to remove a component from an Object (Entity/Ref).
*
* @param object Object (Entity/Ref) to remove component from
* @param type Type of component to remove
* @param <ECS> Store type
* @param <T> Component type
*/
@SuppressWarnings("unchecked")
public static <ECS, T extends Component<ECS>> void tryRemoveComponent(Object object, ComponentType<ECS, T> type) {
Ref<ECS> reference = (Ref<ECS>) getRef(object);
if (reference == null) {
throw new IllegalStateException("Object '" + object + "' does not have a reference");
}
reference.getStore().tryRemoveComponent(reference, type);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,30 @@
import com.hypixel.hytale.math.vector.Location;
import com.hypixel.hytale.math.vector.Vector3d;
import com.hypixel.hytale.math.vector.Vector3f;
import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType;
import com.hypixel.hytale.server.core.asset.type.item.config.Item;
import com.hypixel.hytale.server.core.asset.type.model.config.Model;
import com.hypixel.hytale.server.core.asset.type.model.config.ModelAsset;
import com.hypixel.hytale.server.core.entity.Entity;
import com.hypixel.hytale.server.core.entity.LivingEntity;
import com.hypixel.hytale.server.core.entity.UUIDComponent;
import com.hypixel.hytale.server.core.entity.entities.BlockEntity;
import com.hypixel.hytale.server.core.entity.movement.MovementStatesComponent;
import com.hypixel.hytale.server.core.entity.nameplate.Nameplate;
import com.hypixel.hytale.server.core.inventory.ItemStack;
import com.hypixel.hytale.server.core.modules.entity.component.EntityScaleComponent;
import com.hypixel.hytale.server.core.modules.entity.component.HeadRotation;
import com.hypixel.hytale.server.core.modules.entity.component.ModelComponent;
import com.hypixel.hytale.server.core.modules.entity.component.PersistentModel;
import com.hypixel.hytale.server.core.modules.entity.component.PropComponent;
import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
import com.hypixel.hytale.server.core.modules.entity.item.ItemComponent;
import com.hypixel.hytale.server.core.modules.entity.item.PreventItemMerging;
import com.hypixel.hytale.server.core.modules.entity.item.PreventPickup;
import com.hypixel.hytale.server.core.modules.entity.tracker.NetworkId;
import com.hypixel.hytale.server.core.modules.entitystats.EntityStatMap;
import com.hypixel.hytale.server.core.modules.entitystats.EntityStatsModule;
import com.hypixel.hytale.server.core.universe.Universe;
import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.server.npc.entities.NPCEntity;
Expand All @@ -29,6 +44,7 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.annotation.Nonnull;
import java.util.UUID;

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

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

private static String getItemModelId(@Nonnull Item item) {
String modelId = item.getModel();

if (modelId == null && item.hasBlockType()) {
BlockType blockType = BlockType.getAssetMap().getAsset(item.getId());

if (blockType != null && blockType.getCustomModel() != null) {
modelId = blockType.getCustomModel();
}
}

return modelId;
}

private static Model getItemModel(@Nonnull Item item) {
String modelId = getItemModelId(item);

if (modelId == null) {
return null;
} else {
ModelAsset modelAsset = ModelAsset.getAssetMap().getAsset(modelId);

return modelAsset != null ? Model.createStaticScaledModel(modelAsset, 1.0f) : null;
}
}

public static Ref<EntityStore> spawnModel(@NotNull Object object, @NotNull Location location) {
return switch (object) {
case Item item -> spawnItem(item, location);
case BlockType blockType -> spawnBlock(null, blockType, location);
case ModelAsset modelAsset -> spawnModel(null, Model.createStaticScaledModel(modelAsset, 1.0f), location);
default -> null;
};
}

public static Ref<EntityStore> spawnModel(@Nullable Item item, @NotNull Model model, @NotNull Location location) {
World world = Universe.get().getWorld(location.getWorld());
if (world == null) return null;

Store<EntityStore> store = world.getEntityStore().getStore();
Holder<EntityStore> holder = store.getRegistry().newHolder();

holder.addComponent(NetworkId.getComponentType(), new NetworkId(store.getExternalData().takeNextNetworkId()));
holder.addComponent(TransformComponent.getComponentType(), new TransformComponent(location.getPosition(), location.getRotation()));
holder.addComponent(ModelComponent.getComponentType(), new ModelComponent(model));
holder.addComponent(PersistentModel.getComponentType(),
new PersistentModel(
new Model.ModelReference(model.getModelAssetId(), 1.0f, null, true)));
if (item != null) {
ItemStack itemStack = new ItemStack(item.getId(), 1);
itemStack.setOverrideDroppedItemAnimation(true);
holder.addComponent(ItemComponent.getComponentType(), new ItemComponent(itemStack));
}
holder.addComponent(EntityScaleComponent.getComponentType(), new EntityScaleComponent(1.0f));
holder.addComponent(PreventPickup.getComponentType(), PreventPickup.INSTANCE);
holder.addComponent(PreventItemMerging.getComponentType(), PreventItemMerging.INSTANCE);
holder.addComponent(HeadRotation.getComponentType(), new HeadRotation(location.getRotation()));
holder.addComponent(PropComponent.getComponentType(), PropComponent.get());
holder.ensureComponent(UUIDComponent.getComponentType());
return store.addEntity(holder, AddReason.SPAWN);
}

public static Ref<EntityStore> spawnItem(@NotNull Item item, @NotNull Location location) {
Model model = getItemModel(item);
if (model != null) {
return spawnModel(item, model, location);
}
if (item.hasBlockType()) {
BlockType blockType = BlockType.getAssetMap().getAsset(item.getId());
if (blockType != null) {
return spawnBlock(item, blockType, location);
}
}
World world = Universe.get().getWorld(location.getWorld());
if (world == null) return null;

Store<EntityStore> store = world.getEntityStore().getStore();
Holder<EntityStore> holder = store.getRegistry().newHolder();

holder.addComponent(NetworkId.getComponentType(), new NetworkId(store.getExternalData().takeNextNetworkId()));
holder.addComponent(TransformComponent.getComponentType(), new TransformComponent(location.getPosition(), location.getRotation()));
ItemStack itemStack = new ItemStack(item.getId(), 1);
itemStack.setOverrideDroppedItemAnimation(true);
holder.addComponent(ItemComponent.getComponentType(), new ItemComponent(itemStack));
holder.addComponent(EntityScaleComponent.getComponentType(), new EntityScaleComponent(1.0f));
holder.addComponent(PreventPickup.getComponentType(), PreventPickup.INSTANCE);
holder.addComponent(PreventItemMerging.getComponentType(), PreventItemMerging.INSTANCE);
holder.addComponent(HeadRotation.getComponentType(), new HeadRotation(location.getRotation()));
holder.addComponent(PropComponent.getComponentType(), PropComponent.get());
return store.addEntity(holder, AddReason.SPAWN);
}

public static Ref<EntityStore> spawnBlock(@Nullable Item item, @NotNull BlockType blockType, @NotNull Location location) {
World world = Universe.get().getWorld(location.getWorld());
if (world == null) return null;

Store<EntityStore> store = world.getEntityStore().getStore();
Holder<EntityStore> holder = store.getRegistry().newHolder();

holder.addComponent(BlockEntity.getComponentType(), new BlockEntity(blockType.getId()));
holder.addComponent(TransformComponent.getComponentType(), new TransformComponent(location.getPosition(), location.getRotation()));
holder.addComponent(EntityScaleComponent.getComponentType(), new EntityScaleComponent(1.0F));
if (item != null) {
ItemStack itemStack = new ItemStack(item.getId(), 1);
itemStack.setOverrideDroppedItemAnimation(true);
holder.addComponent(ItemComponent.getComponentType(), new ItemComponent(itemStack));
}
holder.addComponent(PreventPickup.getComponentType(), PreventPickup.INSTANCE);
holder.addComponent(PreventItemMerging.getComponentType(), PreventItemMerging.INSTANCE);
holder.addComponent(HeadRotation.getComponentType(), new HeadRotation(location.getRotation()));
holder.addComponent(PropComponent.getComponentType(), PropComponent.get());
holder.ensureComponent(UUIDComponent.getComponentType());
return store.addEntity(holder, AddReason.SPAWN);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public class JsonDocPrinter {
private final SkriptAddon addon;
private final String addonKey;
private final boolean includeSkriptParser;
private final List<String> ids = new ArrayList<>();

public JsonDocPrinter(CommandSender sender, SkriptAddon addon) {
this.sender = sender;
Expand Down Expand Up @@ -593,7 +594,12 @@ private BsonString getId(String type, String syntaxId) {
addonName = "HySkript";
}
String s = type + ":" + addonName + ":" + syntaxId;
return new BsonString(s.toLowerCase(Locale.ROOT).replace(" ", "_"));
String id = s.toLowerCase(Locale.ROOT).replace(" ", "_");
if (this.ids.contains(id)) {
Utils.error("Duplicate ID: " + id);
}
this.ids.add(id);
return new BsonString(id);

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

import com.hypixel.hytale.server.core.modules.accesscontrol.AccessControlModule;
import com.hypixel.hytale.server.core.modules.accesscontrol.provider.HytaleBanProvider;
import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.server.core.universe.world.WorldConfig;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.lang.reflect.Field;
Expand Down Expand Up @@ -37,4 +40,28 @@ public static void init() {
return BAN_PROVIDER;
}

/**
* Set world override time durations of a world.
* <br>I didn't want to do this, but Hytale doesn't have a setter and this is private.
*
* @param world World to change times for
* @param seconds Seconds to override
* @param day Whether to override daytime or nighttime duration
*/
public static void setWorldTimeOverrides(@NotNull World world, @Nullable Integer seconds, boolean day) {
WorldConfig worldConfig = world.getWorldConfig();
try {
Field field;
if (day) {
field = worldConfig.getClass().getDeclaredField("daytimeDurationSecondsOverride");
} else {
field = worldConfig.getClass().getDeclaredField("nighttimeDurationSecondsOverride");
}
field.setAccessible(true);
field.set(worldConfig, seconds);
} catch (NoSuchFieldException | IllegalAccessException ignore) {

}
}

}
Loading
Loading