summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md13
-rw-r--r--README.md2
-rw-r--r--conf/char/char-server.conf5
-rw-r--r--conf/clans.conf2
-rw-r--r--conf/common/inter-server.conf2
-rw-r--r--conf/common/socket.conf2
-rw-r--r--conf/global/console.conf44
-rw-r--r--conf/global/sql_connection.conf2
-rw-r--r--conf/import-tmpl/battle.conf2
-rw-r--r--conf/import-tmpl/char-server.conf2
-rw-r--r--conf/import-tmpl/inter-server.conf2
-rw-r--r--conf/import-tmpl/login-server.conf2
-rw-r--r--conf/import-tmpl/logs.conf2
-rw-r--r--conf/import-tmpl/map-server.conf2
-rw-r--r--conf/import-tmpl/script.conf2
-rw-r--r--conf/import-tmpl/socket.conf2
-rw-r--r--conf/login/login-server.conf6
-rw-r--r--conf/map/battle.conf2
-rw-r--r--conf/map/battle/battle.conf2
-rw-r--r--conf/map/battle/battleground.conf2
-rw-r--r--conf/map/battle/client.conf2
-rw-r--r--conf/map/battle/drops.conf7
-rw-r--r--conf/map/battle/exp.conf2
-rw-r--r--conf/map/battle/feature.conf2
-rw-r--r--conf/map/battle/gm.conf2
-rw-r--r--conf/map/battle/guild.conf2
-rw-r--r--conf/map/battle/homunc.conf2
-rw-r--r--conf/map/battle/items.conf2
-rw-r--r--conf/map/battle/misc.conf2
-rw-r--r--conf/map/battle/monster.conf4
-rw-r--r--conf/map/battle/party.conf2
-rw-r--r--conf/map/battle/pet.conf2
-rw-r--r--conf/map/battle/player.conf2
-rw-r--r--conf/map/battle/skill.conf14
-rw-r--r--conf/map/battle/status.conf2
-rw-r--r--conf/map/logs.conf2
-rw-r--r--conf/map/map-server.conf2
-rw-r--r--conf/map/maps.conf2
-rw-r--r--conf/map/script.conf2
-rw-r--r--conf/messages.conf5
-rw-r--r--db/mob_db2.conf2
-rw-r--r--db/option_drop_groups.conf53
-rw-r--r--db/pre-re/mob_db.conf2
-rw-r--r--db/re/item_combo_db.txt1
-rw-r--r--db/re/mob_db.conf2
-rw-r--r--doc/atcommands.txt20
-rw-r--r--doc/constants.md9
-rw-r--r--doc/mob_db.txt68
-rw-r--r--doc/option_drop_group.md97
-rw-r--r--doc/script_commands.txt27
-rw-r--r--npc/custom/etc/quest_warper.txt6
-rw-r--r--npc/custom/events/mushroom_event.txt9
-rw-r--r--npc/custom/quests/quest_shop.txt4
-rw-r--r--npc/custom/quests/thq/THQS_TTShop.txt4
-rw-r--r--npc/dev/test.txt10
-rw-r--r--npc/woe-fe/agit_main.txt3
-rw-r--r--src/char/int_rodex.c136
-rw-r--r--src/char/int_rodex.h4
-rw-r--r--src/char/inter.c2
-rw-r--r--src/char/mapif.c34
-rw-r--r--src/char/mapif.h3
-rw-r--r--src/common/HPMDataCheck.h5
-rw-r--r--src/common/mmo.h10
-rw-r--r--src/common/sysinfo.c8
-rw-r--r--src/map/atcommand.c35
-rw-r--r--src/map/atcommand.h2
-rw-r--r--src/map/battle.c1
-rw-r--r--src/map/battle.h2
-rw-r--r--src/map/chat.c8
-rw-r--r--src/map/intif.c50
-rw-r--r--src/map/intif.h4
-rw-r--r--src/map/mob.c361
-rw-r--r--src/map/mob.h55
-rw-r--r--src/map/pet.c15
-rw-r--r--src/map/rodex.c94
-rw-r--r--src/map/rodex.h2
-rw-r--r--src/map/script.c62
-rw-r--r--src/plugins/HPMHooking/HPMHooking.Defs.inc42
-rw-r--r--src/plugins/HPMHooking/HPMHooking_char.HPMHooksCore.inc16
-rw-r--r--src/plugins/HPMHooking/HPMHooking_char.HookingPoints.inc4
-rw-r--r--src/plugins/HPMHooking/HPMHooking_char.Hooks.inc118
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc44
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc11
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.Hooks.inc315
84 files changed, 1704 insertions, 218 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c7424dec8..c434f0b1a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,13 @@ and this project does not adhere to [Semantic Versioning](http://semver.org/spec
If you are reading this in a text editor, simply ignore this section
-->
+## [v2019.04.07+1] `April 7 2019` `PATCH 1`
+
+### Fixed
+
+- Fixed some race conditions and missing validation in the item and zeny handling code for RODEX. (#2437)
+- Fixed pet eggs getting lost for pets that were hatched before the pet evolution system. Pets are now automatically migrated to the new system that keeps eggs in the user's inventory. (#2428)
+
## [v2019.04.07] `April 7 2019`
### Added
@@ -47,9 +54,6 @@ If you are reading this in a text editor, simply ignore this section
- Deprecated the command `petstat()`, superseded by `getpetinfo()`. (part of #2398)
- Deprecated the `PET_*` constants, used by the `petstat()` command. (part of #2398)
-### Removed
-
-
## [v2019.03.10] `March 10 2019`
### Added
@@ -90,8 +94,6 @@ If you are reading this in a text editor, simply ignore this section
- Deprecated the `UDT_MAPIDXY` constant. Its use in `setunitdata()` is replaced by `unitwarp()` and its use in `getunitdata()` is replaced by `getmapxy()`. (#2391)
- Deprecated the `UDT_WALKTOXY` constant. Its use in `setunitdata()` is replaced by `unitwalk()`. (#2391)
-### Removed
-
## [v2019.02.10+1] `February 10 2019` `PATCH 1`
### Fixed
@@ -679,6 +681,7 @@ If you are reading this in a text editor, simply ignore this section
- New versioning scheme and project changelogs/release notes (#1853)
[Unreleased]: https://github.com/HerculesWS/Hercules/compare/stable...master
+[v2019.04.07+1]: https://github.com/HerculesWS/Hercules/compare/v2019.04.07...v2019.04.07+1
[v2019.04.07]: https://github.com/HerculesWS/Hercules/compare/v2019.03.10...v2019.04.07
[v2019.03.10]: https://github.com/HerculesWS/Hercules/compare/v2019.02.10+1...v2019.03.10
[v2019.02.10+1]: https://github.com/HerculesWS/Hercules/compare/v2019.02.10...v2019.02.10+1
diff --git a/README.md b/README.md
index 2cc75b250..b17eedbda 100644
--- a/README.md
+++ b/README.md
@@ -149,7 +149,7 @@ Examples:
[Error]: npc_parsesrcfile: Unable to parse, probably a missing or extra TAB in file 'npc/custom/jobmaster.txt', line '17'. Skipping line...
* w1=prontera,153,193,6 script
* w2=Job Master
- * w3=123,{
+ * w3=2_F_MAGICMASTER,{
* w4=
```
diff --git a/conf/char/char-server.conf b/conf/char/char-server.conf
index 0f07731fb..e3d0fd8c0 100644
--- a/conf/char/char-server.conf
+++ b/conf/char/char-server.conf
@@ -9,7 +9,7 @@
//= This file is part of Hercules.
//= http://herc.ws - http://github.com/HerculesWS/Hercules
//=
-//= Copyright (C) 2014-2018 Hercules Dev Team
+//= Copyright (C) 2014-2019 Hercules Dev Team
//=
//= Hercules is free software: you can redistribute it and/or modify
//= it under the terms of the GNU General Public License as published by
@@ -214,8 +214,7 @@ char_configuration: {
pincode: {
// A window is opened before you can select your character and you will have to enter a pincode by using only your mouse
// NOTE: Requires client 2011-03-09aragexeRE or newer.
- // 0: disabled
- // 1: enabled
+ // Default: true
enabled: true
// Request Pincode only on login or on everytime char select is accessed?
diff --git a/conf/clans.conf b/conf/clans.conf
index 85ef280fe..82211fce0 100644
--- a/conf/clans.conf
+++ b/conf/clans.conf
@@ -9,7 +9,7 @@
//= This file is part of Hercules.
//= http://herc.ws - http://github.com/HerculesWS/Hercules
//=
-//= Copyright (C) 2017 Hercules Dev Team
+//= Copyright (C) 2017-2019 Hercules Dev Team
//=
//= Hercules is free software: you can redistribute it and/or modify
//= it under the terms of the GNU General Public License as published by
diff --git a/conf/common/inter-server.conf b/conf/common/inter-server.conf
index cbeb6617d..d45657dca 100644
--- a/conf/common/inter-server.conf
+++ b/conf/common/inter-server.conf
@@ -9,7 +9,7 @@
//= This file is part of Hercules.
//= http://herc.ws - http://github.com/HerculesWS/Hercules
//=
-//= Copyright (C) 2014-2018 Hercules Dev Team
+//= Copyright (C) 2014-2019 Hercules Dev Team
//=
//= Hercules is free software: you can redistribute it and/or modify
//= it under the terms of the GNU General Public License as published by
diff --git a/conf/common/socket.conf b/conf/common/socket.conf
index 8b8b21865..eb7d494b4 100644
--- a/conf/common/socket.conf
+++ b/conf/common/socket.conf
@@ -9,7 +9,7 @@
//= This file is part of Hercules.
//= http://herc.ws - http://github.com/HerculesWS/Hercules
//=
-//= Copyright (C) 2014-2018 Hercules Dev Team
+//= Copyright (C) 2014-2019 Hercules Dev Team
//=
//= Hercules is free software: you can redistribute it and/or modify
//= it under the terms of the GNU General Public License as published by
diff --git a/conf/global/console.conf b/conf/global/console.conf
index 84a16a7c8..266b301b2 100644
--- a/conf/global/console.conf
+++ b/conf/global/console.conf
@@ -9,7 +9,7 @@
//= This file is part of Hercules.
//= http://herc.ws - http://github.com/HerculesWS/Hercules
//=
-//= Copyright (C) 2014-2018 Hercules Dev Team
+//= Copyright (C) 2014-2019 Hercules Dev Team
//=
//= Hercules is free software: you can redistribute it and/or modify
//= it under the terms of the GNU General Public License as published by
@@ -32,36 +32,36 @@
//=========================================================================
console: {
- //Time-stamp format which will be printed before all messages.
- //Can at most be 20 characters long.
- //Common formats:
- // %I:%M:%S %p (hour:minute:second 12 hour, AM/PM format)
- // %H:%M:%S (hour:minute:second, 24 hour format)
- // %d/%b/%Y (day/Month/year)
- //For full format information, consult the strftime() manual.
+ // Time-stamp format which will be printed before all messages.
+ // Can at most be 20 characters long.
+ // Common formats:
+ // %I:%M:%S %p (hour:minute:second 12 hour, AM/PM format)
+ // %H:%M:%S (hour:minute:second, 24 hour format)
+ // %d/%b/%Y (day/Month/year)
+ // For full format information, consult the strftime() manual.
//timestamp_format: "[%d/%b %H:%M]"
- //If redirected output contains escape sequences (color codes)
+ // If redirected output contains escape sequences (color codes)
stdout_with_ansisequence: false
- //Makes server output more silent by omitting certain types of messages:
- //1: Hide Information messages
- //2: Hide Status messages
- //4: Hide Notice Messages
- //8: Hide Warning Messages
- //16: Hide Error and SQL Error messages.
- //32: Hide Debug Messages
- //Example: "console_silent: 7" Hides information, status and notice messages (1+2+4)
+ // Makes server output more silent by omitting certain types of messages:
+ // 1: Hide Information messages
+ // 2: Hide Status messages
+ // 4: Hide Notice Messages
+ // 8: Hide Warning Messages
+ // 16: Hide Error and SQL Error messages.
+ // 32: Hide Debug Messages
+ // Example: "console_silent: 7" Hides information, status and notice messages (1+2+4)
console_silent: 0
// [CHAR] Display information on the console whenever characters/guilds/parties/pets are loaded/saved?
save_log: true
// [MAP] Makes server log selected message types to a file in the /log/ folder
- //1: Log Warning Messages
- //2: Log Error and SQL Error messages.
- //4: Log Debug Messages
- //Example: "console_msg_log: 7" logs all 3 kinds
- //Messages logged by this overrides console_silent setting
+ // 1: Log Warning Messages
+ // 2: Log Error and SQL Error messages.
+ // 4: Log Debug Messages
+ // Example: "console_msg_log: 7" logs all 3 kinds
+ // Messages logged by this overrides console_silent setting
console_msg_log: 0
}
diff --git a/conf/global/sql_connection.conf b/conf/global/sql_connection.conf
index 3a465afea..7b1a2b97b 100644
--- a/conf/global/sql_connection.conf
+++ b/conf/global/sql_connection.conf
@@ -9,7 +9,7 @@
//= This file is part of Hercules.
//= http://herc.ws - http://github.com/HerculesWS/Hercules
//=
-//= Copyright (C) 2014-2018 Hercules Dev Team
+//= Copyright (C) 2014-2019 Hercules Dev Team
//=
//= Hercules is free software: you can redistribute it and/or modify
//= it under the terms of the GNU General Public License as published by
diff --git a/conf/import-tmpl/battle.conf b/conf/import-tmpl/battle.conf
index 7d1d03578..ff05022c2 100644
--- a/conf/import-tmpl/battle.conf
+++ b/conf/import-tmpl/battle.conf
@@ -9,7 +9,7 @@
//= This file is part of Hercules.
//= http://herc.ws - http://github.com/HerculesWS/Hercules
//=
-//= Copyright (C) 2014-2018 Hercules Dev Team
+//= Copyright (C) 2014-2019 Hercules Dev Team
//=
//= Hercules is free software: you can redistribute it and/or modify
//= it under the terms of the GNU General Public License as published by
diff --git a/conf/import-tmpl/char-server.conf b/conf/import-tmpl/char-server.conf
index 4c9462bc7..3162a31ad 100644
--- a/conf/import-tmpl/char-server.conf
+++ b/conf/import-tmpl/char-server.conf
@@ -9,7 +9,7 @@
//= This file is part of Hercules.
//= http://herc.ws - http://github.com/HerculesWS/Hercules
//=
-//= Copyright (C) 2014-2018 Hercules Dev Team
+//= Copyright (C) 2014-2019 Hercules Dev Team
//=
//= Hercules is free software: you can redistribute it and/or modify
//= it under the terms of the GNU General Public License as published by
diff --git a/conf/import-tmpl/inter-server.conf b/conf/import-tmpl/inter-server.conf
index c23143b35..9cd3932f5 100644
--- a/conf/import-tmpl/inter-server.conf
+++ b/conf/import-tmpl/inter-server.conf
@@ -9,7 +9,7 @@
//= This file is part of Hercules.
//= http://herc.ws - http://github.com/HerculesWS/Hercules
//=
-//= Copyright (C) 2014-2018 Hercules Dev Team
+//= Copyright (C) 2014-2019 Hercules Dev Team
//=
//= Hercules is free software: you can redistribute it and/or modify
//= it under the terms of the GNU General Public License as published by
diff --git a/conf/import-tmpl/login-server.conf b/conf/import-tmpl/login-server.conf
index 1c45f94f9..c8f1f8546 100644
--- a/conf/import-tmpl/login-server.conf
+++ b/conf/import-tmpl/login-server.conf
@@ -9,7 +9,7 @@
//= This file is part of Hercules.
//= http://herc.ws - http://github.com/HerculesWS/Hercules
//=
-//= Copyright (C) 2014-2018 Hercules Dev Team
+//= Copyright (C) 2014-2019 Hercules Dev Team
//=
//= Hercules is free software: you can redistribute it and/or modify
//= it under the terms of the GNU General Public License as published by
diff --git a/conf/import-tmpl/logs.conf b/conf/import-tmpl/logs.conf
index 8f8c2ea68..47e5a665a 100644
--- a/conf/import-tmpl/logs.conf
+++ b/conf/import-tmpl/logs.conf
@@ -9,7 +9,7 @@
//= This file is part of Hercules.
//= http://herc.ws - http://github.com/HerculesWS/Hercules
//=
-//= Copyright (C) 2014-2018 Hercules Dev Team
+//= Copyright (C) 2014-2019 Hercules Dev Team
//=
//= Hercules is free software: you can redistribute it and/or modify
//= it under the terms of the GNU General Public License as published by
diff --git a/conf/import-tmpl/map-server.conf b/conf/import-tmpl/map-server.conf
index 4d907025e..11e4356ba 100644
--- a/conf/import-tmpl/map-server.conf
+++ b/conf/import-tmpl/map-server.conf
@@ -9,7 +9,7 @@
//= This file is part of Hercules.
//= http://herc.ws - http://github.com/HerculesWS/Hercules
//=
-//= Copyright (C) 2014-2018 Hercules Dev Team
+//= Copyright (C) 2014-2019 Hercules Dev Team
//=
//= Hercules is free software: you can redistribute it and/or modify
//= it under the terms of the GNU General Public License as published by
diff --git a/conf/import-tmpl/script.conf b/conf/import-tmpl/script.conf
index 040245285..042644ff1 100644
--- a/conf/import-tmpl/script.conf
+++ b/conf/import-tmpl/script.conf
@@ -9,7 +9,7 @@
//= This file is part of Hercules.
//= http://herc.ws - http://github.com/HerculesWS/Hercules
//=
-//= Copyright (C) 2014-2018 Hercules Dev Team
+//= Copyright (C) 2014-2019 Hercules Dev Team
//=
//= Hercules is free software: you can redistribute it and/or modify
//= it under the terms of the GNU General Public License as published by
diff --git a/conf/import-tmpl/socket.conf b/conf/import-tmpl/socket.conf
index 7ce178140..57806f21e 100644
--- a/conf/import-tmpl/socket.conf
+++ b/conf/import-tmpl/socket.conf
@@ -9,7 +9,7 @@
//= This file is part of Hercules.
//= http://herc.ws - http://github.com/HerculesWS/Hercules
//=
-//= Copyright (C) 2014-2018 Hercules Dev Team
+//= Copyright (C) 2014-2019 Hercules Dev Team
//=
//= Hercules is free software: you can redistribute it and/or modify
//= it under the terms of the GNU General Public License as published by
diff --git a/conf/login/login-server.conf b/conf/login/login-server.conf
index a3d0b6955..22e927c5e 100644
--- a/conf/login/login-server.conf
+++ b/conf/login/login-server.conf
@@ -9,7 +9,7 @@
//= This file is part of Hercules.
//= http://herc.ws - http://github.com/HerculesWS/Hercules
//=
-//= Copyright (C) 2014-2018 Hercules Dev Team
+//= Copyright (C) 2014-2019 Hercules Dev Team
//=
//= Hercules is free software: you can redistribute it and/or modify
//= it under the terms of the GNU General Public License as published by
@@ -75,8 +75,8 @@ login_configuration: {
// Can you use _M/_F to make new accounts on the server?
new_account: true
- //If new_account is enabled, minimum length to userid and passwords should be 4?
- //Must be 'true' unless your client uses both 'Disable 4 LetterUserID/Password' Diffs
+ // If new_account is enabled, minimum length to userid and passwords should be 4?
+ // Must be 'true' unless your client uses both 'Disable 4 LetterUserID/Password' Diffs
new_acc_length_limit: true
// Account registration flood protection system
diff --git a/conf/map/battle.conf b/conf/map/battle.conf
index 75cf0fb49..4bb60dab4 100644
--- a/conf/map/battle.conf
+++ b/conf/map/battle.conf
@@ -9,7 +9,7 @@
//= This file is part of Hercules.
//= http://herc.ws - http://github.com/HerculesWS/Hercules
//=
-//= Copyright (C) 2014-2018 Hercules Dev Team
+//= Copyright (C) 2014-2019 Hercules Dev Team
//=
//= Hercules is free software: you can redistribute it and/or modify
//= it under the terms of the GNU General Public License as published by
diff --git a/conf/map/battle/battle.conf b/conf/map/battle/battle.conf
index 4b1632e31..eafb5ec9b 100644
--- a/conf/map/battle/battle.conf
+++ b/conf/map/battle/battle.conf
@@ -9,7 +9,7 @@
//= This file is part of Hercules.
//= http://herc.ws - http://github.com/HerculesWS/Hercules
//=
-//= Copyright (C) 2014-2018 Hercules Dev Team
+//= Copyright (C) 2014-2019 Hercules Dev Team
//=
//= Hercules is free software: you can redistribute it and/or modify
//= it under the terms of the GNU General Public License as published by
diff --git a/conf/map/battle/battleground.conf b/conf/map/battle/battleground.conf
index b2a482f3d..08c7fcd8a 100644
--- a/conf/map/battle/battleground.conf
+++ b/conf/map/battle/battleground.conf
@@ -9,7 +9,7 @@
//= This file is part of Hercules.
//= http://herc.ws - http://github.com/HerculesWS/Hercules
//=
-//= Copyright (C) 2014-2018 Hercules Dev Team
+//= Copyright (C) 2014-2019 Hercules Dev Team
//=
//= Hercules is free software: you can redistribute it and/or modify
//= it under the terms of the GNU General Public License as published by
diff --git a/conf/map/battle/client.conf b/conf/map/battle/client.conf
index 24b1c8157..12661180a 100644
--- a/conf/map/battle/client.conf
+++ b/conf/map/battle/client.conf
@@ -9,7 +9,7 @@
//= This file is part of Hercules.
//= http://herc.ws - http://github.com/HerculesWS/Hercules
//=
-//= Copyright (C) 2014-2018 Hercules Dev Team
+//= Copyright (C) 2014-2019 Hercules Dev Team
//=
//= Hercules is free software: you can redistribute it and/or modify
//= it under the terms of the GNU General Public License as published by
diff --git a/conf/map/battle/drops.conf b/conf/map/battle/drops.conf
index eb7d94f13..cf09d14d9 100644
--- a/conf/map/battle/drops.conf
+++ b/conf/map/battle/drops.conf
@@ -9,7 +9,7 @@
//= This file is part of Hercules.
//= http://herc.ws - http://github.com/HerculesWS/Hercules
//=
-//= Copyright (C) 2014-2018 Hercules Dev Team
+//= Copyright (C) 2014-2019 Hercules Dev Team
//=
//= Hercules is free software: you can redistribute it and/or modify
//= it under the terms of the GNU General Public License as published by
@@ -146,3 +146,8 @@ drops_by_luk2: 0
// 1: Only marine spheres drop items.
// 2: All alchemist summons drop items.
alchemist_summon_reward: 1
+
+// The maximum number of full iterations that server can do when dropping an item with options.
+// When picking random options for a dropped item, it does lots of iterations to choose the option to be set,
+// this value limits the number of iterations to avoid making the server hang in a long loop.
+option_drop_max_loop: 10
diff --git a/conf/map/battle/exp.conf b/conf/map/battle/exp.conf
index 8ca3de933..54b2ec4e0 100644
--- a/conf/map/battle/exp.conf
+++ b/conf/map/battle/exp.conf
@@ -9,7 +9,7 @@
//= This file is part of Hercules.
//= http://herc.ws - http://github.com/HerculesWS/Hercules
//=
-//= Copyright (C) 2014-2018 Hercules Dev Team
+//= Copyright (C) 2014-2019 Hercules Dev Team
//=
//= Hercules is free software: you can redistribute it and/or modify
//= it under the terms of the GNU General Public License as published by
diff --git a/conf/map/battle/feature.conf b/conf/map/battle/feature.conf
index c306dd97b..5e40f2898 100644
--- a/conf/map/battle/feature.conf
+++ b/conf/map/battle/feature.conf
@@ -9,7 +9,7 @@
//= This file is part of Hercules.
//= http://herc.ws - http://github.com/HerculesWS/Hercules
//=
-//= Copyright (C) 2014-2018 Hercules Dev Team
+//= Copyright (C) 2014-2019 Hercules Dev Team
//=
//= Hercules is free software: you can redistribute it and/or modify
//= it under the terms of the GNU General Public License as published by
diff --git a/conf/map/battle/gm.conf b/conf/map/battle/gm.conf
index 872aaea6d..32e407866 100644
--- a/conf/map/battle/gm.conf
+++ b/conf/map/battle/gm.conf
@@ -9,7 +9,7 @@
//= This file is part of Hercules.
//= http://herc.ws - http://github.com/HerculesWS/Hercules
//=
-//= Copyright (C) 2014-2018 Hercules Dev Team
+//= Copyright (C) 2014-2019 Hercules Dev Team
//=
//= Hercules is free software: you can redistribute it and/or modify
//= it under the terms of the GNU General Public License as published by
diff --git a/conf/map/battle/guild.conf b/conf/map/battle/guild.conf
index e92760796..101349a85 100644
--- a/conf/map/battle/guild.conf
+++ b/conf/map/battle/guild.conf
@@ -9,7 +9,7 @@
//= This file is part of Hercules.
//= http://herc.ws - http://github.com/HerculesWS/Hercules
//=
-//= Copyright (C) 2014-2018 Hercules Dev Team
+//= Copyright (C) 2014-2019 Hercules Dev Team
//=
//= Hercules is free software: you can redistribute it and/or modify
//= it under the terms of the GNU General Public License as published by
diff --git a/conf/map/battle/homunc.conf b/conf/map/battle/homunc.conf
index 0042df016..7ccaf8f8a 100644
--- a/conf/map/battle/homunc.conf
+++ b/conf/map/battle/homunc.conf
@@ -9,7 +9,7 @@
//= This file is part of Hercules.
//= http://herc.ws - http://github.com/HerculesWS/Hercules
//=
-//= Copyright (C) 2014-2018 Hercules Dev Team
+//= Copyright (C) 2014-2019 Hercules Dev Team
//=
//= Hercules is free software: you can redistribute it and/or modify
//= it under the terms of the GNU General Public License as published by
diff --git a/conf/map/battle/items.conf b/conf/map/battle/items.conf
index e834b80f6..0dd990e0a 100644
--- a/conf/map/battle/items.conf
+++ b/conf/map/battle/items.conf
@@ -9,7 +9,7 @@
//= This file is part of Hercules.
//= http://herc.ws - http://github.com/HerculesWS/Hercules
//=
-//= Copyright (C) 2014-2018 Hercules Dev Team
+//= Copyright (C) 2014-2019 Hercules Dev Team
//=
//= Hercules is free software: you can redistribute it and/or modify
//= it under the terms of the GNU General Public License as published by
diff --git a/conf/map/battle/misc.conf b/conf/map/battle/misc.conf
index 5a8f916aa..f2bd00429 100644
--- a/conf/map/battle/misc.conf
+++ b/conf/map/battle/misc.conf
@@ -9,7 +9,7 @@
//= This file is part of Hercules.
//= http://herc.ws - http://github.com/HerculesWS/Hercules
//=
-//= Copyright (C) 2014-2018 Hercules Dev Team
+//= Copyright (C) 2014-2019 Hercules Dev Team
//=
//= Hercules is free software: you can redistribute it and/or modify
//= it under the terms of the GNU General Public License as published by
diff --git a/conf/map/battle/monster.conf b/conf/map/battle/monster.conf
index 192e54615..8f969dc48 100644
--- a/conf/map/battle/monster.conf
+++ b/conf/map/battle/monster.conf
@@ -9,7 +9,7 @@
//= This file is part of Hercules.
//= http://herc.ws - http://github.com/HerculesWS/Hercules
//=
-//= Copyright (C) 2014-2018 Hercules Dev Team
+//= Copyright (C) 2014-2019 Hercules Dev Team
//=
//= Hercules is free software: you can redistribute it and/or modify
//= it under the terms of the GNU General Public License as published by
@@ -137,7 +137,7 @@ mob_skill_delay: 100
mob_count_rate: 100
// Respawn rate of monsters on a map. 50 would make mobs respawn twice as fast (half delay time) (Note 2)
-//Note: This does not affects mobs with immediate respawn (most normal mobs)
+// Note: This does not affects mobs with immediate respawn (most normal mobs)
mob_spawn_delay: 100
plant_spawn_delay: 100
boss_spawn_delay: 100
diff --git a/conf/map/battle/party.conf b/conf/map/battle/party.conf
index 621ec50f4..79230eac4 100644
--- a/conf/map/battle/party.conf
+++ b/conf/map/battle/party.conf
@@ -9,7 +9,7 @@
//= This file is part of Hercules.
//= http://herc.ws - http://github.com/HerculesWS/Hercules
//=
-//= Copyright (C) 2014-2018 Hercules Dev Team
+//= Copyright (C) 2014-2019 Hercules Dev Team
//=
//= Hercules is free software: you can redistribute it and/or modify
//= it under the terms of the GNU General Public License as published by
diff --git a/conf/map/battle/pet.conf b/conf/map/battle/pet.conf
index 02324ac52..f3c6fc12f 100644
--- a/conf/map/battle/pet.conf
+++ b/conf/map/battle/pet.conf
@@ -9,7 +9,7 @@
//= This file is part of Hercules.
//= http://herc.ws - http://github.com/HerculesWS/Hercules
//=
-//= Copyright (C) 2014-2018 Hercules Dev Team
+//= Copyright (C) 2014-2019 Hercules Dev Team
//=
//= Hercules is free software: you can redistribute it and/or modify
//= it under the terms of the GNU General Public License as published by
diff --git a/conf/map/battle/player.conf b/conf/map/battle/player.conf
index c7bb13e88..0762b1f54 100644
--- a/conf/map/battle/player.conf
+++ b/conf/map/battle/player.conf
@@ -9,7 +9,7 @@
//= This file is part of Hercules.
//= http://herc.ws - http://github.com/HerculesWS/Hercules
//=
-//= Copyright (C) 2014-2018 Hercules Dev Team
+//= Copyright (C) 2014-2019 Hercules Dev Team
//=
//= Hercules is free software: you can redistribute it and/or modify
//= it under the terms of the GNU General Public License as published by
diff --git a/conf/map/battle/skill.conf b/conf/map/battle/skill.conf
index da8d1906d..3c4b90505 100644
--- a/conf/map/battle/skill.conf
+++ b/conf/map/battle/skill.conf
@@ -9,7 +9,7 @@
//= This file is part of Hercules.
//= http://herc.ws - http://github.com/HerculesWS/Hercules
//=
-//= Copyright (C) 2014-2018 Hercules Dev Team
+//= Copyright (C) 2014-2019 Hercules Dev Team
//=
//= Hercules is free software: you can redistribute it and/or modify
//= it under the terms of the GNU General Public License as published by
@@ -53,8 +53,8 @@ min_skill_delay_limit: 100
// appear to "teleport" afterwards.
default_walk_delay: 300
-//Completely disable skill delay of the following types (Note 3)
-//NOTE: By default mobs don't have the skill delay as specified in the skill
+// Completely disable skill delay of the following types (Note 3)
+// NOTE: By default mobs don't have the skill delay as specified in the skill
// database, but follow their own 'reuse' skill delay which is specified on
// the mob skill db. When set, the delay for all skills become
// min_skill_delay_limit.
@@ -107,9 +107,9 @@ clear_skills_on_death: 0
// Should ground placed skills be removed when the caster changes maps? (Note 3)
clear_skills_on_warp: 15
-//Setting this to true will override the target mode of ground-based skills with the flag 0x01 to "No Enemies"
-//The two skills affected by default are Pneuma and Safety Wall (if set to true, those two skills will not protect everyone, but only allies)
-//See db/skill_unit_db.txt for more info.
+// Setting this to true will override the target mode of ground-based skills with the flag 0x01 to "No Enemies"
+// The two skills affected by default are Pneuma and Safety Wall (if set to true, those two skills will not protect everyone, but only allies)
+// See db/skill_unit_db.txt for more info.
defunit_not_enemy: false
// Do skills do at least 'hits' damage when they don't miss/are blocked?
@@ -175,7 +175,7 @@ monster_cloak_check_type: 4
// Can't place unlimited land skills at the same time (Note 3)
land_skill_limit: 9
-//Determines which kind of skill-failed messages should be sent:
+// Determines which kind of skill-failed messages should be sent:
// 0 - Enable by default
// 1 - Disable all skill-failed messages.
// 2 - Disable skill-failed messages due to can-act delays.
diff --git a/conf/map/battle/status.conf b/conf/map/battle/status.conf
index 94459e113..8ba761992 100644
--- a/conf/map/battle/status.conf
+++ b/conf/map/battle/status.conf
@@ -9,7 +9,7 @@
//= This file is part of Hercules.
//= http://herc.ws - http://github.com/HerculesWS/Hercules
//=
-//= Copyright (C) 2014-2018 Hercules Dev Team
+//= Copyright (C) 2014-2019 Hercules Dev Team
//=
//= Hercules is free software: you can redistribute it and/or modify
//= it under the terms of the GNU General Public License as published by
diff --git a/conf/map/logs.conf b/conf/map/logs.conf
index f56db9eee..db584049a 100644
--- a/conf/map/logs.conf
+++ b/conf/map/logs.conf
@@ -9,7 +9,7 @@
//= This file is part of Hercules.
//= http://herc.ws - http://github.com/HerculesWS/Hercules
//=
-//= Copyright (C) 2014-2018 Hercules Dev Team
+//= Copyright (C) 2014-2019 Hercules Dev Team
//=
//= Hercules is free software: you can redistribute it and/or modify
//= it under the terms of the GNU General Public License as published by
diff --git a/conf/map/map-server.conf b/conf/map/map-server.conf
index 943b7b5a6..e1de55edb 100644
--- a/conf/map/map-server.conf
+++ b/conf/map/map-server.conf
@@ -9,7 +9,7 @@
//= This file is part of Hercules.
//= http://herc.ws - http://github.com/HerculesWS/Hercules
//=
-//= Copyright (C) 2014-2018 Hercules Dev Team
+//= Copyright (C) 2014-2019 Hercules Dev Team
//=
//= Hercules is free software: you can redistribute it and/or modify
//= it under the terms of the GNU General Public License as published by
diff --git a/conf/map/maps.conf b/conf/map/maps.conf
index 1634ef3a8..644ced6bb 100644
--- a/conf/map/maps.conf
+++ b/conf/map/maps.conf
@@ -9,7 +9,7 @@
//= This file is part of Hercules.
//= http://herc.ws - http://github.com/HerculesWS/Hercules
//=
-//= Copyright (C) 2014-2018 Hercules Dev Team
+//= Copyright (C) 2014-2019 Hercules Dev Team
//=
//= Hercules is free software: you can redistribute it and/or modify
//= it under the terms of the GNU General Public License as published by
diff --git a/conf/map/script.conf b/conf/map/script.conf
index f18e9d6e2..fc617d858 100644
--- a/conf/map/script.conf
+++ b/conf/map/script.conf
@@ -9,7 +9,7 @@
//= This file is part of Hercules.
//= http://herc.ws - http://github.com/HerculesWS/Hercules
//=
-//= Copyright (C) 2014-2018 Hercules Dev Team
+//= Copyright (C) 2014-2019 Hercules Dev Team
//=
//= Hercules is free software: you can redistribute it and/or modify
//= it under the terms of the GNU General Public License as published by
diff --git a/conf/messages.conf b/conf/messages.conf
index 2f790b13f..772b882c9 100644
--- a/conf/messages.conf
+++ b/conf/messages.conf
@@ -1569,5 +1569,10 @@
1498: You can't add a party bound item to a character without party!
1499: You can't add a guild bound item to a character without guild!
+// @dropall
+1500: Usage: @dropall {<type>}
+1501: Type List: (default) all = -1, healing = 0, usable = 2, etc = 3, weapon = 4, armor = 5, card = 6, petegg = 7, petarmor = 8, ammo = 10, delayed-consumable = 11, cash = 18
+1502: %d items are dropped!
+
//Custom translations
import: conf/import/msg_conf.txt
diff --git a/db/mob_db2.conf b/db/mob_db2.conf
index 8d3e67904..e2894a719 100644
--- a/db/mob_db2.conf
+++ b/db/mob_db2.conf
@@ -89,6 +89,8 @@ mob_db: (
}
Drops: {
AegisName: chance (string: int)
+ // or
+ AegisName: (chance, "Option Drop Group")
// ...
}
},
diff --git a/db/option_drop_groups.conf b/db/option_drop_groups.conf
new file mode 100644
index 000000000..b293be19a
--- /dev/null
+++ b/db/option_drop_groups.conf
@@ -0,0 +1,53 @@
+//================= Hercules Database =====================================
+//= _ _ _
+//= | | | | | |
+//= | |_| | ___ _ __ ___ _ _| | ___ ___
+//= | _ |/ _ \ '__/ __| | | | |/ _ \/ __|
+//= | | | | __/ | | (__| |_| | | __/\__ \
+//= \_| |_/\___|_| \___|\__,_|_|\___||___/
+//================= License ===============================================
+//= This file is part of Hercules.
+//= http://herc.ws - http://github.com/HerculesWS/Hercules
+//=
+//= Copyright (C) 2018 Hercules Dev Team
+//=
+//= Hercules is free software: you can redistribute it and/or modify
+//= it under the terms of the GNU General Public License as published by
+//= the Free Software Foundation, either version 3 of the License, or
+//= (at your option) any later version.
+//=
+//= This program is distributed in the hope that it will be useful,
+//= but WITHOUT ANY WARRANTY; without even the implied warranty of
+//= MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+//= GNU General Public License for more details.
+//=
+//= You should have received a copy of the GNU General Public License
+//= along with this program. If not, see <http://www.gnu.org/licenses/>.
+//=========================================================================
+//= Random Option Drop Group Database
+//=========================================================================
+
+option_drop_group_db: (
+{
+/**************************************************************************
+ ************* Entry structure ********************************************
+ **************************************************************************
+ <Group Name Constant>: (
+ { // Option Slot 1
+ Rate: (int) chance of filling option slot 1 (100 = 1%)
+
+ // Possible options for slot 1
+ // min/max value : int, defaults to 0
+ // chance : int, 100 = 1% if not set, will be 100%/number of possibiltiies
+ OptionName: value
+ // or
+ OptionName: [min value, max value]
+ // or
+ OptionName: [min value, max value, chance]
+ // ... (as many as you want)
+ },
+ // ... (up to MAX_ITEM_OPTION)
+ ),
+**************************************************************************/
+}
+)
diff --git a/db/pre-re/mob_db.conf b/db/pre-re/mob_db.conf
index 40635cd68..553593cea 100644
--- a/db/pre-re/mob_db.conf
+++ b/db/pre-re/mob_db.conf
@@ -89,6 +89,8 @@ mob_db: (
}
Drops: {
AegisName: chance (string: int)
+ // or
+ AegisName: (chance, "Option Drop Group")
// ...
}
},
diff --git a/db/re/item_combo_db.txt b/db/re/item_combo_db.txt
index 739be9a65..3cbaef807 100644
--- a/db/re/item_combo_db.txt
+++ b/db/re/item_combo_db.txt
@@ -436,3 +436,4 @@
24238:24239,{ bonus bAtk,5; if(getequiprefinerycnt(EQI_SHADOW_ACC_R) + getequiprefinerycnt(EQI_SHADOW_ACC_L) >=15) { bonus2 bAddSize,Size_Small,1; } }
24240:24241:24242,{ bonus bUseSPrate,-1; .@refine = getequiprefinerycnt(EQI_SHADOW_SHIELD)+getequiprefinerycnt(EQI_SHADOW_ARMOR)+getequiprefinerycnt(EQI_SHADOW_SHOES); bonus bVariableCastrate,(.@refine)/5; if(.@refine)>=25 { bonus bUseSPrate,-1; } }
24243:24244:24245,{ bonus bDelayrate,-1; if (getequiprefinerycnt(EQI_SHADOW_SHIELD)+getequiprefinerycnt(EQI_SHADOW_ARMOR)+getequiprefinerycnt(EQI_SHADOW_SHOES) >= 25) bonus bDelayrate,-5; }
+2161:1646,{ .@r = (getequiprefinerycnt(EQI_HAND_L)*4); bonus2 bVariableCastrate,"WZ_STORMGUST",-.@r; bonus2 bVariableCastrate,"WL_FROSTMISTY",-.@r; bonus2 bVariableCastrate,"WL_JACKFROST",-.@r; }
diff --git a/db/re/mob_db.conf b/db/re/mob_db.conf
index e90b478e7..f787d5478 100644
--- a/db/re/mob_db.conf
+++ b/db/re/mob_db.conf
@@ -89,6 +89,8 @@ mob_db: (
}
Drops: {
AegisName: chance (string: int)
+ // or
+ AegisName: (chance, "Option Drop Group")
// ...
}
},
diff --git a/doc/atcommands.txt b/doc/atcommands.txt
index b455d9151..dd8ad0969 100644
--- a/doc/atcommands.txt
+++ b/doc/atcommands.txt
@@ -692,9 +692,23 @@ Repairs all broken items in your inventory.
---------------------------------------
-@dropall
-
-Drops all inventory and equipped items onto the floor.
+@dropall {<item type>}
+
+Drops all items based on the item type.
+
+Valid item types:
+ -1 = All Items (default)
+ 0 = Healing Items
+ 2 = Useable Items
+ 3 = Etc Items
+ 4 = Weapons
+ 5 = Armors
+ 6 = Cards
+ 7 = Pet Eggs
+ 8 = Pet Armors
+ 10 = Ammunition Items
+ 11 = Delayed-Consumable Items
+ 18 = Cash Items
---------------------------------------
diff --git a/doc/constants.md b/doc/constants.md
index aedb1755e..1fce24643 100644
--- a/doc/constants.md
+++ b/doc/constants.md
@@ -4262,6 +4262,15 @@
- `MAPINFO_SIZE_Y`: 3
- `MAPINFO_ZONE`: 4
+### consolemes options
+
+- `CONSOLEMES_DEBUG`: 0
+- `CONSOLEMES_ERROR`: 1
+- `CONSOLEMES_WARNING`: 2
+- `CONSOLEMES_INFO`: 3
+- `CONSOLEMES_STATUS`: 4
+- `CONSOLEMES_NOTICE`: 5
+
### set/getiteminfo options
- `ITEMINFO_BUYPRICE`: 0
diff --git a/doc/mob_db.txt b/doc/mob_db.txt
index 29d2ab465..d62181048 100644
--- a/doc/mob_db.txt
+++ b/doc/mob_db.txt
@@ -63,10 +63,14 @@ mob_db: (
MvpExp: mvp experience (int, defaults to 0)
MvpDrops: {
AegisName: chance (string: int)
+ // or
+ AegisName: (chance, "Option Drop Group")
// ...
}
Drops: {
- AegisName: chance (string: int)
+ AegisName: chance (string: int)
+ // or
+ AegisName: (chance, "Option Drop Group")
// ...
}
},
@@ -199,21 +203,55 @@ MvpExp: Base Experience given by the monster to the player who inflict more atta
MvpDrops: Sets monster mvp drops list. Requires to have MvpExp to trigger.
- Accepted values are AegisName as defined on item_db.conf and a chance.
+ There are two ways to define a drop:
+ 1) The first one is used for simple drops and uses the item AegisName
+ as defined on item_db.conf and a chance.
+ Format:
+ AegisName: chance
Chance is an integer from 1 to 10000 (10000 = 100%).
- Required format:
- MvpDrops: {
- AegisName: chance
- // ...
- }
- When not specified, becomes false.
+
+ 2) The second way to define a drop allows setting a random option drop
+ group to be used by this drop.
+ Format:
+ AegisName: (chance, "Option Drop Group")
+
+ The item drop chance refers to the chance of dropping this item, same as chance in the first option.
+ the "Option Drop Group" parameter refers to an entry on option_drop_group database file. The specified
+ entry will be used when this item is dropped in order to add random options to the dropped equipment.
+
+ A monster drop list may use both format for different items.
+ Required Format:
+ Drops: {
+ AegisName: chance
+ // or
+ AegisName: (chance, "Option Drop Group")
+ }
+
+ When not specified, becomes false (no drops).
Drops: Sets monster drops list.
- Accepted values are AegisName as defined on item_db.conf and a chance.
+ There are two ways to define a drop:
+ 1) The first one is used for simple drops and uses the item AegisName
+ as defined on item_db.conf and a chance.
+ Format:
+ AegisName: chance
Chance is an integer from 1 to 10000 (10000 = 100%).
- Required format:
- Drops: {
- AegisName: chance
- // ...
- }
- When not specified, becomes false.
+
+ 2) The second way to define a drop allows setting a random option drop
+ group to be used by this drop.
+ Format:
+ AegisName: (chance, "Option Drop Group")
+
+ The item drop chance refers to the chance of dropping this item, same as chance in the first option.
+ the "Option Drop Group" parameter refers to an entry on option_drop_group database file. The specified
+ entry will be used when this item is dropped in order to add random options to the dropped equipment.
+
+ A monster drop list may use both format for different items.
+ Required Format:
+ Drops: {
+ AegisName: chance
+ // or
+ AegisName: (chance, "Option Drop Group")
+ }
+
+ When not specified, becomes false (no drops).
diff --git a/doc/option_drop_group.md b/doc/option_drop_group.md
new file mode 100644
index 000000000..325cf9fe2
--- /dev/null
+++ b/doc/option_drop_group.md
@@ -0,0 +1,97 @@
+# Option Drop Group Database
+
+## Description
+Explanation of the `db/option_drop_groups.conf` file and structure.
+
+This database file allows the creation of groups of random options
+that will be added to certain equipments when dropped. After creating
+a group in this database file, you may set up drops in `mob_db` to use
+it in order to get items with these options. For more information on
+adding option drop groups to `mob_db`, check `doc/mob_db.txt` documentation file.
+
+Each item may have up to `MAX_ITEM_OPTION` options at the same time,
+in this document, each of these independent options will be called
+`option slot`. One drop group will define the possibilities of random
+options for each of these slots.
+
+## Entries Format
+
+```
+<Group Name Constant>: (
+ { // Option Slot 1
+ Rate: (int) chance of filling option slot 1 (100 = 1%)
+
+ // Possible options for slot 1
+ // min/max value : int, defaults to 0
+ // chance : int, 100 = 1% if not set, will be 100%/number of possibiltiies
+ OptionName: value
+ // or
+ OptionName: [min value, max value]
+ // or
+ OptionName: [min value, max value, chance]
+ // ... (as many as you want)
+ },
+ // ... (up to MAX_ITEM_OPTION)
+),
+```
+
+### `Group Name Constant`
+This is the group name, it is how this group is referenced in other files
+(e.g. mob_db). It must be globally unique, as it is a server constant, and
+must contain only letters, numbers and " _ ".
+
+### `Rate`
+This is the chance of this option slot to drop. In other words, this is the
+chance of getting this slot filled with something, where something is given
+by the list of `OptionName` that follows.
+
+Rate is an integer value where 100 means 1%.
+
+### `OptionName`
+Adds `OptionName` as one option that may fill this slot when it drops.
+
+The details of this option may be specified in one of 3 ways:
+
+#### `OptionName: value`
+The chance of this option being picked is auto calculated (see below),
+and if this option is chosen, its value will be `value`.
+
+#### `OptionName: [min, max]`
+The chance of this option being picked is auto calculated (see below),
+and if this option is chosen, its value will be a random integer between
+`min` and `max` (both included).
+
+#### `OptionName: [min, max, chance]`
+The chance of this option being picked is `chance`, and if this option is chosen,
+its value will be a random integer between `min` and `max` (both included).
+
+#### Auto calculated chances
+When chance is not specified in an option, it will be auto calculated by
+the server as being `100%/num`, when `num` is the number of possibilities
+in this option slot.
+
+For example, if you specify 3 possible options, all of them without
+a `chance` defined, all of them will have 33.33% chance of being
+picked (100%/3). If you set the chance of one of them to 50%, you
+will have one option with 50% chance, and each of the others with
+33.33% chance.
+
+## Example
+```
+MYITEM: (
+ { // Option Slot 1
+ Rate: 10000 // It has 100% of chance of being filled
+
+ // This slot may have one of the following options:
+ WEAPON_ATTR_WIND: 5, // WEAPON_ATTR_WIND Lv5 (33.33%)
+ WEAPON_ATTR_GROUND: [2, 4] // WEAPON_ATTR_GROUND Lv 2~4 (33.33%)
+ WEAPON_ATTR_POISON: [1, 4, 8000] // WEAPON_ATTR_POISON Lv 1~4 (80%)
+ },
+ { // Option Slot 2
+ Rate: 5000 // It has 50% of chance of being filled
+
+ // If filled, may have one of the following options:
+ WEAPON_ATTR_WATER: 4 // WEAPON_ATTR_WATER Lv4 (100%)
+ }
+)
+```
diff --git a/doc/script_commands.txt b/doc/script_commands.txt
index fd593f17e..4cfb821a3 100644
--- a/doc/script_commands.txt
+++ b/doc/script_commands.txt
@@ -7776,6 +7776,10 @@ solution rather than sending the map and the monster_id.
*debugmes("<format string>"{, <param>{, ...}})
+ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+ @ /!\ This command is deprecated @
+ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+
This command will print a message in the server console (map-server window),
after applying the same format-string replacements as sprintf(). It will not be
displayed anywhere else. Returns true on success.
@@ -7789,6 +7793,29 @@ Example:
---------------------------------------
+*consolemes("<type>", "<format string>"{,<param>{, ...}})
+
+This command will print a message in the server console (map-server window),
+after applying the same format-string replacements as sprintf(). It will not be
+displayed anywhere else. Returns true on success.
+
+List of available <type> are:
+ CONSOLEMES_DEBUG = 0
+ CONSOLEMES_ERROR = 1
+ CONSOLEMES_WARNING = 2
+ CONSOLEMES_INFO = 3
+ CONSOLEMES_STATUS = 4
+ CONSOLEMES_NOTICE = 5
+
+Example:
+
+ // Displays "NAME has clicked me!" in the map-server window.
+ consolemes(CONSOLEMES_DEBUG, "%s has clicked me!", strcharinfo(PC_NAME));
+
+ consolemes(CONSOLEMES_DEBUG, "\033[0;32mHello World"); // supports ANSI escape sequences
+
+---------------------------------------
+
*logmes("<message>"{, <log type>})
This command will write the message given to the map server log files, as
diff --git a/npc/custom/etc/quest_warper.txt b/npc/custom/etc/quest_warper.txt
index 35b863e9d..2ae2e7f7f 100644
--- a/npc/custom/etc/quest_warper.txt
+++ b/npc/custom/etc/quest_warper.txt
@@ -82,7 +82,7 @@ function script Q_Warpra {
case 2:
warp $QW_SP_WarpMap$, $QW_SP_WarpX, $QW_SP_WarpY;
close2;
- debugmes "Please check your special warp menu settings on the Warpra.";
+ consolemes(CONSOLEMES_WARNING, "Please check your special warp menu settings on the Warpra.");
end;
case 3: goto L_town;
case 4: goto L_dungeon;
@@ -1533,7 +1533,7 @@ function script QWS_Dungeon_Warpra {
mes "[Warpra]";
mes "Sorry, I can only unlock this location.";
} else
- debugmes "QWS_Dungeon_Warpra error, improper syntax?";
+ consolemes(CONSOLEMES_ERROR, "QWS_Dungeon_Warpra error, improper syntax?");
return;
function QWS_D_setbin {
@@ -1577,7 +1577,7 @@ function script QWS_Town_Warpra {
} else if (QWS_T_getbin(getarg(0)) == 1) {
callfunc "Q_Warpra",0;
} else
- debugmes "QWS_Town_Warpra error, improper syntax ?";
+ consolemes(CONSOLEMES_ERROR, "QWS_Town_Warpra error, improper syntax ?");
return;
function QWS_T_setbin {
diff --git a/npc/custom/events/mushroom_event.txt b/npc/custom/events/mushroom_event.txt
index b9c54c09e..b04b99fff 100644
--- a/npc/custom/events/mushroom_event.txt
+++ b/npc/custom/events/mushroom_event.txt
@@ -50,9 +50,12 @@ OnMinute10: // Start time (every hour)
OnMobKilled:
set .Spawn, .Spawn - 1;
- getitem .Prize, .Amount;
- if (.Spawn) announce "[ "+strcharinfo(PC_NAME)+" ] has killed a Mushroom. There are now "+.Spawn+" Mushroom(s) left.",bc_map;
- else {
+ if (playerattached() != 0) {
+ getitem .Prize, .Amount;
+ if (.Spawn)
+ announce "[ "+strcharinfo(PC_NAME)+" ] has killed a Mushroom. There are now "+.Spawn+" Mushroom(s) left.",bc_map;
+ }
+ if (!.Spawn) {
announce "The Find the Mushroom Event has ended. All the Mushrooms have been killed.",0;
set .status,0;
}
diff --git a/npc/custom/quests/quest_shop.txt b/npc/custom/quests/quest_shop.txt
index 739b53c02..c2481e991 100644
--- a/npc/custom/quests/quest_shop.txt
+++ b/npc/custom/quests/quest_shop.txt
@@ -170,13 +170,13 @@ OnEnd:
function Add {
if (getitemname(getarg(1)) == "null") {
- debugmes "Quest reward #"+getarg(1)+" invalid (skipped).";
+ consolemes(CONSOLEMES_WARNING, "Quest reward #"+getarg(1)+" invalid (skipped).");
return;
}
setarray .@j[0],getarg(2),getarg(3),getarg(4);
for(set .@i,5; .@i<getargcount(); set .@i,.@i+2) {
if (getitemname(getarg(.@i)) == "null") {
- debugmes "Quest requirement #"+getarg(.@i)+" invalid (skipped).";
+ consolemes(CONSOLEMES_WARNING, "Quest requirement #"+getarg(.@i)+" invalid (skipped).");
return;
} else
setarray .@j[.@i-2],getarg(.@i),getarg(.@i+1);
diff --git a/npc/custom/quests/thq/THQS_TTShop.txt b/npc/custom/quests/thq/THQS_TTShop.txt
index 96e7346d3..4c12f9938 100644
--- a/npc/custom/quests/thq/THQS_TTShop.txt
+++ b/npc/custom/quests/thq/THQS_TTShop.txt
@@ -93,7 +93,7 @@ function script thqs_trade_token {
// getarg(1) - .@mp$ -> PRICE
function script thqs_menu_buy {
if( getargcount() != 2 ) {
- debugmes "thqs_menu_buy: Wrong number of arguments!!";
+ consolemes(CONSOLEMES_ERROR, "thqs_menu_buy: Wrong number of arguments!!");
close;
}
@@ -101,7 +101,7 @@ function script thqs_menu_buy {
.@mp$ = getarg(1);
if( getarraysize( getd(.@mw$) ) != getarraysize( getd(.@mp$) ) ) {
- debugmes "thqs_menu_buy: Missing entries in data!";
+ consolemes(CONSOLEMES_ERROR, "thqs_menu_buy: Missing entries in data!");
close;
}
diff --git a/npc/dev/test.txt b/npc/dev/test.txt
index 2822ee65c..a867a09b2 100644
--- a/npc/dev/test.txt
+++ b/npc/dev/test.txt
@@ -786,10 +786,10 @@ function script HerculesSelfTestHelper {
callsub(OnCheck, "data_to_string (integer variable)", data_to_string(.@x), ".@x");
if (.errors) {
- debugmes "Script engine self-test [ \033[0;31mFAILED\033[0m ]";
- debugmes "**** The test was completed with " + .errors + " errors. ****";
+ consolemes(CONSOLEMES_DEBUG, "Script engine self-test [ \033[0;31mFAILED\033[0m ]");
+ consolemes(CONSOLEMES_DEBUG, "**** The test was completed with " + .errors + " errors. ****");
} else {
- debugmes "Script engine self-test [ \033[0;32mPASSED\033[0m ]";
+ consolemes(CONSOLEMES_DEBUG, "Script engine self-test [ \033[0;32mPASSED\033[0m ]");
}
return .errors;
end;
@@ -840,8 +840,8 @@ OnReportError:
.@val$ = getarg(1,"");
.@ref$ = getarg(2,"");
if (.errors == 1)
- debugmes "**** WARNING: Any self-test results past this point are unreliable because of previous errors. ****";
- debugmes "Error: "+.@msg$+": '"+.@val$+"' (found) != '"+.@ref$+"' (expected)";
+ consolemes(CONSOLEMES_DEBUG, "**** WARNING: Any self-test results past this point are unreliable because of previous errors. ****");
+ consolemes(CONSOLEMES_DEBUG, "Error: "+.@msg$+": '"+.@val$+"' (found) != '"+.@ref$+"' (expected)");
++.errors;
//end;
return;
diff --git a/npc/woe-fe/agit_main.txt b/npc/woe-fe/agit_main.txt
index 5ac5b8e9a..a0db6402b 100644
--- a/npc/woe-fe/agit_main.txt
+++ b/npc/woe-fe/agit_main.txt
@@ -105,7 +105,8 @@ OnAgitBreak:
// Show and log error if an unguilded player breaks the Emperium. (Should NEVER happen)
if (.@GID <= 0) {
.@notice$ = "Character "+strcharinfo(PC_NAME)+" ("+getcharid(CHAR_ID_CHAR)+") broke the Emperium in Castle: "+strnpcinfo(NPC_NAME_HIDDEN)+" while guildless. No data will be saved and Emperium respawned.";
- logmes .@notice$; debugmes .@notice$;
+ logmes .@notice$;
+ consolemes(CONSOLEMES_NOTICE, .@notice$);
donpcevent "Agit#"+strnpcinfo(NPC_NAME_HIDDEN)+"::OnStartArena";
end;
}
diff --git a/src/char/int_rodex.c b/src/char/int_rodex.c
index 5725c3777..ffa5f5452 100644
--- a/src/char/int_rodex.c
+++ b/src/char/int_rodex.c
@@ -346,11 +346,128 @@ static int64 inter_rodex_savemessage(struct rodex_message *msg)
return msg->id;
}
+static int64 inter_rodex_getzeny(int64 mail_id)
+{
+ Assert_retr(-1, mail_id > 0);
+
+ if (SQL_ERROR == SQL->Query(inter->sql_handle, "SELECT `zeny`, `type` FROM `%s` WHERE `mail_id` = '%"PRId64"'", rodex_db, mail_id)) {
+ Sql_ShowDebug(inter->sql_handle);
+ } else {
+ if (SQL_SUCCESS == SQL->NextRow(inter->sql_handle)) {
+ char *data;
+ SQL->GetData(inter->sql_handle, 0, &data, NULL);
+ int64 zeny = atoi(data);
+ SQL->GetData(inter->sql_handle, 1, &data, NULL);
+ uint8 type = atoi(data);
+ SQL->FreeResult(inter->sql_handle);
+ if ((type & MAIL_TYPE_ZENY) == 0)
+ return -1;
+ return zeny;
+ }
+ }
+ SQL->FreeResult(inter->sql_handle);
+
+ return -1;
+}
+
+static int inter_rodex_getitems(int64 mail_id, struct rodex_item *items)
+{
+ Assert_retr(-1, mail_id > 0);
+ nullpo_retr(-1, items);
+
+ if (SQL_ERROR == SQL->Query(inter->sql_handle, "SELECT `type` FROM `%s` WHERE `mail_id` = '%"PRId64"'", rodex_db, mail_id)) {
+ Sql_ShowDebug(inter->sql_handle);
+ return -1;
+ } else {
+ if (SQL_SUCCESS == SQL->NextRow(inter->sql_handle)) {
+ char *data;
+ SQL->GetData(inter->sql_handle, 0, &data, NULL);
+ uint8 type = atoi(data);
+ SQL->FreeResult(inter->sql_handle);
+ if ((type & MAIL_TYPE_ITEM) == 0)
+ return -1;
+ } else {
+ SQL->FreeResult(inter->sql_handle);
+ return -1;
+ }
+ }
+
+
+ int itemsCount = 0;
+
+ struct SqlStmt *stmt_items = SQL->StmtMalloc(inter->sql_handle);
+
+ if (stmt_items == NULL) {
+ return -1;
+ }
+
+ StringBuf buf;
+ StrBuf->Init(&buf);
+
+ StrBuf->AppendStr(&buf, "SELECT `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `bound`, `unique_id`");
+ for (int i = 0; i < MAX_SLOTS; i++) {
+ StrBuf->Printf(&buf, ", `card%d`", i);
+ }
+ for (int i = 0; i < MAX_ITEM_OPTIONS; i++) {
+ StrBuf->Printf(&buf, ", `opt_idx%d`, `opt_val%d`", i, i);
+ }
+ StrBuf->Printf(&buf, "FROM `%s` WHERE mail_id = ? ORDER BY `mail_id` ASC", rodex_item_db);
+
+ struct item it = { 0 };
+
+ if (SQL_ERROR == SQL->StmtPrepareStr(stmt_items, StrBuf->Value(&buf))
+ || SQL_ERROR == SQL->StmtBindParam(stmt_items, 0, SQLDT_INT64, &mail_id, sizeof mail_id)
+ ) {
+ SqlStmt_ShowDebug(stmt_items);
+ }
+
+ if (SQL_ERROR == SQL->StmtExecute(stmt_items)
+ || SQL_ERROR == SQL->StmtBindColumn(stmt_items, 0, SQLDT_INT, &it.nameid, sizeof it.nameid, NULL, NULL)
+ || SQL_ERROR == SQL->StmtBindColumn(stmt_items, 1, SQLDT_SHORT, &it.amount, sizeof it.amount, NULL, NULL)
+ || SQL_ERROR == SQL->StmtBindColumn(stmt_items, 2, SQLDT_UINT, &it.equip, sizeof it.equip, NULL, NULL)
+ || SQL_ERROR == SQL->StmtBindColumn(stmt_items, 3, SQLDT_CHAR, &it.identify, sizeof it.identify, NULL, NULL)
+ || SQL_ERROR == SQL->StmtBindColumn(stmt_items, 4, SQLDT_CHAR, &it.refine, sizeof it.refine, NULL, NULL)
+ || SQL_ERROR == SQL->StmtBindColumn(stmt_items, 5, SQLDT_CHAR, &it.attribute, sizeof it.attribute, NULL, NULL)
+ || SQL_ERROR == SQL->StmtBindColumn(stmt_items, 6, SQLDT_UINT, &it.expire_time, sizeof it.expire_time, NULL, NULL)
+ || SQL_ERROR == SQL->StmtBindColumn(stmt_items, 7, SQLDT_UCHAR, &it.bound, sizeof it.bound, NULL, NULL)
+ || SQL_ERROR == SQL->StmtBindColumn(stmt_items, 8, SQLDT_UINT64, &it.unique_id, sizeof it.unique_id, NULL, NULL)
+ ) {
+ SqlStmt_ShowDebug(stmt_items);
+ }
+ for (int i = 0; i < MAX_SLOTS; i++) {
+ if (SQL_ERROR == SQL->StmtBindColumn(stmt_items, 9 + i, SQLDT_INT, &it.card[i], sizeof it.card[i], NULL, NULL))
+ SqlStmt_ShowDebug(stmt_items);
+ }
+ for (int i = 0; i < MAX_ITEM_OPTIONS; i++) {
+ if (SQL_ERROR == SQL->StmtBindColumn(stmt_items, 9 + MAX_SLOTS + i * 2, SQLDT_INT16, &it.option[i].index, sizeof it.option[i].index, NULL, NULL)
+ || SQL_ERROR == SQL->StmtBindColumn(stmt_items, 10 + MAX_SLOTS + i * 2, SQLDT_INT16, &it.option[i].value, sizeof it.option[i].value, NULL, NULL)
+ ) {
+ SqlStmt_ShowDebug(stmt_items);
+ }
+ }
+
+ for (int i = 0; i < RODEX_MAX_ITEM && SQL_SUCCESS == SQL->StmtNextRow(stmt_items); ++i) {
+ items[i].item = it;
+ items[i].idx = itemsCount;
+ itemsCount++;
+ }
+
+ SQL->StmtFreeResult(stmt_items);
+
+ StrBuf->Destroy(&buf);
+ SQL->StmtFree(stmt_items);
+
+ return itemsCount;
+}
+
/*==========================================
* Update/Delete mail
*------------------------------------------*/
-static bool inter_rodex_updatemail(int64 mail_id, int8 flag)
+static bool inter_rodex_updatemail(int fd, int account_id, int char_id, int64 mail_id, uint8 opentype, int8 flag)
{
+ Assert_retr(false, fd >= 0);
+ Assert_retr(false, account_id > 0);
+ Assert_retr(false, char_id > 0);
Assert_retr(false, mail_id > 0);
Assert_retr(false, flag >= 0 && flag <= 4);
@@ -361,17 +478,26 @@ static bool inter_rodex_updatemail(int64 mail_id, int8 flag)
break;
case 1: // Get Zeny
- if (SQL_ERROR == SQL->Query(inter->sql_handle, "UPDATE `%s` SET `zeny` = 0, `type` = `type` & (~2) WHERE `mail_id` = '%"PRId64"'", rodex_db, mail_id))
+ {
+ const int64 zeny = inter_rodex->getzeny(mail_id);
+ if (SQL_ERROR == SQL->Query(inter->sql_handle, "UPDATE `%s` SET `zeny` = 0, `type` = `type` & (~2) WHERE `mail_id` = '%"PRId64"'", rodex_db, mail_id)) {
Sql_ShowDebug(inter->sql_handle);
+ break;
+ }
+ mapif->rodex_getzenyack(fd, char_id, mail_id, opentype, zeny);
break;
-
+ }
case 2: // Get Items
+ {
+ struct rodex_item items[RODEX_MAX_ITEM];
+ const int count = inter_rodex->getitems(mail_id, &items[0]);
if (SQL_ERROR == SQL->Query(inter->sql_handle, "DELETE FROM `%s` WHERE `mail_id` = '%"PRId64"'", rodex_item_db, mail_id))
Sql_ShowDebug(inter->sql_handle);
if (SQL_ERROR == SQL->Query(inter->sql_handle, "UPDATE `%s` SET `zeny` = 0, `type` = `type` & (~4) WHERE `mail_id` = '%"PRId64"'", rodex_db, mail_id))
Sql_ShowDebug(inter->sql_handle);
+ mapif->rodex_getitemsack(fd, char_id, mail_id, opentype, count, &items[0]);
break;
-
+ }
case 3: // Delete Mail
if (SQL_ERROR == SQL->Query(inter->sql_handle, "DELETE FROM `%s` WHERE `mail_id` = '%"PRId64"'", rodex_db, mail_id))
Sql_ShowDebug(inter->sql_handle);
@@ -429,4 +555,6 @@ void inter_rodex_defaults(void)
inter_rodex->hasnew = inter_rodex_hasnew;
inter_rodex->checkname = inter_rodex_checkname;
inter_rodex->updatemail = inter_rodex_updatemail;
+ inter_rodex->getzeny = inter_rodex_getzeny;
+ inter_rodex->getitems = inter_rodex_getitems;
}
diff --git a/src/char/int_rodex.h b/src/char/int_rodex.h
index 7fae77d8d..a6a172ceb 100644
--- a/src/char/int_rodex.h
+++ b/src/char/int_rodex.h
@@ -36,7 +36,9 @@ struct inter_rodex_interface {
bool (*hasnew) (int char_id, int account_id);
bool (*checkname) (const char *name, int *target_char_id, int *target_class, int *target_level);
int64 (*savemessage) (struct rodex_message* msg);
- bool (*updatemail) (int64 mail_id, int8 flag);
+ bool (*updatemail) (int fd, int account_id, int char_id, int64 mail_id, uint8 opentype, int8 flag);
+ int64 (*getzeny) (int64 mail_id);
+ int (*getitems) (int64 mail_id, struct rodex_item *items);
};
#ifdef HERCULES_CORE
diff --git a/src/char/inter.c b/src/char/inter.c
index 1f1750e32..64c840c16 100644
--- a/src/char/inter.c
+++ b/src/char/inter.c
@@ -79,7 +79,7 @@ static int inter_recv_packet_length[] = {
6,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3060- Quest system [Kevin] [Inkfish]
-1,10, 6,-1, 0, 0, 0, 0, 0, 0, 0, 0, -1,10, 6,-1, // 3070- Mercenary packets [Zephyrus], Elemental packets [pakpil]
56,14,-1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3080-
- -1,10,-1, 6, 0, 20,10,11, -1,6 + NAME_LENGTH, 0, 0, 0, 0, 0, 0, // 3090- Homunculus packets [albator], RoDEX packets
+ -1,10,-1, 6, 0, 20,10,20, -1,6 + NAME_LENGTH, 0, 0, 0, 0, 0, 0, // 3090- Homunculus packets [albator], RoDEX packets
};
static struct DBMap *wis_db = NULL; // int wis_id -> struct WisData*
diff --git a/src/char/mapif.c b/src/char/mapif.c
index fb904a46d..8f213ecb5 100644
--- a/src/char/mapif.c
+++ b/src/char/mapif.c
@@ -1744,10 +1744,13 @@ static void mapif_rodex_sendhasnew(int fd, int char_id, bool has_new)
*------------------------------------------*/
static void mapif_parse_rodex_updatemail(int fd)
{
- int64 mail_id = RFIFOL(fd, 2);
- int8 flag = RFIFOB(fd, 10);
+ int account_id = RFIFOL(fd, 2);
+ int char_id = RFIFOL(fd, 6);
+ int64 mail_id = RFIFOQ(fd, 10);
+ uint8 opentype = RFIFOB(fd, 18);
+ int8 flag = RFIFOB(fd, 19);
- inter_rodex->updatemail(mail_id, flag);
+ inter_rodex->updatemail(fd, account_id, char_id, mail_id, opentype, flag);
}
/*==========================================
@@ -2461,6 +2464,29 @@ static void mapif_achievement_save(int char_id, struct char_achievements *p)
inter_achievement->tosql(char_id, cp, p);
}
+static void mapif_rodex_getzenyack(int fd, int char_id, int64 mail_id, uint8 opentype, int64 zeny)
+{
+ WFIFOHEAD(fd, 23);
+ WFIFOW(fd, 0) = 0x3899;
+ WFIFOL(fd, 2) = char_id;
+ WFIFOQ(fd, 6) = zeny;
+ WFIFOQ(fd, 14) = mail_id;
+ WFIFOB(fd, 22) = opentype;
+ WFIFOSET(fd, 23);
+}
+
+static void mapif_rodex_getitemsack(int fd, int char_id, int64 mail_id, uint8 opentype, int count, const struct rodex_item *items)
+{
+ WFIFOHEAD(fd, 15 + sizeof(struct rodex_item) * RODEX_MAX_ITEM);
+ WFIFOW(fd, 0) = 0x389a;
+ WFIFOL(fd, 2) = char_id;
+ WFIFOQ(fd, 6) = mail_id;
+ WFIFOB(fd, 14) = opentype;
+ WFIFOB(fd, 15) = count;
+ memcpy(WFIFOP(fd, 16), items, sizeof(struct rodex_item) * RODEX_MAX_ITEM);
+ WFIFOSET(fd, 16 + sizeof(struct rodex_item) * RODEX_MAX_ITEM);
+}
+
void mapif_defaults(void)
{
mapif = &mapif_s;
@@ -2605,6 +2631,8 @@ void mapif_defaults(void)
mapif->rodex_send = mapif_rodex_send;
mapif->parse_rodex_checkname = mapif_parse_rodex_checkname;
mapif->rodex_checkname = mapif_rodex_checkname;
+ mapif->rodex_getzenyack = mapif_rodex_getzenyack;
+ mapif->rodex_getitemsack = mapif_rodex_getitemsack;
mapif->load_guild_storage = mapif_load_guild_storage;
mapif->save_guild_storage_ack = mapif_save_guild_storage_ack;
mapif->parse_LoadGuildStorage = mapif_parse_LoadGuildStorage;
diff --git a/src/char/mapif.h b/src/char/mapif.h
index f57748ac6..71a41f94c 100644
--- a/src/char/mapif.h
+++ b/src/char/mapif.h
@@ -24,6 +24,7 @@
#include "common/mmo.h"
struct WisData;
+struct rodex_item;
/**
* mapif interface
@@ -168,6 +169,8 @@ struct mapif_interface {
void (*rodex_send) (int fd, int sender_id, int receiver_id, int receiver_accountid, bool result);
void (*parse_rodex_checkname) (int fd);
void (*rodex_checkname) (int fd, int reqchar_id, int target_char_id, int target_class, int target_level, char *name);
+ void (*rodex_getzenyack) (int fd, int char_id, int64 mail_id, uint8 opentype, int64 zeny);
+ void (*rodex_getitemsack) (int fd, int char_id, int64 mail_id, uint8 opentype, int count, const struct rodex_item *items);
int (*load_guild_storage) (int fd, int account_id, int guild_id, char flag);
int (*save_guild_storage_ack) (int fd, int account_id, int guild_id, int fail);
int (*parse_LoadGuildStorage) (int fd);
diff --git a/src/common/HPMDataCheck.h b/src/common/HPMDataCheck.h
index 57b57c345..02d6c9631 100644
--- a/src/common/HPMDataCheck.h
+++ b/src/common/HPMDataCheck.h
@@ -230,6 +230,7 @@ HPExport const struct s_HPMDataCheck HPMDataCheck[] = {
{ "party_member", sizeof(struct party_member), SERVER_TYPE_ALL },
{ "point", sizeof(struct point), SERVER_TYPE_ALL },
{ "quest", sizeof(struct quest), SERVER_TYPE_ALL },
+ { "rodex_item", sizeof(struct rodex_item), SERVER_TYPE_ALL },
{ "rodex_maillist", sizeof(struct rodex_maillist), SERVER_TYPE_ALL },
{ "rodex_message", sizeof(struct rodex_message), SERVER_TYPE_ALL },
{ "s_elemental", sizeof(struct s_elemental), SERVER_TYPE_ALL },
@@ -590,8 +591,12 @@ HPExport const struct s_HPMDataCheck HPMDataCheck[] = {
{ "mob_chat", sizeof(struct mob_chat), SERVER_TYPE_MAP },
{ "mob_data", sizeof(struct mob_data), SERVER_TYPE_MAP },
{ "mob_db", sizeof(struct mob_db), SERVER_TYPE_MAP },
+ { "mob_drop", sizeof(struct mob_drop), SERVER_TYPE_MAP },
{ "mob_interface", sizeof(struct mob_interface), SERVER_TYPE_MAP },
{ "mob_skill", sizeof(struct mob_skill), SERVER_TYPE_MAP },
+ { "optdrop_group", sizeof(struct optdrop_group), SERVER_TYPE_MAP },
+ { "optdrop_group_option", sizeof(struct optdrop_group_option), SERVER_TYPE_MAP },
+ { "optdrop_group_optslot", sizeof(struct optdrop_group_optslot), SERVER_TYPE_MAP },
{ "spawn_info", sizeof(struct spawn_info), SERVER_TYPE_MAP },
#else
#define MAP_MOB_H
diff --git a/src/common/mmo.h b/src/common/mmo.h
index 2fc464243..a29b0f2db 100644
--- a/src/common/mmo.h
+++ b/src/common/mmo.h
@@ -978,6 +978,11 @@ enum fame_list_type {
RANKTYPE_PK = 3, //Not supported yet
};
+struct rodex_item {
+ struct item item;
+ int idx;
+};
+
struct rodex_message {
int64 id;
int sender_id;
@@ -987,10 +992,7 @@ struct rodex_message {
char receiver_name[NAME_LENGTH];
char title[RODEX_TITLE_LENGTH];
char body[RODEX_BODY_LENGTH];
- struct {
- struct item item;
- int idx;
- } items[RODEX_MAX_ITEM];
+ struct rodex_item items[RODEX_MAX_ITEM];
int64 zeny;
uint8 type;
int8 opentype;
diff --git a/src/common/sysinfo.c b/src/common/sysinfo.c
index b8cb2a90a..e3977f440 100644
--- a/src/common/sysinfo.c
+++ b/src/common/sysinfo.c
@@ -2,7 +2,7 @@
* This file is part of Hercules.
* http://herc.ws - http://github.com/HerculesWS/Hercules
*
- * Copyright (C) 2013-2015 Hercules Dev Team
+ * Copyright (C) 2013-2019 Hercules Dev Team
* Copyright (C) Athena Dev Teams
*
* Hercules is free software: you can redistribute it and/or modify
@@ -221,8 +221,12 @@ enum windows_ver_suite {
#define SYSINFO_COMPILER "Microsoft Visual C++ 2012 (v" EXPAND_AND_QUOTE(_MSC_VER) ")"
#elif _MSC_VER >= 1800 && _MSC_VER < 1900
#define SYSINFO_COMPILER "Microsoft Visual C++ 2013 (v" EXPAND_AND_QUOTE(_MSC_VER) ")"
-#elif _MSC_VER >= 1900 && _MSC_VER < 2000
+#elif _MSC_VER >= 1900 && _MSC_VER < 1910
#define SYSINFO_COMPILER "Microsoft Visual C++ 2015 (v" EXPAND_AND_QUOTE(_MSC_VER) ")"
+#elif _MSC_VER >= 1910 && _MSC_VER < 1920
+#define SYSINFO_COMPILER "Microsoft Visual C++ 2017 (v" EXPAND_AND_QUOTE(_MSC_VER) ")"
+#elif _MSC_VER >= 1920 && _MSC_VER < 2000
+#define SYSINFO_COMPILER "Microsoft Visual C++ 2019 (v" EXPAND_AND_QUOTE(_MSC_VER) ")"
#else // < 1300 || >= 2000
#define SYSINFO_COMPILER "Microsoft Visual C++ v" EXPAND_AND_QUOTE(_MSC_VER)
#endif
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index a9bbff7bd..9ed56545c 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -5277,18 +5277,43 @@ ACMD(follow)
}
/*==========================================
- * @dropall by [MouseJstr]
- * Drop all your possession on the ground
+ * @dropall by [MouseJstr] and [Xantara]
+ * Drop all your possession on the ground based on item type
*------------------------------------------*/
ACMD(dropall)
{
+ int type = -1;
+ int count = 0;
+
+ if (message[0] != '\0') {
+ type = atoi(message);
+ if (!((type >= IT_HEALING && type <= IT_DELAYCONSUME) || type == IT_CASH || type == -1)) {
+ clif->message(fd, msg_fd(fd, 1500));
+ clif->message(fd, msg_fd(fd, 1501));
+ return false;
+ }
+ }
+
for (int i = 0; i < sd->status.inventorySize; i++) {
if (sd->status.inventory[i].amount) {
- if(sd->status.inventory[i].equip != 0)
- pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE);
- pc->dropitem(sd, i, sd->status.inventory[i].amount);
+ struct item_data *item_data = itemdb->exists(sd->status.inventory[i].nameid);
+ if (item_data == NULL) {
+ ShowWarning("Non-existant item %d on dropall list (account_id: %d, char_id: %d)\n", sd->status.inventory[i].nameid, sd->status.account_id, sd->status.char_id);
+ continue;
+ }
+ if (!pc->candrop(sd, &sd->status.inventory[i]))
+ continue;
+ if (type == -1 || type == item_data->type) {
+ if (sd->status.inventory[i].equip != 0)
+ pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC | PCUNEQUIPITEM_FORCE);
+ count += sd->status.inventory[i].amount;
+ pc->dropitem(sd, i, sd->status.inventory[i].amount);
+ }
}
}
+
+ sprintf(atcmd_output, msg_fd(fd, 1502), count); // %d items are dropped!
+ clif->message(fd, atcmd_output);
return true;
}
diff --git a/src/map/atcommand.h b/src/map/atcommand.h
index 1783e5dc6..4fbf6b93a 100644
--- a/src/map/atcommand.h
+++ b/src/map/atcommand.h
@@ -41,7 +41,7 @@ struct config_setting_t;
* Defines
**/
#define ATCOMMAND_LENGTH 50
-#define MAX_MSG 1500
+#define MAX_MSG 1503
#define msg_txt(idx) atcommand->msg(idx)
#define msg_sd(sd,msg_number) atcommand->msgsd((sd),(msg_number))
#define msg_fd(fd,msg_number) atcommand->msgfd((fd),(msg_number))
diff --git a/src/map/battle.c b/src/map/battle.c
index fe7a64b51..ba7c1130d 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -7417,6 +7417,7 @@ static const struct battle_data {
{ "features/enable_achievement_system", &battle_config.feature_enable_achievement, 1, 0, 1, },
{ "ping_timer_inverval", &battle_config.ping_timer_interval, 30, 0, 99999999, },
{ "ping_time", &battle_config.ping_time, 20, 0, 99999999, },
+ { "option_drop_max_loop", &battle_config.option_drop_max_loop, 10, 1, 100000, },
};
static bool battle_set_value_sub(int index, int value)
diff --git a/src/map/battle.h b/src/map/battle.h
index 723a86874..a99e95c86 100644
--- a/src/map/battle.h
+++ b/src/map/battle.h
@@ -583,6 +583,8 @@ struct Battle_Config {
int ping_timer_interval;
int ping_time;
+
+ int option_drop_max_loop;
};
/* criteria for battle_config.idletime_critera */
diff --git a/src/map/chat.c b/src/map/chat.c
index d9b642219..77a12a560 100644
--- a/src/map/chat.c
+++ b/src/map/chat.c
@@ -255,6 +255,14 @@ static int chat_leavechat(struct map_session_data *sd, bool kicked)
}
if( leavechar == 0 && cd->owner->type == BL_PC ) {
+
+ // check if new location are CELL_CHKNOCHAT
+ if (map->getcell(cd->usersd[0]->bl.m, NULL, cd->usersd[0]->bl.x, cd->usersd[0]->bl.y, CELL_CHKNOCHAT)) {
+ for (i = (cd->users - 1); i >= 0; i--)
+ chat->leave(cd->usersd[i], false);
+ return 2;
+ }
+
// Set and announce new owner
cd->owner = &cd->usersd[0]->bl;
clif->changechatowner(cd, cd->usersd[0]);
diff --git a/src/map/intif.c b/src/map/intif.c
index 86bf07bce..e25f56b63 100644
--- a/src/map/intif.c
+++ b/src/map/intif.c
@@ -2754,16 +2754,21 @@ static void intif_parse_RodexNotifications(int fd)
/// 2 - user got Items
/// 3 - delete
/// 4 - sender Read (returned mail)
-static int intif_rodex_updatemail(int64 mail_id, int8 flag)
+static int intif_rodex_updatemail(struct map_session_data *sd, int64 mail_id, uint8 opentype, int8 flag)
{
+ nullpo_ret(sd);
+
if (intif->CheckForCharServer())
return 0;
- WFIFOHEAD(inter_fd, 11);
+ WFIFOHEAD(inter_fd, 20);
WFIFOW(inter_fd, 0) = 0x3097;
- WFIFOQ(inter_fd, 2) = mail_id;
- WFIFOB(inter_fd, 10) = flag;
- WFIFOSET(inter_fd, 11);
+ WFIFOL(inter_fd, 2) = sd->status.account_id;
+ WFIFOL(inter_fd, 6) = sd->status.char_id;
+ WFIFOQ(inter_fd, 10) = mail_id;
+ WFIFOB(inter_fd, 18) = opentype;
+ WFIFOB(inter_fd, 19) = flag;
+ WFIFOSET(inter_fd, 20);
return 0;
}
@@ -2855,6 +2860,35 @@ static void intif_parse_RodexCheckName(int fd)
clif->rodex_checkname_result(sd, target_char_id, target_class, target_level, name);
}
+static void intif_parse_GetZenyAck(int fd)
+{
+ int char_id = RFIFOL(fd, 2);
+ int64 zeny = RFIFOL(fd, 6);
+ int64 mail_id = RFIFOQ(fd, 14);
+ uint8 opentype = RFIFOB(fd, 22);
+ struct map_session_data *sd = map->charid2sd(char_id);
+
+ if (sd == NULL) // User is not online anymore
+ return;
+ rodex->getZenyAck(sd, mail_id, opentype, zeny);
+}
+
+static void intif_parse_GetItemsAck(int fd)
+{
+ int char_id = RFIFOL(fd, 2);
+
+ struct map_session_data *sd = map->charid2sd(char_id);
+ if (sd == NULL) // User is not online anymore
+ return;
+
+ int64 mail_id = RFIFOQ(fd, 6);
+ uint8 opentype = RFIFOB(fd, 14);
+ int count = RFIFOB(fd, 15);
+ struct rodex_item items[RODEX_MAX_ITEM];
+ memcpy(&items[0], RFIFOP(fd, 16), sizeof(struct rodex_item) * RODEX_MAX_ITEM);
+ rodex->getItemsAck(sd, mail_id, opentype, count, &items[0]);
+}
+
//-----------------------------------------------------------------
// Communication from the inter server
// Return a 0 (false) if there were any errors.
@@ -2972,6 +3006,8 @@ static int intif_parse(int fd)
case 0x3896: intif->pRodexHasNew(fd); break;
case 0x3897: intif->pRodexSendMail(fd); break;
case 0x3898: intif->pRodexCheckName(fd); break;
+ case 0x3899: intif->pGetZenyAck(fd); break;
+ case 0x389a: intif->pGetItemsAck(fd); break;
// Clan System
case 0x3858: intif->pRecvClanMemberAction(fd); break;
@@ -3001,7 +3037,7 @@ void intif_defaults(void)
-1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3860 Quests [Kevin] [Inkfish]
-1, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 3, 3, 0, //0x3870 Mercenaries [Zephyrus] / Elemental [pakpil]
14,-1, 7, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3880
- -1,-1, 7, 3, 0,-1, 7, 15,18 + NAME_LENGTH, 0, 0, 0, 0, 0, 0, 0, //0x3890 Homunculus [albator] / RoDEX [KirieZ]
+ -1,-1, 7, 3, 0,-1, 7, 15,18 + NAME_LENGTH, 23, 16 + sizeof(struct rodex_item) * RODEX_MAX_ITEM, 0, 0, 0, 0, 0, //0x3890 Homunculus [albator] / RoDEX [KirieZ]
};
intif = &intif_s;
@@ -3171,6 +3207,8 @@ void intif_defaults(void)
intif->pRodexHasNew = intif_parse_RodexNotifications;
intif->pRodexSendMail = intif_parse_RodexSendMail;
intif->pRodexCheckName = intif_parse_RodexCheckName;
+ intif->pGetZenyAck = intif_parse_GetZenyAck;
+ intif->pGetItemsAck = intif_parse_GetItemsAck;
/* Clan System */
intif->pRecvClanMemberAction = intif_parse_RecvClanMemberAction;
/* Achievement System */
diff --git a/src/map/intif.h b/src/map/intif.h
index 425ab1d18..8df669217 100644
--- a/src/map/intif.h
+++ b/src/map/intif.h
@@ -135,9 +135,11 @@ struct intif_interface {
// RoDEX
int(*rodex_requestinbox) (int char_id, int account_id, int8 flag, int8 opentype, int64 mail_id);
int(*rodex_checkhasnew) (struct map_session_data *sd);
- int(*rodex_updatemail) (int64 mail_id, int8 flag);
+ int(*rodex_updatemail) (struct map_session_data *sd, int64 mail_id, uint8 opentype, int8 flag);
int(*rodex_sendmail) (struct rodex_message *msg);
int(*rodex_checkname) (struct map_session_data *sd, const char *name);
+ void (*pGetZenyAck) (int fd);
+ void (*pGetItemsAck) (int fd);
/* Clan System */
int (*clan_kickoffline) (int clan_id, int kick_interval);
int (*clan_membercount) (int clan_id, int kick_interval);
diff --git a/src/map/mob.c b/src/map/mob.c
index fed4d6c60..8dac1ea43 100644
--- a/src/map/mob.c
+++ b/src/map/mob.c
@@ -1900,15 +1900,53 @@ static int mob_ai_hard(int tid, int64 tick, int id, intptr_t data)
return 0;
}
+/**
+ * Adds random options of a given options drop group into item.
+ *
+ * @param item : item receiving random options
+ * @param options : Random Option Drop Group to be used
+ */
+static void mob_setdropitem_options(struct item *item, struct optdrop_group *options)
+{
+ nullpo_retv(item);
+ nullpo_retv(options);
+
+ for (int i = 0; i < options->optslot_count; i++) {
+ if (rnd() % 10000 >= options->optslot_rate[i])
+ continue;
+
+ // count avoids a too long loop that would cause lag.
+ // if after option_drop_max_loop full iterations (running through all possibilities)
+ // it still fails to pick one, it'll stop at one random index in the next iteration
+ int count = battle_config.option_drop_max_loop * options->optslot[i].option_count + (rnd() % options->optslot[i].option_count);
+ int idx = 0;
+ while (count > 0 && rnd() % 10000 >= options->optslot[i].options[idx].rate) {
+ idx = (idx + 1) % options->optslot[i].option_count;
+ --count;
+ }
+
+ item->option[i].index = options->optslot[i].options[idx].id;
+
+ int min = options->optslot[i].options[idx].min;
+ int max = options->optslot[i].options[idx].max;
+ item->option[i].value = min + (rnd() % (max - min + 1));
+ }
+}
+
/*==========================================
* Initializes the delay drop structure for mob-dropped items.
*------------------------------------------*/
-static struct item_drop *mob_setdropitem(int nameid, int qty, struct item_data *data)
+static struct item_drop *mob_setdropitem(int nameid, struct optdrop_group *options, int qty, struct item_data *data)
{
struct item_drop *drop = ers_alloc(item_drop_ers, struct item_drop);
drop->item_data.nameid = nameid;
drop->item_data.amount = qty;
drop->item_data.identify = data ? itemdb->isidentified2(data) : itemdb->isidentified(nameid);
+
+ // Set item options [KirieZ]
+ if (options != NULL)
+ mob->setdropitem_options(&drop->item_data, options);
+
drop->showdropeffect = true;
drop->next = NULL;
return drop;
@@ -2521,7 +2559,7 @@ static int mob_dead(struct mob_data *md, struct block_list *src, int type)
continue;
}
- ditem = mob->setdropitem(md->db->dropitem[i].nameid, 1, it);
+ ditem = mob->setdropitem(md->db->dropitem[i].nameid, md->db->dropitem[i].options, 1, it);
// Official Drop Announce [Jedzkie]
if (mvp_sd != NULL) {
@@ -2538,7 +2576,7 @@ static int mob_dead(struct mob_data *md, struct block_list *src, int type)
// Ore Discovery [Celest]
if (sd == mvp_sd && pc->checkskill(sd,BS_FINDINGORE) > 0) {
if( (temp = itemdb->chain_item(itemdb->chain_cache[ECC_ORE],&i)) ) {
- ditem = mob->setdropitem(temp, 1, NULL);
+ ditem = mob->setdropitem(temp, NULL, 1, NULL);
mob->item_drop(md, dlist, ditem, 0, i, homkillonly);
}
}
@@ -2570,7 +2608,7 @@ static int mob_dead(struct mob_data *md, struct block_list *src, int type)
continue;
itemid = (!sd->add_drop[i].is_group) ? sd->add_drop[i].id : itemdb->chain_item(sd->add_drop[i].id, &drop_rate);
if( itemid )
- mob->item_drop(md, dlist, mob->setdropitem(itemid,1,NULL), 0, drop_rate, homkillonly);
+ mob->item_drop(md, dlist, mob->setdropitem(itemid, NULL, 1, NULL), 0, drop_rate, homkillonly);
}
}
@@ -2629,10 +2667,7 @@ static int mob_dead(struct mob_data *md, struct block_list *src, int type)
if (!(map->list[m].flag.nomvploot || type&1)) {
/* pose them randomly in the list -- so on 100% drop servers it wont always drop the same item */
- struct {
- int nameid;
- int p;
- } mdrop[MAX_MVP_DROP] = { { 0 } };
+ struct mob_drop mdrop[MAX_MVP_DROP] = { { 0 } };
for (i = 0; i < MAX_MVP_DROP; i++) {
int rpos;
@@ -2644,6 +2679,7 @@ static int mob_dead(struct mob_data *md, struct block_list *src, int type)
mdrop[rpos].nameid = md->db->mvpitem[i].nameid;
mdrop[rpos].p = md->db->mvpitem[i].p;
+ mdrop[rpos].options = md->db->mvpitem[i].options;
}
for (i = 0; i < MAX_MVP_DROP; i++) {
@@ -2663,6 +2699,7 @@ static int mob_dead(struct mob_data *md, struct block_list *src, int type)
item.nameid = mdrop[i].nameid;
item.identify = itemdb->isidentified2(data);
+ mob->setdropitem_options(&item, mdrop[i].options);
clif->mvp_item(mvp_sd, item.nameid);
log_mvp[0] = item.nameid;
@@ -3861,6 +3898,212 @@ static inline int mob_parse_dbrow_cap_value(int class_, int min, int max, int va
}
/**
+ * Reads one possible option for a option slot in a option drop group
+ * @param option : Libconfig entry
+ * @param entry : memory db entry for current slot
+ * @param idx : index of entry where this option should be inserted at
+ * @param calc_rate : if rates should be recalculated after reading all entries
+ * @param slot : option group slot being read (for messages)
+ * @param group : option group being read (for messages)
+ * @return true if it successfully read the entry, false otherwise
+ */
+static bool mob_read_optdrops_option(struct config_setting_t *option, struct optdrop_group_optslot *entry, int *idx, bool *calc_rate, int slot, const char *group)
+{
+ nullpo_retr(false, option);
+ nullpo_retr(false, entry);
+ nullpo_retr(false, idx);
+ nullpo_retr(false, calc_rate);
+ nullpo_retr(false, group);
+
+ const char *name = config_setting_name(option);
+ int opt_id;
+
+ if (strncmp(name, "Rate", 4) == 0)
+ return true;
+
+ if (script->get_constant(name, &opt_id) == false) {
+ ShowWarning("mob_read_optdrops_option: Invalid option \"%s\" for option slot %d of %s group, skipping.\n", name, slot, group);
+ return false;
+ }
+
+ int min = 0, max = 0, opt_rate = 0;
+ if (config_setting_is_number(option)) {
+ // OptionName: value
+ min = libconfig->setting_get_int(option);
+ } else if (config_setting_is_array(option)) {
+ // OptionName: [min, max]
+ // OptionName: [min, max, rate]
+ int slen = libconfig->setting_length(option);
+
+ if (slen >= 2) {
+ // [min, max,...]
+ min = libconfig->setting_get_int_elem(option, 0);
+ max = libconfig->setting_get_int_elem(option, 1);
+ }
+
+ if (slen == 3) {
+ // [min, max, rate]
+ opt_rate = libconfig->setting_get_int_elem(option, 2);
+ }
+ } else {
+ ShowWarning("mob_read_optdrops_option: Invalid value \"%s\" for option slot %d of %s group, skipping.\n", name, slot, group);
+ return false;
+ }
+
+ if (max < min)
+ max = min;
+
+ entry->options[*idx].id = opt_id;
+ entry->options[*idx].min = min;
+ entry->options[*idx].max = max;
+ entry->options[*idx].rate = opt_rate;
+
+ if (entry->options[*idx].rate == 0)
+ *calc_rate = true;
+
+ (*idx)++;
+
+ return true;
+}
+
+/**
+ * Reads the settings for one random option slot of a random option drop group.
+ * @param optslot : The slot entry from config file
+ * @param n : slot index
+ * @param group_id : Group index
+ * @param group : group name (used in messages)
+ * @return true if it succesfully read, false otherwise
+ */
+static bool mob_read_optdrops_optslot(struct config_setting_t *optslot, int n, int group_id, const char *group)
+{
+ nullpo_retr(false, optslot);
+ nullpo_retr(false, group);
+ Assert_retr(false, group_id >= 0 && group_id < mob->opt_drop_groups_count);
+ Assert_retr(false, n >= 0 && n < MAX_ITEM_OPTIONS);
+
+ // Structure:
+ // {
+ // Rate: chance of option 1 (int)
+ // OptionName1: value
+ // OptionName2: [min, max]
+ // OptionName3: [min, max, rate]
+ // ....
+ // }
+
+ int drop_rate; // The rate for this option to be dropped (Rate field)
+ if (libconfig->setting_lookup_int(optslot, "Rate", &drop_rate) == CONFIG_FALSE) {
+ ShowWarning("mob_read_optdrops_optslot: Missing option %d rate in group %s, skipping.\n", n, group);
+ return false;
+ }
+
+ int count = libconfig->setting_length(optslot);
+ if (count <= 1) { // 1 = Rate
+ ShowWarning("mob_read_optdrops_optslot: Option %d of %s group doesn't contain any possible options, skipping.\n", n, group);
+ return false;
+ }
+
+ struct optdrop_group_optslot *entry = &(mob->opt_drop_groups[group_id].optslot[n]);
+ entry->options = aCalloc(sizeof(struct optdrop_group_option), count);
+
+ int idx = 0;
+ int i = 0;
+ struct config_setting_t *opt = NULL;
+ bool calc_rate = false;
+ while (i < count && (opt = libconfig->setting_get_elem(optslot, i)) != NULL) {
+ ++i;
+ mob->read_optdrops_option(opt, entry, &idx, &calc_rate, n, group);
+ }
+ entry->option_count = idx;
+ mob->opt_drop_groups[group_id].optslot_count++;
+ mob->opt_drop_groups[group_id].optslot_rate[n] = drop_rate;
+
+ // If there're empty rates, calculate them
+ if (calc_rate == true) {
+ for (int j = 0; j < idx; ++j) {
+ if (entry->options[j].rate == 0)
+ entry->options[j].rate = 10000 / idx;
+ }
+ }
+
+ return true;
+}
+
+/**
+ * Reads one random option drop group.
+ * @param group : Drop Group entry from config file
+ * @param n : group index
+ * @return true if it successfuly read, false otherwise
+ */
+static bool mob_read_optdrops_group(struct config_setting_t *group, int n)
+{
+ /* Structure:
+ <Group Name>: (
+ { <Option 1 drop data> },
+ { <Option 2 drop data> },
+ ... // Up to MAX_ITEM_OPTIONS
+ )
+ */
+ nullpo_retr(false, group);
+
+ const char *group_name = config_setting_name(group);
+
+ if (group_name == NULL || *group_name == '\0') {
+ ShowWarning("mob_read_optdrops_group: Invalid name for random option drop group, skipping group %d...\n", n);
+ return false;
+ }
+
+ script->set_constant2(group_name, n, false, false);
+
+ int i = 0;
+ struct config_setting_t *drop_data = NULL;
+ while (i < MAX_ITEM_OPTIONS && (drop_data = libconfig->setting_get_elem(group, i)) != NULL) {
+ mob->read_optdrops_optslot(drop_data, i, n, group_name);
+ i++;
+ }
+
+ return true;
+}
+
+/**
+ * Reads random option drop groups database.
+ */
+static bool mob_read_optdrops_db(void)
+{
+ const char *filename = "option_drop_groups.conf"; // FIXME hardcoded name
+
+ char filepath[256];
+ safesnprintf(filepath, sizeof(filepath), "%s/%s", map->db_path, filename);
+
+ struct config_t option_groups;
+ if (libconfig->load_file(&option_groups, filepath) == CONFIG_FALSE) {
+ ShowError("Failed to load option drop groups\n");
+ return false;
+ }
+
+ struct config_setting_t *its = libconfig->lookup(&option_groups, "option_drop_group_db");
+ struct config_setting_t *groups = NULL;
+
+ int i = 0;
+ if (its != NULL && (groups = libconfig->setting_get_elem(its, 0)) != NULL) {
+ int count = libconfig->setting_length(groups);
+ mob->opt_drop_groups = aCalloc(sizeof(struct optdrop_group), count);
+ mob->opt_drop_groups_count = count; // maximum size (used by assertions)
+
+ struct config_setting_t *group = NULL;
+ while ((group = libconfig->setting_get_elem(groups, i)) != NULL) {
+ mob->read_optdrops_group(group, i);
+ i++;
+ }
+ mob->opt_drop_groups_count = i; // number of entries used (should be the same amount)
+ }
+
+ libconfig->destroy(&option_groups);
+
+ ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", i, filepath);
+ return true;
+}
+
+/**
* Processes the stats for a mob database entry.
*
* @param[in,out] entry The destination mob_db entry, already initialized
@@ -3941,6 +4184,51 @@ static uint32 mob_read_db_mode_sub(struct mob_db *entry, struct config_setting_t
}
/**
+ * Process an entry of mob/mvp drops that contains a random option drop group.
+ *
+ * @param entry : mob db entry being read (used in error messages)
+ * @param item_name : AegisName of the item in this entry (used in error messages)
+ * @param drop : drop data entry
+ * @param drop_rate : used to return the entry drop_rate
+ * @returns a reference to the opt_drop_group to be used when creating this item drop
+ */
+static struct optdrop_group *mob_read_db_drops_option(struct mob_db *entry, const char *item_name, struct config_setting_t *drop, int *drop_rate)
+{
+ nullpo_retr(NULL, entry);
+ nullpo_retr(NULL, item_name);
+ nullpo_retr(NULL, drop);
+ nullpo_retr(NULL, drop_rate);
+
+ // (Drop Rate, "Option Group")
+ if (!config_setting_is_list(drop) || config_setting_length(drop) != 2) {
+ ShowError("mob_read_db_optdrops: Invalid format for option drop group on item \"%s\" in monster %d, skipping.\n", item_name, entry->mob_id);
+ return NULL;
+ }
+
+ int i32;
+ if (mob->get_const(libconfig->setting_get_elem(drop, 0), &i32) && i32 >= 0)
+ *drop_rate = i32;
+
+ const char *group_name = libconfig->setting_get_string_elem(drop, 1);
+ if (group_name == NULL || *group_name == '\0') {
+ ShowError("mob_read_db_optdrops: Missing option drop group name on item \"%s\" in monster %d, skipping.\n", item_name, entry->mob_id);
+ return NULL;
+ }
+
+ int opt_id;
+ if (script->get_constant(group_name, &opt_id) == false) {
+ ShowError("mob_read_db_optdrops: Invalid option drop group \"%s\" on item \"%s\" in monster %d, does this group really exists? Skipping...\n", group_name, item_name, entry->mob_id);
+ return NULL;
+ }
+ if (opt_id < 0 || opt_id >= mob->opt_drop_groups_count) {
+ ShowError("mob_read_db_optdrops: Invalid option drop group \"%s\" index \"%d\" on item \"%s\" in monster %d, does this group really exists? Skipping...\n", group_name, opt_id, item_name, entry->mob_id);
+ return NULL;
+ }
+
+ return &mob->opt_drop_groups[opt_id];
+}
+
+/**
* Processes the MVP drops for a mob_db entry.
*
* @param[in,out] entry The destination mob_db entry, already initialized
@@ -3965,9 +4253,18 @@ static void mob_read_db_mvpdrops_sub(struct mob_db *entry, struct config_setting
i++;
continue;
}
- if (mob->get_const(drop, &i32) && i32 >= 0) {
- value = i32;
+
+ struct optdrop_group *drop_option = NULL;
+ if (config_setting_is_number(drop)) {
+ // Setting is a number, item doesn't contain options
+ if (mob->get_const(drop, &i32) && i32 >= 0) {
+ value = i32;
+ }
+ } else {
+ // (Drop Rate, "Opt Drop Group")
+ drop_option = mob->read_db_drops_option(entry, name, drop, &value);
}
+
if (value <= 0) {
ShowWarning("mob_read_db: wrong drop chance %d for mvp drop item %s in monster %d\n", value, name, entry->mob_id);
i++;
@@ -3981,6 +4278,7 @@ static void mob_read_db_mvpdrops_sub(struct mob_db *entry, struct config_setting
}
mob->item_dropratio_adjust(entry->mvpitem[idx].nameid, entry->mob_id, &rate_adjust);
entry->mvpitem[idx].p = mob->drop_adjust(value, rate_adjust, battle_config.item_drop_mvp_min, battle_config.item_drop_mvp_max);
+ entry->mvpitem[idx].options = drop_option;
//calculate and store Max available drop chance of the MVP item
if (entry->mvpitem[idx].p) {
@@ -4024,9 +4322,18 @@ static void mob_read_db_drops_sub(struct mob_db *entry, struct config_setting_t
i++;
continue;
}
- if (mob->get_const(drop, &i32) && i32 >= 0) {
- value = i32;
+
+ struct optdrop_group *drop_option = NULL;
+ if (config_setting_is_number(drop)) {
+ // Setting is a number, item doesn't contain options
+ if (mob->get_const(drop, &i32) && i32 >= 0) {
+ value = i32;
+ }
+ } else {
+ // (Drop Rate, "Opt Drop Group")
+ drop_option = mob->read_db_drops_option(entry, name, drop, &value);
}
+
if (value <= 0) {
ShowWarning("mob_read_db: wrong drop chance %d for drop item %s in monster %d\n", value, name, entry->mob_id);
i++;
@@ -4034,6 +4341,7 @@ static void mob_read_db_drops_sub(struct mob_db *entry, struct config_setting_t
}
entry->dropitem[idx].nameid = id->nameid;
+ entry->dropitem[idx].options = drop_option;
if (!entry->dropitem[idx].nameid) {
entry->dropitem[idx].p = 0; //No drop.
i++;
@@ -4301,6 +4609,8 @@ static int mob_read_db_sub(struct config_setting_t *mobt, int n, const char *sou
* }
* Drops: {
* AegisName: chance
+ * // or
+ * AegisName: (chance, "Option Drop Group")
* ...
* }
*/
@@ -5213,6 +5523,7 @@ static void mob_load(bool minimal)
return;
}
sv->readdb(map->db_path, "mob_item_ratio.txt", ',', 2, 2+MAX_ITEMRATIO_MOBS, -1, mob->readdb_itemratio); // must be read before mobdb
+ mob->read_optdrops_db();
mob->readchatdb();
mob->readdb();
mob->readskilldb();
@@ -5254,6 +5565,8 @@ static void mob_reload(void)
}
mob->item_drop_ratio_other_db->clear(mob->item_drop_ratio_other_db, mob->final_ratio_sub);
+ mob->destroy_drop_groups();
+
mob->load(false);
}
@@ -5309,6 +5622,22 @@ static void mob_destroy_mob_db(int index)
mob->db_data[index] = NULL;
}
+/**
+ * Unloads option drop group database
+ */
+static void mob_destroy_drop_groups(void)
+{
+ for (int i = 0; i < mob->opt_drop_groups_count; i++) {
+ struct optdrop_group *group = &mob->opt_drop_groups[i];
+
+ for (int j = 0; j < group->optslot_count; j++) {
+ aFree(group->optslot[j].options);
+ }
+ }
+
+ aFree(mob->opt_drop_groups);
+}
+
/*==========================================
* Clean memory usage.
*------------------------------------------*/
@@ -5327,6 +5656,7 @@ static int do_final_mob(void)
mob->destroy_mob_db(i);
}
}
+ mob->destroy_drop_groups();
for (i = 0; i <= MAX_MOB_CHAT; i++)
{
if (mob->chat_db[i] != NULL)
@@ -5443,6 +5773,7 @@ void mob_defaults(void)
mob->ai_sub_lazy = mob_ai_sub_lazy;
mob->ai_lazy = mob_ai_lazy;
mob->ai_hard = mob_ai_hard;
+ mob->setdropitem_options = mob_setdropitem_options;
mob->setdropitem = mob_setdropitem;
mob->setlootitem = mob_setlootitem;
mob->delay_item_drop = mob_delay_item_drop;
@@ -5476,6 +5807,10 @@ void mob_defaults(void)
mob->clone_delete = mob_clone_delete;
mob->drop_adjust = mob_drop_adjust;
mob->item_dropratio_adjust = item_dropratio_adjust;
+ mob->read_optdrops_option = mob_read_optdrops_option;
+ mob->read_optdrops_optslot = mob_read_optdrops_optslot;
+ mob->read_optdrops_group = mob_read_optdrops_group;
+ mob->read_optdrops_db = mob_read_optdrops_db;
mob->lookup_const = mob_lookup_const;
mob->get_const = mob_get_const;
mob->db_validate_entry = mob_db_validate_entry;
@@ -5486,6 +5821,7 @@ void mob_defaults(void)
mob->read_db_drops_sub = mob_read_db_drops_sub;
mob->read_db_mvpdrops_sub = mob_read_db_mvpdrops_sub;
mob->read_db_mode_sub = mob_read_db_mode_sub;
+ mob->read_db_drops_option = mob_read_db_drops_option;
mob->read_db_stats_sub = mob_read_db_stats_sub;
mob->name_constants = mob_name_constants;
mob->readdb_mobavail = mob_readdb_mobavail;
@@ -5501,6 +5837,7 @@ void mob_defaults(void)
mob->final_ratio_sub = mob_final_ratio_sub;
mob->clear_spawninfo = mob_clear_spawninfo;
mob->destroy_mob_db = mob_destroy_mob_db;
+ mob->destroy_drop_groups = mob_destroy_drop_groups;
mob->skill_db_libconfig = mob_skill_db_libconfig;
mob->skill_db_libconfig_sub = mob_skill_db_libconfig_sub;
mob->skill_db_libconfig_sub_skill = mob_skill_db_libconfig_sub_skill;
diff --git a/src/map/mob.h b/src/map/mob.h
index cdfc07c7d..b63efd272 100644
--- a/src/map/mob.h
+++ b/src/map/mob.h
@@ -152,6 +152,45 @@ struct spawn_info {
unsigned short qty;
};
+/**
+ * Information of one possible option that will fill
+ * an option slot (see optdrop_group_optslot)
+ */
+struct optdrop_group_option {
+ int id; //< Option ID
+ int min; //< Minimun value when this option drops
+ int max; //< Maximun value when this option drops
+ int rate; //< Chance of dropping this option
+};
+
+/**
+ * Information of possible options that will fill
+ * one option slot
+ */
+struct optdrop_group_optslot {
+ int option_count; //< Number of options in *options
+ struct optdrop_group_option *options; //< Array of possible options
+};
+
+/**
+ * A group of options to be random picked when
+ * dropping an item
+ */
+struct optdrop_group {
+ int optslot_count; //< How many option slots are configured by this group
+ int optslot_rate[MAX_ITEM_OPTIONS]; //< The rate to fill each of the configured slots
+ struct optdrop_group_optslot optslot[MAX_ITEM_OPTIONS]; //< Details of the options that will go in each slot
+};
+
+/**
+ * Stores data related to a monster drop (normal or mvp drop)
+ */
+struct mob_drop {
+ int nameid; //< Item ID
+ int p; //< Drop chance
+ struct optdrop_group *options; //< Option Drop Group associated with this drop (NULL if none)
+};
+
struct mob_db {
int mob_id;
char sprite[NAME_LENGTH],name[NAME_LENGTH],jname[NAME_LENGTH];
@@ -160,8 +199,8 @@ struct mob_db {
short range2,range3;
short race2; // celest
unsigned short lv;
- struct { int nameid,p; } dropitem[MAX_MOB_DROP];
- struct { int nameid,p; } mvpitem[MAX_MVP_DROP];
+ struct mob_drop dropitem[MAX_MOB_DROP];
+ struct mob_drop mvpitem[MAX_MVP_DROP];
struct status_data status;
struct view_data vd;
unsigned int option;
@@ -436,6 +475,9 @@ struct mob_interface {
struct mob_db *dummy; //Dummy mob to be returned when a non-existant one is requested.
// Dynamic mob chat database
struct mob_chat *chat_db[MAX_MOB_CHAT + 1];
+ // Random Option Drop groups
+ struct optdrop_group *opt_drop_groups;
+ int opt_drop_groups_count;
// Defines the Manuk/Splendide/Mora mob groups for the status reductions [Epoque & Frost]
int manuk[8];
int splendide[5];
@@ -494,7 +536,8 @@ struct mob_interface {
int (*ai_sub_lazy) (struct mob_data *md, va_list args);
int (*ai_lazy) (int tid, int64 tick, int id, intptr_t data);
int (*ai_hard) (int tid, int64 tick, int id, intptr_t data);
- struct item_drop* (*setdropitem) (int nameid, int qty, struct item_data *data);
+ void (*setdropitem_options) (struct item *item, struct optdrop_group *options);
+ struct item_drop* (*setdropitem) (int nameid, struct optdrop_group *options, int qty, struct item_data *data);
struct item_drop* (*setlootitem) (struct item *item);
int (*delay_item_drop) (int tid, int64 tick, int id, intptr_t data);
void (*item_drop) (struct mob_data *md, struct item_drop_list *dlist, struct item_drop *ditem, int loot, int drop_rate, unsigned short flag);
@@ -527,6 +570,10 @@ struct mob_interface {
int (*clone_delete) (struct mob_data *md);
unsigned int (*drop_adjust) (int baserate, int rate_adjust, unsigned short rate_min, unsigned short rate_max);
void (*item_dropratio_adjust) (int nameid, int mob_id, int *rate_adjust);
+ bool (*read_optdrops_option) (struct config_setting_t *option, struct optdrop_group_optslot *entry, int *idx, bool *calc_rate, int slot, const char *group);
+ bool (*read_optdrops_optslot) (struct config_setting_t *optslot, int n, int group_id, const char *group);
+ bool (*read_optdrops_group) (struct config_setting_t *group, int n);
+ bool (*read_optdrops_db) (void);
void (*readdb) (void);
bool (*lookup_const) (const struct config_setting_t *it, const char *name, int *value);
bool (*get_const) (const struct config_setting_t *it, int *value);
@@ -537,6 +584,7 @@ struct mob_interface {
void (*read_db_drops_sub) (struct mob_db *entry, struct config_setting_t *t);
void (*read_db_mvpdrops_sub) (struct mob_db *entry, struct config_setting_t *t);
uint32 (*read_db_mode_sub) (struct mob_db *entry, struct config_setting_t *t);
+ struct optdrop_group *(*read_db_drops_option) (struct mob_db *entry, const char *item_name, struct config_setting_t *drop, int *drop_rate);
void (*read_db_stats_sub) (struct mob_db *entry, struct config_setting_t *t);
void (*name_constants) (void);
bool (*readdb_mobavail) (char *str[], int columns, int current);
@@ -552,6 +600,7 @@ struct mob_interface {
void (*set_item_drop_ratio) (int nameid, struct item_drop_ratio *ratio);
int (*final_ratio_sub) (union DBKey key, struct DBData *data, va_list ap);
void (*destroy_mob_db) (int index);
+ void (*destroy_drop_groups) (void);
bool (*skill_db_libconfig) (const char *filename, bool ignore_missing);
bool (*skill_db_libconfig_sub) (struct config_setting_t *it, int n);
bool (*skill_db_libconfig_sub_skill) (struct config_setting_t *it, int n, int mob_id);
diff --git a/src/map/pet.c b/src/map/pet.c
index 96fe63c51..ce26b6cb1 100644
--- a/src/map/pet.c
+++ b/src/map/pet.c
@@ -348,6 +348,21 @@ static int pet_return_egg(struct map_session_data *sd, struct pet_data *pd)
if (i != sd->status.inventorySize) {
sd->status.inventory[i].attribute &= ~ATTR_BROKEN;
sd->status.inventory[i].bound = IBT_NONE;
+ } else {
+ // The pet egg wasn't found: it was probably hatched with the old system that deleted the egg.
+ struct item tmp_item = {0};
+ int flag;
+
+ tmp_item.nameid = pd->petDB->EggID;
+ tmp_item.identify = 1;
+ tmp_item.card[0] = CARD0_PET;
+ tmp_item.card[1] = GetWord(pd->pet.pet_id, 0);
+ tmp_item.card[2] = GetWord(pd->pet.pet_id, 1);
+ tmp_item.card[3] = pd->pet.rename_flag;
+ if ((flag = pc->additem(sd, &tmp_item, 1, LOG_TYPE_EGG)) != 0) {
+ clif->additem(sd, 0, 0, flag);
+ map->addflooritem(&sd->bl, &tmp_item, 1, sd->bl.m, sd->bl.x, sd->bl.y, 0, 0, 0, 0, false);
+ }
}
#if PACKETVER >= 20180704
clif->inventoryList(sd);
diff --git a/src/map/rodex.c b/src/map/rodex.c
index 33070c5f8..766fdc5ea 100644
--- a/src/map/rodex.c
+++ b/src/map/rodex.c
@@ -404,12 +404,12 @@ static void rodex_read_mail(struct map_session_data *sd, int64 mail_id)
if (msg->opentype == RODEX_OPENTYPE_RETURN) {
if (msg->sender_read == false) {
- intif->rodex_updatemail(msg->id, 4);
+ intif->rodex_updatemail(sd, msg->id, 0, 4);
msg->sender_read = true;
}
} else {
if (msg->is_read == false) {
- intif->rodex_updatemail(msg->id, 0);
+ intif->rodex_updatemail(sd, msg->id, 0, 0);
msg->is_read = true;
}
}
@@ -430,21 +430,36 @@ static void rodex_delete_mail(struct map_session_data *sd, int64 mail_id)
nullpo_retv(msg);
msg->is_deleted = true;
- intif->rodex_updatemail(msg->id, 3);
+ intif->rodex_updatemail(sd, msg->id, 0, 3);
clif->rodex_delete_mail(sd, msg->opentype, msg->id);
}
+/// give requested zeny from message to player
+static void rodex_getZenyAck(struct map_session_data *sd, int64 mail_id, int8 opentype, int64 zeny)
+{
+ nullpo_retv(sd);
+ if (zeny <= 0) {
+ clif->rodex_request_zeny(sd, opentype, mail_id, RODEX_GET_ZENY_FATAL_ERROR);
+ return;
+ }
+
+ if (pc->getzeny(sd, (int)zeny, LOG_TYPE_MAIL, NULL) != 0) {
+ clif->rodex_request_zeny(sd, opentype, mail_id, RODEX_GET_ZENY_FATAL_ERROR);
+ return;
+ }
+
+ clif->rodex_request_zeny(sd, opentype, mail_id, RODEX_GET_ZENY_SUCCESS);
+}
+
/// Gets attached zeny
/// @param sd : Who's getting
/// @param mail_id : Mail ID that we're getting zeny from
static void rodex_get_zeny(struct map_session_data *sd, int8 opentype, int64 mail_id)
{
- struct rodex_message *msg;
-
nullpo_retv(sd);
- msg = rodex->get_mail(sd, mail_id);
+ struct rodex_message *msg = rodex->get_mail(sd, mail_id);
if (msg == NULL) {
clif->rodex_request_zeny(sd, opentype, mail_id, RODEX_GET_ZENY_FATAL_ERROR);
@@ -456,16 +471,31 @@ static void rodex_get_zeny(struct map_session_data *sd, int8 opentype, int64 mai
return;
}
- if (pc->getzeny(sd, (int)msg->zeny, LOG_TYPE_MAIL, NULL) != 0) {
- clif->rodex_request_zeny(sd, opentype, mail_id, RODEX_GET_ZENY_FATAL_ERROR);
- return;
- }
-
msg->type &= ~MAIL_TYPE_ZENY;
msg->zeny = 0;
- intif->rodex_updatemail(mail_id, 1);
+ intif->rodex_updatemail(sd, mail_id, opentype, 1);
+}
- clif->rodex_request_zeny(sd, opentype, mail_id, RODEX_GET_ZENY_SUCCESS);
+// give requested items from message to player
+static void rodex_getItemsAck(struct map_session_data *sd, int64 mail_id, int8 opentype, int count, const struct rodex_item *items)
+{
+ nullpo_retv(sd);
+ nullpo_retv(items);
+
+ for (int i = 0; i < count; ++i) {
+ const struct item *it = &items[i].item;
+
+ if (it->nameid == 0) {
+ continue;
+ }
+
+ if (pc->additem(sd, it, it->amount, LOG_TYPE_MAIL) != 0) {
+ clif->rodex_request_items(sd, opentype, mail_id, RODEX_GET_ITEM_FULL_ERROR);
+ return;
+ }
+ }
+
+ clif->rodex_request_items(sd, opentype, mail_id, RODEX_GET_ITEMS_SUCCESS);
}
/// Gets attached item
@@ -473,14 +503,12 @@ static void rodex_get_zeny(struct map_session_data *sd, int8 opentype, int64 mai
/// @param mail_id : Mail ID that we're getting items from
static void rodex_get_items(struct map_session_data *sd, int8 opentype, int64 mail_id)
{
- struct rodex_message *msg;
- int weight = 0;
- int empty_slots = 0, required_slots;
- int i;
-
nullpo_retv(sd);
- msg = rodex->get_mail(sd, mail_id);
+ int weight = 0;
+ int empty_slots = 0;
+
+ struct rodex_message *msg = rodex->get_mail(sd, mail_id);
if (msg == NULL) {
clif->rodex_request_items(sd, opentype, mail_id, RODEX_GET_ITEM_FATAL_ERROR);
@@ -492,7 +520,7 @@ static void rodex_get_items(struct map_session_data *sd, int8 opentype, int64 ma
return;
}
- for (i = 0; i < RODEX_MAX_ITEM; ++i) {
+ for (int i = 0; i < RODEX_MAX_ITEM; ++i) {
if (msg->items[i].item.nameid != 0) {
weight += itemdb->search(msg->items[i].item.nameid)->weight * msg->items[i].item.amount;
}
@@ -503,8 +531,8 @@ static void rodex_get_items(struct map_session_data *sd, int8 opentype, int64 ma
return;
}
- required_slots = msg->items_count;
- for (i = 0; i < sd->status.inventorySize; ++i) {
+ int required_slots = msg->items_count;
+ for (int i = 0; i < sd->status.inventorySize; ++i) {
if (sd->status.inventory[i].nameid == 0) {
empty_slots++;
} else if (itemdb->isstackable(sd->status.inventory[i].nameid) == 1) {
@@ -529,27 +557,9 @@ static void rodex_get_items(struct map_session_data *sd, int8 opentype, int64 ma
return;
}
- for (i = 0; i < RODEX_MAX_ITEM; ++i) {
- struct item *it = &msg->items[i].item;
-
- if (it->nameid == 0) {
- continue;
- }
-
- if (pc->additem(sd, it, it->amount, LOG_TYPE_MAIL) != 0) {
- clif->rodex_request_items(sd, opentype, mail_id, RODEX_GET_ITEM_FULL_ERROR);
- intif->rodex_updatemail(mail_id, 2);
- return;
- } else {
- memset(it, 0x0, sizeof(*it));
- }
- }
-
msg->type &= ~MAIL_TYPE_ITEM;
msg->items_count = 0;
- intif->rodex_updatemail(mail_id, 2);
-
- clif->rodex_request_items(sd, opentype, mail_id, RODEX_GET_ITEMS_SUCCESS);
+ intif->rodex_updatemail(sd, mail_id, opentype, 2);
}
/// Cleans user's RoDEX related data
@@ -668,4 +678,6 @@ void rodex_defaults(void)
rodex->get_zeny = rodex_get_zeny;
rodex->get_items = rodex_get_items;
rodex->clean = rodex_clean;
+ rodex->getZenyAck = rodex_getZenyAck;
+ rodex->getItemsAck = rodex_getItemsAck;
}
diff --git a/src/map/rodex.h b/src/map/rodex.h
index 56cc3a9d1..b6e7ca5b7 100644
--- a/src/map/rodex.h
+++ b/src/map/rodex.h
@@ -74,6 +74,8 @@ struct rodex_interface {
void (*get_items) (struct map_session_data *sd, int8 opentype, int64 mail_id);
void (*delete_mail) (struct map_session_data *sd, int64 mail_id);
void (*clean) (struct map_session_data *sd, int8 flag);
+ void (*getZenyAck) (struct map_session_data *sd, int64 mail_id, int8 opentype, int64 zeny);
+ void (*getItemsAck) (struct map_session_data *sd, int64 mail_id, int8 opentype, int count, const struct rodex_item *items);
};
#ifdef HERCULES_CORE
diff --git a/src/map/script.c b/src/map/script.c
index dea94c6a3..b4a955f09 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -24566,6 +24566,57 @@ static BUILDIN(getcalendartime)
return true;
}
+enum consolemes_type {
+ CONSOLEMES_DEBUG = 0,
+ CONSOLEMES_ERROR = 1,
+ CONSOLEMES_WARNING = 2,
+ CONSOLEMES_INFO = 3,
+ CONSOLEMES_STATUS = 4,
+ CONSOLEMES_NOTICE = 5,
+};
+
+/*==========================================
+* consolemes(<type>, "text")
+*------------------------------------------*/
+static BUILDIN(consolemes)
+{
+ struct StringBuf buf;
+ StrBuf->Init(&buf);
+ int type = script_hasdata(st, 2) ? script_getnum(st, 2) : 0;
+
+ if (!script->sprintf_helper(st, 3, &buf)) {
+ StrBuf->Destroy(&buf);
+ script_pushint(st, 0);
+ return false;
+ }
+
+ switch (type) {
+ default:
+ case CONSOLEMES_DEBUG:
+ ShowDebug("consolemes: %s\n", StrBuf->Value(&buf));
+ break;
+ case CONSOLEMES_ERROR:
+ ShowError("consolemes: (st->rid: %d) (st->oid: %d) %s\n", st->rid, st->oid, StrBuf->Value(&buf));
+ break;
+ case CONSOLEMES_WARNING:
+ ShowWarning("consolemes: (st->rid: %d) (st->oid: %d) %s\n", st->rid, st->oid, StrBuf->Value(&buf));
+ break;
+ case CONSOLEMES_INFO:
+ ShowInfo("consolemes: %s\n", StrBuf->Value(&buf));
+ break;
+ case CONSOLEMES_STATUS:
+ ShowStatus("consolemes: %s\n", StrBuf->Value(&buf));
+ break;
+ case CONSOLEMES_NOTICE:
+ ShowNotice("consolemes: %s\n", StrBuf->Value(&buf));
+ break;
+ }
+
+ StrBuf->Destroy(&buf);
+ script_pushint(st, 1);
+ return true;
+}
+
/** place holder for the translation macro **/
static BUILDIN(_)
{
@@ -25485,7 +25536,8 @@ static void script_parse_builtin(void)
BUILDIN_DEF(sc_end,"i?"),
BUILDIN_DEF(getstatus, "i?"),
BUILDIN_DEF(getscrate,"ii?"),
- BUILDIN_DEF(debugmes,"v*"),
+ BUILDIN_DEF_DEPRECATED(debugmes,"v*"),
+ BUILDIN_DEF(consolemes,"iv*"),
BUILDIN_DEF2(catchpet,"pet","i"),
BUILDIN_DEF2(birthpet,"bpet",""),
BUILDIN_DEF(resetlvl,"i"),
@@ -26212,6 +26264,14 @@ static void script_hardcoded_constants(void)
script->set_constant("MAPINFO_SIZE_Y", MAPINFO_SIZE_Y, false, false);
script->set_constant("MAPINFO_ZONE", MAPINFO_ZONE, false, false);
+ script->constdb_comment("consolemes options");
+ script->set_constant("CONSOLEMES_DEBUG", CONSOLEMES_DEBUG, false, false);
+ script->set_constant("CONSOLEMES_ERROR", CONSOLEMES_ERROR, false, false);
+ script->set_constant("CONSOLEMES_WARNING", CONSOLEMES_WARNING, false, false);
+ script->set_constant("CONSOLEMES_INFO", CONSOLEMES_INFO, false, false);
+ script->set_constant("CONSOLEMES_STATUS", CONSOLEMES_STATUS, false, false);
+ script->set_constant("CONSOLEMES_NOTICE", CONSOLEMES_NOTICE, false, false);
+
script->constdb_comment("set/getiteminfo options");
script->set_constant("ITEMINFO_BUYPRICE", ITEMINFO_BUYPRICE, false, false);
script->set_constant("ITEMINFO_SELLPRICE", ITEMINFO_SELLPRICE, false, false);
diff --git a/src/plugins/HPMHooking/HPMHooking.Defs.inc b/src/plugins/HPMHooking/HPMHooking.Defs.inc
index c1016d19b..374a1bcc4 100644
--- a/src/plugins/HPMHooking/HPMHooking.Defs.inc
+++ b/src/plugins/HPMHooking/HPMHooking.Defs.inc
@@ -3532,8 +3532,12 @@ typedef bool (*HPMHOOK_pre_inter_rodex_checkname) (const char **name, int **targ
typedef bool (*HPMHOOK_post_inter_rodex_checkname) (bool retVal___, const char *name, int *target_char_id, int *target_class, int *target_level);
typedef int64 (*HPMHOOK_pre_inter_rodex_savemessage) (struct rodex_message **msg);
typedef int64 (*HPMHOOK_post_inter_rodex_savemessage) (int64 retVal___, struct rodex_message *msg);
-typedef bool (*HPMHOOK_pre_inter_rodex_updatemail) (int64 *mail_id, int8 *flag);
-typedef bool (*HPMHOOK_post_inter_rodex_updatemail) (bool retVal___, int64 mail_id, int8 flag);
+typedef bool (*HPMHOOK_pre_inter_rodex_updatemail) (int *fd, int *account_id, int *char_id, int64 *mail_id, uint8 *opentype, int8 *flag);
+typedef bool (*HPMHOOK_post_inter_rodex_updatemail) (bool retVal___, int fd, int account_id, int char_id, int64 mail_id, uint8 opentype, int8 flag);
+typedef int64 (*HPMHOOK_pre_inter_rodex_getzeny) (int64 *mail_id);
+typedef int64 (*HPMHOOK_post_inter_rodex_getzeny) (int64 retVal___, int64 mail_id);
+typedef int (*HPMHOOK_pre_inter_rodex_getitems) (int64 *mail_id, struct rodex_item **items);
+typedef int (*HPMHOOK_post_inter_rodex_getitems) (int retVal___, int64 mail_id, struct rodex_item *items);
#endif // CHAR_INT_RODEX_H
#ifdef CHAR_INT_STORAGE_H /* inter_storage */
typedef int (*HPMHOOK_pre_inter_storage_tosql) (int *account_id, const struct storage_data **p);
@@ -3700,12 +3704,16 @@ typedef int (*HPMHOOK_pre_intif_rodex_requestinbox) (int *char_id, int *account_
typedef int (*HPMHOOK_post_intif_rodex_requestinbox) (int retVal___, int char_id, int account_id, int8 flag, int8 opentype, int64 mail_id);
typedef int (*HPMHOOK_pre_intif_rodex_checkhasnew) (struct map_session_data **sd);
typedef int (*HPMHOOK_post_intif_rodex_checkhasnew) (int retVal___, struct map_session_data *sd);
-typedef int (*HPMHOOK_pre_intif_rodex_updatemail) (int64 *mail_id, int8 *flag);
-typedef int (*HPMHOOK_post_intif_rodex_updatemail) (int retVal___, int64 mail_id, int8 flag);
+typedef int (*HPMHOOK_pre_intif_rodex_updatemail) (struct map_session_data **sd, int64 *mail_id, uint8 *opentype, int8 *flag);
+typedef int (*HPMHOOK_post_intif_rodex_updatemail) (int retVal___, struct map_session_data *sd, int64 mail_id, uint8 opentype, int8 flag);
typedef int (*HPMHOOK_pre_intif_rodex_sendmail) (struct rodex_message **msg);
typedef int (*HPMHOOK_post_intif_rodex_sendmail) (int retVal___, struct rodex_message *msg);
typedef int (*HPMHOOK_pre_intif_rodex_checkname) (struct map_session_data **sd, const char **name);
typedef int (*HPMHOOK_post_intif_rodex_checkname) (int retVal___, struct map_session_data *sd, const char *name);
+typedef void (*HPMHOOK_pre_intif_pGetZenyAck) (int *fd);
+typedef void (*HPMHOOK_post_intif_pGetZenyAck) (int fd);
+typedef void (*HPMHOOK_pre_intif_pGetItemsAck) (int *fd);
+typedef void (*HPMHOOK_post_intif_pGetItemsAck) (int fd);
typedef int (*HPMHOOK_pre_intif_clan_kickoffline) (int *clan_id, int *kick_interval);
typedef int (*HPMHOOK_post_intif_clan_kickoffline) (int retVal___, int clan_id, int kick_interval);
typedef int (*HPMHOOK_pre_intif_clan_membercount) (int *clan_id, int *kick_interval);
@@ -5048,6 +5056,10 @@ typedef void (*HPMHOOK_pre_mapif_parse_rodex_checkname) (int *fd);
typedef void (*HPMHOOK_post_mapif_parse_rodex_checkname) (int fd);
typedef void (*HPMHOOK_pre_mapif_rodex_checkname) (int *fd, int *reqchar_id, int *target_char_id, int *target_class, int *target_level, char **name);
typedef void (*HPMHOOK_post_mapif_rodex_checkname) (int fd, int reqchar_id, int target_char_id, int target_class, int target_level, char *name);
+typedef void (*HPMHOOK_pre_mapif_rodex_getzenyack) (int *fd, int *char_id, int64 *mail_id, uint8 *opentype, int64 *zeny);
+typedef void (*HPMHOOK_post_mapif_rodex_getzenyack) (int fd, int char_id, int64 mail_id, uint8 opentype, int64 zeny);
+typedef void (*HPMHOOK_pre_mapif_rodex_getitemsack) (int *fd, int *char_id, int64 *mail_id, uint8 *opentype, int *count, const struct rodex_item **items);
+typedef void (*HPMHOOK_post_mapif_rodex_getitemsack) (int fd, int char_id, int64 mail_id, uint8 opentype, int count, const struct rodex_item *items);
typedef int (*HPMHOOK_pre_mapif_load_guild_storage) (int *fd, int *account_id, int *guild_id, char *flag);
typedef int (*HPMHOOK_post_mapif_load_guild_storage) (int retVal___, int fd, int account_id, int guild_id, char flag);
typedef int (*HPMHOOK_pre_mapif_save_guild_storage_ack) (int *fd, int *account_id, int *guild_id, int *fail);
@@ -5324,8 +5336,10 @@ typedef int (*HPMHOOK_pre_mob_ai_lazy) (int *tid, int64 *tick, int *id, intptr_t
typedef int (*HPMHOOK_post_mob_ai_lazy) (int retVal___, int tid, int64 tick, int id, intptr_t data);
typedef int (*HPMHOOK_pre_mob_ai_hard) (int *tid, int64 *tick, int *id, intptr_t *data);
typedef int (*HPMHOOK_post_mob_ai_hard) (int retVal___, int tid, int64 tick, int id, intptr_t data);
-typedef struct item_drop* (*HPMHOOK_pre_mob_setdropitem) (int *nameid, int *qty, struct item_data **data);
-typedef struct item_drop* (*HPMHOOK_post_mob_setdropitem) (struct item_drop* retVal___, int nameid, int qty, struct item_data *data);
+typedef void (*HPMHOOK_pre_mob_setdropitem_options) (struct item **item, struct optdrop_group **options);
+typedef void (*HPMHOOK_post_mob_setdropitem_options) (struct item *item, struct optdrop_group *options);
+typedef struct item_drop* (*HPMHOOK_pre_mob_setdropitem) (int *nameid, struct optdrop_group **options, int *qty, struct item_data **data);
+typedef struct item_drop* (*HPMHOOK_post_mob_setdropitem) (struct item_drop* retVal___, int nameid, struct optdrop_group *options, int qty, struct item_data *data);
typedef struct item_drop* (*HPMHOOK_pre_mob_setlootitem) (struct item **item);
typedef struct item_drop* (*HPMHOOK_post_mob_setlootitem) (struct item_drop* retVal___, struct item *item);
typedef int (*HPMHOOK_pre_mob_delay_item_drop) (int *tid, int64 *tick, int *id, intptr_t *data);
@@ -5390,6 +5404,14 @@ typedef unsigned int (*HPMHOOK_pre_mob_drop_adjust) (int *baserate, int *rate_ad
typedef unsigned int (*HPMHOOK_post_mob_drop_adjust) (unsigned int retVal___, int baserate, int rate_adjust, unsigned short rate_min, unsigned short rate_max);
typedef void (*HPMHOOK_pre_mob_item_dropratio_adjust) (int *nameid, int *mob_id, int **rate_adjust);
typedef void (*HPMHOOK_post_mob_item_dropratio_adjust) (int nameid, int mob_id, int *rate_adjust);
+typedef bool (*HPMHOOK_pre_mob_read_optdrops_option) (struct config_setting_t **option, struct optdrop_group_optslot **entry, int **idx, bool **calc_rate, int *slot, const char **group);
+typedef bool (*HPMHOOK_post_mob_read_optdrops_option) (bool retVal___, struct config_setting_t *option, struct optdrop_group_optslot *entry, int *idx, bool *calc_rate, int slot, const char *group);
+typedef bool (*HPMHOOK_pre_mob_read_optdrops_optslot) (struct config_setting_t **optslot, int *n, int *group_id, const char **group);
+typedef bool (*HPMHOOK_post_mob_read_optdrops_optslot) (bool retVal___, struct config_setting_t *optslot, int n, int group_id, const char *group);
+typedef bool (*HPMHOOK_pre_mob_read_optdrops_group) (struct config_setting_t **group, int *n);
+typedef bool (*HPMHOOK_post_mob_read_optdrops_group) (bool retVal___, struct config_setting_t *group, int n);
+typedef bool (*HPMHOOK_pre_mob_read_optdrops_db) (void);
+typedef bool (*HPMHOOK_post_mob_read_optdrops_db) (bool retVal___);
typedef void (*HPMHOOK_pre_mob_readdb) (void);
typedef void (*HPMHOOK_post_mob_readdb) (void);
typedef bool (*HPMHOOK_pre_mob_lookup_const) (const struct config_setting_t **it, const char **name, int **value);
@@ -5410,6 +5432,8 @@ typedef void (*HPMHOOK_pre_mob_read_db_mvpdrops_sub) (struct mob_db **entry, str
typedef void (*HPMHOOK_post_mob_read_db_mvpdrops_sub) (struct mob_db *entry, struct config_setting_t *t);
typedef uint32 (*HPMHOOK_pre_mob_read_db_mode_sub) (struct mob_db **entry, struct config_setting_t **t);
typedef uint32 (*HPMHOOK_post_mob_read_db_mode_sub) (uint32 retVal___, struct mob_db *entry, struct config_setting_t *t);
+typedef struct optdrop_group* (*HPMHOOK_pre_mob_read_db_drops_option) (struct mob_db **entry, const char **item_name, struct config_setting_t **drop, int **drop_rate);
+typedef struct optdrop_group* (*HPMHOOK_post_mob_read_db_drops_option) (struct optdrop_group* retVal___, struct mob_db *entry, const char *item_name, struct config_setting_t *drop, int *drop_rate);
typedef void (*HPMHOOK_pre_mob_read_db_stats_sub) (struct mob_db **entry, struct config_setting_t **t);
typedef void (*HPMHOOK_post_mob_read_db_stats_sub) (struct mob_db *entry, struct config_setting_t *t);
typedef void (*HPMHOOK_pre_mob_name_constants) (void);
@@ -5440,6 +5464,8 @@ typedef int (*HPMHOOK_pre_mob_final_ratio_sub) (union DBKey *key, struct DBData
typedef int (*HPMHOOK_post_mob_final_ratio_sub) (int retVal___, union DBKey key, struct DBData *data, va_list ap);
typedef void (*HPMHOOK_pre_mob_destroy_mob_db) (int *index);
typedef void (*HPMHOOK_post_mob_destroy_mob_db) (int index);
+typedef void (*HPMHOOK_pre_mob_destroy_drop_groups) (void);
+typedef void (*HPMHOOK_post_mob_destroy_drop_groups) (void);
typedef bool (*HPMHOOK_pre_mob_skill_db_libconfig) (const char **filename, bool *ignore_missing);
typedef bool (*HPMHOOK_post_mob_skill_db_libconfig) (bool retVal___, const char *filename, bool ignore_missing);
typedef bool (*HPMHOOK_pre_mob_skill_db_libconfig_sub) (struct config_setting_t **it, int *n);
@@ -6608,6 +6634,10 @@ typedef void (*HPMHOOK_pre_rodex_delete_mail) (struct map_session_data **sd, int
typedef void (*HPMHOOK_post_rodex_delete_mail) (struct map_session_data *sd, int64 mail_id);
typedef void (*HPMHOOK_pre_rodex_clean) (struct map_session_data **sd, int8 *flag);
typedef void (*HPMHOOK_post_rodex_clean) (struct map_session_data *sd, int8 flag);
+typedef void (*HPMHOOK_pre_rodex_getZenyAck) (struct map_session_data **sd, int64 *mail_id, int8 *opentype, int64 *zeny);
+typedef void (*HPMHOOK_post_rodex_getZenyAck) (struct map_session_data *sd, int64 mail_id, int8 opentype, int64 zeny);
+typedef void (*HPMHOOK_pre_rodex_getItemsAck) (struct map_session_data **sd, int64 *mail_id, int8 *opentype, int *count, const struct rodex_item **items);
+typedef void (*HPMHOOK_post_rodex_getItemsAck) (struct map_session_data *sd, int64 mail_id, int8 opentype, int count, const struct rodex_item *items);
#endif // MAP_RODEX_H
#ifdef MAP_SCRIPT_H /* script */
typedef void (*HPMHOOK_pre_script_init) (bool *minimal);
diff --git a/src/plugins/HPMHooking/HPMHooking_char.HPMHooksCore.inc b/src/plugins/HPMHooking/HPMHooking_char.HPMHooksCore.inc
index dbabf8ed4..9302a8d19 100644
--- a/src/plugins/HPMHooking/HPMHooking_char.HPMHooksCore.inc
+++ b/src/plugins/HPMHooking/HPMHooking_char.HPMHooksCore.inc
@@ -764,6 +764,10 @@ struct {
struct HPMHookPoint *HP_inter_rodex_savemessage_post;
struct HPMHookPoint *HP_inter_rodex_updatemail_pre;
struct HPMHookPoint *HP_inter_rodex_updatemail_post;
+ struct HPMHookPoint *HP_inter_rodex_getzeny_pre;
+ struct HPMHookPoint *HP_inter_rodex_getzeny_post;
+ struct HPMHookPoint *HP_inter_rodex_getitems_pre;
+ struct HPMHookPoint *HP_inter_rodex_getitems_post;
struct HPMHookPoint *HP_inter_storage_tosql_pre;
struct HPMHookPoint *HP_inter_storage_tosql_post;
struct HPMHookPoint *HP_inter_storage_fromsql_pre;
@@ -1224,6 +1228,10 @@ struct {
struct HPMHookPoint *HP_mapif_parse_rodex_checkname_post;
struct HPMHookPoint *HP_mapif_rodex_checkname_pre;
struct HPMHookPoint *HP_mapif_rodex_checkname_post;
+ struct HPMHookPoint *HP_mapif_rodex_getzenyack_pre;
+ struct HPMHookPoint *HP_mapif_rodex_getzenyack_post;
+ struct HPMHookPoint *HP_mapif_rodex_getitemsack_pre;
+ struct HPMHookPoint *HP_mapif_rodex_getitemsack_post;
struct HPMHookPoint *HP_mapif_load_guild_storage_pre;
struct HPMHookPoint *HP_mapif_load_guild_storage_post;
struct HPMHookPoint *HP_mapif_save_guild_storage_ack_pre;
@@ -2403,6 +2411,10 @@ struct {
int HP_inter_rodex_savemessage_post;
int HP_inter_rodex_updatemail_pre;
int HP_inter_rodex_updatemail_post;
+ int HP_inter_rodex_getzeny_pre;
+ int HP_inter_rodex_getzeny_post;
+ int HP_inter_rodex_getitems_pre;
+ int HP_inter_rodex_getitems_post;
int HP_inter_storage_tosql_pre;
int HP_inter_storage_tosql_post;
int HP_inter_storage_fromsql_pre;
@@ -2863,6 +2875,10 @@ struct {
int HP_mapif_parse_rodex_checkname_post;
int HP_mapif_rodex_checkname_pre;
int HP_mapif_rodex_checkname_post;
+ int HP_mapif_rodex_getzenyack_pre;
+ int HP_mapif_rodex_getzenyack_post;
+ int HP_mapif_rodex_getitemsack_pre;
+ int HP_mapif_rodex_getitemsack_post;
int HP_mapif_load_guild_storage_pre;
int HP_mapif_load_guild_storage_post;
int HP_mapif_save_guild_storage_ack_pre;
diff --git a/src/plugins/HPMHooking/HPMHooking_char.HookingPoints.inc b/src/plugins/HPMHooking/HPMHooking_char.HookingPoints.inc
index f666ad1fd..60162c1a8 100644
--- a/src/plugins/HPMHooking/HPMHooking_char.HookingPoints.inc
+++ b/src/plugins/HPMHooking/HPMHooking_char.HookingPoints.inc
@@ -416,6 +416,8 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(inter_rodex->checkname, HP_inter_rodex_checkname) },
{ HP_POP(inter_rodex->savemessage, HP_inter_rodex_savemessage) },
{ HP_POP(inter_rodex->updatemail, HP_inter_rodex_updatemail) },
+ { HP_POP(inter_rodex->getzeny, HP_inter_rodex_getzeny) },
+ { HP_POP(inter_rodex->getitems, HP_inter_rodex_getitems) },
/* inter_storage_interface */
{ HP_POP(inter_storage->tosql, HP_inter_storage_tosql) },
{ HP_POP(inter_storage->fromsql, HP_inter_storage_fromsql) },
@@ -650,6 +652,8 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(mapif->rodex_send, HP_mapif_rodex_send) },
{ HP_POP(mapif->parse_rodex_checkname, HP_mapif_parse_rodex_checkname) },
{ HP_POP(mapif->rodex_checkname, HP_mapif_rodex_checkname) },
+ { HP_POP(mapif->rodex_getzenyack, HP_mapif_rodex_getzenyack) },
+ { HP_POP(mapif->rodex_getitemsack, HP_mapif_rodex_getitemsack) },
{ HP_POP(mapif->load_guild_storage, HP_mapif_load_guild_storage) },
{ HP_POP(mapif->save_guild_storage_ack, HP_mapif_save_guild_storage_ack) },
{ HP_POP(mapif->parse_LoadGuildStorage, HP_mapif_parse_LoadGuildStorage) },
diff --git a/src/plugins/HPMHooking/HPMHooking_char.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_char.Hooks.inc
index edffe7c11..2b7e25e5d 100644
--- a/src/plugins/HPMHooking/HPMHooking_char.Hooks.inc
+++ b/src/plugins/HPMHooking/HPMHooking_char.Hooks.inc
@@ -9904,15 +9904,15 @@ int64 HP_inter_rodex_savemessage(struct rodex_message *msg) {
}
return retVal___;
}
-bool HP_inter_rodex_updatemail(int64 mail_id, int8 flag) {
+bool HP_inter_rodex_updatemail(int fd, int account_id, int char_id, int64 mail_id, uint8 opentype, int8 flag) {
int hIndex = 0;
bool retVal___ = false;
if (HPMHooks.count.HP_inter_rodex_updatemail_pre > 0) {
- bool (*preHookFunc) (int64 *mail_id, int8 *flag);
+ bool (*preHookFunc) (int *fd, int *account_id, int *char_id, int64 *mail_id, uint8 *opentype, int8 *flag);
*HPMforce_return = false;
for (hIndex = 0; hIndex < HPMHooks.count.HP_inter_rodex_updatemail_pre; hIndex++) {
preHookFunc = HPMHooks.list.HP_inter_rodex_updatemail_pre[hIndex].func;
- retVal___ = preHookFunc(&mail_id, &flag);
+ retVal___ = preHookFunc(&fd, &account_id, &char_id, &mail_id, &opentype, &flag);
}
if (*HPMforce_return) {
*HPMforce_return = false;
@@ -9920,13 +9920,67 @@ bool HP_inter_rodex_updatemail(int64 mail_id, int8 flag) {
}
}
{
- retVal___ = HPMHooks.source.inter_rodex.updatemail(mail_id, flag);
+ retVal___ = HPMHooks.source.inter_rodex.updatemail(fd, account_id, char_id, mail_id, opentype, flag);
}
if (HPMHooks.count.HP_inter_rodex_updatemail_post > 0) {
- bool (*postHookFunc) (bool retVal___, int64 mail_id, int8 flag);
+ bool (*postHookFunc) (bool retVal___, int fd, int account_id, int char_id, int64 mail_id, uint8 opentype, int8 flag);
for (hIndex = 0; hIndex < HPMHooks.count.HP_inter_rodex_updatemail_post; hIndex++) {
postHookFunc = HPMHooks.list.HP_inter_rodex_updatemail_post[hIndex].func;
- retVal___ = postHookFunc(retVal___, mail_id, flag);
+ retVal___ = postHookFunc(retVal___, fd, account_id, char_id, mail_id, opentype, flag);
+ }
+ }
+ return retVal___;
+}
+int64 HP_inter_rodex_getzeny(int64 mail_id) {
+ int hIndex = 0;
+ int64 retVal___ = 0;
+ if (HPMHooks.count.HP_inter_rodex_getzeny_pre > 0) {
+ int64 (*preHookFunc) (int64 *mail_id);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_inter_rodex_getzeny_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_inter_rodex_getzeny_pre[hIndex].func;
+ retVal___ = preHookFunc(&mail_id);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.inter_rodex.getzeny(mail_id);
+ }
+ if (HPMHooks.count.HP_inter_rodex_getzeny_post > 0) {
+ int64 (*postHookFunc) (int64 retVal___, int64 mail_id);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_inter_rodex_getzeny_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_inter_rodex_getzeny_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, mail_id);
+ }
+ }
+ return retVal___;
+}
+int HP_inter_rodex_getitems(int64 mail_id, struct rodex_item *items) {
+ int hIndex = 0;
+ int retVal___ = 0;
+ if (HPMHooks.count.HP_inter_rodex_getitems_pre > 0) {
+ int (*preHookFunc) (int64 *mail_id, struct rodex_item **items);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_inter_rodex_getitems_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_inter_rodex_getitems_pre[hIndex].func;
+ retVal___ = preHookFunc(&mail_id, &items);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.inter_rodex.getitems(mail_id, items);
+ }
+ if (HPMHooks.count.HP_inter_rodex_getitems_post > 0) {
+ int (*postHookFunc) (int retVal___, int64 mail_id, struct rodex_item *items);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_inter_rodex_getitems_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_inter_rodex_getitems_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, mail_id, items);
}
}
return retVal___;
@@ -16047,6 +16101,58 @@ void HP_mapif_rodex_checkname(int fd, int reqchar_id, int target_char_id, int ta
}
return;
}
+void HP_mapif_rodex_getzenyack(int fd, int char_id, int64 mail_id, uint8 opentype, int64 zeny) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_mapif_rodex_getzenyack_pre > 0) {
+ void (*preHookFunc) (int *fd, int *char_id, int64 *mail_id, uint8 *opentype, int64 *zeny);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_mapif_rodex_getzenyack_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_mapif_rodex_getzenyack_pre[hIndex].func;
+ preHookFunc(&fd, &char_id, &mail_id, &opentype, &zeny);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.mapif.rodex_getzenyack(fd, char_id, mail_id, opentype, zeny);
+ }
+ if (HPMHooks.count.HP_mapif_rodex_getzenyack_post > 0) {
+ void (*postHookFunc) (int fd, int char_id, int64 mail_id, uint8 opentype, int64 zeny);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_mapif_rodex_getzenyack_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_mapif_rodex_getzenyack_post[hIndex].func;
+ postHookFunc(fd, char_id, mail_id, opentype, zeny);
+ }
+ }
+ return;
+}
+void HP_mapif_rodex_getitemsack(int fd, int char_id, int64 mail_id, uint8 opentype, int count, const struct rodex_item *items) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_mapif_rodex_getitemsack_pre > 0) {
+ void (*preHookFunc) (int *fd, int *char_id, int64 *mail_id, uint8 *opentype, int *count, const struct rodex_item **items);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_mapif_rodex_getitemsack_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_mapif_rodex_getitemsack_pre[hIndex].func;
+ preHookFunc(&fd, &char_id, &mail_id, &opentype, &count, &items);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.mapif.rodex_getitemsack(fd, char_id, mail_id, opentype, count, items);
+ }
+ if (HPMHooks.count.HP_mapif_rodex_getitemsack_post > 0) {
+ void (*postHookFunc) (int fd, int char_id, int64 mail_id, uint8 opentype, int count, const struct rodex_item *items);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_mapif_rodex_getitemsack_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_mapif_rodex_getitemsack_post[hIndex].func;
+ postHookFunc(fd, char_id, mail_id, opentype, count, items);
+ }
+ }
+ return;
+}
int HP_mapif_load_guild_storage(int fd, int account_id, int guild_id, char flag) {
int hIndex = 0;
int retVal___ = 0;
diff --git a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
index 5648dd267..d3b4ff504 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
@@ -2900,6 +2900,10 @@ struct {
struct HPMHookPoint *HP_intif_rodex_sendmail_post;
struct HPMHookPoint *HP_intif_rodex_checkname_pre;
struct HPMHookPoint *HP_intif_rodex_checkname_post;
+ struct HPMHookPoint *HP_intif_pGetZenyAck_pre;
+ struct HPMHookPoint *HP_intif_pGetZenyAck_post;
+ struct HPMHookPoint *HP_intif_pGetItemsAck_pre;
+ struct HPMHookPoint *HP_intif_pGetItemsAck_post;
struct HPMHookPoint *HP_intif_clan_kickoffline_pre;
struct HPMHookPoint *HP_intif_clan_kickoffline_post;
struct HPMHookPoint *HP_intif_clan_membercount_pre;
@@ -3900,6 +3904,8 @@ struct {
struct HPMHookPoint *HP_mob_ai_lazy_post;
struct HPMHookPoint *HP_mob_ai_hard_pre;
struct HPMHookPoint *HP_mob_ai_hard_post;
+ struct HPMHookPoint *HP_mob_setdropitem_options_pre;
+ struct HPMHookPoint *HP_mob_setdropitem_options_post;
struct HPMHookPoint *HP_mob_setdropitem_pre;
struct HPMHookPoint *HP_mob_setdropitem_post;
struct HPMHookPoint *HP_mob_setlootitem_pre;
@@ -3966,6 +3972,14 @@ struct {
struct HPMHookPoint *HP_mob_drop_adjust_post;
struct HPMHookPoint *HP_mob_item_dropratio_adjust_pre;
struct HPMHookPoint *HP_mob_item_dropratio_adjust_post;
+ struct HPMHookPoint *HP_mob_read_optdrops_option_pre;
+ struct HPMHookPoint *HP_mob_read_optdrops_option_post;
+ struct HPMHookPoint *HP_mob_read_optdrops_optslot_pre;
+ struct HPMHookPoint *HP_mob_read_optdrops_optslot_post;
+ struct HPMHookPoint *HP_mob_read_optdrops_group_pre;
+ struct HPMHookPoint *HP_mob_read_optdrops_group_post;
+ struct HPMHookPoint *HP_mob_read_optdrops_db_pre;
+ struct HPMHookPoint *HP_mob_read_optdrops_db_post;
struct HPMHookPoint *HP_mob_readdb_pre;
struct HPMHookPoint *HP_mob_readdb_post;
struct HPMHookPoint *HP_mob_lookup_const_pre;
@@ -3986,6 +4000,8 @@ struct {
struct HPMHookPoint *HP_mob_read_db_mvpdrops_sub_post;
struct HPMHookPoint *HP_mob_read_db_mode_sub_pre;
struct HPMHookPoint *HP_mob_read_db_mode_sub_post;
+ struct HPMHookPoint *HP_mob_read_db_drops_option_pre;
+ struct HPMHookPoint *HP_mob_read_db_drops_option_post;
struct HPMHookPoint *HP_mob_read_db_stats_sub_pre;
struct HPMHookPoint *HP_mob_read_db_stats_sub_post;
struct HPMHookPoint *HP_mob_name_constants_pre;
@@ -4016,6 +4032,8 @@ struct {
struct HPMHookPoint *HP_mob_final_ratio_sub_post;
struct HPMHookPoint *HP_mob_destroy_mob_db_pre;
struct HPMHookPoint *HP_mob_destroy_mob_db_post;
+ struct HPMHookPoint *HP_mob_destroy_drop_groups_pre;
+ struct HPMHookPoint *HP_mob_destroy_drop_groups_post;
struct HPMHookPoint *HP_mob_skill_db_libconfig_pre;
struct HPMHookPoint *HP_mob_skill_db_libconfig_post;
struct HPMHookPoint *HP_mob_skill_db_libconfig_sub_pre;
@@ -5122,6 +5140,10 @@ struct {
struct HPMHookPoint *HP_rodex_delete_mail_post;
struct HPMHookPoint *HP_rodex_clean_pre;
struct HPMHookPoint *HP_rodex_clean_post;
+ struct HPMHookPoint *HP_rodex_getZenyAck_pre;
+ struct HPMHookPoint *HP_rodex_getZenyAck_post;
+ struct HPMHookPoint *HP_rodex_getItemsAck_pre;
+ struct HPMHookPoint *HP_rodex_getItemsAck_post;
struct HPMHookPoint *HP_script_init_pre;
struct HPMHookPoint *HP_script_init_post;
struct HPMHookPoint *HP_script_final_pre;
@@ -9587,6 +9609,10 @@ struct {
int HP_intif_rodex_sendmail_post;
int HP_intif_rodex_checkname_pre;
int HP_intif_rodex_checkname_post;
+ int HP_intif_pGetZenyAck_pre;
+ int HP_intif_pGetZenyAck_post;
+ int HP_intif_pGetItemsAck_pre;
+ int HP_intif_pGetItemsAck_post;
int HP_intif_clan_kickoffline_pre;
int HP_intif_clan_kickoffline_post;
int HP_intif_clan_membercount_pre;
@@ -10587,6 +10613,8 @@ struct {
int HP_mob_ai_lazy_post;
int HP_mob_ai_hard_pre;
int HP_mob_ai_hard_post;
+ int HP_mob_setdropitem_options_pre;
+ int HP_mob_setdropitem_options_post;
int HP_mob_setdropitem_pre;
int HP_mob_setdropitem_post;
int HP_mob_setlootitem_pre;
@@ -10653,6 +10681,14 @@ struct {
int HP_mob_drop_adjust_post;
int HP_mob_item_dropratio_adjust_pre;
int HP_mob_item_dropratio_adjust_post;
+ int HP_mob_read_optdrops_option_pre;
+ int HP_mob_read_optdrops_option_post;
+ int HP_mob_read_optdrops_optslot_pre;
+ int HP_mob_read_optdrops_optslot_post;
+ int HP_mob_read_optdrops_group_pre;
+ int HP_mob_read_optdrops_group_post;
+ int HP_mob_read_optdrops_db_pre;
+ int HP_mob_read_optdrops_db_post;
int HP_mob_readdb_pre;
int HP_mob_readdb_post;
int HP_mob_lookup_const_pre;
@@ -10673,6 +10709,8 @@ struct {
int HP_mob_read_db_mvpdrops_sub_post;
int HP_mob_read_db_mode_sub_pre;
int HP_mob_read_db_mode_sub_post;
+ int HP_mob_read_db_drops_option_pre;
+ int HP_mob_read_db_drops_option_post;
int HP_mob_read_db_stats_sub_pre;
int HP_mob_read_db_stats_sub_post;
int HP_mob_name_constants_pre;
@@ -10703,6 +10741,8 @@ struct {
int HP_mob_final_ratio_sub_post;
int HP_mob_destroy_mob_db_pre;
int HP_mob_destroy_mob_db_post;
+ int HP_mob_destroy_drop_groups_pre;
+ int HP_mob_destroy_drop_groups_post;
int HP_mob_skill_db_libconfig_pre;
int HP_mob_skill_db_libconfig_post;
int HP_mob_skill_db_libconfig_sub_pre;
@@ -11809,6 +11849,10 @@ struct {
int HP_rodex_delete_mail_post;
int HP_rodex_clean_pre;
int HP_rodex_clean_post;
+ int HP_rodex_getZenyAck_pre;
+ int HP_rodex_getZenyAck_post;
+ int HP_rodex_getItemsAck_pre;
+ int HP_rodex_getItemsAck_post;
int HP_script_init_pre;
int HP_script_init_post;
int HP_script_final_pre;
diff --git a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
index 6ab056dfd..51ea6a44e 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
@@ -1487,6 +1487,8 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(intif->rodex_updatemail, HP_intif_rodex_updatemail) },
{ HP_POP(intif->rodex_sendmail, HP_intif_rodex_sendmail) },
{ HP_POP(intif->rodex_checkname, HP_intif_rodex_checkname) },
+ { HP_POP(intif->pGetZenyAck, HP_intif_pGetZenyAck) },
+ { HP_POP(intif->pGetItemsAck, HP_intif_pGetItemsAck) },
{ HP_POP(intif->clan_kickoffline, HP_intif_clan_kickoffline) },
{ HP_POP(intif->clan_membercount, HP_intif_clan_membercount) },
{ HP_POP(intif->request_accinfo, HP_intif_request_accinfo) },
@@ -1999,6 +2001,7 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(mob->ai_sub_lazy, HP_mob_ai_sub_lazy) },
{ HP_POP(mob->ai_lazy, HP_mob_ai_lazy) },
{ HP_POP(mob->ai_hard, HP_mob_ai_hard) },
+ { HP_POP(mob->setdropitem_options, HP_mob_setdropitem_options) },
{ HP_POP(mob->setdropitem, HP_mob_setdropitem) },
{ HP_POP(mob->setlootitem, HP_mob_setlootitem) },
{ HP_POP(mob->delay_item_drop, HP_mob_delay_item_drop) },
@@ -2032,6 +2035,10 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(mob->clone_delete, HP_mob_clone_delete) },
{ HP_POP(mob->drop_adjust, HP_mob_drop_adjust) },
{ HP_POP(mob->item_dropratio_adjust, HP_mob_item_dropratio_adjust) },
+ { HP_POP(mob->read_optdrops_option, HP_mob_read_optdrops_option) },
+ { HP_POP(mob->read_optdrops_optslot, HP_mob_read_optdrops_optslot) },
+ { HP_POP(mob->read_optdrops_group, HP_mob_read_optdrops_group) },
+ { HP_POP(mob->read_optdrops_db, HP_mob_read_optdrops_db) },
{ HP_POP(mob->readdb, HP_mob_readdb) },
{ HP_POP(mob->lookup_const, HP_mob_lookup_const) },
{ HP_POP(mob->get_const, HP_mob_get_const) },
@@ -2042,6 +2049,7 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(mob->read_db_drops_sub, HP_mob_read_db_drops_sub) },
{ HP_POP(mob->read_db_mvpdrops_sub, HP_mob_read_db_mvpdrops_sub) },
{ HP_POP(mob->read_db_mode_sub, HP_mob_read_db_mode_sub) },
+ { HP_POP(mob->read_db_drops_option, HP_mob_read_db_drops_option) },
{ HP_POP(mob->read_db_stats_sub, HP_mob_read_db_stats_sub) },
{ HP_POP(mob->name_constants, HP_mob_name_constants) },
{ HP_POP(mob->readdb_mobavail, HP_mob_readdb_mobavail) },
@@ -2057,6 +2065,7 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(mob->set_item_drop_ratio, HP_mob_set_item_drop_ratio) },
{ HP_POP(mob->final_ratio_sub, HP_mob_final_ratio_sub) },
{ HP_POP(mob->destroy_mob_db, HP_mob_destroy_mob_db) },
+ { HP_POP(mob->destroy_drop_groups, HP_mob_destroy_drop_groups) },
{ HP_POP(mob->skill_db_libconfig, HP_mob_skill_db_libconfig) },
{ HP_POP(mob->skill_db_libconfig_sub, HP_mob_skill_db_libconfig_sub) },
{ HP_POP(mob->skill_db_libconfig_sub_skill, HP_mob_skill_db_libconfig_sub_skill) },
@@ -2624,6 +2633,8 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(rodex->get_items, HP_rodex_get_items) },
{ HP_POP(rodex->delete_mail, HP_rodex_delete_mail) },
{ HP_POP(rodex->clean, HP_rodex_clean) },
+ { HP_POP(rodex->getZenyAck, HP_rodex_getZenyAck) },
+ { HP_POP(rodex->getItemsAck, HP_rodex_getItemsAck) },
/* script_interface */
{ HP_POP(script->init, HP_script_init) },
{ HP_POP(script->final, HP_script_final) },
diff --git a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
index 26cf8ef00..7978909eb 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
@@ -38047,15 +38047,15 @@ int HP_intif_rodex_checkhasnew(struct map_session_data *sd) {
}
return retVal___;
}
-int HP_intif_rodex_updatemail(int64 mail_id, int8 flag) {
+int HP_intif_rodex_updatemail(struct map_session_data *sd, int64 mail_id, uint8 opentype, int8 flag) {
int hIndex = 0;
int retVal___ = 0;
if (HPMHooks.count.HP_intif_rodex_updatemail_pre > 0) {
- int (*preHookFunc) (int64 *mail_id, int8 *flag);
+ int (*preHookFunc) (struct map_session_data **sd, int64 *mail_id, uint8 *opentype, int8 *flag);
*HPMforce_return = false;
for (hIndex = 0; hIndex < HPMHooks.count.HP_intif_rodex_updatemail_pre; hIndex++) {
preHookFunc = HPMHooks.list.HP_intif_rodex_updatemail_pre[hIndex].func;
- retVal___ = preHookFunc(&mail_id, &flag);
+ retVal___ = preHookFunc(&sd, &mail_id, &opentype, &flag);
}
if (*HPMforce_return) {
*HPMforce_return = false;
@@ -38063,13 +38063,13 @@ int HP_intif_rodex_updatemail(int64 mail_id, int8 flag) {
}
}
{
- retVal___ = HPMHooks.source.intif.rodex_updatemail(mail_id, flag);
+ retVal___ = HPMHooks.source.intif.rodex_updatemail(sd, mail_id, opentype, flag);
}
if (HPMHooks.count.HP_intif_rodex_updatemail_post > 0) {
- int (*postHookFunc) (int retVal___, int64 mail_id, int8 flag);
+ int (*postHookFunc) (int retVal___, struct map_session_data *sd, int64 mail_id, uint8 opentype, int8 flag);
for (hIndex = 0; hIndex < HPMHooks.count.HP_intif_rodex_updatemail_post; hIndex++) {
postHookFunc = HPMHooks.list.HP_intif_rodex_updatemail_post[hIndex].func;
- retVal___ = postHookFunc(retVal___, mail_id, flag);
+ retVal___ = postHookFunc(retVal___, sd, mail_id, opentype, flag);
}
}
return retVal___;
@@ -38128,6 +38128,58 @@ int HP_intif_rodex_checkname(struct map_session_data *sd, const char *name) {
}
return retVal___;
}
+void HP_intif_pGetZenyAck(int fd) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_intif_pGetZenyAck_pre > 0) {
+ void (*preHookFunc) (int *fd);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_intif_pGetZenyAck_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_intif_pGetZenyAck_pre[hIndex].func;
+ preHookFunc(&fd);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.intif.pGetZenyAck(fd);
+ }
+ if (HPMHooks.count.HP_intif_pGetZenyAck_post > 0) {
+ void (*postHookFunc) (int fd);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_intif_pGetZenyAck_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_intif_pGetZenyAck_post[hIndex].func;
+ postHookFunc(fd);
+ }
+ }
+ return;
+}
+void HP_intif_pGetItemsAck(int fd) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_intif_pGetItemsAck_pre > 0) {
+ void (*preHookFunc) (int *fd);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_intif_pGetItemsAck_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_intif_pGetItemsAck_pre[hIndex].func;
+ preHookFunc(&fd);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.intif.pGetItemsAck(fd);
+ }
+ if (HPMHooks.count.HP_intif_pGetItemsAck_post > 0) {
+ void (*postHookFunc) (int fd);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_intif_pGetItemsAck_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_intif_pGetItemsAck_post[hIndex].func;
+ postHookFunc(fd);
+ }
+ }
+ return;
+}
int HP_intif_clan_kickoffline(int clan_id, int kick_interval) {
int hIndex = 0;
int retVal___ = 0;
@@ -51698,15 +51750,41 @@ int HP_mob_ai_hard(int tid, int64 tick, int id, intptr_t data) {
}
return retVal___;
}
-struct item_drop* HP_mob_setdropitem(int nameid, int qty, struct item_data *data) {
+void HP_mob_setdropitem_options(struct item *item, struct optdrop_group *options) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_mob_setdropitem_options_pre > 0) {
+ void (*preHookFunc) (struct item **item, struct optdrop_group **options);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_mob_setdropitem_options_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_mob_setdropitem_options_pre[hIndex].func;
+ preHookFunc(&item, &options);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.mob.setdropitem_options(item, options);
+ }
+ if (HPMHooks.count.HP_mob_setdropitem_options_post > 0) {
+ void (*postHookFunc) (struct item *item, struct optdrop_group *options);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_mob_setdropitem_options_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_mob_setdropitem_options_post[hIndex].func;
+ postHookFunc(item, options);
+ }
+ }
+ return;
+}
+struct item_drop* HP_mob_setdropitem(int nameid, struct optdrop_group *options, int qty, struct item_data *data) {
int hIndex = 0;
struct item_drop* retVal___ = NULL;
if (HPMHooks.count.HP_mob_setdropitem_pre > 0) {
- struct item_drop* (*preHookFunc) (int *nameid, int *qty, struct item_data **data);
+ struct item_drop* (*preHookFunc) (int *nameid, struct optdrop_group **options, int *qty, struct item_data **data);
*HPMforce_return = false;
for (hIndex = 0; hIndex < HPMHooks.count.HP_mob_setdropitem_pre; hIndex++) {
preHookFunc = HPMHooks.list.HP_mob_setdropitem_pre[hIndex].func;
- retVal___ = preHookFunc(&nameid, &qty, &data);
+ retVal___ = preHookFunc(&nameid, &options, &qty, &data);
}
if (*HPMforce_return) {
*HPMforce_return = false;
@@ -51714,13 +51792,13 @@ struct item_drop* HP_mob_setdropitem(int nameid, int qty, struct item_data *data
}
}
{
- retVal___ = HPMHooks.source.mob.setdropitem(nameid, qty, data);
+ retVal___ = HPMHooks.source.mob.setdropitem(nameid, options, qty, data);
}
if (HPMHooks.count.HP_mob_setdropitem_post > 0) {
- struct item_drop* (*postHookFunc) (struct item_drop* retVal___, int nameid, int qty, struct item_data *data);
+ struct item_drop* (*postHookFunc) (struct item_drop* retVal___, int nameid, struct optdrop_group *options, int qty, struct item_data *data);
for (hIndex = 0; hIndex < HPMHooks.count.HP_mob_setdropitem_post; hIndex++) {
postHookFunc = HPMHooks.list.HP_mob_setdropitem_post[hIndex].func;
- retVal___ = postHookFunc(retVal___, nameid, qty, data);
+ retVal___ = postHookFunc(retVal___, nameid, options, qty, data);
}
}
return retVal___;
@@ -52613,6 +52691,114 @@ void HP_mob_item_dropratio_adjust(int nameid, int mob_id, int *rate_adjust) {
}
return;
}
+bool HP_mob_read_optdrops_option(struct config_setting_t *option, struct optdrop_group_optslot *entry, int *idx, bool *calc_rate, int slot, const char *group) {
+ int hIndex = 0;
+ bool retVal___ = false;
+ if (HPMHooks.count.HP_mob_read_optdrops_option_pre > 0) {
+ bool (*preHookFunc) (struct config_setting_t **option, struct optdrop_group_optslot **entry, int **idx, bool **calc_rate, int *slot, const char **group);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_mob_read_optdrops_option_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_mob_read_optdrops_option_pre[hIndex].func;
+ retVal___ = preHookFunc(&option, &entry, &idx, &calc_rate, &slot, &group);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.mob.read_optdrops_option(option, entry, idx, calc_rate, slot, group);
+ }
+ if (HPMHooks.count.HP_mob_read_optdrops_option_post > 0) {
+ bool (*postHookFunc) (bool retVal___, struct config_setting_t *option, struct optdrop_group_optslot *entry, int *idx, bool *calc_rate, int slot, const char *group);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_mob_read_optdrops_option_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_mob_read_optdrops_option_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, option, entry, idx, calc_rate, slot, group);
+ }
+ }
+ return retVal___;
+}
+bool HP_mob_read_optdrops_optslot(struct config_setting_t *optslot, int n, int group_id, const char *group) {
+ int hIndex = 0;
+ bool retVal___ = false;
+ if (HPMHooks.count.HP_mob_read_optdrops_optslot_pre > 0) {
+ bool (*preHookFunc) (struct config_setting_t **optslot, int *n, int *group_id, const char **group);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_mob_read_optdrops_optslot_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_mob_read_optdrops_optslot_pre[hIndex].func;
+ retVal___ = preHookFunc(&optslot, &n, &group_id, &group);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.mob.read_optdrops_optslot(optslot, n, group_id, group);
+ }
+ if (HPMHooks.count.HP_mob_read_optdrops_optslot_post > 0) {
+ bool (*postHookFunc) (bool retVal___, struct config_setting_t *optslot, int n, int group_id, const char *group);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_mob_read_optdrops_optslot_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_mob_read_optdrops_optslot_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, optslot, n, group_id, group);
+ }
+ }
+ return retVal___;
+}
+bool HP_mob_read_optdrops_group(struct config_setting_t *group, int n) {
+ int hIndex = 0;
+ bool retVal___ = false;
+ if (HPMHooks.count.HP_mob_read_optdrops_group_pre > 0) {
+ bool (*preHookFunc) (struct config_setting_t **group, int *n);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_mob_read_optdrops_group_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_mob_read_optdrops_group_pre[hIndex].func;
+ retVal___ = preHookFunc(&group, &n);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.mob.read_optdrops_group(group, n);
+ }
+ if (HPMHooks.count.HP_mob_read_optdrops_group_post > 0) {
+ bool (*postHookFunc) (bool retVal___, struct config_setting_t *group, int n);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_mob_read_optdrops_group_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_mob_read_optdrops_group_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, group, n);
+ }
+ }
+ return retVal___;
+}
+bool HP_mob_read_optdrops_db(void) {
+ int hIndex = 0;
+ bool retVal___ = false;
+ if (HPMHooks.count.HP_mob_read_optdrops_db_pre > 0) {
+ bool (*preHookFunc) (void);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_mob_read_optdrops_db_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_mob_read_optdrops_db_pre[hIndex].func;
+ retVal___ = preHookFunc();
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.mob.read_optdrops_db();
+ }
+ if (HPMHooks.count.HP_mob_read_optdrops_db_post > 0) {
+ bool (*postHookFunc) (bool retVal___);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_mob_read_optdrops_db_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_mob_read_optdrops_db_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___);
+ }
+ }
+ return retVal___;
+}
void HP_mob_readdb(void) {
int hIndex = 0;
if (HPMHooks.count.HP_mob_readdb_pre > 0) {
@@ -52879,6 +53065,33 @@ uint32 HP_mob_read_db_mode_sub(struct mob_db *entry, struct config_setting_t *t)
}
return retVal___;
}
+struct optdrop_group* HP_mob_read_db_drops_option(struct mob_db *entry, const char *item_name, struct config_setting_t *drop, int *drop_rate) {
+ int hIndex = 0;
+ struct optdrop_group* retVal___ = NULL;
+ if (HPMHooks.count.HP_mob_read_db_drops_option_pre > 0) {
+ struct optdrop_group* (*preHookFunc) (struct mob_db **entry, const char **item_name, struct config_setting_t **drop, int **drop_rate);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_mob_read_db_drops_option_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_mob_read_db_drops_option_pre[hIndex].func;
+ retVal___ = preHookFunc(&entry, &item_name, &drop, &drop_rate);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.mob.read_db_drops_option(entry, item_name, drop, drop_rate);
+ }
+ if (HPMHooks.count.HP_mob_read_db_drops_option_post > 0) {
+ struct optdrop_group* (*postHookFunc) (struct optdrop_group* retVal___, struct mob_db *entry, const char *item_name, struct config_setting_t *drop, int *drop_rate);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_mob_read_db_drops_option_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_mob_read_db_drops_option_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, entry, item_name, drop, drop_rate);
+ }
+ }
+ return retVal___;
+}
void HP_mob_read_db_stats_sub(struct mob_db *entry, struct config_setting_t *t) {
int hIndex = 0;
if (HPMHooks.count.HP_mob_read_db_stats_sub_pre > 0) {
@@ -53282,6 +53495,32 @@ void HP_mob_destroy_mob_db(int index) {
}
return;
}
+void HP_mob_destroy_drop_groups(void) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_mob_destroy_drop_groups_pre > 0) {
+ void (*preHookFunc) (void);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_mob_destroy_drop_groups_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_mob_destroy_drop_groups_pre[hIndex].func;
+ preHookFunc();
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.mob.destroy_drop_groups();
+ }
+ if (HPMHooks.count.HP_mob_destroy_drop_groups_post > 0) {
+ void (*postHookFunc) (void);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_mob_destroy_drop_groups_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_mob_destroy_drop_groups_post[hIndex].func;
+ postHookFunc();
+ }
+ }
+ return;
+}
bool HP_mob_skill_db_libconfig(const char *filename, bool ignore_missing) {
int hIndex = 0;
bool retVal___ = false;
@@ -68218,6 +68457,58 @@ void HP_rodex_clean(struct map_session_data *sd, int8 flag) {
}
return;
}
+void HP_rodex_getZenyAck(struct map_session_data *sd, int64 mail_id, int8 opentype, int64 zeny) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_rodex_getZenyAck_pre > 0) {
+ void (*preHookFunc) (struct map_session_data **sd, int64 *mail_id, int8 *opentype, int64 *zeny);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_rodex_getZenyAck_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_rodex_getZenyAck_pre[hIndex].func;
+ preHookFunc(&sd, &mail_id, &opentype, &zeny);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.rodex.getZenyAck(sd, mail_id, opentype, zeny);
+ }
+ if (HPMHooks.count.HP_rodex_getZenyAck_post > 0) {
+ void (*postHookFunc) (struct map_session_data *sd, int64 mail_id, int8 opentype, int64 zeny);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_rodex_getZenyAck_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_rodex_getZenyAck_post[hIndex].func;
+ postHookFunc(sd, mail_id, opentype, zeny);
+ }
+ }
+ return;
+}
+void HP_rodex_getItemsAck(struct map_session_data *sd, int64 mail_id, int8 opentype, int count, const struct rodex_item *items) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_rodex_getItemsAck_pre > 0) {
+ void (*preHookFunc) (struct map_session_data **sd, int64 *mail_id, int8 *opentype, int *count, const struct rodex_item **items);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_rodex_getItemsAck_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_rodex_getItemsAck_pre[hIndex].func;
+ preHookFunc(&sd, &mail_id, &opentype, &count, &items);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.rodex.getItemsAck(sd, mail_id, opentype, count, items);
+ }
+ if (HPMHooks.count.HP_rodex_getItemsAck_post > 0) {
+ void (*postHookFunc) (struct map_session_data *sd, int64 mail_id, int8 opentype, int count, const struct rodex_item *items);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_rodex_getItemsAck_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_rodex_getItemsAck_post[hIndex].func;
+ postHookFunc(sd, mail_id, opentype, count, items);
+ }
+ }
+ return;
+}
/* script_interface */
void HP_script_init(bool minimal) {
int hIndex = 0;