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/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 +++-- 15 files changed, 71 insertions(+), 67 deletions(-) (limited to 'src/map') 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-70-g09d2