Skip to content
봇관련다크 모드

샵봇 내장하기

조회 수
1,795
추천 수
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 함수는 약간 복잡해질 수도 있읍니다. 자멜라의 경우처럼. 어차피 자멜라는 자주 만나러 가는 캐릭이니 갬블할 때 굳이 거래창을 열 필요가 없다고 생각하여 갬블 끝나고 거래창 열지 않습니다.

고칠 부분이 조금 많기는 하지만 방식은 거의 비슷하니 수정에 큰 문제 없으리라 생각합니다. 특히 오리에서 봇 돌리는 분들에게 도움이 되기를 바랍니다.

댓글 20
  • 댓글 #233851

    디아블러네님// 좀 오해하신 듯. 별도의 샵봇을 돌리기 싫어서 사냥봇에 내장시킨다는 것이 주 아이디어인데.
  • 댓글 #233854

    음음... 강추합니다. 아쉽던 부분이 시원해 지는군요. 좋은자료 잘 쓰겠습니다. 감사합니다.
  • 댓글 #233857

    와우 좋은자료 감사합니다 날아다녀님 1차수정본에 적용가능한가요? '헤븐리님의 원본을 조금씩 수정하고 쓰고있읍니다'라는 말이 적혀있어서요 날아다녀님껄 수정해도 문제는 없는건가요?
  • 댓글 #233860

    이미 미니 샵봇이라는 기능이 날아다녀님 추가버젼에 있습니다. 그거랑 똑같은 기능 아닌가요?
  • 댓글 #233863

    참고로 미니 샵봇은 NPC를 만날 때마다 NPC가 팔고 있는 아이템중 아이템 이니에 설정된 게 있으면 구입하는 스크립트입니다.
  • 댓글 #233869

    임털A3L님.. 초보자라.. 궁금한게 있는데.. 이렇게 함수설정을 다 해주고.... 샵에서 구매하는 아이템에 관한 이니는 어디서 적용하는가요? 그냥 아이템 스크립트 normal부분에서 이니를 추가해주어야하나요? 예를들면 아칸 100피 4솟갑을 이니추가해두면 샵에 존재할 경우 알아서 구매할까요..?
  • 댓글 #233872

    이거 좋네요 미니샵봇이 항상아쉬웠는데 지금 막 수정했는데 에러없이 잘됐으면 좋겠네요.
  • 댓글 #233884

    안녕하세요. sw_ShopActive 이게 뭔지 알수있을까요? 이 문장뜨면서 에러가 나서 지웠는데 뭔질모르겠네요.
  • 댓글 #233887

    던전도너스// 죄송합니다. 제가 수정해 쓸때는 샵을 활성화시키는 변수로 쓰던 것인데 본문에서는 빼고 쓴다는 것이 중간에 들어간 부분이 있네요. 이런 실수를 안할려고 무척 노력했는데... sw_ShopActive 변수는 정의되지 않은 변수이니 삭제하시기 바랍니다. 위에 파라 함수 부터 if(_NTTMGR_DoRepair || sw_ShopActive) { 이렇게 조건문이 있는데 여기서 || sw_ShopActive를 삭제하시면 됩니다. 이렇게요. if(_NTTMGR_DoRepair) { 모든 if문에서 || sw_ShopActive 부분을 모두 없애기 바랍니다.
  • 댓글 #233890

    디아블러네님// 제 답글에 혹 기분이 상하셨을지 신경이 쓰였는데 아주 상큼하시게 답글 달아주셨네요. 고맙습니다.
  • 댓글 #233905

    오늘두 하나 배우고 가는군요!! 감사 드리고 즐디아 하십시요!!!
권한이 없습니다.
다크 모드