summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTING.md89
-rw-r--r--npc/other/Global_Functions.txt27
-rw-r--r--npc/other/auction.txt15
-rw-r--r--npc/re/quests/quests_eclage.txt2
-rw-r--r--src/char/char.c17
-rw-r--r--src/char/int_guild.c1
-rw-r--r--src/char/int_homun.c1
-rw-r--r--src/char/int_mail.c1
-rw-r--r--src/char/inter.c2
-rw-r--r--src/char/pincode.c3
-rw-r--r--src/login/account_sql.c12
-rw-r--r--src/login/login.c11
-rw-r--r--src/map/battle.c6
-rw-r--r--src/map/clif.c58
-rw-r--r--src/map/pc.c98
-rw-r--r--src/map/pc.h2
-rw-r--r--src/map/script.c19
-rw-r--r--src/map/skill.c2
-rw-r--r--src/map/status.c2
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc8
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc2
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.Hooks.inc54
22 files changed, 334 insertions, 98 deletions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 000000000..25fa4b6e4
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,89 @@
+# Contributing to Hercules
+
+Hello! Third party patches are essential to keep Hercules great. We want to
+keep it as easy as possible to contribute changes that get things working in
+your environment. There are a few guidelines that we need contributors to
+follow so that we can have a chance of keeping on top of things.
+
+## Hercules Core vs Modules
+
+Due to the nature of the project, and the wide range of different applications
+it has, we provide a plugin interface, to keep the core clean of unnecessary
+features.
+
+Generally, bugfixes and improvements to existing code, as well as the
+implementation of official Ragnarok Online features and content, should be part
+of the Hercules core, while custom functionalities should be moved to plugins,
+to avoid burdening the core with code potentially useful only to a small subset
+of users.
+
+If you are unsure of whether your contribution should be implemented as a
+module or part of Hercules Core, you may visit [#Hercules on Rizon
+IRC](http://herc.ws/board/topic/91-hercules-irc/), create an issue on GitHub,
+or drop us an email at dev@herc.ws
+
+## Getting Started
+
+* Make sure you have a [GitHub account](https://github.com/signup/free)
+* Open an issue in GitHub, if one does not already exist.
+ * Clearly describe the issue including steps to reproduce when it is a bug.
+ * Describe your configuration, following the provided template.
+* Fork the repository on GitHub
+
+## Submitting an Issue on GitHub
+
+When you open an issue, in order for it to be helpful, you should include as
+much description as possible of the issue you are observing or feature you're
+suggesting.
+
+If you're reporting an issue, you should describe your setup, and provide the
+output of `./map-server --version`.
+
+If you report a crash, make sure that you include a backtrace of the crash,
+generated with either gdb or Visual Studio (depending on your build
+environment). For the backtrace to be useful, you need to compile Hercules in
+debug mode.
+
+## Making Changes
+
+* Create a topic branch from where you want to base your work.
+ * This is usually the master branch.
+ * To quickly create a topic branch based on master; `git checkout -b
+ my_contribution master`. Please avoid working directly on the
+ `master` branch.
+* Make commits of logical units. Each commit you submit, must be atomic and
+ complete. **Each commit must do one thing, and do it well.** For separate
+ fixes, make separate commits. Even if this causes commits that only affect
+ one line of code.
+* Check for unnecessary whitespace with `git diff --check` before committing.
+* Make sure you follow our [coding style guidelines](http://TODO).
+* Make sure your commit messages are complete, describe the changes you made,
+ and in proper English language. Make sure you mention the ID of the issue
+ you fix.
+* Make sure your changes don't accidentally break anything when, for example,
+ Hercules is compiled with different settings.
+
+### Making Trivial Changes
+
+For changes of a trivial nature to comments and documentation, it is not always
+necessary to create a new issue in GitHub.
+
+## Submitting Changes
+
+* Push your changes to a topic branch in your fork of the repository.
+* Submit a pull request to the repository in the HerculesWS organization.
+* The dev team looks at Pull Requests on a weekly basis, compatibly with the
+ amount of patches in review queue and current workload.
+* After feedback has been given we expect responses within two weeks. After two
+ weeks we may close the pull request if it isn't showing any activity.
+
+## Other ways to help
+
+* You can help us diagnose and fix existing bugs by asking and providing answers for the following:
+
+ * Is the bug reproducible as explained?
+ * Is it reproducible in other environments?
+ * Are the steps to reproduce the bug clear? If not, can you describe how you might reproduce it?
+ * Is this bug something you have run into? Would you appreciate it being looked into faster?
+
+* You can close fixed bugs by testing old bugs to see if they are still happening.
diff --git a/npc/other/Global_Functions.txt b/npc/other/Global_Functions.txt
index 4e9060419..b88fa647a 100644
--- a/npc/other/Global_Functions.txt
+++ b/npc/other/Global_Functions.txt
@@ -39,10 +39,37 @@
//= 2.16 Added F_GetWeaponType, and F_GetArmorType. [L0ne_W0lf]
//= 2.17 Renamed 'F_RandMes' to 'F_Rand'. [Euphy]
//= 2.18 Removed useless 'getJobName' function. [Euphy]
+//= 2.19 Improved 'F_InsertComma' function. [Emistry]
//============================================================
//////////////////////////////////////////////////////////////////////////////////
+// Returns a number with commas based on precision of digits and custom separator.
+// -- callfunc "F_InsertComma",<number>{,<precision>,<separator>}
+// Examples:
+// callfunc("F_InsertComma",7777777{,<precision>,<separator>}) // returns "7,777,777"
+// callfunc("F_InsertComma",1000000000,3,","}) // returns "1,000,000,000"
+// callfunc("F_InsertComma",1000000000,3,"_"}) // returns "1_000_000_000"
+// callfunc("F_InsertComma",1000000000,4) // returns "10,0000,0000"
+//////////////////////////////////////////////////////////////////////////////////
+function script F_InsertComma {
+ .@value = getarg(0);
+ .@precision = getarg(1,3);
+ .@separator$ = getarg( 2,"," );
+
+ .@str$ = ""+.@value;
+ .@is_negative = ( .@value < 0 );
+
+ .@length = getstrlen( .@str$ ) - .@precision - .@is_negative;
+ while ( .@length > 0 ) {
+ .@str$ = insertchar( .@str$, .@separator$ , ( .@length + .@is_negative ) );
+ .@length -= .@precision;
+ }
+ return .@str$;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////////
// Function that clears job quest variables
//////////////////////////////////////////////////////////////////////////////////
diff --git a/npc/other/auction.txt b/npc/other/auction.txt
index eb4eb7bc4..df76daa32 100644
--- a/npc/other/auction.txt
+++ b/npc/other/auction.txt
@@ -98,11 +98,16 @@ auction_02,43,17,0 warp auction_enterance_lhz 1,1,lighthalzen,209,169
next;
if (select("Yes:No") == 1) {
mes "[Auction Broker]";
- mes "Very well.";
- mes "Please take";
- mes "a look, and see";
- mes "What's being offered~";
- openauction;
+ if ( getbattleflag( "feature.auction" ) ) {
+ mes "Very well.";
+ mes "Please take";
+ mes "a look, and see";
+ mes "What's being offered~";
+ openauction;
+ }
+ else {
+ mes "Auction feature isn't enabled.";
+ }
close;
}
mes "[Auction Broker]";
diff --git a/npc/re/quests/quests_eclage.txt b/npc/re/quests/quests_eclage.txt
index 164f66fad..4f85b42c8 100644
--- a/npc/re/quests/quests_eclage.txt
+++ b/npc/re/quests/quests_eclage.txt
@@ -18543,7 +18543,7 @@ ecl_tdun04,32,35,3 script Hisie#tlord 4_M_FARIY_HISIE,{
mes "[Hisie]";
mes "If you climbed all the way here out of curiosity, you'd better start going down now.";
mes "Professor has been under the weather nowadays.";
- close;
+ close2;
}
else if (ep14_2_mylord == 14) {
cutin "hisie01",0;
diff --git a/src/char/char.c b/src/char/char.c
index 5e3c34684..5f5dad539 100644
--- a/src/char/char.c
+++ b/src/char/char.c
@@ -850,6 +850,7 @@ int char_inventory_to_sql(const struct item items[], int max, int id) {
bool found;
int errors = 0;
+ nullpo_ret(items);
// The following code compares inventory with current database values
// and performs modification/deletion/insertion only on relevant rows.
@@ -1479,6 +1480,7 @@ bool char_char_slotchange(struct char_session_data *sd, int fd, unsigned short f
struct mmo_charstatus char_dat;
int from_id = 0;
+ nullpo_ret(sd);
if( from >= MAX_CHARS || to >= MAX_CHARS || ( sd->char_slots && to > sd->char_slots ) || sd->found_char[from] <= 0 )
return false;
@@ -1649,6 +1651,8 @@ int char_make_new_char_sql(struct char_session_data* sd, char* name_, int str, i
char esc_name[NAME_LENGTH*2+1];
int char_id, flag, k, l;
+ nullpo_retr(-2, sd);
+ nullpo_retr(-2, name_);
safestrncpy(name, name_, NAME_LENGTH);
normalize_name(name,TRIM_CHARS);
SQL->EscapeStringLen(inter->sql_handle, esc_name, name, strnlen(name, NAME_LENGTH));
@@ -4256,6 +4260,7 @@ static void char_delete2_req(int fd, struct char_session_data* sd)
time_t delete_date;
char_id = RFIFOL(fd,2);
+ nullpo_retv(sd);
ARR_FIND( 0, MAX_CHARS, i, sd->found_char[i] == char_id );
if( i == MAX_CHARS )
@@ -4327,6 +4332,7 @@ static void char_delete2_accept(int fd, struct char_session_data* sd)
char* data;
time_t delete_date;
+ nullpo_retv(sd);
char_id = RFIFOL(fd,2);
ShowInfo(CL_RED"Request Char Deletion: "CL_GREEN"%d (%d)"CL_RESET"\n", sd->account_id, char_id);
@@ -4394,6 +4400,7 @@ static void char_delete2_cancel(int fd, struct char_session_data* sd)
{// CH: <082b>.W <char id>.L
int char_id, i;
+ nullpo_retv(sd);
char_id = RFIFOL(fd,2);
ARR_FIND( 0, MAX_CHARS, i, sd->found_char[i] == char_id );
@@ -4542,6 +4549,7 @@ int char_search_default_maps_mapserver(struct mmo_charstatus *cd)
return i;
}
+void char_parse_char_select(int fd, struct char_session_data* sd, uint32 ipl) __attribute__((nonnull (2)));
void char_parse_char_select(int fd, struct char_session_data* sd, uint32 ipl)
{
struct mmo_charstatus char_dat;
@@ -4706,6 +4714,7 @@ void char_creation_ok(int fd, struct mmo_charstatus *char_dat)
WFIFOSET(fd,len);
}
+void char_parse_char_create_new_char(int fd, struct char_session_data* sd) __attribute__((nonnull (2)));
void char_parse_char_create_new_char(int fd, struct char_session_data* sd)
{
int result;
@@ -4756,6 +4765,7 @@ void char_delete_char_ok(int fd)
WFIFOSET(fd,2);
}
+void char_parse_char_delete_char(int fd, struct char_session_data* sd, unsigned short cmd) __attribute__((nonnull (2)));
void char_parse_char_delete_char(int fd, struct char_session_data* sd, unsigned short cmd)
{
char email[40];
@@ -4823,6 +4833,7 @@ void char_allow_rename(int fd, int flag)
WFIFOSET(fd,4);
}
+void char_parse_char_rename_char(int fd, struct char_session_data* sd) __attribute__((nonnull (2)));
void char_parse_char_rename_char(int fd, struct char_session_data* sd)
{
int i, cid =RFIFOL(fd,2);
@@ -4847,6 +4858,7 @@ void char_parse_char_rename_char(int fd, struct char_session_data* sd)
chr->allow_rename(fd, i);
}
+void char_parse_char_rename_char2(int fd, struct char_session_data* sd) __attribute__((nonnull (2)));
void char_parse_char_rename_char2(int fd, struct char_session_data* sd)
{
int i, aid = RFIFOL(fd,2), cid =RFIFOL(fd,6);
@@ -4882,6 +4894,7 @@ void char_rename_char_ack(int fd, int flag)
WFIFOSET(fd,4);
}
+void char_parse_char_rename_char_confirm(int fd, struct char_session_data* sd) __attribute__((nonnull (2)));
void char_parse_char_rename_char_confirm(int fd, struct char_session_data* sd)
{
int i;
@@ -4977,6 +4990,7 @@ void char_parse_char_login_map_server(int fd)
RFIFOSKIP(fd,60);
}
+void char_parse_char_pincode_check(int fd, struct char_session_data* sd) __attribute__((nonnull (2)));
void char_parse_char_pincode_check(int fd, struct char_session_data* sd)
{
if (RFIFOL(fd,2) == sd->account_id)
@@ -4985,6 +4999,7 @@ void char_parse_char_pincode_check(int fd, struct char_session_data* sd)
RFIFOSKIP(fd, 10);
}
+void char_parse_char_pincode_window(int fd, struct char_session_data* sd) __attribute__((nonnull (2)));
void char_parse_char_pincode_window(int fd, struct char_session_data* sd)
{
if (RFIFOL(fd,2) == sd->account_id)
@@ -4993,6 +5008,7 @@ void char_parse_char_pincode_window(int fd, struct char_session_data* sd)
RFIFOSKIP(fd, 6);
}
+void char_parse_char_pincode_change(int fd, struct char_session_data* sd) __attribute__((nonnull (2)));
void char_parse_char_pincode_change(int fd, struct char_session_data* sd)
{
if (RFIFOL(fd,2) == sd->account_id)
@@ -5001,6 +5017,7 @@ void char_parse_char_pincode_change(int fd, struct char_session_data* sd)
RFIFOSKIP(fd, 14);
}
+void char_parse_char_pincode_first_pin(int fd, struct char_session_data* sd) __attribute__((nonnull (2)));
void char_parse_char_pincode_first_pin(int fd, struct char_session_data* sd)
{
if (RFIFOL(fd,2) == sd->account_id)
diff --git a/src/char/int_guild.c b/src/char/int_guild.c
index 96a78203f..24561fe21 100644
--- a/src/char/int_guild.c
+++ b/src/char/int_guild.c
@@ -882,7 +882,6 @@ int inter_guild_calcinfo(struct guild *g)
int mapif_guild_created(int fd, int account_id, struct guild *g)
{
- nullpo_ret(g);
WFIFOHEAD(fd, 10);
WFIFOW(fd,0)=0x3830;
WFIFOL(fd,2)=account_id;
diff --git a/src/char/int_homun.c b/src/char/int_homun.c
index 2ec589eaf..eda2afe69 100644
--- a/src/char/int_homun.c
+++ b/src/char/int_homun.c
@@ -54,7 +54,6 @@ void mapif_homunculus_deleted(int fd, int flag)
void mapif_homunculus_loaded(int fd, int account_id, struct s_homunculus *hd)
{
- nullpo_retv(hd);
WFIFOHEAD(fd, sizeof(struct s_homunculus)+9);
WFIFOW(fd,0) = 0x3891;
WFIFOW(fd,2) = sizeof(struct s_homunculus)+9;
diff --git a/src/char/int_mail.c b/src/char/int_mail.c
index 0d46339e0..d4bfe14e4 100644
--- a/src/char/int_mail.c
+++ b/src/char/int_mail.c
@@ -459,7 +459,6 @@ void inter_mail_sendmail(int send_id, const char* send_name, int dest_id, const
nullpo_retv(dest_name);
nullpo_retv(title);
nullpo_retv(body);
- nullpo_retv(item);
memset(&msg, 0, sizeof(struct mail_message));
msg.send_id = send_id;
diff --git a/src/char/inter.c b/src/char/inter.c
index ca041d581..dbb782093 100644
--- a/src/char/inter.c
+++ b/src/char/inter.c
@@ -503,7 +503,7 @@ void mapif_parse_accinfo2(bool success, int map_fd, int u_fd, int u_aid, int acc
inter->msg_to_fd(map_fd, u_fd, u_aid, "-- Account %d --", account_id);
inter->msg_to_fd(map_fd, u_fd, u_aid, "User: %s | GM Group: %d | State: %d", userid, group_id, state);
- if (user_pass && *user_pass != '\0') { /* password is only received if your gm level is greater than the one you're searching for */
+ if (*user_pass != '\0') { /* password is only received if your gm level is greater than the one you're searching for */
if (pin_code && *pin_code != '\0')
inter->msg_to_fd(map_fd, u_fd, u_aid, "Password: %s (PIN:%s)", user_pass, pin_code);
else
diff --git a/src/char/pincode.c b/src/char/pincode.c
index 43958af8a..5085349cc 100644
--- a/src/char/pincode.c
+++ b/src/char/pincode.c
@@ -21,9 +21,10 @@
struct pincode_interface pincode_s;
void pincode_handle (int fd, struct char_session_data* sd) {
- struct online_char_data* character = (struct online_char_data*)idb_get(chr->online_char_db, sd->account_id);
+ struct online_char_data* character;
nullpo_retv(sd);
+ character = (struct online_char_data*)idb_get(chr->online_char_db, sd->account_id);
if( character && character->pincode_enable > pincode->charselect ){
character->pincode_enable = pincode->charselect * 2;
}else{
diff --git a/src/login/account_sql.c b/src/login/account_sql.c
index 3f72e6867..37837fc35 100644
--- a/src/login/account_sql.c
+++ b/src/login/account_sql.c
@@ -363,12 +363,13 @@ static bool account_db_sql_set_property(AccountDB* self, const char* key, const
static bool account_db_sql_create(AccountDB* self, struct mmo_account* acc)
{
AccountDB_SQL* db = (AccountDB_SQL*)self;
- Sql* sql_handle = db->accounts;
+ Sql* sql_handle;
// decide on the account id to assign
int account_id;
nullpo_ret(db);
nullpo_ret(acc);
+ sql_handle = db->accounts;
if( acc->account_id != -1 )
{// caller specifies it manually
account_id = acc->account_id;
@@ -416,10 +417,11 @@ static bool account_db_sql_create(AccountDB* self, struct mmo_account* acc)
static bool account_db_sql_remove(AccountDB* self, const int account_id)
{
AccountDB_SQL* db = (AccountDB_SQL*)self;
- Sql* sql_handle = db->accounts;
+ Sql* sql_handle;
bool result = false;
nullpo_ret(db);
+ sql_handle = db->accounts;
if( SQL_SUCCESS != SQL->QueryStr(sql_handle, "START TRANSACTION")
|| SQL_SUCCESS != SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = %d", db->account_db, account_id)
|| SQL_SUCCESS != SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = %d", db->global_acc_reg_num_db, account_id)
@@ -607,6 +609,7 @@ static bool mmo_auth_tosql(AccountDB_SQL* db, const struct mmo_account* acc, boo
bool result = false;
nullpo_ret(db);
+ nullpo_ret(acc);
sql_handle = db->accounts;
stmt = SQL->StmtMalloc(sql_handle);
@@ -687,11 +690,12 @@ Sql* account_db_sql_up(AccountDB* self) {
return db ? db->accounts : NULL;
}
void mmo_save_accreg2(AccountDB* self, int fd, int account_id, int char_id) {
- Sql* sql_handle = ((AccountDB_SQL*)self)->accounts;
+ Sql* sql_handle;
AccountDB_SQL* db = (AccountDB_SQL*)self;
int count = RFIFOW(fd, 12);
nullpo_retv(db);
+ sql_handle = db->accounts;
if (count) {
int cursor = 14, i;
char key[32], sval[254];
@@ -742,7 +746,7 @@ void mmo_send_accreg2(AccountDB* self, int fd, int account_id, int char_id) {
size_t len;
nullpo_retv(db);
- sql_handle = ((AccountDB_SQL*)self)->accounts;
+ sql_handle = db->accounts;
if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `key`, `index`, `value` FROM `%s` WHERE `account_id`='%d'", db->global_acc_reg_str_db, account_id) )
Sql_ShowDebug(sql_handle);
diff --git a/src/login/login.c b/src/login/login.c
index 1fdf2d198..bb8ba51b3 100644
--- a/src/login/login.c
+++ b/src/login/login.c
@@ -1230,15 +1230,15 @@ void login_kick(struct login_session_data* sd)
void login_auth_ok(struct login_session_data* sd)
{
- int fd = sd->fd;
+ int fd = 0;
uint32 ip;
-
uint8 server_num, n;
uint32 subnet_char_ip;
struct login_auth_node* node;
int i;
nullpo_retv(sd);
+ fd = sd->fd;
ip = session[fd]->client_addr;
if( runflag != LOGINSERVER_ST_RUNNING )
{
@@ -1431,11 +1431,13 @@ void login_login_error(int fd, uint8 status)
WFIFOSET(fd,23);
}
+void login_parse_ping(int fd, struct login_session_data* sd) __attribute__((nonnull (2)));
void login_parse_ping(int fd, struct login_session_data* sd)
{
RFIFOSKIP(fd,26);
}
+void login_parse_client_md5(int fd, struct login_session_data* sd) __attribute__((nonnull (2)));
void login_parse_client_md5(int fd, struct login_session_data* sd)
{
sd->has_client_hash = 1;
@@ -1444,6 +1446,7 @@ void login_parse_client_md5(int fd, struct login_session_data* sd)
RFIFOSKIP(fd,18);
}
+bool login_parse_client_login(int fd, struct login_session_data* sd, const char *const ip) __attribute__((nonnull (2)));
bool login_parse_client_login(int fd, struct login_session_data* sd, const char *const ip)
{
uint32 version;
@@ -1523,6 +1526,7 @@ bool login_parse_client_login(int fd, struct login_session_data* sd, const char
return false;
}
+void login_send_coding_key(int fd, struct login_session_data* sd) __attribute__((nonnull (2)));
void login_send_coding_key(int fd, struct login_session_data* sd)
{
WFIFOHEAD(fd,4 + sd->md5keylen);
@@ -1532,6 +1536,7 @@ void login_send_coding_key(int fd, struct login_session_data* sd)
WFIFOSET(fd,WFIFOW(fd,2));
}
+void login_parse_request_coding_key(int fd, struct login_session_data* sd) __attribute__((nonnull (2)));
void login_parse_request_coding_key(int fd, struct login_session_data* sd)
{
memset(sd->md5key, '\0', sizeof(sd->md5key));
@@ -1541,6 +1546,7 @@ void login_parse_request_coding_key(int fd, struct login_session_data* sd)
login->send_coding_key(fd, sd);
}
+void login_char_server_connection_status(int fd, struct login_session_data* sd, uint8 status) __attribute__((nonnull (2)));
void login_char_server_connection_status(int fd, struct login_session_data* sd, uint8 status)
{
WFIFOHEAD(fd,3);
@@ -1549,6 +1555,7 @@ void login_char_server_connection_status(int fd, struct login_session_data* sd,
WFIFOSET(fd,3);
}
+void login_parse_request_connection(int fd, struct login_session_data* sd, const char *const ip) __attribute__((nonnull (2, 3)));
void login_parse_request_connection(int fd, struct login_session_data* sd, const char *const ip)
{
char server_name[20];
diff --git a/src/map/battle.c b/src/map/battle.c
index 8a834574b..3575dea6f 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -3627,7 +3627,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
}
}
#ifndef HMAP_ZONE_DAMAGE_CAP_TYPE
- if( target && skill_id ) {
+ if (skill_id) {
for(i = 0; i < map->list[target->m].zone->capped_skills_count; i++) {
if( skill_id == map->list[target->m].zone->capped_skills[i]->nameid && (map->list[target->m].zone->capped_skills[i]->type & target->type) ) {
if( target->type == BL_MOB && map->list[target->m].zone->capped_skills[i]->subtype != MZS_NONE ) {
@@ -4101,7 +4101,7 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
}
}
#ifndef HMAP_ZONE_DAMAGE_CAP_TYPE
- if( target && skill_id ) {
+ if (skill_id) {
for(i = 0; i < map->list[target->m].zone->capped_skills_count; i++) {
if( skill_id == map->list[target->m].zone->capped_skills[i]->nameid && (map->list[target->m].zone->capped_skills[i]->type & target->type) ) {
if( target->type == BL_MOB && map->list[target->m].zone->capped_skills[i]->subtype != MZS_NONE ) {
@@ -5314,7 +5314,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
if(skill_id == CR_GRANDCROSS || skill_id == NPC_GRANDDARKNESS)
return wd; //Enough, rest is not needed.
#ifndef HMAP_ZONE_DAMAGE_CAP_TYPE
- if( target && skill_id ) {
+ if (skill_id) {
for(i = 0; i < map->list[target->m].zone->capped_skills_count; i++) {
if( skill_id == map->list[target->m].zone->capped_skills[i]->nameid && (map->list[target->m].zone->capped_skills[i]->type & target->type) ) {
if( target->type == BL_MOB && map->list[target->m].zone->capped_skills[i]->subtype != MZS_NONE ) {
diff --git a/src/map/clif.c b/src/map/clif.c
index f01b59fda..cc517c24f 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -5715,54 +5715,30 @@ void clif_solved_charname(int fd, int charid, const char* name)
/// 017b <packet len>.W { <name id>.W }*
void clif_use_card(struct map_session_data *sd,int idx)
{
- int i,c,ep;
- int fd=sd->fd;
+ int i, c;
+ int fd;
nullpo_retv(sd);
- if (idx < 0 || idx >= MAX_INVENTORY) //Crash-fix from bad packets.
+ fd = sd->fd;
+ if (sd->state.trading != 0)
+ return;
+ if (!pc->can_insert_card(sd, idx))
return;
- if (!sd->inventory_data[idx] || sd->inventory_data[idx]->type != IT_CARD)
- return; //Avoid parsing invalid item indexes (no card/no item)
-
- ep=sd->inventory_data[idx]->equip;
- WFIFOHEAD(fd,MAX_INVENTORY * 2 + 4);
- WFIFOW(fd,0)=0x17b;
-
- for(i=c=0;i<MAX_INVENTORY;i++){
- int j;
-
- if(sd->inventory_data[i] == NULL)
- continue;
- if(sd->inventory_data[i]->type!=IT_WEAPON && sd->inventory_data[i]->type!=IT_ARMOR)
- continue;
- if(itemdb_isspecial(sd->status.inventory[i].card[0])) //Can't slot it
- continue;
-
- if (sd->status.inventory[i].identify == 0) //Not identified
- continue;
-
- if ((sd->inventory_data[i]->equip&ep) == 0) //Not equippable on this part.
- continue;
-
- if(sd->inventory_data[i]->type==IT_WEAPON && ep==EQP_SHIELD) //Shield card won't go on left weapon.
- continue;
-
- ARR_FIND( 0, sd->inventory_data[i]->slot, j, sd->status.inventory[i].card[j] == 0 );
- if (j == sd->inventory_data[i]->slot) // No room
- continue;
+ WFIFOHEAD(fd, MAX_INVENTORY * 2 + 4);
+ WFIFOW(fd, 0) = 0x17b;
- if( sd->status.inventory[i].equip > 0 ) // Do not check items that are already equipped
+ for (i = c = 0; i < MAX_INVENTORY; i++) {
+ if (!pc->can_insert_card_into(sd, idx, i))
continue;
-
- WFIFOW(fd,4+c*2)=i+2;
+ WFIFOW(fd, 4 + c * 2) = i + 2;
c++;
}
- if( !c ) return; // no item is available for card insertion
+ if (!c) return; // no item is available for card insertion
- WFIFOW(fd,2)=4+c*2;
- WFIFOSET(fd,WFIFOW(fd,2));
+ WFIFOW(fd, 2) = 4 + c * 2;
+ WFIFOSET(fd, WFIFOW(fd, 2));
}
@@ -11394,8 +11370,6 @@ void clif_parse_AutoSpell(int fd,struct map_session_data *sd)
/// 017a <card index>.W
void clif_parse_UseCard(int fd,struct map_session_data *sd)
{
- if (sd->state.trading != 0)
- return;
clif->use_card(sd,RFIFOW(fd,2)-2);
}
@@ -11404,8 +11378,6 @@ void clif_parse_UseCard(int fd,struct map_session_data *sd)
/// 017c <card index>.W <equip index>.W
void clif_parse_InsertCard(int fd,struct map_session_data *sd)
{
- if (sd->state.trading != 0)
- return;
pc->insert_card(sd,RFIFOW(fd,2)-2,RFIFOW(fd,4)-2);
}
@@ -12746,7 +12718,7 @@ bool clif_sub_guild_invite(int fd, struct map_session_data *sd, struct map_sessi
return false;
}
- if ( t_sd && t_sd->state.noask ) {// @noask [LuzZza]
+ if (t_sd->state.noask) {// @noask [LuzZza]
clif->noask_sub(sd, t_sd, 2);
return false;
}
diff --git a/src/map/pc.c b/src/map/pc.c
index 4dac559e2..b9ef479dc 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -4059,42 +4059,78 @@ int pc_skill(TBL_PC* sd, int id, int level, int flag)
}
return 1;
}
+
+/**
+ * Checks if the given card can be inserted into the given equipment piece.
+ *
+ * @param sd The current character.
+ * @param idx_card The card's inventory index (note: it must be a valid index and can be checked by pc_can_insert_card)
+ * @param idx_equip The target equipment's inventory index.
+ * @retval true if the card can be inserted.
+ */
+bool pc_can_insert_card_into(struct map_session_data* sd, int idx_card, int idx_equip)
+{
+ int i;
+
+ nullpo_ret(sd);
+
+ if (idx_equip < 0 || idx_equip >= MAX_INVENTORY || sd->inventory_data[idx_equip] == NULL)
+ return false; //Invalid item index.
+ if (sd->status.inventory[idx_equip].nameid <= 0 || sd->status.inventory[idx_equip].amount < 1)
+ return false; // target item missing
+ if (sd->inventory_data[idx_equip]->type != IT_WEAPON && sd->inventory_data[idx_equip]->type != IT_ARMOR)
+ return false; // only weapons and armor are allowed
+ if (sd->status.inventory[idx_equip].identify == 0)
+ return false; // target must be identified
+ if (itemdb_isspecial(sd->status.inventory[idx_equip].card[0]))
+ return false; // card slots reserved for other purposes
+ if (sd->status.inventory[idx_equip].equip != 0)
+ return false; // item must be unequipped
+ if ((sd->inventory_data[idx_equip]->equip & sd->inventory_data[idx_card]->equip) == 0)
+ return false; // card cannot be compounded on this item type
+ if (sd->inventory_data[idx_equip]->type == IT_WEAPON && sd->inventory_data[idx_card]->equip == EQP_SHIELD)
+ return false; // attempted to place shield card on left-hand weapon.
+
+ ARR_FIND( 0, sd->inventory_data[idx_equip]->slot, i, sd->status.inventory[idx_equip].card[i] == 0);
+ if (i == sd->inventory_data[idx_equip]->slot)
+ return false; // no free slots
+ return true;
+}
+
+/**
+ * Checks if the given item is card and it can be inserted into some equipment.
+ *
+ * @param sd The current character.
+ * @param idx_card The card's inventory index.
+ * @retval true if the card can be inserted.
+ */
+bool pc_can_insert_card(struct map_session_data* sd, int idx_card)
+{
+ nullpo_ret(sd);
+
+ if (idx_card < 0 || idx_card >= MAX_INVENTORY || sd->inventory_data[idx_card] == NULL)
+ return false; //Invalid card index.
+ if (sd->status.inventory[idx_card].nameid <= 0 || sd->status.inventory[idx_card].amount < 1)
+ return false; // target card missing
+ if (sd->inventory_data[idx_card]->type != IT_CARD)
+ return false; // must be a card
+ return true;
+}
+
/*==========================================
* Append a card to an item ?
*------------------------------------------*/
int pc_insert_card(struct map_session_data* sd, int idx_card, int idx_equip)
{
- int i;
int nameid;
nullpo_ret(sd);
- if( idx_equip < 0 || idx_equip >= MAX_INVENTORY || sd->inventory_data[idx_equip] == NULL )
- return 0; //Invalid item index.
- if( idx_card < 0 || idx_card >= MAX_INVENTORY || sd->inventory_data[idx_card] == NULL )
- return 0; //Invalid card index.
- if( sd->status.inventory[idx_equip].nameid <= 0 || sd->status.inventory[idx_equip].amount < 1 )
- return 0; // target item missing
- if( sd->status.inventory[idx_card].nameid <= 0 || sd->status.inventory[idx_card].amount < 1 )
- return 0; // target card missing
- if( sd->inventory_data[idx_equip]->type != IT_WEAPON && sd->inventory_data[idx_equip]->type != IT_ARMOR )
- return 0; // only weapons and armor are allowed
- if( sd->inventory_data[idx_card]->type != IT_CARD )
- return 0; // must be a card
- if( sd->status.inventory[idx_equip].identify == 0 )
- return 0; // target must be identified
- if( itemdb_isspecial(sd->status.inventory[idx_equip].card[0]) )
- return 0; // card slots reserved for other purposes
- if( (sd->inventory_data[idx_equip]->equip & sd->inventory_data[idx_card]->equip) == 0 )
- return 0; // card cannot be compounded on this item type
- if( sd->inventory_data[idx_equip]->type == IT_WEAPON && sd->inventory_data[idx_card]->equip == EQP_SHIELD )
- return 0; // attempted to place shield card on left-hand weapon.
- if( sd->status.inventory[idx_equip].equip != 0 )
- return 0; // item must be unequipped
-
- ARR_FIND( 0, sd->inventory_data[idx_equip]->slot, i, sd->status.inventory[idx_equip].card[i] == 0 );
- if( i == sd->inventory_data[idx_equip]->slot )
- return 0; // no free slots
+ if (sd->state.trading != 0)
+ return 0;
+
+ if (!pc->can_insert_card(sd, idx_card) || !pc->can_insert_card_into(sd, idx_card, idx_equip))
+ return 0;
// remember the card id to insert
nameid = sd->status.inventory[idx_card].nameid;
@@ -4105,6 +4141,10 @@ int pc_insert_card(struct map_session_data* sd, int idx_card, int idx_equip)
}
else
{// success
+ int i;
+ ARR_FIND( 0, sd->inventory_data[idx_equip]->slot, i, sd->status.inventory[idx_equip].card[i] == 0);
+ if (i == sd->inventory_data[idx_equip]->slot)
+ return 0; // no free slots
logs->pick_pc(sd, LOG_TYPE_OTHER, -1, &sd->status.inventory[idx_equip],sd->inventory_data[idx_equip]);
sd->status.inventory[idx_equip].card[i] = nameid;
logs->pick_pc(sd, LOG_TYPE_OTHER, 1, &sd->status.inventory[idx_equip],sd->inventory_data[idx_equip]);
@@ -11497,7 +11537,9 @@ void pc_defaults(void) {
pc->skill = pc_skill;
pc->insert_card = pc_insert_card;
-
+ pc->can_insert_card = pc_can_insert_card;
+ pc->can_insert_card_into = pc_can_insert_card_into;
+
pc->steal_item = pc_steal_item;
pc->steal_coin = pc_steal_coin;
diff --git a/src/map/pc.h b/src/map/pc.h
index 4dea27693..c370f9956 100644
--- a/src/map/pc.h
+++ b/src/map/pc.h
@@ -880,6 +880,8 @@ END_ZEROED_BLOCK; /* End */
int (*skill) (struct map_session_data *sd, int id, int level, int flag);
int (*insert_card) (struct map_session_data *sd,int idx_card,int idx_equip);
+ bool (*can_insert_card) (struct map_session_data* sd, int idx_card);
+ bool (*can_insert_card_into) (struct map_session_data* sd, int idx_card, int idx_equip);
int (*steal_item) (struct map_session_data *sd,struct block_list *bl, uint16 skill_lv);
int (*steal_coin) (struct map_session_data *sd,struct block_list *bl);
diff --git a/src/map/script.c b/src/map/script.c
index f2fce3a8f..30af4d0f7 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -17177,18 +17177,27 @@ BUILDIN(changequest) {
BUILDIN(questactive) {
struct map_session_data *sd = script->rid2sd(st);
- int quest_progress = 0;
+ int qid, i;
- if (sd == NULL)
+ if (sd == NULL) {
+ ShowError("questactive: no player attached!");
return false;
+ }
+
+ qid = script_getnum(st, 2);
+
+ ARR_FIND(0, sd->avail_quests, i, sd->quest_log[i].quest_id == qid );
- if (quest->check(sd, script_getnum(st, 2), HAVEQUEST) == Q_ACTIVE)
+ if( i >= sd->avail_quests ) {
+ script_pushint(st, 0);
+ return true;
+ }
+
+ if(sd->quest_log[i].state == Q_ACTIVE)
script_pushint(st, 1);
else
script_pushint(st, 0);
- script_pushint(st, quest_progress);
-
return true;
}
diff --git a/src/map/skill.c b/src/map/skill.c
index 13cdeede3..3a69bf380 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -2714,7 +2714,7 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr
}
/* monsters with skill lv higher than MAX_SKILL_LEVEL may get this value beyond the max depending on conditions, we cap to the system's limit */
- if( dsrc && dsrc->type == BL_MOB && skill_lv > MAX_SKILL_LEVEL && dmg.blewcount > 25 )
+ if (dsrc->type == BL_MOB && skill_lv > MAX_SKILL_LEVEL && dmg.blewcount > 25)
dmg.blewcount = 25;
//blown-specific handling
diff --git a/src/map/status.c b/src/map/status.c
index dc4813055..d88bcf146 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -5145,7 +5145,7 @@ signed short status_calc_mdef2(struct block_list *bl, struct status_change *sc,
if(sc->data[SC_MINDBREAKER])
mdef2 -= mdef2 * sc->data[SC_MINDBREAKER]->val3/100;
#ifdef RENEWAL
- if(sc && sc->data[SC_ASSUMPTIO])
+ if (sc->data[SC_ASSUMPTIO])
mdef2 <<= 1;
return (short)cap_value(mdef2,SHRT_MIN,SHRT_MAX);
#else
diff --git a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
index e35a4c81c..f3e3711c1 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
@@ -3697,6 +3697,10 @@ struct {
struct HPMHookPoint *HP_pc_skill_post;
struct HPMHookPoint *HP_pc_insert_card_pre;
struct HPMHookPoint *HP_pc_insert_card_post;
+ struct HPMHookPoint *HP_pc_can_insert_card_pre;
+ struct HPMHookPoint *HP_pc_can_insert_card_post;
+ struct HPMHookPoint *HP_pc_can_insert_card_into_pre;
+ struct HPMHookPoint *HP_pc_can_insert_card_into_post;
struct HPMHookPoint *HP_pc_steal_item_pre;
struct HPMHookPoint *HP_pc_steal_item_post;
struct HPMHookPoint *HP_pc_steal_coin_pre;
@@ -8912,6 +8916,10 @@ struct {
int HP_pc_skill_post;
int HP_pc_insert_card_pre;
int HP_pc_insert_card_post;
+ int HP_pc_can_insert_card_pre;
+ int HP_pc_can_insert_card_post;
+ int HP_pc_can_insert_card_into_pre;
+ int HP_pc_can_insert_card_into_post;
int HP_pc_steal_item_pre;
int HP_pc_steal_item_post;
int HP_pc_steal_coin_pre;
diff --git a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
index 6501c0943..4e23425ec 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
@@ -1880,6 +1880,8 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(pc->bonus5, HP_pc_bonus5) },
{ HP_POP(pc->skill, HP_pc_skill) },
{ HP_POP(pc->insert_card, HP_pc_insert_card) },
+ { HP_POP(pc->can_insert_card, HP_pc_can_insert_card) },
+ { HP_POP(pc->can_insert_card_into, HP_pc_can_insert_card_into) },
{ HP_POP(pc->steal_item, HP_pc_steal_item) },
{ HP_POP(pc->steal_coin, HP_pc_steal_coin) },
{ HP_POP(pc->modifybuyvalue, HP_pc_modifybuyvalue) },
diff --git a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
index 04f31aea5..85f477bec 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
@@ -49461,6 +49461,60 @@ int HP_pc_insert_card(struct map_session_data *sd, int idx_card, int idx_equip)
}
return retVal___;
}
+bool HP_pc_can_insert_card(struct map_session_data *sd, int idx_card) {
+ int hIndex = 0;
+ bool retVal___ = false;
+ if( HPMHooks.count.HP_pc_can_insert_card_pre ) {
+ bool (*preHookFunc) (struct map_session_data *sd, int *idx_card);
+ *HPMforce_return = false;
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_can_insert_card_pre; hIndex++ ) {
+ preHookFunc = HPMHooks.list.HP_pc_can_insert_card_pre[hIndex].func;
+ retVal___ = preHookFunc(sd, &idx_card);
+ }
+ if( *HPMforce_return ) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.pc.can_insert_card(sd, idx_card);
+ }
+ if( HPMHooks.count.HP_pc_can_insert_card_post ) {
+ bool (*postHookFunc) (bool retVal___, struct map_session_data *sd, int *idx_card);
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_can_insert_card_post; hIndex++ ) {
+ postHookFunc = HPMHooks.list.HP_pc_can_insert_card_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, sd, &idx_card);
+ }
+ }
+ return retVal___;
+}
+bool HP_pc_can_insert_card_into(struct map_session_data *sd, int idx_card, int idx_equip) {
+ int hIndex = 0;
+ bool retVal___ = false;
+ if( HPMHooks.count.HP_pc_can_insert_card_into_pre ) {
+ bool (*preHookFunc) (struct map_session_data *sd, int *idx_card, int *idx_equip);
+ *HPMforce_return = false;
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_can_insert_card_into_pre; hIndex++ ) {
+ preHookFunc = HPMHooks.list.HP_pc_can_insert_card_into_pre[hIndex].func;
+ retVal___ = preHookFunc(sd, &idx_card, &idx_equip);
+ }
+ if( *HPMforce_return ) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.pc.can_insert_card_into(sd, idx_card, idx_equip);
+ }
+ if( HPMHooks.count.HP_pc_can_insert_card_into_post ) {
+ bool (*postHookFunc) (bool retVal___, struct map_session_data *sd, int *idx_card, int *idx_equip);
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_can_insert_card_into_post; hIndex++ ) {
+ postHookFunc = HPMHooks.list.HP_pc_can_insert_card_into_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, sd, &idx_card, &idx_equip);
+ }
+ }
+ return retVal___;
+}
int HP_pc_steal_item(struct map_session_data *sd, struct block_list *bl, uint16 skill_lv) {
int hIndex = 0;
int retVal___ = 0;