int checkweight_sub(struct map_session_data *sd, int nameid, int amount, int slots, int amount2)
{
short amount2 = 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) ){// stackable
amount2++;
if( slots < amount2 )
return -1;
}
else {// non-stackable
amount2 += amount;
if( slots < amount2 )
return -1;
}
break;
case CHKADDITEM_OVERAMOUNT:
return -1;
} //end switch
return amount2;
}
/*==========================================
* 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)
{
int nameid, amount, slots, amount2=0;
unsigned int weight=0, i, nbargs;
TBL_PC *sd = script_rid2sd(st);
nullpo_retr(1,sd);
if( ( sd = script_rid2sd(st) ) == NULL )
return 0;
if(!strcmp(script_getfuncname(st),"checkweight")) {
struct item_data* id = NULL;
struct script_data* data;
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;
}
slots = pc_inventoryblank(sd); //nb of empty slot
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 = id->nameid;
amount = script_getnum(st,i+1);
if(amount < 0 ){
ShowError("buildin_checkweight: Invalid amount '%d'.\n", amount);
amount2 = -1;
break;
}
weight += itemdb_weight(nameid)*amount;
if( weight + sd->weight > sd->max_weight ) {
amount2 = -1;
break;
}
if(amount2 = checkweight_sub(sd,nameid,amount,slots,amount2) == -1)
break;
}
} else {
//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
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);
amount2 = -1;
}
slots = pc_inventoryblank(sd); //nb of empty slot
for(i=0; i<nb_it; i++) {
nameid = (int32)__64BPRTSIZE(get_val2(st,reference_uid(id_it,idx_it+i),reference_getref(data_it)));
script_removetop(st, -1, 0);
amount = (int32)__64BPRTSIZE(get_val2(st,reference_uid(id_nb,idx_nb+i),reference_getref(data_nb)));
script_removetop(st, -1, 0);
if(amount2 == -1)
continue; //cpntonie to depop rest
if(itemdb_exists(nameid) == NULL ){
ShowError("buildin_checkweight2: Invalid item '%d'.\n", nameid);
amount2 = -1;
continue;
}
if(amount < 0 ){
ShowError("buildin_checkweight2: Invalid amount '%d'.\n", amount);
amount2 = -1;
continue;
}
weight += itemdb_weight(nameid)*amount;
if( weight + sd->weight > sd->max_weight ) {
amount2 = -1;
continue;
}
amount2 = checkweight_sub(sd,nameid,amount,slots,amount2);
} //end loop DO NOT break it prematurly we need to depop all stack
}
(amount2 == -1)?script_pushint(st,0):script_pushint(st,1);
return 0;
}