summaryrefslogtreecommitdiff
path: root/src/map/script.c
diff options
context:
space:
mode:
authorMichieru <Michieru@users.noreply.github.com>2014-08-29 17:51:30 +0200
committerMichieru <Michieru@users.noreply.github.com>2014-08-29 17:51:30 +0200
commita06e53479131c25ce2343c431c688c57b3bfa2c0 (patch)
tree2c7e97912c83d029efc1e0461ccaa4ddd46bc50d /src/map/script.c
parentb9511727e6a754ad5a11d21d30df98451c2dd69c (diff)
downloadhercules-a06e53479131c25ce2343c431c688c57b3bfa2c0.tar.gz
hercules-a06e53479131c25ce2343c431c688c57b3bfa2c0.tar.bz2
hercules-a06e53479131c25ce2343c431c688c57b3bfa2c0.tar.xz
hercules-a06e53479131c25ce2343c431c688c57b3bfa2c0.zip
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)
Diffstat (limited to 'src/map/script.c')
-rw-r--r--src/map/script.c148
1 files changed, 55 insertions, 93 deletions
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?"),