[수정]봇순이 혹사시키기? 시간죽이기 또는 간식먹기.. 공격입니다.
분류
봇관련
조회 수
2,631
추천 수
1
무지 죄송합니다. 소스 수정했습니다. 정확한 정보를 올려야 하는데.. 규칙과 다르게 돌아가는 버그가 있는 소스를 올렸더군요.
이미 소스긁어서 적용하신분 다시한번 아래 소스부분 긁어서 적용해 주시기 바랍니다.
아래 어떤분이 "take snake!!" 가 가끔 보이신다길래 에리어 클리어부분에선 거의 매번 보여야 할텐데... 하면서 자세히 들여다 봤더니 이전소스에 문제가 좀 있었더군요. 이거 만들때 getUnit함수 사용시 무한루프 문제로 고민하고 있었던게 있어서 미쳐 주변몹 찻는부분 수정을 못하고 방치했네요.
그래서 과감히 리펙토링했습니다.
보시면 아시겟지만 간식먹기용 주변몹찻는 부분을 _TK_getTimeKillingMonster함수로 들어내 버려서 본체가 무지 짧아졌고 찻기규칙도 정확하게 적용됩니다.
다시한번 말씀드리지만 이미 긁어서 적용하신분 무지 죄송합니다.
----------------------------------------------------------------------------------------------------------------
디아블로네님의 D2JSP_1.1.4+XP.bot_Avenger.Ver4.0 용입니다. 파이널도 가능하지 않을까 합니다만...
봇순이 혹사시키기? 일명 시간죽이기 또는 간식먹기.. 공격입니다.
정확한 용도는 파볼오브 소서인 경우 타겟으로 잡힌 몹이 파이어내성일때 오브만 날리고 있죠. 주변에 파이어내성이 아닌넘이 있어도 타겟으로 잡힌 넘때문에 계속 오브만 날리면서 놀죠. 아시다시피 오브는 딜레이 시간이 있고.. 그 딜레이 시간이 파볼 약 5번 쏠 정도 됩니다.
그래서 그 놀고 있는 꼴을 못봐줘서 그시간에 간식용으로 주변에 원 타겟이 아닌넘중에 파볼내성이 아닌넘이 있으면 그넘 파볼로 쏘는것입니다.
간식용타겟을 잡는 규칙은 아래와 같습니다.
1. 타겟이 딜레이 있는 기술만 써야 할 내성일때(즉 타겟이 딜레이 없는 기술의 이뮨일때)
2. 우선 캐릭터 주변에 딜레이 없는 기술의 내성이 아닌넘이 있나본다. 있으면 5번으로 건너뜀.
3. 캐릭터 주변에 없으면 용병주변을 살핀다. 있으면 5번으로 건너뜀.
4. 전체 서치범위를 살핀다. 있으면 5번으로 건너뜀. 없으면 7번으로 건너뜀.
5. 2,3,4중에 하나라도 걸린넘이 있으면 그넘을 간식용타겟으로 잡고 딜레이 없는 기술을 최대 5번을 쏘는데 죽으면 그만둔다.
6. 1번으로 돌아간다.
7. 주변에 없다. 그냥 1번으로 간다.
![[수정]봇순이 혹사시키기? 시간죽이기 또는 간식먹기.. 공격입니다. - 1](http://image.durune.com/_data/2006061723160296.jpg)
스샷보면 이마에 "N target!! ID = 21"이라고 서 붙이고 있는넘 이넘은 원타겟입니다. 스샷 위쪽 중앙에 타겟으로 "DEVILKIN"으로 잡고 있고 아래에 파이어이뮨이라고 쓰여진거 보일겁니다. 피트에 있는 이넘은 파이어내성이죠. 그런데 주변에 파이어내성이 아닌넘(저넘 이름은 모르겟습니다.) 이마에 "take snake!!" 라고 붙인넘이 바로 간식용타겟으로 잡힌넘입니다. 방향이 좀 이상하긴 하다만 여튼 파볼 날리는게 보일겁니다.
저넘이 주변에서 얼쩡거리며 함 싸워보겟다고 덤비다가 간식거리가 된거지요.
이것을 쓸때는 반드시 캐릭컨피그 설정에서 소서기술중에 서로 다른 내성으로 딜레이있는 기술과 없는기술이 지정되어야 합니다. 오브파볼이 가장 좋은예지요. 아니면.. 아마 라이트링기술이 대부분 딜레이가 없는걸로 알고 있습니다만.. 이경우는 오브,라이트닝기술 또는 메테오, 라이트닝기술 조합이겟군요.
이걸쓰니 의외로 효과가 좋더군요. 시간도 조금 빨리 끝날뿐만 아니라 약한넘 오브로 잡느라 주변에 강한넘 와도 대처를 못했는데 그런점을 어느정도 해소 할 수 있습니다. 스샷에 "N Target", "R Target"이라고 보이는데 이것은 N은(Normal)이고 R은(Recursive)입니다. R은 재귀호출로 주변에 싸우는넘 있음 그넘부터 먼저 잡는 모드에 걸린넘인데 이것때문에 약간 딜레이가 생기는듯해서 이 방법은 지금 알려드리지 못하겟네요.
사용법은 scripts\libs\XP\Libs\XP_AreaClearing.d2l 파일을 불러올린다음 function XP_AttackMonsterSorceress(monster,range,x,y,attackSkills) 를 찻아(한 400라인 즈음에 있습니다.) 원래것을 전체 주석처리하고(반드시) 아래것을 다 긁어서 그 위나 아래쪽에 붙여넣으십시요. 그리고 바로 실행시키시면 됩니다. 실행중에 에러가 나면 원래로 돌리고 상황을 리플이나 쪽지 주세요. 거의 한 한달정도 별문제는 없었습니다만.. 혹 제가 찻지 못한 레퍼런스에러가 있을 수 있습니다. 에러가 걸릴만한것은 다 찻아서 if (typeof(XXXXX) == "undefined")등으로 체크했습니다만.. 빠졌을 수도 있습니다.
그리고 모니터링 해보시다가 이마에 "take snake!!" 달고 나와서 얻어맞고 있으면 간식거리에 걸린것입니다.
if (typeof(XP_isDead) == "undefined")
{
// 2006년 5월 함수 추가. deer
function XP_isDead(victim)
{
if(!victim || victim.hp <= 0 || victim.mode == 12 || victim.mode == 0) return true;
return false;
}
//------------------------------------------------------------------------
}
if (typeof(XP_TownQuitMsgReceived) == "undefined")
{
// 2006년 5월 함수 추가. deer
function XP_TownQuitMsgReceived()
{
if(_XP_MercDead || _XP_OutOfPots || _XP_Town) return true;
return false;
}
//------------------------------------------------------------------------
}
if (typeof(ALIVE_MODE) == "undefined")
{
var ALIVE_MODE = (1<<29)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7)|(1<<8)|(1<<9)|(1<<10)|(1<<11)|(1<<13)|(1<<14)|(1<<15);
}
if (typeof(CAN_ATTACK) == "undefined")
{
var CAN_ATTACK = (1<<0)|(1<<1)|(1<<2)|(1<<5)|(1<<10)|(1<<11);
}
if (typeof(c_UnitType_Monster) == "undefined")
{
c_UnitType_Monster = 1;
}
// 2006년 6월 시간죽이기용 몬스터 가져오기 추가 deer
function _TK_getTimeKillingMonster(pUnit,range)
{
var TimeKilling = null;
var TK_Untimed;
var TK_MonArray;
if(pUnit == null) return TimeKilling;
TK_MonArray = pUnit.getNearUnits(range,100,c_UnitType_Monster, ALIVE_MODE,CAN_ATTACK);
for(var i = 0; i < TK_MonArray.length; i += 1)
{
TimeKilling = TK_MonArray[i];
if( DA_IsValidTarget(TimeKilling))
{
TK_Untimed = XP_SelectAttack(TimeKilling, _XP_MonsterUntimedSpells, 0);
if(TK_Untimed >= 0) break;
}
TimeKilling = null;
}
if(TimeKilling) me.TK_Untimed = TK_Untimed;
else me.TK_Untimed = -1;
TK_MonArray = null; // 쓰레기수집기(GC)에게 넘김.
return TimeKilling;
}
function XP_AttackMonsterSorceress(monster,range,x,y,attackSkills)
{
DC_DPrint("XP_AttackMonsterSorceress() : Entering attack loop!");
_XP_AttackCompleted = 0;
_XP_CurrentTimed = 0;
_XP_CurrentUntimed = 0;
// 2006년 5월 추가 deer
_TK_TimeKillingAttack = true;
var _skill;
var hand;
var hpprev = 129;
var attprev = _XP_AttackCompleted;
_XP_CurrentTimed = XP_SelectAttack(monster, _XP_MonsterTimedSpells, 0);
_XP_CurrentUntimed = XP_SelectAttack(monster, _XP_MonsterUntimedSpells, 0);
_XP_haveTimed = (_XP_CurrentTimed >= 0) ? true : false;
_XP_haveUntimed = (_XP_CurrentUntimed >= 0) ? true : false;
//Sanity check, must be at least one to attack at all - SB
if (XP_UntimedRepeat === 0) { XP_UntimedRepeat=1; }
// If we have a timed spell, cast it first
if (XP_TimedFirst && _XP_haveTimed)
{
_skill = _XP_MonsterTimedSpells[_XP_CurrentTimed];
DC_DPrint("XP_AttackMonsterSorceress() : XP_TimedFirst : Casting TimedSkill # " + _skill + " on index " + _XP_CurrentTimed);
_XP_CurrentTimed+=1;
_XP_CurrentTimed = XP_SelectAttack(monster, _XP_MonsterTimedSpells, _XP_CurrentTimed);
DC_DoCast(_skill,0,monster);
}
// 2006년 6월 루프안 아래쪽에서 밖으로 끌어올림. deer
if (!_XP_haveUntimed && !_XP_haveTimed ) { return false; }
// 2006년 6월 수정(XP_isDead) deer
while (!XP_isDead(monster) && (monster.hp < hpprev || attprev >= _XP_AttackCompleted) && DA_GetRangeXY(monster,x,y) < range)
{
// 2006년 5월 _XP_haveUntimed 조건문 안에 있는것을 이동 deer
// Go to town if one of the messages is received from LW
if (XP_TownQuitMsgReceived()) { XP_TownManager(); }
// Untimed attack
if (_XP_haveUntimed)
{
_skill = _XP_MonsterUntimedSpells[_XP_CurrentUntimed];
hand = (DC_IsLeftSkill(_skill) ? 2 : 0);
// 2006년 6월 수정(XP_isDead) deer
for (var r = 0; !XP_isDead(monster) && r < XP_UntimedRepeat; r+=1)
{
DC_DPrint("XP_AttackMonsterSorceress() Casting UntimedSkill # " + _skill + " on index " + _XP_CurrentUntimed);
if (XP_TownQuitMsgReceived()) break; // // 2006년 6월 추가 deer
DC_DoCast(_skill,hand,monster.x,monster.y);
}
if (monster.hp < hpprev)
{
hpprev = monster.hp;
attprev = _XP_AttackCompleted + 1;
}
// lLast = new Date(); // 2006년 5월 사용하는곳이 없음. deer
_XP_CurrentUntimed+=1;
_XP_CurrentUntimed = XP_SelectAttack(monster, _XP_MonsterUntimedSpells, _XP_CurrentUntimed);
}
// Timed attack.
// 2006년 5월 수정 deer
//if (_XP_haveTimed && (monster.hp > 0) && (monster.mode != 12) && (monster.mode !== 0)) {
if (!XP_TownQuitMsgReceived() && _XP_haveTimed && !XP_isDead(monster))
{
_skill = _XP_MonsterTimedSpells[_XP_CurrentTimed];
DC_DPrint("XP_AttackMonsterSorceress() : Casting TimedSkill #" + _skill + " on index " + _XP_CurrentTimed);
_XP_CurrentTimed+=1;
_XP_CurrentTimed = XP_SelectAttack(monster, _XP_MonsterTimedSpells, _XP_CurrentTimed);
DC_DoCast(_skill,0,monster);
// lLast = new Date(); // 2006년 5월 사용하는곳이 없음. deer
}
// 2006년 5월 추가 (자투리시간에 딴넘이나 공격할거나.....) deer
if(!XP_isDead(monster) && _TK_TimeKillingAttack && !XP_TownQuitMsgReceived() && !_XP_haveUntimed && _XP_haveTimed)
{
var TimeKilling;
var TK_Skill;
var TK_Hand;
var TK_Range = 10; // 주변 서치범위
TimeKilling = _TK_getTimeKillingMonster(me,TK_Range);
if(TimeKilling == null) TimeKilling = _TK_getTimeKillingMonster(DC_GetMerc(),TK_Range);
if(TimeKilling == null) TimeKilling = _TK_getTimeKillingMonster(me,range);
if(TimeKilling && me.TK_Untimed >= 0)
{
TK_Skill = _XP_MonsterUntimedSpells[me.TK_Untimed];
TK_Hand = (DC_IsLeftSkill(TK_Skill) ? 2 : 0);
TimeKilling.overhead("take snake!!!");
for (var r = 0; !XP_isDead(TimeKilling) && r < XP_UntimedRepeat; r+=1)
{
if (XP_TownQuitMsgReceived()) break;
DC_DPrint("XP_AttackMonsterSorceress() Casting TK_UntimedSkill # " + _skill + " on index " + me.TK_Untimed);
DC_DoCast(TK_Skill,TK_Hand,TimeKilling.x,TimeKilling.y);
}
}
}
// 여기까지 시간죽이기 공격 끝.
XP_CheckAttacks();
}
return true;
}