@@ -9,7 +9,6 @@ import at.petrak.hexcasting.api.casting.eval.env.PlayerBasedCastEnv
99import at.petrak.hexcasting.api.casting.getVec3
1010import at.petrak.hexcasting.api.casting.iota.Iota
1111import at.petrak.hexcasting.api.casting.mishaps.MishapBadLocation
12- import at.petrak.hexcasting.common.msgs.MsgBlinkS2C
1312import at.petrak.hexcasting.xplat.IXplatAbstractions
1413import net.minecraft.server.level.ServerPlayer
1514import net.minecraft.world.entity.Entity
@@ -77,10 +76,7 @@ object OpCloseGate : VarargSpellAction {
7776 fun teleport (teleportee : Entity , allTeleportees : Set <Entity >, delta : Vec3 , env : CastingEnvironment ) {
7877 val distance = delta.length()
7978
80- // TODO make this not a magic number (config?)
81- if (distance < 32768.0 ) {
82- teleportRespectSticky(teleportee, allTeleportees, delta)
83- }
79+ teleportRespectSticky(teleportee, allTeleportees, delta)
8480
8581 if (teleportee is ServerPlayer && teleportee == env.caster && distance < PlayerBasedCastEnv .AMBIT_RADIUS && dropItems) {
8682 // Drop items conditionally, based on distance teleported.
@@ -116,37 +112,35 @@ object OpCloseGate : VarargSpellAction {
116112 }
117113
118114 fun teleportRespectSticky (teleportee : Entity , allTeleportees : Set <Entity >, delta : Vec3 ) {
119- val base = teleportee.rootVehicle
120-
121- val playersToUpdate = mutableListOf<ServerPlayer >()
122- val indirect = base.indirectPassengers
123-
124- val allGated = indirect.all { allTeleportees.contains(it) }
125- val sticky = indirect.any { it.type.`is `(HexTags .Entities .STICKY_TELEPORTERS ) }
126- val cannotSticky = indirect.none { it.type.`is `(HexTags .Entities .CANNOT_TELEPORT ) }
127- if (sticky && cannotSticky)
128- return
115+ // pop off any riders in the stack that shouldn't get teleported
116+ recursiveDismount(teleportee, allTeleportees)
129117
130- if (cannotSticky || ! allGated) {
131- // Break it into two stacks
118+ // only dismount+teleport if nothing below you is getting teleported
119+ if (! aboveStackRoot(teleportee, allTeleportees)) {
120+ val target = teleportee.position().add(delta)
132121 teleportee.stopRiding()
133- teleportee.passengers.forEach(Entity ::stopRiding)
134- teleportee.setPos(teleportee.position().add(delta))
135- if (teleportee is ServerPlayer ) {
136- playersToUpdate.add(teleportee)
122+ teleportee.teleportTo(target.x, target.y, target.z)
123+ }
124+ }
125+
126+ fun recursiveDismount (base : Entity , allTeleportees : Set <Entity >) {
127+ val sticky = base.type.`is `(HexTags .Entities .STICKY_TELEPORTERS )
128+ for (passenger in base.passengers) {
129+ if (passenger.type.`is `(HexTags .Entities .CANNOT_TELEPORT ) || (! sticky && ! allTeleportees.contains(passenger))) {
130+ passenger.stopRiding()
131+ } else {
132+ recursiveDismount(passenger, allTeleportees)
137133 }
138- } else {
139- // this handles teleporting the passengers
140- val target = base.position().add(delta)
141- base.teleportTo(target.x, target.y, target.z)
142- indirect
143- .filterIsInstance<ServerPlayer >()
144- .forEach(playersToUpdate::add)
145134 }
135+ }
146136
147- for (player in playersToUpdate) {
148- player.connection.resetPosition()
149- IXplatAbstractions .INSTANCE .sendPacketToPlayer(player, MsgBlinkS2C (delta))
137+ fun aboveStackRoot (toCheck : Entity , allTeleportees : Set <Entity >): Boolean {
138+ val lowerVehicle = toCheck.vehicle?.vehicle
139+ val vehicleGated = allTeleportees.contains(toCheck.vehicle)
140+ if (lowerVehicle == null ) {
141+ return vehicleGated
142+ } else {
143+ return vehicleGated || (allTeleportees.contains(lowerVehicle) && lowerVehicle.type.`is `(HexTags .Entities .STICKY_TELEPORTERS ))
150144 }
151145 }
152146}
0 commit comments