Document a portion of NPCs
This commit is contained in:
parent
de6ead8b2a
commit
e392b65c68
@ -39,6 +39,13 @@ import mineplex.core.newnpc.event.NPCInteractEvent;
|
||||
import mineplex.core.newnpc.event.NPCRefreshEvent;
|
||||
import mineplex.core.recharge.Recharge;
|
||||
|
||||
/**
|
||||
* NPCManager is a new version of the previous NpcManager to improve usability and more general purpose.
|
||||
* <br>
|
||||
* NPCs are saved in the table <b>newNPCs</b> in the <b>accounts</b> database.
|
||||
* <br>
|
||||
* Details on how to create NPCs can be found in the {@link NPC} and {@link PlayerNPC} classes.
|
||||
*/
|
||||
@ReflectivelyCreateMiniPlugin
|
||||
public class NewNPCManager extends MiniPlugin
|
||||
{
|
||||
@ -71,7 +78,9 @@ public class NewNPCManager extends MiniPlugin
|
||||
_builders = new HashMap<>();
|
||||
_teleportMap = new HashMap<>();
|
||||
|
||||
// Loading NPCs on the main thread makes sure that _npcs is populated before anything tries to spawn NPCs.
|
||||
loadNPCs();
|
||||
// Any NPC with the metadata DUMMY will always be spawned regardless, useful for testing designs
|
||||
spawnNPCs("DUMMY", null);
|
||||
|
||||
generatePermissions();
|
||||
@ -93,6 +102,12 @@ public class NewNPCManager extends MiniPlugin
|
||||
addCommand(new NPCCommand(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads synchronously all NPCs from the database and populates the {@link #_npcs} list if the npc was not already
|
||||
* contained within the collection. Thus this method can be called more than once during runtime. Though it is
|
||||
* recommended that if the caller is not calling this during startup then this should not be called from the main
|
||||
* thread.
|
||||
*/
|
||||
private void loadNPCs()
|
||||
{
|
||||
_repository.getNPCs(npcs ->
|
||||
@ -109,6 +124,12 @@ public class NewNPCManager extends MiniPlugin
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Spawns all NPCs that have the metadata specified.
|
||||
*
|
||||
* @param metadata The metadata that must equal the NPC's metadata.
|
||||
* @param after A callback consumer for each npc.
|
||||
*/
|
||||
public void spawnNPCs(String metadata, Consumer<NPC> after)
|
||||
{
|
||||
_creature.SetForce(true);
|
||||
@ -128,6 +149,9 @@ public class NewNPCManager extends MiniPlugin
|
||||
_creature.SetForce(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls {@link #loadNPCs()} then the {@link NPCRefreshEvent}
|
||||
*/
|
||||
public void refreshNPCS()
|
||||
{
|
||||
loadNPCs();
|
||||
@ -135,6 +159,11 @@ public class NewNPCManager extends MiniPlugin
|
||||
UtilServer.CallEvent(new NPCRefreshEvent());
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an NPC's entity and removes it from the database.
|
||||
*
|
||||
* @param npc The NPC you want to delete.
|
||||
*/
|
||||
public void deleteNPC(NPC npc)
|
||||
{
|
||||
runAsync(() -> _repository.deleteNPC(npc));
|
||||
@ -147,6 +176,11 @@ public class NewNPCManager extends MiniPlugin
|
||||
_npcs.remove(npc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes every NPC.
|
||||
*
|
||||
* @param deleteFromDB If true, all NPC's are deleted from the database. If false this action is only temporary.
|
||||
*/
|
||||
public void clearNPCS(boolean deleteFromDB)
|
||||
{
|
||||
if (deleteFromDB)
|
||||
@ -165,25 +199,54 @@ public class NewNPCManager extends MiniPlugin
|
||||
_npcs.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param npc The NPC you want to spawn.
|
||||
* @see #addNPC(NPC, boolean)
|
||||
*/
|
||||
public void addNPC(NPC npc)
|
||||
{
|
||||
addNPC(npc, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds and spawns an NPC.
|
||||
*
|
||||
* @param npc The NPC you want to spawn.
|
||||
* @param saveToDB If true the NPC will be saved to the database.
|
||||
*/
|
||||
public void addNPC(NPC npc, boolean saveToDB)
|
||||
{
|
||||
_creature.SetForce(true);
|
||||
|
||||
_npcs.add(npc);
|
||||
npc.spawnEntity();
|
||||
|
||||
runAsync(() -> _repository.insertNPCIfNotExists(npc));
|
||||
if (saveToDB)
|
||||
{
|
||||
runAsync(() -> _repository.insertNPCIfNotExists(npc));
|
||||
}
|
||||
|
||||
_creature.SetForce(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by {@link NPCMoveCommand}. Has no other purpose.
|
||||
*/
|
||||
@Deprecated
|
||||
public void setPlayerTeleport(Player player)
|
||||
{
|
||||
_teleportMap.put(player, player.getLocation());
|
||||
}
|
||||
|
||||
/**
|
||||
* Teleports an NPC to a location and saves that in the database for future reference.
|
||||
*
|
||||
* @param npc The NPC you want to move.
|
||||
* @param location The Location you want to move the NPC to.
|
||||
*/
|
||||
public void teleport(NPC npc, Location location)
|
||||
{
|
||||
// If there isn't an entity or the location to go is null, then don't teleport.
|
||||
if (npc.getEntity() == null || location == null)
|
||||
{
|
||||
return;
|
||||
@ -193,6 +256,9 @@ public class NewNPCManager extends MiniPlugin
|
||||
runAsync(() -> _repository.teleportNPC(npc, location));
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by {@link mineplex.core.newnpc.command.NPCBuildCommand}. Has no other purpose.
|
||||
*/
|
||||
public void createBuilder(Player player)
|
||||
{
|
||||
_builders.put(player, new NPCBuilder());
|
||||
@ -201,6 +267,9 @@ public class NewNPCManager extends MiniPlugin
|
||||
player.sendMessage(F.main("Step 1", "Type in chat the Entity Type of your NPC."));
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans up NPC creation maps, if the player quits.
|
||||
*/
|
||||
@EventHandler
|
||||
public void playerQuit(PlayerQuitEvent event)
|
||||
{
|
||||
@ -210,6 +279,9 @@ public class NewNPCManager extends MiniPlugin
|
||||
_teleportMap.remove(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles {@link NPCBuilder} data input.
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void chat(AsyncPlayerChatEvent event)
|
||||
{
|
||||
@ -296,6 +368,9 @@ public class NewNPCManager extends MiniPlugin
|
||||
_builders.remove(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles {@link NPCDeleteCommand} and {@link NPCMoveCommand} data input.
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void npcInteract(NPCInteractEvent event)
|
||||
{
|
||||
@ -318,6 +393,9 @@ public class NewNPCManager extends MiniPlugin
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevents chunk unloading when there is an NPC in it.
|
||||
*/
|
||||
@EventHandler
|
||||
public void chunkUnload(ChunkUnloadEvent event)
|
||||
{
|
||||
@ -331,6 +409,10 @@ public class NewNPCManager extends MiniPlugin
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
A collection of listeners that make sure NPCs don't die.
|
||||
*/
|
||||
|
||||
@EventHandler
|
||||
public void entityCombust(EntityCombustEvent event)
|
||||
{
|
||||
@ -383,6 +465,11 @@ public class NewNPCManager extends MiniPlugin
|
||||
event.GetEntities().removeIf(this::isNPC);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param metadata The metadata you wish to find all the NPCs of.
|
||||
* @return A list of {@link NPC} that are unloaded (have no entity attached to them) and that have the metadata
|
||||
* specified.
|
||||
*/
|
||||
private List<NPC> getUnloadedNPCs(String metadata)
|
||||
{
|
||||
return _npcs.stream()
|
||||
@ -390,6 +477,10 @@ public class NewNPCManager extends MiniPlugin
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param entity The entity you want to get it's NPC of.
|
||||
* @return The {@link NPC} representation of that entity or null if the entity is not an NPC.
|
||||
*/
|
||||
public NPC getNPC(Entity entity)
|
||||
{
|
||||
for (NPC npc : _npcs)
|
||||
@ -403,6 +494,10 @@ public class NewNPCManager extends MiniPlugin
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param entity The entity you want to check.
|
||||
* @return true if the entity is a {@link NPC}.
|
||||
*/
|
||||
private boolean isNPC(Entity entity)
|
||||
{
|
||||
return getNPC(entity) != null;
|
||||
|
@ -17,13 +17,31 @@ import mineplex.serverdata.database.column.ColumnDouble;
|
||||
import mineplex.serverdata.database.column.ColumnInt;
|
||||
import mineplex.serverdata.database.column.ColumnVarChar;
|
||||
|
||||
/**
|
||||
* A repository class that provides an interface for getting and saving NPCs.
|
||||
*/
|
||||
class NewNPCRepository extends RepositoryBase
|
||||
{
|
||||
|
||||
/**
|
||||
* A SQL statement that returns all entries form the table.
|
||||
*/
|
||||
private static final String GET_NPCS = "SELECT * FROM newNPCs;";
|
||||
/**
|
||||
* A SQL statement that inserts an entry and returns the id field generated.
|
||||
*/
|
||||
private static final String INSERT_NPC = "INSERT INTO newNPCs (entity_type, name, world, x, y, z, yaw, pitch, in_hand, in_hand_data, helmet, chestplate, leggings, boots, metadata, skinValue, skinSignature) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);";
|
||||
/**
|
||||
* A SQL statement that deletes an entry with a specific id field.
|
||||
*/
|
||||
private static final String DELETE_NPC = "DELETE FROM newNPCs WHERE id=?;";
|
||||
/**
|
||||
* A SQL statement that removes all entries from the table.
|
||||
*/
|
||||
private static final String CLEAR_NPCS = "DELETE FROM newNPCs;";
|
||||
/**
|
||||
* A SQL statement that adjusts the location properties of an entry with a specific id field.
|
||||
*/
|
||||
private static final String MOVE_NPC = "UPDATE newNPCs SET world=?, x=?, y=?, z=?, yaw=?, pitch=? WHERE id=?";
|
||||
|
||||
NewNPCRepository()
|
||||
@ -31,12 +49,23 @@ class NewNPCRepository extends RepositoryBase
|
||||
super(DBPool.getAccount());
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the SQL query:
|
||||
* <p>
|
||||
* {@value GET_NPCS}
|
||||
* </p>
|
||||
* The values return are parsed into an instance of {@link NPC} or one of it's subclasses such as {@link PlayerNPC}
|
||||
* if appropriate.
|
||||
*
|
||||
* @param response The consumer callback that supplies the list of NPCs.
|
||||
*/
|
||||
void getNPCs(Consumer<List<NPC>> response)
|
||||
{
|
||||
executeQuery(GET_NPCS, resultSet ->
|
||||
{
|
||||
List<NPC> npcs = new ArrayList<>();
|
||||
|
||||
// While there are more entries
|
||||
while (resultSet.next())
|
||||
{
|
||||
int id = resultSet.getInt("id");
|
||||
@ -61,11 +90,13 @@ class NewNPCRepository extends RepositoryBase
|
||||
NPC npc;
|
||||
World world = Bukkit.getWorld(worldName);
|
||||
|
||||
// If the world is not loaded on the server then don't add it to the list
|
||||
if (world == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the entity type is of player then the NPC must be specified as a PlayerNPC
|
||||
if (entityType == EntityType.PLAYER)
|
||||
{
|
||||
npc = new PlayerNPC(id, name, new Location(world, x, y, z, yaw, pitch), inHand, inHandData, helmet, chestplate, leggings, boots, metadata, skinValue, skinSignature);
|
||||
@ -81,7 +112,8 @@ class NewNPCRepository extends RepositoryBase
|
||||
response.accept(npcs);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Simply calls Material.valueOf, if invalid null
|
||||
private Material parseMaterial(String material)
|
||||
{
|
||||
try
|
||||
@ -94,8 +126,18 @@ class NewNPCRepository extends RepositoryBase
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the SQL insert:
|
||||
* <p>
|
||||
* {@value INSERT_NPC}
|
||||
* </p>
|
||||
* If the NPC does not have an id of -1, the insert will not be run.
|
||||
*
|
||||
* @param npc The NPC you want to insert into the database.
|
||||
*/
|
||||
void insertNPCIfNotExists(NPC npc)
|
||||
{
|
||||
// If the id isn't -1 then it has already been inserted
|
||||
if (npc.getId() != -1)
|
||||
{
|
||||
return;
|
||||
@ -104,23 +146,48 @@ class NewNPCRepository extends RepositoryBase
|
||||
Column<?>[] columns = npc.toDatabaseQuery().toArray(new Column[0]);
|
||||
executeInsert(INSERT_NPC, resultSet ->
|
||||
{
|
||||
// If successful
|
||||
if (resultSet.next())
|
||||
{
|
||||
// Set the NPC's id with that generated by the database
|
||||
npc.setId(resultSet.getInt(1));
|
||||
}
|
||||
}, columns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the SQL insert:
|
||||
* <p>
|
||||
* {@value DELETE_NPC}
|
||||
* </p>
|
||||
*
|
||||
* @param npc The NPC you want to delete.
|
||||
*/
|
||||
void deleteNPC(NPC npc)
|
||||
{
|
||||
executeUpdate(DELETE_NPC, new ColumnInt("id", npc.getId()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the SQL insert:
|
||||
* <p>
|
||||
* {@value CLEAR_NPCS}
|
||||
* </p>
|
||||
*/
|
||||
void clearNPCs()
|
||||
{
|
||||
executeUpdate(CLEAR_NPCS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the SQL insert:
|
||||
* <p>
|
||||
* {@value MOVE_NPC}
|
||||
* </p>
|
||||
*
|
||||
* @param npc The NPC you want to teleport.
|
||||
* @param location The Location that you want to the npc to teleport to.
|
||||
*/
|
||||
void teleportNPC(NPC npc, Location location)
|
||||
{
|
||||
executeUpdate(MOVE_NPC,
|
||||
|
@ -19,7 +19,7 @@ public class NPCRefreshCommand extends CommandBase<NewNPCManager>
|
||||
public void Execute(Player caller, String[] args)
|
||||
{
|
||||
caller.sendMessage(F.main(Plugin.getName(), "Refreshing NPCs..."));
|
||||
Plugin.refreshNPCS();
|
||||
Plugin.runAsync(() -> Plugin.refreshNPCS());
|
||||
caller.sendMessage(F.main(Plugin.getName(), "Refreshed NPCs"));
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ public class NewsRepository extends RepositoryBase
|
||||
private static final String INSERT_NEWS = "INSERT INTO hubNews (newsValue) VALUES (?);";
|
||||
private static final String DELETE_NEWS = "DELETE FROM hubNews WHERE newsId=?;";
|
||||
|
||||
public NewsRepository()
|
||||
NewsRepository()
|
||||
{
|
||||
super(DBPool.getAccount());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user