Jump to content
  • 0
Sign in to follow this  
Tranquility

Failing to debug an error

Question

Greetings,

 

Upon converting some of my scripts I noticed Herc didn't have a few scriptcommands that rA had. No big deal since we got plugins here!

Anyhow, that's what I thought until I bumped into getting stuck with the follow plugin that I'm attempting to create:

 

 

 

#include <stdio.h>#include <string.h>#include <stdlib.h>#include "common/HPMi.h"#include "map/pc.h"#include "common/HPMDataCheck.h" // should always be the last file included! (if you don't make it last, it'll intentionally break compile time)HPExport struct hplugin_info pinfo = {    "storagecountitem", // Plugin name    SERVER_TYPE_MAP,// Which server types this plugin works with?    "0.1",            // Plugin version    HPM_VERSION,    // HPM Version (don't change, macro is automatically updated)};/*========================================== * storagecountitem(nameID,{accountID}) * returns number of items that meet the conditions *==========================================*/BUILDIN(storagecountitem) {    int nameid, i;    int count = 0;    struct item_data* id = NULL;    TBL_PC* sd = script->rid2sd(st);    if( !sd )        return true;    if( script_isstringtype(st, 2) ) {        // item name        id = itemdb->search_name(script_getstr(st, 2));    } else {        // item id        id = itemdb->exists(script_getnum(st, 2));    }    if( id == NULL ) {        ShowError("buildin_storagecountitem: Invalid item '%s'.n", script_getstr(st,2));  // returns string, regardless of what it was        script_pushint(st,0);        return false;    }    nameid = id->nameid;    for(i = 0; i < MAX_STORAGE; i++)        if(sd->status.storage.items[i].nameid == nameid)            count += sd->status.storage.items[i].amount;    script_pushint(st,count);    return true;}/*========================================== * storagecountitem2(nameID,Identified,Refine,Attribute,Card0,Card1,Card2,Card3) * returns number of items that meet the conditions *==========================================*/BUILDIN(storagecountitem2) {    int nameid, iden, ref, attr, c0, c1, c2, c3;    int count = 0;    int i;    struct item_data* id = NULL;    TBL_PC* sd = script->rid2sd(st);    if (!sd) {        return true;    }    if( script_isstringtype(st, 2) ) { //item name        id = itemdb->search_name(script_getstr(st, 2));    } else { //item id        id = itemdb->exists(script_getnum(st, 2));    }    if( id == NULL ) {        ShowError("buildin_storagecountitem2: Invalid item '%s'.n", script_getstr(st,2));  // returns string, regardless of what it was        script_pushint(st,0);        return false;    }    nameid = id->nameid;    iden = script_getnum(st,3);    ref  = script_getnum(st,4);    attr = script_getnum(st,5);    c0 = (short)script_getnum(st,6);    c1 = (short)script_getnum(st,7);    c2 = (short)script_getnum(st,8);    c3 = (short)script_getnum(st,9);    for(i = 0; i < MAX_STORAGE; i++) {        if(sd->status.storage.items[i].nameid > 0 && sd->status.storage.items[i].amount > 0 &&           sd->status.storage.items[i].nameid == nameid && sd->status.storage.items[i].identify == iden &&           sd->status.storage.items[i].refine == ref && sd->status.storage.items[i].attribute == attr &&           sd->status.storage.items[i].card[0] == c0 && sd->status.storage.items[i].card[1] == c1 &&           sd->status.storage.items[i].card[2] == c2 && sd->status.storage.items[i].card[3] == c3           )           count += sd->status.storage.items[i].amount;    }    script_pushint(st,count);    return true;}/* Server Startup */HPExport void plugin_init (void) {    addScriptCommand( "storagecountitem", "v", storagecountitem);    addScriptCommand( "storagecountitem2", "viiiiiii", storagecountitem2);}

 

 

Fixed the above script, added it incase people are interested. Will 'officially' release it in the plugin release when the below script is finished/working as well.

 

The next script that had to be made was the deletion of items in the storage. Thus storagedelitem came here to ruin my night, the follow is what I got, but doesn't work for one milimeter:

 

 

