11package com .github .skriptdev .skript .api .hytale .utils ;
22
3+ import com .github .skriptdev .skript .api .skript .registration .NPCRegistry ;
4+ import com .github .skriptdev .skript .api .utils .Utils ;
35import com .hypixel .hytale .component .AddReason ;
46import com .hypixel .hytale .component .Component ;
57import com .hypixel .hytale .component .ComponentType ;
2022import com .hypixel .hytale .server .core .modules .entitystats .EntityStatsModule ;
2123import com .hypixel .hytale .server .core .universe .world .World ;
2224import com .hypixel .hytale .server .core .universe .world .storage .EntityStore ;
25+ import com .hypixel .hytale .server .npc .entities .NPCEntity ;
26+ import com .hypixel .hytale .server .npc .role .Role ;
27+ import com .hypixel .hytale .server .npc .systems .RoleChangeSystem ;
2328import io .github .syst3ms .skriptparser .util .Pair ;
2429import org .jetbrains .annotations .NotNull ;
2530import org .jetbrains .annotations .Nullable ;
@@ -99,7 +104,7 @@ public static void setNameplateName(Entity entity, @Nullable String name) {
99104 }
100105
101106 /**
102- * Get a component from an Entity
107+ * Get a component from an Entity.
103108 *
104109 * @param entity Entity to get component from
105110 * @param type Component type to get
@@ -116,6 +121,61 @@ public static void setNameplateName(Entity entity, @Nullable String name) {
116121 return store .getComponent (reference , type );
117122 }
118123
124+ /**
125+ * Get a component from an Entity or create it if not present.
126+ *
127+ * @param entity Entity to get component from
128+ * @param type Component type to get
129+ * @param <ECS> EntityStore Type
130+ * @param <T> Type of returned component
131+ * @return Component from entity if available otherwise will create/add a new one
132+ */
133+ @ SuppressWarnings ("unchecked" )
134+ public static <ECS , T extends Component <ECS >> @ NotNull T ensureAndGetComponent (Entity entity , ComponentType <ECS , T > type ) {
135+ Ref <ECS > reference = (Ref <ECS >) entity .getReference ();
136+ if (reference == null ) {
137+ throw new IllegalStateException ("Entity '" + entity + "' does not have a reference" );
138+ }
139+
140+ Store <ECS > store = reference .getStore ();
141+ return store .ensureAndGetComponent (reference , type );
142+ }
143+
144+ /**
145+ * Put a component on an Entity.
146+ *
147+ * @param entity Entity to add component to
148+ * @param type Type of component to add
149+ * @param component Component to add
150+ * @param <ECS> EntityStore Type
151+ * @param <T> Type of component
152+ */
153+ @ SuppressWarnings ("unchecked" )
154+ public static <ECS , T extends Component <ECS >> void putComponent (Entity entity , ComponentType <ECS , T > type , Component <ECS > component ) {
155+ Ref <ECS > reference = (Ref <ECS >) entity .getReference ();
156+ if (reference == null ) {
157+ throw new IllegalStateException ("Entity '" + entity + "' does not have a reference" );
158+ }
159+ reference .getStore ().addComponent (reference , type , (T ) component );
160+ }
161+
162+ /**
163+ * Try to remove a component from an Entity.
164+ *
165+ * @param entity Entity to remove component from
166+ * @param type Type of component to remove
167+ * @param <ECS> Store type
168+ * @param <T> Component type
169+ */
170+ @ SuppressWarnings ("unchecked" )
171+ public static <ECS , T extends Component <ECS >> void tryRemoveComponent (Entity entity , ComponentType <ECS , T > type ) {
172+ Ref <ECS > reference = (Ref <ECS >) entity .getReference ();
173+ if (reference == null ) {
174+ throw new IllegalStateException ("Entity '" + entity + "' does not have a reference" );
175+ }
176+ reference .getStore ().tryRemoveComponent (reference , type );
177+ }
178+
119179 /**
120180 * Get the EntityStatMap component of an entity.
121181 *
@@ -173,4 +233,54 @@ public static void setNameplateName(Entity entity, @Nullable String name) {
173233 return new Pair <>(com .hypixel .hytale .server .core .entity .EntityUtils .getEntity (itemEntityHolder ), itemComponent );
174234 }
175235
236+ public static boolean isTameable (NPCEntity npcEntity ) {
237+ Role role = npcEntity .getRole ();
238+ if (role == null ) return false ;
239+
240+ String roleName = role .getRoleName ();
241+ if (roleName .contains ("Tamed_" )) {
242+ return true ;
243+ }
244+ // I know this is hacky, but Hytale doesn't have any API for taming
245+ // Maybe we'll get lucky and Hytale will create API for this
246+ NPCRegistry .NPCRole parse = NPCRegistry .parse ("tamed_" + roleName );
247+ return parse != null ;
248+ }
249+
250+ public static boolean isTamed (NPCEntity npcEntity ) {
251+ Role role = npcEntity .getRole ();
252+ if (role == null ) return false ;
253+
254+ // I know this is hacky, but Hytale doesn't have any API for taming
255+ // Maybe we'll get lucky and Hytale will create API for this
256+ String roleName = role .getRoleName ();
257+ return roleName .startsWith ("Tamed_" );
258+ }
259+
260+ public static void setTamed (NPCEntity npcEntity , boolean tamed ) {
261+ if (!isTameable (npcEntity )) {
262+ return ;
263+ }
264+ if ((tamed && isTamed (npcEntity )) || (!tamed && !isTamed (npcEntity ))) {
265+ return ;
266+ }
267+ Ref <EntityStore > reference = npcEntity .getReference ();
268+ if (reference == null ) return ;
269+
270+ Store <EntityStore > store = reference .getStore ();
271+
272+ // I know this is hacky, but Hytale doesn't have any API for taming
273+ // Maybe we'll get lucky and Hytale will create API for this
274+ Role currentRole = npcEntity .getRole ();
275+ if (currentRole == null || currentRole .isRoleChangeRequested ()) return ;
276+
277+ String roleName = currentRole .getRoleName ();
278+ roleName = tamed ? "Tamed_" + roleName : roleName .replace ("Tamed_" , "" );
279+
280+ NPCRegistry .NPCRole parse = NPCRegistry .parse (roleName );
281+
282+ Utils .log ("Changing role to %s" , parse .name ());
283+ RoleChangeSystem .requestRoleChange (reference , currentRole , parse .index (), true , store );
284+ }
285+
176286}
0 commit comments