서버구축

NPC 대화 추가/수정 방법

컨텐츠 정보

본문



1. Pak Viewer.exe 를 준비해주세요 ( 자료실에 올려두겠습니다. )


2. 클라이언트에 있는 text.idx 파일을 열어주세요.


3. NPC가 사용하는 대화창은 OOO.html 로 저장됩니다. 해당 파일의 내용을 수정해주세요.


4. 서버팩 소스코드 수정할때는 각 객체(Object)의 toTalk() 함수를 구현해주면 됩니다. 

- 자동물약을 기준으로 예를 들어보겠습니다.


---


1) 서버팩 - toTalk()

public class 자동물약 extends object {

...

public void toTalk(PcInstance pc, String action, String type, ClientBasePacket cbp){

if (pc.getInventory() != null) {

if (action.equalsIgnoreCase("on"))

pc.isAutoPotion = true;

if (action.equalsIgnoreCase("off"))

pc.isAutoPotion = false;

if (action.contains("percent-")) {

try {

int percent = Integer.valueOf(action.replace("percent-", "").trim());

if (percent < 1 || percent > 99)

percent = 50;

pc.autoPotionPercent = percent;

} catch (Exception e) {

ChattingController.toChatting(pc, "[자동 물약] 체력 설정이 잘못되었습니다.", Lineage.CHATTING_MODE_MESSAGE);

}

}

if (action.contains("potion-")) {

try {

int idx = Integer.valueOf(action.replace("potion-", "").trim());

pc.autoPotionName = pc.autoPotionIdx[idx];

} catch (Exception e) {

ChattingController.toChatting(pc, "[자동 물약] 물약 설정이 잘못되었습니다.", Lineage.CHATTING_MODE_MESSAGE);

}

}

showHtml(pc);

}

}


2) 클라이언트 text.idx 의 autopotion-k.html

<body>

<p align=center><font fg=FFFF00>자동 물약</font><br>

<br>

<font fg=FFFFFF>상태:&nbsp;&nbsp;</font><font fg=ffffaf><var src="#0"></font><br>

[<a action="on">ON</font> / <a action="off">OFF</a>]<br>

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ<br>

<font fg=FFFFFF>체력: <font fg=ffffaf><var src="#1"></font></font><br>

<br>

<font fg=BDBDBD><a action="percent-90">90%</a>&nbsp;<a action="percent-80">80%</a>&nbsp;<a action="percent-70">70%</a>&nbsp;<a action="percent-60">60%</a></font><font fg=EAEAEA>&nbsp;<a action="percent-50">50%</a>&nbsp;<a action="percent-40">40%</a>&nbsp;<a action="percent-30">30%</a></font><br>

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ<br>

<font fg=FFFFFF>물약: <font fg=ffffaf><var src="#2"></font></font><br>

<br>

<font fg=FFFFFF><a action="potion-0"><var src="#3"></a></font><br>

<br>

<font fg=FFFFFF><a action="potion-1"><var src="#4"></a></font><br>

<br>

<font fg=FFFFFF><a action="potion-2"><var src="#5"></a></font><br>

<br>

<font fg=FFFFFF><a action="potion-3"><var src="#6"></a></font><br>

<br>

<font fg=FFFFFF><a action="potion-4"><var src="#7"></a></font><br>

<br>

<font fg=FFFFFF><a action="potion-5"><var src="#8"></a></font><br>

...



간단하게 정리하면, 클라이언트 text.idx 에 저장되어 있는 *-k.html 을 packviewer.exe 로 수정한다.

만약 새로운 *-k.html 을 추가하고자 하는 경우 클라이언트 폴더 안에 text 폴더안에 새로운 *-k.html 을 추가하고 묶는다.


이후 코드는 팩에 따라 다르겠지만 PC의 경우 PCInstance 의 totalk에 코드를 추가하고 NPC 또는 다른 인스턴스의 경우

각각의 인스턴스의 totalk 에 html action 에 맞는 코드를 추가해주면 됩니다.


제가 최근에 F1 단축키에 자동판매, 자동물약등 연동하면서 이해한 내용 정리하였습니다.



추가적으로 동일한 형태로 개발되는 옆동네에 올라온 자돌스킬 코드 추가하는 방법도 첨부합니다. (출처: 옆동네 서약님)


조금이나마 도움이 되었으면 합니다. 

---------------------------------------------------------------------------------------------


