Added new camera API methods (including shake and reset)

Added new admin commands for testing camera movements (::poscam, ::movcam, ::rotcam, ::shakecam, ::resetcam)
This commit is contained in:
Woahscam
2023-08-19 15:45:54 +00:00
committed by Ryan
parent 1b4e0aafaa
commit 5cb9ef8511
5 changed files with 192 additions and 39 deletions
@@ -3,3 +3,21 @@ package core.api.utils
object CameraUtils { object CameraUtils {
} }
/*
* All camera shake types were found by facing the camera North using
* these values:
* Type [0-4] Jit: 0 Amp: 0 Freq: 128 Speed: 2
*
* **See Also:** [This forum post](https://forum.2009scape.org/viewtopic.php?t=173-in-game-camera-movement-documentation-server-sided)
*
* WARNING: Playing around with camera shake values may potentially trigger seizures for people with photosensitive epilepsy.
* Please use care when discovering camera values.
*/
enum class CameraShakeType {
TRUCK, // camera movement from left to right
PEDESTAL, // camera movement vertically up to down, fixated on one location
DOLLY, // camera movement forwards to backwards
PAN, // camera movement horizontally, fixed on a certain point
TILT // camera movement vertically, fixed on a certain point
}
@@ -5,6 +5,16 @@ import core.net.packet.PacketRepository
import core.net.packet.context.CameraContext import core.net.packet.context.CameraContext
import core.net.packet.out.CameraViewPacket import core.net.packet.out.CameraViewPacket
/**
* Player camera
*
* @property player
* @constructor Create empty Player camera
* **See Also:** [This forum post](https://forum.2009scape.org/viewtopic.php?t=173-in-game-camera-movement-documentation-server-sided)
*
* WARNING: Playing around with camera values may potentially trigger seizures for people with photosensitive epilepsy.
* Please use care when using camera values.
*/
class PlayerCamera(val player: Player?) { class PlayerCamera(val player: Player?) {
var ctx: CameraContext? = null var ctx: CameraContext? = null
@@ -29,4 +39,14 @@ class PlayerCamera(val player: Player?) {
ctx = CameraContext(player,CameraContext.CameraType.POSITION,x,y,height,speed,1) ctx = CameraContext(player,CameraContext.CameraType.POSITION,x,y,height,speed,1)
PacketRepository.send(CameraViewPacket::class.java,ctx) PacketRepository.send(CameraViewPacket::class.java,ctx)
} }
fun shake(cameraType: Int, jitter: Int, amplitude: Int, frequency: Int, speed: Int){
player ?: return
ctx = CameraContext(player,CameraContext.CameraType.SHAKE,cameraType,jitter,amplitude,frequency,speed)
PacketRepository.send(CameraViewPacket::class.java,ctx)
}
fun reset(){
player ?: return
ctx = CameraContext(player,CameraContext.CameraType.RESET, -1, -1, -1, -1, -1)
PacketRepository.send(CameraViewPacket::class.java,ctx)
}
} }
+37 -1
View File
@@ -22,9 +22,9 @@ import core.net.packet.out.MinimapState
import org.rs09.consts.Components import org.rs09.consts.Components
import core.ServerConstants import core.ServerConstants
import core.api.Event import core.api.Event
import core.api.utils.CameraShakeType
import core.api.utils.PlayerCamera import core.api.utils.PlayerCamera
import core.game.system.timer.impl.AntiMacro import core.game.system.timer.impl.AntiMacro
import core.tools.SystemLogger
import core.game.world.GameWorld import core.game.world.GameWorld
import core.tools.Log import core.tools.Log
@@ -314,6 +314,42 @@ abstract class Cutscene(val player: Player) {
camera.rotateTo(globalLoc.x, globalLoc.y, height, speed) camera.rotateTo(globalLoc.x, globalLoc.y, height, speed)
} }
/**
* Rotates the camera to face the given difference of the X and Y coordinates
* @param regionX the difference X value to rotate the camera to (0-63)
* @param regionY the difference Y value to rotate the camera to (0-63)
* @param height (optional) the height of the camera, defaults to 300.
* @param speed (optional) the speed of the camera transition, defaults to 100.
*/
fun rotateCameraBy(diffX: Int, diffY: Int, diffHeight: Int = 300, diffSpeed: Int = 100)
{
camera.rotateBy(diffX, diffY, diffHeight, diffSpeed)
}
/**
* Manipulates the camera using different camera types. Also known as "shake"
* @param cameraType the "type" of shake: TRUCK, PEDESTAL, DOLLY, PAN, TILT
* @param jitter (optional) the amount to rock the camera while looping
* @param amplitude (optional) the maximum extent of camera vibration
* @param frequency (optional) the rate at which jitter and amplitude are repeated
* @param speed (optional) the rate at which the whole camera "shake" loop is repeated
*
* WARNING: Playing around with camera shake values may potentially trigger seizures for people with photosensitive epilepsy.
* Please use care when using the "shake" camera values.
*/
fun shakeCamera(cameraType: CameraShakeType, jitter: Int = 0, amplitude: Int = 0, frequency: Int = 128, speed: Int = 2)
{
camera.shake(cameraType.ordinal, jitter, amplitude, frequency, speed)
}
/**
* Resets the camera to the current player position
*/
fun resetCamera()
{
camera.reset()
}
/** /**
* Sets the location the player is placed at when the cutscene ends. * Sets the location the player is placed at when the cutscene ends.
*/ */
@@ -0,0 +1,117 @@
package core.game.system.command.sets
import core.api.sendMessage
import core.api.utils.PlayerCamera
import core.game.system.command.Privilege
import core.game.world.map.RegionManager
import core.plugin.Initializable
/**
* Camera command set
*
* @constructor Create empty Camera command set
*
* WARNING: Playing around with camera values may potentially trigger seizures for people with photosensitive epilepsy.
* Please use care when discovering camera values.
*/
@Initializable
class CameraCommandSet : CommandSet(Privilege.ADMIN) {
override fun defineCommands() {
define("poscam", Privilege.ADMIN, "::poscam <lt>Region X<gt> <lt>Region Y<gt> [<lt>Height<gt>]", "Positions the camera to the given region-local coordinates.") { player, args ->
val regionX = args[1].toIntOrNull() ?: return@define
val regionY = args[2].toIntOrNull() ?: return@define
var height = 300
if (args.size > 3) {
height = args[3].toIntOrNull() ?: return@define
}
val region = RegionManager.forId(player.location.regionId)
val base = region.baseLocation
val globalLoc = base.transform(regionX, regionY, 0)
sendMessage(player, "<col=8e7cc3><shad=000000>CAMERA POSITION | loc:[$regionX, $regionY] settings:[height:$height]</shad></col>")
PlayerCamera(player).setPosition(globalLoc.x, globalLoc.y, height)
}
define("movcam", Privilege.ADMIN, "::movcam <lt>Region X<gt> <lt>Region Y<gt> [<lt>Height<gt> <lt>Speed<gt>]", "Moves the camera to the given region-local coordinates.") { player, args ->
val regionX = args[1].toIntOrNull() ?: return@define
val regionY = args[2].toIntOrNull() ?: return@define
var height = 300
var speed = 100
if (args.size > 3)
height = args[3].toIntOrNull() ?: return@define
if (args.size > 4)
speed = args[4].toIntOrNull() ?: return@define
val region = RegionManager.forId(player.location.regionId)
val base = region.baseLocation
val globalLoc = base.transform(regionX, regionY, 0)
sendMessage(player, "<col=8e7cc3><shad=000000>CAMERA MOVE | loc:[$regionX, $regionY] settings:[height:$height, speed:$speed]</shad></col>")
PlayerCamera(player).panTo(globalLoc.x, globalLoc.y, height, speed)
}
define("rotcam", Privilege.ADMIN, "::rotcam <lt>Region X<gt> <lt>Region Y<gt> [<lt>Height<gt> <lt>Speed<gt>]", "Rotates the camera to face the given region-local coordinates.") { player, args ->
val regionX = args[1].toIntOrNull() ?: return@define
val regionY = args[2].toIntOrNull() ?: return@define
var height = 300
var speed = 100
if (args.size > 3) {
height = args[3].toIntOrNull() ?: return@define
}
if (args.size > 4) {
speed = args[4].toIntOrNull() ?: return@define
}
val region = RegionManager.forId(player.location.regionId)
val base = region.baseLocation
val globalLoc = base.transform(regionX, regionY, 0)
sendMessage(player, "<col=8e7cc3><shad=000000>CAMERA ROTATE | loc:[$regionX, $regionY] settings:[height:$height, speed:$speed]</shad></col>")
PlayerCamera(player).rotateTo(globalLoc.x, globalLoc.y, height, speed)
}
define("shakecam", Privilege.ADMIN, "::shakecam <lt>Camera Movement Type (0-4)<gt> [<lt>Jitter<gt> <lt>Amplitude<gt> <lt>Frequency<gt> <lt>Speed<gt>]",
"Type (0-4) Jitter, Amplitude, Frequency (0-255)") {player, args ->
val cameraMovementType = args[1].toIntOrNull() ?: return@define
if (cameraMovementType < 0 || cameraMovementType > 4) {
return@define
}
// Type [0-4] Jit: 0 Amp: 0 Freq: 128 Speed: 2
var jitter = 0
var amplitude = 0
var frequency = 128
var speed = 2
if (args.size > 2) {
jitter = args[2].toIntOrNull() ?: return@define
}
if (args.size > 3) {
amplitude = args[3].toIntOrNull() ?: return@define
}
if (args.size > 4) {
frequency = args[4].toIntOrNull() ?: return@define
}
if (args.size > 5) {
speed = args[5].toIntOrNull() ?: return@define
}
sendMessage(player, "<col=8e7cc3><shad=000000>CAMERA SHAKE | type:$cameraMovementType settings:[jit:$jitter, amp:$amplitude, freq:$frequency, speed:$speed]</shad></col>")
PlayerCamera(player).shake(cameraMovementType, jitter, amplitude, frequency, speed)
}
define("resetcam", Privilege.ADMIN, "::resetcam", "Resets the current camera position.") {player, args ->
sendMessage(player, "<col=8e7cc3><shad=000000>CAMERA RESET</shad></col>")
PlayerCamera(player).reset()
}
}
}
@@ -64,44 +64,6 @@ class MiscCommandSet : CommandSet(Privilege.ADMIN){
} }
} }
define("movcam", Privilege.ADMIN, "::movcam <lt>Region X<gt> <lt>Region Y<gt> [<lt>Height<gt> <lt>Speed<gt>]", "Moves the camera to the given region-local coordinates.") {player, args ->
val regionX = args[1].toIntOrNull() ?: return@define
val regionY = args[2].toIntOrNull() ?: return@define
var height = 300
var speed = 100
if (args.size > 3)
height = args[3].toIntOrNull() ?: return@define
if (args.size > 4)
speed = args[4].toIntOrNull() ?: return@define
val region = RegionManager.forId(player.location.regionId)
val base = region.baseLocation
val globalLoc = base.transform(regionX, regionY, 0)
PlayerCamera(player).panTo(globalLoc.x, globalLoc.y, height, speed)
}
define("rotcam", Privilege.ADMIN, "::rotcam <lt>Region X<gt> <lt>Region Y<gt> [<lt>Height<gt> <lt>Speed<gt>]", "Rotates the camera to face the given region-local coordinates.") {player, args ->
val regionX = args[1].toIntOrNull() ?: return@define
val regionY = args[2].toIntOrNull() ?: return@define
var height = 300
var speed = 100
if (args.size > 3)
height = args[3].toIntOrNull() ?: return@define
if (args.size > 4)
speed = args[4].toIntOrNull() ?: return@define
val region = RegionManager.forId(player.location.regionId)
val base = region.baseLocation
val globalLoc = base.transform(regionX, regionY, 0)
PlayerCamera(player).rotateTo(globalLoc.x, globalLoc.y, height, speed)
}
define("anmacs", Privilege.ADMIN) { player, _ -> define("anmacs", Privilege.ADMIN) { player, _ ->
AnmaCutscene(player).start() AnmaCutscene(player).start()
} }