diff --git a/src/api/java/de/teamlapen/vampirism/api/entity/player/actions/DefaultAction.java b/src/api/java/de/teamlapen/vampirism/api/entity/player/actions/DefaultAction.java index fc6658b856..1596e6b62b 100755 --- a/src/api/java/de/teamlapen/vampirism/api/entity/player/actions/DefaultAction.java +++ b/src/api/java/de/teamlapen/vampirism/api/entity/player/actions/DefaultAction.java @@ -24,7 +24,7 @@ public DefaultAction(IPlayableFaction faction, ResourceLocation icons) { } /** - * Can be overriden to check addidional requirements + * Can be overridden to check additional requirements * * @return */ diff --git a/src/api/java/de/teamlapen/vampirism/api/event/VampirismVillageEvent.java b/src/api/java/de/teamlapen/vampirism/api/event/VampirismVillageEvent.java index 12882674d1..efbfb46c78 100644 --- a/src/api/java/de/teamlapen/vampirism/api/event/VampirismVillageEvent.java +++ b/src/api/java/de/teamlapen/vampirism/api/event/VampirismVillageEvent.java @@ -1,13 +1,22 @@ package de.teamlapen.vampirism.api.event; import de.teamlapen.vampirism.api.entity.IVillageCaptureEntity; +import de.teamlapen.vampirism.api.entity.factions.IFaction; +import de.teamlapen.vampirism.api.entity.factions.IPlayableFaction; import de.teamlapen.vampirism.api.world.IVampirismVillage; +import net.minecraft.block.state.IBlockState; import net.minecraft.entity.passive.EntityVillager; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraftforge.fml.common.eventhandler.Cancelable; import net.minecraftforge.fml.common.eventhandler.Event; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import java.util.List; public abstract class VampirismVillageEvent extends Event { @@ -31,7 +40,7 @@ public IVampirismVillage getVillage() { *

* Your villager should have the position set, but should not be spawned in the world. *

- * The willBeAggressive field tells if the villager will be converted to an aggressive version. You can change this. + * The {@linkplain #willBeConverted} field tells if the villager will be converted to an aggressive version. You can change this. * DON'T set an aggressive villager even if this field is true */ @HasResult @@ -45,12 +54,14 @@ public static class SpawnNewVillager extends VampirismVillageEvent { EntityVillager seedVillager; private @Nullable EntityVillager newVillager; - private boolean willBeVampire; + private boolean willBeConverted; + private final IPlayableFaction faction; - public SpawnNewVillager(@Nonnull IVampirismVillage village, @Nonnull EntityVillager seedVillager, boolean willBeVampire) { + public SpawnNewVillager(@Nonnull IVampirismVillage village, @Nonnull EntityVillager seedVillager, boolean willBeConverted, IPlayableFaction faction) { super(village); this.seedVillager = seedVillager; - this.willBeVampire = willBeVampire; + this.willBeConverted = willBeConverted; + this.faction = faction; } public EntityVillager getNewVillager() { @@ -78,32 +89,39 @@ public EntityVillager getSeedVillager() { } /** - * If the villager will be converted to a vampire version afterwards. - * Default: Is sometimes true if the village is controlled by vampires. Can be overridden by {@link #setWillBeVampire} + * If the villager will be converted afterwards (e.g. to a vampire version). + * Default: Is sometimes true if the village is not controlled by hunters. Can be overridden by {@link #setWillBeConverted} */ - public boolean isWillBeVampire() { - return willBeVampire; + public boolean isWillBeConverted() { + return willBeConverted; } /** * Overwrite the default value. */ - public void setWillBeVampire(boolean willBeVampire) { - this.willBeVampire = willBeVampire; + public void setWillBeConverted(boolean willBeConverted) { + this.willBeConverted = willBeConverted; } + + /** + * Faction that owns the village + */ + public IPlayableFaction getFaction() { + return faction; + } + } /** * Fired when a normal villager should be converted to angry villager. * You can set a custom replacement and cancel this event to make it take effect. - * The oldVillager is probably not added to a world + * The {@link #oldVillager} is probably not added to a world */ @Cancelable public static class MakeAggressive extends VampirismVillageEvent { private final EntityVillager oldVillager; - private @Nullable - IVillageCaptureEntity captureVillager; + private @Nullable IVillageCaptureEntity captureVillager; public MakeAggressive(@Nullable IVampirismVillage village, @Nonnull EntityVillager villager) { super(village); @@ -126,7 +144,7 @@ public EntityVillager getOldVillager() { * Set the aggressive version of the old villager. * Event has to be canceled for this to take effect * - * @param aggressiveVillager Must extend EntityVillager + * @param captureVillager Must extend EntityVillager */ public void setAgressiveVillager(@Nullable IVillageCaptureEntity captureVillager) { if (captureVillager != null && !(captureVillager instanceof EntityVillager)) { @@ -135,4 +153,288 @@ public void setAgressiveVillager(@Nullable IVillageCaptureEntity captureVillager this.captureVillager = captureVillager; } } + + /** + * Fired when the Capture process is finished the the Villager should be affected by the faction change + * if result is {@link Result#DENY} the Vanilla code is skipped + */ + @HasResult + public static class VillagerCaptureFinish extends VampirismVillageEvent { + + private final @Nonnull List villager; + private final @Nullable IPlayableFaction controllingFaction; + private final @Nonnull IPlayableFaction capturingFaction; + private final @Nonnull AxisAlignedBB affectedArea; + + public VillagerCaptureFinish(@Nonnull IVampirismVillage village, @Nonnull List villagerIn, @Nullable IPlayableFaction controllingFactionIn, @Nonnull IPlayableFaction capturingFactionIn, @Nonnull AxisAlignedBB affectedAreaIn) { + super(village); + villager = villagerIn; + controllingFaction = controllingFactionIn; + capturingFaction = capturingFactionIn; + affectedArea = affectedAreaIn; + } + + /** + * @returns all {@link EntityVillager} that are in the village boundingBox + */ + @Nonnull + public List getVillager() { + return villager; + } + + /** + * @returns the faction that controls the village before the village is converted to the new faction + */ + @Nullable + public IPlayableFaction getControllingFaction() { + return controllingFaction; + } + + /** + * @returns the faction that has captured the village at this moment + */ + @Nonnull + public IPlayableFaction getCapturingFaction() { + return capturingFaction; + } + + /** + * @returns the village area + */ + @Nonnull + public AxisAlignedBB getAffectedArea(){ return affectedArea;} + + @Nonnull + @Override + public IVampirismVillage getVillage() { + return super.getVillage(); + } + } + + /** + * Fired when a new Capture Entity should be spawned and the faction of the entity is not a Hunter or Vampire Entity + */ + public static class SpawnCaptureEntity extends VampirismVillageEvent { + + private @Nonnull final IFaction faction; + private ResourceLocation entity; + + public SpawnCaptureEntity(@Nullable IVampirismVillage village, @Nonnull IFaction f) { + super(village); + faction = f; + } + + /** + * the faction of the spawning entity + */ + @Nonnull + public IFaction getFaction() { + return faction; + } + + /** + * set the Entity to spawn + * + * @param {@link ResourceLocation} + * of the entity + */ + public void setEntity(ResourceLocation entity) { + this.entity = entity; + } + + /** + * @returns {@link ResourceLocation} of the capture entity which should be spawned + */ + @Nullable + public ResourceLocation getEntity() { + return entity; + } + } + + /** + * Fired when a Faction villager should be spawned, but the controlling faction in not hunter or vampire. + * The {@link #newVillager} will replace the {@link #seed} villager + */ + public static class SpawnFactionVillager extends VampirismVillageEvent { + + private final @Nonnull IPlayableFaction faction; + private final @Nonnull EntityVillager seed; + private EntityVillager newVillager; + private boolean poisonousBlood; + + public SpawnFactionVillager(@Nullable IVampirismVillage village, @Nonnull EntityVillager seed, @Nonnull IPlayableFaction faction) { + super(village); + this.faction = faction; + this.seed = seed; + } + + /** + * faction of the village + */ + @Nonnull + public IPlayableFaction getFaction() { + return faction; + } + + /** + * @returns entity to be replaced + */ + @Nonnull + public EntityVillager getSeed() { + return seed; + } + + /** + * @returns the new villager + */ + @Nullable + public EntityVillager getVillager() { + return newVillager; + } + + /** + * sets the new villager + */ + public void setVillager(EntityVillager villager) { + newVillager = villager; + } + + /** + * if the villager should be protected against vampire + */ + public boolean hasPoisonousBlood() { + return poisonousBlood; + } + + /** + * sets the protection against vampire + */ + public void setPoisonousBlood(boolean poisonous) { + poisonousBlood = poisonous; + } + + } + + /** + * Fired when blocks around a village should be replaced + * Only fired if Vampirism didn't already replace a block. + * Can be used to replace a block on your own + */ + public static class ReplaceBlock extends VampirismVillageEvent { + + private final @Nonnull World world; + private final @Nonnull IBlockState state; + private final @Nonnull IPlayableFaction faction; + private final @Nonnull + BlockPos pos; + + public ReplaceBlock(@Nullable IVampirismVillage village, @Nonnull World world, @Nonnull IBlockState b, @Nonnull BlockPos pos, @Nonnull IPlayableFaction controllingFaction) { + super(village); + this.world = world; + this.state = b; + this.faction = controllingFaction; + this.pos = pos; + } + + /** + * @returns the world of the block + */ + @Nonnull + public World getWorld() { + return world; + } + + /** + * @returns blockstate of the block to be replaced + */ + @Nonnull + public IBlockState getState() { + return state; + } + + /** + * @returns faction of the village + */ + @Nonnull + public IPlayableFaction getFaction() { + return faction; + } + + /** + * @returns the position of the block + */ + @Nonnull + public BlockPos getBlockPos() { + return pos; + } + + } + + /** + * fired when the caption process is started + * set the result to DENY to skip the vanilla code + */ + @HasResult + public static class InitiateCapture extends VampirismVillageEvent { + + private final @Nonnull World world; + private final @Nullable IPlayableFaction controllingFaction; + private final @Nonnull IPlayableFaction capturingFaction; + + public InitiateCapture(@Nonnull IVampirismVillage village, @Nonnull World world, @Nullable IPlayableFaction controllingFaction, @Nonnull IPlayableFaction capturingFaction) { + super(village); + this.world = world; + this.controllingFaction = controllingFaction; + this.capturingFaction = capturingFaction; + } + + @Nonnull + public World getWorld() { + return world; + } + + /** + * @returns controlling faction + */ + @Nullable + public IPlayableFaction getControllingFaction() { + return controllingFaction; + } + + /** + * @returns capturing faction + */ + @Nonnull + public IPlayableFaction getCapturingFaction() { + return capturingFaction; + } + + @Nonnull + @Override + public IVampirismVillage getVillage() { + return super.getVillage(); + } + } + + /** + * fired when the village area is updated (used for vampire fog rendering & sundamage) + */ + public static class UpdateBoundingBox extends VampirismVillageEvent { + + private final @Nonnull StructureBoundingBox bb; + + public UpdateBoundingBox(@Nullable IVampirismVillage village, @Nonnull StructureBoundingBox bb) { + super(village); + this.bb = bb; + } + + /** + * @returns bounding box of the village + */ + @Nonnull + public StructureBoundingBox getBoundingBox() { + return bb; + } + + } } diff --git a/src/main/java/de/teamlapen/vampirism/VampirismMod.java b/src/main/java/de/teamlapen/vampirism/VampirismMod.java index 821d4424b9..f35810dc55 100755 --- a/src/main/java/de/teamlapen/vampirism/VampirismMod.java +++ b/src/main/java/de/teamlapen/vampirism/VampirismMod.java @@ -166,6 +166,7 @@ public void init(FMLInitializationEvent event) { VampireBookManager.getInstance().init(); BloodPotions.register(); StructureManager.init(); + Permissions.init(); VampirismEntitySelectors.registerSelectors(); registryManager.onInitStep(IInitListener.Step.INIT, event); proxy.onInitStep(IInitListener.Step.INIT, event); diff --git a/src/main/java/de/teamlapen/vampirism/client/core/ModEntitiesRender.java b/src/main/java/de/teamlapen/vampirism/client/core/ModEntitiesRender.java index 4a9b40b9a9..ad32b54e77 100755 --- a/src/main/java/de/teamlapen/vampirism/client/core/ModEntitiesRender.java +++ b/src/main/java/de/teamlapen/vampirism/client/core/ModEntitiesRender.java @@ -4,12 +4,9 @@ import de.teamlapen.vampirism.client.render.entities.*; import de.teamlapen.vampirism.entity.*; import de.teamlapen.vampirism.entity.converted.EntityConvertedCreature; +import de.teamlapen.vampirism.entity.converted.EntityConvertedHorse; import de.teamlapen.vampirism.entity.converted.EntityConvertedVillager; -import de.teamlapen.vampirism.entity.hunter.EntityAdvancedHunter; -import de.teamlapen.vampirism.entity.hunter.EntityAggressiveVillager; -import de.teamlapen.vampirism.entity.hunter.EntityBasicHunter; -import de.teamlapen.vampirism.entity.hunter.EntityHunterTrainer; -import de.teamlapen.vampirism.entity.hunter.EntityHunterTrainerDummy; +import de.teamlapen.vampirism.entity.hunter.*; import de.teamlapen.vampirism.entity.minions.vampire.EntityVampireMinionBase; import de.teamlapen.vampirism.entity.special.EntityDraculaHalloween; import de.teamlapen.vampirism.entity.vampire.EntityAdvancedVampire; @@ -48,5 +45,6 @@ public static void registerEntityRenderer() { RenderingRegistry.registerEntityRenderingHandler(EntityDarkBloodProjectile.class, RenderDarkBloodProjectile::new); RenderingRegistry.registerEntityRenderingHandler(EntitySoulOrb.class, manager -> new RenderSoulOrb(manager, Minecraft.getMinecraft().getRenderItem())); RenderingRegistry.registerEntityRenderingHandler(EntityHunterTrainerDummy.class, RenderHunterTrainerDummy::new); + RenderingRegistry.registerEntityRenderingHandler(EntityConvertedHorse.class, RenderConvertedHorse::new); } } diff --git a/src/main/java/de/teamlapen/vampirism/client/render/entities/RenderConvertedHorse.java b/src/main/java/de/teamlapen/vampirism/client/render/entities/RenderConvertedHorse.java new file mode 100644 index 0000000000..7b7aa9c860 --- /dev/null +++ b/src/main/java/de/teamlapen/vampirism/client/render/entities/RenderConvertedHorse.java @@ -0,0 +1,17 @@ +package de.teamlapen.vampirism.client.render.entities; + +import de.teamlapen.vampirism.client.render.LayerVampireEntity; +import de.teamlapen.vampirism.util.REFERENCE; +import net.minecraft.client.renderer.entity.RenderHorse; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.util.ResourceLocation; + +public class RenderConvertedHorse extends RenderHorse { + + private final ResourceLocation overlay = new ResourceLocation(REFERENCE.MODID, "textures/entity/vanilla/horse_overlay.png"); + + public RenderConvertedHorse(RenderManager renderManager) { + super(renderManager); + this.addLayer(new LayerVampireEntity(this, overlay, false)); + } +} diff --git a/src/main/java/de/teamlapen/vampirism/core/ModEntities.java b/src/main/java/de/teamlapen/vampirism/core/ModEntities.java index 6cbd317af6..adec446684 100755 --- a/src/main/java/de/teamlapen/vampirism/core/ModEntities.java +++ b/src/main/java/de/teamlapen/vampirism/core/ModEntities.java @@ -8,6 +8,7 @@ import de.teamlapen.vampirism.config.Balance; import de.teamlapen.vampirism.entity.*; import de.teamlapen.vampirism.entity.converted.EntityConvertedCreature; +import de.teamlapen.vampirism.entity.converted.EntityConvertedHorse; import de.teamlapen.vampirism.entity.converted.EntityConvertedSheep; import de.teamlapen.vampirism.entity.converted.EntityConvertedVillager; import de.teamlapen.vampirism.entity.hunter.*; @@ -71,6 +72,7 @@ public class ModEntities { public static final String VILLAGER_ANGRY = "villager_angry"; public static final String VILLAGER_CONVERTED = "villager_converted"; public static final String HUNTER_TRAINER_DUMMY = "hunter_trainer_dummy"; + public static final String HORSE_CONVERTED = "converted_horse"; /** @@ -98,7 +100,7 @@ static void registerConvertibles() { registry.addConvertible(EntityCow.class, String.format(base, "cow")); registry.addConvertible(EntityPig.class, String.format(base, "pig")); registry.addConvertible(EntityOcelot.class, String.format(base, "cat")); - registry.addConvertible(EntityHorse.class, String.format(base, "horse")); + registry.addConvertible(EntityHorse.class, String.format(base, "horse"), new EntityConvertedHorse.ConvertingHandler()); registry.addConvertible(EntityPolarBear.class, String.format(base, "polarbear")); registry.addConvertible(EntityRabbit.class, String.format(base, "rabbit")); registry.addConvertible(EntitySheep.class, String.format(base, "sheep"), new EntityConvertedSheep.ConvertingHandler()); @@ -138,6 +140,7 @@ static void registerEntities(IForgeRegistry registry) { registry.register(prepareEntityEntry(EntityHunterFactionVillager.class, VILLAGER_HUNTER_FACTION, null, EntityLiving.SpawnPlacementType.ON_GROUND, false).build()); registry.register(prepareEntityEntry(EntityVampireFactionVillager.class, VILLAGER_VAMPIRE_FACTION, null, EntityLiving.SpawnPlacementType.ON_GROUND, false).build()); registry.register(prepareEntityEntry(EntityHunterTrainerDummy.class, HUNTER_TRAINER_DUMMY, "hunter_trainer_dummy", EntityLiving.SpawnPlacementType.ON_GROUND, false).build()); + registry.register(prepareEntityEntry(EntityConvertedHorse.class, HORSE_CONVERTED, null, EntityLiving.SpawnPlacementType.ON_GROUND, false).build()); } static Biome[] getZombieBiomes() { diff --git a/src/main/java/de/teamlapen/vampirism/core/ModEventHandler.java b/src/main/java/de/teamlapen/vampirism/core/ModEventHandler.java index bd8c0caa06..a986f349cc 100755 --- a/src/main/java/de/teamlapen/vampirism/core/ModEventHandler.java +++ b/src/main/java/de/teamlapen/vampirism/core/ModEventHandler.java @@ -12,6 +12,7 @@ import de.teamlapen.vampirism.network.SyncConfigPacket; import de.teamlapen.vampirism.tileentity.TileTotem; import de.teamlapen.vampirism.util.DaySleepHelper; +import de.teamlapen.vampirism.util.Permissions; import de.teamlapen.vampirism.util.REFERENCE; import de.teamlapen.vampirism.world.ModWorldEventListener; import de.teamlapen.vampirism.world.villages.VampirismVillage; @@ -40,6 +41,7 @@ import net.minecraftforge.fml.common.network.FMLNetworkEvent; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; +import net.minecraftforge.server.permission.PermissionAPI; import java.util.List; @@ -133,6 +135,9 @@ public void onPlayerLoggedIn(PlayerEvent.PlayerLoggedInEvent event) { event.player.sendMessage(new TextComponentString("For more information use " + TextFormatting.DARK_GREEN + "'/vampirism resetBalance help'" + TextFormatting.RESET)); } } + if (!PermissionAPI.hasPermission(event.player, Permissions.VAMPIRISM)) { + event.player.sendMessage(new TextComponentString("[" + TextFormatting.DARK_PURPLE + "Vampirism" + TextFormatting.RESET + "] It seems like the permission plugin used is not properly set up. Make sure all players have 'vampirism.*' for the mod to work (or at least '" + Permissions.VAMPIRISM + "' to suppress this warning).")); + } if (!Configs.disable_config_sync) { if (event.player != null && (event.player instanceof EntityPlayerMP)) { diff --git a/src/main/java/de/teamlapen/vampirism/entity/converted/BiteableEntryManager.java b/src/main/java/de/teamlapen/vampirism/entity/converted/BiteableEntryManager.java index 17d103e27e..53138b9592 100644 --- a/src/main/java/de/teamlapen/vampirism/entity/converted/BiteableEntryManager.java +++ b/src/main/java/de/teamlapen/vampirism/entity/converted/BiteableEntryManager.java @@ -5,6 +5,7 @@ import com.google.common.collect.Sets; import de.teamlapen.vampirism.VampirismMod; import de.teamlapen.vampirism.api.entity.BiteableEntry; +import de.teamlapen.vampirism.api.entity.vampire.IVampire; import de.teamlapen.vampirism.config.Configs; import net.minecraft.entity.EntityCreature; import net.minecraft.entity.EntityList; @@ -86,7 +87,7 @@ BiteableEntry calculate(EntityCreature creature) { if (blacklist.contains(id)) return null; BiteableEntry entry = get(id); if (entry != null) return entry; - if (!Configs.autoCalculateEntityBlood || !(creature instanceof EntityAnimal)) { + if (!Configs.autoCalculateEntityBlood || !(creature instanceof EntityAnimal) || creature instanceof IVampire) { blacklist.add(id); return null; } diff --git a/src/main/java/de/teamlapen/vampirism/entity/converted/EntityConvertedHorse.java b/src/main/java/de/teamlapen/vampirism/entity/converted/EntityConvertedHorse.java new file mode 100644 index 0000000000..f14b2576e1 --- /dev/null +++ b/src/main/java/de/teamlapen/vampirism/entity/converted/EntityConvertedHorse.java @@ -0,0 +1,258 @@ +package de.teamlapen.vampirism.entity.converted; + +import de.teamlapen.lib.lib.util.UtilLib; +import de.teamlapen.vampirism.api.EnumStrength; +import de.teamlapen.vampirism.api.VReference; +import de.teamlapen.vampirism.api.VampirismAPI; +import de.teamlapen.vampirism.api.entity.convertible.IConvertedCreature; +import de.teamlapen.vampirism.api.entity.convertible.IConvertingHandler; +import de.teamlapen.vampirism.api.items.IVampireFinisher; +import de.teamlapen.vampirism.config.Balance; +import de.teamlapen.vampirism.core.ModPotions; +import de.teamlapen.vampirism.entity.DamageHandler; +import de.teamlapen.vampirism.entity.EntityCrossbowArrow; +import de.teamlapen.vampirism.entity.EntitySoulOrb; +import de.teamlapen.vampirism.util.Helper; +import de.teamlapen.vampirism.util.REFERENCE; +import net.minecraft.entity.*; +import net.minecraft.entity.ai.EntityAIAvoidEntity; +import net.minecraft.entity.ai.EntityAIHurtByTarget; +import net.minecraft.entity.ai.EntityAINearestAttackableTarget; +import net.minecraft.entity.ai.EntityAIRestrictSun; +import net.minecraft.entity.passive.EntityHorse; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.MobEffects; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.potion.PotionEffect; +import net.minecraft.util.DamageSource; +import net.minecraft.util.math.MathHelper; +import net.minecraft.world.World; + +public class EntityConvertedHorse extends EntityHorse implements IConvertedCreature { + + private EnumStrength garlicCache = EnumStrength.NONE; + private EntityHorse entityCreature; + private boolean sundamageCache; + private boolean dropSoul = false; + protected boolean vulnerableToFire = true; + + public EntityConvertedHorse(World world) { + super(world); + } + + @Override + public EnumCreatureAttribute getCreatureAttribute() { + return VReference.VAMPIRE_CREATURE_ATTRIBUTE; + } + + @Override + public float getEyeHeight() { + return height * 0.875f; + } + + @Override + public EntityLivingBase getRepresentingEntity() { + return this; + } + + @Override + public String getName() { + return UtilLib.translate("entity.vampirism.vampire.name") + " " + UtilLib.translate("entity.Horse.name"); + } + + @Override + public boolean isCreatureType(EnumCreatureType type, boolean forSpawnCount) { + if (forSpawnCount) return true; + return super.isCreatureType(type, forSpawnCount); + } + + @Override + protected void dropFewItems(boolean wasRecentlyHit, int lootingModifier) { + getConvertedHelper().dropConvertedItems(this, entityCreature, wasRecentlyHit, lootingModifier); + } + + /** + * @return The {@link de.teamlapen.vampirism.api.entity.convertible.IConvertingHandler.IDefaultHelper} for this creature + */ + protected IConvertingHandler.IDefaultHelper getConvertedHelper() { + IConvertingHandler handler = VampirismAPI.entityRegistry().getEntry(entityCreature).convertingHandler; + if (handler instanceof ConvertingHandler) { + return ((ConvertingHandler) handler).getHelper(); + } + return null; + } + + @Override + protected boolean canDespawn() { + return !isTame(); + } + + @Override + public boolean doesResistGarlic(EnumStrength strength) { + return !strength.isStrongerThan(EnumStrength.NONE); + } + + @Override + public void drinkBlood(int amt, float saturationMod, boolean useRemaining) { + this.addPotionEffect(new PotionEffect(MobEffects.REGENERATION, amt * 20)); + } + + @Override + public EnumStrength isGettingGarlicDamage(boolean forceRefresh) { + if (forceRefresh) { + garlicCache = Helper.getGarlicStrength(this); + } + return garlicCache; + } + + @Override + public boolean isGettingSundamage(boolean forceRefresh) { + if (!forceRefresh) + return sundamageCache; + return (sundamageCache = Helper.gettingSundamge(this)); + } + + @Override + public boolean isIgnoringSundamage() { + return this.isPotionActive(ModPotions.sunscreen); + } + + @Override + public boolean useBlood(int amt, boolean allowPartial) { + this.addPotionEffect(new PotionEffect(MobEffects.WEAKNESS, amt * 20)); + return true; + } + + @Override + public boolean wantsBlood() { + return false; + } + + @Override + public void onLivingUpdate() { + if (this.ticksExisted % REFERENCE.REFRESH_GARLIC_TICKS == 1) { + isGettingGarlicDamage(true); + } + if (this.ticksExisted % REFERENCE.REFRESH_SUNDAMAGE_TICKS == 2) { + isGettingSundamage(true); + } + if (!world.isRemote) { + if (isGettingSundamage() && ticksExisted % 40 == 11) { + double dmg = getEntityAttribute(VReference.sunDamage).getAttributeValue(); + if (dmg > 0) this.attackEntityFrom(VReference.SUNDAMAGE, (float) dmg); + } + if (isGettingGarlicDamage() != EnumStrength.NONE) { + DamageHandler.affectVampireGarlicAmbient(this, isGettingGarlicDamage(), this.ticksExisted); + } + if (isEntityAlive() && isInWater()) { + setAir(300); + if (ticksExisted % 16 == 4) { + addPotionEffect(new PotionEffect(MobEffects.WEAKNESS, 80, 0)); + } + } + } + super.onLivingUpdate(); + } + + @Override + public void onDeath(DamageSource cause) { + super.onDeath(cause); + if (cause.getImmediateSource() instanceof EntityCrossbowArrow && Helper.isHunter(cause.getTrueSource())) { + dropSoul = true; + } else if (cause.getImmediateSource() instanceof EntityPlayer && Helper.isHunter(cause.getImmediateSource())) { + ItemStack weapon = ((EntityPlayer) cause.getImmediateSource()).getHeldItemMainhand(); + if (!weapon.isEmpty() && weapon.getItem() instanceof IVampireFinisher) { + dropSoul = true; + } + } else { + dropSoul = false;//In case a previous death has been canceled somehow + } + } + + @Override + protected void onDeathUpdate() { + if (this.deathTime == 19) { + if (!this.world.isRemote && (dropSoul && this.world.getGameRules().getBoolean("doMobLoot"))) { + this.world.spawnEntity(new EntitySoulOrb(this.world, this.posX, this.posY, this.posZ, EntitySoulOrb.TYPE.VAMPIRE)); + } + } + super.onDeathUpdate(); + } + + @Override + public boolean attackEntityFrom(DamageSource damageSource, float amount) { + if (vulnerableToFire) { + if (DamageSource.IN_FIRE.equals(damageSource)) { + return this.attackEntityFrom(VReference.VAMPIRE_IN_FIRE, calculateFireDamage(amount)); + } else if (DamageSource.ON_FIRE.equals(damageSource)) { + return this.attackEntityFrom(VReference.VAMPIRE_ON_FIRE, calculateFireDamage(amount)); + } + } + return super.attackEntityFrom(damageSource, amount); + } + + /** + * Calculates the increased fire damage is this vampire creature is especially vulnerable to fire + * + * @param amount + * @return + */ + protected float calculateFireDamage(float amount) { + return amount; + } + + @Override + protected void initEntityAI() { + super.initEntityAI(); + + this.tasks.addTask(1, new EntityAIAvoidEntity<>(this, EntityCreature.class, VampirismAPI.factionRegistry().getPredicate(getFaction(), false, true, false, false, VReference.HUNTER_FACTION), 10, 1.0, 1.1)); + this.tasks.addTask(4, new EntityAIRestrictSun(this)); + this.experienceValue = 2; + + this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false)); + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget<>(this, EntityPlayer.class, 5, true, false, VampirismAPI.factionRegistry().getPredicate(getFaction(), true, false, true, false, null))); + this.targetTasks.addTask(3, new EntityAINearestAttackableTarget<>(this, EntityCreature.class, 5, true, false, VampirismAPI.factionRegistry().getPredicate(getFaction(), false, true, false, false, null))); + } + + @Override + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + getAttributeMap().registerAttribute(VReference.sunDamage).setBaseValue(Balance.mobProps.VAMPIRE_MOB_SUN_DAMAGE); + } + + protected void updateEnttityAttributes() { + IConvertingHandler.IDefaultHelper helper = getConvertedHelper(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(helper.getConvertedMaxHealth(entityCreature)); + this.getEntityAttribute(SharedMonsterAttributes.KNOCKBACK_RESISTANCE).setBaseValue(helper.getConvertedKnockbackResistance(entityCreature)); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(helper.getConvertedSpeed(entityCreature)); + } + + protected void setEntityCreature(EntityHorse creature) { + entityCreature = creature; + } + + public static class ConvertingHandler extends DefaultConvertingHandler { + public ConvertingHandler() { + super(null); + } + + @Override + public IConvertedCreature createFrom(EntityHorse entity) { + EntityConvertedHorse converted = new EntityConvertedHorse(entity.world); + copyImportantStuff(converted, entity); + converted.setUniqueId(MathHelper.getRandomUUID(converted.rand)); + converted.addPotionEffect(new PotionEffect(MobEffects.WEAKNESS, 200, 2)); + return converted; + } + + protected void copyImportantStuff(EntityConvertedHorse converted, EntityHorse entity) { + NBTTagCompound nbt = new NBTTagCompound(); + entity.writeToNBT(nbt); + converted.readFromNBT(nbt); + converted.setEntityCreature(entity); + converted.updateEnttityAttributes(); + converted.setHealth(converted.getMaxHealth() / 3 * 2); + } + } +} diff --git a/src/main/java/de/teamlapen/vampirism/entity/factions/FactionPlayerHandler.java b/src/main/java/de/teamlapen/vampirism/entity/factions/FactionPlayerHandler.java index e3c979f4de..bf824d7432 100755 --- a/src/main/java/de/teamlapen/vampirism/entity/factions/FactionPlayerHandler.java +++ b/src/main/java/de/teamlapen/vampirism/entity/factions/FactionPlayerHandler.java @@ -7,9 +7,9 @@ import de.teamlapen.vampirism.api.entity.factions.IFactionPlayerHandler; import de.teamlapen.vampirism.api.entity.factions.IPlayableFaction; import de.teamlapen.vampirism.api.entity.player.IFactionPlayer; -import de.teamlapen.vampirism.api.event.FactionEvent; import de.teamlapen.vampirism.config.Configs; import de.teamlapen.vampirism.core.ModAdvancements; +import de.teamlapen.vampirism.util.ModEventFactory; import de.teamlapen.vampirism.util.REFERENCE; import de.teamlapen.vampirism.util.ScoreboardUtil; import net.minecraft.entity.player.EntityPlayer; @@ -20,7 +20,6 @@ import net.minecraft.util.EntityDamageSource; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; -import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.capabilities.*; import net.minecraftforge.fml.common.eventhandler.Event; @@ -91,12 +90,11 @@ private FactionPlayerHandler(EntityPlayer player) { @Override public boolean canJoin(IPlayableFaction faction) { - FactionEvent.CanJoinFaction event = new FactionEvent.CanJoinFaction(this, currentFaction, faction); - MinecraftForge.EVENT_BUS.post(event); - if (event.getResult() == Event.Result.DEFAULT) { + Event.Result res = ModEventFactory.fireCanJoinFactionEvent(this,currentFaction,faction); + if (res == Event.Result.DEFAULT) { return currentFaction == null; } - return event.getResult() == Event.Result.ALLOW; + return res == Event.Result.ALLOW; } @Override @@ -237,8 +235,7 @@ public boolean setFactionAndLevel(IPlayableFaction faction, int level) { VampirismMod.log.w(TAG, "Level %d in faction %s cannot be reached", level, faction.getKey()); return false; } - FactionEvent.ChangeLevelOrFaction event = new FactionEvent.ChangeLevelOrFaction(this, old, oldLevel, faction, faction == null ? 0 : level); - if (MinecraftForge.EVENT_BUS.post(event)) { + if (ModEventFactory.fireChangeLevelOrFactionEvent(this, old, oldLevel, faction, faction == null ? 0 : level)) { VampirismMod.log.d(TAG, "Faction or Level change event canceled"); return false; } diff --git a/src/main/java/de/teamlapen/vampirism/network/InputEventPacket.java b/src/main/java/de/teamlapen/vampirism/network/InputEventPacket.java index 23dddd3257..50549f623c 100755 --- a/src/main/java/de/teamlapen/vampirism/network/InputEventPacket.java +++ b/src/main/java/de/teamlapen/vampirism/network/InputEventPacket.java @@ -125,6 +125,8 @@ public IMessage handleServerMessage(EntityPlayer player, InputEventPacket messag case COOLDOWN: player.sendMessage(new TextComponentTranslation("text.vampirism.action.cooldown_not_over")); break; + case DISALLOWED: + player.sendMessage(new TextComponentTranslation("text.vampirism.action.disallowed")); default://Everything alright } } else { diff --git a/src/main/java/de/teamlapen/vampirism/player/actions/ActionHandler.java b/src/main/java/de/teamlapen/vampirism/player/actions/ActionHandler.java index 6d6e15fe1d..8e2a18f8e7 100755 --- a/src/main/java/de/teamlapen/vampirism/player/actions/ActionHandler.java +++ b/src/main/java/de/teamlapen/vampirism/player/actions/ActionHandler.java @@ -7,12 +7,14 @@ import de.teamlapen.vampirism.api.entity.player.actions.IActionHandler; import de.teamlapen.vampirism.api.entity.player.actions.ILastingAction; import de.teamlapen.vampirism.core.VampirismRegistries; +import de.teamlapen.vampirism.util.Permissions; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import it.unimi.dsi.fastutil.objects.ObjectIterator; import it.unimi.dsi.fastutil.objects.ObjectSet; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.ResourceLocation; +import net.minecraftforge.server.permission.PermissionAPI; import javax.annotation.Nonnull; import java.util.ArrayList; @@ -248,6 +250,7 @@ public IAction.PERM toggleAction(IAction action) { return IAction.PERM.COOLDOWN; } else{ if (!isActionUnlocked(action)) return IAction.PERM.NOT_UNLOCKED; + if (!isActionAllowedPermission(action)) return IAction.PERM.DISALLOWED; IAction.PERM r = action.canUse(player); if (r == IAction.PERM.ALLOWED) { if (action.onActivated(player)) { @@ -277,6 +280,11 @@ public void unlockActions(Collection actions) { unlockedActions.addAll(actions); } + private boolean isActionAllowedPermission(IAction action) { + ResourceLocation id = action.getRegistryName(); + return player.getRepresentingEntity().world.isRemote || PermissionAPI.hasPermission(player.getRepresentingPlayer(), Permissions.ACTION_PREFIX + id.getNamespace() + "." + id.getPath()); + } + /** * Update the actions * Should only be called by the corresponding Capability instance diff --git a/src/main/java/de/teamlapen/vampirism/player/vampire/VampirePlayer.java b/src/main/java/de/teamlapen/vampirism/player/vampire/VampirePlayer.java index 7bab6b98ab..24b0e9239c 100755 --- a/src/main/java/de/teamlapen/vampirism/player/vampire/VampirePlayer.java +++ b/src/main/java/de/teamlapen/vampirism/player/vampire/VampirePlayer.java @@ -34,7 +34,6 @@ import de.teamlapen.vampirism.potion.PotionSanguinare; import de.teamlapen.vampirism.potion.VampireNightVisionEffect; import de.teamlapen.vampirism.util.*; - import net.minecraft.block.state.IBlockState; import net.minecraft.entity.*; import net.minecraft.entity.ai.attributes.IAttribute; @@ -63,16 +62,16 @@ import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.gameevent.TickEvent; import net.minecraftforge.fml.relauncher.ReflectionHelper; +import net.minecraftforge.server.permission.PermissionAPI; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.function.Predicate; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import static de.teamlapen.lib.lib.util.UtilLib.getNull; /** @@ -284,7 +283,7 @@ public BITE_TYPE determineBiteType(EntityLivingBase entity) { return BITE_TYPE.SUCK_BLOOD_CREATURE; } } else if (entity instanceof EntityPlayer) { - if (((EntityPlayer) entity).capabilities.isCreativeMode || !Permissions.getPermission("pvp", player)) { + if (((EntityPlayer) entity).capabilities.isCreativeMode || !Permissions.isPvpEnabled(player)) { return BITE_TYPE.NONE; } boolean hunter = Helper.isHunter(player); @@ -1117,6 +1116,7 @@ private void applyEntityAttributes() { * @param hunter Is the entity a hunter? */ private void biteAttack(EntityLivingBase entity, boolean hunter) { + if (!PermissionAPI.hasPermission(player, Permissions.BITE_PLAYER)) return; checkAttributes(VReference.biteDamage); float damage = getSpecialAttributes().bat ? 0.1F : (float) player.getEntityAttribute(VReference.biteDamage).getAttributeValue(); entity.attackEntityFrom(DamageSource.causePlayerDamage(player), damage); diff --git a/src/main/java/de/teamlapen/vampirism/tileentity/TileTotem.java b/src/main/java/de/teamlapen/vampirism/tileentity/TileTotem.java index c204bc37d2..69a5b16d36 100644 --- a/src/main/java/de/teamlapen/vampirism/tileentity/TileTotem.java +++ b/src/main/java/de/teamlapen/vampirism/tileentity/TileTotem.java @@ -22,6 +22,7 @@ import de.teamlapen.vampirism.entity.vampire.EntityVampireBase; import de.teamlapen.vampirism.entity.vampire.EntityVampireFactionVillager; import de.teamlapen.vampirism.potion.PotionSanguinare; +import de.teamlapen.vampirism.util.ModEventFactory; import de.teamlapen.vampirism.world.villages.VampirismVillage; import de.teamlapen.vampirism.world.villages.VampirismVillageHelper; @@ -310,8 +311,9 @@ public NBTTagCompound getUpdateTag() { public void handleUpdateTag(@Nonnull NBTTagCompound tag) { readFromNBT(tag); if (tag.hasKey("village_bb")) { + StructureBoundingBox bb = new StructureBoundingBox(tag.getIntArray("village_bb")); + ModEventFactory.fireUpdateBoundingBoxEvent(getVillage(), bb); if (controllingFaction == VReference.VAMPIRE_FACTION) { - StructureBoundingBox bb = new StructureBoundingBox(tag.getIntArray("village_bb")); registerVampireArea(bb); //Replaces old area if different } else { unregisterVampireArea(); @@ -350,12 +352,15 @@ public void initiateCapture(@Nonnull IPlayableFaction faction, EntityPlayer play this.capture_timer = 0; force_village_update = true; this.markDirty(); - if (!world.isRemote && capturingFaction == VReference.VAMPIRE_FACTION) { - List villager = this.world.getEntitiesWithinAABB(EntityVillager.class, getAffectedArea()); - for (EntityVillager v : villager) { - if (v instanceof EntityFactionVillager) continue; - if (v.getRNG().nextInt(3) == 0) { - makeAggressive(v, this.getVillage()); + if (getVillage() != null && ModEventFactory.fireInitiateCaptureEvent(getVillage(), world, controllingFaction, capturingFaction)) { + if (!world.isRemote && capturingFaction == VReference.VAMPIRE_FACTION) { + List villager = this.world.getEntitiesWithinAABB(EntityVillager.class, getAffectedArea()); + for (EntityVillager v : villager) { + if (v instanceof EntityFactionVillager) + continue; + if (v.getRNG().nextInt(3) == 0) { + makeAggressive(v, this.getVillage()); + } } } } @@ -371,8 +376,10 @@ public void invalidate() { public void markDirty() { super.markDirty(); world.notifyBlockUpdate(getPos(), world.getBlockState(pos), world.getBlockState(pos), 3); + StructureBoundingBox bb = new StructureBoundingBox(UtilLib.bbToInt(getAffectedArea())); + ModEventFactory.fireUpdateBoundingBoxEvent(getVillage(), bb); if (this.controllingFaction == VReference.VAMPIRE_FACTION) { - registerVampireArea(new StructureBoundingBox(UtilLib.bbToInt(getAffectedArea()))); + registerVampireArea(bb); } else { unregisterVampireArea(); } @@ -630,11 +637,13 @@ public void update() { spawnVillagerInVillage(new EntityHunterFactionVillager(this.world), seed, true); } else if (controllingFaction.equals(VReference.VAMPIRE_FACTION)) { spawnVillagerInVillage(new EntityVampireFactionVillager(this.world), seed, false); + } else { + VampirismVillageEvent.SpawnFactionVillager event = ModEventFactory.fireSpawnFactionVillagerEvent(village, seed, controllingFaction); + spawnVillagerInVillage(event.getVillager(), seed, event.hasPoisonousBlood()); } } else { - boolean isVampire = this.controllingFaction == VReference.VAMPIRE_FACTION && seed.getRNG().nextBoolean(); - VampirismVillageEvent.SpawnNewVillager event = new VampirismVillageEvent.SpawnNewVillager(village, seed, isVampire); - MinecraftForge.EVENT_BUS.post(event); + boolean isConverted = this.controllingFaction != VReference.HUNTER_FACTION && seed.getRNG().nextBoolean(); + VampirismVillageEvent.SpawnNewVillager event = ModEventFactory.fireSpawnNewVillagerEvent(village, seed, isConverted, controllingFaction); if (event.getResult() != Event.Result.DENY) { EntityVillager newVillager; if (event.getResult() == Event.Result.ALLOW && event.getNewVillager() != null) { @@ -645,7 +654,7 @@ public void update() { newVillager.setGrowingAge(-24000); seed.setGrowingAge(6000); } - if (event.isWillBeVampire()) { + if (event.isWillBeConverted()) { IConvertedCreature converted = ExtendedCreature.get(newVillager).makeVampire(); //Already spawns the creature in the world } else { this.spawnVillagerInVillage(newVillager, seed, this.controllingFaction == VReference.HUNTER_FACTION); @@ -682,13 +691,23 @@ public void update() { int z = (int) (affectedArea.minZ + rng.nextInt((int) (affectedArea.maxZ - affectedArea.minZ))); BlockPos pos = new BlockPos(x, world.getHeight(x, z) - 1, z); IBlockState b = world.getBlockState(pos); - if (b.getBlock() == world.getBiome(pos).topBlock.getBlock() && b.getBlock() != Blocks.SAND && controllingFaction == VReference.VAMPIRE_FACTION) { - world.setBlockState(pos, ModBlocks.cursed_earth.getDefaultState()); - if (world.getBlockState(pos.up()).getBlock() == Blocks.TALLGRASS) { - world.setBlockToAir(pos.up()); + boolean flag = false; + if (controllingFaction == VReference.VAMPIRE_FACTION) { + if (b.getBlock() == world.getBiome(pos).topBlock.getBlock() && b.getBlock() != Blocks.SAND) { + world.setBlockState(pos, ModBlocks.cursed_earth.getDefaultState()); + if (world.getBlockState(pos.up()).getBlock() == Blocks.TALLGRASS) { + world.setBlockToAir(pos.up()); + flag = true; + } } - } else if (b.getBlock() == ModBlocks.cursed_earth && controllingFaction == VReference.HUNTER_FACTION) { - world.setBlockState(pos, world.getBiome(pos).topBlock); + } else if (controllingFaction == VReference.HUNTER_FACTION) { + if (b.getBlock() == ModBlocks.cursed_earth) { + world.setBlockState(pos, world.getBiome(pos).topBlock); + flag = true; + } + } + if (!flag) { + ModEventFactory.fireReplaceVillageBlockEvent(getVillage(), world, b, pos, controllingFaction); } } } @@ -813,7 +832,7 @@ private ResourceLocation getEntityForFaction(@Nonnull IFaction f) { } else if (f == VReference.VAMPIRE_FACTION) { return new ResourceLocation("vampirism:vampire"); } - return null; + return ModEventFactory.fireSpawnCaptureEntityEvent(getVillage(), f); } @Nullable @@ -935,7 +954,8 @@ private boolean spawnEntityInVillage(@Nonnull Entity newEntity, @Nullable Entity * @param poisonousBlood if the villager should have poisonous blood * @return false if spawn is not possible */ - private boolean spawnVillagerInVillage(@Nonnull EntityVillager newVillager, @Nullable Entity entityToReplace, boolean poisonousBlood) { + private boolean spawnVillagerInVillage(EntityVillager newVillager, @Nullable Entity entityToReplace, boolean poisonousBlood) { + if (newVillager == null) return false; if (!spawnEntityInVillage(newVillager, entityToReplace)) return false; if (entityToReplace instanceof EntityVillager) { newVillager.setHomePosAndDistance(((EntityVillager) entityToReplace).getHomePosition(), (int) ((EntityVillager) entityToReplace).getMaximumHomeDistance()); @@ -1013,50 +1033,54 @@ private void updateBossinfoPlayers(@Nullable List includedPlayerEntities */ private void updateCreaturesOnCapture() { List villager = this.world.getEntitiesWithinAABB(EntityVillager.class, getAffectedArea()); - if (capturingFaction == VReference.HUNTER_FACTION) { - List hunter = this.world.getEntitiesWithinAABB(EntityHunterBase.class, getAffectedArea()); - if (controllingFaction == VReference.VAMPIRE_FACTION) { - int i = Math.max(2, hunter.size() / 2); - if (hunter.size() > 0) { - for (EntityHunterBase e : hunter) { - if (i-- > 0) { - spawnVillagerInVillage(new EntityVillager(this.world), e, true); + if(getVillage() != null) { + if (ModEventFactory.fireVillagerCaptureEvent(getVillage(), villager, controllingFaction, capturingFaction, getAffectedArea())) + return; + if (capturingFaction == VReference.HUNTER_FACTION) { + List hunter = this.world.getEntitiesWithinAABB(EntityHunterBase.class, getAffectedArea()); + if (controllingFaction == VReference.VAMPIRE_FACTION) { + int i = Math.max(2, hunter.size() / 2); + if (hunter.size() > 0) { + for (EntityHunterBase e : hunter) { + if (i-- > 0) { + spawnVillagerInVillage(new EntityVillager(this.world), e, true); + } } } + for (int o = i; o > 0; o--) { + spawnVillagerInVillage(new EntityVillager(this.world), null, true); + } + + } else { + for (EntityVillager e : villager) { + ExtendedCreature.get(e).setPoisonousBlood(true); + } } - for (int o = i; o > 0; o--) { - spawnVillagerInVillage(new EntityVillager(this.world), null, true); + List huntertrainerdummy = this.world.getEntitiesWithinAABB(EntityHunterTrainerDummy.class, getAffectedArea()); + for (EntityHunterTrainerDummy e : huntertrainerdummy) { + EntityHunterTrainer trainer = new EntityHunterTrainer(this.world); + trainer.copyLocationAndAnglesFrom(e); + trainer.setHome(e.getHome()); + world.removeEntity(e); + world.spawnEntity(trainer); } - - } else { + spawnVillagerInVillage(new EntityHunterFactionVillager(this.world), null, false); + } else if (capturingFaction == VReference.VAMPIRE_FACTION) { for (EntityVillager e : villager) { - ExtendedCreature.get(e).setPoisonousBlood(true); + ExtendedCreature.get(e).setPoisonousBlood(false); + if (e.getRNG().nextInt(2) == 1) continue; + PotionSanguinare.addRandom(e, false); } + List huntertrainer = this.world.getEntitiesWithinAABB(EntityHunterTrainer.class, getAffectedArea()); + for (EntityHunterTrainer e : huntertrainer) { + EntityHunterTrainerDummy dummy = new EntityHunterTrainerDummy(this.world); + dummy.copyLocationAndAnglesFrom(e); + dummy.setHome(e.getHome()); + world.removeEntity(e); + world.spawnEntity(dummy); + } + spawnVillagerInVillage(new EntityVampireFactionVillager(this.world), null, false); } - List huntertrainerdummy = this.world.getEntitiesWithinAABB(EntityHunterTrainerDummy.class, getAffectedArea()); - for (EntityHunterTrainerDummy e : huntertrainerdummy) { - EntityHunterTrainer trainer = new EntityHunterTrainer(this.world); - trainer.copyLocationAndAnglesFrom(e); - trainer.setHome(e.getHome()); - world.removeEntity(e); - world.spawnEntity(trainer); - } - spawnVillagerInVillage(new EntityHunterFactionVillager(this.world), null, false); - } else if (capturingFaction == VReference.VAMPIRE_FACTION) { - for (EntityVillager e : villager) { - ExtendedCreature.get(e).setPoisonousBlood(false); - if (e.getRNG().nextInt(2) == 1) continue; - PotionSanguinare.addRandom(e, false); - } - List huntertrainer = this.world.getEntitiesWithinAABB(EntityHunterTrainer.class, getAffectedArea()); - for (EntityHunterTrainer e : huntertrainer) { - EntityHunterTrainerDummy dummy = new EntityHunterTrainerDummy(this.world); - dummy.copyLocationAndAnglesFrom(e); - dummy.setHome(e.getHome()); - world.removeEntity(e); - world.spawnEntity(dummy); - } - spawnVillagerInVillage(new EntityVampireFactionVillager(this.world), null, false); } } diff --git a/src/main/java/de/teamlapen/vampirism/util/Helper.java b/src/main/java/de/teamlapen/vampirism/util/Helper.java index a1cda7ada7..bf21da6447 100755 --- a/src/main/java/de/teamlapen/vampirism/util/Helper.java +++ b/src/main/java/de/teamlapen/vampirism/util/Helper.java @@ -27,6 +27,7 @@ import net.minecraft.world.World; import net.minecraft.world.biome.Biome; import net.minecraftforge.fml.relauncher.ReflectionHelper; +import net.minecraftforge.server.permission.PermissionAPI; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -126,7 +127,7 @@ public static boolean canBecomeVampire(EntityPlayer player) { public static boolean canTurnPlayer(IVampire biter, @Nullable EntityPlayer target) { if (biter instanceof IVampirePlayer) { - return Permissions.canPlayerTurnPlayer(((IVampirePlayer) biter).getRepresentingPlayer()); + return PermissionAPI.hasPermission(((IVampirePlayer) biter).getRepresentingPlayer(), Permissions.INFECT_PLAYER); } else { return !Configs.disable_mob_bite_infection; } diff --git a/src/main/java/de/teamlapen/vampirism/util/ModEventFactory.java b/src/main/java/de/teamlapen/vampirism/util/ModEventFactory.java new file mode 100644 index 0000000000..46495cc1a5 --- /dev/null +++ b/src/main/java/de/teamlapen/vampirism/util/ModEventFactory.java @@ -0,0 +1,75 @@ +package de.teamlapen.vampirism.util; + +import de.teamlapen.vampirism.api.entity.factions.IFaction; +import de.teamlapen.vampirism.api.entity.factions.IFactionPlayerHandler; +import de.teamlapen.vampirism.api.entity.factions.IPlayableFaction; +import de.teamlapen.vampirism.api.event.FactionEvent; +import de.teamlapen.vampirism.api.event.VampirismVillageEvent; +import de.teamlapen.vampirism.api.world.IVampirismVillage; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.passive.EntityVillager; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureBoundingBox; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.fml.common.eventhandler.Event.Result; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.List; + +public class ModEventFactory { + + public static boolean fireVillagerCaptureEvent(@Nonnull IVampirismVillage village, @Nonnull List villagerIn, @Nullable IPlayableFaction controllingFactionIn, @Nonnull IPlayableFaction capturingFactionIn, @Nonnull AxisAlignedBB affectedArea) { + VampirismVillageEvent.VillagerCaptureFinish event = new VampirismVillageEvent.VillagerCaptureFinish(village, villagerIn, controllingFactionIn, capturingFactionIn, affectedArea); + MinecraftForge.EVENT_BUS.post(event); + return event.getResult().equals(Result.DENY); + } + + public static ResourceLocation fireSpawnCaptureEntityEvent(@Nullable IVampirismVillage village, @Nonnull IFaction faction) { + VampirismVillageEvent.SpawnCaptureEntity event = new VampirismVillageEvent.SpawnCaptureEntity(village, faction); + MinecraftForge.EVENT_BUS.post(event); + return event.getEntity(); + } + + public static VampirismVillageEvent.SpawnNewVillager fireSpawnNewVillagerEvent(@Nonnull IVampirismVillage village, @Nonnull EntityVillager seed, boolean converted, IPlayableFaction controllingFaction) { + VampirismVillageEvent.SpawnNewVillager event = new VampirismVillageEvent.SpawnNewVillager(village, seed, converted, controllingFaction); + MinecraftForge.EVENT_BUS.post(event); + return event; + } + + public static void fireReplaceVillageBlockEvent(@Nullable IVampirismVillage village, @Nonnull World world, @Nonnull IBlockState b, @Nonnull BlockPos pos, @Nonnull IPlayableFaction controllingFaction) { + VampirismVillageEvent.ReplaceBlock event = new VampirismVillageEvent.ReplaceBlock(village, world, b, pos, controllingFaction); + MinecraftForge.EVENT_BUS.post(event); + } + + public static boolean fireInitiateCaptureEvent(@Nonnull IVampirismVillage village, @Nonnull World world, @Nullable IPlayableFaction controllingFaction, @Nonnull IPlayableFaction capturingFaction) { + VampirismVillageEvent.InitiateCapture event = new VampirismVillageEvent.InitiateCapture(village, world, controllingFaction, capturingFaction); + MinecraftForge.EVENT_BUS.post(event); + return !event.getResult().equals(Result.DENY); + } + + public static VampirismVillageEvent.SpawnFactionVillager fireSpawnFactionVillagerEvent(@Nullable IVampirismVillage village, @Nonnull EntityVillager seed, @Nonnull IPlayableFaction controllingFaction) { + VampirismVillageEvent.SpawnFactionVillager event = new VampirismVillageEvent.SpawnFactionVillager(village, seed, controllingFaction); + MinecraftForge.EVENT_BUS.post(event); + return event; + } + + public static void fireUpdateBoundingBoxEvent(@Nullable IVampirismVillage village, @Nonnull StructureBoundingBox bb) { + VampirismVillageEvent.UpdateBoundingBox event = new VampirismVillageEvent.UpdateBoundingBox(village, bb); + MinecraftForge.EVENT_BUS.post(event); + } + + public static Result fireCanJoinFactionEvent(@Nonnull IFactionPlayerHandler playerHandler, @Nullable IPlayableFaction currentFaction, IPlayableFaction newFaction){ + FactionEvent.CanJoinFaction event = new FactionEvent.CanJoinFaction(playerHandler, currentFaction, newFaction); + MinecraftForge.EVENT_BUS.post(event); + return event.getResult(); + } + + public static boolean fireChangeLevelOrFactionEvent(@Nonnull IFactionPlayerHandler player, @Nullable IPlayableFaction currentFaction, int currentLevel, @Nullable IPlayableFaction newFaction, int newLevel){ + FactionEvent.ChangeLevelOrFaction event = new FactionEvent.ChangeLevelOrFaction(player, currentFaction, currentLevel, newFaction, newLevel); + return MinecraftForge.EVENT_BUS.post(event); + } +} diff --git a/src/main/java/de/teamlapen/vampirism/util/Permissions.java b/src/main/java/de/teamlapen/vampirism/util/Permissions.java index a089553379..de168c7482 100755 --- a/src/main/java/de/teamlapen/vampirism/util/Permissions.java +++ b/src/main/java/de/teamlapen/vampirism/util/Permissions.java @@ -1,27 +1,41 @@ package de.teamlapen.vampirism.util; -import de.teamlapen.vampirism.config.Configs; +import de.teamlapen.vampirism.api.entity.player.actions.IAction; +import de.teamlapen.vampirism.core.VampirismRegistries; import net.minecraft.entity.player.EntityPlayer; import net.minecraftforge.fml.common.FMLCommonHandler; +import net.minecraftforge.server.permission.DefaultPermissionLevel; +import net.minecraftforge.server.permission.PermissionAPI; + -/** - * TODO integrate with e.g. ForgeEssentials - */ public class Permissions { - public static boolean getPermission(String permission) { - return true; + + public static final String VAMPIRISM = "vampirism.check"; + public static final String BITE_PLAYER = "vampirism.bite.attack.player"; + public static final String BITE = "vampirism.bite.attack"; + public static final String FEED = "vampirism.bite.feed"; + public static final String FEED_PLAYER = "vampirism.bite.feed.player"; + public static final String INFECT_PLAYER = "vampirism.infect.player"; + public static final String ACTION_PREFIX = "vampirism.action."; + + public static void init() { + PermissionAPI.registerNode(VAMPIRISM, DefaultPermissionLevel.ALL, "Used to check if permission system works"); + PermissionAPI.registerNode(BITE_PLAYER, DefaultPermissionLevel.ALL, "Allow players to bite attack players"); + PermissionAPI.registerNode(BITE, DefaultPermissionLevel.ALL, "Allow players to bite attack creatures"); + PermissionAPI.registerNode(FEED, DefaultPermissionLevel.ALL, "Allow feeding"); + PermissionAPI.registerNode(FEED_PLAYER, DefaultPermissionLevel.ALL, "Allow feeding from players"); + PermissionAPI.registerNode(INFECT_PLAYER, DefaultPermissionLevel.ALL, "Allow players to infect other players"); + for (IAction action : VampirismRegistries.ACTIONS.getValuesCollection()) { + PermissionAPI.registerNode(ACTION_PREFIX + action.getRegistryName().getNamespace() + "." + action.getRegistryName().getPath(), DefaultPermissionLevel.ALL, "Use action " + action.getUnlocalizedName()); + } } - public static boolean getPermission(String permission, EntityPlayer player) { - if ("pvp".equals(permission)) { - if (!player.getEntityWorld().isRemote) { - return FMLCommonHandler.instance().getMinecraftServerInstance().isPVPEnabled(); - } + public static boolean isPvpEnabled(EntityPlayer player) { + if (!player.getEntityWorld().isRemote) { + return FMLCommonHandler.instance().getMinecraftServerInstance().isPVPEnabled(); } return true; } - public static boolean canPlayerTurnPlayer(EntityPlayer player) { - return Configs.playerCanTurnPlayer; - } + } diff --git a/src/main/resources/assets/vampirism/lang/en_US.lang b/src/main/resources/assets/vampirism/lang/en_US.lang index 06adb78344..fea31d5b08 100644 --- a/src/main/resources/assets/vampirism/lang/en_US.lang +++ b/src/main/resources/assets/vampirism/lang/en_US.lang @@ -517,6 +517,7 @@ text.vampirism.garlic_weapons=This weapon is coated with garlic and poisons vamp text.vampirism.outdated=You are running Vampirism %s, the latest version is %s. text.vampirism.update_message=["Click for... [",{"text":"Download","color":"green","hoverEvent":{"action":"show_text","value":{"text":"Click this to go to the download page","color":"green"}},"clickEvent":{"action":"open_url","value":"@download@"}},"] [",{"text":"Website","color":"green","hoverEvent":{"action":"show_text","value":{"text":"Click this to go to the mod's forum page","color":"green"}},"clickEvent":{"action":"open_url","value":"@forum@"}},"] [",{"text":"Changelog","color":"green","hoverEvent":{"action":"show_text","value":{"text":"Click this see the version's Changelog","color":"green"}},"clickEvent":{"action":"run_command","value":"/vampirism changelog"}},"]"] text.vampirism.action.cooldown_not_over=Cooldown is not over yet +text.vampirism.action.disallowed=You cannot use this action here and now text.vampirism.item_tier.normal=Normal text.vampirism.item_tier.enhanced=Enhanced text.vampirism.item_tier.ultimate=Special