Jump to content

Recommended Posts

Posted

I don't understand why my version of lineage 2 gracia final leaves I have the animation that freezes for pets and summons if I exceed 600 of Patkspeed on the client of the owner of the summon while the client of a character who look at the same summon at the same time see the animation

 

look video

https://youtu.be/DDzhxDodZZs

 

Thx for Help

Posted
2 hours ago, sacrifice said:

I don't understand why my version of lineage 2 gracia final leaves I have the animation that freezes for pets and summons if I exceed 600 of Patkspeed on the client of the owner of the summon while the client of a character who look at the same summon at the same time see the animation

 

look video

https://youtu.be/DDzhxDodZZs

 

Thx for Help

 

propably cant handle it by client

Posted (edited)

u can guess anything u want , like - some variable( of pet structure, like in packet) that is being handled by client from server  exceed its limit , if its int8 type for example.

But the truth is in reversing pet class structure constructor and its functions and understanding how the codelogic goes, better with debug !

Edited by LightFusionMain
Posted (edited)

you think it s in packet in the core java of server?

exemple in file of \l2jfree-core\src\main\java\com\l2jfree\gameserver\network?

 

and why the vision of owner summon is different vision no owner summon?

Edited by sacrifice
Posted (edited)
10 hours ago, sacrifice said:

you think it s in packet in the core java of server?

exemple in file of \l2jfree-core\src\main\java\com\l2jfree\gameserver\network?

 

and why the vision of owner summon is different vision no owner summon?

if u had read carefully(what i was telling in prev msg) u will understand why, owner doesn't need to receive information data( about pet attack ) on client, but player's surround him, must receive that info, 

on where exact its issuing i can only guess, to say how it rly is u must understand codeflow of both client( as i mentioned) and probably server .

 

Edited by LightFusionMain
Posted

huh )) i read your main post again, and what  i told is opposite to what u have, player's surround u are receiving correct info data, but u are not , so the sollution is opposite, problem is in pet class function that is used for attack, guessing what exact problem it is is useless, u rly must look in IDA ( dissamble it ) ,

Posted (edited)

Yes I think the player's surround see the pet summon like a NPC class, but the owner pet see the pet like a summon class

 

You think the problem is Client Side in dll ?

