Skip to content

Instantly share code, notes, and snippets.

@Namnodorel
Last active November 6, 2019 15:32
Show Gist options
  • Save Namnodorel/fbf72c7ae871115d78c9a6aa76c693b6 to your computer and use it in GitHub Desktop.
Save Namnodorel/fbf72c7ae871115d78c9a6aa76c693b6 to your computer and use it in GitHub Desktop.
import net.citizensnpcs.api.CitizensAPI;
import net.citizensnpcs.api.event.NPCSpawnEvent;
import net.citizensnpcs.api.npc.NPC;
import org.bukkit.Bukkit;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.plugin.Plugin;
import pl.betoncraft.betonquest.*;
import pl.betoncraft.betonquest.api.QuestEvent;
import pl.betoncraft.betonquest.config.Config;
import pl.betoncraft.betonquest.config.ConfigPackage;
import pl.betoncraft.betonquest.utils.PlayerConverter;
import java.util.HashMap;
import java.util.HashSet;
public class NPCHider implements Listener, Runnable{
private static NPCHider instance;
private EntityHider hider;
private HashMap<Integer, HashSet<ConditionID>> npcs;
private ConfigurationSection configSection;
private Integer updateInterval;
public static void init(Plugin plugin){
if(instance == null){
instance = new NPCHider(plugin);
}
}
private NPCHider(Plugin plugin){
configSection = BetonQuest.getInstance().getConfig().getConfigurationSection("hide_npcs");
if (configSection == null){
return;
}
hider = new EntityHider(plugin, EntityHider.Policy.BLACKLIST);
npcs = new HashMap<>();
loadFromConfig();
Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, this, 0L, 20 * updateInterval);
}
private void loadFromConfig(){
for(ConfigPackage cfgPackage : Config.getPackages().values()){
if(cfgPackage.getCustom().getConfig() == null || cfgPackage.getCustom().getConfig().getConfigurationSection("hide_npcs") == null){
continue;
}
for (String npcID : cfgPackage.getCustom().getConfig().getConfigurationSection("hide_npcs").getKeys(false)) {
try {
int id = Integer.parseInt(npcID);
NPC npc = CitizensAPI.getNPCRegistry().getById(id);
if(npc != null){
HashSet<ConditionID> conditions = new HashSet<>();
String conditionsString = cfgPackage.getCustom().getConfig().getConfigurationSection("hide_npcs").getString(npcID);
for(String condition : conditionsString.split(",")){
conditions.add(new ConditionID(cfgPackage, condition));
}
if(npcs.containsKey(id)){
npcs.get(id).addAll(conditions);
}else{
npcs.put(id, conditions);
}
}else{
System.out.println("[NPCHider]: An NPC with the id " + npcID + " does not exist!");
}
} catch (NumberFormatException e) {
System.err.println("[NPCHider]: Given NPC ID " + npcID + " is not a valid number!");
} catch (ObjectNotFoundException e){
System.err.println("[NPCHider]: " + e.getMessage());
}
}
}
updateInterval = configSection.getInt("updateInterval");
}
//These methods check the conditions and apply according visibilities immediately,
//and need to go through more or less entities and conditions depending on how specific
//the arguments are
public void applyVisibility(Player p, Integer npcID){
boolean hidden = true;
if(npcs.get(npcID).isEmpty()){
hidden = false;
}else{
for(ConditionID condition : npcs.get(npcID)){
if(!BetonQuest.condition(PlayerConverter.getID(p), condition)){
hidden = false;
break;
}
}
}
NPC npc = CitizensAPI.getNPCRegistry().getById(npcID);
if(npc.isSpawned()){
if(hidden){
hider.hideEntity(p, npc.getEntity());
}else{
hider.showEntity(p, npc.getEntity());
}
}
}
public void applyVisibility(Player p){
for(Integer npcID : npcs.keySet()){
applyVisibility(p, npcID);
}
}
public void applyVisibility(NPC npc){
for(Player p : Bukkit.getOnlinePlayers()){
applyVisibility(p, npc.getId());
}
}
public void applyVisibility(){
for(Player p : Bukkit.getOnlinePlayers()){
for(Integer npcID : npcs.keySet()){
applyVisibility(p, npcID);
}
}
}
public static NPCHider getInstance() {
return instance;
}
@Override
public void run() {
applyVisibility();
}
//We want to have the visibility applied immediately, NPCs shouldn't spawn, stay there for a second and only then disappear
@EventHandler
public void onNPCSpawn(NPCSpawnEvent event) {
applyVisibility(event.getNPC());
}
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
applyVisibility(event.getPlayer());
}
//Optional; in case something changed and the updated visibilities need to be applied immediately for that player
public static class UpdateVisibilityNowEvent extends QuestEvent {
public UpdateVisibilityNowEvent(Instruction instruction) throws InstructionParseException {
super(instruction);
}
@Override
public void run(String id) throws QuestRuntimeException {
NPCHider.getInstance().applyVisibility(PlayerConverter.getPlayer(id));
}
}
//Optional; I implemented it because in some cases there are temporary NPCs which shouldn't be
//Visible to everyone
public static class WriteHideConditionEvent extends QuestEvent {
private Integer npcID;
private HashSet<ConditionID> conditions;
public WriteHideConditionEvent(Instruction instruction) throws InstructionParseException {
super(instruction);
super.staticness = true;
super.persistent = true;
npcID = instruction.getInt();
conditions = new HashSet<>();
conditions.addAll(instruction.getList(instruction.getOptional("cons"), instruction::getCondition));
}
@Override
public void run(String s) throws QuestRuntimeException {
NPC npc = CitizensAPI.getNPCRegistry().getById(npcID);
if(npc != null){
NPCHider.getInstance().npcs.put(npcID, conditions);
NPCHider.getInstance().applyVisibility(npc);
}else{
System.out.println("[NPCHider]: An NPC with the id " + npcID + " does not exist!");
}
}
}
}
@MWFIAE
Copy link

MWFIAE commented Oct 27, 2017

@Namnodorel
I messed with Unity and Unreal-Engine a few times in the past which are even better equipped engines, but the problem with the whole moddeling/texturing/etc. still remains and I'm not very good with this artist stuff :p

@Co0sh
Nah, you don't have time for spam.
I already try to help all the other people in the issues so that you have more time to resolve my own issues and implementing features I could make good use of :3 (selfish me :3 )

@Namnodorel
Copy link
Author

@MWFIAE Me neither, but that can be learned. I found https://cgcookie.com/ to be a good resource for learning to model stuff. And you can still use the plenty of presets existing- in MC, you're using a number of "presets" as well, right? :D

@MWFIAE
Copy link

MWFIAE commented Oct 28, 2017

@Namnodorel looks good, will take a look at it sometime if I have some real free time :)
Yeah, but it's not the same, as all presets are from the same source and don't look wild mixed... You know what I mean, right?

@Namnodorel
Copy link
Author

Namnodorel commented Oct 29, 2017

@MWFIAE Yes, kinda. You can get them to look quite similar if you are picky about which presets you use. Buut of course it takes significantly more time to find the right stuff.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment