From 392e49a6097460851f10501cfe34a9ee86010468 Mon Sep 17 00:00:00 2001 From: skotlex Date: Wed, 7 May 2008 18:46:21 +0000 Subject: - Added function battle_attr_ratio to handle just getting the attribute table data. Fixes Sense messing up with elemental based statuses. - Added Throw tomahawk to the list of items that do not trigger the equipment breaking code. - Moved a bit around the SC_ start of dancing skills to fix Moonlight petals pushing back the casters. - Modified status_damage to handle SC_KAZIEL. The return value of *_dead functions can pass 8 to specify that kaziel should not be triggered (ie: pvp/gvg) - Infinite Endure won't be passed on to devoted characters. - Infinite Endure is no longer saved on logout. - Added check to avoid gms opening vending shops if they don't have the required level. - Moved around the Steel Body S. Novice code, simplified it so it triggers before most of the penalties (death is cancelled). - Fixed the flee penalty not applying when you walk into a gvg map. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@12688 54d463be-8e91-2dee-dedb-b68131a5f0ec --- Changelog-Trunk.txt | 10 +++++++++ src/map/battle.c | 17 +++++++++++++-- src/map/battle.h | 1 + src/map/clif.c | 8 ++++++-- src/map/map.c | 2 ++ src/map/mob.c | 9 +------- src/map/pc.c | 59 +++++++++++++++-------------------------------------- src/map/pc.h | 2 +- src/map/skill.c | 25 ++++++++++++----------- src/map/status.c | 23 ++++++++++++++++----- src/map/vending.c | 7 ++++++- 11 files changed, 90 insertions(+), 73 deletions(-) diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt index 90c214a23..335900619 100644 --- a/Changelog-Trunk.txt +++ b/Changelog-Trunk.txt @@ -3,6 +3,16 @@ Date Added AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK. IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK. +2008/05/07 + * Fixed Sense messing up with Spiderweb. [Skotlex] + * Added Throw tomahawk to the list of items that do not trigger the + equipment breaking code. + * Probably fixed Moonlight petals pushing back the casters. + * Infinite Endure won't be passed on to devoted characters. + * Infinite Endure is no longer saved on logout. + * Added check to avoid gms opening vending shops if they don't have the + required level. + * Fixed the flee penalty not applying when you walk into a gvg map. 2008/05/03 * NPC_GUIDEDATTACK is not supposed to bypass pneuma/safetywall [ultramage] 2008/05/02 diff --git a/src/map/battle.c b/src/map/battle.c index d0d955719..cdf7cca46 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -207,6 +207,19 @@ int battle_delay_damage (unsigned int tick, int amotion, struct block_list *src, return 0; } + +int battle_attr_ratio(int atk_elem,int def_type, int def_lv) +{ + + if (atk_elem < 0 || atk_elem >= ELE_MAX) + return 100; + + if (def_type < 0 || def_type > ELE_MAX || def_lv < 1 || def_lv > 4) + return 100; + + return attr_fix_table[def_lv-1][atk_elem][def_type]; +} + /*========================================== * Does attribute fix modifiers. * Added passing of the chars so that the status changes can affect it. [Skotlex] @@ -2047,8 +2060,8 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo if (breakrate) skill_break_equip(src, EQP_WEAPON, breakrate, BCT_SELF); } - //Cart Termination won't trigger breaking data. Why? No idea, go ask Gravity. - if (battle_config.equip_skill_break_rate && skill_num != WS_CARTTERMINATION) + //Cart Termination/Tomahawk won't trigger breaking data. Why? No idea, go ask Gravity. + if (battle_config.equip_skill_break_rate && skill_num != WS_CARTTERMINATION && skill_num != ITM_TOMAHAWK) { // Target equipment breaking int breakrate[2] = {0,0}; // weapon = 0, armor = 1 if (sd) { // Break rate from equipment diff --git a/src/map/battle.h b/src/map/battle.h index 06fe16723..4b272c85f 100644 --- a/src/map/battle.h +++ b/src/map/battle.h @@ -37,6 +37,7 @@ int battle_calc_return_damage(struct block_list *bl, int damage, int flag); void battle_drain(struct map_session_data *sd, struct block_list *tbl, int rdamage, int ldamage, int race, int boss); +int battle_attr_ratio(int atk_elem,int def_type, int def_lv); int battle_attr_fix(struct block_list *src, struct block_list *target, int damage,int atk_elem,int def_type, int def_lv); // ダメージ最終計算 diff --git a/src/map/clif.c b/src/map/clif.c index 78277161f..bc3872ad6 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -4344,9 +4344,9 @@ int clif_skill_estimation(struct map_session_data *sd,struct block_list *dst) +(battle_config.estimation_type&2?status->mdef2:0); WBUFW(buf,18)= status->def_ele; for(i=0;i<9;i++) - WBUFB(buf,20+i)= (unsigned char)battle_attr_fix(NULL,dst,100,i+1,status->def_ele, status->ele_lv); + WBUFB(buf,20+i)= (unsigned char)battle_attr_ratio(i+1,status->def_ele, status->ele_lv); // The following caps negative attributes to 0 since the client displays them as 255-fix. [Skotlex] -// WBUFB(buf,20+i)= (unsigned char)((fix=battle_attr_fix(NULL,dst,100,i+1,status->def_ele, status->ele_lv))<0?0:fix); +// WBUFB(buf,20+i)= (unsigned char)((fix=battle_attr_ratio(i+1,status->def_ele, status->ele_lv))<0?0:fix); clif_send(buf,packet_len(0x18c),&sd->bl, sd->status.party_id>0?PARTY_SAMEMAP:SELF); @@ -7813,7 +7813,11 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) } if(map_flag_gvg(sd->bl.m)) + { clif_set0199(sd,3); + if (battle_config.gvg_flee_penalty != 100) + status_calc_bl(&sd->bl, SCB_FLEE); //Apply flee penalty + } // info about nearby objects // must use foreachinarea (CIRCULAR_AREA interferes with foreachinrange) diff --git a/src/map/map.c b/src/map/map.c index 79f72caac..688956f62 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -1588,6 +1588,8 @@ int map_quit(struct map_session_data *sd) status_change_end(&sd->bl,SC_TRICKDEAD,-1); if(sd->sc.data[SC_GUILDAURA]) status_change_end(&sd->bl,SC_GUILDAURA,-1); + if(sd->sc.data[SC_ENDURE] && sd->sc.data[SC_ENDURE]->val4) + status_change_end(&sd->bl,SC_ENDURE,-1); //No need to save infinite endure. if (battle_config.debuff_on_logout&1) { if(sd->sc.data[SC_ORCISH]) status_change_end(&sd->bl,SC_ORCISH,-1); diff --git a/src/map/mob.c b/src/map/mob.c index d50f9ddd0..ac81e23e1 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -890,7 +890,7 @@ int mob_linksearch(struct block_list *bl,va_list ap) static int mob_delayspawn(int tid, unsigned int tick, int id, intptr data) { struct block_list *bl = map_id2bl(id); - if (bl && bl->type == BL_MOB) + if (bl && bl->type == BL_MOB && bl->prev == NULL) mob_spawn((TBL_MOB*)bl); return 0; } @@ -2095,13 +2095,6 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type) md->state.skillstate = MSS_DEAD; mobskill_use(md,tick,-1); //On Dead skill. - if (md->sc.data[SC_KAIZEL]) - { //Revive in a bit. - add_timer(gettick()+3000, mob_respawn, md->bl.id, md->sc.data[SC_KAIZEL]->val2); //% of life to rebirth with - map_delblock(&md->bl); - return 1; //Return 1 to only clear the object. - } - map_freeblock_lock(); memset(pt,0,sizeof(pt)); diff --git a/src/map/pc.c b/src/map/pc.c index 5f9545651..5d0c1a914 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -302,12 +302,7 @@ int pc_setrestartvalue(struct map_session_data *sd,int type) if (type&1) { //Normal resurrection status->hp = 1; //Otherwise status_heal may fail if dead. - if(sd->state.snovice_dead_flag == 1) { // [Celest] - status_heal(&sd->bl, status->max_hp, status->max_sp, 1); - sd->state.snovice_dead_flag = 2; - sc_start(&sd->bl,status_skill2sc(MO_STEELBODY),100,1,skill_get_time(MO_STEELBODY,1)); - } else - status_heal(&sd->bl, b_status->hp, b_status->sp>status->sp?b_status->sp-status->sp:0, 1); + status_heal(&sd->bl, b_status->hp, b_status->sp>status->sp?b_status->sp-status->sp:0, 1); } else { //Just for saving on the char-server (with values as if respawned) sd->status.hp = b_status->hp; sd->status.sp = (status->sp < b_status->sp)?b_status->sp:status->sp; @@ -2847,7 +2842,7 @@ void pc_getcash(struct map_session_data *sd, int cash, int points) { pc_setaccountreg(sd,"#CASHPOINTS",sd->cashPoints + cash); - sprintf(output, "Gained %d cash points. Total %d points", points, sd->cashPoints); + sprintf(output, "Gained %d cash points. Total %d points", cash, sd->cashPoints); clif_disp_onlyself(sd, output, strlen(output)); } @@ -4233,7 +4228,7 @@ int pc_checkbaselevelup(struct map_session_data *sd) sc_start(&sd->bl,status_skill2sc(PR_MAGNIFICAT),100,1,skill_get_time(PR_MAGNIFICAT,1)); sc_start(&sd->bl,status_skill2sc(PR_GLORIA),100,1,skill_get_time(PR_GLORIA,1)); sc_start(&sd->bl,status_skill2sc(PR_SUFFRAGIUM),100,1,skill_get_time(PR_SUFFRAGIUM,1)); - if (sd->state.snovice_dead_flag == 2) + if (sd->state.snovice_dead_flag) sd->state.snovice_dead_flag = 0; //Reenable steelbody resurrection on dead. } else if((sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON || (sd->class_&MAPID_UPPERMASK) == MAPID_STAR_GLADIATOR) @@ -5085,11 +5080,22 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) unsigned int next = pc_nextbaseexp(sd); if( next == 0 ) next = pc_thisbaseexp(sd); if( get_percentage(sd->status.base_exp,next) >= 99 && !map_flag_gvg(sd->bl.m) ) + { sd->state.snovice_dead_flag = 1; + pc_setstand(sd); + status_percent_heal(&sd->bl, 100, 100); + clif_resurrection(&sd->bl, 1); + if(battle_config.pc_invincible_time) + pc_setinvincibletimer(sd, battle_config.pc_invincible_time); + sc_start(&sd->bl,status_skill2sc(MO_STEELBODY),100,1,skill_get_time(MO_STEELBODY,1)); + if(map_flag_gvg(sd->bl.m)) + pc_respawn_timer(-1, gettick(), sd->bl.id, 0); + return 0; + } } // changed penalty options, added death by player if pk_mode [Valaris] - if(battle_config.death_penalty_type && sd->state.snovice_dead_flag != 1 + if(battle_config.death_penalty_type && (sd->class_&MAPID_UPPERMASK) != MAPID_NOVICE // only novices will receive no penalty && !map[sd->bl.m].flag.noexppenalty && !map_flag_gvg(sd->bl.m) && !sd->sc.data[SC_BABY] && !sd->sc.data[SC_LIFEINSURANCE]) @@ -5207,44 +5213,13 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) if( sd->pvp_point < 0 ){ sd->pvp_point=0; add_timer(tick+1000, pc_respawn_timer,sd->bl.id,0); - return 1; + return 1|8; } } //GvG if(map_flag_gvg(sd->bl.m)){ add_timer(tick+1000, pc_respawn_timer,sd->bl.id,0); - return 1; - } - - if (sd->sc.data[SC_KAIZEL]) - { - j = sd->sc.data[SC_KAIZEL]->val1; //Kaizel Lv. - i = sd->sc.data[SC_KAIZEL]->val2; //Revive % - pc_setstand(sd); - status_change_clear(&sd->bl,0); - clif_skill_nodamage(&sd->bl,&sd->bl,ALL_RESURRECTION,1,1); - if(sd->special_state.restart_full_recover) - status_percent_heal(&sd->bl, 100, 100); - else - status_percent_heal(&sd->bl, i, 0); - clif_resurrection(&sd->bl, 1); - if(battle_config.pc_invincible_time) - pc_setinvincibletimer(sd, battle_config.pc_invincible_time); - sc_start(&sd->bl,status_skill2sc(PR_KYRIE),100,10,skill_get_time2(SL_KAIZEL,j)); - return 0; - } - if (sd->state.snovice_dead_flag == 1) - { - pc_setstand(sd); - status_change_clear(&sd->bl,0); - clif_skill_nodamage(&sd->bl,&sd->bl,ALL_RESURRECTION,1,1); - status_percent_heal(&sd->bl, 100, 100); - clif_resurrection(&sd->bl, 1); - sd->state.snovice_dead_flag = 2; - if(battle_config.pc_invincible_time) - pc_setinvincibletimer(sd, battle_config.pc_invincible_time); - sc_start(&sd->bl,status_skill2sc(MO_STEELBODY),100,1,skill_get_time(MO_STEELBODY,1)); - return 0; + return 1|8; } //Reset "can log out" tick. diff --git a/src/map/pc.h b/src/map/pc.h index a8f0b57df..ccd6d0e95 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -88,7 +88,7 @@ struct map_session_data { unsigned rest : 1; unsigned storage_flag : 2; //0: closed, 1: Normal Storage open, 2: guild storage open [Skotlex] unsigned snovice_call_flag : 2; //Summon Angel (stage 1~3) - unsigned snovice_dead_flag : 2; //Explosion spirits on death: 0 off, 1 active, 2 used. + unsigned snovice_dead_flag : 1; //Explosion spirits on death: 0 off, 1 used. unsigned abra_flag : 1; // Abracadabra bugfix by Aru unsigned autotrade : 1; //By Fantik unsigned reg_dirty : 3; //By Skotlex (marks whether registry variables have been saved or not yet) diff --git a/src/map/skill.c b/src/map/skill.c index 7222f618e..47b25a0ef 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -6419,6 +6419,19 @@ struct skill_unit_group* skill_unitsetting (struct block_list *src, short skilli safestrncpy(group->valstr, "Boo!", MESSAGE_SIZE); } + if (group->state.song_dance) { + if(sd){ + sd->skillid_dance = skillid; + sd->skilllv_dance = skilllv; + } + if ( + sc_start4(src, SC_DANCING, 100, skillid, (int)group, skilllv, + (group->state.song_dance&2?BCT_SELF:0), limit+1000) && + sd && group->state.song_dance&2 && skillid != CG_HERMODE //Hermod is a encore with a warp! + ) + skill_check_pc_partner(sd, skillid, &skilllv, 1, 1); + } + limit = group->limit; for( i = 0; i < layout->count; i++ ) { @@ -6496,18 +6509,6 @@ struct skill_unit_group* skill_unitsetting (struct block_list *src, short skilli return NULL; } - if (group->state.song_dance) { - if(sd){ - sd->skillid_dance = skillid; - sd->skilllv_dance = skilllv; - } - if ( - sc_start4(src, SC_DANCING, 100, skillid, (int)group, skilllv, - (group->state.song_dance&2?BCT_SELF:0), limit+1000) && - sd && group->state.song_dance&2 && skillid != CG_HERMODE //Hermod is a encore with a warp! - ) - skill_check_pc_partner(sd, skillid, &skilllv, 1, 1); - } if (skillid == NJ_TATAMIGAESHI) //Store number of tiles. group->val1 = group->alive_count; diff --git a/src/map/status.c b/src/map/status.c index c30833314..575b6b4ff 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -599,7 +599,6 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s if (!hp && !sp) return 0; - if (target->type == BL_SKILL) return skill_unit_ondamaged((struct skill_unit *)target, src, hp, gettick()); @@ -731,7 +730,6 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s if (battle_config.clear_unit_ondeath && battle_config.clear_unit_ondeath&target->type) skill_clear_unitgroup(target); - status_change_clear(target,0); if(target->type&BL_REGEN) { //Reset regen ticks. @@ -744,6 +742,18 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s memset(®en->ssregen->tick, 0, sizeof(regen->ssregen->tick)); } } + + if (!(flag&8) && sc && sc->data[SC_KAIZEL]) { //flag&8 = disable Kaizel + int time = skill_get_time2(SL_KAIZEL,sc->data[SC_KAIZEL]->val1); + status_revive(target, sc->data[SC_KAIZEL]->val2, 0); + status_change_clear(target,0); + clif_skill_nodamage(target,target,ALL_RESURRECTION,1,1); + sc_start(target,status_skill2sc(PR_KYRIE),100,10,time); + return hp+sp; + } + + status_change_clear(target,0); + if(flag&4) //Delete from memory. (also invokes map removal code) unit_free(target,1); else @@ -5031,12 +5041,13 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val break; case SC_ENDURE: val2 = 7; // Hit-count [Celest] - if (!(flag&1) && sd && !map_flag_gvg(bl->m)) - { + if (!(flag&1) && sd && !map_flag_gvg(bl->m) && (type != SC_ENDURE || !val4)) + { //See if there are devoted characters, and pass the status to them. [Skotlex] + //(but do not pass infinite endure) struct map_session_data *tsd; int i; for (i = 0; i < 5; i++) - { //See if there are devoted characters, and pass the status to them. [Skotlex] + { if (sd->devotion[i] && (tsd = map_id2sd(sd->devotion[i]))) status_change_start(&tsd->bl,type,10000,val1,val2,val3,val4,tick,1); } @@ -6209,6 +6220,8 @@ int status_change_clear(struct block_list* bl, int type) case SC_READYTURN: case SC_DODGE: case SC_JAILED: + case SC_EXPBOOST: + case SC_ITEMBOOST: continue; } diff --git a/src/map/vending.c b/src/map/vending.c index 935971b16..0420d5288 100644 --- a/src/map/vending.c +++ b/src/map/vending.c @@ -42,7 +42,6 @@ void vending_closevending(struct map_session_data* sd) void vending_vendinglistreq(struct map_session_data* sd, int id) { struct map_session_data* vsd; - nullpo_retv(sd); if( (vsd = map_id2sd(id)) == NULL ) @@ -50,6 +49,12 @@ void vending_vendinglistreq(struct map_session_data* sd, int id) if( vsd->vender_id == 0 ) return; // not vending + if ( !pc_can_give_items(pc_isGM(sd)) || !pc_can_give_items(pc_isGM(vsd)) ) //check if both GMs are allowed to trade + { // GM is not allowed to trade + clif_displaymessage(sd->fd, msg_txt(246)); + return; + } + clif_vendinglist(sd, id, vsd->vending); } -- cgit v1.2.3-60-g2f50