summaryrefslogtreecommitdiff
path: root/src/map
diff options
context:
space:
mode:
Diffstat (limited to 'src/map')
-rw-r--r--src/map/CMakeLists.txt4
-rw-r--r--src/map/atcommand.c18
-rw-r--r--src/map/battle.c1
-rw-r--r--src/map/battle.h1
-rw-r--r--src/map/chrif.c2
-rw-r--r--src/map/clif.c248
-rw-r--r--src/map/clif.h5
-rw-r--r--src/map/itemdb.h2
-rw-r--r--src/map/map.c10
-rw-r--r--src/map/map.h1
-rw-r--r--src/map/mob.c38
-rw-r--r--src/map/npc.c4
-rw-r--r--src/map/npc_chat.c14
-rw-r--r--src/map/pc.c86
-rw-r--r--src/map/pc.h2
-rw-r--r--src/map/script.c73
-rw-r--r--src/map/searchstore.c4
-rw-r--r--src/map/skill.c90
-rw-r--r--src/map/sql/CMakeLists.txt166
-rw-r--r--src/map/status.c178
-rw-r--r--src/map/status.h3
-rw-r--r--src/map/txt/CMakeLists.txt166
-rw-r--r--src/map/unit.c31
23 files changed, 623 insertions, 524 deletions
diff --git a/src/map/CMakeLists.txt b/src/map/CMakeLists.txt
index 9199702be..1d82fc2ca 100644
--- a/src/map/CMakeLists.txt
+++ b/src/map/CMakeLists.txt
@@ -2,7 +2,9 @@
#
# setup
#
-set( MAP_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} )
+set( MAP_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE INTERNAL "" )
+set( TXT_MAP_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE INTERNAL "" )
+set( SQL_MAP_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE INTERNAL "" )
#
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index 32c2cabf7..5ccf14ea2 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -416,7 +416,7 @@ ACMD_FUNC(mapmove)
{
char map_name[MAP_NAME_LENGTH_EXT];
unsigned short mapindex;
- int x = 0, y = 0;
+ short x = 0, y = 0;
int m = -1;
nullpo_retr(-1, sd);
@@ -424,8 +424,8 @@ ACMD_FUNC(mapmove)
memset(map_name, '\0', sizeof(map_name));
if (!message || !*message ||
- (sscanf(message, "%15s %d %d", map_name, &x, &y) < 3 &&
- sscanf(message, "%15[^,],%d,%d", map_name, &x, &y) < 1)) {
+ (sscanf(message, "%15s %hd %hd", map_name, &x, &y) < 3 &&
+ sscanf(message, "%15[^,],%hd,%hd", map_name, &x, &y) < 1)) {
clif_displaymessage(fd, "Please, enter a map (usage: @warp/@rura/@mapmove <mapname> <x> <y>).");
return -1;
@@ -443,7 +443,8 @@ ACMD_FUNC(mapmove)
if ((x || y) && map_getcell(m, x, y, CELL_CHKNOPASS))
{ //This is to prevent the pc_setpos call from printing an error.
clif_displaymessage(fd, msg_txt(2));
- x = y = 0; //Invalid cell, use random spot.
+ if (!map_search_freecell(NULL, m, &x, &y, 10, 10, 1))
+ x = y = 0; //Invalid cell, use random spot.
}
if (map[m].flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
clif_displaymessage(fd, msg_txt(247));
@@ -548,13 +549,13 @@ ACMD_FUNC(jumpto)
*------------------------------------------*/
ACMD_FUNC(jump)
{
- int x = 0, y = 0;
+ short x = 0, y = 0;
nullpo_retr(-1, sd);
memset(atcmd_output, '\0', sizeof(atcmd_output));
- sscanf(message, "%d %d", &x, &y);
+ sscanf(message, "%hd %hd", &x, &y);
if (map[sd->bl.m].flag.noteleport && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
clif_displaymessage(fd, msg_txt(248)); // You are not authorized to warp from your current map.
@@ -570,7 +571,8 @@ ACMD_FUNC(jump)
if ((x || y) && map_getcell(sd->bl.m, x, y, CELL_CHKNOPASS))
{ //This is to prevent the pc_setpos call from printing an error.
clif_displaymessage(fd, msg_txt(2));
- x = y = 0; //Invalid cell, use random spot.
+ if (!map_search_freecell(NULL, sd->bl.m, &x, &y, 10, 10, 1))
+ x = y = 0; //Invalid cell, use random spot.
}
pc_setpos(sd, sd->mapindex, x, y, CLR_TELEPORT);
@@ -4499,6 +4501,8 @@ ACMD_FUNC(mapinfo)
strcat(atcmd_output, "NoIcewall | ");
if (map[m_id].flag.allowks)
strcat(atcmd_output, "AllowKS | ");
+ if (map[m_id].flag.reset)
+ strcat(atcmd_output, "Reset | ");
clif_displaymessage(fd, atcmd_output);
strcpy(atcmd_output,"Other Flags: ");
diff --git a/src/map/battle.c b/src/map/battle.c
index 711310442..b0e42a7c7 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -4046,6 +4046,7 @@ static const struct _battle_data {
{ "display_party_name", &battle_config.display_party_name, 0, 0, 1, },
{ "cashshop_show_points", &battle_config.cashshop_show_points, 0, 0, 1, },
{ "mail_show_status", &battle_config.mail_show_status, 0, 0, 2, },
+ { "client_limit_unit_lv", &battle_config.client_limit_unit_lv, 0, 0, BL_ALL, },
// BattleGround Settings
{ "bg_update_interval", &battle_config.bg_update_interval, 1000, 100, INT_MAX, },
{ "bg_short_attack_damage_rate", &battle_config.bg_short_damage_rate, 80, 0, INT_MAX, },
diff --git a/src/map/battle.h b/src/map/battle.h
index 100174fcc..08a2a46f4 100644
--- a/src/map/battle.h
+++ b/src/map/battle.h
@@ -485,6 +485,7 @@ extern struct Battle_Config
int display_party_name;
int cashshop_show_points;
int mail_show_status;
+ int client_limit_unit_lv;
// [BattleGround Settings]
int bg_update_interval;
diff --git a/src/map/chrif.c b/src/map/chrif.c
index a14200a36..d1332fab2 100644
--- a/src/map/chrif.c
+++ b/src/map/chrif.c
@@ -311,8 +311,10 @@ int chrif_save(struct map_session_data *sd, int flag)
merc_save(sd->hd);
if( sd->md && mercenary_get_lifetime(sd->md) > 0 )
mercenary_save(sd->md);
+#ifndef TXT_ONLY
if( sd->save_quest )
intif_quest_save(sd);
+#endif
return 0;
}
diff --git a/src/map/clif.c b/src/map/clif.c
index ef48e6d60..db34d30ae 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -4,6 +4,7 @@
#include "../common/cbasetypes.h"
#include "../common/socket.h"
#include "../common/timer.h"
+#include "../common/grfio.h"
#include "../common/malloc.h"
#include "../common/version.h"
#include "../common/nullpo.h"
@@ -57,7 +58,7 @@ struct Clif_Config {
struct s_packet_db packet_db[MAX_PACKET_VER + 1][MAX_PACKET_DB + 1];
//Converts item type in case of pet eggs.
-inline int itemtype(int type)
+static inline int itemtype(int type)
{
return ( type == IT_PETEGG ) ? IT_WEAPON : type;
}
@@ -755,13 +756,37 @@ void clif_get_weapon_view(struct map_session_data* sd, unsigned short *rhand, un
}
//To make the assignation of the level based on limits clearer/easier. [Skotlex]
-static int clif_setlevel(int lv)
+static int clif_setlevel_sub(int lv)
{
- if( lv < battle_config.max_lv )
- return lv;
- if( lv < battle_config.aura_lv )
- return battle_config.max_lv - 1;
- return battle_config.max_lv;
+ if( lv < battle_config.max_lv )
+ {
+ ;
+ }
+ else if( lv < battle_config.aura_lv )
+ {
+ lv = battle_config.max_lv - 1;
+ }
+ else
+ {
+ lv = battle_config.max_lv;
+ }
+
+ return lv;
+}
+
+static int clif_setlevel(struct block_list* bl)
+{
+ int lv = status_get_lv(bl);
+ if( battle_config.client_limit_unit_lv&bl->type )
+ return clif_setlevel_sub(lv);
+ switch( bl->type )
+ {
+ case BL_NPC:
+ case BL_PET:
+ // npcs and pets do not have level
+ return 0;
+ }
+ return lv;
}
/*==========================================
@@ -915,7 +940,7 @@ static int clif_set_unit_idle(struct block_list* bl, unsigned char* buffer, bool
offset++;
buf = WBUFP(buffer,offset);
}
- WBUFW(buf,51) = clif_setlevel(status_get_lv(bl));
+ WBUFW(buf,51) = clif_setlevel(bl);
#if PACKETVER < 20091103
if (type) //End for non-player packet
return packet_len(WBUFW(buffer,0));
@@ -1026,7 +1051,7 @@ static int clif_set_unit_walking(struct block_list* bl, struct unit_data* ud, un
WBUFPOS2(buf,50,bl->x,bl->y,ud->to_x,ud->to_y,8,8);
WBUFB(buf,56) = (sd)? 5 : 0;
WBUFB(buf,57) = (sd)? 5 : 0;
- WBUFW(buf,58) = clif_setlevel(status_get_lv(bl));
+ WBUFW(buf,58) = clif_setlevel(bl);
#if PACKETVER >= 20080102
WBUFW(buf,60) = sd?sd->user_font:0;
#endif
@@ -1214,8 +1239,8 @@ int 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
- WBUFW(buf,35)=cap_value(status->rhw.atk2+status->batk, 0, SHRT_MAX);
- WBUFW(buf,37)=cap_value(status->matk_max, 0, SHRT_MAX);
+ WBUFW(buf,35)=cap_value(status->rhw.atk2+status->batk, 0, INT16_MAX);
+ WBUFW(buf,37)=cap_value(status->matk_max, 0, INT16_MAX);
WBUFW(buf,39)=status->hit;
if (battle_config.hom_setting&0x10)
WBUFW(buf,41)=status->luk/3 + 1; //crit is a +1 decimal value! Just display purpose.[Vicious]
@@ -1225,14 +1250,14 @@ int clif_hominfo(struct map_session_data *sd, struct homun_data *hd, int flag)
WBUFW(buf,45)=status->mdef;
WBUFW(buf,47)=status->flee;
WBUFW(buf,49)=(flag)?0:status->amotion;
- if (status->max_hp > SHRT_MAX) {
+ if (status->max_hp > INT16_MAX) {
WBUFW(buf,51) = status->hp/(status->max_hp/100);
WBUFW(buf,53) = 100;
} else {
WBUFW(buf,51)=status->hp;
WBUFW(buf,53)=status->max_hp;
}
- if (status->max_sp > SHRT_MAX) {
+ if (status->max_sp > INT16_MAX) {
WBUFW(buf,55) = status->sp/(status->max_sp/100);
WBUFW(buf,57) = 100;
} else {
@@ -2824,18 +2849,18 @@ int clif_initialstatus(struct map_session_data *sd)
buf=WFIFOP(fd,0);
WBUFW(buf,0)=0xbd;
- WBUFW(buf,2)=min(sd->status.status_point, SHRT_MAX);
- WBUFB(buf,4)=min(sd->status.str, UCHAR_MAX);
+ WBUFW(buf,2)=min(sd->status.status_point, INT16_MAX);
+ WBUFB(buf,4)=min(sd->status.str, UINT8_MAX);
WBUFB(buf,5)=pc_need_status_point(sd,SP_STR,1);
- WBUFB(buf,6)=min(sd->status.agi, UCHAR_MAX);
+ WBUFB(buf,6)=min(sd->status.agi, UINT8_MAX);
WBUFB(buf,7)=pc_need_status_point(sd,SP_AGI,1);
- WBUFB(buf,8)=min(sd->status.vit, UCHAR_MAX);
+ WBUFB(buf,8)=min(sd->status.vit, UINT8_MAX);
WBUFB(buf,9)=pc_need_status_point(sd,SP_VIT,1);
- WBUFB(buf,10)=min(sd->status.int_, UCHAR_MAX);
+ WBUFB(buf,10)=min(sd->status.int_, UINT8_MAX);
WBUFB(buf,11)=pc_need_status_point(sd,SP_INT,1);
- WBUFB(buf,12)=min(sd->status.dex, UCHAR_MAX);
+ WBUFB(buf,12)=min(sd->status.dex, UINT8_MAX);
WBUFB(buf,13)=pc_need_status_point(sd,SP_DEX,1);
- WBUFB(buf,14)=min(sd->status.luk, UCHAR_MAX);
+ WBUFB(buf,14)=min(sd->status.luk, UINT8_MAX);
WBUFB(buf,15)=pc_need_status_point(sd,SP_LUK,1);
WBUFW(buf,16) = sd->battle_status.batk;
@@ -2969,7 +2994,7 @@ int clif_statusupack(struct map_session_data *sd,int type,int ok,int val)
WFIFOW(fd,0)=0xbc;
WFIFOW(fd,2)=type;
WFIFOB(fd,4)=ok;
- WFIFOB(fd,5)=cap_value(val,0,UCHAR_MAX);
+ WFIFOB(fd,5)=cap_value(val,0,UINT8_MAX);
WFIFOSET(fd,packet_len(0xbc));
return 0;
@@ -3103,7 +3128,7 @@ int clif_changeoption2(struct block_list* bl)
WBUFW(buf,0) = 0x28a;
WBUFL(buf,2) = bl->id;
WBUFL(buf,6) = sc->option;
- WBUFL(buf,10) = clif_setlevel(status_get_lv(bl));
+ WBUFL(buf,10) = clif_setlevel(bl);
WBUFL(buf,14) = sc->opt3;
if(disguised(bl)) {
clif_send(buf,packet_len(0x28a),bl,AREA_WOS);
@@ -3834,7 +3859,7 @@ int clif_damage(struct block_list* src, struct block_list* dst, unsigned int tic
WBUFW(buf,22)=damage?div:0;
WBUFW(buf,27)=damage2?div:0;
} else {
- WBUFW(buf,22)=min(damage, SHRT_MAX);
+ WBUFW(buf,22)=min(damage, INT16_MAX);
WBUFW(buf,27)=damage2;
}
WBUFW(buf,24)=div;
@@ -4191,10 +4216,7 @@ int clif_skillinfoblock(struct map_session_data *sd)
if( (id = sd->status.skill[i].id) != 0 )
{
WFIFOW(fd,len) = id;
- if( (id == MO_EXTREMITYFIST && sd->state.combo&1) || (id == TK_JUMPKICK && sd->state.combo&2) )
- WFIFOW(fd,len+2) = INF_SELF_SKILL;
- else
- WFIFOW(fd,len+2) = skill_get_inf(id);
+ WFIFOW(fd,len+2) = skill_get_inf(id);
WFIFOW(fd,len+4) = 0;
WFIFOW(fd,len+6) = sd->status.skill[i].lv;
WFIFOW(fd,len+8) = skill_get_sp(id,sd->status.skill[i].lv);
@@ -4228,10 +4250,7 @@ int clif_addskill(struct map_session_data *sd, int id )
WFIFOHEAD(fd, packet_len(0x111));
WFIFOW(fd,0) = 0x111;
WFIFOW(fd,2) = id;
- if( (id == MO_EXTREMITYFIST && sd->state.combo&1) || (id == TK_JUMPKICK && sd->state.combo&2) )
- WFIFOW(fd,4) = INF_SELF_SKILL;
- else
- WFIFOW(fd,4) = skill_get_inf(id);
+ WFIFOW(fd,4) = skill_get_inf(id);
WFIFOW(fd,6) = 0;
WFIFOW(fd,8) = sd->status.skill[id].lv;
WFIFOW(fd,10) = skill_get_sp(id,sd->status.skill[id].lv);
@@ -4287,6 +4306,24 @@ int clif_skillup(struct map_session_data *sd,int skill_num)
return 0;
}
+//PACKET_ZC_SKILLINFO_UPDATE2
+//Like packet 0x0x10e, but also contains inf information
+void clif_skillinfo(struct map_session_data *sd,int skill, int inf)
+{
+ const int fd = sd->fd;
+ WFIFOHEAD(fd,packet_len(0x7e1));
+ WFIFOW(fd,0) = 0x7e1;
+ WFIFOW(fd,2) = skill;
+ WFIFOL(fd,4) = inf?inf:skill_get_inf(skill);
+ WFIFOW(fd,8) = sd->status.skill[skill].lv;
+ WFIFOW(fd,10) = skill_get_sp(skill,sd->status.skill[skill].lv);
+ WFIFOW(fd,12) = skill_get_range2(&sd->bl,skill,sd->status.skill[skill].lv);
+ if( sd->status.skill[skill].flag == SKILL_FLAG_PERMANENT )
+ WFIFOB(fd,14) = (sd->status.skill[skill].lv < skill_tree_get_max(skill, sd->status.class_))? 1:0;
+ else
+ WFIFOB(fd,14) = 0;
+ WFIFOSET(fd,packet_len(0x7e1));
+}
/// Notifies clients, that an object is about to use a skill (ZC_USESKILL_ACK/ZC_USESKILL_ACK2)
/// 013e <src id>.L <dst id>.L <x pos>.W <y pos>.W <skill id>.W <property>.L <delaytime>.L
@@ -4627,7 +4664,7 @@ int clif_skill_nodamage(struct block_list *src,struct block_list *dst,int skill_
WBUFW(buf,0)=0x11a;
WBUFW(buf,2)=skill_id;
- WBUFW(buf,4)=min(heal, SHRT_MAX);
+ WBUFW(buf,4)=min(heal, INT16_MAX);
WBUFL(buf,6)=dst->id;
WBUFL(buf,10)=src?src->id:0;
WBUFB(buf,14)=fail;
@@ -5085,7 +5122,7 @@ int clif_heal(int fd,int type,int val)
WFIFOHEAD(fd,packet_len(0x13d));
WFIFOW(fd,0)=0x13d;
WFIFOW(fd,2)=type;
- WFIFOW(fd,4)=cap_value(val,0,SHRT_MAX);
+ WFIFOW(fd,4)=cap_value(val,0,INT16_MAX);
WFIFOSET(fd,packet_len(0x13d));
return 0;
@@ -5157,7 +5194,7 @@ int clif_pvpset(struct map_session_data *sd,int pvprank,int pvpnum,int type)
WBUFW(buf,0) = 0x19a;
WBUFL(buf,2) = sd->bl.id;
if(sd->sc.option&(OPTION_HIDE|OPTION_CLOAK))
- WBUFL(buf,6) = ULONG_MAX; //On client displays as --
+ WBUFL(buf,6) = UINT32_MAX; //On client displays as --
else
WBUFL(buf,6) = pvprank;
WBUFL(buf,10) = pvpnum;
@@ -6075,7 +6112,7 @@ int clif_party_hp(struct map_session_data *sd)
WBUFW(buf,0)=cmd;
WBUFL(buf,2)=sd->status.account_id;
#if PACKETVER < 20100126
- if (sd->battle_status.max_hp > SHRT_MAX) { //To correctly display the %hp bar. [Skotlex]
+ if (sd->battle_status.max_hp > INT16_MAX) { //To correctly display the %hp bar. [Skotlex]
WBUFW(buf,6) = sd->battle_status.hp/(sd->battle_status.max_hp/100);
WBUFW(buf,8) = 100;
} else {
@@ -6104,7 +6141,7 @@ void clif_hpmeter_single(int fd, int id, unsigned int hp, unsigned int maxhp)
WFIFOW(fd,0) = cmd;
WFIFOL(fd,2) = id;
#if PACKETVER < 20100126
- if( maxhp > SHRT_MAX )
+ if( maxhp > INT16_MAX )
{// To correctly display the %hp bar. [Skotlex]
WFIFOW(fd,6) = hp/(maxhp/100);
WFIFOW(fd,8) = 100;
@@ -6147,7 +6184,7 @@ int clif_hpmeter_sub(struct block_list *bl, va_list ap)
WFIFOW(tsd->fd,0) = cmd;
WFIFOL(tsd->fd,2) = sd->status.account_id;
#if PACKETVER < 20100126
- if( sd->battle_status.max_hp > SHRT_MAX )
+ if( sd->battle_status.max_hp > INT16_MAX )
{ //To correctly display the %hp bar. [Skotlex]
WFIFOW(tsd->fd,6) = sd->battle_status.hp/(sd->battle_status.max_hp/100);
WFIFOW(tsd->fd,8) = 100;
@@ -6582,7 +6619,7 @@ int clif_mvp_exp(struct map_session_data *sd, unsigned int exp)
fd=sd->fd;
WFIFOHEAD(fd,packet_len(0x10b));
WFIFOW(fd,0)=0x10b;
- WFIFOL(fd,2)=cap_value(exp,0,INT_MAX);
+ WFIFOL(fd,2)=cap_value(exp,0,INT32_MAX);
WFIFOSET(fd,packet_len(0x10b));
return 0;
}
@@ -6608,27 +6645,30 @@ int clif_guild_created(struct map_session_data *sd,int flag)
WFIFOSET(fd,packet_len(0x167));
return 0;
}
-/*==========================================
- * ギルド所属通知
- *------------------------------------------*/
-int clif_guild_belonginfo(struct map_session_data *sd, struct guild *g)
+
+
+/// Notifies the client that it is belonging to a guild (ZC_UPDATE_GDID)
+/// 016c <guild id>.L <emblem id>.L <mode>.L <ismaster>.B <inter sid>.L <guild name>.24B
+void clif_guild_belonginfo(struct map_session_data *sd, struct guild *g)
{
int ps,fd;
- nullpo_ret(sd);
- nullpo_ret(g);
+ nullpo_retv(sd);
+ nullpo_retv(g);
fd=sd->fd;
ps=guild_getposition(g,sd);
WFIFOHEAD(fd,packet_len(0x16c));
- memset(WFIFOP(fd,0),0,packet_len(0x16c));
WFIFOW(fd,0)=0x16c;
WFIFOL(fd,2)=g->guild_id;
WFIFOL(fd,6)=g->emblem_id;
WFIFOL(fd,10)=g->position[ps].mode;
+ WFIFOB(fd,14)=(bool)(sd->state.gmaster_flag==g);
+ WFIFOL(fd,15)=0; // InterSID (unknown purpose)
memcpy(WFIFOP(fd,19),g->name,NAME_LENGTH);
WFIFOSET(fd,packet_len(0x16c));
- return 0;
}
+
+
/*==========================================
* ギルドメンバログイン通知
*------------------------------------------*/
@@ -6729,7 +6769,7 @@ int clif_guild_basicinfo(struct map_session_data *sd)
WFIFOL(fd,10)=g->connect_member;
WFIFOL(fd,14)=g->max_member;
WFIFOL(fd,18)=g->average_lv;
- WFIFOL(fd,22)=(uint32)cap_value(g->exp,0,INT_MAX);
+ WFIFOL(fd,22)=(uint32)cap_value(g->exp,0,INT32_MAX);
WFIFOL(fd,26)=g->next_exp;
WFIFOL(fd,30)=0; // Tax Points
WFIFOL(fd,34)=0; // Tendency: (left) Vulgar [-100,100] Famed (right)
@@ -6807,7 +6847,7 @@ int clif_guild_memberlist(struct map_session_data *sd)
WFIFOW(fd,c*104+16)=m->gender;
WFIFOW(fd,c*104+18)=m->class_;
WFIFOW(fd,c*104+20)=m->lv;
- WFIFOL(fd,c*104+22)=(int)cap_value(m->exp,0,INT_MAX);
+ WFIFOL(fd,c*104+22)=(int)cap_value(m->exp,0,INT32_MAX);
WFIFOL(fd,c*104+26)=m->online;
WFIFOL(fd,c*104+30)=m->position;
memset(WFIFOP(fd,c*104+34),0,50); // メモ?
@@ -10032,7 +10072,7 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd)
if( skillnotok(skillnum, sd) )
return;
- if( sd->bl.id != target_id && (tmp&INF_SELF_SKILL || sd->state.combo) )
+ if( sd->bl.id != target_id && tmp&INF_SELF_SKILL )
target_id = sd->bl.id; // never trust the client
if( target_id < 0 && -target_id == sd->bl.id ) // for disguises [Valaris]
@@ -11121,16 +11161,43 @@ void clif_parse_GuildRequestEmblem(int fd,struct map_session_data *sd)
clif_guild_emblem(sd,g);
}
+
+/// Validates data of a guild emblem (compressed bitmap)
+static bool clif_validate_emblem(const uint8* emblem, unsigned long emblem_len)
+{
+ bool success;
+ uint8 buf[1800]; // no well-formed emblem bitmap is larger than 1782 (24 bit) / 1654 (8 bit) bytes
+ unsigned long buf_len = sizeof(buf);
+
+ success = ( decode_zip(buf, &buf_len, emblem, emblem_len) == 0 && buf_len >= 18 ) // sizeof(BITMAPFILEHEADER) + sizeof(biSize) of the following info header struct
+ && RBUFW(buf,0) == 0x4d42 // BITMAPFILEHEADER.bfType (signature)
+ && RBUFL(buf,2) == buf_len // BITMAPFILEHEADER.bfSize (file size)
+ && RBUFL(buf,10) < buf_len // BITMAPFILEHEADER.bfOffBits (offset to bitmap bits)
+ ;
+
+ return success;
+}
+
+
/*==========================================
* ギルドエンブレム変更
* S 0153 <packet len>.W <emblem data>.?B
*------------------------------------------*/
void clif_parse_GuildChangeEmblem(int fd,struct map_session_data *sd)
{
- if(!sd->state.gmaster_flag)
+ unsigned long emblem_len = RFIFOW(fd,2)-4;
+ const uint8* emblem = RFIFOP(fd,4);
+
+ if( !emblem_len || !sd->state.gmaster_flag )
return;
- guild_change_emblem(sd,RFIFOW(fd,2)-4,(char*)RFIFOP(fd,4));
+ if( !clif_validate_emblem(emblem, emblem_len) )
+ {
+ ShowWarning("clif_parse_GuildChangeEmblem: Rejected malformed guild emblem (size=%lu, accound_id=%d, char_id=%d, guild_id=%d).\n", emblem_len, sd->status.account_id, sd->status.char_id, sd->status.guild_id);
+ return;
+ }
+
+ guild_change_emblem(sd, emblem_len, (const char*)emblem);
}
/*==========================================
@@ -12496,17 +12563,17 @@ void clif_check(int fd, struct map_session_data* pl_sd)
{
WFIFOHEAD(fd,packet_len(0x214));
WFIFOW(fd, 0) = 0x214;
- WFIFOB(fd, 2) = min(pl_sd->status.str, UCHAR_MAX);
+ WFIFOB(fd, 2) = min(pl_sd->status.str, UINT8_MAX);
WFIFOB(fd, 3) = pc_need_status_point(pl_sd, SP_STR, 1);
- WFIFOB(fd, 4) = min(pl_sd->status.agi, UCHAR_MAX);
+ WFIFOB(fd, 4) = min(pl_sd->status.agi, UINT8_MAX);
WFIFOB(fd, 5) = pc_need_status_point(pl_sd, SP_AGI, 1);
- WFIFOB(fd, 6) = min(pl_sd->status.vit, UCHAR_MAX);
+ WFIFOB(fd, 6) = min(pl_sd->status.vit, UINT8_MAX);
WFIFOB(fd, 7) = pc_need_status_point(pl_sd, SP_VIT, 1);
- WFIFOB(fd, 8) = min(pl_sd->status.int_, UCHAR_MAX);
+ WFIFOB(fd, 8) = min(pl_sd->status.int_, UINT8_MAX);
WFIFOB(fd, 9) = pc_need_status_point(pl_sd, SP_INT, 1);
- WFIFOB(fd,10) = min(pl_sd->status.dex, UCHAR_MAX);
+ WFIFOB(fd,10) = min(pl_sd->status.dex, UINT8_MAX);
WFIFOB(fd,11) = pc_need_status_point(pl_sd, SP_DEX, 1);
- WFIFOB(fd,12) = min(pl_sd->status.luk, UCHAR_MAX);
+ WFIFOB(fd,12) = min(pl_sd->status.luk, UINT8_MAX);
WFIFOB(fd,13) = pc_need_status_point(pl_sd, SP_LUK, 1);
WFIFOW(fd,14) = pl_sd->battle_status.batk+pl_sd->battle_status.rhw.atk+pl_sd->battle_status.lhw.atk;
WFIFOW(fd,16) = pl_sd->battle_status.rhw.atk2+pl_sd->battle_status.lhw.atk2;
@@ -13280,34 +13347,46 @@ void clif_parse_Auction_buysell(int fd, struct map_session_data* sd)
/*==========================================
* CASH/POINT SHOP
*==========================================*/
+
+/// List of items offered in a cash shop (ZC_PC_CASH_POINT_ITEMLIST)
+/// 0287 <packet len>.W <cash point>.L { <sell price>.L <discount price>.L <item type>.B <name id>.W }*
+/// 0287 <packet len>.W <cash point>.L <kafra point>.L { <sell price>.L <discount price>.L <item type>.B <name id>.W }* (PACKETVER >= 20070711)
void clif_cashshop_show(struct map_session_data *sd, struct npc_data *nd)
{
int fd,i;
+#if PACKETVER < 20070711
+ const int offset = 8;
+#else
+ const int offset = 12;
+#endif
nullpo_retv(sd);
nullpo_retv(nd);
fd = sd->fd;
sd->npc_shopid = nd->bl.id;
- WFIFOHEAD(fd, 200 * 11 + 12);
+ WFIFOHEAD(fd,offset+nd->u.shop.count*11);
WFIFOW(fd,0) = 0x287;
- WFIFOW(fd,2) = 12 + nd->u.shop.count*11;
+ WFIFOW(fd,2) = offset+nd->u.shop.count*11;
WFIFOL(fd,4) = sd->cashPoints; // Cash Points
+#if PACKETVER >= 20070711
WFIFOL(fd,8) = sd->kafraPoints; // Kafra Points
+#endif
for( i = 0; i < nd->u.shop.count; i++ )
{
struct item_data* id = itemdb_search(nd->u.shop.shop_item[i].nameid);
- WFIFOL(fd,12+i*11) = nd->u.shop.shop_item[i].value;
- WFIFOL(fd,16+i*11) = nd->u.shop.shop_item[i].value; // Discount Price? Maybe a Discount item
- WFIFOB(fd,20+i*11) = itemtype(id->type);
- WFIFOW(fd,21+i*11) = ( id->view_id > 0 ) ? id->view_id : id->nameid;
+ WFIFOL(fd,offset+0+i*11) = nd->u.shop.shop_item[i].value;
+ WFIFOL(fd,offset+4+i*11) = nd->u.shop.shop_item[i].value; // Discount Price
+ WFIFOB(fd,offset+8+i*11) = itemtype(id->type);
+ WFIFOW(fd,offset+9+i*11) = ( id->view_id > 0 ) ? id->view_id : id->nameid;
}
WFIFOSET(fd,WFIFOW(fd,2));
}
/// Cashshop Buy Ack (ZC_PC_CASH_POINT_UPDATE)
-/// S 0289 <cash point>.L <kafra point>.L <error>.W
+/// S 0289 <cash point>.L <error>.W
+/// S 0289 <cash point>.L <kafra point>.L <error>.W (PACKETVER >= 20070711)
///
/// @param error
/// 0: The deal has successfully completed. (ERROR_TYPE_NONE)
@@ -13326,20 +13405,30 @@ void clif_cashshop_ack(struct map_session_data* sd, int error)
WFIFOHEAD(fd, packet_len(0x289));
WFIFOW(fd,0) = 0x289;
WFIFOL(fd,2) = sd->cashPoints;
+#if PACKETVER < 20070711
+ WFIFOW(fd,6) = TOW(error);
+#else
WFIFOL(fd,6) = sd->kafraPoints;
WFIFOW(fd,10) = TOW(error);
+#endif
WFIFOSET(fd, packet_len(0x289));
}
+/// Request to buy item(s) from cash shop (CZ_PC_BUY_CASH_POINT_ITEM).
+/// 0288 <name id>.W <amount>.W
+/// 0288 <name id>.W <amount>.W <kafra points>.L (PACKETVER >= 20070711)
+/// 0288 <packet len>.W <kafra points>.L <count>.W { <amount>.W <name id>.W }.4B*count (PACKETVER >= 20100803)
void clif_parse_cashshop_buy(int fd, struct map_session_data *sd)
{
- int fail = 0, amount, points;
+ int fail = 0, amount, points = 0;
short nameid;
nullpo_retv(sd);
nameid = RFIFOW(fd,2);
amount = RFIFOW(fd,4);
+#if PACKETVER >= 20070711
points = RFIFOL(fd,6); // Not Implemented. Should be 0
+#endif
if( sd->state.trading || !sd->npc_shopid )
fail = 1;
@@ -13662,11 +13751,11 @@ void clif_mercenary_updatestatus(struct map_session_data *sd, int type)
case SP_ATK1:
{
int atk = rand()%(status->rhw.atk2 - status->rhw.atk + 1) + status->rhw.atk;
- WFIFOL(fd,4) = cap_value(atk, 0, SHRT_MAX);
+ WFIFOL(fd,4) = cap_value(atk, 0, INT16_MAX);
}
break;
case SP_MATK1:
- WFIFOL(fd,4) = cap_value(status->matk_max, 0, SHRT_MAX);
+ WFIFOL(fd,4) = cap_value(status->matk_max, 0, INT16_MAX);
break;
case SP_HIT:
WFIFOL(fd,4) = status->hit;
@@ -13727,8 +13816,8 @@ void clif_mercenary_info(struct map_session_data *sd)
// Mercenary shows ATK as a random value between ATK ~ ATK2
atk = rand()%(status->rhw.atk2 - status->rhw.atk + 1) + status->rhw.atk;
- WFIFOW(fd,6) = cap_value(atk, 0, SHRT_MAX);
- WFIFOW(fd,8) = cap_value(status->matk_max, 0, SHRT_MAX);
+ WFIFOW(fd,6) = cap_value(atk, 0, INT16_MAX);
+ WFIFOW(fd,8) = cap_value(status->matk_max, 0, INT16_MAX);
WFIFOW(fd,10) = status->hit;
WFIFOW(fd,12) = status->cri/10;
WFIFOW(fd,14) = status->def;
@@ -13813,11 +13902,14 @@ void clif_rental_time(int fd, int nameid, int seconds)
WFIFOSET(fd,8);
}
-void clif_rental_expired(int fd, int nameid)
+
+/// Deletes a rental item from client's inventory (ZC_CASH_ITEM_DELETE).
+/// 0299 <index>.W <nameid>.W
+void clif_rental_expired(int fd, int index, int nameid)
{ // '<ItemName>' item has been deleted from the Inventory
WFIFOHEAD(fd,6);
WFIFOW(fd,0) = 0x0299;
- WFIFOW(fd,2) = 0;
+ WFIFOW(fd,2) = index+2;
WFIFOW(fd,4) = nameid;
WFIFOSET(fd,6);
}
@@ -13850,7 +13942,7 @@ int clif_bg_hp(struct map_session_data *sd)
WBUFW(buf,0)=cmd;
WBUFL(buf,2) = sd->status.account_id;
#if PACKETVER < 20100126
- if( sd->battle_status.max_hp > SHRT_MAX )
+ if( sd->battle_status.max_hp > INT16_MAX )
{ // To correctly display the %hp bar. [Skotlex]
WBUFW(buf,6) = sd->battle_status.hp/(sd->battle_status.max_hp/100);
WBUFW(buf,8) = 100;
@@ -14581,7 +14673,7 @@ void clif_search_store_info_ack(struct map_session_data* sd)
WFIFOW(fd,2) = 7+(end-start)*blocksize;
WFIFOB(fd,4) = !sd->searchstore.pages;
WFIFOB(fd,5) = searchstore_querynext(sd);
- WFIFOB(fd,6) = (unsigned char)min(sd->searchstore.uses, UCHAR_MAX);
+ WFIFOB(fd,6) = (unsigned char)min(sd->searchstore.uses, UINT8_MAX);
for( i = start; i < end; i++ )
{
@@ -14650,7 +14742,7 @@ void clif_open_search_store_info(struct map_session_data* sd)
WFIFOW(fd,0) = 0x83a;
WFIFOW(fd,2) = sd->searchstore.effect;
#if PACKETVER > 20100701
- WFIFOB(fd,4) = (unsigned char)min(sd->searchstore.uses, UCHAR_MAX);
+ WFIFOB(fd,4) = (unsigned char)min(sd->searchstore.uses, UINT8_MAX);
#endif
WFIFOSET(fd,packet_len(0x83a));
}
@@ -14985,7 +15077,11 @@ static int packetdb_readdb(void)
6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
//#0x0280
- 0, 0, 0, 6, 0, 0, 0, 0, 0, 12, 18, 0, 0, 0, 0, 0,
+#if PACKETVER < 20070711
+ 0, 0, 0, 6, 0, 0, 0, -1, 6, 8, 18, 0, 0, 0, 0, 0,
+#else
+ 0, 0, 0, 6, 0, 0, 0, -1, 10, 12, 18, 0, 0, 0, 0, 0, // 0x288, 0x289 increase by 4 (kafra points)
+#endif
0, 4, 0, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
85, -1, -1,107, 6, -1, 7, 7, 22,191, 0, 0, 0, 0, 0, 0,
@@ -15096,7 +15192,7 @@ static int packetdb_readdb(void)
#else // 0x7d9 changed
6, 2, -1, 4, 4, 4, 4, 8, 8,268, 6, 8, 6, 54, 30, 54,
#endif
- 0, 0, 0, 0, 0, 8, 8, 32, -1, 5, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 0, 8, 8, 32, -1, 5, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 14, -1, -1, -1, 8, 25, 0, 0, 26, 0,
//#0x0800
#if PACKETVER < 20091229
diff --git a/src/map/clif.h b/src/map/clif.h
index 0feeb22b5..620ba0668 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -323,6 +323,7 @@ int clif_mob_equip(struct mob_data *md,int nameid); // [Valaris]
int clif_skillinfoblock(struct map_session_data *sd);
int clif_skillup(struct map_session_data *sd,int skill_num);
+void clif_skillinfo(struct map_session_data *sd,int skill, int inf);
int clif_addskill(struct map_session_data *sd, int skill);
int clif_deleteskill(struct map_session_data *sd, int skill);
@@ -419,7 +420,7 @@ int clif_hpmeter_sub(struct block_list *bl, va_list ap);
// guild
int clif_guild_created(struct map_session_data *sd,int flag);
-int clif_guild_belonginfo(struct map_session_data *sd,struct guild *g);
+void clif_guild_belonginfo(struct map_session_data *sd,struct guild *g);
int clif_guild_masterormember(struct map_session_data *sd);
int clif_guild_basicinfo(struct map_session_data *sd);
int clif_guild_allianceinfo(struct map_session_data *sd);
@@ -584,7 +585,7 @@ void clif_mercenary_updatestatus(struct map_session_data *sd, int type);
// RENTAL SYSTEM
void clif_rental_time(int fd, int nameid, int seconds);
-void clif_rental_expired(int fd, int nameid);
+void clif_rental_expired(int fd, int index, int nameid);
// BOOK READING
void clif_readbook(int fd, int book_id, int page);
diff --git a/src/map/itemdb.h b/src/map/itemdb.h
index c94534566..6a201008e 100644
--- a/src/map/itemdb.h
+++ b/src/map/itemdb.h
@@ -122,7 +122,7 @@ int itemdb_searchrandomid(int flags);
#define itemdb_value_buy(n) itemdb_search(n)->value_buy
#define itemdb_value_sell(n) itemdb_search(n)->value_sell
-#define itemdb_canrefine(n) itemdb_search(n)->flag.no_refine
+#define itemdb_canrefine(n) (!itemdb_search(n)->flag.no_refine)
//Item trade restrictions [Skotlex]
int itemdb_isdropable_sub(struct item_data *, int, int);
int itemdb_cantrade_sub(struct item_data*, int, int);
diff --git a/src/map/map.c b/src/map/map.c
index bc9465781..39077de6c 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -2305,7 +2305,7 @@ int map_random_dir(struct block_list *bl, short *x, short *y)
if (dist < 1) dist =1;
do {
- j = rand()%8; //Pick a random direction
+ j = 1 + 2*(rand()%4); //Pick a random diagonal direction
segment = 1+(rand()%dist); //Pick a random interval from the whole vector in that direction
xi = bl->x + segment*dirx[j];
segment = (short)sqrt((float)(dist2 - segment*segment)); //The complement of the previously picked segment
@@ -2676,7 +2676,7 @@ static char *map_init_mapcache(FILE *fp)
fseek(fp, 0, SEEK_SET);
// Allocate enough space
- CREATE(buffer, unsigned char, size);
+ CREATE(buffer, char, size);
// No memory? Return..
nullpo_ret(buffer);
@@ -2699,7 +2699,7 @@ int map_readfromcache(struct map_data *m, char *buffer, char *decode_buffer)
int i;
struct map_cache_main_header *header = (struct map_cache_main_header *)buffer;
struct map_cache_map_info *info = NULL;
- unsigned char *p = buffer + sizeof(struct map_cache_main_header);
+ char *p = buffer + sizeof(struct map_cache_main_header);
for(i = 0; i < header->map_count; i++) {
info = (struct map_cache_map_info *)p;
@@ -2906,8 +2906,8 @@ int map_readallmaps (void)
int i;
FILE* fp=NULL;
int maps_removed = 0;
- unsigned char *map_cache_buffer = NULL; // Has the uncompressed gat data of all maps, so just one allocation has to be made
- unsigned char map_cache_decode_buffer[MAX_MAP_SIZE];
+ char *map_cache_buffer = NULL; // Has the uncompressed gat data of all maps, so just one allocation has to be made
+ char map_cache_decode_buffer[MAX_MAP_SIZE];
if( enable_grf )
ShowStatus("Loading maps (using GRF files)...\n");
diff --git a/src/map/map.h b/src/map/map.h
index a9277c330..6fbb36cdc 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -535,6 +535,7 @@ struct map_data {
unsigned partylock :1;
unsigned guildlock :1;
unsigned src4instance : 1; // To flag this map when it's used as a src map for instances
+ unsigned reset :1; // [Daegaladh]
} flag;
struct point save;
struct npc_data *npc[MAX_NPC_PER_MAP];
diff --git a/src/map/mob.c b/src/map/mob.c
index 9b83440dd..5272b17e8 100644
--- a/src/map/mob.c
+++ b/src/map/mob.c
@@ -2259,10 +2259,11 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
int itemid = 0;
for (i = 0; i < ARRAYLENGTH(sd->add_drop) && (sd->add_drop[i].id || sd->add_drop[i].group); i++)
{
- if ( ( sd->add_drop[i].race <= (1<<status->race) &&
- sd->add_drop[i].race & (1<<status->race) ||
- sd->add_drop[i].race & 1<<(status->mode&MD_BOSS?RC_BOSS:RC_NONBOSS) ) ||
- ( sd->add_drop[i].race > (1<<RC_MAX) && sd->add_drop[i].race == md->class_) )
+ if ( sd->add_drop[i].race == -md->class_ ||
+ ( sd->add_drop[i].race > 0 && (
+ sd->add_drop[i].race & (1<<status->race) ||
+ sd->add_drop[i].race & (1<<(status->mode&MD_BOSS?RC_BOSS:RC_NONBOSS))
+ )))
{
//check if the bonus item drop rate should be multiplied with mob level/10 [Lupus]
if(sd->add_drop[i].rate < 0) {
@@ -3638,6 +3639,9 @@ static bool mob_parse_dbrow(char** str)
// Finally insert monster's data into the database.
if (mob_db_data[class_] == NULL)
mob_db_data[class_] = (struct mob_db*)aCalloc(1, sizeof(struct mob_db));
+ else
+ //Copy over spawn data
+ memcpy(&db->spawn, mob_db_data[class_]->spawn, sizeof(db->spawn));
memcpy(mob_db_data[class_], db, sizeof(struct mob_db));
return true;
@@ -3960,6 +3964,21 @@ static bool mob_parse_row_mobskilldb(char** str, int columns, int current)
static const struct {
char str[32];
enum MobSkillState id;
+ } state[] = {
+ { "any", MSS_ANY }, //All states except Dead
+ { "idle", MSS_IDLE },
+ { "walk", MSS_WALK },
+ { "loot", MSS_LOOT },
+ { "dead", MSS_DEAD },
+ { "attack", MSS_BERSERK }, //Retaliating attack
+ { "angry", MSS_ANGRY }, //Preemptive attack (aggressive mobs)
+ { "chase", MSS_RUSH }, //Chase escaping target
+ { "follow", MSS_FOLLOW }, //Preemptive chase (aggressive mobs)
+ { "anytarget",MSS_ANYTARGET }, //Berserk+Angry+Rush+Follow
+ };
+ static const struct {
+ char str[32];
+ int id;
} cond1[] = {
{ "always", MSC_ALWAYS },
{ "myhpltmaxrate", MSC_MYHPLTMAXRATE },
@@ -3997,17 +4016,6 @@ static bool mob_parse_row_mobskilldb(char** str, int columns, int current)
{ "blind", SC_BLIND },
{ "hiding", SC_HIDING },
{ "sight", SC_SIGHT },
- }, state[] = {
- { "any", MSS_ANY }, //All states except Dead
- { "idle", MSS_IDLE },
- { "walk", MSS_WALK },
- { "loot", MSS_LOOT },
- { "dead", MSS_DEAD },
- { "attack", MSS_BERSERK }, //Retaliating attack
- { "angry", MSS_ANGRY }, //Preemptive attack (aggressive mobs)
- { "chase", MSS_RUSH }, //Chase escaping target
- { "follow", MSS_FOLLOW }, //Preemptive chase (aggressive mobs)
- { "anytarget",MSS_ANYTARGET }, //Berserk+Angry+Rush+Follow
}, target[] = {
{ "target", MST_TARGET },
{ "randomtarget", MST_RANDOM },
diff --git a/src/map/npc.c b/src/map/npc.c
index dd3a671b0..897475f73 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -2340,7 +2340,7 @@ const char* npc_parse_duplicate(char* w1, char* w2, char* w3, char* w4, const ch
nd->speed = 200;
nd->src_id = src_id;
nd->bl.type = BL_NPC;
- nd->subtype = type;
+ nd->subtype = (enum npc_subtype)type;
switch( type )
{
case SCRIPT:
@@ -3117,6 +3117,8 @@ static const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, con
map[m].flag.partylock=state;
else if (!strcmpi(w3,"guildlock"))
map[m].flag.guildlock=state;
+ else if (!strcmpi(w3,"reset"))
+ map[m].flag.reset=state;
else
ShowError("npc_parse_mapflag: unrecognized mapflag '%s' (file '%s', line '%d').\n", w3, filepath, strline(buffer,start-buffer));
diff --git a/src/map/npc_chat.c b/src/map/npc_chat.c
index 99fa40a20..77c875a7e 100644
--- a/src/map/npc_chat.c
+++ b/src/map/npc_chat.c
@@ -73,8 +73,8 @@
struct pcrematch_entry {
struct pcrematch_entry* next;
char* pattern;
- pcre* pcre;
- pcre_extra* pcre_extra;
+ pcre* pcre_;
+ pcre_extra* pcre_extra_;
char* label;
};
@@ -108,8 +108,8 @@ struct npc_parse {
*/
void finalize_pcrematch_entry(struct pcrematch_entry* e)
{
- pcre_free(e->pcre);
- pcre_free(e->pcre_extra);
+ pcre_free(e->pcre_);
+ pcre_free(e->pcre_extra_);
aFree(e->pattern);
aFree(e->label);
}
@@ -316,8 +316,8 @@ void npc_chat_def_pattern(struct npc_data* nd, int setid, const char* pattern, c
struct pcrematch_entry *e = create_pcrematch_entry(s);
e->pattern = aStrdup(pattern);
e->label = aStrdup(label);
- e->pcre = pcre_compile(pattern, PCRE_CASELESS, &err, &erroff, NULL);
- e->pcre_extra = pcre_study(e->pcre, 0, &err);
+ e->pcre_ = pcre_compile(pattern, PCRE_CASELESS, &err, &erroff, NULL);
+ e->pcre_extra_ = pcre_study(e->pcre_, 0, &err);
}
/**
@@ -373,7 +373,7 @@ int npc_chat_sub(struct block_list* bl, va_list ap)
int offsets[2*10 + 10]; // 1/3 reserved for temp space requred by pcre_exec
// perform pattern match
- int r = pcre_exec(e->pcre, e->pcre_extra, msg, len, 0, 0, offsets, ARRAYLENGTH(offsets));
+ int r = pcre_exec(e->pcre_, e->pcre_extra_, msg, len, 0, 0, offsets, ARRAYLENGTH(offsets));
if (r > 0)
{
// save out the matched strings
diff --git a/src/map/pc.c b/src/map/pc.c
index 1869372ae..ff775be07 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -335,8 +335,8 @@ void pc_inventory_rentals(struct map_session_data *sd)
if( sd->status.inventory[i].expire_time <= time(NULL) )
{
- clif_rental_expired(sd->fd, sd->status.inventory[i].nameid);
- pc_delitem(sd, i, sd->status.inventory[i].amount, 0, 0);
+ clif_rental_expired(sd->fd, i, sd->status.inventory[i].nameid);
+ pc_delitem(sd, i, sd->status.inventory[i].amount, 1, 0);
}
else
{
@@ -347,48 +347,6 @@ void pc_inventory_rentals(struct map_session_data *sd)
}
}
- for( i = 0; i < MAX_CART; i++ )
- { // Check for Rentals on Cart
- if( sd->status.cart[i].nameid == 0 )
- continue; // Nothing here
- if( sd->status.cart[i].expire_time == 0 )
- continue;
-
- if( sd->status.cart[i].expire_time <= time(NULL) )
- {
- clif_rental_expired(sd->fd, sd->status.cart[i].nameid);
- pc_cart_delitem(sd, i, 1, 0);
- }
- else
- {
- expire_tick = (unsigned int)(sd->status.cart[i].expire_time - time(NULL)) * 1000;
- clif_rental_time(sd->fd, sd->status.cart[i].nameid, (int)(expire_tick / 1000));
- next_tick = min(expire_tick, next_tick);
- c++;
- }
- }
-
- for( i = 0; i < MAX_STORAGE; i++ )
- { // Check for Rentals on Storage
- if( sd->status.storage.items[i].nameid == 0 )
- continue;
- if( sd->status.storage.items[i].expire_time == 0 )
- continue;
-
- if( sd->status.storage.items[i].expire_time <= time(NULL) )
- {
- clif_rental_expired(sd->fd, sd->status.storage.items[i].nameid);
- storage_delitem(sd, i, 1);
- }
- else
- {
- expire_tick = (unsigned int)(sd->status.storage.items[i].expire_time - time(NULL)) * 1000;
- clif_rental_time(sd->fd, sd->status.storage.items[i].nameid, (int)(expire_tick / 1000));
- next_tick = min(expire_tick, next_tick);
- c++;
- }
- }
-
if( c > 0 ) // min(next_tick,3600000) 1 hour each timer to keep announcing to the owner, and to avoid a but with rental time > 15 days
sd->rental_timer = add_timer(gettick() + min(next_tick,3600000), pc_inventory_rental_end, sd->bl.id, 0);
else
@@ -762,13 +720,17 @@ int pc_isequip(struct map_session_data *sd,int n)
return 0;
if(item->sex != 2 && sd->status.sex != item->sex)
return 0;
- if(map[sd->bl.m].flag.pvp && ((item->flag.no_equip&1) || !pc_isAllowedCardOn(sd,item->slot,n,1)))
+ if(!map_flag_vs(sd->bl.m) && ((item->flag.no_equip&1) || !pc_isAllowedCardOn(sd,item->slot,n,1)))
+ return 0;
+ if(map[sd->bl.m].flag.pvp && ((item->flag.no_equip&2) || !pc_isAllowedCardOn(sd,item->slot,n,2)))
+ return 0;
+ if(map_flag_gvg(sd->bl.m) && ((item->flag.no_equip&4) || !pc_isAllowedCardOn(sd,item->slot,n,4)))
+ return 0;
+ if(map[sd->bl.m].flag.battleground && ((item->flag.no_equip&8) || !pc_isAllowedCardOn(sd,item->slot,n,8)))
return 0;
- if(map_flag_gvg(sd->bl.m) && ((item->flag.no_equip&2) || !pc_isAllowedCardOn(sd,item->slot,n,2)))
- return 0;
if(map[sd->bl.m].flag.restricted)
{
- int flag =map[sd->bl.m].zone;
+ int flag =8*map[sd->bl.m].zone;
if (item->flag.no_equip&flag || !pc_isAllowedCardOn(sd,item->slot,n,flag))
return 0;
}
@@ -1608,7 +1570,8 @@ static int pc_bonus_item_drop(struct s_add_drop *drop, const short max, short id
for(i = 0; i < max && (drop[i].id || drop[i].group); i++) {
if(
((id && drop[i].id == id) ||
- (group && drop[i].group == group)) && race < (1<<RC_MAX)
+ (group && drop[i].group == group))
+ && race > 0
) {
drop[i].race |= race;
if(drop[i].rate > 0 && rate > 0)
@@ -2884,7 +2847,7 @@ int pc_bonus3(struct map_session_data *sd,int type,int type2,int type3,int val)
break;
case SP_ADD_CLASS_DROP_ITEM:
if(sd->state.lr_flag != 2)
- pc_bonus_item_drop(sd->add_drop, ARRAYLENGTH(sd->add_drop), type2, 0, type3, val);
+ pc_bonus_item_drop(sd->add_drop, ARRAYLENGTH(sd->add_drop), type2, 0, -type3, val);
break;
case SP_AUTOSPELL:
if(sd->state.lr_flag != 2)
@@ -3731,6 +3694,11 @@ int pc_isUseitem(struct map_session_data *sd,int n)
if( nameid == 12243 && sd->md->db->lv < 80 )
return 0;
break;
+
+ case 12213: //Neuralizer
+ if( !map[sd->bl.m].flag.reset )
+ return 0;
+ break;
}
if( nameid >= 12153 && nameid <= 12182 && sd->md != NULL )
@@ -3738,9 +3706,11 @@ int pc_isUseitem(struct map_session_data *sd,int n)
//added item_noequip.txt items check by Maya&[Lupus]
if (
- (map[sd->bl.m].flag.pvp && item->flag.no_equip&1) || // PVP
- (map_flag_gvg(sd->bl.m) && item->flag.no_equip&2) || // GVG
- (map[sd->bl.m].flag.restricted && item->flag.no_equip&map[sd->bl.m].zone) // Zone restriction
+ (!map_flag_vs(sd->bl.m) && item->flag.no_equip&1) || // Normal
+ (map[sd->bl.m].flag.pvp && item->flag.no_equip&2) || // PVP
+ (map_flag_gvg(sd->bl.m) && item->flag.no_equip&4) || // GVG
+ (map[sd->bl.m].flag.battleground && item->flag.no_equip&8) || // Battleground
+ (map[sd->bl.m].flag.restricted && item->flag.no_equip&(8*map[sd->bl.m].zone)) // Zone restriction
)
return 0;
@@ -7444,7 +7414,7 @@ int pc_equipitem(struct map_session_data *sd,int n,int req_pos)
pos = pc_equippoint(sd,n); //With a few exceptions, item should go in all specified slots.
if(battle_config.battle_log)
- ShowInfo("equip %d(%d) %x:%x\n",sd->status.inventory[n].nameid,n,id->equip,req_pos);
+ ShowInfo("equip %d(%d) %x:%x\n",sd->status.inventory[n].nameid,n,id?id->equip:0,req_pos);
if(!pc_isequip(sd,n) || !(pos&req_pos) || sd->status.inventory[n].equip != 0 || sd->status.inventory[n].attribute==1 ) { // [Valaris]
clif_equipitemack(sd,n,0,0); // fail
return 0;
@@ -7752,9 +7722,11 @@ int pc_checkitem(struct map_session_data *sd)
if( it )
{ // check for forbiden items.
int flag =
- (map[sd->bl.m].flag.restricted?map[sd->bl.m].zone:0)
- | (map[sd->bl.m].flag.pvp?1:0)
- | (map_flag_gvg(sd->bl.m)?2:0);
+ (map[sd->bl.m].flag.restricted?(8*map[sd->bl.m].zone):0)
+ | (!map_flag_vs(sd->bl.m)?1:0)
+ | (map[sd->bl.m].flag.pvp?2:0)
+ | (map_flag_gvg(sd->bl.m)?4:0)
+ | (map[sd->bl.m].flag.battleground?8:0);
if( flag && (it->flag.no_equip&flag || !pc_isAllowedCardOn(sd,it->slot,i,flag)) )
{
pc_unequipitem(sd, i, 2);
diff --git a/src/map/pc.h b/src/map/pc.h
index 46e96ff85..a49c4628e 100644
--- a/src/map/pc.h
+++ b/src/map/pc.h
@@ -10,7 +10,6 @@
#include "buyingstore.h" // struct s_buyingstore
#include "itemdb.h" // MAX_ITEMGROUP
#include "map.h" // RC_MAX
-#include "pc.h" // struct map_session_data
#include "script.h" // struct script_reg, struct script_regstr
#include "searchstore.h" // struct s_search_store_info
#include "status.h" // OPTION_*, struct weapon_atk
@@ -102,7 +101,6 @@ struct map_session_data {
unsigned int lr_flag : 2;
unsigned int connect_new : 1;
unsigned int arrow_atk : 1;
- unsigned int combo : 2; // 1:Asura, 2:Kick [Inkfish]
unsigned int gangsterparadise : 1;
unsigned int rest : 1;
unsigned int storage_flag : 2; //0: closed, 1: Normal Storage open, 2: guild storage open [Skotlex]
diff --git a/src/map/script.c b/src/map/script.c
index 451e5a40b..881d2f082 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -348,7 +348,8 @@ enum {
MF_ALLOWKS,
MF_MONSTER_NOTELEPORT,
MF_PVP_NOCALCRANK, //50
- MF_BATTLEGROUND
+ MF_BATTLEGROUND,
+ MF_RESET
};
const char* script_op2name(int op)
@@ -901,7 +902,7 @@ int add_word(const char* p)
disp_error_message("script:add_word: invalid word. A word consists of undercores and/or alfanumeric characters, and valid variable prefixes/postfixes.", p);
// Duplicate the word
- word = aMalloc(len+1);
+ word = (char*)aMalloc(len+1);
memcpy(word, p, len);
word[len] = 0;
@@ -4559,7 +4560,7 @@ BUILDIN_FUNC(warpparty)
struct party_data* p;
int type;
int mapindex;
- int i, j;
+ int i;
const char* str = script_getstr(st,2);
int x = script_getnum(st,3);
@@ -4579,9 +4580,27 @@ BUILDIN_FUNC(warpparty)
: ( strcmp(str,"Leader")==0 ) ? 3
: 4;
- if( type == 2 && ( sd = script_rid2sd(st) ) == NULL )
- {// "SavePoint" uses save point of the currently attached player
- return 0;
+ switch (type)
+ {
+ case 3:
+ for(i = 0; i < MAX_PARTY && !p->party.member[i].leader; i++);
+ if (i == MAX_PARTY || !p->data[i].sd) //Leader not found / not online
+ return 0;
+ pl_sd = p->data[i].sd;
+ mapindex = pl_sd->mapindex;
+ x = pl_sd->bl.x;
+ y = pl_sd->bl.y;
+ break;
+ case 4:
+ mapindex = mapindex_name2id(str);
+ break;
+ case 2:
+ //"SavePoint" uses save point of the currently attached player
+ if (( sd = script_rid2sd(st) ) == NULL )
+ return 0;
+ default:
+ mapindex = 0;
+ break;
}
for (i = 0; i < MAX_PARTY; i++)
@@ -4610,25 +4629,9 @@ BUILDIN_FUNC(warpparty)
pc_setpos(pl_sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,CLR_TELEPORT);
break;
case 3: // Leader
- for(j = 0; j < MAX_PARTY && !p->party.member[j].leader; j++);
- if (j == MAX_PARTY || !p->data[j].sd) //Leader not found / not online
- return 0;
- mapindex = p->data[j].sd->mapindex;
- x = p->data[j].sd->bl.x;
- y = p->data[j].sd->bl.y;
- for (j = 0; j < MAX_PARTY; j++)
- {
- pl_sd = p->data[j].sd;
- if (!pl_sd)
- continue;
- if(map[pl_sd->bl.m].flag.noreturn || map[pl_sd->bl.m].flag.nowarp)
- continue;
- pc_setpos(pl_sd,mapindex,x,y,CLR_TELEPORT);
- }
- break;
case 4: // m,x,y
if(!map[pl_sd->bl.m].flag.noreturn && !map[pl_sd->bl.m].flag.nowarp)
- pc_setpos(pl_sd,mapindex_name2id(str),x,y,CLR_TELEPORT);
+ pc_setpos(pl_sd,mapindex,x,y,CLR_TELEPORT);
break;
}
}
@@ -5568,8 +5571,8 @@ BUILDIN_FUNC(checkweight)
}
/*==========================================
- * getitem <item id>,<amount>{,<character ID>};
- * getitem "<item name>",<amount>{,<character ID>};
+ * getitem <item id>,<amount>{,<account ID>};
+ * getitem "<item name>",<amount>{,<account ID>};
*------------------------------------------*/
BUILDIN_FUNC(getitem)
{
@@ -6574,6 +6577,9 @@ BUILDIN_FUNC(strnpcinfo)
case 3: // unique name
name = aStrdup(nd->exname);
break;
+ case 4: // map name
+ name = aStrdup(map[nd->bl.m].name);
+ break;
}
if(name)
@@ -9628,6 +9634,7 @@ BUILDIN_FUNC(getmapflag)
case MF_MONSTER_NOTELEPORT: script_pushint(st,map[m].flag.monster_noteleport); break;
case MF_PVP_NOCALCRANK: script_pushint(st,map[m].flag.pvp_nocalcrank); break;
case MF_BATTLEGROUND: script_pushint(st,map[m].flag.battleground); break;
+ case MF_RESET: script_pushint(st,map[m].flag.reset); break;
}
}
@@ -9697,6 +9704,7 @@ BUILDIN_FUNC(setmapflag)
case MF_MONSTER_NOTELEPORT: map[m].flag.monster_noteleport=1; break;
case MF_PVP_NOCALCRANK: map[m].flag.pvp_nocalcrank=1; break;
case MF_BATTLEGROUND: map[m].flag.battleground = (!val || atoi(val) < 0 || atoi(val) > 2) ? 1 : atoi(val); break;
+ case MF_RESET: map[m].flag.reset=1; break;
}
}
@@ -9763,6 +9771,7 @@ BUILDIN_FUNC(removemapflag)
case MF_MONSTER_NOTELEPORT: map[m].flag.monster_noteleport=0; break;
case MF_PVP_NOCALCRANK: map[m].flag.pvp_nocalcrank=0; break;
case MF_BATTLEGROUND: map[m].flag.battleground=0; break;
+ case MF_RESET: map[m].flag.reset=0; break;
}
}
@@ -13448,13 +13457,23 @@ BUILDIN_FUNC(unitwarp)
short x;
short y;
struct block_list* bl;
+ const char *mapname;
unit_id = script_getnum(st,2);
- map = map_mapname2mapid(script_getstr(st, 3));
+ mapname = script_getstr(st, 3);
x = (short)script_getnum(st,4);
y = (short)script_getnum(st,5);
+
+ if (!unit_id) //Warp the script's runner
+ bl = map_id2bl(st->rid);
+ else
+ bl = map_id2bl(unit_id);
+
+ if( strcmp(mapname,"this") == 0 )
+ map = bl?bl->m:-1;
+ else
+ map = map_mapname2mapid(mapname);
- bl = map_id2bl(unit_id);
if( map >= 0 && bl != NULL )
script_pushint(st, unit_warp(bl,map,x,y,CLR_OUTSIGHT));
else
diff --git a/src/map/searchstore.c b/src/map/searchstore.c
index 76f0d4e2e..c59c13bed 100644
--- a/src/map/searchstore.c
+++ b/src/map/searchstore.c
@@ -184,7 +184,7 @@ void searchstore_query(struct map_session_data* sd, unsigned char type, unsigned
searchstore_clear(sd);
// allocate max. amount of results
- sd->searchstore.items = aMalloc(sizeof(struct s_search_store_info_item)*battle_config.searchstore_maxresults);
+ sd->searchstore.items = (struct s_search_store_info_item*)aMalloc(sizeof(struct s_search_store_info_item)*battle_config.searchstore_maxresults);
// search
s.search_sd = sd;
@@ -215,7 +215,7 @@ void searchstore_query(struct map_session_data* sd, unsigned char type, unsigned
if( sd->searchstore.count )
{
// reclaim unused memory
- sd->searchstore.items = aRealloc(sd->searchstore.items, sizeof(struct s_search_store_info_item)*sd->searchstore.count);
+ sd->searchstore.items = (struct s_search_store_info_item*)aRealloc(sd->searchstore.items, sizeof(struct s_search_store_info_item)*sd->searchstore.count);
// present results
clif_search_store_info_ack(sd);
diff --git a/src/map/skill.c b/src/map/skill.c
index 3f386bbb7..976f50bd4 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -270,8 +270,8 @@ int skill_get_range2 (struct block_list *bl, int id, int lv)
int skill_calc_heal(struct block_list *src, struct block_list *target, int skill_id, int skill_lv, bool heal)
{
int skill, hp, mod = 100;
- struct map_session_data *sd = map_id2sd(src->id);
- struct map_session_data *tsd = map_id2sd(target->id);
+ struct map_session_data *sd = BL_CAST(BL_PC, src);
+ struct map_session_data *tsd = BL_CAST(BL_PC, target);
struct status_change* sc;
struct status_data *status;
bool FullCalc = false;
@@ -1067,8 +1067,9 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int
tbl = (sd->autospell[i].id < 0) ? src : bl;
- if( !battle_check_range(src, tbl, skill_get_range2(src, skill,skilllv) + (skill == RG_CLOSECONFINE?0:1)) && battle_config.autospell_check_range )
- continue; // If autospell_check_range is yes, fail the autocast.
+ if( battle_config.autospell_check_range &&
+ !battle_check_range(src, tbl, skill_get_range2(src, skill,skilllv) + (skill == RG_CLOSECONFINE?0:1)) )
+ continue;
if (skill == AS_SONICBLOW)
pc_stop_attack(sd); //Special case, Sonic Blow autospell should stop the player attacking.
@@ -1172,7 +1173,8 @@ int skill_onskillusage(struct map_session_data *sd, struct block_list *bl, int s
continue;
tbl = (sd->autospell3[i].id < 0) ? &sd->bl : bl;
- if( !battle_check_range(&sd->bl, tbl, skill_get_range2(&sd->bl, skill,skilllv) + (skill == RG_CLOSECONFINE?0:1)) && battle_config.autospell_check_range )
+ if( battle_config.autospell_check_range &&
+ !battle_check_range(&sd->bl, tbl, skill_get_range2(&sd->bl, skill,skilllv) + (skill == RG_CLOSECONFINE?0:1)) )
continue;
sd->state.autocast = 1;
@@ -1699,13 +1701,10 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
//Spirit of Wizard blocks Kaite's reflection
if( type == 2 && sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_WIZARD )
- { //Consume one Fragment per hit of the casted skill. Val3 is the skill id and val4 is the ID of the damage src.
- //This should account for ground spells (and single target spells will be completed on castend_id) [Skotlex]
- type = pc_search_inventory (tsd, 7321);
- if (type >= 0)
- pc_delitem(tsd, type, 1, 0, 1);
-
+ { //Consume one Fragment per hit of the casted skill? [Skotlex]
+ type = tsd?pc_search_inventory (tsd, 7321):0;
if (type >= 0) {
+ if ( tsd ) pc_delitem(tsd, type, 1, 0, 1);
dmg.damage = dmg.damage2 = 0;
dmg.dmg_lv = ATK_MISS;
sc->data[SC_SPIRIT]->val3 = skillid;
@@ -1757,7 +1756,8 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
if(sd) {
int flag = 0; //Used to signal if this skill can be combo'ed later on.
- if (sd->sc.data[SC_COMBO])
+ struct status_change_entry *sce;
+ if ((sce = sd->sc.data[SC_COMBO]))
{ //End combo state after skill is invoked. [Skotlex]
switch (skillid) {
case TK_TURNKICK:
@@ -1766,13 +1766,10 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
case TK_COUNTER:
if (pc_famerank(sd->status.char_id,MAPID_TAEKWON))
{ //Extend combo time.
- sd->skillid_old = skillid; //Set as previous so you can't repeat
- sd->skilllv_old = skilllv;
- sd->sc.data[SC_COMBO]->val1 = skillid; //Update combo-skill
- delete_timer(sd->sc.data[SC_COMBO]->timer, status_change_timer);
- sd->sc.data[SC_COMBO]->timer = add_timer(
- tick+sd->sc.data[SC_COMBO]->val4,
- status_change_timer, src->id, SC_COMBO);
+ sce->val1 = skillid; //Update combo-skill
+ sce->val3 = skillid;
+ delete_timer(sce->timer, status_change_timer);
+ sce->timer = add_timer(tick+sce->val4, status_change_timer, src->id, SC_COMBO);
break;
}
unit_cancel_combo(src); // Cancel combo wait
@@ -1808,7 +1805,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
if( (tstatus->race == RC_BRUTE || tstatus->race == RC_INSECT) && pc_checkskill(sd, HT_POWER))
{
//TODO: This code was taken from Triple Blows, is this even how it should be? [Skotlex]
- sc_start4(src,SC_COMBO,100,HT_POWER,bl->id,0,0,2000);
+ sc_start2(src,SC_COMBO,100,HT_POWER,bl->id,2000);
clif_combo_delay(src,2000);
}
break;
@@ -1831,9 +1828,8 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
} //Switch End
if (flag) { //Possible to chain
flag = DIFF_TICK(sd->ud.canact_tick, tick);
- if (flag < 0) flag = 0;
- flag += 300 * battle_config.combo_delay_rate/100;
- sc_start(src,SC_COMBO,100,skillid,flag);
+ if (flag < 1) flag = 1;
+ sc_start2(src,SC_COMBO,100,skillid,bl->id,flag);
clif_combo_delay(src, flag);
}
}
@@ -3337,7 +3333,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
break;
{
int per = 0, sper = 0;
- if (status_get_sc(bl)->data[SC_HELLPOWER])
+ if (tsc && tsc->data[SC_HELLPOWER])
break;
if (map[bl->m].flag.pvp && dstsd && dstsd->pvp_point < 0)
@@ -3385,7 +3381,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
case AL_CRUCIS:
if (flag&1)
- sc_start(bl,type, 23+skilllv*4 +status_get_lv(src) -status_get_lv(bl), skilllv,60000);
+ sc_start(bl,type, 23+skilllv*4 +status_get_lv(src) -status_get_lv(bl), skilllv,skill_get_time(skillid,skilllv));
else {
map_foreachinrange(skill_area_sub, src, skill_get_splash(skillid, skilllv), BL_CHAR,
src, skillid, skilllv, tick, flag|BCT_ENEMY|1, skill_castend_nodamage_id);
@@ -3470,7 +3466,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
break;
heal = status_percent_heal(bl, 100, 0);
clif_skill_nodamage(NULL, bl, AL_HEAL, heal, 1);
- if( skillid == NPC_ALLHEAL && dstmd )
+ if( dstmd )
{ // Reset Damage Logs
memset(dstmd->dmglog, 0, sizeof(dstmd->dmglog));
dstmd->tdmg = 0;
@@ -3936,7 +3932,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
mer->devotion_flag = 1; // Mercenary Devoting Owner
clif_skill_nodamage(src, bl, skillid, skilllv,
- sc_start4(bl, type, 100, src->id, i, skill_get_range2(src,skillid,skilllv), skill_get_time2(skillid, skilllv), 1000));
+ sc_start4(bl, type, 100, src->id, i, skill_get_range2(src,skillid,skilllv),0, skill_get_time2(skillid, skilllv)));
clif_devotion(src, NULL);
}
break;
@@ -6479,7 +6475,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, int skillid, int sk
case SA_VIOLENTGALE:
{ //Does not consumes if the skill is already active. [Skotlex]
struct skill_unit_group *sg;
- if ((sg= skill_locate_element_field(&sd->bl)) != NULL && ( sg->skill_id == SA_VOLCANO || sg->skill_id == SA_DELUGE || sg->skill_id == SA_VIOLENTGALE ))
+ if ((sg= skill_locate_element_field(src)) != NULL && ( sg->skill_id == SA_VOLCANO || sg->skill_id == SA_DELUGE || sg->skill_id == SA_VIOLENTGALE ))
{
if (sg->limit - DIFF_TICK(gettick(), sg->tick) > 0)
{
@@ -6697,7 +6693,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, int skillid, int sk
}
} else {
int i = skilllv%11 - 1;
- struct item_data *item = itemdb_search(i);
+ struct item_data *item;
i = skill_db[skillid].itemid[i];
item = itemdb_search(i);
potion_flag = 1;
@@ -8566,7 +8562,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, short skill, sh
require = skill_get_requirement(sd,skill,lv);
//Can only update state when weapon/arrow info is checked.
- if (require.weapon) sd->state.arrow_atk = require.ammo?1:0;
+ sd->state.arrow_atk = require.ammo?1:0;
// perform skill-specific checks (and actions)
switch( skill )
@@ -8669,14 +8665,14 @@ int skill_check_condition_castbegin(struct map_session_data* sd, short skill, sh
return 0; //Anti-Soul Linker check in case you job-changed with Stances active.
if(!(sc && sc->data[SC_COMBO]))
return 0; //Combo needs to be ready
- if (pc_famerank(sd->status.char_id,MAPID_TAEKWON))
- { //Unlimited Combo
- if (skill == sd->skillid_old) {
- status_change_end(&sd->bl, SC_COMBO, INVALID_TIMER);
- sd->skillid_old = sd->skilllv_old = 0;
- return 0; //Can't repeat previous combo skill.
- }
- break;
+
+ if (sc->data[SC_COMBO]->val3)
+ { //Kick chain
+ //Do not repeat a kick.
+ if (sc->data[SC_COMBO]->val3 != skill)
+ break;
+ status_change_end(&sd->bl, SC_COMBO, INVALID_TIMER);
+ return 0;
}
if(sc->data[SC_COMBO]->val1 != skill)
{ //Cancel combo wait.
@@ -8696,7 +8692,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, short skill, sh
if (skill_get_time(
(sc->data[SC_DANCING]->val1&0xFFFF), //Dance Skill ID
(sc->data[SC_DANCING]->val1>>16)) //Dance Skill LV
- - time <= skill_get_time2(skill,lv))
+ - time < skill_get_time2(skill,lv))
{
clif_skill_fail(sd,skill,0,0);
return 0;
@@ -9256,9 +9252,11 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, short
req.weapon = skill_db[j].weapon;
- req.ammo = skill_db[j].ammo;
req.ammo_qty = skill_db[j].ammo_qty[lv-1];
- if (req.weapon && !req.ammo && skill && skill_isammotype(sd, skill))
+ if (req.ammo_qty)
+ req.ammo = skill_db[j].ammo;
+
+ if (!req.ammo && skill && skill_isammotype(sd, skill))
{ //Assume this skill is using the weapon, therefore it requires arrows.
req.ammo = 0xFFFFFFFF; //Enable use on all ammo types.
req.ammo_qty = 1;
@@ -12088,9 +12086,9 @@ static bool skill_parse_row_requiredb(char* split[], int columns, int current)
for( j = 0; j < 32; j++ )
{
int l = atoi(p);
- if( l == 99 ) // magic value?
+ if( l == 99 ) // Any weapon
{
- skill_db[i].weapon = 0xffffffff;
+ skill_db[i].weapon = 0;
break;
}
else
@@ -12106,12 +12104,12 @@ static bool skill_parse_row_requiredb(char* split[], int columns, int current)
for( j = 0; j < 32; j++ )
{
int l = atoi(p);
- if( l == 99 ) // magic value?
+ if( l == 99 ) // Any ammo type
{
- skill_db[i].ammo = 0xffffffff;
+ skill_db[i].ammo = 0xFFFFFFFF;
break;
}
- else if( l ) // 0 not allowed?
+ else if( l ) // 0 stands for no requirement
skill_db[i].ammo |= 1<<l;
p = strchr(p,':');
if( !p )
diff --git a/src/map/sql/CMakeLists.txt b/src/map/sql/CMakeLists.txt
index 74598423a..eadddb2a0 100644
--- a/src/map/sql/CMakeLists.txt
+++ b/src/map/sql/CMakeLists.txt
@@ -2,90 +2,92 @@
#
# map sql
#
-if( HAVE_common_sql )
+if( BUILD_SQL_SERVERS )
message( STATUS "Creating target map-server_sql" )
set( SQL_MAP_HEADERS
- "${MAP_SOURCE_DIR}/atcommand.h"
- "${MAP_SOURCE_DIR}/battle.h"
- "${MAP_SOURCE_DIR}/battleground.h"
- "${MAP_SOURCE_DIR}/buyingstore.h"
- "${MAP_SOURCE_DIR}/chat.h"
- "${MAP_SOURCE_DIR}/chrif.h"
- "${MAP_SOURCE_DIR}/clif.h"
- "${MAP_SOURCE_DIR}/date.h"
- "${MAP_SOURCE_DIR}/duel.h"
- "${MAP_SOURCE_DIR}/guild.h"
- "${MAP_SOURCE_DIR}/homunculus.h"
- "${MAP_SOURCE_DIR}/instance.h"
- "${MAP_SOURCE_DIR}/intif.h"
- "${MAP_SOURCE_DIR}/itemdb.h"
- "${MAP_SOURCE_DIR}/log.h"
- "${MAP_SOURCE_DIR}/mail.h"
- "${MAP_SOURCE_DIR}/map.h"
- "${MAP_SOURCE_DIR}/mapreg.h"
- "${MAP_SOURCE_DIR}/mercenary.h"
- "${MAP_SOURCE_DIR}/mob.h"
- "${MAP_SOURCE_DIR}/npc.h"
- "${MAP_SOURCE_DIR}/party.h"
- "${MAP_SOURCE_DIR}/path.h"
- "${MAP_SOURCE_DIR}/pc.h"
- "${MAP_SOURCE_DIR}/pet.h"
- "${MAP_SOURCE_DIR}/quest.h"
- "${MAP_SOURCE_DIR}/script.h"
- "${MAP_SOURCE_DIR}/searchstore.h"
- "${MAP_SOURCE_DIR}/skill.h"
- "${MAP_SOURCE_DIR}/status.h"
- "${MAP_SOURCE_DIR}/storage.h"
- "${MAP_SOURCE_DIR}/trade.h"
- "${MAP_SOURCE_DIR}/unit.h"
- "${MAP_SOURCE_DIR}/vending.h"
+ "${SQL_MAP_SOURCE_DIR}/atcommand.h"
+ "${SQL_MAP_SOURCE_DIR}/battle.h"
+ "${SQL_MAP_SOURCE_DIR}/battleground.h"
+ "${SQL_MAP_SOURCE_DIR}/buyingstore.h"
+ "${SQL_MAP_SOURCE_DIR}/chat.h"
+ "${SQL_MAP_SOURCE_DIR}/chrif.h"
+ "${SQL_MAP_SOURCE_DIR}/clif.h"
+ "${SQL_MAP_SOURCE_DIR}/date.h"
+ "${SQL_MAP_SOURCE_DIR}/duel.h"
+ "${SQL_MAP_SOURCE_DIR}/guild.h"
+ "${SQL_MAP_SOURCE_DIR}/homunculus.h"
+ "${SQL_MAP_SOURCE_DIR}/instance.h"
+ "${SQL_MAP_SOURCE_DIR}/intif.h"
+ "${SQL_MAP_SOURCE_DIR}/itemdb.h"
+ "${SQL_MAP_SOURCE_DIR}/log.h"
+ "${SQL_MAP_SOURCE_DIR}/mail.h"
+ "${SQL_MAP_SOURCE_DIR}/map.h"
+ "${SQL_MAP_SOURCE_DIR}/mapreg.h"
+ "${SQL_MAP_SOURCE_DIR}/mercenary.h"
+ "${SQL_MAP_SOURCE_DIR}/mob.h"
+ "${SQL_MAP_SOURCE_DIR}/npc.h"
+ "${SQL_MAP_SOURCE_DIR}/party.h"
+ "${SQL_MAP_SOURCE_DIR}/path.h"
+ "${SQL_MAP_SOURCE_DIR}/pc.h"
+ "${SQL_MAP_SOURCE_DIR}/pet.h"
+ "${SQL_MAP_SOURCE_DIR}/quest.h"
+ "${SQL_MAP_SOURCE_DIR}/script.h"
+ "${SQL_MAP_SOURCE_DIR}/searchstore.h"
+ "${SQL_MAP_SOURCE_DIR}/skill.h"
+ "${SQL_MAP_SOURCE_DIR}/status.h"
+ "${SQL_MAP_SOURCE_DIR}/storage.h"
+ "${SQL_MAP_SOURCE_DIR}/trade.h"
+ "${SQL_MAP_SOURCE_DIR}/unit.h"
+ "${SQL_MAP_SOURCE_DIR}/vending.h"
)
set( SQL_MAP_SOURCES
- "${MAP_SOURCE_DIR}/atcommand.c"
- "${MAP_SOURCE_DIR}/battle.c"
- "${MAP_SOURCE_DIR}/battleground.c"
- "${MAP_SOURCE_DIR}/buyingstore.c"
- "${MAP_SOURCE_DIR}/chat.c"
- "${MAP_SOURCE_DIR}/chrif.c"
- "${MAP_SOURCE_DIR}/clif.c"
- "${MAP_SOURCE_DIR}/date.c"
- "${MAP_SOURCE_DIR}/duel.c"
- "${MAP_SOURCE_DIR}/guild.c"
- "${MAP_SOURCE_DIR}/homunculus.c"
- "${MAP_SOURCE_DIR}/instance.c"
- "${MAP_SOURCE_DIR}/intif.c"
- "${MAP_SOURCE_DIR}/itemdb.c"
- "${MAP_SOURCE_DIR}/log.c"
- "${MAP_SOURCE_DIR}/mail.c"
- "${MAP_SOURCE_DIR}/map.c"
- "${MAP_SOURCE_DIR}/mapreg_sql.c"
- "${MAP_SOURCE_DIR}/mercenary.c"
- "${MAP_SOURCE_DIR}/mob.c"
- "${MAP_SOURCE_DIR}/npc.c"
- "${MAP_SOURCE_DIR}/npc_chat.c"
- "${MAP_SOURCE_DIR}/party.c"
- "${MAP_SOURCE_DIR}/path.c"
- "${MAP_SOURCE_DIR}/pc.c"
- "${MAP_SOURCE_DIR}/pet.c"
- "${MAP_SOURCE_DIR}/quest.c"
- "${MAP_SOURCE_DIR}/script.c"
- "${MAP_SOURCE_DIR}/searchstore.c"
- "${MAP_SOURCE_DIR}/skill.c"
- "${MAP_SOURCE_DIR}/status.c"
- "${MAP_SOURCE_DIR}/storage.c"
- "${MAP_SOURCE_DIR}/trade.c"
- "${MAP_SOURCE_DIR}/unit.c"
- "${MAP_SOURCE_DIR}/vending.c"
+ "${SQL_MAP_SOURCE_DIR}/atcommand.c"
+ "${SQL_MAP_SOURCE_DIR}/battle.c"
+ "${SQL_MAP_SOURCE_DIR}/battleground.c"
+ "${SQL_MAP_SOURCE_DIR}/buyingstore.c"
+ "${SQL_MAP_SOURCE_DIR}/chat.c"
+ "${SQL_MAP_SOURCE_DIR}/chrif.c"
+ "${SQL_MAP_SOURCE_DIR}/clif.c"
+ "${SQL_MAP_SOURCE_DIR}/date.c"
+ "${SQL_MAP_SOURCE_DIR}/duel.c"
+ "${SQL_MAP_SOURCE_DIR}/guild.c"
+ "${SQL_MAP_SOURCE_DIR}/homunculus.c"
+ "${SQL_MAP_SOURCE_DIR}/instance.c"
+ "${SQL_MAP_SOURCE_DIR}/intif.c"
+ "${SQL_MAP_SOURCE_DIR}/itemdb.c"
+ "${SQL_MAP_SOURCE_DIR}/log.c"
+ "${SQL_MAP_SOURCE_DIR}/mail.c"
+ "${SQL_MAP_SOURCE_DIR}/map.c"
+ "${SQL_MAP_SOURCE_DIR}/mapreg_sql.c"
+ "${SQL_MAP_SOURCE_DIR}/mercenary.c"
+ "${SQL_MAP_SOURCE_DIR}/mob.c"
+ "${SQL_MAP_SOURCE_DIR}/npc.c"
+ "${SQL_MAP_SOURCE_DIR}/npc_chat.c"
+ "${SQL_MAP_SOURCE_DIR}/party.c"
+ "${SQL_MAP_SOURCE_DIR}/path.c"
+ "${SQL_MAP_SOURCE_DIR}/pc.c"
+ "${SQL_MAP_SOURCE_DIR}/pet.c"
+ "${SQL_MAP_SOURCE_DIR}/quest.c"
+ "${SQL_MAP_SOURCE_DIR}/script.c"
+ "${SQL_MAP_SOURCE_DIR}/searchstore.c"
+ "${SQL_MAP_SOURCE_DIR}/skill.c"
+ "${SQL_MAP_SOURCE_DIR}/status.c"
+ "${SQL_MAP_SOURCE_DIR}/storage.c"
+ "${SQL_MAP_SOURCE_DIR}/trade.c"
+ "${SQL_MAP_SOURCE_DIR}/unit.c"
+ "${SQL_MAP_SOURCE_DIR}/vending.c"
)
set( DEPENDENCIES common_sql )
set( LIBRARIES ${GLOBAL_LIBRARIES} )
set( INCLUDE_DIRS ${GLOBAL_INCLUDE_DIRS} )
-set( DEFINITIONS ${GLOBAL_DEFINITIONS} )
+set( DEFINITIONS "${GLOBAL_DEFINITIONS}" )
if( WITH_PCRE )
- message( STATUS "Using PCRE" )
- list( APPEND LIBRARIES ${PCRE_LIBRARIES} )
- list( APPEND INCLUDE_DIRS ${PCRE_INCLUDE_DIRS} )
- list( APPEND DEFINITIONS PCRE_SUPPORT )
+ message( STATUS "Enabled PCRE code" )
+ set( LIBRARIES ${LIBRARIES} ${PCRE_LIBRARIES} )
+ set( INCLUDE_DIRS ${INCLUDE_DIRS} ${PCRE_INCLUDE_DIRS} )
+ set( DEFINITIONS "${DEFINITIONS} -DPCRE_SUPPORT" )
+else()
+ message( STATUS "Disabled PCRE code" )
endif()
set( SOURCE_FILES ${COMMON_BASE_HEADERS} ${COMMON_SQL_HEADERS} ${SQL_MAP_HEADERS} ${SQL_MAP_SOURCES} )
source_group( common FILES ${COMMON_BASE_HEADERS} ${COMMON_SQL_HEADERS} )
@@ -94,17 +96,13 @@ include_directories( ${INCLUDE_DIRS} )
add_executable( map-server_sql ${SOURCE_FILES} )
add_dependencies( map-server_sql ${DEPENDENCIES} )
target_link_libraries( map-server_sql ${LIBRARIES} ${DEPENDENCIES} )
-set_target_properties( map-server_sql PROPERTIES COMPILE_DEFINITIONS "${DEFINITIONS}" )
-if( WITH_COMPONENT_RUNTIME )
+set_target_properties( map-server_sql PROPERTIES COMPILE_FLAGS "${DEFINITIONS}" )
+if( INSTALL_COMPONENT_RUNTIME )
cpack_add_component( Runtime_mapserver_sql DESCRIPTION "map-server (sql version)" DISPLAY_NAME "map-server_sql" GROUP Runtime )
install( TARGETS map-server_sql
DESTINATION "."
COMPONENT Runtime_mapserver_sql )
-endif()
+endif( INSTALL_COMPONENT_RUNTIME )
+set( TARGET_LIST ${TARGET_LIST} map-server_sql CACHE INTERNAL "" )
message( STATUS "Creating target map-server_sql - done" )
-set( HAVE_map-server_sql ON CACHE BOOL "map-server_sql target is available" )
-mark_as_advanced( HAVE_map-server_sql )
-else()
-message( STATUS "Skipping target map-server_sql (requires common_sql; optional PCRE)" )
-unset( HAVE_map-server_sql CACHE )
-endif()
+endif( BUILD_SQL_SERVERS )
diff --git a/src/map/status.c b/src/map/status.c
index 933d18690..cf3d17228 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -673,7 +673,7 @@ int status_charge(struct block_list* bl, int hp, int sp)
//If flag&1, damage is passive and does not triggers cancelling status changes.
//If flag&2, fail if target does not has enough to substract.
//If flag&4, if killed, mob must not give exp/loot.
-//If flag&8, sp loss on dead target.
+//flag will be set to &8 when damaging sp of a dead character
int status_damage(struct block_list *src,struct block_list *target,int hp, int sp, int walkdelay, int flag)
{
struct status_data *status;
@@ -683,18 +683,15 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
sp = 0; //Not a valid SP target.
if (hp < 0) { //Assume absorbed damage.
- status_heal(target, cap_value(-hp, INT_MIN, INT_MAX), 0, 1);
+ status_heal(target, -hp, 0, 1);
hp = 0;
}
if (sp < 0) {
- status_heal(target, 0, cap_value(-sp, INT_MIN, INT_MAX), 1);
+ status_heal(target, 0, -sp, 1);
sp = 0;
}
- if (!hp && !sp)
- return 0;
-
if (target->type == BL_SKILL)
return skill_unit_ondamaged((struct skill_unit *)target, src, hp, gettick());
@@ -702,6 +699,19 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
if( status == &dummy_status )
return 0;
+ if ((unsigned int)hp >= status->hp) {
+ if (flag&2) return 0;
+ hp = status->hp;
+ }
+
+ if ((unsigned int)sp > status->sp) {
+ if (flag&2) return 0;
+ sp = status->sp;
+ }
+
+ if (!hp && !sp)
+ return 0;
+
if( !status->hp )
flag |= 8;
@@ -711,10 +721,10 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
// return 0; //Cannot damage a bl not on a map, except when "charging" hp/sp
sc = status_get_sc(target);
- if( battle_config.invincible_nodamage && src && sc && sc->data[SC_INVINCIBLE] && !sc->data[SC_INVINCIBLEOFF] )
+ if( hp && battle_config.invincible_nodamage && src && sc && sc->data[SC_INVINCIBLE] && !sc->data[SC_INVINCIBLEOFF] )
hp = 1;
- if( hp && !(flag&(1|8)) ) {
+ if( hp && !(flag&1) ) {
if( sc ) {
struct status_change_entry *sce;
if (sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
@@ -748,16 +758,6 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
unit_skillcastcancel(target, 2);
}
- if ((unsigned int)hp >= status->hp) {
- if (flag&2) return 0;
- hp = status->hp;
- }
-
- if ((unsigned int)sp > status->sp) {
- if (flag&2) return 0;
- sp = status->sp;
- }
-
status->hp-= hp;
status->sp-= sp;
@@ -778,7 +778,7 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
case BL_MER: mercenary_damage((TBL_MER*)target,src,hp,sp); break;
}
- if( status->hp || flag&8 )
+ if( status->hp || (flag&8) )
{ //Still lives or has been dead before this damage.
if (walkdelay)
unit_set_walkdelay(target, gettick(), walkdelay, 0);
@@ -822,11 +822,11 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
}
}
- if( !(flag&8) && sc && sc->data[SC_KAIZEL] )
+ if( sc && sc->data[SC_KAIZEL] )
{ //flag&8 = disable Kaizel
int time = skill_get_time2(SL_KAIZEL,sc->data[SC_KAIZEL]->val1);
//Look for Osiris Card's bonus effect on the character and revive 100% or revive normally
- if ( target->type == BL_PC && BL_CAST(BL_PC,target)->special_state.restart_full_recover == 1 )
+ if ( target->type == BL_PC && BL_CAST(BL_PC,target)->special_state.restart_full_recover )
status_revive(target, 100, 100);
else
status_revive(target, sc->data[SC_KAIZEL]->val2, 0);
@@ -886,7 +886,8 @@ int status_heal(struct block_list *bl,int hp,int sp, int flag)
sc = NULL;
if (hp < 0) {
- status_damage(NULL, bl, cap_value(-hp, INT_MIN, INT_MAX), 0, 0, 1);
+ if (hp == INT_MIN) hp++; //-INT_MIN == INT_MIN in some architectures!
+ status_damage(NULL, bl, -hp, 0, 0, 1);
hp = 0;
}
@@ -899,7 +900,8 @@ int status_heal(struct block_list *bl,int hp,int sp, int flag)
}
if(sp < 0) {
- status_damage(NULL, bl, 0, cap_value(-sp, INT_MIN, INT_MAX), 0, 1);
+ if (sp==INT_MIN) sp++;
+ status_damage(NULL, bl, 0, -sp, 0, 1);
sp = 0;
}
@@ -1539,19 +1541,14 @@ int status_calc_mob_(struct mob_data* md, bool first)
gc=guild_mapname2gc(map[md->bl.m].name);
if (!gc)
ShowError("status_calc_mob: No castle set at map %s\n", map[md->bl.m].name);
- else {
- if(gc->castle_id > 23) {
- if(md->class_ == MOBID_EMPERIUM) {
- status->max_hp += 1000 * gc->defense;
- status->max_sp += 200 * gc->defense;
- status->hp = status->max_hp;
- status->sp = status->max_sp;
- }
- }else{
- status->max_hp += 1000 * gc->defense;
- status->max_sp += 200 * gc->defense;
- status->hp = status->max_hp;
- status->sp = status->max_sp;
+ else
+ if(gc->castle_id < 24 || md->class_ == MOBID_EMPERIUM) {
+ status->max_hp += 1000 * gc->defense;
+ status->max_sp += 200 * gc->defense;
+ status->hp = status->max_hp;
+ status->sp = status->max_sp;
+ if( gc->castle_id < 24 )
+ {
status->def += (gc->defense+2)/3;
status->mdef += (gc->defense+2)/3;
}
@@ -2034,11 +2031,15 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
if(!data->script)
continue;
if(data->flag.no_equip) { //Card restriction checks.
- if(map[sd->bl.m].flag.restricted && data->flag.no_equip&map[sd->bl.m].zone)
+ if(map[sd->bl.m].flag.restricted && data->flag.no_equip&(8*map[sd->bl.m].zone))
+ continue;
+ if(!map_flag_vs(sd->bl.m) && data->flag.no_equip&1)
+ continue;
+ if(map[sd->bl.m].flag.pvp && data->flag.no_equip&2)
continue;
- if(map[sd->bl.m].flag.pvp && data->flag.no_equip&1)
+ if(map_flag_gvg(sd->bl.m) && data->flag.no_equip&4)
continue;
- if(map_flag_gvg(sd->bl.m) && data->flag.no_equip&2)
+ if(map[sd->bl.m].flag.battleground && data->flag.no_equip&8)
continue;
}
if(i == EQI_HAND_L && sd->status.inventory[index].equip == EQP_HAND_L)
@@ -2466,6 +2467,11 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
status_cpy(&sd->battle_status, status);
// ----- CLIENT-SIDE REFRESH -----
+ if(!sd->bl.prev) {
+ //Will update on LoadEndAck
+ calculating = 0;
+ return 0;
+ }
if(memcmp(b_skill,sd->status.skill,sizeof(sd->status.skill)))
clif_skillinfoblock(sd);
if(b_weight != sd->weight)
@@ -2740,7 +2746,7 @@ void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, str
if (
sc->data[SC_DANCING]
|| (
- (((TBL_PC*)bl)->class_&MAPID_UPPERMASK) == MAPID_MONK &&
+ (bl->type == BL_PC && ((TBL_PC*)bl)->class_&MAPID_UPPERMASK) == MAPID_MONK &&
(sc->data[SC_EXTREMITYFIST] || (sc->data[SC_EXPLOSIONSPIRITS] && (!sc->data[SC_SPIRIT] || sc->data[SC_SPIRIT]->val2 != SL_MONK)))
)
|| sc->data[SC_MAXIMIZEPOWER]
@@ -2773,7 +2779,7 @@ void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, str
/// Recalculates parts of an object's battle status according to the specified flags.
/// @param flag bitfield of values from enum scb_flag
-void status_calc_bl_main(struct block_list *bl, enum scb_flag flag)
+void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
{
const struct status_data *b_status = status_get_base_status(bl);
struct status_data *status = status_get_status_data(bl);
@@ -5897,44 +5903,17 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
//val1: Skill ID
//val2: When given, target (for autotargetting skills)
//val3: When set, this combo time should NOT delay attack/movement
- //val4: Combo time
+ //val3: TK: Last used kick
+ //val4: TK: Combo time
struct unit_data *ud = unit_bl2ud(bl);
- switch (val1) {
- case TK_STORMKICK:
- clif_skill_nodamage(bl,bl,TK_READYSTORM,1,1);
- break;
- case TK_DOWNKICK:
- clif_skill_nodamage(bl,bl,TK_READYDOWN,1,1);
- break;
- case TK_TURNKICK:
- clif_skill_nodamage(bl,bl,TK_READYTURN,1,1);
- break;
- case TK_COUNTER:
- clif_skill_nodamage(bl,bl,TK_READYCOUNTER,1,1);
- break;
- case MO_COMBOFINISH:
- case CH_TIGERFIST:
- case CH_CHAINCRUSH:
- if( sd )
- {
- sd->state.combo = 1;
- clif_skillinfoblock(sd);
- }
- break;
- case TK_JUMPKICK:
- if( sd )
- {
- sd->state.combo = 2;
- clif_skillinfoblock(sd);
- }
- break;
- }
if (ud && !val3)
{
+ tick += 300 * battle_config.combo_delay_rate/100;
ud->attackabletime = gettick()+tick;
unit_set_walkdelay(bl, gettick(), tick, 1);
}
- val4 = tick; //Store combo-time in val4.
+ val3 = 0;
+ val4 = tick;
}
break;
case SC_EARTHSCROLL:
@@ -6498,6 +6477,31 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_MERC_SPUP:
status_percent_heal(bl, 0, 100); // Recover Full SP
break;
+ case SC_COMBO:
+ switch (sce->val1) {
+ case TK_STORMKICK:
+ clif_skill_nodamage(bl,bl,TK_READYSTORM,1,1);
+ break;
+ case TK_DOWNKICK:
+ clif_skill_nodamage(bl,bl,TK_READYDOWN,1,1);
+ break;
+ case TK_TURNKICK:
+ clif_skill_nodamage(bl,bl,TK_READYTURN,1,1);
+ break;
+ case TK_COUNTER:
+ clif_skill_nodamage(bl,bl,TK_READYCOUNTER,1,1);
+ break;
+ case MO_COMBOFINISH:
+ case CH_TIGERFIST:
+ case CH_CHAINCRUSH:
+ if (sd)
+ clif_skillinfo(sd,MO_EXTREMITYFIST, INF_SELF_SKILL);
+ break;
+ case TK_JUMPKICK:
+ if (sd)
+ clif_skillinfo(sd,TK_JUMPKICK, INF_SELF_SKILL);
+ break;
+ }
}
if( opt_flag&2 && sd && sd->touching_id )
@@ -6836,16 +6840,17 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
bl->m, bl->x-range, bl->y-range, bl->x+range,bl->y+range,BL_CHAR,bl,sce,type,gettick());
}
break;
- case SC_COMBO: //Clear last used skill when it is part of a combo.
+ case SC_COMBO:
if( sd )
- {
- if( sd->state.combo )
- {
- sd->state.combo = 0;
- clif_skillinfoblock(sd);
- }
- if( sd->skillid_old == sce->val1 )
- sd->skillid_old = sd->skilllv_old = 0;
+ switch (sce->val1) {
+ case MO_COMBOFINISH:
+ case CH_TIGERFIST:
+ case CH_CHAINCRUSH:
+ clif_skillinfo(sd, MO_EXTREMITYFIST, 0);
+ break;
+ case TK_JUMPKICK:
+ clif_skillinfo(sd, TK_JUMPKICK, 0);
+ break;
}
break;
@@ -7404,15 +7409,6 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
}
break;
- case SC_DEVOTION:
- //FIXME: use normal status duration instead of a looping timer
- if( (sce->val4 -= 1000) > 0 )
- {
- sc_timer_next(1000+tick, status_change_timer, bl->id, data);
- return 0;
- }
- break;
-
case SC_BERSERK:
// 5% every 10 seconds [DracoRPG]
if( --( sce->val3 ) > 0 && status_charge(bl, sce->val2, 0) && status->hp > 100 )
diff --git a/src/map/status.h b/src/map/status.h
index 169d193ae..27c3e1782 100644
--- a/src/map/status.h
+++ b/src/map/status.h
@@ -8,6 +8,7 @@ struct block_list;
struct mob_data;
struct pet_data;
struct homun_data;
+struct mercenary_data;
struct status_change;
//Use this to refer the max refinery level [Skotlex]
@@ -1368,7 +1369,7 @@ int status_change_timer_sub(struct block_list* bl, va_list ap);
int status_change_clear(struct block_list* bl, int type);
int status_change_clear_buffs(struct block_list* bl, int type);
-#define status_calc_bl(bl, flag) status_calc_bl_(bl, flag, false)
+#define status_calc_bl(bl, flag) status_calc_bl_(bl, (enum scb_flag)(flag), false)
#define status_calc_mob(md, first) status_calc_bl_(&(md)->bl, SCB_ALL, first)
#define status_calc_pet(pd, first) status_calc_bl_(&(pd)->bl, SCB_ALL, first)
#define status_calc_pc(sd, first) status_calc_bl_(&(sd)->bl, SCB_ALL, first)
diff --git a/src/map/txt/CMakeLists.txt b/src/map/txt/CMakeLists.txt
index d58866f96..b2634000a 100644
--- a/src/map/txt/CMakeLists.txt
+++ b/src/map/txt/CMakeLists.txt
@@ -2,90 +2,92 @@
#
# map txt
#
-if( HAVE_common_base )
+if( BUILD_TXT_SERVERS )
message( STATUS "Creating target map-server" )
set( TXT_MAP_HEADERS
- "${MAP_SOURCE_DIR}/atcommand.h"
- "${MAP_SOURCE_DIR}/battle.h"
- "${MAP_SOURCE_DIR}/battleground.h"
- "${MAP_SOURCE_DIR}/buyingstore.h"
- "${MAP_SOURCE_DIR}/chat.h"
- "${MAP_SOURCE_DIR}/chrif.h"
- "${MAP_SOURCE_DIR}/clif.h"
- "${MAP_SOURCE_DIR}/date.h"
- "${MAP_SOURCE_DIR}/duel.h"
- "${MAP_SOURCE_DIR}/guild.h"
- "${MAP_SOURCE_DIR}/homunculus.h"
- "${MAP_SOURCE_DIR}/instance.h"
- "${MAP_SOURCE_DIR}/intif.h"
- "${MAP_SOURCE_DIR}/itemdb.h"
- "${MAP_SOURCE_DIR}/log.h"
- "${MAP_SOURCE_DIR}/mail.h"
- "${MAP_SOURCE_DIR}/map.h"
- "${MAP_SOURCE_DIR}/mapreg.h"
- "${MAP_SOURCE_DIR}/mercenary.h"
- "${MAP_SOURCE_DIR}/mob.h"
- "${MAP_SOURCE_DIR}/npc.h"
- "${MAP_SOURCE_DIR}/party.h"
- "${MAP_SOURCE_DIR}/path.h"
- "${MAP_SOURCE_DIR}/pc.h"
- "${MAP_SOURCE_DIR}/pet.h"
- "${MAP_SOURCE_DIR}/quest.h"
- "${MAP_SOURCE_DIR}/script.h"
- "${MAP_SOURCE_DIR}/searchstore.h"
- "${MAP_SOURCE_DIR}/skill.h"
- "${MAP_SOURCE_DIR}/status.h"
- "${MAP_SOURCE_DIR}/storage.h"
- "${MAP_SOURCE_DIR}/trade.h"
- "${MAP_SOURCE_DIR}/unit.h"
- "${MAP_SOURCE_DIR}/vending.h"
+ "${TXT_MAP_SOURCE_DIR}/atcommand.h"
+ "${TXT_MAP_SOURCE_DIR}/battle.h"
+ "${TXT_MAP_SOURCE_DIR}/battleground.h"
+ "${TXT_MAP_SOURCE_DIR}/buyingstore.h"
+ "${TXT_MAP_SOURCE_DIR}/chat.h"
+ "${TXT_MAP_SOURCE_DIR}/chrif.h"
+ "${TXT_MAP_SOURCE_DIR}/clif.h"
+ "${TXT_MAP_SOURCE_DIR}/date.h"
+ "${TXT_MAP_SOURCE_DIR}/duel.h"
+ "${TXT_MAP_SOURCE_DIR}/guild.h"
+ "${TXT_MAP_SOURCE_DIR}/homunculus.h"
+ "${TXT_MAP_SOURCE_DIR}/instance.h"
+ "${TXT_MAP_SOURCE_DIR}/intif.h"
+ "${TXT_MAP_SOURCE_DIR}/itemdb.h"
+ "${TXT_MAP_SOURCE_DIR}/log.h"
+ "${TXT_MAP_SOURCE_DIR}/mail.h"
+ "${TXT_MAP_SOURCE_DIR}/map.h"
+ "${TXT_MAP_SOURCE_DIR}/mapreg.h"
+ "${TXT_MAP_SOURCE_DIR}/mercenary.h"
+ "${TXT_MAP_SOURCE_DIR}/mob.h"
+ "${TXT_MAP_SOURCE_DIR}/npc.h"
+ "${TXT_MAP_SOURCE_DIR}/party.h"
+ "${TXT_MAP_SOURCE_DIR}/path.h"
+ "${TXT_MAP_SOURCE_DIR}/pc.h"
+ "${TXT_MAP_SOURCE_DIR}/pet.h"
+ "${TXT_MAP_SOURCE_DIR}/quest.h"
+ "${TXT_MAP_SOURCE_DIR}/script.h"
+ "${TXT_MAP_SOURCE_DIR}/searchstore.h"
+ "${TXT_MAP_SOURCE_DIR}/skill.h"
+ "${TXT_MAP_SOURCE_DIR}/status.h"
+ "${TXT_MAP_SOURCE_DIR}/storage.h"
+ "${TXT_MAP_SOURCE_DIR}/trade.h"
+ "${TXT_MAP_SOURCE_DIR}/unit.h"
+ "${TXT_MAP_SOURCE_DIR}/vending.h"
)
set( TXT_MAP_SOURCES
- "${MAP_SOURCE_DIR}/atcommand.c"
- "${MAP_SOURCE_DIR}/battle.c"
- "${MAP_SOURCE_DIR}/battleground.c"
- "${MAP_SOURCE_DIR}/buyingstore.c"
- "${MAP_SOURCE_DIR}/chat.c"
- "${MAP_SOURCE_DIR}/chrif.c"
- "${MAP_SOURCE_DIR}/clif.c"
- "${MAP_SOURCE_DIR}/date.c"
- "${MAP_SOURCE_DIR}/duel.c"
- "${MAP_SOURCE_DIR}/guild.c"
- "${MAP_SOURCE_DIR}/homunculus.c"
- "${MAP_SOURCE_DIR}/instance.c"
- "${MAP_SOURCE_DIR}/intif.c"
- "${MAP_SOURCE_DIR}/itemdb.c"
- "${MAP_SOURCE_DIR}/log.c"
- "${MAP_SOURCE_DIR}/mail.c"
- "${MAP_SOURCE_DIR}/map.c"
- "${MAP_SOURCE_DIR}/mapreg_txt.c"
- "${MAP_SOURCE_DIR}/mercenary.c"
- "${MAP_SOURCE_DIR}/mob.c"
- "${MAP_SOURCE_DIR}/npc.c"
- "${MAP_SOURCE_DIR}/npc_chat.c"
- "${MAP_SOURCE_DIR}/party.c"
- "${MAP_SOURCE_DIR}/path.c"
- "${MAP_SOURCE_DIR}/pc.c"
- "${MAP_SOURCE_DIR}/pet.c"
- "${MAP_SOURCE_DIR}/quest.c"
- "${MAP_SOURCE_DIR}/script.c"
- "${MAP_SOURCE_DIR}/searchstore.c"
- "${MAP_SOURCE_DIR}/skill.c"
- "${MAP_SOURCE_DIR}/status.c"
- "${MAP_SOURCE_DIR}/storage.c"
- "${MAP_SOURCE_DIR}/trade.c"
- "${MAP_SOURCE_DIR}/unit.c"
- "${MAP_SOURCE_DIR}/vending.c"
+ "${TXT_MAP_SOURCE_DIR}/atcommand.c"
+ "${TXT_MAP_SOURCE_DIR}/battle.c"
+ "${TXT_MAP_SOURCE_DIR}/battleground.c"
+ "${TXT_MAP_SOURCE_DIR}/buyingstore.c"
+ "${TXT_MAP_SOURCE_DIR}/chat.c"
+ "${TXT_MAP_SOURCE_DIR}/chrif.c"
+ "${TXT_MAP_SOURCE_DIR}/clif.c"
+ "${TXT_MAP_SOURCE_DIR}/date.c"
+ "${TXT_MAP_SOURCE_DIR}/duel.c"
+ "${TXT_MAP_SOURCE_DIR}/guild.c"
+ "${TXT_MAP_SOURCE_DIR}/homunculus.c"
+ "${TXT_MAP_SOURCE_DIR}/instance.c"
+ "${TXT_MAP_SOURCE_DIR}/intif.c"
+ "${TXT_MAP_SOURCE_DIR}/itemdb.c"
+ "${TXT_MAP_SOURCE_DIR}/log.c"
+ "${TXT_MAP_SOURCE_DIR}/mail.c"
+ "${TXT_MAP_SOURCE_DIR}/map.c"
+ "${TXT_MAP_SOURCE_DIR}/mapreg_txt.c"
+ "${TXT_MAP_SOURCE_DIR}/mercenary.c"
+ "${TXT_MAP_SOURCE_DIR}/mob.c"
+ "${TXT_MAP_SOURCE_DIR}/npc.c"
+ "${TXT_MAP_SOURCE_DIR}/npc_chat.c"
+ "${TXT_MAP_SOURCE_DIR}/party.c"
+ "${TXT_MAP_SOURCE_DIR}/path.c"
+ "${TXT_MAP_SOURCE_DIR}/pc.c"
+ "${TXT_MAP_SOURCE_DIR}/pet.c"
+ "${TXT_MAP_SOURCE_DIR}/quest.c"
+ "${TXT_MAP_SOURCE_DIR}/script.c"
+ "${TXT_MAP_SOURCE_DIR}/searchstore.c"
+ "${TXT_MAP_SOURCE_DIR}/skill.c"
+ "${TXT_MAP_SOURCE_DIR}/status.c"
+ "${TXT_MAP_SOURCE_DIR}/storage.c"
+ "${TXT_MAP_SOURCE_DIR}/trade.c"
+ "${TXT_MAP_SOURCE_DIR}/unit.c"
+ "${TXT_MAP_SOURCE_DIR}/vending.c"
)
set( DEPENDENCIES common_base )
set( LIBRARIES ${GLOBAL_LIBRARIES} )
set( INCLUDE_DIRS ${GLOBAL_INCLUDE_DIRS} )
-set( DEFINITIONS ${GLOBAL_DEFINITIONS} TXT_ONLY )
+set( DEFINITIONS "${GLOBAL_DEFINITIONS} -DTXT_ONLY" )
if( WITH_PCRE )
- message( STATUS "Using PCRE" )
- list( APPEND LIBRARIES ${PCRE_LIBRARIES} )
- list( APPEND INCLUDE_DIRS ${PCRE_INCLUDE_DIRS} )
- list( APPEND DEFINITIONS PCRE_SUPPORT )
+ message( STATUS "Enabled PCRE code" )
+ set( LIBRARIES ${LIBRARIES} ${PCRE_LIBRARIES} )
+ set( INCLUDE_DIRS ${INCLUDE_DIRS} ${PCRE_INCLUDE_DIRS} )
+ set( DEFINITIONS "${DEFINITIONS} -DPCRE_SUPPORT" )
+else()
+ message( STATUS "Disabled PCRE code" )
endif()
set( SOURCE_FILES ${COMMON_BASE_HEADERS} ${TXT_MAP_HEADERS} ${TXT_MAP_SOURCES} )
source_group( common FILES ${COMMON_BASE_HEADERS} )
@@ -94,17 +96,13 @@ include_directories( ${INCLUDE_DIRS} )
add_executable( map-server ${SOURCE_FILES} )
add_dependencies( map-server ${DEPENDENCIES} )
target_link_libraries( map-server ${LIBRARIES} ${DEPENDENCIES} )
-set_target_properties( map-server PROPERTIES COMPILE_DEFINITIONS "${DEFINITIONS}" )
-if( WITH_COMPONENT_RUNTIME )
+set_target_properties( map-server PROPERTIES COMPILE_FLAGS "${DEFINITIONS}" )
+if( INSTALL_COMPONENT_RUNTIME )
cpack_add_component( Runtime_mapserver_txt DESCRIPTION "map-server (txt version)" DISPLAY_NAME "map-server" GROUP Runtime )
install( TARGETS map-server
DESTINATION "."
COMPONENT Runtime_mapserver_txt )
-endif()
+endif( INSTALL_COMPONENT_RUNTIME )
+set( TARGET_LIST ${TARGET_LIST} map-server CACHE INTERNAL "" )
message( STATUS "Creating target map-server - done" )
-set( HAVE_map-server ON CACHE BOOL "map-server target is available" )
-mark_as_advanced( HAVE_map-server )
-else()
-message( STATUS "Skipping target map-server (requires common_base; optional PCRE)" )
-unset( HAVE_map-server CACHE )
-endif()
+endif( BUILD_TXT_SERVERS )
diff --git a/src/map/unit.c b/src/map/unit.c
index cffb97b1f..c8b0e0d26 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -912,7 +912,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, short skill_num, sh
struct map_session_data *sd = NULL;
struct block_list * target = NULL;
unsigned int tick = gettick();
- int temp;
+ int temp = 0;
nullpo_ret(src);
if(status_isdead(src))
@@ -927,14 +927,21 @@ int unit_skilluse_id2(struct block_list *src, int target_id, short skill_num, sh
sc = NULL; //Unneeded
//temp: used to signal combo-skills right now.
- temp = ( target_id == src->id &&
- (
- ( !(skill_get_inf(skill_num)&INF_SELF_SKILL) && sd && sd->state.combo ) ||
- ( skill_get_inf(skill_num)&INF_SELF_SKILL && skill_get_inf2(skill_num)&INF2_NO_TARGET_SELF )
- )
- );
- if (temp)
- target_id = ud->target; //Auto-select skills. [Skotlex]
+ if (sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == skill_num)
+ {
+ if (sc->data[SC_COMBO]->val2)
+ target_id = sc->data[SC_COMBO]->val2;
+ else
+ target_id = ud->target;
+ temp = 1;
+ } else
+ if ( target_id == src->id &&
+ skill_get_inf(skill_num)&INF_SELF_SKILL &&
+ skill_get_inf2(skill_num)&INF2_NO_TARGET_SELF )
+ {
+ target_id = ud->target; //Auto-select target. [Skotlex]
+ temp = 1;
+ }
if (sd) {
//Target_id checking.
@@ -949,12 +956,6 @@ int unit_skilluse_id2(struct block_list *src, int target_id, short skill_num, sh
return 0;
}
break;
- case TK_JUMPKICK:
- case TK_COUNTER:
- case HT_POWER:
- if (sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == skill_num)
- target_id = sc->data[SC_COMBO]->val2;
- break;
case WE_MALE:
case WE_FEMALE:
if (!sd->status.partner_id)