int chekweight_sub(TBL_PC *sd,int nbargs,uint16 *eitemid, uint16 *eamount){
struct item_data* id = NULL;
uint16 nameid,amount,amount2=0,slots,weight,i;
slots = pc_inventoryblank(sd); //nb of empty slot
for(i=2; i<nbargs; i++){
id = itemdb_exists(eitemid[i]);
if( id == NULL ) {
ShowError("buildin_checkweight: Invalid item '%d'.\n", eitemid[i]);
return 0;
}
nameid = id->nameid;
amount = eamount[i];
if( amount < 1 ) {
ShowError("buildin_checkweight: Invalid amount '%d'.\n", eamount[i]);
return 0;
}
weight += (id->weight)*amount; //total weight for all chk
if( weight + sd->weight > sd->max_weight ){// too heavy
return 0;
}
switch( pc_checkadditem(sd, nameid, amount) ){
case CHKADDITEM_EXIST:
// item is already in inventory, but there is still space for the requested amount
break;
case CHKADDITEM_NEW:
if( itemdb_isstackable(nameid) ) amount2++; // stackable
else amount2 += amount; // non-stackable
if( slots < amount2)
return 0;
break;
case CHKADDITEM_OVERAMOUNT:
return 0;
}
}
return 1;
}
/*==========================================
* Check if item with this amount can fit in inventory
* Checking : weight, stack amount >32k, slots amount >(MAX_INVENTORY)
* Return
* 0 : fail
* 1 : success (npc side only)
*------------------------------------------*/
BUILDIN_FUNC(checkweight){
struct map_session_data* sd;
struct script_data* data;
struct item_data* id = NULL;
uint16 nameid[128], amount[128], nbargs,i;
if( ( sd = script_rid2sd(st) ) == NULL ){
return 0;
}
nbargs = script_lastdata(st)+1;
if(nbargs%2){
ShowError("buildin_checkweight: Invalid nb of args should be a multiple of 2.\n");
script_pushint(st,0);
return 1;
}
for(i=2; i<nbargs; i=i+2){
data = script_getdata(st,i);
get_val(st, data); // convert into value in case of a variable
if( data_isstring(data) ) // item name
id = itemdb_searchname(conv_str(st, data));
else // item id
id = itemdb_exists(conv_num(st, data));
if( id == NULL ) {
ShowError("buildin_checkweight: Invalid item '%s'.\n", script_getstr(st,i)); // returns string, regardless of what it was
script_pushint(st,0);
return 1;
}
nameid[i] = id->nameid;
amount[i] = script_getnum(st,i+1);
}
script_pushint(st,chekweight_sub(sd,nbargs-2,nameid,amount));
return 0;
}
BUILDIN_FUNC(checkweight2){
//variable sub checkweight
uint16 nameid[128], amount[128];
int fail,i;
//variable for array parsing
struct script_data* data_it;
struct script_data* data_nb;
const char* name_it;
const char* name_nb;
int32 id_it, id_nb;
int32 idx_it, idx_nb;
int nb_it, nb_nb; //array size
TBL_PC *sd = script_rid2sd(st);
nullpo_retr(1,sd);
data_it = script_getdata(st, 2);
data_nb = script_getdata(st, 3);
if( !data_isreference(data_it) || !data_isreference(data_nb))
{
ShowError("script:checkweight2: parameter not a variable\n");
script_pushint(st,0);
return 1;// not a variable
}
id_it = reference_getid(data_it);
id_nb = reference_getid(data_nb);
idx_it = reference_getindex(data_it);
idx_nb = reference_getindex(data_nb);
name_it = reference_getname(data_it);
name_nb = reference_getname(data_nb);
if( not_array_variable(*name_it) || not_array_variable(*name_nb))
{
ShowError("script:checkweight2: illegal scope\n");
script_pushint(st,0);
return 1;// not supported
}
if(is_string_variable(name_it) || is_string_variable(name_nb)){
ShowError("script:checkweight2: illegal type, need int\n");
script_pushint(st,0);
return 1;// not supported
}
nb_it = getarraysize(st, id_it, idx_it, 0, reference_getref(data_it));
nb_nb = getarraysize(st, id_nb, idx_nb, 0, reference_getref(data_nb));
if(nb_it != nb_nb){
ShowError("Size mistmatch: nb_it=%d, nb_nb=%d\n",nb_it,nb_nb);
fail = 1;
}
for(i=0; i<nb_it; i++){
nameid[i] = (int32)__64BPRTSIZE(get_val2(st,reference_uid(id_it,idx_it+i),reference_getref(data_it)));
script_removetop(st, -1, 0);
amount[i] = (int32)__64BPRTSIZE(get_val2(st,reference_uid(id_nb,idx_nb+i),reference_getref(data_nb)));
script_removetop(st, -1, 0);
} //end loop DO NOT break it prematurly we need to depop all stack
if(fail) script_pushint(st,0);
else script_pushint(st,chekweight_sub(sd,nb_it,nameid,amount)); //push result of sub to script
return 0;
}