diff options
40 files changed, 639 insertions, 162 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d9a156298..fb038ea66 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -124,14 +124,22 @@ zero-2018:clang-4.0: pre_re:clang-5.0: <<: *branch_exceptions - <<: *prerequisites + before_script: + - echo "Building $CI_BUILD_NAME" + - uname -a + - echo 'deb http://ftp.debian.org/debian stretch-backports main' >> /etc/apt/sources.list + - ./tools/ci/retry.sh apt-get update + - ./tools/ci/retry.sh apt-get install -t stretch-backports -y -qq clang-5.0 + - ./tools/ci/retry.sh apt-get install -y -qq $INSTALL_PACKAGES $DEBIAN_COMMON_PACKAGES + - ./tools/ci/travis.sh importdb ragnarok ragnarok ragnarok $SQLHOST + - ./tools/ci/travis.sh getplugins || true stage: secondary - image: debian:unstable + image: debian:stretch services: - - mariadb:10 + - mariadb:10.1 variables: <<: *base_vars - INSTALL_PACKAGES: clang-5.0 mariadb-client libmariadbclient-dev-compat + INSTALL_PACKAGES: mariadb-client libmariadbclient-dev-compat SQLHOST: mariadb script: - ./tools/ci/travis.sh build CC=clang-5.0 --enable-debug --enable-Werror --enable-buildbot --disable-renewal @@ -139,14 +147,22 @@ pre_re:clang-5.0: re:clang-5.0: <<: *branch_exceptions - <<: *prerequisites + before_script: + - echo "Building $CI_BUILD_NAME" + - uname -a + - echo 'deb http://ftp.debian.org/debian stretch-backports main' >> /etc/apt/sources.list + - ./tools/ci/retry.sh apt-get update + - ./tools/ci/retry.sh apt-get install -t stretch-backports -y -qq clang-5.0 + - ./tools/ci/retry.sh apt-get install -y -qq $INSTALL_PACKAGES $DEBIAN_COMMON_PACKAGES + - ./tools/ci/travis.sh importdb ragnarok ragnarok ragnarok $SQLHOST + - ./tools/ci/travis.sh getplugins || true stage: secondary - image: debian:unstable + image: debian:stretch services: - - mariadb:10 + - mariadb:10.1 variables: <<: *base_vars - INSTALL_PACKAGES: clang-5.0 mariadb-client libmariadbclient-dev-compat + INSTALL_PACKAGES: mariadb-client libmariadbclient-dev-compat SQLHOST: mariadb script: - ./tools/ci/travis.sh build CC=clang-5.0 --enable-debug --enable-Werror --enable-buildbot @@ -154,14 +170,22 @@ re:clang-5.0: zero-2018:clang-5.0: <<: *branch_exceptions - <<: *prerequisites + before_script: + - echo "Building $CI_BUILD_NAME" + - uname -a + - echo 'deb http://ftp.debian.org/debian stretch-backports main' >> /etc/apt/sources.list + - ./tools/ci/retry.sh apt-get update + - ./tools/ci/retry.sh apt-get install -t stretch-backports -y -qq clang-5.0 + - ./tools/ci/retry.sh apt-get install -y -qq $INSTALL_PACKAGES $DEBIAN_COMMON_PACKAGES + - ./tools/ci/travis.sh importdb ragnarok ragnarok ragnarok $SQLHOST + - ./tools/ci/travis.sh getplugins || true stage: clients - image: debian:unstable + image: debian:stretch services: - - mariadb:10 + - mariadb:10.1 variables: <<: *base_vars - INSTALL_PACKAGES: clang-5.0 mariadb-client libmariadbclient-dev-compat + INSTALL_PACKAGES: mariadb-client libmariadbclient-dev-compat SQLHOST: mariadb script: - ./tools/ci/travis.sh build CC=clang-5.0 --enable-debug --enable-Werror --enable-buildbot --enable-packetver-zero --enable-packetver=20180511 diff --git a/.travis.yml b/.travis.yml index fc28a5aef..9312dac9e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -38,7 +38,7 @@ matrix: - compiler: false include: - compiler: gcc - env: LDFLAGS="-fuse-ld=gold" CONFIGURE_FLAGS="--enable-debug CC=gcc-6 --disable-manager --enable-Werror --enable-packetver=20180919 --enable-packetver-re --enable-buildbot" HPM="1" + env: LDFLAGS="-fuse-ld=gold" CONFIGURE_FLAGS="--enable-debug CC=gcc-6 --disable-manager --enable-Werror --enable-packetver=20181017 --enable-packetver-re --enable-buildbot" HPM="1" addons: apt: sources: @@ -50,7 +50,7 @@ matrix: - libxml-sax-perl - libxml-parser-perl - compiler: clang - env: CONFIGURE_FLAGS="--enable-debug CC=clang-5.0 --enable-Werror --enable-packetver=20180919 --enable-packetver-re --enable-buildbot" + env: CONFIGURE_FLAGS="--enable-debug CC=clang-5.0 --enable-Werror --enable-packetver=20181017 --enable-packetver-re --enable-buildbot" addons: apt: sources: @@ -68,7 +68,7 @@ matrix: packages: - clang-5.0 - compiler: clang - env: CONFIGURE_FLAGS="--enable-debug CC=clang-4.0 --enable-Werror --enable-packetver=20180919 --enable-packetver-re --enable-buildbot" + env: CONFIGURE_FLAGS="--enable-debug CC=clang-4.0 --enable-Werror --enable-packetver=20181017 --enable-packetver-re --enable-buildbot" addons: apt: sources: @@ -90,11 +90,11 @@ matrix: - compiler: clang env: CONFIGURE_FLAGS="--enable-debug --disable-renewal --enable-Werror --enable-buildbot" - compiler: gcc - env: CONFIGURE_FLAGS="--enable-debug --enable-Werror --enable-packetver=20180919 --enable-packetver-re --enable-buildbot" + env: CONFIGURE_FLAGS="--enable-debug --enable-Werror --enable-packetver=20181017 --enable-packetver-re --enable-buildbot" - compiler: gcc env: CONFIGURE_FLAGS="--enable-debug --disable-renewal --enable-Werror --enable-buildbot" - compiler: gcc - env: LDFLAGS="-fuse-ld=gold" CONFIGURE_FLAGS="--enable-debug --enable-sanitize=full CC=gcc-5 --disable-manager --enable-Werror --enable-packetver=20180919 --enable-packetver-re --enable-buildbot" + env: LDFLAGS="-fuse-ld=gold" CONFIGURE_FLAGS="--enable-debug --enable-sanitize=full CC=gcc-5 --disable-manager --enable-Werror --enable-packetver=20181017 --enable-packetver-re --enable-buildbot" addons: apt: sources: @@ -110,7 +110,7 @@ matrix: packages: - gcc-5 - compiler: gcc - env: LDFLAGS="-fuse-ld=gold" CONFIGURE_FLAGS="--enable-debug --enable-sanitize=full CC=gcc-6 --disable-manager --enable-Werror --enable-packetver=20180919 --enable-packetver-re --enable-buildbot" + env: LDFLAGS="-fuse-ld=gold" CONFIGURE_FLAGS="--enable-debug --enable-sanitize=full CC=gcc-6 --disable-manager --enable-Werror --enable-packetver=20181017 --enable-packetver-re --enable-buildbot" addons: apt: sources: diff --git a/conf/map/battle/items.conf b/conf/map/battle/items.conf index 144e04ea4..e834b80f6 100644 --- a/conf/map/battle/items.conf +++ b/conf/map/battle/items.conf @@ -123,3 +123,11 @@ boarding_halter_speed: 25 // Allow to use items when the storage is open? // Official: false (Default) storage_use_item: false + +// Minimum item buy price at shop +// Default: 1 +min_item_buy_price: 1 + +// Minimum item sell price at shop +// Default: 0 +min_item_sell_price: 0 diff --git a/conf/map/battle/skill.conf b/conf/map/battle/skill.conf index d258567a0..64bba68b5 100644 --- a/conf/map/battle/skill.conf +++ b/conf/map/battle/skill.conf @@ -307,6 +307,12 @@ dancing_weaponswitch_fix: true // 1: Traps in GvG make player stop moving right when stepping over it. skill_trap_type: 0 +// Trap Reflect +// Whether the damage from traps must be reflected (for example by Reflect Shield or High Orc Card)? +// true: Aegis - traps are reflected +// false: Athena - traps are not reflected +trap_reflect: true + // Max Possible Level of Monster skills // Note: If your MVPs are too tough, reduce it to 10. mob_max_skilllvl: 100 diff --git a/db/pre-re/skill_db.conf b/db/pre-re/skill_db.conf index 4873012aa..21a0f0e78 100644 --- a/db/pre-re/skill_db.conf +++ b/db/pre-re/skill_db.conf @@ -4299,6 +4299,7 @@ skill_db: ( Element: "Ele_Wind" DamageType: { SplashArea: true + SplitDamage: true IgnoreFlee: true } SplashRange: 1 @@ -4350,6 +4351,7 @@ skill_db: ( Element: "Ele_Fire" DamageType: { SplashArea: true + SplitDamage: true IgnoreFlee: true } SplashRange: 2 diff --git a/db/re/skill_db.conf b/db/re/skill_db.conf index 4863e4051..ec8548ab2 100644 --- a/db/re/skill_db.conf +++ b/db/re/skill_db.conf @@ -4520,6 +4520,7 @@ skill_db: ( Element: "Ele_Wind" DamageType: { SplashArea: true + SplitDamage: true IgnoreFlee: true } SplashRange: 1 @@ -4572,6 +4573,7 @@ skill_db: ( Element: "Ele_Fire" DamageType: { SplashArea: true + SplitDamage: true IgnoreFlee: true } SplashRange: 2 diff --git a/doc/constants.md b/doc/constants.md index 451f2a5fe..b85dd9768 100644 --- a/doc/constants.md +++ b/doc/constants.md @@ -4278,6 +4278,7 @@ - `ITEMINFO_VIEWID`: 14 - `ITEMINFO_MATK`: 15 - `ITEMINFO_VIEWSPRITE`: 16 +- `ITEMINFO_TRADE`: 17 ### monster skill states @@ -4367,6 +4368,7 @@ - `QINFO_HOMUN_LEVEL`: 5 - `QINFO_HOMUN_TYPE`: 6 - `QINFO_QUEST`: 7 +- `QINFO_MERCENARY_CLASS`: 8 ### function types @@ -4375,6 +4377,20 @@ - `FUNCTION_IS_LOCAL`: 3 - `FUNCTION_IS_LABEL`: 4 +### item trade restrictions + +- `ITR_NONE`: 0 +- `ITR_NODROP`: 1 +- `ITR_NOTRADE`: 2 +- `ITR_PARTNEROVERRIDE`: 4 +- `ITR_NOSELLTONPC`: 8 +- `ITR_NOCART`: 16 +- `ITR_NOSTORAGE`: 32 +- `ITR_NOGSTORAGE`: 64 +- `ITR_NOMAIL`: 128 +- `ITR_NOAUCTION`: 256 +- `ITR_ALL`: 511 + ### Renewal - `RENEWAL`: 1 diff --git a/doc/global_configuration.md b/doc/global_configuration.md new file mode 100644 index 000000000..b0e99e698 --- /dev/null +++ b/doc/global_configuration.md @@ -0,0 +1,65 @@ +# Global configuration reference + +## What is global configuration? + +Global configuration is an import system that allows configuration files to be +shared between servers (login, char, map), but can also be used independently +in each server. + + +## How does it work? + +It works by using the `@include` directive from libconfig: + +> "A configuration file may "include" the contents of another file using an +> include directive. This directive has the effect of inlining the contents of +> the named file at the point of inclusion. + +An include directive must appear on its own line and takes this form: + +``` + @include "filename" +``` + +Any backslashes or double quotes in the filename must be escaped as `\\` and +`\"`, respectively. + + +## How do I stop using global configurations? + +To stop using global configuration, all you have to do is copy the contents of +the file being imported and paste it _exactly_ where the include directive was. + +### Example + +If you want map server and char server to have their own separate SQL connection +settings, you would search in `conf/map/map-server.conf` and +`conf/char/char-server.conf` for this line: + +``` + @include "conf/global/sql_connection.conf" +``` + +And replace it with: + +``` + sql_connection: { + // [INTER] You can specify the codepage to use in your mySQL tables here. + // (Note that this feature requires MySQL 4.1+) + //default_codepage: "" + + // [LOGIN] Is `userid` in account_db case sensitive? + //case_sensitive: false + + // For IPs, ideally under linux, you want to use localhost instead of 127.0.0.1. + // Under windows, you want to use 127.0.0.1. If you see a message like + // "Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)" + // and you have localhost, switch it to 127.0.0.1 + db_hostname: "127.0.0.1" + db_port: 3306 + db_username: "ragnarok" + db_password: "ragnarok" + db_database: "ragnarok" + //codepage:"" + } +``` diff --git a/doc/global_configuration.txt b/doc/global_configuration.txt deleted file mode 100644 index a000a4572..000000000 --- a/doc/global_configuration.txt +++ /dev/null @@ -1,69 +0,0 @@ -//===== Hercules Documentation =============================== -//= Global configuration reference -//===== By: ================================================== -//= Panikon (Hercules Dev. Team) -//===== Current Version: ===================================== -//= 20140616 -//===== Description: ========================================= -//= Global configurations found in conf/global/ -//============================================================ - -- What are global configurations? - -Global configurations are configurations that can be shared between servers, -but can also be set independently in each server. - -- How do they work? - -They work by using an include system that is available with libconfig: - - "A configuration file may "include" the contents of another file using an - include directive. This directive has the effect of inlining the contents of - the named file at the point of inclusion. - - An include directive must appear on its own line in the input. It has the - form: - - @include "filename" - - Any backslashes or double quotes in the filename must be escaped as '\\' and - '\"', respectively." - From libconfig's documentation - -So each file that is included is actually inside each one of the main -configuration files and thus a change in the first will be a change in the -latter. -Note: the @include directive is read by the server executable, so any path -should be from were it is and NOT from where the main configuration file is! - -- How do I stop using global configurations? - -To stop using global configurations is very simple, all you have to do is copy -the contents that are inside the global configuration file and put them -_exactly_ where the include directive were in the main configuration file. - -E.g. - Find in any file: - @include "conf/global/sql_connection.conf" - Replace it with: - sql_connection: { - // [INTER] You can specify the codepage to use in your mySQL tables here. - // (Note that this feature requires MySQL 4.1+) - //default_codepage: "" - - // [LOGIN] Is `userid` in account_db case sensitive? - //case_sensitive: false - - // For IPs, ideally under linux, you want to use localhost instead of 127.0.0.1 - // Under windows, you want to use 127.0.0.1. If you see a message like - // "Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)" - // and you have localhost, switch it to 127.0.0.1 - db_hostname: "127.0.0.1" - db_port: 3306 - db_username: "ragnarok" - db_password: "ragnarok" - db_database: "ragnarok" - //codepage:"" - } - If the main configuration file belongs to the map server, for instance, you - don't need to include default_codepage and case_sensitive. diff --git a/doc/sample/getiteminfo.txt b/doc/sample/getiteminfo.txt index 57407c072..9d5121635 100644 --- a/doc/sample/getiteminfo.txt +++ b/doc/sample/getiteminfo.txt @@ -9,12 +9,12 @@ //============================================================ prontera,156,179,6 script test_getiteminfo 4_F_KAFRA1,{ - mes "Please enter an item ID."; - input .@value; + mes("Please enter an item ID."); + input(.@value); // This line uses an INTERNAL function of your client to show item name by its ID! // ^nItemID^XXXX -> Item Name - mes "Item ID: "+.@value+" ^nItemID^"+.@value; + mesf("Item ID: %d ^nItemID^%d", .@value, .@value); mes("Current item info:"); mesf("Buy Price: %d", getiteminfo(.@value, ITEMINFO_BUYPRICE)); @@ -34,5 +34,8 @@ prontera,156,179,6 script test_getiteminfo 4_F_KAFRA1,{ mesf("View ID: %d", getiteminfo(.@value, ITEMINFO_VIEWID)); mesf("MATK: %d", getiteminfo(.@value, ITEMINFO_MATK)); mesf("View Sprite: %d", getiteminfo(.@value, ITEMINFO_VIEWSPRITE)); + + .@trade$ = callfunc("F_GetTradeRestriction", .@value); + mesf("Trade Restriction: %s", .@trade$); close; } diff --git a/doc/script_commands.txt b/doc/script_commands.txt index 64468ed49..4812a2cf2 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -3239,6 +3239,7 @@ Valid types are: ITEMINFO_VIEWID - View ID ("Sprite" field in the Item DB) ITEMINFO_MATK - MATK (only relevant if RENEWAL is set) ITEMINFO_VIEWSPRITE - View Sprite ("ViewSprite" field in the Item DB) + ITEMINFO_TRADE - Trade Restriction (see "doc/constant.md": item trade restriction) Check sample in doc/sample/getiteminfo.txt @@ -9429,6 +9430,7 @@ supported types: values QINFO_HOMUN_LEVEL: min QINFO_HOMUN_TYPE: homunculus_type (0 - regular, 1 - evolved, 2 - S) QINFO_QUEST: quest_id, state // append to the quests list on each use + QINFO_MERCENARY_CLASS: mercenary_class --------------------------------------- @@ -10199,3 +10201,25 @@ camera. Works for 20160525 clients or newer. --------------------------------------- + +*achievement_progress(<ach_id>, <obj_idx>, <progress>, <incremental>{, <account_id>}); + +Make the player progress in the specified achievement. +aid - achievement ID +obj_idx - achievement objective index. +progress - objective progress towards goal. +incremental - (boolean) true to add the progress towards the goal, + false to use the progress only as a comparand. +account_id - (optional) AID to perform on (default to attached player). + +returns progress on success and false on failure + +--------------------------------------- + +*itempreview(<index>) + +Update already opened preview window with item from + inventory with given index. +Works for 20181017 RE and main clients or newer. + +--------------------------------------- diff --git a/npc/other/Global_Functions.txt b/npc/other/Global_Functions.txt index 9882e9d71..904ed7165 100644 --- a/npc/other/Global_Functions.txt +++ b/npc/other/Global_Functions.txt @@ -438,3 +438,40 @@ function script F_ShuffleNumbers { function script F_MesColor { return sprintf("^%06X", min(getarg(0), 0xFFFFFF)); } + +//== Function F_GetTradeRestriction ======================== +// Function to get item trade restriction +// Examples: +// mes "Red Potion Restriction: "+ callfunc("F_GetTradeRestriction", Red_Potion); +function script F_GetTradeRestriction { + .@trade = getiteminfo(getarg(0), ITEMINFO_TRADE); + + if (.@trade == 0) { + return "None"; + } + .@trade$ = ""; + if (.@trade & ITR_NODROP) { + .@trade$ += "NoDrop|"; + } + if (.@trade & ITR_NOTRADE) { + .@trade$ += "NoTrade|"; + } + if (.@trade & ITR_PARTNEROVERRIDE) { + .@trade$ += "PartnerOverride|"; + } + if (.@trade & ITR_NOSELLTONPC) { + .@trade$ += "NoSellToNpc|"; + } + if (.@trade & ITR_NOSTORAGE) { + .@trade$ += "NoStorage|"; + } + if (.@trade & ITR_NOGSTORAGE) { + .@trade$ += "NoGuildStorage|"; + } + if (.@trade & ITR_NOMAIL) { + .@trade$ += "NoMail|"; + } + if (.@trade & ITR_NOAUCTION) { + .@trade$ += "NoAuction|"; + } +} diff --git a/src/common/HPMDataCheck.h b/src/common/HPMDataCheck.h index 21b90ee50..eed35aabf 100644 --- a/src/common/HPMDataCheck.h +++ b/src/common/HPMDataCheck.h @@ -677,6 +677,7 @@ HPExport const struct s_HPMDataCheck HPMDataCheck[] = { { "PACKET_ZC_INVENTORY_MOVE_FAILED", sizeof(struct PACKET_ZC_INVENTORY_MOVE_FAILED), SERVER_TYPE_MAP }, { "PACKET_ZC_ITEM_ENTRY", sizeof(struct PACKET_ZC_ITEM_ENTRY), SERVER_TYPE_MAP }, { "PACKET_ZC_ITEM_PICKUP_PARTY", sizeof(struct PACKET_ZC_ITEM_PICKUP_PARTY), SERVER_TYPE_MAP }, + { "PACKET_ZC_ITEM_PREVIEW", sizeof(struct PACKET_ZC_ITEM_PREVIEW), SERVER_TYPE_MAP }, { "PACKET_ZC_MAIL_LIST", sizeof(struct PACKET_ZC_MAIL_LIST), SERVER_TYPE_MAP }, { "PACKET_ZC_MAKABLEITEMLIST", sizeof(struct PACKET_ZC_MAKABLEITEMLIST), SERVER_TYPE_MAP }, { "PACKET_ZC_MAKABLEITEMLIST_sub", sizeof(struct PACKET_ZC_MAKABLEITEMLIST_sub), SERVER_TYPE_MAP }, diff --git a/src/common/mmo.h b/src/common/mmo.h index d6946cecc..9bcf82cc7 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -1331,7 +1331,8 @@ enum questinfo_type { QINFO_ITEM, QINFO_HOMUN_LEVEL, QINFO_HOMUN_TYPE, - QINFO_QUEST + QINFO_QUEST, + QINFO_MERCENARY_CLASS }; /* packet size constant for itemlist */ diff --git a/src/map/achievement.c b/src/map/achievement.c index 68fc8a983..7148acae8 100644 --- a/src/map/achievement.c +++ b/src/map/achievement.c @@ -772,6 +772,10 @@ static void achievement_validate_refine(struct map_session_data *sd, unsigned in criteria.goal = sd->status.inventory[idx].refine; + // achievement should not trigger if refine is 0 + if (criteria.goal == 0) + return; + /* Universal */ achievement->validate_type(sd, success ? ACH_EQUIP_REFINE_SUCCESS : ACH_EQUIP_REFINE_FAILURE, diff --git a/src/map/atcommand.c b/src/map/atcommand.c index a7dc5dd95..809a740d7 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -1776,18 +1776,7 @@ ACMD(bodystyle) memset(atcmd_output, '\0', sizeof(atcmd_output)); - if ((sd->job & MAPID_THIRDMASK) != MAPID_GUILLOTINE_CROSS - && (sd->job & MAPID_THIRDMASK) != MAPID_GENETIC - && (sd->job & MAPID_THIRDMASK) != MAPID_MECHANIC - && (sd->job & MAPID_THIRDMASK) != MAPID_ROYAL_GUARD - && (sd->job & MAPID_THIRDMASK) != MAPID_ARCH_BISHOP - && (sd->job & MAPID_THIRDMASK) != MAPID_RANGER - && (sd->job & MAPID_THIRDMASK) != MAPID_WARLOCK - && (sd->job & MAPID_THIRDMASK) != MAPID_SHADOW_CHASER - && (sd->job & MAPID_THIRDMASK) != MAPID_MINSTRELWANDERER - && (sd->job & MAPID_THIRDMASK) != MAPID_SORCERER - && (sd->job & MAPID_THIRDMASK) != MAPID_SURA - ) { + if (!pc->has_second_costume(sd)) { clif->message(fd, msg_fd(fd, 35)); // This job has no alternate body styles. return false; } diff --git a/src/map/battle.c b/src/map/battle.c index fceb30be1..44241bf23 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -4339,6 +4339,8 @@ static struct Damage battle_calc_misc_attack(struct block_list *src, struct bloc } break; } + + battle->reflect_trap(target, src, &md, skill_id); return md; } @@ -6008,6 +6010,37 @@ static void battle_reflect_damage(struct block_list *target, struct block_list * #undef NORMALIZE_RDAMAGE } +/** + * Reflects damage from certain traps, if battle_config.trap_reflect is true. + * @param target : Player who triggered the trap + * @param src : Player who set the trap + * @param md : Trap damage structure + * @param skill_id : Trap skill ID + */ +static void battle_reflect_trap(struct block_list *target, struct block_list *src, struct Damage *md, uint16 skill_id) +{ + if (battle_config.trap_reflect == true) { + if (src != target) { // Don't reflect your own damage + switch (skill_id) { + case HT_CLAYMORETRAP: + case HT_LANDMINE: + case HT_FREEZINGTRAP: + case HT_BLASTMINE: + // Needs official info + //case RA_CLUSTERBOMB: + //case RA_FIRINGTRAP: + //case RA_ICEBOUNDTRAP: + //case GN_THORNS_TRAP: + //case KO_MAKIBISHI: + case MA_LANDMINE: + case MA_FREEZINGTRAP: + battle->reflect_damage(target, src, md, skill_id); + break; + } + } + } +} + static void battle_drain(struct map_session_data *sd, struct block_list *tbl, int64 rdamage, int64 ldamage, int race, int boss) { struct weapon_data *wd; @@ -7325,6 +7358,7 @@ static const struct battle_data { * Hercules **/ { "skill_trap_type", &battle_config.skill_trap_type, 0, 0, 1, }, + { "trap_reflect", &battle_config.trap_reflect, 1, 0, 1, }, { "item_restricted_consumption_type", &battle_config.item_restricted_consumption_type,1, 0, 1, }, { "unequip_restricted_equipment", &battle_config.unequip_restricted_equipment, 0, 0, 3, }, { "max_walk_path", &battle_config.max_walk_path, 17, 1, MAX_WALKPATH, }, @@ -7371,6 +7405,8 @@ static const struct battle_data { { "storage_use_item", &battle_config.storage_use_item, 0, 0, 1, }, { "features/enable_attendance_system", &battle_config.feature_enable_attendance_system,1, 0, 1, }, { "features/feature_attendance_endtime",&battle_config.feature_attendance_endtime, 1, 0, 99999999, }, + { "min_item_buy_price", &battle_config.min_item_buy_price, 1, 0, INT_MAX, }, + { "min_item_sell_price", &battle_config.min_item_sell_price, 0, 0, INT_MAX, }, }; static bool battle_set_value_sub(int index, int value) @@ -7614,6 +7650,7 @@ void battle_defaults(void) battle->delay_damage = battle_delay_damage; battle->drain = battle_drain; battle->reflect_damage = battle_reflect_damage; + battle->reflect_trap = battle_reflect_trap; battle->attr_ratio = battle_attr_ratio; battle->attr_fix = battle_attr_fix; battle->calc_cardfix = battle_calc_cardfix; diff --git a/src/map/battle.h b/src/map/battle.h index 9f5207e95..02536e4a1 100644 --- a/src/map/battle.h +++ b/src/map/battle.h @@ -506,6 +506,7 @@ struct Battle_Config { /** Hercules **/ int skill_trap_type; + int trap_reflect; int item_restricted_consumption_type; int unequip_restricted_equipment; int max_walk_path; @@ -570,6 +571,9 @@ struct Battle_Config { int feature_enable_attendance_system; int feature_attendance_endtime; + + int min_item_buy_price; + int min_item_sell_price; }; /* criteria for battle_config.idletime_critera */ @@ -636,6 +640,8 @@ struct battle_interface { void (*drain) (struct map_session_data *sd, struct block_list *tbl, int64 rdamage, int64 ldamage, int race, int boss); /* damage reflect */ void (*reflect_damage) (struct block_list *target, struct block_list *src, struct Damage *wd,uint16 skill_id); + /* trap reflect */ + void(*reflect_trap) (struct block_list *target, struct block_list *src, struct Damage *md, uint16 skill_id); /* attribute rate */ int (*attr_ratio) (int atk_elem, int def_type, int def_lv); /* applies attribute modifiers */ diff --git a/src/map/clif.c b/src/map/clif.c index 1e9844f14..62b9a4ca9 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -8872,7 +8872,7 @@ static void clif_specialeffect_value(struct block_list *bl, int effect_id, int n /// @see doc/effect_list.txt static void clif_removeSpecialEffect(struct block_list *bl, int effectId, enum send_target target) { -#if PACKETVER_MAIN_NUM >= 20181002 || PACKETVER_RE_NUM >= 20181002 +#if PACKETVER_MAIN_NUM >= 20181002 || PACKETVER_RE_NUM >= 20181002 || PACKETVER_ZERO_NUM >= 20181010 nullpo_retv(bl); struct PACKET_ZC_REMOVE_EFFECT p; @@ -8891,7 +8891,7 @@ static void clif_removeSpecialEffect(struct block_list *bl, int effectId, enum s static void clif_removeSpecialEffect_single(struct block_list *bl, int effectId, struct block_list *targetBl) { -#if PACKETVER_MAIN_NUM >= 20181002 || PACKETVER_RE_NUM >= 20181002 +#if PACKETVER_MAIN_NUM >= 20181002 || PACKETVER_RE_NUM >= 20181002 || PACKETVER_ZERO_NUM >= 20181010 nullpo_retv(bl); nullpo_retv(targetBl); @@ -16872,7 +16872,11 @@ static void clif_quest_send_list(struct map_session_data *sd) real_len += sizeof(info->objectives[j]); mob_data = mob->db(qi->objectives[j].mob); -#if PACKETVER >= 20150513 +#if PACKETVER_ZERO_NUM >= 20181010 || PACKETVER >= 20181017 + info->objectives[j].huntIdent = sd->quest_log[i].quest_id; + info->objectives[j].huntIdent2 = j; + info->objectives[j].mobType = 0; // Info Needed +#elif PACKETVER >= 20150513 info->objectives[j].huntIdent = (sd->quest_log[i].quest_id * 1000) + j; info->objectives[j].mobType = 0; // Info Needed #endif @@ -16961,7 +16965,11 @@ static void clif_quest_add(struct map_session_data *sd, struct quest *qd) monster = mob->db(qi->objectives[i].mob); -#if PACKETVER >= 20150513 +#if PACKETVER_ZERO_NUM >= 20181010 || PACKETVER >= 20181017 + packet->objectives[i].huntIdent = qd->quest_id; + packet->objectives[i].huntIdent2 = i; + packet->objectives[i].mobType = 0; // Info Needed +#elif PACKETVER >= 20150513 packet->objectives[i].huntIdent = (qd->quest_id * 1000) + i; packet->objectives[i].mobType = 0; // Info Needed #endif @@ -17022,7 +17030,10 @@ static void clif_quest_update_objective(struct map_session_data *sd, struct ques real_len += sizeof(packet->objectives[i]); packet->objectives[i].questID = qd->quest_id; -#if PACKETVER >= 20150513 +#if PACKETVER_ZERO_NUM >= 20181010 || PACKETVER >= 20181017 + packet->objectives[i].huntIdent = qd->quest_id; + packet->objectives[i].huntIdent2 = i; +#elif PACKETVER >= 20150513 packet->objectives[i].huntIdent = (qd->quest_id * 1000) + i; #else packet->objectives[i].mob_id = qi->objectives[i].mob; @@ -21925,6 +21936,7 @@ static void clif_parse_memorial_dungeon_command(int fd, struct map_session_data static void clif_camera_showWindow(struct map_session_data *sd) { #if PACKETVER >= 20160525 + nullpo_retv(sd); struct PACKET_ZC_CAMERA_INFO p; p.packetType = 0xa78; p.action = 1; @@ -21938,6 +21950,7 @@ static void clif_camera_showWindow(struct map_session_data *sd) static void clif_camera_change(struct map_session_data *sd, float range, float rotation, float latitude, enum send_target target) { #if PACKETVER >= 20160525 + nullpo_retv(sd); struct PACKET_ZC_CAMERA_INFO p; p.packetType = 0xa78; p.action = 0; @@ -21948,6 +21961,26 @@ static void clif_camera_change(struct map_session_data *sd, float range, float r #endif } +// show item preview in already opened preview window +static void clif_item_preview(struct map_session_data *sd, int n) +{ +#if PACKETVER_MAIN_NUM >= 20170726 || PACKETVER_RE_NUM >= 20170621 || defined(PACKETVER_ZERO) + nullpo_retv(sd); + Assert_retv(n >= 0 && n < MAX_INVENTORY); + + struct PACKET_ZC_ITEM_PREVIEW p; + p.packetType = itemPreview; + p.index = n + 2; +#if PACKETVER_MAIN_NUM >= 20181017 || PACKETVER_RE_NUM >= 20181017 + p.isDamaged = (sd->status.inventory[n].attribute & ATTR_BROKEN) != 0 ? 1 : 0; +#endif + p.refiningLevel = sd->status.inventory[n].refine; + clif->addcards(&p.slot, &sd->status.inventory[n]); + clif->add_item_options(&p.option_data[0], &sd->status.inventory[n]); + clif->send(&p, sizeof(p), &sd->bl, SELF); +#endif +} + /*========================================== * Main client packet processing function *------------------------------------------*/ @@ -23114,6 +23147,7 @@ void clif_defaults(void) clif->camera_showWindow = clif_camera_showWindow; clif->camera_change = clif_camera_change; + clif->item_preview = clif_item_preview; // -- Pet Evolution clif->pPetEvolution = clif_parse_pet_evolution; diff --git a/src/map/clif.h b/src/map/clif.h index 13c34c77d..b76c5ed70 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -1554,6 +1554,7 @@ struct clif_interface { void (*pMemorialDungeonCommand) (int fd, struct map_session_data *sd); void (*camera_showWindow) (struct map_session_data *sd); void (*camera_change) (struct map_session_data *sd, float range, float rotation, float latitude, enum send_target target); + void (*item_preview) (struct map_session_data *sd, int n); }; #ifdef HERCULES_CORE diff --git a/src/map/map.h b/src/map/map.h index d50666d4b..cb025e9c1 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -815,6 +815,7 @@ struct questinfo { struct s_homunculus homunculus; int homunculus_type; VECTOR_DECL(struct questinfo_qreq) quest_requirement; + int mercenary_class; }; diff --git a/src/map/messages_zero.h b/src/map/messages_zero.h index c562bb07c..348bc00c8 100644 --- a/src/map/messages_zero.h +++ b/src/map/messages_zero.h @@ -23,7 +23,7 @@ /* This file is autogenerated, please do not commit manual changes -Latest version: 20180919 +Latest version: 20181010 */ enum clif_messages { @@ -13926,9 +13926,11 @@ DEATH : %.1f%% ( basic 100.0%% VIP Bonus %.1f%% + %s %.1f%%) DEATH: %.1f%% (Basic 100.0%% VIP Bonus %.1f%% + %s %.1f%%) */ MSG_ID_AFB = 0xafb, -/*20171018 to latest +/*20171018 to 20180928 해당 태그는 이름으로 사용하실 수 없습니다. Name with this tag cannot be used. +20181010 to latest + 해당 내용은 이름으로 사용하실 수 없습니다. */ MSG_ID_AFC = 0xafc, /*20171018 to latest diff --git a/src/map/packets.h b/src/map/packets.h index dc610ce2a..fb48d953b 100644 --- a/src/map/packets.h +++ b/src/map/packets.h @@ -4355,4 +4355,28 @@ packet(0x96e,-1,clif->ackmergeitems); // changed packet sizes #endif +// 2018-10-10_2aRagexe_zero +#if PACKETVER_ZERO_NUM >= 20181010 +// new packets + packet(0x0b10,10,clif->pDull/*,XXX*/); + packet(0x0b11,4,clif->pDull/*,XXX*/); +// changed packet sizes +#endif + +// 2018-10-17bRagexe +#if PACKETVER_MAIN_NUM >= 20181017 +// new packets + packet(0x0b12,2,clif->pDull/*,XXX*/); + packet(0x0b13,40); +// changed packet sizes +#endif + +// 2018-10-17bRagexeRE +#if PACKETVER_RE_NUM >= 20181017 +// new packets + packet(0x0b12,2,clif->pDull/*,XXX*/); + packet(0x0b13,48); +// changed packet sizes +#endif + #endif /* MAP_PACKETS_H */ diff --git a/src/map/packets_keys_main.h b/src/map/packets_keys_main.h index 03ece5d27..c94e44525 100644 --- a/src/map/packets_keys_main.h +++ b/src/map/packets_keys_main.h @@ -874,7 +874,7 @@ packetKeys(0x6A596301,0x76866D0E,0x32294A45); #endif -// 2013-12-23aRagexeRE, 2014-05-08aRagexe, 2014-05-08aRagexeRE, 2014-06-11eRagexe, 2015-02-25hRagexe, 2018-03-15aRagexe, 2018-03-21aRagexe, 2018-03-21aRagexeRE, 2018-03-28bRagexe, 2018-03-28bRagexeRE, 2018-04-04bRagexe, 2018-04-04cRagexeRE, 2018-04-18aRagexe, 2018-04-18bRagexeRE, 2018-04-25cRagexe, 2018-04-25cRagexeRE, 2018-05-02bRagexe, 2018-05-02bRagexeRE, 2018-05-02dRagexeRE, 2018-05-09aRagexe, 2018-05-16cRagexe, 2018-05-16cRagexeRE, 2018-05-23aRagexe, 2018-05-23aRagexeRE, 2018-05-30aRagexe, 2018-05-30bRagexeRE, 2018-05-30cRagexeRE, 2018-06-05bRagexe, 2018-06-05bRagexeRE, 2018-06-12aRagexeRE, 2018-06-12bRagexeRE, 2018-06-20cRagexe, 2018-06-20dRagexeRE, 2018-06-20eRagexe, 2018-06-20eRagexeRE, 2018-06-21aRagexe, 2018-06-21aRagexeRE, 2018-07-04aRagexe, 2018-07-04aRagexeRE, 2018-07-11aRagexeRE, 2018-07-18bRagexe, 2018-07-18bRagexeRE, 2018-07-18bRagexeRE1, 2018-07-18cRagexe, 2018-07-18cRagexeRE, 2018-08-01cRagexe, 2018-08-01cRagexeRE, 2018-08-08bRagexe, 2018-08-08bRagexeRE, 2018-08-22cRagexe, 2018-08-22cRagexeRE, 2018-08-29aRagexe, 2018-08-29aRagexeRE, 2018-08-29bRagexeRE, 2018-08-31aRagexe, 2018-09-12dRagexe, 2018-09-12dRagexeRE, 2018-09-19aRagexe, 2018-09-19aRagexeRE, 2018-10-02aRagexe, 2018-10-02aRagexeRE, 2018-10-02bRagexe, 2018-10-02bRagexeRE +// 2013-12-23aRagexeRE, 2014-05-08aRagexe, 2014-05-08aRagexeRE, 2014-06-11eRagexe, 2015-02-25hRagexe, 2018-03-15aRagexe, 2018-03-21aRagexe, 2018-03-21aRagexeRE, 2018-03-28bRagexe, 2018-03-28bRagexeRE, 2018-04-04bRagexe, 2018-04-04cRagexeRE, 2018-04-18aRagexe, 2018-04-18bRagexeRE, 2018-04-25cRagexe, 2018-04-25cRagexeRE, 2018-05-02bRagexe, 2018-05-02bRagexeRE, 2018-05-02dRagexeRE, 2018-05-09aRagexe, 2018-05-16cRagexe, 2018-05-16cRagexeRE, 2018-05-23aRagexe, 2018-05-23aRagexeRE, 2018-05-30aRagexe, 2018-05-30bRagexeRE, 2018-05-30cRagexeRE, 2018-06-05bRagexe, 2018-06-05bRagexeRE, 2018-06-12aRagexeRE, 2018-06-12bRagexeRE, 2018-06-20cRagexe, 2018-06-20dRagexeRE, 2018-06-20eRagexe, 2018-06-20eRagexeRE, 2018-06-21aRagexe, 2018-06-21aRagexeRE, 2018-07-04aRagexe, 2018-07-04aRagexeRE, 2018-07-11aRagexeRE, 2018-07-18bRagexe, 2018-07-18bRagexeRE, 2018-07-18bRagexeRE1, 2018-07-18cRagexe, 2018-07-18cRagexeRE, 2018-08-01cRagexe, 2018-08-01cRagexeRE, 2018-08-08bRagexe, 2018-08-08bRagexeRE, 2018-08-22cRagexe, 2018-08-22cRagexeRE, 2018-08-29aRagexe, 2018-08-29aRagexeRE, 2018-08-29bRagexeRE, 2018-08-31aRagexe, 2018-09-12dRagexe, 2018-09-12dRagexeRE, 2018-09-19aRagexe, 2018-09-19aRagexeRE, 2018-10-02aRagexe, 2018-10-02aRagexeRE, 2018-10-02bRagexe, 2018-10-02bRagexeRE, 2018-10-17bRagexe, 2018-10-17bRagexeRE #if PACKETVER == 20131223 || \ PACKETVER == 20140508 || \ PACKETVER == 20140611 || \ @@ -904,7 +904,8 @@ PACKETVER == 20180831 || \ PACKETVER == 20180912 || \ PACKETVER == 20180919 || \ - PACKETVER >= 20181002 + PACKETVER == 20181002 || \ + PACKETVER >= 20181017 packetKeys(0x00000000,0x00000000,0x00000000); #endif diff --git a/src/map/packets_keys_zero.h b/src/map/packets_keys_zero.h index 1b6cd537c..2d1f35e94 100644 --- a/src/map/packets_keys_zero.h +++ b/src/map/packets_keys_zero.h @@ -29,7 +29,7 @@ /* This file is autogenerated, please do not commit manual changes */ -// 2017-10-18aRagexe_zero, 2017-10-19aRagexe_zero, 2017-10-23aRagexe_zero, 2017-10-23bRagexe_zero, 2017-10-23cRagexe_zero, 2017-10-24aRagexe_2_zero, 2017-10-24aRagexe_zero, 2017-10-25bRagexe_zero, 2017-10-27aRagexe_zero, 2017-10-27bRagexe_zero, 2017-10-30aRagexe_zero, 2017-10-31aRagexe_zero, 2017-11-09aRagexe_zero, 2017-11-13aRagexe_zero, 2017-11-13bRagexe_zero, 2018-03-15aRagexe_zero, 2018-03-21aRagexe_zero, 2018-03-21bRagexe_zero, 2018-03-28_1aRagexe_zero, 2018-03-28cRagexe_zero, 2018-04-11aRagexe_zero, 2018-04-25_3aRagexe_zero, 2018-05-09_3aRagexe_zero, 2018-05-23aRagexe_zero, 2018-06-05bRagexe_zero, 2018-06-05cRagexe_zero, 2018-06-27aRagexe_zero, 2018-07-03aRagexe_zero, 2018-07-11_2aRagexe_zero, 2018-07-25_2aRagexe_zero, 2018-08-01aRagexe_zero, 2018-08-08_2aRagexe_zero, 2018-08-22aRagexe_zero, 2018-08-29aRagexe_zero, 2018-09-05aRagexe_zero, 2018-09-12aRagexe_zero, 2018-09-19aRagexe_zero, 2018-09-28aRagexe_zero +// 2017-10-18aRagexe_zero, 2017-10-19aRagexe_zero, 2017-10-23aRagexe_zero, 2017-10-23bRagexe_zero, 2017-10-23cRagexe_zero, 2017-10-24aRagexe_2_zero, 2017-10-24aRagexe_zero, 2017-10-25bRagexe_zero, 2017-10-27aRagexe_zero, 2017-10-27bRagexe_zero, 2017-10-30aRagexe_zero, 2017-10-31aRagexe_zero, 2017-11-09aRagexe_zero, 2017-11-13aRagexe_zero, 2017-11-13bRagexe_zero, 2018-03-15aRagexe_zero, 2018-03-21aRagexe_zero, 2018-03-21bRagexe_zero, 2018-03-28_1aRagexe_zero, 2018-03-28cRagexe_zero, 2018-04-11aRagexe_zero, 2018-04-25_3aRagexe_zero, 2018-05-09_3aRagexe_zero, 2018-05-23aRagexe_zero, 2018-06-05bRagexe_zero, 2018-06-05cRagexe_zero, 2018-06-27aRagexe_zero, 2018-07-03aRagexe_zero, 2018-07-11_2aRagexe_zero, 2018-07-25_2aRagexe_zero, 2018-08-01aRagexe_zero, 2018-08-08_2aRagexe_zero, 2018-08-22aRagexe_zero, 2018-08-29aRagexe_zero, 2018-09-05aRagexe_zero, 2018-09-12aRagexe_zero, 2018-09-19aRagexe_zero, 2018-09-28aRagexe_zero, 2018-10-10_2aRagexe_zero #if PACKETVER == 20171018 || \ PACKETVER == 20171019 || \ PACKETVER == 20171023 || \ @@ -59,7 +59,8 @@ PACKETVER == 20180905 || \ PACKETVER == 20180912 || \ PACKETVER == 20180919 || \ - PACKETVER >= 20180928 + PACKETVER == 20180928 || \ + PACKETVER >= 20181010 packetKeys(0x00000000,0x00000000,0x00000000); #endif diff --git a/src/map/packets_shuffle_main.h b/src/map/packets_shuffle_main.h index 53bdfa59d..32396ad99 100644 --- a/src/map/packets_shuffle_main.h +++ b/src/map/packets_shuffle_main.h @@ -3344,7 +3344,7 @@ packet(0x0969,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE #endif -// 2014-06-11eRagexe, 2015-02-25hRagexe, 2018-03-15aRagexe, 2018-03-21aRagexe, 2018-03-28bRagexe, 2018-04-04bRagexe, 2018-04-18aRagexe, 2018-04-25cRagexe, 2018-05-02bRagexe, 2018-05-09aRagexe, 2018-05-16cRagexe, 2018-05-23aRagexe, 2018-05-30aRagexe, 2018-06-05bRagexe, 2018-06-20cRagexe, 2018-06-20eRagexe, 2018-06-21aRagexe, 2018-07-04aRagexe, 2018-07-18bRagexe, 2018-07-18cRagexe, 2018-08-01cRagexe, 2018-08-08bRagexe, 2018-08-22cRagexe, 2018-08-29aRagexe, 2018-08-31aRagexe, 2018-09-12dRagexe, 2018-09-19aRagexe, 2018-10-02aRagexe, 2018-10-02bRagexe +// 2014-06-11eRagexe, 2015-02-25hRagexe, 2018-03-15aRagexe, 2018-03-21aRagexe, 2018-03-28bRagexe, 2018-04-04bRagexe, 2018-04-18aRagexe, 2018-04-25cRagexe, 2018-05-02bRagexe, 2018-05-09aRagexe, 2018-05-16cRagexe, 2018-05-23aRagexe, 2018-05-30aRagexe, 2018-06-05bRagexe, 2018-06-20cRagexe, 2018-06-20eRagexe, 2018-06-21aRagexe, 2018-07-04aRagexe, 2018-07-18bRagexe, 2018-07-18cRagexe, 2018-08-01cRagexe, 2018-08-08bRagexe, 2018-08-22cRagexe, 2018-08-29aRagexe, 2018-08-31aRagexe, 2018-09-12dRagexe, 2018-09-19aRagexe, 2018-10-02aRagexe, 2018-10-02bRagexe, 2018-10-17bRagexe #if PACKETVER == 20140611 || \ PACKETVER == 20150225 || \ PACKETVER == 20180315 || \ @@ -3370,7 +3370,8 @@ PACKETVER == 20180831 || \ PACKETVER == 20180912 || \ PACKETVER == 20180919 || \ - PACKETVER >= 20181002 + PACKETVER == 20181002 || \ + PACKETVER >= 20181017 packet(0x0202,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS packet(0x022d,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER packet(0x023b,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD diff --git a/src/map/packets_shuffle_re.h b/src/map/packets_shuffle_re.h index e77b97cac..bf44faa7c 100644 --- a/src/map/packets_shuffle_re.h +++ b/src/map/packets_shuffle_re.h @@ -9662,7 +9662,7 @@ packet(0x083c,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK #endif -// 2018-07-04aRagexeRE, 2018-07-11aRagexeRE, 2018-07-18bRagexeRE, 2018-07-18bRagexeRE1, 2018-07-18cRagexeRE, 2018-08-01cRagexeRE, 2018-08-08bRagexeRE, 2018-08-22cRagexeRE, 2018-08-29aRagexeRE, 2018-08-29bRagexeRE, 2018-09-12dRagexeRE, 2018-09-19aRagexeRE, 2018-10-02aRagexeRE, 2018-10-02bRagexeRE +// 2018-07-04aRagexeRE, 2018-07-11aRagexeRE, 2018-07-18bRagexeRE, 2018-07-18bRagexeRE1, 2018-07-18cRagexeRE, 2018-08-01cRagexeRE, 2018-08-08bRagexeRE, 2018-08-22cRagexeRE, 2018-08-29aRagexeRE, 2018-08-29bRagexeRE, 2018-09-12dRagexeRE, 2018-09-19aRagexeRE, 2018-10-02aRagexeRE, 2018-10-02bRagexeRE, 2018-10-17bRagexeRE #if PACKETVER == 20180704 || \ PACKETVER == 20180711 || \ PACKETVER == 20180718 || \ @@ -9672,7 +9672,8 @@ PACKETVER == 20180829 || \ PACKETVER == 20180912 || \ PACKETVER == 20180919 || \ - PACKETVER >= 20181002 + PACKETVER == 20181002 || \ + PACKETVER >= 20181017 packet(0x0202,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS packet(0x022d,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER packet(0x023b,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD diff --git a/src/map/packets_shuffle_zero.h b/src/map/packets_shuffle_zero.h index fedefbe3d..db83c0ba0 100644 --- a/src/map/packets_shuffle_zero.h +++ b/src/map/packets_shuffle_zero.h @@ -36,7 +36,7 @@ /* This file is autogenerated, please do not commit manual changes */ -// 2017-10-18aRagexe_zero, 2017-10-19aRagexe_zero, 2017-10-23aRagexe_zero, 2017-10-23bRagexe_zero, 2017-10-23cRagexe_zero, 2017-10-24aRagexe_2_zero, 2017-10-24aRagexe_zero, 2017-10-25bRagexe_zero, 2017-10-27aRagexe_zero, 2017-10-27bRagexe_zero, 2017-10-30aRagexe_zero, 2017-10-31aRagexe_zero, 2017-11-09aRagexe_zero, 2017-11-13aRagexe_zero, 2017-11-13bRagexe_zero, 2018-03-15aRagexe_zero, 2018-03-21aRagexe_zero, 2018-03-21bRagexe_zero, 2018-03-28_1aRagexe_zero, 2018-03-28cRagexe_zero, 2018-04-11aRagexe_zero, 2018-04-25_3aRagexe_zero, 2018-05-09_3aRagexe_zero, 2018-05-23aRagexe_zero, 2018-06-05bRagexe_zero, 2018-06-05cRagexe_zero, 2018-06-27aRagexe_zero, 2018-07-03aRagexe_zero, 2018-07-11_2aRagexe_zero, 2018-07-25_2aRagexe_zero, 2018-08-01aRagexe_zero, 2018-08-08_2aRagexe_zero, 2018-08-22aRagexe_zero, 2018-08-29aRagexe_zero, 2018-09-05aRagexe_zero, 2018-09-12aRagexe_zero, 2018-09-19aRagexe_zero, 2018-09-28aRagexe_zero +// 2017-10-18aRagexe_zero, 2017-10-19aRagexe_zero, 2017-10-23aRagexe_zero, 2017-10-23bRagexe_zero, 2017-10-23cRagexe_zero, 2017-10-24aRagexe_2_zero, 2017-10-24aRagexe_zero, 2017-10-25bRagexe_zero, 2017-10-27aRagexe_zero, 2017-10-27bRagexe_zero, 2017-10-30aRagexe_zero, 2017-10-31aRagexe_zero, 2017-11-09aRagexe_zero, 2017-11-13aRagexe_zero, 2017-11-13bRagexe_zero, 2018-03-15aRagexe_zero, 2018-03-21aRagexe_zero, 2018-03-21bRagexe_zero, 2018-03-28_1aRagexe_zero, 2018-03-28cRagexe_zero, 2018-04-11aRagexe_zero, 2018-04-25_3aRagexe_zero, 2018-05-09_3aRagexe_zero, 2018-05-23aRagexe_zero, 2018-06-05bRagexe_zero, 2018-06-05cRagexe_zero, 2018-06-27aRagexe_zero, 2018-07-03aRagexe_zero, 2018-07-11_2aRagexe_zero, 2018-07-25_2aRagexe_zero, 2018-08-01aRagexe_zero, 2018-08-08_2aRagexe_zero, 2018-08-22aRagexe_zero, 2018-08-29aRagexe_zero, 2018-09-05aRagexe_zero, 2018-09-12aRagexe_zero, 2018-09-19aRagexe_zero, 2018-09-28aRagexe_zero, 2018-10-10_2aRagexe_zero #if PACKETVER == 20171018 || \ PACKETVER == 20171019 || \ PACKETVER == 20171023 || \ @@ -66,7 +66,8 @@ PACKETVER == 20180905 || \ PACKETVER == 20180912 || \ PACKETVER == 20180919 || \ - PACKETVER >= 20180928 + PACKETVER == 20180928 || \ + PACKETVER >= 20181010 packet(0x0202,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS packet(0x022d,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER packet(0x023b,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD diff --git a/src/map/packets_struct.h b/src/map/packets_struct.h index 29a3355f7..c786e2457 100644 --- a/src/map/packets_struct.h +++ b/src/map/packets_struct.h @@ -324,7 +324,9 @@ enum packet_headers { achievementUpdateType = 0xa24, achievementRewardAckType = 0xa26, #endif // PACKETVER >= 20141016 -#if PACKETVER >= 20150513 // [4144] 0x09f8 handling in client from 2014-10-29aRagexe and 2014-03-26cRagexeRE +#if PACKETVER_ZERO_NUM >= 20181010 || PACKETVER >= 20181017 + questListType = 0xaff, ///< ZC_ALL_QUEST_LIST4 +#elif PACKETVER >= 20150513 // [4144] 0x09f8 handling in client from 2014-10-29aRagexe and 2014-03-26cRagexeRE questListType = 0x9f8, ///< ZC_ALL_QUEST_LIST3 #elif PACKETVER >= 20141022 questListType = 0x97a, ///< ZC_ALL_QUEST_LIST2 @@ -378,12 +380,16 @@ enum packet_headers { clanLeave = 0x0989, ///< ZC_ACK_CLAN_LEAVE clanMessage = 0x098E, ///< ZC_NOTIFY_CLAN_CHAT #endif -#if PACKETVER >= 20150513 // [4144] 0x09f9 handled in client from 2014-10-29aRagexe and 2014-03-26cRagexeRE +#if PACKETVER_ZERO_NUM >= 20181010 || PACKETVER >= 20181017 + questAddType = 0xb0c, +#elif PACKETVER >= 20150513 // [4144] 0x09f9 handled in client from 2014-10-29aRagexe and 2014-03-26cRagexeRE questAddType = 0x9f9, #else questAddType = 0x2b3, #endif // PACKETVER < 20150513 -#if PACKETVER >= 20150513 +#if PACKETVER_ZERO_NUM >= 20181010 || PACKETVER >= 20181017 + questUpdateType = 0xafe, +#elif PACKETVER >= 20150513 questUpdateType = 0x9fa, #else questUpdateType = 0x2b5, @@ -445,6 +451,11 @@ enum packet_headers { #else guildLeave = 0x15a, #endif +#if PACKETVER_MAIN_NUM >= 20181017 || PACKETVER_RE_NUM >= 20181017 + itemPreview = 0xb13, +#else + itemPreview = 0xab9, +#endif }; #if !defined(sun) && (!defined(__NETBSD__) || __NetBSD_Version__ >= 600000000) // NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute @@ -1449,7 +1460,11 @@ struct packet_hotkey { * MISSION_HUNT_INFO_EX (PACKETVER >= 20150513) */ struct packet_mission_info_sub { -#if PACKETVER >= 20150513 +#if PACKETVER_ZERO_NUM >= 20181010 || PACKETVER >= 20181017 + uint32 huntIdent; + uint32 huntIdent2; + uint32 mobType; +#elif PACKETVER >= 20150513 uint32 huntIdent; uint32 mobType; #endif @@ -1819,7 +1834,11 @@ struct PACKET_ZC_NOTIFY_CLAN_CHAT { * PACKET_ZC_MISSION_HUNT_EX (PACKETVER >= 20150513) */ struct packet_quest_hunt_sub { -#if PACKETVER >= 20150513 +#if PACKETVER_ZERO_NUM >= 20181010 || PACKETVER >= 20181017 + uint32 huntIdent; + uint32 huntIdent2; + uint32 mobType; +#elif PACKETVER >= 20150513 uint32 huntIdent; uint32 mobType; #endif @@ -1853,7 +1872,10 @@ struct packet_quest_add_header { */ struct packet_quest_update_hunt { uint32 questID; -#if PACKETVER >= 20150513 +#if PACKETVER_ZERO_NUM >= 20181010 || PACKETVER >= 20181017 + uint32 huntIdent; + uint32 huntIdent2; +#elif PACKETVER >= 20150513 uint32 huntIdent; #else uint32 mob_id; @@ -2274,8 +2296,13 @@ struct PACKET_ZC_PROPERTY_HOMUN { uint16 mdef; uint16 flee; uint16 amotion; +#if PACKETVER < 20150513 + uint16 hp; + uint16 maxHp; +#else uint32 hp; uint32 maxHp; +#endif uint16 sp; uint16 maxSp; uint32 exp; @@ -2850,6 +2877,17 @@ struct PACKET_ZC_CAMERA_INFO { float latitude; } __attribute__((packed)); +struct PACKET_ZC_ITEM_PREVIEW { + int16 packetType; + int16 index; +#if PACKETVER_MAIN_NUM >= 20181017 || PACKETVER_RE_NUM >= 20181017 + int8 isDamaged; +#endif + int16 refiningLevel; + struct EQUIPSLOTINFO slot; + struct ItemOptions option_data[MAX_ITEM_OPTIONS]; +} __attribute__((packed)); + #if !defined(sun) && (!defined(__NETBSD__) || __NetBSD_Version__ >= 600000000) // NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute #pragma pack(pop) diff --git a/src/map/pc.c b/src/map/pc.c index 56f42690d..b8a6912ee 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -4402,8 +4402,6 @@ static int pc_insert_card(struct map_session_data *sd, int idx_card, int idx_equ static int pc_modifybuyvalue(struct map_session_data *sd, int orig_value) { int skill_lv, rate1 = 0, rate2 = 0; - if (orig_value <= 0) - return 0; if ((skill_lv=pc->checkskill(sd,MC_DISCOUNT)) > 0) // merchant discount rate1 = 5+skill_lv*2-((skill_lv==10)? 1:0); if ((skill_lv=pc->checkskill(sd,RG_COMPULSION)) > 0) // rogue discount @@ -4412,8 +4410,9 @@ static int pc_modifybuyvalue(struct map_session_data *sd, int orig_value) rate1 = rate2; if (rate1 != 0) orig_value = apply_percentrate(orig_value, 100-rate1, 100); - if (orig_value < 1) - orig_value = 1; + + if (orig_value < battle_config.min_item_buy_price) + orig_value = battle_config.min_item_buy_price; return orig_value; } @@ -4423,14 +4422,13 @@ static int pc_modifybuyvalue(struct map_session_data *sd, int orig_value) static int pc_modifysellvalue(struct map_session_data *sd, int orig_value) { int skill_lv, rate = 0; - if (orig_value <= 0) - return 0; if ((skill_lv=pc->checkskill(sd,MC_OVERCHARGE)) > 0) //OverCharge rate = 5+skill_lv*2-((skill_lv==10)? 1:0); if (rate != 0) orig_value = apply_percentrate(orig_value, 100+rate, 100); - if (orig_value < 1) - orig_value = 1; + + if (orig_value < battle_config.min_item_sell_price) + orig_value = battle_config.min_item_sell_price; return orig_value; } diff --git a/src/map/quest.c b/src/map/quest.c index 02bf7638b..f10d6847f 100644 --- a/src/map/quest.c +++ b/src/map/quest.c @@ -30,6 +30,7 @@ #include "map/itemdb.h" #include "map/log.h" #include "map/map.h" +#include "map/mercenary.h" #include "map/mob.h" #include "map/npc.h" #include "map/party.h" @@ -719,6 +720,8 @@ static bool quest_questinfo_validate(struct map_session_data *sd, struct questin return false; if (VECTOR_LENGTH(qi->quest_requirement) > 0 && quest->questinfo_validate_quests(sd, qi) == false) return false; + if (qi->mercenary_class != 0 && quest->questinfo_validate_mercenary_class(sd, qi) == false) + return false; return true; } @@ -901,6 +904,29 @@ static bool quest_questinfo_validate_quests(struct map_session_data *sd, struct } /** + * Validate mercenary class required for the questinfo + * + * @param sd session data. + * @param qi questinfo data. + * + * @retval true if player have a mercenary with the given class. + * @retval false if player does NOT have a mercenary with the given class. + */ +static bool quest_questinfo_validate_mercenary_class(struct map_session_data *sd, struct questinfo *qi) +{ + nullpo_retr(false, sd); + nullpo_retr(false, qi); + + if (sd->md == NULL) + return false; + + if (sd->md->mercenary.class_ != qi->mercenary_class) + return false; + + return true; +} + +/** * Clears the questinfo data vector * * @param m mapindex. @@ -993,5 +1019,6 @@ void quest_defaults(void) quest->questinfo_validate_homunculus_level = quest_questinfo_validate_homunculus_level; quest->questinfo_validate_homunculus_type = quest_questinfo_validate_homunculus_type; quest->questinfo_validate_quests = quest_questinfo_validate_quests; + quest->questinfo_validate_mercenary_class = quest_questinfo_validate_mercenary_class; quest->questinfo_vector_clear = quest_questinfo_vector_clear; } diff --git a/src/map/quest.h b/src/map/quest.h index 305a48df1..206a7902f 100644 --- a/src/map/quest.h +++ b/src/map/quest.h @@ -92,6 +92,7 @@ struct quest_interface { bool (*questinfo_validate_homunculus_level) (struct map_session_data *sd, struct questinfo *qi); bool (*questinfo_validate_homunculus_type) (struct map_session_data *sd, struct questinfo *qi); bool (*questinfo_validate_quests) (struct map_session_data *sd, struct questinfo *qi); + bool (*questinfo_validate_mercenary_class) (struct map_session_data *sd, struct questinfo *qi); void (*questinfo_vector_clear) (int m); }; diff --git a/src/map/script.c b/src/map/script.c index 5eed58977..e7a2fdb14 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -14415,6 +14415,9 @@ static BUILDIN(getiteminfo) case ITEMINFO_VIEWSPRITE: script_pushint(st, it->view_sprite); break; + case ITEMINFO_TRADE: + script_pushint(st, it->flag.trade_restriction); + break; default: ShowError("buildin_getiteminfo: Invalid item type %d.\n", n); script_pushint(st,-1); @@ -14681,6 +14684,9 @@ static BUILDIN(setiteminfo) case ITEMINFO_VIEWSPRITE: it->view_sprite = value; break; + case ITEMINFO_TRADE: + it->flag.trade_restriction = value; + break; default: ShowError("buildin_setiteminfo: invalid type %d.\n", n); script_pushint(st,-1); @@ -21171,6 +21177,17 @@ static BUILDIN(setquestinfo) VECTOR_PUSH(qi->quest_requirement, quest_req); break; } + case QINFO_MERCENARY_CLASS: + { + int mer_class = script_getnum(st, 3); + + if (!mercenary->class(mer_class)) { + ShowWarning("buildin_setquestinfo: invalid mercenary class given (%d).\n", mer_class); + return false; + } + qi->mercenary_class = mer_class; + break; + } default: ShowWarning("buildin_setquestinfo: invalid type given (%u).\n", type); return false; @@ -21324,18 +21341,7 @@ static BUILDIN(showevent) } } -#if PACKETVER >= 20170315 - if (icon < 0 || (icon > 10 && icon != 9999)) - icon = 9999; -#elif PACKETVER >= 20120410 - if (icon < 0 || (icon > 8 && icon != 9999) || icon == 7) - icon = 9999; // Default to nothing if icon id is invalid. -#else - if (icon < 0 || icon > 7) - icon = 0; - else - icon = icon + 1; -#endif + icon = quest->questinfo_validate_icon(icon); clif->quest_show_event(sd, &nd->bl, icon, color); return true; @@ -24810,6 +24816,16 @@ static BUILDIN(changecamera) return true; } +// update preview window to given item +static BUILDIN(itempreview) +{ + struct map_session_data *sd = script_rid2sd(st); + if (sd == NULL) + return false; + clif->item_preview(sd, script_getnum(st, 2)); + return true; +} + /** * Adds a built-in script function. * @@ -25544,6 +25560,8 @@ static void script_parse_builtin(void) // camera BUILDIN_DEF(camerainfo, ""), BUILDIN_DEF(changecamera, "iii?"), + + BUILDIN_DEF(itempreview, "i"), }; int i, len = ARRAYLENGTH(BUILDIN); RECREATE(script->buildin, char *, script->buildin_count + len); // Pre-alloc to speed up @@ -25859,6 +25877,7 @@ static void script_hardcoded_constants(void) script->set_constant("ITEMINFO_VIEWID", ITEMINFO_VIEWID, false, false); script->set_constant("ITEMINFO_MATK", ITEMINFO_MATK, false, false); script->set_constant("ITEMINFO_VIEWSPRITE", ITEMINFO_VIEWSPRITE, false, false); + script->set_constant("ITEMINFO_TRADE", ITEMINFO_TRADE, false, false); script->constdb_comment("monster skill states"); script->set_constant("MSS_ANY", MSS_ANY, false, false); @@ -25942,6 +25961,7 @@ static void script_hardcoded_constants(void) script->set_constant("QINFO_HOMUN_LEVEL", QINFO_HOMUN_LEVEL, false, false); script->set_constant("QINFO_HOMUN_TYPE", QINFO_HOMUN_TYPE, false, false); script->set_constant("QINFO_QUEST", QINFO_QUEST, false, false); + script->set_constant("QINFO_MERCENARY_CLASS", QINFO_MERCENARY_CLASS, false, false); script->constdb_comment("function types"); script->set_constant("FUNCTION_IS_COMMAND", FUNCTION_IS_COMMAND, false, false); @@ -25949,6 +25969,20 @@ static void script_hardcoded_constants(void) script->set_constant("FUNCTION_IS_LOCAL", FUNCTION_IS_LOCAL, false, false); script->set_constant("FUNCTION_IS_LABEL", FUNCTION_IS_LABEL, false, false); + script->constdb_comment("item trade restrictions"); + script->set_constant("ITR_NONE", ITR_NONE, false, false); + script->set_constant("ITR_NODROP", ITR_NODROP, false, false); + script->set_constant("ITR_NOTRADE", ITR_NOTRADE, false, false); + script->set_constant("ITR_PARTNEROVERRIDE", ITR_PARTNEROVERRIDE, false, false); + script->set_constant("ITR_NOSELLTONPC", ITR_NOSELLTONPC, false, false); + script->set_constant("ITR_NOCART", ITR_NOCART, false, false); + script->set_constant("ITR_NOSTORAGE", ITR_NOSTORAGE, false, false); + script->set_constant("ITR_NOGSTORAGE", ITR_NOGSTORAGE, false, false); + script->set_constant("ITR_NOMAIL", ITR_NOMAIL, false, false); + script->set_constant("ITR_NOAUCTION", ITR_NOAUCTION, false, false); + script->set_constant("ITR_ALL", ITR_ALL, false, false); + + script->constdb_comment("Renewal"); #ifdef RENEWAL script->set_constant("RENEWAL", 1, false, false); diff --git a/src/map/script.h b/src/map/script.h index 9c72b793c..72210b05b 100644 --- a/src/map/script.h +++ b/src/map/script.h @@ -450,6 +450,7 @@ enum script_iteminfo_types { ITEMINFO_VIEWID, ITEMINFO_MATK, ITEMINFO_VIEWSPRITE, + ITEMINFO_TRADE, ITEMINFO_MAX }; diff --git a/src/map/skill.c b/src/map/skill.c index 4eaab5457..9857badbe 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -4138,7 +4138,7 @@ static int skill_activate_reverberation(struct block_list *bl, va_list ap) if( su->alive && (sg = su->group) != NULL && sg->skill_id == WM_REVERBERATION && sg->unit_id == UNT_REVERBERATION ) { int64 tick = timer->gettick(); clif->changetraplook(bl,UNT_USED_TRAPS); - map->foreachinrange(skill->trap_splash, bl, skill->get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag, bl, tick); + skill->trap_do_splash(bl, sg->skill_id, sg->skill_lv, sg->bl_flag, tick); su->limit = DIFF_TICK32(tick,sg->tick)+1500; sg->unit_id = UNT_USED_TRAPS; } @@ -12644,7 +12644,7 @@ static int skill_unit_onplace(struct skill_unit *src, struct block_list *bl, int if (sg->src_id == bl->id) break; //Does not affect the caster. clif->changetraplook(&src->bl,UNT_USED_TRAPS); - map->foreachinrange(skill->trap_splash,&src->bl, skill->get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag, &src->bl,tick); + skill->trap_do_splash(&src->bl, sg->skill_id, sg->skill_lv, sg->bl_flag, tick); sg->unit_id = UNT_USED_TRAPS; sg->limit = DIFF_TICK32(tick,sg->tick) + 1500; break; @@ -12938,7 +12938,7 @@ static int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *b } - map->foreachinrange(skill->trap_splash, &src->bl, skill->get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag, &src->bl, tick); + skill->trap_do_splash(&src->bl, sg->skill_id, sg->skill_lv, sg->bl_flag, tick); sg->unit_id = UNT_USED_TRAPS; //Changed ID so it does not invoke a for each in area again. } break; @@ -12969,10 +12969,10 @@ static int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *b case UNT_FREEZINGTRAP: case UNT_FIREPILLAR_ACTIVE: case UNT_CLAYMORETRAP: - if( sg->unit_id == UNT_FIRINGTRAP || sg->unit_id == UNT_ICEBOUNDTRAP || sg->unit_id == UNT_CLAYMORETRAP ) - map->foreachinrange(skill->trap_splash,&src->bl, skill->get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag|BL_SKILL|~BCT_SELF, &src->bl,tick); + if (sg->unit_id == UNT_FIRINGTRAP || sg->unit_id == UNT_ICEBOUNDTRAP || sg->unit_id == UNT_CLAYMORETRAP) + skill->trap_do_splash(&src->bl, sg->skill_id, sg->skill_lv, sg->bl_flag | BL_SKILL | ~BCT_SELF, tick); else - map->foreachinrange(skill->trap_splash,&src->bl, skill->get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag, &src->bl,tick); + skill->trap_do_splash(&src->bl, sg->skill_id, sg->skill_lv, sg->bl_flag, tick); if (sg->unit_id != UNT_FIREPILLAR_ACTIVE) clif->changetraplook(&src->bl, sg->unit_id==UNT_LANDMINE?UNT_FIREPILLAR_ACTIVE:UNT_USED_TRAPS); sg->limit=DIFF_TICK32(tick,sg->tick)+1500 + @@ -13203,9 +13203,7 @@ static int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *b case UNT_GROUNDDRIFT_POISON: case UNT_GROUNDDRIFT_WATER: case UNT_GROUNDDRIFT_FIRE: - map->foreachinrange(skill->trap_splash,&src->bl, - skill->get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag, - &src->bl,tick); + skill->trap_do_splash(&src->bl, sg->skill_id, sg->skill_lv, sg->bl_flag, tick); sg->unit_id = UNT_USED_TRAPS; //clif->changetraplook(&src->bl, UNT_FIREPILLAR_ACTIVE); sg->limit=DIFF_TICK32(tick,sg->tick)+1500; @@ -13266,7 +13264,7 @@ static int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *b case UNT_REVERBERATION: clif->changetraplook(&src->bl,UNT_USED_TRAPS); - map->foreachinrange(skill->trap_splash,&src->bl, skill->get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag, &src->bl,tick); + skill->trap_do_splash(&src->bl, sg->skill_id, sg->skill_lv, sg->bl_flag, tick); sg->limit = DIFF_TICK32(tick,sg->tick)+1500; sg->unit_id = UNT_USED_TRAPS; break; @@ -16630,10 +16628,10 @@ static int skill_detonator(struct block_list *bl, va_list ap) case UNT_CLAYMORETRAP: case UNT_FIRINGTRAP: case UNT_ICEBOUNDTRAP: - map->foreachinrange(skill->trap_splash,bl,skill->get_splash(su->group->skill_id,su->group->skill_lv),su->group->bl_flag|BL_SKILL|~BCT_SELF,bl,su->group->tick); + skill->trap_do_splash(bl, su->group->skill_id, su->group->skill_lv, su->group->bl_flag | BL_SKILL | ~BCT_SELF, su->group->tick); break; default: - map->foreachinrange(skill->trap_splash,bl,skill->get_splash(su->group->skill_id,su->group->skill_lv),su->group->bl_flag,bl,su->group->tick); + skill->trap_do_splash(bl, su->group->skill_id, su->group->skill_lv, su->group->bl_flag, su->group->tick); } clif->changetraplook(bl, UNT_USED_TRAPS); su->group->limit = DIFF_TICK32(timer->gettick(),su->group->tick) + @@ -16766,6 +16764,27 @@ static int skill_chastle_mob_changetarget(struct block_list *bl, va_list ap) return 0; } +/** + * Does final adjustments (e.g. count enemies affected by splash) then runs trap splash function (skill_trap_splash). + * + * @param bl : trap skill unit's bl + * @param skill_id : Trap Skill ID + * @param skill_lv : Trap Skill Level + * @param bl_flag : Flag representing units affected by this trap + * @param tick : tick related to this trap + */ +static void skill_trap_do_splash(struct block_list *bl, uint16 skill_id, uint16 skill_lv, int bl_flag, int64 tick) +{ + int enemy_count = 0; + + if (skill->get_nk(skill_id) & NK_SPLASHSPLIT) { + enemy_count = map->foreachinrange(skill->area_sub, bl, skill->get_splash(skill_id, skill_lv), BL_CHAR, bl, skill_id, skill_lv, tick, BCT_ENEMY, skill->area_sub_count); + enemy_count = max(1, enemy_count); // Don't let enemy_count be 0 when spliting trap damage + } + + map->foreachinrange(skill->trap_splash, bl, skill->get_splash(skill_id, skill_lv), bl_flag, bl, tick, enemy_count); +} + /*========================================== * *------------------------------------------*/ @@ -16776,6 +16795,7 @@ static int skill_trap_splash(struct block_list *bl, va_list ap) struct skill_unit *src_su = NULL; struct skill_unit_group *sg; struct block_list *ss; + int enemy_count = va_arg(ap, int); nullpo_ret(bl); nullpo_ret(src); @@ -16870,7 +16890,7 @@ static int skill_trap_splash(struct block_list *bl, va_list ap) } /* Fall through */ default: - skill->attack(skill->get_type(sg->skill_id),ss,src,bl,sg->skill_id,sg->skill_lv,tick,0); + skill->attack(skill->get_type(sg->skill_id), ss, src, bl, sg->skill_id, sg->skill_lv, tick, enemy_count); break; } return 1; @@ -17585,7 +17605,7 @@ static int skill_unit_timer_sub(union DBKey key, struct DBData *data, va_list ap break; } clif->changetraplook(bl,UNT_USED_TRAPS); - map->foreachinrange(skill->trap_splash, bl, skill->get_splash(group->skill_id, group->skill_lv), group->bl_flag, bl, tick); + skill->trap_do_splash(bl, group->skill_id, group->skill_lv, group->bl_flag, tick); group->limit = DIFF_TICK32(tick,group->tick)+1500; su->limit = DIFF_TICK32(tick,group->tick)+1500; group->unit_id = UNT_USED_TRAPS; @@ -18973,7 +18993,7 @@ static int skill_destroy_trap(struct block_list *bl, va_list ap) case UNT_CLAYMORETRAP: case UNT_FIRINGTRAP: case UNT_ICEBOUNDTRAP: - map->foreachinrange(skill->trap_splash,&su->bl, skill->get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag|BL_SKILL|~BCT_SELF, &su->bl,tick); + skill->trap_do_splash(&su->bl, sg->skill_id, sg->skill_lv, sg->bl_flag | BL_SKILL | ~BCT_SELF, tick); break; case UNT_LANDMINE: case UNT_BLASTMINE: @@ -18982,7 +19002,7 @@ static int skill_destroy_trap(struct block_list *bl, va_list ap) case UNT_FLASHER: case UNT_FREEZINGTRAP: case UNT_CLUSTERBOMB: - map->foreachinrange(skill->trap_splash,&su->bl, skill->get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag, &su->bl,tick); + skill->trap_do_splash(&su->bl, sg->skill_id, sg->skill_lv, sg->bl_flag, tick); break; } // Traps aren't recovered. @@ -21578,6 +21598,7 @@ void skill_defaults(void) skill->onskillusage = skill_onskillusage; skill->cell_overlap = skill_cell_overlap; skill->timerskill = skill_timerskill; + skill->trap_do_splash = skill_trap_do_splash; skill->trap_splash = skill_trap_splash; skill->check_condition_mercenary = skill_check_condition_mercenary; skill->locate_element_field = skill_locate_element_field; diff --git a/src/map/skill.h b/src/map/skill.h index 97134224e..0ace19927 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -2059,6 +2059,7 @@ struct skill_interface { int (*onskillusage) (struct map_session_data *sd, struct block_list *bl, uint16 skill_id, int64 tick); int (*cell_overlap) (struct block_list *bl, va_list ap); int (*timerskill) (int tid, int64 tick, int id, intptr_t data); + void (*trap_do_splash) (struct block_list *bl, uint16 skill_id, uint16 skill_lv, int bl_flag, int64 tick); int (*trap_splash) (struct block_list *bl, va_list ap); int (*check_condition_mercenary) (struct block_list *bl, int skill_id, int lv, int type); struct skill_unit_group *(*locate_element_field) (struct block_list *bl); diff --git a/src/plugins/HPMHooking/HPMHooking.Defs.inc b/src/plugins/HPMHooking/HPMHooking.Defs.inc index a8d48546d..81e25f033 100644 --- a/src/plugins/HPMHooking/HPMHooking.Defs.inc +++ b/src/plugins/HPMHooking/HPMHooking.Defs.inc @@ -282,6 +282,8 @@ typedef void (*HPMHOOK_pre_battle_drain) (struct map_session_data **sd, struct b typedef void (*HPMHOOK_post_battle_drain) (struct map_session_data *sd, struct block_list *tbl, int64 rdamage, int64 ldamage, int race, int boss); typedef void (*HPMHOOK_pre_battle_reflect_damage) (struct block_list **target, struct block_list **src, struct Damage **wd, uint16 *skill_id); typedef void (*HPMHOOK_post_battle_reflect_damage) (struct block_list *target, struct block_list *src, struct Damage *wd, uint16 skill_id); +typedef void (*HPMHOOK_pre_battle_reflect_trap) (struct block_list **target, struct block_list **src, struct Damage **md, uint16 *skill_id); +typedef void (*HPMHOOK_post_battle_reflect_trap) (struct block_list *target, struct block_list *src, struct Damage *md, uint16 skill_id); typedef int (*HPMHOOK_pre_battle_attr_ratio) (int *atk_elem, int *def_type, int *def_lv); typedef int (*HPMHOOK_post_battle_attr_ratio) (int retVal___, int atk_elem, int def_type, int def_lv); typedef int64 (*HPMHOOK_pre_battle_attr_fix) (struct block_list **src, struct block_list **target, int64 *damage, int *atk_elem, int *def_type, int *def_lv); @@ -2628,6 +2630,8 @@ typedef void (*HPMHOOK_pre_clif_camera_showWindow) (struct map_session_data **sd typedef void (*HPMHOOK_post_clif_camera_showWindow) (struct map_session_data *sd); typedef void (*HPMHOOK_pre_clif_camera_change) (struct map_session_data **sd, float *range, float *rotation, float *latitude, enum send_target *target); typedef void (*HPMHOOK_post_clif_camera_change) (struct map_session_data *sd, float range, float rotation, float latitude, enum send_target target); +typedef void (*HPMHOOK_pre_clif_item_preview) (struct map_session_data **sd, int *n); +typedef void (*HPMHOOK_post_clif_item_preview) (struct map_session_data *sd, int n); #endif // MAP_CLIF_H #ifdef COMMON_CORE_H /* cmdline */ typedef void (*HPMHOOK_pre_cmdline_init) (void); @@ -6480,6 +6484,8 @@ typedef bool (*HPMHOOK_pre_quest_questinfo_validate_homunculus_type) (struct map typedef bool (*HPMHOOK_post_quest_questinfo_validate_homunculus_type) (bool retVal___, struct map_session_data *sd, struct questinfo *qi); typedef bool (*HPMHOOK_pre_quest_questinfo_validate_quests) (struct map_session_data **sd, struct questinfo **qi); typedef bool (*HPMHOOK_post_quest_questinfo_validate_quests) (bool retVal___, struct map_session_data *sd, struct questinfo *qi); +typedef bool (*HPMHOOK_pre_quest_questinfo_validate_mercenary_class) (struct map_session_data **sd, struct questinfo **qi); +typedef bool (*HPMHOOK_post_quest_questinfo_validate_mercenary_class) (bool retVal___, struct map_session_data *sd, struct questinfo *qi); typedef void (*HPMHOOK_pre_quest_questinfo_vector_clear) (int *m); typedef void (*HPMHOOK_post_quest_questinfo_vector_clear) (int m); #endif // MAP_QUEST_H @@ -7198,6 +7204,8 @@ typedef int (*HPMHOOK_pre_skill_cell_overlap) (struct block_list **bl, va_list a typedef int (*HPMHOOK_post_skill_cell_overlap) (int retVal___, struct block_list *bl, va_list ap); typedef int (*HPMHOOK_pre_skill_timerskill) (int *tid, int64 *tick, int *id, intptr_t *data); typedef int (*HPMHOOK_post_skill_timerskill) (int retVal___, int tid, int64 tick, int id, intptr_t data); +typedef void (*HPMHOOK_pre_skill_trap_do_splash) (struct block_list **bl, uint16 *skill_id, uint16 *skill_lv, int *bl_flag, int64 *tick); +typedef void (*HPMHOOK_post_skill_trap_do_splash) (struct block_list *bl, uint16 skill_id, uint16 skill_lv, int bl_flag, int64 tick); typedef int (*HPMHOOK_pre_skill_trap_splash) (struct block_list **bl, va_list ap); typedef int (*HPMHOOK_post_skill_trap_splash) (int retVal___, struct block_list *bl, va_list ap); typedef int (*HPMHOOK_pre_skill_check_condition_mercenary) (struct block_list **bl, int *skill_id, int *lv, int *type); diff --git a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc index 889faa44c..b0b2e7a32 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc @@ -236,6 +236,8 @@ struct { struct HPMHookPoint *HP_battle_drain_post; struct HPMHookPoint *HP_battle_reflect_damage_pre; struct HPMHookPoint *HP_battle_reflect_damage_post; + struct HPMHookPoint *HP_battle_reflect_trap_pre; + struct HPMHookPoint *HP_battle_reflect_trap_post; struct HPMHookPoint *HP_battle_attr_ratio_pre; struct HPMHookPoint *HP_battle_attr_ratio_post; struct HPMHookPoint *HP_battle_attr_fix_pre; @@ -2220,6 +2222,8 @@ struct { struct HPMHookPoint *HP_clif_camera_showWindow_post; struct HPMHookPoint *HP_clif_camera_change_pre; struct HPMHookPoint *HP_clif_camera_change_post; + struct HPMHookPoint *HP_clif_item_preview_pre; + struct HPMHookPoint *HP_clif_item_preview_post; struct HPMHookPoint *HP_cmdline_init_pre; struct HPMHookPoint *HP_cmdline_init_post; struct HPMHookPoint *HP_cmdline_final_pre; @@ -5008,6 +5012,8 @@ struct { struct HPMHookPoint *HP_quest_questinfo_validate_homunculus_type_post; struct HPMHookPoint *HP_quest_questinfo_validate_quests_pre; struct HPMHookPoint *HP_quest_questinfo_validate_quests_post; + struct HPMHookPoint *HP_quest_questinfo_validate_mercenary_class_pre; + struct HPMHookPoint *HP_quest_questinfo_validate_mercenary_class_post; struct HPMHookPoint *HP_quest_questinfo_vector_clear_pre; struct HPMHookPoint *HP_quest_questinfo_vector_clear_post; struct HPMHookPoint *HP_rnd_init_pre; @@ -5714,6 +5720,8 @@ struct { struct HPMHookPoint *HP_skill_cell_overlap_post; struct HPMHookPoint *HP_skill_timerskill_pre; struct HPMHookPoint *HP_skill_timerskill_post; + struct HPMHookPoint *HP_skill_trap_do_splash_pre; + struct HPMHookPoint *HP_skill_trap_do_splash_post; struct HPMHookPoint *HP_skill_trap_splash_pre; struct HPMHookPoint *HP_skill_trap_splash_post; struct HPMHookPoint *HP_skill_check_condition_mercenary_pre; @@ -6831,6 +6839,8 @@ struct { int HP_battle_drain_post; int HP_battle_reflect_damage_pre; int HP_battle_reflect_damage_post; + int HP_battle_reflect_trap_pre; + int HP_battle_reflect_trap_post; int HP_battle_attr_ratio_pre; int HP_battle_attr_ratio_post; int HP_battle_attr_fix_pre; @@ -8815,6 +8825,8 @@ struct { int HP_clif_camera_showWindow_post; int HP_clif_camera_change_pre; int HP_clif_camera_change_post; + int HP_clif_item_preview_pre; + int HP_clif_item_preview_post; int HP_cmdline_init_pre; int HP_cmdline_init_post; int HP_cmdline_final_pre; @@ -11603,6 +11615,8 @@ struct { int HP_quest_questinfo_validate_homunculus_type_post; int HP_quest_questinfo_validate_quests_pre; int HP_quest_questinfo_validate_quests_post; + int HP_quest_questinfo_validate_mercenary_class_pre; + int HP_quest_questinfo_validate_mercenary_class_post; int HP_quest_questinfo_vector_clear_pre; int HP_quest_questinfo_vector_clear_post; int HP_rnd_init_pre; @@ -12309,6 +12323,8 @@ struct { int HP_skill_cell_overlap_post; int HP_skill_timerskill_pre; int HP_skill_timerskill_post; + int HP_skill_trap_do_splash_pre; + int HP_skill_trap_do_splash_post; int HP_skill_trap_splash_pre; int HP_skill_trap_splash_post; int HP_skill_check_condition_mercenary_pre; diff --git a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc index b11e2d61c..508465411 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc @@ -135,6 +135,7 @@ struct HookingPointData HookingPoints[] = { { HP_POP(battle->delay_damage, HP_battle_delay_damage) }, { HP_POP(battle->drain, HP_battle_drain) }, { HP_POP(battle->reflect_damage, HP_battle_reflect_damage) }, + { HP_POP(battle->reflect_trap, HP_battle_reflect_trap) }, { HP_POP(battle->attr_ratio, HP_battle_attr_ratio) }, { HP_POP(battle->attr_fix, HP_battle_attr_fix) }, { HP_POP(battle->calc_cardfix, HP_battle_calc_cardfix) }, @@ -1134,6 +1135,7 @@ struct HookingPointData HookingPoints[] = { { HP_POP(clif->pMemorialDungeonCommand, HP_clif_pMemorialDungeonCommand) }, { HP_POP(clif->camera_showWindow, HP_clif_camera_showWindow) }, { HP_POP(clif->camera_change, HP_clif_camera_change) }, + { HP_POP(clif->item_preview, HP_clif_item_preview) }, /* cmdline_interface */ { HP_POP(cmdline->init, HP_cmdline_init) }, { HP_POP(cmdline->final, HP_cmdline_final) }, @@ -2564,6 +2566,7 @@ struct HookingPointData HookingPoints[] = { { HP_POP(quest->questinfo_validate_homunculus_level, HP_quest_questinfo_validate_homunculus_level) }, { HP_POP(quest->questinfo_validate_homunculus_type, HP_quest_questinfo_validate_homunculus_type) }, { HP_POP(quest->questinfo_validate_quests, HP_quest_questinfo_validate_quests) }, + { HP_POP(quest->questinfo_validate_mercenary_class, HP_quest_questinfo_validate_mercenary_class) }, { HP_POP(quest->questinfo_vector_clear, HP_quest_questinfo_vector_clear) }, /* rnd_interface */ { HP_POP(rnd->init, HP_rnd_init) }, @@ -2923,6 +2926,7 @@ struct HookingPointData HookingPoints[] = { { HP_POP(skill->onskillusage, HP_skill_onskillusage) }, { HP_POP(skill->cell_overlap, HP_skill_cell_overlap) }, { HP_POP(skill->timerskill, HP_skill_timerskill) }, + { HP_POP(skill->trap_do_splash, HP_skill_trap_do_splash) }, { HP_POP(skill->trap_splash, HP_skill_trap_splash) }, { HP_POP(skill->check_condition_mercenary, HP_skill_check_condition_mercenary) }, { HP_POP(skill->locate_element_field, HP_skill_locate_element_field) }, diff --git a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc index 6405c03a2..fa80a68fd 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc @@ -2859,6 +2859,32 @@ void HP_battle_reflect_damage(struct block_list *target, struct block_list *src, } return; } +void HP_battle_reflect_trap(struct block_list *target, struct block_list *src, struct Damage *md, uint16 skill_id) { + int hIndex = 0; + if (HPMHooks.count.HP_battle_reflect_trap_pre > 0) { + void (*preHookFunc) (struct block_list **target, struct block_list **src, struct Damage **md, uint16 *skill_id); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_battle_reflect_trap_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_battle_reflect_trap_pre[hIndex].func; + preHookFunc(&target, &src, &md, &skill_id); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.battle.reflect_trap(target, src, md, skill_id); + } + if (HPMHooks.count.HP_battle_reflect_trap_post > 0) { + void (*postHookFunc) (struct block_list *target, struct block_list *src, struct Damage *md, uint16 skill_id); + for (hIndex = 0; hIndex < HPMHooks.count.HP_battle_reflect_trap_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_battle_reflect_trap_post[hIndex].func; + postHookFunc(target, src, md, skill_id); + } + } + return; +} int HP_battle_attr_ratio(int atk_elem, int def_type, int def_lv) { int hIndex = 0; int retVal___ = 0; @@ -28939,6 +28965,32 @@ void HP_clif_camera_change(struct map_session_data *sd, float range, float rotat } return; } +void HP_clif_item_preview(struct map_session_data *sd, int n) { + int hIndex = 0; + if (HPMHooks.count.HP_clif_item_preview_pre > 0) { + void (*preHookFunc) (struct map_session_data **sd, int *n); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_item_preview_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_clif_item_preview_pre[hIndex].func; + preHookFunc(&sd, &n); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.clif.item_preview(sd, n); + } + if (HPMHooks.count.HP_clif_item_preview_post > 0) { + void (*postHookFunc) (struct map_session_data *sd, int n); + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_item_preview_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_clif_item_preview_post[hIndex].func; + postHookFunc(sd, n); + } + } + return; +} /* cmdline_interface */ void HP_cmdline_init(void) { int hIndex = 0; @@ -66709,6 +66761,33 @@ bool HP_quest_questinfo_validate_quests(struct map_session_data *sd, struct ques } return retVal___; } +bool HP_quest_questinfo_validate_mercenary_class(struct map_session_data *sd, struct questinfo *qi) { + int hIndex = 0; + bool retVal___ = false; + if (HPMHooks.count.HP_quest_questinfo_validate_mercenary_class_pre > 0) { + bool (*preHookFunc) (struct map_session_data **sd, struct questinfo **qi); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_quest_questinfo_validate_mercenary_class_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_quest_questinfo_validate_mercenary_class_pre[hIndex].func; + retVal___ = preHookFunc(&sd, &qi); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.quest.questinfo_validate_mercenary_class(sd, qi); + } + if (HPMHooks.count.HP_quest_questinfo_validate_mercenary_class_post > 0) { + bool (*postHookFunc) (bool retVal___, struct map_session_data *sd, struct questinfo *qi); + for (hIndex = 0; hIndex < HPMHooks.count.HP_quest_questinfo_validate_mercenary_class_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_quest_questinfo_validate_mercenary_class_post[hIndex].func; + retVal___ = postHookFunc(retVal___, sd, qi); + } + } + return retVal___; +} void HP_quest_questinfo_vector_clear(int m) { int hIndex = 0; if (HPMHooks.count.HP_quest_questinfo_vector_clear_pre > 0) { @@ -76342,6 +76421,32 @@ int HP_skill_timerskill(int tid, int64 tick, int id, intptr_t data) { } return retVal___; } +void HP_skill_trap_do_splash(struct block_list *bl, uint16 skill_id, uint16 skill_lv, int bl_flag, int64 tick) { + int hIndex = 0; + if (HPMHooks.count.HP_skill_trap_do_splash_pre > 0) { + void (*preHookFunc) (struct block_list **bl, uint16 *skill_id, uint16 *skill_lv, int *bl_flag, int64 *tick); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_skill_trap_do_splash_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_skill_trap_do_splash_pre[hIndex].func; + preHookFunc(&bl, &skill_id, &skill_lv, &bl_flag, &tick); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.skill.trap_do_splash(bl, skill_id, skill_lv, bl_flag, tick); + } + if (HPMHooks.count.HP_skill_trap_do_splash_post > 0) { + void (*postHookFunc) (struct block_list *bl, uint16 skill_id, uint16 skill_lv, int bl_flag, int64 tick); + for (hIndex = 0; hIndex < HPMHooks.count.HP_skill_trap_do_splash_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_skill_trap_do_splash_post[hIndex].func; + postHookFunc(bl, skill_id, skill_lv, bl_flag, tick); + } + } + return; +} int HP_skill_trap_splash(struct block_list *bl, va_list ap) { int hIndex = 0; int retVal___ = 0; |