diff options
-rw-r--r-- | conf/battle/skill.conf | 2 | ||||
-rw-r--r-- | src/char/char.c | 29 | ||||
-rw-r--r-- | src/char/int_guild.c | 7 | ||||
-rw-r--r-- | src/char/int_pet.c | 7 | ||||
-rw-r--r-- | src/common/mapindex.c | 9 | ||||
-rw-r--r-- | src/login/login.c | 7 | ||||
-rw-r--r-- | src/map/chrif.c | 7 | ||||
-rw-r--r-- | src/map/clif.c | 27 | ||||
-rw-r--r-- | src/map/elemental.c | 10 | ||||
-rw-r--r-- | src/map/homunculus.c | 11 | ||||
-rw-r--r-- | src/map/map.c | 9 | ||||
-rw-r--r-- | src/map/mercenary.c | 9 | ||||
-rw-r--r-- | src/map/mob.c | 7 | ||||
-rw-r--r-- | src/map/npc.c | 12 | ||||
-rw-r--r-- | src/map/pc.c | 2 | ||||
-rw-r--r-- | src/map/pc.h | 9 | ||||
-rw-r--r-- | src/map/script.c | 34 | ||||
-rw-r--r-- | src/map/skill.c | 338 | ||||
-rw-r--r-- | src/map/unit.c | 4 |
19 files changed, 298 insertions, 242 deletions
diff --git a/conf/battle/skill.conf b/conf/battle/skill.conf index 03aae2ad1..0dd97610e 100644 --- a/conf/battle/skill.conf +++ b/conf/battle/skill.conf @@ -278,5 +278,5 @@ dancing_weaponswitch_fix: yes // Skill Trap Type // 0: (official) traps only makes player unable to move after its walk path is complete, and it activates other traps on the way. -// 1: trap makes player stops moving right when stepping over it. +// 1: trap makes player stop moving right when stepping over it. skill_trap_type: 0 diff --git a/src/char/char.c b/src/char/char.c index 83b58a0a7..d454e8bd0 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -3991,6 +3991,35 @@ int parse_char(int fd) return 0; RFIFOSKIP(fd,6); break; + // char rename request + // R 08fc <char ID>.l <new name>.24B + case 0x8fc: + FIFOSD_CHECK(30); + { + int i, cid =RFIFOL(fd,2); + char name[NAME_LENGTH]; + char esc_name[NAME_LENGTH*2+1]; + safestrncpy(name, (char *)RFIFOP(fd,6), NAME_LENGTH); + RFIFOSKIP(fd,30); + + ARR_FIND( 0, MAX_CHARS, i, sd->found_char[i] == cid ); + if( i == MAX_CHARS ) + break; + + normalize_name(name,TRIM_CHARS); + Sql_EscapeStringLen(sql_handle, esc_name, name, strnlen(name, NAME_LENGTH)); + if( !check_char_name(name,esc_name) ) { + i = 1; + safestrncpy(sd->new_name, name, NAME_LENGTH); + } else + i = 0; + + WFIFOHEAD(fd, 4); + WFIFOW(fd,0) = 0x28e; + WFIFOW(fd,2) = i; + WFIFOSET(fd,4); + } + break; // char rename request // R 028d <account ID>.l <char ID>.l <new name>.24B diff --git a/src/char/int_guild.c b/src/char/int_guild.c index 7090af5ee..9cb17dca8 100644 --- a/src/char/int_guild.c +++ b/src/char/int_guild.c @@ -1,5 +1,6 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder +// Copyright (c) Hercules dev team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena dev team #include "../common/cbasetypes.h" #include "../common/mmo.h" @@ -1815,7 +1816,7 @@ int mapif_parse_GuildMasterChange(int fd, int guild_id, const char* name, int le g->member[0].position = 0; //Position 0: guild Master. g->member[0].modified = GS_MEMBER_MODIFIED; - strncpy(g->master, name, len); + safestrncpy(g->master, name, len); if (len < NAME_LENGTH) g->master[len] = '\0'; diff --git a/src/char/int_pet.c b/src/char/int_pet.c index 114398290..d9b0cf5ef 100644 --- a/src/char/int_pet.c +++ b/src/char/int_pet.c @@ -1,5 +1,6 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder +// Copyright (c) Hercules dev team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena dev team #include "../common/mmo.h" #include "../common/malloc.h" @@ -184,7 +185,7 @@ int mapif_create_pet(int fd, int account_id, int char_id, short pet_class, short short pet_equip, short intimate, short hungry, char rename_flag, char incuvate, char *pet_name) { memset(pet_pt, 0, sizeof(struct s_pet)); - strncpy(pet_pt->name, pet_name, NAME_LENGTH); + safestrncpy(pet_pt->name, pet_name, NAME_LENGTH); if(incuvate == 1) pet_pt->account_id = pet_pt->char_id = 0; else { diff --git a/src/common/mapindex.c b/src/common/mapindex.c index d46047833..cea945ac0 100644 --- a/src/common/mapindex.c +++ b/src/common/mapindex.c @@ -1,5 +1,6 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder +// Copyright (c) Hercules dev team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena dev team #include "../common/mmo.h" #include "../common/showmsg.h" @@ -37,7 +38,7 @@ const char* mapindex_getmapname(const char* string, char* output) len -= 4; // strip .gat extension len = min(len, MAP_NAME_LENGTH-1); - strncpy(dest, string, len+1); + safestrncpy(dest, string, len+1); memset(&dest[len], '\0', MAP_NAME_LENGTH-len); return dest; @@ -61,7 +62,7 @@ const char* mapindex_getmapname_ext(const char* string, char* output) ShowWarning("(mapindex_normalize_name) Map name '%*s' is too long!\n", 2*MAP_NAME_LENGTH, buf); len--; } - strncpy(dest, buf, len+1); + safestrncpy(dest, buf, len+1); if (len < 4 || stricmp(&dest[len-4], ".gat") != 0) { strcpy(&dest[len], ".gat"); diff --git a/src/login/login.c b/src/login/login.c index e079dbaf2..625e0f5c6 100644 --- a/src/login/login.c +++ b/src/login/login.c @@ -1,5 +1,6 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder +// Copyright (c) Hercules dev team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena dev team #include "../common/core.h" #include "../common/db.h" @@ -1596,7 +1597,7 @@ int login_config_read(const char* cfgName) continue; if(!strcmpi(w1,"timestamp_format")) - strncpy(timestamp_format, w2, 20); + safestrncpy(timestamp_format, w2, 20); else if(!strcmpi(w1,"stdout_with_ansisequence")) stdout_with_ansisequence = config_switch(w2); else if(!strcmpi(w1,"console_silent")) { diff --git a/src/map/chrif.c b/src/map/chrif.c index e109f7095..3ad164b89 100644 --- a/src/map/chrif.c +++ b/src/map/chrif.c @@ -1,5 +1,6 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder +// Copyright (c) Hercules dev team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena dev team #include "../common/cbasetypes.h" #include "../common/malloc.h" @@ -246,7 +247,7 @@ int chrif_setip(const char* ip) { return 0; } - strncpy(char_ip_str, ip, sizeof(char_ip_str)); + safestrncpy(char_ip_str, ip, sizeof(char_ip_str)); ShowInfo("Char Server IP Address : '"CL_WHITE"%s"CL_RESET"' -> '"CL_WHITE"%s"CL_RESET"'.\n", ip, ip2str(char_ip, ip_str)); diff --git a/src/map/clif.c b/src/map/clif.c index 3f4ea8bc2..3443c1ae3 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -203,7 +203,7 @@ int clif_setip(const char* ip) return 0; } - strncpy(map_ip_str, ip, sizeof(map_ip_str)); + safestrncpy(map_ip_str, ip, sizeof(map_ip_str)); ShowInfo("Map Server IP Address : '"CL_WHITE"%s"CL_RESET"' -> '"CL_WHITE"%s"CL_RESET"'.\n", ip, ip2str(map_ip, ip_str)); return 1; } @@ -10141,7 +10141,7 @@ void clif_parse_DropItem(int fd, struct map_session_data *sd) if (pc_isdead(sd)) break; - if (pc_cant_act(sd)) + if ( pc_cant_act2(sd) ) break; if (sd->sc.count && ( @@ -10180,7 +10180,7 @@ void clif_parse_UseItem(int fd, struct map_session_data *sd) if (sd->npc_id != sd->npc_item_flag) return; } - else if (pc_istrading(sd)) + else if ( pc_istrading(sd) || sd->chatID ) return; //Whether the item is used or not is irrelevant, the char ain't idle. [Skotlex] @@ -10213,7 +10213,7 @@ void clif_parse_EquipItem(int fd,struct map_session_data *sd) return; } else if (sd->state.storage_flag || sd->sc.opt1) ; //You can equip/unequip stuff while storage is open/under status changes - else if (pc_cant_act(sd)) + else if ( pc_cant_act2(sd) ) return; if(!sd->status.inventory[index].identify) { @@ -10250,7 +10250,7 @@ void clif_parse_UnequipItem(int fd,struct map_session_data *sd) if (sd->state.storage_flag || sd->sc.opt1) ; //You can equip/unequip stuff while storage is open/under status changes - else if (pc_cant_act(sd)) + else if ( pc_cant_act2(sd) ) return; index = RFIFOW(fd,2)-2; @@ -10272,7 +10272,7 @@ void clif_parse_NpcClicked(int fd,struct map_session_data *sd) return; } - if (pc_cant_act(sd)) + if ( pc_cant_act2(sd) ) return; bl = map_id2bl(RFIFOL(fd,2)); @@ -11111,11 +11111,16 @@ void clif_parse_NpcSelectMenu(int fd,struct map_session_data *sd) int npc_id = RFIFOL(fd,2); uint8 select = RFIFOB(fd,6); - if( (select > sd->npc_menu && select != 0xff) || select == 0 ) - { - TBL_NPC* nd = map_id2nd(npc_id); - ShowWarning("Invalid menu selection on npc %d:'%s' - got %d, valid range is [%d..%d] (player AID:%d, CID:%d, name:'%s')!\n", npc_id, (nd)?nd->name:"invalid npc id", select, 1, sd->npc_menu, sd->bl.id, sd->status.char_id, sd->status.name); - clif_GM_kick(NULL,sd); + if( (select > sd->npc_menu && select != 0xff) || select == 0 ) { +#if SECURE_NPCTIMEOUT + if( sd->npc_idle_timer != INVALID_TIMER ) { +#endif + TBL_NPC* nd = map_id2nd(npc_id); + ShowWarning("Invalid menu selection on npc %d:'%s' - got %d, valid range is [%d..%d] (player AID:%d, CID:%d, name:'%s')!\n", npc_id, (nd)?nd->name:"invalid npc id", select, 1, sd->npc_menu, sd->bl.id, sd->status.char_id, sd->status.name); + clif_GM_kick(NULL,sd); +#if SECURE_NPCTIMEOUT + } +#endif return; } diff --git a/src/map/elemental.c b/src/map/elemental.c index 90b90c1e3..f6c9eff84 100644 --- a/src/map/elemental.c +++ b/src/map/elemental.c @@ -1,5 +1,6 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder +// Copyright (c) Hercules dev team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena dev team #include "../common/cbasetypes.h" #include "../common/malloc.h" @@ -10,6 +11,7 @@ #include "../common/showmsg.h" #include "../common/utils.h" #include "../common/random.h" +#include "../common/strlib.h" #include "log.h" #include "clif.h" @@ -795,8 +797,8 @@ int read_elementaldb(void) { db = &elemental_db[j]; db->class_ = atoi(str[0]); - strncpy(db->sprite, str[1], NAME_LENGTH); - strncpy(db->name, str[2], NAME_LENGTH); + safestrncpy(db->sprite, str[1], NAME_LENGTH); + safestrncpy(db->name, str[2], NAME_LENGTH); db->lv = atoi(str[3]); status = &db->status; diff --git a/src/map/homunculus.c b/src/map/homunculus.c index 081287d8a..c94a95775 100644 --- a/src/map/homunculus.c +++ b/src/map/homunculus.c @@ -1,5 +1,6 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder +// Copyright (c) Hercules dev team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena dev team #include "../common/cbasetypes.h" #include "../common/malloc.h" @@ -709,7 +710,7 @@ int merc_hom_change_name_ack(struct map_session_data *sd, char* name, int flag) clif_displaymessage(sd->fd, msg_txt(280)); // You cannot use this name return 0; } - strncpy(hd->homunculus.name,name,NAME_LENGTH); + safestrncpy(hd->homunculus.name,name,NAME_LENGTH); clif_charnameack (0,&hd->bl); hd->homunculus.rename_flag = 1; clif_hominfo(sd,hd,0); @@ -887,7 +888,7 @@ int merc_create_homunculus_request(struct map_session_data *sd, int class_) memset(&homun, 0, sizeof(struct s_homunculus)); //Initial data - strncpy(homun.name, homunculus_db[i].name, NAME_LENGTH-1); + safestrncpy(homun.name, homunculus_db[i].name, NAME_LENGTH-1); homun.class_ = class_; homun.level = 1; homun.hunger = 32; //32% @@ -1050,7 +1051,7 @@ static bool read_homunculusdb_sub(char* str[], int columns, int current) } db->evo_class = classid; //Name, Food, Hungry Delay, Base Size, Evo Size, Race, Element, ASPD - strncpy(db->name,str[2],NAME_LENGTH-1); + safestrncpy(db->name,str[2],NAME_LENGTH-1); db->foodID = atoi(str[3]); db->hungryDelay = atoi(str[4]); db->base_size = atoi(str[5]); diff --git a/src/map/map.c b/src/map/map.c index a8521de7d..d2cc9c4a9 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -1,5 +1,6 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder +// Copyright (c) Hercules dev team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena dev team #include "../common/cbasetypes.h" #include "../common/core.h" @@ -3216,7 +3217,7 @@ int map_config_read(char *cfgName) *ptr = '\0'; if(strcmpi(w1,"timestamp_format")==0) - strncpy(timestamp_format, w2, 20); + safestrncpy(timestamp_format, w2, 20); else if(strcmpi(w1,"stdout_with_ansisequence")==0) stdout_with_ansisequence = config_switch(w2); else if(strcmpi(w1,"console_silent")==0) { @@ -3267,7 +3268,7 @@ int map_config_read(char *cfgName) else if (strcmpi(w1, "charhelp_txt") == 0) strcpy(charhelp_txt, w2); else if(strcmpi(w1,"db_path") == 0) - strncpy(db_path,w2,255); + safestrncpy(db_path,w2,255); else if (strcmpi(w1, "console") == 0) { console = config_switch(w2); if (console) diff --git a/src/map/mercenary.c b/src/map/mercenary.c index 973dac33e..c3fb8e3e2 100644 --- a/src/map/mercenary.c +++ b/src/map/mercenary.c @@ -1,5 +1,6 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder +// Copyright (c) Hercules dev team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena dev team #include "../common/cbasetypes.h" #include "../common/malloc.h" @@ -404,8 +405,8 @@ static bool read_mercenarydb_sub(char* str[], int columns, int current) db = &mercenary_db[current]; db->class_ = atoi(str[0]); - strncpy(db->sprite, str[1], NAME_LENGTH); - strncpy(db->name, str[2], NAME_LENGTH); + safestrncpy(db->sprite, str[1], NAME_LENGTH); + safestrncpy(db->name, str[2], NAME_LENGTH); db->lv = atoi(str[3]); status = &db->status; diff --git a/src/map/mob.c b/src/map/mob.c index ac3c1dfe3..6550d9b0e 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -1,5 +1,6 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder +// Copyright (c) Hercules dev team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena dev team #include "../common/cbasetypes.h" #include "../common/timer.h" @@ -4120,7 +4121,7 @@ static bool mob_parse_row_chatdb(char** str, const char* source, int line, int* } msg[len] = 0; // strip previously found EOL - strncpy(ms->msg, str[2], CHAT_SIZE_MAX); + safestrncpy(ms->msg, str[2], CHAT_SIZE_MAX); return true; } diff --git a/src/map/npc.c b/src/map/npc.c index 5d8a0274e..3aabeaf98 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -1,5 +1,6 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder +// Copyright (c) Hercules dev team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena dev team #include "../common/cbasetypes.h" #include "../common/timer.h" @@ -231,6 +232,9 @@ int npc_rr_secure_timeout_timer(int tid, unsigned int tick, int id, intptr_t dat **/ if( sd->st ) sd->st->state = END; + sd->state.menu_or_input = 0; + sd->npc_menu = 0; + /** * This guy's been idle for longer than allowed, close him. **/ @@ -1915,7 +1919,7 @@ void npc_addsrcfile(const char* name) file = (struct npc_src_list*)aMalloc(sizeof(struct npc_src_list) + strlen(name)); file->next = NULL; - strncpy(file->name, name, strlen(name) + 1); + safestrncpy(file->name, name, strlen(name) + 1); if( file_prev == NULL ) npc_src_files = file; else @@ -3606,7 +3610,7 @@ void npc_read_event_script(void) DBData *data; char name[64]="::"; - strncpy(name+2,config[i].event_name,62); + safestrncpy(name+2,config[i].event_name,62); script_event[i].event_count = 0; iter = db_iterator(ev_db); diff --git a/src/map/pc.c b/src/map/pc.c index 89925f8f2..abfbbcc12 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -5518,6 +5518,8 @@ int pc_stop_following (struct map_session_data *sd) sd->followtarget = -1; sd->ud.target_to = 0; + unit_stop_walking(&sd->bl, 1); + return 0; } diff --git a/src/map/pc.h b/src/map/pc.h index 3027c5f10..870945d73 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -1,5 +1,6 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder +// Copyright (c) Hercules dev team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena dev team #ifndef _PC_H_ #define _PC_H_ @@ -592,6 +593,10 @@ enum equip_index { #define pc_isidle(sd) ( (sd)->chatID || (sd)->state.vending || (sd)->state.buyingstore || DIFF_TICK(last_tick, (sd)->idletime) >= battle_config.idle_no_share ) #define pc_istrading(sd) ( (sd)->npc_id || (sd)->state.vending || (sd)->state.buyingstore || (sd)->state.trading ) #define pc_cant_act(sd) ( (sd)->npc_id || (sd)->state.vending || (sd)->state.buyingstore || (sd)->chatID || ((sd)->sc.opt1 && (sd)->sc.opt1 != OPT1_BURNING) || (sd)->state.trading || (sd)->state.storage_flag ) + +/* equals pc_cant_act except it doesn't check for chat rooms */ +#define pc_cant_act2(sd) ( (sd)->npc_id || (sd)->state.vending || (sd)->state.buyingstore || ((sd)->sc.opt1 && (sd)->sc.opt1 != OPT1_BURNING) || (sd)->state.trading || (sd)->state.storage_flag ) + #define pc_setdir(sd,b,h) ( (sd)->ud.dir = (b) ,(sd)->head_dir = (h) ) #define pc_setchatid(sd,n) ( (sd)->chatID = n ) #define pc_ishiding(sd) ( (sd)->sc.option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) ) diff --git a/src/map/script.c b/src/map/script.c index 4099820f1..60a61654a 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -3590,30 +3590,26 @@ static void script_detach_state(struct script_state* st, bool dequeue_event) { struct map_session_data* sd; - if(st->rid && (sd = map_id2sd(st->rid))!=NULL) - { + if(st->rid && (sd = map_id2sd(st->rid))!=NULL) { sd->st = st->bk_st; sd->npc_id = st->bk_npcid; - /** - * For the Secure NPC Timeout option (check config/Secure.h) [RR] - **/ - #if SECURE_NPCTIMEOUT - /** - * We're done with this NPC session, so we cancel the timer (if existent) and move on - **/ - if( sd->npc_idle_timer != INVALID_TIMER ) { - delete_timer(sd->npc_idle_timer,npc_rr_secure_timeout_timer); - sd->npc_idle_timer = INVALID_TIMER; - } - #endif - if(st->bk_st) - { + if(st->bk_st) { //Remove tag for removal. st->bk_st = NULL; st->bk_npcid = 0; - } - else if(dequeue_event) - { + } else if(dequeue_event) { + /** + * For the Secure NPC Timeout option (check config/Secure.h) [RR] + **/ +#if SECURE_NPCTIMEOUT + /** + * We're done with this NPC session, so we cancel the timer (if existent) and move on + **/ + if( sd->npc_idle_timer != INVALID_TIMER ) { + delete_timer(sd->npc_idle_timer,npc_rr_secure_timeout_timer); + sd->npc_idle_timer = INVALID_TIMER; + } +#endif npc_event_dequeue(sd); } } diff --git a/src/map/skill.c b/src/map/skill.c index 752b1ece0..448f54406 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -1,4 +1,4 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL +// Copyright (c) Athena Dev Teams - Licensed under GNU GPL // For more information, see LICENCE in the main folder #include "../common/cbasetypes.h" @@ -1560,7 +1560,7 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, uint if (skill == AS_SONICBLOW) pc_stop_attack(sd); //Special case, Sonic Blow autospell should stop the player attacking. - if (skill == PF_SPIDERWEB) //Special case, due to its nature of coding. + else if (skill == PF_SPIDERWEB) //Special case, due to its nature of coding. type = CAST_GROUND; sd->state.autocast = 1; @@ -9373,7 +9373,15 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data) } if (target && target->m == src->m) { //Move character to target anyway. - if (unit_movepos(src, src->x+3, src->y+3, 1, 1)) + int dir, x, y; + dir = map_calc_dir(src,target->x,target->y); + if( dir > 0 && dir < 4) x = -2; + else if( dir > 4 ) x = 2; + else x = 0; + if( dir > 2 && dir < 6 ) y = -2; + else if( dir == 7 || dir < 2 ) y = 2; + else y = 0; + if (unit_movepos(src, src->x+x, src->y+y, 1, 1)) { //Display movement + animation. clif_slide(src,src->x,src->y); clif_skill_damage(src,target,tick,sd->battle_status.amotion,0,0,1,ud->skill_id, ud->skill_lv, 5); @@ -11041,195 +11049,191 @@ static int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, un type = status_skill2sc(sg->skill_id); sce = (sc && type != -1)?sc->data[type]:NULL; skill_id = sg->skill_id; //In case the group is deleted, we need to return the correct skill id, still. - switch (sg->unit_id) - { - case UNT_SPIDERWEB: - if( sc && sc->data[SC_SPIDERWEB] && sc->data[SC_SPIDERWEB]->val1 > 0 ) - { // If you are fiberlocked and can't move, it will only increase your fireweakness level. [Inkfish] - sc->data[SC_SPIDERWEB]->val2++; - break; - } - else if( sc ) - { - int sec = skill_get_time2(sg->skill_id,sg->skill_lv); - if( status_change_start(bl,type,10000,sg->skill_lv,1,sg->group_id,0,sec,8) ) - { - const struct TimerData* td = sc->data[type]?get_timer(sc->data[type]->timer):NULL; - if( td ) - sec = DIFF_TICK(td->tick, tick); - map_moveblock(bl, src->bl.x, src->bl.y, tick); - clif_fixpos(bl); - sg->val2 = bl->id; + switch (sg->unit_id) { + case UNT_SPIDERWEB: + if( sc && sc->data[SC_SPIDERWEB] && sc->data[SC_SPIDERWEB]->val1 > 0 ) { + // If you are fiberlocked and can't move, it will only increase your fireweakness level. [Inkfish] + sc->data[SC_SPIDERWEB]->val2++; + break; + } else if( sc && battle_check_target(&sg->unit->bl,bl,sg->target_flag) > 0 ) { + int sec = skill_get_time2(sg->skill_id,sg->skill_lv); + if( status_change_start(bl,type,10000,sg->skill_lv,1,sg->group_id,0,sec,8) ) { + const struct TimerData* td = sc->data[type]?get_timer(sc->data[type]->timer):NULL; + if( td ) + sec = DIFF_TICK(td->tick, tick); + map_moveblock(bl, src->bl.x, src->bl.y, tick); + clif_fixpos(bl); + sg->val2 = bl->id; + } + else + sec = 3000; //Couldn't trap it? + sg->limit = DIFF_TICK(tick,sg->tick)+sec; } - else - sec = 3000; //Couldn't trap it? - sg->limit = DIFF_TICK(tick,sg->tick)+sec; - } - break; - case UNT_SAFETYWALL: - if (!sce) - sc_start4(bl,type,100,sg->skill_lv,sg->skill_id,sg->group_id,0,sg->limit); - break; + break; + case UNT_SAFETYWALL: + if (!sce) + sc_start4(bl,type,100,sg->skill_lv,sg->skill_id,sg->group_id,0,sg->limit); + break; - case UNT_PNEUMA: - case UNT_CHAOSPANIC: - case UNT_MAELSTROM: - if (!sce) - sc_start4(bl,type,100,sg->skill_lv,sg->group_id,0,0,sg->limit); - break; - case UNT_BLOODYLUST: - if (sg->src_id == bl->id) - break; //Does not affect the caster. - if (!sce) { - TBL_PC *sd = BL_CAST(BL_PC, bl); //prevent fullheal exploit - if (sd && sd->bloodylust_tick && DIFF_TICK(gettick(), sd->bloodylust_tick) < skill_get_time2(SC_BLOODYLUST, 1)) - clif_skill_nodamage(&src->bl,bl,sg->skill_id,sg->skill_lv, - sc_start4(bl, type, 100, sg->skill_lv, 1, 0, 0, skill_get_time(LK_BERSERK, sg->skill_lv))); - else { - if (sd) sd->bloodylust_tick = gettick(); + case UNT_PNEUMA: + case UNT_CHAOSPANIC: + case UNT_MAELSTROM: + if (!sce) + sc_start4(bl,type,100,sg->skill_lv,sg->group_id,0,0,sg->limit); + break; + case UNT_BLOODYLUST: + if (sg->src_id == bl->id) + break; //Does not affect the caster. + if (!sce) { + TBL_PC *sd = BL_CAST(BL_PC, bl); //prevent fullheal exploit + if (sd && sd->bloodylust_tick && DIFF_TICK(gettick(), sd->bloodylust_tick) < skill_get_time2(SC_BLOODYLUST, 1)) clif_skill_nodamage(&src->bl,bl,sg->skill_id,sg->skill_lv, - sc_start4(bl, type, 100, sg->skill_lv, 0, 0, 0, skill_get_time(LK_BERSERK, sg->skill_lv))); + sc_start4(bl, type, 100, sg->skill_lv, 1, 0, 0, skill_get_time(LK_BERSERK, sg->skill_lv))); + else { + if (sd) sd->bloodylust_tick = gettick(); + clif_skill_nodamage(&src->bl,bl,sg->skill_id,sg->skill_lv, + sc_start4(bl, type, 100, sg->skill_lv, 0, 0, 0, skill_get_time(LK_BERSERK, sg->skill_lv))); + } } - } - break; + break; - case UNT_WARP_WAITING: { - int working = sg->val1&0xffff; + case UNT_WARP_WAITING: { + int working = sg->val1&0xffff; - if(bl->type==BL_PC && !working){ - struct map_session_data *sd = (struct map_session_data *)bl; - if((!sd->chatID || battle_config.chat_warpportal) - && sd->ud.to_x == src->bl.x && sd->ud.to_y == src->bl.y) - { - int x = sg->val2>>16; - int y = sg->val2&0xffff; - int count = sg->val1>>16; - unsigned short m = sg->val3; + if(bl->type==BL_PC && !working){ + struct map_session_data *sd = (struct map_session_data *)bl; + if((!sd->chatID || battle_config.chat_warpportal) + && sd->ud.to_x == src->bl.x && sd->ud.to_y == src->bl.y) + { + int x = sg->val2>>16; + int y = sg->val2&0xffff; + int count = sg->val1>>16; + unsigned short m = sg->val3; - if( --count <= 0 ) - skill_delunitgroup(sg); + if( --count <= 0 ) + skill_delunitgroup(sg); - if ( map_mapindex2mapid(sg->val3) == sd->bl.m && x == sd->bl.x && y == sd->bl.y ) - working = 1;/* we break it because officials break it, lovely stuff. */ + if ( map_mapindex2mapid(sg->val3) == sd->bl.m && x == sd->bl.x && y == sd->bl.y ) + working = 1;/* we break it because officials break it, lovely stuff. */ - sg->val1 = (count<<16)|working; + sg->val1 = (count<<16)|working; - pc_setpos(sd,m,x,y,CLR_TELEPORT); + pc_setpos(sd,m,x,y,CLR_TELEPORT); + } + } else if(bl->type == BL_MOB && battle_config.mob_warp&2) { + int16 m = map_mapindex2mapid(sg->val3); + if (m < 0) break; //Map not available on this map-server. + unit_warp(bl,m,sg->val2>>16,sg->val2&0xffff,CLR_TELEPORT); } - } else if(bl->type == BL_MOB && battle_config.mob_warp&2) { - int16 m = map_mapindex2mapid(sg->val3); - if (m < 0) break; //Map not available on this map-server. - unit_warp(bl,m,sg->val2>>16,sg->val2&0xffff,CLR_TELEPORT); } - } - break; + break; - case UNT_QUAGMIRE: - if( !sce && battle_check_target(&sg->unit->bl,bl,sg->target_flag) > 0 ) - sc_start4(bl,type,100,sg->skill_lv,sg->group_id,0,0,sg->limit); - break; + case UNT_QUAGMIRE: + if( !sce && battle_check_target(&sg->unit->bl,bl,sg->target_flag) > 0 ) + sc_start4(bl,type,100,sg->skill_lv,sg->group_id,0,0,sg->limit); + break; - case UNT_VOLCANO: - case UNT_DELUGE: - case UNT_VIOLENTGALE: - if(!sce) - sc_start(bl,type,100,sg->skill_lv,sg->limit); - break; + case UNT_VOLCANO: + case UNT_DELUGE: + case UNT_VIOLENTGALE: + if(!sce) + sc_start(bl,type,100,sg->skill_lv,sg->limit); + break; - case UNT_SUITON: - if(!sce) - sc_start4(bl,type,100,sg->skill_lv, - map_flag_vs(bl->m) || battle_check_target(&src->bl,bl,BCT_ENEMY)>0?1:0, //Send val3 =1 to reduce agi. - 0,0,sg->limit); - break; + case UNT_SUITON: + if(!sce) + sc_start4(bl,type,100,sg->skill_lv, + map_flag_vs(bl->m) || battle_check_target(&src->bl,bl,BCT_ENEMY)>0?1:0, //Send val3 =1 to reduce agi. + 0,0,sg->limit); + break; - case UNT_HERMODE: - if (sg->src_id!=bl->id && battle_check_target(&src->bl,bl,BCT_PARTY|BCT_GUILD) > 0) - status_change_clear_buffs(bl,1); //Should dispell only allies. - case UNT_RICHMANKIM: - case UNT_ETERNALCHAOS: - case UNT_DRUMBATTLEFIELD: - case UNT_RINGNIBELUNGEN: - case UNT_ROKISWEIL: - case UNT_INTOABYSS: - case UNT_SIEGFRIED: - //Needed to check when a dancer/bard leaves their ensemble area. - if (sg->src_id==bl->id && !(sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_BARDDANCER)) - return skill_id; - if (!sce) - sc_start4(bl,type,100,sg->skill_lv,sg->val1,sg->val2,0,sg->limit); - break; - case UNT_WHISTLE: - case UNT_ASSASSINCROSS: - case UNT_POEMBRAGI: - case UNT_APPLEIDUN: - case UNT_HUMMING: - case UNT_DONTFORGETME: - case UNT_FORTUNEKISS: - case UNT_SERVICEFORYOU: - if (sg->src_id==bl->id && !(sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_BARDDANCER)) - return 0; + case UNT_HERMODE: + if (sg->src_id!=bl->id && battle_check_target(&src->bl,bl,BCT_PARTY|BCT_GUILD) > 0) + status_change_clear_buffs(bl,1); //Should dispell only allies. + case UNT_RICHMANKIM: + case UNT_ETERNALCHAOS: + case UNT_DRUMBATTLEFIELD: + case UNT_RINGNIBELUNGEN: + case UNT_ROKISWEIL: + case UNT_INTOABYSS: + case UNT_SIEGFRIED: + //Needed to check when a dancer/bard leaves their ensemble area. + if (sg->src_id==bl->id && !(sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_BARDDANCER)) + return skill_id; + if (!sce) + sc_start4(bl,type,100,sg->skill_lv,sg->val1,sg->val2,0,sg->limit); + break; + case UNT_WHISTLE: + case UNT_ASSASSINCROSS: + case UNT_POEMBRAGI: + case UNT_APPLEIDUN: + case UNT_HUMMING: + case UNT_DONTFORGETME: + case UNT_FORTUNEKISS: + case UNT_SERVICEFORYOU: + if (sg->src_id==bl->id && !(sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_BARDDANCER)) + return 0; - if (!sc) return 0; - if (!sce) - sc_start4(bl,type,100,sg->skill_lv,sg->val1,sg->val2,0,sg->limit); - else if (sce->val4 == 1) { - //Readjust timers since the effect will not last long. - sce->val4 = 0; - delete_timer(sce->timer, status_change_timer); - sce->timer = add_timer(tick+sg->limit, status_change_timer, bl->id, type); - } - break; + if (!sc) return 0; + if (!sce) + sc_start4(bl,type,100,sg->skill_lv,sg->val1,sg->val2,0,sg->limit); + else if (sce->val4 == 1) { + //Readjust timers since the effect will not last long. + sce->val4 = 0; + delete_timer(sce->timer, status_change_timer); + sce->timer = add_timer(tick+sg->limit, status_change_timer, bl->id, type); + } + break; - case UNT_FOGWALL: - if (!sce) - { - sc_start4(bl, type, 100, sg->skill_lv, sg->val1, sg->val2, sg->group_id, sg->limit); - if (battle_check_target(&src->bl,bl,BCT_ENEMY)>0) - skill_additional_effect (ss, bl, sg->skill_id, sg->skill_lv, BF_MISC, ATK_DEF, tick); - } - break; + case UNT_FOGWALL: + if (!sce) + { + sc_start4(bl, type, 100, sg->skill_lv, sg->val1, sg->val2, sg->group_id, sg->limit); + if (battle_check_target(&src->bl,bl,BCT_ENEMY)>0) + skill_additional_effect (ss, bl, sg->skill_id, sg->skill_lv, BF_MISC, ATK_DEF, tick); + } + break; - case UNT_GRAVITATION: - if (!sce) - sc_start4(bl,type,100,sg->skill_lv,0,BCT_ENEMY,sg->group_id,sg->limit); - break; + case UNT_GRAVITATION: + if (!sce) + sc_start4(bl,type,100,sg->skill_lv,0,BCT_ENEMY,sg->group_id,sg->limit); + break; -// officially, icewall has no problems existing on occupied cells [ultramage] -// case UNT_ICEWALL: //Destroy the cell. [Skotlex] -// src->val1 = 0; -// if(src->limit + sg->tick > tick + 700) -// src->limit = DIFF_TICK(tick+700,sg->tick); -// break; + // officially, icewall has no problems existing on occupied cells [ultramage] + // case UNT_ICEWALL: //Destroy the cell. [Skotlex] + // src->val1 = 0; + // if(src->limit + sg->tick > tick + 700) + // src->limit = DIFF_TICK(tick+700,sg->tick); + // break; - case UNT_MOONLIT: - //Knockback out of area if affected char isn't in Moonlit effect - if (sc && sc->data[SC_DANCING] && (sc->data[SC_DANCING]->val1&0xFFFF) == CG_MOONLIT) - break; - if (ss == bl) //Also needed to prevent infinite loop crash. + case UNT_MOONLIT: + //Knockback out of area if affected char isn't in Moonlit effect + if (sc && sc->data[SC_DANCING] && (sc->data[SC_DANCING]->val1&0xFFFF) == CG_MOONLIT) + break; + if (ss == bl) //Also needed to prevent infinite loop crash. + break; + skill_blown(ss,bl,skill_get_blewcount(sg->skill_id,sg->skill_lv),unit_getdir(bl),0); break; - skill_blown(ss,bl,skill_get_blewcount(sg->skill_id,sg->skill_lv),unit_getdir(bl),0); - break; - case UNT_WALLOFTHORN: - if( status_get_mode(bl)&MD_BOSS ) - break; // iRO Wiki says that this skill don't affect to Boss monsters. - if( map_flag_vs(bl->m) || bl->id == src->bl.id || battle_check_target(&src->bl,bl, BCT_ENEMY) == 1 ) - skill_attack(skill_get_type(sg->skill_id), ss, &src->bl, bl, sg->skill_id, sg->skill_lv, tick, 0); - break; + case UNT_WALLOFTHORN: + if( status_get_mode(bl)&MD_BOSS ) + break; // iRO Wiki says that this skill don't affect to Boss monsters. + if( map_flag_vs(bl->m) || bl->id == src->bl.id || battle_check_target(&src->bl,bl, BCT_ENEMY) == 1 ) + skill_attack(skill_get_type(sg->skill_id), ss, &src->bl, bl, sg->skill_id, sg->skill_lv, tick, 0); + break; - case UNT_VOLCANIC_ASH: - if (!sce) - sc_start(bl, SC_ASH, 100, sg->skill_lv, skill_get_time(MH_VOLCANIC_ASH, sg->skill_lv)); - break; + case UNT_VOLCANIC_ASH: + if (!sce) + sc_start(bl, SC_ASH, 100, sg->skill_lv, skill_get_time(MH_VOLCANIC_ASH, sg->skill_lv)); + break; - case UNT_GD_LEADERSHIP: - case UNT_GD_GLORYWOUNDS: - case UNT_GD_SOULCOLD: - case UNT_GD_HAWKEYES: - if ( !sce ) - sc_start4(bl,type,100,sg->skill_lv,0,0,0,1000); - break; + case UNT_GD_LEADERSHIP: + case UNT_GD_GLORYWOUNDS: + case UNT_GD_SOULCOLD: + case UNT_GD_HAWKEYES: + if ( !sce ) + sc_start4(bl,type,100,sg->skill_lv,0,0,0,1000); + break; } return skill_id; } diff --git a/src/map/unit.c b/src/map/unit.c index 148a35782..b7da5629f 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -350,7 +350,7 @@ int unit_walktoxy( struct block_list *bl, short x, short y, int flag) map_random_dir(bl, &ud->to_x, &ud->to_y); if(ud->walktimer != INVALID_TIMER) { - if( !battle_config.skill_trap_type && sc->data[SC_ANKLE] ) // Ankle disallows you from changing your path + if( !battle_config.skill_trap_type && sc && sc->data[SC_ANKLE] ) // Ankle disallows you from changing your path return 0; // When you come to the center of the grid because the change of destination while you're walking right now // Call a function from a timer unit_walktoxy_sub @@ -427,7 +427,7 @@ int unit_walktobl(struct block_list *bl, struct block_list *tbl, int range, int map_random_dir(bl, &ud->to_x, &ud->to_y); if(ud->walktimer != INVALID_TIMER) { - if( !battle_config.skill_trap_type && sc->data[SC_ANKLE] ) // Ankle disallows you from changing your path + if( !battle_config.skill_trap_type && sc && sc->data[SC_ANKLE] ) // Ankle disallows you from changing your path return 0; ud->state.change_walk_target = 1; set_mobstate(bl, flag&2); |