summaryrefslogtreecommitdiff
path: root/src/map
diff options
context:
space:
mode:
Diffstat (limited to 'src/map')
-rw-r--r--src/map/Makefile.in4
-rw-r--r--src/map/atcommand.c19
-rw-r--r--src/map/atcommand.h2
-rw-r--r--src/map/battle.c2
-rw-r--r--src/map/battle.h2
-rw-r--r--src/map/battleground.c30
-rw-r--r--src/map/battleground.h4
-rw-r--r--src/map/chat.h2
-rw-r--r--src/map/clif.c226
-rw-r--r--src/map/clif.h4
-rw-r--r--src/map/duel.c189
-rw-r--r--src/map/duel.h29
-rw-r--r--src/map/guild.c21
-rw-r--r--src/map/instance.c13
-rw-r--r--src/map/intif.c2
-rw-r--r--src/map/map.c33
-rw-r--r--src/map/map.h20
-rw-r--r--src/map/mob.c54
-rw-r--r--src/map/mob.h28
-rw-r--r--src/map/npc.c30
-rw-r--r--src/map/npc.h1
-rw-r--r--src/map/pc.c268
-rw-r--r--src/map/pc.h137
-rw-r--r--src/map/quest.c20
-rw-r--r--src/map/script.c43
-rw-r--r--src/map/status.c25
-rw-r--r--src/map/status.h3
-rw-r--r--src/map/unit.c3
-rw-r--r--src/map/unit.h3
29 files changed, 734 insertions, 483 deletions
diff --git a/src/map/Makefile.in b/src/map/Makefile.in
index f45f4dd00..7070a0a9d 100644
--- a/src/map/Makefile.in
+++ b/src/map/Makefile.in
@@ -18,7 +18,7 @@ MAP_OBJ = map.o chrif.o clif.o pc.o status.o npc.o \
storage.o skill.o atcommand.o battle.o battleground.o \
intif.o trade.o party.o vending.o guild.o pet.o \
log.o mail.o date.o unit.o homunculus.o mercenary.o quest.o instance.o \
- buyingstore.o searchstore.o
+ buyingstore.o searchstore.o duel.o
MAP_TXT_OBJ = $(MAP_OBJ:%=obj_txt/%) \
obj_txt/mapreg_txt.o
MAP_SQL_OBJ = $(MAP_OBJ:%=obj_sql/%) \
@@ -28,7 +28,7 @@ MAP_H = map.h chrif.h clif.h pc.h status.h npc.h \
storage.h skill.h atcommand.h battle.h battleground.h \
intif.h trade.h party.h vending.h guild.h pet.h \
log.h mail.h date.h unit.h homunculus.h mercenary.h quest.h instance.h mapreg.h \
- buyingstore.h searchstore.h
+ buyingstore.h searchstore.h duel.h
HAVE_MYSQL=@HAVE_MYSQL@
ifeq ($(HAVE_MYSQL),yes)
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index 3eb0c37ac..7d66d1694 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -17,6 +17,7 @@
#include "chat.h"
#include "clif.h"
#include "chrif.h"
+#include "duel.h"
#include "intif.h"
#include "itemdb.h"
#include "log.h"
@@ -88,7 +89,7 @@ int lowtohigh_compare (const void * a, const void * b)
//-----------------------------------------------------------
// Return the message string of the specified number by [Yor]
//-----------------------------------------------------------
-char* msg_txt(int msg_number)
+const char* msg_txt(int msg_number)
{
if (msg_number >= 0 && msg_number < MAX_MSG &&
msg_table[msg_number] != NULL && msg_table[msg_number][0] != '\0')
@@ -5837,7 +5838,7 @@ ACMD_FUNC(skilltree)
struct map_session_data *pl_sd = NULL;
int skillnum;
int meets, j, c=0;
- char target[NAME_LENGTH], *tbl;
+ char target[NAME_LENGTH];
struct skill_tree_entry *ent;
nullpo_retr(-1, sd);
@@ -5855,9 +5856,7 @@ ACMD_FUNC(skilltree)
c = pc_calc_skilltree_normalize_job(pl_sd);
c = pc_mapid2jobid(c, pl_sd->status.sex);
- tbl = job_name(c);
-
- sprintf(atcmd_output, "Player is using %s skill tree (%d basic points)", tbl, pc_checkskill(pl_sd, 1));
+ sprintf(atcmd_output, "Player is using %s skill tree (%d basic points)", job_name(c), pc_checkskill(pl_sd, 1));
clif_displaymessage(fd, atcmd_output);
ARR_FIND( 0, MAX_SKILL_TREE, j, skill_tree[c][j].id == 0 || skill_tree[c][j].id == skillnum );
@@ -7250,7 +7249,7 @@ ACMD_FUNC(makehomun)
int homunid;
nullpo_retr(-1, sd);
- if ( merc_is_hom_active(sd->hd) ) {
+ if ( sd->status.hom_id ) {
clif_displaymessage(fd, msg_txt(450));
return -1;
}
@@ -8652,9 +8651,9 @@ ACMD_FUNC(font)
font_id = atoi(message);
if( font_id == 0 )
{
- if( sd->state.user_font )
+ if( sd->user_font )
{
- sd->state.user_font = 0;
+ sd->user_font = 0;
clif_displaymessage(fd, "Returning to normal font.");
clif_font(sd);
}
@@ -8666,9 +8665,9 @@ ACMD_FUNC(font)
}
else if( font_id < 0 || font_id > 9 )
clif_displaymessage(fd, "Invalid font. Use a Value from 0 to 9.");
- else if( font_id != sd->state.user_font )
+ else if( font_id != sd->user_font )
{
- sd->state.user_font = font_id;
+ sd->user_font = font_id;
clif_font(sd);
clif_displaymessage(fd, "Font changed.");
}
diff --git a/src/map/atcommand.h b/src/map/atcommand.h
index 37ce87ca3..5456bc348 100644
--- a/src/map/atcommand.h
+++ b/src/map/atcommand.h
@@ -41,7 +41,7 @@ int atcommand_killmonster(const int fd, struct map_session_data* sd, const char*
#define MAX_MSG 1000
extern char* msg_table[MAX_MSG];
-char* msg_txt(int msg_number);
+const char* msg_txt(int msg_number);
int msg_config_read(const char* cfgName);
void do_final_msg(void);
diff --git a/src/map/battle.c b/src/map/battle.c
index 40e59039b..11e696a7f 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -4012,6 +4012,8 @@ static const struct _battle_data {
{ "searchstore_querydelay", &battle_config.searchstore_querydelay, 10, 0, INT_MAX, },
{ "searchstore_maxresults", &battle_config.searchstore_maxresults, 30, 1, INT_MAX, },
{ "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, },
// 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 b2f33b73b..58f622321 100644
--- a/src/map/battle.h
+++ b/src/map/battle.h
@@ -486,6 +486,8 @@ extern struct Battle_Config
int searchstore_querydelay;
int searchstore_maxresults;
int display_party_name;
+ int cashshop_show_points;
+ int mail_show_status;
// [BattleGround Settings]
int bg_update_interval;
diff --git a/src/map/battleground.c b/src/map/battleground.c
index 58e3b469c..13f62a042 100644
--- a/src/map/battleground.c
+++ b/src/map/battleground.c
@@ -52,7 +52,7 @@ int bg_team_delete(int bg_id)
continue;
bg_send_dot_remove(sd);
- sd->state.bg_id = 0;
+ sd->bg_id = 0;
}
idb_remove(bg_team_db, bg_id);
return 1;
@@ -70,7 +70,7 @@ int bg_team_warp(int bg_id, unsigned short mapindex, short x, short y)
int bg_send_dot_remove(struct map_session_data *sd)
{
- if( sd && sd->state.bg_id )
+ if( sd && sd->bg_id )
clif_bg_xy_remove(sd);
return 0;
}
@@ -81,12 +81,12 @@ int bg_team_join(int bg_id, struct map_session_data *sd)
struct battleground_data *bg = bg_team_search(bg_id);
struct map_session_data *pl_sd;
- if( bg == NULL || sd == NULL || sd->state.bg_id ) return 0;
+ if( bg == NULL || sd == NULL || sd->bg_id ) return 0;
ARR_FIND(0, MAX_BG_MEMBERS, i, bg->members[i].sd == NULL);
if( i == MAX_BG_MEMBERS ) return 0; // No free slots
- sd->state.bg_id = bg_id;
+ sd->bg_id = bg_id;
bg->members[i].sd = sd;
bg->members[i].x = sd->bl.x;
bg->members[i].y = sd->bl.y;
@@ -111,12 +111,12 @@ int bg_team_leave(struct map_session_data *sd, int flag)
struct battleground_data *bg;
char output[128];
- if( sd == NULL || !sd->state.bg_id )
+ if( sd == NULL || !sd->bg_id )
return 0;
bg_send_dot_remove(sd);
- bg_id = sd->state.bg_id;
- sd->state.bg_id = 0;
+ bg_id = sd->bg_id;
+ sd->bg_id = 0;
if( (bg = bg_team_search(bg_id)) == NULL )
return 0;
@@ -141,7 +141,7 @@ int bg_team_leave(struct map_session_data *sd, int flag)
int bg_member_respawn(struct map_session_data *sd)
{ // Respawn after killed
struct battleground_data *bg;
- if( sd == NULL || !pc_isdead(sd) || !sd->state.bg_id || (bg = bg_team_search(sd->state.bg_id)) == NULL )
+ if( sd == NULL || !pc_isdead(sd) || !sd->bg_id || (bg = bg_team_search(sd->bg_id)) == NULL )
return 0;
if( bg->mapindex == 0 )
return 0; // Respawn not handled by Core
@@ -177,26 +177,26 @@ int bg_team_get_id(struct block_list *bl)
switch( bl->type )
{
case BL_PC:
- return ((TBL_PC*)bl)->state.bg_id;
+ return ((TBL_PC*)bl)->bg_id;
case BL_PET:
if( ((TBL_PET*)bl)->msd )
- return ((TBL_PET*)bl)->msd->state.bg_id;
+ return ((TBL_PET*)bl)->msd->bg_id;
break;
case BL_MOB:
{
struct map_session_data *msd;
struct mob_data *md = (TBL_MOB*)bl;
if( md->special_state.ai && (msd = map_id2sd(md->master_id)) != NULL )
- return msd->state.bg_id;
- return md->state.bg_id;
+ return msd->bg_id;
+ return md->bg_id;
}
case BL_HOM:
if( ((TBL_HOM*)bl)->master )
- return ((TBL_HOM*)bl)->master->state.bg_id;
+ return ((TBL_HOM*)bl)->master->bg_id;
break;
case BL_MER:
if( ((TBL_MER*)bl)->master )
- return ((TBL_MER*)bl)->master->state.bg_id;
+ return ((TBL_MER*)bl)->master->bg_id;
break;
case BL_SKILL:
return ((TBL_SKILL*)bl)->group->bg_id;
@@ -210,7 +210,7 @@ int bg_send_message(struct map_session_data *sd, const char *mes, int len)
struct battleground_data *bg;
nullpo_ret(sd);
- if( sd->state.bg_id == 0 || (bg = bg_team_search(sd->state.bg_id)) == NULL )
+ if( sd->bg_id == 0 || (bg = bg_team_search(sd->bg_id)) == NULL )
return 0;
clif_bg_message(bg, sd->bl.id, sd->status.name, mes, len);
return 0;
diff --git a/src/map/battleground.h b/src/map/battleground.h
index 946ac2692..c2b74a534 100644
--- a/src/map/battleground.h
+++ b/src/map/battleground.h
@@ -22,8 +22,8 @@ struct battleground_data {
// BG Cementery
unsigned short mapindex, x, y;
// Logout Event
- char logout_event[50];
- char die_event[50];
+ char logout_event[EVENT_NAME_LENGTH];
+ char die_event[EVENT_NAME_LENGTH];
};
void do_init_battleground(void);
diff --git a/src/map/chat.h b/src/map/chat.h
index be3efb513..b80832d3d 100644
--- a/src/map/chat.h
+++ b/src/map/chat.h
@@ -22,7 +22,7 @@ struct chat_data {
uint32 maxLvl; // maximum base level allowed to join
struct map_session_data* usersd[20];
struct block_list* owner;
- char npc_event[50];
+ char npc_event[EVENT_NAME_LENGTH];
};
diff --git a/src/map/clif.c b/src/map/clif.c
index e4105c170..eeb9f7532 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -451,7 +451,7 @@ int clif_send(const uint8* buf, int len, struct block_list* bl, enum send_target
if( !(fd=sd->fd) )
continue;
- if( type == GUILD_NOBG && sd->state.bg_id )
+ if( type == GUILD_NOBG && sd->bg_id )
continue;
if( sd->bl.id == bl->id && (type == GUILD_WOS || type == GUILD_SAMEMAP_WOS || type == GUILD_AREA_WOS) )
@@ -498,7 +498,7 @@ int clif_send(const uint8* buf, int len, struct block_list* bl, enum send_target
case BG_SAMEMAP_WOS:
case BG:
case BG_WOS:
- if( sd && sd->state.bg_id && (bg = bg_team_search(sd->state.bg_id)) != NULL )
+ if( sd && sd->bg_id && (bg = bg_team_search(sd->bg_id)) != NULL )
{
for( i = 0; i < MAX_BG_MEMBERS; i++ )
{
@@ -797,13 +797,19 @@ static int clif_set_unit_idle(struct block_list* bl, unsigned char* buffer, bool
WBUFW(buf,0) = spawn?0x22b:0x22a;
#elif PACKETVER < 20091103
WBUFW(buf,0) = spawn?0x2ed:0x2ee;
-#else
+#elif PACKETVER < 20101124
WBUFW(buf,0) = spawn?0x7f8:0x7f9;
+#else
+ WBUFW(buf,0) = spawn?0x858:0x857;
#endif
#if PACKETVER >= 20091103
name = status_get_name(bl);
+#if PACKETVER < 20110111
WBUFW(buf,2) = (spawn?62:63)+strlen(name);
+#else
+ WBUFW(buf,2) = (spawn?64:65)+strlen(name);
+#endif
WBUFB(buf,4) = clif_bl_type(bl);
offset+=3;
buf = WBUFP(buffer,offset);
@@ -877,6 +883,11 @@ static int clif_set_unit_idle(struct block_list* bl, unsigned char* buffer, bool
return packet_len(0x7c);
}
#endif
+#if PACKETVER >= 20110111
+ WBUFW(buf,34) = vd->robe;
+ offset+= 2;
+ buf = WBUFP(buffer,offset);
+#endif
WBUFL(buf,34) = status_get_guild_id(bl);
WBUFW(buf,38) = status_get_emblem_id(bl);
WBUFW(buf,40) = (sd)? sd->status.manner : 0;
@@ -910,7 +921,7 @@ static int clif_set_unit_idle(struct block_list* bl, unsigned char* buffer, bool
return packet_len(WBUFW(buffer,0));
#endif
#if PACKETVER >= 20080102
- WBUFW(buf,53) = sd?sd->state.user_font:0;
+ WBUFW(buf,53) = sd?sd->user_font:0;
#endif
#if PACKETVER >= 20091103
strcpy((char*)WBUFP(buf,55), name);
@@ -946,13 +957,19 @@ static int clif_set_unit_walking(struct block_list* bl, struct unit_data* ud, un
WBUFW(buf, 0) = 0x22c;
#elif PACKETVER < 20091103
WBUFW(buf, 0) = 0x2ec;
-#else
+#elif PACKETVER < 20101124
WBUFW(buf, 0) = 0x7f7;
+#else
+ WBUFW(buf, 0) = 0x856;
#endif
#if PACKETVER >= 20091103
name = status_get_name(bl);
+#if PACKETVER < 20110111
WBUFW(buf, 2) = 69+strlen(name);
+#else
+ WBUFW(buf, 2) = 71+strlen(name);
+#endif
offset+=2;
buf = WBUFP(buffer,offset);
#endif
@@ -989,6 +1006,11 @@ static int clif_set_unit_walking(struct block_list* bl, struct unit_data* ud, un
WBUFW(buf,32) = vd->hair_color;
WBUFW(buf,34) = vd->cloth_color;
WBUFW(buf,36) = (sd)? sd->head_dir : 0;
+#if PACKETVER >= 20110111
+ WBUFW(buf,38) = vd->robe;
+ offset+= 2;
+ buf = WBUFP(buffer,offset);
+#endif
WBUFL(buf,38) = status_get_guild_id(bl);
WBUFW(buf,42) = status_get_emblem_id(bl);
WBUFW(buf,44) = (sd)? sd->status.manner : 0;
@@ -1006,7 +1028,7 @@ static int clif_set_unit_walking(struct block_list* bl, struct unit_data* ud, un
WBUFB(buf,57) = (sd)? 5 : 0;
WBUFW(buf,58) = clif_setlevel(status_get_lv(bl));
#if PACKETVER >= 20080102
- WBUFW(buf,60) = sd?sd->state.user_font:0;
+ WBUFW(buf,60) = sd?sd->user_font:0;
#endif
#if PACKETVER >= 20091103
strcpy((char*)WBUFP(buf,62), name);
@@ -1144,7 +1166,7 @@ int clif_spawn(struct block_list *bl)
clif_specialeffect(bl,423,AREA);
else if(sd->state.size==1)
clif_specialeffect(bl,421,AREA);
- if( sd->state.bg_id && map[sd->bl.m].flag.battleground )
+ if( sd->bg_id && map[sd->bl.m].flag.battleground )
clif_sendbgemblem_area(sd);
}
break;
@@ -2057,7 +2079,7 @@ void clif_inventorylist(struct map_session_data *sd)
WBUFW(bufe,ne*se+28)=0; //Unknown
#endif
#if PACKETVER >= 20100629
- if (sd->inventory_data[i]->equip&EQP_HELM)
+ if (sd->inventory_data[i]->equip&EQP_VISIBLE)
WBUFW(bufe,ne*se+30)= sd->inventory_data[i]->look;
else
WBUFW(bufe,ne*se+30)=0;
@@ -2140,7 +2162,7 @@ void clif_equiplist(struct map_session_data *sd)
WBUFW(buf,n*cmd+28)=0; //Unknown
#endif
#if PACKETVER >= 20100629
- if (sd->inventory_data[i]->equip&EQP_HELM)
+ if (sd->inventory_data[i]->equip&EQP_VISIBLE)
WBUFW(buf,n*cmd+30)= sd->inventory_data[i]->look;
else
WBUFW(buf,n*cmd+30)=0;
@@ -2350,7 +2372,7 @@ int clif_guild_xy(struct map_session_data *sd)
*------------------------------------------*/
int clif_guild_xy_single(int fd, struct map_session_data *sd)
{
- if( sd->state.bg_id )
+ if( sd->bg_id )
return 0;
WFIFOHEAD(fd,packet_len(0x1eb));
@@ -2449,7 +2471,7 @@ int clif_updatestatus(struct map_session_data *sd,int type)
clif_hpmeter(sd);
if( !battle_config.party_hp_mode && sd->status.party_id )
clif_party_hp(sd);
- if( sd->state.bg_id )
+ if( sd->bg_id )
clif_bg_hp(sd);
break;
case SP_SP:
@@ -2705,6 +2727,17 @@ void clif_changelook(struct block_list *bl,int type,int val)
#endif
//Shoes? No packet uses this....
break;
+ case LOOK_BODY:
+ case LOOK_FLOOR:
+ // unknown purpose
+ break;
+ case LOOK_ROBE:
+#if PACKETVER < 20110111
+ return;
+#else
+ vd->robe = val;
+#endif
+ break;
}
// prevent leaking the presence of GM-hidden objects
@@ -2726,8 +2759,7 @@ void clif_changelook(struct block_list *bl,int type,int val)
WBUFW(buf,9)=vd->shield;
} else {
WBUFB(buf,6)=type;
- WBUFW(buf,7)=val;
- WBUFW(buf,9)=0;
+ WBUFL(buf,7)=val;
}
clif_send(buf,packet_len(0x1d7),bl,target);
#endif
@@ -2952,7 +2984,7 @@ int clif_equipitemack(struct map_session_data *sd,int n,int pos,int ok)
#if PACKETVER < 20100629
WFIFOB(fd,6)=ok;
#else
- if (ok && sd->inventory_data[n]->equip&EQP_HELM)
+ if (ok && sd->inventory_data[n]->equip&EQP_VISIBLE)
WFIFOW(fd,6)=sd->inventory_data[n]->look;
else
WFIFOW(fd,6)=0;
@@ -3649,7 +3681,7 @@ static void clif_getareachar_pc(struct map_session_data* sd,struct map_session_d
clif_spiritball_single(sd->fd, dstsd);
if( (sd->status.party_id && dstsd->status.party_id == sd->status.party_id) || //Party-mate, or hpdisp setting.
- (sd->state.bg_id && sd->state.bg_id == dstsd->state.bg_id) || //BattleGround
+ (sd->bg_id && sd->bg_id == dstsd->bg_id) || //BattleGround
(battle_config.disp_hpmeter && (gmlvl = pc_isGM(sd)) >= battle_config.disp_hpmeter && gmlvl >= pc_isGM(dstsd)) )
clif_hpmeter_single(sd->fd, dstsd->bl.id, dstsd->battle_status.hp, dstsd->battle_status.max_hp);
@@ -3692,7 +3724,7 @@ void clif_getareachar_unit(struct map_session_data* sd,struct block_list *bl)
clif_specialeffect_single(bl,423,sd->fd);
else if(tsd->state.size==1)
clif_specialeffect_single(bl,421,sd->fd);
- if( tsd->state.bg_id && map[tsd->bl.m].flag.battleground )
+ if( tsd->bg_id && map[tsd->bl.m].flag.battleground )
clif_sendbgemblem_single(sd->fd,tsd);
}
break;
@@ -4972,17 +5004,12 @@ void clif_MainChatMessage(const char* message)
/*==========================================
* Send broadcast message with font formatting.
* S 01C3 <len>.W <fontColor>.L <fontType>.W <fontSize>.W <fontAlign>.W <fontY>.W <message>.?B
- * S 040C <len>.W <fontColor>.L <fontType>.W <fontSize>.W <fontAlign>.W <fontY>.W <message>.?B
*------------------------------------------*/
int clif_broadcast2(struct block_list* bl, const char* mes, int len, unsigned long fontColor, short fontType, short fontSize, short fontAlign, short fontY, enum send_target target)
{
unsigned char *buf = (unsigned char*)aMallocA((16 + len)*sizeof(unsigned char));
-#if PACKETVER < 20080820
WBUFW(buf,0) = 0x1c3;
-#else
- WBUFW(buf,0) = 0x40c;
-#endif
WBUFW(buf,2) = len + 16;
WBUFL(buf,4) = fontColor;
WBUFW(buf,8) = fontType;
@@ -6986,7 +7013,7 @@ int clif_guild_leave(struct map_session_data *sd,const char *name,const char *me
/*==========================================
* ギルドメンバ追放通知
*------------------------------------------*/
-int clif_guild_expulsion(struct map_session_data *sd,const char *name,const char *mes,int account_id)
+void clif_guild_expulsion(struct map_session_data* sd, const char* name, const char* mes, int account_id)
{
unsigned char buf[128];
#if PACKETVER < 20100803
@@ -6995,46 +7022,58 @@ int clif_guild_expulsion(struct map_session_data *sd,const char *name,const char
const unsigned short cmd = 0x839;
#endif
- nullpo_ret(sd);
+ nullpo_retv(sd);
WBUFW(buf,0) = cmd;
- safestrncpy((char*)WBUFP(buf, 2),name,NAME_LENGTH);
- safestrncpy((char*)WBUFP(buf,26),mes,40);
+ safestrncpy((char*)WBUFP(buf,2), name, NAME_LENGTH);
+ safestrncpy((char*)WBUFP(buf,26), mes, 40);
#if PACKETVER < 20100803
- safestrncpy((char*)WBUFP(buf,66),"",NAME_LENGTH); // account name (not used for security reasons)
+ memset(WBUFP(buf,66), 0, NAME_LENGTH); // account name (not used for security reasons)
#endif
- clif_send(buf,packet_len(cmd),&sd->bl,GUILD_NOBG);
- return 0;
+ clif_send(buf, packet_len(cmd), &sd->bl, GUILD_NOBG);
}
/*==========================================
* ギルド追放メンバリスト
*------------------------------------------*/
-int clif_guild_expulsionlist(struct map_session_data *sd)
+void clif_guild_expulsionlist(struct map_session_data* sd)
{
- int fd;
- int i,c;
- struct guild *g;
+#if PACKETVER < 20100803
+ const int offset = NAME_LENGTH*2+40;
+#else
+ const int offset = NAME_LENGTH+40;
+#endif
+ int fd, i, c = 0;
+ struct guild* g;
+
+ nullpo_retv(sd);
- nullpo_ret(sd);
if( (g = guild_search(sd->status.guild_id)) == NULL )
- return 0;
+ return;
fd = sd->fd;
- WFIFOHEAD(fd,4 + MAX_GUILDEXPULSION * 88);
- WFIFOW(fd,0)=0x163;
- for(i=c=0;i<MAX_GUILDEXPULSION;i++){
- struct guild_expulsion *e=&g->expulsion[i];
- if(e->account_id>0){
- safestrncpy((char*)WFIFOP(fd,4 + c*88),e->name,NAME_LENGTH);
- safestrncpy((char*)WFIFOP(fd,4 + c*88+24),"",24); // account name (not used for security reasons)
- safestrncpy((char*)WFIFOP(fd,4 + c*88+48),e->mes,40);
+
+ WFIFOHEAD(fd,4 + MAX_GUILDEXPULSION * offset);
+ WFIFOW(fd,0) = 0x163;
+
+ for( i = 0; i < MAX_GUILDEXPULSION; i++ )
+ {
+ struct guild_expulsion* e = &g->expulsion[i];
+
+ if( e->account_id > 0 )
+ {
+ memcpy(WFIFOP(fd,4 + c*offset), e->name, NAME_LENGTH);
+#if PACKETVER < 20100803
+ memset(WFIFOP(fd,4 + c*offset+24), 0, NAME_LENGTH); // account name (not used for security reasons)
+ memcpy(WFIFOP(fd,4 + c*offset+48), e->mes, 40);
+#else
+ memcpy(WFIFOP(fd,4 + c*offset+24), e->mes, 40);
+#endif
c++;
}
}
- WFIFOW(fd,2) = 4 + c*88;
+ WFIFOW(fd,2) = 4 + c*offset;
WFIFOSET(fd,WFIFOW(fd,2));
- return 0;
}
/*==========================================
@@ -8024,15 +8063,15 @@ void clif_equipcheckbox(struct map_session_data* sd)
WFIFOSET(fd, packet_len(0x2da));
}
-/*==========================================
- * Sends info about a player's equipped items
- * R 002d7 <length>.W <name>.24B <class>.w <hairstyle>.w <up-viewid>.w <mid-viewid>.w <low-viewid>.w <haircolor>.w <cloth-dye>.w <gender>.1B {equip item}.26B*
- * for PACKETVER >= 20100629
- * R 002d7 <length>.W <name>.24B <class>.w <hairstyle>.w <bottom-viewid>.w <mid-viewid>.w <up-viewid>.w <haircolor>.w <cloth-dye>.w <gender>.1B {equip item}.28B*
- *------------------------------------------*/
+/// Sends info about a player's equipped items (ZC_EQUIPWIN_MICROSCOPE)
+/// 02d7 <packet len>.W <name>.24B <class>.W <hairstyle>.W <up-viewid>.W <mid-viewid>.W <low-viewid>.W <haircolor>.W <cloth-dye>.W <gender>.B {equip item}.26B*
+/// 02d7 <packet len>.W <name>.24B <class>.W <hairstyle>.W <bottom-viewid>.W <mid-viewid>.W <up-viewid>.W <haircolor>.W <cloth-dye>.W <gender>.B {equip item}.28B* (PACKETVER >= 20100629)
+/// 0859 <packet len>.W <name>.24B <class>.W <hairstyle>.W <bottom-viewid>.W <mid-viewid>.W <up-viewid>.W <haircolor>.W <cloth-dye>.W <gender>.B {equip item}.28B* (PACKETVER >= 20101124)
+/// 0859 <packet len>.W <name>.24B <class>.W <hairstyle>.W <bottom-viewid>.W <mid-viewid>.W <up-viewid>.W <robe>.W <haircolor>.W <cloth-dye>.W <gender>.B {equip item}.28B* (PACKETVER >= 20110111)
void clif_viewequip_ack(struct map_session_data* sd, struct map_session_data* tsd)
{
- int i, n, fd;
+ uint8* buf;
+ int i, n, fd, offset = 0;
#if PACKETVER < 20100629
const int s = 26;
#else
@@ -8043,17 +8082,27 @@ void clif_viewequip_ack(struct map_session_data* sd, struct map_session_data* ts
fd = sd->fd;
WFIFOHEAD(fd, MAX_INVENTORY * s + 43);
+ buf = WFIFOP(fd,0);
- WFIFOW(fd, 0) = 0x2d7;
- safestrncpy((char*)WFIFOP(fd, 4), tsd->status.name, NAME_LENGTH);
- WFIFOW(fd,28) = tsd->status.class_;
- WFIFOW(fd,30) = tsd->vd.hair_style;
- WFIFOW(fd,32) = tsd->vd.head_bottom;
- WFIFOW(fd,34) = tsd->vd.head_mid;
- WFIFOW(fd,36) = tsd->vd.head_top;
- WFIFOW(fd,38) = tsd->vd.hair_color;
- WFIFOW(fd,40) = tsd->vd.cloth_color;
- WFIFOB(fd,42) = tsd->vd.sex;
+#if PACKETVER < 20101124
+ WBUFW(buf, 0) = 0x2d7;
+#else
+ WBUFW(buf, 0) = 0x859;
+#endif
+ safestrncpy((char*)WBUFP(buf, 4), tsd->status.name, NAME_LENGTH);
+ WBUFW(buf,28) = tsd->status.class_;
+ WBUFW(buf,30) = tsd->vd.hair_style;
+ WBUFW(buf,32) = tsd->vd.head_bottom;
+ WBUFW(buf,34) = tsd->vd.head_mid;
+ WBUFW(buf,36) = tsd->vd.head_top;
+#if PACKETVER >= 20110111
+ WBUFW(buf,38) = tsd->vd.robe;
+ offset+= 2;
+ buf = WBUFP(buf,2);
+#endif
+ WBUFW(buf,38) = tsd->vd.hair_color;
+ WBUFW(buf,40) = tsd->vd.cloth_color;
+ WBUFB(buf,42) = tsd->vd.sex;
for(i=0,n=0; i < MAX_INVENTORY; i++)
{
@@ -8063,24 +8112,24 @@ void clif_viewequip_ack(struct map_session_data* sd, struct map_session_data* ts
continue;
// Inventory position
- WFIFOW(fd, n*s+43) = i + 2;
+ WBUFW(buf, n*s+43) = i + 2;
// Add refine, identify flag, element, etc.
- clif_item_sub(WFIFOP(fd,0), n*s+45, &tsd->status.inventory[i], tsd->inventory_data[i], pc_equippoint(tsd, i));
+ clif_item_sub(WBUFP(buf,0), n*s+45, &tsd->status.inventory[i], tsd->inventory_data[i], pc_equippoint(tsd, i));
// Add cards
- clif_addcards(WFIFOP(fd, n*s+55), &tsd->status.inventory[i]);
+ clif_addcards(WBUFP(buf, n*s+55), &tsd->status.inventory[i]);
// Expiration date stuff, if all of those are set to 0 then the client doesn't show anything related (6 bytes)
- WFIFOL(fd, n*s+63) = tsd->status.inventory[i].expire_time;
- WFIFOW(fd, n*s+67) = 0;
+ WBUFL(buf, n*s+63) = tsd->status.inventory[i].expire_time;
+ WBUFW(buf, n*s+67) = 0;
#if PACKETVER >= 20100629
- if (tsd->inventory_data[i]->equip&EQP_HELM)
- WFIFOW(fd, n*s+69) = tsd->inventory_data[i]->look;
+ if (tsd->inventory_data[i]->equip&EQP_VISIBLE)
+ WBUFW(buf, n*s+69) = tsd->inventory_data[i]->look;
else
- WFIFOW(fd, n*s+69) = 0;
+ WBUFW(buf, n*s+69) = 0;
#endif
n++;
}
- WFIFOW(fd, 2) = 43 + n*s; // Set length
+ WFIFOW(fd, 2) = 43+offset+n*s; // Set length
WFIFOSET(fd, WFIFOW(fd, 2));
}
@@ -8443,13 +8492,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
clif_party_hp(sd); // Show hp after displacement [LuzZza]
}
- if( sd->state.bg_id ) clif_bg_hp(sd); // BattleGround System
- if( sd->state.changemap && map[sd->bl.m].flag.battleground )
- {
- clif_map_type(sd, MAPTYPE_BATTLEFIELD); // Battleground Mode
- if( map[sd->bl.m].flag.battleground == 2 )
- clif_bg_updatescore_single(sd);
- }
+ if( sd->bg_id ) clif_bg_hp(sd); // BattleGround System
if(map[sd->bl.m].flag.pvp) {
if(!battle_config.pk_mode) { // remove pvp stuff for pk_mode [Valaris]
@@ -8606,6 +8649,13 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
clif_status_load(&sd->bl, SI_NIGHT, 0);
}
+ if( map[sd->bl.m].flag.battleground )
+ {
+ clif_map_type(sd, MAPTYPE_BATTLEFIELD); // Battleground Mode
+ if( map[sd->bl.m].flag.battleground == 2 )
+ clif_bg_updatescore_single(sd);
+ }
+
if( map[sd->bl.m].flag.allowks && !map_flag_ks(sd->bl.m) )
{
char output[128];
@@ -9642,7 +9692,8 @@ void clif_parse_ChatLeave(int fd, struct map_session_data* sd)
//0:
static void clif_noask_sub(struct map_session_data *src, struct map_session_data *target, int type)
{
- char *msg, output[256];
+ const char* msg;
+ char output[256];
// Your request has been rejected by autoreject option.
msg = msg_txt(392);
clif_disp_onlyself(src, msg, strlen(msg));
@@ -10928,7 +10979,7 @@ void clif_parse_GuildCheckMaster(int fd, struct map_session_data *sd)
*------------------------------------------*/
void clif_parse_GuildRequestInfo(int fd, struct map_session_data *sd)
{
- if( !sd->status.guild_id && !sd->state.bg_id )
+ if( !sd->status.guild_id && !sd->bg_id )
return;
switch( RFIFOL(fd,2) )
@@ -11076,7 +11127,7 @@ void clif_parse_GuildLeave(int fd,struct map_session_data *sd)
clif_displaymessage(fd, msg_txt(228));
return;
}
- if( sd->state.bg_id )
+ if( sd->bg_id )
{
clif_displaymessage(fd, "You can't leave battleground guilds.");
return;
@@ -11091,7 +11142,7 @@ void clif_parse_GuildLeave(int fd,struct map_session_data *sd)
*------------------------------------------*/
void clif_parse_GuildExpulsion(int fd,struct map_session_data *sd)
{
- if( map[sd->bl.m].flag.guildlock || sd->state.bg_id )
+ if( map[sd->bl.m].flag.guildlock || sd->bg_id )
{ // Guild locked.
clif_displaymessage(fd, msg_txt(228));
return;
@@ -11128,7 +11179,7 @@ void clif_parse_GuildMessage(int fd, struct map_session_data* sd)
sd->cantalk_tick = gettick() + battle_config.min_chat_delay;
}
- if( sd->state.bg_id )
+ if( sd->bg_id )
bg_send_message(sd, text, textlen);
else
guild_send_message(sd, text, textlen);
@@ -13859,7 +13910,7 @@ int clif_sendbgemblem_area(struct map_session_data *sd)
WBUFW(buf, 0) = 0x2dd;
WBUFL(buf,2) = sd->bl.id;
safestrncpy((char*)WBUFP(buf,6), sd->status.name, NAME_LENGTH); // name don't show in screen.
- WBUFW(buf,30) = sd->state.bg_id;
+ WBUFW(buf,30) = sd->bg_id;
clif_send(buf,packet_len(0x2dd), &sd->bl, AREA);
return 0;
}
@@ -13871,7 +13922,7 @@ int clif_sendbgemblem_single(int fd, struct map_session_data *sd)
WFIFOW(fd,0) = 0x2dd;
WFIFOL(fd,2) = sd->bl.id;
safestrncpy((char*)WFIFOP(fd,6), sd->status.name, NAME_LENGTH);
- WFIFOW(fd,30) = sd->state.bg_id;
+ WFIFOW(fd,30) = sd->bg_id;
WFIFOSET(fd,packet_len(0x2dd));
return 0;
}
@@ -13886,7 +13937,7 @@ int clif_font(struct map_session_data *sd)
nullpo_ret(sd);
WBUFW(buf,0) = 0x2ef;
WBUFL(buf,2) = sd->bl.id;
- WBUFW(buf,6) = sd->state.user_font;
+ WBUFW(buf,6) = sd->user_font;
clif_send(buf, packet_len(0x2ef), &sd->bl, AREA);
return 1;
}
@@ -14977,6 +15028,11 @@ static int packetdb_readdb(void)
3, -1, 8, -1, 86, 2, 6, 6, -1, -1, 4, 10, 10, 0, 0, 0,
0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, -1, -1, 3, 2, 66, 5, 2, 12, 6, 0, 0,
+ //#0x0840
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
struct {
void (*func)(int, struct map_session_data *);
diff --git a/src/map/clif.h b/src/map/clif.h
index 2d90eb522..70a7fdce8 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -29,7 +29,7 @@ struct party_booking_ad_info;
#include <stdarg.h>
// packet DB
#define MAX_PACKET_DB 0x900
-#define MAX_PACKET_VER 25
+#define MAX_PACKET_VER 26
struct s_packet_db {
short len;
@@ -430,7 +430,7 @@ int clif_guild_memberlogin_notice(struct guild *g,int idx,int flag);
int clif_guild_invite(struct map_session_data *sd,struct guild *g);
int clif_guild_inviteack(struct map_session_data *sd,int flag);
int clif_guild_leave(struct map_session_data *sd,const char *name,const char *mes);
-int clif_guild_expulsion(struct map_session_data *sd,const char *name,const char *mes,int account_id);
+void clif_guild_expulsion(struct map_session_data* sd, const char* name, const char* mes, int account_id);
int clif_guild_positionchanged(struct guild *g,int idx);
int clif_guild_memberpositionchanged(struct guild *g,int idx);
int clif_guild_emblem(struct map_session_data *sd,struct guild *g);
diff --git a/src/map/duel.c b/src/map/duel.c
new file mode 100644
index 000000000..7621b92be
--- /dev/null
+++ b/src/map/duel.c
@@ -0,0 +1,189 @@
+// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
+// For more information, see LICENCE in the main folder
+
+#include "../common/cbasetypes.h"
+
+#include "atcommand.h" // msg_txt
+#include "clif.h"
+#include "duel.h"
+#include "pc.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+struct duel duel_list[MAX_DUEL];
+int duel_count = 0;
+
+/*==========================================
+ * Duel organizing functions [LuzZza]
+ *------------------------------------------*/
+void duel_savetime(struct map_session_data* sd)
+{
+ time_t timer;
+ struct tm *t;
+
+ time(&timer);
+ t = localtime(&timer);
+
+ pc_setglobalreg(sd, "PC_LAST_DUEL_TIME", t->tm_mday*24*60 + t->tm_hour*60 + t->tm_min);
+ return;
+}
+
+int duel_checktime(struct map_session_data* sd)
+{
+ int diff;
+ time_t timer;
+ struct tm *t;
+
+ time(&timer);
+ t = localtime(&timer);
+
+ diff = t->tm_mday*24*60 + t->tm_hour*60 + t->tm_min - pc_readglobalreg(sd, "PC_LAST_DUEL_TIME");
+
+ return !(diff >= 0 && diff < battle_config.duel_time_interval);
+}
+static int duel_showinfo_sub(struct map_session_data* sd, va_list va)
+{
+ struct map_session_data *ssd = va_arg(va, struct map_session_data*);
+ int *p = va_arg(va, int*);
+ char output[256];
+
+ if (sd->duel_group != ssd->duel_group) return 0;
+
+ sprintf(output, " %d. %s", ++(*p), sd->status.name);
+ clif_disp_onlyself(ssd, output, strlen(output));
+ return 1;
+}
+
+int duel_showinfo(const unsigned int did, struct map_session_data* sd)
+{
+ int p=0;
+ char output[256];
+
+ if(duel_list[did].max_players_limit > 0)
+ sprintf(output, msg_txt(370), //" -- Duels: %d/%d, Members: %d/%d, Max players: %d --"
+ did, duel_count,
+ duel_list[did].members_count,
+ duel_list[did].members_count + duel_list[did].invites_count,
+ duel_list[did].max_players_limit);
+ else
+ sprintf(output, msg_txt(371), //" -- Duels: %d/%d, Members: %d/%d --"
+ did, duel_count,
+ duel_list[did].members_count,
+ duel_list[did].members_count + duel_list[did].invites_count);
+
+ clif_disp_onlyself(sd, output, strlen(output));
+ map_foreachpc(duel_showinfo_sub, sd, &p);
+ return 0;
+}
+
+int duel_create(struct map_session_data* sd, const unsigned int maxpl)
+{
+ int i=1;
+ char output[256];
+
+ while(duel_list[i].members_count > 0 && i < MAX_DUEL) i++;
+ if(i == MAX_DUEL) return 0;
+
+ duel_count++;
+ sd->duel_group = i;
+ duel_list[i].members_count++;
+ duel_list[i].invites_count = 0;
+ duel_list[i].max_players_limit = maxpl;
+
+ strcpy(output, msg_txt(372)); // " -- Duel has been created (@invite/@leave) --"
+ clif_disp_onlyself(sd, output, strlen(output));
+
+ clif_map_property(sd, MAPPROPERTY_FREEPVPZONE);
+ //clif_misceffect2(&sd->bl, 159);
+ return i;
+}
+
+int duel_invite(const unsigned int did, struct map_session_data* sd, struct map_session_data* target_sd)
+{
+ char output[256];
+
+ // " -- Player %s invites %s to duel --"
+ sprintf(output, msg_txt(373), sd->status.name, target_sd->status.name);
+ clif_disp_message(&sd->bl, output, strlen(output), DUEL_WOS);
+
+ target_sd->duel_invite = did;
+ duel_list[did].invites_count++;
+
+ // "Blue -- Player %s invites you to PVP duel (@accept/@reject) --"
+ sprintf(output, msg_txt(374), sd->status.name);
+ clif_broadcast((struct block_list *)target_sd, output, strlen(output)+1, 0x10, SELF);
+ return 0;
+}
+
+static int duel_leave_sub(struct map_session_data* sd, va_list va)
+{
+ int did = va_arg(va, int);
+ if (sd->duel_invite == did)
+ sd->duel_invite = 0;
+ return 0;
+}
+
+int duel_leave(const unsigned int did, struct map_session_data* sd)
+{
+ char output[256];
+
+ // " <- Player %s has left duel --"
+ sprintf(output, msg_txt(375), sd->status.name);
+ clif_disp_message(&sd->bl, output, strlen(output), DUEL_WOS);
+
+ duel_list[did].members_count--;
+
+ if(duel_list[did].members_count == 0) {
+ map_foreachpc(duel_leave_sub, did);
+ duel_count--;
+ }
+
+ sd->duel_group = 0;
+ duel_savetime(sd);
+ clif_map_property(sd, MAPPROPERTY_NOTHING);
+ return 0;
+}
+
+int duel_accept(const unsigned int did, struct map_session_data* sd)
+{
+ char output[256];
+
+ duel_list[did].members_count++;
+ sd->duel_group = sd->duel_invite;
+ duel_list[did].invites_count--;
+ sd->duel_invite = 0;
+
+ // " -> Player %s has accepted duel --"
+ sprintf(output, msg_txt(376), sd->status.name);
+ clif_disp_message(&sd->bl, output, strlen(output), DUEL_WOS);
+
+ clif_map_property(sd, MAPPROPERTY_FREEPVPZONE);
+ //clif_misceffect2(&sd->bl, 159);
+ return 0;
+}
+
+int duel_reject(const unsigned int did, struct map_session_data* sd)
+{
+ char output[256];
+
+ // " -- Player %s has rejected duel --"
+ sprintf(output, msg_txt(377), sd->status.name);
+ clif_disp_message(&sd->bl, output, strlen(output), DUEL_WOS);
+
+ duel_list[did].invites_count--;
+ sd->duel_invite = 0;
+ return 0;
+}
+
+void do_final_duel(void)
+{
+}
+
+int do_init_duel(void)
+{
+ memset(&duel_list[0], 0, sizeof(duel_list));
+ return 0;
+}
diff --git a/src/map/duel.h b/src/map/duel.h
new file mode 100644
index 000000000..674d0e12f
--- /dev/null
+++ b/src/map/duel.h
@@ -0,0 +1,29 @@
+// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
+// For more information, see LICENCE in the main folder
+
+#ifndef _DUEL_H_
+#define _DUEL_H_
+
+struct duel {
+ int members_count;
+ int invites_count;
+ int max_players_limit;
+};
+
+#define MAX_DUEL 1024
+extern struct duel duel_list[MAX_DUEL];
+extern int duel_count;
+
+//Duel functions // [LuzZza]
+int duel_create(struct map_session_data* sd, const unsigned int maxpl);
+int duel_invite(const unsigned int did, struct map_session_data* sd, struct map_session_data* target_sd);
+int duel_accept(const unsigned int did, struct map_session_data* sd);
+int duel_reject(const unsigned int did, struct map_session_data* sd);
+int duel_leave(const unsigned int did, struct map_session_data* sd);
+int duel_showinfo(const unsigned int did, struct map_session_data* sd);
+int duel_checktime(struct map_session_data* sd);
+
+int do_init_duel(void);
+void do_final_duel(void);
+
+#endif /* _DUEL_H_ */
diff --git a/src/map/guild.c b/src/map/guild.c
index e56b346ec..c80b124ef 100644
--- a/src/map/guild.c
+++ b/src/map/guild.c
@@ -36,7 +36,7 @@ static DBMap* guild_infoevent_db; // int guild_id -> struct eventlist*
static DBMap* guild_castleinfoevent_db; // int castle_id_index -> struct eventlist*
struct eventlist {
- char name[50];
+ char name[EVENT_NAME_LENGTH];
struct eventlist *next;
};
@@ -325,7 +325,7 @@ int guild_send_xy_timer_sub(DBKey key,void *data,va_list ap)
for(i=0;i<g->max_member;i++){
//struct map_session_data* sd = g->member[i].sd;
struct map_session_data* sd = map_charid2sd(g->member[i].char_id); // temporary crashfix
- if( sd != NULL && (sd->guild_x != sd->bl.x || sd->guild_y != sd->bl.y) && !sd->state.bg_id )
+ if( sd != NULL && (sd->guild_x != sd->bl.x || sd->guild_y != sd->bl.y) && !sd->bg_id )
{
clif_guild_xy(sd);
sd->guild_x = sd->bl.x;
@@ -1545,7 +1545,7 @@ int guild_broken(int guild_id,int flag)
struct guild_castle *gc=NULL;
struct map_session_data *sd;
int i;
- char name[50];
+ char name[EVENT_NAME_LENGTH];
if(flag!=0 || g==NULL)
return 0;
@@ -1604,7 +1604,7 @@ int guild_gm_changed(int guild_id, int account_id, int char_id)
{
struct guild *g;
struct guild_member gm;
- int pos;
+ int pos, i;
g=guild_search(guild_id);
@@ -1638,7 +1638,18 @@ int guild_gm_changed(int guild_id, int account_id, int char_id)
g->member[0].sd->state.gmaster_flag = g;
//Block his skills for 5 minutes to prevent abuse.
guild_block_skill(g->member[0].sd, 300000);
- }
+ }
+
+ // announce the change to all guild members
+ for( i = 0; i < g->max_member; i++ )
+ {
+ if( g->member[i].sd && g->member[i].sd->fd )
+ {
+ clif_guild_basicinfo(g->member[i].sd);
+ clif_guild_memberlist(g->member[i].sd);
+ }
+ }
+
return 1;
}
diff --git a/src/map/instance.c b/src/map/instance.c
index 6fa3a2c0a..e9ff2b409 100644
--- a/src/map/instance.c
+++ b/src/map/instance.c
@@ -31,22 +31,21 @@ struct s_instance instance[MAX_INSTANCE];
/*--------------------------------------
* name : instance name
* Return value could be
- * -4 = already exists | -3 = no free instances | -2 = missing parameter | -1 = invalid type
+ * -4 = already exists | -3 = no free instances | -2 = party not found | -1 = invalid type
* On success return instance_id
*--------------------------------------*/
int instance_create(int party_id, const char *name)
{
int i;
- struct party_data *p = NULL;
+ struct party_data* p;
- if( !party_id || !name )
+ if( ( p = party_search(party_id) ) == NULL )
{
- ShowError("map_instance_create: missing parameter.\n");
+ ShowError("instance_create: party %d not found for instance '%s'.\n", party_id, name);
return -2;
}
- p = party_search(party_id);
- if( !p || p->instance_id )
+ if( p->instance_id )
return -4; // Party already instancing
// Searching a Free Instance
@@ -54,7 +53,7 @@ int instance_create(int party_id, const char *name)
ARR_FIND(1, MAX_INSTANCE, i, instance[i].state == INSTANCE_FREE);
if( i == MAX_INSTANCE )
{
- ShowError("map_instance_create: no free instances, consider increasing MAX_INSTANCE.\n");
+ ShowError("instance_create: no free instances, consider increasing MAX_INSTANCE.\n");
return -3;
}
diff --git a/src/map/intif.c b/src/map/intif.c
index 875baa036..1b69c0837 100644
--- a/src/map/intif.c
+++ b/src/map/intif.c
@@ -1465,7 +1465,7 @@ int intif_parse_Mail_inboxreceived(int fd)
if (flag)
clif_Mail_refreshinbox(sd);
- else
+ else if( battle_config.mail_show_status && ( battle_config.mail_show_status == 1 || sd->mail.inbox.unread ) )
{
char output[128];
sprintf(output, msg_txt(510), sd->mail.inbox.unchecked, sd->mail.inbox.unread + sd->mail.inbox.unchecked);
diff --git a/src/map/map.c b/src/map/map.c
index 9f9c93608..c086b73c0 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -17,6 +17,7 @@
#include "path.h"
#include "chrif.h"
#include "clif.h"
+#include "duel.h"
#include "intif.h"
#include "npc.h"
#include "pc.h"
@@ -1508,7 +1509,7 @@ void map_addiddb(struct block_list *bl)
TBL_MOB* md = (TBL_MOB*)bl;
idb_put(mobid_db,bl->id,bl);
- if( md->boss )
+ if( md->state.boss )
idb_put(bossid_db, bl->id, bl);
}
@@ -1658,8 +1659,30 @@ struct mob_data * map_id2md(int id)
struct npc_data * map_id2nd(int id)
{// just a id2bl lookup because there's no npc_db
- if (id <= 0) return NULL;
- return (struct npc_data*)map_id2bl(id);
+ struct block_list* bl = map_id2bl(id);
+
+ return BL_CAST(BL_NPC, bl);
+}
+
+struct homun_data* map_id2hd(int id)
+{
+ struct block_list* bl = map_id2bl(id);
+
+ return BL_CAST(BL_HOM, bl);
+}
+
+struct mercenary_data* map_id2mc(int id)
+{
+ struct block_list* bl = map_id2bl(id);
+
+ return BL_CAST(BL_MER, bl);
+}
+
+struct chat_data* map_id2cd(int id)
+{
+ struct block_list* bl = map_id2bl(id);
+
+ return BL_CAST(BL_CHAT, bl);
}
/// Returns the nick of the target charid or NULL if unknown (requests the nick to the char server).
@@ -2704,7 +2727,7 @@ int map_readfromcache(struct map_data *m, char *buffer, char *decode_buffer)
}
// TO-DO: Maybe handle the scenario, if the decoded buffer isn't the same size as expected? [Shinryo]
- decode_zip(decode_buffer, &size, p+sizeof(struct map_cache_map_info), info->len);
+ uncompress(decode_buffer, &size, p+sizeof(struct map_cache_map_info), info->len);
CREATE(m->cell, struct mapcell, size);
@@ -3438,6 +3461,7 @@ void do_final(void)
do_final_status();
do_final_unit();
do_final_battleground();
+ do_final_duel();
map_db->destroy(map_db, map_db_final);
@@ -3673,6 +3697,7 @@ int do_init(int argc, char *argv[])
do_init_npc();
do_init_unit();
do_init_battleground();
+ do_init_duel();
npc_event_do_oninit(); // npcのOnInitイベント?行
diff --git a/src/map/map.h b/src/map/map.h
index 8c817387f..d572cec4c 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -203,6 +203,8 @@ enum {
#define CHATROOM_PASS_SIZE (8 + 1)
//Max allowed chat text length
#define CHAT_SIZE_MAX (255 + 1)
+//24 for npc name + 24 for label + 2 for a "::" and 1 for EOS
+#define EVENT_NAME_LENGTH ( NAME_LENGTH * 2 + 3 )
#define DEFAULT_AUTOSAVE_INTERVAL 5*60*1000
@@ -301,18 +303,18 @@ struct block_list {
// Expanded to specify all mob-related spawn data by [Skotlex]
struct spawn_data {
short class_; //Class, used because a mob can change it's class
- unsigned boss : 1;
unsigned short m,x,y; //Spawn information (map, point, spawn-area around point)
signed short xs,ys;
unsigned short num; //Number of mobs using this structure
unsigned short active; //Number of mobs that are already spawned (for mob_remove_damaged: no)
unsigned int delay1,delay2; //Min delay before respawning after spawn/death
struct {
- unsigned size :2; //Holds if mob has to be tiny/large
- unsigned ai :2; //Holds if mob is special ai.
- unsigned dynamic :1; //Whether this data is indexed by a map's dynamic mob list
+ unsigned int size :2; //Holds if mob has to be tiny/large
+ unsigned int ai :2; //Holds if mob is special ai.
+ unsigned int dynamic :1; //Whether this data is indexed by a map's dynamic mob list
+ unsigned int boss : 1;
} state;
- char name[NAME_LENGTH],eventname[50]; //Name/event
+ char name[NAME_LENGTH],eventname[EVENT_NAME_LENGTH]; //Name/event
};
@@ -398,7 +400,10 @@ enum _look {
LOOK_HAIR_COLOR,
LOOK_CLOTHES_COLOR,
LOOK_SHIELD,
- LOOK_SHOES
+ LOOK_SHOES,
+ LOOK_BODY,
+ LOOK_FLOOR,
+ LOOK_ROBE,
};
// used by map_setcell()
@@ -625,6 +630,9 @@ struct map_session_data* map_charid2sd(int charid);
struct map_session_data * map_id2sd(int id);
struct mob_data * map_id2md(int id);
struct npc_data * map_id2nd(int id);
+struct homun_data* map_id2hd(int id);
+struct mercenary_data* map_id2mc(int id);
+struct chat_data* map_id2cd(int id);
struct block_list * map_id2bl(int id);
#define map_id2index(id) map[(id)].index
diff --git a/src/map/mob.c b/src/map/mob.c
index 1626f49a0..4c8fa685a 100644
--- a/src/map/mob.c
+++ b/src/map/mob.c
@@ -160,7 +160,8 @@ struct view_data * mob_get_viewdata(int class_)
*------------------------------------------*/
int mob_parse_dataset(struct spawn_data *data)
{
- int i;
+ size_t len;
+
//FIXME: This implementation is not stable, npc scripts will stop working once MAX_MOB_DB changes value! [Skotlex]
if(data->class_ > 2*MAX_MOB_DB){ // large/tiny mobs [Valaris]
data->state.size=2;
@@ -173,36 +174,33 @@ int mob_parse_dataset(struct spawn_data *data)
if ((!mobdb_checkid(data->class_) && !mob_is_clone(data->class_)) || !data->num)
return 0;
- //better safe than sorry, current md->npc_event has a size of 50
- if ((i=strlen(data->eventname)) >= 50)
- return 0;
+ if( npc_event_isspecial(data->eventname) )
+ {//Portable monster big/small implementation. [Skotlex]
+ int i = atoi(data->eventname);
- if (data->eventname[0])
- {
- if(i <= 2)
- { //Portable monster big/small implementation. [Skotlex]
- i = atoi(data->eventname);
- if (i) {
- if (i&2)
- data->state.size=1;
- else if (i&4)
- data->state.size=2;
- if (i&8)
- data->state.ai=1;
- data->eventname[0] = '\0'; //Clear event as it is not used.
- }
- } else {
- if (data->eventname[i-1] == '"')
- data->eventname[i-1] = '\0'; //Remove trailing quote.
- if (data->eventname[0] == '"') //Strip leading quotes
- memmove(data->eventname, data->eventname+1, i-1);
+ if( i )
+ {
+ if( i&2 )
+ data->state.size = 1;
+ else if( i&4 )
+ data->state.size = 2;
+ if( i&8 )
+ data->state.ai = 1;
}
+ data->eventname[0] = '\0'; //Clear event as it is not used.
+ }
+ else if( ( len = strlen(data->eventname) ) > 0 )
+ {
+ if( data->eventname[len-1] == '"' )
+ data->eventname[len-1] = '\0'; //Remove trailing quote.
+ if( data->eventname[0] == '"' ) //Strip leading quotes
+ memmove(data->eventname, data->eventname+1, len-1);
}
if(strcmp(data->name,"--en--")==0)
- strncpy(data->name,mob_db(data->class_)->name,NAME_LENGTH-1);
+ safestrncpy(data->name, mob_db(data->class_)->name, sizeof(data->name));
else if(strcmp(data->name,"--ja--")==0)
- strncpy(data->name,mob_db(data->class_)->jname,NAME_LENGTH-1);
+ safestrncpy(data->name, mob_db(data->class_)->jname, sizeof(data->name));
return 1;
}
@@ -218,7 +216,7 @@ struct mob_data* mob_spawn_dataset(struct spawn_data *data)
md->bl.x = data->x;
md->bl.y = data->y;
md->class_ = data->class_;
- md->boss = data->boss;
+ md->state.boss = data->state.boss;
md->db = mob_db(md->class_);
memcpy(md->name, data->name, NAME_LENGTH);
if (data->state.ai)
@@ -667,7 +665,7 @@ int mob_spawn_guardian(const char* mapname, short x, short y, const char* mobnam
/*==========================================
* Summoning BattleGround [Zephyrus]
*------------------------------------------*/
-int mob_spawn_bg(const char* mapname, short x, short y, const char* mobname, int class_, const char* event, int bg_id)
+int mob_spawn_bg(const char* mapname, short x, short y, const char* mobname, int class_, const char* event, unsigned int bg_id)
{
struct mob_data *md = NULL;
struct spawn_data data;
@@ -704,7 +702,7 @@ int mob_spawn_bg(const char* mapname, short x, short y, const char* mobname, int
md = mob_spawn_dataset(&data);
mob_spawn(md);
- md->state.bg_id = bg_id; // BG Team ID
+ md->bg_id = bg_id; // BG Team ID
return md->bl.id;
}
diff --git a/src/map/mob.h b/src/map/mob.h
index ce896646c..605439f12 100644
--- a/src/map/mob.h
+++ b/src/map/mob.h
@@ -113,42 +113,42 @@ struct mob_data {
struct mob_db *db; //For quick data access (saves doing mob_db(md->class_) all the time) [Skotlex]
char name[NAME_LENGTH];
struct {
- unsigned size : 2; //Small/Big monsters.
- unsigned ai : 2; //Special ai for summoned monsters.
+ unsigned int size : 2; //Small/Big monsters.
+ unsigned int ai : 2; //Special ai for summoned monsters.
//0: Normal mob.
//1: Standard summon, attacks mobs.
//2: Alchemist Marine Sphere
//3: Alchemist Summon Flora
} special_state; //Special mob information that does not needs to be zero'ed on mob respawn.
struct {
+ unsigned int aggressive : 1; //Signals whether the mob AI is in aggressive mode or reactive mode. [Skotlex]
+ unsigned int steal_coin_flag : 1;
+ unsigned int soul_change_flag : 1; // Celest
+ unsigned int alchemist: 1;
+ unsigned int spotted: 1;
+ unsigned int npc_killmonster: 1; //for new killmonster behavior
+ unsigned int rebirth: 1; // NPC_Rebirth used
+ unsigned int boss : 1;
enum MobSkillState skillstate;
- unsigned aggressive : 1; //Signals whether the mob AI is in aggressive mode or reactive mode. [Skotlex]
unsigned char steal_flag; //number of steal tries (to prevent steal exploit on mobs with few items) [Lupus]
- unsigned steal_coin_flag : 1;
- unsigned soul_change_flag : 1; // Celest
- unsigned alchemist: 1;
- unsigned spotted: 1;
unsigned char attacked_count; //For rude attacked.
int provoke_flag; // Celest
- unsigned npc_killmonster: 1; //for new killmonster behavior
- unsigned rebirth: 1; // NPC_Rebirth used
- unsigned int bg_id; // BattleGround System
} state;
struct guardian_data* guardian_data;
struct {
int id;
unsigned int dmg;
- unsigned flag : 2; //0: Normal. 1: Homunc exp. 2: Pet exp
+ unsigned int flag : 2; //0: Normal. 1: Homunc exp. 2: Pet exp
} dmglog[DAMAGELOG_SIZE];
struct spawn_data *spawn; //Spawn data.
int spawn_timer; //Required for Convex Mirror
struct item *lootitem;
short class_;
- unsigned boss : 1;
unsigned int tdmg; //Stores total damage given to the mob, for exp calculations. [Skotlex]
int level;
int target_id,attacked_id;
int areanpc_id; //Required in OnTouchNPC (to avoid multiple area touchs)
+ unsigned int bg_id; // BattleGround System
unsigned int next_walktime,last_thinktime,last_linktime,last_pcneartime;
short move_fail_count;
@@ -160,7 +160,7 @@ struct mob_data {
short skillidx;
unsigned int skilldelay[MAX_MOBSKILL];
- char npc_event[50];
+ char npc_event[EVENT_NAME_LENGTH];
};
@@ -230,7 +230,7 @@ int mob_once_spawn_area(struct map_session_data* sd,int m,int x0,int y0,int x1,i
bool mob_ksprotected (struct block_list *src, struct block_list *target);
int mob_spawn_guardian(const char* mapname, short x, short y, const char* mobname, int class_, const char* event, int guardian, bool has_index); // Spawning Guardians [Valaris]
-int mob_spawn_bg(const char* mapname, short x, short y, const char* mobname, int class_, const char* event, int bg_id);
+int mob_spawn_bg(const char* mapname, short x, short y, const char* mobname, int class_, const char* event, unsigned int bg_id);
int mob_guardian_guildchange(struct block_list *bl,va_list ap); //Change Guardian's ownership. [Skotlex]
int mob_randomwalk(struct mob_data *md,unsigned int tick);
diff --git a/src/map/npc.c b/src/map/npc.c
index 95331ae5b..d070b6886 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -105,7 +105,7 @@ struct view_data* npc_get_viewdata(int class_)
int npc_ontouch_event(struct map_session_data *sd, struct npc_data *nd)
{
- char name[NAME_LENGTH*2+3];
+ char name[EVENT_NAME_LENGTH];
if( nd->touching_id )
return 0; // Attached a player already. Can't trigger on anyone else.
@@ -119,7 +119,7 @@ int npc_ontouch_event(struct map_session_data *sd, struct npc_data *nd)
int npc_ontouch2_event(struct map_session_data *sd, struct npc_data *nd)
{
- char name[NAME_LENGTH*2+3];
+ char name[EVENT_NAME_LENGTH];
if( sd->areanpc_id == nd->bl.id )
return 0;
@@ -245,7 +245,7 @@ int npc_event_export(char* lname, void* data, va_list ap)
if ((lname[0]=='O' || lname[0]=='o')&&(lname[1]=='N' || lname[1]=='n')) {
struct event_data *ev;
- char buf[NAME_LENGTH*2+3];
+ char buf[EVENT_NAME_LENGTH];
char* p = strchr(lname, ':');
// エクスポートされる
ev = (struct event_data *) aMalloc(sizeof(struct event_data));
@@ -345,6 +345,14 @@ int npc_event_doall_id(const char* name, int rid)
}
+/// Checks whether or not the event name is used as transport for
+/// special flags.
+bool npc_event_isspecial(const char* eventname)
+{
+ return (bool)( eventname && ISDIGIT(eventname[0]) && !strstr(eventname, "::") );
+}
+
+
/*==========================================
* 時計イベント実行
*------------------------------------------*/
@@ -636,7 +644,7 @@ void npc_timerevent_quit(struct map_session_data* sd)
// Execute OnTimerQuit
if( nd && nd->bl.type == BL_NPC )
{
- char buf[NAME_LENGTH*2+3];
+ char buf[EVENT_NAME_LENGTH];
struct event_data *ev;
snprintf(buf, ARRAYLENGTH(buf), "%s::OnTimerQuit", nd->exname);
@@ -813,7 +821,7 @@ int npc_touchnext_areanpc(struct map_session_data* sd, bool leavemap)
sd->bl.y < nd->bl.y - ys || sd->bl.y > nd->bl.y + ys ||
pc_ishiding(sd) || leavemap )
{
- char name[NAME_LENGTH*2+3];
+ char name[EVENT_NAME_LENGTH];
nd->touching_id = sd->touching_id = 0;
snprintf(name, ARRAYLENGTH(name), "%s::%s", nd->exname, script_config.ontouch_name);
@@ -894,7 +902,7 @@ int npc_touch_areanpc(struct map_session_data* sd, int m, int x, int y)
int npc_touch_areanpc2(struct mob_data *md)
{
int i, m = md->bl.m, x = md->bl.x, y = md->bl.y, id;
- char eventname[NAME_LENGTH*2+3];
+ char eventname[EVENT_NAME_LENGTH];
struct event_data* ev;
int xs, ys;
@@ -1144,7 +1152,7 @@ int npc_buysellsel(struct map_session_data* sd, int id, int type)
//npc_buylist for script-controlled shops.
static int npc_buylist_sub(struct map_session_data* sd, int n, unsigned short* item_list, struct npc_data* nd)
{
- char npc_ev[NAME_LENGTH*2+3];
+ char npc_ev[EVENT_NAME_LENGTH];
int i;
int key_nameid = 0;
int key_amount = 0;
@@ -1379,7 +1387,7 @@ int npc_buylist(struct map_session_data* sd, int n, unsigned short* item_list)
/// npc_selllist for script-controlled shops
static int npc_selllist_sub(struct map_session_data* sd, int n, unsigned short* item_list, struct npc_data* nd)
{
- char npc_ev[NAME_LENGTH*2+3];
+ char npc_ev[EVENT_NAME_LENGTH];
int i, idx;
int key_nameid = 0;
int key_amount = 0;
@@ -2211,7 +2219,7 @@ static const char* npc_parse_script(char* w1, char* w2, char* w3, char* w4, cons
if ((lname[0] == 'O' || lname[0] == 'o') && (lname[1] == 'N' || lname[1] == 'n'))
{
struct event_data* ev;
- char buf[NAME_LENGTH*2+3]; // 24 for npc name + 24 for label + 2 for a "::" and 1 for EOS
+ char buf[EVENT_NAME_LENGTH];
snprintf(buf, ARRAYLENGTH(buf), "%s::%s", nd->exname, lname);
// generate the data and insert it
@@ -2399,7 +2407,7 @@ const char* npc_parse_duplicate(char* w1, char* w2, char* w3, char* w4, const ch
if ((lname[0] == 'O' || lname[0] == 'o') && (lname[1] == 'N' || lname[1] == 'n'))
{
struct event_data* ev;
- char buf[NAME_LENGTH*2+3]; // 24 for npc name + 24 for label + 2 for a "::" and 1 for EOS
+ char buf[EVENT_NAME_LENGTH];
snprintf(buf, ARRAYLENGTH(buf), "%s::%s", nd->exname, lname);
// generate the data and insert it
@@ -2697,7 +2705,7 @@ static const char* npc_parse_mob(char* w1, char* w2, char* w3, char* w4, const c
memset(&mob, 0, sizeof(struct spawn_data));
- mob.boss = !strcmpi(w2,"boss_monster");
+ mob.state.boss = !strcmpi(w2,"boss_monster");
// w1=<map name>,<x>,<y>,<xs>,<ys>
// w4=<mob id>,<amount>,<delay1>,<delay2>,<event>
diff --git a/src/map/npc.h b/src/map/npc.h
index 6f705a09c..6e7c7cbeb 100644
--- a/src/map/npc.h
+++ b/src/map/npc.h
@@ -134,6 +134,7 @@ int npc_do_ontimer(int npc_id, int option);
int npc_event_do(const char* name);
int npc_event_doall(const char* name);
int npc_event_doall_id(const char* name, int rid);
+bool npc_event_isspecial(const char* eventname);
int npc_timerevent_start(struct npc_data* nd, int rid);
int npc_timerevent_stop(struct npc_data* nd);
diff --git a/src/map/pc.c b/src/map/pc.c
index 7ee8bec90..f55a77b6a 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -18,6 +18,7 @@
#include "chrif.h"
#include "clif.h"
#include "date.h" // is_day_of_*()
+#include "duel.h"
#include "intif.h"
#include "itemdb.h"
#include "log.h"
@@ -63,9 +64,6 @@ static unsigned short equip_pos[EQI_MAX]={EQP_ACC_L,EQP_ACC_R,EQP_SHOES,EQP_GARM
#define MOTD_LINE_SIZE 128
static char motd_text[MOTD_LINE_SIZE][CHAT_SIZE_MAX]; // Message of the day buffer [Valaris]
-struct duel duel_list[MAX_DUEL];
-int duel_count = 0;
-
//Links related info to the sd->hate_mob[]/sd->feel_map[] entries
const struct sg_data sg_info[MAX_PC_FEELHATE] = {
{ SG_SUN_ANGER, SG_SUN_BLESS, SG_SUN_COMFORT, "PC_FEEL_SUN", "PC_HATE_MOB_SUN", is_day_of_sun },
@@ -3271,13 +3269,37 @@ int pc_payzeny(struct map_session_data *sd,int zeny)
void pc_paycash(struct map_session_data *sd, int price, int points)
{
char output[128];
- int cash = price - points;
+ int cash;
nullpo_retv(sd);
- pc_setaccountreg(sd,"#CASHPOINTS",sd->cashPoints - cash);
- pc_setaccountreg(sd,"#KAFRAPOINTS",sd->kafraPoints - points);
- sprintf(output, "Used %d kafra points and %d cash points. %d kafra and %d cash points remaining.", points, cash, sd->kafraPoints, sd->cashPoints);
- clif_disp_onlyself(sd, output, strlen(output));
+ if( price < 0 || points < 0 )
+ {
+ ShowError("pc_paycash: Paying negative points (price=%d, points=%d, account_id=%d, char_id=%d).\n", price, points, sd->status.account_id, sd->status.char_id);
+ return;
+ }
+
+ if( points > price )
+ {
+ ShowWarning("pc_paycash: More kafra points provided than needed (price=%d, points=%d, account_id=%d, char_id=%d).\n", price, points, sd->status.account_id, sd->status.char_id);
+ points = price;
+ }
+
+ cash = price-points;
+
+ if( sd->cashPoints < cash || sd->kafraPoints < points )
+ {
+ ShowError("pc_paycash: Not enough points (cash=%d, kafra=%d) to cover the price (cash=%d, kafra=%d) (account_id=%d, char_id=%d).\n", sd->cashPoints, sd->kafraPoints, cash, points, sd->status.account_id, sd->status.char_id);
+ return;
+ }
+
+ pc_setaccountreg(sd, "#CASHPOINTS", sd->cashPoints-cash);
+ pc_setaccountreg(sd, "#KAFRAPOINTS", sd->kafraPoints-points);
+
+ if( battle_config.cashshop_show_points )
+ {
+ sprintf(output, msg_txt(504), points, cash, sd->kafraPoints, sd->cashPoints);
+ clif_disp_onlyself(sd, output, strlen(output));
+ }
}
void pc_getcash(struct map_session_data *sd, int cash, int points)
@@ -3287,18 +3309,44 @@ void pc_getcash(struct map_session_data *sd, int cash, int points)
if( cash > 0 )
{
- pc_setaccountreg(sd,"#CASHPOINTS",sd->cashPoints + cash);
+ if( cash > MAX_ZENY-sd->cashPoints )
+ {
+ ShowWarning("pc_getcash: Cash point overflow (cash=%d, have cash=%d, account_id=%d, char_id=%d).\n", cash, sd->cashPoints, sd->status.account_id, sd->status.char_id);
+ cash = MAX_ZENY-sd->cashPoints;
+ }
- sprintf(output, "Gained %d cash points. Total %d points", cash, sd->cashPoints);
- clif_disp_onlyself(sd, output, strlen(output));
+ pc_setaccountreg(sd, "#CASHPOINTS", sd->cashPoints+cash);
+
+ if( battle_config.cashshop_show_points )
+ {
+ sprintf(output, msg_txt(505), cash, sd->cashPoints);
+ clif_disp_onlyself(sd, output, strlen(output));
+ }
+ }
+ else if( cash < 0 )
+ {
+ ShowError("pc_getcash: Obtaining negative cash points (cash=%d, account_id=%d, char_id=%d).\n", cash, sd->status.account_id, sd->status.char_id);
}
if( points > 0 )
{
- pc_setaccountreg(sd,"#KAFRAPOINTS",sd->kafraPoints + points);
+ if( points > MAX_ZENY-sd->kafraPoints )
+ {
+ ShowWarning("pc_getcash: Kafra point overflow (points=%d, have points=%d, account_id=%d, char_id=%d).\n", points, sd->kafraPoints, sd->status.account_id, sd->status.char_id);
+ points = MAX_ZENY-sd->kafraPoints;
+ }
- sprintf(output, "Gained %d kafra points. Total %d points", points, sd->kafraPoints);
- clif_disp_onlyself(sd, output, strlen(output));
+ pc_setaccountreg(sd, "#KAFRAPOINTS", sd->kafraPoints+points);
+
+ if( battle_config.cashshop_show_points )
+ {
+ sprintf(output, msg_txt(506), points, sd->kafraPoints);
+ clif_disp_onlyself(sd, output, strlen(output));
+ }
+ }
+ else if( points < 0 )
+ {
+ ShowError("pc_getcash: Obtaining negative kafra points (points=%d, account_id=%d, char_id=%d).\n", points, sd->status.account_id, sd->status.char_id);
}
}
@@ -4386,6 +4434,7 @@ int pc_checkallowskill(struct map_session_data *sd)
SC_SPEARQUICKEN,
SC_ADRENALINE,
SC_ADRENALINE2,
+ SC_DANCING,
SC_GATLINGFEVER
};
const enum sc_type scs_list[] = {
@@ -4703,7 +4752,7 @@ int pc_mapid2jobid(unsigned short class_, int sex)
/*====================================================
* This function return the name of the job (by [Yor])
*----------------------------------------------------*/
-char* job_name(int class_)
+const char* job_name(int class_)
{
switch (class_) {
case JOB_NOVICE:
@@ -5809,7 +5858,7 @@ void pc_respawn(struct map_session_data* sd, clr_type clrtype)
{
if( !pc_isdead(sd) )
return; // not applicable
- if( sd->state.bg_id && bg_member_respawn(sd) )
+ if( sd->bg_id && bg_member_respawn(sd) )
return; // member revived by battleground
pc_setstand(sd);
@@ -5900,10 +5949,10 @@ int pc_dead(struct map_session_data *sd,struct block_list *src)
pc_setglobalreg(sd,"PC_DIE_COUNTER",sd->die_counter+1);
pc_setparam(sd, SP_KILLERRID, src?src->id:0);
- if( sd->state.bg_id )
+ if( sd->bg_id )
{
struct battleground_data *bg;
- if( (bg = bg_team_search(sd->state.bg_id)) != NULL && bg->die_event[0] )
+ if( (bg = bg_team_search(sd->bg_id)) != NULL && bg->die_event[0] )
npc_event(sd, bg->die_event, 0);
}
npc_script_event(sd,NPCE_DIE);
@@ -6147,9 +6196,9 @@ int pc_dead(struct map_session_data *sd,struct block_list *src)
add_timer(tick+1000, pc_respawn_timer, sd->bl.id, 0);
return 1|8;
}
- else if( sd->state.bg_id )
+ else if( sd->bg_id )
{
- struct battleground_data *bg = bg_team_search(sd->state.bg_id);
+ struct battleground_data *bg = bg_team_search(sd->bg_id);
if( bg && bg->mapindex > 0 )
{ // Respawn by BG
add_timer(tick+1000, pc_respawn_timer, sd->bl.id, 0);
@@ -6627,6 +6676,7 @@ int pc_equiplookall(struct map_session_data *sd)
clif_changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom);
clif_changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top);
clif_changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid);
+ clif_changelook(&sd->bl, LOOK_ROBE, sd->status.robe);
return 0;
}
@@ -6683,6 +6733,9 @@ int pc_changelook(struct map_session_data *sd,int type,int val)
break;
case LOOK_SHOES:
break;
+ case LOOK_ROBE:
+ sd->status.robe = val;
+ break;
}
clif_changelook(&sd->bl,type,val);
return 0;
@@ -7413,6 +7466,11 @@ int pc_equipitem(struct map_session_data *sd,int n,int req_pos)
}
if(pos & EQP_SHOES)
clif_changelook(&sd->bl,LOOK_SHOES,0);
+ if( pos&EQP_GARMENT )
+ {
+ sd->status.robe = id ? id->look : 0;
+ clif_changelook(&sd->bl, LOOK_ROBE, sd->status.robe);
+ }
pc_checkallowskill(sd); //Check if status changes should be halted.
@@ -7483,7 +7541,6 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag)
sd->status.weapon = sd->weapontype2;
pc_calcweapontype(sd);
clif_changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon);
- status_change_end(&sd->bl, SC_DANCING, INVALID_TIMER); //When unequipping, stop dancing. [Skotlex]
}
if(sd->status.inventory[n].equip & EQP_HAND_L) {
sd->status.shield = sd->weapontype2 = 0;
@@ -7504,6 +7561,11 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag)
}
if(sd->status.inventory[n].equip & EQP_SHOES)
clif_changelook(&sd->bl,LOOK_SHOES,0);
+ if( sd->status.inventory[n].equip&EQP_GARMENT )
+ {
+ sd->status.robe = 0;
+ clif_changelook(&sd->bl, LOOK_ROBE, 0);
+ }
clif_unequipitemack(sd,n,sd->status.inventory[n].equip,1);
@@ -7963,168 +8025,6 @@ void pc_setstand(struct map_session_data *sd){
sd->state.dead_sit = sd->vd.dead_sit = 0;
}
-/*==========================================
- * Duel organizing functions [LuzZza]
- *------------------------------------------*/
-void duel_savetime(struct map_session_data* sd)
-{
- time_t timer;
- struct tm *t;
-
- time(&timer);
- t = localtime(&timer);
-
- pc_setglobalreg(sd, "PC_LAST_DUEL_TIME", t->tm_mday*24*60 + t->tm_hour*60 + t->tm_min);
- return;
-}
-
-int duel_checktime(struct map_session_data* sd)
-{
- int diff;
- time_t timer;
- struct tm *t;
-
- time(&timer);
- t = localtime(&timer);
-
- diff = t->tm_mday*24*60 + t->tm_hour*60 + t->tm_min - pc_readglobalreg(sd, "PC_LAST_DUEL_TIME");
-
- return !(diff >= 0 && diff < battle_config.duel_time_interval);
-}
-static int duel_showinfo_sub(struct map_session_data* sd, va_list va)
-{
- struct map_session_data *ssd = va_arg(va, struct map_session_data*);
- int *p = va_arg(va, int*);
- char output[256];
-
- if (sd->duel_group != ssd->duel_group) return 0;
-
- sprintf(output, " %d. %s", ++(*p), sd->status.name);
- clif_disp_onlyself(ssd, output, strlen(output));
- return 1;
-}
-
-int duel_showinfo(const unsigned int did, struct map_session_data* sd)
-{
- int p=0;
- char output[256];
-
- if(duel_list[did].max_players_limit > 0)
- sprintf(output, msg_txt(370), //" -- Duels: %d/%d, Members: %d/%d, Max players: %d --"
- did, duel_count,
- duel_list[did].members_count,
- duel_list[did].members_count + duel_list[did].invites_count,
- duel_list[did].max_players_limit);
- else
- sprintf(output, msg_txt(371), //" -- Duels: %d/%d, Members: %d/%d --"
- did, duel_count,
- duel_list[did].members_count,
- duel_list[did].members_count + duel_list[did].invites_count);
-
- clif_disp_onlyself(sd, output, strlen(output));
- map_foreachpc(duel_showinfo_sub, sd, &p);
- return 0;
-}
-
-int duel_create(struct map_session_data* sd, const unsigned int maxpl)
-{
- int i=1;
- char output[256];
-
- while(duel_list[i].members_count > 0 && i < MAX_DUEL) i++;
- if(i == MAX_DUEL) return 0;
-
- duel_count++;
- sd->duel_group = i;
- duel_list[i].members_count++;
- duel_list[i].invites_count = 0;
- duel_list[i].max_players_limit = maxpl;
-
- strcpy(output, msg_txt(372)); // " -- Duel has been created (@invite/@leave) --"
- clif_disp_onlyself(sd, output, strlen(output));
-
- clif_map_property(sd, MAPPROPERTY_FREEPVPZONE);
- //clif_misceffect2(&sd->bl, 159);
- return i;
-}
-
-int duel_invite(const unsigned int did, struct map_session_data* sd, struct map_session_data* target_sd)
-{
- char output[256];
-
- // " -- Player %s invites %s to duel --"
- sprintf(output, msg_txt(373), sd->status.name, target_sd->status.name);
- clif_disp_message(&sd->bl, output, strlen(output), DUEL_WOS);
-
- target_sd->duel_invite = did;
- duel_list[did].invites_count++;
-
- // "Blue -- Player %s invites you to PVP duel (@accept/@reject) --"
- sprintf(output, msg_txt(374), sd->status.name);
- clif_broadcast((struct block_list *)target_sd, output, strlen(output)+1, 0x10, SELF);
- return 0;
-}
-
-static int duel_leave_sub(struct map_session_data* sd, va_list va)
-{
- int did = va_arg(va, int);
- if (sd->duel_invite == did)
- sd->duel_invite = 0;
- return 0;
-}
-
-int duel_leave(const unsigned int did, struct map_session_data* sd)
-{
- char output[256];
-
- // " <- Player %s has left duel --"
- sprintf(output, msg_txt(375), sd->status.name);
- clif_disp_message(&sd->bl, output, strlen(output), DUEL_WOS);
-
- duel_list[did].members_count--;
-
- if(duel_list[did].members_count == 0) {
- map_foreachpc(duel_leave_sub, did);
- duel_count--;
- }
-
- sd->duel_group = 0;
- duel_savetime(sd);
- clif_map_property(sd, MAPPROPERTY_NOTHING);
- return 0;
-}
-
-int duel_accept(const unsigned int did, struct map_session_data* sd)
-{
- char output[256];
-
- duel_list[did].members_count++;
- sd->duel_group = sd->duel_invite;
- duel_list[did].invites_count--;
- sd->duel_invite = 0;
-
- // " -> Player %s has accepted duel --"
- sprintf(output, msg_txt(376), sd->status.name);
- clif_disp_message(&sd->bl, output, strlen(output), DUEL_WOS);
-
- clif_map_property(sd, MAPPROPERTY_FREEPVPZONE);
- //clif_misceffect2(&sd->bl, 159);
- return 0;
-}
-
-int duel_reject(const unsigned int did, struct map_session_data* sd)
-{
- char output[256];
-
- // " -- Player %s has rejected duel --"
- sprintf(output, msg_txt(377), sd->status.name);
- clif_disp_message(&sd->bl, output, strlen(output), DUEL_WOS);
-
- duel_list[did].invites_count--;
- sd->duel_invite = 0;
- return 0;
-}
-
int pc_split_str(char *str,char **val,int num)
{
int i;
@@ -8486,8 +8386,6 @@ int do_init_pc(void)
pc_readdb();
pc_read_motd(); // Read MOTD [Valaris]
- memset(&duel_list[0], 0, sizeof(duel_list));
-
add_timer_func_list(pc_invincible_timer, "pc_invincible_timer");
add_timer_func_list(pc_eventtimer, "pc_eventtimer");
add_timer_func_list(pc_inventory_rental_end, "pc_inventory_rental_end");
diff --git a/src/map/pc.h b/src/map/pc.h
index 7d86706ca..b6b6fb851 100644
--- a/src/map/pc.h
+++ b/src/map/pc.h
@@ -96,63 +96,61 @@ struct map_session_data {
//NOTE: When deciding to add a flag to state or special_state, take into consideration that state is preserved in
//status_calc_pc, while special_state is recalculated in each call. [Skotlex]
struct {
- unsigned active : 1; //Marks active player (not active is logging in/out, or changing map servers)
- unsigned menu_or_input : 1;// if a script is waiting for feedback from the player
- unsigned dead_sit : 2;
- unsigned lr_flag : 2;
- unsigned connect_new : 1;
- unsigned arrow_atk : 1;
- unsigned combo : 2; // 1:Asura, 2:Kick [Inkfish]
- unsigned gangsterparadise : 1;
- unsigned rest : 1;
- unsigned storage_flag : 2; //0: closed, 1: Normal Storage open, 2: guild storage open [Skotlex]
- unsigned snovice_dead_flag : 1; //Explosion spirits on death: 0 off, 1 used.
- unsigned abra_flag : 1; // Abracadabra bugfix by Aru
- unsigned autocast : 1; // Autospell flag [Inkfish]
- unsigned autotrade : 1; //By Fantik
- unsigned reg_dirty : 3; //By Skotlex (marks whether registry variables have been saved or not yet)
- unsigned showdelay :1;
- unsigned showexp :1;
- unsigned showzeny :1;
- unsigned mainchat :1; //[LuzZza]
- unsigned noask :1; // [LuzZza]
- unsigned trading :1; //[Skotlex] is 1 only after a trade has started.
- unsigned deal_locked :2; //1: Clicked on OK. 2: Clicked on TRADE
- unsigned monster_ignore :1; // for monsters to ignore a character [Valaris] [zzo]
- unsigned size :2; // for tiny/large types
- unsigned night :1; //Holds whether or not the player currently has the SI_NIGHT effect on. [Skotlex]
- unsigned blockedmove :1;
- unsigned using_fake_npc :1;
- unsigned rewarp :1; //Signals that a player should warp as soon as he is done loading a map. [Skotlex]
- unsigned killer : 1;
- unsigned killable : 1;
- unsigned doridori : 1;
- unsigned ignoreAll : 1;
- unsigned debug_remove_map : 1; // temporary state to track double remove_map's [FlavioJS]
- unsigned buyingstore : 1;
- unsigned lesseffect : 1;
- unsigned vending : 1;
+ unsigned int active : 1; //Marks active player (not active is logging in/out, or changing map servers)
+ unsigned int menu_or_input : 1;// if a script is waiting for feedback from the player
+ unsigned int dead_sit : 2;
+ 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]
+ unsigned int snovice_dead_flag : 1; //Explosion spirits on death: 0 off, 1 used.
+ unsigned int abra_flag : 1; // Abracadabra bugfix by Aru
+ unsigned int autocast : 1; // Autospell flag [Inkfish]
+ unsigned int autotrade : 1; //By Fantik
+ unsigned int reg_dirty : 3; //By Skotlex (marks whether registry variables have been saved or not yet)
+ unsigned int showdelay :1;
+ unsigned int showexp :1;
+ unsigned int showzeny :1;
+ unsigned int mainchat :1; //[LuzZza]
+ unsigned int noask :1; // [LuzZza]
+ unsigned int trading :1; //[Skotlex] is 1 only after a trade has started.
+ unsigned int deal_locked :2; //1: Clicked on OK. 2: Clicked on TRADE
+ unsigned int monster_ignore :1; // for monsters to ignore a character [Valaris] [zzo]
+ unsigned int size :2; // for tiny/large types
+ unsigned int night :1; //Holds whether or not the player currently has the SI_NIGHT effect on. [Skotlex]
+ unsigned int blockedmove :1;
+ unsigned int using_fake_npc :1;
+ unsigned int rewarp :1; //Signals that a player should warp as soon as he is done loading a map. [Skotlex]
+ unsigned int killer : 1;
+ unsigned int killable : 1;
+ unsigned int doridori : 1;
+ unsigned int ignoreAll : 1;
+ unsigned int debug_remove_map : 1; // temporary state to track double remove_map's [FlavioJS]
+ unsigned int buyingstore : 1;
+ unsigned int lesseffect : 1;
+ unsigned int vending : 1;
+ unsigned int noks : 3; // [Zeph Kill Steal Protection]
+ unsigned int changemap : 1;
+ short pmap; // Previous map on Map Change
unsigned short autoloot;
unsigned short autolootid; // [Zephyrus]
- unsigned noks : 3; // [Zeph Kill Steal Protection]
- bool changemap;
- short pmap; // Previous map on Map Change
- struct guild *gmaster_flag;
- unsigned int bg_id;
- unsigned short user_font;
unsigned short autobonus; //flag to indicate if an autobonus is activated. [Inkfish]
+ struct guild *gmaster_flag;
} state;
struct {
unsigned char no_weapon_damage, no_magic_damage, no_misc_damage;
- unsigned restart_full_recover : 1;
- unsigned no_castcancel : 1;
- unsigned no_castcancel2 : 1;
- unsigned no_sizefix : 1;
- unsigned no_gemstone : 1;
- unsigned intravision : 1; // Maya Purple Card effect [DracoRPG]
- unsigned perfect_hiding : 1; // [Valaris]
- unsigned no_knockback : 1;
- unsigned bonus_coma : 1;
+ unsigned int restart_full_recover : 1;
+ unsigned int no_castcancel : 1;
+ unsigned int no_castcancel2 : 1;
+ unsigned int no_sizefix : 1;
+ unsigned int no_gemstone : 1;
+ unsigned int intravision : 1; // Maya Purple Card effect [DracoRPG]
+ unsigned int perfect_hiding : 1; // [Valaris]
+ unsigned int no_knockback : 1;
+ unsigned int bonus_coma : 1;
} special_state;
int login_id1, login_id2;
unsigned short class_; //This is the internal job ID used by the map server to simplify comparisons/queries/etc. [Skotlex]
@@ -380,7 +378,7 @@ struct map_session_data {
unsigned short pvp_rank, pvp_lastusers;
unsigned short pvp_won, pvp_lost;
- char eventqueue[MAX_EVENTQUEUE][NAME_LENGTH*2+3];
+ char eventqueue[MAX_EVENTQUEUE][EVENT_NAME_LENGTH];
int eventtimer[MAX_EVENTTIMER];
unsigned short eventcount; // [celest]
@@ -420,6 +418,13 @@ struct map_session_data {
const char* debug_file;
int debug_line;
const char* debug_func;
+
+ unsigned int bg_id;
+ unsigned short user_font;
+
+ // temporary debugging of bug #3504
+ const char* delunit_prevfile;
+ int delunit_prevline;
};
//Update this max as necessary. 55 is the value needed for Super Baby currently
@@ -493,6 +498,13 @@ enum equip_pos {
#define EQP_HELM (EQP_HEAD_LOW|EQP_HEAD_MID|EQP_HEAD_TOP)
#define EQP_ACC (EQP_ACC_L|EQP_ACC_R)
+/// Equip positions that use a visible sprite
+#if PACKETVER < 20110111
+ #define EQP_VISIBLE EQP_HELM
+#else
+ #define EQP_VISIBLE (EQP_HELM|EQP_GARMENT)
+#endif
+
//Equip indexes constants. (eg: sd->equip_index[EQI_AMMO] returns the index
//where the arrows are equipped)
enum equip_index {
@@ -510,16 +522,6 @@ enum equip_index {
EQI_MAX
};
-struct duel {
- int members_count;
- int invites_count;
- int max_players_limit;
-};
-
-#define MAX_DUEL 1024
-extern struct duel duel_list[MAX_DUEL];
-extern int duel_count;
-
#define pc_setdead(sd) ( (sd)->state.dead_sit = (sd)->vd.dead_sit = 1 )
#define pc_setsit(sd) ( (sd)->state.dead_sit = (sd)->vd.dead_sit = 2 )
#define pc_isdead(sd) ( (sd)->state.dead_sit == 1 )
@@ -731,7 +733,7 @@ int pc_candrop(struct map_session_data *sd,struct item *item);
int pc_jobid2mapid(unsigned short b_class); // Skotlex
int pc_mapid2jobid(unsigned short class_, int sex); // Skotlex
-char * job_name(int class_);
+const char * job_name(int class_);
struct skill_tree_entry {
short id;
@@ -784,15 +786,6 @@ void pc_inventory_rentals(struct map_session_data *sd);
int pc_inventory_rental_clear(struct map_session_data *sd);
void pc_inventory_rental_add(struct map_session_data *sd, int seconds);
-//Duel functions // [LuzZza]
-int duel_create(struct map_session_data* sd, const unsigned int maxpl);
-int duel_invite(const unsigned int did, struct map_session_data* sd, struct map_session_data* target_sd);
-int duel_accept(const unsigned int did, struct map_session_data* sd);
-int duel_reject(const unsigned int did, struct map_session_data* sd);
-int duel_leave(const unsigned int did, struct map_session_data* sd);
-int duel_showinfo(const unsigned int did, struct map_session_data* sd);
-int duel_checktime(struct map_session_data* sd);
-
int pc_read_motd(void); // [Valaris]
int pc_disguise(struct map_session_data *sd, int class_);
diff --git a/src/map/quest.c b/src/map/quest.c
index 3e43fcda6..4960d8a93 100644
--- a/src/map/quest.c
+++ b/src/map/quest.c
@@ -279,17 +279,13 @@ int quest_check(TBL_PC * sd, int quest_id, quest_check_type type)
return (sd->quest_log[i].time < (unsigned int)time(NULL) ? 2 : sd->quest_log[i].state == Q_COMPLETE ? 1 : 0);
case HUNTING:
{
- int j = sd->quest_index[i];
-
- if( sd->quest_log[i].count[0] < quest_db[j].count[0] || sd->quest_log[i].count[1] < quest_db[j].count[1] || sd->quest_log[i].count[2] < quest_db[j].count[2] )
- {
- if( sd->quest_log[i].time < (unsigned int)time(NULL) )
- return 1;
-
- return 0;
- }
-
- return 2;
+ int j;
+ ARR_FIND(0, MAX_QUEST_OBJECTIVES, j, sd->quest_log[i].count[j] < quest_db[sd->quest_index[i]].count[j]);
+ if( j == MAX_QUEST_OBJECTIVES )
+ return 2;
+ if( sd->quest_log[i].time < (unsigned int)time(NULL) )
+ return 1;
+ return 0;
}
default:
ShowError("quest_check_quest: Unknown parameter %d",type);
@@ -334,7 +330,7 @@ int quest_read_db(void)
continue;
else
{
- ShowError("quest_read_db: insufficient columes in line %s\n", line);
+ ShowError("quest_read_db: insufficient columns in line %s\n", line);
continue;
}
}
diff --git a/src/map/script.c b/src/map/script.c
index 4e874b5f0..bf0b4f652 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -577,9 +577,17 @@ static void disp_error_message2(const char *mes,const char *pos,int report)
/// Checks event parameter validity
static void check_event(struct script_state *st, const char *evt)
{
- if( evt != NULL && *evt != '\0' && !stristr(evt,"::On") ){
- ShowError("NPC event parameter deprecated! Please use 'NPCNAME::OnEVENT' instead of '%s'.\n",evt);
- script_reportsrc(st);
+ if( evt && evt[0] && !stristr(evt, "::On") )
+ {
+ if( npc_event_isspecial(evt) )
+ {
+ ; // portable small/large monsters or other attributes
+ }
+ else
+ {
+ ShowWarning("NPC event parameter deprecated! Please use 'NPCNAME::OnEVENT' instead of '%s'.\n", evt);
+ script_reportsrc(st);
+ }
}
}
@@ -4780,7 +4788,7 @@ BUILDIN_FUNC(jobchange)
BUILDIN_FUNC(jobname)
{
int class_=script_getnum(st,2);
- script_pushconststr(st,job_name(class_));
+ script_pushconststr(st, (char*)job_name(class_));
return 0;
}
@@ -6316,7 +6324,7 @@ BUILDIN_FUNC(getcharid)
case 1: script_pushint(st,sd->status.party_id); break;
case 2: script_pushint(st,sd->status.guild_id); break;
case 3: script_pushint(st,sd->status.account_id); break;
- case 4: script_pushint(st,sd->state.bg_id); break;
+ case 4: script_pushint(st,sd->bg_id); break;
default:
ShowError("buildin_getcharid: invalid parameter (%d).\n", num);
script_pushint(st,0);
@@ -8179,8 +8187,8 @@ BUILDIN_FUNC(cmdothernpc) // Added by RoVeRT
{
const char* npc = script_getstr(st,2);
const char* command = script_getstr(st,3);
- char event[51];
- snprintf(event, 51, "%s::OnCommand%s", npc, command);
+ char event[EVENT_NAME_LENGTH];
+ snprintf(event, sizeof(event), "%s::OnCommand%s", npc, command);
check_event(st, event);
npc_event_do(event);
return 0;
@@ -12737,6 +12745,13 @@ BUILDIN_FUNC(query_sql)
BUILDIN_FUNC(query_logsql)
{
#ifndef TXT_ONLY
+ if( !log_config.sql_logs )
+ {// logmysql_handle == NULL
+ ShowWarning("buildin_query_logsql: SQL logs are disabled, query '%s' will not be executed.\n", script_getstr(st,2));
+ script_pushint(st,-1);
+ return 1;
+ }
+
return buildin_query_sql_sub(st, logmysql_handle);
#else
//for TXT version, we always return -1
@@ -14239,7 +14254,7 @@ BUILDIN_FUNC(bg_monster_set_team)
if( (mbl = map_id2bl(id)) == NULL || mbl->type != BL_MOB )
return 0;
md = (TBL_MOB *)mbl;
- md->state.bg_id = bg_id;
+ md->bg_id = bg_id;
mob_stop_attack(md);
mob_stop_walking(md, 0);
@@ -14252,7 +14267,7 @@ BUILDIN_FUNC(bg_monster_set_team)
BUILDIN_FUNC(bg_leave)
{
struct map_session_data *sd = script_rid2sd(st);
- if( sd == NULL || !sd->state.bg_id )
+ if( sd == NULL || !sd->bg_id )
return 0;
bg_team_leave(sd,0);
@@ -14360,11 +14375,11 @@ BUILDIN_FUNC(instance_create)
}
else if( res < 0 )
{
- char *err;
+ const char *err;
switch(res)
{
case -3: err = "No free instances"; break;
- case -2: err = "Missing parameter"; break;
+ case -2: err = "Invalid party ID"; break;
case -1: err = "Invalid type"; break;
default: err = "Unknown"; break;
}
@@ -14658,10 +14673,10 @@ BUILDIN_FUNC(setfont)
if( sd == NULL )
return 0;
- if( sd->state.user_font != font )
- sd->state.user_font = font;
+ if( sd->user_font != font )
+ sd->user_font = font;
else
- sd->state.user_font = 0;
+ sd->user_font = 0;
clif_font(sd);
return 0;
diff --git a/src/map/status.c b/src/map/status.c
index e4f333753..e68ebd291 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -6429,7 +6429,7 @@ int status_change_clear(struct block_list* bl, int type)
/*==========================================
* ステータス異常終了
*------------------------------------------*/
-int status_change_end(struct block_list* bl, enum sc_type type, int tid)
+int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const char* file, int line)
{
struct map_session_data *sd;
struct status_change *sc;
@@ -6588,10 +6588,27 @@ int status_change_end(struct block_list* bl, enum sc_type type, int tid)
break;
case SC_DANCING:
{
+ const char* prevfile = "<unknown>";
+ int prevline = 0;
struct map_session_data *dsd;
struct status_change_entry *dsc;
struct skill_unit_group *group;
+ if( sd )
+ {
+ if( sd->delunit_prevfile )
+ {// initially this is NULL, when a character logs in
+ prevfile = sd->delunit_prevfile;
+ prevline = sd->delunit_prevline;
+ }
+ else
+ {
+ prevfile = "<none>";
+ }
+ sd->delunit_prevfile = file;
+ sd->delunit_prevline = line;
+ }
+
if(sce->val4 && sce->val4 != BCT_SELF && (dsd=map_id2sd(sce->val4)))
{// end status on partner as well
dsc = dsd->sc.data[SC_DANCING];
@@ -6608,10 +6625,12 @@ int status_change_end(struct block_list* bl, enum sc_type type, int tid)
if( group == NULL )
{
- ShowDebug("status_change_end: SC_DANCING is missing skill unit group (val1=%d, val2=%d, val3=%d, val4=%d, timer=%d, tid=%d, char_id=%d, map=%s, x=%d, y=%d). Please report this! (#3504)\n",
+ ShowDebug("status_change_end: SC_DANCING is missing skill unit group (val1=%d, val2=%d, val3=%d, val4=%d, timer=%d, tid=%d, char_id=%d, map=%s, x=%d, y=%d, prev=%s:%d, from=%s:%d). Please report this! (#3504)\n",
sce->val1, sce->val2, sce->val3, sce->val4, sce->timer, tid,
sd ? sd->status.char_id : 0,
- mapindex_id2name(map_id2index(bl->m)), bl->x, bl->y);
+ mapindex_id2name(map_id2index(bl->m)), bl->x, bl->y,
+ prevfile, prevline,
+ file, line);
}
sce->val2 = 0;
diff --git a/src/map/status.h b/src/map/status.h
index 718fd2e88..45eaa5c8d 100644
--- a/src/map/status.h
+++ b/src/map/status.h
@@ -1276,7 +1276,8 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti
#define sc_start4(bl, type, rate, val1, val2, val3, val4, tick) status_change_start(bl,type,100*(rate),val1,val2,val3,val4,tick,0)
int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val1,int val2,int val3,int val4,int tick,int flag);
-int status_change_end(struct block_list* bl, enum sc_type type, int tid);
+int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const char* file, int line);
+#define status_change_end(bl,type,tid) status_change_end_(bl,type,tid,__FILE__,__LINE__)
int kaahi_heal_timer(int tid, unsigned int tick, int id, intptr data);
int status_change_timer(int tid, unsigned int tick, int id, intptr data);
int status_change_timer_sub(struct block_list* bl, va_list ap);
diff --git a/src/map/unit.c b/src/map/unit.c
index da1ce1c14..3cec43f70 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -17,6 +17,7 @@
#include "mercenary.h"
#include "skill.h"
#include "clif.h"
+#include "duel.h"
#include "npc.h"
#include "guild.h"
#include "status.h"
@@ -2067,7 +2068,7 @@ int unit_free(struct block_list *bl, clr_type clrtype)
guild_send_memberinfoshort(sd,0);
pc_cleareventtimer(sd);
pc_inventory_rental_clear(sd);
- if( sd->state.bg_id ) bg_team_leave(sd,1);
+ if( sd->bg_id ) bg_team_leave(sd,1);
pc_delspiritball(sd,sd->spiritball,1);
if( sd->reg )
diff --git a/src/map/unit.h b/src/map/unit.h
index fd5a83208..e349a7466 100644
--- a/src/map/unit.h
+++ b/src/map/unit.h
@@ -47,9 +47,10 @@ struct unit_data {
struct view_data {
unsigned short
- class_,
+ class_,
weapon,
shield, //Or left-hand weapon.
+ robe,
head_top,
head_mid,
head_bottom,