summaryrefslogtreecommitdiff
path: root/src/map
diff options
context:
space:
mode:
authorskotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec>2006-04-25 18:05:40 +0000
committerskotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec>2006-04-25 18:05:40 +0000
commite7153a55c1392f478faa0522c7f62ded1c115b3a (patch)
tree5b694367c254201d171fa9155db5d2ad7cebd793 /src/map
parent1d675068f04afe6ab0829e99a32d0179c5183431 (diff)
downloadhercules-e7153a55c1392f478faa0522c7f62ded1c115b3a.tar.gz
hercules-e7153a55c1392f478faa0522c7f62ded1c115b3a.tar.bz2
hercules-e7153a55c1392f478faa0522c7f62ded1c115b3a.tar.xz
hercules-e7153a55c1392f478faa0522c7f62ded1c115b3a.zip
- Modified and simplified the random item group format. It now is <GroupID>,<ItemID>,<Rate>, where Rate normally is 1, greater numbers is the equivalent of adding the line multiple times.
- Added constants to identify all groups to db/const.txt - Cleaned up and updated item_db to use these new constants (warning: item_db.sql needs to be updated!) git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@6275 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src/map')
-rw-r--r--src/map/itemdb.c266
-rw-r--r--src/map/itemdb.h38
-rw-r--r--src/map/mob.c4
-rw-r--r--src/map/npc.c2
-rw-r--r--src/map/script.c2
-rw-r--r--src/map/skill.c14
6 files changed, 134 insertions, 192 deletions
diff --git a/src/map/itemdb.c b/src/map/itemdb.c
index 5f5c21c16..cdb724ef3 100644
--- a/src/map/itemdb.c
+++ b/src/map/itemdb.c
@@ -15,18 +15,12 @@
#include "script.h"
#include "pc.h"
-#define MAX_RANDITEM 10000
-#define MAX_ITEMGROUP 32
// ** ITEMDB_OVERRIDE_NAME_VERBOSE **
// 定義すると、itemdb.txtとgrfで名前が異なる場合、表示します.
//#define ITEMDB_OVERRIDE_NAME_VERBOSE 1
static struct dbt* item_db;
-static struct random_item_data blue_box[MAX_RANDITEM], violet_box[MAX_RANDITEM], card_album[MAX_RANDITEM], gift_box[MAX_RANDITEM], scroll[MAX_RANDITEM], finding_ore[MAX_RANDITEM], cookie_bag[MAX_RANDITEM];
-static int blue_box_count=0, violet_box_count=0, card_album_count=0, gift_box_count=0, scroll_count=0, finding_ore_count = 0, cookie_bag_count=0;
-static int blue_box_default=0, violet_box_default=0, card_album_default=0, gift_box_default=0, scroll_default=0, finding_ore_default = 0, cookie_bag_default=0;
-
static struct item_group itemgroup_db[MAX_ITEMGROUP];
struct item_data *dummy_item=NULL; //This is the default dummy item used for non-existant items. [Skotlex]
@@ -102,56 +96,19 @@ int itemdb_searchname_array(struct item_data** data, int size, const char *str)
* 箱系アイテム検索
*------------------------------------------
*/
-int itemdb_searchrandomid(int flags)
+int itemdb_searchrandomid(int group)
{
- int nameid=0,i,index,count;
- struct random_item_data *list=NULL;
-
- static struct {
- int nameid,count;
- struct random_item_data *list;
- } data[8];
-
- if (flags == 0) { //Initialize.
- memset(data, 0, sizeof(data));
- data[1].nameid = blue_box_default;
- data[1].count = blue_box_count;
- data[1].list = blue_box;
- data[2].nameid = violet_box_default;
- data[2].count = violet_box_count;
- data[2].list = violet_box;
- data[3].nameid = card_album_default;
- data[3].count = card_album_count;
- data[3].list = card_album;
- data[4].nameid = gift_box_default;
- data[4].count = gift_box_count;
- data[4].list = gift_box;
- data[5].nameid = scroll_default;
- data[5].count = scroll_count;
- data[5].list = scroll;
- data[6].nameid = finding_ore_default;
- data[6].count = finding_ore_count;
- data[6].list = finding_ore;
- data[7].nameid = cookie_bag_default;
- data[7].count = cookie_bag_count;
- data[7].list = cookie_bag;
- }
- if(flags>=1 && flags<=7){
- nameid=data[flags].nameid;
- count=data[flags].count;
- list=data[flags].list;
-
- if(count > 0) {
- for(i=0;i<1000;i++) {
- index = rand()%count;
- if(rand()%1000000 < list[index].per) {
- nameid = list[index].nameid;
- break;
- }
- }
- }
+ if(group<1 || group>=MAX_ITEMGROUP) {
+ if (battle_config.error_log)
+ ShowError("itemdb_searchrandomid: Invalid group id %d\n", group);
+ return 512; //Return apple?
}
- return nameid;
+ if (itemgroup_db[group].qty)
+ return itemgroup_db[group].nameid[rand()%itemgroup_db[group].qty];
+
+ if (battle_config.error_log)
+ ShowError("itemdb_searchrandomid: No item entries for group id %d\n", group);
+ return 512;
}
/*==========================================
@@ -162,21 +119,13 @@ int itemdb_group (int nameid)
{
int i, j;
for (i=0; i < MAX_ITEMGROUP; i++) {
- for (j=0; j < itemgroup_db[i].qty && itemgroup_db[i].id[j]; j++) {
+ for (j=0; j < itemgroup_db[i].qty; j++) {
if (itemgroup_db[i].id[j] == nameid)
return i;
}
}
return -1;
}
-int itemdb_searchrandomgroup (int groupid)
-{
- if (groupid < 0 || groupid >= MAX_ITEMGROUP ||
- itemgroup_db[groupid].qty == 0 || itemgroup_db[groupid].id[0] == 0)
- return 0;
-
- return itemgroup_db[groupid].id[ rand()%itemgroup_db[groupid].qty ];
-}
/*==========================================
* DBの存在確認
@@ -382,90 +331,6 @@ int itemdb_isequip3(int nameid)
}
/*==========================================
- * ランダムアイテム出現データの読み込み
- *------------------------------------------
- */
-static int itemdb_read_randomitem(void)
-{
- FILE *fp;
- char line[1024];
- int nameid,i,j;
- char *str[10],*p;
-
- const struct {
- char filename[64];
- struct random_item_data *pdata;
- int *pcount,*pdefault;
- } data[] = {
- {"item_bluebox.txt", blue_box, &blue_box_count, &blue_box_default },
- {"item_violetbox.txt", violet_box, &violet_box_count, &violet_box_default },
- {"item_cardalbum.txt", card_album, &card_album_count, &card_album_default },
- {"item_giftbox.txt", gift_box, &gift_box_count, &gift_box_default },
- {"item_scroll.txt", scroll, &scroll_count, &scroll_default },
- {"item_findingore.txt", finding_ore,&finding_ore_count, &finding_ore_default },
- {"item_cookie_bag.txt", cookie_bag,&cookie_bag_count, &cookie_bag_default },
- };
-
- for(i=0;i<sizeof(data)/sizeof(data[0]);i++){
- struct random_item_data *pd=data[i].pdata;
- int *pc=data[i].pcount;
- int *pdefault=data[i].pdefault;
- char *fn=(char *) data[i].filename;
-
- *pdefault = 0;
- *pc = 0; //zero the count in case we are reloading. [Skotlex]
-
- sprintf(line, "%s/%s", db_path, fn);
- if( (fp=fopen(line,"r"))==NULL ){
- ShowError("can't read %s\n",line);
- continue;
- }
-
- while(fgets(line,1020,fp)){
- if(line[0]=='/' && line[1]=='/')
- continue;
- memset(str,0,sizeof(str));
- for(j=0,p=line;j<3 && p;j++){
- str[j]=p;
- p=strchr(p,',');
- if(p) *p++=0;
- }
-
- if(str[0]==NULL)
- continue;
-
- nameid=atoi(str[0]);
- if(nameid<0 || nameid>=20000)
- continue;
- if(nameid == 0) {
- if(str[2])
- *pdefault = atoi(str[2]);
- continue;
- }
-
- if(str[2]){
- pd[ *pc ].nameid = nameid;
- pd[(*pc)++].per = atoi(str[2]);
- }
-
- if(*pc >= MAX_RANDITEM)
- {
- if (battle_config.error_log)
- ShowWarning("Reached limit of random items [%d] in file [%s]\n", MAX_RANDITEM, data[i].filename);
- break;
- }
- }
- fclose(fp);
- if (*pc > 0) {
- ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n",*pc,fn);
- }
- }
-
- itemdb_searchrandomid(0); //Initialize values.
- return 0;
-}
-
-/*==========================================
* アイテム使用可能フラグのオーバーライド
*------------------------------------------
*/
@@ -514,62 +379,106 @@ static int itemdb_read_itemavail (void)
* read item group data
*------------------------------------------
*/
-static int itemdb_read_itemgroup(void)
+static void itemdb_read_itemgroup_sub(const char* filename)
{
FILE *fp;
char line[1024];
int ln=0;
- int groupid,j,k;
- char *str[31],*p;
-
- sprintf(line, "%s/item_group_db.txt", db_path);
- if( (fp=fopen(line,"r"))==NULL ){
+ int groupid,j,k,nameid;
+ char *str[3],*p;
+ char w1[1024], w2[1024];
+
+ if( (fp=fopen(filename,"r"))==NULL ){
ShowError("can't read %s\n", line);
- return -1;
+ return;
}
while(fgets(line,1020,fp)){
+ ln++;
if(line[0]=='/' && line[1]=='/')
continue;
+ if(strstr(line,"import")) {
+ if (sscanf(line, "%[^:]: %[^\r\n]", w1, w2) == 2 &&
+ strcmpi(w1, "import") == 0) {
+ itemdb_read_itemgroup_sub(w2);
+ continue;
+ }
+ }
memset(str,0,sizeof(str));
- for(j=0,p=line;j<31 && p;j++){
+ for(j=0,p=line;j<3 && p;j++){
str[j]=p;
p=strchr(p,',');
if(p) *p++=0;
}
if(str[0]==NULL)
continue;
-
+ if (j<3)
+ continue;
groupid = atoi(str[0]);
- if (groupid < 0 || groupid >= MAX_ITEMGROUP)
+ if (groupid < 0 || groupid >= MAX_ITEMGROUP) {
+ ShowWarning("itemdb_read_itemgroup: Invalid group %d in %s:%d\n", groupid, filename, ln);
continue;
-
- for (j=1; j<=30; j++) {
- if (!str[j])
- break;
- k=atoi(str[j]);
- if (k < 0 || k >= 20000 || !itemdb_exists(k))
- continue;
- //printf ("%d[%d] = %d\n", groupid, j-1, k);
- itemgroup_db[groupid].id[j-1] = k;
- itemgroup_db[groupid].qty=j;
}
- for (j=1; j<30; j++) { //Cleanup the contents. [Skotlex]
- if (itemgroup_db[groupid].id[j-1] == 0 &&
- itemgroup_db[groupid].id[j] != 0)
- {
- itemgroup_db[groupid].id[j-1] = itemgroup_db[groupid].id[j];
- itemgroup_db[groupid].id[j] = 0;
- itemgroup_db[groupid].qty = j;
- }
+ nameid = atoi(str[1]);
+ if (!itemdb_exists(nameid)) {
+ ShowWarning("itemdb_read_itemgroup: Non-existant item %d in %s:%d\n", nameid, filename, ln);
+ continue;
}
- ln++;
+ k = atoi(str[2]);
+ if (itemgroup_db[groupid].qty+k > MAX_RANDITEM) {
+ ShowWarning("itemdb_read_itemgroup: Group %d is full (%d entries) in %s:%d\n", groupid, MAX_RANDITEM, filename, ln);
+ continue;
+ }
+ for(j=0;j<k;j++)
+ itemgroup_db[groupid].nameid[itemgroup_db[groupid].qty++] = nameid;
}
fclose(fp);
- ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n",ln,"item_group_db.txt");
- return 0;
+ return;
}
+static void itemdb_read_itemgroup(void)
+{
+ char path[256];
+ int i;
+ const char* groups[] = {
+ "Blue Box",
+ "Violet Box",
+ "Card Album",
+ "Gift Box",
+ "Scroll Box",
+ "Finding Ore",
+ "Cookie Bag",
+ "Potion",
+ "Herbs",
+ "Fruits",
+ "Meat",
+ "Candy",
+ "Juice",
+ "Fish",
+ "Boxes",
+ "Gemstone",
+ "Jellopy",
+ "Ore",
+ "Food",
+ "Recovery",
+ "Minerals",
+ "Taming",
+ "Scrolls",
+ "Quivers",
+ "Masks",
+ "Accesory",
+ "Jewels",
+ };
+ memset(&itemgroup_db, 0, sizeof(itemgroup_db));
+ snprintf(path, 255, "%s/item_group_db.txt", db_path);
+ itemdb_read_itemgroup_sub(path);
+ ShowStatus("Done reading '"CL_WHITE"%s"CL_RESET"'.\n","item_group_db.txt");
+ if (battle_config.etc_log) {
+ for (i = 1; i < MAX_ITEMGROUP; i++)
+ ShowInfo("Group %s: %d entries.\n", groups[i-1], itemgroup_db[i].qty);
+ }
+ return;
+}
/*==========================================
* アイテムの名前テーブルを読み込む
*------------------------------------------
@@ -1188,7 +1097,6 @@ static void itemdb_read(void)
itemdb_readdb();
itemdb_read_itemgroup();
- itemdb_read_randomitem();
itemdb_read_itemavail();
itemdb_read_noequip();
itemdb_read_itemtrade();
diff --git a/src/map/itemdb.h b/src/map/itemdb.h
index 88741b3b6..c439782e7 100644
--- a/src/map/itemdb.h
+++ b/src/map/itemdb.h
@@ -5,6 +5,7 @@
#define _ITEMDB_H_
#include "map.h"
+#define MAX_RANDITEM 10000
struct item_data {
int nameid;
@@ -53,16 +54,43 @@ struct item_data {
int view_id;
};
-struct random_item_data {
- int nameid;
- int per;
-};
-
struct item_group {
+ int nameid[MAX_RANDITEM];
int qty; //Counts amount of items in the group.
int id[30]; // 120 bytes
};
+enum {
+ IG_BLUEBOX=1,
+ IG_VIOLETBOX, //2
+ IG_CARDALBUM, //3
+ IG_GIFTBOX, //4
+ IG_SCROLLBOX, //5
+ IG_FINDINGORE, //6
+ IG_COOKIEBAG, //7
+ IG_POTION, //8
+ IG_HERBS, //9
+ IG_FRUITS, //10
+ IG_MEAT, //11
+ IG_CANDY, //12
+ IG_JUICE, //13
+ IG_FISH, //14
+ IG_BOXES, //15
+ IG_GEMSTONE, //16
+ IG_JELLOPY, //17
+ IG_ORE, //18
+ IG_FOOD, //19
+ IG_RECOVERY, //20
+ IG_MINERALS, //21
+ IG_TAMING, //22
+ IG_SCROLLS, //23
+ IG_QUIVERS, //24
+ IG_MASKS, //25
+ IG_ACCESORY, //26
+ IG_JEWELS, //27
+ MAX_ITEMGROUP,
+} item_group_list;
+
struct item_data* itemdb_searchname(const char *name);
int itemdb_searchname_array(struct item_data** data, int size, const char *str);
struct item_data* itemdb_load(int nameid);
diff --git a/src/map/mob.c b/src/map/mob.c
index bdd6d6bb4..342ab5b43 100644
--- a/src/map/mob.c
+++ b/src/map/mob.c
@@ -1985,7 +1985,7 @@ int mob_damage(struct block_list *src,struct mob_data *md,int damage,int type)
// Ore Discovery [Celest]
if (sd == mvp_sd && !map[md->bl.m].flag.nomobloot && pc_checkskill(sd,BS_FINDINGORE)>0 && battle_config.finding_ore_rate/10 >= rand()%10000) {
- ditem = mob_setdropitem(itemdb_searchrandomid(6), 1);
+ ditem = mob_setdropitem(itemdb_searchrandomid(IG_FINDINGORE), 1);
if (drop_ore<0) drop_ore=8; //we have only 10 slots in LOG, there's a check to not overflow (9th item usually a card, so we use 8th slot)
log_item[drop_ore] = ditem->item_data.nameid; //it's for logging only
drop_items++; //we count if there were any drops
@@ -2020,7 +2020,7 @@ int mob_damage(struct block_list *src,struct mob_data *md,int damage,int type)
if (drop_rate < rand()%10000 +1)
continue;
itemid = (sd->add_drop[i].id > 0) ? sd->add_drop[i].id :
- itemdb_searchrandomgroup(sd->add_drop[i].group);
+ itemdb_searchrandomid(sd->add_drop[i].group);
mob_item_drop(md, dlist, mob_setdropitem(itemid,1), 0, drop_rate);
}
diff --git a/src/map/npc.c b/src/map/npc.c
index 8f1445838..857c5963d 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -744,8 +744,6 @@ void npc_timerevent_quit(struct map_session_data *sd) {
int npc_gettimerevent_tick(struct npc_data *nd)
{
int tick;
- struct map_session_data *sd =NULL;
-
nullpo_retr(0, nd);
tick=nd->u.scr.timer;
diff --git a/src/map/script.c b/src/map/script.c
index 876f17477..626512003 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -3945,7 +3945,7 @@ int buildin_grouprandomitem(struct script_state *st)
int group;
group = conv_num(st,& (st->stack->stack_data[st->start+2]));
- push_val(st->stack, C_INT, itemdb_searchrandomgroup(group));
+ push_val(st->stack, C_INT, itemdb_searchrandomid(group));
return 0;
}
diff --git a/src/map/skill.c b/src/map/skill.c
index e419b2f56..38f244a4e 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -6653,13 +6653,13 @@ int skill_unit_onplace(struct skill_unit *src,struct block_list *bl,unsigned int
case UNT_ROKISWEIL:
case UNT_INTOABYSS:
case UNT_SIEGFRIED:
+ case UNT_HERMODE:
//Needed to check when a dancer/bard leaves their ensemble area.
if (sg->src_id==bl->id && (!sc || sc->data[SC_SPIRIT].timer == -1 || sc->data[SC_SPIRIT].val2 != SL_BARDDANCER))
return sg->skill_id;
if (sc && sc->data[type].timer==-1)
sc_start4(bl,type,100,sg->skill_lv,sg->val1,sg->val2,0,sg->limit);
break;
-
case UNT_WHISTLE:
case UNT_ASSASSINCROSS:
case UNT_POEMBRAGI:
@@ -6668,11 +6668,18 @@ int skill_unit_onplace(struct skill_unit *src,struct block_list *bl,unsigned int
case UNT_DONTFORGETME:
case UNT_FORTUNEKISS:
case UNT_SERVICEFORYOU:
- case UNT_HERMODE:
if (sg->src_id==bl->id && (!sc || sc->data[SC_SPIRIT].timer == -1 || sc->data[SC_SPIRIT].val2 != SL_BARDDANCER))
return 0;
- if (sc && sc->data[type].timer==-1)
+ if (!sc)
+ break;
+ if (sc->data[type].timer==-1)
sc_start4(bl,type,100,sg->skill_lv,sg->val1,sg->val2,0,sg->limit);
+ else if (sc->data[type].val4 == 1) {
+ //Readjust timers since the effect will not last long.
+ sc->data[type].val4 = 0;
+ delete_timer(sc->data[type].timer, status_change_timer);
+ sc->data[type].timer = add_timer(tick+sg->limit, status_change_timer, bl->id, type);
+ }
break;
/* Basilica does not knocks back...
case UNT_BASILICA:
@@ -7188,6 +7195,7 @@ static int skill_unit_onleft(int skill_id, struct block_list *bl,unsigned int ti
delete_timer(sc->data[type].timer, status_change_timer);
//NOTE: It'd be nice if we could get the skill_lv for a more accurate extra time, but alas...
//not possible on our current implementation.
+ sc->data[type].val4 = 1; //Store the fact that this is a "reduced" duration effect.
sc->data[type].timer = add_timer(tick+skill_get_time2(skill_id,1), status_change_timer, bl->id, type);
}
break;