/* This file is part of the OdinMS Maple Story Server Copyright (C) 2008 ~ 2010 Patrick Huy Matthias Butz Jan Christian Meyer This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License version 3 as published by the Free Software Foundation. You may not use, modify or distribute this program under any other version of the GNU Affero General Public License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package handling.channel.handler; import server.movement.ChangeEquipSpecialAwesome; import server.movement.AbsoluteLifeMovement; import server.movement.LifeMovementFragment; import server.movement.GroundMovement; import server.movement.LifeMovement; import server.movement.TeleportMovement; import server.movement.BounceMovement; import server.movement.RelativeLifeMovement; import java.awt.Point; import java.util.ArrayList; import java.util.List; import server.maps.AnimatedMapleMapObject; import tools.FileoutputUtil; import tools.data.LittleEndianAccessor; public class MovementParse { //1 = player, 2 = mob, 3 = pet, 4 = summon, 5 = dragon public static List parseMovement(final LittleEndianAccessor lea, final int kind) { final List res = new ArrayList<>(); final byte numCommands = lea.readByte(); for (byte i = 0; i < numCommands; i++) { final byte command = lea.readByte(); switch (command) { case 0: case 8: case 15: case 17: case 49: case 50: case 51: { final short xpos = lea.readShort(); final short ypos = lea.readShort(); final short xwobble = lea.readShort(); final short ywobble = lea.readShort(); final short unk = lea.readShort(); short fh = 0, xoffset = 0, yoffset = 0; if (command == 15) { fh = lea.readShort(); } if (command != 49) { xoffset = lea.readShort(); yoffset = lea.readShort(); } final byte newstate = lea.readByte(); final short duration = lea.readShort(); final AbsoluteLifeMovement alm = new AbsoluteLifeMovement(command, new Point(xpos, ypos), duration, newstate); alm.setUnk(unk); alm.setFh(fh); alm.setPixelsPerSecond(new Point(xwobble, ywobble)); alm.setOffset(new Point(xoffset, yoffset)); res.add(alm); break; } case 1: case 2: case 16: case 19: case 20: case 22: case 45: case 46: case 47: case 48: { final short xmod = lea.readShort(); final short ymod = lea.readShort(); short unk = 0; if (command == 19 || command == 20) { unk = lea.readShort(); } final byte newstate = lea.readByte(); final short duration = lea.readShort(); final RelativeLifeMovement rlm = new RelativeLifeMovement(command, new Point(xmod, ymod), duration, newstate); rlm.setUnk(unk); res.add(rlm); break; } case 26: case 27: case 28: case 29: case 30: case 31: case 32: case 33: case 34: case 35: case 36: case 37: case 38: case 39: case 40: case 41: case 42: case 43: case 44: // special case case 18: // special?...final charge aran case 23: case 25: { final byte newstate = lea.readByte(); final short unk = lea.readShort(); final GroundMovement am = new GroundMovement(command, new Point(0, 0), unk, newstate); res.add(am); break; } case 3: case 4: case 5: case 6: case 7: case 9: case 10: case 11: case 13: case 14: case 24: { final short xpos = lea.readShort(); final short ypos = lea.readShort(); final short fh = lea.readShort(); final byte newstate = lea.readByte(); final short duration = lea.readShort(); final TeleportMovement tm = new TeleportMovement(command, new Point(xpos, ypos), duration, newstate); tm.setFh(fh); res.add(tm); break; } case 21: { final short xpos = lea.readShort(); final short ypos = lea.readShort(); final short xoffset = lea.readShort(); final short yoffset = lea.readShort(); final byte newstate = lea.readByte(); final short duration = lea.readShort(); final BounceMovement bm = new BounceMovement(command, new Point(xpos, ypos), duration, newstate); bm.setOffset(new Point(xoffset, yoffset)); res.add(bm); break; } case 12: { // Update Equip or Dash res.add(new ChangeEquipSpecialAwesome(command, lea.readByte())); break; } default: System.out.println("Kind movement: " + kind + ", Remaining : " + (numCommands - res.size()) + " New type of movement ID : " + command + ", packet : " + lea.toString(true)); FileoutputUtil.log(FileoutputUtil.Movement_Log, "Kind movement: " + kind + ", Remaining : " + (numCommands - res.size()) + " New type of movement ID : " + command + ", packet : " + lea.toString(true)); return null; } } if (numCommands != res.size()) { return null; // Probably hack } return res; } public static void updatePosition(final List movement, final AnimatedMapleMapObject target, final int yoffset) { if (movement == null) { return; } for (final LifeMovementFragment move : movement) { if (move instanceof LifeMovement) { if (move instanceof AbsoluteLifeMovement) { final Point position = ((LifeMovement) move).getPosition(); position.y += yoffset; target.setPosition(position); } target.setStance(((LifeMovement) move).getNewstate()); } } } }