summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/char/char.c13
-rw-r--r--src/char/pincode.c4
-rw-r--r--src/common/console.c2
-rw-r--r--src/common/malloc.c2
-rw-r--r--src/common/mapindex.c17
-rw-r--r--src/common/mapindex.h7
-rw-r--r--src/common/mmo.h8
-rw-r--r--src/config/const.h6
-rw-r--r--src/map/atcommand.c58
-rw-r--r--src/map/battle.c100
-rw-r--r--src/map/battle.h1
-rw-r--r--src/map/clif.c274
-rw-r--r--src/map/clif.h8
-rw-r--r--src/map/guild.c20
-rw-r--r--src/map/homunculus.c2
-rw-r--r--src/map/homunculus.h11
-rw-r--r--src/map/irc-bot.c32
-rw-r--r--src/map/itemdb.c5
-rw-r--r--src/map/itemdb.h1
-rw-r--r--src/map/map.c20
-rw-r--r--src/map/mob.c19
-rw-r--r--src/map/mob.h9
-rw-r--r--src/map/npc.c85
-rw-r--r--src/map/npc.h3
-rw-r--r--src/map/pc.c306
-rw-r--r--src/map/pc.h6
-rw-r--r--src/map/pet.c49
-rw-r--r--src/map/pet.h1
-rw-r--r--src/map/script.c78
-rw-r--r--src/map/skill.c59
-rw-r--r--src/map/status.c1027
-rw-r--r--src/map/status.h9
-rw-r--r--src/map/unit.c73
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc32
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc8
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.Hooks.inc224
36 files changed, 1452 insertions, 1127 deletions
diff --git a/src/char/char.c b/src/char/char.c
index d3b18cfa6..b18beed60 100644
--- a/src/char/char.c
+++ b/src/char/char.c
@@ -1216,15 +1216,15 @@ int char_mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_every
p->save_point.map = mapindex->name2id(save_map);
if( p->last_point.map == 0 ) {
- p->last_point.map = (unsigned short)strdb_iget(mapindex->db, MAP_DEFAULT);
- p->last_point.x = MAP_DEFAULT_X;
- p->last_point.y = MAP_DEFAULT_Y;
+ p->last_point.map = (unsigned short)strdb_iget(mapindex->db, mapindex->default_map);
+ p->last_point.x = mapindex->default_x;
+ p->last_point.y = mapindex->default_y;
}
if( p->save_point.map == 0 ) {
- p->save_point.map = (unsigned short)strdb_iget(mapindex->db, MAP_DEFAULT);
- p->save_point.x = MAP_DEFAULT_X;
- p->save_point.y = MAP_DEFAULT_Y;
+ p->save_point.map = (unsigned short)strdb_iget(mapindex->db, mapindex->default_map);
+ p->save_point.x = mapindex->default_x;
+ p->save_point.y = mapindex->default_y;
}
strcat(t_msg, " status");
@@ -5718,6 +5718,7 @@ void do_shutdown(void)
}
void char_hp_symbols(void) {
+ HPM->share(mapindex,"mapindex");
HPM->share(chr, "chr");
HPM->share(geoip, "geoip");
HPM->share(inter_auction, "inter_auction");
diff --git a/src/char/pincode.c b/src/char/pincode.c
index 299079358..a3843ff53 100644
--- a/src/char/pincode.c
+++ b/src/char/pincode.c
@@ -152,9 +152,9 @@ bool pincode_config_read(char *w1, char *w2) {
if ( strcmpi(w1, "pincode_enabled") == 0 ) {
pincode->enabled = atoi(w2);
#if PACKETVER < 20110309
- if( pincode_enabled ) {
+ if( pincode->enabled ) {
ShowWarning("pincode_enabled requires PACKETVER 20110309 or higher. disabling...\n");
- pincode_enabled = 0;
+ pincode->enabled = 0;
}
#endif
} else if ( strcmpi(w1, "pincode_changetime") == 0 ) {
diff --git a/src/common/console.c b/src/common/console.c
index 577d1a3f0..6c5a5c886 100644
--- a/src/common/console.c
+++ b/src/common/console.c
@@ -112,7 +112,9 @@ CPCMD_C(ers_report,server) {
* Displays memory usage
**/
CPCMD_C(mem_report,server) {
+#ifdef USE_MEMMGR
memmgr_report(line?atoi(line):0);
+#endif
}
/**
diff --git a/src/common/malloc.c b/src/common/malloc.c
index 625875b76..244b1114c 100644
--- a/src/common/malloc.c
+++ b/src/common/malloc.c
@@ -822,8 +822,10 @@ void malloc_final (void) {
}
void malloc_init (void) {
+#ifdef USE_MEMMGR
memmgr_usage_bytes_t = 0;
memmgr_usage_bytes = 0;
+#endif
#if defined(DMALLOC) && defined(CYGWIN)
// http://dmalloc.com/docs/latest/online/dmalloc_19.html
dmalloc_debug_setup(getenv("DMALLOC_OPTIONS"));
diff --git a/src/common/mapindex.c b/src/common/mapindex.c
index ec829ee56..0d8a69726 100644
--- a/src/common/mapindex.c
+++ b/src/common/mapindex.c
@@ -165,13 +165,20 @@ int mapindex_init(void) {
}
fclose(fp);
- if( !strdb_iget(mapindex->db, MAP_DEFAULT) ) {
- ShowError("mapindex_init: MAP_DEFAULT '%s' not found in cache! update mapindex.h MAP_DEFAULT var!!!\n",MAP_DEFAULT);
- }
+ mapindex->check_default();
return total;
}
+bool mapindex_check_default(void)
+{
+ if (!strdb_iget(mapindex->db, mapindex->default_map)) {
+ ShowError("mapindex_init: MAP_DEFAULT '%s' not found in cache! update mapindex.h MAP_DEFAULT var!!!\n", mapindex->default_map);
+ return false;
+ }
+ return true;
+}
+
void mapindex_removemap(int index){
strdb_remove(mapindex->db, mapindex->list[index].name);
mapindex->list[index].name[0] = '\0';
@@ -189,6 +196,9 @@ void mapindex_defaults(void) {
/* */
mapindex->db = NULL;
mapindex->num = 0;
+ mapindex->default_map = MAP_DEFAULT;
+ mapindex->default_x = MAP_DEFAULT_X;
+ mapindex->default_y = MAP_DEFAULT_Y;
memset (&mapindex->list, 0, sizeof (mapindex->list));
/* */
@@ -201,4 +211,5 @@ void mapindex_defaults(void) {
mapindex->getmapname_ext = mapindex_getmapname_ext;
mapindex->name2id = mapindex_name2id;
mapindex->id2name = mapindex_id2name_sub;
+ mapindex->check_default = mapindex_check_default;
}
diff --git a/src/common/mapindex.h b/src/common/mapindex.h
index 446a2422d..91bf4562e 100644
--- a/src/common/mapindex.h
+++ b/src/common/mapindex.h
@@ -67,6 +67,12 @@ struct mapindex_interface {
DBMap *db;
/* number of entries in the index table */
int num;
+ /* default map name */
+ char *default_map;
+ /* default x on map */
+ int default_x;
+ /* default y on map */
+ int default_y;
/* index list -- since map server map count is *unlimited* this should be too */
struct {
char name[MAP_NAME_LENGTH];
@@ -84,6 +90,7 @@ struct mapindex_interface {
/* TODO: Hello World! make up your mind, this thing is int on some places and unsigned short on others */
unsigned short (*name2id) (const char*);
const char* (*id2name) (unsigned short,const char *file, int line, const char *func);
+ bool (*check_default) (void);
};
struct mapindex_interface *mapindex;
diff --git a/src/common/mmo.h b/src/common/mmo.h
index fd054ba91..ef42e49c0 100644
--- a/src/common/mmo.h
+++ b/src/common/mmo.h
@@ -376,6 +376,14 @@ struct s_homunculus { //[orn]
int int_;
int dex;
int luk;
+
+ int str_value;
+ int agi_value;
+ int vit_value;
+ int int_value;
+ int dex_value;
+ int luk_value;
+
int8 spiritball; //for homun S [lighta]
};
diff --git a/src/config/const.h b/src/config/const.h
index 2b5b180c4..7b5ed5506 100644
--- a/src/config/const.h
+++ b/src/config/const.h
@@ -52,10 +52,14 @@
#define DEFTYPE_MAX CHAR_MAX
#endif
-/* ATCMD_FUNC(mobinfo) HIT and FLEE calculations */
+/* ATCMD_FUNC(mobinfo) HIT, FLEE, ATK, ATK2, MATK and MATK2 calculations */
#ifdef RENEWAL
#define MOB_FLEE(mobdata) ( (mobdata)->lv + (mobdata)->status.agi + 100 )
#define MOB_HIT(mobdata) ( (mobdata)->lv + (mobdata)->status.dex + 150 )
+ #define MOB_ATK1(mobdata) ( ((mobdata)->lv + (mobdata)->status.str) + (mobdata)->status.rhw.atk * 8 / 10 )
+ #define MOB_ATK2(mobdata) ( ((mobdata)->lv + (mobdata)->status.str) + (mobdata)->status.rhw.atk * 12 / 10 )
+ #define MOB_MATK1(mobdata)( ((mobdata)->lv + (mobdata)->status.int_) + (mobdata)->status.rhw.atk2 * 7 / 10 )
+ #define MOB_MATK2(mobdata)( ((mobdata)->lv + (mobdata)->status.int_) + (mobdata)->status.rhw.atk2 * 13 / 10 )
#define RE_SKILL_REDUCTION() do { \
wd.damage = battle->calc_elefix(src, target, skill_id, skill_lv, battle->calc_cardfix(BF_WEAPON, src, target, nk, s_ele, s_ele_, wd.damage, 0, wd.flag), nk, n_ele, s_ele, s_ele_, false, flag.arrow); \
if( flag.lh ) \
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index 254da5c5b..330fe6284 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -6564,8 +6564,14 @@ ACMD(mobinfo)
monster->status.vit, monster->status.int_, monster->status.dex, monster->status.luk);
clif->message(fd, atcmd_output);
+
+#ifdef RENEWAL
+ sprintf(atcmd_output, msg_txt(1291), // ATK : %d~%d MATK : %d~%d Range : %d~%d~%d Size : %s Race : %s Element : %s(Lv : %d)
+ MOB_ATK1(monster), MOB_ATK2(monster), MOB_MATK1(monster), MOB_MATK2(monster), monster->status.rhw.range,
+#else
sprintf(atcmd_output, msg_txt(1244), // ATK:%d~%d Range:%d~%d~%d Size:%s Race: %s Element: %s (Lv:%d)
monster->status.rhw.atk, monster->status.rhw.atk2, monster->status.rhw.range,
+#endif
monster->range2 , monster->range3, msize[monster->status.size],
mrace[monster->status.race], melement[monster->status.def_ele], monster->status.ele_lv);
clif->message(fd, atcmd_output);
@@ -8609,14 +8615,14 @@ ACMD(join) {
clif->message(fd, atcmd_output);
return false;
}
- if( hChSys.local && strcmpi(name + 1, hChSys.local_name) == 0 ) {
+ if (clif->hChSys->local && strcmpi(name + 1, clif->hChSys->local_name) == 0) {
if( !map->list[sd->bl.m].channel ) {
clif->chsys_mjoin(sd);
if( map->list[sd->bl.m].channel ) /* join might have refused, map has chatting capabilities disabled */
return true;
} else
channel = map->list[sd->bl.m].channel;
- } else if( hChSys.ally && sd->status.guild_id && strcmpi(name + 1, hChSys.ally_name) == 0 ) {
+ } else if (clif->hChSys->ally && sd->status.guild_id && strcmpi(name + 1, clif->hChSys->ally_name) == 0) {
struct guild *g = sd->guild;
if( !g ) return false;/* unlikely, but we wont let it crash anyway. */
channel = g->channel;
@@ -8653,7 +8659,7 @@ ACMD(join) {
return false;
}
- if( !( channel->opt & hChSys_OPT_ANNOUNCE_JOIN ) ) {
+ if (!(channel->opt & hChSys_OPT_ANNOUNCE_JOIN)) {
sprintf(atcmd_output, msg_txt(1403),name); // You're now in the '%s' channel
clif->message(fd, atcmd_output);
}
@@ -8730,11 +8736,11 @@ ACMD(channel) {
sub1[0] = sub2[0] = sub3[0] = '\0';
if (!message || !*message || sscanf(message, "%19s %19s %19s %19s", subcmd, sub1, sub2, sub3) < 1) {
- atcmd_channel_help(fd,command,( hChSys.allow_user_channel_creation || pc_has_permission(sd, PC_PERM_HCHSYS_ADMIN) ));
+ atcmd_channel_help(fd,command, (clif->hChSys->allow_user_channel_creation || pc_has_permission(sd, PC_PERM_HCHSYS_ADMIN)));
return true;
}
- if (strcmpi(subcmd,"create") == 0 && (hChSys.allow_user_channel_creation || pc_has_permission(sd, PC_PERM_HCHSYS_ADMIN))) {
+ if (strcmpi(subcmd,"create") == 0 && (clif->hChSys->allow_user_channel_creation || pc_has_permission(sd, PC_PERM_HCHSYS_ADMIN))) {
// sub1 = channel name; sub2 = password; sub3 = unused
if (sub1[0] != '#') {
clif->message(fd, msg_txt(1405));// Channel name must start with a '#'
@@ -8747,7 +8753,7 @@ ACMD(channel) {
clif->message(fd, msg_txt(1408)); // Channel password may not contain spaces
return false;
}
- if (strcmpi(sub1 + 1,hChSys.local_name) == 0 || strcmpi(sub1 + 1,hChSys.ally_name) == 0 || strdb_exists(clif->channel_db, sub1 + 1)) {
+ if (strcmpi(sub1 + 1, clif->hChSys->local_name) == 0 || strcmpi(sub1 + 1, clif->hChSys->ally_name) == 0 || strdb_exists(clif->channel_db, sub1 + 1)) {
sprintf(atcmd_output, msg_txt(1407), sub1);// Channel '%s' is not available
clif->message(fd, atcmd_output);
return false;
@@ -8769,15 +8775,15 @@ ACMD(channel) {
// sub1 = list type; sub2 = unused; sub3 = unused
if (sub1[0] != '\0' && strcmpi(sub1,"colors") == 0) {
char mout[40];
- for (k = 0; k < hChSys.colors_count; k++) {
+ for (k = 0; k < clif->hChSys->colors_count; k++) {
unsigned short msg_len = 1;
- msg_len += sprintf(mout, "[ %s list colors ] : %s",command,hChSys.colors_name[k]);
+ msg_len += sprintf(mout, "[ %s list colors ] : %s", command, clif->hChSys->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) = hChSys.colors[k];
+ WFIFOL(fd,8) = clif->hChSys->colors[k];
safestrncpy((char*)WFIFOP(fd,12), mout, msg_len);
WFIFOSET(fd, msg_len + 12);
}
@@ -8785,14 +8791,14 @@ ACMD(channel) {
DBIterator *iter = db_iterator(clif->channel_db);
bool show_all = pc_has_permission(sd, PC_PERM_HCHSYS_ADMIN) ? true : false;
clif->message(fd, msg_txt(1410)); // -- Public Channels
- if (hChSys.local) {
- sprintf(atcmd_output, msg_txt(1409), hChSys.local_name, map->list[sd->bl.m].channel ? db_size(map->list[sd->bl.m].channel->users) : 0);// - #%s ( %d users )
+ if (clif->hChSys->local) {
+ sprintf(atcmd_output, msg_txt(1409), clif->hChSys->local_name, map->list[sd->bl.m].channel ? db_size(map->list[sd->bl.m].channel->users) : 0);// - #%s ( %d users )
clif->message(fd, atcmd_output);
}
- if (hChSys.ally && sd->status.guild_id) {
+ if (clif->hChSys->ally && sd->status.guild_id) {
struct guild *g = sd->guild;
if( !g ) { dbi_destroy(iter); return false; }
- sprintf(atcmd_output, msg_txt(1409), hChSys.ally_name, db_size(g->channel->users));// - #%s ( %d users )
+ sprintf(atcmd_output, msg_txt(1409), clif->hChSys->ally_name, db_size(g->channel->users));// - #%s ( %d users )
clif->message(fd, atcmd_output);
}
for (channel = dbi_first(iter); dbi_exists(iter); channel = dbi_next(iter)) {
@@ -8822,17 +8828,17 @@ ACMD(channel) {
return false;
}
- for (k = 0; k < hChSys.colors_count; k++) {
- if (strcmpi(sub2, hChSys.colors_name[k]) == 0)
+ for (k = 0; k < clif->hChSys->colors_count; k++) {
+ if (strcmpi(sub2, clif->hChSys->colors_name[k]) == 0)
break;
}
- if (k == hChSys.colors_count) {
+ if (k == clif->hChSys->colors_count) {
sprintf(atcmd_output, msg_txt(1411), sub2);// Unknown color '%s'
clif->message(fd, atcmd_output);
return false;
}
channel->color = k;
- sprintf(atcmd_output, msg_txt(1413),sub1,hChSys.colors_name[k]);// '%s' channel color updated to '%s'
+ sprintf(atcmd_output, msg_txt(1413), sub1, clif->hChSys->colors_name[k]);// '%s' channel color updated to '%s'
clif->message(fd, atcmd_output);
} else if (strcmpi(subcmd,"leave") == 0) {
// sub1 = channel name; sub2 = unused; sub3 = unused
@@ -9167,7 +9173,7 @@ ACMD(channel) {
}
}
} else {
- atcmd_channel_help(fd,command,( hChSys.allow_user_channel_creation || pc_has_permission(sd, PC_PERM_HCHSYS_ADMIN) ));
+ atcmd_channel_help(fd, command, (clif->hChSys->allow_user_channel_creation || pc_has_permission(sd, PC_PERM_HCHSYS_ADMIN)));
}
return true;
}
@@ -9178,14 +9184,14 @@ ACMD(fontcolor) {
char mout[40];
if( !message || !*message ) {
- for( k = 0; k < hChSys.colors_count; k++ ) {
- msg_len += sprintf(mout, "[ %s ] : %s",command,hChSys.colors_name[k]);
+ for( k = 0; k < clif->hChSys->colors_count; k++ ) {
+ msg_len += sprintf(mout, "[ %s ] : %s", command, clif->hChSys->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) = hChSys.colors[k];
+ WFIFOL(fd,8) = clif->hChSys->colors[k];
safestrncpy((char*)WFIFOP(fd,12), mout, msg_len);
WFIFOSET(fd, msg_len + 12);
}
@@ -9197,24 +9203,24 @@ ACMD(fontcolor) {
return true;
}
- for( k = 0; k < hChSys.colors_count; k++ ) {
- if( strcmpi(message,hChSys.colors_name[k]) == 0 )
+ for( k = 0; k < clif->hChSys->colors_count; k++ ) {
+ if (strcmpi(message, clif->hChSys->colors_name[k]) == 0)
break;
}
- if( k == hChSys.colors_count ) {
+ if( k == clif->hChSys->colors_count ) {
sprintf(atcmd_output, msg_txt(1411), message);// Unknown color '%s'
clif->message(fd, atcmd_output);
return false;
}
sd->fontcolor = k + 1;
- msg_len += sprintf(mout, "Color changed to '%s'",hChSys.colors_name[k]);
+ msg_len += sprintf(mout, "Color changed to '%s'", clif->hChSys->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) = hChSys.colors[k];
+ WFIFOL(fd,8) = clif->hChSys->colors[k];
safestrncpy((char*)WFIFOP(fd,12), mout, msg_len);
WFIFOSET(fd, msg_len + 12);
return true;
diff --git a/src/map/battle.c b/src/map/battle.c
index 9ee4695f7..459af3a81 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -451,6 +451,9 @@ int64 battle_calc_weapon_damage(struct block_list *src, struct block_list *bl, u
eatk = sd->base_status.equip_atk;
}
+ if ( skill_id == TF_POISON )
+ eatk += 15 * skill_lv;
+
if( sc && sc->count ){
if( sc->data[SC_ZENKAI] && watk->ele == sc->data[SC_ZENKAI]->val2 )
eatk += 200;
@@ -506,16 +509,20 @@ int64 battle_calc_base_damage(struct block_list *src, struct block_list *bl, uin
struct status_data *st = status->get_status_data(src);
struct status_change *sc = status->get_sc(src);
- // Property from mild wind bypasses it
- if (sc && sc->data[SC_TK_SEVENWIND])
- batk = battle->calc_elefix(src, bl, skill_id, skill_lv, status->calc_batk(bl, sc, st->batk, false), nk, n_ele, s_ele, s_ele_, false, flag);
- else
- batk = battle->calc_elefix(src, bl, skill_id, skill_lv, status->calc_batk(bl, sc, st->batk, false), nk, n_ele, ELE_NEUTRAL, ELE_NEUTRAL, false, flag);
-
- if( type == EQI_HAND_L )
- damage = batk + 3 * battle->calc_weapon_damage(src, bl, skill_id, skill_lv, &st->lhw, nk, n_ele, s_ele, s_ele_, status_get_size(bl), type, flag, flag2) / 4;
- else
- damage = (batk << 1) + battle->calc_weapon_damage(src, bl, skill_id, skill_lv, &st->rhw, nk, n_ele, s_ele, s_ele_, status_get_size(bl), type, flag, flag2);
+ if (src->type == BL_PC){
+ // Property from mild wind bypasses it
+ if (sc && sc->data[SC_TK_SEVENWIND])
+ batk = battle->calc_elefix(src, bl, skill_id, skill_lv, status->calc_batk(bl, sc, st->batk, false), nk, n_ele, s_ele, s_ele_, false, flag);
+ else
+ batk = battle->calc_elefix(src, bl, skill_id, skill_lv, status->calc_batk(bl, sc, st->batk, false), nk, n_ele, ELE_NEUTRAL, ELE_NEUTRAL, false, flag);
+ if (type == EQI_HAND_L)
+ damage = batk + 3 * battle->calc_weapon_damage(src, bl, skill_id, skill_lv, &st->lhw, nk, n_ele, s_ele, s_ele_, status_get_size(bl), type, flag, flag2) / 4;
+ else
+ damage = (batk << 1) + battle->calc_weapon_damage(src, bl, skill_id, skill_lv, &st->rhw, nk, n_ele, s_ele, s_ele_, status_get_size(bl), type, flag, flag2);
+ }
+ else{
+ damage = st->batk + battle->calc_weapon_damage(src, bl, skill_id, skill_lv, &st->rhw, nk, n_ele, s_ele, s_ele_, status_get_size(bl), type, flag, flag2);
+ }
return damage;
}
@@ -1463,9 +1470,9 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block
break;
case WZ_FIREPILLAR:
if (skill_lv > 10)
- skillratio += 100;
+ skillratio += 2300; //200% MATK each hit
else
- skillratio -= 80;
+ skillratio += -60 + 20*skill_lv; //20% MATK each hit
break;
case WZ_SIGHTRASHER:
skillratio += 20 * skill_lv;
@@ -2824,7 +2831,7 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
//Now damage increasing effects
if( sc->data[SC_LEXAETERNA] && skill_id != PF_SOULBURN
#ifdef RENEWAL
- && skill_id != CR_ACIDDEMONSTRATION && skill_id != ASC_BREAKER
+ && skill_id != CR_ACIDDEMONSTRATION
#endif
)
{
@@ -2910,6 +2917,13 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
if ( sc->data[SC_WATER_BARRIER] )
damage = damage * ( 100 - 20 ) / 100;
+ if( sc->data[SC_FIRE_EXPANSION_SMOKE_POWDER] ) {
+ if( (flag&(BF_SHORT|BF_WEAPON)) == (BF_SHORT|BF_WEAPON) )
+ damage -= 15 * damage / 100;//15% reduction to physical melee attacks
+ else if( (flag&(BF_LONG|BF_WEAPON)) == (BF_LONG|BF_WEAPON) )
+ damage -= 50 * damage / 100;//50% reduction to physical ranged attacks
+ }
+
// Compressed code, fixed by map.h [Epoque]
if (src->type == BL_MOB) {
int i;
@@ -3322,7 +3336,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
struct status_data *sstatus = status->get_status_data(src);
struct status_data *tstatus = status->get_status_data(target);
struct {
- unsigned imdef : 1;
+ unsigned imdef : 2;
unsigned infdef : 1;
} flag;
@@ -3384,11 +3398,10 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
switch(skill_id) {
case MG_FIREWALL:
- case NJ_KAENSIN:
- ad.dmotion = 0; //No flinch animation.
if ( tstatus->def_ele == ELE_FIRE || battle->check_undead(tstatus->race, tstatus->def_ele) )
ad.blewcount = 0; //No knockback
break;
+ case NJ_KAENSIN:
case PR_SANCTUARY:
ad.dmotion = 0; //No flinch animation.
break;
@@ -3407,7 +3420,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
case CR_ACIDDEMONSTRATION:
case ASC_BREAKER:
case HW_MAGICCRASHER:
- flag.imdef = 1;
+ flag.imdef = 2;
break;
#endif
}
@@ -3495,7 +3508,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
}
//Constant/misc additions from skills
if (skill_id == WZ_FIREPILLAR)
- MATK_ADD(50);
+ MATK_ADD(100+50*skill_lv);
if( sd && ( sd->status.class_ == JOB_ARCH_BISHOP_T || sd->status.class_ == JOB_ARCH_BISHOP ) &&
(i=pc->checkskill(sd,AB_EUCHARISTICA)) > 0 &&
(tstatus->race == RC_DEMON || tstatus->def_ele == ELE_DARK) )
@@ -3566,7 +3579,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
flag.imdef = 1;
}
- ad.damage = battle->calc_defense(BF_MAGIC, src, target, skill_id, skill_lv, ad.damage, (flag.imdef?1:0), 0);
+ ad.damage = battle->calc_defense(BF_MAGIC, src, target, skill_id, skill_lv, ad.damage, flag.imdef, 0);
if (skill_id == NPC_EARTHQUAKE) {
//Adds atk2 to the damage, should be influenced by number of hits and skill-ratio, but not mdef reductions. [Skotlex]
@@ -3621,8 +3634,8 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
if (flag.infdef && ad.damage)
ad.damage = ad.damage>0?1:-1;
-
- ad.damage=battle->calc_damage(src,target,&ad,ad.damage,skill_id,skill_lv);
+ if (skill_id != ASC_BREAKER)
+ ad.damage = battle->calc_damage(src, target, &ad, ad.damage, skill_id, skill_lv);
if( map_flag_gvg2(target->m) )
ad.damage=battle->calc_gvg_damage(src,target,ad.damage,ad.div_,skill_id,skill_lv,ad.flag);
else if( map->list[target->m].flag.battleground )
@@ -3848,10 +3861,6 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
ratio >>= 1;
md.damage = (matk + atk) * ratio / 100;
md.damage -= totaldef;
- if( tsc && tsc->data[SC_LEXAETERNA] ) {
- md.damage <<= 1;
- status_change_end(target, SC_LEXAETERNA, INVALID_TIMER);
- }
#endif
}
break;
@@ -5070,8 +5079,6 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
if(sd && (temp=pc->checkskill(sd,BS_WEAPONRESEARCH)) > 0)
ATK_ADD(temp*2);
#endif
- if(skill_id==TF_POISON)
- ATK_ADD(15*skill_lv);
#ifndef RENEWAL
wd.damage = battle->calc_elefix(src, target, skill_id, skill_lv, wd.damage, nk, n_ele, s_ele, s_ele_, false, flag.arrow);
@@ -5239,22 +5246,31 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
if( wd.damage + wd.damage2 ) { //There is a total damage value
int64 damage = wd.damage + wd.damage2;
- if(!wd.damage2) {
- wd.damage = battle->calc_damage(src,target,&wd,wd.damage,skill_id,skill_lv);
+ if (!wd.damage2) {
+#ifdef RENEWAL
+ if (skill_id != ASC_BREAKER)
+#endif
+ wd.damage = battle->calc_damage(src, target, &wd, wd.damage, skill_id, skill_lv);
if( map_flag_gvg2(target->m) )
wd.damage=battle->calc_gvg_damage(src,target,wd.damage,wd.div_,skill_id,skill_lv,wd.flag);
else if( map->list[target->m].flag.battleground )
wd.damage=battle->calc_bg_damage(src,target,wd.damage,wd.div_,skill_id,skill_lv,wd.flag);
- } else if(!wd.damage) {
- wd.damage2 = battle->calc_damage(src,target,&wd,wd.damage2,skill_id,skill_lv);
- if( map_flag_gvg2(target->m) )
- wd.damage2 = battle->calc_gvg_damage(src,target,wd.damage2,wd.div_,skill_id,skill_lv,wd.flag);
- else if( map->list[target->m].flag.battleground )
- wd.damage = battle->calc_bg_damage(src,target,wd.damage2,wd.div_,skill_id,skill_lv,wd.flag);
+ }
+ else if (!wd.damage) {
+#ifdef RENEWAL
+ if (skill_id != ASC_BREAKER)
+#endif
+ wd.damage2 = battle->calc_damage(src, target, &wd, wd.damage2, skill_id, skill_lv);
+ if (map_flag_gvg2(target->m))
+ wd.damage2 = battle->calc_gvg_damage(src, target, wd.damage2, wd.div_, skill_id, skill_lv, wd.flag);
+ else if (map->list[target->m].flag.battleground)
+ wd.damage = battle->calc_bg_damage(src, target, wd.damage2, wd.div_, skill_id, skill_lv, wd.flag);
} else {
#ifdef RENEWAL
- wd.damage = battle->calc_damage(src,target,&wd,wd.damage,skill_id,skill_lv);
- wd.damage2 = battle->calc_damage(src,target,&wd,wd.damage2,skill_id,skill_lv);
+ if( skill_id != ASC_BREAKER ){
+ wd.damage = battle->calc_damage(src, target, &wd, wd.damage, skill_id, skill_lv);
+ wd.damage2 = battle->calc_damage(src, target, &wd, wd.damage2, skill_id, skill_lv);
+ }
#else
int64 d1 = wd.damage + wd.damage2,d2 = wd.damage2;
wd.damage = battle->calc_damage(src,target,&wd,d1,skill_id,skill_lv);
@@ -5682,7 +5698,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) {
- clif->arrow_fail(sd,0);
+ 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
@@ -5699,13 +5718,13 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
case W_GATLING:
case W_SHOTGUN:
if (sd->inventory_data[index]->look != A_BULLET) {
- clif->arrow_fail(sd,0);
+ clif->skill_fail(sd, 0, USESKILL_FAIL_NEED_MORE_BULLET, 0);
return ATK_NONE;
}
break;
case W_GRENADE:
if (sd->inventory_data[index]->look != A_GRENADE) {
- clif->arrow_fail(sd,0);
+ clif->skill_fail(sd, 0, USESKILL_FAIL_NEED_MORE_BULLET, 0);
return ATK_NONE;
}
break;
@@ -6839,6 +6858,7 @@ static const struct battle_data {
{ "guild_castle_expulsion", &battle_config.guild_castle_expulsion, 0, 0, 1, },
{ "song_timer_reset", &battle_config.song_timer_reset, 0, 0, 1, },
{ "snap_dodge", &battle_config.snap_dodge, 0, 0, 1, },
+ { "stormgust_knockback", &battle_config.stormgust_knockback, 1, 0, 1, },
{ "monster_chase_refresh", &battle_config.mob_chase_refresh, 1, 0, 30, },
{ "mob_icewall_walk_block", &battle_config.mob_icewall_walk_block, 75, 0, 255, },
{ "boss_icewall_walk_block", &battle_config.boss_icewall_walk_block, 0, 0, 255, },
diff --git a/src/map/battle.h b/src/map/battle.h
index ad879bd1a..e80e0091d 100644
--- a/src/map/battle.h
+++ b/src/map/battle.h
@@ -482,6 +482,7 @@ struct Battle_Config {
int song_timer_reset; // [csnv]
int snap_dodge; // Enable or disable dodging damage snapping away [csnv]
+ int stormgust_knockback;
int feature_roulette;
};
diff --git a/src/map/clif.c b/src/map/clif.c
index 950898ba5..5194a637a 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -72,6 +72,8 @@ static struct packet_npc_market_open npcmarket_open;
//#define DUMP_UNKNOWN_PACKET
//#define DUMP_INVALID_PACKET
+static struct hChSysConfig clif_hChSys;
+
//Converts item type in case of pet eggs.
static inline int itemtype(int type) {
switch( type ) {
@@ -334,6 +336,11 @@ int clif_send_sub(struct block_list *bl, va_list ap) {
if( clif->ally_only && !sd->sc.data[SC_CLAIRVOYANCE] && !sd->special_state.intravision && battle->check_target( src_bl, &sd->bl, BCT_ENEMY ) > 0 )
return 0;
+ return clif->send_actual(fd, buf, len);
+}
+
+int clif_send_actual(int fd, void *buf, int len)
+{
WFIFOHEAD(fd, len);
if (WFIFOP(fd,0) == buf) {
ShowError("WARNING: Invalid use of clif->send function\n");
@@ -1415,15 +1422,24 @@ void clif_hominfo(struct map_session_data *sd, struct homun_data *hd, int flag)
WBUFW(buf,29)=hd->homunculus.hunger;
WBUFW(buf,31)=(unsigned short) (hd->homunculus.intimacy / 100) ;
WBUFW(buf,33)=0; // equip id
+#ifdef RENEWAL
+ WBUFW(buf, 35) = cap_value(hstatus->rhw.atk2, 0, INT16_MAX);
+#else
WBUFW(buf,35)=cap_value(hstatus->rhw.atk2+hstatus->batk, 0, INT16_MAX);
+#endif
WBUFW(buf,37)=cap_value(hstatus->matk_max, 0, INT16_MAX);
WBUFW(buf,39)=hstatus->hit;
if (battle_config.hom_setting&0x10)
WBUFW(buf,41)=hstatus->luk/3 + 1; //crit is a +1 decimal value! Just display purpose.[Vicious]
else
WBUFW(buf,41)=hstatus->cri/10;
+#ifdef RENEWAL
+ WBUFW(buf, 43) = hstatus->def + hstatus->def2;
+ WBUFW(buf, 45) = hstatus->mdef + hstatus->mdef2;
+#else
WBUFW(buf,43)=hstatus->def + hstatus->vit ;
- WBUFW(buf,45)=hstatus->mdef;
+ WBUFW(buf, 45) = hstatus->mdef;
+#endif
WBUFW(buf,47)=hstatus->flee;
WBUFW(buf,49)=(flag)?0:hstatus->amotion;
if (hstatus->max_hp > INT16_MAX) {
@@ -2674,36 +2690,36 @@ void read_channels_config(void) {
if( !libconfig->setting_lookup_string(settings, "map_local_channel_name", &local_name) )
local_name = "map";
- safestrncpy(hChSys.local_name, local_name, HCHSYS_NAME_LENGTH);
+ safestrncpy(clif->hChSys->local_name, local_name, HCHSYS_NAME_LENGTH);
if( !libconfig->setting_lookup_string(settings, "ally_channel_name", &ally_name) )
ally_name = "ally";
- safestrncpy(hChSys.ally_name, ally_name, HCHSYS_NAME_LENGTH);
+ safestrncpy(clif->hChSys->ally_name, ally_name, HCHSYS_NAME_LENGTH);
if( !libconfig->setting_lookup_string(settings, "irc_channel_name", &irc_name) )
irc_name = "irc";
- safestrncpy(hChSys.irc_name, irc_name, HCHSYS_NAME_LENGTH);
+ safestrncpy(clif->hChSys->irc_name, irc_name, HCHSYS_NAME_LENGTH);
libconfig->setting_lookup_bool(settings, "map_local_channel", &local_enabled);
libconfig->setting_lookup_bool(settings, "ally_channel_enabled", &ally_enabled);
libconfig->setting_lookup_bool(settings, "irc_channel_enabled", &irc_enabled);
- if( local_enabled )
- hChSys.local = true;
- if( ally_enabled )
- hChSys.ally = true;
- if( irc_enabled )
- hChSys.irc = true;
+ if (local_enabled)
+ clif->hChSys->local = true;
+ if (ally_enabled)
+ clif->hChSys->ally = true;
+ if (irc_enabled)
+ clif->hChSys->irc = true;
- hChSys.irc_server[0] = hChSys.irc_channel[0] = hChSys.irc_nick[0] = hChSys.irc_nick_pw[0] = '\0';
+ clif->hChSys->irc_server[0] = clif->hChSys->irc_channel[0] = clif->hChSys->irc_nick[0] = clif->hChSys->irc_nick_pw[0] = '\0';
- if( hChSys.irc ) {
+ if (clif->hChSys->irc) {
const char *irc_server, *irc_channel,
*irc_nick, *irc_nick_pw;
int irc_use_ghost = 0;
if( libconfig->setting_lookup_string(settings, "irc_channel_network", &irc_server) ) {
if( !strstr(irc_server,":") ) {
- hChSys.irc = false;
+ clif->hChSys->irc = false;
ShowWarning("channels.conf : network port wasn't found in 'irc_channel_network', disabling irc channel...\n");
} else {
unsigned char d = 0, dlen = strlen(irc_server);
@@ -2715,36 +2731,36 @@ void read_channels_config(void) {
for(d = 0; d < dlen; d++) {
if(irc_server[d] == ':') {
memcpy(server, irc_server, d);
- safestrncpy(hChSys.irc_server, server, 40);
+ safestrncpy(clif->hChSys->irc_server, server, 40);
memcpy(server, &irc_server[d+1], dlen - d - 1);
- hChSys.irc_server_port = atoi(server);
+ clif->hChSys->irc_server_port = atoi(server);
break;
}
}
}
} else {
- hChSys.irc = false;
+ clif->hChSys->irc = false;
ShowWarning("channels.conf : irc channel enabled but irc_channel_network wasn't found, disabling irc channel...\n");
}
if( libconfig->setting_lookup_string(settings, "irc_channel_channel", &irc_channel) )
- safestrncpy(hChSys.irc_channel, irc_channel, 50);
+ safestrncpy(clif->hChSys->irc_channel, irc_channel, 50);
else {
- hChSys.irc = false;
+ clif->hChSys->irc = false;
ShowWarning("channels.conf : irc channel enabled but irc_channel_channel wasn't found, disabling irc channel...\n");
}
if( libconfig->setting_lookup_string(settings, "irc_channel_nick", &irc_nick) ) {
if( strcmpi(irc_nick,"Hercules_chSysBot") == 0 ) {
- sprintf(hChSys.irc_nick, "Hercules_chSysBot%d",rand()%777);
+ sprintf(clif->hChSys->irc_nick, "Hercules_chSysBot%d",rand()%777);
} else
- safestrncpy(hChSys.irc_nick, irc_nick, 40);
+ safestrncpy(clif->hChSys->irc_nick, irc_nick, 40);
} else {
- hChSys.irc = false;
+ clif->hChSys->irc = false;
ShowWarning("channels.conf : irc channel enabled but irc_channel_nick wasn't found, disabling irc channel...\n");
}
if( libconfig->setting_lookup_string(settings, "irc_channel_nick_pw", &irc_nick_pw) ) {
- safestrncpy(hChSys.irc_nick_pw, irc_nick_pw, 30);
+ safestrncpy(clif->hChSys->irc_nick_pw, irc_nick_pw, 30);
config_setting_lookup_bool(settings, "irc_channel_use_ghost", &irc_use_ghost);
- hChSys.irc_use_ghost = irc_use_ghost;
+ clif->hChSys->irc_use_ghost = irc_use_ghost;
}
}
@@ -2752,83 +2768,83 @@ 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);
- if( local_autojoin )
- hChSys.local_autojoin = true;
- if( ally_autojoin )
- hChSys.ally_autojoin = true;
+ if (local_autojoin)
+ clif->hChSys->local_autojoin = true;
+ if (ally_autojoin)
+ clif->hChSys->ally_autojoin = true;
libconfig->setting_lookup_bool(settings, "allow_user_channel_creation", &allow_user_channel_creation);
if( allow_user_channel_creation )
- hChSys.allow_user_channel_creation = true;
+ clif->hChSys->allow_user_channel_creation = true;
if( (colors = libconfig->setting_get_member(settings, "colors")) != NULL ) {
int color_count = libconfig->setting_length(colors);
- CREATE( hChSys.colors, unsigned int, color_count );
- CREATE( hChSys.colors_name, char *, color_count );
+ CREATE(clif->hChSys->colors, unsigned int, color_count);
+ CREATE(clif->hChSys->colors_name, char *, color_count);
for(i = 0; i < color_count; i++) {
config_setting_t *color = libconfig->setting_get_elem(colors, i);
- CREATE( hChSys.colors_name[i], char, HCHSYS_NAME_LENGTH );
+ CREATE(clif->hChSys->colors_name[i], char, HCHSYS_NAME_LENGTH);
- safestrncpy(hChSys.colors_name[i], config_setting_name(color), HCHSYS_NAME_LENGTH);
+ safestrncpy(clif->hChSys->colors_name[i], config_setting_name(color), HCHSYS_NAME_LENGTH);
- hChSys.colors[i] = (unsigned int)strtoul(libconfig->setting_get_string_elem(colors,i),NULL,0);
- hChSys.colors[i] = (hChSys.colors[i] & 0x0000FF) << 16 | (hChSys.colors[i] & 0x00FF00) | (hChSys.colors[i] & 0xFF0000) >> 16;//RGB to BGR
+ clif->hChSys->colors[i] = (unsigned int)strtoul(libconfig->setting_get_string_elem(colors,i),NULL,0);
+ clif->hChSys->colors[i] = (clif->hChSys->colors[i] & 0x0000FF) << 16 | (clif->hChSys->colors[i] & 0x00FF00) | (clif->hChSys->colors[i] & 0xFF0000) >> 16;//RGB to BGR
}
- hChSys.colors_count = color_count;
+ clif->hChSys->colors_count = color_count;
}
libconfig->setting_lookup_string(settings, "map_local_channel_color", &local_color);
- for (k = 0; k < hChSys.colors_count; k++) {
- if( strcmpi(hChSys.colors_name[k],local_color) == 0 )
+ for (k = 0; k < clif->hChSys->colors_count; k++) {
+ if (strcmpi(clif->hChSys->colors_name[k], local_color) == 0)
break;
}
- if( k < hChSys.colors_count ) {
- hChSys.local_color = k;
+ if (k < clif->hChSys->colors_count) {
+ clif->hChSys->local_color = k;
} else {
ShowError("channels.conf: unknown color '%s' for 'map_local_channel_color', disabling '#%s'...\n",local_color,local_name);
- hChSys.local = false;
+ clif->hChSys->local = false;
}
libconfig->setting_lookup_string(settings, "ally_channel_color", &ally_color);
- for (k = 0; k < hChSys.colors_count; k++) {
- if( strcmpi(hChSys.colors_name[k],ally_color) == 0 )
+ for (k = 0; k < clif->hChSys->colors_count; k++) {
+ if (strcmpi(clif->hChSys->colors_name[k], ally_color) == 0)
break;
}
- if( k < hChSys.colors_count ) {
- hChSys.ally_color = k;
+ if( k < clif->hChSys->colors_count ) {
+ clif->hChSys->ally_color = k;
} else {
ShowError("channels.conf: unknown color '%s' for 'ally_channel_color', disabling '#%s'...\n",ally_color,ally_name);
- hChSys.ally = false;
+ clif->hChSys->ally = false;
}
libconfig->setting_lookup_string(settings, "irc_channel_color", &irc_color);
- for (k = 0; k < hChSys.colors_count; k++) {
- if( strcmpi(hChSys.colors_name[k],irc_color) == 0 )
+ for (k = 0; k < clif->hChSys->colors_count; k++) {
+ if (strcmpi(clif->hChSys->colors_name[k], irc_color) == 0)
break;
}
- if( k < hChSys.colors_count ) {
- hChSys.irc_color = k;
+ if (k < clif->hChSys->colors_count) {
+ clif->hChSys->irc_color = k;
} else {
ShowError("channels.conf: unknown color '%s' for 'irc_channel_color', disabling '#%s'...\n",irc_color,irc_name);
- hChSys.irc = false;
+ clif->hChSys->irc = false;
}
- if( hChSys.irc ) {
+ if (clif->hChSys->irc) {
struct hChSysCh *chd;
- CREATE( chd, struct hChSysCh, 1 );
+ CREATE(chd, struct hChSysCh, 1);
- safestrncpy(chd->name, hChSys.irc_name, HCHSYS_NAME_LENGTH);
+ safestrncpy(chd->name, clif->hChSys->irc_name, HCHSYS_NAME_LENGTH);
chd->type = hChSys_IRC;
- clif->chsys_create(chd,NULL,NULL,hChSys.irc_color);
+ clif->chsys_create(chd, NULL, NULL, clif->hChSys->irc_color);
ircbot->channel = chd;
}
@@ -2841,15 +2857,15 @@ void read_channels_config(void) {
const char *color = libconfig->setting_get_string_elem(channels,i);
struct hChSysCh *chd;
- for (k = 0; k < hChSys.colors_count; k++) {
- if( strcmpi(hChSys.colors_name[k],color) == 0 )
+ for (k = 0; k < clif->hChSys->colors_count; k++) {
+ if (strcmpi(clif->hChSys->colors_name[k],color) == 0)
break;
}
- if( k == hChSys.colors_count ) {
+ if( k == clif->hChSys->colors_count) {
ShowError("channels.conf: unknown color '%s' for channel '%s', skipping channel...\n",color,name);
continue;
}
- if( strcmpi(name,hChSys.local_name) == 0 || strcmpi(name,hChSys.ally_name) == 0 || strcmpi(name,hChSys.irc_name) == 0 || strdb_exists(clif->channel_db, name) ) {
+ if( strcmpi(name, clif->hChSys->local_name) == 0 || strcmpi(name, clif->hChSys->ally_name) == 0 || strcmpi(name, clif->hChSys->irc_name) == 0 || strdb_exists(clif->channel_db, name) ) {
ShowError("channels.conf: duplicate channel '%s', skipping channel...\n",name);
continue;
@@ -3179,17 +3195,14 @@ void clif_changestatus(struct map_session_data* sd,int type,int val)
clif->send(buf,packet_len(0x1ab),&sd->bl,AREA_WOS);
}
-
/// Updates sprite/style properties of an object.
-/// 00c3 <id>.L <type>.B <value>.B (ZC_SPRITE_CHANGE)
-/// 01d7 <id>.L <type>.B <value>.L (ZC_SPRITE_CHANGE2)
void clif_changelook(struct block_list *bl,int type,int val)
{
- unsigned char buf[16];
struct map_session_data* sd;
struct status_change* sc;
struct view_data* vd;
enum send_target target = AREA;
+ int val2 = 0;
nullpo_retv(bl);
sd = BL_CAST(BL_PC, bl);
@@ -3297,56 +3310,32 @@ void clif_changelook(struct block_list *bl,int type,int val)
// prevent leaking the presence of GM-hidden objects
if( sc && sc->option&OPTION_INVISIBLE && !disguised(bl) )
target = SELF;
-
#if PACKETVER < 4
- WBUFW(buf,0)=0xc3;
- WBUFL(buf,2)=bl->id;
- WBUFB(buf,6)=type;
- WBUFB(buf,7)=val;
- clif->send(buf,packet_len(0xc3),bl,target);
+ clif->sendlook(bl, bl->id, type, val, 0, target);
#else
- WBUFW(buf,0)=0x1d7;
- WBUFL(buf,2)=bl->id;
if(type == LOOK_WEAPON || type == LOOK_SHIELD) {
nullpo_retv(vd);
- WBUFB(buf,6)=LOOK_WEAPON;
- WBUFW(buf,7)=vd->weapon;
- WBUFW(buf,9)=vd->shield;
- } else {
- WBUFB(buf,6)=type;
- WBUFL(buf,7)=val;
+ type = LOOK_WEAPON;
+ val = vd->weapon;
+ val2 = vd->shield;
}
if( disguised(bl) ) {
- clif->send(buf,packet_len(0x1d7),bl,AREA_WOS);
- WBUFL(buf,2)=-bl->id;
- clif->send(buf,packet_len(0x1d7),bl,SELF);
+ clif->sendlook(bl, bl->id, type, val, val2, AREA_WOS);
+ clif->sendlook(bl, -bl->id, type, val, val2, SELF);
} else
- clif->send(buf,packet_len(0x1d7),bl,target);
+ clif->sendlook(bl, bl->id, type, val, val2, target);
#endif
}
//Sends a change-base-look packet required for traps as they are triggered.
void clif_changetraplook(struct block_list *bl,int val)
{
- unsigned char buf[32];
-#if PACKETVER < 4
- WBUFW(buf,0)=0xc3;
- WBUFL(buf,2)=bl->id;
- WBUFB(buf,6)=LOOK_BASE;
- WBUFB(buf,7)=val;
- clif->send(buf,packet_len(0xc3),bl,AREA);
-#else
- WBUFW(buf,0)=0x1d7;
- WBUFL(buf,2)=bl->id;
- WBUFB(buf,6)=LOOK_BASE;
- WBUFW(buf,7)=val;
- WBUFW(buf,9)=0;
- clif->send(buf,packet_len(0x1d7),bl,AREA);
-#endif
+ clif->sendlook(bl, bl->id, LOOK_BASE, val, 0, AREA);
}
-//For the stupid cloth-dye bug. Resends the given view data to the area specified by bl.
-void clif_refreshlook(struct block_list *bl,int id,int type,int val,enum send_target target)
+/// 00c3 <id>.L <type>.B <value>.B (ZC_SPRITE_CHANGE)
+/// 01d7 <id>.L <type>.B <value>.L (ZC_SPRITE_CHANGE2)
+void clif_sendlook(struct block_list *bl, int id, int type, int val, int val2, enum send_target target)
{
unsigned char buf[32];
#if PACKETVER < 4
@@ -3360,11 +3349,17 @@ void clif_refreshlook(struct block_list *bl,int id,int type,int val,enum send_ta
WBUFL(buf,2)=id;
WBUFB(buf,6)=type;
WBUFW(buf,7)=val;
- WBUFW(buf,9)=0;
+ WBUFW(buf,9)=val2;
clif->send(buf,packet_len(0x1d7),bl,target);
#endif
}
+//For the stupid cloth-dye bug. Resends the given view data to the area specified by bl.
+void clif_refreshlook(struct block_list *bl,int id,int type,int val,enum send_target target)
+{
+ clif->sendlook(bl, id, type, val, 0, target);
+}
+
/// Character status (ZC_STATUS).
/// 00bd <stpoint>.W <str>.B <need str>.B <agi>.B <need agi>.B <vit>.B <need vit>.B
@@ -9140,7 +9135,7 @@ void clif_hercules_chsys_msg(struct hChSysCh *channel, struct map_session_data *
WFIFOW(sd->fd,0) = 0x2C1;
WFIFOW(sd->fd,2) = msg_len + 12;
WFIFOL(sd->fd,4) = 0;
- WFIFOL(sd->fd,8) = hChSys.colors[channel->color];
+ WFIFOL(sd->fd,8) = clif->hChSys->colors[channel->color];
safestrncpy((char*)WFIFOP(sd->fd,12), msg, msg_len);
for( user = dbi_first(iter); dbi_exists(iter); user = dbi_next(iter) ) {
@@ -9165,7 +9160,7 @@ void clif_hercules_chsys_msg2(struct hChSysCh *channel, char *msg) {
WBUFW(buf,0) = 0x2C1;
WBUFW(buf,2) = msg_len + 12;
WBUFL(buf,4) = 0;
- WBUFL(buf,8) = hChSys.colors[channel->color];
+ WBUFL(buf,8) = clif->hChSys->colors[channel->color];
safestrncpy((char*)WBUFP(buf,12), msg, msg_len);
for( user = dbi_first(iter); dbi_exists(iter); user = dbi_next(iter) ) {
@@ -9266,11 +9261,11 @@ void clif_hercules_chsys_mjoin(struct map_session_data *sd) {
return;
CREATE(map->list[sd->bl.m].channel, struct hChSysCh , 1);
- safestrncpy(map->list[sd->bl.m].channel->name, hChSys.local_name, HCHSYS_NAME_LENGTH);
+ safestrncpy(map->list[sd->bl.m].channel->name, clif->hChSys->local_name, HCHSYS_NAME_LENGTH);
map->list[sd->bl.m].channel->type = hChSys_MAP;
map->list[sd->bl.m].channel->m = sd->bl.m;
- clif->chsys_create(map->list[sd->bl.m].channel,NULL,NULL,hChSys.local_color);
+ clif->chsys_create(map->list[sd->bl.m].channel, NULL, NULL, clif->hChSys->local_color);
}
if( map->list[sd->bl.m].channel->banned && idb_exists(map->list[sd->bl.m].channel->banned, sd->status.account_id) ) {
@@ -9281,7 +9276,7 @@ void clif_hercules_chsys_mjoin(struct map_session_data *sd) {
if( !( map->list[sd->bl.m].channel->opt & hChSys_OPT_ANNOUNCE_JOIN ) ) {
char mout[60];
- sprintf(mout, msg_txt(1435),hChSys.local_name,map->list[sd->bl.m].name); // You're now in the '#%s' channel for '%s'
+ sprintf(mout, msg_txt(1435), clif->hChSys->local_name, map->list[sd->bl.m].name); // You're now in the '#%s' channel for '%s'
clif->colormes(sd->fd, COLOR_DEFAULT, mout);
}
}
@@ -9556,7 +9551,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) {
status_calc_pc(sd, SCO_NONE);/* some conditions are map-dependent so we must recalculate */
sd->state.changemap = false;
- if( hChSys.local && hChSys.local_autojoin ) {
+ if (clif->hChSys->local && clif->hChSys->local_autojoin) {
clif->chsys_mjoin(sd);
}
}
@@ -9959,7 +9954,7 @@ void clif_parse_GlobalMessage(int fd, struct map_session_data* sd)
WFIFOW(fd,0) = 0x2C1;
WFIFOW(fd,2) = mylen + 12;
WFIFOL(fd,4) = sd->bl.id;
- WFIFOL(fd,8) = hChSys.colors[sd->fontcolor - 1];
+ WFIFOL(fd,8) = clif->hChSys->colors[sd->fontcolor - 1];
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;
@@ -10236,7 +10231,7 @@ void clif_hercules_chsys_left(struct hChSysCh *channel, struct map_session_data
if( !db_size(channel->users) && channel->type == hChSys_PRIVATE ) {
clif->chsys_delete(channel);
- } else if( !hChSys.closing && (channel->opt & hChSys_OPT_ANNOUNCE_JOIN) ) {
+ } else if( !clif->hChSys->closing && (channel->opt & hChSys_OPT_ANNOUNCE_JOIN) ) {
char message[60];
sprintf(message, "#%s '%s' left",channel->name,sd->status.name);
clif->chsys_msg(channel,sd,message);
@@ -10280,9 +10275,9 @@ void clif_hercules_chsys_quitg(struct map_session_data *sd) {
if( channel == sd->gcbind )
sd->gcbind = NULL;
- if( !db_size(channel->users) && channel->type == hChSys_PRIVATE ) {
+ if (!db_size(channel->users) && channel->type == hChSys_PRIVATE) {
clif->chsys_delete(channel);
- } else if( !hChSys.closing && (channel->opt & hChSys_OPT_ANNOUNCE_JOIN) ) {
+ } else if (!clif->hChSys->closing && (channel->opt & hChSys_OPT_ANNOUNCE_JOIN)) {
char message[60];
sprintf(message, "#%s '%s' left",channel->name,sd->status.name);
clif->chsys_msg(channel,sd,message);
@@ -10321,9 +10316,9 @@ void clif_hercules_chsys_quit(struct map_session_data *sd) {
if( channel == sd->gcbind )
sd->gcbind = NULL;
- if( !db_size(channel->users) && channel->type == hChSys_PRIVATE ) {
+ if (!db_size(channel->users) && channel->type == hChSys_PRIVATE) {
clif->chsys_delete(channel);
- } else if( !hChSys.closing && (channel->opt & hChSys_OPT_ANNOUNCE_JOIN) ) {
+ } else if (!clif->hChSys->closing && (channel->opt & hChSys_OPT_ANNOUNCE_JOIN)) {
char message[60];
sprintf(message, "#%s '%s' left",channel->name,sd->status.name);
clif->chsys_msg(channel,sd,message);
@@ -10462,12 +10457,12 @@ void clif_parse_WisMessage(int fd, struct map_session_data* sd)
chname++;
- if( hChSys.local && strcmpi(chname, hChSys.local_name) == 0 ) {
+ if (clif->hChSys->local && strcmpi(chname, clif->hChSys->local_name) == 0) {
if( !map->list[sd->bl.m].channel ) {
clif->chsys_mjoin(sd);
}
channel = map->list[sd->bl.m].channel;
- } else if( hChSys.ally && sd->status.guild_id && strcmpi(chname, hChSys.ally_name) == 0 ) {
+ } else if (clif->hChSys->ally && sd->status.guild_id && strcmpi(chname, clif->hChSys->ally_name) == 0) {
struct guild *g = sd->guild;
if( !g ) return;
channel = g->channel;
@@ -10718,7 +10713,7 @@ void clif_parse_EquipItem(int fd,struct map_session_data *sd) {
}
void clif_hercules_chsys_delete(struct hChSysCh *channel) {
- if( db_size(channel->users) && !hChSys.closing ) {
+ if (db_size(channel->users) && !clif->hChSys->closing) {
DBIterator *iter;
struct map_session_data *sd;
unsigned char i;
@@ -10758,7 +10753,7 @@ void clif_hercules_chsys_delete(struct hChSysCh *channel) {
aFree(channel);
} else if ( channel->type == hChSys_ALLY )
aFree(channel);
- else if( !hChSys.closing )
+ else if (!clif->hChSys->closing)
strdb_remove(clif->channel_db, channel->name);
}
void clif_hercules_chsys_gjoin(struct guild *g1,struct guild *g2) {
@@ -11274,15 +11269,23 @@ void clif_parse_UseSkillToId_homun(struct homun_data *hd, struct map_session_dat
if( !hd )
return;
- if( skill->not_ok_hom(skill_id, hd) )
+ if (skill->not_ok_hom(skill_id, hd)){
+ clif->emotion(&hd->bl, E_DOTS);
return;
- if( hd->bl.id != target_id && skill->get_inf(skill_id)&INF_SELF_SKILL )
+ }
+ if (hd->bl.id != target_id && skill->get_inf(skill_id)&INF_SELF_SKILL)
target_id = hd->bl.id;
- if( hd->ud.skilltimer != INVALID_TIMER ) {
- if( skill_id != SA_CASTCANCEL && skill_id != SO_SPELLFIST ) return;
- } else if( DIFF_TICK(tick, hd->ud.canact_tick) < 0 )
+ if (hd->ud.skilltimer != INVALID_TIMER) {
+ if (skill_id != SA_CASTCANCEL && skill_id != SO_SPELLFIST) return;
+ }
+ else if (DIFF_TICK(tick, hd->ud.canact_tick) < 0){
+ clif->emotion(&hd->bl, E_DOTS);
+ if (hd->master)
+ clif->skill_fail(hd->master, skill_id, USESKILL_FAIL_SKILLINTERVAL, 0);
return;
+ }
+
lv = homun->checkskill(hd, skill_id);
if( skill_lv > lv )
skill_lv = lv;
@@ -11294,12 +11297,19 @@ void clif_parse_UseSkillToPos_homun(struct homun_data *hd, struct map_session_da
int lv;
if( !hd )
return;
- if( skill->not_ok_hom(skill_id, hd) )
+ if (skill->not_ok_hom(skill_id, hd)){
+ clif->emotion(&hd->bl, E_DOTS);
return;
- if( hd->ud.skilltimer != INVALID_TIMER ) {
- if( skill_id != SA_CASTCANCEL && skill_id != SO_SPELLFIST ) return;
- } else if( DIFF_TICK(tick, hd->ud.canact_tick) < 0 )
+ }
+ if ( hd->ud.skilltimer != INVALID_TIMER ) {
+ if ( skill_id != SA_CASTCANCEL && skill_id != SO_SPELLFIST ) return;
+
+ } else if ( DIFF_TICK(tick, hd->ud.canact_tick) < 0 ) {
+ clif->emotion(&hd->bl, E_DOTS);
+ if ( hd->master )
+ clif->skill_fail(hd->master, skill_id, USESKILL_FAIL_SKILLINTERVAL, 0);
return;
+ }
if( hd->sc.data[SC_BASILICA] )
return;
@@ -17739,13 +17749,14 @@ void clif_parse_CashShopReqTab(int fd, struct map_session_data *sd) {
void clif_maptypeproperty2(struct block_list *bl,enum send_target t) {
#if PACKETVER >= 20121010
struct packet_maptypeproperty2 p;
+ struct map_session_data *sd = BL_CAST(BL_PC, bl);
p.PacketType = maptypeproperty2Type;
p.type = 0x28;
p.flag.party = map->list[bl->m].flag.pvp ? 1 : 0;
p.flag.guild = (map->list[bl->m].flag.battleground || map_flag_gvg(bl->m)) ? 1 : 0;
p.flag.siege = (map->list[bl->m].flag.battleground || map_flag_gvg2(bl->m)) ? 1: 0;
- p.flag.mineffect = map_flag_gvg(bl->m); // FIXME/CHECKME Forcing /mineffect in castles during WoE (probably redundant? I'm not sure)
+ p.flag.mineffect = map_flag_gvg(bl->m) ? 1 : ( (sd && sd->state.lesseffect) ? 1 : 0); // Forcing /mineffect in castles during WoE (probably redundant? I'm not sure)
p.flag.nolockon = 0; // TODO
p.flag.countpk = map->list[bl->m].flag.pvp ? 1 : 0;
p.flag.nopartyformation = map->list[bl->m].flag.partylock ? 1 : 0;
@@ -18865,7 +18876,7 @@ int do_init_clif(bool minimal) {
clif->delayed_damage_ers = ers_new(sizeof(struct cdelayed_damage),"clif.c::delayed_damage_ers",ERS_OPT_CLEAR);
clif->channel_db = stridb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, HCHSYS_NAME_LENGTH);
- hChSys.ally = hChSys.local = hChSys.irc = hChSys.ally_autojoin = hChSys.local_autojoin = false;
+ clif->hChSys->ally = clif->hChSys->local = clif->hChSys->irc = clif->hChSys->ally_autojoin = clif->hChSys->local_autojoin = false;
clif->chann_config_read();
return 0;
@@ -18882,13 +18893,13 @@ void do_final_clif(void) {
dbi_destroy(iter);
- for(i = 0; i < hChSys.colors_count; i++) {
- aFree(hChSys.colors_name[i]);
+ for(i = 0; i < clif->hChSys->colors_count; i++) {
+ aFree(clif->hChSys->colors_name[i]);
}
- if( hChSys.colors_count ) {
- aFree(hChSys.colors_name);
- aFree(hChSys.colors);
+ if (clif->hChSys->colors_count) {
+ aFree(clif->hChSys->colors_name);
+ aFree(clif->hChSys->colors);
}
db_destroy(clif->channel_db);
@@ -18927,6 +18938,7 @@ void clif_defaults(void) {
clif->refresh_ip = clif_refresh_ip;
clif->send = clif_send;
clif->send_sub = clif_send_sub;
+ clif->send_actual = clif_send_actual;
clif->parse = clif_parse;
clif->parse_cmd = clif_parse_cmd_optional;
clif->decrypt_cmd = clif_decrypt_cmd;
@@ -18971,6 +18983,7 @@ void clif_defaults(void) {
clif->changelook = clif_changelook;
clif->changetraplook = clif_changetraplook;
clif->refreshlook = clif_refreshlook;
+ clif->sendlook = clif_sendlook;
clif->class_change = clif_class_change;
clif->skill_delunit = clif_skill_delunit;
clif->skillunit_update = clif_skillunit_update;
@@ -19385,6 +19398,7 @@ void clif_defaults(void) {
clif->bc_ready = clif_bc_ready;
clif->undisguise_timer = clif_undisguise_timer;
/* Hercules Channel System */
+ clif->hChSys = &clif_hChSys;
clif->chsys_create = clif_hercules_chsys_create;
clif->chsys_msg = clif_hercules_chsys_msg;
clif->chsys_msg2 = clif_hercules_chsys_msg2;
diff --git a/src/map/clif.h b/src/map/clif.h
index ccaedabcb..4d11fc281 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -340,6 +340,7 @@ typedef enum useskill_fail_cause { // clif_skill_fail
USESKILL_FAIL_STYLE_CHANGE_FIGHTER = 81,
USESKILL_FAIL_STYLE_CHANGE_GRAPPLER = 82,
USESKILL_FAIL_THERE_ARE_NPC_AROUND = 83,
+ USESKILL_FAIL_NEED_MORE_BULLET = 84,
}useskill_fail_cause;
enum clif_messages {
@@ -517,7 +518,7 @@ struct s_packet_db {
short pos[MAX_PACKET_POS];
};
-struct {
+struct hChSysConfig {
unsigned int *colors;
char **colors_name;
unsigned char colors_count;
@@ -530,7 +531,7 @@ struct {
char irc_server[40], irc_channel[50], irc_nick[40], irc_nick_pw[30];
unsigned short irc_server_port;
bool irc_use_ghost;
-} hChSys;
+};
struct hChSysBanEntry {
char name[NAME_LENGTH];
@@ -576,6 +577,7 @@ struct clif_interface {
char map_ip_str[128];
int map_fd;
DBMap* channel_db;
+ struct hChSysConfig *hChSys;
/* for clif_clearunit_delayed */
struct eri *delay_clearunit_ers;
/* Cash Shop [Ind/Hercules] */
@@ -604,6 +606,7 @@ struct clif_interface {
uint32 (*refresh_ip) (void);
bool (*send) (const void* buf, int len, struct block_list* bl, enum send_target type);
int (*send_sub) (struct block_list *bl, va_list ap);
+ int (*send_actual) (int fd, void *buf, int len);
int (*parse) (int fd);
unsigned short (*parse_cmd) ( int fd, struct map_session_data *sd );
unsigned short (*decrypt_cmd) ( int cmd, struct map_session_data *sd );
@@ -648,6 +651,7 @@ struct clif_interface {
void (*changelook) (struct block_list *bl,int type,int val);
void (*changetraplook) (struct block_list *bl,int val);
void (*refreshlook) (struct block_list *bl,int id,int type,int val,enum send_target target);
+ void (*sendlook) (struct block_list *bl, int id, int type, int val, int val2, enum send_target target);
void (*class_change) (struct block_list *bl,int class_,int type);
void (*skill_delunit) (struct skill_unit *su);
void (*skillunit_update) (struct block_list* bl);
diff --git a/src/map/guild.c b/src/map/guild.c
index e43a5881e..d46da60a3 100644
--- a/src/map/guild.c
+++ b/src/map/guild.c
@@ -470,15 +470,15 @@ int guild_recv_info(struct guild *sg) {
g->instance = NULL;
g->instances = 0;
idb_put(guild->db,sg->guild_id,g);
- if( hChSys.ally ) {
+ if (clif->hChSys->ally) {
struct hChSysCh *channel;
-
+
CREATE(channel, struct hChSysCh , 1);
- safestrncpy(channel->name, hChSys.ally_name, HCHSYS_NAME_LENGTH);
+ safestrncpy(channel->name, clif->hChSys->ally_name, HCHSYS_NAME_LENGTH);
channel->type = hChSys_ALLY;
- clif->chsys_create(channel,NULL,NULL,hChSys.ally_color);
- if( hChSys.ally_autojoin ) {
+ clif->chsys_create(channel, NULL, NULL, clif->hChSys->ally_color);
+ if (clif->hChSys->ally_autojoin) {
struct s_mapiterator* iter = mapit_getallusers();
struct guild *tg[MAX_GUILDALLIANCE];
@@ -745,7 +745,7 @@ void guild_member_joined(struct map_session_data *sd)
g->member[i].sd = sd;
sd->guild = g;
- if( hChSys.ally && hChSys.ally_autojoin ) {
+ if (clif->hChSys->ally && clif->hChSys->ally_autojoin) {
struct guild* sg = NULL;
struct hChSysCh *channel = g->channel;
@@ -913,7 +913,7 @@ int guild_member_withdraw(int guild_id, int account_id, int char_id, int flag, c
if (sd->state.storage_flag == 2) //Close the guild storage.
gstorage->close(sd);
guild->send_dot_remove(sd);
- if( hChSys.ally ) {
+ if (clif->hChSys->ally) {
clif->chsys_quitg(sd);
}
sd->status.guild_id = 0;
@@ -1646,9 +1646,9 @@ int guild_allianceack(int guild_id1,int guild_id2,int account_id1,int account_id
return 0;
}
- if( g[0] && g[1] && hChSys.ally && ( flag & 1 ) == 0 ) {
+ if (g[0] && g[1] && clif->hChSys->ally && ( flag & 1 ) == 0) {
if( !(flag & 0x08) ) {
- if( hChSys.ally_autojoin )
+ if (clif->hChSys->ally_autojoin)
clif->chsys_gjoin(g[0],g[1]);
} else {
clif->chsys_gleave(g[0],g[1]);
@@ -1777,7 +1777,7 @@ int guild_broken(int guild_id,int flag)
guild->db->foreach(guild->db,guild->broken_sub,guild_id);
guild->castle_db->foreach(guild->castle_db,guild->castle_broken_sub,guild_id);
gstorage->delete(guild_id);
- if( hChSys.ally ) {
+ if (clif->hChSys->ally) {
if( g->channel != NULL ) {
clif->chsys_delete(g->channel);
}
diff --git a/src/map/homunculus.c b/src/map/homunculus.c
index e45f654ff..1d226749b 100644
--- a/src/map/homunculus.c
+++ b/src/map/homunculus.c
@@ -347,6 +347,8 @@ bool homunculus_levelup(struct homun_data *hd) {
hom->int_+= growth_int;
hom->luk += growth_luk;
+ APPLY_HOMUN_LEVEL_STATWEIGHT();
+
if ( battle_config.homunculus_show_growth ) {
char output[256] ;
sprintf(output,
diff --git a/src/map/homunculus.h b/src/map/homunculus.h
index 263922e4e..5b1fd2031 100644
--- a/src/map/homunculus.h
+++ b/src/map/homunculus.h
@@ -14,6 +14,17 @@
#define homdb_checkid(id) ((id) >= HM_CLASS_BASE && (id) <= HM_CLASS_MAX)
#define homun_alive(x) ((x) && (x)->homunculus.vaporize == HOM_ST_ACTIVE && (x)->battle_status.hp > 0)
+#ifdef RENEWAL
+#define HOMUN_LEVEL_STATWEIGHT_VALUE 0
+#define APPLY_HOMUN_LEVEL_STATWEIGHT()( \
+ hom->str_value = hom->agi_value = \
+ hom->vit_value = hom->int_value = \
+ hom->dex_value = hom->luk_value = hom->level / 10 - HOMUN_LEVEL_STATWEIGHT_VALUE \
+ )
+#else
+#define APPLY_HOMUN_LEVEL_STATWEIGHT()
+#endif
+
struct h_stats {
unsigned int HP, SP;
unsigned short str, agi, vit, int_, dex, luk;
diff --git a/src/map/irc-bot.c b/src/map/irc-bot.c
index 8a510b969..8b4991c20 100644
--- a/src/map/irc-bot.c
+++ b/src/map/irc-bot.c
@@ -41,7 +41,7 @@ int irc_connect_timer(int tid, int64 tick, int id, intptr_t data) {
ircbot->last_try = timer->gettick();
- if( ( ircbot->fd = make_connection(ircbot->ip,hChSys.irc_server_port,&opt) ) > 0 ){
+ if ((ircbot->fd = make_connection(ircbot->ip, clif->hChSys->irc_server_port, &opt)) > 0) {
session[ircbot->fd]->func_parse = ircbot->parse;
session[ircbot->fd]->flag.server = 1;
timer->add(timer->gettick() + 3000, ircbot->identify_timer, 0, 0);
@@ -60,7 +60,7 @@ int irc_identify_timer(int tid, int64 tick, int id, intptr_t data) {
sprintf(send_string, "USER HerculesWS%d 8 * : Hercules IRC Bridge",rand()%777);
ircbot->send(send_string);
- sprintf(send_string, "NICK %s", hChSys.irc_nick);
+ sprintf(send_string, "NICK %s", clif->hChSys->irc_nick);
ircbot->send(send_string);
timer->add(timer->gettick() + 3000, ircbot->join_timer, 0, 0);
@@ -76,15 +76,15 @@ int irc_join_timer(int tid, int64 tick, int id, intptr_t data) {
if( !ircbot->isOn )
return 0;
- if( hChSys.irc_nick_pw[0] != '\0' ) {
- sprintf(send_string, "PRIVMSG NICKSERV : IDENTIFY %s", hChSys.irc_nick_pw);
+ if (clif->hChSys->irc_nick_pw[0] != '\0') {
+ sprintf(send_string, "PRIVMSG NICKSERV : IDENTIFY %s", clif->hChSys->irc_nick_pw);
ircbot->send(send_string);
- if( hChSys.irc_use_ghost ) {
- sprintf(send_string, "PRIVMSG NICKSERV : GHOST %s %s", hChSys.irc_nick, hChSys.irc_nick_pw);
+ if (clif->hChSys->irc_use_ghost) {
+ sprintf(send_string, "PRIVMSG NICKSERV : GHOST %s %s", clif->hChSys->irc_nick, clif->hChSys->irc_nick_pw);
}
}
- sprintf(send_string, "JOIN %s", hChSys.irc_channel);
+ sprintf(send_string, "JOIN %s", clif->hChSys->irc_channel);
ircbot->send(send_string);
ircbot->isIn = true;
@@ -120,7 +120,7 @@ int irc_parse(int fd) {
ircbot->isOn = false;
ircbot->isIn = false;
ircbot->fails = 0;
- ircbot->ip = host2ip(hChSys.irc_server);
+ ircbot->ip = host2ip(clif->hChSys->irc_server);
timer->add(timer->gettick() + 120000, ircbot->connect_timer, 0, 0);
return 0;
}
@@ -289,10 +289,10 @@ void irc_privmsg(int fd, char *cmd, char *source, char *target, char *msg) {
irc_privmsg_ctcp(fd, command, source, target, message);
#ifdef IRCBOT_DEBUG
- } else if( strcmpi(target,hChSys.irc_nick) == 0 ) {
+ } else if (strcmpi(target, clif->hChSys->irc_nick) == 0) {
ShowDebug("irc_privmsg: Received message from %s: '%s'\n", source ? source : "(null)", msg);
#endif // IRCBOT_DEBUG
- } else if( msg && strcmpi(target,hChSys.irc_channel) == 0 ) {
+ } else if (msg && strcmpi(target, clif->hChSys->irc_channel) == 0) {
char source_nick[IRC_NICK_LENGTH], source_ident[IRC_IDENT_LENGTH], source_host[IRC_HOST_LENGTH];
source_nick[0] = source_ident[0] = source_host[0] = '\0';
@@ -382,7 +382,7 @@ void irc_usernick(int fd, char *cmd, char *source, char *target, char *msg) {
void irc_relay(char *name, const char *msg) {
if( !ircbot->isIn )
return;
- sprintf(send_string,"PRIVMSG %s :[ %s ] : %s",hChSys.irc_channel,name,msg);
+ sprintf(send_string,"PRIVMSG %s :[ %s ] : %s", clif->hChSys->irc_channel, name, msg);
ircbot->send(send_string);
}
@@ -405,12 +405,12 @@ void irc_bot_init(bool minimal) {
if (minimal)
return;
- if( !hChSys.irc )
+ if (!clif->hChSys->irc)
return;
- if (!(ircbot->ip = host2ip(hChSys.irc_server))) {
- ShowError("Unable to resolve '%s' (irc server), disabling irc channel...\n", hChSys.irc_server);
- hChSys.irc = false;
+ if (!(ircbot->ip = host2ip(clif->hChSys->irc_server))) {
+ ShowError("Unable to resolve '%s' (irc server), disabling irc channel...\n", clif->hChSys->irc_server);
+ clif->hChSys->irc = false;
return;
}
@@ -443,7 +443,7 @@ void irc_bot_init(bool minimal) {
void irc_bot_final(void) {
int i;
- if( !hChSys.irc )
+ if (!clif->hChSys->irc)
return;
if( ircbot->isOn ) {
ircbot->send("QUIT :Hercules is shutting down");
diff --git a/src/map/itemdb.c b/src/map/itemdb.c
index 67aab7a18..508a0ccec 100644
--- a/src/map/itemdb.c
+++ b/src/map/itemdb.c
@@ -1787,9 +1787,12 @@ int itemdb_readdb_libconfig_sub(config_setting_t *it, int n, const char *source)
if ( (t = libconfig->setting_get_member(it, "BuyingStore")) )
id.flag.buyingstore = libconfig->setting_get_bool(t) ? 1 : 0;
+ if ((t = libconfig->setting_get_member(it, "KeepAfterUse")))
+ id.flag.keepafteruse = libconfig->setting_get_bool(t) ? 1 : 0;
+
if (libconfig->setting_lookup_int(it, "Delay", &i32) && i32 >= 0)
id.delay = i32;
-
+
if ( (t = libconfig->setting_get_member(it, "Trade")) ) {
if (config_setting_is_group(t)) {
config_setting_t *tt = NULL;
diff --git a/src/map/itemdb.h b/src/map/itemdb.h
index a1c4d1053..5504d72d9 100644
--- a/src/map/itemdb.h
+++ b/src/map/itemdb.h
@@ -414,6 +414,7 @@ struct item_data {
unsigned autoequip: 1;
unsigned buyingstore : 1;
unsigned bindonequip : 1;
+ unsigned keepafteruse : 1;
} flag;
struct {// item stacking limitation
unsigned short amount;
diff --git a/src/map/map.c b/src/map/map.c
index 651c895ec..2c1495f32 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -1787,7 +1787,7 @@ int map_quit(struct map_session_data *sd) {
if( sd->bg_id && !sd->bg_queue.arena ) /* TODO: dump this chunk after bg_queue is fully enabled */
bg->team_leave(sd,BGTL_QUIT);
- if( sd->state.autotrade && runflag != MAPSERVER_ST_SHUTDOWN && !hChSys.closing )
+ if (sd->state.autotrade && runflag != MAPSERVER_ST_SHUTDOWN && !clif->hChSys->closing)
pc->autotrade_update(sd,PAUC_REMOVE);
skill->cooldown_save(sd);
@@ -1844,7 +1844,7 @@ int map_quit(struct map_session_data *sd) {
unit->remove_map(&sd->ed->bl,CLR_TELEPORT,ALC_MARK);
}
- if( hChSys.local && map->list[sd->bl.m].channel && idb_exists(map->list[sd->bl.m].channel->users, sd->status.char_id) ) {
+ if (clif->hChSys->local && map->list[sd->bl.m].channel && idb_exists(map->list[sd->bl.m].channel->users, sd->status.char_id)) {
clif->chsys_left(map->list[sd->bl.m].channel,sd);
}
@@ -2569,7 +2569,7 @@ int map_random_dir(struct block_list *bl, int16 *x, int16 *y)
}
// gat system
-inline static struct mapcell map_gat2cell(int gat) {
+struct mapcell map_gat2cell(int gat) {
struct mapcell cell;
memset(&cell,0,sizeof(struct mapcell));
@@ -2616,9 +2616,6 @@ void map_cellfromcache(struct map_data *m) {
// Set cell properties
for( xy = 0; xy < size; ++xy ) {
m->cell[xy] = map->gat2cell(decode_buffer[xy]);
-#ifdef CELL_NOSTACK
- m->cell[xy].cell_bl = 0;
-#endif
}
m->getcellp = map->getcellp;
@@ -3394,9 +3391,6 @@ int map_readgat (struct map_data* m)
type = 3; // Cell is 0 (walkable) but under water level, set to 3 (walkable water)
m->cell[xy] = map->gat2cell(type);
-#ifdef CELL_NOSTACK
- m->cell[xy].cell_bl = 0;
-#endif
}
aFree(gat);
@@ -5346,7 +5340,7 @@ int do_final(void) {
ShowStatus("Terminating...\n");
- hChSys.closing = true;
+ clif->hChSys->closing = true;
HPM->event(HPET_FINAL);
if (map->cpsd) aFree(map->cpsd);
@@ -5587,9 +5581,9 @@ void map_cp_defaults(void) {
/* default HCP data */
map->cpsd = pc->get_dummy_sd();
strcpy(map->cpsd->status.name, "Hercules Console");
- map->cpsd->bl.x = MAP_DEFAULT_X;
- map->cpsd->bl.y = MAP_DEFAULT_Y;
- map->cpsd->bl.m = map->mapname2mapid(MAP_DEFAULT);
+ map->cpsd->bl.x = mapindex->default_x;
+ map->cpsd->bl.y = mapindex->default_y;
+ map->cpsd->bl.m = map->mapname2mapid(mapindex->default_map);
console->input->addCommand("gm:info",CPCMD_A(gm_position));
console->input->addCommand("gm:use",CPCMD_A(gm_use));
diff --git a/src/map/mob.c b/src/map/mob.c
index 28e70c5c0..629653c8d 100644
--- a/src/map/mob.c
+++ b/src/map/mob.c
@@ -141,14 +141,9 @@ void mvptomb_create(struct mob_data *md, char *killer, time_t time)
if ( md->tomb_nid )
mob->mvptomb_destroy(md);
- CREATE(nd, struct npc_data, 1);
-
- nd->bl.id = md->tomb_nid = npc->get_new_npc_id();
-
+ nd = npc->create_npc(md->bl.m, md->bl.x, md->bl.y);
+ md->tomb_nid = nd->bl.id;
nd->dir = md->ud.dir;
- nd->bl.m = md->bl.m;
- nd->bl.x = md->bl.x;
- nd->bl.y = md->bl.y;
nd->bl.type = BL_NPC;
safestrncpy(nd->name, msg_txt(856), sizeof(nd->name)); // "Tomb"
@@ -941,6 +936,7 @@ int mob_spawn (struct mob_data *md)
md->move_fail_count = 0;
md->ud.state.attack_continue = 0;
md->ud.target_to = 0;
+ md->ud.dir = 0;
if( md->spawn_timer != INVALID_TIMER )
{
timer->delete(md->spawn_timer, mob->delayspawn);
@@ -1080,6 +1076,15 @@ int mob_ai_sub_hard_activesearch(struct block_list *bl,va_list ap)
((*target) == NULL || !check_distance_bl(&md->bl, *target, dist)) &&
battle->check_range(&md->bl,bl,md->db->range2)
) { //Pick closest target?
+#ifdef ACTIVEPATHSEARCH
+ struct walkpath_data wpd;
+ if (!path->search(&wpd, md->bl.m, md->bl.x, md->bl.y, bl->x, bl->y, 0, CELL_CHKNOPASS)) // Count walk path cells
+ return 0;
+ //Standing monsters use range2, walking monsters use range3
+ if ((md->ud.walktimer == INVALID_TIMER && wpd.path_len > md->db->range2)
+ || (md->ud.walktimer != INVALID_TIMER && wpd.path_len > md->db->range3))
+ return 0;
+#endif
(*target) = bl;
md->target_id=bl->id;
md->min_chase= dist + md->db->range3;
diff --git a/src/map/mob.h b/src/map/mob.h
index c61d29103..f79b33804 100644
--- a/src/map/mob.h
+++ b/src/map/mob.h
@@ -42,6 +42,15 @@
#define MAX_MOB_CHAT 250 //Max Skill's messages
+// On official servers, monsters will only seek targets that are closer to walk to than their
+// search range. The search range is affected depending on if the monster is walking or not.
+// On some maps there can be a quite long path for just walking two cells in a direction and
+// the client does not support displaying walk paths that are longer than 14 cells, so this
+// option reduces position lag in such situation. But doing a complex search for every possible
+// target, might be CPU intensive.
+// Disable this to make monsters not do any path search when looking for a target (old behavior).
+#define ACTIVEPATHSEARCH
+
//Mob skill states.
enum MobSkillState {
MSS_ANY = -1,
diff --git a/src/map/npc.c b/src/map/npc.c
index ce668bfae..8c2f61d58 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -2495,18 +2495,27 @@ bool npc_viewisid(const char * viewid)
return true;
}
+struct npc_data* npc_create_npc(int m, int x, int y)
+{
+ struct npc_data *nd;
+
+ CREATE(nd, struct npc_data, 1);
+ nd->bl.id = npc->get_new_npc_id();
+ nd->bl.prev = nd->bl.next = NULL;
+ nd->bl.m = m;
+ nd->bl.x = x;
+ nd->bl.y = y;
+
+ return nd;
+}
+
//Add then display an npc warp on map
struct npc_data* npc_add_warp(char* name, short from_mapid, short from_x, short from_y, short xs, short ys, unsigned short to_mapindex, short to_x, short to_y) {
int i, flag = 0;
struct npc_data *nd;
- CREATE(nd, struct npc_data, 1);
- nd->bl.id = npc->get_new_npc_id();
+ nd = npc->create_npc(from_mapid, from_x, from_y);
map->addnpc(from_mapid, nd);
- nd->bl.prev = nd->bl.next = NULL;
- nd->bl.m = from_mapid;
- nd->bl.x = from_x;
- nd->bl.y = from_y;
safestrncpy(nd->exname, name, ARRAYLENGTH(nd->exname));
if (npc->name2id(nd->exname) != NULL)
@@ -2574,14 +2583,8 @@ const char* npc_parse_warp(char* w1, char* w2, char* w3, char* w4, const char* s
return strchr(start,'\n');;//try next
}
- CREATE(nd, struct npc_data, 1);
-
- nd->bl.id = npc->get_new_npc_id();
+ nd = npc->create_npc(m, x, y);
map->addnpc(m, nd);
- nd->bl.prev = nd->bl.next = NULL;
- nd->bl.m = m;
- nd->bl.x = x;
- nd->bl.y = y;
npc->parsename(nd, w3, start, buffer, filepath);
if (!battle_config.warp_point_debug)
@@ -2716,17 +2719,12 @@ const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const char* s
return strchr(start,'\n');// continue
}
- CREATE(nd, struct npc_data, 1);
+ nd = npc->create_npc(m, x, y);
CREATE(nd->u.shop.shop_item, struct npc_item_list, i);
memcpy(nd->u.shop.shop_item, items, sizeof(items[0])*i);
aFree(items);
nd->u.shop.count = i;
- nd->bl.prev = nd->bl.next = NULL;
- nd->bl.m = m;
- nd->bl.x = x;
- nd->bl.y = y;
- nd->bl.id = npc->get_new_npc_id();
npc->parsename(nd, w3, start, buffer, filepath);
nd->class_ = m == -1 ? -1 : npc->parseview(w4, start, buffer, filepath);
nd->speed = 200;
@@ -2890,8 +2888,7 @@ const char* npc_parse_script(char* w1, char* w2, char* w3, char* w4, const char*
npc->convertlabel_db(label_list,filepath);
}
- CREATE(nd, struct npc_data, 1);
-
+ nd = npc->create_npc(m, x, y);
if( sscanf(w4, "%*[^,],%d,%d", &xs, &ys) == 2 )
{// OnTouch area defined
nd->u.scr.xs = xs;
@@ -2903,12 +2900,7 @@ const char* npc_parse_script(char* w1, char* w2, char* w3, char* w4, const char*
nd->u.scr.ys = -1;
}
- nd->bl.prev = nd->bl.next = NULL;
- nd->bl.m = m;
- nd->bl.x = x;
- nd->bl.y = y;
npc->parsename(nd, w3, start, buffer, filepath);
- nd->bl.id = npc->get_new_npc_id();
nd->class_ = m == -1 ? -1 : npc->parseview(w4, start, buffer, filepath);
nd->speed = 200;
nd->u.scr.script = scriptroot;
@@ -3040,14 +3032,8 @@ const char* npc_parse_duplicate(char* w1, char* w2, char* w3, char* w4, const ch
return end;// next line, try to continue
}
- CREATE(nd, struct npc_data, 1);
-
- nd->bl.prev = nd->bl.next = NULL;
- nd->bl.m = m;
- nd->bl.x = x;
- nd->bl.y = y;
+ nd = npc->create_npc(m, x, y);
npc->parsename(nd, w3, start, buffer, filepath);
- nd->bl.id = npc->get_new_npc_id();
nd->class_ = m == -1 ? -1 : npc->parseview(w4, start, buffer, filepath);
nd->speed = 200;
nd->src_id = src_id;
@@ -3159,13 +3145,8 @@ int npc_duplicate4instance(struct npc_data *snd, int16 m) {
return 1;
}
- CREATE(wnd, struct npc_data, 1);
- wnd->bl.id = npc->get_new_npc_id();
+ wnd = npc->create_npc(m, snd->bl.x, snd->bl.y);
map->addnpc(m, wnd);
- wnd->bl.prev = wnd->bl.next = NULL;
- wnd->bl.m = m;
- wnd->bl.x = snd->bl.x;
- wnd->bl.y = snd->bl.y;
safestrncpy(wnd->name, "", ARRAYLENGTH(wnd->name));
safestrncpy(wnd->exname, newname, ARRAYLENGTH(wnd->exname));
wnd->class_ = WARP_CLASS;
@@ -3606,6 +3587,14 @@ const char* npc_parse_mob(char* w1, char* w2, char* w3, char* w4, const char* st
return strchr(start,'\n');// continue
}
+
+void npc_parse_unknown_mapflag(const char *name, char *w3, char *w4, const char* start, const char* buffer, const char* filepath, int *retval)
+{
+ ShowError("npc_parse_mapflag: unrecognized mapflag '%s' in file '%s', line '%d'.\n", w3, filepath, strline(buffer,start-buffer));
+ if (retval)
+ *retval = EXIT_FAILURE;
+}
+
/*==========================================
* Set or disable mapflag on map
* eg : bat_c01<TAB>mapflag<TAB>battleground<TAB>2
@@ -4013,13 +4002,20 @@ const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, const char
} else if ( !strcmpi(w3,"nocashshop") ) {
map->list[m].flag.nocashshop = (state) ? 1 : 0;
} else {
- ShowError("npc_parse_mapflag: unrecognized mapflag '%s' in file '%s', line '%d'.\n", w3, filepath, strline(buffer,start-buffer));
- if (retval) *retval = EXIT_FAILURE;
+ npc->parse_unknown_mapflag(mapname, w3, w4, start, buffer, filepath, retval);
}
return strchr(start,'\n');// continue
}
+const char* npc_parse_unknown_object(char *w1, char *w2, char *w3, char *w4, const char* start, const char* buffer, const char* filepath, int *retval)
+{
+ ShowError("npc_parsesrcfile: Unable to parse, probably a missing or extra TAB in file '%s', line '%d'. Skipping line...\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4);
+ start = strchr(start,'\n');// skip and continue
+ *retval = EXIT_FAILURE;
+ return start;
+}
+
/**
* Parses a script file and creates NPCs/functions/mapflags/monsters/etc
* accordingly.
@@ -4208,9 +4204,7 @@ int npc_parsesrcfile(const char* filepath, bool runOnInit) {
}
else
{
- ShowError("npc_parsesrcfile: Unable to parse, probably a missing or extra TAB in file '%s', line '%d'. Skipping line...\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,p-buffer), w1, w2, w3, w4);
- p = strchr(p,'\n');// skip and continue
- success = EXIT_FAILURE;
+ p = npc->parse_unknown_object(w1, w2, w3, w4, p, buffer, filepath, &success);
}
}
aFree(buffer);
@@ -4663,6 +4657,7 @@ void npc_defaults(void) {
npc->parsename = npc_parsename;
npc->parseview = npc_parseview;
npc->viewisid = npc_viewisid;
+ npc->create_npc = npc_create_npc;
npc->add_warp = npc_add_warp;
npc->parse_warp = npc_parse_warp;
npc->parse_shop = npc_parse_shop;
@@ -4682,7 +4677,9 @@ void npc_defaults(void) {
npc->parse_mob2 = npc_parse_mob2;
npc->parse_mob = npc_parse_mob;
npc->parse_mapflag = npc_parse_mapflag;
+ npc->parse_unknown_mapflag = npc_parse_unknown_mapflag;
npc->parsesrcfile = npc_parsesrcfile;
+ npc->parse_unknown_object = npc_parse_unknown_object;
npc->script_event = npc_script_event;
npc->read_event_script = npc_read_event_script;
npc->path_db_clear_sub = npc_path_db_clear_sub;
diff --git a/src/map/npc.h b/src/map/npc.h
index 9c497ffe9..fba14d485 100644
--- a/src/map/npc.h
+++ b/src/map/npc.h
@@ -231,9 +231,11 @@ struct npc_interface {
void (*parsename) (struct npc_data *nd, const char *name, const char *start, const char *buffer, const char *filepath);
int (*parseview) (const char *w4, const char *start, const char *buffer, const char *filepath);
bool (*viewisid) (const char *viewid);
+ struct npc_data* (*create_npc) (int m, int x, int y);
struct npc_data* (*add_warp) (char *name, short from_mapid, short from_x, short from_y, short xs, short ys, unsigned short to_mapindex, short to_x, short to_y);
const char* (*parse_warp) (char *w1, char *w2, char *w3, char *w4, const char *start, const char *buffer, const char *filepath, int *retval);
const char* (*parse_shop) (char *w1, char *w2, char *w3, char *w4, const char *start, const char *buffer, const char *filepath, int *retval);
+ const char* (*parse_unknown_object) (char *w1, char *w2, char *w3, char *w4, const char *start, const char *buffer, const char *filepath, int *retval);
void (*convertlabel_db) (struct npc_label_list *label_list, const char *filepath);
const char* (*skip_script) (const char *start, const char *buffer, const char *filepath, int *retval);
const char* (*parse_script) (char *w1, char *w2, char *w3, char *w4, const char *start, const char *buffer, const char *filepath, int options, int *retval);
@@ -250,6 +252,7 @@ struct npc_interface {
void (*parse_mob2) (struct spawn_data *mobspawn);
const char* (*parse_mob) (char *w1, char *w2, char *w3, char *w4, const char *start, const char *buffer, const char *filepath, int *retval);
const char* (*parse_mapflag) (char *w1, char *w2, char *w3, char *w4, const char *start, const char *buffer, const char *filepath, int *retval);
+ void (*parse_unknown_mapflag) (const char *name, char *w3, char *w4, const char *start, const char *buffer, const char *filepath, int *retval);
int (*parsesrcfile) (const char *filepath, bool runOnInit);
int (*script_event) (struct map_session_data *sd, enum npce_event type);
void (*read_event_script) (void);
diff --git a/src/map/pc.c b/src/map/pc.c
index 6ba06c82b..b22c0d74e 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -902,6 +902,16 @@ int pc_isequip(struct map_session_data *sd,int n)
if(item->sex != 2 && sd->status.sex != item->sex)
return 0;
+ if ( item->equip & EQP_AMMO ) {
+ if ( !pc_iscarton(sd) && (sd->status.class_ == JOB_GENETIC_T || sd->status.class_ == JOB_GENETIC) ) {
+ clif->msg(sd, 0x5EF);
+ return 0;
+ }
+ if ( !pc_ismadogear(sd) && (sd->status.class_ == JOB_MECHANIC_T || sd->status.class_ == JOB_MECHANIC) ) {
+ clif->msg(sd, 0x59B);
+ return 0;
+ }
+ }
if (sd->sc.count) {
if(item->equip & EQP_ARMS && item->type == IT_WEAPON && sd->sc.data[SC_NOEQUIPWEAPON]) // Also works with left-hand weapons [DracoRPG]
@@ -4519,7 +4529,7 @@ int pc_useitem(struct map_session_data *sd,int n) {
if( sd->inventory_data[n]->flag.delay_consume )
clif->useitemack(sd,n,amount,true);
else {
- if( sd->status.inventory[n].expire_time == 0 ) {
+ 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
@@ -5025,7 +5035,7 @@ int pc_setpos(struct map_session_data* sd, unsigned short map_index, int x, int
vending->close(sd);
}
- if( hChSys.local && map->list[sd->bl.m].channel && idb_exists(map->list[sd->bl.m].channel->users, sd->status.char_id) ) {
+ if (clif->hChSys->local && map->list[sd->bl.m].channel && idb_exists(map->list[sd->bl.m].channel->users, sd->status.char_id)) {
clif->chsys_left(map->list[sd->bl.m].channel,sd);
}
}
@@ -8047,6 +8057,8 @@ int pc_setoption(struct map_session_data *sd,int type)
clif->clearcart(sd->fd);
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);
}
#endif
@@ -8082,6 +8094,8 @@ 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);
}
if (type&OPTION_FLYING && !(p_type&OPTION_FLYING))
@@ -8134,6 +8148,8 @@ int pc_setcart(struct map_session_data *sd,int type) {
status_change_end(&sd->bl,SC_PUSH_CART,INVALID_TIMER);
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);
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 */
@@ -8825,6 +8841,89 @@ int pc_load_combo(struct map_session_data *sd) {
}
return ret;
}
+
+void pc_equipitem_pos(struct map_session_data *sd, struct item_data *id, int pos)
+{
+ if (pos & (EQP_HAND_R|EQP_SHADOW_WEAPON)) {
+ if(id)
+ sd->weapontype1 = id->look;
+ else
+ sd->weapontype1 = 0;
+ pc->calcweapontype(sd);
+ clif->changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon);
+ }
+ if (pos & (EQP_HAND_L|EQP_SHADOW_SHIELD)) {
+ if (id) {
+ if(id->type == IT_WEAPON) {
+ sd->status.shield = 0;
+ sd->weapontype2 = id->look;
+ } else if(id->type == IT_ARMOR) {
+ sd->status.shield = id->look;
+ sd->weapontype2 = 0;
+ }
+ } else
+ sd->status.shield = sd->weapontype2 = 0;
+ pc->calcweapontype(sd);
+ clif->changelook(&sd->bl,LOOK_SHIELD,sd->status.shield);
+ }
+ //Added check to prevent sending the same look on multiple slots ->
+ //causes client to redraw item on top of itself. (suggested by Lupus)
+ if (pos & EQP_HEAD_LOW && pc->checkequip(sd,EQP_COSTUME_HEAD_LOW) == -1) {
+ if (id && !(pos&(EQP_HEAD_TOP|EQP_HEAD_MID)))
+ sd->status.head_bottom = id->look;
+ else
+ sd->status.head_bottom = 0;
+ clif->changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom);
+ }
+ if (pos & EQP_HEAD_TOP && pc->checkequip(sd,EQP_COSTUME_HEAD_TOP) == -1) {
+ if (id)
+ sd->status.head_top = id->look;
+ else
+ sd->status.head_top = 0;
+ clif->changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top);
+ }
+ if (pos & EQP_HEAD_MID && pc->checkequip(sd,EQP_COSTUME_HEAD_MID) == -1) {
+ if (id && !(pos&EQP_HEAD_TOP))
+ sd->status.head_mid = id->look;
+ else
+ sd->status.head_mid = 0;
+ clif->changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid);
+ }
+ if (pos & EQP_COSTUME_HEAD_TOP) {
+ if (id){
+ sd->status.head_top = id->look;
+ } else
+ sd->status.head_top = 0;
+ clif->changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top);
+ }
+ if (pos & EQP_COSTUME_HEAD_MID) {
+ if(id && !(pos&EQP_HEAD_TOP)){
+ sd->status.head_mid = id->look;
+ } else
+ sd->status.head_mid = 0;
+ clif->changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid);
+ }
+ if (pos & EQP_COSTUME_HEAD_LOW) {
+ if (id && !(pos&(EQP_HEAD_TOP|EQP_HEAD_MID))){
+ sd->status.head_bottom = id->look;
+ } else
+ sd->status.head_bottom = 0;
+ clif->changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom);
+ }
+
+ if (pos & EQP_SHOES)
+ clif->changelook(&sd->bl,LOOK_SHOES,0);
+ if (pos&EQP_GARMENT && pc->checkequip(sd,EQP_COSTUME_GARMENT) == -1) {
+ sd->status.robe = id ? id->look : 0;
+ clif->changelook(&sd->bl, LOOK_ROBE, sd->status.robe);
+ }
+
+ if (pos & EQP_COSTUME_GARMENT) {
+ sd->status.robe = id ? id->look : 0;
+ clif->changelook(&sd->bl,LOOK_ROBE,sd->status.robe);
+ }
+}
+
/*==========================================
* Equip item on player sd at req_pos from inventory index n
*------------------------------------------*/
@@ -8914,86 +9013,8 @@ int pc_equipitem(struct map_session_data *sd,int n,int req_pos)
sd->status.inventory[n].equip=pos;
- if(pos & (EQP_HAND_R|EQP_SHADOW_WEAPON)) {
- if(id)
- sd->weapontype1 = id->look;
- else
- sd->weapontype1 = 0;
- pc->calcweapontype(sd);
- clif->changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon);
- }
- if(pos & (EQP_HAND_L|EQP_SHADOW_SHIELD)) {
- if(id) {
- if(id->type == IT_WEAPON) {
- sd->status.shield = 0;
- sd->weapontype2 = id->look;
- } else if(id->type == IT_ARMOR) {
- sd->status.shield = id->look;
- sd->weapontype2 = 0;
- }
- } else
- sd->status.shield = sd->weapontype2 = 0;
- pc->calcweapontype(sd);
- clif->changelook(&sd->bl,LOOK_SHIELD,sd->status.shield);
- }
- //Added check to prevent sending the same look on multiple slots ->
- //causes client to redraw item on top of itself. (suggested by Lupus)
- if(pos & EQP_HEAD_LOW && pc->checkequip(sd,EQP_COSTUME_HEAD_LOW) == -1) {
- if(id && !(pos&(EQP_HEAD_TOP|EQP_HEAD_MID)))
- sd->status.head_bottom = id->look;
- else
- sd->status.head_bottom = 0;
- clif->changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom);
- }
- if(pos & EQP_HEAD_TOP && pc->checkequip(sd,EQP_COSTUME_HEAD_TOP) == -1) {
- if(id)
- sd->status.head_top = id->look;
- else
- sd->status.head_top = 0;
- clif->changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top);
- }
- if(pos & EQP_HEAD_MID && pc->checkequip(sd,EQP_COSTUME_HEAD_MID) == -1) {
- if(id && !(pos&EQP_HEAD_TOP))
- sd->status.head_mid = id->look;
- else
- sd->status.head_mid = 0;
- clif->changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid);
- }
- if(pos & EQP_COSTUME_HEAD_TOP) {
- if(id){
- sd->status.head_top = id->look;
- } else
- sd->status.head_top = 0;
- clif->changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top);
- }
- if(pos & EQP_COSTUME_HEAD_MID) {
- if(id && !(pos&EQP_HEAD_TOP)){
- sd->status.head_mid = id->look;
- } else
- sd->status.head_mid = 0;
- clif->changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid);
- }
- if(pos & EQP_COSTUME_HEAD_LOW) {
- if(id && !(pos&(EQP_HEAD_TOP|EQP_HEAD_MID))){
- sd->status.head_bottom = id->look;
- } else
- sd->status.head_bottom = 0;
- clif->changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom);
- }
-
- if(pos & EQP_SHOES)
- clif->changelook(&sd->bl,LOOK_SHOES,0);
- if( pos&EQP_GARMENT && pc->checkequip(sd,EQP_COSTUME_GARMENT) == -1 ) {
- sd->status.robe = id ? id->look : 0;
- clif->changelook(&sd->bl, LOOK_ROBE, sd->status.robe);
- }
-
- if(pos & EQP_COSTUME_GARMENT) {
- sd->status.robe = id ? id->look : 0;
- clif->changelook(&sd->bl,LOOK_ROBE,sd->status.robe);
- }
+ pc->equipitem_pos(sd, id, pos);
-
pc->checkallowskill(sd); //Check if status changes should be halted.
iflag = sd->npc_item_flag;
@@ -9043,6 +9064,63 @@ int pc_equipitem(struct map_session_data *sd,int n,int req_pos)
return 0;
}
+void pc_unequipitem_pos(struct map_session_data *sd, int n, int pos)
+{
+ if (pos & EQP_HAND_R) {
+ sd->weapontype1 = 0;
+ sd->status.weapon = sd->weapontype2;
+ pc->calcweapontype(sd);
+ clif->changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon);
+ if (!battle_config.dancing_weaponswitch_fix)
+ status_change_end(&sd->bl, SC_DANCING, INVALID_TIMER); // Unequipping => stop dancing.
+ }
+ if (pos & EQP_HAND_L) {
+ sd->status.shield = sd->weapontype2 = 0;
+ pc->calcweapontype(sd);
+ clif->changelook(&sd->bl,LOOK_SHIELD,sd->status.shield);
+ }
+ if (pos & EQP_HEAD_LOW && pc->checkequip(sd,EQP_COSTUME_HEAD_LOW) == -1) {
+ sd->status.head_bottom = 0;
+ clif->changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom);
+ }
+ if (pos & EQP_HEAD_TOP && pc->checkequip(sd,EQP_COSTUME_HEAD_TOP) == -1) {
+ sd->status.head_top = 0;
+ clif->changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top);
+ }
+ if (pos & EQP_HEAD_MID && pc->checkequip(sd,EQP_COSTUME_HEAD_MID) == -1) {
+ sd->status.head_mid = 0;
+ clif->changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid);
+ }
+
+ if (pos & EQP_COSTUME_HEAD_TOP) {
+ sd->status.head_top = ( pc->checkequip(sd,EQP_HEAD_TOP) >= 0 ) ? sd->inventory_data[pc->checkequip(sd,EQP_HEAD_TOP)]->look : 0;
+ clif->changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top);
+ }
+
+ if (pos & EQP_COSTUME_HEAD_MID) {
+ sd->status.head_mid = ( pc->checkequip(sd,EQP_HEAD_MID) >= 0 ) ? sd->inventory_data[pc->checkequip(sd,EQP_HEAD_MID)]->look : 0;
+ clif->changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid);
+ }
+
+ if (pos & EQP_COSTUME_HEAD_LOW) {
+ sd->status.head_bottom = ( pc->checkequip(sd,EQP_HEAD_LOW) >= 0 ) ? sd->inventory_data[pc->checkequip(sd,EQP_HEAD_LOW)]->look : 0;
+ clif->changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom);
+ }
+
+ if (pos & EQP_SHOES)
+ clif->changelook(&sd->bl,LOOK_SHOES,0);
+
+ if (pos & EQP_GARMENT && pc->checkequip(sd,EQP_COSTUME_GARMENT) == -1) {
+ sd->status.robe = 0;
+ clif->changelook(&sd->bl, LOOK_ROBE, 0);
+ }
+
+ if (pos & EQP_COSTUME_GARMENT) {
+ sd->status.robe = ( pc->checkequip(sd,EQP_GARMENT) >= 0 ) ? sd->inventory_data[pc->checkequip(sd,EQP_GARMENT)]->look : 0;
+ clif->changelook(&sd->bl,LOOK_ROBE,sd->status.robe);
+ }
+}
+
/*==========================================
* Called when attemting to unequip an item from player
* type:
@@ -9053,6 +9131,7 @@ int pc_equipitem(struct map_session_data *sd,int n,int req_pos)
int pc_unequipitem(struct map_session_data *sd,int n,int flag) {
int i,iflag;
bool status_cacl = false;
+ int pos;
nullpo_ret(sd);
if( n < 0 || n >= MAX_INVENTORY ) {
@@ -9085,73 +9164,22 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag) {
sd->equip_index[i] = -1;
}
- if(sd->status.inventory[n].equip & EQP_HAND_R) {
- sd->weapontype1 = 0;
- sd->status.weapon = sd->weapontype2;
- pc->calcweapontype(sd);
- clif->changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon);
- if( !battle_config.dancing_weaponswitch_fix )
- status_change_end(&sd->bl, SC_DANCING, INVALID_TIMER); // Unequipping => stop dancing.
- }
- if(sd->status.inventory[n].equip & EQP_HAND_L) {
- sd->status.shield = sd->weapontype2 = 0;
- pc->calcweapontype(sd);
- clif->changelook(&sd->bl,LOOK_SHIELD,sd->status.shield);
- }
- if(sd->status.inventory[n].equip & EQP_HEAD_LOW && pc->checkequip(sd,EQP_COSTUME_HEAD_LOW) == -1 ) {
- sd->status.head_bottom = 0;
- clif->changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom);
- }
- if(sd->status.inventory[n].equip & EQP_HEAD_TOP && pc->checkequip(sd,EQP_COSTUME_HEAD_TOP) == -1 ) {
- sd->status.head_top = 0;
- clif->changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top);
- }
- if(sd->status.inventory[n].equip & EQP_HEAD_MID && pc->checkequip(sd,EQP_COSTUME_HEAD_MID) == -1 ) {
- sd->status.head_mid = 0;
- clif->changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid);
- }
-
- if(sd->status.inventory[n].equip & EQP_COSTUME_HEAD_TOP) {
- sd->status.head_top = ( pc->checkequip(sd,EQP_HEAD_TOP) >= 0 ) ? sd->inventory_data[pc->checkequip(sd,EQP_HEAD_TOP)]->look : 0;
- clif->changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top);
- }
-
- if(sd->status.inventory[n].equip & EQP_COSTUME_HEAD_MID) {
- sd->status.head_mid = ( pc->checkequip(sd,EQP_HEAD_MID) >= 0 ) ? sd->inventory_data[pc->checkequip(sd,EQP_HEAD_MID)]->look : 0;
- clif->changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid);
- }
+ pos = sd->status.inventory[n].equip;
+ pc->unequipitem_pos(sd, n, pos);
- if(sd->status.inventory[n].equip & EQP_COSTUME_HEAD_LOW) {
- sd->status.head_bottom = ( pc->checkequip(sd,EQP_HEAD_LOW) >= 0 ) ? sd->inventory_data[pc->checkequip(sd,EQP_HEAD_LOW)]->look : 0;
- clif->changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom);
- }
-
- if(sd->status.inventory[n].equip & EQP_SHOES)
- clif->changelook(&sd->bl,LOOK_SHOES,0);
-
- if( sd->status.inventory[n].equip&EQP_GARMENT && pc->checkequip(sd,EQP_COSTUME_GARMENT) == -1 ) {
- sd->status.robe = 0;
- clif->changelook(&sd->bl, LOOK_ROBE, 0);
- }
-
- if(sd->status.inventory[n].equip & EQP_COSTUME_GARMENT) {
- sd->status.robe = ( pc->checkequip(sd,EQP_GARMENT) >= 0 ) ? sd->inventory_data[pc->checkequip(sd,EQP_GARMENT)]->look : 0;
- clif->changelook(&sd->bl,LOOK_ROBE,sd->status.robe);
- }
-
- clif->unequipitemack(sd,n,sd->status.inventory[n].equip,UIA_SUCCESS);
+ clif->unequipitemack(sd,n,pos,UIA_SUCCESS);
- if((sd->status.inventory[n].equip & EQP_ARMS) &&
+ if((pos & EQP_ARMS) &&
sd->weapontype1 == 0 && sd->weapontype2 == 0 && (!sd->sc.data[SC_TK_SEVENWIND] || sd->sc.data[SC_ASPERSIO])) //Check for seven wind (but not level seven!)
skill->enchant_elemental_end(&sd->bl,-1);
- if(sd->status.inventory[n].equip & EQP_ARMOR) {
+ if(pos & EQP_ARMOR) {
// On Armor Change...
status_change_end(&sd->bl, SC_BENEDICTIO, INVALID_TIMER);
status_change_end(&sd->bl, SC_ARMOR_RESIST, INVALID_TIMER);
}
- if( sd->state.autobonus&sd->status.inventory[n].equip )
+ if( sd->state.autobonus&pos )
sd->state.autobonus &= ~sd->status.inventory[n].equip; //Check for activated autobonus [Inkfish]
sd->status.inventory[n].equip=0;
@@ -11028,7 +11056,9 @@ void pc_defaults(void) {
pc->resetfeel = pc_resetfeel;
pc->resethate = pc_resethate;
pc->equipitem = pc_equipitem;
+ pc->equipitem_pos = pc_equipitem_pos;
pc->unequipitem = pc_unequipitem;
+ pc->unequipitem_pos = pc_unequipitem_pos;
pc->checkitem = pc_checkitem;
pc->useitem = pc_useitem;
diff --git a/src/map/pc.h b/src/map/pc.h
index aa2bb0e74..0adb25a7b 100644
--- a/src/map/pc.h
+++ b/src/map/pc.h
@@ -640,8 +640,8 @@ struct map_session_data {
#define pc_rightside_def(sd) ((sd)->battle_status.def)
#define pc_leftside_mdef(sd) ((sd)->battle_status.mdef2)
#define pc_rightside_mdef(sd) ((sd)->battle_status.mdef)
-#define pc_leftside_matk(sd) (status->base_matk(status->get_status_data(&(sd)->bl), (sd)->status.base_level))
-#define pc_rightside_matk(sd) ((sd)->battle_status.rhw.matk+(sd)->battle_status.lhw.matk+(sd)->bonus.ematk)
+ #define pc_leftside_matk(sd) (status->base_matk(&(sd)->bl, status->get_status_data(&(sd)->bl), (sd)->status.base_level))
+ #define pc_rightside_matk(sd) ((sd)->battle_status.rhw.matk+(sd)->battle_status.lhw.matk+(sd)->bonus.ematk)
#else
#define pc_leftside_atk(sd) ((sd)->battle_status.batk + (sd)->battle_status.rhw.atk + (sd)->battle_status.lhw.atk)
#define pc_rightside_atk(sd) ((sd)->battle_status.rhw.atk2 + (sd)->battle_status.lhw.atk2)
@@ -883,7 +883,9 @@ struct pc_interface {
int (*resetfeel) (struct map_session_data *sd);
int (*resethate) (struct map_session_data *sd);
int (*equipitem) (struct map_session_data *sd,int n,int req_pos);
+ void (*equipitem_pos) (struct map_session_data *sd, struct item_data *id, int pos);
int (*unequipitem) (struct map_session_data *sd,int n,int flag);
+ void (*unequipitem_pos) (struct map_session_data *sd, int n, int pos);
int (*checkitem) (struct map_session_data *sd);
int (*useitem) (struct map_session_data *sd,int n);
diff --git a/src/map/pet.c b/src/map/pet.c
index 0378ea0c3..71dd39401 100644
--- a/src/map/pet.c
+++ b/src/map/pet.c
@@ -688,10 +688,7 @@ int pet_equipitem(struct map_session_data *sd,int index) {
//Skotlex: start support timers if need
int64 tick = timer->gettick();
if (pd->s_skill && pd->s_skill->timer == INVALID_TIMER) {
- if (pd->s_skill->id)
- pd->s_skill->timer=timer->add(tick+pd->s_skill->delay*1000, pet->skill_support_timer, sd->bl.id, 0);
- else
- pd->s_skill->timer=timer->add(tick+pd->s_skill->delay*1000, pet->heal_timer, sd->bl.id, 0);
+ pd->s_skill->timer=timer->add(tick+pd->s_skill->delay*1000, pet->skill_support_timer, sd->bl.id, 0);
}
if (pd->bonus && pd->bonus->timer == INVALID_TIMER)
pd->bonus->timer=timer->add(tick+pd->bonus->delay*1000, pet->skill_bonus_timer, sd->bl.id, 0);
@@ -725,12 +722,8 @@ int pet_unequipitem(struct map_session_data *sd, struct pet_data *pd) {
pd->state.skillbonus = 0;
status_calc_pc(sd,SCO_NONE);
}
- if( pd->s_skill && pd->s_skill->timer != INVALID_TIMER )
- {
- if( pd->s_skill->id )
- timer->delete(pd->s_skill->timer, pet->skill_support_timer);
- else
- timer->delete(pd->s_skill->timer, pet->heal_timer);
+ if (pd->s_skill && pd->s_skill->timer != INVALID_TIMER) {
+ timer->delete(pd->s_skill->timer, pet->skill_support_timer);
pd->s_skill->timer = INVALID_TIMER;
}
if( pd->bonus && pd->bonus->timer != INVALID_TIMER )
@@ -1117,40 +1110,6 @@ int pet_recovery_timer(int tid, int64 tick, int id, intptr_t data) {
return 0;
}
-int pet_heal_timer(int tid, int64 tick, int id, intptr_t data) {
- struct map_session_data *sd=map->id2sd(id);
- struct status_data *st;
- struct pet_data *pd;
- unsigned int rate = 100;
-
- if(sd==NULL || sd->pd == NULL || sd->pd->s_skill == NULL)
- return 1;
-
- pd=sd->pd;
-
- if(pd->s_skill->timer != tid) {
- ShowError("pet_heal_timer %d != %d\n",pd->s_skill->timer,tid);
- return 0;
- }
-
- st = status->get_status_data(&sd->bl);
-
- if(pc_isdead(sd) ||
- (rate = get_percentage(st->sp, st->max_sp)) > pd->s_skill->sp ||
- (rate = get_percentage(st->hp, st->max_hp)) > pd->s_skill->hp ||
- (rate = (pd->ud.skilltimer != INVALID_TIMER)) //Another skill is in effect
- ) { //Wait (how long? 1 sec for every 10% of remaining)
- pd->s_skill->timer=timer->add(timer->gettick()+(rate>10?rate:10)*100,pet->heal_timer,sd->bl.id,0);
- return 0;
- }
- pet_stop_attack(pd);
- pet_stop_walking(pd,1);
- clif->skill_nodamage(&pd->bl,&sd->bl,AL_HEAL,pd->s_skill->lv,1);
- status->heal(&sd->bl, pd->s_skill->lv,0, 0);
- pd->s_skill->timer=timer->add(tick+pd->s_skill->delay*1000,pet->heal_timer,sd->bl.id,0);
- return 0;
-}
-
/*==========================================
* pet support skills [Skotlex]
*------------------------------------------*/
@@ -1361,7 +1320,6 @@ int do_init_pet(bool minimal) {
timer->add_func_list(pet->delay_item_drop,"pet_delay_item_drop");
timer->add_func_list(pet->skill_support_timer, "pet_skill_support_timer"); // [Skotlex]
timer->add_func_list(pet->recovery_timer,"pet_recovery_timer"); // [Valaris]
- timer->add_func_list(pet->heal_timer,"pet_heal_timer"); // [Valaris]
timer->add_interval(timer->gettick()+MIN_PETTHINKTIME,pet->ai_hard,0,0,MIN_PETTHINKTIME);
return 0;
@@ -1433,7 +1391,6 @@ void pet_defaults(void) {
pet->lootitem_drop = pet_lootitem_drop;
pet->skill_bonus_timer = pet_skill_bonus_timer;
pet->recovery_timer = pet_recovery_timer;
- pet->heal_timer = pet_heal_timer;
pet->skill_support_timer = pet_skill_support_timer;
pet->read_db = read_petdb;
}
diff --git a/src/map/pet.h b/src/map/pet.h
index 286109126..cffcf7dd0 100644
--- a/src/map/pet.h
+++ b/src/map/pet.h
@@ -149,7 +149,6 @@ struct pet_interface {
int (*lootitem_drop) (struct pet_data *pd, struct map_session_data *sd);
int (*skill_bonus_timer) (int tid, int64 tick, int id, intptr_t data);
int (*recovery_timer) (int tid, int64 tick, int id, intptr_t data);
- int (*heal_timer) (int tid, int64 tick, int id, intptr_t data);
int (*skill_support_timer) (int tid, int64 tick, int id, intptr_t data);
int (*read_db) ();
};
diff --git a/src/map/script.c b/src/map/script.c
index 5fecd6b64..a458bab49 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -155,7 +155,7 @@ static void script_dump_stack(struct script_state* st)
break;
case C_NAME:
- ShowMessage(" \"%s\" (id=%d ref=%p subtype=%s)\n", reference_getname(data), data->u.num, data->ref, script_op2name(script->str_data[data->u.num].type));
+ ShowMessage(" \"%s\" (id=%d ref=%p subtype=%s)\n", reference_getname(data), data->u.num, data->ref, script->op2name(script->str_data[data->u.num].type));
break;
case C_RETINFO:
@@ -12762,46 +12762,6 @@ BUILDIN(petrecovery)
}
/*==========================================
- * pet healing [Valaris] //Rewritten by [Skotlex]
- *------------------------------------------*/
-BUILDIN(petheal)
-{
- struct pet_data *pd;
- TBL_PC *sd=script->rid2sd(st);
-
- if(sd==NULL || sd->pd==NULL)
- return true;
-
- pd=sd->pd;
- if (pd->s_skill)
- { //Clear previous skill
- if (pd->s_skill->timer != INVALID_TIMER)
- {
- if (pd->s_skill->id)
- timer->delete(pd->s_skill->timer, pet->skill_support_timer);
- else
- timer->delete(pd->s_skill->timer, pet->heal_timer);
- }
- } else //init memory
- pd->s_skill = (struct pet_skill_support *) aMalloc(sizeof(struct pet_skill_support));
-
- pd->s_skill->id=0; //This id identifies that it IS petheal rather than pet_skillsupport
- //Use the lv as the amount to heal
- pd->s_skill->lv=script_getnum(st,2);
- pd->s_skill->delay=script_getnum(st,3);
- pd->s_skill->hp=script_getnum(st,4);
- pd->s_skill->sp=script_getnum(st,5);
-
- //Use delay as initial offset to avoid skill/heal exploits
- if (battle_config.pet_equip_required && pd->pet.equip == 0)
- pd->s_skill->timer = INVALID_TIMER;
- else
- pd->s_skill->timer = timer->add(timer->gettick()+pd->s_skill->delay*1000,pet->heal_timer,sd->bl.id,0);
-
- return true;
-}
-
-/*==========================================
* pet attack skills [Valaris] //Rewritten by [Skotlex]
*------------------------------------------*/
/// petskillattack <skill id>,<level>,<rate>,<bonusrate>
@@ -12864,17 +12824,15 @@ BUILDIN(petskillsupport) {
return true;
pd=sd->pd;
- if (pd->s_skill)
- { //Clear previous skill
- if (pd->s_skill->timer != INVALID_TIMER)
- {
- if (pd->s_skill->id)
- timer->delete(pd->s_skill->timer, pet->skill_support_timer);
- else
- timer->delete(pd->s_skill->timer, pet->heal_timer);
+ if (pd->s_skill) {
+ //Clear previous skill
+ if (pd->s_skill->timer != INVALID_TIMER) {
+ timer->delete(pd->s_skill->timer, pet->skill_support_timer);
}
- } else //init memory
+ } else {
+ //init memory
pd->s_skill = (struct pet_skill_support *) aMalloc(sizeof(struct pet_skill_support));
+ }
pd->s_skill->id=( script_isstringtype(st,2) ? skill->name2id(script_getstr(st,2)) : script_getnum(st,2) );
pd->s_skill->lv=script_getnum(st,3);
@@ -16547,23 +16505,6 @@ BUILDIN(changequest) {
return true;
}
-// Deprecated
-// Please use questprogress instead.
-BUILDIN(checkquest) {
- struct map_session_data *sd = script->rid2sd(st);
- enum quest_check_type type = HAVEQUEST;
-
- if( sd == NULL )
- return false;
-
- if( script_hasdata(st, 3) )
- type = (enum quest_check_type)script_getnum(st, 3);
-
- script_pushint(st, quest->check(sd, script_getnum(st, 2), type));
-
- return true;
-}
-
BUILDIN(questactive) {
struct map_session_data *sd = script->rid2sd(st);
int quest_progress = 0;
@@ -19417,7 +19358,6 @@ void script_parse_builtin(void) {
BUILDIN_DEF(petskillbonus,"iiii"), // [Valaris]
BUILDIN_DEF(petrecovery,"ii"), // [Valaris]
BUILDIN_DEF(petloot,"i"), // [Valaris]
- BUILDIN_DEF_DEPRECATED(petheal,"iiii"), // Deprecated 2014-10-27 [Haru]
BUILDIN_DEF(petskillattack,"viii"), // [Skotlex]
BUILDIN_DEF(petskillattack2,"viiii"), // [Valaris]
BUILDIN_DEF(petskillsupport,"viiii"), // [Skotlex]
@@ -19467,7 +19407,6 @@ void script_parse_builtin(void) {
BUILDIN_DEF(gethominfo,"i"),
BUILDIN_DEF(getmercinfo,"i?"),
BUILDIN_DEF(checkequipedcard,"i"),
- BUILDIN_DEF2_DEPRECATED(__jump_zero,"jump_zero","il"), // Deprecated 2014-10-27 [Haru]
BUILDIN_DEF(globalmes,"s?"), //end jA addition
BUILDIN_DEF(unequip,"i"), // unequip command [Spectre]
BUILDIN_DEF(getstrlen,"s"), //strlen [Valaris]
@@ -19662,7 +19601,6 @@ void script_parse_builtin(void) {
BUILDIN_DEF(setquest, "i"),
BUILDIN_DEF(erasequest, "i?"),
BUILDIN_DEF(completequest, "i?"),
- BUILDIN_DEF_DEPRECATED(checkquest, "i?"), // Deprecated 2014-10-28 [Haru]
BUILDIN_DEF(questprogress, "i?"),
BUILDIN_DEF(questactive, "i"),
BUILDIN_DEF(changequest, "ii"),
diff --git a/src/map/skill.c b/src/map/skill.c
index 169f4bcb9..763af64b7 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -2658,7 +2658,8 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr
break;
// This ensures the storm randomly pushes instead of exactly a cell backwards per official mechanics.
case WZ_STORMGUST:
- dir = rnd()%8;
+ if(!battle_config.stormgust_knockback)
+ dir = rand()%8;
break;
case WL_CRIMSONROCK:
dir = map->calc_dir(bl,skill->area_temp[4],skill->area_temp[5]);
@@ -2856,9 +2857,11 @@ int skill_check_unit_range_sub (struct block_list *bl, va_list ap) {
g_skill_id = su->group->skill_id;
switch (skill_id) {
- case MH_STEINWAND:
- case MG_SAFETYWALL:
case AL_PNEUMA:
+ if(g_skill_id == SA_LANDPROTECTOR)
+ break;
+ case MG_SAFETYWALL:
+ case MH_STEINWAND:
case SC_MAELSTROM:
case SO_ELEMENTAL_SHIELD:
if(g_skill_id != MH_STEINWAND && g_skill_id != MG_SAFETYWALL && g_skill_id != AL_PNEUMA && g_skill_id != SC_MAELSTROM && g_skill_id != SO_ELEMENTAL_SHIELD)
@@ -3303,7 +3306,8 @@ int skill_timerskill(int tid, int64 tick, int id, intptr_t data) {
int x = skl->type>>16, y = skl->type&0xFFFF;
if( path->search_long(NULL, src->m, src->x, src->y, x, y, CELL_CHKWALL) )
skill->unitsetting(src,skl->skill_id,skl->skill_lv,x,y,skl->flag);
- if( path->search_long(NULL, src->m, src->x, src->y, skl->x, skl->y, CELL_CHKWALL) )
+ if( path->search_long(NULL, src->m, src->x, src->y, skl->x, skl->y, CELL_CHKWALL)
+ && !map->getcell(src->m, skl->x, skl->y, CELL_CHKLANDPROTECTOR) )
clif->skill_poseffect(src,skl->skill_id,skl->skill_lv,skl->x,skl->y,tick);
}
else if( path->search_long(NULL, src->m, src->x, src->y, skl->x, skl->y, CELL_CHKWALL) )
@@ -3758,8 +3762,6 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
case NPC_SPLASHATTACK:
flag |= SD_PREAMBLE; // a fake packet will be sent for the first target to be hit
case AS_SPLASHER:
- case SM_MAGNUM:
- case MS_MAGNUM:
case HT_BLITZBEAT:
case AC_SHOWER:
case MA_SHOWER:
@@ -3869,6 +3871,14 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
}
break;
+ case SM_MAGNUM:
+ 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));
+ }
+ break;
+
case KN_BRANDISHSPEAR:
case ML_BRANDISH:
//Coded apart for it needs the flag passed to the damage calculation.
@@ -9589,7 +9599,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
if (tsc->data[scs[i]]) status_change_end(bl, scs[i], INVALID_TIMER);
}
}
- heal = 5 * status->get_lv(&hd->bl) + status->base_matk(&hd->battle_status, status->get_lv(&hd->bl));
+ heal = 5 * status->get_lv(&hd->bl) + status->base_matk(&hd->bl, &hd->battle_status, status->get_lv(&hd->bl));
status->heal(bl, heal, 0, 0);
clif->skill_nodamage(src, src, skill_id, skill_lv, clif->skill_nodamage(src, bl, AL_HEAL, heal, 1));
status->change_start(src, src, type, 1000, skill_lv, 0, 0, 0, skill->get_time(skill_id,skill_lv), SCFLAG_NOAVOID|SCFLAG_FIXEDTICK|SCFLAG_FIXEDRATE);
@@ -9896,7 +9906,6 @@ int skill_castend_map (struct map_session_data *sd, uint16 skill_id, const char
}
pc_stop_attack(sd);
- pc_stop_walking(sd,0);
if(battle_config.skill_log && battle_config.skill_log&BL_PC)
ShowInfo("PC %d skill castend skill =%d map=%s\n",sd->bl.id,skill_id,mapname);
@@ -10098,6 +10107,11 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
}
case MG_SAFETYWALL:
+ if (map->foreachincell(skill->cell_overlap,src->m,x,y,BL_SKILL)) {
+ skill->unitsetting(src,skill_id,skill_lv,x,y,0);
+ return 0; // Don't consume gems if cast on LP
+ }
+
case MG_FIREWALL:
case MG_THUNDERSTORM:
@@ -10186,6 +10200,8 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
case GN_THORNS_TRAP:
case GN_DEMONIC_FIRE:
case GN_HELLS_PLANT:
+ case GN_FIRE_EXPANSION_SMOKE_POWDER:
+ case GN_FIRE_EXPANSION_TEAR_GAS:
case SO_EARTHGRAVE:
case SO_DIAMONDDUST:
case SO_FIRE_INSIGNIA:
@@ -10265,7 +10281,8 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
tmpx = x - area + rnd()%(area * 2 + 1);
tmpy = y - area + rnd()%(area * 2 + 1);
- if( i == 0 && path->search_long(NULL, src->m, src->x, src->y, tmpx, tmpy, CELL_CHKWALL) )
+ if( i == 0 && path->search_long(NULL, src->m, src->x, src->y, tmpx, tmpy, CELL_CHKWALL)
+ && !map->getcell(src->m, tmpx, tmpy, CELL_CHKLANDPROTECTOR))
clif->skill_poseffect(src,skill_id,skill_lv,tmpx,tmpy,tick);
if( i > 0 )
@@ -10641,13 +10658,14 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
case GN_FIRE_EXPANSION: {
int i;
+ int aciddemocast = 5;//If player doesent know Acid Demonstration or knows level 5 or lower, effect 5 will cast level 5 Acid Demo.
struct unit_data *ud = unit->bl2ud(src);
if( !ud ) break;
for( i = 0; i < MAX_SKILLUNITGROUP && ud->skillunit[i]; i ++ ) {
if( ud->skillunit[i]->skill_id == GN_DEMONIC_FIRE &&
- distance_xy(x, y, ud->skillunit[i]->unit->bl.x, ud->skillunit[i]->unit->bl.y) < 4 ) {
+ distance_xy(x, y, ud->skillunit[i]->unit->bl.x, ud->skillunit[i]->unit->bl.y) < 3 ) {
switch( skill_lv ) {
case 3:
ud->skillunit[i]->unit_id = UNT_FIRE_EXPANSION_SMOKE_POWDER;
@@ -10657,11 +10675,13 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
ud->skillunit[i]->unit_id = UNT_FIRE_EXPANSION_TEAR_GAS;
clif->changetraplook(&ud->skillunit[i]->unit->bl, UNT_FIRE_EXPANSION_TEAR_GAS);
break;
- case 5:
+ case 5:// If player knows a level of Acid Demonstration greater then 5, that level will be casted.
+ if ( pc->checkskill(sd, CR_ACIDDEMONSTRATION) > 5 )
+ aciddemocast = pc->checkskill(sd, CR_ACIDDEMONSTRATION);
map->foreachinarea(skill->area_sub, src->m,
- ud->skillunit[i]->unit->bl.x - 3, ud->skillunit[i]->unit->bl.y - 3,
- ud->skillunit[i]->unit->bl.x + 3, ud->skillunit[i]->unit->bl.y + 3, BL_CHAR,
- src, CR_ACIDDEMONSTRATION, sd ? pc->checkskill(sd, CR_ACIDDEMONSTRATION) : skill_lv, tick, flag|BCT_ENEMY|1|SD_LEVEL, skill->castend_damage_id);
+ ud->skillunit[i]->unit->bl.x - 2, ud->skillunit[i]->unit->bl.y - 2,
+ ud->skillunit[i]->unit->bl.x + 2, ud->skillunit[i]->unit->bl.y + 2, BL_CHAR,
+ src, CR_ACIDDEMONSTRATION, aciddemocast, tick, flag|BCT_ENEMY|1|SD_LEVEL, skill->castend_damage_id);
skill->delunit(ud->skillunit[i]->unit);
break;
default:
@@ -11288,8 +11308,7 @@ struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_
if (skill->get_unit_flag(skill_id) & UF_RANGEDSINGLEUNIT && i == (layout->count / 2))
val2 |= UF_RANGEDSINGLEUNIT; // center.
- if( range <= 0 )
- map->foreachincell(skill->cell_overlap,src->m,ux,uy,BL_SKILL,skill_id, &alive, src);
+ map->foreachincell(skill->cell_overlap,src->m,ux,uy,BL_SKILL,skill_id, &alive, src);
if( !alive )
continue;
@@ -11344,7 +11363,7 @@ int skill_unit_onplace(struct skill_unit *src, struct block_list *bl, int64 tick
nullpo_ret(sg=src->group);
nullpo_ret(ss=map->id2bl(sg->src_id));
- if( skill->get_type(sg->skill_id) == BF_MAGIC && map->getcell(bl->m, bl->x, bl->y, CELL_CHKLANDPROTECTOR) && sg->skill_id != SA_LANDPROTECTOR )
+ if( skill->get_type(sg->skill_id) == BF_MAGIC && map->getcell(src->bl.m, src->bl.x, src->bl.y, CELL_CHKLANDPROTECTOR) && sg->skill_id != SA_LANDPROTECTOR )
return 0; //AoE skills are ineffective. [Skotlex]
sc = status->get_sc(bl);
@@ -12142,11 +12161,11 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6
break;
case UNT_FIRE_EXPANSION_SMOKE_POWDER:
- sc_start(ss, bl, status->skill2sc(GN_FIRE_EXPANSION_SMOKE_POWDER), 100, sg->skill_lv, 1000);
+ sc_start(ss, bl, SC_FIRE_EXPANSION_SMOKE_POWDER, 100, sg->skill_lv, 1000);
break;
case UNT_FIRE_EXPANSION_TEAR_GAS:
- sc_start(ss, bl, status->skill2sc(GN_FIRE_EXPANSION_TEAR_GAS), 100, sg->skill_lv, 1000);
+ sc_start(ss, bl, SC_FIRE_EXPANSION_TEAR_GAS, 100, sg->skill_lv, 1000);
break;
case UNT_HELLS_PLANT:
@@ -16010,7 +16029,7 @@ int skill_unit_timer_sub_onplace(struct block_list* bl, va_list ap) {
nullpo_ret(group);
- if( !(skill->get_inf2(group->skill_id)&(INF2_SONG_DANCE|INF2_TRAP|INF2_NOLP)) && map->getcell(bl->m, bl->x, bl->y, CELL_CHKLANDPROTECTOR) )
+ if( !(skill->get_inf2(group->skill_id)&(INF2_SONG_DANCE|INF2_TRAP|INF2_NOLP)) && map->getcell(su->bl.m, su->bl.x, su->bl.y, CELL_CHKLANDPROTECTOR) )
return 0; //AoE skills are ineffective. [Skotlex]
if( battle->check_target(&su->bl,bl,group->target_flag) <= 0 )
diff --git a/src/map/status.c b/src/map/status.c
index e2eede490..6d4b8d5fa 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -1851,237 +1851,6 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin
return 1;
}
-//Checks whether the source can see and chase target.
-int status_check_visibility(struct block_list *src, struct block_list *target) {
- int view_range;
- struct status_change *tsc = NULL;
-
- switch (src->type) {
- case BL_MOB:
- view_range = ((TBL_MOB*)src)->min_chase;
- break;
- case BL_PET:
- view_range = ((TBL_PET*)src)->db->range2;
- break;
- default:
- view_range = AREA_SIZE;
- }
-
- if (src->m != target->m || !check_distance_bl(src, target, view_range))
- return 0;
-
- if( src->type == BL_NPC ) /* NPCs don't care for the rest */
- return 1;
-
- if( ( tsc = status->get_sc(target) ) ) {
- struct status_data *st = status->get_status_data(src);
-
- switch (target->type) { //Check for chase-walk/hiding/cloaking opponents.
- case BL_PC:
- if ( tsc->data[SC_CLOAKINGEXCEED] && !(st->mode&MD_BOSS) )
- return 0;
- if( (tsc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) || tsc->data[SC_STEALTHFIELD] || tsc->data[SC__INVISIBILITY] || tsc->data[SC_CAMOUFLAGE]) && !(st->mode&MD_BOSS) &&
- ( ((TBL_PC*)target)->special_state.perfect_hiding || !(st->mode&MD_DETECTOR) ) )
- return 0;
- break;
- default:
- if( (tsc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) || tsc->data[SC_CAMOUFLAGE]) && !(st->mode&(MD_BOSS|MD_DETECTOR)) )
- return 0;
-
- }
- }
-
- return 1;
-}
-
-// 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]);
-
- 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 );
-
-#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
-
- // 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;
-
- return amotion;
-}
-
-unsigned short status_base_atk(const struct block_list *bl, const struct status_data *st) {
- int flag = 0, str, dex,
-#ifdef RENEWAL
- rstr,
-#endif
- dstr;
-
-
- if(!(bl->type&battle_config.enable_baseatk))
- return 0;
-
- if (bl->type == BL_PC)
- switch(((TBL_PC*)bl)->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:
- flag = 1;
- }
- if (flag) {
-#ifdef RENEWAL
- rstr =
-#endif
- str = st->dex;
- dex = st->str;
- } else {
-#ifdef RENEWAL
- rstr =
-#endif
- str = st->str;
- dex = st->dex;
- }
- //Normally only players have base-atk, but homunc have a different batk
- // equation, hinting that perhaps non-players should use this for batk.
- // [Skotlex]
-#ifdef RENEWAL
- if (bl->type == BL_HOM)
- str = (int)(floor((rstr + dex + st->luk) / 3) + floor(((TBL_HOM*)bl)->homunculus.level / 10));
-#endif
- dstr = str/10;
- str += dstr*dstr;
- if (bl->type == BL_PC)
-#ifdef RENEWAL
- str = (int)(rstr + (float)dex/5 + (float)st->luk/3 + (float)((TBL_PC*)bl)->status.base_level/4);
- else if(bl->type == BL_MOB)
- str = rstr + ((TBL_MOB*)bl)->level;
-#else
- str+= dex/5 + st->luk/5;
-#endif
- return cap_value(str, 0, USHRT_MAX);
-}
-
-#ifndef RENEWAL
-static inline unsigned short status_base_matk_min(const struct status_data *st){ return st->int_+(st->int_/7)*(st->int_/7); }
-#endif // not RENEWAL
-static inline unsigned short status_base_matk_max(const struct status_data *st){ return st->int_+(st->int_/5)*(st->int_/5); }
-
-unsigned short status_base_matk(const struct status_data *st, int level) {
-#ifdef RENEWAL
- return st->int_+(st->int_/2)+(st->dex/5)+(st->luk/3)+(level/4);
-#else
- return 0;
-#endif
-}
-
-//Fills in the misc data that can be calculated from the other status info (except for level)
-void status_calc_misc(struct block_list *bl, struct status_data *st, int level) {
- //Non players get the value set, players need to stack with previous bonuses.
- if( bl->type != BL_PC )
- st->batk =
- st->hit = st->flee =
- st->def2 = st->mdef2 =
- st->cri = st->flee2 = 0;
-
-#ifdef RENEWAL // renewal formulas
- if (bl->type == BL_HOM) {
- st->hit = level + st->dex + 150; //base level + dex + 150
- st->flee = level + st->agi + level/10; //base level + agi + base level/10
- } else {
- st->matk_min = st->matk_max = bl->type == BL_PC ? status->base_matk(st, level) : level + st->int_;
- st->hit += level + st->dex + (bl->type == BL_PC ? st->luk/3 + 175 : 150); //base level + ( every 1 dex = +1 hit ) + (every 3 luk = +1 hit) + 175
- st->flee += level + st->agi + (bl->type == BL_PC ? st->luk/5 : 0) + 100; //base level + ( every 1 agi = +1 flee ) + (every 5 luk = +1 flee) + 100
- st->def2 += (int)(((float)level + st->vit)/2 + ( bl->type == BL_PC ? ((float)st->agi/5) : 0 )); //base level + (every 2 vit = +1 def) + (every 5 agi = +1 def)
- st->mdef2 += (int)( bl->type == BL_PC ?(st->int_ + ((float)level/4) + ((float)(st->dex+st->vit)/5)):((float)(st->int_ + level)/4)); //(every 4 base level = +1 mdef) + (every 1 int = +1 mdef) + (every 5 dex = +1 mdef) + (every 5 vit = +1 mdef)
- }
-#else // not RENEWAL
- st->matk_min = status_base_matk_min(st);
- st->matk_max = status_base_matk_max(st);
- st->hit += level + st->dex;
- st->flee += level + st->agi;
- st->def2 += st->vit;
- st->mdef2 += st->int_ + (st->vit>>1);
-#endif // RENEWAL
-
- if( bl->type&battle_config.enable_critical )
- st->cri += 10 + (st->luk*10/3); //(every 1 luk = +0.3 critical)
- else
- st->cri = 0;
-
- if (bl->type&battle_config.enable_perfect_flee)
- st->flee2 += st->luk + 10; //(every 10 luk = +1 perfect flee)
- else
- st->flee2 = 0;
-
- if (st->batk) {
- int temp = st->batk + status->base_atk(bl, st);
- st->batk = cap_value(temp, 0, USHRT_MAX);
- } else
- st->batk = status->base_atk(bl, st);
- if (st->cri)
- switch (bl->type) {
- case BL_MOB:
- if(battle_config.mob_critical_rate != 100)
- st->cri = st->cri*battle_config.mob_critical_rate/100;
- if(!st->cri && battle_config.mob_critical_rate)
- st->cri = 10;
- break;
- case BL_PC:
- //Players don't have a critical adjustment setting as of yet.
- break;
- case BL_MER:
-#ifdef RENEWAL
- st->matk_min = st->matk_max = status_base_matk_max(st);
- st->def2 = st->vit + level / 10 + st->vit / 5;
- st->mdef2 = level / 10 + st->int_ / 5;
-#endif
- break;
- default:
- if(battle_config.critical_rate != 100)
- st->cri = st->cri*battle_config.critical_rate/100;
- if (!st->cri && battle_config.critical_rate)
- st->cri = 10;
- }
- if(bl->type&BL_REGEN)
- status->calc_regen(bl, st, status->get_regen_data(bl));
-}
-
//Skotlex: Calculates the initial status for the given mob
//first will only be false when the mob leveled up or got a GuardUp level.
int status_calc_mob_(struct mob_data* md, enum e_status_calc_opt opt) {
@@ -3284,105 +3053,17 @@ int status_calc_mercenary_(struct mercenary_data *md, enum e_status_calc_opt opt
return 0;
}
-int status_calc_homunculus_(struct homun_data *hd, enum e_status_calc_opt opt) {
- struct status_data *hstatus = &hd->base_status;
- struct s_homunculus *hom = &hd->homunculus;
- int skill_lv;
- int amotion;
-
- hstatus->str = hom->str / 10;
- hstatus->agi = hom->agi / 10;
- hstatus->vit = hom->vit / 10;
- hstatus->dex = hom->dex / 10;
- hstatus->int_ = hom->int_ / 10;
- hstatus->luk = hom->luk / 10;
-
- if ( opt&SCO_FIRST ) { //[orn]
- const struct s_homunculus_db *db = hd->homunculusDB;
- hstatus->def_ele = db->element;
- hstatus->ele_lv = 1;
- hstatus->race = db->race;
- hstatus->size = (hom->class_ == db->evo_class)?db->evo_size:db->base_size;
- hstatus->rhw.range = 1 + hstatus->size;
- hstatus->mode = MD_CANMOVE|MD_CANATTACK;
- hstatus->speed = DEFAULT_WALK_SPEED;
- if (battle_config.hom_setting&0x8 && hd->master)
- hstatus->speed = status->get_speed(&hd->master->bl);
-
- hstatus->hp = 1;
- hstatus->sp = 1;
- }
-
- hstatus->aspd_rate = 1000;
-
-#ifdef RENEWAL
- hstatus->def = (hstatus->vit + (hom->level / 10)) + ((hstatus->agi + (hom->level / 10)) / 2);
- hstatus->mdef = hstatus->int_ + ((hstatus->int_ + hstatus->dex + hstatus->luk) / 3) + (hom->level / 10) * 2;
-
- amotion = (1000 -2*hstatus->agi -hstatus->dex) * hd->homunculusDB->baseASPD/1000;
-#else
- skill_lv = hom->level/10 + hstatus->vit/5;
- hstatus->def = cap_value(skill_lv, 0, 99);
-
- skill_lv = hom->level/10 + hstatus->int_/5;
- hstatus->mdef = cap_value(skill_lv, 0, 99);
- amotion = (1000 -4*hstatus->agi - hstatus->dex) * hd->homunculusDB->baseASPD/1000;
-#endif
-
- 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;
-
- homun->calc_skilltree(hd, 0);
-
- if((skill_lv=homun->checkskill(hd,HAMI_SKIN)) > 0)
- hstatus->def += skill_lv * 4;
-
- if((skill_lv = homun->checkskill(hd,HVAN_INSTRUCT)) > 0) {
- hstatus->int_ += 1 +skill_lv/2 +skill_lv/4 +skill_lv/5;
- hstatus->str += 1 +skill_lv/3 +skill_lv/3 +skill_lv/4;
- }
-
- if((skill_lv=homun->checkskill(hd,HAMI_SKIN)) > 0)
- hstatus->max_hp += skill_lv * 2 * hstatus->max_hp / 100;
-
- if((skill_lv = homun->checkskill(hd,HLIF_BRAIN)) > 0)
- hstatus->max_sp += (1 +skill_lv/2 -skill_lv/4 +skill_lv/5) * hstatus->max_sp / 100;
-
- if ( opt&SCO_FIRST ) {
- hd->battle_status.hp = hom->hp;
- hd->battle_status.sp = hom->sp;
- }
-
-#ifndef RENEWAL
- hstatus->rhw.atk = hstatus->dex;
- hstatus->rhw.atk2 = hstatus->str + hom->level;
-#endif
-
- status->calc_misc(&hd->bl, hstatus, hom->level);
-
-#ifdef RENEWAL
- hstatus->matk_max = hstatus->matk_min;
-#endif
-
- status_cpy(&hd->battle_status, hstatus);
- return 1;
-}
-
int status_calc_elemental_(struct elemental_data *ed, enum e_status_calc_opt opt) {
struct status_data *estatus = &ed->base_status;
struct s_elemental *ele = &ed->elemental;
struct map_session_data *sd = ed->master;
- if( !sd )
+ if ( !sd )
return 0;
- if( opt&SCO_FIRST ) {
+ if ( opt&SCO_FIRST ) {
memcpy(estatus, &ed->db->status, sizeof(struct status_data));
- if( !ele->mode )
+ if ( !ele->mode )
estatus->mode = EL_MODE_PASSIVE;
else
estatus->mode = ele->mode;
@@ -3402,7 +3083,7 @@ int status_calc_elemental_(struct elemental_data *ed, enum e_status_calc_opt opt
estatus->flee = ele->flee;
estatus->hit = ele->hit;
- memcpy(&ed->battle_status,estatus,sizeof(struct status_data));
+ memcpy(&ed->battle_status, estatus, sizeof(struct status_data));
} else {
status->calc_misc(&ed->bl, estatus, 0);
status_cpy(&ed->battle_status, estatus);
@@ -3445,6 +3126,89 @@ int status_calc_npc_(struct npc_data *nd, enum e_status_calc_opt opt) {
return 0;
}
+int status_calc_homunculus_(struct homun_data *hd, enum e_status_calc_opt opt) {
+ struct status_data *hstatus = &hd->base_status;
+ struct s_homunculus *hom = &hd->homunculus;
+ int skill_lv;
+ int amotion;
+
+ hstatus->str = hom->str / 10;
+ hstatus->agi = hom->agi / 10;
+ hstatus->vit = hom->vit / 10;
+ hstatus->dex = hom->dex / 10;
+ hstatus->int_ = hom->int_ / 10;
+ hstatus->luk = hom->luk / 10;
+
+ APPLY_HOMUN_LEVEL_STATWEIGHT();
+
+ if ( opt&SCO_FIRST ) { //[orn]
+ const struct s_homunculus_db *db = hd->homunculusDB;
+ hstatus->def_ele = db->element;
+ hstatus->ele_lv = 1;
+ hstatus->race = db->race;
+ hstatus->size = (hom->class_ == db->evo_class) ? db->evo_size : db->base_size;
+ hstatus->rhw.range = 1 + hstatus->size;
+ hstatus->mode = MD_CANMOVE | MD_CANATTACK;
+ hstatus->speed = DEFAULT_WALK_SPEED;
+ if ( battle_config.hom_setting & 0x8 && hd->master )
+ hstatus->speed = status->get_speed(&hd->master->bl);
+
+ hstatus->hp = 1;
+ hstatus->sp = 1;
+ }
+
+ hstatus->aspd_rate = 1000;
+
+#ifdef RENEWAL
+ amotion = hd->homunculusDB->baseASPD;
+ amotion = amotion - amotion * (hstatus->dex + hom->dex_value) / 1000 - (hstatus->agi + hom->agi_value) * amotion / 250;
+#else
+ skill_lv = hom->level / 10 + hstatus->vit / 5;
+ hstatus->def = cap_value(skill_lv, 0, 99);
+
+ skill_lv = hom->level / 10 + hstatus->int_ / 5;
+ hstatus->mdef = cap_value(skill_lv, 0, 99);
+ amotion = (1000 - 4 * hstatus->agi - hstatus->dex) * hd->homunculusDB->baseASPD / 1000;
+#endif
+
+ 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;
+
+ homun->calc_skilltree(hd, 0);
+
+ if ( (skill_lv = homun->checkskill(hd, HAMI_SKIN)) > 0 )
+ hstatus->def += skill_lv * 4;
+
+ if ( (skill_lv = homun->checkskill(hd, HVAN_INSTRUCT)) > 0 ) {
+ hstatus->int_ += 1 + skill_lv / 2 + skill_lv / 4 + skill_lv / 5;
+ hstatus->str += 1 + skill_lv / 3 + skill_lv / 3 + skill_lv / 4;
+ }
+
+ if ( (skill_lv = homun->checkskill(hd, HAMI_SKIN)) > 0 )
+ hstatus->max_hp += skill_lv * 2 * hstatus->max_hp / 100;
+
+ if ( (skill_lv = homun->checkskill(hd, HLIF_BRAIN)) > 0 )
+ hstatus->max_sp += (1 + skill_lv / 2 - skill_lv / 4 + skill_lv / 5) * hstatus->max_sp / 100;
+
+ if ( opt&SCO_FIRST ) {
+ hd->battle_status.hp = hom->hp;
+ hd->battle_status.sp = hom->sp;
+ }
+
+#ifndef RENEWAL
+ hstatus->rhw.atk = hstatus->dex;
+ hstatus->rhw.atk2 = hstatus->str + hom->level;
+#endif
+
+ status->calc_misc(&hd->bl, hstatus, hom->level);
+
+ status_cpy(&hd->battle_status, hstatus);
+ return 1;
+}
//Calculates base regen values.
void status_calc_regen(struct block_list *bl, struct status_data *st, struct regen_data *regen) {
@@ -3639,6 +3403,21 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag) {
if (!bst || !st)
return;
+ /** [Playtester]
+ * This needs to be done even if there is currently no status change active, because
+ * we need to update the speed on the client when the last status change ends.
+ **/
+ if(flag&SCB_SPEED) {
+ struct unit_data *ud = unit->bl2ud(bl);
+ /** [Skotlex]
+ * Re-walk to adjust speed (we do not check if walktimer != INVALID_TIMER
+ * because if you step on something while walking, the moment this
+ * piece of code triggers the walk-timer is set on INVALID_TIMER)
+ **/
+ if (ud)
+ ud->state.change_walk_target = ud->state.speed_changed = 1;
+ }
+
if((!(bl->type&BL_REGEN)) && (!sc || !sc->count)) { //No difference.
status_cpy(st, bst);
return;
@@ -3727,13 +3506,6 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag) {
st->lhw.atk2 = status->calc_watk(bl, sc, bst->lhw.atk2, true);
}
}
-
- /*if( bl->type&BL_HOM ) {
- st->rhw.atk += (st->dex - bst->dex);
- st->rhw.atk2 += (st->str - bst->str);
- if( st->rhw.atk2 < st->rhw.atk )
- st->rhw.atk2 = st->rhw.atk;
- }*/
}
if(flag&SCB_HIT) {
@@ -3815,16 +3587,9 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag) {
}
if(flag&SCB_SPEED) {
- struct unit_data *ud = unit->bl2ud(bl);
st->speed = status->calc_speed(bl, sc, bst->speed);
- //Re-walk to adjust speed (we do not check if walktimer != INVALID_TIMER
- //because if you step on something while walking, the moment this
- //piece of code triggers the walk-timer is set on INVALID_TIMER) [Skotlex]
- if (ud)
- ud->state.change_walk_target = ud->state.speed_changed = 1;
-
if( bl->type&BL_PC && !(sd && sd->state.permanent_speed) && st->speed < battle_config.max_walk_speed )
st->speed = battle_config.max_walk_speed;
@@ -3920,80 +3685,82 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag) {
if(flag&SCB_MATK) {
status->update_matk(bl);
}
+
+ if ( flag&SCB_DSPD ) {
+ int dmotion;
+ if ( bl->type&BL_PC ) {
+ if (bst->agi == st->agi)
+ st->dmotion = status->calc_dmotion(bl, sc, bst->dmotion);
+ else {
+ dmotion = 800-st->agi*4;
+ st->dmotion = cap_value(dmotion, 400, 800);
+ if ( battle_config.pc_damage_delay_rate != 100 )
+ st->dmotion = st->dmotion*battle_config.pc_damage_delay_rate / 100;
+ //It's safe to ignore bst->dmotion since no bonus affects it.
+ st->dmotion = status->calc_dmotion(bl, sc, st->dmotion);
+ }
+ } else if ( bl->type&BL_HOM ) {
+ dmotion = 800 - st->agi * 4;
+ st->dmotion = cap_value(dmotion, 400, 800);
+ st->dmotion = status->calc_dmotion(bl, sc, bst->dmotion);
+ } else { // mercenary and mobs
+ st->dmotion = status->calc_dmotion(bl, sc, bst->dmotion);
+ }
+ }
if(flag&SCB_ASPD) {
int amotion;
- if( bl->type&BL_PC ) {
- 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;
+ if ( bl->type&BL_HOM ) {
+#ifdef RENEWAL
+ amotion = ((TBL_HOM*)bl)->homunculusDB->baseASPD;
+ amotion = amotion - amotion * status_get_homdex(bl) / 1000 - status_get_homagi(bl) * amotion / 250;
+ amotion = (amotion * status->calc_aspd(bl, sc, 1) + status->calc_aspd(bl, sc, 2)) / -100 + amotion;
#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;
+ amotion = (1000 - 4 * st->agi - st->dex) * ((TBL_HOM*)bl)->homunculusDB->baseASPD / 1000;
- 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;
+ amotion = status->calc_aspd_rate(bl, sc, bst->aspd_rate);
- if(st->aspd_rate != 1000) // absolute percentage modifier
- amotion = ( 200 - (200-amotion/10) * st->aspd_rate / 1000 ) * 10;
+ if ( st->aspd_rate != 1000 )
+ amotion = amotion*st->aspd_rate / 1000;
#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);
+ st->amotion = cap_value(amotion, battle_config.max_aspd, 2000);
- st->adelay = 2*st->amotion;
- } else if( bl->type&BL_HOM ) {
-#ifdef RENEWAL
- amotion = (1000 - 2*st->agi - st->dex) * ((TBL_HOM*)bl)->homunculusDB->baseASPD/1000;
-#else
- amotion = (1000 - 4*st->agi - st->dex) * ((TBL_HOM*)bl)->homunculusDB->baseASPD/1000;
-#endif
+ st->adelay = st->amotion;
+ } else if ( bl->type&BL_PC ) {
+ 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;
+
+ if ( st->aspd_rate != 1000 ) // absolute percentage modifier
+ amotion = (200 - (200 - amotion / 10) * st->aspd_rate / 1000) * 10;
+#endif
amotion = status->calc_fix_aspd(bl, sc, amotion);
- st->amotion = cap_value(amotion,battle_config.max_aspd,2000);
+ st->amotion = cap_value(amotion, ((sd->class_&JOBL_THIRD) ? battle_config.max_third_aspd : battle_config.max_aspd), 2000);
- st->adelay = st->amotion;
+ st->adelay = 2 * st->amotion;
} else { // mercenary and mobs
amotion = bst->amotion;
st->aspd_rate = status->calc_aspd_rate(bl, sc, bst->aspd_rate);
- if(st->aspd_rate != 1000)
- amotion = amotion*st->aspd_rate/1000;
+ if ( st->aspd_rate != 1000 )
+ amotion = amotion*st->aspd_rate / 1000;
amotion = status->calc_fix_aspd(bl, sc, amotion);
st->amotion = cap_value(amotion, battle_config.monster_max_aspd, 2000);
- temp = bst->adelay*st->aspd_rate/1000;
- st->adelay = cap_value(temp, battle_config.monster_max_aspd*2, 4000);
- }
- }
-
- if(flag&SCB_DSPD) {
- int dmotion;
- if( bl->type&BL_PC ) {
- if (bst->agi == st->agi)
- st->dmotion = status->calc_dmotion(bl, sc, bst->dmotion);
- else {
- dmotion = 800-st->agi*4;
- st->dmotion = cap_value(dmotion, 400, 800);
- if(battle_config.pc_damage_delay_rate != 100)
- st->dmotion = st->dmotion*battle_config.pc_damage_delay_rate/100;
- //It's safe to ignore bst->dmotion since no bonus affects it.
- st->dmotion = status->calc_dmotion(bl, sc, st->dmotion);
- }
- } else if( bl->type&BL_HOM ) {
- dmotion = 800-st->agi*4;
- st->dmotion = cap_value(dmotion, 400, 800);
- st->dmotion = status->calc_dmotion(bl, sc, bst->dmotion);
- } else { // mercenary and mobs
- st->dmotion = status->calc_dmotion(bl, sc, bst->dmotion);
+ temp = bst->adelay*st->aspd_rate / 1000;
+ st->adelay = cap_value(temp, battle_config.monster_max_aspd * 2, 4000);
}
}
@@ -4185,6 +3952,245 @@ void status_calc_bl_(struct block_list *bl, enum scb_flag flag, enum e_status_ca
clif->mercenary_updatestatus(ed->master, SP_SP);
}
}
+//Checks whether the source can see and chase target.
+int status_check_visibility(struct block_list *src, struct block_list *target) {
+ int view_range;
+ struct status_change *tsc = NULL;
+
+ switch ( src->type ) {
+ case BL_MOB:
+ view_range = ((TBL_MOB*)src)->min_chase;
+ break;
+ case BL_PET:
+ view_range = ((TBL_PET*)src)->db->range2;
+ break;
+ default:
+ view_range = AREA_SIZE;
+ }
+
+ if ( src->m != target->m || !check_distance_bl(src, target, view_range) )
+ return 0;
+
+ if ( src->type == BL_NPC ) /* NPCs don't care for the rest */
+ return 1;
+
+ if ( (tsc = status->get_sc(target)) ) {
+ struct status_data *st = status->get_status_data(src);
+
+ switch ( target->type ) { //Check for chase-walk/hiding/cloaking opponents.
+ case BL_PC:
+ if ( tsc->data[SC_CLOAKINGEXCEED] && !(st->mode&MD_BOSS) )
+ return 0;
+ if ( (tsc->option&(OPTION_HIDE | OPTION_CLOAK | OPTION_CHASEWALK) || tsc->data[SC_STEALTHFIELD] || tsc->data[SC__INVISIBILITY] || tsc->data[SC_CAMOUFLAGE]) && !(st->mode&MD_BOSS) &&
+ (((TBL_PC*)target)->special_state.perfect_hiding || !(st->mode&MD_DETECTOR)) )
+ return 0;
+ break;
+ default:
+ if ( (tsc->option&(OPTION_HIDE | OPTION_CLOAK | OPTION_CHASEWALK) || tsc->data[SC_CAMOUFLAGE]) && !(st->mode&(MD_BOSS | MD_DETECTOR)) )
+ return 0;
+
+ }
+ }
+
+ return 1;
+}
+
+// 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]);
+
+ 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);
+
+#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
+
+ // 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;
+
+ return amotion;
+}
+
+unsigned short status_base_atk(const struct block_list *bl, const struct status_data *st) {
+ int flag = 0, str, dex, dstr;
+
+ if ( !(bl->type&battle_config.enable_baseatk) )
+ return 0;
+
+ if ( bl->type == BL_PC )
+ switch ( ((TBL_PC*)bl)->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:
+ flag = 1;
+ }
+ if ( flag ) {
+#ifdef RENEWAL
+ dstr =
+#endif
+ str = st->dex;
+ dex = st->str;
+ } else {
+#ifdef RENEWAL
+ dstr =
+#endif
+ str = st->str;
+ dex = st->dex;
+ }
+ //Normally only players have base-atk, but homunc have a different batk
+ // equation, hinting that perhaps non-players should use this for batk.
+ // [Skotlex]
+#ifdef RENEWAL
+ if ( bl->type == BL_HOM )
+ str = 2 * (((TBL_HOM*)bl)->homunculus.level + status_get_homstr(bl));
+#else
+ dstr = str / 10;
+ str += dstr*dstr;
+#endif
+ if ( bl->type == BL_PC )
+#ifdef RENEWAL
+ str = (int)(dstr + (float)dex / 5 + (float)st->luk / 3 + (float)((TBL_PC*)bl)->status.base_level / 4);
+ else if ( bl->type == BL_MOB )
+ str = dstr + ((TBL_MOB*)bl)->level;
+#else
+ str += dex / 5 + st->luk / 5;
+#endif
+ return cap_value(str, 0, USHRT_MAX);
+}
+
+#ifndef RENEWAL
+static inline unsigned short status_base_matk_min(const struct status_data *st) { return st->int_ + (st->int_ / 7)*(st->int_ / 7); }
+#endif // not RENEWAL
+static inline unsigned short status_base_matk_max(const struct status_data *st) { return st->int_ + (st->int_ / 5)*(st->int_ / 5); }
+
+unsigned short status_base_matk(struct block_list *bl, const struct status_data *st, int level) {
+#ifdef RENEWAL
+ switch ( bl->type ) {
+ case BL_MOB:
+ return st->int_ + level;
+ case BL_HOM:
+ return status_get_homint(bl) + level;
+ case BL_PC:
+ default: // temporary until all are formulated
+ return st->int_ + (st->int_ / 2) + (st->dex / 5) + (st->luk / 3) + (level / 4);
+ }
+#else
+ return 0;
+#endif
+}
+
+//Fills in the misc data that can be calculated from the other status info (except for level)
+void status_calc_misc(struct block_list *bl, struct status_data *st, int level) {
+ //Non players get the value set, players need to stack with previous bonuses.
+ if ( bl->type != BL_PC )
+ st->batk =
+ st->hit = st->flee =
+ st->def2 = st->mdef2 =
+ st->cri = st->flee2 = 0;
+
+#ifdef RENEWAL // renewal formulas
+ 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->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);
+ st->rhw.atk = (status_get_homstr(bl) + status_get_homdex(bl)) / 5;
+ st->rhw.atk2 = (status_get_homluk(bl) + status_get_homstr(bl) + status_get_homdex(bl)) / 3;
+ } else {
+ st->hit += level + st->dex + (bl->type == BL_PC ? st->luk / 3 + 175 : 150); //base level + ( every 1 dex = +1 hit ) + (every 3 luk = +1 hit) + 175
+ st->flee += level + st->agi + (bl->type == BL_PC ? st->luk / 5 : 0) + 100; //base level + ( every 1 agi = +1 flee ) + (every 5 luk = +1 flee) + 100
+ st->def2 += (int)(((float)level + st->vit) / 2 + (bl->type == BL_PC ? ((float)st->agi / 5) : 0)); //base level + (every 2 vit = +1 def) + (every 5 agi = +1 def)
+ st->mdef2 += (int)(bl->type == BL_PC ? (st->int_ + ((float)level / 4) + ((float)(st->dex + st->vit) / 5)) : ((float)(st->int_ + level) / 4)); //(every 4 base level = +1 mdef) + (every 1 int = +1 mdef) + (every 5 dex = +1 mdef) + (every 5 vit = +1 mdef)
+ }
+#else // not RENEWAL
+ st->matk_min = status_base_matk_min(st);
+ st->matk_max = status_base_matk_max(st);
+ st->hit += level + st->dex;
+ st->flee += level + st->agi;
+ st->def2 += st->vit;
+ st->mdef2 += st->int_ + (st->vit >> 1);
+#endif // RENEWAL
+
+ if ( bl->type&battle_config.enable_critical )
+ st->cri += 10 + (st->luk * 10 / 3); //(every 1 luk = +0.3 critical)
+ else
+ st->cri = 0;
+
+ if ( bl->type&battle_config.enable_perfect_flee )
+ st->flee2 += st->luk + 10; //(every 10 luk = +1 perfect flee)
+ else
+ st->flee2 = 0;
+
+ if ( st->batk ) {
+ int temp = st->batk + status->base_atk(bl, st);
+ st->batk = cap_value(temp, 0, USHRT_MAX);
+ } else
+ st->batk = status->base_atk(bl, st);
+ if ( st->cri )
+ switch ( bl->type ) {
+ case BL_MOB:
+ if ( battle_config.mob_critical_rate != 100 )
+ st->cri = st->cri*battle_config.mob_critical_rate / 100;
+ if ( !st->cri && battle_config.mob_critical_rate )
+ st->cri = 10;
+ break;
+ case BL_PC:
+ //Players don't have a critical adjustment setting as of yet.
+ break;
+ case BL_MER:
+#ifdef RENEWAL
+ st->matk_min = st->matk_max = status_base_matk_max(st);
+ st->def2 = st->vit + level / 10 + st->vit / 5;
+ st->mdef2 = level / 10 + st->int_ / 5;
+#endif
+ break;
+ default:
+ if ( battle_config.critical_rate != 100 )
+ st->cri = st->cri*battle_config.critical_rate / 100;
+ if ( !st->cri && battle_config.critical_rate )
+ st->cri = 10;
+ }
+ if ( bl->type&BL_REGEN )
+ status->calc_regen(bl, st, status->get_regen_data(bl));
+}
/*==========================================
* Apply shared stat mods from status changes [DracoRPG]
@@ -4194,14 +4200,14 @@ unsigned short status_calc_str(struct block_list *bl, struct status_change *sc,
if(!sc || !sc->count)
return cap_value(str,0,USHRT_MAX);
+ if(sc->data[SC_FULL_THROTTLE])
+ str += str * 20 / 100;
if(sc->data[SC_HARMONIZE]) {
str -= sc->data[SC_HARMONIZE]->val2;
return (unsigned short)cap_value(str,0,USHRT_MAX);
}
if(sc->data[SC_BEYOND_OF_WARCRY])
str += sc->data[SC_BEYOND_OF_WARCRY]->val3;
- if(sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_HIGH && str < 50)
- return 50;
if(sc->data[SC_INCALLSTATUS])
str += sc->data[SC_INCALLSTATUS]->val1;
if(sc->data[SC_CHASEWALK2])
@@ -4232,6 +4238,8 @@ unsigned short status_calc_str(struct block_list *bl, struct status_change *sc,
str -= ((sc->data[SC_MARIONETTE_MASTER]->val3)>>16)&0xFF;
if(sc->data[SC_MARIONETTE])
str += ((sc->data[SC_MARIONETTE]->val3)>>16)&0xFF;
+ if(sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_HIGH)
+ str += ((sc->data[SC_SOULLINK]->val3)>>16)&0xFF;
if(sc->data[SC_GIANTGROWTH])
str += 30;
if(sc->data[SC_SAVAGE_STEAK])
@@ -4242,8 +4250,6 @@ unsigned short status_calc_str(struct block_list *bl, struct status_change *sc,
str -= sc->data[SC_STOMACHACHE]->val1;
if(sc->data[SC_KYOUGAKU])
str -= sc->data[SC_KYOUGAKU]->val3;
- if(sc->data[SC_FULL_THROTTLE])
- str += str * 20 / 100;
return (unsigned short)cap_value(str,0,USHRT_MAX);
}
@@ -4253,12 +4259,12 @@ unsigned short status_calc_agi(struct block_list *bl, struct status_change *sc,
if(!sc || !sc->count)
return cap_value(agi,0,USHRT_MAX);
+ if(sc->data[SC_FULL_THROTTLE])
+ agi += agi * 20 / 100;
if(sc->data[SC_HARMONIZE]) {
agi -= sc->data[SC_HARMONIZE]->val2;
return (unsigned short)cap_value(agi,0,USHRT_MAX);
}
- if(sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_HIGH && agi < 50)
- return 50;
if(sc->data[SC_CONCENTRATION] && !sc->data[SC_QUAGMIRE])
agi += (agi-sc->data[SC_CONCENTRATION]->val3)*sc->data[SC_CONCENTRATION]->val2/100;
if(sc->data[SC_INCALLSTATUS])
@@ -4287,6 +4293,8 @@ unsigned short status_calc_agi(struct block_list *bl, struct status_change *sc,
agi -= ((sc->data[SC_MARIONETTE_MASTER]->val3)>>8)&0xFF;
if(sc->data[SC_MARIONETTE])
agi += ((sc->data[SC_MARIONETTE]->val3)>>8)&0xFF;
+ if(sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_HIGH)
+ agi += ((sc->data[SC_SOULLINK]->val3)>>8)&0xFF;
if(sc->data[SC_ADORAMUS])
agi -= sc->data[SC_ADORAMUS]->val2;
if(sc->data[SC_DROCERA_HERB_STEAMED])
@@ -4300,8 +4308,6 @@ unsigned short status_calc_agi(struct block_list *bl, struct status_change *sc,
if(sc->data[SC_MARSHOFABYSS])
agi -= agi * sc->data[SC_MARSHOFABYSS]->val2 / 100;
- if(sc->data[SC_FULL_THROTTLE])
- agi += agi * 20 / 100;
return (unsigned short)cap_value(agi,0,USHRT_MAX);
}
@@ -4311,12 +4317,12 @@ unsigned short status_calc_vit(struct block_list *bl, struct status_change *sc,
if(!sc || !sc->count)
return cap_value(vit,0,USHRT_MAX);
+ if(sc->data[SC_FULL_THROTTLE])
+ vit += vit * 20 / 100;
if(sc->data[SC_HARMONIZE]) {
vit -= sc->data[SC_HARMONIZE]->val2;
return (unsigned short)cap_value(vit,0,USHRT_MAX);
}
- if(sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_HIGH && vit < 50)
- return 50;
if(sc->data[SC_INCALLSTATUS])
vit += sc->data[SC_INCALLSTATUS]->val1;
if(sc->data[SC_INCVIT])
@@ -4335,6 +4341,8 @@ unsigned short status_calc_vit(struct block_list *bl, struct status_change *sc,
vit -= sc->data[SC_MARIONETTE_MASTER]->val3&0xFF;
if(sc->data[SC_MARIONETTE])
vit += sc->data[SC_MARIONETTE]->val3&0xFF;
+ if(sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_HIGH)
+ vit += sc->data[SC_SOULLINK]->val3&0xFF;
if(sc->data[SC_LAUDAAGNUS])
vit += 4 + sc->data[SC_LAUDAAGNUS]->val1;
if(sc->data[SC_MINOR_BBQ])
@@ -4348,8 +4356,6 @@ unsigned short status_calc_vit(struct block_list *bl, struct status_change *sc,
if(sc->data[SC_NOEQUIPARMOR])
vit -= vit * sc->data[SC_NOEQUIPARMOR]->val2/100;
- if(sc->data[SC_FULL_THROTTLE])
- vit += vit * 20 / 100;
return (unsigned short)cap_value(vit,0,USHRT_MAX);
}
@@ -4359,14 +4365,14 @@ unsigned short status_calc_int(struct block_list *bl, struct status_change *sc,
if(!sc || !sc->count)
return cap_value(int_,0,USHRT_MAX);
+ if(sc->data[SC_FULL_THROTTLE])
+ int_ += int_ * 20 / 100;
if(sc->data[SC_HARMONIZE]) {
int_ -= sc->data[SC_HARMONIZE]->val2;
return (unsigned short)cap_value(int_,0,USHRT_MAX);
}
if(sc->data[SC_MELODYOFSINK])
int_ -= sc->data[SC_MELODYOFSINK]->val3;
- if(sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_HIGH && int_ < 50)
- return 50;
if(sc->data[SC_INCALLSTATUS])
int_ += sc->data[SC_INCALLSTATUS]->val1;
if(sc->data[SC_INCINT])
@@ -4393,6 +4399,8 @@ unsigned short status_calc_int(struct block_list *bl, struct status_change *sc,
int_ -= ((sc->data[SC_MARIONETTE_MASTER]->val4)>>16)&0xFF;
if(sc->data[SC_MARIONETTE])
int_ += ((sc->data[SC_MARIONETTE]->val4)>>16)&0xFF;
+ if(sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_HIGH)
+ int_ += ((sc->data[SC_SOULLINK]->val4)>>16)&0xFF;
if(sc->data[SC_MANDRAGORA])
int_ -= 4 * sc->data[SC_MANDRAGORA]->val1;
if(sc->data[SC_COCKTAIL_WARG_BLOOD])
@@ -4410,8 +4418,6 @@ unsigned short status_calc_int(struct block_list *bl, struct status_change *sc,
if(sc->data[SC__STRIPACCESSARY])
int_ -= int_ * sc->data[SC__STRIPACCESSARY]->val2 / 100;
}
- if(sc->data[SC_FULL_THROTTLE])
- int_ += int_ * 20 / 100;
return (unsigned short)cap_value(int_,0,USHRT_MAX);
}
@@ -4421,12 +4427,12 @@ unsigned short status_calc_dex(struct block_list *bl, struct status_change *sc,
if(!sc || !sc->count)
return cap_value(dex,0,USHRT_MAX);
+ if(sc->data[SC_FULL_THROTTLE])
+ dex += dex * 20 / 100;
if(sc->data[SC_HARMONIZE]) {
dex -= sc->data[SC_HARMONIZE]->val2;
return (unsigned short)cap_value(dex,0,USHRT_MAX);
}
- if(sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_HIGH && dex < 50)
- return 50;
if(sc->data[SC_CONCENTRATION] && !sc->data[SC_QUAGMIRE])
dex += (dex-sc->data[SC_CONCENTRATION]->val4)*sc->data[SC_CONCENTRATION]->val2/100;
if(sc->data[SC_INCALLSTATUS])
@@ -4457,6 +4463,8 @@ unsigned short status_calc_dex(struct block_list *bl, struct status_change *sc,
dex -= ((sc->data[SC_MARIONETTE_MASTER]->val4)>>8)&0xFF;
if(sc->data[SC_MARIONETTE])
dex += ((sc->data[SC_MARIONETTE]->val4)>>8)&0xFF;
+ if(sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_HIGH)
+ dex += ((sc->data[SC_SOULLINK]->val4)>>8)&0xFF;
if(sc->data[SC_SIROMA_ICE_TEA])
dex += sc->data[SC_SIROMA_ICE_TEA]->val1;
if(sc->data[SC_INSPIRATION])
@@ -4470,8 +4478,6 @@ unsigned short status_calc_dex(struct block_list *bl, struct status_change *sc,
dex -= dex * sc->data[SC_MARSHOFABYSS]->val2 / 100;
if(sc->data[SC__STRIPACCESSARY] && bl->type != BL_PC)
dex -= dex * sc->data[SC__STRIPACCESSARY]->val2 / 100;
- if(sc->data[SC_FULL_THROTTLE])
- dex += dex * 20 / 100;
return (unsigned short)cap_value(dex,0,USHRT_MAX);
}
@@ -4481,14 +4487,14 @@ unsigned short status_calc_luk(struct block_list *bl, struct status_change *sc,
if(!sc || !sc->count)
return cap_value(luk,0,USHRT_MAX);
+ if(sc->data[SC_FULL_THROTTLE])
+ luk += luk * 20 / 100;
if(sc->data[SC_HARMONIZE]) {
luk -= sc->data[SC_HARMONIZE]->val2;
return (unsigned short)cap_value(luk,0,USHRT_MAX);
}
if(sc->data[SC_CURSE])
return 0;
- if(sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_HIGH && luk < 50)
- return 50;
if(sc->data[SC_INCALLSTATUS])
luk += sc->data[SC_INCALLSTATUS]->val1;
if(sc->data[SC_INCLUK])
@@ -4505,6 +4511,8 @@ unsigned short status_calc_luk(struct block_list *bl, struct status_change *sc,
luk -= sc->data[SC_MARIONETTE_MASTER]->val4&0xFF;
if(sc->data[SC_MARIONETTE])
luk += sc->data[SC_MARIONETTE]->val4&0xFF;
+ if(sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_HIGH)
+ luk += sc->data[SC_SOULLINK]->val4&0xFF;
if(sc->data[SC_PUTTI_TAILS_NOODLES])
luk += sc->data[SC_PUTTI_TAILS_NOODLES]->val1;
if(sc->data[SC_INSPIRATION])
@@ -4520,8 +4528,6 @@ unsigned short status_calc_luk(struct block_list *bl, struct status_change *sc,
luk -= luk * sc->data[SC__STRIPACCESSARY]->val2 / 100;
if(sc->data[SC_BANANA_BOMB])
luk -= luk * sc->data[SC_BANANA_BOMB]->val1 / 100;
- if(sc->data[SC_FULL_THROTTLE])
- luk += luk * 20 / 100;
return (unsigned short)cap_value(luk,0,USHRT_MAX);
}
@@ -4837,6 +4843,8 @@ signed short status_calc_hit(struct block_list *bl, struct status_change *sc, in
hit += hit * sc->data[SC_INCHITRATE]->val1/100;
if(sc->data[SC_BLIND])
hit -= hit * 25/100;
+ if(sc->data[SC_FIRE_EXPANSION_TEAR_GAS])
+ hit -= hit * 50 / 100;
if(sc->data[SC__GROOMY])
hit -= hit * sc->data[SC__GROOMY]->val3 / 100;
if(sc->data[SC_FEAR])
@@ -4922,6 +4930,10 @@ signed short status_calc_flee(struct block_list *bl, struct status_change *sc, i
flee -= flee * ( 20 + 5 * sc->data[SC_GLOOMYDAY]->val1 ) / 100;
if( sc->data[SC_SATURDAY_NIGHT_FEVER] )
flee -= flee * (40 + 10 * sc->data[SC_SATURDAY_NIGHT_FEVER]->val1) / 100;
+ if ( sc->data[SC_FIRE_EXPANSION_SMOKE_POWDER] )
+ flee += flee * 20 / 100;
+ if ( sc->data[SC_FIRE_EXPANSION_TEAR_GAS] )
+ flee -= flee * 50 / 100;
if( sc->data[SC_WIND_STEP_OPTION] )
flee += flee * sc->data[SC_WIND_STEP_OPTION]->val2 / 100;
if( sc->data[SC_ZEPHYR] )
@@ -5371,7 +5383,7 @@ unsigned short status_calc_speed(struct block_list *bl, struct status_change *sc
if( sc->data[SC_WIND_STEP_OPTION] )
val = max( val, sc->data[SC_WIND_STEP_OPTION]->val2 );
if( sc->data[SC_FULL_THROTTLE] )
- val = max( val, 30);
+ val = max( val, 25);
//FIXME: official items use a single bonus for this [ultramage]
if( sc->data[SC_MOVHASTE_HORSE] ) // temporary item-based speedup
val = max( val, 25 );
@@ -5544,7 +5556,7 @@ short status_calc_fix_aspd(struct block_list *bl, struct status_change *sc, int
aspd -= 10;
if (sc->data[SC_OVERED_BOOST]) // should be final and unmodifiable by any means
- aspd = 2000 - sc->data[SC_OVERED_BOOST]->val3 * 10;
+ aspd = (200 - sc->data[SC_OVERED_BOOST]->val3) * 10;
return cap_value(aspd, 0, 2000); // will be recap for proper bl anyway
}
@@ -7231,9 +7243,13 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
if (sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
status_change_end(bl, SC_STONE, INVALID_TIMER);
}
+ if(sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_HIGH)
+ status_change_end(bl, SC_SOULLINK, INVALID_TIMER);
break;
case SC_INC_AGI:
status_change_end(bl, SC_DEC_AGI, INVALID_TIMER);
+ if(sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_HIGH)
+ status_change_end(bl, SC_SOULLINK, INVALID_TIMER);
break;
case SC_QUAGMIRE:
status_change_end(bl, SC_CONCENTRATION, INVALID_TIMER);
@@ -8051,6 +8067,23 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
stat = (psce->val4 >> 0)&0xFF; stat = min(stat, max_stat - tst->luk ); val4 |= cap_value(stat,0,0xFF);
}
break;
+ case SC_SOULLINK:
+ //1st Transcendent Spirit works similar to Marionette Control
+ if(sd && val2 == SL_HIGH) {
+ int stat,max_stat;
+ // Fetch target's stats
+ struct status_data* status2 = status->get_status_data(bl); // Battle status
+ val3 = 0;
+ val4 = 0;
+ max_stat = (status->get_lv(bl)-10<50)?status->get_lv(bl)-10:50;
+ stat = max(0, max_stat - status2->str ); val3 |= cap_value(stat,0,0xFF)<<16;
+ stat = max(0, max_stat - status2->agi ); val3 |= cap_value(stat,0,0xFF)<<8;
+ stat = max(0, max_stat - status2->vit ); val3 |= cap_value(stat,0,0xFF);
+ stat = max(0, max_stat - status2->int_); val4 |= cap_value(stat,0,0xFF)<<16;
+ stat = max(0, max_stat - status2->dex ); val4 |= cap_value(stat,0,0xFF)<<8;
+ stat = max(0, max_stat - status2->luk ); val4 |= cap_value(stat,0,0xFF);
+ }
+ break;
case SC_SWORDREJECT:
val2 = 15*val1; //Reflect chance
val3 = 3; //Reflections
@@ -11409,10 +11442,20 @@ int status_get_weapon_atk(struct block_list *bl, struct weapon_atk *watk, int fl
min = (int)(watk->atk - variance + strdex_bonus) + watk->atk2;
max = (int)(watk->atk + variance + strdex_bonus) + watk->atk2;
- }else if( watk->atk ){
+ }
+ else if (bl->type == BL_MOB && watk->atk){
min = watk->atk * 80 / 100;
max = watk->atk * 120 / 100;
}
+ else if (bl->type == BL_HOM && watk->atk){
+ if (flag & 4){
+ max = min = status->get_matk(bl, 2);
+ }
+ else{
+ min = watk->atk;
+ max = watk->atk2;
+ }
+ }
if( !(flag&1) ){
if( max > min )
@@ -11421,8 +11464,15 @@ int status_get_weapon_atk(struct block_list *bl, struct weapon_atk *watk, int fl
max = min;
}
- if( bl->type == BL_PC && ((TBL_PC*)bl)->right_weapon.overrefine > 0 && !(flag&2) )
- max += rnd()%((TBL_PC*)bl)->right_weapon.overrefine + 1;
+ if ( bl->type == BL_PC && !(flag & 2) ) {
+ struct map_session_data *sd = (struct map_session_data *)bl;
+ 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 = (rnd() % 100) % ((status->refine_info[watk->wlv].randombonus_max[refine + (4 - watk->wlv)] / 100)) + 1;
+ max += r / 10;
+ }
+ }
max = status->calc_watk(bl, sc, max, false);
@@ -11433,31 +11483,21 @@ int status_get_weapon_atk(struct block_list *bl, struct weapon_atk *watk, int fl
}
/**
- * Gets a random matk value depending on min matk and max matk
- **/
-unsigned short status_get_rand_matk( unsigned short matk_max, unsigned short matk_min ) {
- if( matk_max > matk_min )
- return matk_min + rnd()%(matk_max - matk_min);
- else
- return matk_min;
-}
-
-/**
- * Get bl's matk_max and matk_min values depending on flag
- * @param flag
- * 0 - Get MATK
- * 1 - Get MATK w/o SC bonuses
- * 3 - Get MATK w/o EATK & SC bonuses
- **/
-void status_get_matk_sub( struct block_list *bl, int flag, unsigned short *matk_max, unsigned short *matk_min ) {
+* Get bl's matk_max and matk_min values depending on flag
+* @param flag
+* 0 - Get MATK
+* 1 - Get MATK w/o SC bonuses
+* 3 - Get MATK w/o EATK & SC bonuses
+**/
+void status_get_matk_sub(struct block_list *bl, int flag, unsigned short *matk_max, unsigned short *matk_min) {
struct status_data *st;
struct status_change *sc;
struct map_session_data *sd;
- if( bl == NULL )
+ if ( bl == NULL )
return;
- if( flag != 0 && flag != 1 && flag != 3 ) {
+ if ( flag != 0 && flag != 1 && flag != 3 ) {
ShowError("status_get_matk_sub: Unknown flag %d!\n", flag);
return;
}
@@ -11468,107 +11508,130 @@ void status_get_matk_sub( struct block_list *bl, int flag, unsigned short *matk_
#ifdef RENEWAL
/**
- * RE MATK Formula (from irowiki:http://irowiki.org/wiki/MATK)
- * MATK = (sMATK + wMATK + eMATK) * Multiplicative Modifiers
- **/
- *matk_min = status->base_matk(st, status->get_lv(bl));
+ * RE MATK Formula (from irowiki:http://irowiki.org/wiki/MATK)
+ * MATK = (sMATK + wMATK + eMATK) * Multiplicative Modifiers
+ **/
+ *matk_min = status->base_matk(bl, st, status->get_lv(bl));
// Any +MATK you get from skills and cards, including cards in weapon, is added here.
- if( sd && sd->bonus.ematk > 0 && flag != 3 )
+ if ( sd && sd->bonus.ematk > 0 && flag != 3 )
*matk_min += sd->bonus.ematk;
- if( flag != 3 )
+ if ( flag != 3 )
*matk_min = status->calc_ematk(bl, sc, *matk_min);
*matk_max = *matk_min;
- //This is the only portion in MATK that varies depending on the weapon level and refinement rate.
- if( bl->type&BL_PC && (st->rhw.matk + st->lhw.matk) > 0 ) {
- int wMatk = st->rhw.matk + st->lhw.matk; // Left and right matk stacks
- int variance = wMatk * st->rhw.wlv / 10; // Only use right hand weapon level
- *matk_min += wMatk - variance;
- *matk_max += wMatk + variance;
- } else if( bl->type&BL_MOB ) {
- *matk_min = *matk_max = status_get_int(bl) + status->get_lv(bl);
+ switch ( bl->type ) {
+ case BL_PC:
+ //This is the only portion in MATK that varies depending on the weapon level and refinement rate.
+ if ( (st->rhw.matk + st->lhw.matk) > 0 ) {
+ int wMatk = st->rhw.matk + st->lhw.matk; // Left and right matk stacks
+ int variance = wMatk * st->rhw.wlv / 10; // Only use right hand weapon level
+ *matk_min += wMatk - variance;
+ *matk_max += wMatk + variance;
+ }
+ break;
+ case BL_MOB:
*matk_min += 70 * ((TBL_MOB*)bl)->status.rhw.atk2 / 100;
*matk_max += 130 * ((TBL_MOB*)bl)->status.rhw.atk2 / 100;
+ break;
+ case BL_HOM:
+ *matk_min += (status_get_homint(bl) + status_get_homdex(bl)) / 5;
+ *matk_max += (status_get_homluk(bl) + status_get_homint(bl) + status_get_homdex(bl)) / 3;
+ break;
}
+
#else // not RENEWAL
- *matk_min = status_base_matk_min(st) + (sd?sd->bonus.ematk:0);
- *matk_max = status_base_matk_max(st) + (sd?sd->bonus.ematk:0);
+ *matk_min = status_base_matk_min(st) + (sd ? sd->bonus.ematk : 0);
+ *matk_max = status_base_matk_max(st) + (sd ? sd->bonus.ematk : 0);
#endif
- if (sd && sd->matk_rate != 100) {
- *matk_max = (*matk_max) * sd->matk_rate/100;
- *matk_min = (*matk_min) * sd->matk_rate/100;
+ if ( sd && sd->matk_rate != 100 ) {
+ *matk_max = (*matk_max) * sd->matk_rate / 100;
+ *matk_min = (*matk_min) * sd->matk_rate / 100;
}
- if ((bl->type&BL_HOM && battle_config.hom_setting&0x20) //Hom Min Matk is always the same as Max Matk
- || (sc && sc->data[SC_RECOGNIZEDSPELL]))
+ if ( (bl->type&BL_HOM && battle_config.hom_setting & 0x20) //Hom Min Matk is always the same as Max Matk
+ || (sc && sc->data[SC_RECOGNIZEDSPELL]) )
*matk_min = *matk_max;
#ifdef RENEWAL
- if( sd && sd->right_weapon.overrefine > 0 ) {
- (*matk_min)++;
- *matk_max += sd->right_weapon.overrefine - 1;
+ if ( sd && !(flag & 2) ) {
+ 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 = (rnd() % 100) % ((status->refine_info[sd->inventory_data[index]->wlv].randombonus_max[refine + (4 - sd->inventory_data[index]->wlv)] / 100)) + 1;
+ st->matk_max += r / 10;
+ }
}
#endif
return;
}
/**
- * Get bl's matk value depending on flag
- * @param flag [malufett]
- * 1 - Get MATK w/o SC bonuses
- * 2 - Get modified MATK
- * 3 - Get MATK w/o eATK & SC bonuses
- * @retval 1 failure
- * @retval MATK success
- *
- * Shouldn't change _any_ value! [Panikon]
- **/
-int status_get_matk( struct block_list *bl, int flag ) {
+* Gets a random matk value depending on min matk and max matk
+**/
+unsigned short status_get_rand_matk(unsigned short matk_max, unsigned short matk_min) {
+ if ( matk_max > matk_min )
+ return matk_min + rnd() % (matk_max - matk_min);
+ else
+ return matk_min;
+}
+
+/**
+* Get bl's matk value depending on flag
+* @param flag [malufett]
+* 1 - Get MATK w/o SC bonuses
+* 2 - Get modified MATK
+* 3 - Get MATK w/o eATK & SC bonuses
+* @retval 1 failure
+* @retval MATK success
+*
+* Shouldn't change _any_ value! [Panikon]
+**/
+int status_get_matk(struct block_list *bl, int flag) {
struct status_data *st;
unsigned short matk_max, matk_min;
- if( bl == NULL )
+ if ( bl == NULL )
return 1;
- if( flag < 1 || flag > 3 ) {
+ if ( flag < 1 || flag > 3 ) {
ShowError("status_get_matk: Unknown flag %d!\n", flag);
return 1;
}
- if( (st = status->get_status_data(bl)) == NULL )
+ if ( (st = status->get_status_data(bl)) == NULL )
return 0;
// Just get matk
- if( flag == 2 )
+ if ( flag == 2 )
return status_get_rand_matk(st->matk_max, st->matk_min);
- status_get_matk_sub( bl, flag, &matk_max, &matk_min );
+ status_get_matk_sub(bl, flag, &matk_max, &matk_min);
// Get unmodified from sc matk
return status_get_rand_matk(matk_max, matk_min);
}
/**
- * Updates bl's MATK values
- **/
-void status_update_matk( struct block_list *bl ) {
+* Updates bl's MATK values
+**/
+void status_update_matk(struct block_list *bl) {
struct status_data *st;
struct status_change *sc;
unsigned short matk_max, matk_min;
- if( bl == NULL )
+ if ( bl == NULL )
return;
- if( (st = status->get_status_data(bl)) == NULL )
+ if ( (st = status->get_status_data(bl)) == NULL )
return;
- if( (sc = status->get_sc(bl)) == NULL )
+ if ( (sc = status->get_sc(bl)) == NULL )
return;
- status_get_matk_sub( bl, 0, &matk_max, &matk_min );
+ status_get_matk_sub(bl, 0, &matk_max, &matk_min);
// Update matk
st->matk_min = status->calc_matk(bl, sc, matk_min, true);
diff --git a/src/map/status.h b/src/map/status.h
index 00c243543..63f9854d5 100644
--- a/src/map/status.h
+++ b/src/map/status.h
@@ -1939,6 +1939,13 @@ struct status_change {
#define status_get_size(bl) (status->get_status_data(bl)->size)
#define status_get_mode(bl) (status->get_status_data(bl)->mode)
+#define status_get_homstr(bl) (st->str + ((TBL_HOM*)bl)->homunculus.str_value)
+#define status_get_homagi(bl) (st->agi + ((TBL_HOM*)bl)->homunculus.agi_value)
+#define status_get_homvit(bl) (st->vit + ((TBL_HOM*)bl)->homunculus.vit_value)
+#define status_get_homint(bl) (st->int_ + ((TBL_HOM*)bl)->homunculus.int_value)
+#define status_get_homdex(bl) (st->dex + ((TBL_HOM*)bl)->homunculus.dex_value)
+#define status_get_homluk(bl) (st->luk + ((TBL_HOM*)bl)->homunculus.luk_value)
+
//Short version, receives rate in 1->100 range, and does not uses a flag setting.
#define sc_start(src, bl, type, rate, val1, tick) (status->change_start((src),(bl),(type),100*(rate),(val1),0,0,0,(tick),SCFLAG_NONE))
#define sc_start2(src, bl, type, rate, val1, val2, tick) (status->change_start((src),(bl),(type),100*(rate),(val1),(val2),0,0,(tick),SCFLAG_NONE))
@@ -2062,7 +2069,7 @@ struct status_interface {
defType (*calc_mdef) (struct block_list *bl, struct status_change *sc, int mdef, bool viewable);
short (*calc_mdef2) (struct block_list *bl, struct status_change *sc, int mdef2, bool viewable);
unsigned short (*calc_batk)(struct block_list *bl, struct status_change *sc, int batk, bool viewable);
- unsigned short (*base_matk) (const struct status_data *st, int level);
+ unsigned short(*base_matk) (struct block_list *bl, const struct status_data *st, int level);
int (*get_weapon_atk) (struct block_list *src, struct weapon_atk *watk, int flag);
int (*get_total_mdef) (struct block_list *src);
int (*get_total_def) (struct block_list *src);
diff --git a/src/map/unit.c b/src/map/unit.c
index 2ab13b121..64885541f 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -100,6 +100,13 @@ int unit_walktoxy_sub(struct block_list *bl)
if( !path->search(&wpd,bl->m,bl->x,bl->y,ud->to_x,ud->to_y,ud->state.walk_easy,CELL_CHKNOPASS) )
return 0;
+#ifdef OFFICIAL_WALKPATH
+ if( !path->search_long(NULL, bl->m, bl->x, bl->y, ud->to_x, ud->to_y, CELL_CHKNOPASS) // Check if there is an obstacle between
+ && wpd.path_len > 14 // Official number of walkable cells is 14 if and only if there is an obstacle between. [malufett]
+ && (bl->type != BL_NPC) ) // If type is a NPC, please disregard.
+ return 0;
+#endif
+
memcpy(&ud->walkpath,&wpd,sizeof(wpd));
if (ud->target_to && ud->chaserange>1) {
@@ -391,8 +398,14 @@ int unit_walktoxy_timer(int tid, int64 tick, int id, intptr_t data) {
ud->steptimer = timer->add(tick+i, unit->step_timer, bl->id, 0);
}
- if(ud->state.change_walk_target)
- return unit->walktoxy_sub(bl);
+ if(ud->state.change_walk_target) {
+ if(unit->walktoxy_sub(bl)) {
+ return 1;
+ } else {
+ clif->fixpos(bl);
+ return 0;
+ }
+ }
ud->walkpath.path_pos++;
if(ud->walkpath.path_pos>=ud->walkpath.path_len)
@@ -572,6 +585,10 @@ int unit_walktobl(struct block_list *bl, struct block_list *tbl, int range, int
ud->to_y = bl->y;
ud->target_to = 0;
return 0;
+ } else if (range == 0) {
+ //Should walk on the same cell as target (for looters)
+ ud->to_x = tbl->x;
+ ud->to_y = tbl->y;
}
ud->state.walk_easy = flag&1;
@@ -1131,6 +1148,10 @@ int unit_set_walkdelay(struct block_list *bl, int64 tick, int delay, int type) {
if (delay <= 0 || !ud) return 0;
if (type) {
+ //Bosses can ignore skill induced walkdelay (but not damage induced)
+ if(bl->type == BL_MOB && (((TBL_MOB*)bl)->status.mode&MD_BOSS))
+ return 0;
+ //Make sure walk delay is not decreased
if (DIFF_TICK(ud->canmove_tick, tick+delay) > 0)
return 0;
} else {
@@ -1294,31 +1315,31 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
tstatus = status->get_status_data(target);
// Record the status of the previous skill)
- if(sd) {
+ if (sd) {
- if( (skill->get_inf2(skill_id)&INF2_ENSEMBLE_SKILL) && skill->check_pc_partner(sd, skill_id, &skill_lv, 1, 0) < 1 ) {
- clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
+ if ((skill->get_inf2(skill_id)&INF2_ENSEMBLE_SKILL) && skill->check_pc_partner(sd, skill_id, &skill_lv, 1, 0) < 1) {
+ clif->skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0);
return 0;
}
- switch(skill_id){
+ switch (skill_id){
case SA_CASTCANCEL:
- if(ud->skill_id != skill_id){
+ if (ud->skill_id != skill_id){
sd->skill_id_old = ud->skill_id;
sd->skill_lv_old = ud->skill_lv;
}
break;
case BD_ENCORE:
//Prevent using the dance skill if you no longer have the skill in your tree.
- if(!sd->skill_id_dance || pc->checkskill(sd,sd->skill_id_dance)<=0){
- clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
+ if (!sd->skill_id_dance || pc->checkskill(sd, sd->skill_id_dance) <= 0){
+ clif->skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0);
return 0;
}
sd->skill_id_old = skill_id;
break;
case WL_WHITEIMPRISON:
- if( battle->check_target(src,target,BCT_SELF|BCT_ENEMY) < 0 ) {
- clif->skill_fail(sd,skill_id,USESKILL_FAIL_TOTARGET,0);
+ if (battle->check_target(src, target, BCT_SELF | BCT_ENEMY) < 0) {
+ clif->skill_fail(sd, skill_id, USESKILL_FAIL_TOTARGET, 0);
return 0;
}
break;
@@ -1329,13 +1350,20 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
sd->skill_lv_old = skill_lv;
break;
}
- /* temporarily disabled, awaiting for kenpachi to detail this so we can make it work properly */
+ }
+
+ 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 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 )
@@ -1619,14 +1647,6 @@ int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, ui
if( skill->not_ok(skill_id, sd) || !skill->check_condition_castbegin(sd, skill_id, skill_lv) )
return 0;
/**
- * "WHY IS IT HEREE": pneuma cannot be canceled past this point, the client displays the animation even,
- * if we cancel it from nodamage_id, so it has to be here for it to not display the animation.
- **/
- if( skill_id == AL_PNEUMA && map->getcell(src->m, skill_x, skill_y, CELL_CHKLANDPROTECTOR) ) {
- clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- /**
* "WHY IS IT HEREE": ice wall cannot be canceled past this point, the client displays the animation even,
* if we cancel it from castend_pos, so it has to be here for it to not display the animation.
**/
@@ -2310,7 +2330,7 @@ int unit_remove_map(struct block_list *bl, clr_type clrtype, const char* file, i
//Clear target even if there is no timer
if (ud->target || ud->attacktimer != INVALID_TIMER)
- unit_stop_attack(bl);
+ unit->stop_attack(bl);
//Clear stepaction even if there is no timer
if (ud->stepaction || ud->steptimer != INVALID_TIMER)
@@ -2660,10 +2680,7 @@ int unit_free(struct block_list *bl, clr_type clrtype) {
if( pd->s_skill )
{
if (pd->s_skill->timer != INVALID_TIMER) {
- if (pd->s_skill->id)
- timer->delete(pd->s_skill->timer, pet->skill_support_timer);
- else
- timer->delete(pd->s_skill->timer, pet->heal_timer);
+ timer->delete(pd->s_skill->timer, pet->skill_support_timer);
}
aFree(pd->s_skill);
pd->s_skill = NULL;
diff --git a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
index 6e982bb70..74e765cee 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
@@ -423,6 +423,8 @@ struct {
struct HPMHookPoint *HP_clif_send_post;
struct HPMHookPoint *HP_clif_send_sub_pre;
struct HPMHookPoint *HP_clif_send_sub_post;
+ struct HPMHookPoint *HP_clif_send_actual_pre;
+ struct HPMHookPoint *HP_clif_send_actual_post;
struct HPMHookPoint *HP_clif_parse_pre;
struct HPMHookPoint *HP_clif_parse_post;
struct HPMHookPoint *HP_clif_parse_cmd_pre;
@@ -505,6 +507,8 @@ struct {
struct HPMHookPoint *HP_clif_changetraplook_post;
struct HPMHookPoint *HP_clif_refreshlook_pre;
struct HPMHookPoint *HP_clif_refreshlook_post;
+ struct HPMHookPoint *HP_clif_sendlook_pre;
+ struct HPMHookPoint *HP_clif_sendlook_post;
struct HPMHookPoint *HP_clif_class_change_pre;
struct HPMHookPoint *HP_clif_class_change_post;
struct HPMHookPoint *HP_clif_skill_delunit_pre;
@@ -3301,12 +3305,16 @@ struct {
struct HPMHookPoint *HP_npc_parseview_post;
struct HPMHookPoint *HP_npc_viewisid_pre;
struct HPMHookPoint *HP_npc_viewisid_post;
+ struct HPMHookPoint *HP_npc_create_npc_pre;
+ struct HPMHookPoint *HP_npc_create_npc_post;
struct HPMHookPoint *HP_npc_add_warp_pre;
struct HPMHookPoint *HP_npc_add_warp_post;
struct HPMHookPoint *HP_npc_parse_warp_pre;
struct HPMHookPoint *HP_npc_parse_warp_post;
struct HPMHookPoint *HP_npc_parse_shop_pre;
struct HPMHookPoint *HP_npc_parse_shop_post;
+ struct HPMHookPoint *HP_npc_parse_unknown_object_pre;
+ struct HPMHookPoint *HP_npc_parse_unknown_object_post;
struct HPMHookPoint *HP_npc_convertlabel_db_pre;
struct HPMHookPoint *HP_npc_convertlabel_db_post;
struct HPMHookPoint *HP_npc_skip_script_pre;
@@ -3339,6 +3347,8 @@ struct {
struct HPMHookPoint *HP_npc_parse_mob_post;
struct HPMHookPoint *HP_npc_parse_mapflag_pre;
struct HPMHookPoint *HP_npc_parse_mapflag_post;
+ struct HPMHookPoint *HP_npc_parse_unknown_mapflag_pre;
+ struct HPMHookPoint *HP_npc_parse_unknown_mapflag_post;
struct HPMHookPoint *HP_npc_parsesrcfile_pre;
struct HPMHookPoint *HP_npc_parsesrcfile_post;
struct HPMHookPoint *HP_npc_script_event_pre;
@@ -3691,8 +3701,12 @@ struct {
struct HPMHookPoint *HP_pc_resethate_post;
struct HPMHookPoint *HP_pc_equipitem_pre;
struct HPMHookPoint *HP_pc_equipitem_post;
+ struct HPMHookPoint *HP_pc_equipitem_pos_pre;
+ struct HPMHookPoint *HP_pc_equipitem_pos_post;
struct HPMHookPoint *HP_pc_unequipitem_pre;
struct HPMHookPoint *HP_pc_unequipitem_post;
+ struct HPMHookPoint *HP_pc_unequipitem_pos_pre;
+ struct HPMHookPoint *HP_pc_unequipitem_pos_post;
struct HPMHookPoint *HP_pc_checkitem_pre;
struct HPMHookPoint *HP_pc_checkitem_post;
struct HPMHookPoint *HP_pc_useitem_pre;
@@ -3995,8 +4009,6 @@ struct {
struct HPMHookPoint *HP_pet_skill_bonus_timer_post;
struct HPMHookPoint *HP_pet_recovery_timer_pre;
struct HPMHookPoint *HP_pet_recovery_timer_post;
- struct HPMHookPoint *HP_pet_heal_timer_pre;
- struct HPMHookPoint *HP_pet_heal_timer_post;
struct HPMHookPoint *HP_pet_skill_support_timer_pre;
struct HPMHookPoint *HP_pet_skill_support_timer_post;
struct HPMHookPoint *HP_pet_read_db_pre;
@@ -5482,6 +5494,8 @@ struct {
int HP_clif_send_post;
int HP_clif_send_sub_pre;
int HP_clif_send_sub_post;
+ int HP_clif_send_actual_pre;
+ int HP_clif_send_actual_post;
int HP_clif_parse_pre;
int HP_clif_parse_post;
int HP_clif_parse_cmd_pre;
@@ -5564,6 +5578,8 @@ struct {
int HP_clif_changetraplook_post;
int HP_clif_refreshlook_pre;
int HP_clif_refreshlook_post;
+ int HP_clif_sendlook_pre;
+ int HP_clif_sendlook_post;
int HP_clif_class_change_pre;
int HP_clif_class_change_post;
int HP_clif_skill_delunit_pre;
@@ -8360,12 +8376,16 @@ struct {
int HP_npc_parseview_post;
int HP_npc_viewisid_pre;
int HP_npc_viewisid_post;
+ int HP_npc_create_npc_pre;
+ int HP_npc_create_npc_post;
int HP_npc_add_warp_pre;
int HP_npc_add_warp_post;
int HP_npc_parse_warp_pre;
int HP_npc_parse_warp_post;
int HP_npc_parse_shop_pre;
int HP_npc_parse_shop_post;
+ int HP_npc_parse_unknown_object_pre;
+ int HP_npc_parse_unknown_object_post;
int HP_npc_convertlabel_db_pre;
int HP_npc_convertlabel_db_post;
int HP_npc_skip_script_pre;
@@ -8398,6 +8418,8 @@ struct {
int HP_npc_parse_mob_post;
int HP_npc_parse_mapflag_pre;
int HP_npc_parse_mapflag_post;
+ int HP_npc_parse_unknown_mapflag_pre;
+ int HP_npc_parse_unknown_mapflag_post;
int HP_npc_parsesrcfile_pre;
int HP_npc_parsesrcfile_post;
int HP_npc_script_event_pre;
@@ -8750,8 +8772,12 @@ struct {
int HP_pc_resethate_post;
int HP_pc_equipitem_pre;
int HP_pc_equipitem_post;
+ int HP_pc_equipitem_pos_pre;
+ int HP_pc_equipitem_pos_post;
int HP_pc_unequipitem_pre;
int HP_pc_unequipitem_post;
+ int HP_pc_unequipitem_pos_pre;
+ int HP_pc_unequipitem_pos_post;
int HP_pc_checkitem_pre;
int HP_pc_checkitem_post;
int HP_pc_useitem_pre;
@@ -9054,8 +9080,6 @@ struct {
int HP_pet_skill_bonus_timer_post;
int HP_pet_recovery_timer_pre;
int HP_pet_recovery_timer_post;
- int HP_pet_heal_timer_pre;
- int HP_pet_heal_timer_post;
int HP_pet_skill_support_timer_pre;
int HP_pet_skill_support_timer_post;
int HP_pet_read_db_pre;
diff --git a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
index 00bd82f94..5d0545f82 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
@@ -221,6 +221,7 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(clif->refresh_ip, HP_clif_refresh_ip) },
{ HP_POP(clif->send, HP_clif_send) },
{ HP_POP(clif->send_sub, HP_clif_send_sub) },
+ { HP_POP(clif->send_actual, HP_clif_send_actual) },
{ HP_POP(clif->parse, HP_clif_parse) },
{ HP_POP(clif->parse_cmd, HP_clif_parse_cmd) },
{ HP_POP(clif->decrypt_cmd, HP_clif_decrypt_cmd) },
@@ -262,6 +263,7 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(clif->changelook, HP_clif_changelook) },
{ HP_POP(clif->changetraplook, HP_clif_changetraplook) },
{ HP_POP(clif->refreshlook, HP_clif_refreshlook) },
+ { HP_POP(clif->sendlook, HP_clif_sendlook) },
{ HP_POP(clif->class_change, HP_clif_class_change) },
{ HP_POP(clif->skill_delunit, HP_clif_skill_delunit) },
{ HP_POP(clif->skillunit_update, HP_clif_skillunit_update) },
@@ -1677,9 +1679,11 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(npc->parsename, HP_npc_parsename) },
{ HP_POP(npc->parseview, HP_npc_parseview) },
{ HP_POP(npc->viewisid, HP_npc_viewisid) },
+ { HP_POP(npc->create_npc, HP_npc_create_npc) },
{ HP_POP(npc->add_warp, HP_npc_add_warp) },
{ HP_POP(npc->parse_warp, HP_npc_parse_warp) },
{ HP_POP(npc->parse_shop, HP_npc_parse_shop) },
+ { HP_POP(npc->parse_unknown_object, HP_npc_parse_unknown_object) },
{ HP_POP(npc->convertlabel_db, HP_npc_convertlabel_db) },
{ HP_POP(npc->skip_script, HP_npc_skip_script) },
{ HP_POP(npc->parse_script, HP_npc_parse_script) },
@@ -1696,6 +1700,7 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(npc->parse_mob2, HP_npc_parse_mob2) },
{ HP_POP(npc->parse_mob, HP_npc_parse_mob) },
{ HP_POP(npc->parse_mapflag, HP_npc_parse_mapflag) },
+ { HP_POP(npc->parse_unknown_mapflag, HP_npc_parse_unknown_mapflag) },
{ HP_POP(npc->parsesrcfile, HP_npc_parsesrcfile) },
{ HP_POP(npc->script_event, HP_npc_script_event) },
{ HP_POP(npc->read_event_script, HP_npc_read_event_script) },
@@ -1876,7 +1881,9 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(pc->resetfeel, HP_pc_resetfeel) },
{ HP_POP(pc->resethate, HP_pc_resethate) },
{ HP_POP(pc->equipitem, HP_pc_equipitem) },
+ { HP_POP(pc->equipitem_pos, HP_pc_equipitem_pos) },
{ HP_POP(pc->unequipitem, HP_pc_unequipitem) },
+ { HP_POP(pc->unequipitem_pos, HP_pc_unequipitem_pos) },
{ HP_POP(pc->checkitem, HP_pc_checkitem) },
{ HP_POP(pc->useitem, HP_pc_useitem) },
{ HP_POP(pc->skillatk_bonus, HP_pc_skillatk_bonus) },
@@ -2029,7 +2036,6 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(pet->lootitem_drop, HP_pet_lootitem_drop) },
{ HP_POP(pet->skill_bonus_timer, HP_pet_skill_bonus_timer) },
{ HP_POP(pet->recovery_timer, HP_pet_recovery_timer) },
- { HP_POP(pet->heal_timer, HP_pet_heal_timer) },
{ HP_POP(pet->skill_support_timer, HP_pet_skill_support_timer) },
{ HP_POP(pet->read_db, HP_pet_read_db) },
/* quest */
diff --git a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
index 57a609024..0169d43c7 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
@@ -5688,6 +5688,33 @@ int HP_clif_send_sub(struct block_list *bl, va_list ap) {
}
return retVal___;
}
+int HP_clif_send_actual(int fd, void *buf, int len) {
+ int hIndex = 0;
+ int retVal___ = 0;
+ if( HPMHooks.count.HP_clif_send_actual_pre ) {
+ int (*preHookFunc) (int *fd, void *buf, int *len);
+ *HPMforce_return = false;
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_send_actual_pre; hIndex++ ) {
+ preHookFunc = HPMHooks.list.HP_clif_send_actual_pre[hIndex].func;
+ retVal___ = preHookFunc(&fd, buf, &len);
+ }
+ if( *HPMforce_return ) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.clif.send_actual(fd, buf, len);
+ }
+ if( HPMHooks.count.HP_clif_send_actual_post ) {
+ int (*postHookFunc) (int retVal___, int *fd, void *buf, int *len);
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_send_actual_post; hIndex++ ) {
+ postHookFunc = HPMHooks.list.HP_clif_send_actual_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, &fd, buf, &len);
+ }
+ }
+ return retVal___;
+}
int HP_clif_parse(int fd) {
int hIndex = 0;
int retVal___ = 0;
@@ -6757,6 +6784,32 @@ void HP_clif_refreshlook(struct block_list *bl, int id, int type, int val, enum
}
return;
}
+void HP_clif_sendlook(struct block_list *bl, int id, int type, int val, int val2, enum send_target target) {
+ int hIndex = 0;
+ if( HPMHooks.count.HP_clif_sendlook_pre ) {
+ void (*preHookFunc) (struct block_list *bl, int *id, int *type, int *val, int *val2, enum send_target *target);
+ *HPMforce_return = false;
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_sendlook_pre; hIndex++ ) {
+ preHookFunc = HPMHooks.list.HP_clif_sendlook_pre[hIndex].func;
+ preHookFunc(bl, &id, &type, &val, &val2, &target);
+ }
+ if( *HPMforce_return ) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.clif.sendlook(bl, id, type, val, val2, target);
+ }
+ if( HPMHooks.count.HP_clif_sendlook_post ) {
+ void (*postHookFunc) (struct block_list *bl, int *id, int *type, int *val, int *val2, enum send_target *target);
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_sendlook_post; hIndex++ ) {
+ postHookFunc = HPMHooks.list.HP_clif_sendlook_post[hIndex].func;
+ postHookFunc(bl, &id, &type, &val, &val2, &target);
+ }
+ }
+ return;
+}
void HP_clif_class_change(struct block_list *bl, int class_, int type) {
int hIndex = 0;
if( HPMHooks.count.HP_clif_class_change_pre ) {
@@ -44115,6 +44168,33 @@ bool HP_npc_viewisid(const char *viewid) {
}
return retVal___;
}
+struct npc_data* HP_npc_create_npc(int m, int x, int y) {
+ int hIndex = 0;
+ struct npc_data* retVal___ = NULL;
+ if( HPMHooks.count.HP_npc_create_npc_pre ) {
+ struct npc_data* (*preHookFunc) (int *m, int *x, int *y);
+ *HPMforce_return = false;
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_create_npc_pre; hIndex++ ) {
+ preHookFunc = HPMHooks.list.HP_npc_create_npc_pre[hIndex].func;
+ retVal___ = preHookFunc(&m, &x, &y);
+ }
+ if( *HPMforce_return ) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.npc.create_npc(m, x, y);
+ }
+ if( HPMHooks.count.HP_npc_create_npc_post ) {
+ struct npc_data* (*postHookFunc) (struct npc_data* retVal___, int *m, int *x, int *y);
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_create_npc_post; hIndex++ ) {
+ postHookFunc = HPMHooks.list.HP_npc_create_npc_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, &m, &x, &y);
+ }
+ }
+ return retVal___;
+}
struct npc_data* HP_npc_add_warp(char *name, short from_mapid, short from_x, short from_y, short xs, short ys, unsigned short to_mapindex, short to_x, short to_y) {
int hIndex = 0;
struct npc_data* retVal___ = NULL;
@@ -44196,6 +44276,33 @@ const char* HP_npc_parse_shop(char *w1, char *w2, char *w3, char *w4, const char
}
return retVal___;
}
+const char* HP_npc_parse_unknown_object(char *w1, char *w2, char *w3, char *w4, const char *start, const char *buffer, const char *filepath, int *retval) {
+ int hIndex = 0;
+ const char* retVal___ = NULL;
+ if( HPMHooks.count.HP_npc_parse_unknown_object_pre ) {
+ const char* (*preHookFunc) (char *w1, char *w2, char *w3, char *w4, const char *start, const char *buffer, const char *filepath, int *retval);
+ *HPMforce_return = false;
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_parse_unknown_object_pre; hIndex++ ) {
+ preHookFunc = HPMHooks.list.HP_npc_parse_unknown_object_pre[hIndex].func;
+ retVal___ = preHookFunc(w1, w2, w3, w4, start, buffer, filepath, retval);
+ }
+ if( *HPMforce_return ) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.npc.parse_unknown_object(w1, w2, w3, w4, start, buffer, filepath, retval);
+ }
+ if( HPMHooks.count.HP_npc_parse_unknown_object_post ) {
+ const char* (*postHookFunc) (const char* retVal___, char *w1, char *w2, char *w3, char *w4, const char *start, const char *buffer, const char *filepath, int *retval);
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_parse_unknown_object_post; hIndex++ ) {
+ postHookFunc = HPMHooks.list.HP_npc_parse_unknown_object_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, w1, w2, w3, w4, start, buffer, filepath, retval);
+ }
+ }
+ return retVal___;
+}
void HP_npc_convertlabel_db(struct npc_label_list *label_list, const char *filepath) {
int hIndex = 0;
if( HPMHooks.count.HP_npc_convertlabel_db_pre ) {
@@ -44627,6 +44734,32 @@ const char* HP_npc_parse_mapflag(char *w1, char *w2, char *w3, char *w4, const c
}
return retVal___;
}
+void HP_npc_parse_unknown_mapflag(const char *name, char *w3, char *w4, const char *start, const char *buffer, const char *filepath, int *retval) {
+ int hIndex = 0;
+ if( HPMHooks.count.HP_npc_parse_unknown_mapflag_pre ) {
+ void (*preHookFunc) (const char *name, char *w3, char *w4, const char *start, const char *buffer, const char *filepath, int *retval);
+ *HPMforce_return = false;
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_parse_unknown_mapflag_pre; hIndex++ ) {
+ preHookFunc = HPMHooks.list.HP_npc_parse_unknown_mapflag_pre[hIndex].func;
+ preHookFunc(name, w3, w4, start, buffer, filepath, retval);
+ }
+ if( *HPMforce_return ) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.npc.parse_unknown_mapflag(name, w3, w4, start, buffer, filepath, retval);
+ }
+ if( HPMHooks.count.HP_npc_parse_unknown_mapflag_post ) {
+ void (*postHookFunc) (const char *name, char *w3, char *w4, const char *start, const char *buffer, const char *filepath, int *retval);
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_parse_unknown_mapflag_post; hIndex++ ) {
+ postHookFunc = HPMHooks.list.HP_npc_parse_unknown_mapflag_post[hIndex].func;
+ postHookFunc(name, w3, w4, start, buffer, filepath, retval);
+ }
+ }
+ return;
+}
int HP_npc_parsesrcfile(const char *filepath, bool runOnInit) {
int hIndex = 0;
int retVal___ = 0;
@@ -49387,6 +49520,32 @@ int HP_pc_equipitem(struct map_session_data *sd, int n, int req_pos) {
}
return retVal___;
}
+void HP_pc_equipitem_pos(struct map_session_data *sd, struct item_data *id, int pos) {
+ int hIndex = 0;
+ if( HPMHooks.count.HP_pc_equipitem_pos_pre ) {
+ void (*preHookFunc) (struct map_session_data *sd, struct item_data *id, int *pos);
+ *HPMforce_return = false;
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_equipitem_pos_pre; hIndex++ ) {
+ preHookFunc = HPMHooks.list.HP_pc_equipitem_pos_pre[hIndex].func;
+ preHookFunc(sd, id, &pos);
+ }
+ if( *HPMforce_return ) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.pc.equipitem_pos(sd, id, pos);
+ }
+ if( HPMHooks.count.HP_pc_equipitem_pos_post ) {
+ void (*postHookFunc) (struct map_session_data *sd, struct item_data *id, int *pos);
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_equipitem_pos_post; hIndex++ ) {
+ postHookFunc = HPMHooks.list.HP_pc_equipitem_pos_post[hIndex].func;
+ postHookFunc(sd, id, &pos);
+ }
+ }
+ return;
+}
int HP_pc_unequipitem(struct map_session_data *sd, int n, int flag) {
int hIndex = 0;
int retVal___ = 0;
@@ -49414,6 +49573,32 @@ int HP_pc_unequipitem(struct map_session_data *sd, int n, int flag) {
}
return retVal___;
}
+void HP_pc_unequipitem_pos(struct map_session_data *sd, int n, int pos) {
+ int hIndex = 0;
+ if( HPMHooks.count.HP_pc_unequipitem_pos_pre ) {
+ void (*preHookFunc) (struct map_session_data *sd, int *n, int *pos);
+ *HPMforce_return = false;
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_unequipitem_pos_pre; hIndex++ ) {
+ preHookFunc = HPMHooks.list.HP_pc_unequipitem_pos_pre[hIndex].func;
+ preHookFunc(sd, &n, &pos);
+ }
+ if( *HPMforce_return ) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.pc.unequipitem_pos(sd, n, pos);
+ }
+ if( HPMHooks.count.HP_pc_unequipitem_pos_post ) {
+ void (*postHookFunc) (struct map_session_data *sd, int *n, int *pos);
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_unequipitem_pos_post; hIndex++ ) {
+ postHookFunc = HPMHooks.list.HP_pc_unequipitem_pos_post[hIndex].func;
+ postHookFunc(sd, &n, &pos);
+ }
+ }
+ return;
+}
int HP_pc_checkitem(struct map_session_data *sd) {
int hIndex = 0;
int retVal___ = 0;
@@ -53492,33 +53677,6 @@ int HP_pet_recovery_timer(int tid, int64 tick, int id, intptr_t data) {
}
return retVal___;
}
-int HP_pet_heal_timer(int tid, int64 tick, int id, intptr_t data) {
- int hIndex = 0;
- int retVal___ = 0;
- if( HPMHooks.count.HP_pet_heal_timer_pre ) {
- int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data);
- *HPMforce_return = false;
- for(hIndex = 0; hIndex < HPMHooks.count.HP_pet_heal_timer_pre; hIndex++ ) {
- preHookFunc = HPMHooks.list.HP_pet_heal_timer_pre[hIndex].func;
- retVal___ = preHookFunc(&tid, &tick, &id, &data);
- }
- if( *HPMforce_return ) {
- *HPMforce_return = false;
- return retVal___;
- }
- }
- {
- retVal___ = HPMHooks.source.pet.heal_timer(tid, tick, id, data);
- }
- if( HPMHooks.count.HP_pet_heal_timer_post ) {
- int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data);
- for(hIndex = 0; hIndex < HPMHooks.count.HP_pet_heal_timer_post; hIndex++ ) {
- postHookFunc = HPMHooks.list.HP_pet_heal_timer_post[hIndex].func;
- retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data);
- }
- }
- return retVal___;
-}
int HP_pet_skill_support_timer(int tid, int64 tick, int id, intptr_t data) {
int hIndex = 0;
int retVal___ = 0;
@@ -64693,15 +64851,15 @@ unsigned short HP_status_calc_batk(struct block_list *bl, struct status_change *
}
return retVal___;
}
-unsigned short HP_status_base_matk(const struct status_data *st, int level) {
+unsigned short HP_status_base_matk(struct block_list *bl, const struct status_data *st, int level) {
int hIndex = 0;
unsigned short retVal___ = 0;
if( HPMHooks.count.HP_status_base_matk_pre ) {
- unsigned short (*preHookFunc) (const struct status_data *st, int *level);
+ unsigned short (*preHookFunc) (struct block_list *bl, const struct status_data *st, int *level);
*HPMforce_return = false;
for(hIndex = 0; hIndex < HPMHooks.count.HP_status_base_matk_pre; hIndex++ ) {
preHookFunc = HPMHooks.list.HP_status_base_matk_pre[hIndex].func;
- retVal___ = preHookFunc(st, &level);
+ retVal___ = preHookFunc(bl, st, &level);
}
if( *HPMforce_return ) {
*HPMforce_return = false;
@@ -64709,13 +64867,13 @@ unsigned short HP_status_base_matk(const struct status_data *st, int level) {
}
}
{
- retVal___ = HPMHooks.source.status.base_matk(st, level);
+ retVal___ = HPMHooks.source.status.base_matk(bl, st, level);
}
if( HPMHooks.count.HP_status_base_matk_post ) {
- unsigned short (*postHookFunc) (unsigned short retVal___, const struct status_data *st, int *level);
+ unsigned short (*postHookFunc) (unsigned short retVal___, struct block_list *bl, const struct status_data *st, int *level);
for(hIndex = 0; hIndex < HPMHooks.count.HP_status_base_matk_post; hIndex++ ) {
postHookFunc = HPMHooks.list.HP_status_base_matk_post[hIndex].func;
- retVal___ = postHookFunc(retVal___, st, &level);
+ retVal___ = postHookFunc(retVal___, bl, st, &level);
}
}
return retVal___;