Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -239,14 +239,21 @@ class CloningService : Service() {
corpse.posture = Posture.UPRIGHT
corpse.setTurnScale(1.0)
corpse.setMovementPercent(1.0)
corpse.health = corpse.maxHealth
applyCloneWounds(corpse)
corpse.health = corpse.maxHealth - corpse.healthWounds
corpse.sendObservers(PlayClientEffectObjectMessage("clienteffect/player_clone_compile.cef", "", corpse.objectId, ""))
corpse.sendSelf(PlayMusicMessage(0, "sound/item_repairobj.snd", 1, false))
if (corpse.pvpFaction != PvpFaction.NEUTRAL) {
corpse.broadcast(UpdateFactionStatusIntent(corpse, PvpStatus.ONLEAVE))
}
}

// Pre-designating a facility isn't supported yet, so every clone is away from the players clone data and costs the full wounds
private fun applyCloneWounds(corpse: CreatureObject) {
val woundCeiling = (corpse.maxHealth * MAX_WOUND_PERCENTAGE).toInt()
corpse.healthWounds = (corpse.healthWounds + CLONE_WOUNDS).coerceAtMost(woundCeiling)
}

/**
* Picks the closest cloning facility and clones `cloneRequestor`
* there. If an error occurs upon attempting to clone, it will pick the next
Expand Down Expand Up @@ -318,6 +325,8 @@ class CloningService : Service() {

companion object {
private const val CLONE_TIMER: Long = 30 // Amount of minutes before a player is forced to clone
private const val CLONE_WOUNDS = 100 // Health wounds received when cloning away from your clone data
private const val MAX_WOUND_PERCENTAGE = 0.7 // Wounds can never take more than this share of unmodified maximum health
private val defaultCloner: BuildingObject?
get() {
val defaultCloner = BuildingLookup.getBuildingByTag("tat_moseisley_cloning1")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import com.projectswg.holocore.services.gameplay.combat.cloning.CloningService
import com.projectswg.holocore.services.gameplay.combat.duel.DuelService
import com.projectswg.holocore.services.support.objects.ObjectStorageService
import com.projectswg.holocore.test.runners.AcceptanceTest
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertDoesNotThrow
Expand Down Expand Up @@ -61,4 +62,24 @@ class CloningTest : AcceptanceTest() {

assertDoesNotThrow { character2.waitForObjectMove() }
}

@Test
fun `cloning applies health wounds`() {
val user = generateUser(AccessLevel.DEV)
val character1 = HeadlessSWGClient.createZonedInCharacter(user.username, user.password, "charone")
val character2 = HeadlessSWGClient.createZonedInCharacter(user.username, user.password, "chartwo")
character1.duel(character2.player.creatureObject)
character2.duel(character1.player.creatureObject)
character1.adminKill(character2.player.creatureObject)
character1.deathblow(character2.player.creatureObject)

val suiWindow = character2.waitForCloneActivation()
suiWindow.select(0)
suiWindow.clickOk()
character2.waitForObjectMove()

val clone = character2.player.creatureObject
assertEquals(100, clone.healthWounds)
assertEquals(clone.maxHealth - clone.healthWounds, clone.health)
}
}