diff --git a/conf/msg_conf/map_msg.conf b/conf/msg_conf/map_msg.conf index f0af25eb11..bf49506a1f 100644 --- a/conf/msg_conf/map_msg.conf +++ b/conf/msg_conf/map_msg.conf @@ -451,9 +451,29 @@ 463: Message configuration has been reloaded. 464: ---- Available languages: +480: ----- Players in Map ----- +481: Player '%s' (session #%d) | Location: %d,%d +482: ----- NPCs in Map ----- +483: ----- Chats in Map ----- +484: Chat: %s | Player: %s | Location: %d %d +485: Users: %d/%d | Password: %s | Public: %s +486: Yes +487: No +488: Please enter at least one valid list number (usage: @mapinfo <0-3> ). +489: NPC %d: %s::%s | Direction: %s | Sprite: %d | Location: %d %d +490: NPC %d: %s | Direction: %s | Sprite: %d | Location: %d %d +491: North +492: North West +493: West +494: South West +495: South +496: South East +497: East +498: North East +499: Unknown + // Messages of others (not for GM commands) // ---------------------------------------- - //500 free 501: Your account time limit is: %d-%m-%Y %H:%M:%S. 502: Day Mode is activated @@ -848,7 +868,7 @@ 1042: Town Map 1043: Autotrade Enabled 1044: Autotrade Disabled -1045: Battlegrounds ON +1045: Battlegrounds ON type=%d 1046: PvP Flags: 1047: Pvp ON | 1048: NoGuild | @@ -901,27 +921,15 @@ 1095: NoMVPLoot | 1096: PartyLock | 1097: GuildLock | -1098: ----- Players in Map ----- -1099: Player '%s' (session #%d) | Location: %d,%d -1100: ----- NPCs in Map ----- -1101: North -1102: North West -1103: West -1104: South West -1105: South -1106: South East -1107: East -1108: North East -1109: North -1110: Unknown -1111: NPC %d: %s | Direction: %s | Sprite: %d | Location: %d %d -1112: NPC %d: %s::%s | Direction: %s | Sprite: %d | Location: %d %d -1113: ----- Chats in Map ----- -1114: Chat: %s | Player: %s | Location: %d %d -1115: Users: %d/%d | Password: %s | Public: %s -1116: Yes -1117: No -1118: Please enter at least one valid list number (usage: @mapinfo <0-3> ). +1098: Loadevent | +1099: Src4instance | +1100: Chmautojoin | +1101: nousecart | +1102: noitemconsumption | +1103: nosumstarmiracle | +1104: nomineeffect | +1105: nolockon | +1106: Restricted zone=%d // @mount 1119: You have mounted your Dragon. diff --git a/src/char/char.c b/src/char/char.c index 73f5ca4965..f1b641f94a 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -1104,7 +1104,7 @@ int mmo_chars_fromsql(struct char_session_data* sd, uint8* buf) || SQL_ERROR == SqlStmt_BindColumn(stmt, 29, SQLDT_SHORT, &p.head_top, 0, NULL, NULL) || SQL_ERROR == SqlStmt_BindColumn(stmt, 30, SQLDT_SHORT, &p.head_mid, 0, NULL, NULL) || SQL_ERROR == SqlStmt_BindColumn(stmt, 31, SQLDT_SHORT, &p.head_bottom, 0, NULL, NULL) - || SQL_ERROR == SqlStmt_BindColumn(stmt, 32, SQLDT_STRING, &last_map, sizeof(last_map), NULL, NULL) + || SQL_ERROR == SqlStmt_BindColumn(stmt, 32, SQLDT_STRING, &last_map, sizeof(last_map), NULL, NULL) || SQL_ERROR == SqlStmt_BindColumn(stmt, 33, SQLDT_SHORT, &p.rename, 0, NULL, NULL) || SQL_ERROR == SqlStmt_BindColumn(stmt, 34, SQLDT_UINT32, &p.delete_date, 0, NULL, NULL) || SQL_ERROR == SqlStmt_BindColumn(stmt, 35, SQLDT_SHORT, &p.robe, 0, NULL, NULL) @@ -1223,7 +1223,7 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything || SQL_ERROR == SqlStmt_BindColumn(stmt, 46, SQLDT_INT, &p->mother, 0, NULL, NULL) || SQL_ERROR == SqlStmt_BindColumn(stmt, 47, SQLDT_INT, &p->child, 0, NULL, NULL) || SQL_ERROR == SqlStmt_BindColumn(stmt, 48, SQLDT_INT, &p->fame, 0, NULL, NULL) - || SQL_ERROR == SqlStmt_BindColumn(stmt, 49, SQLDT_SHORT, &p->rename, 0, NULL, NULL) + || SQL_ERROR == SqlStmt_BindColumn(stmt, 49, SQLDT_SHORT, &p->rename, 0, NULL, NULL) || SQL_ERROR == SqlStmt_BindColumn(stmt, 50, SQLDT_UINT32, &p->delete_date, 0, NULL, NULL) || SQL_ERROR == SqlStmt_BindColumn(stmt, 51, SQLDT_SHORT, &p->robe, 0, NULL, NULL) || SQL_ERROR == SqlStmt_BindColumn(stmt, 52, SQLDT_UINT32, &p->character_moves, 0, NULL, NULL) @@ -1242,6 +1242,18 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything p->last_point.map = mapindex_name2id(last_map); p->save_point.map = mapindex_name2id(save_map); + if( p->last_point.map == 0 ) { + p->last_point.map = mapindex_name2id(MAP_DEFAULT); + p->last_point.x = MAP_DEFAULT_X; + p->last_point.y = MAP_DEFAULT_Y; + } + + if( p->save_point.map == 0 ) { + p->save_point.map = mapindex_name2id(MAP_DEFAULT); + p->save_point.x = MAP_DEFAULT_X; + p->save_point.y = MAP_DEFAULT_Y; + } + strcat(t_msg, " status"); if (!load_everything) // For quick selection of data when displaying the char menu @@ -1727,9 +1739,9 @@ int delete_char_sql(int char_id) if( hom_id ) mapif_homunculus_delete(hom_id); - /* remove elemental */ - if (elemental_id) - mapif_elemental_delete(elemental_id); + /* remove elemental */ + if (elemental_id) + mapif_elemental_delete(elemental_id); /* remove mercenary data */ mercenary_owner_delete(char_id); @@ -1907,16 +1919,46 @@ int mmo_char_tobuf(uint8* buffer, struct mmo_charstatus* p) return 106+offset; } + + +// Tell client how many pages, kRO sends 17 (Yommy) + +void char_charlist_notify( int fd, struct char_session_data* sd ){ + WFIFOHEAD(fd, 6); + WFIFOW(fd, 0) = 0x9a0; + // pages to req / send them all in 1 until mmo_chars_fromsql can split them up + WFIFOL(fd, 2) = 1; //int TotalCnt + WFIFOSET(fd,6); +} + +void char_block_character( int fd, struct char_session_data* sd ){ + WFIFOHEAD(fd, 4); + WFIFOW(fd, 0) = 0x20d; + WFIFOW(fd, 2) = 4; //packet len + WFIFOSET(fd,4); +} + +/* Made Possible by Yommy~! <3 */ +void mmo_char_send099d(int fd, struct char_session_data *sd) { + WFIFOHEAD(fd,4 + (MAX_CHARS*MAX_CHAR_BUF)); + WFIFOW(fd,0) = 0x99d; + WFIFOW(fd,2) = mmo_chars_fromsql(sd, WFIFOP(fd,4)) + 4; + WFIFOSET(fd,WFIFOW(fd,2)); +} + +//struct PACKET_CH_CHARLIST_REQ { 0x0 short PacketType} +void char_parse_req_charlist(int fd, struct char_session_data* sd){ + mmo_char_send099d(fd,sd); +} + //---------------------------------------- // Function to send characters to a player //---------------------------------------- -int mmo_char_send006b(int fd, struct char_session_data* sd) -{ +int mmo_char_send006b(int fd, struct char_session_data* sd){ int j, offset = 0; #if PACKETVER >= 20100413 offset += 3; #endif - if (save_log) ShowInfo("Loading Char Data ("CL_BOLD"%d"CL_RESET")\n",sd->account_id); @@ -1942,7 +1984,6 @@ int mmo_char_send006b(int fd, struct char_session_data* sd) void mmo_char_send082d(int fd, struct char_session_data* sd) { if (save_log) ShowInfo("Loading Char Data ("CL_BOLD"%d"CL_RESET")\n",sd->account_id); - WFIFOHEAD(fd,29); WFIFOW(fd,0) = 0x82d; WFIFOW(fd,2) = 29; @@ -1953,7 +1994,16 @@ void mmo_char_send082d(int fd, struct char_session_data* sd) { WFIFOB(fd,8) = sd->char_slots; memset(WFIFOP(fd,9), 0, 20); // unused bytes WFIFOSET(fd,29); +} + +void mmo_char_send(int fd, struct char_session_data* sd){ + #if PACKETVER >= 20130000 + mmo_char_send082d(fd,sd); + char_charlist_notify(fd,sd); + char_block_character(fd,sd); + #else mmo_char_send006b(fd,sd); + #endif } int char_married(int pl1, int pl2) @@ -2258,11 +2308,7 @@ int parse_fromlogin(int fd) { WFIFOSET(i,3); } else { // send characters to player - #if PACKETVER >= 20130000 - mmo_char_send082d(i, sd); - #else - mmo_char_send006b(i, sd); - #endif + mmo_char_send(i, sd); #if PACKETVER >= 20110309 if( pincode_enabled ){ // PIN code system enabled @@ -4254,50 +4300,47 @@ int parse_char(int fd) case 0x2af8: if (RFIFOREST(fd) < 60) return 0; - { - char* l_user = (char*)RFIFOP(fd,2); - char* l_pass = (char*)RFIFOP(fd,26); - l_user[23] = '\0'; - l_pass[23] = '\0'; - ARR_FIND( 0, ARRAYLENGTH(server), i, server[i].fd <= 0 ); - if( runflag != CHARSERVER_ST_RUNNING || - i == ARRAYLENGTH(server) || - strcmp(l_user, userid) != 0 || - strcmp(l_pass, passwd) != 0 ) - { - WFIFOHEAD(fd,3); - WFIFOW(fd,0) = 0x2af9; - WFIFOB(fd,2) = 3; - WFIFOSET(fd,3); - } else { - WFIFOHEAD(fd,3); - WFIFOW(fd,0) = 0x2af9; - WFIFOB(fd,2) = 0; - WFIFOSET(fd,3); + else { + char* l_user = (char*)RFIFOP(fd,2); + char* l_pass = (char*)RFIFOP(fd,26); + l_user[23] = '\0'; + l_pass[23] = '\0'; + ARR_FIND( 0, ARRAYLENGTH(server), i, server[i].fd <= 0 ); + if( runflag != CHARSERVER_ST_RUNNING || + i == ARRAYLENGTH(server) || + strcmp(l_user, userid) != 0 || + strcmp(l_pass, passwd) != 0 ) + { + WFIFOHEAD(fd,3); + WFIFOW(fd,0) = 0x2af9; + WFIFOB(fd,2) = 3; + WFIFOSET(fd,3); + } else { + WFIFOHEAD(fd,3); + WFIFOW(fd,0) = 0x2af9; + WFIFOB(fd,2) = 0; + WFIFOSET(fd,3); - server[i].fd = fd; - server[i].ip = ntohl(RFIFOL(fd,54)); - server[i].port = ntohs(RFIFOW(fd,58)); - server[i].users = 0; - memset(server[i].map, 0, sizeof(server[i].map)); - session[fd]->func_parse = parse_frommap; - session[fd]->flag.server = 1; - realloc_fifo(fd, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK); - char_mapif_init(fd); + server[i].fd = fd; + server[i].ip = ntohl(RFIFOL(fd,54)); + server[i].port = ntohs(RFIFOW(fd,58)); + server[i].users = 0; + memset(server[i].map, 0, sizeof(server[i].map)); + session[fd]->func_parse = parse_frommap; + session[fd]->flag.server = 1; + realloc_fifo(fd, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK); + char_mapif_init(fd); + } + RFIFOSKIP(fd,60); } - - RFIFOSKIP(fd,60); - } - return 0; // avoid processing of followup packets here + return 0; // avoid processing of followup packets here // checks the entered pin case 0x8b8: if( RFIFOREST(fd) < 10 ) return 0; - if( pincode_enabled && RFIFOL(fd,2) == sd->account_id ) pincode_check( fd, sd ); - RFIFOSKIP(fd,10); break; @@ -4305,7 +4348,6 @@ int parse_char(int fd) case 0x8c5: if( RFIFOREST(fd) < 6 ) return 0; - if( pincode_enabled && RFIFOL(fd,2) == sd->account_id ){ if( strlen( sd->pincode ) <= 0 ){ pincode_sendstate( fd, sd, PINCODE_NEW ); @@ -4313,7 +4355,6 @@ int parse_char(int fd) pincode_sendstate( fd, sd, PINCODE_ASK ); } } - RFIFOSKIP(fd,6); break; @@ -4332,10 +4373,8 @@ int parse_char(int fd) case 0x8ba: if( RFIFOREST(fd) < 10 ) return 0; - if( pincode_enabled && RFIFOL(fd,2) == sd->account_id ) pincode_setnew( fd, sd ); - RFIFOSKIP(fd,10); break; @@ -4345,10 +4384,17 @@ int parse_char(int fd) return 0; moveCharSlot( fd, sd, RFIFOW(fd, 2), RFIFOW(fd, 4) ); - + mmo_char_send(fd, sd); RFIFOSKIP(fd,8); break; + case 0x9a1: + if( RFIFOREST(fd) < 2 ) + return 0; + char_parse_req_charlist(fd,sd); + RFIFOSKIP(fd,2); + break; + // unknown packet received default: ShowError("parse_char: Received unknown packet "CL_WHITE"0x%x"CL_RESET" from ip '"CL_WHITE"%s"CL_RESET"'! Disconnecting!\n", RFIFOW(fd,0), ip2str(ipl, NULL)); @@ -4720,11 +4766,7 @@ void moveCharSlot( int fd, struct char_session_data* sd, unsigned short from, un // We successfully moved the char - time to notify the client moveCharSlotReply( fd, sd, from, 0 ); -#if PACKETVER >= 20130000 - mmo_char_send082d(fd, sd); -#else - mmo_char_send006b( fd, sd ); -#endif + mmo_char_send(fd, sd); } // reason diff --git a/src/char/int_party.c b/src/char/int_party.c index a88e5c586a..30e694d620 100644 --- a/src/char/int_party.c +++ b/src/char/int_party.c @@ -476,6 +476,11 @@ int mapif_parse_CreateParty(int fd, char *name, int item, int item2, struct part if (char_name_option == 1) { // only letters/symbols in char_name_letters are authorised for (i = 0; i < NAME_LENGTH && name[i]; i++) if (strchr(char_name_letters, name[i]) == NULL) { + if( name[i] == '"' ) { /* client-special-char */ + normalize_name(name,"\""); + mapif_parse_CreateParty(fd,name,item,item2,leader); + return 0; + } mapif_party_created(fd,leader->account_id,leader->char_id,NULL); return 0; } diff --git a/src/common/cbasetypes.h b/src/common/cbasetypes.h index 731a8b5786..4e541a4cf9 100644 --- a/src/common/cbasetypes.h +++ b/src/common/cbasetypes.h @@ -177,6 +177,7 @@ typedef unsigned long int ppuint32; // integer with exact processor width (and best speed) ////////////////////////////// #include // size_t +//#include //boolean #if defined(WIN32) && !defined(MINGW) // does not have a signed size_t ////////////////////////////// @@ -276,7 +277,7 @@ typedef char bool; #undef swap #endif // hmm only ints? -//#define swap(a,b) { int temp=a; a=b; b=temp;} +//#define swap(a,b) { int temp=a; a=b; b=temp;} // if using macros then something that is type independent //#define swap(a,b) ((a == b) || ((a ^= b), (b ^= a), (a ^= b))) // Avoid "value computed is not used" warning and generates the same assembly code diff --git a/src/common/core.c b/src/common/core.c index d0e89e5dc7..89e6b67daa 100644 --- a/src/common/core.c +++ b/src/common/core.c @@ -55,8 +55,7 @@ char SERVER_TYPE = ATHENA_SERVER_NONE; #ifndef POSIX #define compat_signal(signo, func) signal(signo, func) #else -sigfunc *compat_signal(int signo, sigfunc *func) -{ +sigfunc *compat_signal(int signo, sigfunc *func) { struct sigaction sact, oact; sact.sa_handler = func; @@ -77,10 +76,8 @@ sigfunc *compat_signal(int signo, sigfunc *func) * CORE : Console events for Windows *--------------------------------------*/ #ifdef _WIN32 -static BOOL WINAPI console_handler(DWORD c_event) -{ - switch(c_event) - { +static BOOL WINAPI console_handler(DWORD c_event) { + switch(c_event) { case CTRL_CLOSE_EVENT: case CTRL_LOGOFF_EVENT: case CTRL_SHUTDOWN_EVENT: @@ -95,8 +92,7 @@ static BOOL WINAPI console_handler(DWORD c_event) return TRUE; } -static void cevents_init() -{ +static void cevents_init() { if (SetConsoleCtrlHandler(console_handler,TRUE)==FALSE) ShowWarning ("Unable to install the console handler!\n"); } @@ -105,8 +101,7 @@ static void cevents_init() /*====================================== * CORE : Signal Sub Function *--------------------------------------*/ -static void sig_proc(int sn) -{ +static void sig_proc(int sn) { static int is_called = 0; switch (sn) { @@ -139,8 +134,7 @@ static void sig_proc(int sn) } } -void signals_init (void) -{ +void signals_init (void) { compat_signal(SIGTERM, sig_proc); compat_signal(SIGINT, sig_proc); #ifndef _DEBUG // need unhandled exceptions to debug on Windows @@ -158,13 +152,11 @@ void signals_init (void) #endif #ifdef SVNVERSION - const char *get_svn_revision(void) - { +const char *get_svn_revision(void) { return EXPAND_AND_QUOTE(SVNVERSION); } #else// not SVNVERSION -const char* get_svn_revision(void) -{ +const char* get_svn_revision(void) { static char svn_version_buffer[16] = ""; FILE *fp; @@ -199,12 +191,10 @@ const char* get_svn_revision(void) fclose(fp); // parse buffer - for( i = prefix_len + 1; i + postfix_len <= len; ++i ) - { + for( i = prefix_len + 1; i + postfix_len <= len; ++i ) { if( buffer[i] != postfix[0] || memcmp(buffer + i, postfix, postfix_len) != 0 ) continue; // postfix missmatch - for( j = i; j > 0; --j ) - {// skip digits + for( j = i; j > 0; --j ) {// skip digits if( !ISDIGIT(buffer[j - 1]) ) break; } diff --git a/src/common/mapindex.c b/src/common/mapindex.c index dcebbb1a61..2361f3a83b 100644 --- a/src/common/mapindex.c +++ b/src/common/mapindex.c @@ -5,12 +5,14 @@ #include "../common/showmsg.h" #include "../common/malloc.h" #include "../common/strlib.h" +#include "../common/db.h" #include "mapindex.h" #include #include #include +DBMap *mapindex_db; struct _indexes { char name[MAP_NAME_LENGTH]; //Stores map name } indexes[MAX_MAPINDEX]; @@ -23,11 +25,10 @@ char mapindex_cfgfile[80] = "db/map_index.txt"; /// Retrieves the map name from 'string' (removing .gat extension if present). /// Result gets placed either into 'buf' or in a static local buffer. -const char* mapindex_getmapname(const char* string, char* output) -{ +const char* mapindex_getmapname(const char* string, char* output) { static char buf[MAP_NAME_LENGTH]; char* dest = (output != NULL) ? output : buf; - + size_t len = strnlen(string, MAP_NAME_LENGTH_EXT); if (len == MAP_NAME_LENGTH_EXT) { ShowWarning("(mapindex_normalize_name) Map name '%*s' is too long!\n", 2*MAP_NAME_LENGTH_EXT, string); @@ -35,18 +36,17 @@ const char* mapindex_getmapname(const char* string, char* output) } if (len >= 4 && stricmp(&string[len-4], ".gat") == 0) len -= 4; // strip .gat extension - + len = min(len, MAP_NAME_LENGTH-1); safestrncpy(dest, string, len+1); memset(&dest[len], '\0', MAP_NAME_LENGTH-len); - + return dest; } /// Retrieves the map name from 'string' (adding .gat extension if not already present). /// Result gets placed either into 'buf' or in a static local buffer. -const char* mapindex_getmapname_ext(const char* string, char* output) -{ +const char* mapindex_getmapname_ext(const char* string, char* output) { static char buf[MAP_NAME_LENGTH_EXT]; char* dest = (output != NULL) ? output : buf; @@ -69,19 +69,17 @@ const char* mapindex_getmapname_ext(const char* string, char* output) } memset(&dest[len], '\0', MAP_NAME_LENGTH_EXT-len); - + return dest; } /// Adds a map to the specified index /// Returns 1 if successful, 0 oherwise -int mapindex_addmap(int index, const char* name) -{ +int mapindex_addmap(int index, const char* name) { char map_name[MAP_NAME_LENGTH]; if (index == -1){ - for (index = 1; index < max_index; index++) - { + for (index = 1; index < max_index; index++) { //if (strcmp(indexes[index].name,"#CLEARED#")==0) if (indexes[index].name[0] == '\0') break; @@ -105,29 +103,27 @@ int mapindex_addmap(int index, const char* name) return 0; } - if (mapindex_exists(index)) + if (mapindex_exists(index)) { ShowWarning("(mapindex_add) Overriding index %d: map \"%s\" -> \"%s\"\n", index, indexes[index].name, map_name); + strdb_remove(mapindex_db, indexes[index].name); + } safestrncpy(indexes[index].name, map_name, MAP_NAME_LENGTH); + strdb_iput(mapindex_db, map_name, index); if (max_index <= index) max_index = index+1; return index; } -unsigned short mapindex_name2id(const char* name) -{ - //TODO: Perhaps use a db to speed this up? [Skotlex] +unsigned short mapindex_name2id(const char* name) { int i; - char map_name[MAP_NAME_LENGTH]; mapindex_getmapname(name, map_name); - for (i = 1; i < max_index; i++) - { - if (strcmpi(indexes[i].name,map_name)==0) - return i; - } + if( (i = strdb_iget(mapindex_db, map_name)) ) + return i; + ShowDebug("mapindex_name2id: Map \"%s\" not found in index list!\n", map_name); return 0; } @@ -141,27 +137,24 @@ const char* mapindex_id2name(unsigned short id) return indexes[id].name; } -void mapindex_init(void) -{ +void mapindex_init(void) { FILE *fp; char line[1024]; int last_index = -1; int index; - char map_name[1024]; - - memset (&indexes, 0, sizeof (indexes)); - fp=fopen(mapindex_cfgfile,"r"); - if(fp==NULL){ + char map_name[MAP_NAME_LENGTH]; + + if( ( fp = fopen(mapindex_cfgfile,"r") ) == NULL ){ ShowFatalError("Unable to read mapindex config file %s!\n", mapindex_cfgfile); exit(EXIT_FAILURE); //Server can't really run without this file. } - while(fgets(line, sizeof(line), fp)) - { + memset (&indexes, 0, sizeof (indexes)); + mapindex_db = strdb_alloc(DB_OPT_DUP_KEY, MAP_NAME_LENGTH); + while(fgets(line, sizeof(line), fp)) { if(line[0] == '/' && line[1] == '/') continue; - switch (sscanf(line, "%1023s\t%d", map_name, &index)) - { + switch (sscanf(line, "%12s\t%d", map_name, &index)) { case 1: //Map with no ID given, auto-assign index = last_index+1; case 2: //Map with ID given @@ -173,6 +166,10 @@ void mapindex_init(void) last_index = index; } fclose(fp); + + if( !strdb_iget(mapindex_db, MAP_DEFAULT) ) { + ShowError("mapindex_init: MAP_DEFAULT '%s' not found in cache! update mapindex.h MAP_DEFAULT var!!!\n",MAP_DEFAULT); + } } int mapindex_removemap(int index){ @@ -180,6 +177,6 @@ int mapindex_removemap(int index){ return 0; } -void mapindex_final(void) -{ +void mapindex_final(void) { + db_destroy(mapindex_db); } diff --git a/src/common/mapindex.h b/src/common/mapindex.h index 75cb254c06..d557013ff3 100644 --- a/src/common/mapindex.h +++ b/src/common/mapindex.h @@ -47,6 +47,11 @@ extern char mapindex_cfgfile[80]; #define MAP_MALAYA "malaya" #define MAP_ECLAGE "eclage" +// When a map index search fails, return results from what map? default:prontera +#define MAP_DEFAULT MAP_PRONTERA +#define MAP_DEFAULT_X 150 +#define MAP_DEFAULT_Y 150 + const char* mapindex_getmapname(const char* string, char* output); const char* mapindex_getmapname_ext(const char* string, char* output); unsigned short mapindex_name2id(const char*); diff --git a/src/common/socket.c b/src/common/socket.c index d86cbd7e86..5ee3d4a904 100644 --- a/src/common/socket.c +++ b/src/common/socket.c @@ -1163,7 +1163,7 @@ void socket_final(void) if(session[i]) do_close(i); - // session[0] �̃_�~�[�f�[�^���폜 + // session[0] aFree(session[0]->rdata); aFree(session[0]->wdata); aFree(session[0]); diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 6f02a234e2..6e627389d8 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -676,7 +676,7 @@ ACMD_FUNC(whogm) memcpy(player_name, pl_sd->status.name, NAME_LENGTH); for (j = 0; player_name[j]; j++) player_name[j] = TOLOWER(player_name[j]); - // search with no case sensitive + // search with no case sensitive if (strstr(player_name, match_text) == NULL) continue; } @@ -2492,8 +2492,7 @@ ACMD_FUNC(stat_all) /*========================================== * *------------------------------------------*/ -ACMD_FUNC(guildlevelup) -{ +ACMD_FUNC(guildlevelup) { int level = 0; short added_level; struct guild *guild_info; @@ -2533,8 +2532,7 @@ ACMD_FUNC(guildlevelup) /*========================================== * *------------------------------------------*/ -ACMD_FUNC(makeegg) -{ +ACMD_FUNC(makeegg) { struct item_data *item_data; int id, pet_id; nullpo_retr(-1, sd); @@ -2573,8 +2571,7 @@ ACMD_FUNC(makeegg) /*========================================== * *------------------------------------------*/ -ACMD_FUNC(hatch) -{ +ACMD_FUNC(hatch) { nullpo_retr(-1, sd); if (sd->status.pet_id <= 0) clif_sendegg(sd); @@ -2589,8 +2586,7 @@ ACMD_FUNC(hatch) /*========================================== * *------------------------------------------*/ -ACMD_FUNC(petfriendly) -{ +ACMD_FUNC(petfriendly) { int friendly; struct pet_data *pd; nullpo_retr(-1, sd); @@ -3707,7 +3703,7 @@ ACMD_FUNC(reload) packetdb_readdb(); clif_displaymessage(fd, msg_txt(sd,1477)); // Packet database has been reloaded. } - + return 0; } @@ -3776,15 +3772,20 @@ ACMD_FUNC(mapinfo) { clif_displaymessage(fd, msg_txt(sd,1041)); // ------ Map Flags ------ if (map[m_id].flag.town) clif_displaymessage(fd, msg_txt(sd,1042)); // Town Map + if (map[m_id].flag.restricted){ + sprintf(atcmd_output, msg_txt(sd,1106),map[m_id].zone); + clif_displaymessage(fd, atcmd_output); //restricted + } if (battle_config.autotrade_mapflag == map[m_id].flag.autotrade) clif_displaymessage(fd, msg_txt(sd,1043)); // Autotrade Enabled else clif_displaymessage(fd, msg_txt(sd,1044)); // Autotrade Disabled - if (map[m_id].flag.battleground) - clif_displaymessage(fd, msg_txt(sd,1045)); // Battlegrounds ON - + if (map[m_id].flag.battleground){ + sprintf(atcmd_output, msg_txt(sd,1106),map[m_id].zone); + clif_displaymessage(fd, atcmd_output); // Battlegrounds ON type=%d + } strcpy(atcmd_output,msg_txt(sd,1046)); // PvP Flags: if (map[m_id].flag.pvp) strcat(atcmd_output, msg_txt(sd,1047)); // Pvp ON | @@ -3897,6 +3898,22 @@ ACMD_FUNC(mapinfo) { strcat(atcmd_output, msg_txt(sd,1096)); // PartyLock | if (map[m_id].flag.guildlock) strcat(atcmd_output, msg_txt(sd,1097)); // GuildLock | + if (map[m_id].flag.loadevent) + strcat(atcmd_output, msg_txt(sd,1098)); //Loadevent | + if (map[m_id].flag.src4instance) + strcat(atcmd_output, msg_txt(sd,1099)); // Src4instance | + if (map[m_id].flag.chmautojoin) + strcat(atcmd_output, msg_txt(sd,1100)); // Chmautojoin | + if (map[m_id].flag.nousecart) + strcat(atcmd_output, msg_txt(sd,1101)); // nousecart | + if (map[m_id].flag.noitemconsumption) + strcat(atcmd_output, msg_txt(sd,1102)); // noitemconsumption | + if (map[m_id].flag.nosumstarmiracle) + strcat(atcmd_output, msg_txt(sd,1103)); // nosumstarmiracle | + if (map[m_id].flag.nomineeffect) + strcat(atcmd_output, msg_txt(sd,1104)); // nomineeffect | + if (map[m_id].flag.nolockon) + strcat(atcmd_output, msg_txt(sd,1105)); // nolockon | clif_displaymessage(fd, atcmd_output); switch (list) { @@ -3904,12 +3921,12 @@ ACMD_FUNC(mapinfo) { // Do nothing. It's list 0, no additional display. break; case 1: - clif_displaymessage(fd, msg_txt(sd,1098)); // ----- Players in Map ----- + clif_displaymessage(fd, msg_txt(sd,480)); // ----- Players in Map ----- iter = mapit_getallusers(); for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) ) { if (pl_sd->mapindex == m_index) { - sprintf(atcmd_output, msg_txt(sd,1099), // Player '%s' (session #%d) | Location: %d,%d + sprintf(atcmd_output, msg_txt(sd,481), // Player '%s' (session #%d) | Location: %d,%d pl_sd->status.name, pl_sd->fd, pl_sd->bl.x, pl_sd->bl.y); clif_displaymessage(fd, atcmd_output); } @@ -3917,33 +3934,33 @@ ACMD_FUNC(mapinfo) { mapit_free(iter); break; case 2: - clif_displaymessage(fd, msg_txt(sd,1100)); // ----- NPCs in Map ----- + clif_displaymessage(fd, msg_txt(sd,482)); // ----- NPCs in Map ----- for (i = 0; i < map[m_id].npc_num;) { nd = map[m_id].npc[i]; switch(nd->ud.dir) { - case 0: strcpy(direction, msg_txt(sd,1101)); break; // North - case 1: strcpy(direction, msg_txt(sd,1102)); break; // North West - case 2: strcpy(direction, msg_txt(sd,1103)); break; // West - case 3: strcpy(direction, msg_txt(sd,1104)); break; // South West - case 4: strcpy(direction, msg_txt(sd,1105)); break; // South - case 5: strcpy(direction, msg_txt(sd,1106)); break; // South East - case 6: strcpy(direction, msg_txt(sd,1107)); break; // East - case 7: strcpy(direction, msg_txt(sd,1108)); break; // North East - case 9: strcpy(direction, msg_txt(sd,1109)); break; // North - default: strcpy(direction, msg_txt(sd,1110)); break; // Unknown + case 0: strcpy(direction, msg_txt(sd,491)); break; // North + case 1: strcpy(direction, msg_txt(sd,492)); break; // North West + case 2: strcpy(direction, msg_txt(sd,493)); break; // West + case 3: strcpy(direction, msg_txt(sd,494)); break; // South West + case 4: strcpy(direction, msg_txt(sd,495)); break; // South + case 5: strcpy(direction, msg_txt(sd,496)); break; // South East + case 6: strcpy(direction, msg_txt(sd,497)); break; // East + case 7: strcpy(direction, msg_txt(sd,498)); break; // North East + case 9: strcpy(direction, msg_txt(sd,491)); break; // North + default: strcpy(direction, msg_txt(sd,499)); break; // Unknown } if(strcmp(nd->name,nd->exname) == 0) - sprintf(atcmd_output, msg_txt(sd,1111), // NPC %d: %s | Direction: %s | Sprite: %d | Location: %d %d + sprintf(atcmd_output, msg_txt(sd,490), // NPC %d: %s | Direction: %s | Sprite: %d | Location: %d %d ++i, nd->name, direction, nd->class_, nd->bl.x, nd->bl.y); else - sprintf(atcmd_output, msg_txt(sd,1112), // NPC %d: %s::%s | Direction: %s | Sprite: %d | Location: %d %d - ++i, nd->name, nd->exname, direction, nd->class_, nd->bl.x, nd->bl.y); + sprintf(atcmd_output, msg_txt(sd,489), // NPC %d: %s::%s | Direction: %s | Sprite: %d | Location: %d %d + ++i, nd->name, nd->exname, direction, nd->class_, nd->bl.x, nd->bl.y); clif_displaymessage(fd, atcmd_output); } break; case 3: - clif_displaymessage(fd, msg_txt(sd,1113)); // ----- Chats in Map ----- + clif_displaymessage(fd, msg_txt(sd,483)); // ----- Chats in Map ----- iter = mapit_getallusers(); for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) ) { @@ -3951,18 +3968,18 @@ ACMD_FUNC(mapinfo) { pl_sd->mapindex == m_index && cd->usersd[0] == pl_sd) { - sprintf(atcmd_output, msg_txt(sd,1114), // Chat: %s | Player: %s | Location: %d %d - cd->title, pl_sd->status.name, cd->bl.x, cd->bl.y); + sprintf(atcmd_output, msg_txt(sd,484), // Chat: %s | Player: %s | Location: %d %d + cd->title, pl_sd->status.name, cd->bl.x, cd->bl.y); clif_displaymessage(fd, atcmd_output); - sprintf(atcmd_output, msg_txt(sd,1115), // Users: %d/%d | Password: %s | Public: %s - cd->users, cd->limit, cd->pass, (cd->pub) ? msg_txt(sd,1116) : msg_txt(sd,1117)); // Yes / No + sprintf(atcmd_output, msg_txt(sd,485), // Users: %d/%d | Password: %s | Public: %s + cd->users, cd->limit, cd->pass, (cd->pub) ? msg_txt(sd,486) : msg_txt(sd,487)); // Yes / No clif_displaymessage(fd, atcmd_output); } } mapit_free(iter); break; default: // normally impossible to arrive here - clif_displaymessage(fd, msg_txt(sd,1118)); // Please enter at least one valid list number (usage: @mapinfo <0-3> ). + clif_displaymessage(fd, msg_txt(sd,488)); // Please enter at least one valid list number (usage: @mapinfo <0-3> ). return -1; break; } @@ -6320,7 +6337,7 @@ ACMD_FUNC(summon) return -1; md->master_id=sd->bl.id; - md->special_state.ai=1; + md->special_state.ai=AI_ATTACK; md->deletetimer=add_timer(tick+(duration*60000),mob_timer_delete,md->bl.id,0); clif_specialeffect(&md->bl,344,AREA); mob_spawn(md); diff --git a/src/map/battle.c b/src/map/battle.c index 57e91f4b3f..ba1aa9414e 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -1708,7 +1708,7 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo wd.div_=skill_id?skill_get_num(skill_id,skill_lv):1; wd.amotion=(skill_id && skill_get_inf(skill_id)&INF_GROUND_SKILL)?0:sstatus->amotion; //Amotion should be 0 for ground skills. /*if(skill_id == KN_AUTOCOUNTER) // counter attack obeys ASPD delay on official - wd.amotion >>= 1; */ + wd.amotion >>= 1; */ wd.dmotion=tstatus->dmotion; wd.blewcount=skill_get_blewcount(skill_id,skill_lv); wd.flag = BF_WEAPON; //Initial Flag @@ -5160,8 +5160,8 @@ struct block_list* battle_get_master(struct block_list *src) prev = src; switch (src->type) { case BL_PET: - if (((TBL_PET*)src)->msd) - src = (struct block_list*)((TBL_PET*)src)->msd; + if (((TBL_PET*)src)->master) + src = (struct block_list*)((TBL_PET*)src)->master; break; case BL_MOB: if (((TBL_MOB*)src)->master_id) @@ -5245,9 +5245,9 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f } break; case BL_MOB: - if(((((TBL_MOB*)target)->special_state.ai == 2 || //Marine Spheres - (((TBL_MOB*)target)->special_state.ai == 3 && battle_config.summon_flora&1)) && //Floras - s_bl->type == BL_PC && src->type != BL_MOB) || (((TBL_MOB*)target)->special_state.ai == 4 && t_bl->id != s_bl->id)) //Zanzoe + if(((((TBL_MOB*)target)->special_state.ai == AI_SPHERE || //Marine Spheres + (((TBL_MOB*)target)->special_state.ai == AI_FLORA && battle_config.summon_flora&1)) && //Floras + s_bl->type == BL_PC && src->type != BL_MOB) || (((TBL_MOB*)target)->special_state.ai == AI_ZANZOU && t_bl->id != s_bl->id)) //Zanzoe { //Targettable by players state |= BCT_ENEMY; strip_enemy = 0; @@ -5412,7 +5412,7 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f if( !md->special_state.ai ) { //Normal mobs if( - ( target->type == BL_MOB && t_bl->type == BL_PC && ( ((TBL_MOB*)target)->special_state.ai != 4 && ((TBL_MOB*)target)->special_state.ai != 1 ) ) || + ( target->type == BL_MOB && t_bl->type == BL_PC && ( ((TBL_MOB*)target)->special_state.ai != AI_ZANZOU && ((TBL_MOB*)target)->special_state.ai != AI_ATTACK ) ) || ( t_bl->type == BL_MOB && !((TBL_MOB*)t_bl)->special_state.ai ) ) state |= BCT_PARTY; //Normal mobs with no ai are friends. diff --git a/src/map/battleground.c b/src/map/battleground.c index 7b605066d2..c3845e8c4e 100644 --- a/src/map/battleground.c +++ b/src/map/battleground.c @@ -179,8 +179,8 @@ int bg_team_get_id(struct block_list *bl) case BL_PC: return ((TBL_PC*)bl)->bg_id; case BL_PET: - if( ((TBL_PET*)bl)->msd ) - return ((TBL_PET*)bl)->msd->bg_id; + if( ((TBL_PET*)bl)->master ) + return ((TBL_PET*)bl)->master->bg_id; break; case BL_MOB: { diff --git a/src/map/buyingstore.c b/src/map/buyingstore.c index 44f6cf9bda..f4651e24b8 100644 --- a/src/map/buyingstore.c +++ b/src/map/buyingstore.c @@ -44,10 +44,8 @@ static unsigned int buyingstore_getuid(void) } -bool buyingstore_setup(struct map_session_data* sd, unsigned char slots) -{ - if( !battle_config.feature_buying_store || sd->state.vending || sd->state.buyingstore || sd->state.trading || slots == 0 ) - { +bool buyingstore_setup(struct map_session_data* sd, unsigned char slots){ + if (!battle_config.feature_buying_store || sd->state.vending || sd->state.buyingstore || sd->state.trading || slots == 0) { return false; } diff --git a/src/map/chrif.c b/src/map/chrif.c index c8094e0ebc..8ed44416eb 100644 --- a/src/map/chrif.c +++ b/src/map/chrif.c @@ -1230,7 +1230,7 @@ int chrif_load_scdata(int fd) { for (i = 0; i < count; i++) { data = (struct status_change_data*)RFIFOP(fd,14 + i*sizeof(struct status_change_data)); - status_change_start(NULL,&sd->bl, (sc_type)data->type, 10000, data->val1, data->val2, data->val3, data->val4, data->tick, 15); + status_change_start(NULL,&sd->bl, (sc_type)data->type, 10000, data->val1, data->val2, data->val3, data->val4, data->tick, 1|2|4|8); } #endif @@ -1600,7 +1600,11 @@ int do_final_chrif(void) { * *------------------------------------------*/ int do_init_chrif(void) { - + if(sizeof(struct mmo_charstatus) > 0xFFFF){ + ShowError("mmo_charstatus size = %d is too big to be transmit\n", + sizeof(struct mmo_charstatus)); + exit(EXIT_FAILURE); + } auth_db = idb_alloc(DB_OPT_BASE); auth_db_ers = ers_new(sizeof(struct auth_node),"chrif.c::auth_db_ers",ERS_OPT_NONE); diff --git a/src/map/clif.c b/src/map/clif.c index 5697f8bc3d..59886b33c2 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -2815,10 +2815,10 @@ void clif_updatestatus(struct map_session_data *sd,int type) WFIFOL(fd,4)=sd->battle_status.cri/10; break; case SP_MATK1: - WFIFOL(fd,4)=pc_rightside_matk(sd); + WFIFOL(fd,4)=pc_rightside_matk(sd); break; case SP_MATK2: - WFIFOL(fd,4)=pc_leftside_matk(sd); + WFIFOL(fd,4)=pc_leftside_matk(sd); break; @@ -11579,7 +11579,7 @@ void clif_parse_ReplyPartyInvite2(int fd,struct map_session_data *sd) /// 0100 void clif_parse_LeaveParty(int fd, struct map_session_data *sd) { - if(map[sd->bl.m].flag.partylock) { //Guild locked. + if(map[sd->bl.m].flag.partylock) { //part locked. clif_displaymessage(fd, msg_txt(sd,227)); return; } @@ -11591,7 +11591,7 @@ void clif_parse_LeaveParty(int fd, struct map_session_data *sd) /// 0103 .L .24B void clif_parse_RemovePartyMember(int fd, struct map_session_data *sd) { - if(map[sd->bl.m].flag.partylock) { //Guild locked. + if(map[sd->bl.m].flag.partylock) { //party locked. clif_displaymessage(fd, msg_txt(sd,227)); return; } diff --git a/src/map/clif.h b/src/map/clif.h index 65ce859d8b..b89b66d1b3 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -783,4 +783,5 @@ void clif_channel_msg(struct Channel *channel, struct map_session_data *sd, char #define clif_menuskill_clear(sd) (sd)->menuskill_id = (sd)->menuskill_val = (sd)->menuskill_val2 = 0; + #endif /* _CLIF_H_ */ diff --git a/src/map/elemental.c b/src/map/elemental.c index b757ec3ffa..57e7baed85 100644 --- a/src/map/elemental.c +++ b/src/map/elemental.c @@ -76,27 +76,27 @@ int elemental_create(struct map_session_data *sd, int class_, unsigned int lifet ele.mode = EL_MODE_PASSIVE; // Initial mode i = db->status.size+1; // summon level - //[(Casters Max HP/ 3 ) + (Casters INT x 10 )+ (Casters Job Level x 20 )] x [(Elemental Summon Level + 2) / 3] + //[(Caster�s Max HP/ 3 ) + (Caster�s INT x 10 )+ (Caster�s Job Level x 20 )] x [(Elemental Summon Level + 2) / 3] ele.hp = ele.max_hp = (sd->battle_status.max_hp/3 + sd->battle_status.int_*10 + sd->status.job_level) * ((i + 2) / 3); - //Casters Max SP /4 + //Caster�s Max SP /4 ele.sp = ele.max_sp = sd->battle_status.max_sp/4; - //Casters [ Max SP / (18 / Elemental Summon Skill Level) 1- 100 ] + //Caster�s [ Max SP / (18 / Elemental Summon Skill Level) 1- 100 ] ele.atk = (sd->battle_status.max_sp / (18 / i) * 1 - 100); - //Casters [ Max SP / (18 / Elemental Summon Skill Level) ] + //Caster�s [ Max SP / (18 / Elemental Summon Skill Level) ] ele.atk2 = sd->battle_status.max_sp / 18; - //Casters HIT + (Casters Base Level ) + //Caster�s HIT + (Caster�s Base Level ) ele.hit = sd->battle_status.hit + sd->status.base_level; - //[Elemental Summon Skill Level x (Casters INT / 2 + Casters DEX / 4)] + //[Elemental Summon Skill Level x (Caster�s INT / 2 + Caster�s DEX / 4)] ele.matk = i * (sd->battle_status.int_ / 2 + sd->battle_status.dex / 4); - //150 + [Casters DEX / 10] + [Elemental Summon Skill Level x 3 ] + //150 + [Caster�s DEX / 10] + [Elemental Summon Skill Level x 3 ] ele.amotion = 150 + sd->battle_status.dex / 10 + i * 3; - //Casters DEF + (Casters Base Level / (5 Elemental Summon Skill Level) + //Caster�s DEF + (Caster�s Base Level / (5 � Elemental Summon Skill Level) ele.def = sd->battle_status.def + sd->status.base_level / (5-i); - //Casters MDEF + (Casters INT / (5 - Elemental Summon Skill Level) + //Caster�s MDEF + (Caster�s INT / (5 - Elemental Summon Skill Level) ele.mdef = sd->battle_status.mdef + sd->battle_status.int_ / (5-i); - //Casters FLEE + (Casters Base Level / (5 Elemental Summon Skill Level) + //Caster�s FLEE + (Caster�s Base Level / (5 � Elemental Summon Skill Level) ele.flee = sd->status.base_level / (5-i); - //Casters HIT + (Casters Base Level ) + //Caster�s HIT + (Caster�s Base Level ) ele.hit = sd->battle_status.hit + sd->status.base_level; //per individual bonuses diff --git a/src/map/elemental.h b/src/map/elemental.h index f941f3dfd0..5033b461a4 100644 --- a/src/map/elemental.h +++ b/src/map/elemental.h @@ -47,6 +47,7 @@ struct elemental_data { struct s_elemental_db *db; struct s_elemental elemental; + int masterteleport_timer; struct map_session_data *master; int summon_timer; int skill_timer; diff --git a/src/map/homunculus.h b/src/map/homunculus.h index 146e956b35..f132701757 100644 --- a/src/map/homunculus.h +++ b/src/map/homunculus.h @@ -49,6 +49,7 @@ struct homun_data { struct s_homunculus_db *homunculusDB; //[orn] struct s_homunculus homunculus; //[orn] + int masterteleport_timer; struct map_session_data *master; //pointer back to its master int hungry_timer; //[orn] unsigned int exp_next; diff --git a/src/map/map.c b/src/map/map.c index cef8040def..7c9a253675 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -1735,43 +1735,38 @@ int map_quit(struct map_session_data *sd) { /*========================================== * Lookup, id to session (player,mob,npc,homon,merc..) *------------------------------------------*/ -struct map_session_data * map_id2sd(int id) -{ +struct map_session_data * map_id2sd(int id){ if (id <= 0) return NULL; return (struct map_session_data*)idb_get(pc_db,id); } -struct mob_data * map_id2md(int id) -{ +struct mob_data * map_id2md(int id){ if (id <= 0) return NULL; return (struct mob_data*)idb_get(mobid_db,id); } -struct npc_data * map_id2nd(int id) -{// just a id2bl lookup because there's no npc_db +struct npc_data * map_id2nd(int id){ struct block_list* bl = map_id2bl(id); - return BL_CAST(BL_NPC, bl); } -struct homun_data* map_id2hd(int id) -{ +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 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 pet_data* map_id2pd(int id){ struct block_list* bl = map_id2bl(id); + return BL_CAST(BL_PET, bl); +} +struct chat_data* map_id2cd(int id){ + struct block_list* bl = map_id2bl(id); return BL_CAST(BL_CHAT, bl); } diff --git a/src/map/map.h b/src/map/map.h index 45b8e31d30..b9d028e681 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -303,6 +303,16 @@ enum { ELE_MAX }; +enum mob_ai { + AI_NONE = 0, + AI_ATTACK, + AI_SPHERE, + AI_FLORA, + AI_ZANZOU, + AI_LEGION, + AI_MAX +}; + enum auto_trigger_flag { ATF_SELF=0x01, ATF_TARGET=0x02, @@ -333,9 +343,7 @@ struct spawn_data { unsigned int level; struct { unsigned int size : 2; //Holds if mob has to be tiny/large - unsigned int ai : 4; //Special ai for summoned monsters. - //0: Normal mob | 1: Standard summon, attacks mobs - //2: Alchemist Marine Sphere | 3: Alchemist Summon Flora | 4: Summon Zanzou + enum mob_ai ai; //Special ai for summoned monsters. unsigned int dynamic : 1; //Whether this data is indexed by a map's dynamic mob list unsigned int boss : 1; //0: Non-boss monster | 1: Boss monster } state; @@ -553,12 +561,12 @@ struct map_data { unsigned sakura : 1; // [Valaris] unsigned leaves : 1; // [Valaris] unsigned nogo : 1; // [Valaris] - unsigned nobaseexp : 1; // [Lorky] added by Lupus - unsigned nojobexp : 1; // [Lorky] - unsigned nomobloot : 1; // [Lorky] - unsigned nomvploot : 1; // [Lorky] + unsigned nobaseexp : 1; // [Lorky] added by Lupus + unsigned nojobexp : 1; // [Lorky] + unsigned nomobloot : 1; // [Lorky] + unsigned nomvploot : 1; // [Lorky] unsigned nightenabled :1; //For night display. [Skotlex] - unsigned restricted : 1; // [Komurka] + unsigned restricted : 1; // [Komurka] unsigned nodrop : 1; unsigned novending : 1; unsigned loadevent : 1; diff --git a/src/map/mob.c b/src/map/mob.c index 8484f17f3e..ca8e74c513 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -1969,11 +1969,11 @@ void mob_log_damage(struct mob_data *md, struct block_list *src, int damage) { struct pet_data *pd = (TBL_PET*)src; flag = MDLF_PET; - if( pd->msd ) + if( pd->master ) { - char_id = pd->msd->status.char_id; + char_id = pd->master->status.char_id; if( damage ) //Let mobs retaliate against the pet's master [Skotlex] - md->attacked_id = pd->msd->bl.id; + md->attacked_id = pd->master->bl.id; } break; } @@ -2079,7 +2079,7 @@ void mob_damage(struct mob_data *md, struct block_list *src, int damage) } #endif - if( md->special_state.ai == 2 ) {//LOne WOlf explained that ANYONE can trigger the marine countdown skill. [Skotlex] + if( md->special_state.ai == AI_SPHERE ) {//LOne WOlf explained that ANYONE can trigger the marine countdown skill. [Skotlex] md->state.alchemist = 1; mobskill_use(md, gettick(), MSC_ALCHEMIST); } @@ -2308,7 +2308,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type) if( !(type&1) && !map[m].flag.nomobloot && !md->state.rebirth && ( !md->special_state.ai || //Non special mob battle_config.alchemist_summon_reward == 2 || //All summoned give drops - (md->special_state.ai==2 && battle_config.alchemist_summon_reward == 1) //Marine Sphere Drops items. + (md->special_state.ai==AI_SPHERE && battle_config.alchemist_summon_reward == 1) //Marine Sphere Drops items. ) ) { // Item Drop struct item_drop_list *dlist = ers_alloc(item_drop_list_ers, struct item_drop_list); @@ -2736,7 +2736,7 @@ int mob_class_change (struct mob_data *md, int class_) if( mob_is_treasure(md) ) return 0; //Treasure Boxes - if( md->special_state.ai > 1 ) + if( md->special_state.ai > AI_ATTACK ) return 0; //Marine Spheres and Floras. if( mob_is_clone(md->class_) ) diff --git a/src/map/mob.h b/src/map/mob.h index d097f800d6..892b662dfb 100644 --- a/src/map/mob.h +++ b/src/map/mob.h @@ -69,14 +69,6 @@ enum size { SZ_BIG, }; -enum ai { - AI_NONE = 0, - AI_ATTACK, - AI_SPHERE, - AI_FLORA, - AI_ZANZOU, -}; - struct mob_skill { enum MobSkillState state; uint16 skill_id,skill_lv; @@ -129,13 +121,7 @@ struct mob_data { char name[NAME_LENGTH]; struct { unsigned int size : 2; //Small/Big monsters. - unsigned int ai : 4; //Special ai for summoned monsters. - //0: Normal mob. - //1: Standard summon, attacks mobs. - //2: Alchemist Marine Sphere - //3: Alchemist Summon Flora - //4: Summon Zanzou - //5: Summon Legion + enum mob_ai ai; //Special ai for summoned monsters. unsigned int clone : 1;/* is clone? 1:0 */ } special_state; //Special mob information that does not needs to be zero'ed on mob respawn. struct { diff --git a/src/map/npc.c b/src/map/npc.c index 2db638cae7..09b830d047 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -3063,7 +3063,7 @@ static const char* npc_parse_mob(char* w1, char* w2, char* w3, char* w4, const c return strchr(start, '\n'); } - if( (mob.state.ai < 0 || mob.state.ai > 4) && ai != -1 ) + if( (mob.state.ai < AI_NONE || mob.state.ai >= AI_MAX) && ai != -1 ) { ShowError("npc_parse_mob: Invalid ai %d for mob ID %d (file '%s', line '%d').\n", mob.state.ai, class_, filepath, strline(buffer, start - buffer)); return strchr(start, '\n'); @@ -3086,7 +3086,7 @@ static const char* npc_parse_mob(char* w1, char* w2, char* w3, char* w4, const c mob.level = mob_lv; if (size > 0 && size <= 2) mob.state.size = size; - if (ai > 0 && ai <= 4) + if (ai > AI_NONE && ai <= AI_MAX) mob.state.ai = ai; if (mob.num > 1 && battle_config.mob_count_rate != 100) { diff --git a/src/map/pc.c b/src/map/pc.c index 5d17891a32..e402c13854 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -519,7 +519,7 @@ int pc_makesavestatus(struct map_session_data *sd) if(!battle_config.save_clothcolor) sd->status.clothes_color=0; - //Only copy the Cart/Peco/Falcon options, the rest are handled via + //Only copy the Cart/Peco/Falcon options, the rest are handled via //status change load/saving. [Skotlex] #ifdef NEW_CARTS sd->status.option = sd->sc.option&(OPTION_INVISIBLE|OPTION_FALCON|OPTION_RIDING|OPTION_DRAGON|OPTION_WUG|OPTION_WUGRIDER|OPTION_MADOGEAR|OPTION_MOUNTING); @@ -4044,7 +4044,7 @@ int pc_takeitem(struct map_session_data *sd,struct flooritem_data *fitem) } else if(fitem->second_get_charid > 0 && fitem->second_get_charid != sd->status.char_id) - { + { second_sd = map_charid2sd(fitem->second_get_charid); if(DIFF_TICK(tick, fitem->second_get_tick) < 0) { if(!(p && p->party.item&1 && @@ -4837,8 +4837,7 @@ int pc_setpos(struct map_session_data* sd, unsigned short mapindex, int x, int y if(sd->bl.prev != NULL){ unit_remove_map_pc(sd,clrtype); clif_changemap(sd,map[m].index,x,y); // [MouseJstr] - } else if(sd->state.active) - //Tag player for rewarping after map-loading is done. [Skotlex] + } else if(sd->state.active) //Tag player for rewarping after map-loading is done. [Skotlex] sd->state.rewarp = 1; sd->mapindex = mapindex; @@ -6573,10 +6572,8 @@ static int pc_close_npc_timer(int tid, unsigned int tick, int id, intptr_t data) { TBL_PC *sd = map_id2sd(id); if(sd) pc_close_npc(sd,data); - return 0; } - /* * Method to properly close npc for player and clear anything related * @flag == 1 : produce close button @@ -7815,7 +7812,7 @@ int pc_setcart(struct map_session_data *sd,int type) { clif_cartlist(sd); clif_updatestatus(sd, SP_CARTINFO); sc_start(&sd->bl,&sd->bl, SC_PUSH_CART, 100, type, 0); - clif_status_load_notick(&sd->bl, SI_ON_PUSH_CART, 2 , type, 0, 0); + clif_status_load_notick(&sd->bl, SI_ON_PUSH_CART, 2 , type, 0, 0); if( sd->sc.data[SC_PUSH_CART] )/* forcefully update */ sd->sc.data[SC_PUSH_CART]->val1 = type; break; @@ -9231,7 +9228,7 @@ int pc_autosave(int tid, unsigned int tick, int id, intptr_t data) static int pc_daynight_timer_sub(struct map_session_data *sd,va_list ap) { if (sd->state.night != night_flag && map[sd->bl.m].flag.nightenabled) - { //Night/day state does not match. + { //Night/day state does not match. clif_status_load(&sd->bl, SI_NIGHT, night_flag); //New night effect by dynamix [Skotlex] sd->state.night = night_flag; return 1; diff --git a/src/map/pet.c b/src/map/pet.c index 07b9b069cd..f6b9d60299 100644 --- a/src/map/pet.c +++ b/src/map/pet.c @@ -64,7 +64,7 @@ void pet_set_intimate(struct pet_data *pd, int value) nullpo_retv(pd); intimate = pd->pet.intimate; - sd = pd->msd; + sd = pd->master; pd->pet.intimate = value; if( (intimate >= battle_config.pet_equip_min_friendly && pd->pet.intimate < battle_config.pet_equip_min_friendly) || (intimate < battle_config.pet_equip_min_friendly && pd->pet.intimate >= battle_config.pet_equip_min_friendly) ) @@ -135,7 +135,7 @@ int pet_target_check(struct map_session_data *sd,struct block_list *bl,int type) pd = sd->pd; - Assert((pd->msd == 0) || (pd->msd->pd == pd)); + Assert((pd->master == 0) || (pd->master->pd == pd)); if(bl == NULL || bl->type != BL_MOB || bl->prev == NULL || pd->pet.intimate < battle_config.pet_support_min_friendly || @@ -323,7 +323,7 @@ int pet_data_init(struct map_session_data *sd, struct s_pet *pet) nullpo_retr(1, sd); - Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->msd == sd); + Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->master == sd); if(sd->status.account_id != pet->account_id || sd->status.char_id != pet->char_id) { sd->status.pet_id = 0; @@ -350,7 +350,7 @@ int pet_data_init(struct map_session_data *sd, struct s_pet *pet) pd->bl.type = BL_PET; pd->bl.id = npc_get_new_npc_id(); - pd->msd = sd; + pd->master = sd; pd->petDB = &pet_db[i]; pd->db = mob_db(pet->class_); memcpy(&pd->pet, pet, sizeof(struct s_pet)); @@ -389,7 +389,7 @@ int pet_birth_process(struct map_session_data *sd, struct s_pet *pet) { nullpo_retr(1, sd); - Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->msd == sd); + Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->master == sd); if(sd->status.pet_id && pet->incuvate == 1) { sd->status.pet_id = 0; @@ -417,7 +417,7 @@ int pet_birth_process(struct map_session_data *sd, struct s_pet *pet) clif_pet_equip_area(sd->pd); clif_send_petstatus(sd); } - Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->msd == sd); + Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->master == sd); return 0; } @@ -791,7 +791,7 @@ static int pet_randomwalk(struct pet_data *pd,unsigned int tick) { nullpo_ret(pd); - Assert((pd->msd == 0) || (pd->msd->pd == pd)); + Assert((pd->master == 0) || (pd->master->pd == pd)); if(DIFF_TICK(pd->next_walktime,tick) < 0 && unit_can_move(&pd->bl)) { const int retrycount=20; @@ -968,7 +968,7 @@ static int pet_ai_sub_hard_lootsearch(struct block_list *bl,va_list ap) sd_charid = fitem->first_get_charid; - if(sd_charid && sd_charid != pd->msd->status.char_id) + if(sd_charid && sd_charid != pd->master->status.char_id) return 0; if(unit_can_reach_bl(&pd->bl,bl, pd->db->range2, 1, NULL, NULL) && diff --git a/src/map/pet.h b/src/map/pet.h index b46f552299..92ab41e814 100644 --- a/src/map/pet.h +++ b/src/map/pet.h @@ -95,7 +95,8 @@ struct pet_data { struct pet_skill_support* s_skill; struct pet_loot* loot; - struct map_session_data *msd; + int masterteleport_timer; + struct map_session_data *master; }; diff --git a/src/map/script.c b/src/map/script.c index a824c8053f..6426d2f87d 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -12083,7 +12083,7 @@ BUILDIN_FUNC(petloot) pd = sd->pd; if (pd->loot != NULL) { //Release whatever was there already and reallocate memory - pet_lootitem_drop(pd, pd->msd); + pet_lootitem_drop(pd, pd->master); aFree(pd->loot->item); } else diff --git a/src/map/skill.c b/src/map/skill.c index b4d9e47525..0a589a4902 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -919,17 +919,13 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, uint break; case MG_FROSTDIVER: -#ifndef RENEWAL - case WZ_FROSTNOVA: -#endif - sc_start(src,bl,SC_FREEZE,skill_lv*3+35,skill_lv,skill_get_time2(skill_id,skill_lv)); + if(!sc_start(src,bl,SC_FREEZE,skill_lv*3+35,skill_lv,skill_get_time2(skill_id,skill_lv))) + clif_skill_fail(sd,skill_id,0,0); break; -#ifdef RENEWAL case WZ_FROSTNOVA: sc_start(src,bl,SC_FREEZE,skill_lv*5+33,skill_lv,skill_get_time2(skill_id,skill_lv)); break; -#endif case WZ_STORMGUST: /** @@ -5140,7 +5136,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui if (!ud) break; if (inf&INF_SELF_SKILL || inf&INF_SUPPORT_SKILL) { if (src->type == BL_PET) - bl = (struct block_list*)((TBL_PET*)src)->msd; + bl = (struct block_list*)((TBL_PET*)src)->master; if (!bl) bl = src; unit_skilluse_id(src, bl->id, abra_skill_id, abra_skill_lv); } else { //Assume offensive skills @@ -5846,7 +5842,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case NPC_SELFDESTRUCTION: //Self Destruction hits everyone in range (allies+enemies) //Except for Summoned Marine spheres on non-versus maps, where it's just enemy. - i = ((!md || md->special_state.ai == 2) && !map_flag_vs(src->m))? + i = ((!md || md->special_state.ai == AI_SPHERE) && !map_flag_vs(src->m))? BCT_ENEMY:BCT_ALL; clif_skill_nodamage(src, src, skill_id, -1, 1); map_delblock(src); //Required to prevent chain-self-destructions hitting back. @@ -8734,7 +8730,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui if (!ud) break; if (inf&INF_SELF_SKILL || inf&INF_SUPPORT_SKILL) { if (src->type == BL_PET) - bl = (struct block_list*)((TBL_PET*)src)->msd; + bl = (struct block_list*)((TBL_PET*)src)->master; if (!bl) bl = src; unit_skilluse_id(src, bl->id, improv_skill_id, improv_skill_lv); } else { @@ -9266,7 +9262,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui sum_md = mob_once_spawn_sub(src, src->m, src->x, src->y, status_get_name(src), summons[skill_lv - 1], "", SZ_SMALL, AI_ATTACK); if (sum_md) { sum_md->master_id = src->id; - sum_md->special_state.ai = 5; + sum_md->special_state.ai = AI_LEGION; if (sum_md->deletetimer != INVALID_TIMER) delete_timer(sum_md->deletetimer, mob_timer_delete); sum_md->deletetimer = add_timer(gettick() + skill_get_time(skill_id, skill_lv), mob_timer_delete, sum_md->bl.id, 0); @@ -9496,7 +9492,16 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data) } break; } - +#ifdef OFFICIAL_WALKPATH + if( !path_search_long(NULL, src->m, src->x, src->y, target->x, target->y, CELL_CHKWALL) ) + { + if (sd) { + clif_skill_fail(sd,ud->skill_id,USESKILL_FAIL_LEVEL,0); + skill_consume_requirement(sd,ud->skill_id,ud->skill_lv,3); //Consume items anyway. + } + break; + } +#endif if( sd ) { if( !skill_check_condition_castend(sd, ud->skill_id, ud->skill_lv) ) @@ -9504,18 +9509,14 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data) else skill_consume_requirement(sd,ud->skill_id,ud->skill_lv,1); } -#ifdef OFFICIAL_WALKPATH - if( !path_search_long(NULL, src->m, src->x, src->y, target->x, target->y, CELL_CHKWALL) ) - break; -#endif + if( (src->type == BL_MER || src->type == BL_HOM) && !skill_check_condition_mercenary(src, ud->skill_id, ud->skill_lv, 1) ) break; - if (ud->state.running && ud->skill_id == TK_JUMPKICK) - { - ud->state.running = 0; - status_change_end(src, SC_RUN, INVALID_TIMER); - flag = 1; + if (ud->state.running && ud->skill_id == TK_JUMPKICK){ + ud->state.running = 0; + status_change_end(src, SC_RUN, INVALID_TIMER); + flag = 1; } if (ud->walktimer != INVALID_TIMER && ud->skill_id != TK_RUN && ud->skill_id != RA_WUGDASH) @@ -9579,7 +9580,7 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data) if(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_WIZARD && sc->data[SC_SPIRIT]->val3 == ud->skill_id && - ud->skill_id != WZ_WATERBALL) + ud->skill_id != WZ_WATERBALL) sc->data[SC_SPIRIT]->val3 = 0; //Clear bounced spell check. if( sc->data[SC_DANCING] && skill_get_inf2(ud->skill_id)&INF2_SONG_DANCE && sd ) @@ -9600,7 +9601,7 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data) //Skill failed. if (ud->skill_id == MO_EXTREMITYFIST && sd && !(sc && sc->data[SC_FOGWALL])) - { //When Asura fails... (except when it fails from Fog of Wall) + { //When Asura fails... (except when it fails from Fog of Wall) //Consume SP/spheres skill_consume_requirement(sd,ud->skill_id, ud->skill_lv,1); status_set_sp(src, 0, 0); @@ -17582,7 +17583,7 @@ void skill_init_unit_layout (void) { static const int dx[] = {-1,-1,-1,-1, 0, 0, 0, 0, 1, 1, 1, 1, -5,-5,-5,-5,-4,-4,-4,-4,-3,-3,-3,-3,-2,-2,-2,-2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, -1,-1,-1, 0, 0, 0, 1, 1, 1}; - static const int dy[] = { 0,-1,-2,-3, 0,-1,-2,-3, 0,-1,-2,-3, + static const int dy[] = { 0,-1,-2,-3, 0,-1,-2,-3, 0,-1,-2,-3, 0,-1,-2,-3, 0,-1,-2,-3, 0,-1,-2,-3, 0,-1,-2,-3, 0,-1,-2,-3, 0,-1,-2,-3, 0,-1,-2,-3, 0,-1,-2,-3, -4,-5,-6,-4,-5,-6,-4,-5,-6}; skill_unit_layout[pos].count = 53; diff --git a/src/map/status.c b/src/map/status.c index 476815fdc6..13dc10586c 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -2014,7 +2014,7 @@ int status_calc_mob_(struct mob_data* md, bool first) if (battle_config.slaves_inherit_speed && md->master_id) flag|=8; - if (md->master_id && md->special_state.ai>1) + if (md->master_id && md->special_state.ai>AI_ATTACK) flag|=16; if (!flag) @@ -2050,28 +2050,28 @@ int status_calc_mob_(struct mob_data* md, bool first) struct unit_data *ud = unit_bl2ud(mbl); //Remove special AI when this is used by regular mobs. if (mbl->type == BL_MOB && !((TBL_MOB*)mbl)->special_state.ai) - md->special_state.ai = 0; + md->special_state.ai = AI_NONE; if (ud) { // different levels of HP according to skill level switch(ud->skill_id){ case AM_SPHEREMINE: - status->max_hp = 2000 + 400*ud->skill_lv; - break; + status->max_hp = 2000 + 400*ud->skill_lv; + break; case KO_ZANZOU: - status->max_hp = 3000 + 3000 * ud->skill_lv; - break; + status->max_hp = 3000 + 3000 * ud->skill_lv; + break; case AM_CANNIBALIZE: - status->max_hp = 1500 + 200*ud->skill_lv + 10*status_get_lv(mbl); - status->mode|= MD_CANATTACK|MD_AGGRESSIVE; - break; + status->max_hp = 1500 + 200*ud->skill_lv + 10*status_get_lv(mbl); + status->mode|= MD_CANATTACK|MD_AGGRESSIVE; + break; case MH_SUMMON_LEGION:{ - int homblvl = status_get_lv(mbl); - status->max_hp = 10 * (100 * (ud->skill_lv + 2) + homblvl); - status->batk = 100 * (ud->skill_lv+5) / 2; - status->def = 10 * (100 * (ud->skill_lv+2) + homblvl); - // status->aspd_rate = 10 * (2 * (20 - ud->skill_lv) - homblvl/10); - // status->aspd_rate = max(100,status->aspd_rate); - break; + int homblvl = status_get_lv(mbl); + status->max_hp = 10 * (100 * (ud->skill_lv + 2) + homblvl); + status->batk = 100 * (ud->skill_lv+5) / 2; + status->def = 10 * (100 * (ud->skill_lv+2) + homblvl); + // status->aspd_rate = 10 * (2 * (20 - ud->skill_lv) - homblvl/10); + // status->aspd_rate = max(100,status->aspd_rate); + break; } } status->hp = status->max_hp; @@ -2182,9 +2182,9 @@ int status_calc_pet_(struct pet_data *pd, bool first) } } - if (battle_config.pet_lv_rate && pd->msd) + if (battle_config.pet_lv_rate && pd->master) { - struct map_session_data *sd = pd->msd; + struct map_session_data *sd = pd->master; int lv; lv =sd->status.base_level*battle_config.pet_lv_rate/100; @@ -3157,6 +3157,8 @@ int status_calc_mercenary_(struct mercenary_data *md, bool first) status->sp = status->max_sp; md->battle_status.hp = merc->hp; md->battle_status.sp = merc->sp; + if (md->master) + status->speed = status_get_speed(&md->master->bl); } status_calc_misc(&md->bl, status, md->db->lv); @@ -3287,6 +3289,9 @@ int status_calc_elemental_(struct elemental_data *ed, bool first) { status->flee = ele->flee; status->hit = ele->hit; + if (ed->master) + status->speed = status_get_speed(&ed->master->bl); + memcpy(&ed->battle_status,status,sizeof(struct status_data)); } else { status_calc_misc(&ed->bl, status, 0); @@ -3807,7 +3812,7 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag) //Re-walk to adjust speed (we do not check if walktimer != INVALID_TIMER //because if you step on something while walking, the moment this //piece of code triggers the walk-timer is set on INVALID_TIMER) [Skotlex] - if (ud) + if (ud) ud->state.change_walk_target = ud->state.speed_changed = 1; if( bl->type&BL_PC && status->speed < battle_config.max_walk_speed ) @@ -3815,6 +3820,10 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag) if( bl->type&BL_HOM && battle_config.hom_setting&0x8 && ((TBL_HOM*)bl)->master) status->speed = status_get_speed(&((TBL_HOM*)bl)->master->bl); + if( bl->type&BL_MER && ((TBL_MER*)bl)->master) + status->speed = status_get_speed(&((TBL_MER*)bl)->master->bl); + if( bl->type&BL_ELEM && ((TBL_ELEM*)bl)->master) + status->speed = status_get_speed(&((TBL_ELEM*)bl)->master->bl); } @@ -5905,8 +5914,8 @@ int status_get_party_id(struct block_list *bl) { case BL_PC: return ((TBL_PC*)bl)->status.party_id; case BL_PET: - if (((TBL_PET*)bl)->msd) - return ((TBL_PET*)bl)->msd->status.party_id; + if (((TBL_PET*)bl)->master) + return ((TBL_PET*)bl)->master->status.party_id; break; case BL_MOB: { struct mob_data *md=(TBL_MOB*)bl; @@ -5942,8 +5951,8 @@ int status_get_guild_id(struct block_list *bl) { case BL_PC: return ((TBL_PC*)bl)->status.guild_id; case BL_PET: - if (((TBL_PET*)bl)->msd) - return ((TBL_PET*)bl)->msd->status.guild_id; + if (((TBL_PET*)bl)->master) + return ((TBL_PET*)bl)->master->status.guild_id; break; case BL_MOB: { struct map_session_data *msd; @@ -5982,8 +5991,8 @@ int status_get_emblem_id(struct block_list *bl) { case BL_PC: return ((TBL_PC*)bl)->guild_emblem_id; case BL_PET: - if (((TBL_PET*)bl)->msd) - return ((TBL_PET*)bl)->msd->guild_emblem_id; + if (((TBL_PET*)bl)->master) + return ((TBL_PET*)bl)->master->guild_emblem_id; break; case BL_MOB: { struct map_session_data *msd; @@ -7600,7 +7609,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty else val4 = (type == SC_DPOISON) ? 2 + status->max_hp/100 : 2 + status->max_hp/200; break; - + case SC_CONFUSION: clif_emotion(bl,E_WHAT); break; diff --git a/src/map/unit.c b/src/map/unit.c index 5c368f27cb..e83647d8bd 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -112,16 +112,92 @@ int unit_walktoxy_sub(struct block_list *bl) return 1; } -static int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data) -{ + + +TBL_PC* unit_get_master(struct block_list *bl){ + if(bl) + switch(bl->type){ + case BL_HOM : return (((TBL_HOM *)bl)->master); + case BL_ELEM : return (((TBL_ELEM *)bl)->master); + case BL_PET : return (((TBL_PET *)bl)->master); + case BL_MER : return (((TBL_MER *)bl)->master); + } + return NULL; +} + +int* unit_get_masterteleport_timer(struct block_list *bl){ + if(bl) + switch(bl->type){ + case BL_HOM: return &(((TBL_HOM *)bl)->masterteleport_timer); + case BL_ELEM: return &(((TBL_ELEM *)bl)->masterteleport_timer); + case BL_PET: return &(((TBL_PET *)bl)->masterteleport_timer); + case BL_MER: return &(((TBL_MER *)bl)->masterteleport_timer); + } + return NULL; +} + +int unit_teleport_timer(int tid, unsigned int tick, int id, intptr_t data){ + if(tid == INVALID_TIMER) + return 0; + else { + struct block_list *bl = map_id2bl(id); + int *mast_tid = unit_get_masterteleport_timer(bl); + TBL_PC *msd = unit_get_master(bl); + + switch(data){ + case BL_HOM: + case BL_ELEM: + case BL_PET : + case BL_MER : + if(msd && *mast_tid != INVALID_TIMER && !check_distance_bl(&msd->bl, bl, MAX_MER_DISTANCE)){ + *mast_tid = INVALID_TIMER; + unit_warp(bl, msd->bl.id, msd->bl.x, msd->bl.y, CLR_TELEPORT ); + } + break; + } + } + return 0; +} + +int unit_check_start_teleport_timer(struct block_list *sbl){ + TBL_PC *msd = unit_get_master(sbl); + int max_dist=AREA_SIZE; + switch(sbl->type){ + //case BL_HOM: max_dist = MAX_HOM_DISTANCE; break; + case BL_ELEM: max_dist = MAX_ELEDISTANCE; break; + //case BL_PET : max_dist = MAX_PET_DISTANCE; break; + case BL_MER : max_dist = MAX_MER_DISTANCE; break; + } + if(msd){ //if there is a master + int *msd_tid = unit_get_masterteleport_timer(sbl); + if(msd_tid == NULL) return 0; + + if (!check_distance_bl(&msd->bl, sbl, MAX_MER_DISTANCE)) { + if(*msd_tid == INVALID_TIMER) + *msd_tid = add_timer(gettick()+3000,unit_teleport_timer,sbl->id,BL_MER); + } + else { + if(*msd_tid != INVALID_TIMER) + delete_timer(*msd_tid,unit_teleport_timer); + *msd_tid = INVALID_TIMER; //cancel recall + } + } + return 0; +} + +static int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data){ int i; int x,y,dx,dy; uint8 dir; struct block_list *bl; - struct map_session_data *sd; - struct mob_data *md; struct unit_data *ud; - struct mercenary_data *mrd; + TBL_PC *sd; + TBL_MOB *md; + TBL_MER *mrd; + TBL_ELEM *ed; + TBL_PET *pd; + TBL_HOM *hd; + bl = map_id2bl(id); if(bl == NULL) @@ -129,6 +205,9 @@ static int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data sd = BL_CAST(BL_PC, bl); md = BL_CAST(BL_MOB, bl); mrd = BL_CAST(BL_MER, bl); + ed = BL_CAST(BL_ELEM, bl); + pd = BL_CAST(BL_PET, bl); + hd = BL_CAST(BL_HOM, bl); ud = unit_bl2ud(bl); if(ud == NULL) return 0; @@ -174,6 +253,7 @@ static int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data ud->walktimer = INVALID_TIMER; if(sd) { + struct block_list *sbl; //slave bl if( sd->touching_id ) npc_touchnext_areanpc(sd,false); if(map_getcell(bl->m,x,y,CELL_CHKNPC)) { @@ -183,24 +263,10 @@ static int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data } else sd->areanpc_id=0; - if( sd->md && !check_distance_bl(&sd->bl, &sd->md->bl, MAX_MER_DISTANCE) ) - { - // mercenary should be warped after being 3 seconds too far from the master [greenbox] - if (sd->md->masterteleport_timer == 0) - { - sd->md->masterteleport_timer = gettick(); - } - else if (DIFF_TICK(gettick(), sd->md->masterteleport_timer) > 3000) - { - sd->md->masterteleport_timer = 0; - unit_warp( &sd->md->bl, sd->bl.m, sd->bl.x, sd->bl.y, CLR_TELEPORT ); - } - } - else if( sd->md ) - { - // reset the tick, he is not far anymore - sd->md->masterteleport_timer = 0; - } + if( sd->md) unit_check_start_teleport_timer(&sd->md->bl); + if( sd->ed) unit_check_start_teleport_timer(&sd->ed->bl); + if( sd->hd) unit_check_start_teleport_timer(&sd->hd->bl); + if( sd->pd) unit_check_start_teleport_timer(&sd->pd->bl); } else if (md) { if( map_getcell(bl->m,x,y,CELL_CHKNPC) ) { if( npc_touch_areanpc2(md) ) return 0; // Warped @@ -212,7 +278,7 @@ static int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data if(tid != INVALID_TIMER && !(ud->walk_count%WALK_SKILL_INTERVAL) && mobskill_use(md, tick, -1)) - { + { if (!(ud->skill_id == NPC_SELFDESTRUCTION && ud->skilltimer != INVALID_TIMER)) { //Skill used, abort walking clif_fixpos(bl); //Fix position as walk has been cancelled. @@ -222,26 +288,10 @@ static int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data clif_move(ud); } } - else if( mrd && mrd->master ) - { - if (!check_distance_bl(&mrd->master->bl, bl, MAX_MER_DISTANCE)) - { - // mercenary should be warped after being 3 seconds too far from the master [greenbox] - if (mrd->masterteleport_timer == 0) - { - mrd->masterteleport_timer = gettick(); - } - else if (DIFF_TICK(gettick(), mrd->masterteleport_timer) > 3000) - { - mrd->masterteleport_timer = 0; - unit_warp( bl, mrd->master->bl.id, mrd->master->bl.x, mrd->master->bl.y, CLR_TELEPORT ); - } - } - else - { - mrd->masterteleport_timer = 0; - } - } + else if( hd) unit_check_start_teleport_timer(&hd->bl); + else if( ed) unit_check_start_teleport_timer(&ed->bl); + else if( pd) unit_check_start_teleport_timer(&pd->bl); + else if( mrd) unit_check_start_teleport_timer(&mrd->bl); if(tid == INVALID_TIMER) //A directly invoked timer is from battle_stop_walking, therefore the rest is irrelevant. return 0; @@ -798,7 +848,7 @@ int unit_warp(struct block_list *bl,short m,short x,short y,clr_type type) } if (x<0 || y<0) - { //Random map position. + { //Random map position. if (!map_search_freecell(NULL, m, &x, &y, -1, -1, 1)) { ShowWarning("unit_warp failed. Unit Id:%d/Type:%d, target position map %d (%s) at [%d,%d]\n", bl->id, bl->type, m, map[m].name, x, y); return 2; @@ -809,7 +859,7 @@ int unit_warp(struct block_list *bl,short m,short x,short y,clr_type type) ShowWarning("unit_warp: Specified non-walkable target cell: %d (%s) at [%d,%d]\n", m, map[m].name, x,y); if (!map_search_freecell(NULL, m, &x, &y, 4, 4, 1)) - { //Can't find a nearby cell + { //Can't find a nearby cell ShowWarning("unit_warp failed. Unit Id:%d/Type:%d, target position map %d (%s) at [%d,%d]\n", bl->id, bl->type, m, map[m].name, x, y); return 2; } @@ -2187,7 +2237,7 @@ int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char* file, } case BL_PET: { struct pet_data *pd = (struct pet_data*)bl; - if( pd->pet.intimate <= 0 && !(pd->msd && !pd->msd->state.active) ) + if( pd->pet.intimate <= 0 && !(pd->master && !pd->master->state.active) ) { //If logging out, this is deleted on unit_free clif_clearunit_area(bl,clrtype); map_delblock(bl); @@ -2350,7 +2400,7 @@ int unit_free(struct block_list *bl, clr_type clrtype) case BL_PET: { struct pet_data *pd = (struct pet_data*)bl; - struct map_session_data *sd = pd->msd; + struct map_session_data *sd = pd->master; pet_hungry_timer_delete(pd); if( pd->a_skill ) { @@ -2528,6 +2578,7 @@ int do_init_unit(void) add_timer_func_list(unit_walktobl_sub, "unit_walktobl_sub"); add_timer_func_list(unit_delay_walktoxy_timer,"unit_delay_walktoxy_timer"); add_timer_func_list(unit_delay_walktobl_timer,"unit_delay_walktobl_timer"); + add_timer_func_list(unit_teleport_timer,"unit_teleport_timer"); return 0; }