diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/common/mmo.h | 6 | ||||
-rw-r--r-- | src/map/battle.c | 24 | ||||
-rw-r--r-- | src/map/clif.c | 26 | ||||
-rw-r--r-- | src/map/skill.c | 86 | ||||
-rw-r--r-- | src/map/status.c | 37 | ||||
-rw-r--r-- | src/map/status.h | 4 |
6 files changed, 135 insertions, 48 deletions
diff --git a/src/common/mmo.h b/src/common/mmo.h index c3c2dc06e..7557d0ce3 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -79,7 +79,7 @@ #define MAX_ZENY 1000000000 #define MAX_FAME 1000000000 #define MAX_CART 100 -#define MAX_SKILL 3040 +#define MAX_SKILL 3100 #define GLOBAL_REG_NUM 256 #define ACCOUNT_REG_NUM 64 #define ACCOUNT_REG2_NUM 16 @@ -139,8 +139,8 @@ //Base Homun skill. #define HM_SKILLBASE 8001 -#define MAX_HOMUNSKILL 16 -#define MAX_HOMUNCULUS_CLASS 60 //[orn], Increased to 60 from 16 to allow new Homun-S. +#define MAX_HOMUNSKILL 43 +#define MAX_HOMUNCULUS_CLASS 52 //[orn], Increased to 60 from 16 to allow new Homun-S. #define HM_CLASS_BASE 6001 #define HM_CLASS_MAX (HM_CLASS_BASE+MAX_HOMUNCULUS_CLASS-1) 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; |