How search with IDA :( I do not master IDA

 

in which dll i should look?

Edited by sacrifice
Posted

obvsly Pet class resides in engine.dll but is called from Nwindow.dll , so u have to first decompile engine find pet class constructor ( by text/name, some referencies  ) then find it's function , referencies in engine.dll and nwindow.dll 

 

  • 4 weeks later...
Posted

The problem does not come from the client because I managed to test a summon on a L2OFF Gracia server and there is no animation problem On the other hand on L2JFree and L2J there is the problem

Posted

I have this file java in server side:AbstractNpcInfo.java

l2jfree-core\src\main\java\com\l2jfree\gameserver\network\packets\server

 

Who know if it s here I can fix bug?

 

/*
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 * 
 * 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 General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <http://www.gnu.org/licenses/>.
 */
package com.l2jfree.gameserver.network.packets.server;

import com.l2jfree.Config;
import com.l2jfree.gameserver.datatables.CharTemplateTable;						// Tauphraen for Sacrifice : implantation NPC to PJ from Darki
import com.l2jfree.gameserver.gameobjects.L2Creature;
import com.l2jfree.gameserver.gameobjects.L2Npc;
import com.l2jfree.gameserver.gameobjects.L2Player;
import com.l2jfree.gameserver.gameobjects.L2Summon;
import com.l2jfree.gameserver.gameobjects.L2Trap;
import com.l2jfree.gameserver.gameobjects.instance.L2MonsterInstance;
import com.l2jfree.gameserver.gameobjects.itemcontainer.Inventory;
import com.l2jfree.gameserver.gameobjects.templates.L2NpcTemplate;
import com.l2jfree.gameserver.model.skills.effects.AbnormalEffect;
import com.l2jfree.gameserver.network.L2Client;
import com.l2jfree.gameserver.network.packets.L2ServerPacket;

public abstract class AbstractNpcInfo extends L2ServerPacket
{
	private static final String _S__22_NPCINFO = "[S] 0c NpcInfo";
	
	protected int _x, _y, _z, _heading;
	protected int _idTemplate;
	protected boolean _isSummoned;
	protected int _mAtkSpd, _pAtkSpd;
	
	/**
	 * Run speed, swimming run speed and flying run speed
	 */
	protected int _runSpd;
	
	/**
	 * Walking speed, swimming walking speed and flying walking speed
	 */
	protected int _walkSpd;
	
	protected int _rhand, _lhand, _chest;
	protected double _collisionHeight, _collisionRadius;
	protected String _name = "";
	protected String _title = "";
	
	public AbstractNpcInfo(L2Creature cha)
	{
		_isSummoned = cha.isShowSummonAnimation();
		_x = cha.getX();
		_y = cha.getY();
		_z = cha.getZ();
		_heading = cha.getHeading();
		_mAtkSpd = cha.getMAtkSpd();
		_pAtkSpd = cha.getPAtkSpd();
		_runSpd = cha.getTemplate().getBaseRunSpd();
		_walkSpd = cha.getTemplate().getBaseWalkSpd();
	}
	
	/* (non-Javadoc)
	 * @see com.l2jfree.gameserver.serverpackets.ServerBasePacket#getType()
	 */
	@Override
	public String getType()
	{
		return _S__22_NPCINFO;
	}

	// Panday for Sacrifice : NPC to PJ - Classe interne CustomNpcInfo
	public static class CustomNpcInfo extends AbstractNpcInfo
	{
		private final L2Npc _customNpc;
		
		public CustomNpcInfo(L2Npc cha)
		{
			super(cha);
			_customNpc = cha;
			_customNpc.setClientX(_customNpc.getPosition().getX());
			_customNpc.setClientY(_customNpc.getPosition().getY());
			_customNpc.setClientZ(_customNpc.getPosition().getZ());
		}
		
		@Override
		protected void writeImpl(L2Client client, L2Player activeChar)
		{
			// Aide : sources L2J, comprehension des octets du byte buffer
		
			writeC(0x31); //writeC(0x31);																					OK
			writeD(_customNpc.getX()); //writeD(_x);																		OK
			writeD(_customNpc.getY()); //writeD(_y);																		OK
			writeD(_customNpc.getZ()); //writeD(_z);																		OK
			writeD(_customNpc.getHeading()); //writeD(_heading);															OK
			writeD(_customNpc.getObjectId()); //writeD(_npc.getObjectId());													OK
			writeS(_customNpc.getCustomNpcInstance().getName()); //writeS(fpc.name);										OK
			writeD(_customNpc.getCustomNpcInstance().getRace()); //writeD(fpc.race);										OK
			writeD(_customNpc.getCustomNpcInstance().isFemaleSex()? 1 : 0); //writeD(fpc.sex);								OK
			writeD(_customNpc.getCustomNpcInstance().getClassId()); //writeD(fpc.clazz);									OK
			writeD(0); //writeD(fpc.pdHairall);																				TEST
			writeD(0); //writeD(fpc.pdHead);																				TEST
			writeD(_customNpc.getCustomNpcInstance().PAPERDOLL_RHAND()); //writeD(fpc.pdRHand);								OK
			writeD(_customNpc.getCustomNpcInstance().PAPERDOLL_LHAND()); //writeD(fpc.pdLHand);								OK
			writeD(_customNpc.getCustomNpcInstance().PAPERDOLL_GLOVES()); //writeD(fpc.pdGloves);							OK
			writeD(_customNpc.getCustomNpcInstance().PAPERDOLL_CHEST()); //writeD(fpc.pdChest);								OK
			writeD(_customNpc.getCustomNpcInstance().PAPERDOLL_LEGS()); //writeD(fpc.pdLegs);								OK
			writeD(_customNpc.getCustomNpcInstance().PAPERDOLL_FEET()); //writeD(fpc.pdFeet);								OK
			writeD(_customNpc.getCustomNpcInstance().PAPERDOLL_BACK()); //writeD(fpc.pdBack);								TEST
			writeD(_customNpc.getCustomNpcInstance().PAPERDOLL_RHAND()); //writeD(fpc.pdLRHand);							TEST
			writeD(_customNpc.getCustomNpcInstance().PAPERDOLL_HAIR()); //writeD(fpc.pdHair);								OK
			writeD(_customNpc.getCustomNpcInstance().PAPERDOLL_HAIR2()); //writeD(fpc.pdHair2);								OK

			//write('D',0, 8);
			writeD(0); //writeD(fpc.pdRBracelet);																			TEST
			writeD(0); //writeD(fpc.pdLBracelet);																			TEST
			writeD(0); //writeD(fpc.pdDeco1);																				TEST
			writeD(0); //writeD(fpc.pdDeco2);																				TEST
			writeD(0); //writeD(fpc.pdDeco3);																				TEST
			writeD(0); //writeD(fpc.pdDeco4);																				TEST
			writeD(0); //writeD(fpc.pdDeco5);																				TEST
			writeD(0); //writeD(fpc.pdDeco6);																				TEST
			
			writeD(0x00); // Correctif L2J																					TEST
			
			writeD(0); //writeD(fpc.pdUnderAug);
			writeD(0); //writeD(fpc.pdHeadAug);
			writeD(0); //writeD(fpc.pdRHandAug);
			writeD(0); //writeD(fpc.pdLHandAug);
			writeD(0); //writeD(fpc.pdGlovesAug);
			writeD(0); //writeD(fpc.pdChestAug);
			writeD(0); //writeD(fpc.pdLegsAug);
			writeD(0); //writeD(fpc.pdFeetAug);
			writeD(0); //writeD(fpc.pdBackAug);
			writeD(0); //writeD(fpc.pdLRHandAug);
			writeD(0); //writeD(fpc.pdHairAug);
			writeD(0); //writeD(fpc.pdHair2Aug);
			
			writeD(0); //writeD(fpc.pdRBraceletAug);
			writeD(0); //writeD(fpc.pdLBraceletAug);
			writeD(0); //writeD(fpc.pdDeco1Aug);
			writeD(0); //writeD(fpc.pdDeco2Aug);
			writeD(0); //writeD(fpc.pdDeco3);
			writeD(0); //writeD(fpc.pdDeco4);
			writeD(0); //writeD(fpc.pdDeco5);
			writeD(0); //writeD(fpc.pdDeco6);
			
			writeD(0x00); // Correctif L2J																					TEST
			writeD(0x00); // Correctif L2J																					TEST
			writeD(0x00); // Correctif L2J																					TEST
			
			writeD(_customNpc.getCustomNpcInstance().getPvpFlag() ? 1 : 0); //writeD(fpc.pvpFlag);
			writeD(_customNpc.getCustomNpcInstance().getKarma()); //writeD(fpc.karma);

			writeD(_customNpc.getMAtkSpd()); //writeD(_mAtkSpd);
			writeD(_customNpc.getPAtkSpd()); //writeD(_pAtkSpd);
			
			writeD(_customNpc.getCustomNpcInstance().getPvpFlag() ? 1 : 0); //writeD(fpc.pvpFlag);
			writeD(_customNpc.getCustomNpcInstance().getKarma()); //writeD(fpc.karma);

			writeD(_customNpc.getRunSpeed()); //writeD(_runSpd);
			writeD(_customNpc.getRunSpeed()/2); //writeD(_walkSpd);
			writeD(_customNpc.getRunSpeed()/3); //writeD(50);  // swimspeed
			writeD(_customNpc.getRunSpeed()/3); //writeD(50);  // swimspeed
			writeD(_customNpc.getRunSpeed()); //writeD(_flRunSpd);
			writeD(_customNpc.getRunSpeed()); //writeD(_flWalkSpd);
			writeD(_customNpc.getRunSpeed()); //writeD(_flyRunSpd);
			writeD(_customNpc.getRunSpeed()); //writeD(_flyWalkSpd);
			writeF(_customNpc.getStat().getMovementSpeedMultiplier()); //writeF(_npc.getMovementSpeedMultiplier());
			writeF(_customNpc.getStat().getAttackSpeedMultiplier()); //writeF(_npc.getAttackSpeedMultiplier());

			writeF(CharTemplateTable.getInstance().getTemplate(_customNpc.getCustomNpcInstance().getClassId()).getCollisionRadius()); //writeF(pctmpl.collisionRadius);
			writeF(CharTemplateTable.getInstance().getTemplate(_customNpc.getCustomNpcInstance().getClassId()).getCollisionHeight()); //writeF(pctmpl.collisionHeight);
			
			writeD(_customNpc.getCustomNpcInstance().getHairStyle()); //writeD(fpc.hairStyle);
			writeD(_customNpc.getCustomNpcInstance().getHairColor()); //writeD(fpc.hairColor);
			writeD(_customNpc.getCustomNpcInstance().getFace()); //writeD(fpc.face);
			
			writeS(_customNpc.getCustomNpcInstance().getTitle()); //writeS(fpc.title);
			
			writeD(_customNpc.getCustomNpcInstance().getClanId()); //writeD(0x00);
			writeD(_customNpc.getCustomNpcInstance().getClanCrestId()); //writeD(0x00);
			writeD(_customNpc.getCustomNpcInstance().getAllyId()); //writeD(0x00);
			writeD(_customNpc.getCustomNpcInstance().getAllyCrestId()); //writeD(0x00);
			writeD(0); //writeD(0);
			writeC(_customNpc.getCustomNpcInstance().isSit() ? 0 : 1); //writeC(0x01);    // standing = 1  sitting = 0
			writeC(_customNpc.isRunning() ? 1 : 0); //writeC(_npc.isRunning() ? 1 : 0);    // running = 1   walking = 0
			writeC(_customNpc.isInCombat() ? 1 : 0); //writeC(_npc.isInCombat() ? 1 : 0);
			writeC(_customNpc.isAlikeDead() ? 1 : 0); //writeC(_npc.isAlikeDead() ? 1 : 0);
			
			//write('C',0, 3);
			writeC(0); //writeC(fpc.invisible); // invisible = 1  visible =0
			writeC(0); //writeC(fpc.mount); // 1 on strider   2 on wyvern  3 on Great Wolf  0 no mount
			writeC(0); //writeC(0x00);   //  1 - sellshop
			
			writeH(0); //writeH(0x00); // cubic count
			writeC(0); //writeC(0x00); // find party members
			writeD(_customNpc.getAbnormalEffect()); //writeD(0x00);
			writeC(0); //writeC(0x00);                       //Changed by Thorgrim
			writeH(0); //writeH(0x00); //Blue value for name (0 = white, 255 = pure blue)
			writeD(_customNpc.getCustomNpcInstance().getClassId()); //writeD(fpc.clazz);
			writeD(_customNpc.getMaxCp()); //writeD(0x00);//max cp
			writeD((int)_customNpc.getStatus().getCurrentCp()); //writeD(0x00);//cur cp
			writeC(_customNpc.getCustomNpcInstance().getEnchantWeapon()); //writeC(fpc.enchantEffect);
			writeC(0); //writeC(fpc.team);
			writeD(0); //writeD(0x00);
			writeC(_customNpc.getCustomNpcInstance().isNoble() ? 1 : 0); //writeC(0x00); // Symbol on char menu ctrl+I
			writeC(_customNpc.getCustomNpcInstance().isHero()  ? 1 : 0); //writeC(0x00); // Hero Aura
			writeC(0); //writeC(fpc.fishing); //0x01: Fishing Mode (Cant be undone by setting back to 0)

			//write('D',0, 3);
			writeD(0); //writeD(fpc.fishingX);
			writeD(0); //writeD(fpc.fishingY);
			writeD(0); //writeD(fpc.fishingZ);
			
			writeD(_customNpc.getCustomNpcInstance().nameColor()); //writeD(fpc.nameColor);
			writeD(0); //writeD(0x00); // isRunning() as in UserInfo?
			writeD(_customNpc.getCustomNpcInstance().getPledgeClass()); //writeD(0x00); // pledge class
			writeD(0); //writeD(0x00); // ??
			writeD(_customNpc.getCustomNpcInstance().titleColor()); //writeD(fpc.titleColor);
			writeD(_customNpc.getCustomNpcInstance().getCursedWeaponLevel()); //writeD(0x00); // cursed weapon level
			
			//write('D',0, 2);
			writeD(0); //writeD(0x00);
			writeD(0); //writeD(0x00); // transformation id
		}
		
		@Override
		public boolean canBeSentTo(L2Client client, L2Player activeChar)
		{
			if (!activeChar.canSee(_customNpc))
				return false;

			return true;
		}
	}
	// End code by Sacrifice

	/**
	 * Packet for Npcs
	 */
	public static class NpcInfo extends AbstractNpcInfo
	{
		private final L2Npc _npc;
		
		public NpcInfo(L2Npc cha)
		{
			super(cha);
			_npc = cha;
			_idTemplate = cha.getTemplate().getIdTemplate(); // On every subclass
			_rhand = cha.getRightHandItem(); // On every subclass
			_lhand = cha.getLeftHandItem(); // On every subclass
			_collisionHeight = cha.getCollisionHeight(); // On every subclass
			_collisionRadius = cha.getCollisionRadius(); // On every subclass
			
			if (cha.getTemplate().isServerSideName())
				_name = cha.getTemplate().getName(); // On every subclass
				
			if (cha.isChampion())
			{
				_title = Config.CHAMPION_TITLE; // On every subclass
			}
			else if (cha.getTemplate().isServerSideTitle())
			{
				_title = cha.getTemplate().getTitle(); // On every subclass
			}
			else
			{
				_title = cha.getTitle(); // On every subclass
			}
			
			if (Config.SHOW_NPC_LVL && _npc instanceof L2MonsterInstance)
			{
				String t = "Lvl " + cha.getLevel();
				if (cha.getAggroRange() > 0)
				{
					if (!cha.isChampion() || (cha.isChampion() && !Config.CHAMPION_PASSIVE))
						t += "*";
				}
				
				if (_title != null && !_title.isEmpty())
					t += " " + _title;
				
				_title = t;
			}
		}
		
		@Override
		protected void writeImpl(L2Client client, L2Player activeChar)
		{
			writeC(0x0c);
			writeD(_npc.getObjectId());
			writeD(_idTemplate + 1000000); // npctype id
			writeD(_npc.isAutoAttackable(activeChar) ? 1 : 0);
			writeD(_x);
			writeD(_y);
			writeD(_z);
			writeD(_heading);
			writeD(0x00);
			writeD(_mAtkSpd);
			writeD(_pAtkSpd);
			writeD(_runSpd);
			writeD(_walkSpd);
			writeD(_runSpd); // swim run speed
			writeD(_walkSpd); // swim walk speed
			writeD(_runSpd);
			writeD(_walkSpd);
			writeD(_runSpd); // fly run speed
			writeD(_walkSpd); // fly walk speed
			writeF(_npc.getStat().getMovementSpeedMultiplier());
			writeF(_npc.getStat().getAttackSpeedMultiplier());
			writeF(_collisionRadius);
			writeF(_collisionHeight);
			writeD(_rhand); // right hand weapon
			writeD(_chest);
			writeD(_lhand); // left hand weapon
			writeC(1); // name above char 1=true ... ??
			writeC(_npc.isRunning() ? 1 : 0);
			writeC(_npc.isInCombat() ? 1 : 0);
			writeC(_npc.isAlikeDead() ? 1 : 0);
			writeC(_isSummoned ? 2 : 0); // 0=teleported 1=default 2=summoned
			writeS(_name);
			writeS(_title);
			writeD(0x00); // Title color 0=client default
			writeD(0x00);
			writeD(0x00); // pvp flag
			
			writeD(_npc.getAbnormalEffect()); // C2
			writeD(0x00); //clan id
			writeD(0x00); //crest id
			writeD(0000); // C2
			writeD(0000); // C2
			writeC(_npc.isFlying() ? 2 : 0); // C2
			writeC(0x00); // title color 0=client
			
			writeF(_collisionRadius);
			writeF(_collisionHeight);
			writeD(_npc.getWeaponEnchantLevel()); // C4
			writeD(_npc.isFlying() ? 1 : 0); // C6
			writeD(0x00);
			writeD(0x00);// CT1.5 Pet form and skills
			if (Config.PACKET_FINAL)
			{
				writeC(0x01);
				writeC(0x01);
				writeD(_npc.getSpecialEffect());
			}
		}
		
		@Override
		public boolean canBeSentTo(L2Client client, L2Player activeChar)
		{
			if (!activeChar.canSee(_npc))
				return false;
			
			return true;
		}
	}
	
	public static class TrapInfo extends AbstractNpcInfo
	{
		private final L2Trap _trap;
		
		public TrapInfo(L2Trap cha)
		{
			super(cha);
			_trap = cha;
			_idTemplate = cha.getTemplate().getIdTemplate();
			_rhand = 0;
			_lhand = 0;
			_collisionHeight = _trap.getTemplate().getCollisionHeight();
			_collisionRadius = _trap.getTemplate().getCollisionRadius();
			_title = cha.getOwner().getName();
			_runSpd = _trap.getStat().getRunSpeed();
			_walkSpd = _trap.getStat().getWalkSpeed();
		}
		
		@Override
		protected void writeImpl(L2Client client, L2Player activeChar)
		{
			writeC(0x0c);
			writeD(_trap.getObjectId());
			writeD(_idTemplate + 1000000); // npctype id
			writeD(_trap.isAutoAttackable(activeChar) ? 1 : 0);
			writeD(_x);
			writeD(_y);
			writeD(_z);
			writeD(_heading);
			writeD(0x00);
			writeD(_mAtkSpd);
			writeD(_pAtkSpd);
			writeD(_runSpd);
			writeD(_walkSpd);
			writeD(_runSpd); // swim run speed
			writeD(_walkSpd); // swim walk speed
			writeD(_runSpd);
			writeD(_walkSpd);
			writeD(_runSpd); // fly run speed
			writeD(_walkSpd); // fly walk speed
			writeF(1.1/*_trap.getStat().getMovementSpeedMultiplier()*/);
			writeF(_trap.getStat().getAttackSpeedMultiplier());
			writeF(_collisionRadius);
			writeF(_collisionHeight);
			writeD(_rhand); // right hand weapon
			writeD(_chest);
			writeD(_lhand); // left hand weapon
			writeC(1); // name above char 1=true ... ??
			writeC(1);
			writeC(_trap.isInCombat() ? 1 : 0);
			writeC(_trap.isAlikeDead() ? 1 : 0);
			writeC(_isSummoned ? 2 : 0); //  0=teleported  1=default   2=summoned
			writeS(_name);
			writeS(_title);
			writeD(0x00); // title color 0 = client default
			
			writeD(0x00);
			writeD(0x00); // pvp flag
			
			writeD(_trap.getAbnormalEffect()); // C2
			writeD(0x00); //clan id
			writeD(0x00); //crest id
			writeD(0000); // C2
			writeD(0000); // C2
			writeD(0000); // C2
			writeC(0000); // C2
			
			writeC(0x00); // Title color 0=client default
			
			writeF(_collisionRadius);
			writeF(_collisionHeight);
			writeD(0x00); // C4
			writeD(0x00); // C6
			writeD(0x00);
			writeD(0);//CT1.5 Pet form and skills
			if (Config.PACKET_FINAL)
			{
				writeC(0x01);
				writeC(0x01);
				writeD(0x00);
			}
		}
		
		@Override
		public boolean canBeSentTo(L2Client client, L2Player activeChar)
		{
			if (!activeChar.canSee(_trap))
				return false;
			
			return true;
		}
	}
	
	/**
	 * Packet for summons
	 */
	public static class SummonInfo extends AbstractNpcInfo
	{
		private final L2Summon _summon;
		private int _form = 0;
		private int _val = 0;
		
		public SummonInfo(L2Summon cha, int val)
		{
			super(cha);
			_summon = cha;
			_val = val;
			
			int npcId = cha.getTemplate().getNpcId();
			
			if (npcId == 16041 || npcId == 16042)
			{
				if (cha.getLevel() > 84)
					_form = 3;
				else if (cha.getLevel() > 79)
					_form = 2;
				else if (cha.getLevel() > 74)
					_form = 1;
			}
			else if (npcId == 16025 || npcId == 16037)
			{
				if (cha.getLevel() > 69)
					_form = 3;
				else if (cha.getLevel() > 64)
					_form = 2;
				else if (cha.getLevel() > 59)
					_form = 1;
			}
			
			// fields not set on AbstractNpcInfo
			_rhand = cha.getWeapon();
			_lhand = 0;
			_chest = cha.getArmor();
			_collisionHeight = _summon.getTemplate().getCollisionHeight();
			_collisionRadius = _summon.getTemplate().getCollisionRadius();
			_name = cha.getName();
			_title = cha.getOwner() != null ? (cha.getOwner().isOnline() == 0 ? "" : cha.getOwner().getName()) : ""; // when owner online, summon will show in title owner name
			_idTemplate = cha.getTemplate().getIdTemplate();
			
			_collisionHeight = cha.getTemplate().getCollisionHeight();
			_collisionRadius = cha.getTemplate().getCollisionRadius();
			
			// few fields needing fix from AbstractNpcInfo
			_runSpd = cha.getPetSpeed();
			_walkSpd = cha.isMountable() ? 45 : 30;
		}
		
		@Override
		protected void writeImpl(L2Client client, L2Player activeChar)
		{
			writeC(0x0c);
			writeD(_summon.getObjectId());
			writeD(_idTemplate + 1000000); // npctype id
			writeD(_summon.isAutoAttackable(activeChar) ? 1 : 0);
			writeD(_x);
			writeD(_y);
			writeD(_z);
			writeD(_heading);
			writeD(0x00);
			writeD(_mAtkSpd);
			writeD(_pAtkSpd);
			writeD(_runSpd);
			writeD(_walkSpd);
			writeD(_runSpd); // swim run speed
			writeD(_walkSpd); // swim walk speed
			writeD(_runSpd);
			writeD(_walkSpd);
			writeD(_runSpd); // fly run speed
			writeD(_walkSpd); // fly walk speed
			writeF(_summon.getStat().getMovementSpeedMultiplier());
			writeF(_summon.getStat().getAttackSpeedMultiplier());
			writeF(_collisionRadius);
			writeF(_collisionHeight);
			writeD(_rhand); // right hand weapon
			writeD(_chest);
			writeD(_lhand); // left hand weapon
			writeC(1); // name above char 1=true ... ??
			writeC(1);
			writeC(_summon.isInCombat() ? 1 : 0);
			writeC(_summon.isAlikeDead() ? 1 : 0);
			writeC(_val); //  0=teleported  1=default   2=summoned
			writeS(_name);
			writeS(_title);
			writeD(0x01);// Title color 0=client default
			
			writeD(_summon.getPvpFlag());
			writeD(_summon.getKarma());
			
			if (_summon.getOwner().getAppearance().isInvisible())
			{
				writeD((_summon.getAbnormalEffect() | AbnormalEffect.STEALTH.getMask()));
			}
			else
			{
				writeD(_summon.getAbnormalEffect());
			}
			writeD(_summon.getOwner().getClanId());
			writeD(0x00); //crest id
			writeD(0000); // C2
			writeD(0000); // C2
			writeC(0000); // C2
			
			writeC(_summon.getTeam());
			writeF(_collisionRadius);
			writeF(_collisionHeight);
			writeD(0x00); // C4
			writeD(0x00); // C6
			writeD(0x00);
			writeD(_form);//CT1.5 Pet form and skills
			if (Config.PACKET_FINAL)
			{
				writeC(0x01);
				writeC(0x01);
				writeD(0x00);
			}
		}
		
		@Override
		public boolean canBeSentTo(L2Client client, L2Player activeChar)
		{
			// Owner gets PetInfo
			if (_summon.getOwner() == activeChar)
				return false;
			
			if (!activeChar.canSee(_summon))
				return false;
			
			return true;
		}
	}
	
	/**
	 * Packet for morphed PCs
	 */
	public static class PlayerMorphInfo extends AbstractNpcInfo
	{
		private final L2Player _pc;
		private final L2NpcTemplate _template;
		
		public PlayerMorphInfo(L2Player cha, L2NpcTemplate template)
		{
			super(cha);
			_pc = cha;
			_template = template;
		}
		
		@Override
		protected void writeImpl(L2Client client, L2Player activeChar)
		{
			writeC(0x0c);
			writeD(_pc.getObjectId());
			writeD(_pc.getPoly().getPolyId() + 1000000); // npctype id
			writeD(_pc.isAutoAttackable(activeChar) ? 1 : 0);
			writeD(_x);
			writeD(_y);
			writeD(_z);
			writeD(_heading);
			writeD(0x00);
			writeD(_mAtkSpd);
			writeD(_pAtkSpd);
			writeD(_runSpd);
			writeD(_walkSpd);
			writeD(_runSpd); // swim run speed
			writeD(_walkSpd); // swim walk speed
			writeD(_runSpd);
			writeD(_walkSpd);
			writeD(_runSpd); // fly run speed
			writeD(_walkSpd); // fly walk speed
			writeF(_pc.getStat().getMovementSpeedMultiplier());
			writeF(_pc.getStat().getAttackSpeedMultiplier());
			writeF(_template.getCollisionRadius());
			writeF(_template.getCollisionHeight());
			writeD(_pc.getInventory().getPaperdollItemDisplayId(Inventory.PAPERDOLL_RHAND)); // right hand weapon
			writeD(0); // Chest
			writeD(_pc.getInventory().getPaperdollItemDisplayId(Inventory.PAPERDOLL_LHAND)); // left hand weapon
			writeC(1); // name above char 1=true ... ??
			writeC(_pc.isRunning() ? 1 : 0);
			writeC(_pc.isInCombat() ? 1 : 0);
			writeC(_pc.isAlikeDead() ? 1 : 0);
			writeC(0);
			writeS(_pc.getAppearance().getVisibleName());
			writeS(_pc.getAppearance().getVisibleTitle());
			
			writeD(0x00); // Title Color
			writeD(_pc.getKarma());
			writeD(_pc.getPvpFlag());
			
			if (_pc.getAppearance().isInvisible())
			{
				writeD((_pc.getAbnormalEffect() | AbnormalEffect.STEALTH.getMask()));
			}
			else
			{
				writeD(_pc.getAbnormalEffect()); // C2
			}
			
			writeD(0x00);
			writeD(0x00);
			writeD(0x00);
			writeD(0x00);
			writeC(0x00);
			writeC(0x00);
			writeF(_template.getCollisionRadius());
			writeF(_template.getCollisionHeight());
			writeD(0x00);
			writeD(0x00);
			writeD(0x00);
			writeD(0x00);
			if (Config.PACKET_FINAL)
			{
				writeC(0x01);
				writeC(0x01);
				writeD(0x00);
			}
		}
		
		@Override
		public boolean canBeSentTo(L2Client client, L2Player activeChar)
		{
			// Won't work
			if (_pc == activeChar)
				return false;
			
			if (!activeChar.canSee(_pc))
				return false;
			
			return true;
		}
	}
}

 

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...