summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--npc/merchants/shops.txt8
-rw-r--r--npc/merchants/socket_enchant2.txt3
-rw-r--r--npc/re/merchants/ninja_craftsman.txt351
-rw-r--r--npc/re/scripts.conf1
-rw-r--r--src/map/clif.c8
-rw-r--r--src/map/script.c31
-rw-r--r--src/map/skill.c2
7 files changed, 385 insertions, 19 deletions
diff --git a/npc/merchants/shops.txt b/npc/merchants/shops.txt
index 81125c6fd..a45ec6adb 100644
--- a/npc/merchants/shops.txt
+++ b/npc/merchants/shops.txt
@@ -282,6 +282,14 @@ OnInit:
sellitem Ice_Stone;
sellitem Wind_Stone;
sellitem Shadow_Orb;
+ sellitem Charm_Fire;
+ sellitem Charm_Ice;
+ sellitem Charm_Wind;
+ sellitem Charm_Earth;
+ if (checkre(0)){
+ sellitem Fox_Armguard;
+ sellitem Special_Ninja_Suit;
+ }
}
diff --git a/npc/merchants/socket_enchant2.txt b/npc/merchants/socket_enchant2.txt
index 08fe62ed9..afd19eba6 100644
--- a/npc/merchants/socket_enchant2.txt
+++ b/npc/merchants/socket_enchant2.txt
@@ -169,10 +169,11 @@
mes "A class? You seem to want little too much. But, no problem.";
mes "So, what kind of armor do you have?";
next;
- switch(select("Pirate Bandana:Black Leather Boots"))
+ switch(select("Pirate Bandana:Black Leather Boots"+(checkre(0)?":Special Ninja Suit":"")))
{
case 1: callfunc "Func_Socket2",2287,5350,50,61,500,985,1; // 50,61 - it's not a typo
case 2: callfunc "Func_Socket2",2425,2434,40,51,500,985,1;
+ case 3: callfunc "Func_Socket2",15053,15056,50,61,500,985,1;
}
case 4:
mes "[Leablem]";
diff --git a/npc/re/merchants/ninja_craftsman.txt b/npc/re/merchants/ninja_craftsman.txt
new file mode 100644
index 000000000..b9025f3aa
--- /dev/null
+++ b/npc/re/merchants/ninja_craftsman.txt
@@ -0,0 +1,351 @@
+//===== Hercules Script ======================================
+//= Ninja Weapon and Armor
+//===== By: ==================================================
+//= Dastgir
+//===== Current Version: =====================================
+//= 1.0
+//===== Description: =========================================
+//= Ninja Armor and Weapon Craftsman
+//===== Additional Comments: =================================
+//= 1.0 Official Conversion. [Dastgir]
+//============================================================
+que_ng,21,72,6 script Master Craftsman Gyo#arm 4_M_RASWORD,{
+ mes "[Gyo]";
+ mes "How would you define victory?";
+ mes "To fell the enemy...";
+ mes "However, the most important thing is...";
+ mes "Never to fall yourself!";
+ next;
+ mes "[Gyo]";
+ mes "For that, you must better protect yourself.";
+ mes "You cannot protect 'others' while you hinder your 'own' protection.";
+ next;
+ if (select("Combine armor.:End conversation.") == 2) {
+ mes "[Gyo]";
+ mes "Prudence is also an important virtue in battle.";
+ close;
+ }
+ switch (select("Wolf Armguard:Crescent Armguard:Ninja Scale Armor:Shadow King's Armor:Quit.")) {
+ case 1:
+ mes "[Gyo]";
+ mes "Wolf Armguard... One beastly piece of armor.";
+ next;
+ callsub L_Menu,Wolf_Armguard;
+ close;
+ case 2:
+ mes "[Gyo]";
+ mes "Crescent Armguard... A thing of beauty and strength... With none the lesser.";
+ next;
+ callsub L_Menu,Crescent_Armguard;
+ close;
+ case 3:
+ mes "[Gyo]";
+ mes "Ninja Scale Armor... It's said that a legendary Ninja once wore it.";
+ next;
+ callsub L_Menu,Ninja_Scale_Armor;
+ close;
+ case 4:
+ mes "[Gyo]";
+ mes "Shadow King's Armor... It was made to protect others.";
+ next;
+ callsub L_Menu,Tenebris_Latitantes;
+ close;
+ case 5:
+ mes "[Gyo]";
+ mes "Looks like you need more time to decide.";
+ close;
+ }
+
+L_Menu:
+ .@item_make = getarg(0);
+ while(1){
+ switch(select("Check Ingredients.:Check Stats.:Combine.:Quit.")){
+ case 1:
+ mes "[Gyo]";
+ mes "To make a ^ff0000"+getitemname(.@item_make)+", "+callsub(L_Ingredients,.@item_make)+".^000000";
+ if (.@item_make==Wolf_Armguard)
+ mes "Can you feel it? The throbbing of the wolf blood¡¦";
+ else if (.@item_make==Crescent_Armguard)
+ mes "A crescent as beautiful and clear as a crystal will be engraved on it.";
+ else if (.@item_make==Ninja_Scale_Armor)
+ mes "You can feel its legendary powers.";
+ else if (.@item_make==Tenebris_Latitantes)
+ mes "With the darkness it erases existence itself...";
+ break;
+ case 2:
+ mes "["+ getitemname(getarg(0)) +"]";
+ if (.@item_make == Wolf_Armguard){
+ mes "Chance to have 5 sec. of ATK +100, FLEE -50 upon melee attack.";
+ mes "Shield Type, Defense 45, Slot 1";
+ mes "Required Level 100, Ninja Type Only";
+ }
+ else if (.@item_make == Crescent_Armguard){
+ mes "Decreases post skill delay for 2% for every enhancement.";
+ mes "Shield Type, Defense 70, Slot 1";
+ mes "Required Level 100, Ninja Type Only";
+ }
+ else if (.@item_make == Ninja_Scale_Armor){
+ mes "MHP+15%, MSP-30%.";
+ mes "Armor Type, Defense 90, Slot 1";
+ mes "Required Level 100, Ninja Type Only";
+ }
+ else if (.@item_make == Tenebris_Latitantes){
+ mes "Chance to activate Lvl. 1 Illusion - Shadow when attacked by melee attacks.";
+ mes "Armor Type, Defense 60, Slot 1";
+ mes "Required Level 100, Ninja Type Only";
+ }
+ break;
+ case 3:
+ mes "[Gyo]";
+ mes "Make sure that ^ff0000you have the correct ingredients and equipment at hand.^000000";
+ mes "No use crying over it later.";
+ next;
+ if (select("Combine.:Quit.") == 2) {
+ mes "[Gyo]";
+ mes "Looks like you need more time to decide.";
+ close;
+ }
+ if (checkweight(1201,1) == 0 || (MaxWeight - Weight) < 2000) {
+ mes "- Hold on!! -";
+ mes "- You cannot receive items -";
+ mes "- because you carry too much. -";
+ mes "- Please try again -";
+ mes "- after lightening your burden. -";
+ close;
+ }
+ mes "[Gyo]";
+ switch(.@item_make){
+ case 2172: //Wolf_Armguard
+ if (countitem(Fox_Armguard) && countitem(Wolf_Blood) > 9) {
+ delitem Fox_Armguard,1; //Fox_Armguard
+ delitem Wolf_Blood,10; //Wolf_Blood
+ getitem Wolf_Armguard,1; //Wolf_Armguard
+ mes "Can you feel the wolfish instinct?";
+ mes "Wild, but beautiful¡¦";
+ }
+ else {
+ mes "You don't have enough ingredients.";
+ mes "Look again......";
+ }
+ break;
+ case 2173: //Crescent_Armguard
+ if (countitem(Fox_Armguard) && countitem(Fragment_Of_Crystal) > 99) {
+ delitem Fox_Armguard,1; //Fox_Armguard
+ delitem Fragment_Of_Crystal,100; //Fragment_Of_Crystal
+ getitem Crescent_Armguard,1; //Crescent_Armguard
+ mes "B-e-a-utiful......";
+ mes "Feel the overwhelming magic within.";
+ }
+ else {
+ mes "You don't have enough ingredients.";
+ mes "Look again......";
+ }
+ break;
+ case 15054: //Ninja_Scale_Armor
+ if (countitem(Scale_Of_Red_Dragon) > 29 && countitem(Ice_Scale) > 29 && countitem(Dark_Red_Scale) > 29) {
+ delitem Scale_Of_Red_Dragon,30; //Scale_Of_Red_Dragon
+ delitem Ice_Scale,30; //Ice_Scale
+ delitem Dark_Red_Scale,30; //Dark_Red_Scale
+ getitem Ninja_Scale_Armor,1; //Ninja_Scale_Armor
+ mes "This armor holds a legend...";
+ mes "Though I don't believe in them...";
+ }
+ else {
+ mes "You don't have enough ingredients.";
+ mes "Look again......";
+ }
+ break;
+ case 15055: //Tenebris_Latitantes
+ if (countitem(Special_Ninja_Suit_) && countitem(Piece_Of_Darkness) > 9) {
+ delitem Special_Ninja_Suit_,1; //Special_Ninja_Suit_
+ delitem Piece_Of_Darkness,10; //Piece_Of_Darkness
+ getitem Tenebris_Latitantes,1; //Tenebris_Latitantes
+ mes "How about it?";
+ mes "It looks like two sets of them, doesn't it?";
+ }
+ else {
+ mes "You don't have enough ingredients.";
+ mes "Look again......";
+ }
+ break;
+ }
+ close;
+ case 4:
+ mes "[Gyo]";
+ mes "Looks like you need more time to decide.";
+ close;
+ }
+ next;
+ }
+
+L_Ingredients:
+ switch(getarg(0)){
+ case 2172: //Wolf_Armguard
+ return "you need 1 Fox Armguard and 10 Blood of Wolf";
+ case 2173: //Crescent_Armguard
+ return "you need 1 Fox Armguard and 100 Crystal Fragments";
+ case 15054: //Ninja_Scale_Armor
+ return "you need 30 Fire Dragon Scales, 30 Ice Scales and 30 Darkred Scale Pieces";
+ case 15055: //Tenebris_Latitantes
+ return "you'll need a Special Ninja Suit with a slot and 10 Dark Pieces";
+ }
+ end;
+
+}
+
+que_ng,21,72,6 script Master Craftsman Ki#weap 4_M_RASWORD,{
+ mes "[Ki]";
+ mes "To attack is the best means of defense.";
+ mes "A powerful weapon will make you truly complete.";
+ next;
+ mes "[Ki]";
+ mes "Of course, it would be better to have something special at hand.";
+ next;
+ if (select("Combine weapon.:End conversation.") == 2) {
+ mes "[Ki]";
+ mes "Being too careful could sometimes be lethal.";
+ close;
+ }
+ switch (select("Raksasa Dagger:Mikatsuki:Petal Shuriken:Quit.")) {
+ case 1:
+ mes "[Ki]";
+ mes "Raksasa Dagger can only be used after plenty of training.";
+ next;
+ callsub L_Menu,Raksasa_Dagger;
+ close;
+ case 2:
+ mes "[Ki]";
+ mes "Mikatsuki... A beautiful curve like the crescent moon...";
+ mes "There aren't many who can make them.";
+ next;
+ callsub L_Menu,Mikatsuki;
+ close;
+ case 3:
+ mes "[Ki]";
+ mes "Petal Shuriken... Have you every seen petals swirl?";
+ next;
+ callsub L_Menu,Huuma_Swirling_Petal;
+ close;
+ case 4:
+ mes "[Ki]";
+ mes "Think carefully~~";
+ close;
+ }
+
+L_Menu:
+ .@item_make = getarg(0);
+ while(1){
+ switch(select("Check Ingredients.:Check Stats.:Combine.:Quit.")){
+ case 1:
+ mes "[Ki]";
+ mes "To make a ^ff0000"+getitemname(.@item_make)+", "+callsub(L_Ingredients,.@item_make)+".^000000";
+ if (.@item_make==Raksasa_Dagger)
+ mes "The garnet gives the Raksasa Dagger its unique color.";
+ else if (.@item_make==Mikatsuki)
+ mes "The opal is what gives off the translucent glow.";
+ else if (.@item_make==Huuma_Swirling_Petal)
+ mes "It may seem like too many shurikens are needed... But it is essential for the beautiful fluttering effect.";
+ break;
+ case 2:
+ mes "["+ getitemname(getarg(0)) +"]";
+ if (.@item_make == Raksasa_Dagger){
+ mes "INT+3 MATK+100.";
+ mes "Dagger Type, ATK 120, Slot 1";
+ mes "Required Level 110, Ninja Type Only";
+ }
+ else if (.@item_make == Mikatsuki){
+ mes "MATK + 120, Fluctuated Casting and SP use decreased by 5% upon skill use.";
+ mes "Dagger Type, ATK 50, Weapon Lvl. 4";
+ mes "Slot 1";
+ mes "Required Level 100, Ninja Type Only";
+ }
+ else if (.@item_make == Huuma_Swirling_Petal){
+ mes "MATK + 50, Petal Shuriken skill damage increased by 20%.";
+ mes "Shuriken Type, ATK 150";
+ mes "Weapon Lvl. 3, Slot 2";
+ mes "Required Level 110, Ninja Type Only";
+ }
+ break;
+ case 3:
+ mes "[Ki]";
+ mes "Make sure that ^ff0000you have the correct ingredients and equipment at hand.^000000";
+ mes "No use crying over it later.";
+ next;
+ if (select("Combine.:Quit.") == 2) {
+ mes "[Ki]";
+ mes "Think carefully~~";
+ close;
+ }
+ if (checkweight(1201,1) == 0 || (MaxWeight - Weight) < 2000) {
+ mes "- Hold on!! -";
+ mes "- You cannot receive items -";
+ mes "- because you carry too much. -";
+ mes "- Please try again -";
+ mes "- after lightening your burden. -";
+ close;
+ }
+ mes "[Ki]";
+ switch(.@item_make){
+ case 13076: //Raksasa_Dagger
+ if (countitem(Murasame_) && countitem(Dark_Red_Jewel)) {
+ delitem Murasame_,1; //Murasame_
+ delitem Dark_Red_Jewel,1; //Dark_Red_Jewel
+ getitem Raksasa_Dagger,1; //Raksasa_Dagger
+ mes "Oh yes...";
+ mes "It is a beautiful glow...";
+ }
+ else {
+ mes "Hmm... You do not have enough to make a Raksasa Dagger.";
+ mes "Why don't you check again?";
+ mes "Some just can't give up what they hold.";
+ }
+ break;
+ case 13078: //Mikatsuki
+ if (countitem(Hakujin_) && countitem(White_Jewel)) {
+ delitem Hakujin_,1; //Hakujin_
+ delitem White_Jewel,1; //White_Jewel
+ getitem Mikatsuki,1; //Mikatsuki
+ mes "Splendid¡¦";
+ mes "It is always mesmerizing to look upon such a beautiful weapon¡¦";
+ }
+ else {
+ mes "Hmm... You do not have enough to make a Mikatsuki.";
+ mes "Why don't you check again?";
+ mes "Some just can't give up what they hold.";
+ }
+ break;
+ case 13313: //Huuma_Swirling_Petal
+ if (countitem(Huuma_Calm_Mind) && countitem(Broken_Shuriken) > 99) {
+ delitem Huuma_Calm_Mind,1; //Huuma_Calm_Mind
+ delitem Broken_Shuriken,100; //Broken_Shuriken
+ getitem Huuma_Swirling_Petal,1; //Huuma_Swirling_Petal
+ mes "Swirling Petal!!";
+ }
+ else {
+ mes "Hmm... You do not have enough to make Petal Shurikens.";
+ mes "Why don't you check again?";
+ mes "Some just can't give up what they hold.";
+ }
+ break;
+ }
+ close;
+ case 4:
+ mes "[Ki]";
+ mes "Looks like you need more time to decide.";
+ close;
+ }
+ next;
+ }
+
+L_Ingredients:
+ switch(getarg(0)){
+ case 13076: //Raksasa_Dagger
+ return "you need 1 Murasame with 2 sockets and 1 Garnet";
+ case 13078: //Mikatsuki
+ return "you need a Hakujin with a Slot and an Opal";
+ case 13313: //Huuma_Swirling_Petal
+ return "you need one Huuma Calm Mind Shuriken and 100 Broken Shurikens";
+ }
+ end;
+
+}
diff --git a/npc/re/scripts.conf b/npc/re/scripts.conf
index 2f980265e..518cfdc94 100644
--- a/npc/re/scripts.conf
+++ b/npc/re/scripts.conf
@@ -88,6 +88,7 @@ npc: npc/re/merchants/renters.txt
npc: npc/re/merchants/shops.txt
//npc: npc/re/merchants/ticket_refiner.txt
//npc: npc/re/merchants/enchan_upg.txt
+npc: npc/re/merchants/ninja_craftsman.txt
// --------------------------- Others ---------------------------
npc: npc/re/other/bulletin_boards.txt
diff --git a/src/map/clif.c b/src/map/clif.c
index 029080958..47b0a5f45 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -6183,6 +6183,14 @@ void clif_openvending(struct map_session_data* sd, int id, struct s_vending* ven
clif->addcards(WFIFOP(fd,22+i*22), &sd->status.cart[index]);
}
WFIFOSET(fd,WFIFOW(fd,2));
+
+#if PACKETVER >= 20141022
+ /** should go elsewhere perhaps? it has to be bundled with this however. **/
+ WFIFOHEAD(fd, 3);
+ WFIFOW(fd, 0) = 0xa28;
+ WFIFOB(fd, 2) = 0;/** 1 is failure. our current responses to failure are working so not yet implemented **/
+ WFIFOSET(fd, 3);
+#endif
}
diff --git a/src/map/script.c b/src/map/script.c
index c01e8c391..235b7b8d5 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -2427,9 +2427,11 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o
script->syntax.translation_db = strdb_get(script->translation_db, script->parser_current_npc_name);
}
- script->buf=(unsigned char *)aMalloc(SCRIPT_BLOCK_SIZE*sizeof(unsigned char));
+ if( !script->buf ) {
+ script->buf = (unsigned char *)aMalloc(SCRIPT_BLOCK_SIZE*sizeof(unsigned char));
+ script->size = SCRIPT_BLOCK_SIZE;
+ }
script->pos=0;
- script->size=SCRIPT_BLOCK_SIZE;
script->parse_nextline(true, NULL);
// who called parse_script is responsible for clearing the database after using it, but just in case... lets clear it here
@@ -2443,10 +2445,7 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o
if( script->error_report )
script->error(src,file,line,script->error_msg,script->error_pos);
aFree( script->error_msg );
- aFree( script->buf );
script->pos = 0;
- script->size = 0;
- script->buf = NULL;
for(i=LABEL_START;i<script->str_num;i++)
if(script->str_data[i].type == C_NOP) script->str_data[i].type = C_NAME;
for(i=0; i<size; i++)
@@ -2468,10 +2467,7 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o
{// does not require brackets around the script
if( *p == '\0' && !(options&SCRIPT_RETURN_EMPTY_SCRIPT) )
{// empty script and can return NULL
- aFree( script->buf );
script->pos = 0;
- script->size = 0;
- script->buf = NULL;
#ifdef ENABLE_CASE_CHECK
script->local_casecheck.clear();
script->parser_current_src = NULL;
@@ -2491,10 +2487,7 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o
p = script->skip_space(p+1);
if( *p == '}' && !(options&SCRIPT_RETURN_EMPTY_SCRIPT) )
{// empty script and can return NULL
- aFree( script->buf );
script->pos = 0;
- script->size = 0;
- script->buf = NULL;
#ifdef ENABLE_CASE_CHECK
script->local_casecheck.clear();
script->parser_current_src = NULL;
@@ -2543,10 +2536,6 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o
script->addc(C_NOP);
- // trim code to size
- script->size = script->pos;
- RECREATE(script->buf,unsigned char,script->pos);
-
// default unknown references to variables
for (i = LABEL_START; i < script->str_num; i++) {
if (script->str_data[i].type == C_NOP) {
@@ -2611,8 +2600,9 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o
#endif
CREATE(code,struct script_code,1);
- code->script_buf = script->buf;
- code->script_size = script->size;
+ code->script_buf = (unsigned char *)aMalloc(script->pos*sizeof(unsigned char));
+ memcpy(code->script_buf, script->buf, script->pos);
+ code->script_size = script->pos;
code->local.vars = NULL;
code->local.arrays = NULL;
#ifdef ENABLE_CASE_CHECK
@@ -4970,6 +4960,13 @@ int script_translation_db_destroyer(DBKey key, DBData *data, va_list ap) {
*
**/
void script_parser_clean_leftovers(void) {
+
+ if( script->buf )
+ aFree(script->buf);
+
+ script->buf = NULL;
+ script->size = 0;
+
if( script->translation_db ) {
script->translation_db->destroy(script->translation_db,script->translation_db_destroyer);
script->translation_db = NULL;
diff --git a/src/map/skill.c b/src/map/skill.c
index 96ade3908..88ca45ae5 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -6146,7 +6146,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
{
int sp = 0;
if ( dstsd && dstsd->spiritball
- && (sd == dstsd || map_flag_vs(src->m) || (sd->duel_group && sd->duel_group == dstsd->duel_group))
+ && (sd == dstsd || map_flag_vs(src->m) || (sd && sd->duel_group && sd->duel_group == dstsd->duel_group))
&& ((dstsd->class_&MAPID_BASEMASK) != MAPID_GUNSLINGER || (dstsd->class_&MAPID_UPPERMASK) != MAPID_REBELLION)
) {
// split the if for readability, and included gunslingers in the check so that their coins cannot be removed [Reddozen]