게시판 제목 잘보고 올리세요 일반게시판에 홍보글 보이면 바로 회원 차단입니다

DamageController 마법사는 무기를 착용하면 공격성공이 안돼요

컨텐츠 정보

본문

package lineage.world.controller;

import lineage.bean.database.Skill;
import lineage.bean.lineage.Clan;
import lineage.bean.lineage.Kingdom;
import lineage.database.CharactersDatabase;
import lineage.database.MagicdollListDatabase;
import lineage.database.ServerDatabase;
import lineage.database.SkillDatabase;
import lineage.network.packet.BasePacketPooling;
import lineage.network.packet.server.S_ClanWar;
import lineage.network.packet.server.S_ObjectEffect;
import lineage.plugin.PluginController;
import lineage.share.Lineage;
import lineage.share.TimeLine;
import lineage.util.Util;
import lineage.world.World;
import lineage.world.object.Character;
import lineage.world.object.object;
import lineage.world.object.instance.BackgroundInstance;
import lineage.world.object.instance.BoardInstance;
import lineage.world.object.instance.GuardInstance;
import lineage.world.object.instance.ItemInstance;
import lineage.world.object.instance.ItemWeaponInstance;
import lineage.world.object.instance.MonsterInstance;
import lineage.world.object.instance.NpcInstance;
import lineage.world.object.instance.PcInstance;
import lineage.world.object.instance.SummonInstance;
import lineage.world.object.magic.AbsoluteBarrier;
import lineage.world.object.magic.CursePoison;
import lineage.world.object.magic.Detection;
import lineage.world.object.magic.EraseMagic;
import lineage.world.object.magic.FogOfSleeping;
import lineage.world.object.magic.Meditation;
import lineage.world.object.npc.background.Cracker;
import lineage.world.object.npc.background.PigeonGroup;
import lineage.world.object.npc.guard.ElvenGuard;
import lineage.world.object.npc.kingdom.KingdomDoor;
import lineage.world.object.npc.kingdom.KingdomGuard;