#include <stdio.h>#include <string.h>#include <stdlib.h>#include "common/HPMi.h"#include "common/utils.c"#include "map/intif.h"#include "map/pc.h"#include "map/storage.c"#include "common/HPMDataCheck.h" // should always be the last file included! (if you don't make it last, it'll intentionally break compile time)HPExport struct hplugin_info pinfo = {	"storagedelitem", // Plugin name	SERVER_TYPE_MAP,// Which server types this plugin works with?	"0.1",			// Plugin version	HPM_VERSION,	// HPM Version (don't change, macro is automatically updated)};/// Counts / deletes the current item given by idx./// Used by buildin_delitem_search/// Relies on all input data being already fully valid.void buildin_storage_delitem_delete(struct map_session_data* sd, int idx, int* amount, bool delete_items){	int delamount;	struct item* inv = &sd->status.storage.items[idx];	delamount = ( amount[0] < inv->amount ) ? amount[0] : inv->amount;	if( delete_items )	{		if( itemdb_type(inv->nameid) == IT_PETEGG && inv->card[0] == CARD0_PET )		{// delete associated pet			intif->delete_petdata(MakeDWord(inv->card[1], inv->card[2]));		}		storage_delitem(sd, idx, delamount);	}	amount[0]-= delamount;}/// Searches for item(s) and checks, if there is enough of them./// Used by delitem and delitem2/// Relies on all input data being already fully valid./// @param exact_match will also match item attributes and cards, not just name id/// @return true when all items could be deleted, false when there were not enough items to deletebool buildin_storage_delitem_search(struct map_session_data* sd, struct item* it, bool exact_match){	bool delete_items = false;	int i, amount, size;	struct item* inv;	// prefer always non-equipped items	it->equip = 0;	// when searching for nameid only, prefer additionally	if (!exact_match) {		// non-refined items		it->refine = 0;		// card-less items		memset(it->card, 0, sizeof(it->card));	}	size = MAX_STORAGE;	for (; {		int important = 0;		amount = it->amount;		// 1st pass -- less important items / exact match		for (i = 0; amount && i < size; i++) {			inv = &sd->status.storage.items[i];			if (!inv->nameid || !&inv || inv->nameid != it->nameid) {				// wrong/invalid item				continue;			}			if (inv->equip != it->equip || inv->refine != it->refine) {				// not matching attributes				important++;				continue;			}			if (exact_match) {				if (inv->identify != it->identify || inv->attribute != it->attribute || memcmp(inv->card, it->card, sizeof(inv->card))) {					// not matching exact attributes					continue;				}			} else {				if (itemdb_type(inv->nameid) == IT_PETEGG) {					if (inv->card[0] == CARD0_PET && intif->CheckForCharServer()) {						// pet which cannot be deleted						continue;					}				} else if (memcmp(inv->card, it->card, sizeof(inv->card))) {					// named/carded item					important++;					continue;				}			}			// count / delete item			buildin_storage_delitem_delete(sd, i, &amount, delete_items);		}		// 2nd pass -- any matching item		if (amount == 0 || important == 0) {			// either everything was already consumed or no items were skipped			;		} else {			for (i = 0; amount && i < size; i++) {				inv = &sd->status.storage.items[i];				if (!inv->nameid || !&inv || inv->nameid != it->nameid) {					// wrong/invalid item					continue;				}				if (itemdb_type(inv->nameid) == IT_PETEGG && inv->card[0] == CARD0_PET && intif->CheckForCharServer()) {					// pet which cannot be deleted					continue;				}				if (exact_match) {					if (inv->refine != it->refine || inv->identify != it->identify || inv->attribute != it->attribute					 || memcmp(inv->card, it->card, sizeof(inv->card))) {						// not matching attributes						continue;					}				}				// count / delete item				buildin_storage_delitem_delete(sd, i, &amount, delete_items);			}		}		if (amount) {			// not enough items			return false;		} else if(delete_items) {			// we are done with the work			return true;		} else {			// get rid of the items now			delete_items = true;		}	}}/*========================================== * delitem <item id>,<amount>{,<account id>} * delitem "<item name>",<amount>{,<account id>} * Deletes items from the target/attached player. *==========================================*/BUILDIN(storagedelitem) {	TBL_PC *sd;	struct item it;	if (script_hasdata(st,4)) {		int account_id = script_getnum(st,4);		sd = map->id2sd(account_id); // <account id>		if (sd == NULL) {			ShowError("script:storagedelitem: player not found (AID=%d).n", account_id);			st->state = END;			return false;		}	} else {		sd = script->rid2sd(st);// attached player		if (sd == NULL)			return true;	}	memset(&it, 0, sizeof(it));	if (script_isstringtype(st, 2)) {		const char* item_name = script_getstr(st, 2);		struct item_data* id = itemdb->search_name(item_name);		if (id == NULL) {			ShowError("script:storagedelitem: unknown item "%s".n", item_name);			st->state = END;			return false;		}		it.nameid = id->nameid;// "<item name>"	} else {		it.nameid = script_getnum(st, 2);// <item id>		if (!itemdb->exists(it.nameid)) {			ShowError("script:storagedelitem: unknown item "%d".n", it.nameid);			st->state = END;			return false;		}	}	it.amount=script_getnum(st,3);	if( it.amount <= 0 )		return true;// nothing to do	if( buildin_storage_delitem_search(sd, &it, false) )	{// success		return true;	}	ShowError("script:storagedelitem: failed to delete %d items (AID=%d item_id=%d).n", it.amount, sd->status.account_id, it.nameid);	st->state = END;	clif->scriptclose(sd, st->oid);	return false;}/* Server Startup */HPExport void plugin_init (void) {	addScriptCommand( "storagedelitem", "vi?", storagedelitem);}

 

 

