summaryrefslogtreecommitdiff
path: root/src/map
diff options
context:
space:
mode:
Diffstat (limited to 'src/map')
-rw-r--r--src/map/HPMmap.c124
-rw-r--r--src/map/HPMmap.h6
-rw-r--r--src/map/Makefile.in12
-rw-r--r--src/map/atcommand.c286
-rw-r--r--src/map/atcommand.h9
-rw-r--r--src/map/battle.c631
-rw-r--r--src/map/battle.h26
-rw-r--r--src/map/battleground.c81
-rw-r--r--src/map/battleground.h15
-rw-r--r--src/map/buyingstore.c28
-rw-r--r--src/map/buyingstore.h4
-rw-r--r--src/map/channel.c61
-rw-r--r--src/map/channel.h11
-rw-r--r--src/map/chat.c38
-rw-r--r--src/map/chat.h6
-rw-r--r--src/map/chrif.c136
-rw-r--r--src/map/chrif.h12
-rw-r--r--src/map/clif.c811
-rw-r--r--src/map/clif.h130
-rw-r--r--src/map/date.c4
-rw-r--r--src/map/date.h2
-rw-r--r--src/map/duel.c10
-rw-r--r--src/map/duel.h2
-rw-r--r--src/map/elemental.c70
-rw-r--r--src/map/elemental.h9
-rw-r--r--src/map/guild.c80
-rw-r--r--src/map/guild.h8
-rw-r--r--src/map/homunculus.c148
-rw-r--r--src/map/homunculus.h17
-rw-r--r--src/map/instance.c37
-rw-r--r--src/map/instance.h7
-rw-r--r--src/map/intif.c56
-rw-r--r--src/map/intif.h2
-rw-r--r--src/map/irc-bot.c24
-rw-r--r--src/map/irc-bot.h4
-rw-r--r--src/map/itemdb.c102
-rw-r--r--src/map/itemdb.h131
-rw-r--r--src/map/log.c24
-rw-r--r--src/map/log.h4
-rw-r--r--src/map/mail.c21
-rw-r--r--src/map/mail.h2
-rw-r--r--src/map/map.c112
-rw-r--r--src/map/map.h46
-rw-r--r--src/map/mapreg.h8
-rw-r--r--src/map/mapreg_sql.c22
-rw-r--r--src/map/mercenary.c66
-rw-r--r--src/map/mercenary.h10
-rw-r--r--src/map/mob.c108
-rw-r--r--src/map/mob.h43
-rw-r--r--src/map/npc.c142
-rw-r--r--src/map/npc.h14
-rw-r--r--src/map/npc_chat.c22
-rw-r--r--src/map/packets.h74
-rw-r--r--src/map/packets_struct.h18
-rw-r--r--src/map/party.c50
-rw-r--r--src/map/party.h10
-rw-r--r--src/map/path.c20
-rw-r--r--src/map/path.h4
-rw-r--r--src/map/pc.c1399
-rw-r--r--src/map/pc.h120
-rw-r--r--src/map/pc_groups.c22
-rw-r--r--src/map/pc_groups.h6
-rw-r--r--src/map/pet.c80
-rw-r--r--src/map/pet.h10
-rw-r--r--src/map/quest.c50
-rw-r--r--src/map/quest.h8
-rw-r--r--src/map/script.c443
-rw-r--r--src/map/script.h15
-rw-r--r--src/map/searchstore.c18
-rw-r--r--src/map/searchstore.h8
-rw-r--r--src/map/skill.c1220
-rw-r--r--src/map/skill.h39
-rw-r--r--src/map/status.c1519
-rw-r--r--src/map/status.h96
-rw-r--r--src/map/storage.c68
-rw-r--r--src/map/storage.h13
-rw-r--r--src/map/trade.c42
-rw-r--r--src/map/unit.c159
-rw-r--r--src/map/unit.h21
-rw-r--r--src/map/vending.c32
-rw-r--r--src/map/vending.h4
81 files changed, 5318 insertions, 4034 deletions
diff --git a/src/map/HPMmap.c b/src/map/HPMmap.c
index 3da49c3b9..7600d3d0c 100644
--- a/src/map/HPMmap.c
+++ b/src/map/HPMmap.c
@@ -5,63 +5,73 @@
#include "HPMmap.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
+#include "common/HPM.h"
+#include "common/cbasetypes.h"
+
+#include "common/HPMi.h"
+#include "common/conf.h"
+#include "common/console.h"
+#include "common/core.h"
+#include "common/db.h"
+#include "common/des.h"
+#include "common/ers.h"
+#include "common/malloc.h"
+#include "common/mapindex.h"
+#include "common/mmo.h"
+#include "common/nullpo.h"
+#include "common/showmsg.h"
+#include "common/socket.h"
+#include "common/spinlock.h"
+#include "common/sql.h"
+#include "common/strlib.h"
+#include "common/sysinfo.h"
+#include "common/timer.h"
+#include "common/utils.h"
+#include "map/atcommand.h"
+#include "map/battle.h"
+#include "map/battleground.h"
+#include "map/buyingstore.h"
+#include "map/channel.h"
+#include "map/chat.h"
+#include "map/chrif.h"
+#include "map/clif.h"
+#include "map/date.h"
+#include "map/duel.h"
+#include "map/elemental.h"
+#include "map/guild.h"
+#include "map/homunculus.h"
+#include "map/instance.h"
+#include "map/intif.h"
+#include "map/irc-bot.h"
+#include "map/itemdb.h"
+#include "map/log.h"
+#include "map/mail.h"
+#include "map/map.h"
+#include "map/mapreg.h"
+#include "map/mercenary.h"
+#include "map/mob.h"
+#include "map/npc.h"
+#include "map/packets_struct.h"
+#include "map/party.h"
+#include "map/path.h"
+#include "map/pc.h"
+#include "map/pc_groups.h"
+#include "map/pet.h"
+#include "map/quest.h"
+#include "map/script.h"
+#include "map/searchstore.h"
+#include "map/skill.h"
+#include "map/status.h"
+#include "map/storage.h"
+#include "map/trade.h"
+#include "map/unit.h"
+#include "map/vending.h"
-#include "atcommand.h"
-#include "battle.h"
-#include "battleground.h"
-#include "channel.h"
-#include "chat.h"
-#include "chrif.h"
-#include "clif.h"
-#include "date.h"
-#include "duel.h"
-#include "elemental.h"
-#include "guild.h"
-#include "homunculus.h"
-#include "instance.h"
-#include "intif.h"
-#include "irc-bot.h"
-#include "itemdb.h"
-#include "log.h"
-#include "mail.h"
-#include "map.h"
-#include "mapreg.h"
-#include "mercenary.h"
-#include "mob.h"
-#include "npc.h"
-#include "party.h"
-#include "path.h"
-#include "pc.h"
-#include "pc_groups.h"
-#include "pet.h"
-#include "quest.h"
-#include "script.h"
-#include "searchstore.h"
-#include "skill.h"
-#include "status.h"
-#include "storage.h"
-#include "trade.h"
-#include "unit.h"
-#include "vending.h"
-#include "../common/HPM.h"
-#include "../common/cbasetypes.h"
-#include "../common/conf.h"
-#include "../common/db.h"
-#include "../common/des.h"
-#include "../common/ers.h"
-#include "../common/malloc.h"
-#include "../common/mapindex.h"
-#include "../common/mmo.h"
-#include "../common/showmsg.h"
-#include "../common/socket.h"
-#include "../common/strlib.h"
-#include "../common/sysinfo.h"
+// HPMDataCheck comes after all the other includes
+#include "common/HPMDataCheck.h"
-#include "../common/HPMDataCheck.h"
+#include <stdio.h>
+#include <stdlib.h>
struct HPM_atcommand_list {
//tracking currently not enabled
@@ -114,6 +124,10 @@ bool HPM_map_grabHPData(struct HPDataOperationStorage *ret, enum HPluginDataType
ret->HPDataSRCPtr = (void**)(&((struct item_data *)ptr)->hdata);
ret->hdatac = &((struct item_data *)ptr)->hdatac;
break;
+ case HPDT_BGDATA:
+ ret->HPDataSRCPtr = (void**)(&((struct battleground_data *)ptr)->hdata);
+ ret->hdatac = &((struct battleground_data *)ptr)->hdatac;
+ break;
default:
return false;
}
diff --git a/src/map/HPMmap.h b/src/map/HPMmap.h
index 0c727d017..00a8f43c3 100644
--- a/src/map/HPMmap.h
+++ b/src/map/HPMmap.h
@@ -8,9 +8,9 @@
#error You should never include HPMmap.h from a plugin.
#endif
-#include "../common/cbasetypes.h"
-#include "../map/atcommand.h"
-#include "../common/HPM.h"
+#include "map/atcommand.h"
+#include "common/cbasetypes.h"
+#include "common/HPM.h"
struct hplugin;
struct map_session_data;
diff --git a/src/map/Makefile.in b/src/map/Makefile.in
index 90bb55694..ac1b4d837 100644
--- a/src/map/Makefile.in
+++ b/src/map/Makefile.in
@@ -9,18 +9,20 @@ CONFIG_H = $(wildcard $(CONFIG_D)/*.h) $(wildcard $(CONFIG_D)/*/*.h)
COMMON_D = ../common
COMMON_H = $(wildcard $(COMMON_D)/*.h)
SYSINFO_INC = $(COMMON_D)/sysinfo.inc
+COMMON_INCLUDE = -I..
-LIBCONFIG_D = ../../3rdparty/libconfig
+THIRDPARTY_D = ../../3rdparty
+THIRDPARTY_INCLUDE = -I$(THIRDPARTY_D)
+
+LIBCONFIG_D = $(THIRDPARTY_D)/libconfig
LIBCONFIG_OBJ = $(addprefix $(LIBCONFIG_D)/, libconfig.o grammar.o scanctx.o \
scanner.o strbuf.o)
LIBCONFIG_H = $(addprefix $(LIBCONFIG_D)/, libconfig.h grammar.h parsectx.h \
scanctx.h scanner.h strbuf.h wincompat.h)
-LIBCONFIG_INCLUDE = -I$(LIBCONFIG_D)
-MT19937AR_D = ../../3rdparty/mt19937ar
+MT19937AR_D = $(THIRDPARTY_D)/mt19937ar
MT19937AR_OBJ = $(MT19937AR_D)/mt19937ar.o
MT19937AR_H = $(MT19937AR_D)/mt19937ar.h
-MT19937AR_INCLUDE = -I$(MT19937AR_D)
MAP_C = atcommand.c battle.c battleground.c buyingstore.c channel.c chat.c \
chrif.c clif.c date.c duel.c elemental.c guild.c homunculus.c HPMmap.c \
@@ -111,7 +113,7 @@ map-server: ../../map-server@EXEEXT@
obj_sql/%.o: %.c $(MAP_H) $(COMMON_H) $(CONFIG_H) $(MT19937AR_H) $(LIBCONFIG_H) | obj_sql
@echo " CC $<"
- @$(CC) @CFLAGS@ @DEFS@ $(MT19937AR_INCLUDE) $(LIBCONFIG_INCLUDE) $(PCRE_CFLAGS) @MYSQL_CFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
+ @$(CC) @CFLAGS@ @DEFS@ $(COMMON_INCLUDE) $(THIRDPARTY_INCLUDE) $(PCRE_CFLAGS) @MYSQL_CFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
# missing object files
$(COMMON_D)/obj_all/common.a:
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index 560848c5b..fb0b89381 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -4,59 +4,59 @@
#define HERCULES_CORE
-#include "../config/core.h" // AUTOLOOTITEM_SIZE, AUTOTRADE_PERSISTENCY, MAX_SUGGESTIONS, MOB_FLEE(), MOB_HIT(), RENEWAL, RENEWAL_DROP, RENEWAL_EXP
+#include "config/core.h" // AUTOLOOTITEM_SIZE, AUTOTRADE_PERSISTENCY, MAX_SUGGESTIONS, MOB_FLEE(), MOB_HIT(), RENEWAL, RENEWAL_DROP, RENEWAL_EXP
#include "atcommand.h"
+#include "map/HPMmap.h"
+#include "map/battle.h"
+#include "map/channel.h"
+#include "map/chat.h"
+#include "map/chrif.h"
+#include "map/clif.h"
+#include "map/duel.h"
+#include "map/elemental.h"
+#include "map/guild.h"
+#include "map/homunculus.h"
+#include "map/intif.h"
+#include "map/itemdb.h"
+#include "map/log.h"
+#include "map/mail.h"
+#include "map/map.h"
+#include "map/mapreg.h"
+#include "map/mercenary.h"
+#include "map/mob.h"
+#include "map/npc.h"
+#include "map/party.h"
+#include "map/pc.h"
+#include "map/pc_groups.h" // groupid2name
+#include "map/pet.h"
+#include "map/quest.h"
+#include "map/script.h"
+#include "map/searchstore.h"
+#include "map/skill.h"
+#include "map/status.h"
+#include "map/storage.h"
+#include "map/trade.h"
+#include "map/unit.h"
+#include "common/cbasetypes.h"
+#include "common/conf.h"
+#include "common/core.h"
+#include "common/malloc.h"
+#include "common/mmo.h" // MAX_CARTS
+#include "common/nullpo.h"
+#include "common/random.h"
+#include "common/showmsg.h"
+#include "common/socket.h"
+#include "common/strlib.h"
+#include "common/sysinfo.h"
+#include "common/timer.h"
+#include "common/utils.h"
+
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include "HPMmap.h"
-#include "battle.h"
-#include "channel.h"
-#include "chat.h"
-#include "chrif.h"
-#include "clif.h"
-#include "duel.h"
-#include "elemental.h"
-#include "guild.h"
-#include "homunculus.h"
-#include "intif.h"
-#include "itemdb.h"
-#include "log.h"
-#include "mail.h"
-#include "map.h"
-#include "mapreg.h"
-#include "mercenary.h"
-#include "mob.h"
-#include "npc.h"
-#include "party.h"
-#include "pc.h"
-#include "pc_groups.h" // groupid2name
-#include "pet.h"
-#include "quest.h"
-#include "script.h"
-#include "searchstore.h"
-#include "skill.h"
-#include "status.h"
-#include "storage.h"
-#include "trade.h"
-#include "unit.h"
-#include "../common/cbasetypes.h"
-#include "../common/conf.h"
-#include "../common/core.h"
-#include "../common/malloc.h"
-#include "../common/mmo.h" // MAX_CARTS
-#include "../common/nullpo.h"
-#include "../common/random.h"
-#include "../common/showmsg.h"
-#include "../common/socket.h"
-#include "../common/strlib.h"
-#include "../common/sysinfo.h"
-#include "../common/timer.h"
-#include "../common/utils.h"
-
struct atcommand_interface atcommand_s;
static char atcmd_output[CHAT_SIZE_MAX];
@@ -209,9 +209,10 @@ ACMD(send)
long num;
// read message type as hex number (without the 0x)
- if(!message || !*message ||
- !((sscanf(message, "len %x", &type)==1 && (len=1))
- || sscanf(message, "%x", &type)==1) ) {
+ if (!message || !*message
+ || !((sscanf(message, "len %x", &type)==1 && (len=1))
+ || sscanf(message, "%x", &type)==1)
+ ) {
clif->message(fd, msg_fd(fd,900)); // Usage:
clif->message(fd, msg_fd(fd,901)); // @send len <packet hex number>
clif->message(fd, msg_fd(fd,902)); // @send <packet hex number> {<value>}*
@@ -663,7 +664,7 @@ ACMD(who) {
break;
}
}
- clif->colormes(fd, COLOR_DEFAULT, StrBuf->Value(&buf));/** for whatever reason clif->message crashes with some patterns, see bugreport:8186 **/
+ clif->messagecolor_self(fd, COLOR_DEFAULT, StrBuf->Value(&buf));/** for whatever reason clif->message crashes with some patterns, see bugreport:8186 **/
StrBuf->Clear(&buf);
count++;
}
@@ -875,12 +876,12 @@ ACMD(guildstorage)
if (sd->npc_id || sd->state.vending || sd->state.buyingstore || sd->state.trading)
return false;
- if (sd->state.storage_flag == 1) {
+ if (sd->state.storage_flag == STORAGE_FLAG_NORMAL) {
clif->message(fd, msg_fd(fd,250));
return false;
}
- if (sd->state.storage_flag == 2) {
+ if (sd->state.storage_flag == STORAGE_FLAG_GUILD) {
clif->message(fd, msg_fd(fd,251));
return false;
}
@@ -1124,7 +1125,7 @@ ACMD(heal)
if ( hp < 0 && sp <= 0 ) {
status->damage(NULL, &sd->bl, -hp, -sp, 0, 0);
- clif->damage(&sd->bl,&sd->bl, 0, 0, -hp, 0, 4, 0);
+ clif->damage(&sd->bl,&sd->bl, 0, 0, -hp, 0, BDT_ENDURE, 0);
clif->message(fd, msg_fd(fd,156)); // HP or/and SP modified.
return true;
}
@@ -1135,7 +1136,7 @@ ACMD(heal)
status->heal(&sd->bl, hp, 0, 0);
else {
status->damage(NULL, &sd->bl, -hp, 0, 0, 0);
- clif->damage(&sd->bl,&sd->bl, 0, 0, -hp, 0, 4, 0);
+ clif->damage(&sd->bl,&sd->bl, 0, 0, -hp, 0, BDT_ENDURE, 0);
}
}
@@ -1344,7 +1345,7 @@ ACMD(itemreset)
for (i = 0; i < MAX_INVENTORY; i++) {
if (sd->status.inventory[i].amount && sd->status.inventory[i].equip == 0) {
- pc->delitem(sd, i, sd->status.inventory[i].amount, 0, 0, LOG_TYPE_COMMAND);
+ pc->delitem(sd, i, sd->status.inventory[i].amount, 0, DELITEM_NORMAL, LOG_TYPE_COMMAND);
}
}
clif->message(fd, msg_fd(fd,20)); // All of your items have been removed.
@@ -1443,7 +1444,7 @@ ACMD(joblevelup)
level = sd->status.job_level-1;
sd->status.job_level -= (unsigned int)level;
if (sd->status.skill_point < level)
- pc->resetskill(sd,0); //Reset skills since we need to subtract more points.
+ pc->resetskill(sd, PCRESETSKILL_NONE); //Reset skills since we need to subtract more points.
if (sd->status.skill_point < level)
sd->status.skill_point = 0;
else
@@ -2086,9 +2087,9 @@ ACMD(refine)
if (sd->status.inventory[idx].refine != final_refine) {
sd->status.inventory[idx].refine = final_refine;
current_position = sd->status.inventory[idx].equip;
- pc->unequipitem(sd, idx, 3);
+ pc->unequipitem(sd, idx, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE);
clif->refine(fd, 0, idx, sd->status.inventory[idx].refine);
- clif->delitem(sd, idx, 1, 3);
+ clif->delitem(sd, idx, 1, DELITEM_MATERIALCHANGE);
clif->additem(sd, idx, 1, 0);
pc->equipitem(sd, idx, current_position);
clif->misceffect(&sd->bl, 3);
@@ -2730,7 +2731,7 @@ ACMD(char_block)
return false;
}
- chrif->char_ask_name(sd->status.account_id, atcmd_player_name, 1, 0, 0, 0, 0, 0, 0); // type: 1 - block
+ chrif->char_ask_name(sd->status.account_id, atcmd_player_name, CHAR_ASK_NAME_BLOCK, 0, 0, 0, 0, 0, 0);
clif->message(fd, msg_fd(fd,88)); // Character name sent to char-server to ask it.
return true;
@@ -2826,7 +2827,8 @@ ACMD(char_ban)
return false;
}
- chrif->char_ask_name(sd->status.account_id, atcmd_player_name, !strcmpi(info->command,"charban") ? 6 : 2, year, month, day, hour, minute, second); // type: 2 - ban; 6 - charban
+ chrif->char_ask_name(sd->status.account_id, atcmd_player_name,
+ !strcmpi(info->command,"charban") ? CHAR_ASK_NAME_CHARBAN : CHAR_ASK_NAME_BAN, year, month, day, hour, minute, second);
clif->message(fd, msg_fd(fd,88)); // Character name sent to char-server to ask it.
return true;
@@ -2845,7 +2847,7 @@ ACMD(char_unblock)
}
// send answer to login server via char-server
- chrif->char_ask_name(sd->status.account_id, atcmd_player_name, 3, 0, 0, 0, 0, 0, 0); // type: 3 - unblock
+ chrif->char_ask_name(sd->status.account_id, atcmd_player_name, CHAR_ASK_NAME_UNBLOCK, 0, 0, 0, 0, 0, 0);
clif->message(fd, msg_fd(fd,88)); // Character name sent to char-server to ask it.
return true;
@@ -2864,7 +2866,8 @@ ACMD(char_unban)
}
// send answer to login server via char-server
- chrif->char_ask_name(sd->status.account_id, atcmd_player_name, !strcmpi(info->command,"charunban") ? 7 : 4, 0, 0, 0, 0, 0, 0); // type: 4 - unban account; type 7 - unban character
+ chrif->char_ask_name(sd->status.account_id, atcmd_player_name,
+ !strcmpi(info->command,"charunban") ? CHAR_ASK_NAME_CHARUNBAN : CHAR_ASK_NAME_UNBAN, 0, 0, 0, 0, 0, 0);
clif->message(fd, msg_fd(fd,88)); // Character name sent to char-server to ask it.
return true;
@@ -3101,7 +3104,7 @@ ACMD(questskill)
return false;
}
- pc->skill(sd, skill_id, 1, 0);
+ pc->skill(sd, skill_id, 1, SKILL_GRANT_PERMANENT);
clif->message(fd, msg_fd(fd,70)); // You have learned the skill.
return true;
@@ -5096,7 +5099,7 @@ ACMD(dropall)
for (i = 0; i < MAX_INVENTORY; i++) {
if (sd->status.inventory[i].amount) {
if(sd->status.inventory[i].equip != 0)
- pc->unequipitem(sd, i, 3);
+ pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE);
pc->dropitem(sd, i, sd->status.inventory[i].amount);
}
}
@@ -5111,7 +5114,7 @@ ACMD(storeall)
{
int i;
- if (sd->state.storage_flag != 1) {
+ if (sd->state.storage_flag != STORAGE_FLAG_NORMAL) {
//Open storage.
if( storage->open(sd) == 1 ) {
clif->message(fd, msg_fd(fd,1161)); // You currently cannot open your storage.
@@ -5122,7 +5125,7 @@ ACMD(storeall)
for (i = 0; i < MAX_INVENTORY; i++) {
if (sd->status.inventory[i].amount) {
if(sd->status.inventory[i].equip != 0)
- pc->unequipitem(sd, i, 3);
+ pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE);
storage->add(sd, i, sd->status.inventory[i].amount);
}
}
@@ -5136,7 +5139,7 @@ ACMD(clearstorage)
{
int i, j;
- if (sd->state.storage_flag == 1) {
+ if (sd->state.storage_flag == STORAGE_FLAG_NORMAL) {
clif->message(fd, msg_fd(fd,250));
return false;
}
@@ -5164,12 +5167,12 @@ ACMD(cleargstorage)
return false;
}
- if (sd->state.storage_flag == 1) {
+ if (sd->state.storage_flag == STORAGE_FLAG_NORMAL) {
clif->message(fd, msg_fd(fd,250));
return false;
}
- if (sd->state.storage_flag == 2) {
+ if (sd->state.storage_flag == STORAGE_FLAG_GUILD) {
clif->message(fd, msg_fd(fd,251));
return false;
}
@@ -5200,7 +5203,7 @@ ACMD(clearcart)
return false;
}
- if( sd->state.vending == 1 ) {
+ if (sd->state.vending) {
clif->message(fd, msg_fd(fd,548)); // You can't clean a cart while vending!
return false;
}
@@ -5241,11 +5244,11 @@ ACMD(skillid) {
for (data = iter->first(iter,&key); iter->exists(iter); data = iter->next(iter,&key)) {
int idx = skill->get_index(DB->data2i(data));
- if (strnicmp(key.str, message, skillen) == 0 || strnicmp(skill->db[idx].desc, message, skillen) == 0) {
- sprintf(atcmd_output, msg_fd(fd,1164), DB->data2i(data), skill->db[idx].desc, key.str); // skill %d: %s (%s)
+ if (strnicmp(key.str, message, skillen) == 0 || strnicmp(skill->dbs->db[idx].desc, message, skillen) == 0) {
+ sprintf(atcmd_output, msg_fd(fd,1164), DB->data2i(data), skill->dbs->db[idx].desc, key.str); // skill %d: %s (%s)
clif->message(fd, atcmd_output);
- } else if ( found < MAX_SKILLID_PARTIAL_RESULTS && ( stristr(key.str,message) || stristr(skill->db[idx].desc,message) ) ) {
- snprintf(partials[found], MAX_SKILLID_PARTIAL_RESULTS_LEN, msg_fd(fd,1164), DB->data2i(data), skill->db[idx].desc, key.str);
+ } else if ( found < MAX_SKILLID_PARTIAL_RESULTS && ( stristr(key.str,message) || stristr(skill->dbs->db[idx].desc,message) ) ) {
+ snprintf(partials[found], MAX_SKILLID_PARTIAL_RESULTS_LEN, msg_fd(fd,1164), DB->data2i(data), skill->dbs->db[idx].desc, key.str);
found++;
}
}
@@ -5326,7 +5329,7 @@ ACMD(displayskill) {
}
st = status->get_status_data(&sd->bl);
tick = timer->gettick();
- clif->skill_damage(&sd->bl,&sd->bl, tick, st->amotion, st->dmotion, 1, 1, skill_id, skill_lv, 5);
+ clif->skill_damage(&sd->bl,&sd->bl, tick, st->amotion, st->dmotion, 1, 1, skill_id, skill_lv, BDT_SPLASH);
clif->skill_nodamage(&sd->bl, &sd->bl, skill_id, skill_lv, 1);
clif->skill_poseffect(&sd->bl, skill_id, skill_lv, sd->bl.x, sd->bl.y, tick);
return true;
@@ -5373,7 +5376,7 @@ ACMD(skilltree) {
{
if( ent->need[j].id && pc->checkskill(sd,ent->need[j].id) < ent->need[j].lv)
{
- sprintf(atcmd_output, msg_fd(fd,1170), ent->need[j].lv, skill->db[ent->need[j].id].desc); // Player requires level %d of skill %s.
+ sprintf(atcmd_output, msg_fd(fd,1170), ent->need[j].lv, skill->dbs->db[ent->need[j].id].desc); // Player requires level %d of skill %s.
clif->message(fd, atcmd_output);
meets = 0;
}
@@ -5603,7 +5606,7 @@ ACMD(partyoption)
return false;
}
- option = (config_switch(w1)?1:0)|(config_switch(w2)?2:0);
+ option = (config_switch(w1)?1:0)|(config_switch(w2)?2:0); // TODO: Add documentation for these values
//Change item share type.
if (option != p->party.item)
@@ -6075,14 +6078,14 @@ ACMD(cleanmap) {
}
ACMD(cleanarea) {
- int x0 = 0, y0 = 0, x1 = 0, y1 = 0;
+ int x0 = 0, y0 = 0, x1 = 0, y1 = 0, n = 0;
- if (!message || !*message || sscanf(message, "%d %d %d %d", &x0, &y0, &x1, &y1) < 1) {
+ if (!message || !*message || (n=sscanf(message, "%d %d %d %d", &x0, &y0, &x1, &y1)) < 1) {
map->foreachinrange(atcommand->cleanfloor_sub, &sd->bl, AREA_SIZE * 2, BL_ITEM);
- } else if (sscanf(message, "%d %d %d %d", &x0, &y0, &x1, &y1) == 1) {
- map->foreachinrange(atcommand->cleanfloor_sub, &sd->bl, x0, BL_ITEM);
- } else if (sscanf(message, "%d %d %d %d", &x0, &y0, &x1, &y1) == 4) {
+ } else if (n == 4) {
map->foreachinarea(atcommand->cleanfloor_sub, sd->bl.m, x0, y0, x1, y1, BL_ITEM);
+ } else {
+ map->foreachinrange(atcommand->cleanfloor_sub, &sd->bl, x0, BL_ITEM);
}
clif->message(fd, msg_fd(fd,1221)); // All dropped items have been cleaned up.
@@ -6244,10 +6247,9 @@ ACMD(users)
/*==========================================
*
*------------------------------------------*/
-ACMD(reset)
-{
+ACMD(reset) {
pc->resetstate(sd);
- pc->resetskill(sd,1);
+ pc->resetskill(sd, PCRESETSKILL_RESYNC);
sprintf(atcmd_output, msg_fd(fd,208), sd->status.name); // '%s' skill and stats points reseted!
clif->message(fd, atcmd_output);
return true;
@@ -6288,9 +6290,9 @@ ACMD(summon)
if(!md)
return false;
- md->master_id=sd->bl.id;
- md->special_state.ai=1;
- md->deletetimer=timer->add(tick+(duration*60000),mob->timer_delete,md->bl.id,0);
+ md->master_id = sd->bl.id;
+ md->special_state.ai = AI_ATTACK;
+ md->deletetimer = timer->add(tick+(duration*60000),mob->timer_delete,md->bl.id,0);
clif->specialeffect(&md->bl,344,AREA);
mob->spawn(md);
sc_start4(NULL,&md->bl, SC_MODECHANGE, 100, 1, 0, MD_AGGRESSIVE, 0, 60000);
@@ -6423,15 +6425,14 @@ ACMD(uptime)
* @changesex <sex>
* => Changes one's sex. Argument sex can be 0 or 1, m or f, male or female.
*------------------------------------------*/
-ACMD(changesex)
-{
+ACMD(changesex) {
int i;
- pc->resetskill(sd,4);
+ pc->resetskill(sd, PCRESETSKILL_CHSEX);
// to avoid any problem with equipment and invalid sex, equipment is unequipped.
for( i=0; i<EQI_MAX; i++ )
- if( sd->equip_index[i] >= 0 ) pc->unequipitem(sd, sd->equip_index[i], 3);
- chrif->changesex(sd);
+ if( sd->equip_index[i] >= 0 ) pc->unequipitem(sd, sd->equip_index[i], PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE);
+ chrif->changesex(sd, true);
return true;
}
@@ -6745,7 +6746,7 @@ ACMD(showmobs)
continue;
if( mob_id != -1 && md->class_ != mob_id )
continue;
- if( md->special_state.ai || md->master_id )
+ if (md->special_state.ai != AI_NONE || md->master_id)
continue; // hide slaves and player summoned mobs
if( md->spawn_timer != INVALID_TIMER )
continue; // hide mobs waiting for respawn
@@ -7804,13 +7805,15 @@ ACMD(cash)
if( !battle_config.cashshop_show_points ){
sprintf(output, msg_fd(fd,505), ret, sd->cashPoints);
clif_disp_onlyself(sd, output, strlen(output));
+ clif->message(fd, output);
}
} else
clif->message(fd, msg_fd(fd,149)); // Unable to decrease the number/value.
} else {
if( (ret=pc->paycash(sd, -value, 0)) >= 0){
sprintf(output, msg_fd(fd,410), ret, sd->cashPoints);
- clif_disp_onlyself(sd, output, strlen(output));
+ clif_disp_onlyself(sd, output, strlen(output));
+ clif->message(fd, output);
} else
clif->message(fd, msg_fd(fd,41)); // Unable to decrease the number/value.
}
@@ -7821,13 +7824,15 @@ ACMD(cash)
if( !battle_config.cashshop_show_points ){
sprintf(output, msg_fd(fd,506), ret, sd->kafraPoints);
clif_disp_onlyself(sd, output, strlen(output));
+ clif->message(fd, output);
}
} else
clif->message(fd, msg_fd(fd,149)); // Unable to decrease the number/value.
} else {
if( (ret=pc->paycash(sd, -value, -value)) >= 0){
sprintf(output, msg_fd(fd,411), ret, sd->kafraPoints);
- clif_disp_onlyself(sd, output, strlen(output));
+ clif_disp_onlyself(sd, output, strlen(output));
+ clif->message(fd, output);
} else
clif->message(fd, msg_fd(fd,41)); // Unable to decrease the number/value.
}
@@ -7940,10 +7945,10 @@ ACMD(feelreset)
/*==========================================
* AUCTION SYSTEM
*------------------------------------------*/
-ACMD(auction) {
-
- if( !battle_config.feature_auction ) {
- clif->colormes(sd->fd,COLOR_RED,msg_fd(fd,1484));
+ACMD(auction)
+{
+ if (!battle_config.feature_auction) {
+ clif->messagecolor_self(sd->fd, COLOR_RED, msg_fd(fd,1484));
return false;
}
@@ -7955,31 +7960,22 @@ ACMD(auction) {
/*==========================================
* Kill Steal Protection
*------------------------------------------*/
-ACMD(ksprotection)
-{
+ACMD(ksprotection) {
if( sd->state.noks ) {
- sd->state.noks = 0;
+ sd->state.noks = KSPROTECT_NONE;
clif->message(fd, msg_fd(fd,1325)); // [ K.S Protection Inactive ]
- }
- else
- {
- if( !message || !*message || !strcmpi(message, "party") )
- { // Default is Party
- sd->state.noks = 2;
- clif->message(fd, msg_fd(fd,1326)); // [ K.S Protection Active - Option: Party ]
- }
- else if( !strcmpi(message, "self") )
- {
- sd->state.noks = 1;
- clif->message(fd, msg_fd(fd,1327)); // [ K.S Protection Active - Option: Self ]
- }
- else if( !strcmpi(message, "guild") )
- {
- sd->state.noks = 3;
- clif->message(fd, msg_fd(fd,1328)); // [ K.S Protection Active - Option: Guild ]
- }
- else
- clif->message(fd, msg_fd(fd,1329)); // Usage: @noks <self|party|guild>
+ } else if( !message || !*message || strcmpi(message, "party") == 0 ) {
+ // Default is Party
+ sd->state.noks = KSPROTECT_PARTY;
+ clif->message(fd, msg_fd(fd,1326)); // [ K.S Protection Active - Option: Party ]
+ } else if( strcmpi(message, "self") == 0 ) {
+ sd->state.noks = KSPROTECT_SELF;
+ clif->message(fd, msg_fd(fd,1327)); // [ K.S Protection Active - Option: Self ]
+ } else if( strcmpi(message, "guild") == 0 ) {
+ sd->state.noks = KSPROTECT_GUILD;
+ clif->message(fd, msg_fd(fd,1328)); // [ K.S Protection Active - Option: Guild ]
+ } else {
+ clif->message(fd, msg_fd(fd,1329)); // Usage: @noks <self|party|guild>
}
return true;
}
@@ -8008,7 +8004,7 @@ ACMD(resetstat)
ACMD(resetskill)
{
- pc->resetskill(sd,1);
+ pc->resetskill(sd, PCRESETSKILL_RESYNC);
sprintf(atcmd_output, msg_fd(fd,206), sd->status.name);
clif->message(fd, atcmd_output);
return true;
@@ -8255,7 +8251,7 @@ ACMD(delitem) {
{// delete pet
intif->delete_petdata(MakeDWord(sd->status.inventory[idx].card[1], sd->status.inventory[idx].card[2]));
}
- pc->delitem(sd, idx, delamount, 0, 0, LOG_TYPE_COMMAND);
+ pc->delitem(sd, idx, delamount, 0, DELITEM_NORMAL, LOG_TYPE_COMMAND);
amount-= delamount;
}
@@ -8793,13 +8789,7 @@ ACMD(channel) {
unsigned short msg_len = 1;
msg_len += sprintf(mout, "[ %s list colors ] : %s", command, channel->config->colors_name[k]);
- WFIFOHEAD(fd,msg_len + 12);
- WFIFOW(fd,0) = 0x2C1;
- WFIFOW(fd,2) = msg_len + 12;
- WFIFOL(fd,4) = 0;
- WFIFOL(fd,8) = channel->config->colors[k];
- safestrncpy((char*)WFIFOP(fd,12), mout, msg_len);
- WFIFOSET(fd, msg_len + 12);
+ clif->messagecolor_self(fd, channel->config->colors[k], mout);
}
} else {
DBIterator *iter = db_iterator(channel->db);
@@ -9153,7 +9143,7 @@ ACMD(channel) {
return false;
} else {
channel->set_options(chan, chan->options | k);
- sprintf(atcmd_output, msg_fd(fd,1454), opt_str[k],chan->name);//option '%s' is now enabled for channel '%s'
+ sprintf(atcmd_output, msg_fd(fd,1450), opt_str[k],chan->name);//option '%s' is now enabled for channel '%s'
clif->message(fd, atcmd_output);
}
} else {
@@ -9185,13 +9175,7 @@ ACMD(fontcolor) {
for( k = 0; k < channel->config->colors_count; k++ ) {
msg_len += sprintf(mout, "[ %s ] : %s", command, channel->config->colors_name[k]);
- WFIFOHEAD(fd,msg_len + 12);
- WFIFOW(fd,0) = 0x2C1;
- WFIFOW(fd,2) = msg_len + 12;
- WFIFOL(fd,4) = 0;
- WFIFOL(fd,8) = channel->config->colors[k];
- safestrncpy((char*)WFIFOP(fd,12), mout, msg_len);
- WFIFOSET(fd, msg_len + 12);
+ clif->messagecolor_self(fd, channel->config->colors[k], mout);
}
return false;
}
@@ -9214,13 +9198,8 @@ ACMD(fontcolor) {
sd->fontcolor = k + 1;
msg_len += sprintf(mout, "Color changed to '%s'", channel->config->colors_name[k]);
- WFIFOHEAD(fd,msg_len + 12);
- WFIFOW(fd,0) = 0x2C1;
- WFIFOW(fd,2) = msg_len + 12;
- WFIFOL(fd,4) = 0;
- WFIFOL(fd,8) = channel->config->colors[k];
- safestrncpy((char*)WFIFOP(fd,12), mout, msg_len);
- WFIFOSET(fd, msg_len + 12);
+ clif->messagecolor_self(fd, channel->config->colors[k], mout);
+
return true;
}
ACMD(searchstore){
@@ -9327,7 +9306,7 @@ ACMD(cddebug) {
const struct TimerData *td = timer->get(cd->entry[i]->timer);
if( !td || td->func != skill->blockpc_end ) {
- clif->messages(fd,"Found invalid entry in slot %d for skill %s",i,skill->db[cd->entry[i]->skidx].name);
+ clif->messages(fd,"Found invalid entry in slot %d for skill %s",i,skill->dbs->db[cd->entry[i]->skidx].name);
sd->blockskill[cd->entry[i]->skidx] = false;
}
}
@@ -9337,7 +9316,7 @@ ACMD(cddebug) {
if( !cd || (message && *message && !strcmpi(message,"reset")) ) {
for(i = 0; i < MAX_SKILL; i++) {
if( sd->blockskill[i] ) {
- clif->messages(fd,"Found skill '%s', unblocking...",skill->db[i].name);
+ clif->messages(fd,"Found skill '%s', unblocking...",skill->dbs->db[i].name);
sd->blockskill[i] = false;
}
}
@@ -9959,11 +9938,12 @@ bool atcommand_exec(const int fd, struct map_session_data *sd, const char *messa
}
for(i = 0; i < map->list[sd->bl.m].zone->disabled_commands_count; i++) {
if( info->func == map->list[sd->bl.m].zone->disabled_commands[i]->cmd ) {
- if( pc_get_group_level(sd) < map->list[sd->bl.m].zone->disabled_commands[i]->group_lv ) {
- clif->colormes(sd->fd,COLOR_RED,"This command is disabled in this area");
+ if (pc_get_group_level(sd) < map->list[sd->bl.m].zone->disabled_commands[i]->group_lv) {
+ clif->messagecolor_self(sd->fd, COLOR_RED, "This command is disabled in this area");
return true;
- } else
+ } else {
break;/* already found the matching command, no need to keep checking -- just go on */
+ }
}
}
}
@@ -10263,7 +10243,7 @@ void atcommand_doload(void) {
void atcommand_expand_message_table(void) {
RECREATE(atcommand->msg_table, char **, ++atcommand->max_message_table);
- RECREATE(atcommand->msg_table[atcommand->max_message_table - 1], char *, MAX_MSG);
+ CREATE(atcommand->msg_table[atcommand->max_message_table - 1], char *, MAX_MSG);
}
void do_init_atcommand(bool minimal) {
diff --git a/src/map/atcommand.h b/src/map/atcommand.h
index c1f451ad3..88ddde8c2 100644
--- a/src/map/atcommand.h
+++ b/src/map/atcommand.h
@@ -5,9 +5,12 @@
#ifndef MAP_ATCOMMAND_H
#define MAP_ATCOMMAND_H
-#include "pc_groups.h"
-#include "../common/conf.h"
-#include "../common/db.h"
+#include "map/pc_groups.h"
+#include "common/cbasetypes.h"
+#include "common/conf.h"
+#include "common/db.h"
+
+#include <stdarg.h>
/**
* Declarations
diff --git a/src/map/battle.c b/src/map/battle.c
index b2ee9cf1d..3575dea6f 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -4,43 +4,43 @@
#define HERCULES_CORE
-#include "../config/core.h" // CELL_NOSTACK, CIRCULAR_AREA, CONSOLE_INPUT, HMAP_ZONE_DAMAGE_CAP_TYPE, OFFICIAL_WALKPATH, RENEWAL, RENEWAL_ASPD, RENEWAL_CAST, RENEWAL_DROP, RENEWAL_EDP, RENEWAL_EXP, RENEWAL_LVDMG, RE_LVL_DMOD(), RE_LVL_MDMOD(), RE_LVL_TMDMOD(), RE_SKILL_REDUCTION(), SCRIPT_CALLFUNC_CHECK, SECURE_NPCTIMEOUT, STATS_OPT_OUT
+#include "config/core.h" // CELL_NOSTACK, CIRCULAR_AREA, CONSOLE_INPUT, HMAP_ZONE_DAMAGE_CAP_TYPE, OFFICIAL_WALKPATH, RENEWAL, RENEWAL_ASPD, RENEWAL_CAST, RENEWAL_DROP, RENEWAL_EDP, RENEWAL_EXP, RENEWAL_LVDMG, RE_LVL_DMOD(), RE_LVL_MDMOD(), RE_LVL_TMDMOD(), RE_SKILL_REDUCTION(), SCRIPT_CALLFUNC_CHECK, SECURE_NPCTIMEOUT, STATS_OPT_OUT
#include "battle.h"
+#include "map/battleground.h"
+#include "map/chrif.h"
+#include "map/clif.h"
+#include "map/elemental.h"
+#include "map/guild.h"
+#include "map/homunculus.h"
+#include "map/itemdb.h"
+#include "map/map.h"
+#include "map/mercenary.h"
+#include "map/mob.h"
+#include "map/party.h"
+#include "map/path.h"
+#include "map/pc.h"
+#include "map/pet.h"
+#include "map/skill.h"
+#include "map/status.h"
+#include "common/HPM.h"
+#include "common/cbasetypes.h"
+#include "common/ers.h"
+#include "common/malloc.h"
+#include "common/nullpo.h"
+#include "common/random.h"
+#include "common/showmsg.h"
+#include "common/socket.h"
+#include "common/strlib.h"
+#include "common/sysinfo.h"
+#include "common/timer.h"
+#include "common/utils.h"
+
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include "battleground.h"
-#include "chrif.h"
-#include "clif.h"
-#include "elemental.h"
-#include "guild.h"
-#include "homunculus.h"
-#include "itemdb.h"
-#include "map.h"
-#include "mercenary.h"
-#include "mob.h"
-#include "party.h"
-#include "path.h"
-#include "pc.h"
-#include "pet.h"
-#include "skill.h"
-#include "status.h"
-#include "../common/HPM.h"
-#include "../common/cbasetypes.h"
-#include "../common/ers.h"
-#include "../common/malloc.h"
-#include "../common/nullpo.h"
-#include "../common/random.h"
-#include "../common/showmsg.h"
-#include "../common/socket.h"
-#include "../common/strlib.h"
-#include "../common/sysinfo.h"
-#include "../common/timer.h"
-#include "../common/utils.h"
-
struct Battle_Config battle_config;
struct battle_interface battle_s;
@@ -300,10 +300,10 @@ int battle_delay_damage(int64 tick, int amotion, struct block_list *src, struct
int battle_attr_ratio(int atk_elem,int def_type, int def_lv)
{
- if (atk_elem < 0 || atk_elem >= ELE_MAX)
+ if (atk_elem < ELE_NEUTRAL || atk_elem >= ELE_MAX)
return 100;
- if (def_type < 0 || def_type >= ELE_MAX || def_lv < 1 || def_lv > 4)
+ if (def_type < ELE_NEUTRAL || def_type >= ELE_MAX || def_lv < 1 || def_lv > 4)
return 100;
return battle->attr_fix_table[def_lv-1][atk_elem][def_type];
@@ -322,10 +322,10 @@ int64 battle_attr_fix(struct block_list *src, struct block_list *target, int64 d
if (src) sc = status->get_sc(src);
if (target) tsc = status->get_sc(target);
- if (atk_elem < 0 || atk_elem >= ELE_MAX)
+ if (atk_elem < ELE_NEUTRAL || atk_elem >= ELE_MAX)
atk_elem = rnd()%ELE_MAX;
- if (def_type < 0 || def_type >= ELE_MAX ||
+ if (def_type < ELE_NEUTRAL || def_type >= ELE_MAX ||
def_lv < 1 || def_lv > 4) {
ShowError("battle_attr_fix: unknown attr type: atk=%d def_type=%d def_lv=%d\n",atk_elem,def_type,def_lv);
return damage;
@@ -407,6 +407,8 @@ int64 battle_attr_fix(struct block_list *src, struct block_list *target, int64 d
else
return damage + (damage * (ratio - 100) / 100);
}
+
+//FIXME: Missing documentation for flag, flag2
int64 battle_calc_weapon_damage(struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, struct weapon_atk *watk, int nk, bool n_ele, short s_ele, short s_ele_, int size, int type, int flag, int flag2){ // [malufett]
#ifdef RENEWAL
int64 damage, eatk = 0;
@@ -421,41 +423,47 @@ int64 battle_calc_weapon_damage(struct block_list *src, struct block_list *bl, u
damage = status->get_weapon_atk(src, watk, flag);
- if( sd ){
- if( type == EQI_HAND_R )
- damage = battle->calc_sizefix(sd, damage, EQI_HAND_R, size, flag&8);
+ if ( sd ) {
+ if ( type == EQI_HAND_R )
+ damage = battle->calc_sizefix(sd, damage, EQI_HAND_R, size, flag & 8);
else
- damage = battle->calc_sizefix(sd, damage, EQI_HAND_L, size, flag&8);
+ damage = battle->calc_sizefix(sd, damage, EQI_HAND_L, size, flag & 8);
- if( flag&2 && sd->bonus.arrow_atk )
+ if ( flag & 2 && sd->bonus.arrow_atk && skill_id != GN_CARTCANNON )
damage += sd->bonus.arrow_atk;
- if( sd->battle_status.equip_atk != 0 )
+ if ( sd->battle_status.equip_atk != 0 )
eatk = sd->base_status.equip_atk;
+
+ if ( sd->bonus.atk_rate )
+ damage += damage * sd->bonus.atk_rate / 100;
}
if ( skill_id == TF_POISON )
eatk += 15 * skill_lv;
+ if ( skill_id != ASC_METEORASSAULT ) {
+ if ( sc && sc->data[SC_SUB_WEAPONPROPERTY] ) // Temporary. [malufett]
+ damage += damage * sc->data[SC_SUB_WEAPONPROPERTY]->val2 / 100;
+ }
+
if( sc && sc->count ){
if( sc->data[SC_ZENKAI] && watk->ele == sc->data[SC_ZENKAI]->val2 )
eatk += 200;
+ }
+
#ifdef RENEWAL_EDP
- if( sc->data[SC_EDP] && skill_id != AS_GRIMTOOTH && skill_id != AS_VENOMKNIFE && skill_id != ASC_BREAKER ){
- eatk = eatk * (sc->data[SC_EDP]->val4 / 100 - 1);
- damage = damage * (sc->data[SC_EDP]->val4 / 100);
- }
+ if ( sc && sc->data[SC_EDP] && skill_id != AS_GRIMTOOTH && skill_id != AS_VENOMKNIFE && skill_id != ASC_BREAKER ) {
+ struct status_data *tstatus;
+ tstatus = status->get_status_data(bl);
+ eatk += damage * 0x19 * battle->attr_fix_table[tstatus->ele_lv - 1][ELE_POISON][tstatus->def_ele] / 10000;
+ damage += (eatk + damage) * sc->data[SC_EDP]->val3 / 100 + eatk;
+ } else /* fall through */
#endif
- }
-
- if( skill_id != ASC_METEORASSAULT ){
- if( sc && sc->data[SC_SUB_WEAPONPROPERTY] ) // Temporary. [malufett]
- damage += damage * sc->data[SC_SUB_WEAPONPROPERTY]->val2 / 100;
- }
-
- // Temporary. [malufett]
- damage = battle->calc_elefix(src, bl, skill_id, skill_lv, damage + eatk, nk, n_ele, s_ele, s_ele_, type == EQI_HAND_L, flag);
-
+ damage += eatk;
+
+ damage = battle->calc_elefix(src, bl, skill_id, skill_lv, damage, nk, n_ele, s_ele, s_ele_, type == EQI_HAND_L, flag);
+
/**
* In RE Shield Boomerang takes weapon element only for damage calculation,
* - resist calculation is always against neutral
@@ -479,7 +487,7 @@ int64 battle_calc_weapon_damage(struct block_list *src, struct block_list *bl, u
* it calculates nothing extra fancy, is needed for magnum breaks WATK_ELEMENT bonus. [Skotlex]
*------------------------------------------
* Pass damage2 as NULL to not calc it.
- * Flag values:
+ * Flag values: // TODO: Check whether these values are correct (the flag parameter seems to be passed through to other functions), and replace them with an enum.
* &1: Critical hit
* &2: Arrow attack
* &4: Skill is Magic Crasher
@@ -487,11 +495,23 @@ int64 battle_calc_weapon_damage(struct block_list *src, struct block_list *bl, u
*&16: Arrow attack but BOW, REVOLVER, RIFLE, SHOTGUN, GATLING or GRENADE type weapon not equipped (i.e. shuriken, kunai and venom knives not affected by DEX)
*/
/* 'battle_calc_base_damage' is used on renewal, 'battle_calc_base_damage2' otherwise. */
+// FIXME: Missing documentation for flag2
int64 battle_calc_base_damage(struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int nk, bool n_ele, short s_ele, short s_ele_, int type, int flag, int flag2) {
int64 damage;
struct status_data *st = status->get_status_data(src);
struct status_change *sc = status->get_sc(src);
-
+
+ if ( !skill_id ) {
+ s_ele = st->rhw.ele;
+ s_ele_ = st->lhw.ele;
+ if ( src->type == BL_PC ) {
+ if ( ((TBL_PC*)src)->charm_type != CHARM_TYPE_NONE && ((TBL_PC*)src)->charm_count >= MAX_SPIRITCHARM ) {
+ s_ele = s_ele_ = ((TBL_PC*)src)->charm_type;
+ }
+ if ( flag & 2 && ((TBL_PC*)src)->bonus.arrow_ele )
+ s_ele = ((TBL_PC*)src)->bonus.arrow_ele;
+ }
+ }
if (src->type == BL_PC) {
int64 batk;
// Property from mild wind bypasses it
@@ -599,6 +619,7 @@ int64 battle_calc_sizefix(struct map_session_data *sd, int64 damage, int type, i
/*==========================================
* Passive skill damages increases
*------------------------------------------*/
+// FIXME: type is undocumented
int64 battle_addmastery(struct map_session_data *sd,struct block_list *target,int64 dmg,int type) {
int64 damage;
struct status_data *st = status->get_status_data(target);
@@ -849,6 +870,7 @@ void battle_calc_masteryfix_unknown(struct block_list *src, struct block_list *t
/*==========================================
* Elemental attribute fix.
*------------------------------------------*/
+// FIXME: flag is undocumented
int64 battle_calc_elefix(struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, int64 damage, int nk, int n_ele, int s_ele, int s_ele_, bool left, int flag){
struct status_data *tstatus;
@@ -869,8 +891,6 @@ int64 battle_calc_elefix(struct block_list *src, struct block_list *target, uint
damage = battle->attr_fix(src,target,damage,ELE_NEUTRAL,tstatus->def_ele, tstatus->ele_lv);
if( skill_id == NC_ARMSCANNON )
damage = battle->attr_fix(src,target,damage,ELE_NEUTRAL,tstatus->def_ele, tstatus->ele_lv);
- if( skill_id == GN_CARTCANNON )
- damage = battle->attr_fix(src,target,damage,ELE_NEUTRAL,tstatus->def_ele, tstatus->ele_lv);
if( skill_id == GS_GROUNDDRIFT ) //Additional 50*lv Neutral damage.
damage += battle->attr_fix(src,target,50*skill_lv,ELE_NEUTRAL,tstatus->def_ele, tstatus->ele_lv);
}
@@ -896,15 +916,53 @@ int64 battle_calc_elefix(struct block_list *src, struct block_list *target, uint
#endif
return damage;
}
+int64 battle_calc_cardfix2(struct block_list *src, struct block_list *bl, int64 damage, int s_ele, int nk, int flag) {
+#ifdef RENEWAL
+ struct map_session_data *tsd;
+ struct status_data *sstatus;
+
+ if ( !damage )
+ return 0;
+
+ nullpo_ret(bl);
+ nullpo_ret(src);
+
+ tsd = BL_CAST(BL_PC, bl);
+ sstatus = status->get_status_data(src);
+
+ if ( tsd ) {
+ if ( !(nk&NK_NO_CARDFIX_DEF) ) {
+ // RaceAddTolerance
+ damage -= damage * tsd->race_tolerance[sstatus->race] / 100;
+ damage -= damage * tsd->race_tolerance[is_boss(src) ? RC_BOSS : RC_NONBOSS] / 100;
+ if ( flag&BF_SHORT )
+ damage -= damage * tsd->bonus.near_attack_def_rate / 100;
+ else // SubRangeAttackDamage or bLongAtkDef
+ damage -= damage * tsd->bonus.long_attack_def_rate / 100;
+ }
+ if ( flag&BF_LONG && tsd->sc.data[SC_GS_ADJUSTMENT] ) {
+ damage -= 20 * damage / 100;
+ }
+ }
+#endif
+ return damage;
+}
/*==========================================
* Calculates card bonuses damage adjustments.
* cflag(cardfix flag):
* &1 - calc for left hand.
* &2 - atker side cardfix(BF_WEAPON) otherwise target side(BF_WEAPON).
*------------------------------------------*/
+// FIXME: wflag is undocumented
int64 battle_calc_cardfix(int attack_type, struct block_list *src, struct block_list *target, int nk, int s_ele, int s_ele_, int64 damage, int cflag, int wflag){
struct map_session_data *sd, *tsd;
- short cardfix = 1000, t_class, s_class, s_race2, t_race2;
+ short cardfix =
+#ifdef RENEWAL
+ 100;
+#else
+ 1000;
+#endif
+ short t_class, s_class, s_race2, t_race2;
struct status_data *sstatus, *tstatus;
int i;
@@ -937,8 +995,6 @@ int64 battle_calc_cardfix(int attack_type, struct block_list *src, struct block_
break;
}
}
- if (cardfix != 1000)
- damage = damage * cardfix / 1000;
}
if( tsd && !(nk&NK_NO_CARDFIX_DEF) )
@@ -961,8 +1017,6 @@ int64 battle_calc_cardfix(int attack_type, struct block_list *src, struct block_
cardfix = cardfix * (100 - tsd->subrace2[s_race2]) / 100;
cardfix = cardfix * (100 - tsd->subrace[sstatus->race]) / 100;
cardfix = cardfix * (100 - tsd->subrace[is_boss(src)?RC_BOSS:RC_NONBOSS]) / 100;
- if( sstatus->race != RC_DEMIHUMAN )
- cardfix = cardfix * (100-tsd->subrace[RC_NONDEMIHUMAN]) / 100;
for(i=0; i < ARRAYLENGTH(tsd->add_mdef) && tsd->add_mdef[i].rate;i++) {
if(tsd->add_mdef[i].class_ == s_class) {
@@ -982,16 +1036,25 @@ int64 battle_calc_cardfix(int attack_type, struct block_list *src, struct block_
if( tsd->sc.data[SC_PROTECT_MDEF] )
cardfix = cardfix * ( 100 - tsd->sc.data[SC_PROTECT_MDEF]->val1 ) / 100;
-
- if( cardfix != 1000 )
- damage = damage * cardfix / 1000;
}
+#ifdef RENEWAL
+ if ( cardfix != 100 )
+ damage += damage * (cardfix - 100) / 100;
+#else
+ if ( cardfix != 1000 )
+ damage = damage * cardfix / 1000;
+#endif
break;
case BF_WEAPON:
t_race2 = status->get_race2(target);
if( cflag&2 ){
if( sd && !(nk&NK_NO_CARDFIX_ATK) ){
- short cardfix_ = 1000;
+ short cardfix_ =
+#ifdef RENEWAL
+ 100;
+#else
+ 1000;
+#endif
if( sd->state.arrow_atk ){
cardfix = cardfix * (100 + sd->right_weapon.addrace[tstatus->race] + sd->arrow_addrace[tstatus->race]) / 100;
if( !(nk&NK_NO_ELEFIX) ){
@@ -1009,8 +1072,6 @@ int64 battle_calc_cardfix(int attack_type, struct block_list *src, struct block_
cardfix = cardfix * (100 + sd->right_weapon.addsize[tstatus->size]+sd->arrow_addsize[tstatus->size]) / 100;
cardfix = cardfix * (100 + sd->right_weapon.addrace2[t_race2]) / 100;
cardfix = cardfix * (100 + sd->right_weapon.addrace[is_boss(target)?RC_BOSS:RC_NONBOSS] + sd->arrow_addrace[is_boss(target)?RC_BOSS:RC_NONBOSS]) / 100;
- if( tstatus->race != RC_DEMIHUMAN )
- cardfix = cardfix * (100 + sd->right_weapon.addrace[RC_NONDEMIHUMAN]+sd->arrow_addrace[RC_NONDEMIHUMAN]) / 100;
}else{ // Melee attack
if( !battle_config.left_cardfix_to_right ){
cardfix=cardfix*(100+sd->right_weapon.addrace[tstatus->race])/100;
@@ -1029,8 +1090,6 @@ int64 battle_calc_cardfix(int attack_type, struct block_list *src, struct block_
cardfix = cardfix * (100+sd->right_weapon.addsize[tstatus->size]) / 100;
cardfix = cardfix * (100+sd->right_weapon.addrace2[t_race2]) / 100;
cardfix = cardfix * (100+sd->right_weapon.addrace[is_boss(target)?RC_BOSS:RC_NONBOSS]) / 100;
- if( tstatus->race != RC_DEMIHUMAN )
- cardfix = cardfix * (100 + sd->right_weapon.addrace[RC_NONDEMIHUMAN]) / 100;
if( cflag&1 ){
cardfix_ = cardfix_*(100+sd->left_weapon.addrace[tstatus->race])/100;
@@ -1049,8 +1108,6 @@ int64 battle_calc_cardfix(int attack_type, struct block_list *src, struct block_
cardfix_ = cardfix_ * (100+sd->left_weapon.addsize[tstatus->size]) / 100;
cardfix_ = cardfix_ * (100+sd->left_weapon.addrace2[t_race2]) / 100;
cardfix_ = cardfix_ * (100+sd->left_weapon.addrace[is_boss(target)?RC_BOSS:RC_NONBOSS]) / 100;
- if( tstatus->race != RC_DEMIHUMAN )
- cardfix_ = cardfix_*(100+sd->left_weapon.addrace[RC_NONDEMIHUMAN])/100;
}
}else{
int ele_fix = sd->right_weapon.addele[tstatus->def_ele] + sd->left_weapon.addele[tstatus->def_ele];
@@ -1076,8 +1133,6 @@ int64 battle_calc_cardfix(int attack_type, struct block_list *src, struct block_
cardfix = cardfix * (100 + sd->right_weapon.addsize[tstatus->size] + sd->left_weapon.addsize[tstatus->size])/100;
cardfix = cardfix * (100 + sd->right_weapon.addrace2[t_race2] + sd->left_weapon.addrace2[t_race2])/100;
cardfix = cardfix * (100 + sd->right_weapon.addrace[is_boss(target)?RC_BOSS:RC_NONBOSS] + sd->left_weapon.addrace[is_boss(target)?RC_BOSS:RC_NONBOSS]) / 100;
- if( tstatus->race != RC_DEMIHUMAN )
- cardfix = cardfix * (100+sd->right_weapon.addrace[RC_NONDEMIHUMAN] + sd->left_weapon.addrace[RC_NONDEMIHUMAN]) / 100;
}
}
@@ -1099,11 +1154,16 @@ int64 battle_calc_cardfix(int attack_type, struct block_list *src, struct block_
#ifndef RENEWAL
if( wflag&BF_LONG )
cardfix = cardfix * (100 + sd->bonus.long_attack_atk_rate) / 100;
-#endif
if( (cflag&1) && cardfix_ != 1000 )
damage = damage * cardfix_ / 1000;
else if( cardfix != 1000 )
damage = damage * cardfix / 1000;
+#else
+ if ( (cflag & 1) && cardfix_ != 100 )
+ damage += damage * (cardfix - 100) / 100;
+ else if ( cardfix != 100 )
+ damage += damage * (cardfix - 100) / 100;
+#endif
}
}else{
// Target side
@@ -1137,8 +1197,6 @@ int64 battle_calc_cardfix(int attack_type, struct block_list *src, struct block_
cardfix = cardfix * (100-tsd->subrace2[s_race2]) / 100;
cardfix = cardfix * (100-tsd->subrace[sstatus->race]) / 100;
cardfix = cardfix * (100-tsd->subrace[is_boss(src)?RC_BOSS:RC_NONBOSS]) / 100;
- if( sstatus->race != RC_DEMIHUMAN )
- cardfix = cardfix * (100-tsd->subrace[RC_NONDEMIHUMAN]) / 100;
for( i = 0; i < ARRAYLENGTH(tsd->add_def) && tsd->add_def[i].rate;i++ ){
if( tsd->add_def[i].class_ == s_class )
@@ -1147,52 +1205,59 @@ int64 battle_calc_cardfix(int attack_type, struct block_list *src, struct block_
break;
}
}
-
+#ifndef RENEWAL
if( wflag&BF_SHORT )
cardfix = cardfix * (100 - tsd->bonus.near_attack_def_rate) / 100;
else // BF_LONG (there's no other choice)
cardfix = cardfix * (100 - tsd->bonus.long_attack_def_rate) / 100;
-
+#endif
if( tsd->sc.data[SC_PROTECT_DEF] )
cardfix = cardfix * (100 - tsd->sc.data[SC_PROTECT_DEF]->val1) / 100;
-
+#ifdef RENEWAL
+ if ( cardfix != 100 )
+ damage += damage * (cardfix - 100) / 100;
+#else
if( cardfix != 1000 )
damage = damage * cardfix / 1000;
+#endif
}
}
break;
case BF_MISC:
- if( tsd && !(nk&NK_NO_CARDFIX_DEF) ){
- // misc damage reduction from equipment
- if (!(nk&NK_NO_ELEFIX))
+ if ( tsd && !(nk&NK_NO_CARDFIX_DEF) ) {
+ // misc damage reduction from equipment
+#ifndef RENEWAL
+ if ( !(nk&NK_NO_ELEFIX) )
{
int ele_fix = tsd->subele[s_ele];
for (i = 0; ARRAYLENGTH(tsd->subele2) > i && tsd->subele2[i].rate != 0; i++)
{
if(tsd->subele2[i].ele != s_ele) continue;
if(!(tsd->subele2[i].flag&wflag&BF_WEAPONMASK &&
- tsd->subele2[i].flag&wflag&BF_RANGEMASK &&
- tsd->subele2[i].flag&wflag&BF_SKILLMASK))
+ tsd->subele2[i].flag&wflag&BF_RANGEMASK &&
+ tsd->subele2[i].flag&wflag&BF_SKILLMASK))
continue;
ele_fix += tsd->subele2[i].rate;
}
cardfix = cardfix * (100 - ele_fix) / 100;
}
- cardfix = cardfix*(100-tsd->subsize[sstatus->size]) / 100;
- cardfix = cardfix*(100-tsd->subrace2[s_race2]) / 100;
cardfix = cardfix*(100-tsd->subrace[sstatus->race]) / 100;
cardfix = cardfix*(100-tsd->subrace[is_boss(src)?RC_BOSS:RC_NONBOSS]) / 100;
- if( sstatus->race != RC_DEMIHUMAN )
- cardfix = cardfix * (100 - tsd->subrace[RC_NONDEMIHUMAN]) / 100;
-
- cardfix = cardfix * ( 100 - tsd->bonus.misc_def_rate ) / 100;
if( wflag&BF_SHORT )
cardfix = cardfix * ( 100 - tsd->bonus.near_attack_def_rate ) / 100;
else // BF_LONG (there's no other choice)
cardfix = cardfix * ( 100 - tsd->bonus.long_attack_def_rate ) / 100;
-
- if (cardfix != 1000)
+#endif
+ cardfix = cardfix*(100 - tsd->subsize[sstatus->size]) / 100;
+ cardfix = cardfix*(100 - tsd->subrace2[s_race2]) / 100;
+ cardfix = cardfix * (100 - tsd->bonus.misc_def_rate) / 100;
+#ifdef RENEWAL
+ if ( cardfix != 100 )
+ damage += damage * (cardfix - 100) / 100;
+#else
+ if ( cardfix != 1000 )
damage = damage * cardfix / 1000;
+#endif
}
break;
}
@@ -1207,6 +1272,7 @@ int64 battle_calc_cardfix(int attack_type, struct block_list *src, struct block_
* &2 - pdef(Pierce defense)
* &4 - tdef(Total defense reduction)
*------------------------------------------*/
+// TODO: Add an enum for flag
int64 battle_calc_defense(int attack_type, struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, int64 damage, int flag, int pdef){
struct status_data *sstatus, *tstatus;
struct map_session_data *sd, *tsd;
@@ -1244,21 +1310,26 @@ int64 battle_calc_defense(int attack_type, struct block_list *src, struct block_
#endif
if ( sd ) {
+ if ( sd->charm_type == CHARM_TYPE_LAND && sd->charm_count > 0 ) // hidden from status window
+ def1 += 10 * def1 * sd->charm_count / 100;
+
i = sd->ignore_def[is_boss(target) ? RC_BOSS : RC_NONBOSS];
i += sd->ignore_def[tstatus->race];
if ( i ) {
if ( i > 100 ) i = 100;
def1 -= def1 * i / 100;
+#ifndef RENEWAL
def2 -= def2 * i / 100;
+#endif
}
- if (sd->charm_type == CHARM_TYPE_LAND && sd->charm_count > 0 ) // hidden from status window
- def1 += 10 * def1 * sd->charm_count / 100;
}
if( sc && sc->data[SC_EXPIATIO] ){
i = 5 * sc->data[SC_EXPIATIO]->val1; // 5% per level
def1 -= def1 * i / 100;
+#ifndef RENEWAL
def2 -= def2 * i / 100;
+#endif
}
if( battle_config.vit_penalty_type && battle_config.vit_penalty_target&target->type ) {
@@ -1275,7 +1346,9 @@ int64 battle_calc_defense(int attack_type, struct block_list *src, struct block_
def2 -= (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num;
}
}
+#ifndef RENEWAL
if(skill_id == AM_ACIDTERROR) def1 = 0; //Acid Terror ignores only armor defense. [Skotlex]
+#endif
if(def2 < 1) def2 = 1;
}
//Vitality reduction from rodatazone: http://rodatazone.simgaming.net/mechanics/substats.php#def
@@ -1403,6 +1476,7 @@ int battle_calc_chorusbonus(struct map_session_data *sd) {
return members - 2; // Effect bonus from additional Minstrel's/Wanderer's if not above the max possible
}
+// FIXME: flag is undocumented
int battle_calc_skillratio(int attack_type, struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, int skillratio, int flag){
int i;
struct status_change *sc, *tsc;
@@ -1927,7 +2001,11 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block
skillratio += 20 * skill_lv;
break;
case AM_ACIDTERROR:
+#ifdef RENEWAL
+ skillratio += 80 * skill_lv + 100;
+#else
skillratio += 40 * skill_lv;
+#endif
break;
case MO_FINGEROFFENSIVE:
skillratio+= 50 * skill_lv;
@@ -1935,8 +2013,8 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block
case MO_INVESTIGATE:
skillratio += 75 * skill_lv;
break;
- #ifndef RENEWAL
case MO_EXTREMITYFIST:
+ #ifndef RENEWAL
{
//Overflow check. [Skotlex]
unsigned int ratio = skillratio + 100*(8 + st->sp/10);
@@ -1944,8 +2022,8 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block
if (ratio > 60000) ratio = 60000; //We leave some room here in case skillratio gets further increased.
skillratio = (unsigned short)ratio;
}
+#endif
break;
- #endif
case MO_TRIPLEATTACK:
skillratio += 20 * skill_lv;
break;
@@ -2050,14 +2128,11 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block
case GS_TRACKING:
skillratio += 100 * (skill_lv+1);
break;
+#ifndef RENEWAL
case GS_PIERCINGSHOT:
-#ifdef RENEWAL
- if( sd && sd->weapontype1 == W_RIFLE )
- skillratio += 50 + 30 * skill_lv;
- else
-#endif
skillratio += 20 * skill_lv;
break;
+#endif
case GS_RAPIDSHOWER:
skillratio += 10 * skill_lv;
break;
@@ -2456,7 +2531,7 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block
}
break;
case GN_CARTCANNON:
- skillratio = 50 * (sd ? pc->checkskill(sd, GN_REMODELING_CART) : 5) * (st->int_ / 40) + 60 * skill_lv;
+ skillratio += -100 + (int)(50.0f * (sd ? pc->checkskill(sd, GN_REMODELING_CART) : 5) * (st->int_ / 40.0f) + 60.0f * skill_lv);
break;
case GN_SPORE_EXPLOSION:
skillratio = 100 * skill_lv + (200 + st->int_) * status->get_lv(src) / 100;
@@ -2705,6 +2780,8 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
group->val2 -= (int)cap_value(damage,INT_MIN,INT_MAX);
} else
skill->del_unitgroup(group,ALC_MARK);
+ if (--group->val3<=0)
+ skill->del_unitgroup(group,ALC_MARK);
#else
if (--group->val2<=0)
skill->del_unitgroup(group,ALC_MARK);
@@ -2920,11 +2997,11 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
if(sc->data[SC_DEFENDER] &&
((flag&(BF_LONG|BF_WEAPON)) == (BF_LONG|BF_WEAPON) || skill_id == CR_ACIDDEMONSTRATION))
damage = damage * ( 100 - sc->data[SC_DEFENDER]->val2 ) / 100;
-
+#ifndef RENEWAL
if(sc->data[SC_GS_ADJUSTMENT] &&
(flag&(BF_LONG|BF_WEAPON)) == (BF_LONG|BF_WEAPON))
damage -= damage * 20 / 100;
-
+#endif
if(sc->data[SC_FOGWALL]) {
if(flag&BF_SKILL) { //25% reduction
if ( !(skill->get_inf(skill_id)&INF_GROUND_SKILL) && !(skill->get_nk(skill_id)&NK_SPLASH) )
@@ -3076,28 +3153,31 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
if( sc->data[SC__DEADLYINFECT] && flag&BF_SHORT && damage > 0 && rnd()%100 < 30 + 10 * sc->data[SC__DEADLYINFECT]->val1 && !is_boss(src) )
status->change_spread(bl, src); // Deadly infect attacked side
+
+ if ( sd && damage > 0 && (sce = sc->data[SC_GENTLETOUCH_ENERGYGAIN]) ) {
+ if ( rnd() % 100 < sce->val2 )
+ pc->addspiritball(sd, skill->get_time(MO_CALLSPIRITS, 1), pc->getmaxspiritball(sd, 0));
+ }
}
//SC effects from caster side.
- sc = status->get_sc(src);
-
- if (sc && sc->count) {
- if( sc->data[SC_INVINCIBLE] && !sc->data[SC_INVINCIBLEOFF] )
+ if (tsc && tsc->count) {
+ if( tsc->data[SC_INVINCIBLE] && !tsc->data[SC_INVINCIBLEOFF] )
damage += damage * 75 / 100;
// [Epoque]
if (bl->type == BL_MOB) {
int i;
- if ( ((sce=sc->data[SC_MANU_ATK]) && (flag&BF_WEAPON)) ||
- ((sce=sc->data[SC_MANU_MATK]) && (flag&BF_MAGIC))
+ if ( ((sce=tsc->data[SC_MANU_ATK]) && (flag&BF_WEAPON)) ||
+ ((sce=tsc->data[SC_MANU_MATK]) && (flag&BF_MAGIC))
)
for (i=0;ARRAYLENGTH(mob->manuk)>i;i++)
if (((TBL_MOB*)bl)->class_==mob->manuk[i]) {
damage += damage * sce->val1 / 100;
break;
}
- if ( ((sce=sc->data[SC_SPL_ATK]) && (flag&BF_WEAPON)) ||
- ((sce=sc->data[SC_SPL_MATK]) && (flag&BF_MAGIC))
+ if ( ((sce=tsc->data[SC_SPL_ATK]) && (flag&BF_WEAPON)) ||
+ ((sce=tsc->data[SC_SPL_MATK]) && (flag&BF_MAGIC))
)
for (i=0;ARRAYLENGTH(mob->splendide)>i;i++)
if (((TBL_MOB*)bl)->class_==mob->splendide[i]) {
@@ -3114,14 +3194,19 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
sc_start(src,bl,tsc->data[SC_POISONINGWEAPON]->val2,rate,tsc->data[SC_POISONINGWEAPON]->val1,skill->get_time2(GC_POISONINGWEAPON,1) - (tstatus->vit + tstatus->luk) / 2 * 1000);
}
}
- if( sc->data[SC__DEADLYINFECT] && flag&BF_SHORT && damage > 0 && rnd()%100 < 30 + 10 * sc->data[SC__DEADLYINFECT]->val1 && !is_boss(src) )
+ if( tsc->data[SC__DEADLYINFECT] && flag&BF_SHORT && damage > 0 && rnd()%100 < 30 + 10 * tsc->data[SC__DEADLYINFECT]->val1 && !is_boss(src) )
status->change_spread(src, bl);
- if (sc->data[SC_SHIELDSPELL_REF] && sc->data[SC_SHIELDSPELL_REF]->val1 == 1 && damage > 0)
+ if (tsc->data[SC_SHIELDSPELL_REF] && tsc->data[SC_SHIELDSPELL_REF]->val1 == 1 && damage > 0)
skill->break_equip(bl,EQP_ARMOR,10000,BCT_ENEMY );
- if (sc->data[SC_STYLE_CHANGE] && rnd()%2) {
+ if (tsc->data[SC_STYLE_CHANGE] && rnd()%2) {
TBL_HOM *hd = BL_CAST(BL_HOM,bl);
if (hd) homun->addspiritball(hd, 10);
}
+ if ( src->type == BL_PC && damage > 0 && (sce = tsc->data[SC_GENTLETOUCH_ENERGYGAIN]) ) {
+ struct map_session_data *tsd = (struct map_session_data *)src;
+ if ( tsd && rnd() % 100 < sce->val2 )
+ pc->addspiritball(tsd, skill->get_time(MO_CALLSPIRITS, 1), pc->getmaxspiritball(tsd, 0));
+ }
}
/* no data claims these settings affect anything other than players */
if( damage && sd && bl->type == BL_PC ) {
@@ -3191,6 +3276,7 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
/*==========================================
* Calculates BG related damage adjustments.
*------------------------------------------*/
+// FIXME: flag is undocumented
int64 battle_calc_bg_damage(struct block_list *src, struct block_list *bl, int64 damage, int div_, uint16 skill_id, uint16 skill_lv, int flag)
{
if( !damage )
@@ -3209,6 +3295,7 @@ int64 battle_calc_bg_damage(struct block_list *src, struct block_list *bl, int64
/*==========================================
* Calculates GVG related damage adjustments.
*------------------------------------------*/
+// FIXME: flag is undocumented
int64 battle_calc_gvg_damage(struct block_list *src,struct block_list *bl,int64 damage,int div_,uint16 skill_id,uint16 skill_lv,int flag) {
struct mob_data* md = BL_CAST(BL_MOB, bl);
int class_ = status->get_class(bl);
@@ -3285,13 +3372,13 @@ void battle_consume_ammo(TBL_PC*sd, int skill_id, int lv) {
if (!battle_config.arrow_decrement)
return;
- if (skill_id) {
+ if (skill_id && lv) {
qty = skill->get_ammo_qty(skill_id, lv);
if (!qty) qty = 1;
}
if(sd->equip_index[EQI_AMMO]>=0) //Qty check should have been done in skill_check_condition
- pc->delitem(sd,sd->equip_index[EQI_AMMO],qty,0,1,LOG_TYPE_CONSUME);
+ pc->delitem(sd, sd->equip_index[EQI_AMMO], qty, 0, DELITEM_SKILLUSE, LOG_TYPE_CONSUME);
sd->state.arrow_atk = 0;
}
@@ -3345,6 +3432,7 @@ int battle_blewcount_bonus(struct map_session_data *sd, uint16 skill_id) {
/*==========================================
* battle_calc_magic_attack [DracoRPG]
*------------------------------------------*/
+// FIXME: mflag is undocumented
struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list *target,uint16 skill_id,uint16 skill_lv,int mflag) {
int nk;
short s_ele = 0;
@@ -3500,7 +3588,10 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
break;
default: {
MATK_ADD( status->get_matk(src, 2) );
-
+#ifdef RENEWAL
+ ad.damage = battle->calc_cardfix(BF_MAGIC, src, target, nk, s_ele, 0, ad.damage, 0, ad.flag);
+ ad.damage = battle->calc_cardfix2(src, target, ad.damage, s_ele, nk, ad.flag);
+#endif
if (nk&NK_SPLASHSPLIT) { // Divide MATK in case of multiple targets skill
if(mflag>0)
ad.damage/= mflag;
@@ -3520,7 +3611,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
skillratio = sc->data[SC_SPELLFIST]->val2 * 50 + sc->data[SC_SPELLFIST]->val4 * 100;// val4 = used bolt level, val2 = used spellfist level. [Rytech]
ad.div_ = 1;// ad mods, to make it work similar to regular hits [Xazax]
ad.flag = BF_WEAPON|BF_SHORT;
- ad.type = 0;
+ ad.type = BDT_NORMAL;
}
/* Fall through */
default:
@@ -3536,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 ) {
@@ -3554,9 +3645,6 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
}
}
#endif
-#ifdef RENEWAL
- ad.damage = battle->calc_cardfix(BF_MAGIC, src, target, nk, s_ele, 0, ad.damage, 0, ad.flag);
-#endif
if(sd) {
uint16 rskill;/* redirect skill */
//Damage bonuses
@@ -3671,6 +3759,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
/*==========================================
* Calculate Misc damage for skill_id
*------------------------------------------*/
+// FIXME: mflag is undocumented
struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *target,uint16 skill_id,uint16 skill_lv,int mflag) {
int temp;
short i, nk;
@@ -3789,7 +3878,7 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
short tdef = status->get_total_def(target);
short tmdef = status->get_total_mdef(target);
int targetVit = min(120, status_get_vit(target));
- short totaldef = (tmdef + tdef - ((uint64)(tmdef + tdef) >> 32)) >> 1;
+ short totaldef = (tmdef + tdef - ((uint64)(tmdef + tdef) >> 32)) >> 1; // FIXME: What's the >> 32 supposed to do here? tmdef and tdef are both 16-bit...
matk = battle->calc_magic_attack(src, target, skill_id, skill_lv, mflag).damage;
atk = battle->calc_base_damage(src, target, skill_id, skill_lv, nk, false, s_ele, ELE_NEUTRAL, EQI_HAND_R, (sc && sc->data[SC_MAXIMIZEPOWER]?1:0)|(sc && sc->data[SC_WEAPONPERFECT]?8:0), md.flag);
@@ -3866,10 +3955,11 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
int ratio = 300 + 50 * skill_lv;
int64 matk = battle->calc_magic_attack(src, target, skill_id, skill_lv, mflag).damage;
short totaldef = status->get_total_def(target) + status->get_total_mdef(target);
- int64 atk = battle->calc_base_damage(src, target, skill_id, skill_lv, nk, false, s_ele, ELE_NEUTRAL, EQI_HAND_R, (sc && sc->data[SC_MAXIMIZEPOWER]?1:0)|(sc && sc->data[SC_WEAPONPERFECT]?8:0), md.flag);
-
+ int64 atk = battle->calc_base_damage(src, target, skill_id, skill_lv, nk, false, s_ele, ELE_NEUTRAL, EQI_HAND_R, (sc && sc->data[SC_MAXIMIZEPOWER] ? 1 : 0) | (sc && sc->data[SC_WEAPONPERFECT] ? 8 : 0), md.flag);
+#ifdef RENEWAL_EDP
if( sc && sc->data[SC_EDP] )
ratio >>= 1;
+#endif
md.damage = (matk + atk) * ratio / 100;
md.damage -= totaldef;
#endif
@@ -3895,7 +3985,7 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
case RA_CLUSTERBOMB:
case RA_FIRINGTRAP:
case RA_ICEBOUNDTRAP:
- md.damage = skill_lv * sstatus->dex + sstatus->int_ * 5 ;
+ md.damage = (int64)skill_lv * sstatus->dex + sstatus->int_ * 5 ;
RE_LVL_TMDMOD();
if(sd)
{
@@ -3909,7 +3999,7 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
break;
case WM_SOUND_OF_DESTRUCTION:
- md.damage = 1000 * skill_lv + sstatus->int_ * (sd ? pc->checkskill(sd,WM_LESSON) : 10);
+ md.damage = 1000 * (int64)skill_lv + sstatus->int_ * (sd ? pc->checkskill(sd,WM_LESSON) : 10);
md.damage += md.damage * 10 * battle->calc_chorusbonus(sd) / 100;
break;
/**
@@ -4011,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 ) {
@@ -4030,6 +4120,7 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
}
#endif
md.damage = battle->calc_cardfix(BF_MISC, src, target, nk, s_ele, 0, md.damage, 0, md.flag);
+ md.damage = battle->calc_cardfix2(src, target, md.damage, s_ele, nk, md.flag);
if(skill_id){
uint16 rskill;/* redirect skill id */
switch(skill_id){
@@ -4100,6 +4191,7 @@ void battle_calc_misc_attack_unknown(struct block_list *src, struct block_list *
/*==========================================
* battle_calc_weapon_attack (by Skotlex)
*------------------------------------------*/
+// FIXME: wflag is undocumented
struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list *target,uint16 skill_id,uint16 skill_lv,int wflag)
{
unsigned int skillratio = 100; //Skill dmg modifiers.
@@ -4128,6 +4220,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
unsigned weapon : 1; ///< It's a weapon attack (consider VVS, and all that)
#ifdef RENEWAL
unsigned tdef : 1; ///< Total defense reduction
+ unsigned distinct : 1; ///< Has its own battle calc formula
#endif
} flag;
@@ -4149,13 +4242,13 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
flag.infdef = 1; // Reverberation takes 1 damage
//Initial Values
- wd.type=0; //Normal attack
- wd.div_=skill_id?skill->get_num(skill_id,skill_lv):1;
+ wd.type = BDT_NORMAL;
+ wd.div_ = skill_id ? skill->get_num(skill_id,skill_lv) : 1;
wd.amotion=(skill_id && skill->get_inf(skill_id)&INF_GROUND_SKILL)?0:sstatus->amotion; //Amotion should be 0 for ground skills.
if(skill_id == KN_AUTOCOUNTER)
wd.amotion >>= 1;
wd.dmotion=tstatus->dmotion;
- wd.blewcount=skill->get_blewcount(skill_id,skill_lv);
+ wd.blewcount = skill_id ? skill->get_blewcount(skill_id,skill_lv) : 0;
wd.flag = BF_WEAPON; //Initial Flag
wd.flag |= (skill_id||wflag)?BF_SKILL:BF_NORMAL; // Baphomet card's splash damage is counted as a skill. [Inkfish]
wd.dmg_lv=ATK_DEF; //This assumption simplifies the assignation later
@@ -4216,7 +4309,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
case TF_DOUBLE: //For NPC used skill.
case GS_CHAINACTION:
- wd.type = 0x08;
+ wd.type = BDT_MULTIHIT;
break;
case GS_GROUNDDRIFT:
@@ -4255,13 +4348,28 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
if( tsc && (tsc->data[SC_WUGBITE] || tsc->data[SC_ANKLESNARE] || tsc->data[SC_ELECTRICSHOCKER]) )
wd.div_ = tstatus->size + 2 + ( (rnd()%100 < 50-tstatus->size*10) ? 1 : 0 );
break;
+
+ case NPC_EARTHQUAKE:
+ wd.flag = (wd.flag&~(BF_WEAPON)) | BF_MAGIC;
+ break;
#ifdef RENEWAL
+ case MO_EXTREMITYFIST:
+ case GS_PIERCINGSHOT:
+ case AM_ACIDTERROR:
+ case AM_DEMONSTRATION:
+ case NJ_ISSEN:
+ case PA_SACRIFICE:
+ flag.distinct = 1;
+ break;
+ case GN_CARTCANNON:
case PA_SHIELDCHAIN:
- case NJ_KUNAI:
- case HW_MAGICCRASHER:
- case NJ_SYURIKEN:
case GS_MAGICALBULLET:
+ case NJ_SYURIKEN:
case KO_BAKURETSU:
+ flag.distinct = 1;
+ /* Fall through */
+ case NJ_KUNAI:
+ case HW_MAGICCRASHER:
flag.tdef = 1;
break;
#endif
@@ -4270,15 +4378,15 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
wd.flag |= flag.arrow?BF_LONG:BF_SHORT;
if ((!skill_id || skill_id == PA_SACRIFICE) && tstatus->flee2 && rnd()%1000 < tstatus->flee2) {
//Check for Lucky Dodge
- wd.type=0x0b;
+ wd.type = BDT_PDODGE;
wd.dmg_lv=ATK_LUCKY;
if (wd.div_ < 0) wd.div_*=-1;
return wd;
}
- s_ele = s_ele_ = skill->get_ele(skill_id, skill_lv);
- if( !skill_id || s_ele == -1 )
- { //Take weapon's element
+ s_ele = s_ele_ = skill_id ? skill->get_ele(skill_id, skill_lv) : -1;
+ if (s_ele == -1) {
+ //Take weapon's element
s_ele = sstatus->rhw.ele;
s_ele_ = sstatus->lhw.ele;
if (sd && sd->charm_type != CHARM_TYPE_NONE && sd->charm_count >= MAX_SPIRITCHARM) {
@@ -4289,13 +4397,14 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
s_ele = sd->bonus.arrow_ele;
if( battle_config.attack_attr_none&src->type )
n_ele = true; //Weapon's element is "not elemental"
- }
- else if( s_ele == -2 ) //Use enchantment's element
+ } else if (s_ele == -2) {
+ //Use enchantment's element
s_ele = s_ele_ = status_get_attack_sc_element(src,sc);
- else if( s_ele == -3 ) //Use random element
+ } else if (s_ele == -3) {
+ //Use random element
s_ele = s_ele_ = rnd()%ELE_MAX;
- switch( skill_id )
- {
+ }
+ switch (skill_id) {
case GS_GROUNDDRIFT:
s_ele = s_ele_ = wflag; //element comes in flag.
break;
@@ -4337,13 +4446,13 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
if( rnd()%100 < ( 5*skill_lv > sd->bonus.double_rate ? 5*skill_lv : sc && sc->data[SC_KAGEMUSYA]?sc->data[SC_KAGEMUSYA]->val1*3:sd->bonus.double_rate ) )
{
wd.div_ = skill->get_num(TF_DOUBLE,skill_lv?skill_lv:1);
- wd.type = 0x08;
+ wd.type = BDT_MULTIHIT;
}
}
else if( sd->weapontype1 == W_REVOLVER && (skill_lv = pc->checkskill(sd,GS_CHAINACTION)) > 0 && rnd()%100 < 5*skill_lv )
{
wd.div_ = skill->get_num(GS_CHAINACTION,skill_lv);
- wd.type = 0x08;
+ wd.type = BDT_MULTIHIT;
}
else if(sc && sc->data[SC_FEARBREEZE] && sd->weapontype1==W_BOW
&& (i = sd->equip_index[EQI_AMMO]) >= 0 && sd->inventory_data[i] && sd->status.inventory[i].amount > 1){
@@ -4374,13 +4483,13 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
if ( wd.div_ > 1 ) {
wd.div_ = min(wd.div_, sd->status.inventory[i].amount);
sc->data[SC_FEARBREEZE]->val4 = wd.div_ - 1;
- wd.type = 0x08;
+ wd.type = BDT_MULTIHIT;
}
}
}
//Check for critical
- if( !flag.cri && !(wd.type&0x08) && sstatus->cri &&
+ if( !flag.cri && wd.type != BDT_MULTIHIT && sstatus->cri &&
(!skill_id ||
skill_id == KN_AUTOCOUNTER ||
skill_id == SN_SHARPSHOOTING || skill_id == MA_SHARPSHOOTING ||
@@ -4432,7 +4541,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
flag.cri = 1;
}
if (flag.cri) {
- wd.type = 0x0a;
+ wd.type = BDT_CRIT;
#ifndef RENEWAL
flag.idef = flag.idef2 =
#endif
@@ -4590,8 +4699,8 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
#define ATK_ADD( a ) do { int64 temp__ = (a); wd.damage += temp__; if (flag.lh) wd.damage2 += temp__; } while(0)
#define ATK_ADD2( a , b ) do { wd.damage += (a); if (flag.lh) wd.damage2 += (b); } while(0)
#ifdef RENEWAL
-#define GET_NORMAL_ATTACK( f ) ( wd.damage = battle->calc_base_damage(src, target, skill_id, skill_lv, nk, n_ele, s_ele, s_ele_, EQI_HAND_R, (f), wd.flag) )
-#define GET_NORMAL_ATTACK2( f ) ( wd.damage2 = battle->calc_base_damage(src, target, skill_id, skill_lv, nk, n_ele, s_ele, s_ele_, EQI_HAND_L, (f), wd.flag) )
+#define GET_NORMAL_ATTACK( f , s ) ( wd.damage = battle->calc_base_damage(src, target, s, skill_lv, nk, n_ele, s_ele, s_ele_, EQI_HAND_R, (f), wd.flag) )
+#define GET_NORMAL_ATTACK2( f , s ) ( wd.damage2 = battle->calc_base_damage(src, target, s, skill_lv, nk, n_ele, s_ele, s_ele_, EQI_HAND_L, (f), wd.flag) )
#endif
switch (skill_id) {
//Calc base damage according to skill
@@ -4610,7 +4719,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
{
short totaldef = status->get_total_def(target);
i = 0;
- GET_NORMAL_ATTACK( (sc && sc->data[SC_MAXIMIZEPOWER]?1:0)|(sc && sc->data[SC_WEAPONPERFECT]?8:0) );
+ GET_NORMAL_ATTACK( (sc && sc->data[SC_MAXIMIZEPOWER]?1:0)|(sc && sc->data[SC_WEAPONPERFECT]?8:0), 0 );
if( sc && sc->data[SC_NJ_BUNSINJYUTSU] && (i=sc->data[SC_NJ_BUNSINJYUTSU]->val2) > 0 )
wd.div_ = ~( i++ + 2 ) + 1;
if( wd.damage ){
@@ -4623,18 +4732,8 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
}
break;
case NJ_SYURIKEN: // [malufett]
- GET_NORMAL_ATTACK( (sc && sc->data[SC_MAXIMIZEPOWER]?1:0)|(sc && sc->data[SC_WEAPONPERFECT]?8:0) );
- wd.damage += battle->calc_masteryfix(src, target, skill_id, skill_lv, 4 * skill_lv + (sd ? sd->bonus.arrow_atk : 0), wd.div_, 0, flag.weapon);
- break;
- case MO_EXTREMITYFIST: // [malufett]
- {
- short totaldef = status->get_total_def(target);
- GET_NORMAL_ATTACK( (sc && sc->data[SC_MAXIMIZEPOWER]?1:0)|8 );
- if( wd.damage ){
- wd.damage = (250 + 150 * skill_lv) + (10 * (status_get_sp(src)+1) * wd.damage / 100) + (8 * wd.damage);
- ATK_ADD(-totaldef);
- }
- }
+ GET_NORMAL_ATTACK( (sc && sc->data[SC_MAXIMIZEPOWER]?1:0)|(sc && sc->data[SC_WEAPONPERFECT]?8:0), 0);
+ ATK_ADD(battle->calc_masteryfix(src, target, skill_id, skill_lv, 4 * skill_lv + (sd ? sd->bonus.arrow_atk : 0), wd.div_, 0, flag.weapon));
#endif
break;
#ifndef RENEWAL
@@ -4710,11 +4809,13 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
i |= 16; // for ex. shuriken must not be influenced by DEX
}
#ifdef RENEWAL
- GET_NORMAL_ATTACK( i );
+ GET_NORMAL_ATTACK( i, skill_id);
wd.damage = battle->calc_masteryfix(src, target, skill_id, skill_lv, wd.damage, wd.div_, 0, flag.weapon);
+ wd.damage = battle->calc_cardfix2(src, target, wd.damage, s_ele, nk, wd.flag);
if (flag.lh){
- GET_NORMAL_ATTACK2( i );
+ GET_NORMAL_ATTACK2( i, skill_id );
wd.damage2 = battle->calc_masteryfix(src, target, skill_id, skill_lv, wd.damage2, wd.div_, 1, flag.weapon);
+ wd.damage2 = battle->calc_cardfix2(src, target, wd.damage2, s_ele, nk, wd.flag);
}
#else
wd.damage = battle->calc_base_damage2(sstatus, &sstatus->rhw, sc, tstatus->size, sd, i);
@@ -4730,8 +4831,10 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
//Add any bonuses that modify the base baseatk+watk (pre-skills)
if(sd) {
+#ifndef RENEWAL
if (sd->bonus.atk_rate)
ATK_ADDRATE(sd->bonus.atk_rate);
+#endif
if(flag.cri && sd->bonus.crit_atk_rate)
ATK_ADDRATE(sd->bonus.crit_atk_rate);
if(flag.cri && sc && sc->data[SC_MTF_CRIDAMAGE])
@@ -4775,7 +4878,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
case KO_BAKURETSU:
{
#ifdef RENEWAL
- GET_NORMAL_ATTACK((sc && sc->data[SC_MAXIMIZEPOWER] ? 1 : 0) | (sc && sc->data[SC_WEAPONPERFECT] ? 8 : 0));
+ GET_NORMAL_ATTACK((sc && sc->data[SC_MAXIMIZEPOWER] ? 1 : 0) | (sc && sc->data[SC_WEAPONPERFECT] ? 8 : 0), skill_id);
#endif
skillratio = skill_lv * (50 + status_get_dex(src) / 4);
skillratio = (int)(skillratio * (sd ? pc->checkskill(sd, NJ_TOBIDOUGU) : 10) * 40.f / 100.0f * status->get_lv(src) / 120);
@@ -4784,7 +4887,32 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
break;
#ifdef RENEWAL
+ case GS_MAGICALBULLET:
+ GET_NORMAL_ATTACK((sc && sc->data[SC_MAXIMIZEPOWER] ? 1 : 0) | (sc && sc->data[SC_WEAPONPERFECT] ? 8 : 0), skill_id);
+ ATK_ADD(battle->attr_fix(src, target,
+ battle->calc_cardfix(BF_MAGIC, src, target, nk, s_ele, 0, status->get_matk(src, 2), 0, wd.flag), ELE_NEUTRAL, tstatus->def_ele, tstatus->ele_lv));
+ break;
+ case GS_PIERCINGSHOT:
+ GET_NORMAL_ATTACK((sc && sc->data[SC_MAXIMIZEPOWER] ? 1 : 0) | (sc && sc->data[SC_WEAPONPERFECT] ? 8 : 0), 0);
+ if ( wd.damage ) {
+ if ( sd && sd->weapontype1 == W_RIFLE )
+ ATK_RATE(30 * (skill_lv + 5));
+ else
+ ATK_RATE(20 * (skill_lv + 5));
+ }
+ break;
+ case MO_EXTREMITYFIST: // [malufett]
+ {
+ short totaldef = status->get_total_def(target);
+ GET_NORMAL_ATTACK((sc && sc->data[SC_MAXIMIZEPOWER] ? 1 : 0) | 8, skill_id);
+ if ( wd.damage ) {
+ ATK_ADD(250 * (skill_lv + 1) + (10 * (status_get_sp(src) + 1) * wd.damage / 100) + (8 * wd.damage));
+ ATK_ADD(-totaldef);
+ }
+ }
+ break;
case PA_SHIELDCHAIN:
+ GET_NORMAL_ATTACK((sc && sc->data[SC_MAXIMIZEPOWER] ? 1 : 0) | (sc && sc->data[SC_WEAPONPERFECT] ? 8 : 0), skill_id);
if ( sd ) {
short index = sd->equip_index[EQI_HAND_L];
if ( index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_ARMOR ) {
@@ -4794,6 +4922,32 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
ATK_ADD(sstatus->rhw.atk2); //Else use Atk2
ATK_RATE(battle->calc_skillratio(BF_WEAPON, src, target, skill_id, skill_lv, skillratio, wflag));
break;
+ case AM_DEMONSTRATION:
+ case AM_ACIDTERROR: // [malufett/Hercules]
+ {
+ int64 matk;
+ int totaldef = status->get_total_def(target) + status->get_total_mdef(target);
+ matk = battle->calc_cardfix(BF_MAGIC, src, target, nk, s_ele, 0, status->get_matk(src, 2), 0, wd.flag);
+ matk = battle->attr_fix(src, target, matk, ELE_NEUTRAL, tstatus->def_ele, tstatus->ele_lv);
+ matk = matk * battle->calc_skillratio(BF_WEAPON, src, target, skill_id, skill_lv, skillratio, wflag) / 100;
+ GET_NORMAL_ATTACK((sc && sc->data[SC_MAXIMIZEPOWER] ? 1 : 0) | (sc && sc->data[SC_WEAPONPERFECT] ? 8 : 0), 0);
+ ATK_RATE(battle->calc_skillratio(BF_WEAPON, src, target, skill_id, skill_lv, skillratio, wflag));
+ ATK_ADD(matk);
+ ATK_ADD(-totaldef);
+ if ( skill_id == AM_ACIDTERROR && is_boss(target) )
+ ATK_RATE(50);
+ if ( skill_id == AM_DEMONSTRATION )
+ wd.damage = max(wd.damage, 1);
+ }
+ break;
+ case GN_CARTCANNON:
+ GET_NORMAL_ATTACK((sc && sc->data[SC_MAXIMIZEPOWER] ? 1 : 0) | (sc && sc->data[SC_WEAPONPERFECT] ? 8 : 0), skill_id);
+ ATK_ADD(sd ? sd->bonus.arrow_atk : 0);
+ wd.damage = battle->calc_masteryfix(src, target, skill_id, skill_lv, wd.damage, wd.div_, 0, flag.weapon);
+ ATK_RATE(battle->calc_skillratio(BF_WEAPON, src, target, skill_id, skill_lv, skillratio, wflag));
+ if ( sd && s_ele != sd->bonus.arrow_ele )
+ s_ele = sd->bonus.arrow_ele;
+ break;
case NJ_TATAMIGAESHI:
ATK_RATE(200);
/* Fall through */
@@ -4801,7 +4955,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
case ML_SPIRALPIERCE: // [malufett]
if( skill_id != NJ_TATAMIGAESHI ){
short index = sd?sd->equip_index[EQI_HAND_R]:0;
- GET_NORMAL_ATTACK( (sc && sc->data[SC_MAXIMIZEPOWER]?1:0)|(sc && sc->data[SC_WEAPONPERFECT]?8:0) );
+ GET_NORMAL_ATTACK( (sc && sc->data[SC_MAXIMIZEPOWER]?1:0)|(sc && sc->data[SC_WEAPONPERFECT]?8:0), 0);
wd.damage = wd.damage * 70 / 100;
//n_ele = true; // FIXME: This is has no effect if it's after GET_NORMAL_ATTACK (was this intended, or was it supposed to be put above?)
@@ -4818,6 +4972,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
ATK_RATE(85);
}
wd.damage = battle->calc_masteryfix(src, target, skill_id, skill_lv, wd.damage, wd.div_, 0, flag.weapon);
+ wd.damage = battle->calc_cardfix2(src, target, wd.damage, s_ele, nk, wd.flag);
}
/* Fall through */
#endif
@@ -4845,13 +5000,11 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
if(sd && sd->weapontype1 == W_FIST && sd->weapontype2 == W_FIST)
ATK_ADD(10*pc->checkskill(sd, TK_RUN));
break;
- case GS_MAGICALBULLET:
+
#ifndef RENEWAL
+ case GS_MAGICALBULLET:
ATK_ADD( status->get_matk(src, 2) );
-#else
- ATK_ADD( battle->calc_magic_attack(src, target, skill_id, skill_lv, wflag).damage );
-#endif
-#ifndef RENEWAL
+ break;
case NJ_SYURIKEN:
ATK_ADD(4*skill_lv);
#endif
@@ -4886,15 +5039,15 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
}
break;
case SR_GATEOFHELL:
- ATK_ADD (sstatus->max_hp - status_get_hp(src));
- if(sc && sc->data[SC_COMBOATTACK] && sc->data[SC_COMBOATTACK]->val1 == SR_FALLENEMPIRE) {
- ATK_ADD( (sstatus->max_sp * (1 + skill_lv * 2 / 10)) + 40 * status->get_lv(src) );
+ ATK_ADD(sstatus->max_hp - status_get_hp(src));
+ if ( sc && sc->data[SC_COMBOATTACK] && sc->data[SC_COMBOATTACK]->val1 == SR_FALLENEMPIRE ) {
+ ATK_ADD((sstatus->max_sp * (1 + skill_lv * 2 / 10)) + 40 * status->get_lv(src));
} else {
- ATK_ADD( (sstatus->sp * (1 + skill_lv * 2 / 10)) + 10 * status->get_lv(src) );
+ ATK_ADD((sstatus->sp * (1 + skill_lv * 2 / 10)) + 10 * status->get_lv(src));
}
break;
case SR_FALLENEMPIRE:// [(Target Size value + Skill Level - 1) x Caster STR] + [(Target current weight x Caster DEX / 120)]
- ATK_ADD( ((tstatus->size+1)*2 + skill_lv - 1) * sstatus->str);
+ ATK_ADD( ((tstatus->size+1)*2 + (int64)skill_lv - 1) * sstatus->str);
if( tsd && tsd->weight ){
ATK_ADD( (tsd->weight/10) * sstatus->dex / 120 );
}else{
@@ -5045,7 +5198,11 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
}
}
- if(!flag.idef || !flag.idef2) { //Defense reduction
+ if((!flag.idef || !flag.idef2)
+#ifdef RENEWAL
+ && (!flag.distinct || flag.tdef)
+#endif
+ ) { //Defense reduction
wd.damage = battle->calc_defense(BF_WEAPON, src, target, skill_id, skill_lv, wd.damage,
(flag.idef?1:0)|(flag.pdef?2:0)
#ifdef RENEWAL
@@ -5062,8 +5219,19 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
}
#ifdef RENEWAL
+ if ( flag.distinct ) {
+ wd.damage = battle->calc_cardfix2(src, target, wd.damage, s_ele, nk, wd.flag);
+ if ( flag.lh ) {
+ wd.damage2 = battle->calc_cardfix2(src, target, wd.damage2, s_ele, nk, wd.flag);
+ }
+ }
//Div fix.
damage_div_fix(wd.damage, wd.div_);
+ if ( skill_id > 0 && (skill->get_ele(skill_id, skill_lv) == ELE_NEUTRAL || flag.distinct) ) { // re-evaluate forced neutral skills
+ wd.damage = battle->attr_fix(src, target, wd.damage, s_ele, tstatus->def_ele, tstatus->ele_lv);
+ if ( flag.lh )
+ wd.damage2 = battle->attr_fix(src, target, wd.damage2, s_ele_, tstatus->def_ele, tstatus->ele_lv);
+ }
#endif
#if 0 // Can't find any source about this one even in eagis
if (skill_id == NPC_EARTHQUAKE) {
@@ -5146,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 ) {
@@ -5187,11 +5355,12 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
ATK_ADD(10*sd->status.inventory[index].refine);
}
}
-#endif
//Card Fix, tsd side
- if(tsd){ //if player on player then it was already measured above
- wd.damage = battle->calc_cardfix(BF_WEAPON, src, target, nk, s_ele, s_ele_, wd.damage, (flag.lh?1:0), wd.flag);
+ if ( tsd ) { //if player on player then it was already measured above
+ wd.damage = battle->calc_cardfix(BF_WEAPON, src, target, nk, s_ele, s_ele_, wd.damage, (flag.lh ? 1 : 0), wd.flag);
}
+#endif
+
if( flag.infdef ) { //Plants receive 1 damage when hit
short class_ = status->get_class(target);
if( flag.hit || wd.damage > 0 )
@@ -5370,7 +5539,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
rnd()%100 < tsc->data[SC_SWORDREJECT]->val2
) {
ATK_RATER(50);
- status_fix_damage(target,src,wd.damage,clif->damage(target,src,0,0,wd.damage,0,0,0));
+ status_fix_damage(target,src,wd.damage,clif->damage(target,src,0,0,wd.damage,0,BDT_NORMAL,0));
clif->skill_nodamage(target,target,ST_REJECTSWORD,tsc->data[SC_SWORDREJECT]->val1,1);
if( --(tsc->data[SC_SWORDREJECT]->val3) <= 0 )
status_change_end(target, SC_SWORDREJECT, INVALID_TIMER);
@@ -5476,8 +5645,8 @@ void battle_reflect_damage(struct block_list *target, struct block_list *src, st
rdamage = ratio + (damage)* (10 + sc->data[SC_CRESCENTELBOW]->val1 * 20 / 10) / 10;
skill->blown(target, src, skill->get_blewcount(SR_CRESCENTELBOW_AUTOSPELL, sc->data[SC_CRESCENTELBOW]->val1), unit->getdir(src), 0);
clif->skill_damage(target, src, tick, status_get_amotion(src), 0, rdamage,
- 1, SR_CRESCENTELBOW_AUTOSPELL, sc->data[SC_CRESCENTELBOW]->val1, 6); // This is how official does
- clif->delay_damage(tick + delay, src, target,status_get_amotion(src)+1000,0, rdamage/10, 1, 0);
+ 1, SR_CRESCENTELBOW_AUTOSPELL, sc->data[SC_CRESCENTELBOW]->val1, BDT_SKILL); // This is how official does
+ clif->delay_damage(tick + delay, src, target,status_get_amotion(src)+1000,0, rdamage/10, 1, BDT_NORMAL);
status->damage(src, target, status->damage(target, src, rdamage, 0, 0, 1)/10, 0, 0, 1);
status_change_end(target, SC_CRESCENTELBOW, INVALID_TIMER);
/* shouldn't this trigger skill->additional_effect? */
@@ -5495,7 +5664,7 @@ void battle_reflect_damage(struct block_list *target, struct block_list *src, st
int64 rd1 = damage * sc->data[SC_DEATHBOUND]->val2 / 100; // Amplify damage.
trdamage += rdamage = rd1 - (damage = rd1 * 30 / 100); // not normalized as intended.
- rdelay = clif->skill_damage(src, target, tick, status_get_amotion(src), status_get_dmotion(src), -3000, 1, RK_DEATHBOUND, sc->data[SC_DEATHBOUND]->val1, 6);
+ rdelay = clif->skill_damage(src, target, tick, status_get_amotion(src), status_get_dmotion(src), -3000, 1, RK_DEATHBOUND, sc->data[SC_DEATHBOUND]->val1, BDT_SKILL);
skill->blown(target, src, skill->get_blewcount(RK_DEATHBOUND, sc->data[SC_DEATHBOUND]->val1), unit->getdir(src), 0);
if( tsd ) /* is this right? rdamage as both left and right? */
@@ -5522,7 +5691,7 @@ void battle_reflect_damage(struct block_list *target, struct block_list *src, st
if ( tsd && tsd->bonus.short_weapon_damage_return ) {
NORMALIZE_RDAMAGE(damage * tsd->bonus.short_weapon_damage_return / 100);
- rdelay = clif->delay_damage(tick+delay,src, src, status_get_amotion(src), status_get_dmotion(src), rdamage, 1, 4);
+ rdelay = clif->delay_damage(tick+delay,src, src, status_get_amotion(src), status_get_dmotion(src), rdamage, 1, BDT_ENDURE);
/* is this right? rdamage as both left and right? */
battle->drain(tsd, src, rdamage, rdamage, status_get_race(src), 0);
@@ -5547,9 +5716,9 @@ void battle_reflect_damage(struct block_list *target, struct block_list *src, st
NORMALIZE_RDAMAGE(damage * sc->data[SC_REFLECTSHIELD]->val2 / 100);
#ifndef RENEWAL
- rdelay = clif->delay_damage(tick+delay,src, src, status_get_amotion(src), status_get_dmotion(src), rdamage, 1, 4);
+ rdelay = clif->delay_damage(tick+delay,src, src, status_get_amotion(src), status_get_dmotion(src), rdamage, 1, BDT_ENDURE);
#else
- rdelay = clif->skill_damage(src, src, tick, delay, status_get_dmotion(src), rdamage, 1, CR_REFLECTSHIELD, 1, 4);
+ rdelay = clif->skill_damage(src, src, tick, delay, status_get_dmotion(src), rdamage, 1, CR_REFLECTSHIELD, 1, BDT_ENDURE);
#endif
/* is this right? rdamage as both left and right? */
if( tsd )
@@ -5583,7 +5752,7 @@ void battle_reflect_damage(struct block_list *target, struct block_list *src, st
if( sc->data[SC_SHIELDSPELL_DEF] && sc->data[SC_SHIELDSPELL_DEF]->val1 == 2 ){
NORMALIZE_RDAMAGE(damage * sc->data[SC_SHIELDSPELL_DEF]->val2 / 100);
- rdelay = clif->delay_damage(tick+delay,src, src, status_get_amotion(src), status_get_dmotion(src), rdamage, 1, 4);
+ rdelay = clif->delay_damage(tick+delay,src, src, status_get_amotion(src), status_get_dmotion(src), rdamage, 1, BDT_ENDURE);
/* is this right? rdamage as both left and right? */
if( tsd )
@@ -5597,7 +5766,7 @@ void battle_reflect_damage(struct block_list *target, struct block_list *src, st
if( ssc->data[SC_INSPIRATION] ) {
NORMALIZE_RDAMAGE(damage / 100);
- rdelay = clif->delay_damage(tick+delay,target, target, status_get_amotion(target), status_get_dmotion(target), rdamage, 1, 4);
+ rdelay = clif->delay_damage(tick+delay,target, target, status_get_amotion(target), status_get_dmotion(target), rdamage, 1, BDT_ENDURE);
/* is this right? rdamage as both left and right? */
if( sd )
@@ -5612,7 +5781,7 @@ void battle_reflect_damage(struct block_list *target, struct block_list *src, st
if ( tsd && tsd->bonus.long_weapon_damage_return ) {
NORMALIZE_RDAMAGE(damage * tsd->bonus.long_weapon_damage_return / 100);
- rdelay = clif->delay_damage(tick+delay,src, src, status_get_amotion(src), status_get_dmotion(src), rdamage, 1, 4);
+ rdelay = clif->delay_damage(tick+delay,src, src, status_get_amotion(src), status_get_dmotion(src), rdamage, 1, BDT_ENDURE);
/* is this right? rdamage as both left and right? */
battle->drain(tsd, src, rdamage, rdamage, status_get_race(src), 0);
@@ -5707,7 +5876,7 @@ int battle_damage_area(struct block_list *bl, va_list ap) {
battle->delay_damage(tick, amotion,src,bl,0,CR_REFLECTSHIELD,0,damage,ATK_DEF,0,true);
else
status_fix_damage(src,bl,damage,0);
- clif->damage(bl,bl,amotion,dmotion,damage,1,ATK_BLOCK,0);
+ clif->damage(bl,bl,amotion,dmotion,damage,1,BDT_ENDURE,0);
if( !(src->type == BL_PC && ((TBL_PC*)src)->state.autocast) )
skill->additional_effect(src, bl, CR_REFLECTSHIELD, 1, BF_WEAPON|BF_SHORT|BF_NORMAL,ATK_DEF,tick);
map->freeblock_unlock();
@@ -5718,6 +5887,7 @@ int battle_damage_area(struct block_list *bl, va_list ap) {
/*==========================================
* Do a basic physical attack (call trough unit_attack_timer)
*------------------------------------------*/
+// FIXME: flag is undocumented
enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* target, int64 tick, int flag) {
struct map_session_data *sd = NULL, *tsd = NULL;
struct status_data *sstatus, *tstatus;
@@ -5753,10 +5923,10 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
{
int index = sd->equip_index[EQI_AMMO];
if (index<0) {
- if (sd->weapontype1 > W_KATAR && sd->weapontype1 < W_HUUMA)
- clif->arrow_fail(sd, 0);
- else
+ if ( sd->weapontype1 > W_KATAR && sd->weapontype1 < W_HUUMA )
clif->skill_fail(sd, 0, USESKILL_FAIL_NEED_MORE_BULLET, 0);
+ else
+ clif->arrow_fail(sd, 0);
return ATK_NONE;
}
//Ammo check by Ishizu-chan
@@ -5799,7 +5969,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
if(dist <= 0 || (!map->check_dir(dir,t_dir) && dist <= tstatus->rhw.range+1)) {
uint16 skill_lv = tsc->data[SC_AUTOCOUNTER]->val1;
clif->skillcastcancel(target); //Remove the casting bar. [Skotlex]
- clif->damage(src, target, sstatus->amotion, 1, 0, 1, 0, 0); //Display MISS.
+ clif->damage(src, target, sstatus->amotion, 1, 0, 1, BDT_NORMAL, 0); //Display MISS.
status_change_end(target, SC_AUTOCOUNTER, INVALID_TIMER);
skill->attack(BF_WEAPON,target,target,src,KN_AUTOCOUNTER,skill_lv,tick,0);
return ATK_BLOCK;
@@ -5812,7 +5982,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
status_change_end(target, SC_BLADESTOP_WAIT, INVALID_TIMER);
if(sc_start4(target, src, SC_BLADESTOP, 100, sd?pc->checkskill(sd, MO_BLADESTOP):5, 0, 0, target->id, duration)) {
//Target locked.
- clif->damage(src, target, sstatus->amotion, 1, 0, 1, 0, 0); //Display MISS.
+ clif->damage(src, target, sstatus->amotion, 1, 0, 1, BDT_NORMAL, 0); //Display MISS.
clif->bladestop(target, src->id, 1);
sc_start4(target, target, SC_BLADESTOP, 100, skill_lv, 0, 0, src->id, duration);
return ATK_BLOCK;
@@ -5856,18 +6026,6 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
return ATK_DEF;
return ATK_MISS;
}
- if( sc->data[SC_GENTLETOUCH_ENERGYGAIN] ) {
- if( sd && rnd()%100 < 10 + 5 * sc->data[SC_GENTLETOUCH_ENERGYGAIN]->val1)
- pc->addspiritball(sd,
- skill->get_time(MO_CALLSPIRITS, sc->data[SC_GENTLETOUCH_ENERGYGAIN]->val1),
- sc->data[SC_GENTLETOUCH_ENERGYGAIN]->val1);
- }
- if( tsc && tsc->data[SC_GENTLETOUCH_ENERGYGAIN] ) {
- if( tsd && rnd()%100 < 10 + 5 * tsc->data[SC_GENTLETOUCH_ENERGYGAIN]->val1)
- pc->addspiritball(tsd,
- skill->get_time(MO_CALLSPIRITS, tsc->data[SC_GENTLETOUCH_ENERGYGAIN]->val1),
- tsc->data[SC_GENTLETOUCH_ENERGYGAIN]->val1);
- }
if( tsc && tsc->data[SC_MTF_MLEATKED] && rnd()%100 < 20 )
clif->skill_nodamage(target, target, SM_ENDURE, 5,
@@ -5890,7 +6048,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
}
if( sd && sc->data[SC_FEARBREEZE] && sc->data[SC_FEARBREEZE]->val4 > 0 && sd->status.inventory[sd->equip_index[EQI_AMMO]].amount >= sc->data[SC_FEARBREEZE]->val4 && battle_config.arrow_decrement){
- pc->delitem(sd,sd->equip_index[EQI_AMMO],sc->data[SC_FEARBREEZE]->val4,0,1,LOG_TYPE_CONSUME);
+ pc->delitem(sd, sd->equip_index[EQI_AMMO], sc->data[SC_FEARBREEZE]->val4, 0, DELITEM_SKILLUSE, LOG_TYPE_CONSUME);
sc->data[SC_FEARBREEZE]->val4 = 0;
}
}
@@ -5938,7 +6096,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
(d_bl->type == BL_PC && ((TBL_PC*)d_bl)->devotion[sce->val2] == target->id)
) && check_distance_bl(target, d_bl, sce->val3) )
{
- clif->damage(d_bl, d_bl, 0, 0, damage, 0, 0, 0);
+ clif->damage(d_bl, d_bl, 0, 0, damage, 0, BDT_NORMAL, 0);
status_fix_damage(NULL, d_bl, damage, 0);
}
else
@@ -5946,7 +6104,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
} else if( tsc->data[SC_CIRCLE_OF_FIRE_OPTION] && (wd.flag&BF_SHORT) && target->type == BL_PC ) {
struct elemental_data *ed = ((TBL_PC*)target)->ed;
if( ed ) {
- clif->skill_damage(&ed->bl, target, tick, status_get_amotion(src), 0, -30000, 1, EL_CIRCLE_OF_FIRE, tsc->data[SC_CIRCLE_OF_FIRE_OPTION]->val1, 6);
+ clif->skill_damage(&ed->bl, target, tick, status_get_amotion(src), 0, -30000, 1, EL_CIRCLE_OF_FIRE, tsc->data[SC_CIRCLE_OF_FIRE_OPTION]->val1, BDT_SKILL);
skill->attack(BF_MAGIC,&ed->bl,&ed->bl,src,EL_CIRCLE_OF_FIRE,tsc->data[SC_CIRCLE_OF_FIRE_OPTION]->val1,tick,wd.flag);
}
} else if( tsc->data[SC_WATER_SCREEN_OPTION] && tsc->data[SC_WATER_SCREEN_OPTION]->val1 ) {
@@ -6215,21 +6373,28 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
}
break;
case BL_MOB:
- if(((((TBL_MOB*)target)->special_state.ai == 2 || //Marine Spheres
- (((TBL_MOB*)target)->special_state.ai == 3 && battle_config.summon_flora&1)) && //Floras
- s_bl->type == BL_PC && src->type != BL_MOB) || (((TBL_MOB*)target)->special_state.ai == 4 && t_bl->id != s_bl->id)) //Zanzoe
- {
+ {
+ TBL_MOB *md = BL_CAST(BL_MOB, target);
+ if((
+ (md->special_state.ai == AI_SPHERE || (md->special_state.ai == AI_FLORA && battle_config.summon_flora&1))
+ && s_bl->type == BL_PC && src->type != BL_MOB
+ )
+ || (md->special_state.ai == AI_ZANZOU && t_bl->id != s_bl->id)
+ ) {
//Targetable by players
state |= BCT_ENEMY;
strip_enemy = 0;
}
break;
+ }
case BL_SKILL:
{
TBL_SKILL *su = (TBL_SKILL*)target;
if( !su->group )
return 0;
- if( skill->get_inf2(su->group->skill_id)&INF2_TRAP && su->group->unit_id != UNT_USED_TRAPS) { //Only a few skills can target traps...
+ if( skill->get_inf2(su->group->skill_id)&INF2_TRAP &&
+ su->group->unit_id != UNT_USED_TRAPS &&
+ su->group->unit_id != UNT_NETHERWORLD ) { //Only a few skills can target traps...
switch( battle->get_current_skill(src) ) {
case RK_DRAGONBREATH:// it can only hit traps in pvp/gvg maps
case RK_DRAGONBREATH_WATER:
@@ -6367,8 +6532,8 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
) {
if( t_bl->type == BL_PC && (sd->duel_group == ((TBL_PC*)t_bl)->duel_group) )
return (BCT_ENEMY&flag)?1:-1; // Duel targets can ONLY be your enemy, nothing else.
- else
- return 0; // You can't target anything out of your duel
+ else if ( src->type != BL_SKILL || (flag&BCT_ENEMY) )
+ return 0;
}
}
if( map_flag_gvg(m) && !sd->status.guild_id && t_bl->type == BL_MOB && ((TBL_MOB*)t_bl)->class_ == MOBID_EMPERIUM )
@@ -6384,19 +6549,16 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
&& md->guardian_data && (md->guardian_data->g || md->guardian_data->castle->guild_id) )
return 0; // Disable guardians/emperium owned by Guilds on non-woe times.
- if( !md->special_state.ai )
- { //Normal mobs
- if(
- ( target->type == BL_MOB && t_bl->type == BL_PC && ( ((TBL_MOB*)target)->special_state.ai != 4 && ((TBL_MOB*)target)->special_state.ai != 1 ) ) ||
- ( t_bl->type == BL_MOB && !((TBL_MOB*)t_bl)->special_state.ai )
- )
+ if (md->special_state.ai == AI_NONE) {
+ //Normal mobs
+ struct mob_data *target_md = BL_CAST(BL_MOB, target);
+ if( (target_md && t_bl->type == BL_PC && target_md->special_state.ai != AI_ZANZOU && target_md->special_state.ai != AI_ATTACK)
+ || (t_bl->type == BL_MOB && !((TBL_MOB*)t_bl)->special_state.ai) )
state |= BCT_PARTY; //Normal mobs with no ai are friends.
else
state |= BCT_ENEMY; //However, all else are enemies.
- }
- else
- {
- if( t_bl->type == BL_MOB && !((TBL_MOB*)t_bl)->special_state.ai )
+ } else {
+ if (t_bl->type == BL_MOB && ((TBL_MOB*)t_bl)->special_state.ai == AI_NONE)
state |= BCT_ENEMY; //Natural enemy for AI mobs are normal mobs.
}
break;
@@ -7287,6 +7449,7 @@ void battle_defaults(void) {
battle->attr_ratio = battle_attr_ratio;
battle->attr_fix = battle_attr_fix;
battle->calc_cardfix = battle_calc_cardfix;
+ battle->calc_cardfix2 = battle_calc_cardfix2;
battle->calc_elefix = battle_calc_elefix;
battle->calc_masteryfix = battle_calc_masteryfix;
battle->calc_chorusbonus = battle_calc_chorusbonus;
diff --git a/src/map/battle.h b/src/map/battle.h
index 233c325cf..6bc2659b9 100644
--- a/src/map/battle.h
+++ b/src/map/battle.h
@@ -5,8 +5,8 @@
#ifndef MAP_BATTLE_H
#define MAP_BATTLE_H
-#include "map.h" //ELE_MAX
-#include "../common/cbasetypes.h"
+#include "map/map.h" //ELE_MAX
+#include "common/cbasetypes.h"
/**
* Declarations
@@ -77,6 +77,27 @@ enum e_battle_check_target { //New definitions [Skotlex]
};
/**
+ * Values used by (struct Damage).type, as well as clif->damage(type) and clif->skill_damage(type)
+ *
+ * Note: some values may not apply in some contexts.
+ */
+enum battle_dmg_type {
+ BDT_NORMAL = 0, // Normal attack
+ //BDT_PICKUP = 1, // Pick up item
+ //BDT_SITDOWN = 2, // Sit down
+ //BDT_STANDUP = 3, // Stand up
+ BDT_ENDURE = 4, // Damage (endure)
+ BDT_SPLASH = 5, // Splash
+ BDT_SKILL = 6, // Skill
+ //BDT_REPEAT = 7, // (repeat damage?)
+ BDT_MULTIHIT = 8, // Multi-hit damage
+ BDT_MULTIENDURE = 9, // Multi-hit damage (endure)
+ BDT_CRIT = 10, // Critical hit
+ BDT_PDODGE = 11, // Lucky dodge
+ //BDT_TOUCH = 12, // (touch skill?)
+};
+
+/**
* Structures
**/
@@ -558,6 +579,7 @@ struct battle_interface {
int64 (*attr_fix) (struct block_list *src, struct block_list *target, int64 damage, int atk_elem, int def_type, int def_lv);
/* applies card modifiers */
int64 (*calc_cardfix) (int attack_type, struct block_list *src, struct block_list *target, int nk, int s_ele, int s_ele_, int64 damage, int left, int flag);
+ int64 (*calc_cardfix2) (struct block_list *src, struct block_list *bl, int64 damage, int s_ele, int nk, int flag);
/* applies element modifiers */
int64 (*calc_elefix) (struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, int64 damage, int nk, int n_ele, int s_ele, int s_ele_, bool left, int flag);
/* applies mastery modifiers */
diff --git a/src/map/battleground.c b/src/map/battleground.c
index 2d4ba6bf1..0fe42110f 100644
--- a/src/map/battleground.c
+++ b/src/map/battleground.c
@@ -6,29 +6,31 @@
#include "battleground.h"
+#include "map/battle.h"
+#include "map/clif.h"
+#include "map/guild.h"
+#include "map/homunculus.h"
+#include "map/map.h"
+#include "map/mapreg.h"
+#include "map/mercenary.h"
+#include "map/mob.h" // struct mob_data
+#include "map/npc.h"
+#include "map/party.h"
+#include "map/pc.h"
+#include "map/pet.h"
+#include "common/cbasetypes.h"
+#include "common/conf.h"
+#include "common/HPM.h"
+#include "common/malloc.h"
+#include "common/nullpo.h"
+#include "common/showmsg.h"
+#include "common/socket.h"
+#include "common/strlib.h"
+#include "common/timer.h"
+
#include <stdio.h>
#include <string.h>
-#include "battle.h"
-#include "clif.h"
-#include "homunculus.h"
-#include "map.h"
-#include "mapreg.h"
-#include "mercenary.h"
-#include "mob.h" // struct mob_data
-#include "npc.h"
-#include "party.h"
-#include "pc.h"
-#include "pet.h"
-#include "../common/cbasetypes.h"
-#include "../common/conf.h"
-#include "../common/malloc.h"
-#include "../common/nullpo.h"
-#include "../common/showmsg.h"
-#include "../common/socket.h"
-#include "../common/strlib.h"
-#include "../common/timer.h"
-
struct battleground_interface bg_s;
/// Search a BG Team using bg_id
@@ -210,7 +212,7 @@ int bg_team_get_id(struct block_list *bl) {
{
struct map_session_data *msd;
struct mob_data *md = (TBL_MOB*)bl;
- if( md->special_state.ai && (msd = map->id2sd(md->master_id)) != NULL )
+ if (md->special_state.ai != AI_NONE && (msd = map->id2sd(md->master_id)) != NULL)
return msd->bg_id;
return md->bg_id;
}
@@ -537,11 +539,10 @@ void bg_match_over(struct bg_arena *arena, bool canceled) {
bg->team_leave(sd, 0);
bg->queue_pc_cleanup(sd);
}
- if( canceled )
- clif->colormes(sd->fd,COLOR_RED,"BG Match Canceled: not enough players");
- else {
+ if (canceled)
+ clif->messagecolor_self(sd->fd, COLOR_RED, "BG Match Canceled: not enough players");
+ else
pc_setglobalreg(sd, script->add_str(arena->delay_var), (unsigned int)time(NULL));
- }
}
}
@@ -765,7 +766,7 @@ enum BATTLEGROUNDS_QUEUE_ACK bg_canqueue(struct map_session_data *sd, struct bg_
sprintf(response, "You are a deserter! Wait %d minute(s) before you can apply again",(tick-tsec)/60);
else
sprintf(response, "You are a deserter! Wait %d seconds before you can apply again",(tick-tsec));
- clif->colormes(sd->fd,COLOR_RED,response);
+ clif->messagecolor_self(sd->fd, COLOR_RED, response);
return BGQA_FAIL_DESERTER;
}
@@ -775,7 +776,7 @@ enum BATTLEGROUNDS_QUEUE_ACK bg_canqueue(struct map_session_data *sd, struct bg_
sprintf(response, "You can't reapply to this arena so fast. Apply to the different arena or wait %d minute(s)",(tick-tsec)/60);
else
sprintf(response, "You can't reapply to this arena so fast. Apply to the different arena or wait %d seconds",(tick-tsec));
- clif->colormes(sd->fd,COLOR_RED,response);
+ clif->messagecolor_self(sd->fd, COLOR_RED, response);
return BGQA_FAIL_COOLDOWN;
}
@@ -799,7 +800,7 @@ enum BATTLEGROUNDS_QUEUE_ACK bg_canqueue(struct map_session_data *sd, struct bg_
sprintf(response, "Can't apply: not enough members in your team/guild that have not entered the queue in individual mode, minimum is %d",arena->min_team_players);
else
sprintf(response, "Can't apply: not enough members in your team/guild, minimum is %d",arena->min_team_players);
- clif->colormes(sd->fd,COLOR_RED,response);
+ clif->messagecolor_self(sd->fd, COLOR_RED, response);
return BGQA_FAIL_TEAM_COUNT;
}
}
@@ -831,7 +832,7 @@ enum BATTLEGROUNDS_QUEUE_ACK bg_canqueue(struct map_session_data *sd, struct bg_
sprintf(response, "Can't apply: not enough members in your team/party that have not entered the queue in individual mode, minimum is %d",arena->min_team_players);
else
sprintf(response, "Can't apply: not enough members in your team/party, minimum is %d",arena->min_team_players);
- clif->colormes(sd->fd,COLOR_RED,response);
+ clif->messagecolor_self(sd->fd, COLOR_RED, response);
return BGQA_FAIL_TEAM_COUNT;
}
} else
@@ -856,9 +857,27 @@ void do_init_battleground(bool minimal) {
bg->config_read();
}
+/**
+ * @see DBApply
+ */
+int bg_team_db_final(DBKey key, DBData *data, va_list ap) {
+ struct battleground_data* bgd = DB->data2ptr(data);
+ int i;
+ for(i = 0; i < bgd->hdatac; i++ ) {
+ if( bgd->hdata[i]->flag.free ) {
+ aFree(bgd->hdata[i]->data);
+ }
+ aFree(bgd->hdata[i]);
+ }
+ if( bgd->hdata )
+ aFree(bgd->hdata);
+
+ return 0;
+}
+
void do_final_battleground(void)
{
- db_destroy(bg->team_db);
+ bg->team_db->destroy(bg->team_db,bg->team_db_final);
if (bg->arena) {
int i;
@@ -868,6 +887,7 @@ void do_final_battleground(void)
}
aFree(bg->arena);
}
+
}
void battleground_defaults(void) {
bg = &bg_s;
@@ -911,6 +931,7 @@ void battleground_defaults(void) {
bg->send_xy_timer_sub = bg_send_xy_timer_sub;
bg->send_xy_timer = bg_send_xy_timer;
bg->afk_timer = bg_afk_timer;
+ bg->team_db_final = bg_team_db_final;
/* */
bg->str2teamtype = bg_str2teamtype;
/* */
diff --git a/src/map/battleground.h b/src/map/battleground.h
index 9878d6be0..a67deb722 100644
--- a/src/map/battleground.h
+++ b/src/map/battleground.h
@@ -5,9 +5,14 @@
#ifndef MAP_BATTLEGROUND_H
#define MAP_BATTLEGROUND_H
-#include "clif.h"
-#include "guild.h"
-#include "../common/mmo.h" // struct party
+#include "map/map.h" // EVENT_NAME_LENGTH
+#include "common/cbasetypes.h"
+#include "common/db.h"
+#include "common/mmo.h" // struct party
+
+struct HPluginData;
+struct block_list;
+struct map_session_data;
/**
* Defines
@@ -48,6 +53,9 @@ struct battleground_data {
// Logout Event
char logout_event[EVENT_NAME_LENGTH];
char die_event[EVENT_NAME_LENGTH];
+ /* HPM Custom Struct */
+ struct HPluginData **hdata;
+ unsigned int hdatac;
};
struct bg_arena {
@@ -112,6 +120,7 @@ struct battleground_interface {
int (*send_xy_timer_sub) (DBKey key, DBData *data, va_list ap);
int (*send_xy_timer) (int tid, int64 tick, int id, intptr_t data);
int (*afk_timer) (int tid, int64 tick, int id, intptr_t data);
+ int (*team_db_final) (DBKey key, DBData *data, va_list ap);
/* */
enum bg_queue_types (*str2teamtype) (const char *str);
/* */
diff --git a/src/map/buyingstore.c b/src/map/buyingstore.c
index 85fef98aa..d1ce4ba0d 100644
--- a/src/map/buyingstore.c
+++ b/src/map/buyingstore.c
@@ -4,19 +4,19 @@
#define HERCULES_CORE
-#include "buyingstore.h" // struct s_buyingstore
-
-#include "atcommand.h" // msg_txt
-#include "battle.h" // battle_config.*
-#include "chrif.h"
-#include "clif.h" // clif->buyingstore_*
-#include "log.h" // log_pick_pc, log_zeny
-#include "pc.h" // struct map_session_data
-#include "../common/cbasetypes.h"
-#include "../common/db.h" // ARR_FIND
-#include "../common/showmsg.h" // ShowWarning
-#include "../common/socket.h" // RBUF*
-#include "../common/strlib.h" // safestrncpy
+#include "buyingstore.h" // struct s_buyingstore
+
+#include "map/atcommand.h" // msg_txt
+#include "map/battle.h" // battle_config.*
+#include "map/chrif.h"
+#include "map/clif.h" // clif-"buyingstore_*
+#include "map/log.h" // log_pick_pc, log_zeny
+#include "map/pc.h" // struct map_session_data
+#include "common/cbasetypes.h"
+#include "common/db.h" // ARR_FIND
+#include "common/showmsg.h" // ShowWarning
+#include "common/socket.h" // RBUF*
+#include "common/strlib.h" // safestrncpy
struct buyingstore_interface buyingstore_s;
@@ -353,7 +353,7 @@ void buyingstore_trade(struct map_session_data* sd, int account_id, unsigned int
// move item
pc->additem(pl_sd, &sd->status.inventory[index], amount, LOG_TYPE_BUYING_STORE);
- pc->delitem(sd, index, amount, 1, 0, LOG_TYPE_BUYING_STORE);
+ pc->delitem(sd, index, amount, 1, DELITEM_NORMAL, LOG_TYPE_BUYING_STORE);
pl_sd->buyingstore.items[listidx].amount-= amount;
// pay up
diff --git a/src/map/buyingstore.h b/src/map/buyingstore.h
index 7b8e369d2..f23790459 100644
--- a/src/map/buyingstore.h
+++ b/src/map/buyingstore.h
@@ -5,8 +5,8 @@
#ifndef MAP_BUYINGSTORE_H
#define MAP_BUYINGSTORE_H
-#include "../common/cbasetypes.h"
-#include "../common/mmo.h" // MAX_SLOTS
+#include "common/cbasetypes.h"
+#include "common/mmo.h" // MAX_SLOTS
struct map_session_data;
diff --git a/src/map/channel.c b/src/map/channel.c
index 0704bf706..69f7ab872 100644
--- a/src/map/channel.c
+++ b/src/map/channel.c
@@ -5,28 +5,28 @@
#include "channel.h"
+#include "map/atcommand.h"
+#include "map/guild.h"
+#include "map/instance.h"
+#include "map/irc-bot.h"
+#include "map/map.h"
+#include "map/pc.h"
+#include "common/cbasetypes.h"
+#include "common/conf.h"
+#include "common/db.h"
+#include "common/malloc.h"
+#include "common/nullpo.h"
+#include "common/random.h"
+#include "common/showmsg.h"
+#include "common/socket.h"
+#include "common/strlib.h"
+#include "common/timer.h"
+#include "common/utils.h"
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include "atcommand.h"
-#include "guild.h"
-#include "instance.h"
-#include "irc-bot.h"
-#include "map.h"
-#include "pc.h"
-#include "../common/cbasetypes.h"
-#include "../common/conf.h"
-#include "../common/db.h"
-#include "../common/malloc.h"
-#include "../common/nullpo.h"
-#include "../common/random.h"
-#include "../common/showmsg.h"
-#include "../common/socket.h"
-#include "../common/strlib.h"
-#include "../common/timer.h"
-#include "../common/utils.h"
-
struct channel_interface channel_s;
static struct Channel_Config channel_config;
@@ -258,7 +258,7 @@ void channel_send(struct channel_data *chan, struct map_session_data *sd, const
if (sd && chan->msg_delay != 0
&& DIFF_TICK(sd->hchsysch_tick + chan->msg_delay*1000, timer->gettick()) > 0
&& !pc_has_permission(sd, PC_PERM_HCHSYS_ADMIN)) {
- clif->colormes(sd->fd,COLOR_RED,msg_sd(sd,1455));
+ clif->messagecolor_self(sd->fd, COLOR_RED, msg_sd(sd,1455));
return;
} else if (sd) {
snprintf(message, 150, "[ #%s ] %s : %s",chan->name,sd->status.name, msg);
@@ -352,7 +352,7 @@ enum channel_operation_status channel_join(struct channel_data *chan, struct map
} else {
sprintf(output, msg_sd(sd,1403), chan->name); // You're now in the '%s' channel
}
- clif->colormes(sd->fd, COLOR_DEFAULT, output);
+ clif->messagecolor_self(sd->fd, COLOR_DEFAULT, output);
}
if (chan->type == HCS_TYPE_ALLY) {
@@ -477,6 +477,17 @@ void channel_map_join(struct map_session_data *sd)
channel->join(map->list[sd->bl.m].channel, sd, NULL, false);
}
+void channel_irc_join(struct map_session_data *sd)
+{
+ struct channel_data *chan = ircbot->channel;
+ if (sd->state.autotrade || sd->state.standalone)
+ return;
+ if (channel->config->irc_name[0] == '\0')
+ return;
+ if (chan)
+ channel->join(chan, sd, NULL, false);
+}
+
/**
* Lets a guild's members join a newly allied guild's channel.
*
@@ -574,7 +585,8 @@ void read_channels_config(void)
int ally_enabled = 0, local_enabled = 0,
local_autojoin = 0, ally_autojoin = 0,
allow_user_channel_creation = 0,
- irc_enabled = 0;
+ irc_enabled = 0,
+ irc_autojoin = 0;
if( !libconfig->setting_lookup_string(settings, "map_local_channel_name", &local_name) )
local_name = "map";
@@ -655,11 +667,14 @@ void read_channels_config(void)
libconfig->setting_lookup_bool(settings, "map_local_channel_autojoin", &local_autojoin);
libconfig->setting_lookup_bool(settings, "ally_channel_autojoin", &ally_autojoin);
+ libconfig->setting_lookup_bool(settings, "irc_channel_autojoin", &irc_autojoin);
if (local_autojoin)
channel->config->local_autojoin = true;
if (ally_autojoin)
channel->config->ally_autojoin = true;
+ if (irc_autojoin)
+ channel->config->irc_autojoin = true;
libconfig->setting_lookup_bool(settings, "allow_user_channel_creation", &allow_user_channel_creation);
@@ -678,7 +693,6 @@ void read_channels_config(void)
safestrncpy(channel->config->colors_name[i], config_setting_name(color), HCS_NAME_LENGTH);
channel->config->colors[i] = (unsigned int)strtoul(libconfig->setting_get_string_elem(colors,i),NULL,0);
- channel->config->colors[i] = (channel->config->colors[i] & 0x0000FF) << 16 | (channel->config->colors[i] & 0x00FF00) | (channel->config->colors[i] & 0xFF0000) >> 16;//RGB to BGR
}
channel->config->colors_count = color_count;
}
@@ -768,7 +782,7 @@ int do_init_channel(bool minimal)
return 0;
channel->db = stridb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, HCS_NAME_LENGTH);
- channel->config->ally = channel->config->local = channel->config->irc = channel->config->ally_autojoin = channel->config->local_autojoin = false;
+ channel->config->ally = channel->config->local = channel->config->irc = channel->config->ally_autojoin = channel->config->local_autojoin = channel->config->irc_autojoin = false;
channel->config_read();
return 0;
@@ -828,6 +842,7 @@ void channel_defaults(void)
channel->guild_join_alliance = channel_guild_join_alliance;
channel->guild_leave_alliance = channel_guild_leave_alliance;
channel->quit_guild = channel_quit_guild;
+ channel->irc_join = channel_irc_join;
channel->config_read = read_channels_config;
}
diff --git a/src/map/channel.h b/src/map/channel.h
index ba6aafc79..de1779d96 100644
--- a/src/map/channel.h
+++ b/src/map/channel.h
@@ -4,11 +4,9 @@
#ifndef MAP_CHANNEL_H
#define MAP_CHANNEL_H
-#include <stdarg.h>
-
-#include "map.h"
-#include "../common/cbasetypes.h"
-#include "../common/db.h"
+#include "common/cbasetypes.h"
+#include "common/db.h"
+#include "common/mmo.h"
/**
* Declarations
@@ -51,7 +49,7 @@ struct Channel_Config {
char **colors_name;
unsigned char colors_count;
bool local, ally, irc;
- bool local_autojoin, ally_autojoin;
+ bool local_autojoin, ally_autojoin, irc_autojoin;
char local_name[HCS_NAME_LENGTH], ally_name[HCS_NAME_LENGTH], irc_name[HCS_NAME_LENGTH];
unsigned char local_color, ally_color, irc_color;
bool closing;
@@ -106,6 +104,7 @@ struct channel_interface {
void (*guild_join_alliance) (const struct guild *g_source, const struct guild *g_ally);
void (*guild_leave_alliance) (const struct guild *g_source, const struct guild *g_ally);
void (*quit_guild) (struct map_session_data *sd);
+ void (*irc_join) (struct map_session_data *sd);
void (*config_read) (void);
};
diff --git a/src/map/chat.c b/src/map/chat.c
index a232781ca..08c904290 100644
--- a/src/map/chat.c
+++ b/src/map/chat.c
@@ -6,23 +6,23 @@
#include "chat.h"
+#include "map/atcommand.h" // msg_sd(sd,)
+#include "map/battle.h" // struct battle_config
+#include "map/clif.h"
+#include "map/map.h"
+#include "map/npc.h" // npc_event_do()
+#include "map/pc.h"
+#include "map/skill.h" // ext_skill_unit_onplace()
+#include "common/cbasetypes.h"
+#include "common/malloc.h"
+#include "common/mmo.h"
+#include "common/nullpo.h"
+#include "common/showmsg.h"
+#include "common/strlib.h"
+
#include <stdio.h>
#include <string.h>
-#include "atcommand.h" // msg_sd(sd,)
-#include "battle.h" // struct battle_config
-#include "clif.h"
-#include "map.h"
-#include "npc.h" // npc_event_do()
-#include "pc.h"
-#include "skill.h" // ext_skill_unit_onplace()
-#include "../common/cbasetypes.h"
-#include "../common/malloc.h"
-#include "../common/mmo.h"
-#include "../common/nullpo.h"
-#include "../common/showmsg.h"
-#include "../common/strlib.h"
-
struct chat_interface chat_s;
/// Initializes a chatroom object (common functionality for both pc and npc chatrooms).
@@ -93,7 +93,7 @@ bool chat_createpcchat(struct map_session_data* sd, const char* title, const cha
return false;
}
- pc_stop_walking(sd,1);
+ pc_stop_walking(sd, STOPWALKING_FLAG_FIXPOS);
cd = chat->create(&sd->bl, title, pass, limit, pub, 0, "", 0, 1, MAX_LEVEL);
if( cd ) {
@@ -101,7 +101,7 @@ bool chat_createpcchat(struct map_session_data* sd, const char* title, const cha
cd->usersd[0] = sd;
pc_setchatid(sd,cd->bl.id);
pc_stop_attack(sd);
- clif->createchat(sd,0);
+ clif->createchat(sd,0); // 0 = success
clif->dispchat(cd,0);
return true;
}
@@ -150,7 +150,7 @@ bool chat_joinchat(struct map_session_data* sd, int chatid, const char* pass) {
return false;
}
- pc_stop_walking(sd,1);
+ pc_stop_walking(sd, STOPWALKING_FLAG_FIXPOS);
cd->usersd[cd->users] = sd;
cd->users++;
@@ -339,7 +339,7 @@ bool chat_kickchat(struct map_session_data* sd, const char* kickusername) {
idb_iput(cd->kick_list,cd->usersd[i]->status.char_id,1);
- chat->leave(cd->usersd[i],1);
+ chat->leave(cd->usersd[i], true);
return true;
}
@@ -440,7 +440,7 @@ bool chat_npckickall(struct chat_data* cd)
nullpo_ret(cd);
while( cd->users > 0 )
- chat->leave(cd->usersd[cd->users-1],0);
+ chat->leave(cd->usersd[cd->users-1], false);
return true;
}
diff --git a/src/map/chat.h b/src/map/chat.h
index ced216b41..31048d5dd 100644
--- a/src/map/chat.h
+++ b/src/map/chat.h
@@ -5,9 +5,9 @@
#ifndef MAP_CHAT_H
#define MAP_CHAT_H
-#include "map.h" // struct block_list, CHATROOM_TITLE_SIZE
-#include "../common/cbasetypes.h"
-#include "../common/db.h"
+#include "map/map.h" // struct block_list, CHATROOM_TITLE_SIZE
+#include "common/cbasetypes.h"
+#include "common/db.h"
struct chat_data;
struct map_session_data;
diff --git a/src/map/chrif.c b/src/map/chrif.c
index da946f050..5bd1e436f 100644
--- a/src/map/chrif.c
+++ b/src/map/chrif.c
@@ -4,39 +4,38 @@
#define HERCULES_CORE
-#include "../config/core.h" // AUTOTRADE_PERSISTENCY, STATS_OPT_OUT
+#include "config/core.h" // AUTOTRADE_PERSISTENCY, STATS_OPT_OUT
#include "chrif.h"
+#include "map/battle.h"
+#include "map/clif.h"
+#include "map/elemental.h"
+#include "map/guild.h"
+#include "map/homunculus.h"
+#include "map/instance.h"
+#include "map/intif.h"
+#include "map/map.h"
+#include "map/mercenary.h"
+#include "map/npc.h"
+#include "map/pc.h"
+#include "map/pet.h"
+#include "map/quest.h"
+#include "map/skill.h"
+#include "map/status.h"
+#include "map/storage.h"
+#include "common/HPM.h"
+#include "common/cbasetypes.h"
+#include "common/ers.h"
+#include "common/malloc.h"
+#include "common/nullpo.h"
+#include "common/showmsg.h"
+#include "common/socket.h"
+#include "common/strlib.h"
+#include "common/timer.h"
+
#include <stdio.h>
#include <stdlib.h>
-#include <string.h>
#include <sys/types.h>
-#include <time.h>
-
-#include "map.h"
-#include "battle.h"
-#include "clif.h"
-#include "intif.h"
-#include "npc.h"
-#include "pc.h"
-#include "pet.h"
-#include "skill.h"
-#include "status.h"
-#include "homunculus.h"
-#include "instance.h"
-#include "mercenary.h"
-#include "elemental.h"
-#include "quest.h"
-#include "storage.h"
-#include "../common/HPM.h"
-#include "../common/cbasetypes.h"
-#include "../common/ers.h"
-#include "../common/malloc.h"
-#include "../common/nullpo.h"
-#include "../common/showmsg.h"
-#include "../common/socket.h"
-#include "../common/strlib.h"
-#include "../common/timer.h"
struct chrif_interface chrif_s;
@@ -62,7 +61,7 @@ struct chrif_interface chrif_s;
//2b0a: Incoming/Outgoing, socket_datasync()
//2b0b: Outgoing, update charserv skillid2idx
//2b0c: Outgoing, chrif_changeemail -> 'change mail address ...'
-//2b0d: Incoming, chrif_changedsex -> 'Change sex of acc XY'
+//2b0d: Incoming, chrif_changedsex -> 'Change sex of acc XY' (or char)
//2b0e: Outgoing, chrif_char_ask_name -> 'Do some operations (change sex, ban / unban etc)'
//2b0f: Incoming, chrif_char_ask_name_answer -> 'answer of the 2b0e'
//2b10: Outgoing, chrif_updatefamelist -> 'Update the fame ranking lists and send them'
@@ -247,6 +246,7 @@ int chrif_isconnected(void) {
* Flag = 1: Character is quitting
* Flag = 2: Character is changing map-servers
*------------------------------------------*/
+// TODO: Flag enum
bool chrif_save(struct map_session_data *sd, int flag) {
nullpo_ret(sd);
@@ -263,11 +263,11 @@ bool chrif_save(struct map_session_data *sd, int flag) {
chrif_check(false); //Character is saved on reconnect.
//For data sync
- if (sd->state.storage_flag == 2)
+ if (sd->state.storage_flag == STORAGE_FLAG_GUILD)
gstorage->save(sd->status.account_id, sd->status.guild_id, flag);
if (flag)
- sd->state.storage_flag = 0; //Force close it.
+ sd->state.storage_flag = STORAGE_FLAG_CLOSED; //Force close it.
//Saving of registry values.
if (sd->vars_dirty)
@@ -401,7 +401,7 @@ bool chrif_changemapserverack(int account_id, int login_id1, int login_id2, int
if ( !login_id1 ) {
ShowError("chrif_changemapserverack: map server change failed.\n");
- clif->authfail_fd(node->fd, 0);
+ clif->authfail_fd(node->fd, 0); // Disconnected from server
} else
clif->changemapserver(node->sd, map_index, x, y, ntohl(ip), ntohs(port));
@@ -465,7 +465,7 @@ int chrif_reconnect(DBKey key, DBData *data, va_list ap) {
if( map->mapname2ipport(sd->mapindex,&ip,&port) == 0 )
chrif->changemapserver(sd, ip, port);
else //too much lag/timeout is the closest explanation for this error.
- clif->authfail_fd(sd->fd, 3);
+ clif->authfail_fd(sd->fd, 3); // timeout
break;
}
}
@@ -643,7 +643,7 @@ void chrif_authfail(int fd) {/* HELLO WORLD. ip in RFIFOL 15 is not being used (
node->sex == sex &&
node->state == ST_LOGIN )
{// found a match
- clif->authfail_fd(node->fd, 0);
+ clif->authfail_fd(node->fd, 0); // Disconnected from server
chrif->auth_delete(account_id, char_id, ST_LOGIN);
}
}
@@ -744,10 +744,18 @@ bool chrif_changeemail(int id, const char *actual_email, const char *new_email)
}
/*==========================================
- * S 2b0e <accid>.l <name>.24B <type>.w { <year>.w <month>.w <day>.w <hour>.w <minute>.w <second>.w }
+ * S 2b0e <accid>.l <name>.24B <type>.w { <additional fields>.12B }
+ * { <year>.w <month>.w <day>.w <hour>.w <minute>.w <second>.w }
* Send an account modification request to the login server (via char server).
- * type of operation:
- * 1: block, 2: ban, 3: unblock, 4: unban, 5: changesex (use next function for 5), 6: charban
+ * type of operation: @see enum zh_char_ask_name
+ * block { n/a }
+ * ban { <year>.w <month>.w <day>.w <hour>.w <minute>.w <second>.w }
+ * unblock { n/a }
+ * unban { n/a }
+ * changesex { n/a } -- use chrif_changesex
+ * charban { <year>.w <month>.w <day>.w <hour>.w <minute>.w <second>.w }
+ * charunban { n/a }
+ * changecharsex { <sex>.b } -- use chrif_changesex
*------------------------------------------*/
bool chrif_char_ask_name(int acc, const char* character_name, unsigned short operation_type, int year, int month, int day, int hour, int minute, int second)
{
@@ -759,7 +767,7 @@ bool chrif_char_ask_name(int acc, const char* character_name, unsigned short ope
safestrncpy((char*)WFIFOP(chrif->fd,6), character_name, NAME_LENGTH);
WFIFOW(chrif->fd,30) = operation_type;
- if ( operation_type == 2 || operation_type == 6 ) {
+ if (operation_type == CHAR_ASK_NAME_BAN || operation_type == CHAR_ASK_NAME_CHARBAN) {
WFIFOW(chrif->fd,32) = year;
WFIFOW(chrif->fd,34) = month;
WFIFOW(chrif->fd,36) = day;
@@ -772,14 +780,24 @@ bool chrif_char_ask_name(int acc, const char* character_name, unsigned short ope
return true;
}
-bool chrif_changesex(struct map_session_data *sd) {
+/**
+ * Requests a sex change (either per character or per account).
+ *
+ * @param sd The character's data.
+ * @param change_account Whether to change the per-account sex.
+ * @retval true.
+ */
+bool chrif_changesex(struct map_session_data *sd, bool change_account)
+{
chrif_check(false);
WFIFOHEAD(chrif->fd,44);
WFIFOW(chrif->fd,0) = 0x2b0e;
WFIFOL(chrif->fd,2) = sd->status.account_id;
safestrncpy((char*)WFIFOP(chrif->fd,6), sd->status.name, NAME_LENGTH);
- WFIFOW(chrif->fd,30) = 5;
+ WFIFOW(chrif->fd,30) = change_account ? CHAR_ASK_NAME_CHANGESEX : CHAR_ASK_NAME_CHANGECHARSEX;
+ if (!change_account)
+ WFIFOB(chrif->fd,32) = sd->status.sex == SEX_MALE ? SEX_FEMALE : SEX_MALE;
WFIFOSET(chrif->fd,44);
clif->message(sd->fd, msg_sd(sd,408)); //"Disconnecting to perform change-sex request..."
@@ -794,19 +812,14 @@ bool chrif_changesex(struct map_session_data *sd) {
/*==========================================
* R 2b0f <accid>.l <name>.24B <type>.w <answer>.w
* Processing a reply to chrif->char_ask_name() (request to modify an account).
- * type of operation:
- * 1: block, 2: ban, 3: unblock, 4: unban, 5: changesex, 6: charban, 7: charunban
- * type of answer:
- * 0: login-server request done
- * 1: player not found
- * 2: gm level too low
- * 3: login-server offline
+ * type of operation: @see chrif_char_ask_name
+ * type of answer: @see hz_char_ask_name_answer
*------------------------------------------*/
bool chrif_char_ask_name_answer(int acc, const char* player_name, uint16 type, uint16 answer) {
struct map_session_data* sd;
char action[25];
char output[256];
- bool charsrv = ( type == 6 || type == 7 ) ? true : false;
+ bool charsrv = ( type == CHAR_ASK_NAME_CHARBAN || type == CHAR_ASK_NAME_CHARUNBAN ) ? true : false;
sd = map->id2sd(acc);
@@ -816,19 +829,19 @@ bool chrif_char_ask_name_answer(int acc, const char* player_name, uint16 type, u
}
/* re-use previous msg_number */
- if( type == 6 ) type = 2;
- if( type == 7 ) type = 4;
+ if( type == CHAR_ASK_NAME_CHARBAN ) type = CHAR_ASK_NAME_BAN;
+ if( type == CHAR_ASK_NAME_CHARUNBAN ) type = CHAR_ASK_NAME_UNBAN;
- if( type > 0 && type <= 5 )
+ if( type >= CHAR_ASK_NAME_BLOCK && type <= CHAR_ASK_NAME_CHANGESEX )
snprintf(action,25,"%s",msg_sd(sd,427+type)); //block|ban|unblock|unban|change the sex of
else
snprintf(action,25,"???");
switch( answer ) {
- case 0 : sprintf(output, msg_sd(sd,charsrv?434:424), action, NAME_LENGTH, player_name); break;
- case 1 : sprintf(output, msg_sd(sd,425), NAME_LENGTH, player_name); break;
- case 2 : sprintf(output, msg_sd(sd,426), action, NAME_LENGTH, player_name); break;
- case 3 : sprintf(output, msg_sd(sd,427), action, NAME_LENGTH, player_name); break;
+ case CHAR_ASK_NAME_ANS_DONE: sprintf(output, msg_sd(sd,charsrv?434:424), action, NAME_LENGTH, player_name); break;
+ case CHAR_ASK_NAME_ANS_NOTFOUND: sprintf(output, msg_sd(sd,425), NAME_LENGTH, player_name); break;
+ case CHAR_ASK_NAME_ANS_GMLOW: sprintf(output, msg_sd(sd,426), action, NAME_LENGTH, player_name); break;
+ case CHAR_ASK_NAME_ANS_OFFLINE: sprintf(output, msg_sd(sd,427), action, NAME_LENGTH, player_name); break;
default: output[0] = '\0'; break;
}
@@ -847,8 +860,11 @@ void chrif_changedsex(int fd) {
ShowNotice("chrif_changedsex %d.\n", acc);
// Path to activate this response:
- // Map(start) (0x2b0e) -> Char(0x2727) -> Login
+ // Map(start) (0x2b0e type 5) -> Char(0x2727) -> Login
// Login(0x2723) [ALL] -> Char (0x2b0d)[ALL] -> Map (HERE)
+ // OR
+ // Map(start) (0x2b03 type 8) -> Char
+ // Char(0x2b0d)[ALL] -> Map (HERE)
// Char will usually be "logged in" despite being forced to log-out in the beginning
// of this process, but there's no need to perform map-server specific response
// as everything should been changed through char-server [Panikon]
@@ -883,14 +899,14 @@ bool chrif_divorceack(int char_id, int partner_id) {
sd->status.partner_id = 0;
for(i = 0; i < MAX_INVENTORY; i++)
if (sd->status.inventory[i].nameid == WEDDING_RING_M || sd->status.inventory[i].nameid == WEDDING_RING_F)
- pc->delitem(sd, i, 1, 0, 0, LOG_TYPE_OTHER);
+ pc->delitem(sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_OTHER);
}
if( ( sd = map->charid2sd(partner_id) ) != NULL && sd->status.partner_id == char_id ) {
sd->status.partner_id = 0;
for(i = 0; i < MAX_INVENTORY; i++)
if (sd->status.inventory[i].nameid == WEDDING_RING_M || sd->status.inventory[i].nameid == WEDDING_RING_F)
- pc->delitem(sd, i, 1, 0, 0, LOG_TYPE_OTHER);
+ pc->delitem(sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_OTHER);
}
return true;
@@ -1305,8 +1321,8 @@ void chrif_skillid2idx(int fd) {
WFIFOHEAD(fd,4 + (MAX_SKILL * 4));
WFIFOW(fd,0) = 0x2b0b;
for(i = 0; i < MAX_SKILL; i++) {
- if( skill->db[i].nameid ) {
- WFIFOW(fd, 4 + (count*4)) = skill->db[i].nameid;
+ if( skill->dbs->db[i].nameid ) {
+ WFIFOW(fd, 4 + (count*4)) = skill->dbs->db[i].nameid;
WFIFOW(fd, 6 + (count*4)) = i;
count++;
}
diff --git a/src/map/chrif.h b/src/map/chrif.h
index 271fc076d..cac965f74 100644
--- a/src/map/chrif.h
+++ b/src/map/chrif.h
@@ -5,12 +5,12 @@
#ifndef MAP_CHRIF_H
#define MAP_CHRIF_H
-#include <time.h>
-
-#include "map.h" //TBL_stuff
-#include "../common/cbasetypes.h"
-#include "../common/db.h"
+#include "map/map.h" //TBL_PC
+#include "common/cbasetypes.h"
+#include "common/db.h"
+struct eri;
+struct map_session_data;
struct status_change_entry;
/**
@@ -103,7 +103,7 @@ struct chrif_interface {
bool (*char_reset_offline) (void);
bool (*send_users_tochar) (void);
bool (*char_online) (struct map_session_data *sd);
- bool (*changesex) (struct map_session_data *sd);
+ bool (*changesex) (struct map_session_data *sd, bool change_account);
//int (*chardisconnect) (struct map_session_data *sd); // FIXME: Commented out in clif.c, function does not exist
bool (*divorce) (int partner_id1, int partner_id2);
diff --git a/src/map/clif.c b/src/map/clif.c
index 029080958..d00cac0ee 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -4,60 +4,60 @@
#define HERCULES_CORE
-#include "../config/core.h" // ANTI_MAYAP_CHEAT, RENEWAL, SECURE_NPCTIMEOUT
+#include "config/core.h" // ANTI_MAYAP_CHEAT, RENEWAL, SECURE_NPCTIMEOUT
#include "clif.h"
+#include "map/atcommand.h"
+#include "map/battle.h"
+#include "map/battleground.h"
+#include "map/channel.h"
+#include "map/chat.h"
+#include "map/chrif.h"
+#include "map/elemental.h"
+#include "map/guild.h"
+#include "map/homunculus.h"
+#include "map/instance.h"
+#include "map/intif.h"
+#include "map/irc-bot.h"
+#include "map/itemdb.h"
+#include "map/log.h"
+#include "map/mail.h"
+#include "map/map.h"
+#include "map/mercenary.h"
+#include "map/mob.h"
+#include "map/npc.h"
+#include "map/party.h"
+#include "map/pc.h"
+#include "map/pet.h"
+#include "map/quest.h"
+#include "map/script.h"
+#include "map/skill.h"
+#include "map/status.h"
+#include "map/storage.h"
+#include "map/trade.h"
+#include "map/unit.h"
+#include "map/vending.h"
+#include "common/HPM.h"
+#include "common/cbasetypes.h"
+#include "common/conf.h"
+#include "common/ers.h"
+#include "common/grfio.h"
+#include "common/malloc.h"
+#include "common/mmo.h" // NEW_CARTS
+#include "common/nullpo.h"
+#include "common/random.h"
+#include "common/showmsg.h"
+#include "common/socket.h"
+#include "common/strlib.h"
+#include "common/timer.h"
+#include "common/utils.h"
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <time.h>
-#include "atcommand.h"
-#include "battle.h"
-#include "battleground.h"
-#include "channel.h"
-#include "chat.h"
-#include "chrif.h"
-#include "elemental.h"
-#include "guild.h"
-#include "homunculus.h"
-#include "instance.h"
-#include "intif.h"
-#include "irc-bot.h"
-#include "itemdb.h"
-#include "log.h"
-#include "mail.h"
-#include "map.h"
-#include "mercenary.h"
-#include "mob.h"
-#include "npc.h"
-#include "party.h"
-#include "pc.h"
-#include "pet.h"
-#include "quest.h"
-#include "script.h"
-#include "skill.h"
-#include "status.h"
-#include "storage.h"
-#include "trade.h"
-#include "unit.h"
-#include "vending.h"
-#include "../common/HPM.h"
-#include "../common/cbasetypes.h"
-#include "../common/conf.h"
-#include "../common/ers.h"
-#include "../common/grfio.h"
-#include "../common/malloc.h"
-#include "../common/mmo.h" // NEW_CARTS
-#include "../common/nullpo.h"
-#include "../common/random.h"
-#include "../common/showmsg.h"
-#include "../common/socket.h"
-#include "../common/strlib.h"
-#include "../common/timer.h"
-#include "../common/utils.h"
-
struct clif_interface clif_s;
/* re-usable */
@@ -688,6 +688,7 @@ void clif_authrefuse(int fd, uint8 error_code)
/// 109 = BAN_INVALID_PWD_CNT
/// 110 = BAN_NOT_ALLOWED_JOBCLASS
/// ? = disconnected -> MsgStringTable[3]
+// TODO: type enum
void clif_authfail_fd(int fd, int type)
{
if (!fd || !session[fd] || session[fd]->func_parse != clif->parse) //clif_authfail should only be invoked on players!
@@ -1369,7 +1370,7 @@ bool clif_spawn(struct block_list *bl)
if( sd->bg_id && map->list[sd->bl.m].flag.battleground )
clif->sendbgemblem_area(sd);
for( i = 0; i < sd->sc_display_count; i++ ) {
- clif->sc_load(&sd->bl, sd->bl.id,AREA,status->IconChangeTable[sd->sc_display[i]->type],sd->sc_display[i]->val1,sd->sc_display[i]->val2,sd->sc_display[i]->val3);
+ clif->sc_load(&sd->bl, sd->bl.id,AREA,status->dbs->IconChangeTable[sd->sc_display[i]->type],sd->sc_display[i]->val1,sd->sc_display[i]->val2,sd->sc_display[i]->val3);
}
if (sd->charm_type != CHARM_TYPE_NONE && sd->charm_count > 0)
clif->spiritcharm(sd);
@@ -1520,19 +1521,24 @@ void clif_homskillinfoblock(struct map_session_data *sd) {
WFIFOHEAD(fd, 4+37*MAX_HOMUNSKILL);
WFIFOW(fd,0)=0x235;
- for ( i = 0; i < MAX_HOMUNSKILL; i++){
+ for ( i = 0; i < MAX_HOMUNSKILL; i++ ) {
int id = hd->homunculus.hskill[i].id;
- if (id != 0) {
+ if ( id != 0 ) {
j = id - HM_SKILLBASE;
- WFIFOW(fd,len ) = id;
- WFIFOW(fd,len+2) = skill->get_inf(id);
- WFIFOW(fd,len+4) = 0;
- WFIFOW(fd,len+6) = hd->homunculus.hskill[j].lv;
- WFIFOW(fd,len+8) = skill->get_sp(id,hd->homunculus.hskill[j].lv);
- WFIFOW(fd,len+10)= skill->get_range2(&sd->hd->bl, id,hd->homunculus.hskill[j].lv);
- safestrncpy((char*)WFIFOP(fd,len+12), skill->get_name(id), NAME_LENGTH);
- WFIFOB(fd,len+36) = (hd->homunculus.hskill[j].lv < homun->skill_tree_get_max(id, hd->homunculus.class_))?1:0;
- len+=37;
+ WFIFOW(fd, len) = id;
+ WFIFOW(fd, len + 2) = skill->get_inf(id);
+ WFIFOW(fd, len + 4) = 0;
+ WFIFOW(fd, len + 6) = hd->homunculus.hskill[j].lv;
+ if ( hd->homunculus.hskill[j].lv ) {
+ WFIFOW(fd, len + 8) = skill->get_sp(id, hd->homunculus.hskill[j].lv);
+ WFIFOW(fd, len + 10) = skill->get_range2(&sd->hd->bl, id, hd->homunculus.hskill[j].lv);
+ } else {
+ WFIFOW(fd, len + 8) = 0;
+ WFIFOW(fd, len + 10) = 0;
+ }
+ safestrncpy((char*)WFIFOP(fd, len + 12), skill->get_name(id), NAME_LENGTH);
+ WFIFOB(fd, len + 36) = (hd->homunculus.hskill[j].lv < homun->skill_tree_get_max(id, hd->homunculus.class_)) ? 1 : 0;
+ len += 37;
}
}
WFIFOW(fd,2)=len;
@@ -2292,15 +2298,7 @@ void clif_dropitem(struct map_session_data *sd,int n,int amount)
/// Notifies the client, that an inventory item was deleted (ZC_DELETE_ITEM_FROM_BODY).
/// 07fa <delete type>.W <index>.W <amount>.W
-/// delete type:
-/// 0 = Normal
-/// 1 = Item used for a skill
-/// 2 = Refine failed
-/// 3 = Material changed
-/// 4 = Moved to storage
-/// 5 = Moved to cart
-/// 6 = Item sold
-/// 7 = Consumed by Four Spirit Analysis (SO_EL_ANALYSIS) skill
+/// delete type: @see enum delitem_reason
void clif_delitem(struct map_session_data *sd,int n,int amount, short reason)
{
#if PACKETVER < 20091117
@@ -2976,6 +2974,9 @@ void clif_changelook(struct block_list *bl,int type,int val)
case LOOK_BASE:
if( !sd ) break;
+ if ( val == INVISIBLE_CLASS ) /* nothing to change look */
+ return;
+
if( sd->sc.option&OPTION_COSTUME )
vd->weapon = vd->shield = 0;
@@ -3226,14 +3227,14 @@ void clif_arrow_create_list(struct map_session_data *sd)
for (i = 0, c = 0; i < MAX_SKILL_ARROW_DB; i++) {
int j;
- if (skill->arrow_db[i].nameid > 0
- && (j = pc->search_inventory(sd, skill->arrow_db[i].nameid)) != INDEX_NOT_FOUND
+ if (skill->dbs->arrow_db[i].nameid > 0
+ && (j = pc->search_inventory(sd, skill->dbs->arrow_db[i].nameid)) != INDEX_NOT_FOUND
&& !sd->status.inventory[j].equip && sd->status.inventory[j].identify
) {
- if ((j = itemdb_viewid(skill->arrow_db[i].nameid)) > 0)
+ if ((j = itemdb_viewid(skill->dbs->arrow_db[i].nameid)) > 0)
WFIFOW(fd,c*2+4) = j;
else
- WFIFOW(fd,c*2+4) = skill->arrow_db[i].nameid;
+ WFIFOW(fd,c*2+4) = skill->dbs->arrow_db[i].nameid;
c++;
}
}
@@ -3459,6 +3460,7 @@ void clif_useitemack(struct map_session_data *sd,int index,int amount,bool ok)
/// 0 = Room has been successfully created (opens chat room)
/// 1 = Room limit exceeded
/// 2 = Same room already exists
+// TODO: Flag enum
void clif_createchat(struct map_session_data* sd, int flag)
{
int fd;
@@ -4003,7 +4005,7 @@ void clif_getareachar_pc(struct map_session_data* sd,struct map_session_data* ds
clif->charm_single(sd->fd, dstsd);
for( i = 0; i < dstsd->sc_display_count; i++ ) {
- clif->sc_load(&sd->bl,dstsd->bl.id,SELF,status->IconChangeTable[dstsd->sc_display[i]->type],dstsd->sc_display[i]->val1,dstsd->sc_display[i]->val2,dstsd->sc_display[i]->val3);
+ clif->sc_load(&sd->bl,dstsd->bl.id,SELF,status->dbs->IconChangeTable[dstsd->sc_display[i]->type],dstsd->sc_display[i]->val1,dstsd->sc_display[i]->val2,dstsd->sc_display[i]->val3);
}
if( (sd->status.party_id && dstsd->status.party_id == sd->status.party_id) || //Party-mate, or hpdisp setting.
(sd->bg_id && sd->bg_id == dstsd->bg_id) || //BattleGround
@@ -4012,11 +4014,11 @@ void clif_getareachar_pc(struct map_session_data* sd,struct map_session_data* ds
clif->hpmeter_single(sd->fd, dstsd->bl.id, dstsd->battle_status.hp, dstsd->battle_status.max_hp);
// display link (sd - dstsd) to sd
- ARR_FIND( 0, 5, i, sd->devotion[i] == dstsd->bl.id );
- if( i < 5 ) clif->devotion(&sd->bl, sd);
+ ARR_FIND( 0, MAX_PC_DEVOTION, i, sd->devotion[i] == dstsd->bl.id );
+ if( i < MAX_PC_DEVOTION ) clif->devotion(&sd->bl, sd);
// display links (dstsd - devotees) to sd
- ARR_FIND( 0, 5, i, dstsd->devotion[i] > 0 );
- if( i < 5 ) clif->devotion(&dstsd->bl, sd);
+ ARR_FIND( 0, MAX_PC_DEVOTION, i, dstsd->devotion[i] > 0 );
+ if( i < MAX_PC_DEVOTION ) clif->devotion(&dstsd->bl, sd);
// display link (dstsd - crusader) to sd
if( dstsd->sc.data[SC_DEVOTION] && (d_bl = map->id2bl(dstsd->sc.data[SC_DEVOTION]->val1)) != NULL )
clif->devotion(d_bl, sd);
@@ -4131,20 +4133,8 @@ int clif_calc_walkdelay(struct block_list *bl,int delay, int type, int damage, i
/// Sends a 'damage' packet (src performs action on dst)
/// 008a <src ID>.L <dst ID>.L <server tick>.L <src speed>.L <dst speed>.L <damage>.W <div>.W <type>.B <damage2>.W (ZC_NOTIFY_ACT)
/// 02e1 <src ID>.L <dst ID>.L <server tick>.L <src speed>.L <dst speed>.L <damage>.L <div>.W <type>.B <damage2>.L (ZC_NOTIFY_ACT2)
-/// type:
-/// 0 = damage [ damage: total damage, div: amount of hits, damage2: assassin dual-wield damage ]
-/// 1 = pick up item
-/// 2 = sit down
-/// 3 = stand up
-/// 4 = damage (endure)
-/// 5 = (splash?)
-/// 6 = (skill?)
-/// 7 = (repeat damage?)
-/// 8 = multi-hit damage
-/// 9 = multi-hit damage (endure)
-/// 10 = critical hit
-/// 11 = lucky dodge
-/// 12 = (touch skill?)
+/// type: @see enum battle_dmg_type
+/// for BDT_NORMAL: [ damage: total damage, div: amount of hits, damage2: assassin dual-wield damage ]
int clif_damage(struct block_list* src, struct block_list* dst, int sdelay, int ddelay, int64 in_damage, short div, unsigned char type, int64 in_damage2) {
struct packet_damage p;
struct status_change *sc;
@@ -4222,7 +4212,7 @@ int clif_damage(struct block_list* src, struct block_list* dst, int sdelay, int
*------------------------------------------*/
void clif_takeitem(struct block_list* src, struct block_list* dst)
{
- //clif->damage(src,dst,0,0,0,0,1,0);
+ //clif->damage(src,dst,0,0,0,0,BDT_PICKUP,0);
unsigned char buf[32];
nullpo_retv(src);
@@ -4576,15 +4566,23 @@ void clif_skillinfoblock(struct map_session_data *sd)
WFIFOW(fd,0) = 0x10f;
for ( i = 0, len = 4; i < MAX_SKILL; i++) {
if( (id = sd->status.skill[i].id) != 0 ) {
+ int level;
// workaround for bugreport:5348
if (len + 37 > 8192)
break;
- WFIFOW(fd,len) = id;
- WFIFOL(fd,len+2) = skill->get_inf(id);
- WFIFOW(fd,len+6) = sd->status.skill[i].lv;
- WFIFOW(fd,len+8) = skill->get_sp(id,sd->status.skill[i].lv);
- WFIFOW(fd,len+10)= skill->get_range2(&sd->bl, id,sd->status.skill[i].lv);
+ WFIFOW(fd, len) = id;
+ WFIFOL(fd, len + 2) = skill->get_inf(id);
+ level = sd->status.skill[i].lv;
+ WFIFOW(fd, len + 6) = level;
+ if (level) {
+ WFIFOW(fd, len + 8) = skill->get_sp(id, level);
+ WFIFOW(fd, len + 10)= skill->get_range2(&sd->bl, id, level);
+ }
+ else {
+ WFIFOW(fd, len + 8) = 0;
+ WFIFOW(fd, len + 10)= 0;
+ }
safestrncpy((char*)WFIFOP(fd,len+12), skill->get_name(id), NAME_LENGTH);
if(sd->status.skill[i].flag == SKILL_FLAG_PERMANENT)
WFIFOB(fd,len+36) = (sd->status.skill[i].lv < skill->tree_get_max(id, sd->status.class_))? 1:0;
@@ -4612,26 +4610,33 @@ void clif_skillinfoblock(struct map_session_data *sd)
/// 0111 <skill id>.W <type>.L <level>.W <sp cost>.W <attack range>.W <skill name>.24B <upgradable>.B
void clif_addskill(struct map_session_data *sd, int id)
{
- int fd, idx = skill->get_index(id);
+ int fd, skill_lv, idx = skill->get_index(id);
nullpo_retv(sd);
fd = sd->fd;
if (!fd) return;
- if( sd->status.skill[idx].id <= 0 )
+ if (sd->status.skill[idx].id <= 0)
return;
+ skill_lv = sd->status.skill[idx].lv;
+
WFIFOHEAD(fd, packet_len(0x111));
WFIFOW(fd,0) = 0x111;
WFIFOW(fd,2) = id;
WFIFOL(fd,4) = skill->get_inf(id);
- WFIFOW(fd,8) = sd->status.skill[idx].lv;
- WFIFOW(fd,10) = skill->get_sp(id,sd->status.skill[idx].lv);
- WFIFOW(fd,12)= skill->get_range2(&sd->bl, id,sd->status.skill[idx].lv);
+ WFIFOW(fd,8) = skill_lv;
+ if (skill_lv > 0) {
+ WFIFOW(fd,10) = skill->get_sp(id, skill_lv);
+ WFIFOW(fd,12) = skill->get_range2(&sd->bl, id, skill_lv);
+ } else {
+ WFIFOW(fd,10) = 0;
+ WFIFOW(fd,12) = 0;
+ }
safestrncpy((char*)WFIFOP(fd,14), skill->get_name(id), NAME_LENGTH);
- if( sd->status.skill[idx].flag == SKILL_FLAG_PERMANENT )
- WFIFOB(fd,38) = (sd->status.skill[idx].lv < skill->tree_get_max(id, sd->status.class_))? 1:0;
+ if (sd->status.skill[idx].flag == SKILL_FLAG_PERMANENT)
+ WFIFOB(fd,38) = (skill_lv < skill->tree_get_max(id, sd->status.class_))? 1:0;
else
WFIFOB(fd,38) = 0;
WFIFOSET(fd,packet_len(0x111));
@@ -4691,16 +4696,22 @@ void clif_skillinfo(struct map_session_data *sd,int skill_id, int inf)
{
const int fd = sd->fd;
int idx = skill->get_index(skill_id);
+ int skill_lv = sd->status.skill[idx].lv;
WFIFOHEAD(fd,packet_len(0x7e1));
WFIFOW(fd,0) = 0x7e1;
WFIFOW(fd,2) = skill_id;
WFIFOL(fd,4) = inf?inf:skill->get_inf(skill_id);
- WFIFOW(fd,8) = sd->status.skill[idx].lv;
- WFIFOW(fd,10) = skill->get_sp(skill_id,sd->status.skill[idx].lv);
- WFIFOW(fd,12) = skill->get_range2(&sd->bl,skill_id,sd->status.skill[idx].lv);
- if( sd->status.skill[idx].flag == SKILL_FLAG_PERMANENT )
- WFIFOB(fd,14) = (sd->status.skill[idx].lv < skill->tree_get_max(skill_id, sd->status.class_))? 1:0;
+ WFIFOW(fd,8) = skill_lv;
+ if (skill_lv > 0) {
+ WFIFOW(fd,10) = skill->get_sp(skill_id, skill_lv);
+ WFIFOW(fd,12) = skill->get_range2(&sd->bl, skill_id, skill_lv);
+ } else {
+ WFIFOW(fd,10) = 0;
+ WFIFOW(fd,12) = 0;
+ }
+ if (sd->status.skill[idx].flag == SKILL_FLAG_PERMANENT)
+ WFIFOB(fd,14) = (skill_lv < skill->tree_get_max(skill_id, sd->status.class_))? 1:0;
else
WFIFOB(fd,14) = 0;
WFIFOSET(fd,packet_len(0x7e1));
@@ -5179,13 +5190,13 @@ void clif_skill_produce_mix_list(struct map_session_data *sd, int skill_id , int
WFIFOW(fd, 0)=0x18d;
for(i=0,c=0;i<MAX_SKILL_PRODUCE_DB;i++){
- if( skill->can_produce_mix(sd,skill->produce_db[i].nameid, trigger, 1) &&
- ( ( skill_id > 0 && skill->produce_db[i].req_skill == skill_id ) || skill_id < 0 )
+ if( skill->can_produce_mix(sd,skill->dbs->produce_db[i].nameid, trigger, 1) &&
+ ( ( skill_id > 0 && skill->dbs->produce_db[i].req_skill == skill_id ) || skill_id < 0 )
){
- if((view = itemdb_viewid(skill->produce_db[i].nameid)) > 0)
+ if((view = itemdb_viewid(skill->dbs->produce_db[i].nameid)) > 0)
WFIFOW(fd,c*8+ 4)= view;
else
- WFIFOW(fd,c*8+ 4)= skill->produce_db[i].nameid;
+ WFIFOW(fd,c*8+ 4)= skill->dbs->produce_db[i].nameid;
WFIFOW(fd,c*8+ 6)= 0;
WFIFOW(fd,c*8+ 8)= 0;
WFIFOW(fd,c*8+10)= 0;
@@ -5226,13 +5237,13 @@ void clif_cooking_list(struct map_session_data *sd, int trigger, uint16 skill_id
c = 0;
for( i = 0; i < MAX_SKILL_PRODUCE_DB; i++ ) {
- if( !skill->can_produce_mix(sd,skill->produce_db[i].nameid,trigger, qty) )
+ if( !skill->can_produce_mix(sd,skill->dbs->produce_db[i].nameid,trigger, qty) )
continue;
- if( (view = itemdb_viewid(skill->produce_db[i].nameid)) > 0 )
+ if( (view = itemdb_viewid(skill->dbs->produce_db[i].nameid)) > 0 )
WFIFOW(fd, 6 + 2 * c) = view;
else
- WFIFOW(fd, 6 + 2 * c) = skill->produce_db[i].nameid;
+ WFIFOW(fd, 6 + 2 * c) = skill->dbs->produce_db[i].nameid;
c++;
}
@@ -5256,7 +5267,7 @@ void clif_cooking_list(struct map_session_data *sd, int trigger, uint16 skill_id
if( skill_id != AM_PHARMACY ) { // AM_PHARMACY is used to Cooking.
// It fails.
#if PACKETVER >= 20090922
- clif->msg_skill(sd,skill_id,0x625);
+ clif->msgtable_skill(sd, skill_id, MSG_COOKING_LIST_FAIL);
#else
WFIFOW(fd,2) = 6 + 2 * c;
WFIFOSET(fd,WFIFOW(fd,2));
@@ -5338,7 +5349,7 @@ void clif_displaymessage(const int fd, const char* mes) {
#if PACKETVER == 20141022
/** for some reason game client crashes depending on message pattern (only for this packet) **/
/** so we redirect to ZC_NPC_CHAT **/
- clif->colormes(fd,COLOR_DEFAULT,mes);
+ clif->messagecolor_self(fd, COLOR_DEFAULT, mes);
#else
size_t len;
@@ -5558,6 +5569,7 @@ void clif_map_type(struct map_session_data* sd, enum map_type type) {
/// Updates PvP ranking (ZC_NOTIFY_RANKING).
/// 019a <id>.L <ranking>.L <total>.L
+// FIXME: missing documentation for the 'type' parameter
void clif_pvpset(struct map_session_data *sd,int pvprank,int pvpnum,int type)
{
if(type == 2) {
@@ -5703,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));
}
@@ -6183,6 +6171,14 @@ void clif_openvending(struct map_session_data* sd, int id, struct s_vending* ven
clif->addcards(WFIFOP(fd,22+i*22), &sd->status.cart[index]);
}
WFIFOSET(fd,WFIFOW(fd,2));
+
+#if PACKETVER >= 20141022
+ /** should go elsewhere perhaps? it has to be bundled with this however. **/
+ WFIFOHEAD(fd, 3);
+ WFIFOW(fd, 0) = 0xa28;
+ WFIFOB(fd, 2) = 0;/** 1 is failure. our current responses to failure are working so not yet implemented **/
+ WFIFOSET(fd, 3);
+#endif
}
@@ -6877,7 +6873,7 @@ void clif_devotion(struct block_list *src, struct map_session_data *tsd)
if( sd == NULL )
return;
- for( i = 0; i < 5; i++ )
+ for( i = 0; i < MAX_PC_DEVOTION; i++ )
WBUFL(buf,6+4*i) = sd->devotion[i];
WBUFW(buf,26) = skill->get_range2(src, CR_DEVOTION, pc->checkskill(sd, CR_DEVOTION));
}
@@ -7034,9 +7030,7 @@ void clif_guild_created(struct map_session_data *sd,int flag)
/// Notifies the client that it is belonging to a guild (ZC_UPDATE_GDID).
/// 016c <guild id>.L <emblem id>.L <mode>.L <ismaster>.B <inter sid>.L <guild name>.24B
-/// mode:
-/// &0x01 = allow invite
-/// &0x10 = allow expel
+/// mode: @see enum guild_permission
void clif_guild_belonginfo(struct map_session_data *sd, struct guild *g)
{
int ps,fd;
@@ -7286,9 +7280,7 @@ void clif_guild_positionnamelist(struct map_session_data *sd) {
/// Guild position information (ZC_POSITION_INFO).
/// 0160 <packet len>.W { <position id>.L <mode>.L <ranking>.L <pay rate>.L }*
-/// mode:
-/// &0x01 = allow invite
-/// &0x10 = allow expel
+/// mode: @see enum guild_permission
/// ranking:
/// TODO
void clif_guild_positioninfolist(struct map_session_data *sd) {
@@ -7316,9 +7308,7 @@ void clif_guild_positioninfolist(struct map_session_data *sd) {
/// Notifies clients in a guild about updated position information (ZC_ACK_CHANGE_GUILD_POSITIONINFO).
/// 0174 <packet len>.W { <position id>.L <mode>.L <ranking>.L <pay rate>.L <position name>.24B }*
-/// mode:
-/// &0x01 = allow invite
-/// &0x10 = allow expel
+/// mode: @see enum guild_permission
/// ranking:
/// TODO
void clif_guild_positionchanged(struct guild *g,int idx)
@@ -7432,8 +7422,13 @@ void clif_guild_skillinfo(struct map_session_data* sd)
WFIFOW(fd,p+0) = id;
WFIFOL(fd,p+2) = skill->get_inf(id);
WFIFOW(fd,p+6) = g->skill[i].lv;
- WFIFOW(fd,p+8) = skill->get_sp(id, g->skill[i].lv);
- WFIFOW(fd,p+10) = skill->get_range(id, g->skill[i].lv);
+ if ( g->skill[i].lv ) {
+ WFIFOW(fd, p + 8) = skill->get_sp(id, g->skill[i].lv);
+ WFIFOW(fd, p + 10) = skill->get_range(id, g->skill[i].lv);
+ } else {
+ WFIFOW(fd, p + 8) = 0;
+ WFIFOW(fd, p + 10) = 0;
+ }
safestrncpy((char*)WFIFOP(fd,p+12), skill->get_name(id), NAME_LENGTH);
WFIFOB(fd,p+36)= (g->skill[i].lv < guild->skill_get_max(id) && sd == g->member[0].sd) ? 1 : 0;
c++;
@@ -8107,28 +8102,41 @@ void clif_specialeffect_value(struct block_list* bl, int effect_id, int num, sen
clif->send(buf, packet_len(0x284), bl, SELF);
}
}
-// Modification of clif_messagecolor to send colored messages to players to chat log only (doesn't display overhead)
-/// 02c1 <packet len>.W <id>.L <color>.L <message>.?B
-int clif_colormes(int fd, enum clif_colors color, const char* msg) {
+/**
+ * Modification of clif_messagecolor to send colored messages to players to chat log only (doesn't display overhead).
+ *
+ * 02c1 <packet len>.W <id>.L <color>.L <message>.?B
+ *
+ * @param fd Target fd to send the message to
+ * @param color Message color (RGB format: 0xRRGGBB)
+ * @param msg Message text
+ */
+void clif_messagecolor_self(int fd, uint32 color, const char *msg)
+{
size_t msg_len = strlen(msg) + 1;
WFIFOHEAD(fd,msg_len + 12);
WFIFOW(fd,0) = 0x2C1;
WFIFOW(fd,2) = msg_len + 12;
WFIFOL(fd,4) = 0;
- WFIFOL(fd,8) = color_table[color];
+ WFIFOL(fd,8) = RGB2BGR(color);
safestrncpy((char*)WFIFOP(fd,12), msg, msg_len);
WFIFOSET(fd, msg_len + 12);
-
- return 0;
}
-/// Monster/NPC color chat [SnakeDrak] (ZC_NPC_CHAT).
-/// 02c1 <packet len>.W <id>.L <color>.L <message>.?B
-void clif_messagecolor(struct block_list* bl, unsigned int color, const char* msg) {
+/**
+ * Monster/NPC color chat [SnakeDrak] (ZC_NPC_CHAT).
+ *
+ * 02c1 <packet len>.W <id>.L <color>.L <message>.?B
+ *
+ * @param bl Source block list.
+ * @param color Message color (RGB format: 0xRRGGBB)
+ * @param msg Message text
+ */
+void clif_messagecolor(struct block_list* bl, uint32 color, const char *msg)
+{
size_t msg_len = strlen(msg) + 1;
uint8 buf[256];
- color = (color & 0x0000FF) << 16 | (color & 0x00FF00) | (color & 0xFF0000) >> 16; // RGB to BGR
nullpo_retv(bl);
@@ -8140,48 +8148,29 @@ void clif_messagecolor(struct block_list* bl, unsigned int color, const char* ms
WBUFW(buf,0) = 0x2C1;
WBUFW(buf,2) = msg_len + 12;
WBUFL(buf,4) = bl->id;
- WBUFL(buf,8) = color;
+ WBUFL(buf,8) = RGB2BGR(color);
memcpy(WBUFP(buf,12), msg, msg_len);
clif->send(buf, WBUFW(buf,2), bl, AREA_CHAT_WOC);
}
-/// Public chat message [Valaris] (ZC_NOTIFY_CHAT).
-/// 008d <packet len>.W <id>.L <message>.?B
-void clif_message(struct block_list* bl, const char* msg) {
- unsigned short msg_len = strlen(msg) + 1;
- uint8 buf[256];
- nullpo_retv(bl);
-
- if( msg_len > sizeof(buf)-8 ) {
- ShowWarning("clif_message: Truncating too long message '%s' (len=%u).\n", msg, msg_len);
- msg_len = sizeof(buf)-8;
- }
-
- WBUFW(buf,0) = 0x8d;
- WBUFW(buf,2) = msg_len + 8;
- WBUFL(buf,4) = bl->id;
- safestrncpy((char*)WBUFP(buf,8), msg, msg_len);
-
- clif->send(buf, WBUFW(buf,2), bl, AREA_CHAT_WOC);
-}
-
/**
* Notifies the client that the storage window is still open
*
* Should only be used in cases where the client closed the
* storage window without server's consent
**/
-void clif_refresh_storagewindow( struct map_session_data *sd ) {
+void clif_refresh_storagewindow(struct map_session_data *sd)
+{
// Notify the client that the storage is open
- if( sd->state.storage_flag == 1 ) {
+ if (sd->state.storage_flag == STORAGE_FLAG_NORMAL) {
storage->sortitem(sd->status.storage.items, ARRAYLENGTH(sd->status.storage.items));
clif->storagelist(sd, sd->status.storage.items, ARRAYLENGTH(sd->status.storage.items));
clif->updatestorageamount(sd, sd->status.storage.storage_amount, MAX_STORAGE);
}
// Notify the client that the gstorage is open otherwise it will
// remain locked forever and nobody will be able to access it
- if( sd->state.storage_flag == 2 ) {
+ if (sd->state.storage_flag == STORAGE_FLAG_GUILD) {
struct guild_storage *gstor;
if( (gstor = idb_get(gstorage->db,sd->status.guild_id)) == NULL) {
// Shouldn't happen... The information should already be at the map-server
@@ -8231,7 +8220,7 @@ void clif_refresh(struct map_session_data *sd)
map->foreachinrange(clif->getareachar,&sd->bl,AREA_SIZE,BL_ALL,sd);
clif->weather_check(sd);
if( sd->chatID )
- chat->leave(sd,0);
+ chat->leave(sd, false);
if( sd->state.vending )
clif->openvending(sd, sd->bl.id, sd->vending);
if( pc_issit(sd) )
@@ -8712,9 +8701,15 @@ void clif_viewequip_ack(struct map_session_data* sd, struct map_session_data* ts
}
-/// Display msgstringtable.txt string (ZC_MSG).
-/// 0291 <message>.W
-void clif_msg(struct map_session_data* sd, unsigned short id)
+/**
+ * Displays a string from msgstringtable.txt (ZC_MSG).
+ *
+ * 0291 <msg id>.W
+ *
+ * @param sd The target character.
+ * @param msg_id msgstringtable message index, 0-based (@see enum clif_messages)
+ */
+void clif_msgtable(struct map_session_data* sd, unsigned short msg_id)
{
int fd;
nullpo_retv(sd);
@@ -8722,31 +8717,47 @@ void clif_msg(struct map_session_data* sd, unsigned short id)
WFIFOHEAD(fd, packet_len(0x291));
WFIFOW(fd, 0) = 0x291;
- WFIFOW(fd, 2) = id; // zero-based msgstringtable.txt index
+ WFIFOW(fd, 2) = msg_id; // zero-based msgstringtable.txt index
WFIFOSET(fd, packet_len(0x291));
}
-
-/// Display msgstringtable.txt string and fill in a valid for %d format (ZC_MSG_VALUE).
-/// 0x7e2 <message>.W <value>.L
-void clif_msg_value(struct map_session_data* sd, unsigned short id, int value)
+/**
+ * Displays a format string from msgstringtable.txt with a %d value (ZC_MSG_VALUE).
+ *
+ * 0x7e2 <msg id>.W <value>.L
+ *
+ * @param sd The target character.
+ * @param msg_id msgstringtable message index, 0-based (@see enum clif_messages)
+ * @param value The value to fill %d.
+ */
+void clif_msgtable_num(struct map_session_data *sd, unsigned short msg_id, int value)
{
- int fd = sd->fd;
+#if PACKETVER >= 20090805
+ int fd;
+ nullpo_retv(sd);
+ fd = sd->fd;
WFIFOHEAD(fd, packet_len(0x7e2));
- WFIFOW(fd,0) = 0x7e2;
- WFIFOW(fd,2) = id;
- WFIFOL(fd,4) = value;
+ WFIFOW(fd, 0) = 0x7e2;
+ WFIFOW(fd, 2) = msg_id;
+ WFIFOL(fd, 4) = value;
WFIFOSET(fd, packet_len(0x7e2));
+#endif
}
-
-/// Displays msgstringtable.txt string, prefixed with a skill name. (ZC_MSG_SKILL).
-/// 07e6 <skill id>.W <msg id>.L
-///
-/// NOTE: Message has following format and is printed in color 0xCDCDFF (purple):
-/// "[SkillName] Message"
-void clif_msg_skill(struct map_session_data* sd, uint16 skill_id, int msg_id)
+/**
+ * Displays a string from msgstringtable.txt, prefixed with a skill name (ZC_MSG_SKILL).
+ *
+ * 07e6 <skill id>.W <msg id>.L
+ *
+ * NOTE: Message has following format and is printed in color 0xCDCDFF (purple):
+ * "[SkillName] Message"
+ *
+ * @param sd The target character.
+ * @param skill_id ID of the skill to display.
+ * @param msg_id msgstringtable message index, 0-based (@see enum clif_messages)
+ */
+void clif_msgtable_skill(struct map_session_data* sd, uint16 skill_id, int msg_id)
{
int fd = sd->fd;
@@ -8857,12 +8868,13 @@ void clif_channel_msg(struct channel_data *chan, struct map_session_data *sd, ch
DBIterator *iter = db_iterator(chan->users);
struct map_session_data *user;
unsigned short msg_len = strlen(msg) + 1;
+ uint32 color = channel->config->colors[chan->color];
WFIFOHEAD(sd->fd,msg_len + 12);
WFIFOW(sd->fd,0) = 0x2C1;
WFIFOW(sd->fd,2) = msg_len + 12;
WFIFOL(sd->fd,4) = 0;
- WFIFOL(sd->fd,8) = channel->config->colors[chan->color];
+ WFIFOL(sd->fd,8) = RGB2BGR(color);
safestrncpy((char*)WFIFOP(sd->fd,12), msg, msg_len);
for (user = dbi_first(iter); dbi_exists(iter); user = dbi_next(iter)) {
@@ -8884,11 +8896,12 @@ void clif_channel_msg2(struct channel_data *chan, char *msg)
struct map_session_data *user;
unsigned char buf[210];
unsigned short msg_len = strlen(msg) + 1;
+ uint32 color = channel->config->colors[chan->color];
WBUFW(buf,0) = 0x2C1;
WBUFW(buf,2) = msg_len + 12;
WBUFL(buf,4) = 0;
- WBUFL(buf,8) = channel->config->colors[chan->color];
+ WBUFL(buf,8) = RGB2BGR(color);
safestrncpy((char*)WBUFP(buf,12), msg, msg_len);
for (user = dbi_first(iter); dbi_exists(iter); user = dbi_next(iter)) {
@@ -8984,9 +8997,6 @@ void clif_parse_WantToConnection(int fd, struct map_session_data* sd) {
/// Notification from the client, that it has finished map loading and is about to display player's character (CZ_NOTIFY_ACTORINIT).
/// 007d
void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) {
-#if PACKETVER >= 20090218
- int i;
-#endif
bool first_time = false;
if(sd->bl.prev != NULL)
@@ -9171,10 +9181,13 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) {
//Auron reported that This skill only triggers when you logon on the map o.O [Skotlex]
if ((lv = pc->checkskill(sd,SG_KNOWLEDGE)) > 0) {
- if(sd->bl.m == sd->feel_map[0].m
- || sd->bl.m == sd->feel_map[1].m
- || sd->bl.m == sd->feel_map[2].m)
- sc_start(NULL,&sd->bl, SC_KNOWLEDGE, 100, lv, skill->get_time(SG_KNOWLEDGE, lv));
+ int i;
+ for (i = 0; i < MAX_PC_FEELHATE; i++) {
+ if (sd->bl.m == sd->feel_map[i].m) {
+ sc_start(NULL,&sd->bl, SC_KNOWLEDGE, 100, lv, skill->get_time(SG_KNOWLEDGE, lv));
+ break;
+ }
+ }
}
if(sd->pd && sd->pd->pet.intimate > 900)
@@ -9202,14 +9215,16 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) {
clif->updatestatus(sd,SP_DEX);
clif->updatestatus(sd,SP_LUK);
- // abort currently running script
- sd->state.using_fake_npc = 0;
- sd->state.menu_or_input = 0;
- sd->npc_menu = 0;
-
- if(sd->npc_id)
- npc->event_dequeue(sd);
-
+ if (sd->state.warp_clean) {
+ // abort currently running script
+ sd->state.using_fake_npc = 0;
+ sd->state.menu_or_input = 0;
+ sd->npc_menu = 0;
+ if(sd->npc_id)
+ npc->event_dequeue(sd);
+ } else {
+ sd->state.warp_clean = 1;
+ }
if( sd->guild && ( battle_config.guild_notice_changemap == 2 || ( battle_config.guild_notice_changemap == 1 && sd->state.changemap ) ) )
clif->guild_notice(sd,sd->guild);
}
@@ -9254,6 +9269,9 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) {
if (channel->config->local && channel->config->local_autojoin) {
channel->map_join(sd);
}
+ if (channel->config->irc && channel->config->irc_autojoin) {
+ channel->irc_join(sd);
+ }
}
mail->clear(sd);
@@ -9317,14 +9335,17 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) {
// NPC Quest / Event Icon Check [Kisuka]
#if PACKETVER >= 20090218
- for(i = 0; i < map->list[sd->bl.m].qi_count; i++) {
- struct questinfo *qi = &map->list[sd->bl.m].qi_data[i];
- if( quest->check(sd, qi->quest_id, HAVEQUEST) == -1 ) {// Check if quest is not started
- if( qi->hasJob ) { // Check if quest is job-specific, check is user is said job class.
- if( sd->class_ == qi->job )
+ {
+ int i;
+ for(i = 0; i < map->list[sd->bl.m].qi_count; i++) {
+ struct questinfo *qi = &map->list[sd->bl.m].qi_data[i];
+ if( quest->check(sd, qi->quest_id, HAVEQUEST) == -1 ) {// Check if quest is not started
+ if( qi->hasJob ) { // Check if quest is job-specific, check is user is said job class.
+ if( sd->class_ == qi->job )
+ clif->quest_show_event(sd, &qi->nd->bl, qi->icon, qi->color);
+ } else {
clif->quest_show_event(sd, &qi->nd->bl, qi->icon, qi->color);
- } else {
- clif->quest_show_event(sd, &qi->nd->bl, qi->icon, qi->color);
+ }
}
}
}
@@ -9633,6 +9654,7 @@ void clif_parse_GlobalMessage(int fd, struct map_session_data* sd)
} else if ( sd->fontcolor && !sd->chatID ) {
char mout[200];
unsigned char mylen = 1;
+ uint32 color = 0;
if( sd->disguise == -1 ) {
sd->fontcolor_tid = timer->add(timer->gettick()+5000, clif->undisguise_timer, sd->bl.id, 0);
@@ -9650,11 +9672,12 @@ void clif_parse_GlobalMessage(int fd, struct map_session_data* sd)
mylen += snprintf(mout, 200, "%s : %s",sd->fakename[0]?sd->fakename:sd->status.name,message);
+ color = channel->config->colors[sd->fontcolor - 1];
WFIFOHEAD(fd,mylen + 12);
WFIFOW(fd,0) = 0x2C1;
WFIFOW(fd,2) = mylen + 12;
WFIFOL(fd,4) = sd->bl.id;
- WFIFOL(fd,8) = channel->config->colors[sd->fontcolor - 1];
+ WFIFOL(fd,8) = RGB2BGR(color);
safestrncpy((char*)WFIFOP(fd,12), mout, mylen);
clif->send(WFIFOP(fd,0), WFIFOW(fd,2), &sd->bl, AREA_WOS);
WFIFOL(fd,4) = -sd->bl.id;
@@ -9841,7 +9864,7 @@ void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type,
return;
if(action_type != 0x00 && action_type != 0x07)
- pc_stop_walking(sd, 1);
+ pc_stop_walking(sd, STOPWALKING_FLAG_FIXPOS);
pc_stop_attack(sd);
if(target_id<0 && -target_id == sd->bl.id) // for disguises [Valaris]
@@ -10245,7 +10268,7 @@ void clif_parse_EquipItem(int fd,struct map_session_data *sd) {
if( sd->npc_id ) {
if ( !sd->npc_item_flag )
return;
- } else if ( sd->state.storage_flag || sd->sc.opt1 )
+ } else if (sd->state.storage_flag != STORAGE_FLAG_CLOSED || sd->sc.opt1)
; //You can equip/unequip stuff while storage is open/under status changes
else if ( pc_cant_act2(sd) || sd->state.prerefining )
return;
@@ -10287,7 +10310,7 @@ void clif_parse_UnequipItem(int fd,struct map_session_data *sd)
if( sd->npc_id ) {
if ( !sd->npc_item_flag )
return;
- } else if ( sd->state.storage_flag || sd->sc.opt1 )
+ } else if (sd->state.storage_flag != STORAGE_FLAG_CLOSED || sd->sc.opt1)
; //You can equip/unequip stuff while storage is open/under status changes
else if ( pc_cant_act2(sd) || sd->state.prerefining )
return;
@@ -10297,7 +10320,7 @@ void clif_parse_UnequipItem(int fd,struct map_session_data *sd)
if( battle_config.idletime_criteria & BCIDLE_USEITEM )
sd->idletime = sockt->last_tick;
- pc->unequipitem(sd,index,1);
+ pc->unequipitem(sd,index, PCUNEQUIPITEM_RECALC);
}
@@ -10315,7 +10338,7 @@ void clif_parse_NpcClicked(int fd,struct map_session_data *sd)
}
if( sd->npc_id || sd->state.workinprogress&2 ){
#ifdef RENEWAL
- clif->msg(sd, 0x783); // TODO look for the client date that has this message.
+ clif->msgtable(sd, MSG_NPC_WORK_IN_PROGRESS); // TODO look for the client date that has this message.
#endif
return;
}
@@ -10330,7 +10353,7 @@ void clif_parse_NpcClicked(int fd,struct map_session_data *sd)
case BL_NPC:
if( sd->ud.skill_id < RK_ENCHANTBLADE && sd->ud.skilltimer != INVALID_TIMER ) {// TODO: should only work with none 3rd job skills
#ifdef RENEWAL
- clif->msg(sd, 0x783);
+ clif->msgtable(sd, MSG_NPC_WORK_IN_PROGRESS);
#endif
break;
}
@@ -10525,7 +10548,7 @@ void clif_parse_KickFromChat(int fd,struct map_session_data *sd)
/// 00e3
void clif_parse_ChatLeave(int fd, struct map_session_data* sd)
{
- chat->leave(sd,0);
+ chat->leave(sd, false);
}
@@ -10682,7 +10705,7 @@ void clif_parse_ChangeCart(int fd,struct map_session_data *sd)
#ifdef RENEWAL
if( sd->npc_id || sd->state.workinprogress&1 ){
- clif->msg(sd, 0x783);
+ clif->msgtable(sd, MSG_NPC_WORK_IN_PROGRESS);
return;
}
#endif
@@ -10872,7 +10895,7 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd)
if( sd->npc_id || sd->state.workinprogress&1 ){
#ifdef RENEWAL
- clif->msg(sd, 0x783); // TODO look for the client date that has this message.
+ clif->msgtable(sd, MSG_NPC_WORK_IN_PROGRESS); // TODO look for the client date that has this message.
#endif
return;
}
@@ -10880,7 +10903,7 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd)
if( pc_cant_act(sd)
&& skill_id != RK_REFRESH
&& !(skill_id == SR_GENTLETOUCH_CURE && (sd->sc.opt1 == OPT1_STONE || sd->sc.opt1 == OPT1_FREEZE || sd->sc.opt1 == OPT1_STUN))
- && ( sd->state.storage_flag && !(tmp&INF_SELF_SKILL) ) // SELF skills can be used with the storage open, issue: 8027
+ && (sd->state.storage_flag != STORAGE_FLAG_CLOSED && !(tmp&INF_SELF_SKILL)) // SELF skills can be used with the storage open, issue: 8027
)
return;
@@ -10968,7 +10991,7 @@ void clif_parse_UseSkillToPosSub(int fd, struct map_session_data *sd, uint16 ski
#ifdef RENEWAL
if( sd->state.workinprogress&1 ){
- clif->msg(sd, 0x783); // TODO look for the client date that has this message.
+ clif->msgtable(sd, MSG_NPC_WORK_IN_PROGRESS); // TODO look for the client date that has this message.
return;
}
#endif
@@ -11085,7 +11108,7 @@ void clif_parse_UseSkillMap(int fd, struct map_session_data* sd)
return;
// It is possible to use teleport with the storage window open issue:8027
- if( pc_cant_act(sd) && (!sd->state.storage_flag && skill_id != AL_TELEPORT) ) {
+ if (pc_cant_act(sd) && (sd->state.storage_flag == STORAGE_FLAG_CLOSED && skill_id != AL_TELEPORT)) {
clif_menuskill_clear(sd);
return;
}
@@ -11349,8 +11372,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);
}
@@ -11359,8 +11380,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);
}
@@ -11428,9 +11447,9 @@ void clif_parse_MoveToKafra(int fd, struct map_session_data *sd)
if (item_index < 0 || item_index >= MAX_INVENTORY || item_amount < 1)
return;
- if (sd->state.storage_flag == 1)
+ if (sd->state.storage_flag == STORAGE_FLAG_NORMAL)
storage->add(sd, item_index, item_amount);
- else if (sd->state.storage_flag == 2)
+ else if (sd->state.storage_flag == STORAGE_FLAG_GUILD)
gstorage->add(sd, item_index, item_amount);
}
@@ -11446,9 +11465,9 @@ void clif_parse_MoveFromKafra(int fd,struct map_session_data *sd)
item_index = RFIFOW(fd,packet_db[RFIFOW(fd,0)].pos[0])-1;
item_amount = RFIFOL(fd,packet_db[RFIFOW(fd,0)].pos[1]);
- if (sd->state.storage_flag == 1)
+ if (sd->state.storage_flag == STORAGE_FLAG_NORMAL)
storage->get(sd, item_index, item_amount);
- else if(sd->state.storage_flag == 2)
+ else if(sd->state.storage_flag == STORAGE_FLAG_GUILD)
gstorage->get(sd, item_index, item_amount);
}
@@ -11462,9 +11481,9 @@ void clif_parse_MoveToKafraFromCart(int fd, struct map_session_data *sd)
if (!pc_iscarton(sd))
return;
- if (sd->state.storage_flag == 1)
+ if (sd->state.storage_flag == STORAGE_FLAG_NORMAL)
storage->addfromcart(sd, RFIFOW(fd,2) - 2, RFIFOL(fd,4));
- else if (sd->state.storage_flag == 2)
+ else if (sd->state.storage_flag == STORAGE_FLAG_GUILD)
gstorage->addfromcart(sd, RFIFOW(fd,2) - 2, RFIFOL(fd,4));
}
@@ -11478,9 +11497,9 @@ void clif_parse_MoveFromKafraToCart(int fd, struct map_session_data *sd)
if (!pc_iscarton(sd))
return;
- if (sd->state.storage_flag == 1)
+ if (sd->state.storage_flag == STORAGE_FLAG_NORMAL)
storage->gettocart(sd, RFIFOW(fd,2)-1, RFIFOL(fd,4));
- else if (sd->state.storage_flag == 2)
+ else if (sd->state.storage_flag == STORAGE_FLAG_GUILD)
gstorage->gettocart(sd, RFIFOW(fd,2)-1, RFIFOL(fd,4));
}
@@ -11489,9 +11508,9 @@ void clif_parse_MoveFromKafraToCart(int fd, struct map_session_data *sd)
/// 00f7
void clif_parse_CloseKafra(int fd, struct map_session_data *sd)
{
- if( sd->state.storage_flag == 1 )
+ if( sd->state.storage_flag == STORAGE_FLAG_NORMAL )
storage->close(sd);
- else if( sd->state.storage_flag == 2 )
+ else if( sd->state.storage_flag == STORAGE_FLAG_GUILD )
gstorage->close(sd);
}
@@ -12701,7 +12720,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;
}
@@ -14142,7 +14161,7 @@ void clif_parse_AutoRevive(int fd, struct map_session_data *sd) {
if (item_position == INDEX_NOT_FOUND)
status_change_end(&sd->bl,SC_LIGHT_OF_REGENE,INVALID_TIMER);
else
- pc->delitem(sd, item_position, 1, 0, 1, LOG_TYPE_CONSUME);
+ pc->delitem(sd, item_position, 1, 0, DELITEM_SKILLUSE, LOG_TYPE_CONSUME);
clif->skill_nodamage(&sd->bl,&sd->bl,ALL_RESURRECTION,4,1);
}
@@ -14672,7 +14691,7 @@ void clif_Auction_openwindow(struct map_session_data *sd)
{
int fd = sd->fd;
- if( sd->state.storage_flag || sd->state.vending || sd->state.buyingstore || sd->state.trading )
+ if (sd->state.storage_flag != STORAGE_FLAG_CLOSED || sd->state.vending || sd->state.buyingstore || sd->state.trading)
return;
if( !battle_config.feature_auction )
@@ -14918,7 +14937,7 @@ void clif_parse_Auction_register(int fd, struct map_session_data *sd)
{
int zeny = auction.hours*battle_config.auction_feeperhour;
- pc->delitem(sd, sd->auction.index, sd->auction.amount, 1, 6, LOG_TYPE_AUCTION);
+ pc->delitem(sd, sd->auction.index, sd->auction.amount, 1, DELITEM_SOLD, LOG_TYPE_AUCTION);
sd->auction.amount = 0;
pc->payzeny(sd, zeny, LOG_TYPE_AUCTION, NULL);
@@ -15269,7 +15288,7 @@ void clif_parse_ViewPlayerEquip(int fd, struct map_session_data* sd) {
if( tsd->status.show_equip || pc_has_permission(sd, PC_PERM_VIEW_EQUIPMENT) )
clif->viewequip_ack(sd, tsd);
else
- clif_viewequip_fail(sd);
+ clif->msgtable(sd, MSG_EQUIP_NOT_PUBLIC);
}
@@ -15632,8 +15651,13 @@ void clif_mercenary_skillblock(struct map_session_data *sd)
WFIFOW(fd,len) = id;
WFIFOL(fd,len+2) = skill->get_inf(id);
WFIFOW(fd,len+6) = md->db->skill[j].lv;
- WFIFOW(fd,len+8) = skill->get_sp(id, md->db->skill[j].lv);
- WFIFOW(fd,len+10) = skill->get_range2(&md->bl, id, md->db->skill[j].lv);
+ if ( md->db->skill[j].lv ) {
+ WFIFOW(fd, len + 8) = skill->get_sp(id, md->db->skill[j].lv);
+ WFIFOW(fd, len + 10) = skill->get_range2(&md->bl, id, md->db->skill[j].lv);
+ } else {
+ WFIFOW(fd, len + 8) = 0;
+ WFIFOW(fd, len + 10) = 0;
+ }
safestrncpy((char*)WFIFOP(fd,len+12), skill->get_name(id), NAME_LENGTH);
WFIFOB(fd,len+36) = 0; // Skillable for Mercenary?
len += 37;
@@ -15667,7 +15691,7 @@ void clif_parse_mercenary_action(int fd, struct map_session_data* sd)
/// 3 = Your mercenary soldier has ran away.
void clif_mercenary_message(struct map_session_data* sd, int message)
{
- clif->msg(sd, 1266 + message);
+ clif->msgtable(sd, MSG_MERCENARY_EXPIRED + message);
}
@@ -16701,11 +16725,11 @@ int clif_elementalconverter_list(struct map_session_data *sd) {
WFIFOW(fd, 0)=0x1ad;
for(i=0,c=0;i<MAX_SKILL_PRODUCE_DB;i++){
- if( skill->can_produce_mix(sd,skill->produce_db[i].nameid,23, 1) ){
- if((view = itemdb_viewid(skill->produce_db[i].nameid)) > 0)
+ if( skill->can_produce_mix(sd,skill->dbs->produce_db[i].nameid,23, 1) ){
+ if((view = itemdb_viewid(skill->dbs->produce_db[i].nameid)) > 0)
WFIFOW(fd,c*2+ 4)= view;
else
- WFIFOW(fd,c*2+ 4)= skill->produce_db[i].nameid;
+ WFIFOW(fd,c*2+ 4)= skill->dbs->produce_db[i].nameid;
c++;
}
}
@@ -16903,26 +16927,6 @@ int clif_skill_itemlistwindow( struct map_session_data *sd, uint16 skill_id, uin
return 1;
}
-// msgstringtable.txt
-// 0x291 <line>.W
-void clif_msgtable(int fd, int line) {
- WFIFOHEAD(fd, packet_len(0x291));
- WFIFOW(fd, 0) = 0x291;
- WFIFOW(fd, 2) = line;
- WFIFOSET(fd, packet_len(0x291));
-}
-
-// msgstringtable.txt
-// 0x7e2 <line>.W <value>.L
-void clif_msgtable_num(int fd, int line, int num) {
-#if PACKETVER >= 20090805
- WFIFOHEAD(fd, packet_len(0x7e2));
- WFIFOW(fd, 0) = 0x7e2;
- WFIFOW(fd, 2) = line;
- WFIFOL(fd, 4) = num;
- WFIFOSET(fd, packet_len(0x7e2));
-#endif
-}
/*==========================================
* used by SC_AUTOSHADOWSPELL
* RFIFOL(fd,2) - flag (currently not used)
@@ -17062,7 +17066,7 @@ void clif_favorite_item(struct map_session_data* sd, unsigned short index) {
WFIFOHEAD(fd,packet_len(0x908));
WFIFOW(fd,0) = 0x908;
WFIFOW(fd,2) = index+2;
- WFIFOL(fd,4) = (sd->status.inventory[index].favorite == 1) ? 0 : 1;
+ WFIFOB(fd,4) = (sd->status.inventory[index].favorite == 1) ? 0 : 1;
WFIFOSET(fd,packet_len(0x908));
}
@@ -17093,8 +17097,8 @@ void __attribute__ ((unused)) clif_parse_dull(int fd,struct map_session_data *sd
}
void clif_parse_CashShopOpen(int fd, struct map_session_data *sd) {
- if( map->list[sd->bl.m].flag.nocashshop ) {
- clif->colormes(fd,COLOR_RED,msg_fd(fd,1489)); //Cash Shop is disabled in this map
+ if (map->list[sd->bl.m].flag.nocashshop) {
+ clif->messagecolor_self(fd, COLOR_RED, msg_fd(fd,1489)); //Cash Shop is disabled in this map
return;
}
@@ -17134,8 +17138,8 @@ void clif_parse_CashShopBuy(int fd, struct map_session_data *sd) {
unsigned short limit = RFIFOW(fd, 4), i, j;
unsigned int kafra_pay = RFIFOL(fd, 6);// [Ryuuzaki] - These are free cash points (strangely #CASH = main cash currently for us, confusing)
- if( map->list[sd->bl.m].flag.nocashshop ) {
- clif->colormes(fd,COLOR_RED,msg_fd(fd,1489)); //Cash Shop is disabled in this map
+ if (map->list[sd->bl.m].flag.nocashshop) {
+ clif->messagecolor_self(fd, COLOR_RED, msg_fd(fd,1489)); //Cash Shop is disabled in this map
return;
}
@@ -17536,8 +17540,8 @@ void clif_parse_BankDeposit(int fd, struct map_session_data* sd) {
struct packet_banking_deposit_req *p = P2PTR(fd);
int money;
- if( !battle_config.feature_banking ) {
- clif->colormes(fd,COLOR_RED,msg_fd(fd,1483));
+ if (!battle_config.feature_banking) {
+ clif->messagecolor_self(fd, COLOR_RED, msg_fd(fd,1483));
return;
}
@@ -17550,8 +17554,8 @@ void clif_parse_BankWithdraw(int fd, struct map_session_data* sd) {
struct packet_banking_withdraw_req *p = P2PTR(fd);
int money;
- if( !battle_config.feature_banking ) {
- clif->colormes(fd,COLOR_RED,msg_fd(fd,1483));
+ if (!battle_config.feature_banking) {
+ clif->messagecolor_self(fd, COLOR_RED, msg_fd(fd,1483));
return;
}
@@ -17563,8 +17567,8 @@ void clif_parse_BankWithdraw(int fd, struct map_session_data* sd) {
void clif_parse_BankCheck(int fd, struct map_session_data* sd) {
struct packet_banking_check p;
- if( !battle_config.feature_banking ) {
- clif->colormes(fd,COLOR_RED,msg_fd(fd,1483));
+ if (!battle_config.feature_banking) {
+ clif->messagecolor_self(fd, COLOR_RED, msg_fd(fd,1483));
return;
}
@@ -17639,7 +17643,7 @@ void clif_parse_GMFullStrip(int fd, struct map_session_data *sd) {
for( i = 0; i < EQI_MAX; i++ ) {
if( tsd->equip_index[ i ] >= 0 )
- pc->unequipitem( tsd , tsd->equip_index[ i ] , 2 );
+ pc->unequipitem(tsd, tsd->equip_index[i], PCUNEQUIPITEM_FORCE);
}
}
/**
@@ -18093,6 +18097,157 @@ void clif_roulette_generate_ack(struct map_session_data *sd, unsigned char resul
clif->send(&p,sizeof(p), &sd->bl, SELF);
}
+/**
+* Stackable items merger
+**/
+void clif_openmergeitem(int fd, struct map_session_data *sd)
+{
+ int i = 0, n = 0, j = 0;
+ struct merge_item merge_items[MAX_INVENTORY];
+ struct merge_item *merge_items_[MAX_INVENTORY] = {0};
+
+ memset(&merge_items,'\0',sizeof(merge_items));
+
+ for (i = 0; i < MAX_INVENTORY; i++) {
+ struct item *item_data = &sd->status.inventory[i];
+
+ if (item_data->nameid == 0 || !itemdb->isstackable(item_data->nameid))
+ continue;
+
+ merge_items[n].nameid = item_data->nameid;
+ merge_items[n].position = i + 2;
+ n++;
+
+
+ }
+
+ qsort(merge_items,n,sizeof(struct merge_item),clif->comparemergeitem);
+
+ for (i = 0, j = 0; i < n; i++) {
+ if (i > 0 && merge_items[i].nameid == merge_items[i-1].nameid)
+ {
+ merge_items_[j] = &merge_items[i];
+ j++;
+ continue;
+ }
+
+ if (i < n - 1 && merge_items[i].nameid == merge_items[i+1].nameid)
+ {
+ merge_items_[j] = &merge_items[i];
+ j++;
+ continue;
+ }
+ }
+
+ WFIFOHEAD(fd,2*j+4);
+ WFIFOW(fd,0) = 0x96d;
+ WFIFOW(fd,2) = 2*j+4;
+ for ( i = 0; i < j; i++ )
+ WFIFOW(fd,i*2+4) = merge_items_[i]->position;
+ WFIFOSET(fd,2*j+4);
+}
+
+int clif_comparemergeitem(const void *a, const void *b)
+{
+ const struct merge_item *a_ = a;
+ const struct merge_item *b_ = b;
+
+ if (a_->nameid == b_->nameid)
+ return 0;
+ return a_->nameid > b_->nameid ? -1 : 1;
+}
+
+void clif_ackmergeitems(int fd, struct map_session_data *sd)
+{
+ int i = 0, n = 0, length = 0, count = 0;
+ int16 nameid = 0, indexes[MAX_INVENTORY] = {0}, amounts[MAX_INVENTORY] = {0};
+ struct item item_data;
+
+ length = (RFIFOW(fd,2) - 4)/2;
+
+ if (length >= MAX_INVENTORY || length < 2) {
+ WFIFOHEAD(fd,7);
+ WFIFOW(fd,0) = 0x96f;
+ WFIFOW(fd,2) = 0;
+ WFIFOW(fd,4) = 0;
+ WFIFOB(fd,6) = MERGEITEM_FAILD;
+ WFIFOSET(fd,7);
+ return;
+ }
+
+ for (i = 0, n = 0; i < length; i++) {
+ int16 idx = RFIFOW(fd,i*2+4) - 2;
+ struct item *it = NULL;
+
+ if (idx < 0 || idx >= MAX_INVENTORY)
+ continue;
+
+ it = &sd->status.inventory[idx];
+
+ if (it->nameid == 0 || !itemdb->isstackable(it->nameid))
+ continue;
+
+ if (nameid == 0)
+ nameid = it->nameid;
+
+ if (nameid != it->nameid)
+ continue;
+
+ count += it->amount;
+ indexes[n] = idx;
+ amounts[n] = it->amount;
+ n++;
+ }
+
+
+ if (n < 2 || count == 0) {
+ WFIFOHEAD(fd,7);
+ WFIFOW(fd,0) = 0x96f;
+ WFIFOW(fd,2) = 0;
+ WFIFOW(fd,4) = 0;
+ WFIFOB(fd,6) = MERGEITEM_FAILD;
+ WFIFOSET(fd,7);
+ return;
+ }
+
+ if (count > MAX_AMOUNT) {
+ WFIFOHEAD(fd,7);
+ WFIFOW(fd,0) = 0x96f;
+ WFIFOW(fd,2) = 0;
+ WFIFOW(fd,4) = 0;
+ WFIFOB(fd,6) = MERGEITEM_MAXCOUNTFAILD;
+ WFIFOSET(fd,7);
+ return;
+ }
+
+ for (i = 0; i < n; i++)
+ pc->delitem(sd,indexes[i],amounts[i],0,DELITEM_NORMAL,LOG_TYPE_NPC);
+
+
+ memset(&item_data,'\0',sizeof(item_data));
+
+ item_data.nameid = nameid;
+ item_data.identify = 1;
+ item_data.unique_id = itemdb->unique_id(sd);
+ pc->additem(sd,&item_data,count,LOG_TYPE_NPC);
+
+ ARR_FIND(0,MAX_INVENTORY,i,item_data.unique_id == sd->status.inventory[i].unique_id);
+
+ WFIFOHEAD(fd,7);
+ WFIFOW(fd,0) = 0x96f;
+ WFIFOW(fd,2) = i+2;
+ WFIFOW(fd,4) = count;
+ WFIFOB(fd,6) = MERGEITEM_SUCCESS;
+ WFIFOSET(fd,7);
+
+}
+
+void clif_cancelmergeitem (int fd, struct map_session_data *sd)
+{
+ //Track The merge item cancelation ?
+ return;
+}
+
/* */
unsigned short clif_decrypt_cmd( int cmd, struct map_session_data *sd ) {
if( sd ) {
@@ -18344,21 +18499,11 @@ void clif_bc_ready(void) {
/*==========================================
*
*------------------------------------------*/
-int do_init_clif(bool minimal) {
- const char* colors[COLOR_MAX] = { "0xFF0000", "0x00ff00", "0xffffff" };
- int i;
-
+int do_init_clif(bool minimal)
+{
if (minimal)
return 0;
- /**
- * Setup Color Table (saves unnecessary load of strtoul on every call)
- **/
- for(i = 0; i < COLOR_MAX; i++) {
- color_table[i] = (unsigned int)strtoul(colors[i],NULL,0);
- color_table[i] = (color_table[i] & 0x0000FF) << 16 | (color_table[i] & 0x00FF00) | (color_table[i] & 0xFF0000) >> 16;//RGB to BGR
- }
-
packetdb_loaddb();
set_defaultparse(clif->parse);
@@ -18653,17 +18798,15 @@ void clif_defaults(void) {
clif->disp_message = clif_disp_message;
clif->broadcast = clif_broadcast;
clif->broadcast2 = clif_broadcast2;
+ clif->messagecolor_self = clif_messagecolor_self;
clif->messagecolor = clif_messagecolor;
clif->disp_overhead = clif_disp_overhead;
- clif->msg = clif_msg;
- clif->msg_value = clif_msg_value;
- clif->msg_skill = clif_msg_skill;
+ clif->msgtable_skill = clif_msgtable_skill;
clif->msgtable = clif_msgtable;
clif->msgtable_num = clif_msgtable_num;
clif->message = clif_displaymessage;
clif->messageln = clif_displaymessage2;
clif->messages = clif_displaymessage_sprintf;
- clif->colormes = clif_colormes;
clif->process_message = clif_process_message;
clif->wisexin = clif_wisexin;
clif->wisall = clif_wisall;
@@ -18894,6 +19037,12 @@ void clif_defaults(void) {
/* */
clif->parse_roulette_db = clif_parse_roulette_db;
clif->roulette_generate_ack = clif_roulette_generate_ack;
+ /* Merge Items */
+ clif->openmergeitem = clif_openmergeitem;
+ clif->cancelmergeitem = clif_cancelmergeitem;
+ clif->comparemergeitem = clif_comparemergeitem;
+ clif->ackmergeitems = clif_ackmergeitems;
+
/*------------------------
*- Parse Incoming Packet
*------------------------*/
diff --git a/src/map/clif.h b/src/map/clif.h
index 5f1a2a899..c827406ca 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -5,40 +5,38 @@
#ifndef MAP_CLIF_H
#define MAP_CLIF_H
-#include <stdarg.h>
+#include "map/map.h"
+#include "map/packets_struct.h"
+#include "common/cbasetypes.h"
+#include "common/mmo.h"
-#include "map.h"
-#include "packets_struct.h"
-#include "../common/cbasetypes.h"
-#include "../common/db.h"
-#include "../common/mmo.h"
+#include <stdarg.h>
/**
* Declarations
**/
+struct battleground_data;
+struct channel_data;
+struct chat_data;
+struct eri;
+struct flooritem_data;
+struct guild;
+struct homun_data;
struct item;
struct item_data;
-struct unit_data;
struct map_session_data;
-struct homun_data;
struct mercenary_data;
-struct pet_data;
struct mob_data;
struct npc_data;
-struct chat_data;
-struct flooritem_data;
-struct skill_unit;
-struct s_vending;
-struct party;
+struct party_booking_ad_info;
struct party_data;
-struct guild;
-struct battleground_data;
+struct pet_data;
struct quest;
-struct party_booking_ad_info;
-struct view_data;
-struct eri;
+struct s_vending;
struct skill_cd;
-struct channel_data;
+struct skill_unit;
+struct unit_data;
+struct view_data;
/**
* Defines
@@ -47,9 +45,14 @@ struct channel_data;
#define P2PTR(fd) RFIFO2PTR(fd)
#define clif_menuskill_clear(sd) ((sd)->menuskill_id = (sd)->menuskill_val = (sd)->menuskill_val2 = 0)
#define clif_disp_onlyself(sd,mes,len) clif->disp_message( &(sd)->bl, (mes), (len), SELF )
-#define clif_viewequip_fail( sd ) clif->msg( (sd), 0x54d );
#define MAX_ROULETTE_LEVEL 7 /** client-defined value **/
#define MAX_ROULETTE_COLUMNS 9 /** client-defined value **/
+#define RGB2BGR(c) ((c & 0x0000FF) << 16 | (c & 0x00FF00) | (c & 0xFF0000) >> 16)
+
+#define COLOR_RED 0xff0000U
+#define COLOR_GREEN 0x00ff00U
+#define COLOR_WHITE 0xffffffU
+#define COLOR_DEFAULT COLOR_GREEN
/**
* Enumerations
@@ -344,9 +347,30 @@ typedef enum useskill_fail_cause { // clif_skill_fail
}useskill_fail_cause;
enum clif_messages {
- ITEM_CANT_OBTAIN_WEIGHT = 0x34, /* you cannot carry more items because you are overweight. */
- SKILL_CANT_USE_AREA = 0x536,
- ITEM_CANT_USE_AREA = 0x537,
+ MSG_ITEM_CANT_OBTAIN_WEIGHT = 0x034, ///< You cannot carry more items because you are overweight.
+ MSG_ITEM_NEED_STANDING = 0x297, ///< You cannot use this item while sitting.
+ MSG_MERCENARY_EXPIRED = 0x4f2, ///< The mercenary contract has expired.
+ MSG_MERCENARY_DIED = 0x4f3, ///< The mercenary has died.
+ MSG_MERCENARY_RELEASED = 0x4f4, ///< You have released the mercenary.
+ MSG_MERCENARY_ESCAPED = 0x4f5, ///< The mercenary has run away.
+ MSG_SKILL_CANT_USE_AREA = 0x536, ///< This skill cannot be used within this area
+ MSG_ITEM_CANT_USE_AREA = 0x537, ///< This item cannot be used within this area.
+ MSG_EQUIP_NOT_PUBLIC = 0x54d, ///< This character's equipment information is not open to the public.
+ MSG_ITEM_NEED_MADO = 0x59b, ///< Item can only be used when Mado Gear is mounted.
+ MSG_ITEM_NEED_CART = 0x5ef, ///< Usable only when cart is put on
+ MSG_RUNE_STONE_MAX_AMOUNT = 0x61b, ///< Cannot create Rune stone more than the maximum amount.
+ MSG_SKILL_POINTS_LEFT_JOB1 = 0x61e, ///< You must consume all '%d' remaining points in your 1st Job tab.
+ MSG_SKILL_POINTS_LEFT_JOB2 = 0x61f, ///< You must consume all '%d' remaining points in your 2nd Job tab. 1st Tab is already done.
+ MSG_SKILL_ITEM_NOT_FOUND = 0x623, // FIXME[Haru]: This seems to be 0x622 in the msgstringtable files I found.
+ MSG_SKILL_SUCCESS = 0x627, // FIXME[Haru]: This seems to be 0x626 in the msgstringtable files I found.
+ MSG_SKILL_FAILURE = 0x628, // FIXME[Haru]: This seems to be 0x627 in the msgstringtable files I found.
+ MSG_SKILL_ITEM_NEED_IDENTIFY = 0x62d, ///< Unable to use unchecked items as materials.
+ MSG_ITEM_CANT_EQUIP_LVL = 0x6ed, // FIXME[Haru]: This seems to be 0x6ee in the msgstringtable files I found.
+ MSG_ITEM_CANT_USE_LVL = 0x6ee, // FIXME[Haru]: This seems to be 0x6ef in the msgstringtable files I found.
+ MSG_COOKING_LIST_FAIL = 0x625, // FIXME[Haru]: This might be a wrong message ID. Not sure what it should be.
+ MSG_SECONDS_UNTIL_USE = 0x746, ///< %d seconds left until you can use
+ MSG_NPC_WORK_IN_PROGRESS = 0x783, // FIXME[Haru]: This seems to be 0x784 in the msgstringtable files I found.
+ MSG_REINS_CANT_USE_MOUNTED = 0x78b, // FIXME[Haru]: This seems to be 0x785 in the msgstringtalbe files I found.
};
/**
@@ -365,16 +389,6 @@ enum cashshop_error {
ERROR_TYPE_NOT_ALL = 8, ///< Some items could not be purchased. (ERROR_TYPE_NOT_ALL)
};
-/**
- * Color Table
- **/
-enum clif_colors {
- COLOR_RED,
- COLOR_DEFAULT,
- COLOR_WHITE,
- COLOR_MAX
-};
-
enum CASH_SHOP_TABS {
CASHSHOP_TAB_NEW = 0,
CASHSHOP_TAB_POPULAR = 1,
@@ -495,6 +509,30 @@ enum CLOSE_ROULETTE_ACK {
};
/**
+ * Reason for item deletion (clif->delitem)
+ */
+enum delitem_reason {
+ DELITEM_NORMAL = 0, /// Normal
+ DELITEM_SKILLUSE = 1, /// Item used for a skill
+ DELITEM_FAILREFINE = 2, /// Refine failed
+ DELITEM_MATERIALCHANGE = 3, /// Material changed
+ DELITEM_TOSTORAGE = 4, /// Moved to storage
+ DELITEM_TOCART = 5, /// Moved to cart
+ DELITEM_SOLD = 6, /// Item sold
+ DELITEM_ANALYSIS = 7, /// Consumed by Four Spirit Analysis (SO_EL_ANALYSIS) skill
+};
+
+/*
+* Merge items reasons
+*/
+
+enum mergeitem_reason {
+ MERGEITEM_SUCCESS = 0x0,
+ MERGEITEM_FAILD = 0x1,
+ MERGEITEM_MAXCOUNTFAILD = 0x2,
+};
+
+/**
* Structures
**/
typedef void (*pFunc)(int, struct map_session_data *); //cant help but put it first
@@ -514,11 +552,15 @@ struct cdelayed_damage {
struct block_list bl;
};
+struct merge_item {
+ int16 position;
+ int16 nameid;
+};
+
/**
* Vars
**/
struct s_packet_db packet_db[MAX_PACKET_DB + 1];
-unsigned int color_table[COLOR_MAX];
/**
* Clif.c Interface
@@ -796,18 +838,16 @@ struct clif_interface {
void (*disp_message) (struct block_list* src, const char* mes, size_t len, enum send_target target);
void (*broadcast) (struct block_list* bl, const char* mes, size_t len, int type, enum send_target target);
void (*broadcast2) (struct block_list* bl, const char* mes, size_t len, unsigned int fontColor, short fontType, short fontSize, short fontAlign, short fontY, enum send_target target);
- void (*messagecolor) (struct block_list* bl, unsigned int color, const char* msg);
+ void (*messagecolor_self) (int fd, uint32 color, const char *msg);
+ void (*messagecolor) (struct block_list* bl, uint32 color, const char* msg);
void (*disp_overhead) (struct block_list *bl, const char* mes);
- void (*msg) (struct map_session_data* sd, unsigned short id);
- void (*msg_value) (struct map_session_data* sd, unsigned short id, int value);
- void (*msg_skill) (struct map_session_data* sd, uint16 skill_id, int msg_id);
- void (*msgtable) (int fd, int line);
- void (*msgtable_num) (int fd, int line, int num);
+ void (*msgtable) (struct map_session_data* sd, unsigned short msg_id);
+ void (*msgtable_num) (struct map_session_data *sd, unsigned short msg_id, int value);
+ void (*msgtable_skill) (struct map_session_data *sd, uint16 skill_id, int msg_id);
void (*message) (const int fd, const char* mes);
void (*messageln) (const int fd, const char* mes);
/* message+s(printf) */
void (*messages) (const int fd, const char *mes, ...) __attribute__((format(printf, 2, 3)));
- int (*colormes) (int fd, enum clif_colors color, const char* msg);
bool (*process_message) (struct map_session_data *sd, int format, char **name_, size_t *namelen_, char **message_, size_t *messagelen_);
void (*wisexin) (struct map_session_data *sd,int type,int flag);
void (*wisall) (struct map_session_data *sd,int type,int flag);
@@ -1037,6 +1077,12 @@ struct clif_interface {
/* */
bool (*parse_roulette_db) (void);
void (*roulette_generate_ack) (struct map_session_data *sd, unsigned char result, short stage, short prizeIdx, short bonusItemID);
+ /* Merge Items */
+ void (*openmergeitem) (int fd, struct map_session_data *sd);
+ void (*cancelmergeitem) (int fd, struct map_session_data *sd);
+ int (*comparemergeitem) (const void *a, const void *b);
+ void (*ackmergeitems) (int fd, struct map_session_data *sd);
+
/*------------------------
*- Parse Incoming Packet
*------------------------*/
diff --git a/src/map/date.c b/src/map/date.c
index 975a00c50..e2ad2b179 100644
--- a/src/map/date.c
+++ b/src/map/date.c
@@ -5,9 +5,9 @@
#include "date.h"
-#include <time.h>
+#include "common/cbasetypes.h"
-#include "../common/cbasetypes.h"
+#include <time.h>
int date_get_year(void)
{
diff --git a/src/map/date.h b/src/map/date.h
index a57d8132c..e7d06f29d 100644
--- a/src/map/date.h
+++ b/src/map/date.h
@@ -4,7 +4,7 @@
#ifndef MAP_DATE_H
#define MAP_DATE_H
-#include "../common/cbasetypes.h"
+#include "common/cbasetypes.h"
#ifdef HERCULES_CORE
// TODO: Interface
diff --git a/src/map/duel.c b/src/map/duel.c
index 2dae0ae0e..4cd2e276f 100644
--- a/src/map/duel.c
+++ b/src/map/duel.c
@@ -6,16 +6,16 @@
#include "duel.h"
+#include "map/atcommand.h" // msg_txt
+#include "map/clif.h"
+#include "map/pc.h"
+#include "common/cbasetypes.h"
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
-#include "atcommand.h" // msg_txt
-#include "clif.h"
-#include "pc.h"
-#include "../common/cbasetypes.h"
-
struct duel_interface duel_s;
/*==========================================
diff --git a/src/map/duel.h b/src/map/duel.h
index fa12a4032..0c55c1266 100644
--- a/src/map/duel.h
+++ b/src/map/duel.h
@@ -5,7 +5,7 @@
#ifndef MAP_DUEL_H
#define MAP_DUEL_H
-#include "../common/cbasetypes.h"
+#include "common/cbasetypes.h"
struct map_session_data;
diff --git a/src/map/elemental.c b/src/map/elemental.c
index a21c128b0..459ce2a39 100644
--- a/src/map/elemental.c
+++ b/src/map/elemental.c
@@ -6,41 +6,41 @@
#include "elemental.h"
+#include "map/atcommand.h"
+#include "map/battle.h"
+#include "map/chrif.h"
+#include "map/clif.h"
+#include "map/guild.h"
+#include "map/intif.h"
+#include "map/itemdb.h"
+#include "map/log.h"
+#include "map/map.h"
+#include "map/mob.h"
+#include "map/npc.h"
+#include "map/party.h"
+#include "map/pc.h"
+#include "map/pet.h"
+#include "map/script.h"
+#include "map/skill.h"
+#include "map/status.h"
+#include "map/trade.h"
+#include "map/unit.h"
+#include "common/cbasetypes.h"
+#include "common/malloc.h"
+#include "common/mmo.h"
+#include "common/nullpo.h"
+#include "common/random.h"
+#include "common/showmsg.h"
+#include "common/socket.h"
+#include "common/strlib.h"
+#include "common/timer.h"
+#include "common/utils.h"
+
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include "atcommand.h"
-#include "battle.h"
-#include "chrif.h"
-#include "clif.h"
-#include "guild.h"
-#include "intif.h"
-#include "itemdb.h"
-#include "log.h"
-#include "map.h"
-#include "mob.h"
-#include "npc.h"
-#include "party.h"
-#include "pc.h"
-#include "pet.h"
-#include "script.h"
-#include "skill.h"
-#include "status.h"
-#include "trade.h"
-#include "unit.h"
-#include "../common/cbasetypes.h"
-#include "../common/malloc.h"
-#include "../common/mmo.h"
-#include "../common/nullpo.h"
-#include "../common/random.h"
-#include "../common/showmsg.h"
-#include "../common/socket.h"
-#include "../common/strlib.h"
-#include "../common/timer.h"
-#include "../common/utils.h"
-
struct elemental_interface elemental_s;
int elemental_search_index(int class_) {
@@ -442,9 +442,9 @@ int elemental_action(struct elemental_data *ed, struct block_list *bl, int64 tic
ed->ud.skill_lv = skill_lv;
if( skill->get_inf(skill_id) & INF_GROUND_SKILL )
- ed->ud.skilltimer = timer->add( tick+status->get_speed(&ed->bl)*walk_dist, skill->castend_pos, ed->bl.id, 0 );
+ ed->ud.skilltimer = timer->add(tick+(int64)status->get_speed(&ed->bl)*walk_dist, skill->castend_pos, ed->bl.id, 0);
else
- ed->ud.skilltimer = timer->add( tick+status->get_speed(&ed->bl)*walk_dist, skill->castend_id, ed->bl.id, 0 );
+ ed->ud.skilltimer = timer->add(tick+(int64)status->get_speed(&ed->bl)*walk_dist, skill->castend_id, ed->bl.id, 0);
}
return 1;
@@ -560,7 +560,7 @@ int elemental_unlocktarget(struct elemental_data *ed) {
ed->target_id = 0;
elemental_stop_attack(ed);
- elemental_stop_walking(ed,1);
+ elemental_stop_walking(ed, STOPWALKING_FLAG_FIXPOS);
return 0;
}
@@ -586,8 +586,8 @@ struct skill_condition elemental_skill_get_requirements(uint16 skill_id, uint16
if( skill_lv < 1 || skill_lv > MAX_SKILL_LEVEL )
return req;
- req.hp = skill->db[idx].hp[skill_lv-1];
- req.sp = skill->db[idx].sp[skill_lv-1];
+ req.hp = skill->dbs->db[idx].hp[skill_lv-1];
+ req.sp = skill->dbs->db[idx].sp[skill_lv-1];
return req;
}
diff --git a/src/map/elemental.h b/src/map/elemental.h
index 8015f84c0..582e1059c 100644
--- a/src/map/elemental.h
+++ b/src/map/elemental.h
@@ -5,9 +5,12 @@
#ifndef MAP_ELEMENTAL_H
#define MAP_ELEMENTAL_H
-#include "status.h" // struct status_data, struct status_change
-#include "unit.h" // struct unit_data
-#include "../common/mmo.h" // NAME_LENGTH
+#include "map/status.h" // struct status_data, struct status_change
+#include "map/unit.h" // struct unit_data
+#include "common/cbasetypes.h"
+#include "common/mmo.h" // NAME_LENGTH
+
+#include <stdarg.h>
/**
* Defines
diff --git a/src/map/guild.c b/src/map/guild.c
index 936b4c900..5f6ce83c6 100644
--- a/src/map/guild.c
+++ b/src/map/guild.c
@@ -4,37 +4,37 @@
#define HERCULES_CORE
-#include "../config/core.h" // GP_BOUND_ITEMS
+#include "config/core.h" // GP_BOUND_ITEMS
#include "guild.h"
+#include "map/battle.h"
+#include "map/channel.h"
+#include "map/clif.h"
+#include "map/instance.h"
+#include "map/intif.h"
+#include "map/log.h"
+#include "map/map.h"
+#include "map/mob.h"
+#include "map/npc.h"
+#include "map/pc.h"
+#include "map/skill.h"
+#include "map/status.h"
+#include "map/storage.h"
+#include "common/HPM.h"
+#include "common/cbasetypes.h"
+#include "common/ers.h"
+#include "common/malloc.h"
+#include "common/mapindex.h"
+#include "common/nullpo.h"
+#include "common/showmsg.h"
+#include "common/strlib.h"
+#include "common/timer.h"
+#include "common/utils.h"
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include "battle.h"
-#include "channel.h"
-#include "clif.h"
-#include "instance.h"
-#include "intif.h"
-#include "log.h"
-#include "map.h"
-#include "mob.h"
-#include "npc.h"
-#include "pc.h"
-#include "skill.h"
-#include "status.h"
-#include "storage.h"
-#include "../common/HPM.h"
-#include "../common/cbasetypes.h"
-#include "../common/ers.h"
-#include "../common/malloc.h"
-#include "../common/mapindex.h"
-#include "../common/nullpo.h"
-#include "../common/showmsg.h"
-#include "../common/strlib.h"
-#include "../common/timer.h"
-#include "../common/utils.h"
-
struct guild_interface guild_s;
/*==========================================
@@ -343,14 +343,12 @@ int guild_create(struct map_session_data *sd, const char *name)
if( !tname[0] )
return 0; // empty name
- if( sd->status.guild_id )
- {// already in a guild
- clif->guild_created(sd,1);
+ if( sd->status.guild_id ) {
+ clif->guild_created(sd,1); // You're already in a guild
return 0;
}
if (battle_config.guild_emperium_check && pc->search_inventory(sd, ITEMID_EMPERIUM) == INDEX_NOT_FOUND) {
- // item required
- clif->guild_created(sd,3);
+ clif->guild_created(sd,3); // You need the necessary item to create a guild
return 0;
}
@@ -367,14 +365,14 @@ int guild_created(int account_id,int guild_id) {
if(sd==NULL)
return 0;
if(!guild_id) {
- clif->guild_created(sd, 2); // Creation failure (presence of the same name Guild)
+ clif->guild_created(sd, 2); // Creation failure (The guild name already exists)
return 0;
}
//struct guild *g;
sd->status.guild_id=guild_id;
- clif->guild_created(sd,0);
+ clif->guild_created(sd,0); // Success
if(battle_config.guild_emperium_check)
- pc->delitem(sd,pc->search_inventory(sd,ITEMID_EMPERIUM),1,0,0,LOG_TYPE_CONSUME); //emperium consumption
+ pc->delitem(sd, pc->search_inventory(sd, ITEMID_EMPERIUM), 1, 0, DELITEM_NORMAL, LOG_TYPE_CONSUME); //emperium consumption
return 0;
}
@@ -615,7 +613,7 @@ int guild_invite(struct map_session_data *sd, struct map_session_data *tsd) {
if(tsd==NULL || g==NULL)
return 0;
- if( (i=guild->getposition(g,sd))<0 || !(g->position[i].mode&0x0001) )
+ if( (i=guild->getposition(g,sd)) < 0 || !(g->position[i].mode&GPERM_INVITE) )
return 0; //Invite permission.
if(!battle_config.invite_request_check) {
@@ -840,7 +838,7 @@ int guild_expulsion(struct map_session_data* sd, int guild_id, int account_id, i
if(sd->status.guild_id!=guild_id)
return 0;
- if( (ps=guild->getposition(g,sd))<0 || !(g->position[ps].mode&0x0010) )
+ if ((ps=guild->getposition(g,sd))<0 || !(g->position[ps].mode&GPERM_EXPEL))
return 0; //Expulsion permission
//Can't leave inside guild castles.
@@ -895,7 +893,7 @@ int guild_member_withdraw(int guild_id, int account_id, int char_id, int flag, c
// update char, if online
if(sd != NULL && sd->status.guild_id == guild_id) {
// do stuff that needs the guild_id first, BEFORE we wipe it
- if (sd->state.storage_flag == 2) //Close the guild storage.
+ if (sd->state.storage_flag == STORAGE_FLAG_GUILD) //Close the guild storage.
gstorage->close(sd);
guild->send_dot_remove(sd);
if (channel->config->ally) {
@@ -926,7 +924,7 @@ void guild_retrieveitembound(int char_id,int aid,int guild_id) {
if(gstor && gstor->storage_status == 1) { //Someone is in guild storage, close them
struct s_mapiterator* iter = mapit_getallusers();
for( sd = (TBL_PC*)mapit->first(iter); mapit->exists(iter); sd = (TBL_PC*)mapit->next(iter) ) {
- if(sd->status.guild_id == guild_id && sd->state.storage_flag == 2) {
+ if(sd->status.guild_id == guild_id && sd->state.storage_flag == STORAGE_FLAG_GUILD) {
gstorage->close(sd);
break;
}
@@ -1095,9 +1093,7 @@ int guild_change_position(int guild_id,int idx,int mode,int exp_mode,const char
struct guild_position p;
exp_mode = cap_value(exp_mode, 0, battle_config.guild_exp_limit);
- //Mode 0x01 <- Invite
- //Mode 0x10 <- Expel.
- p.mode=mode&0x11;
+ p.mode=mode&GPERM_BOTH; // Invite and Expel
p.exp_mode=exp_mode;
safestrncpy(p.name,name,NAME_LENGTH);
return intif->guild_position(guild_id,idx,&p);
@@ -1750,7 +1746,7 @@ int guild_broken(int guild_id,int flag)
for(i=0;i<g->max_member;i++){
// Destroy all relationships
if((sd=g->member[i].sd)!=NULL){
- if(sd->state.storage_flag == 2)
+ if(sd->state.storage_flag == STORAGE_FLAG_GUILD)
gstorage->pc_quit(sd,1);
sd->status.guild_id=0;
sd->guild = NULL;
@@ -1910,7 +1906,7 @@ int guild_break(struct map_session_data *sd,char *name) {
}
}
- for(i = 0; i < count; i++) {
+ for(i = 0; i < count; i++) { // FIXME: Why is this not done in the above loop?
skill->del_unitgroup(groups[i],ALC_MARK);
}
}
diff --git a/src/map/guild.h b/src/map/guild.h
index a75b8a7a5..18a25af58 100644
--- a/src/map/guild.h
+++ b/src/map/guild.h
@@ -5,10 +5,10 @@
#ifndef MAP_GUILD_H
#define MAP_GUILD_H
-#include "map.h" // EVENT_NAME_LENGTH, TBL_PC
-#include "../common/cbasetypes.h"
-#include "../common/db.h"
-#include "../common/mmo.h"
+#include "map/map.h" // EVENT_NAME_LENGTH, TBL_PC
+#include "common/cbasetypes.h"
+#include "common/db.h"
+#include "common/mmo.h"
/**
* Defines
diff --git a/src/map/homunculus.c b/src/map/homunculus.c
index 51686d3aa..305d60f5b 100644
--- a/src/map/homunculus.c
+++ b/src/map/homunculus.c
@@ -4,50 +4,51 @@
#define HERCULES_CORE
-#include "../config/core.h" // DBPATH
+#include "config/core.h" // DBPATH
#include "homunculus.h"
+#include "map/atcommand.h"
+#include "map/battle.h"
+#include "map/chrif.h"
+#include "map/clif.h"
+#include "map/guild.h"
+#include "map/intif.h"
+#include "map/itemdb.h"
+#include "map/log.h"
+#include "map/map.h"
+#include "map/mob.h"
+#include "map/npc.h"
+#include "map/party.h"
+#include "map/pc.h"
+#include "map/pet.h"
+#include "map/script.h"
+#include "map/skill.h"
+#include "map/status.h"
+#include "map/trade.h"
+#include "map/unit.h"
+#include "common/cbasetypes.h"
+#include "common/malloc.h"
+#include "common/mmo.h"
+#include "common/nullpo.h"
+#include "common/random.h"
+#include "common/showmsg.h"
+#include "common/socket.h"
+#include "common/strlib.h"
+#include "common/timer.h"
+#include "common/utils.h"
+
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include "atcommand.h"
-#include "battle.h"
-#include "chrif.h"
-#include "clif.h"
-#include "guild.h"
-#include "intif.h"
-#include "itemdb.h"
-#include "log.h"
-#include "map.h"
-#include "mob.h"
-#include "npc.h"
-#include "party.h"
-#include "pc.h"
-#include "pet.h"
-#include "script.h"
-#include "skill.h"
-#include "status.h"
-#include "trade.h"
-#include "unit.h"
-#include "../common/cbasetypes.h"
-#include "../common/malloc.h"
-#include "../common/mmo.h"
-#include "../common/nullpo.h"
-#include "../common/random.h"
-#include "../common/showmsg.h"
-#include "../common/socket.h"
-#include "../common/strlib.h"
-#include "../common/timer.h"
-#include "../common/utils.h"
-
struct homunculus_interface homunculus_s;
+struct homun_dbs homundbs;
//Returns the viewdata for homunculus
struct view_data* homunculus_get_viewdata(int class_) {
if (homdb_checkid(class_))
- return &homun->viewdb[class_-HM_CLASS_BASE];
+ return &homun->dbs->viewdb[class_-HM_CLASS_BASE];
return NULL;
}
@@ -193,13 +194,13 @@ int homunculus_calc_skilltree(struct homun_data *hd, int flag_evolve) {
if( hd->homunculus.prev_class != 0 ) {
c = hd->homunculus.prev_class - HM_CLASS_BASE;
- for( i = 0; i < MAX_SKILL_TREE && ( id = homun->skill_tree[c][i].id ) > 0; i++ ) {
+ for( i = 0; i < MAX_SKILL_TREE && ( id = homun->dbs->skill_tree[c][i].id ) > 0; i++ ) {
if( hd->homunculus.hskill[ id - HM_SKILLBASE ].id )
continue; //Skill already known.
if(!battle_config.skillfree) {
for( j = 0; j < MAX_PC_SKILL_REQUIRE; j++ ) {
- if( homun->skill_tree[c][i].need[j].id &&
- homun->checkskill(hd,homun->skill_tree[c][i].need[j].id) < homun->skill_tree[c][i].need[j].lv ) {
+ if( homun->dbs->skill_tree[c][i].need[j].id &&
+ homun->checkskill(hd,homun->dbs->skill_tree[c][i].need[j].id) < homun->dbs->skill_tree[c][i].need[j].lv ) {
f = 0;
break;
}
@@ -214,16 +215,16 @@ int homunculus_calc_skilltree(struct homun_data *hd, int flag_evolve) {
c = hd->homunculus.class_ - HM_CLASS_BASE;
- for( i = 0; i < MAX_SKILL_TREE && ( id = homun->skill_tree[c][i].id ) > 0; i++ ) {
+ for( i = 0; i < MAX_SKILL_TREE && ( id = homun->dbs->skill_tree[c][i].id ) > 0; i++ ) {
if( hd->homunculus.hskill[ id - HM_SKILLBASE ].id )
continue; //Skill already known.
j = ( flag_evolve ) ? 10 : hd->homunculus.intimacy;
- if( j < homun->skill_tree[c][i].intimacylv )
+ if( j < homun->dbs->skill_tree[c][i].intimacylv )
continue;
if(!battle_config.skillfree) {
for( j = 0; j < MAX_PC_SKILL_REQUIRE; j++ ) {
- if( homun->skill_tree[c][i].need[j].id &&
- homun->checkskill(hd,homun->skill_tree[c][i].need[j].id) < homun->skill_tree[c][i].need[j].lv ) {
+ if( homun->dbs->skill_tree[c][i].need[j].id &&
+ homun->checkskill(hd,homun->dbs->skill_tree[c][i].need[j].id) < homun->dbs->skill_tree[c][i].need[j].lv ) {
f = 0;
break;
}
@@ -252,9 +253,9 @@ int homunculus_checkskill(struct homun_data *hd,uint16 skill_id) {
int homunculus_skill_tree_get_max(int id, int b_class) {
int i, skill_id;
b_class -= HM_CLASS_BASE;
- for(i=0;(skill_id=homun->skill_tree[b_class][i].id)>0;i++)
+ for(i=0;(skill_id=homun->dbs->skill_tree[b_class][i].id)>0;i++)
if (id == skill_id)
- return homun->skill_tree[b_class][i].max;
+ return homun->dbs->skill_tree[b_class][i].max;
return skill->get_max(id);
}
@@ -316,7 +317,7 @@ bool homunculus_levelup(struct homun_data *hd) {
hom->skillpts++; //1 skillpoint each 3 base level
hom->exp -= hd->exp_next;
- hd->exp_next = homun->exptable[hom->level - 1];
+ hd->exp_next = homun->dbs->exptable[hom->level - 1];
max = &hd->homunculusDB->gmax;
min = &hd->homunculusDB->gmin;
@@ -366,7 +367,7 @@ int homunculus_change_class(struct homun_data *hd, short class_) {
i = homun->db_search(class_,HOMUNCULUS_CLASS);
if(i < 0)
return 0;
- hd->homunculusDB = &homun->db[i];
+ hd->homunculusDB = &homun->dbs->db[i];
hd->homunculus.class_ = class_;
status->set_viewdata(&hd->bl, class_);
homun->calc_skilltree(hd, 1);
@@ -584,7 +585,7 @@ bool homunculus_feed(struct map_session_data *sd, struct homun_data *hd) {
clif->hom_food(sd,foodID,0);
return false;
}
- pc->delitem(sd,i,1,0,0,LOG_TYPE_CONSUME);
+ pc->delitem(sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_CONSUME);
if ( hd->homunculus.hunger >= 91 ) {
homun->consume_intimacy(hd, 50);
@@ -703,16 +704,16 @@ int homunculus_db_search(int key,int type) {
int i;
for(i=0;i<MAX_HOMUNCULUS_CLASS;i++) {
- if(homun->db[i].base_class <= 0)
+ if(homun->dbs->db[i].base_class <= 0)
continue;
switch(type) {
case HOMUNCULUS_CLASS:
- if(homun->db[i].base_class == key ||
- homun->db[i].evo_class == key)
+ if(homun->dbs->db[i].base_class == key ||
+ homun->dbs->db[i].evo_class == key)
return i;
break;
case HOMUNCULUS_FOOD:
- if(homun->db[i].foodID == key)
+ if(homun->dbs->db[i].foodID == key)
return i;
break;
default:
@@ -729,7 +730,7 @@ bool homunculus_create(struct map_session_data *sd, struct s_homunculus *hom) {
nullpo_retr(false, sd);
- Assert((sd->status.hom_id == 0 || sd->hd == 0) || sd->hd->master == sd);
+ Assert_retr(false, sd->status.hom_id == 0 || sd->hd == 0 || sd->hd->master == sd);
i = homun->db_search(hom->class_,HOMUNCULUS_CLASS);
if(i < 0) {
@@ -743,9 +744,9 @@ bool homunculus_create(struct map_session_data *sd, struct s_homunculus *hom) {
hd->bl.id = npc->get_new_npc_id();
hd->master = sd;
- hd->homunculusDB = &homun->db[i];
+ hd->homunculusDB = &homun->dbs->db[i];
memcpy(&hd->homunculus, hom, sizeof(struct s_homunculus));
- hd->exp_next = homun->exptable[hd->homunculus.level - 1];
+ hd->exp_next = homun->dbs->exptable[hd->homunculus.level - 1];
status->set_viewdata(&hd->bl, hd->homunculus.class_);
status->change_init(&hd->bl);
@@ -879,7 +880,7 @@ bool homunculus_creation_request(struct map_session_data *sd, int class_) {
memset(&hom, 0, sizeof(struct s_homunculus));
//Initial data
- safestrncpy(hom.name, homun->db[i].name, NAME_LENGTH-1);
+ safestrncpy(hom.name, homun->dbs->db[i].name, NAME_LENGTH-1);
hom.class_ = class_;
hom.level = 1;
hom.hunger = 32; //32%
@@ -887,7 +888,7 @@ bool homunculus_creation_request(struct map_session_data *sd, int class_) {
hom.char_id = sd->status.char_id;
hom.hp = 10 ;
- base = &homun->db[i].base;
+ base = &homun->dbs->db[i].base;
hom.max_hp = base->HP;
hom.max_sp = base->SP;
hom.str = base->str *10;
@@ -963,7 +964,7 @@ void homunculus_stat_reset(struct homun_data *hd) {
hom->dex = base->dex *10;
hom->luk = base->luk *10;
hom->exp = 0;
- hd->exp_next = homun->exptable[0];
+ hd->exp_next = homun->dbs->exptable[0];
memset(&hd->homunculus.hskill, 0, sizeof hd->homunculus.hskill);
hd->homunculus.skillpts = 0;
}
@@ -1026,7 +1027,7 @@ bool homunculus_read_db_sub(char* str[], int columns, int current) {
ShowError("homunculus_read_db_sub : Invalid class %d\n", classid);
return false;
}
- db = &homun->db[current];
+ db = &homun->dbs->db[current];
db->base_class = classid;
classid = atoi(str[1]);
if (classid < HM_CLASS_BASE || classid > HM_CLASS_MAX) {
@@ -1129,8 +1130,7 @@ bool homunculus_read_db_sub(char* str[], int columns, int current) {
void homunculus_read_db(void) {
int i;
const char *filename[]={DBPATH"homunculus_db.txt","homunculus_db2.txt"};
-
- memset(homun->db,0,sizeof(homun->db));
+ memset(homun->dbs->db, 0, sizeof(homun->dbs->db));
for(i = 0; i<ARRAYLENGTH(filename); i++) {
if( i > 0 ) {
char filepath[256];
@@ -1165,23 +1165,23 @@ bool homunculus_read_skill_db_sub(char* split[], int columns, int current) {
k = atoi(split[1]); //This is to avoid adding two lines for the same skill. [Skotlex]
// Search an empty line or a line with the same skill_id (stored in j)
- ARR_FIND( 0, MAX_SKILL_TREE, j, !homun->skill_tree[classid][j].id || homun->skill_tree[classid][j].id == k );
+ ARR_FIND( 0, MAX_SKILL_TREE, j, !homun->dbs->skill_tree[classid][j].id || homun->dbs->skill_tree[classid][j].id == k );
if (j == MAX_SKILL_TREE) {
ShowWarning("Unable to load skill %d into homunculus %d's tree. Maximum number of skills per class has been reached.\n", k, classid);
return false;
}
- homun->skill_tree[classid][j].id = k;
- homun->skill_tree[classid][j].max = atoi(split[2]);
+ homun->dbs->skill_tree[classid][j].id = k;
+ homun->dbs->skill_tree[classid][j].max = atoi(split[2]);
if (minJobLevelPresent)
- homun->skill_tree[classid][j].joblv = atoi(split[3]);
+ homun->dbs->skill_tree[classid][j].joblv = atoi(split[3]);
for( k = 0; k < MAX_PC_SKILL_REQUIRE; k++ ) {
- homun->skill_tree[classid][j].need[k].id = atoi(split[3+k*2+minJobLevelPresent]);
- homun->skill_tree[classid][j].need[k].lv = atoi(split[3+k*2+minJobLevelPresent+1]);
+ homun->dbs->skill_tree[classid][j].need[k].id = atoi(split[3+k*2+minJobLevelPresent]);
+ homun->dbs->skill_tree[classid][j].need[k].lv = atoi(split[3+k*2+minJobLevelPresent+1]);
}
- homun->skill_tree[classid][j].intimacylv = atoi(split[13+minJobLevelPresent]);
+ homun->dbs->skill_tree[classid][j].intimacylv = atoi(split[13+minJobLevelPresent]);
return true;
}
@@ -1205,9 +1205,8 @@ int8 homunculus_get_intimacy_grade(struct homun_data *hd) {
}
void homunculus_skill_db_read(void) {
- memset(homun->skill_tree,0,sizeof(homun->skill_tree));
+ memset(homun->dbs->skill_tree, 0, sizeof(homun->dbs->skill_tree));
sv->readdb(map->db_path, "homun_skill_tree.txt", ',', 13, 15, -1, homun->read_skill_db_sub);
-
}
void homunculus_exp_db_read(void) {
@@ -1217,7 +1216,7 @@ void homunculus_exp_db_read(void) {
DBPATH"exp_homun.txt",
"exp_homun2.txt"};
- memset(homun->exptable,0,sizeof(homun->exptable));
+ memset(homun->dbs->exptable, 0, sizeof(homun->dbs->exptable));
for(i = 0; i < 2; i++) {
FILE *fp;
sprintf(line, "%s/%s", map->db_path, filename[i]);
@@ -1231,13 +1230,13 @@ void homunculus_exp_db_read(void) {
if(line[0] == '/' && line[1] == '/')
continue;
- if (!(homun->exptable[j++] = (unsigned int)strtoul(line, NULL, 10)))
+ if (!(homun->dbs->exptable[j++] = (unsigned int)strtoul(line, NULL, 10)))
break;
}
// Last permitted level have to be 0!
- if (homun->exptable[MAX_LEVEL - 1]) {
+ if (homun->dbs->exptable[MAX_LEVEL - 1]) {
ShowWarning("homunculus_exp_db_read: Reached max level in exp_homun [%d]. Remaining lines were not read.\n ", MAX_LEVEL);
- homun->exptable[MAX_LEVEL - 1] = 0;
+ homun->dbs->exptable[MAX_LEVEL - 1] = 0;
}
fclose(fp);
ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' levels in '"CL_WHITE"%s"CL_RESET"'.\n", j, filename[i]);
@@ -1266,9 +1265,9 @@ void do_init_homunculus(bool minimal) {
timer->add_func_list(homun->hunger_timer, "homunculus_hunger_timer");
//Stock view data for homuncs
- memset(&homun->viewdb, 0, sizeof(homun->viewdb));
- for (class_ = 0; class_ < ARRAYLENGTH(homun->viewdb); class_++)
- homun->viewdb[class_].class_ = HM_CLASS_BASE+class_;
+ memset(homun->dbs->viewdb, 0, sizeof(homun->dbs->viewdb));
+ for (class_ = 0; class_ < MAX_HOMUNCULUS_CLASS; class_++)
+ homun->dbs->viewdb[class_].class_ = HM_CLASS_BASE+class_;
}
void do_final_homunculus(void) {
@@ -1277,7 +1276,8 @@ void do_final_homunculus(void) {
void homunculus_defaults(void) {
homun = &homunculus_s;
-
+ homun->dbs = &homundbs;
+
homun->init = do_init_homunculus;
homun->final = do_final_homunculus;
homun->reload = homunculus_reload;
diff --git a/src/map/homunculus.h b/src/map/homunculus.h
index 18f8728d3..95b613fff 100644
--- a/src/map/homunculus.h
+++ b/src/map/homunculus.h
@@ -5,10 +5,11 @@
#ifndef MAP_HOMUNCULUS_H
#define MAP_HOMUNCULUS_H
-#include "pc.h"
-#include "status.h" // struct status_data, struct status_change
-#include "unit.h" // struct unit_data
-#include "../common/mmo.h"
+#include "map/status.h" // struct status_data, struct status_change
+#include "map/unit.h" // struct unit_data
+#include "common/mmo.h"
+
+struct map_session_data;
#define MAX_HOM_SKILL_REQUIRE 5
#define homdb_checkid(id) ((id) >= HM_CLASS_BASE && (id) <= HM_CLASS_MAX)
@@ -98,12 +99,16 @@ enum homun_type {
HT_INVALID = -1, // Invalid Homunculus
};
-/* homunculus.c interface */
-struct homunculus_interface {
+struct homun_dbs {
unsigned int exptable[MAX_LEVEL];
struct view_data viewdb[MAX_HOMUNCULUS_CLASS];
struct s_homunculus_db db[MAX_HOMUNCULUS_CLASS];
struct homun_skill_tree_entry skill_tree[MAX_HOMUNCULUS_CLASS][MAX_SKILL_TREE];
+};
+
+/* homunculus.c interface */
+struct homunculus_interface {
+ struct homun_dbs *dbs;
/* */
void (*init) (bool minimal);
void (*final) (void);
diff --git a/src/map/instance.c b/src/map/instance.c
index dd5709452..f5688d02c 100644
--- a/src/map/instance.c
+++ b/src/map/instance.c
@@ -4,32 +4,33 @@
#define HERCULES_CORE
+#include "config/core.h" // CELL_NOSTACK
#include "instance.h"
+#include "map/channel.h"
+#include "map/clif.h"
+#include "map/guild.h"
+#include "map/map.h"
+#include "map/npc.h"
+#include "map/party.h"
+#include "map/pc.h"
+#include "common/HPM.h"
+#include "common/cbasetypes.h"
+#include "common/db.h"
+#include "common/malloc.h"
+#include "common/nullpo.h"
+#include "common/showmsg.h"
+#include "common/socket.h"
+#include "common/strlib.h"
+#include "common/timer.h"
+#include "common/utils.h"
+
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
-#include "../config/core.h" // CELL_NOSTACK
-#include "channel.h"
-#include "clif.h"
-#include "map.h"
-#include "npc.h"
-#include "party.h"
-#include "pc.h"
-#include "../common/HPM.h"
-#include "../common/cbasetypes.h"
-#include "../common/db.h"
-#include "../common/malloc.h"
-#include "../common/nullpo.h"
-#include "../common/showmsg.h"
-#include "../common/socket.h"
-#include "../common/strlib.h"
-#include "../common/timer.h"
-#include "../common/utils.h"
-
struct instance_interface instance_s;
/// Checks whether given instance id is valid or not.
diff --git a/src/map/instance.h b/src/map/instance.h
index 80bd1f012..e17d6866f 100644
--- a/src/map/instance.h
+++ b/src/map/instance.h
@@ -5,10 +5,11 @@
#ifndef MAP_INSTANCE_H
#define MAP_INSTANCE_H
-#include "script.h" // struct reg_db
-#include "../common/cbasetypes.h"
-#include "../common/mmo.h" // struct point
+#include "map/script.h" // struct reg_db
+#include "common/cbasetypes.h"
+#include "common/mmo.h" // struct point
+struct HPluginData;
struct block_list;
struct map_session_data;
diff --git a/src/map/intif.c b/src/map/intif.c
index 50857baa8..26fd1949c 100644
--- a/src/map/intif.c
+++ b/src/map/intif.c
@@ -3,9 +3,32 @@
#define HERCULES_CORE
-#include "../config/core.h" // GP_BOUND_ITEMS
+#include "config/core.h" // GP_BOUND_ITEMS
#include "intif.h"
+#include "map/atcommand.h"
+#include "map/battle.h"
+#include "map/chrif.h"
+#include "map/clif.h"
+#include "map/elemental.h"
+#include "map/guild.h"
+#include "map/homunculus.h"
+#include "map/log.h"
+#include "map/mail.h"
+#include "map/map.h"
+#include "map/mercenary.h"
+#include "map/party.h"
+#include "map/pc.h"
+#include "map/pet.h"
+#include "map/quest.h"
+#include "map/storage.h"
+#include "common/malloc.h"
+#include "common/nullpo.h"
+#include "common/showmsg.h"
+#include "common/socket.h"
+#include "common/strlib.h"
+#include "common/timer.h"
+
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
@@ -13,29 +36,6 @@
#include <string.h>
#include <sys/types.h>
-#include "atcommand.h"
-#include "battle.h"
-#include "chrif.h"
-#include "clif.h"
-#include "elemental.h"
-#include "guild.h"
-#include "homunculus.h"
-#include "log.h"
-#include "mail.h"
-#include "map.h"
-#include "mercenary.h"
-#include "party.h"
-#include "pc.h"
-#include "pet.h"
-#include "quest.h"
-#include "storage.h"
-#include "../common/malloc.h"
-#include "../common/nullpo.h"
-#include "../common/showmsg.h"
-#include "../common/socket.h"
-#include "../common/strlib.h"
-#include "../common/timer.h"
-
struct intif_interface intif_s;
#define inter_fd (chrif->fd) // alias
@@ -130,7 +130,7 @@ int intif_rename(struct map_session_data *sd, int type, char *name)
// GM Send a message
int intif_broadcast(const char* mes, size_t len, int type)
{
- int lp = (type|BC_COLOR_MASK) ? 4 : 0;
+ int lp = (type&BC_COLOR_MASK) ? 4 : 0;
// Send to the local players
clif->broadcast(NULL, mes, len, type, ALL_CLIENT);
@@ -149,9 +149,9 @@ int intif_broadcast(const char* mes, size_t len, int type)
WFIFOW(inter_fd,10) = 0; // fontSize not used with standard broadcast
WFIFOW(inter_fd,12) = 0; // fontAlign not used with standard broadcast
WFIFOW(inter_fd,14) = 0; // fontY not used with standard broadcast
- if( type|BC_BLUE )
+ if (type&BC_BLUE)
WFIFOL(inter_fd,16) = 0x65756c62; //If there's "blue" at the beginning of the message, game client will display it in blue instead of yellow.
- else if( type|BC_WOE )
+ else if (type&BC_WOE)
WFIFOL(inter_fd,16) = 0x73737373; //If there's "ssss", game client will recognize message as 'WoE broadcast'.
memcpy(WFIFOP(inter_fd,16 + lp), mes, len);
WFIFOSET(inter_fd, WFIFOW(inter_fd,2));
@@ -2152,7 +2152,7 @@ void intif_parse_MessageToFD(int fd) {
if( sd && sd->bl.id == aid ) {
char msg[512];
safestrncpy(msg, (char*)RFIFOP(fd,12), RFIFOW(fd,2) - 12);
- clif->message(u_fd,msg);
+ clif->messagecolor_self(u_fd, COLOR_DEFAULT ,msg);
}
}
diff --git a/src/map/intif.h b/src/map/intif.h
index 52aa32259..3303feb6e 100644
--- a/src/map/intif.h
+++ b/src/map/intif.h
@@ -5,7 +5,7 @@
#ifndef MAP_INTIF_H
#define MAP_INTIF_H
-#include "../common/cbasetypes.h"
+#include "common/cbasetypes.h"
/**
* Declarations
diff --git a/src/map/irc-bot.c b/src/map/irc-bot.c
index d492ad9ca..b0f687c0d 100644
--- a/src/map/irc-bot.c
+++ b/src/map/irc-bot.c
@@ -1,26 +1,26 @@
// Copyright (c) Hercules Dev Team, licensed under GNU GPL.
// See the LICENSE file
-// Base Author: shennetsind @ http://hercules.ws
+// Base Author: shennetsind @ http://herc.ws
#define HERCULES_CORE
#include "irc-bot.h"
+#include "map/channel.h"
+#include "map/map.h"
+#include "map/pc.h"
+#include "common/cbasetypes.h"
+#include "common/malloc.h"
+#include "common/random.h"
+#include "common/showmsg.h"
+#include "common/socket.h"
+#include "common/strlib.h"
+#include "common/timer.h"
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include "channel.h"
-#include "map.h"
-#include "pc.h"
-#include "../common/cbasetypes.h"
-#include "../common/malloc.h"
-#include "../common/random.h"
-#include "../common/showmsg.h"
-#include "../common/socket.h"
-#include "../common/strlib.h"
-#include "../common/timer.h"
-
//#define IRCBOT_DEBUG
struct irc_bot_interface irc_bot_s;
diff --git a/src/map/irc-bot.h b/src/map/irc-bot.h
index 8dcfea5bd..b0bfd72f8 100644
--- a/src/map/irc-bot.h
+++ b/src/map/irc-bot.h
@@ -1,12 +1,12 @@
// Copyright (c) Hercules Dev Team, licensed under GNU GPL.
// See the LICENSE file
-// Base Author: shennetsind @ http://hercules.ws
+// Base Author: shennetsind @ http://herc.ws
#ifndef MAP_IRC_BOT_H
#define MAP_IRC_BOT_H
-#include "../common/cbasetypes.h"
+#include "common/cbasetypes.h"
#define IRC_NICK_LENGTH 40
#define IRC_IDENT_LENGTH 40
diff --git a/src/map/itemdb.c b/src/map/itemdb.c
index fb6bcc730..09303978c 100644
--- a/src/map/itemdb.c
+++ b/src/map/itemdb.c
@@ -4,27 +4,27 @@
#define HERCULES_CORE
-#include "../config/core.h" // DBPATH, RENEWAL
+#include "config/core.h" // DBPATH, RENEWAL
#include "itemdb.h"
+#include "map/battle.h" // struct battle_config
+#include "map/map.h"
+#include "map/mob.h" // MAX_MOB_DB
+#include "map/pc.h" // W_MUSICAL, W_WHIP
+#include "map/script.h" // item script processing
+#include "common/HPM.h"
+#include "common/conf.h"
+#include "common/malloc.h"
+#include "common/nullpo.h"
+#include "common/random.h"
+#include "common/showmsg.h"
+#include "common/strlib.h"
+#include "common/utils.h"
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include "battle.h" // struct battle_config
-#include "map.h"
-#include "mob.h" // MAX_MOB_DB
-#include "pc.h" // W_MUSICAL, W_WHIP
-#include "script.h" // item script processing
-#include "../common/HPM.h"
-#include "../common/conf.h"
-#include "../common/malloc.h"
-#include "../common/nullpo.h"
-#include "../common/random.h"
-#include "../common/showmsg.h"
-#include "../common/strlib.h"
-#include "../common/utils.h"
-
struct itemdb_interface itemdb_s;
/**
@@ -199,6 +199,9 @@ void itemdb_package_item(struct map_session_data *sd, struct item_package *packa
if( package->must_items[i].announce )
clif->package_announce(sd,package->must_items[i].id,package->id);
+ if ( package->must_items[i].force_serial )
+ it.unique_id = itemdb->unique_id(sd);
+
get_count = itemdb->isstackable(package->must_items[i].id) ? package->must_items[i].qty : 1;
it.amount = get_count == 1 ? 1 : get_count;
@@ -719,7 +722,7 @@ void itemdb_write_cached_packages(const char *config_filename) {
//now we loop into must
for(c = 0; c < must_qty; c++) {
struct item_package_must_entry *entry = &itemdb->packages[i].must_items[c];
- unsigned char announce = entry->announce == 1 ? 1 : 0, named = entry->named == 1 ? 1 : 0;
+ unsigned char announce = entry->announce == 1 ? 1 : 0, named = entry->named == 1 ? 1 : 0, force_serial = entry->force_serial == 1 ? 1 : 0;
//first 2 byte = item id
hwrite(&entry->id,sizeof(entry->id),1,file);
//next 2 byte = qty
@@ -729,7 +732,9 @@ void itemdb_write_cached_packages(const char *config_filename) {
//next 1 byte = announce (1:0)
hwrite(&announce,sizeof(announce),1,file);
//next 1 byte = named (1:0)
- hwrite(&named,sizeof(announce),1,file);
+ hwrite(&named,sizeof(named),1,file);
+ //next 1 byte = ForceSerial (1:0)
+ hwrite(&force_serial,sizeof(force_serial),1,file);
}
//now we loop into random groups
for(c = 0; c < random_qty; c++) {
@@ -741,7 +746,7 @@ void itemdb_write_cached_packages(const char *config_filename) {
//now we loop into the group's list
for(h = 0; h < group_qty; h++) {
struct item_package_rand_entry *entry = &itemdb->packages[i].random_groups[c].random_list[h];
- unsigned char announce = entry->announce == 1 ? 1 : 0, named = entry->named == 1 ? 1 : 0;
+ unsigned char announce = entry->announce == 1 ? 1 : 0, named = entry->named == 1 ? 1 : 0, force_serial = entry->force_serial == 1 ? 1 : 0;
//first 2 byte = item id
hwrite(&entry->id,sizeof(entry->id),1,file);
//next 2 byte = qty
@@ -753,7 +758,9 @@ void itemdb_write_cached_packages(const char *config_filename) {
//next 1 byte = announce (1:0)
hwrite(&announce,sizeof(announce),1,file);
//next 1 byte = named (1:0)
- hwrite(&named,sizeof(announce),1,file);
+ hwrite(&named,sizeof(named),1,file);
+ //next 1 byte = ForceSerial (1:0)
+ hwrite(&force_serial,sizeof(force_serial),1,file);
}
}
}
@@ -807,7 +814,7 @@ bool itemdb_read_cached_packages(const char *config_filename) {
for(c = 0; c < package->must_qty; c++) {
struct item_package_must_entry *entry = &itemdb->packages[i].must_items[c];
unsigned short mid = 0, qty = 0, hours = 0;
- unsigned char announce = 0, named = 0;
+ unsigned char announce = 0, named = 0, force_serial = 0;
struct item_data *data;
//first 2 byte = item id
hread(&mid,sizeof(mid),1,file);
@@ -818,8 +825,10 @@ bool itemdb_read_cached_packages(const char *config_filename) {
//next 1 byte = announce (1:0)
hread(&announce,sizeof(announce),1,file);
//next 1 byte = named (1:0)
- hread(&named,sizeof(announce),1,file);
-
+ hread(&named,sizeof(named),1,file);
+ //next 1 byte = ForceSerial (1:0)
+ hread(&force_serial,sizeof(force_serial),1,file);
+
if( !(data = itemdb->exists(mid)) )
ShowWarning("itemdb_read_cached_packages: unknown item '%d' in package '%s'!\n",mid,itemdb_name(package->id));
@@ -828,6 +837,7 @@ bool itemdb_read_cached_packages(const char *config_filename) {
entry->qty = qty;
entry->announce = announce ? 1 : 0;
entry->named = named ? 1 : 0;
+ entry->force_serial = force_serial ? 1 : 0;
}
}
if( package->random_qty ) {
@@ -847,7 +857,7 @@ bool itemdb_read_cached_packages(const char *config_filename) {
for(h = 0; h < group_qty; h++) {
struct item_package_rand_entry *entry = &itemdb->packages[i].random_groups[c].random_list[h];
unsigned short mid = 0, qty = 0, hours = 0, rate = 0;
- unsigned char announce = 0, named = 0;
+ unsigned char announce = 0, named = 0, force_serial = 0;
struct item_data *data;
if( prev ) prev->next = entry;
@@ -863,8 +873,10 @@ bool itemdb_read_cached_packages(const char *config_filename) {
//next 1 byte = announce (1:0)
hread(&announce,sizeof(announce),1,file);
//next 1 byte = named (1:0)
- hread(&named,sizeof(announce),1,file);
-
+ hread(&named,sizeof(named),1,file);
+ //next 1 byte = ForceSerial (1:0)
+ hread(&force_serial,sizeof(force_serial),1,file);
+
if( !(data = itemdb->exists(mid)) )
ShowWarning("itemdb_read_cached_packages: unknown item '%d' in package '%s'!\n",mid,itemdb_name(package->id));
@@ -874,7 +886,7 @@ bool itemdb_read_cached_packages(const char *config_filename) {
entry->qty = qty;
entry->announce = announce ? 1 : 0;
entry->named = named ? 1 : 0;
-
+ entry->force_serial = force_serial ? 1 : 0;
prev = entry;
}
if( prev )
@@ -1020,7 +1032,7 @@ void itemdb_read_packages(void) {
c = 0;
while( (it = libconfig->setting_get_elem(itg,c++)) ) {
int icount = 1, expire = 0, rate = 10000, gid = 0;
- bool announce = false, named = false;
+ bool announce = false, named = false, force_serial = false;
itname = config_setting_name(it);
@@ -1049,6 +1061,9 @@ void itemdb_read_packages(void) {
if( ( t = libconfig->setting_get_member(it, "Named")) && libconfig->setting_get_bool(t) )
named = true;
+ if( ( t = libconfig->setting_get_member(it, "ForceSerial")) && libconfig->setting_get_bool(t) )
+ force_serial = true;
+
if( !( t = libconfig->setting_get_member(it, "Random") ) ) {
ShowWarning("itemdb_read_packages: missing 'Random' field for item '%s' in package '%s', defaulting to must!\n",itname,config_setting_name(itg));
gid = 0;
@@ -1061,6 +1076,7 @@ void itemdb_read_packages(void) {
itemdb->packages[count].must_items[m].hours = expire;
itemdb->packages[count].must_items[m].announce = announce == true ? 1 : 0;
itemdb->packages[count].must_items[m].named = named == true ? 1 : 0;
+ itemdb->packages[count].must_items[m].force_serial = force_serial == true ? 1 : 0;
m++;
} else {
int gidx = gid - 1;
@@ -1078,6 +1094,7 @@ void itemdb_read_packages(void) {
itemdb->packages[count].random_groups[gidx].random_list[r].hours = expire;
itemdb->packages[count].random_groups[gidx].random_list[r].announce = announce == true ? 1 : 0;
itemdb->packages[count].random_groups[gidx].random_list[r].named = named == true ? 1 : 0;
+ itemdb->packages[count].random_groups[gidx].random_list[r].force_serial = force_serial == true ? 1 : 0;
itemdb->packages[count].random_groups[gidx].random_qty += 1;
prev[gidx] = &itemdb->packages[count].random_groups[gidx].random_list[r];
@@ -1583,14 +1600,15 @@ int itemdb_readdb_sql_sub(Sql *handle, int n, const char *source) {
SQL->GetData(handle, 19, &data, NULL); id.flag.no_refine = data && atoi(data) ? 0 : 1;
SQL->GetData(handle, 20, &data, NULL); id.look = data ? atoi(data) : 0;
SQL->GetData(handle, 21, &data, NULL); id.flag.bindonequip = data && atoi(data) ? 1 : 0;
- SQL->GetData(handle, 22, &data, NULL); id.flag.buyingstore = data && atoi(data) ? 1 : 0;
- SQL->GetData(handle, 23, &data, NULL); id.delay = data ? atoi(data) : 0;
- SQL->GetData(handle, 24, &data, NULL); id.flag.trade_restriction = data ? atoi(data) : ITR_NONE;
- SQL->GetData(handle, 25, &data, NULL); id.gm_lv_trade_override = data ? atoi(data) : 0;
- SQL->GetData(handle, 26, &data, NULL); id.item_usage.flag = data ? atoi(data) : INR_NONE;
- SQL->GetData(handle, 27, &data, NULL); id.item_usage.override = data ? atoi(data) : 0;
- SQL->GetData(handle, 28, &data, NULL); id.stack.amount = data ? atoi(data) : 0;
- SQL->GetData(handle, 29, &data, NULL);
+ SQL->GetData(handle, 22, &data, NULL); id.flag.force_serial = data && atoi(data) ? 1 : 0;
+ SQL->GetData(handle, 23, &data, NULL); id.flag.buyingstore = data && atoi(data) ? 1 : 0;
+ SQL->GetData(handle, 24, &data, NULL); id.delay = data ? atoi(data) : 0;
+ SQL->GetData(handle, 25, &data, NULL); id.flag.trade_restriction = data ? atoi(data) : ITR_NONE;
+ SQL->GetData(handle, 26, &data, NULL); id.gm_lv_trade_override = data ? atoi(data) : 0;
+ SQL->GetData(handle, 27, &data, NULL); id.item_usage.flag = data ? atoi(data) : INR_NONE;
+ SQL->GetData(handle, 28, &data, NULL); id.item_usage.override = data ? atoi(data) : 0;
+ SQL->GetData(handle, 29, &data, NULL); id.stack.amount = data ? atoi(data) : 0;
+ SQL->GetData(handle, 30, &data, NULL);
if (data) {
int stack_flag = atoi(data);
id.stack.inventory = (stack_flag&1)!=0;
@@ -1598,15 +1616,15 @@ int itemdb_readdb_sql_sub(Sql *handle, int n, const char *source) {
id.stack.storage = (stack_flag&4)!=0;
id.stack.guildstorage = (stack_flag&8)!=0;
}
- SQL->GetData(handle, 30, &data, NULL);
+ SQL->GetData(handle, 31, &data, NULL);
if (data) {
id.view_id = atoi(data);
if (id.view_id)
id.flag.available = 1;
}
- SQL->GetData(handle, 31, &data, NULL); id.script = data && *data ? script->parse(data, source, -id.nameid, SCRIPT_IGNORE_EXTERNAL_BRACKETS, NULL) : NULL;
- SQL->GetData(handle, 32, &data, NULL); id.equip_script = data && *data ? script->parse(data, source, -id.nameid, SCRIPT_IGNORE_EXTERNAL_BRACKETS, NULL) : NULL;
- SQL->GetData(handle, 33, &data, NULL); id.unequip_script = data && *data ? script->parse(data, source, -id.nameid, SCRIPT_IGNORE_EXTERNAL_BRACKETS, NULL) : NULL;
+ SQL->GetData(handle, 32, &data, NULL); id.script = data && *data ? script->parse(data, source, -id.nameid, SCRIPT_IGNORE_EXTERNAL_BRACKETS, NULL) : NULL;
+ SQL->GetData(handle, 33, &data, NULL); id.equip_script = data && *data ? script->parse(data, source, -id.nameid, SCRIPT_IGNORE_EXTERNAL_BRACKETS, NULL) : NULL;
+ SQL->GetData(handle, 34, &data, NULL); id.unequip_script = data && *data ? script->parse(data, source, -id.nameid, SCRIPT_IGNORE_EXTERNAL_BRACKETS, NULL) : NULL;
return itemdb->validate_entry(&id, n, source);
}
@@ -1657,6 +1675,7 @@ int itemdb_readdb_libconfig_sub(config_setting_t *it, int n, const char *source)
* BindOnEquip: (true or false)
* BuyingStore: (true or false)
* Delay: Delay to use item
+ * ForceSerial: (true or false)
* Trade: {
* override: Group to override
* nodrop: (true or false)
@@ -1790,6 +1809,9 @@ int itemdb_readdb_libconfig_sub(config_setting_t *it, int n, const char *source)
if( (t = libconfig->setting_get_member(it, "BindOnEquip")) )
id.flag.bindonequip = libconfig->setting_get_bool(t) ? 1 : 0;
+
+ if( (t = libconfig->setting_get_member(it, "ForceSerial")) )
+ id.flag.force_serial = libconfig->setting_get_bool(t) ? 1 : 0;
if ( (t = libconfig->setting_get_member(it, "BuyingStore")) )
id.flag.buyingstore = libconfig->setting_get_bool(t) ? 1 : 0;
@@ -1992,7 +2014,7 @@ int itemdb_readdb_sql(const char *tablename) {
" `matk`, `defence`, `range`, `slots`,"
" `equip_jobs`, `equip_upper`, `equip_genders`, `equip_locations`,"
" `weapon_level`, `equip_level_min`, `equip_level_max`, `refineable`,"
- " `view`, `bindonequip`, `buyingstore`, `delay`,"
+ " `view`, `bindonequip`, `forceserial`, `buyingstore`, `delay`,"
" `trade_flag`, `trade_group`, `nouse_flag`, `nouse_group`,"
" `stack_amount`, `stack_flag`, `sprite`, `script`,"
" `equip_script`, `unequip_script`"
diff --git a/src/map/itemdb.h b/src/map/itemdb.h
index 1d811e3cb..e50ebfd3d 100644
--- a/src/map/itemdb.h
+++ b/src/map/itemdb.h
@@ -5,18 +5,14 @@
#ifndef MAP_ITEMDB_H
#define MAP_ITEMDB_H
-#include "map.h"
-#include "../common/cbasetypes.h"
-#include "../common/conf.h"
-#include "../common/db.h"
-#include "../common/mmo.h" // ITEM_NAME_LENGTH
-#include "../common/sql.h"
+/* #include "map/map.h" */
+#include "common/cbasetypes.h"
+#include "common/conf.h"
+#include "common/db.h"
+#include "common/mmo.h" // ITEM_NAME_LENGTH
+#include "common/sql.h"
-/**
- * Declarations
- **/
-struct item_group;
-struct item_package;
+struct script_code;
/**
* Defines
@@ -371,6 +367,63 @@ enum ItemNouseRestrictions {
INR_ALL = 0x1 ///< Sum of all the above values
};
+struct item_combo {
+ struct script_code *script;
+ unsigned short nameid[MAX_ITEMS_PER_COMBO];/* nameid array */
+ unsigned char count;
+ unsigned short id;/* id of this combo */
+};
+
+struct item_group {
+ unsigned short id;
+ unsigned short *nameid;
+ unsigned short qty;
+};
+
+struct item_chain_entry {
+ unsigned short id;
+ unsigned short rate;
+ struct item_chain_entry *next;
+};
+
+struct item_chain {
+ struct item_chain_entry *items;
+ unsigned short qty;
+};
+
+struct item_package_rand_entry {
+ unsigned short id;
+ unsigned short qty;
+ unsigned short rate;
+ unsigned short hours;
+ unsigned int announce : 1;
+ unsigned int named : 1;
+ unsigned int force_serial: 1;
+ struct item_package_rand_entry *next;
+};
+
+struct item_package_must_entry {
+ unsigned short id;
+ unsigned short qty;
+ unsigned short hours;
+ unsigned int announce : 1;
+ unsigned int named : 1;
+ unsigned int force_serial : 1;
+};
+
+struct item_package_rand_group {
+ struct item_package_rand_entry *random_list;
+ unsigned short random_qty;
+};
+
+struct item_package {
+ unsigned short id;
+ struct item_package_rand_group *random_groups;
+ struct item_package_must_entry *must_items;
+ unsigned short random_qty;
+ unsigned short must_qty;
+};
+
struct item_data {
uint16 nameid;
char name[ITEM_NAME_LENGTH],jname[ITEM_NAME_LENGTH];
@@ -415,6 +468,7 @@ struct item_data {
unsigned buyingstore : 1;
unsigned bindonequip : 1;
unsigned keepafteruse : 1;
+ unsigned force_serial : 1;
} flag;
struct {// item stacking limitation
unsigned short amount;
@@ -440,61 +494,6 @@ struct item_data {
unsigned int hdatac;
};
-struct item_combo {
- struct script_code *script;
- unsigned short nameid[MAX_ITEMS_PER_COMBO];/* nameid array */
- unsigned char count;
- unsigned short id;/* id of this combo */
-};
-
-struct item_group {
- unsigned short id;
- unsigned short *nameid;
- unsigned short qty;
-};
-
-struct item_chain_entry {
- unsigned short id;
- unsigned short rate;
- struct item_chain_entry *next;
-};
-
-struct item_chain {
- struct item_chain_entry *items;
- unsigned short qty;
-};
-
-struct item_package_rand_entry {
- unsigned short id;
- unsigned short qty;
- unsigned short rate;
- unsigned short hours;
- unsigned int announce : 1;
- unsigned int named : 1;
- struct item_package_rand_entry *next;
-};
-
-struct item_package_must_entry {
- unsigned short id;
- unsigned short qty;
- unsigned short hours;
- unsigned int announce : 1;
- unsigned int named : 1;
-};
-
-struct item_package_rand_group {
- struct item_package_rand_entry *random_list;
- unsigned short random_qty;
-};
-
-struct item_package {
- unsigned short id;
- struct item_package_rand_group *random_groups;
- struct item_package_must_entry *must_items;
- unsigned short random_qty;
- unsigned short must_qty;
-};
-
#define itemdb_name(n) (itemdb->search(n)->name)
#define itemdb_jname(n) (itemdb->search(n)->jname)
#define itemdb_type(n) (itemdb->search(n)->type)
diff --git a/src/map/log.c b/src/map/log.c
index f18efbfb7..0a9b16418 100644
--- a/src/map/log.c
+++ b/src/map/log.c
@@ -6,22 +6,22 @@
#include "log.h"
+#include "map/battle.h"
+#include "map/itemdb.h"
+#include "map/map.h"
+#include "map/mob.h"
+#include "map/pc.h"
+#include "common/cbasetypes.h"
+#include "common/nullpo.h"
+#include "common/showmsg.h"
+#include "common/sql.h" // SQL_INNODB
+#include "common/strlib.h"
+#include "common/HPM.h"
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include "battle.h"
-#include "itemdb.h"
-#include "map.h"
-#include "mob.h"
-#include "pc.h"
-#include "../common/cbasetypes.h"
-#include "../common/nullpo.h"
-#include "../common/showmsg.h"
-#include "../common/sql.h" // SQL_INNODB
-#include "../common/strlib.h"
-#include "../common/HPM.h"
-
struct log_interface log_s;
/// obtain log type character for item/zeny logs
diff --git a/src/map/log.h b/src/map/log.h
index b4b8b84f4..ef654149c 100644
--- a/src/map/log.h
+++ b/src/map/log.h
@@ -5,8 +5,8 @@
#ifndef MAP_LOG_H
#define MAP_LOG_H
-#include "../common/cbasetypes.h"
-#include "../common/sql.h"
+#include "common/cbasetypes.h"
+#include "common/sql.h"
/**
* Declarations
diff --git a/src/map/mail.c b/src/map/mail.c
index 7ba7d7470..184e2be8d 100644
--- a/src/map/mail.c
+++ b/src/map/mail.c
@@ -6,17 +6,18 @@
#include "mail.h"
+#include "map/atcommand.h"
+#include "map/clif.h"
+#include "map/itemdb.h"
+#include "map/log.h"
+#include "map/pc.h"
+#include "map/storage.h"
+#include "common/nullpo.h"
+#include "common/showmsg.h"
+
#include <time.h>
#include <string.h>
-#include "atcommand.h"
-#include "clif.h"
-#include "itemdb.h"
-#include "log.h"
-#include "pc.h"
-#include "../common/nullpo.h"
-#include "../common/showmsg.h"
-
struct mail_interface mail_s;
void mail_clear(struct map_session_data *sd)
@@ -36,7 +37,7 @@ int mail_removeitem(struct map_session_data *sd, short flag)
if( sd->mail.amount )
{
if (flag) // Item send
- pc->delitem(sd, sd->mail.index, sd->mail.amount, 1, 0, LOG_TYPE_MAIL);
+ pc->delitem(sd, sd->mail.index, sd->mail.amount, 1, DELITEM_NORMAL, LOG_TYPE_MAIL);
else
clif->additem(sd, sd->mail.index, sd->mail.amount, 0);
}
@@ -151,7 +152,7 @@ int mail_openmail(struct map_session_data *sd)
{
nullpo_ret(sd);
- if( sd->state.storage_flag || sd->state.vending || sd->state.buyingstore || sd->state.trading )
+ if (sd->state.storage_flag != STORAGE_FLAG_CLOSED || sd->state.vending || sd->state.buyingstore || sd->state.trading)
return 0;
clif->mail_window(sd->fd, 0);
diff --git a/src/map/mail.h b/src/map/mail.h
index db49ca39e..4f325067d 100644
--- a/src/map/mail.h
+++ b/src/map/mail.h
@@ -5,7 +5,7 @@
#ifndef MAP_MAIL_H
#define MAP_MAIL_H
-#include "../common/cbasetypes.h"
+#include "common/cbasetypes.h"
struct item;
struct mail_message;
diff --git a/src/map/map.c b/src/map/map.c
index c79d49c3e..dc935079a 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -4,65 +4,64 @@
#define HERCULES_CORE
-#include "../config/core.h" // CELL_NOSTACK, CIRCULAR_AREA, CONSOLE_INPUT, DBPATH, RENEWAL
+#include "config/core.h" // CELL_NOSTACK, CIRCULAR_AREA, CONSOLE_INPUT, DBPATH, RENEWAL
#include "map.h"
+#include "map/HPMmap.h"
+#include "map/atcommand.h"
+#include "map/battle.h"
+#include "map/battleground.h"
+#include "map/channel.h"
+#include "map/chat.h"
+#include "map/chrif.h"
+#include "map/clif.h"
+#include "map/duel.h"
+#include "map/elemental.h"
+#include "map/guild.h"
+#include "map/homunculus.h"
+#include "map/instance.h"
+#include "map/intif.h"
+#include "map/irc-bot.h"
+#include "map/itemdb.h"
+#include "map/log.h"
+#include "map/mail.h"
+#include "map/mapreg.h"
+#include "map/mercenary.h"
+#include "map/mob.h"
+#include "map/npc.h"
+#include "map/npc.h" // npc_setcells(), npc_unsetcells()
+#include "map/party.h"
+#include "map/path.h"
+#include "map/pc.h"
+#include "map/pet.h"
+#include "map/quest.h"
+#include "map/script.h"
+#include "map/skill.h"
+#include "map/status.h"
+#include "map/storage.h"
+#include "map/trade.h"
+#include "map/unit.h"
+#include "common/HPM.h"
+#include "common/cbasetypes.h"
+#include "common/conf.h"
+#include "common/console.h"
+#include "common/core.h"
+#include "common/ers.h"
+#include "common/grfio.h"
+#include "common/malloc.h"
+#include "common/nullpo.h"
+#include "common/random.h"
+#include "common/showmsg.h"
+#include "common/socket.h" // WFIFO*()
+#include "common/strlib.h"
+#include "common/timer.h"
+#include "common/utils.h"
+
#include <math.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-
-#include "HPMmap.h"
-#include "atcommand.h"
-#include "battle.h"
-#include "battleground.h"
-#include "channel.h"
-#include "chat.h"
-#include "chrif.h"
-#include "clif.h"
-#include "duel.h"
-#include "elemental.h"
-#include "guild.h"
-#include "homunculus.h"
-#include "instance.h"
-#include "intif.h"
-#include "irc-bot.h"
-#include "itemdb.h"
-#include "log.h"
-#include "mail.h"
-#include "mapreg.h"
-#include "mercenary.h"
-#include "mob.h"
-#include "npc.h"
-#include "npc.h" // npc_setcells(), npc_unsetcells()
-#include "party.h"
-#include "path.h"
-#include "pc.h"
-#include "pet.h"
-#include "quest.h"
-#include "script.h"
-#include "skill.h"
-#include "status.h"
-#include "storage.h"
-#include "trade.h"
-#include "unit.h"
-#include "../common/HPM.h"
-#include "../common/cbasetypes.h"
-#include "../common/conf.h"
-#include "../common/console.h"
-#include "../common/core.h"
-#include "../common/ers.h"
-#include "../common/grfio.h"
-#include "../common/malloc.h"
-#include "../common/nullpo.h"
-#include "../common/random.h"
-#include "../common/showmsg.h"
-#include "../common/socket.h" // WFIFO*()
-#include "../common/strlib.h"
-#include "../common/timer.h"
-#include "../common/utils.h"
-
#ifndef _WIN32
#include <unistd.h>
#endif
@@ -1844,13 +1843,13 @@ int map_quit(struct map_session_data *sd) {
for( i = 0; i < EQI_MAX; i++ ) {
if( sd->equip_index[ i ] >= 0 )
if( !pc->isequip( sd , sd->equip_index[ i ] ) )
- pc->unequipitem( sd , sd->equip_index[ i ] , 2 );
+ pc->unequipitem(sd, sd->equip_index[i], PCUNEQUIPITEM_FORCE);
}
// Return loot to owner
if( sd->pd ) pet->lootitem_drop(sd->pd, sd);
- if( sd->state.storage_flag == 1 ) sd->state.storage_flag = 0; // No need to Double Save Storage on Quit.
+ if( sd->state.storage_flag == STORAGE_FLAG_NORMAL ) sd->state.storage_flag = STORAGE_FLAG_CLOSED; // No need to Double Save Storage on Quit.
if( sd->ed ) {
elemental->clean_effect(sd->ed);
@@ -6140,10 +6139,7 @@ void map_defaults(void) {
map->bl_list_size = 0;
//all in a big chunk, respects order
- memset(&map->bl_head,0,sizeof(map->bl_head)
- + sizeof(map->zone_all)
- + sizeof(map->zone_pk)
- );
+ memset(ZEROED_BLOCK_POS(map), 0, ZEROED_BLOCK_SIZE(map));
map->cpsd = NULL;
map->list = NULL;
diff --git a/src/map/map.h b/src/map/map.h
index 26aac7720..8d879cd56 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -5,17 +5,18 @@
#ifndef MAP_MAP_H
#define MAP_MAP_H
-#include "../config/core.h"
+#include "config/core.h"
-#include <stdarg.h>
+#include "map/atcommand.h"
+#include "common/cbasetypes.h"
+#include "common/core.h" // CORE_ST_LAST
+#include "common/db.h"
+#include "common/mapindex.h"
+#include "common/mmo.h"
+#include "common/sql.h"
-#include "atcommand.h"
-#include "../common/cbasetypes.h"
-#include "../common/core.h" // CORE_ST_LAST
-#include "../common/db.h"
-#include "../common/mapindex.h"
-#include "../common/mmo.h"
-#include "../common/sql.h"
+#include <stdio.h>
+#include <stdarg.h>
struct mob_data;
struct npc_data;
@@ -65,16 +66,6 @@ enum MOBID {
MOBID_MAGICDECOY_WIND = 2046,
};
-// The following system marks a different job ID system used by the map server,
-// which makes a lot more sense than the normal one. [Skotlex]
-// These marks the "level" of the job.
-#define JOBL_2_1 0x100 //256
-#define JOBL_2_2 0x200 //512
-#define JOBL_2 0x300
-#define JOBL_UPPER 0x1000 //4096
-#define JOBL_BABY 0x2000 //8192
-#define JOBL_THIRD 0x4000 //16384
-
// For filtering and quick checking.
#define MAPID_BASEMASK 0x00ff
#define MAPID_UPPERMASK 0x0fff
@@ -266,10 +257,15 @@ enum {
RC_DEMIHUMAN,
RC_ANGEL,
RC_DRAGON,
+ RC_PLAYER,
RC_BOSS,
RC_NONBOSS,
+ RC_MAX,
RC_NONDEMIHUMAN,
- RC_MAX
+ RC_NONPLAYER,
+ RC_DEMIPLAYER,
+ RC_NONDEMIPLAYER,
+ RC_ALL = 0xFF
};
enum {
@@ -280,6 +276,8 @@ enum {
RC2_GOLEM,
RC2_GUARDIAN,
RC2_NINJA,
+ RC2_SCARABA,
+ RC2_TURTLE,
RC2_MAX
};
@@ -294,7 +292,8 @@ enum elements {
ELE_DARK,
ELE_GHOST,
ELE_UNDEAD,
- ELE_MAX
+ ELE_MAX,
+ ELE_ALL = 0xFF
};
/**
@@ -425,6 +424,7 @@ enum status_point_types {
SP_SKILL_COOLDOWN,SP_SKILL_FIXEDCAST, SP_SKILL_VARIABLECAST, SP_FIXCASTRATE, SP_VARCASTRATE, //2050-2054
SP_SKILL_USE_SP,SP_MAGIC_ATK_ELE, SP_ADD_FIXEDCAST, SP_ADD_VARIABLECAST, //2055-2058
SP_SET_DEF_RACE,SP_SET_MDEF_RACE, //2059-2060
+ SP_RACE_TOLERANCE, //2061
/* must be the last, plugins add bonuses from this value onwards */
SP_LAST_KNOWN,
@@ -895,15 +895,15 @@ struct map_interface {
DBMap* regen_db; // int id -> struct block_list* (status_natural_heal processing)
DBMap* zone_db; // string => struct map_zone_data
DBMap* iwall_db;
- /* order respected by map_defaults() in order to zero */
- /* from block_free until zone_pk */
struct block_list **block_free;
int block_free_count, block_free_lock, block_free_list_size;
struct block_list **bl_list;
int bl_list_count, bl_list_size;
+BEGIN_ZEROED_BLOCK; // This block is zeroed in map_defaults()
struct block_list bl_head;
struct map_zone_data zone_all;/* used as a base on all maps */
struct map_zone_data zone_pk;/* used for (pk_mode) */
+END_ZEROED_BLOCK;
/* */
struct map_session_data *cpsd;
struct map_data *list;
diff --git a/src/map/mapreg.h b/src/map/mapreg.h
index 9c9a1acee..cafd25b64 100644
--- a/src/map/mapreg.h
+++ b/src/map/mapreg.h
@@ -5,9 +5,11 @@
#ifndef MAP_MAPREG_H
#define MAP_MAPREG_H
-#include "script.h" // struct reg_db
-#include "../common/cbasetypes.h"
-#include "../common/db.h"
+#include "map/script.h" // struct reg_db
+#include "common/cbasetypes.h"
+#include "common/db.h"
+
+struct eri;
/** Container for a mapreg value */
struct mapreg_save {
diff --git a/src/map/mapreg_sql.c b/src/map/mapreg_sql.c
index 0092a6c61..bed40e295 100644
--- a/src/map/mapreg_sql.c
+++ b/src/map/mapreg_sql.c
@@ -6,20 +6,20 @@
#include "mapreg.h"
+#include "map/map.h" // map-"mysql_handle
+#include "map/script.h"
+#include "common/cbasetypes.h"
+#include "common/db.h"
+#include "common/ers.h"
+#include "common/malloc.h"
+#include "common/showmsg.h"
+#include "common/sql.h"
+#include "common/strlib.h"
+#include "common/timer.h"
+
#include <stdlib.h>
#include <string.h>
-#include "map.h" // map->mysql_handle
-#include "script.h"
-#include "../common/cbasetypes.h"
-#include "../common/db.h"
-#include "../common/ers.h"
-#include "../common/malloc.h"
-#include "../common/showmsg.h"
-#include "../common/sql.h"
-#include "../common/strlib.h"
-#include "../common/timer.h"
-
struct mapreg_interface mapreg_s;
#define MAPREG_AUTOSAVE_INTERVAL (300*1000)
diff --git a/src/map/mercenary.c b/src/map/mercenary.c
index 84f6a3c41..c60234d5d 100644
--- a/src/map/mercenary.c
+++ b/src/map/mercenary.c
@@ -6,42 +6,43 @@
#include "mercenary.h"
+#include "map/atcommand.h"
+#include "map/battle.h"
+#include "map/chrif.h"
+#include "map/clif.h"
+#include "map/guild.h"
+#include "map/intif.h"
+#include "map/itemdb.h"
+#include "map/log.h"
+#include "map/map.h"
+#include "map/mob.h"
+#include "map/npc.h"
+#include "map/party.h"
+#include "map/pc.h"
+#include "map/pet.h"
+#include "map/script.h"
+#include "map/skill.h"
+#include "map/status.h"
+#include "map/trade.h"
+#include "map/unit.h"
+#include "common/cbasetypes.h"
+#include "common/malloc.h"
+#include "common/mmo.h"
+#include "common/nullpo.h"
+#include "common/random.h"
+#include "common/showmsg.h"
+#include "common/socket.h"
+#include "common/strlib.h"
+#include "common/timer.h"
+#include "common/utils.h"
+
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include "atcommand.h"
-#include "battle.h"
-#include "chrif.h"
-#include "clif.h"
-#include "guild.h"
-#include "intif.h"
-#include "itemdb.h"
-#include "log.h"
-#include "map.h"
-#include "mob.h"
-#include "npc.h"
-#include "party.h"
-#include "pc.h"
-#include "pet.h"
-#include "script.h"
-#include "skill.h"
-#include "status.h"
-#include "trade.h"
-#include "unit.h"
-#include "../common/cbasetypes.h"
-#include "../common/malloc.h"
-#include "../common/mmo.h"
-#include "../common/nullpo.h"
-#include "../common/random.h"
-#include "../common/showmsg.h"
-#include "../common/socket.h"
-#include "../common/strlib.h"
-#include "../common/timer.h"
-#include "../common/utils.h"
-
struct mercenary_interface mercenary_s;
+struct s_mercenary_db mercdb[MAX_MERCENARY_CLASS];
int merc_search_index(int class_)
{
@@ -449,7 +450,7 @@ bool read_mercenarydb_sub(char* str[], int columns, int current) {
}
int read_mercenarydb(void) {
- memset(mercenary->db,0,sizeof(mercenary->db));
+ memset(mercenary->db, 0, sizeof(struct s_mercenary_db) * MAX_MERCENARY_CLASS);
sv->readdb(map->db_path, "mercenary_db.txt", ',', 26, 26, MAX_MERCENARY_CLASS, mercenary->read_db_sub);
return 0;
@@ -511,7 +512,8 @@ void mercenary_defaults(void) {
mercenary = &mercenary_s;
/* vars */
- memset(mercenary->db,0,sizeof(mercenary->db));
+ mercenary->db = mercdb;
+ memset(mercenary->db, 0, sizeof(struct s_mercenary_db) * MAX_MERCENARY_CLASS);
/* funcs */
diff --git a/src/map/mercenary.h b/src/map/mercenary.h
index fbf3603f6..c96b5a5ef 100644
--- a/src/map/mercenary.h
+++ b/src/map/mercenary.h
@@ -4,9 +4,11 @@
#ifndef MAP_MERCENARY_H
#define MAP_MERCENARY_H
-#include "status.h" // struct status_data, struct status_change
-#include "unit.h" // struct unit_data
-#include "../common/cbasetypes.h"
+#include "map/status.h" // struct status_data, struct status_change
+#include "map/unit.h" // struct unit_data
+#include "common/cbasetypes.h"
+
+struct map_session_data;
// number of cells that a mercenary can walk to from it's master before being warped
#define MAX_MER_DISTANCE 15
@@ -56,7 +58,7 @@ struct mercenary_interface {
/* vars */
- struct s_mercenary_db db[MAX_MERCENARY_CLASS];
+ struct s_mercenary_db *db;
/* funcs */
diff --git a/src/map/mob.c b/src/map/mob.c
index 8a8e96508..8112c208c 100644
--- a/src/map/mob.c
+++ b/src/map/mob.c
@@ -4,49 +4,49 @@
#define HERCULES_CORE
-#include "../config/core.h" // AUTOLOOT_DISTANCE, DBPATH, DEFTYPE_MAX, DEFTYPE_MIN, RENEWAL_DROP, RENEWAL_EXP
+#include "config/core.h" // AUTOLOOT_DISTANCE, DBPATH, DEFTYPE_MAX, DEFTYPE_MIN, RENEWAL_DROP, RENEWAL_EXP
#include "mob.h"
+#include "map/atcommand.h"
+#include "map/battle.h"
+#include "map/clif.h"
+#include "map/date.h"
+#include "map/elemental.h"
+#include "map/guild.h"
+#include "map/homunculus.h"
+#include "map/intif.h"
+#include "map/itemdb.h"
+#include "map/log.h"
+#include "map/map.h"
+#include "map/mercenary.h"
+#include "map/npc.h"
+#include "map/party.h"
+#include "map/path.h"
+#include "map/pc.h"
+#include "map/pet.h"
+#include "map/quest.h"
+#include "map/script.h"
+#include "map/skill.h"
+#include "map/status.h"
+#include "common/HPM.h"
+#include "common/cbasetypes.h"
+#include "common/db.h"
+#include "common/ers.h"
+#include "common/malloc.h"
+#include "common/nullpo.h"
+#include "common/random.h"
+#include "common/showmsg.h"
+#include "common/socket.h"
+#include "common/strlib.h"
+#include "common/timer.h"
+#include "common/utils.h"
+
#include <math.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include "atcommand.h"
-#include "battle.h"
-#include "clif.h"
-#include "date.h"
-#include "elemental.h"
-#include "guild.h"
-#include "homunculus.h"
-#include "intif.h"
-#include "itemdb.h"
-#include "log.h"
-#include "map.h"
-#include "mercenary.h"
-#include "npc.h"
-#include "party.h"
-#include "path.h"
-#include "pc.h"
-#include "pet.h"
-#include "quest.h"
-#include "script.h"
-#include "skill.h"
-#include "status.h"
-#include "../common/HPM.h"
-#include "../common/cbasetypes.h"
-#include "../common/db.h"
-#include "../common/ers.h"
-#include "../common/malloc.h"
-#include "../common/nullpo.h"
-#include "../common/random.h"
-#include "../common/showmsg.h"
-#include "../common/socket.h"
-#include "../common/strlib.h"
-#include "../common/timer.h"
-#include "../common/utils.h"
-
struct mob_interface mob_s;
#define ACTIVE_AI_RANGE 2 //Distance added on top of 'AREA_SIZE' at which mobs enter active AI mode.
@@ -378,14 +378,14 @@ bool mob_ksprotected(struct block_list *src, struct block_list *target) {
break; // No KS Protected
if( sd->bl.id == sce->val1 || // Same Owner
- (sce->val2 == 2 && sd->status.party_id && sd->status.party_id == sce->val3) || // Party KS allowed
- (sce->val2 == 3 && sd->status.guild_id && sd->status.guild_id == sce->val4) ) // Guild KS allowed
+ (sce->val2 == KSPROTECT_PARTY && sd->status.party_id && sd->status.party_id == sce->val3) || // Party KS allowed
+ (sce->val2 == KSPROTECT_GUILD && sd->status.guild_id && sd->status.guild_id == sce->val4) ) // Guild KS allowed
break;
if( t_sd && (
- (sce->val2 == 1 && sce->val1 != t_sd->bl.id) ||
- (sce->val2 == 2 && sce->val3 && sce->val3 != t_sd->status.party_id) ||
- (sce->val2 == 3 && sce->val4 && sce->val4 != t_sd->status.guild_id)) )
+ (sce->val2 == KSPROTECT_SELF && sce->val1 != t_sd->bl.id) ||
+ (sce->val2 == KSPROTECT_PARTY && sce->val3 && sce->val3 != t_sd->status.party_id) ||
+ (sce->val2 == KSPROTECT_GUILD && sce->val4 && sce->val4 != t_sd->status.guild_id)) )
break;
if( (pl_sd = map->id2sd(sce->val1)) == NULL || pl_sd->bl.m != md->bl.m )
@@ -1298,7 +1298,7 @@ int mob_unlocktarget(struct mob_data *md, int64 tick) {
break;
default:
mob_stop_attack(md);
- mob_stop_walking(md,1); //Stop chasing.
+ mob_stop_walking(md, STOPWALKING_FLAG_FIXPOS); //Stop chasing.
md->state.skillstate = MSS_IDLE;
if(battle_config.mob_ai&0x8) //Walk instantly after dropping target
md->next_walktime = tick+rnd()%1000;
@@ -1975,7 +1975,7 @@ void mob_log_damage(struct mob_data *md, struct block_list *src, int damage)
case BL_MOB:
{
struct mob_data* md2 = (TBL_MOB*)src;
- if( md2->special_state.ai && md2->master_id ) {
+ if (md2->special_state.ai != AI_NONE && md2->master_id) {
struct map_session_data* msd = map->id2sd(md2->master_id);
if( msd )
char_id = msd->status.char_id;
@@ -2170,7 +2170,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type) {
if( !(type&2) //No exp
&& (!map->list[m].flag.pvp || battle_config.pvp_exp) //Pvp no exp rule [MouseJstr]
- && (!md->master_id || !md->special_state.ai) //Only player-summoned mobs do not give exp. [Skotlex]
+ && (!md->master_id || md->special_state.ai == AI_NONE) //Only player-summoned mobs do not give exp. [Skotlex]
&& (!map->list[m].flag.nobaseexp || !map->list[m].flag.nojobexp) //Gives Exp
) { //Experience calculation.
int bonus = 100; //Bonus on top of your share (common to all attackers).
@@ -2298,9 +2298,9 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type) {
} //End EXP giving.
if( !(type&1) && !map->list[m].flag.nomobloot && !md->state.rebirth && (
- !md->special_state.ai || //Non special mob
+ md->special_state.ai == AI_NONE || //Non special mob
battle_config.alchemist_summon_reward == 2 || //All summoned give drops
- (md->special_state.ai==2 && battle_config.alchemist_summon_reward == 1) //Marine Sphere Drops items.
+ (md->special_state.ai == AI_SPHERE && battle_config.alchemist_summon_reward == 1) //Marine Sphere Drops items.
) )
{ // Item Drop
struct item_drop_list *dlist = ers_alloc(item_drop_list_ers, struct item_drop_list);
@@ -2473,7 +2473,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type) {
timer->add(tick + (!battle_config.delay_battle_damage?500:0), mob->delay_item_drop, 0, (intptr_t)dlist);
}
- if(mvp_sd && md->db->mexp > 0 && !md->special_state.ai) {
+ if(mvp_sd && md->db->mexp > 0 && md->special_state.ai == AI_NONE) {
int log_mvp[2] = {0};
unsigned int mexp;
double exp;
@@ -2746,7 +2746,7 @@ int mob_class_change (struct mob_data *md, int class_)
if( mob_is_treasure(md) )
return 0; //Treasure Boxes
- if( md->special_state.ai > 1 )
+ if( md->special_state.ai > AI_ATTACK )
return 0; //Marine Spheres and Floras.
if( mob->is_clone(md->class_) )
@@ -2764,7 +2764,7 @@ int mob_class_change (struct mob_data *md, int class_)
memcpy(md->name,md->db->jname,NAME_LENGTH);
mob_stop_attack(md);
- mob_stop_walking(md, 0);
+ mob_stop_walking(md, STOPWALKING_FLAG_NONE);
unit->skillcastcancel(&md->bl, 0);
status->set_viewdata(&md->bl, class_);
clif->class_change(&md->bl, md->vd->class_, 1);
@@ -3016,7 +3016,7 @@ struct block_list *mob_getfriendhprate(struct mob_data *md,int min_rate,int max_
nullpo_retr(NULL, md);
- if (md->special_state.ai) //Summoned creatures. [Skotlex]
+ if (md->special_state.ai != AI_NONE) //Summoned creatures. [Skotlex]
type = BL_PC;
map->foreachinrange(mob->getfriendhprate_sub, &md->bl, 8, type,md,min_rate,max_rate,&fr);
@@ -3302,7 +3302,7 @@ int mobskill_event(struct mob_data *md, struct block_list *src, int64 tick, int
if(md->bl.prev == NULL || md->status.hp <= 0)
return 0;
- if( md->special_state.ai == 2 ) {//LOne WOlf explained that ANYONE can trigger the marine countdown skill. [Skotlex]
+ if (md->special_state.ai == AI_SPHERE) {//LOne WOlf explained that ANYONE can trigger the marine countdown skill. [Skotlex]
md->state.alchemist = 1;
return mob->skill_use(md, timer->gettick(), MSC_ALCHEMIST);
}
@@ -3402,7 +3402,7 @@ int mob_clone_spawn(struct map_session_data *sd, int16 m, int16 x, int16 y, cons
int idx = pc->skill_tree[pc->class2idx(sd->status.class_)][j].idx;
int skill_id = pc->skill_tree[pc->class2idx(sd->status.class_)][j].id;
if (!skill_id || sd->status.skill[idx].lv < 1 ||
- (skill->db[idx].inf2&(INF2_WEDDING_SKILL|INF2_GUILD_SKILL))
+ (skill->dbs->db[idx].inf2&(INF2_WEDDING_SKILL|INF2_GUILD_SKILL))
)
continue;
for(h = 0; h < map->list[sd->bl.m].zone->disabled_skills_count; h++) {
@@ -3435,7 +3435,7 @@ int mob_clone_spawn(struct map_session_data *sd, int16 m, int16 x, int16 y, cons
ms[i].casttime = skill->cast_fix(&sd->bl,skill_id, ms[i].skill_lv);
ms[i].delay = 5000+skill->delay_fix(&sd->bl,skill_id, ms[i].skill_lv);
- inf = skill->db[idx].inf;
+ inf = skill->dbs->db[idx].inf;
if (inf&INF_ATTACK_SKILL) {
ms[i].target = MST_TARGET;
ms[i].cond1 = MSC_ALWAYS;
@@ -4399,13 +4399,13 @@ bool mob_parse_row_mobskilldb(char** str, int columns, int current)
if ( skill->get_casttype2(sidx) == CAST_GROUND) {//Ground skill.
if (ms->target > MST_AROUND) {
ShowWarning("mob_parse_row_mobskilldb: Wrong mob skill target for ground skill %d (%s) for %s.\n",
- ms->skill_id, skill->db[sidx].name,
+ ms->skill_id, skill->dbs->db[sidx].name,
mob_id < 0?"all mobs":mob->db_data[mob_id]->sprite);
ms->target = MST_TARGET;
}
} else if (ms->target > MST_MASTER) {
ShowWarning("mob_parse_row_mobskilldb: Wrong mob skill target 'around' for non-ground skill %d (%s) for %s.\n",
- ms->skill_id, skill->db[sidx].name,
+ ms->skill_id, skill->dbs->db[sidx].name,
mob_id < 0?"all mobs":mob->db_data[mob_id]->sprite);
ms->target = MST_TARGET;
}
diff --git a/src/map/mob.h b/src/map/mob.h
index 02ae1630a..85d2bf9b8 100644
--- a/src/map/mob.h
+++ b/src/map/mob.h
@@ -5,11 +5,11 @@
#ifndef MAP_MOB_H
#define MAP_MOB_H
-#include "map.h" // struct status_data, struct view_data, struct mob_skill
-#include "status.h" // struct status_data, struct status_change
-#include "unit.h" // struct unit_data
-#include "../common/cbasetypes.h"
-#include "../common/mmo.h" // struct item
+#include "map/map.h" // struct block_list
+#include "map/status.h" // struct status_data, struct status_change
+#include "map/unit.h" // struct unit_data, view_data
+#include "common/cbasetypes.h"
+#include "common/mmo.h" // struct item
#define MAX_RANDOMMONSTER 5
@@ -38,7 +38,7 @@
#define MOB_CLONE_END MAX_MOB_DB
//Used to determine default enemy type of mobs (for use in each in range calls)
-#define DEFAULT_ENEMY_TYPE(md) ((md)->special_state.ai?BL_CHAR:BL_MOB|BL_PC|BL_HOM|BL_MER)
+#define DEFAULT_ENEMY_TYPE(md) ((md)->special_state.ai != AI_NONE ?BL_CHAR:BL_MOB|BL_PC|BL_HOM|BL_MER)
#define MAX_MOB_CHAT 250 //Max Skill's messages
@@ -79,11 +79,23 @@ enum size {
};
enum ai {
- AI_NONE = 0,
- AI_ATTACK,
- AI_SPHERE,
- AI_FLORA,
- AI_ZANZOU,
+ AI_NONE = 0, //0: Normal mob.
+ AI_ATTACK, //1: Standard summon, attacks mobs.
+ AI_SPHERE, //2: Alchemist Marine Sphere
+ AI_FLORA, //3: Alchemist Summon Flora
+ AI_ZANZOU, //4: Summon Zanzou
+
+ AI_MAX
+};
+
+/**
+ * Acceptable values for map_session_data.state.noks
+ */
+enum ksprotection_mode {
+ KSPROTECT_NONE = 0,
+ KSPROTECT_SELF = 1,
+ KSPROTECT_PARTY = 2,
+ KSPROTECT_GUILD = 3,
};
struct mob_skill {
@@ -141,13 +153,8 @@ struct mob_data {
struct mob_db *db; //For quick data access (saves doing mob_db(md->class_) all the time) [Skotlex]
char name[NAME_LENGTH];
struct {
- unsigned int size : 2; //Small/Big monsters.
- unsigned int ai : 4; //Special AI for summoned monsters.
- //0: Normal mob.
- //1: Standard summon, attacks mobs.
- //2: Alchemist Marine Sphere
- //3: Alchemist Summon Flora
- //4: Summon Zanzou
+ unsigned int size : 2; //Small/Big monsters. @see enum size
+ unsigned int ai : 4; //Special AI for summoned monsters. @see enum ai
unsigned int clone : 1;/* is clone? 1:0 */
} special_state; //Special mob information that does not needs to be zero'ed on mob respawn.
struct {
diff --git a/src/map/npc.c b/src/map/npc.c
index 16789b726..a79062c77 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -4,9 +4,37 @@
#define HERCULES_CORE
-#include "../config/core.h" // NPC_SECURE_TIMEOUT_INPUT, NPC_SECURE_TIMEOUT_MENU, NPC_SECURE_TIMEOUT_NEXT, SECURE_NPCTIMEOUT, SECURE_NPCTIMEOUT_INTERVAL
+#include "config/core.h" // NPC_SECURE_TIMEOUT_INPUT, NPC_SECURE_TIMEOUT_MENU, NPC_SECURE_TIMEOUT_NEXT, SECURE_NPCTIMEOUT, SECURE_NPCTIMEOUT_INTERVAL
#include "npc.h"
+#include "map/battle.h"
+#include "map/chat.h"
+#include "map/clif.h"
+#include "map/guild.h"
+#include "map/instance.h"
+#include "map/intif.h"
+#include "map/itemdb.h"
+#include "map/log.h"
+#include "map/map.h"
+#include "map/mob.h"
+#include "map/pc.h"
+#include "map/pet.h"
+#include "map/script.h"
+#include "map/skill.h"
+#include "map/status.h"
+#include "map/unit.h"
+#include "common/HPM.h"
+#include "common/cbasetypes.h"
+#include "common/db.h"
+#include "common/ers.h"
+#include "common/malloc.h"
+#include "common/nullpo.h"
+#include "common/showmsg.h"
+#include "common/socket.h"
+#include "common/strlib.h"
+#include "common/timer.h"
+#include "common/utils.h"
+
#include <errno.h>
#include <math.h>
#include <stdio.h>
@@ -14,33 +42,6 @@
#include <string.h>
#include <time.h>
-#include "battle.h"
-#include "chat.h"
-#include "clif.h"
-#include "instance.h"
-#include "intif.h"
-#include "itemdb.h"
-#include "log.h"
-#include "map.h"
-#include "mob.h"
-#include "pc.h"
-#include "pet.h"
-#include "script.h"
-#include "skill.h"
-#include "status.h"
-#include "unit.h"
-#include "../common/HPM.h"
-#include "../common/cbasetypes.h"
-#include "../common/db.h"
-#include "../common/ers.h"
-#include "../common/malloc.h"
-#include "../common/nullpo.h"
-#include "../common/showmsg.h"
-#include "../common/socket.h"
-#include "../common/strlib.h"
-#include "../common/timer.h"
-#include "../common/utils.h"
-
struct npc_interface npc_s;
static int npc_id=START_NPC_NUM;
@@ -62,34 +63,52 @@ static struct view_data npc_viewdb2[MAX_NPC_CLASS2_END-MAX_NPC_CLASS2_START];
/* for speedup */
unsigned int npc_market_qty[MAX_INVENTORY];
-static struct script_event_s
-{
+static struct script_event_s {
//Holds pointers to the commonly executed scripts for speedup. [Skotlex]
struct event_data *event[UCHAR_MAX];
const char *event_name[UCHAR_MAX];
uint8 event_count;
} script_event[NPCE_MAX];
-struct view_data* npc_get_viewdata(int class_)
+/**
+ * Returns the viewdata for normal npc classes.
+ * @param class_ The NPC class ID.
+ * @return The viewdata, or NULL if the ID is invalid.
+ */
+struct view_data *npc_get_viewdata(int class_)
{
- //Returns the viewdata for normal npc classes.
- if( class_ == INVISIBLE_CLASS )
+ if (class_ == INVISIBLE_CLASS)
return &npc_viewdb[0];
- if (npc->db_checkid(class_) || class_ == WARP_CLASS){
- if( class_ > MAX_NPC_CLASS2_START ){
- return &npc_viewdb2[class_-MAX_NPC_CLASS2_START];
- }else{
+ if (npc->db_checkid(class_)) {
+ if (class_ < MAX_NPC_CLASS) {
return &npc_viewdb[class_];
+ } else if (class_ >= MAX_NPC_CLASS2_START && class_ < MAX_NPC_CLASS2_END) {
+ return &npc_viewdb2[class_-MAX_NPC_CLASS2_START];
}
}
return NULL;
}
-//Checks if a given id is a valid npc id. [Skotlex]
-//Since new npcs are added all the time, the max valid value is the one before the first mob (Scorpion = 1001)
+/**
+ * Checks if a given id is a valid npc id.
+ *
+ * Since new npcs are added all the time, the max valid value is the one before the first mob (Scorpion = 1001)
+ *
+ * @param id The NPC ID to validate.
+ * @return Whether the value is a valid ID.
+ */
bool npc_db_checkid(int id)
{
- return ((id >= 46 && id <= 125) || id == HIDDEN_WARP_CLASS || (id > 400 && id < MAX_NPC_CLASS) || id == INVISIBLE_CLASS || (id > MAX_NPC_CLASS2_START && id < MAX_NPC_CLASS2_END));
+ if (id >= WARP_CLASS && id <= 125) // First subrange
+ return true;
+ if (id == HIDDEN_WARP_CLASS || id == INVISIBLE_CLASS) // Special IDs not included in the valid ranges
+ return true;
+ if (id > 400 && id < MAX_NPC_CLASS) // Second subrange
+ return true;
+ if (id >= MAX_NPC_CLASS2_START && id < MAX_NPC_CLASS2_END) // Second range
+ return true;
+ // Anything else is invalid
+ return false;
}
/// Returns a new npc id that isn't being used in id_db.
@@ -185,7 +204,7 @@ int npc_enable_sub(struct block_list *bl, va_list ap)
if (sd->npc_id != 0)
return 0;
- pc_stop_walking(sd,1);
+ pc_stop_walking(sd, STOPWALKING_FLAG_FIXPOS);
npc->click(sd,nd);
}
}
@@ -1565,8 +1584,8 @@ bool npc_trader_open(struct map_session_data *sd, struct npc_data *nd) {
}
/* nothing to display, no items available */
- if( i == nd->u.scr.shop->items ) {
- clif->colormes(sd->fd,COLOR_RED, msg_sd(sd,881));
+ if (i == nd->u.scr.shop->items) {
+ clif->messagecolor_self(sd->fd, COLOR_RED, msg_sd(sd,881));
return false;
}
@@ -2038,19 +2057,18 @@ int npc_selllist_sub(struct map_session_data* sd, int n, unsigned short* item_li
script->setarray_pc(sd, "@sold_nameid", i, (void*)(intptr_t)sd->status.inventory[idx].nameid, &key_nameid);
script->setarray_pc(sd, "@sold_quantity", i, (void*)(intptr_t)item_list[i*2+1], &key_amount);
-
- if (itemdb->isequip(sd->status.inventory[idx].nameid)) {
- // process equipment based information into the arrays
- script->setarray_pc(sd, "@sold_refine", i, (void*)(intptr_t)sd->status.inventory[idx].refine, &key_refine);
- script->setarray_pc(sd, "@sold_attribute", i, (void*)(intptr_t)sd->status.inventory[idx].attribute, &key_attribute);
- script->setarray_pc(sd, "@sold_identify", i, (void*)(intptr_t)sd->status.inventory[idx].identify, &key_identify);
-
- for (j = 0; j < MAX_SLOTS; j++) {
- // store each of the cards from the equipment in the array
- snprintf(card_slot, sizeof(card_slot), "@sold_card%d", j + 1);
- script->setarray_pc(sd, card_slot, i, (void*)(intptr_t)sd->status.inventory[idx].card[j], &key_card[j]);
- }
+
+ // process item based information into the arrays
+ script->setarray_pc(sd, "@sold_refine", i, (void*)(intptr_t)sd->status.inventory[idx].refine, &key_refine);
+ script->setarray_pc(sd, "@sold_attribute", i, (void*)(intptr_t)sd->status.inventory[idx].attribute, &key_attribute);
+ script->setarray_pc(sd, "@sold_identify", i, (void*)(intptr_t)sd->status.inventory[idx].identify, &key_identify);
+
+ for (j = 0; j < MAX_SLOTS; j++) {
+ // store each of the cards/special info from the item in the array
+ snprintf(card_slot, sizeof(card_slot), "@sold_card%d", j + 1);
+ script->setarray_pc(sd, card_slot, i, (void*)(intptr_t)sd->status.inventory[idx].card[j], &key_card[j]);
}
+
}
// invoke event
@@ -2127,7 +2145,7 @@ int npc_selllist(struct map_session_data* sd, int n, unsigned short* item_list)
}
}
- pc->delitem(sd, idx, amount, 0, 6, LOG_TYPE_NPC);
+ pc->delitem(sd, idx, amount, 0, DELITEM_SOLD, LOG_TYPE_NPC);
}
if( z > MAX_ZENY )
@@ -3537,7 +3555,7 @@ const char* npc_parse_mob(char* w1, char* w2, char* w3, char* w4, const char* st
return strchr(start, '\n');
}
- if (mobspawn.state.ai > 4 && ai != -1) {
+ if (mobspawn.state.ai >= AI_MAX && ai != -1) {
ShowError("npc_parse_mob: Invalid ai %d for mob ID %d in file '%s', line '%d'.\n", mobspawn.state.ai, class_, filepath, strline(buffer, start - buffer));
if (retval) *retval = EXIT_FAILURE;
return strchr(start, '\n');
@@ -3560,7 +3578,7 @@ const char* npc_parse_mob(char* w1, char* w2, char* w3, char* w4, const char* st
mobspawn.level = mob_lv;
if (size > 0 && size <= 2)
mobspawn.state.size = size;
- if (ai > 0 && ai <= 4)
+ if (ai > AI_NONE && ai < AI_MAX)
mobspawn.state.ai = ai;
if (mobspawn.num > 1 && battle_config.mob_count_rate != 100) {
@@ -3812,13 +3830,14 @@ const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, const char
}
else if (!strcmpi(w3,"battleground")) {
struct map_zone_data *zone;
- if( state ) {
- if( sscanf(w4, "%d", &state) == 1 )
+ if (state) {
+ if (w4 && sscanf(w4, "%d", &state) == 1)
map->list[m].flag.battleground = state;
else
map->list[m].flag.battleground = 1; // Default value
- } else
+ } else {
map->list[m].flag.battleground = 0;
+ }
if( map->list[m].flag.battleground && map->list[m].flag.pvp ) {
map->list[m].flag.pvp = 0;
@@ -4624,6 +4643,7 @@ int do_init_npc(bool minimal) {
}
if( script->lang_export_fp ) {
+ ShowInfo("Lang exported to '%s'\n",script->lang_export_file);
fclose(script->lang_export_fp);
script->lang_export_fp = NULL;
}
diff --git a/src/map/npc.h b/src/map/npc.h
index 68d683847..bc779b56b 100644
--- a/src/map/npc.h
+++ b/src/map/npc.h
@@ -5,11 +5,11 @@
#ifndef MAP_NPC_H
#define MAP_NPC_H
-#include "map.h" // struct block_list
-#include "status.h" // struct status_change
-#include "unit.h" // struct unit_data
-#include "../common/cbasetypes.h"
-#include "../common/db.h"
+#include "map/map.h" // struct block_list
+#include "map/status.h" // struct status_change
+#include "map/unit.h" // struct unit_data
+#include "common/cbasetypes.h"
+#include "common/db.h"
struct HPluginData;
struct view_data;
@@ -121,7 +121,7 @@ enum actor_classes {
// Old NPC range
#define MAX_NPC_CLASS 1000
// New NPC range
-#define MAX_NPC_CLASS2_START 10000
+#define MAX_NPC_CLASS2_START 10001
#define MAX_NPC_CLASS2_END 10110
//Script NPC events.
@@ -288,7 +288,7 @@ void npc_defaults(void);
/* comes from npc_chat.c */
#ifdef PCRE_SUPPORT
-#include "../../3rdparty/pcre/include/pcre.h"
+#include <pcre/include/pcre.h>
/* Structure containing all info associated with a single pattern block */
struct pcrematch_entry {
struct pcrematch_entry* next;
diff --git a/src/map/npc_chat.c b/src/map/npc_chat.c
index 8bc246819..3fe379f36 100644
--- a/src/map/npc_chat.c
+++ b/src/map/npc_chat.c
@@ -8,22 +8,22 @@
#include "npc.h" // struct npc_data
+#include "map/mob.h" // struct mob_data
+#include "map/pc.h" // struct map_session_data
+#include "map/script.h" // set_var()
+#include "common/malloc.h"
+#include "common/nullpo.h"
+#include "common/showmsg.h"
+#include "common/strlib.h"
+#include "common/timer.h"
+
+#include <pcre/include/pcre.h>
+
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include "../../3rdparty/pcre/include/pcre.h"
-
-#include "mob.h" // struct mob_data
-#include "pc.h" // struct map_session_data
-#include "script.h" // set_var()
-#include "../common/malloc.h"
-#include "../common/nullpo.h"
-#include "../common/showmsg.h"
-#include "../common/strlib.h"
-#include "../common/timer.h"
-
/**
* interface sources
**/
diff --git a/src/map/packets.h b/src/map/packets.h
index ccf1c28ef..6623c091c 100644
--- a/src/map/packets.h
+++ b/src/map/packets.h
@@ -448,6 +448,8 @@ packet(0x020a,10);
//packet(0x020b,-1);
//packet(0x020c,-1);
packet(0x020d,-1);
+packet(0x974,2,clif->cancelmergeitem);
+packet(0x96e,-1,clif->ackmergeitems);
//2004-07-05aSakexe
#if PACKETVER >= 20040705
@@ -2802,6 +2804,21 @@ packet(0x020d,-1);
packet(0x0a00,269);
#endif
+/* Roulette System [Yommy/Hercules] */
+#if PACKETVER >= 20141016
+ packet(0x0A19,2,clif->pRouletteOpen,0); // HEADER_CZ_REQ_OPEN_ROULETTE
+ packet(0x0A1A,23); // HEADER_ZC_ACK_OPEN_ROULETTE
+ packet(0x0A1B,2,clif->pRouletteInfo,0); // HEADER_CZ_REQ_ROULETTE_INFO
+ packet(0x0A1C,-1); // HEADER_ZC_ACK_ROULEITTE_INFO
+ packet(0x0A1D,2,clif->pRouletteClose,0); // HEADER_CZ_REQ_CLOSE_ROULETTE
+ packet(0x0A1E,3); // HEADER_ZC_ACK_CLOSE_ROULETTE
+ packet(0x0A1F,2,clif->pRouletteGenerate,0); // HEADER_CZ_REQ_GENERATE_ROULETTE
+ packet(0x0A20,21); // HEADER_ZC_ACK_GENERATE_ROULETTE
+ packet(0x0A21,3,clif->pRouletteRecvItem,2); // HEADER_CZ_RECV_ROULETTE_ITEM
+ packet(0x0A22,5); // HEADER_ZC_RECV_ROULETTE_ITEM
+#endif
+
+
// 2014-10-22bRagexe - YomRawr
#if PACKETVER >= 20141022
packet(0x0369,7,clif->pActionRequest,2,6);
@@ -2835,21 +2852,42 @@ packet(0x020d,-1);
packet(0x0438,36,clif->pStoragePassword,0);
#endif
-/* Roulette System [Yommy/Hercules] */
-#if PACKETVER >= 20141016
- packet(0x0A19,2,clif->pRouletteOpen,0); // HEADER_CZ_REQ_OPEN_ROULETTE
- packet(0x0A1A,23); // HEADER_ZC_ACK_OPEN_ROULETTE
- packet(0x0A1B,2,clif->pRouletteInfo,0); // HEADER_CZ_REQ_ROULETTE_INFO
- packet(0x0A1C,-1); // HEADER_ZC_ACK_ROULEITTE_INFO
- packet(0x0A1D,2,clif->pRouletteClose,0); // HEADER_CZ_REQ_CLOSE_ROULETTE
- packet(0x0A1E,3); // HEADER_ZC_ACK_CLOSE_ROULETTE
- packet(0x0A1F,2,clif->pRouletteGenerate,0); // HEADER_CZ_REQ_GENERATE_ROULETTE
- packet(0x0A20,21); // HEADER_ZC_ACK_GENERATE_ROULETTE
- packet(0x0A21,3,clif->pRouletteRecvItem,2); // HEADER_CZ_RECV_ROULETTE_ITEM
- packet(0x0A22,5); // HEADER_ZC_RECV_ROULETTE_ITEM
-#endif
-
-/* PacketKeys: http://hercules.ws/board/topic/1105-hercules-wpe-free-june-14th-patch/ */
+// 2015-05-13aRagexe
+#if PACKETVER >= 20150513
+ packet(0x0369,7,clif->pActionRequest,2,6);
+ packet(0x083C,10,clif->pUseSkillToId,2,4,6);
+ packet(0x0437,5,clif->pWalkToXY,2);
+ packet(0x035F,6,clif->pTickSend,2);
+ packet(0x0924,5,clif->pChangeDir,2,4);
+ packet(0x0958,6,clif->pTakeItem,2);
+ packet(0x0885,6,clif->pDropItem,2,4);
+ packet(0x0879,8,clif->pMoveToKafra,2,4);
+ packet(0x0864,8,clif->pMoveFromKafra,2,4);
+ packet(0x0438,10,clif->pUseSkillToPos,2,4,6,8);
+ packet(0x0366,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10);
+ packet(0x096A,6,clif->pGetCharNameRequest,2);
+ packet(0x0368,6,clif->pSolveCharName,2);
+ packet(0x0838,12,clif->pSearchStoreInfoListItemClick,2,6,10);
+ packet(0x0835,2,clif->pSearchStoreInfoNextPage,0);
+ packet(0x0819,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15);
+ packet(0x0811,-1,clif->pReqTradeBuyingStore,2,4,8,12);
+ packet(0x0360,6,clif->pReqClickBuyingStore,2);
+ packet(0x022D,2,clif->pReqCloseBuyingStore,0);
+ packet(0x0815,-1,clif->pReqOpenBuyingStore,2,4,8,9,89);
+ packet(0x0883,18,clif->pPartyBookingRegisterReq,2,4);
+ packet(0x02C4,8); // CZ_JOIN_BATTLE_FIELD
+ packet(0x0960,-1,clif->pItemListWindowSelected,2,4,8);
+ packet(0x0363,19,clif->pWantToConnection,2,6,10,14,18);
+ packet(0x094A,26,clif->pPartyInvite2,2);
+ packet(0x0927,4); // CZ_GANGSI_RANK
+ packet(0x08A8,26,clif->pFriendsListAdd,2);
+ packet(0x0817,5,clif->pHomMenu,2,4);
+ packet(0x0923,36,clif->pStoragePassword,0);
+ packet(0x09e8,11,clif->pDull); //CZ_OPEN_MAILBOX
+ packet(0x0a2e,6,clif->pDull); //TITLE
+#endif
+
+/* PacketKeys: http://herc.ws/board/topic/1105-hercules-wpe-free-june-14th-patch/ */
#if PACKETVER >= 20110817
packetKeys(0x053D5CED,0x3DED6DED,0x6DED6DED); /* Thanks to Shakto */
#endif
@@ -3088,6 +3126,12 @@ packet(0x020d,-1);
packetKeys(0x290551EA,0x2B952C75,0x2D67669B); /* YomRawr */
#endif
+// 2015 Packet Keys
+
+#if PACKETVER >= 20150513
+ packetKeys(0x62C86D09,0x75944F17,0x112C133D); /* Dastgir */
+#endif
+
#if defined(OBFUSCATIONKEY1) && defined(OBFUSCATIONKEY2) && defined(OBFUSCATIONKEY3)
packetKeys(OBFUSCATIONKEY1,OBFUSCATIONKEY2,OBFUSCATIONKEY3);
#endif
diff --git a/src/map/packets_struct.h b/src/map/packets_struct.h
index 71471e5c6..231321c88 100644
--- a/src/map/packets_struct.h
+++ b/src/map/packets_struct.h
@@ -1,13 +1,13 @@
// Copyright (c) Hercules Dev Team, licensed under GNU GPL.
// See the LICENSE file
-/* Hercules Renewal: Phase Two http://hercules.ws/board/topic/383-hercules-renewal-phase-two/ */
+/* Hercules Renewal: Phase Two http://herc.ws/board/topic/383-hercules-renewal-phase-two/ */
#ifndef MAP_PACKETS_STRUCT_H
#define MAP_PACKETS_STRUCT_H
-#include "../common/cbasetypes.h"
-#include "../common/mmo.h"
+#include "common/cbasetypes.h"
+#include "common/mmo.h"
/**
*
@@ -360,8 +360,8 @@ struct packet_dropflooritem {
unsigned char subY;
short count;
} __attribute__((packed));
-#if PACKETVER < 20091103
struct packet_idle_unit2 {
+#if PACKETVER < 20091103
short PacketType;
#if PACKETVER >= 20071106
unsigned char objecttype;
@@ -392,8 +392,13 @@ struct packet_idle_unit2 {
unsigned char ySize;
unsigned char state;
short clevel;
+#else // ! PACKETVER < 20091103
+ char UNUSED;
+#endif // PACKETVER < 20091103
} __attribute__((packed));
+
struct packet_spawn_unit2 {
+#if PACKETVER < 20091103
short PacketType;
#if PACKETVER >= 20071106
unsigned char objecttype;
@@ -418,8 +423,11 @@ struct packet_spawn_unit2 {
unsigned char PosDir[3];
unsigned char xSize;
unsigned char ySize;
+#else // ! PACKETVER < 20091103
+ char UNUSED;
+#endif // PACKETVER < 20091103
} __attribute__((packed));
-#endif
+
struct packet_spawn_unit {
short PacketType;
#if PACKETVER >= 20091103
diff --git a/src/map/party.c b/src/map/party.c
index fb738a12b..6b35debe5 100644
--- a/src/map/party.c
+++ b/src/map/party.c
@@ -4,36 +4,36 @@
#define HERCULES_CORE
-#include "../config/core.h" // GP_BOUND_ITEMS, RENEWAL_EXP
+#include "config/core.h" // GP_BOUND_ITEMS, RENEWAL_EXP
#include "party.h"
+#include "map/atcommand.h" //msg_txt()
+#include "map/battle.h"
+#include "map/clif.h"
+#include "map/instance.h"
+#include "map/intif.h"
+#include "map/itemdb.h"
+#include "map/log.h"
+#include "map/map.h"
+#include "map/mob.h" // struct mob_data
+#include "map/pc.h"
+#include "map/skill.h"
+#include "map/status.h"
+#include "common/HPM.h"
+#include "common/cbasetypes.h"
+#include "common/malloc.h"
+#include "common/nullpo.h"
+#include "common/random.h"
+#include "common/showmsg.h"
+#include "common/socket.h" // last_tick
+#include "common/strlib.h"
+#include "common/timer.h"
+#include "common/utils.h"
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include "atcommand.h" //msg_txt()
-#include "battle.h"
-#include "clif.h"
-#include "instance.h"
-#include "intif.h"
-#include "itemdb.h"
-#include "log.h"
-#include "map.h"
-#include "mob.h" // struct mob_data
-#include "pc.h"
-#include "skill.h"
-#include "status.h"
-#include "../common/HPM.h"
-#include "../common/cbasetypes.h"
-#include "../common/malloc.h"
-#include "../common/nullpo.h"
-#include "../common/random.h"
-#include "../common/showmsg.h"
-#include "../common/socket.h" // last_tick
-#include "../common/strlib.h"
-#include "../common/timer.h"
-#include "../common/utils.h"
-
struct party_interface party_s;
/*==========================================
@@ -640,7 +640,7 @@ int party_optionchanged(int party_id,int account_id,int exp,int item,int flag) {
if( (p=party->search(party_id))==NULL)
return 0;
- //Flag&1: Exp change denied. Flag&2: Item change denied.
+ //Flag&0x1: Exp change denied. Flag&0x10: Item change denied.
if(!(flag&0x01) && p->party.exp != exp)
p->party.exp=exp;
if(!(flag&0x10) && p->party.item != item) {
diff --git a/src/map/party.h b/src/map/party.h
index a541d03cb..95faa2213 100644
--- a/src/map/party.h
+++ b/src/map/party.h
@@ -5,12 +5,12 @@
#ifndef MAP_PARTY_H
#define MAP_PARTY_H
-#include <stdarg.h>
+#include "map/map.h" // TBL_PC
+#include "common/cbasetypes.h"
+#include "common/db.h"
+#include "common/mmo.h" // struct party
-#include "map.h" // TBL_PC
-#include "../common/cbasetypes.h"
-#include "../common/db.h"
-#include "../common/mmo.h" // struct party
+#include <stdarg.h>
#define PARTY_BOOKING_JOBS 6
#define PARTY_BOOKING_RESULTS 10
diff --git a/src/map/path.c b/src/map/path.c
index 600dfc082..3ded5423e 100644
--- a/src/map/path.c
+++ b/src/map/path.c
@@ -4,21 +4,21 @@
#define HERCULES_CORE
-#include "../config/core.h" // CELL_NOSTACK, CIRCULAR_AREA
+#include "config/core.h" // CELL_NOSTACK, CIRCULAR_AREA
#include "path.h"
+#include "map/map.h"
+#include "common/cbasetypes.h"
+#include "common/db.h"
+#include "common/malloc.h"
+#include "common/nullpo.h"
+#include "common/random.h"
+#include "common/showmsg.h"
+
+#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <math.h>
-
-#include "map.h"
-#include "../common/cbasetypes.h"
-#include "../common/db.h"
-#include "../common/malloc.h"
-#include "../common/nullpo.h"
-#include "../common/random.h"
-#include "../common/showmsg.h"
#define SET_OPEN 0
#define SET_CLOSED 1
diff --git a/src/map/path.h b/src/map/path.h
index eb42df6d0..bbd81b8c6 100644
--- a/src/map/path.h
+++ b/src/map/path.h
@@ -5,8 +5,8 @@
#ifndef MAP_PATH_H
#define MAP_PATH_H
-#include "map.h" // enum cell_chk
-#include "../common/cbasetypes.h"
+#include "map/map.h" // enum cell_chk
+#include "common/cbasetypes.h"
#define MOVE_COST 10
#define MOVE_DIAGONAL_COST 14
diff --git a/src/map/pc.c b/src/map/pc.c
index 3d5e240f8..107d656f0 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -4,58 +4,58 @@
#define HERCULES_CORE
-#include "../config/core.h" // DBPATH, GP_BOUND_ITEMS, MAX_SPIRITBALL, RENEWAL, RENEWAL_ASPD, RENEWAL_CAST, RENEWAL_DROP, RENEWAL_EXP, SECURE_NPCTIMEOUT
+#include "config/core.h" // DBPATH, GP_BOUND_ITEMS, MAX_SPIRITBALL, RENEWAL, RENEWAL_ASPD, RENEWAL_CAST, RENEWAL_DROP, RENEWAL_EXP, SECURE_NPCTIMEOUT
#include "pc.h"
+#include "map/atcommand.h" // get_atcommand_level()
+#include "map/battle.h" // battle_config
+#include "map/battleground.h"
+#include "map/channel.h"
+#include "map/chat.h"
+#include "map/chrif.h"
+#include "map/clif.h"
+#include "map/date.h" // is_day_of_*()
+#include "map/duel.h"
+#include "map/elemental.h"
+#include "map/guild.h" // guild-"search(), guild_request_info()
+#include "map/homunculus.h"
+#include "map/instance.h"
+#include "map/intif.h"
+#include "map/itemdb.h"
+#include "map/log.h"
+#include "map/mail.h"
+#include "map/map.h"
+#include "map/mercenary.h"
+#include "map/mob.h" // struct mob_data
+#include "map/npc.h" // fake_nd
+#include "map/party.h" // party-"search()
+#include "map/path.h"
+#include "map/pc_groups.h"
+#include "map/pet.h" // pet_unlocktarget()
+#include "map/quest.h"
+#include "map/script.h" // script_config
+#include "map/skill.h"
+#include "map/status.h" // struct status_data
+#include "map/storage.h"
+#include "common/cbasetypes.h"
+#include "common/conf.h"
+#include "common/core.h" // get_svn_revision()
+#include "common/malloc.h"
+#include "common/mmo.h" // NAME_LENGTH, MAX_CARTS, NEW_CARTS
+#include "common/nullpo.h"
+#include "common/random.h"
+#include "common/showmsg.h"
+#include "common/socket.h" // session[]
+#include "common/strlib.h" // safestrncpy()
+#include "common/sysinfo.h"
+#include "common/timer.h"
+#include "common/utils.h"
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
-#include "atcommand.h" // get_atcommand_level()
-#include "battle.h" // battle_config
-#include "battleground.h"
-#include "channel.h"
-#include "chat.h"
-#include "chrif.h"
-#include "clif.h"
-#include "date.h" // is_day_of_*()
-#include "duel.h"
-#include "elemental.h"
-#include "guild.h" // guild->search(), guild_request_info()
-#include "homunculus.h"
-#include "instance.h"
-#include "intif.h"
-#include "itemdb.h"
-#include "log.h"
-#include "mail.h"
-#include "map.h"
-#include "mercenary.h"
-#include "mob.h" // struct mob_data
-#include "npc.h" // fake_nd
-#include "party.h" // party->search()
-#include "path.h"
-#include "pc_groups.h"
-#include "pet.h" // pet_unlocktarget()
-#include "quest.h"
-#include "script.h" // script_config
-#include "skill.h"
-#include "status.h" // struct status_data
-#include "storage.h"
-#include "../common/cbasetypes.h"
-#include "../common/conf.h"
-#include "../common/core.h" // get_svn_revision()
-#include "../common/malloc.h"
-#include "../common/mmo.h" // NAME_LENGTH, MAX_CARTS, NEW_CARTS
-#include "../common/nullpo.h"
-#include "../common/random.h"
-#include "../common/showmsg.h"
-#include "../common/socket.h" // session[]
-#include "../common/strlib.h" // safestrncpy()
-#include "../common/sysinfo.h"
-#include "../common/timer.h"
-#include "../common/utils.h"
-
struct pc_interface pc_s;
//Converts a class to its array index for CLASS_COUNT defined arrays.
@@ -174,6 +174,28 @@ int pc_spiritball_timer(int tid, int64 tick, int id, intptr_t data) {
return 0;
}
+/**
+* Get the possible number of spiritball that a player can call.
+* @param sd the affected player structure
+* @param min the minimum number of spiritball regardless the level of MO_CALLSPIRITS
+* @retval total number of spiritball
+**/
+int pc_getmaxspiritball(struct map_session_data *sd, int min) {
+ int result;
+
+ nullpo_ret(sd);
+
+ result = pc->checkskill(sd, MO_CALLSPIRITS);
+
+ if ( min && result < min )
+ result = min;
+ else if ( sd->sc.data[SC_RAISINGDRAGON] )
+ result += sd->sc.data[SC_RAISINGDRAGON]->val1;
+ if ( result > MAX_SPIRITBALL )
+ result = MAX_SPIRITBALL;
+ return result;
+}
+
int pc_addspiritball(struct map_session_data *sd,int interval,int max)
{
int tid, i;
@@ -495,7 +517,7 @@ void pc_rental_expire(struct map_session_data *sd, int i) {
}
clif->rental_expired(sd->fd, i, sd->status.inventory[i].nameid);
- pc->delitem(sd, i, sd->status.inventory[i].amount, 0, 0, LOG_TYPE_OTHER);
+ pc->delitem(sd, i, sd->status.inventory[i].amount, 0, DELITEM_NORMAL, LOG_TYPE_OTHER);
}
void pc_inventory_rentals(struct map_session_data *sd)
{
@@ -629,6 +651,7 @@ int pc_setnewpc(struct map_session_data *sd, int account_id, int char_id, int lo
sd->canlog_tick = timer->gettick();
//Required to prevent homunculus copuing a base speed of 0.
sd->battle_status.speed = sd->base_status.speed = DEFAULT_WALK_SPEED;
+ sd->state.warp_clean = 1;
return 0;
}
@@ -861,12 +884,12 @@ bool pc_adoption(struct map_session_data *p1_sd, struct map_session_data *p2_sd,
clif->updatestatus(b_sd, SP_JOBEXP);
// Baby Skills
- pc->skill(b_sd, WE_BABY, 1, 0);
- pc->skill(b_sd, WE_CALLPARENT, 1, 0);
+ pc->skill(b_sd, WE_BABY, 1, SKILL_GRANT_PERMANENT);
+ pc->skill(b_sd, WE_CALLPARENT, 1, SKILL_GRANT_PERMANENT);
// Parents Skills
- pc->skill(p1_sd, WE_CALLBABY, 1, 0);
- pc->skill(p2_sd, WE_CALLBABY, 1, 0);
+ pc->skill(p1_sd, WE_CALLBABY, 1, SKILL_GRANT_PERMANENT);
+ pc->skill(p2_sd, WE_CALLBABY, 1, SKILL_GRANT_PERMANENT);
return true;
}
@@ -892,12 +915,12 @@ int pc_isequip(struct map_session_data *sd,int n)
if(pc_has_permission(sd, PC_PERM_USE_ALL_EQUIPMENT))
return 1;
- if(item->elv && sd->status.base_level < (unsigned int)item->elv){
- clif->msg(sd, 0x6ED);
+ if (item->elv && sd->status.base_level < (unsigned int)item->elv) {
+ clif->msgtable(sd, MSG_ITEM_CANT_EQUIP_LVL);
return 0;
}
- if(item->elvmax && sd->status.base_level > (unsigned int)item->elvmax){
- clif->msg(sd, 0x6ED);
+ if (item->elvmax && sd->status.base_level > (unsigned int)item->elvmax) {
+ clif->msgtable(sd, MSG_ITEM_CANT_EQUIP_LVL);
return 0;
}
if(item->sex != 2 && sd->status.sex != item->sex)
@@ -906,11 +929,11 @@ int pc_isequip(struct map_session_data *sd,int n)
if ( item->equip & EQP_AMMO ) {
if ( (sd->state.active && !pc_iscarton(sd)) // check if sc data is already loaded.
&& (sd->status.class_ == JOB_GENETIC_T || sd->status.class_ == JOB_GENETIC) ) {
- clif->msg(sd, 0x5EF);
+ clif->msgtable(sd, MSG_ITEM_NEED_CART);
return 0;
}
if ( !pc_ismadogear(sd) && (sd->status.class_ == JOB_MECHANIC_T || sd->status.class_ == JOB_MECHANIC) ) {
- clif->msg(sd, 0x59B);
+ clif->msgtable(sd, MSG_ITEM_NEED_MADO);
return 0;
}
}
@@ -1119,7 +1142,7 @@ bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_tim
// Rental Timer
sd->rental_timer = INVALID_TIMER;
- for( i = 0; i < 3; i++ )
+ for( i = 0; i < MAX_PC_FEELHATE; i++ )
sd->hate_mob[i] = -1;
sd->quest_log = NULL;
@@ -1217,7 +1240,7 @@ void pc_authfail(struct map_session_data *sd)
int pc_set_hate_mob(struct map_session_data *sd, int pos, struct block_list *bl)
{
int class_;
- if (!sd || !bl || pos < 0 || pos > 2)
+ if (!sd || !bl || pos < 0 || pos >= MAX_PC_FEELHATE)
return 0;
if (sd->hate_mob[pos] != -1) {
//Can't change hate targets.
@@ -1367,7 +1390,7 @@ int pc_calc_skillpoint(struct map_session_data* sd) {
for (i = 1; i < MAX_SKILL; i++) {
int skill_lv = pc->checkskill2(sd,i);
if (skill_lv > 0) {
- inf2 = skill->db[i].inf2;
+ inf2 = skill->dbs->db[i].inf2;
if((!(inf2&INF2_QUEST_SKILL) || battle_config.quest_skill_learn) &&
!(inf2&(INF2_WEDDING_SKILL|INF2_SPIRIT_SKILL|INF2_GUILD_SKILL)) //Do not count wedding/link skills. [Skotlex]
) {
@@ -1406,7 +1429,7 @@ int pc_calc_skilltree(struct map_session_data *sd)
sd->status.skill[i].id = 0; //First clear skills.
/* permanent skills that must be re-checked */
if( sd->status.skill[i].flag == SKILL_FLAG_PERMANENT ) {
- switch( skill->db[i].nameid ) {
+ switch( skill->dbs->db[i].nameid ) {
case NV_TRICKDEAD:
if( (sd->class_&(MAPID_BASEMASK|JOBL_2)) != MAPID_NOVICE ) {
sd->status.skill[i].id = 0;
@@ -1425,21 +1448,21 @@ int pc_calc_skilltree(struct map_session_data *sd)
sd->status.skill[i].flag = SKILL_FLAG_PERMANENT;
}
- if( sd->sc.count && sd->sc.data[SC_SOULLINK] && sd->sc.data[SC_SOULLINK]->val2 == SL_BARDDANCER && skill->db[i].nameid >= DC_HUMMING && skill->db[i].nameid <= DC_SERVICEFORYOU )
+ if( sd->sc.count && sd->sc.data[SC_SOULLINK] && sd->sc.data[SC_SOULLINK]->val2 == SL_BARDDANCER && skill->dbs->db[i].nameid >= DC_HUMMING && skill->dbs->db[i].nameid <= DC_SERVICEFORYOU )
{ //Enable Bard/Dancer spirit linked skills.
if( sd->status.sex )
{ //Link dancer skills to bard.
// i can be < 8?
if( sd->status.skill[i-8].lv < 10 )
continue;
- sd->status.skill[i].id = skill->db[i].nameid;
+ sd->status.skill[i].id = skill->dbs->db[i].nameid;
sd->status.skill[i].lv = sd->status.skill[i-8].lv; // Set the level to the same as the linking skill
sd->status.skill[i].flag = SKILL_FLAG_TEMPORARY; // Tag it as a non-savable, non-uppable, bonus skill
} else { //Link bard skills to dancer.
if( sd->status.skill[i].lv < 10 )
continue;
// i can be < 8?
- sd->status.skill[i-8].id = skill->db[i-8].nameid;
+ sd->status.skill[i-8].id = skill->dbs->db[i-8].nameid;
sd->status.skill[i-8].lv = sd->status.skill[i].lv; // Set the level to the same as the linking skill
sd->status.skill[i-8].flag = SKILL_FLAG_TEMPORARY; // Tag it as a non-savable, non-uppable, bonus skill
}
@@ -1448,7 +1471,7 @@ int pc_calc_skilltree(struct map_session_data *sd)
if( pc_has_permission(sd, PC_PERM_ALL_SKILL) ) {
for( i = 0; i < MAX_SKILL; i++ ) {
- switch(skill->db[i].nameid) {
+ switch(skill->dbs->db[i].nameid) {
/**
* Dummy skills must be added here otherwise they'll be displayed in the,
* skill tree and since they have no icons they'll give resource errors
@@ -1471,10 +1494,10 @@ int pc_calc_skilltree(struct map_session_data *sd)
default:
break;
}
- if( skill->db[i].inf2&(INF2_NPC_SKILL|INF2_GUILD_SKILL) )
+ if( skill->dbs->db[i].inf2&(INF2_NPC_SKILL|INF2_GUILD_SKILL) )
continue; //Only skills you can't have are npc/guild ones
- if( skill->db[i].max > 0 )
- sd->status.skill[i].id = skill->db[i].nameid;
+ if( skill->dbs->db[i].max > 0 )
+ sd->status.skill[i].id = skill->dbs->db[i].nameid;
}
return 0;
}
@@ -1517,7 +1540,7 @@ int pc_calc_skilltree(struct map_session_data *sd)
}
if( f ) {
int inf2;
- inf2 = skill->db[idx].inf2;
+ inf2 = skill->dbs->db[idx].inf2;
if(!sd->status.skill[idx].lv && (
(inf2&INF2_QUEST_SKILL && !battle_config.quest_skill_learn) ||
@@ -1548,7 +1571,7 @@ int pc_calc_skilltree(struct map_session_data *sd)
for( i = 0; i < MAX_SKILL_TREE && (id = pc->skill_tree[c][i].id) > 0; i++ ) {
int idx = pc->skill_tree[c][i].idx;
- if( (skill->db[idx].inf2&(INF2_QUEST_SKILL|INF2_WEDDING_SKILL)) )
+ if( (skill->dbs->db[idx].inf2&(INF2_QUEST_SKILL|INF2_WEDDING_SKILL)) )
continue; //Do not include Quest/Wedding skills.
if( sd->status.skill[idx].id == 0 ) {
@@ -1618,7 +1641,7 @@ void pc_check_skilltree(struct map_session_data *sd, int skill_id)
continue;
}
- j = skill->db[idx].inf2;
+ j = skill->dbs->db[idx].inf2;
if( !sd->status.skill[idx].lv && (
(j&INF2_QUEST_SKILL && !battle_config.quest_skill_learn) ||
j&INF2_WEDDING_SKILL ||
@@ -1777,7 +1800,7 @@ int pc_disguise(struct map_session_data *sd, int class_) {
if( class_ == -1 && sd->disguise == sd->status.class_ ) {
clif->clearunit_single(-sd->bl.id,CLR_OUTSIGHT,sd->fd);
} else if ( class_ != sd->status.class_ ) {
- pc_stop_walking(sd, 0);
+ pc_stop_walking(sd, STOPWALKING_FLAG_NONE);
clif->clearunit_area(&sd->bl, CLR_OUTSIGHT);
}
}
@@ -1877,7 +1900,20 @@ int pc_bonus_autospell_onskill(struct s_autospell *spell, int max, short src_ski
return 1;
}
-int pc_bonus_addeff(struct s_addeffect* effect, int max, enum sc_type id, short rate, short arrow_rate, unsigned char flag)
+/**
+ * Adds an AddEff/AddEff2/AddEffWhenHit bonus to a character.
+ *
+ * @param effect Effects array to append to.
+ * @param max Size of the effect array.
+ * @param id Effect ID (@see enum sc_type).
+ * @param rate Trigger rate.
+ * @param arrow_rate Trigger rate modifier for ranged attacks (adds to the base rate).
+ * @param flag Trigger flags (@see enum auto_trigger_flag).
+ * @param duration Fixed (non-reducible) duration in ms. If 0, uses the default (reducible) duration of the given effect.
+ * @retval 1 on success.
+ * @retval 0 on failure.
+ */
+int pc_bonus_addeff(struct s_addeffect* effect, int max, enum sc_type id, int16 rate, int16 arrow_rate, uint8 flag, uint16 duration)
{
int i;
if (!(flag&(ATF_SHORT|ATF_LONG)))
@@ -1888,8 +1924,8 @@ int pc_bonus_addeff(struct s_addeffect* effect, int max, enum sc_type id, short
flag|=ATF_WEAPON; //Default type: weapon.
for (i = 0; i < max && effect[i].flag; i++) {
- if (effect[i].id == id && effect[i].flag == flag)
- {
+ // Update existing effect if any.
+ if (effect[i].id == id && effect[i].flag == flag && effect[i].duration == duration) {
effect[i].rate += rate;
effect[i].arrow_rate += arrow_rate;
return 1;
@@ -1903,6 +1939,7 @@ int pc_bonus_addeff(struct s_addeffect* effect, int max, enum sc_type id, short
effect[i].rate = rate;
effect[i].arrow_rate = arrow_rate;
effect[i].flag = flag;
+ effect[i].duration = duration;
return 1;
}
@@ -2769,24 +2806,56 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
switch(type){
case SP_ADDELE:
- if(type2 >= ELE_MAX) {
+ if( (type2 >= ELE_MAX && type2 != ELE_ALL) || (type2 < ELE_NEUTRAL) ) {
ShowError("pc_bonus2: SP_ADDELE: Invalid element %d\n", type2);
break;
}
- if(!sd->state.lr_flag)
- sd->right_weapon.addele[type2]+=val;
- else if(sd->state.lr_flag == 1)
- sd->left_weapon.addele[type2]+=val;
- else if(sd->state.lr_flag == 2)
- sd->arrow_addele[type2]+=val;
+ if ( type2 == ELE_ALL ) {
+ for ( i = ELE_NEUTRAL; i < ELE_MAX; i++ ) {
+ if ( !sd->state.lr_flag )
+ sd->right_weapon.addele[i] += val;
+ else if ( sd->state.lr_flag == 1 )
+ sd->left_weapon.addele[i] += val;
+ else if ( sd->state.lr_flag == 2 )
+ sd->arrow_addele[i] += val;
+ }
+ } else {
+ if(!sd->state.lr_flag)
+ sd->right_weapon.addele[type2] += val;
+ else if(sd->state.lr_flag == 1)
+ sd->left_weapon.addele[type2] += val;
+ else if(sd->state.lr_flag == 2)
+ sd->arrow_addele[type2] += val;
+ }
break;
case SP_ADDRACE:
- if(!sd->state.lr_flag)
- sd->right_weapon.addrace[type2]+=val;
- else if(sd->state.lr_flag == 1)
- sd->left_weapon.addrace[type2]+=val;
- else if(sd->state.lr_flag == 2)
- sd->arrow_addrace[type2]+=val;
+ if (type2 == RC_MAX || (type2 > RC_NONDEMIPLAYER && type2 != RC_ALL) || type2 < RC_FORMLESS ){
+ ShowWarning("pc_bonus2: SP_ADDRACE: Invalid Race(%d)\n",type2);
+ break;
+ }
+ if ( type2 >= RC_MAX ) {
+ for ( i = RC_FORMLESS; i < RC_MAX; i++ ) {
+ if ( (type2 == RC_NONPLAYER && i == RC_PLAYER) ||
+ (type2 == RC_NONDEMIHUMAN && i == RC_DEMIHUMAN) ||
+ (type2 == RC_DEMIPLAYER && (i != RC_PLAYER && i != RC_DEMIHUMAN)) ||
+ (type2 == RC_NONDEMIPLAYER && (i == RC_PLAYER || i == RC_DEMIHUMAN))
+ )
+ continue;
+ if ( !sd->state.lr_flag )
+ sd->right_weapon.addrace[i] += val;
+ else if ( sd->state.lr_flag == 1 )
+ sd->left_weapon.addrace[i] += val;
+ else if ( sd->state.lr_flag == 2 )
+ sd->arrow_addrace[i] += val;
+ }
+ } else {
+ if(!sd->state.lr_flag)
+ sd->right_weapon.addrace[type2] += val;
+ else if(sd->state.lr_flag == 1)
+ sd->left_weapon.addrace[type2] += val;
+ else if(sd->state.lr_flag == 2)
+ sd->arrow_addrace[type2] += val;
+ }
break;
case SP_ADDSIZE:
if(!sd->state.lr_flag)
@@ -2797,16 +2866,40 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
sd->arrow_addsize[type2]+=val;
break;
case SP_SUBELE:
- if(type2 >= ELE_MAX) {
+ if( (type2 >= ELE_MAX && type2 != ELE_ALL) || (type2 < ELE_NEUTRAL) ) {
ShowError("pc_bonus2: SP_SUBELE: Invalid element %d\n", type2);
break;
}
- if(sd->state.lr_flag != 2)
- sd->subele[type2]+=val;
+ if(sd->state.lr_flag != 2) {
+ if ( type2 == ELE_ALL ) {
+ for ( i = ELE_NEUTRAL; i < ELE_MAX; i++ ){
+ sd->subele[i] += val;
+ }
+ } else {
+ sd->subele[type2] += val;
+ }
+ }
break;
case SP_SUBRACE:
- if(sd->state.lr_flag != 2)
- sd->subrace[type2]+=val;
+ if (type2 == RC_MAX || (type2 > RC_NONDEMIPLAYER && type2 != RC_ALL) || type2 < RC_FORMLESS ){
+ ShowWarning("pc_bonus2: SP_SUBRACE: Invalid Race(%d)\n",type2);
+ break;
+ }
+ if(sd->state.lr_flag != 2) {
+ if (type2 >= RC_MAX ) {
+ for ( i = RC_FORMLESS; i < RC_MAX; i++ ){
+ if ( (type2 == RC_NONPLAYER && i == RC_PLAYER) ||
+ (type2 == RC_NONDEMIHUMAN && i == RC_DEMIHUMAN) ||
+ (type2 == RC_DEMIPLAYER && (i != RC_PLAYER && i != RC_DEMIHUMAN)) ||
+ (type2 == RC_NONDEMIPLAYER && (i == RC_PLAYER || i == RC_DEMIHUMAN))
+ )
+ continue;
+ sd->subrace[i] += val;
+ }
+ } else {
+ sd->subrace[type2]+=val;
+ }
+ }
break;
case SP_ADDEFF:
if (type2 > SC_MAX) {
@@ -2814,7 +2907,7 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
break;
}
pc->bonus_addeff(sd->addeff, ARRAYLENGTH(sd->addeff), (sc_type)type2,
- sd->state.lr_flag!=2?val:0, sd->state.lr_flag==2?val:0, 0);
+ sd->state.lr_flag!=2?val:0, sd->state.lr_flag==2?val:0, 0, 0);
break;
case SP_ADDEFF2:
if (type2 > SC_MAX) {
@@ -2822,7 +2915,7 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
break;
}
pc->bonus_addeff(sd->addeff, ARRAYLENGTH(sd->addeff), (sc_type)type2,
- sd->state.lr_flag!=2?val:0, sd->state.lr_flag==2?val:0, ATF_SELF);
+ sd->state.lr_flag!=2?val:0, sd->state.lr_flag==2?val:0, ATF_SELF, 0);
break;
case SP_RESEFF:
if (type2 < SC_COMMON_MIN || type2 > SC_COMMON_MAX) {
@@ -2835,24 +2928,57 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
sd->reseff[type2-SC_COMMON_MIN]= cap_value(i, 0, 10000);
break;
case SP_MAGIC_ADDELE:
- if(type2 >= ELE_MAX) {
+ if( (type2 >= ELE_MAX && type2 != ELE_ALL) || (type2 < ELE_NEUTRAL) ) {
ShowError("pc_bonus2: SP_MAGIC_ADDELE: Invalid element %d\n", type2);
break;
}
- if(sd->state.lr_flag != 2)
- sd->magic_addele[type2]+=val;
+ if ( sd->state.lr_flag != 2 ) {
+ if ( type2 == ELE_ALL ) {
+ for ( i = ELE_NEUTRAL; i < ELE_MAX; i++ )
+ sd->magic_addele[i] += val;
+ } else {
+ sd->magic_addele[type2] += val;
+ }
+ }
break;
case SP_MAGIC_ADDRACE:
- if(sd->state.lr_flag != 2)
- sd->magic_addrace[type2]+=val;
+ if (type2 == RC_MAX || (type2 > RC_NONDEMIPLAYER && type2 != RC_ALL) || type2 < RC_FORMLESS ){
+ ShowWarning("pc_bonus2: SP_MAGIC_ADDRACE: Invalid Race(%d)\n",type2);
+ break;
+ }
+ if(sd->state.lr_flag != 2){
+ if ( type2 >= RC_MAX ){
+ for ( i = RC_FORMLESS; i < RC_MAX; i++ ){
+ if ( (type2 == RC_NONPLAYER && i == RC_PLAYER) ||
+ (type2 == RC_NONDEMIHUMAN && i == RC_DEMIHUMAN) ||
+ (type2 == RC_DEMIPLAYER && (i != RC_PLAYER && i != RC_DEMIHUMAN)) ||
+ (type2 == RC_NONDEMIPLAYER && (i == RC_PLAYER || i == RC_DEMIHUMAN))
+ )
+ continue;
+ sd->magic_addrace[i] += val;
+ }
+ } else {
+ sd->magic_addrace[type2]+=val;
+ }
+ }
break;
case SP_MAGIC_ADDSIZE:
if(sd->state.lr_flag != 2)
sd->magic_addsize[type2]+=val;
break;
case SP_MAGIC_ATK_ELE:
- if(sd->state.lr_flag != 2)
- sd->magic_atk_ele[type2]+=val;
+ if( (type2 >= ELE_MAX && type2 != ELE_ALL) || (type2 < ELE_NEUTRAL) ) {
+ ShowError("pc_bonus2: SP_MAGIC_ATK_ELE: Invalid element %d\n", type2);
+ break;
+ }
+ if ( sd->state.lr_flag != 2 ) {
+ if ( type2 == ELE_ALL ) {
+ for ( i = ELE_NEUTRAL; i < ELE_MAX; i++ )
+ sd->magic_atk_ele[i] += val;
+ } else {
+ sd->magic_atk_ele[type2] += val;
+ }
+ }
break;
case SP_ADD_DAMAGE_CLASS:
switch (sd->state.lr_flag) {
@@ -3001,19 +3127,40 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
}
break;
case SP_WEAPON_COMA_ELE:
- if(type2 >= ELE_MAX) {
+ if( (type2 >= ELE_MAX && type2 != ELE_ALL) || (type2 < ELE_NEUTRAL) ) {
ShowError("pc_bonus2: SP_WEAPON_COMA_ELE: Invalid element %d\n", type2);
break;
}
if(sd->state.lr_flag == 2)
break;
- sd->weapon_coma_ele[type2] += val;
+ if ( type2 == ELE_ALL ) {
+ for ( i = ELE_NEUTRAL; i < ELE_MAX; i++ )
+ sd->weapon_coma_ele[i] += val;
+ } else {
+ sd->weapon_coma_ele[type2] += val;
+ }
sd->special_state.bonus_coma = 1;
break;
case SP_WEAPON_COMA_RACE:
+ if (type2 == RC_MAX || (type2 > RC_NONDEMIPLAYER && type2 != RC_ALL) || type2 < RC_FORMLESS ){
+ ShowWarning("pc_bonus2: SP_WEAPON_COMA_RACE: Invalid Race(%d)\n",type2);
+ break;
+ }
if(sd->state.lr_flag == 2)
break;
- sd->weapon_coma_race[type2] += val;
+ if ( type2 >= RC_MAX ) {
+ for ( i = RC_FORMLESS; i < RC_MAX; i++ ){
+ if ( (type2 == RC_NONPLAYER && i == RC_PLAYER) ||
+ (type2 == RC_NONDEMIHUMAN && i == RC_DEMIHUMAN) ||
+ (type2 == RC_DEMIPLAYER && (i != RC_PLAYER && i != RC_DEMIHUMAN)) ||
+ (type2 == RC_NONDEMIPLAYER && (i == RC_PLAYER || i == RC_DEMIHUMAN))
+ )
+ continue;
+ sd->weapon_coma_race[i] += val;
+ }
+ } else {
+ sd->weapon_coma_race[type2] += val;
+ }
sd->special_state.bonus_coma = 1;
break;
case SP_WEAPON_ATK:
@@ -3025,8 +3172,25 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
sd->weapon_atk_rate[type2]+=val;
break;
case SP_CRITICAL_ADDRACE:
- if(sd->state.lr_flag != 2)
- sd->critaddrace[type2] += val*10;
+ if (type2 == RC_MAX || (type2 > RC_NONDEMIPLAYER && type2 != RC_ALL) || type2 < RC_FORMLESS ){
+ ShowWarning("pc_bonus2: SP_CRITICAL_ADDRACE: Invalid Race(%d)\n",type2);
+ break;
+ }
+ if(sd->state.lr_flag != 2){
+ if ( type2 >= RC_MAX ){
+ for ( i = RC_FORMLESS; i < RC_MAX; i++ ){
+ if ( (type2 == RC_NONPLAYER && i == RC_PLAYER) ||
+ (type2 == RC_NONDEMIHUMAN && i == RC_DEMIHUMAN) ||
+ (type2 == RC_DEMIPLAYER && (i != RC_PLAYER && i != RC_DEMIHUMAN)) ||
+ (type2 == RC_NONDEMIPLAYER && (i == RC_PLAYER || i == RC_DEMIHUMAN))
+ )
+ continue;
+ sd->critaddrace[i] += val*10;
+ }
+ } else {
+ sd->critaddrace[type2] += val*10;
+ }
+ }
break;
case SP_ADDEFF_WHENHIT:
if (type2 > SC_MAX) {
@@ -3034,7 +3198,7 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
break;
}
if(sd->state.lr_flag != 2)
- pc->bonus_addeff(sd->addeff2, ARRAYLENGTH(sd->addeff2), (sc_type)type2, val, 0, 0);
+ pc->bonus_addeff(sd->addeff2, ARRAYLENGTH(sd->addeff2), (sc_type)type2, val, 0, 0, 0);
break;
case SP_SKILL_ATK:
if(sd->state.lr_flag == 2)
@@ -3197,12 +3361,46 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
sd->itemhealrate[i].rate += val;
break;
case SP_EXP_ADDRACE:
- if(sd->state.lr_flag != 2)
- sd->expaddrace[type2]+=val;
+ if (type2 == RC_MAX || (type2 > RC_NONDEMIPLAYER && type2 != RC_ALL) || type2 < RC_FORMLESS ){
+ ShowWarning("pc_bonus2: SP_EXP_ADDRACE: Invalid Race(%d)\n",type2);
+ break;
+ }
+ if(sd->state.lr_flag != 2) {
+ if ( type2 >= RC_MAX ){
+ for ( i = RC_FORMLESS; i < RC_MAX; i++ ){
+ if ( (type2 == RC_NONPLAYER && i == RC_PLAYER) ||
+ (type2 == RC_NONDEMIHUMAN && i == RC_DEMIHUMAN) ||
+ (type2 == RC_DEMIPLAYER && (i != RC_PLAYER && i != RC_DEMIHUMAN)) ||
+ (type2 == RC_NONDEMIPLAYER && (i == RC_PLAYER || i == RC_DEMIHUMAN))
+ )
+ continue;
+ sd->expaddrace[i] += val;
+ }
+ } else {
+ sd->expaddrace[type2] += val;
+ }
+ }
break;
case SP_SP_GAIN_RACE:
- if(sd->state.lr_flag != 2)
- sd->sp_gain_race[type2]+=val;
+ if (type2 == RC_MAX || (type2 > RC_NONDEMIPLAYER && type2 != RC_ALL) || type2 < RC_FORMLESS ){
+ ShowWarning("pc_bonus2: SP_SP_GAIN_RACE: Invalid Race(%d)\n",type2);
+ break;
+ }
+ if(sd->state.lr_flag != 2) {
+ if ( type2 >= RC_MAX ){
+ for ( i = RC_FORMLESS; i < RC_MAX; i++ ){
+ if ( (type2 == RC_NONPLAYER && i == RC_PLAYER) ||
+ (type2 == RC_NONDEMIHUMAN && i == RC_DEMIHUMAN) ||
+ (type2 == RC_DEMIPLAYER && (i != RC_PLAYER && i != RC_DEMIHUMAN)) ||
+ (type2 == RC_NONDEMIPLAYER && (i == RC_PLAYER || i == RC_DEMIHUMAN))
+ )
+ continue;
+ sd->sp_gain_race[i] += val;
+ }
+ } else {
+ sd->sp_gain_race[type2] += val;
+ }
+ }
break;
case SP_ADD_MONSTER_DROP_ITEM:
if (sd->state.lr_flag != 2)
@@ -3221,19 +3419,61 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
}
break;
case SP_HP_DRAIN_VALUE_RACE:
- if(!sd->state.lr_flag) {
- sd->right_weapon.hp_drain[type2].value += val;
+ if (type2 == RC_MAX || (type2 > RC_NONDEMIPLAYER && type2 != RC_ALL) || type2 < RC_FORMLESS ){
+ ShowWarning("pc_bonus2: SP_HP_DRAIN_VALUE_RACE: Invalid Race(%d)\n",type2);
+ break;
}
- else if(sd->state.lr_flag == 1) {
- sd->left_weapon.hp_drain[type2].value += val;
+ if ( type2 >= RC_MAX ){
+ for ( i = RC_FORMLESS; i < RC_MAX; i++ ){
+ if ( (type2 == RC_NONPLAYER && i == RC_PLAYER) ||
+ (type2 == RC_NONDEMIHUMAN && i == RC_DEMIHUMAN) ||
+ (type2 == RC_DEMIPLAYER && (i != RC_PLAYER && i != RC_DEMIHUMAN)) ||
+ (type2 == RC_NONDEMIPLAYER && (i == RC_PLAYER || i == RC_DEMIHUMAN))
+ )
+ continue;
+ if(!sd->state.lr_flag) {
+ sd->right_weapon.hp_drain[i].value += val;
+ }
+ else if(sd->state.lr_flag == 1) {
+ sd->left_weapon.hp_drain[i].value += val;
+ }
+ }
+ } else {
+ if(!sd->state.lr_flag) {
+ sd->right_weapon.hp_drain[type2].value += val;
+ }
+ else if(sd->state.lr_flag == 1) {
+ sd->left_weapon.hp_drain[type2].value += val;
+ }
}
break;
case SP_SP_DRAIN_VALUE_RACE:
- if(!sd->state.lr_flag) {
- sd->right_weapon.sp_drain[type2].value += val;
+ if (type2 == RC_MAX || (type2 > RC_NONDEMIPLAYER && type2 != RC_ALL) || type2 < RC_FORMLESS ){
+ ShowWarning("pc_bonus2: SP_SP_DRAIN_VALUE_RACE: Invalid Race(%d)\n",type2);
+ break;
}
- else if(sd->state.lr_flag == 1) {
- sd->left_weapon.sp_drain[type2].value += val;
+ if ( type2 >= RC_MAX ){
+ for ( i = RC_FORMLESS; i < RC_MAX; i++ ){
+ if ( (type2 == RC_NONPLAYER && i == RC_PLAYER) ||
+ (type2 == RC_NONDEMIHUMAN && i == RC_DEMIHUMAN) ||
+ (type2 == RC_DEMIPLAYER && (i != RC_PLAYER && i != RC_DEMIHUMAN)) ||
+ (type2 == RC_NONDEMIPLAYER && (i == RC_PLAYER || i == RC_DEMIHUMAN))
+ )
+ continue;
+ if(!sd->state.lr_flag) {
+ sd->right_weapon.sp_drain[i].value += val;
+ }
+ else if(sd->state.lr_flag == 1) {
+ sd->left_weapon.sp_drain[i].value += val;
+ }
+ }
+ } else {
+ if(!sd->state.lr_flag) {
+ sd->right_weapon.sp_drain[type2].value += val;
+ }
+ else if(sd->state.lr_flag == 1) {
+ sd->left_weapon.sp_drain[type2].value += val;
+ }
}
break;
case SP_IGNORE_MDEF_RATE:
@@ -3245,12 +3485,46 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
sd->ignore_def[type2] += val;
break;
case SP_SP_GAIN_RACE_ATTACK:
- if(sd->state.lr_flag != 2)
- sd->sp_gain_race_attack[type2] = cap_value(sd->sp_gain_race_attack[type2] + val, 0, INT16_MAX);
+ if (type2 == RC_MAX || (type2 > RC_NONDEMIPLAYER && type2 != RC_ALL) || type2 < RC_FORMLESS ){
+ ShowWarning("pc_bonus2: SP_SP_GAIN_RACE_ATTACK: Invalid Race(%d)\n",type2);
+ break;
+ }
+ if(sd->state.lr_flag != 2) {
+ if ( type2 >= RC_MAX ) {
+ for ( i = RC_FORMLESS; i < RC_MAX; i++ ){
+ if ( (type2 == RC_NONPLAYER && i == RC_PLAYER) ||
+ (type2 == RC_NONDEMIHUMAN && i == RC_DEMIHUMAN) ||
+ (type2 == RC_DEMIPLAYER && (i != RC_PLAYER && i != RC_DEMIHUMAN)) ||
+ (type2 == RC_NONDEMIPLAYER && (i == RC_PLAYER || i == RC_DEMIHUMAN))
+ )
+ continue;
+ sd->sp_gain_race_attack[i] = cap_value(sd->sp_gain_race_attack[i] + val, 0, INT16_MAX);
+ }
+ } else {
+ sd->sp_gain_race_attack[type2] = cap_value(sd->sp_gain_race_attack[type2] + val, 0, INT16_MAX);
+ }
+ }
break;
case SP_HP_GAIN_RACE_ATTACK:
- if(sd->state.lr_flag != 2)
- sd->hp_gain_race_attack[type2] = cap_value(sd->hp_gain_race_attack[type2] + val, 0, INT16_MAX);
+ if (type2 == RC_MAX || (type2 > RC_NONDEMIPLAYER && type2 != RC_ALL) || type2 < RC_FORMLESS ){
+ ShowWarning("pc_bonus2: SP_HP_GAIN_RACE_ATTACK: Invalid Race(%d)\n",type2);
+ break;
+ }
+ if(sd->state.lr_flag != 2) {
+ if ( type2 >= RC_MAX ) {
+ for ( i = RC_FORMLESS; i < RC_MAX; i++ ){
+ if ( (type2 == RC_NONPLAYER && i == RC_PLAYER) ||
+ (type2 == RC_NONDEMIHUMAN && i == RC_DEMIHUMAN) ||
+ (type2 == RC_DEMIPLAYER && (i != RC_PLAYER && i != RC_DEMIHUMAN)) ||
+ (type2 == RC_NONDEMIPLAYER && (i == RC_PLAYER || i == RC_DEMIHUMAN))
+ )
+ continue;
+ sd->hp_gain_race_attack[i] = cap_value(sd->hp_gain_race_attack[i] + val, 0, INT16_MAX);
+ }
+ } else {
+ sd->hp_gain_race_attack[type2] = cap_value(sd->hp_gain_race_attack[type2] + val, 0, INT16_MAX);
+ }
+ }
break;
case SP_SKILL_USE_SP_RATE: //bonus2 bSkillUseSPrate,n,x;
if(sd->state.lr_flag == 2)
@@ -3354,6 +3628,29 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
if (sd->state.lr_flag != 2)
pc->bonus_item_drop(sd->add_drop, ARRAYLENGTH(sd->add_drop), 0, val, 1<<type2, 10000);
break;
+#ifdef RENEWAL
+ case SP_RACE_TOLERANCE:
+ if (type2 == RC_MAX || (type2 > RC_NONDEMIPLAYER && type2 != RC_ALL) || type2 < RC_FORMLESS ){
+ ShowWarning("pc_bonus2: SP_RACE_TOLERANCE: Invalid Race(%d)\n",type2);
+ break;
+ }
+ if(sd->state.lr_flag != 2) {
+ if ( type2 >= RC_MAX ) {
+ for ( i = RC_FORMLESS; i < RC_MAX; i++ ){
+ if ( (type2 == RC_NONPLAYER && i == RC_PLAYER) ||
+ (type2 == RC_NONDEMIHUMAN && i == RC_DEMIHUMAN) ||
+ (type2 == RC_DEMIPLAYER && (i != RC_PLAYER && i != RC_DEMIHUMAN)) ||
+ (type2 == RC_NONDEMIPLAYER && (i == RC_PLAYER || i == RC_DEMIHUMAN))
+ )
+ continue;
+ sd->race_tolerance[i] += val;
+ }
+ } else {
+ sd->race_tolerance[type2] += val;
+ }
+ }
+ break;
+#endif
default:
ShowWarning("pc_bonus2: unknown type %d %d %d!\n",type,type2,val);
break;
@@ -3363,6 +3660,7 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
int pc_bonus3(struct map_session_data *sd,int type,int type2,int type3,int val)
{
+ int i;
nullpo_ret(sd);
switch(type){
@@ -3412,23 +3710,69 @@ int pc_bonus3(struct map_session_data *sd,int type,int type2,int type3,int val)
}
break;
case SP_HP_DRAIN_RATE_RACE:
- if(!sd->state.lr_flag) {
- sd->right_weapon.hp_drain[type2].rate += type3;
- sd->right_weapon.hp_drain[type2].per += val;
+ if (type2 == RC_MAX || (type2 > RC_NONDEMIPLAYER && type2 != RC_ALL) || type2 < RC_FORMLESS ){
+ ShowWarning("pc_bonus3: SP_HP_DRAIN_RATE_RACE: Invalid Race(%d)\n",type2);
+ break;
}
- else if(sd->state.lr_flag == 1) {
- sd->left_weapon.hp_drain[type2].rate += type3;
- sd->left_weapon.hp_drain[type2].per += val;
+ if ( type2 >= RC_MAX ) {
+ for ( i = RC_FORMLESS; i < RC_MAX; i++ ){
+ if ( (type2 == RC_NONPLAYER && i == RC_PLAYER) ||
+ (type2 == RC_NONDEMIHUMAN && i == RC_DEMIHUMAN) ||
+ (type2 == RC_DEMIPLAYER && (i != RC_PLAYER && i != RC_DEMIHUMAN)) ||
+ (type2 == RC_NONDEMIPLAYER && (i == RC_PLAYER || i == RC_DEMIHUMAN))
+ )
+ continue;
+ if(!sd->state.lr_flag) {
+ sd->right_weapon.hp_drain[i].rate += type3;
+ sd->right_weapon.hp_drain[i].per += val;
+ }
+ else if(sd->state.lr_flag == 1) {
+ sd->left_weapon.hp_drain[i].rate += type3;
+ sd->left_weapon.hp_drain[i].per += val;
+ }
+ }
+ } else {
+ if(!sd->state.lr_flag) {
+ sd->right_weapon.hp_drain[type2].rate += type3;
+ sd->right_weapon.hp_drain[type2].per += val;
+ }
+ else if(sd->state.lr_flag == 1) {
+ sd->left_weapon.hp_drain[type2].rate += type3;
+ sd->left_weapon.hp_drain[type2].per += val;
+ }
}
break;
case SP_SP_DRAIN_RATE_RACE:
- if(!sd->state.lr_flag) {
- sd->right_weapon.sp_drain[type2].rate += type3;
- sd->right_weapon.sp_drain[type2].per += val;
+ if (type2 == RC_MAX || (type2 > RC_NONDEMIPLAYER && type2 != RC_ALL) || type2 < RC_FORMLESS ){
+ ShowWarning("pc_bonus3: SP_SP_DRAIN_RATE_RACE: Invalid Race(%d)\n",type2);
+ break;
}
- else if(sd->state.lr_flag == 1) {
- sd->left_weapon.sp_drain[type2].rate += type3;
- sd->left_weapon.sp_drain[type2].per += val;
+ if ( type2 >= RC_MAX ) {
+ for ( i = RC_FORMLESS; i < RC_MAX; i++ ){
+ if ( (type2 == RC_NONPLAYER && i == RC_PLAYER) ||
+ (type2 == RC_NONDEMIHUMAN && i == RC_DEMIHUMAN) ||
+ (type2 == RC_DEMIPLAYER && (i != RC_PLAYER && i != RC_DEMIHUMAN)) ||
+ (type2 == RC_NONDEMIPLAYER && (i == RC_PLAYER || i == RC_DEMIHUMAN))
+ )
+ continue;
+ if(!sd->state.lr_flag) {
+ sd->right_weapon.sp_drain[i].rate += type3;
+ sd->right_weapon.sp_drain[i].per += val;
+ }
+ else if(sd->state.lr_flag == 1) {
+ sd->left_weapon.sp_drain[i].rate += type3;
+ sd->left_weapon.sp_drain[i].per += val;
+ }
+ }
+ } else {
+ if(!sd->state.lr_flag) {
+ sd->right_weapon.sp_drain[type2].rate += type3;
+ sd->right_weapon.sp_drain[type2].per += val;
+ }
+ else if(sd->state.lr_flag == 1) {
+ sd->left_weapon.sp_drain[type2].rate += type3;
+ sd->left_weapon.sp_drain[type2].per += val;
+ }
}
break;
case SP_ADDEFF:
@@ -3437,7 +3781,7 @@ int pc_bonus3(struct map_session_data *sd,int type,int type2,int type3,int val)
break;
}
pc->bonus_addeff(sd->addeff, ARRAYLENGTH(sd->addeff), (sc_type)type2,
- sd->state.lr_flag!=2?type3:0, sd->state.lr_flag==2?type3:0, val);
+ sd->state.lr_flag!=2?type3:0, sd->state.lr_flag==2?type3:0, val, 0);
break;
case SP_ADDEFF_WHENHIT:
@@ -3446,7 +3790,7 @@ int pc_bonus3(struct map_session_data *sd,int type,int type2,int type3,int val)
break;
}
if(sd->state.lr_flag != 2)
- pc->bonus_addeff(sd->addeff2, ARRAYLENGTH(sd->addeff2), (sc_type)type2, type3, 0, val);
+ pc->bonus_addeff(sd->addeff2, ARRAYLENGTH(sd->addeff2), (sc_type)type2, type3, 0, val, 0);
break;
case SP_ADDEFF_ONSKILL:
@@ -3459,21 +3803,33 @@ int pc_bonus3(struct map_session_data *sd,int type,int type2,int type3,int val)
break;
case SP_ADDELE:
- if (type2 > ELE_MAX) {
- ShowWarning("pc_bonus3 (SP_ADDELE): element %d is out of range.\n", type2);
+ if( (type2 >= ELE_MAX && type2 != ELE_ALL) || (type2 < ELE_NEUTRAL) ) {
+ ShowError("pc_bonus3: SP_ADDELE: Invalid element %d\n", type2);
break;
}
- if (sd->state.lr_flag != 2)
- pc_bonus_addele(sd, (unsigned char)type2, type3, val);
+ if ( sd->state.lr_flag != 2 ) {
+ if ( type2 == ELE_ALL ) {
+ for ( i = ELE_NEUTRAL; i < ELE_MAX; i++ )
+ pc_bonus_addele(sd, (unsigned char)i, type3, val);
+ } else {
+ pc_bonus_addele(sd, (unsigned char)type2, type3, val);
+ }
+ }
break;
case SP_SUBELE:
- if (type2 > ELE_MAX) {
- ShowWarning("pc_bonus3 (SP_SUBELE): element %d is out of range.\n", type2);
+ if( (type2 >= ELE_MAX && type2 != ELE_ALL) || (type2 < ELE_NEUTRAL) ) {
+ ShowError("pc_bonus3: SP_SUBELE: Invalid element %d\n", type2);
break;
}
- if (sd->state.lr_flag != 2)
- pc_bonus_subele(sd, (unsigned char)type2, type3, val);
+ if ( sd->state.lr_flag != 2 ) {
+ if ( type2 == ELE_ALL ) {
+ for ( i = ELE_NEUTRAL; i < ELE_MAX; i++ )
+ pc_bonus_subele(sd, (unsigned char)i, type3, val);
+ } else {
+ pc_bonus_subele(sd, (unsigned char)type2, type3, val);
+ }
+ }
break;
case SP_SP_VANISH_RATE:
if(sd->state.lr_flag != 2) {
@@ -3492,6 +3848,7 @@ int pc_bonus3(struct map_session_data *sd,int type,int type2,int type3,int val)
}
int pc_bonus4(struct map_session_data *sd,int type,int type2,int type3,int type4,int val) {
+ int i;
nullpo_ret(sd);
switch(type) {
@@ -3524,27 +3881,74 @@ int pc_bonus4(struct map_session_data *sd,int type,int type2,int type3,int type4
break;
case SP_SET_DEF_RACE: //bonus4 bSetDefRace,n,x,r,y;
- if( type2 >= RC_MAX ) {
- ShowWarning("pc_bonus4 (DEF_SET): %d is not supported.\n", type2);
+ if (type2 == RC_MAX || (type2 > RC_NONDEMIPLAYER && type2 != RC_ALL) || type2 < RC_FORMLESS ){
+ ShowWarning("pc_bonus4: SP_SET_DEF_RACE: Invalid Race(%d)\n",type2);
break;
}
if(sd->state.lr_flag == 2)
break;
- sd->def_set_race[type2].rate = type3;
- sd->def_set_race[type2].tick = type4;
- sd->def_set_race[type2].value = val;
+ if ( type2 >= RC_MAX ) {
+ for ( i = RC_FORMLESS; i < RC_MAX; i++ ){
+ if ( (type2 == RC_NONPLAYER && i == RC_PLAYER) ||
+ (type2 == RC_NONDEMIHUMAN && i == RC_DEMIHUMAN) ||
+ (type2 == RC_DEMIPLAYER && (i != RC_PLAYER && i != RC_DEMIHUMAN)) ||
+ (type2 == RC_NONDEMIPLAYER && (i == RC_PLAYER || i == RC_DEMIHUMAN))
+ )
+ continue;
+ sd->def_set_race[i].rate = type3;
+ sd->def_set_race[i].tick = type4;
+ sd->def_set_race[i].value = val;
+ }
+ } else {
+ sd->def_set_race[type2].rate = type3;
+ sd->def_set_race[type2].tick = type4;
+ sd->def_set_race[type2].value = val;
+ }
break;
case SP_SET_MDEF_RACE: //bonus4 bSetMDefRace,n,x,r,y;
- if( type2 >= RC_MAX ) {
- ShowWarning("pc_bonus4 (MDEF_SET): %d is not supported.\n", type2);
+ if (type2 == RC_MAX || (type2 > RC_NONDEMIPLAYER && type2 != RC_ALL) || type2 < RC_FORMLESS ){
+ ShowWarning("pc_bonus4: SP_SET_MDEF_RACE: Invalid Race(%d)\n",type2);
break;
}
if(sd->state.lr_flag == 2)
break;
- sd->mdef_set_race[type2].rate = type3;
- sd->mdef_set_race[type2].tick = type4;
- sd->mdef_set_race[type2].value = val;
+ if ( type2 >= RC_MAX ) {
+ for ( i = RC_FORMLESS; i < RC_MAX; i++ ){
+ if ( (type2 == RC_NONPLAYER && i == RC_PLAYER) ||
+ (type2 == RC_NONDEMIHUMAN && i == RC_DEMIHUMAN) ||
+ (type2 == RC_DEMIPLAYER && (i != RC_PLAYER && i != RC_DEMIHUMAN)) ||
+ (type2 == RC_NONDEMIPLAYER && (i == RC_PLAYER || i == RC_DEMIHUMAN))
+ )
+ continue;
+ sd->mdef_set_race[i].rate = type3;
+ sd->mdef_set_race[i].tick = type4;
+ sd->mdef_set_race[i].value = val;
+ }
+ } else {
+ sd->mdef_set_race[type2].rate = type3;
+ sd->mdef_set_race[type2].tick = type4;
+ sd->mdef_set_race[type2].value = val;
+ }
+ break;
+
+ case SP_ADDEFF:
+ {
+ uint16 duration;
+ if (type2 > SC_MAX) {
+ ShowWarning("pc_bonus4 (Add Effect): %d is not supported.\n", type2);
+ break;
+ }
+ if (val < 0 || val > UINT16_MAX) {
+ ShowWarning("pc_bonus4 (Add Effect): invalid duration %d. Valid range: [0:%d].\n", val, UINT16_MAX);
+ duration = (val < 0 ? 0 : UINT16_MAX);
+ } else {
+ duration = (uint16)val;
+ }
+
+ pc->bonus_addeff(sd->addeff, ARRAYLENGTH(sd->addeff), (sc_type)type2,
+ sd->state.lr_flag!=2?type3:0, sd->state.lr_flag==2?type3:0, type4, duration);
+ }
break;
default:
@@ -3583,13 +3987,11 @@ int pc_bonus5(struct map_session_data *sd,int type,int type2,int type3,int type4
}
/*==========================================
- * Grants a player a given skill. Flag values are:
- * 0 - Grant permanent skill to be bound to skill tree
- * 1 - Grant an item skill (temporary)
- * 2 - Like 1, except the level granted can stack with previously learned level.
- * 3 - Grant skill unconditionally and forever (persistent to job changes and skill resets)
+ * Grants a player a given skill.
+ * Flag values: @see enum pc_skill_flag
*------------------------------------------*/
-int pc_skill(TBL_PC* sd, int id, int level, int flag) {
+int pc_skill(TBL_PC* sd, int id, int level, int flag)
+{
uint16 index = 0;
nullpo_ret(sd);
@@ -3601,13 +4003,13 @@ int pc_skill(TBL_PC* sd, int id, int level, int flag) {
ShowError("pc_skill: Skill level %d too high. Max lv supported is %d\n", level, MAX_SKILL_LEVEL);
return 0;
}
- if( flag == 2 && sd->status.skill[index].lv + level > MAX_SKILL_LEVEL ) {
+ if( flag == SKILL_GRANT_TEMPSTACK && sd->status.skill[index].lv + level > MAX_SKILL_LEVEL ) {
ShowError("pc_skill: Skill level bonus %d too high. Max lv supported is %d. Curr lv is %d\n", level, MAX_SKILL_LEVEL, sd->status.skill[index].lv);
return 0;
}
switch( flag ){
- case 0: //Set skill data overwriting whatever was there before.
+ case SKILL_GRANT_PERMANENT: //Set skill data overwriting whatever was there before.
sd->status.skill[index].id = id;
sd->status.skill[index].lv = level;
sd->status.skill[index].flag = SKILL_FLAG_PERMANENT;
@@ -3616,10 +4018,10 @@ int pc_skill(TBL_PC* sd, int id, int level, int flag) {
clif->deleteskill(sd,id);
} else
clif->addskill(sd,id);
- if( !skill->db[index].inf ) //Only recalculate for passive skills.
+ if( !skill->dbs->db[index].inf ) //Only recalculate for passive skills.
status_calc_pc(sd, SCO_NONE);
break;
- case 1: //Item bonus skill.
+ case SKILL_GRANT_TEMPORARY: //Item bonus skill.
if( sd->status.skill[index].id == id ) {
if( sd->status.skill[index].lv >= level )
return 0;
@@ -3631,7 +4033,7 @@ int pc_skill(TBL_PC* sd, int id, int level, int flag) {
}
sd->status.skill[index].lv = level;
break;
- case 2: //Add skill bonus on top of what you had.
+ case SKILL_GRANT_TEMPSTACK: //Add skill bonus on top of what you had.
if( sd->status.skill[index].id == id ) {
if( sd->status.skill[index].flag == SKILL_FLAG_PERMANENT )
sd->status.skill[index].flag = SKILL_FLAG_REPLACED_LV_0 + sd->status.skill[index].lv; // Store previous level.
@@ -3641,7 +4043,7 @@ int pc_skill(TBL_PC* sd, int id, int level, int flag) {
}
sd->status.skill[index].lv += level;
break;
- case 3:
+ case SKILL_GRANT_UNCONDITIONAL:
sd->status.skill[index].id = id;
sd->status.skill[index].lv = level;
sd->status.skill[index].flag = SKILL_FLAG_PERM_GRANTED;
@@ -3650,60 +4052,100 @@ int pc_skill(TBL_PC* sd, int id, int level, int flag) {
clif->deleteskill(sd,id);
} else
clif->addskill(sd,id);
- if( !skill->db[index].inf ) //Only recalculate for passive skills.
+ if( !skill->dbs->db[index].inf ) //Only recalculate for passive skills.
status_calc_pc(sd, SCO_NONE);
break;
- default: //Unknown flag?
- return 0;
+ default: //Unknown flag?
+ return 0;
}
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;
- if( pc->delitem(sd,idx_card,1,1,0,LOG_TYPE_OTHER) == 1 )
+ if( pc->delitem(sd, idx_card, 1, 1, DELITEM_NORMAL, LOG_TYPE_OTHER) == 1 )
{// failed
clif->insert_card(sd,idx_equip,idx_card,1);
}
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]);
@@ -4047,6 +4489,7 @@ int pc_additem(struct map_session_data *sd,struct item *item_data,int amount,e_l
if( sd->status.inventory[i].nameid == item_data->nameid &&
sd->status.inventory[i].bound == item_data->bound &&
sd->status.inventory[i].expire_time == 0 &&
+ sd->status.inventory[i].unique_id == item_data->unique_id &&
memcmp(&sd->status.inventory[i].card, &item_data->card, sizeof(item_data->card)) == 0 ) {
if( amount > MAX_AMOUNT - sd->status.inventory[i].amount || ( data->stack.inventory && amount > data->stack.amount - sd->status.inventory[i].amount ) )
return 5;
@@ -4074,8 +4517,8 @@ int pc_additem(struct map_session_data *sd,struct item *item_data,int amount,e_l
clif->additem(sd,i,amount,0);
}
- if( !itemdb->isstackable2(data) && !item_data->unique_id )
- sd->status.inventory[i].unique_id = itemdb->unique_id(sd);
+ if( ( !itemdb->isstackable2(data) || data->flag.force_serial || data->type == IT_CASH) && !item_data->unique_id )
+ sd->status.inventory[i].unique_id = itemdb->unique_id(sd);
logs->pick_pc(sd, log_type, amount, &sd->status.inventory[i],sd->inventory_data[i]);
@@ -4105,6 +4548,7 @@ int pc_additem(struct map_session_data *sd,struct item *item_data,int amount,e_l
* @type
* 1 : don't notify deletion
* 2 : don't notify weight change
+ * reason: @see enum delitem_reason
* Return:
* 0 = success
* 1 = invalid itemid or negative amount
@@ -4122,7 +4566,7 @@ int pc_delitem(struct map_session_data *sd,int n,int amount,int type, short reas
sd->weight -= sd->inventory_data[n]->weight*amount ;
if( sd->status.inventory[n].amount <= 0 ){
if(sd->status.inventory[n].equip)
- pc->unequipitem(sd,n,3);
+ pc->unequipitem(sd, n, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE);
memset(&sd->status.inventory[n],0,sizeof(sd->status.inventory[0]));
sd->inventory_data[n] = NULL;
}
@@ -4172,7 +4616,7 @@ int pc_dropitem(struct map_session_data *sd,int n,int amount)
if (!map->addflooritem(&sd->status.inventory[n], amount, sd->bl.m, sd->bl.x, sd->bl.y, 0, 0, 0, 2))
return 0;
- pc->delitem(sd, n, amount, 1, 0, LOG_TYPE_PICKDROP_PLAYER);
+ pc->delitem(sd, n, amount, 1, DELITEM_NORMAL, LOG_TYPE_PICKDROP_PLAYER);
clif->dropitem(sd, n, amount);
return 1;
}
@@ -4267,14 +4711,14 @@ int pc_isUseitem(struct map_session_data *sd,int n)
if( !item->script ) //if it has no script, you can't really consume it!
return 0;
- if( (item->item_usage.flag&INR_SITTING) && (pc_issit(sd) == 1) && (pc_get_group_level(sd) < item->item_usage.override) ) {
- clif->msgtable(sd->fd,0x297);
- //clif->colormes(sd->fd,COLOR_WHITE,msg_txt(1474));
+ if ((item->item_usage.flag&INR_SITTING) && (pc_issit(sd) == 1) && (pc_get_group_level(sd) < item->item_usage.override)) {
+ clif->msgtable(sd, MSG_ITEM_NEED_STANDING);
+ //clif->messagecolor_self(sd->fd, COLOR_WHITE, msg_txt(1474));
return 0; // You cannot use this item while sitting.
}
- if (sd->state.storage_flag && item->type != IT_CASH) {
- clif->colormes(sd->fd, COLOR_RED, msg_sd(sd,1475));
+ if (sd->state.storage_flag != STORAGE_FLAG_CLOSED && item->type != IT_CASH) {
+ clif->messagecolor_self(sd->fd, COLOR_RED, msg_sd(sd,1475));
return 0; // You cannot use this item while storage is open.
}
@@ -4373,12 +4817,12 @@ int pc_isUseitem(struct map_session_data *sd,int n)
return 0;
if( item->package || item->group ) {
- if( pc_is90overweight(sd) ) {
- clif->msgtable(sd->fd,ITEM_CANT_OBTAIN_WEIGHT);
+ if (pc_is90overweight(sd)) {
+ clif->msgtable(sd, MSG_ITEM_CANT_OBTAIN_WEIGHT);
return 0;
}
- if( !pc->inventoryblank(sd) ) {
- clif->colormes(sd->fd,COLOR_RED,msg_sd(sd,1477));
+ if (!pc->inventoryblank(sd)) {
+ clif->messagecolor_self(sd->fd, COLOR_RED, msg_sd(sd,1477));
return 0;
}
}
@@ -4387,13 +4831,13 @@ int pc_isUseitem(struct map_session_data *sd,int n)
if(item->sex != 2 && sd->status.sex != item->sex)
return 0;
//Required level check
- if(item->elv && sd->status.base_level < (unsigned int)item->elv){
- clif->msg(sd, 0x6EE);
+ if (item->elv && sd->status.base_level < (unsigned int)item->elv) {
+ clif->msgtable(sd, MSG_ITEM_CANT_USE_LVL);
return 0;
}
- if(item->elvmax && sd->status.base_level > (unsigned int)item->elvmax){
- clif->msg(sd, 0x6EE);
+ if (item->elvmax && sd->status.base_level > (unsigned int)item->elvmax) {
+ clif->msgtable(sd, MSG_ITEM_CANT_USE_LVL);
return 0;
}
@@ -4445,7 +4889,7 @@ int pc_useitem(struct map_session_data *sd,int n) {
if( sd->npc_id || sd->state.workinprogress&1 ){
/* TODO: add to clif->messages enum */
#ifdef RENEWAL
- clif->msg(sd, 0x783); // TODO look for the client date that has this message.
+ clif->msgtable(sd, MSG_NPC_WORK_IN_PROGRESS); // TODO look for the client date that has this message.
#endif
return 0;
}
@@ -4508,7 +4952,7 @@ int pc_useitem(struct map_session_data *sd,int n) {
if( sd->item_delay[i].nameid ) {// found
if( DIFF_TICK(sd->item_delay[i].tick, tick) > 0 ) {
int e_tick = (int)(DIFF_TICK(sd->item_delay[i].tick, tick)/1000);
- clif->msgtable_num(sd->fd, 0x746, e_tick + 1); // [%d] seconds left until you can use
+ clif->msgtable_num(sd, MSG_SECONDS_UNTIL_USE, e_tick + 1); // [%d] seconds left until you can use
return 0; // Delay has not expired yet
}
} else {// not yet used item (all slots are initially empty)
@@ -4531,10 +4975,10 @@ int pc_useitem(struct map_session_data *sd,int n) {
/* on restricted maps the item is consumed but the effect is not used */
for(i = 0; i < map->list[sd->bl.m].zone->disabled_items_count; i++) {
if( map->list[sd->bl.m].zone->disabled_items[i] == nameid ) {
- clif->msg(sd, ITEM_CANT_USE_AREA); // This item cannot be used within this area
+ clif->msgtable(sd, MSG_ITEM_CANT_USE_AREA); // This item cannot be used within this area
if( battle_config.item_restricted_consumption_type && sd->status.inventory[n].expire_time == 0 ) {
clif->useitemack(sd,n,sd->status.inventory[n].amount-1,true);
- pc->delitem(sd,n,1,1,0,LOG_TYPE_CONSUME);
+ pc->delitem(sd, n, 1, 1, DELITEM_NORMAL, LOG_TYPE_CONSUME);
}
return 0;
}
@@ -4552,14 +4996,15 @@ int pc_useitem(struct map_session_data *sd,int n) {
amount = sd->status.inventory[n].amount;
item_script = sd->inventory_data[n]->script;
//Check if the item is to be consumed immediately [Skotlex]
- if( sd->inventory_data[n]->flag.delay_consume )
+ if (sd->inventory_data[n]->flag.delay_consume || sd->inventory_data[n]->flag.keepafteruse)
clif->useitemack(sd,n,amount,true);
else {
- if (sd->status.inventory[n].expire_time == 0 && !(sd->inventory_data[n]->flag.keepafteruse)) {
- clif->useitemack(sd,n,amount-1,true);
- pc->delitem(sd,n,1,1,0,LOG_TYPE_CONSUME); // Rental Usable Items are not deleted until expiration
- } else
- clif->useitemack(sd,n,0,false);
+ if (sd->status.inventory[n].expire_time == 0) {
+ clif->useitemack(sd, n, amount - 1, true);
+ pc->delitem(sd, n, 1, 1, DELITEM_NORMAL, LOG_TYPE_CONSUME); // Rental Usable Items are not deleted until expiration
+ } else {
+ clif->useitemack(sd, n, 0, false);
+ }
}
if(sd->status.inventory[n].card[0]==CARD0_CREATE &&
pc->famerank(MakeDWord(sd->status.inventory[n].card[2],sd->status.inventory[n].card[3]), MAPID_ALCHEMIST))
@@ -4625,7 +5070,7 @@ int pc_cart_additem(struct map_session_data *sd,struct item *item_data,int amoun
sd->status.cart[i].card[2] == item_data->card[2] && sd->status.cart[i].card[3] == item_data->card[3] );
};
- if( i < MAX_CART )
+ if( i < MAX_CART && item_data->unique_id == sd->status.cart[i].unique_id)
{// item already in cart, stack it
if( amount > MAX_AMOUNT - sd->status.cart[i].amount || ( data->stack.cart && amount > data->stack.amount - sd->status.cart[i].amount ) )
return 2; // no room
@@ -4704,7 +5149,7 @@ int pc_putitemtocart(struct map_session_data *sd,int idx,int amount)
return 1;
if( (flag = pc->cart_additem(sd,item_data,amount,LOG_TYPE_NONE)) == 0 )
- return pc->delitem(sd,idx,amount,0,5,LOG_TYPE_NONE);
+ return pc->delitem(sd, idx, amount, 0, DELITEM_TOCART, LOG_TYPE_NONE);
return flag;
}
@@ -4763,7 +5208,7 @@ void pc_bound_clear(struct map_session_data *sd, enum e_item_bound_type type) {
case IBT_CHARACTER:
for( i = 0; i < MAX_INVENTORY; i++ ){
if( sd->status.inventory[i].bound == type ) {
- pc->delitem(sd,i,sd->status.inventory[i].amount,0,1,LOG_TYPE_OTHER);
+ pc->delitem(sd, i, sd->status.inventory[i].amount, 0, DELITEM_SKILLUSE, LOG_TYPE_OTHER); // FIXME: is this the correct reason flag?
}
}
break;
@@ -4777,7 +5222,7 @@ void pc_bound_clear(struct map_session_data *sd, enum e_item_bound_type type) {
if(sd->status.inventory[i].bound == type) {
if( gstor )
gstorage->additem(sd,gstor,&sd->status.inventory[i],sd->status.inventory[i].amount);
- pc->delitem(sd,i,sd->status.inventory[i].amount,0,1,gstor?LOG_TYPE_GSTORAGE:LOG_TYPE_OTHER);
+ pc->delitem(sd, i, sd->status.inventory[i].amount, 0, DELITEM_SKILLUSE, gstor ? LOG_TYPE_GSTORAGE : LOG_TYPE_OTHER); // FIXME: is this the correct reason flag?
}
}
if( gstor )
@@ -5046,7 +5491,7 @@ int pc_setpos(struct map_session_data* sd, unsigned short map_index, int x, int
for( i = 0; i < EQI_MAX; i++ ) {
if( sd->equip_index[ i ] >= 0 )
if( !pc->isequip( sd , sd->equip_index[ i ] ) )
- pc->unequipitem( sd , sd->equip_index[ i ] , 2 );
+ pc->unequipitem(sd, sd->equip_index[i], PCUNEQUIPITEM_FORCE);
}
if (battle_config.clear_unit_onwarp&BL_PC)
skill->clear_unitgroup(&sd->bl);
@@ -5262,14 +5707,14 @@ int pc_checkskill2(struct map_session_data *sd,uint16 index) {
ShowError("pc_checkskill: Invalid skill index %d (char_id=%d).\n", index, sd->status.char_id);
return 0;
}
- if( skill->db[index].nameid >= GD_SKILLBASE && skill->db[index].nameid < GD_MAX ) {
+ if( skill->dbs->db[index].nameid >= GD_SKILLBASE && skill->dbs->db[index].nameid < GD_MAX ) {
struct guild *g;
if( sd->status.guild_id>0 && (g=sd->guild)!=NULL)
- return guild->checkskill(g,skill->db[index].nameid);
+ return guild->checkskill(g,skill->dbs->db[index].nameid);
return 0;
}
- if(sd->status.skill[index].id == skill->db[index].nameid)
+ if(sd->status.skill[index].id == skill->dbs->db[index].nameid)
return (sd->status.skill[index].lv);
return 0;
@@ -5862,6 +6307,138 @@ const char* job_name(int class_)
}
}
+int pc_check_job_name(const char *name) {
+ int i, len;
+ struct {
+ const char *name;
+ int id;
+ } names[] = {
+ { "Novice", JOB_NOVICE },
+ { "Swordsman", JOB_SWORDMAN },
+ { "Magician", JOB_MAGE },
+ { "Archer", JOB_ARCHER },
+ { "Acolyte", JOB_ACOLYTE },
+ { "Merchant", JOB_MERCHANT },
+ { "Thief", JOB_THIEF },
+ { "Knight", JOB_KNIGHT },
+ { "Priest", JOB_PRIEST },
+ { "Wizard", JOB_WIZARD },
+ { "Blacksmith", JOB_BLACKSMITH },
+ { "Hunter", JOB_HUNTER },
+ { "Assassin", JOB_ASSASSIN },
+ { "Crusader", JOB_CRUSADER },
+ { "Monk", JOB_MONK },
+ { "Sage", JOB_SAGE },
+ { "Rogue", JOB_ROGUE },
+ { "Alchemist", JOB_ALCHEMIST },
+ { "Bard", JOB_BARD },
+ { "Dancer", JOB_DANCER },
+ { "Super_Novice", JOB_SUPER_NOVICE },
+ { "Gunslinger", JOB_GUNSLINGER },
+ { "Ninja", JOB_NINJA },
+ { "Novice_High", JOB_NOVICE_HIGH },
+ { "Swordsman_High", JOB_SWORDMAN_HIGH },
+ { "Magician_High", JOB_MAGE_HIGH },
+ { "Archer_High", JOB_ARCHER_HIGH },
+ { "Acolyte_High", JOB_ACOLYTE_HIGH },
+ { "Merchant_High", JOB_MERCHANT_HIGH },
+ { "Thief_High", JOB_THIEF_HIGH },
+ { "Lord_Knight", JOB_LORD_KNIGHT },
+ { "High_Priest", JOB_HIGH_PRIEST },
+ { "High_Wizard", JOB_HIGH_WIZARD },
+ { "Whitesmith", JOB_WHITESMITH },
+ { "Sniper", JOB_SNIPER },
+ { "Assassin_Cross", JOB_ASSASSIN_CROSS },
+ { "Paladin", JOB_PALADIN },
+ { "Champion", JOB_CHAMPION },
+ { "Professor", JOB_PROFESSOR },
+ { "Stalker", JOB_STALKER },
+ { "Creator", JOB_CREATOR },
+ { "Clown", JOB_CLOWN },
+ { "Gypsy", JOB_GYPSY },
+ { "Baby_Novice", JOB_BABY },
+ { "Baby_Swordsman", JOB_BABY_SWORDMAN },
+ { "Baby_Magician", JOB_BABY_MAGE },
+ { "Baby_Archer", JOB_BABY_ARCHER },
+ { "Baby_Acolyte", JOB_BABY_ACOLYTE },
+ { "Baby_Merchant", JOB_BABY_MERCHANT },
+ { "Baby_Thief", JOB_BABY_THIEF },
+ { "Baby_Knight", JOB_BABY_KNIGHT },
+ { "Baby_Priest", JOB_BABY_PRIEST },
+ { "Baby_Wizard", JOB_BABY_WIZARD },
+ { "Baby_Blacksmith", JOB_BABY_BLACKSMITH },
+ { "Baby_Hunter", JOB_BABY_HUNTER },
+ { "Baby_Assassin", JOB_BABY_ASSASSIN },
+ { "Baby_Crusader", JOB_BABY_CRUSADER },
+ { "Baby_Monk", JOB_BABY_MONK },
+ { "Baby_Sage", JOB_BABY_SAGE },
+ { "Baby_Rogue", JOB_BABY_ROGUE },
+ { "Baby_Alchemist", JOB_BABY_ALCHEMIST },
+ { "Baby_Bard", JOB_BABY_BARD },
+ { "Baby_Dancer", JOB_BABY_DANCER },
+ { "Super_Baby", JOB_SUPER_BABY },
+ { "Taekwon", JOB_TAEKWON },
+ { "Star_Gladiator", JOB_STAR_GLADIATOR },
+ { "Soul_Linker", JOB_SOUL_LINKER },
+ { "Gangsi", JOB_GANGSI },
+ { "Death_Knight", JOB_DEATH_KNIGHT },
+ { "Dark_Collector", JOB_DARK_COLLECTOR },
+ { "Rune_Knight", JOB_RUNE_KNIGHT },
+ { "Warlock", JOB_WARLOCK },
+ { "Ranger", JOB_RANGER },
+ { "Arch_Bishop", JOB_ARCH_BISHOP },
+ { "Mechanic", JOB_MECHANIC },
+ { "Guillotine_Cross", JOB_GUILLOTINE_CROSS },
+ { "Rune_Knight_Trans", JOB_RUNE_KNIGHT_T },
+ { "Warlock_Trans", JOB_WARLOCK_T },
+ { "Ranger_Trans", JOB_RANGER_T },
+ { "Arch_Bishop_Trans", JOB_ARCH_BISHOP_T },
+ { "Mechanic_Trans", JOB_MECHANIC_T },
+ { "Guillotine_Cross_Trans", JOB_GUILLOTINE_CROSS_T },
+ { "Royal_Guard", JOB_ROYAL_GUARD },
+ { "Sorcerer", JOB_SORCERER },
+ { "Minstrel", JOB_MINSTREL },
+ { "Wanderer", JOB_WANDERER },
+ { "Sura", JOB_SURA },
+ { "Genetic", JOB_GENETIC },
+ { "Shadow_Chaser", JOB_SHADOW_CHASER },
+ { "Royal_Guard_Trans", JOB_ROYAL_GUARD_T },
+ { "Sorcerer_Trans", JOB_SORCERER_T },
+ { "Minstrel_Trans", JOB_MINSTREL_T },
+ { "Wanderer_Trans", JOB_WANDERER_T },
+ { "Sura_Trans", JOB_SURA_T },
+ { "Genetic_Trans", JOB_GENETIC_T },
+ { "Shadow_Chaser_Trans", JOB_SHADOW_CHASER_T },
+ { "Baby_Rune_Knight", JOB_BABY_RUNE },
+ { "Baby_Warlock", JOB_BABY_WARLOCK },
+ { "Baby_Ranger", JOB_BABY_RANGER },
+ { "Baby_Arch_Bishop", JOB_BABY_BISHOP },
+ { "Baby_Mechanic", JOB_BABY_MECHANIC },
+ { "Baby_Guillotine_Cross", JOB_BABY_CROSS },
+ { "Baby_Royal_Guard", JOB_BABY_GUARD },
+ { "Baby_Sorcerer", JOB_BABY_SORCERER },
+ { "Baby_Minstrel", JOB_BABY_MINSTREL },
+ { "Baby_Wanderer", JOB_BABY_WANDERER },
+ { "Baby_Sura", JOB_BABY_SURA },
+ { "Baby_Genetic", JOB_BABY_GENETIC },
+ { "Baby_Shadow_Chaser", JOB_BABY_CHASER },
+ { "Expanded_Super_Novice", JOB_SUPER_NOVICE_E },
+ { "Expanded_Super_Baby", JOB_SUPER_BABY_E },
+ { "Kagerou", JOB_KAGEROU },
+ { "Oboro", JOB_OBORO },
+ { "Rebellion", JOB_REBELLION },
+ };
+
+ len = ARRAYLENGTH(names);
+
+ ARR_FIND(0, len, i, strcmpi(names[i].name, name) == 0);
+
+ if ( i == len )
+ return -1;
+
+ return names[i].id;
+}
+
int pc_follow_timer(int tid, int64 tick, int id, intptr_t data) {
struct map_session_data *sd;
struct block_list *tbl;
@@ -5911,7 +6488,7 @@ int pc_stop_following (struct map_session_data *sd)
sd->followtarget = -1;
sd->ud.target_to = 0;
- unit->stop_walking(&sd->bl, 1);
+ unit->stop_walking(&sd->bl, STOPWALKING_FLAG_FIXPOS);
return 0;
}
@@ -5984,7 +6561,7 @@ void pc_baselevelchanged(struct map_session_data *sd) {
for( i = 0; i < EQI_MAX; i++ ) {
if( sd->equip_index[i] >= 0 ) {
if( sd->inventory_data[ sd->equip_index[i] ]->elvmax && sd->status.base_level > (unsigned int)sd->inventory_data[ sd->equip_index[i] ]->elvmax )
- pc->unequipitem(sd, sd->equip_index[i], 3);
+ pc->unequipitem(sd, sd->equip_index[i], PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE);
}
}
}
@@ -6439,7 +7016,7 @@ int pc_skillup(struct map_session_data *sd,uint16 skill_id) {
{
sd->status.skill[index].lv++;
sd->status.skill_point--;
- if( !skill->db[index].inf )
+ if( !skill->dbs->db[index].inf )
status_calc_pc(sd,SCO_NONE); // Only recalculate for passive skills.
else if( sd->status.skill_point == 0 && (sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= 90 && pc->famerank(sd->status.char_id, MAPID_TAEKWON) )
pc->calc_skilltree(sd); // Required to grant all TK Ranger skills.
@@ -6453,14 +7030,12 @@ int pc_skillup(struct map_session_data *sd,uint16 skill_id) {
if (!pc_has_permission(sd, PC_PERM_ALL_SKILL)) // may skill everything at any time anyways, and this would cause a huge slowdown
clif->skillinfoblock(sd);
} else if( battle_config.skillup_limit ){
- if( sd->sktree.second )
- clif->msg_value(sd, 0x61E, sd->sktree.second);
- else if( sd->sktree.third )
- clif->msg_value(sd, 0x61F, sd->sktree.third);
- else if( pc->calc_skillpoint(sd) < 9 ) {
- /* TODO: official response? */
- clif->colormes(sd->fd,COLOR_RED,"You need the basic skills");
- }
+ if (sd->sktree.second)
+ clif->msgtable_num(sd, MSG_SKILL_POINTS_LEFT_JOB1, sd->sktree.second);
+ else if (sd->sktree.third)
+ clif->msgtable_num(sd, MSG_SKILL_POINTS_LEFT_JOB2, sd->sktree.third);
+ else if (pc->calc_skillpoint(sd) < 9) /* TODO: official response? */
+ clif->messagecolor_self(sd->fd, COLOR_RED, "You need the basic skills");
}
return 0;
}
@@ -6486,22 +7061,22 @@ int pc_allskillup(struct map_session_data *sd)
if (pc_has_permission(sd, PC_PERM_ALL_SKILL)) { //Get ALL skills except npc/guild ones. [Skotlex]
//and except SG_DEVIL [Komurka] and MO_TRIPLEATTACK and RG_SNATCHER [ultramage]
for(i=0;i<MAX_SKILL;i++){
- switch( skill->db[i].nameid ) {
+ switch( skill->dbs->db[i].nameid ) {
case SG_DEVIL:
case MO_TRIPLEATTACK:
case RG_SNATCHER:
continue;
default:
- if( !(skill->db[i].inf2&(INF2_NPC_SKILL|INF2_GUILD_SKILL)) )
- if ( ( sd->status.skill[i].lv = skill->db[i].max ) )//Nonexistant skills should return a max of 0 anyway.
- sd->status.skill[i].id = skill->db[i].nameid;
+ if( !(skill->dbs->db[i].inf2&(INF2_NPC_SKILL|INF2_GUILD_SKILL)) )
+ if ( ( sd->status.skill[i].lv = skill->dbs->db[i].max ) )//Nonexistant skills should return a max of 0 anyway.
+ sd->status.skill[i].id = skill->dbs->db[i].nameid;
}
}
} else {
int id;
for (i = 0; i < MAX_SKILL_TREE && (id=pc->skill_tree[pc->class2idx(sd->status.class_)][i].id) > 0; i++) {
int idx = pc->skill_tree[pc->class2idx(sd->status.class_)][i].idx;
- int inf2 = skill->db[idx].inf2;
+ int inf2 = skill->dbs->db[idx].inf2;
if (
(inf2&INF2_QUEST_SKILL && !battle_config.quest_skill_learn) ||
(inf2&(INF2_WEDDING_SKILL|INF2_SPIRIT_SKILL)) ||
@@ -6530,9 +7105,9 @@ int pc_resetlvl(struct map_session_data* sd,int type)
nullpo_ret(sd);
if (type != 3) //Also reset skills
- pc->resetskill(sd, 0);
+ pc->resetskill(sd, PCRESETSKILL_NONE);
- if(type == 1){
+ if(type == 1) {
sd->status.skill_point=0;
sd->status.base_level=1;
sd->status.job_level=1;
@@ -6550,8 +7125,8 @@ int pc_resetlvl(struct map_session_data* sd,int type)
if(sd->status.class_ == JOB_NOVICE_HIGH) {
sd->status.status_point=100; // not 88 [celest]
// give platinum skills upon changing
- pc->skill(sd,142,1,0);
- pc->skill(sd,143,1,0);
+ pc->skill(sd, NV_FIRSTAID, 1, SKILL_GRANT_PERMANENT);
+ pc->skill(sd, NV_TRICKDEAD, 1, SKILL_GRANT_PERMANENT);
}
}
@@ -6597,7 +7172,7 @@ int pc_resetlvl(struct map_session_data* sd,int type)
for(i=0;i<EQI_MAX;i++) { // unequip items that can't be equipped by base 1 [Valaris]
if(sd->equip_index[i] >= 0)
if(!pc->isequip(sd,sd->equip_index[i]))
- pc->unequipitem(sd,sd->equip_index[i],2);
+ pc->unequipitem(sd, sd->equip_index[i], PCUNEQUIPITEM_FORCE);
}
if ((type == 1 || type == 2 || type == 3) && sd->status.party_id)
@@ -6675,19 +7250,17 @@ int pc_resetstate(struct map_session_data* sd)
/*==========================================
* /resetskill
- * if flag&1, perform block resync and status_calc call.
- * if flag&2, just count total amount of skill points used by player, do not really reset.
- * if flag&4, just reset the skills if the player class is a bard/dancer type (for changesex.)
+ * @param flag: @see enum pc_resetskill_flag
*------------------------------------------*/
int pc_resetskill(struct map_session_data* sd, int flag)
{
int i, inf2, skill_point=0;
nullpo_ret(sd);
- if( flag&4 && (sd->class_&MAPID_UPPERMASK) != MAPID_BARDDANCER )
+ if( flag&PCRESETSKILL_CHSEX && (sd->class_&MAPID_UPPERMASK) != MAPID_BARDDANCER )
return 0;
- if( !(flag&2) ) { //Remove stuff lost when resetting skills.
+ if( !(flag&PCRESETSKILL_RECOUNT) ) { //Remove stuff lost when resetting skills.
/**
* It has been confirmed on official server that when you reset skills with a ranked tweakwon your skills are not reset (because you have all of them anyway)
@@ -6726,17 +7299,17 @@ int pc_resetskill(struct map_session_data* sd, int flag)
for( i = 1; i < MAX_SKILL; i++ ) {
// FIXME: We're looping on i = [1..MAX_SKILL-1] (which makes sense as index for sd->status.skill[]) but then we're using the
- // same i to access skill->db[], and especially to check skill_ischangesex(). This is wrong.
+ // same i to access skill->dbs->db[], and especially to check skill_ischangesex(). This is wrong.
uint16 skill_id = 0;
int lv = sd->status.skill[i].lv;
if (lv < 1) continue;
- inf2 = skill->db[i].inf2;
+ inf2 = skill->dbs->db[i].inf2;
if( inf2&(INF2_WEDDING_SKILL|INF2_SPIRIT_SKILL) ) //Avoid reseting wedding/linker skills.
continue;
- skill_id = skill->db[i].nameid;
+ skill_id = skill->dbs->db[i].nameid;
// Don't reset trick dead if not a novice/baby
if( skill_id == NV_TRICKDEAD && (sd->class_&(MAPID_BASEMASK|JOBL_2)) != MAPID_NOVICE ) {
@@ -6752,12 +7325,12 @@ int pc_resetskill(struct map_session_data* sd, int flag)
if( sd->status.skill[i].flag == SKILL_FLAG_PERM_GRANTED )
continue;
- if( flag&4 && !skill_ischangesex(i) )
+ if( flag&PCRESETSKILL_CHSEX && !skill_ischangesex(i) )
continue;
if( inf2&INF2_QUEST_SKILL && !battle_config.quest_skill_learn ) {
//Only handle quest skills in a special way when you can't learn them manually
- if( battle_config.quest_skill_reset && !(flag&2) ) { //Wipe them
+ if( battle_config.quest_skill_reset && !(flag&PCRESETSKILL_RECOUNT) ) { //Wipe them
sd->status.skill[i].lv = 0;
sd->status.skill[i].flag = 0;
}
@@ -6768,18 +7341,18 @@ int pc_resetskill(struct map_session_data* sd, int flag)
else if( sd->status.skill[i].flag >= SKILL_FLAG_REPLACED_LV_0 )
skill_point += (sd->status.skill[i].flag - SKILL_FLAG_REPLACED_LV_0);
- if( !(flag&2) ) {// reset
+ if( !(flag&PCRESETSKILL_RECOUNT) ) {// reset
sd->status.skill[i].lv = 0;
sd->status.skill[i].flag = 0;
}
}
- if( flag&2 || !skill_point ) return skill_point;
+ if( flag&PCRESETSKILL_RECOUNT || !skill_point ) return skill_point;
sd->status.skill_point += skill_point;
- if( !(flag&2) ) {
+ if (!(flag&PCRESETSKILL_RECOUNT)) {
// Remove all SCs that can't be inactivated without a skill
if( sd->sc.data[SC_STORMKICK_READY] )
status_change_end(&sd->bl, SC_STORMKICK_READY, INVALID_TIMER);
@@ -6793,7 +7366,7 @@ int pc_resetskill(struct map_session_data* sd, int flag)
status_change_end(&sd->bl, SC_DODGE_READY, INVALID_TIMER);
}
- if( flag&1 ) {
+ if (flag&PCRESETSKILL_RESYNC) {
clif->updatestatus(sd,SP_SKILLPOINT);
clif->skillinfoblock(sd);
status_calc_pc(sd,SCO_FORCE);
@@ -6825,8 +7398,7 @@ int pc_resethate(struct map_session_data* sd)
int i;
nullpo_ret(sd);
- for (i=0; i<3; i++)
- {
+ for (i = 0; i < MAX_PC_FEELHATE; i++) {
sd->hate_mob[i] = -1;
pc_setglobalreg(sd,script->add_str(pc->sg_info[i].hate_var),0);
}
@@ -6943,8 +7515,8 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) {
nullpo_retr(0, sd);
- for(j = 0; j < 5; j++) {
- if (sd->devotion[j]){
+ for (j = 0; j < MAX_PC_DEVOTION; j++) {
+ if (sd->devotion[j]) {
struct map_session_data *devsd = map->id2sd(sd->devotion[j]);
if (devsd)
status_change_end(&devsd->bl, SC_DEVOTION, INVALID_TIMER);
@@ -7048,7 +7620,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) {
mob->unlocktarget(md,tick);
if (battle_config.mobs_level_up && md->status.hp
&& (unsigned int)md->level < pc->maxbaselv(sd)
- && !md->guardian_data && !md->special_state.ai// Guardians/summons should not level. [Skotlex]
+ && !md->guardian_data && md->special_state.ai == AI_NONE// Guardians/summons should not level. [Skotlex]
) {
// monster level up [Valaris]
clif->misceffect(&md->bl,0);
@@ -7228,7 +7800,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) {
int n = eq_n[rnd()%eq_num];
if(rnd()%10000 < per){
if(sd->status.inventory[n].equip)
- pc->unequipitem(sd,n,3);
+ pc->unequipitem(sd, n, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE);
pc->dropitem(sd,n,1);
}
}
@@ -7241,7 +7813,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) {
|| (type == 2 && sd->status.inventory[i].equip)
|| type == 3) ){
if(sd->status.inventory[i].equip)
- pc->unequipitem(sd,i,3);
+ pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE);
pc->dropitem(sd,i,1);
break;
}
@@ -7890,7 +8462,7 @@ int pc_jobchange(struct map_session_data *sd,int job, int upper)
for(i=0;i<EQI_MAX;i++) {
if(sd->equip_index[i] >= 0)
if(!pc->isequip(sd,sd->equip_index[i]))
- pc->unequipitem(sd,sd->equip_index[i],2); // unequip invalid item for class
+ pc->unequipitem(sd,sd->equip_index[i], PCUNEQUIPITEM_FORCE); // unequip invalid item for class
}
//Change look, if disguised, you need to undisguise
@@ -8085,7 +8657,7 @@ int pc_setoption(struct map_session_data *sd,int type)
if(pc->checkskill(sd, MC_PUSHCART) < 10)
status_calc_pc(sd,SCO_NONE); //Remove speed penalty.
if ( sd->equip_index[EQI_AMMO] > 0 )
- pc->unequipitem(sd, sd->equip_index[EQI_AMMO], 2);
+ pc->unequipitem(sd, sd->equip_index[EQI_AMMO], PCUNEQUIPITEM_FORCE);
}
#endif
@@ -8122,7 +8694,7 @@ int pc_setoption(struct map_session_data *sd,int type)
status_change_end(&sd->bl, (sc_type)i, INVALID_TIMER);
}
if ( sd->equip_index[EQI_AMMO] > 0 )
- pc->unequipitem(sd, sd->equip_index[EQI_AMMO], 2);
+ pc->unequipitem(sd, sd->equip_index[EQI_AMMO], PCUNEQUIPITEM_FORCE);
}
if (type&OPTION_FLYING && !(p_type&OPTION_FLYING))
@@ -8176,7 +8748,7 @@ int pc_setcart(struct map_session_data *sd,int type) {
clif->clearcart(sd->fd);
clif->updatestatus(sd, SP_CARTINFO);
if ( sd->equip_index[EQI_AMMO] > 0 )
- pc->unequipitem(sd, sd->equip_index[EQI_AMMO], 2);
+ pc->unequipitem(sd, sd->equip_index[EQI_AMMO], PCUNEQUIPITEM_FORCE);
break;
default:/* everything else is an allowed ID so we can move on */
if( !sd->sc.data[SC_PUSH_CART] ) /* first time, so fill cart data */
@@ -8952,6 +9524,9 @@ void pc_equipitem_pos(struct map_session_data *sd, struct item_data *id, int pos
/*==========================================
* Equip item on player sd at req_pos from inventory index n
+ * Return:
+ * 0 = fail
+ * 1 = success
*------------------------------------------*/
int pc_equipitem(struct map_session_data *sd,int n,int req_pos)
{
@@ -9024,7 +9599,7 @@ int pc_equipitem(struct map_session_data *sd,int n,int req_pos)
for(i=0;i<EQI_MAX;i++) {
if(pos & pc->equip_pos[i]) {
if(sd->equip_index[i] >= 0) //Slot taken, remove item from there.
- pc->unequipitem(sd,sd->equip_index[i],2);
+ pc->unequipitem(sd, sd->equip_index[i], PCUNEQUIPITEM_FORCE);
sd->equip_index[i] = n;
}
@@ -9083,7 +9658,7 @@ int pc_equipitem(struct map_session_data *sd,int n,int req_pos)
}
sd->npc_item_flag = iflag;
- return 0;
+ return 1;
}
void pc_unequipitem_pos(struct map_session_data *sd, int n, int pos)
@@ -9145,12 +9720,13 @@ void pc_unequipitem_pos(struct map_session_data *sd, int n, int pos)
/*==========================================
* Called when attemting to unequip an item from player
- * type:
- * 0 - only unequip
- * 1 - calculate status after unequipping
- * 2 - force unequip
+ * type: @see enum pc_unequipitem_flag
+ * Return:
+ * 0 = fail
+ * 1 = success
*------------------------------------------*/
-int pc_unequipitem(struct map_session_data *sd,int n,int flag) {
+int pc_unequipitem(struct map_session_data *sd,int n,int flag)
+{
int i,iflag;
bool status_cacl = false;
int pos;
@@ -9162,13 +9738,13 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag) {
}
// if player is berserk then cannot unequip
- if (!(flag & 2) && sd->sc.count && (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_NO_SWITCH_EQUIP]) )
+ if (!(flag&PCUNEQUIPITEM_FORCE) && sd->sc.count && (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_NO_SWITCH_EQUIP]) )
{
clif->unequipitemack(sd,n,0,UIA_FAIL);
return 0;
}
- if( !(flag&2) && sd->sc.count && sd->sc.data[SC_KYOUGAKU] )
+ if( !(flag&PCUNEQUIPITEM_FORCE) && sd->sc.count && sd->sc.data[SC_KYOUGAKU] )
{
clif->unequipitemack(sd,n,0,UIA_FAIL);
return 0;
@@ -9229,7 +9805,7 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag) {
}
}
- if(flag&1 || status_cacl) {
+ if(flag&PCUNEQUIPITEM_RECALC || status_cacl) {
pc->checkallowskill(sd);
status_calc_pc(sd,SCO_NONE);
}
@@ -9274,7 +9850,7 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag) {
}
sd->npc_item_flag = iflag;
- return 0;
+ return 1;
}
/*==========================================
@@ -9300,7 +9876,7 @@ int pc_checkitem(struct map_session_data *sd)
if (!itemdb_available(id)) {
ShowWarning("Removed invalid/disabled item id %d from inventory (amount=%d, char_id=%d).\n", id, sd->status.inventory[i].amount, sd->status.char_id);
- pc->delitem(sd, i, sd->status.inventory[i].amount, 0, 0, LOG_TYPE_OTHER);
+ pc->delitem(sd, i, sd->status.inventory[i].amount, 0, DELITEM_NORMAL, LOG_TYPE_OTHER);
continue;
}
@@ -9374,28 +9950,28 @@ int pc_checkitem(struct map_session_data *sd)
continue;
if( sd->status.inventory[i].equip&~pc->equippoint(sd,i) ) {
- pc->unequipitem(sd, i, 2);
+ pc->unequipitem(sd, i, PCUNEQUIPITEM_FORCE);
calc_flag = 1;
continue;
}
- if ( battle_config.unequip_restricted_equipment & 1 ) {
+ if (battle_config.unequip_restricted_equipment&1) {
int j;
- for ( j = 0; j < map->list[sd->bl.m].zone->disabled_items_count; j++ ) {
- if ( map->list[sd->bl.m].zone->disabled_items[j] == sd->status.inventory[i].nameid ) {
- pc->unequipitem( sd, i, 2 );
+ for (j = 0; j < map->list[sd->bl.m].zone->disabled_items_count; j++) {
+ if (map->list[sd->bl.m].zone->disabled_items[j] == sd->status.inventory[i].nameid) {
+ pc->unequipitem(sd, i, PCUNEQUIPITEM_FORCE);
calc_flag = 1;
}
}
}
- if ( battle_config.unequip_restricted_equipment & 2 ) {
- if ( !itemdb_isspecial( sd->status.inventory[i].card[0] ) ) {
+ if (battle_config.unequip_restricted_equipment&2) {
+ if (!itemdb_isspecial(sd->status.inventory[i].card[0])) {
int j, slot;
- for ( slot = 0; slot < MAX_SLOTS; slot++ ) {
- for ( j = 0; j < map->list[sd->bl.m].zone->disabled_items_count; j++ ) {
- if ( map->list[sd->bl.m].zone->disabled_items[j] == sd->status.inventory[i].card[slot] ) {
- pc->unequipitem( sd, i, 2 );
+ for (slot = 0; slot < MAX_SLOTS; slot++) {
+ for (j = 0; j < map->list[sd->bl.m].zone->disabled_items_count; j++) {
+ if (map->list[sd->bl.m].zone->disabled_items[j] == sd->status.inventory[i].card[slot]) {
+ pc->unequipitem(sd, i, PCUNEQUIPITEM_FORCE);
calc_flag = 1;
}
}
@@ -9531,9 +10107,9 @@ int pc_divorce(struct map_session_data *sd)
for( i = 0; i < MAX_INVENTORY; i++ )
{
if( sd->status.inventory[i].nameid == WEDDING_RING_M || sd->status.inventory[i].nameid == WEDDING_RING_F )
- pc->delitem(sd, i, 1, 0, 0, LOG_TYPE_OTHER);
+ pc->delitem(sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_OTHER);
if( p_sd->status.inventory[i].nameid == WEDDING_RING_M || p_sd->status.inventory[i].nameid == WEDDING_RING_F )
- pc->delitem(p_sd, i, 1, 0, 0, LOG_TYPE_OTHER);
+ pc->delitem(p_sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_OTHER);
}
clif->divorced(sd, p_sd->status.name);
@@ -10035,151 +10611,27 @@ void pc_read_skill_tree(void) {
#else
const char *config_filename = "db/pre-re/skill_tree.conf"; // FIXME hardcoded name
#endif
- int i = 0, jnamelen = 0;
+ int i = 0;
struct s_mapiterator *iter;
struct map_session_data *sd;
- struct {
- const char *name;
- int id;
- } jnames[] = {
- { "Novice", JOB_NOVICE },
- { "Swordsman", JOB_SWORDMAN },
- { "Magician", JOB_MAGE },
- { "Archer", JOB_ARCHER },
- { "Acolyte", JOB_ACOLYTE },
- { "Merchant", JOB_MERCHANT },
- { "Thief", JOB_THIEF },
- { "Knight", JOB_KNIGHT },
- { "Priest", JOB_PRIEST },
- { "Wizard", JOB_WIZARD },
- { "Blacksmith", JOB_BLACKSMITH },
- { "Hunter", JOB_HUNTER },
- { "Assassin", JOB_ASSASSIN },
- { "Crusader", JOB_CRUSADER },
- { "Monk", JOB_MONK },
- { "Sage", JOB_SAGE },
- { "Rogue", JOB_ROGUE },
- { "Alchemist", JOB_ALCHEMIST },
- { "Bard", JOB_BARD },
- { "Dancer", JOB_DANCER },
- { "Super_Novice", JOB_SUPER_NOVICE },
- { "Gunslinger", JOB_GUNSLINGER },
- { "Ninja", JOB_NINJA },
- { "Novice_High", JOB_NOVICE_HIGH },
- { "Swordsman_High", JOB_SWORDMAN_HIGH },
- { "Magician_High", JOB_MAGE_HIGH },
- { "Archer_High", JOB_ARCHER_HIGH },
- { "Acolyte_High", JOB_ACOLYTE_HIGH },
- { "Merchant_High", JOB_MERCHANT_HIGH },
- { "Thief_High", JOB_THIEF_HIGH },
- { "Lord_Knight", JOB_LORD_KNIGHT },
- { "High_Priest", JOB_HIGH_PRIEST },
- { "High_Wizard", JOB_HIGH_WIZARD },
- { "Whitesmith", JOB_WHITESMITH },
- { "Sniper", JOB_SNIPER },
- { "Assassin_Cross", JOB_ASSASSIN_CROSS },
- { "Paladin", JOB_PALADIN },
- { "Champion", JOB_CHAMPION },
- { "Professor", JOB_PROFESSOR },
- { "Stalker", JOB_STALKER },
- { "Creator", JOB_CREATOR },
- { "Clown", JOB_CLOWN },
- { "Gypsy", JOB_GYPSY },
- { "Baby_Novice", JOB_BABY },
- { "Baby_Swordsman", JOB_BABY_SWORDMAN },
- { "Baby_Magician", JOB_BABY_MAGE },
- { "Baby_Archer", JOB_BABY_ARCHER },
- { "Baby_Acolyte", JOB_BABY_ACOLYTE },
- { "Baby_Merchant", JOB_BABY_MERCHANT },
- { "Baby_Thief", JOB_BABY_THIEF },
- { "Baby_Knight", JOB_BABY_KNIGHT },
- { "Baby_Priest", JOB_BABY_PRIEST },
- { "Baby_Wizard", JOB_BABY_WIZARD },
- { "Baby_Blacksmith", JOB_BABY_BLACKSMITH },
- { "Baby_Hunter", JOB_BABY_HUNTER },
- { "Baby_Assassin", JOB_BABY_ASSASSIN },
- { "Baby_Crusader", JOB_BABY_CRUSADER },
- { "Baby_Monk", JOB_BABY_MONK },
- { "Baby_Sage", JOB_BABY_SAGE },
- { "Baby_Rogue", JOB_BABY_ROGUE },
- { "Baby_Alchemist", JOB_BABY_ALCHEMIST },
- { "Baby_Bard", JOB_BABY_BARD },
- { "Baby_Dancer", JOB_BABY_DANCER },
- { "Super_Baby", JOB_SUPER_BABY },
- { "Taekwon", JOB_TAEKWON },
- { "Star_Gladiator", JOB_STAR_GLADIATOR },
- { "Soul_Linker", JOB_SOUL_LINKER },
- { "Gangsi", JOB_GANGSI },
- { "Death_Knight", JOB_DEATH_KNIGHT },
- { "Dark_Collector", JOB_DARK_COLLECTOR },
- { "Rune_Knight", JOB_RUNE_KNIGHT },
- { "Warlock", JOB_WARLOCK },
- { "Ranger", JOB_RANGER },
- { "Arch_Bishop", JOB_ARCH_BISHOP },
- { "Mechanic", JOB_MECHANIC },
- { "Guillotine_Cross", JOB_GUILLOTINE_CROSS },
- { "Rune_Knight_Trans", JOB_RUNE_KNIGHT_T },
- { "Warlock_Trans", JOB_WARLOCK_T },
- { "Ranger_Trans", JOB_RANGER_T },
- { "Arch_Bishop_Trans", JOB_ARCH_BISHOP_T },
- { "Mechanic_Trans", JOB_MECHANIC_T },
- { "Guillotine_Cross_Trans", JOB_GUILLOTINE_CROSS_T },
- { "Royal_Guard", JOB_ROYAL_GUARD },
- { "Sorcerer", JOB_SORCERER },
- { "Minstrel", JOB_MINSTREL },
- { "Wanderer", JOB_WANDERER },
- { "Sura", JOB_SURA },
- { "Genetic", JOB_GENETIC },
- { "Shadow_Chaser", JOB_SHADOW_CHASER },
- { "Royal_Guard_Trans", JOB_ROYAL_GUARD_T },
- { "Sorcerer_Trans", JOB_SORCERER_T },
- { "Minstrel_Trans", JOB_MINSTREL_T },
- { "Wanderer_Trans", JOB_WANDERER_T },
- { "Sura_Trans", JOB_SURA_T },
- { "Genetic_Trans", JOB_GENETIC_T },
- { "Shadow_Chaser_Trans", JOB_SHADOW_CHASER_T },
- { "Baby_Rune_Knight", JOB_BABY_RUNE },
- { "Baby_Warlock", JOB_BABY_WARLOCK },
- { "Baby_Ranger", JOB_BABY_RANGER },
- { "Baby_Arch_Bishop", JOB_BABY_BISHOP },
- { "Baby_Mechanic", JOB_BABY_MECHANIC },
- { "Baby_Guillotine_Cross", JOB_BABY_CROSS },
- { "Baby_Royal_Guard", JOB_BABY_GUARD },
- { "Baby_Sorcerer", JOB_BABY_SORCERER },
- { "Baby_Minstrel", JOB_BABY_MINSTREL },
- { "Baby_Wanderer", JOB_BABY_WANDERER },
- { "Baby_Sura", JOB_BABY_SURA },
- { "Baby_Genetic", JOB_BABY_GENETIC },
- { "Baby_Shadow_Chaser", JOB_BABY_CHASER },
- { "Expanded_Super_Novice", JOB_SUPER_NOVICE_E },
- { "Expanded_Super_Baby", JOB_SUPER_BABY_E },
- { "Kagerou", JOB_KAGEROU },
- { "Oboro", JOB_OBORO },
- { "Rebellion", JOB_REBELLION },
- };
if (libconfig->read_file(&skill_tree_conf, config_filename)) {
ShowError("can't read %s\n", config_filename);
return;
}
-
- jnamelen = ARRAYLENGTH(jnames);
-
+
while ((skt = libconfig->setting_get_elem(skill_tree_conf.root,i++))) {
int k;
const char *name = config_setting_name(skt);
- ARR_FIND(0, jnamelen, k, strcmpi(jnames[k].name,name) == 0 );
-
- if( k == jnamelen ) {
- ShowWarning("pc_read_skill_tree: '%s' unknown job name!\n",name);
+ if ( (k = pc->check_job_name(name)) == -1 ) {
+ ShowWarning("pc_read_skill_tree: '%s' unknown job name!\n", name);
continue;
}
-
-
+
if( ( skills = libconfig->setting_get_member(skt,"skills") ) ) {
int c = 0;
- int idx = pc->class2idx(jnames[k].id);
+ int idx = pc->class2idx(k);
while ((sk = libconfig->setting_get_elem(skills,c++))) {
const char *sk_name = config_setting_name(sk);
@@ -10193,7 +10645,7 @@ void pc_read_skill_tree(void) {
ShowWarning("pc_read_skill_tree: Unable to load skill %d (%s) into '%s's tree. Maximum number of skills per class has been reached.\n", skill_id, sk_name, name);
continue;
} else if (pc->skill_tree[idx][skidx].id) {
- ShowNotice("pc_read_skill_tree: Overwriting %d for '%s' (%d)\n", skill_id, name, jnames[k].id);
+ ShowNotice("pc_read_skill_tree: Overwriting %d for '%s' (%d)\n", skill_id, name, k);
}
pc->skill_tree[idx][skidx].id = skill_id;
@@ -10237,46 +10689,42 @@ void pc_read_skill_tree(void) {
while( (skt = libconfig->setting_get_elem(skill_tree_conf.root,i++)) ) {
int k, idx;
const char *name = config_setting_name(skt);
-
- ARR_FIND(0, jnamelen, k, strcmpi(jnames[k].name,name) == 0 );
-
- if( k == jnamelen ) {
- ShowWarning("pc_read_skill_tree: '%s' unknown job name!\n",name);
+ if ( (k = pc->check_job_name(name)) == -1 ) {
+ ShowWarning("pc_read_skill_tree: '%s' unknown job name!\n", name);
continue;
}
- idx = pc->class2idx(jnames[k].id);
+
+ idx = pc->class2idx(k);
if( ( inherit = libconfig->setting_get_member(skt,"inherit") ) ) {
const char *iname;
int v = 0;
- while ((iname = libconfig->setting_get_string_elem(inherit, v++))) {
+ while ( (iname = libconfig->setting_get_string_elem(inherit, v++)) ) {
int b = 0, a, d, f, fidx;
- ARR_FIND(0, jnamelen, b, strcmpi(jnames[b].name,iname) == 0 );
-
- if( b == jnamelen ) {
- ShowWarning("pc_read_skill_tree: '%s' trying to inherit unknown '%s'!\n",name,iname);
+ if ( (b = pc->check_job_name(iname)) == -1 ) {
+ ShowWarning("pc_read_skill_tree: '%s' trying to inherit unknown '%s'!\n", name, iname);
continue;
}
-
- fidx = pc->class2idx(jnames[b].id);
-
- ARR_FIND( 0, MAX_SKILL_TREE, d, pc->skill_tree[fidx][d].id == 0 );
- for( f = 0; f < d; f++ ) {
-
- ARR_FIND( 0, MAX_SKILL_TREE, a, pc->skill_tree[idx][a].id == 0 || pc->skill_tree[idx][a].id == pc->skill_tree[fidx][f].id );
+ fidx = pc->class2idx(b);
+
+ ARR_FIND(0, MAX_SKILL_TREE, d, pc->skill_tree[fidx][d].id == 0);
+
+ for ( f = 0; f < d; f++ ) {
+
+ ARR_FIND(0, MAX_SKILL_TREE, a, pc->skill_tree[idx][a].id == 0 || pc->skill_tree[idx][a].id == pc->skill_tree[fidx][f].id);
- if( a == MAX_SKILL_TREE ) {
- ShowWarning("pc_read_skill_tree: '%s' can't inherit '%s', skill tree is full!\n", name,iname);
+ if ( a == MAX_SKILL_TREE ) {
+ ShowWarning("pc_read_skill_tree: '%s' can't inherit '%s', skill tree is full!\n", name, iname);
break;
- } else if ( pc->skill_tree[idx][a].id || ( pc->skill_tree[idx][a].id == NV_TRICKDEAD && ((pc->jobid2mapid(jnames[k].id)&(MAPID_BASEMASK|JOBL_2))!=MAPID_NOVICE) ) ) /* we skip trickdead for non-novices */
+ } else if ( pc->skill_tree[idx][a].id || (pc->skill_tree[idx][a].id == NV_TRICKDEAD && ((pc->jobid2mapid(k)&(MAPID_BASEMASK | JOBL_2)) != MAPID_NOVICE)) ) /* we skip trickdead for non-novices */
continue;/* skip */
memcpy(&pc->skill_tree[idx][a], &pc->skill_tree[fidx][f], sizeof(pc->skill_tree[fidx][f]));
pc->skill_tree[idx][a].inherited = 1;
}
-
+
}
}
@@ -10427,8 +10875,8 @@ int pc_readdb(void) {
// Reset then read attr_fix
for(i=0;i<4;i++)
- for(j=0;j<ELE_MAX;j++)
- for(k=0;k<ELE_MAX;k++)
+ for ( j = ELE_NEUTRAL; j<ELE_MAX; j++ )
+ for ( k = ELE_NEUTRAL; k<ELE_MAX; k++ )
battle->attr_fix_table[i][j][k]=100;
sprintf(line, "%s/"DBPATH"attr_fix.txt", map->db_path);
@@ -10455,13 +10903,13 @@ int pc_readdb(void) {
lv=atoi(split[0]);
n=atoi(split[1]);
count++;
- for(i=0;i<n && i<ELE_MAX;){
+ for ( i = ELE_NEUTRAL; i<n && i<ELE_MAX; ) {
if( !fgets(line, sizeof(line), fp) )
break;
if(line[0]=='/' && line[1]=='/')
continue;
- for(j=0,p=line;j<n && j<ELE_MAX && p;j++){
+ for ( j = ELE_NEUTRAL, p = line; j<n && j<ELE_MAX && p; j++ ) {
while(*p==32 && *p>0)
p++;
battle->attr_fix_table[lv-1][i][j]=atoi(p);
@@ -10589,15 +11037,15 @@ void pc_bank_deposit(struct map_session_data *sd, int money) {
void pc_bank_withdraw(struct map_session_data *sd, int money) {
unsigned int limit_check = money+sd->status.zeny;
- if( money <= 0 ) {
+ if (money <= 0) {
clif->bank_withdraw(sd,BWA_UNKNOWN_ERROR);
return;
- } else if ( money > sd->status.bank_vault ) {
+ } else if (money > sd->status.bank_vault) {
clif->bank_withdraw(sd,BWA_NO_MONEY);
return;
- } else if ( limit_check > MAX_ZENY ) {
+ } else if (limit_check > MAX_ZENY) {
/* no official response for this scenario exists. */
- clif->colormes(sd->fd,COLOR_RED,msg_sd(sd,1482));
+ clif->messagecolor_self(sd->fd, COLOR_RED, msg_sd(sd,1482));
return;
}
@@ -10997,16 +11445,10 @@ void pc_defaults(void) {
/* */
pc->day_timer_tid = INVALID_TIMER;
pc->night_timer_tid = INVALID_TIMER;
- /* respecting order */
- memset(pc->exp_table, 0, sizeof(pc->exp_table)
- + sizeof(pc->max_level)
- + sizeof(pc->statp)
- + sizeof(pc->level_penalty)
- + sizeof(pc->skill_tree)
- + sizeof(pc->smith_fame_list)
- + sizeof(pc->chemist_fame_list)
- + sizeof(pc->taekwon_fame_list)
- );
+
+ // These macros are used instead of a sum of sizeof(), to ensure that padding won't interfere with our size, and code won't rot when adding more fields
+ memset(ZEROED_BLOCK_POS(pc), 0, ZEROED_BLOCK_SIZE(pc));
+
/* */
memcpy(pc->equip_pos, &equip_pos, sizeof(pc->equip_pos));
/* */
@@ -11096,7 +11538,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;
@@ -11203,6 +11647,7 @@ void pc_defaults(void) {
pc->addfame = pc_addfame;
pc->famerank = pc_famerank;
pc->set_hate_mob = pc_set_hate_mob;
+ pc->getmaxspiritball = pc_getmaxspiritball;
pc->readdb = pc_readdb;
pc->map_day_timer = map_day_timer; // by [yor]
@@ -11281,4 +11726,6 @@ void pc_defaults(void) {
pc->autotrade_start = pc_autotrade_start;
pc->autotrade_prepare = pc_autotrade_prepare;
pc->autotrade_populate = pc_autotrade_populate;
+
+ pc->check_job_name = pc_check_job_name;
}
diff --git a/src/map/pc.h b/src/map/pc.h
index 56380447e..f546d4910 100644
--- a/src/map/pc.h
+++ b/src/map/pc.h
@@ -5,23 +5,23 @@
#ifndef MAP_PC_H
#define MAP_PC_H
-#include "../config/core.h" // AUTOLOOTITEM_SIZE, RENEWAL, SECURE_NPCTIMEOUT
-
-#include "battle.h" // battle
-#include "battleground.h" // enum bg_queue_types
-#include "buyingstore.h" // struct s_buyingstore
-#include "itemdb.h" // MAX_ITEMDELAYS
-#include "log.h" // struct e_log_pick_type
-#include "map.h" // RC_MAX, ELE_MAX
-#include "pc_groups.h" // GroupSettings
-#include "script.h" // struct reg_db
-#include "searchstore.h" // struct s_search_store_info
-#include "status.h" // enum sc_type, OPTION_*
-#include "unit.h" // struct unit_data, struct view_data
-#include "vending.h" // struct s_vending
-#include "../common/cbasetypes.h"
-#include "../common/ers.h" // struct eri
-#include "../common/mmo.h" // JOB_*, MAX_FAME_LIST, struct fame_list, struct mmo_charstatus, NEW_CARTS
+#include "config/core.h" // AUTOLOOTITEM_SIZE, RENEWAL, SECURE_NPCTIMEOUT
+
+#include "map/battle.h" // battle
+#include "map/battleground.h" // enum bg_queue_types
+#include "map/buyingstore.h" // struct s_buyingstore
+#include "map/itemdb.h" // MAX_ITEMDELAYS
+#include "map/log.h" // struct e_log_pick_type
+#include "map/map.h" // RC_MAX, ELE_MAX
+#include "map/pc_groups.h" // GroupSettings
+#include "map/script.h" // struct reg_db
+#include "map/searchstore.h" // struct s_search_store_info
+#include "map/status.h" // enum sc_type, OPTION_*
+#include "map/unit.h" // struct unit_data, struct view_data
+#include "map/vending.h" // struct s_vending
+#include "common/cbasetypes.h"
+#include "common/ers.h" // struct eri
+#include "common/mmo.h" // JOB_*, MAX_FAME_LIST, struct fame_list, struct mmo_charstatus, NEW_CARTS
/**
* Defines
@@ -29,7 +29,8 @@
#define MAX_PC_BONUS 10
#define MAX_PC_SKILL_REQUIRE 5
#define MAX_PC_FEELHATE 3
-#define PVP_CALCRANK_INTERVAL 1000 // PVP calculation interval
+#define MAX_PC_DEVOTION 5 ///< Max amount of devotion targets
+#define PVP_CALCRANK_INTERVAL 1000 ///< PVP calculation interval
//Equip indexes constants. (eg: sd->equip_index[EQI_AMMO] returns the index
//where the arrows are equipped)
@@ -57,11 +58,23 @@ enum equip_index {
EQI_SHADOW_ACC_L,
EQI_MAX
};
+
+enum pc_unequipitem_flag {
+ PCUNEQUIPITEM_NONE = 0x0, ///< Just unequip
+ PCUNEQUIPITEM_RECALC = 0x1, ///< Recalculate status after unequipping
+ PCUNEQUIPITEM_FORCE = 0x2, ///< Force unequip
+};
+
+enum pc_resetskill_flag {
+ PCRESETSKILL_NONE = 0x0,
+ PCRESETSKILL_RESYNC = 0x1, // perform block resync and status_calc call
+ PCRESETSKILL_RECOUNT = 0x2, // just count total amount of skill points used by player, do not really reset
+ PCRESETSKILL_CHSEX = 0x4, // just reset the skills if the player class is a bard/dancer type (for changesex.)
+};
+
struct weapon_data {
int atkmods[3];
- // all the variables except atkmods get zero'ed in each call of status_calc_pc
- // NOTE: if you want to add a non-zeroed variable, you need to update the memset call
- // in status_calc_pc as well! All the following are automatically zero'ed. [Skotlex]
+BEGIN_ZEROED_BLOCK; // all the variables within this block get zero'ed in each call of status_calc_pc
int overrefine;
int star;
int ignore_def_ele;
@@ -85,15 +98,20 @@ struct weapon_data {
short flag, rate;
unsigned char ele;
} addele2[MAX_PC_BONUS];
+END_ZEROED_BLOCK;
};
struct s_autospell {
short id, lv, rate, card_id, flag;
bool lock; // bAutoSpellOnSkill: blocks autospell from triggering again, while being executed
};
+/// AddEff bonus data
struct s_addeffect {
- enum sc_type id;
- short rate, arrow_rate;
- unsigned char flag;
+ enum sc_type id; ///< Effect ID
+ int16 rate; ///< Base success rate
+ int16 arrow_rate; ///< Success rate modifier for ranged attacks (adds to the base rate)
+ uint8 flag; ///< Trigger flag (@see enum auto_trigger_flag)
+ uint16 duration; ///< Optional, non-reducible duration in ms. If 0, the default, reducible effect's duration is used.
+ // TODO[Haru]: Duration is only used in addeff (set through bonus4 bAddEff). The other addeffect types could also use it.
};
struct s_addeffectonskill {
enum sc_type id;
@@ -141,7 +159,7 @@ struct map_session_data {
unsigned int arrow_atk : 1;
unsigned int gangsterparadise : 1;
unsigned int rest : 1;
- unsigned int storage_flag : 2; //0: closed, 1: Normal Storage open, 2: guild storage open [Skotlex]
+ unsigned int storage_flag : 2; // @see enum storage_flag
unsigned int snovice_dead_flag : 1; //Explosion spirits on death: 0 off, 1 used.
unsigned int abra_flag : 2; // Abracadabra bugfix by Aru
unsigned int autocast : 1; // Autospell flag [Inkfish]
@@ -188,6 +206,7 @@ struct map_session_data {
unsigned int itemcheck : 1;
unsigned int standalone : 1;/* [Ind/Hercules <3] */
unsigned int loggingout : 1;
+ unsigned int warp_clean : 1;
} state;
struct {
unsigned char no_weapon_damage, no_magic_damage, no_misc_damage;
@@ -260,7 +279,8 @@ struct map_session_data {
short weapontype1,weapontype2;
short disguise; // [Valaris]
struct weapon_data right_weapon, left_weapon;
- // here start arrays to be globally zeroed at the beginning of status_calc_pc()
+
+BEGIN_ZEROED_BLOCK; // this block will be globally zeroed at the beginning of status_calc_pc()
int param_bonus[6],param_equip[6]; //Stores card/equipment bonuses.
int subele[ELE_MAX];
int subrace[RC_MAX];
@@ -285,8 +305,9 @@ struct map_session_data {
short sp_gain_race[RC_MAX];
short sp_gain_race_attack[RC_MAX];
short hp_gain_race_attack[RC_MAX];
- // zeroed arrays end here.
- // zeroed structures start here
+#ifdef RENEWAL
+ int race_tolerance[RC_MAX];
+#endif
struct s_autospell autospell[15], autospell2[15], autospell3[15];
struct s_addeffect addeff[MAX_PC_BONUS], addeff2[MAX_PC_BONUS];
struct s_addeffectonskill addeff3[MAX_PC_BONUS];
@@ -315,11 +336,6 @@ struct map_session_data {
short value;
int rate, tick;
} def_set_race[RC_MAX], mdef_set_race[RC_MAX];
- // zeroed structures end here
- // manually zeroed structures start here.
- struct s_autobonus autobonus[MAX_PC_BONUS], autobonus2[MAX_PC_BONUS], autobonus3[MAX_PC_BONUS]; //Auto script on attack, when attacked, on skill usage
- // manually zeroed structures end here.
- // zeroed vars start here.
struct {
int atk_rate;
int arrow_atk,arrow_ele,arrow_cri,arrow_hit;
@@ -356,7 +372,11 @@ struct map_session_data {
int add_fixcast,add_varcast;
int ematk; // matk bonus from equipment
} bonus;
- // zeroed vars end here.
+END_ZEROED_BLOCK;
+
+ // The following structures are zeroed manually in status_calc_pc_
+ struct s_autobonus autobonus[MAX_PC_BONUS], autobonus2[MAX_PC_BONUS], autobonus3[MAX_PC_BONUS]; //Auto script on attack, when attacked, on skill usage
+
int castrate,delayrate,hprate,sprate,dsprate;
int hprecov_rate,sprecov_rate;
int matk_rate;
@@ -373,7 +393,7 @@ struct map_session_data {
unsigned char mission_count; //Stores the bounty kill count for TK_MISSION
short mission_mobid; //Stores the target mob_id for TK_MISSION
int die_counter; //Total number of times you've died
- int devotion[5]; //Stores the account IDs of chars devoted to.
+ int devotion[MAX_PC_DEVOTION]; //Stores the account IDs of chars devoted to.
int trade_partner;
struct {
struct {
@@ -405,11 +425,11 @@ struct map_session_data {
struct mercenary_data *md;
struct elemental_data *ed;
- struct{
+ struct {
int m; //-1 - none, other: map index corresponding to map name.
unsigned short index; //map index
- } feel_map[3];// 0 - Sun; 1 - Moon; 2 - Stars
- short hate_mob[3];
+ } feel_map[MAX_PC_FEELHATE];// 0 - Sun; 1 - Moon; 2 - Stars
+ short hate_mob[MAX_PC_FEELHATE];
int pvp_timer;
short pvp_point;
@@ -723,6 +743,16 @@ enum e_pc_autotrade_update_action {
};
/**
+ * Flag values for pc->skill
+ */
+enum pc_skill_flag {
+ SKILL_GRANT_PERMANENT = 0, // Grant permanent skill to be bound to skill tree
+ SKILL_GRANT_TEMPORARY = 1, // Grant an item skill (temporary)
+ SKILL_GRANT_TEMPSTACK = 2, // Like 1, except the level granted can stack with previously learned level.
+ SKILL_GRANT_UNCONDITIONAL = 3, // Grant skill unconditionally and forever (persistent to job changes and skill resets)
+};
+
+/**
* Used to temporarily remember vending data
**/
struct autotrade_vending {
@@ -746,17 +776,20 @@ struct pc_interface {
int day_timer_tid;
int night_timer_tid;
/* */
+
+BEGIN_ZEROED_BLOCK; /* Everything within this block will be memset to 0 when status_defaults() is executed */
unsigned int exp_table[CLASS_COUNT][2][MAX_LEVEL];
unsigned int max_level[CLASS_COUNT][2];
unsigned int statp[MAX_LEVEL+1];
unsigned int level_penalty[3][RC_MAX][MAX_LEVEL*2+1];
-
- unsigned int equip_pos[EQI_MAX];
/* */
struct skill_tree_entry skill_tree[CLASS_COUNT][MAX_SKILL_TREE];
struct fame_list smith_fame_list[MAX_FAME_LIST];
struct fame_list chemist_fame_list[MAX_FAME_LIST];
struct fame_list taekwon_fame_list[MAX_FAME_LIST];
+END_ZEROED_BLOCK; /* End */
+
+ unsigned int equip_pos[EQI_MAX];
struct sg_data sg_info[MAX_PC_FEELHATE];
/* */
struct eri *sc_display_ers;
@@ -848,6 +881,8 @@ struct pc_interface {
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);
@@ -950,6 +985,7 @@ struct pc_interface {
int (*addspiritball) (struct map_session_data *sd,int interval,int max);
int (*delspiritball) (struct map_session_data *sd,int count,int type);
+ int (*getmaxspiritball) (struct map_session_data *sd, int min);
void (*addfame) (struct map_session_data *sd,int count);
unsigned char (*famerank) (int char_id, int job);
int (*set_hate_mob) (struct map_session_data *sd, int pos, struct block_list *bl);
@@ -987,7 +1023,7 @@ struct pc_interface {
void (*check_skilltree) (struct map_session_data *sd, int skill_id);
int (*bonus_autospell) (struct s_autospell *spell, int max, short id, short lv, short rate, short flag, short card_id);
int (*bonus_autospell_onskill) (struct s_autospell *spell, int max, short src_skill, short id, short lv, short rate, short card_id);
- int (*bonus_addeff) (struct s_addeffect* effect, int max, enum sc_type id, short rate, short arrow_rate, unsigned char flag);
+ int (*bonus_addeff) (struct s_addeffect* effect, int max, enum sc_type id, int16 rate, int16 arrow_rate, uint8 flag, uint16 duration);
int (*bonus_addeff_onskill) (struct s_addeffectonskill* effect, int max, enum sc_type id, short rate, short skill_id, unsigned char target);
int (*bonus_item_drop) (struct s_add_drop *drop, const short max, short id, short group, int race, int rate);
void (*calcexp) (struct map_session_data *sd, unsigned int *base_exp, unsigned int *job_exp, struct block_list *src);
@@ -1032,6 +1068,8 @@ struct pc_interface {
void (*autotrade_start) (struct map_session_data *sd);
void (*autotrade_prepare) (struct map_session_data *sd);
void (*autotrade_populate) (struct map_session_data *sd);
+
+ int (*check_job_name) (const char *name);
};
struct pc_interface *pc;
diff --git a/src/map/pc_groups.c b/src/map/pc_groups.c
index 9cd478b3f..f9a442d97 100644
--- a/src/map/pc_groups.c
+++ b/src/map/pc_groups.c
@@ -6,17 +6,17 @@
#include "pc_groups.h"
-#include "atcommand.h" // atcommand->exists(), atcommand->load_groups()
-#include "clif.h" // clif->GM_kick()
-#include "map.h" // mapiterator
-#include "pc.h" // pc->set_group()
-#include "../common/cbasetypes.h"
-#include "../common/conf.h"
-#include "../common/db.h"
-#include "../common/malloc.h"
-#include "../common/nullpo.h"
-#include "../common/showmsg.h"
-#include "../common/strlib.h" // strcmp
+#include "map/atcommand.h" // atcommand-"exists(), atcommand-"load_groups()
+#include "map/clif.h" // clif-"GM_kick()
+#include "map/map.h" // mapiterator
+#include "map/pc.h" // pc-"set_group()
+#include "common/cbasetypes.h"
+#include "common/conf.h"
+#include "common/db.h"
+#include "common/malloc.h"
+#include "common/nullpo.h"
+#include "common/showmsg.h"
+#include "common/strlib.h" // strcmp
static GroupSettings dummy_group; ///< dummy group used in dummy map sessions @see pc_get_dummy_sd()
diff --git a/src/map/pc_groups.h b/src/map/pc_groups.h
index 8dd95a177..4fee312a4 100644
--- a/src/map/pc_groups.h
+++ b/src/map/pc_groups.h
@@ -5,9 +5,9 @@
#ifndef MAP_PC_GROUPS_H
#define MAP_PC_GROUPS_H
-#include "../common/cbasetypes.h"
-#include "../common/conf.h"
-#include "../common/db.h"
+#include "common/cbasetypes.h"
+#include "common/conf.h"
+#include "common/db.h"
/// PC permissions
enum e_pc_permission {
diff --git a/src/map/pet.c b/src/map/pet.c
index b37d3c350..2379ec984 100644
--- a/src/map/pet.c
+++ b/src/map/pet.c
@@ -6,36 +6,36 @@
#include "pet.h"
+#include "map/atcommand.h" // msg_txt()
+#include "map/battle.h"
+#include "map/chrif.h"
+#include "map/clif.h"
+#include "map/intif.h"
+#include "map/itemdb.h"
+#include "map/log.h"
+#include "map/map.h"
+#include "map/mob.h"
+#include "map/npc.h"
+#include "map/path.h"
+#include "map/pc.h"
+#include "map/script.h"
+#include "map/skill.h"
+#include "map/status.h"
+#include "map/unit.h"
+#include "common/db.h"
+#include "common/ers.h"
+#include "common/malloc.h"
+#include "common/nullpo.h"
+#include "common/random.h"
+#include "common/showmsg.h"
+#include "common/strlib.h"
+#include "common/timer.h"
+#include "common/utils.h"
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include "atcommand.h" // msg_txt()
-#include "battle.h"
-#include "chrif.h"
-#include "clif.h"
-#include "intif.h"
-#include "itemdb.h"
-#include "log.h"
-#include "map.h"
-#include "mob.h"
-#include "npc.h"
-#include "path.h"
-#include "pc.h"
-#include "script.h"
-#include "skill.h"
-#include "status.h"
-#include "unit.h"
-#include "../common/db.h"
-#include "../common/ers.h"
-#include "../common/malloc.h"
-#include "../common/nullpo.h"
-#include "../common/random.h"
-#include "../common/showmsg.h"
-#include "../common/strlib.h"
-#include "../common/timer.h"
-#include "../common/utils.h"
-
struct pet_interface pet_s;
#define MIN_PETTHINKTIME 100
@@ -91,7 +91,7 @@ int pet_unlocktarget(struct pet_data *pd)
pd->target_id=0;
pet_stop_attack(pd);
- pet_stop_walking(pd,1);
+ pet_stop_walking(pd, STOPWALKING_FLAG_FIXPOS);
return 0;
}
@@ -132,7 +132,7 @@ int pet_target_check(struct map_session_data *sd,struct block_list *bl,int type)
pd = sd->pd;
- Assert((pd->msd == 0) || (pd->msd->pd == pd));
+ Assert_ret(pd->msd == 0 || pd->msd->pd == pd);
if( bl == NULL || bl->type != BL_MOB || bl->prev == NULL
|| pd->pet.intimate < battle_config.pet_support_min_friendly
@@ -280,7 +280,7 @@ int pet_performance(struct map_session_data *sd, struct pet_data *pd)
else
val = 1;
- pet_stop_walking(pd,2000<<8);
+ pet_stop_walking(pd,STOPWALKING_FLAG_NONE | (2000<<8)); // Stop walking for 2000ms
clif->send_petdata(NULL, pd, 4, rnd()%val + 1);
pet->lootitem_drop(pd,NULL);
return 1;
@@ -318,8 +318,7 @@ int pet_data_init(struct map_session_data *sd, struct s_pet *petinfo)
int i=0,interval=0;
nullpo_retr(1, sd);
-
- Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->msd == sd);
+ Assert_retr(1, sd->status.pet_id == 0 || sd->pd == 0 || sd->pd->msd == sd);
if(sd->status.account_id != petinfo->account_id || sd->status.char_id != petinfo->char_id) {
sd->status.pet_id = 0;
@@ -389,8 +388,7 @@ int pet_data_init(struct map_session_data *sd, struct s_pet *petinfo)
int pet_birth_process(struct map_session_data *sd, struct s_pet *petinfo)
{
nullpo_retr(1, sd);
-
- Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->msd == sd);
+ Assert_retr(1, sd->status.pet_id == 0 || sd->pd == 0 || sd->pd->msd == sd);
if(sd->status.pet_id && petinfo->incubate == 1) {
sd->status.pet_id = 0;
@@ -418,7 +416,7 @@ int pet_birth_process(struct map_session_data *sd, struct s_pet *petinfo)
clif->send_petdata(NULL, sd->pd, 3, sd->pd->vd.head_bottom);
clif->send_petstatus(sd);
}
- Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->msd == sd);
+ Assert_retr(1, sd->status.pet_id == 0 || sd->pd == 0 || sd->pd->msd == sd);
return 0;
}
@@ -447,7 +445,7 @@ int pet_recv_petdata(int account_id,struct s_pet *p,int flag) {
return 1;
}
if (!pet->birth_process(sd,p)) //Pet hatched. Delete egg.
- pc->delitem(sd,i,1,0,0,LOG_TYPE_OTHER);
+ pc->delitem(sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_OTHER);
} else {
pet->data_init(sd,p);
if(sd->pd && sd->bl.prev != NULL) {
@@ -680,7 +678,7 @@ int pet_equipitem(struct map_session_data *sd,int index) {
return 1;
}
- pc->delitem(sd,index,1,0,0,LOG_TYPE_OTHER);
+ pc->delitem(sd, index, 1, 0, DELITEM_NORMAL, LOG_TYPE_OTHER);
pd->pet.equip = nameid;
status->set_viewdata(&pd->bl, pd->pet.class_); //Updates view_data.
clif->send_petdata(NULL, sd->pd, 3, sd->pd->vd.head_bottom);
@@ -745,7 +743,7 @@ int pet_food(struct map_session_data *sd, struct pet_data *pd) {
clif->pet_food(sd, food_id, 0);
return 1;
}
- pc->delitem(sd,i,1,0,0,LOG_TYPE_CONSUME);
+ pc->delitem(sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_CONSUME);
if (pd->pet.hungry > 90) {
pet->set_intimate(pd, pd->pet.intimate - pd->petDB->r_full);
@@ -781,10 +779,10 @@ int pet_food(struct map_session_data *sd, struct pet_data *pd) {
return 0;
}
-int pet_randomwalk(struct pet_data *pd, int64 tick) {
+int pet_randomwalk(struct pet_data *pd, int64 tick)
+{
nullpo_ret(pd);
-
- Assert((pd->msd == 0) || (pd->msd->pd == pd));
+ Assert_ret(pd->msd == 0 || pd->msd->pd == pd);
if (DIFF_TICK(pd->next_walktime,tick) < 0 && unit->can_move(&pd->bl)) {
const int retrycount=20;
@@ -1146,7 +1144,7 @@ int pet_skill_support_timer(int tid, int64 tick, int id, intptr_t data) {
}
pet_stop_attack(pd);
- pet_stop_walking(pd,1);
+ pet_stop_walking(pd, STOPWALKING_FLAG_FIXPOS);
pd->s_skill->timer=timer->add(tick+pd->s_skill->delay*1000,pet->skill_support_timer,sd->bl.id,0);
if (skill->get_inf(pd->s_skill->id) & INF_GROUND_SKILL)
unit->skilluse_pos(&pd->bl, sd->bl.x, sd->bl.y, pd->s_skill->id, pd->s_skill->lv);
diff --git a/src/map/pet.h b/src/map/pet.h
index 0b51bcb16..06302c9b2 100644
--- a/src/map/pet.h
+++ b/src/map/pet.h
@@ -5,11 +5,11 @@
#ifndef MAP_PET_H
#define MAP_PET_H
-#include "map.h" // struct block_list
-#include "status.h" // enum sc_type
-#include "unit.h" // struct unit_data
-#include "../common/cbasetypes.h"
-#include "../common/mmo.h" // NAME_LENGTH, struct s_pet
+#include "map/map.h" // struct block_list
+#include "map/status.h" // enum sc_type
+#include "map/unit.h" // struct unit_data
+#include "common/cbasetypes.h"
+#include "common/mmo.h" // NAME_LENGTH, struct s_pet
#define MAX_PET_DB 300
#define MAX_PETLOOT_SIZE 30
diff --git a/src/map/quest.c b/src/map/quest.c
index 93ec1b04c..463a3395a 100644
--- a/src/map/quest.c
+++ b/src/map/quest.c
@@ -6,37 +6,38 @@
#include "quest.h"
+#include "map/battle.h"
+#include "map/chrif.h"
+#include "map/clif.h"
+#include "map/intif.h"
+#include "map/itemdb.h"
+#include "map/log.h"
+#include "map/map.h"
+#include "map/mob.h"
+#include "map/npc.h"
+#include "map/party.h"
+#include "map/pc.h"
+#include "map/script.h"
+#include "map/unit.h"
+#include "common/cbasetypes.h"
+#include "common/conf.h"
+#include "common/malloc.h"
+#include "common/nullpo.h"
+#include "common/random.h"
+#include "common/showmsg.h"
+#include "common/socket.h"
+#include "common/strlib.h"
+#include "common/timer.h"
+#include "common/utils.h"
+
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
-#include "battle.h"
-#include "chrif.h"
-#include "clif.h"
-#include "intif.h"
-#include "itemdb.h"
-#include "log.h"
-#include "map.h"
-#include "mob.h"
-#include "npc.h"
-#include "party.h"
-#include "pc.h"
-#include "script.h"
-#include "unit.h"
-#include "../common/cbasetypes.h"
-#include "../common/conf.h"
-#include "../common/malloc.h"
-#include "../common/nullpo.h"
-#include "../common/random.h"
-#include "../common/showmsg.h"
-#include "../common/socket.h"
-#include "../common/strlib.h"
-#include "../common/timer.h"
-#include "../common/utils.h"
-
struct quest_interface quest_s;
+struct quest_db *db_data[MAX_QUEST_DB]; ///< Quest database
/**
* Searches a quest by ID.
@@ -618,6 +619,7 @@ void do_reload_quest(void) {
*/
void quest_defaults(void) {
quest = &quest_s;
+ quest->db_data = db_data;
memset(&quest->db, 0, sizeof(quest->db));
memset(&quest->dummy, 0, sizeof(quest->dummy));
diff --git a/src/map/quest.h b/src/map/quest.h
index 36ac69a53..9b5199625 100644
--- a/src/map/quest.h
+++ b/src/map/quest.h
@@ -5,9 +5,9 @@
#ifndef MAP_QUEST_H
#define MAP_QUEST_H
-#include "map.h" // TBL_PC
-#include "../common/cbasetypes.h"
-#include "../common/conf.h"
+#include "map/map.h" // TBL_PC
+#include "common/cbasetypes.h"
+#include "common/conf.h"
#define MAX_QUEST_DB (60355+1) // Highest quest ID + 1
@@ -40,7 +40,7 @@ enum quest_check_type {
};
struct quest_interface {
- struct quest_db *db_data[MAX_QUEST_DB]; ///< Quest database
+ struct quest_db **db_data; ///< Quest database
struct quest_db dummy; ///< Dummy entry for invalid quest lookups
/* */
void (*init) (bool minimal);
diff --git a/src/map/script.c b/src/map/script.c
index d5cf58946..e7a0175c7 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -4,60 +4,59 @@
#define HERCULES_CORE
-#include "../config/core.h" // RENEWAL, RENEWAL_ASPD, RENEWAL_CAST, RENEWAL_DROP, RENEWAL_EDP, RENEWAL_EXP, RENEWAL_LVDMG, SCRIPT_CALLFUNC_CHECK, SECURE_NPCTIMEOUT, SECURE_NPCTIMEOUT_INTERVAL
+#include "config/core.h" // RENEWAL, RENEWAL_ASPD, RENEWAL_CAST, RENEWAL_DROP, RENEWAL_EDP, RENEWAL_EXP, RENEWAL_LVDMG, SCRIPT_CALLFUNC_CHECK, SECURE_NPCTIMEOUT, SECURE_NPCTIMEOUT_INTERVAL
#include "script.h"
+#include "map/atcommand.h"
+#include "map/battle.h"
+#include "map/battleground.h"
+#include "map/channel.h"
+#include "map/chat.h"
+#include "map/chrif.h"
+#include "map/clif.h"
+#include "map/elemental.h"
+#include "map/guild.h"
+#include "map/homunculus.h"
+#include "map/instance.h"
+#include "map/intif.h"
+#include "map/itemdb.h"
+#include "map/log.h"
+#include "map/mail.h"
+#include "map/map.h"
+#include "map/mapreg.h"
+#include "map/mercenary.h"
+#include "map/mob.h"
+#include "map/npc.h"
+#include "map/party.h"
+#include "map/path.h"
+#include "map/pc.h"
+#include "map/pet.h"
+#include "map/pet.h"
+#include "map/quest.h"
+#include "map/skill.h"
+#include "map/status.h"
+#include "map/status.h"
+#include "map/storage.h"
+#include "map/unit.h"
+#include "common/cbasetypes.h"
+#include "common/malloc.h"
+#include "common/md5calc.h"
+#include "common/mmo.h" // NEW_CARTS
+#include "common/nullpo.h"
+#include "common/random.h"
+#include "common/showmsg.h"
+#include "common/socket.h" // usage: getcharip
+#include "common/strlib.h"
+#include "common/sysinfo.h"
+#include "common/timer.h"
+#include "common/utils.h"
+#include "common/HPM.h"
+
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
-
-#include "atcommand.h"
-#include "battle.h"
-#include "battleground.h"
-#include "channel.h"
-#include "chat.h"
-#include "chrif.h"
-#include "clif.h"
-#include "elemental.h"
-#include "guild.h"
-#include "homunculus.h"
-#include "instance.h"
-#include "intif.h"
-#include "itemdb.h"
-#include "log.h"
-#include "mail.h"
-#include "map.h"
-#include "mapreg.h"
-#include "mercenary.h"
-#include "mob.h"
-#include "npc.h"
-#include "party.h"
-#include "path.h"
-#include "pc.h"
-#include "pet.h"
-#include "pet.h"
-#include "quest.h"
-#include "skill.h"
-#include "status.h"
-#include "status.h"
-#include "storage.h"
-#include "unit.h"
-#include "../common/cbasetypes.h"
-#include "../common/malloc.h"
-#include "../common/md5calc.h"
-#include "../common/mmo.h" // NEW_CARTS
-#include "../common/nullpo.h"
-#include "../common/random.h"
-#include "../common/showmsg.h"
-#include "../common/socket.h" // usage: getcharip
-#include "../common/strlib.h"
-#include "../common/sysinfo.h"
-#include "../common/timer.h"
-#include "../common/utils.h"
-#include "../common/HPM.h"
-
#ifndef WIN32
#include <sys/time.h>
#endif
@@ -406,7 +405,7 @@ unsigned int calc_hash_ci(const char* p) {
/// Looks up string using the provided id.
const char* script_get_str(int id)
{
- Assert( id >= LABEL_START && id < script->str_size );
+ Assert_retr(NULL, id >= LABEL_START && id < script->str_size);
return script->str_buf+script->str_data[id].str;
}
@@ -462,7 +461,7 @@ const char *script_casecheck_add_str_sub(struct casecheck_data *ccd, const char
int i;
for (i = ccd->str_hash[h]; ; i = ccd->str_data[i].next) {
const char *s = NULL;
- Assert( i >= 0 && i < ccd->str_size );
+ Assert_retb(i >= 0 && i < ccd->str_size);
s = ccd->str_buf+ccd->str_data[i].str;
if (strcasecmp(s,p) == 0) {
return s; // string already in list
@@ -1295,7 +1294,8 @@ const char* parse_simpleexpr(const char *p)
const char *line_start = start_point;
const char *line_end = start_point;
struct script_string_buf *lbuf = &script->lang_export_line_buf;
- size_t line_length;
+ struct script_string_buf *ubuf = &script->lang_export_unescaped_buf;
+ size_t line_length, cursor;
while( line_start > script->parser_current_src ) {
if( *line_start != '\n' )
@@ -1319,6 +1319,13 @@ const char* parse_simpleexpr(const char *p)
normalize_name(lbuf->ptr, "\r\n\t ");
}
+ for(cursor = 0; cursor < sbuf->pos; cursor++) {
+ if( sbuf->ptr[cursor] == '"' )
+ script_string_buf_addb(ubuf, '\\');
+ script_string_buf_addb(ubuf, sbuf->ptr[cursor]);
+ }
+ script_string_buf_addb(ubuf, 0);
+
fprintf(script->lang_export_fp, "#: %s\n"
"# %s\n"
"msgctxt \"%s\"\n"
@@ -1327,10 +1334,11 @@ const char* parse_simpleexpr(const char *p)
script->parser_current_file ? script->parser_current_file : "Unknown File",
lbuf->ptr,
script->parser_current_npc_name ? script->parser_current_npc_name : "Unknown NPC",
- sbuf->ptr
+ ubuf->ptr
);
lbuf->pos = 0;
+ ubuf->pos = 0;
}
sbuf->pos = 0;
@@ -2427,9 +2435,11 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o
script->syntax.translation_db = strdb_get(script->translation_db, script->parser_current_npc_name);
}
- script->buf=(unsigned char *)aMalloc(SCRIPT_BLOCK_SIZE*sizeof(unsigned char));
+ if( !script->buf ) {
+ script->buf = (unsigned char *)aMalloc(SCRIPT_BLOCK_SIZE*sizeof(unsigned char));
+ script->size = SCRIPT_BLOCK_SIZE;
+ }
script->pos=0;
- script->size=SCRIPT_BLOCK_SIZE;
script->parse_nextline(true, NULL);
// who called parse_script is responsible for clearing the database after using it, but just in case... lets clear it here
@@ -2443,10 +2453,7 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o
if( script->error_report )
script->error(src,file,line,script->error_msg,script->error_pos);
aFree( script->error_msg );
- aFree( script->buf );
script->pos = 0;
- script->size = 0;
- script->buf = NULL;
for(i=LABEL_START;i<script->str_num;i++)
if(script->str_data[i].type == C_NOP) script->str_data[i].type = C_NAME;
for(i=0; i<size; i++)
@@ -2468,10 +2475,7 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o
{// does not require brackets around the script
if( *p == '\0' && !(options&SCRIPT_RETURN_EMPTY_SCRIPT) )
{// empty script and can return NULL
- aFree( script->buf );
script->pos = 0;
- script->size = 0;
- script->buf = NULL;
#ifdef ENABLE_CASE_CHECK
script->local_casecheck.clear();
script->parser_current_src = NULL;
@@ -2491,10 +2495,7 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o
p = script->skip_space(p+1);
if( *p == '}' && !(options&SCRIPT_RETURN_EMPTY_SCRIPT) )
{// empty script and can return NULL
- aFree( script->buf );
script->pos = 0;
- script->size = 0;
- script->buf = NULL;
#ifdef ENABLE_CASE_CHECK
script->local_casecheck.clear();
script->parser_current_src = NULL;
@@ -2543,10 +2544,6 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o
script->addc(C_NOP);
- // trim code to size
- script->size = script->pos;
- RECREATE(script->buf,unsigned char,script->pos);
-
// default unknown references to variables
for (i = LABEL_START; i < script->str_num; i++) {
if (script->str_data[i].type == C_NOP) {
@@ -2611,8 +2608,9 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o
#endif
CREATE(code,struct script_code,1);
- code->script_buf = script->buf;
- code->script_size = script->size;
+ code->script_buf = (unsigned char *)aMalloc(script->pos*sizeof(unsigned char));
+ memcpy(code->script_buf, script->buf, script->pos);
+ code->script_size = script->pos;
code->local.vars = NULL;
code->local.arrays = NULL;
#ifdef ENABLE_CASE_CHECK
@@ -3397,15 +3395,13 @@ void script_free_code(struct script_code* code)
{
nullpo_retv(code);
- if( code->instances )
+ if (code->instances)
script->stop_instances(code);
- else {
- script->free_vars(code->local.vars);
- if( code->local.arrays )
- code->local.arrays->destroy(code->local.arrays,script->array_free_db);
- }
- aFree( code->script_buf );
- aFree( code );
+ script->free_vars(code->local.vars);
+ if (code->local.arrays)
+ code->local.arrays->destroy(code->local.arrays,script->array_free_db);
+ aFree(code->script_buf);
+ aFree(code);
}
/// Creates a new script state.
@@ -4682,6 +4678,9 @@ void script_load_translations(void) {
int i, size;
uint32 total = 0;
uint8 lang_id = 0, k;
+
+ if (map->minimal) // No translations in minimal mode
+ return;
script->translation_db = strdb_alloc(DB_OPT_DUP_KEY, NAME_LENGTH*2+1);
@@ -4815,6 +4814,7 @@ void script_load_translation(const char *file, uint8 lang_id, uint32 *total) {
continue;
if( strncasecmp(line,"msgctxt \"", 9) == 0 ) {
+ msgctxt[0] = '\0';
for(i = 9; i < len - 2; i++) {
if( line[i] == '\\' && line[i+1] == '"' ) {
msgctxt[cursor] = '"';
@@ -4826,6 +4826,7 @@ void script_load_translation(const char *file, uint8 lang_id, uint32 *total) {
}
msgctxt[cursor] = '\0';
} else if ( strncasecmp(line, "msgid \"", 7) == 0 ) {
+ msgid.pos = 0;
for(i = 7; i < len - 2; i++) {
if( line[i] == '\\' && line[i+1] == '"' ) {
script_string_buf_addb(&msgid, '"');
@@ -4835,6 +4836,7 @@ void script_load_translation(const char *file, uint8 lang_id, uint32 *total) {
}
script_string_buf_addb(&msgid,0);
} else if ( len > 9 && line[9] != '"' && strncasecmp(line, "msgstr \"",8) == 0 ) {
+ msgstr.pos = 0;
for(i = 8; i < len - 2; i++) {
if( line[i] == '\\' && line[i+1] == '"' ) {
script_string_buf_addb(&msgstr, '"');
@@ -4886,7 +4888,6 @@ void script_load_translation(const char *file, uint8 lang_id, uint32 *total) {
st->translations++;
st->len += inner_len;
}
-
msgctxt[0] = '\0';
msgid.pos = msgstr.pos = 0;
translations++;
@@ -4967,6 +4968,13 @@ int script_translation_db_destroyer(DBKey key, DBData *data, va_list ap) {
*
**/
void script_parser_clean_leftovers(void) {
+
+ if( script->buf )
+ aFree(script->buf);
+
+ script->buf = NULL;
+ script->size = 0;
+
if( script->translation_db ) {
script->translation_db->destroy(script->translation_db,script->translation_db_destroyer);
script->translation_db = NULL;
@@ -4979,6 +4987,7 @@ void script_parser_clean_leftovers(void) {
script_string_buf_destroy(&script->parse_simpleexpr_str);
script_string_buf_destroy(&script->lang_export_line_buf);
+ script_string_buf_destroy(&script->lang_export_unescaped_buf);
}
/**
@@ -5672,6 +5681,13 @@ BUILDIN(getarg)
/// return;
/// return <value>;
BUILDIN(return) {
+ st->state = RETFUNC;
+
+ if( st->stack->defsp < 1 || st->stack->stack_data[st->stack->defsp-1].type != C_RETINFO ) {
+ // Incorrect usage of return outside the scope of a function or subroutine.
+ return true; // No need for further processing, running script is about to be aborted.
+ }
+
if( script_hasdata(st,2) )
{// return value
struct script_data* data;
@@ -5685,16 +5701,19 @@ BUILDIN(return) {
script->get_val(st, data);// current scope, convert to value
if( data->ref && data->ref->vars == st->stack->stack_data[st->stack->defsp-1].u.ri->scope.vars )
data->ref = NULL; // Reference to the parent scope, remove reference pointer
- } else if( name[0] == '.' && !data->ref ) {
- // script variable without a reference set, link to current script
- data->ref = (struct reg_db *)aCalloc(sizeof(struct reg_db), 1);
- script->add_pending_ref(st, data->ref);
- data->ref->vars = st->script->local.vars;
- if( !st->script->local.arrays )
- st->script->local.arrays = idb_alloc(DB_OPT_BASE);
- data->ref->arrays = st->script->local.arrays;
- } else if ( name[0] == '.' /* && data->ref != NULL */ ) {
- data->ref = NULL; // Reference to the parent scope's script, remove reference pointer.
+ } else if( name[0] == '.' ) {
+ // npc variable
+ if( !data->ref ) {
+ // npc variable without a reference set, link to current script
+ data->ref = (struct reg_db *)aCalloc(sizeof(struct reg_db), 1);
+ script->add_pending_ref(st, data->ref);
+ data->ref->vars = st->script->local.vars;
+ if( !st->script->local.arrays )
+ st->script->local.arrays = idb_alloc(DB_OPT_BASE);
+ data->ref->arrays = st->script->local.arrays;
+ } else if( data->ref->vars == st->stack->stack_data[st->stack->defsp-1].u.ri->script->local.vars ) {
+ data->ref = NULL; // Reference to the parent scope's script, remove reference pointer.
+ }
}
}
}
@@ -5702,7 +5721,7 @@ BUILDIN(return) {
{// no return value
script_pushnil(st);
}
- st->state = RETFUNC;
+
return true;
}
@@ -5744,6 +5763,7 @@ BUILDIN(warp)
{
int ret;
int x,y;
+ int warp_clean = 1;
const char* str;
TBL_PC* sd;
@@ -5755,6 +5775,11 @@ BUILDIN(warp)
x = script_getnum(st,3);
y = script_getnum(st,4);
+ if (script_hasdata(st, 5)) {
+ warp_clean = script_getnum(st, 5);
+ }
+
+ sd->state.warp_clean = warp_clean;
if(strcmp(str,"Random")==0)
ret = pc->randomwarp(sd,CLR_TELEPORT);
else if(strcmp(str,"SavePoint")==0 || strcmp(str,"Save")==0)
@@ -7424,7 +7449,7 @@ void buildin_delitem_delete(struct map_session_data* sd, int idx, int* amount, b
{// delete associated pet
intif->delete_petdata(MakeDWord(inv->card[1], inv->card[2]));
}
- pc->delitem(sd, idx, delamount, 0, 0, LOG_TYPE_SCRIPT);
+ pc->delitem(sd, idx, delamount, 0, DELITEM_NORMAL, LOG_TYPE_SCRIPT);
}
amount[0]-= delamount;
@@ -8085,6 +8110,23 @@ BUILDIN(strnpcinfo) {
return true;
}
+/**
+ * charid2rid: Returns the RID associated to the given character ID
+ */
+BUILDIN(charid2rid)
+{
+ int cid = script_getnum(st, 2);
+ TBL_PC *sd = map->charid2sd(cid);
+
+ if (sd == NULL) {
+ script_pushint(st, 0);
+ return true;
+ }
+
+ script_pushint(st, sd->status.account_id);
+ return true;
+}
+
/*==========================================
* GetEquipID(Pos); Pos: 1-SCRIPT_EQUIP_TABLE_SIZE
*------------------------------------------*/
@@ -8455,10 +8497,10 @@ BUILDIN(successrefitem)
sd->status.inventory[i].refine += up;
sd->status.inventory[i].refine = cap_value( sd->status.inventory[i].refine, 0, MAX_REFINE);
- pc->unequipitem(sd,i,2); // status calc will happen in pc->equipitem() below
+ pc->unequipitem(sd, i, PCUNEQUIPITEM_FORCE); // status calc will happen in pc->equipitem() below
clif->refine(sd->fd,0,i,sd->status.inventory[i].refine);
- clif->delitem(sd,i,1,3);
+ clif->delitem(sd, i, 1, DELITEM_MATERIALCHANGE);
//Logs items, got from (N)PC scripts [Lupus]
logs->pick_pc(sd, LOG_TYPE_SCRIPT, 1, &sd->status.inventory[i],sd->inventory_data[i]);
@@ -8504,10 +8546,10 @@ BUILDIN(failedrefitem)
i=pc->checkequip(sd,script->equip[num-1]);
if(i >= 0) {
sd->status.inventory[i].refine = 0;
- pc->unequipitem(sd,i,3); //recalculate bonus
+ pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE); //recalculate bonus
clif->refine(sd->fd,1,i,sd->status.inventory[i].refine); //notify client of failure
- pc->delitem(sd,i,1,0,2,LOG_TYPE_SCRIPT);
+ pc->delitem(sd, i, 1, 0, DELITEM_FAILREFINE, LOG_TYPE_SCRIPT);
clif->misceffect(&sd->bl,2); // display failure effect
}
@@ -8538,12 +8580,12 @@ BUILDIN(downrefitem)
//Logs items, got from (N)PC scripts [Lupus]
logs->pick_pc(sd, LOG_TYPE_SCRIPT, -1, &sd->status.inventory[i],sd->inventory_data[i]);
- pc->unequipitem(sd,i,2); // status calc will happen in pc->equipitem() below
+ pc->unequipitem(sd, i, PCUNEQUIPITEM_FORCE); // status calc will happen in pc->equipitem() below
sd->status.inventory[i].refine -= down;
sd->status.inventory[i].refine = cap_value( sd->status.inventory[i].refine, 0, MAX_REFINE);
clif->refine(sd->fd,2,i,sd->status.inventory[i].refine);
- clif->delitem(sd,i,1,3);
+ clif->delitem(sd, i, 1, DELITEM_MATERIALCHANGE);
//Logs items, got from (N)PC scripts [Lupus]
logs->pick_pc(sd, LOG_TYPE_SCRIPT, 1, &sd->status.inventory[i],sd->inventory_data[i]);
@@ -8572,8 +8614,8 @@ BUILDIN(delequip)
if (num > 0 && num <= ARRAYLENGTH(script->equip))
i=pc->checkequip(sd,script->equip[num-1]);
if(i >= 0) {
- pc->unequipitem(sd,i,3); //recalculate bonus
- pc->delitem(sd,i,1,0,2,LOG_TYPE_SCRIPT);
+ pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE); //recalculate bonus
+ pc->delitem(sd, i, 1, 0, DELITEM_FAILREFINE, LOG_TYPE_SCRIPT);
return true;
}
@@ -8829,7 +8871,7 @@ BUILDIN(autobonus3) {
BUILDIN(skill) {
int id;
int level;
- int flag = 1;
+ int flag = SKILL_GRANT_TEMPORARY;
TBL_PC* sd;
sd = script->rid2sd(st);
@@ -8857,7 +8899,7 @@ BUILDIN(skill) {
BUILDIN(addtoskill) {
int id;
int level;
- int flag = 2;
+ int flag = SKILL_GRANT_TEMPSTACK;
TBL_PC* sd;
sd = script->rid2sd(st);
@@ -9702,8 +9744,7 @@ BUILDIN(monster)
if (script_hasdata(st, 10))
{
ai = script_getnum(st, 10);
- if (ai > 4)
- {
+ if (ai > AI_FLORA) {
ShowWarning("buildin_monster: Attempted to spawn non-existing ai %d for monster class %d\n", ai, class_);
return false;
}
@@ -9807,7 +9848,7 @@ BUILDIN(areamonster) {
if (script_hasdata(st, 12)) {
ai = script_getnum(st, 12);
- if (ai > 4) {
+ if (ai > AI_FLORA) {
ShowWarning("buildin_monster: Attempted to spawn non-existing ai %d for monster class %d\n", ai, class_);
return false;
}
@@ -10977,7 +11018,7 @@ BUILDIN(homunculus_mutate)
if (m_class == HT_EVO && m_id == HT_S &&
sd->hd->homunculus.level >= 99 && i != INDEX_NOT_FOUND &&
- !pc->delitem(sd, i, 1, 0, 0, LOG_TYPE_SCRIPT) ) {
+ !pc->delitem(sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_SCRIPT) ) {
sd->hd->homunculus.vaporize = HOM_ST_REST; // Remove morph state.
homun->call(sd); // Respawn homunculus.
homun->mutate(sd->hd, homun_id);
@@ -11158,26 +11199,24 @@ BUILDIN(resetstatus)
/*==========================================
* script command resetskill
*------------------------------------------*/
-BUILDIN(resetskill)
-{
+BUILDIN(resetskill) {
TBL_PC *sd;
sd=script->rid2sd(st);
if( sd == NULL )
return false;
- pc->resetskill(sd,1);
+ pc->resetskill(sd, PCRESETSKILL_RESYNC);
return true;
}
/*==========================================
* Counts total amount of skill points.
*------------------------------------------*/
-BUILDIN(skillpointcount)
-{
+BUILDIN(skillpointcount) {
TBL_PC *sd;
sd=script->rid2sd(st);
if( sd == NULL )
return false;
- script_pushint(st,sd->status.skill_point + pc->resetskill(sd,2));
+ script_pushint(st,sd->status.skill_point + pc->resetskill(sd, PCRESETSKILL_RECOUNT));
return true;
}
@@ -11219,10 +11258,10 @@ static TBL_PC *prepareChangeSex(struct script_state* st)
if (sd == NULL)
return NULL;
- pc->resetskill(sd, 4);
+ pc->resetskill(sd, PCRESETSKILL_CHSEX);
// to avoid any problem with equipment and invalid sex, equipment is unequiped.
for (i=0; i<EQI_MAX; i++)
- if (sd->equip_index[i] >= 0) pc->unequipitem(sd, sd->equip_index[i], 3);
+ if (sd->equip_index[i] >= 0) pc->unequipitem(sd, sd->equip_index[i], PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE);
return sd;
}
@@ -11234,7 +11273,7 @@ BUILDIN(changesex)
TBL_PC *sd = prepareChangeSex(st);
if (sd == NULL)
return false;
- chrif->changesex(sd);
+ chrif->changesex(sd, true);
return true;
}
@@ -11246,12 +11285,7 @@ BUILDIN(changecharsex)
TBL_PC *sd = prepareChangeSex(st);
if (sd == NULL)
return false;
- if (sd->status.sex == 99)
- sd->status.sex = 0;
- sd->status.sex = sd->status.sex ? 0 : 1;
- chrif->save(sd, 0);
- if (sd->fd)
- clif->authfail_fd(sd->fd, 15);
+ chrif->changesex(sd, false);
return true;
}
@@ -12280,7 +12314,7 @@ BUILDIN(successremovecards)
for (j = sd->inventory_data[i]->slot; j < MAX_SLOTS; j++)
item_tmp.card[j]=sd->status.inventory[i].card[j];
- pc->delitem(sd,i,1,0,3,LOG_TYPE_SCRIPT);
+ pc->delitem(sd, i, 1, 0, DELITEM_MATERIALCHANGE, LOG_TYPE_SCRIPT);
if ((flag=pc->additem(sd,&item_tmp,1,LOG_TYPE_SCRIPT))) {
//chk if can be spawn in inventory otherwise put on floor
clif->additem(sd,0,0,flag);
@@ -12342,7 +12376,7 @@ BUILDIN(failedremovecards)
if (cardflag == 1) {
if (typefail == 0 || typefail == 2) {
// destroy the item
- pc->delitem(sd,i,1,0,2,LOG_TYPE_SCRIPT);
+ pc->delitem(sd, i, 1, 0, DELITEM_FAILREFINE, LOG_TYPE_SCRIPT);
} else if (typefail == 1) {
// destroy the card
int flag, j;
@@ -12360,7 +12394,7 @@ BUILDIN(failedremovecards)
for (j = sd->inventory_data[i]->slot; j < MAX_SLOTS; j++)
item_tmp.card[j]=sd->status.inventory[i].card[j];
- pc->delitem(sd,i,1,0,2,LOG_TYPE_SCRIPT);
+ pc->delitem(sd, i, 1, 0, DELITEM_FAILREFINE, LOG_TYPE_SCRIPT);
if((flag=pc->additem(sd,&item_tmp,1,LOG_TYPE_SCRIPT))) {
clif->additem(sd,0,0,flag);
@@ -13054,7 +13088,7 @@ BUILDIN(clearitem)
if(sd==NULL) return true;
for (i=0; i<MAX_INVENTORY; i++) {
if (sd->status.inventory[i].amount) {
- pc->delitem(sd, i, sd->status.inventory[i].amount, 0, 0, LOG_TYPE_SCRIPT);
+ pc->delitem(sd, i, sd->status.inventory[i].amount, 0, DELITEM_NORMAL, LOG_TYPE_SCRIPT);
}
}
return true;
@@ -13483,7 +13517,7 @@ BUILDIN(nude)
if( sd->equip_index[ i ] >= 0 ) {
if( !calcflag )
calcflag = 1;
- pc->unequipitem( sd , sd->equip_index[ i ] , 2);
+ pc->unequipitem(sd, sd->equip_index[i], PCUNEQUIPITEM_FORCE);
}
}
@@ -13830,7 +13864,7 @@ BUILDIN(npcstop) {
if( nd ) {
unit->bl2ud2(&nd->bl); // ensure nd->ud is safe to edit
- unit->stop_walking(&nd->bl,1|4);
+ unit->stop_walking(&nd->bl, STOPWALKING_FLAG_FIXPOS|STOPWALKING_FLAG_NEXTCELL);
}
return true;
@@ -14240,11 +14274,6 @@ BUILDIN(isnight) {
return true;
}
-BUILDIN(isday) {
- script_pushint(st,(map->night_flag == 0));
- return true;
-}
-
/*================================================
* Check how many items/cards in the list are
* equipped - used for 2/15's cards patch [celest]
@@ -14460,7 +14489,7 @@ BUILDIN(unequip)
if (sd != NULL && num >= 1 && num <= ARRAYLENGTH(script->equip)) {
int i = pc->checkequip(sd,script->equip[num-1]);
if (i >= 0)
- pc->unequipitem(sd,i,1|2);
+ pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE);
}
return true;
}
@@ -15466,8 +15495,26 @@ BUILDIN(compare)
return true;
}
-// [zBuffer] List of mathematics commands --->
-BUILDIN(sqrt)
+BUILDIN(strcmp)
+{
+ const char *str1 = script_getstr(st,2);
+ const char *str2 = script_getstr(st,3);
+ script_pushint(st,strcmp(str1, str2));
+ return true;
+}
+
+// List of mathematics commands --->
+
+BUILDIN(log10)
+{
+ double i, a;
+ i = script_getnum(st,2);
+ a = log10(i);
+ script_pushint(st,(int)a);
+ return true;
+}
+
+BUILDIN(sqrt) //[zBuffer]
{
double i, a;
i = script_getnum(st,2);
@@ -15476,7 +15523,7 @@ BUILDIN(sqrt)
return true;
}
-BUILDIN(pow)
+BUILDIN(pow) //[zBuffer]
{
double i, a, b;
a = script_getnum(st,2);
@@ -15486,7 +15533,7 @@ BUILDIN(pow)
return true;
}
-BUILDIN(distance)
+BUILDIN(distance) //[zBuffer]
{
int x0, y0, x1, y1;
@@ -15499,7 +15546,7 @@ BUILDIN(distance)
return true;
}
-// <--- [zBuffer] List of mathematics commands
+// <--- List of mathematics commands
BUILDIN(min)
{
@@ -16432,7 +16479,7 @@ BUILDIN(unitstop) {
if( bl != NULL ) {
unit->bl2ud2(bl); // ensure ((TBL_NPC*)bl)->ud is safe to edit
unit->stop_attack(bl);
- unit->stop_walking(bl,4);
+ unit->stop_walking(bl, STOPWALKING_FLAG_NEXTCELL);
if( bl->type == BL_MOB )
((TBL_MOB*)bl)->target_id = 0;
}
@@ -17136,18 +17183,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( i >= sd->avail_quests ) {
+ script_pushint(st, 0);
+ return true;
+ }
- if (quest->check(sd, script_getnum(st, 2), HAVEQUEST) == Q_ACTIVE)
+ if(sd->quest_log[i].state == Q_ACTIVE)
script_pushint(st, 1);
else
script_pushint(st, 0);
- script_pushint(st, quest_progress);
-
return true;
}
@@ -17251,7 +17307,9 @@ BUILDIN(waitingroom2bg) {
return true;
}
+ Assert_retr(false, cd->users < MAX_CHAT_USERS);
n = cd->users; // This is always < MAX_CHAT_USERS
+
for (i = 0; i < n && i < MAX_BG_MEMBERS; i++) {
struct map_session_data *sd = cd->usersd[i];
if (sd != NULL && bg->team_join(bg_id, sd))
@@ -17356,7 +17414,7 @@ BUILDIN(bg_monster_set_team) {
md->bg_id = bg_id;
mob_stop_attack(md);
- mob_stop_walking(md, 0);
+ mob_stop_walking(md, STOPWALKING_FLAG_NONE);
md->target_id = md->attacked_id = 0;
clif->charnameack(0, &md->bl);
@@ -18158,7 +18216,7 @@ BUILDIN(setcashmount)
if ((sd = script->rid2sd(st)) == NULL)
return true;
if (pc_hasmount(sd)) {
- clif->msgtable(sd->fd, 0X78b);
+ clif->msgtable(sd, MSG_REINS_CANT_USE_MOUNTED);
script_pushint(st,0);//can't mount with one of these
} else {
if (sd->sc.data[SC_ALL_RIDING])
@@ -19617,6 +19675,48 @@ BUILDIN(channelmes)
return true;
}
+
+/** By Cydh
+Display script message
+showscript "<message>"{,<GID>};
+*/
+BUILDIN(showscript) {
+ struct block_list *bl = NULL;
+ const char *msg = script_getstr(st, 2);
+ int id = 0;
+
+ if (script_hasdata(st, 3)) {
+ id = script_getnum(st, 3);
+ bl = map->id2bl(id);
+ }
+ else {
+ bl = st->rid ? map->id2bl(st->rid) : map->id2bl(st->oid);
+ }
+
+ if (!bl) {
+ ShowError("buildin_showscript: Script not attached. (id=%d, rid=%d, oid=%d)\n", id, st->rid, st->oid);
+ script_pushint(st, 0);
+ return false;
+ }
+
+ clif->ShowScript(bl, msg);
+
+ script_pushint(st, 1);
+
+ return true;
+}
+
+BUILDIN(mergeitem)
+{
+ struct map_session_data *sd = script->rid2sd(st);
+
+ if (sd == NULL)
+ return true;
+
+ clif->openmergeitem(sd->fd, sd);
+
+ return true;
+}
/** place holder for the translation macro **/
BUILDIN(_) {
return true;
@@ -19761,7 +19861,7 @@ void script_parse_builtin(void) {
BUILDIN_DEF(jobchange,"i?"),
BUILDIN_DEF(jobname,"i"),
BUILDIN_DEF(input,"r??"),
- BUILDIN_DEF(warp,"sii"),
+ BUILDIN_DEF(warp,"sii?"),
BUILDIN_DEF(areawarp,"siiiisii??"),
BUILDIN_DEF(warpchar,"siii"), // [LuzZza]
BUILDIN_DEF(warpparty,"siii?"), // [Fredzilla] [Paradox924X]
@@ -19807,6 +19907,7 @@ void script_parse_builtin(void) {
BUILDIN_DEF(getguildmember,"i?"),
BUILDIN_DEF(strcharinfo,"i"),
BUILDIN_DEF(strnpcinfo,"i"),
+ BUILDIN_DEF(charid2rid,"i"),
BUILDIN_DEF(getequipid,"i"),
BUILDIN_DEF(getequipname,"i"),
BUILDIN_DEF(getbrokenid,"i"), // [Valaris]
@@ -19997,7 +20098,6 @@ void script_parse_builtin(void) {
BUILDIN_DEF(logmes,"s"), //this command actls as MES but rints info into LOG file either SQL/TXT [Lupus]
BUILDIN_DEF(summon,"si??"), // summons a slave monster [Celest]
BUILDIN_DEF(isnight,""), // check whether it is night time [Celest]
- BUILDIN_DEF_DEPRECATED(isday,""), // check whether it is day time [Celest] // DEPRECATED 2015-01-21 [Haru]
BUILDIN_DEF(isequipped,"i*"), // check whether another item/card has been equipped [Celest]
BUILDIN_DEF(isequippedcnt,"i*"), // check how many items/cards are being equipped [Celest]
BUILDIN_DEF(cardscnt,"i*"), // check how many items/cards are being equipped in the same arm [Lupus]
@@ -20040,14 +20140,16 @@ void script_parse_builtin(void) {
BUILDIN_DEF(countstr,"ss?"),
BUILDIN_DEF(setnpcdisplay,"sv??"),
BUILDIN_DEF(compare,"ss"), // Lordalfa - To bring strstr to scripting Engine.
+ BUILDIN_DEF(strcmp,"ss"),
BUILDIN_DEF(getiteminfo,"ii"), //[Lupus] returns Items Buy / sell Price, etc info
BUILDIN_DEF(setiteminfo,"iii"), //[Lupus] set Items Buy / sell Price, etc info
BUILDIN_DEF(getequipcardid,"ii"), //[Lupus] returns CARD ID or other info from CARD slot N of equipped item
- // [zBuffer] List of mathematics commands --->
- BUILDIN_DEF(sqrt,"i"),
- BUILDIN_DEF(pow,"ii"),
- BUILDIN_DEF(distance,"iiii"),
- // <--- [zBuffer] List of mathematics commands
+ // List of mathematics commands --->
+ BUILDIN_DEF(log10,"i"),
+ BUILDIN_DEF(sqrt,"i"), //[zBuffer]
+ BUILDIN_DEF(pow,"ii"), //[zBuffer]
+ BUILDIN_DEF(distance,"iiii"), //[zBuffer]
+ // <--- List of mathematics commands
BUILDIN_DEF(min, "i*"),
BUILDIN_DEF(max, "i*"),
BUILDIN_DEF(md5,"s"),
@@ -20175,7 +20277,7 @@ void script_parse_builtin(void) {
BUILDIN_DEF(makerune,"i"),
BUILDIN_DEF(hascashmount,""),//[Ind]
BUILDIN_DEF(setcashmount,""),//[Ind]
- BUILDIN_DEF(checkre,"i"),
+ BUILDIN_DEF_DEPRECATED(checkre,"i"), // Deprecated 2015-05-08 [Haru]
/**
* rAthena and beyond!
**/
@@ -20252,6 +20354,8 @@ void script_parse_builtin(void) {
BUILDIN_DEF(shopcount, "i"),
BUILDIN_DEF(channelmes, "ss"),
+ BUILDIN_DEF(showscript, "s?"),
+ BUILDIN_DEF(mergeitem,""),
BUILDIN_DEF(_,"s"),
};
int i, len = ARRAYLENGTH(BUILDIN);
@@ -20357,6 +20461,43 @@ void script_hardcoded_constants(void) {
script->set_constant("BG_AREA",BG_AREA,false);
script->set_constant("BG_AREA_WOS",BG_AREA_WOS,false);
script->set_constant("BG_QUEUE",BG_QUEUE,false);
+
+ /* Renewal */
+#ifdef RENEWAL
+ script->set_constant("RENEWAL", 1, false);
+#else
+ script->set_constant("RENEWAL", 0, false);
+#endif
+#ifdef RENEWAL_CAST
+ script->set_constant("RENEWAL_CAST", 1, false);
+#else
+ script->set_constant("RENEWAL_CAST", 0, false);
+#endif
+#ifdef RENEWAL_DROP
+ script->set_constant("RENEWAL_DROP", 1, false);
+#else
+ script->set_constant("RENEWAL_DROP", 0, false);
+#endif
+#ifdef RENEWAL_EXP
+ script->set_constant("RENEWAL_EXP", 1, false);
+#else
+ script->set_constant("RENEWAL_EXP", 0, false);
+#endif
+#ifdef RENEWAL_LVDMG
+ script->set_constant("RENEWAL_LVDMG", 1, false);
+#else
+ script->set_constant("RENEWAL_LVDMG", 0, false);
+#endif
+#ifdef RENEWAL_EDP
+ script->set_constant("RENEWAL_EDP", 1, false);
+#else
+ script->set_constant("RENEWAL_EDP", 0, false);
+#endif
+#ifdef RENEWAL_ASPD
+ script->set_constant("RENEWAL_ASPD", 1, false);
+#else
+ script->set_constant("RENEWAL_ASPD", 0, false);
+#endif
}
/**
diff --git a/src/map/script.h b/src/map/script.h
index 51bdf23b5..93d60f416 100644
--- a/src/map/script.h
+++ b/src/map/script.h
@@ -5,16 +5,16 @@
#ifndef MAP_SCRIPT_H
#define MAP_SCRIPT_H
+#include "map/map.h" //EVENT_NAME_LENGTH
+#include "common/cbasetypes.h"
+#include "common/db.h"
+#include "common/mmo.h" // struct item
+#include "common/sql.h" // Sql
+#include "common/strlib.h" //StringBuf
+
#include <errno.h>
#include <setjmp.h>
-#include "map.h" //EVENT_NAME_LENGTH
-#include "../common/cbasetypes.h"
-#include "../common/db.h"
-#include "../common/mmo.h" // struct item
-#include "../common/sql.h" // Sql
-#include "../common/strlib.h" //StringBuf
-
/**
* Declarations
**/
@@ -605,6 +605,7 @@ struct script_interface {
/* */
struct script_string_buf parse_simpleexpr_str;
struct script_string_buf lang_export_line_buf;
+ struct script_string_buf lang_export_unescaped_buf;
/* */
int parse_cleanup_timer_id;
/* */
diff --git a/src/map/searchstore.c b/src/map/searchstore.c
index 782c14987..b9e23ae82 100644
--- a/src/map/searchstore.c
+++ b/src/map/searchstore.c
@@ -4,15 +4,15 @@
#define HERCULES_CORE
-#include "searchstore.h" // struct s_search_store_info
-
-#include "battle.h" // battle_config.*
-#include "clif.h" // clif->open_search_store_info, clif->search_store_info_*
-#include "pc.h" // struct map_session_data
-#include "../common/cbasetypes.h"
-#include "../common/malloc.h" // aMalloc, aRealloc, aFree
-#include "../common/showmsg.h" // ShowError, ShowWarning
-#include "../common/strlib.h" // safestrncpy
+#include "searchstore.h" // struct s_search_store_info
+
+#include "map/battle.h" // battle_config.*
+#include "map/clif.h" // clif-"open_search_store_info, clif-"search_store_info_*
+#include "map/pc.h" // struct map_session_data
+#include "common/cbasetypes.h"
+#include "common/malloc.h" // aMalloc, aRealloc, aFree
+#include "common/showmsg.h" // ShowError, ShowWarning
+#include "common/strlib.h" // safestrncpy
struct searchstore_interface searchstore_s;
diff --git a/src/map/searchstore.h b/src/map/searchstore.h
index 6664eddfa..2778740a5 100644
--- a/src/map/searchstore.h
+++ b/src/map/searchstore.h
@@ -5,11 +5,11 @@
#ifndef MAP_SEARCHSTORE_H
#define MAP_SEARCHSTORE_H
-#include <time.h>
+#include "map/map.h" // MESSAGE_SIZE
+#include "common/cbasetypes.h"
+#include "common/mmo.h" // MAX_SLOTS
-#include "map.h" // MESSAGE_SIZE
-#include "../common/cbasetypes.h"
-#include "../common/mmo.h" // MAX_SLOTS
+#include <time.h>
/**
* Defines
diff --git a/src/map/skill.c b/src/map/skill.c
index 96ade3908..f2154aa22 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -4,47 +4,47 @@
#define HERCULES_CORE
-#include "../config/core.h" // DBPATH, MAGIC_REFLECTION_TYPE, OFFICIAL_WALKPATH, RENEWAL, RENEWAL_CAST, VARCAST_REDUCTION()
+#include "config/core.h" // DBPATH, MAGIC_REFLECTION_TYPE, OFFICIAL_WALKPATH, RENEWAL, RENEWAL_CAST, VARCAST_REDUCTION()
#include "skill.h"
+#include "map/battle.h"
+#include "map/battleground.h"
+#include "map/chrif.h"
+#include "map/clif.h"
+#include "map/date.h"
+#include "map/elemental.h"
+#include "map/guild.h"
+#include "map/homunculus.h"
+#include "map/intif.h"
+#include "map/itemdb.h"
+#include "map/log.h"
+#include "map/map.h"
+#include "map/mercenary.h"
+#include "map/mob.h"
+#include "map/npc.h"
+#include "map/party.h"
+#include "map/path.h"
+#include "map/pc.h"
+#include "map/pet.h"
+#include "map/script.h"
+#include "map/status.h"
+#include "map/unit.h"
+#include "common/cbasetypes.h"
+#include "common/ers.h"
+#include "common/malloc.h"
+#include "common/nullpo.h"
+#include "common/random.h"
+#include "common/showmsg.h"
+#include "common/strlib.h"
+#include "common/timer.h"
+#include "common/utils.h"
+
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
-#include "battle.h"
-#include "battleground.h"
-#include "chrif.h"
-#include "clif.h"
-#include "date.h"
-#include "elemental.h"
-#include "guild.h"
-#include "homunculus.h"
-#include "intif.h"
-#include "itemdb.h"
-#include "log.h"
-#include "map.h"
-#include "mercenary.h"
-#include "mob.h"
-#include "npc.h"
-#include "party.h"
-#include "path.h"
-#include "pc.h"
-#include "pet.h"
-#include "script.h"
-#include "status.h"
-#include "unit.h"
-#include "../common/cbasetypes.h"
-#include "../common/ers.h"
-#include "../common/malloc.h"
-#include "../common/nullpo.h"
-#include "../common/random.h"
-#include "../common/showmsg.h"
-#include "../common/strlib.h"
-#include "../common/timer.h"
-#include "../common/utils.h"
-
#define SKILLUNITTIMER_INTERVAL 100
// ranges reserved for mapping skill ids to skilldb offsets
@@ -62,6 +62,7 @@
#endif
struct skill_interface skill_s;
+struct s_skill_dbs skilldbs;
//Since only mob-casted splash skills can hit ice-walls
static inline int splash_target(struct block_list* bl) {
@@ -99,7 +100,7 @@ int skill_get_index( uint16 skill_id ) {
skill_id = MC_SKILLRANGEMIN + skill_id - MC_SKILLBASE;
else if( skill_id >= HM_SKILLBASE )
skill_id = HM_SKILLRANGEMIN + skill_id - HM_SKILLBASE;
- //[Ind/Hercules] GO GO GO LESS! - http://hercules.ws/board/topic/512-skill-id-processing-overhaul/
+ //[Ind/Hercules] GO GO GO LESS! - http://herc.ws/board/topic/512-skill-id-processing-overhaul/
else if( skill_id > 1019 && skill_id < 8001 ) {
if( skill_id < 2058 ) // 1020 - 2000 are empty
skill_id = 1020 + skill_id - 2001;
@@ -121,11 +122,11 @@ int skill_get_index( uint16 skill_id ) {
}
const char* skill_get_name( uint16 skill_id ) {
- return skill->db[skill->get_index(skill_id)].name;
+ return skill->dbs->db[skill->get_index(skill_id)].name;
}
const char* skill_get_desc( uint16 skill_id ) {
- return skill->db[skill->get_index(skill_id)].desc;
+ return skill->dbs->db[skill->get_index(skill_id)].desc;
}
// out of bounds error checking [celest]
@@ -138,58 +139,58 @@ void skill_chk(uint16* skill_id) {
skill->chk(&(id)); \
if(!(id)) return 0; \
if( (lv) > MAX_SKILL_LEVEL && (var) > 1 ) { \
- int lv2__ = (lv); (lv) = skill->db[(id)].max; \
+ int lv2__ = (lv); (lv) = skill->dbs->db[(id)].max; \
return (var) + ((lv2__-(lv))/2);\
} \
return (var);\
} while(0)
#define skill_glv(lv) min((lv),MAX_SKILL_LEVEL-1)
// Skill DB
-int skill_get_hit( uint16 skill_id ) { skill_get (skill->db[skill_id].hit, skill_id); }
-int skill_get_inf( uint16 skill_id ) { skill_get (skill->db[skill_id].inf, skill_id); }
-int skill_get_ele( uint16 skill_id , uint16 skill_lv ) { skill_get (skill->db[skill_id].element[skill_glv(skill_lv-1)], skill_id); }
-int skill_get_nk( uint16 skill_id ) { skill_get (skill->db[skill_id].nk, skill_id); }
-int skill_get_max( uint16 skill_id ) { skill_get (skill->db[skill_id].max, skill_id); }
-int skill_get_range( uint16 skill_id , uint16 skill_lv ) { skill_get2 (skill->db[skill_id].range[skill_glv(skill_lv-1)], skill_id, skill_lv); }
-int skill_get_splash( uint16 skill_id , uint16 skill_lv ) { skill_get2 ( (skill->db[skill_id].splash[skill_glv(skill_lv-1)]>=0?skill->db[skill_id].splash[skill_glv(skill_lv-1)]:AREA_SIZE), skill_id, skill_lv); }
-int skill_get_hp( uint16 skill_id ,uint16 skill_lv ) { skill_get2 (skill->db[skill_id].hp[skill_glv(skill_lv-1)], skill_id, skill_lv); }
-int skill_get_sp( uint16 skill_id ,uint16 skill_lv ) { skill_get2 (skill->db[skill_id].sp[skill_glv(skill_lv-1)], skill_id, skill_lv); }
-int skill_get_hp_rate(uint16 skill_id, uint16 skill_lv ) { skill_get2 (skill->db[skill_id].hp_rate[skill_glv(skill_lv-1)], skill_id, skill_lv); }
-int skill_get_sp_rate(uint16 skill_id, uint16 skill_lv ) { skill_get2 (skill->db[skill_id].sp_rate[skill_glv(skill_lv-1)], skill_id, skill_lv); }
-int skill_get_state(uint16 skill_id) { skill_get (skill->db[skill_id].state, skill_id); }
-int skill_get_spiritball(uint16 skill_id, uint16 skill_lv) { skill_get2 (skill->db[skill_id].spiritball[skill_glv(skill_lv-1)], skill_id, skill_lv); }
-int skill_get_itemid(uint16 skill_id, int idx) { skill_get (skill->db[skill_id].itemid[idx], skill_id); }
-int skill_get_itemqty(uint16 skill_id, int idx) { skill_get (skill->db[skill_id].amount[idx], skill_id); }
-int skill_get_zeny( uint16 skill_id ,uint16 skill_lv ) { skill_get2 (skill->db[skill_id].zeny[skill_glv(skill_lv-1)], skill_id, skill_lv); }
-int skill_get_num( uint16 skill_id ,uint16 skill_lv ) { skill_get2 (skill->db[skill_id].num[skill_glv(skill_lv-1)], skill_id, skill_lv); }
-int skill_get_cast( uint16 skill_id ,uint16 skill_lv ) { skill_get2 (skill->db[skill_id].cast[skill_glv(skill_lv-1)], skill_id, skill_lv); }
-int skill_get_delay( uint16 skill_id ,uint16 skill_lv ) { skill_get2 (skill->db[skill_id].delay[skill_glv(skill_lv-1)], skill_id, skill_lv); }
-int skill_get_walkdelay( uint16 skill_id ,uint16 skill_lv ) { skill_get2 (skill->db[skill_id].walkdelay[skill_glv(skill_lv-1)], skill_id, skill_lv); }
-int skill_get_time( uint16 skill_id ,uint16 skill_lv ) { skill_get2 (skill->db[skill_id].upkeep_time[skill_glv(skill_lv-1)], skill_id, skill_lv); }
-int skill_get_time2( uint16 skill_id ,uint16 skill_lv ) { skill_get2 (skill->db[skill_id].upkeep_time2[skill_glv(skill_lv-1)], skill_id, skill_lv); }
-int skill_get_castdef( uint16 skill_id ) { skill_get (skill->db[skill_id].cast_def_rate, skill_id); }
-int skill_get_weapontype( uint16 skill_id ) { skill_get (skill->db[skill_id].weapon, skill_id); }
-int skill_get_ammotype( uint16 skill_id ) { skill_get (skill->db[skill_id].ammo, skill_id); }
-int skill_get_ammo_qty( uint16 skill_id, uint16 skill_lv ) { skill_get2 (skill->db[skill_id].ammo_qty[skill_glv(skill_lv-1)], skill_id, skill_lv); }
-int skill_get_inf2( uint16 skill_id ) { skill_get (skill->db[skill_id].inf2, skill_id); }
-int skill_get_castcancel( uint16 skill_id ) { skill_get (skill->db[skill_id].castcancel, skill_id); }
-int skill_get_maxcount( uint16 skill_id ,uint16 skill_lv ) { skill_get2 (skill->db[skill_id].maxcount[skill_glv(skill_lv-1)], skill_id, skill_lv); }
-int skill_get_blewcount( uint16 skill_id ,uint16 skill_lv ) { skill_get2 (skill->db[skill_id].blewcount[skill_glv(skill_lv-1)], skill_id, skill_lv); }
-int skill_get_mhp( uint16 skill_id ,uint16 skill_lv ) { skill_get2 (skill->db[skill_id].mhp[skill_glv(skill_lv-1)], skill_id, skill_lv); }
-int skill_get_castnodex( uint16 skill_id ,uint16 skill_lv ) { skill_get2 (skill->db[skill_id].castnodex[skill_glv(skill_lv-1)], skill_id, skill_lv); }
-int skill_get_delaynodex( uint16 skill_id ,uint16 skill_lv ){ skill_get2 (skill->db[skill_id].delaynodex[skill_glv(skill_lv-1)], skill_id, skill_lv); }
-int skill_get_type( uint16 skill_id ) { skill_get (skill->db[skill_id].skill_type, skill_id); }
-int skill_get_unit_id ( uint16 skill_id, int flag ){ skill_get (skill->db[skill_id].unit_id[flag], skill_id); }
-int skill_get_unit_interval( uint16 skill_id ) { skill_get (skill->db[skill_id].unit_interval, skill_id); }
-int skill_get_unit_range( uint16 skill_id, uint16 skill_lv ) { skill_get2 (skill->db[skill_id].unit_range[skill_glv(skill_lv-1)], skill_id, skill_lv); }
-int skill_get_unit_target( uint16 skill_id ) { skill_get (skill->db[skill_id].unit_target&BCT_ALL, skill_id); }
-int skill_get_unit_bl_target( uint16 skill_id ) { skill_get (skill->db[skill_id].unit_target&BL_ALL, skill_id); }
-int skill_get_unit_flag( uint16 skill_id ) { skill_get (skill->db[skill_id].unit_flag, skill_id); }
-int skill_get_unit_layout_type( uint16 skill_id ,uint16 skill_lv ){ skill_get2 (skill->db[skill_id].unit_layout_type[skill_glv(skill_lv-1)], skill_id, skill_lv); }
-int skill_get_cooldown( uint16 skill_id, uint16 skill_lv ) { skill_get2 (skill->db[skill_id].cooldown[skill_glv(skill_lv-1)], skill_id, skill_lv); }
+int skill_get_hit( uint16 skill_id ) { skill_get (skill->dbs->db[skill_id].hit, skill_id); }
+int skill_get_inf( uint16 skill_id ) { skill_get (skill->dbs->db[skill_id].inf, skill_id); }
+int skill_get_ele( uint16 skill_id , uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get (skill->dbs->db[skill_id].element[skill_glv(skill_lv-1)], skill_id); }
+int skill_get_nk( uint16 skill_id ) { skill_get (skill->dbs->db[skill_id].nk, skill_id); }
+int skill_get_max( uint16 skill_id ) { skill_get (skill->dbs->db[skill_id].max, skill_id); }
+int skill_get_range( uint16 skill_id , uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].range[skill_glv(skill_lv-1)], skill_id, skill_lv); }
+int skill_get_splash( uint16 skill_id , uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 ( (skill->dbs->db[skill_id].splash[skill_glv(skill_lv-1)]>=0?skill->dbs->db[skill_id].splash[skill_glv(skill_lv-1)]:AREA_SIZE), skill_id, skill_lv); }
+int skill_get_hp( uint16 skill_id ,uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].hp[skill_glv(skill_lv-1)], skill_id, skill_lv); }
+int skill_get_sp( uint16 skill_id ,uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].sp[skill_glv(skill_lv-1)], skill_id, skill_lv); }
+int skill_get_hp_rate(uint16 skill_id, uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].hp_rate[skill_glv(skill_lv-1)], skill_id, skill_lv); }
+int skill_get_sp_rate(uint16 skill_id, uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].sp_rate[skill_glv(skill_lv-1)], skill_id, skill_lv); }
+int skill_get_state(uint16 skill_id) { skill_get (skill->dbs->db[skill_id].state, skill_id); }
+int skill_get_spiritball(uint16 skill_id, uint16 skill_lv) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].spiritball[skill_glv(skill_lv-1)], skill_id, skill_lv); }
+int skill_get_itemid(uint16 skill_id, int idx) { skill_get (skill->dbs->db[skill_id].itemid[idx], skill_id); }
+int skill_get_itemqty(uint16 skill_id, int idx) { skill_get (skill->dbs->db[skill_id].amount[idx], skill_id); }
+int skill_get_zeny( uint16 skill_id ,uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].zeny[skill_glv(skill_lv-1)], skill_id, skill_lv); }
+int skill_get_num( uint16 skill_id ,uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].num[skill_glv(skill_lv-1)], skill_id, skill_lv); }
+int skill_get_cast( uint16 skill_id ,uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].cast[skill_glv(skill_lv-1)], skill_id, skill_lv); }
+int skill_get_delay( uint16 skill_id ,uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].delay[skill_glv(skill_lv-1)], skill_id, skill_lv); }
+int skill_get_walkdelay( uint16 skill_id ,uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].walkdelay[skill_glv(skill_lv-1)], skill_id, skill_lv); }
+int skill_get_time( uint16 skill_id ,uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].upkeep_time[skill_glv(skill_lv-1)], skill_id, skill_lv); }
+int skill_get_time2( uint16 skill_id ,uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].upkeep_time2[skill_glv(skill_lv-1)], skill_id, skill_lv); }
+int skill_get_castdef( uint16 skill_id ) { skill_get (skill->dbs->db[skill_id].cast_def_rate, skill_id); }
+int skill_get_weapontype( uint16 skill_id ) { skill_get (skill->dbs->db[skill_id].weapon, skill_id); }
+int skill_get_ammotype( uint16 skill_id ) { skill_get (skill->dbs->db[skill_id].ammo, skill_id); }
+int skill_get_ammo_qty( uint16 skill_id, uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].ammo_qty[skill_glv(skill_lv-1)], skill_id, skill_lv); }
+int skill_get_inf2( uint16 skill_id ) { skill_get (skill->dbs->db[skill_id].inf2, skill_id); }
+int skill_get_castcancel( uint16 skill_id ) { skill_get (skill->dbs->db[skill_id].castcancel, skill_id); }
+int skill_get_maxcount( uint16 skill_id ,uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].maxcount[skill_glv(skill_lv-1)], skill_id, skill_lv); }
+int skill_get_blewcount( uint16 skill_id ,uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].blewcount[skill_glv(skill_lv-1)], skill_id, skill_lv); }
+int skill_get_mhp( uint16 skill_id ,uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].mhp[skill_glv(skill_lv-1)], skill_id, skill_lv); }
+int skill_get_castnodex( uint16 skill_id ,uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].castnodex[skill_glv(skill_lv-1)], skill_id, skill_lv); }
+int skill_get_delaynodex( uint16 skill_id ,uint16 skill_lv ){ Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].delaynodex[skill_glv(skill_lv-1)], skill_id, skill_lv); }
+int skill_get_type( uint16 skill_id ) { skill_get (skill->dbs->db[skill_id].skill_type, skill_id); }
+int skill_get_unit_id ( uint16 skill_id, int flag ){ skill_get (skill->dbs->db[skill_id].unit_id[flag], skill_id); }
+int skill_get_unit_interval( uint16 skill_id ) { skill_get (skill->dbs->db[skill_id].unit_interval, skill_id); }
+int skill_get_unit_range( uint16 skill_id, uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].unit_range[skill_glv(skill_lv-1)], skill_id, skill_lv); }
+int skill_get_unit_target( uint16 skill_id ) { skill_get (skill->dbs->db[skill_id].unit_target&BCT_ALL, skill_id); }
+int skill_get_unit_bl_target( uint16 skill_id ) { skill_get (skill->dbs->db[skill_id].unit_target&BL_ALL, skill_id); }
+int skill_get_unit_flag( uint16 skill_id ) { skill_get (skill->dbs->db[skill_id].unit_flag, skill_id); }
+int skill_get_unit_layout_type( uint16 skill_id ,uint16 skill_lv ){ Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].unit_layout_type[skill_glv(skill_lv-1)], skill_id, skill_lv); }
+int skill_get_cooldown( uint16 skill_id, uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].cooldown[skill_glv(skill_lv-1)], skill_id, skill_lv); }
int skill_get_fixed_cast( uint16 skill_id ,uint16 skill_lv ) {
#ifdef RENEWAL_CAST
- skill_get2 (skill->db[skill_id].fixed_cast[skill_glv(skill_lv-1)], skill_id, skill_lv);
+ Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].fixed_cast[skill_glv(skill_lv-1)], skill_id, skill_lv);
#else
return 0;
#endif
@@ -223,17 +224,17 @@ int skill_get_casttype (uint16 skill_id) {
}
int skill_get_casttype2 (uint16 index) {
- int inf = skill->db[index].inf;
+ int inf = skill->dbs->db[index].inf;
if (inf&(INF_GROUND_SKILL))
return CAST_GROUND;
if (inf&INF_SUPPORT_SKILL)
return CAST_NODAMAGE;
if (inf&INF_SELF_SKILL) {
- if(skill->db[index].inf2&INF2_NO_TARGET_SELF)
+ if(skill->dbs->db[index].inf2&INF2_NO_TARGET_SELF)
return CAST_DAMAGE; //Combo skill.
return CAST_NODAMAGE;
}
- if (skill->db[index].nk&NK_NO_DAMAGE)
+ if (skill->dbs->db[index].nk&NK_NO_DAMAGE)
return CAST_NODAMAGE;
return CAST_DAMAGE;
}
@@ -438,7 +439,7 @@ int can_copy (struct map_session_data *sd, uint16 skill_id, struct block_list* b
if( !(sd->sc.data[SC__REPRODUCE]) && ((skill_id >= RK_ENCHANTBLADE && skill_id <= LG_OVERBRAND_PLUSATK) || (skill_id >= RL_GLITTERING_GREED && skill_id <= OB_AKAITSUKI) || (skill_id >= GC_DARKCROW && skill_id <= NC_MAGMA_ERUPTION_DOTDAMAGE)))
return 0;
// Reproduce will only copy skills according on the list. [Jobbie]
- else if( sd->sc.data[SC__REPRODUCE] && !skill->reproduce_db[skill->get_index(skill_id)] )
+ else if( sd->sc.data[SC__REPRODUCE] && !skill->dbs->reproduce_db[skill->get_index(skill_id)] )
return 0;
return 1;
@@ -619,19 +620,19 @@ struct s_skill_unit_layout* skill_get_unit_layout (uint16 skill_id, uint16 skill
}
if (pos != -1) // simple single-definition layout
- return &skill->unit_layout[pos];
+ return &skill->dbs->unit_layout[pos];
dir = (src->x == x && src->y == y) ? 6 : map->calc_dir(src,x,y); // 6 - default aegis direction
if (skill_id == MG_FIREWALL)
- return &skill->unit_layout [skill->firewall_unit_pos + dir];
+ return &skill->dbs->unit_layout [skill->firewall_unit_pos + dir];
else if (skill_id == WZ_ICEWALL)
- return &skill->unit_layout [skill->icewall_unit_pos + dir];
+ return &skill->dbs->unit_layout [skill->icewall_unit_pos + dir];
else if( skill_id == WL_EARTHSTRAIN ) //Warlock
- return &skill->unit_layout [skill->earthstrain_unit_pos + dir];
+ return &skill->dbs->unit_layout [skill->earthstrain_unit_pos + dir];
ShowError("skill_get_unit_layout: unknown unit layout for skill %d (level %d)\n", skill_id, skill_lv);
- return &skill->unit_layout[0]; // default 1x1 layout
+ return &skill->dbs->unit_layout[0]; // default 1x1 layout
}
/*==========================================
@@ -671,7 +672,7 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
if( skill_id != WS_CARTTERMINATION && skill_id != AM_DEMONSTRATION && skill_id != CR_REFLECTSHIELD && skill_id != MS_REFLECTSHIELD && skill_id != ASC_BREAKER ) {
// Trigger status effects
enum sc_type type;
- int i;
+ int i, flag;
for( i = 0; i < ARRAYLENGTH(sd->addeff) && sd->addeff[i].flag; i++ ) {
rate = sd->addeff[i].rate;
if( attack_type&BF_LONG ) // Any ranged physical attack takes status arrows into account (Grimtooth...) [DracoRPG]
@@ -695,13 +696,22 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
}
type = sd->addeff[i].id;
- temp = skill->get_time2(status->sc2skill(type),7);
+
+ if (sd->addeff[i].duration > 0) {
+ // Fixed duration
+ temp = sd->addeff[i].duration;
+ flag = SCFLAG_FIXEDRATE|SCFLAG_FIXEDTICK;
+ } else {
+ // Default duration
+ temp = skill->get_time2(status->sc2skill(type),7);
+ flag = SCFLAG_NONE;
+ }
if (sd->addeff[i].flag&ATF_TARGET)
- status->change_start(src,bl,type,rate,7,0,(type == SC_BURNING)?src->id:0,0,temp,SCFLAG_NONE);
+ status->change_start(src,bl,type,rate,7,0,(type == SC_BURNING)?src->id:0,0,temp,flag);
if (sd->addeff[i].flag&ATF_SELF)
- status->change_start(src,src,type,rate,7,0,(type == SC_BURNING)?src->id:0,0,temp,SCFLAG_NONE);
+ status->change_start(src,src,type,rate,7,0,(type == SC_BURNING)?src->id:0,0,temp,flag);
}
}
@@ -912,9 +922,11 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
break;
case AM_ACIDTERROR:
- sc_start2(src,bl,SC_BLOODING,(skill_lv*3),skill_lv,src->id,skill->get_time2(skill_id,skill_lv));
- if (skill->break_equip(bl, EQP_ARMOR, 100*skill->get_time(skill_id,skill_lv), BCT_ENEMY))
- clif->emotion(bl,E_OMG);
+ sc_start2(src, bl, SC_BLOODING, (skill_lv * 3), skill_lv, src->id, skill->get_time2(skill_id, skill_lv));
+ if ( bl->type == BL_PC && rnd() % 1000 < 10 * skill->get_time(skill_id, skill_lv) ) {
+ skill->break_equip(bl, EQP_ARMOR, 10000, BCT_ENEMY);
+ clif->emotion(bl, E_OMG); // emote icon still shows even there is no armor equip.
+ }
break;
case AM_DEMONSTRATION:
@@ -1356,7 +1368,7 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
break;
}
- if (md && battle_config.summons_trigger_autospells && md->master_id && md->special_state.ai) {
+ if (md && battle_config.summons_trigger_autospells && md->master_id && md->special_state.ai != AI_NONE) {
//Pass heritage to Master for status causing effects. [Skotlex]
sd = map->id2sd(md->master_id);
src = sd?&sd->bl:src;
@@ -2002,7 +2014,7 @@ int skill_break_equip (struct block_list *bl, unsigned short where, int rate, in
}
if (flag) {
sd->status.inventory[j].attribute = 1;
- pc->unequipitem(sd, j, 3);
+ pc->unequipitem(sd, j, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE);
}
}
clif->equiplist(sd);
@@ -2194,7 +2206,12 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr
//Trick Dead protects you from damage, but not from buffs and the like, hence it's placed here.
if (sc && sc->data[SC_TRICKDEAD])
return 0;
-
+ if ( skill_id != HW_GRAVITATION ) {
+ struct status_change *csc = status->get_sc(src);
+ if(csc && csc->data[SC_GRAVITATION] && csc->data[SC_GRAVITATION]->val3 == BCT_SELF )
+ return 0;
+ }
+
dmg = battle->calc_attack(attack_type,src,bl,skill_id,skill_lv,flag&0xFFF);
//Skotlex: Adjusted to the new system
@@ -2213,9 +2230,11 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr
}
}
- if( dmg.flag&BF_MAGIC && ( (battle_config.eq_single_target_reflectable && (flag&0xFFF) == 1) ) ) {
+ if( dmg.flag&BF_MAGIC
+ && (skill_id != NPC_EARTHQUAKE || (battle_config.eq_single_target_reflectable && (flag & 0xFFF) == 1)) ) { /* Need more info cause NPC_EARTHQUAKE is ground type */
// Earthquake on multiple targets is not counted as a target skill. [Inkfish]
- if( (dmg.damage || dmg.damage2) && (type = skill->magic_reflect(src, bl, src==dsrc)) ) {
+ int reflecttype;
+ if( (dmg.damage || dmg.damage2) && (reflecttype = skill->magic_reflect(src, bl, src==dsrc)) ) {
//Magic reflection, switch caster/target
struct block_list *tbl = bl;
rmdamage = true;
@@ -2232,17 +2251,17 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr
/* bugreport:7859 magical reflected zeroes blow count */
dmg.blewcount = 0;
//Spirit of Wizard blocks Kaite's reflection
- if (type == 2 && sc && sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_WIZARD) {
+ if (reflecttype == 2 && sc && sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_WIZARD) {
//Consume one Fragment per hit of the casted skill? [Skotlex]
- type = tsd ? pc->search_inventory(tsd, ITEMID_FRAGMENT_OF_CRYSTAL) : 0;
- if (type != INDEX_NOT_FOUND) {
- if ( tsd ) pc->delitem(tsd, type, 1, 0, 1, LOG_TYPE_CONSUME);
+ int consumeitem = tsd ? pc->search_inventory(tsd, ITEMID_FRAGMENT_OF_CRYSTAL) : 0;
+ if (consumeitem != INDEX_NOT_FOUND) {
+ if ( tsd ) pc->delitem(tsd, consumeitem, 1, 0, DELITEM_SKILLUSE, LOG_TYPE_CONSUME);
dmg.damage = dmg.damage2 = 0;
dmg.dmg_lv = ATK_MISS;
sc->data[SC_SOULLINK]->val3 = skill_id;
sc->data[SC_SOULLINK]->val4 = dsrc->id;
}
- } else if( type != 2 ) /* Kaite bypasses */
+ } else if( reflecttype != 2 ) /* Kaite bypasses */
additional_effects = false;
/**
@@ -2255,7 +2274,7 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr
#else
// issue:6415 in pre-renewal Kaite reflected the entire damage received
// regardless of caster's equipment (Aegis 11.1)
- if( dmg.dmg_lv != ATK_MISS && type == 1 ) //Wiz SL canceled and consumed fragment
+ if( dmg.dmg_lv != ATK_MISS && reflecttype == 1 ) //Wiz SL canceled and consumed fragment
#endif
{
short s_ele = skill->get_ele(skill_id, skill_lv);
@@ -2303,14 +2322,13 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr
if( damage && sc && sc->data[SC_GENSOU] && dmg.flag&BF_MAGIC ){
struct block_list *nbl;
nbl = battle->get_enemy_area(bl,bl->x,bl->y,2,BL_CHAR,bl->id);
- if( nbl ){ // Only one target is chosen.
- int temp = (int)(damage / (float)(10 / skill_lv));
- clif->skill_damage(bl, nbl, tick, status_get_amotion(src), 0, status_fix_damage(bl,nbl,temp,0), 1, OB_OBOROGENSOU_TRANSITION_ATK, -1, 6);
+ if (nbl) { // Only one target is chosen.
+ clif->skill_damage(bl, nbl, tick, status_get_amotion(src), 0, status_fix_damage(bl,nbl,damage * skill_lv / 10,0), 1, OB_OBOROGENSOU_TRANSITION_ATK, -1, BDT_SKILL);
}
}
//Skill hit type
- type=(skill_id==0)?5:skill->get_hit(skill_id);
+ type=(skill_id==0)?BDT_SPLASH:skill->get_hit(skill_id);
if(damage < dmg.div_
//Only skills that knockback even when they miss. [Skotlex]
@@ -2319,7 +2337,7 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr
if(skill_id == CR_GRANDCROSS||skill_id == NPC_GRANDDARKNESS) {
if(battle_config.gx_disptype) dsrc = src;
- if(src == bl) type = 4;
+ if(src == bl) type = BDT_ENDURE;
else flag|=SD_ANIMATION;
}
if(skill_id == NJ_TATAMIGAESHI) {
@@ -2425,7 +2443,7 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr
//Display damage.
switch( skill_id ) {
case PA_GOSPEL: //Should look like Holy Cross [Skotlex]
- dmg.dmotion = clif->skill_damage(dsrc,bl,tick,dmg.amotion,dmg.dmotion, damage, dmg.div_, CR_HOLYCROSS, -1, 5);
+ dmg.dmotion = clif->skill_damage(dsrc,bl,tick,dmg.amotion,dmg.dmotion, damage, dmg.div_, CR_HOLYCROSS, -1, BDT_SPLASH);
break;
//Skills that need be passed as a normal attack for the client to display correctly.
case HVAN_EXPLOSION:
@@ -2443,13 +2461,13 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr
case AS_SPLASHER:
if( flag&SD_ANIMATION ) // the surrounding targets
- dmg.dmotion = clif->skill_damage(dsrc,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skill_id, -1, 5); // needs -1 as skill level
+ dmg.dmotion = clif->skill_damage(dsrc,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skill_id, -1, BDT_SPLASH); // needs -1 as skill level
else // the central target doesn't display an animation
- dmg.dmotion = clif->skill_damage(dsrc,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skill_id, -2, 5); // needs -2(!) as skill level
+ dmg.dmotion = clif->skill_damage(dsrc,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skill_id, -2, BDT_SPLASH); // needs -2(!) as skill level
break;
case WL_HELLINFERNO:
case SR_EARTHSHAKER:
- dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,1,skill_id,-2,6);
+ dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,1,skill_id,-2,BDT_SKILL);
break;
case KO_MUCHANAGE:
if( dmg.dmg_lv == ATK_FLEE )
@@ -2457,17 +2475,17 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr
case WL_SOULEXPANSION:
case WL_COMET:
case NJ_HUUMA:
- dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,skill_id,skill_lv,8);
+ dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,skill_id,skill_lv,BDT_MULTIHIT);
break;
case WL_CHAINLIGHTNING_ATK:
- dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,1,WL_CHAINLIGHTNING,-2,6);
+ dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,1,WL_CHAINLIGHTNING,-2,BDT_SKILL);
break;
case LG_OVERBRAND_BRANDISH:
case LG_OVERBRAND:
/* Fall through */
dmg.amotion = status_get_amotion(src) * 2;
case LG_OVERBRAND_PLUSATK:
- dmg.dmotion = clif->skill_damage(dsrc,bl,tick,status_get_amotion(src),dmg.dmotion,damage,dmg.div_,skill_id,-1,5);
+ dmg.dmotion = clif->skill_damage(dsrc,bl,tick,status_get_amotion(src),dmg.dmotion,damage,dmg.div_,skill_id,-1,BDT_SPLASH);
break;
case EL_FIRE_BOMB:
case EL_FIRE_BOMB_ATK:
@@ -2490,29 +2508,29 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr
case GN_CRAZYWEED_ATK:
case KO_BAKURETSU:
case NC_MAGMA_ERUPTION:
- dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,skill_id,-1,5);
+ dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,skill_id,-1,BDT_SPLASH);
break;
case GN_SLINGITEM_RANGEMELEEATK:
- dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,GN_SLINGITEM,-2,6);
+ dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,GN_SLINGITEM,-2,BDT_SKILL);
break;
case SC_FEINTBOMB:
- dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,1,skill_id,skill_lv,5);
+ dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,1,skill_id,skill_lv,BDT_SPLASH);
break;
case EL_STONE_RAIN:
- dmg.dmotion = clif->skill_damage(dsrc,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,skill_id,-1,(flag&1)?8:5);
+ dmg.dmotion = clif->skill_damage(dsrc,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,skill_id,-1,(flag&1)?BDT_MULTIHIT:BDT_SPLASH);
break;
case WM_SEVERE_RAINSTORM_MELEE:
- dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,WM_SEVERE_RAINSTORM,-2,6);
+ dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,WM_SEVERE_RAINSTORM,-2,BDT_SPLASH);
break;
case WM_REVERBERATION_MELEE:
case WM_REVERBERATION_MAGIC:
- dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,WM_REVERBERATION,-2,6);
+ dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,WM_REVERBERATION,-2,BDT_SKILL);
break;
case WL_TETRAVORTEX_FIRE:
case WL_TETRAVORTEX_WATER:
case WL_TETRAVORTEX_WIND:
case WL_TETRAVORTEX_GROUND:
- dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_, WL_TETRAVORTEX,-1,5);
+ dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_, WL_TETRAVORTEX,-1,BDT_SPLASH);
break;
case HT_CLAYMORETRAP:
case HT_BLASTMINE:
@@ -2521,14 +2539,17 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr
case RA_CLUSTERBOMB:
case RA_FIRINGTRAP:
case RA_ICEBOUNDTRAP:
- dmg.dmotion = clif->skill_damage(src,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skill_id, (flag&SD_LEVEL) ? -1 : skill_lv, 5);
+ dmg.dmotion = clif->skill_damage(src,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skill_id, (flag&SD_LEVEL) ? -1 : skill_lv, BDT_SPLASH);
if( dsrc != src ) // avoid damage display redundancy
break;
case HT_LANDMINE:
dmg.dmotion = clif->skill_damage(dsrc,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skill_id, -1, type);
break;
+ case HW_GRAVITATION:
+ dmg.dmotion = clif->damage(bl, bl, 0, 0, damage, 1, BDT_ENDURE, 0);
+ break;
case WZ_SIGHTBLASTER:
- dmg.dmotion = clif->skill_damage(src,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skill_id, (flag&SD_LEVEL) ? -1 : skill_lv, 5);
+ dmg.dmotion = clif->skill_damage(src,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skill_id, (flag&SD_LEVEL) ? -1 : skill_lv, BDT_SPLASH);
break;
case AB_DUPLELIGHT_MELEE:
case AB_DUPLELIGHT_MAGIC:
@@ -2610,6 +2631,7 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr
tsd->status.skill[cidx].flag = SKILL_FLAG_PLAGIARIZED;
clif->addskill(tsd,copy_skill);
} else {
+ int plagiarismlvl;
lv = skill_lv;
if ( tsd->cloneskill_id ) {
idx = skill->get_index(tsd->cloneskill_id);
@@ -2621,8 +2643,8 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr
}
}
- if ((type = pc->checkskill(tsd,RG_PLAGIARISM)) < lv)
- lv = type;
+ if ((plagiarismlvl = pc->checkskill(tsd,RG_PLAGIARISM)) < lv)
+ lv = plagiarismlvl;
tsd->cloneskill_id = copy_skill;
pc_setglobalreg(tsd, script->add_str("CLONE_SKILL"), copy_skill);
@@ -2693,7 +2715,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
@@ -2738,12 +2760,12 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr
) && check_distance_bl(bl, d_bl, sce->val3) )
{
if(!rmdamage){
- clif->damage(d_bl,d_bl, 0, 0, damage, 0, 0, 0);
+ clif->damage(d_bl,d_bl, 0, 0, damage, 0, BDT_NORMAL, 0);
status_fix_damage(NULL,d_bl, damage, 0);
} else{ //Reflected magics are done directly on the target not on paladin
//This check is only for magical skill.
//For BF_WEAPON skills types track var rdamage and function battle_calc_return_damage
- clif->damage(bl,bl, 0, 0, damage, 0, 0, 0);
+ clif->damage(bl,bl, 0, 0, damage, 0, BDT_NORMAL, 0);
status_fix_damage(bl,bl, damage, 0);
}
}
@@ -2837,11 +2859,11 @@ void skill_attack_combo2_unknown(int *attack_type, struct block_list* src, struc
void skill_attack_display_unknown(int *attack_type, struct block_list* src, struct block_list *dsrc, struct block_list *bl, uint16 *skill_id, uint16 *skill_lv, int64 *tick, int *flag, int *type, struct Damage *dmg, int64 *damage) {
if (*flag & SD_ANIMATION && dmg->div_ < 2) //Disabling skill animation doesn't works on multi-hit.
- *type = 5;
+ *type = BDT_SPLASH;
if (bl->type == BL_SKILL ) {
TBL_SKILL *su = (TBL_SKILL*)bl;
if (su->group && skill->get_inf2(su->group->skill_id) & INF2_TRAP) // show damage on trap targets
- clif->skill_damage(src, bl, *tick, dmg->amotion, dmg->dmotion, *damage, dmg->div_, *skill_id, (*flag & SD_LEVEL) ? -1 : *skill_lv, 5);
+ clif->skill_damage(src, bl, *tick, dmg->amotion, dmg->dmotion, *damage, dmg->div_, *skill_id, (*flag & SD_LEVEL) ? -1 : *skill_lv, BDT_SPLASH);
}
dmg->dmotion = clif->skill_damage(dsrc, bl, *tick, dmg->amotion, dmg->dmotion, *damage, dmg->div_, *skill_id, (*flag & SD_LEVEL) ? -1 : *skill_lv, *type);
}
@@ -2890,7 +2912,7 @@ int skill_area_sub(struct block_list *bl, va_list ap) {
if(battle->check_target(src,bl,flag) > 0) {
// several splash skills need this initial dummy packet to display correctly
if (flag&SD_PREAMBLE && skill->area_temp[2] == 0)
- clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
+ clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL);
if (flag&(SD_SPLASH|SD_PREAMBLE))
skill->area_temp[2]++;
@@ -3065,15 +3087,15 @@ int skill_check_condition_mercenary(struct block_list *bl, int skill_id, int lv,
// Requirements
for( i = 0; i < ARRAYLENGTH(itemid); i++ )
{
- itemid[i] = skill->db[idx].itemid[i];
- amount[i] = skill->db[idx].amount[i];
- }
- hp = skill->db[idx].hp[lv-1];
- sp = skill->db[idx].sp[lv-1];
- hp_rate = skill->db[idx].hp_rate[lv-1];
- sp_rate = skill->db[idx].sp_rate[lv-1];
- state = skill->db[idx].state;
- if( (mhp = skill->db[idx].mhp[lv-1]) > 0 )
+ itemid[i] = skill->dbs->db[idx].itemid[i];
+ amount[i] = skill->dbs->db[idx].amount[i];
+ }
+ hp = skill->dbs->db[idx].hp[lv-1];
+ sp = skill->dbs->db[idx].sp[lv-1];
+ hp_rate = skill->dbs->db[idx].hp_rate[lv-1];
+ sp_rate = skill->dbs->db[idx].sp_rate[lv-1];
+ state = skill->dbs->db[idx].state;
+ if( (mhp = skill->dbs->db[idx].mhp[lv-1]) > 0 )
hp += (st->max_hp * mhp) / 100;
if( hp_rate > 0 )
hp += (st->hp * hp_rate) / 100;
@@ -3135,7 +3157,7 @@ int skill_check_condition_mercenary(struct block_list *bl, int skill_id, int lv,
// Consume items
for (i = 0; i < ARRAYLENGTH(itemid); i++) {
if (index[i] != INDEX_NOT_FOUND)
- pc->delitem(sd, index[i], amount[i], 0, 1, LOG_TYPE_CONSUME);
+ pc->delitem(sd, index[i], amount[i], 0, DELITEM_SKILLUSE, LOG_TYPE_CONSUME);
}
if( type&2 )
@@ -3315,7 +3337,7 @@ int skill_timerskill(int tid, int64 tick, int id, intptr_t data) {
break;
case SC_ESCAPE:
if( skl->type < 4+skl->skill_lv ){
- clif->skill_damage(src,src,tick,0,0,-30000,1,skl->skill_id,skl->skill_lv,5);
+ clif->skill_damage(src,src,tick,0,0,-30000,1,skl->skill_id,skl->skill_lv,BDT_SPLASH);
skill->blown(src,src,1,unit->getdir(src),0);
skill->addtimerskill(src,tick+80,src->id,0,0,skl->skill_id,skl->skill_lv,skl->type+1,0);
}
@@ -3814,9 +3836,16 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
if( dir > 2 && dir < 6 ) y = -i;
else if( dir == 7 || dir < 2 ) y = i;
else y = 0;
- if( (mbl == src || (!map_flag_gvg2(src->m) && !map->list[src->m].flag.battleground) ) // only NJ_ISSEN don't have slide effect in GVG
- && unit->movepos(src, mbl->x+x, mbl->y+y, 1, 1)
- ) {
+ if ((mbl == src || (!map_flag_gvg2(src->m) && !map->list[src->m].flag.battleground))) { // only NJ_ISSEN don't have slide effect in GVG
+ if (!(unit->movepos(src, mbl->x+x, mbl->y+y, 1, 1))) {
+ // The cell is not reachable (wall, object, ...), move next to the target
+ if (x > 0) x = -1;
+ else if (x < 0) x = 1;
+ if (y > 0) y = -1;
+ else if (y < 0) y = 1;
+
+ unit->movepos(src, bl->x+x, bl->y+y, 1, 1);
+ }
clif->slide(src, src->x, src->y);
clif->fixpos(src);
clif->spiritball(src);
@@ -3914,7 +3943,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
/* Fall through */
case LG_MOONSLASHER:
case MH_XENO_SLASHER:
- clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
+ clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL);
break;
default:
break;
@@ -3946,7 +3975,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
case MS_MAGNUM:
if( flag&1 ) {
//Damage depends on distance, so add it to flag if it is > 1
- skill->attack(skill->get_type(skill_id), src, src, bl, skill_id, skill_lv, tick, flag|distance_bl(src, bl));
+ skill->attack(skill->get_type(skill_id), src, src, bl, skill_id, skill_lv, tick, flag|SD_ANIMATION|distance_bl(src, bl));
}
break;
@@ -4069,7 +4098,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
break;
case CH_PALMSTRIKE: // Palm Strike takes effect 1sec after casting. [Skotlex]
//clif->skill_nodamage(src,bl,skill_id,skill_lv,0); //Can't make this one display the correct attack animation delay :/
- clif->damage(src,bl,status_get_amotion(src),0,-1,1,4,0); //Display an absorbed damage attack.
+ clif->damage(src,bl,status_get_amotion(src),0,-1,1,BDT_ENDURE,0); //Display an absorbed damage attack.
skill->addtimerskill(src, tick + (1000+status_get_amotion(src)), bl->id, 0, 0, skill_id, skill_lv, BF_WEAPON, flag);
break;
@@ -4523,7 +4552,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER); // Need confirm it.
} else {
map->foreachinrange(skill->area_sub, bl, skill->get_splash(skill_id, skill_lv), splash_target(src), src, skill_id, skill_lv, tick, flag|BCT_ENEMY|SD_SPLASH|1, skill->castend_damage_id);
- clif->skill_damage(src,src,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
+ clif->skill_damage(src,src,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL);
if( sd ) pc->overheat(sd,1);
}
break;
@@ -4542,7 +4571,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
skill->area_temp[5] = y;
map->foreachinrange(skill->area_sub, bl, skill->get_splash(skill_id, skill_lv), splash_target(src), src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1, skill->castend_damage_id);
skill->addtimerskill(src,tick + 800,src->id,x,y,skill_id,skill_lv,0,flag); // To teleport Self
- clif->skill_damage(src,src,tick,status_get_amotion(src),0,-30000,1,skill_id,skill_lv,6);
+ clif->skill_damage(src,src,tick,status_get_amotion(src),0,-30000,1,skill_id,skill_lv,BDT_SKILL);
}
break;
case LG_PINPOINTATTACK:
@@ -4581,14 +4610,12 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
status_change_end(bl, SC_RUSH_WINDMILL, INVALID_TIMER);
status_change_end(bl, SC_ECHOSONG, INVALID_TIMER);
status_change_end(bl, SC_HARMONIZE, INVALID_TIMER);
+ status_change_end(bl, SC_NETHERWORLD, INVALID_TIMER);
status_change_end(bl, SC_SIREN, INVALID_TIMER);
- status_change_end(bl, SC_DEEP_SLEEP, INVALID_TIMER);
- status_change_end(bl, SC_SIRCLEOFNATURE, INVALID_TIMER);
status_change_end(bl, SC_GLOOMYDAY, INVALID_TIMER);
status_change_end(bl, SC_SONG_OF_MANA, INVALID_TIMER);
status_change_end(bl, SC_DANCE_WITH_WUG, INVALID_TIMER);
status_change_end(bl, SC_SATURDAY_NIGHT_FEVER, INVALID_TIMER);
- status_change_end(bl, SC_LERADS_DEW, INVALID_TIMER);
status_change_end(bl, SC_MELODYOFSINK, INVALID_TIMER);
status_change_end(bl, SC_BEYOND_OF_WARCRY, INVALID_TIMER);
status_change_end(bl, SC_UNLIMITED_HUMMING_VOICE, INVALID_TIMER);
@@ -4602,7 +4629,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER);
} else{
map->foreachinrange(skill->area_sub, bl, skill->get_splash(skill_id, skill_lv), splash_target(src), src, skill_id, skill_lv, tick, flag|BCT_ENEMY|SD_SPLASH|1, skill->castend_damage_id);
- clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
+ clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL);
}
break;
@@ -4669,7 +4696,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
else {
int i = skill->get_splash(skill_id,skill_lv);
clif->skill_nodamage(src,battle->get_master(src),skill_id,skill_lv,1);
- clif->skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
+ clif->skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL);
if( rnd()%100 < 30 )
map->foreachinrange(skill->area_sub,bl,i,BL_CHAR,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill->castend_damage_id);
else
@@ -4679,7 +4706,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
case EL_ROCK_CRUSHER:
clif->skill_nodamage(src,battle->get_master(src),skill_id,skill_lv,1);
- clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
+ clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL);
if( rnd()%100 < 50 )
skill->attack(BF_MAGIC,src,src,bl,skill_id,skill_lv,tick,flag);
else
@@ -4692,7 +4719,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
else {
int i = skill->get_splash(skill_id,skill_lv);
clif->skill_nodamage(src,battle->get_master(src),skill_id,skill_lv,1);
- clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
+ clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL);
if( rnd()%100 < 30 )
map->foreachinrange(skill->area_sub,bl,i,BL_CHAR,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill->castend_damage_id);
else
@@ -4705,7 +4732,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
case EL_WIND_SLASH:
case EL_STONE_HAMMER:
clif->skill_nodamage(src,battle->get_master(src),skill_id,skill_lv,1);
- clif->skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
+ clif->skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL);
skill->attack(skill->get_type(skill_id),src,src,bl,skill_id,skill_lv,tick,flag);
break;
@@ -4718,7 +4745,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
type2 = type-1;
clif->skill_nodamage(src,battle->get_master(src),skill_id,skill_lv,1);
- clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
+ clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL);
if( (esc && esc->data[type2]) || (tsc && tsc->data[type]) ) {
elemental->clean_single_effect(ele, skill_id);
}
@@ -4855,7 +4882,7 @@ int skill_castend_id(int tid, int64 tick, int id, intptr_t data) {
if( sd && ud->skilltimer != INVALID_TIMER && (pc->checkskill(sd,SA_FREECAST) > 0 || ud->skill_id == LG_EXEEDBREAK) )
{// restore original walk speed
ud->skilltimer = INVALID_TIMER;
- status_calc_bl(&sd->bl, SCB_SPEED);
+ status_calc_bl(&sd->bl, SCB_SPEED|SCB_ASPD);
}
ud->skilltimer = INVALID_TIMER;
@@ -5021,7 +5048,7 @@ int skill_castend_id(int tid, int64 tick, int id, intptr_t data) {
}
if (ud->walktimer != INVALID_TIMER && ud->skill_id != TK_RUN && ud->skill_id != RA_WUGDASH)
- unit->stop_walking(src,1);
+ unit->stop_walking(src, STOPWALKING_FLAG_FIXPOS);
if( !sd || sd->skillitem != ud->skill_id || skill->get_delay(ud->skill_id,ud->skill_lv) )
ud->canact_tick = tick + skill->delay_fix(src, ud->skill_id, ud->skill_lv); // Tests show wings don't overwrite the delay but skill scrolls do. [Inkfish]
@@ -5141,9 +5168,9 @@ int skill_castend_id(int tid, int64 tick, int id, intptr_t data) {
}
}
- ud->skill_id = ud->skill_lv = ud->skilltarget = 0;
if( !sd || sd->skillitem != ud->skill_id || skill->get_delay(ud->skill_id,ud->skill_lv) )
ud->canact_tick = tick;
+ ud->skill_id = ud->skill_lv = ud->skilltarget = 0;
//You can't place a skill failed packet here because it would be
//sent in ALL cases, even cases where skill_check_condition fails
//which would lead to double 'skill failed' messages u.u [Skotlex]
@@ -5512,10 +5539,10 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
int abra_skill_id = 0, abra_skill_lv, abra_idx;
do {
abra_idx = rnd() % MAX_SKILL_ABRA_DB;
- abra_skill_id = skill->abra_db[abra_idx].skill_id;
+ abra_skill_id = skill->dbs->abra_db[abra_idx].skill_id;
} while (abra_skill_id == 0 ||
- skill->abra_db[abra_idx].req_lv > skill_lv || //Required lv for it to appear
- rnd()%10000 >= skill->abra_db[abra_idx].per
+ skill->dbs->abra_db[abra_idx].req_lv > skill_lv || //Required lv for it to appear
+ rnd()%10000 >= skill->dbs->abra_db[abra_idx].per
);
abra_skill_lv = min(skill_lv, skill->get_max(abra_skill_id));
clif->skill_nodamage (src, bl, skill_id, skill_lv, 1);
@@ -6081,7 +6108,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
}
i = 0;
- count = (sd)? min(skill_lv,5) : 1; // Mercenary only can Devote owner
+ count = (sd)? min(skill_lv,MAX_PC_DEVOTION) : 1; // Mercenary only can Devote owner
if( sd )
{ // Player Devoting Player
ARR_FIND(0, count, i, sd->devotion[i] == bl->id );
@@ -6109,22 +6136,17 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
case MO_CALLSPIRITS:
if(sd) {
- int limit = skill_lv;
- if( sd->sc.data[SC_RAISINGDRAGON] )
- limit += sd->sc.data[SC_RAISINGDRAGON]->val1;
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
- pc->addspiritball(sd,skill->get_time(skill_id,skill_lv),limit);
+ pc->addspiritball(sd, skill->get_time(skill_id, skill_lv), pc->getmaxspiritball(sd, 0));
}
break;
case CH_SOULCOLLECT:
if(sd) {
- int limit = 5, i;
- if( sd->sc.data[SC_RAISINGDRAGON] )
- limit += sd->sc.data[SC_RAISINGDRAGON]->val1;
+ int i, limit = pc->getmaxspiritball(sd, 5);
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
- for (i = 0; i < limit; i++)
- pc->addspiritball(sd,skill->get_time(skill_id,skill_lv),limit);
+ for ( i = 0; i < limit; i++ )
+ pc->addspiritball(sd, skill->get_time(skill_id, skill_lv), limit);
}
break;
@@ -6146,7 +6168,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
{
int sp = 0;
if ( dstsd && dstsd->spiritball
- && (sd == dstsd || map_flag_vs(src->m) || (sd->duel_group && sd->duel_group == dstsd->duel_group))
+ && (sd == dstsd || map_flag_vs(src->m) || (sd && sd->duel_group && sd->duel_group == dstsd->duel_group))
&& ((dstsd->class_&MAPID_BASEMASK) != MAPID_GUNSLINGER || (dstsd->class_&MAPID_UPPERMASK) != MAPID_REBELLION)
) {
// split the if for readability, and included gunslingers in the check so that their coins cannot be removed [Reddozen]
@@ -6216,7 +6238,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
count = map->foreachinrange(skill->area_sub, bl, skill->get_splash(skill_id, skill_lv), splash_target(src),
src, skill_id, skill_lv, tick, flag|BCT_ENEMY|SD_SPLASH|1, skill->castend_damage_id);
if( !count && ( skill_id == NC_AXETORNADO || skill_id == SR_SKYNETBLOW || skill_id == KO_HAPPOKUNAI ) )
- clif->skill_damage(src,src,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
+ clif->skill_damage(src,src,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL);
}
break;
@@ -6268,7 +6290,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
{
//Self Destruction hits everyone in range (allies+enemies)
//Except for Summoned Marine spheres on non-versus maps, where it's just enemy.
- int targetmask = ((!md || md->special_state.ai == 2) && !map_flag_vs(src->m))?
+ int targetmask = ((!md || md->special_state.ai == AI_SPHERE) && !map_flag_vs(src->m))?
BCT_ENEMY:BCT_ALL;
clif->skill_nodamage(src, src, skill_id, -1, 1);
map->delblock(src); //Required to prevent chain-self-destructions hitting back.
@@ -6439,7 +6461,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
// custom hack to make the mob display the skill, because these skills don't show the skill use text themselves
//NOTE: mobs don't have the sprite animation that is used when performing this skill (will cause glitches)
char temp[70];
- snprintf(temp, sizeof(temp), "%s : %s !!",md->name,skill->db[skill_id].desc);
+ snprintf(temp, sizeof(temp), "%s : %s !!",md->name,skill->dbs->db[skill_id].desc);
clif->disp_overhead(&md->bl,temp);
}
break;
@@ -6554,6 +6576,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
status_change_end(bl, SC_STUN, INVALID_TIMER);
status_change_end(bl, SC_WHITEIMPRISON, INVALID_TIMER);
}
+ status_change_end(bl, SC_NETHERWORLD, INVALID_TIMER);
//Is this equation really right? It looks so... special.
if( battle->check_undead(tstatus->race,tstatus->def_ele) ) {
status->change_start(src, bl, SC_BLIND,
@@ -6636,7 +6659,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
return 1;
}
if( sd->skillitem != skill_id )
- status_zap(src,0,skill->db[skill->get_index(skill_id)].sp[skill_lv]); // consume sp only if succeeded
+ status_zap(src,0,skill->dbs->db[skill->get_index(skill_id)].sp[skill_lv]); // consume sp only if succeeded
}
break;
@@ -6814,13 +6837,13 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
if( sd ) {
int x,bonus=100, potion = min(500+skill_lv,505);
x = skill_lv%11 - 1;
- i = pc->search_inventory(sd,skill->db[skill_id].itemid[x]);
- if (i == INDEX_NOT_FOUND || skill->db[skill_id].itemid[x] <= 0) {
+ i = pc->search_inventory(sd,skill->dbs->db[skill_id].itemid[x]);
+ if (i == INDEX_NOT_FOUND || skill->dbs->db[skill_id].itemid[x] <= 0) {
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
map->freeblock_unlock();
return 1;
}
- if(sd->inventory_data[i] == NULL || sd->status.inventory[i].amount < skill->db[skill_id].amount[x]) {
+ if(sd->inventory_data[i] == NULL || sd->status.inventory[i].amount < skill->dbs->db[skill_id].amount[x]) {
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
map->freeblock_unlock();
return 1;
@@ -6917,44 +6940,24 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
}
break;
case AM_CP_WEAPON:
- if(dstsd && dstsd->inventory_data[dstsd->equip_index[EQI_HAND_R]])
- clif->skill_nodamage(src,bl,skill_id,skill_lv,
- sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
- else {
- clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- break;
- case AM_CP_SHIELD: {
- int i;
- if(dstsd && (i=dstsd->equip_index[EQI_HAND_L])>=0 && dstsd->inventory_data[i] &&
- dstsd->inventory_data[i]->type==IT_ARMOR)
- clif->skill_nodamage(src,bl,skill_id,skill_lv,
- sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
- else {
- clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- }
- break;
+ case AM_CP_SHIELD:
case AM_CP_ARMOR:
- if(dstsd && dstsd->inventory_data[dstsd->equip_index[EQI_ARMOR]])
- clif->skill_nodamage(src,bl,skill_id,skill_lv,
- sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
- else {
- clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- break;
case AM_CP_HELM:
- if(dstsd && dstsd->inventory_data[dstsd->equip_index[EQI_HEAD_TOP]])
- clif->skill_nodamage(src,bl,skill_id,skill_lv,
- sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
- else {
- clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
+ {
+ unsigned int equip[] = { EQP_WEAPON, EQP_SHIELD, EQP_ARMOR, EQP_HEAD_TOP };
+ int index;
+ if ( sd && (bl->type != BL_PC || (dstsd && pc->checkequip(dstsd, equip[skill_id - AM_CP_WEAPON]) < 0) ||
+ (dstsd && equip[skill_id - AM_CP_WEAPON] == EQP_SHIELD && pc->checkequip(dstsd, EQP_SHIELD) > 0
+ && (index = dstsd->equip_index[EQI_HAND_L]) >= 0 && dstsd->inventory_data[index]
+ && dstsd->inventory_data[index]->type != IT_ARMOR)) ) {
+ clif->skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0);
+ map->freeblock_unlock(); // Don't consume item requirements
return 0;
}
+ clif->skill_nodamage(src, bl, skill_id, skill_lv,
+ sc_start(src, bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv)));
break;
+ }
case AM_TWILIGHT1:
if (sd) {
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
@@ -7382,14 +7385,14 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
case WE_MALE:
{
- int hp_rate = (!skill_lv)? 0:skill->db[skill_id].hp_rate[skill_lv-1];
+ int hp_rate = (!skill_lv)? 0:skill->dbs->db[skill_id].hp_rate[skill_lv-1];
int gain_hp = tstatus->max_hp*abs(hp_rate)/100; // The earned is the same % of the target HP than it cost the caster. [Skotlex]
clif->skill_nodamage(src,bl,skill_id,status->heal(bl, gain_hp, 0, 0),1);
}
break;
case WE_FEMALE:
{
- int sp_rate = (!skill_lv)? 0:skill->db[skill_id].sp_rate[skill_lv-1];
+ int sp_rate = (!skill_lv)? 0:skill->dbs->db[skill_id].sp_rate[skill_lv-1];
int gain_sp = tstatus->max_sp*abs(sp_rate)/100;// The earned is the same % of the target SP than it cost the caster. [Skotlex]
clif->skill_nodamage(src,bl,skill_id,status->heal(bl, 0, gain_sp, 0),1);
}
@@ -7453,15 +7456,15 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
int i;
// get back all items used to deploy the trap
for( i = 0; i < 10; i++ ) {
- if( skill->db[su->group->skill_id].itemid[i] > 0 ) {
+ if( skill->dbs->db[su->group->skill_id].itemid[i] > 0 ) {
int success;
struct item item_tmp;
memset(&item_tmp,0,sizeof(item_tmp));
- item_tmp.nameid = skill->db[su->group->skill_id].itemid[i];
+ item_tmp.nameid = skill->dbs->db[su->group->skill_id].itemid[i];
item_tmp.identify = 1;
- if( item_tmp.nameid && (success=pc->additem(sd,&item_tmp,skill->db[su->group->skill_id].amount[i],LOG_TYPE_OTHER)) ) {
+ if( item_tmp.nameid && (success=pc->additem(sd,&item_tmp,skill->dbs->db[su->group->skill_id].amount[i],LOG_TYPE_OTHER)) ) {
clif->additem(sd,0,0,success);
- map->addflooritem(&item_tmp,skill->db[su->group->skill_id].amount[i],sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
+ map->addflooritem(&item_tmp,skill->dbs->db[su->group->skill_id].amount[i],sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
}
}
}
@@ -7638,28 +7641,27 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
}
break;
// Full Chemical Protection
- case CR_FULLPROTECTION: {
- bool iused=false;
- int i;
- if(dstsd && dstsd->inventory_data[dstsd->equip_index[EQI_HAND_R]]) {
- iused=true;
- clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start(src,bl,SC_PROTECTWEAPON,100,skill_lv,skill->get_time(skill_id,skill_lv)));
- } if(dstsd && (i=dstsd->equip_index[EQI_HAND_L])>=0 && dstsd->inventory_data[i] &&
- dstsd->inventory_data[i]->type==IT_ARMOR) {
- iused=true;
- clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start(src,bl,SC_PROTECTSHIELD,100,skill_lv,skill->get_time(skill_id,skill_lv)));
- } if(dstsd && dstsd->inventory_data[dstsd->equip_index[EQI_ARMOR]]) {
- iused=true;
- clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start(src,bl,SC_PROTECTARMOR,100,skill_lv,skill->get_time(skill_id,skill_lv)));
- } if(dstsd && dstsd->inventory_data[dstsd->equip_index[EQI_HEAD_TOP]]) {
- iused=true;
- clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start(src,bl,SC_PROTECTHELM,100,skill_lv,skill->get_time(skill_id,skill_lv)));
- } if(iused)
- clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
- else {
- clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
+ case CR_FULLPROTECTION:
+ {
+ unsigned int equip[] = { EQP_WEAPON, EQP_SHIELD, EQP_ARMOR, EQP_HEAD_TOP };
+ int i, s = 0, skilltime = skill->get_time(skill_id, skill_lv);
+ for ( i = 0; i < 4; i++ ) {
+ if ( bl->type != BL_PC || (dstsd && pc->checkequip(dstsd, equip[i]) < 0) )
+ continue;
+ if ( dstsd && equip[i] == EQP_SHIELD ) {
+ short index = dstsd->equip_index[EQI_HAND_L];
+ if ( index >= 0 && dstsd->inventory_data[index] && dstsd->inventory_data[index]->type != IT_ARMOR )
+ continue;
+ }
+ sc_start(src, bl, (sc_type)(SC_PROTECTWEAPON + i), 100, skill_lv, skilltime);
+ s++;
+ }
+ if ( sd && !s ) {
+ clif->skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0);
+ map->freeblock_unlock(); // Don't consume item requirements
return 0;
}
+ clif->skill_nodamage(src, bl, skill_id, skill_lv, 1);
}
break;
@@ -7692,7 +7694,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
map->freeblock_unlock();
return 0;
}
- status_zap(src,0,skill->db[skill->get_index(skill_id)].sp[skill_lv]); // consume sp only if succeeded [Inkfish]
+ status_zap(src,0,skill->dbs->db[skill->get_index(skill_id)].sp[skill_lv]); // consume sp only if succeeded [Inkfish]
do {
int eff = rnd() % 14;
if( eff == 5 )
@@ -7713,7 +7715,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
case 3: // 1000 damage, random armor destroyed
{
status_fix_damage(src, bl, 1000, 0);
- clif->damage(src,bl,0,0,1000,0,0,0);
+ clif->damage(src,bl,0,0,1000,0,BDT_NORMAL,0);
if( !status->isdead(bl) ) {
int where[] = { EQP_ARMOR, EQP_SHIELD, EQP_HELM, EQP_SHOES, EQP_GARMENT };
skill->break_equip(bl, where[rnd()%5], 10000, BCT_ENEMY);
@@ -7750,14 +7752,14 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
break;
case 10: // 6666 damage, atk matk halved, cursed
status_fix_damage(src, bl, 6666, 0);
- clif->damage(src,bl,0,0,6666,0,0,0);
+ clif->damage(src,bl,0,0,6666,0,BDT_NORMAL,0);
sc_start(src,bl,SC_INCATKRATE,100,-50,skill->get_time2(skill_id,skill_lv));
sc_start(src,bl,SC_INCMATKRATE,100,-50,skill->get_time2(skill_id,skill_lv));
sc_start(src,bl,SC_CURSE,skill_lv,100,skill->get_time2(skill_id,skill_lv));
break;
case 11: // 4444 damage
status_fix_damage(src, bl, 4444, 0);
- clif->damage(src,bl,0,0,4444,0,0,0);
+ clif->damage(src,bl,0,0,4444,0,BDT_NORMAL,0);
break;
case 12: // stun
sc_start(src,bl,SC_STUN,100,skill_lv,5000);
@@ -8135,7 +8137,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
case LG_EARTHDRIVE:
{
int splash;
- clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
+ clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL);
splash = skill->get_splash(skill_id,skill_lv);
if( skill_id == LG_EARTHDRIVE ) {
int dummy = 1;
@@ -8316,7 +8318,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
case GC_PHANTOMMENACE:
{
int r;
- clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
+ clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL);
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
r = skill->get_splash(skill_id, skill_lv);
map->foreachinrange(skill->area_sub,src,skill->get_splash(skill_id,skill_lv),BL_CHAR,
@@ -8612,7 +8614,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
* Ranger
**/
case RA_FEARBREEZE:
- clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
+ clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL);
clif->skill_nodamage(src, bl, skill_id, skill_lv, sc_start(src, bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv)));
break;
@@ -8653,7 +8655,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
case RA_SENSITIVEKEEN:
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
- clif->skill_damage(src,src,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
+ clif->skill_damage(src,src,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL);
map->foreachinrange(skill->area_sub,src,skill->get_splash(skill_id,skill_lv),BL_CHAR|BL_SKILL,src,skill_id,skill_lv,tick,flag|BCT_ENEMY,skill->castend_damage_id);
break;
/**
@@ -8680,7 +8682,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
break;
case NC_ANALYZE:
- clif->skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
+ clif->skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL);
clif->skill_nodamage(src, bl, skill_id, skill_lv,
sc_start(src,bl,type, 30 + 12 * skill_lv,skill_lv,skill->get_time(skill_id,skill_lv)));
if( sd ) pc->overheat(sd,1);
@@ -8692,7 +8694,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
if( (failure = sc_start2(src,bl,type,100,skill_lv,src->id,skill->get_time(skill_id,skill_lv))) )
{
map->foreachinrange(skill->area_sub,src,skill->get_splash(skill_id,skill_lv),splash_target(src),src,skill_id,skill_lv,tick,flag|BCT_ENEMY|SD_SPLASH|1,skill->castend_damage_id);;
- clif->skill_damage(src,src,tick,status_get_amotion(src),0,-30000,1,skill_id,skill_lv,6);
+ clif->skill_damage(src,src,tick,status_get_amotion(src),0,-30000,1,skill_id,skill_lv,BDT_SKILL);
if (sd) pc->overheat(sd,1);
}
clif->skill_nodamage(src,src,skill_id,skill_lv,failure);
@@ -8812,7 +8814,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
break;
case LG_TRAMPLE:
- clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
+ clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL);
map->foreachinrange(skill->destroy_trap,bl,skill->get_splash(skill_id,skill_lv),BL_SKILL,tick);
break;
@@ -8850,7 +8852,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
switch( opt ) {
case 1:
sc_start(src,bl,SC_SHIELDSPELL_DEF,100,opt,INVALID_TIMER); //Splash AoE ATK
- clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
+ clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL);
map->foreachinrange(skill->area_sub,src,splashrange,BL_CHAR,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill->castend_damage_id);
status_change_end(bl,SC_SHIELDSPELL_DEF,INVALID_TIMER);
break;
@@ -8877,13 +8879,13 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
switch( opt ) {
case 1:
sc_start(src,bl,SC_SHIELDSPELL_MDEF,100,opt,INVALID_TIMER); //Splash AoE MATK
- clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
+ clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL);
map->foreachinrange(skill->area_sub,src,splashrange,BL_CHAR,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill->castend_damage_id);
status_change_end(bl,SC_SHIELDSPELL_MDEF,INVALID_TIMER);
break;
case 2:
sc_start(src,bl,SC_SHIELDSPELL_MDEF,100,opt,sd->bonus.shieldmdef * 2000); //Splash AoE Lex Divina
- clif->skill_damage(src,bl,tick,status_get_amotion(src),0,-30000,1,skill_id,skill_lv,6);
+ clif->skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL);
map->foreachinrange(skill->area_sub,src,splashrange,BL_CHAR,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill->castend_nodamage_id);
break;
case 3:
@@ -8996,7 +8998,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
}
} else {
int count = 0;
- clif->skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
+ clif->skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL);
count = map->forcountinrange(skill->area_sub, src, skill->get_splash(skill_id,skill_lv), (sd)?sd->spiritball_old:15, // Assume 15 spiritballs in non-characters
BL_CHAR, src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1, skill->castend_nodamage_id);
if( sd ) pc->delspiritball(sd, count, 0);
@@ -9006,13 +9008,14 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
break;
case SR_RAISINGDRAGON:
- if( sd ) {
- short max = 5 + skill_lv;
- int i;
+ if ( sd ) {
+ int i, max;
sc_start(src, bl, SC_EXPLOSIONSPIRITS, 100, skill_lv, skill->get_time(skill_id, skill_lv));
- for( i = 0; i < max; i++ ) // Don't call more than max available spheres.
- pc->addspiritball(sd, skill->get_time(skill_id, skill_lv), max);
- clif->skill_nodamage(src, bl, skill_id, skill_lv, sc_start(src, bl, type, 100, skill_lv,skill->get_time(skill_id, skill_lv)));
+ clif->skill_nodamage(src, bl, skill_id, skill_lv,
+ sc_start(src, bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv)));
+ max = pc->getmaxspiritball(sd, 0);
+ for ( i = 0; i < max; i++ )
+ pc->addspiritball(sd, skill->get_time(MO_CALLSPIRITS, skill_lv), max);
}
break;
@@ -9030,7 +9033,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
}
clif->skill_nodamage(src, bl, skill_id, skill_lv, sp ? 1:0);
} else {
- clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
+ clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL);
map->foreachinrange(skill->area_sub, bl, skill->get_splash(skill_id, skill_lv), splash_target(src), src, skill_id, skill_lv, tick, flag|BCT_ENEMY|BCT_SELF|SD_SPLASH|1, skill->castend_nodamage_id);
}
break;
@@ -9038,12 +9041,12 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
case SR_POWERVELOCITY:
if( !dstsd )
break;
- if( sd && dstsd->spiritball <= 5 ) {
- int i;
- for(i = 0; i <= 5; i++) {
- pc->addspiritball(dstsd, skill->get_time(MO_CALLSPIRITS, pc->checkskill(sd,MO_CALLSPIRITS)), i);
- pc->delspiritball(sd, sd->spiritball, 0);
+ if ( sd && (dstsd->class_&MAPID_BASEMASK) != MAPID_GUNSLINGER ) {
+ int i, max = pc->getmaxspiritball(dstsd, 5);
+ for ( i = 0; i < max; i++ ) {
+ pc->addspiritball(dstsd, skill->get_time(MO_CALLSPIRITS, 1), max);
}
+ pc->delspiritball(sd, sd->spiritball, 0);
}
clif->skill_nodamage(src, bl, skill_id, skill_lv, 1);
break;
@@ -9199,7 +9202,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
madnesscheck = map->foreachinrange(skill->area_sub, src, skill->get_splash(skill_id,skill_lv),BL_PC, src, skill_id, skill_lv, tick, flag|BCT_ENEMY, skill->area_sub_count);
sc_start(src, bl, type, 100, skill_lv,skill->get_time(skill_id, skill_lv));
if ( madnesscheck >= 8 )//The god of madness deals 9999 fixed unreduceable damage when 8 or more enemy players are affected.
- status_fix_damage(src, bl, 9999, clif->damage(src, bl, 0, 0, 9999, 0, 0, 0));
+ status_fix_damage(src, bl, 9999, clif->damage(src, bl, 0, 0, 9999, 0, BDT_NORMAL, 0));
//skill->attack(BF_MISC,src,src,bl,skillid,skilllv,tick,flag);//To renable when I can confirm it deals damage like this. Data shows its dealt as reflected damage which I don't have it coded like that yet. [Rytech]
} else if( sd ) {
int rate = sstatus->int_ / 6 + (sd? sd->status.job_level:0) / 5 + skill_lv * 4;
@@ -9230,8 +9233,8 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
int improv_skill_id = 0, improv_skill_lv, improv_idx;
do {
improv_idx = rnd() % MAX_SKILL_IMPROVISE_DB;
- improv_skill_id = skill->improvise_db[improv_idx].skill_id;
- } while( improv_skill_id == 0 || rnd()%10000 >= skill->improvise_db[improv_idx].per );
+ improv_skill_id = skill->dbs->improvise_db[improv_idx].skill_id;
+ } while( improv_skill_id == 0 || rnd()%10000 >= skill->dbs->improvise_db[improv_idx].per );
improv_skill_lv = 4 + skill_lv;
clif->skill_nodamage (src, bl, skill_id, skill_lv, 1);
@@ -9335,7 +9338,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
break;
}
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
- clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, 0, 1, skill_id, -2, 6);
+ clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, 0, 1, skill_id, -2, BDT_SKILL);
break;
case GM_SANDMAN:
@@ -9560,7 +9563,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
elemental->clean_single_effect(ele, skill_id);
} else {
clif->skill_nodamage(src,src,skill_id,skill_lv,1);
- clif->skill_damage(src, ( skill_id == EL_GUST || skill_id == EL_BLAST || skill_id == EL_WILD_STORM )?src:bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
+ clif->skill_damage(src, ( skill_id == EL_GUST || skill_id == EL_BLAST || skill_id == EL_WILD_STORM )?src:bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL);
if( skill_id == EL_WIND_STEP ) // There aren't teleport, just push the master away.
skill->blown(src,bl,(rnd()%skill->get_blewcount(skill_id,skill_lv))+1,rnd()%8,0);
sc_start(src, src,type2,100,skill_lv,skill->get_time(skill_id,skill_lv));
@@ -9575,7 +9578,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
case EL_ZEPHYR:
case EL_POWER_OF_GAIA:
clif->skill_nodamage(src,src,skill_id,skill_lv,1);
- clif->skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
+ clif->skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL);
skill->unitsetting(src,skill_id,skill_lv,bl->x,bl->y,0);
break;
@@ -9591,7 +9594,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
elemental->clean_single_effect(ele, skill_id);
} else {
// This not heals at the end.
- clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
+ clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL);
sc_start(src, src,type2,100,skill_lv,skill->get_time(skill_id,skill_lv));
sc_start(src, bl,type,100,src->id,skill->get_time(skill_id,skill_lv));
}
@@ -9668,8 +9671,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
clif->skill_nodamage(src, src, skill_id, skill_lv, 1);
clif->slide(src, bl->x, bl->y) ;
sc_start(src, src, SC_CONFUSION, 25, skill_lv, skill->get_time(skill_id, skill_lv));
- if ( !is_boss(bl) && unit->stop_walking(&sd->bl, 1) && unit->movepos(bl, x, y, 0, 0) )
- {
+ if ( !is_boss(bl) && unit->stop_walking(&sd->bl, STOPWALKING_FLAG_FIXPOS) && unit->movepos(bl, x, y, 0, 0) ) {
if( dstsd && pc_issit(dstsd) )
pc->setstand(dstsd);
clif->slide(bl, x, y) ;
@@ -9692,7 +9694,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
case KG_KAGEMUSYA:
clif->skill_nodamage(src,bl,skill_id,skill_lv,
sc_start(src, bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
- clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
+ clif->skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL);
break;
case KG_KAGEHUMI:
@@ -9711,7 +9713,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
status_change_end(bl, SC_HARMONIZE, INVALID_TIMER);
}
if( skill->area_temp[2] == 1 ){
- clif->skill_damage(src,src,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
+ clif->skill_damage(src,src,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL);
sc_start(src, src, SC_STOP, 100, skill_lv, skill->get_time(skill_id, skill_lv));
}
} else {
@@ -9889,7 +9891,7 @@ int skill_castend_pos(int tid, int64 tick, int id, intptr_t data)
if( sd && ud->skilltimer != INVALID_TIMER && ( pc->checkskill(sd,SA_FREECAST) > 0 || ud->skill_id == LG_EXEEDBREAK ) )
{// restore original walk speed
ud->skilltimer = INVALID_TIMER;
- status_calc_bl(&sd->bl, SCB_SPEED);
+ status_calc_bl(&sd->bl, SCB_SPEED|SCB_ASPD);
}
ud->skilltimer = INVALID_TIMER;
@@ -9965,7 +9967,7 @@ int skill_castend_pos(int tid, int64 tick, int id, intptr_t data)
src->type, src->id, ud->skill_id, ud->skill_lv, ud->skillx, ud->skilly);
if (ud->walktimer != INVALID_TIMER)
- unit->stop_walking(src,1);
+ unit->stop_walking(src, STOPWALKING_FLAG_FIXPOS);
if( !sd || sd->skillitem != ud->skill_id || skill->get_delay(ud->skill_id,ud->skill_lv) )
ud->canact_tick = tick + skill->delay_fix(src, ud->skill_id, ud->skill_lv);
@@ -10527,9 +10529,9 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
case CR_SLIMPITCHER:
if (sd) {
int i = skill_lv%11 - 1;
- int j = pc->search_inventory(sd,skill->db[skill_id].itemid[i]);
- if (j == INDEX_NOT_FOUND || skill->db[skill_id].itemid[i] <= 0
- || sd->inventory_data[j] == NULL || sd->status.inventory[j].amount < skill->db[skill_id].amount[i]
+ int j = pc->search_inventory(sd,skill->dbs->db[skill_id].itemid[i]);
+ if (j == INDEX_NOT_FOUND || skill->dbs->db[skill_id].itemid[i] <= 0
+ || sd->inventory_data[j] == NULL || sd->status.inventory[j].amount < skill->dbs->db[skill_id].amount[i]
) {
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 1;
@@ -10558,7 +10560,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
} else {
int i = skill_lv%11 - 1;
struct item_data *item;
- i = skill->db[skill_id].itemid[i];
+ i = skill->dbs->db[skill_id].itemid[i];
item = itemdb->search(i);
script->potion_flag = 1;
script->potion_hp = 0;
@@ -10661,7 +10663,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
break;
case RK_WINDCUTTER:
- clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
+ clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL);
/* Fall through */
case NC_COLDSLOWER:
case RK_DRAGONBREATH:
@@ -10701,7 +10703,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
clif->skill_fail(sd,skill_id,USESKILL_FAIL_GC_POISONINGWEAPON,0);
return 0;
}
- clif->skill_damage(src,src,tick,status_get_amotion(src),0,-30000,1,skill_id,skill_lv,6);
+ clif->skill_damage(src,src,tick,status_get_amotion(src),0,-30000,1,skill_id,skill_lv,BDT_SKILL);
skill->unitsetting(src, skill_id, skill_lv, x, y, flag);
//status_change_end(src,SC_POISONINGWEAPON,INVALID_TIMER); // 08/31/2011 - When using poison smoke, you no longer lose the poisoning weapon effect.
break;
@@ -10738,7 +10740,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
case RA_DETONATOR:
r = skill->get_splash(skill_id, skill_lv);
map->foreachinarea(skill->detonator, src->m, x-r, y-r, x+r, y+r, BL_SKILL, src);
- clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
+ clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL);
break;
/**
* Mechanic
@@ -11074,6 +11076,7 @@ struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_
* According to data provided in RE, SW life is equal to 3 times caster's health
**/
val2 = status_get_max_hp(src) * 3;
+ val3 = skill_lv+1;
#else
val2 = skill_lv+1;
#endif
@@ -11389,7 +11392,7 @@ struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_
}
break;
case NPC_EARTHQUAKE:
- clif->skill_damage(src, src, timer->gettick(), status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
+ clif->skill_damage(src, src, timer->gettick(), status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL);
break;
default:
skill->unitsetting1_unknown(src, &skill_id, &skill_lv, &x, &y, &flag, &val1, &val2, &val3);
@@ -11785,7 +11788,7 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6
struct skill_unit_group *sg;
struct block_list *ss;
TBL_PC* tsd;
- struct status_data *tstatus;
+ struct status_data *tstatus, *bst;
struct status_change *tsc, *ssc;
struct skill_unit_group_tickset *ts;
enum sc_type type;
@@ -11809,6 +11812,7 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6
return 0;
tstatus = status->get_status_data(bl);
+ bst = status->get_base_status(bl);
type = status->skill2sc(sg->skill_id);
skill_id = sg->skill_id;
@@ -12346,10 +12350,11 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6
skill->attack(BF_WEAPON,ss,&src->bl,bl,WM_SEVERE_RAINSTORM_MELEE,sg->skill_lv,tick,0);
break;
case UNT_NETHERWORLD:
- if( !(status_get_mode(bl)&MD_BOSS)) {
- if( !(tsc && tsc->data[type]) ){
- sc_start(ss, bl, type, 100, sg->skill_lv, skill->get_time2(sg->skill_id,sg->skill_lv));
- }
+ if ( battle->check_target(&src->bl, bl, BCT_PARTY) == -1 && bl->id != sg->src_id ) {
+ sc_start(ss, bl, type, 100, sg->skill_lv, skill->get_time2(sg->skill_id, sg->skill_lv));
+ sg->limit = 0;
+ clif->changetraplook(&src->bl, UNT_USED_TRAPS);
+ sg->unit_id = UNT_USED_TRAPS;
}
break;
case UNT_THORNS_TRAP:
@@ -12420,7 +12425,6 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6
hp = tstatus->max_hp * 3 * sg->skill_lv / 100;
else
hp = tstatus->max_hp * sg->skill_lv / 100;
- status->heal(bl, hp, 0, 0);
if( tstatus->hp != tstatus->max_hp )
clif->skill_nodamage(&src->bl, bl, AL_HEAL, hp, 0);
if( tsc && tsc->data[SC_AKAITSUKI] && hp )
@@ -12457,7 +12461,7 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6
if (tsc && (tsc->data[SC_HALLUCINATIONWALK] || tsc->data[SC_VACUUM_EXTREME])) {
return 0;
} else {
- sg->limit -= 100 * tstatus->str/20;
+ sg->limit -= 1000 * bst->str/20;
sc_start(ss, bl, SC_VACUUM_EXTREME, 100, sg->skill_lv, sg->limit);
if ( !map_flag_gvg(bl->m) && !map->list[bl->m].flag.battleground && !is_boss(bl) ) {
@@ -12924,7 +12928,8 @@ int skill_check_condition_mob_master_sub (struct block_list *bl, va_list ap) {
mob_class=va_arg(ap,int);
skill_id=va_arg(ap,int);
c=va_arg(ap,int *);
- if( md->master_id != src_id || md->special_state.ai != (unsigned)(skill_id == AM_SPHEREMINE?2:skill_id == KO_ZANZOU?4:skill_id == MH_SUMMON_LEGION?1:3) )
+ if( md->master_id != src_id
+ || md->special_state.ai != (skill_id == AM_SPHEREMINE?AI_SPHERE:skill_id == KO_ZANZOU?AI_ZANZOU:skill_id == MH_SUMMON_LEGION?AI_ATTACK:AI_FLORA) )
return 0; //Non alchemist summoned mobs have nothing to do here.
if(md->class_==mob_class)
(*c)++;
@@ -13038,8 +13043,8 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
sd->itemid = sd->itemindex = -1;
if( skill_id == WZ_EARTHSPIKE && sc && sc->data[SC_EARTHSCROLL] && rnd()%100 > sc->data[SC_EARTHSCROLL]->val2 ) // [marquis007]
; //Do not consume item.
- else if( sd->status.inventory[i].expire_time == 0 )
- pc->delitem(sd,i,1,0,0,LOG_TYPE_CONSUME); // Rental usable items are not consumed until expiration
+ else if( sd->status.inventory[i].expire_time == 0 ) // Rental usable items are not consumed until expiration
+ pc->delitem(sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_CONSUME);
}
return 1;
}
@@ -13644,7 +13649,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
MOBID_EMPERIUM, MOBID_GUARIDAN_STONE1, MOBID_GUARIDAN_STONE2)) {
char output[128];
sprintf(output, "You're too close to a stone or emperium to do this skill"); /* TODO official response? or message.conf it */
- clif->colormes(sd->fd, COLOR_RED, output);
+ clif->messagecolor_self(sd->fd, COLOR_RED, output);
return 0;
}
}
@@ -14078,7 +14083,7 @@ int skill_check_condition_castend(struct map_session_data* sd, uint16 skill_id,
skill->get_desc(skill_id),
require.ammo_qty,
itemdb_jname(sd->status.inventory[i].nameid));
- clif->colormes(sd->fd,COLOR_RED,e_msg);
+ clif->messagecolor_self(sd->fd, COLOR_RED, e_msg);
return 0;
}
if (!(require.ammo&1<<sd->inventory_data[i]->look)) { //Ammo type check. Send the "wrong weapon type" message
@@ -14214,7 +14219,7 @@ int skill_consume_requirement( struct map_session_data *sd, uint16 skill_id, uin
}
if ((n = pc->search_inventory(sd,req.itemid[i])) != INDEX_NOT_FOUND)
- pc->delitem(sd,n,req.amount[i],0,1,LOG_TYPE_CONSUME);
+ pc->delitem(sd, n, req.amount[i], 0, DELITEM_SKILLUSE, LOG_TYPE_CONSUME);
}
}
@@ -14280,17 +14285,17 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16
st = &sd->battle_status;
- req.hp = skill->db[idx].hp[skill_lv-1];
- hp_rate = skill->db[idx].hp_rate[skill_lv-1];
+ req.hp = skill->dbs->db[idx].hp[skill_lv-1];
+ hp_rate = skill->dbs->db[idx].hp_rate[skill_lv-1];
if(hp_rate > 0)
req.hp += (st->hp * hp_rate)/100;
else
req.hp += (st->max_hp * (-hp_rate))/100;
- req.sp = skill->db[idx].sp[skill_lv-1];
+ req.sp = skill->dbs->db[idx].sp[skill_lv-1];
if((sd->skill_id_old == BD_ENCORE) && skill_id == sd->skill_id_dance)
req.sp /= 2;
- sp_rate = skill->db[idx].sp_rate[skill_lv-1];
+ sp_rate = skill->dbs->db[idx].sp_rate[skill_lv-1];
if(sp_rate > 0)
req.sp += (st->sp * sp_rate)/100;
else
@@ -14318,22 +14323,22 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16
req.sp -= req.sp * sc->data[SC_TELEKINESIS_INTENSE]->val2 / 100;
}
- req.zeny = skill->db[idx].zeny[skill_lv-1];
+ req.zeny = skill->dbs->db[idx].zeny[skill_lv-1];
if( sc && sc->data[SC__UNLUCKY] )
req.zeny += sc->data[SC__UNLUCKY]->val1 * 500;
- req.spiritball = skill->db[idx].spiritball[skill_lv-1];
+ req.spiritball = skill->dbs->db[idx].spiritball[skill_lv-1];
- req.state = skill->db[idx].state;
+ req.state = skill->dbs->db[idx].state;
- req.mhp = skill->db[idx].mhp[skill_lv-1];
+ req.mhp = skill->dbs->db[idx].mhp[skill_lv-1];
- req.weapon = skill->db[idx].weapon;
+ req.weapon = skill->dbs->db[idx].weapon;
- req.ammo_qty = skill->db[idx].ammo_qty[skill_lv-1];
+ req.ammo_qty = skill->dbs->db[idx].ammo_qty[skill_lv-1];
if (req.ammo_qty)
- req.ammo = skill->db[idx].ammo;
+ req.ammo = skill->dbs->db[idx].ammo;
if (!req.ammo && skill_id && skill->isammotype(sd, skill_id)) {
//Assume this skill is using the weapon, therefore it requires arrows.
@@ -14359,11 +14364,11 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16
continue;
break;
case AB_ADORAMUS:
- if( itemid_isgemstone(skill->db[idx].itemid[i]) && skill->check_pc_partner(sd,skill_id,&skill_lv, 1, 2) )
+ if( itemid_isgemstone(skill->dbs->db[idx].itemid[i]) && skill->check_pc_partner(sd,skill_id,&skill_lv, 1, 2) )
continue;
break;
case WL_COMET:
- if( itemid_isgemstone(skill->db[idx].itemid[i]) && skill->check_pc_partner(sd,skill_id,&skill_lv, 1, 0) )
+ if( itemid_isgemstone(skill->dbs->db[idx].itemid[i]) && skill->check_pc_partner(sd,skill_id,&skill_lv, 1, 0) )
continue;
break;
case GN_FIRE_EXPANSION:
@@ -14389,8 +14394,8 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16
}
}
- req.itemid[i] = skill->db[idx].itemid[i];
- req.amount[i] = skill->db[idx].amount[i];
+ req.itemid[i] = skill->dbs->db[idx].itemid[i];
+ req.amount[i] = skill->dbs->db[idx].amount[i];
if (itemid_isgemstone(req.itemid[i]) && skill_id != HW_GANBANTEIN) {
if (sd->special_state.no_gemstone) {
@@ -14432,8 +14437,8 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16
case SO_FIRE_INSIGNIA:
case SO_WIND_INSIGNIA:
case SO_EARTH_INSIGNIA:
- req.itemid[skill_lv-1] = skill->db[idx].itemid[skill_lv-1];
- req.amount[skill_lv-1] = skill->db[idx].amount[skill_lv-1];
+ req.itemid[skill_lv-1] = skill->dbs->db[idx].itemid[skill_lv-1];
+ req.amount[skill_lv-1] = skill->dbs->db[idx].amount[skill_lv-1];
break;
}
if (skill_id == NC_REPAIR) {
@@ -14737,8 +14742,11 @@ int skill_vfcastfix(struct block_list *bl, double time, uint16 skill_id, uint16
fixcast_r = max(fixcast_r, sc->data[SC_DANCE_WITH_WUG]->val4);
if( sc->data[SC_SECRAMENT] )
fixcast_r = max(fixcast_r, sc->data[SC_SECRAMENT]->val2);
- if( sd && ( skill_lv = pc->checkskill(sd, WL_RADIUS) ) && (skill_id >= WL_WHITEIMPRISON && skill_id < WL_FREEZE_SP) )
- fixcast_r = max(fixcast_r, (status_get_int(bl) + status->get_lv(bl)) / 15 + skill_lv * 5); // [{(Caster?s INT / 15) + (Caster?s Base Level / 15) + (Radius Skill Level x 5)}] %
+ if (sd && skill_id >= WL_WHITEIMPRISON && skill_id < WL_FREEZE_SP) {
+ int radius_lv = pc->checkskill(sd, WL_RADIUS);
+ if (radius_lv)
+ fixcast_r = max(fixcast_r, (status_get_int(bl) + status->get_lv(bl)) / 15 + radius_lv * 5); // [{(Caster?s INT / 15) + (Caster?s Base Level / 15) + (Radius Skill Level x 5)}] %
+ }
// Fixed cast non percentage bonuses
if( sc->data[SC_MANDRAGORA] )
fixed += sc->data[SC_MANDRAGORA]->val1 * 500;
@@ -15078,7 +15086,7 @@ void skill_repairweapon (struct map_session_data *sd, int idx) {
clif->equiplist(target_sd);
- pc->delitem(sd,pc->search_inventory(sd,material),1,0,0,LOG_TYPE_CONSUME);
+ pc->delitem(sd, pc->search_inventory(sd, material), 1, 0, DELITEM_NORMAL, LOG_TYPE_CONSUME); // FIXME: is this the correct reason flag?
clif->item_repaireffect(sd,idx,0);
@@ -15147,7 +15155,7 @@ void skill_weaponrefine (struct map_session_data *sd, int idx)
else
per += 5 * ((signed int)sd->status.job_level - 50);
- pc->delitem(sd, i, 1, 0, 0, LOG_TYPE_OTHER);
+ pc->delitem(sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_OTHER); // FIXME: is this the correct reason flag?
if (per > rnd() % 1000) {
int ep = 0;
logs->pick_pc(sd, LOG_TYPE_OTHER, -1, item, ditem);
@@ -15155,9 +15163,9 @@ void skill_weaponrefine (struct map_session_data *sd, int idx)
logs->pick_pc(sd, LOG_TYPE_OTHER, 1, item, ditem);
if(item->equip) {
ep = item->equip;
- pc->unequipitem(sd,idx,3);
+ pc->unequipitem(sd, idx, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE);
}
- clif->delitem(sd,idx,1,0);
+ clif->delitem(sd, idx, 1, DELITEM_NORMAL);
clif->upgrademessage(sd->fd, 0,item->nameid);
clif->inventorylist(sd);
clif->refine(sd->fd,0,idx,item->refine);
@@ -15183,9 +15191,9 @@ void skill_weaponrefine (struct map_session_data *sd, int idx)
} else {
item->refine = 0;
if(item->equip)
- pc->unequipitem(sd,idx,3);
+ pc->unequipitem(sd, idx, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE);
clif->refine(sd->fd,1,idx,item->refine);
- pc->delitem(sd,idx,1,0,0, LOG_TYPE_OTHER);
+ pc->delitem(sd, idx, 1, 0, DELITEM_NORMAL, LOG_TYPE_OTHER);
clif->misceffect(&sd->bl,2);
clif->emotion(&sd->bl, E_OMG);
}
@@ -15488,7 +15496,6 @@ int skill_graffitiremover (struct block_list *bl, va_list ap) {
struct skill_unit *su=NULL;
nullpo_ret(bl);
- nullpo_ret(ap);
if(bl->type != BL_SKILL)
return 0;
@@ -15519,7 +15526,6 @@ int skill_detonator(struct block_list *bl, va_list ap) {
int unit_id;
nullpo_ret(bl);
- nullpo_ret(ap);
src = va_arg(ap,struct block_list *);
if( bl->type != BL_SKILL )
@@ -15725,7 +15731,7 @@ int skill_trap_splash(struct block_list *bl, va_list ap) {
skill->blown(src,bl,skill->get_blewcount(sg->skill_id,sg->skill_lv),-1,0);
break;
case UNT_ELECTRICSHOCKER:
- clif->skill_damage(src,bl,tick,0,0,-30000,1,sg->skill_id,sg->skill_lv,5);
+ clif->skill_damage(src,bl,tick,0,0,-30000,1,sg->skill_id,sg->skill_lv,BDT_SPLASH);
break;
case UNT_MAGENTATRAP:
case UNT_COBALTTRAP:
@@ -15912,7 +15918,7 @@ bool skill_check_shadowform(struct block_list *bl, int64 damage, int hit)
return false;
}
- status->damage(bl, src, damage, 0, clif->damage(src, src, 500, 500, damage, hit, (hit > 1 ? 8 : 0), 0), 0);
+ status->damage(bl, src, damage, 0, clif->damage(src, src, 500, 500, damage, hit, (hit > 1 ? BDT_MULTIHIT : BDT_NORMAL), 0), 0);
/* because damage can cancel it */
if( sc->data[SC__SHADOWFORM] && (--sc->data[SC__SHADOWFORM]->val3) <= 0 ) {
@@ -15945,7 +15951,8 @@ struct skill_unit *skill_initunit (struct skill_unit_group *group, int idx, int
su->group=group;
su->alive=1;
su->val1=val1;
- su->val2=val2;
+ su->val2 = val2;
+ su->prev = 0;
idb_put(skill->unit_db, su->bl.id, su);
map->addiddb(&su->bl);
@@ -16539,7 +16546,7 @@ int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap) {
dissonance = skill->dance_switch(su, 0);
- if( su->range >= 0 && group->interval != -1 ) {
+ if( su->range >= 0 && group->interval != -1 && su->bl.id != su->prev) {
if( battle_config.skill_wall_check )
map->foreachinshootrange(skill->unit_timer_sub_onplace, bl, su->range, group->bl_flag, bl,tick);
else
@@ -16555,6 +16562,8 @@ int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap) {
group->bl_flag= BL_NUL;
}
}
+ if ( group->limit == group->interval )
+ su->prev = su->bl.id;
}
if( dissonance ) skill->dance_switch(su, 1);
@@ -16795,9 +16804,9 @@ int skill_can_produce_mix (struct map_session_data *sd, int nameid, int trigger,
return 0;
for(i=0;i<MAX_SKILL_PRODUCE_DB;i++){
- if(skill->produce_db[i].nameid == nameid ){
- if((j=skill->produce_db[i].req_skill)>0 &&
- pc->checkskill(sd,j) < skill->produce_db[i].req_skill_lv)
+ if(skill->dbs->produce_db[i].nameid == nameid ){
+ if((j=skill->dbs->produce_db[i].req_skill)>0 &&
+ pc->checkskill(sd,j) < skill->dbs->produce_db[i].req_skill_lv)
continue; // must iterate again to check other skills that produce it. [malufett]
if( j > 0 && sd->menuskill_id > 0 && sd->menuskill_id != j )
continue; // special case
@@ -16815,22 +16824,22 @@ int skill_can_produce_mix (struct map_session_data *sd, int nameid, int trigger,
if(trigger>=0){
if(trigger>20) { // Non-weapon, non-food item (itemlv must match)
- if(skill->produce_db[i].itemlv!=trigger)
+ if(skill->dbs->produce_db[i].itemlv!=trigger)
return 0;
} else if(trigger>10) { // Food (any item level between 10 and 20 will do)
- if(skill->produce_db[i].itemlv<=10 || skill->produce_db[i].itemlv>20)
+ if(skill->dbs->produce_db[i].itemlv<=10 || skill->dbs->produce_db[i].itemlv>20)
return 0;
} else { // Weapon (itemlv must be higher or equal)
- if(skill->produce_db[i].itemlv>trigger)
+ if(skill->dbs->produce_db[i].itemlv>trigger)
return 0;
}
}
for (j = 0; j < MAX_PRODUCE_RESOURCE; j++) {
- int id = skill->produce_db[i].mat_id[j];
+ int id = skill->dbs->produce_db[i].mat_id[j];
if (id <= 0)
continue;
- if (skill->produce_db[i].mat_amount[j] <= 0) {
+ if (skill->dbs->produce_db[i].mat_amount[j] <= 0) {
if (pc->search_inventory(sd,id) == INDEX_NOT_FOUND)
return 0;
} else {
@@ -16838,7 +16847,7 @@ int skill_can_produce_mix (struct map_session_data *sd, int nameid, int trigger,
for(y=0,x=0;y<MAX_INVENTORY;y++)
if( sd->status.inventory[y].nameid == id )
x+=sd->status.inventory[y].amount;
- if(x<qty*skill->produce_db[i].mat_amount[j])
+ if(x<qty*skill->dbs->produce_db[i].mat_amount[j])
return 0;
}
}
@@ -16869,7 +16878,7 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid,
qty = 1;
if (!skill_id) //A skill can be specified for some override cases.
- skill_id = skill->produce_db[idx].req_skill;
+ skill_id = skill->dbs->produce_db[idx].req_skill;
if( skill_id == GC_RESEARCHNEWPOISON )
skill_id = GC_CREATENEWPOISON;
@@ -16886,12 +16895,12 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid,
if (j == INDEX_NOT_FOUND)
continue;
if( slot[i]==ITEMID_STAR_CRUMB ) {
- pc->delitem(sd,j,1,1,0,LOG_TYPE_PRODUCE);
+ pc->delitem(sd, j, 1, 1, DELITEM_NORMAL, LOG_TYPE_PRODUCE); // FIXME: is this the correct reason flag?
sc++;
}
if( slot[i] >= ITEMID_FLAME_HEART && slot[i] <= ITEMID_GREAT_NATURE && ele == 0 ) {
static const int ele_table[4]={3,1,4,2};
- pc->delitem(sd,j,1,1,0,LOG_TYPE_PRODUCE);
+ pc->delitem(sd, j, 1, 1, DELITEM_NORMAL, LOG_TYPE_PRODUCE); // FIXME: is this the correct reason flag?
ele=ele_table[slot[i]-994];
}
}
@@ -16908,7 +16917,7 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid,
for( i = 0; i < MAX_INVENTORY; i++ ) {
if( sd->status.inventory[i].nameid == nameid ) {
if( sd->status.inventory[i].amount >= data->stack.amount ) {
- clif->msgtable(sd->fd,0x61b);
+ clif->msgtable(sd, MSG_RUNE_STONE_MAX_AMOUNT);
return 0;
} else {
/**
@@ -16926,10 +16935,10 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid,
for(i=0;i<MAX_PRODUCE_RESOURCE;i++){
int j,id,x;
- if( (id=skill->produce_db[idx].mat_id[i]) <= 0 )
+ if( (id=skill->dbs->produce_db[idx].mat_id[i]) <= 0 )
continue;
num++;
- x=( skill_id == RK_RUNEMASTERY ? 1 : qty)*skill->produce_db[idx].mat_amount[i];
+ x=( skill_id == RK_RUNEMASTERY ? 1 : qty)*skill->dbs->produce_db[idx].mat_amount[i];
do{
int y=0;
j = pc->search_inventory(sd,id);
@@ -16937,7 +16946,7 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid,
if (j != INDEX_NOT_FOUND) {
y = sd->status.inventory[j].amount;
if(y>x)y=x;
- pc->delitem(sd,j,y,0,0,LOG_TYPE_PRODUCE);
+ pc->delitem(sd, j, y, 0, DELITEM_NORMAL, LOG_TYPE_PRODUCE); // FIXME: is this the correct reason flag?
} else
ShowError("skill_produce_mix: material item error\n");
@@ -17070,8 +17079,8 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid,
break;
case GN_CHANGEMATERIAL:
for(i=0; i<MAX_SKILL_PRODUCE_DB; i++)
- if( skill->changematerial_db[i].itemid == nameid ){
- make_per = skill->changematerial_db[i].rate * 10;
+ if( skill->dbs->changematerial_db[i].itemid == nameid ){
+ make_per = skill->dbs->changematerial_db[i].rate * 10;
break;
}
break;
@@ -17183,7 +17192,7 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid,
+ 20 * (sd->status.base_level + 1)
+ 20 * (st->dex + 1)
+ 100 * (rnd()%(30+5*(sd->cook_mastery/400) - (6+sd->cook_mastery/80)) + (6+sd->cook_mastery/80))
- - 400 * (skill->produce_db[idx].itemlv - 11 + 1)
+ - 400 * (skill->dbs->produce_db[idx].itemlv - 11 + 1)
- 10 * (100 - st->luk + 1)
- 500 * (num - 1)
- 100 * (rnd()%4 + 1);
@@ -17339,11 +17348,11 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid,
clif->misceffect(&sd->bl,5);
break;
default: //Those that don't require a skill?
- if( skill->produce_db[idx].itemlv > 10 && skill->produce_db[idx].itemlv <= 20)
+ if( skill->dbs->produce_db[idx].itemlv > 10 && skill->dbs->produce_db[idx].itemlv <= 20)
{ //Cooking items.
clif->specialeffect(&sd->bl, 608, AREA);
if( sd->cook_mastery < 1999 )
- pc_setglobalreg(sd, script->add_str("COOK_MASTERY"),sd->cook_mastery + ( 1 << ( (skill->produce_db[idx].itemlv - 11) / 2 ) ) * 5);
+ pc_setglobalreg(sd, script->add_str("COOK_MASTERY"),sd->cook_mastery + ( 1 << ( (skill->dbs->produce_db[idx].itemlv - 11) / 2 ) ) * 5);
}
break;
}
@@ -17351,10 +17360,10 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid,
if ( skill_id == GN_CHANGEMATERIAL && tmp_item.amount) { //Success
int j, k = 0;
for(i=0; i<MAX_SKILL_PRODUCE_DB; i++)
- if( skill->changematerial_db[i].itemid == nameid ){
+ if( skill->dbs->changematerial_db[i].itemid == nameid ){
for(j=0; j<5; j++){
- if( rnd()%1000 < skill->changematerial_db[i].qty_rate[j] ){
- tmp_item.amount = qty * skill->changematerial_db[i].qty[j];
+ if( rnd()%1000 < skill->dbs->changematerial_db[i].qty_rate[j] ){
+ tmp_item.amount = qty * skill->dbs->changematerial_db[i].qty[j];
if((flag = pc->additem(sd,&tmp_item,tmp_item.amount,LOG_TYPE_PRODUCE))) {
clif->additem(sd,0,0,flag);
map->addflooritem(&tmp_item,tmp_item.amount,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
@@ -17365,7 +17374,7 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid,
break;
}
if( k ){
- clif->msg_skill(sd,skill_id,0x627);
+ clif->msgtable_skill(sd, skill_id, MSG_SKILL_SUCCESS);
return 1;
}
} else if (tmp_item.amount) { //Success
@@ -17374,7 +17383,7 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid,
map->addflooritem(&tmp_item,tmp_item.amount,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
}
if( skill_id == GN_MIX_COOKING || skill_id == GN_MAKEBOMB || skill_id == GN_S_PHARMACY )
- clif->msg_skill(sd,skill_id,0x627);
+ clif->msgtable_skill(sd, skill_id, MSG_SKILL_SUCCESS);
return 1;
}
}
@@ -17433,20 +17442,20 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid,
clif->additem(sd,0,0,flag);
map->addflooritem(&tmp_item,tmp_item.amount,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
}
- clif->msg_skill(sd,skill_id,0x628);
+ clif->msgtable_skill(sd, skill_id, MSG_SKILL_FAILURE);
}
break;
case GN_MAKEBOMB:
case GN_S_PHARMACY:
case GN_CHANGEMATERIAL:
- clif->msg_skill(sd,skill_id,0x628);
+ clif->msgtable_skill(sd, skill_id, MSG_SKILL_FAILURE);
break;
default:
- if( skill->produce_db[idx].itemlv > 10 && skill->produce_db[idx].itemlv <= 20 )
+ if( skill->dbs->produce_db[idx].itemlv > 10 && skill->dbs->produce_db[idx].itemlv <= 20 )
{ //Cooking items.
clif->specialeffect(&sd->bl, 609, AREA);
if( sd->cook_mastery > 0 )
- pc_setglobalreg(sd, script->add_str("COOK_MASTERY"), sd->cook_mastery - ( 1 << ((skill->produce_db[idx].itemlv - 11) / 2) ) - ( ( ( 1 << ((skill->produce_db[idx].itemlv - 11) / 2) ) >> 1 ) * 3 ));
+ pc_setglobalreg(sd, script->add_str("COOK_MASTERY"), sd->cook_mastery - ( 1 << ((skill->dbs->produce_db[idx].itemlv - 11) / 2) ) - ( ( ( 1 << ((skill->dbs->produce_db[idx].itemlv - 11) / 2) ) >> 1 ) * 3 ));
}
}
}
@@ -17464,7 +17473,7 @@ int skill_arrow_create (struct map_session_data *sd, int nameid)
return 1;
for(i=0;i<MAX_SKILL_ARROW_DB;i++)
- if(nameid == skill->arrow_db[i].nameid) {
+ if(nameid == skill->dbs->arrow_db[i].nameid) {
index = i;
break;
}
@@ -17472,12 +17481,12 @@ int skill_arrow_create (struct map_session_data *sd, int nameid)
if(index < 0 || (j = pc->search_inventory(sd,nameid)) == INDEX_NOT_FOUND)
return 1;
- pc->delitem(sd,j,1,0,0,LOG_TYPE_PRODUCE);
+ pc->delitem(sd, j, 1, 0, DELITEM_NORMAL, LOG_TYPE_PRODUCE); // FIXME: is this the correct reason flag?
for(i=0;i<MAX_ARROW_RESOURCE;i++) {
memset(&tmp_item,0,sizeof(tmp_item));
tmp_item.identify = 1;
- tmp_item.nameid = skill->arrow_db[index].cre_id[i];
- tmp_item.amount = skill->arrow_db[index].cre_amount[i];
+ tmp_item.nameid = skill->dbs->arrow_db[index].cre_id[i];
+ tmp_item.amount = skill->dbs->arrow_db[index].cre_amount[i];
if(battle_config.produce_item_name_input&0x4) {
tmp_item.card[0]=CARD0_CREATE;
tmp_item.card[1]=0;
@@ -17498,7 +17507,7 @@ int skill_poisoningweapon( struct map_session_data *sd, int nameid) {
sc_type type;
int chance, i;
nullpo_ret(sd);
- if( nameid <= 0 || (i = pc->search_inventory(sd,nameid)) == INDEX_NOT_FOUND || pc->delitem(sd,i,1,0,0,LOG_TYPE_CONSUME) ) {
+ if (nameid <= 0 || (i = pc->search_inventory(sd,nameid)) == INDEX_NOT_FOUND || pc->delitem(sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_CONSUME)) {
clif->skill_fail(sd,GC_POISONINGWEAPON,USESKILL_FAIL_LEVEL,0);
return 0;
}
@@ -17555,15 +17564,16 @@ int skill_magicdecoy(struct map_session_data *sd, int nameid) {
nullpo_ret(sd);
skill_id = sd->menuskill_val;
- if (nameid <= 0 || !itemdb_is_element(nameid) || (i = pc->search_inventory(sd,nameid)) == INDEX_NOT_FOUND
- || !skill_id || pc->delitem(sd,i,1,0,0,LOG_TYPE_CONSUME)
+ if (nameid <= 0 || !itemdb_is_element(nameid) || !skill_id
+ || (i = pc->search_inventory(sd, nameid)) == INDEX_NOT_FOUND
+ || pc->delitem(sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_CONSUME) != 0
) {
clif->skill_fail(sd,NC_MAGICDECOY,USESKILL_FAIL_LEVEL,0);
return 0;
}
// Spawn Position
- pc->delitem(sd,i,1,0,0,LOG_TYPE_CONSUME);
+ pc->delitem(sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_CONSUME); // FIXME: is this intended to be there twice?
x = sd->sc.comet_x;
y = sd->sc.comet_y;
sd->sc.comet_x = sd->sc.comet_y = 0;
@@ -17603,10 +17613,10 @@ int skill_spellbook (struct map_session_data *sd, int nameid) {
return 0;
}
- ARR_FIND(0,MAX_SKILL_SPELLBOOK_DB,i,skill->spellbook_db[i].nameid == nameid); // Search for information of this item
+ ARR_FIND(0,MAX_SKILL_SPELLBOOK_DB,i,skill->dbs->spellbook_db[i].nameid == nameid); // Search for information of this item
if( i == MAX_SKILL_SPELLBOOK_DB ) return 0;
- if( !pc->checkskill(sd, (skill_id = skill->spellbook_db[i].skill_id)) )
+ if( !pc->checkskill(sd, (skill_id = skill->dbs->spellbook_db[i].skill_id)) )
{ // User don't know the skill
sc_start(&sd->bl, &sd->bl, SC_SLEEP, 100, 1, skill->get_time(WL_READING_SB, pc->checkskill(sd,WL_READING_SB)));
clif->skill_fail(sd, WL_READING_SB, USESKILL_FAIL_SPELLBOOK_DIFFICULT_SLEEP, 0);
@@ -17614,7 +17624,7 @@ int skill_spellbook (struct map_session_data *sd, int nameid) {
}
max_preserve = 4 * pc->checkskill(sd, WL_FREEZE_SP) + (status_get_int(&sd->bl) + sd->status.base_level) / 10;
- point = skill->spellbook_db[i].point;
+ point = skill->dbs->spellbook_db[i].point;
if( sc && sc->data[SC_READING_SB] ) {
if( (sc->data[SC_READING_SB]->val2 + point) > max_preserve ) {
@@ -17699,7 +17709,7 @@ int skill_elementalanalysis(struct map_session_data* sd, int n, uint16 skill_lv,
return 1;
}
- if( pc->delitem(sd,idx,del_amount,0,1,LOG_TYPE_CONSUME) ) {
+ if( pc->delitem(sd, idx, del_amount, 0, DELITEM_SKILLUSE, LOG_TYPE_CONSUME) ) {
clif->skill_fail(sd,SO_EL_ANALYSIS,USESKILL_FAIL_LEVEL,0);
return 1;
}
@@ -17737,23 +17747,23 @@ int skill_changematerial(struct map_session_data *sd, int n, unsigned short *ite
// Search for objects that can be created.
for( i = 0; i < MAX_SKILL_PRODUCE_DB; i++ ) {
- if( skill->produce_db[i].itemlv == 26 ) {
+ if( skill->dbs->produce_db[i].itemlv == 26 ) {
p = 0;
do {
c = 0;
// Verification of overlap between the objects required and the list submitted.
for( j = 0; j < MAX_PRODUCE_RESOURCE; j++ ) {
- if( skill->produce_db[i].mat_id[j] > 0 ) {
+ if( skill->dbs->produce_db[i].mat_id[j] > 0 ) {
for( k = 0; k < n; k++ ) {
int idx = item_list[k*2+0]-2;
nameid = sd->status.inventory[idx].nameid;
amount = item_list[k*2+1];
if( nameid > 0 && sd->status.inventory[idx].identify == 0 ){
- clif->msg_skill(sd,GN_CHANGEMATERIAL,0x62D);
+ clif->msgtable_skill(sd, GN_CHANGEMATERIAL, MSG_SKILL_ITEM_NEED_IDENTIFY);
return 0;
}
- if( nameid == skill->produce_db[i].mat_id[j] && (amount-p*skill->produce_db[i].mat_amount[j]) >= skill->produce_db[i].mat_amount[j]
- && (amount-p*skill->produce_db[i].mat_amount[j])%skill->produce_db[i].mat_amount[j] == 0 ) // must be in exact amount
+ if( nameid == skill->dbs->produce_db[i].mat_id[j] && (amount-p*skill->dbs->produce_db[i].mat_amount[j]) >= skill->dbs->produce_db[i].mat_amount[j]
+ && (amount-p*skill->dbs->produce_db[i].mat_amount[j])%skill->dbs->produce_db[i].mat_amount[j] == 0 ) // must be in exact amount
c++; // match
}
}
@@ -17764,14 +17774,14 @@ int skill_changematerial(struct map_session_data *sd, int n, unsigned short *ite
} while(n == j && c == n);
p--;
if ( p > 0 ) {
- skill->produce_mix(sd,GN_CHANGEMATERIAL,skill->produce_db[i].nameid,0,0,0,p);
+ skill->produce_mix(sd,GN_CHANGEMATERIAL,skill->dbs->produce_db[i].nameid,0,0,0,p);
return 1;
}
}
}
if( p == 0)
- clif->msg_skill(sd,GN_CHANGEMATERIAL,0x623);
+ clif->msgtable_skill(sd, GN_CHANGEMATERIAL, MSG_SKILL_ITEM_NOT_FOUND);
return 0;
}
@@ -17894,6 +17904,9 @@ int skill_blockpc_start_(struct map_session_data *sd, uint16 skill_id, int tick)
}
if( i != cd->cursor ) {/* duplicate, update necessary */
+ // Don't do anything if there's already a tick longer than the incoming one
+ if (DIFF_TICK32(cd->entry[i]->started + cd->entry[i]->duration, now) > tick)
+ return 0;
cd->entry[i]->duration = tick;
#if PACKETVER >= 20120604
cd->entry[i]->total = tick;
@@ -18077,25 +18090,25 @@ void skill_init_unit_layout (void)
//when != it was already cleared during skill_defaults() no need to repeat
if( runflag == MAPSERVER_ST_RUNNING )
- memset(skill->unit_layout,0,sizeof(skill->unit_layout));
+ memset(skill->dbs->unit_layout, 0, sizeof(skill->dbs->unit_layout));
// standard square layouts go first
for (i=0; i<=MAX_SQUARE_LAYOUT; i++) {
int size = i*2+1;
- skill->unit_layout[i].count = size*size;
+ skill->dbs->unit_layout[i].count = size*size;
for (j=0; j<size*size; j++) {
- skill->unit_layout[i].dx[j] = (j%size-i);
- skill->unit_layout[i].dy[j] = (j/size-i);
+ skill->dbs->unit_layout[i].dx[j] = (j%size-i);
+ skill->dbs->unit_layout[i].dy[j] = (j/size-i);
}
}
// afterwards add special ones
pos = i;
for (i=0;i<MAX_SKILL_DB;i++) {
- if (!skill->db[i].unit_id[0] || skill->db[i].unit_layout_type[0] != -1)
+ if (!skill->dbs->db[i].unit_id[0] || skill->dbs->db[i].unit_layout_type[0] != -1)
continue;
- switch (skill->db[i].nameid) {
+ switch (skill->dbs->db[i].nameid) {
case MG_FIREWALL:
case WZ_ICEWALL:
case WL_EARTHSTRAIN://Warlock
@@ -18109,9 +18122,9 @@ void skill_init_unit_layout (void)
static const int dy[]={
-2,-2,-2,-1,-1,-1,-1,-1, 0, 0,
0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2};
- skill->unit_layout[pos].count = 21;
- memcpy(skill->unit_layout[pos].dx,dx,sizeof(dx));
- memcpy(skill->unit_layout[pos].dy,dy,sizeof(dy));
+ skill->dbs->unit_layout[pos].count = 21;
+ memcpy(skill->dbs->unit_layout[pos].dx,dx,sizeof(dx));
+ memcpy(skill->dbs->unit_layout[pos].dy,dy,sizeof(dy));
}
break;
case PR_MAGNUS: {
@@ -18123,18 +18136,18 @@ void skill_init_unit_layout (void)
-3,-3,-3,-2,-2,-2,-1,-1,-1,-1,
-1,-1,-1, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3};
- skill->unit_layout[pos].count = 33;
- memcpy(skill->unit_layout[pos].dx,dx,sizeof(dx));
- memcpy(skill->unit_layout[pos].dy,dy,sizeof(dy));
+ skill->dbs->unit_layout[pos].count = 33;
+ memcpy(skill->dbs->unit_layout[pos].dx,dx,sizeof(dx));
+ memcpy(skill->dbs->unit_layout[pos].dy,dy,sizeof(dy));
}
break;
case MH_POISON_MIST:
case AS_VENOMDUST: {
static const int dx[] = {-1, 0, 0, 0, 1};
static const int dy[] = { 0,-1, 0, 1, 0};
- skill->unit_layout[pos].count = 5;
- memcpy(skill->unit_layout[pos].dx,dx,sizeof(dx));
- memcpy(skill->unit_layout[pos].dy,dy,sizeof(dy));
+ skill->dbs->unit_layout[pos].count = 5;
+ memcpy(skill->dbs->unit_layout[pos].dx,dx,sizeof(dx));
+ memcpy(skill->dbs->unit_layout[pos].dy,dy,sizeof(dy));
}
break;
case CR_GRANDCROSS:
@@ -18147,9 +18160,9 @@ void skill_init_unit_layout (void)
-4,-3,-2,-2,-2,-1,-1,-1,-1,-1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 1, 1, 1, 2, 2, 2, 3, 4};
- skill->unit_layout[pos].count = 29;
- memcpy(skill->unit_layout[pos].dx,dx,sizeof(dx));
- memcpy(skill->unit_layout[pos].dy,dy,sizeof(dy));
+ skill->dbs->unit_layout[pos].count = 29;
+ memcpy(skill->dbs->unit_layout[pos].dx,dx,sizeof(dx));
+ memcpy(skill->dbs->unit_layout[pos].dy,dy,sizeof(dy));
}
break;
case PF_FOGWALL: {
@@ -18157,9 +18170,9 @@ void skill_init_unit_layout (void)
-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2};
static const int dy[] = {
-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1};
- skill->unit_layout[pos].count = 15;
- memcpy(skill->unit_layout[pos].dx,dx,sizeof(dx));
- memcpy(skill->unit_layout[pos].dy,dy,sizeof(dy));
+ skill->dbs->unit_layout[pos].count = 15;
+ memcpy(skill->dbs->unit_layout[pos].dx,dx,sizeof(dx));
+ memcpy(skill->dbs->unit_layout[pos].dy,dy,sizeof(dy));
}
break;
case PA_GOSPEL: {
@@ -18173,17 +18186,17 @@ void skill_init_unit_layout (void)
-1,-1,-1, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 2, 2, 2,
3, 3, 3};
- skill->unit_layout[pos].count = 33;
- memcpy(skill->unit_layout[pos].dx,dx,sizeof(dx));
- memcpy(skill->unit_layout[pos].dy,dy,sizeof(dy));
+ skill->dbs->unit_layout[pos].count = 33;
+ memcpy(skill->dbs->unit_layout[pos].dx,dx,sizeof(dx));
+ memcpy(skill->dbs->unit_layout[pos].dy,dy,sizeof(dy));
}
break;
case NJ_KAENSIN: {
static const int dx[] = {-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2};
static const int dy[] = { 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0,-1,-1,-1,-1,-1,-2,-2,-2,-2,-2};
- skill->unit_layout[pos].count = 24;
- memcpy(skill->unit_layout[pos].dx,dx,sizeof(dx));
- memcpy(skill->unit_layout[pos].dy,dy,sizeof(dy));
+ skill->dbs->unit_layout[pos].count = 24;
+ memcpy(skill->dbs->unit_layout[pos].dx,dx,sizeof(dx));
+ memcpy(skill->dbs->unit_layout[pos].dy,dy,sizeof(dy));
}
break;
case NJ_TATAMIGAESHI: {
@@ -18198,29 +18211,29 @@ void skill_init_unit_layout (void)
static const int dy3[] = { 0, 0, 0, 0, 0, 0,-3,-2,-1, 1, 2, 3};
//lv1
j = 0;
- skill->unit_layout[pos].count = 4;
- memcpy(skill->unit_layout[pos].dx,dx1,sizeof(dx1));
- memcpy(skill->unit_layout[pos].dy,dy1,sizeof(dy1));
- skill->db[i].unit_layout_type[j] = pos;
+ skill->dbs->unit_layout[pos].count = 4;
+ memcpy(skill->dbs->unit_layout[pos].dx,dx1,sizeof(dx1));
+ memcpy(skill->dbs->unit_layout[pos].dy,dy1,sizeof(dy1));
+ skill->dbs->db[i].unit_layout_type[j] = pos;
//lv2/3
j++;
pos++;
- skill->unit_layout[pos].count = 8;
- memcpy(skill->unit_layout[pos].dx,dx2,sizeof(dx2));
- memcpy(skill->unit_layout[pos].dy,dy2,sizeof(dy2));
- skill->db[i].unit_layout_type[j] = pos;
- skill->db[i].unit_layout_type[++j] = pos;
+ skill->dbs->unit_layout[pos].count = 8;
+ memcpy(skill->dbs->unit_layout[pos].dx,dx2,sizeof(dx2));
+ memcpy(skill->dbs->unit_layout[pos].dy,dy2,sizeof(dy2));
+ skill->dbs->db[i].unit_layout_type[j] = pos;
+ skill->dbs->db[i].unit_layout_type[++j] = pos;
//lv4/5
j++;
pos++;
- skill->unit_layout[pos].count = 12;
- memcpy(skill->unit_layout[pos].dx,dx3,sizeof(dx3));
- memcpy(skill->unit_layout[pos].dy,dy3,sizeof(dy3));
- skill->db[i].unit_layout_type[j] = pos;
- skill->db[i].unit_layout_type[++j] = pos;
+ skill->dbs->unit_layout[pos].count = 12;
+ memcpy(skill->dbs->unit_layout[pos].dx,dx3,sizeof(dx3));
+ memcpy(skill->dbs->unit_layout[pos].dy,dy3,sizeof(dy3));
+ skill->dbs->db[i].unit_layout_type[j] = pos;
+ skill->dbs->db[i].unit_layout_type[++j] = pos;
//Fill in the rest using lv 5.
for (;j<MAX_SKILL_LEVEL;j++)
- skill->db[i].unit_layout_type[j] = pos;
+ skill->dbs->db[i].unit_layout_type[j] = pos;
//Skip, this way the check below will fail and continue to the next skill.
pos++;
}
@@ -18228,27 +18241,27 @@ void skill_init_unit_layout (void)
case GN_WALLOFTHORN: {
static const int dx[] = {-1,-2,-2,-2,-2,-2,-1, 0, 1, 2, 2, 2, 2, 2, 1, 0};
static const int dy[] = { 2, 2, 1, 0,-1,-2,-2,-2,-2,-2,-1, 0, 1, 2, 2, 2};
- skill->unit_layout[pos].count = 16;
- memcpy(skill->unit_layout[pos].dx,dx,sizeof(dx));
- memcpy(skill->unit_layout[pos].dy,dy,sizeof(dy));
+ skill->dbs->unit_layout[pos].count = 16;
+ memcpy(skill->dbs->unit_layout[pos].dx,dx,sizeof(dx));
+ memcpy(skill->dbs->unit_layout[pos].dy,dy,sizeof(dy));
}
break;
case EL_FIRE_MANTLE: {
static const int dx[] = {-1, 0, 1, 1, 1, 0,-1,-1};
static const int dy[] = { 1, 1, 1, 0,-1,-1,-1, 0};
- skill->unit_layout[pos].count = 8;
- memcpy(skill->unit_layout[pos].dx,dx,sizeof(dx));
- memcpy(skill->unit_layout[pos].dy,dy,sizeof(dy));
+ skill->dbs->unit_layout[pos].count = 8;
+ memcpy(skill->dbs->unit_layout[pos].dx,dx,sizeof(dx));
+ memcpy(skill->dbs->unit_layout[pos].dy,dy,sizeof(dy));
}
break;
default:
ShowError("unknown unit layout at skill %d\n",i);
break;
}
- if (!skill->unit_layout[pos].count)
+ if (!skill->dbs->unit_layout[pos].count)
continue;
for (j=0;j<MAX_SKILL_LEVEL;j++)
- skill->db[i].unit_layout_type[j] = pos;
+ skill->dbs->db[i].unit_layout_type[j] = pos;
pos++;
}
@@ -18256,60 +18269,60 @@ void skill_init_unit_layout (void)
skill->firewall_unit_pos = pos;
for (i=0;i<8;i++) {
if (i&1) {
- skill->unit_layout[pos].count = 5;
+ skill->dbs->unit_layout[pos].count = 5;
if (i&0x2) {
int dx[] = {-1,-1, 0, 0, 1};
int dy[] = { 1, 0, 0,-1,-1};
- memcpy(skill->unit_layout[pos].dx,dx,sizeof(dx));
- memcpy(skill->unit_layout[pos].dy,dy,sizeof(dy));
+ memcpy(skill->dbs->unit_layout[pos].dx,dx,sizeof(dx));
+ memcpy(skill->dbs->unit_layout[pos].dy,dy,sizeof(dy));
} else {
int dx[] = { 1, 1 ,0, 0,-1};
int dy[] = { 1, 0, 0,-1,-1};
- memcpy(skill->unit_layout[pos].dx,dx,sizeof(dx));
- memcpy(skill->unit_layout[pos].dy,dy,sizeof(dy));
+ memcpy(skill->dbs->unit_layout[pos].dx,dx,sizeof(dx));
+ memcpy(skill->dbs->unit_layout[pos].dy,dy,sizeof(dy));
}
} else {
- skill->unit_layout[pos].count = 3;
+ skill->dbs->unit_layout[pos].count = 3;
if (i%4==0) {
int dx[] = {-1, 0, 1};
int dy[] = { 0, 0, 0};
- memcpy(skill->unit_layout[pos].dx,dx,sizeof(dx));
- memcpy(skill->unit_layout[pos].dy,dy,sizeof(dy));
+ memcpy(skill->dbs->unit_layout[pos].dx,dx,sizeof(dx));
+ memcpy(skill->dbs->unit_layout[pos].dy,dy,sizeof(dy));
} else {
int dx[] = { 0, 0, 0};
int dy[] = {-1, 0, 1};
- memcpy(skill->unit_layout[pos].dx,dx,sizeof(dx));
- memcpy(skill->unit_layout[pos].dy,dy,sizeof(dy));
+ memcpy(skill->dbs->unit_layout[pos].dx,dx,sizeof(dx));
+ memcpy(skill->dbs->unit_layout[pos].dy,dy,sizeof(dy));
}
}
pos++;
}
skill->icewall_unit_pos = pos;
for (i=0;i<8;i++) {
- skill->unit_layout[pos].count = 5;
+ skill->dbs->unit_layout[pos].count = 5;
if (i&1) {
if (i&0x2) {
int dx[] = {-2,-1, 0, 1, 2};
int dy[] = { 2, 1, 0,-1,-2};
- memcpy(skill->unit_layout[pos].dx,dx,sizeof(dx));
- memcpy(skill->unit_layout[pos].dy,dy,sizeof(dy));
+ memcpy(skill->dbs->unit_layout[pos].dx,dx,sizeof(dx));
+ memcpy(skill->dbs->unit_layout[pos].dy,dy,sizeof(dy));
} else {
int dx[] = { 2, 1 ,0,-1,-2};
int dy[] = { 2, 1, 0,-1,-2};
- memcpy(skill->unit_layout[pos].dx,dx,sizeof(dx));
- memcpy(skill->unit_layout[pos].dy,dy,sizeof(dy));
+ memcpy(skill->dbs->unit_layout[pos].dx,dx,sizeof(dx));
+ memcpy(skill->dbs->unit_layout[pos].dy,dy,sizeof(dy));
}
} else {
if (i%4==0) {
int dx[] = {-2,-1, 0, 1, 2};
int dy[] = { 0, 0, 0, 0, 0};
- memcpy(skill->unit_layout[pos].dx,dx,sizeof(dx));
- memcpy(skill->unit_layout[pos].dy,dy,sizeof(dy));
+ memcpy(skill->dbs->unit_layout[pos].dx,dx,sizeof(dx));
+ memcpy(skill->dbs->unit_layout[pos].dy,dy,sizeof(dy));
} else {
int dx[] = { 0, 0, 0, 0, 0};
int dy[] = {-2,-1, 0, 1, 2};
- memcpy(skill->unit_layout[pos].dx,dx,sizeof(dx));
- memcpy(skill->unit_layout[pos].dy,dy,sizeof(dy));
+ memcpy(skill->dbs->unit_layout[pos].dx,dx,sizeof(dx));
+ memcpy(skill->dbs->unit_layout[pos].dy,dy,sizeof(dy));
}
}
pos++;
@@ -18317,15 +18330,15 @@ void skill_init_unit_layout (void)
skill->earthstrain_unit_pos = pos;
for( i = 0; i < 8; i++ )
{ // For each Direction
- skill->unit_layout[pos].count = 15;
+ skill->dbs->unit_layout[pos].count = 15;
switch( i )
{
case 0: case 1: case 3: case 4: case 5: case 7:
{
int dx[] = {-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7};
int dy[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- memcpy(skill->unit_layout[pos].dx,dx,sizeof(dx));
- memcpy(skill->unit_layout[pos].dy,dy,sizeof(dy));
+ memcpy(skill->dbs->unit_layout[pos].dx,dx,sizeof(dx));
+ memcpy(skill->dbs->unit_layout[pos].dy,dy,sizeof(dy));
}
break;
case 2:
@@ -18333,8 +18346,8 @@ void skill_init_unit_layout (void)
{
int dx[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int dy[] = {-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7};
- memcpy(skill->unit_layout[pos].dx,dx,sizeof(dx));
- memcpy(skill->unit_layout[pos].dy,dy,sizeof(dy));
+ memcpy(skill->dbs->unit_layout[pos].dx,dx,sizeof(dx));
+ memcpy(skill->dbs->unit_layout[pos].dy,dy,sizeof(dy));
}
break;
}
@@ -18581,36 +18594,36 @@ bool skill_parse_row_skilldb(char* split[], int columns, int current) {
if( !idx ) // invalid skill id
return false;
- skill->db[idx].nameid = skill_id;
- skill->split_atoi(split[1],skill->db[idx].range);
- skill->db[idx].hit = atoi(split[2]);
- skill->db[idx].inf = atoi(split[3]);
- skill->split_atoi(split[4],skill->db[idx].element);
- skill->db[idx].nk = (int)strtol(split[5], NULL, 0);
- skill->split_atoi(split[6],skill->db[idx].splash);
- skill->db[idx].max = atoi(split[7]);
- skill->split_atoi(split[8],skill->db[idx].num);
+ skill->dbs->db[idx].nameid = skill_id;
+ skill->split_atoi(split[1],skill->dbs->db[idx].range);
+ skill->dbs->db[idx].hit = atoi(split[2]);
+ skill->dbs->db[idx].inf = atoi(split[3]);
+ skill->split_atoi(split[4],skill->dbs->db[idx].element);
+ skill->dbs->db[idx].nk = (int)strtol(split[5], NULL, 0);
+ skill->split_atoi(split[6],skill->dbs->db[idx].splash);
+ skill->dbs->db[idx].max = atoi(split[7]);
+ skill->split_atoi(split[8],skill->dbs->db[idx].num);
if( strcmpi(split[9],"yes") == 0 )
- skill->db[idx].castcancel = 1;
+ skill->dbs->db[idx].castcancel = 1;
else
- skill->db[idx].castcancel = 0;
- skill->db[idx].cast_def_rate = atoi(split[10]);
- skill->db[idx].inf2 = (int)strtol(split[11], NULL, 0);
- skill->split_atoi(split[12],skill->db[idx].maxcount);
+ skill->dbs->db[idx].castcancel = 0;
+ skill->dbs->db[idx].cast_def_rate = atoi(split[10]);
+ skill->dbs->db[idx].inf2 = (int)strtol(split[11], NULL, 0);
+ skill->split_atoi(split[12],skill->dbs->db[idx].maxcount);
if( strcmpi(split[13],"weapon") == 0 )
- skill->db[idx].skill_type = BF_WEAPON;
+ skill->dbs->db[idx].skill_type = BF_WEAPON;
else if( strcmpi(split[13],"magic") == 0 )
- skill->db[idx].skill_type = BF_MAGIC;
+ skill->dbs->db[idx].skill_type = BF_MAGIC;
else if( strcmpi(split[13],"misc") == 0 )
- skill->db[idx].skill_type = BF_MISC;
+ skill->dbs->db[idx].skill_type = BF_MISC;
else
- skill->db[idx].skill_type = 0;
- skill->split_atoi(split[14],skill->db[idx].blewcount);
- safestrncpy(skill->db[idx].name, trim(split[15]), sizeof(skill->db[idx].name));
- safestrncpy(skill->db[idx].desc, trim(split[16]), sizeof(skill->db[idx].desc));
- strdb_iput(skill->name2id_db, skill->db[idx].name, skill_id);
- script->set_constant2(skill->db[idx].name,(int)skill_id,0);
+ skill->dbs->db[idx].skill_type = 0;
+ skill->split_atoi(split[14],skill->dbs->db[idx].blewcount);
+ safestrncpy(skill->dbs->db[idx].name, trim(split[15]), sizeof(skill->dbs->db[idx].name));
+ safestrncpy(skill->dbs->db[idx].desc, trim(split[16]), sizeof(skill->dbs->db[idx].desc));
+ strdb_iput(skill->name2id_db, skill->dbs->db[idx].name, skill_id);
+ script->set_constant2(skill->dbs->db[idx].name,(int)skill_id,0);
return true;
}
@@ -18625,22 +18638,22 @@ bool skill_parse_row_requiredb(char* split[], int columns, int current) {
if( !idx ) // invalid skill id
return false;
- skill->split_atoi(split[1],skill->db[idx].hp);
- skill->split_atoi(split[2],skill->db[idx].mhp);
- skill->split_atoi(split[3],skill->db[idx].sp);
- skill->split_atoi(split[4],skill->db[idx].hp_rate);
- skill->split_atoi(split[5],skill->db[idx].sp_rate);
- skill->split_atoi(split[6],skill->db[idx].zeny);
+ skill->split_atoi(split[1],skill->dbs->db[idx].hp);
+ skill->split_atoi(split[2],skill->dbs->db[idx].mhp);
+ skill->split_atoi(split[3],skill->dbs->db[idx].sp);
+ skill->split_atoi(split[4],skill->dbs->db[idx].hp_rate);
+ skill->split_atoi(split[5],skill->dbs->db[idx].sp_rate);
+ skill->split_atoi(split[6],skill->dbs->db[idx].zeny);
//Which weapon type are required, see doc/item_db for types
p = split[7];
for( j = 0; j < 32; j++ ) {
int l = atoi(p);
if( l == 99 ) { // Any weapon
- skill->db[idx].weapon = 0;
+ skill->dbs->db[idx].weapon = 0;
break;
} else
- skill->db[idx].weapon |= 1<<l;
+ skill->dbs->db[idx].weapon |= 1<<l;
p = strchr(p,':');
if(!p)
break;
@@ -18652,49 +18665,49 @@ bool skill_parse_row_requiredb(char* split[], int columns, int current) {
for( j = 0; j < 32; j++ ) {
int l = atoi(p);
if( l == 99 ) { // Any ammo type
- skill->db[idx].ammo = 0xFFFFFFFF;
+ skill->dbs->db[idx].ammo = 0xFFFFFFFF;
break;
} else if( l ) // 0 stands for no requirement
- skill->db[idx].ammo |= 1<<l;
+ skill->dbs->db[idx].ammo |= 1<<l;
p = strchr(p,':');
if( !p )
break;
p++;
}
- skill->split_atoi(split[9],skill->db[idx].ammo_qty);
-
- if( strcmpi(split[10],"hiding") == 0 ) skill->db[idx].state = ST_HIDING;
- else if( strcmpi(split[10],"cloaking") == 0 ) skill->db[idx].state = ST_CLOAKING;
- else if( strcmpi(split[10],"hidden") == 0 ) skill->db[idx].state = ST_HIDDEN;
- else if( strcmpi(split[10],"riding") == 0 ) skill->db[idx].state = ST_RIDING;
- else if( strcmpi(split[10],"falcon") == 0 ) skill->db[idx].state = ST_FALCON;
- else if( strcmpi(split[10],"cart") == 0 ) skill->db[idx].state = ST_CART;
- else if( strcmpi(split[10],"shield") == 0 ) skill->db[idx].state = ST_SHIELD;
- else if( strcmpi(split[10],"sight") == 0 ) skill->db[idx].state = ST_SIGHT;
- else if( strcmpi(split[10],"explosionspirits") == 0 ) skill->db[idx].state = ST_EXPLOSIONSPIRITS;
- else if( strcmpi(split[10],"cartboost") == 0 ) skill->db[idx].state = ST_CARTBOOST;
- else if( strcmpi(split[10],"recover_weight_rate") == 0 ) skill->db[idx].state = ST_RECOV_WEIGHT_RATE;
- else if( strcmpi(split[10],"move_enable") == 0 ) skill->db[idx].state = ST_MOVE_ENABLE;
- else if( strcmpi(split[10],"water") == 0 ) skill->db[idx].state = ST_WATER;
- else if( strcmpi(split[10],"dragon") == 0 ) skill->db[idx].state = ST_RIDINGDRAGON;
- else if( strcmpi(split[10],"warg") == 0 ) skill->db[idx].state = ST_WUG;
- else if( strcmpi(split[10],"ridingwarg") == 0 ) skill->db[idx].state = ST_RIDINGWUG;
- else if( strcmpi(split[10],"mado") == 0 ) skill->db[idx].state = ST_MADO;
- else if( strcmpi(split[10],"elementalspirit") == 0 ) skill->db[idx].state = ST_ELEMENTALSPIRIT;
- else if( strcmpi(split[10],"poisonweapon") == 0 ) skill->db[idx].state = ST_POISONINGWEAPON;
- else if( strcmpi(split[10],"rollingcutter") == 0 ) skill->db[idx].state = ST_ROLLINGCUTTER;
- else if( strcmpi(split[10],"mh_fighting") == 0 ) skill->db[idx].state = ST_MH_FIGHTING;
- else if( strcmpi(split[10],"mh_grappling") == 0 ) skill->db[idx].state = ST_MH_GRAPPLING;
- else if( strcmpi(split[10],"peco") == 0 ) skill->db[idx].state = ST_PECO;
+ skill->split_atoi(split[9],skill->dbs->db[idx].ammo_qty);
+
+ if( strcmpi(split[10],"hiding") == 0 ) skill->dbs->db[idx].state = ST_HIDING;
+ else if( strcmpi(split[10],"cloaking") == 0 ) skill->dbs->db[idx].state = ST_CLOAKING;
+ else if( strcmpi(split[10],"hidden") == 0 ) skill->dbs->db[idx].state = ST_HIDDEN;
+ else if( strcmpi(split[10],"riding") == 0 ) skill->dbs->db[idx].state = ST_RIDING;
+ else if( strcmpi(split[10],"falcon") == 0 ) skill->dbs->db[idx].state = ST_FALCON;
+ else if( strcmpi(split[10],"cart") == 0 ) skill->dbs->db[idx].state = ST_CART;
+ else if( strcmpi(split[10],"shield") == 0 ) skill->dbs->db[idx].state = ST_SHIELD;
+ else if( strcmpi(split[10],"sight") == 0 ) skill->dbs->db[idx].state = ST_SIGHT;
+ else if( strcmpi(split[10],"explosionspirits") == 0 ) skill->dbs->db[idx].state = ST_EXPLOSIONSPIRITS;
+ else if( strcmpi(split[10],"cartboost") == 0 ) skill->dbs->db[idx].state = ST_CARTBOOST;
+ else if( strcmpi(split[10],"recover_weight_rate") == 0 ) skill->dbs->db[idx].state = ST_RECOV_WEIGHT_RATE;
+ else if( strcmpi(split[10],"move_enable") == 0 ) skill->dbs->db[idx].state = ST_MOVE_ENABLE;
+ else if( strcmpi(split[10],"water") == 0 ) skill->dbs->db[idx].state = ST_WATER;
+ else if( strcmpi(split[10],"dragon") == 0 ) skill->dbs->db[idx].state = ST_RIDINGDRAGON;
+ else if( strcmpi(split[10],"warg") == 0 ) skill->dbs->db[idx].state = ST_WUG;
+ else if( strcmpi(split[10],"ridingwarg") == 0 ) skill->dbs->db[idx].state = ST_RIDINGWUG;
+ else if( strcmpi(split[10],"mado") == 0 ) skill->dbs->db[idx].state = ST_MADO;
+ else if( strcmpi(split[10],"elementalspirit") == 0 ) skill->dbs->db[idx].state = ST_ELEMENTALSPIRIT;
+ else if( strcmpi(split[10],"poisonweapon") == 0 ) skill->dbs->db[idx].state = ST_POISONINGWEAPON;
+ else if( strcmpi(split[10],"rollingcutter") == 0 ) skill->dbs->db[idx].state = ST_ROLLINGCUTTER;
+ else if( strcmpi(split[10],"mh_fighting") == 0 ) skill->dbs->db[idx].state = ST_MH_FIGHTING;
+ else if( strcmpi(split[10],"mh_grappling") == 0 ) skill->dbs->db[idx].state = ST_MH_GRAPPLING;
+ else if( strcmpi(split[10],"peco") == 0 ) skill->dbs->db[idx].state = ST_PECO;
/**
* Unknown or no state
**/
- else skill->db[idx].state = ST_NONE;
+ else skill->dbs->db[idx].state = ST_NONE;
- skill->split_atoi(split[11],skill->db[idx].spiritball);
+ skill->split_atoi(split[11],skill->dbs->db[idx].spiritball);
for( j = 0; j < MAX_SKILL_ITEM_REQUIRE; j++ ) {
- skill->db[idx].itemid[j] = atoi(split[12+ 2*j]);
- skill->db[idx].amount[j] = atoi(split[13+ 2*j]);
+ skill->dbs->db[idx].itemid[j] = atoi(split[12+ 2*j]);
+ skill->dbs->db[idx].amount[j] = atoi(split[13+ 2*j]);
}
return true;
@@ -18707,14 +18720,14 @@ bool skill_parse_row_castdb(char* split[], int columns, int current) {
if( !idx ) // invalid skill id
return false;
- skill->split_atoi(split[1],skill->db[idx].cast);
- skill->split_atoi(split[2],skill->db[idx].delay);
- skill->split_atoi(split[3],skill->db[idx].walkdelay);
- skill->split_atoi(split[4],skill->db[idx].upkeep_time);
- skill->split_atoi(split[5],skill->db[idx].upkeep_time2);
- skill->split_atoi(split[6],skill->db[idx].cooldown);
+ skill->split_atoi(split[1],skill->dbs->db[idx].cast);
+ skill->split_atoi(split[2],skill->dbs->db[idx].delay);
+ skill->split_atoi(split[3],skill->dbs->db[idx].walkdelay);
+ skill->split_atoi(split[4],skill->dbs->db[idx].upkeep_time);
+ skill->split_atoi(split[5],skill->dbs->db[idx].upkeep_time2);
+ skill->split_atoi(split[6],skill->dbs->db[idx].cooldown);
#ifdef RENEWAL_CAST
- skill->split_atoi(split[7],skill->db[idx].fixed_cast);
+ skill->split_atoi(split[7],skill->dbs->db[idx].fixed_cast);
#endif
return true;
}
@@ -18726,9 +18739,9 @@ bool skill_parse_row_castnodexdb(char* split[], int columns, int current) {
if( !idx ) // invalid skill id
return false;
- skill->split_atoi(split[1],skill->db[idx].castnodex);
+ skill->split_atoi(split[1],skill->dbs->db[idx].castnodex);
if( split[2] ) // optional column
- skill->split_atoi(split[2],skill->db[idx].delaynodex);
+ skill->split_atoi(split[2],skill->dbs->db[idx].delaynodex);
return true;
}
@@ -18740,37 +18753,37 @@ bool skill_parse_row_unitdb(char* split[], int columns, int current) {
if( !idx ) // invalid skill id
return false;
- skill->db[idx].unit_id[0] = (int)strtol(split[1],NULL,16);
- skill->db[idx].unit_id[1] = (int)strtol(split[2],NULL,16);
- skill->split_atoi(split[3],skill->db[idx].unit_layout_type);
- skill->split_atoi(split[4],skill->db[idx].unit_range);
- skill->db[idx].unit_interval = atoi(split[5]);
-
- if( strcmpi(split[6],"noenemy")==0 ) skill->db[idx].unit_target = BCT_NOENEMY;
- else if( strcmpi(split[6],"friend")==0 ) skill->db[idx].unit_target = BCT_NOENEMY;
- else if( strcmpi(split[6],"party")==0 ) skill->db[idx].unit_target = BCT_PARTY;
- else if( strcmpi(split[6],"ally")==0 ) skill->db[idx].unit_target = BCT_PARTY|BCT_GUILD;
- else if( strcmpi(split[6],"guild")==0 ) skill->db[idx].unit_target = BCT_GUILD;
- else if( strcmpi(split[6],"all")==0 ) skill->db[idx].unit_target = BCT_ALL;
- else if( strcmpi(split[6],"enemy")==0 ) skill->db[idx].unit_target = BCT_ENEMY;
- else if( strcmpi(split[6],"self")==0 ) skill->db[idx].unit_target = BCT_SELF;
- else if( strcmpi(split[6],"sameguild")==0 ) skill->db[idx].unit_target = BCT_GUILD|BCT_SAMEGUILD;
- else if( strcmpi(split[6],"noone")==0 ) skill->db[idx].unit_target = BCT_NOONE;
- else skill->db[idx].unit_target = (int)strtol(split[6],NULL,16);
-
- skill->db[idx].unit_flag = (int)strtol(split[7],NULL,16);
-
- if (skill->db[idx].unit_flag&UF_DEFNOTENEMY && battle_config.defnotenemy)
- skill->db[idx].unit_target = BCT_NOENEMY;
+ skill->dbs->db[idx].unit_id[0] = (int)strtol(split[1],NULL,16);
+ skill->dbs->db[idx].unit_id[1] = (int)strtol(split[2],NULL,16);
+ skill->split_atoi(split[3],skill->dbs->db[idx].unit_layout_type);
+ skill->split_atoi(split[4],skill->dbs->db[idx].unit_range);
+ skill->dbs->db[idx].unit_interval = atoi(split[5]);
+
+ if( strcmpi(split[6],"noenemy")==0 ) skill->dbs->db[idx].unit_target = BCT_NOENEMY;
+ else if( strcmpi(split[6],"friend")==0 ) skill->dbs->db[idx].unit_target = BCT_NOENEMY;
+ else if( strcmpi(split[6],"party")==0 ) skill->dbs->db[idx].unit_target = BCT_PARTY;
+ else if( strcmpi(split[6],"ally")==0 ) skill->dbs->db[idx].unit_target = BCT_PARTY|BCT_GUILD;
+ else if( strcmpi(split[6],"guild")==0 ) skill->dbs->db[idx].unit_target = BCT_GUILD;
+ else if( strcmpi(split[6],"all")==0 ) skill->dbs->db[idx].unit_target = BCT_ALL;
+ else if( strcmpi(split[6],"enemy")==0 ) skill->dbs->db[idx].unit_target = BCT_ENEMY;
+ else if( strcmpi(split[6],"self")==0 ) skill->dbs->db[idx].unit_target = BCT_SELF;
+ else if( strcmpi(split[6],"sameguild")==0 ) skill->dbs->db[idx].unit_target = BCT_GUILD|BCT_SAMEGUILD;
+ else if( strcmpi(split[6],"noone")==0 ) skill->dbs->db[idx].unit_target = BCT_NOONE;
+ else skill->dbs->db[idx].unit_target = (int)strtol(split[6],NULL,16);
+
+ skill->dbs->db[idx].unit_flag = (int)strtol(split[7],NULL,16);
+
+ if (skill->dbs->db[idx].unit_flag&UF_DEFNOTENEMY && battle_config.defnotenemy)
+ skill->dbs->db[idx].unit_target = BCT_NOENEMY;
//By default, target just characters.
- skill->db[idx].unit_target |= BL_CHAR;
- if (skill->db[idx].unit_flag&UF_NOPC)
- skill->db[idx].unit_target &= ~BL_PC;
- if (skill->db[idx].unit_flag&UF_NOMOB)
- skill->db[idx].unit_target &= ~BL_MOB;
- if (skill->db[idx].unit_flag&UF_SKILL)
- skill->db[idx].unit_target |= BL_SKILL;
+ skill->dbs->db[idx].unit_target |= BL_CHAR;
+ if (skill->dbs->db[idx].unit_flag&UF_NOPC)
+ skill->dbs->db[idx].unit_target &= ~BL_PC;
+ if (skill->dbs->db[idx].unit_flag&UF_NOMOB)
+ skill->dbs->db[idx].unit_target &= ~BL_MOB;
+ if (skill->dbs->db[idx].unit_flag&UF_SKILL)
+ skill->dbs->db[idx].unit_target |= BL_SKILL;
return true;
}
@@ -18783,14 +18796,14 @@ bool skill_parse_row_producedb(char* split[], int columns, int current) {
if( !i )
return false;
- skill->produce_db[current].nameid = i;
- skill->produce_db[current].itemlv = atoi(split[1]);
- skill->produce_db[current].req_skill = atoi(split[2]);
- skill->produce_db[current].req_skill_lv = atoi(split[3]);
+ skill->dbs->produce_db[current].nameid = i;
+ skill->dbs->produce_db[current].itemlv = atoi(split[1]);
+ skill->dbs->produce_db[current].req_skill = atoi(split[2]);
+ skill->dbs->produce_db[current].req_skill_lv = atoi(split[3]);
for( x = 4, y = 0; x+1 < columns && split[x] && split[x+1] && y < MAX_PRODUCE_RESOURCE; x += 2, y++ ) {
- skill->produce_db[current].mat_id[y] = atoi(split[x]);
- skill->produce_db[current].mat_amount[y] = atoi(split[x+1]);
+ skill->dbs->produce_db[current].mat_id[y] = atoi(split[x]);
+ skill->dbs->produce_db[current].mat_amount[y] = atoi(split[x+1]);
}
return true;
@@ -18804,11 +18817,11 @@ bool skill_parse_row_createarrowdb(char* split[], int columns, int current) {
if( !i )
return false;
- skill->arrow_db[current].nameid = i;
+ skill->dbs->arrow_db[current].nameid = i;
for( x = 1, y = 0; x+1 < columns && split[x] && split[x+1] && y < MAX_ARROW_RESOURCE; x += 2, y++ ) {
- skill->arrow_db[current].cre_id[y] = atoi(split[x]);
- skill->arrow_db[current].cre_amount[y] = atoi(split[x+1]);
+ skill->dbs->arrow_db[current].cre_id[y] = atoi(split[x]);
+ skill->dbs->arrow_db[current].cre_amount[y] = atoi(split[x+1]);
}
return true;
@@ -18827,9 +18840,9 @@ bool skill_parse_row_spellbookdb(char* split[], int columns, int current) {
if( points < 1 )
ShowError("spellbook_db: PreservePoints have to be 1 or above! (%d/%s)\n", skill_id, skill->get_name(skill_id));
else {
- skill->spellbook_db[current].skill_id = skill_id;
- skill->spellbook_db[current].point = points;
- skill->spellbook_db[current].nameid = nameid;
+ skill->dbs->spellbook_db[current].skill_id = skill_id;
+ skill->dbs->spellbook_db[current].point = points;
+ skill->dbs->spellbook_db[current].nameid = nameid;
return true;
}
@@ -18857,8 +18870,8 @@ bool skill_parse_row_improvisedb(char* split[], int columns, int current) {
ShowError("skill_improvise_db: Maximum amount of entries reached (%d), increase MAX_SKILL_IMPROVISE_DB\n",MAX_SKILL_IMPROVISE_DB);
return false;
}
- skill->improvise_db[current].skill_id = skill_id;
- skill->improvise_db[current].per = j; // Still need confirm it.
+ skill->dbs->improvise_db[current].skill_id = skill_id;
+ skill->dbs->improvise_db[current].per = j; // Still need confirm it.
return true;
}
@@ -18875,7 +18888,7 @@ bool skill_parse_row_magicmushroomdb(char* split[], int column, int current) {
return false;
}
- skill->magicmushroom_db[current].skill_id = skill_id;
+ skill->dbs->magicmushroom_db[current].skill_id = skill_id;
return true;
}
@@ -18886,7 +18899,7 @@ bool skill_parse_row_reproducedb(char* split[], int column, int current) {
if( !idx )
return false;
- skill->reproduce_db[idx] = true;
+ skill->dbs->reproduce_db[idx] = true;
return true;
}
@@ -18904,9 +18917,9 @@ bool skill_parse_row_abradb(char* split[], int columns, int current) {
return false;
}
- skill->abra_db[current].skill_id = skill_id;
- skill->abra_db[current].req_lv = atoi(split[2]);
- skill->abra_db[current].per = atoi(split[3]);
+ skill->dbs->abra_db[current].skill_id = skill_id;
+ skill->dbs->abra_db[current].req_lv = atoi(split[2]);
+ skill->dbs->abra_db[current].per = atoi(split[3]);
return true;
}
@@ -18918,8 +18931,8 @@ bool skill_parse_row_changematerialdb(char* split[], int columns, int current) {
int x,y;
for(x=0; x<MAX_SKILL_PRODUCE_DB; x++){
- if( skill->produce_db[x].nameid == skill_id )
- if( skill->produce_db[x].req_skill == GN_CHANGEMATERIAL )
+ if( skill->dbs->produce_db[x].nameid == skill_id )
+ if( skill->dbs->produce_db[x].req_skill == GN_CHANGEMATERIAL )
break;
}
@@ -18933,12 +18946,12 @@ bool skill_parse_row_changematerialdb(char* split[], int columns, int current) {
return false;
}
- skill->changematerial_db[current].itemid = skill_id;
- skill->changematerial_db[current].rate = j;
+ skill->dbs->changematerial_db[current].itemid = skill_id;
+ skill->dbs->changematerial_db[current].rate = j;
for( x = 2, y = 0; x+1 < columns && split[x] && split[x+1] && y < 5; x += 2, y++ ) {
- skill->changematerial_db[current].qty[y] = atoi(split[x]);
- skill->changematerial_db[current].qty_rate[y] = atoi(split[x+1]);
+ skill->dbs->changematerial_db[current].qty[y] = atoi(split[x]);
+ skill->dbs->changematerial_db[current].qty_rate[y] = atoi(split[x+1]);
}
return true;
@@ -18962,21 +18975,12 @@ void skill_readdb(bool minimal) {
/* when != it was called during init and this procedure was already performed by skill_defaults() */
if( runflag == MAPSERVER_ST_RUNNING ) {
- memset(skill->db,0,sizeof(skill->db)
- + sizeof(skill->produce_db)
- + sizeof(skill->arrow_db)
- + sizeof(skill->abra_db)
- + sizeof(skill->magicmushroom_db)
- + sizeof(skill->improvise_db)
- + sizeof(skill->changematerial_db)
- + sizeof(skill->spellbook_db)
- + sizeof(skill->reproduce_db)
- );
+ memset(ZEROED_BLOCK_POS(skill->dbs), 0, ZEROED_BLOCK_SIZE(skill->dbs));
}
// load skill databases
- safestrncpy(skill->db[0].name, "UNKNOWN_SKILL", sizeof(skill->db[0].name));
- safestrncpy(skill->db[0].desc, "Unknown Skill", sizeof(skill->db[0].desc));
+ safestrncpy(skill->dbs->db[0].name, "UNKNOWN_SKILL", sizeof(skill->dbs->db[0].name));
+ safestrncpy(skill->dbs->db[0].desc, "Unknown Skill", sizeof(skill->dbs->db[0].desc));
#ifdef ENABLE_CASE_CHECK
script->parser_current_file = DBPATH"skill_db.txt";
@@ -19094,6 +19098,8 @@ void skill_defaults(void) {
const int skill_deluge_eff[5] = { 5, 9, 12, 14, 15 };
skill = &skill_s;
+ skill->dbs = &skilldbs;
+
skill->init = do_init_skill;
skill->final = do_final_skill;
skill->reload = skill_reload;
@@ -19110,18 +19116,10 @@ void skill_defaults(void) {
skill->timer_ers = NULL;
skill->cd_ers = NULL;
skill->cd_entry_ers = NULL;
- /* one huge 0, follows skill.h order */
- memset(skill->db,0,sizeof(skill->db)
- + sizeof(skill->produce_db)
- + sizeof(skill->arrow_db)
- + sizeof(skill->abra_db)
- + sizeof(skill->magicmushroom_db)
- + sizeof(skill->improvise_db)
- + sizeof(skill->changematerial_db)
- + sizeof(skill->spellbook_db)
- + sizeof(skill->reproduce_db)
- + sizeof(skill->unit_layout)
- );
+
+ memset(ZEROED_BLOCK_POS(skill->dbs), 0, ZEROED_BLOCK_SIZE(skill->dbs));
+ memset(skill->dbs->unit_layout, 0, sizeof(skill->dbs->unit_layout));
+
/* */
memcpy(skill->enchant_eff, skill_enchant_eff, sizeof(skill->enchant_eff));
memcpy(skill->deluge_eff, skill_deluge_eff, sizeof(skill->deluge_eff));
diff --git a/src/map/skill.h b/src/map/skill.h
index b598b91c8..aa0188be6 100644
--- a/src/map/skill.h
+++ b/src/map/skill.h
@@ -5,13 +5,13 @@
#ifndef MAP_SKILL_H
#define MAP_SKILL_H
-#include "../config/core.h" // RENEWAL_CAST
+#include "config/core.h" // RENEWAL_CAST
-#include "map.h" // struct block_list
-#include "status.h" // enum sc_type
-#include "../common/cbasetypes.h"
-#include "../common/db.h"
-#include "../common/mmo.h" // MAX_SKILL, struct square
+#include "map/map.h" // struct block_list
+#include "map/status.h" // enum sc_type
+#include "common/cbasetypes.h"
+#include "common/db.h"
+#include "common/mmo.h" // MAX_SKILL, struct square
/**
* Declarations
@@ -1732,6 +1732,7 @@ struct skill_unit {
int limit;
int val1,val2;
short alive,range;
+ int prev;
};
struct skill_unit_group_tickset {
@@ -1813,6 +1814,21 @@ struct s_skill_spellbook_db {
typedef int (*SkillFunc)(struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, int64 tick, int flag);
+struct s_skill_dbs {
+BEGIN_ZEROED_BLOCK; // This block will be zeroed in skill_defaults() as well as skill_readdb()
+ struct s_skill_db db[MAX_SKILL_DB];
+ struct s_skill_produce_db produce_db[MAX_SKILL_PRODUCE_DB];
+ struct s_skill_arrow_db arrow_db[MAX_SKILL_ARROW_DB];
+ struct s_skill_abra_db abra_db[MAX_SKILL_ABRA_DB];
+ struct s_skill_magicmushroom_db magicmushroom_db[MAX_SKILL_MAGICMUSHROOM_DB];
+ struct s_skill_improvise_db improvise_db[MAX_SKILL_IMPROVISE_DB];
+ struct s_skill_changematerial_db changematerial_db[MAX_SKILL_PRODUCE_DB];
+ struct s_skill_spellbook_db spellbook_db[MAX_SKILL_SPELLBOOK_DB];
+ bool reproduce_db[MAX_SKILL_DB];
+END_ZEROED_BLOCK;
+ struct s_skill_unit_layout unit_layout[MAX_SKILL_UNIT_LAYOUT];
+};
+
/**
* Skill.c Interface
**/
@@ -1834,16 +1850,7 @@ struct skill_interface {
struct eri *cd_ers; // ERS Storage for skill cool down managers [Ind/Hercules]
struct eri *cd_entry_ers; // ERS Storage for skill cool down entries [Ind/Hercules]
/* */
- struct s_skill_db db[MAX_SKILL_DB];
- struct s_skill_produce_db produce_db[MAX_SKILL_PRODUCE_DB];
- struct s_skill_arrow_db arrow_db[MAX_SKILL_ARROW_DB];
- struct s_skill_abra_db abra_db[MAX_SKILL_ABRA_DB];
- struct s_skill_magicmushroom_db magicmushroom_db[MAX_SKILL_MAGICMUSHROOM_DB];
- struct s_skill_improvise_db improvise_db[MAX_SKILL_IMPROVISE_DB];
- struct s_skill_changematerial_db changematerial_db[MAX_SKILL_PRODUCE_DB];
- struct s_skill_spellbook_db spellbook_db[MAX_SKILL_SPELLBOOK_DB];
- bool reproduce_db[MAX_SKILL_DB];
- struct s_skill_unit_layout unit_layout[MAX_SKILL_UNIT_LAYOUT];
+ struct s_skill_dbs *dbs;
/* */
int enchant_eff[5];
int deluge_eff[5];
diff --git a/src/map/status.c b/src/map/status.c
index 16f5f3906..b513c6975 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -4,9 +4,38 @@
#define HERCULES_CORE
-#include "../config/core.h" // ANTI_MAYAP_CHEAT, DBPATH, DEFTYPE_MAX, DEFTYPE_MIN, DEVOTION_REFLECT_DAMAGE, RENEWAL, RENEWAL_ASPD, RENEWAL_EDP
+#include "config/core.h" // ANTI_MAYAP_CHEAT, DBPATH, DEFTYPE_MAX, DEFTYPE_MIN, DEVOTION_REFLECT_DAMAGE, RENEWAL, RENEWAL_ASPD, RENEWAL_EDP
#include "status.h"
+#include "map/battle.h"
+#include "map/chrif.h"
+#include "map/clif.h"
+#include "map/elemental.h"
+#include "map/guild.h"
+#include "map/homunculus.h"
+#include "map/itemdb.h"
+#include "map/map.h"
+#include "map/mercenary.h"
+#include "map/mob.h"
+#include "map/npc.h"
+#include "map/path.h"
+#include "map/pc.h"
+#include "map/pet.h"
+#include "map/script.h"
+#include "map/skill.h"
+#include "map/skill.h"
+#include "map/unit.h"
+#include "map/vending.h"
+#include "common/cbasetypes.h"
+#include "common/ers.h"
+#include "common/malloc.h"
+#include "common/nullpo.h"
+#include "common/random.h"
+#include "common/showmsg.h"
+#include "common/strlib.h"
+#include "common/timer.h"
+#include "common/utils.h"
+
#include <math.h>
#include <memory.h>
#include <stdio.h>
@@ -14,36 +43,8 @@
#include <string.h>
#include <time.h>
-#include "battle.h"
-#include "chrif.h"
-#include "clif.h"
-#include "elemental.h"
-#include "guild.h"
-#include "homunculus.h"
-#include "itemdb.h"
-#include "map.h"
-#include "mercenary.h"
-#include "mob.h"
-#include "npc.h"
-#include "path.h"
-#include "pc.h"
-#include "pet.h"
-#include "script.h"
-#include "skill.h"
-#include "skill.h"
-#include "unit.h"
-#include "vending.h"
-#include "../common/cbasetypes.h"
-#include "../common/ers.h"
-#include "../common/malloc.h"
-#include "../common/nullpo.h"
-#include "../common/random.h"
-#include "../common/showmsg.h"
-#include "../common/strlib.h"
-#include "../common/timer.h"
-#include "../common/utils.h"
-
struct status_interface status_s;
+struct s_status_dbs statusdbs;
/**
* Returns the status change associated with a skill.
@@ -56,7 +57,7 @@ sc_type status_skill2sc(int skill_id) {
ShowError("status_skill2sc: Unsupported skill id %d\n", skill_id);
return SC_NONE;
}
- return status->Skill2SCTable[idx];
+ return status->dbs->Skill2SCTable[idx];
}
/**
@@ -72,7 +73,7 @@ int status_sc2skill(sc_type sc)
return 0;
}
- return status->SkillChangeTable[sc];
+ return status->dbs->SkillChangeTable[sc];
}
/**
@@ -87,7 +88,7 @@ unsigned int status_sc2scb_flag(sc_type sc)
return SCB_NONE;
}
- return status->ChangeFlagTable[sc];
+ return status->dbs->ChangeFlagTable[sc];
}
/**
@@ -102,7 +103,7 @@ int status_type2relevant_bl_types(int type)
return BL_NUL;
}
- return status->RelevantBLTypes[type];
+ return status->dbs->RelevantBLTypes[type];
}
static void set_sc(uint16 skill_id, sc_type sc, int icon, unsigned int flag) {
@@ -116,35 +117,35 @@ static void set_sc(uint16 skill_id, sc_type sc, int icon, unsigned int flag) {
return;
}
- if( status->SkillChangeTable[sc] == 0 )
- status->SkillChangeTable[sc] = skill_id;
- if( status->IconChangeTable[sc] == SI_BLANK )
- status->IconChangeTable[sc] = icon;
- status->ChangeFlagTable[sc] |= flag;
+ if( status->dbs->SkillChangeTable[sc] == 0 )
+ status->dbs->SkillChangeTable[sc] = skill_id;
+ if( status->dbs->IconChangeTable[sc] == SI_BLANK )
+ status->dbs->IconChangeTable[sc] = icon;
+ status->dbs->ChangeFlagTable[sc] |= flag;
- if( status->Skill2SCTable[idx] == SC_NONE )
- status->Skill2SCTable[idx] = sc;
+ if( status->dbs->Skill2SCTable[idx] == SC_NONE )
+ status->dbs->Skill2SCTable[idx] = sc;
}
void initChangeTables(void) {
#define add_sc(skill,sc) set_sc((skill),(sc),SI_BLANK,SCB_NONE)
// indicates that the status displays a visual effect for the affected unit, and should be sent to the client for all supported units
-#define set_sc_with_vfx(skill, sc, icon, flag) do { set_sc((skill), (sc), (icon), (flag)); if((icon) < SI_MAX) status->RelevantBLTypes[(icon)] |= BL_SCEFFECT; } while(0)
+#define set_sc_with_vfx(skill, sc, icon, flag) do { set_sc((skill), (sc), (icon), (flag)); if((icon) < SI_MAX) status->dbs->RelevantBLTypes[(icon)] |= BL_SCEFFECT; } while(0)
int i;
for (i = 0; i < SC_MAX; i++)
- status->IconChangeTable[i] = SI_BLANK;
+ status->dbs->IconChangeTable[i] = SI_BLANK;
for (i = 0; i < MAX_SKILL; i++)
- status->Skill2SCTable[i] = SC_NONE;
+ status->dbs->Skill2SCTable[i] = SC_NONE;
for (i = 0; i < SI_MAX; i++)
- status->RelevantBLTypes[i] = BL_PC;
+ status->dbs->RelevantBLTypes[i] = BL_PC;
- memset(status->SkillChangeTable, 0, sizeof(status->SkillChangeTable));
- memset(status->ChangeFlagTable, 0, sizeof(status->ChangeFlagTable));
- memset(status->DisplayType, 0, sizeof(status->DisplayType));
+ memset(status->dbs->SkillChangeTable, 0, sizeof(status->dbs->SkillChangeTable));
+ memset(status->dbs->ChangeFlagTable, 0, sizeof(status->dbs->ChangeFlagTable));
+ memset(status->dbs->DisplayType, 0, sizeof(status->dbs->DisplayType));
//First we define the skill for common ailments. These are used in skill_additional_effect through sc cards. [Skotlex]
set_sc( NPC_PETRIFYATTACK , SC_STONE , SI_BLANK , SCB_DEF_ELE|SCB_DEF|SCB_MDEF );
@@ -654,7 +655,7 @@ void initChangeTables(void) {
set_sc( MI_RUSH_WINDMILL , SC_RUSH_WINDMILL , SI_RUSHWINDMILL , SCB_WATK );
set_sc( MI_ECHOSONG , SC_ECHOSONG , SI_ECHOSONG , SCB_DEF2 );
set_sc( MI_HARMONIZE , SC_HARMONIZE , SI_HARMONIZE , SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK );
- set_sc( WM_POEMOFNETHERWORLD , SC_STOP , SI_NETHERWORLD , SCB_NONE );
+ set_sc_with_vfx(WM_POEMOFNETHERWORLD, SC_NETHERWORLD , SI_NETHERWORLD , SCB_NONE);
set_sc_with_vfx( WM_VOICEOFSIREN , SC_SIREN , SI_SIREN , SCB_NONE );
set_sc_with_vfx( WM_LULLABY_DEEPSLEEP , SC_DEEP_SLEEP , SI_DEEPSLEEP , SCB_NONE );
set_sc( WM_SIRCLEOFNATURE , SC_SIRCLEOFNATURE , SI_SIRCLEOFNATURE , SCB_NONE );
@@ -754,308 +755,303 @@ void initChangeTables(void) {
set_sc_with_vfx( GN_ILLUSIONDOPING , SC_ILLUSIONDOPING , SI_ILLUSIONDOPING , SCB_HIT );
// Storing the target job rather than simply SC_SOULLINK simplifies code later on.
- status->Skill2SCTable[SL_ALCHEMIST] = (sc_type)MAPID_ALCHEMIST,
- status->Skill2SCTable[SL_MONK] = (sc_type)MAPID_MONK,
- status->Skill2SCTable[SL_STAR] = (sc_type)MAPID_STAR_GLADIATOR,
- status->Skill2SCTable[SL_SAGE] = (sc_type)MAPID_SAGE,
- status->Skill2SCTable[SL_CRUSADER] = (sc_type)MAPID_CRUSADER,
- status->Skill2SCTable[SL_SUPERNOVICE] = (sc_type)MAPID_SUPER_NOVICE,
- status->Skill2SCTable[SL_KNIGHT] = (sc_type)MAPID_KNIGHT,
- status->Skill2SCTable[SL_WIZARD] = (sc_type)MAPID_WIZARD,
- status->Skill2SCTable[SL_PRIEST] = (sc_type)MAPID_PRIEST,
- status->Skill2SCTable[SL_BARDDANCER] = (sc_type)MAPID_BARDDANCER,
- status->Skill2SCTable[SL_ROGUE] = (sc_type)MAPID_ROGUE,
- status->Skill2SCTable[SL_ASSASIN] = (sc_type)MAPID_ASSASSIN,
- status->Skill2SCTable[SL_BLACKSMITH] = (sc_type)MAPID_BLACKSMITH,
- status->Skill2SCTable[SL_HUNTER] = (sc_type)MAPID_HUNTER,
- status->Skill2SCTable[SL_SOULLINKER] = (sc_type)MAPID_SOUL_LINKER,
+ status->dbs->Skill2SCTable[SL_ALCHEMIST] = (sc_type)MAPID_ALCHEMIST,
+ status->dbs->Skill2SCTable[SL_MONK] = (sc_type)MAPID_MONK,
+ status->dbs->Skill2SCTable[SL_STAR] = (sc_type)MAPID_STAR_GLADIATOR,
+ status->dbs->Skill2SCTable[SL_SAGE] = (sc_type)MAPID_SAGE,
+ status->dbs->Skill2SCTable[SL_CRUSADER] = (sc_type)MAPID_CRUSADER,
+ status->dbs->Skill2SCTable[SL_SUPERNOVICE] = (sc_type)MAPID_SUPER_NOVICE,
+ status->dbs->Skill2SCTable[SL_KNIGHT] = (sc_type)MAPID_KNIGHT,
+ status->dbs->Skill2SCTable[SL_WIZARD] = (sc_type)MAPID_WIZARD,
+ status->dbs->Skill2SCTable[SL_PRIEST] = (sc_type)MAPID_PRIEST,
+ status->dbs->Skill2SCTable[SL_BARDDANCER] = (sc_type)MAPID_BARDDANCER,
+ status->dbs->Skill2SCTable[SL_ROGUE] = (sc_type)MAPID_ROGUE,
+ status->dbs->Skill2SCTable[SL_ASSASIN] = (sc_type)MAPID_ASSASSIN,
+ status->dbs->Skill2SCTable[SL_BLACKSMITH] = (sc_type)MAPID_BLACKSMITH,
+ status->dbs->Skill2SCTable[SL_HUNTER] = (sc_type)MAPID_HUNTER,
+ status->dbs->Skill2SCTable[SL_SOULLINKER] = (sc_type)MAPID_SOUL_LINKER,
//Status that don't have a skill associated.
- status->IconChangeTable[SC_WEIGHTOVER50] = SI_WEIGHTOVER50;
- status->IconChangeTable[SC_WEIGHTOVER90] = SI_WEIGHTOVER90;
- status->IconChangeTable[SC_ATTHASTE_POTION1] = SI_ATTHASTE_POTION1;
- status->IconChangeTable[SC_ATTHASTE_POTION2] = SI_ATTHASTE_POTION2;
- status->IconChangeTable[SC_ATTHASTE_POTION3] = SI_ATTHASTE_POTION3;
- status->IconChangeTable[SC_ATTHASTE_INFINITY] = SI_ATTHASTE_INFINITY;
- status->IconChangeTable[SC_MOVHASTE_HORSE] = SI_MOVHASTE_HORSE;
- status->IconChangeTable[SC_MOVHASTE_INFINITY] = SI_MOVHASTE_INFINITY;
- status->IconChangeTable[SC_CHASEWALK2] = SI_INCSTR;
- status->IconChangeTable[SC_MIRACLE] = SI_SOULLINK;
- status->IconChangeTable[SC_CLAIRVOYANCE] = SI_CLAIRVOYANCE;
- status->IconChangeTable[SC_FOOD_STR] = SI_FOOD_STR;
- status->IconChangeTable[SC_FOOD_AGI] = SI_FOOD_AGI;
- status->IconChangeTable[SC_FOOD_VIT] = SI_FOOD_VIT;
- status->IconChangeTable[SC_FOOD_INT] = SI_FOOD_INT;
- status->IconChangeTable[SC_FOOD_DEX] = SI_FOOD_DEX;
- status->IconChangeTable[SC_FOOD_LUK] = SI_FOOD_LUK;
- status->IconChangeTable[SC_FOOD_BASICAVOIDANCE]= SI_FOOD_BASICAVOIDANCE;
- status->IconChangeTable[SC_FOOD_BASICHIT] = SI_FOOD_BASICHIT;
- status->IconChangeTable[SC_MANU_ATK] = SI_MANU_ATK;
- status->IconChangeTable[SC_MANU_DEF] = SI_MANU_DEF;
- status->IconChangeTable[SC_SPL_ATK] = SI_SPL_ATK;
- status->IconChangeTable[SC_SPL_DEF] = SI_SPL_DEF;
- status->IconChangeTable[SC_MANU_MATK] = SI_MANU_MATK;
- status->IconChangeTable[SC_SPL_MATK] = SI_SPL_MATK;
- status->IconChangeTable[SC_PLUSATTACKPOWER] = SI_PLUSATTACKPOWER;
- status->IconChangeTable[SC_PLUSMAGICPOWER] = SI_PLUSMAGICPOWER;
+ status->dbs->IconChangeTable[SC_WEIGHTOVER50] = SI_WEIGHTOVER50;
+ status->dbs->IconChangeTable[SC_WEIGHTOVER90] = SI_WEIGHTOVER90;
+ status->dbs->IconChangeTable[SC_ATTHASTE_POTION1] = SI_ATTHASTE_POTION1;
+ status->dbs->IconChangeTable[SC_ATTHASTE_POTION2] = SI_ATTHASTE_POTION2;
+ status->dbs->IconChangeTable[SC_ATTHASTE_POTION3] = SI_ATTHASTE_POTION3;
+ status->dbs->IconChangeTable[SC_ATTHASTE_INFINITY] = SI_ATTHASTE_INFINITY;
+ status->dbs->IconChangeTable[SC_MOVHASTE_HORSE] = SI_MOVHASTE_HORSE;
+ status->dbs->IconChangeTable[SC_MOVHASTE_INFINITY] = SI_MOVHASTE_INFINITY;
+ status->dbs->IconChangeTable[SC_CHASEWALK2] = SI_INCSTR;
+ status->dbs->IconChangeTable[SC_MIRACLE] = SI_SOULLINK;
+ status->dbs->IconChangeTable[SC_CLAIRVOYANCE] = SI_CLAIRVOYANCE;
+ status->dbs->IconChangeTable[SC_FOOD_STR] = SI_FOOD_STR;
+ status->dbs->IconChangeTable[SC_FOOD_AGI] = SI_FOOD_AGI;
+ status->dbs->IconChangeTable[SC_FOOD_VIT] = SI_FOOD_VIT;
+ status->dbs->IconChangeTable[SC_FOOD_INT] = SI_FOOD_INT;
+ status->dbs->IconChangeTable[SC_FOOD_DEX] = SI_FOOD_DEX;
+ status->dbs->IconChangeTable[SC_FOOD_LUK] = SI_FOOD_LUK;
+ status->dbs->IconChangeTable[SC_FOOD_BASICAVOIDANCE]= SI_FOOD_BASICAVOIDANCE;
+ status->dbs->IconChangeTable[SC_FOOD_BASICHIT] = SI_FOOD_BASICHIT;
+ status->dbs->IconChangeTable[SC_MANU_ATK] = SI_MANU_ATK;
+ status->dbs->IconChangeTable[SC_MANU_DEF] = SI_MANU_DEF;
+ status->dbs->IconChangeTable[SC_SPL_ATK] = SI_SPL_ATK;
+ status->dbs->IconChangeTable[SC_SPL_DEF] = SI_SPL_DEF;
+ status->dbs->IconChangeTable[SC_MANU_MATK] = SI_MANU_MATK;
+ status->dbs->IconChangeTable[SC_SPL_MATK] = SI_SPL_MATK;
+ status->dbs->IconChangeTable[SC_PLUSATTACKPOWER] = SI_PLUSATTACKPOWER;
+ status->dbs->IconChangeTable[SC_PLUSMAGICPOWER] = SI_PLUSMAGICPOWER;
//Cash Items
- status->IconChangeTable[SC_FOOD_STR_CASH] = SI_FOOD_STR_CASH;
- status->IconChangeTable[SC_FOOD_AGI_CASH] = SI_FOOD_AGI_CASH;
- status->IconChangeTable[SC_FOOD_VIT_CASH] = SI_FOOD_VIT_CASH;
- status->IconChangeTable[SC_FOOD_DEX_CASH] = SI_FOOD_DEX_CASH;
- status->IconChangeTable[SC_FOOD_INT_CASH] = SI_FOOD_INT_CASH;
- status->IconChangeTable[SC_FOOD_LUK_CASH] = SI_FOOD_LUK_CASH;
- status->IconChangeTable[SC_CASH_PLUSEXP] = SI_CASH_PLUSEXP;
- status->IconChangeTable[SC_CASH_RECEIVEITEM] = SI_CASH_RECEIVEITEM;
- status->IconChangeTable[SC_CASH_PLUSONLYJOBEXP] = SI_CASH_PLUSONLYJOBEXP;
- status->IconChangeTable[SC_CASH_DEATHPENALTY] = SI_CASH_DEATHPENALTY;
- status->IconChangeTable[SC_CASH_BOSS_ALARM] = SI_CASH_BOSS_ALARM;
- status->IconChangeTable[SC_PROTECT_DEF] = SI_PROTECT_DEF;
- status->IconChangeTable[SC_PROTECT_MDEF] = SI_PROTECT_MDEF;
- status->IconChangeTable[SC_CRITICALPERCENT] = SI_CRITICALPERCENT;
- status->IconChangeTable[SC_PLUSAVOIDVALUE] = SI_PLUSAVOIDVALUE;
- status->IconChangeTable[SC_HEALPLUS] = SI_HEALPLUS;
- status->IconChangeTable[SC_S_LIFEPOTION] = SI_S_LIFEPOTION;
- status->IconChangeTable[SC_L_LIFEPOTION] = SI_L_LIFEPOTION;
- status->IconChangeTable[SC_ATKER_BLOOD] = SI_ATKER_BLOOD;
- status->IconChangeTable[SC_TARGET_BLOOD] = SI_TARGET_BLOOD;
+ status->dbs->IconChangeTable[SC_FOOD_STR_CASH] = SI_FOOD_STR_CASH;
+ status->dbs->IconChangeTable[SC_FOOD_AGI_CASH] = SI_FOOD_AGI_CASH;
+ status->dbs->IconChangeTable[SC_FOOD_VIT_CASH] = SI_FOOD_VIT_CASH;
+ status->dbs->IconChangeTable[SC_FOOD_DEX_CASH] = SI_FOOD_DEX_CASH;
+ status->dbs->IconChangeTable[SC_FOOD_INT_CASH] = SI_FOOD_INT_CASH;
+ status->dbs->IconChangeTable[SC_FOOD_LUK_CASH] = SI_FOOD_LUK_CASH;
+ status->dbs->IconChangeTable[SC_CASH_PLUSEXP] = SI_CASH_PLUSEXP;
+ status->dbs->IconChangeTable[SC_CASH_RECEIVEITEM] = SI_CASH_RECEIVEITEM;
+ status->dbs->IconChangeTable[SC_CASH_PLUSONLYJOBEXP] = SI_CASH_PLUSONLYJOBEXP;
+ status->dbs->IconChangeTable[SC_CASH_DEATHPENALTY] = SI_CASH_DEATHPENALTY;
+ status->dbs->IconChangeTable[SC_CASH_BOSS_ALARM] = SI_CASH_BOSS_ALARM;
+ status->dbs->IconChangeTable[SC_PROTECT_DEF] = SI_PROTECT_DEF;
+ status->dbs->IconChangeTable[SC_PROTECT_MDEF] = SI_PROTECT_MDEF;
+ status->dbs->IconChangeTable[SC_CRITICALPERCENT] = SI_CRITICALPERCENT;
+ status->dbs->IconChangeTable[SC_PLUSAVOIDVALUE] = SI_PLUSAVOIDVALUE;
+ status->dbs->IconChangeTable[SC_HEALPLUS] = SI_HEALPLUS;
+ status->dbs->IconChangeTable[SC_S_LIFEPOTION] = SI_S_LIFEPOTION;
+ status->dbs->IconChangeTable[SC_L_LIFEPOTION] = SI_L_LIFEPOTION;
+ status->dbs->IconChangeTable[SC_ATKER_BLOOD] = SI_ATKER_BLOOD;
+ status->dbs->IconChangeTable[SC_TARGET_BLOOD] = SI_TARGET_BLOOD;
// Mercenary Bonus Effects
- status->IconChangeTable[SC_MER_FLEE] = SI_MER_FLEE;
- status->IconChangeTable[SC_MER_ATK] = SI_MER_ATK;
- status->IconChangeTable[SC_MER_HP] = SI_MER_HP;
- status->IconChangeTable[SC_MER_SP] = SI_MER_SP;
- status->IconChangeTable[SC_MER_HIT] = SI_MER_HIT;
+ status->dbs->IconChangeTable[SC_MER_FLEE] = SI_MER_FLEE;
+ status->dbs->IconChangeTable[SC_MER_ATK] = SI_MER_ATK;
+ status->dbs->IconChangeTable[SC_MER_HP] = SI_MER_HP;
+ status->dbs->IconChangeTable[SC_MER_SP] = SI_MER_SP;
+ status->dbs->IconChangeTable[SC_MER_HIT] = SI_MER_HIT;
// Warlock Spheres
- status->IconChangeTable[SC_SUMMON1] = SI_SPHERE_1;
- status->IconChangeTable[SC_SUMMON2] = SI_SPHERE_2;
- status->IconChangeTable[SC_SUMMON3] = SI_SPHERE_3;
- status->IconChangeTable[SC_SUMMON4] = SI_SPHERE_4;
- status->IconChangeTable[SC_SUMMON5] = SI_SPHERE_5;
+ status->dbs->IconChangeTable[SC_SUMMON1] = SI_SPHERE_1;
+ status->dbs->IconChangeTable[SC_SUMMON2] = SI_SPHERE_2;
+ status->dbs->IconChangeTable[SC_SUMMON3] = SI_SPHERE_3;
+ status->dbs->IconChangeTable[SC_SUMMON4] = SI_SPHERE_4;
+ status->dbs->IconChangeTable[SC_SUMMON5] = SI_SPHERE_5;
// Warlock Preserved spells
- status->IconChangeTable[SC_SPELLBOOK1] = SI_SPELLBOOK1;
- status->IconChangeTable[SC_SPELLBOOK2] = SI_SPELLBOOK2;
- status->IconChangeTable[SC_SPELLBOOK3] = SI_SPELLBOOK3;
- status->IconChangeTable[SC_SPELLBOOK4] = SI_SPELLBOOK4;
- status->IconChangeTable[SC_SPELLBOOK5] = SI_SPELLBOOK5;
- status->IconChangeTable[SC_SPELLBOOK6] = SI_SPELLBOOK6;
- status->IconChangeTable[SC_SPELLBOOK7] = SI_SPELLBOOK7;
-
- status->IconChangeTable[SC_NEUTRALBARRIER_MASTER] = SI_NEUTRALBARRIER_MASTER;
- status->IconChangeTable[SC_STEALTHFIELD_MASTER] = SI_STEALTHFIELD_MASTER;
- status->IconChangeTable[SC_OVERHEAT] = SI_OVERHEAT;
- status->IconChangeTable[SC_OVERHEAT_LIMITPOINT] = SI_OVERHEAT_LIMITPOINT;
-
- status->IconChangeTable[SC_HALLUCINATIONWALK_POSTDELAY] = SI_HALLUCINATIONWALK_POSTDELAY;
- status->IconChangeTable[SC_TOXIN] = SI_TOXIN;
- status->IconChangeTable[SC_PARALYSE] = SI_PARALYSE;
- status->IconChangeTable[SC_VENOMBLEED] = SI_VENOMBLEED;
- status->IconChangeTable[SC_MAGICMUSHROOM] = SI_MAGICMUSHROOM;
- status->IconChangeTable[SC_DEATHHURT] = SI_DEATHHURT;
- status->IconChangeTable[SC_PYREXIA] = SI_PYREXIA;
- status->IconChangeTable[SC_OBLIVIONCURSE] = SI_OBLIVIONCURSE;
- status->IconChangeTable[SC_LEECHESEND] = SI_LEECHESEND;
-
- status->IconChangeTable[SC_SHIELDSPELL_DEF] = SI_SHIELDSPELL_DEF;
- status->IconChangeTable[SC_SHIELDSPELL_MDEF] = SI_SHIELDSPELL_MDEF;
- status->IconChangeTable[SC_SHIELDSPELL_REF] = SI_SHIELDSPELL_REF;
- status->IconChangeTable[SC_BANDING_DEFENCE] = SI_BANDING_DEFENCE;
-
- status->IconChangeTable[SC_CURSEDCIRCLE_ATKER] = SI_CURSEDCIRCLE_ATKER;
-
- status->IconChangeTable[SC_STOMACHACHE] = SI_STOMACHACHE;
- status->IconChangeTable[SC_MYSTERIOUS_POWDER] = SI_MYSTERIOUS_POWDER;
- status->IconChangeTable[SC_MELON_BOMB] = SI_MELON_BOMB;
- status->IconChangeTable[SC_BANANA_BOMB] = SI_BANANA_BOMB;
- status->IconChangeTable[SC_BANANA_BOMB_SITDOWN_POSTDELAY] = SI_BANANA_BOMB_SITDOWN_POSTDELAY;
+ status->dbs->IconChangeTable[SC_SPELLBOOK1] = SI_SPELLBOOK1;
+ status->dbs->IconChangeTable[SC_SPELLBOOK2] = SI_SPELLBOOK2;
+ status->dbs->IconChangeTable[SC_SPELLBOOK3] = SI_SPELLBOOK3;
+ status->dbs->IconChangeTable[SC_SPELLBOOK4] = SI_SPELLBOOK4;
+ status->dbs->IconChangeTable[SC_SPELLBOOK5] = SI_SPELLBOOK5;
+ status->dbs->IconChangeTable[SC_SPELLBOOK6] = SI_SPELLBOOK6;
+ status->dbs->IconChangeTable[SC_SPELLBOOK7] = SI_SPELLBOOK7;
+
+ status->dbs->IconChangeTable[SC_NEUTRALBARRIER_MASTER] = SI_NEUTRALBARRIER_MASTER;
+ status->dbs->IconChangeTable[SC_STEALTHFIELD_MASTER] = SI_STEALTHFIELD_MASTER;
+ status->dbs->IconChangeTable[SC_OVERHEAT] = SI_OVERHEAT;
+ status->dbs->IconChangeTable[SC_OVERHEAT_LIMITPOINT] = SI_OVERHEAT_LIMITPOINT;
+
+ status->dbs->IconChangeTable[SC_HALLUCINATIONWALK_POSTDELAY] = SI_HALLUCINATIONWALK_POSTDELAY;
+ status->dbs->IconChangeTable[SC_TOXIN] = SI_TOXIN;
+ status->dbs->IconChangeTable[SC_PARALYSE] = SI_PARALYSE;
+ status->dbs->IconChangeTable[SC_VENOMBLEED] = SI_VENOMBLEED;
+ status->dbs->IconChangeTable[SC_MAGICMUSHROOM] = SI_MAGICMUSHROOM;
+ status->dbs->IconChangeTable[SC_DEATHHURT] = SI_DEATHHURT;
+ status->dbs->IconChangeTable[SC_PYREXIA] = SI_PYREXIA;
+ status->dbs->IconChangeTable[SC_OBLIVIONCURSE] = SI_OBLIVIONCURSE;
+ status->dbs->IconChangeTable[SC_LEECHESEND] = SI_LEECHESEND;
+
+ status->dbs->IconChangeTable[SC_SHIELDSPELL_DEF] = SI_SHIELDSPELL_DEF;
+ status->dbs->IconChangeTable[SC_SHIELDSPELL_MDEF] = SI_SHIELDSPELL_MDEF;
+ status->dbs->IconChangeTable[SC_SHIELDSPELL_REF] = SI_SHIELDSPELL_REF;
+ status->dbs->IconChangeTable[SC_BANDING_DEFENCE] = SI_BANDING_DEFENCE;
+
+ status->dbs->IconChangeTable[SC_CURSEDCIRCLE_ATKER] = SI_CURSEDCIRCLE_ATKER;
+
+ status->dbs->IconChangeTable[SC_STOMACHACHE] = SI_STOMACHACHE;
+ status->dbs->IconChangeTable[SC_MYSTERIOUS_POWDER] = SI_MYSTERIOUS_POWDER;
+ status->dbs->IconChangeTable[SC_MELON_BOMB] = SI_MELON_BOMB;
+ status->dbs->IconChangeTable[SC_BANANA_BOMB] = SI_BANANA_BOMB;
+ status->dbs->IconChangeTable[SC_BANANA_BOMB_SITDOWN_POSTDELAY] = SI_BANANA_BOMB_SITDOWN_POSTDELAY;
//Genetics New Food Items Status Icons
- status->IconChangeTable[SC_SAVAGE_STEAK] = SI_SAVAGE_STEAK;
- status->IconChangeTable[SC_COCKTAIL_WARG_BLOOD] = SI_COCKTAIL_WARG_BLOOD;
- status->IconChangeTable[SC_MINOR_BBQ] = SI_MINOR_BBQ;
- status->IconChangeTable[SC_SIROMA_ICE_TEA] = SI_SIROMA_ICE_TEA;
- status->IconChangeTable[SC_DROCERA_HERB_STEAMED] = SI_DROCERA_HERB_STEAMED;
- status->IconChangeTable[SC_PUTTI_TAILS_NOODLES] = SI_PUTTI_TAILS_NOODLES;
-
- status->IconChangeTable[SC_BOOST500] |= SI_BOOST500;
- status->IconChangeTable[SC_FULL_SWING_K] |= SI_FULL_SWING_K;
- status->IconChangeTable[SC_MANA_PLUS] |= SI_MANA_PLUS;
- status->IconChangeTable[SC_MUSTLE_M] |= SI_MUSTLE_M;
- status->IconChangeTable[SC_LIFE_FORCE_F] |= SI_LIFE_FORCE_F;
- status->IconChangeTable[SC_EXTRACT_WHITE_POTION_Z] |= SI_EXTRACT_WHITE_POTION_Z;
- status->IconChangeTable[SC_VITATA_500] |= SI_VITATA_500;
- status->IconChangeTable[SC_EXTRACT_SALAMINE_JUICE] |= SI_EXTRACT_SALAMINE_JUICE;
+ status->dbs->IconChangeTable[SC_SAVAGE_STEAK] = SI_SAVAGE_STEAK;
+ status->dbs->IconChangeTable[SC_COCKTAIL_WARG_BLOOD] = SI_COCKTAIL_WARG_BLOOD;
+ status->dbs->IconChangeTable[SC_MINOR_BBQ] = SI_MINOR_BBQ;
+ status->dbs->IconChangeTable[SC_SIROMA_ICE_TEA] = SI_SIROMA_ICE_TEA;
+ status->dbs->IconChangeTable[SC_DROCERA_HERB_STEAMED] = SI_DROCERA_HERB_STEAMED;
+ status->dbs->IconChangeTable[SC_PUTTI_TAILS_NOODLES] = SI_PUTTI_TAILS_NOODLES;
+
+ status->dbs->IconChangeTable[SC_BOOST500] |= SI_BOOST500;
+ status->dbs->IconChangeTable[SC_FULL_SWING_K] |= SI_FULL_SWING_K;
+ status->dbs->IconChangeTable[SC_MANA_PLUS] |= SI_MANA_PLUS;
+ status->dbs->IconChangeTable[SC_MUSTLE_M] |= SI_MUSTLE_M;
+ status->dbs->IconChangeTable[SC_LIFE_FORCE_F] |= SI_LIFE_FORCE_F;
+ status->dbs->IconChangeTable[SC_EXTRACT_WHITE_POTION_Z] |= SI_EXTRACT_WHITE_POTION_Z;
+ status->dbs->IconChangeTable[SC_VITATA_500] |= SI_VITATA_500;
+ status->dbs->IconChangeTable[SC_EXTRACT_SALAMINE_JUICE] |= SI_EXTRACT_SALAMINE_JUICE;
// Elemental Spirit's 'side' status change icons.
- status->IconChangeTable[SC_CIRCLE_OF_FIRE] = SI_CIRCLE_OF_FIRE;
- status->IconChangeTable[SC_FIRE_CLOAK] = SI_FIRE_CLOAK;
- status->IconChangeTable[SC_WATER_SCREEN] = SI_WATER_SCREEN;
- status->IconChangeTable[SC_WATER_DROP] = SI_WATER_DROP;
- status->IconChangeTable[SC_WIND_STEP] = SI_WIND_STEP;
- status->IconChangeTable[SC_WIND_CURTAIN] = SI_WIND_CURTAIN;
- status->IconChangeTable[SC_SOLID_SKIN] = SI_SOLID_SKIN;
- status->IconChangeTable[SC_STONE_SHIELD] = SI_STONE_SHIELD;
- status->IconChangeTable[SC_PYROTECHNIC] = SI_PYROTECHNIC;
- status->IconChangeTable[SC_HEATER] = SI_HEATER;
- status->IconChangeTable[SC_TROPIC] = SI_TROPIC;
- status->IconChangeTable[SC_AQUAPLAY] = SI_AQUAPLAY;
- status->IconChangeTable[SC_COOLER] = SI_COOLER;
- status->IconChangeTable[SC_CHILLY_AIR] = SI_CHILLY_AIR;
- status->IconChangeTable[SC_GUST] = SI_GUST;
- status->IconChangeTable[SC_BLAST] = SI_BLAST;
- status->IconChangeTable[SC_WILD_STORM] = SI_WILD_STORM;
- status->IconChangeTable[SC_PETROLOGY] = SI_PETROLOGY;
- status->IconChangeTable[SC_CURSED_SOIL] = SI_CURSED_SOIL;
- status->IconChangeTable[SC_UPHEAVAL] = SI_UPHEAVAL;
- status->IconChangeTable[SC_PUSH_CART] = SI_ON_PUSH_CART;
- status->IconChangeTable[SC_REBOUND] = SI_REBOUND;
- status->IconChangeTable[SC_ALL_RIDING] = SI_ALL_RIDING;
- status->IconChangeTable[SC_MONSTER_TRANSFORM] = SI_MONSTER_TRANSFORM;
- status->IconChangeTable[SC_MOONSTAR] = SI_MOONSTAR;
- status->IconChangeTable[SC_SUPER_STAR] = SI_SUPER_STAR;
- status->IconChangeTable[SC_STRANGELIGHTS] = SI_STRANGELIGHTS;
- status->IconChangeTable[SC_DECORATION_OF_MUSIC] = SI_DECORATION_OF_MUSIC;
+ status->dbs->IconChangeTable[SC_CIRCLE_OF_FIRE] = SI_CIRCLE_OF_FIRE;
+ status->dbs->IconChangeTable[SC_FIRE_CLOAK] = SI_FIRE_CLOAK;
+ status->dbs->IconChangeTable[SC_WATER_SCREEN] = SI_WATER_SCREEN;
+ status->dbs->IconChangeTable[SC_WATER_DROP] = SI_WATER_DROP;
+ status->dbs->IconChangeTable[SC_WIND_STEP] = SI_WIND_STEP;
+ status->dbs->IconChangeTable[SC_WIND_CURTAIN] = SI_WIND_CURTAIN;
+ status->dbs->IconChangeTable[SC_SOLID_SKIN] = SI_SOLID_SKIN;
+ status->dbs->IconChangeTable[SC_STONE_SHIELD] = SI_STONE_SHIELD;
+ status->dbs->IconChangeTable[SC_PYROTECHNIC] = SI_PYROTECHNIC;
+ status->dbs->IconChangeTable[SC_HEATER] = SI_HEATER;
+ status->dbs->IconChangeTable[SC_TROPIC] = SI_TROPIC;
+ status->dbs->IconChangeTable[SC_AQUAPLAY] = SI_AQUAPLAY;
+ status->dbs->IconChangeTable[SC_COOLER] = SI_COOLER;
+ status->dbs->IconChangeTable[SC_CHILLY_AIR] = SI_CHILLY_AIR;
+ status->dbs->IconChangeTable[SC_GUST] = SI_GUST;
+ status->dbs->IconChangeTable[SC_BLAST] = SI_BLAST;
+ status->dbs->IconChangeTable[SC_WILD_STORM] = SI_WILD_STORM;
+ status->dbs->IconChangeTable[SC_PETROLOGY] = SI_PETROLOGY;
+ status->dbs->IconChangeTable[SC_CURSED_SOIL] = SI_CURSED_SOIL;
+ status->dbs->IconChangeTable[SC_UPHEAVAL] = SI_UPHEAVAL;
+ status->dbs->IconChangeTable[SC_PUSH_CART] = SI_ON_PUSH_CART;
+ status->dbs->IconChangeTable[SC_REBOUND] = SI_REBOUND;
+ status->dbs->IconChangeTable[SC_ALL_RIDING] = SI_ALL_RIDING;
+ status->dbs->IconChangeTable[SC_MONSTER_TRANSFORM] = SI_MONSTER_TRANSFORM;
+ status->dbs->IconChangeTable[SC_MOONSTAR] = SI_MOONSTAR;
+ status->dbs->IconChangeTable[SC_SUPER_STAR] = SI_SUPER_STAR;
+ status->dbs->IconChangeTable[SC_STRANGELIGHTS] = SI_STRANGELIGHTS;
+ status->dbs->IconChangeTable[SC_DECORATION_OF_MUSIC] = SI_DECORATION_OF_MUSIC;
//Other SC which are not necessarily associated to skills.
- status->ChangeFlagTable[SC_ATTHASTE_POTION1] = SCB_ASPD;
- status->ChangeFlagTable[SC_ATTHASTE_POTION2] = SCB_ASPD;
- status->ChangeFlagTable[SC_ATTHASTE_POTION3] = SCB_ASPD;
- status->ChangeFlagTable[SC_ATTHASTE_INFINITY] = SCB_ASPD;
- status->ChangeFlagTable[SC_MOVHASTE_HORSE] = SCB_SPEED;
- status->ChangeFlagTable[SC_MOVHASTE_INFINITY] = SCB_SPEED;
- status->ChangeFlagTable[SC_PLUSATTACKPOWER] = SCB_BATK;
- status->ChangeFlagTable[SC_PLUSMAGICPOWER] = SCB_MATK;
- status->ChangeFlagTable[SC_INCALLSTATUS] |= SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK;
- status->ChangeFlagTable[SC_CHASEWALK2] |= SCB_STR;
- status->ChangeFlagTable[SC_INCAGI] |= SCB_AGI;
- status->ChangeFlagTable[SC_INCVIT] |= SCB_VIT;
- status->ChangeFlagTable[SC_INCINT] |= SCB_INT;
- status->ChangeFlagTable[SC_INCDEX] |= SCB_DEX;
- status->ChangeFlagTable[SC_INCLUK] |= SCB_LUK;
- status->ChangeFlagTable[SC_INCHIT] |= SCB_HIT;
- status->ChangeFlagTable[SC_INCHITRATE] |= SCB_HIT;
- status->ChangeFlagTable[SC_INCFLEE] |= SCB_FLEE;
- status->ChangeFlagTable[SC_INCFLEERATE] |= SCB_FLEE;
- status->ChangeFlagTable[SC_MTF_HITFLEE] |= SCB_HIT|SCB_FLEE;
- status->ChangeFlagTable[SC_CRITICALPERCENT] |= SCB_CRI;
- status->ChangeFlagTable[SC_INCASPDRATE] |= SCB_ASPD;
- status->ChangeFlagTable[SC_PLUSAVOIDVALUE] |= SCB_FLEE2;
- status->ChangeFlagTable[SC_INCMHPRATE] |= SCB_MAXHP;
- status->ChangeFlagTable[SC_INCMSPRATE] |= SCB_MAXSP;
- status->ChangeFlagTable[SC_INCMHP] |= SCB_MAXHP;
- status->ChangeFlagTable[SC_MTF_MHP] |= SCB_MAXHP;
- status->ChangeFlagTable[SC_INCMSP] |= SCB_MAXSP;
- status->ChangeFlagTable[SC_MTF_MSP] |= SCB_MAXSP;
- status->ChangeFlagTable[SC_INCATKRATE] |= SCB_BATK|SCB_WATK;
- status->ChangeFlagTable[SC_INCMATKRATE] |= SCB_MATK;
- status->ChangeFlagTable[SC_INCDEFRATE] |= SCB_DEF;
- status->ChangeFlagTable[SC_FOOD_STR] |= SCB_STR;
- status->ChangeFlagTable[SC_FOOD_AGI] |= SCB_AGI;
- status->ChangeFlagTable[SC_FOOD_VIT] |= SCB_VIT;
- status->ChangeFlagTable[SC_FOOD_INT] |= SCB_INT;
- status->ChangeFlagTable[SC_FOOD_DEX] |= SCB_DEX;
- status->ChangeFlagTable[SC_FOOD_LUK] |= SCB_LUK;
- status->ChangeFlagTable[SC_FOOD_BASICHIT] |= SCB_HIT;
- status->ChangeFlagTable[SC_FOOD_BASICAVOIDANCE] |= SCB_FLEE;
- status->ChangeFlagTable[SC_BATKFOOD] |= SCB_BATK;
- status->ChangeFlagTable[SC_WATKFOOD] |= SCB_WATK;
- status->ChangeFlagTable[SC_MATKFOOD] |= SCB_MATK;
- status->ChangeFlagTable[SC_ARMORPROPERTY] |= SCB_ALL;
- status->ChangeFlagTable[SC_ARMOR_RESIST] |= SCB_ALL;
- status->ChangeFlagTable[SC_ATKER_BLOOD] |= SCB_ALL;
- status->ChangeFlagTable[SC_WALKSPEED] |= SCB_SPEED;
- status->ChangeFlagTable[SC_ITEMSCRIPT] |= SCB_ALL;
+ status->dbs->ChangeFlagTable[SC_ATTHASTE_POTION1] = SCB_ASPD;
+ status->dbs->ChangeFlagTable[SC_ATTHASTE_POTION2] = SCB_ASPD;
+ status->dbs->ChangeFlagTable[SC_ATTHASTE_POTION3] = SCB_ASPD;
+ status->dbs->ChangeFlagTable[SC_ATTHASTE_INFINITY] = SCB_ASPD;
+ status->dbs->ChangeFlagTable[SC_MOVHASTE_HORSE] = SCB_SPEED;
+ status->dbs->ChangeFlagTable[SC_MOVHASTE_INFINITY] = SCB_SPEED;
+ status->dbs->ChangeFlagTable[SC_PLUSATTACKPOWER] = SCB_BATK;
+ status->dbs->ChangeFlagTable[SC_PLUSMAGICPOWER] = SCB_MATK;
+ status->dbs->ChangeFlagTable[SC_INCALLSTATUS] |= SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK;
+ status->dbs->ChangeFlagTable[SC_CHASEWALK2] |= SCB_STR;
+ status->dbs->ChangeFlagTable[SC_INCAGI] |= SCB_AGI;
+ status->dbs->ChangeFlagTable[SC_INCVIT] |= SCB_VIT;
+ status->dbs->ChangeFlagTable[SC_INCINT] |= SCB_INT;
+ status->dbs->ChangeFlagTable[SC_INCDEX] |= SCB_DEX;
+ status->dbs->ChangeFlagTable[SC_INCLUK] |= SCB_LUK;
+ status->dbs->ChangeFlagTable[SC_INCHIT] |= SCB_HIT;
+ status->dbs->ChangeFlagTable[SC_INCHITRATE] |= SCB_HIT;
+ status->dbs->ChangeFlagTable[SC_INCFLEE] |= SCB_FLEE;
+ status->dbs->ChangeFlagTable[SC_INCFLEERATE] |= SCB_FLEE;
+ status->dbs->ChangeFlagTable[SC_MTF_HITFLEE] |= SCB_HIT|SCB_FLEE;
+ status->dbs->ChangeFlagTable[SC_CRITICALPERCENT] |= SCB_CRI;
+ status->dbs->ChangeFlagTable[SC_INCASPDRATE] |= SCB_ASPD;
+ status->dbs->ChangeFlagTable[SC_PLUSAVOIDVALUE] |= SCB_FLEE2;
+ status->dbs->ChangeFlagTable[SC_INCMHPRATE] |= SCB_MAXHP;
+ status->dbs->ChangeFlagTable[SC_INCMSPRATE] |= SCB_MAXSP;
+ status->dbs->ChangeFlagTable[SC_INCMHP] |= SCB_MAXHP;
+ status->dbs->ChangeFlagTable[SC_MTF_MHP] |= SCB_MAXHP;
+ status->dbs->ChangeFlagTable[SC_INCMSP] |= SCB_MAXSP;
+ status->dbs->ChangeFlagTable[SC_MTF_MSP] |= SCB_MAXSP;
+ status->dbs->ChangeFlagTable[SC_INCATKRATE] |= SCB_BATK|SCB_WATK;
+ status->dbs->ChangeFlagTable[SC_INCMATKRATE] |= SCB_MATK;
+ status->dbs->ChangeFlagTable[SC_INCDEFRATE] |= SCB_DEF;
+ status->dbs->ChangeFlagTable[SC_FOOD_STR] |= SCB_STR;
+ status->dbs->ChangeFlagTable[SC_FOOD_AGI] |= SCB_AGI;
+ status->dbs->ChangeFlagTable[SC_FOOD_VIT] |= SCB_VIT;
+ status->dbs->ChangeFlagTable[SC_FOOD_INT] |= SCB_INT;
+ status->dbs->ChangeFlagTable[SC_FOOD_DEX] |= SCB_DEX;
+ status->dbs->ChangeFlagTable[SC_FOOD_LUK] |= SCB_LUK;
+ status->dbs->ChangeFlagTable[SC_FOOD_BASICHIT] |= SCB_HIT;
+ status->dbs->ChangeFlagTable[SC_FOOD_BASICAVOIDANCE] |= SCB_FLEE;
+ status->dbs->ChangeFlagTable[SC_BATKFOOD] |= SCB_BATK;
+ status->dbs->ChangeFlagTable[SC_WATKFOOD] |= SCB_WATK;
+ status->dbs->ChangeFlagTable[SC_MATKFOOD] |= SCB_MATK;
+ status->dbs->ChangeFlagTable[SC_ARMORPROPERTY] |= SCB_ALL;
+ status->dbs->ChangeFlagTable[SC_ARMOR_RESIST] |= SCB_ALL;
+ status->dbs->ChangeFlagTable[SC_ATKER_BLOOD] |= SCB_ALL;
+ status->dbs->ChangeFlagTable[SC_WALKSPEED] |= SCB_SPEED;
+ status->dbs->ChangeFlagTable[SC_ITEMSCRIPT] |= SCB_ALL;
// Cash Items
- status->ChangeFlagTable[SC_FOOD_STR_CASH] = SCB_STR;
- status->ChangeFlagTable[SC_FOOD_AGI_CASH] = SCB_AGI;
- status->ChangeFlagTable[SC_FOOD_VIT_CASH] = SCB_VIT;
- status->ChangeFlagTable[SC_FOOD_DEX_CASH] = SCB_DEX;
- status->ChangeFlagTable[SC_FOOD_INT_CASH] = SCB_INT;
- status->ChangeFlagTable[SC_FOOD_LUK_CASH] = SCB_LUK;
+ status->dbs->ChangeFlagTable[SC_FOOD_STR_CASH] = SCB_STR;
+ status->dbs->ChangeFlagTable[SC_FOOD_AGI_CASH] = SCB_AGI;
+ status->dbs->ChangeFlagTable[SC_FOOD_VIT_CASH] = SCB_VIT;
+ status->dbs->ChangeFlagTable[SC_FOOD_DEX_CASH] = SCB_DEX;
+ status->dbs->ChangeFlagTable[SC_FOOD_INT_CASH] = SCB_INT;
+ status->dbs->ChangeFlagTable[SC_FOOD_LUK_CASH] = SCB_LUK;
// Mercenary Bonus Effects
- status->ChangeFlagTable[SC_MER_FLEE] |= SCB_FLEE;
- status->ChangeFlagTable[SC_MER_ATK] |= SCB_WATK;
- status->ChangeFlagTable[SC_MER_HP] |= SCB_MAXHP;
- status->ChangeFlagTable[SC_MER_SP] |= SCB_MAXSP;
- status->ChangeFlagTable[SC_MER_HIT] |= SCB_HIT;
+ status->dbs->ChangeFlagTable[SC_MER_FLEE] |= SCB_FLEE;
+ status->dbs->ChangeFlagTable[SC_MER_ATK] |= SCB_WATK;
+ status->dbs->ChangeFlagTable[SC_MER_HP] |= SCB_MAXHP;
+ status->dbs->ChangeFlagTable[SC_MER_SP] |= SCB_MAXSP;
+ status->dbs->ChangeFlagTable[SC_MER_HIT] |= SCB_HIT;
// Guillotine Cross Poison Effects
- status->ChangeFlagTable[SC_PARALYSE] |= SCB_FLEE|SCB_SPEED|SCB_ASPD;
- status->ChangeFlagTable[SC_VENOMBLEED] |= SCB_MAXHP;
- status->ChangeFlagTable[SC_MAGICMUSHROOM] |= SCB_REGEN;
- status->ChangeFlagTable[SC_DEATHHURT] |= SCB_REGEN;
- status->ChangeFlagTable[SC_PYREXIA] |= SCB_HIT|SCB_FLEE;
- status->ChangeFlagTable[SC_OBLIVIONCURSE] |= SCB_REGEN;
+ status->dbs->ChangeFlagTable[SC_PARALYSE] |= SCB_FLEE|SCB_SPEED|SCB_ASPD;
+ status->dbs->ChangeFlagTable[SC_VENOMBLEED] |= SCB_MAXHP;
+ status->dbs->ChangeFlagTable[SC_MAGICMUSHROOM] |= SCB_REGEN;
+ status->dbs->ChangeFlagTable[SC_DEATHHURT] |= SCB_REGEN;
+ status->dbs->ChangeFlagTable[SC_PYREXIA] |= SCB_HIT|SCB_FLEE;
+ status->dbs->ChangeFlagTable[SC_OBLIVIONCURSE] |= SCB_REGEN;
// RG status
- status->ChangeFlagTable[SC_SHIELDSPELL_DEF] |= SCB_WATK;
- status->ChangeFlagTable[SC_SHIELDSPELL_REF] |= SCB_DEF;
+ status->dbs->ChangeFlagTable[SC_SHIELDSPELL_DEF] |= SCB_WATK;
+ status->dbs->ChangeFlagTable[SC_SHIELDSPELL_REF] |= SCB_DEF;
// Meca status
- status->ChangeFlagTable[SC_STEALTHFIELD_MASTER] |= SCB_SPEED;
-
- status->ChangeFlagTable[SC_SAVAGE_STEAK] |= SCB_STR;
- status->ChangeFlagTable[SC_COCKTAIL_WARG_BLOOD] |= SCB_INT;
- status->ChangeFlagTable[SC_MINOR_BBQ] |= SCB_VIT;
- status->ChangeFlagTable[SC_SIROMA_ICE_TEA] |= SCB_DEX;
- status->ChangeFlagTable[SC_DROCERA_HERB_STEAMED] |= SCB_AGI;
- status->ChangeFlagTable[SC_PUTTI_TAILS_NOODLES] |= SCB_LUK;
- status->ChangeFlagTable[SC_BOOST500] |= SCB_ASPD;
- status->ChangeFlagTable[SC_FULL_SWING_K] |= SCB_BATK;
- status->ChangeFlagTable[SC_MANA_PLUS] |= SCB_MATK;
- status->ChangeFlagTable[SC_MUSTLE_M] |= SCB_MAXHP;
- status->ChangeFlagTable[SC_LIFE_FORCE_F] |= SCB_MAXSP;
- status->ChangeFlagTable[SC_EXTRACT_WHITE_POTION_Z] |= SCB_REGEN;
- status->ChangeFlagTable[SC_VITATA_500] |= SCB_REGEN;
- status->ChangeFlagTable[SC_EXTRACT_SALAMINE_JUICE] |= SCB_ASPD;
- status->ChangeFlagTable[SC_REBOUND] |= SCB_SPEED|SCB_REGEN;
- status->ChangeFlagTable[SC_DEFSET] |= SCB_DEF|SCB_DEF2;
- status->ChangeFlagTable[SC_MDEFSET] |= SCB_MDEF|SCB_MDEF2;
- status->ChangeFlagTable[SC_MYSTERIOUS_POWDER] |= SCB_MAXHP;
-
- status->ChangeFlagTable[SC_ALL_RIDING] = SCB_SPEED;
- status->ChangeFlagTable[SC_WEDDING] = SCB_SPEED;
-
- status->ChangeFlagTable[SC_MTF_ASPD] = SCB_ASPD|SCB_HIT;
- status->ChangeFlagTable[SC_MTF_MATK] = SCB_MATK;
- status->ChangeFlagTable[SC_MTF_MLEATKED] |= SCB_ALL;
-
- status->ChangeFlagTable[SC_MOONSTAR] |= SCB_NONE;
- status->ChangeFlagTable[SC_SUPER_STAR] |= SCB_NONE;
- status->ChangeFlagTable[SC_STRANGELIGHTS] |= SCB_NONE;
- status->ChangeFlagTable[SC_DECORATION_OF_MUSIC] |= SCB_NONE;
-
- /* status->DisplayType Table [Ind/Hercules] */
- status->DisplayType[SC_ALL_RIDING] = true;
- status->DisplayType[SC_PUSH_CART] = true;
- status->DisplayType[SC_SUMMON1] = true;
- status->DisplayType[SC_SUMMON2] = true;
- status->DisplayType[SC_SUMMON3] = true;
- status->DisplayType[SC_SUMMON4] = true;
- status->DisplayType[SC_SUMMON5] = true;
- status->DisplayType[SC_CAMOUFLAGE] = true;
- status->DisplayType[SC_DUPLELIGHT] = true;
- status->DisplayType[SC_ORATIO] = true;
- status->DisplayType[SC_FROSTMISTY] = true;
- status->DisplayType[SC_VENOMIMPRESS] = true;
- status->DisplayType[SC_HALLUCINATIONWALK] = true;
- status->DisplayType[SC_ROLLINGCUTTER] = true;
- status->DisplayType[SC_BANDING] = true;
- status->DisplayType[SC_COLD] = true;
- status->DisplayType[SC_DEEP_SLEEP] = true;
- status->DisplayType[SC_CURSEDCIRCLE_ATKER] = true;
- status->DisplayType[SC_CURSEDCIRCLE_TARGET] = true;
- status->DisplayType[SC_BLOOD_SUCKER] = true;
- status->DisplayType[SC__SHADOWFORM] = true;
- status->DisplayType[SC_MONSTER_TRANSFORM] = true;
- status->DisplayType[SC_MOONSTAR] = true;
- status->DisplayType[SC_SUPER_STAR] = true;
- status->DisplayType[SC_STRANGELIGHTS] = true;
- status->DisplayType[SC_DECORATION_OF_MUSIC] = true;
-
-#ifdef RENEWAL_EDP
- // renewal EDP increases your weapon atk
- status->ChangeFlagTable[SC_EDP] |= SCB_WATK;
-#endif
+ status->dbs->ChangeFlagTable[SC_STEALTHFIELD_MASTER] |= SCB_SPEED;
+
+ status->dbs->ChangeFlagTable[SC_SAVAGE_STEAK] |= SCB_STR;
+ status->dbs->ChangeFlagTable[SC_COCKTAIL_WARG_BLOOD] |= SCB_INT;
+ status->dbs->ChangeFlagTable[SC_MINOR_BBQ] |= SCB_VIT;
+ status->dbs->ChangeFlagTable[SC_SIROMA_ICE_TEA] |= SCB_DEX;
+ status->dbs->ChangeFlagTable[SC_DROCERA_HERB_STEAMED] |= SCB_AGI;
+ status->dbs->ChangeFlagTable[SC_PUTTI_TAILS_NOODLES] |= SCB_LUK;
+ status->dbs->ChangeFlagTable[SC_BOOST500] |= SCB_ASPD;
+ status->dbs->ChangeFlagTable[SC_FULL_SWING_K] |= SCB_BATK;
+ status->dbs->ChangeFlagTable[SC_MANA_PLUS] |= SCB_MATK;
+ status->dbs->ChangeFlagTable[SC_MUSTLE_M] |= SCB_MAXHP;
+ status->dbs->ChangeFlagTable[SC_LIFE_FORCE_F] |= SCB_MAXSP;
+ status->dbs->ChangeFlagTable[SC_EXTRACT_WHITE_POTION_Z] |= SCB_REGEN;
+ status->dbs->ChangeFlagTable[SC_VITATA_500] |= SCB_REGEN;
+ status->dbs->ChangeFlagTable[SC_EXTRACT_SALAMINE_JUICE] |= SCB_ASPD;
+ status->dbs->ChangeFlagTable[SC_REBOUND] |= SCB_SPEED|SCB_REGEN;
+ status->dbs->ChangeFlagTable[SC_DEFSET] |= SCB_DEF|SCB_DEF2;
+ status->dbs->ChangeFlagTable[SC_MDEFSET] |= SCB_MDEF|SCB_MDEF2;
+ status->dbs->ChangeFlagTable[SC_MYSTERIOUS_POWDER] |= SCB_MAXHP;
+
+ status->dbs->ChangeFlagTable[SC_ALL_RIDING] = SCB_SPEED;
+ status->dbs->ChangeFlagTable[SC_WEDDING] = SCB_SPEED;
+
+ status->dbs->ChangeFlagTable[SC_MTF_ASPD] = SCB_ASPD|SCB_HIT;
+ status->dbs->ChangeFlagTable[SC_MTF_MATK] = SCB_MATK;
+ status->dbs->ChangeFlagTable[SC_MTF_MLEATKED] |= SCB_ALL;
+
+ status->dbs->ChangeFlagTable[SC_MOONSTAR] |= SCB_NONE;
+ status->dbs->ChangeFlagTable[SC_SUPER_STAR] |= SCB_NONE;
+ status->dbs->ChangeFlagTable[SC_STRANGELIGHTS] |= SCB_NONE;
+ status->dbs->ChangeFlagTable[SC_DECORATION_OF_MUSIC] |= SCB_NONE;
+
+ /* status->dbs->DisplayType Table [Ind/Hercules] */
+ status->dbs->DisplayType[SC_ALL_RIDING] = true;
+ status->dbs->DisplayType[SC_PUSH_CART] = true;
+ status->dbs->DisplayType[SC_SUMMON1] = true;
+ status->dbs->DisplayType[SC_SUMMON2] = true;
+ status->dbs->DisplayType[SC_SUMMON3] = true;
+ status->dbs->DisplayType[SC_SUMMON4] = true;
+ status->dbs->DisplayType[SC_SUMMON5] = true;
+ status->dbs->DisplayType[SC_CAMOUFLAGE] = true;
+ status->dbs->DisplayType[SC_DUPLELIGHT] = true;
+ status->dbs->DisplayType[SC_ORATIO] = true;
+ status->dbs->DisplayType[SC_FROSTMISTY] = true;
+ status->dbs->DisplayType[SC_VENOMIMPRESS] = true;
+ status->dbs->DisplayType[SC_HALLUCINATIONWALK] = true;
+ status->dbs->DisplayType[SC_ROLLINGCUTTER] = true;
+ status->dbs->DisplayType[SC_BANDING] = true;
+ status->dbs->DisplayType[SC_COLD] = true;
+ status->dbs->DisplayType[SC_DEEP_SLEEP] = true;
+ status->dbs->DisplayType[SC_CURSEDCIRCLE_ATKER] = true;
+ status->dbs->DisplayType[SC_CURSEDCIRCLE_TARGET] = true;
+ status->dbs->DisplayType[SC_BLOOD_SUCKER] = true;
+ status->dbs->DisplayType[SC__SHADOWFORM] = true;
+ status->dbs->DisplayType[SC_MONSTER_TRANSFORM] = true;
+ status->dbs->DisplayType[SC_MOONSTAR] = true;
+ status->dbs->DisplayType[SC_SUPER_STAR] = true;
+ status->dbs->DisplayType[SC_STRANGELIGHTS] = true;
+ status->dbs->DisplayType[SC_DECORATION_OF_MUSIC] = true;
if( !battle_config.display_hallucination ) //Disable Hallucination.
- status->IconChangeTable[SC_ILLUSION] = SI_BLANK;
+ status->dbs->IconChangeTable[SC_ILLUSION] = SI_BLANK;
#undef add_sc
#undef set_sc_with_vfx
}
@@ -1199,7 +1195,7 @@ int status_damage(struct block_list *src,struct block_list *target,int64 in_hp,
if(d_bl &&((d_bl->type == BL_MER && ((TBL_MER *)d_bl)->master && ((TBL_MER *)d_bl)->master->bl.id == target->id)
|| (d_bl->type == BL_PC && ((TBL_PC *)d_bl)->devotion[sce->val2] == target->id)) && check_distance_bl(target, d_bl, sce->val3)) {
- clif->damage(d_bl, d_bl, 0, 0, hp, 0, 0, 0);
+ clif->damage(d_bl, d_bl, 0, 0, hp, 0, BDT_NORMAL, 0);
status_fix_damage(NULL, d_bl, hp, 0);
return 0;
}
@@ -1266,7 +1262,7 @@ int status_damage(struct block_list *src,struct block_list *target,int64 in_hp,
}
if( src && target->type == BL_PC && (((TBL_PC*)target)->disguise) > 0 ) {// stop walking when attacked in disguise to prevent walk-delay bug
- unit->stop_walking( target, 1 );
+ unit->stop_walking(target, STOPWALKING_FLAG_FIXPOS);
}
if (st->hp || (flag&8)) {
@@ -1349,7 +1345,7 @@ int status_damage(struct block_list *src,struct block_list *target,int64 in_hp,
unit->remove_map(target,CLR_DEAD,ALC_MARK);
else { //Some death states that would normally be handled by unit_remove_map
unit->stop_attack(target);
- unit->stop_walking(target,1);
+ unit->stop_walking(target, STOPWALKING_FLAG_FIXPOS);
unit->skillcastcancel(target,0);
clif->clearunit_area(target,CLR_DEAD);
skill->unit_move(target,timer->gettick(),4);
@@ -1601,13 +1597,13 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin
for(i = 0; i < map->list[src->m].zone->disabled_skills_count; i++) {
if( skill_id == map->list[src->m].zone->disabled_skills[i]->nameid && (map->list[src->m].zone->disabled_skills[i]->type&src->type) ) {
- if( src->type == BL_PC )
- clif->msg((TBL_PC*)src, SKILL_CANT_USE_AREA); // This skill cannot be used within this area
- else if( src->type == BL_MOB && map->list[src->m].zone->disabled_skills[i]->subtype != MZS_NONE ) {
- if( st->mode&MD_BOSS ) { /** is boss **/
+ if (src->type == BL_PC) {
+ clif->msgtable((TBL_PC*)src, MSG_SKILL_CANT_USE_AREA); // This skill cannot be used within this area
+ } else if (src->type == BL_MOB && map->list[src->m].zone->disabled_skills[i]->subtype != MZS_NONE) {
+ if( st->mode&MD_BOSS ) { /* is boss */
if( !( map->list[src->m].zone->disabled_skills[i]->subtype&MZS_BOSS ) )
break;
- } else { /** is not boss **/
+ } else { /* is not boss */
if( map->list[src->m].zone->disabled_skills[i]->subtype&MZS_BOSS )
break;
}
@@ -1657,15 +1653,19 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin
(sc->data[SC_TRICKDEAD] && skill_id != NV_TRICKDEAD)
|| (sc->data[SC_AUTOCOUNTER] && !flag && skill_id)
|| (sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_SELF && skill_id != PA_GOSPEL)
- || (sc->data[SC_GRAVITATION] && sc->data[SC_GRAVITATION]->val3 == BCT_SELF && flag != 2)
)
return 0;
if (sc->data[SC_DC_WINKCHARM] && target && !flag) { //Prevents skill usage
- if( unit->bl2ud(src) && (unit->bl2ud(src))->walktimer == INVALID_TIMER )
- unit->walktobl(src, map->id2bl(sc->data[SC_DC_WINKCHARM]->val2), 3, 1);
- clif->emotion(src, E_LV);
- return 0;
+ struct block_list *winkcharm_target = map->id2bl(sc->data[SC_DC_WINKCHARM]->val2);
+ if (winkcharm_target != NULL) {
+ if (unit->bl2ud(src) && (unit->bl2ud(src))->walktimer == INVALID_TIMER)
+ unit->walktobl(src, map->id2bl(sc->data[SC_DC_WINKCHARM]->val2), 3, 1);
+ clif->emotion(src, E_LV);
+ return 0;
+ } else {
+ status_change_end(src, SC_DC_WINKCHARM, INVALID_TIMER);
+ }
}
if (sc->data[SC_BLADESTOP]) {
@@ -1880,7 +1880,7 @@ int status_calc_mob_(struct mob_data* md, enum e_status_calc_opt opt) {
if (battle_config.slaves_inherit_speed && md->master_id)
flag|=8;
- if (md->master_id && md->special_state.ai>1)
+ if (md->master_id && md->special_state.ai > AI_ATTACK)
flag|=16;
if (!flag)
@@ -1916,8 +1916,8 @@ int status_calc_mob_(struct mob_data* md, enum e_status_calc_opt opt) {
//Max HP setting from Summon Flora/marine Sphere
struct unit_data *ud = unit->bl2ud(mbl);
//Remove special AI when this is used by regular mobs.
- if (mbl->type == BL_MOB && !((TBL_MOB*)mbl)->special_state.ai)
- md->special_state.ai = 0;
+ if (mbl->type == BL_MOB && ((TBL_MOB*)mbl)->special_state.ai == AI_NONE)
+ md->special_state.ai = AI_NONE;
if (ud) {
// different levels of HP according to skill level
if (ud->skill_id == AM_SPHEREMINE) {
@@ -2087,64 +2087,42 @@ int status_calc_pet_(struct pet_data *pd, enum e_status_calc_opt opt)
return 1;
}
-/// Helper function for status_base_pc_maxhp(), used to pre-calculate the hp_sigma_val[] array
-void status_calc_sigma(void)
-{
- int i,j;
+unsigned int status_get_base_maxsp(struct map_session_data* sd, struct status_data *st) {
+ uint64 val = pc->class2idx(sd->status.class_);
- for(i = 0; i < CLASS_COUNT; i++)
- {
- unsigned int k = 0;
- status->hp_sigma_val[i][0] = status->hp_sigma_val[i][1] = 0;
- for(j = 2; j <= MAX_LEVEL; j++)
- {
- k += (status->hp_coefficient[i]*j + 50) / 100;
- status->hp_sigma_val[i][j] = k;
- if (k >= INT_MAX)
- break; //Overflow protection. [Skotlex]
- }
- for(; j <= MAX_LEVEL; j++)
- status->hp_sigma_val[i][j] = INT_MAX;
- }
+ val = status->dbs->SP_table[val][sd->status.base_level];
+
+ if ( sd->class_&JOBL_UPPER )
+ val += val * 25 / 100;
+ else if ( sd->class_&JOBL_BABY )
+ val = val * 70 / 100;
+ if ( (sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= 90 && pc->famerank(sd->status.char_id, MAPID_TAEKWON) )
+ val *= 3; //Triple max SP for top ranking Taekwons over level 90.
+
+ val += val * st->int_ / 100;
+
+ return (unsigned int)cap_value(val, 0, UINT_MAX);
}
-/// Calculates base MaxHP value according to class and base level
-/// The recursive equation used to calculate level bonus is (using integer operations)
-/// f(0) = 35 | f(x+1) = f(x) + A + (x + B)*C/D
-/// which reduces to something close to
-/// f(x) = 35 + x*(A + B*C/D) + sum(i=2..x){ i*C/D }
-unsigned int status_base_pc_maxhp(struct map_session_data *sd, struct status_data *st) {
+unsigned int status_get_base_maxhp(struct map_session_data *sd, struct status_data *st) {
uint64 val = pc->class2idx(sd->status.class_);
- val = 35 + sd->status.base_level*(int64)status->hp_coefficient2[val]/100 + status->hp_sigma_val[val][sd->status.base_level];
- if((sd->class_&MAPID_UPPERMASK) == MAPID_NINJA || (sd->class_&MAPID_UPPERMASK) == MAPID_GUNSLINGER || (sd->class_&MAPID_UPPERMASK) == MAPID_REBELLION)
- val += 100; //Since their HP can't be approximated well enough without this.
- if((sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= 90 && pc->famerank(sd->status.char_id, MAPID_TAEKWON))
- val *= 3; //Triple max HP for top ranking Taekwons over level 90.
- if((sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE && sd->status.base_level >= 99)
- val += 2000; //Supernovice lvl99 hp bonus.
-
- val += val * st->vit/100; // +1% per each point of VIT
+ val = status->dbs->HP_table[val][sd->status.base_level];
- if (sd->class_&JOBL_UPPER)
- val += val * 25/100; //Trans classes get a 25% hp bonus
- else if (sd->class_&JOBL_BABY)
- val -= val * 30/100; //Baby classes get a 30% hp penalty
- return (unsigned int)cap_value(val,0,UINT_MAX);
-}
+ if ( (sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE && sd->status.base_level >= 99 )
+ val += 2000; //Supernovice lvl99 hp bonus.
+ if ( (sd->class_&MAPID_THIRDMASK) == MAPID_SUPER_NOVICE_E && sd->status.base_level >= 150 )
+ val += 2000; //Extented Supernovice lvl150 hp bonus.
-unsigned int status_base_pc_maxsp(struct map_session_data* sd, struct status_data *st) {
- uint64 val;
+ if ( sd->class_&JOBL_UPPER )
+ val += val * 25 / 100; //Trans classes get a 25% hp bonus
+ else if ( sd->class_&JOBL_BABY )
+ val = val * 70 / 100; //Baby classes get a 30% hp penalty
- val = 10 + sd->status.base_level*(int64)status->sp_coefficient[pc->class2idx(sd->status.class_)]/100;
- val += val * st->int_/100;
+ if ( (sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= 90 && pc->famerank(sd->status.char_id, MAPID_TAEKWON) )
+ val *= 3; //Triple max HP for top ranking Taekwons over level 90.
- if (sd->class_&JOBL_UPPER)
- val += val * 25/100;
- else if (sd->class_&JOBL_BABY)
- val -= val * 30/100;
- if ((sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= 90 && pc->famerank(sd->status.char_id, MAPID_TAEKWON))
- val *= 3; //Triple max SP for top ranking Taekwons over level 90.
+ val += val * st->vit / 100; // +1% per each point of VIT
return (unsigned int)cap_value(val,0,UINT_MAX);
}
@@ -2176,7 +2154,7 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
pc->calc_skilltree(sd); // SkillTree calculation
- sd->max_weight = status->max_weight_base[pc->class2idx(sd->status.class_)]+sd->status.str*300;
+ sd->max_weight = status->dbs->max_weight_base[pc->class2idx(sd->status.class_)]+sd->status.str*300;
if(opt&SCO_FIRST) {
//Load Hp/SP from char-received data.
@@ -2214,37 +2192,11 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
sd->def_rate = sd->def2_rate = sd->mdef_rate = sd->mdef2_rate = 100;
sd->regen.state.block = 0;
- // zeroed arrays, order follows the order in pc.h.
- // add new arrays to the end of zeroed area in pc.h (see comments) and size here. [zzo]
- memset (sd->param_bonus, 0, sizeof(sd->param_bonus)
- + sizeof(sd->param_equip)
- + sizeof(sd->subele)
- + sizeof(sd->subrace)
- + sizeof(sd->subrace2)
- + sizeof(sd->subsize)
- + sizeof(sd->reseff)
- + sizeof(sd->weapon_coma_ele)
- + sizeof(sd->weapon_coma_race)
- + sizeof(sd->weapon_atk)
- + sizeof(sd->weapon_atk_rate)
- + sizeof(sd->arrow_addele)
- + sizeof(sd->arrow_addrace)
- + sizeof(sd->arrow_addsize)
- + sizeof(sd->magic_addele)
- + sizeof(sd->magic_addrace)
- + sizeof(sd->magic_addsize)
- + sizeof(sd->magic_atk_ele)
- + sizeof(sd->critaddrace)
- + sizeof(sd->expaddrace)
- + sizeof(sd->ignore_mdef)
- + sizeof(sd->ignore_def)
- + sizeof(sd->sp_gain_race)
- + sizeof(sd->sp_gain_race_attack)
- + sizeof(sd->hp_gain_race_attack)
- );
+ // zeroed arrays
+ memset(ZEROED_BLOCK_POS(sd), 0, ZEROED_BLOCK_SIZE(sd));
- memset (&sd->right_weapon.overrefine, 0, sizeof(sd->right_weapon) - sizeof(sd->right_weapon.atkmods));
- memset (&sd->left_weapon.overrefine, 0, sizeof(sd->left_weapon) - sizeof(sd->left_weapon.atkmods));
+ memset(ZEROED_BLOCK_POS(&(sd->right_weapon)), 0, ZEROED_BLOCK_SIZE(&(sd->right_weapon)));
+ memset(ZEROED_BLOCK_POS(&(sd->left_weapon)), 0, ZEROED_BLOCK_SIZE(&(sd->left_weapon)));
if (sd->special_state.intravision && !sd->sc.data[SC_CLAIRVOYANCE]) //Clear intravision as long as nothing else is using it
clif->sc_end(&sd->bl,sd->bl.id,SELF,SI_CLAIRVOYANCE);
@@ -2276,41 +2228,7 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
}
bstatus->aspd_rate = 1000;
bstatus->ele_lv = 1;
- bstatus->race = RC_DEMIHUMAN;
-
- //zero up structures...
- memset(&sd->autospell,0,sizeof(sd->autospell)
- + sizeof(sd->autospell2)
- + sizeof(sd->autospell3)
- + sizeof(sd->addeff)
- + sizeof(sd->addeff2)
- + sizeof(sd->addeff3)
- + sizeof(sd->skillatk)
- + sizeof(sd->skillusesprate)
- + sizeof(sd->skillusesp)
- + sizeof(sd->skillheal)
- + sizeof(sd->skillheal2)
- + sizeof(sd->hp_loss)
- + sizeof(sd->sp_loss)
- + sizeof(sd->hp_regen)
- + sizeof(sd->sp_regen)
- + sizeof(sd->skillblown)
- + sizeof(sd->skillcast)
- + sizeof(sd->add_def)
- + sizeof(sd->add_mdef)
- + sizeof(sd->add_mdmg)
- + sizeof(sd->add_drop)
- + sizeof(sd->itemhealrate)
- + sizeof(sd->subele2)
- + sizeof(sd->skillcooldown)
- + sizeof(sd->skillfixcast)
- + sizeof(sd->skillvarcast)
- + sizeof(sd->skillfixcastrate)
- + sizeof(sd->def_set_race)
- + sizeof(sd->mdef_set_race)
- );
-
- memset (&sd->bonus, 0,sizeof(sd->bonus));
+ bstatus->race = RC_PLAYER;
// Autobonus
pc->delautobonus(sd,sd->autobonus,ARRAYLENGTH(sd->autobonus),true);
@@ -2373,18 +2291,18 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
}
wa->atk += sd->inventory_data[index]->atk;
if ( (r = sd->status.inventory[index].refine) )
- wa->atk2 = status->refine_info[wlv].bonus[r-1] / 100;
+ wa->atk2 = status->dbs->refine_info[wlv].bonus[r-1] / 100;
#ifdef RENEWAL
wa->matk += sd->inventory_data[index]->matk;
wa->wlv = wlv;
if( r && sd->weapontype1 != W_BOW ) // renewal magic attack refine bonus
- wa->matk += status->refine_info[wlv].bonus[r-1] / 100;
+ wa->matk += status->dbs->refine_info[wlv].bonus[r-1] / 100;
#endif
//Overrefined bonus.
if (r)
- wd->overrefine = status->refine_info[wlv].randombonus_max[r-1] / 100;
+ wd->overrefine = status->dbs->refine_info[wlv].randombonus_max[r-1] / 100;
wa->range += sd->inventory_data[index]->range;
if(sd->inventory_data[index]->script) {
@@ -2412,7 +2330,7 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
else if(sd->inventory_data[index]->type == IT_ARMOR) {
int r;
if ( (r = sd->status.inventory[index].refine) )
- refinedef += status->refine_info[REFINE_TYPE_ARMOR].bonus[r-1];
+ refinedef += status->dbs->refine_info[REFINE_TYPE_ARMOR].bonus[r-1];
if(sd->inventory_data[index]->script) {
if( i == EQI_HAND_L ) //Shield
sd->state.lr_flag = 3;
@@ -2557,12 +2475,12 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
sd->bonus.splash_range += sd->bonus.splash_add_range;
// Damage modifiers from weapon type
- sd->right_weapon.atkmods[0] = status->atkmods[0][sd->weapontype1];
- sd->right_weapon.atkmods[1] = status->atkmods[1][sd->weapontype1];
- sd->right_weapon.atkmods[2] = status->atkmods[2][sd->weapontype1];
- sd->left_weapon.atkmods[0] = status->atkmods[0][sd->weapontype2];
- sd->left_weapon.atkmods[1] = status->atkmods[1][sd->weapontype2];
- sd->left_weapon.atkmods[2] = status->atkmods[2][sd->weapontype2];
+ sd->right_weapon.atkmods[0] = status->dbs->atkmods[0][sd->weapontype1];
+ sd->right_weapon.atkmods[1] = status->dbs->atkmods[1][sd->weapontype1];
+ sd->right_weapon.atkmods[2] = status->dbs->atkmods[2][sd->weapontype1];
+ sd->left_weapon.atkmods[0] = status->dbs->atkmods[0][sd->weapontype2];
+ sd->left_weapon.atkmods[1] = status->dbs->atkmods[1][sd->weapontype2];
+ sd->left_weapon.atkmods[2] = status->dbs->atkmods[2][sd->weapontype2];
if ((pc_isridingpeco(sd) || pc_isridingdragon(sd))
&& (sd->status.weapon==W_1HSPEAR || sd->status.weapon==W_2HSPEAR)
@@ -2578,9 +2496,9 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
// Job bonuses
index = pc->class2idx(sd->status.class_);
for(i=0;i<(int)sd->status.job_level && i<MAX_LEVEL;i++){
- if(!status->job_bonus[index][i])
+ if(!status->dbs->job_bonus[index][i])
continue;
- switch(status->job_bonus[index][i]) {
+ switch(status->dbs->job_bonus[index][i]) {
case 1: bstatus->str++; break;
case 2: bstatus->agi++; break;
case 3: bstatus->vit++; break;
@@ -2640,7 +2558,7 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
// Basic MaxHP value
//We hold the standard Max HP here to make it faster to recalculate on vit changes.
- sd->status.max_hp = status->base_pc_maxhp(sd,bstatus);
+ sd->status.max_hp = status->get_base_maxhp(sd,bstatus);
//This is done to handle underflows from negative Max HP bonuses
i64 = sd->status.max_hp + (int)bstatus->max_hp;
bstatus->max_hp = (unsigned int)cap_value(i64, 0, INT_MAX);
@@ -2665,7 +2583,7 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
// ----- SP MAX CALCULATION -----
// Basic MaxSP value
- sd->status.max_sp = status->base_pc_maxsp(sd,bstatus);
+ sd->status.max_sp = status->get_base_maxsp(sd,bstatus);
//This is done to handle underflows from negative Max SP bonuses
i64 = sd->status.max_sp + (int)bstatus->max_sp;
bstatus->max_sp = (unsigned int)cap_value(i64, 0, INT_MAX);
@@ -2852,17 +2770,12 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
else if (pc_isridingdragon(sd))
bstatus->aspd_rate += 250-50*pc->checkskill(sd,RK_DRAGONTRAINING);
#else // needs more info
- if((skill_lv=pc->checkskill(sd,SA_ADVANCEDBOOK))>0 && sd->status.weapon == W_BOOK)
- bstatus->aspd_rate += 5*skill_lv;
- if((skill_lv = pc->checkskill(sd,SG_DEVIL)) > 0 && !pc->nextjobexp(sd))
- bstatus->aspd_rate += 30*skill_lv;
- if((skill_lv=pc->checkskill(sd,GS_SINGLEACTION))>0 &&
- (sd->status.weapon >= W_REVOLVER && sd->status.weapon <= W_GRENADE))
- bstatus->aspd_rate += ((skill_lv+1)/2) * 10;
- if (pc_isridingpeco(sd))
- bstatus->aspd_rate -= 500-100*pc->checkskill(sd,KN_CAVALIERMASTERY);
- else if (pc_isridingdragon(sd))
- bstatus->aspd_rate -= 250-50*pc->checkskill(sd,RK_DRAGONTRAINING);
+ if ( (skill_lv = pc->checkskill(sd, SG_DEVIL)) > 0 && !pc->nextjobexp(sd) )
+ bstatus->aspd_rate += 30 * skill_lv;
+ if ( pc_isridingpeco(sd) )
+ bstatus->aspd_rate -= 500 - 100 * pc->checkskill(sd, KN_CAVALIERMASTERY);
+ else if ( pc_isridingdragon(sd) )
+ bstatus->aspd_rate -= 250 - 50 * pc->checkskill(sd, RK_DRAGONTRAINING);
#endif
bstatus->adelay = 2*bstatus->amotion;
@@ -2937,7 +2850,11 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
sd->right_weapon.addrace[RC_DRAGON]+=skill_lv;
sd->left_weapon.addrace[RC_DRAGON]+=skill_lv;
sd->magic_addrace[RC_DRAGON]+=skill_lv;
+#ifdef RENEWAL
+ sd->race_tolerance[RC_DRAGON] += skill_lv;
+#else
sd->subrace[RC_DRAGON]+=skill_lv;
+#endif
}
if( (skill_lv = pc->checkskill(sd, AB_EUCHARISTICA)) > 0 ) {
@@ -2947,7 +2864,11 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
sd->left_weapon.addele[ELE_DARK] += skill_lv;
sd->magic_addrace[RC_DEMON] += skill_lv;
sd->magic_addele[ELE_DARK] += skill_lv;
+#ifdef RENEWAL
+ sd->race_tolerance[RC_DEMON] += skill_lv;
+#else
sd->subrace[RC_DEMON] += skill_lv;
+#endif
sd->subele[ELE_DARK] += skill_lv;
}
@@ -2970,7 +2891,11 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
}
if(sc->data[SC_PROVIDENCE]){
sd->subele[ELE_HOLY] += sc->data[SC_PROVIDENCE]->val2;
+#ifdef RENEWAL
+ sd->race_tolerance[RC_DEMON] += sc->data[SC_PROVIDENCE]->val2;
+#else
sd->subrace[RC_DEMON] += sc->data[SC_PROVIDENCE]->val2;
+#endif
}
if(sc->data[SC_ARMORPROPERTY]) {
//This status change should grant card-type elemental resist.
@@ -3115,7 +3040,7 @@ int status_calc_npc_(struct npc_data *nd, enum e_status_calc_opt opt) {
nstatus->def_ele = ELE_NEUTRAL;
nstatus->ele_lv = 1;
- nstatus->race = RC_DEMIHUMAN;
+ nstatus->race = RC_PLAYER;
nstatus->size = nd->size;
nstatus->rhw.range = 1 + nstatus->size;
nstatus->mode = (MD_CANMOVE|MD_CANATTACK);
@@ -3169,6 +3094,8 @@ int status_calc_homunculus_(struct homun_data *hd, enum e_status_calc_opt opt) {
hstatus->aspd_rate = 1000;
#ifdef RENEWAL
+ hstatus->def = 0;
+
amotion = hd->homunculusDB->baseASPD;
amotion = amotion - amotion * (hstatus->dex + hom->dex_value) / 1000 - (hstatus->agi + hom->agi_value) * amotion / 250;
#else
@@ -3183,7 +3110,6 @@ int status_calc_homunculus_(struct homun_data *hd, enum e_status_calc_opt opt) {
hstatus->amotion = cap_value(amotion, battle_config.max_aspd, 2000);
hstatus->adelay = hstatus->amotion; //It seems adelay = amotion for Homunculus.
-
hstatus->max_hp = hom->max_hp;
hstatus->max_sp = hom->max_sp;
@@ -3644,7 +3570,7 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag) {
if (!(st->mode&MD_CANATTACK))
unit->stop_attack(bl);
if (!(st->mode&MD_CANMOVE))
- unit->stop_walking(bl,1);
+ unit->stop_walking(bl, STOPWALKING_FLAG_FIXPOS);
}
// No status changes alter these yet.
@@ -3654,7 +3580,7 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag) {
if(flag&SCB_MAXHP) {
if( bl->type&BL_PC ) {
- st->max_hp = status->base_pc_maxhp(sd,st);
+ st->max_hp = status->get_base_maxhp(sd,st);
if (sd)
st->max_hp += bst->max_hp - sd->status.max_hp;
@@ -3675,7 +3601,7 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag) {
if(flag&SCB_MAXSP) {
if( bl->type&BL_PC ) {
- st->max_sp = status->base_pc_maxsp(sd,st);
+ st->max_sp = status->get_base_maxsp(sd,st);
if (sd)
st->max_sp += bst->max_sp - sd->status.max_sp;
@@ -3742,19 +3668,14 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag) {
amotion = status->base_amotion_pc(sd, st);
#ifndef RENEWAL_ASPD
st->aspd_rate = status->calc_aspd_rate(bl, sc, bst->aspd_rate);
-
- if(st->aspd_rate != 1000)
- amotion = amotion*st->aspd_rate/1000;
-#else
- // aspd = baseaspd + floor(sqrt((agi^2/2) + (dex^2/5))/4 + (potskillbonus*agi/200))
- amotion -= (int)(sqrt((pow(st->agi, 2) / 2) + (pow(st->dex, 2) / 5)) / 4 + ((float)status->calc_aspd(bl, sc, 1) * st->agi / 200)) * 10;
-
- if ( (status->calc_aspd(bl, sc, 2) + st->aspd_rate2) != 0 ) // RE ASPD percertage modifier
- amotion -= ((amotion - ((sd->class_&JOBL_THIRD) ? battle_config.max_third_aspd : battle_config.max_aspd))
- * (status->calc_aspd(bl, sc, 2) + st->aspd_rate2) / 10 + 5) / 10;
-
+#endif
if ( st->aspd_rate != 1000 ) // absolute percentage modifier
- amotion = (200 - (200 - amotion / 10) * st->aspd_rate / 1000) * 10;
+ amotion = amotion * st->aspd_rate / 1000;
+ if ( sd && sd->ud.skilltimer != INVALID_TIMER && pc->checkskill(sd, SA_FREECAST) > 0 )
+ amotion = amotion * 5 * (pc->checkskill(sd, SA_FREECAST) + 10) / 100;
+#ifdef RENEWAL_ASPD
+ amotion += (max(0xc3 - amotion, 2) * (st->aspd_rate2 + status->calc_aspd(bl, sc, 2))) / 100;
+ amotion = 10 * (200 - amotion) + sd->bonus.aspd_add;
#endif
amotion = status->calc_fix_aspd(bl, sc, amotion);
st->amotion = cap_value(amotion, ((sd->class_&JOBL_THIRD) ? battle_config.max_third_aspd : battle_config.max_aspd), 2000);
@@ -4009,46 +3930,46 @@ int status_check_visibility(struct block_list *src, struct block_list *target) {
// Basic ASPD value
int status_base_amotion_pc(struct map_session_data *sd, struct status_data *st) {
int amotion;
-#ifdef RENEWAL_ASPD
- short mod = -1;
-
- switch ( sd->weapontype2 ) { // adjustment for dual wielding
- case W_DAGGER:
- mod = 0;
- break; // 0, 1, 1
- case W_1HSWORD:
- case W_1HAXE:
- mod = 1;
- if ( (sd->class_&MAPID_THIRDMASK) == MAPID_GUILLOTINE_CROSS ) // 0, 2, 3
- mod = sd->weapontype2 / W_1HSWORD + W_1HSWORD / sd->weapontype2;
- }
-
- amotion = (sd->status.weapon < MAX_WEAPON_TYPE && mod < 0)
- ? (status->aspd_base[pc->class2idx(sd->status.class_)][sd->status.weapon]) // single weapon
- : ((status->aspd_base[pc->class2idx(sd->status.class_)][sd->weapontype2] // dual-wield
- + status->aspd_base[pc->class2idx(sd->status.class_)][sd->weapontype2]) * 6 / 10 + 10 * mod
- - status->aspd_base[pc->class2idx(sd->status.class_)][sd->weapontype2]
- + status->aspd_base[pc->class2idx(sd->status.class_)][sd->weapontype1]);
-
+#ifdef RENEWAL_ASPD /* [malufett/Hercules] */
+ float temp;
+ int skill_lv, val = 0;
+ amotion = status->dbs->aspd_base[pc->class2idx(sd->status.class_)][sd->weapontype1];
+ if ( sd->status.weapon > MAX_WEAPON_TYPE )
+ amotion += status->dbs->aspd_base[pc->class2idx(sd->status.class_)][sd->weapontype2] / 4;
if ( sd->status.shield )
- amotion += (2000 - status->aspd_base[pc->class2idx(sd->status.class_)][W_FIST]) +
- (status->aspd_base[pc->class2idx(sd->status.class_)][MAX_WEAPON_TYPE] - 2000);
-
+ amotion += status->dbs->aspd_base[pc->class2idx(sd->status.class_)][MAX_WEAPON_TYPE];
+ switch ( sd->status.weapon ) {
+ case W_BOW: case W_MUSICAL:
+ case W_WHIP: case W_REVOLVER:
+ case W_RIFLE: case W_GATLING:
+ case W_SHOTGUN: case W_GRENADE:
+ temp = st->dex * st->dex / 7.0f + st->agi * st->agi * 0.5f;
+ break;
+ default:
+ temp = st->dex * st->dex / 5.0f + st->agi * st->agi * 0.5f;
+ }
+ temp = (float)(sqrt(temp) * 0.25f) + 0xc4;
+ if ( (skill_lv = pc->checkskill(sd, SA_ADVANCEDBOOK)) > 0 && sd->status.weapon == W_BOOK )
+ val += (skill_lv - 1) / 2 + 1;
+ if ( (skill_lv = pc->checkskill(sd, GS_SINGLEACTION)) > 0 )
+ val += ((skill_lv + 1) / 2);
+ amotion = ((int)(temp + ((float)(status->calc_aspd(&sd->bl, &sd->sc, 1) + val) * st->agi / 200)) - min(amotion, 200));
#else
// base weapon delay
amotion = (sd->status.weapon < MAX_WEAPON_TYPE)
- ? (status->aspd_base[pc->class2idx(sd->status.class_)][sd->status.weapon]) // single weapon
- : (status->aspd_base[pc->class2idx(sd->status.class_)][sd->weapontype1] + status->aspd_base[pc->class2idx(sd->status.class_)][sd->weapontype2]) * 7 / 10; // dual-wield
+ ? (status->dbs->aspd_base[pc->class2idx(sd->status.class_)][sd->status.weapon]) // single weapon
+ : (status->dbs->aspd_base[pc->class2idx(sd->status.class_)][sd->weapontype1] + status->dbs->aspd_base[pc->class2idx(sd->status.class_)][sd->weapontype2]) * 7 / 10; // dual-wield
// percentual delay reduction from stats
amotion -= amotion * (4 * st->agi + st->dex) / 1000;
-#endif
+
// raw delay adjustment from bAspd bonus
amotion += sd->bonus.aspd_add;
/* angra manyu disregards aspd_base and similar */
if ( sd->equip_index[EQI_HAND_R] >= 0 && sd->status.inventory[sd->equip_index[EQI_HAND_R]].nameid == ITEMID_ANGRA_MANYU )
return 0;
+#endif
return amotion;
}
@@ -4141,7 +4062,7 @@ void status_calc_misc(struct block_list *bl, struct status_data *st, int level)
if ( bl->type == BL_HOM ) {
st->def2 = status_get_homvit(bl) + status_get_homagi(bl) / 2;
st->mdef2 = (status_get_homvit(bl) + status_get_homint(bl)) / 2;
- st->def += status_get_homvit(bl) + level / 2;
+ st->def += status_get_homvit(bl) + level / 2; // Increase. Already initialized in status_calc_homunculus_
st->mdef = (int)(((float)status_get_homvit(bl) + level) / 4 + (float)status_get_homint(bl) / 2);
st->hit = level + st->dex + 150;
st->flee = level + status_get_homagi(bl);
@@ -4593,6 +4514,9 @@ unsigned short status_calc_batk(struct block_list *bl, struct status_change *sc,
#ifndef RENEWAL
if(sc->data[SC_LKCONCENTRATION])
batk += batk * sc->data[SC_LKCONCENTRATION]->val2/100;
+#else
+ if ( sc->data[SC_NOEQUIPWEAPON] && bl->type != BL_PC )
+ batk -= batk * sc->data[SC_NOEQUIPWEAPON]->val2 / 100;
#endif
if(sc->data[SC_SKE])
batk += batk * 3;
@@ -4672,7 +4596,7 @@ unsigned short status_calc_watk(struct block_list *bl, struct status_change *sc,
if(sc->data[SC_LKCONCENTRATION])
watk += watk * sc->data[SC_LKCONCENTRATION]->val2/100;
#endif
- if(sc->data[SC_INCATKRATE])
+ if(sc->data[SC_INCATKRATE] && bl->type != BL_MOB)
watk += watk * sc->data[SC_INCATKRATE]->val1/100;
if(sc->data[SC_PROVOKE])
watk += watk * sc->data[SC_PROVOKE]->val3/100;
@@ -4682,8 +4606,10 @@ unsigned short status_calc_watk(struct block_list *bl, struct status_change *sc,
watk += watk * sc->data[SC_HLIF_FLEET]->val3/100;
if(sc->data[SC_CURSE])
watk -= watk * 25/100;
+#ifndef RENEWAL
if(sc->data[SC_NOEQUIPWEAPON] && bl->type != BL_PC)
watk -= watk * sc->data[SC_NOEQUIPWEAPON]->val2/100;
+#endif
if(sc->data[SC__ENERVATION])
watk -= watk * sc->data[SC__ENERVATION]->val2 / 100;
if(sc->data[SC_RUSH_WINDMILL])
@@ -5227,7 +5153,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
@@ -5508,8 +5434,8 @@ short status_calc_aspd(struct block_list *bl, struct status_change *sc, short fl
bonus -= sc->data[SC_DEFENDER]->val4 / 10;
if (sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_ENEMY) // needs more info
bonus -= 25;
- if (sc->data[SC_GRAVITATION])
- bonus -= sc->data[SC_GRAVITATION]->val2; // needs more info
+ if (sc->data[SC_GRAVITATION] && sc->data[SC_GRAVITATION]->val3 != BCT_SELF)
+ bonus -= sc->data[SC_GRAVITATION]->val2 / 10;
if (sc->data[SC_JOINTBEAT]) { // needs more info
if (sc->data[SC_JOINTBEAT]->val2&BREAK_WRIST)
bonus -= 25;
@@ -5670,7 +5596,7 @@ short status_calc_aspd_rate(struct block_list *bl, struct status_change *sc, int
aspd_rate += sc->data[SC_DEFENDER]->val4;
if(sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_ENEMY)
aspd_rate += 250;
- if(sc->data[SC_GRAVITATION])
+ if(sc->data[SC_GRAVITATION] && sc->data[SC_GRAVITATION]->val3 != BCT_SELF)
aspd_rate += sc->data[SC_GRAVITATION]->val2;
if(sc->data[SC_JOINTBEAT]) {
if( sc->data[SC_JOINTBEAT]->val2&BREAK_WRIST )
@@ -6047,7 +5973,7 @@ int status_get_party_id(struct block_list *bl) {
struct mob_data *md=(TBL_MOB*)bl;
if( md->master_id > 0 ) {
struct map_session_data *msd;
- if (md->special_state.ai && (msd = map->id2sd(md->master_id)) != NULL)
+ if (md->special_state.ai != AI_NONE && (msd = map->id2sd(md->master_id)) != NULL)
return msd->status.party_id;
return -md->master_id;
}
@@ -6090,7 +6016,7 @@ int status_get_guild_id(struct block_list *bl) {
// Guardian guild data may not been available yet, castle data is always set
return (md->guardian_data->g)?md->guardian_data->g->guild_id:md->guardian_data->castle->guild_id;
}
- if( md->special_state.ai && (msd = map->id2sd(md->master_id)) != NULL )
+ if (md->special_state.ai != AI_NONE && (msd = map->id2sd(md->master_id)) != NULL)
return msd->status.guild_id; //Alchemist's mobs [Skotlex]
break;
}
@@ -6132,7 +6058,7 @@ int status_get_emblem_id(struct block_list *bl) {
struct mob_data *md = (struct mob_data *)bl;
if (md->guardian_data) //Guardian's guild [Skotlex]
return (md->guardian_data->g) ? md->guardian_data->g->emblem_id:0;
- if (md->special_state.ai && (msd = map->id2sd(md->master_id)) != NULL)
+ if (md->special_state.ai != AI_NONE && (msd = map->id2sd(md->master_id)) != NULL)
return msd->guild_emblem_id; //Alchemist's mobs [Skotlex]
}
break;
@@ -6315,7 +6241,7 @@ void status_set_viewdata(struct block_list *bl, int class_)
if (vd)
nd->vd = vd;
else
- ShowError("status_set_viewdata (NPC): No view data for class %d\n", class_);
+ ShowError("status_set_viewdata (NPC): No view data for class %d (name=%s)\n", class_, nd->name);
}
break;
case BL_HOM: //[blackhole89]
@@ -6604,9 +6530,6 @@ int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_typ
case SC_COLD:
tick_def2 = bst->vit*100 + status->get_lv(bl)*20;
break;
- case SC_VACUUM_EXTREME:
- tick_def2 = bst->str*50;
- break;
case SC_MANDRAGORA:
sc_def = (st->vit + st->luk)*20;
break;
@@ -6616,6 +6539,9 @@ int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_typ
case SC_NEEDLE_OF_PARALYZE:
tick_def2 = (st->vit + st->luk) * 50;
break;
+ case SC_NETHERWORLD:
+ tick_def2 = 1000 * (((bl->type == BL_PC) ? ((TBL_PC*)bl)->status.job_level : 0) / 10 + status->get_lv(bl) / 50);
+ break;
default:
//Effect that cannot be reduced? Likely a buff.
if (!(rnd()%10000 < rate))
@@ -6717,6 +6643,9 @@ int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_typ
case SC_FROSTMISTY:
tick = max(tick, 6000);
break;
+ case SC_NETHERWORLD:
+ tick = max(tick, 4000);
+ break;
default:
//Skills need to trigger even if the duration is reduced below 1ms
tick = max(tick, 1);
@@ -7055,7 +6984,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
i = sd->equip_index[EQI_HAND_R];
if (i>=0 && sd->inventory_data[i] && sd->inventory_data[i]->type == IT_WEAPON) {
opt_flag|=2;
- pc->unequipitem(sd,i,3);
+ pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE);
}
if (!opt_flag) return 0;
}
@@ -7071,7 +7000,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
i = sd->equip_index[EQI_HAND_L];
if ( i < 0 || !sd->inventory_data[i] || sd->inventory_data[i]->type != IT_ARMOR )
return 0;
- pc->unequipitem(sd,i,3);
+ pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE);
}
if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
break;
@@ -7083,7 +7012,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
i = sd->equip_index[EQI_ARMOR];
if ( i < 0 || !sd->inventory_data[i] )
return 0;
- pc->unequipitem(sd,i,3);
+ pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE);
}
if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
break;
@@ -7095,7 +7024,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
i = sd->equip_index[EQI_HEAD_TOP];
if ( i < 0 || !sd->inventory_data[i] )
return 0;
- pc->unequipitem(sd,i,3);
+ pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE);
}
if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
break;
@@ -7165,12 +7094,12 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
if( !(sd->bonus.unstripable_equip&EQP_ACC_L) ) {
i = sd->equip_index[EQI_ACC_L];
if( i >= 0 && sd->inventory_data[i] && sd->inventory_data[i]->type == IT_ARMOR )
- pc->unequipitem(sd,i,3); //L-Accessory
+ pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE); //L-Accessory
}
if( !(sd->bonus.unstripable_equip&EQP_ACC_R) ) {
i = sd->equip_index[EQI_ACC_R];
if( i >= 0 && sd->inventory_data[i] && sd->inventory_data[i]->type == IT_ARMOR )
- pc->unequipitem(sd,i,3); //R-Accessory
+ pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE); //R-Accessory
}
if( i < 0 )
return 0;
@@ -7248,6 +7177,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
// Other Effects
case SC_VACUUM_EXTREME:
+ case SC_NETHERWORLD:
return 0;
}
@@ -7400,7 +7330,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
status_change_end(bl, SC_FOOD_LUK, INVALID_TIMER);
break;
case SC_ENDURE:
- if( val4 )
+ if( val4 == 1 )
status_change_end(bl, SC_LKCONCENTRATION, INVALID_TIMER);
break;
case SC_FIGHTINGSPIRIT:
@@ -7603,7 +7533,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
}
vd = status->get_viewdata(bl);
- calc_flag = status->ChangeFlagTable[type];
+ calc_flag = status->dbs->ChangeFlagTable[type];
if(!(flag&SCFLAG_LOADED)) { // Do not parse val settings when loading SCs
switch(type) {
case SC_ADORAMUS:
@@ -7619,7 +7549,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
struct map_session_data *tsd;
if( sd ) {
int i;
- for( i = 0; i < 5; i++ ) {
+ for( i = 0; i < MAX_PC_DEVOTION; i++ ) {
if( sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) )
status->change_start(bl, &tsd->bl, type, 10000, val1, val2, val3, val4, tick, SCFLAG_ALL);
}
@@ -7646,11 +7576,13 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
tick = -1; // duration sent to the client should be infinite
break;
case SC_EDP: // [Celest]
- val2 = val1 + 2; //Chance to Poison enemies.
- val3 = 50*(val1+1); //Damage increase (+50 +50*lv%)
- #ifdef RENEWAL_EDP
- val4 = 100 * ((val1 + 1)/2 + 2);
- #endif
+ //Chance to Poison enemies.
+#ifdef RENEWAL_EDP
+ val2 = ((val1 + 1) / 2 + 2);
+#else
+ val2 = val1 + 2;
+#endif
+ val3 = 50 * (val1 + 1); //Damage increase (+50 +50*lv%)
if( sd )//[Ind] - iROwiki says each level increases its duration by 3 seconds
tick += pc->checkskill(sd,GC_RESEARCHNEWPOISON)*3000;
break;
@@ -7716,7 +7648,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
struct map_session_data *tsd;
if( sd ) {
int i;
- for( i = 0; i < 5; i++ ) {
+ for( i = 0; i < MAX_PC_DEVOTION; i++ ) {
if( sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) )
status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, SCFLAG_ALL);
}
@@ -7974,7 +7906,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
if( bl->type&(BL_PC|BL_MER) ) {
if( sd ) {
- for( i = 0; i < 5; i++ ) {
+ for( i = 0; i < MAX_PC_DEVOTION; i++ ) {
if( sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) )
status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, SCFLAG_ALL);
}
@@ -7994,7 +7926,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
if (sd) {
struct map_session_data *tsd;
int i;
- for (i = 0; i < 5; i++) {
+ for (i = 0; i < MAX_PC_DEVOTION; i++) {
//See if there are devoted characters, and pass the status to them. [Skotlex]
if (sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])))
status->change_start(bl, &tsd->bl,type,10000,val1,5+val1*5,val3,val4,tick,SCFLAG_NOAVOID);
@@ -8030,7 +7962,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
case SC_BERSERK:
if( val3 == SC__BLOODYLUST )
sc_start(src,bl,(sc_type)val3,100,val1,tick);
- if( !val3 && !(!sc->data[SC_ENDURE] || !sc->data[SC_ENDURE]->val4) )
+ if (!val3 && (!sc->data[SC_ENDURE] || !sc->data[SC_ENDURE]->val4))
sc_start4(src, bl, SC_ENDURE, 100,10,0,0,2, tick);
//HP healing is performing after the calc_status call.
//Val2 holds HP penalty
@@ -8887,6 +8819,9 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
else
val2 = val2 / 4 * val1; // STAT DEF increase: [(Caster VIT / 4) x Skill Level]
break;
+ case SC_GENTLETOUCH_ENERGYGAIN:
+ val2 = 10 + 5 * val1;
+ break;
case SC_PYROTECHNIC_OPTION:
val2 = 60;
break;
@@ -9129,7 +9064,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
val2 = 20+(20*val1);
break;
default:
- if (calc_flag == SCB_NONE && status->SkillChangeTable[type] == 0 && status->IconChangeTable[type] == 0) {
+ if (calc_flag == SCB_NONE && status->dbs->SkillChangeTable[type] == 0 && status->dbs->IconChangeTable[type] == 0) {
//Status change with no calc, no icon, and no skill associated...?
ShowError("UnknownStatusChange [%d]\n", type);
return 0;
@@ -9283,7 +9218,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
}
/* [Ind/Hercules] */
- if( sd && status->DisplayType[type] ) {
+ if( sd && status->dbs->DisplayType[type] ) {
int dval1 = 0, dval2 = 0, dval3 = 0;
switch( type ) {
case SC_ALL_RIDING:
@@ -9334,11 +9269,12 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
case SC_MEIKYOUSISUI:
case SC_NEEDLE_OF_PARALYZE:
case SC_DEATHBOUND:
- unit->stop_walking(bl,1);
+ case SC_NETHERWORLD:
+ unit->stop_walking(bl, STOPWALKING_FLAG_FIXPOS);
break;
case SC_ANKLESNARE:
if( battle_config.skill_trap_type || !map_flag_gvg(bl->m) )
- unit->stop_walking(bl,1);
+ unit->stop_walking(bl, STOPWALKING_FLAG_FIXPOS);
break;
case SC_HIDING:
case SC_CLOAKING:
@@ -9575,8 +9511,8 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
calc_flag&=~SCB_DYE;
}
- if(!(flag&SCFLAG_NOICON) && !(flag&SCFLAG_LOADED && status->DisplayType[type]))
- clif->status_change(bl,status->IconChangeTable[type],1,tick,(val_flag&1)?val1:1,(val_flag&2)?val2:0,(val_flag&4)?val3:0);
+ if(!(flag&SCFLAG_NOICON) && !(flag&SCFLAG_LOADED && status->dbs->DisplayType[type]))
+ clif->status_change(bl,status->dbs->IconChangeTable[type],1,tick,(val_flag&1)?val1:1,(val_flag&2)?val2:0,(val_flag&4)?val3:0);
/**
* used as temporary storage for scs with interval ticks, so that the actual duration is sent to the client first.
@@ -9592,14 +9528,18 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
++(sc->count);
sce = sc->data[type] = ers_alloc(status->data_ers, struct status_change_entry);
}
+
sce->val1 = val1;
sce->val2 = val2;
sce->val3 = val3;
sce->val4 = val4;
- if (tick >= 0)
+
+ if (tick >= 0) {
sce->timer = timer->add(timer->gettick() + tick, status->change_timer, bl->id, type);
- else {
+ sce->infinite_duration = false;
+ } else {
sce->timer = INVALID_TIMER; //Infinite duration
+ sce->infinite_duration = true;
if( sd )
chrif->save_scdata_single(sd->status.account_id,sd->status.char_id,type,sce);
}
@@ -9629,7 +9569,8 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
}
break;
case SC_CASH_BOSS_ALARM:
- clif->bossmapinfo(sd->fd, map->id2boss(sce->val1), 0); // First Message
+ if( sd )
+ clif->bossmapinfo(sd->fd, map->id2boss(sce->val1), 0); // First Message
break;
case SC_MER_HP:
status_percent_heal(bl, 100, 0); // Recover Full HP
@@ -9773,17 +9714,18 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
nullpo_ret(bl);
sc = status->get_sc(bl);
- st = status->get_status_data(bl);
if(type < 0 || type >= SC_MAX || !sc || !(sce = sc->data[type]))
return 0;
sd = BL_CAST(BL_PC,bl);
- if (sce->timer != tid && tid != INVALID_TIMER)
+ if (sce->timer != tid && tid != INVALID_TIMER && sce->timer != INVALID_TIMER)
return 0;
- if( sd && sce->timer == INVALID_TIMER && !sd->state.loggingout )
+ st = status->get_status_data(bl);
+
+ if( sd && sce->infinite_duration && !sd->state.loggingout )
chrif->del_scdata_single(sd->status.account_id,sd->status.char_id,type);
if (tid == INVALID_TIMER) {
@@ -9817,7 +9759,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
sc->data[type] = NULL;
- if( sd && status->DisplayType[type] ) {
+ if( sd && status->dbs->DisplayType[type] ) {
status->display_remove(sd,type);
}
@@ -9827,7 +9769,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
#endif
vd = status->get_viewdata(bl);
- calc_flag = status->ChangeFlagTable[type];
+ calc_flag = status->dbs->ChangeFlagTable[type];
switch(type) {
case SC_GRANITIC_ARMOR:
{
@@ -9854,7 +9796,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
begin_spurt = false;
ud->state.running = 0;
if (ud->walktimer != INVALID_TIMER)
- unit->stop_walking(bl,1);
+ unit->stop_walking(bl, STOPWALKING_FLAG_FIXPOS);
}
if (begin_spurt && sce->val1 >= 7
&& DIFF_TICK(timer->gettick(), starttick) <= 1000
@@ -9877,7 +9819,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
if( bl->type == BL_PC ) {
// Clear Status from others
int i;
- for( i = 0; i < 5; i++ ) {
+ for( i = 0; i < MAX_PC_DEVOTION; i++ ) {
if( sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) && tsd->sc.data[type] )
status_change_end(&tsd->bl, type, INVALID_TIMER);
}
@@ -9964,7 +9906,9 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
}
sce->val2 = 0;
- skill->del_unitgroup(group,ALC_MARK);
+
+ if( group )
+ skill->del_unitgroup(group,ALC_MARK);
}
if ((sce->val1&0xFFFF) == CG_MOONLIT)
@@ -9996,11 +9940,11 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
if (src && sc2 && sc2->data[SC_RG_CCONFINE_M]) {
//If status was already ended, do nothing.
//Decrease count
- if (--(sc2->data[SC_RG_CCONFINE_M]->val1) <= 0) //No more holds, free him up.
+ if (--(sc2->data[SC_RG_CCONFINE_M]->val2) <= 0) //No more holds, free him up.
status_change_end(src, SC_RG_CCONFINE_M, INVALID_TIMER);
}
}
- /* Fall through */
+ break;
case SC_RG_CCONFINE_M:
if (sce->val2 > 0) {
//Caster has been unlocked... nearby chars need to be unlocked.
@@ -10067,7 +10011,8 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
if (sce->val3) { //Clear the group.
struct skill_unit_group* group = skill->id2group(sce->val3);
sce->val3 = 0;
- skill->del_unitgroup(group,ALC_MARK);
+ if( group )
+ skill->del_unitgroup(group,ALC_MARK);
}
break;
case SC_HERMODE:
@@ -10113,10 +10058,12 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
break;
// Note: vending/buying is closed by unit_remove_map, no
// need to do it here.
- map->quit(sd);
- // Because map->quit calls status_change_end with tid -1
- // from here it's not neccesary to continue
- return 1;
+ if( sd ) {
+ map->quit(sd);
+ // Because map->quit calls status_change_end with tid -1
+ // from here it's not neccesary to continue
+ return 1;
+ }
break;
case SC_STOP:
if( sce->val2 ) {
@@ -10128,7 +10075,8 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
}
break;
case SC_LKCONCENTRATION:
- status_change_end(bl, SC_ENDURE, INVALID_TIMER);
+ if (sc->data[SC_ENDURE] && sc->data[SC_ENDURE]->val4 != 2)
+ status_change_end(bl, SC_ENDURE, INVALID_TIMER);
break;
/**
* 3rd Stuff
@@ -10144,7 +10092,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
struct block_list* src = map->id2bl(sce->val2);
if( tid == -1 || !src)
break; // Terminated by Damage
- status_fix_damage(src,bl,400*sce->val1,clif->damage(bl,bl,0,0,400*sce->val1,0,0,0));
+ status_fix_damage(src,bl,400*sce->val1,clif->damage(bl,bl,0,0,400*sce->val1,0,BDT_NORMAL,0));
}
break;
case SC_WUGDASH:
@@ -10153,7 +10101,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
if (ud) {
ud->state.running = 0;
if (ud->walktimer != -1)
- unit->stop_walking(bl,1);
+ unit->stop_walking(bl, STOPWALKING_FLAG_FIXPOS);
}
}
break;
@@ -10196,15 +10144,11 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
map->foreachinrange(status->change_timer_sub, bl, battle_config.area_size,BL_CHAR, bl, sce, SC_CURSEDCIRCLE_TARGET, timer->gettick());
break;
case SC_RAISINGDRAGON:
- if( sd && sce->val2 && !pc_isdead(sd) ) {
+ if ( sd && sce->val2 && !pc_isdead(sd) ) {
int i;
- i = min(sd->spiritball,5);
- pc->delspiritball(sd, sd->spiritball, 0);
+ if ( (i = (sd->spiritball - 5)) > 0 )
+ pc->delspiritball(sd, i, 0);
status_change_end(bl, SC_EXPLOSIONSPIRITS, INVALID_TIMER);
- while( i > 0 ) {
- pc->addspiritball(sd, skill->get_time(MO_CALLSPIRITS, pc->checkskill(sd,MO_CALLSPIRITS)), 5);
- --i;
- }
}
break;
case SC_CURSEDCIRCLE_TARGET:
@@ -10222,7 +10166,8 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
struct block_list *src = map->id2bl(sce->val2);
if(src) {
struct status_change *ssc = status->get_sc(src);
- ssc->bs_counter--;
+ if( ssc )
+ ssc->bs_counter--;
}
}
break;
@@ -10468,7 +10413,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
}
//On Aegis, when turning off a status change, first goes the sc packet, then the option packet.
- clif->sc_end(bl,bl->id,AREA,status->IconChangeTable[type]);
+ clif->sc_end(bl,bl->id,AREA,status->dbs->IconChangeTable[type]);
if( opt_flag&8 ) //bugreport:681
clif->changeoption2(bl);
@@ -10563,6 +10508,8 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) {
ShowError("status_change_timer: Mismatch for type %d: %d != %d (bl id %d)\n",type,tid,sce->timer, bl->id);
return 0;
}
+
+ sce->timer = INVALID_TIMER;
sd = BL_CAST(BL_PC, bl);
@@ -10593,7 +10540,6 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) {
}
sc_timer_next(sce->val2+tick, status->change_timer, bl->id, data);
return 0;
- break;
case SC_SKA:
if(--(sce->val2)>0) {
@@ -10641,12 +10587,12 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) {
case SC_STONE:
if(sc->opt1 == OPT1_STONEWAIT && sce->val3) {
sce->val4 = 0;
- unit->stop_walking(bl,1);
+ unit->stop_walking(bl, STOPWALKING_FLAG_FIXPOS);
unit->stop_attack(bl);
sc->opt1 = OPT1_STONE;
clif->changeoption(bl);
sc_timer_next(1000+tick, status->change_timer, bl->id, data );
- status_calc_bl(bl, status->ChangeFlagTable[type]);
+ status_calc_bl(bl, status->dbs->ChangeFlagTable[type]);
return 0;
}
if(--(sce->val3) > 0) {
@@ -10688,14 +10634,16 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) {
case SC_KNOWLEDGE:
if (!sd) break;
- if (bl->m == sd->feel_map[0].m
- || bl->m == sd->feel_map[1].m
- || bl->m == sd->feel_map[2].m
- ) {
- //Timeout will be handled by pc->setpos
- sce->timer = INVALID_TIMER;
- return 0;
+ {
+ int i;
+ for (i = 0; i < MAX_PC_FEELHATE; i++) {
+ if (bl->m == sd->feel_map[i].m) {
+ //Timeout will be handled by pc->setpos
+ sce->timer = INVALID_TIMER;
+ return 0;
+ }
}
+ }
break;
case SC_BLOODING:
@@ -10882,7 +10830,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) {
case SC_PYREXIA:
if( --(sce->val4) > 0 ) {
map->freeblock_lock();
- clif->damage(bl,bl,status_get_amotion(bl),status_get_dmotion(bl)+500,100,0,0,0);
+ clif->damage(bl,bl,status_get_amotion(bl),status_get_dmotion(bl)+500,100,0,BDT_NORMAL,0);
status_fix_damage(NULL,bl,100,0);
if( sc->data[type] ) {
sc_timer_next(3000+tick,status->change_timer,bl->id,data);
@@ -10898,7 +10846,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) {
damage += st->vit * (sce->val1 - 3);
unit->skillcastcancel(bl,2);
map->freeblock_lock();
- status->damage(bl, bl, damage, 0, clif->damage(bl,bl,status_get_amotion(bl),status_get_dmotion(bl)+500,damage,1,0,0), 1);
+ status->damage(bl, bl, damage, 0, clif->damage(bl,bl,status_get_amotion(bl),status_get_dmotion(bl)+500,damage,1,BDT_NORMAL,0), 1);
if( sc->data[type] ) {
sc_timer_next(1000 + tick, status->change_timer, bl->id, data );
}
@@ -10922,13 +10870,15 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) {
}
if( !flag ) { // Random Skill Cast
+ map->freeblock_lock();
+
if (sd && !pc_issit(sd)) { //can't cast if sit
int mushroom_skill_id = 0;
unit->stop_attack(bl);
unit->skillcastcancel(bl,0);
do {
int i = rnd() % MAX_SKILL_MAGICMUSHROOM_DB;
- mushroom_skill_id = skill->magicmushroom_db[i].skill_id;
+ mushroom_skill_id = skill->dbs->magicmushroom_db[i].skill_id;
} while (mushroom_skill_id == 0);
switch( skill->get_casttype(mushroom_skill_id) ) { // Magic Mushroom skills are buffs or area damage
@@ -10945,7 +10895,10 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) {
}
clif->emotion(bl,E_HEH);
- sc_timer_next(4000+tick,status->change_timer,bl->id,data);
+ if( sc->data[type] )
+ sc_timer_next(4000+tick,status->change_timer,bl->id,data);
+
+ map->freeblock_unlock();
}
return 0;
}
@@ -10955,7 +10908,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) {
if( --(sce->val4) > 0 ) {
//Damage is every 10 seconds including 3%sp drain.
map->freeblock_lock();
- clif->damage(bl,bl,status_get_amotion(bl),1,1,0,0,0);
+ clif->damage(bl,bl,status_get_amotion(bl),1,1,0,BDT_NORMAL,0);
status->damage(NULL, bl, 1, st->max_sp * 3 / 100, 0, 0); //cancel dmg only if cancelable
if( sc->data[type] ) {
sc_timer_next(10000 + tick, status->change_timer, bl->id, data );
@@ -10993,8 +10946,15 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) {
int heal = st->max_hp * 3 / 100;
if (sc->count && sc->data[SC_AKAITSUKI] && heal)
heal = ~heal + 1;
+
+ map->freeblock_lock();
+
status->heal(bl, heal, 0, 2);
- sc_timer_next(5000 + tick, status->change_timer, bl->id, data);
+ if( sc->data[type] ) {
+ sc_timer_next(5000 + tick, status->change_timer, bl->id, data);
+ }
+ map->freeblock_unlock();
+
return 0;
}
break;
@@ -11005,7 +10965,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) {
int damage = 1000 + 3 * status_get_max_hp(bl) / 100; // Deals fixed (1000 + 3%*MaxHP)
map->freeblock_lock();
- clif->damage(bl,bl,0,0,damage,1,9,0); //damage is like endure effect with no walk delay
+ clif->damage(bl,bl,0,0,damage,1,BDT_MULTIENDURE,0); //damage is like endure effect with no walk delay
status->damage(src, bl, damage, 0, 0, 1);
if( sc->data[type]){ // Target still lives. [LimitLine]
@@ -11107,13 +11067,13 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) {
break;
map->freeblock_lock();
damage = sce->val3;
- status->damage(src, bl, damage, 0, clif->damage(bl,bl,st->amotion,st->dmotion+200,damage,1,0,0), 1);
+ status->damage(src, bl, damage, 0, clif->damage(bl,bl,st->amotion,st->dmotion+200,damage,1,BDT_NORMAL,0), 1);
unit->skillcastcancel(bl,1);
if ( sc->data[type] ) {
sc_timer_next(1000 + tick, status->change_timer, bl->id, data);
}
- map->freeblock_unlock();
status->heal(src, damage*(5 + 5 * sce->val1)/100, 0, 0); // 5 + 5% per level
+ map->freeblock_unlock();
return 0;
}
break;
@@ -11215,11 +11175,12 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) {
int damage = st->max_hp / 100; // Suggestion 1% each second
if( damage >= st->hp ) damage = st->hp - 1; // Do not kill, just keep you with 1 hp minimum
map->freeblock_lock();
- status_fix_damage(NULL,bl,damage,clif->damage(bl,bl,0,0,damage,0,0,0));
+ status_fix_damage(NULL,bl,damage,clif->damage(bl,bl,0,0,damage,0,BDT_NORMAL,0));
if( sc->data[type] ) {
sc_timer_next(1000 + tick, status->change_timer, bl->id, data);
}
map->freeblock_unlock();
+ return 0;
}
break;
@@ -11300,18 +11261,19 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) {
case SC_WATER_DROP:
case SC_WIND_CURTAIN:
case SC_STONE_SHIELD:
- if(status->charge(bl, 0, sce->val2) && (sce->val4==-1 || (sce->val4-=sce->val3)>=0))
+ if(status->charge(bl, 0, sce->val2) && (sce->val4==-1 || (sce->val4-=sce->val3)>=0)) {
sc_timer_next(sce->val3 + tick, status->change_timer, bl->id, data);
- else
+ return 0;
+ } else
if (bl->type == BL_ELEM)
elemental->change_mode(BL_CAST(BL_ELEM,bl),MAX_ELESKILLTREE);
- return 0;
+ break;
case SC_STOMACHACHE:
if( --(sce->val4) > 0 ) {
status->charge(bl,0,sce->val2); // Reduce 8 every 10 seconds.
if( sd && !pc_issit(sd) ) { // Force to sit every 10 seconds.
- pc_stop_walking(sd,1|4);
+ pc_stop_walking(sd, STOPWALKING_FLAG_FIXPOS|STOPWALKING_FLAG_NEXTCELL);
pc_stop_attack(sd);
pc_setsit(sd);
clif->sitting(bl);
@@ -11495,7 +11457,7 @@ int status_get_weapon_atk(struct block_list *bl, struct weapon_atk *watk, int fl
short index = sd->equip_index[EQI_HAND_R], refine;
if ( index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_WEAPON
&& (refine = sd->status.inventory[index].refine) < 16 && refine ) {
- int r = status->refine_info[watk->wlv].randombonus_max[refine + (4 - watk->wlv)] / 100;
+ int r = status->dbs->refine_info[watk->wlv].randombonus_max[refine + (4 - watk->wlv)] / 100;
if ( r )
max += (rnd() % 100) % r + 1;
}
@@ -11594,7 +11556,7 @@ void status_get_matk_sub(struct block_list *bl, int flag, unsigned short *matk_m
short index = sd->equip_index[EQI_HAND_R], refine;
if ( index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_WEAPON
&& (refine = sd->status.inventory[index].refine) < 16 && refine ) {
- int r = status->refine_info[sd->inventory_data[index]->wlv].randombonus_max[refine + (4 - sd->inventory_data[index]->wlv)] / 100;
+ int r = status->dbs->refine_info[sd->inventory_data[index]->wlv].randombonus_max[refine + (4 - sd->inventory_data[index]->wlv)] / 100;
if ( r )
*matk_max += (rnd() % 100) % r + 1;
}
@@ -11691,6 +11653,8 @@ int status_change_clear_buffs (struct block_list* bl, int type) {
if (!sc || !sc->count)
return 0;
+ map->freeblock_lock();
+
if (type&6) //Debuffs
for (i = SC_COMMON_MIN; i <= SC_COMMON_MAX; i++)
status_change_end(bl, (sc_type)i, INVALID_TIMER);
@@ -11737,6 +11701,9 @@ int status_change_clear_buffs (struct block_list* bl, int type) {
}
status_change_end(bl, (sc_type)i, INVALID_TIMER);
}
+
+ map->freeblock_unlock();
+
return 0;
}
@@ -12032,7 +11999,7 @@ int status_get_refine_chance(enum refine_type wlv, int refine) {
if ( refine < 0 || refine >= MAX_REFINE)
return 0;
- return status->refine_info[wlv].chance[refine];
+ return status->dbs->refine_info[wlv].chance[refine];
}
int status_get_sc_type(sc_type type) {
@@ -12040,43 +12007,206 @@ int status_get_sc_type(sc_type type) {
if( type <= SC_NONE || type >= SC_MAX )
return 0;
- return status->sc_conf[type];
+ return status->dbs->sc_conf[type];
+}
+
+void status_read_job_db_sub(int idx, const char *name, config_setting_t *jdb)
+{
+ config_setting_t *temp = NULL;
+ int i32 = 0;
+
+ struct {
+ const char *name;
+ int id;
+ } wnames[] = {
+ { "Fist", W_FIST },
+ { "Dagger", W_DAGGER },
+ { "Sword", W_1HSWORD },
+ { "TwoHandSword", W_2HSWORD },
+ { "Spear", W_1HSPEAR },
+ { "TwoHandSpear", W_2HSPEAR },
+ { "Axe", W_1HAXE },
+ { "TwoHandAxe", W_2HAXE },
+ { "Mace", W_MACE },
+ { "TwoHandMace", W_2HMACE },
+ { "Rod", W_STAFF },
+ { "Bow", W_BOW },
+ { "Knuckle", W_KNUCKLE },
+ { "Instrument", W_MUSICAL },
+ { "Whip", W_WHIP },
+ { "Book", W_BOOK },
+ { "Katar", W_KATAR },
+ { "Revolver", W_REVOLVER },
+ { "Rifle", W_RIFLE },
+ { "GatlingGun", W_GATLING },
+ { "Shotgun", W_SHOTGUN },
+ { "GrenadeLauncher", W_GRENADE },
+ { "FuumaShuriken", W_HUUMA },
+ { "TwoHandRod", W_2HSTAFF },
+#ifdef RENEWAL_ASPD
+ { "Shield", MAX_WEAPON_TYPE }
+#endif
+ };
+
+ if ((temp = libconfig->setting_get_member(jdb, "Inherit"))) {
+ int nidx = 0;
+ const char *iname;
+ while ((iname = libconfig->setting_get_string_elem(temp, nidx++))) {
+ int i, iidx, iclass, avg_increment, base;
+ if ((iclass = pc->check_job_name(iname)) == -1) {
+ ShowWarning("status_read_job_db: '%s' trying to inherit unknown '%s'!\n", name, iname);
+ continue;
+ }
+ iidx = pc->class2idx(iclass);
+ status->dbs->max_weight_base[idx] = status->dbs->max_weight_base[iidx];
+ memcpy(&status->dbs->aspd_base[idx], &status->dbs->aspd_base[iidx], sizeof(status->dbs->aspd_base[iidx]));
+
+ for (i = 1; i <= MAX_LEVEL && status->dbs->HP_table[iidx][i]; i++) {
+ status->dbs->HP_table[idx][i] = status->dbs->HP_table[iidx][i];
+ }
+ base = (i > 1 ? status->dbs->HP_table[idx][1] : 35); // Safe value if none are specified
+ avg_increment = (i > 2 ? (status->dbs->HP_table[idx][i] - base) / (i-1) : 5); // Safe value if none are specified
+ for ( ; i <= pc->max_level[idx][0]; i++) {
+ status->dbs->HP_table[idx][i] = min(base + avg_increment * i, battle_config.max_hp);
+ }
+
+ for (i = 1; i <= MAX_LEVEL && status->dbs->SP_table[iidx][i]; i++) {
+ status->dbs->SP_table[idx][i] = status->dbs->SP_table[iidx][i];
+ }
+ base = (i > 1 ? status->dbs->SP_table[idx][1] : 10); // Safe value if none are specified
+ avg_increment = (i > 2 ? (status->dbs->SP_table[idx][i] - base) / (i-1) : 1); // Safe value if none are specified
+ for ( ; i <= pc->max_level[idx][0]; i++) {
+ status->dbs->SP_table[idx][i] = min(base + avg_increment * i, battle_config.max_sp);
+ }
+ }
+ }
+ if ((temp = libconfig->setting_get_member(jdb, "InheritHP"))) {
+ int nidx = 0;
+ const char *iname;
+ while ((iname = libconfig->setting_get_string_elem(temp, nidx++))) {
+ int i, iidx, iclass, avg_increment, base;
+ if ((iclass = pc->check_job_name(iname)) == -1) {
+ ShowWarning("status_read_job_db: '%s' trying to inherit unknown '%s' HP!\n", name, iname);
+ continue;
+ }
+ iidx = pc->class2idx(iclass);
+ for (i = 1; i <= MAX_LEVEL && status->dbs->HP_table[iidx][i]; i++) {
+ status->dbs->HP_table[idx][i] = status->dbs->HP_table[iidx][i];
+ }
+ base = (i > 1 ? status->dbs->HP_table[idx][1] : 35); // Safe value if none are specified
+ avg_increment = (i > 2 ? (status->dbs->HP_table[idx][i] - base) / (i-1) : 5); // Safe value if none are specified
+ for ( ; i <= pc->max_level[idx][0]; i++) {
+ status->dbs->HP_table[idx][i] = min(base + avg_increment * i, battle_config.max_hp);
+ }
+ }
+ }
+ if ((temp = libconfig->setting_get_member(jdb, "InheritSP"))) {
+ int nidx = 0;
+ const char *iname;
+ while ((iname = libconfig->setting_get_string_elem(temp, nidx++))) {
+ int i, iidx, iclass, avg_increment, base;
+ if ((iclass = pc->check_job_name(iname)) == -1) {
+ ShowWarning("status_read_job_db: '%s' trying to inherit unknown '%s' SP!\n", name, iname);
+ continue;
+ }
+ iidx = pc->class2idx(iclass);
+ for (i = 1; i <= MAX_LEVEL && status->dbs->SP_table[iidx][i]; i++) {
+ status->dbs->SP_table[idx][i] = status->dbs->SP_table[iidx][i];
+ }
+ base = (i > 1 ? status->dbs->SP_table[idx][1] : 10); // Safe value if none are specified
+ avg_increment = (i > 2 ? (status->dbs->SP_table[idx][i] - base) / (i-1) : 1); // Safe value if none are specified
+ for ( ; i <= pc->max_level[idx][0]; i++) {
+ status->dbs->SP_table[idx][i] = min(avg_increment * i, battle_config.max_sp);
+ }
+ }
+ }
+
+ if (libconfig->setting_lookup_int(jdb, "Weight", &i32))
+ status->dbs->max_weight_base[idx] = i32;
+ else if (!status->dbs->max_weight_base[idx])
+ status->dbs->max_weight_base[idx] = 20000;
+
+ if ((temp = libconfig->setting_get_member(jdb, "BaseASPD"))) {
+ int widx = 0;
+ config_setting_t *wpn = NULL;
+ while ((wpn = libconfig->setting_get_elem(temp, widx++))) {
+ int w, wlen = ARRAYLENGTH(wnames);
+ const char *wname = config_setting_name(wpn);
+
+ ARR_FIND(0, wlen, w, strcmp(wnames[w].name, wname) == 0);
+ if (w != wlen) {
+ status->dbs->aspd_base[idx][wnames[w].id] = libconfig->setting_get_int(wpn);
+ } else {
+ ShowWarning("status_read_job_db: unknown weapon type '%s'!\n", wname);
+ }
+ }
+ }
+
+ if ((temp = libconfig->setting_get_member(jdb, "HPTable"))) {
+ int level = 0, avg_increment, base;
+ config_setting_t *hp = NULL;
+ while (level <= MAX_LEVEL && (hp = libconfig->setting_get_elem(temp, level))) {
+ i32 = libconfig->setting_get_int(hp);
+ status->dbs->HP_table[idx][++level] = min(i32, battle_config.max_hp);
+ }
+ base = (level > 0 ? status->dbs->HP_table[idx][1] : 35); // Safe value if none are specified
+ avg_increment = (level > 1 ? (status->dbs->HP_table[idx][level] - base) / level : 5); // Safe value if none are specified
+ for (++level; level <= pc->max_level[idx][0]; ++level) { /* limit only to possible maximum level of the given class */
+ status->dbs->HP_table[idx][level] = min(base + avg_increment * level, battle_config.max_hp); /* some are still empty? then let's use the average increase */
+ }
+ }
+
+ if ((temp = libconfig->setting_get_member(jdb, "SPTable"))) {
+ int level = 0, avg_increment, base;
+ config_setting_t *sp = NULL;
+ while (level <= MAX_LEVEL && (sp = libconfig->setting_get_elem(temp, level))) {
+ i32 = libconfig->setting_get_int(sp);
+ status->dbs->SP_table[idx][++level] = min(i32, battle_config.max_sp);
+ }
+ base = (level > 0 ? status->dbs->SP_table[idx][1] : 10); // Safe value if none are specified
+ avg_increment = (level > 1 ? (status->dbs->SP_table[idx][level] - base) / level : 1);
+ for ( ; level <= pc->max_level[idx][0]; level++ ) {
+ status->dbs->SP_table[idx][level] = min(base + avg_increment * level, battle_config.max_sp);
+ }
+ }
}
/*------------------------------------------
* DB reading.
-* job_db1.txt - weight, hp, sp, aspd
+* job_db.conf - weight, hp, sp, aspd
* job_db2.txt - job level stat bonuses
* size_fix.txt - size adjustment table for weapons
* refine_db.txt - refining data table
*------------------------------------------*/
-bool status_readdb_job1(char* fields[], int columns, int current)
-{// Job-specific values (weight, HP, SP, ASPD)
- int idx, class_;
- unsigned int i;
-
- class_ = atoi(fields[0]);
-
- if(!pc->db_checkid(class_))
- {
- ShowWarning("status_readdb_job1: Invalid job class %d specified.\n", class_);
- return false;
- }
- idx = pc->class2idx(class_);
-
- status->max_weight_base[idx] = atoi(fields[1]);
- status->hp_coefficient[idx] = atoi(fields[2]);
- status->hp_coefficient2[idx] = atoi(fields[3]);
- status->sp_coefficient[idx] = atoi(fields[4]);
+void status_read_job_db(void) { /* [malufett/Hercules] */
+ int i = 0;
+ config_t job_db_conf;
+ config_setting_t *jdb = NULL;
+ const char *config_filename =
#ifdef RENEWAL_ASPD
- for(i = 0; i <= MAX_WEAPON_TYPE; i++)
+ "db/re/job_db.conf";
#else
- for(i = 0; i < MAX_WEAPON_TYPE; i++)
+ "db/pre-re/job_db.conf";
#endif
- {
- status->aspd_base[idx][i] = atoi(fields[i+5]);
+
+ if ( libconfig->read_file(&job_db_conf, config_filename) ) {
+ ShowError("can't read %s\n", config_filename);
+ return;
}
- return true;
+ while ( (jdb = libconfig->setting_get_elem(job_db_conf.root, i++)) ) {
+ int class_, idx;
+ const char *name = config_setting_name(jdb);
+
+ if ( (class_ = pc->check_job_name(name)) == -1 ) {
+ ShowWarning("pc_read_job_db: '%s' unknown job name!\n", name);
+ continue;
+ }
+
+ idx = pc->class2idx(class_);
+ status->read_job_db_sub(idx, name, jdb);
+ }
+ ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", i, config_filename);
+ libconfig->destroy(&job_db_conf);
}
bool status_readdb_job2(char* fields[], int columns, int current)
@@ -12094,7 +12224,7 @@ bool status_readdb_job2(char* fields[], int columns, int current)
for(i = 1; i < columns; i++)
{
- status->job_bonus[idx][i-1] = atoi(fields[i]);
+ status->dbs->job_bonus[idx][i-1] = atoi(fields[i]);
}
return true;
}
@@ -12105,7 +12235,7 @@ bool status_readdb_sizefix(char* fields[], int columns, int current)
for(i = 0; i < MAX_WEAPON_TYPE; i++)
{
- status->atkmods[current][i] = atoi(fields[i]);
+ status->dbs->atkmods[current][i] = atoi(fields[i]);
}
return true;
}
@@ -12132,14 +12262,14 @@ bool status_readdb_refine(char* fields[], int columns, int current)
*delim = '\0';
- status->refine_info[current].chance[i] = atoi(fields[4+i]);
+ status->dbs->refine_info[current].chance[i] = atoi(fields[4+i]);
if (i >= random_bonus_start_level - 1)
- status->refine_info[current].randombonus_max[i] = random_bonus * (i - random_bonus_start_level + 2);
+ status->dbs->refine_info[current].randombonus_max[i] = random_bonus * (i - random_bonus_start_level + 2);
- status->refine_info[current].bonus[i] = bonus_per_level + atoi(delim+1);
+ status->dbs->refine_info[current].bonus[i] = bonus_per_level + atoi(delim+1);
if (i > 0)
- status->refine_info[current].bonus[i] += status->refine_info[current].bonus[i-1];
+ status->dbs->refine_info[current].bonus[i] += status->dbs->refine_info[current].bonus[i-1];
}
return true;
}
@@ -12153,7 +12283,7 @@ bool status_readdb_scconfig(char* fields[], int columns, int current) {
return false;
}
- status->sc_conf[val] = (int)strtol(fields[1], NULL, 0);
+ status->dbs->sc_conf[val] = (int)strtol(fields[1], NULL, 0);
return true;
}
@@ -12171,42 +12301,42 @@ int status_readdb(void)
// initialize databases to default
//
if( runflag == MAPSERVER_ST_RUNNING ) {//not necessary during boot
- // reset job_db1.txt data
- memset(status->max_weight_base, 0, sizeof(status->max_weight_base));
- memset(status->hp_coefficient, 0, sizeof(status->hp_coefficient));
- memset(status->hp_coefficient2, 0, sizeof(status->hp_coefficient2));
- memset(status->sp_coefficient, 0, sizeof(status->sp_coefficient));
- memset(status->aspd_base, 0, sizeof(status->aspd_base));
+ // reset job_db.conf data
+ memset(status->dbs->max_weight_base, 0, sizeof(status->dbs->max_weight_base));
+ memset(status->dbs->HP_table, 0, sizeof(status->dbs->HP_table));
+ memset(status->dbs->SP_table, 0, sizeof(status->dbs->SP_table));
// reset job_db2.txt data
- memset(status->job_bonus,0,sizeof(status->job_bonus)); // Job-specific stats bonus
+ memset(status->dbs->job_bonus,0,sizeof(status->dbs->job_bonus)); // Job-specific stats bonus
+ }
+ for ( i = 0; i < CLASS_COUNT; i++ ) {
+ for ( j = 0; j < MAX_WEAPON_TYPE; j++ )
+ status->dbs->aspd_base[i][j] = 2000;
+#ifdef RENEWAL_ASPD
+ status->dbs->aspd_base[i][MAX_WEAPON_TYPE] = 0;
+#endif
}
+
// size_fix.txt
- for(i = 0; i < ARRAYLENGTH(status->atkmods); i++)
+ for(i = 0; i < ARRAYLENGTH(status->dbs->atkmods); i++)
for(j = 0; j < MAX_WEAPON_TYPE; j++)
- status->atkmods[i][j] = 100;
+ status->dbs->atkmods[i][j] = 100;
// refine_db.txt
- for(i=0;i<ARRAYLENGTH(status->refine_info);i++) {
+ for(i=0;i<ARRAYLENGTH(status->dbs->refine_info);i++) {
for(j=0;j<MAX_REFINE; j++) {
- status->refine_info[i].chance[j] = 100;
- status->refine_info[i].bonus[j] = 0;
- status->refine_info[i].randombonus_max[j] = 0;
+ status->dbs->refine_info[i].chance[j] = 100;
+ status->dbs->refine_info[i].bonus[j] = 0;
+ status->dbs->refine_info[i].randombonus_max[j] = 0;
}
}
// read databases
//
-
-
-#ifdef RENEWAL_ASPD
- sv->readdb(map->db_path, "re/job_db1.txt", ',', 6+MAX_WEAPON_TYPE, 6+MAX_WEAPON_TYPE, -1, status->readdb_job1);
-#else
- sv->readdb(map->db_path, "pre-re/job_db1.txt", ',', 5+MAX_WEAPON_TYPE, 5+MAX_WEAPON_TYPE, -1, status->readdb_job1);
-#endif
sv->readdb(map->db_path, "job_db2.txt", ',', 1, 1+MAX_LEVEL, -1, status->readdb_job2);
- sv->readdb(map->db_path, DBPATH"size_fix.txt", ',', MAX_WEAPON_TYPE, MAX_WEAPON_TYPE, ARRAYLENGTH(status->atkmods), status->readdb_sizefix);
- sv->readdb(map->db_path, DBPATH"refine_db.txt", ',', 4+MAX_REFINE, 4+MAX_REFINE, ARRAYLENGTH(status->refine_info), status->readdb_refine);
+ sv->readdb(map->db_path, DBPATH"size_fix.txt", ',', MAX_WEAPON_TYPE, MAX_WEAPON_TYPE, ARRAYLENGTH(status->dbs->atkmods), status->readdb_sizefix);
+ sv->readdb(map->db_path, DBPATH"refine_db.txt", ',', 4+MAX_REFINE, 4+MAX_REFINE, ARRAYLENGTH(status->dbs->refine_info), status->readdb_refine);
sv->readdb(map->db_path, "sc_config.txt", ',', 2, 2, SC_MAX, status->readdb_scconfig);
+ status->read_job_db();
return 0;
}
@@ -12224,7 +12354,6 @@ int do_init_status(bool minimal) {
status->initChangeTables();
status->initDummyData();
status->readdb();
- status->calc_sigma();
status->natural_heal_prev_tick = timer->gettick();
status->data_ers = ers_new(sizeof(struct status_change_entry),"status.c::data_ers",ERS_OPT_NONE);
timer->add_interval(status->natural_heal_prev_tick + NATURAL_HEAL_INTERVAL, status->natural_heal_timer, 0, 0, NATURAL_HEAL_INTERVAL);
@@ -12241,6 +12370,7 @@ void do_final_status(void) {
*-------------------------------------*/
void status_defaults(void) {
status = &status_s;
+ status->dbs = &statusdbs;
/* vars */
//we need it for new cards 15 Feb 2005, to check if the combo cards are insrerted into the CURRENT weapon only
@@ -12248,23 +12378,8 @@ void status_defaults(void) {
status->current_equip_item_index = 0; //Contains inventory index of an equipped item. To pass it into the EQUP_SCRIPT [Lupus]
status->current_equip_card_id = 0; //To prevent card-stacking (from jA) [Skotlex]
- memset(status->max_weight_base,0,sizeof(status->max_weight_base)
- + sizeof(status->hp_coefficient)
- + sizeof(status->hp_coefficient2)
- + sizeof(status->hp_sigma_val)
- + sizeof(status->sp_coefficient)
- + sizeof(status->aspd_base)
- + sizeof(status->Skill2SCTable)
- + sizeof(status->IconChangeTable)
- + sizeof(status->ChangeFlagTable)
- + sizeof(status->SkillChangeTable)
- + sizeof(status->RelevantBLTypes)
- + sizeof(status->DisplayType)
- + sizeof(status->refine_info)
- + sizeof(status->atkmods)
- + sizeof(status->job_bonus)
- + sizeof(status->sc_conf)
- );
+ // These macros are used instead of a sum of sizeof(), to ensure that padding won't interfere with our size, and code won't rot when adding more fields
+ memset(ZEROED_BLOCK_POS(status->dbs), 0, ZEROED_BLOCK_SIZE(status->dbs));
status->data_ers = NULL;
memset(&status->dummy, 0, sizeof(status->dummy));
@@ -12361,9 +12476,8 @@ void status_defaults(void) {
status->initDummyData = initDummyData;
status->base_amotion_pc = status_base_amotion_pc;
status->base_atk = status_base_atk;
- status->calc_sigma = status_calc_sigma;
- status->base_pc_maxhp = status_base_pc_maxhp;
- status->base_pc_maxsp = status_base_pc_maxsp;
+ status->get_base_maxhp = status_get_base_maxhp;
+ status->get_base_maxsp = status_get_base_maxsp;
status->calc_npc_ = status_calc_npc_;
status->calc_str = status_calc_str;
status->calc_agi = status_calc_agi;
@@ -12393,9 +12507,10 @@ void status_defaults(void) {
status->display_remove = status_display_remove;
status->natural_heal = status_natural_heal;
status->natural_heal_timer = status_natural_heal_timer;
- status->readdb_job1 = status_readdb_job1;
status->readdb_job2 = status_readdb_job2;
status->readdb_sizefix = status_readdb_sizefix;
status->readdb_refine = status_readdb_refine;
status->readdb_scconfig = status_readdb_scconfig;
+ status->read_job_db = status_read_job_db;
+ status->read_job_db_sub = status_read_job_db_sub;
}
diff --git a/src/map/status.h b/src/map/status.h
index 1a8d7ef51..45a1300a0 100644
--- a/src/map/status.h
+++ b/src/map/status.h
@@ -5,10 +5,11 @@
#ifndef MAP_STATUS_H
#define MAP_STATUS_H
-#include "../config/core.h" // defType, RENEWAL, RENEWAL_ASPD
+#include "config/core.h" // defType, RENEWAL, RENEWAL_ASPD
-#include "../common/cbasetypes.h"
-#include "../common/mmo.h" // NEW_CARTS
+#include "common/conf.h"
+#include "common/cbasetypes.h"
+#include "common/mmo.h" // NEW_CARTS
struct block_list;
struct elemental_data;
@@ -527,7 +528,7 @@ typedef enum sc_type {
SC_BEYOND_OF_WARCRY,
SC_UNLIMITED_HUMMING_VOICE, // 410
SC_SITDOWN_FORCE,
- //SC_NETHERWORLD,
+ SC_NETHERWORLD,
/**
* Sura
**/
@@ -1655,49 +1656,6 @@ enum {
OPT3_CONTRACT = 0x00020000,
};
-enum {
- OPTION_NOTHING = 0x00000000,
- OPTION_SIGHT = 0x00000001,
- OPTION_HIDE = 0x00000002,
- OPTION_CLOAK = 0x00000004,
- OPTION_FALCON = 0x00000010,
- OPTION_RIDING = 0x00000020,
- OPTION_INVISIBLE = 0x00000040,
- OPTION_ORCISH = 0x00000800,
- OPTION_WEDDING = 0x00001000,
- OPTION_RUWACH = 0x00002000,
- OPTION_CHASEWALK = 0x00004000,
- OPTION_FLYING = 0x00008000, //Note that clientside Flying and Xmas are 0x8000 for clients prior to 2007.
- OPTION_XMAS = 0x00010000,
- OPTION_TRANSFORM = 0x00020000,
- OPTION_SUMMER = 0x00040000,
- OPTION_DRAGON1 = 0x00080000,
- OPTION_WUG = 0x00100000,
- OPTION_WUGRIDER = 0x00200000,
- OPTION_MADOGEAR = 0x00400000,
- OPTION_DRAGON2 = 0x00800000,
- OPTION_DRAGON3 = 0x01000000,
- OPTION_DRAGON4 = 0x02000000,
- OPTION_DRAGON5 = 0x04000000,
- OPTION_HANBOK = 0x08000000,
- OPTION_OKTOBERFEST = 0x10000000,
-
-#ifndef NEW_CARTS
- OPTION_CART1 = 0x00000008,
- OPTION_CART2 = 0x00000080,
- OPTION_CART3 = 0x00000100,
- OPTION_CART4 = 0x00000200,
- OPTION_CART5 = 0x00000400,
-
- /* compound constant for older carts */
- OPTION_CART = OPTION_CART1|OPTION_CART2|OPTION_CART3|OPTION_CART4|OPTION_CART5,
-#endif
-
- // compound constants
- OPTION_DRAGON = OPTION_DRAGON1|OPTION_DRAGON2|OPTION_DRAGON3|OPTION_DRAGON4|OPTION_DRAGON5,
- OPTION_COSTUME = OPTION_WEDDING|OPTION_XMAS|OPTION_SUMMER|OPTION_HANBOK|OPTION_OKTOBERFEST,
-};
-
//Defines for the manner system [Skotlex]
enum manner_flags
{
@@ -1868,6 +1826,7 @@ struct sc_display_entry {
struct status_change_entry {
int timer;
int val1,val2,val3,val4;
+ bool infinite_duration;
};
struct status_change {
@@ -1969,22 +1928,11 @@ struct s_refine_info {
int randombonus_max[MAX_REFINE]; // cumulative maximum random bonus damage
};
-/*=====================================
-* Interface : status.h
-* Generated by HerculesInterfaceMaker
-* created by Susu
-*-------------------------------------*/
-struct status_interface {
-
- /* vars */
- int current_equip_item_index;
- int current_equip_card_id;
- /* */
+struct s_status_dbs {
+BEGIN_ZEROED_BLOCK; /* Everything within this block will be memset to 0 when status_defaults() is executed */
int max_weight_base[CLASS_COUNT];
- int hp_coefficient[CLASS_COUNT];
- int hp_coefficient2[CLASS_COUNT];
- int hp_sigma_val[CLASS_COUNT][MAX_LEVEL+1];
- int sp_coefficient[CLASS_COUNT];
+ int HP_table[CLASS_COUNT][MAX_LEVEL + 1];
+ int SP_table[CLASS_COUNT][MAX_LEVEL + 1];
int aspd_base[CLASS_COUNT][MAX_WEAPON_TYPE+1]; // +1 for RENEWAL_ASPD
sc_type Skill2SCTable[MAX_SKILL]; // skill -> status
int IconChangeTable[SC_MAX]; // status -> "icon" (icon is a bit of a misnomer, since there exist values with no icon associated)
@@ -1998,6 +1946,22 @@ struct status_interface {
int atkmods[3][MAX_WEAPON_TYPE];//ATK weapon modification for size (size_fix.txt)
char job_bonus[CLASS_COUNT][MAX_LEVEL];
sc_conf_type sc_conf[SC_MAX];
+END_ZEROED_BLOCK; /* End */
+};
+
+/*=====================================
+* Interface : status.h
+* Generated by HerculesInterfaceMaker
+* created by Susu
+*-------------------------------------*/
+struct status_interface {
+
+ /* vars */
+ int current_equip_item_index;
+ int current_equip_card_id;
+
+ struct s_status_dbs *dbs;
+
struct eri *data_ers; //For sc_data entries
struct status_data dummy;
int64 natural_heal_prev_tick;
@@ -2082,9 +2046,8 @@ struct status_interface {
void (*initDummyData) (void);
int (*base_amotion_pc) (struct map_session_data *sd, struct status_data *st);
unsigned short (*base_atk) (const struct block_list *bl, const struct status_data *st);
- void (*calc_sigma) (void);
- unsigned int (*base_pc_maxhp) (struct map_session_data *sd, struct status_data *st);
- unsigned int (*base_pc_maxsp) (struct map_session_data *sd, struct status_data *st);
+ unsigned int (*get_base_maxhp) (struct map_session_data *sd, struct status_data *st);
+ unsigned int (*get_base_maxsp) (struct map_session_data *sd, struct status_data *st);
int (*calc_npc_) (struct npc_data *nd, enum e_status_calc_opt opt);
unsigned short (*calc_str) (struct block_list *bl, struct status_change *sc, int str);
unsigned short (*calc_agi) (struct block_list *bl, struct status_change *sc, int agi);
@@ -2114,11 +2077,12 @@ struct status_interface {
void (*display_remove) (struct map_session_data *sd, enum sc_type type);
int (*natural_heal) (struct block_list *bl, va_list args);
int (*natural_heal_timer) (int tid, int64 tick, int id, intptr_t data);
- bool (*readdb_job1) (char *fields[], int columns, int current);
bool (*readdb_job2) (char *fields[], int columns, int current);
bool (*readdb_sizefix) (char *fields[], int columns, int current);
bool (*readdb_refine) (char *fields[], int columns, int current);
bool (*readdb_scconfig) (char *fields[], int columns, int current);
+ void (*read_job_db) (void);
+ void (*read_job_db_sub) (int idx, const char *name, config_setting_t *jdb);
};
struct status_interface *status;
diff --git a/src/map/storage.c b/src/map/storage.c
index 79a5ad52d..95194bc47 100644
--- a/src/map/storage.c
+++ b/src/map/storage.c
@@ -6,25 +6,25 @@
#include "storage.h"
+#include "map/atcommand.h"
+#include "map/battle.h"
+#include "map/chrif.h"
+#include "map/clif.h"
+#include "map/guild.h"
+#include "map/intif.h"
+#include "map/itemdb.h"
+#include "map/log.h"
+#include "map/map.h" // struct map_session_data
+#include "map/pc.h"
+#include "common/cbasetypes.h"
+#include "common/db.h"
+#include "common/malloc.h"
+#include "common/nullpo.h"
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include "atcommand.h"
-#include "battle.h"
-#include "chrif.h"
-#include "clif.h"
-#include "guild.h"
-#include "intif.h"
-#include "itemdb.h"
-#include "log.h"
-#include "map.h" // struct map_session_data
-#include "pc.h"
-#include "../common/cbasetypes.h"
-#include "../common/db.h"
-#include "../common/malloc.h"
-#include "../common/nullpo.h"
-
struct storage_interface storage_s;
struct guild_storage_interface gstorage_s;
@@ -83,7 +83,7 @@ int storage_storageopen(struct map_session_data *sd)
{
nullpo_ret(sd);
- if(sd->state.storage_flag)
+ if (sd->state.storage_flag != STORAGE_FLAG_CLOSED)
return 1; //Already open?
if( !pc_can_give_items(sd) ) {
@@ -92,7 +92,7 @@ int storage_storageopen(struct map_session_data *sd)
return 1;
}
- sd->state.storage_flag = 1;
+ sd->state.storage_flag = STORAGE_FLAG_NORMAL;
storage->sortitem(sd->status.storage.items, ARRAYLENGTH(sd->status.storage.items));
clif->storagelist(sd, sd->status.storage.items, ARRAYLENGTH(sd->status.storage.items));
clif->updatestorageamount(sd, sd->status.storage.storage_amount, MAX_STORAGE);
@@ -109,7 +109,8 @@ int compare_item(struct item *a, struct item *b)
a->refine == b->refine &&
a->attribute == b->attribute &&
a->expire_time == b->expire_time &&
- a->bound == b->bound )
+ a->bound == b->bound &&
+ a->unique_id == b->unique_id)
{
int i;
for (i = 0; i < MAX_SLOTS && (a->card[i] == b->card[i]); i++);
@@ -155,6 +156,7 @@ int storage_additem(struct map_session_data* sd, struct item* item_data, int amo
{// existing items found, stack them
if( amount > MAX_AMOUNT - stor->items[i].amount || ( data->stack.storage && amount > data->stack.amount - stor->items[i].amount ) )
return 1;
+
stor->items[i].amount += amount;
clif->storageitemadded(sd,&stor->items[i],i,amount);
return 0;
@@ -190,9 +192,11 @@ int storage_delitem(struct map_session_data* sd, int n, int amount)
{
memset(&sd->status.storage.items[n],0,sizeof(sd->status.storage.items[0]));
sd->status.storage.storage_amount--;
- if( sd->state.storage_flag == 1 ) clif->updatestorageamount(sd, sd->status.storage.storage_amount, MAX_STORAGE);
+ if( sd->state.storage_flag == STORAGE_FLAG_NORMAL )
+ clif->updatestorageamount(sd, sd->status.storage.storage_amount, MAX_STORAGE);
}
- if( sd->state.storage_flag == 1 ) clif->storageitemremoved(sd,n,amount);
+ if( sd->state.storage_flag == STORAGE_FLAG_NORMAL )
+ clif->storageitemremoved(sd,n,amount);
return 0;
}
@@ -219,9 +223,9 @@ int storage_storageadd(struct map_session_data* sd, int index, int amount) {
return 0;
if( storage->additem(sd,&sd->status.inventory[index],amount) == 0 )
- pc->delitem(sd,index,amount,0,4,LOG_TYPE_STORAGE);
+ pc->delitem(sd, index, amount, 0, DELITEM_TOSTORAGE, LOG_TYPE_STORAGE);
else
- clif->dropitem(sd, index,0);
+ clif->dropitem(sd, index, 0);
return 1;
}
@@ -325,7 +329,7 @@ void storage_storageclose(struct map_session_data* sd) {
if( map->save_settings&4 )
chrif->save(sd,0); //Invokes the storage saving as well.
- sd->state.storage_flag = 0;
+ sd->state.storage_flag = STORAGE_FLAG_CLOSED;
}
/*==========================================
@@ -337,7 +341,7 @@ void storage_storage_quit(struct map_session_data* sd, int flag) {
if (map->save_settings&4)
chrif->save(sd, flag); //Invokes the storage saving as well.
- sd->state.storage_flag = 0;
+ sd->state.storage_flag = STORAGE_FLAG_CLOSED;
}
/**
@@ -380,7 +384,7 @@ int storage_guild_storageopen(struct map_session_data* sd)
if(sd->status.guild_id <= 0)
return 2;
- if(sd->state.storage_flag)
+ if (sd->state.storage_flag != STORAGE_FLAG_CLOSED)
return 1; //Can't open both storages at a time.
if( !pc_can_give_items(sd) ) { //check is this GM level can open guild storage and store items [Lupus]
@@ -399,7 +403,7 @@ int storage_guild_storageopen(struct map_session_data* sd)
return 1;
gstor->storage_status = 1;
- sd->state.storage_flag = 2;
+ sd->state.storage_flag = STORAGE_FLAG_GUILD;
storage->sortitem(gstor->items, ARRAYLENGTH(gstor->items));
clif->storagelist(sd, gstor->items, ARRAYLENGTH(gstor->items));
clif->updatestorageamount(sd, gstor->storage_amount, MAX_GUILD_STORAGE);
@@ -525,10 +529,10 @@ int storage_guild_storageadd(struct map_session_data* sd, int index, int amount)
return 0;
}
- if(gstorage->additem(sd,stor,&sd->status.inventory[index],amount)==0)
- pc->delitem(sd,index,amount,0,4,LOG_TYPE_GSTORAGE);
+ if( gstorage->additem(sd,stor,&sd->status.inventory[index],amount) == 0 )
+ pc->delitem(sd, index, amount, 0, DELITEM_TOSTORAGE, LOG_TYPE_GSTORAGE);
else
- clif->dropitem(sd, index,0);
+ clif->dropitem(sd, index, 0);
return 1;
}
@@ -694,7 +698,7 @@ int storage_guild_storageclose(struct map_session_data* sd) {
gstorage->save(sd->status.account_id, sd->status.guild_id,0);
stor->storage_status=0;
}
- sd->state.storage_flag = 0;
+ sd->state.storage_flag = STORAGE_FLAG_CLOSED;
return 0;
}
@@ -707,7 +711,7 @@ int storage_guild_storage_quit(struct map_session_data* sd, int flag) {
if(flag) {
//Only during a guild break flag is 1 (don't save storage)
- sd->state.storage_flag = 0;
+ sd->state.storage_flag = STORAGE_FLAG_CLOSED;
stor->storage_status = 0;
clif->storageclose(sd);
if (map->save_settings&4)
@@ -721,7 +725,7 @@ int storage_guild_storage_quit(struct map_session_data* sd, int flag) {
else
gstorage->save(sd->status.account_id,sd->status.guild_id,1);
}
- sd->state.storage_flag = 0;
+ sd->state.storage_flag = STORAGE_FLAG_CLOSED;
stor->storage_status = 0;
return 0;
diff --git a/src/map/storage.h b/src/map/storage.h
index 6393e124a..5f2c69f56 100644
--- a/src/map/storage.h
+++ b/src/map/storage.h
@@ -5,13 +5,22 @@
#ifndef MAP_STORAGE_H
#define MAP_STORAGE_H
-#include "../common/cbasetypes.h"
-#include "../common/db.h"
+#include "common/cbasetypes.h"
+#include "common/db.h"
struct guild_storage;
struct item;
struct map_session_data;
+/**
+ * Acceptable values for map_session_data.state.storage_flag
+ */
+enum storage_flag {
+ STORAGE_FLAG_CLOSED = 0, // Closed
+ STORAGE_FLAG_NORMAL = 1, // Normal Storage open
+ STORAGE_FLAG_GUILD = 2, // Guild Storage open
+};
+
struct storage_interface {
/* */
void (*reconnect) (void);
diff --git a/src/map/trade.c b/src/map/trade.c
index 7417f05af..4dd6ffafa 100644
--- a/src/map/trade.c
+++ b/src/map/trade.c
@@ -6,24 +6,24 @@
#include "trade.h"
+#include "map/atcommand.h"
+#include "map/battle.h"
+#include "map/chrif.h"
+#include "map/clif.h"
+#include "map/intif.h"
+#include "map/itemdb.h"
+#include "map/log.h"
+#include "map/map.h"
+#include "map/npc.h"
+#include "map/path.h"
+#include "map/pc.h"
+#include "map/storage.h"
+#include "common/nullpo.h"
+#include "common/socket.h"
+
#include <stdio.h>
#include <string.h>
-#include "atcommand.h"
-#include "battle.h"
-#include "chrif.h"
-#include "clif.h"
-#include "intif.h"
-#include "itemdb.h"
-#include "log.h"
-#include "map.h"
-#include "npc.h"
-#include "path.h"
-#include "pc.h"
-#include "storage.h"
-#include "../common/nullpo.h"
-#include "../common/socket.h"
-
struct trade_interface trade_s;
/*==========================================
@@ -145,8 +145,8 @@ void trade_tradeack(struct map_session_data *sd, int type) {
}
//Check if you can start trade.
- if (sd->npc_id || sd->state.vending || sd->state.buyingstore || sd->state.storage_flag
- || tsd->npc_id || tsd->state.vending || tsd->state.buyingstore || tsd->state.storage_flag
+ if (sd->npc_id || sd->state.vending || sd->state.buyingstore || sd->state.storage_flag != STORAGE_FLAG_CLOSED
+ || tsd->npc_id || tsd->state.vending || tsd->state.buyingstore || tsd->state.storage_flag != STORAGE_FLAG_CLOSED
) {
//Fail
clif->tradestart(sd, 2);
@@ -208,13 +208,13 @@ int impossible_trade_check(struct map_session_data *sd)
intif->wis_message_to_gm(map->wisp_server_name, PC_PERM_RECEIVE_HACK_INFO, message_to_gm);
// if we block people
if (battle_config.ban_hack_trade < 0) {
- chrif->char_ask_name(-1, sd->status.name, 1, 0, 0, 0, 0, 0, 0); // type: 1 - block
+ chrif->char_ask_name(-1, sd->status.name, CHAR_ASK_NAME_BLOCK, 0, 0, 0, 0, 0, 0);
set_eof(sd->fd); // forced to disconnect because of the hack
// message about the ban
safestrncpy(message_to_gm, msg_txt(540), sizeof(message_to_gm)); // This player has been definitively blocked.
// if we ban people
} else if (battle_config.ban_hack_trade > 0) {
- chrif->char_ask_name(-1, sd->status.name, 2, 0, 0, 0, 0, battle_config.ban_hack_trade, 0); // type: 2 - ban (year, month, day, hour, minute, second)
+ chrif->char_ask_name(-1, sd->status.name, CHAR_ASK_NAME_BAN, 0, 0, 0, 0, battle_config.ban_hack_trade, 0); // type: 2 - ban (year, month, day, hour, minute, second)
set_eof(sd->fd); // forced to disconnect because of the hack
// message about the ban
sprintf(message_to_gm, msg_txt(507), battle_config.ban_hack_trade); // This player has been banned for %d minute(s).
@@ -561,7 +561,7 @@ void trade_tradecommit(struct map_session_data *sd) {
flag = pc->additem(tsd, &sd->status.inventory[n], sd->deal.item[trade_i].amount,LOG_TYPE_TRADE);
if (flag == 0)
- pc->delitem(sd, n, sd->deal.item[trade_i].amount, 1, 6, LOG_TYPE_TRADE);
+ pc->delitem(sd, n, sd->deal.item[trade_i].amount, 1, DELITEM_SOLD, LOG_TYPE_TRADE);
else
clif->additem(sd, n, sd->deal.item[trade_i].amount, 0);
sd->deal.item[trade_i].index = 0;
@@ -573,7 +573,7 @@ void trade_tradecommit(struct map_session_data *sd) {
flag = pc->additem(sd, &tsd->status.inventory[n], tsd->deal.item[trade_i].amount,LOG_TYPE_TRADE);
if (flag == 0)
- pc->delitem(tsd, n, tsd->deal.item[trade_i].amount, 1, 6, LOG_TYPE_TRADE);
+ pc->delitem(tsd, n, tsd->deal.item[trade_i].amount, 1, DELITEM_SOLD, LOG_TYPE_TRADE);
else
clif->additem(tsd, n, tsd->deal.item[trade_i].amount, 0);
tsd->deal.item[trade_i].index = 0;
diff --git a/src/map/unit.c b/src/map/unit.c
index 2e96e9c20..60911b85a 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -4,47 +4,47 @@
#define HERCULES_CORE
-#include "../config/core.h" // RENEWAL_CAST
+#include "config/core.h" // RENEWAL_CAST
#include "unit.h"
+#include "map/battle.h"
+#include "map/battleground.h"
+#include "map/chat.h"
+#include "map/chrif.h"
+#include "map/clif.h"
+#include "map/duel.h"
+#include "map/elemental.h"
+#include "map/guild.h"
+#include "map/homunculus.h"
+#include "map/instance.h"
+#include "map/intif.h"
+#include "map/map.h"
+#include "map/mercenary.h"
+#include "map/mob.h"
+#include "map/npc.h"
+#include "map/party.h"
+#include "map/path.h"
+#include "map/pc.h"
+#include "map/pet.h"
+#include "map/script.h"
+#include "map/skill.h"
+#include "map/status.h"
+#include "map/storage.h"
+#include "map/trade.h"
+#include "map/vending.h"
+#include "common/HPM.h"
+#include "common/db.h"
+#include "common/malloc.h"
+#include "common/nullpo.h"
+#include "common/random.h"
+#include "common/showmsg.h"
+#include "common/socket.h"
+#include "common/timer.h"
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include "battle.h"
-#include "battleground.h"
-#include "chat.h"
-#include "chrif.h"
-#include "clif.h"
-#include "duel.h"
-#include "elemental.h"
-#include "guild.h"
-#include "homunculus.h"
-#include "instance.h"
-#include "intif.h"
-#include "map.h"
-#include "mercenary.h"
-#include "mob.h"
-#include "npc.h"
-#include "party.h"
-#include "path.h"
-#include "pc.h"
-#include "pet.h"
-#include "script.h"
-#include "skill.h"
-#include "status.h"
-#include "storage.h"
-#include "trade.h"
-#include "vending.h"
-#include "../common/HPM.h"
-#include "../common/db.h"
-#include "../common/malloc.h"
-#include "../common/nullpo.h"
-#include "../common/random.h"
-#include "../common/showmsg.h"
-#include "../common/socket.h"
-#include "../common/timer.h"
-
const short dirx[8]={0,-1,-1,-1,0,1,1,1};
const short diry[8]={1,1,0,-1,-1,-1,0,1};
@@ -737,7 +737,7 @@ int unit_movepos(struct block_list *bl, short dst_x, short dst_y, int easy, bool
if( ud == NULL) return 0;
- unit->stop_walking(bl,1);
+ unit->stop_walking(bl, STOPWALKING_FLAG_FIXPOS);
unit->stop_attack(bl);
if( checkpath && (map->getcell(bl->m,dst_x,dst_y,CELL_CHKNOPASS) || !path->search(NULL,bl->m,bl->x,bl->y,dst_x,dst_y,easy,CELL_CHKNOREACH)) )
@@ -834,7 +834,7 @@ int unit_blown(struct block_list* bl, int dx, int dy, int count, int flag)
ny = result&0xffff;
if(!su) {
- unit->stop_walking(bl, 0);
+ unit->stop_walking(bl, STOPWALKING_FLAG_NONE);
}
if( sd ) {
@@ -952,14 +952,10 @@ int unit_warp(struct block_list *bl,short m,short x,short y,clr_type type)
/*==========================================
* Caused the target object to stop moving.
- * Flag values:
- * &0x1: Issue a fixpos packet afterwards
- * &0x2: Force the unit to move one cell if it hasn't yet
- * &0x4: Enable moving to the next cell when unit was already half-way there
- * (may cause on-touch/place side-effects, such as a scripted map change)
+ * Flag values: @see unit_stopwalking_flag.
+ * Upper bytes may be used for other purposes depending on the unit type.
*------------------------------------------*/
-int unit_stop_walking(struct block_list *bl,int type)
-{
+int unit_stop_walking(struct block_list *bl, int flag) {
struct unit_data *ud;
const struct TimerData* td;
int64 tick;
@@ -976,22 +972,22 @@ int unit_stop_walking(struct block_list *bl,int type)
ud->walktimer = INVALID_TIMER;
ud->state.change_walk_target = 0;
tick = timer->gettick();
- if( (type&0x02 && !ud->walkpath.path_pos) //Force moving at least one cell.
- || (type&0x04 && td && DIFF_TICK(td->tick, tick) <= td->data/2) //Enough time has passed to cover half-cell
+ if( (flag&STOPWALKING_FLAG_ONESTEP && !ud->walkpath.path_pos) //Force moving at least one cell.
+ || (flag&STOPWALKING_FLAG_NEXTCELL && td && DIFF_TICK(td->tick, tick) <= td->data/2) //Enough time has passed to cover half-cell
) {
ud->walkpath.path_len = ud->walkpath.path_pos+1;
unit->walktoxy_timer(INVALID_TIMER, tick, bl->id, ud->walkpath.path_pos);
}
- if(type&0x01)
+ if(flag&STOPWALKING_FLAG_FIXPOS)
clif->fixpos(bl);
ud->walkpath.path_len = 0;
ud->walkpath.path_pos = 0;
ud->to_x = bl->x;
ud->to_y = bl->y;
- if(bl->type == BL_PET && type&~0xff)
- ud->canmove_tick = timer->gettick() + (type>>8);
+ if(bl->type == BL_PET && flag&~STOPWALKING_FLAG_MASK)
+ ud->canmove_tick = timer->gettick() + (flag>>8);
//Read, the check in unit_set_walkdelay means dmg during running won't fall through to this place in code [Kevin]
if (ud->state.running) {
@@ -1081,6 +1077,7 @@ int unit_can_move(struct block_list *bl) {
|| sc->data[SC_NEEDLE_OF_PARALYZE]
|| sc->data[SC_VACUUM_EXTREME]
|| (sc->data[SC_FEAR] && sc->data[SC_FEAR]->val2 > 0)
+ || sc->data[SC_NETHERWORLD]
|| (sc->data[SC_SPIDERWEB] && sc->data[SC_SPIDERWEB]->val1)
|| (sc->data[SC_CLOAKING] && sc->data[SC_CLOAKING]->val1 < 3 && !(sc->data[SC_CLOAKING]->val4&1)) //Need wall at level 1-2
|| (
@@ -1168,17 +1165,14 @@ int unit_set_walkdelay(struct block_list *bl, int64 tick, int delay, int type) {
//Stop walking, if chasing, readjust timers.
if (delay == 1) {
//Minimal delay (walk-delay) disabled. Just stop walking.
- unit->stop_walking(bl,4);
+ unit->stop_walking(bl, STOPWALKING_FLAG_NEXTCELL);
} else {
//Resume running after can move again [Kevin]
- if(ud->state.running)
- {
+ if (ud->state.running) {
timer->add(ud->canmove_tick, unit->resume_running, bl->id, (intptr_t)ud);
- }
- else
- {
- unit->stop_walking(bl,4);
- if(ud->target)
+ } else {
+ unit->stop_walking(bl, STOPWALKING_FLAG_NEXTCELL);
+ if (ud->target)
timer->add(ud->canmove_tick+1, unit->walktobl_sub, bl->id, ud->target);
}
}
@@ -1353,18 +1347,21 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
}
}
- if (sd || src->type == BL_HOM){
- if (!sd && (target = battle->get_master(src)))
- sd = map->id2sd(target->id);
- if (sd){
- /* temporarily disabled, awaiting for kenpachi to detail this so we can make it work properly */
+ if (src->type == BL_HOM) {
+ // In case of homunuculus, set the sd to the homunculus' master, as needed below
+ struct block_list *master = battle->get_master(src);
+ if (master)
+ sd = map->id2sd(master->id);
+ }
+
+ if (sd) {
+ /* temporarily disabled, awaiting for kenpachi to detail this so we can make it work properly */
#if 0
- if (sd->skillitem != skill_id && !skill->check_condition_castbegin(sd, skill_id, skill_lv))
+ if (sd->skillitem != skill_id && !skill->check_condition_castbegin(sd, skill_id, skill_lv))
#else
- if (!skill->check_condition_castbegin(sd, skill_id, skill_lv))
+ if (!skill->check_condition_castbegin(sd, skill_id, skill_lv))
#endif
- return 0;
- }
+ return 0;
}
if( src->type == BL_MOB )
@@ -1372,7 +1369,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
case NPC_SUMMONSLAVE:
case NPC_SUMMONMONSTER:
case AL_TELEPORT:
- if( ((TBL_MOB*)src)->master_id && ((TBL_MOB*)src)->special_state.ai )
+ if (((TBL_MOB*)src)->master_id && ((TBL_MOB*)src)->special_state.ai != AI_NONE)
return 0;
}
@@ -1543,8 +1540,8 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
}
}
- if(!ud->state.running) //need TK_RUN or WUGDASH handler to be done before that, see bugreport:6026
- unit->stop_walking(src,1);// even though this is not how official works but this will do the trick. bugreport:6829
+ if (!ud->state.running) //need TK_RUN or WUGDASH handler to be done before that, see bugreport:6026
+ unit->stop_walking(src, STOPWALKING_FLAG_FIXPOS);// even though this is not how official works but this will do the trick. bugreport:6829
// in official this is triggered even if no cast time.
clif->skillcasting(src, src->id, target_id, 0,0, skill_id, skill->get_ele(skill_id, skill_lv), casttime);
@@ -1604,7 +1601,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
unit->setdir(src, map->calc_dir(src, target->x, target->y));
ud->skilltimer = timer->add( tick+casttime, skill->castend_id, src->id, 0 );
if( sd && (pc->checkskill(sd,SA_FREECAST) > 0 || skill_id == LG_EXEEDBREAK) )
- status_calc_bl(&sd->bl, SCB_SPEED);
+ status_calc_bl(&sd->bl, SCB_SPEED|SCB_ASPD);
} else
skill->castend_id(ud->skilltimer,tick,src->id,0);
@@ -1741,14 +1738,15 @@ int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, ui
}
}
- unit->stop_walking(src,1);
+ unit->stop_walking(src, STOPWALKING_FLAG_FIXPOS);
// in official this is triggered even if no cast time.
clif->skillcasting(src, src->id, 0, skill_x, skill_y, skill_id, skill->get_ele(skill_id, skill_lv), casttime);
if( casttime > 0 ) {
unit->setdir(src, map->calc_dir(src, skill_x, skill_y));
ud->skilltimer = timer->add( tick+casttime, skill->castend_pos, src->id, 0 );
- if( (sd && pc->checkskill(sd,SA_FREECAST) > 0) || skill_id == LG_EXEEDBREAK)
- status_calc_bl(&sd->bl, SCB_SPEED);
+ if ( (sd && pc->checkskill(sd, SA_FREECAST) > 0) || skill_id == LG_EXEEDBREAK ) {
+ status_calc_bl(&sd->bl, SCB_SPEED|SCB_ASPD);
+ }
} else {
ud->skilltimer = INVALID_TIMER;
skill->castend_pos(ud->skilltimer,tick,src->id,0);
@@ -2129,7 +2127,7 @@ int unit_attack_timer_sub(struct block_list* src, int tid, int64 tick) {
ud->dir = map->calc_dir(src, target->x,target->y );
}
if(ud->walktimer != INVALID_TIMER)
- unit->stop_walking(src,1);
+ unit->stop_walking(src, STOPWALKING_FLAG_FIXPOS);
if(md) {
//First attack is always a normal attack
if(md->state.skillstate == MSS_ANGRY || md->state.skillstate == MSS_BERSERK) {
@@ -2231,7 +2229,7 @@ int unit_skillcastcancel(struct block_list *bl,int type)
ud->skilltimer = INVALID_TIMER;
if( sd && pc->checkskill(sd,SA_FREECAST) > 0 )
- status_calc_bl(&sd->bl, SCB_SPEED);
+ status_calc_bl(&sd->bl, SCB_SPEED|SCB_ASPD);
if( sd ) {
switch( skill_id ) {
@@ -2324,7 +2322,7 @@ int unit_remove_map(struct block_list *bl, clr_type clrtype, const char* file, i
map->freeblock_lock();
if (ud->walktimer != INVALID_TIMER)
- unit->stop_walking(bl,0);
+ unit->stop_walking(bl, STOPWALKING_FLAG_NONE);
if (ud->skilltimer != INVALID_TIMER)
unit->skillcastcancel(bl,0);
@@ -2374,6 +2372,7 @@ int unit_remove_map(struct block_list *bl, clr_type clrtype, const char* file, i
status_change_end(bl, SC__MANHOLE, INVALID_TIMER);
status_change_end(bl, SC_VACUUM_EXTREME, INVALID_TIMER);
status_change_end(bl, SC_CURSEDCIRCLE_ATKER, INVALID_TIMER); //callme before warp
+ status_change_end(bl, SC_NETHERWORLD, INVALID_TIMER);
}
if (bl->type&(BL_CHAR|BL_PET)) {
@@ -2392,18 +2391,18 @@ int unit_remove_map(struct block_list *bl, clr_type clrtype, const char* file, i
}
//Leave/reject all invitations.
if(sd->chatID)
- chat->leave(sd,0);
+ chat->leave(sd, false);
if(sd->trade_partner)
trade->cancel(sd);
buyingstore->close(sd);
searchstore->close(sd);
if( sd->menuskill_id != AL_TELEPORT ) { // issue: 8027
- if(sd->state.storage_flag == 1)
+ if(sd->state.storage_flag == STORAGE_FLAG_NORMAL)
storage->pc_quit(sd,0);
- else if (sd->state.storage_flag == 2)
+ else if (sd->state.storage_flag == STORAGE_FLAG_GUILD)
gstorage->pc_quit(sd,0);
- sd->state.storage_flag = 0; //Force close it when being warped.
+ sd->state.storage_flag = STORAGE_FLAG_CLOSED; //Force close it when being warped.
}
if(sd->party_invite>0)
party->reply_invite(sd,sd->party_invite,0);
diff --git a/src/map/unit.h b/src/map/unit.h
index 881fa16f4..00fff5981 100644
--- a/src/map/unit.h
+++ b/src/map/unit.h
@@ -5,14 +5,27 @@
#ifndef MAP_UNIT_H
#define MAP_UNIT_H
-#include "clif.h" // clr_type
-#include "path.h" // struct walkpath_data
-#include "skill.h" // 'MAX_SKILLTIMERSKILL, struct skill_timerskill, struct skill_unit_group, struct skill_unit_group_tickset
-#include "../common/cbasetypes.h"
+#include "map/clif.h" // clr_type
+#include "map/path.h" // struct walkpath_data
+#include "map/skill.h" // 'MAX_SKILLTIMERSKILL, struct skill_timerskill, struct skill_unit_group, struct skill_unit_group_tickset
+#include "common/cbasetypes.h"
struct map_session_data;
struct block_list;
+/**
+ * Bitmask values usable as a flag in unit_stopwalking
+ */
+enum unit_stopwalking_flag {
+ STOPWALKING_FLAG_NONE = 0x00,
+ STOPWALKING_FLAG_FIXPOS = 0x01, ///< Issue a fixpos packet afterwards
+ STOPWALKING_FLAG_ONESTEP = 0x02, ///< Force the unit to move one cell if it hasn't yet
+ STOPWALKING_FLAG_NEXTCELL = 0x04, ///< Enable moving to the next cell when unit was already half-way there
+ /// (may cause on-touch/place side-effects, such as a scripted map change)
+ STOPWALKING_FLAG_MASK = 0xff, ///< Mask all of the above
+ // Note: Upper bytes are reserved for duration.
+};
+
struct unit_data {
struct block_list *bl;
struct walkpath_data walkpath;
diff --git a/src/map/vending.c b/src/map/vending.c
index 8ae3f36a4..d0f0dee00 100644
--- a/src/map/vending.c
+++ b/src/map/vending.c
@@ -6,24 +6,24 @@
#include "vending.h"
+#include "map/atcommand.h"
+#include "map/battle.h"
+#include "map/chrif.h"
+#include "map/clif.h"
+#include "map/itemdb.h"
+#include "map/log.h"
+#include "map/map.h"
+#include "map/npc.h"
+#include "map/path.h"
+#include "map/pc.h"
+#include "map/skill.h"
+#include "common/nullpo.h"
+#include "common/strlib.h"
+#include "common/utils.h"
+
#include <stdio.h>
#include <string.h>
-#include "atcommand.h"
-#include "battle.h"
-#include "chrif.h"
-#include "clif.h"
-#include "itemdb.h"
-#include "log.h"
-#include "map.h"
-#include "npc.h"
-#include "path.h"
-#include "pc.h"
-#include "skill.h"
-#include "../common/nullpo.h"
-#include "../common/strlib.h"
-#include "../common/utils.h"
-
struct vending_interface vending_s;
/// Returns an unique vending shop id.
@@ -38,7 +38,7 @@ void vending_closevending(struct map_session_data* sd) {
nullpo_retv(sd);
if( sd->state.vending ) {
- sd->state.vending = false;
+ sd->state.vending = 0;
clif->closevendingboard(&sd->bl, 0);
idb_remove(vending->db, sd->status.char_id);
}
diff --git a/src/map/vending.h b/src/map/vending.h
index 00d3eefff..189189227 100644
--- a/src/map/vending.h
+++ b/src/map/vending.h
@@ -5,8 +5,8 @@
#ifndef MAP_VENDING_H
#define MAP_VENDING_H
-#include "../common/cbasetypes.h"
-#include "../common/db.h"
+#include "common/cbasetypes.h"
+#include "common/db.h"
struct map_session_data;
struct s_search_store_search;