diff options
Diffstat (limited to 'src/map')
-rw-r--r-- | src/map/battle.c | 6 | ||||
-rw-r--r-- | src/map/battleground.h | 1 | ||||
-rw-r--r-- | src/map/instance.c | 6 | ||||
-rw-r--r-- | src/map/itemdb.c | 425 | ||||
-rw-r--r-- | src/map/itemdb.h | 10 | ||||
-rw-r--r-- | src/map/mob.c | 9 | ||||
-rw-r--r-- | src/map/packets_struct.h | 8 | ||||
-rw-r--r-- | src/map/script.c | 6 | ||||
-rw-r--r-- | src/map/skill.c | 8 | ||||
-rw-r--r-- | src/map/skill.h | 4 |
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); |