I think i finished goal selectors
This commit is contained in:
parent
41da2e4c8e
commit
76efbdcb1f
13 changed files with 404 additions and 44 deletions
|
@ -5,21 +5,19 @@
|
|||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="9d5d9b6f-43c8-41a4-bb42-a66ffc96c9b0" name="Changes" comment="">
|
||||
<change afterPath="$PROJECT_DIR$/src/main/java/me/tofaa/entitylib/Tickable.java" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/main/java/me/tofaa/entitylib/TickingContainer.java" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/main/java/me/tofaa/entitylib/entity/WrapperEntityCreature.java" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/main/java/me/tofaa/entitylib/entity/WrapperExperienceOrbEntity.java" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/main/java/me/tofaa/entitylib/entity/ai/AIGroup.java" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/main/java/me/tofaa/entitylib/entity/ai/GoalSelector.java" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/main/java/me/tofaa/entitylib/entity/ai/TargetSelector.java" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/main/java/me/tofaa/entitylib/world/WrapperWorld.java" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/test-plugin/src/main/java/me/tofaa/entitylib/SpawnClickableFrogCommand.java" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/main/java/me/tofaa/entitylib/entity/ai/GoalSelectorList.java" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/main/java/me/tofaa/entitylib/entity/ai/goals/RandomHeadMovementGoal.java" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/main/java/me/tofaa/entitylib/extras/CoordinateUtil.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/main/java/me/tofaa/entitylib/EntityLib.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/me/tofaa/entitylib/EntityLib.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/README.md" beforeDir="false" afterPath="$PROJECT_DIR$/README.md" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/main/java/me/tofaa/entitylib/TickingContainer.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/me/tofaa/entitylib/TickingContainer.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/main/java/me/tofaa/entitylib/entity/WrapperEntity.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/me/tofaa/entitylib/entity/WrapperEntity.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/main/java/me/tofaa/entitylib/entity/WrapperEntityCreature.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/me/tofaa/entitylib/entity/WrapperEntityCreature.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/main/java/me/tofaa/entitylib/entity/WrapperLivingEntity.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/me/tofaa/entitylib/entity/WrapperLivingEntity.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/test-plugin/src/main/java/me/tofaa/entitylib/EntityLibPlugin.java" beforeDir="false" afterPath="$PROJECT_DIR$/test-plugin/src/main/java/me/tofaa/entitylib/EntityLibPlugin.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/test-plugin/src/main/resources/plugin.yml" beforeDir="false" afterPath="$PROJECT_DIR$/test-plugin/src/main/resources/plugin.yml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/main/java/me/tofaa/entitylib/entity/ai/AIGroup.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/me/tofaa/entitylib/entity/ai/AIGroup.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/main/java/me/tofaa/entitylib/entity/ai/GoalSelector.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/me/tofaa/entitylib/entity/ai/GoalSelector.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/main/java/me/tofaa/entitylib/entity/ai/TargetSelector.java" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/main/java/me/tofaa/entitylib/world/WrapperWorld.java" beforeDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
|
@ -221,7 +219,7 @@
|
|||
<workItem from="1704485939274" duration="2440000" />
|
||||
<workItem from="1704502790346" duration="6191000" />
|
||||
<workItem from="1705192736239" duration="496000" />
|
||||
<workItem from="1705534524814" duration="8652000" />
|
||||
<workItem from="1705534524814" duration="13073000" />
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
# EntityLib
|
||||
EntityLib is a PacketEvents addon that provides an abstraction over raw entity data and packets to make it easier to work with entities as a whole.
|
||||
Currently EntityLib is only stable for 1.18+, but it will support all versions that PacketEvents supports in the future.
|
||||
```groovy
|
||||
//https://jitpack.io/#Tofaa2/EntityLib/
|
||||
repositories {
|
||||
|
@ -99,7 +100,7 @@ Once this list is complete, i will release a stable version of the library.
|
|||
- [ ] Add support for more actions using WrapperEntities.
|
||||
- [ ] More javadocs.
|
||||
- [x] Make ObjectData actually useful.
|
||||
- [ ] Multi-version support
|
||||
- [ ] Multi-version support, currently only 1.18+ is stable.
|
||||
- [ ] Make class names match the protocol specified names.
|
||||
|
||||
### Credits
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
package me.tofaa.entitylib;
|
||||
|
||||
/**
|
||||
* A container that can hold and tick {@link Tickable}s.
|
||||
* This is for specific users to extend if they want ticking functionality.
|
||||
*
|
||||
*/
|
||||
public interface TickingContainer {
|
||||
|
||||
void addTickable(Tickable tickable);
|
||||
|
|
|
@ -24,7 +24,7 @@ public class WrapperEntity implements Tickable {
|
|||
private Location location;
|
||||
private boolean onGround;
|
||||
private boolean spawned;
|
||||
private Vector3d velocity = Vector3d.zero();
|
||||
protected Vector3d velocity = Vector3d.zero();
|
||||
|
||||
public WrapperEntity(int entityId, @NotNull UUID uuid, EntityType entityType, EntityMeta meta) {
|
||||
this.uuid = Optional.of(uuid);
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
package me.tofaa.entitylib.entity;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
|
||||
import me.tofaa.entitylib.entity.ai.AIGroup;
|
||||
import me.tofaa.entitylib.meta.EntityMeta;
|
||||
import me.tofaa.entitylib.EntityLib;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
|
@ -18,9 +22,55 @@ import java.util.UUID;
|
|||
* The {@link WrapperEntityCreature} can be inherited to create custom entities.
|
||||
* </p>
|
||||
*/
|
||||
public class WrapperEntityCreature extends WrapperLivingEntity{
|
||||
public class WrapperEntityCreature extends WrapperLivingEntity {
|
||||
|
||||
private final Set<AIGroup> aiGroups;
|
||||
|
||||
public WrapperEntityCreature(int entityId, @NotNull UUID uuid, EntityType entityType, EntityMeta meta) {
|
||||
super(entityId, uuid, entityType, meta);
|
||||
this.aiGroups = new HashSet<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void kill() {
|
||||
super.kill();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an {@link AIGroup} to the entity.
|
||||
* <p>
|
||||
* The AIGroup will be updated every tick.
|
||||
* </p>
|
||||
*
|
||||
* @param aiGroup The AIGroup to add.
|
||||
*/
|
||||
public void addAIGroup(AIGroup aiGroup) {
|
||||
aiGroups.add(aiGroup);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an {@link AIGroup} from the entity.
|
||||
*
|
||||
* @param aiGroup The AIGroup to remove.
|
||||
*/
|
||||
public void removeAIGroup(AIGroup aiGroup) {
|
||||
aiGroups.remove(aiGroup);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all {@link AIGroup}s from the entity.
|
||||
*/
|
||||
public void clearAIGroups() {
|
||||
aiGroups.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link AIGroup}s of the entity.
|
||||
*
|
||||
* @return The AIGroups of the entity.
|
||||
*/
|
||||
public Set<AIGroup> getAIGroups() {
|
||||
return Collections.unmodifiableSet(aiGroups);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
package me.tofaa.entitylib.entity;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
|
||||
import com.github.retrooper.packetevents.util.Vector3d;
|
||||
import com.github.retrooper.packetevents.util.Vector3f;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityStatus;
|
||||
import me.tofaa.entitylib.meta.EntityMeta;
|
||||
import me.tofaa.entitylib.meta.types.LivingEntityMeta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
@ -18,6 +21,16 @@ public class WrapperLivingEntity extends WrapperEntity{
|
|||
}
|
||||
|
||||
|
||||
public void kill() {
|
||||
sendStatus((byte) 3);
|
||||
setHealth(0);
|
||||
this.velocity = Vector3d.zero();
|
||||
}
|
||||
|
||||
public void sendStatus(byte status) {
|
||||
sendPacketsToViewers(new WrapperPlayServerEntityStatus(getEntityId(), status));
|
||||
}
|
||||
|
||||
public float getHealth() {
|
||||
return getMeta().getHealth();
|
||||
}
|
||||
|
|
|
@ -1,4 +1,69 @@
|
|||
package me.tofaa.entitylib.entity.ai;
|
||||
|
||||
public interface AIGroup {
|
||||
import me.tofaa.entitylib.Tickable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class AIGroup implements Tickable {
|
||||
|
||||
private final List<GoalSelector> goalSelectors = new GoalSelectorList(this);
|
||||
private GoalSelector currentGoalSelector;
|
||||
|
||||
public @NotNull Collection<GoalSelector> getGoalSelectors() {
|
||||
return goalSelectors;
|
||||
}
|
||||
|
||||
public @Nullable GoalSelector getCurrentGoal() {
|
||||
return currentGoalSelector;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a goal selector to the end of the list. Might be potentially unsafe to use after the entity has been spawned.
|
||||
*
|
||||
* @param goalSelector the goal selector to add
|
||||
*/
|
||||
public void addGoalSelector(@NotNull GoalSelector goalSelector) {
|
||||
this.goalSelectors.add(goalSelector);
|
||||
}
|
||||
|
||||
public void setCurrentGoal(@Nullable GoalSelector goalSelector) {
|
||||
if (goalSelector != null && goalSelector.getAIGroup() != this) {
|
||||
throw new IllegalArgumentException("GoalSelector is not in this AIGroup");
|
||||
}
|
||||
currentGoalSelector = goalSelector;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(long time) {
|
||||
GoalSelector currentGoalSelector = getCurrentGoal();
|
||||
|
||||
if (currentGoalSelector != null && currentGoalSelector.shouldEnd()) {
|
||||
currentGoalSelector.end();
|
||||
currentGoalSelector = null;
|
||||
setCurrentGoal(null);
|
||||
}
|
||||
|
||||
for (GoalSelector selector : getGoalSelectors()) {
|
||||
if (selector == currentGoalSelector) {
|
||||
break;
|
||||
}
|
||||
if (selector.shouldStart()) {
|
||||
if (currentGoalSelector != null) {
|
||||
currentGoalSelector.end();
|
||||
}
|
||||
currentGoalSelector = selector;
|
||||
setCurrentGoal(currentGoalSelector);
|
||||
currentGoalSelector.start();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (currentGoalSelector != null) {
|
||||
currentGoalSelector.tick(time);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,4 +1,85 @@
|
|||
package me.tofaa.entitylib.entity.ai;
|
||||
|
||||
public class GoalSelector {
|
||||
import me.tofaa.entitylib.entity.WrapperEntityCreature;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
/**
|
||||
* Goals represent tasks that a {@link me.tofaa.entitylib.entity.WrapperEntityCreature} can perform.
|
||||
*/
|
||||
public abstract class GoalSelector {
|
||||
|
||||
private WeakReference<AIGroup> aiGroupRef;
|
||||
protected WrapperEntityCreature entity;
|
||||
|
||||
public GoalSelector(WrapperEntityCreature entity) {
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this {@link GoalSelector} should start.
|
||||
*
|
||||
* @return true to start
|
||||
*/
|
||||
public abstract boolean shouldStart();
|
||||
|
||||
/**
|
||||
* Starts this {@link GoalSelector}.
|
||||
*/
|
||||
public abstract void start();
|
||||
|
||||
/**
|
||||
* Called every tick when this {@link GoalSelector} is running.
|
||||
*
|
||||
* @param time the time of the update in milliseconds
|
||||
*/
|
||||
public abstract void tick(long time);
|
||||
|
||||
/**
|
||||
* Whether this {@link GoalSelector} should end.
|
||||
*
|
||||
* @return true to end
|
||||
*/
|
||||
public abstract boolean shouldEnd();
|
||||
|
||||
/**
|
||||
* Ends this {@link GoalSelector}.
|
||||
*/
|
||||
public abstract void end();
|
||||
|
||||
|
||||
/**
|
||||
* Gets the entity behind the goal selector.
|
||||
*
|
||||
* @return the entity
|
||||
*/
|
||||
@NotNull
|
||||
public WrapperEntityCreature getEntityCreature() {
|
||||
return entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the entity affected by the goal selector.
|
||||
* <p>
|
||||
* WARNING: this does not add the goal selector to {@code entityCreature},
|
||||
* this only change the internal entity AI group's field. Be sure to remove the goal from
|
||||
* the previous entity AI group and add it to the new one using {@link AIGroup#getGoalSelectors()}.
|
||||
*
|
||||
* @param entity the new affected entity
|
||||
*/
|
||||
public void setEntityCreature(@NotNull WrapperEntityCreature entity) {
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
void setAIGroup(@NotNull AIGroup group) {
|
||||
this.aiGroupRef = new WeakReference<>(group);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected AIGroup getAIGroup() {
|
||||
return this.aiGroupRef.get();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
package me.tofaa.entitylib.entity.ai;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
final class GoalSelectorList extends ArrayList<GoalSelector> {
|
||||
|
||||
final AIGroup aiGroup;
|
||||
|
||||
GoalSelectorList(AIGroup aiGroup) {
|
||||
this.aiGroup = aiGroup;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GoalSelector set(int index, GoalSelector element) {
|
||||
element.setAIGroup(aiGroup);
|
||||
return super.set(index, element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(GoalSelector element) {
|
||||
element.setAIGroup(aiGroup);
|
||||
return super.add(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(int index, GoalSelector element) {
|
||||
element.setAIGroup(aiGroup);
|
||||
super.add(index, element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addAll(Collection<? extends GoalSelector> c) {
|
||||
c.forEach(goalSelector -> goalSelector.setAIGroup(aiGroup));
|
||||
return super.addAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addAll(int index, Collection<? extends GoalSelector> c) {
|
||||
c.forEach(goalSelector -> goalSelector.setAIGroup(aiGroup));
|
||||
return super.addAll(index, c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void replaceAll(UnaryOperator<GoalSelector> operator) {
|
||||
super.replaceAll(goalSelector -> {
|
||||
goalSelector = operator.apply(goalSelector);
|
||||
goalSelector.setAIGroup(aiGroup);
|
||||
return goalSelector;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
package me.tofaa.entitylib.entity.ai;
|
||||
|
||||
public class TargetSelector {
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
package me.tofaa.entitylib.entity.ai.goals;
|
||||
|
||||
import com.github.retrooper.packetevents.util.Vector3d;
|
||||
import me.tofaa.entitylib.entity.WrapperEntityCreature;
|
||||
import me.tofaa.entitylib.entity.ai.GoalSelector;
|
||||
import me.tofaa.entitylib.extras.CoordinateUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class RandomHeadMovementGoal extends GoalSelector {
|
||||
|
||||
private static final Random RANDOM = new Random();
|
||||
private final int chancePerTick;
|
||||
private final Supplier<Integer> minimalLookTimeSupplier;
|
||||
private final Function<WrapperEntityCreature, Vector3d> randomDirectionFunction;
|
||||
private Vector3d lookDirection;
|
||||
private int lookTime = 0;
|
||||
|
||||
public RandomHeadMovementGoal(WrapperEntityCreature entityCreature, int chancePerTick) {
|
||||
this(entityCreature, chancePerTick,
|
||||
// These two functions act similarly enough to how MC randomly looks around.
|
||||
// Look in one direction for at most 40 ticks and at minimum 20 ticks.
|
||||
() -> 20 + RANDOM.nextInt(20),
|
||||
// Look at a random block
|
||||
(creature) -> {
|
||||
final double n = Math.PI * 2 * RANDOM.nextDouble();
|
||||
return new Vector3d(
|
||||
(float) Math.cos(n),
|
||||
0,
|
||||
(float) Math.sin(n)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param entityCreature Creature that should randomly look around.
|
||||
* @param chancePerTick The chance (per tick) that the entity looks around. Setting this to N would mean there is a 1 in N chance.
|
||||
* @param minimalLookTimeSupplier A supplier that returns the minimal amount of time an entity looks in a direction.
|
||||
* @param randomDirectionFunction A function that returns a random vector that the entity will look in/at.
|
||||
*/
|
||||
public RandomHeadMovementGoal(
|
||||
WrapperEntityCreature entityCreature,
|
||||
int chancePerTick,
|
||||
@NotNull Supplier<Integer> minimalLookTimeSupplier,
|
||||
@NotNull Function<WrapperEntityCreature, Vector3d> randomDirectionFunction) {
|
||||
super(entityCreature);
|
||||
this.chancePerTick = chancePerTick;
|
||||
this.minimalLookTimeSupplier = minimalLookTimeSupplier;
|
||||
this.randomDirectionFunction = randomDirectionFunction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldStart() {
|
||||
return RANDOM.nextInt(chancePerTick) == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
lookTime = minimalLookTimeSupplier.get();
|
||||
lookDirection = randomDirectionFunction.apply(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick(long time) {
|
||||
--lookTime;
|
||||
entity.teleport(CoordinateUtil.withDirection(entity.getLocation(), lookDirection));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldEnd() {
|
||||
return this.lookTime < 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end() {
|
||||
|
||||
}
|
||||
}
|
38
src/main/java/me/tofaa/entitylib/extras/CoordinateUtil.java
Normal file
38
src/main/java/me/tofaa/entitylib/extras/CoordinateUtil.java
Normal file
|
@ -0,0 +1,38 @@
|
|||
package me.tofaa.entitylib.extras;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.world.Location;
|
||||
import com.github.retrooper.packetevents.util.Vector3d;
|
||||
|
||||
public final class CoordinateUtil {
|
||||
|
||||
private CoordinateUtil() {}
|
||||
|
||||
public static Location withDirection(Location location, Vector3d direction) {
|
||||
/*
|
||||
* Sin = Opp / Hyp
|
||||
* Cos = Adj / Hyp
|
||||
* Tan = Opp / Adj
|
||||
*
|
||||
* x = -Opp
|
||||
* z = Adj
|
||||
*/
|
||||
final double x = direction.getX();
|
||||
final double z = direction.getZ();
|
||||
if (x == 0 && z == 0) {
|
||||
float pitch = direction.getY() > 0 ? -90f : 90f;
|
||||
return new Location(location.getX(), location.getY(), location.getZ(), location.getYaw(), pitch);
|
||||
}
|
||||
final double theta = Math.atan2(-x, z);
|
||||
final double xz = Math.sqrt(square(x) + square(z));
|
||||
final double _2PI = 2 * Math.PI;
|
||||
|
||||
return new Location(location.getX(), location.getY(), location.getZ(),
|
||||
(float) Math.toDegrees((theta + _2PI) % _2PI),
|
||||
(float) Math.toDegrees(Math.atan(-direction.getY() / xz)));
|
||||
}
|
||||
|
||||
public static double square(double in) {
|
||||
return in * in;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
package me.tofaa.entitylib.world;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.player.User;
|
||||
import me.tofaa.entitylib.entity.WrapperEntity;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public class WrapperWorld {
|
||||
|
||||
private final UUID uuid;
|
||||
private final Set<WrapperEntity> entities;
|
||||
private final Set<User> players;
|
||||
|
||||
public WrapperWorld(UUID uuid) {
|
||||
this.uuid = uuid;
|
||||
this.entities = new HashSet<>();
|
||||
this.players = new HashSet<>();
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue