mirror of
https://github.com/ProjectSWGCore/Holocore.git
synced 2026-09-12 22:45:18 -04:00
Merge pull request #1283 from madsboddum/Holocore-1275
[Mission] Terminal missions spawn lairs
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/***********************************************************************************
|
||||
* Copyright (c) 2018 /// Project SWG /// www.projectswg.com *
|
||||
* Copyright (c) 2023 /// Project SWG /// www.projectswg.com *
|
||||
* *
|
||||
* ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
|
||||
* July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
|
||||
@@ -53,14 +53,27 @@ import me.joshlarson.jlcommon.control.IntentChain;
|
||||
import me.joshlarson.jlcommon.log.Log;
|
||||
import me.joshlarson.jlcommon.utilities.Arguments;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
public class NPCCreator {
|
||||
|
||||
public static AIObject createNPC(Spawner spawner) {
|
||||
public static Collection<AIObject> createNPCs(Spawner spawner) {
|
||||
Arguments.validate(spawner.getMinLevel() <= spawner.getMaxLevel(), "min level must be less than max level");
|
||||
int amount = spawner.getAmount();
|
||||
Collection<AIObject> npcs = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < amount; i++) {
|
||||
npcs.add(createNPC(spawner));
|
||||
}
|
||||
|
||||
return npcs;
|
||||
}
|
||||
|
||||
private static AIObject createNPC(Spawner spawner) {
|
||||
int combatLevel = ThreadLocalRandom.current().nextInt(spawner.getMinLevel(), spawner.getMaxLevel()+1);
|
||||
AIObject object = ObjectCreator.createObjectFromTemplate(spawner.getRandomIffTemplate(), AIObject.class);
|
||||
|
||||
|
||||
+28
-16
@@ -31,6 +31,7 @@ import com.projectswg.common.data.encodables.oob.ProsePackage
|
||||
import com.projectswg.common.data.encodables.oob.StringId
|
||||
import com.projectswg.common.data.encodables.oob.waypoint.WaypointColor
|
||||
import com.projectswg.common.data.encodables.oob.waypoint.WaypointPackage
|
||||
import com.projectswg.common.data.encodables.tangible.PvpFlag
|
||||
import com.projectswg.common.data.location.Location
|
||||
import com.projectswg.common.data.location.Terrain
|
||||
import com.projectswg.common.data.swgfile.ClientFactory
|
||||
@@ -38,7 +39,6 @@ import com.projectswg.common.network.packets.swg.zone.object_controller.MissionA
|
||||
import com.projectswg.common.network.packets.swg.zone.object_controller.MissionAcceptRequest
|
||||
import com.projectswg.common.network.packets.swg.zone.object_controller.MissionAcceptResponse
|
||||
import com.projectswg.common.network.packets.swg.zone.object_controller.MissionListRequest
|
||||
import com.projectswg.holocore.intents.gameplay.combat.CreatureKilledIntent
|
||||
import com.projectswg.holocore.intents.support.global.chat.SystemMessageIntent
|
||||
import com.projectswg.holocore.intents.support.global.network.InboundPacketIntent
|
||||
import com.projectswg.holocore.intents.support.objects.swg.DestroyObjectIntent
|
||||
@@ -58,9 +58,11 @@ import com.projectswg.holocore.resources.support.objects.swg.SWGObject
|
||||
import com.projectswg.holocore.resources.support.objects.swg.ServerAttribute
|
||||
import com.projectswg.holocore.resources.support.objects.swg.creature.CreatureDifficulty
|
||||
import com.projectswg.holocore.resources.support.objects.swg.creature.CreatureObject
|
||||
import com.projectswg.holocore.resources.support.objects.swg.custom.AIObject
|
||||
import com.projectswg.holocore.resources.support.objects.swg.custom.AIBehavior
|
||||
import com.projectswg.holocore.resources.support.objects.swg.group.GroupObject
|
||||
import com.projectswg.holocore.resources.support.objects.swg.mission.MissionObject
|
||||
import com.projectswg.holocore.resources.support.objects.swg.tangible.OptionFlag
|
||||
import com.projectswg.holocore.resources.support.objects.swg.tangible.TangibleObject
|
||||
import com.projectswg.holocore.resources.support.objects.swg.waypoint.WaypointObject
|
||||
import com.projectswg.holocore.services.support.objects.ObjectStorageService.ObjectLookup
|
||||
import me.joshlarson.jlcommon.control.IntentHandler
|
||||
@@ -74,7 +76,7 @@ class DestroyMissionService : Service() {
|
||||
|
||||
private val maxAcceptedMissions = 2
|
||||
private val missionsToGenerate = 5
|
||||
private val npcToMission = mutableMapOf<AIObject, MissionObject>()
|
||||
private val lairToMission = mutableMapOf<TangibleObject, MissionObject>()
|
||||
private val missionComplete = StringId("mission/mission_generic", "success_w_amount")
|
||||
|
||||
@IntentHandler
|
||||
@@ -107,11 +109,9 @@ class DestroyMissionService : Service() {
|
||||
return
|
||||
}
|
||||
|
||||
npcToMission.filterValues { it == missionObject }.forEach {
|
||||
val key = it.key
|
||||
DestroyObjectIntent.broadcast(key)
|
||||
DestroyObjectIntent.broadcast(npcToMission.remove(key))
|
||||
}
|
||||
val lairs = lairToMission.filterValues { it == missionObject }.keys
|
||||
lairs.forEach { lairToMission.remove(it) }
|
||||
DestroyObjectIntent.broadcast(missionObject)
|
||||
|
||||
val response = MissionAbort(creatureObject.objectId)
|
||||
response.missionObjectId = missionObjectId
|
||||
@@ -119,13 +119,13 @@ class DestroyMissionService : Service() {
|
||||
}
|
||||
|
||||
@IntentHandler
|
||||
private fun handleCreatureKilled(creatureKilledIntent: CreatureKilledIntent) {
|
||||
val corpse = creatureKilledIntent.corpse
|
||||
val missionObject = npcToMission.remove(corpse)
|
||||
private fun handleDestroyObject(destroyObjectIntent: DestroyObjectIntent) {
|
||||
val destroyedObject = destroyObjectIntent.`object`
|
||||
val missionObject = lairToMission.remove(destroyedObject)
|
||||
if (missionObject != null) {
|
||||
val owner = missionObject.owner
|
||||
if (owner != null) {
|
||||
handleMissionCompleted(owner, missionObject, corpse.location)
|
||||
handleMissionCompleted(owner, missionObject, destroyedObject.location)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -188,12 +188,14 @@ class DestroyMissionService : Service() {
|
||||
val location = missionObject.startLocation.toLocation()
|
||||
missionObject.waypointPackage = createWaypoint(location)
|
||||
|
||||
spawnNpc(location, missionObject)
|
||||
val lair = createLair(missionObject, location)
|
||||
lairToMission[lair] = missionObject
|
||||
spawnNpcs(location, missionObject)
|
||||
StandardLog.onPlayerEvent(this, player, "accepted %s", missionObject)
|
||||
}
|
||||
}
|
||||
|
||||
private fun spawnNpc(location: Location, missionObject: MissionObject) {
|
||||
private fun spawnNpcs(location: Location, missionObject: MissionObject) {
|
||||
val difficulty = missionObject.difficulty
|
||||
val egg = ObjectCreator.createObjectFromTemplate(SpawnerType.MISSION_EASY.objectTemplate)
|
||||
egg.containerPermissions = AdminPermissions.getPermissions()
|
||||
@@ -213,10 +215,20 @@ class DestroyMissionService : Service() {
|
||||
.withMinLevel(difficulty)
|
||||
.withMaxLevel(difficulty)
|
||||
.withLocation(location)
|
||||
.withAmount(3)
|
||||
.withBehavior(AIBehavior.LOITER)
|
||||
.build()
|
||||
|
||||
val npc = NPCCreator.createNPC(Spawner(spawnInfo, egg))
|
||||
npcToMission[npc] = missionObject
|
||||
NPCCreator.createNPCs(Spawner(spawnInfo, egg))
|
||||
}
|
||||
|
||||
private fun createLair(missionObject: MissionObject, location: Location): TangibleObject {
|
||||
val lair = ObjectCreator.createObjectFromTemplate(missionObject.targetAppearance.string) as TangibleObject
|
||||
lair.removeOptionFlags(OptionFlag.INVULNERABLE)
|
||||
lair.setPvpFlags(PvpFlag.YOU_CAN_ATTACK)
|
||||
lair.moveToContainer(null, location)
|
||||
ObjectCreatedIntent.broadcast(lair)
|
||||
return lair
|
||||
}
|
||||
|
||||
private fun handleTooManyMissions(creatureObject: CreatureObject, missionId: Long, missionAcceptRequest: MissionAcceptRequest, player: Player) {
|
||||
|
||||
+15
-21
@@ -1,29 +1,29 @@
|
||||
/***********************************************************************************
|
||||
* Copyright (c) 2018 /// Project SWG /// www.projectswg.com *
|
||||
* *
|
||||
* Copyright (c) 2023 /// Project SWG /// www.projectswg.com *
|
||||
* *
|
||||
* ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
|
||||
* July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
|
||||
* Our goal is to create an emulator which will provide a server for players to *
|
||||
* continue playing a game similar to the one they used to play. We are basing *
|
||||
* it on the final publish of the game prior to end-game events. *
|
||||
* *
|
||||
* *
|
||||
* This file is part of Holocore. *
|
||||
* *
|
||||
* *
|
||||
* --------------------------------------------------------------------------------*
|
||||
* *
|
||||
* *
|
||||
* Holocore is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Affero General Public License as *
|
||||
* published by the Free Software Foundation, either version 3 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* *
|
||||
* Holocore is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Affero General Public License for more details. *
|
||||
* *
|
||||
* *
|
||||
* You should have received a copy of the GNU Affero General Public License *
|
||||
* along with Holocore. If not, see <http:></http:>//www.gnu.org/licenses/>. *
|
||||
*/
|
||||
* along with Holocore. If not, see <http://www.gnu.org/licenses/>. *
|
||||
***********************************************************************************/
|
||||
package com.projectswg.holocore.services.support.npc.spawn
|
||||
|
||||
import com.projectswg.common.data.location.Location
|
||||
@@ -153,7 +153,9 @@ class SpawnerService : Service() {
|
||||
val respawnDelay = spawner.respawnDelay
|
||||
|
||||
if (respawnDelay > 0) {
|
||||
executor.execute((respawnDelay * 1000).toLong()) { respawn(spawner) }
|
||||
executor.execute((respawnDelay * 1000).toLong()) {
|
||||
NPCCreator.createNPCs(spawner)
|
||||
}
|
||||
} else {
|
||||
DestroyObjectIntent.broadcast(spawner.egg)
|
||||
}
|
||||
@@ -199,10 +201,8 @@ class SpawnerService : Service() {
|
||||
val egg = createEgg(spawn)
|
||||
val spawner = Spawner(spawn, egg)
|
||||
egg.setServerAttribute(ServerAttribute.EGG_SPAWNER, spawner)
|
||||
|
||||
for (i in 0 until spawner.amount) {
|
||||
NPCCreator.createNPC(spawner)
|
||||
}
|
||||
|
||||
NPCCreator.createNPCs(spawner)
|
||||
|
||||
val patrolRoute = spawner.patrolRoute
|
||||
if (patrolRoute != null) {
|
||||
@@ -217,13 +217,7 @@ class SpawnerService : Service() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun respawn(spawner: Spawner) {
|
||||
for (i in spawner.npcs.size until spawner.amount) {
|
||||
NPCCreator.createNPC(spawner)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun createEgg(spawn: SpawnInfo): SWGObject {
|
||||
val spawnerType = SpawnerType.valueOf(spawn.spawnerType)
|
||||
val egg = ObjectCreator.createObjectFromTemplate(spawnerType.objectTemplate)
|
||||
|
||||
+27
-2
@@ -1,3 +1,29 @@
|
||||
/***********************************************************************************
|
||||
* Copyright (c) 2023 /// Project SWG /// www.projectswg.com *
|
||||
* *
|
||||
* ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
|
||||
* July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
|
||||
* Our goal is to create an emulator which will provide a server for players to *
|
||||
* continue playing a game similar to the one they used to play. We are basing *
|
||||
* it on the final publish of the game prior to end-game events. *
|
||||
* *
|
||||
* This file is part of Holocore. *
|
||||
* *
|
||||
* --------------------------------------------------------------------------------*
|
||||
* *
|
||||
* Holocore is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Affero General Public License as *
|
||||
* published by the Free Software Foundation, either version 3 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* Holocore is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Affero General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Affero General Public License *
|
||||
* along with Holocore. If not, see <http://www.gnu.org/licenses/>. *
|
||||
***********************************************************************************/
|
||||
package com.projectswg.holocore.services.gameplay.combat
|
||||
|
||||
import com.projectswg.common.data.location.Location
|
||||
@@ -8,7 +34,6 @@ import com.projectswg.holocore.resources.support.npc.spawn.Spawner
|
||||
import com.projectswg.holocore.resources.support.objects.ObjectCreator
|
||||
import com.projectswg.holocore.resources.support.objects.swg.creature.CreatureDifficulty
|
||||
import com.projectswg.holocore.resources.support.objects.swg.custom.AIObject
|
||||
import com.projectswg.holocore.resources.support.objects.swg.weapon.WeaponObject
|
||||
import com.projectswg.holocore.test.runners.TestRunnerSynchronousIntents
|
||||
import org.junit.jupiter.api.Assertions.assertTrue
|
||||
import org.junit.jupiter.api.Test
|
||||
@@ -55,7 +80,7 @@ class NpcDefaultAttackTest : TestRunnerSynchronousIntents() {
|
||||
.withLocation(inFrontOfMosEisleyStarport)
|
||||
.build()
|
||||
|
||||
return NPCCreator.createNPC(Spawner(spawnInfo, egg))
|
||||
return NPCCreator.createNPCs(Spawner(spawnInfo, egg)).first()
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user