Skip to content

Commit

Permalink
add fakespawn 'cancel' arg
Browse files Browse the repository at this point in the history
  • Loading branch information
mcmonkey4eva committed Jun 12, 2020
1 parent 6e47011 commit 2d4bec2
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 13 deletions.
Expand Up @@ -10,6 +10,7 @@
import com.denizenscript.denizen.utilities.blocks.MaterialCompat;
import com.denizenscript.denizen.utilities.depends.Depends;
import com.denizenscript.denizen.utilities.entity.DenizenEntityType;
import com.denizenscript.denizen.utilities.entity.FakeEntity;
import com.denizenscript.denizen.utilities.nbt.CustomNBT;
import com.denizenscript.denizencore.objects.*;
import com.denizenscript.denizen.flags.FlagManager;
Expand Down Expand Up @@ -199,6 +200,19 @@ public static EntityTag valueOf(String string, TagContext context) {

return new EntityTag(randomType, "RANDOM");
}
if (string.startsWith("e@fake:")) {
try {
UUID entityID = UUID.fromString(string);
FakeEntity entity = FakeEntity.idsToEntities.get(entityID);
if (entity != null) {
return entity.entity;
}
return null;
}
catch (Exception ex) {
// DO NOTHING
}
}
if (string.startsWith("n@") || string.startsWith("e@") || string.startsWith("p@")) {
// NPC entity
if (string.startsWith("n@")) {
Expand Down Expand Up @@ -444,6 +458,7 @@ public EntityTag(NPCTag npc) {
private NPCTag npc = null;
private UUID uuid = null;
private String entityScript = null;
public boolean isFake = false;

public DenizenEntityType getEntityType() {
return entity_type;
Expand Down Expand Up @@ -1032,6 +1047,10 @@ public String identify() {
else if (isSpawnedOrValidForTag()) {
return "e@" + entity.getUniqueId().toString();
}

else if (isFake) {
return "e@fake:" + entity.getUniqueId().toString();
}
}

// Try to identify as an entity script
Expand Down
Expand Up @@ -2408,7 +2408,7 @@ else if (foodLevel / maxHunger < 1) {
// -->
registerTag("fake_entities", (attribute, object) -> {
ListTag list = new ListTag();
FakeEntity.FakeEntityMap map = FakeEntity.entityMap.get(object.getOfflinePlayer().getUniqueId());
FakeEntity.FakeEntityMap map = FakeEntity.playersToEntities.get(object.getOfflinePlayer().getUniqueId());
if (map != null) {
for (Map.Entry<Integer, FakeEntity> entry : map.byId.entrySet()) {
list.addObject(entry.getValue().entity);
Expand Down
Expand Up @@ -9,6 +9,7 @@
import com.denizenscript.denizencore.exceptions.InvalidArgumentsException;
import com.denizenscript.denizencore.objects.*;
import com.denizenscript.denizencore.objects.core.DurationTag;
import com.denizenscript.denizencore.objects.core.ElementTag;
import com.denizenscript.denizencore.objects.core.ListTag;
import com.denizenscript.denizencore.scripts.ScriptEntry;
import com.denizenscript.denizencore.scripts.commands.AbstractCommand;
Expand All @@ -20,7 +21,7 @@ public class FakeSpawnCommand extends AbstractCommand {

public FakeSpawnCommand() {
setName("fakespawn");
setSyntax("fakespawn [<entity>] [<location>] (players:<player>|...) (d:<duration>{10s})");
setSyntax("fakespawn [<entity>] [cancel/<location>] (players:<player>|...) (d:<duration>{10s})");
setRequiredArguments(2, 4);
isProcedural = false;
}
Expand All @@ -47,8 +48,11 @@ public FakeSpawnCommand() {
// If unspecified, will default to 10 seconds.
// After the duration is up, the entity will be removed from the player(s).
//
// To remove a fake entity, specify the fake entity object and 'cancel' instead of a location.
//
// @Tags
// <PlayerTag.fake_entities>
// <entry[saveName].faked_entities> returns the list of spawned faked entities (one per player).
//
// @Usage
// Use to show a fake creeper in front of the attached player.
Expand Down Expand Up @@ -77,6 +81,10 @@ else if (!scriptEntry.hasObject("location")
&& arg.matchesArgumentType(LocationTag.class)) {
scriptEntry.addObject("location", arg.asType(LocationTag.class));
}
else if (!scriptEntry.hasObject("cancel")
&& arg.matches("cancel")) {
scriptEntry.addObject("cancel", new ElementTag(true));
}
else {
arg.reportUnhandled();
}
Expand All @@ -86,7 +94,7 @@ else if (!scriptEntry.hasObject("location")
scriptEntry.defaultObject("players", Arrays.asList(Utilities.getEntryPlayer(scriptEntry)));
}

if (!scriptEntry.hasObject("location")) {
if (!scriptEntry.hasObject("location") && !scriptEntry.hasObject("cancel")) {
throw new InvalidArgumentsException("Must specify a valid location!");
}

Expand All @@ -108,12 +116,29 @@ public void execute(ScriptEntry scriptEntry) {
LocationTag location = scriptEntry.getObjectTag("location");
List<PlayerTag> players = (List<PlayerTag>) scriptEntry.getObject("players");
DurationTag duration = scriptEntry.getObjectTag("duration");
ElementTag cancel = scriptEntry.getElement("cancel");

if (scriptEntry.dbCallShouldDebug()) {
Debug.report(scriptEntry, getName(), entity.debug() + location.debug() + duration.debug()
Debug.report(scriptEntry, getName(), entity.debug()
+ (cancel != null ? cancel.debug() :
location.debug() + duration.debug())
+ ArgumentHelper.debugList("players", players));
}

FakeEntity.showFakeEntityTo(players, entity, location, duration);
if (cancel != null && cancel.asBoolean()) {
if (entity.isFake) {
FakeEntity fakeEnt = FakeEntity.idsToEntities.get(entity.getUUID());
if (fakeEnt != null) {
fakeEnt.cancelEntity();
}
else {
Debug.echoDebug(scriptEntry, "Entity '" + entity + "' cannot be cancelled: not listed in fake-entity map.");
}
}
}
else {
ListTag created = FakeEntity.showFakeEntityTo(players, entity, location, duration);
scriptEntry.addObject("faked_entities", created);
}
}
}
Expand Up @@ -6,6 +6,7 @@
import com.denizenscript.denizen.objects.PlayerTag;
import com.denizenscript.denizen.utilities.DenizenAPI;
import com.denizenscript.denizencore.objects.core.DurationTag;
import com.denizenscript.denizencore.objects.core.ListTag;
import org.bukkit.entity.Entity;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask;
Expand Down Expand Up @@ -33,10 +34,11 @@ public void remove(FakeEntity entity) {
}
}

public final static Map<UUID, FakeEntityMap> entityMap = new HashMap<>();
public final static Map<UUID, FakeEntityMap> playersToEntities = new HashMap<>();
public final static Map<UUID, FakeEntity> idsToEntities = new HashMap<>();

public static FakeEntity getFakeEntityFor(UUID uuid, int id) {
FakeEntityMap map = entityMap.get(uuid);
FakeEntityMap map = playersToEntities.get(uuid);
if (map == null) {
return null;
}
Expand All @@ -55,32 +57,39 @@ private FakeEntity(PlayerTag player, LocationTag location, int id) {
this.id = id;
}

public static void showFakeEntityTo(List<PlayerTag> players, EntityTag entityTag, LocationTag location, DurationTag duration) {
public static ListTag showFakeEntityTo(List<PlayerTag> players, EntityTag typeToSpawn, LocationTag location, DurationTag duration) {
ListTag result = new ListTag();
for (PlayerTag player : players) {
if (!player.isOnline() || !player.isValid()) {
continue;
}
UUID uuid = player.getPlayerEntity().getUniqueId();
FakeEntity.FakeEntityMap playerEntities = entityMap.get(uuid);
FakeEntity.FakeEntityMap playerEntities = playersToEntities.get(uuid);
if (playerEntities == null) {
playerEntities = new FakeEntity.FakeEntityMap();
entityMap.put(uuid, playerEntities);
playersToEntities.put(uuid, playerEntities);
}
Entity entity = NMSHandler.getPlayerHelper().sendEntitySpawn(player.getPlayerEntity(), entityTag.getBukkitEntityType(), location, entityTag.getWaitingMechanisms());
Entity entity = NMSHandler.getPlayerHelper().sendEntitySpawn(player.getPlayerEntity(), typeToSpawn.getBukkitEntityType(), location, typeToSpawn.getWaitingMechanisms());
FakeEntity fakeEntity = playerEntities.getOrAdd(player, location, entity.getEntityId());
fakeEntity.updateEntity(new EntityTag(entity), duration);
EntityTag entTag = new EntityTag(entity);
entTag.isFake = true;
fakeEntity.updateEntity(entTag, duration);
idsToEntities.put(entTag.getUUID(), fakeEntity);
result.addObject(entTag);
}
return result;
}

public void cancelEntity() {
if (currentTask != null) {
currentTask.cancel();
currentTask = null;
}
idsToEntities.remove(entity.getUUID());
if (player.isOnline()) {
NMSHandler.getPlayerHelper().sendEntityDestroy(player.getPlayerEntity(), entity.getBukkitEntity());
}
FakeEntity.FakeEntityMap mapping = entityMap.get(player.getOfflinePlayer().getUniqueId());
FakeEntity.FakeEntityMap mapping = playersToEntities.get(player.getOfflinePlayer().getUniqueId());
mapping.remove(this);
}

Expand Down

0 comments on commit 2d4bec2

Please sign in to comment.