lineage.world.object.instance 안에 PcInstance.java 파일을 수정해주시면됩니다. 1. 자동스킬 넣을 클레스함수 추가하기. public boolean is_auto_경험치100; // (약300번대줄 밑에넣어주면됩니다.) 이런씩으로 넣고싶은 클레스 함수 만들어서넣어주세요. 2. showAutobuff() 검색. 밑에 이런씩으로 붙여넣기. 1번에 내가 새로만든 온오프버튼 클레스함수가있으면 그거 넣으시면됩니다. Manachekc1.add(새로만든클레스함수 ? "ON" : "OFF"); // << 클레스함수 온오프부분 public void showAutobuff() { try { List<String> Manachekc1 = new ArrayList<String>(); Manachekc1.clear(); Manachekc1.add(is_auto_skill ? "ON" : "OFF"); Manachekc1.add(autoMPPercent < 1 ? "설정 X" : String.format("%d%% 이상 스킬 사용", autoMPPercent)); for (int i = 0; i < Lineage.auto_hunt_mp_list.size(); i++) { Manachekc1.add(String.format("%d%%", Lineage.auto_hunt_mp_list.get(i))); if (i > 6) { break; } } for (int i = 0; i < 7 - Lineage.auto_hunt_mp_list.size(); i++) { Manachekc1.add(" "); } Manachekc1.add(is_auto_haste ? "ON" : "OFF"); // 자동촐기 온오프부분 / html번호 9번 Manachekc1.add(is_auto_haste_buy ? "ON" : "OFF"); // 촐기구매 온오프부분 / html번호 10번 Manachekc1.add(is_auto_bravery ? "ON" : "OFF"); // 자동용기 온오프부분 / html번호 11번 Manachekc1.add(is_auto_bravery_buy ? "ON" : "OFF"); // 용기구매 온오프부분 / html번호 12번 Manachekc1.add(is_auto_poly ? "ON" : "OFF"); // 자동변신 온오프부분 / html번호 13번 Manachekc1.add(is_auto_poly_buy ? "ON" : "OFF"); // 변신구매 온오프부분 / html번호 14번 Manachekc1.add(is_auto_buff ? "ON" : "OFF"); // 자동버프 온오프부분 / html번호 15번 Manachekc1.add(is_auto_경험치100 ? "ON" : "OFF"); // 경험치100%물약 온프부분 / html번호 16번 Manachekc1.add(is_auto_경험치2배 ? "ON" : "OFF"); // 경험치2배물약 온오프부분 / html번호 17번 switch (getClassType()) { case Lineage.LINEAGE_CLASS_KNIGHT: //기사일 경우 클라이언트 huntbuffl1.html을 불러옴 toSender(S_Html.clone(BasePacketPooling.getPool(S_Html.class), this, "huntbuffl1", null, Manachekc1)); // 클라 html 파일명 이건 huntbuffl1 < 이게 파일명임 break; case Lineage.LINEAGE_CLASS_ROYAL: //군주일 경우 클라이언트 huntbuffl2.html을 불러옴 toSender(S_Html.clone(BasePacketPooling.getPool(S_Html.class), this, "huntbuffl2", null, Manachekc1)); // 클라 html 파일명 break; case Lineage.LINEAGE_CLASS_ELF: //요정일 경우 클라이언트 huntbuffl3.html을 불러옴 Manachekc1.add(is_auto_정령옥 ? "ON" : "OFF"); // 정령옥구매 온오프부분 / html번호 18번 Manachekc1.add(is_auto_은화살 ? "ON" : "OFF"); // 은화살구매 온오프부분 / html번호 19번 Manachekc1.add(is_auto_오리하루콘화살 ? "ON" : "OFF"); // 오리하루콘화살구매 온오프부분 / html번호 20번 Manachekc1.add(is_auto_블랙미스릴화살 ? "ON" : "OFF"); // 블랙미스릴화살구매 온오프부분 / html번호 21번 toSender(S_Html.clone(BasePacketPooling.getPool(S_Html.class), this, "huntbuffl3", null, Manachekc1)); // 클라 html 파일명 break; case Lineage.LINEAGE_CLASS_WIZARD: //법사일 경우 클라이언트 huntbuffl4.html을 불러옴 Manachekc1.add(is_auto_마력의돌 ? "ON" : "OFF"); // 마력의돌 온오프부분 / html번호 18번 toSender(S_Html.clone(BasePacketPooling.getPool(S_Html.class), this, "huntbuffl4", null, Manachekc1)); // 클라 html 파일명 break; case Lineage.LINEAGE_CLASS_DARKELF: //다엘일 경우 클라이언트 huntbuffl5.html을 불러옴 Manachekc1.add(is_auto_흑요석 ? "ON" : "OFF"); // 흑요석구매 온오프부분 / html번호 18번 toSender(S_Html.clone(BasePacketPooling.getPool(S_Html.class), this, "huntbuffl5", null, Manachekc1)); // 클라 html 파일명 break; } } catch (Exception e) { lineage.share.System.printf("[자동 사냥] showAutobuffHtml()\r\n : %s\r\n", e.toString()); } } 3. toTalk 검색 public void toTalk(PcInstance pc, String action, String type, ClientBasePacket cbp) { else if (action.contains("buff-")) { action = action.replace("buff-", ""); if (action.equalsIgnoreCase("on")) { if (autoMPPercent < 1) { ChattingController.toChatting(this, " \\fY자동 마나 설정을 해주시기 바랍니다.", Lineage.CHATTING_MODE_MESSAGE); return; } pc.is_auto_skill = true; } else if (action.equalsIgnoreCase("off")) { pc.is_auto_skill = false; } if (action.contains("mana-")) { action = action.replace("mana-", ""); if (action.equalsIgnoreCase("1")) { if (Lineage.auto_hunt_mp_list.size() > 0) { autoMPPercent = Lineage.auto_hunt_mp_list.get(0); } } else if (action.equalsIgnoreCase("2")) { if (Lineage.auto_hunt_mp_list.size() > 1) { autoMPPercent = Lineage.auto_hunt_mp_list.get(1); } } else if (action.equalsIgnoreCase("3")) { if (Lineage.auto_hunt_mp_list.size() > 2) { autoMPPercent = Lineage.auto_hunt_mp_list.get(2); } } else if (action.equalsIgnoreCase("4")) { if (Lineage.auto_hunt_mp_list.size() > 3) { autoMPPercent = Lineage.auto_hunt_mp_list.get(3); } } else if (action.equalsIgnoreCase("5")) { if (Lineage.auto_hunt_mp_list.size() > 4) { autoMPPercent = Lineage.auto_hunt_mp_list.get(4); } } else if (action.equalsIgnoreCase("6")) { if (Lineage.auto_hunt_mp_list.size() > 5) { autoMPPercent = Lineage.auto_hunt_mp_list.get(5); } } else if (action.equalsIgnoreCase("7")) { if (Lineage.auto_hunt_mp_list.size() > 6) { autoMPPercent = Lineage.auto_hunt_mp_list.get(6); } } } else if (action.equalsIgnoreCase("흑요석")) { if(!pc.is_auto_흑요석) pc.is_auto_흑요석 = true; else pc.is_auto_흑요석 = false; } else if (action.equalsIgnoreCase("용기")) { if (!pc.is_auto_bravery) pc.is_auto_bravery = true; else pc.is_auto_bravery = false; } else if (action.equalsIgnoreCase("용기구매")) { if (!pc.is_auto_bravery_buy) pc.is_auto_bravery_buy = true; else pc.is_auto_bravery_buy = false; } else if (action.equalsIgnoreCase("촐기")) { if(!pc.is_auto_haste) pc.is_auto_haste = true; else pc.is_auto_haste = false; } else if (action.equalsIgnoreCase("촐기구매")) { if(!pc.is_auto_haste_buy) pc.is_auto_haste_buy = true; else { pc.is_auto_haste_buy = false; } } else if (action.equalsIgnoreCase("정령옥")) { if(!pc.is_auto_정령옥) pc.is_auto_정령옥 = true; else pc.is_auto_정령옥 = false; } else if (action.equalsIgnoreCase("마력의돌")) { if(!pc.is_auto_마력의돌) pc.is_auto_마력의돌 = true; else pc.is_auto_마력의돌 = false; } else if (action.equalsIgnoreCase("은화살")) { if(!pc.is_auto_은화살) { pc.is_auto_은화살 = true; pc.is_auto_오리하루콘화살 = false; pc.is_auto_블랙미스릴화살 = false; } else pc.is_auto_은화살 = false; } else if (action.equalsIgnoreCase("오리하루콘화살")) { if(!pc.is_auto_오리하루콘화살) { pc.is_auto_은화살 = false; pc.is_auto_오리하루콘화살 = true; pc.is_auto_블랙미스릴화살 = false; } else pc.is_auto_오리하루콘화살 = false; } else if (action.equalsIgnoreCase("블랙미스릴화살")) { if(!is_auto_블랙미스릴화살) { pc.is_auto_은화살 = false; pc.is_auto_오리하루콘화살 = false; pc.is_auto_블랙미스릴화살 = true; } else is_auto_블랙미스릴화살 = false; } else if (action.equalsIgnoreCase("변신")) { if(!pc.is_auto_poly) pc.is_auto_poly = true; else pc.is_auto_poly = false; } else if (action.equalsIgnoreCase("변신구매")) { if(!pc.is_auto_poly_buy) pc.is_auto_poly_buy = true; else pc.is_auto_poly_buy = false; } else if (action.equalsIgnoreCase("buff")) { if(!pc.is_auto_buff) pc.is_auto_buff = true; else pc.is_auto_buff = false; } else if (action.equalsIgnoreCase("경험치100")) { if(!pc.is_auto_경험치100) pc.is_auto_경험치100 = true; else pc.is_auto_경험치100 = false; } else if (action.equalsIgnoreCase("경험치2배")) { if(!pc.is_auto_경험치2배) pc.is_auto_경험치2배 = true; else pc.is_auto_경험치2배 = false; } showAutobuff(); } } 안에 이렇게 소스넣어주면됩니다. 새로운 클레스함수가 있다고 한다면 만들어주신 그 함수를 넣어주시면됩니다. else if (action.equalsIgnoreCase("경험치2배")) { if(!pc.is_auto_경험치2배) pc.is_auto_경험치2배 = true; else pc.is_auto_경험치2배 = false; } 이런씩으로요. 4. autoHuntbuff2 < 검색 if (is_auto_경험치100) { // is_auto_경험치100 가 온일 경우 for (ItemInstance item100 : getInventory().getList()) { // 인벤에서 아이템정보 찾아오기 if (item100.getItem().getName().contains("무한 경험치 100% 물약")) { // 인벤에 이름이 무한 경험치 100% 물약이 포함되어있는 아이템이 있을경우 if (BuffController.find(this, SkillDatabase.find(704)) == null) { // 스킬 704번 버프가 사용중이 아닐경우 ExpPotion.onBuff(this, SkillDatabase.find(704)); // 스킬 704번버프를 사용 return true; // 함수 실행을 종료하고 true를 반환. } } } for (ItemInstance item100 : getInventory().getList()) { // 인벤에서 아이템정보 찾아오기 if (item100.getItem().getName().contains("경험치 100% 물약")) { // 인벤에 이름이 경험치 100% 물약이 포함되어있는 아이템이 있을경우 if (BuffController.find(this, SkillDatabase.find(704)) == null) { // 스킬 704번 버프가 사용중이 아닐경우 ExpPotion.onBuff(this, SkillDatabase.find(704)); // 스킬 704번버프를 사용 getInventory().count(item100, item100.getCount() - 1, true); // 무한이아니기때문에 갯수를 -1씩 카운터 (즉 1개씩 사용되게) return true; // 함수 실행을 종료하고 true를 반환. } } } } 이런씩으로 스위치가 온일시 사용되게 넣어주면됩니다. 5. 클라이언트안에 html파일 넣기. huntbuffl1 ~ huntbuffl5 까지 파일을 클라이언트 text폴더안에 넣어서 업데이트 해주시면됩니다. html파일 안에 <var src="#9"> 이부분이 html번호 입니다.

 

관련자료

댓글 0
등록된 댓글이 없습니다.

서버구축

🏆 포인트 랭킹 TOP 10
순위 닉네임 포인트
1 no_profile 라프텔쪽지보내기 자기소개 아이디로 검색 전체게시물 51,240
2 no_profile Revolution쪽지보내기 자기소개 아이디로 검색 전체게시물 28,199
3 no_profile 타키야겐지쪽지보내기 자기소개 아이디로 검색 전체게시물 21,003
4 no_profile 다음쪽지보내기 자기소개 아이디로 검색 전체게시물 15,510
5 no_profile 김구빵쪽지보내기 자기소개 아이디로 검색 전체게시물 12,620
6 no_profile 0842쪽지보내기 자기소개 아이디로 검색 전체게시물 12,003
7 no_profile 파도풀쪽지보내기 자기소개 아이디로 검색 전체게시물 11,340
8 no_profile 호롤롤로쪽지보내기 자기소개 아이디로 검색 전체게시물 10,640
9 no_profile TC향기로운쪽지보내기 자기소개 아이디로 검색 전체게시물 10,540
10 no_profile 불멸의행복쪽지보내기 자기소개 아이디로 검색 전체게시물 10,200
알림 0