Merge pull request #143 from rathena/feature/separated_item_guid
Corrected `guid` implementation of item package in 51074a0. See http://rathena.org/board/topic/99743-item-guid/
This commit is contained in:
commit
7295bdc925
@ -4,4 +4,5 @@
|
||||
// <Flag>:
|
||||
// 1 - As Dead Branch item (will be logged at `branchlog` table and cannot be used at 'nobranch' mapflag)
|
||||
// 2 - As item group container, check player's inventory and weight before consumed
|
||||
// 4 - GUID item, cannot be stacked even same or stackable item
|
||||
// NOTE: For removing flag by import file, use "-" to remove the flag. Example, 604,-1 will removes flag 1 from Branch_Of_Dead_Tree
|
||||
|
@ -4,6 +4,7 @@
|
||||
// <Flag>:
|
||||
// 1 - As Dead Branch item (will be logged at `branchlog` table and cannot be used at 'nobranch' mapflag)
|
||||
// 2 - As item group container, check player's inventory and weight before consumed
|
||||
// 4 - GUID item, cannot be stacked even same or stackable item
|
||||
// NOTE: For removing flag by import file, use "-" to remove the flag. Example, 604,-1 will removes flag 1 from Branch_Of_Dead_Tree
|
||||
|
||||
// Logged as Dead Branch item
|
||||
|
@ -4,6 +4,7 @@
|
||||
// <Flag>:
|
||||
// 1 - As Dead Branch item (will be logged at `branchlog` table and cannot be used at 'nobranch' mapflag)
|
||||
// 2 - As item group container, check player's inventory and weight before consumed
|
||||
// 4 - GUID item, cannot be stacked even same or stackable item
|
||||
// NOTE: For removing flag by import file, use "-" to remove the flag. Example, 604,-1 will removes flag 1 from Branch_Of_Dead_Tree
|
||||
|
||||
// Logged as Dead Branch item
|
||||
@ -213,11 +214,19 @@
|
||||
13909,2 //MVP_Hunt_Box
|
||||
13910,2 //Brewing_Box
|
||||
13911,2 //Christmas_Pet_Scroll
|
||||
13925,2 //Lucky_Scroll08
|
||||
13945,2 //Br_SwordPackage
|
||||
13946,2 //Br_MagePackage
|
||||
13947,2 //Br_AcolPackage
|
||||
13948,2 //Br_ArcherPackage
|
||||
13949,2 //Br_MerPackage
|
||||
13950,2 //Br_ThiefPackage
|
||||
13953,2 //All_In_One_Ring_Box
|
||||
13989,2 //Acidbomb_10_Box
|
||||
14001,2 //Basic_Siege_Supply_Box
|
||||
14002,2 //Adv_Siege_Supply_Box
|
||||
14003,2 //Elite_Siege_Supply_Box
|
||||
14229,2 //Sakura_Scroll
|
||||
14242,2 //Beholder_Ring_Box
|
||||
14243,2 //Hallow_Ring_Box
|
||||
14244,2 //Clamorous_Ring_Box
|
||||
@ -242,6 +251,7 @@
|
||||
14469,2 //Ox_Tail_Scroll
|
||||
14596,2 //Pierre_Treasurebox
|
||||
14613,2 //RWC_Scroll_2012
|
||||
14624,2 //Blue_Scroll
|
||||
14626,2 //Indigo_Scroll
|
||||
14643,2 //Violet_Scroll
|
||||
14664,2 //Bi_Hwang_Scroll
|
||||
@ -366,3 +376,259 @@
|
||||
22558,2 //Lucky_Bag
|
||||
22669,2 //HALLOWEEN_G_BOX
|
||||
22685,2 //Solo_Christmas_Gift
|
||||
|
||||
// GUID
|
||||
12915,4 //Aspersio_5_Scroll_Box
|
||||
12923,4 //Pet_Egg_Scroll_Box1
|
||||
12924,4 //Pet_Egg_Scroll_Box2
|
||||
12925,4 //Pet_Egg_Scroll1
|
||||
12926,4 //Pet_Egg_Scroll2
|
||||
12929,4 //Pet_Egg_Scroll_Box3
|
||||
12930,4 //Pet_Egg_Scroll_Box4
|
||||
12931,4 //Pet_Egg_Scroll_Box5
|
||||
12932,4 //Pet_Egg_Scroll3
|
||||
12933,4 //Pet_Egg_Scroll4
|
||||
12934,4 //Pet_Egg_Scroll5
|
||||
12935,4 //Infiltrator_Box
|
||||
12936,4 //Muramasa_Box
|
||||
12937,4 //Excalibur_Box
|
||||
12938,4 //Combat_Knife_Box
|
||||
12939,4 //Counter_Dagger_Box
|
||||
12940,4 //Kaiser_Knuckle_Box
|
||||
12941,4 //Pole_Axe_Box
|
||||
12942,4 //Mighty_Staff_Box
|
||||
12943,4 //Right_Epsilon_Box
|
||||
12944,4 //Balistar_Box
|
||||
12945,4 //Diary_Of_Great_Sage_Box
|
||||
12946,4 //Asura_Box
|
||||
12947,4 //Apple_Of_Archer_Box
|
||||
12948,4 //Bunny_Band_Box
|
||||
12949,4 //Sahkkat_Box
|
||||
12950,4 //Lord_Circlet_Box
|
||||
12951,4 //Elven_Ears_Box
|
||||
12952,4 //Steel_Flower_Box
|
||||
12953,4 //Critical_Ring_Box
|
||||
12954,4 //Earring_Box
|
||||
12955,4 //Ring_Box
|
||||
12956,4 //Necklace_Box
|
||||
12957,4 //Glove_Box
|
||||
12958,4 //Brooch_Box
|
||||
12959,4 //Rosary_Box
|
||||
12960,4 //Safety_Ring_Box
|
||||
12961,4 //Vesper_Core01_Box
|
||||
12962,4 //Vesper_Core02_Box
|
||||
12963,4 //Vesper_Core03_Box
|
||||
12964,4 //Vesper_Core04_Box
|
||||
12983,4 //Pet_Egg_Scroll_Box6
|
||||
12984,4 //Pet_Egg_Scroll_Box7
|
||||
12985,4 //Pet_Egg_Scroll_Box8
|
||||
12986,4 //Pet_Egg_Scroll_Box9
|
||||
12987,4 //Pet_Egg_Scroll_Box10
|
||||
12988,4 //Pet_Egg_Scroll_Box11
|
||||
12989,4 //Pet_Egg_Scroll6
|
||||
12990,4 //Pet_Egg_Scroll7
|
||||
12991,4 //Pet_Egg_Scroll8
|
||||
12992,4 //Pet_Egg_Scroll9
|
||||
12993,4 //Pet_Egg_Scroll10
|
||||
12994,4 //Pet_Egg_Scroll11
|
||||
13543,4 //CP_Helm_Scroll_Box
|
||||
13544,4 //CP_Shield_Scroll_Box
|
||||
13545,4 //CP_Armor_Scroll_Box
|
||||
13546,4 //CP_Weapon_Scroll_Box
|
||||
13547,4 //Repair_Scroll_Box
|
||||
13617,4 //Super_Pet_Egg1
|
||||
13618,4 //Super_Pet_Egg2
|
||||
13619,4 //Super_Pet_Egg3
|
||||
13620,4 //Super_Pet_Egg4
|
||||
13630,4 //Super_Card_Pet_Egg1
|
||||
13631,4 //Super_Card_Pet_Egg2
|
||||
13632,4 //Super_Card_Pet_Egg3
|
||||
13633,4 //Super_Card_Pet_Egg4
|
||||
13634,4 //Vigorgra_Package1
|
||||
13635,4 //Vigorgra_Package2
|
||||
13636,4 //Vigorgra_Package3
|
||||
13637,4 //Vigorgra_Package4
|
||||
13638,4 //Vigorgra_Package5
|
||||
13639,4 //Vigorgra_Package6
|
||||
13640,4 //Vigorgra_Package7
|
||||
13641,4 //Vigorgra_Package8
|
||||
13642,4 //Vigorgra_Package9
|
||||
13643,4 //Vigorgra_Package10
|
||||
13644,4 //Vigorgra_Package11
|
||||
13645,4 //Vigorgra_Package12
|
||||
13701,4 //Pet_Egg_Scroll12
|
||||
13702,4 //Pet_Egg_Scroll13
|
||||
13703,4 //Pet_Egg_Scroll14
|
||||
13704,4 //Super_Pet_Egg5
|
||||
13705,4 //Super_Pet_Egg6
|
||||
13706,4 //Super_Pet_Egg7
|
||||
13707,4 //Super_Pet_Egg8
|
||||
13708,4 //Pet_Egg_Scroll_E
|
||||
13725,4 //Ramen_Hat_Box
|
||||
13773,4 //Fire_Brand_Box
|
||||
13845,4 //Mysterious_Travel_Sack1
|
||||
13846,4 //Mysterious_Travel_Sack2
|
||||
13847,4 //Mysterious_Travel_Sack3
|
||||
13848,4 //Mysterious_Travel_Sack4
|
||||
13871,4 //Magician_Card_Box
|
||||
13872,4 //Acolyte_Card_Box
|
||||
13873,4 //Archer_Card_Box
|
||||
13874,4 //Swordman_Card_Box
|
||||
13875,4 //Thief_Card_Box
|
||||
13876,4 //Merchant_Card_Box
|
||||
13905,4 //Hard_Core_Set_Box
|
||||
13906,4 //Kitty_Set_Box
|
||||
13907,4 //Soft_Core_Set_Box
|
||||
13908,4 //Deviruchi_Set_Box
|
||||
13909,4 //MVP_Hunt_Box
|
||||
13910,4 //Brewing_Box
|
||||
13911,4 //Christmas_Pet_Scroll
|
||||
13925,4 //Lucky_Scroll08
|
||||
13945,4 //Br_SwordPackage
|
||||
13946,4 //Br_MagePackage
|
||||
13947,4 //Br_AcolPackage
|
||||
13948,4 //Br_ArcherPackage
|
||||
13949,4 //Br_MerPackage
|
||||
13950,4 //Br_ThiefPackage
|
||||
13953,4 //All_In_One_Ring_Box
|
||||
13989,4 //Acidbomb_10_Box
|
||||
14001,4 //Basic_Siege_Supply_Box
|
||||
14002,4 //Adv_Siege_Supply_Box
|
||||
14003,4 //Elite_Siege_Supply_Box
|
||||
14229,4 //Sakura_Scroll
|
||||
14242,4 //Beholder_Ring_Box
|
||||
14243,4 //Hallow_Ring_Box
|
||||
14244,4 //Clamorous_Ring_Box
|
||||
14245,4 //Chemical_Ring_Box
|
||||
14246,4 //Insecticide_Ring_Box
|
||||
14247,4 //Fisher_Ring_Box
|
||||
14248,4 //Decussate_Ring_Box
|
||||
14249,4 //Bloody_Ring_Box
|
||||
14250,4 //Satanic_Ring_Box
|
||||
14251,4 //Dragoon_Ring_Box
|
||||
14296,4 //Angel_Scroll
|
||||
14297,4 //Devil_Scroll
|
||||
14298,4 //Surprise_Scroll
|
||||
14306,4 //RWC_Special_Scroll
|
||||
14307,4 //RWC_Limited_Scroll
|
||||
14316,4 //July7_Scroll
|
||||
14317,4 //Bacsojin_Scroll
|
||||
14345,4 //Animal_Scroll
|
||||
14363,4 //Heart_Scroll
|
||||
14408,4 //New_Year_Scroll
|
||||
14466,4 //Valentine_Pledge_Box
|
||||
14469,4 //Ox_Tail_Scroll
|
||||
16245,4 //Tw_April_Scroll
|
||||
16304,4 //Evil_Incarnation
|
||||
16371,4 //Tw_Aug_Scroll
|
||||
16372,4 //F_Clover_Box_Mouth
|
||||
16374,4 //Mouth_Bubble_Gum_Box
|
||||
16385,4 //F_Clover_Box_Mouth2
|
||||
16386,4 //F_Clover_Box_Mouth4
|
||||
16389,4 //BGum_Box_In_Mouth2
|
||||
16390,4 //BGum_Box_In_Mouth4
|
||||
16409,4 //Tw_Sep_Scroll
|
||||
16446,4 //Tw_October_Scroll
|
||||
16456,4 //My_Scroll1
|
||||
16457,4 //Tw_Nov_Scroll
|
||||
16466,4 //My_Scroll2
|
||||
16542,4 //Xmas_Bless
|
||||
16555,4 //Pr_Reset_Stone_Box
|
||||
16556,4 //FPr_Reset_Stone_Box
|
||||
16562,4 //Majestic_Devil_Scroll
|
||||
16576,4 //Illusion_Nothing
|
||||
16638,4 //Life_Ribbon_Box
|
||||
16639,4 //Life_Ribbon_Box2
|
||||
16640,4 //Life_Ribbon_Box3
|
||||
16652,4 //Flame_Light
|
||||
16666,4 //Magic_Candy_Box10
|
||||
16673,4 //Libra_Scroll
|
||||
16675,4 //Splash_Scroll
|
||||
16681,4 //BR_Independence_Scroll
|
||||
16682,4 //Boarding_Halter_Box
|
||||
16687,4 //RWC2010_SuitcaseA
|
||||
16688,4 //RWC2010_SuitcaseB
|
||||
16741,4 //Hairtail_Box1
|
||||
16742,4 //Hairtail_Box2
|
||||
16743,4 //Spearfish_Box1
|
||||
16744,4 //Spearfish_Box2
|
||||
16745,4 //Saurel_Box1
|
||||
16746,4 //Saurel_Box2
|
||||
16747,4 //Tuna_Box1
|
||||
16748,4 //Tuna_Box2
|
||||
16749,4 //Malang_Crab_Box1
|
||||
16750,4 //Malang_Crab_Box2
|
||||
16751,4 //Brindle_Eel_Box1
|
||||
16752,4 //Brindle_Eel_Box2
|
||||
16757,4 //Hallo_Scroll
|
||||
16760,4 //Umbala_Spirit_Box2
|
||||
16761,4 //F_Umbala_Spirit_Box2
|
||||
16763,4 //Ptotection_Seagod_Box2
|
||||
16764,4 //Ptotection_Seagod_Box3
|
||||
16765,4 //Octo_Hstick_Box
|
||||
16766,4 //Octo_Hstick_Box2
|
||||
16767,4 //Octo_Hstick_Box3
|
||||
16770,4 //Silvervine_Fruit_Box10
|
||||
16771,4 //Silvervine_Fruit_Box40
|
||||
16774,4 //Asgard_Scroll
|
||||
16775,4 //Sagittarius_Scroll
|
||||
16826,4 //Sagittarius_Scr_Box
|
||||
16972,4 //Weather_Report_Box
|
||||
16974,4 //Comin_Actor_Box
|
||||
16976,4 //Hen_Set_Box
|
||||
16979,4 //Silvervine_Fruit_Box4
|
||||
16990,4 //Sagittar_Diadem_Scroll
|
||||
16991,4 //Sagittar_Di_Scroll_Box
|
||||
16996,4 //Capri_Crown_Scroll
|
||||
16997,4 //Capri_Crown_Scroll_Box
|
||||
17011,4 //Capricon_Di_Scroll
|
||||
17012,4 //Capricon_Di_Scroll_Box
|
||||
17013,4 //Malang_Woe_Encard_Box
|
||||
17016,4 //Aquarius_Diadem_Scroll
|
||||
17017,4 //Aquarius_Di_Scroll_Box
|
||||
17020,4 //Tw_Nov_Scroll2
|
||||
17021,4 //Summer_Scroll3
|
||||
17022,4 //Super_Pet_Egg1_2
|
||||
17023,4 //Super_Pet_Egg4_2
|
||||
17024,4 //Lovely_Aquarius_Scroll
|
||||
17025,4 //Lovely_Aquarius_Box
|
||||
17026,4 //Boitata_Scroll
|
||||
17028,4 //Pisces_Diadem_Scroll
|
||||
17029,4 //Pisces_Diadem_Box
|
||||
17035,4 //Energetic_Pisces_Scroll
|
||||
17036,4 //Energetic_Pisces_Box
|
||||
17050,4 //Aries_Scroll
|
||||
17051,4 //Aries_Scroll_Box
|
||||
17062,4 //Taurus_Diadem_Scroll
|
||||
17063,4 //Taurus_Di_Scroll_Box
|
||||
17077,4 //Taurus_Crown_Scroll
|
||||
17078,4 //Taurus_Crown_Scroll_Box
|
||||
17082,4 //Gemi_Diadem_Scroll
|
||||
17083,4 //Gemi_Diadem_Scroll_Box
|
||||
17107,4 //Gemi_Crown_Scroll
|
||||
17108,4 //Gemi_Crown_Scroll_Box
|
||||
17138,4 //Ms_Cancer_Scroll
|
||||
17139,4 //RWC_Super_Scroll
|
||||
17140,4 //Leo_Scroll
|
||||
17141,4 //Ms_Virgo_Scroll
|
||||
17143,4 //Ms_Scorpio_Scroll
|
||||
17156,4 //TCG_Card_Scroll
|
||||
17165,4 //Challenge_Kit
|
||||
17209,4 //Tw_Rainbow_Scroll
|
||||
17210,4 //Tw_Red_Scroll
|
||||
17211,4 //Tw_Orange_Scroll
|
||||
17212,4 //Tw_Yellow_Scroll
|
||||
17233,4 //Scroll_Of_Death
|
||||
17234,4 //Scroll_Of_Life
|
||||
17235,4 //Scroll_Of_Magic
|
||||
17236,4 //Scroll_Of_Thews
|
||||
17237,4 //Scroll_Of_Darkness
|
||||
17238,4 //Scroll_Of_Holiness
|
||||
17239,4 //Horned_Scroll
|
||||
17240,4 //Mercury_Scroll
|
||||
17251,4 //C_Wing_Of_Fly_3Day_Box
|
||||
17252,4 //RWC_2012_Set_Box
|
||||
17256,4 //Good_Student_Gift_Box
|
||||
17257,4 //Bad_Student_Gift_Box
|
||||
17262,4 //Ex_Def_Potion_Box
|
||||
22558,4 //Lucky_Bag
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Item Package Database
|
||||
//
|
||||
// Structure of Database:
|
||||
// GroupID,ItemID,Rate{,Amount,Random,isAnnounced,Duration,isNamed,isBound}
|
||||
// GroupID,ItemID,Rate{,Amount,Random,isAnnounced,Duration,GUID,isBound,isNamed}
|
||||
|
||||
IG_Special_Box,Wrapped_Mask,3,1,1
|
||||
IG_Special_Box,Poison_Bottle,10,2,1
|
||||
|
@ -29,10 +29,12 @@ accessed in each.
|
||||
+===============+====================+================+
|
||||
| Duration | no | YES |
|
||||
+===============+====================+================+
|
||||
| isNamed | no | YES |
|
||||
| GUID | no | YES |
|
||||
+===============+====================+================+
|
||||
| isBound | no | YES |
|
||||
+===============+====================+================+
|
||||
| isNamed | no | YES |
|
||||
+===============+====================+================+
|
||||
|
||||
---------------------------------------
|
||||
|
||||
@ -117,7 +119,12 @@ Duration: Makes the item a rental item, which will be expire in the given amount
|
||||
|
||||
---------------------------------------
|
||||
|
||||
isNamed: Inscribes the item with the obtainer's name.
|
||||
GUID: Makes the given item(s) with Unique ID. Item will be stacked ONLY each group
|
||||
when it obtained. Cannot be stacked with same item, even it's stackable item.
|
||||
Example, there is Box (just call it Apple_Box) that contains 3x Apples with
|
||||
GUID = 1. When Apples appear it will stack for each 3 even another 3x Apples
|
||||
are appeared by same box. So it will be filled in inventory as:
|
||||
3x Apples | 3x Apples | so on... | nx Apples (normal)
|
||||
|
||||
---------------------------------------
|
||||
|
||||
@ -126,6 +133,10 @@ isBound: Binds the obtained item.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
isNamed: Inscribes the item with the obtainer's name.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
Supports to import other file, usage:
|
||||
import: db/path/filename.txt
|
||||
|
||||
|
@ -2841,6 +2841,17 @@ Returns value from equipped item slot in the indicated slot (0, 1, 2, or 3).
|
||||
This function returns CARD ID, 255,254,-255 (for card 0, if the item is produced).
|
||||
It's useful for when you want to check whether an item contains cards or if it's signed.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
*mergeitem({<item_id>});
|
||||
*mergeitem({"<item name>"});
|
||||
|
||||
Merge all stackable items that separated by GUID flags
|
||||
(either by flag 4 item_flag.txt or GUID in item_group).
|
||||
If no item ID/name given, all possible items in player's inventory will be merged.
|
||||
|
||||
Example, just see the NPC 'npc/re/other/merge_item.txt'.
|
||||
|
||||
---------------------------------------
|
||||
//
|
||||
2,1.- End of item-related commands.
|
||||
|
@ -3,7 +3,7 @@
|
||||
//===== By: ==================================================
|
||||
//= Euphy
|
||||
//===== Current Version: =====================================
|
||||
//= 1.0
|
||||
//= 1.1
|
||||
//===== Compatible With: =====================================
|
||||
//= rAthena Project
|
||||
//===== Description: =========================================
|
||||
@ -12,6 +12,7 @@
|
||||
//= inventory.
|
||||
//===== Additional Comments: =================================
|
||||
//= 1.0 First version, currently useless/disabled.
|
||||
//= 1.1 Implemented the 'mergeitem' script command. [Cydh]
|
||||
//============================================================
|
||||
|
||||
prontera,146,95,3 script Mergician#pron 64,{
|
||||
@ -55,7 +56,7 @@ prontera,146,95,3 script Mergician#pron 64,{
|
||||
next;
|
||||
switch(select("Merrrrge!:Don't follow what he says.")) {
|
||||
case 1:
|
||||
// MergeItem
|
||||
mergeitem;
|
||||
mes "[Mergician]";
|
||||
mes "Merge just heard your wish and let it be realised!";
|
||||
mes "Open your inventory to check the miracle!";
|
||||
|
@ -90,7 +90,7 @@ npc: npc/re/merchants/shops.txt
|
||||
|
||||
// --------------------------- Others ---------------------------
|
||||
npc: npc/re/other/bulletin_boards.txt
|
||||
//npc: npc/re/other/item_merge.txt
|
||||
npc: npc/re/other/item_merge.txt
|
||||
npc: npc/re/other/mail.txt
|
||||
npc: npc/re/other/mercenary_rent.txt
|
||||
npc: npc/re/other/pvp.txt
|
||||
|
@ -64,6 +64,14 @@
|
||||
/// Uncomment to enable the job base HP/SP table (job_basehpsp_db.txt)
|
||||
//#define HP_SP_TABLES
|
||||
|
||||
/// Enable separated item by `guid`. [Cydh]
|
||||
/// See db/[pre-]re/item_flag.txt and doc/item_group.txt for the `guid` explanation.
|
||||
/// NOTE:
|
||||
/// If this feature is disabled "in the middle" of your game, the separated is still
|
||||
/// separated in inventory, storage, or guild storage until player move the item
|
||||
/// to/from storage/inventory to restack them.
|
||||
#define ENABLE_ITEM_GUID
|
||||
|
||||
/// Uncomment to enable VIP system.
|
||||
//#define VIP_ENABLE
|
||||
|
||||
|
@ -1271,7 +1271,6 @@ ACMD_FUNC(item)
|
||||
item_tmp.nameid = item_id;
|
||||
item_tmp.identify = 1;
|
||||
item_tmp.bound = bound;
|
||||
|
||||
if ((flag = pc_additem(sd, &item_tmp, get_count, LOG_TYPE_COMMAND)))
|
||||
clif_additem(sd, 0, 0, flag);
|
||||
}
|
||||
|
@ -13207,8 +13207,14 @@ void clif_parse_GM_Item_Monster(int fd, struct map_session_data *sd)
|
||||
StringBuf_Init(&command);
|
||||
if( !itemdb_isstackable2(id) ) //Nonstackable
|
||||
StringBuf_Printf(&command, "%citem2 %d 1 0 0 0 0 0 0 0", atcommand_symbol, id->nameid);
|
||||
else
|
||||
StringBuf_Printf(&command, "%citem %d 20", atcommand_symbol, id->nameid);
|
||||
else {
|
||||
#ifdef ENABLE_ITEM_GUID
|
||||
if (id->flag.guid)
|
||||
StringBuf_Printf(&command, "%citem %d 1", atcommand_symbol, id->nameid);
|
||||
else
|
||||
#endif
|
||||
StringBuf_Printf(&command, "%citem %d 20", atcommand_symbol, id->nameid);
|
||||
}
|
||||
is_atcommand(fd, sd, StringBuf_Value(&command), 1);
|
||||
StringBuf_Destroy(&command);
|
||||
return;
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "cashshop.h"
|
||||
#include "script.h" // item script processing
|
||||
#include "pc.h" // W_MUSICAL, W_WHIP
|
||||
#include "intif.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -198,12 +199,17 @@ static void itemdb_pc_get_itemgroup_sub(struct map_session_data *sd, struct s_it
|
||||
// Do loop for non-stackable item
|
||||
for (i = 0; i < data->amount; i++) {
|
||||
char flag = 0;
|
||||
#ifdef ENABLE_ITEM_GUID
|
||||
tmp.unique_id = data->GUID ? pc_generate_unique_id(sd) : 0; // Generate UID
|
||||
#endif
|
||||
if ((flag = pc_additem(sd, &tmp, tmp.amount, LOG_TYPE_SCRIPT)))
|
||||
clif_additem(sd, 0, 0, flag);
|
||||
else if (!flag && data->isAnnounced) { ///TODO: Move this broadcast to proper behavior (it should on at different packet)
|
||||
else if (!flag && data->isAnnounced) {
|
||||
char output[CHAT_SIZE_MAX];
|
||||
sprintf(output, msg_txt(NULL, 717), sd->status.name, itemdb_jname(data->nameid), itemdb_jname(sd->itemid));
|
||||
clif_broadcast(&sd->bl, output, strlen(output), BC_DEFAULT, ALL_CLIENT);
|
||||
|
||||
//! TODO: Move this broadcast to proper packet
|
||||
intif_broadcast(output, strlen(output) + 1, BC_DEFAULT);
|
||||
//clif_broadcast_obtain_special_item();
|
||||
}
|
||||
if (itemdb_isstackable(data->nameid))
|
||||
@ -438,17 +444,17 @@ bool itemdb_isequip2(struct item_data *id)
|
||||
*/
|
||||
bool itemdb_isstackable2(struct item_data *id)
|
||||
{
|
||||
nullpo_ret(id);
|
||||
switch(id->type) {
|
||||
case IT_WEAPON:
|
||||
case IT_ARMOR:
|
||||
case IT_PETEGG:
|
||||
case IT_PETARMOR:
|
||||
case IT_SHADOWGEAR:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
nullpo_ret(id);
|
||||
switch(id->type) {
|
||||
case IT_WEAPON:
|
||||
case IT_ARMOR:
|
||||
case IT_PETEGG:
|
||||
case IT_PETARMOR:
|
||||
case IT_SHADOWGEAR:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -557,7 +563,7 @@ static bool itemdb_read_itemavail(char* str[], int columns, int current) {
|
||||
}
|
||||
|
||||
/** Read item group data
|
||||
* Structure: GroupID,ItemID,Rate{,Amount,isMust,isAnnounced,Duration,isNamed,isBound}
|
||||
* Structure: GroupID,ItemID,Rate{,Amount,isMust,isAnnounced,Duration,GUID,isBound,isNamed}
|
||||
*/
|
||||
static void itemdb_read_itemgroup_sub(const char* filename, bool silent)
|
||||
{
|
||||
@ -574,7 +580,7 @@ static void itemdb_read_itemgroup_sub(const char* filename, bool silent)
|
||||
int group_id = -1;
|
||||
unsigned int j, prob = 1;
|
||||
uint8 rand_group = 1;
|
||||
char *str[9], *p;
|
||||
char *str[10], *p;
|
||||
struct s_item_group_random *random = NULL;
|
||||
struct s_item_group_db *group = NULL;
|
||||
struct s_item_group_entry entry;
|
||||
@ -658,8 +664,11 @@ static void itemdb_read_itemgroup_sub(const char* filename, bool silent)
|
||||
if (str[3] != NULL) entry.amount = cap_value(atoi(str[3]),1,MAX_AMOUNT);
|
||||
if (str[5] != NULL) entry.isAnnounced= atoi(str[5]);
|
||||
if (str[6] != NULL) entry.duration = cap_value(atoi(str[6]),0,UINT16_MAX);
|
||||
if (str[7] != NULL) entry.isNamed = atoi(str[7]);
|
||||
#ifdef ENABLE_ITEM_GUID
|
||||
if (str[7] != NULL) entry.GUID = atoi(str[7]);
|
||||
#endif
|
||||
if (str[8] != NULL) entry.bound = cap_value(atoi(str[8]),BOUND_NONE,BOUND_MAX-1);
|
||||
if (str[9] != NULL) entry.isNamed = atoi(str[9]);
|
||||
|
||||
if (!(group = (struct s_item_group_db *) uidb_get(itemdb_group, group_id))) {
|
||||
CREATE(group, struct s_item_group_db, 1);
|
||||
@ -894,6 +903,7 @@ static bool itemdb_read_nouse(char* fields[], int columns, int current) {
|
||||
* <item_id>,<flag>
|
||||
* &1 - As dead branch item
|
||||
* &2 - As item container
|
||||
* &4 - GUID item, cannot be stacked even same or stackable item
|
||||
*/
|
||||
static bool itemdb_read_flag(char* fields[], int columns, int current) {
|
||||
unsigned short nameid = atoi(fields[0]);
|
||||
@ -911,6 +921,9 @@ static bool itemdb_read_flag(char* fields[], int columns, int current) {
|
||||
|
||||
if (flag&1) id->flag.dead_branch = set ? 1 : 0;
|
||||
if (flag&2) id->flag.group = set ? 1 : 0;
|
||||
#ifdef ENABLE_ITEM_GUID
|
||||
if (flag&4 && itemdb_isstackable2(id)) id->flag.guid = set ? 1 : 0;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -345,6 +345,7 @@ struct s_item_group_entry
|
||||
duration, /// Duration if item as rental item (in minutes)
|
||||
amount; /// Amount of item will be obtained
|
||||
bool isAnnounced, /// Broadcast if player get this item
|
||||
GUID, /// Gives Unique ID for items in each box opened
|
||||
isNamed; /// Named the item (if possible)
|
||||
char bound; /// Makes the item as bound item (according to bound type)
|
||||
};
|
||||
@ -414,6 +415,7 @@ struct item_data
|
||||
unsigned buyingstore : 1;
|
||||
unsigned dead_branch : 1; // As dead branch item. Logged at `branchlog` table and cannot be used at 'nobranch' mapflag [Cydh]
|
||||
unsigned group : 1; // As item group container [Cydh]
|
||||
unsigned guid : 1; // This item always be attached with GUID and make it as bound item! [Cydh]
|
||||
} flag;
|
||||
struct {// item stacking limitation
|
||||
unsigned short amount;
|
||||
|
35
src/map/pc.c
35
src/map/pc.c
@ -4289,13 +4289,23 @@ char pc_additem(struct map_session_data *sd,struct item *item,int amount,e_log_p
|
||||
|
||||
i = MAX_INVENTORY;
|
||||
|
||||
#ifdef ENABLE_ITEM_GUID
|
||||
if (id->flag.guid && !item->unique_id)
|
||||
item->unique_id = pc_generate_unique_id(sd);
|
||||
#endif
|
||||
|
||||
// Stackable | Non Rental
|
||||
if( itemdb_isstackable2(id) && item->expire_time == 0 ) {
|
||||
for( i = 0; i < MAX_INVENTORY; i++ ) {
|
||||
if( sd->status.inventory[i].nameid == item->nameid &&
|
||||
sd->status.inventory[i].bound == item->bound &&
|
||||
sd->status.inventory[i].expire_time == 0 &&
|
||||
memcmp(&sd->status.inventory[i].card, &item->card, sizeof(item->card)) == 0 ) {
|
||||
sd->status.inventory[i].bound == item->bound &&
|
||||
sd->status.inventory[i].expire_time == 0 &&
|
||||
#ifdef ENABLE_ITEM_GUID
|
||||
sd->status.inventory[i].unique_id == item->unique_id &&
|
||||
#endif
|
||||
memcmp(&sd->status.inventory[i].card, &item->card, sizeof(item->card)) == 0
|
||||
)
|
||||
{
|
||||
if( amount > MAX_AMOUNT - sd->status.inventory[i].amount || ( id->stack.inventory && amount > id->stack.amount - sd->status.inventory[i].amount ) )
|
||||
return ADDITEM_OVERAMOUNT;
|
||||
sd->status.inventory[i].amount += amount;
|
||||
@ -4324,7 +4334,7 @@ char pc_additem(struct map_session_data *sd,struct item *item,int amount,e_log_p
|
||||
clif_additem(sd,i,amount,0);
|
||||
}
|
||||
if( !itemdb_isstackable2(id) && !item->unique_id )
|
||||
sd->status.inventory[i].unique_id = pc_generate_unique_id(sd);
|
||||
item->unique_id = pc_generate_unique_id(sd);
|
||||
log_pick_pc(sd, log_type, amount, &sd->status.inventory[i]);
|
||||
|
||||
sd->weight += w;
|
||||
@ -4858,11 +4868,17 @@ unsigned char pc_cart_additem(struct map_session_data *sd,struct item *item,int
|
||||
i = MAX_CART;
|
||||
if( itemdb_isstackable2(data) && !item->expire_time )
|
||||
{
|
||||
ARR_FIND( 0, MAX_CART, i,
|
||||
sd->status.cart[i].nameid == item->nameid && sd->status.cart[i].bound == item->bound &&
|
||||
sd->status.cart[i].card[0] == item->card[0] && sd->status.cart[i].card[1] == item->card[1] &&
|
||||
sd->status.cart[i].card[2] == item->card[2] && sd->status.cart[i].card[3] == item->card[3] );
|
||||
};
|
||||
for (i = 0; i < MAX_CART; i++) {
|
||||
if (sd->status.cart[i].nameid == item->nameid
|
||||
&& sd->status.cart[i].bound == item->bound
|
||||
#ifdef ENABLE_ITEM_GUID
|
||||
&& sd->status.cart[i].unique_id == item->unique_id
|
||||
#endif
|
||||
&& memcmp(sd->status.cart[i].card, item->card, sizeof(item->card)) == 0
|
||||
)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( i < MAX_CART )
|
||||
{// item already in cart, stack it
|
||||
@ -11274,6 +11290,7 @@ bool pc_is_same_equip_index(enum equip_index eqi, short *equip_index, short inde
|
||||
* @return A generated Unique item ID
|
||||
*/
|
||||
uint64 pc_generate_unique_id(struct map_session_data *sd) {
|
||||
nullpo_ret(sd);
|
||||
return ((uint64)sd->status.char_id << 32) | sd->status.uniqueitem_counter++;
|
||||
}
|
||||
|
||||
|
@ -6497,20 +6497,21 @@ BUILDIN_FUNC(getitem)
|
||||
struct script_data *data;
|
||||
unsigned char flag = 0;
|
||||
const char* command = script_getfuncname(st);
|
||||
struct item_data *id = NULL;
|
||||
|
||||
data=script_getdata(st,2);
|
||||
data = script_getdata(st,2);
|
||||
get_val(st,data);
|
||||
if( data_isstring(data) ) {// "<item name>"
|
||||
const char *name = conv_str(st,data);
|
||||
struct item_data *item_data = itemdb_searchname(name);
|
||||
if( item_data == NULL ){
|
||||
id = itemdb_searchname(name);
|
||||
if( id == NULL ){
|
||||
ShowError("buildin_getitem: Nonexistant item %s requested.\n", name);
|
||||
return SCRIPT_CMD_FAILURE; //No item created.
|
||||
}
|
||||
nameid = item_data->nameid;
|
||||
nameid = id->nameid;
|
||||
} else if( data_isint(data) ) {// <item id>
|
||||
nameid = conv_num(st,data);
|
||||
if( !itemdb_exists(nameid) ){
|
||||
if( !(id = itemdb_exists(nameid)) ){
|
||||
ShowError("buildin_getitem: Nonexistant item %d requested.\n", nameid);
|
||||
return SCRIPT_CMD_FAILURE; //No item created.
|
||||
}
|
||||
@ -6548,7 +6549,7 @@ BUILDIN_FUNC(getitem)
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
|
||||
//Check if it's stackable.
|
||||
if (!itemdb_isstackable(nameid))
|
||||
if (!itemdb_isstackable2(id))
|
||||
get_count = 1;
|
||||
else
|
||||
get_count = amount;
|
||||
@ -6666,7 +6667,7 @@ BUILDIN_FUNC(getitem2)
|
||||
item_tmp.bound = bound;
|
||||
|
||||
//Check if it's stackable.
|
||||
if (!itemdb_isstackable(nameid))
|
||||
if (!itemdb_isstackable2(item_data))
|
||||
get_count = 1;
|
||||
else
|
||||
get_count = amount;
|
||||
@ -19111,6 +19112,89 @@ BUILDIN_FUNC(countspiritball) {
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
}
|
||||
|
||||
/** Merges separated stackable items because of guid
|
||||
* mergeitem {<item_id>};
|
||||
* mergeitem {"<item name>"};
|
||||
* @param item Item ID/Name for merging specific item (Optional)
|
||||
* @author [Cydh]
|
||||
*/
|
||||
BUILDIN_FUNC(mergeitem) {
|
||||
struct map_session_data *sd = script_rid2sd(st);
|
||||
struct item *items;
|
||||
uint16 i, count = 0;
|
||||
int nameid = 0;
|
||||
|
||||
if (!sd)
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
|
||||
if (script_hasdata(st, 2)) {
|
||||
struct script_data *data = script_getdata(st, 2);
|
||||
struct item_data *id;
|
||||
get_val(st, data);
|
||||
|
||||
if (data_isstring(data)) {// "<item name>"
|
||||
const char *name = conv_str(st,data);
|
||||
if (!(id = itemdb_searchname(name))) {
|
||||
ShowError("buildin_mergeitem: Nonexistant item %s requested.\n", name);
|
||||
script_pushint(st, count);
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
}
|
||||
nameid = id->nameid;
|
||||
}
|
||||
else if (data_isint(data)) {// <item id>
|
||||
nameid = conv_num(st,data);
|
||||
if (!(id = itemdb_exists(nameid))) {
|
||||
ShowError("buildin_mergeitem: Nonexistant item %d requested.\n", nameid);
|
||||
script_pushint(st, count);
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_INVENTORY; i++) {
|
||||
struct item *it = &sd->status.inventory[i];
|
||||
if (!it || !it->unique_id || it->expire_time || !itemdb_isstackable(it->nameid))
|
||||
continue;
|
||||
if ((!nameid || (nameid == it->nameid))) {
|
||||
uint8 k;
|
||||
if (!count) {
|
||||
CREATE(items, struct item, 1);
|
||||
memcpy(&items[count++], it, sizeof(struct item));
|
||||
pc_delitem(sd, i, it->amount, 0, 0, LOG_TYPE_NPC);
|
||||
continue;
|
||||
}
|
||||
for (k = 0; k < count; k++) {
|
||||
// Find Match
|
||||
if (&items[k] && items[k].nameid == it->nameid && items[k].bound == it->bound && memcmp(items[k].card, it->card, sizeof(it->card)) == 0) {
|
||||
items[k].amount += it->amount;
|
||||
pc_delitem(sd, i, it->amount, 0, 0, LOG_TYPE_NPC);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (k >= count) {
|
||||
// New entry
|
||||
RECREATE(items, struct item, count+1);
|
||||
memcpy(&items[count++], it, sizeof(struct item));
|
||||
pc_delitem(sd, i, it->amount, 0, 0, LOG_TYPE_NPC);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Retrieve the items
|
||||
for (i = 0; i < count; i++) {
|
||||
uint8 flag = 0;
|
||||
if (!&items[i])
|
||||
continue;
|
||||
items[i].id = 0;
|
||||
items[i].unique_id = 0;
|
||||
if ((flag = pc_additem(sd, &items[i], items[i].amount, LOG_TYPE_NPC)))
|
||||
clif_additem(sd, i, items[i].amount, flag);
|
||||
}
|
||||
aFree(items);
|
||||
script_pushint(st, count);
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
}
|
||||
|
||||
#include "../custom/script.inc"
|
||||
|
||||
// declarations that were supposed to be exported from npc_chat.c
|
||||
@ -19653,6 +19737,7 @@ struct script_function buildin_func[] = {
|
||||
BUILDIN_DEF(addspiritball,"ii?"),
|
||||
BUILDIN_DEF(delspiritball,"i?"),
|
||||
BUILDIN_DEF(countspiritball,"?"),
|
||||
BUILDIN_DEF(mergeitem,"?"),
|
||||
|
||||
#include "../custom/script_def.inc"
|
||||
|
||||
|
@ -131,7 +131,7 @@ int storage_storageopen(struct map_session_data *sd)
|
||||
}
|
||||
|
||||
/**
|
||||
* check if 2 item a and b have same values
|
||||
* Check if 2 item a and b have same values
|
||||
* @param a : item 1
|
||||
* @param b : item 2
|
||||
* @return 1:same, 0:are different
|
||||
@ -143,7 +143,12 @@ int compare_item(struct item *a, struct item *b)
|
||||
a->refine == b->refine &&
|
||||
a->attribute == b->attribute &&
|
||||
a->expire_time == b->expire_time &&
|
||||
a->bound == b->bound ) {
|
||||
a->bound == b->bound
|
||||
#ifdef ENABLE_ITEM_GUID
|
||||
&& a->unique_id == b->unique_id
|
||||
#endif
|
||||
)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_SLOTS && (a->card[i] == b->card[i]); i++);
|
||||
|
Loading…
x
Reference in New Issue
Block a user