From f6bcd12cd633717e9e503bb453c85955e29cd519 Mon Sep 17 00:00:00 2001 From: ultramage Date: Wed, 23 May 2007 21:23:36 +0000 Subject: - Added new flag to skill_castnodex.txt, to allow per-skill tweaking of cast time and delay reducibility by item scripts (cards and such) - Fixed Martyr's Reckoning never triggering for gms with all skills - Added MO_TRIPLEATTACK and RG_SNATCHER to @skillall's skill filter - Made gm_skill_unconditional bypass skill blocking (guild timer, etc) - Reverted the weird delay_dependon_agi thing (r8923, r9055, r9059) - Changed a few memsets to strncpy (reading past buffer is a bad idea) - Sped up some memset operations (multiples of 4 are faster) git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@10613 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/char/char.c | 37 +++++++++++++++++---------------- src/char/int_guild.c | 22 ++++++++++---------- src/char/int_homun.c | 2 +- src/char/int_party.c | 2 +- src/char/int_pet.c | 4 ++-- src/char_sql/char.c | 54 ++++++++++++++++++++++++------------------------ src/char_sql/int_guild.c | 9 +++----- src/char_sql/int_homun.c | 2 +- src/char_sql/int_party.c | 5 +---- src/char_sql/int_pet.c | 11 ++++------ src/login_sql/login.c | 2 +- src/map/battle.c | 17 ++++++++------- src/map/battle.h | 2 +- src/map/charcommand.c | 2 +- src/map/chrif.c | 2 +- src/map/clif.c | 2 +- src/map/guild.c | 12 +++++------ src/map/map.c | 2 +- src/map/mob.c | 12 +++++------ src/map/npc.c | 16 +++++++------- src/map/pc.c | 4 ++-- src/map/pet.c | 6 +++--- src/map/script.c | 6 +++--- src/map/skill.c | 47 ++++++++++++++++++++--------------------- src/map/skill.h | 3 +-- src/map/unit.c | 5 +++-- 26 files changed, 142 insertions(+), 146 deletions(-) (limited to 'src') diff --git a/src/char/char.c b/src/char/char.c index f1476bbb3..d5b4bbb37 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -43,7 +43,7 @@ #include #ifndef TXT_SQL_CONVERT -struct mmo_map_server{ +struct mmo_map_server { uint32 ip; uint16 port; int users; @@ -57,16 +57,16 @@ char passwd[24]; char server_name[20]; char wisp_server_name[NAME_LENGTH] = "Server"; char login_ip_str[128]; -uint32 login_ip; +uint32 login_ip = 0; uint16 login_port = 6900; char char_ip_str[128]; -uint32 char_ip; +uint32 char_ip = 0; char bind_ip_str[128]; uint32 bind_ip = INADDR_ANY; uint16 char_port = 6121; -int char_maintenance; -int char_new; -int char_new_display; +int char_maintenance = 0; +int char_new = 1; +int char_new_display = 0; int email_creation = 0; // disabled by default #endif char char_txt[1024]="save/athena.txt"; @@ -364,7 +364,7 @@ void set_char_offline(int char_id, int account_id) character->waiting_disconnect = -1; } } - + if (login_fd > 0 && !session[login_fd]->eof) { WFIFOHEAD(login_fd,6); @@ -652,7 +652,7 @@ int mmo_char_fromstr(char *str, struct mmo_charstatus *p, struct global_reg *reg tmp_int[46] = mapindex_name2id(tmp_str[2]); } // Char structure of version 1500 (homun + mapindex maps) - memcpy(p->name, tmp_str[0], NAME_LENGTH-1); //Overflow protection [Skotlex] + memcpy(p->name, tmp_str[0], NAME_LENGTH); //Overflow protection [Skotlex] p->char_id = tmp_int[0]; p->account_id = tmp_int[1]; p->char_num = tmp_int[2]; @@ -1946,7 +1946,7 @@ int parse_tologin(int fd) struct char_session_data *sd; // only login-server can have an access to here. - // so, if it isn't the login-server, we disconnect the session (fd != login_fd). + // so, if it isn't the login-server, we disconnect the session. if (fd != login_fd) set_eof(fd); if(session[fd]->eof) { @@ -2360,7 +2360,7 @@ int parse_tologin(int fd) if (GM_num == 0) { gm_account = (struct gm_account*)aMalloc(sizeof(struct gm_account)); } else { - gm_account = (struct gm_account*)aRealloc(gm_account, sizeof(struct gm_account) * (GM_num + 1)); + gm_account = (struct gm_account*)aRealloc(gm_account, sizeof(struct gm_account) * (GM_num + 1)); } gm_account[GM_num].account_id = RFIFOL(fd,2); gm_account[GM_num].level = (int)RFIFOB(fd,6); @@ -3005,7 +3005,7 @@ int parse_frommap(int fd) { char character_name[NAME_LENGTH]; int acc = RFIFOL(fd,2); // account_id of who ask (-1 if nobody) - memcpy(character_name, RFIFOP(fd,6), NAME_LENGTH-1); + memcpy(character_name, RFIFOP(fd,6), NAME_LENGTH); character_name[NAME_LENGTH-1] = '\0'; // prepare answer WFIFOHEAD(fd,34); @@ -3155,7 +3155,7 @@ int parse_frommap(int fd) // Find the position where the player has to be inserted for(i = 0; i < size && fame < list[i].fame; i++); - if(i >= size) break;//Out of ranking. + if(i >= size) break; //Out of ranking. // When found someone with less or as much fame, insert just above memmove(list+i+1, list+i, (size-i-1) * sizeof(struct fame_list)); list[i].id = cid; @@ -3190,7 +3190,7 @@ int parse_frommap(int fd) set_all_offline(id); RFIFOSKIP(fd,2); break; - + case 0x2b19: // Character set online [Wizputer] if (RFIFOREST(fd) < 6) return 0; @@ -3239,8 +3239,8 @@ int parse_frommap(int fd) break; default: - // inter server - packet { + // inter server - packet int r = inter_parse_frommap(fd); if (r == 1) break; // processed if (r == 2) return 0; // need more packet @@ -3252,6 +3252,7 @@ int parse_frommap(int fd) } } // switch } // while + return 0; } @@ -3566,7 +3567,7 @@ int parse_char(int fd) if (i < 0) { WFIFOHEAD(fd,3); - WFIFOW(fd, 0) = 0x6e; + WFIFOW(fd,0) = 0x6e; switch (i) { case -1: WFIFOB(fd,2) = 0x00; break; case -2: WFIFOB(fd,2) = 0x02; break; @@ -3891,7 +3892,7 @@ static int send_accounts_tologin_sub(DBKey key, void* data, va_list ap) return 0; //This is an error that shouldn't happen.... if(character->server > -1) { WFIFOHEAD(login_fd,8+count*4); - WFIFOL(login_fd, 8+(*i)*4) =character->account_id; + WFIFOL(login_fd,8+(*i)*4) = character->account_id; (*i)++; return 1; } @@ -3939,7 +3940,7 @@ int check_connect_login_server(int tid, unsigned int tick, int id, int data) memcpy(WFIFOP(login_fd,60), server_name, 20); WFIFOW(login_fd,80) = 0; WFIFOW(login_fd,82) = char_maintenance; - WFIFOW(login_fd,84) = char_new_display; //only display (New) if they want to [Kevin] + WFIFOW(login_fd,84) = char_new_display; //only display (New) if they want to [Kevin] WFIFOSET(login_fd,86); return 1; @@ -4206,7 +4207,7 @@ int char_config_read(const char *cfgName) } fclose(fp); - ShowInfo("done reading %s.\n", cfgName); + ShowInfo("Done reading %s.\n", cfgName); return 0; } diff --git a/src/char/int_guild.c b/src/char/int_guild.c index 14297712f..2cf8b8b91 100644 --- a/src/char/int_guild.c +++ b/src/char/int_guild.c @@ -123,8 +123,8 @@ int inter_guild_fromstr(char *str, struct guild *g) { #ifndef TXT_SQL_CONVERT g->castle_id = tmp_int[5]; #endif - memcpy(g->name, tmp_str[0], NAME_LENGTH-1); - memcpy(g->master, tmp_str[1], NAME_LENGTH-1); + memcpy(g->name, tmp_str[0], NAME_LENGTH); + memcpy(g->master, tmp_str[1], NAME_LENGTH); memcpy(g->mes1, tmp_str[2], 60); memcpy(g->mes2, tmp_str[3], 120); g->mes1[strlen(g->mes1)-1] = 0; @@ -152,7 +152,7 @@ int inter_guild_fromstr(char *str, struct guild *g) { m->exp = exp; m->exp_payper = tmp_int[8]; m->position = tmp_int[9]; - memcpy(m->name, tmp_str[0], NAME_LENGTH-1); + memcpy(m->name, tmp_str[0], NAME_LENGTH); for(j = 0; j < 2 && str != NULL; j++) // 位置スキップ str = strchr(str + 1, '\t'); @@ -167,7 +167,7 @@ int inter_guild_fromstr(char *str, struct guild *g) { p->mode = tmp_int[0]; p->exp_mode = tmp_int[1]; tmp_str[0][strlen(tmp_str[0])-1] = 0; - memcpy(p->name, tmp_str[0], NAME_LENGTH-1); + memcpy(p->name, tmp_str[0], NAME_LENGTH); for(j = 0; j < 2 && str != NULL; j++) // 位置スキップ str = strchr(str+1, '\t'); @@ -204,7 +204,7 @@ int inter_guild_fromstr(char *str, struct guild *g) { return 1; a->guild_id = tmp_int[0]; a->opposition = tmp_int[1]; - memcpy(a->name, tmp_str[0], NAME_LENGTH-1); + memcpy(a->name, tmp_str[0], NAME_LENGTH); for(j = 0; j < 2 && str != NULL; j++) // 位置スキップ str = strchr(str + 1, '\t'); @@ -224,7 +224,7 @@ int inter_guild_fromstr(char *str, struct guild *g) { e->rsv1 = tmp_int[1]; e->rsv2 = tmp_int[2]; e->rsv3 = tmp_int[3]; - memcpy(e->name, tmp_str[0], NAME_LENGTH-1); + memcpy(e->name, tmp_str[0], NAME_LENGTH); memcpy(e->acc, tmp_str[1], 24); tmp_str[2][strlen(tmp_str[2])-1] = 0; memcpy(e->mes, tmp_str[2], 40); @@ -980,8 +980,8 @@ int mapif_parse_CreateGuild(int fd, int account_id, char *name, struct guild_mem } // memset(g, 0, sizeof(struct guild)); Meh... g->guild_id = guild_newid++; - memcpy(g->name, name, NAME_LENGTH-1); - memcpy(g->master, master->name, NAME_LENGTH-1); + memcpy(g->name, name, NAME_LENGTH); + memcpy(g->master, master->name, NAME_LENGTH); memcpy(&g->member[0], master, sizeof(struct guild_member)); g->position[0].mode = 0x11; @@ -1071,8 +1071,8 @@ int mapif_parse_GuildLeave(int fd, int guild_id, int account_id, int char_id, in j = MAX_GUILDEXPULSION - 1; } g->expulsion[j].account_id = account_id; - memcpy(g->expulsion[j].acc, "dummy", NAME_LENGTH-1); - memcpy(g->expulsion[j].name, g->member[i].name, NAME_LENGTH-1); + strncpy(g->expulsion[j].acc, "dummy", NAME_LENGTH); + memcpy(g->expulsion[j].name, g->member[i].name, NAME_LENGTH); memcpy(g->expulsion[j].mes, mes, 40); } @@ -1344,7 +1344,7 @@ int mapif_parse_GuildAlliance(int fd, int guild_id1, int guild_id2, int account_ for(j = 0; j < MAX_GUILDALLIANCE; j++) if (g[i]->alliance[j].guild_id == 0) { g[i]->alliance[j].guild_id = g[1-i]->guild_id; - memcpy(g[i]->alliance[j].name, g[1-i]->name, NAME_LENGTH-1); + memcpy(g[i]->alliance[j].name, g[1-i]->name, NAME_LENGTH); g[i]->alliance[j].opposition = flag & 1; break; } diff --git a/src/char/int_homun.c b/src/char/int_homun.c index 492d8a76e..43d56359d 100644 --- a/src/char/int_homun.c +++ b/src/char/int_homun.c @@ -68,7 +68,7 @@ int inter_homun_fromstr(char *str,struct s_homunculus *p) p->hom_id = tmp_int[0]; p->class_ = tmp_int[1]; - memcpy(p->name, tmp_str, NAME_LENGTH-1); + memcpy(p->name, tmp_str, NAME_LENGTH); p->char_id = tmp_int[2]; p->hp = tmp_int[3]; diff --git a/src/char/int_party.c b/src/char/int_party.c index 50a33295b..2c18f29ab 100644 --- a/src/char/int_party.c +++ b/src/char/int_party.c @@ -132,7 +132,7 @@ int inter_party_fromstr(char *str, struct party *p) { return 1; p->party_id = tmp_int[0]; - memcpy(p->name, tmp_str, NAME_LENGTH-1); + memcpy(p->name, tmp_str, NAME_LENGTH); p->exp = tmp_int[1]?1:0; p->item = tmp_int[2]; // printf("%d [%s] %d %d\n", tmp_int[0], tmp_str[0], tmp_int[1], tmp_int[2]); diff --git a/src/char/int_pet.c b/src/char/int_pet.c index c49150a9c..4eb3f5b49 100644 --- a/src/char/int_pet.c +++ b/src/char/int_pet.c @@ -58,7 +58,7 @@ int inter_pet_fromstr(char *str,struct s_pet *p) p->pet_id = tmp_int[0]; p->class_ = tmp_int[1]; - memcpy(p->name,tmp_str,NAME_LENGTH-1); + memcpy(p->name,tmp_str,NAME_LENGTH); p->account_id = tmp_int[2]; p->char_id = tmp_int[3]; p->level = tmp_int[4]; @@ -234,7 +234,7 @@ int mapif_create_pet(int fd,int account_id,int char_id,short pet_class,short pet } // memset(p,0,sizeof(struct s_pet)); unnecessary after aCalloc [Skotlex] p->pet_id = pet_newid++; - memcpy(p->name,pet_name,NAME_LENGTH-1); + memcpy(p->name,pet_name,NAME_LENGTH); if(incuvate == 1) p->account_id = p->char_id = 0; else { diff --git a/src/char_sql/char.c b/src/char_sql/char.c index eeca0209f..a1fdc8835 100644 --- a/src/char_sql/char.c +++ b/src/char_sql/char.c @@ -70,13 +70,12 @@ int lowest_gm_level = 1; char *SQL_CONF_NAME = "conf/inter_athena.conf"; -struct mmo_map_server{ - uint32 ip; - uint16 port; - int users; - unsigned short map[MAX_MAP_PER_SERVER]; +struct mmo_map_server { + uint32 ip; + uint16 port; + int users; + unsigned short map[MAX_MAP_PER_SERVER]; } server[MAX_MAP_SERVERS]; - int server_fd[MAX_MAP_SERVERS]; int login_fd, char_fd; @@ -93,10 +92,11 @@ char bind_ip_str[128]; uint32 bind_ip = INADDR_ANY; uint16 char_port = 6121; int char_maintenance = 0; -int char_new; -int char_new_display; +int char_new = 1; +int char_new_display = 0; int name_ignoring_case = 0; // Allow or not identical name for characters but with a different case by [Yor] int char_name_option = 0; // Option to know which letters/symbols are authorised in the name of a character (0: all, 1: only those in char_name_letters, 2: all EXCEPT those in char_name_letters) by [Yor] +char unknown_char_name[NAME_LENGTH] = "Unknown"; char char_name_letters[1024] = ""; // list of letters/symbols used to authorise or not a name of a character. by [Yor] //The following are characters that are trimmed regardless because they cause confusion and problems on the servers. [Skotlex] #define TRIM_CHARS "\032\t\x0A\x0D " @@ -116,7 +116,6 @@ struct _subnet { int subnet_count = 0; -char unknown_char_name[NAME_LENGTH] = "Unknown"; char db_path[1024]="db"; //These are used to aid the map server in identifying valid clients. [Skotlex] @@ -185,8 +184,6 @@ struct online_char_data { struct dbt *online_char_db; //Holds all online characters. -static int chardb_waiting_disconnect(int tid, unsigned int tick, int id, int data); - static void * create_online_char_data(DBKey key, va_list args) { struct online_char_data* character; @@ -199,6 +196,8 @@ static void * create_online_char_data(DBKey key, va_list args) return character; } +static int chardb_waiting_disconnect(int tid, unsigned int tick, int id, int data); + //------------------------------------------------- // Set Character online/offline [Wizputer] //------------------------------------------------- @@ -206,7 +205,7 @@ static void * create_online_char_data(DBKey key, va_list args) void set_char_online(int map_id, int char_id, int account_id) { struct online_char_data* character; - + if ( char_id != 99 ) { sprintf(tmp_sql, "UPDATE `%s` SET `online`='1' WHERE `char_id`='%d'",char_db,char_id); if (mysql_query(&mysql_handle, tmp_sql)) { @@ -1732,7 +1731,6 @@ int parse_tologin(int fd) struct char_session_data *sd; // only login-server can have an access to here. // so, if it isn't the login-server, we disconnect the session. - //session eof check! if(fd != login_fd) set_eof(fd); if(session[fd]->eof) { @@ -2597,7 +2595,7 @@ int parse_frommap(int fd) auth_fifo_pos++; WFIFOHEAD(fd,7); WFIFOW(fd,0) = 0x2b03; - WFIFOL(fd,2) = RFIFOL(fd, 2); + WFIFOL(fd,2) = RFIFOL(fd,2); WFIFOB(fd,6) = 0; WFIFOSET(fd,7); RFIFOSKIP(fd,18); @@ -2968,8 +2966,8 @@ int parse_frommap(int fd) break; default: - // inter server - packet { + // inter server - packet int r = inter_parse_frommap(fd); if (r == 1) break; // processed if (r == 2) return 0; // need more packet @@ -2981,6 +2979,7 @@ int parse_frommap(int fd) } } // switch } // while + return 0; } @@ -3223,7 +3222,7 @@ int parse_char(int fd) char_dat.last_point.map = j; } { - //Send player to map. + //Send player to map uint32 subnet_map_ip; char map_name[MAP_NAME_LENGTH_EXT]; snprintf(map_name, MAP_NAME_LENGTH_EXT, "%s.gat", mapindex_id2name(char_dat.last_point.map)); @@ -3252,11 +3251,11 @@ int parse_char(int fd) //Send NEW auth packet [Kevin] if ((map_fd = server_fd[i]) < 1 || session[map_fd] == NULL) { - WFIFOHEAD(fd,3); ShowError("parse_char: Attempting to write to invalid session %d! Map Server #%d disconnected.\n", map_fd, i); server_fd[i] = -1; memset(&server[i], 0, sizeof(struct mmo_map_server)); //Send server closed. + WFIFOHEAD(fd,3); WFIFOW(fd,0) = 0x81; WFIFOB(fd,2) = 1; // 01 = Server closed WFIFOSET(fd,3); @@ -3276,7 +3275,7 @@ int parse_char(int fd) set_char_online(i, auth_fifo[auth_fifo_pos].char_id, auth_fifo[auth_fifo_pos].account_id); auth_fifo_pos++; - break; + break; case 0x67: // make new FIFOSD_CHECK(37); @@ -3317,7 +3316,7 @@ int parse_char(int fd) break; } } - break; + break; case 0x68: // delete char FIFOSD_CHECK(46); @@ -3394,8 +3393,8 @@ int parse_char(int fd) /* Char successfully deleted.*/ WFIFOW(fd,0) = 0x6f; WFIFOSET(fd,2); - break; } + break; case 0x2af8: // login as map-server if (RFIFOREST(fd) < 60) @@ -3441,14 +3440,14 @@ int parse_char(int fd) WFIFOW(fd,2) = len; WFIFOSET(fd,len); } - break; } + break; case 0x187: // Alive? if (RFIFOREST(fd) < 6) return 0; RFIFOSKIP(fd, 6); - break; + break; case 0x7530: // Athena info get { @@ -3465,6 +3464,7 @@ int parse_char(int fd) RFIFOSKIP(fd,2); return 0; } + case 0x7532: // disconnect(default also disconnect) default: set_eof(fd); @@ -3588,7 +3588,7 @@ static int send_accounts_tologin_sub(DBKey key, void* data, va_list ap) return 0; //This is an error that shouldn't happen.... if(character->server > -1) { WFIFOHEAD(login_fd,8+count*4); - WFIFOL(login_fd,8+(*i)*4) =character->account_id; + WFIFOL(login_fd,8+(*i)*4) = character->account_id; (*i)++; return 1; } @@ -3613,7 +3613,7 @@ int send_accounts_tologin(int tid, unsigned int tick, int id, int data) int check_connect_login_server(int tid, unsigned int tick, int id, int data) { - if (login_fd > 0 && session[login_fd] != NULL) + if (login_fd > 0 && session[login_fd] != NULL) return 0; ShowInfo("Attempt to connect to login-server...\n"); @@ -3811,7 +3811,7 @@ void sql_config_read(const char *cfgName) } fclose(fp); - ShowInfo("done reading %s.\n", cfgName); + ShowInfo("Done reading %s.\n", cfgName); } #ifndef TXT_SQL_CONVERT @@ -4098,11 +4098,11 @@ int do_init(int argc, char **argv) ShowStatus("Defaulting to %s as our IP address\n", ip_str); if (!login_ip) { strcpy(login_ip_str, ip_str); - login_ip = ntohl(inet_addr(login_ip_str)); + login_ip = str2ip(login_ip_str); } if (!char_ip) { strcpy(char_ip_str, ip_str); - char_ip = ntohl(inet_addr(char_ip_str)); + char_ip = str2ip(char_ip_str); } } diff --git a/src/char_sql/int_guild.c b/src/char_sql/int_guild.c index 4bbe15b0c..3ecaec839 100644 --- a/src/char_sql/int_guild.c +++ b/src/char_sql/int_guild.c @@ -1,9 +1,6 @@ // Copyright (c) Athena Dev Teams - Licensed under GNU GPL // For more information, see LICENCE in the main folder -// original code from athena -// SQL conversion by hack - #include #include #include @@ -1439,8 +1436,8 @@ int mapif_parse_GuildLeave(int fd,int guild_id,int account_id,int char_id,int fl } // Save the expulsion g->expulsion[j].account_id=account_id; - memcpy(g->expulsion[j].acc,"dummy",NAME_LENGTH-1); - memcpy(g->expulsion[j].name,g->member[i].name,NAME_LENGTH-1); + strncpy(g->expulsion[j].acc,"dummy",NAME_LENGTH); + memcpy(g->expulsion[j].name,g->member[i].name,NAME_LENGTH); memcpy(g->expulsion[j].mes,mes,40); } @@ -1860,7 +1857,7 @@ int mapif_parse_GuildAlliance(int fd,int guild_id1,int guild_id2, if(g[i]->alliance[j].guild_id==0) { g[i]->alliance[j].guild_id=g[1-i]->guild_id; - memcpy(g[i]->alliance[j].name,g[1-i]->name,NAME_LENGTH-1); + memcpy(g[i]->alliance[j].name,g[1-i]->name,NAME_LENGTH); // Set alliance type g[i]->alliance[j].opposition = flag&GUILD_ALLIANCE_TYPE_MASK; break; diff --git a/src/char_sql/int_homun.c b/src/char_sql/int_homun.c index acee4f823..42f4ef225 100644 --- a/src/char_sql/int_homun.c +++ b/src/char_sql/int_homun.c @@ -147,7 +147,7 @@ int mapif_load_homunculus(int fd){ homun_pt->hom_id = RFIFOL(fd,6) ; //RFIFOL(fd,2); homun_pt->class_ = atoi(sql_row[2]); - memcpy(homun_pt->name, sql_row[3],NAME_LENGTH-1); + strncpy(homun_pt->name, sql_row[3], NAME_LENGTH); homun_pt->char_id = atoi(sql_row[1]); homun_pt->level = atoi(sql_row[4]); homun_pt->exp = atoi(sql_row[5]); diff --git a/src/char_sql/int_party.c b/src/char_sql/int_party.c index 181050e4e..3f3a88de1 100644 --- a/src/char_sql/int_party.c +++ b/src/char_sql/int_party.c @@ -1,9 +1,6 @@ // Copyright (c) Athena Dev Teams - Licensed under GNU GPL // For more information, see LICENCE in the main folder -// original code from athena -// SQL conversion by hack - #include #include #include @@ -247,7 +244,7 @@ struct party_data *inter_party_fromsql(int party_id) return NULL; } p->party.party_id = party_id; - memcpy(&p->party.name, sql_row[1], NAME_LENGTH-1); + strncpy(&p->party.name, sql_row[1], NAME_LENGTH); p->party.exp = atoi(sql_row[2])?1:0; p->party.item = atoi(sql_row[3]); leader_id = atoi(sql_row[4]); diff --git a/src/char_sql/int_pet.c b/src/char_sql/int_pet.c index 3f6406be5..6352412ce 100644 --- a/src/char_sql/int_pet.c +++ b/src/char_sql/int_pet.c @@ -1,9 +1,6 @@ // Copyright (c) Athena Dev Teams - Licensed under GNU GPL // For more information, see LICENCE in the main folder -// original code from athena -// SQL conversion by Jioh L. Jung - #include #include #include @@ -81,7 +78,7 @@ int inter_pet_fromsql(int pet_id, struct s_pet *p){ p->pet_id = pet_id; p->class_ = atoi(sql_row[1]); - memcpy(p->name, sql_row[2],NAME_LENGTH-1); + strncpy(p->name, sql_row[2], NAME_LENGTH); p->account_id = atoi(sql_row[3]); p->char_id = atoi(sql_row[4]); p->level = atoi(sql_row[5]); @@ -192,10 +189,10 @@ int mapif_delete_pet_ack(int fd, int flag){ } int mapif_create_pet(int fd, int account_id, int char_id, short pet_class, short pet_lv, short pet_egg_id, - short pet_equip, short intimate, short hungry, char rename_flag, char incuvate, char *pet_name){ - + short pet_equip, short intimate, short hungry, char rename_flag, char incuvate, char *pet_name) +{ memset(pet_pt, 0, sizeof(struct s_pet)); - memcpy(pet_pt->name, pet_name, NAME_LENGTH-1); + strncpy(pet_pt->name, pet_name, NAME_LENGTH); if(incuvate == 1) pet_pt->account_id = pet_pt->char_id = 0; else { diff --git a/src/login_sql/login.c b/src/login_sql/login.c index a24a9ed80..f42eb681a 100644 --- a/src/login_sql/login.c +++ b/src/login_sql/login.c @@ -1933,7 +1933,7 @@ void sql_config_read(const char* cfgName) sql_config_read(w2); } fclose(fp); - ShowInfo("done reading %s.\n", cfgName); + ShowInfo("Done reading %s.\n", cfgName); } void login_set_defaults() diff --git a/src/map/battle.c b/src/map/battle.c index 9ec58981e..cee92d515 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -2778,6 +2778,7 @@ int battle_weapon_attack(struct block_list* src, struct block_list* target, unsi struct status_data *sstatus, *tstatus; struct status_change *sc, *tsc; int damage,rdamage=0,rdelay=0; + int skillv; struct Damage wd; nullpo_retr(0, src); @@ -2874,19 +2875,21 @@ int battle_weapon_attack(struct block_list* src, struct block_list* target, unsi } } } - //Recycled the damage variable rather than use a new one... [Skotlex] - if(sd && (damage = pc_checkskill(sd,MO_TRIPLEATTACK)) > 0) + + if(sd && (skillv = pc_checkskill(sd,MO_TRIPLEATTACK)) > 0) { - int triple_rate= 30 - damage; //Base Rate + int triple_rate= 30 - skillv; //Base Rate if (sc && sc->data[SC_SKILLRATE_UP].timer!=-1 && sc->data[SC_SKILLRATE_UP].val1 == MO_TRIPLEATTACK) { triple_rate+= triple_rate*(sc->data[SC_SKILLRATE_UP].val2)/100; status_change_end(src,SC_SKILLRATE_UP,-1); } if (rand()%100 < triple_rate) - return skill_attack(BF_WEAPON,src,src,target,MO_TRIPLEATTACK,damage,tick,0); + return skill_attack(BF_WEAPON,src,src,target,MO_TRIPLEATTACK,skillv,tick,0); } - else if (sc) { + + if (sc) + { if (sc->data[SC_SACRIFICE].timer != -1) return skill_attack(BF_WEAPON,src,src,target,PA_SACRIFICE,sc->data[SC_SACRIFICE].val1,tick,0); if (sc->data[SC_MAGICALATTACK].timer != -1) @@ -3340,7 +3343,7 @@ static const struct battle_data_short { { "enable_perfect_flee", &battle_config.enable_perfect_flee }, { "casting_rate", &battle_config.cast_rate }, { "delay_rate", &battle_config.delay_rate }, - { "delay_dependon_agi", &battle_config.delay_dependon_agi }, + { "delay_dependon_dex", &battle_config.delay_dependon_dex }, { "skill_delay_attack_enable", &battle_config.sdelay_attack_enable }, { "left_cardfix_to_right", &battle_config.left_cardfix_to_right }, { "skill_add_range", &battle_config.skill_add_range }, @@ -3734,7 +3737,7 @@ void battle_set_defaults() battle_config.enable_perfect_flee = BL_PC|BL_PET; battle_config.cast_rate=100; battle_config.delay_rate=100; - battle_config.delay_dependon_agi=0; + battle_config.delay_dependon_dex=0; battle_config.sdelay_attack_enable=0; battle_config.left_cardfix_to_right=0; battle_config.skill_add_range=0; diff --git a/src/map/battle.h b/src/map/battle.h index c574f2db5..8796ac48e 100644 --- a/src/map/battle.h +++ b/src/map/battle.h @@ -94,7 +94,7 @@ extern struct Battle_Config { unsigned short critical_rate; unsigned short enable_baseatk; unsigned short enable_perfect_flee; - unsigned short cast_rate,delay_rate,delay_dependon_agi; + unsigned short cast_rate,delay_rate,delay_dependon_dex; unsigned short sdelay_attack_enable; unsigned short left_cardfix_to_right; unsigned short skill_add_range; diff --git a/src/map/charcommand.c b/src/map/charcommand.c index ca7da3f7b..7d4151b64 100644 --- a/src/map/charcommand.c +++ b/src/map/charcommand.c @@ -1349,7 +1349,7 @@ int charcommand_fakename(const int fd, struct map_session_data* sd, const char* return 0; } - memcpy(pl_sd->fakename,name, NAME_LENGTH-1); + memcpy(pl_sd->fakename, name, NAME_LENGTH); clif_charnameack(0, &pl_sd->bl); clif_displaymessage(sd->fd,"Fake name enabled."); diff --git a/src/map/chrif.c b/src/map/chrif.c index ba11565b7..1adee71a9 100644 --- a/src/map/chrif.c +++ b/src/map/chrif.c @@ -668,7 +668,7 @@ int chrif_char_ask_name_answer(int fd) char player_name[NAME_LENGTH]; acc = RFIFOL(fd,2); // account_id of who has asked (-1 if nobody) - memcpy(player_name, RFIFOP(fd,6), NAME_LENGTH-1); + memcpy(player_name, RFIFOP(fd,6), NAME_LENGTH); player_name[NAME_LENGTH-1] = '\0'; sd = map_id2sd(acc); diff --git a/src/map/clif.c b/src/map/clif.c index fd5f69bd0..a4ffc3b6b 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -10825,7 +10825,7 @@ void clif_parse_PMIgnore(int fd, struct map_session_data *sd) return; } //Insert in position i - memcpy(sd->ignore[i].name, nick, NAME_LENGTH-1); + memcpy(sd->ignore[i].name, nick, NAME_LENGTH); WFIFOB(fd,3) = 0; // success WFIFOSET(fd, packet_len(0x0d1)); if (strcmp(wisp_server_name, nick) == 0) diff --git a/src/map/guild.c b/src/map/guild.c index 74d2a1978..857eeffb0 100644 --- a/src/map/guild.c +++ b/src/map/guild.c @@ -182,9 +182,9 @@ static int guild_read_castledb(void) gc=(struct guild_castle *)aCalloc(1,sizeof(struct guild_castle)); gc->castle_id=atoi(str[0]); - memcpy(gc->map_name,mapindex_normalize_name(str[1]),MAP_NAME_LENGTH-1); - memcpy(gc->castle_name,str[2],NAME_LENGTH-1); - memcpy(gc->castle_event,str[3],NAME_LENGTH-1); + memcpy(gc->map_name,mapindex_normalize_name(str[1]),MAP_NAME_LENGTH); + memcpy(gc->castle_name,str[2],NAME_LENGTH); + memcpy(gc->castle_event,str[3],NAME_LENGTH); idb_put(castle_db,gc->castle_id,gc); @@ -336,7 +336,7 @@ void guild_makemember(struct guild_member *m,struct map_session_data *sd) // m->exp_payper =0; m->online =1; m->position =MAX_GUILDPOSITION-1; - memcpy(m->name,sd->status.name,NAME_LENGTH-1); + memcpy(m->name,sd->status.name,NAME_LENGTH); return; } // ギルド競合確認 @@ -1032,7 +1032,7 @@ int guild_change_position(int guild_id,int idx, //Mode 0x10 <- Expel. p.mode=mode&0x11; p.exp_mode=exp_mode; - memcpy(p.name,name,NAME_LENGTH-1); + memcpy(p.name,name,NAME_LENGTH); p.name[NAME_LENGTH-1] = '\0'; //Security check... [Skotlex] return intif_guild_position(guild_id,idx,&p); } @@ -1462,7 +1462,7 @@ int guild_allianceack(int guild_id1,int guild_id2,int account_id1,int account_id for(j=0;jalliance[j].guild_id==0){ g[i]->alliance[j].guild_id=guild_id[1-i]; - memcpy(g[i]->alliance[j].name,guild_name[1-i],NAME_LENGTH-1); + memcpy(g[i]->alliance[j].name,guild_name[1-i],NAME_LENGTH); g[i]->alliance[j].opposition=flag&1; break; } diff --git a/src/map/map.c b/src/map/map.c index 5af776569..6df33fe26 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -2464,7 +2464,7 @@ int map_addmap(char *mapname) return 1; } - memcpy(map[map_num].name, mapindex_normalize_name(mapname), MAP_NAME_LENGTH-1); + memcpy(map[map_num].name, mapindex_normalize_name(mapname), MAP_NAME_LENGTH); map_num++; return 0; } diff --git a/src/map/mob.c b/src/map/mob.c index 76a89f2e1..79ae84435 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -204,7 +204,7 @@ struct mob_data* mob_spawn_dataset(struct spawn_data *data) md->bl.y = data->y; md->class_ = data->class_; md->db = mob_db(md->class_); - memcpy(md->name, data->name, NAME_LENGTH-1); + memcpy(md->name, data->name, NAME_LENGTH); if (data->state.ai) md->special_state.ai = data->state.ai; if (data->state.size) @@ -2338,9 +2338,9 @@ int mob_class_change (struct mob_data *md, int class_) md->class_ = class_; md->db = mob_db(class_); if (battle_config.override_mob_names==1) - memcpy(md->name,md->db->name,NAME_LENGTH-1); + memcpy(md->name,md->db->name,NAME_LENGTH); else - memcpy(md->name,md->db->jname,NAME_LENGTH-1); + memcpy(md->name,md->db->jname,NAME_LENGTH); mob_stop_attack(md); mob_stop_walking(md, 0); @@ -3210,9 +3210,9 @@ int mob_parse_dbrow(char** str) status = &db->status; db->vd.class_ = class_; - memcpy(db->sprite, str[1], NAME_LENGTH-1); - memcpy(db->jname, str[2], NAME_LENGTH-1); - memcpy(db->name, str[3], NAME_LENGTH-1); + strncpy(db->sprite, str[1], NAME_LENGTH); + strncpy(db->jname, str[2], NAME_LENGTH); + strncpy(db->name, str[3], NAME_LENGTH); db->lv = atoi(str[4]); db->lv = cap_value(db->lv, 1, USHRT_MAX); status->max_hp = atoi(str[5]); diff --git a/src/map/npc.c b/src/map/npc.c index f037bea2d..61a8ef093 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -464,7 +464,7 @@ int npc_addeventtimer(struct npc_data *nd,int tick,const char *name) if(evname==NULL){ ShowFatalError("npc_addeventtimer: out of memory !\n");exit(1); } - memcpy(evname,name,NAME_LENGTH-1); + strncpy(evname,name,NAME_LENGTH); evname[NAME_LENGTH-1] = '\0'; nd->eventtimer[i]=add_timer(gettick()+tick, npc_event_timer,nd->bl.id,(int)evname); @@ -1660,8 +1660,8 @@ int npc_parse_warp (char *w1,char *w2,char *w3,char *w4) nd->bl.m = m; nd->bl.x = x; nd->bl.y = y; - memcpy(nd->name, w3, NAME_LENGTH-1); - memcpy(nd->exname, w3, NAME_LENGTH-1); + strncpy(nd->name, w3, NAME_LENGTH); + strncpy(nd->exname, w3, NAME_LENGTH); if (!battle_config.warp_point_debug) nd->class_ = WARP_CLASS; @@ -1761,7 +1761,7 @@ static int npc_parse_shop (char *w1, char *w2, char *w3, char *w4) nd->bl.x = x; nd->bl.y = y; nd->bl.id = npc_get_new_npc_id(); - memcpy(nd->name, w3, NAME_LENGTH-1); + memcpy(nd->name, w3, NAME_LENGTH); nd->name[NAME_LENGTH-1] = '\0'; nd->class_ = m==-1?-1:atoi(w4); nd->speed = 200; @@ -2036,11 +2036,11 @@ static int npc_parse_script(char *w1,char *w2,char *w3,char *w4,char *first_line } if (p) { *p = 0; - memcpy(nd->name, w3, NAME_LENGTH-1); - memcpy(nd->exname, p+2, NAME_LENGTH-1); + memcpy(nd->name, w3, NAME_LENGTH); + memcpy(nd->exname, p+2, NAME_LENGTH); } else { - memcpy(nd->name, w3, NAME_LENGTH-1); - memcpy(nd->exname, w3, NAME_LENGTH-1); + memcpy(nd->name, w3, NAME_LENGTH); + memcpy(nd->exname, w3, NAME_LENGTH); } if((dnd = npc_name2id(nd->exname))){ diff --git a/src/map/pc.c b/src/map/pc.c index caa4b535c..22dad96f0 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -4578,9 +4578,9 @@ int pc_allskillup(struct map_session_data *sd) //pc_calc_skilltree takes care of setting the ID to valid skills. [Skotlex] if (battle_config.gm_allskill > 0 && pc_isGM(sd) >= battle_config.gm_allskill) { //Get ALL skills except npc/guild ones. [Skotlex] - //and except SG_DEVIL [Komurka] + //and except SG_DEVIL [Komurka] and MO_TRIPLEATTACK and RG_SNATCHER [ultramage] for(i=0;istatus.skill[i].lv=skill_get_max(i); //Nonexistant skills should return a max of 0 anyway. } } diff --git a/src/map/pet.c b/src/map/pet.c index 02ae3b5e2..82168ac48 100644 --- a/src/map/pet.c +++ b/src/map/pet.c @@ -709,7 +709,7 @@ int pet_change_name_ack(struct map_session_data *sd, char* name, int flag) clif_send_petstatus(sd); //Send status so client knows oet name change got rejected. return 0; } - memcpy(pd->pet.name, name, NAME_LENGTH-1); + memcpy(pd->pet.name, name, NAME_LENGTH); clif_charnameack (0,&pd->bl); pd->pet.rename_flag = 1; clif_pet_equip(pd); @@ -1327,8 +1327,8 @@ int read_petdb() } pet_db[j].class_ = nameid; - memcpy(pet_db[j].name,str[1],NAME_LENGTH-1); - memcpy(pet_db[j].jname,str[2],NAME_LENGTH-1); + strncpy(pet_db[j].name,str[1],NAME_LENGTH); + strncpy(pet_db[j].jname,str[2],NAME_LENGTH); pet_db[j].itemID=atoi(str[3]); pet_db[j].EggID=atoi(str[4]); pet_db[j].AcceID=atoi(str[5]); diff --git a/src/map/script.c b/src/map/script.c index 2a4c4ccc5..46042f085 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -6132,7 +6132,7 @@ char *buildin_getpartyname_sub(int party_id) if(p!=NULL){ char *buf; buf=(char *)aMallocA(NAME_LENGTH*sizeof(char)); - memcpy(buf, p->party.name, NAME_LENGTH-1); + memcpy(buf, p->party.name, NAME_LENGTH); buf[NAME_LENGTH-1] = '\0'; return buf; } @@ -6248,7 +6248,7 @@ char *buildin_getguildname_sub(int guild_id) if(g!=NULL){ char *buf; buf=(char *)aMallocA(NAME_LENGTH*sizeof(char)); - memcpy(buf, g->name, NAME_LENGTH-1); + memcpy(buf, g->name, NAME_LENGTH); buf[NAME_LENGTH-1] = '\0'; return buf; } @@ -6277,7 +6277,7 @@ char *buildin_getguildmaster_sub(int guild_id) if(g!=NULL){ char *buf; buf=(char *)aMallocA(NAME_LENGTH*sizeof(char)); - memcpy(buf, g->master, NAME_LENGTH-1); + memcpy(buf, g->master, NAME_LENGTH); buf[NAME_LENGTH-1] = '\0'; return buf; } diff --git a/src/map/skill.c b/src/map/skill.c index 11706ac42..0fff9ba0c 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -683,7 +683,7 @@ int skill_get_maxcount( int id ){ skill_get (skill_db[id].maxcount, id, 1); } int skill_get_blewcount( int id ,int lv ){ skill_get (skill_db[id].blewcount[lv-1], id, lv); } int skill_get_mhp( int id ,int lv ){ skill_get (skill_db[id].mhp[lv-1], id, lv); } int skill_get_castnodex( int id ,int lv ){ skill_get (skill_db[id].castnodex[lv-1], id, lv); } -int skill_get_delaynodex( int id ,int lv ){ skill_get (skill_db[id].delaynoagi[lv-1], id, lv); } +int skill_get_delaynodex( int id ,int lv ){ skill_get (skill_db[id].delaynodex[lv-1], id, lv); } int skill_get_nocast ( int id ){ skill_get (skill_db[id].nocast, id, 1); } int skill_get_type( int id ){ skill_get (skill_db[id].skill_type, id, 1); } int skill_get_unit_id ( int id, int flag ){ skill_get (skill_db[id].unit_id[flag], id, 1); } @@ -858,12 +858,12 @@ int skillnotok (int skillid, struct map_session_data *sd) if (i > MAX_SKILL || i < 0) return 1; - if (sd->blockskill[i] > 0) - return 1; - if (battle_config.gm_skilluncond && pc_isGM(sd) >= battle_config.gm_skilluncond) return 0; // gm's can do anything damn thing they want + if (sd->blockskill[i] > 0) + return 1; + // Check skill restrictions [Celest] if(!map_flag_vs(m) && skill_get_nocast (skillid) & 1) return 1; @@ -8671,7 +8671,7 @@ int skill_check_condition (struct map_session_data *sd, int skill, int lv, int t } /*========================================== - * + * Does cast-time reductions based on dex, item bonuses and config setting *------------------------------------------*/ int skill_castfix (struct block_list *bl, int skill_id, int skill_lv) { @@ -8689,9 +8689,10 @@ int skill_castfix (struct block_list *bl, int skill_id, int skill_lv) else return 0; // instant cast } - // calculate cast time reduced by card bonuses - if (sd && sd->castrate != 100) - time = time * sd->castrate / 100; + // calculate cast time reduced by item/card bonuses + if (!(skill_get_castnodex(skill_id, skill_lv)&4)) + if (sd && sd->castrate != 100) + time = time * sd->castrate / 100; // config cast time multiplier if (battle_config.cast_rate != 100) @@ -8725,11 +8726,11 @@ int skill_castfix_sc (struct block_list *bl, int time) } /*========================================== - * + * Does delay reductions based on dex, *------------------------------------------*/ int skill_delayfix (struct block_list *bl, int skill_id, int skill_lv) { - int delaynochange = skill_get_delaynodex(skill_id, skill_lv); + int delaynodex = skill_get_delaynodex(skill_id, skill_lv); int time = skill_get_delay(skill_id, skill_lv); nullpo_retr(0, bl); @@ -8756,9 +8757,9 @@ int skill_delayfix (struct block_list *bl, int skill_id, int skill_lv) time -= 4*status_get_agi(bl) - 2*status_get_dex(bl); break; default: - if (battle_config.delay_dependon_agi && !(delaynochange&1)) - { // if skill casttime is allowed to be reduced by agi - int scale = battle_config.castrate_dex_scale - status_get_agi(bl); + if (battle_config.delay_dependon_dex && !(delaynodex&1)) + { // if skill delay is allowed to be reduced by dex + int scale = battle_config.castrate_dex_scale - status_get_dex(bl); if (scale > 0) time = time * scale / battle_config.castrate_dex_scale; else //To be capped later to minimum. @@ -8766,13 +8767,7 @@ int skill_delayfix (struct block_list *bl, int skill_id, int skill_lv) } } - if (bl->type == BL_PC && ((TBL_PC*)bl)->delayrate != 100) - time = time * ((TBL_PC*)bl)->delayrate / 100; - - if (battle_config.delay_rate != 100) - time = time * battle_config.delay_rate / 100; - - if (!(delaynochange&2)) + if (!(delaynodex&2)) { struct status_change *sc; sc= status_get_sc(bl); @@ -8793,8 +8788,14 @@ int skill_delayfix (struct block_list *bl, int skill_id, int skill_lv) } } - return (time < battle_config.min_skill_delay_limit)? - battle_config.min_skill_delay_limit:time; + if (!(delaynodex&4)) + if (bl->type == BL_PC && ((TBL_PC*)bl)->delayrate != 100) + time = time * ((TBL_PC*)bl)->delayrate / 100; + + if (battle_config.delay_rate != 100) + time = time * battle_config.delay_rate / 100; + + return max(time, battle_config.min_skill_delay_limit); } /*========================================= @@ -11553,7 +11554,7 @@ int skill_readdb (void) skill_split_atoi(split[1],skill_db[i].castnodex); if (!split[2]) continue; - skill_split_atoi(split[2],skill_db[i].delaynoagi); + skill_split_atoi(split[2],skill_db[i].delaynodex); } fclose(fp); ShowStatus("Done reading '"CL_WHITE"%s"CL_RESET"'.\n",path); diff --git a/src/map/skill.h b/src/map/skill.h index 9d61a8f54..29bd94ac9 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -71,8 +71,7 @@ struct skill_db { int hp[MAX_SKILL_LEVEL],sp[MAX_SKILL_LEVEL],mhp[MAX_SKILL_LEVEL],hp_rate[MAX_SKILL_LEVEL],sp_rate[MAX_SKILL_LEVEL],zeny[MAX_SKILL_LEVEL]; int weapon,ammo,ammo_qty[MAX_SKILL_LEVEL],state,spiritball[MAX_SKILL_LEVEL]; int itemid[10],amount[10]; - int castnodex[MAX_SKILL_LEVEL]; - int delaynoagi[MAX_SKILL_LEVEL]; + int castnodex[MAX_SKILL_LEVEL], delaynodex[MAX_SKILL_LEVEL]; int nocast; int unit_id[2]; int unit_layout_type[MAX_SKILL_LEVEL]; diff --git a/src/map/unit.c b/src/map/unit.c index c4ca10395..a60ab2d95 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -954,7 +954,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, int skill_num, int break; case MO_FINGEROFFENSIVE: if(sd) - casttime += casttime * ((skill_lv > sd->spiritball)? sd->spiritball:skill_lv); + casttime += casttime * min(skill_lv, sd->spiritball); break; case MO_EXTREMITYFIST: if (sc && sc->data[SC_COMBO].timer != -1 && @@ -981,6 +981,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, int skill_num, int break; } + // moved here to prevent Suffragium from ending if skill fails if (!(skill_get_castnodex(skill_num, skill_lv)&2)) casttime = skill_castfix_sc(src, casttime); @@ -1116,7 +1117,7 @@ int unit_skilluse_pos2( struct block_list *src, int skill_x, int skill_y, int sk unit_stop_attack(src); ud->state.skillcastcancel = castcancel; - + // moved here to prevent Suffragium from ending if skill fails if (!(skill_get_castnodex(skill_num, skill_lv)&2)) casttime = skill_castfix_sc(src, casttime); -- cgit v1.2.3-60-g2f50