diff options
author | shennetsind <ind@henn.et> | 2013-06-23 16:35:42 -0300 |
---|---|---|
committer | shennetsind <ind@henn.et> | 2013-06-23 16:35:42 -0300 |
commit | fcba8a2161a392369db99ab9a516a24470c54796 (patch) | |
tree | dc223cbd60e53b57eee6ff5e03a3a6bfea76e516 /src/map/script.c | |
parent | a48f523555f02b4245cfc0313cb35f8a332cac50 (diff) | |
download | hercules-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.c | 260 |
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; |