public final class DamageController {

static public void init(){
TimeLine.start("DamageController..");
TimeLine.end();
}

/**
* 공격이 가해졋을때 공격성공여부를 처리하고
* 그후 이곳으로 오게 되는데 이부분에서는 데미지공식을 연산해도 되는지 여부를 판단하는 메서드.
* 예로 활일경우 화살이 없다면 false를 리턴하며, 사이하활인데 화살이 없을경우 true를 리턴한다.
* - PcInstance쪽에서도 호출해서 사용중. 패킷중에 화살이 없더라도 사이하활은 이팩트를 그려줘야 하기때문에 해당 메서드를 활용중.
*/
static public boolean isAttack(boolean bow, ItemInstance weapon, ItemInstance arrow){
if(bow){
if(weapon != null){
switch(weapon.getItem().getNameIdNumber()){
case 1821: // 사이하활
return true;
default:
return arrow != null;
}
}else{
return false;
}
}
return true;
}

/**
* cha 로부터 o 가 데미지를 입었을때 뒷처리를 담당.
* @param cha : 가격자
* @param o : 데미지 줄 타격자
* @param dmg : 데미지
* @param type : 공격 방식
*/
static public void toDamage(Character cha, object o, int dmg, int type){
if(dmg<=0 || cha==null || o==null || cha.isDead() || o.isDead())
return;

// 데미지 입었다는거 알리기.
o.toDamage(cha, dmg, type);
// hp 처리
o.setNowHp( o.getNowHp()-dmg );
// 투망상태 해제
Detection.onBuff(cha);
Detection.onBuff(o);
// 관련 버프 제거.
if(o.isBuffMeditation())
BuffController.remove(o, Meditation.class);
if(o.isBuffFogOfSleeping())
BuffController.remove(o, FogOfSleeping.class);
if(type == Lineage.ATTACK_TYPE_MAGIC) {
if(o.isBuffEraseMagic())
BuffController.remove(o, EraseMagic.class);
}

if(o.isDead()){
// 죽엇을경우.
toDead(cha, o);
// 죽은거 알리기.
o.toDead(cha);

}else{
// 공격자 분류별로 처리
if(cha instanceof PcInstance){
PcInstance pc = (PcInstance)cha;
// 소환객체에게 알리기.
SummonController.toDamage(pc, o, dmg);
// 요정이라면 근처 경비에게 도움 요청.
toElven(pc, o);
}
}
}

/**
* 대미지 시스템 중심 부분.
*/
static public int getDamage(Character cha, object target, boolean bow, ItemInstance weapon, ItemInstance arrow, int alpha_dmg){
double dmg = 0;

// 앱솔상태 해제
if(cha.isBuffAbsoluteBarrier())
BuffController.remove(cha, AbsoluteBarrier.class);

if(target == null)
return 0;

// 기본적으로 공격 불가능한 객체
if(target instanceof ItemInstance || target instanceof BoardInstance || (!(target instanceof Cracker || target instanceof PigeonGroup) && target instanceof BackgroundInstance) )
return 0;

// 굳은상태라면 패스
if(target.isLockHigh())
return 0;

// 앱솔 상태라면 패스
if(target.isBuffAbsoluteBarrier())
return 0;

// 타켓이 죽은상태라면 패스
if(target.isDead())
return 0;

// 자기자신을 공격할 순 없음.
if(cha.getObjectId() == target.getObjectId())
return 0;

// 장애물 방해하는지 확인.
if(!Util.isAreaAttack(cha, target) && !Util.isAreaAttack(target, cha))
return 0;

// 내성문이라면 공성중일때만 가능.
if(target instanceof KingdomDoor){
KingdomDoor kd = (KingdomDoor)target;
if(kd.getKingdom()==null || kd.getNpc()==null)
return 0;
if(!kd.getKingdom().isWar() && kd.getNpc().getName().indexOf("내성문")>0)
return 0;
}

Object temp = PluginController.init(DamageController.class, "getDamage", cha, target, bow, weapon, arrow);
if(temp!=null && temp instanceof Double)
dmg += (Double)temp;

if(cha instanceof PcInstance){
dmg += toPcInstance((PcInstance)cha, target, bow, weapon, arrow);

}else if(cha instanceof SummonInstance){
dmg += toSummonInstance((SummonInstance)cha, target, bow);

}else if(cha instanceof MonsterInstance){
dmg += toMonsterInstance((MonsterInstance)cha, target, bow);

}else if(cha instanceof GuardInstance){
dmg += toGuardInstance((GuardInstance)cha, target, bow);
}

if(dmg <= 0){
return 0;
}else{
if(alpha_dmg > 0)
dmg += Util.random(0, alpha_dmg);

// 버닝스피릿 1.5배
if(cha.isBuffBurningSpirit() && Util.random(0, 99)<50)
dmg += dmg*1.5;
// 더블 브레이크 2배
if(cha.isBuffBurningSpirit() && Util.random(0, 99)<50)
dmg += dmg*2;
// 위크니스 상태라면 데미지 6 감소
if(target.isBuffWeakness())
dmg -= 6;
// 이문투함 일땐 데미지 50% 만. 제노타임 이뮨투함
if(target.isBuffImmuneToHarm())
dmg = dmg==0 ? 0 : dmg / 2;
// 마법인형 : 돌 골렘 (대미지 감소 +15)
if(target.isMagicdollStoneGolem() && Util.random(0, 99)<10) {
dmg -= 15;
int effect = MagicdollListDatabase.getBuffEffect("돌골렘");
if(effect > 0)
target.toSender(S_ObjectEffect.clone(BasePacketPooling.getPool(S_ObjectEffect.class), target, effect), true);
}
// 리덕션아머 데미지 레벨에 따른 데미지 감소.
if(target.isBuffReductionArmor() && target.getLevel()>=50)
// 50레벨 기준으로 4에 배수만큼 데미지 -1씩 처리.
dmg -= (target.getLevel()-46) / 4;
//
if(target instanceof Character){
Character c = (Character)target;
// 방어력에 따른 데미지 감소.
dmg -= Util.random(0, c.getTotalAc()*0.18);
// 리덕션 효과 넣기.
dmg -= c.getTotalReduction();
}
// 카운터베리어 상태라면 일정확률로 데미지 반사.
if(target.isBuffCounterBarrier() && Util.random(0, 99)<50) {
weapon = target.getInventory().getSlot(Lineage.SLOT_WEAPON);
if(weapon!=null && target instanceof Character) {
// 공격당한 기본 데미지에 무기 큰 데미지 적용.
dmg += weapon.getItem().getDmgMax();
// 현재 착용중인 무기에 대한 데미지 적용.
if(target instanceof PcInstance)
dmg += toPcInstance((PcInstance)target, cha, false, weapon, null);
else if(target instanceof SummonInstance)
dmg += toSummonInstance((SummonInstance)target, cha, bow);
else if(target instanceof MonsterInstance)
dmg += toMonsterInstance((MonsterInstance)target, cha, bow);
else if(target instanceof GuardInstance)
dmg += toGuardInstance((GuardInstance)target, cha, bow);
//
if(dmg > 0)
toDamage((Character)target, cha, (int)dmg, Lineage.ATTACK_TYPE_WEAPON);
return 0;
}
}
//
return dmg>0 ? (int)dmg : 0;
}
}

/**
* 사용자 데미지 추출 함수.
* @param pc
* @param target
* @param bow
* @param weapon
* @param arrow
* @return
*/
static private double toPcInstance(PcInstance pc, object target, boolean bow, ItemInstance weapon, ItemInstance arrow){
boolean Small = true;
double dmg = 0;
if(World.isAttack(pc, target)){
// 장로 변신상태라면 데미지 일정한거 주기.
if(pc.getGfx()==32)
return Util.random(5, 15);

// 데미지 연산
if(isAttack(bow, weapon, arrow) && isHitFigure(pc, target, bow, weapon)){
if(weapon==null){
dmg += Util.random(0, 3);
}else{
// 큰몹인지 작은몹인지 설정
if(target instanceof MonsterInstance){
MonsterInstance mon = (MonsterInstance)target;
Small = mon.getMonster().getSize().equalsIgnoreCase("small");
}
// 대미지 산출
dmg += DmgFigure(pc, bow);
dmg += DmgWeaponFigure(bow, weapon, arrow, Small);
dmg += DmgPlus(pc, weapon, target, bow);
dmg += DmgElement(weapon, target);

if(target instanceof MonsterInstance){
MonsterInstance mon = (MonsterInstance)target;
if(mon.getMonster().getResistanceUndead()<0){
double undead_dmg = Util.random(1, 10);
int material = bow && arrow!=null ? arrow.getItem().getMaterial() : weapon.getItem().getMaterial();
// 언덴드 몬스터일경우
switch(material){
case 14: // 은
case 17: // 미스릴
case 22: // 오리하루콘
int a = mon.getMonster().getResistanceUndead();
a = (~a) + 1;
dmg += (int)(undead_dmg*(a*0.05) );  //제노타임 기본값 0.01
break;
}
}
// 손상을 시키는 몬스터일경우 장거리공격시 데미지 50%만 들어가도록 하기.
if(mon.getMonster().isToughskin() && bow)
dmg = (int)(dmg * 0.7);
}

// 무기 손상도 데미지 감소
dmg -= weapon.getDurability();
}
}
}
return dmg;
}

static private double toSummonInstance(SummonInstance si, object target, boolean bow){
double dmg = 0;
// 데미지 연산
if(World.isAttack(si, target) && isHitFigure(si, target, bow, null)){
// 대미지 산출
dmg += DmgFigure(si, bow);
dmg += DmgPlus(si, null, target, bow);
dmg += getMonsterLeveltoDamage(si);
}
return dmg;
}

static private double toMonsterInstance(MonsterInstance mi, object target, boolean bow){
double dmg = 0;
// 데미지 연산
if(isHitFigure(mi, target, bow, null)){
// 대미지 산출
dmg += DmgFigure(mi, bow);
dmg += DmgPlus(mi, null, target, bow);
dmg += getMonsterLeveltoDamage(mi);
}
return dmg;
}

static private double toGuardInstance(GuardInstance gi, object target, boolean bow){
double dmg = 0;
// 데미지 연산
if(isHitFigure(gi, target, bow, null))
dmg = gi instanceof KingdomGuard ? Util.random(10, 30) : Util.random(100, 120);
return dmg;
}

/**
* 객체가 죽엇을때 그에따른 처리를 하는 함수.
* @param cha : 가해자
* @param o : 피해자
*/
static private void toDead(Character cha, object o){
PluginController.init(DamageController.class, "toDead", cha, o);

// 객체별 처리 구간.
if(o instanceof PcInstance){
PcInstance use = (PcInstance)o;
Kingdom kingdom = KingdomController.findKingdomLocation(use);
boolean exp_drop = o.getLevel()>9 &&
( cha instanceof NpcInstance ||
cha instanceof MonsterInstance ||
World.isNormalZone(o.getX(), o.getY(), o.getMap())
);
boolean item_drop = cha instanceof NpcInstance ||
cha instanceof MonsterInstance ||
!World.isCombatZone(o.getX(), o.getY(), o.getMap());
boolean magic_drop = o.getLawful()<Lineage.NEUTRAL && !World.isCombatZone(o.getX(), o.getY(), o.getMap());
boolean kingdom_war = use.getClassType()==Lineage.LINEAGE_CLASS_ROYAL && // 군주면서
use.getClanId()>0 && // 혈이 있으면서
kingdom!=null && // 외성 좌표 안쪽에 있으면서
kingdom.isWar() && // 해당성이 공성전중이면서
kingdom.getListWar().contains(use.getClanName()); // 공성전 선포를 한 상태라면.

// 경험치 드랍 처리.
if(exp_drop){
if(kingdom!=null && kingdom.isWar()){
if(Lineage.kingdom_player_dead_expdown)
CharacterController.toExpDown(use);
}else if(Lineage.player_dead_expdown){
CharacterController.toExpDown(use);
}
}
// 아이템 드랍 처리.
if(item_drop){
if(kingdom!=null && kingdom.isWar()){
if(Lineage.kingdom_player_dead_itemdrop)
CharacterController.toItemDrop(use);
}else if(Lineage.player_dead_itemdrop){
CharacterController.toItemDrop(use);
}
}
// 마법 드랍 처리.
if(magic_drop){
for(int i=0 ; i<3 ; ++i){
Skill s = SkillController.find(use, Util.random(-200, 200), false);
if(s != null)
SkillController.remove(use, s, false);
}
}
// 공성전 패배 처리.
if(kingdom_war){
// 전쟁 관리 목록에서 제거.
kingdom.getListWar().remove(use.getClanName());
//
World.toSender(S_ClanWar.clone(BasePacketPooling.getPool(S_ClanWar.class), 3, kingdom.getClanName(), use.getClanName()));
}
}

// pvp 처리
if(cha instanceof PcInstance && o instanceof PcInstance) {
PcInstance pc = (PcInstance)cha;
PcInstance use = (PcInstance)o;

// 컴뱃존이 아니면서 카오틱이 아니라면 pc를 피커로 판단. 보라돌이도.
boolean is = !World.isCombatZone(use.getX(), use.getY(), use.getMap()) && use.getLawful()>=Lineage.NEUTRAL && !use.isBuffCriminal();
// 공성존 인지 확인.
Kingdom kingdom = KingdomController.findKingdomLocation(use);
// 성존이고 공성중일경우 환경설정에서 피커 처리 하도록 되있을때만 처리하게 유도.
if(kingdom!=null && kingdom.isWar())
is = Lineage.kingdom_pvp_pk;
// 혈전상태 확인. (혈전 상태일때 카오처리 할지 여부.)
Clan clan = ClanController.find(pc);
if(clan!=null && clan.getWarClan()!=null && clan.getWarClan().equalsIgnoreCase(use.getClanName()))
is = false;
// 피커 처리를 해도 된다면.
if(is) {
PluginController.init(DamageController.class, "toPk", pc, use);
// pkcount 상승
pc.setPkCount(pc.getPkCount()+1);
// pk한 최근 시간값 기록. 만라였다면 한번 바줌.
if(pc.getLawful() != Lineage.LAWFUL)
pc.setPkTime( System.currentTimeMillis() );
// 라우풀값 하향.
if(pc.getLawful() >= Lineage.NEUTRAL)
pc.setLawful(Lineage.NEUTRAL - (pc.getLevel() * 150));
else
pc.setLawful(pc.getLawful() - (pc.getLevel() * 150));
// 로그 처리.
CharactersDatabase.updatePvpKill(pc, use);
CharactersDatabase.updatePvpDead(use, pc);
//
if(Lineage.pvp_print_message) {
for(PcInstance p : World.getPcList())
ChattingController.toChatting(p, String.format("'%s'가 '%s'에게 살해 되었습니다.", use.getName(), pc.getName()), Lineage.CHATTING_MODE_MESSAGE);
}
}
}

// gvp 처리
if(cha instanceof GuardInstance && o instanceof PcInstance){
GuardInstance gi = (GuardInstance)cha;
PcInstance pc = (PcInstance)o;

// 피케이한 이전기록이 남았을경우 그값을 초기화함.
if(pc.getPkTime()>0)
pc.setPkTime(0);
}
}

/**
* 몬스터의 레벨에따른 데미지 산출 메서드.
*/
static private int getMonsterLeveltoDamage(MonsterInstance mi){
return ((mi.getLevel()/10) * 5) + 5;
}

/**
* 속성 데미지 처리 부분.
* @param item
* @param target
* @return
*/
static private double DmgElement(ItemInstance item, object target) {
double dmg=0;
int fire=0, earh=0, wind=0, warter=0;
//
if(target instanceof Character) {
Character cha = (Character)target;
fire = cha.getTotalFireress();
earh = cha.getTotalEarthress();
wind = cha.getTotalWindress();
warter = cha.getTotalWaterress();
}
//
if(item.getItem().getFireress() > 0) {
double item_dmg = item.getItem().getFireress() + item.getEnFireDamage();
double el_dmg = (fire*0.25) * 0.01;
item_dmg -= Util.random(0, item_dmg * el_dmg);
dmg += item_dmg;
}
if(item.getItem().getEarthress() > 0) {
double item_dmg = item.getItem().getEarthress() + item.getEnEarthDamage();
double el_dmg = (earh*0.25) * 0.01;
item_dmg -= Util.random(0, item_dmg * el_dmg);
dmg += item_dmg;
}
if(item.getItem().getWindress() > 0) {
double item_dmg = item.getItem().getWindress() + item.getEnWindDamage();
double el_dmg = (wind*0.25) * 0.01;
item_dmg -= Util.random(0, item_dmg * el_dmg);
dmg += item_dmg;
}
if(item.getItem().getWaterress() > 0) {
double item_dmg = item.getItem().getWaterress() + item.getEnWaterDamage();
double el_dmg = (warter*0.25) * 0.01;
item_dmg -= Util.random(0, item_dmg * el_dmg);
dmg += item_dmg;
}
//
return dmg;
}

/**
* 추가적으로 적용되는 대미지 처리 부분
* - 버프상태에 따른처리
* @param cha : 가격자
* @param item : 착용한 무기
* @param target : 몬스터인지 유저인지 구분 처리하기위한 객체정보
* @return : 계산된 대미지 리턴
*/
static private double DmgPlus(Character cha, ItemInstance item, object target, boolean bow){
double dmg = 0;
if(item != null){
ItemWeaponInstance weapon = (ItemWeaponInstance)item;
// 인첸트 웨폰
if(weapon.isBuffEnchantWeapon())
dmg += 2;
// 블레스웨폰 상태라면 랜타 데미지 2 추가
if(weapon.isBuffBlessWeapon())
dmg += Util.random(0, 2);
// 쉐도우팽
if(weapon.isBuffShadowFang())
dmg += 5;
}
// 홀리써클 상태라면 랜타 데미지 2 추가
// if(buff->findMagic(52))
// dmg += Common::random(0, 2);
// 글로잉오라
if(cha.isBuffGlowingAura())
dmg += 1;
// 인첸트베놈
if(cha.isBuffEnchantVenom() && Util.random(0, 99)<20)
BuffController.append(target, CursePoison.clone(BuffController.getPool(CursePoison.class), null, SkillDatabase.find(2, 2), 32));
// 마법인형 : 라미아
if(cha.isMagicdollRamia() && Util.random(0, 99)<10)
BuffController.append(target, CursePoison.clone(BuffController.getPool(CursePoison.class), null, SkillDatabase.find(2, 2), 10));

// 장거리 공격일때.
if(bow){
dmg += cha.getDynamicAddDmgBow();
// 아이오브스톰
if(cha.isBuffEyeOfStorm())
dmg += 3;
// 마법인형 : 코카트리스
if(cha.isMagicdollCockatrice())
dmg += 1;
// 마법인형 : 스파토이
if(cha.isMagicdollSpartoi())
dmg += 2;
// 근접 공격일때.
}else{
dmg += cha.getDynamicAddDmg();
// 버서커스
if(cha.isBuffBerserks())
dmg += 5;
// 마법인형 : 늑대인간 (근거리 대미지 +15)
// 마법인형 : 크러스트시안 (근거리 대미지 +15)
if((cha.isMagicdollWerewolf() || cha.isMagicdollCrustacean()) && Util.random(0, 99)<10){
dmg += 15;
int effect = MagicdollListDatabase.getBuffEffect(cha.isMagicdollWerewolf() ? "늑대인간" : "크러스트시안");
if(effect > 0)
cha.toSender(S_ObjectEffect.clone(BasePacketPooling.getPool(S_ObjectEffect.class), cha, effect), true);
}
}
// 홀리웨폰 상태라면 랜타 데미지 2 추가
if(cha.isBuffHolyWeapon()){
if(target instanceof MonsterInstance){
MonsterInstance mon = (MonsterInstance)target;
if(mon.getMonster().getResistanceUndead()<0)
dmg += 2;
}
}

return dmg;
}

/**
* 인벤토리에서 무기를 찾은후 무기의 대미지 토탈값 리턴
*/
static private double DmgWeaponFigure(boolean bow, ItemInstance weapon, ItemInstance arrow, boolean Small){
Object temp = PluginController.init(DamageController.class, "DmgWeaponFigure", bow, weapon, arrow, Small);
if(temp!=null && temp instanceof Double)
return (Double)temp;

double dmg = 0;
dmg += weapon.getEnLevel();
// dmg += weapon.getItem().getSafeEnchant();
dmg += weapon.getItem().getAddDmg();
// 축복무기 특화
//if(weapon.getBress()==0 && Util.random(0, 100)<=30)
// dmg += Util.random(0, 2);
// 7인첸 상급무기 특화.
if(weapon.getEnLevel()>7 && weapon.getItem().getSafeEnchant()==6)
{
dmg += Util.random(0, dmg*(weapon.getEnLevel()-7)) * 0.4;
// dmg += Util.random(0, dmg*(weapon.getEnLevel()-7));
}
else if(weapon.getEnLevel()>0 && weapon.getItem().getSafeEnchant()==0)
{
dmg += Util.random(0, dmg*(weapon.getEnLevel()+0)) * 0.9;
// dmg += Util.random(0, dmg*(weapon.getEnLevel()-7));
}
/* // 상급무기 특화 오리지날
if(weapon.getEnLevel()>7)
dmg += Util.random(0, dmg*(weapon.getEnLevel()-7)) * 0.4;
// dmg += Util.random(0, dmg*(weapon.getEnLevel()-7));

*/
// 기본 데미지 연산값 저장 변수
int d = 0;
// 큰몹 및 작은몹 구분하여 무기의 기본 데미지 추출
if(Small) d += weapon.getItem().getDmgMin();
else d += weapon.getItem().getDmgMax();

// 활일경우 화살에 데미지 추출
if( bow ){
// 화살이 있을경우.
if(arrow != null){
if(Small)
d += arrow.getItem().getDmgMin();
else
d += arrow.getItem().getDmgMax();
}
// 사이하활일 경우 마법 데미지 추가
if(weapon.getItem().getNameIdNumber()==1821)
d += Util.random(0, 6);
}

// 추출된 무기데미지를 랜덤값으로 추출 [기본]
if(d > 0)
d = Util.random(0, d);

return dmg + d;
}

/**
* 해당 객체의 스탯정보만으로 총 대미지 산출.
*/
static private double DmgFigure(Character cha, boolean bow){
Object temp = PluginController.init(DamageController.class, "DmgFigure", cha, bow);
if(temp!=null && temp instanceof Double)
return (Double)temp;

double dmg = 0;
if(bow){
// 활일경우
// 순수스탯에 따른 보너스
if(cha.getClassType() == Lineage.LINEAGE_CLASS_ELF)
dmg += Util.random(0, cha.getLevel()/10);
// 스탯에따른 +@ 데미지
if(cha.getTotalDex()<=14)
dmg += 0;
else if(cha.getTotalDex()<=15)
dmg += 1;
else if(cha.getTotalDex()<=15)
dmg += 2;
else if(cha.getTotalDex()<=15)
dmg += 3;
else if(cha.getTotalDex()<=20)
dmg += 4;
else if(cha.getTotalDex()<=23)
dmg += 5;
else if(cha.getTotalDex()<=26)
dmg += 6;
else if(cha.getTotalDex()<=29)
dmg += 7;
else if(cha.getTotalDex()<=32)
dmg += 8;
else if(cha.getTotalDex()<=35)
dmg += 9;
else if(cha.getTotalDex()<=39)
dmg += 10;
else if(cha.getTotalDex()<=43)
dmg += 11;
else
dmg += 12;

// 순수에따른 데미지 추가
dmg += toOriginalStatBowDamage(cha);

// 레벨에 따른 추타
switch(cha.getClassType()){
case Lineage.LINEAGE_CLASS_ELF:
dmg += cha.getLevel() / 10;
break;
}
}else{
// 근접무기일경우
// 순수스탯에 따른 보너스
if(cha.getClassType() == Lineage.LINEAGE_CLASS_KNIGHT)
dmg += Util.random(0, cha.getLevel()/10);
// 스탯에따른 +@ 데미지
if(cha.getTotalStr()<=8)
dmg -= 2;
else if(cha.getTotalStr()<=10)
dmg -= 1;
else if(cha.getTotalStr()<=12)
dmg += 0;
else if(cha.getTotalStr()<=14)
dmg += 1;
else if(cha.getTotalStr()<=16)
dmg += 2;
else if(cha.getTotalStr()<=18)
dmg += 3;
else if(cha.getTotalStr()<=20)
dmg += 4;
else if(cha.getTotalStr()<=22)
dmg += 5;
else if(cha.getTotalStr()<=25)
dmg += 6;
else if(cha.getTotalStr()<=28)
dmg += 7;
else if(cha.getTotalStr()<=30)
dmg += 8;
else if(cha.getTotalStr()<=32)
dmg += 9;
else if(cha.getTotalStr()<=33)
dmg += 10;
else if(cha.getTotalStr()<=34)
dmg += 11;
else if(cha.getTotalStr()<=38)
dmg += 12;
else if(cha.getTotalStr()<=42)
dmg += 13;
else if(cha.getTotalStr()<=46)
dmg += 14;
else if(cha.getTotalStr()<=48)
dmg += 15;
else if(cha.getTotalStr()<=49)
dmg += 16;
else
dmg += 17;

// 순수에따른 데미지 추가
dmg += toOriginalStatDamage(cha);

// 레벨에 따른 추타
switch(cha.getClassType()){
case Lineage.LINEAGE_CLASS_KNIGHT:
case Lineage.LINEAGE_CLASS_DARKELF:
case Lineage.LINEAGE_CLASS_DRAGONKNIGHT:
case Lineage.LINEAGE_CLASS_BLACKWIZARD:
dmg += cha.getLevel() / 10;
break;
}
}
// 경험치 획득 페널티 부분에서 데미지 추가 혜택 적용 (본섭도 이와 같은 상황)
if(cha.getLevel()>65 && cha.getLevel()<70){
dmg += 1;
}else if(cha.getLevel()>69 && cha.getLevel()<75){
dmg += 2;
}else if(cha.getLevel()>74 && cha.getLevel()<80){
dmg += 3;
}else if(cha.getLevel()>=80){
dmg += 4;
}
return dmg;
}

/**
* 공격 성공여부 처리
*/
static private boolean isHitFigure(Character cha, object target, boolean bow, ItemInstance weapon){
int basic_flee = 0; // 기본이되는 공격성공율
int target_flee = 0; // 타켓에 방어력 및 er에따른 회피율
int max_flee = 99;
int min_flee = 0;

// 클레스별
basic_flee += toHitLv(cha);

// 무기 인첸
if(weapon != null)
basic_flee += weapon.getEnLevel();

// 무기 옵션
if(weapon != null)
basic_flee += weapon.getItem().getAddHit();

// 스탯에 따른 보정
basic_flee += toHitDex(cha) + toHitStr(cha);

if(bow){
// 활착용상태라면
basic_flee += toOriginalStatBowHit(cha) + cha.getDynamicAddHitBow();
if(target instanceof Character){
// 활공격시 타켓에 er값을 추출함.
Character c = (Character)target;
// 근접 공격보다 장거리 공격이 ac에 영향을 적게 받게 함.
target_flee += c.getTotalAc()<=0 ? 0 : c.getTotalAc() / 6;
// er값을 추출함.
target_flee += getEr(c) + toOriginalStatER(c) + c.getDynamicEr();
}
// 윈드샷 상태일때 공격 성공률 적용 (활 공격에만 적용)
if(cha.isBuffWindShot())
basic_flee += 6;
// 스톰샷 상태일때 공격 성공률 적용 (활 공격에만 적용)
if(cha.isBuffStormShot())
basic_flee -= 1;
// 아이오브스톰
if(cha.isBuffEyeOfStorm())
basic_flee += 2;
// 글로잉오라
if(cha.isBuffGlowingAura())
basic_flee += 1;
// 마법인형 : 코카트리스
if(cha.isMagicdollCockatrice())
basic_flee += 1;
// 마법인형 : 허수아비
if(cha.isMagicdollCracker())
basic_flee += 2;
// 레벨에따른 명중
switch(cha.getClassType()){
case Lineage.LINEAGE_CLASS_ELF:
basic_flee += cha.getLevel() / 5;
break;
}
}else{
// 근접무기착용상태라면
basic_flee += toOriginalStatHit(cha) + cha.getDynamicAddHit();
if(target instanceof Character){
// 근거리공격시 타켓에 ac따른 값 추출
Character c = (Character)target;
target_flee += c.getTotalAc()<=0 ? 0 : c.getTotalAc() / 3;

// 상대 레벨에따른 감소처리부분
if(c.getLevel() >= cha.getLevel()+5)
target_flee += c.getLevel() - (cha.getLevel()+5);

target_flee += c.getDynamicDg();
}
// 버닝웨폰 상태일때 공격 성공률 적용 (활이 아닌 경우)
if(cha.isBuffBurningWeapon())
basic_flee += 3;
// 레벨에따른 명중
switch(cha.getClassType()){
case Lineage.LINEAGE_CLASS_KNIGHT:
case Lineage.LINEAGE_CLASS_DARKELF:
basic_flee += cha.getLevel() / 3;
break;
case Lineage.LINEAGE_CLASS_DRAGONKNIGHT:
basic_flee += cha.getLevel() / 4;
break;
case Lineage.LINEAGE_CLASS_ELF:
case Lineage.LINEAGE_CLASS_BLACKWIZARD:
basic_flee += cha.getLevel() / 5;
break;
}
}

// 블레스웨폰 상태일때 공격 성공률 증가 적용
if(weapon!=null && ((ItemWeaponInstance)weapon).isBuffBlessWeapon())
basic_flee += 2;
// 위크니스 상태일때 공격 성공률 감소 적용
if(cha.isBuffWeakness())
basic_flee -= 1;
// 홀리써클 상태일때 공격 성공률 증가 적용
// if(buff->findMagic(52))
// basic_flee += 2;
// 디지즈 상태일때 공격 성공률 감소 적용
if(cha.isBuffDisease())
basic_flee -= 6;
// 마법인형 : 허수아비
if(cha.isMagicdollCracker())
basic_flee += 2;

// 최대치 확인.
if(max_flee < target_flee)
target_flee = max_flee;
if(min_flee > target_flee)
target_flee = min_flee;
// 최대치 확인.
if(max_flee < basic_flee)
basic_flee = max_flee;
if(min_flee > basic_flee)
basic_flee = min_flee;

return Util.random(0, target_flee) <= Util.random(0, basic_flee);
}

/**
* 클레스별 추가 타격치 +@ 리턴
*/
static private double toOriginalStatDamage(Character cha){
double sum = 0;
int str = cha.getStr() + cha.getLvStr();
switch(cha.getClassType()){
case Lineage.LINEAGE_CLASS_ROYAL:
str -= 13;
sum += str/3;
break;
case Lineage.LINEAGE_CLASS_KNIGHT:
str -= 16;
sum += str/2;
break;
case Lineage.LINEAGE_CLASS_ELF:
str -= 11;
sum += str/2.5;
break;
case Lineage.LINEAGE_CLASS_WIZARD:
str -= 8;
sum += str/2;
break;
default:
break;
}
return sum;
}

/**
* 클레스별 활추가데미지 +@ 리턴
*/
static private double toOriginalStatBowDamage(Character cha){
double sum = 0;
int dex = cha.getDex() + cha.getLvDex();
switch(cha.getClassType()){
case Lineage.LINEAGE_CLASS_ROYAL:
dex -= 10;
sum += dex/3;
break;
case Lineage.LINEAGE_CLASS_KNIGHT:
break;
case Lineage.LINEAGE_CLASS_ELF:
dex -= 12;
sum += dex/2;
break;
case Lineage.LINEAGE_CLASS_WIZARD:
break;
}
return sum;
}

/**
* 클레스별 공격 성공율 +@ 리턴
*/
static private int toOriginalStatHit(Character cha){
int sum = 0;
int str = cha.getStr() + cha.getLvStr();
switch(cha.getClassType()){
case Lineage.LINEAGE_CLASS_ROYAL:
str -= 13;
if(str>=3){
sum += 1;
}
if(str>=6){
sum += 1;
}
break;
case Lineage.LINEAGE_CLASS_KNIGHT:
str -= 16;
if(str>=1){
sum += 2;
}
if(str>=3){
sum += 2;
}
break;
case Lineage.LINEAGE_CLASS_ELF:
str -= 11;
if(str>=2){
sum += 1;
}
if(str>=4){
sum += 1;
}
break;
case Lineage.LINEAGE_CLASS_WIZARD:
str -= 8;
if(str>=3){ 
sum += 1;
}
if(str>=5){ 
sum += 1;
}
break;
}
return sum;
}

/**
* 힘에 따른 공격성공율 +@ 리턴
*/

static private int toHitStr(Character cha){
int[] strHit = { -2, -2, -2, -2, -2, -2, -2,
-2, -1, -1, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6,
7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 12,
13, 13, 13, 14, 14, 14, 15, 15, 15, 16, 16, 16, 17, 17};

try {
if(cha.getTotalStr() > 59)
return strHit[58];
else
return strHit[cha.getTotalStr()-1];
} catch (Exception e) {
return 0;
}
}

/**
* 덱스에 따른 활 전용 공격성공율 +@ 리턴
*/
static private int toHitDex(Character cha){
int[] dexHit = { -2, -2, -2, -2, -2, -2, -1, -1, 0, 0,
1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 19, 19, 20, 20, 20, 21, 21, 21, 22, 22, 22, 23,
23, 23, 24, 24, 24, 25, 25, 25, 26, 26, 26, 27, 27, 27, 28 };

try {
if(cha.getTotalDex() > 60)
return dexHit[59];
else
return dexHit[cha.getTotalDex()-1];
} catch (Exception e) {
return -1;
}
}

/**
* 레벨에 따른 공격성공율 +@ 리턴
*/
static private int toHitLv(Character cha){
return cha.getLevel();
}

/**
* 클레스별 활명중률 +@ 리턴
*/
static private int toOriginalStatBowHit(Character cha){
int sum = 0;
int dex = cha.getDex() + cha.getLvDex();
switch(cha.getClassType()){
case Lineage.LINEAGE_CLASS_ROYAL:
break;
case Lineage.LINEAGE_CLASS_KNIGHT:
break;
case Lineage.LINEAGE_CLASS_ELF:
dex -= 12;
if(dex>=1){
sum += 2;
}
if(dex>=4){
sum += 1;
}
break;
case Lineage.LINEAGE_CLASS_WIZARD:
break;
}
return sum;
}

/**
* 장거리 공격 회피율 리턴
*/
static private int getEr(Character cha){
// 8부터 +1된값만큼 1씩 증가함.
// 레벨 10부터 1씩 증가함.
int er = 0;
if(cha.getTotalDex()<8)
er = -1;
else
er = (cha.getTotalDex()-8) / 2;
er += cha.getLevel() / 10;
return er;
}

/**
* 클레스별 ER +@ 리턴
*/
static private int toOriginalStatER(Character cha){
int sum = 0;
int dex = cha.getDex() + cha.getLvDex();
switch(cha.getClassType()){
case Lineage.LINEAGE_CLASS_ROYAL:
dex -= 10;
if(dex>=4)
sum += 1;
if(dex>=6)
sum += 1;
if(dex>=8)
sum += 1;
break;
case Lineage.LINEAGE_CLASS_KNIGHT:
dex -= 12;
if(dex>=2){
sum += 1;
}
if(dex>=4){
sum += 2;
}
break;
case Lineage.LINEAGE_CLASS_ELF:
break;
case Lineage.LINEAGE_CLASS_WIZARD:
dex -= 7;
if(dex>=2){
sum += 1;
}
if(dex>=4){
sum += 1;
}
break;
}
return sum;
}

/**
* 요정 클레스 요숲경비병에게 도움처리 함수.
*  : 요정은 요숲에서 사냥시 근처 요숲경비가잇을경우 도움을 줌.
*/
static private void toElven(PcInstance pc, object o){
if(pc.getClassType()==Lineage.LINEAGE_CLASS_ELF && o instanceof MonsterInstance && !(o instanceof SummonInstance)){
for(object inside : pc.getInsideList()){
if(inside instanceof ElvenGuard)
inside.toDamage((Character)o, 0, Lineage.ATTACK_TYPE_DIRECT);
}
}
}

/**
* 근처 경비병에게 도움요청처리하는 함수.
*  : 다른 놈에게 pk를 당하거나 할때 처리하는 함수.
* @param pc : 요청자
* @param cha : 공격자
*/
static public void toGuardHelper(PcInstance pc, Character cha){
// 요청자가 카오라면 무시.
if(pc.getLawful() < Lineage.NEUTRAL)
return;
// 요청자가 보라돌이 상태라면 무시. 단! 가격자가 카오가 아닐때만.
if(pc.isBuffCriminal() && cha.getLawful()>=Lineage.NEUTRAL)
return;
// 사용자가 가격햇고 노말존에 잇엇을경우.
if(World.isNormalZone(pc.getX(), pc.getY(), pc.getMap())){
for(object inside : pc.getInsideList()){
if(inside instanceof GuardInstance)
inside.toDamage(cha, 0, Lineage.ATTACK_TYPE_DIRECT);
}
}
}

/**
* 해당 몬스터가 언데드 인지 확인해주는 함수.
* @param mon
* @return
*/
static private boolean isUndeadDamage(Character cha) {
if(cha instanceof MonsterInstance){
MonsterInstance mon = (MonsterInstance)cha;
return mon.getMonster().getResistanceUndead()<0 && ServerDatabase.isNight();
}
return false;
}





}




힘이 8일 경우는 안박히고요. 힘이 9~11은 되어야 박힙니다.
지팡이 공성10으로 올려도 안박혀요
맨손은 잘박히는데 무기만 착용하면 안박히네요.

관련자료

댓글 0
등록된 댓글이 없습니다.
전체 10 / 1 페이지
번호
제목
이름

포인트 랭킹


알림 0