diff options
-rw-r--r-- | doc/script_commands.txt | 132 | ||||
-rw-r--r-- | src/map/script.c | 213 | ||||
-rw-r--r-- | src/map/skill.c | 2 | ||||
-rw-r--r-- | src/map/status.c | 4 | ||||
-rw-r--r-- | src/map/unit.c | 2 | ||||
-rw-r--r-- | src/plugins/HPMHooking/HPMHooking_map.Hooks.inc | 12 | ||||
-rwxr-xr-x | tools/validateinterfaces.py | 2 |
7 files changed, 338 insertions, 29 deletions
diff --git a/doc/script_commands.txt b/doc/script_commands.txt index 33e706004..3467a5366 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -2922,7 +2922,7 @@ recreate these items perfectly if they are destroyed. Here's what you get: @inventorylist_id[] - array of item ids. @inventorylist_amount[] - their corresponding item amounts. -@inventorylist_equip[] - whether the item is equipped or not. +@inventorylist_equip[] - will return the slot the item is equipped on, if at all. @inventorylist_refine[] - for how much it is refined. @inventorylist_identify[] - whether it is identified. @inventorylist_attribute[] - whether it is broken. @@ -2933,8 +2933,8 @@ recreate these items perfectly if they are destroyed. Here's what you get: made by a specific craftsman. @inventorylist_expire[] - expire time (Unix time stamp). 0 means never expires. -@inventorylist_count - the number of items in these lists. @inventorylist_bound - whether it is an account bounded item or not. +@inventorylist_count - the number of items in these lists. This could be handy to save/restore a character's inventory, since no other command returns such a complete set of data, and could also be the @@ -2951,6 +2951,42 @@ runs of 'getinventorylist'. --------------------------------------- +*getcartinventorylist; + +This command sets a bunch of arrays with a complete list of whatever the +invoking character has in its cart_inventory, including all the data needed to +recreate these items perfectly if they are destroyed. Here's what you get: + +@cartinventorylist_id[] - array of item ids. +@cartinventorylist_amount[] - their corresponding item amounts. +@cartinventorylist_refine[] - for how much it is refined. +@cartinventorylist_identify[] - whether it is identified. +@cartinventorylist_attribute[] - whether it is broken. +@cartinventorylist_card1[] - These four arrays contain card data for the +@cartinventorylist_card2[] items. These data slots are also used to store +@cartinventorylist_card3[] names inscribed on the items, so you can +@cartinventorylist_card4[] explicitly check if the character owns an item + made by a specific craftsman. +@cartinventorylist_expire[] - expire time (Unix time stamp). 0 means never + expires. +@cartinventorylist_bound - whether it is an account bounded item or not. +@cartinventorylist_count - the number of items in these lists. + +This could be handy to save/restore a character's cart_inventory, since no +other command returns such a complete set of data, and could also be the +only way to correctly handle an NPC trader for carded and named items who +could resell them - since NPC objects cannot own items, so they have to +store item data in variables and recreate the items. + +Notice that the variables this command generates are all temporary, +attached to the character, and integer. + +Be sure to use @cartinventorylist_count to go through these arrays, and not +'getarraysize', because the arrays are not automatically cleared between +runs of 'getcartinventorylist'. + +--------------------------------------- + *cardscnt() This function will return the number of cards inserted into the weapon @@ -4787,6 +4823,68 @@ Example: --------------------------------------- +*checkbound(<item_id>{,<bound_type>{,<refine>{,<attribute>{,<card_1>{,<card_2>{,<card_3>{,<card_4>}}}}}}}); + +This command allows you to check whether or not the attached player has the specified bound item in their inventory. +If a bound type is not specified or a bound type of 0 is used, it will search the player's inventory for a bound item +of any type, so long as the other parameters match. In all cases, this command will return the bound type of the +item found, or 0 if the specified item was not found. + +Valid bound types are: + 0 - All Bound types. + 1 - Account Bound + 2 - Guild Bound + 3 - Party Bound + 4 - Character Bound + +Optional Parameters: + bound_type - checks to see if the item has the specified bound type. + refine - checks to see if the item is refined to the given number. + attribute - whether the item is broken (1) or not (0). + card 1,2,3,4 - checks to see if the specified cards are compounded on the item as well. + +Example: + // This will check if you have a bound (any type) 1205 (Cutter). + if (checkbound(1205)) { + mes "You have a bound Cutter"; + } else { + mes "You do not have a bound Cutter"; + } + close; + + // This will also check if you have a bound (any type) 1205 (Cutter). + if (checkbound(1205,0)) { + mes "You have a bound Cutter"; + } else { + mes "You do not have a bound Cutter"; + } + close; + + // This will check if the player doesn't have a bound 1205 (Cutter). + if (!checkbound(1205)) { + mes "You do not have a bound Cutter"; + } else { + mes "You do have a bound Cutter"; + } + close; + + // This will check if the item found, has a bound type of 2 (guild_bound) + if (checkbound(1205) == 2) { + mes "You have a guild_bound Cutter"; + } else { + mes "You do not have a guild_bound Cutter."; + } + close; + + // This will check if you have a 'guild_bound' +7 1205 (Cutter). + if (checkbound(1205, 2, 7)) { + mes "You have a +7 guild_bound Cutter."; + } else { + mes "You don't have the required item."; + } + close; +--------------------------------------- + *getnameditem <item id>,<character name|character ID>; *getnameditem "<item name>",<character name|character ID>; @@ -5186,6 +5284,7 @@ like storage or cart. --------------------------------------- *equip <item id>; +*equip2 <item id>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>; *autoequip <item id>,<option>; These commands are to equip a equipment on the attached character. @@ -5199,7 +5298,11 @@ Examples: //This will equip a 1104 (falchion) on the character if this is in the //inventory. equip 1104; - + +//This will equip a +10 1104 (falchion) on the character if this is in the +//inventory. + equip2 1104,10,0,0,0,0,0; + //The invoked character will now automatically equip a falchion when it's //looted. autoequip 1104,1; @@ -8340,11 +8443,32 @@ if (instance_check_party(getcharid(1),2,2,149)) { mes "All online members are between levels 1-150 and at least two are online."; close; } else { - mes "Sorry, your party does not meet requirements."; + mes "Sorry, your party does not meet the requirements."; close; } --------------------------------------- + +*instance_check_guild(<guild_id>{,<amount>{,<min>{,<max>}}}); + +This function checks if a guild meets certain requirements, returning 1 if +all conditions are met and 0 otherwise. it will only check online characters. + +amount - number of online guild members (default is 1). +min - minimum level of all characters in the guild (default is 1). +max - maximum level of all characters in the guild (default is max level in conf). + +Example: + if (instance_check_guild(getcharid(2), 2, 1, 150)) { + mes "Your guild meets the Memorial Dungeon requirements.", + mes "All online members are between levels 1-150 and at least two are online."; + close; + } else { + mes "Sorry, your guild does not meet the requirements."; + close; + } + +--------------------------------------- *instance_set_respawn(<map_name>,<x>,<y>{,<instance_id>}); Updates the 'reload spawn' position of a instance, diff --git a/src/map/script.c b/src/map/script.c index e04ba6f32..a458bab49 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -10677,15 +10677,8 @@ BUILDIN(changebase) { return true; } - if(sd->disguise == -1 && vclass != sd->vd.class_) { - status->set_viewdata(&sd->bl, vclass); - //Updated client view. Base, Weapon and Cloth Colors. - clif->changelook(&sd->bl,LOOK_BASE,sd->vd.class_); - clif->changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon); - if (sd->vd.cloth_color) - clif->changelook(&sd->bl,LOOK_CLOTHES_COLOR,sd->vd.cloth_color); - clif->skillinfoblock(sd); - } + if(sd->disguise == -1 && vclass != sd->vd.class_) + pc->changelook(sd,LOOK_BASE,vclass); //Updated client view. Base, Weapon and Cloth Colors. return true; } @@ -12424,23 +12417,26 @@ BUILDIN(petloot) * @inventorylist_card(0..3), @inventorylist_expire * @inventorylist_count = scalar *------------------------------------------*/ -BUILDIN(getinventorylist) -{ +BUILDIN(getinventorylist){ TBL_PC *sd=script->rid2sd(st); char card_var[NAME_LENGTH]; int i,j=0,k; if(!sd) return true; + for(i=0;i<MAX_INVENTORY;i++) { if(sd->status.inventory[i].nameid > 0 && sd->status.inventory[i].amount > 0) { pc->setreg(sd,reference_uid(script->add_str("@inventorylist_id"), j),sd->status.inventory[i].nameid); pc->setreg(sd,reference_uid(script->add_str("@inventorylist_amount"), j),sd->status.inventory[i].amount); - pc->setreg(sd,reference_uid(script->add_str("@inventorylist_equip"), j),sd->status.inventory[i].equip); + if(sd->status.inventory[i].equip) { + pc->setreg(sd,reference_uid(script->add_str("@inventorylist_equip"), j),pc->equippoint(sd,i)); + } else { + pc->setreg(sd,reference_uid(script->add_str("@inventorylist_equip"), j),0); + } pc->setreg(sd,reference_uid(script->add_str("@inventorylist_refine"), j),sd->status.inventory[i].refine); pc->setreg(sd,reference_uid(script->add_str("@inventorylist_identify"), j),sd->status.inventory[i].identify); pc->setreg(sd,reference_uid(script->add_str("@inventorylist_attribute"), j),sd->status.inventory[i].attribute); - for (k = 0; k < MAX_SLOTS; k++) - { + for (k = 0; k < MAX_SLOTS; k++) { sprintf(card_var, "@inventorylist_card%d",k+1); pc->setreg(sd,reference_uid(script->add_str(card_var), j),sd->status.inventory[i].card[k]); } @@ -12453,6 +12449,34 @@ BUILDIN(getinventorylist) return true; } +BUILDIN(getcartinventorylist){ + TBL_PC *sd=script->rid2sd(st); + char card_var[NAME_LENGTH]; + + int i,j=0,k; + if(!sd) return true; + + for(i=0;i<MAX_CART;i++) { + if(sd->status.cart[i].nameid > 0 && sd->status.cart[i].amount > 0) { + pc->setreg(sd,reference_uid(script->add_str("@cartinventorylist_id"), j),sd->status.cart[i].nameid); + pc->setreg(sd,reference_uid(script->add_str("@cartinventorylist_amount"), j),sd->status.cart[i].amount); + pc->setreg(sd,reference_uid(script->add_str("@cartinventorylist_equip"), j),sd->status.cart[i].equip); + pc->setreg(sd,reference_uid(script->add_str("@cartinventorylist_refine"), j),sd->status.cart[i].refine); + pc->setreg(sd,reference_uid(script->add_str("@cartinventorylist_identify"), j),sd->status.cart[i].identify); + pc->setreg(sd,reference_uid(script->add_str("@cartinventorylist_attribute"), j),sd->status.cart[i].attribute); + for (k = 0; k < MAX_SLOTS; k++) { + sprintf(card_var, "@cartinventorylist_card%d",k+1); + pc->setreg(sd,reference_uid(script->add_str(card_var), j),sd->status.cart[i].card[k]); + } + pc->setreg(sd,reference_uid(script->add_str("@cartinventorylist_expire"), j),sd->status.cart[i].expire_time); + pc->setreg(sd,reference_uid(script->add_str("@cartinventorylist_bound"), j),sd->status.cart[i].bound); + j++; + } + } + pc->setreg(sd,script->add_str("@cartinventorylist_count"),j); + return true; +} + BUILDIN(getskilllist) { TBL_PC *sd=script->rid2sd(st); @@ -13858,6 +13882,57 @@ BUILDIN(autoequip) return true; } +/*======================================================= + * Equip2 + * equip2 <item id>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>; + *-------------------------------------------------------*/ +BUILDIN(equip2) +{ + int i,nameid,ref,attr,c0,c1,c2,c3; + struct item_data *item_data; + TBL_PC *sd; + + sd = script->rid2sd(st); + + if ( sd == NULL ) { + script_pushint(st,0); + return true; + } + + nameid = script_getnum(st,2); + if( (item_data = itemdb->exists(nameid)) == NULL ) + { + ShowError("Wrong item ID : equip2(%i)\n",nameid); + script_pushint(st,0); + return false; + } + + ref = script_getnum(st,3); + attr = script_getnum(st,4); + c0 = (short)script_getnum(st,5); + c1 = (short)script_getnum(st,6); + c2 = (short)script_getnum(st,7); + c3 = (short)script_getnum(st,8); + + ARR_FIND( 0, MAX_INVENTORY, i,( sd->status.inventory[i].equip == 0 && + sd->status.inventory[i].nameid == nameid && + sd->status.inventory[i].refine == ref && + sd->status.inventory[i].attribute == attr && + sd->status.inventory[i].card[0] == c0 && + sd->status.inventory[i].card[1] == c1 && + sd->status.inventory[i].card[2] == c2 && + sd->status.inventory[i].card[3] == c3 ) ); + + if( i < MAX_INVENTORY ) { + script_pushint(st,1); + pc->equipitem(sd,i,item_data->equip); + } + else + script_pushint(st,0); + + return true; +} + BUILDIN(setbattleflag) { const char *flag, *value; @@ -17127,6 +17202,63 @@ BUILDIN(instance_check_party) { } /*========================================== + * instance_check_guild + * Values: + * guild_id : Guild ID of the invoking character. [Required Parameter] + * amount : Amount of needed Guild Members for the Instance. [Optional Parameter] + * min : Minimum Level needed to join the Instance. [Optional Parameter] + * max : Maxium Level allowed to join the Instance. [Optional Parameter] + * Example: instance_check_guild (getcharid(2){,amount}{,min}{,max}); + * Example 2: instance_check_guild (getcharid(2),1,1,99); + *------------------------------------------*/ +BUILDIN(instance_check_guild){ + struct map_session_data *pl_sd; + int amount, min, max, i, guild_id, c = 0; + struct guild *g = NULL; + + amount = script_hasdata(st,3) ? script_getnum(st,3) : 1; + min = script_hasdata(st,4) ? script_getnum(st,4) : 1; + max = script_hasdata(st,5) ? script_getnum(st,5) : MAX_LEVEL; + + if( min < 1 || min > MAX_LEVEL ){ + ShowError("instance_check_guild: Invalid min level, %d\n", min); + return true; + } else if( max < 1 || max > MAX_LEVEL ){ + ShowError("instance_check_guild: Invalid max level, %d\n", max); + return true; + } + + if( script_hasdata(st,2) ) + guild_id = script_getnum(st,2); + else return true; + + if( !(g = guild->search(guild_id)) ){ + script_pushint(st,0); + return true; + } + + for( i = 0; i < MAX_GUILD; i++ ) + if( (pl_sd = g->member[i].sd) ) + if( map->id2bl(pl_sd->bl.id) ){ + if( pl_sd->status.base_level < min ){ + script_pushint(st,0); + return true; + } else if( pl_sd->status.base_level > max ){ + script_pushint(st,0); + return true; + } + c++; + } + + if( c < amount ) + script_pushint(st,0); + else + script_pushint(st,1); + + return true; +} + +/*========================================== * Custom Fonts *------------------------------------------*/ BUILDIN(setfont) @@ -18474,6 +18606,55 @@ BUILDIN(countbound) return 0; } +/*========================================== + * checkbound(<item_id>{,<bound_type>{,<refine>{,<attribute>{,<card_1>{,<card_2>{,<card_3>{,<card_4>}}}}}}}); + * Checks to see if specified item is in inventory. + * Returns the bound type of item found. + * Type: + * 1 - Account Bound + * 2 - Guild Bound + * 3 - Party Bound + * 4 - Character Bound + *------------------------------------------*/ +BUILDIN(checkbound){ + int i, nameid = script_getnum(st,2); + int bound_type = 0, ref, attr, c1, c2, c3, c4; + TBL_PC *sd; + + sd = script->rid2sd(st); + if( sd == NULL ) + return false; + + if( !(itemdb->exists(nameid)) ){ + ShowError("script_checkbound: Invalid item ID = %d\n", nameid); + return false; + } + + if (script_hasdata(st,3)) + bound_type = script_getnum(st,3); + + if( bound_type <= -1 || bound_type > IBT_MAX ){ + ShowError("script_checkbound: Not a valid bind type! Type=%d\n", bound_type); + } + + ARR_FIND( 0, MAX_INVENTORY, i, (sd->status.inventory[i].nameid == nameid && + ( sd->status.inventory[i].refine == (script_hasdata(st,4)? (ref = script_getnum(st,4)) : sd->status.inventory[i].refine) ) && + ( sd->status.inventory[i].attribute == (script_hasdata(st,5)? (attr = script_getnum(st,5)) : sd->status.inventory[i].attribute) ) && + ( sd->status.inventory[i].card[0] == (script_hasdata(st,6)? (c1 = script_getnum(st,6)) : sd->status.inventory[i].card[0]) ) && + ( sd->status.inventory[i].card[1] == (script_hasdata(st,7)? (c2 = script_getnum(st,7)) : sd->status.inventory[i].card[1]) ) && + ( sd->status.inventory[i].card[2] == (script_hasdata(st,8)? (c3 = script_getnum(st,8)) : sd->status.inventory[i].card[2]) ) && + ( sd->status.inventory[i].card[3] == (script_hasdata(st,9)? (c4 = script_getnum(st,9)) : sd->status.inventory[i].card[3]) ) && + ((sd->status.inventory[i].bound > 0 && !bound_type) || sd->status.inventory[i].bound == bound_type )) ); + + if( i < MAX_INVENTORY ){ + script_pushint(st, sd->status.inventory[i].bound); + return true; + } else + script_pushint(st,0); + + return true; +} + /* bg_match_over( arena_name {, optional canceled } ) */ /* returns 0 when successful, 1 otherwise */ BUILDIN(bg_match_over) { @@ -19162,6 +19343,7 @@ void script_parse_builtin(void) { BUILDIN_DEF(makepet,"i"), BUILDIN_DEF(getexp,"ii"), BUILDIN_DEF(getinventorylist,""), + BUILDIN_DEF(getcartinventorylist,""), BUILDIN_DEF(getskilllist,""), BUILDIN_DEF(clearitem,""), BUILDIN_DEF(classchange,"ii"), @@ -19270,6 +19452,7 @@ void script_parse_builtin(void) { BUILDIN_DEF(npcshopattach,"s?"), BUILDIN_DEF(equip,"i"), BUILDIN_DEF(autoequip,"ii"), + BUILDIN_DEF(equip2,"iiiiiii"), BUILDIN_DEF(setbattleflag,"si"), BUILDIN_DEF(getbattleflag,"s"), BUILDIN_DEF(setitemscript,"is?"), //Set NEW item bonus script. Lupus @@ -19370,6 +19553,7 @@ void script_parse_builtin(void) { BUILDIN_DEF(has_instance,"s?"), BUILDIN_DEF(instance_warpall,"sii?"), BUILDIN_DEF(instance_check_party,"i???"), + BUILDIN_DEF(instance_check_guild,"i???"), BUILDIN_DEF(instance_mapname,"s?"), BUILDIN_DEF(instance_set_respawn,"sii?"), BUILDIN_DEF2(has_instance,"has_instance2","s"), @@ -19410,6 +19594,7 @@ void script_parse_builtin(void) { BUILDIN_DEF2(getitem,"getitembound","vii?"), BUILDIN_DEF2(getitem2,"getitembound2","viiiiiiiii?"), BUILDIN_DEF(countbound, "?"), + BUILDIN_DEF(checkbound, "i???????"), //Quest Log System [Inkfish] BUILDIN_DEF(questinfo, "ii??"), diff --git a/src/map/skill.c b/src/map/skill.c index d89d82f57..c8737517d 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -3875,7 +3875,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1 case MS_MAGNUM: if( flag&1 ) { //Damage depends on distance, so add it to flag if it is > 1 - skill_attack(skill_get_type(skill_id), src, src, bl, skill_id, skill_lv, tick, flag|distance_bl(src, bl)); + skill->attack(skill->get_type(skill_id), src, src, bl, skill_id, skill_lv, tick, flag|distance_bl(src, bl)); } break; diff --git a/src/map/status.c b/src/map/status.c index 9fbda4b59..6d4b8d5fa 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -8072,10 +8072,10 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t if(sd && val2 == SL_HIGH) { int stat,max_stat; // Fetch target's stats - struct status_data* status2 = status_get_status_data(bl); // Battle status + struct status_data* status2 = status->get_status_data(bl); // Battle status val3 = 0; val4 = 0; - max_stat = (status_get_lv(bl)-10<50)?status_get_lv(bl)-10:50; + max_stat = (status->get_lv(bl)-10<50)?status->get_lv(bl)-10:50; stat = max(0, max_stat - status2->str ); val3 |= cap_value(stat,0,0xFF)<<16; stat = max(0, max_stat - status2->agi ); val3 |= cap_value(stat,0,0xFF)<<8; stat = max(0, max_stat - status2->vit ); val3 |= cap_value(stat,0,0xFF); diff --git a/src/map/unit.c b/src/map/unit.c index 243a7c28a..64885541f 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -399,7 +399,7 @@ int unit_walktoxy_timer(int tid, int64 tick, int id, intptr_t data) { } if(ud->state.change_walk_target) { - if(unit_walktoxy_sub(bl)) { + if(unit->walktoxy_sub(bl)) { return 1; } else { clif->fixpos(bl); diff --git a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc index 6531492a3..0169d43c7 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc @@ -64851,15 +64851,15 @@ unsigned short HP_status_calc_batk(struct block_list *bl, struct status_change * } return retVal___; } -unsigned short HP_status_base_matk(const struct status_data *st, int level) { +unsigned short HP_status_base_matk(struct block_list *bl, const struct status_data *st, int level) { int hIndex = 0; unsigned short retVal___ = 0; if( HPMHooks.count.HP_status_base_matk_pre ) { - unsigned short (*preHookFunc) (const struct status_data *st, int *level); + unsigned short (*preHookFunc) (struct block_list *bl, const struct status_data *st, int *level); *HPMforce_return = false; for(hIndex = 0; hIndex < HPMHooks.count.HP_status_base_matk_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_status_base_matk_pre[hIndex].func; - retVal___ = preHookFunc(st, &level); + retVal___ = preHookFunc(bl, st, &level); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -64867,13 +64867,13 @@ unsigned short HP_status_base_matk(const struct status_data *st, int level) { } } { - retVal___ = HPMHooks.source.status.base_matk(st, level); + retVal___ = HPMHooks.source.status.base_matk(bl, st, level); } if( HPMHooks.count.HP_status_base_matk_post ) { - unsigned short (*postHookFunc) (unsigned short retVal___, const struct status_data *st, int *level); + unsigned short (*postHookFunc) (unsigned short retVal___, struct block_list *bl, const struct status_data *st, int *level); for(hIndex = 0; hIndex < HPMHooks.count.HP_status_base_matk_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_status_base_matk_post[hIndex].func; - retVal___ = postHookFunc(retVal___, st, &level); + retVal___ = postHookFunc(retVal___, bl, st, &level); } } return retVal___; diff --git a/tools/validateinterfaces.py b/tools/validateinterfaces.py index b34bd6233..87ff46a85 100755 --- a/tools/validateinterfaces.py +++ b/tools/validateinterfaces.py @@ -177,7 +177,7 @@ def checkLostFile(tracker, cFile): m = methodRe.search(line) if m != None: name = "{0}_{1}".format(m.group("ifname"), m.group("method")) - if m.group("ifname") not in tracker.interfaces: + if name[:name.find("_")] not in tracker.interfaces and m.group("ifname") not in tracker.interfaces: continue if name not in tracker.fullmethods: # print "src : " + line |