diff --git a/Commons/core/src/main/i18n/templates/pgm/PGMUI.properties b/Commons/core/src/main/i18n/templates/pgm/PGMUI.properties index 8cd057e..8604c7e 100644 --- a/Commons/core/src/main/i18n/templates/pgm/PGMUI.properties +++ b/Commons/core/src/main/i18n/templates/pgm/PGMUI.properties @@ -134,6 +134,9 @@ specialAbility.knockbackResistance = Knockback Resistance ({0}%) specialAbility.knockbackReduction = Knockback Reduction ({0}%) specialAbility.walkSpeed = Walking Speed ({0}x) +match.blitz.livesRemaining.singularLives = {0} life remaining +match.blitz.livesRemaining.pluralLives = {0} lives remaining + maps.singularCompound = 1 map # {0} = number of maps maps.pluralCompound = {0} maps diff --git a/PGM/src/main/java/tc/oc/pgm/kits/ItemParser.java b/PGM/src/main/java/tc/oc/pgm/kits/ItemParser.java index 991a4cb..b3d21dc 100644 --- a/PGM/src/main/java/tc/oc/pgm/kits/ItemParser.java +++ b/PGM/src/main/java/tc/oc/pgm/kits/ItemParser.java @@ -1,14 +1,19 @@ package tc.oc.pgm.kits; import javax.inject.Inject; +import javax.inject.Provider; +import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.inventory.meta.ItemMeta; import org.jdom2.Element; import tc.oc.pgm.features.FeatureDefinitionContext; +import tc.oc.pgm.kits.tag.ItemTags; import tc.oc.pgm.map.MapModule; +import tc.oc.pgm.map.MapModuleContext; import tc.oc.pgm.projectile.ProjectileDefinition; import tc.oc.pgm.projectile.Projectiles; +import tc.oc.pgm.utils.XMLUtils; import tc.oc.pgm.xml.InvalidXMLException; import tc.oc.pgm.xml.Node; import tc.oc.pgm.xml.parser.Parser; @@ -18,10 +23,12 @@ import static tc.oc.commons.core.exception.LambdaExceptionUtils.rethrowConsumer; public class ItemParser extends GlobalItemParser implements MapModule { private final FeatureDefinitionContext fdc; + private final MapModuleContext context; - @Inject private ItemParser(Parser materialParser, FeatureDefinitionContext fdc) { + @Inject private ItemParser(Parser materialParser, FeatureDefinitionContext fdc, Provider contextProvider) { super(materialParser); this.fdc = fdc; + context = contextProvider.get(); } @Override @@ -32,5 +39,15 @@ public class ItemParser extends GlobalItemParser implements MapModule { fdc.reference(node, ProjectileDefinition.class); Projectiles.setProjectileId(meta, node.getValue()); })); + + Node.tryAttr(el, "victim-kit").ifPresent(rethrowConsumer(node -> { + fdc.reference(node, Kit.class); + ItemTags.KIT.set(meta, node.getValue()); + })); + + Node.tryAttr(el, "attacker-kit").ifPresent(rethrowConsumer(node -> { + fdc.reference(node, Kit.class); + ItemTags.HITTER_KIT.set(meta, node.getValue()); + })); } } diff --git a/PGM/src/main/java/tc/oc/pgm/kits/KitListener.java b/PGM/src/main/java/tc/oc/pgm/kits/KitListener.java new file mode 100644 index 0000000..892dd82 --- /dev/null +++ b/PGM/src/main/java/tc/oc/pgm/kits/KitListener.java @@ -0,0 +1,46 @@ +package tc.oc.pgm.kits; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.inventory.ItemStack; +import tc.oc.pgm.events.ListenerScope; +import tc.oc.pgm.features.FeatureDefinitionContext; +import tc.oc.pgm.kits.tag.ItemTags; +import tc.oc.pgm.match.Match; +import tc.oc.pgm.match.MatchScope; +import javax.inject.Inject; + +@ListenerScope(MatchScope.RUNNING) +public class KitListener implements Listener { + + private final Match match; + private final FeatureDefinitionContext context; + + @Inject KitListener(Match match, FeatureDefinitionContext context) { + this.match = match; + this.context = context; + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onPlayerDamage(EntityDamageByEntityEvent event) { + if (event.getActor() instanceof Player && event.getEntity() instanceof Player) { + Player actor = (Player)event.getActor(); + Player receiver = (Player)event.getEntity(); + ItemStack item = actor.getInventory().getItemInMainHand(); + String id = ItemTags.KIT.get(item); + Kit kit = id == null ? null : context.get(id, Kit.class); + if (kit != null) { + kit.apply(match.getPlayer(receiver)); + } + String hitterId = ItemTags.HITTER_KIT.get(item); + Kit hitterKit = hitterId == null ? null : context.get(hitterId, Kit.class); + if (hitterKit != null) { + hitterKit.apply(match.getPlayer(actor)); + } + } + } +} diff --git a/PGM/src/main/java/tc/oc/pgm/kits/KitManifest.java b/PGM/src/main/java/tc/oc/pgm/kits/KitManifest.java index 8a39327..8193eba 100644 --- a/PGM/src/main/java/tc/oc/pgm/kits/KitManifest.java +++ b/PGM/src/main/java/tc/oc/pgm/kits/KitManifest.java @@ -25,6 +25,9 @@ public class KitManifest extends HybridManifest implements ParserBinders, MatchB bind(GrenadeListener.class).in(MatchScoped.class); matchListener(GrenadeListener.class); + bind(KitListener.class).in(MatchScoped.class); + matchListener(KitListener.class); + bind(ItemSharingAndLockingListener.class).in(MatchScoped.class); matchListener(ItemSharingAndLockingListener.class); diff --git a/PGM/src/main/java/tc/oc/pgm/kits/tag/ItemTags.java b/PGM/src/main/java/tc/oc/pgm/kits/tag/ItemTags.java index a7ef3ee..56932ae 100644 --- a/PGM/src/main/java/tc/oc/pgm/kits/tag/ItemTags.java +++ b/PGM/src/main/java/tc/oc/pgm/kits/tag/ItemTags.java @@ -1,11 +1,14 @@ package tc.oc.pgm.kits.tag; import tc.oc.commons.bukkit.item.BooleanItemTag; +import tc.oc.commons.bukkit.item.StringItemTag; public class ItemTags { public static final BooleanItemTag PREVENT_SHARING = new BooleanItemTag("prevent-sharing", false); public static final BooleanItemTag LOCKED = new BooleanItemTag("locked", false); + public static final StringItemTag KIT = new StringItemTag("victim-kit", null); + public static final StringItemTag HITTER_KIT = new StringItemTag("attacker-kit", null); private ItemTags() {} } diff --git a/PGM/src/main/java/tc/oc/pgm/projectile/ProjectileDefinition.java b/PGM/src/main/java/tc/oc/pgm/projectile/ProjectileDefinition.java index 7bb01a0..2ef7982 100644 --- a/PGM/src/main/java/tc/oc/pgm/projectile/ProjectileDefinition.java +++ b/PGM/src/main/java/tc/oc/pgm/projectile/ProjectileDefinition.java @@ -3,6 +3,7 @@ package tc.oc.pgm.projectile; import java.util.List; import javax.annotation.Nullable; +import com.google.inject.Inject; import org.bukkit.entity.Entity; import org.bukkit.potion.PotionEffect; import java.time.Duration; @@ -32,7 +33,9 @@ public interface ProjectileDefinition extends FeatureDefinition { boolean throwable(); - Kit kit(); + Kit victimKit(); + + Kit attackerKit(); } class ProjectileDefinitionImpl extends FeatureDefinition.Impl implements ProjectileDefinition { @@ -45,7 +48,8 @@ class ProjectileDefinitionImpl extends FeatureDefinition.Impl implements Project private @Inspect Filter destroyFilter; private @Inspect Duration coolDown; private @Inspect boolean throwable; - private @Inspect Kit kit; + private @Inspect Kit victimKit; + private @Inspect Kit attackerKit; public ProjectileDefinitionImpl(@Nullable String name, @Nullable Double damage, @@ -56,7 +60,8 @@ class ProjectileDefinitionImpl extends FeatureDefinition.Impl implements Project Filter destroyFilter, Duration coolDown, boolean throwable, - Kit kit) { + Kit victimKit, + Kit attackerKit) { this.name = name; this.damage = damage; this.velocity = velocity; @@ -66,7 +71,8 @@ class ProjectileDefinitionImpl extends FeatureDefinition.Impl implements Project this.destroyFilter = destroyFilter; this.coolDown = coolDown; this.throwable = throwable; - this.kit = kit; + this.victimKit = victimKit; + this.attackerKit = attackerKit; } @Override @@ -116,7 +122,12 @@ class ProjectileDefinitionImpl extends FeatureDefinition.Impl implements Project } @Override - public Kit kit() { - return kit; + public Kit victimKit() { + return victimKit; + } + + @Override + public Kit attackerKit() { + return attackerKit; } } diff --git a/PGM/src/main/java/tc/oc/pgm/projectile/ProjectileMatchModule.java b/PGM/src/main/java/tc/oc/pgm/projectile/ProjectileMatchModule.java index 5671576..29ca50e 100644 --- a/PGM/src/main/java/tc/oc/pgm/projectile/ProjectileMatchModule.java +++ b/PGM/src/main/java/tc/oc/pgm/projectile/ProjectileMatchModule.java @@ -1,5 +1,6 @@ package tc.oc.pgm.projectile; +import com.google.inject.Inject; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.entity.LivingEntity; @@ -19,10 +20,18 @@ import tc.oc.pgm.filters.query.PlayerBlockEventQuery; import tc.oc.pgm.match.MatchModule; import tc.oc.pgm.match.MatchPlayer; import tc.oc.pgm.match.MatchScope; +import tc.oc.pgm.match.ParticipantState; +import tc.oc.pgm.tracker.trackers.EntityTracker; @ListenerScope(MatchScope.RUNNING) public class ProjectileMatchModule extends MatchModule implements Listener { + private EntityTracker tracker; + + @Inject ProjectileMatchModule (EntityTracker tracker) { + this.tracker = tracker; + } + @EventHandler public void onProjectileHurtEvent(EntityDamageByEntityEvent event) { if(!(event.getEntity() instanceof LivingEntity)) return; @@ -39,9 +48,19 @@ public class ProjectileMatchModule extends MatchModule implements Listener { event.setDamage(projectileDefinition.damage()); } - if (projectileDefinition.kit() != null) { + if (projectileDefinition.victimKit() != null) { if (event.getEntity() instanceof Player) { - projectileDefinition.kit().apply(match.getPlayer((Player)event.getEntity())); + projectileDefinition.victimKit().apply(match.getPlayer((Player)event.getEntity())); + } + } + + if (projectileDefinition.attackerKit() != null) { + tracker.getOwner(event.getActor()).getMatchPlayer(); + if (event.getActor() != null) { + ParticipantState state = tracker.getOwner(event.getActor()); + if (state != null && state.isParticipating()) { + projectileDefinition.attackerKit().apply(state.getMatchPlayer()); + } } } } diff --git a/PGM/src/main/java/tc/oc/pgm/projectile/ProjectileModule.java b/PGM/src/main/java/tc/oc/pgm/projectile/ProjectileModule.java index 4410da7..f0eee04 100644 --- a/PGM/src/main/java/tc/oc/pgm/projectile/ProjectileModule.java +++ b/PGM/src/main/java/tc/oc/pgm/projectile/ProjectileModule.java @@ -42,9 +42,10 @@ public class ProjectileModule implements MapModule { Filter destroyFilter = filterParser.parseOptionalProperty(projectileElement, "destroy-filter").orElse(null); Duration coolDown = XMLUtils.parseDuration(projectileElement.getAttribute("cooldown")); boolean throwable = XMLUtils.parseBoolean(projectileElement.getAttribute("throwable"), true); - Kit kit = kitParser.parseOptionalProperty(projectileElement, "kit").orElse(null); + Kit kit = kitParser.parseOptionalProperty(projectileElement, "victim-kit").orElse(null); + Kit shooterKit = kitParser.parseOptionalProperty(projectileElement, "attacker-kit").orElse(null); - context.features().define(projectileElement, new ProjectileDefinitionImpl(name, damage, velocity, clickAction, entity, potionKit, destroyFilter, coolDown, throwable, kit)); + context.features().define(projectileElement, new ProjectileDefinitionImpl(name, damage, velocity, clickAction, entity, potionKit, destroyFilter, coolDown, throwable, kit, shooterKit)); } return null;