summaryrefslogtreecommitdiff
path: root/src/map
diff options
context:
space:
mode:
Diffstat (limited to 'src/map')
-rw-r--r--src/map/battle.c6
-rw-r--r--src/map/battleground.h1
-rw-r--r--src/map/instance.c6
-rw-r--r--src/map/itemdb.c425
-rw-r--r--src/map/itemdb.h10
-rw-r--r--src/map/mob.c9
-rw-r--r--src/map/packets_struct.h8
-rw-r--r--src/map/script.c6
-rw-r--r--src/map/skill.c8
-rw-r--r--src/map/skill.h4
10 files changed, 382 insertions, 101 deletions
diff --git a/src/map/battle.c b/src/map/battle.c
index aeed4c2b0..3268128ac 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -1554,7 +1554,7 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block
if( sd && sd->status.party_id ){
struct map_session_data* psd;
- int static p_sd[5] = {0, 0, 0, 0, 0}, c; // just limit it to 5
+ int p_sd[5] = {0, 0, 0, 0, 0}, c; // just limit it to 5
c = 0;
memset (p_sd, 0, sizeof(p_sd));
@@ -1594,7 +1594,7 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block
break;
case LG_RAYOFGENESIS:
{
- int16 lv = skill_lv;
+ uint16 lv = skill_lv;
int bandingBonus = 0;
if( sc && sc->data[SC_BANDING] )
bandingBonus = 200 * (sd ? skill->check_pc_partner(sd,skill_id,&lv,skill->get_splash(skill_id,skill_lv),0) : 1);
@@ -2378,7 +2378,7 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block
case WM_GREAT_ECHO:
skillratio += 800 + 100 * skill_lv;
if( sd ) { // Still need official value [pakpil]
- short lv = (short)skill_lv;
+ uint16 lv = skill_lv;
skillratio += 100 * skill->check_pc_partner(sd,skill_id,&lv,skill->get_splash(skill_id,skill_lv),0);
}
break;
diff --git a/src/map/battleground.h b/src/map/battleground.h
index 88d75f953..36f6f0cee 100644
--- a/src/map/battleground.h
+++ b/src/map/battleground.h
@@ -6,6 +6,7 @@
#define _BATTLEGROUND_H_
#include "../common/mmo.h" // struct party
+#include "clif.h"
#include "guild.h"
/**
diff --git a/src/map/instance.c b/src/map/instance.c
index 9207c1d53..3f4b29a89 100644
--- a/src/map/instance.c
+++ b/src/map/instance.c
@@ -118,15 +118,15 @@ int instance_create(int owner_id, const char *name, enum instance_owner_type typ
if( j == *icptr ) {
switch( type ) {
case IOT_CHAR:
- RECREATE(sd->instance, unsigned short, ++*icptr);
+ RECREATE(sd->instance, short, ++*icptr);
sd->instance[sd->instances-1] = i;
break;
case IOT_PARTY:
- RECREATE(p->instance, unsigned short, ++*icptr);
+ RECREATE(p->instance, short, ++*icptr);
p->instance[p->instances-1] = i;
break;
case IOT_GUILD:
- RECREATE(g->instance, unsigned short, ++*icptr);
+ RECREATE(g->instance, short, ++*icptr);
g->instance[g->instances-1] = i;
break;
}
diff --git a/src/map/itemdb.c b/src/map/itemdb.c
index 87ba90410..7c28c6968 100644
--- a/src/map/itemdb.c
+++ b/src/map/itemdb.c
@@ -197,44 +197,46 @@ void itemdb_package_item(struct map_session_data *sd, struct item_package *packa
}
if( package->random_qty ) {
- struct item_package_rand_entry *entry;
-
- entry = &package->random_list[rnd()%package->random_qty];
-
- while( 1 ) {
- if( rnd()%10000 >= entry->rate ) {
- entry = entry->next;
- continue;
- } else {
- struct item it;
- memset(&it, 0, sizeof(it));
-
- it.nameid = entry->id;
- it.identify = 1;
-
- if( entry->hours ) {
- it.expire_time = (unsigned int)(time(NULL) + ((entry->hours*60)*60));
- }
-
- if( entry->named ) {
- it.card[0] = CARD0_FORGE;
- it.card[1] = 0;
- it.card[2] = GetWord(sd->status.char_id, 0);
- it.card[3] = GetWord(sd->status.char_id, 1);
- }
-
- if( entry->announce )
- clif->package_announce(sd,entry->id,package->id);
-
- get_count = itemdb_isstackable(entry->id) ? entry->qty : 1;
-
- it.amount = get_count == 1 ? 1 : get_count;
-
- for( j = 0; j < entry->qty; j += get_count ) {
- if ( ( flag = pc->additem(sd, &it, get_count, LOG_TYPE_SCRIPT) ) )
- clif->additem(sd, 0, 0, flag);
+ for( i = 0; i < package->random_qty; i++ ) {
+ struct item_package_rand_entry *entry;
+
+ entry = &package->random_groups[i].random_list[rnd()%package->random_groups[i].random_qty];
+
+ while( 1 ) {
+ if( rnd()%10000 >= entry->rate ) {
+ entry = entry->next;
+ continue;
+ } else {
+ struct item it;
+ memset(&it, 0, sizeof(it));
+
+ it.nameid = entry->id;
+ it.identify = 1;
+
+ if( entry->hours ) {
+ it.expire_time = (unsigned int)(time(NULL) + ((entry->hours*60)*60));
+ }
+
+ if( entry->named ) {
+ it.card[0] = CARD0_FORGE;
+ it.card[1] = 0;
+ it.card[2] = GetWord(sd->status.char_id, 0);
+ it.card[3] = GetWord(sd->status.char_id, 1);
+ }
+
+ if( entry->announce )
+ clif->package_announce(sd,entry->id,package->id);
+
+ get_count = itemdb_isstackable(entry->id) ? entry->qty : 1;
+
+ it.amount = get_count == 1 ? 1 : get_count;
+
+ for( j = 0; j < entry->qty; j += get_count ) {
+ if ( ( flag = pc->additem(sd, &it, get_count, LOG_TYPE_SCRIPT) ) )
+ clif->additem(sd, 0, 0, flag);
+ }
+ break;
}
- break;
}
}
}
@@ -673,7 +675,6 @@ void itemdb_read_groups(void) {
itemdb->groups[count].qty = gsize[ count ];
CREATE(itemdb->groups[count].nameid, unsigned short, gsize[ count ] + 1);
-
c = 0;
while( (it = config_setting_get_elem(itg,c++)) ) {
int repeat = 1;
@@ -705,7 +706,188 @@ void itemdb_read_groups(void) {
ShowStatus("Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, config_filename);
}
+/* [Ind/Hercules] - HCache for Packages */
+void itemdb_write_cached_packages(const char *config_filename) {
+ FILE *file;
+ unsigned short pcount = itemdb->package_count;
+ unsigned short i;
+
+ if( !(file = HCache->open(config_filename,"wb")) ) {
+ return;
+ }
+
+ // first 2 bytes = package count
+ fwrite(&pcount,sizeof(pcount),1,file);
+
+ for(i = 0; i < pcount; i++) {
+ unsigned short id = itemdb->packages[i].id, random_qty = itemdb->packages[i].random_qty, must_qty = itemdb->packages[i].must_qty;
+ unsigned short c;
+ //into a package, first 2 bytes = id.
+ fwrite(&id,sizeof(id),1,file);
+ //next 2 bytes = must count
+ fwrite(&must_qty,sizeof(must_qty),1,file);
+ //next 2 bytes = random count
+ fwrite(&random_qty,sizeof(random_qty),1,file);
+ //now we loop into must
+ for(c = 0; c < must_qty; c++) {
+ struct item_package_must_entry *entry = &itemdb->packages[i].must_items[c];
+ unsigned char announce = entry->announce == 1 ? 1 : 0, named = entry->named == 1 ? 1 : 0;
+ //first 2 byte = item id
+ fwrite(&entry->id,sizeof(entry->id),1,file);
+ //next 2 byte = qty
+ fwrite(&entry->qty,sizeof(entry->qty),1,file);
+ //next 2 byte = hours
+ fwrite(&entry->hours,sizeof(entry->hours),1,file);
+ //next 1 byte = announce (1:0)
+ fwrite(&announce,sizeof(announce),1,file);
+ //next 1 byte = named (1:0)
+ fwrite(&named,sizeof(announce),1,file);
+ }
+ //now we loop into random groups
+ for(c = 0; c < random_qty; c++) {
+ struct item_package_rand_group *group = &itemdb->packages[i].random_groups[c];
+ unsigned short group_qty = group->random_qty, h;
+
+ //next 2 bytes = how many entries in this group
+ fwrite(&group_qty,sizeof(group_qty),1,file);
+ //now we loop into the group's list
+ for(h = 0; h < group_qty; h++) {
+ struct item_package_rand_entry *entry = &itemdb->packages[i].random_groups[c].random_list[h];
+ unsigned char announce = entry->announce == 1 ? 1 : 0, named = entry->named == 1 ? 1 : 0;
+ //first 2 byte = item id
+ fwrite(&entry->id,sizeof(entry->id),1,file);
+ //next 2 byte = qty
+ fwrite(&entry->qty,sizeof(entry->qty),1,file);
+ //next 2 byte = rate
+ fwrite(&entry->rate,sizeof(entry->rate),1,file);
+ //next 2 byte = hours
+ fwrite(&entry->hours,sizeof(entry->hours),1,file);
+ //next 1 byte = announce (1:0)
+ fwrite(&announce,sizeof(announce),1,file);
+ //next 1 byte = named (1:0)
+ fwrite(&named,sizeof(announce),1,file);
+ }
+ }
+ }
+
+ fclose(file);
+
+ return;
+}
+bool itemdb_read_cached_packages(const char *config_filename) {
+ FILE *file;
+ unsigned short pcount;
+ unsigned short i;
+
+ if( !(file = HCache->open(config_filename,"rb")) ) {
+ return false;
+ }
+
+ // first 2 bytes = package count
+ fread(&pcount,sizeof(pcount),1,file);
+ CREATE(itemdb->packages, struct item_package, pcount);
+ itemdb->package_count = pcount;
+
+ for( i = 0; i < pcount; i++ ) {
+ unsigned short id = 0, random_qty = 0, must_qty = 0;
+ struct item_package *package = &itemdb->packages[i];
+ unsigned short c;
+
+ //into a package, first 2 bytes = id.
+ fread(&id,sizeof(id),1,file);
+ //next 2 bytes = must count
+ fread(&must_qty,sizeof(must_qty),1,file);
+ //next 2 bytes = random count
+ fread(&random_qty,sizeof(random_qty),1,file);
+
+ package->id = id;
+ package->random_qty = random_qty;
+ package->must_qty = must_qty;
+ package->must_items = NULL;
+ package->random_groups = NULL;
+
+ if( package->must_qty ) {
+ CREATE(package->must_items, struct item_package_must_entry, package->must_qty);
+ //now we loop into must
+ for(c = 0; c < package->must_qty; c++) {
+ struct item_package_must_entry *entry = &itemdb->packages[i].must_items[c];
+ unsigned short mid = 0, qty = 0, hours = 0;
+ unsigned char announce = 0, named = 0;
+ struct item_data *data;
+ //first 2 byte = item id
+ fread(&mid,sizeof(mid),1,file);
+ //next 2 byte = qty
+ fread(&qty,sizeof(qty),1,file);
+ //next 2 byte = hours
+ fread(&hours,sizeof(hours),1,file);
+ //next 1 byte = announce (1:0)
+ fread(&announce,sizeof(announce),1,file);
+ //next 1 byte = named (1:0)
+ fread(&named,sizeof(announce),1,file);
+
+ if( !(data = itemdb->exists(mid)) )
+ ShowWarning("itemdb_read_packages: unknown item '%d' in package '%s'!\n",mid,itemdb_name(package->id));
+
+ entry->id = data ? data->nameid : 0;
+ entry->hours = hours;
+ entry->qty = qty;
+ entry->announce = announce ? 1 : 0;
+ entry->named = named ? 1 : 0;
+ }
+ }
+ if( package->random_qty ) {
+ //now we loop into random groups
+ CREATE(package->random_groups, struct item_package_rand_group, package->random_qty);
+ for(c = 0; c < package->random_qty; c++) {
+ unsigned short group_qty = 0, h;
+
+ //next 2 bytes = how many entries in this group
+ fread(&group_qty,sizeof(group_qty),1,file);
+
+ package->random_groups[c].random_qty = group_qty;
+ CREATE(package->random_groups[c].random_list, struct item_package_rand_entry, package->random_groups[c].random_qty);
+
+ //now we loop into the group's list
+ for(h = 0; h < group_qty; h++) {
+ struct item_package_rand_entry *entry = &itemdb->packages[i].random_groups[c].random_list[h];
+ unsigned short mid = 0, qty = 0, hours = 0, rate = 0;
+ unsigned char announce = 0, named = 0;
+ struct item_data *data;
+
+ //first 2 byte = item id
+ fread(&mid,sizeof(mid),1,file);
+ //next 2 byte = qty
+ fread(&qty,sizeof(qty),1,file);
+ //next 2 byte = rate
+ fread(&rate,sizeof(rate),1,file);
+ //next 2 byte = hours
+ fread(&hours,sizeof(hours),1,file);
+ //next 1 byte = announce (1:0)
+ fread(&announce,sizeof(announce),1,file);
+ //next 1 byte = named (1:0)
+ fread(&named,sizeof(announce),1,file);
+
+ if( !(data = itemdb->exists(mid)) )
+ ShowWarning("itemdb_read_packages: unknown item '%d' in package '%s'!\n",mid,itemdb_name(package->id));
+
+ entry->id = data ? data->nameid : 0;
+ entry->rate = rate;
+ entry->hours = hours;
+ entry->qty = qty;
+ entry->announce = announce ? 1 : 0;
+ entry->named = named ? 1 : 0;
+ }
+ }
+ }
+ }
+
+ fclose(file);
+
+ ShowStatus("Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", pcount, config_filename);
+
+ return true;
+}
void itemdb_read_packages(void) {
config_t item_packages_conf;
config_setting_t *itg = NULL, *it = NULL, *t = NULL;
@@ -715,8 +897,14 @@ void itemdb_read_packages(void) {
const char *config_filename = "db/pre-re/item_packages.conf"; // FIXME hardcoded name
#endif
const char *itname;
- int i = 0, count = 0, c = 0;
- unsigned int *must = NULL, *random = NULL;
+ int i = 0, count = 0, c = 0, highest_gcount = 0;
+ unsigned int *must = NULL, *random = NULL, *rgroup = NULL, **rgroups = NULL;
+ struct item_package_rand_entry **prev = NULL;
+
+ if( HCache->check(config_filename) ) {
+ if( itemdb->read_cached_packages(config_filename) )
+ return;
+ }
if (conf_read_file(&item_packages_conf, config_filename)) {
ShowError("can't read %s\n", config_filename);
@@ -725,12 +913,17 @@ void itemdb_read_packages(void) {
must = aMalloc( config_setting_length(item_packages_conf.root) * sizeof(unsigned int) );
random = aMalloc( config_setting_length(item_packages_conf.root) * sizeof(unsigned int) );
+ rgroup = aMalloc( config_setting_length(item_packages_conf.root) * sizeof(unsigned int) );
+ rgroups = aMalloc( config_setting_length(item_packages_conf.root) * sizeof(unsigned int *) );
+
for(i = 0; i < config_setting_length(item_packages_conf.root); i++) {
must[i] = 0;
random[i] = 0;
+ rgroup[i] = 0;
}
+ /* validate tree, drop poisonous fruits! */
i = 0;
while( (itg = config_setting_get_elem(item_packages_conf.root,i++)) ) {
const char *name = config_setting_name(itg);
@@ -744,40 +937,86 @@ void itemdb_read_packages(void) {
c = 0;
while( (it = config_setting_get_elem(itg,c++)) ) {
- if( ( t = config_setting_get_member(it, "Random")) && !config_setting_get_bool(t) )
+ int rval;
+ if( !( t = config_setting_get_member(it, "Random") ) || (rval = config_setting_get_int(t)) < 0 ) {
+ ShowWarning("itemdb_read_packages: invalid 'Random' value (%d) for item '%s' in package '%s', defaulting to must!\n",rval,config_setting_name(it),name);
+ config_setting_remove(it, config_setting_name(it));
+ --c;
+ continue;
+ }
+
+ if( rval == 0 )
must[ i - 1 ] += 1;
- else
+ else {
random[ i - 1 ] += 1;
+ if( rval > rgroup[i - 1] )
+ rgroup[i - 1] = rval;
+ if( rval > highest_gcount )
+ highest_gcount = rval;
+ }
}
-
+ }
+
+ CREATE(prev, struct item_package_rand_entry *, highest_gcount);
+ for(i = 0; i < highest_gcount; i++) {
+ prev[i] = NULL;
}
+ for(i = 0; i < config_setting_length(item_packages_conf.root); i++ ) {
+ rgroups[i] = aMalloc( rgroup[i] * sizeof(unsigned int) );
+ for( c = 0; c < rgroup[i]; c++ ) {
+ rgroups[i][c] = 0;
+ }
+ }
+
+ /* grab the known sizes */
+ i = 0;
+ while( (itg = config_setting_get_elem(item_packages_conf.root,i++)) ) {
+ c = 0;
+ while( (it = config_setting_get_elem(itg,c++)) ) {
+ int rval = 0;
+ if( ( t = config_setting_get_member(it, "Random")) && ( rval = config_setting_get_int(t) ) > 0 ) {
+ rgroups[i - 1][rval - 1] += 1;
+ }
+ }
+ }
+
CREATE(itemdb->packages, struct item_package, config_setting_length(item_packages_conf.root));
itemdb->package_count = (unsigned short)config_setting_length(item_packages_conf.root);
+ /* write */
i = 0;
while( (itg = config_setting_get_elem(item_packages_conf.root,i++)) ) {
struct item_data *data = itemdb->name2id(config_setting_name(itg));
- struct item_package_rand_entry *prev = NULL;
int r = 0, m = 0;
+ for(r = 0; r < highest_gcount; r++) {
+ prev[r] = NULL;
+ }
+ r = 0;
+
data->package = &itemdb->packages[count];
itemdb->packages[count].id = data->nameid;
- itemdb->packages[count].random_list = NULL;
+ itemdb->packages[count].random_groups = NULL;
itemdb->packages[count].must_items = NULL;
- itemdb->packages[count].random_qty = random[ i - 1 ];
+ itemdb->packages[count].random_qty = rgroup[ i - 1 ];
itemdb->packages[count].must_qty = must[ i - 1 ];
-
- if( itemdb->packages[count].random_qty )
- CREATE(itemdb->packages[count].random_list, struct item_package_rand_entry, itemdb->packages[count].random_qty);
+
+ if( itemdb->packages[count].random_qty ) {
+ CREATE(itemdb->packages[count].random_groups, struct item_package_rand_group, itemdb->packages[count].random_qty);
+ for( c = 0; c < itemdb->packages[count].random_qty; c++ ) {
+ CREATE(itemdb->packages[count].random_groups[c].random_list, struct item_package_rand_entry, rgroups[ i - 1 ][c]);
+ itemdb->packages[count].random_groups[c].random_qty = 0;
+ }
+ }
if( itemdb->packages[count].must_qty )
CREATE(itemdb->packages[count].must_items, struct item_package_must_entry, itemdb->packages[count].must_qty);
c = 0;
while( (it = config_setting_get_elem(itg,c++)) ) {
int icount = 1, expire = 0, rate = 10000;
- bool announce = false, named = false;
+ bool announce = false, named = false, gid = 0;
itname = config_setting_name(it);
@@ -792,7 +1031,7 @@ void itemdb_read_packages(void) {
if( ( t = config_setting_get_member(it, "Rate")) ) {
if( (rate = (unsigned short)config_setting_get_int(t)) > 10000 ) {
- ShowWarning("itemdb_read_packages: invalid rate (%d) for item '%s' in package '%s'!\n",itname,config_setting_name(itg));
+ ShowWarning("itemdb_read_packages: invalid rate (%d) for item '%s' in package '%s'!\n",rate,itname,config_setting_name(itg));
rate = 10000;
}
}
@@ -803,7 +1042,13 @@ void itemdb_read_packages(void) {
if( ( t = config_setting_get_member(it, "Named")) && config_setting_get_bool(t) )
named = true;
- if( ( t = config_setting_get_member(it, "Random")) && !config_setting_get_bool(t) ) {
+ if( !( t = config_setting_get_member(it, "Random") ) ) {
+ ShowWarning("itemdb_read_packages: missing 'Random' field for item '%s' in package '%s', defaulting to must!\n",itname,config_setting_name(itg));
+ gid = 0;
+ } else
+ gid = config_setting_get_int(t);
+
+ if( gid == 0 ) {
itemdb->packages[count].must_items[m].id = data ? data->nameid : 0;
itemdb->packages[count].must_items[m].qty = icount;
itemdb->packages[count].must_items[m].hours = expire;
@@ -811,41 +1056,58 @@ void itemdb_read_packages(void) {
itemdb->packages[count].must_items[m].named = named == true ? 1 : 0;
m++;
} else {
- if( prev )
- prev->next = &itemdb->packages[count].random_list[r];
+ int gidx = gid - 1;
+
+ r = itemdb->packages[count].random_groups[gidx].random_qty;
- itemdb->packages[count].random_list[r].id = data ? data->nameid : 0;
- itemdb->packages[count].random_list[r].qty = icount;
- if( (itemdb->packages[count].random_list[r].rate = rate) == 10000 ) {
- ShowWarning("itemdb_read_packages: item '%s' in '%s' has 100% drop rate!! set this item as 'Random: false' or other items won't drop!!!\n",itname,config_setting_name(itg));
+ if( prev[gidx] )
+ prev[gidx]->next = &itemdb->packages[count].random_groups[gidx].random_list[r];
+
+ itemdb->packages[count].random_groups[gidx].random_list[r].id = data ? data->nameid : 0;
+ itemdb->packages[count].random_groups[gidx].random_list[r].qty = icount;
+ if( (itemdb->packages[count].random_groups[gidx].random_list[r].rate = rate) == 10000 ) {
+ ShowWarning("itemdb_read_packages: item '%s' in '%s' has 100% drop rate!! set this item as 'Random: 0' or other items won't drop!!!\n",itname,config_setting_name(itg));
}
- itemdb->packages[count].random_list[r].hours = expire;
- itemdb->packages[count].random_list[r].announce = announce == true ? 1 : 0;
- itemdb->packages[count].random_list[r].named = named == true ? 1 : 0;
-
- prev = &itemdb->packages[count].random_list[r];
+ itemdb->packages[count].random_groups[gidx].random_list[r].hours = expire;
+ itemdb->packages[count].random_groups[gidx].random_list[r].announce = announce == true ? 1 : 0;
+ itemdb->packages[count].random_groups[gidx].random_list[r].named = named == true ? 1 : 0;
+ itemdb->packages[count].random_groups[gidx].random_qty += 1;
- r++;
+ prev[gidx] = &itemdb->packages[count].random_groups[gidx].random_list[r];
}
}
- if( prev )
- prev->next = &itemdb->packages[count].random_list[0];
-
- if( itemdb->packages[count].random_qty == 1 ) {
- //item packages dont stop looping until something comes out of them, so if you have only one item in it the drop is guaranteed.
- ShowWarning("itemdb_read_packages: '%s' has only 1 random option, drop rate will be 100%!\n",itemdb_name(itemdb->packages[count].id));
- itemdb->packages[count].random_list[0].rate = 10000;
+ for(r = 0; r < highest_gcount; r++) {
+ if( prev[r] )
+ prev[r]->next = &itemdb->packages[count].random_groups[r].random_list[0];
}
+ for( r = 0; r < itemdb->packages[count].random_qty; r++ ) {
+ if( itemdb->packages[count].random_groups[r].random_qty == 1 ) {
+ //item packages dont stop looping until something comes out of them, so if you have only one item in it the drop is guaranteed.
+ ShowWarning("itemdb_read_packages: in '%s' 'Random: %d' group has only 1 random option, drop rate will be 100%!\n",itemdb_name(itemdb->packages[count].id),r+1);
+ itemdb->packages[count].random_groups[r].random_list[0].rate = 10000;
+ }
+ }
+
count++;
}
- config_destroy(&item_packages_conf);
aFree(must);
aFree(random);
+ for(i = 0; i < config_setting_length(item_packages_conf.root); i++ ) {
+ aFree(rgroups[i]);
+ }
+ aFree(rgroups);
+ aFree(rgroup);
+ aFree(prev);
+
+ config_destroy(&item_packages_conf);
+
+ if( HCache->enabled )
+ itemdb->write_cached_packages(config_filename);
ShowStatus("Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, config_filename);
}
@@ -1648,7 +1910,7 @@ static void itemdb_read(void) {
itemdb->read_groups();
itemdb->read_chains();
itemdb->read_packages();
-
+
sv->readdb(iMap->db_path, "item_avail.txt", ',', 2, 2, -1, &itemdb_read_itemavail);
sv->readdb(iMap->db_path, DBPATH"item_trade.txt", ',', 3, 3, -1, &itemdb_read_itemtrade);
sv->readdb(iMap->db_path, "item_delay.txt", ',', 2, 2, -1, &itemdb_read_itemdelay);
@@ -1745,8 +2007,11 @@ void itemdb_reload(void) {
itemdb->chain_count = 0;
for( i = 0; i < itemdb->package_count; i++ ) {
- if( itemdb->packages[i].random_list )
- aFree(itemdb->packages[i].random_list);
+ int c;
+ for( c = 0; c < itemdb->packages[i].random_qty; c++ )
+ aFree(itemdb->packages[i].random_groups[c].random_list);
+ if( itemdb->packages[i].random_groups )
+ aFree(itemdb->packages[i].random_groups);
if( itemdb->packages[i].must_items )
aFree(itemdb->packages[i].must_items);
}
@@ -1846,8 +2111,11 @@ void do_final_itemdb(void) {
aFree(itemdb->chains);
for( i = 0; i < itemdb->package_count; i++ ) {
- if( itemdb->packages[i].random_list )
- aFree(itemdb->packages[i].random_list);
+ int c;
+ for( c = 0; c < itemdb->packages[i].random_qty; c++ )
+ aFree(itemdb->packages[i].random_groups[c].random_list);
+ if( itemdb->packages[i].random_groups )
+ aFree(itemdb->packages[i].random_groups);
if( itemdb->packages[i].must_items )
aFree(itemdb->packages[i].must_items);
}
@@ -1892,6 +2160,9 @@ void itemdb_defaults(void) {
itemdb->read_chains = itemdb_read_chains;
itemdb->read_packages = itemdb_read_packages;
/* */
+ itemdb->write_cached_packages = itemdb_write_cached_packages;
+ itemdb->read_cached_packages = itemdb_read_cached_packages;
+ /* */
itemdb->search_name = itemdb_searchname;
itemdb->search_name_array = itemdb_searchname_array;
itemdb->load = itemdb_load;
diff --git a/src/map/itemdb.h b/src/map/itemdb.h
index db1330344..93bb8e0b9 100644
--- a/src/map/itemdb.h
+++ b/src/map/itemdb.h
@@ -203,9 +203,14 @@ struct item_package_must_entry {
unsigned int named : 1;
};
+struct item_package_rand_group {
+ struct item_package_rand_entry *random_list;
+ unsigned short random_qty;
+};
+
struct item_package {
unsigned short id;
- struct item_package_rand_entry *random_list;
+ struct item_package_rand_group *random_groups;
struct item_package_must_entry *must_items;
unsigned short random_qty;
unsigned short must_qty;
@@ -292,6 +297,9 @@ struct itemdb_interface {
void (*read_chains) (void);
void (*read_packages) (void);
/* */
+ void (*write_cached_packages) (const char *config_filename);
+ bool (*read_cached_packages) (const char *config_filename);
+ /* */
struct item_data* (*name2id) (const char *str);
struct item_data* (*search_name) (const char *name);
int (*search_name_array) (struct item_data** data, int size, const char *str);
diff --git a/src/map/mob.c b/src/map/mob.c
index 7482a9d56..71c81749a 100644
--- a/src/map/mob.c
+++ b/src/map/mob.c
@@ -3868,13 +3868,12 @@ static bool mob_parse_dbrow(char** str)
id->mob[k].id = class_;
}
}
-
// Finally insert monster's data into the database.
if (mob_db_data[class_] == NULL)
- mob_db_data[class_] = (struct mob_db*)aCalloc(1, sizeof(struct mob_db));
+ mob_db_data[class_] = (struct mob_db*)aMalloc(sizeof(struct mob_db));
else
//Copy over spawn data
- memcpy(&db->spawn, mob_db_data[class_]->spawn, sizeof(db->spawn));
+ memcpy(&db->spawn, mob_db_data[class_]->spawn, sizeof(db->spawn));
memcpy(mob_db_data[class_], db, sizeof(struct mob_db));
return true;
@@ -4608,10 +4607,10 @@ static void mob_load(void)
void mob_reload(void) {
int i;
-
+
//Mob skills need to be cleared before re-reading them. [Skotlex]
for (i = 0; i < MAX_MOB_DB; i++)
- if (mob_db_data[i]) {
+ if (mob_db_data[i] && !mob_is_clone(i)) {
memset(&mob_db_data[i]->skill,0,sizeof(mob_db_data[i]->skill));
mob_db_data[i]->maxskill=0;
}
diff --git a/src/map/packets_struct.h b/src/map/packets_struct.h
index 8e7506686..f6e6a8a3f 100644
--- a/src/map/packets_struct.h
+++ b/src/map/packets_struct.h
@@ -112,7 +112,7 @@ enum packet_headers {
struct packet_authok {
short PacketType;
unsigned int startTime;
- char PosDir[3];
+ unsigned char PosDir[3];
unsigned char xSize;
unsigned char ySize;
#if PACKETVER >= 20080102
@@ -217,7 +217,7 @@ struct packet_spawn_unit {
#endif
bool isPKModeON;
unsigned char sex;
- char PosDir[3];
+ unsigned char PosDir[3];
unsigned char xSize;
unsigned char ySize;
short clevel;
@@ -276,7 +276,7 @@ struct packet_unit_walking {
#endif
bool isPKModeON;
unsigned char sex;
- char MoveData[6];
+ unsigned char MoveData[6];
unsigned char xSize;
unsigned char ySize;
short clevel;
@@ -334,7 +334,7 @@ struct packet_idle_unit {
#endif
bool isPKModeON;
unsigned char sex;
- char PosDir[3];
+ unsigned char PosDir[3];
unsigned char xSize;
unsigned char ySize;
unsigned char state;
diff --git a/src/map/script.c b/src/map/script.c
index 3ba8ea9fc..19e6457bd 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -4344,8 +4344,10 @@ BUILDIN(callfunc)
{
const char* name = reference_getname(data);
if( name[0] == '.' ) {
- ref = (struct DBMap**)aCalloc(sizeof(struct DBMap*), 1);
- ref[0] = (name[1] == '@' ? st->stack->var_function : st->script->script_vars);
+ if( !ref ) {
+ ref = (struct DBMap**)aCalloc(sizeof(struct DBMap*), 1);
+ ref[0] = (name[1] == '@' ? st->stack->var_function : st->script->script_vars);
+ }
data->ref = ref;
}
}
diff --git a/src/map/skill.c b/src/map/skill.c
index b8ac90225..da35bbbd3 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -173,7 +173,7 @@ const char* skill_get_desc( uint16 skill_id ) {
}
// out of bounds error checking [celest]
-void skill_chk(int16* skill_id) {
+void skill_chk(uint16* skill_id) {
*skill_id = skill->get_index(*skill_id); // checks/adjusts id
}
@@ -8755,7 +8755,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
sc_start2(bl,type,100,skill_lv,sc->data[type]->val2,skill->get_time(skill_id,skill_lv));
}
} else if( sd ) {
- short lv = (short)skill_lv;
+ uint16 lv = skill_lv;
int count = skill->check_pc_partner(sd,skill_id,&lv,skill->get_splash(skill_id,skill_lv),1);
if( sc_start2(bl,type,100,skill_lv,count,skill->get_time(skill_id,skill_lv)) )
party_foreachsamemap(skill->area_sub,sd,skill->get_splash(skill_id,skill_lv),src,skill_id,skill_lv,tick,flag|BCT_PARTY|1,skill->castend_nodamage_id);
@@ -8770,7 +8770,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
if( flag&1 ) {
sc_start2(bl,type,100,skill_lv,skill_area_temp[0],skill->get_time(skill_id,skill_lv));
} else { // These affect to all targets arround the caster.
- short lv = (short)skill_lv;
+ uint16 lv = skill_lv;
skill_area_temp[0] = (sd) ? skill->check_pc_partner(sd,skill_id,&lv,skill->get_splash(skill_id,skill_lv),1) : 50; // 50% chance in non BL_PC (clones).
iMap->foreachinrange(skill->area_sub, src, skill->get_splash(skill_id,skill_lv),BL_PC, src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1, skill->castend_nodamage_id);
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
@@ -12257,7 +12257,7 @@ int skill_check_condition_char_sub (struct block_list *bl, va_list ap) {
/*==========================================
* Checks and stores partners for ensemble skills [Skotlex]
*------------------------------------------*/
-int skill_check_pc_partner (struct map_session_data *sd, uint16 skill_id, short* skill_lv, int range, int cast_flag) {
+int skill_check_pc_partner (struct map_session_data *sd, uint16 skill_id, uint16* skill_lv, int range, int cast_flag) {
static int c=0;
static int p_sd[2] = { 0, 0 };
int i;
diff --git a/src/map/skill.h b/src/map/skill.h
index a2eed585f..cff2fc0cf 100644
--- a/src/map/skill.h
+++ b/src/map/skill.h
@@ -1792,7 +1792,7 @@ struct skill_interface {
const char* (*get_name) ( uint16 skill_id );
const char* (*get_desc) ( uint16 skill_id );
/* check */
- void (*chk) (int16* skill_id);
+ void (*chk) (uint16* skill_id);
/* whether its CAST_GROUND, CAST_DAMAGE or CAST_NODAMAGE */
int (*get_casttype) (uint16 skill_id);
int (*get_casttype2) (uint16 index);
@@ -1828,7 +1828,7 @@ struct skill_interface {
int (*check_condition_castend) (struct map_session_data *sd, uint16 skill_id, uint16 skill_lv);
int (*consume_requirement) (struct map_session_data *sd, uint16 skill_id, uint16 skill_lv, short type);
struct skill_condition (*get_requirement) (struct map_session_data *sd, uint16 skill_id, uint16 skill_lv);
- int (*check_pc_partner) (struct map_session_data *sd, uint16 skill_id, short* skill_lv, int range, int cast_flag);
+ int (*check_pc_partner) (struct map_session_data *sd, uint16 skill_id, uint16* skill_lv, int range, int cast_flag);
int (*unit_move) (struct block_list *bl,unsigned int tick,int flag);
int (*unit_onleft) (uint16 skill_id, struct block_list *bl,unsigned int tick);
int (*unit_onout) (struct skill_unit *src, struct block_list *bl, unsigned int tick);