diff --git a/Server/src/main/content/global/ame/events/evilchicken/EvilChickenNPC.kt b/Server/src/main/content/global/ame/events/evilchicken/EvilChickenNPC.kt index 5b065f567..dd3851cd8 100644 --- a/Server/src/main/content/global/ame/events/evilchicken/EvilChickenNPC.kt +++ b/Server/src/main/content/global/ame/events/evilchicken/EvilChickenNPC.kt @@ -27,7 +27,7 @@ class EvilChickenNPC(override var loot: WeightBasedTable? = null) : RandomEventN override fun finalizeDeath(killer: Entity?) { super.finalizeDeath(killer) - GroundItemManager.create(Item(Items.FEATHER_314, RandomFunction.random(50,300)), this.dropLocation, player) + GroundItemManager.create(Item(Items.RED_EGG_10532, RandomFunction.random(50,300)), this.dropLocation, player) } override fun tick() { diff --git a/Server/src/main/content/minigame/barbassault/arena/BarbassaultActivity.kt b/Server/src/main/content/minigame/barbassault/arena/BarbassaultActivity.kt index a12c0be5f..201f77c6f 100644 --- a/Server/src/main/content/minigame/barbassault/arena/BarbassaultActivity.kt +++ b/Server/src/main/content/minigame/barbassault/arena/BarbassaultActivity.kt @@ -2,19 +2,27 @@ package content.minigame.barbassault import content.minigame.barbassault.arena.BarbassaultSession import content.minigame.barbassault.arena.BarbassaultState +import content.minigame.barbassault.arena.Npcs.dropPenanceEggCluster import core.api.log import core.game.activity.ActivityManager import core.game.activity.ActivityPlugin import core.game.node.Node import core.game.node.entity.Entity import core.game.node.entity.combat.CombatStyle +import core.game.node.entity.npc.NPC import core.game.node.entity.player.Player +import core.game.node.item.GroundItem +import core.game.node.item.GroundItemManager +import core.game.node.item.Item import core.game.system.task.Pulse import core.game.world.GameWorld import core.game.world.map.Location import core.game.world.map.zone.ZoneRestriction +import core.game.worldevents.holiday.easter.EasterEvent.Companion.EGG_SPAWN_TIME +import core.game.worldevents.holiday.easter.EasterEvent.Companion.eggs import core.plugin.Initializable import core.tools.Log +import org.rs09.consts.Items private val sessions = mutableListOf() private var activity: BarbassaultActivity? = null @@ -64,6 +72,10 @@ open class BarbassaultActivity : ActivityPlugin("barbassault",false, true, true, e.getProperties().setTeleportLocation(null) return true } + if (e is NPC) { + // dropPenanceEggCluster(e) + //GroundItemManager.create(Item(Items.RED_EGG_10532, 1), e.location).apply { forceVisible = true } + } return false } diff --git a/Server/src/main/content/minigame/barbassault/arena/BarbassaultGameArea.kt b/Server/src/main/content/minigame/barbassault/arena/BarbassaultGameArea.kt index 75c0d0c00..0cf3aa7ef 100644 --- a/Server/src/main/content/minigame/barbassault/arena/BarbassaultGameArea.kt +++ b/Server/src/main/content/minigame/barbassault/arena/BarbassaultGameArea.kt @@ -4,10 +4,10 @@ import content.minigame.barbassault.BarbRole import content.minigame.barbassault.BarbassaultTut import content.minigame.barbassault.arena.BaHornSystem.HornHelper.getHealerHorn import content.minigame.barbassault.arena.BarbassaultSession.AttackerStyle -import content.minigame.barbassault.arena.scenery.EggCannon -import content.minigame.barbassault.arena.scenery.EggCannon.Companion.loadEggHopper -import content.minigame.barbassault.arena.scenery.EggCannon.Companion.loadHopperEggs -import content.minigame.barbassault.arena.scenery.EggCannon.Companion.showEggHopperCount +import content.minigame.barbassault.arena.scenery.EggHopper +import content.minigame.barbassault.arena.scenery.EggHopper.Companion.loadEggHopper +import content.minigame.barbassault.arena.scenery.EggHopper.Companion.loadHopperEggs +import content.minigame.barbassault.arena.scenery.EggHopper.Companion.showEggHopperCount import content.minigame.barbassault.baSession import content.minigame.barbassault.getBarbLevels import content.minigame.barbassault.isBAHealer @@ -102,7 +102,7 @@ class BarbassaultGameArea : InteractionListener, MapArea { override fun defineListeners() { //Wrong food message "That's the wrong type of poisoned food to use! Penalty!" on(Scenery.EGG_LAUNCHER_20133, IntType.SCENERY, "Shoot") { player, node -> - EggCannon.openTurretIface(player) + EggHopper.openTurretIface(player) return@on true } on(Scenery.EGG_HOPPER_20264, IntType.SCENERY, "Load","Look-in") { player, node -> @@ -116,7 +116,7 @@ class BarbassaultGameArea : InteractionListener, MapArea { player.faceLocation(location(loc.x,loc.y+1,0)) return@on true } - onUseWith(IntType.SCENERY, EggCannon.ALL_EGGS,Scenery.EGG_HOPPER_20264){ player, used, with -> + onUseWith(IntType.SCENERY, EggHopper.ALL_EGGS,Scenery.EGG_HOPPER_20264){ player, used, with -> val loc = player.location player.faceLocation(location(loc.x,loc.y+1,0)) loadHopperEggs(player,used.id ) diff --git a/Server/src/main/content/minigame/barbassault/arena/BarbassaultSession.kt b/Server/src/main/content/minigame/barbassault/arena/BarbassaultSession.kt index 6623fc177..b3e40a0db 100644 --- a/Server/src/main/content/minigame/barbassault/arena/BarbassaultSession.kt +++ b/Server/src/main/content/minigame/barbassault/arena/BarbassaultSession.kt @@ -3,7 +3,7 @@ package content.minigame.barbassault.arena import content.minigame.barbassault.ALL_BARBASS_ITEMS import content.minigame.barbassault.BarbRole import content.minigame.barbassault.BarbassaultActivity -import content.minigame.barbassault.arena.scenery.EggCannon +import content.minigame.barbassault.arena.scenery.EggHopper import content.minigame.barbassault.arena.scenery.GloryHorn import content.minigame.barbassault.baSession import content.minigame.barbassault.getBarbLevels @@ -44,8 +44,10 @@ class BarbassaultSession( val activity: BarbassaultActivity ? = null) :LogoutLi var state: BarbassaultState = BarbassaultState.PARTY_CREATION lateinit var team: BarbTeam val sessionNpcs = mutableListOf() - val groundItems = mutableListOf() - val eggHopper = EggCannon.EggHopper() + val BAgroundItems = mutableListOf() + val eggHopper = EggHopper.EggHopper() + var eggCannonNpcWest: NPC? = null + var eggCannonNpcEast: NPC? = null val scoreManager = BarbScoreManager() val eventBus = BarbAssEventBus() val npcCaps = SpawnCaps(4,4,2,2)//wave 1 @@ -313,15 +315,10 @@ class BarbassaultSession( val activity: BarbassaultActivity ? = null) :LogoutLi return npc } fun spawnEggCannons() { - val eggCannonNpcWest = sessionNPCSpawn( NPCs.EGG_LAUNCHER_5026, base.transform(21, 34, 0), Direction.NORTH ) - eggCannonNpcWest?.isWalks = false - eggCannonNpcWest?.isNeverWalks = true - eggCannonNpcWest?.definition?.combatDistance = 14 - eggCannonNpcWest?.properties?.combatPulse?.style = CombatStyle.RANGE + eggCannonNpcWest = sessionNPCSpawn( NPCs.EGG_LAUNCHER_5026, base.transform(21, 34, 0), Direction.NORTH ) //eggCannonNpcWest?. - eggCannonNpcWest?.definition?.combatGraphics[1] = Graphics(866, 25, 0) if (currentWave == 10) return - val eggCannonNpcEast = sessionNPCSpawn( NPCs.EGG_LAUNCHER_5026, base.transform(40, 34, 0), Direction.NORTH ) + eggCannonNpcEast = sessionNPCSpawn( NPCs.EGG_LAUNCHER_5026, base.transform(40, 34, 0), Direction.NORTH ) } diff --git a/Server/src/main/content/minigame/barbassault/arena/Npcs/EggCannon.kt b/Server/src/main/content/minigame/barbassault/arena/Npcs/EggCannon.kt new file mode 100644 index 000000000..3ae66e5fd --- /dev/null +++ b/Server/src/main/content/minigame/barbassault/arena/Npcs/EggCannon.kt @@ -0,0 +1,37 @@ +package content.minigame.barbassault.arena.Npcs + +import core.game.node.entity.Entity +import core.game.node.entity.combat.CombatStyle +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.world.map.RegionManager +import core.game.world.update.flag.context.Graphics +import org.rs09.consts.NPCs + + +class EggCannon : NPCBehavior(NPCs.EGG_LAUNCHER_5026) { + override fun onCreation (self: NPC) { + self.isWalks = false + self.isNeverWalks = true + self.walkRadius = 0 + self.dropLocation + self.definition.combatGraphics[1] = Graphics(866, 25, 0) + + self.definition.combatDistance = 14 + self.properties.combatPulse.style = CombatStyle.RANGE + + } + override fun getXpMultiplier(self: NPC, attacker: Entity): Double { + return 0.0 + } + + override fun tick(self: NPC): Boolean { + + + return true + } + fun FireEggAt(target:String,eggColor: String){ + // RegionManager.getSurroundingNPCs() + } + +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/barbassault/arena/monsters/PenanceFighterNPC.kt b/Server/src/main/content/minigame/barbassault/arena/Npcs/PenanceFighterNPC.kt similarity index 85% rename from Server/src/main/content/minigame/barbassault/arena/monsters/PenanceFighterNPC.kt rename to Server/src/main/content/minigame/barbassault/arena/Npcs/PenanceFighterNPC.kt index e755b19e3..2558ba245 100644 --- a/Server/src/main/content/minigame/barbassault/arena/monsters/PenanceFighterNPC.kt +++ b/Server/src/main/content/minigame/barbassault/arena/Npcs/PenanceFighterNPC.kt @@ -3,6 +3,7 @@ package content.minigame.barbassault.arenas.monsters import content.minigame.barbassault.BarbRole import content.minigame.barbassault.arena.BarbAssEvent import content.minigame.barbassault.arena.BarbAssaultCombat +import content.minigame.barbassault.arena.Npcs.dropPenanceEggCluster import content.minigame.barbassault.baSession import core.api.* import core.game.node.entity.Entity @@ -11,6 +12,9 @@ import core.game.node.entity.combat.CombatStyle import core.game.node.entity.npc.NPC import core.game.node.entity.npc.NPCBehavior import core.game.node.entity.player.Player +import core.game.node.item.GroundItemManager +import core.game.node.item.Item +import org.rs09.consts.Items import org.rs09.consts.NPCs val PENANCE_FIGHTER_IDS = listOf( @@ -25,7 +29,7 @@ val PENANCE_FIGHTER_IDS = listOf( NPCs.PENANCE_FIGHTER_5218, NPCs.PENANCE_FIGHTER_5219) -class PenanceFighterNPC : NPCBehavior(*PENANCE_FIGHTER_IDS.toIntArray()) { +class PenanceFighterNPC : NPCBehavior(*PENANCE_FIGHTER_IDS.toIntArray()) { override fun canBeAttackedBy(self: NPC, attacker: Entity, style: CombatStyle, shouldSendMessage: Boolean): Boolean { if (attacker is Player && getItemFromEquipment(attacker, EquipmentSlot.CAPE)?.id != 10556) { //todo make list of not allowed weapons to attack IE: Crystal bow, Karils Crossbow @@ -37,6 +41,7 @@ class PenanceFighterNPC : NPCBehavior(*PENANCE_FIGHTER_IDS.toIntArray()) { override fun getXpMultiplier(self: NPC, attacker: Entity): Double { return 0.0 } + override fun beforeDamageReceived(self: NPC, attacker: Entity, state: BattleState) { val player = attacker as? Player ?: return @@ -45,14 +50,21 @@ class PenanceFighterNPC : NPCBehavior(*PENANCE_FIGHTER_IDS.toIntArray()) { } } + override fun tick(self: NPC): Boolean { + self.shouldPreventStacking(self) + return super.tick(self) + } + override fun onCreation (self: NPC) { self.setAttribute("agg_radius",6) self.isWalks = true - self.isNeverWalks = false + // self.isNeverWalks = false + self.properties.isNPCWalkable = false self.walkRadius = 64 self.isAggressive = true self.isRespawn = false + self.setAttribute("barbass-role", BarbRole.ATTACKER) self.definition.combatDistance = 1 @@ -61,12 +73,14 @@ class PenanceFighterNPC : NPCBehavior(*PENANCE_FIGHTER_IDS.toIntArray()) { } override fun onDeathFinished(self: NPC, killer: Entity) { - super.onDeathFinished(self, killer) val player = killer as? Player ?: return + dropPenanceEggCluster(killer,self) val session = player.baSession ?: return session.eventBus.emit(BarbAssEvent.NPCDied(self,player)) + super.onDeathFinished(self, killer) } + } //Shrink death 5098 diff --git a/Server/src/main/content/minigame/barbassault/arena/monsters/PenanceHealerNPC.kt b/Server/src/main/content/minigame/barbassault/arena/Npcs/PenanceHealerNPC.kt similarity index 97% rename from Server/src/main/content/minigame/barbassault/arena/monsters/PenanceHealerNPC.kt rename to Server/src/main/content/minigame/barbassault/arena/Npcs/PenanceHealerNPC.kt index cfe1e0995..af42658ca 100644 --- a/Server/src/main/content/minigame/barbassault/arena/monsters/PenanceHealerNPC.kt +++ b/Server/src/main/content/minigame/barbassault/arena/Npcs/PenanceHealerNPC.kt @@ -1,4 +1,4 @@ -package content.minigame.barbassault.arena.monsters +package content.minigame.barbassault.arena.Npcs import content.minigame.barbassault.BarbRole import content.minigame.barbassault.arena.BarbAssEvent diff --git a/Server/src/main/content/minigame/barbassault/arena/Npcs/PenanceHelper.kt b/Server/src/main/content/minigame/barbassault/arena/Npcs/PenanceHelper.kt new file mode 100644 index 000000000..f2685c476 --- /dev/null +++ b/Server/src/main/content/minigame/barbassault/arena/Npcs/PenanceHelper.kt @@ -0,0 +1,84 @@ +package content.minigame.barbassault.arena.Npcs + + +import core.api.hasLineOfSight +import core.api.produceGroundItem +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.item.GroundItemManager +import core.game.node.item.Item +import core.game.world.map.Location +import core.game.world.map.RegionManager +import org.rs09.consts.Items + +fun dropPenanceEggCluster(killer: Player, npc: NPC) { + val tiles = npc.dropLocation.get3x3Tiles().shuffled() + + val eggs = listOf( Items.RED_EGG_10532, Items.RED_EGG_10532, + Items.BLUE_EGG_10533, Items.BLUE_EGG_10533, + Items.GREEN_EGG_10531, Items.GREEN_EGG_10531) + + for (i in eggs.indices) { + val tile = tiles[i] + produceGroundItem(killer, eggs[i], 1, tile).apply { + decayTime = 10000 + forceVisible = true + isRemainPrivate = false + } + } +} + +//GroundItemManager.create(Item(eggs[i], 1), tile).apply { forceVisible = true } +// GroundItemManager.create(Item(Items.RED_EGG_10532, 1), tile).apply { forceVisible = true } +// GroundItemManager.create(Item(eggs[i], 1), tile, null) + +/** + * Finds the closest visible player to the given NPC within a specified range. + * Filters out invisible players and those without line of sight. + * + * @param npc The NPC used as the search origin. + * @param range Maximum distance to search for players. + * @return The closest valid Player, or null if none are found. + */ +fun findClosestPlayerFromNPC(npc: NPC,range:Int = 14): Player? { + var closest: Player? = null + var bestDistance = Double.MAX_VALUE + + for (player in RegionManager.getLocalPlayers(npc, range)) { + if (player.isInvisible) continue + if (!hasLineOfSight(npc, player)) continue + + val dist = npc.location.getDistance(player.location) + if (dist < bestDistance) { + bestDistance = dist + closest = player + } + } + return closest +} + +/** + * Finds the closest NPC matching the given target NPC within a range, + * ensuring there is line of sight between the source NPC and the target. + * + * @param targetNPC The specific NPC being searched for. + * @param npc The source NPC performing the search. + * @param range Maximum search radius. + * @return The closest matching NPC if found and visible, otherwise null. + */ +fun findClosestTargetNPCFromNPC(targetNPC:NPC,npc: NPC,range:Int = 14): NPC? { + var closest: NPC? = null + var bestDistance = Double.MAX_VALUE + + for (foundNpc in RegionManager.getLocalNpcs(npc, range)) { + if (targetNPC != foundNpc) continue + if (!hasLineOfSight(npc, foundNpc)) continue + + val dist = npc.location.getDistance(foundNpc.location) + if (dist < bestDistance) { + bestDistance = dist + closest = foundNpc + } + } + return closest +} diff --git a/Server/src/main/content/minigame/barbassault/arena/monsters/PenanceQueenNPC.kt b/Server/src/main/content/minigame/barbassault/arena/Npcs/PenanceQueenNPC.kt similarity index 94% rename from Server/src/main/content/minigame/barbassault/arena/monsters/PenanceQueenNPC.kt rename to Server/src/main/content/minigame/barbassault/arena/Npcs/PenanceQueenNPC.kt index ae54b9612..9334548d1 100644 --- a/Server/src/main/content/minigame/barbassault/arena/monsters/PenanceQueenNPC.kt +++ b/Server/src/main/content/minigame/barbassault/arena/Npcs/PenanceQueenNPC.kt @@ -1,4 +1,4 @@ -package content.minigame.barbassault.arena.monsters +package content.minigame.barbassault.arena.Npcs import core.api.sendMessage import core.game.node.entity.Entity diff --git a/Server/src/main/content/minigame/barbassault/arena/monsters/PenanceRangerNPC.kt b/Server/src/main/content/minigame/barbassault/arena/Npcs/PenanceRangerNPC.kt similarity index 98% rename from Server/src/main/content/minigame/barbassault/arena/monsters/PenanceRangerNPC.kt rename to Server/src/main/content/minigame/barbassault/arena/Npcs/PenanceRangerNPC.kt index b031d341c..770b62ed0 100644 --- a/Server/src/main/content/minigame/barbassault/arena/monsters/PenanceRangerNPC.kt +++ b/Server/src/main/content/minigame/barbassault/arena/Npcs/PenanceRangerNPC.kt @@ -1,4 +1,4 @@ -package content.minigame.barbassault.arena.monsters +package content.minigame.barbassault.arena.Npcs import content.minigame.barbassault.BarbRole import content.minigame.barbassault.arena.BarbAssEvent diff --git a/Server/src/main/content/minigame/barbassault/arena/monsters/PenanceRunnerNPC.kt b/Server/src/main/content/minigame/barbassault/arena/Npcs/PenanceRunnerNPC.kt similarity index 97% rename from Server/src/main/content/minigame/barbassault/arena/monsters/PenanceRunnerNPC.kt rename to Server/src/main/content/minigame/barbassault/arena/Npcs/PenanceRunnerNPC.kt index ccc83e0fd..0ae6620bf 100644 --- a/Server/src/main/content/minigame/barbassault/arena/monsters/PenanceRunnerNPC.kt +++ b/Server/src/main/content/minigame/barbassault/arena/Npcs/PenanceRunnerNPC.kt @@ -1,4 +1,4 @@ -package content.minigame.barbassault.arena.monsters +package content.minigame.barbassault.arena.Npcs import content.minigame.barbassault.BarbRole import core.game.node.entity.Entity diff --git a/Server/src/main/content/minigame/barbassault/arena/monsters/PenanceSpawnNPC.kt b/Server/src/main/content/minigame/barbassault/arena/Npcs/PenanceSpawnNPC.kt similarity index 85% rename from Server/src/main/content/minigame/barbassault/arena/monsters/PenanceSpawnNPC.kt rename to Server/src/main/content/minigame/barbassault/arena/Npcs/PenanceSpawnNPC.kt index 94b51d992..a5cee0c87 100644 --- a/Server/src/main/content/minigame/barbassault/arena/monsters/PenanceSpawnNPC.kt +++ b/Server/src/main/content/minigame/barbassault/arena/Npcs/PenanceSpawnNPC.kt @@ -1,4 +1,4 @@ -package content.minigame.barbassault.arena.monsters +package content.minigame.barbassault.arena.Npcs import core.game.node.entity.Entity import core.game.node.entity.npc.NPC import core.game.node.entity.npc.NPCBehavior diff --git a/Server/src/main/content/minigame/barbassault/arena/scenery/DefenderTrap.kt b/Server/src/main/content/minigame/barbassault/arena/scenery/DefenderTrap.kt index 7b8d8fcc2..e6a679847 100644 --- a/Server/src/main/content/minigame/barbassault/arena/scenery/DefenderTrap.kt +++ b/Server/src/main/content/minigame/barbassault/arena/scenery/DefenderTrap.kt @@ -1,6 +1,6 @@ package content.minigame.barbassault.arena.scenery -import content.minigame.barbassault.arena.monsters.PENANCE_RUNNER_IDS +import content.minigame.barbassault.arena.Npcs.PENANCE_RUNNER_IDS import core.api.* import core.game.node.entity.Entity import core.game.node.entity.player.Player diff --git a/Server/src/main/content/minigame/barbassault/arena/scenery/EggCannon.kt b/Server/src/main/content/minigame/barbassault/arena/scenery/EggHopper.kt similarity index 97% rename from Server/src/main/content/minigame/barbassault/arena/scenery/EggCannon.kt rename to Server/src/main/content/minigame/barbassault/arena/scenery/EggHopper.kt index 831e9b5bd..34ae85e49 100644 --- a/Server/src/main/content/minigame/barbassault/arena/scenery/EggCannon.kt +++ b/Server/src/main/content/minigame/barbassault/arena/scenery/EggHopper.kt @@ -1,6 +1,7 @@ package content.minigame.barbassault.arena.scenery import content.minigame.barbassault.BarbRole +import content.minigame.barbassault.arena.BarbassaultSession import content.minigame.barbassault.baSession import core.api.* import core.game.component.CloseEvent @@ -19,8 +20,9 @@ import org.rs09.consts.Items // half -> EGG_HOPPER_20265 // full -> EGG_HOPPER_20266 //varbit 3268 +//todo fix naming of hopper/cannon @Initializable -class EggCannon : ComponentPlugin() { +class EggHopper : ComponentPlugin() { //Easter Egg "Blinky Switch" private val currentSequence = mutableListOf() @@ -227,10 +229,18 @@ class EggCannon : ComponentPlugin() { val explosive = eggsCount?.red val stun = eggsCount?.blue sendDialogueLines(player,"The hopper contains:","$poison poison eggs, $explosive explosive eggs","and $stun stun eggs.") + + } + + fun fireEgg(int: Int,){ + + } } } + + data class EggColors(val green: Int, val red: Int, val blue: Int) object EggTurret { const val ID = 495 @@ -281,7 +291,7 @@ You load the hopper. You cant load any more /Egg_type/s. Picking up wrong egg, "The egg exploded" / 5 damage - +getAttribute(self, "target", null) // you can set the NPC CANNON a target. "You put the egg in the bag"