nesss, ну вот что есть в тоталчекере
Код:
skill_begin skill_name = [s_hate11] /* [헤이트] */ skill_id = 28 level = 1 operate_type = A2 magic_level = 22 self_effect = {} effect = {{p_target_me};{i_get_agro}} end_effect = {} is_magic = 0 mp_consume2 = 0 cast_range = 400 effective_range = 900 skill_hit_time = 0.7 skill_cool_time = 0.2 skill_hit_cancel_time = 0.5 reuse_delay = 6 reuse_delay_lock = 1 activate_rate = -1 lv_bonus_rate = 0 basic_property = none abnormal_time = 3 abnormal_lv = 1 abnormal_type = target_lock abnormal_instant = 0 irreplaceable_buff = 0 buff_protect_level = 0 attribute = {attr_none;0} trait = {trait_none} effect_point = -3928 target_type = enemy_only affect_scope = single affect_limit = {0;0} next_action = none debuff = 1 ride_state = {@ride_none} multi_class = 0 olympiad_use = 1 skill_end
C++:
char __fastcall CSkillEffect_i_get_agro::Instant(
CSkillEffect_i_get_agro *this,
CCreature *pSkillUser,
CWorldObject *pTarget,
const CSkillInfo *pSkillInfo)
{
unsigned int m_nId; // edi
unsigned int v7; // esi
int v9; // [rsp+20h] [rbp-28h]
unsigned int v10; // [rsp+28h] [rbp-20h]
int v11; // [rsp+30h] [rbp-18h]
if ( !((unsigned __int8 (__fastcall *)(CWorldObject *, CCreature *, CWorldObject *, const CSkillInfo *))pTarget->IsNPC)(
pTarget,
pSkillUser,
pTarget,
pSkillInfo)
|| !pTarget->IsVisible(pTarget) )
{
return 0;
}
m_nId = pSkillUser->m_nId;
v7 = pTarget->m_nId;
v11 = pSkillUser->GetIndex(pSkillUser);
v10 = m_nId;
v9 = pTarget->GetIndex(pTarget);
NpcServer::Send(&g_npcserver, "cdddd", 146i64, v7, v9, v10, v11);
return 1;
}
void __fastcall CSkillEffect_i_get_agro::CSkillEffect_i_get_agro(CSkillEffect_i_get_agro *this)
{
*(_QWORD *)&this->nUnitTick = 0i64;
this->effectCondList._Mypair._Myval2._Myfirst = 0i64;
this->effectCondList._Mypair._Myval2._Mylast = 0i64;
this->effectCondList._Mypair._Myval2._Myend = 0i64;
this->__vftable = (CSkillEffect_i_get_agro_vtbl *)&CSkillEffect_i_get_agro::`vftable';
}
CSkillEffect_i_get_agro *__fastcall CSkillEffect_i_get_agro::`vector deleting destructor'(
CSkillEffect_i_get_agro *this,
char a2)
{
CEffectCondition **Myfirst; // rdx
this->__vftable = (CSkillEffect_i_get_agro_vtbl *)&CSkillEffect::`vftable';
Myfirst = this->effectCondList._Mypair._Myval2._Myfirst;
if ( Myfirst )
{
Memory::Free(&g_Memory, Myfirst, 1);
this->effectCondList._Mypair._Myval2._Myfirst = 0i64;
this->effectCondList._Mypair._Myval2._Mylast = 0i64;
this->effectCondList._Mypair._Myval2._Myend = 0i64;
}
if ( (a2 & 1) != 0 )
operator delete(this, 0x28ui64);
return this;
}
C++:
char __fastcall CSkillEffect_p_target_me::PumpEnd(
CSkillEffect_p_target_me *this,
CCreature *target,
CCreature *__formal,
const CSkillInfo *pSkillInfo)
{
int *p_m_TargetMeCount; // rcx
int m_TargetMeCount; // eax
int *v8; // rax
int v9; // [rsp+38h] [rbp+10h] BYREF
if ( !((unsigned __int8 (__fastcall *)(CCreature *, CCreature *, CCreature *, const CSkillInfo *))target->IsPC)(
target,
target,
__formal,
pSkillInfo) )
return 0;
p_m_TargetMeCount = &target->m_SkillDurationMod.m_TargetMeCount;
m_TargetMeCount = target->m_SkillDurationMod.m_TargetMeCount;
if ( m_TargetMeCount <= 0 )
return 0;
v9 = 0;
*p_m_TargetMeCount = m_TargetMeCount - 1;
v8 = &v9;
if ( *p_m_TargetMeCount > 0 )
v8 = &target->m_SkillDurationMod.m_TargetMeCount;
*p_m_TargetMeCount = *v8;
return 1;
}
char __fastcall CSkillEffect_p_target_me::PumpStart(
CSkillEffect_p_target_me *this,
CCreature *target,
CCreature *pCaster,
const CSkillInfo *pSkillInfo)
{
__int64 Shuttle; // rax
_BOOL8 v7; // r8
if ( !pCaster || !target->IsPC(target) )
return 0;
Shuttle = CSmartID::GetShuttle((__crt_locale_data *)&target->m_spTarget);
if ( !Shuttle || pCaster->m_nId != *(_DWORD *)(Shuttle + 24) )
{
LOBYTE(v7) = target->m_AreaMod.m_bIsInBattleField;
target->Action(target, pCaster, v7, 0);
}
++target->m_SkillDurationMod.m_TargetMeCount;
return 1;
}
void __fastcall CSkillEffect_p_target_me::CSkillEffect_p_target_me(CSkillEffect_p_target_me *this)
{
*(_QWORD *)&this->nUnitTick = 0i64;
this->effectCondList._Mypair._Myval2._Myfirst = 0i64;
this->effectCondList._Mypair._Myval2._Mylast = 0i64;
this->effectCondList._Mypair._Myval2._Myend = 0i64;
this->__vftable = (CSkillEffect_p_target_me_vtbl *)&CSkillEffect_p_target_me::`vftable';
}
CSkillEffect_p_target_me *__fastcall CSkillEffect_p_target_me::`vector deleting destructor'(
CSkillEffect_p_target_me *this,
char a2)
{
CEffectCondition **Myfirst; // rdx
this->__vftable = (CSkillEffect_p_target_me_vtbl *)&CSkillEffect::`vftable';
Myfirst = this->effectCondList._Mypair._Myval2._Myfirst;
if ( Myfirst )
{
Memory::Free(&g_Memory, Myfirst, 1);
this->effectCondList._Mypair._Myval2._Myfirst = 0i64;
this->effectCondList._Mypair._Myval2._Mylast = 0i64;
this->effectCondList._Mypair._Myval2._Myend = 0i64;
}
if ( (a2 & 1) != 0 )
operator delete(this, 0x28ui64);
return this;
}
С твоего позволения накину в java коде что бы человек понял что к чему (хотя бы поверхностно).
/**
* Эффект мгновенного скилла "GetAgro".
* Используется, например, для агро-скиллов, отправляющих пакет на NpcServer.
*/
public class GetAgroEffect extends L2Effect {
public GetAgroEffect(Env env, EffectTemplate template) {
super(env, template);
}
@Override
public boolean onInstant(L2Character effector, L2Character effected, L2Skill skill) {
// Проверяем, что цель — NPC и видима
if (!(effected instanceof L2Npc) || !effected.isVisible()) {
return false;
}
L2Character user = effector;
L2Npc target = (L2Npc) effected;
int userId = user.getObjectId();
int targetId = target.getObjectId();
int userIndex = user.getIndex(); // предполагаемый метод
int targetIndex = target.getIndex();
// Отправляем пакет на NpcServer (opcode 146)
NpcServer.getInstance().sendPacket("cdddd", 146, targetId, targetIndex, userId, userIndex);
return true;
}
}
/**
* Эффект "Target Me" (заставляет монстров переключаться на игрока, получившего эффект).
* Накапливает счётчик на персонаже и управляет сменой цели.
*/
public class TargetMeEffect extends L2Effect {
public TargetMeEffect(Env env, EffectTemplate template) {
super(env, template);
// Инициализация списка условий эффекта (аналог effectCondList)
// В Java это можно оставить пустым или реализовать при необходимости.
}
@Override
public void onStart() {
L2Character caster = getEffector();
L2Character target = getEffected();
// Скилл должен применяться к игроку, и кастер должен существовать
if (caster == null || !(target instanceof L2PcInstance)) {
return;
}
L2PcInstance player = (L2PcInstance) target;
// Получаем текущую цель игрока (или другого существа)
L2Object currentTarget = player.getTarget();
int currentTargetId = (currentTarget != null) ? currentTarget.getObjectId() : 0;
// Если игрок не целится в кастера — принудительно меняем цель и выполняем действие
if (currentTarget == null || currentTarget.getObjectId() != caster.getObjectId()) {
boolean isInBattlefield = player.isInBattlefield(); // m_AreaMod.m_bIsInBattleField
player.setTarget(caster);
// Action(target, pCaster, v7, 0) — вероятно, атака или другая реакция
player.doAction(caster, isInBattlefield, false);
}
// Увеличиваем счётчик TargetMe
player.incrementTargetMeCount();
}
@Override
public void onExit() {
L2Character target = getEffected();
if (!(target instanceof L2PcInstance)) {
return;
}
L2PcInstance player = (L2PcInstance) target;
// Уменьшаем счётчик, если он больше нуля
player.decrementTargetMeCount();
}
}
// Дополнительные методы в L2PcInstance (или другом классе игрока)
public class L2PcInstance extends L2Character {
// ...
private int targetMeCount = 0;
public void incrementTargetMeCount() {
targetMeCount++;
}
public void decrementTargetMeCount() {
if (targetMeCount > 0) {
targetMeCount--; // логика гарантирует, что счётчик не станет отрицательным
}
}
public int getTargetMeCount() {
return targetMeCount;
}
}