- Removed status_get_sc_tick, duration and chance are now both handled by status_get_sc_def

- Fixed mob-kill experience getting screwed up when characters who did damage die/logout at the moment the mob dies.


git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@8619 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
skotlex 2006-09-04 19:06:46 +00:00
parent 9e07adc071
commit 19d37b82d0
3 changed files with 62 additions and 110 deletions

View File

@ -4,6 +4,11 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO
IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK. IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
2006/09/04 2006/09/04
* Removed status_get_sc_tick, duration and chance are now both handled by
status_get_sc_def (this means status change duration and success rate
both will always follow the very same formula) [Skotlex]
* Fixed mob-kill experience getting screwed up when characters who did
damage die/logout at the moment the mob dies. [Skotlex]
* Should have fixed "sleep", thanks to Lance for figuring out the error. * Should have fixed "sleep", thanks to Lance for figuring out the error.
[Skotlex] [Skotlex]
* SC_REFLECTSHIELD will now be passed to devoted characters at cast-time. * SC_REFLECTSHIELD will now be passed to devoted characters at cast-time.

View File

@ -1750,24 +1750,25 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
} }
} }
for(temp=0,i=0,mvp_damage=0;i<DAMAGELOG_SIZE && md->dmglog[i].id;i++) for(i=0,mvp_damage=0;i<DAMAGELOG_SIZE && md->dmglog[i].id;i++)
{ {
tmpbl[temp] = (struct block_list*)map_id2bl(md->dmglog[i].id); tmpbl[i] = map_id2bl(md->dmglog[i].id);
if(tmpbl[temp] == NULL) if(tmpbl[i] == NULL)
continue; continue;
if( (tmpbl[temp])->m != md->bl.m || status_isdead(tmpbl[temp])) if( (tmpbl[i])->m != md->bl.m || status_isdead(tmpbl[i]))
{
tmpbl[i] = NULL;
continue; continue;
}
if(mvp_damage<(unsigned int)md->dmglog[i].dmg){ if(mvp_damage<(unsigned int)md->dmglog[i].dmg){
third_sd = second_sd; third_sd = second_sd;
second_sd = mvp_sd; second_sd = mvp_sd;
if ( (tmpbl[temp])->type == BL_HOM ) { if ( (tmpbl[i])->type == BL_HOM )
mvp_sd = (struct map_session_data *) ((struct homun_data *)tmpbl[temp])->master ; mvp_sd=((struct homun_data *)tmpbl[i])->master ;
} else else
mvp_sd=(struct map_session_data *)tmpbl[temp]; mvp_sd=(struct map_session_data *)tmpbl[i];
mvp_damage=md->dmglog[i].dmg; mvp_damage=md->dmglog[i].dmg;
} }
temp++; // [Lance]
} }
count = i; //Total number of attackers. count = i; //Total number of attackers.
@ -1777,16 +1778,15 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
(!map[md->bl.m].flag.nobaseexp || !map[md->bl.m].flag.nojobexp) //Gives Exp (!map[md->bl.m].flag.nobaseexp || !map[md->bl.m].flag.nojobexp) //Gives Exp
) { //Experience calculation. ) { //Experience calculation.
for(i=0;i<DAMAGELOG_SIZE && tmpbl[i];i++){ for(i=0;i<DAMAGELOG_SIZE && md->dmglog[i].id;i++){
int flag=1,zeny=0; int flag=1,zeny=0;
unsigned int base_exp,job_exp; unsigned int base_exp,job_exp;
double per; //Your share of the mob's exp double per; //Your share of the mob's exp
double jper; //For the job-exp double jper; //For the job-exp
int bonus; //Bonus on top of your share. int bonus; //Bonus on top of your share.
if (status_isdead(tmpbl[i]) || tmpbl[i]->m != md->bl.m) if (!tmpbl[i]) continue;
continue; //When someone is dead or on another map, their share of exp is gone.
if (!battle_config.exp_calc_type && md->tdmg) if (!battle_config.exp_calc_type && md->tdmg)
//jAthena's exp formula based on total damage. //jAthena's exp formula based on total damage.
per = (double)md->dmglog[i].dmg/(double)md->tdmg; per = (double)md->dmglog[i].dmg/(double)md->tdmg;

View File

@ -3146,7 +3146,7 @@ static unsigned short status_calc_agi(struct block_list *bl, struct status_chang
if(sc->data[SC_INCREASING].timer!=-1) if(sc->data[SC_INCREASING].timer!=-1)
agi += 4; // added based on skill updates [Reddozen] agi += 4; // added based on skill updates [Reddozen]
if(sc->data[SC_DECREASEAGI].timer!=-1) if(sc->data[SC_DECREASEAGI].timer!=-1)
agi -= 2 + sc->data[SC_DECREASEAGI].val1; agi -= sc->data[SC_DECREASEAGI].val2;
if(sc->data[SC_QUAGMIRE].timer!=-1) if(sc->data[SC_QUAGMIRE].timer!=-1)
agi -= sc->data[SC_QUAGMIRE].val2; agi -= sc->data[SC_QUAGMIRE].val2;
if(sc->data[SC_SUITON].timer!=-1 && sc->data[SC_SUITON].val3) // does not affect players when not in PVP nor WoE. Does not affect Ninjas. if(sc->data[SC_SUITON].timer!=-1 && sc->data[SC_SUITON].val3) // does not affect players when not in PVP nor WoE. Does not affect Ninjas.
@ -4398,88 +4398,6 @@ int status_get_sc_def(struct block_list *bl, int type)
return sc_def>10000?10000:sc_def; return sc_def>10000?10000:sc_def;
} }
//Reduces tick delay based on type and character defenses.
int status_get_sc_tick(struct block_list *bl, int type, int tick)
{
struct map_session_data *sd;
struct status_data* status;
int rate=0, min=0;
//If rate is positive, it is a % reduction (10000 -> 100%)
//if it is negative, it is an absolute reduction in ms.
BL_CAST(BL_PC,bl,sd);
status = status_get_status_data(bl);
switch (type) {
case SC_DECREASEAGI: /* ¬“xŒ¸<C592>­ */
if (sd) // Celest
tick>>=1;
break;
case SC_ADRENALINE:
case SC_ADRENALINE2:
case SC_WEAPONPERFECTION:
case SC_OVERTHRUST:
if(sd && pc_checkskill(sd,BS_HILTBINDING)>0)
tick += tick / 10;
break;
case SC_DPOISON:
case SC_POISON:
case SC_STUN:
case SC_BLEEDING:
case SC_SILENCE:
case SC_CURSE:
rate = 100*status->vit;
break;
case SC_SLEEP:
rate = 100*status->int_;
break;
case SC_STONE:
rate = -200*status->mdef;
break;
case SC_FREEZE:
rate = 100*status->mdef;
break;
case SC_BLIND:
rate = 50*status->vit +50*status->int_;
break;
case SC_CONFUSION:
rate = 50*status->str +50*status->int_;
break;
case SC_SWOO:
if (status->mode&MD_BOSS)
tick /= 5; //TODO: Reduce skill's duration. But for how long?
break;
case SC_ANKLE:
if(status->mode&MD_BOSS) // Lasts 5 times less on bosses
tick /= 5;
rate = -100*status->agi;
// Minimum trap time of 3+0.03*skilllv seconds [celest]
// Changed to 3 secs and moved from skill.c [Skotlex]
min = 3000;
break;
case SC_SPIDERWEB:
if (map[bl->m].flag.pvp)
tick /=2;
break;
}
if (rate) {
if (bl->type == BL_PC) {
if (battle_config.pc_sc_def_rate != 100)
rate = rate*battle_config.pc_sc_def_rate/100;
if (battle_config.pc_max_sc_def != 10000)
min = tick*(10000-battle_config.pc_max_sc_def)/10000;
} else {
if (battle_config.mob_sc_def_rate != 100)
rate = rate*battle_config.mob_sc_def_rate/100;
if (battle_config.mob_max_sc_def != 10000)
min = tick*(10000-battle_config.mob_max_sc_def)/10000;
}
if (rate >0)
tick -= tick*rate/10000;
else
tick += rate;
}
return tick<min?min:tick;
}
/*========================================== /*==========================================
* Starts a status change. * Starts a status change.
* type = type, val1~4 depend on the type. * type = type, val1~4 depend on the type.
@ -4525,22 +4443,21 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val
} }
//Check rate //Check rate
if (!(flag&(4|1))) { if (!(flag&(1|4))) {
int def; int def = flag&(2|8)?status_get_sc_def(bl, type):0;
def = flag&8?0:status_get_sc_def(bl, type); //recycling race to store the sc_def value.
if (def) if (def && !(flag&8))
rate -= rate*def/10000; rate -= rate*def/10000;
if (!(rand()%10000 < rate)) if (!(rand()%10000 < rate))
return 0; return 0;
}
if (def && tick && !(flag&2))
//SC duration reduction. {
if(!(flag&(2|4)) && tick) { tick -= rate*def/10000;
tick = status_get_sc_tick(bl, type, tick); if (tick <= 0)
if (tick <= 0) return 0;
return 0; }
} }
undead_flag=battle_check_undead(status->race,status->def_ele); undead_flag=battle_check_undead(status->race,status->def_ele);
@ -4850,7 +4767,11 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val
calc_flag = StatusChangeFlagTable[type]; calc_flag = StatusChangeFlagTable[type];
if(!(flag&4)) //Do not parse val settings when loading SCs if(!(flag&4)) //Do not parse val settings when loading SCs
switch(type){ switch(type){
case SC_ENDURE: /* ƒCƒ“ƒfƒ…ƒA */ case SC_DECREASEAGI:
val2 = 2 + val1; //Agi decrease
if (sd) tick>>=1; //Half duration for players.
break;
case SC_ENDURE:
val2 = 7; // Hit-count [Celest] val2 = 7; // Hit-count [Celest]
break; break;
case SC_AUTOBERSERK: case SC_AUTOBERSERK:
@ -5516,6 +5437,10 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val
val3 = 300; val3 = 300;
else else
val3 = 200; val3 = 200;
case SC_WEAPONPERFECTION:
case SC_OVERTHRUST:
if(sd && pc_checkskill(sd,BS_HILTBINDING)>0)
tick += tick / 10;
break; break;
case SC_CONCENTRATION: case SC_CONCENTRATION:
val2 = 5*val1; //Batk/Watk Increase val2 = 5*val1; //Batk/Watk Increase
@ -5614,6 +5539,28 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val
val2= 30*val1; //Vit increase val2= 30*val1; //Vit increase
val3= 20*val1; //Int increase val3= 20*val1; //Int increase
break; break;
case SC_SWOO:
if(status->mode&MD_BOSS)
tick /= 5; //TODO: Reduce skill's duration. But for how long?
break;
case SC_ANKLE:
if (sd && battle_config.pc_sc_def_rate != 100)
tick -= tick*status->agi*battle_config.pc_sc_def_rate/10000;
else if (battle_config.mob_sc_def_rate != 100)
tick -= tick*status->agi*battle_config.mob_sc_def_rate/10000;
else
tick -= tick*status->agi/100;
if(status->mode&MD_BOSS) // Lasts 5 times less on bosses
tick /= 5;
// Minimum trap time of 3+0.03*skilllv seconds [celest]
// Changed to 3 secs and moved from skill.c [Skotlex]
if (tick < 3000)
tick = 3000;
break;
case SC_SPIDERWEB:
if (map[bl->m].flag.pvp)
tick /=2;
break;
case SC_ARMOR_ELEMENT: case SC_ARMOR_ELEMENT:
break; // It just change the armor element of the player (used by battle_attr_fix) break; // It just change the armor element of the player (used by battle_attr_fix)
// So it has no SCB and no skill associated (used by potion scripts) // So it has no SCB and no skill associated (used by potion scripts)