The original delitem script is used as reference and is as following:

 

 

/// Counts / deletes the current item given by idx./// Used by buildin_delitem_search/// Relies on all input data being already fully valid.void buildin_delitem_delete(struct map_session_data* sd, int idx, int* amount, bool delete_items){	int delamount;	struct item* inv = &sd->status.inventory[idx];	delamount = ( amount[0] < inv->amount ) ? amount[0] : inv->amount;	if( delete_items )	{		if( sd->inventory_data[idx]->type == IT_PETEGG && inv->card[0] == CARD0_PET )		{// delete associated pet			intif->delete_petdata(MakeDWord(inv->card[1], inv->card[2]));		}		pc->delitem(sd, idx, delamount, 0, DELITEM_NORMAL, LOG_TYPE_SCRIPT);	}	amount[0]-= delamount;}/// Searches for item(s) and checks, if there is enough of them./// Used by delitem and delitem2/// Relies on all input data being already fully valid./// @param exact_match will also match item attributes and cards, not just name id/// @return true when all items could be deleted, false when there were not enough items to deletebool buildin_delitem_search(struct map_session_data* sd, struct item* it, bool exact_match){	bool delete_items = false;	int i, amount;	struct item* inv;	// prefer always non-equipped items	it->equip = 0;	// when searching for nameid only, prefer additionally	if (!exact_match) {		// non-refined items		it->refine = 0;		// card-less items		memset(it->card, 0, sizeof(it->card));	}	for (; {		int important = 0;		amount = it->amount;		// 1st pass -- less important items / exact match		for (i = 0; amount && i < ARRAYLENGTH(sd->status.inventory); i++) {			inv = &sd->status.inventory[i];			if (!inv->nameid || !sd->inventory_data[i] || inv->nameid != it->nameid) {				// wrong/invalid item				continue;			}			if (inv->equip != it->equip || inv->refine != it->refine) {				// not matching attributes				important++;				continue;			}			if (exact_match) {				if (inv->identify != it->identify || inv->attribute != it->attribute || memcmp(inv->card, it->card, sizeof(inv->card))) {					// not matching exact attributes					continue;				}			} else {				if (sd->inventory_data[i]->type == IT_PETEGG) {					if (inv->card[0] == CARD0_PET && intif->CheckForCharServer()) {						// pet which cannot be deleted						continue;					}				} else if (memcmp(inv->card, it->card, sizeof(inv->card))) {					// named/carded item					important++;					continue;				}			}			// count / delete item			script->buildin_delitem_delete(sd, i, &amount, delete_items);		}		// 2nd pass -- any matching item		if (amount == 0 || important == 0) {			// either everything was already consumed or no items were skipped			;		} else {			for (i = 0; amount && i < ARRAYLENGTH(sd->status.inventory); i++) {				inv = &sd->status.inventory[i];				if (!inv->nameid || !sd->inventory_data[i] || inv->nameid != it->nameid) {					// wrong/invalid item					continue;				}				if (sd->inventory_data[i]->type == IT_PETEGG && inv->card[0] == CARD0_PET && intif->CheckForCharServer()) {					// pet which cannot be deleted					continue;				}				if (exact_match) {					if (inv->refine != it->refine || inv->identify != it->identify || inv->attribute != it->attribute					 || memcmp(inv->card, it->card, sizeof(inv->card))) {						// not matching attributes						continue;					}				}				// count / delete item				script->buildin_delitem_delete(sd, i, &amount, delete_items);			}		}		if (amount) {			// not enough items			return false;		} else if(delete_items) {			// we are done with the work			return true;		} else {			// get rid of the items now			delete_items = true;		}	}}/// Deletes items from the target/attached player./// Prioritizes ordinary items.////// delitem <item id>,<amount>{,<account id>}/// delitem "<item name>",<amount>{,<account id>}BUILDIN(delitem) {	TBL_PC *sd;	struct item it;	if (script_hasdata(st,4)) {		int account_id = script_getnum(st,4);		sd = map->id2sd(account_id); // <account id>		if (sd == NULL) {			ShowError("script:delitem: player not found (AID=%d).n", account_id);			st->state = END;			return false;		}	} else {		sd = script->rid2sd(st);// attached player		if (sd == NULL)			return true;	}	memset(&it, 0, sizeof(it));	if (script_isstringtype(st, 2)) {		const char* item_name = script_getstr(st, 2);		struct item_data* id = itemdb->search_name(item_name);		if (id == NULL) {			ShowError("script:delitem: unknown item "%s".n", item_name);			st->state = END;			return false;		}		it.nameid = id->nameid;// "<item name>"	} else {		it.nameid = script_getnum(st, 2);// <item id>		if (!itemdb->exists(it.nameid)) {			ShowError("script:delitem: unknown item "%d".n", it.nameid);			st->state = END;			return false;		}	}	it.amount=script_getnum(st,3);	if( it.amount <= 0 )		return true;// nothing to do	if( script->buildin_delitem_search(sd, &it, false) )	{// success		return true;	}	ShowError("script:delitem: failed to delete %d items (AID=%d item_id=%d).n", it.amount, sd->status.account_id, it.nameid);	st->state = END;	clif->scriptclose(sd, st->oid);	return false;}

 

 

 And what I think is needed is the following part from storage.c:

 

 

/*========================================== * Internal del-item function *------------------------------------------*/int storage_delitem(struct map_session_data* sd, int n, int amount){	if( sd->status.storage.items[n].nameid == 0 || sd->status.storage.items[n].amount < amount )		return 1;	sd->status.storage.items[n].amount -= amount;	if( sd->status.storage.items[n].amount == 0 )	{		memset(&sd->status.storage.items[n],0,sizeof(sd->status.storage.items[0]));		sd->status.storage.storage_amount--;		if( sd->state.storage_flag == STORAGE_FLAG_NORMAL )			clif->updatestorageamount(sd, sd->status.storage.storage_amount, MAX_STORAGE);	}	if( sd->state.storage_flag == STORAGE_FLAG_NORMAL )		clif->storageitemremoved(sd,n,amount);	return 0;}

 

 

Where did I mess up this time? Where didn't I mess up you're probably thinking by now..

Edited by Tranquility

Share this post


Link to post
Share on other sites

2 answers to this question

Recommended Posts

  • 0

Another question then, how am I able to call  *delitem from storage.h?
It's located within in the storage_interface struct and I think I need to use that for the storagedelitem script I'm writing. However, when including storage.c I'm able to do it, but it'll throw tons of errors.
Struggling with an undeclared MakeDWord when processing "buildin_delitem_delete".

intif->delete_petdata(MakeDWord(inv->card[1], inv->card[2])); 

That line specifically, anyone able to help out there?
 
Latest modification for the storagedelitem script but still stuck on the MakeDWord part.

 

Fixed, had to declare MakeDWord again:

 

//Declaration of MakeDWord to allow the uint32 MakeDWord(uint16 word0, uint16 word1) {	return		( (uint32)(word0        ) )|		( (uint32)(word1 << 0x10) );}
Edited by Tranquility

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
Sign in to follow this  

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.