summaryrefslogtreecommitdiff
path: root/src/map
diff options
context:
space:
mode:
Diffstat (limited to 'src/map')
-rw-r--r--src/map/battle.c24
-rw-r--r--src/map/clif.c26
-rw-r--r--src/map/skill.c86
-rw-r--r--src/map/status.c37
-rw-r--r--src/map/status.h4
5 files changed, 132 insertions, 45 deletions
diff --git a/src/map/battle.c b/src/map/battle.c
index 64c695264..bbed08be6 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -2429,6 +2429,12 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
case EL_ROCK_CRUSHER:
skillratio += 700;
break;
+ case MH_STAHL_HORN:
+ skillratio += 500 + 100 * skill_lv;
+ break;
+ case MH_LAVA_SLIDE:
+ skillratio = 70 * skill_lv;
+ break;
}
ATK_RATE(skillratio);
@@ -3678,7 +3684,12 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
case EL_TYPOON_MIS_ATK:
skillratio += 1100;
break;
-
+ case MH_ERASER_CUTTER:
+ if (skill_lv >= 3)
+ skillratio += 800 + 200 * skill_lv ;
+ else
+ skillratio += 500 + 400 * skill_lv;
+ break;
}
MATK_RATE(skillratio);
@@ -3839,10 +3850,13 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
else if( map[target->m].flag.battleground )
ad.damage=battle_calc_bg_damage(src,target,ad.damage,ad.div_,skill_num,skill_lv,ad.flag);
-
- if( skill_num == SO_VARETYR_SPEAR ) { // Physical damage.
- struct Damage wd = battle_calc_weapon_attack(src,target,skill_num,skill_lv,mflag);
- ad.damage += wd.damage;
+ switch( skill_num ) { /* post-calc modifiers */
+ case SO_VARETYR_SPEAR: { // Physical damage.
+ struct Damage wd = battle_calc_weapon_attack(src,target,skill_num,skill_lv,mflag);
+ ad.damage += wd.damage;
+ break;
+ }
+ //case HM_ERASER_CUTTER:
}
return ad;
diff --git a/src/map/clif.c b/src/map/clif.c
index 4153130e5..a35e0fa49 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -10582,6 +10582,27 @@ static void clif_parse_UseSkillToId_homun(struct homun_data *hd, struct map_sess
unit_skilluse_id(&hd->bl, target_id, skillnum, skilllv);
}
+static void clif_parse_UseSkillToPos_homun(struct homun_data *hd, struct map_session_data *sd, unsigned int tick, short skillnum, short skilllv, short x, short y, int skillmoreinfo)
+{
+ int lv;
+ if( !hd )
+ return;
+ if( skillnotok_hom(skillnum, hd) )
+ return;
+ if( hd->ud.skilltimer != INVALID_TIMER ) {
+ if( skillnum != SA_CASTCANCEL && skillnum != SO_SPELLFIST ) return;
+ } else if( DIFF_TICK(tick, hd->ud.canact_tick) < 0 )
+ return;
+
+ if( hd->sc.data[SC_BASILICA] )
+ return;
+ lv = merc_hom_checkskill(hd, skillnum);
+ if( skilllv > lv )
+ skilllv = lv;
+ if( skilllv )
+ unit_skilluse_pos(&hd->bl, x, y, skillnum, skilllv);
+}
+
static void clif_parse_UseSkillToId_mercenary(struct mercenary_data *md, struct map_session_data *sd, unsigned int tick, short skillnum, short skilllv, int target_id)
{
int lv;
@@ -10743,6 +10764,11 @@ static void clif_parse_UseSkillToPosSub(int fd, struct map_session_data *sd, sho
if( !(skill_get_inf(skillnum)&INF_GROUND_SKILL) )
return; //Using a target skill on the ground? WRONG.
+
+ if( skillnum >= HM_SKILLBASE && skillnum < HM_SKILLBASE + MAX_HOMUNSKILL ) {
+ clif_parse_UseSkillToPos_homun(sd->hd, sd, tick, skillnum, skilllv, x, y, skillmoreinfo);
+ return;
+ }
if( skillnum >= MC_SKILLBASE && skillnum < MC_SKILLBASE + MAX_MERCSKILL )
{
diff --git a/src/map/skill.c b/src/map/skill.c
index cd67eac80..9e7b5711a 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -44,15 +44,18 @@
#define SKILLUNITTIMER_INTERVAL 100
// ranges reserved for mapping skill ids to skilldb offsets
-#define GD_SKILLRANGEMIN 900
-#define GD_SKILLRANGEMAX (GD_SKILLRANGEMIN+MAX_GUILDSKILL)
-#define MC_SKILLRANGEMIN 800
-#define MC_SKILLRANGEMAX (MC_SKILLRANGEMIN+MAX_MERCSKILL)
#define HM_SKILLRANGEMIN 700
-#define HM_SKILLRANGEMAX (HM_SKILLRANGEMIN+MAX_HOMUNSKILL)
+#define HM_SKILLRANGEMAX HM_SKILLRANGEMIN + MAX_HOMUNSKILL
+#define MC_SKILLRANGEMIN HM_SKILLRANGEMAX + 1
+#define MC_SKILLRANGEMAX MC_SKILLRANGEMIN + MAX_MERCSKILL
#define EL_SKILLRANGEMIN MC_SKILLRANGEMAX + 1
#define EL_SKILLRANGEMAX EL_SKILLRANGEMIN + MAX_ELEMENTALSKILL
+#define GD_SKILLRANGEMIN EL_SKILLRANGEMAX + 1
+#define GD_SKILLRANGEMAX GD_SKILLRANGEMIN + MAX_GUILDSKILL
+#if GD_SKILLRANGEMAX > 999
+ #error GD_SKILLRANGEMAX is greater than 999
+#endif
static struct eri *skill_unit_ers = NULL; //For handling skill_unit's [Skotlex]
static struct eri *skill_timer_ers = NULL; //For handling skill_timerskills [Skotlex]
@@ -1122,9 +1125,6 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int
case NPC_CRITICALWOUND:
sc_start(bl,SC_CRITICALWOUND,100,skilllv,skill_get_time2(skillid,skilllv));
break;
- /**
- * Rune Knight
- **/
case RK_HUNDREDSPEAR:
if( !sd || pc_checkskill(sd,KN_SPEARBOOMERANG) == 0 )
break; // Spear Boomerang auto cast chance only works if you have mastered Spear Boomerang.
@@ -1138,16 +1138,10 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int
case RK_DRAGONBREATH:
sc_start4(bl,SC_BURNING,5+5*skilllv,skilllv,1000,src->id,0,skill_get_time(skillid,skilllv));
break;
- /**
- * Arch Bishop
- **/
case AB_ADORAMUS:
if( tsc && !tsc->data[SC_DECREASEAGI] ) //Prevent duplicate agi-down effect.
sc_start(bl, SC_ADORAMUS, 100, skilllv, skill_get_time(skillid, skilllv));
break;
- /**
- * Warlock
- **/
case WL_CRIMSONROCK:
sc_start(bl, SC_STUN, 40, skilllv, skill_get_time(skillid, skilllv));
break;
@@ -1168,9 +1162,6 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int
case WL_JACKFROST:
sc_start(bl,SC_FREEZE,100,skilllv,skill_get_time(skillid,skilllv));
break;
- /**
- * Ranger
- **/
case RA_WUGBITE:
{
int chance = (50+10*skilllv)-(sstatus->agi/4) + (sd ? pc_checkskill(sd,RA_TOOTHOFWUG)*2 : 0);
@@ -1193,9 +1184,6 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int
case RA_ICEBOUNDTRAP:
sc_start(bl, (skillid == RA_FIRINGTRAP) ? SC_BURNING:SC_FREEZING, 40 + 10 * skilllv, skilllv, skill_get_time2(skillid, skilllv));
break;
- /**
- * Mechanic
- **/
case NC_PILEBUNKER:
if( rnd()%100 < 5 + 15*skilllv )
{ //Deactivatable Statuses: Kyrie Eleison, Auto Guard, Steel Body, Assumptio, and Millennium Shield
@@ -1218,15 +1206,9 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int
if( rnd()%100 < 5*skilllv )
skill_castend_damage_id(src, bl, NC_AXEBOOMERANG, pc_checkskill(sd, NC_AXEBOOMERANG), tick, 1);
break;
- /**
- * Guilotine Cross
- **/
case GC_WEAPONCRUSH:
skill_castend_nodamage_id(src,bl,skillid,skilllv,tick,BCT_ENEMY);
break;
- /**
- * Royal Guard
- **/
case LG_SHIELDPRESS:
sc_start(bl, SC_STUN, 30 + 8 * skilllv, skilllv, skill_get_time(skillid,skilllv));
break;
@@ -1361,6 +1343,12 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int
case EL_TYPOON_MIS:
sc_start(bl,SC_SILENCE,10*skilllv,skilllv,skill_get_time(skillid,skilllv));
break;
+ case MH_LAVA_SLIDE:
+ sc_start4(bl,SC_BURNING,10*skilllv,skilllv,1000,src->id,0,skill_get_time(skillid,skilllv));
+ break;
+ case MH_STAHL_HORN:
+ sc_start(bl,SC_STUN,(20 + 4 * skilllv),skilllv,skill_get_time2(skillid,skilllv));
+ break;
}
if (md && battle_config.summons_trigger_autospells && md->master_id && md->special_state.ai)
@@ -2769,7 +2757,7 @@ static int skill_check_unit_range_sub (struct block_list *bl, va_list ap)
case RA_ICEBOUNDTRAP:
case SC_DIMENSIONDOOR:
//Non stackable on themselves and traps (including venom dust which does not has the trap inf2 set)
- if (skillid != g_skillid && !(skill_get_inf2(g_skillid)&INF2_TRAP) && g_skillid != AS_VENOMDUST)
+ if (skillid != g_skillid && !(skill_get_inf2(g_skillid)&INF2_TRAP) && g_skillid != AS_VENOMDUST && g_skillid != MH_POISON_MIST)
return 0;
break;
default: //Avoid stacking with same kind of trap. [Skotlex]
@@ -3421,7 +3409,8 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
case SR_GENTLETOUCH_QUIET:
case WM_SEVERE_RAINSTORM_MELEE:
case WM_GREAT_ECHO:
- case GN_SLINGITEM_RANGEMELEEATK:
+ case GN_SLINGITEM_RANGEMELEEATK:
+ case MH_STAHL_HORN:
skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
break;
@@ -3648,7 +3637,8 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
case WM_REVERBERATION_MAGIC:
case SO_VARETYR_SPEAR:
case GN_CART_TORNADO:
- case GN_CARTCANNON:
+ case GN_CARTCANNON:
+ case MH_LAVA_SLIDE:
if( flag&1 ) {//Recursive invocation
// skill_area_temp[0] holds number of targets in area
// skill_area_temp[1] holds the id of the original target
@@ -3806,6 +3796,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
case AB_HIGHNESSHEAL:
case AB_DUPLELIGHT_MAGIC:
case WM_METALICSOUND:
+ case MH_ERASER_CUTTER:
skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag);
break;
@@ -4501,7 +4492,11 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
break;
default:
- ShowWarning("skill_castend_damage_id: Unknown skill used:%d\n",skillid);
+ if( skillid >= HM_SKILLBASE && skillid <= HM_SKILLBASE + MAX_HOMUNSKILL ) {
+ if( src->type == BL_HOM && ((TBL_HOM*)src)->master->fd )
+ clif_colormes(((TBL_HOM*)src)->master, COLOR_RED, "This skill is not yet supported");
+ } else /* temporary until all the homun-s skills are supported otherwise console would fill up with pointless warnings */
+ ShowWarning("skill_castend_damage_id: Unknown skill used:%d\n",skillid);
clif_skill_damage(src, bl, tick, status_get_amotion(src), tstatus->dmotion,
0, abs(skill_get_num(skillid, skilllv)),
skillid, skilllv, skill_get_hit(skillid));
@@ -7119,15 +7114,19 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
break;
case AM_REST:
- if (sd)
- {
+ if (sd) {
if (merc_hom_vaporize(sd,1))
clif_skill_nodamage(src, bl, skillid, skilllv, 1);
else
clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
}
break;
-
+ case MH_STAHL_HORN:
+ if (sd) {
+ if( skillid == MH_GOLDENE_FERSE )
+ clif_skill_fail(sd,skillid,USESKILL_FAIL_CONDITION,0);
+ }
+ break;
case HAMI_CASTLE: //[orn]
if(rnd()%100 < 20*skilllv && src != bl)
{
@@ -7182,6 +7181,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
case HFLI_FLEET:
case HFLI_SPEED:
case HLIF_CHANGE:
+ case MH_ANGRIFFS_MODUS:
+ case MH_GOLDENE_FERSE:
clif_skill_nodamage(src,bl,skillid,skilllv,
sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
if (hd)
@@ -7263,7 +7264,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
}
break;
case RK_IGNITIONBREAK:
- case LG_EARTHDRIVE:
+ case LG_EARTHDRIVE:
+ case MH_LAVA_SLIDE:
clif_skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
i = skill_get_splash(skillid,skilllv);
if( skillid == LG_EARTHDRIVE ) {
@@ -8609,7 +8611,11 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
break;
default:
- ShowWarning("skill_castend_nodamage_id: Unknown skill used:%d\n",skillid);
+ if( skillid >= HM_SKILLBASE && skillid <= HM_SKILLBASE + MAX_HOMUNSKILL ) {
+ if( src->type == BL_HOM && ((TBL_HOM*)src)->master->fd )
+ clif_colormes(((TBL_HOM*)src)->master, COLOR_RED, "This skill is not yet supported");
+ } else /* temporary until all the homun-s skills are supported otherwise console would fill up with pointless warnings */
+ ShowWarning("skill_castend_nodamage_id: Unknown skill used:%d\n",skillid);
clif_skill_nodamage(src,bl,skillid,skilllv,1);
map_freeblock_unlock();
return 1;
@@ -9299,7 +9305,8 @@ int skill_castend_pos2(struct block_list* src, int x, int y, int skillid, int sk
case SO_FIRE_INSIGNIA:
case SO_WATER_INSIGNIA:
case SO_WIND_INSIGNIA:
- case SO_EARTH_INSIGNIA:
+ case SO_EARTH_INSIGNIA:
+ case MH_POISON_MIST:
flag|=1;//Set flag to 1 to prevent deleting ammo (it will be deleted on group-delete).
case GS_GROUNDDRIFT: //Ammo should be deleted right away.
skill_unitsetting(src,skillid,skilllv,x,y,0);
@@ -9751,7 +9758,11 @@ int skill_castend_pos2(struct block_list* src, int x, int y, int skillid, int sk
break;
default:
- ShowWarning("skill_castend_pos2: Unknown skill used:%d\n",skillid);
+ if( skillid >= HM_SKILLBASE && skillid <= HM_SKILLBASE + MAX_HOMUNSKILL ) {
+ if( src->type == BL_HOM && ((TBL_HOM*)src)->master->fd )
+ clif_colormes(((TBL_HOM*)src)->master, COLOR_RED, "This skill is not yet supported");
+ } else /* temporary until all the homun-s skills are supported otherwise console would fill up with pointless warnings */
+ ShowWarning("skill_castend_pos2: Unknown skill used:%d\n",skillid);
return 1;
}
@@ -16253,6 +16264,7 @@ void skill_init_unit_layout (void)
memcpy(skill_unit_layout[pos].dy,dy,sizeof(dy));
}
break;
+ case MH_POISON_MIST:
case AS_VENOMDUST: {
static const int dx[] = {-1, 0, 0, 0, 1};
static const int dy[] = { 0,-1, 0, 1, 0};
diff --git a/src/map/status.c b/src/map/status.c
index 3b874c918..f1ad9fd8d 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -707,6 +707,13 @@ void initChangeTables(void) {
set_sc( EL_ROCK_CRUSHER , SC_ROCK_CRUSHER , SI_ROCK_CRUSHER , SCB_DEF );
set_sc( EL_ROCK_CRUSHER_ATK, SC_ROCK_CRUSHER_ATK , SI_ROCK_CRUSHER_ATK , SCB_SPEED );
+ add_sc( MH_STAHL_HORN , SC_STUN );
+ set_sc( MH_ANGRIFFS_MODUS , SC_ANGRIFFS_MODUS , SI_ANGRIFFS_MODUS , SCB_BATK|SCB_WATK|SCB_DEF|SCB_FLEE );
+ set_sc( MH_GOLDENE_FERSE , SC_GOLDENE_FERSE , SI_GOLDENE_FERSE , SCB_SPEED|SCB_FLEE|SCB_ATK_ELE );
+ add_sc( MH_LAVA_SLIDE , SC_BURNING );
+ add_sc( MH_POISON_MIST , SC_BLIND );
+ set_sc( MH_ERASER_CUTTER , SC_ERASER_CUTTER , SI_BLANK , SCB_NONE );
+
// Storing the target job rather than simply SC_SPIRIT simplifies code later on.
SkillStatusChangeTable[SL_ALCHEMIST] = (sc_type)MAPID_ALCHEMIST,
SkillStatusChangeTable[SL_MONK] = (sc_type)MAPID_MONK,
@@ -4330,6 +4337,8 @@ static unsigned short status_calc_batk(struct block_list *bl, struct status_chan
batk += sc->data[SC_FULL_SWING_K]->val1;
if(sc->data[SC_ODINS_POWER])
batk += 70;
+ if(sc->data[SC_ANGRIFFS_MODUS])
+ batk += batk * sc->data[SC_ANGRIFFS_MODUS]->val2/100;
#ifdef RENEWAL_EDP
// renewal EDP increases your base atk by atk x skill level
if( sc->data[SC_EDP] )
@@ -4413,7 +4422,8 @@ static unsigned short status_calc_watk(struct block_list *bl, struct status_chan
watk += watk / 10;
if( sc && sc->data[SC_TIDAL_WEAPON] )
watk += watk * sc->data[SC_TIDAL_WEAPON]->val2 / 100;
-
+ if(sc->data[SC_ANGRIFFS_MODUS])
+ watk += watk * sc->data[SC_ANGRIFFS_MODUS]->val2/100;
#ifdef RENEWAL_EDP
// renewal EDP increases your weapon atk by watk x Skill Level - 1
if( sc->data[SC_EDP] && sc->data[SC_EDP]->val1 > 1 )
@@ -4592,6 +4602,10 @@ static signed short status_calc_flee(struct block_list *bl, struct status_change
flee += flee * sc->data[SC_ZEPHYR]->val2 / 100;
if( sc->data[SC_MARSHOFABYSS] )
flee -= (9 * sc->data[SC_MARSHOFABYSS]->val3 / 10 + sc->data[SC_MARSHOFABYSS]->val2 / 10) * (bl->type == BL_MOB ? 2 : 1);
+ if( sc->data[SC_ANGRIFFS_MODUS] )
+ flee -= flee * sc->data[SC_ANGRIFFS_MODUS]->val3 / 100;
+ if( sc->data[SC_GOLDENE_FERSE ] )
+ flee -= flee * sc->data[SC_GOLDENE_FERSE ]->val2 / 100;
#ifdef RENEWAL
if( sc->data[SC_SPEARQUICKEN] )
flee += 2 * sc->data[SC_SPEARQUICKEN]->val1;
@@ -4684,7 +4698,9 @@ static defType status_calc_def(struct block_list *bl, struct status_change *sc,
def += 50;
if(sc->data[SC_ODINS_POWER])
def -= 20;
-
+ if( sc->data[SC_ANGRIFFS_MODUS] )
+ def -= def * sc->data[SC_ANGRIFFS_MODUS]->val4 / 100;
+
return (defType)cap_value(def,DEFTYPE_MIN,DEFTYPE_MAX);;
}
@@ -5164,7 +5180,10 @@ static short status_calc_aspd_rate(struct block_list *bl, struct status_change *
if(sc->data[SC_FLEET] &&
max < sc->data[SC_FLEET]->val2)
max = sc->data[SC_FLEET]->val2;
-
+
+ if( sc->data[SC_GOLDENE_FERSE] && max < sc->data[SC_GOLDENE_FERSE]->val3 )
+ max = sc->data[SC_GOLDENE_FERSE]->val3;
+
if(sc->data[SC_ASSNCROS] &&
max < sc->data[SC_ASSNCROS]->val2)
{
@@ -5428,6 +5447,8 @@ unsigned char status_calc_attack_element(struct block_list *bl, struct status_ch
return ELE_GHOST;
if(sc->data[SC_TIDAL_WEAPON_OPTION] || sc->data[SC_TIDAL_WEAPON] )
return ELE_WATER;
+ if(sc->data[SC_GOLDENE_FERSE] && rand()%100 < sc->data[SC_GOLDENE_FERSE]->val4)
+ return ELE_HOLY;
return (unsigned char)cap_value(element,0,UCHAR_MAX);
}
@@ -7507,6 +7528,16 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
val3 = 3*val1; //Leech chance
val4 = 20; //Leech percent
break;
+ case SC_ANGRIFFS_MODUS:
+ val2 = 70 + 30*val1; //atk
+ val3 = 50 + 20*val1; //flee
+ val4 = 60 + 20*val1; //def
+ break;
+ case SC_GOLDENE_FERSE:
+ val2 = 20 + 10*val1; //flee
+ val3 = 10 + 4*val1; //aspd
+ val4 = 2 + 2*val1; //chance to issue holy-ele attack
+ break;
case SC_FLEET:
val2 = 30*val1; //Aspd change
val3 = 5+5*val1; //bAtk/wAtk rate change
diff --git a/src/map/status.h b/src/map/status.h
index ab21311b8..532eb8d13 100644
--- a/src/map/status.h
+++ b/src/map/status.h
@@ -612,6 +612,10 @@ typedef enum sc_type {
* To increase the maximum value just add another status type before SC_MAXSPELLBOOK (ex. SC_SPELLBOOK7, SC_SPELLBOOK8 and so on)
**/
SC_MAXSPELLBOOK,
+ /* homun-s */
+ SC_ANGRIFFS_MODUS,
+ SC_GOLDENE_FERSE,
+ SC_ERASER_CUTTER,
SC_MAX, //Automatically updated max, used in for's to check we are within bounds.
} sc_type;