* Fixed bugreport:8471, http://rathena.org/board/tracker/issue-8471-star-gladiators-feeling-randomising-map/
* Follow up f4eb33e, 5a2849d Signed-off-by: Cydh Ramdh <house.bad@gmail.com>
This commit is contained in:
parent
1a9b546540
commit
a32d3a6e76
@ -8994,7 +8994,7 @@ void clif_feel_info(struct map_session_data* sd, unsigned char feel_level, unsig
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -122,16 +122,18 @@ struct view_data* npc_get_viewdata(int class_)
|
||||
int npc_isnear_sub(struct block_list* bl, va_list args) {
|
||||
struct npc_data *nd = (struct npc_data*)bl;
|
||||
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 && (idx = skill_get_index(skill_id)) && skill_db[idx].unit_nonearnpc_type) {
|
||||
while (1) {
|
||||
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&4 && nd->subtype == SCRIPT) break;
|
||||
if (skill_db[idx].unit_nonearnpc_type&8 && nd->subtype == TOMB) break;
|
||||
return 0;
|
||||
if (skill_id > 0) { //If skill_id > 0 that means is used for INF2_NO_NEARNPC [Cydh]
|
||||
int16 idx = skill_get_index(skill_id);
|
||||
|
||||
if (idx >= 0 && skill_db[idx].unit_nonearnpc_type) {
|
||||
while (1) {
|
||||
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&4 && nd->subtype == SCRIPT) break;
|
||||
if (skill_db[idx].unit_nonearnpc_type&8 && nd->subtype == TOMB) break;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1231,7 +1231,7 @@ int pc_reg_received(struct map_session_data *sd)
|
||||
//SG map and mob read [Komurka]
|
||||
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) {
|
||||
sd->feel_map[i].index = j;
|
||||
sd->feel_map[i].m = map_mapindex2mapid(j);
|
||||
@ -1254,10 +1254,10 @@ int pc_reg_received(struct map_session_data *sd)
|
||||
}
|
||||
if ((i = pc_checkskill(sd,SC_REPRODUCE)) > 0) {
|
||||
sd->reproduceskill_idx = skill_get_index(pc_readglobalreg(sd,SKILL_VAR_REPRODUCE));
|
||||
if( sd->reproduceskill_idx >= 0) {
|
||||
if (sd->reproduceskill_idx >= 0) {
|
||||
sd->status.skill[sd->reproduceskill_idx].id = pc_readglobalreg(sd,SKILL_VAR_REPRODUCE);
|
||||
sd->status.skill[sd->reproduceskill_idx].lv = pc_readglobalreg(sd,SKILL_VAR_REPRODUCE_LV);
|
||||
if( i < sd->status.skill[sd->reproduceskill_idx].lv)
|
||||
if (i < sd->status.skill[sd->reproduceskill_idx].lv)
|
||||
sd->status.skill[sd->reproduceskill_idx].lv = i;
|
||||
sd->status.skill[sd->reproduceskill_idx].flag = SKILL_FLAG_PLAGIARIZED;
|
||||
}
|
||||
|
104
src/map/skill.c
104
src/map/skill.c
@ -450,7 +450,7 @@ int skill_calc_heal(struct block_list *src, struct block_list *target, uint16 sk
|
||||
* @param sd: Player who will copy the skill
|
||||
* @param skill_id: Target skill
|
||||
* @return 0 - Cannot be copied; 1 - Can be copied by Plagiarism 2 - Can be copied by Reproduce
|
||||
* @author Aru -for previous check; Jobbie for class restriction idea; Cydh expands the copyable skill
|
||||
* @author Aru - for previous check; Jobbie for class restriction idea; Cydh expands the copyable skill
|
||||
*/
|
||||
static char skill_isCopyable(struct map_session_data *sd, uint16 skill_id) {
|
||||
int idx = skill_get_index(skill_id);
|
||||
@ -484,8 +484,13 @@ static char skill_isCopyable(struct map_session_data *sd, uint16 skill_id) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// [MouseJstr] - skill ok to cast? and when?
|
||||
//done before check_condition_begin, requirement
|
||||
/** Check if the skill is ok to cast and when.
|
||||
* 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)
|
||||
{
|
||||
int16 idx,m;
|
||||
@ -641,6 +646,12 @@ bool skill_isNotOk(uint16 skill_id, struct map_session_data *sd)
|
||||
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)
|
||||
{
|
||||
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;
|
||||
break;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
break;
|
||||
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;
|
||||
break;
|
||||
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;
|
||||
break;
|
||||
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;
|
||||
break;
|
||||
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;
|
||||
break;
|
||||
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;
|
||||
break;
|
||||
}
|
||||
@ -695,6 +712,12 @@ bool skill_isNotOk_hom(uint16 skill_id, struct homun_data *hd)
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
/// Check if the skill can be casted near NPC or not [Cydh]
|
||||
/// NOTE: 'target' may be NULL if the skill is targetting ground/area
|
||||
bool skill_isNotOk_npcRange(struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, int pos_x, int pos_y) {
|
||||
/** Check if the skill can be casted near NPC or not
|
||||
* @param src Object who casted
|
||||
* @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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (pos_x <= 0 || pos_y <= 0) {
|
||||
pos_x = src->x;
|
||||
pos_y = src->y;
|
||||
}
|
||||
if (pos_x <= 0) pos_x = src->x;
|
||||
if (pos_y <= 0) pos_y = src->y;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if ((lv = pc_checkskill(tsd,RG_PLAGIARISM)) < skill_lv)
|
||||
skill_lv = lv;
|
||||
lv = min(skill_lv,pc_checkskill(tsd,RG_PLAGIARISM)); //Copied level never be > player's RG_PLAGIARISM level
|
||||
|
||||
tsd->cloneskill_idx = idx;
|
||||
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;
|
||||
}
|
||||
|
||||
//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;
|
||||
pc_setglobalreg(tsd,SKILL_VAR_REPRODUCE,skill_id);
|
||||
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;
|
||||
int64 damage;
|
||||
int8 rmdamage=0;//magic reflected
|
||||
int type, shadow_flag = 0;
|
||||
int type;
|
||||
bool shadow_flag = false;
|
||||
bool additional_effects = true;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
//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)
|
||||
{
|
||||
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_lv = min(skill_lv, skill_get_max(abra_skill_id));
|
||||
} 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);
|
||||
@ -16079,15 +16121,15 @@ bool skill_check_cloaking(struct block_list *bl, struct status_change_entry *sce
|
||||
* @param bl: Target
|
||||
* @param damage: Damage amount
|
||||
* @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;
|
||||
|
||||
nullpo_retr(0, bl);
|
||||
nullpo_retr(false,bl);
|
||||
|
||||
if (!damage)
|
||||
return 0;
|
||||
return false;
|
||||
|
||||
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 ) {
|
||||
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->type == BL_PC )
|
||||
((TBL_PC*)src)->shadowform_id = 0;
|
||||
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);
|
||||
@ -16112,9 +16154,9 @@ char skill_check_shadowform(struct block_list *bl, int64 damage, int hit) {
|
||||
if( src->type == BL_PC )
|
||||
((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)
|
||||
|
@ -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_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);
|
||||
|
||||
@ -1966,7 +1966,7 @@ struct s_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);
|
||||
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
|
||||
**/
|
||||
|
@ -1357,7 +1357,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
|
||||
return 0;
|
||||
|
||||
// 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)
|
||||
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
|
||||
return 0;
|
||||
@ -1674,7 +1674,7 @@ int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, ui
|
||||
return 0;
|
||||
|
||||
// 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)
|
||||
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
|
||||
return 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user