* Follow up f4eb33e, 5a2849d

Signed-off-by: Cydh Ramdh <house.bad@gmail.com>
This commit is contained in:
Cydh Ramdh 2014-01-20 22:38:10 +07:00
parent 1a9b546540
commit a32d3a6e76
6 changed files with 92 additions and 48 deletions

View File

@ -8994,7 +8994,7 @@ void clif_feel_info(struct map_session_data* sd, unsigned char feel_level, unsig
{ {
char mapname[MAP_NAME_LENGTH_EXT]; char mapname[MAP_NAME_LENGTH_EXT];
mapindex_getmapname_ext(mapindex_id2name(sd->feel_map[feel_level].index), mapname); mapindex_getmapname_ext(map[sd->feel_map[feel_level].m].name, mapname);
clif_starskill(sd, mapname, 0, feel_level, type ? 1 : 0); clif_starskill(sd, mapname, 0, feel_level, type ? 1 : 0);
} }

View File

@ -122,10 +122,11 @@ struct view_data* npc_get_viewdata(int class_)
int npc_isnear_sub(struct block_list* bl, va_list args) { int npc_isnear_sub(struct block_list* bl, va_list args) {
struct npc_data *nd = (struct npc_data*)bl; struct npc_data *nd = (struct npc_data*)bl;
int skill_id = va_arg(args, int); int skill_id = va_arg(args, int);
uint16 idx = -1;
//Check the NPC type if is used by INF2_NO_NEARNPC (skill_id is not null) [Cydh] if (skill_id > 0) { //If skill_id > 0 that means is used for INF2_NO_NEARNPC [Cydh]
if (skill_id && (idx = skill_get_index(skill_id)) && skill_db[idx].unit_nonearnpc_type) { int16 idx = skill_get_index(skill_id);
if (idx >= 0 && skill_db[idx].unit_nonearnpc_type) {
while (1) { while (1) {
if (skill_db[idx].unit_nonearnpc_type&1 && nd->subtype == WARP) break; if (skill_db[idx].unit_nonearnpc_type&1 && nd->subtype == WARP) break;
if (skill_db[idx].unit_nonearnpc_type&2 && nd->subtype == SHOP) break; if (skill_db[idx].unit_nonearnpc_type&2 && nd->subtype == SHOP) break;
@ -134,6 +135,7 @@ int npc_isnear_sub(struct block_list* bl, va_list args) {
return 0; return 0;
} }
} }
}
if( nd->sc.option & (OPTION_HIDE|OPTION_INVISIBLE) ) if( nd->sc.option & (OPTION_HIDE|OPTION_INVISIBLE) )
return 0; return 0;

View File

@ -1231,7 +1231,7 @@ int pc_reg_received(struct map_session_data *sd)
//SG map and mob read [Komurka] //SG map and mob read [Komurka]
for(i=0;i<MAX_PC_FEELHATE;i++) //for now - someone need to make reading from txt/sql for(i=0;i<MAX_PC_FEELHATE;i++) //for now - someone need to make reading from txt/sql
{ {
uint8 j; uint16 j;
if ((j = pc_readglobalreg(sd,sg_info[i].feel_var))!=0) { if ((j = pc_readglobalreg(sd,sg_info[i].feel_var))!=0) {
sd->feel_map[i].index = j; sd->feel_map[i].index = j;
sd->feel_map[i].m = map_mapindex2mapid(j); sd->feel_map[i].m = map_mapindex2mapid(j);

View File

@ -484,8 +484,13 @@ static char skill_isCopyable(struct map_session_data *sd, uint16 skill_id) {
return 0; return 0;
} }
// [MouseJstr] - skill ok to cast? and when? /** Check if the skill is ok to cast and when.
//done before check_condition_begin, requirement * Done before check_condition_begin, requirement
* @param skill_id: Skill ID that casted
* @param sd: Player who casted
* @return true: Skill cannot be used, false: otherwise
* @author [MouseJstr]
*/
bool skill_isNotOk(uint16 skill_id, struct map_session_data *sd) bool skill_isNotOk(uint16 skill_id, struct map_session_data *sd)
{ {
int16 idx,m; int16 idx,m;
@ -641,6 +646,12 @@ bool skill_isNotOk(uint16 skill_id, struct map_session_data *sd)
return (map[m].flag.noskill); return (map[m].flag.noskill);
} }
/** Check if the homunculus skill is ok to be processed
* After checking from Homunculus side, also check the master condition
* @param skill_id: Skill ID that casted
* @param hd: Homunculus who casted
* @return true: Skill cannot be used, false: otherwise
*/
bool skill_isNotOk_hom(uint16 skill_id, struct homun_data *hd) bool skill_isNotOk_hom(uint16 skill_id, struct homun_data *hd)
{ {
uint16 idx = skill_get_index(skill_id); uint16 idx = skill_get_index(skill_id);
@ -660,33 +671,39 @@ bool skill_isNotOk_hom(uint16 skill_id, struct homun_data *hd)
if(hd->homunculus.hunger <= 1) return true; if(hd->homunculus.hunger <= 1) return true;
break; break;
case MH_GOLDENE_FERSE: //cant be used with angriff case MH_GOLDENE_FERSE: //cant be used with angriff
if(hd->sc.data[SC_ANGRIFFS_MODUS]) return true; if(&hd->sc && hd->sc.data[SC_ANGRIFFS_MODUS]) return true;
break; break;
case MH_ANGRIFFS_MODUS: case MH_ANGRIFFS_MODUS:
if(hd->sc.data[SC_GOLDENE_FERSE]) return true; if(&hd->sc && hd->sc.data[SC_GOLDENE_FERSE]) return true;
break; break;
case MH_TINDER_BREAKER: //must be in grappling mode case MH_TINDER_BREAKER: //must be in grappling mode
if(!(hd->sc.data[SC_STYLE_CHANGE] && hd->sc.data[SC_STYLE_CHANGE]->val1 == MH_MD_GRAPPLING) if(!&hd->sc
|| !(hd->sc.data[SC_STYLE_CHANGE] && hd->sc.data[SC_STYLE_CHANGE]->val1 == MH_MD_GRAPPLING)
|| !hd->homunculus.spiritball) return true; || !hd->homunculus.spiritball) return true;
break; break;
case MH_SONIC_CRAW: //must be in fighting mode case MH_SONIC_CRAW: //must be in fighting mode
if(!(hd->sc.data[SC_STYLE_CHANGE] && hd->sc.data[SC_STYLE_CHANGE]->val1 == MH_MD_FIGHTING) if(!&hd->sc
|| !(hd->sc.data[SC_STYLE_CHANGE] && hd->sc.data[SC_STYLE_CHANGE]->val1 == MH_MD_FIGHTING)
|| !hd->homunculus.spiritball) return true; || !hd->homunculus.spiritball) return true;
break; break;
case MH_SILVERVEIN_RUSH: case MH_SILVERVEIN_RUSH:
if(!(hd->sc.data[SC_COMBO] && hd->sc.data[SC_COMBO]->val1 == MH_SONIC_CRAW) if(!&hd->sc
|| !(hd->sc.data[SC_COMBO] && hd->sc.data[SC_COMBO]->val1 == MH_SONIC_CRAW)
|| hd->homunculus.spiritball < 2) return true; || hd->homunculus.spiritball < 2) return true;
break; break;
case MH_MIDNIGHT_FRENZY: case MH_MIDNIGHT_FRENZY:
if(!(hd->sc.data[SC_COMBO] && hd->sc.data[SC_COMBO]->val1 == MH_SILVERVEIN_RUSH) if(!&hd->sc
|| !(hd->sc.data[SC_COMBO] && hd->sc.data[SC_COMBO]->val1 == MH_SILVERVEIN_RUSH)
|| !hd->homunculus.spiritball) return true; || !hd->homunculus.spiritball) return true;
break; break;
case MH_CBC: case MH_CBC:
if(!(hd->sc.data[SC_COMBO] && hd->sc.data[SC_COMBO]->val1 == MH_TINDER_BREAKER) if(!&hd->sc
|| !(hd->sc.data[SC_COMBO] && hd->sc.data[SC_COMBO]->val1 == MH_TINDER_BREAKER)
|| hd->homunculus.spiritball < 2) return true; || hd->homunculus.spiritball < 2) return true;
break; break;
case MH_EQC: case MH_EQC:
if(!(hd->sc.data[SC_COMBO] && hd->sc.data[SC_COMBO]->val1 == MH_CBC) if(!&hd->sc
|| !(hd->sc.data[SC_COMBO] && hd->sc.data[SC_COMBO]->val1 == MH_CBC)
|| hd->homunculus.spiritball < 3) return true; || hd->homunculus.spiritball < 3) return true;
break; break;
} }
@ -695,6 +712,12 @@ bool skill_isNotOk_hom(uint16 skill_id, struct homun_data *hd)
return skill_isNotOk(skill_id, hd->master); return skill_isNotOk(skill_id, hd->master);
} }
/** Check if the mercenary skill is ok to be processed
* After checking from Homunculus side, also check the master condition
* @param skill_id: Skill ID that casted
* @param md: Mercenary who casted
* @return true: Skill cannot be used, false: otherwise
*/
bool skill_isNotOk_mercenary(uint16 skill_id, struct mercenary_data *md) bool skill_isNotOk_mercenary(uint16 skill_id, struct mercenary_data *md)
{ {
uint16 idx = skill_get_index(skill_id); uint16 idx = skill_get_index(skill_id);
@ -708,9 +731,16 @@ bool skill_isNotOk_mercenary(uint16 skill_id, struct mercenary_data *md)
return skill_isNotOk(skill_id, md->master); return skill_isNotOk(skill_id, md->master);
} }
/// Check if the skill can be casted near NPC or not [Cydh] /** Check if the skill can be casted near NPC or not
/// NOTE: 'target' may be NULL if the skill is targetting ground/area * @param src Object who casted
bool skill_isNotOk_npcRange(struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, int pos_x, int pos_y) { * @param skill_id Skill ID that casted
* @param skill_lv Skill Lv
* @param pos_x Position x of the target
* @param pos_y Position y of the target
* @return true: Skill cannot be used, false: otherwise
* @author [Cydh]
*/
bool skill_isNotOk_npcRange(struct block_list *src, uint16 skill_id, uint16 skill_lv, int pos_x, int pos_y) {
int inf; int inf;
if (!src || skill_get_index(skill_id) < 0) if (!src || skill_get_index(skill_id) < 0)
@ -726,10 +756,8 @@ bool skill_isNotOk_npcRange(struct block_list *src, struct block_list *target, u
pos_y = src->y; pos_y = src->y;
} }
if (pos_x <= 0 || pos_y <= 0) { if (pos_x <= 0) pos_x = src->x;
pos_x = src->x; if (pos_y <= 0) pos_y = src->y;
pos_y = src->y;
}
return skill_check_unit_range2(src,pos_x,pos_y,skill_id,skill_lv,true); return skill_check_unit_range2(src,pos_x,pos_y,skill_id,skill_lv,true);
} }
@ -2526,8 +2554,7 @@ static void skill_do_copy(struct block_list* src,struct block_list *bl, uint16 s
tsd->status.skill[tsd->cloneskill_idx].flag = SKILL_FLAG_PERMANENT; tsd->status.skill[tsd->cloneskill_idx].flag = SKILL_FLAG_PERMANENT;
} }
if ((lv = pc_checkskill(tsd,RG_PLAGIARISM)) < skill_lv) lv = min(skill_lv,pc_checkskill(tsd,RG_PLAGIARISM)); //Copied level never be > player's RG_PLAGIARISM level
skill_lv = lv;
tsd->cloneskill_idx = idx; tsd->cloneskill_idx = idx;
pc_setglobalreg(tsd,SKILL_VAR_PLAGIARISM,skill_id); pc_setglobalreg(tsd,SKILL_VAR_PLAGIARISM,skill_id);
@ -2547,6 +2574,12 @@ static void skill_do_copy(struct block_list* src,struct block_list *bl, uint16 s
tsd->status.skill[tsd->reproduceskill_idx].flag = SKILL_FLAG_PERMANENT; tsd->status.skill[tsd->reproduceskill_idx].flag = SKILL_FLAG_PERMANENT;
} }
//Level dependent and limitation.
if (src->type == BL_PC) //If player, max skill level is skill_get_max(skill_id)
lv = min(lv,skill_get_max(skill_id));
else //Monster might used skill level > allowed player max skill lv. Ex. Drake with Waterball lv. 10
lv = min(lv,skill_lv);
tsd->reproduceskill_idx = idx; tsd->reproduceskill_idx = idx;
pc_setglobalreg(tsd,SKILL_VAR_REPRODUCE,skill_id); pc_setglobalreg(tsd,SKILL_VAR_REPRODUCE,skill_id);
pc_setglobalreg(tsd,SKILL_VAR_REPRODUCE_LV,lv); pc_setglobalreg(tsd,SKILL_VAR_REPRODUCE_LV,lv);
@ -2582,7 +2615,8 @@ int64 skill_attack (int attack_type, struct block_list* src, struct block_list *
struct map_session_data *sd, *tsd; struct map_session_data *sd, *tsd;
int64 damage; int64 damage;
int8 rmdamage=0;//magic reflected int8 rmdamage=0;//magic reflected
int type, shadow_flag = 0; int type;
bool shadow_flag = false;
bool additional_effects = true; bool additional_effects = true;
if(skill_id > 0 && !skill_lv) return 0; if(skill_id > 0 && !skill_lv) return 0;
@ -3194,7 +3228,15 @@ static int skill_check_unit_range2_sub (struct block_list *bl, va_list ap)
return 1; return 1;
} }
//NOTE: 'isNearNPC' is used to check is the skill near NPC or not, if yes will use npc_isnear and range calculation [Cydh] /** Used to check range condition of the casted skill. Used if the skill has UF_NOFOOTSET or INF2_NO_NEARNPC
* @param bl Object that casted skill
* @param x Position x of the target
* @param y Position y of the target
* @param skill_id The casted skill
* @param skill_lv The skill Lv
* @param isNearNPC 'true' means, check the range between target and nearer NPC by using npc_isnear and range calculation [Cydh]
* @return 0: No object (BL_CHAR or BL_PC) within the range. If 'isNearNPC' the target oject is BL_NPC
*/
static int skill_check_unit_range2 (struct block_list *bl, int x, int y, uint16 skill_id, uint16 skill_lv, bool isNearNPC) static int skill_check_unit_range2 (struct block_list *bl, int x, int y, uint16 skill_id, uint16 skill_lv, bool isNearNPC)
{ {
int range = 0, type; int range = 0, type;
@ -5472,7 +5514,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
abra_skill_id = skill_abra_db[i].skill_id; abra_skill_id = skill_abra_db[i].skill_id;
abra_skill_lv = min(skill_lv, skill_get_max(abra_skill_id)); abra_skill_lv = min(skill_lv, skill_get_max(abra_skill_id));
} while (abra_skill_id == 0 || } while (abra_skill_id == 0 ||
rnd()%10000 >= skill_abra_db[i].per[abra_skill_lv] rnd()%10000 >= skill_abra_db[i].per[max(skill_lv-1,0)]
); );
clif_skill_nodamage (src, bl, skill_id, skill_lv, 1); clif_skill_nodamage (src, bl, skill_id, skill_lv, 1);
@ -16079,15 +16121,15 @@ bool skill_check_cloaking(struct block_list *bl, struct status_change_entry *sce
* @param bl: Target * @param bl: Target
* @param damage: Damage amount * @param damage: Damage amount
* @param hit * @param hit
* @return val * @return true - in Shadow Form state; false - otherwise
*/ */
char skill_check_shadowform(struct block_list *bl, int64 damage, int hit) { bool skill_check_shadowform(struct block_list *bl, int64 damage, int hit) {
struct status_change *sc; struct status_change *sc;
nullpo_retr(0, bl); nullpo_retr(false,bl);
if (!damage) if (!damage)
return 0; return false;
sc = status_get_sc(bl); sc = status_get_sc(bl);
@ -16096,14 +16138,14 @@ char skill_check_shadowform(struct block_list *bl, int64 damage, int hit) {
if( !src || src->m != bl->m ) { if( !src || src->m != bl->m ) {
status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER); status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER);
return 0; return false;
} }
if( src && (status_isdead(src) || !battle_check_target(bl,src,BCT_ENEMY)) ) { if( src && (status_isdead(src) || !battle_check_target(bl,src,BCT_ENEMY)) ) {
if( src->type == BL_PC ) if( src->type == BL_PC )
((TBL_PC*)src)->shadowform_id = 0; ((TBL_PC*)src)->shadowform_id = 0;
status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER); status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER);
return 0; return false;
} }
status_damage(bl, src, damage, 0, clif_damage(src, src, gettick(), 500, 500, damage, hit, (hit > 1 ? 8 : 0), 0), 0); status_damage(bl, src, damage, 0, clif_damage(src, src, gettick(), 500, 500, damage, hit, (hit > 1 ? 8 : 0), 0), 0);
@ -16112,9 +16154,9 @@ char skill_check_shadowform(struct block_list *bl, int64 damage, int hit) {
if( src->type == BL_PC ) if( src->type == BL_PC )
((TBL_PC*)src)->shadowform_id = 0; ((TBL_PC*)src)->shadowform_id = 0;
} }
return 1; return true;
} }
return 0; return false;
} }
bool skill_check_camouflage(struct block_list *bl, struct status_change_entry *sce) bool skill_check_camouflage(struct block_list *bl, struct status_change_entry *sce)

View File

@ -417,7 +417,7 @@ bool skill_isNotOk(uint16 skill_id, struct map_session_data *sd);
bool skill_isNotOk_hom(uint16 skill_id, struct homun_data *hd); bool skill_isNotOk_hom(uint16 skill_id, struct homun_data *hd);
bool skill_isNotOk_mercenary(uint16 skill_id, struct mercenary_data *md); bool skill_isNotOk_mercenary(uint16 skill_id, struct mercenary_data *md);
bool skill_isNotOk_npcRange(struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, int pos_x, int pos_y); bool skill_isNotOk_npcRange(struct block_list *src, uint16 skill_id, uint16 skill_lv, int pos_x, int pos_y);
int skill_chastle_mob_changetarget(struct block_list *bl,va_list ap); int skill_chastle_mob_changetarget(struct block_list *bl,va_list ap);
@ -1966,7 +1966,7 @@ struct s_skill_magicmushroom_db {
}; };
extern struct s_skill_magicmushroom_db skill_magicmushroom_db[MAX_SKILL_MAGICMUSHROOM_DB]; extern struct s_skill_magicmushroom_db skill_magicmushroom_db[MAX_SKILL_MAGICMUSHROOM_DB];
int skill_maelstrom_suction(struct block_list *bl, va_list ap); int skill_maelstrom_suction(struct block_list *bl, va_list ap);
char skill_check_shadowform(struct block_list *bl, int64 damage, int hit); bool skill_check_shadowform(struct block_list *bl, int64 damage, int hit);
/** /**
* Ranger * Ranger
**/ **/

View File

@ -1357,7 +1357,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
return 0; return 0;
// Fail if the targetted skill is near NPC [Cydh] // Fail if the targetted skill is near NPC [Cydh]
if(skill_get_inf2(skill_id)&INF2_NO_NEARNPC && skill_isNotOk_npcRange(src,target,skill_id,skill_lv,target->x,target->y)) { if(skill_get_inf2(skill_id)&INF2_NO_NEARNPC && skill_isNotOk_npcRange(src,skill_id,skill_lv,target->x,target->y)) {
if (sd) if (sd)
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0; return 0;
@ -1674,7 +1674,7 @@ int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, ui
return 0; return 0;
// Fail if the targetted skill is near NPC [Cydh] // Fail if the targetted skill is near NPC [Cydh]
if(skill_get_inf2(skill_id)&INF2_NO_NEARNPC && skill_isNotOk_npcRange(src,NULL,skill_id,skill_lv,skill_x,skill_y)) { if(skill_get_inf2(skill_id)&INF2_NO_NEARNPC && skill_isNotOk_npcRange(src,skill_id,skill_lv,skill_x,skill_y)) {
if (sd) if (sd)
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0; return 0;