summaryrefslogtreecommitdiff
path: root/src/map/skill.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/skill.c')
-rw-r--r--src/map/skill.c124
1 files changed, 85 insertions, 39 deletions
diff --git a/src/map/skill.c b/src/map/skill.c
index 93eb3bf36..bb0f5fb0f 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -591,6 +591,7 @@ int skillnotok (int skillid, struct map_session_data *sd)
break;
case WM_LULLABY_DEEPSLEEP:
case WM_SIRCLEOFNATURE:
+ case WM_SATURDAY_NIGHT_FEVER:
if( !map_flag_vs(m) ) {
clif_skill_teleportmessage(sd,2); // This skill uses this msg instead of skill fails.
return 1;
@@ -3069,19 +3070,19 @@ static int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data)
do {
if(src->prev == NULL)
- break;
+ break; // Source not on Map
if(skl->target_id) {
target = map_id2bl(skl->target_id);
if( ( skl->skill_id == RG_INTIMIDATE || skl->skill_id == SC_FATALMENACE ) && (!target || target->prev == NULL || !check_distance_bl(src,target,AREA_SIZE)) )
target = src; //Required since it has to warp.
if(target == NULL)
- break;
+ break; // Target offline?
if(target->prev == NULL)
- break;
+ break; // Target not on Map
if(src->m != target->m)
- break;
+ break; // Different Maps
if(status_isdead(src))
- break;
+ break; // Caster is Dead
if(status_isdead(target) && skl->skill_id != RG_INTIMIDATE && skl->skill_id != WZ_WATERBALL)
break;
@@ -8335,7 +8336,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
if( src->id != bl->id && battle_check_target(src,bl,BCT_ENEMY) > 0 )
status_fix_damage(src,bl,9999,clif_damage(src,bl,tick,0,0,9999,0,0,0));
} else if( sd ) {
- if( !sd->status.party_id ) {
+ short chance = sstatus->int_/6 + sd->status.job_level/5 + skilllv*4;
+ if( !sd->status.party_id || (rnd()%100 > chance)) {
clif_skill_fail(sd,skillid,USESKILL_FAIL_NEED_HELPER,0);
break;
}
@@ -11567,6 +11569,23 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
case UNT_EARTH_INSIGNIA:
case UNT_ZEPHYR:
sc_start(bl,type, 100, sg->skill_lv, sg->interval);
+ if (!battle_check_undead(tstatus->race, tstatus->def_ele)) {
+ int hp = tstatus->max_hp / 100; //+1% each 5s
+ if ((sg->val3) % 5) { //each 5s
+ if (tstatus->def_ele == skill_get_ele(sg->skill_id,sg->skill_lv)){
+ status_heal(bl, hp, 0, 2);
+ } else if((sg->unit_id == UNT_FIRE_INSIGNIA && tstatus->def_ele == ELE_EARTH)
+ ||(sg->unit_id == UNT_WATER_INSIGNIA && tstatus->def_ele == ELE_FIRE)
+ ||(sg->unit_id == UNT_WIND_INSIGNIA && tstatus->def_ele == ELE_WATER)
+ ||(sg->unit_id == UNT_EARTH_INSIGNIA && tstatus->def_ele == ELE_WIND)
+ ){
+ status_heal(bl, -hp, 0, 0);
+ }
+ }
+ }
+ sg->val3++; //timer
+ if (sg->val3 > 5)
+ sg->val3 = 0;
break;
case UNT_VACUUM_EXTREME:
@@ -12554,19 +12573,6 @@ int skill_check_condition_castbegin(struct map_session_data* sd, short skill, sh
return 0;
}
break;
- case GC_CROSSRIPPERSLASHER:
- if( !(sc && sc->data[SC_ROLLINGCUTTER]) ) {
- clif_skill_fail(sd, skill, USESKILL_FAIL_CONDITION, 0);
- return 0;
- }
- break;
- case GC_POISONSMOKE:
- case GC_VENOMPRESSURE:
- if( !(sc && sc->data[SC_POISONINGWEAPON]) ) {
- clif_skill_fail(sd, skill, USESKILL_FAIL_GC_POISONINGWEAPON, 0);
- return 0;
- }
- break;
/**
* Ranger
**/
@@ -12848,6 +12854,18 @@ int skill_check_condition_castbegin(struct map_session_data* sd, short skill, sh
return 0;
}
break;
+ case ST_POISONINGWEAPON:
+ if (!(sc && sc->data[SC_POISONINGWEAPON])) {
+ clif_skill_fail(sd, skill, USESKILL_FAIL_GC_POISONINGWEAPON, 0);
+ return 0;
+ }
+ break;
+ case ST_ROLLINGCUTTER:
+ if (!(sc && sc->data[SC_ROLLINGCUTTER])) {
+ clif_skill_fail(sd, skill, USESKILL_FAIL_CONDITION, 0);
+ return 0;
+ }
+ break;
}
if(require.mhp > 0 && get_percentage(status->hp, status->max_hp) > require.mhp) {
@@ -13218,6 +13236,10 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, short
case SO_SUMMON_AQUA:
case SO_SUMMON_VENTUS:
case SO_SUMMON_TERA:
+ case SO_WATER_INSIGNIA:
+ case SO_FIRE_INSIGNIA:
+ case SO_WIND_INSIGNIA:
+ case SO_EARTH_INSIGNIA:
if( i < 3 )
continue;
break;
@@ -13258,6 +13280,10 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, short
case SO_SUMMON_AQUA:
case SO_SUMMON_VENTUS:
case SO_SUMMON_TERA:
+ case SO_WATER_INSIGNIA:
+ case SO_FIRE_INSIGNIA:
+ case SO_WIND_INSIGNIA:
+ case SO_EARTH_INSIGNIA:
req.itemid[lv-1] = skill_db[j].itemid[lv-1];
req.amount[lv-1] = skill_db[j].amount[lv-1];
break;
@@ -13386,7 +13412,10 @@ int skill_castfix (struct block_list *bl, int skill_id, int skill_lv) {
if (battle_config.cast_rate != 100)
time = time * battle_config.cast_rate / 100;
// return final cast time
- return (time > 0) ? time : 0;
+ time = max(time, 0);
+
+// ShowInfo("Castime castfix = %d\n",time);
+ return time;
}
/*==========================================
@@ -13416,8 +13445,10 @@ int skill_castfix_sc (struct block_list *bl, int time)
if (sc->data[SC_IZAYOI])
time -= time * 50 / 100;
}
-
- return (time > 0) ? time : 0;
+ time = max(time, 0);
+
+// ShowInfo("Castime castfix_sc = %d\n",time);
+ return time;
}
#ifdef RENEWAL_CAST
int skill_vfcastfix (struct block_list *bl, double time, int skill_id, int skill_lv)
@@ -13475,6 +13506,8 @@ int skill_vfcastfix (struct block_list *bl, double time, int skill_id, int skill
VARCAST_REDUCTION(sc->data[SC_POEMBRAGI]->val2);
if (sc->data[SC_IZAYOI])
VARCAST_REDUCTION(50);
+ if (sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 3 && (skill_get_ele(skill_id, skill_lv) == ELE_WATER))
+ VARCAST_REDUCTION(30); //Reduces 30% Variable Cast Time of Water spells.
// Fixed cast reduction bonuses
if( sc->data[SC__LAZINESS] )
fixcast_r = max(fixcast_r, sc->data[SC__LAZINESS]->val2);
@@ -13486,7 +13519,7 @@ int skill_vfcastfix (struct block_list *bl, double time, int skill_id, int skill
if( sc->data[SC_MANDRAGORA] && (skill_id >= SM_BASH && skill_id <= RETURN_TO_ELDICASTES) )
fixed += sc->data[SC_MANDRAGORA]->val1 * 1000 / 2;
if (sc->data[SC_IZAYOI] && (skill_id >= NJ_TOBIDOUGU && skill_id <= NJ_ISSEN))
- fixed = 0;
+ fixed = 0;
}
if( sd && !(skill_get_castnodex(skill_id, skill_lv)&4) ){
@@ -13500,7 +13533,8 @@ int skill_vfcastfix (struct block_list *bl, double time, int skill_id, int skill
time = (1 - sqrt( ((float)(status_get_dex(bl)*2 + status_get_int(bl)) / battle_config.vcast_stat_scale) )) * time;
// underflow checking/capping
time = max(time, 0) + (1 - (float)min(fixcast_r, 100) / 100) * fixed;
-
+
+ // ShowInfo("Casttime vfcastfix = %d\n",time);
return (int)time;
}
#endif
@@ -13580,7 +13614,10 @@ int skill_delayfix (struct block_list *bl, int skill_id, int skill_lv)
if (sc && sc->count) {
if (sc->data[SC_POEMBRAGI])
time -= time * sc->data[SC_POEMBRAGI]->val3 / 100;
+ if (sc->data[SC_WIND_INSIGNIA] && sc->data[SC_WIND_INSIGNIA]->val1 == 3 && (skill_get_ele(skill_id, skill_lv) == ELE_WIND))
+ time /= 2; // After Delay of Wind element spells reduced by 50%.
}
+
}
if( !(delaynodex&4) && sd && sd->delayrate != 100 )
@@ -13589,10 +13626,12 @@ int skill_delayfix (struct block_list *bl, int skill_id, int skill_lv)
if (battle_config.delay_rate != 100)
time = time * battle_config.delay_rate / 100;
- if (time < status_get_amotion(bl))
- time = status_get_amotion(bl); // Delay can never be below amotion [Playtester]
-
- return max(time, battle_config.min_skill_delay_limit);
+ //min delay
+ time = max(time, status_get_amotion(bl)); // Delay can never be below amotion [Playtester]
+ time = max(time, battle_config.min_skill_delay_limit);
+
+// ShowInfo("Delay delayfix = %d\n",time);
+ return time;
}
/*=========================================
@@ -17071,16 +17110,8 @@ void skill_cooldown_load(struct map_session_data * sd)
}
/*==========================================
- * DB reading.
+ * sub-function of DB reading.
* skill_db.txt
- * skill_require_db.txt
- * skill_cast_db.txt
- * skill_castnodex_db.txt
- * skill_nocast_db.txt
- * skill_unit_db.txt
- * produce_db.txt
- * create_arrow_db.txt
- * abra_db.txt
*------------------------------------------*/
static bool skill_parse_row_skilldb(char* split[], int columns, int current)
@@ -17148,7 +17179,7 @@ static bool skill_parse_row_requiredb(char* split[], int columns, int current)
skill_split_atoi(split[5],skill_db[i].sp_rate);
skill_split_atoi(split[6],skill_db[i].zeny);
- //FIXME: document this
+ //Wich weapon type are required, see doc/item_db for types
p = split[7];
for( j = 0; j < 32; j++ )
{
@@ -17206,6 +17237,9 @@ static bool skill_parse_row_requiredb(char* split[], int columns, int current)
else if( strcmpi(split[10],"ridingwarg")==0 ) skill_db[i].state = ST_RIDINGWUG;
else if( strcmpi(split[10],"mado")==0 ) skill_db[i].state = ST_MADO;
else if( strcmpi(split[10],"elementalspirit")==0 ) skill_db[i].state = ST_ELEMENTALSPIRIT;
+ else if (strcmpi(split[10], "poisonweapon") == 0) skill_db[i].state = ST_POISONINGWEAPON;
+ else if (strcmpi(split[10], "rollingcutter") == 0) skill_db[i].state = ST_ROLLINGCUTTER;
+
/**
* Unknown or no state
**/
@@ -17215,7 +17249,7 @@ static bool skill_parse_row_requiredb(char* split[], int columns, int current)
for( j = 0; j < MAX_SKILL_ITEM_REQUIRE; j++ ) {
skill_db[i].itemid[j] = atoi(split[12+ 2*j]);
skill_db[i].amount[j] = atoi(split[13+ 2*j]);
- }
+ }
return true;
}
@@ -17482,6 +17516,18 @@ static bool skill_parse_row_changematerialdb(char* split[], int columns, int cur
return true;
}
+/*===============================
+ * DB reading.
+ * skill_db.txt
+ * skill_require_db.txt
+ * skill_cast_db.txt
+ * skill_castnodex_db.txt
+ * skill_nocast_db.txt
+ * skill_unit_db.txt
+ * produce_db.txt
+ * create_arrow_db.txt
+ * abra_db.txt
+ *------------------------------*/
static void skill_readdb(void)
{
// init skill db structures