summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--db/const.txt6
-rw-r--r--doc/sample/npc_trader_sample.txt58
-rw-r--r--doc/script_commands.txt64
-rw-r--r--npc/merchants/shops.txt2240
-rw-r--r--sql-files/main.sql12
-rw-r--r--sql-files/upgrades/2013-12-24--00-15.sql8
-rw-r--r--sql-files/upgrades/index.txt1
-rw-r--r--src/common/mmo.h2
-rw-r--r--src/map/atcommand.c27
-rw-r--r--src/map/clif.c224
-rw-r--r--src/map/clif.h8
-rw-r--r--src/map/map.c3
-rw-r--r--src/map/npc.c566
-rw-r--r--src/map/npc.h46
-rw-r--r--src/map/packets.h43
-rw-r--r--src/map/packets_struct.h44
-rw-r--r--src/map/script.c277
-rw-r--r--src/map/status.c324
-rw-r--r--src/map/status.h51
19 files changed, 3500 insertions, 504 deletions
diff --git a/db/const.txt b/db/const.txt
index 8e7807695..ab14afca2 100644
--- a/db/const.txt
+++ b/db/const.txt
@@ -1257,6 +1257,7 @@ SC_MTF_MLEATKED 569
SC_MTF_CRIDAMAGE 570
SC_MOONSTAR 571
SC_SUPER_STAR 572
+SC_OKTOBERFEST 573
e_gasp 0
e_what 1
@@ -3348,3 +3349,8 @@ IOT_GUILD 3
false 0
true 1
+
+NST_ZENY 0
+NST_CASH 1
+NST_MARKET 2
+NST_CUSTOM 3
diff --git a/doc/sample/npc_trader_sample.txt b/doc/sample/npc_trader_sample.txt
new file mode 100644
index 000000000..abc87f6b4
--- /dev/null
+++ b/doc/sample/npc_trader_sample.txt
@@ -0,0 +1,58 @@
+//===== Hercules Script =======================================
+//= Sample: NPC Trader
+//===== By: ==================================================
+//= Hercules Dev Team
+//===== Current Version: =====================================
+//= 20131223
+//===== Description: =========================================
+//= Demonstrates NPC Trader.
+//============================================================
+
+/* ordinary zeny trader */
+prontera,152,151,1 trader TestTrader 952,{
+ OnInit:
+ sellitem 2115;
+ end;
+}
+/* ordinary cash trader */
+prontera,152,152,1 trader TestTraderCash 952,{
+ OnInit:
+ tradertype(NST_CASH);
+ sellitem 2115;
+ end;
+}
+/* custom npc trader */
+prontera,153,152,1 trader TestCustom2 952,{
+ OnInit:
+ tradertype(NST_CUSTOM);
+ sellitem 501,2;
+ end;
+
+/* allows currency to be item 501 and 502 */
+OnCountFunds:
+ setcurrency(countitem(501),countitem(502));
+ end;
+
+/* receives @price (total cost) and @points (the secondary input field for cash windows) */
+OnPayFunds:
+ dispbottom "Hi: price="+@price+" and points="+@points;
+ if( countitem(502) < @points || countitem(501) < @price-@points )
+ end;
+ delitem 502,@points;
+ delitem 501,@price-@points;
+ purchaseok();
+ end;
+}
+/* demonstrates Market Trader */
+prontera,150,160,6 trader HaiMarket 952,{
+OnInit:
+ tradertype(NST_MARKET);
+ sellitem 501,-1,49;
+ end;
+
+OnClock0000://resupplies red potions on midnight
+OnMyResupply:
+ if( shopcount(501) < 20 )
+ sellitem 501,-1,49;
+ end;
+} \ No newline at end of file
diff --git a/doc/script_commands.txt b/doc/script_commands.txt
index 9186ba714..f5f2d7d9c 100644
--- a/doc/script_commands.txt
+++ b/doc/script_commands.txt
@@ -1120,6 +1120,7 @@ From here on, we will have the commands sorted as follow:
9.- Battleground commands.
10.- Mercenary commands.
11.- Queue commands.
+12.- NPC Trader commands
=====================
@@ -8471,3 +8472,66 @@ Deletes a queue iterator from memory and returns 1 when it fails,
otherwise 0 is returned.
---------------------------------------
+
+======================
+|12.- NPC Trader Commands.|
+======================
+---------------------------------------
+Commands that control NPC Trader Shops
+See /doc/sample/npc_trader_sample.txt
+
+---------------------------------------
+
+*openshop({NPC_Name});
+
+opens the trader shop from the currently-attached npc unless,
+when the optional NPC_Name param is used.
+
+---------------------------------------
+
+*sellitem <Item_ID>{,<price>{,<qty>}};
+
+adds (or modifies) <Item_ID> data to the shop,
+when <price> is not provided (or when it is -1) itemdb default is used.
+qty is only necessary for NST_MARKET trader types.
+
+when <Item_ID> is already in the shop,
+the previous data (price/qty), is overwritten with the new.
+
+---------------------------------------
+
+*stopselling <Item_ID>;
+
+attempts to remove <Item_ID> from the current shop list.
+
+---------------------------------------
+
+*setcurrency <Val1>{,<Val2>};
+
+updates the currently attached player shop funds.
+
+---------------------------------------
+
+*tradertype(<Type>);
+
+Modifies the npc trader type, item list is cleared upon modifiying the value.
+By default, all npcs staart with tradertype(NST_ZENY);
+
+- NST_ZENY (0) Normal Zeny Shop
+- NST_CASH (1) Normal Cash Shop
+- NST_MARKET (2) Normal NPC Market Shop (where items have limited availability and need to be refurbished)
+- NST_CUSTOM (3) Custom Shop (any currency, item/var/etca, check sample)
+
+---------------------------------------
+
+*purchaseok();
+
+Signs that the transaction (on a NST_CUSTOM trader) has been successful.
+
+---------------------------------------
+
+*shopcount(<Item_ID>);
+
+Returns the amount of still-available <Item_ID> in the shop (on a NST_MARKET trader).
+
+---------------------------------------
diff --git a/npc/merchants/shops.txt b/npc/merchants/shops.txt
index b20874ffb..a1ab894d0 100644
--- a/npc/merchants/shops.txt
+++ b/npc/merchants/shops.txt
@@ -1,9 +1,7 @@
//===== Hercules Script ======================================
//= Shops
-//===== By: ==================================================
-//= rAthena Dev Team
//===== Current Version: =====================================
-//= 3.4
+//= 3.5
//===== Description: =========================================
//= Town shop NPCs.
//===== Additional Comments: =================================
@@ -36,291 +34,2169 @@
//= 3.2 Added Missing Items to the pet Groomers in prontera, payon, and yuno. BugReport:6680[Spre]
//= 3.3 Moved more shops to Renewal file. [Euphy]
//= 3.4 Moved Izlude shops to pre-re/re paths. [Streusel]
+//= 3.5 Converted to trader format [Yommy]
//============================================================
//=======================================================
// Alberta
//=======================================================
-alb2trea,87,65,5 shop Tool Dealer#alb 4_M_01,1750:-1,1751:-1,1752:-1,501:-1,502:-1,503:-1,504:-1,506:-1,645:-1,656:-1
-alberta_in,165,96,0 shop Item Collector#alb 1_F_MERCHANT_02,911:-1,528:-1
-alberta_in,182,97,0 shop Tool Dealer#alb2 1_F_MERCHANT_01,1750:-1,611:-1,501:-1,502:-1,503:-1,504:-1,506:-1,645:-1,656:-1,601:-1,602:-1,2243:-1
-alberta_in,180,15,0 shop Armor Dealer#alb 4W_F_01,2101:-1,2103:-1,2401:-1,2403:-1,2405:-1,2501:-1,2503:-1,2505:-1,2203:-1,2201:-1,2205:-1,2226:-1,2301:-1,2303:-1,2305:-1,2321:-1,2328:-1,2332:-1,2307:-1,2309:-1,2312:-1,2314:-1,2628:-1
-alberta_in,188,21,0 shop Weapon Dealer#alb 1_M_03,1750:-1,1751:-1,1101:-1,1104:-1,1107:-1,1201:-1,1204:-1,1207:-1,1601:-1,1701:-1,1301:-1,1351:-1,1354:-1,1357:-1,1360:-1
-alberta_in,175,97,4 shop Weapon Dealer#alb2 4_KID01,1146:-1,1245:-1
-alberta_in,176,81,3 shop Trading Merchant#alb 4_M_HUMERCHANT,13200:-1,13201:-1,13202:-1,13150:-1,13102:-1,13151:-1,13154:-1,13155:-1,13163:-1,13165:-1,13168:-1
+alb2trea,87,65,5 trader Tool Dealer#alb 4_M_01,{
+OnInit:
+ sellitem Arrow;
+ sellitem Silver_Arrow;
+ sellitem Fire_Arrow;
+ sellitem Red_Potion;
+ sellitem Orange_Potion;
+ sellitem Yellow_Potion;
+ sellitem White_Potion;
+ sellitem Green_Potion;
+ sellitem Center_Potion;
+ sellitem Awakening_Potion;
+}
+
+alberta_in,165,96,0 trader Item Collector#alb 1_F_MERCHANT_02,{
+OnInit:
+ sellitem Scell;
+ sellitem Monster's_Feed;
+}
+
+alberta_in,182,97,0 trader Tool Dealer#alb2 1_F_MERCHANT_01,{
+OnInit:
+ sellitem Arrow;
+ sellitem Spectacles;
+ sellitem Red_Potion;
+ sellitem Orange_Potion;
+ sellitem Yellow_Potion;
+ sellitem White_Potion;
+ sellitem Green_Potion;
+ sellitem Center_Potion;
+ sellitem Awakening_Potion;
+ sellitem Wing_Of_Fly;
+ sellitem Wing_Of_Butterfly;
+ sellitem Spinning_Eyes;
+}
+
+alberta_in,180,15,0 trader Armor Dealer#alb 4W_F_01,{
+OnInit:
+ sellitem Guard;
+ sellitem Buckler;
+ sellitem Sandals;
+ sellitem Shoes;
+ sellitem Boots;
+ sellitem Hood;
+ sellitem Muffler;
+ sellitem Manteau;
+ sellitem Glasses;
+ sellitem Sunglasses;
+ sellitem Diver's_Goggles;
+ sellitem Cap;
+ sellitem Cotton_Shirt;
+ sellitem Leather_Jacket;
+ sellitem Adventure_Suit;
+ sellitem Silk_Robe;
+ sellitem Wooden_Mail;
+ sellitem Silver_Robe;
+ sellitem Mantle;
+ sellitem Coat;
+ sellitem Padded_Armor;
+ sellitem Chain_Mail;
+ sellitem Novice_Armlet;
+}
+
+alberta_in,188,21,0 trader Weapon Dealer#alb 1_M_03,{
+OnInit:
+ sellitem Arrow;
+ sellitem Silver_Arrow;
+ sellitem Sword;
+ sellitem Falchion;
+ sellitem Blade;
+ sellitem Knife;
+ sellitem Cutter;
+ sellitem Main_Gauche;
+ sellitem Rod;
+ sellitem Bow;
+ sellitem Axe;
+ sellitem Battle_Axe;
+ sellitem Hammer;
+ sellitem Buster;
+ sellitem Two_Handed_Axe;
+}
+
+alberta_in,175,97,4 trader Weapon Dealer#alb2 4_KID01,{
+OnInit:
+ sellitem Town_Sword;
+ sellitem Cinquedea;
+}
+
+alberta_in,176,81,3 trader Trading Merchant#alb 4_M_HUMERCHANT,{
+OnInit:
+ sellitem Bullet;
+ sellitem Silver_Bullet;
+ sellitem Shell_Of_Blood;
+ sellitem Branch;
+ sellitem Crimson_Bolt;
+ sellitem The_Cyclone;
+ sellitem Rolling_Stone;
+ sellitem Black_Rose;
+ sellitem Long_Barrel;
+ sellitem Jungle_Carbine;
+ sellitem Thunder_P;
+}
+
//=======================================================
// Al De Baran
//=======================================================
-aldeba_in,20,60,0 shop Armor Dealer#alde 4W_F_01,2228:-1,2103:-1,2105:-1,2307:-1,2309:-1,2312:-1,2314:-1,2316:-1,2505:-1,2405:-1,2628:-1,2627:-1
-aldeba_in,28,54,0 shop Weapon Dealer#alde 1_M_03,1201:-1,1204:-1,1207:-1,1210:-1,1213:-1,1216:-1,1219:-1,1222:-1
-aldeba_in,22,47,4 shop Weapon Dealer#alde2 4_M_06,1146:-1,1245:-1
-aldeba_in,94,56,5 shop Tool Dealer#alde 4_M_01,501:-1,502:-1,503:-1,504:-1,506:-1,645:-1,656:-1,601:-1,602:-1,611:-1,610:-1
-alde_alche,38,184,3 shop Material Seller#alche 4_M_SAGE_C,7143:-1,7141:-1,7140:-1,6248:-1,6250:-1,6251:-1,6255:-1,6261:-1,6262:-1,6297:-1
+aldeba_in,20,60,0 trader Armor Dealer#alde 4W_F_01,{
+OnInit:
+ sellitem Helm;
+ sellitem Buckler;
+ sellitem Shield;
+ sellitem Mantle;
+ sellitem Coat;
+ sellitem Padded_Armor;
+ sellitem Chain_Mail;
+ sellitem Plate_Armor;
+ sellitem Manteau;
+ sellitem Boots;
+ sellitem Novice_Armlet;
+ sellitem Belt;
+}
+
+aldeba_in,28,54,0 trader Weapon Dealer#alde 1_M_03,{
+OnInit:
+ sellitem Knife;
+ sellitem Cutter;
+ sellitem Main_Gauche;
+ sellitem Dirk;
+ sellitem Dagger;
+ sellitem Stiletto;
+ sellitem Gladius;
+ sellitem Damascus;
+}
+
+aldeba_in,22,47,4 trader Weapon Dealer#alde2 4_M_06,{
+OnInit:
+ sellitem Town_Sword;
+ sellitem Cinquedea;
+}
+
+aldeba_in,94,56,5 trader Tool Dealer#alde 4_M_01,{
+OnInit:
+ sellitem Red_Potion;
+ sellitem Orange_Potion;
+ sellitem Yellow_Potion;
+ sellitem White_Potion;
+ sellitem Green_Potion;
+ sellitem Center_Potion;
+ sellitem Awakening_Potion;
+ sellitem Wing_Of_Fly;
+ sellitem Wing_Of_Butterfly;
+ sellitem Spectacles;
+ sellitem Leaf_Of_Yggdrasil;
+}
+
+alde_alche,38,184,3 trader Material Seller#alche 4_M_SAGE_C,{
+OnInit:
+ sellitem Life_Force_Pot;
+ sellitem Yggdrasilberry_Dew;
+ sellitem Seed_Of_Life;
+ sellitem Melange_Pot;
+ sellitem Cooking_Skewer;
+ sellitem Black_Charcoal;
+ sellitem Large_Cookpot;
+ sellitem Fine_Noodle;
+ sellitem Cool_Gravy;
+ sellitem Bottle_To_Throw;
+}
+
//=======================================================
// Amatsu
//=======================================================
-ama_in01,89,28,5 shop Armor Dealer#ama 4_F_JPN2,2211:-1,2401:-1,2403:-1,2501:-1,2503:-1,2101:-1,2103:-1,2305:-1,2321:-1,2332:-1,2328:-1,2627:-1
-ama_in01,102,28,3 shop Weapon Dealer#ama 4_M_JPNOJI,1207:-1,1216:-1,1107:-1,1122:-1,1116:-1,1154:-1,1407:-1,1457:-1,1354:-1,1519:-1
-ama_in01,24,30,5 shop Tool Dealer#ama 4_M_JPN,1750:-1,1770:-1,611:-1,501:-1,502:-1,503:-1,504:-1,506:-1,645:-1,656:-1,601:-1,602:-1,1065:-1
+ama_in01,89,28,5 trader Armor Dealer#ama 4_F_JPN2,{
+OnInit:
+ sellitem Bandana;
+ sellitem Sandals;
+ sellitem Shoes;
+ sellitem Hood;
+ sellitem Muffler;
+ sellitem Guard;
+ sellitem Buckler;
+ sellitem Adventure_Suit;
+ sellitem Silk_Robe;
+ sellitem Silver_Robe;
+ sellitem Wooden_Mail;
+ sellitem Belt;
+}
+
+ama_in01,102,28,3 trader Weapon Dealer#ama 4_M_JPNOJI,{
+OnInit:
+ sellitem Main_Gauche;
+ sellitem Stiletto;
+ sellitem Blade;
+ sellitem Ring_Pommel_Saber;
+ sellitem Katana;
+ sellitem Bastard_Sword;
+ sellitem Pike;
+ sellitem Partizan;
+ sellitem Hammer;
+ sellitem Chain;
+}
+
+ama_in01,24,30,5 trader Tool Dealer#ama 4_M_JPN,{
+OnInit:
+ sellitem Arrow;
+ sellitem Iron_Arrow;
+ sellitem Spectacles;
+ sellitem Red_Potion;
+ sellitem Orange_Potion;
+ sellitem Yellow_Potion;
+ sellitem White_Potion;
+ sellitem Green_Potion;
+ sellitem Center_Potion;
+ sellitem Awakening_Potion;
+ sellitem Wing_Of_Fly;
+ sellitem Wing_Of_Butterfly;
+ sellitem Booby_Trap;
+}
+
// Ninja Shops
-que_ng,72,31,2 shop Boonji#nin 4_M_01,13250:-1,13251:-1,13252:-1,13253:-1,13254:-1
-que_ng,73,26,5 shop Boonray#nin 4_M_01,2117:-1,7521:-1,7522:-1,7523:-1,7524:-1
+que_ng,72,31,2 trader Boonji#nin 4_M_01,{
+OnInit:
+ sellitem Shuriken;
+ sellitem Nimbus_Shuriken;
+ sellitem Flash_Shuriken;
+ sellitem Sharp_Leaf_Shuriken;
+ sellitem Thorn_Needle_Shuriken;
+}
+
+que_ng,73,26,5 trader Boonray#nin 4_M_01,{
+OnInit:
+ sellitem Arm_Guard;
+ sellitem Flame_Stone;
+ sellitem Ice_Stone;
+ sellitem Wind_Stone;
+ sellitem Shadow_Orb;
+}
+
//=======================================================
// Ayothaya
//=======================================================
-ayo_in01,18,182,1 shop Tool Dealer#ayo 4_F_THAISHAMAN,1750:-1,1770:-1,611:-1,501:-1,502:-1,503:-1,504:-1,506:-1,645:-1,656:-1,601:-1,602:-1,1065:-1
-ayo_in01,90,192,3 shop Weapon Dealer#ayo 4_M_THAIONGBAK,1207:-1,1216:-1,1107:-1,1122:-1,1116:-1,1154:-1,1407:-1,1457:-1,1354:-1,1519:-1
-ayo_in01,90,160,1 shop Armor Dealer#ayo 4_M_THAIOLD,2211:-1,2401:-1,2403:-1,2501:-1,2503:-1,2101:-1,2103:-1,2305:-1,2321:-1,2332:-1,2328:-1,2627:-1
+ayo_in01,18,182,1 trader Tool Dealer#ayo 4_F_THAISHAMAN,{
+OnInit:
+ sellitem Arrow;
+ sellitem Iron_Arrow;
+ sellitem Spectacles;
+ sellitem Red_Potion;
+ sellitem Orange_Potion;
+ sellitem Yellow_Potion;
+ sellitem White_Potion;
+ sellitem Green_Potion;
+ sellitem Center_Potion;
+ sellitem Awakening_Potion;
+ sellitem Wing_Of_Fly;
+ sellitem Wing_Of_Butterfly;
+ sellitem Booby_Trap;
+}
+
+ayo_in01,90,192,3 trader Weapon Dealer#ayo 4_M_THAIONGBAK,{
+OnInit:
+ sellitem Main_Gauche;
+ sellitem Stiletto;
+ sellitem Blade;
+ sellitem Ring_Pommel_Saber;
+ sellitem Katana;
+ sellitem Bastard_Sword;
+ sellitem Pike;
+ sellitem Partizan;
+ sellitem Hammer;
+ sellitem Chain;
+}
+
+ayo_in01,90,160,1 trader Armor Dealer#ayo 4_M_THAIOLD,{
+OnInit:
+ sellitem Bandana;
+ sellitem Sandals;
+ sellitem Shoes;
+ sellitem Hood;
+ sellitem Muffler;
+ sellitem Guard;
+ sellitem Buckler;
+ sellitem Adventure_Suit;
+ sellitem Silk_Robe;
+ sellitem Silver_Robe;
+ sellitem Wooden_Mail;
+ sellitem Belt;
+}
+
//=======================================================
// Brasilis
//=======================================================
-brasilis,252,257,3 shop Tool Dealer#bra 4_F_BRZ_WOMAN,645:-1,656:-1,601:-1,602:-1,611:-1,1065:-1,610:-1
-brasilis,244,243,3 shop Weapon Dealer#bra 4_M_BRZ_MAN2,1407:-1,1457:-1,1354:-1,1519:-1,13003:-1
-brasilis,201,309,3 shop Pet Groomer#bra 4_M_BRZ_MAN1,537:-1,643:-1
-brasilis,221,128,3 shop Fruit Gardener#bra 4_M_BRZ_MAN2,11515:-1,513:-1,11516:-1
+brasilis,252,257,3 trader Tool Dealer#bra 4_F_BRZ_WOMAN,{
+OnInit:
+ sellitem Center_Potion;
+ sellitem Awakening_Potion;
+ sellitem Wing_Of_Fly;
+ sellitem Wing_Of_Butterfly;
+ sellitem Spectacles;
+ sellitem Booby_Trap;
+ sellitem Leaf_Of_Yggdrasil;
+}
+
+brasilis,244,243,3 trader Weapon Dealer#bra 4_M_BRZ_MAN2,{
+OnInit:
+ sellitem Pike;
+ sellitem Partizan;
+ sellitem Hammer;
+ sellitem Chain;
+ sellitem Coward;
+}
+
+brasilis,201,309,3 trader Pet Groomer#bra 4_M_BRZ_MAN1,{
+OnInit:
+ sellitem Pet_Food;
+ sellitem Pet_Incubator;
+}
+
+brasilis,221,128,3 trader Fruit Gardener#bra 4_M_BRZ_MAN2,{
+OnInit:
+ sellitem Coconut;
+ sellitem Banana;
+ sellitem Asai_Fruit;
+}
+
//=======================================================
// Comodo
//=======================================================
-cmd_in01,117,165,4 shop Armor Dealer#cmd 4W_F_01,2226:-1,2228:-1,2103:-1,2105:-1,2405:-1,2503:-1,2505:-1,2305:-1,2321:-1,2307:-1,2309:-1,2335:-1,2312:-1,2314:-1,2316:-1
-cmd_in01,128,165,2 shop Weapon Dealer#cmd 1_M_03,1901:-1,1903:-1,1905:-1,1909:-1,1911:-1,1907:-1,1950:-1,1952:-1,1954:-1,1958:-1,1960:-1,1956:-1
-cmd_in01,79,182,5 shop Tool Dealer#cmd 4_M_01,1770:-1,501:-1,502:-1,503:-1,504:-1,645:-1,656:-1,657:-1,601:-1,602:-1,611:-1,1065:-1
-comodo,296,125,4 shop Souvenir Vendor#cmd 4W_F_01,965:-1,964:-1
-cmd_fild07,257,126,5 shop Tool Dealer#cmd2 4_M_01,1770:-1,501:-1,502:-1,503:-1,504:-1,645:-1,656:-1,601:-1,602:-1,611:-1,1065:-1
-cmd_fild07,250,98,2 shop Weapon Dealer#cmd2 1_M_03,1401:-1,1404:-1,1407:-1,1451:-1,1454:-1,1457:-1,1460:-1,1463:-1,1410:-1
-cmd_fild07,277,85,4 shop Armor Dealer#cmd2 4W_F_01,2226:-1,2228:-1,2103:-1,2105:-1,2405:-1,2503:-1,2505:-1,2305:-1,2321:-1,2307:-1,2309:-1,2335:-1,2312:-1,2314:-1,2316:-1
+cmd_in01,117,165,4 trader Armor Dealer#cmd 4W_F_01,{
+OnInit:
+ sellitem Cap;
+ sellitem Helm;
+ sellitem Buckler;
+ sellitem Shield;
+ sellitem Boots;
+ sellitem Muffler;
+ sellitem Manteau;
+ sellitem Adventure_Suit;
+ sellitem Silk_Robe;
+ sellitem Mantle;
+ sellitem Coat;
+ sellitem Thief_Clothes;
+ sellitem Padded_Armor;
+ sellitem Chain_Mail;
+ sellitem Plate_Armor;
+}
+
+cmd_in01,128,165,2 trader Weapon Dealer#cmd 1_M_03,{
+OnInit:
+ sellitem Violin;
+ sellitem Mandolin;
+ sellitem Lute;
+ sellitem Harp;
+ sellitem Guh_Moon_Goh;
+ sellitem Guitar;
+ sellitem Rope;
+ sellitem Line;
+ sellitem Wire;
+ sellitem Tail;
+ sellitem Whip;
+ sellitem Rante;
+}
+
+cmd_in01,79,182,5 trader Tool Dealer#cmd 4_M_01,{
+OnInit:
+ sellitem Iron_Arrow;
+ sellitem Red_Potion;
+ sellitem Orange_Potion;
+ sellitem Yellow_Potion;
+ sellitem White_Potion;
+ sellitem Center_Potion;
+ sellitem Awakening_Potion;
+ sellitem Berserk_Potion;
+ sellitem Wing_Of_Fly;
+ sellitem Wing_Of_Butterfly;
+ sellitem Spectacles;
+ sellitem Booby_Trap;
+}
+
+comodo,296,125,4 trader Souvenir Vendor#cmd 4W_F_01,{
+OnInit:
+ sellitem Clam_Shell;
+ sellitem Crap_Shell;
+}
+
+cmd_fild07,257,126,5 trader Tool Dealer#cmd2 4_M_01,{
+OnInit:
+ sellitem Iron_Arrow;
+ sellitem Red_Potion;
+ sellitem Orange_Potion;
+ sellitem Yellow_Potion;
+ sellitem White_Potion;
+ sellitem Center_Potion;
+ sellitem Awakening_Potion;
+ sellitem Wing_Of_Fly;
+ sellitem Wing_Of_Butterfly;
+ sellitem Spectacles;
+ sellitem Booby_Trap;
+}
+
+cmd_fild07,250,98,2 trader Weapon Dealer#cmd2 1_M_03,{
+OnInit:
+ sellitem Javelin;
+ sellitem Spear;
+ sellitem Pike;
+ sellitem Guisarme;
+ sellitem Glaive;
+ sellitem Partizan;
+ sellitem Trident;
+ sellitem Halberd;
+ sellitem Lance;
+}
+
+cmd_fild07,277,85,4 trader Armor Dealer#cmd2 4W_F_01,{
+OnInit:
+ sellitem Cap;
+ sellitem Helm;
+ sellitem Buckler;
+ sellitem Shield;
+ sellitem Boots;
+ sellitem Muffler;
+ sellitem Manteau;
+ sellitem Adventure_Suit;
+ sellitem Silk_Robe;
+ sellitem Mantle;
+ sellitem Coat;
+ sellitem Thief_Clothes;
+ sellitem Padded_Armor;
+ sellitem Chain_Mail;
+ sellitem Plate_Armor;
+}
+
//=======================================================
// Einbroch
//=======================================================
-ein_in01,106,27,4 shop One Hand Weapon Dealer 4_F_EINWOMAN,1101:-1,1104:-1,1107:-1,1110:-1,1113:-1,1119:-1,1122:-1,1123:-1,1126:-1,1129:-1,1201:-1,1204:-1,1207:-1,1210:-1,1213:-1,1216:-1,1219:-1,1222:-1,1301:-1,1401:-1,1404:-1,1407:-1,1501:-1,1504:-1,1507:-1,1510:-1,1513:-1,1516:-1,1519:-1,1522:-1,1801:-1,1803:-1,1805:-1,1807:-1,1809:-1,1811:-1
-ein_in01,109,27,4 shop Two Hand Weapon Dealer 4_F_EINWOMAN,1116:-1,1151:-1,1154:-1,1157:-1,1160:-1,1351:-1,1354:-1,1357:-1,1360:-1,1410:-1,1451:-1,1454:-1,1457:-1,1460:-1,1463:-1,1250:-1,1252:-1,1254:-1
-ein_in01,119,26,4 shop Weapon Dealer#ein 4_M_EINMAN,1247:-1,1248:-1,1249:-1,13000:-1
-ein_in01,189,15,1 shop Tool Dealer#ein 4_F_EINWOMAN,1750:-1,1752:-1,1751:-1,611:-1,501:-1,502:-1,503:-1,504:-1,506:-1,645:-1,656:-1,601:-1,602:-1,1065:-1
-einbroch,138,66,4 shop Flu Mask Dealer#ein 4_F_EINWOMAN,5114:-1,2218:-1
-einbroch,82,199,4 shop Paddler#ein 4_M_EINMAN,512:-1,645:-1,1750:-1,501:-1
+ein_in01,106,27,4 trader One Hand Weapon Dealer 4_F_EINWOMAN,{
+OnInit:
+ sellitem Sword;
+ sellitem Falchion;
+ sellitem Blade;
+ sellitem Lapier;
+ sellitem Scimiter;
+ sellitem Tsurugi;
+ sellitem Ring_Pommel_Saber;
+ sellitem Haedonggum;
+ sellitem Saber;
+ sellitem Flamberge;
+ sellitem Knife;
+ sellitem Cutter;
+ sellitem Main_Gauche;
+ sellitem Dirk;
+ sellitem Dagger;
+ sellitem Stiletto;
+ sellitem Gladius;
+ sellitem Damascus;
+ sellitem Axe;
+ sellitem Javelin;
+ sellitem Spear;
+ sellitem Pike;
+ sellitem Club;
+ sellitem Mace;
+ sellitem Smasher;
+ sellitem Flail;
+ sellitem Morning_Star;
+ sellitem Sword_Mace;
+ sellitem Chain;
+ sellitem Stunner;
+ sellitem Waghnakh;
+ sellitem Knuckle_Duster;
+ sellitem Hora;
+ sellitem Fist;
+ sellitem Claw;
+ sellitem Finger;
+}
+
+ein_in01,109,27,4 trader Two Hand Weapon Dealer 4_F_EINWOMAN,{
+OnInit:
+ sellitem Katana;
+ sellitem Slayer;
+ sellitem Bastard_Sword;
+ sellitem Two_Hand_Sword;
+ sellitem Broad_Sword;
+ sellitem Battle_Axe;
+ sellitem Hammer;
+ sellitem Buster;
+ sellitem Two_Handed_Axe;
+ sellitem Lance;
+ sellitem Guisarme;
+ sellitem Glaive;
+ sellitem Partizan;
+ sellitem Trident;
+ sellitem Halberd;
+ sellitem Jur;
+ sellitem Katar;
+ sellitem Jamadhar;
+}
+
+ein_in01,119,26,4 trader Weapon Dealer#ein 4_M_EINMAN,{
+OnInit:
+ sellitem Kindling_Dagger;
+ sellitem Obsidian_Dagger;
+ sellitem Fisherman's_Dagger;
+ sellitem Jujube_Dagger;
+}
+
+ein_in01,189,15,1 trader Tool Dealer#ein 4_F_EINWOMAN,{
+OnInit:
+ sellitem Arrow;
+ sellitem Fire_Arrow;
+ sellitem Silver_Arrow;
+ sellitem Spectacles;
+ sellitem Red_Potion;
+ sellitem Orange_Potion;
+ sellitem Yellow_Potion;
+ sellitem White_Potion;
+ sellitem Green_Potion;
+ sellitem Center_Potion;
+ sellitem Awakening_Potion;
+ sellitem Wing_Of_Fly;
+ sellitem Wing_Of_Butterfly;
+ sellitem Booby_Trap;
+}
+
+einbroch,138,66,4 trader Flu Mask Dealer#ein 4_F_EINWOMAN,{
+OnInit:
+ sellitem Fedora;
+ sellitem Flu_Mask;
+}
+
+einbroch,82,199,4 trader Paddler#ein 4_M_EINMAN,{
+OnInit:
+ sellitem Apple;
+ sellitem Center_Potion;
+ sellitem Arrow;
+ sellitem Red_Potion;
+}
+
//Official Gunslingers shops.
-que_ng,179,91,3 shop Chivas Lugal 4_M_HUMERCHANT,13150:-1,13102:-1,13151:-1,13154:-1,13155:-1,13163:-1,13165:-1,13168:-1
-que_ng,180,79,3 shop Johnny Waiker 4_M_HUMERCHANT,13200:-1,13201:-1,13202:-1
+que_ng,179,91,3 trader Chivas Lugal 4_M_HUMERCHANT,{
+OnInit:
+ sellitem Branch;
+ sellitem Crimson_Bolt;
+ sellitem The_Cyclone;
+ sellitem Rolling_Stone;
+ sellitem Black_Rose;
+ sellitem Long_Barrel;
+ sellitem Jungle_Carbine;
+ sellitem Thunder_P;
+}
+
+que_ng,180,79,3 trader Johnny Waiker 4_M_HUMERCHANT,{
+OnInit:
+ sellitem Bullet;
+ sellitem Silver_Bullet;
+ sellitem Shell_Of_Blood;
+}
+
//=======================================================
// Geffen
//=======================================================
-geffen_in,26,178,4 shop Armor Dealer#gef 1_F_01,2628:-1,2101:-1,2107:-1,2401:-1,2501:-1,2230:-1,2301:-1,2303:-1,2305:-1,2321:-1,2332:-1
-geffen_in,30,178,4 shop Weapon Dealer#gef2 1_M_01,1750:-1,1751:-1,1101:-1,1701:-1,1201:-1,1204:-1,1207:-1,1210:-1,1213:-1,1216:-1,1601:-1,1604:-1,1607:-1,1610:-1
-geffen_in,22,171,7 shop Weapon Dealer#gef 4_M_02,1146:-1,1245:-1
-geffen_in,74,144,0 shop Trader#gef 1_F_01,911:-1,910:-1,912:-1
-geffen_in,77,167,0 shop Tool Dealer#gef 1_F_03,1750:-1,611:-1,501:-1,502:-1,503:-1,504:-1,506:-1,645:-1,656:-1,601:-1,602:-1,2241:-1
-geffen_in,77,173,0 shop Magical Item Seller#gef 1_M_WIZARD,717:-1,1601:-1,1604:-1,1607:-1,1610:-1,2232:-1,2321:-1,2332:-1
-geffen_in,171,123,4 shop Tool Dealer#gef2 1_M_WIZARD,1092:-1,1093:-1
-geffen,193,152,4 shop Pet Groomer#gef 4_F_TELEPORTER,537:-1,643:-1,10013:-1,10014:-1,554:-1,6113:-1,6114:-1,6115:-1
+geffen_in,26,178,4 trader Armor Dealer#gef 1_F_01,{
+OnInit:
+ sellitem Novice_Armlet;
+ sellitem Guard;
+ sellitem Mirror_Shield;
+ sellitem Sandals;
+ sellitem Hood;
+ sellitem Gemmed_Sallet;
+ sellitem Cotton_Shirt;
+ sellitem Leather_Jacket;
+ sellitem Adventure_Suit;
+ sellitem Silk_Robe;
+ sellitem Silver_Robe;
+}
+
+geffen_in,30,178,4 trader Weapon Dealer#gef2 1_M_01,{
+OnInit:
+ sellitem Arrow;
+ sellitem Silver_Arrow;
+ sellitem Sword;
+ sellitem Bow;
+ sellitem Knife;
+ sellitem Cutter;
+ sellitem Main_Gauche;
+ sellitem Dirk;
+ sellitem Dagger;
+ sellitem Stiletto;
+ sellitem Rod;
+ sellitem Wand;
+ sellitem Staff;
+ sellitem Arc_Wand;
+}
+
+geffen_in,22,171,7 trader Weapon Dealer#gef 4_M_02,{
+OnInit:
+ sellitem Town_Sword;
+ sellitem Cinquedea;
+}
+
+geffen_in,74,144,0 trader Trader#gef 1_F_01,{
+OnInit:
+ sellitem Scell;
+ sellitem Garlet;
+ sellitem Zargon;
+}
+
+geffen_in,77,167,0 trader Tool Dealer#gef 1_F_03,{
+OnInit:
+ sellitem Arrow;
+ sellitem Spectacles;
+ sellitem Red_Potion;
+ sellitem Orange_Potion;
+ sellitem Yellow_Potion;
+ sellitem White_Potion;
+ sellitem Green_Potion;
+ sellitem Center_Potion;
+ sellitem Awakening_Potion;
+ sellitem Wing_Of_Fly;
+ sellitem Wing_Of_Butterfly;
+ sellitem Granpa_Beard;
+}
+
+geffen_in,77,173,0 trader Magical Item Seller#gef 1_M_WIZARD,{
+OnInit:
+ sellitem Blue_Gemstone;
+ sellitem Rod;
+ sellitem Wand;
+ sellitem Staff;
+ sellitem Arc_Wand;
+ sellitem Circlet;
+ sellitem Silk_Robe;
+ sellitem Silver_Robe;
+}
+
+geffen_in,171,123,4 trader Tool Dealer#gef2 1_M_WIZARD,{
+OnInit:
+ sellitem Empty_Cylinder;
+ sellitem Empty_Potion;
+}
+
+geffen,193,152,4 trader Pet Groomer#gef 4_F_TELEPORTER,{
+OnInit:
+ sellitem Pet_Food;
+ sellitem Pet_Incubator;
+ sellitem Backpack;
+ sellitem Rocker_Glasses;
+ sellitem Mojji;
+ sellitem Vital_Flower_;
+ sellitem Flame_Gemstone;
+ sellitem Bun_;
+}
+
//=======================================================
// Gonryun
//=======================================================
-gonryun,147,84,5 shop Tool Dealer#gon 4_M_TWOLDMAN,1750:-1,1770:-1,611:-1,501:-1,502:-1,503:-1,504:-1,506:-1,645:-1,656:-1,601:-1,602:-1,1065:-1
-gonryun,174,101,3 shop Weapon Dealer#gon 4_M_TWBOY,1207:-1,1216:-1,1107:-1,1122:-1,1116:-1,1154:-1,1407:-1,1457:-1,1354:-1,1519:-1
-gonryun,173,84,3 shop Armor Dealer#gon 4_F_TWGIRL,2211:-1,2401:-1,2403:-1,2501:-1,2503:-1,2101:-1,2103:-1,2305:-1,2321:-1,2332:-1,2328:-1,2627:-1
+gonryun,147,84,5 trader Tool Dealer#gon 4_M_TWOLDMAN,{
+OnInit:
+ sellitem Arrow;
+ sellitem Iron_Arrow;
+ sellitem Spectacles;
+ sellitem Red_Potion;
+ sellitem Orange_Potion;
+ sellitem Yellow_Potion;
+ sellitem White_Potion;
+ sellitem Green_Potion;
+ sellitem Center_Potion;
+ sellitem Awakening_Potion;
+ sellitem Wing_Of_Fly;
+ sellitem Wing_Of_Butterfly;
+ sellitem Booby_Trap;
+}
+
+gonryun,174,101,3 trader Weapon Dealer#gon 4_M_TWBOY,{
+OnInit:
+ sellitem Main_Gauche;
+ sellitem Stiletto;
+ sellitem Blade;
+ sellitem Ring_Pommel_Saber;
+ sellitem Katana;
+ sellitem Bastard_Sword;
+ sellitem Pike;
+ sellitem Partizan;
+ sellitem Hammer;
+ sellitem Chain;
+}
+
+gonryun,173,84,3 trader Armor Dealer#gon 4_F_TWGIRL,{
+OnInit:
+ sellitem Bandana;
+ sellitem Sandals;
+ sellitem Shoes;
+ sellitem Hood;
+ sellitem Muffler;
+ sellitem Guard;
+ sellitem Buckler;
+ sellitem Adventure_Suit;
+ sellitem Silk_Robe;
+ sellitem Silver_Robe;
+ sellitem Wooden_Mail;
+ sellitem Belt;
+}
+
//=======================================================
// Hugel
//=======================================================
-hugel,105,169,5 shop Vendor from Milk Ranch#h 4_F_01,519:-1
-hugel,77,167,3 shop Vegetable Gardener#hu 4_F_HUGRANMA,522:-1,512:-1,513:-1,515:-1,516:-1,535:-1
-hu_in01,241,368,2 shop Tool Dealer#hu 1_M_INNKEEPER,1750:-1,611:-1,501:-1,502:-1,503:-1,504:-1,506:-1,645:-1,656:-1,601:-1,602:-1,1065:-1
-hu_in01,252,368,3 shop Tool Dealer#hu2 4_F_01,717:-1,2201:-1,910:-1,528:-1
-hu_in01,100,390,3 shop Bow Dealer#hu 4_M_04,1701:-1,1707:-1,1718:-1,1714:-1
-hu_in01,94,390,3 shop Weapon Dealer#hu 4_M_HUMAN_01,1116:-1,1154:-1,1354:-1,1201:-1
-hu_in01,94,313,3 shop Armor Dealer#hu 4_M_04,2224:-1,2232:-1,2226:-1,2101:-1,2103:-1,2401:-1,2501:-1,2307:-1,2105:-1
+hugel,105,169,5 trader Vendor from Milk Ranch#h 4_F_01,{
+OnInit:
+ sellitem Milk;
+}
+
+hugel,77,167,3 trader Vegetable Gardener#hu 4_F_HUGRANMA,{
+OnInit:
+ sellitem Fruit_Of_Mastela;
+ sellitem Apple;
+ sellitem Banana;
+ sellitem Carrot;
+ sellitem Sweet_Potato;
+ sellitem Pumpkin;
+}
+
+hu_in01,241,368,2 trader Tool Dealer#hu 1_M_INNKEEPER,{
+OnInit:
+ sellitem Arrow;
+ sellitem Spectacles;
+ sellitem Red_Potion;
+ sellitem Orange_Potion;
+ sellitem Yellow_Potion;
+ sellitem White_Potion;
+ sellitem Green_Potion;
+ sellitem Center_Potion;
+ sellitem Awakening_Potion;
+ sellitem Wing_Of_Fly;
+ sellitem Wing_Of_Butterfly;
+ sellitem Booby_Trap;
+}
+
+hu_in01,252,368,3 trader Tool Dealer#hu2 4_F_01,{
+OnInit:
+ sellitem Blue_Gemstone;
+ sellitem Sunglasses;
+ sellitem Garlet;
+ sellitem Monster's_Feed;
+}
+
+hu_in01,100,390,3 trader Bow Dealer#hu 4_M_04,{
+OnInit:
+ sellitem Bow;
+ sellitem Great_Bow;
+ sellitem Hunter_Bow;
+ sellitem Kakkung;
+}
+
+hu_in01,94,390,3 trader Weapon Dealer#hu 4_M_HUMAN_01,{
+OnInit:
+ sellitem Katana;
+ sellitem Bastard_Sword;
+ sellitem Hammer;
+ sellitem Knife;
+}
+
+hu_in01,94,313,3 trader Armor Dealer#hu 4_M_04,{
+OnInit:
+ sellitem Goggle;
+ sellitem Circlet;
+ sellitem Cap;
+ sellitem Guard;
+ sellitem Buckler;
+ sellitem Sandals;
+ sellitem Hood;
+ sellitem Mantle;
+ sellitem Shield;
+}
+
//=======================================================
// Izlude
//=======================================================
-izlude_in,60,127,4 shop Weapon Dealer#iz 1_F_MARIA,1750:-1,1751:-1,1701:-1,1601:-1,1201:-1,1204:-1,1207:-1,1101:-1,1104:-1,1107:-1,1116:-1,1151:-1,1154:-1,1157:-1,1160:-1,1301:-1
-izlude_in,70,127,4 shop Armor Dealer#iz 1_M_SIZ,2103:-1,2105:-1,2403:-1,2405:-1,2503:-1,2505:-1,2226:-1,2228:-1,2303:-1,2305:-1,2328:-1,2307:-1,2309:-1,2312:-1,2314:-1,2316:-1,2628:-1
+izlude_in,60,127,4 trader Weapon Dealer#iz 1_F_MARIA,{
+OnInit:
+ sellitem Arrow;
+ sellitem Silver_Arrow;
+ sellitem Bow;
+ sellitem Rod;
+ sellitem Knife;
+ sellitem Cutter;
+ sellitem Main_Gauche;
+ sellitem Sword;
+ sellitem Falchion;
+ sellitem Blade;
+ sellitem Katana;
+ sellitem Slayer;
+ sellitem Bastard_Sword;
+ sellitem Two_Hand_Sword;
+ sellitem Broad_Sword;
+ sellitem Axe;
+}
+
+izlude_in,70,127,4 trader Armor Dealer#iz 1_M_SIZ,{
+OnInit:
+ sellitem Buckler;
+ sellitem Shield;
+ sellitem Shoes;
+ sellitem Boots;
+ sellitem Muffler;
+ sellitem Manteau;
+ sellitem Cap;
+ sellitem Helm;
+ sellitem Leather_Jacket;
+ sellitem Adventure_Suit;
+ sellitem Wooden_Mail;
+ sellitem Mantle;
+ sellitem Coat;
+ sellitem Padded_Armor;
+ sellitem Chain_Mail;
+ sellitem Plate_Armor;
+ sellitem Novice_Armlet;
+}
+
//=======================================================
// Jawaii
//=======================================================
-jawaii,186,174,3 shop Ice Cream Guy#ja 4_M_03,536:-1,536:-1,536:-1,536:-1,536:-1,536:-1,536:-1
+jawaii,186,174,3 trader Ice Cream Guy#ja 4_M_03,{
+OnInit:
+ sellitem Ice_Cream;
+ sellitem Ice_Cream;
+ sellitem Ice_Cream;
+ sellitem Ice_Cream;
+ sellitem Ice_Cream;
+ sellitem Ice_Cream;
+ sellitem Ice_Cream;
+}
+
//=======================================================
// Juno
//=======================================================
-yuno,218,97,5 shop Tool Dealer#yuno 4_M_02,1750:-1,611:-1,501:-1,502:-1,503:-1,504:-1,506:-1,645:-1,656:-1,601:-1,602:-1
-yuno,226,107,5 shop Tool Dealer#yuno1 4_M_01,911:-1,910:-1,912:-1
-yuno,197,114,4 shop Pet Groomer#yuno 4_F_TELEPORTER,537:-1,643:-1,10013:-1,10014:-1,6115:-1,554:-1,6114:-1,6113:-1,6110:-1,6115:-1,6100:-1,6098:-1,6112:-1,6104:-1,6108:-1,6111:-1,6095:-1,6099:-1,6096:-1,6097:-1
-yuno,205,103,4 shop Mr. King's Shop#yuno 4_M_TELEPORTER,2340:-1,2341:-1,2411:-1,2222:-1,2230:-1,1721:-1
-yuno,163,187,5 shop Magical Item Seller#yuno 4_F_01,717:-1,1601:-1,1604:-1,1607:-1,1610:-1,2232:-1,2321:-1,2332:-1
-yuno_in01,25,34,5 shop Tool Dealer#yuno2 4_M_01,1750:-1,611:-1,501:-1,502:-1,503:-1,504:-1,506:-1,645:-1,656:-1,601:-1,602:-1
-yuno_in01,103,35,2 shop Weapon Dealer#yuno 1_M_03,1750:-1,1751:-1,1101:-1,1701:-1,1201:-1,1204:-1,1207:-1,1210:-1,1213:-1,1216:-1,1601:-1,1604:-1,1607:-1,1610:-1
-yuno_in01,112,26,4 shop Armor Dealer#yuno 4W_F_01,2628:-1,2101:-1,2107:-1,2401:-1,2501:-1,2230:-1,2301:-1,2303:-1,2305:-1,2321:-1,2332:-1
-yuno_in03,176,22,3 shop Scroll Merchant#yuno03 4_M_ORIENT02,7433:-1 //Temp shop in Yuno that sells Blank Scrolls
+yuno,218,97,5 trader Tool Dealer#yuno 4_M_02,{
+OnInit:
+ sellitem Arrow;
+ sellitem Spectacles;
+ sellitem Red_Potion;
+ sellitem Orange_Potion;
+ sellitem Yellow_Potion;
+ sellitem White_Potion;
+ sellitem Green_Potion;
+ sellitem Center_Potion;
+ sellitem Awakening_Potion;
+ sellitem Wing_Of_Fly;
+ sellitem Wing_Of_Butterfly;
+}
+
+yuno,226,107,5 trader Tool Dealer#yuno1 4_M_01,{
+OnInit:
+ sellitem Scell;
+ sellitem Garlet;
+ sellitem Zargon;
+}
+
+yuno,197,114,4 trader Pet Groomer#yuno 4_F_TELEPORTER,{
+OnInit:
+ sellitem Pet_Food;
+ sellitem Pet_Incubator;
+ sellitem Backpack;
+ sellitem Rocker_Glasses;
+ sellitem Bun_;
+ sellitem Mojji;
+ sellitem Flame_Gemstone;
+ sellitem Vital_Flower_;
+ sellitem Vital_Flower;
+ sellitem Bun_;
+ sellitem Damp_Darkness;
+ sellitem Small_Snow_Flower;
+ sellitem Fresh_Plant;
+ sellitem Big_Cell;
+ sellitem Apple_Pudding;
+ sellitem Mystic_Stone;
+ sellitem Flavored_Alcohol;
+ sellitem Grilled_Rice_Cake;
+ sellitem Fish_With_Blue_Back;
+ sellitem Pumpkin_Pie_;
+}
+
+yuno,205,103,4 trader Mr. King's Shop#yuno 4_M_TELEPORTER,{
+OnInit:
+ sellitem Novice_Breast;
+ sellitem Full_Plate_Armor;
+ sellitem Grave;
+ sellitem Turban;
+ sellitem Gemmed_Sallet;
+ sellitem Repeting_CrossBow;
+}
+
+yuno,163,187,5 trader Magical Item Seller#yuno 4_F_01,{
+OnInit:
+ sellitem Blue_Gemstone;
+ sellitem Rod;
+ sellitem Wand;
+ sellitem Staff;
+ sellitem Arc_Wand;
+ sellitem Circlet;
+ sellitem Silk_Robe;
+ sellitem Silver_Robe;
+}
+
+yuno_in01,25,34,5 trader Tool Dealer#yuno2 4_M_01,{
+OnInit:
+ sellitem Arrow;
+ sellitem Spectacles;
+ sellitem Red_Potion;
+ sellitem Orange_Potion;
+ sellitem Yellow_Potion;
+ sellitem White_Potion;
+ sellitem Green_Potion;
+ sellitem Center_Potion;
+ sellitem Awakening_Potion;
+ sellitem Wing_Of_Fly;
+ sellitem Wing_Of_Butterfly;
+}
+
+yuno_in01,103,35,2 trader Weapon Dealer#yuno 1_M_03,{
+OnInit:
+ sellitem Arrow;
+ sellitem Silver_Arrow;
+ sellitem Sword;
+ sellitem Bow;
+ sellitem Knife;
+ sellitem Cutter;
+ sellitem Main_Gauche;
+ sellitem Dirk;
+ sellitem Dagger;
+ sellitem Stiletto;
+ sellitem Rod;
+ sellitem Wand;
+ sellitem Staff;
+ sellitem Arc_Wand;
+}
+
+yuno_in01,112,26,4 trader Armor Dealer#yuno 4W_F_01,{
+OnInit:
+ sellitem Novice_Armlet;
+ sellitem Guard;
+ sellitem Mirror_Shield;
+ sellitem Sandals;
+ sellitem Hood;
+ sellitem Gemmed_Sallet;
+ sellitem Cotton_Shirt;
+ sellitem Leather_Jacket;
+ sellitem Adventure_Suit;
+ sellitem Silk_Robe;
+ sellitem Silver_Robe;
+}
+
+yuno_in03,176,22,3 trader Scroll Merchant#yuno03 4_M_ORIENT02,{
+OnInit:
+ sellitem Scroll; //Temp shop in Yuno that sells Blank Scrolls
+}
+
//=======================================================
// Lighthalzen
//=======================================================
-lighthalzen,69,75,5 shop Fruit Gardener#lhz 8_F,512:-1,513:-1
-lighthalzen,112,44,0 shop Flower Girl#lhz 4_F_01,712:-1,744:-1,748:-1
-lighthalzen,124,129,0 shop Vegetable Gardener#lhz 4_F_02,515:-1,516:-1,535:-1
-lighthalzen,220,122,3 shop Vendor from Milk Ranch#l 4_F_01,519:-1
-lighthalzen,222,191,4 shop Pet Groomer#lhz 4_M_TELEPORTER,537:-1,643:-1,10013:-1,10014:-1,554:-1,6113:-1,6114:-1,6115:-1
-lhz_in02,286,95,4 shop Beginner's Merchant#lhz 1_M_SIZ,5112:-1,2416:-1,2113:-1,2512:-1
-lhz_in02,271,99,5 shop Armor Dealer#lhz 4_M_REPAIR,2101:-1,2103:-1,2403:-1,2405:-1,2503:-1,2321:-1,2314:-1,2309:-1,2335:-1,2628:-1
-lhz_in02,276,99,4 shop Weapon Dealer#lhz 4_M_REPAIR,1201:-1,1207:-1,1216:-1,1107:-1,1122:-1,1116:-1,1154:-1,1407:-1,1457:-1,1354:-1,1519:-1,13003:-1
-lhz_in02,273,35,4 shop Wand Dealer#lhz 4_M_EINMAN2,1601:-1,1604:-1,1607:-1,1617:-1,1619:-1
-lhz_in02,105,21,3 shop Jeweler#lhz 4_F_02,721:-1,723:-1,726:-1,728:-1,729:-1,730:-1,2613:-1
-lhz_in02,17,220,5 shop Vegetable Gardener#lhz2 4_F_02,515:-1,516:-1,535:-1
-lhz_in02,21,220,5 shop Fruit Gardener#lhz2 8_F,512:-1,513:-1
-lhz_in02,32,219,5 shop Butcher#lhz 1_M_JOBGUIDER,517:-1
-lhz_in02,38,145,5 shop Gift Merchant#lhz 4_F_02,734:-1,735:-1,736:-1,737:-1,746:-1
-lhz_in02,47,148,3 shop Wedding Shop Dealer#lhz 1_F_LIBRARYGIRL,744:-1,745:-1,2338:-1,2206:-1,7170:-1
-lhz_in02,31,145,4 shop Tool Dealer#lhz 4_F_01,611:-1,503:-1,504:-1,506:-1,657:-1,656:-1,601:-1,602:-1,1065:-1,610:-1,1770:-1
-lhz_in02,85,216,5 shop Doll Supplier#lhz 4_F_LGTGIRL,740:-1,741:-1,742:-1
-lhz_in02,87,208,3 shop Toy Supplier#lhz 4_M_PIERROT,2243:-1,2212:-1,2242:-1,2241:-1
-lhz_in03,239,106,5 shop Tool Dealer#lhz2 4_F_EINWOMAN,501:-1,502:-1,506:-1,645:-1,656:-1,601:-1,602:-1,1065:-1,611:-1
-lhz_in03,258,101,3 shop Arrow Merchant#lhz 4_M_EINMAN,1750:-1,1770:-1,1752:-1,1751:-1
-lhz_in03,249,24,4 shop Merchant#lhz 4_M_EINMAN,911:-1,910:-1,912:-1,528:-1
+lighthalzen,69,75,5 trader Fruit Gardener#lhz 8_F,{
+OnInit:
+ sellitem Apple;
+ sellitem Banana;
+}
+
+lighthalzen,112,44,0 trader Flower Girl#lhz 4_F_01,{
+OnInit:
+ sellitem Flower;
+ sellitem Bunch_Of_Flowers;
+ sellitem Witherless_Rose;
+}
+
+lighthalzen,124,129,0 trader Vegetable Gardener#lhz 4_F_02,{
+OnInit:
+ sellitem Carrot;
+ sellitem Sweet_Potato;
+ sellitem Pumpkin;
+}
+
+lighthalzen,220,122,3 trader Vendor from Milk Ranch#l 4_F_01,{
+OnInit:
+ sellitem Milk;
+}
+
+lighthalzen,222,191,4 trader Pet Groomer#lhz 4_M_TELEPORTER,{
+OnInit:
+ sellitem Pet_Food;
+ sellitem Pet_Incubator;
+ sellitem Backpack;
+ sellitem Rocker_Glasses;
+ sellitem Mojji;
+ sellitem Vital_Flower_;
+ sellitem Flame_Gemstone;
+ sellitem Bun_;
+}
+
+lhz_in02,286,95,4 trader Beginner's Merchant#lhz 1_M_SIZ,{
+OnInit:
+ sellitem Super_Novice_Hat;
+ sellitem Novice_Shoes;
+ sellitem Novice_Shield;
+ sellitem Novice_Manteau;
+}
+
+lhz_in02,271,99,5 trader Armor Dealer#lhz 4_M_REPAIR,{
+OnInit:
+ sellitem Guard;
+ sellitem Buckler;
+ sellitem Shoes;
+ sellitem Boots;
+ sellitem Muffler;
+ sellitem Silk_Robe;
+ sellitem Chain_Mail;
+ sellitem Coat;
+ sellitem Thief_Clothes;
+ sellitem Novice_Armlet;
+}
+
+lhz_in02,276,99,4 trader Weapon Dealer#lhz 4_M_REPAIR,{
+OnInit:
+ sellitem Knife;
+ sellitem Main_Gauche;
+ sellitem Stiletto;
+ sellitem Blade;
+ sellitem Ring_Pommel_Saber;
+ sellitem Katana;
+ sellitem Bastard_Sword;
+ sellitem Pike;
+ sellitem Partizan;
+ sellitem Hammer;
+ sellitem Chain;
+ sellitem Coward;
+}
+
+lhz_in02,273,35,4 trader Wand Dealer#lhz 4_M_EINMAN2,{
+OnInit:
+ sellitem Rod;
+ sellitem Wand;
+ sellitem Staff;
+ sellitem Survival_Rod;
+ sellitem Survival_Rod2;
+}
+
+lhz_in02,105,21,3 trader Jeweler#lhz 4_F_02,{
+OnInit:
+ sellitem Azure_Jewel;
+ sellitem Cardinal_Jewel;
+ sellitem Blue_Jewel;
+ sellitem Golden_Jewel;
+ sellitem Bluish_Green_Jewel;
+ sellitem Crystal_Jewel;
+ sellitem Diamond_Ring;
+}
+
+lhz_in02,17,220,5 trader Vegetable Gardener#lhz2 4_F_02,{
+OnInit:
+ sellitem Carrot;
+ sellitem Sweet_Potato;
+ sellitem Pumpkin;
+}
+
+lhz_in02,21,220,5 trader Fruit Gardener#lhz2 8_F,{
+OnInit:
+ sellitem Apple;
+ sellitem Banana;
+}
+
+lhz_in02,32,219,5 trader Butcher#lhz 1_M_JOBGUIDER,{
+OnInit:
+ sellitem Meat;
+}
+
+lhz_in02,38,145,5 trader Gift Merchant#lhz 4_F_02,{
+OnInit:
+ sellitem Red_Frame;
+ sellitem Blue_Porcelain;
+ sellitem White_Platter;
+ sellitem Black_Ladle;
+ sellitem Glass_Bead;
+}
+
+lhz_in02,47,148,3 trader Wedding Shop Dealer#lhz 1_F_LIBRARYGIRL,{
+OnInit:
+ sellitem Bunch_Of_Flowers;
+ sellitem Wedding_Bouquet;
+ sellitem Wedding_Dress;
+ sellitem Wedding_Veil;
+ sellitem Tuxedo;
+}
+
+lhz_in02,31,145,4 trader Tool Dealer#lhz 4_F_01,{
+OnInit:
+ sellitem Spectacles;
+ sellitem Yellow_Potion;
+ sellitem White_Potion;
+ sellitem Green_Potion;
+ sellitem Berserk_Potion;
+ sellitem Awakening_Potion;
+ sellitem Wing_Of_Fly;
+ sellitem Wing_Of_Butterfly;
+ sellitem Booby_Trap;
+ sellitem Leaf_Of_Yggdrasil;
+ sellitem Iron_Arrow;
+}
+
+lhz_in02,85,216,5 trader Doll Supplier#lhz 4_F_LGTGIRL,{
+OnInit:
+ sellitem Stuffed_Doll;
+ sellitem Poring_Doll;
+ sellitem Chonchon_Doll;
+}
+
+lhz_in02,87,208,3 trader Toy Supplier#lhz 4_M_PIERROT,{
+OnInit:
+ sellitem Spinning_Eyes;
+ sellitem Eye_Bandage;
+ sellitem Luxury_Sunglasses;
+ sellitem Granpa_Beard;
+}
+
+lhz_in03,239,106,5 trader Tool Dealer#lhz2 4_F_EINWOMAN,{
+OnInit:
+ sellitem Red_Potion;
+ sellitem Orange_Potion;
+ sellitem Green_Potion;
+ sellitem Center_Potion;
+ sellitem Awakening_Potion;
+ sellitem Wing_Of_Fly;
+ sellitem Wing_Of_Butterfly;
+ sellitem Booby_Trap;
+ sellitem Spectacles;
+}
+
+lhz_in03,258,101,3 trader Arrow Merchant#lhz 4_M_EINMAN,{
+OnInit:
+ sellitem Arrow;
+ sellitem Iron_Arrow;
+ sellitem Fire_Arrow;
+ sellitem Silver_Arrow;
+}
+
+lhz_in03,249,24,4 trader Merchant#lhz 4_M_EINMAN,{
+OnInit:
+ sellitem Scell;
+ sellitem Garlet;
+ sellitem Zargon;
+ sellitem Monster's_Feed;
+}
+
//=======================================================
// Louyang
//=======================================================
-lou_in02,121,182,5 shop Armor Dealer#lou 4_F_CHNWOMAN,2211:-1,2401:-1,2403:-1,2501:-1,2503:-1,2101:-1,2103:-1,2305:-1,2321:-1,2332:-1,2328:-1,2627:-1
-lou_in02,130,182,5 shop Weapon Dealer#lou 4_M_CHNMAN,1207:-1,1216:-1,1107:-1,1122:-1,1116:-1,1154:-1,1407:-1,1457:-1,1354:-1,1519:-1
-lou_in02,239,176,5 shop Tool Dealer#lou 4_F_CHNWOMAN,1750:-1,1770:-1,611:-1,501:-1,502:-1,503:-1,504:-1,506:-1,645:-1,656:-1,601:-1,602:-1,1065:-1
+lou_in02,121,182,5 trader Armor Dealer#lou 4_F_CHNWOMAN,{
+OnInit:
+ sellitem Bandana;
+ sellitem Sandals;
+ sellitem Shoes;
+ sellitem Hood;
+ sellitem Muffler;
+ sellitem Guard;
+ sellitem Buckler;
+ sellitem Adventure_Suit;
+ sellitem Silk_Robe;
+ sellitem Silver_Robe;
+ sellitem Wooden_Mail;
+ sellitem Belt;
+}
+
+lou_in02,130,182,5 trader Weapon Dealer#lou 4_M_CHNMAN,{
+OnInit:
+ sellitem Main_Gauche;
+ sellitem Stiletto;
+ sellitem Blade;
+ sellitem Ring_Pommel_Saber;
+ sellitem Katana;
+ sellitem Bastard_Sword;
+ sellitem Pike;
+ sellitem Partizan;
+ sellitem Hammer;
+ sellitem Chain;
+}
+
+lou_in02,239,176,5 trader Tool Dealer#lou 4_F_CHNWOMAN,{
+OnInit:
+ sellitem Arrow;
+ sellitem Iron_Arrow;
+ sellitem Spectacles;
+ sellitem Red_Potion;
+ sellitem Orange_Potion;
+ sellitem Yellow_Potion;
+ sellitem White_Potion;
+ sellitem Green_Potion;
+ sellitem Center_Potion;
+ sellitem Awakening_Potion;
+ sellitem Wing_Of_Fly;
+ sellitem Wing_Of_Butterfly;
+ sellitem Booby_Trap;
+}
+
//=======================================================
// Lutie
//=======================================================
-xmas_in,40,38,5 shop Tool Dealer#xmas 4_M_01,501:-1,502:-1,503:-1,504:-1,506:-1,645:-1,656:-1,601:-1,602:-1,611:-1,610:-1
-xmas_in,168,104,4 shop Armor Dealer#xmas 4W_F_01,2228:-1,2103:-1,2105:-1,2307:-1,2309:-1,2312:-1,2314:-1,2316:-1,2505:-1,2405:-1
-xmas_in,169,34,2 shop Gift Seller#xmas 4_F_GON,2612:-1,744:-1,748:-1,736:-1,746:-1,740:-1,2613:-1
-xmas_in,174,98,2 shop Weapon Dealer#xmas 1_M_03,1201:-1,1204:-1,1207:-1,1210:-1,1213:-1,1216:-1,1219:-1,1222:-1
+xmas_in,40,38,5 trader Tool Dealer#xmas 4_M_01,{
+OnInit:
+ sellitem Red_Potion;
+ sellitem Orange_Potion;
+ sellitem Yellow_Potion;
+ sellitem White_Potion;
+ sellitem Green_Potion;
+ sellitem Center_Potion;
+ sellitem Awakening_Potion;
+ sellitem Wing_Of_Fly;
+ sellitem Wing_Of_Butterfly;
+ sellitem Spectacles;
+ sellitem Leaf_Of_Yggdrasil;
+}
+
+xmas_in,168,104,4 trader Armor Dealer#xmas 4W_F_01,{
+OnInit:
+ sellitem Helm;
+ sellitem Buckler;
+ sellitem Shield;
+ sellitem Mantle;
+ sellitem Coat;
+ sellitem Padded_Armor;
+ sellitem Chain_Mail;
+ sellitem Plate_Armor;
+ sellitem Manteau;
+ sellitem Boots;
+}
+
+xmas_in,169,34,2 trader Gift Seller#xmas 4_F_GON,{
+OnInit:
+ sellitem Flower_Ring;
+ sellitem Bunch_Of_Flowers;
+ sellitem Witherless_Rose;
+ sellitem White_Platter;
+ sellitem Glass_Bead;
+ sellitem Stuffed_Doll;
+ sellitem Diamond_Ring;
+}
+
+xmas_in,174,98,2 trader Weapon Dealer#xmas 1_M_03,{
+OnInit:
+ sellitem Knife;
+ sellitem Cutter;
+ sellitem Main_Gauche;
+ sellitem Dirk;
+ sellitem Dagger;
+ sellitem Stiletto;
+ sellitem Gladius;
+ sellitem Damascus;
+}
+
//=======================================================
// Morroc - Post Ep. 12.1
//=======================================================
-in_moc_16,22,20,7 shop Sepulchral Merchant#moc 4_M_MASKMAN,1771:-1
-moc_ruins,91,128,4 shop Tool Dealer#moc1 4_F_04,1750:-1,611:-1,501:-1,502:-1,503:-1,504:-1,506:-1,645:-1,656:-1,601:-1,602:-1,1065:-1
-moc_ruins,114,63,6 shop Tool Dealer#moc2 4W_M_03,1750:-1,611:-1,501:-1,502:-1,503:-1,504:-1,506:-1,645:-1,656:-1,601:-1,602:-1,1065:-1,2242:-1
-moc_ruins,93,53,2 shop Item Collector#moc1 4_M_03,911:-1,528:-1,919:-1,925:-1
-moc_ruins,81,113,0 shop Item Collector#moc2 4_M_03,911:-1,528:-1,919:-1,925:-1
-moc_ruins,110,105,2 shop Jeweler#moc1 8_F,721:-1,723:-1,726:-1,728:-1,729:-1
-moc_ruins,52,85,6 shop Jeweler#moc2 4W_M_03,730:-1,2613:-1
-moc_ruins,113,126,4 shop Trader#moc1 4W_M_03,747:-1
-moc_ruins,131,138,0 shop Trader#moc2 4_F_04,748:-1
-moc_ruins,71,139,5 shop Trader#moc3 4_F_04,2612:-1
-moc_ruins,125,135,6 shop Trader#moc4 4_M_ORIENT02,2609:-1,1516:-1,1522:-1
-moc_ruins,87,109,0 shop Butcher#moc 1_M_MERCHANT,517:-1
-moc_ruins,90,149,6 shop Trader#moc5 4W_M_03,513:-1,513:-1,513:-1,513:-1,513:-1,513:-1
-moc_ruins,118,170,4 shop Pet Groomer#moc 4_M_TELEPORTER,537:-1,643:-1,10013:-1,10014:-1,554:-1,6113:-1,6114:-1,6115:-1
-morocc_in,141,67,0 shop Weapon Dealer#moc1 1_M_MERCHANT,1750:-1,1751:-1,1701:-1,1601:-1,1201:-1,1204:-1,1207:-1,1210:-1,1213:-1,1216:-1,1219:-1,1222:-1,1250:-1,1252:-1,1254:-1
-morocc_in,141,60,0 shop Armor Dealer#moc 1_M_MERCHANT,2101:-1,2103:-1,2401:-1,2403:-1,2405:-1,2501:-1,2503:-1,2218:-1,2301:-1,2303:-1,2305:-1,2321:-1,2328:-1,2332:-1,2307:-1,2309:-1,2335:-1,2628:-1
-morocc_in,132,57,0 shop Weapon Dealer#moc2 4W_M_03,1146:-1,1245:-1
+in_moc_16,22,20,7 trader Sepulchral Merchant#moc 4_M_MASKMAN,{
+OnInit:
+ sellitem Venom_Knife;
+}
+
+moc_ruins,91,128,4 trader Tool Dealer#moc1 4_F_04,{
+OnInit:
+ sellitem Arrow;
+ sellitem Spectacles;
+ sellitem Red_Potion;
+ sellitem Orange_Potion;
+ sellitem Yellow_Potion;
+ sellitem White_Potion;
+ sellitem Green_Potion;
+ sellitem Center_Potion;
+ sellitem Awakening_Potion;
+ sellitem Wing_Of_Fly;
+ sellitem Wing_Of_Butterfly;
+ sellitem Booby_Trap;
+}
+
+moc_ruins,114,63,6 trader Tool Dealer#moc2 4W_M_03,{
+OnInit:
+ sellitem Arrow;
+ sellitem Spectacles;
+ sellitem Red_Potion;
+ sellitem Orange_Potion;
+ sellitem Yellow_Potion;
+ sellitem White_Potion;
+ sellitem Green_Potion;
+ sellitem Center_Potion;
+ sellitem Awakening_Potion;
+ sellitem Wing_Of_Fly;
+ sellitem Wing_Of_Butterfly;
+ sellitem Booby_Trap;
+ sellitem Luxury_Sunglasses;
+}
+
+moc_ruins,93,53,2 trader Item Collector#moc1 4_M_03,{
+OnInit:
+ sellitem Scell;
+ sellitem Monster's_Feed;
+ sellitem Animal's_Skin;
+ sellitem Bill_Of_Birds;
+}
+
+moc_ruins,81,113,0 trader Item Collector#moc2 4_M_03,{
+OnInit:
+ sellitem Scell;
+ sellitem Monster's_Feed;
+ sellitem Animal's_Skin;
+ sellitem Bill_Of_Birds;
+}
+
+moc_ruins,110,105,2 trader Jeweler#moc1 8_F,{
+OnInit:
+ sellitem Azure_Jewel;
+ sellitem Cardinal_Jewel;
+ sellitem Blue_Jewel;
+ sellitem Golden_Jewel;
+ sellitem Bluish_Green_Jewel;
+}
+
+moc_ruins,52,85,6 trader Jeweler#moc2 4W_M_03,{
+OnInit:
+ sellitem Crystal_Jewel;
+ sellitem Diamond_Ring;
+}
+
+moc_ruins,113,126,4 trader Trader#moc1 4W_M_03,{
+OnInit:
+ sellitem Crystal_Mirror;
+}
+
+moc_ruins,131,138,0 trader Trader#moc2 4_F_04,{
+OnInit:
+ sellitem Witherless_Rose;
+}
+
+moc_ruins,71,139,5 trader Trader#moc3 4_F_04,{
+OnInit:
+ sellitem Flower_Ring;
+}
+
+moc_ruins,125,135,6 trader Trader#moc4 4_M_ORIENT02,{
+OnInit:
+ sellitem Skul_Ring;
+ sellitem Sword_Mace;
+ sellitem Stunner;
+}
+
+moc_ruins,87,109,0 trader Butcher#moc 1_M_MERCHANT,{
+OnInit:
+ sellitem Meat;
+}
+
+moc_ruins,90,149,6 trader Trader#moc5 4W_M_03,{
+OnInit:
+ sellitem Banana;
+ sellitem Banana;
+ sellitem Banana;
+ sellitem Banana;
+ sellitem Banana;
+ sellitem Banana;
+}
+
+moc_ruins,118,170,4 trader Pet Groomer#moc 4_M_TELEPORTER,{
+OnInit:
+ sellitem Pet_Food;
+ sellitem Pet_Incubator;
+ sellitem Backpack;
+ sellitem Rocker_Glasses;
+ sellitem Mojji;
+ sellitem Vital_Flower_;
+ sellitem Flame_Gemstone;
+ sellitem Bun_;
+}
+
+morocc_in,141,67,0 trader Weapon Dealer#moc1 1_M_MERCHANT,{
+OnInit:
+ sellitem Arrow;
+ sellitem Silver_Arrow;
+ sellitem Bow;
+ sellitem Rod;
+ sellitem Knife;
+ sellitem Cutter;
+ sellitem Main_Gauche;
+ sellitem Dirk;
+ sellitem Dagger;
+ sellitem Stiletto;
+ sellitem Gladius;
+ sellitem Damascus;
+ sellitem Jur;
+ sellitem Katar;
+ sellitem Jamadhar;
+}
+
+morocc_in,141,60,0 trader Armor Dealer#moc 1_M_MERCHANT,{
+OnInit:
+ sellitem Guard;
+ sellitem Buckler;
+ sellitem Sandals;
+ sellitem Shoes;
+ sellitem Boots;
+ sellitem Hood;
+ sellitem Muffler;
+ sellitem Flu_Mask;
+ sellitem Cotton_Shirt;
+ sellitem Leather_Jacket;
+ sellitem Adventure_Suit;
+ sellitem Silk_Robe;
+ sellitem Wooden_Mail;
+ sellitem Silver_Robe;
+ sellitem Mantle;
+ sellitem Coat;
+ sellitem Thief_Clothes;
+ sellitem Novice_Armlet;
+}
+
+morocc_in,132,57,0 trader Weapon Dealer#moc2 4W_M_03,{
+OnInit:
+ sellitem Town_Sword;
+ sellitem Cinquedea;
+}
+
//=======================================================
// Moscovia
//=======================================================
-mosk_in,21,254,5 shop Tool Dealer#mosk 4_M_RUSMAN2,611:-1,501:-1,502:-1,503:-1,504:-1,506:-1,645:-1,656:-1,601:-1,602:-1,1065:-1,1750:-1
-mosk_in,31,180,3 shop Weapon Dealer#mosk 4_M_RUSMAN2,1207:-1,1216:-1,1107:-1,1122:-1,1116:-1,1154:-1,1407:-1,1457:-1,1354:-1,1519:-1
-mosk_in,79,178,1 shop Armor Dealer#mosk 4_F_RUSWOMAN3,2211:-1,2401:-1,2403:-1,2501:-1,2503:-1,2101:-1,2103:-1,2305:-1,2321:-1,2332:-1,2328:-1,2627:-1
-moscovia,152,71,4 shop Fruit Gardener#mosk 4_M_RUSMAN2,512:-1,513:-1,515:-1,516:-1
-moscovia,199,110,3 shop Vendor from Milk Ranch#m 4_F_RUSWOMAN1,519:-1
+mosk_in,21,254,5 trader Tool Dealer#mosk 4_M_RUSMAN2,{
+OnInit:
+ sellitem Spectacles;
+ sellitem Red_Potion;
+ sellitem Orange_Potion;
+ sellitem Yellow_Potion;
+ sellitem White_Potion;
+ sellitem Green_Potion;
+ sellitem Center_Potion;
+ sellitem Awakening_Potion;
+ sellitem Wing_Of_Fly;
+ sellitem Wing_Of_Butterfly;
+ sellitem Booby_Trap;
+ sellitem Arrow;
+}
+
+mosk_in,31,180,3 trader Weapon Dealer#mosk 4_M_RUSMAN2,{
+OnInit:
+ sellitem Main_Gauche;
+ sellitem Stiletto;
+ sellitem Blade;
+ sellitem Ring_Pommel_Saber;
+ sellitem Katana;
+ sellitem Bastard_Sword;
+ sellitem Pike;
+ sellitem Partizan;
+ sellitem Hammer;
+ sellitem Chain;
+}
+
+mosk_in,79,178,1 trader Armor Dealer#mosk 4_F_RUSWOMAN3,{
+OnInit:
+ sellitem Bandana;
+ sellitem Sandals;
+ sellitem Shoes;
+ sellitem Hood;
+ sellitem Muffler;
+ sellitem Guard;
+ sellitem Buckler;
+ sellitem Adventure_Suit;
+ sellitem Silk_Robe;
+ sellitem Silver_Robe;
+ sellitem Wooden_Mail;
+ sellitem Belt;
+}
+
+moscovia,152,71,4 trader Fruit Gardener#mosk 4_M_RUSMAN2,{
+OnInit:
+ sellitem Apple;
+ sellitem Banana;
+ sellitem Carrot;
+ sellitem Sweet_Potato;
+}
+
+moscovia,199,110,3 trader Vendor from Milk Ranch#m 4_F_RUSWOMAN1,{
+OnInit:
+ sellitem Milk;
+}
+
//=======================================================
// Niflheim
//=======================================================
-nif_in,37,93,1 shop Axe Dealer#nif 4_NFCOFFIN,1301:-1,1351:-1,1354:-1,1357:-1,1360:-1
-nif_in,37,84,1 shop Armor Dealer#nif 4_NFCOFFIN,2501:-1,2501:-1,2503:-1,2503:-1,2505:-1,2505:-1
-nif_in,145,23,1 shop Tool Dealer#nif 4_NFCOFFIN,535:-1,1062:-1,902:-1,7106:-1,537:-1,7154:-1,1052:-1,934:-1
+nif_in,37,93,1 trader Axe Dealer#nif 4_NFCOFFIN,{
+OnInit:
+ sellitem Axe;
+ sellitem Battle_Axe;
+ sellitem Hammer;
+ sellitem Buster;
+ sellitem Two_Handed_Axe;
+}
+
+nif_in,37,84,1 trader Armor Dealer#nif 4_NFCOFFIN,{
+OnInit:
+ sellitem Hood;
+ sellitem Hood;
+ sellitem Muffler;
+ sellitem Muffler;
+ sellitem Manteau;
+ sellitem Manteau;
+}
+
+nif_in,145,23,1 trader Tool Dealer#nif 4_NFCOFFIN,{
+OnInit:
+ sellitem Pumpkin;
+ sellitem Pumpkin_Head;
+ sellitem Tree_Root;
+ sellitem Goat's_Horn;
+ sellitem Pet_Food;
+ sellitem Poison_Powder;
+ sellitem Single_Cell;
+ sellitem Mementos;
+}
+
//=======================================================
// Payon
//=======================================================
-payon_in01,15,119,0 shop Weapon Dealer#pay 1_F_ORIENT_03,1750:-1,1751:-1,1101:-1,1104:-1,1107:-1,1201:-1,1204:-1,1207:-1,1601:-1,1701:-1,1704:-1,1707:-1,1710:-1,1713:-1,1714:-1,1718:-1
-payon_in01,5,129,7 shop Weapon Dealer#pay2 4_F_KID2,1146:-1,1245:-1
-payon_in01,7,119,2 shop Armor Dealer#pay 1_F_ORIENT_02,2401:-1,2403:-1,2405:-1,2501:-1,2503:-1,2505:-1,2208:-1,2211:-1,2212:-1,2301:-1,2303:-1,2305:-1,2321:-1,2328:-1,2332:-1,2307:-1,2309:-1,2330:-1,2628:-1
-payon_in01,5,49,7 shop Tool Dealer#pay 4_M_ORIENT01,1750:-1,611:-1,501:-1,502:-1,503:-1,504:-1,506:-1,645:-1,656:-1,601:-1,602:-1,1065:-1
-payon_in02,87,34,0 shop Tool Dealer#pay2 1_F_ORIENT_01,1750:-1,1751:-1,611:-1,501:-1,502:-1,503:-1,504:-1,506:-1,645:-1,656:-1,601:-1,602:-1,1065:-1
-payon,159,96,4 shop Tool Dealer#pay3 4_M_ORIENT01,1750:-1,501:-1,645:-1,601:-1,602:-1
-payon,177,131,4 shop Pet Groomer#pay 4_F_TELEPORTER,537:-1,643:-1,10013:-1,10014:-1,554:-1,6114:-1,6113:-1,6110:-1,6115:-1,6100:-1,6098:-1,6112:-1,6104:-1,6108:-1,6111:-1,6095:-1,6099:-1,6096:-1,6097:-1,6094:-1
+payon_in01,15,119,0 trader Weapon Dealer#pay 1_F_ORIENT_03,{
+OnInit:
+ sellitem Arrow;
+ sellitem Silver_Arrow;
+ sellitem Sword;
+ sellitem Falchion;
+ sellitem Blade;
+ sellitem Knife;
+ sellitem Cutter;
+ sellitem Main_Gauche;
+ sellitem Rod;
+ sellitem Bow;
+ sellitem Composite_Bow;
+ sellitem Great_Bow;
+ sellitem CrossBow;
+ sellitem Arbalest;
+ sellitem Kakkung;
+ sellitem Hunter_Bow;
+}
+
+payon_in01,5,129,7 trader Weapon Dealer#pay2 4_F_KID2,{
+OnInit:
+ sellitem Town_Sword;
+ sellitem Cinquedea;
+}
+
+payon_in01,7,119,2 trader Armor Dealer#pay 1_F_ORIENT_02,{
+OnInit:
+ sellitem Sandals;
+ sellitem Shoes;
+ sellitem Boots;
+ sellitem Hood;
+ sellitem Muffler;
+ sellitem Manteau;
+ sellitem Ribbon;
+ sellitem Bandana;
+ sellitem Eye_Bandage;
+ sellitem Cotton_Shirt;
+ sellitem Leather_Jacket;
+ sellitem Adventure_Suit;
+ sellitem Silk_Robe;
+ sellitem Wooden_Mail;
+ sellitem Silver_Robe;
+ sellitem Mantle;
+ sellitem Coat;
+ sellitem Tights;
+ sellitem Novice_Armlet;
+}
+
+payon_in01,5,49,7 trader Tool Dealer#pay 4_M_ORIENT01,{
+OnInit:
+ sellitem Arrow;
+ sellitem Spectacles;
+ sellitem Red_Potion;
+ sellitem Orange_Potion;
+ sellitem Yellow_Potion;
+ sellitem White_Potion;
+ sellitem Green_Potion;
+ sellitem Center_Potion;
+ sellitem Awakening_Potion;
+ sellitem Wing_Of_Fly;
+ sellitem Wing_Of_Butterfly;
+ sellitem Booby_Trap;
+}
+
+payon_in02,87,34,0 trader Tool Dealer#pay2 1_F_ORIENT_01,{
+OnInit:
+ sellitem Arrow;
+ sellitem Silver_Arrow;
+ sellitem Spectacles;
+ sellitem Red_Potion;
+ sellitem Orange_Potion;
+ sellitem Yellow_Potion;
+ sellitem White_Potion;
+ sellitem Green_Potion;
+ sellitem Center_Potion;
+ sellitem Awakening_Potion;
+ sellitem Wing_Of_Fly;
+ sellitem Wing_Of_Butterfly;
+ sellitem Booby_Trap;
+}
+
+payon,159,96,4 trader Tool Dealer#pay3 4_M_ORIENT01,{
+OnInit:
+ sellitem Arrow;
+ sellitem Red_Potion;
+ sellitem Center_Potion;
+ sellitem Wing_Of_Fly;
+ sellitem Wing_Of_Butterfly;
+}
+
+payon,177,131,4 trader Pet Groomer#pay 4_F_TELEPORTER,{
+OnInit:
+ sellitem Pet_Food;
+ sellitem Pet_Incubator;
+ sellitem Backpack;
+ sellitem Rocker_Glasses;
+ sellitem Mojji;
+ sellitem Flame_Gemstone;
+ sellitem Vital_Flower_;
+ sellitem Vital_Flower;
+ sellitem Bun_;
+ sellitem Damp_Darkness;
+ sellitem Small_Snow_Flower;
+ sellitem Fresh_Plant;
+ sellitem Big_Cell;
+ sellitem Apple_Pudding;
+ sellitem Mystic_Stone;
+ sellitem Flavored_Alcohol;
+ sellitem Grilled_Rice_Cake;
+ sellitem Fish_With_Blue_Back;
+ sellitem Pumpkin_Pie_;
+ sellitem Traditional_Cookie;
+}
+
//=======================================================
// Prontera
//=======================================================
-prontera,73,134,0 shop Vendor from Milk Ranch#p 4_F_01,519:-1
-prontera,104,49,0 shop Fruit Gardener#prt 8_F,512:-1,513:-1
-prontera,64,125,0 shop Butcher#prt 4_M_BARBER,517:-1,528:-1
-prontera,58,182,0 shop Flower Girl#prt 4W_KID,712:-1,744:-1
-prontera,113,42,0 shop Flower Lady#prt 4_F_01,712:-1,744:-1
-prontera,105,87,0 shop Gift Merchant#prt 4_F_02,734:-1,735:-1,736:-1,737:-1,746:-1
-prontera,218,211,4 shop Pet Groomer#prt 4_M_TELEPORTER,537:-1,643:-1,10013:-1,10014:-1,554:-1,6114:-1,6113:-1,6110:-1,6115:-1,6100:-1,6098:-1,6112:-1,6104:-1,6108:-1,6111:-1,6095:-1,6099:-1,6096:-1,6097:-1,6094:-1
-prontera,248,153,0 shop Doll Supplier#prt 4_M_03,740:-1,741:-1,742:-1
-prontera,48,58,0 shop Vegetable Gardener#prt 4_F_02,515:-1,516:-1,535:-1
-prt_church,108,124,4 shop Nun#prt 1_F_PRIEST,2608:-1,2216:-1,5092:-1,2323:-1,2325:-1,1501:-1,1504:-1,1507:-1,1510:-1,1513:-1,1519:-1
-prt_fild05,290,221,2 shop Tool Dealer#prt 4_M_01,1750:-1,611:-1,501:-1,502:-1,506:-1,645:-1,601:-1,602:-1
-prt_in,211,169,0 shop Wedding Shop Dealer#prt 1_F_LIBRARYGIRL,744:-1,745:-1,2338:-1,2206:-1,7170:-1
-prt_in,126,76,0 shop Tool Dealer#prt1 1_M_INNKEEPER,611:-1,1750:-1,501:-1,502:-1,503:-1,504:-1,506:-1,645:-1,656:-1,601:-1,602:-1,1065:-1,2239:-1
-prt_in,172,130,0 shop Weapon Dealer#prt 1_M_JOBGUIDER,1750:-1,1751:-1,1701:-1,1201:-1,1204:-1,1207:-1,1601:-1,1101:-1,1104:-1,1107:-1,1110:-1,1113:-1,1122:-1,1119:-1,1123:-1,1126:-1,1129:-1,1116:-1,1301:-1
-prt_in,172,132,0 shop Armor Dealer#prt 1_M_02,2101:-1,2103:-1,2401:-1,2403:-1,2501:-1,2503:-1,2220:-1,2226:-1,2301:-1,2303:-1,2305:-1,2328:-1,2307:-1,2309:-1,2312:-1,2314:-1,2628:-1,2627:-1
-prt_in,171,140,0 shop Weapon Dealer#prt2 1_M_01,1401:-1,1404:-1,1407:-1,1451:-1,1454:-1,1457:-1,1460:-1,1463:-1,1410:-1
-prt_in,165,140,4 shop Weapon Dealer#prt3 1_F_01,1146:-1,1245:-1
-prt_monk,135,263,5 shop Weapon Dealer#prt4 4_F_JOB_BLACKSMITH,1801:-1,1803:-1,1805:-1
+prontera,73,134,0 trader Vendor from Milk Ranch#p 4_F_01,{
+OnInit:
+ sellitem Milk;
+}
+
+prontera,104,49,0 trader Fruit Gardener#prt 8_F,{
+OnInit:
+ sellitem Apple;
+ sellitem Banana;
+}
+
+prontera,64,125,0 trader Butcher#prt 4_M_BARBER,{
+OnInit:
+ sellitem Meat;
+ sellitem Monster's_Feed;
+}
+
+prontera,58,182,0 trader Flower Girl#prt 4W_KID,{
+OnInit:
+ sellitem Flower;
+ sellitem Bunch_Of_Flowers;
+}
+
+prontera,113,42,0 trader Flower Lady#prt 4_F_01,{
+OnInit:
+ sellitem Flower;
+ sellitem Bunch_Of_Flowers;
+}
+
+prontera,105,87,0 trader Gift Merchant#prt 4_F_02,{
+OnInit:
+ sellitem Red_Frame;
+ sellitem Blue_Porcelain;
+ sellitem White_Platter;
+ sellitem Black_Ladle;
+ sellitem Glass_Bead;
+}
+
+prontera,218,211,4 trader Pet Groomer#prt 4_M_TELEPORTER,{
+OnInit:
+ sellitem Pet_Food;
+ sellitem Pet_Incubator;
+ sellitem Backpack;
+ sellitem Rocker_Glasses;
+ sellitem Mojji;
+ sellitem Flame_Gemstone;
+ sellitem Vital_Flower_;
+ sellitem Vital_Flower;
+ sellitem Bun_;
+ sellitem Damp_Darkness;
+ sellitem Small_Snow_Flower;
+ sellitem Fresh_Plant;
+ sellitem Big_Cell;
+ sellitem Apple_Pudding;
+ sellitem Mystic_Stone;
+ sellitem Flavored_Alcohol;
+ sellitem Grilled_Rice_Cake;
+ sellitem Fish_With_Blue_Back;
+ sellitem Pumpkin_Pie_;
+ sellitem Traditional_Cookie;
+}
+
+prontera,248,153,0 trader Doll Supplier#prt 4_M_03,{
+OnInit:
+ sellitem Stuffed_Doll;
+ sellitem Poring_Doll;
+ sellitem Chonchon_Doll;
+}
+
+prontera,48,58,0 trader Vegetable Gardener#prt 4_F_02,{
+OnInit:
+ sellitem Carrot;
+ sellitem Sweet_Potato;
+ sellitem Pumpkin;
+}
+
+prt_church,108,124,4 trader Nun#prt 1_F_PRIEST,{
+OnInit:
+ sellitem Rosary;
+ sellitem Biretta;
+ sellitem Blue_Coif;
+ sellitem Scapulare;
+ sellitem Saint_Robe;
+ sellitem Club;
+ sellitem Mace;
+ sellitem Smasher;
+ sellitem Flail;
+ sellitem Morning_Star;
+ sellitem Chain;
+}
+
+prt_fild05,290,221,2 trader Tool Dealer#prt 4_M_01,{
+OnInit:
+ sellitem Arrow;
+ sellitem Spectacles;
+ sellitem Red_Potion;
+ sellitem Orange_Potion;
+ sellitem Green_Potion;
+ sellitem Center_Potion;
+ sellitem Wing_Of_Fly;
+ sellitem Wing_Of_Butterfly;
+}
+
+prt_in,211,169,0 trader Wedding Shop Dealer#prt 1_F_LIBRARYGIRL,{
+OnInit:
+ sellitem Bunch_Of_Flowers;
+ sellitem Wedding_Bouquet;
+ sellitem Wedding_Dress;
+ sellitem Wedding_Veil;
+ sellitem Tuxedo;
+}
+
+prt_in,126,76,0 trader Tool Dealer#prt1 1_M_INNKEEPER,{
+OnInit:
+ sellitem Spectacles;
+ sellitem Arrow;
+ sellitem Red_Potion;
+ sellitem Orange_Potion;
+ sellitem Yellow_Potion;
+ sellitem White_Potion;
+ sellitem Green_Potion;
+ sellitem Center_Potion;
+ sellitem Awakening_Potion;
+ sellitem Wing_Of_Fly;
+ sellitem Wing_Of_Butterfly;
+ sellitem Booby_Trap;
+ sellitem One_Eyed_Glass;
+}
+
+prt_in,172,130,0 trader Weapon Dealer#prt 1_M_JOBGUIDER,{
+OnInit:
+ sellitem Arrow;
+ sellitem Silver_Arrow;
+ sellitem Bow;
+ sellitem Knife;
+ sellitem Cutter;
+ sellitem Main_Gauche;
+ sellitem Rod;
+ sellitem Sword;
+ sellitem Falchion;
+ sellitem Blade;
+ sellitem Lapier;
+ sellitem Scimiter;
+ sellitem Ring_Pommel_Saber;
+ sellitem Tsurugi;
+ sellitem Haedonggum;
+ sellitem Saber;
+ sellitem Flamberge;
+ sellitem Katana;
+ sellitem Axe;
+}
+
+prt_in,172,132,0 trader Armor Dealer#prt 1_M_02,{
+OnInit:
+ sellitem Guard;
+ sellitem Buckler;
+ sellitem Sandals;
+ sellitem Shoes;
+ sellitem Hood;
+ sellitem Muffler;
+ sellitem Hat;
+ sellitem Cap;
+ sellitem Cotton_Shirt;
+ sellitem Leather_Jacket;
+ sellitem Adventure_Suit;
+ sellitem Wooden_Mail;
+ sellitem Mantle;
+ sellitem Coat;
+ sellitem Padded_Armor;
+ sellitem Chain_Mail;
+ sellitem Novice_Armlet;
+ sellitem Belt;
+}
+
+prt_in,171,140,0 trader Weapon Dealer#prt2 1_M_01,{
+OnInit:
+ sellitem Javelin;
+ sellitem Spear;
+ sellitem Pike;
+ sellitem Guisarme;
+ sellitem Glaive;
+ sellitem Partizan;
+ sellitem Trident;
+ sellitem Halberd;
+ sellitem Lance;
+}
+
+prt_in,165,140,4 trader Weapon Dealer#prt3 1_F_01,{
+OnInit:
+ sellitem Town_Sword;
+ sellitem Cinquedea;
+}
+
+prt_monk,135,263,5 trader Weapon Dealer#prt4 4_F_JOB_BLACKSMITH,{
+OnInit:
+ sellitem Waghnakh;
+ sellitem Knuckle_Duster;
+ sellitem Hora;
+}
+
//=======================================================
// Rachel
//=======================================================
-ra_in01,175,364,3 shop Armor Dealer#ra 4_F_SHABBY,2101:-1,2103:-1,2403:-1,2405:-1,2503:-1,2321:-1,2314:-1,2309:-1,2335:-1,2628:-1
-ra_in01,257,269,3 shop Tool Dealer#ra 4_F_SHABBY,501:-1,502:-1,503:-1,504:-1,506:-1,645:-1,656:-1,601:-1,602:-1,611:-1,1065:-1,610:-1
-ra_in01,176,389,3 shop Weapon Dealer#ra 4_M_RACHMAN1,1201:-1,1207:-1,1216:-1,1107:-1,1122:-1,1116:-1,1154:-1,1407:-1,1457:-1,1354:-1,1519:-1,13003:-1,1601:-1,1604:-1,1607:-1
-ra_in01,254,300,3 shop Fruit Gardener#ra 4_M_RACHMAN1,512:-1,513:-1
-rachel,65,80,1 shop Vegetable Gardener#ra 4_F_SHABBY,515:-1,535:-1,516:-1
+ra_in01,175,364,3 trader Armor Dealer#ra 4_F_SHABBY,{
+OnInit:
+ sellitem Guard;
+ sellitem Buckler;
+ sellitem Shoes;
+ sellitem Boots;
+ sellitem Muffler;
+ sellitem Silk_Robe;
+ sellitem Chain_Mail;
+ sellitem Coat;
+ sellitem Thief_Clothes;
+ sellitem Novice_Armlet;
+}
+
+ra_in01,257,269,3 trader Tool Dealer#ra 4_F_SHABBY,{
+OnInit:
+ sellitem Red_Potion;
+ sellitem Orange_Potion;
+ sellitem Yellow_Potion;
+ sellitem White_Potion;
+ sellitem Green_Potion;
+ sellitem Center_Potion;
+ sellitem Awakening_Potion;
+ sellitem Wing_Of_Fly;
+ sellitem Wing_Of_Butterfly;
+ sellitem Spectacles;
+ sellitem Booby_Trap;
+ sellitem Leaf_Of_Yggdrasil;
+}
+
+ra_in01,176,389,3 trader Weapon Dealer#ra 4_M_RACHMAN1,{
+OnInit:
+ sellitem Knife;
+ sellitem Main_Gauche;
+ sellitem Stiletto;
+ sellitem Blade;
+ sellitem Ring_Pommel_Saber;
+ sellitem Katana;
+ sellitem Bastard_Sword;
+ sellitem Pike;
+ sellitem Partizan;
+ sellitem Hammer;
+ sellitem Chain;
+ sellitem Coward;
+ sellitem Rod;
+ sellitem Wand;
+ sellitem Staff;
+}
+
+ra_in01,254,300,3 trader Fruit Gardener#ra 4_M_RACHMAN1,{
+OnInit:
+ sellitem Apple;
+ sellitem Banana;
+}
+
+rachel,65,80,1 trader Vegetable Gardener#ra 4_F_SHABBY,{
+OnInit:
+ sellitem Carrot;
+ sellitem Pumpkin;
+ sellitem Sweet_Potato;
+}
+
//=======================================================
// Turtle Island
//=======================================================
-tur_dun01,158,54,6 shop Tool Dealer#tu 4W_M_03,1750:-1,501:-1,502:-1,503:-1,504:-1,506:-1,601:-1,602:-1,645:-1,656:-1,2242:-1
+tur_dun01,158,54,6 trader Tool Dealer#tu 4W_M_03,{
+OnInit:
+ sellitem Arrow;
+ sellitem Red_Potion;
+ sellitem Orange_Potion;
+ sellitem Yellow_Potion;
+ sellitem White_Potion;
+ sellitem Green_Potion;
+ sellitem Wing_Of_Fly;
+ sellitem Wing_Of_Butterfly;
+ sellitem Center_Potion;
+ sellitem Awakening_Potion;
+ sellitem Luxury_Sunglasses;
+}
+
//=======================================================
// Umbala
//=======================================================
-um_in,104,124,3 shop Tool Dealer#um 4_M_UMOLDMAN,512:-1,515:-1,535:-1,516:-1,513:-1,517:-1,528:-1,537:-1,601:-1,602:-1,645:-1,656:-1,610:-1
-um_in,160,125,3 shop Weapon Dealer#um 4_M_UMSOLDIER,1501:-1,1504:-1,1507:-1,1510:-1,1513:-1,1519:-1,1807:-1,1811:-1,1809:-1
+um_in,104,124,3 trader Tool Dealer#um 4_M_UMOLDMAN,{
+OnInit:
+ sellitem Apple;
+ sellitem Carrot;
+ sellitem Pumpkin;
+ sellitem Sweet_Potato;
+ sellitem Banana;
+ sellitem Meat;
+ sellitem Monster's_Feed;
+ sellitem Pet_Food;
+ sellitem Wing_Of_Fly;
+ sellitem Wing_Of_Butterfly;
+ sellitem Center_Potion;
+ sellitem Awakening_Potion;
+ sellitem Leaf_Of_Yggdrasil;
+}
+
+um_in,160,125,3 trader Weapon Dealer#um 4_M_UMSOLDIER,{
+OnInit:
+ sellitem Club;
+ sellitem Mace;
+ sellitem Smasher;
+ sellitem Flail;
+ sellitem Morning_Star;
+ sellitem Chain;
+ sellitem Fist;
+ sellitem Finger;
+ sellitem Claw;
+}
+
//=======================================================
// Veins
//=======================================================
-ve_in,386,245,3 shop Weapon Dealer#ve 4_M_RACHMAN1,1201:-1,1207:-1,1216:-1,1107:-1,1122:-1,1116:-1,1154:-1
-ve_in,336,243,3 shop Weapon Dealer#ve2 4_M_RACHMAN1,1407:-1,1457:-1,1354:-1,1519:-1,13003:-1
-ve_in,374,230,3 shop Armor Dealer#ve 4_F_SHABBY,2101:-1,2103:-1,2403:-1,2405:-1,2503:-1,2321:-1,2314:-1,2309:-1,2335:-1,2628:-1
-ve_in,243,303,5 shop Tool Dealer#ve 4_M_DESERT,501:-1,502:-1,503:-1,504:-1,506:-1,645:-1,656:-1,601:-1,602:-1,611:-1,1065:-1,610:-1
-ve_in,253,304,5 shop Fruit Gardener#ve 4_F_DST_CHILD,512:-1,513:-1
-ve_in,252,313,0 shop Magical Item Seller#ve 4_F_DST_GRAND,717:-1,1601:-1,1604:-1,1607:-1,1610:-1,2232:-1,2321:-1,2332:-1
+ve_in,386,245,3 trader Weapon Dealer#ve 4_M_RACHMAN1,{
+OnInit:
+ sellitem Knife;
+ sellitem Main_Gauche;
+ sellitem Stiletto;
+ sellitem Blade;
+ sellitem Ring_Pommel_Saber;
+ sellitem Katana;
+ sellitem Bastard_Sword;
+}
+
+ve_in,336,243,3 trader Weapon Dealer#ve2 4_M_RACHMAN1,{
+OnInit:
+ sellitem Pike;
+ sellitem Partizan;
+ sellitem Hammer;
+ sellitem Chain;
+ sellitem Coward;
+}
+
+ve_in,374,230,3 trader Armor Dealer#ve 4_F_SHABBY,{
+OnInit:
+ sellitem Guard;
+ sellitem Buckler;
+ sellitem Shoes;
+ sellitem Boots;
+ sellitem Muffler;
+ sellitem Silk_Robe;
+ sellitem Chain_Mail;
+ sellitem Coat;
+ sellitem Thief_Clothes;
+ sellitem Novice_Armlet;
+}
+
+ve_in,243,303,5 trader Tool Dealer#ve 4_M_DESERT,{
+OnInit:
+ sellitem Red_Potion;
+ sellitem Orange_Potion;
+ sellitem Yellow_Potion;
+ sellitem White_Potion;
+ sellitem Green_Potion;
+ sellitem Center_Potion;
+ sellitem Awakening_Potion;
+ sellitem Wing_Of_Fly;
+ sellitem Wing_Of_Butterfly;
+ sellitem Spectacles;
+ sellitem Booby_Trap;
+ sellitem Leaf_Of_Yggdrasil;
+}
+
+ve_in,253,304,5 trader Fruit Gardener#ve 4_F_DST_CHILD,{
+OnInit:
+ sellitem Apple;
+ sellitem Banana;
+}
+
+ve_in,252,313,0 trader Magical Item Seller#ve 4_F_DST_GRAND,{
+OnInit:
+ sellitem Blue_Gemstone;
+ sellitem Rod;
+ sellitem Wand;
+ sellitem Staff;
+ sellitem Arc_Wand;
+ sellitem Circlet;
+ sellitem Silk_Robe;
+ sellitem Silver_Robe;
+}
+
//=======================================================
// Cooking Addition
//=======================================================
-prontera,156,212,1 shop Chef Assistant#prt 8_F_GIRL,7454:-1,7456:-1,7482:-1,580:-1
-payon,206,119,5 shop Chef Assistant#pay 4_M_ORIENT02,7455:-1
-moc_ruins,115,123,5 shop Chef Assistant#moc 4_M_04,7455:-1,7453:-1,7454:-1,7456:-1,7452:-1
-geffen,196,111,3 shop Chef Assistant#gef 4_M_03,7482:-1
-alberta,167,135,5 shop Chef Assistant#alb 4_M_05,579:-1
-aldebaran,165,107,2 shop Chef Assistant#alde 4W_M_01,7456:-1,7452:-1,580:-1
-comodo,225,164,3 shop Chef Assistant#cmd 4_M_01,7455:-1,7453:-1,7454:-1,579:-1
-umbala,102,154,3 shop Chef Assistant#um 4_M_01,7456:-1,577:-1
-yuno,130,173,3 shop Chef Assistant#yuno 4_M_01,7457:-1,7482:-1
-einbroch,224,207,5 shop Chef Assistant#ein 4_M_01,7457:-1
-lighthalzen,126,126,3 shop Chef Assistant#lhz 4_M_01,7456:-1,7452:-1
-amatsu,206,150,3 shop Chef Assistant#ama 4_M_01,7453:-1,579:-1
-louyang,256,123,5 shop Chef Assistant#lou 4_M_CHNCOOK,7454:-1,577:-1
-gonryun,147,101,5 shop Chef Assistant#gon 4_M_01,7452:-1,580:-1
-ayothaya,203,178,3 shop Chef Assistant#ayo 4_M_01,7455:-1,577:-1
-xmas,152,137,5 shop Chef Assistant#xmas 4_M_01,7457:-1,577:-1
-niflheim,209,180,5 shop Chef Assistant#nif 4_M_01,581:-1
+prontera,156,212,1 trader Chef Assistant#prt 8_F_GIRL,{
+OnInit:
+ sellitem Plain_Sauce;
+ sellitem Red_Spice;
+ sellitem Pot;
+ sellitem Bread;
+}
+
+payon,206,119,5 trader Chef Assistant#pay 4_M_ORIENT02,{
+OnInit:
+ sellitem Hot_Sauce;
+}
+
+moc_ruins,115,123,5 trader Chef Assistant#moc 4_M_04,{
+OnInit:
+ sellitem Hot_Sauce;
+ sellitem Sweet_Sauce;
+ sellitem Plain_Sauce;
+ sellitem Red_Spice;
+ sellitem Yellow_Spice;
+}
+
+geffen,196,111,3 trader Chef Assistant#gef 4_M_03,{
+OnInit:
+ sellitem Pot;
+}
+
+alberta,167,135,5 trader Chef Assistant#alb 4_M_05,{
+OnInit:
+ sellitem Delicious_Fish;
+}
+
+aldebaran,165,107,2 trader Chef Assistant#alde 4W_M_01,{
+OnInit:
+ sellitem Red_Spice;
+ sellitem Yellow_Spice;
+ sellitem Bread;
+}
+
+comodo,225,164,3 trader Chef Assistant#cmd 4_M_01,{
+OnInit:
+ sellitem Hot_Sauce;
+ sellitem Sweet_Sauce;
+ sellitem Plain_Sauce;
+ sellitem Delicious_Fish;
+}
+
+umbala,102,154,3 trader Chef Assistant#um 4_M_01,{
+OnInit:
+ sellitem Red_Spice;
+ sellitem Grain;
+}
+
+yuno,130,173,3 trader Chef Assistant#yuno 4_M_01,{
+OnInit:
+ sellitem Cooking_Oil;
+ sellitem Pot;
+}
+
+einbroch,224,207,5 trader Chef Assistant#ein 4_M_01,{
+OnInit:
+ sellitem Cooking_Oil;
+}
+
+lighthalzen,126,126,3 trader Chef Assistant#lhz 4_M_01,{
+OnInit:
+ sellitem Red_Spice;
+ sellitem Yellow_Spice;
+}
+
+amatsu,206,150,3 trader Chef Assistant#ama 4_M_01,{
+OnInit:
+ sellitem Sweet_Sauce;
+ sellitem Delicious_Fish;
+}
+
+louyang,256,123,5 trader Chef Assistant#lou 4_M_CHNCOOK,{
+OnInit:
+ sellitem Plain_Sauce;
+ sellitem Grain;
+}
+
+gonryun,147,101,5 trader Chef Assistant#gon 4_M_01,{
+OnInit:
+ sellitem Yellow_Spice;
+ sellitem Bread;
+}
+
+ayothaya,203,178,3 trader Chef Assistant#ayo 4_M_01,{
+OnInit:
+ sellitem Hot_Sauce;
+ sellitem Grain;
+}
+
+xmas,152,137,5 trader Chef Assistant#xmas 4_M_01,{
+OnInit:
+ sellitem Cooking_Oil;
+ sellitem Grain;
+}
+
+niflheim,209,180,5 trader Chef Assistant#nif 4_M_01,{
+OnInit:
+ sellitem Mushroom;
+}
+
//===== Additional Comments(old): =================================
//= swapped shop titles in GONRYUN, thanks to Kashy
@@ -364,4 +2240,4 @@ niflheim,209,180,5 shop Chef Assistant#nif 4_M_01,581:-1
//= 1.9a Pet Merchant -> Lighthalzen [erKURITA]
//= 1.9b Added items to Chivas Regal
//= 1.9c Slight update for Rachel shop: Tool Dealer -> Fruit Gardener [L0ne_W0lf]
-//============================================================
+//============================================================ \ No newline at end of file
diff --git a/sql-files/main.sql b/sql-files/main.sql
index 60b21285d..906c329fa 100644
--- a/sql-files/main.sql
+++ b/sql-files/main.sql
@@ -671,6 +671,7 @@ INSERT INTO `sql_updates` (`timestamp`) VALUES (1383205740);
INSERT INTO `sql_updates` (`timestamp`) VALUES (1383955424);
INSERT INTO `sql_updates` (`timestamp`) VALUES (1384545461);
INSERT INTO `sql_updates` (`timestamp`) VALUES (1384588175);
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1387844126);
--
-- Table structure for table `sstatus`
@@ -731,3 +732,14 @@ CREATE TABLE IF NOT EXISTS `account_data` (
PRIMARY KEY (`account_id`)
) ENGINE=MyISAM;
+--
+-- Table structure for table `npc_market_data`
+--
+
+CREATE TABLE IF NOT EXISTS `npc_market_data` (
+ `name` varchar(24) NOT NULL default '',
+ `itemid` int(11) unsigned NOT NULL default '0',
+ `amount` int(11) unsigned NOT NULL default '0',
+ PRIMARY KEY (`name`,`itemid`)
+) ENGINE=MyISAM;
+
diff --git a/sql-files/upgrades/2013-12-24--00-15.sql b/sql-files/upgrades/2013-12-24--00-15.sql
new file mode 100644
index 000000000..b1f8d019d
--- /dev/null
+++ b/sql-files/upgrades/2013-12-24--00-15.sql
@@ -0,0 +1,8 @@
+#1387844126
+CREATE TABLE IF NOT EXISTS `npc_market_data` (
+ `name` varchar(24) NOT NULL default '',
+ `itemid` int(11) unsigned NOT NULL default '0',
+ `amount` int(11) unsigned NOT NULL default '0',
+ PRIMARY KEY (`name`,`itemid`)
+) ENGINE=MyISAM;
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1387844126);
diff --git a/sql-files/upgrades/index.txt b/sql-files/upgrades/index.txt
index 9b7ad20d8..0c4ac87e5 100644
--- a/sql-files/upgrades/index.txt
+++ b/sql-files/upgrades/index.txt
@@ -15,3 +15,4 @@
2013-11-15--19-57.sql
2013-11-16--07-49.sql
2013-11-18--08-23.sql
+2013-12-24--00-15.sql \ No newline at end of file
diff --git a/src/common/mmo.h b/src/common/mmo.h
index b33b01fa7..bd5da6a9f 100644
--- a/src/common/mmo.h
+++ b/src/common/mmo.h
@@ -48,7 +48,7 @@
// 20120307 - 2012-03-07aRagexeRE+ - 0x970
#ifndef PACKETVER
-#define PACKETVER 20120418
+ #define PACKETVER 20131223
#endif // PACKETVER
#ifndef DISABLE_PACKETVER_RE
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index 953f1a0dc..ce73319e2 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -9273,17 +9273,28 @@ ACMD(searchstore){
return true;
}
ACMD(costume){
- const char* names[4] = {
+ const char* names[] = {
"Wedding",
"Xmas",
"Summer",
"Hanbok",
+#if PACKETVER >= 20131218
+ "Oktoberfest",
+#endif
+ };
+ const int name2id[] = {
+ SC_WEDDING,
+ SC_XMAS,
+ SC_SUMMER,
+ SC_HANBOK,
+#if PACKETVER >= 20131218
+ SC_OKTOBERFEST,
+#endif
};
- const int name2id[4] = { SC_WEDDING, SC_XMAS, SC_SUMMER, SC_HANBOK };
- unsigned short k = 0;
+ unsigned short k = 0, len = ARRAYLENGTH(names);
if( !message || !*message ) {
- for( k = 0; k < 4; k++ ) {
+ for( k = 0; k < len; k++ ) {
if( sd->sc.data[name2id[k]] ) {
sprintf(atcmd_output,msg_txt(1473),names[k]);//Costume '%s' removed.
clif->message(sd->fd,atcmd_output);
@@ -9293,14 +9304,14 @@ ACMD(costume){
}
clif->message(sd->fd,msg_txt(1472));
- for( k = 0; k < 4; k++ ) {
+ for( k = 0; k < len; k++ ) {
sprintf(atcmd_output,msg_txt(1471),names[k]);//-- %s
clif->message(sd->fd,atcmd_output);
}
return false;
}
- for( k = 0; k < 4; k++ ) {
+ for( k = 0; k < len; k++ ) {
if( sd->sc.data[name2id[k]] ) {
sprintf(atcmd_output,msg_txt(1470),names[k]);// You're already with a '%s' costume, type '@costume' to remove it.
clif->message(sd->fd,atcmd_output);
@@ -9308,11 +9319,11 @@ ACMD(costume){
}
}
- for( k = 0; k < 4; k++ ) {
+ for( k = 0; k < len; k++ ) {
if( strcmpi(message,names[k]) == 0 )
break;
}
- if( k == 4 ) {
+ if( k == len ) {
sprintf(atcmd_output,msg_txt(1469),message);// '%s' is not a known costume
clif->message(sd->fd,atcmd_output);
return false;
diff --git a/src/map/clif.c b/src/map/clif.c
index 6a55ad344..b442d6279 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -61,7 +61,8 @@ static struct packet_itemlist_equip itemlist_equip;
static struct packet_storelist_normal storelist_normal;
static struct packet_storelist_equip storelist_equip;
static struct packet_viewequip_ack viewequip_list;
-
+static struct packet_npc_market_result_ack npcmarket_result;
+static struct packet_npc_market_open npcmarket_open;
//#define DUMP_UNKNOWN_PACKET
//#define DUMP_INVALID_PACKET
@@ -811,7 +812,7 @@ void clif_clearunit_delayed(struct block_list* bl, clr_type type, int64 tick) {
void clif_get_weapon_view(struct map_session_data* sd, unsigned short *rhand, unsigned short *lhand)
{
- if(sd->sc.option&(OPTION_WEDDING|OPTION_XMAS|OPTION_SUMMER|OPTION_HANBOK)) {
+ if(sd->sc.option&(OPTION_WEDDING|OPTION_XMAS|OPTION_SUMMER|OPTION_HANBOK|OPTION_OKTOBERFEST)) {
*rhand = *lhand = 0;
return;
}
@@ -1743,29 +1744,40 @@ void clif_npcbuysell(struct map_session_data* sd, int id)
/// Presents list of items, that can be bought in an NPC shop (ZC_PC_PURCHASE_ITEMLIST).
/// 00c6 <packet len>.W { <price>.L <discount price>.L <item type>.B <name id>.W }*
-void clif_buylist(struct map_session_data *sd, struct npc_data *nd)
-{
+void clif_buylist(struct map_session_data *sd, struct npc_data *nd) {
+ struct npc_item_list *shop = NULL;
+ unsigned short shop_size = 0;
int fd,i,c;
-
+
nullpo_retv(sd);
nullpo_retv(nd);
+ if( nd->subtype == SCRIPT ) {
+ shop = nd->u.scr.shop->item;
+ shop_size = nd->u.scr.shop->items;
+ } else {
+ shop = nd->u.shop.shop_item;
+ shop_size = nd->u.shop.count;
+ }
+
fd = sd->fd;
- WFIFOHEAD(fd, 4 + nd->u.shop.count * 11);
+
+ WFIFOHEAD(fd, 4 + shop_size * 11);
WFIFOW(fd,0) = 0xc6;
c = 0;
- for( i = 0; i < nd->u.shop.count; i++ )
- {
- struct item_data* id = itemdb->exists(nd->u.shop.shop_item[i].nameid);
- int val = nd->u.shop.shop_item[i].value;
- if( id == NULL )
- continue;
- WFIFOL(fd, 4+c*11) = val;
- WFIFOL(fd, 8+c*11) = pc->modifybuyvalue(sd,val);
- WFIFOB(fd,12+c*11) = itemtype(id->type);
- WFIFOW(fd,13+c*11) = ( id->view_id > 0 ) ? id->view_id : id->nameid;
- c++;
+ for( i = 0; i < shop_size; i++ ) {
+ if( shop[i].nameid ) {
+ struct item_data* id = itemdb->exists(shop[i].nameid);
+ int val = shop[i].value;
+ if( id == NULL )
+ continue;
+ WFIFOL(fd, 4+c*11) = val;
+ WFIFOL(fd, 8+c*11) = pc->modifybuyvalue(sd,val);
+ WFIFOB(fd,12+c*11) = itemtype(id->type);
+ WFIFOW(fd,13+c*11) = ( id->view_id > 0 ) ? id->view_id : id->nameid;
+ c++;
+ }
}
WFIFOW(fd,2) = 4 + c*11;
@@ -3170,7 +3182,7 @@ void clif_changelook(struct block_list *bl,int type,int val)
case LOOK_BASE:
if( !sd ) break;
- if( sd->sc.option&(OPTION_WEDDING|OPTION_XMAS|OPTION_SUMMER|OPTION_HANBOK) )
+ if( sd->sc.option&(OPTION_WEDDING|OPTION_XMAS|OPTION_SUMMER|OPTION_HANBOK|OPTION_OKTOBERFEST) )
vd->weapon = vd->shield = 0;
if( !vd->cloth_color )
@@ -3185,6 +3197,8 @@ void clif_changelook(struct block_list *bl,int type,int val)
vd->cloth_color = 0;
if( sd->sc.option&OPTION_HANBOK && battle_config.hanbok_ignorepalette )
vd->cloth_color = 0;
+ if( sd->sc.option&OPTION_OKTOBERFEST /* TODO: config? */ )
+ vd->cloth_color = 0;
}
break;
case LOOK_HAIR:
@@ -3212,6 +3226,8 @@ void clif_changelook(struct block_list *bl,int type,int val)
val = 0;
if( sd->sc.option&OPTION_HANBOK && battle_config.hanbok_ignorepalette )
val = 0;
+ if( sd->sc.option&OPTION_OKTOBERFEST /* TODO: config? */ )
+ val = 0;
}
vd->cloth_color = val;
break;
@@ -9616,6 +9632,7 @@ void clif_parse_Hotkey(int fd, struct map_session_data *sd) {
/// Displays cast-like progress bar (ZC_PROGRESS).
/// 02f0 <color>.L <time>.L
+/* TODO ZC_PROGRESS_ACTOR <account_id>.L */
void clif_progressbar(struct map_session_data * sd, unsigned int color, unsigned int second)
{
int fd = sd->fd;
@@ -9901,6 +9918,7 @@ void clif_parse_GlobalMessage(int fd, struct map_session_data* sd)
WFIFOW(fd,0) = 0x8e;
}
WFIFOSET(fd, WFIFOW(fd,2));
+
#ifdef PCRE_SUPPORT
// trigger listening npcs
map->foreachinrange(npc_chat->sub, &sd->bl, AREA_SIZE, BL_NPC, text, textlen, &sd->bl);
@@ -10058,7 +10076,7 @@ void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type,
if( pc_cant_act(sd) || sd->sc.option&OPTION_HIDE )
return;
- if( sd->sc.option&(OPTION_WEDDING|OPTION_XMAS|OPTION_SUMMER|OPTION_HANBOK) )
+ if( sd->sc.option&(OPTION_WEDDING|OPTION_XMAS|OPTION_SUMMER|OPTION_HANBOK|OPTION_OKTOBERFEST) )
return;
if( sd->sc.data[SC_BASILICA] || sd->sc.data[SC__SHADOWFORM] )
@@ -11303,7 +11321,7 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd)
}
}
- if( sd->sc.option&(OPTION_WEDDING|OPTION_XMAS|OPTION_SUMMER|OPTION_HANBOK) )
+ if( sd->sc.option&(OPTION_WEDDING|OPTION_XMAS|OPTION_SUMMER|OPTION_HANBOK|OPTION_OKTOBERFEST) )
return;
if( sd->sc.data[SC_BASILICA] && (skill_id != HP_BASILICA || sd->sc.data[SC_BASILICA]->val4 != sd->bl.id) )
@@ -11395,7 +11413,7 @@ void clif_parse_UseSkillToPosSub(int fd, struct map_session_data *sd, uint16 ski
}
}
- if( sd->sc.option&(OPTION_WEDDING|OPTION_XMAS|OPTION_SUMMER|OPTION_HANBOK) )
+ if( sd->sc.option&(OPTION_WEDDING|OPTION_XMAS|OPTION_SUMMER|OPTION_HANBOK|OPTION_OKTOBERFEST) )
return;
if( sd->sc.data[SC_BASILICA] && (skill_id != HP_BASILICA || sd->sc.data[SC_BASILICA]->val4 != sd->bl.id) )
@@ -13524,19 +13542,20 @@ void clif_parse_GMRecall2(int fd, struct map_session_data* sd) {
/// /item cap_n - capture n monster as pet.(not yet implemented)
/// /item agitinvest - reset current global agit investments.(not yet implemented)
/// 013f <item/mob name>.24B
-void clif_parse_GM_Monster_Item(int fd, struct map_session_data *sd)
-{
+/// 09ce <item/mob name>.100B [Ind/Yommy<3]
+void clif_parse_GM_Monster_Item(int fd, struct map_session_data *sd) {
+ struct packet_gm_monster_item *p = P2PTR(fd);
int i, count;
char *item_monster_name;
struct item_data *item_array[10];
struct mob_db *mob_array[10];
- char command[NAME_LENGTH+10];
+ char command[256];
- item_monster_name = (char*)RFIFOP(fd,2);
- item_monster_name[NAME_LENGTH-1] = '\0';
+ item_monster_name = p->str;
+ item_monster_name[(sizeof(struct packet_gm_monster_item)-2)-1] = '\0';
- if ( (count=itemdb->search_name_array(item_array, 10, item_monster_name, 1)) > 0 ){
- for(i = 0; i < count; i++){
+ if ( (count=itemdb->search_name_array(item_array, 10, item_monster_name, 1)) > 0 ) {
+ for(i = 0; i < count; i++) {
if( !item_array[i] )
continue;
// It only accepts aegis name
@@ -13546,7 +13565,7 @@ void clif_parse_GM_Monster_Item(int fd, struct map_session_data *sd)
break;
}
- if( i < count ){
+ if( i < count ) {
if( item_array[i]->type == IT_WEAPON || item_array[i]->type == IT_ARMOR ) // nonstackable
snprintf(command, sizeof(command)-1, "%citem2 %d 1 0 0 0 0 0 0 0", atcommand->at_symbol, item_array[i]->nameid);
else
@@ -13562,8 +13581,8 @@ void clif_parse_GM_Monster_Item(int fd, struct map_session_data *sd)
return;
}
- if( (count=mob->db_searchname_array(mob_array, 10, item_monster_name, 1)) > 0){
- for(i = 0; i < count; i++){
+ if( (count=mob->db_searchname_array(mob_array, 10, item_monster_name, 1)) > 0) {
+ for(i = 0; i < count; i++) {
if( !mob_array[i] )
continue;
// It only accepts sprite name
@@ -15402,9 +15421,11 @@ void clif_parse_Auction_buysell(int fd, struct map_session_data* sd)
/// List of items offered in a cash shop (ZC_PC_CASH_POINT_ITEMLIST).
/// 0287 <packet len>.W <cash point>.L { <sell price>.L <discount price>.L <item type>.B <name id>.W }*
/// 0287 <packet len>.W <cash point>.L <kafra point>.L { <sell price>.L <discount price>.L <item type>.B <name id>.W }* (PACKETVER >= 20070711)
-void clif_cashshop_show(struct map_session_data *sd, struct npc_data *nd)
-{
- int fd,i;
+void clif_cashshop_show(struct map_session_data *sd, struct npc_data *nd) {
+ struct npc_item_list *shop = NULL;
+ unsigned short shop_size = 0;
+ int fd,i, c = 0;
+ int currency[2] = { 0,0 };
#if PACKETVER < 20070711
const int offset = 8;
#else
@@ -15414,23 +15435,43 @@ void clif_cashshop_show(struct map_session_data *sd, struct npc_data *nd)
nullpo_retv(sd);
nullpo_retv(nd);
+ if( nd->subtype == SCRIPT ) {
+ shop = nd->u.scr.shop->item;
+ shop_size = nd->u.scr.shop->items;
+
+ npc->trader_count_funds(nd, sd);
+
+ currency[0] = npc->trader_funds[0];
+ currency[1] = npc->trader_funds[1];
+ } else {
+ shop = nd->u.shop.shop_item;
+ shop_size = nd->u.shop.count;
+
+ currency[0] = sd->cashPoints;
+ currency[1] = sd->kafraPoints;
+ }
+
fd = sd->fd;
sd->npc_shopid = nd->bl.id;
- WFIFOHEAD(fd,offset+nd->u.shop.count*11);
+ WFIFOHEAD(fd,offset+shop_size*11);
WFIFOW(fd,0) = 0x287;
- WFIFOW(fd,2) = offset+nd->u.shop.count*11;
- WFIFOL(fd,4) = sd->cashPoints; // Cash Points
+ /* 0x2 = length, set after parsing */
+ WFIFOL(fd,4) = currency[0]; // Cash Points
#if PACKETVER >= 20070711
- WFIFOL(fd,8) = sd->kafraPoints; // Kafra Points
+ WFIFOL(fd,8) = currency[1]; // Kafra Points
#endif
- for( i = 0; i < nd->u.shop.count; i++ ) {
- struct item_data* id = itemdb->search(nd->u.shop.shop_item[i].nameid);
- WFIFOL(fd,offset+0+i*11) = nd->u.shop.shop_item[i].value;
- WFIFOL(fd,offset+4+i*11) = nd->u.shop.shop_item[i].value; // Discount Price
- WFIFOB(fd,offset+8+i*11) = itemtype(id->type);
- WFIFOW(fd,offset+9+i*11) = ( id->view_id > 0 ) ? id->view_id : id->nameid;
+ for( i = 0; i < shop_size; i++ ) {
+ if( shop[i].nameid ) {
+ struct item_data* id = itemdb->search(shop[i].nameid);
+ WFIFOL(fd,offset+0+i*11) = shop[i].value;
+ WFIFOL(fd,offset+4+i*11) = shop[i].value; // Discount Price
+ WFIFOB(fd,offset+8+i*11) = itemtype(id->type);
+ WFIFOW(fd,offset+9+i*11) = ( id->view_id > 0 ) ? id->view_id : id->nameid;
+ c++;
+ }
}
+ WFIFOW(fd,2) = offset+c*11;
WFIFOSET(fd,WFIFOW(fd,2));
}
@@ -15449,15 +15490,26 @@ void clif_cashshop_show(struct map_session_data *sd, struct npc_data *nd)
/// 7 = You can purchase up to 10 items.
/// 8 = Some items could not be purchased.
void clif_cashshop_ack(struct map_session_data* sd, int error) {
- int fd = sd->fd;
+ struct npc_data *nd;
+ int fd = sd->fd;
+ int currency[2] = { 0,0 };
+
+ if( (nd = map->id2nd(sd->npc_shopid)) && nd->subtype == SCRIPT ) {
+ npc->trader_count_funds(nd,sd);
+ currency[0] = npc->trader_funds[0];
+ currency[1] = npc->trader_funds[1];
+ } else {
+ currency[0] = sd->cashPoints;
+ currency[1] = sd->kafraPoints;
+ }
WFIFOHEAD(fd, packet_len(0x289));
WFIFOW(fd,0) = 0x289;
- WFIFOL(fd,2) = sd->cashPoints;
+ WFIFOL(fd,2) = currency[0];
#if PACKETVER < 20070711
WFIFOW(fd,6) = TOW(error);
#else
- WFIFOL(fd,6) = sd->kafraPoints;
+ WFIFOL(fd,6) = currency[1];
WFIFOW(fd,10) = TOW(error);
#endif
WFIFOSET(fd, packet_len(0x289));
@@ -18048,7 +18100,77 @@ int clif_delay_damage(int64 tick, struct block_list *src, struct block_list *dst
return clif->calc_walkdelay(dst,ddelay,type,damage,div);
}
+/* Thanks to Yommy */
+void clif_parse_NPCShopClosed(int fd, struct map_session_data *sd) {
+ /* TODO track the state <3~ */
+ sd->npc_shopid = 0;
+}
+/* NPC Market (by Ind after an extensive debugging of the packet, only possible thanks to Yommy <3) */
+void clif_npc_market_open(struct map_session_data *sd, struct npc_data *nd) {
+ struct npc_item_list *shop = nd->u.scr.shop->item;
+ unsigned short shop_size = nd->u.scr.shop->items, i, c;
+ struct item_data *id = NULL;
+
+ npcmarket_open.PacketType = npcmarketopenType;
+
+ for(i = 0, c = 0; i < shop_size; i++) {
+ if( shop[i].nameid && (id = itemdb->exists(shop[i].nameid)) ) {
+ npcmarket_open.list[c].nameid = shop[i].nameid;
+ npcmarket_open.list[c].price = shop[i].value;
+ npcmarket_open.list[c].qty = shop[i].qty;
+ npcmarket_open.list[c].type = itemtype(id->type);
+ npcmarket_open.list[c].view = ( id->view_id > 0 ) ? id->view_id : id->nameid;
+ c++;
+ }
+ }
+
+ npcmarket_open.PacketLength = 4 + ( sizeof(npcmarket_open.list[0]) * c );
+
+ clif->send(&npcmarket_open,npcmarket_open.PacketLength,&sd->bl,SELF);
+}
+void clif_parse_NPCMarketClosed(int fd, struct map_session_data *sd) {
+ /* TODO track the state <3~ */
+ sd->npc_shopid = 0;
+}
+void clif_npc_market_purchase_ack(struct map_session_data *sd, struct packet_npc_market_purchase *req, unsigned char response) {
+ unsigned short c = 0;
+
+ npcmarket_result.PacketType = npcmarketresultackType;
+ npcmarket_result.result = response == 0 ? 1 : 0;/* find other values */
+
+ if( npcmarket_result.result ) {
+ unsigned short i, list_size = (req->PacketLength - 4) / sizeof(req->list[0]), j;
+ struct npc_data* nd;
+ struct npc_item_list *shop = NULL;
+ unsigned short shop_size = 0;
+
+ nd = map->id2nd(sd->npc_shopid);
+ shop = nd->u.scr.shop->item;
+ shop_size = nd->u.scr.shop->items;
+
+ for(i = 0; i < list_size; i++) {
+
+ npcmarket_result.list[i].ITID = req->list[i].ITID;
+ npcmarket_result.list[i].qty = req->list[i].qty;
+
+ ARR_FIND( 0, shop_size, j, req->list[i].ITID == shop[j].nameid );
+
+ npcmarket_result.list[i].price = (j != shop_size) ? shop[j].value : 0;
+
+ c++;
+ }
+ }
+
+ npcmarket_result.PacketLength = 5 + ( sizeof(npcmarket_result.list[0]) * c );;
+
+ clif->send(&npcmarket_result,npcmarket_result.PacketLength,&sd->bl,SELF);
+}
+void clif_parse_NPCMarketPurchase(int fd, struct map_session_data *sd) {
+ struct packet_npc_market_purchase *p = P2PTR(fd);
+
+ clif->npc_market_purchase_ack(sd,p,npc->market_buylist(sd,(p->PacketLength - 4) / sizeof(p->list[0]),p));
+}
/* */
unsigned short clif_decrypt_cmd( int cmd, struct map_session_data *sd ) {
if( sd ) {
@@ -18863,6 +18985,9 @@ void clif_defaults(void) {
/* */
clif->delay_damage = clif_delay_damage;
clif->delay_damage_sub = clif_delay_damage_sub;
+ /* NPC Market */
+ clif->npc_market_open = clif_npc_market_open;
+ clif->npc_market_purchase_ack = clif_npc_market_purchase_ack;
/*------------------------
*- Parse Incoming Packet
*------------------------*/
@@ -19092,4 +19217,9 @@ void clif_defaults(void) {
clif->pBankCheck = clif_parse_BankCheck;
clif->pBankOpen = clif_parse_BankOpen;
clif->pBankClose = clif_parse_BankClose;
+ /* */
+ clif->pNPCShopClosed = clif_parse_NPCShopClosed;
+ /* NPC Market */
+ clif->pNPCMarketClosed = clif_parse_NPCMarketClosed;
+ clif->pNPCMarketPurchase = clif_parse_NPCMarketPurchase;
}
diff --git a/src/map/clif.h b/src/map/clif.h
index c4088893a..6405bbd3e 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -1034,6 +1034,9 @@ struct clif_interface {
/* */
int (*delay_damage) (int64 tick, struct block_list *src, struct block_list *dst, int sdelay, int ddelay, int64 in_damage, short div, unsigned char type);
int (*delay_damage_sub) (int tid, int64 tick, int id, intptr_t data);
+ /* NPC Market */
+ void (*npc_market_open) (struct map_session_data *sd, struct npc_data *nd);
+ void (*npc_market_purchase_ack) (struct map_session_data *sd, struct packet_npc_market_purchase *req, unsigned char response);
/*------------------------
*- Parse Incoming Packet
*------------------------*/
@@ -1261,6 +1264,11 @@ struct clif_interface {
void (*pBankCheck) (int fd, struct map_session_data *sd);
void (*pBankOpen) (int fd, struct map_session_data *sd);
void (*pBankClose) (int fd, struct map_session_data *sd);
+ /* */
+ void (*pNPCShopClosed) (int fd, struct map_session_data *sd);
+ /* NPC Market (by Ind after an extensive debugging of the packet, only possible thanks to Yommy <3) */
+ void (*pNPCMarketClosed) (int fd, struct map_session_data *sd);
+ void (*pNPCMarketPurchase) (int fd, struct map_session_data *sd);
};
struct clif_interface *clif;
diff --git a/src/map/map.c b/src/map/map.c
index 7ff4ebcc5..aef34ef00 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -5630,7 +5630,8 @@ int do_init(int argc, char *argv[])
}
npc->event_do_oninit(); // Init npcs (OnInit)
-
+ npc->market_fromsql(); /* after OnInit */
+
if (battle_config.pk_mode)
ShowNotice("Server is running on '"CL_WHITE"PK Mode"CL_RESET"'.\n");
diff --git a/src/map/npc.c b/src/map/npc.c
index 84a2446ad..44df2fe7a 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -56,6 +56,9 @@ struct npc_path_data *npc_last_npd;
static struct view_data npc_viewdb[MAX_NPC_CLASS];
static struct view_data npc_viewdb2[MAX_NPC_CLASS2_END-MAX_NPC_CLASS2_START];
+/* for speedup */
+unsigned int npc_market_qty[MAX_INVENTORY];
+
static struct script_event_s
{ //Holds pointers to the commonly executed scripts for speedup. [Skotlex]
struct event_data *event[UCHAR_MAX];
@@ -1150,8 +1153,10 @@ int npc_click(struct map_session_data* sd, struct npc_data* nd)
}
if(!nd) return 1;
+
if ((nd = npc->checknear(sd,&nd->bl)) == NULL)
return 1;
+
//Hidden/Disabled npc.
if (nd->class_ < 0 || nd->option&(OPTION_INVISIBLE|OPTION_HIDE))
return 1;
@@ -1164,7 +1169,11 @@ int npc_click(struct map_session_data* sd, struct npc_data* nd)
clif->cashshop_show(sd,nd);
break;
case SCRIPT:
- script->run(nd->u.scr.script,0,sd->bl.id,nd->bl.id);
+ if( nd->u.scr.shop && nd->u.scr.shop->items && nd->u.scr.trader ) {
+ if( !npc->trader_open(sd,nd) )
+ return 1;
+ } else
+ script->run(nd->u.scr.script,0,sd->bl.id,nd->bl.id);
break;
case TOMB:
npc->run_tomb(sd,nd);
@@ -1231,16 +1240,22 @@ int npc_buysellsel(struct map_session_data* sd, int id, int type) {
if ((nd = npc->checknear(sd,map->id2bl(id))) == NULL)
return 1;
- if (nd->subtype!=SHOP) {
- ShowError("no such shop npc : %d\n",id);
+ if ( nd->subtype != SHOP && !(nd->subtype == SCRIPT && nd->u.scr.shop && nd->u.scr.shop->items) ) {
+
+ if( nd->subtype == SCRIPT )
+ ShowError("npc_buysellsel: trader '%s' has no shop list!\n",nd->exname);
+ else
+ ShowError("npc_buysellsel: no such shop npc %d (%s)\n",id,nd->exname);
+
if (sd->npc_id == id)
- sd->npc_id=0;
+ sd->npc_id = 0;
return 1;
}
- if (nd->option & OPTION_INVISIBLE) // can't buy if npc is not visible (hack?)
+
+ if (nd->option & OPTION_INVISIBLE) // can't buy if npc is not visible (hack?)
return 1;
- if( nd->class_ < 0 && !sd->state.callshop )
- {// not called through a script and is not a visible NPC so an invalid call
+
+ if( nd->class_ < 0 && !sd->state.callshop ) {// not called through a script and is not a visible NPC so an invalid call
return 1;
}
@@ -1253,6 +1268,7 @@ int npc_buysellsel(struct map_session_data* sd, int id, int type) {
} else {
clif->selllist(sd);
}
+
return 0;
}
@@ -1261,14 +1277,33 @@ int npc_buysellsel(struct map_session_data* sd, int id, int type) {
*------------------------------------------*/
int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, unsigned short* item_list) {
int i, j, nameid, amount, new_, w, vt;
- struct npc_data *nd = (struct npc_data *)map->id2bl(sd->npc_shopid);
-
- if( !nd || nd->subtype != CASHSHOP )
- return 1;
+ struct npc_data *nd = NULL;
+ struct npc_item_list *shop = NULL;
+ unsigned short shop_size = 0;
if( sd->state.trading )
return 4;
+ if( count <= 0 )
+ return 5;
+
+ if( points < 0 )
+ return 6;
+
+ if( !(nd = (struct npc_data *)map->id2bl(sd->npc_shopid)) )
+ return 1;
+
+ if( nd->subtype != CASHSHOP ) {
+ if( nd->subtype == SCRIPT && nd->u.scr.shop && nd->u.scr.shop->type != NST_ZENY && nd->u.scr.shop->type != NST_MARKET ) {
+ shop = nd->u.scr.shop->item;
+ shop_size = nd->u.scr.shop->items;
+ } else
+ return 1;
+ } else {
+ shop = nd->u.shop.shop_item;
+ shop_size = nd->u.shop.count;
+ }
+
new_ = 0;
w = 0;
vt = 0; // Global Value
@@ -1281,12 +1316,13 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, uns
if( !itemdb->exists(nameid) || amount <= 0 )
return 5;
- ARR_FIND(0,nd->u.shop.count,j,nd->u.shop.shop_item[j].nameid == nameid);
- if( j == nd->u.shop.count || nd->u.shop.shop_item[j].value <= 0 )
+ ARR_FIND(0,shop_size,j,shop[j].nameid == nameid);
+ if( j == shop_size || shop[j].value <= 0 )
return 5;
if( !itemdb->isstackable(nameid) && amount > 1 ) {
- ShowWarning("Player %s (%d:%d) sent a hexed packet trying to buy %d of nonstackable item %d!\n", sd->status.name, sd->status.account_id, sd->status.char_id, amount, nameid);
+ ShowWarning("Player %s (%d:%d) sent a hexed packet trying to buy %d of nonstackable item %d!\n",
+ sd->status.name, sd->status.account_id, sd->status.char_id, amount, nameid);
amount = item_list[i*2+0] = 1;
}
@@ -1298,21 +1334,27 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, uns
return 3;
}
- vt += nd->u.shop.shop_item[j].value * amount;
+ vt += shop[j].value * amount;
w += itemdb_weight(nameid) * amount;
}
if( w + sd->weight > sd->max_weight )
return 3;
+
if( pc->inventoryblank(sd) < new_ )
return 3;
+
if( points > vt ) points = vt;
// Payment Process ----------------------------------------------------
- if( sd->kafraPoints < points || sd->cashPoints < (vt - points) )
- return 6;
- pc->paycash(sd,vt,points);
-
+ if( nd->subtype == SCRIPT && nd->u.scr.shop->type == NST_CUSTOM ) {
+ if( !npc->trader_pay(nd,sd,vt,points) )
+ return 6;
+ } else {
+ if( sd->kafraPoints < points || sd->cashPoints < (vt - points) )
+ return 6;
+ pc->paycash(sd,vt,points);
+ }
// Delivery Process ----------------------------------------------------
for( i = 0; i < count; i++ ) {
struct item item_tmp;
@@ -1356,45 +1398,257 @@ int npc_buylist_sub(struct map_session_data* sd, int n, unsigned short* item_lis
return 0;
}
+/**
+ * Loads persistent NPC Market Data from SQL
+ **/
+void npc_market_fromsql(void) {
+ SqlStmt* stmt = SQL->StmtMalloc(map->mysql_handle);
+ char name[NAME_LENGTH+1];
+ int itemid;
+ int amount;
+
+ /* TODO inter-server.conf npc_market_data */
+ if ( SQL_ERROR == SQL->StmtPrepare(stmt, "SELECT `name`, `itemid`, `amount` FROM `npc_market_data`")
+ || SQL_ERROR == SQL->StmtExecute(stmt)
+ ) {
+ SqlStmt_ShowDebug(stmt);
+ SQL->StmtFree(stmt);
+ return;
+ }
+
+ SQL->StmtBindColumn(stmt, 0, SQLDT_STRING, &name[0], sizeof(name), NULL, NULL);
+ SQL->StmtBindColumn(stmt, 1, SQLDT_INT, &itemid, 0, NULL, NULL);
+ SQL->StmtBindColumn(stmt, 2, SQLDT_INT, &amount, 0, NULL, NULL);
+
+ while ( SQL_SUCCESS == SQL->StmtNextRow(stmt) ) {
+ struct npc_data *nd = NULL;
+ unsigned short i;
+
+ if( !(nd = npc->name2id(name)) ) {
+ ShowError("npc_market_fromsql: NPC '%s' not found! skipping...\n",name);
+ continue;
+ } else if ( nd->subtype != SCRIPT || !nd->u.scr.shop || !nd->u.scr.shop->items || nd->u.scr.shop->type != NST_MARKET ) {
+ ShowError("npc_market_fromsql: NPC '%s' is not proper for market, skipping...\n",name);
+ continue;
+ }
+
+ for(i = 0; i < nd->u.scr.shop->items; i++) {
+ if( nd->u.scr.shop->item[i].nameid == itemid ) {
+ nd->u.scr.shop->item[i].qty = amount;
+ break;
+ }
+ }
+
+ if( i == nd->u.scr.shop->items ) {
+ ShowError("npc_market_fromsql: NPC '%s' does not sell item %d (qty %d), deleting...\n",name,itemid,amount);
+ /* TODO inter-server.conf npc_market_data */
+ if( SQL_ERROR == SQL->Query(map->mysql_handle, "DELETE FROM `npc_market_data` WHERE `name`='%s' AND `itemid`='%d' LIMIT 1", name,itemid) )
+ Sql_ShowDebug(map->mysql_handle);
+ continue;
+ }
+
+ }
+
+ SQL->StmtFree(stmt);
+}
+/**
+ * Saves persistent NPC Market Data into SQL
+ **/
+void npc_market_tosql(struct npc_data *nd, unsigned short index) {
+ /* TODO inter-server.conf npc_market_data */
+ if( SQL_ERROR == SQL->Query(map->mysql_handle, "REPLACE INTO `npc_market_data` VALUES ('%s','%d','%d')", nd->exname, nd->u.scr.shop->item[index].nameid, nd->u.scr.shop->item[index].qty) )
+ Sql_ShowDebug(map->mysql_handle);
+}
+/**
+ * Removes persistent NPC Market Data from SQL
+ **/
+void npc_market_delfromsql(struct npc_data *nd, unsigned short index) {
+ /* TODO inter-server.conf npc_market_data */
+ if( index == USHRT_MAX ) {
+ if( SQL_ERROR == SQL->Query(map->mysql_handle, "DELETE FROM `npc_market_data` WHERE `name`='%s'", nd->exname) )
+ Sql_ShowDebug(map->mysql_handle);
+ } else {
+ if( SQL_ERROR == SQL->Query(map->mysql_handle, "DELETE FROM `npc_market_data` WHERE `name`='%s' AND `itemid`='%d' LIMIT 1", nd->exname, nd->u.scr.shop->item[index].nameid) )
+ Sql_ShowDebug(map->mysql_handle);
+ }
+}
+/**
+ * Judges whether to allow and spawn a trader's window.
+ **/
+bool npc_trader_open(struct map_session_data *sd, struct npc_data *nd) {
+
+ if( !nd->u.scr.shop || !nd->u.scr.shop->items )
+ return false;
+
+ switch( nd->u.scr.shop->type ) {
+ case NST_ZENY:
+ sd->state.callshop = 1;
+ npc->buysellsel(sd,nd->bl.id,0);
+ break;
+ case NST_MARKET: {
+ unsigned short i;
+
+ for(i = 0; i < nd->u.scr.shop->items; i++) {
+ if( nd->u.scr.shop->item[i].qty )
+ break;
+ }
+
+ /* nothing to display, no items available */
+ if( i == nd->u.scr.shop->items ) {
+ clif->colormes(sd->fd,COLOR_RED,"Shop is out of stock! Come again later!");/* TODO messages.conf-it */
+ return false;
+ }
+ clif->npc_market_open(sd,nd);
+ }
+ break;
+ default:
+ clif->cashshop_show(sd,nd);
+ break;
+ }
+
+ sd->npc_shopid = nd->bl.id;
+
+ return true;
+}
+/**
+ * Creates (npc_data)->u.scr.shop and updates all duplicates across the server to match the created pointer
+ *
+ * @param master id of the original npc
+ **/
+void npc_trader_update(int master) {
+ DBIterator* iter;
+ struct block_list* bl;
+ struct npc_data *master_nd = map->id2nd(master);
+
+ CREATE(master_nd->u.scr.shop,struct npc_shop_data,1);
+
+ iter = db_iterator(map->id_db);
+
+ for( bl = (struct block_list*)dbi_first(iter); dbi_exists(iter); bl = (struct block_list*)dbi_next(iter) ) {
+ if( bl->type == BL_NPC ) {
+ struct npc_data* nd = (struct npc_data*)bl;
+
+ if( nd->src_id == master ) {
+ nd->u.scr.shop = master_nd->u.scr.shop;
+ }
+ }
+ }
+
+ dbi_destroy(iter);
+}
+/**
+ * Tries to issue a CountFunds event to the shop.
+ *
+ * @param nd shop
+ * @param sd player
+ **/
+void npc_trader_count_funds(struct npc_data *nd, struct map_session_data *sd) {
+ char evname[EVENT_NAME_LENGTH];
+ struct event_data *ev = NULL;
+
+ npc->trader_funds[0] = npc->trader_funds[1] = 0;/* clear */
+
+ switch( nd->u.scr.shop->type ) {
+ case NST_CASH:
+ npc->trader_funds[0] = sd->cashPoints;
+ npc->trader_funds[1] = sd->kafraPoints;
+ return;
+ case NST_CUSTOM:
+ break;
+ default:
+ ShowError("npc_trader_count_funds: unsupported shop type %d\n",nd->u.scr.shop->type);
+ return;
+ }
+
+ snprintf(evname, EVENT_NAME_LENGTH, "%s::OnCountFunds",nd->exname);
+
+ if ( (ev = strdb_get(npc->ev_db, evname)) )
+ script->run(ev->nd->u.scr.script, ev->pos, sd->bl.id, ev->nd->bl.id);
+ else
+ ShowError("npc_trader_count_funds: '%s' event '%s' not found, operation failed\n",nd->exname,evname);
+
+ /* the callee will rely on npc->trader_funds, upon success script->run updates them */
+}
+/**
+ * Tries to issue a payment to the NPC Event capable of handling it
+ *
+ * @param nd shop
+ * @param sd player
+ * @param price total cost
+ * @param points the amount input in the shop by the user to use from the secondary currency (if any is being employed)
+ *
+ * @return bool whether it was successful (if the script does not respond it will fail)
+ **/
+bool npc_trader_pay(struct npc_data *nd, struct map_session_data *sd, int price, int points) {
+ char evname[EVENT_NAME_LENGTH];
+ struct event_data *ev = NULL;
+
+ npc->trader_ok = false;/* clear */
+
+ snprintf(evname, EVENT_NAME_LENGTH, "%s::OnPayFunds",nd->exname);
+
+ if ( (ev = strdb_get(npc->ev_db, evname)) ) {
+ pc->setreg(sd,script->add_str("@price"),price);
+ pc->setreg(sd,script->add_str("@points"),points);
+
+ script->run(ev->nd->u.scr.script, ev->pos, sd->bl.id, ev->nd->bl.id);
+ } else
+ ShowError("npc_trader_pay: '%s' event '%s' not found, operation failed\n",nd->exname,evname);
+
+ return npc->trader_ok;/* run script will deal with it */
+}
/*==========================================
* Cash Shop Buy
*------------------------------------------*/
int npc_cashshop_buy(struct map_session_data *sd, int nameid, int amount, int points) {
- struct npc_data *nd = (struct npc_data *)map->id2bl(sd->npc_shopid);
+ struct npc_data *nd = NULL;
struct item_data *item;
+ struct npc_item_list *shop = NULL;
int i, price, w;
-
+ unsigned short shop_size = 0;
+
if( amount <= 0 )
return 5;
if( points < 0 )
return 6;
- if( !nd || nd->subtype != CASHSHOP )
- return 1;
-
if( sd->state.trading )
return 4;
+
+ if( !(nd = (struct npc_data *)map->id2bl(sd->npc_shopid)) )
+ return 1;
if( (item = itemdb->exists(nameid)) == NULL )
return 5; // Invalid Item
- ARR_FIND(0, nd->u.shop.count, i, nd->u.shop.shop_item[i].nameid == nameid);
- if( i == nd->u.shop.count )
+ if( nd->subtype != CASHSHOP ) {
+ if( nd->subtype == SCRIPT && nd->u.scr.shop && nd->u.scr.shop->type != NST_ZENY && nd->u.scr.shop->type != NST_MARKET ) {
+ shop = nd->u.scr.shop->item;
+ shop_size = nd->u.scr.shop->items;
+ } else
+ return 1;
+ } else {
+ shop = nd->u.shop.shop_item;
+ shop_size = nd->u.shop.count;
+ }
+
+ ARR_FIND(0, shop_size, i, shop[i].nameid == nameid);
+
+ if( i == shop_size )
return 5;
- if( nd->u.shop.shop_item[i].value <= 0 )
+
+ if( shop[i].value <= 0 )
return 5;
- if(!itemdb->isstackable(nameid) && amount > 1)
- {
+ if(!itemdb->isstackable(nameid) && amount > 1) {
ShowWarning("Player %s (%d:%d) sent a hexed packet trying to buy %d of nonstackable item %d!\n",
sd->status.name, sd->status.account_id, sd->status.char_id, amount, nameid);
amount = 1;
}
- switch( pc->checkadditem(sd, nameid, amount) )
- {
+ switch( pc->checkadditem(sd, nameid, amount) ) {
case ADDITEM_NEW:
if( pc->inventoryblank(sd) == 0 )
return 3;
@@ -1407,26 +1661,31 @@ int npc_cashshop_buy(struct map_session_data *sd, int nameid, int amount, int po
if( w + sd->weight > sd->max_weight )
return 3;
- if( (double)nd->u.shop.shop_item[i].value * amount > INT_MAX ) {
+ if( (double)shop[i].value * amount > INT_MAX ) {
ShowWarning("npc_cashshop_buy: Item '%s' (%d) price overflow attempt!\n", item->name, nameid);
ShowDebug("(NPC:'%s' (%s,%d,%d), player:'%s' (%d/%d), value:%d, amount:%d)\n",
nd->exname, map->list[nd->bl.m].name, nd->bl.x, nd->bl.y,
sd->status.name, sd->status.account_id, sd->status.char_id,
- nd->u.shop.shop_item[i].value, amount);
+ shop[i].value, amount);
return 5;
}
- price = nd->u.shop.shop_item[i].value * amount;
+ price = shop[i].value * amount;
+
if( points > price )
points = price;
- if( (sd->kafraPoints < points) || (sd->cashPoints < price - points) )
- return 6;
-
- pc->paycash(sd, price, points);
+ if( nd->subtype == SCRIPT && nd->u.scr.shop->type == NST_CUSTOM ) {
+ if( !npc->trader_pay(nd,sd,price,points) )
+ return 6;
+ } else {
+ if( (sd->kafraPoints < points) || (sd->cashPoints < price - points) )
+ return 6;
+
+ pc->paycash(sd, price, points);
+ }
- if( !pet->create_egg(sd, nameid) )
- {
+ if( !pet->create_egg(sd, nameid) ) {
struct item item_tmp;
memset(&item_tmp, 0, sizeof(struct item));
item_tmp.nameid = nameid;
@@ -1444,104 +1703,115 @@ int npc_cashshop_buy(struct map_session_data *sd, int nameid, int amount, int po
/// @return result code for clif->parse_NpcBuyListSend
int npc_buylist(struct map_session_data* sd, int n, unsigned short* item_list) {
struct npc_data* nd;
+ struct npc_item_list *shop = NULL;
double z;
int i,j,w,skill_t,new_, idx = skill->get_index(MC_DISCOUNT);
-
+ unsigned short shop_size = 0;
+
nullpo_retr(3, sd);
nullpo_retr(3, item_list);
-
+
nd = npc->checknear(sd,map->id2bl(sd->npc_shopid));
if( nd == NULL )
return 3;
- if( nd->subtype != SHOP )
- return 3;
-
+
+ if( nd->subtype != SHOP ) {
+ if( nd->subtype == SCRIPT && nd->u.scr.shop && nd->u.scr.shop->type == NST_ZENY ) {
+ shop = nd->u.scr.shop->item;
+ shop_size = nd->u.scr.shop->items;
+ } else
+ return 3;
+ } else {
+ shop = nd->u.shop.shop_item;
+ shop_size = nd->u.shop.count;
+ }
+
z = 0;
w = 0;
new_ = 0;
// process entries in buy list, one by one
for( i = 0; i < n; ++i ) {
int nameid, amount, value;
-
+
// find this entry in the shop's sell list
- ARR_FIND( 0, nd->u.shop.count, j,
- item_list[i*2+1] == nd->u.shop.shop_item[j].nameid || //Normal items
- item_list[i*2+1] == itemdb_viewid(nd->u.shop.shop_item[j].nameid) //item_avail replacement
- );
-
- if( j == nd->u.shop.count )
+ ARR_FIND( 0, shop_size, j,
+ item_list[i*2+1] == shop[j].nameid || //Normal items
+ item_list[i*2+1] == itemdb_viewid(shop[j].nameid) //item_avail replacement
+ );
+
+ if( j == shop_size )
return 3; // no such item in shop
-
+
amount = item_list[i*2+0];
- nameid = item_list[i*2+1] = nd->u.shop.shop_item[j].nameid; //item_avail replacement
- value = nd->u.shop.shop_item[j].value;
-
+ nameid = item_list[i*2+1] = shop[j].nameid; //item_avail replacement
+ value = shop[j].value;
+
if( !itemdb->exists(nameid) )
return 3; // item no longer in itemdb
-
+
if( !itemdb->isstackable(nameid) && amount > 1 ) {
//Exploit? You can't buy more than 1 of equipment types o.O
ShowWarning("Player %s (%d:%d) sent a hexed packet trying to buy %d of nonstackable item %d!\n",
- sd->status.name, sd->status.account_id, sd->status.char_id, amount, nameid);
+ sd->status.name, sd->status.account_id, sd->status.char_id, amount, nameid);
amount = item_list[i*2+0] = 1;
}
-
+
if( nd->master_nd ) {
// Script-controlled shops decide by themselves, what can be bought and for what price.
continue;
}
-
+
switch( pc->checkadditem(sd,nameid,amount) ) {
case ADDITEM_EXIST:
break;
-
+
case ADDITEM_NEW:
new_++;
break;
-
+
case ADDITEM_OVERAMOUNT:
return 2;
}
-
+
value = pc->modifybuyvalue(sd,value);
-
+
z += (double)value * amount;
w += itemdb_weight(nameid) * amount;
}
-
+
if( nd->master_nd != NULL ) //Script-based shops.
return npc->buylist_sub(sd,n,item_list,nd->master_nd);
-
+
if( z > (double)sd->status.zeny )
return 1; // Not enough Zeny
if( w + sd->weight > sd->max_weight )
return 2; // Too heavy
if( pc->inventoryblank(sd) < new_ )
return 3; // Not enough space to store items
-
+
pc->payzeny(sd,(int)z,LOG_TYPE_NPC, NULL);
-
+
for( i = 0; i < n; ++i ) {
int nameid = item_list[i*2+1];
int amount = item_list[i*2+0];
struct item item_tmp;
-
+
if (itemdb_type(nameid) == IT_PETEGG)
pet->create_egg(sd, nameid);
else {
memset(&item_tmp,0,sizeof(item_tmp));
item_tmp.nameid = nameid;
item_tmp.identify = 1;
-
+
pc->additem(sd,&item_tmp,amount,LOG_TYPE_NPC);
}
}
-
+
// custom merchant shop exp bonus
if( battle_config.shop_exp > 0 && z > 0 && (skill_t = pc->checkskill2(sd,idx)) > 0 ) {
if( sd->status.skill[idx].flag >= SKILL_FLAG_REPLACED_LV_0 )
skill_t = sd->status.skill[idx].flag - SKILL_FLAG_REPLACED_LV_0;
-
+
if( skill_t > 0 ) {
z = z * (double)skill_t * (double)battle_config.shop_exp/10000.;
if( z < 1 )
@@ -1549,10 +1819,120 @@ int npc_buylist(struct map_session_data* sd, int n, unsigned short* item_list) {
pc->gainexp(sd,NULL,0,(int)z, false);
}
}
-
+
return 0;
}
+/**
+ * parses incoming npc market purchase list
+ **/
+int npc_market_buylist(struct map_session_data* sd, unsigned short list_size, struct packet_npc_market_purchase *p) {
+ struct npc_data* nd;
+ struct npc_item_list *shop = NULL;
+ double z;
+ int i,j,w,new_;
+ unsigned short shop_size = 0;
+
+ nullpo_retr(1, sd);
+ nullpo_retr(1, p);
+
+ nd = npc->checknear(sd,map->id2bl(sd->npc_shopid));
+
+ if( nd == NULL || nd->subtype != SCRIPT || !list_size || !nd->u.scr.shop || nd->u.scr.shop->type != NST_MARKET )
+ return 1;
+
+ shop = nd->u.scr.shop->item;
+ shop_size = nd->u.scr.shop->items;
+
+ z = 0;
+ w = 0;
+ new_ = 0;
+
+ // process entries in buy list, one by one
+ for( i = 0; i < list_size; ++i ) {
+ int nameid, amount, value;
+
+ // find this entry in the shop's sell list
+ ARR_FIND( 0, shop_size, j,
+ p->list[i].ITID == shop[j].nameid || //Normal items
+ p->list[i].ITID == itemdb_viewid(shop[j].nameid) //item_avail replacement
+ );
+
+ if( j == shop_size ) /* TODO find official response for this */
+ return 1; // no such item in shop
+
+ if( p->list[i].qty > shop[j].qty )
+ return 1;
+
+ amount = p->list[i].qty;
+ nameid = p->list[i].ITID = shop[j].nameid; //item_avail replacement
+ value = shop[j].value;
+ npc_market_qty[i] = j;
+
+ if( !itemdb->exists(nameid) ) /* TODO find official response for this */
+ return 1; // item no longer in itemdb
+
+ if( !itemdb->isstackable(nameid) && amount > 1 ) {
+ //Exploit? You can't buy more than 1 of equipment types o.O
+ ShowWarning("Player %s (%d:%d) sent a hexed packet trying to buy %d of nonstackable item %d!\n",
+ sd->status.name, sd->status.account_id, sd->status.char_id, amount, nameid);
+ amount = p->list[i].qty = 1;
+ }
+
+ switch( pc->checkadditem(sd,nameid,amount) ) {
+ case ADDITEM_EXIST:
+ break;
+
+ case ADDITEM_NEW:
+ new_++;
+ break;
+
+ case ADDITEM_OVERAMOUNT: /* TODO find official response for this */
+ return 1;
+ }
+
+ z += (double)value * amount;
+ w += itemdb_weight(nameid) * amount;
+ }
+
+ if( z > (double)sd->status.zeny ) /* TODO find official response for this */
+ return 1; // Not enough Zeny
+
+ if( w + sd->weight > sd->max_weight ) /* TODO find official response for this */
+ return 1; // Too heavy
+
+ if( pc->inventoryblank(sd) < new_ ) /* TODO find official response for this */
+ return 1; // Not enough space to store items
+
+ pc->payzeny(sd,(int)z,LOG_TYPE_NPC, NULL);
+
+ for( i = 0; i < list_size; ++i ) {
+ int nameid = p->list[i].ITID;
+ int amount = p->list[i].qty;
+ struct item item_tmp;
+
+ j = npc_market_qty[i];
+
+ if( p->list[i].qty > shop[j].qty ) /* wohoo someone tampered with the packet. */
+ return 1;
+
+ shop[j].qty -= amount;
+
+ npc->market_tosql(nd,j);
+
+ if (itemdb_type(nameid) == IT_PETEGG)
+ pet->create_egg(sd, nameid);
+ else {
+ memset(&item_tmp,0,sizeof(item_tmp));
+ item_tmp.nameid = nameid;
+ item_tmp.identify = 1;
+
+ pc->additem(sd,&item_tmp,amount,LOG_TYPE_NPC);
+ }
+ }
+
+ return 0;
+}
/// npc_selllist for script-controlled shops
int npc_selllist_sub(struct map_session_data* sd, int n, unsigned short* item_list, struct npc_data* nd)
@@ -1844,6 +2224,11 @@ int npc_unload(struct npc_data* nd, bool single) {
nd->u.scr.label_list = NULL;
nd->u.scr.label_list_num = 0;
}
+ if(nd->u.scr.shop) {
+ if(nd->u.scr.shop->item)
+ aFree(nd->u.scr.shop->item);
+ aFree(nd->u.scr.shop);
+ }
}
if( nd->u.scr.guild_id )
guild->flag_remove(nd);
@@ -2395,7 +2780,7 @@ const char* npc_skip_script(const char* start, const char* buffer, const char* f
/// -%TAB%script%TAB%<NPC Name>%TAB%-1,{<code>}
/// <map name>,<x>,<y>,<facing>%TAB%script%TAB%<NPC Name>%TAB%<sprite id>,{<code>}
/// <map name>,<x>,<y>,<facing>%TAB%script%TAB%<NPC Name>%TAB%<sprite id>,<triggerX>,<triggerY>,{<code>}
-const char* npc_parse_script(char* w1, char* w2, char* w3, char* w4, const char* start, const char* buffer, const char* filepath, bool runOnInit) {
+const char* npc_parse_script(char* w1, char* w2, char* w3, char* w4, const char* start, const char* buffer, const char* filepath, int options) {
int x, y, dir = 0, m, xs = 0, ys = 0; // [Valaris] thanks to fov
char mapname[32];
struct script_code *scriptroot;
@@ -2466,7 +2851,10 @@ const char* npc_parse_script(char* w1, char* w2, char* w3, char* w4, const char*
nd->u.scr.script = scriptroot;
nd->u.scr.label_list = label_list;
nd->u.scr.label_list_num = label_list_num;
-
+ if( options&NPO_TRADER )
+ nd->u.scr.trader = true;
+ nd->u.scr.shop = NULL;
+
++npc_script;
nd->bl.type = BL_NPC;
nd->subtype = SCRIPT;
@@ -2500,7 +2888,7 @@ const char* npc_parse_script(char* w1, char* w2, char* w3, char* w4, const char*
nd->u.scr.timerid = INVALID_TIMER;
- if( runOnInit ) {
+ if( options&NPO_ONINIT ) {
char evname[EVENT_NAME_LENGTH];
struct event_data *ev;
@@ -2604,6 +2992,8 @@ const char* npc_parse_duplicate(char* w1, char* w2, char* w3, char* w4, const ch
nd->u.scr.script = dnd->u.scr.script;
nd->u.scr.label_list = dnd->u.scr.label_list;
nd->u.scr.label_list_num = dnd->u.scr.label_list_num;
+ nd->u.scr.shop = dnd->u.scr.shop;
+ nd->u.scr.trader = dnd->u.scr.trader;
break;
case SHOP:
@@ -3656,9 +4046,12 @@ int npc_parsesrcfile(const char* filepath, bool runOnInit) {
#ifdef ENABLE_CASE_CHECK
if( strcasecmp(w1, "function") == 0 ) DeprecationWarning("npc_parsesrcfile", w1, "function", filepath, strline(buffer, p-buffer)); // TODO
#endif // ENABLE_CASE_CHECK
- p = npc->parse_script(w1,w2,w3,w4, p, buffer, filepath,runOnInit);
+ p = npc->parse_script(w1,w2,w3,w4, p, buffer, filepath,runOnInit?NPO_ONINIT:NPO_NONE);
}
}
+ else if( strcmp(w2,"trader") == 0 && count > 3 ) {
+ p = npc->parse_script(w1,w2,w3,w4, p, buffer, filepath,(runOnInit?NPO_ONINIT:NPO_NONE)|NPO_TRADER);
+ }
else if( (i=0, sscanf(w2,"duplicate%n",&i), (i > 0 && w2[i] == '(')) && count > 3 )
{
p = npc->parse_duplicate(w1,w2,w3,w4, p, buffer, filepath);
@@ -3678,6 +4071,7 @@ int npc_parsesrcfile(const char* filepath, bool runOnInit) {
else if( strcasecmp(w2,"shop") == 0 ) { DeprecationWarning("npc_parsesrcfile", w2, "shop", filepath, strline(buffer, p-buffer)); } // TODO
else if( strcasecmp(w2,"cashshop") == 0 ) { DeprecationWarning("npc_parsesrcfile", w2, "cashshop", filepath, strline(buffer, p-buffer)); } // TODO
else if( strcasecmp(w2, "script") == 0 ) { DeprecationWarning("npc_parsesrcfile", w2, "script", filepath, strline(buffer, p-buffer)); } // TODO
+ else if( strcasecmp(w2,"trader") == 0 ) DeprecationWarning("npc_parsesrcfile", w2, "trader", filepath, strline(buffer, p-buffer)) // TODO
else if( strncasecmp(w2, "duplicate", 9) == 0 ) {
char temp[10];
safestrncpy(temp, w2, 10);
@@ -3871,7 +4265,7 @@ int npc_reload(void) {
"\t-'"CL_WHITE"%d"CL_RESET"' Mobs Cached\n"
"\t-'"CL_WHITE"%d"CL_RESET"' Mobs Not Cached\n",
npc_id - npc_new_min, npc_warp, npc_shop, npc_script, npc_mob, npc_cache_mob, npc_delay_mob);
-
+
itemdb->name_constants();
instance->reload();
@@ -3890,6 +4284,8 @@ int npc_reload(void) {
//Execute the OnInit event for freshly loaded npcs. [Skotlex]
ShowStatus("Event '"CL_WHITE"OnInit"CL_RESET"' executed with '"CL_WHITE"%d"CL_RESET"' NPCs.\n",npc->event_doall("OnInit"));
+ npc->market_fromsql();/* after OnInit */
+
// Execute rest of the startup events if connected to char-server. [Lance]
if(!intif->CheckForCharServer()){
ShowStatus("Event '"CL_WHITE"OnInterIfInit"CL_RESET"' executed with '"CL_WHITE"%d"CL_RESET"' NPCs.\n", npc->event_doall("OnInterIfInit"));
@@ -4024,7 +4420,7 @@ int do_init_npc(bool minimal) {
"\t-'"CL_WHITE"%d"CL_RESET"' Mobs Not Cached\n",
npc_id - START_NPC_NUM, npc_warp, npc_shop, npc_script, npc_mob, npc_cache_mob, npc_delay_mob);
}
-
+
itemdb->name_constants();
if (!minimal) {
@@ -4076,6 +4472,9 @@ void npc_defaults(void) {
npc->fake_nd = NULL;
npc->src_files = NULL;
/* */
+ npc->trader_ok = false;
+ npc->trader_funds[0] = npc->trader_funds[1] = 0;
+ /* */
npc->init = do_init_npc;
npc->final = do_final_npc;
/* */
@@ -4165,4 +4564,13 @@ void npc_defaults(void) {
npc->debug_warps_sub = npc_debug_warps_sub;
npc->debug_warps = npc_debug_warps;
npc->secure_timeout_timer = npc_rr_secure_timeout_timer;
+ /* */
+ npc->trader_count_funds = npc_trader_count_funds;
+ npc->trader_pay = npc_trader_pay;
+ npc->trader_update = npc_trader_update;
+ npc->market_buylist = npc_market_buylist;
+ npc->trader_open = npc_trader_open;
+ npc->market_fromsql = npc_market_fromsql;
+ npc->market_tosql = npc_market_tosql;
+ npc->market_delfromsql = npc_market_delfromsql;
}
diff --git a/src/map/npc.h b/src/map/npc.h
index feee8f203..792d85d59 100644
--- a/src/map/npc.h
+++ b/src/map/npc.h
@@ -14,6 +14,21 @@ struct block_list;
struct npc_data;
struct view_data;
+enum npc_parse_options {
+ NPO_NONE = 0x0,
+ NPO_ONINIT = 0x1,
+ NPO_TRADER = 0x2,
+};
+
+enum npc_shop_types {
+ NST_ZENY,/* default */
+ NST_CASH,/* official npc cash shop */
+ NST_MARKET,/* official npc market type */
+ NST_CUSTOM,
+ /* */
+ NST_MAX,
+};
+
struct npc_timerevent_list {
int timer,pos;
};
@@ -22,9 +37,15 @@ struct npc_label_list {
int pos;
};
struct npc_item_list {
- unsigned int nameid,value;
+ unsigned short nameid;
+ unsigned int value;
+ unsigned int qty;
+};
+struct npc_shop_data {
+ unsigned char type;/* what am i */
+ struct npc_item_list *item;/* list */
+ unsigned short items;/* total */
};
-
struct npc_data {
struct block_list bl;
struct unit_data *ud;
@@ -60,10 +81,13 @@ struct npc_data {
struct npc_timerevent_list *timer_event;
int label_list_num;
struct npc_label_list *label_list;
+ /* */
+ struct npc_shop_data *shop;
+ bool trader;
} scr;
- struct {
+ struct { /* TODO duck this as soon as the new shop formatting is deemed stable */
struct npc_item_list* shop_item;
- int count;
+ unsigned short count;
} shop;
struct {
short xs,ys; // OnTouch area radius
@@ -143,6 +167,9 @@ struct npc_interface {
struct npc_data *fake_nd;
struct npc_src_list *src_files;
struct unit_data base_ud;
+ /* npc trader global data, for ease of transition between the script, cleared on every usage */
+ bool trader_ok;
+ int trader_funds[2];
/* */
int (*init) (bool minimal);
int (*final) (void);
@@ -208,7 +235,7 @@ struct npc_interface {
const char* (*parse_shop) (char *w1, char *w2, char *w3, char *w4, const char *start, const char *buffer, const char *filepath);
void (*convertlabel_db) (struct npc_label_list *label_list, const char *filepath);
const char* (*skip_script) (const char *start, const char *buffer, const char *filepath);
- const char* (*parse_script) (char *w1, char *w2, char *w3, char *w4, const char *start, const char *buffer, const char *filepath, bool runOnInit);
+ const char* (*parse_script) (char *w1, char *w2, char *w3, char *w4, const char *start, const char *buffer, const char *filepath, int options);
const char* (*parse_duplicate) (char *w1, char *w2, char *w3, char *w4, const char *start, const char *buffer, const char *filepath);
int (*duplicate4instance) (struct npc_data *snd, int16 m);
void (*setcells) (struct npc_data *nd);
@@ -232,6 +259,15 @@ struct npc_interface {
void (*do_clear_npc) (void);
void (*debug_warps_sub) (struct npc_data *nd);
void (*debug_warps) (void);
+ /* */
+ void (*trader_count_funds) (struct npc_data *nd, struct map_session_data *sd);
+ bool (*trader_pay) (struct npc_data *nd, struct map_session_data *sd, int price, int points);
+ void (*trader_update) (int master);
+ int (*market_buylist) (struct map_session_data* sd, unsigned short list_size, struct packet_npc_market_purchase *p);
+ bool (*trader_open) (struct map_session_data *sd, struct npc_data *nd);
+ void (*market_fromsql) (void);
+ void (*market_tosql) (struct npc_data *nd, unsigned short index);
+ void (*market_delfromsql) (struct npc_data *nd, unsigned short index);
/**
* For the Secure NPC Timeout option (check config/Secure.h) [RR]
**/
diff --git a/src/map/packets.h b/src/map/packets.h
index 08c73fdb0..cea916f6d 100644
--- a/src/map/packets.h
+++ b/src/map/packets.h
@@ -2453,6 +2453,45 @@ packet(0x020d,-1);
packet(0x0887,36,clif->pStoragePassword,0);
#endif
+// 2013-12-23cRagexe - Yommy
+#if PACKETVER >= 20131223
+ packet(0x0369,7,clif->pActionRequest,2,6);
+ packet(0x083C,10,clif->pUseSkillToId,2,4,6);
+ packet(0x0437,5,clif->pWalkToXY,2);
+ packet(0x035F,6,clif->pTickSend,2);
+ packet(0x0202,5,clif->pChangeDir,2,4);
+ packet(0x07E4,6,clif->pTakeItem,2);
+ packet(0x0362,6,clif->pDropItem,2,4);
+ packet(0x07EC,8,clif->pMoveToKafra,2,4);
+ packet(0x0364,8,clif->pMoveFromKafra,2,4);
+ packet(0x0438,10,clif->pUseSkillToPos,2,4,6,8);
+ packet(0x0366,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10);
+ packet(0x096A,6,clif->pGetCharNameRequest,2);
+ packet(0x0368,6,clif->pSolveCharName,2);
+ packet(0x0838,12,clif->pSearchStoreInfoListItemClick,2,6,10);
+ packet(0x0835,2,clif->pSearchStoreInfoNextPage,0);
+ packet(0x0819,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15);
+ packet(0x0811,-1,clif->pReqTradeBuyingStore,2,4,8,12);
+ packet(0x0360,6,clif->pReqClickBuyingStore,2);
+ packet(0x0817,2,clif->pReqCloseBuyingStore,0);
+ packet(0x0815,-1,clif->pReqOpenBuyingStore,2,4,8,9,89);
+ packet(0x0365,18,clif->pPartyBookingRegisterReq,2,4);
+ // packet(0x0363,8); // CZ_JOIN_BATTLE_FIELD
+ packet(0x0281,-1,clif->pItemListWindowSelected,2,4,8);
+ packet(0x022d,19,clif->pWantToConnection,2,6,10,14,18);
+ packet(0x0802,26,clif->pPartyInvite2,2);
+ // packet(0x0436,4); // CZ_GANGSI_RANK
+ packet(0x023B,26,clif->pFriendsListAdd,2);
+ packet(0x0361,5,clif->pHomMenu,2,4);
+ packet(0x08A4,36,clif->pStoragePassword,0);
+ /* New */
+ packet(0x09d4,2,clif->pNPCShopClosed);
+ packet(0x09ce,102,clif->pGM_Monster_Item,2);
+ /* NPC Market */
+ packet(0x09d8,2,clif->pNPCMarketClosed);
+ packet(0x09d6,-1,clif->pNPCMarketPurchase);
+#endif
+
/* PacketKeys: http://hercules.ws/board/topic/1105-hercules-wpe-free-june-14th-patch/ */
#if PACKETVER >= 20110817
packetKeys(0x053D5CED,0x3DED6DED,0x6DED6DED); /* Thanks to Shakto */
@@ -2646,6 +2685,10 @@ packet(0x020d,-1);
packetKeys(0x7E241DE0,0x5E805580,0x3D807D80); /* Thanks to Shakto */
#endif
+#if PACKETVER >= 20131223
+ packetKeys(0x631C511C, 0x111C111C,0x111C111C);
+#endif
+
#if defined(OBFUSCATIONKEY1) && defined(OBFUSCATIONKEY2) && defined(OBFUSCATIONKEY3)
packetKeys(OBFUSCATIONKEY1,OBFUSCATIONKEY2,OBFUSCATIONKEY3);
#endif
diff --git a/src/map/packets_struct.h b/src/map/packets_struct.h
index df90b35a4..8f0989f3d 100644
--- a/src/map/packets_struct.h
+++ b/src/map/packets_struct.h
@@ -201,6 +201,8 @@ enum packet_headers {
notifybindonequip = 0x2d3,
monsterhpType = 0x977,
maptypeproperty2Type = 0x99b,
+ npcmarketresultackType = 0x9d7,
+ npcmarketopenType = 0x9d5,
};
#pragma pack(push, 1)
@@ -895,6 +897,48 @@ struct packet_damage {
#endif
} __attribute__((packed));
+struct packet_gm_monster_item {
+ short PacketType;
+#if PACKETVER >= 20131218
+ char str[100];
+#else
+ char str[24];
+#endif
+} __attribute__((packed));
+
+struct packet_npc_market_purchase {
+ short PacketType;
+ short PacketLength;
+ struct {
+ unsigned short ITID;
+ int qty;
+ } list[MAX_INVENTORY];/* assuming MAX_INVENTORY is max since you can't hold more than MAX_INVENTORY items thus cant buy that many at once. */
+} __attribute__((packed));
+
+struct packet_npc_market_result_ack {
+ short PacketType;
+ short PacketLength;
+ unsigned char result;
+ struct {
+ unsigned short ITID;
+ unsigned short qty;
+ unsigned int price;
+ } list[MAX_INVENTORY];/* assuming MAX_INVENTORY is max since you can't hold more than MAX_INVENTORY items thus cant buy that many at once. */
+} __attribute__((packed));
+
+struct packet_npc_market_open {
+ short PacketType;
+ short PacketLength;
+ /* inner struct figured by Ind after some annoying hour of debugging (data Thanks to Yommy) */
+ struct {
+ unsigned short nameid;
+ unsigned char type;
+ unsigned int price;
+ unsigned int qty;
+ unsigned short view;
+ } list[1000];/* TODO: whats the actual max of this? */
+} __attribute__((packed));
+
#pragma pack(pop)
#endif /* _PACKETS_STRUCT_H_ */
diff --git a/src/map/script.c b/src/map/script.c
index 074348ef0..a9ad69954 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -2072,7 +2072,7 @@ void script_set_constant2(const char *name, int value, bool isparameter) {
int n = script->add_str(name);
if( ( script->str_data[n].type == C_NAME || script->str_data[n].type == C_PARAM ) && ( script->str_data[n].val != 0 || script->str_data[n].backpatch != -1 ) ) { // existing parameter or constant
- ShowNotice("Conflicting item/script var '%s', prioritising the script var\n",name);
+ ShowNotice("Conflicting var name '%s', prioritising the script var\n",name);
return;
}
@@ -18012,6 +18012,272 @@ BUILDIN(instance_set_respawn) {
return true;
}
+/**
+ * @call openshop({NPC Name});
+ *
+ * @return 1 on success, 0 otherwise.
+ **/
+BUILDIN(openshop) {
+ struct npc_data *nd;
+ struct map_session_data *sd;
+ const char *name = NULL;
+
+ if( script_hasdata(st, 2) ) {
+ name = script_getstr(st, 2);
+ if( !(nd = npc->name2id(name)) || nd->subtype != SCRIPT ) {
+ ShowWarning("buildin_openshop(\"%s\"): trying to run without a proper NPC!\n",name);
+ return false;
+ }
+ } else if( !(nd = map->id2nd(st->oid)) ) {
+ ShowWarning("buildin_openshop: trying to run without a proper NPC!\n");
+ return false;
+ }
+ if( !( sd = script->rid2sd(st) ) ) {
+ ShowWarning("buildin_openshop: trying to run without a player attached!\n");
+ return false;
+ } else if ( !nd->u.scr.shop || !nd->u.scr.shop->items ) {
+ ShowWarning("buildin_openshop: trying to open without any items!\n");
+ return false;
+ }
+
+ if( !npc->trader_open(sd,nd) )
+ script_pushint(st, 0);
+ else
+ script_pushint(st, 1);
+
+ return true;
+}
+/**
+ * @call sellitem <Item_ID>,{,price{,qty}};
+ *
+ * adds <Item_ID> (or modifies if present) to shop
+ * if price not provided (or -1) uses the item's value_sell
+ **/
+BUILDIN(sellitem) {
+ struct npc_data *nd;
+ struct item_data *it;
+ int i = 0, id = script_getnum(st,2);
+ int value = 0;
+ int qty = 0;
+
+ if( !(nd = map->id2nd(st->oid)) ) {
+ ShowWarning("buildin_sellitem: trying to run without a proper NPC!\n");
+ return false;
+ } else if ( !(it = itemdb->exists(id)) ) {
+ ShowWarning("buildin_sellitem: unknown item id '%d'!\n",id);
+ return false;
+ }
+
+ value = script_hasdata(st,3) ? script_getnum(st, 3) : it->value_buy;
+ if( value == -1 )
+ value = it->value_buy;
+
+ if( !nd->u.scr.shop )
+ npc->trader_update(nd->src_id?nd->src_id:nd->bl.id);
+ else {/* no need to run this if its empty */
+ for( i = 0; i < nd->u.scr.shop->items; i++ ) {
+ if( nd->u.scr.shop->item[i].nameid == id )
+ break;
+ }
+ }
+
+ if( nd->u.scr.shop->type == NST_MARKET ) {
+ if( !script_hasdata(st,4) || ( qty = script_getnum(st, 4) ) <= 0 ) {
+ ShowError("buildin_sellitem: invalid 'qty' for market-type shop!\n");
+ return false;
+ }
+ }
+
+ if( ( nd->u.scr.shop->type == NST_ZENY || nd->u.scr.shop->type == NST_MARKET ) && value*0.75 < it->value_sell*1.24 ) {
+ ShowWarning("buildin_sellitem: Item %s [%d] discounted buying price (%d->%d) is less than overcharged selling price (%d->%d) in NPC %s (%s)\n",
+ it->name, id, value, (int)(value*0.75), it->value_sell, (int)(it->value_sell*1.24), nd->exname, nd->path);
+ }
+
+ if( i != nd->u.scr.shop->items ) {
+ nd->u.scr.shop->item[i].value = value;
+ nd->u.scr.shop->item[i].qty = qty;
+ if( nd->u.scr.shop->type == NST_MARKET ) /* has been manually updated, make it reflect on sql */
+ npc->market_tosql(nd,i);
+ } else {
+ for( i = 0; i < nd->u.scr.shop->items; i++ ) {
+ if( nd->u.scr.shop->item[i].nameid == 0 )
+ break;
+ }
+
+ if( i == nd->u.scr.shop->items ) {
+ if( nd->u.scr.shop->items == USHRT_MAX ) {
+ ShowWarning("buildin_sellitem: Can't add %s (%s/%s), shop list is full!\n", it->name, nd->exname, nd->path);
+ return false;
+ }
+ i = nd->u.scr.shop->items;
+ RECREATE(nd->u.scr.shop->item, struct npc_item_list, ++nd->u.scr.shop->items);
+ }
+
+ nd->u.scr.shop->item[i].nameid = it->nameid;
+ nd->u.scr.shop->item[i].value = value;
+ nd->u.scr.shop->item[i].qty = qty;
+ }
+
+ return true;
+}
+/**
+ * @call stopselling <Item_ID>;
+ *
+ * removes <Item_ID> from the current npc shop
+ *
+ * @return 1 on success, 0 otherwise
+ **/
+BUILDIN(stopselling) {
+ struct npc_data *nd;
+ int i, id = script_getnum(st,2);
+
+ if( !(nd = map->id2nd(st->oid)) || !nd->u.scr.shop ) {
+ ShowWarning("buildin_stopselling: trying to run without a proper NPC!\n");
+ return false;
+ }
+
+ for( i = 0; i < nd->u.scr.shop->items; i++ ) {
+ if( nd->u.scr.shop->item[i].nameid == id )
+ break;
+ }
+
+ if( i != nd->u.scr.shop->items ) {
+ int cursor;
+
+ if( nd->u.scr.shop->type == NST_MARKET )
+ npc->market_delfromsql(nd,i);
+
+ nd->u.scr.shop->item[i].nameid = 0;
+ nd->u.scr.shop->item[i].value = 0;
+ nd->u.scr.shop->item[i].qty = 0;
+
+ for( i = 0, cursor = 0; i < nd->u.scr.shop->items; i++ ) {
+ if( nd->u.scr.shop->item[i].nameid == 0 )
+ continue;
+
+ if( cursor != i ) {
+ nd->u.scr.shop->item[cursor].nameid = nd->u.scr.shop->item[i].nameid;
+ nd->u.scr.shop->item[cursor].value = nd->u.scr.shop->item[i].value;
+ nd->u.scr.shop->item[cursor].qty = nd->u.scr.shop->item[i].qty;
+ }
+
+ cursor++;
+ }
+
+ script_pushint(st, 1);
+ } else
+ script_pushint(st, 0);
+
+ return true;
+}
+/**
+ * @call setcurrency <Val1>{,<Val2>};
+ *
+ * updates currently-attached player shop currency
+ **/
+/* setcurrency(<Val1>,{<Val2>}) */
+BUILDIN(setcurrency) {
+ int val1 = script_getnum(st,2),
+ val2 = script_hasdata(st, 3) ? script_getnum(st,3) : 0;
+ struct npc_data *nd;
+
+ if( !(nd = map->id2nd(st->oid)) ) {
+ ShowWarning("buildin_setcurrency: trying to run without a proper NPC!\n");
+ return false;
+ }
+
+ npc->trader_funds[0] = val1;
+ npc->trader_funds[1] = val2;
+
+ return true;
+}
+/**
+ * @call tradertype(<type>);
+ *
+ * defaults to 0, so no need to call when you're doing zeny
+ * check enum npc_shop_types for list
+ * cleans shop list on use
+ **/
+BUILDIN(tradertype) {
+ int type = script_getnum(st, 2);
+ struct npc_data *nd;
+
+ if( !(nd = map->id2nd(st->oid)) ) {
+ ShowWarning("buildin_tradertype: trying to run without a proper NPC!\n");
+ return false;
+ } else if ( type < 0 || type > NST_MAX ) {
+ ShowWarning("buildin_tradertype: invalid type param %d!\n",type);
+ return false;
+ }
+
+ if( !nd->u.scr.shop )
+ npc->trader_update(nd->src_id?nd->src_id:nd->bl.id);
+ else {/* clear list */
+ int i;
+ for( i = 0; i < nd->u.scr.shop->items; i++ ) {
+ nd->u.scr.shop->item[i].nameid = 0;
+ nd->u.scr.shop->item[i].value = 0;
+ nd->u.scr.shop->item[i].qty = 0;
+ }
+ npc->market_delfromsql(nd,USHRT_MAX);
+ }
+
+ nd->u.scr.shop->type = type;
+
+ return true;
+}
+/**
+ * @call purchaseok();
+ *
+ * signs the transaction can proceed
+ **/
+BUILDIN(purchaseok) {
+ struct npc_data *nd;
+
+ if( !(nd = map->id2nd(st->oid)) || !nd->u.scr.shop ) {
+ ShowWarning("buildin_purchaseok: trying to run without a proper NPC!\n");
+ return false;
+ }
+
+ npc->trader_ok = true;
+
+ return true;
+}
+/**
+ * @call shopcount(<Item_ID>);
+ *
+ * @return number of available items in the script's attached shop
+ **/
+BUILDIN(shopcount) {
+ struct npc_data *nd;
+ int id = script_getnum(st, 2);
+ unsigned short i;
+
+ if( !(nd = map->id2nd(st->oid)) ) {
+ ShowWarning("buildin_shopcount(%d): trying to run without a proper NPC!\n",id);
+ return false;
+ } else if ( !nd->u.scr.shop || !nd->u.scr.shop->items ) {
+ ShowWarning("buildin_shopcount(%d): trying to use without any items!\n",id);
+ return false;
+ } else if ( nd->u.scr.shop->type != NST_MARKET ) {
+ ShowWarning("buildin_shopcount(%d): trying to use on a non-NST_MARKET shop!\n",id);
+ return false;
+ }
+
+ /* lookup */
+ for(i = 0; i < nd->u.scr.shop->items; i++) {
+ if( nd->u.scr.shop->item[i].nameid == id ) {
+ script_pushint(st, nd->u.scr.shop->item[i].qty);
+ break;
+ }
+ }
+
+ /* didn't find it */
+ if( i == nd->u.scr.shop->items )
+ script_pushint(st, 0);
+
+ return true;
+}
// declarations that were supposed to be exported from npc_chat.c
#ifdef PCRE_SUPPORT
@@ -18609,6 +18875,15 @@ void script_parse_builtin(void) {
BUILDIN_DEF(bg_create_team,"sii"),
BUILDIN_DEF(bg_join_team,"i?"),
BUILDIN_DEF(bg_match_over,"s?"),
+
+ /* New Shop Support */
+ BUILDIN_DEF(openshop,"?"),
+ BUILDIN_DEF(sellitem,"i??"),
+ BUILDIN_DEF(stopselling,"i"),
+ BUILDIN_DEF(setcurrency,"i?"),
+ BUILDIN_DEF(tradertype,"i"),
+ BUILDIN_DEF(purchaseok,""),
+ BUILDIN_DEF(shopcount, "i"),
};
int i, len = ARRAYLENGTH(BUILDIN);
RECREATE(script->buildin, char *, script->buildin_count + len); // Pre-alloc to speed up
diff --git a/src/map/status.c b/src/map/status.c
index f6ca1ff00..7d354718d 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -6060,6 +6060,8 @@ void status_set_viewdata(struct block_list *bl, int class_)
sd->vd.cloth_color = 0;
if( sd->sc.option&OPTION_HANBOK && battle_config.hanbok_ignorepalette )
sd->vd.cloth_color = 0;
+ if( sd->sc.option&OPTION_OKTOBERFEST /* TODO: config? */ )
+ sd->vd.cloth_color = 0;
}
} else if (vd)
memcpy(&sd->vd, vd, sizeof(struct view_data));
@@ -7463,6 +7465,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_XMAS:
case SC_SUMMER:
case SC_HANBOK:
+ case SC_OKTOBERFEST:
if (!vd) return 0;
//Store previous values as they could be removed.
unit->stop_attack(bl);
@@ -8680,6 +8683,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_XMAS:
case SC_SUMMER:
case SC_HANBOK:
+ case SC_OKTOBERFEST:
if( !vd ) break;
clif->changelook(bl,LOOK_BASE,vd->class_);
clif->changelook(bl,LOOK_WEAPON,0);
@@ -9067,6 +9071,10 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_FUSION:
sc->option |= OPTION_FLYING;
break;
+ case SC_OKTOBERFEST:
+ sc->option |= OPTION_OKTOBERFEST;
+ opt_flag |= 0x4;
+ break;
default:
opt_flag = 0;
}
@@ -9768,167 +9776,171 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
opt_flag = 1;
switch(type){
- case SC_STONE:
- case SC_FREEZE:
- case SC_STUN:
- case SC_SLEEP:
- case SC_DEEP_SLEEP:
- case SC_BURNING:
- case SC_WHITEIMPRISON:
- case SC_COLD:
- sc->opt1 = 0;
- break;
+ case SC_STONE:
+ case SC_FREEZE:
+ case SC_STUN:
+ case SC_SLEEP:
+ case SC_DEEP_SLEEP:
+ case SC_BURNING:
+ case SC_WHITEIMPRISON:
+ case SC_COLD:
+ sc->opt1 = 0;
+ break;
- case SC_POISON:
- case SC_CURSE:
- case SC_SILENCE:
- case SC_BLIND:
- sc->opt2 &= ~(1<<(type-SC_POISON));
- break;
- case SC_DPOISON:
- sc->opt2 &= ~OPT2_DPOISON;
- break;
- case SC_CRUCIS:
- sc->opt2 &= ~OPT2_SIGNUMCRUCIS;
- break;
+ case SC_POISON:
+ case SC_CURSE:
+ case SC_SILENCE:
+ case SC_BLIND:
+ sc->opt2 &= ~(1<<(type-SC_POISON));
+ break;
+ case SC_DPOISON:
+ sc->opt2 &= ~OPT2_DPOISON;
+ break;
+ case SC_CRUCIS:
+ sc->opt2 &= ~OPT2_SIGNUMCRUCIS;
+ break;
- case SC_HIDING:
- sc->option &= ~OPTION_HIDE;
- opt_flag|= 2|4; //Check for warp trigger + AoE trigger
- break;
- case SC_CLOAKING:
- case SC_CLOAKINGEXCEED:
- case SC__INVISIBILITY:
- sc->option &= ~OPTION_CLOAK;
- case SC_CAMOUFLAGE:
- opt_flag|= 2;
- break;
- case SC_CHASEWALK:
- sc->option &= ~(OPTION_CHASEWALK|OPTION_CLOAK);
- opt_flag|= 2;
- break;
- case SC_SIGHT:
- sc->option &= ~OPTION_SIGHT;
- break;
- case SC_WEDDING:
- sc->option &= ~OPTION_WEDDING;
- opt_flag |= 0x4;
- break;
- case SC_XMAS:
- sc->option &= ~OPTION_XMAS;
- opt_flag |= 0x4;
- break;
- case SC_SUMMER:
- sc->option &= ~OPTION_SUMMER;
- opt_flag |= 0x4;
- break;
- case SC_HANBOK:
- sc->option &= ~OPTION_HANBOK;
- opt_flag |= 0x4;
- break;
- case SC_ORCISH:
- sc->option &= ~OPTION_ORCISH;
- break;
- case SC_RUWACH:
- sc->option &= ~OPTION_RUWACH;
- break;
- case SC_FUSION:
- sc->option &= ~OPTION_FLYING;
- break;
- //opt3
- case SC_TWOHANDQUICKEN:
- case SC_ONEHANDQUICKEN:
- case SC_SPEARQUICKEN:
- case SC_CONCENTRATION:
- case SC_MER_QUICKEN:
- sc->opt3 &= ~OPT3_QUICKEN;
- opt_flag = 0;
- break;
- case SC_OVERTHRUST:
- case SC_OVERTHRUSTMAX:
- case SC_SWOO:
- sc->opt3 &= ~OPT3_OVERTHRUST;
- if( type == SC_SWOO )
- opt_flag = 8;
- else
+ case SC_HIDING:
+ sc->option &= ~OPTION_HIDE;
+ opt_flag|= 2|4; //Check for warp trigger + AoE trigger
+ break;
+ case SC_CLOAKING:
+ case SC_CLOAKINGEXCEED:
+ case SC__INVISIBILITY:
+ sc->option &= ~OPTION_CLOAK;
+ case SC_CAMOUFLAGE:
+ opt_flag|= 2;
+ break;
+ case SC_CHASEWALK:
+ sc->option &= ~(OPTION_CHASEWALK|OPTION_CLOAK);
+ opt_flag|= 2;
+ break;
+ case SC_SIGHT:
+ sc->option &= ~OPTION_SIGHT;
+ break;
+ case SC_WEDDING:
+ sc->option &= ~OPTION_WEDDING;
+ opt_flag |= 0x4;
+ break;
+ case SC_XMAS:
+ sc->option &= ~OPTION_XMAS;
+ opt_flag |= 0x4;
+ break;
+ case SC_SUMMER:
+ sc->option &= ~OPTION_SUMMER;
+ opt_flag |= 0x4;
+ break;
+ case SC_HANBOK:
+ sc->option &= ~OPTION_HANBOK;
+ opt_flag |= 0x4;
+ break;
+ case SC_OKTOBERFEST:
+ sc->option &= ~OPTION_OKTOBERFEST;
+ opt_flag |= 0x4;
+ break;
+ case SC_ORCISH:
+ sc->option &= ~OPTION_ORCISH;
+ break;
+ case SC_RUWACH:
+ sc->option &= ~OPTION_RUWACH;
+ break;
+ case SC_FUSION:
+ sc->option &= ~OPTION_FLYING;
+ break;
+ //opt3
+ case SC_TWOHANDQUICKEN:
+ case SC_ONEHANDQUICKEN:
+ case SC_SPEARQUICKEN:
+ case SC_CONCENTRATION:
+ case SC_MER_QUICKEN:
+ sc->opt3 &= ~OPT3_QUICKEN;
opt_flag = 0;
- break;
- case SC_ENERGYCOAT:
- case SC_SKE:
- sc->opt3 &= ~OPT3_ENERGYCOAT;
- opt_flag = 0;
- break;
- case SC_INCATKRATE: //Simulated Explosion spirits effect.
- if (bl->type != BL_MOB)
- {
+ break;
+ case SC_OVERTHRUST:
+ case SC_OVERTHRUSTMAX:
+ case SC_SWOO:
+ sc->opt3 &= ~OPT3_OVERTHRUST;
+ if( type == SC_SWOO )
+ opt_flag = 8;
+ else
+ opt_flag = 0;
+ break;
+ case SC_ENERGYCOAT:
+ case SC_SKE:
+ sc->opt3 &= ~OPT3_ENERGYCOAT;
opt_flag = 0;
break;
- }
- case SC_EXPLOSIONSPIRITS:
- sc->opt3 &= ~OPT3_EXPLOSIONSPIRITS;
- opt_flag = 0;
- break;
- case SC_STEELBODY:
- case SC_SKA:
- sc->opt3 &= ~OPT3_STEELBODY;
- opt_flag = 0;
- break;
- case SC_BLADESTOP:
- sc->opt3 &= ~OPT3_BLADESTOP;
- opt_flag = 0;
- break;
- case SC_AURABLADE:
- sc->opt3 &= ~OPT3_AURABLADE;
- opt_flag = 0;
- break;
- case SC_BERSERK:
- opt_flag = 0;
- sc->opt3 &= ~OPT3_BERSERK;
- break;
- // case ???: // doesn't seem to do anything
- // sc->opt3 &= ~OPT3_LIGHTBLADE;
- // opt_flag = 0;
- // break;
- case SC_DANCING:
- if ((sce->val1&0xFFFF) == CG_MOONLIT)
- sc->opt3 &= ~OPT3_MOONLIT;
- opt_flag = 0;
- break;
- case SC_MARIONETTE:
- case SC_MARIONETTE_MASTER:
- sc->opt3 &= ~OPT3_MARIONETTE;
- opt_flag = 0;
- break;
- case SC_ASSUMPTIO:
- sc->opt3 &= ~OPT3_ASSUMPTIO;
- opt_flag = 0;
- break;
- case SC_WARM: //SG skills [Komurka]
- sc->opt3 &= ~OPT3_WARM;
- opt_flag = 0;
- break;
- case SC_KAITE:
- sc->opt3 &= ~OPT3_KAITE;
- opt_flag = 0;
- break;
- case SC_NJ_BUNSINJYUTSU:
- sc->opt3 &= ~OPT3_BUNSIN;
- opt_flag = 0;
- break;
- case SC_SOULLINK:
- sc->opt3 &= ~OPT3_SOULLINK;
- opt_flag = 0;
- break;
- case SC_PROPERTYUNDEAD:
- sc->opt3 &= ~OPT3_UNDEAD;
- opt_flag = 0;
- break;
- // case ???: // from DA_CONTRACT (looks like biolab mobs aura)
- // sc->opt3 &= ~OPT3_CONTRACT;
- // opt_flag = 0;
- // break;
- default:
- opt_flag = 0;
+ case SC_INCATKRATE: //Simulated Explosion spirits effect.
+ if (bl->type != BL_MOB)
+ {
+ opt_flag = 0;
+ break;
+ }
+ case SC_EXPLOSIONSPIRITS:
+ sc->opt3 &= ~OPT3_EXPLOSIONSPIRITS;
+ opt_flag = 0;
+ break;
+ case SC_STEELBODY:
+ case SC_SKA:
+ sc->opt3 &= ~OPT3_STEELBODY;
+ opt_flag = 0;
+ break;
+ case SC_BLADESTOP:
+ sc->opt3 &= ~OPT3_BLADESTOP;
+ opt_flag = 0;
+ break;
+ case SC_AURABLADE:
+ sc->opt3 &= ~OPT3_AURABLADE;
+ opt_flag = 0;
+ break;
+ case SC_BERSERK:
+ opt_flag = 0;
+ sc->opt3 &= ~OPT3_BERSERK;
+ break;
+ // case ???: // doesn't seem to do anything
+ // sc->opt3 &= ~OPT3_LIGHTBLADE;
+ // opt_flag = 0;
+ // break;
+ case SC_DANCING:
+ if ((sce->val1&0xFFFF) == CG_MOONLIT)
+ sc->opt3 &= ~OPT3_MOONLIT;
+ opt_flag = 0;
+ break;
+ case SC_MARIONETTE:
+ case SC_MARIONETTE_MASTER:
+ sc->opt3 &= ~OPT3_MARIONETTE;
+ opt_flag = 0;
+ break;
+ case SC_ASSUMPTIO:
+ sc->opt3 &= ~OPT3_ASSUMPTIO;
+ opt_flag = 0;
+ break;
+ case SC_WARM: //SG skills [Komurka]
+ sc->opt3 &= ~OPT3_WARM;
+ opt_flag = 0;
+ break;
+ case SC_KAITE:
+ sc->opt3 &= ~OPT3_KAITE;
+ opt_flag = 0;
+ break;
+ case SC_NJ_BUNSINJYUTSU:
+ sc->opt3 &= ~OPT3_BUNSIN;
+ opt_flag = 0;
+ break;
+ case SC_SOULLINK:
+ sc->opt3 &= ~OPT3_SOULLINK;
+ opt_flag = 0;
+ break;
+ case SC_PROPERTYUNDEAD:
+ sc->opt3 &= ~OPT3_UNDEAD;
+ opt_flag = 0;
+ break;
+ // case ???: // from DA_CONTRACT (looks like biolab mobs aura)
+ // sc->opt3 &= ~OPT3_CONTRACT;
+ // opt_flag = 0;
+ // break;
+ default:
+ opt_flag = 0;
}
if (calc_flag&SCB_DYE) { //Restore DYE color
diff --git a/src/map/status.h b/src/map/status.h
index cdf3e03d6..1fd354c79 100644
--- a/src/map/status.h
+++ b/src/map/status.h
@@ -696,6 +696,8 @@ typedef enum sc_type {
SC_MOONSTAR,
SC_SUPER_STAR,
+ SC_OKTOBERFEST,
+
SC_MAX, //Automatically updated max, used in for's to check we are within bounds.
} sc_type;
// Official status change ids, used to display status icons on the client.
@@ -1545,30 +1547,31 @@ enum {
};
enum {
- OPTION_NOTHING = 0x00000000,
- OPTION_SIGHT = 0x00000001,
- OPTION_HIDE = 0x00000002,
- OPTION_CLOAK = 0x00000004,
- OPTION_FALCON = 0x00000010,
- OPTION_RIDING = 0x00000020,
- OPTION_INVISIBLE = 0x00000040,
- OPTION_ORCISH = 0x00000800,
- OPTION_WEDDING = 0x00001000,
- OPTION_RUWACH = 0x00002000,
- OPTION_CHASEWALK = 0x00004000,
- OPTION_FLYING = 0x00008000, //Note that clientside Flying and Xmas are 0x8000 for clients prior to 2007.
- OPTION_XMAS = 0x00010000,
- OPTION_TRANSFORM = 0x00020000,
- OPTION_SUMMER = 0x00040000,
- OPTION_DRAGON1 = 0x00080000,
- OPTION_WUG = 0x00100000,
- OPTION_WUGRIDER = 0x00200000,
- OPTION_MADOGEAR = 0x00400000,
- OPTION_DRAGON2 = 0x00800000,
- OPTION_DRAGON3 = 0x01000000,
- OPTION_DRAGON4 = 0x02000000,
- OPTION_DRAGON5 = 0x04000000,
- OPTION_HANBOK = 0x08000000,
+ OPTION_NOTHING = 0x00000000,
+ OPTION_SIGHT = 0x00000001,
+ OPTION_HIDE = 0x00000002,
+ OPTION_CLOAK = 0x00000004,
+ OPTION_FALCON = 0x00000010,
+ OPTION_RIDING = 0x00000020,
+ OPTION_INVISIBLE = 0x00000040,
+ OPTION_ORCISH = 0x00000800,
+ OPTION_WEDDING = 0x00001000,
+ OPTION_RUWACH = 0x00002000,
+ OPTION_CHASEWALK = 0x00004000,
+ OPTION_FLYING = 0x00008000, //Note that clientside Flying and Xmas are 0x8000 for clients prior to 2007.
+ OPTION_XMAS = 0x00010000,
+ OPTION_TRANSFORM = 0x00020000,
+ OPTION_SUMMER = 0x00040000,
+ OPTION_DRAGON1 = 0x00080000,
+ OPTION_WUG = 0x00100000,
+ OPTION_WUGRIDER = 0x00200000,
+ OPTION_MADOGEAR = 0x00400000,
+ OPTION_DRAGON2 = 0x00800000,
+ OPTION_DRAGON3 = 0x01000000,
+ OPTION_DRAGON4 = 0x02000000,
+ OPTION_DRAGON5 = 0x04000000,
+ OPTION_HANBOK = 0x08000000,
+ OPTION_OKTOBERFEST = 0x10000000,
#ifndef NEW_CARTS
OPTION_CART1 = 0x00000008,