mirror of
https://gitlab.com/2009scape/2009scape.git
synced 2025-12-10 10:20:41 -07:00
Rewrote all the logic, encoding, etc for player/npc rendering masks (Animations, force movements, etc.)
Groundwork for modular 578 support has now been laid (at least in regards to render masks) Introduced an improved and more accurate API for using force movement (the old API is still around, all of its methods marked as deprecated) Converted a couple example cases to using the new force movement API just as a proof of concept Added a method to tick/time conversion methods to convert between client cycles and ticks Added all authentically-named buffer read/write methods to the buffer class
This commit is contained in:
parent
9329d9d008
commit
2cb8d82648
58 changed files with 963 additions and 1259 deletions
|
|
@ -9,7 +9,7 @@ import core.game.node.item.Item
|
|||
import core.game.world.map.Location
|
||||
import core.game.world.map.RegionManager
|
||||
import core.game.world.update.flag.context.ChatMessage
|
||||
import core.game.world.update.flag.player.ChatFlag
|
||||
import core.game.world.update.flag.*
|
||||
import core.integrations.discord.Discord
|
||||
import org.json.simple.JSONArray
|
||||
import org.json.simple.JSONObject
|
||||
|
|
@ -132,14 +132,14 @@ class DoublingMoney : Script() {
|
|||
val message = arrayOf("Doubling Money", "Doubling Money", "Doubling Money!", "Doubling moneyy").random()
|
||||
val messageEffect = arrayOf(0, 256).random()
|
||||
val ctx = ChatMessage(bot, message, messageEffect, message.length)
|
||||
bot.updateMasks.register(ChatFlag(ctx))
|
||||
bot.updateMasks.register(EntityFlag.Chat, ctx)
|
||||
sleepTime = 8
|
||||
}
|
||||
Effort.VERY_HIGH -> {
|
||||
val message = arrayOf("Doubling money!", "Doubling money").random()
|
||||
val messageEffect = arrayOf(771, 2818, 2562, 768, 512, 2304, 2560, 769, 1792).random()
|
||||
val ctx = ChatMessage(bot, message, messageEffect, message.length)
|
||||
bot.updateMasks.register(ChatFlag(ctx))
|
||||
bot.updateMasks.register(EntityFlag.Chat, ctx)
|
||||
sleepTime = 9
|
||||
}
|
||||
}
|
||||
|
|
@ -198,7 +198,7 @@ class DoublingMoney : Script() {
|
|||
if (botTradeModule.getInterface() == TradeModule.ACCEPT_INTERFACE && coinsFromBot > 0 && effort == Effort.VERY_HIGH) {
|
||||
val message = "Payed ${(if (coinsFromBot < 1000) "${coinsFromBot}gp" else "${coinsFromBot / 1000}k")}"
|
||||
val ctx = ChatMessage(bot, message, 512, message.length)
|
||||
bot.updateMasks.register(ChatFlag(ctx))
|
||||
bot.updateMasks.register(EntityFlag.Chat, ctx)
|
||||
|
||||
sleepTime = 7
|
||||
}
|
||||
|
|
@ -325,7 +325,7 @@ class DoublingMoney : Script() {
|
|||
if (effort == Effort.VERY_HIGH) {
|
||||
val message = "Received ${(if (coins.amount < 1000) "${coins.amount}gp" else "${coins.amount / 1000}k")}"
|
||||
val ctx = ChatMessage(bot, message, 256, message.length)
|
||||
bot.updateMasks.register(ChatFlag(ctx))
|
||||
bot.updateMasks.register(EntityFlag.Chat, ctx)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import core.game.system.task.Pulse
|
|||
import core.game.world.GameWorld
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.update.flag.context.Animation
|
||||
import core.game.world.update.flag.player.FaceLocationFlag
|
||||
import core.plugin.Initializable
|
||||
import core.plugin.Plugin
|
||||
|
||||
|
|
@ -136,7 +135,7 @@ class BasaltRockShortcut : AgilityShortcut {
|
|||
player.sendMessage(noJump)
|
||||
} else {
|
||||
player.lock(3)
|
||||
player.faceLocation(FaceLocationFlag.getFaceLocation(player, Location.create(2518, 3611, 0)))
|
||||
player.faceLocation(Location.create(2518, 3611, 0))
|
||||
AgilityHandler.forceWalk(player, -1, Location.create(2516, 3611, 0), Location.create(2518, 3611, 0), Animation.create(769), 20, 0.0, null, 1)
|
||||
}
|
||||
return true
|
||||
|
|
@ -147,7 +146,7 @@ class BasaltRockShortcut : AgilityShortcut {
|
|||
player.sendMessage(noJump)
|
||||
} else {
|
||||
player.lock(3)
|
||||
player.faceLocation(FaceLocationFlag.getFaceLocation(player, Location.create(2516, 3611, 0)))
|
||||
player.faceLocation(Location.create(2516, 3611, 0))
|
||||
AgilityHandler.forceWalk(player, -1, Location.create(2518, 3611, 0), Location.create(2516, 3611, 0), Animation.create(769), 20, 0.0, null, 1)
|
||||
}
|
||||
return true
|
||||
|
|
@ -199,4 +198,4 @@ class BasaltRockShortcut : AgilityShortcut {
|
|||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import core.game.node.scenery.SceneryBuilder;
|
|||
import core.game.world.GameWorld;
|
||||
import core.game.world.map.RegionManager;
|
||||
import core.game.world.update.flag.context.Animation;
|
||||
import core.game.world.update.flag.player.FaceLocationFlag;
|
||||
import core.tools.RandomFunction;
|
||||
|
||||
/**
|
||||
|
|
@ -129,7 +128,7 @@ public final class FireMakingPulse extends SkillPulse<Item> {
|
|||
SceneryBuilder.add(object, fire.getLife(), getAsh(player, fire, object));
|
||||
GroundItemManager.destroy(groundItem);
|
||||
player.moveStep();
|
||||
player.faceLocation(FaceLocationFlag.getFaceLocation(player, object));
|
||||
player.faceLocation(object.getFaceLocation(player.getLocation()));
|
||||
player.getSkills().addExperience(Skills.FIREMAKING,fire.getXp());
|
||||
|
||||
int playerRegion = player.getViewport().getRegion().getId();
|
||||
|
|
@ -191,4 +190,4 @@ public final class FireMakingPulse extends SkillPulse<Item> {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import core.cache.def.impl.NPCDefinition;
|
|||
import core.game.interaction.OptionHandler;
|
||||
import core.game.node.Node;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.world.update.flag.player.FaceLocationFlag;
|
||||
import core.plugin.Initializable;
|
||||
import core.plugin.Plugin;
|
||||
|
||||
|
|
@ -39,7 +38,7 @@ public final class FamiliarNPCOptionPlugin extends OptionHandler {
|
|||
}
|
||||
switch (option) {
|
||||
case "pick-up":
|
||||
player.faceLocation(FaceLocationFlag.getFaceLocation(player, familiar));
|
||||
player.faceLocation(familiar.getFaceLocation(player.getLocation()));
|
||||
player.getFamiliarManager().pickup();
|
||||
break;
|
||||
case "interact-with":
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import core.game.system.task.Pulse;
|
|||
import core.game.world.GameWorld;
|
||||
import core.game.world.map.RegionManager;
|
||||
import core.game.world.update.flag.context.Animation;
|
||||
import core.game.world.update.flag.player.FaceLocationFlag;
|
||||
import core.plugin.Initializable;
|
||||
import core.plugin.Plugin;
|
||||
import core.plugin.ClassScanner;
|
||||
|
|
@ -153,7 +152,7 @@ public class ForgeRegentNPC extends Familiar {
|
|||
familiar.moveStep();
|
||||
GroundItemManager.destroy(ground);
|
||||
player.getSkills().addExperience(Skills.FIREMAKING, log.getXp() + 10);
|
||||
familiar.faceLocation(FaceLocationFlag.getFaceLocation(familiar, object));
|
||||
familiar.faceLocation(object.getFaceLocation(familiar.getLocation()));
|
||||
SceneryBuilder.add(object, log.getLife(), FireMakingPulse.getAsh(player, log, object));
|
||||
if (player.getViewport().getRegion().getId() == 10806) {
|
||||
player.getAchievementDiaryManager().finishTask(player, DiaryType.SEERS_VILLAGE, 1, 9);
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ import core.game.world.GameWorld;
|
|||
import core.game.world.map.RegionManager;
|
||||
import core.game.world.update.flag.context.Animation;
|
||||
import core.game.world.update.flag.context.Graphics;
|
||||
import core.game.world.update.flag.player.FaceLocationFlag;
|
||||
import core.plugin.Plugin;
|
||||
import core.plugin.ClassScanner;
|
||||
|
||||
|
|
@ -132,7 +131,7 @@ public class PyreLordNPC extends Familiar {
|
|||
familiar.moveStep();
|
||||
GroundItemManager.destroy(ground);
|
||||
player.getSkills().addExperience(Skills.FIREMAKING, log.getXp() + 10);
|
||||
familiar.faceLocation(FaceLocationFlag.getFaceLocation(familiar, object));
|
||||
familiar.faceLocation(object.getFaceLocation(familiar.getLocation()));
|
||||
SceneryBuilder.add(object, log.getLife(), FireMakingPulse.getAsh(player, log, object));
|
||||
if (player.getViewport().getRegion().getId() == 10806) {
|
||||
player.getAchievementDiaryManager().finishTask(player, DiaryType.SEERS_VILLAGE, 1, 9);
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ import core.tools.RandomFunction;
|
|||
import static core.api.ContentAPIKt.animateScenery;
|
||||
import static core.api.ContentAPIKt.submitWorldPulse;
|
||||
import static core.api.ContentAPIKt.animationDuration;
|
||||
import static core.api.ContentAPIKt.forceMove;
|
||||
|
||||
/**
|
||||
* Handles the puro puro activity.
|
||||
|
|
@ -161,13 +162,7 @@ public final class PuroPuroPlugin extends MapZone implements Plugin<Object> {
|
|||
player.sendMessage("You use your strength to push through the wheat. It's hard work though.");
|
||||
}
|
||||
player.setAttribute("cantMove", true);
|
||||
GameWorld.getPulser().submit(new Pulse(1) {
|
||||
@Override
|
||||
public boolean pulse() {
|
||||
ForceMovement.run(player, player.getLocation(), dest, Animation.create(6594), Animation.create(6594), Direction.getLogicalDirection(player.getLocation(), object.getLocation()), 3, 3);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
forceMove(player, player.getLocation(), dest, 0, 265, null, 6595, null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -85,22 +85,7 @@ class TreeGnomeVillageListeners : InteractionListener {
|
|||
return@on true
|
||||
}
|
||||
on(looseRailing, IntType.SCENERY, "squeeze-through"){ player, _ ->
|
||||
if(player.location != location(2516,3161,0)) {
|
||||
squeezeThrough(player)
|
||||
} else {
|
||||
player.pulseManager.run(object : Pulse(0) {
|
||||
var count = 0
|
||||
override fun pulse(): Boolean {
|
||||
when (count) {
|
||||
0 -> ForceMovement.run(player,player.location,player.location.transform(Direction.WEST,1))
|
||||
2 -> squeezeThrough(player)
|
||||
3 -> return true
|
||||
}
|
||||
count++
|
||||
return false
|
||||
}
|
||||
})
|
||||
}
|
||||
squeezeThrough(player)
|
||||
return@on true
|
||||
}
|
||||
on(crumbledWall, IntType.SCENERY, "climb-over"){ player, _ ->
|
||||
|
|
@ -132,71 +117,55 @@ class TreeGnomeVillageListeners : InteractionListener {
|
|||
return@on true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun squeezeThrough(player: Player){
|
||||
val squeezeAnim = Animation.create(3844)
|
||||
if(player.location.y >= 3161) {
|
||||
AgilityHandler.forceWalk(
|
||||
player,
|
||||
-1,
|
||||
player.location,
|
||||
player.location.transform(Direction.SOUTH, 1),
|
||||
squeezeAnim,
|
||||
5,
|
||||
0.0,
|
||||
null
|
||||
)
|
||||
} else {
|
||||
AgilityHandler.forceWalk(
|
||||
player,
|
||||
-1,
|
||||
player.location,
|
||||
player.location.transform(Direction.NORTH, 1),
|
||||
squeezeAnim,
|
||||
5,
|
||||
0.0,
|
||||
null
|
||||
)
|
||||
fun squeezeThrough(player: Player){
|
||||
val squeezeAnim = Animation.create(3844)
|
||||
|
||||
var dest = if (player.location.y >= 3161)
|
||||
player.location.transform(Direction.SOUTH, 1)
|
||||
else
|
||||
player.location.transform(Direction.NORTH, 1)
|
||||
|
||||
forceMove(player, player.location, dest, 0, 80, anim = 3844)
|
||||
}
|
||||
}
|
||||
|
||||
private class ClimbWall : DialogueFile() {
|
||||
val climbAnimation = Animation(839)
|
||||
val wallLoc = Location(2509,3253,0)
|
||||
override fun handle(componentID: Int, buttonID: Int) {
|
||||
if(questStage(player!!, TreeGnomeVillage.questName) > 30){
|
||||
val northSouth = if (player!!.location.y <= wallLoc.y) Direction.NORTH else Direction.SOUTH
|
||||
when(stage){
|
||||
0 -> sendDialogue(player!!,"The wall has been reduced to rubble. It should be possible to climb over the remains").also{ stage++ }
|
||||
1 -> AgilityHandler.forceWalk(player!!, -1, player!!.location, player!!.location.transform(northSouth, 2), climbAnimation, 20, 0.0, null).also {
|
||||
end()
|
||||
if(northSouth == Direction.SOUTH) return
|
||||
val lowerGuard: NPC = RegionManager.getNpc(player!!.location, NPCs.KHAZARD_COMMANDER_478, 6) ?: return
|
||||
GameWorld.Pulser.submit(object : Pulse(0) {
|
||||
var count = 0
|
||||
override fun pulse(): Boolean {
|
||||
when (count) {
|
||||
0 -> {
|
||||
player!!.lock(4)
|
||||
lowerGuard.sendChat("What? How did you manage to get in here.")
|
||||
}
|
||||
2 -> {
|
||||
player!!.sendChat("I've come for the orb.")
|
||||
}
|
||||
3 -> {
|
||||
lowerGuard.sendChat("I'll never let you take it.")
|
||||
lowerGuard.attack(player)
|
||||
player!!.unlock()
|
||||
return true
|
||||
private class ClimbWall : DialogueFile() {
|
||||
val climbAnimation = Animation(839)
|
||||
val wallLoc = Location(2509,3253,0)
|
||||
override fun handle(componentID: Int, buttonID: Int) {
|
||||
if(questStage(player!!, TreeGnomeVillage.questName) > 30){
|
||||
val northSouth = if (player!!.location.y <= wallLoc.y) Direction.NORTH else Direction.SOUTH
|
||||
when(stage){
|
||||
0 -> sendDialogue(player!!,"The wall has been reduced to rubble. It should be possible to climb over the remains").also{ stage++ }
|
||||
1 -> AgilityHandler.forceWalk(player!!, -1, player!!.location, player!!.location.transform(northSouth, 2), climbAnimation, 20, 0.0, null).also {
|
||||
end()
|
||||
if(northSouth == Direction.SOUTH) return
|
||||
val lowerGuard: NPC = RegionManager.getNpc(player!!.location, NPCs.KHAZARD_COMMANDER_478, 6) ?: return
|
||||
GameWorld.Pulser.submit(object : Pulse(0) {
|
||||
var count = 0
|
||||
override fun pulse(): Boolean {
|
||||
when (count) {
|
||||
0 -> {
|
||||
player!!.lock(4)
|
||||
lowerGuard.sendChat("What? How did you manage to get in here.")
|
||||
}
|
||||
2 -> {
|
||||
player!!.sendChat("I've come for the orb.")
|
||||
}
|
||||
3 -> {
|
||||
lowerGuard.sendChat("I'll never let you take it.")
|
||||
lowerGuard.attack(player)
|
||||
player!!.unlock()
|
||||
return true
|
||||
}
|
||||
}
|
||||
count++
|
||||
return false
|
||||
}
|
||||
count++
|
||||
return false
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import core.game.system.task.Pulse;
|
|||
import core.game.world.GameWorld;
|
||||
import core.game.world.update.flag.context.Animation;
|
||||
import core.plugin.Initializable;
|
||||
import core.game.world.update.flag.player.FaceLocationFlag;
|
||||
|
||||
/**
|
||||
* Represents the dialogue plugin used for mithril seeds.
|
||||
|
|
@ -64,7 +63,7 @@ public final class MithrilSeedsDialogue extends DialoguePlugin {
|
|||
switch (buttonId) {
|
||||
case 1: // First option
|
||||
player.lock(2);
|
||||
player.faceLocation(FaceLocationFlag.getFaceLocation(player, flower));
|
||||
player.faceLocation(flower.getFaceLocation(player.getLocation()));
|
||||
player.animate(ANIMATION);
|
||||
GameWorld.getPulser().submit(new Pulse(2, player, flower) {
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import core.game.system.task.Pulse;
|
|||
import core.game.world.GameWorld;
|
||||
import core.game.world.map.RegionManager;
|
||||
import core.game.world.update.flag.context.Animation;
|
||||
import core.game.world.update.flag.player.FaceLocationFlag;
|
||||
import core.plugin.Initializable;
|
||||
import core.plugin.Plugin;
|
||||
import core.tools.RandomFunction;
|
||||
|
|
@ -67,7 +66,7 @@ public final class MithrilSeedsPlugin extends OptionHandler {
|
|||
player.getPulseManager().run(new Pulse(1, player) {
|
||||
@Override
|
||||
public boolean pulse() {
|
||||
player.faceLocation(FaceLocationFlag.getFaceLocation(player, object));
|
||||
player.faceLocation(object.getFaceLocation(player.getLocation()));
|
||||
player.getDialogueInterpreter().open(1 << 16 | 1, object);
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@ import core.game.world.map.Location;
|
|||
import core.game.world.map.RegionManager;
|
||||
import core.game.world.map.zone.ZoneBorders;
|
||||
import core.game.world.map.zone.ZoneRestriction;
|
||||
import core.game.world.update.flag.player.AppearanceFlag;
|
||||
import core.tools.RandomFunction;
|
||||
|
||||
/**
|
||||
|
|
@ -140,7 +139,7 @@ public final class TzhaarFightPitsPlugin extends ActivityPlugin {
|
|||
lastVictor.getAchievementDiaryManager().finishTask(lastVictor, DiaryType.KARAMJA, 2, 0);
|
||||
addTokkul(lastVictor);
|
||||
lastVictor.getAppearance().setSkullIcon(SKULL_ID);
|
||||
lastVictor.getUpdateMasks().register(new AppearanceFlag(lastVictor));
|
||||
lastVictor.updateAppearance();
|
||||
lastVictor.getPacketDispatch().sendString("Current Champion: " + getChampionName(), INTERFACE_ID, 0);
|
||||
resetDamagePulse(lastVictor);
|
||||
}
|
||||
|
|
@ -158,7 +157,7 @@ public final class TzhaarFightPitsPlugin extends ActivityPlugin {
|
|||
player.getInteraction().remove(Option._P_ATTACK);
|
||||
if (player.getAppearance().getSkullIcon() == SKULL_ID) {
|
||||
player.getAppearance().setSkullIcon(-1);
|
||||
player.getUpdateMasks().register(new AppearanceFlag(player));
|
||||
player.updateAppearance();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -190,7 +189,7 @@ public final class TzhaarFightPitsPlugin extends ActivityPlugin {
|
|||
}
|
||||
if (lastVictor.getAppearance().getSkullIcon() == SKULL_ID) {
|
||||
player.getAppearance().setSkullIcon(-1);
|
||||
player.getUpdateMasks().register(new AppearanceFlag(player));
|
||||
player.updateAppearance();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -238,7 +237,7 @@ public final class TzhaarFightPitsPlugin extends ActivityPlugin {
|
|||
}
|
||||
if (e instanceof Player && (player = (Player) e).getAppearance().getSkullIcon() == SKULL_ID) {
|
||||
player.getAppearance().setSkullIcon(-1);
|
||||
player.getUpdateMasks().register(new AppearanceFlag(player));
|
||||
player.updateAppearance();
|
||||
}
|
||||
return super.leave(e, logout);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,8 +41,6 @@ import core.game.world.map.zone.MapZone
|
|||
import core.game.world.map.zone.ZoneBorders
|
||||
import core.game.world.map.zone.ZoneBuilder
|
||||
import core.game.world.update.flag.chunk.AnimateObjectUpdateFlag
|
||||
import core.game.world.update.flag.context.Animation
|
||||
import core.game.world.update.flag.context.Graphics
|
||||
import org.rs09.consts.Items
|
||||
import org.rs09.consts.NPCs
|
||||
import core.game.dialogue.DialogueFile
|
||||
|
|
@ -55,9 +53,7 @@ import content.global.handlers.iface.ge.StockMarket
|
|||
import content.global.skill.slayer.SlayerManager
|
||||
import content.data.consumables.*
|
||||
import core.game.activity.Cutscene
|
||||
import core.game.interaction.Clocks
|
||||
import core.game.interaction.QueueStrength
|
||||
import core.game.interaction.QueuedScript
|
||||
import core.game.interaction.*
|
||||
import core.game.node.entity.player.info.LogType
|
||||
import core.game.node.entity.player.info.PlayerMonitor
|
||||
import core.tools.SystemLogger
|
||||
|
|
@ -68,11 +64,13 @@ import core.game.world.GameWorld.Pulser
|
|||
import core.game.world.map.path.ProjectilePathfinder
|
||||
import core.game.world.repository.Repository
|
||||
import core.game.consumable.*
|
||||
import core.tools.Log
|
||||
import core.tools.tick
|
||||
import core.ServerConstants
|
||||
import core.api.utils.Vector
|
||||
import core.tools.*
|
||||
import core.game.world.update.flag.*
|
||||
import core.game.world.update.flag.context.*
|
||||
import java.util.regex.*
|
||||
import java.io.*
|
||||
import kotlin.math.*
|
||||
|
||||
/**
|
||||
|
|
@ -1082,6 +1080,68 @@ fun forceWalk(entity: Entity, dest: Location, type: String) {
|
|||
path.walk(entity)
|
||||
}
|
||||
|
||||
/**
|
||||
* Force a player to move from the start location to the dest location
|
||||
* @param player the player we are moving
|
||||
* @param start the start location
|
||||
* @param dest the end location
|
||||
* @param startArrive the number of client cycles to take moving the player to the start location
|
||||
* @param destArrive the number of client cycles to take moving the player to the end location from the start location
|
||||
* @param direction (optional) the direction to face the player during the movement
|
||||
* @param anim (optional) the animation to use throughout the movement
|
||||
* @param callback (optional) a callback called when the forced movement completes
|
||||
* @see NOTE: There are 30 client cycles per second.
|
||||
*/
|
||||
fun forceMove (player: Player, start: Location, dest: Location, startArrive: Int, destArrive: Int, dir: Direction? = null, anim: Int = -1, callback: (()->Unit)? = null) {
|
||||
var direction: Direction
|
||||
|
||||
if (dir == null) {
|
||||
var delta = Location.getDelta(start, dest)
|
||||
var x = abs(delta.x)
|
||||
var y = abs(delta.y)
|
||||
|
||||
if (x > y)
|
||||
direction = Direction.getDirection(delta.x, 0)
|
||||
else
|
||||
direction = Direction.getDirection(0, delta.y)
|
||||
} else direction = dir
|
||||
|
||||
val startLoc = Location.create(start)
|
||||
val destLoc = Location.create(dest)
|
||||
var startArriveTick = getWorldTicks() + cyclesToTicks (startArrive) + 1
|
||||
var destArriveTick = startArriveTick + cyclesToTicks (destArrive)
|
||||
var maskSet = false
|
||||
|
||||
delayEntity(player, (destArriveTick - getWorldTicks()) + 1)
|
||||
queueScript (player, 0, QueueStrength.SOFT) { stage: Int ->
|
||||
if (!finishedMoving(player))
|
||||
return@queueScript keepRunning(player)
|
||||
if (!maskSet) {
|
||||
var ctx = ForceMoveCtx (startLoc, destLoc, startArrive, destArrive, direction)
|
||||
player.updateMasks.register(EntityFlag.ForceMove, ctx)
|
||||
maskSet = true
|
||||
}
|
||||
|
||||
var tick = getWorldTicks()
|
||||
if (tick < startArriveTick) {
|
||||
return@queueScript keepRunning(player)
|
||||
} else if (tick < destArriveTick) {
|
||||
if (animationFinished(player))
|
||||
animate (player, anim)
|
||||
return@queueScript keepRunning(player)
|
||||
} else if (tick >= destArriveTick) {
|
||||
try {
|
||||
callback?.invoke()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
player.properties.teleportLocation = dest
|
||||
return@queueScript stopExecuting(player)
|
||||
}
|
||||
return@queueScript stopExecuting(player)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Interrupts a given entity's walking queue
|
||||
* @param entity the entity to interrupt
|
||||
|
|
@ -2382,6 +2442,24 @@ fun log(origin: Class<*>, type: Log, message: String) {
|
|||
SystemLogger.processLogEntry(origin, type, message)
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs a message to the server console along with a stack trace leading up to it.
|
||||
* @param origin simply put (Kotlin) this::class.java or (Java) this.getClass()
|
||||
* @param type the type of log: Log.FINE (default, visible on VERBOSE), Log.INFO (visible on DETAILED), Log.WARN (visible on CAUTIOUS), Log.ERR (always visible)
|
||||
* @param message the actual message to log.
|
||||
*/
|
||||
fun logWithStack(origin: Class<*>, type: Log, message: String) {
|
||||
try {
|
||||
throw Exception(message)
|
||||
} catch (e: Exception) {
|
||||
val sw = StringWriter()
|
||||
val pw = PrintWriter(sw)
|
||||
e.printStackTrace(pw)
|
||||
|
||||
log(origin, type, "$sw")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by content handlers to check if the entity is done moving yet
|
||||
*/
|
||||
|
|
@ -2403,7 +2481,7 @@ fun delayScript(entity: Entity, ticks: Int): Boolean {
|
|||
*/
|
||||
fun delayEntity(entity: Entity, ticks: Int) {
|
||||
entity.scripts.delay = GameWorld.ticks + ticks
|
||||
lock(entity, 5) //TODO: REMOVE WHEN EVERYTHING IMPORTANT USES PROPER QUEUES - THIS IS INCORRECT BEHAVIOR
|
||||
lock(entity, ticks) //TODO: REMOVE WHEN EVERYTHING IMPORTANT USES PROPER QUEUES - THIS IS INCORRECT BEHAVIOR
|
||||
}
|
||||
|
||||
fun apRange(entity: Entity, apRange: Int) {
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ import core.game.world.map.path.Pathfinder
|
|||
import core.game.world.update.flag.context.Animation
|
||||
import core.game.world.update.flag.context.ChatMessage
|
||||
import core.game.world.update.flag.context.Graphics
|
||||
import core.game.world.update.flag.player.ChatFlag
|
||||
import core.game.world.update.flag.*
|
||||
import core.tools.RandomFunction
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
|
|
@ -90,7 +90,7 @@ class ScriptAPI(private val bot: Player) {
|
|||
|
||||
fun sendChat(message: String) {
|
||||
bot.sendChat(message)
|
||||
bot.updateMasks.register(ChatFlag(ChatMessage(bot, message, 0, 0)))
|
||||
bot.updateMasks.register(EntityFlag.Chat, ChatMessage(bot, message, 0, 0))
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import core.game.node.entity.combat.equipment.WeaponInterface;
|
|||
import core.game.node.entity.player.Player;
|
||||
import core.game.node.entity.skill.Skills;
|
||||
import core.game.node.item.Item;
|
||||
import core.game.world.update.flag.player.AppearanceFlag;
|
||||
import core.net.packet.PacketRepository;
|
||||
import core.net.packet.context.ContainerContext;
|
||||
import core.net.packet.out.ContainerPacket;
|
||||
|
|
@ -306,7 +305,7 @@ public final class EquipmentContainer extends Container {
|
|||
}
|
||||
}
|
||||
player.getAppearance().setAnimations();
|
||||
player.getUpdateMasks().register(new AppearanceFlag(player));
|
||||
player.updateAppearance();
|
||||
player.getSettings().updateWeight();
|
||||
updateBonuses(player);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import core.game.node.entity.player.Player;
|
|||
import core.game.node.item.Item;
|
||||
import core.game.node.scenery.Scenery;
|
||||
import core.game.system.task.Pulse;
|
||||
import core.game.world.update.flag.player.FaceLocationFlag;
|
||||
import core.net.packet.PacketRepository;
|
||||
import core.net.packet.context.InteractionOptionContext;
|
||||
import core.net.packet.out.InteractionOption;
|
||||
|
|
@ -145,7 +144,7 @@ public class InteractPlugin {
|
|||
@Override
|
||||
public boolean pulse() {
|
||||
try {
|
||||
player.faceLocation(FaceLocationFlag.getFaceLocation(player, node));
|
||||
player.faceLocation(node.getFaceLocation(player.getLocation()));
|
||||
if (player.getLocks().isInteractionLocked() || player.getZoneMonitor().interact(node, option)) {
|
||||
return true;
|
||||
}
|
||||
|
|
@ -181,7 +180,7 @@ public class InteractPlugin {
|
|||
@Override
|
||||
public boolean pulse() {
|
||||
try {
|
||||
player.faceLocation(FaceLocationFlag.getFaceLocation(player, node));
|
||||
player.faceLocation(node.getFaceLocation(player.getLocation()));
|
||||
if (player.getLocks().isInteractionLocked() || player.getZoneMonitor().interact(node, option)) {
|
||||
return true;
|
||||
}
|
||||
|
|
@ -344,4 +343,4 @@ public class InteractPlugin {
|
|||
this.initialized = initialized;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import core.tools.Log;
|
|||
import core.tools.SystemLogger;
|
||||
import core.game.system.task.Pulse;
|
||||
import core.game.world.map.Location;
|
||||
import core.game.world.update.flag.player.FaceLocationFlag;
|
||||
import core.plugin.Plugin;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -175,7 +174,7 @@ public abstract class UseWithHandler implements Plugin<Object> {
|
|||
@Override
|
||||
public boolean pulse() {
|
||||
event.getPlayer().dispatch(new UseWithEvent(event.getUsed().getId(), event.getUsedWith().getId()));
|
||||
event.getPlayer().faceLocation(FaceLocationFlag.getFaceLocation(event.getPlayer(), event.getUsedWith()));
|
||||
event.getPlayer().faceLocation(event.getUsedWith().getFaceLocation(event.getPlayer().getLocation()));
|
||||
boolean handled = false;
|
||||
Item used = (Item) event.getUsed();
|
||||
for (UseWithHandler h : handlers) {
|
||||
|
|
@ -273,4 +272,4 @@ public abstract class UseWithHandler implements Plugin<Object> {
|
|||
public boolean isDynamic() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import core.game.world.map.path.Pathfinder;
|
|||
import core.game.world.map.zone.ZoneMonitor;
|
||||
import core.game.world.update.flag.context.Animation;
|
||||
import core.game.world.update.flag.context.Graphics;
|
||||
import core.game.world.update.flag.*;
|
||||
import core.game.node.entity.combat.CombatSwingHandler;
|
||||
import core.game.world.update.UpdateMasks;
|
||||
|
||||
|
|
@ -48,7 +49,7 @@ public abstract class Entity extends Node {
|
|||
/**
|
||||
* The entity's update masks.
|
||||
*/
|
||||
private final UpdateMasks updateMasks = new UpdateMasks();
|
||||
private final UpdateMasks updateMasks = new UpdateMasks(this);
|
||||
|
||||
/**
|
||||
* The walking queue.
|
||||
|
|
@ -631,21 +632,39 @@ public abstract class Entity extends Node {
|
|||
* @param entity The entity to face.
|
||||
* @return {@code True} if succesful.
|
||||
*/
|
||||
public abstract boolean face(Entity entity);
|
||||
public boolean face(Entity entity) {
|
||||
if (entity == null) {
|
||||
int ordinal = EntityFlags.getOrdinal(EFlagType.of(this), EntityFlag.FaceEntity);
|
||||
if (getUpdateMasks().unregisterSynced(ordinal)) {
|
||||
return getUpdateMasks().register(EntityFlag.FaceEntity, null);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return getUpdateMasks().register(EntityFlag.FaceEntity, entity, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a new face location update flag to the update masks.
|
||||
* @param location The location to face.
|
||||
* @return {@code True} if succesful.
|
||||
*/
|
||||
public abstract boolean faceLocation(Location location);
|
||||
public boolean faceLocation(Location location) {
|
||||
if (location == null) {
|
||||
int ordinal = EntityFlags.getOrdinal(EFlagType.of(this), EntityFlag.FaceLocation);
|
||||
getUpdateMasks().unregisterSynced(ordinal);
|
||||
return true;
|
||||
}
|
||||
return getUpdateMasks().register(EntityFlag.FaceLocation, location, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a new force chat update flag to the update masks.
|
||||
* @param string The string.
|
||||
* @return {@code True} if succesful.
|
||||
*/
|
||||
public abstract boolean sendChat(String string);
|
||||
public boolean sendChat(String string) {
|
||||
return getUpdateMasks().register(EntityFlag.ForceChat, string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current combat swing handler.
|
||||
|
|
|
|||
|
|
@ -6,10 +6,7 @@ import core.game.node.entity.npc.NPC;
|
|||
import core.game.world.GameWorld;
|
||||
import core.game.world.update.flag.context.Animation;
|
||||
import core.game.world.update.flag.context.Graphics;
|
||||
import core.game.world.update.flag.npc.NPCAnimation;
|
||||
import core.game.world.update.flag.npc.NPCGraphic;
|
||||
import core.game.world.update.flag.player.AnimationFlag;
|
||||
import core.game.world.update.flag.player.GraphicFlag;
|
||||
import core.game.world.update.flag.EntityFlag;
|
||||
|
||||
/**
|
||||
* Handles the animating of an Entity.
|
||||
|
|
@ -128,12 +125,12 @@ public final class Animator {
|
|||
ticks = 0;
|
||||
}
|
||||
entity.clocks[Clocks.getANIMATION_END()] = ticks;
|
||||
entity.getUpdateMasks().register(entity instanceof NPC ? new NPCAnimation(animation) : new AnimationFlag(animation));
|
||||
entity.getUpdateMasks().register(EntityFlag.Animate, animation);
|
||||
priority = animation.getPriority();
|
||||
}
|
||||
if (graphic != null) {
|
||||
this.graphics = graphic;
|
||||
entity.getUpdateMasks().register(entity instanceof NPC ? new NPCGraphic(graphic) : new GraphicFlag(graphic));
|
||||
entity.getUpdateMasks().register(EntityFlag.SpotAnim, graphic);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -212,4 +209,4 @@ public final class Animator {
|
|||
public void setPriority(Priority priority) {
|
||||
this.priority = priority;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ import core.game.system.task.Pulse;
|
|||
import core.game.world.GameWorld;
|
||||
import core.game.world.map.Direction;
|
||||
import core.game.world.map.Location;
|
||||
import core.game.world.update.flag.context.Animation;
|
||||
import core.game.world.update.flag.player.ForceMovementFlag;
|
||||
import core.game.world.update.flag.context.*;
|
||||
import core.game.world.update.flag.*;
|
||||
|
||||
/**
|
||||
* The force movement handler.
|
||||
|
|
@ -91,8 +91,9 @@ public class ForceMovement extends Pulse {
|
|||
* @param commenceSpeed The commencing speed.
|
||||
* @param pathSpeed The path speed.
|
||||
* @param unlockAfter Whether to unlock the entity after the ForceMovement completes
|
||||
*
|
||||
* @deprecated this is no longer the preferred way to use force movement. Use the ContentAPI forceMove method instead, please.
|
||||
*/
|
||||
@Deprecated
|
||||
public ForceMovement(Entity e, Location start, Location destination, Animation startAnim, Animation animation, Direction direction, int commenceSpeed, int pathSpeed, boolean unlockAfter) {
|
||||
super(1, e);
|
||||
this.entity = e;
|
||||
|
|
@ -113,11 +114,17 @@ public class ForceMovement extends Pulse {
|
|||
* @param end the destination.
|
||||
* @param animation the animation.
|
||||
* @param speed The path speed.
|
||||
* @deprecated this is no longer the preferred way to use force movement. Use the ContentAPI forceMove method instead, please.
|
||||
*/
|
||||
@Deprecated
|
||||
public ForceMovement(Entity e, Location start, Location end, Animation animation, int speed) {
|
||||
this(e, start, end, WALK_ANIMATION, animation, direction(start, end), WALKING_SPEED, speed, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated this is no longer the preferred way to use force movement. Use the ContentAPI forceMove method instead, please.
|
||||
*/
|
||||
@Deprecated
|
||||
public ForceMovement(Entity e, Location destination, int startSpeed, int animSpeed){
|
||||
this(e,e.getLocation(),destination,WALK_ANIMATION,WALK_ANIMATION,direction(e.getLocation(),destination),startSpeed,animSpeed, true);
|
||||
}
|
||||
|
|
@ -128,7 +135,9 @@ public class ForceMovement extends Pulse {
|
|||
* @param start the start location.
|
||||
* @param destination the destination.
|
||||
* @param animation the animation.
|
||||
* @deprecated this is no longer the preferred way to use force movement. Use the ContentAPI forceMove method instead, please.
|
||||
*/
|
||||
@Deprecated
|
||||
public ForceMovement(Entity e, Location start, Location destination, Animation animation) {
|
||||
this(e, start, destination, WALK_ANIMATION, animation, direction(start, destination), WALKING_SPEED, WALKING_SPEED, true);
|
||||
}
|
||||
|
|
@ -138,7 +147,9 @@ public class ForceMovement extends Pulse {
|
|||
* @param start the start loc.
|
||||
* @param destination the destination.
|
||||
* @param animation the animation.
|
||||
* @deprecated this is no longer the preferred way to use force movement. Use the ContentAPI forceMove method instead, please.
|
||||
*/
|
||||
@Deprecated
|
||||
public ForceMovement(Location start, Location destination, Animation animation) {
|
||||
this(null, start, destination, WALK_ANIMATION, animation, direction(start, destination), WALKING_SPEED, WALKING_SPEED, true);
|
||||
}
|
||||
|
|
@ -148,7 +159,9 @@ public class ForceMovement extends Pulse {
|
|||
* @param e The entity.
|
||||
* @param destination The destination location.
|
||||
* @return The created ForceMovement object.
|
||||
* @deprecated this is no longer the preferred way to use force movement. Use the ContentAPI forceMove method instead, please.
|
||||
*/
|
||||
@Deprecated
|
||||
public static ForceMovement run(Entity e, Location destination) {
|
||||
return run(e, e.getLocation(), destination, WALK_ANIMATION, WALK_ANIMATION, direction(e.getLocation(), destination), WALKING_SPEED, WALKING_SPEED, true);
|
||||
}
|
||||
|
|
@ -159,7 +172,9 @@ public class ForceMovement extends Pulse {
|
|||
* @param start The start location.
|
||||
* @param destination The destination location.
|
||||
* @return The created ForceMovement object.
|
||||
* @deprecated this is no longer the preferred way to use force movement. Use the ContentAPI forceMove method instead, please.
|
||||
*/
|
||||
@Deprecated
|
||||
public static ForceMovement run(Entity e, Location start, Location destination) {
|
||||
return run(e, start, destination, WALK_ANIMATION, WALK_ANIMATION, direction(e.getLocation(), destination), WALKING_SPEED, WALKING_SPEED, true);
|
||||
}
|
||||
|
|
@ -171,7 +186,9 @@ public class ForceMovement extends Pulse {
|
|||
* @param destination The destination location.
|
||||
* @param animation The animation.
|
||||
* @return The created ForceMovement object.
|
||||
* @deprecated this is no longer the preferred way to use force movement. Use the ContentAPI forceMove method instead, please.
|
||||
*/
|
||||
@Deprecated
|
||||
public static ForceMovement run(Entity e, Location start, Location destination, Animation animation) {
|
||||
return run(e, start, destination, WALK_ANIMATION, animation, direction(start, destination), WALKING_SPEED, WALKING_SPEED, true);
|
||||
}
|
||||
|
|
@ -184,7 +201,9 @@ public class ForceMovement extends Pulse {
|
|||
* @param animation The animation.
|
||||
* @param speed The path speed.
|
||||
* @return The created ForceMovement object.
|
||||
* @deprecated this is no longer the preferred way to use force movement. Use the ContentAPI forceMove method instead, please.
|
||||
*/
|
||||
@Deprecated
|
||||
public static ForceMovement run(Entity e, Location start, Location destination, Animation animation, int speed) {
|
||||
return run(e, start, destination, WALK_ANIMATION, animation, direction(start, destination), WALKING_SPEED, speed, true);
|
||||
}
|
||||
|
|
@ -196,7 +215,9 @@ public class ForceMovement extends Pulse {
|
|||
* @param destination The destination location.
|
||||
* @param animation The animation.
|
||||
* @return The created ForceMovement object.
|
||||
* @deprecated this is no longer the preferred way to use force movement. Use the ContentAPI forceMove method instead, please.
|
||||
*/
|
||||
@Deprecated
|
||||
public static ForceMovement run(Entity e, Location start, Location destination, Animation startAnim, Animation animation) {
|
||||
return run(e, start, destination, startAnim, animation, direction(start, destination), WALKING_SPEED, WALKING_SPEED, true);
|
||||
}
|
||||
|
|
@ -209,7 +230,9 @@ public class ForceMovement extends Pulse {
|
|||
* @param animation The animation.
|
||||
* @param direction The direction.
|
||||
* @return The created ForceMovement object.
|
||||
* @deprecated this is no longer the preferred way to use force movement. Use the ContentAPI forceMove method instead, please.
|
||||
*/
|
||||
@Deprecated
|
||||
public static ForceMovement run(Entity e, Location start, Location destination, Animation startAnim, Animation animation, Direction direction) {
|
||||
return run(e, start, destination, startAnim, animation, direction, WALKING_SPEED, WALKING_SPEED, true);
|
||||
}
|
||||
|
|
@ -223,11 +246,17 @@ public class ForceMovement extends Pulse {
|
|||
* @param direction The direction.
|
||||
* @param pathSpeed The speed (in ticks).
|
||||
* @return The created ForceMovement object.
|
||||
* @deprecated this is no longer the preferred way to use force movement. Use the ContentAPI forceMove method instead, please.
|
||||
*/
|
||||
@Deprecated
|
||||
public static ForceMovement run(Entity e, Location start, Location destination, Animation startAnim, Animation animation, Direction direction, int pathSpeed) {
|
||||
return run(e, start, destination, startAnim, animation, direction, WALKING_SPEED, pathSpeed, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated this is no longer the preferred way to use force movement. Use the ContentAPI forceMove method instead, please.
|
||||
*/
|
||||
@Deprecated
|
||||
public static ForceMovement run(Entity e, Location start, Location destination, Animation startAnim, Animation animation, Direction direction, int commenceSpeed, int pathSpeed) {
|
||||
return run(e, start, destination, startAnim, animation, direction, commenceSpeed, pathSpeed, true);
|
||||
}
|
||||
|
|
@ -240,7 +269,9 @@ public class ForceMovement extends Pulse {
|
|||
* @param animation The animation.
|
||||
* @param direction The direction.
|
||||
* @return The created ForceMovement object.
|
||||
* @deprecated this is no longer the preferred way to use force movement. Use the ContentAPI forceMove method instead, please.
|
||||
*/
|
||||
@Deprecated
|
||||
public static ForceMovement run(Entity e, Location start, Location destination, Animation startAnim, Animation animation, Direction direction, int commenceSpeed, int pathSpeed, boolean unlockAfter) {
|
||||
if (startAnim != null) {
|
||||
startAnim.setPriority(Animator.Priority.VERY_HIGH);
|
||||
|
|
@ -254,7 +285,10 @@ public class ForceMovement extends Pulse {
|
|||
GameWorld.getPulser().submit(fm);
|
||||
return fm;
|
||||
}
|
||||
|
||||
/*
|
||||
* @deprecated this is no longer the preferred way to use force movement. Use the ContentAPI forceMove method instead, please.
|
||||
*/
|
||||
@Deprecated
|
||||
public static ForceMovement run(Entity e, Location destination, int commenceSpeed, int pathSpeed){
|
||||
return run(e,e.getLocation(),destination,WALK_ANIMATION,WALK_ANIMATION,direction(e.getLocation(),destination),commenceSpeed,pathSpeed, true);
|
||||
}
|
||||
|
|
@ -262,7 +296,9 @@ public class ForceMovement extends Pulse {
|
|||
/**
|
||||
* Method used to run the force movement.
|
||||
* @param e the entity.
|
||||
* @deprecated this is no longer the preferred way to use force movement. Use the ContentAPI forceMove method instead, please.
|
||||
*/
|
||||
@Deprecated
|
||||
public void run(final Entity e, final int speed) {
|
||||
this.entity = e;
|
||||
int commence = (int) start.getDistance(e.getLocation());
|
||||
|
|
@ -321,7 +357,7 @@ public class ForceMovement extends Pulse {
|
|||
}
|
||||
int ticks = 1 + commenceSpeed + pathSpeed;
|
||||
entity.getImpactHandler().setDisabledTicks(ticks);
|
||||
entity.getUpdateMasks().register(new ForceMovementFlag(this));
|
||||
entity.getUpdateMasks().register(EntityFlag.ForceMove, new ForceMoveCtx(start, destination, commenceSpeed * 30, pathSpeed * 30, direction));
|
||||
if(entity instanceof Player) {
|
||||
entity.getWalkingQueue().updateRegion(destination, false);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,10 +26,7 @@ import core.game.world.map.build.DynamicRegion;
|
|||
import core.game.world.map.path.Pathfinder;
|
||||
import core.game.world.update.flag.context.Animation;
|
||||
import core.game.world.update.flag.context.Graphics;
|
||||
import core.game.world.update.flag.npc.NPCFaceEntity;
|
||||
import core.game.world.update.flag.npc.NPCFaceLocation;
|
||||
import core.game.world.update.flag.npc.NPCForceChat;
|
||||
import core.game.world.update.flag.npc.NPCSwitchId;
|
||||
import core.game.world.update.flag.*;
|
||||
import core.tools.RandomFunction;
|
||||
import core.api.utils.GlobalKillCounter;
|
||||
import core.api.utils.Vector;
|
||||
|
|
@ -579,31 +576,6 @@ public class NPC extends Entity {
|
|||
super.reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean face(Entity entity) {
|
||||
if (entity == null) {
|
||||
if (getUpdateMasks().unregisterSynced(NPCFaceEntity.getOrdinal())) {
|
||||
return getUpdateMasks().register(new NPCFaceEntity(null));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return getUpdateMasks().register(new NPCFaceEntity(entity), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean faceLocation(Location location) {
|
||||
if (location == null) {
|
||||
getUpdateMasks().unregisterSynced(NPCFaceLocation.getOrdinal());
|
||||
return true;
|
||||
}
|
||||
return getUpdateMasks().register(new NPCFaceLocation(location), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean sendChat(String string) {
|
||||
return getUpdateMasks().register(new NPCForceChat(string));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CombatSwingHandler getSwingHandler(boolean swing) {
|
||||
CombatSwingHandler original = getProperties().getCombatPulse().getStyle().getSwingHandler();
|
||||
|
|
@ -703,9 +675,10 @@ public class NPC extends Entity {
|
|||
configure();
|
||||
interactPlugin.setDefault();
|
||||
if (id == originalId) {
|
||||
getUpdateMasks().unregisterSynced(NPCSwitchId.getOrdinal());
|
||||
int ordinal = EntityFlags.getOrdinal (EFlagType.NPC, EntityFlag.TypeSwap);
|
||||
getUpdateMasks().unregisterSynced(ordinal);
|
||||
}
|
||||
getUpdateMasks().register(new NPCSwitchId(id), id != originalId);
|
||||
getUpdateMasks().register(EntityFlag.TypeSwap, id, id != originalId);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -43,11 +43,7 @@ import core.game.world.map.build.DynamicRegion;
|
|||
import core.game.world.map.path.Pathfinder;
|
||||
import core.game.world.map.zone.ZoneType;
|
||||
import core.game.world.update.flag.PlayerFlags;
|
||||
import core.game.world.update.flag.context.Animation;
|
||||
import core.game.world.update.flag.context.Graphics;
|
||||
import core.game.world.update.flag.player.FaceEntityFlag;
|
||||
import core.game.world.update.flag.player.FaceLocationFlag;
|
||||
import core.game.world.update.flag.player.ForceChatFlag;
|
||||
import core.game.world.update.flag.*;
|
||||
import core.net.IoSession;
|
||||
import core.net.packet.PacketRepository;
|
||||
import core.net.packet.context.DynamicSceneContext;
|
||||
|
|
@ -81,6 +77,7 @@ import core.game.ge.GrandExchangeRecords;
|
|||
import core.game.ge.GrandExchangeOffer;
|
||||
import core.cache.def.impl.ItemDefinition;
|
||||
import core.worker.ManagementEvents;
|
||||
import core.game.world.update.flag.context.*;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
|
@ -549,31 +546,6 @@ public class Player extends Entity {
|
|||
Arrays.fill(opCounts, (byte) 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean face(Entity entity) {
|
||||
if (entity == null) {
|
||||
if (getUpdateMasks().unregisterSynced(FaceEntityFlag.getOrdinal())) {
|
||||
return getUpdateMasks().register(new FaceEntityFlag(entity));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return getUpdateMasks().register(new FaceEntityFlag(entity), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean faceLocation(Location location) {
|
||||
if (location == null) {
|
||||
getUpdateMasks().unregisterSynced(FaceLocationFlag.getOrdinal());
|
||||
return true;
|
||||
}
|
||||
return getUpdateMasks().register(new FaceLocationFlag(location), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean sendChat(String string) {
|
||||
return getUpdateMasks().register(new ForceChatFlag(string));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getClientIndex() {
|
||||
return this.getIndex() | 0x8000;
|
||||
|
|
@ -1393,4 +1365,8 @@ public class Player extends Entity {
|
|||
}
|
||||
states.remove(key);
|
||||
}
|
||||
|
||||
public void updateAppearance() {
|
||||
getUpdateMasks().register(EntityFlag.Appearance, this);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import core.game.node.entity.player.Player;
|
|||
import core.game.node.entity.player.link.emote.Emotes;
|
||||
import core.game.node.item.Item;
|
||||
import core.game.world.map.RegionManager;
|
||||
import core.game.world.update.flag.player.AppearanceFlag;
|
||||
import core.net.packet.PacketRepository;
|
||||
import core.net.packet.context.InterfaceContext;
|
||||
import core.net.packet.out.Interface;
|
||||
|
|
@ -136,7 +135,7 @@ public final class LoginConfiguration {
|
|||
UpdateSequence.getRenderablePlayers().add(player);
|
||||
RegionManager.move(player);
|
||||
player.getMusicPlayer().init();
|
||||
player.getUpdateMasks().register(new AppearanceFlag(player));
|
||||
player.updateAppearance();
|
||||
player.getPlayerFlags().setUpdateSceneGraph(true);
|
||||
player.getStateManager().init();
|
||||
player.getPacketDispatch().sendInterfaceConfig(226, 1, true);
|
||||
|
|
@ -303,4 +302,4 @@ public final class LoginConfiguration {
|
|||
return LOGIN_PLUGINS;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,8 +12,7 @@ import core.game.world.map.RegionManager;
|
|||
import core.game.world.update.flag.chunk.AnimateObjectUpdateFlag;
|
||||
import core.game.world.update.flag.context.Animation;
|
||||
import core.game.world.update.flag.context.Graphics;
|
||||
import core.game.world.update.flag.player.AnimationFlag;
|
||||
import core.game.world.update.flag.player.GraphicFlag;
|
||||
import core.game.world.update.flag.EntityFlag;
|
||||
import core.net.packet.PacketRepository;
|
||||
import core.net.packet.context.*;
|
||||
import core.net.packet.context.DisplayModelContext.ModelType;
|
||||
|
|
@ -300,7 +299,7 @@ public final class PacketDispatch {
|
|||
* @param id The animation id.
|
||||
*/
|
||||
public void sendAnimation(int id) {
|
||||
player.getUpdateMasks().register(new AnimationFlag(new Animation(id)));
|
||||
player.getUpdateMasks().register(EntityFlag.Animate, new Animation(id));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -309,7 +308,7 @@ public final class PacketDispatch {
|
|||
* @param delay The animation delay.
|
||||
*/
|
||||
public void sendAnimation(int id, int delay) {
|
||||
player.getUpdateMasks().register(new AnimationFlag(new Animation(id, delay)));
|
||||
player.getUpdateMasks().register(EntityFlag.Animate, new Animation(id, delay));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -317,7 +316,7 @@ public final class PacketDispatch {
|
|||
* @param id The graphic id.
|
||||
*/
|
||||
public void sendGraphic(int id) {
|
||||
player.getUpdateMasks().register(new GraphicFlag(new Graphics(id)));
|
||||
player.getUpdateMasks().register(EntityFlag.SpotAnim, new Graphics(id));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -383,7 +382,7 @@ public final class PacketDispatch {
|
|||
* @param height The graphic height.
|
||||
*/
|
||||
public void sendGraphic(int id, int height) {
|
||||
player.getUpdateMasks().register(new GraphicFlag(new Graphics(id, height)));
|
||||
player.getUpdateMasks().register(EntityFlag.SpotAnim, new Graphics(id, height));
|
||||
}
|
||||
public void sendVarClient(int id, int value, boolean cs2) {
|
||||
PacketRepository.send(Config.class, new ConfigContext(player, id, value, cs2));
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ package core.game.node.entity.player.link;
|
|||
import core.game.node.entity.Entity;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.node.entity.state.EntityState;
|
||||
import core.game.world.update.flag.player.AppearanceFlag;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
|
@ -86,7 +85,7 @@ public final class SkullManager {
|
|||
*/
|
||||
public void setSkullIcon(int skullIcon) {
|
||||
player.getAppearance().setSkullIcon(skullIcon);
|
||||
player.getUpdateMasks().register(new AppearanceFlag(player));
|
||||
player.updateAppearance();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import core.game.node.entity.impl.Animator.Priority;
|
|||
import core.game.node.entity.player.Player;
|
||||
import core.game.node.item.Item;
|
||||
import core.game.world.update.flag.context.Animation;
|
||||
import core.game.world.update.flag.player.AppearanceFlag;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
import core.game.system.config.ItemConfigParser;
|
||||
|
|
@ -190,7 +189,7 @@ public final class Appearance {
|
|||
* Method used to sync this appearance with the client.
|
||||
*/
|
||||
public void sync() {
|
||||
player.getUpdateMasks().register(new AppearanceFlag(player));
|
||||
player.updateAppearance();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import core.game.node.entity.npc.NPC;
|
|||
import core.game.node.entity.player.Player;
|
||||
import core.game.node.entity.player.link.request.assist.AssistSession;
|
||||
import core.game.node.item.Item;
|
||||
import core.game.world.update.flag.player.AppearanceFlag;
|
||||
import core.net.packet.PacketRepository;
|
||||
import core.net.packet.context.SkillContext;
|
||||
import core.net.packet.out.SkillLevel;
|
||||
|
|
@ -279,10 +278,8 @@ public final class Skills {
|
|||
staticLevels[slot] = newLevel;
|
||||
|
||||
if (entity instanceof Player) {
|
||||
if (updateCombatLevel()) {
|
||||
player.getUpdateMasks().register(new AppearanceFlag(player));
|
||||
}
|
||||
LevelUp.levelup(player, slot, amount);
|
||||
player.updateAppearance();
|
||||
LevelUp.levelup(player, slot, amount);
|
||||
}
|
||||
}
|
||||
if (entity instanceof Player) {
|
||||
|
|
|
|||
|
|
@ -27,6 +27,10 @@ import java.io.FileWriter
|
|||
import java.util.Arrays
|
||||
import core.net.packet.PacketWriteQueue
|
||||
import core.tools.Log
|
||||
import core.game.world.update.flag.*
|
||||
import core.game.world.update.flag.context.*
|
||||
import core.game.node.entity.impl.*
|
||||
import core.game.world.map.Location
|
||||
|
||||
@Initializable
|
||||
class DevelopmentCommandSet : CommandSet(Privilege.ADMIN) {
|
||||
|
|
@ -239,5 +243,34 @@ class DevelopmentCommandSet : CommandSet(Privilege.ADMIN) {
|
|||
define("drawroute", Privilege.ADMIN, "", "Visualizes the path your player is taking") {player, _ ->
|
||||
setAttribute (player, "routedraw", !getAttribute(player, "routedraw", false))
|
||||
}
|
||||
|
||||
define ("fmstart", Privilege.ADMIN, "", "") {player, _ ->
|
||||
setAttribute(player, "fmstart", Location.create(player.location))
|
||||
}
|
||||
|
||||
define ("fmend", Privilege.ADMIN, "", "") {player, _ ->
|
||||
setAttribute(player, "fmend", Location.create(player.location))
|
||||
}
|
||||
|
||||
define ("fmspeed", Privilege.ADMIN, "", "") {player, args ->
|
||||
setAttribute(player, "fmspeed", args[1].toIntOrNull() ?: 10)
|
||||
}
|
||||
|
||||
define ("fmspeedend", Privilege.ADMIN, "", "") {player, args ->
|
||||
setAttribute(player, "fmspeedend", args[1].toIntOrNull() ?: 10)
|
||||
}
|
||||
|
||||
define("testfm", Privilege.ADMIN, "", "") { player, _ ->
|
||||
val start = getAttribute(player, "fmstart", Location.create(player.location))
|
||||
val end = getAttribute(player, "fmend", Location.create(player.location))
|
||||
val speed = getAttribute(player, "fmspeed", 10)
|
||||
val speedEnd = getAttribute(player, "fmspeedend", 10)
|
||||
val ani = getAttribute(player, "fmanim", -1)
|
||||
forceMove(player, start, end, speed, speedEnd, anim = ani)
|
||||
}
|
||||
|
||||
define("fmanim", Privilege.ADMIN, "", "") {player, args ->
|
||||
setAttribute(player, "fmanim", args[1].toIntOrNull() ?: -1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,82 +5,42 @@ import core.game.node.entity.combat.ImpactHandler
|
|||
import core.game.node.entity.player.Player
|
||||
import core.game.world.update.flag.UpdateFlag
|
||||
import core.game.world.update.flag.context.HitMark
|
||||
import core.game.world.update.flag.npc.NPCHitFlag
|
||||
import core.game.world.update.flag.npc.NPCHitFlag1
|
||||
import core.game.world.update.flag.player.AppearanceFlag
|
||||
import core.game.world.update.flag.player.HitUpdateFlag
|
||||
import core.game.world.update.flag.player.HitUpdateFlag1
|
||||
import core.game.world.update.flag.*
|
||||
import core.net.packet.IoBuffer
|
||||
import core.api.*
|
||||
import core.tools.*
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
|
||||
/**
|
||||
* Holds an entity's update masks.
|
||||
* @author Emperor
|
||||
*/
|
||||
class UpdateMasks {
|
||||
/**
|
||||
* The mask data.
|
||||
*/
|
||||
private var maskData = 0
|
||||
|
||||
/**
|
||||
* The update masks array.
|
||||
*/
|
||||
private val masks = arrayOfNulls<UpdateFlag<*>?>(SIZE)
|
||||
|
||||
/**
|
||||
* Gets the appearanceStamp.
|
||||
* @return The appearanceStamp.
|
||||
*/
|
||||
/**
|
||||
* Sets the appearanceStamp.
|
||||
* @param appearanceStamp The appearanceStamp to set.
|
||||
*/
|
||||
/**
|
||||
* The appearance time stamp.
|
||||
*/
|
||||
class UpdateMasks (val owner: Entity) {
|
||||
var appearanceStamp: Long = 0
|
||||
|
||||
/**
|
||||
* The synced mask data.
|
||||
*/
|
||||
private var syncedMask = 0
|
||||
|
||||
/**
|
||||
* The update masks array.
|
||||
*/
|
||||
private val syncedMasks = arrayOfNulls<UpdateFlag<*>?>(SIZE)
|
||||
|
||||
/**
|
||||
* If the update masks are being updated.
|
||||
*/
|
||||
private val type = EFlagType.of (owner)
|
||||
private val updating = AtomicBoolean()
|
||||
/**
|
||||
* Registers an update flag.
|
||||
* @param flag The update flag.
|
||||
* @return `True` if successful.
|
||||
*/
|
||||
/**
|
||||
* Registers an update flag.
|
||||
* @param flag The update flag.
|
||||
* @return `True` if successful.
|
||||
*/
|
||||
private var presenceFlags = 0
|
||||
private var syncedPresenceFlags = 0
|
||||
private val elements = arrayOfNulls<MaskElement?>(SIZE)
|
||||
private val syncedElements = arrayOfNulls<MaskElement?>(SIZE)
|
||||
private data class MaskElement (val encoder: EFlagProvider, val context: Any?)
|
||||
|
||||
@JvmOverloads
|
||||
fun register(flag: UpdateFlag<*>, synced: Boolean = false): Boolean {
|
||||
var synced = synced
|
||||
if (updating.get()) {
|
||||
fun register(flag: EntityFlag, context: Any?, sync: Boolean = false) : Boolean {
|
||||
var synced = sync
|
||||
var provider = EntityFlags.getFlagFor (type, flag)
|
||||
if (provider == null) {
|
||||
logWithStack(this::class.java, Log.ERR, "Tried to use flag ${flag.name} which is not available for ${type.name} in this revision.")
|
||||
return false
|
||||
}
|
||||
if (flag is AppearanceFlag) {
|
||||
if (updating.get())
|
||||
return false
|
||||
if (flag == EntityFlag.Appearance) {
|
||||
appearanceStamp = System.currentTimeMillis()
|
||||
synced = true
|
||||
}
|
||||
if (synced) {
|
||||
syncedMasks[flag.ordinal()] = flag
|
||||
syncedMask = syncedMask or flag.data()
|
||||
syncedElements[provider.ordinal] = MaskElement (provider, context)
|
||||
syncedPresenceFlags = syncedPresenceFlags or provider.presenceFlag
|
||||
}
|
||||
maskData = maskData or flag.data()
|
||||
masks[flag.ordinal()] = flag
|
||||
elements[provider.ordinal] = MaskElement (provider, context)
|
||||
presenceFlags = presenceFlags or provider.presenceFlag
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
@ -90,9 +50,9 @@ class UpdateMasks {
|
|||
* @return `True` if the mask got removed.
|
||||
*/
|
||||
fun unregisterSynced(ordinal: Int): Boolean {
|
||||
if (syncedMasks[ordinal] != null) {
|
||||
syncedMask = syncedMask and syncedMasks[ordinal]!!.data().inv()
|
||||
syncedMasks[ordinal] = null
|
||||
if (syncedElements[ordinal] != null) {
|
||||
syncedPresenceFlags = syncedPresenceFlags and syncedElements[ordinal]!!.encoder.presenceFlag.inv()
|
||||
syncedElements[ordinal] = null
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
|
@ -105,16 +65,16 @@ class UpdateMasks {
|
|||
* @param buffer The buffer to write on.
|
||||
*/
|
||||
fun write(p: Player?, e: Entity?, buffer: IoBuffer) {
|
||||
var maskData = maskData
|
||||
var maskData = presenceFlags
|
||||
if (maskData >= 0x100) {
|
||||
maskData = maskData or if (e is Player) 0x10 else 0x8
|
||||
buffer.put(maskData).put(maskData shr 8)
|
||||
} else {
|
||||
buffer.put(maskData)
|
||||
}
|
||||
for (i in masks.indices) {
|
||||
val flag = masks[i]
|
||||
flag?.writeDynamic(buffer, p)
|
||||
for (i in elements.indices) {
|
||||
val element = elements[i]
|
||||
element?.encoder?.writeToDynamic(buffer, element.context, p!!)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -126,10 +86,11 @@ class UpdateMasks {
|
|||
* @param appearance If the appearance mask should be written.
|
||||
*/
|
||||
fun writeSynced(p: Player?, e: Entity?, buffer: IoBuffer, appearance: Boolean) {
|
||||
var maskData = maskData
|
||||
var synced = syncedMask
|
||||
if (!appearance && synced and AppearanceFlag.getData() != 0) {
|
||||
synced = synced and AppearanceFlag.getData().inv()
|
||||
var maskData = presenceFlags
|
||||
var synced = syncedPresenceFlags
|
||||
var appearanceFlag = EntityFlags.getPresenceFlag(type, EntityFlag.Appearance)
|
||||
if (!appearance && synced and appearanceFlag != 0) {
|
||||
synced = synced and appearanceFlag.inv()
|
||||
}
|
||||
maskData = maskData or synced
|
||||
if (maskData >= 0x100) {
|
||||
|
|
@ -138,15 +99,15 @@ class UpdateMasks {
|
|||
} else {
|
||||
buffer.put(maskData)
|
||||
}
|
||||
for (i in masks.indices) {
|
||||
var flag = masks[i]
|
||||
if (flag == null) {
|
||||
flag = syncedMasks[i]
|
||||
if (!appearance && flag is AppearanceFlag) {
|
||||
for (i in elements.indices) {
|
||||
var element = elements[i]
|
||||
if (element == null) {
|
||||
element = syncedElements[i]
|
||||
if (!appearance && element != null && element.encoder.flag == EntityFlag.Appearance) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
flag?.writeDynamic(buffer, p)
|
||||
element?.encoder?.writeToDynamic(buffer, element.context, p!!)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -173,13 +134,8 @@ class UpdateMasks {
|
|||
* @param secondary If the hit update is secondary.
|
||||
*/
|
||||
private fun registerHitUpdate(e: Entity, impact: ImpactHandler.Impact, secondary: Boolean): HitMark {
|
||||
val player = e is Player
|
||||
val mark = HitMark(impact.amount, impact.type.ordinal, e)
|
||||
if (player) {
|
||||
register(if (secondary) HitUpdateFlag1(mark) else HitUpdateFlag(mark))
|
||||
} else {
|
||||
register(if (secondary) NPCHitFlag1(mark) else NPCHitFlag(mark))
|
||||
}
|
||||
register(if (secondary) EntityFlag.SecondaryHit else EntityFlag.PrimaryHit, mark)
|
||||
return mark
|
||||
}
|
||||
|
||||
|
|
@ -187,10 +143,10 @@ class UpdateMasks {
|
|||
* Resets the update masks.
|
||||
*/
|
||||
fun reset() {
|
||||
for (i in masks.indices) {
|
||||
masks[i] = null
|
||||
for (i in elements.indices) {
|
||||
elements[i] = null
|
||||
}
|
||||
maskData = 0
|
||||
presenceFlags = 0
|
||||
updating.set(false)
|
||||
}
|
||||
|
||||
|
|
@ -203,14 +159,14 @@ class UpdateMasks {
|
|||
* @return `True` if so.
|
||||
*/
|
||||
val isUpdateRequired: Boolean
|
||||
get() = maskData != 0
|
||||
get() = presenceFlags != 0
|
||||
|
||||
/**
|
||||
* Checks if synced update masks have been registered.
|
||||
* @return `True` if so.
|
||||
*/
|
||||
fun hasSynced(): Boolean {
|
||||
return syncedMask != 0
|
||||
return syncedPresenceFlags != 0
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
@ -219,4 +175,4 @@ class UpdateMasks {
|
|||
*/
|
||||
const val SIZE = 11
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
29
Server/src/main/core/game/world/update/flag/EFlagProvider.kt
Normal file
29
Server/src/main/core/game/world/update/flag/EFlagProvider.kt
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
package core.game.world.update.flag
|
||||
|
||||
import core.net.packet.IoBuffer
|
||||
import core.game.node.entity.Entity
|
||||
import kotlin.reflect.*
|
||||
import core.api.*
|
||||
import core.tools.*
|
||||
|
||||
enum class EFlagType {
|
||||
Player,
|
||||
NPC;
|
||||
companion object {
|
||||
@JvmStatic fun of (e: Entity) : EFlagType {
|
||||
if (e is core.game.node.entity.player.Player) return EFlagType.Player
|
||||
else return EFlagType.NPC
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
open class EFlagProvider (val revision: Int, val type: EFlagType, val presenceFlag: Int, val ordinal: Int, val flag: EntityFlag) {
|
||||
open fun writeTo (buffer: IoBuffer, context: Any?) {}
|
||||
open fun writeToDynamic (buffer: IoBuffer, context: Any?, e: Entity) {
|
||||
writeTo (buffer, context)
|
||||
}
|
||||
|
||||
fun logInvalidType (context: Any?, expected: KType) {
|
||||
logWithStack(this::class.java, Log.ERR, "Invalid context of type ${context?.let { it::class.java.simpleName } ?: "null"} passed to ${this::class.simpleName} flag which expects $expected.")
|
||||
}
|
||||
}
|
||||
16
Server/src/main/core/game/world/update/flag/EntityFlag.kt
Normal file
16
Server/src/main/core/game/world/update/flag/EntityFlag.kt
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
package core.game.world.update.flag
|
||||
|
||||
enum class EntityFlag {
|
||||
Chat,
|
||||
ForceChat,
|
||||
PrimaryHit,
|
||||
SecondaryHit,
|
||||
Animate,
|
||||
SpotAnim,
|
||||
Appearance,
|
||||
FaceEntity,
|
||||
FaceLocation,
|
||||
ForceMove,
|
||||
AnimSeq,
|
||||
TypeSwap
|
||||
}
|
||||
42
Server/src/main/core/game/world/update/flag/EntityFlags.kt
Normal file
42
Server/src/main/core/game/world/update/flag/EntityFlags.kt
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
package core.game.world.update.flag
|
||||
|
||||
import core.api.*
|
||||
import core.ServerConstants
|
||||
import kotlin.reflect.*
|
||||
import kotlin.reflect.full.*
|
||||
|
||||
object EntityFlags {
|
||||
lateinit var flagProviders : HashMap<Int, EFlagProvider>
|
||||
|
||||
init {
|
||||
flagProviders = HashMap()
|
||||
registerFlagProviders (PlayerFlags530::class)
|
||||
registerFlagProviders (NPCFlags530::class)
|
||||
}
|
||||
|
||||
fun registerFlagProviders (parent: KClass<*>) {
|
||||
val clazzes = parent.sealedSubclasses
|
||||
for (clazz in clazzes) {
|
||||
val p = clazz.primaryConstructor?.call() as? EFlagProvider ?: continue
|
||||
flagProviders[getMapToken(p.revision, p.type, p.flag)] = p
|
||||
}
|
||||
}
|
||||
|
||||
fun getFlagFor (type: EFlagType, flag: EntityFlag) : EFlagProvider? {
|
||||
val revision = 530
|
||||
return flagProviders[getMapToken(revision, type, flag)]
|
||||
}
|
||||
|
||||
@JvmStatic fun getOrdinal (type: EFlagType, flag: EntityFlag) : Int {
|
||||
return getFlagFor(type, flag)?.ordinal ?: -1
|
||||
}
|
||||
|
||||
@JvmStatic fun getPresenceFlag (type: EFlagType, flag: EntityFlag) : Int {
|
||||
return getFlagFor(type, flag)?.presenceFlag ?: 0
|
||||
}
|
||||
|
||||
private fun getMapToken (revision: Int, type: EFlagType, flag: EntityFlag) : Int {
|
||||
var token = ((revision shl 8) + (type.ordinal shl 4) + flag.ordinal)
|
||||
return token
|
||||
}
|
||||
}
|
||||
108
Server/src/main/core/game/world/update/flag/NPCFlags530.kt
Normal file
108
Server/src/main/core/game/world/update/flag/NPCFlags530.kt
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
package core.game.world.update.flag
|
||||
|
||||
import core.net.packet.IoBuffer
|
||||
import core.game.world.update.flag.context.*
|
||||
import core.game.world.update.flag.*
|
||||
import core.game.world.map.Location
|
||||
import core.game.node.entity.Entity
|
||||
import core.game.node.entity.impl.ForceMovement
|
||||
import core.game.node.entity.player.Player
|
||||
import core.tools.*
|
||||
import core.api.*
|
||||
|
||||
import java.nio.charset.StandardCharsets
|
||||
import kotlin.reflect.*
|
||||
|
||||
sealed class NPCFlags530 (p: Int, o: Int, f: EntityFlag) : EFlagProvider (530, EFlagType.NPC, p, o, f) {
|
||||
class PrimaryHit : NPCFlags530 (0x40, 0, EntityFlag.PrimaryHit) {
|
||||
override fun writeTo (buffer: IoBuffer, context: Any?) {
|
||||
if (context !is HitMark) {
|
||||
logInvalidType (context, typeOf<HitMark>())
|
||||
return
|
||||
}
|
||||
buffer.p1 (context.damage)
|
||||
buffer.p1neg (context.type)
|
||||
|
||||
val e = context.entity
|
||||
var ratio = 255
|
||||
val max = e.skills.maximumLifepoints
|
||||
if (e.skills.lifepoints < max)
|
||||
ratio = e.skills.lifepoints * 255 / max
|
||||
buffer.p1sub (ratio)
|
||||
}
|
||||
}
|
||||
class SecondaryHit : NPCFlags530 (0x2, 1, EntityFlag.SecondaryHit) {
|
||||
override fun writeTo (buffer: IoBuffer, context: Any?) {
|
||||
if (context !is HitMark) {
|
||||
logInvalidType (context, typeOf<HitMark>())
|
||||
return
|
||||
}
|
||||
buffer.p1neg (context.damage)
|
||||
buffer.p1sub (context.type)
|
||||
}
|
||||
}
|
||||
class Animate : NPCFlags530 (0x10, 2, EntityFlag.Animate) {
|
||||
override fun writeTo (buffer: IoBuffer, context: Any?) {
|
||||
if (context !is Animation) {
|
||||
logInvalidType (context, typeOf<Animation>())
|
||||
return
|
||||
}
|
||||
buffer.p2 (context.id)
|
||||
buffer.p1 (context.delay)
|
||||
}
|
||||
}
|
||||
class FaceEntity : NPCFlags530 (0x4, 3, EntityFlag.FaceEntity) {
|
||||
override fun writeTo (buffer: IoBuffer, context: Any?) {
|
||||
if (context !is Entity?) {
|
||||
logInvalidType (context, typeOf<Entity>())
|
||||
return
|
||||
}
|
||||
if (context == null) {
|
||||
buffer.p2add (-1)
|
||||
} else {
|
||||
buffer.p2add (context.getClientIndex())
|
||||
}
|
||||
}
|
||||
}
|
||||
class SpotAnim : NPCFlags530 (0x80, 4, EntityFlag.SpotAnim) {
|
||||
override fun writeTo (buffer: IoBuffer, context: Any?) {
|
||||
if (context !is Graphics) {
|
||||
logInvalidType (context, typeOf<Graphics>())
|
||||
return
|
||||
}
|
||||
buffer.p2add (context.id)
|
||||
buffer.ip4 ((context.height shl 16) + context.delay)
|
||||
}
|
||||
}
|
||||
class TypeSwap : NPCFlags530 (0x1, 5, EntityFlag.TypeSwap) {
|
||||
override fun writeTo (buffer: IoBuffer, context: Any?) {
|
||||
if (context !is Int) {
|
||||
logInvalidType (context, typeOf<Graphics>())
|
||||
return
|
||||
}
|
||||
buffer.ip2 (context)
|
||||
}
|
||||
}
|
||||
class ForceChat : NPCFlags530 (0x20, 6, EntityFlag.ForceChat) {
|
||||
override fun writeTo (buffer: IoBuffer, context: Any?) {
|
||||
if (context !is String) {
|
||||
logInvalidType (context, typeOf<String>())
|
||||
return
|
||||
}
|
||||
buffer.putString (context)
|
||||
}
|
||||
}
|
||||
class AnimationSequence : NPCFlags530 (0x100, 7, EntityFlag.AnimSeq) {
|
||||
//TODO
|
||||
}
|
||||
class FaceLocation : NPCFlags530 (0x200, 8, EntityFlag.FaceLocation) {
|
||||
override fun writeTo (buffer: IoBuffer, context: Any?) {
|
||||
if (context !is Location) {
|
||||
logInvalidType (context, typeOf<Location>())
|
||||
return
|
||||
}
|
||||
buffer.p2add ((context.x shl 1) + 1)
|
||||
buffer.p2 ((context.y shl 1) + 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
195
Server/src/main/core/game/world/update/flag/PlayerFlags530.kt
Normal file
195
Server/src/main/core/game/world/update/flag/PlayerFlags530.kt
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
package core.game.world.update.flag
|
||||
|
||||
import core.net.packet.IoBuffer
|
||||
import core.game.world.update.flag.context.*
|
||||
import core.game.world.update.flag.*
|
||||
import core.game.world.map.Location
|
||||
import core.game.node.entity.Entity
|
||||
import core.game.node.entity.impl.ForceMovement
|
||||
import core.game.node.entity.player.Player
|
||||
import core.tools.*
|
||||
import core.api.*
|
||||
|
||||
import java.nio.charset.StandardCharsets
|
||||
import kotlin.reflect.*
|
||||
|
||||
sealed class PlayerFlags530 (p: Int, o: Int, f: EntityFlag) : EFlagProvider (530, EFlagType.Player, p, o, f) {
|
||||
class Chat : PlayerFlags530 (0x80, 0, EntityFlag.Chat) {
|
||||
override fun writeTo (buffer: IoBuffer, context: Any?) {
|
||||
if (context !is ChatMessage) {
|
||||
logInvalidType (context, typeOf<ChatMessage>())
|
||||
return
|
||||
}
|
||||
buffer.ip2 (context.effects)
|
||||
if (context.isQuickChat)
|
||||
buffer.p1 (4)
|
||||
else
|
||||
buffer.p1 (context.chatIcon)
|
||||
val chatBuf = ByteArray(256)
|
||||
chatBuf[0] = context.text.length.toByte()
|
||||
val offset = 1 + StringUtils.encryptPlayerChat (
|
||||
chatBuf,
|
||||
0, 1,
|
||||
context.text.length,
|
||||
context.text.toByteArray(StandardCharsets.UTF_8)
|
||||
)
|
||||
buffer.p1 (offset + 1)
|
||||
buffer.putReverse (chatBuf, 0, offset)
|
||||
}
|
||||
}
|
||||
class PrimaryHit : PlayerFlags530 (0x1, 1, EntityFlag.PrimaryHit) {
|
||||
override fun writeTo (buffer: IoBuffer, context: Any?) {
|
||||
if (context !is HitMark) {
|
||||
logInvalidType (context, typeOf<HitMark>())
|
||||
return
|
||||
}
|
||||
buffer.psmarts (context.damage)
|
||||
buffer.p1add (context.type)
|
||||
|
||||
var ratio = 255
|
||||
var e = context.entity
|
||||
var max = e.skills.maximumLifepoints
|
||||
if (max > e.skills.lifepoints)
|
||||
ratio = e.skills.lifepoints * 255 / max
|
||||
buffer.p1sub (ratio)
|
||||
}
|
||||
}
|
||||
class Animate : PlayerFlags530 (0x8, 2, EntityFlag.Animate) {
|
||||
override fun writeTo (buffer: IoBuffer, context: Any?) {
|
||||
if (context !is Animation) {
|
||||
logInvalidType (context, typeOf<Animation>())
|
||||
return
|
||||
}
|
||||
buffer.p2 (context.id)
|
||||
buffer.p1 (context.delay)
|
||||
}
|
||||
}
|
||||
class Appearance : PlayerFlags530 (0x4, 3, EntityFlag.Appearance) {
|
||||
override fun writeTo (buffer: IoBuffer, context: Any?) {
|
||||
if (context !is Player) {
|
||||
logInvalidType (context, typeOf<Player>())
|
||||
return
|
||||
}
|
||||
val appearance = context.appearance
|
||||
appearance.prepareBodyData(context)
|
||||
var settings = appearance.gender.toByte().toInt()
|
||||
val nonPvp = context.skullManager.isWilderness && context.skullManager.isWildernessDisabled
|
||||
if (context.size() > 1)
|
||||
settings += (context.size() - 1) shl 3
|
||||
if (nonPvp)
|
||||
settings += 0x4 //flag the player as being non-pvp, which shows skill level instead of combat level.
|
||||
|
||||
buffer.p1 (0) //stand-in for size.
|
||||
val startPos = buffer.toByteBuffer().position()
|
||||
|
||||
buffer.p1 (settings)
|
||||
buffer.p1 (appearance.skullIcon)
|
||||
buffer.p1 (appearance.headIcon)
|
||||
val npcId = appearance.npcId
|
||||
if (npcId == -1) {
|
||||
val parts = appearance.bodyParts
|
||||
for (i in 0 until 12) {
|
||||
if (parts[i] == 0) buffer.p1 (0)
|
||||
else buffer.p2 (parts[i])
|
||||
}
|
||||
} else {
|
||||
buffer.p2 (-1)
|
||||
buffer.p2 (npcId)
|
||||
buffer.p1 (255)
|
||||
}
|
||||
arrayOf ( appearance.hair, appearance.torso, appearance.legs, appearance.feet, appearance.skin ).forEach { part ->
|
||||
buffer.p1 (part.color)
|
||||
}
|
||||
buffer.p2 (appearance.renderAnimation)
|
||||
buffer.p8 (StringUtils.stringToLong(context.username))
|
||||
if (nonPvp) {
|
||||
buffer.p1 (context.properties.currentCombatLevel) //with summoning
|
||||
buffer.p2 (context.skills.getTotalLevel())
|
||||
} else {
|
||||
buffer.p1 (context.properties.currentCombatLevel) //without summoning
|
||||
buffer.p1 (context.properties.combatLevel) //with summoning
|
||||
buffer.p1 (context.skullManager.level) //combat range
|
||||
}
|
||||
buffer.p1 (0) //this is the sound radius, and if set, 4 shorts need to be set as well which include the sound IDs
|
||||
//to play to everyone in that radius when the player is rendered onscreen for the first time.
|
||||
buffer.psizeadd (buffer.toByteBuffer().position() - startPos)
|
||||
}
|
||||
}
|
||||
class FaceEntity : PlayerFlags530 (0x2, 4, EntityFlag.FaceEntity) {
|
||||
override fun writeTo (buffer: IoBuffer, context: Any?) {
|
||||
if (context !is Entity?) {
|
||||
logInvalidType (context, typeOf<Entity>())
|
||||
return
|
||||
}
|
||||
if (context == null)
|
||||
buffer.p2add (-1)
|
||||
else
|
||||
buffer.p2add (context.getClientIndex())
|
||||
}
|
||||
}
|
||||
class ForceMove : PlayerFlags530 (0x400, 5, EntityFlag.ForceMove) {
|
||||
override fun writeToDynamic (buffer: IoBuffer, context: Any?, e: Entity) {
|
||||
if (context !is ForceMoveCtx) {
|
||||
logInvalidType (context, typeOf<ForceMoveCtx>())
|
||||
return
|
||||
}
|
||||
if (e !is Player) {
|
||||
logInvalidType (context, typeOf<Player>())
|
||||
return
|
||||
}
|
||||
val l = e.playerFlags.getLastSceneGraph()
|
||||
//start location
|
||||
buffer.p1neg (context.start.getSceneX(l))
|
||||
buffer.p1 (context.start.getSceneY(l))
|
||||
//end location
|
||||
buffer.p1add (context.dest.getSceneX(l))
|
||||
buffer.p1 (context.dest.getSceneY(l))
|
||||
//arrival times (in client cycles)
|
||||
buffer.ip2 (context.startArrive) //# of client cycles to start location
|
||||
buffer.ip2 (context.startArrive + context.destArrive) //# of client cycles to end location
|
||||
buffer.p1neg (context.direction.toInteger()) //direction of movement
|
||||
}
|
||||
}
|
||||
class ForceChat : PlayerFlags530 (0x20, 6, EntityFlag.ForceChat) {
|
||||
override fun writeTo (buffer: IoBuffer, context: Any?) {
|
||||
if (context !is String) {
|
||||
logInvalidType (context, typeOf<String>())
|
||||
return
|
||||
}
|
||||
buffer.putString(context)
|
||||
}
|
||||
}
|
||||
class SecondaryHit : PlayerFlags530 (0x200, 7, EntityFlag.SecondaryHit) {
|
||||
override fun writeTo (buffer: IoBuffer, context: Any?) {
|
||||
if (context !is HitMark) {
|
||||
logInvalidType (context, typeOf<HitMark>())
|
||||
return
|
||||
}
|
||||
buffer.psmarts (context.damage)
|
||||
buffer.p1sub (context.type)
|
||||
}
|
||||
}
|
||||
class AnimationSequence : PlayerFlags530 (0x800, 8, EntityFlag.AnimSeq) {
|
||||
//TODO
|
||||
}
|
||||
class SpotAnim : PlayerFlags530 (0x100, 9, EntityFlag.SpotAnim) {
|
||||
override fun writeTo (buffer: IoBuffer, context: Any?) {
|
||||
if (context !is Graphics) {
|
||||
logInvalidType (context, typeOf<Graphics>())
|
||||
return
|
||||
}
|
||||
buffer.ip2 (context.id)
|
||||
buffer.mp4 ((context.height shl 16) + context.delay)
|
||||
}
|
||||
}
|
||||
class FaceLocation : PlayerFlags530 (0x40, 10, EntityFlag.FaceLocation) {
|
||||
override fun writeTo (buffer: IoBuffer, context: Any?) {
|
||||
if (context !is Location) {
|
||||
logInvalidType (context, typeOf<Location>())
|
||||
return
|
||||
}
|
||||
buffer.p2 ((context.x shl 1) + 1)
|
||||
buffer.ip2add ((context.y shl 1) + 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
package core.game.world.update.flag.context
|
||||
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.entity.player.info.Rights
|
||||
|
||||
/**
|
||||
* Represents a chat message.
|
||||
|
|
@ -35,6 +36,8 @@ class ChatMessage
|
|||
var numChars = numChars
|
||||
private set
|
||||
|
||||
var chatIcon = Rights.getChatIcon(player)
|
||||
|
||||
@JvmField
|
||||
var isQuickChat = false
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
package core.game.world.update.flag.context
|
||||
|
||||
import core.game.world.map.*
|
||||
|
||||
data class ForceMoveCtx (val start: Location, val dest: Location, val startArrive: Int, val destArrive: Int, val direction: Direction)
|
||||
|
|
@ -27,6 +27,8 @@ public class HitMark {
|
|||
*/
|
||||
private final Entity entity;
|
||||
|
||||
public boolean showHealthBar = true;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code HitMark} {@code Object}.
|
||||
* @param damage The amount of damage.
|
||||
|
|
@ -39,6 +41,13 @@ public class HitMark {
|
|||
this.entity = entity;
|
||||
}
|
||||
|
||||
public HitMark(int damage, int type, Entity entity, boolean showHealthBar) {
|
||||
this.damage = damage;
|
||||
this.type = type;
|
||||
this.entity = entity;
|
||||
this.showHealthBar = showHealthBar;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the damage.
|
||||
* @return The damage.
|
||||
|
|
@ -77,4 +86,4 @@ public class HitMark {
|
|||
public void setLifepoints(int lifepoints) {
|
||||
this.lifepoints = lifepoints;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,45 +0,0 @@
|
|||
package core.game.world.update.flag.npc;
|
||||
|
||||
import core.game.world.update.flag.UpdateFlag;
|
||||
import core.game.world.update.flag.context.Animation;
|
||||
import core.net.packet.IoBuffer;
|
||||
|
||||
/**
|
||||
* The NPC animation update flag.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public final class NPCAnimation extends UpdateFlag<Animation> {
|
||||
|
||||
/**
|
||||
* Constructs a new {@code NPCAnimation} {@code Object}.
|
||||
* @param context The animation.
|
||||
*/
|
||||
public NPCAnimation(Animation context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(IoBuffer buffer) {
|
||||
buffer.putShort(context.getId()).put(context.getDelay());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int data() {
|
||||
return maskData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int ordinal() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the mask data.
|
||||
* @return The mask data.
|
||||
*/
|
||||
public static int maskData() {
|
||||
return 0x10;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
package core.game.world.update.flag.npc;
|
||||
|
||||
import core.game.node.entity.Entity;
|
||||
import core.game.world.update.flag.UpdateFlag;
|
||||
import core.net.packet.IoBuffer;
|
||||
|
||||
/**
|
||||
* The face entity update flag for NPCs.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public final class NPCFaceEntity extends UpdateFlag<Entity> {
|
||||
|
||||
/**
|
||||
* Constructs a new {@code NPCFaceEntity} {@code Object}.
|
||||
* @param context The context.
|
||||
*/
|
||||
public NPCFaceEntity(Entity context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(IoBuffer buffer) {
|
||||
buffer.putShortA(context == null ? -1 : context.getClientIndex());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int data() {
|
||||
return 0x4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int ordinal() {
|
||||
return getOrdinal();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the mask data.
|
||||
* @return The mask data.
|
||||
*/
|
||||
public static int getOrdinal() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
package core.game.world.update.flag.npc;
|
||||
|
||||
import core.game.world.map.Location;
|
||||
import core.game.world.update.flag.UpdateFlag;
|
||||
import core.net.packet.IoBuffer;
|
||||
|
||||
/**
|
||||
* The NPC face coordinates update flag.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public final class NPCFaceLocation extends UpdateFlag<Location> {
|
||||
|
||||
/**
|
||||
* Constructs a new {@code NPCFaceLocation} {@code Object}.
|
||||
* @param context The location to face.
|
||||
*/
|
||||
public NPCFaceLocation(Location context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(IoBuffer buffer) {
|
||||
buffer.putShortA((context.getX() << 1) + 1).putShort((context.getY() << 1) + 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int data() {
|
||||
return 0x200;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int ordinal() {
|
||||
return getOrdinal();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the mask ordinal.
|
||||
* @return The ordinal.
|
||||
*/
|
||||
public static int getOrdinal() {
|
||||
return 8;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
package core.game.world.update.flag.npc;
|
||||
|
||||
import core.game.world.update.flag.UpdateFlag;
|
||||
import core.net.packet.IoBuffer;
|
||||
|
||||
/**
|
||||
* The NPC force chat update flag.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public final class NPCForceChat extends UpdateFlag<String> {
|
||||
|
||||
/**
|
||||
* Constructs a new {@code NPCForceChat} {@code Object}.
|
||||
* @param context The chat message.
|
||||
*/
|
||||
public NPCForceChat(String context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(IoBuffer buffer) {
|
||||
buffer.putString(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int data() {
|
||||
return maskData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int ordinal() {
|
||||
return 6;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the mask data.
|
||||
* @return The mask data.
|
||||
*/
|
||||
public static int maskData() {
|
||||
return 0x20;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
package core.game.world.update.flag.npc;
|
||||
|
||||
import core.game.world.update.flag.UpdateFlag;
|
||||
import core.game.world.update.flag.context.Graphics;
|
||||
import core.net.packet.IoBuffer;
|
||||
|
||||
/**
|
||||
* Handles an NPC's graphic update flag.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public final class NPCGraphic extends UpdateFlag<Graphics> {
|
||||
|
||||
/**
|
||||
* Constructs a new {@code NPCGraphic} {@code Object}.
|
||||
* @param context The graphics.
|
||||
*/
|
||||
public NPCGraphic(Graphics context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(IoBuffer buffer) {
|
||||
buffer.putShortA(context.getId()).putLEInt(context.getHeight() << 16 | context.getDelay());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int data() {
|
||||
return maskData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int ordinal() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the mask data.
|
||||
* @return The mask data.
|
||||
*/
|
||||
public static int maskData() {
|
||||
return 0x80;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
package core.game.world.update.flag.npc;
|
||||
|
||||
import core.game.node.entity.Entity;
|
||||
import core.game.world.update.flag.UpdateFlag;
|
||||
import core.game.world.update.flag.context.HitMark;
|
||||
import core.net.packet.IoBuffer;
|
||||
|
||||
/**
|
||||
* The NPC's main hit update flag.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public final class NPCHitFlag extends UpdateFlag<HitMark> {
|
||||
|
||||
/**
|
||||
* Constructs a new {@code NPCHitFlag} {@code Object}.
|
||||
* @param context The hit mark.
|
||||
*/
|
||||
public NPCHitFlag(HitMark context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(IoBuffer buffer) {
|
||||
Entity e = context.getEntity();
|
||||
int max = e.getSkills().getMaximumLifepoints();
|
||||
int ratio = 0;
|
||||
if (max > 0) {
|
||||
if (max < e.getSkills().getLifepoints()) {
|
||||
ratio = 255;
|
||||
} else {
|
||||
ratio = e.getSkills().getLifepoints() * 255 / max;
|
||||
}
|
||||
}
|
||||
buffer.put(context.getDamage()).putC(context.getType()).putS(ratio);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int data() {
|
||||
return maskData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int ordinal() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the mask data.
|
||||
* @return The mask data.
|
||||
*/
|
||||
public static int maskData() {
|
||||
return 0x40;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
package core.game.world.update.flag.npc;
|
||||
|
||||
import core.game.world.update.flag.UpdateFlag;
|
||||
import core.game.world.update.flag.context.HitMark;
|
||||
import core.net.packet.IoBuffer;
|
||||
|
||||
/**
|
||||
* The NPC's supporting hit update flag.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public class NPCHitFlag1 extends UpdateFlag<HitMark> {
|
||||
|
||||
/**
|
||||
* Constructs a new {@code NPCHitFlag1} {@code Object}.
|
||||
* @param context The hit mark.
|
||||
*/
|
||||
public NPCHitFlag1(HitMark context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(IoBuffer buffer) {
|
||||
buffer.putC(context.getDamage()).putS(context.getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int data() {
|
||||
return maskData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int ordinal() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the mask data.
|
||||
* @return The mask data.
|
||||
*/
|
||||
public static int maskData() {
|
||||
return 0x2;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
package core.game.world.update.flag.npc;
|
||||
|
||||
import core.game.world.update.flag.UpdateFlag;
|
||||
import core.net.packet.IoBuffer;
|
||||
|
||||
/**
|
||||
* The switch NPC id update flag.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public final class NPCSwitchId extends UpdateFlag<Integer> {
|
||||
|
||||
/**
|
||||
* Constructs a new {@code NPCSwitchId} {@code Object}.
|
||||
* @param context The new NPC id.
|
||||
*/
|
||||
public NPCSwitchId(int context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(IoBuffer buffer) {
|
||||
buffer.putLEShort(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int data() {
|
||||
return 0x1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int ordinal() {
|
||||
return getOrdinal();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the mask ordinal.
|
||||
* @return The ordinal.
|
||||
*/
|
||||
public static int getOrdinal() {
|
||||
return 5;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
package core.game.world.update.flag.player;
|
||||
|
||||
import core.game.world.update.flag.UpdateFlag;
|
||||
import core.game.world.update.flag.context.Animation;
|
||||
import core.net.packet.IoBuffer;
|
||||
|
||||
/**
|
||||
* Handles the animation update flag.
|
||||
* @author Emperor
|
||||
*/
|
||||
public final class AnimationFlag extends UpdateFlag<Animation> {
|
||||
|
||||
/**
|
||||
* Constructs a new {@code AnimationFlag} {@code Object}.
|
||||
*/
|
||||
public AnimationFlag(Animation context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(IoBuffer buffer) {
|
||||
buffer.putShort(context.getId());
|
||||
buffer.put(context.getDelay());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int data() {
|
||||
return maskData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int ordinal() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the mask data of the animation update flag.
|
||||
* @return The mask data.
|
||||
*/
|
||||
public static int maskData() {
|
||||
return 0x8;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,91 +0,0 @@
|
|||
package core.game.world.update.flag.player;
|
||||
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.node.entity.player.link.appearance.Appearance;
|
||||
import core.game.node.entity.player.link.appearance.BodyPart;
|
||||
import core.game.world.update.flag.UpdateFlag;
|
||||
import core.net.packet.IoBuffer;
|
||||
import core.tools.StringUtils;
|
||||
|
||||
/**
|
||||
* Handles the appearance update flag.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public final class AppearanceFlag extends UpdateFlag<Player> {
|
||||
|
||||
/**
|
||||
* Constructs a new {@code AppearanceFlag} {@code Object}.
|
||||
* @param player The player.
|
||||
*/
|
||||
public AppearanceFlag(Player player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(IoBuffer buffer) {
|
||||
Appearance appearance = context.getAppearance();
|
||||
appearance.prepareBodyData(context);
|
||||
IoBuffer block = new IoBuffer();
|
||||
int settings = appearance.getGender().toByte();
|
||||
if (context.size() > 1) {
|
||||
settings |= (context.size() - 1) << 3;
|
||||
}
|
||||
block.put(settings); // settings hash.
|
||||
block.put(appearance.getSkullIcon()); // Skull icon
|
||||
block.put(appearance.getHeadIcon()); // Head icon
|
||||
int npcId = appearance.getNpcId();
|
||||
if (npcId == -1) {
|
||||
int[] parts = appearance.getBodyParts();
|
||||
for (int i = 0; i < 12; i++) {
|
||||
int value = parts[i];
|
||||
if (value == 0) {
|
||||
block.put(0);
|
||||
} else {
|
||||
block.putShort(value);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
block.putShort(-1);
|
||||
block.putShort(npcId);
|
||||
block.put(255);
|
||||
}
|
||||
final BodyPart[] colors = new BodyPart[] { appearance.getHair(), appearance.getTorso(), appearance.getLegs(), appearance.getFeet(), appearance.getSkin() };
|
||||
for (int i = 0; i < colors.length; i++) {// colours
|
||||
block.put(colors[i].getColor());
|
||||
}
|
||||
block.putShort(appearance.getRenderAnimation());
|
||||
block.putLong(StringUtils.stringToLong(context.getUsername()));
|
||||
block.put(context.getProperties().getCurrentCombatLevel());
|
||||
block.putShort(0);
|
||||
block.put(0);
|
||||
buffer.putA(block.toByteBuffer().position());
|
||||
buffer.put(block);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int data() {
|
||||
return getData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int ordinal() {
|
||||
return getOrdinal();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ordinal for this flag.
|
||||
* @return The flag ordinal.
|
||||
*/
|
||||
public static int getOrdinal() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the mask data.
|
||||
* @return The mask data.
|
||||
*/
|
||||
public static int getData() {
|
||||
return 0x4;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
package core.game.world.update.flag.player;
|
||||
|
||||
import core.game.node.entity.player.info.Rights;
|
||||
import core.game.world.update.flag.UpdateFlag;
|
||||
import core.game.world.update.flag.context.ChatMessage;
|
||||
import core.net.packet.IoBuffer;
|
||||
import core.tools.StringUtils;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* Handles the chat flag.
|
||||
* @author Emperor
|
||||
*/
|
||||
public class ChatFlag extends UpdateFlag<ChatMessage> {
|
||||
|
||||
/**
|
||||
* Constructs a new {@code ChatFlag.java} {@code Object}.
|
||||
* @param context The context.
|
||||
*/
|
||||
public ChatFlag(ChatMessage context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(IoBuffer buffer) {
|
||||
byte[] chatStr = new byte[256];
|
||||
chatStr[0] = (byte) context.getText().length();
|
||||
int offset = 1 + StringUtils.encryptPlayerChat(chatStr, 0, 1, context.getText().length(), context.getText().getBytes(StandardCharsets.UTF_8));
|
||||
buffer.putLEShort(context.getEffects()); // 0x8000 does something (you'd
|
||||
// need to send something
|
||||
// extra.
|
||||
if(context.isQuickChat){
|
||||
buffer.put((byte) 4);
|
||||
} else {
|
||||
buffer.put((byte) Rights.getChatIcon(context.getPlayer()));
|
||||
}
|
||||
buffer.put(offset + 1);
|
||||
buffer.putReverse(chatStr, 0, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int data() {
|
||||
return maskData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int ordinal() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the mask data of the chat update flag.
|
||||
* @return The mask data.
|
||||
*/
|
||||
public static int maskData() {
|
||||
return 0x80;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
package core.game.world.update.flag.player;
|
||||
|
||||
import core.game.node.entity.Entity;
|
||||
import core.game.world.update.flag.UpdateFlag;
|
||||
import core.net.packet.IoBuffer;
|
||||
|
||||
/**
|
||||
* The face entity update flag.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public final class FaceEntityFlag extends UpdateFlag<Entity> {
|
||||
|
||||
/**
|
||||
* Constructs a new {@code FaceEntityFlag} {@code Object}.
|
||||
* @param context The entity to face.
|
||||
*/
|
||||
public FaceEntityFlag(Entity context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(IoBuffer buffer) {
|
||||
buffer.putShortA(context == null ? -1 : context.getClientIndex());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int data() {
|
||||
return 0x2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int ordinal() {
|
||||
return getOrdinal();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the mask ordinal.
|
||||
* @return The ordinal.
|
||||
*/
|
||||
public static int getOrdinal() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
package core.game.world.update.flag.player;
|
||||
|
||||
import core.game.node.Node;
|
||||
import core.game.node.scenery.Scenery;
|
||||
import core.game.world.map.Location;
|
||||
import core.game.world.update.flag.UpdateFlag;
|
||||
import core.net.packet.IoBuffer;
|
||||
|
||||
/**
|
||||
* Handles the face coordinates update flag.
|
||||
* @author Emperor
|
||||
*/
|
||||
public class FaceLocationFlag extends UpdateFlag<Location> {
|
||||
|
||||
/**
|
||||
* Constructs a new {@code FaceLocationFlag} {@code Object}.
|
||||
* @param location The location to face.
|
||||
*/
|
||||
public FaceLocationFlag(Location location) {
|
||||
super(location);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the face location of the node.
|
||||
* @param n The facing node.
|
||||
* @param node The node to face.
|
||||
* @return The location.
|
||||
*/
|
||||
public static Location getFaceLocation(Node n, Node node) {
|
||||
int x = node.size() >> 1;
|
||||
int y = node.size() >> 1;
|
||||
if (node instanceof Scenery) {
|
||||
Scenery o = (Scenery) node;
|
||||
x = o.getDefinition().sizeX >> 1;
|
||||
y = o.getDefinition().sizeY >> 1;
|
||||
if (o.getRotation() % 2 != 0) {
|
||||
x = y;
|
||||
y = o.getDefinition().sizeX >> 1;
|
||||
}
|
||||
if (n.getLocation().equals(o.getLocation()) && node.size() == 1) {
|
||||
switch (o.getRotation()) {
|
||||
case 0:
|
||||
x -= 1;
|
||||
break;
|
||||
case 1:
|
||||
y += 1;
|
||||
break;
|
||||
case 2:
|
||||
x += 1;
|
||||
break;
|
||||
case 3:
|
||||
y -= 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return node.getLocation().transform(x, y, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(IoBuffer buffer) {
|
||||
buffer.putShort((context.getX() << 1) + 1);
|
||||
buffer.putLEShortA((context.getY() << 1) + 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int data() {
|
||||
return 0x40;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int ordinal() {
|
||||
return getOrdinal();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the mask ordinal.
|
||||
* @return The ordinal.
|
||||
*/
|
||||
public static int getOrdinal() {
|
||||
return 10;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
package core.game.world.update.flag.player;
|
||||
|
||||
import core.game.world.update.flag.UpdateFlag;
|
||||
import core.net.packet.IoBuffer;
|
||||
|
||||
/**
|
||||
* The force chat update flag.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public final class ForceChatFlag extends UpdateFlag<String> {
|
||||
|
||||
/**
|
||||
* Constructs a new {@code ForceChatFlag} {@code Object}.
|
||||
* @param context The chat message.
|
||||
*/
|
||||
public ForceChatFlag(String context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(IoBuffer buffer) {
|
||||
buffer.putString(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int data() {
|
||||
return maskData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int ordinal() {
|
||||
return 6;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the mask data.
|
||||
* @return The mask data.
|
||||
*/
|
||||
public static int maskData() {
|
||||
return 0x20;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
package core.game.world.update.flag.player;
|
||||
|
||||
import core.game.node.entity.Entity;
|
||||
import core.game.node.entity.impl.ForceMovement;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.world.map.Location;
|
||||
import core.game.world.update.flag.UpdateFlag;
|
||||
import core.net.packet.IoBuffer;
|
||||
|
||||
/**
|
||||
* Handles the force movement player update flag.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public final class ForceMovementFlag extends UpdateFlag<ForceMovement> {
|
||||
|
||||
/**
|
||||
* Constructs a new {@code ForceMovementFlag} {@code Object}.
|
||||
* @param forceMovement The force movement data.
|
||||
*/
|
||||
public ForceMovementFlag(ForceMovement forceMovement) {
|
||||
super(forceMovement);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(IoBuffer buffer) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeDynamic(IoBuffer buffer, Entity e) {
|
||||
Location l = ((Player) e).getPlayerFlags().getLastSceneGraph();
|
||||
buffer.putC(context.getStart().getSceneX(l)) // Start location
|
||||
.put(context.getStart().getSceneY(l)).putA(context.getDestination().getSceneX(l)) // Destination
|
||||
// location
|
||||
.put(context.getDestination().getSceneY(l)).putLEShort(context.getCommenceSpeed() * 30)// Commencing
|
||||
// speed
|
||||
.putLEShort((context.getCommenceSpeed() * 30) + (context.getPathSpeed() * 30 + 1)) // Path
|
||||
// speed
|
||||
.putC(context.getDirection().toInteger());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int data() {
|
||||
return maskData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int ordinal() {
|
||||
return 5;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the mask data.
|
||||
* @return The mask data.
|
||||
*/
|
||||
public static int maskData() {
|
||||
return 0x400;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
package core.game.world.update.flag.player;
|
||||
|
||||
import core.game.world.update.flag.UpdateFlag;
|
||||
import core.game.world.update.flag.context.Graphics;
|
||||
import core.net.packet.IoBuffer;
|
||||
|
||||
/**
|
||||
* Handles the graphic update flag.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public final class GraphicFlag extends UpdateFlag<Graphics> {
|
||||
|
||||
/**
|
||||
* Constructs a new {@code GraphicFlag} {@code Object}.
|
||||
* @param context The context.
|
||||
*/
|
||||
public GraphicFlag(Graphics context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(IoBuffer buffer) {
|
||||
buffer.putLEShort(context.getId());
|
||||
buffer.putIntB(context.getHeight() << 16 | context.getDelay());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int data() {
|
||||
return maskData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int ordinal() {
|
||||
return 9;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the mask data of the graphic update flag.
|
||||
* @return The mask data.
|
||||
*/
|
||||
public static int maskData() {
|
||||
return 0x100;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
package core.game.world.update.flag.player;
|
||||
|
||||
import core.game.node.entity.Entity;
|
||||
import core.game.world.update.flag.UpdateFlag;
|
||||
import core.game.world.update.flag.context.HitMark;
|
||||
import core.net.packet.IoBuffer;
|
||||
|
||||
/**
|
||||
* The main hit update flag.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public final class HitUpdateFlag extends UpdateFlag<HitMark> {
|
||||
|
||||
/**
|
||||
* Constructs a new {@code HitUpdateFlag} {@code Object}.
|
||||
* @param context The hit mark.
|
||||
*/
|
||||
public HitUpdateFlag(HitMark context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(IoBuffer buffer) {
|
||||
Entity e = context.getEntity();
|
||||
int max = e.getSkills().getMaximumLifepoints();
|
||||
int ratio = 255;
|
||||
if (max > e.getSkills().getLifepoints()) {
|
||||
ratio = e.getSkills().getLifepoints() * 255 / max;
|
||||
}
|
||||
buffer.putSmart(context.getDamage()).putA(context.getType()).putS(ratio);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int data() {
|
||||
return maskData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int ordinal() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the mask data.
|
||||
* @return The mask data.
|
||||
*/
|
||||
public static int maskData() {
|
||||
return 0x1;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
package core.game.world.update.flag.player;
|
||||
|
||||
import core.game.world.update.flag.UpdateFlag;
|
||||
import core.game.world.update.flag.context.HitMark;
|
||||
import core.net.packet.IoBuffer;
|
||||
|
||||
/**
|
||||
* The supportive hit update flag.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public final class HitUpdateFlag1 extends UpdateFlag<HitMark> {
|
||||
|
||||
/**
|
||||
* Constructs a new {@code HitUpdateFlag1} {@code Object}.
|
||||
* @param context The hit mark.
|
||||
*/
|
||||
public HitUpdateFlag1(HitMark context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(IoBuffer buffer) {
|
||||
buffer.putSmart(context.getDamage()).putS(context.getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int data() {
|
||||
return maskData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int ordinal() {
|
||||
return 7;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the mask data.
|
||||
* @return The mask data.
|
||||
*/
|
||||
public static int maskData() {
|
||||
return 0x200;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -92,6 +92,219 @@ public class IoBuffer {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* What follows are put/get methods using authentic naming.
|
||||
* The older methods are kept for the sake of backwards compatibility within the codebase.
|
||||
*/
|
||||
public IoBuffer p1 (int value) {
|
||||
buf.put((byte) value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public IoBuffer p1add (int value) {
|
||||
buf.put((byte) (value + 128));
|
||||
return this;
|
||||
}
|
||||
|
||||
public IoBuffer p1sub (int value) {
|
||||
buf.put((byte) (128 - value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public IoBuffer p1neg (int value) {
|
||||
buf.put ((byte) -value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public IoBuffer p2 (int value) {
|
||||
buf.put((byte) (value >> 8));
|
||||
buf.put((byte) value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public IoBuffer p2add (int value) {
|
||||
buf.put((byte) (value >> 8));
|
||||
buf.put((byte) (value + 128));
|
||||
return this;
|
||||
}
|
||||
|
||||
public IoBuffer ip2 (int value) {
|
||||
buf.put((byte) value);
|
||||
buf.put((byte) (value >> 8));
|
||||
return this;
|
||||
}
|
||||
|
||||
public IoBuffer ip2add (int value) {
|
||||
buf.put((byte) (value + 128));
|
||||
buf.put((byte) (value >> 8));
|
||||
return this;
|
||||
}
|
||||
|
||||
public IoBuffer p3 (int value) {
|
||||
buf.put((byte) (value >> 16));
|
||||
buf.put((byte) (value >> 8));
|
||||
buf.put((byte) value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public IoBuffer ip3 (int value) {
|
||||
buf.put((byte) value);
|
||||
buf.put((byte) (value >> 8));
|
||||
buf.put((byte) (value >> 16));
|
||||
return this;
|
||||
}
|
||||
|
||||
public IoBuffer p4 (int value) {
|
||||
buf.put((byte) (value >> 24));
|
||||
buf.put((byte) (value >> 16));
|
||||
buf.put((byte) (value >> 8));
|
||||
buf.put((byte) value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public IoBuffer ip4 (int value) {
|
||||
buf.put((byte) value);
|
||||
buf.put((byte) (value >> 8));
|
||||
buf.put((byte) (value >> 16));
|
||||
buf.put((byte) (value >> 24));
|
||||
return this;
|
||||
}
|
||||
|
||||
public IoBuffer mp4 (int value) {
|
||||
buf.put((byte) (value >> 16));
|
||||
buf.put((byte) (value >> 24));
|
||||
buf.put((byte) value);
|
||||
buf.put((byte) (value >> 8));
|
||||
return this;
|
||||
}
|
||||
|
||||
public IoBuffer imp4 (int value) {
|
||||
buf.put((byte) (value >> 8));
|
||||
buf.put((byte) value);
|
||||
buf.put((byte) (value >> 24));
|
||||
buf.put((byte) (value >> 16));
|
||||
return this;
|
||||
}
|
||||
|
||||
public IoBuffer p8 (long value) {
|
||||
buf.put((byte) (value >> 56));
|
||||
buf.put((byte) (value >> 48));
|
||||
buf.put((byte) (value >> 40));
|
||||
buf.put((byte) (value >> 32));
|
||||
buf.put((byte) (value >> 24));
|
||||
buf.put((byte) (value >> 16));
|
||||
buf.put((byte) (value >> 8));
|
||||
buf.put((byte) value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public IoBuffer pVarInt (int value) {
|
||||
if ((value & 0xffffff80) != 0) {
|
||||
if ((value & 0xffffc000) != 0) {
|
||||
if ((value & 0xFFE00000) != 0) {
|
||||
if ((value & 0xF0000000) != 0) {
|
||||
this.p1(value >>> 28 | 0x80);
|
||||
}
|
||||
this.p1(value >>> 21 | 0x80);
|
||||
}
|
||||
this.p1(value >>> 14 | 0x80);
|
||||
}
|
||||
this.p1(value >>> 7 | 0x80);
|
||||
}
|
||||
return this.p1(value & 0x7F);
|
||||
}
|
||||
|
||||
public IoBuffer pVarLong (int size, long value) {
|
||||
int bytes = size - 1;
|
||||
if (bytes < 0 || bytes > 7)
|
||||
throw new IllegalArgumentException();
|
||||
for (int shift = bytes * 8; shift >= 0; shift -= 8)
|
||||
this.p1 ((byte) (value >> shift));
|
||||
return this;
|
||||
}
|
||||
|
||||
public IoBuffer psmarts (int value) {
|
||||
if (value >= 0 && value < 128)
|
||||
this.p1(value);
|
||||
else if (value >= 0 && value < 0x8000)
|
||||
this.p2(value + 0x8000);
|
||||
else
|
||||
throw new IllegalArgumentException("smart out of range: $value");
|
||||
return this;
|
||||
}
|
||||
|
||||
public IoBuffer psize (int length) {
|
||||
buf.put (buf.position() - length - 1, (byte) length);
|
||||
return this;
|
||||
}
|
||||
|
||||
public IoBuffer psizeadd (int length) {
|
||||
buf.put (buf.position() - length - 1, (byte) (length + 128));
|
||||
return this;
|
||||
}
|
||||
|
||||
public int g1() {
|
||||
return buf.get() & 0xFF;
|
||||
}
|
||||
|
||||
public int g1add() {
|
||||
return (buf.get() - 128) & 0xFF;
|
||||
}
|
||||
|
||||
public int g1neg() {
|
||||
return -(buf.get() & 0xFF);
|
||||
}
|
||||
|
||||
public int g1sub() {
|
||||
return (128 - buf.get()) & 0xFF;
|
||||
}
|
||||
|
||||
public int g2() {
|
||||
return ((buf.get() & 0xFF) << 8) + (buf.get() & 0xFF);
|
||||
}
|
||||
|
||||
public int g2add() {
|
||||
return ((buf.get() & 0xff) << 8) + ((buf.get() - 128) & 0xFF);
|
||||
}
|
||||
|
||||
public int ig2() {
|
||||
return (buf.get() & 0xFF) + ((buf.get() & 0xFF) << 8);
|
||||
}
|
||||
|
||||
public int ig2add() {
|
||||
return ((buf.get() - 128) & 0xFF) + ((buf.get() & 0xFF) << 8);
|
||||
}
|
||||
|
||||
public int g3() {
|
||||
return ((buf.get() & 0xFF) << 16) + ((buf.get() & 0xFF) << 8) + (buf.get() & 0xFF);
|
||||
}
|
||||
|
||||
public int ig3() {
|
||||
return (buf.get() & 0xFF) + ((buf.get() & 0xFF) << 8) + ((buf.get() & 0xFF) << 16);
|
||||
}
|
||||
|
||||
public int g4() {
|
||||
return ((buf.get() & 0xFF) << 24) + ((buf.get() & 0xFF) << 16) + ((buf.get() & 0xFF) << 8) + (buf.get() & 0xFF);
|
||||
}
|
||||
|
||||
public int ig4() {
|
||||
return (buf.get() & 0xFF) + ((buf.get() & 0xFF) << 8) + ((buf.get() & 0xFF) << 16) + ((buf.get() & 0xFF) << 24);
|
||||
}
|
||||
|
||||
public int m4() {
|
||||
return ((buf.get() & 0xFF) << 16) + ((buf.get() & 0xFF) << 24) + (buf.get() & 0xFF) + ((buf.get() & 0xFF) << 8);
|
||||
}
|
||||
|
||||
public int im4() {
|
||||
return ((buf.get() & 0xFF) << 8) + (buf.get() & 0xFF) + ((buf.get() & 0xFF) << 24) + ((buf.get() & 0xFF) << 16);
|
||||
}
|
||||
|
||||
public long g8() {
|
||||
long low = (long) this.g4() & 0xFFFFFFFFL;
|
||||
long high = (long) this.g4() & 0xFFFFFFFFL;
|
||||
return high + (low << 32);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param val
|
||||
* @return
|
||||
|
|
@ -635,4 +848,4 @@ public class IoBuffer {
|
|||
return bitPosition;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ import core.game.system.task.Pulse
|
|||
import core.game.world.map.Location
|
||||
import core.game.world.map.RegionManager
|
||||
import core.game.world.update.flag.context.ChatMessage
|
||||
import core.game.world.update.flag.player.ChatFlag
|
||||
import core.game.world.update.flag.*
|
||||
import core.net.amsc.MSPacketRepository
|
||||
import core.net.packet.context.PlayerContext
|
||||
import core.net.packet.out.ClearMinimapFlag
|
||||
|
|
@ -229,7 +229,7 @@ object PacketProcessor {
|
|||
}
|
||||
PlayerMonitor.logChat(pkt.player, "public", pkt.message)
|
||||
val ctx = ChatMessage(pkt.player, pkt.message, pkt.effects, pkt.message.length)
|
||||
pkt.player.updateMasks.register(ChatFlag(ctx))
|
||||
pkt.player.updateMasks.register(EntityFlag.Chat, ctx)
|
||||
}
|
||||
}
|
||||
is Packet.ChatSetting -> {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import core.game.node.entity.player.Player
|
|||
import core.game.node.entity.skill.Skills
|
||||
import core.game.system.task.Pulse
|
||||
import core.game.world.update.flag.context.ChatMessage
|
||||
import core.game.world.update.flag.player.ChatFlag
|
||||
import core.game.world.update.flag.*
|
||||
import proto.management.ClanMessage
|
||||
import core.game.world.GameWorld.Pulser
|
||||
import core.net.packet.`in`.QCPacketType
|
||||
|
|
@ -54,7 +54,7 @@ object QCRepository {
|
|||
ctx.isQuickChat = true
|
||||
Pulser.submit(object : Pulse(0, player) {
|
||||
override fun pulse(): Boolean {
|
||||
player.updateMasks.register(ChatFlag(ctx))
|
||||
player.updateMasks.register(EntityFlag.Chat, ctx)
|
||||
return true
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package core.tools
|
|||
|
||||
const val tick = 600 //ms
|
||||
const val second = 1000 //ms
|
||||
const val cycle = 20 //ms
|
||||
|
||||
fun secondsToTicks(seconds: Int): Int {
|
||||
val seconds = seconds * second //seconds -> ms
|
||||
|
|
@ -13,6 +14,11 @@ fun ticksToSeconds(ticks: Int): Int {
|
|||
return ticksMs / 1000
|
||||
}
|
||||
|
||||
fun cyclesToTicks (cycles: Int) : Int {
|
||||
val cyclesPerTick = tick / cycle
|
||||
return kotlin.math.ceil (cycles / cyclesPerTick.toDouble()).toInt()
|
||||
}
|
||||
|
||||
fun minutesToTicks(minutes: Int): Int {
|
||||
val minutesMs = minutes * 60 * 1000
|
||||
return minutesMs / tick
|
||||
|
|
@ -24,4 +30,4 @@ fun ticksToMinutes(ticks: Int): Int {
|
|||
}
|
||||
|
||||
const val ticksPerSecond = second / tick
|
||||
const val ticksPerMinute = 60 * ticksPerSecond
|
||||
const val ticksPerMinute = 60 * ticksPerSecond
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue