summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changelog-Trunk.txt8
-rw-r--r--conf-tmpl/battle/skill.conf8
-rw-r--r--src/map/battle.c5
-rw-r--r--src/map/battle.h2
-rw-r--r--src/map/pc.c64
-rw-r--r--src/map/skill.c5
-rw-r--r--src/map/status.c2
7 files changed, 67 insertions, 27 deletions
diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt
index 6431a1046..8dedb9f27 100644
--- a/Changelog-Trunk.txt
+++ b/Changelog-Trunk.txt
@@ -5,6 +5,14 @@ IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK. EV
GOES INTO TRUNK AND WILL BE MERGED INTO STABLE BY VALARIS AND WIZPUTER. -- VALARIS
2006/02/08
+ * Added battle config option skill_caster_check, which does a
+ status_checkskilluse on all skill attacks. When enabled (default on) the
+ caster of the skill is checked on all skill_attacks, which means that
+ ground spells will make no effect if the caster is unable to fight
+ (stunned, frozen, etc) [Skotlex]
+ * Added battle config option status_cast_cancel. When enabled (default off)
+ some status changes (freeze, stone, etc) will cancel your cast. [Skotlex]
+ * Fixed the death exp penalty underflow bug. [Skotlex]
* Rewrote/organized status_change_start, it now receives the base rate for
the effect. It handles reducing this rate/duration through natural
resistances and whatever else should reduce it. [Skotlex]
diff --git a/conf-tmpl/battle/skill.conf b/conf-tmpl/battle/skill.conf
index 570db542f..ce2f334d2 100644
--- a/conf-tmpl/battle/skill.conf
+++ b/conf-tmpl/battle/skill.conf
@@ -72,6 +72,14 @@ skillrange_by_distance: 6
// NOTE: Skills affected by this option are those whose range in the skill_db are negative.
skillrange_from_weapon: no
+// Should a check on the caster's status be performed in all skill attacks?
+// When set to yes, meteors, storm gust and any other ground skills will have
+// no effect while the caster is unable to fight (eg: stunned).
+skill_caster_check: yes
+
+// Should skill casting be cancelled when inflicted by curse/stun/sleep/etc?
+status_cast_cancel: no
+
//Setting this to YES will override the target mode of ground-based skills with the flag 0x01 to "No Enemies"
//The two skills affected by default are Pneuma and Safety Wall (if set to yes, those two skills will not protect everyone, but only allies)
//See db/skill_unit_db.txt for more info.
diff --git a/src/map/battle.c b/src/map/battle.c
index 808f8dbb7..354dc0d88 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -3822,6 +3822,8 @@ static const struct battle_data_short {
{ "skip_teleport_lv1_menu", &battle_config.skip_teleport_lv1_menu}, // [LuzZza]
{ "allow_skill_without_day", &battle_config.allow_skill_without_day}, // [Komurka]
+ { "skill_caster_check", &battle_config.skill_caster_check },
+ { "status_cast_cancel", &battle_config.sc_castcancel },
};
static const struct battle_data_int {
@@ -4207,6 +4209,9 @@ void battle_set_defaults() {
battle_config.skip_teleport_lv1_menu = 0;
battle_config.allow_skill_without_day = 0;
+
+ battle_config.skill_caster_check = 1;
+ battle_config.sc_castcancel = 0;
}
void battle_validate_conf() {
diff --git a/src/map/battle.h b/src/map/battle.h
index e59cd9bd2..353ba7bc1 100644
--- a/src/map/battle.h
+++ b/src/map/battle.h
@@ -416,6 +416,8 @@ extern struct Battle_Config {
unsigned short allow_skill_without_day; // [Komurka]
unsigned short skill_wall_check; // [Skotlex]
unsigned short cell_stack_limit; // [Skotlex]
+ unsigned short skill_caster_check; // [Skotlex]
+ unsigned short sc_castcancel; // [Skotlex]
} battle_config;
void do_init_battle(void);
diff --git a/src/map/pc.c b/src/map/pc.c
index e3c843055..09ed0d7f7 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -5489,33 +5489,47 @@ int pc_damage(struct block_list *src,struct map_session_data *sd,int damage)
&& !map[sd->bl.m].flag.nopenalty && !map_flag_gvg(sd->bl.m)
&& !(sd->sc.count && sd->sc.data[SC_BABY].timer!=-1))
{
- if(battle_config.death_penalty_type==1 && battle_config.death_penalty_base > 0)
- sd->status.base_exp -= (int) ((double)pc_nextbaseexp(sd) * (double)battle_config.death_penalty_base/10000);
- if(battle_config.pk_mode && src && src->type==BL_PC)
- sd->status.base_exp -= (int) ((double)pc_nextbaseexp(sd) * (double)battle_config.death_penalty_base/10000);
- else if(battle_config.death_penalty_type==2 && battle_config.death_penalty_base > 0) {
- if(pc_nextbaseexp(sd) > 0)
- sd->status.base_exp -= (int) ((double)sd->status.base_exp * (double)battle_config.death_penalty_base/10000);
- if(battle_config.pk_mode && src && src->type==BL_PC)
- sd->status.base_exp -= (int) ((double)sd->status.base_exp * (double)battle_config.death_penalty_base/10000);
+ unsigned int base_penalty =0;
+ if (battle_config.death_penalty_base > 0) {
+ switch (battle_config.death_penalty_type) {
+ case 1:
+ base_penalty += (unsigned int) ((double)pc_nextbaseexp(sd) * (double)battle_config.death_penalty_base/10000);
+ break;
+ case 2:
+ base_penalty = (unsigned int) ((double)sd->status.base_exp * (double)battle_config.death_penalty_base/10000);
+ break;
}
- if(sd->status.base_exp < 0)
- sd->status.base_exp = 0;
- clif_updatestatus(sd,SP_BASEEXP);
-
- if(battle_config.death_penalty_type==1 && battle_config.death_penalty_job > 0)
- sd->status.job_exp -= (int) ((double)pc_nextjobexp(sd) * (double)battle_config.death_penalty_job/10000);
- if(battle_config.pk_mode && src && src->type==BL_PC)
- sd->status.job_exp -= (int) ((double)pc_nextjobexp(sd) * (double)battle_config.death_penalty_job/10000);
- else if(battle_config.death_penalty_type==2 && battle_config.death_penalty_job > 0) {
- if(pc_nextjobexp(sd) > 0)
- sd->status.job_exp -= (int) ((double)sd->status.job_exp * (double)battle_config.death_penalty_job/10000);
- if(battle_config.pk_mode && src && src->type==BL_PC)
- sd->status.job_exp -= (int) ((double)sd->status.job_exp * (double)battle_config.death_penalty_job/10000);
+ if(base_penalty) {
+ if (battle_config.pk_mode && src && src->type==BL_PC)
+ base_penalty*=2;
+ if(sd->status.base_exp < base_penalty)
+ sd->status.base_exp = 0;
+ else
+ sd->status.base_exp -= base_penalty;
+ clif_updatestatus(sd,SP_BASEEXP);
}
- if(sd->status.job_exp < 0)
- sd->status.job_exp = 0;
- clif_updatestatus(sd,SP_JOBEXP);
+ }
+ if(battle_config.death_penalty_job > 0)
+ {
+ base_penalty = 0;
+ switch (battle_config.death_penalty_type) {
+ case 1:
+ base_penalty = (unsigned int) ((double)pc_nextjobexp(sd) * (double)battle_config.death_penalty_job/10000);
+ break;
+ case 2:
+ base_penalty = (unsigned int) ((double)sd->status.job_exp * (double)battle_config.death_penalty_job/10000);
+ break;
+ }
+ if(base_penalty) {
+ if (battle_config.pk_mode && src && src->type==BL_PC)
+ base_penalty*=2;
+ if(sd->status.job_exp < base_penalty)
+ sd->status.job_exp = 0;
+ else
+ sd->status.job_exp -= base_penalty;
+ clif_updatestatus(sd,SP_JOBEXP);
+ }
+ }
}
if(src && src->type==BL_MOB) {
struct mob_data *md=(struct mob_data *)src;
diff --git a/src/map/skill.c b/src/map/skill.c
index b9fc9521d..6822c8327 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -1543,7 +1543,10 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds
if(src->prev == NULL || dsrc->prev == NULL || bl->prev == NULL)
return 0;
//When caster is not the src of attack, this is a ground skill, and as such, do the relevant target checking. [Skotlex]
- if (src != dsrc && !status_check_skilluse(NULL, bl, skillid, 1))
+ if (
+ (src != dsrc || battle_config.skill_caster_check) &&
+ !status_check_skilluse(battle_config.skill_caster_check?src:NULL, bl, skillid, 1)
+ )
return 0;
//Note that splash attacks often only check versus the targetted mob, those around the splash area normally don't get checked for being hidden/cloaked/etc. [Skotlex]
diff --git a/src/map/status.c b/src/map/status.c
index 72a5e036a..f9c79cc8c 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -4632,7 +4632,7 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val
battle_stopattack(bl);
skill_stop_dancing(bl); /* 演奏/ダンスの中? */
// Cancel cast when get status [LuzZza]
- if (!sd || sd->skillid != PA_PRESSURE) //Only Pressure cannot be cancelled.
+ if (battle_config.sc_castcancel)
skill_castcancel(bl, 0);
case SC_STOP:
case SC_CONFUSION: