diff options
Diffstat (limited to 'src/map')
-rw-r--r-- | src/map/battle.c | 7 | ||||
-rw-r--r-- | src/map/elemental.c | 3 | ||||
-rw-r--r-- | src/map/script.c | 148 | ||||
-rw-r--r-- | src/map/status.c | 48 |
4 files changed, 69 insertions, 137 deletions
diff --git a/src/map/battle.c b/src/map/battle.c index edc7b38e5..b869ad47c 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -1396,7 +1396,7 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block int i; struct status_change *sc, *tsc; struct map_session_data *sd, *tsd; - struct status_data *st, *tst; + struct status_data *st, *tst, *bst; nullpo_ret(src); nullpo_ret(target); @@ -1406,6 +1406,7 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block sc = status->get_sc(src); tsc = status->get_sc(target); st = status->get_status_data(src); + bst = status->get_base_status(src); tst = status->get_status_data(target); switch(attack_type){ @@ -2411,9 +2412,7 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block break; case GN_CART_TORNADO: { - int strbonus = st->str; // FIXME Supposed to take only base STR, but current code wont allow that. So well just take STR for now. [Rytech] - if ( strbonus > 130 ) // Max base stat limit on official is 130. So well allow no higher then 125 STR here. This limit prevents - strbonus = 130; // the division from going any lower then 30 so the server wont divide by 0 if someone has 150 STR. + int strbonus = bst->str; skillratio = 50 * skill_lv + (sd ? sd->cart_weight : battle_config.max_cart_weight) / 10 / (150 - strbonus) + 50 * (sd ? pc->checkskill(sd, GN_REMODELING_CART) : 5); } break; diff --git a/src/map/elemental.c b/src/map/elemental.c index caba02692..b594c8899 100644 --- a/src/map/elemental.c +++ b/src/map/elemental.c @@ -218,6 +218,9 @@ int elemental_delete(struct elemental_data *ed, int reply) { sd->ed = NULL; sd->status.ele_id = 0; + if( !ed->bl.prev ) + return unit->free(&ed->bl, 0); + return unit->remove_map(&ed->bl, 0, ALC_MARK); } diff --git a/src/map/script.c b/src/map/script.c index ecd12a3c1..2f0aa5831 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -10039,118 +10039,80 @@ BUILDIN(hideonnpc) return true; } -/// Starts a status effect on the target unit or on the attached player. -/// -/// sc_start <effect_id>,<duration>,<val1>{,<unit_id>}; -BUILDIN(sc_start) { +/* Starts a status effect on the target unit or on the attached player. + * + * sc_start <effect_id>,<duration>,<val1>{,<rate>,<flag>,{<unit_id>}}; + * sc_start2 <effect_id>,<duration>,<val1>,<val2>{,<rate,<flag>,{<unit_id>}}; + * sc_start4 <effect_id>,<duration>,<val1>,<val2>,<val3>,<val4>{,<rate,<flag>,{<unit_id>}}; + * <flag> + * &1: Cannot be avoided (it has to start) + * &2: Tick should not be reduced (by vit, luk, lv, etc) + * &4: sc_data loaded, no value has to be altered. + * &8: rate should not be reduced + */ +BUILDIN(sc_start) +{ + TBL_NPC * nd = map->id2nd(st->oid); struct block_list* bl; enum sc_type type; - int tick; - int val1; - int val4 = 0; + int tick, val1, val2, val3, val4=0, rate, flag; + char start_type; + const char* command = script_getfuncname(st); + + if(strstr(command, "4")) + start_type = 4; + else if(strstr(command, "2")) + start_type = 2; + else + start_type = 1; type = (sc_type)script_getnum(st,2); tick = script_getnum(st,3); val1 = script_getnum(st,4); - if( script_hasdata(st,5) ) - bl = map->id2bl(script_getnum(st,5)); - else - bl = map->id2bl(st->rid); - - if( tick == 0 && val1 > 0 && type > SC_NONE && type < SC_MAX && status->sc2skill(type) != 0 ) { - // When there isn't a duration specified, try to get it from the skill_db - tick = skill->get_time(status->sc2skill(type), val1); - } - if( script->potion_flag == 1 && script->potion_target ) { - //skill.c set the flags before running the script, this must be a potion-pitched effect. - bl = map->id2bl(script->potion_target); - tick /= 2;// Thrown potions only last half. - val4 = 1;// Mark that this was a thrown sc_effect - } - - if( bl ) - status->change_start(NULL, bl, type, 10000, val1, 0, 0, val4, tick, 2); - - return true; -} + //If from NPC we make default flag 1 to be unavoidable + if(nd && nd->bl.id == npc->fake_nd->bl.id) + flag = script_hasdata(st,5+start_type)?script_getnum(st,5+start_type):2; + else + flag = script_hasdata(st,5+start_type)?script_getnum(st,5+start_type):1; -/// Starts a status effect on the target unit or on the attached player. -/// -/// sc_start2 <effect_id>,<duration>,<val1>,<percent chance>{,<unit_id>}; -BUILDIN(sc_start2) { - struct block_list* bl; - enum sc_type type; - int tick; - int val1; - int val4 = 0; - int rate; + rate = script_hasdata(st,4+start_type)?min(script_getnum(st,4+start_type),10000):10000; - type = (sc_type)script_getnum(st,2); - tick = script_getnum(st,3); - val1 = script_getnum(st,4); - rate = script_getnum(st,5); - if( script_hasdata(st,6) ) - bl = map->id2bl(script_getnum(st,6)); + if(script_hasdata(st,(6+start_type))) + bl = map->id2bl(script_getnum(st,(6+start_type))); else bl = map->id2bl(st->rid); - if( tick == 0 && val1 > 0 && type > SC_NONE && type < SC_MAX && status->sc2skill(type) != 0 ) { - // When there isn't a duration specified, try to get it from the skill_db + if(tick == 0 && val1 > 0 && type > SC_NONE && type < SC_MAX && status->sc2skill(type) != 0) + {// When there isn't a duration specified, try to get it from the skill_db tick = skill->get_time(status->sc2skill(type), val1); } - if( script->potion_flag == 1 && script->potion_target ) { - //skill.c set the flags before running the script, this must be a potion-pitched effect. + if(script->potion_flag == 1 && script->potion_target) { //skill.c set the flags before running the script, this is a potion-pitched effect. bl = map->id2bl(script->potion_target); tick /= 2;// Thrown potions only last half. val4 = 1;// Mark that this was a thrown sc_effect } - if( bl ) - status->change_start(NULL, bl, type, rate, val1, 0, 0, val4, tick, 2); - - return true; -} - -/// Starts a status effect on the target unit or on the attached player. -/// -/// sc_start4 <effect_id>,<duration>,<val1>,<val2>,<val3>,<val4>{,<unit_id>}; -BUILDIN(sc_start4) { - struct block_list* bl; - enum sc_type type; - int tick; - int val1; - int val2; - int val3; - int val4; - - type = (sc_type)script_getnum(st,2); - tick = script_getnum(st,3); - val1 = script_getnum(st,4); - val2 = script_getnum(st,5); - val3 = script_getnum(st,6); - val4 = script_getnum(st,7); - if( script_hasdata(st,8) ) - bl = map->id2bl(script_getnum(st,8)); - else - bl = map->id2bl(st->rid); - - if( tick == 0 && val1 > 0 && type > SC_NONE && type < SC_MAX && status->sc2skill(type) != 0 ) { - // When there isn't a duration specified, try to get it from the skill_db - tick = skill->get_time(status->sc2skill(type), val1); - } + if(!bl) + return 0; - if( script->potion_flag == 1 && script->potion_target ) { - //skill.c set the flags before running the script, this must be a potion-pitched effect. - bl = map->id2bl(script->potion_target); - tick /= 2;// Thrown potions only last half. + switch(start_type) { + case 1: + status->change_start(bl, bl, type, rate, val1, 0, 0, val4, tick, flag); + break; + case 2: + val2 = script_getnum(st,5); + status->change_start(bl, bl, type, rate, val1, val2, 0, val4, tick, flag); + break; + case 4: + val2 = script_getnum(st,5); + val3 = script_getnum(st,6); + val4 = script_getnum(st,7); + status->change_start(bl, bl, type, rate, val1, val2, val3, val4, tick, flag); + break; } - - if( bl ) - status->change_start(NULL, bl, type, 10000, val1, val2, val3, val4, tick, 2); - - return true; + return 0; } /// Ends one or all status effects on the target unit or on the attached player. @@ -18926,9 +18888,9 @@ void script_parse_builtin(void) { BUILDIN_DEF(disablenpc,"s"), BUILDIN_DEF(hideoffnpc,"s"), BUILDIN_DEF(hideonnpc,"s"), - BUILDIN_DEF(sc_start,"iii?"), - BUILDIN_DEF(sc_start2,"iiii?"), - BUILDIN_DEF(sc_start4,"iiiiii?"), + BUILDIN_DEF(sc_start,"iii???"), + BUILDIN_DEF2(sc_start,"sc_start2","iiii???"), + BUILDIN_DEF2(sc_start,"sc_start4","iiiiii???"), BUILDIN_DEF(sc_end,"i?"), BUILDIN_DEF(getstatus, "i?"), BUILDIN_DEF(getscrate,"ii?"), diff --git a/src/map/status.c b/src/map/status.c index 25376b4b0..718deaefc 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -6294,9 +6294,9 @@ int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_typ int sc_def = 0, tick_def = -1; //-1 = use sc_def //Linear resistance substracted from rate and tick after percentual resistance was applied //Example: 25% -> sc_def2=2000 -> 5%; 2500ms -> tick_def2=2000 -> 500ms - int sc_def2 = 0, tick_def2 = -1; //-1 = use sc_def2 (pre-re only) + int sc_def2 = 0, tick_def2 = 0; - struct status_data *st; + struct status_data *st, *bst; struct status_change *sc; struct map_session_data *sd; @@ -6307,14 +6307,8 @@ int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_typ /// Returns the 'bl's level, capped to 'cap' #define SCDEF_LVL_CAP(bl, cap) ( (bl) ? (status->get_lv(bl) > (cap) ? (cap) : status->get_lv(bl)) : 0 ) -/// Renewal level modifier. -/// In renewal, returns the difference between the levels of 'bl' and 'src', both capped to 'maxlv', multiplied by 'factor' -/// In pre-renewal, returns zero. -#ifdef RENEWAL +/// returns the difference between the levels of 'bl' and 'src', both capped to 'maxlv', multiplied by 'factor' #define SCDEF_LVL_DIFF(bl, src, maxlv, factor) ( ( SCDEF_LVL_CAP((bl), (maxlv)) - SCDEF_LVL_CAP((src), (maxlv)) ) * (factor) ) -#else -#define SCDEF_LVL_DIFF(bl, src, maxlv, factor) 0 -#endif //Status that are blocked by Golden Thief Bug card or Wand of Hermod if (status->isimmune(bl)) @@ -6353,6 +6347,7 @@ int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_typ sd = BL_CAST(BL_PC,bl); st = status->get_status_data(bl); + bst = status_get_base_status(bl); sc = status->get_sc(bl); if( sc && !sc->count ) sc = NULL; @@ -6394,7 +6389,6 @@ int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_typ case SC_DPOISON: sc_def = st->vit*100; sc_def2 = st->luk*10 + SCDEF_LVL_DIFF(bl, src, 99, 10); -#ifdef RENEWAL if (sd) { //For players: 60000 - 450*vit - 100*luk tick_def = st->vit*75; @@ -6404,7 +6398,6 @@ int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_typ tick>>=1; tick_def = (st->vit*200)/3; } -#endif break; case SC_SILENCE: #ifdef RENEWAL @@ -6428,14 +6421,12 @@ int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_typ case SC_SLEEP: sc_def = st->int_*100; sc_def2 = st->luk*10 + SCDEF_LVL_DIFF(bl, src, 99, 10); -#ifdef RENEWAL tick_def2 = st->luk*10; -#endif break; case SC_DEEP_SLEEP: - sc_def = st->int_*50; + sc_def = bst->int_*50; tick_def = 0; // Linear reduction instead - tick_def2 = st->int_ * 50 + SCDEF_LVL_CAP(bl, 150) * 50; // kRO balance update lists this formula + tick_def2 = bst->int_ * 50 + SCDEF_LVL_CAP(bl, 150) * 50; // kRO balance update lists this formula break; case SC_DEC_AGI: case SC_ADORAMUS: @@ -6451,19 +6442,11 @@ int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_typ sc_def = st->mdef*100; sc_def2 = st->luk*10 + SCDEF_LVL_DIFF(bl, src, 99, 10); tick_def = 0; //No duration reduction -#ifndef RENEWAL - tick_def2 = 0; //No duration reduction -#endif break; case SC_FREEZE: sc_def = st->mdef*100; sc_def2 = st->luk*10 + SCDEF_LVL_DIFF(bl, src, 99, 10); - tick_def = 0; //No duration reduction -#ifdef RENEWAL tick_def2 = status_get_luk(src) * -10; //Caster can increase final duration with luk -#else - tick_def2 = 0; //No duration reduction -#endif break; case SC_CURSE: // Special property: immunity when luk is zero @@ -6477,24 +6460,17 @@ int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_typ sc_def = st->luk*100; sc_def2 = st->luk*10 + SCDEF_LVL_DIFF(NULL, src, 99, 10); // Curse only has a level penalty and no resistance tick_def = st->vit*100; -#ifdef RENEWAL tick_def2 = st->luk*10; -#endif break; case SC_BLIND: sc_def = (st->vit + st->int_)*50; sc_def2 = st->luk*10 + SCDEF_LVL_DIFF(bl, src, 99, 10); -#ifdef RENEWAL tick_def2 = st->luk*10; -#endif break; case SC_CONFUSION: sc_def = (st->str + st->int_)*50; sc_def2 = st->luk*10 + SCDEF_LVL_DIFF(bl, src, 99, 10); -#ifdef RENEWAL - sc_def2 = -sc_def2; // Reversed sc_def2 tick_def2 = st->luk*10; -#endif break; case SC_ANKLESNARE: if(st->mode&MD_BOSS) // Lasts 5 times less on bosses @@ -6506,7 +6482,6 @@ int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_typ if (sd) //Duration greatly reduced for players. tick /= 15; sc_def2 = st->vit*25 + st->agi*10 + SCDEF_LVL_CAP(bl, 99) * 20; // Linear Reduction of Rate - tick_def2 = 0; //No duration reduction break; case SC_MARSHOFABYSS: //5 second (Fixed) + 25 second - {( INT + LUK ) / 20 second } @@ -6548,10 +6523,10 @@ int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_typ tick_def2 = (st->vit + st->agi) * 70; break; case SC_COLD: - tick_def2 = st->vit*100 + status->get_lv(bl)*20; + tick_def2 = bst->vit*100 + status->get_lv(bl)*20; break; case SC_VACUUM_EXTREME: - tick_def2 = st->str*50; + tick_def2 = bst->str*50; break; case SC_MANDRAGORA: sc_def = (st->vit + st->luk)*20; @@ -6612,13 +6587,6 @@ int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_typ //When tick def not set, reduction is the same for both. if(tick_def == -1) tick_def = sc_def; - if(tick_def2 == -1) { -#ifdef RENEWAL - tick_def2 = 0; -#else - tick_def2 = sc_def2; -#endif - } //Natural resistance if (!(flag&8)) { |