-Update Char_Client packet 2013+, thx (Yommy, Shaktoh)
--change connection sequence for 82d+9a0+20d => 9a1 => 99d -Merge some Hercules stuffs: --upd char (default map check, 0x99d HC) --CreateParty enforced chk --mapindex_db for name lookup -Add max packet_len check on chrif init for mmo_charstatus. -Upd @mapinfo, add missing mapflag info. -Expand teleport_timer for pet,homon,ele (Daegaladh) -Make homon,ele inherit master speed (Daegaladh) -Fix frostnova status chance and driven fail msg. (Daegaladh) -Cleanup, replace hardcoded ai value with enum eq, change pet.msd to pet.master to harmonize with other blchar. git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@17332 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
parent
54f41e69bc
commit
38f9f0c208
@ -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> <map>).
|
||||
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> <map>).
|
||||
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.
|
||||
|
160
src/char/char.c
160
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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -177,6 +177,7 @@ typedef unsigned long int ppuint32;
|
||||
// integer with exact processor width (and best speed)
|
||||
//////////////////////////////
|
||||
#include <stddef.h> // size_t
|
||||
//#include <stdbool.h> //boolean
|
||||
|
||||
#if defined(WIN32) && !defined(MINGW) // does not have a signed size_t
|
||||
//////////////////////////////
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -5,12 +5,14 @@
|
||||
#include "../common/showmsg.h"
|
||||
#include "../common/malloc.h"
|
||||
#include "../common/strlib.h"
|
||||
#include "../common/db.h"
|
||||
#include "mapindex.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
DBMap *mapindex_db;
|
||||
struct _indexes {
|
||||
char name[MAP_NAME_LENGTH]; //Stores map name
|
||||
} indexes[MAX_MAPINDEX];
|
||||
@ -23,8 +25,7 @@ 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;
|
||||
|
||||
@ -45,8 +46,7 @@ const char* mapindex_getmapname(const char* string, char* output)
|
||||
|
||||
/// 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;
|
||||
|
||||
@ -75,13 +75,11 @@ const char* mapindex_getmapname_ext(const char* string, char* output)
|
||||
|
||||
/// 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];
|
||||
char map_name[MAP_NAME_LENGTH];
|
||||
|
||||
memset (&indexes, 0, sizeof (indexes));
|
||||
fp=fopen(mapindex_cfgfile,"r");
|
||||
if(fp==NULL){
|
||||
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);
|
||||
}
|
||||
|
@ -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*);
|
||||
|
@ -1163,7 +1163,7 @@ void socket_final(void)
|
||||
if(session[i])
|
||||
do_close(i);
|
||||
|
||||
// session[0] <20>̃_<CC83>~<7E>[<5B>f<EFBFBD>[<5B>^<5E><><EFBFBD>폜
|
||||
// session[0]
|
||||
aFree(session[0]->rdata);
|
||||
aFree(session[0]->wdata);
|
||||
aFree(session[0]);
|
||||
|
@ -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);
|
||||
@ -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> <map>).
|
||||
clif_displaymessage(fd, msg_txt(sd,488)); // Please enter at least one valid list number (usage: @mapinfo <0-3> <map>).
|
||||
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);
|
||||
|
@ -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.
|
||||
|
@ -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:
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 <account id>.L <char name>.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;
|
||||
}
|
||||
|
@ -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_ */
|
||||
|
@ -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
|
||||
|
||||
//[(Caster’s Max HP/ 3 ) + (Caster’s INT x 10 )+ (Caster’s Job Level x 20 )] x [(Elemental Summon Level + 2) / 3]
|
||||
//[(Caster<EFBFBD>s Max HP/ 3 ) + (Caster<65>s INT x 10 )+ (Caster<65>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);
|
||||
//Caster’s Max SP /4
|
||||
//Caster<EFBFBD>s Max SP /4
|
||||
ele.sp = ele.max_sp = sd->battle_status.max_sp/4;
|
||||
//Caster’s [ Max SP / (18 / Elemental Summon Skill Level) 1- 100 ]
|
||||
//Caster<EFBFBD>s [ Max SP / (18 / Elemental Summon Skill Level) 1- 100 ]
|
||||
ele.atk = (sd->battle_status.max_sp / (18 / i) * 1 - 100);
|
||||
//Caster’s [ Max SP / (18 / Elemental Summon Skill Level) ]
|
||||
//Caster<EFBFBD>s [ Max SP / (18 / Elemental Summon Skill Level) ]
|
||||
ele.atk2 = sd->battle_status.max_sp / 18;
|
||||
//Caster’s HIT + (Caster’s Base Level )
|
||||
//Caster<EFBFBD>s HIT + (Caster<65>s Base Level )
|
||||
ele.hit = sd->battle_status.hit + sd->status.base_level;
|
||||
//[Elemental Summon Skill Level x (Caster’s INT / 2 + Caster’s DEX / 4)]
|
||||
//[Elemental Summon Skill Level x (Caster<EFBFBD>s INT / 2 + Caster<65>s DEX / 4)]
|
||||
ele.matk = i * (sd->battle_status.int_ / 2 + sd->battle_status.dex / 4);
|
||||
//150 + [Caster’s DEX / 10] + [Elemental Summon Skill Level x 3 ]
|
||||
//150 + [Caster<EFBFBD>s DEX / 10] + [Elemental Summon Skill Level x 3 ]
|
||||
ele.amotion = 150 + sd->battle_status.dex / 10 + i * 3;
|
||||
//Caster’s DEF + (Caster’s Base Level / (5 – Elemental Summon Skill Level)
|
||||
//Caster<EFBFBD>s DEF + (Caster<65>s Base Level / (5 <20> Elemental Summon Skill Level)
|
||||
ele.def = sd->battle_status.def + sd->status.base_level / (5-i);
|
||||
//Caster’s MDEF + (Caster’s INT / (5 - Elemental Summon Skill Level)
|
||||
//Caster<EFBFBD>s MDEF + (Caster<65>s INT / (5 - Elemental Summon Skill Level)
|
||||
ele.mdef = sd->battle_status.mdef + sd->battle_status.int_ / (5-i);
|
||||
//Caster’s FLEE + (Caster’s Base Level / (5 – Elemental Summon Skill Level)
|
||||
//Caster<EFBFBD>s FLEE + (Caster<65>s Base Level / (5 <20> Elemental Summon Skill Level)
|
||||
ele.flee = sd->status.base_level / (5-i);
|
||||
//Caster’s HIT + (Caster’s Base Level )
|
||||
//Caster<EFBFBD>s HIT + (Caster<65>s Base Level )
|
||||
ele.hit = sd->battle_status.hit + sd->status.base_level;
|
||||
|
||||
//per individual bonuses
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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_) )
|
||||
|
@ -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 {
|
||||
|
@ -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) {
|
||||
|
13
src/map/pc.c
13
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;
|
||||
|
@ -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) &&
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
147
src/map/unit.c
147
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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user