summaryrefslogtreecommitdiff
path: root/src/map/script.c
diff options
context:
space:
mode:
authorshennetsind <ind@henn.et>2013-06-23 16:35:42 -0300
committershennetsind <ind@henn.et>2013-06-23 16:35:42 -0300
commitfcba8a2161a392369db99ab9a516a24470c54796 (patch)
treedc223cbd60e53b57eee6ff5e03a3a6bfea76e516 /src/map/script.c
parenta48f523555f02b4245cfc0313cb35f8a332cac50 (diff)
downloadhercules-fcba8a2161a392369db99ab9a516a24470c54796.tar.gz
hercules-fcba8a2161a392369db99ab9a516a24470c54796.tar.bz2
hercules-fcba8a2161a392369db99ab9a516a24470c54796.tar.xz
hercules-fcba8a2161a392369db99ab9a516a24470c54796.zip
Official Item Group/Package/Chain
http://hercules.ws/board/topic/1244-official-item-grouppackagechain/ Also Further implemented itemdb.c/storage.c interfaces, and a minor update to db2sql plugin. Signed-off-by: shennetsind <ind@henn.et>
Diffstat (limited to 'src/map/script.c')
-rw-r--r--src/map/script.c260
1 files changed, 168 insertions, 92 deletions
diff --git a/src/map/script.c b/src/map/script.c
index f65c0c21c..481cb5870 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -1397,7 +1397,7 @@ const char* parse_syntax(const char* p)
v = p2-p; // length of word at p2
memcpy(label,p,v);
label[v]='\0';
- if( !script_get_constant(label, &v) )
+ if( !script->get_constant(label, &v) )
disp_error_message("parse_syntax: 'case' label is not an integer",p);
p = skip_word(p);
} else { //Numeric value
@@ -1951,25 +1951,32 @@ bool script_get_constant(const char* name, int* value)
}
/// Creates new constant or parameter with given value.
-void script_set_constant(const char* name, int value, bool isparameter)
-{
+void script_set_constant(const char* name, int value, bool isparameter) {
int n = add_str(name);
- if( script->str_data[n].type == C_NOP )
- {// new
+ if( script->str_data[n].type == C_NOP ) {// new
script->str_data[n].type = isparameter ? C_PARAM : C_INT;
script->str_data[n].val = value;
- }
- else if( script->str_data[n].type == C_PARAM || script->str_data[n].type == C_INT )
- {// existing parameter or constant
+ } else if( script->str_data[n].type == C_PARAM || script->str_data[n].type == C_INT ) {// existing parameter or constant
ShowError("script_set_constant: Attempted to overwrite existing %s '%s' (old value=%d, new value=%d).\n", ( script->str_data[n].type == C_PARAM ) ? "parameter" : "constant", name, script->str_data[n].val, value);
- }
- else
- {// existing name
+ } else {// existing name
ShowError("script_set_constant: Invalid name for %s '%s' (already defined as %s).\n", isparameter ? "parameter" : "constant", name, script_op2name(script->str_data[n].type));
}
}
+/* will override if necessary */
+void script_set_constant2(const char *name, int value, bool isparameter) {
+ int n = add_str(name);
+
+ if( script->str_data[n].type != C_NOP ) {
+ script->str_data[n].next = 0;
+ script->str_data[n].func = NULL;
+ script->str_data[n].backpatch = -1;
+ script->str_data[n].label = -1;
+ }
+ script->str_data[n].type = isparameter ? C_PARAM : C_INT;
+ script->str_data[n].val = value;
+}
/*==========================================
* Reading constant databases
* const.txt
@@ -5564,11 +5571,11 @@ BUILDIN(countitem)
if( data_isstring(data) )
{// item name
- id = itemdb_searchname(script->conv_str(st, data));
+ id = itemdb->search_name(script->conv_str(st, data));
}
else
{// item id
- id = itemdb_exists(script->conv_num(st, data));
+ id = itemdb->exists(script->conv_num(st, data));
}
if( id == NULL )
@@ -5611,11 +5618,11 @@ BUILDIN(countitem2)
if( data_isstring(data) )
{// item name
- id = itemdb_searchname(script->conv_str(st, data));
+ id = itemdb->search_name(script->conv_str(st, data));
}
else
{// item id
- id = itemdb_exists(script->conv_num(st, data));
+ id = itemdb->exists(script->conv_num(st, data));
}
if( id == NULL )
@@ -5678,9 +5685,9 @@ BUILDIN(checkweight)
data = script_getdata(st,i);
script->get_val(st, data); // convert into value in case of a variable
if( data_isstring(data) ){// item name
- id = itemdb_searchname(script->conv_str(st, data));
+ id = itemdb->search_name(script->conv_str(st, data));
} else {// item id
- id = itemdb_exists(script->conv_num(st, data));
+ id = itemdb->exists(script->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
@@ -5794,7 +5801,7 @@ BUILDIN(checkweight2)
script_removetop(st, -1, 0);
if(fail) continue; //cpntonie to depop rest
- if(itemdb_exists(nameid) == NULL ){
+ if(itemdb->exists(nameid) == NULL ){
ShowError("buildin_checkweight2: Invalid item '%d'.\n", nameid);
fail=1;
continue;
@@ -5852,7 +5859,7 @@ BUILDIN(getitem)
if( data_isstring(data) )
{// "<item name>"
const char *name=script->conv_str(st,data);
- if( (item_data = itemdb_searchname(name)) == NULL ){
+ if( (item_data = itemdb->search_name(name)) == NULL ){
ShowError("buildin_getitem: Nonexistant item %s requested.\n", name);
return false; //No item created.
}
@@ -5864,7 +5871,7 @@ BUILDIN(getitem)
nameid = -nameid;
flag = 1;
}
- if( nameid <= 0 || !(item_data = itemdb_exists(nameid)) ){
+ if( nameid <= 0 || !(item_data = itemdb->exists(nameid)) ){
ShowError("buildin_getitem: Nonexistant item %d requested.\n", nameid);
return false; //No item created.
}
@@ -5939,7 +5946,7 @@ BUILDIN(getitem2)
script->get_val(st,data);
if( data_isstring(data) ){
const char *name=script->conv_str(st,data);
- struct item_data *item_data = itemdb_searchname(name);
+ struct item_data *item_data = itemdb->search_name(name);
if( item_data )
nameid=item_data->nameid;
else
@@ -5963,7 +5970,7 @@ BUILDIN(getitem2)
if(nameid > 0) {
memset(&item_tmp,0,sizeof(item_tmp));
- item_data=itemdb_exists(nameid);
+ item_data=itemdb->exists(nameid);
if (item_data == NULL)
return -1;
if(item_data->type==IT_WEAPON || item_data->type==IT_ARMOR){
@@ -6035,7 +6042,7 @@ BUILDIN(rentitem)
if( data_isstring(data) )
{
const char *name = script->conv_str(st,data);
- struct item_data *itd = itemdb_searchname(name);
+ struct item_data *itd = itemdb->search_name(name);
if( itd == NULL )
{
ShowError("buildin_rentitem: Nonexistant item %s requested.\n", name);
@@ -6046,7 +6053,7 @@ BUILDIN(rentitem)
else if( data_isint(data) )
{
nameid = script->conv_num(st,data);
- if( nameid <= 0 || !itemdb_exists(nameid) )
+ if( nameid <= 0 || !itemdb->exists(nameid) )
{
ShowError("buildin_rentitem: Nonexistant item %d requested.\n", nameid);
return false;
@@ -6097,7 +6104,7 @@ BUILDIN(getnameditem)
script->get_val(st,data);
if( data_isstring(data) ){
const char *name=script->conv_str(st,data);
- struct item_data *item_data = itemdb_searchname(name);
+ struct item_data *item_data = itemdb->search_name(name);
if( item_data == NULL)
{ //Failed
script_pushint(st,0);
@@ -6107,7 +6114,7 @@ BUILDIN(getnameditem)
}else
nameid = script->conv_num(st,data);
- if(!itemdb_exists(nameid)/* || itemdb_isstackable(nameid)*/)
+ if(!itemdb->exists(nameid)/* || itemdb_isstackable(nameid)*/)
{ //Even though named stackable items "could" be risky, they are required for certain quests.
script_pushint(st,0);
return true;
@@ -6146,12 +6153,30 @@ BUILDIN(getnameditem)
* gets a random item ID from an item group [Skotlex]
* groupranditem group_num
*------------------------------------------*/
-BUILDIN(grouprandomitem)
-{
- int group;
+BUILDIN(grouprandomitem) {
+ struct item_data *data;
+ int nameid;
+
+ if( script_hasdata(st, 2) )
+ nameid = script_getnum(st, 2);
+ else if ( script->current_item_id )
+ nameid = script->current_item_id;
+ else {
+ ShowWarning("buildin_grouprandomitem: no item id provided and no item attached\n");
+ script_pushint(st, 0);
+ return true;
+ }
- group = script_getnum(st,2);
- script_pushint(st,itemdb_searchrandomid(group));
+ if( !(data = itemdb->exists(nameid)) ) {
+ ShowWarning("buildin_grouprandomitem: unknown item id %d\n",nameid);
+ script_pushint(st, 0);
+ } else if ( !data->group ) {
+ ShowWarning("buildin_grouprandomitem: item '%s' (%d) isn't a group!\n",data->name,nameid);
+ script_pushint(st, 0);
+ } else {
+ script_pushint(st, itemdb->group_item(data->group));
+ }
+
return true;
}
@@ -6171,13 +6196,13 @@ BUILDIN(makeitem)
script->get_val(st,data);
if( data_isstring(data) ){
const char *name=script->conv_str(st,data);
- if( (item_data = itemdb_searchname(name)) )
+ if( (item_data = itemdb->search_name(name)) )
nameid=item_data->nameid;
else
nameid=UNKNOWN_ITEM_ID;
} else {
nameid=script->conv_num(st,data);
- if( nameid <= 0 || !(item_data = itemdb_exists(nameid)) ){
+ if( nameid <= 0 || !(item_data = itemdb->exists(nameid)) ){
ShowError("makeitem: Nonexistant item %d requested.\n", nameid);
return false; //No item created.
}
@@ -6384,7 +6409,7 @@ BUILDIN(delitem)
if( data_isstring(data) )
{
const char* item_name = script->conv_str(st,data);
- struct item_data* id = itemdb_searchname(item_name);
+ struct item_data* id = itemdb->search_name(item_name);
if( id == NULL )
{
ShowError("script:delitem: unknown item \"%s\".\n", item_name);
@@ -6396,7 +6421,7 @@ BUILDIN(delitem)
else
{
it.nameid = script->conv_num(st,data);// <item id>
- if( !itemdb_exists( it.nameid ) )
+ if( !itemdb->exists( it.nameid ) )
{
ShowError("script:delitem: unknown item \"%d\".\n", it.nameid);
st->state = END;
@@ -6453,7 +6478,7 @@ BUILDIN(delitem2)
if( data_isstring(data) )
{
const char* item_name = script->conv_str(st,data);
- struct item_data* id = itemdb_searchname(item_name);
+ struct item_data* id = itemdb->search_name(item_name);
if( id == NULL )
{
ShowError("script:delitem2: unknown item \"%s\".\n", item_name);
@@ -6465,7 +6490,7 @@ BUILDIN(delitem2)
else
{
it.nameid = script->conv_num(st,data);// <item id>
- if( !itemdb_exists( it.nameid ) )
+ if( !itemdb->exists( it.nameid ) )
{
ShowError("script:delitem: unknown item \"%d\".\n", it.nameid);
st->state = END;
@@ -8422,7 +8447,12 @@ BUILDIN(monster)
if (sd && strcmp(mapn, "this") == 0)
m = sd->bl.m;
else {
- m = iMap->mapname2mapid(mapn);
+
+ if ( ( m = iMap->mapname2mapid(mapn) ) == -1 ) {
+ ShowWarning("buildin_monster: Attempted to spawn monster class %d on non-existing map '%s'\n",class_, mapn);
+ return false;
+ }
+
if (map[m].flag.src4instance && st->instance_id >= 0) { // Try to redirect to the instance map, not the src map
if ((m = instance->mapid2imapid(m, st->instance_id)) < 0) {
ShowError("buildin_monster: Trying to spawn monster (%d) on instance map (%s) without instance attached.\n", class_, mapn);
@@ -8456,7 +8486,7 @@ BUILDIN(getmobdrops)
{
if( mob->dropitem[i].nameid < 1 )
continue;
- if( itemdb_exists(mob->dropitem[i].nameid) == NULL )
+ if( itemdb->exists(mob->dropitem[i].nameid) == NULL )
continue;
mapreg_setreg(reference_uid(add_str("$@MobDrop_item"), j), mob->dropitem[i].nameid);
@@ -9129,14 +9159,14 @@ BUILDIN(itemeffect) {
if( data_isstring( data ) ){
const char *name = script->conv_str( st, data );
- if( ( item_data = itemdb_searchname( name ) ) == NULL ){
+ if( ( item_data = itemdb->search_name( name ) ) == NULL ){
ShowError( "buildin_itemeffect: Nonexistant item %s requested.\n", name );
return false;
}
} else if( data_isint( data ) ){
int nameid = script->conv_num( st, data );
- if( ( item_data = itemdb_exists( nameid ) ) == NULL ){
+ if( ( item_data = itemdb->exists( nameid ) ) == NULL ){
ShowError("buildin_itemeffect: Nonexistant item %d requested.\n", nameid );
return false;
}
@@ -9363,7 +9393,7 @@ BUILDIN(getareadropitem)
script->get_val(st,data);
if( data_isstring(data) ){
const char *name=script->conv_str(st,data);
- struct item_data *item_data = itemdb_searchname(name);
+ struct item_data *item_data = itemdb->search_name(name);
item=UNKNOWN_ITEM_ID;
if( item_data )
item=item_data->nameid;
@@ -11446,13 +11476,13 @@ BUILDIN(getitemname)
if( data_isstring(data) ){
const char *name=script->conv_str(st,data);
- struct item_data *item_data = itemdb_searchname(name);
+ struct item_data *item_data = itemdb->search_name(name);
if( item_data )
item_id=item_data->nameid;
}else
item_id=script->conv_num(st,data);
- i_data = itemdb_exists(item_id);
+ i_data = itemdb->exists(item_id);
if (i_data == NULL)
{
script_pushconststr(st,"null");
@@ -11474,7 +11504,7 @@ BUILDIN(getitemslots)
item_id=script_getnum(st,2);
- i_data = itemdb_exists(item_id);
+ i_data = itemdb->exists(item_id);
if (i_data)
script_pushint(st,i_data->slot);
@@ -11515,7 +11545,7 @@ BUILDIN(getiteminfo)
item_id = script_getnum(st,2);
n = script_getnum(st,3);
- i_data = itemdb_exists(item_id);
+ i_data = itemdb->exists(item_id);
if (i_data && n>=0 && n<=14) {
item_arr = (int*)&i_data->value_buy;
@@ -11557,7 +11587,7 @@ BUILDIN(setiteminfo)
item_id = script_getnum(st,2);
n = script_getnum(st,3);
value = script_getnum(st,4);
- i_data = itemdb_exists(item_id);
+ i_data = itemdb->exists(item_id);
if (i_data && n>=0 && n<=14) {
item_arr = (int*)&i_data->value_buy;
@@ -13106,7 +13136,7 @@ BUILDIN(equip)
sd = script_rid2sd(st);
nameid=script_getnum(st,2);
- if((item_data = itemdb_exists(nameid)) == NULL)
+ if((item_data = itemdb->exists(nameid)) == NULL)
{
ShowError("wrong item ID : equipitem(%i)\n",nameid);
return false;
@@ -13125,7 +13155,7 @@ BUILDIN(autoequip)
nameid=script_getnum(st,2);
flag=script_getnum(st,3);
- if( ( item_data = itemdb_exists(nameid) ) == NULL )
+ if( ( item_data = itemdb->exists(nameid) ) == NULL )
{
ShowError("buildin_autoequip: Invalid item '%d'.\n", nameid);
return false;
@@ -14464,7 +14494,7 @@ BUILDIN(setitemscript)
new_bonus_script = script_getstr(st,3);
if( script_hasdata(st,4) )
n=script_getnum(st,4);
- i_data = itemdb_exists(item_id);
+ i_data = itemdb->exists(item_id);
if (!i_data || new_bonus_script==NULL || ( new_bonus_script[0] && new_bonus_script[0]!='{' )) {
script_pushint(st,0);
@@ -14630,10 +14660,10 @@ BUILDIN(searchitem)
int32 i;
TBL_PC* sd = NULL;
- if ((items[0] = itemdb_exists(atoi(itemname))))
+ if ((items[0] = itemdb->exists(atoi(itemname))))
count = 1;
else {
- count = itemdb_searchname_array(items, ARRAYLENGTH(items), itemname);
+ count = itemdb->search_name_array(items, ARRAYLENGTH(items), itemname);
if (count > MAX_SEARCH) count = MAX_SEARCH;
}
@@ -16831,50 +16861,53 @@ BUILDIN(checkre)
return true;
}
-/* getrandgroupitem <group_id>,<quantity> */
+/* getrandgroupitem <container_item_id>,<quantity> */
BUILDIN(getrandgroupitem) {
- TBL_PC* sd;
- int i, get_count = 0, flag, nameid, group = script_getnum(st, 2), qty = script_getnum(st,3);
- struct item item_tmp;
-
- if( !( sd = script_rid2sd(st) ) )
- return true;
-
- if( qty <= 0 ) {
- ShowError("getrandgroupitem: qty is <= 0!\n");
- return false;
- }
-
- if(group < 1 || group >= MAX_ITEMGROUP) {
- ShowError("getrandgroupitem: Invalid group id %d\n", group);
- return false;
- }
- if (!itemgroup_db[group].qty) {
- ShowError("getrandgroupitem: group id %d is empty!\n", group);
- return false;
- }
-
- nameid = itemdb_searchrandomid(group);
- memset(&item_tmp,0,sizeof(item_tmp));
-
- item_tmp.nameid = nameid;
- item_tmp.identify = itemdb_isidentified(nameid);
-
- //Check if it's stackable.
- if (!itemdb_isstackable(nameid))
- get_count = 1;
- else
- get_count = qty;
+ struct item_data *data = NULL;
+ struct map_session_data *sd = NULL;
+ int nameid = script_getnum(st, 2);
+ int count = script_getnum(st, 3);
- for (i = 0; i < qty; i += get_count) {
- // if not pet egg
- if (!pet_create_egg(sd, nameid)) {
- if ((flag = pc->additem(sd, &item_tmp, get_count, LOG_TYPE_SCRIPT))) {
- clif->additem(sd, 0, 0, flag);
- if( pc->candrop(sd,&item_tmp) )
- iMap->addflooritem(&item_tmp,get_count,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
+ if( !(data = itemdb->exists(nameid)) ) {
+ ShowWarning("buildin_getrandgroupitem: unknown item id %d\n",nameid);
+ script_pushint(st, 1);
+ } else if ( count <= 0 ) {
+ ShowError("buildin_getrandgroupitem: qty is <= 0!\n");
+ script_pushint(st, 1);
+ } else if ( !data->group ) {
+ ShowWarning("buildin_getrandgroupitem: item '%s' (%d) isn't a group!\n",data->name,nameid);
+ script_pushint(st, 1);
+ } else if( !( sd = script->rid2sd(st) ) ) {
+ ShowWarning("buildin_getrandgroupitem: no player attached!! (item %s (%d))\n",data->name,nameid);
+ script_pushint(st, 1);
+ } else {
+ int i, get_count, flag;
+ struct item it;
+
+ memset(&it,0,sizeof(it));
+
+ nameid = itemdb->group_item(data->group);
+
+ it.nameid = nameid;
+ it.identify = itemdb_isidentified(nameid);
+
+ if (!itemdb_isstackable(nameid))
+ get_count = 1;
+ else
+ get_count = count;
+
+ for (i = 0; i < count; i += get_count) {
+ // if not pet egg
+ if (!pet_create_egg(sd, nameid)) {
+ if ((flag = pc->additem(sd, &it, get_count, LOG_TYPE_SCRIPT))) {
+ clif->additem(sd, 0, 0, flag);
+ if( pc->candrop(sd,&it) )
+ iMap->addflooritem(&it,get_count,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
+ }
}
}
+
+ script_pushint(st, 0);
}
return true;
@@ -17268,6 +17301,41 @@ BUILDIN(qiclear) {
return true;
}
+/**
+ * packageitem({<optional container_item_id>})
+ * when no item id is provided it tries to assume it comes from the current item id being processed (if any)
+ **/
+BUILDIN(packageitem) {
+ struct item_data *data = NULL;
+ struct map_session_data *sd = NULL;
+ int nameid;
+
+ if( script_hasdata(st, 2) )
+ nameid = script_getnum(st, 2);
+ else if ( script->current_item_id )
+ nameid = script->current_item_id;
+ else {
+ ShowWarning("buildin_packageitem: no item id provided and no item attached\n");
+ script_pushint(st, 1);
+ return true;
+ }
+
+ if( !(data = itemdb->exists(nameid)) ) {
+ ShowWarning("buildin_packageitem: unknown item id %d\n",nameid);
+ script_pushint(st, 1);
+ } else if ( !data->package ) {
+ ShowWarning("buildin_packageitem: item '%s' (%d) isn't a package!\n",data->name,nameid);
+ script_pushint(st, 1);
+ } else if( !( sd = script->rid2sd(st) ) ) {
+ ShowWarning("buildin_packageitem: no player attached!! (item %s (%d))\n",data->name,nameid);
+ script_pushint(st, 1);
+ } else {
+ itemdb->package_item(sd,data->package);
+ script_pushint(st, 0);
+ }
+
+ return true;
+}
// declarations that were supposed to be exported from npc_chat.c
#ifdef PCRE_SUPPORT
@@ -17782,6 +17850,9 @@ void script_parse_builtin(void) {
BUILDIN_DEF(qicheck,"i"),
BUILDIN_DEF(qiget,"i"),
BUILDIN_DEF(qiclear,"i"),
+
+ BUILDIN_DEF(packageitem,"?"),
+
};
int i,n, len = ARRAYLENGTH(BUILDIN), start = script->buildin_count;
char* p;
@@ -17859,6 +17930,8 @@ void script_defaults(void) {
script->word_buf = NULL;
script->word_size = 0;
+ script->current_item_id = 0;
+
script->init = do_init_script;
script->final = do_final_script;
@@ -17874,6 +17947,9 @@ void script_defaults(void) {
script->push_str = push_str;
script->push_copy = push_copy;
script->pop_stack = pop_stack;
+ script->set_constant = script_set_constant;
+ script->set_constant2 = script_set_constant2;
+ script->get_constant = script_get_constant;
script->queue = script_hqueue_get;
script->queue_add = script_hqueue_add;