Jump to content
  • 0
ThyroDree

Job Skills and Stats Modification

Question

Hello, Anyone willing to help with my little project.  :D

 

  • Stalker - cannot copy skill from monster when got attacked
  • Stalker - Reject Sword will also work on Spear,  and Axe Weapons (Original effect work only for Sword, Dagger)
  • Assassin X - Enchant Deadly Poison will be cancelled (Specifically), if used Fury/Berserk.
  • Sniper - Blitz Beat will not miss/affected by Pneuma & Reverse Tatami

SKILLS

  • Healing Skill max. limit or cap will be 100%. Having 101% or 150% Increase Effectiveness of Healing Skill will be limit to 100% only.
  • True Sight Skill (Sniper)I cannot find the source code to modify. Checked battle.c/h skill.c/.h, and status.c
  • Mind Breaker (MATK Buff), Deluge(HP Buff), Violent Gale (Flee Buff), and Volcano (Attack Buff) I can't also find their source code.

STATS

  • Where can I modify / edit minimum & maximum MATK Formulas (Derives Player Base Level, Status INT)
  • Where can I modify the MATKModifier, the Original Calculation for MATK = (StatusMATK + WeaponMATK + EquipMATK) × MATKModifier, I wanted to make MATK = StatusMATK * MATKModifier (means even I have equipment with high MATK, It wont affected by MATKModifier

 

It really helps me learn and understand sources by the help of others, cuz Im really trying to analyze, how it works. Above this are the things I can't seem to find or maybe requires additional source codes which is im not yet very good at.

So, thank you in advance! Be Safe from COVID 19. 👩‍⚕️ 😷

Edited by ThyroDree

Share this post


Link to post
Share on other sites

5 answers to this question

Recommended Posts

  • 0

Hi.

 

Quote

Stalker - cannot copy skill from monster when got attacked

More details please. I'm not sure what you really want to do.

 

 

Quote

Stalker - Reject Sword will also work on Spear,  and Axe Weapons (Original effect work only for Sword, Dagger)

In src/map/battle.c -> battle_calc_weapon_attack()

// Change:
&& (sd == NULL || sd->weapontype1 == W_DAGGER || sd->weapontype1 == W_1HSWORD || sd->weapontype == W_2HSWORD)

// To:
&& (sd == NULL || (sd->weapontype1 >= W_DAGGER && sd->weapontype1 <= W_2HAXE))

 

 

Quote

Assassin X - Enchant Deadly Poison will be cancelled (Specifically), if used Fury/Berserk.

In src/map/skills.c -> skill_castend_nodamage_id()

// Change:
case SU_ARCLOUSEDASH:
	clif->skill_nodamage(src,bl,skill_id,skill_lv,
		sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
	break;

// To:
case SU_ARCLOUSEDASH:
	clif->skill_nodamage(src, bl, skill_id, skill_lv,
		sc_start(src, bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv)));

	if (sd != NULL && (skill_id == LK_BERSERK || skill_id == MO_EXPLOSIONSPIRITS))
		status_change_end(src, SC_DPOISON, INVALID_TIMER);

	break;

 

 

Quote

Sniper - Blitz Beat will not miss/affected by Pneuma & Reverse Tatami

In src/map/battle.c -> battle_calc_damage()

// Change:
if( ( sc->data[SC_PNEUMA] && (flag&(BF_MAGIC|BF_LONG)) == BF_LONG ) || sc->data[SC__MANHOLE] ) {
	d->dmg_lv = ATK_BLOCK;
	return 0;
}

// To:
if ((sc->data[SC_PNEUMA] != NULL && (flag & (BF_MAGIC | BF_LONG)) == BF_LONG) || sc->data[SC__MANHOLE] != NULL) {
	if (sc->data[SC_PNEUMA] == NULL // Not Pneuma but Man Hole -> Block attack!
	    || skill_id != HT_BLITZBEAT // Not Blitz Beat -> Block attack!
	    || s_sd == NULL // Attacker is not a character -> Block attack!
	    || s_sd->job != MAPID_SNIPER) { // Attacker is not a Sniper -> Block attack!
		d->dmg_lv = ATK_BLOCK;
		return 0;
	}
}

// ##############################################################################################

// Change:
if(sc->data[SC_NJ_TATAMIGAESHI] && (flag&(BF_MAGIC|BF_LONG)) == BF_LONG)
	return 0;

// To:
if (sc->data[SC_NJ_TATAMIGAESHI] != NULL && (flag & (BF_MAGIC | BF_LONG)) == BF_LONG) {
	if (skill_id != HT_BLITZBEAT // Not Blitz Beat -> Block attack!
	    || s_sd == NULL // Attacker is not a character -> Block attack!
	    || s_sd->job != MAPID_SNIPER) { // Attacker is not a Sniper -> Block attack!
		return 0;
	}
}

 

 

Quote

Healing Skill max. limit or cap will be 100%. Having 101% or 150% Increase Effectiveness of Healing Skill will be limit to 100% only.

Modify skill_add_heal_rate in conf/map/battle/skill.conf.

 

 

Quote

 

True Sight Skill (Sniper)I cannot find the source code to modify. Checked battle.c/h skill.c/.h, and status.c

Mind Breaker (MATK Buff), Deluge(HP Buff), Violent Gale (Flee Buff), and Volcano (Attack Buff) I can't also find their source code.

 

I guess you want to modify the bonus stats. Therefor just search for these constants in src/map/status.c:

SC_TRUESIGHT
SC_MINDBREAKER
SC_DELUGE
SC_VIOLENTGALE
SC_VOLCANO

 

 

Quote

Where can I modify / edit minimum & maximum MATK Formulas (Derives Player Base Level, Status INT)

In src/map/status.c have a look at these functions:

status_base_matk_min()
status_base_matk_max()

 

 

Quote

Where can I modify the MATKModifier, the Original Calculation for MATK = (StatusMATK + WeaponMATK + EquipMATK) × MATKModifier, I wanted to make MATK = StatusMATK * MATKModifier (means even I have equipment with high MATK, It wont affected by MATKModifier

That's not as easy as you may think. To keep it simple, just don't apply the bMatk and bMatkRate bonuses.
In src/map/pc.c -> pc_bonus()

// Change:
case SP_MATK_RATE:
	if(sd->state.lr_flag != 2)
		sd->matk_rate += val;
	break;

// To:
case SP_MATK_RATE:
	   break;

// ##############################################################################################

// Change:
case SP_EMATK:
	   if(sd->state.lr_flag != 2)
		   sd->bonus.ematk += val;
	   break;

// To:
case SP_EMATK:
	   break;

 

 

 

~Kenpachi

Share this post


Link to post
Share on other sites
  • 0
Quote

Stalker - cannot copy skill from monster when got attacked 

Example: Stalker copied a skill from a Wizard Player [Storm Gust Level 10], and went to farm from monster but forgot to use preserve skill. On my suggestion even stalker forgot the preserve skill, it will not copy the skill from monster and lose the storm gust level 10. (Normally he/she will lose the Storm Gust Skill, and gets the skill from monster once he/she got hit) In short, Stalker can only copy skills from player-player not player-monster.
 

Assassin EDP Skill

// To:
case SU_ARCLOUSEDASH:
	clif->skill_nodamage(src, bl, skill_id, skill_lv,
		sc_start(src, bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv)));

	if (sd != NULL && (skill_id == LK_BERSERK || skill_id == MO_EXPLOSIONSPIRITS))
		status_change_end(src, SC_DPOISON, INVALID_TIMER);

	break;

Made this and tried to the test server, the EDP skill is not cancelled. (see attached file)

 

 

Quote

 

Quote

Healing Skill max. limit or cap will be 100%. Having 101% or 150% Increase Effectiveness of Healing Skill will be limit to 100% only.

Modify skill_add_heal_rate in conf/map/battle/skill.conf.

 

It only set which skill will be affected by HealPower,

I mean on this is, capping the healpower to 100%, example: bacsojin card give 30% heal power, even Player equip 4 bacsojin cards it will only read 100% heal power instead of 120%.

 

 

In src/map/status.c have a look at these functions:

status_base_matk_min()

status_base_matk_max()

Tried to search this lines, I cant find it on status.c

On this, I wanted to make look like this

Bonus to minimum MATK every 5 INT

Bonus to maximum MATK every 7 INT

 

 

I have a question, I just want to clarify does.

SCB_MDEF - Hard Defense? (Equipment Status Defense)

SCB_MDEF2 - Soft Defense? (Int status defense)

screenLoki 001.jpg

Share this post


Link to post
Share on other sites
  • 0
Quote

Example: Stalker copied a skill from a Wizard Player [Storm Gust Level 10], and went to farm from monster but forgot to use preserve skill. On my suggestion even stalker forgot the preserve skill, it will not copy the skill from monster and lose the storm gust level 10. (Normally he/she will lose the Storm Gust Skill, and gets the skill from monster once he/she got hit) In short, Stalker can only copy skills from player-player not player-monster.

in src/map/skill.c -> skill_attack()

// Change:
if (damage > 0 && dmg.flag&BF_SKILL && tsd
 && pc->checkskill(tsd,RG_PLAGIARISM)
 && (!sc || !sc->data[SC_PRESERVE])
 && damage < tsd->battle_status.hp

// To:
if (damage > 0 && dmg.flag&BF_SKILL && tsd
 && pc->checkskill(tsd,RG_PLAGIARISM)
 && (!sc || !sc->data[SC_PRESERVE])
 && damage < tsd->battle_status.hp
 && src->type == BL_PC // Skill was cast by a character.

 

 

Quote

Made this and tried to the test server, the EDP skill is not cancelled. (see attached file)

Okay, misunderstood you here. I though you want to end the poison status when a Lord Knight casts Berserk or a Monk casts Fury.

In this case I need an explanation. I don't know what you want to achieve.

 

 

Quote

 

It only set which skill will be affected by HealPower,

I mean on this is, capping the healpower to 100%, example: bacsojin card give 30% heal power, even Player equip 4 bacsojin cards it will only read 100% heal power instead of 120%.

 

In src/map/pc.c -> pc_bonus()

// Change:
case SP_ADD_HEAL_RATE:
	if(sd->state.lr_flag != 2)
		sd->bonus.add_heal_rate += val;
	break;
case SP_ADD_HEAL2_RATE:
	if(sd->state.lr_flag != 2)
		sd->bonus.add_heal2_rate += val;
	break;

// To:
case SP_ADD_HEAL_RATE:
	if(sd->state.lr_flag != 2)
		sd->bonus.add_heal_rate += val;

	sd->bonus.add_heal_rate = min(sd->bonus.add_heal_rate, 100);
	break;
case SP_ADD_HEAL2_RATE:
	if(sd->state.lr_flag != 2)
		sd->bonus.add_heal2_rate += val;

	sd->bonus.add_heal2_rate = min(sd->bonus.add_heal2_rate, 100);
	break;

// ###################################################################################################

// Change:
case SP_SKILL_HEAL:
	if(sd->state.lr_flag == 2)
		break;
	ARR_FIND(0, ARRAYLENGTH(sd->skillheal), i, sd->skillheal[i].id == 0 || sd->skillheal[i].id == type2);
	if (i == ARRAYLENGTH(sd->skillheal)) {
		// Better mention this so the array length can be updated. [Skotlex]
		ShowDebug("script->run: bonus2 bSkillHeal reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n",
			  ARRAYLENGTH(sd->skillheal), type2, val);
		break;
	}
	if (sd->skillheal[i].id == type2)
		sd->skillheal[i].val += val;
	else {
		sd->skillheal[i].id = type2;
		sd->skillheal[i].val = val;
	}
	break;
case SP_SKILL_HEAL2:
	if(sd->state.lr_flag == 2)
		break;
	ARR_FIND(0, ARRAYLENGTH(sd->skillheal2), i, sd->skillheal2[i].id == 0 || sd->skillheal2[i].id == type2);
	if (i == ARRAYLENGTH(sd->skillheal2)) {
		// Better mention this so the array length can be updated. [Skotlex]
		ShowDebug("script->run: bonus2 bSkillHeal2 reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n",
			  ARRAYLENGTH(sd->skillheal2), type2, val);
		break;
	}
	if (sd->skillheal2[i].id == type2)
		sd->skillheal2[i].val += val;
	else {
		sd->skillheal2[i].id = type2;
		sd->skillheal2[i].val = val;
	}
	break;

// To:
case SP_SKILL_HEAL:
	if(sd->state.lr_flag == 2)
		break;
	ARR_FIND(0, ARRAYLENGTH(sd->skillheal), i, sd->skillheal[i].id == 0 || sd->skillheal[i].id == type2);
	if (i == ARRAYLENGTH(sd->skillheal)) {
		// Better mention this so the array length can be updated. [Skotlex]
		ShowDebug("script->run: bonus2 bSkillHeal reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n",
			  ARRAYLENGTH(sd->skillheal), type2, val);
		break;
	}
	if (sd->skillheal[i].id == type2)
		sd->skillheal[i].val += val;
	else {
		sd->skillheal[i].id = type2;
		sd->skillheal[i].val = val;
	}

	sd->skillheal[i].val = min(sd->skillheal[i].val, 100);
	break;
case SP_SKILL_HEAL2:
	if(sd->state.lr_flag == 2)
		break;
	ARR_FIND(0, ARRAYLENGTH(sd->skillheal2), i, sd->skillheal2[i].id == 0 || sd->skillheal2[i].id == type2);
	if (i == ARRAYLENGTH(sd->skillheal2)) {
		// Better mention this so the array length can be updated. [Skotlex]
		ShowDebug("script->run: bonus2 bSkillHeal2 reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n",
			  ARRAYLENGTH(sd->skillheal2), type2, val);
		break;
	}
	if (sd->skillheal2[i].id == type2)
		sd->skillheal2[i].val += val;
	else {
		sd->skillheal2[i].id = type2;
		sd->skillheal2[i].val = val;
	}

	sd->skillheal2[i].val = min(sd->skillheal2[i].val, 100);
	break;

 

 

Quote

 

Tried to search this lines, I cant find it on status.c

On this, I wanted to make look like this

Bonus to minimum MATK every 5 INT

Bonus to maximum MATK every 7 INT

 

That's done in the functions I posted. I can't believe your status.c doesn't contain them.

 

 

Quote

 

I have a question, I just want to clarify does.

SCB_MDEF - Hard Defense? (Equipment Status Defense)

SCB_MDEF2 - Soft Defense? (Int status defense)

 

Well, I guess one could call them like this.

 

 

~Kenpachi

Share this post


Link to post
Share on other sites
  • 0
Quote

Made this and tried to the test server, the EDP skill is not cancelled. (see attached file)

Quote

Okay, misunderstood you here. I though you want to end the poison status when a Lord Knight casts Berserk or a Monk casts Fury.

In this case I need an explanation. I don't know what you want to achieve.

Hmmm, the Enchant Deadly Poison skill will automatically cancelled when character is on berserk.

 

Example is, when assassin cross will going to break emperium during WoE. and use his skill Enchant Deadly Poison (EDP) to boost his attack, and then if he use Berserk skill from Lord Knight Card. He will lost the boost damage of EDP or EDP  skill will be cancelled, gone on right side screen status area.

 

Sorry for my bad explanation 😕

 

Thank for all your help

 

Share this post


Link to post
Share on other sites
  • 1

Hi.

 

In src/map/skill.c in function skill_castend_nodamage_id() find this block:

case RK_CRUSHSTRIKE:
case ALL_ODINS_POWER:
case SU_FRESHSHRIMP:
case SU_ARCLOUSEDASH:
	clif->skill_nodamage(src,bl,skill_id,skill_lv,
		sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
	break;
// Works just like the above list of skills, except animation caused by
// status must trigger AFTER the skill cast animation or it will cancel
// out the status's animation.
case SU_STOOP:

 

And replace:

clif->skill_nodamage(src,bl,skill_id,skill_lv,
	sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
break;

With:

// End EDP if Assassin Cross uses LK_BERSERK or MO_EXPLOSIONSPIRITS.
if (sd != NULL && sd->job == MAPID_ASSASSIN_CROSS && sd->sc.data[SC_EDP] != NULL
    && (skill_id == LK_BERSERK || skill_id == MO_EXPLOSIONSPIRITS)) {
	status_change_end(&sd->bl, SC_EDP, INVALID_TIMER);
}

int fail = sc_start(src, bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv));
clif->skill_nodamage(src, bl, skill_id, skill_lv, fail);
break;

 

 

~Kenpachi

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.