샵봇 내장하기
분류
봇관련
조회 수
1,771
추천 수
12
날아다녀님 버전에는 샵봇이 있는 것으로 알고 있지만 날아다녀님 스크립트는 너무 코드가 방대하여 간혹 나만의 필요에 따라 수정하고 싶어도 엄두가 나지 않아 헤븐리님의 원본을 조금씩 수정하고 쓰고있읍니다.
이 수정은 별도의 샵봇을 돌리지 않고 봇이 마을에서 NPC를 만날 때마다 그 NPC가 파는 아이템 중에서 이니에 포함되는 것을 사는 수정입니다. 특히 오리는 팔라의 셉터처럼 상점아이템도 유용하게 쓰이는 경우가 있어 어차피 돌아가는 봇에 상점 기능을 추가하면 좋겠다고 생각했읍니다.
수정은 날아다녀님 샵봇 코드와 헤븐리님의 원본에서 갬블 부분을 적절히 이용하여 작성하였읍니다.
갬블 등의 코드는 NTTown.ntl에 포함되어 있으므로 샵함수도 NTTown.ntl 안에 작성하는 것이 좋습니다. 일단 기본 샵 함수입니다.
function NTT_Shopping(npc)
{
if(!npc) return 1;
if(!GetUIState(0x0C)) return 1;
var i;
var _item = npc.GetItems(); if(!_item) return 1;
for(i = 0; i < _item.length; i++) {
//ignore pots
if(_item[i].itemtype == 76 || _item[i].itemtype == 77) continue;
if(!NTSI_CheckItem(_item[i])) continue;
if(_item[i].GetItemCost(0, npc.classid) > NTC_MyGold()) return 2;
if(!NTT_CheckSpace(_item[i].xsize, _item[i].ysize)) return 3;
NTT_GetOldItemsInt();
if(NTT_ShopItem(_item[i], npc, 2)) {
var _newitem = NTT_GetGambledItemInt();
if(_newitem) NTC_SendLogToOOG(NTC_LOG_ITEM, "Kept " + NTC_ItemQualityToMGRColor[_newitem.quality] + _newitem.name.split("\n")[0] + ";" + _newitem.itemdesc);
}
else return 4;
}
return 0;
}
이 부분을 복사하여 NTTown.ntl 파일 끝에 추가하시면 됩니다. NTT_Shopping 함수를 정의하였으면 이제 NTTownManager.ntl 파일을 엽니다. 이 안에는 NPC와의 소통하는 모든 함수가 들어 있읍니다. 따라서 각 NPC와의 소통 함수를 편집합니다.
예를 들어 액1 아카라의 경우입니다.
function NTTMGR_VisitAkara()
.
.
if(NTT_DoInteract(_npc)) {
if(_NTTMGR_BuyPots || _NTTMGR_BuyTP || _NTTMGR_BuyKey || _NTTMGR_DoID) {
if(NTT_DoTrade(_npc)) {
if(_NTTMGR_BuyPots) NTT_FillBelt(_npc);
if(_NTTMGR_BuyTP) NTT_FillTome(_npc, 1);
if(_NTTMGR_BuyKey) NTT_FillKey(_npc);
if(_NTTMGR_DoID) NTTMGR_IDItems(_npc);
NTT_Shopping(_npc); // 추가
}
}
else { //추가
if(NTT_DoTrade(_npc)) NTT_Shopping(_npc); //추가
} //추가
me.Cancel(1);
}
.
.
추가 부분을 잘 보면 NPC와 DoInteract한 다음 포션구입, 포탈구입, 키구입, 미확아템확인 등의 필요가 있으면 NPC와 DoTrade합니다. 이 때 끝 부분에 NTT_Shopping를 끼워 넣으면 됩니다. 그 밑의 else 부분은 봇이 단지 피회복이나 저주를 풀기 위해 아카라를 만나는 경우로 아카라와 트레이드를 하지 않는 경우에도 샵핑은 하라고 집어 넣은 것입니다.
그러면 각 NPC 함수들입니다.
function NTTMGR_VisitCharsi()
.
.
if(NTT_DoTrade(_npc)) {
NTT_RepairItems(_npc);
NTT_Shopping(_npc); // 추가
}
.
function NTTMGR_VisitGheed()
.
.
while(NTC_MyGold() > NTConfig_GambleStopGold) {
if(NTT_DoInteract(_npc)) {
if(NTT_DoTrade(_npc, 1)) NTT_GambleIt(_npc);
me.Cancel(1);
}
else break;
}
if(NTT_DoInteract(_npc)) { //추가
if(NTT_DoTrade(_npc)) NTT_Shopping(_npc); //추가
me.Cancel(1); //추가
} //추가
기드의 경우 갬블 창과 트레이드 창이 다르므로 갬블이 끝나면 다시 DoInteract, DoTrade 하여야 합니다.
function NTTMGR_VisitFara()
.
.
if(NTT_DoInteract(_npc)) {
if(_NTTMGR_DoRepair) {
if(NTT_DoTrade(_npc)) {
if(_NTTMGR_DoRepair) NTT_RepairItems(_npc);
NTT_Shopping(_npc); //추가
}
}
me.Cancel(1);
}
function NTTMGR_VisitDrognan()
.
.
if(NTT_DoInteract(_npc)) {
if(NTT_DoTrade(_npc)) {
if(_NTTMGR_BuyPots) NTT_FillBelt(_npc);
if(_NTTMGR_BuyTP) NTT_FillTome(_npc, 1);
if(_NTTMGR_DoID) NTTMGR_IDItems(_npc);
NTT_Shopping(_npc); //추가
}
me.Cancel(1);
}
function NTTMGR_VisitLysander()
.
.
if(NTT_DoInteract(_npc)) {
if(NTT_DoTrade(_npc)) {
NTT_FillKey(_npc);
NTT_Shopping(_npc); //추가
}
me.Cancel(1);
}
function NTTMGR_VisitElzix()
.
.
while(NTC_MyGold() > NTConfig_GambleStopGold) {
if(NTT_DoInteract(_npc)) {
if(NTT_DoTrade(_npc, 1)) NTT_GambleIt(_npc);
me.Cancel(1);
}
else break;
}
if(NTT_DoInteract(_npc)) { // 추가
if(NTT_DoTrade(_npc)) NTT_Shopping(_npc); //추가
me.Cancel(1); //추가
} //추가
function NTTMGR_VisitOrmus()
.
.
if(NTT_DoInteract(_npc)) {
if(_NTTMGR_BuyPots || _NTTMGR_BuyTP || _NTTMGR_DoID) {
if(NTT_DoTrade(_npc)) {
if(_NTTMGR_BuyPots) NTT_FillBelt(_npc);
if(_NTTMGR_BuyTP) NTT_FillTome(_npc, 1);
if(_NTTMGR_DoID) NTTMGR_IDItems(_npc);
NTT_Shopping(_npc); //추가
}
}
me.Cancel(1);
}
function NTTMGR_VisitHratli()
.
.
if(NTT_DoInteract(_npc)) {
if(NTT_DoTrade(_npc)) {
if(_NTTMGR_DoRepair) NTT_RepairItems(_npc);
if(_NTTMGR_BuyKey) NTT_FillKey(_npc);
NTT_Shopping(_npc); //추가
}
me.Cancel(1);
}
function NTTMGR_VisitAlkor()
.
.
while(NTC_MyGold() > NTConfig_GambleStopGold) {
if(NTT_DoInteract(_npc)) {
if(NTT_DoTrade(_npc, 1)) NTT_GambleIt(_npc);
me.Cancel(1);
}
else break;
}
if(NTT_DoInteract(_npc)) { // 추가
if(NTT_DoTrade(_npc)) NTT_Shopping(_npc); //추가
me.Cancel(1); //추가
} //추가
function NTTMGR_VisitJamella(gamble)
.
.
if(gamble) {
while(NTC_MyGold() > NTConfig_GambleStopGold) {
if(NTT_DoInteract(_npc)) {
if(NTT_DoTrade(_npc, 1)) NTT_GambleIt(_npc);
me.Cancel(1);
}
else break;
}
}
else {
if(NTT_DoInteract(_npc)) {
if(_NTTMGR_BuyPots || _NTTMGR_BuyTP || _NTTMGR_BuyKey || _NTTMGR_DoID) {
if(NTT_DoTrade(_npc)) {
if(_NTTMGR_BuyPots) NTT_FillBelt(_npc);
if(_NTTMGR_BuyTP) NTT_FillTome(_npc, 1);
if(_NTTMGR_BuyKey) NTT_FillKey(_npc);
if(_NTTMGR_DoID) NTTMGR_IDItems(_npc);
NTT_Shopping(_npc); //추가
}
}
me.Cancel(1);
}
}
function NTTMGR_VisitHalbu()
.
.
if(NTT_DoInteract(_npc)) {
if(NTT_DoTrade(_npc)) {
NTT_RepairItems(_npc);
NTT_Shopping(_npc); //추가
}
me.Cancel(1);
}
function NTTMGR_VisitMalah()
{
.
.
if(NTT_DoInteract(_npc)) {
if(_NTTMGR_BuyPots || _NTTMGR_BuyTP || _NTTMGR_BuyKey || _NTTMGR_DoID) {
if(NTT_DoTrade(_npc)) {
if(_NTTMGR_BuyPots) NTT_FillBelt(_npc);
if(_NTTMGR_BuyTP) NTT_FillTome(_npc, 1);
if(_NTTMGR_BuyKey) NTT_FillKey(_npc);
if(_NTTMGR_DoID) NTTMGR_IDItems(_npc);
NTT_Shopping(_npc); //추가
}
}
me.Cancel(1);
}
function NTTMGR_VisitLarzuk()
.
.
if(NTT_DoInteract(_npc)) {
if(NTT_DoTrade(_npc)) {
NTT_RepairItems(_npc);
NTT_Shopping(_npc); //추가
}
me.Cancel(1);
}
function NTTMGR_VisitAnya()
.
.
while(NTC_MyGold() > NTConfig_GambleStopGold) {
if(NTT_DoInteract(_npc)) {
if(NTT_DoTrade(_npc, 1)) NTT_GambleIt(_npc);
me.Cancel(1);
}
else break;
}
if(NTT_DoInteract(_npc)) { // 추가
if(NTT_DoTrade(_npc)) NTT_Shopping(_npc); //추가
me.Cancel(1); //추가
} //추가
함수의 구조는 대략 회복NPC, 거래NPC, 갬블NPC로 나누어지는데 두 가지 이상의 기능을 하는 NPC 함수는 약간 복잡해질 수도 있읍니다. 자멜라의 경우처럼. 어차피 자멜라는 자주 만나러 가는 캐릭이니 갬블할 때 굳이 거래창을 열 필요가 없다고 생각하여 갬블 끝나고 거래창 열지 않습니다.
고칠 부분이 조금 많기는 하지만 방식은 거의 비슷하니 수정에 큰 문제 없으리라 생각합니다. 특히 오리에서 봇 돌리는 분들에게 도움이 되기를 바랍니다.