From a06e53479131c25ce2343c431c688c57b3bfa2c0 Mon Sep 17 00:00:00 2001 From: Michieru Date: Fri, 29 Aug 2014 17:51:30 +0200 Subject: Fix status def calculation (bug:8306) Updated script command 'sc_start' to allow for more variables and options rAthena 17326 (bug:8217) Fix Cart Tornado damage to official elemental crashing/memory error (thanks to Ind) --- src/map/script.c | 148 +++++++++++++++++++++---------------------------------- 1 file changed, 55 insertions(+), 93 deletions(-) (limited to 'src/map/script.c') 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 ,,{,}; -BUILDIN(sc_start) { +/* Starts a status effect on the target unit or on the attached player. + * + * sc_start ,,{,,,{}}; + * sc_start2 ,,,{,,{}}; + * sc_start4 ,,,,,{,,{}}; + * + * &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 ,,,{,}; -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 ,,,,,{,}; -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?"), -- cgit v1.2.3-60-g2f50