summaryrefslogtreecommitdiff
path: root/src/map/elemental.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/elemental.c')
-rw-r--r--src/map/elemental.c134
1 files changed, 121 insertions, 13 deletions
diff --git a/src/map/elemental.c b/src/map/elemental.c
index 770047138..7bcb9a294 100644
--- a/src/map/elemental.c
+++ b/src/map/elemental.c
@@ -73,8 +73,56 @@ int elemental_create(struct map_session_data *sd, int class_, unsigned int lifet
ele.char_id = sd->status.char_id;
ele.class_ = class_;
ele.mode = EL_MODE_PASSIVE; // Initial mode
- ele.hp = db->status.max_hp;
- ele.sp = db->status.max_sp;
+ i = db->status.size+1; // summon level
+
+ //[(Caster’s Max HP/ 3 ) + (Caster’s INT x 10 )+ (Caster’s Job Level x 20 )] x [(Elemental Summon Level + 2) / 3]
+ ele.hp = ele.max_hp = (sd->battle_status.max_hp/3 + sd->battle_status.int_*10 + sd->status.job_level) * ((i + 2) / 3) * 5 * pc_checkskill(sd,SO_EL_SYMPATHY) / 100;
+ //Caster’s Max SP /4
+ ele.sp = ele.max_sp = sd->battle_status.max_sp/4 * 5 * pc_checkskill(sd,SO_EL_SYMPATHY) / 100;
+ //Caster’s [ Max SP / (18 / Elemental Summon Skill Level) 1- 100 ]
+ ele.atk = (sd->battle_status.max_sp / (18 / i) * 1 - 100) + 25 * pc_checkskill(sd,SO_EL_SYMPATHY);
+ //Caster’s [ Max SP / (18 / Elemental Summon Skill Level) ]
+ ele.atk2 = sd->battle_status.max_sp / 18 + 25 * pc_checkskill(sd,SO_EL_SYMPATHY);
+ //Caster’s HIT + (Caster’s Base Level )
+ ele.hit = sd->battle_status.hit + sd->status.base_level;
+ //[Elemental Summon Skill Level x (Caster’s INT / 2 + Caster’s DEX / 4)]
+ ele.matk = i * (sd->battle_status.int_ / 2 + sd->battle_status.dex / 4) + 25 * pc_checkskill(sd,SO_EL_SYMPATHY);
+ //150 + [Caster’s DEX / 10] + [Elemental Summon Skill Level x 3 ]
+ ele.amotion = 150 + sd->battle_status.dex / 10 + i * 3;
+ //Caster’s DEF + (Caster’s Base Level / (5 – Elemental Summon Skill Level)
+ ele.def = sd->battle_status.def + sd->status.base_level / (5-i);
+ //Caster’s MDEF + (Caster’s INT / (5 - Elemental Summon Skill Level)
+ ele.mdef = sd->battle_status.mdef + sd->battle_status.int_ / (5-i);
+ //Caster’s FLEE + (Caster’s Base Level / (5 – Elemental Summon Skill Level)
+ ele.flee = sd->status.base_level / (5-i);
+ //Caster’s HIT + (Caster’s Base Level )
+ ele.hit = sd->battle_status.hit + sd->status.base_level;
+
+ //per individual bonuses
+ switch(db->class_){
+ case 2114: case 2115:
+ case 2116: //ATK + (Summon Agni Skill Level x 20) / HIT + (Summon Agni Skill Level x 10)
+ ele.atk += i * 20;
+ ele.atk2 += i * 20;
+ ele.hit += i * 10;
+ break;
+ case 2117: case 2118:
+ case 2119: //MDEF + (Summon Aqua Skill Level x 10) / MATK + (Summon Aqua Skill Level x 20)
+ ele.mdef += i * 10;
+ ele.matk += i * 20;
+ break;
+ case 2120: case 2121:
+ case 2122: //FLEE + (Summon Ventus Skill Level x 20) / MATK + (Summon Ventus Skill Level x 10)
+ ele.flee += i * 20;
+ ele.matk += i * 10;
+ break;
+ case 2123: case 2124:
+ case 2125: //DEF + (Summon Tera Skill Level x 25) / ATK + (Summon Tera Skill Level x 5)
+ ele.def += i * 25;
+ ele.atk += i * 5;
+ ele.atk2 += i * 5;
+ break;
+ }
ele.life_time = lifetime;
// Request Char Server to create this elemental
@@ -93,10 +141,19 @@ int elemental_get_lifetime(struct elemental_data *ed) {
}
int elemental_save(struct elemental_data *ed) {
+ ed->elemental.mode = ed->battle_status.mode;
ed->elemental.hp = ed->battle_status.hp;
ed->elemental.sp = ed->battle_status.sp;
+ ed->elemental.max_hp = ed->battle_status.max_hp;
+ ed->elemental.max_sp = ed->battle_status.max_sp;
+ ed->elemental.atk = ed->battle_status.rhw.atk;
+ ed->elemental.atk2 = ed->battle_status.rhw.atk2;
+ ed->elemental.matk = ed->battle_status.matk_min;
+ ed->elemental.def = ed->battle_status.def;
+ ed->elemental.mdef = ed->battle_status.mdef;
+ ed->elemental.flee = ed->battle_status.flee;
+ ed->elemental.hit = ed->battle_status.hit;
ed->elemental.life_time = elemental_get_lifetime(ed);
-
intif_elemental_save(&ed->elemental);
return 1;
}
@@ -192,9 +249,8 @@ int elemental_data_received(struct s_elemental *ele, bool flag) {
map_addiddb(&ed->bl);
status_calc_elemental(ed,1);
- ed->last_thinktime = gettick();
+ ed->last_spdrain_time = ed->last_thinktime = gettick();
ed->summon_timer = INVALID_TIMER;
- ed->battle_status.mode = ele->mode = EL_MODE_PASSIVE; // Initial mode.
elemental_summon_init(ed);
} else {
memcpy(&sd->ed->elemental, ele, sizeof(struct s_elemental));
@@ -202,14 +258,13 @@ int elemental_data_received(struct s_elemental *ele, bool flag) {
}
sd->status.ele_id = ele->elemental_id;
- ed->battle_status.mode = ele->mode = EL_MODE_PASSIVE; // Initial mode.
if( ed->bl.prev == NULL && sd->bl.prev != NULL ) {
map_addblock(&ed->bl);
clif_spawn(&ed->bl);
clif_elemental_info(sd);
clif_elemental_updatestatus(sd,SP_HP);
- clif_hpmeter_single(sd->fd,ed->bl.id,ed->battle_status.hp,ed->battle_status.matk_max);
+ clif_hpmeter_single(sd->fd,ed->bl.id,ed->battle_status.hp,ed->battle_status.max_hp);
clif_elemental_updatestatus(sd,SP_SP);
}
@@ -259,8 +314,6 @@ int elemental_clean_single_effect(struct elemental_data *ed, int skill_num) {
break;
}
}
- if( skill_get_unit_id(skill_num,0) )
- skill_clear_unitgroup(&ed->bl);
return 1;
}
@@ -292,9 +345,7 @@ int elemental_clean_effect(struct elemental_data *ed) {
status_change_end(&ed->bl, SC_UPHEAVAL, INVALID_TIMER);
status_change_end(&ed->bl, SC_CIRCLE_OF_FIRE, INVALID_TIMER);
status_change_end(&ed->bl, SC_TIDAL_WEAPON, INVALID_TIMER);
-
- skill_clear_unitgroup(&ed->bl);
-
+
if( (sd = ed->master) == NULL )
return 0;
@@ -328,6 +379,7 @@ int elemental_clean_effect(struct elemental_data *ed) {
}
int elemental_action(struct elemental_data *ed, struct block_list *bl, unsigned int tick) {
+ struct skill_condition req;
short skillnum, skilllv;
int i;
@@ -377,6 +429,20 @@ int elemental_action(struct elemental_data *ed, struct block_list *bl, unsigned
return 1;
}
+
+ req = elemental_skill_get_requirements(skillnum, skilllv);
+
+ if(req.hp || req.sp){
+ struct map_session_data *sd = BL_CAST(BL_PC, battle_get_master(&ed->bl));
+ if( sd ){
+ if( sd->skillid_old != SO_EL_ACTION && //regardless of remaining HP/SP it can be cast
+ (status_get_hp(&ed->bl) < req.hp || status_get_sp(&ed->bl) < req.sp) )
+ return 1;
+ else
+ status_zap(&ed->bl, req.hp, req.sp);
+ }
+ }
+
//Otherwise, just cast the skill.
if( skill_get_inf(skillnum) & INF_GROUND_SKILL )
unit_skilluse_pos(&ed->bl, bl->x, bl->y, skillnum, skilllv);
@@ -488,6 +554,24 @@ int elemental_skillnotok(int skillid, struct elemental_data *ed) {
return skillnotok(skillid, ed->master);
}
+struct skill_condition elemental_skill_get_requirements(int skill, int lv){
+ struct skill_condition req;
+ int id = skill_get_index(skill);
+
+ memset(&req,0,sizeof(req));
+
+ if( id == 0 ) // invalid skill id
+ return req;
+
+ if( lv < 1 || lv > MAX_SKILL_LEVEL )
+ return req;
+
+ req.hp = skill_db[id].hp[lv-1];
+ req.sp = skill_db[id].sp[lv-1];
+
+ return req;
+}
+
int elemental_set_target( struct map_session_data *sd, struct block_list *bl ) {
struct elemental_data *ed = sd->ed;
@@ -551,6 +635,30 @@ static int elemental_ai_sub_timer(struct elemental_data *ed, struct map_session_
if( ed->bl.prev == NULL || sd == NULL || sd->bl.prev == NULL )
return 0;
+
+ // Check if caster can sustain the summoned elemental
+ if( DIFF_TICK(tick,ed->last_spdrain_time) >= 10000 ){// Drain SP every 10 seconds
+ int sp = 5;
+
+ switch(ed->vd->class_){
+ case 2115: case 2118:
+ case 2121: case 2124:
+ sp = 8;
+ break;
+ case 2116: case 2119:
+ case 2122: case 2125:
+ sp = 11;
+ break;
+ }
+
+ if( status_get_sp(&sd->bl) < sp ){ // Can't sustain delete it.
+ elemental_delete(sd->ed,0);
+ return 0;
+ }
+
+ status_zap(&sd->bl,0,sp);
+ ed->last_spdrain_time = tick;
+ }
if( DIFF_TICK(tick,ed->last_thinktime) < MIN_ELETHINKTIME )
return 0;
@@ -687,7 +795,7 @@ int read_elementaldb(void) {
status->max_sp = atoi(str[5]);
status->rhw.range = atoi(str[6]);
status->rhw.atk = atoi(str[7]);
- status->rhw.atk2 = status->rhw.atk + atoi(str[8]);
+ status->rhw.atk2 = atoi(str[8]);
status->def = atoi(str[9]);
status->mdef = atoi(str[10]);
status->str = atoi(str[11]);