diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/char/char.c | 20 | ||||
-rw-r--r-- | src/common/mapindex.c | 2 | ||||
-rw-r--r-- | src/map/battle.c | 1 | ||||
-rw-r--r-- | src/map/battle.h | 1 | ||||
-rw-r--r-- | src/map/npc.c | 2 | ||||
-rw-r--r-- | src/map/skill.c | 58 | ||||
-rw-r--r-- | src/map/status.c | 52 | ||||
-rw-r--r-- | src/map/unit.c | 13 |
8 files changed, 89 insertions, 60 deletions
diff --git a/src/char/char.c b/src/char/char.c index 9abb17257..abebc5ff9 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -4749,8 +4749,7 @@ int parse_char(int fd) // checks the entered pin case 0x8b8: - if( RFIFOREST(fd) < 10 ) - return 0; + FIFOSD_CHECK(10); if( RFIFOL(fd,2) == sd->account_id ) pincode->check( fd, sd ); @@ -4760,8 +4759,8 @@ int parse_char(int fd) // request for PIN window case 0x8c5: - if( RFIFOREST(fd) < 6 ) - return 0; + FIFOSD_CHECK(6); + if( RFIFOL(fd,2) == sd->account_id ) pincode->sendstate( fd, sd, PINCODE_NOTSET ); @@ -4770,8 +4769,8 @@ int parse_char(int fd) // pincode change request case 0x8be: - if( RFIFOREST(fd) < 14 ) - return 0; + FIFOSD_CHECK(14); + if( RFIFOL(fd,2) == sd->account_id ) pincode->change( fd, sd ); @@ -4780,8 +4779,8 @@ int parse_char(int fd) // activate PIN system and set first PIN case 0x8ba: - if( RFIFOREST(fd) < 10 ) - return 0; + FIFOSD_CHECK(10); + if( RFIFOL(fd,2) == sd->account_id ) pincode->setnew( fd, sd ); RFIFOSKIP(fd,10); @@ -4789,9 +4788,8 @@ int parse_char(int fd) /* 0x8d4 <from>.W <to>.W <unused>.W (2+2+2+2) */ case 0x8d4: - if( RFIFOREST(fd) < 8 ) - return 0; - else { + FIFOSD_CHECK(8); + { bool ret; ret = char_slotchange(sd, fd, RFIFOW(fd, 2), RFIFOW(fd, 4)); WFIFOHEAD(fd, 8); diff --git a/src/common/mapindex.c b/src/common/mapindex.c index f540c98d8..0873b3e59 100644 --- a/src/common/mapindex.c +++ b/src/common/mapindex.c @@ -138,7 +138,7 @@ int mapindex_init(void) { char line[1024]; int last_index = -1; int index, total = 0; - char map_name[12]; + char map_name[13]; if( ( fp = fopen(mapindex->config_file,"r") ) == NULL ){ ShowFatalError("Unable to read mapindex config file %s!\n", mapindex->config_file); diff --git a/src/map/battle.c b/src/map/battle.c index 30b358492..8930d3a7e 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -6733,6 +6733,7 @@ static const struct battle_data { { "mail_show_status", &battle_config.mail_show_status, 0, 0, 2, }, { "client_limit_unit_lv", &battle_config.client_limit_unit_lv, 0, 0, BL_ALL, }, { "client_emblem_max_blank_percent", &battle_config.client_emblem_max_blank_percent, 100, 0, 100, }, + { "song_timer_reset", &battle_config.song_timer_reset, 0, 0, 1, }, // BattleGround Settings { "bg_update_interval", &battle_config.bg_update_interval, 1000, 100, INT_MAX, }, { "bg_flee_penalty", &battle_config.bg_flee_penalty, 20, 0, INT_MAX, }, diff --git a/src/map/battle.h b/src/map/battle.h index 8d1a3cd39..161ddebc4 100644 --- a/src/map/battle.h +++ b/src/map/battle.h @@ -169,6 +169,7 @@ struct Battle_Config { int emergency_call; int guild_aura; int pc_invincible_time; + int song_timer_reset; int pet_catch_rate; int pet_rename; diff --git a/src/map/npc.c b/src/map/npc.c index f1c6f4fbd..f4f20a60d 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -3447,7 +3447,7 @@ const char* npc_parse_mob(char* w1, char* w2, char* w3, char* w4, const char* st // w4=<mob id>,<amount>,<delay1>,<delay2>,<event>{,<mob size>,<mob ai>} if( sscanf(w1, "%31[^,],%d,%d,%d,%d", mapname, &x, &y, &xs, &ys) < 3 || sscanf(w3, "%23[^,],%d", mobname, &mob_lv) < 1 - || sscanf(w4, "%d,%d,%u,%u,%127[^,],%d,%d[^\t\r\n]", &class_, &num, &mobspawn.delay1, &mobspawn.delay2, mobspawn.eventname, &size, &ai) < 2 + || sscanf(w4, "%d,%d,%u,%u,%50[^,],%d,%d[^\t\r\n]", &class_, &num, &mobspawn.delay1, &mobspawn.delay2, mobspawn.eventname, &size, &ai) < 2 ) { ShowError("npc_parse_mob: Invalid mob definition in file '%s', line '%d'.\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4); if (retval) *retval = EXIT_FAILURE; diff --git a/src/map/skill.c b/src/map/skill.c index 9f008d65b..9046ff975 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -6360,7 +6360,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin if (tsc->data[SC_STONE]) { status_change_end(bl, SC_STONE, INVALID_TIMER); - if (sd) clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); + clif->skill_nodamage(src,bl,skill_id,skill_lv,1); break; } if (sc_start4(src,bl,SC_STONE,(skill_lv*4+20)+brate, @@ -11013,19 +11013,21 @@ struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_ val1 = 15+skill_lv+(st->int_/10); // MaxSP percent increase TO-DO: this INT bonus value is guessed val2 = 20+3*skill_lv+(st->int_/10); // SP cost reduction if(sd){ - val1 += pc->checkskill(sd,DC_DANCINGLESSON); //TO-DO This bonus value is guessed - val2 += pc->checkskill(sd,DC_DANCINGLESSON); //TO-DO Should be half this value + val1 += (pc->checkskill(sd,DC_DANCINGLESSON) + 1) / 2; + val2 += (pc->checkskill(sd,DC_DANCINGLESSON) + 1) / 2; } break; case BA_ASSASSINCROSS: -#ifdef RENEWAL - val1 = 10 + skill_lv + (st->agi/10); // ASPD increase if(sd) - val1 += 4*pc->checkskill(sd,BA_MUSICALLESSON); + val1 = (pc->checkskill(sd,BA_MUSICALLESSON) + 1) / 2; +#ifdef RENEWAL + // This formula was taken from a RE calculator + // and the changes published on irowiki + // Luckily, official tests show it's the right one + val1 += skill_lv + (st->agi/20); #else - val1 = 100+(10*skill_lv)+(st->agi/10); // ASPD increase - if(sd) - val1 += 5*pc->checkskill(sd,BA_MUSICALLESSON); + val1 += 10 + skill_lv + (st->agi/10); // ASPD increase + val1 *= 10; // ASPD works with 1000 as 100% #endif break; case DC_FORTUNEKISS: @@ -11456,13 +11458,15 @@ int skill_unit_onplace(struct skill_unit *src, struct block_list *bl, int64 tick return 0; if (!sc) return 0; - if (!sce) - sc_start4(ss,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; - timer->delete(sce->timer, status->change_timer); - sce->timer = timer->add(tick+sg->limit, status->change_timer, bl->id, type); + if (battle_config.song_timer_reset) { // Aegis like behaviour goes on skill_unit_onplace_timer + if (!sce) + sc_start4(ss,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; + timer->delete(sce->timer, status->change_timer); + sce->timer = timer->add(tick+sg->limit, status->change_timer, bl->id, type); + } } break; @@ -11846,6 +11850,12 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6 heal = ~heal + 1; clif->skill_nodamage(&src->bl, bl, AL_HEAL, heal, 1); status->heal(bl, heal, 0, 0); + + if (!(battle_config.song_timer_reset) // songs don't reset prior timers + && !(sg->src_id == bl->id && !(tsc && tsc->data[SC_SOULLINK] && tsc->data[SC_SOULLINK]->val2 == SL_BARDDANCER)) // Don't affect itself + && (!(tsc->data[type]) || (tsc->data[type] && tsc->data[type]->val4 != 1))) // Check for 20 seconds song effect + sc_start4(ss,bl,type,100,sg->skill_lv,sg->val1,sg->val2,0,sg->interval + 100); + break; } @@ -12273,6 +12283,16 @@ int skill_unit_onout(struct skill_unit *src, struct block_list *bl, int64 tick) } } 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_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_BARDDANCER)) + return -1; } return sg->skill_id; } @@ -12350,7 +12370,7 @@ int skill_unit_onleft(uint16 skill_id, struct block_list *bl, int64 tick) { case DC_DONTFORGETME: case DC_FORTUNEKISS: case DC_SERVICEFORYOU: - if (sce) { + if ((battle_config.song_timer_reset && sce) || (!battle_config.song_timer_reset && sce && sce->val4 != 1)) { timer->delete(sce->timer, status->change_timer); //NOTE: It'd be nice if we could get the skill_lv for a more accurate extra time, but alas... //not possible on our current implementation. @@ -12413,8 +12433,8 @@ int skill_unit_effect(struct block_list* bl, va_list ap) { } else { if( flag&1 ) skill->unit_onplace(su,bl,tick); - else - skill->unit_onout(su,bl,tick); + else if (skill->unit_onout(su,bl,tick) == -1) + return 0; // Don't let a Bard/Dancer update their own song timer if( flag&4 ) skill->unit_onleft(skill_id, bl, tick); diff --git a/src/map/status.c b/src/map/status.c index 718deaefc..ac89f2a07 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -1790,16 +1790,8 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin hide_flag = flag?OPTION_HIDE:(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK); //You cannot hide from ground skills. - if( skill->get_ele(skill_id,1) == ELE_EARTH ) //TODO: Need Skill Lv here :/ + if( skill->get_ele(skill_id,1) == ELE_EARTH && skill_id != MG_STONECURSE) hide_flag &= ~OPTION_HIDE; - else { - switch ( skill_id ) { - case MO_ABSORBSPIRITS: // it works when already casted and target suddenly hides. - case SA_DISPELL: - hide_flag &= ~OPTION_HIDE; - break; - } - } switch( target->type ) { case BL_PC: { @@ -1810,6 +1802,7 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin return 0; if( tsc ) { if (tsc->option&hide_flag && !is_boss && + !(flag&1 && skill->get_nk(skill_id)&NK_NO_DAMAGE) && // Buff/debuff skills that started casting before hiding still applies ((sd->special_state.perfect_hiding || !is_detect) || (tsc->data[SC_CLOAKINGEXCEED] && is_detect))) return 0; @@ -5402,7 +5395,25 @@ short status_calc_aspd(struct block_list *bl, struct status_change *sc, short fl skills1 = 5; } - if((sc->data[SC_BERSERK]) && skills1 < 15) + if( sc->data[SC_ASSNCROS] && skills1 < sc->data[SC_ASSNCROS]->val2){ + if (bl->type!=BL_PC) + skills1 = sc->data[SC_ASSNCROS]->val2; + else + switch(((TBL_PC*)bl)->status.weapon) + { + case W_BOW: + case W_REVOLVER: + case W_RIFLE: + case W_GATLING: + case W_SHOTGUN: + case W_GRENADE: + break; + default: + skills1 = sc->data[SC_ASSNCROS]->val2; + } + } + + if((sc->data[SC_BERSERK]) && skills1 < 15) skills1 = 15; else if(sc->data[SC_GS_MADNESSCANCEL] && skills1 < 20) skills1 = 20; @@ -5448,7 +5459,7 @@ short status_calc_aspd(struct block_list *bl, struct status_change *sc, short fl if( sc->data[SC_PAIN_KILLER] ) skills2 -= sc->data[SC_PAIN_KILLER]->val2; - if( sc->data[SC_SWING] ) + if( sc->data[SC_SWING] ) // TODO: SC_SWING shouldn't stack with skill1 modifiers skills2 += sc->data[SC_SWING]->val3; if( sc->data[SC_DANCE_WITH_WUG] ) skills2 += sc->data[SC_DANCE_WITH_WUG]->val3; @@ -5464,23 +5475,7 @@ short status_calc_aspd(struct block_list *bl, struct status_change *sc, short fl skills2 += sc->data[SC_GS_GATLINGFEVER]->val1; if( sc->data[SC_STAR_COMFORT] ) skills2 += 3 * sc->data[SC_STAR_COMFORT]->val1; - if( sc->data[SC_ASSNCROS] && !skills1){ - if (bl->type!=BL_PC) - skills2 += sc->data[SC_ASSNCROS]->val2; - else - switch(((TBL_PC*)bl)->status.weapon) - { - case W_BOW: - case W_REVOLVER: - case W_RIFLE: - case W_GATLING: - case W_SHOTGUN: - case W_GRENADE: - break; - default: - skills2 += sc->data[SC_ASSNCROS]->val2; - } - } + return ( flag&1? (skills1 + pots) : skills2 ); #else return 0; @@ -5569,6 +5564,7 @@ short status_calc_aspd_rate(struct block_list *bl, struct status_change *sc, int max = sc->data[SC_ASSNCROS]->val2; } } + aspd_rate -= max; if(sc->data[SC_BERSERK]) diff --git a/src/map/unit.c b/src/map/unit.c index af0c0a948..8b74ff80c 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -1241,6 +1241,19 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui casttime = -1; temp = 1; break; + case CR_DEVOTION: + if (sd) { + int i = 0, count = min(skill_lv, 5); + ARR_FIND(0, count, i, sd->devotion[i] == target_id); + if (i == count) { + ARR_FIND(0, count, i, sd->devotion[i] == 0); + if(i == count) { + clif->skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0); + return 0; // Can't cast on other characters when limit is reached + } + } + } + break; case SR_GATEOFHELL: case SR_TIGERCANNON: if (sc && sc->data[SC_COMBOATTACK] && |