로스트아크 인벤 스트라이커 게시판

전체보기

모바일 상단 메뉴

본문 페이지

[잡담] (기습 오류 수정) 스커 효율 계산 사이트 & 계산 결과 몇가지 + 코드

양서준
댓글: 28 개
조회: 4236
추천: 21
2024-09-03 05:15:53
스트라이커에 관련한 계산 가능하도록 웹 사이트로 구현해봤습니다!
초보 개발자라 모바일 반응형은 아직이고, pc접속을 추천드립니다.

진화쪽은 아직 스커 관련 스탯만 구현된 상황입니다.
(치명, 예리한 감각, 한계돌파, 일격, 뭉툭한 가시, 인파이팅, 입식타격가만 구현된 상황)

왼쪽에 무기 품질, 스킬 딜 비중, 엘릭서, 장신구를 고정 값으로 넣을 수 있고,
오른쪽에 각인과 진화 스탯을 세팅1, 세팅2로 두어 비교할 수 있습니다.

일단 초기 접속 시에는 세팅1이 제 세팅으로 되어있고, 
아래쪽에 세팅 추가 버튼도 있지만 사용하기 편하게 복제 버튼도 넣어봤습니다.
대부분 니즈가 두가지 세팅 중 뭐가 더 효율이 좋은지 비교일텐데, 복제 눌러주시고 바꾸면 편하실 것 같네요!

아직 캐릭터 검색은 구현을 안했는데, 나중에 캐릭터 검색을 하면 본인 세팅으로 계산할 수 있게 구현 예정입니다.

사용해보시고 ui 피드백, 계산 오류 지적해주시면 정말 감사하겠습니다!! ( _ _ )

F12 누르시고 console 창으로 가시면 세팅 계산에 대한 모든 스탯이 출력되는데, 
혹시 계산 관련 오류 피드백을 해주실 분들은 확인해보면 될 듯 합니다!
대부분 잘 되는 걸로 확인하긴 했는데, 오류가 있을 수도 있습니다..ㅠ
틀은 잘 만들어 뒀으니 계산 오류가 있다면 수정만 하면 잘 써먹을 수 있을 것 같네요!

-------------------------------------------------------------

아래는 제가 사이트 가지고 놀아본 간단한 결과 공유입니다. (사이트 자체의 오류가 있을 수 있습니다)

1. 슈차 고정 기준, 백어택 확률 전 구간 효율은 세팅 상관없이 거의 예둔 > 저받 > 기습
(09/03 14:29 수정)
1. 슈차 고정 기준, 전각 기준 기습 > 예둔 효율 백어택 확률 컷은 약 41%
유물 기준 기습 > 예둔 효율 백어택 확률 컷은 약 45%

2. 기습이 슈차보다 효율이 좋아지는 백어택 확률 컷은 유각 유무와 상관없이 거의 47% 내외
2-1. 만약에 청염각/뇌호격/호왕/나머지의 딜 비중이 34/26/26/14 ->  42/24/24/10으로 바뀐다고
도약 노드 채용을 대충 가정한다면, 백어택 확률 컷은 약 62% 내외
(09/03 14:29 수정)
2. 아드 저받돌 기준, 전 구간 기습 > 슈차

3. 뭉툭한 가시 달인 기준, 전 구간 한계돌파 > 예리한 감각

이 정도로 제가 궁금했던 건 해결됐네요.
만들고 보니 엘릭서를 선택 옵션으로 옮겨야 비교가 편할 것 같은데, 빠른 시일 내에 해보겠습니다!

-------------------------------------------------------------
아래는 피드백용 계산 관련 코드입니다.
# 이슈 수정 기록
09/03 - 예리한 둔기 패널티 반영
09/03, 14:29 - 기습의 대가 수치 오류 수정
// Character.ts

interface FixedStats {
criticalHitRate: number;
criticalDamage: number;
criticalDamageDealt: number;
additionalDamage: number;
}

interface SelectableStats {
engravings: Array<{ engraving: string; level: string; abilityStone: string }>;
evolution: number[];
}

export class Character {
crit_rate: number = 0;
crit_dmg: number = 2;
crit_hit_dmg: number = 1;
additional_dmg: number = 1;
engraving_dmg: number = 1;
back_dmg: number = 1;
charge_dmg: number = 1;
evol_dmg: number = 1;
blunt_level: number = 0;
attack_dmg: number = 1;
crit_stat: number = 66;
is_keen: boolean = false;
skillRatios: { [key: string]: number };

constructor(fixedStats: FixedStats, selectableStats: SelectableStats, skillRatios: { [key: string]: number }) {
this.apply_fixed_stat(fixedStats);
this.apply_selectable_stat(selectableStats);
this.calculate_final_crit_rate();
this.skillRatios = skillRatios;
this.logStats();
}

apply_fixed_stat(fixedStats: FixedStats) {
this.crit_rate += fixedStats.criticalHitRate;
this.crit_dmg += fixedStats.criticalDamage;
this.crit_hit_dmg += fixedStats.criticalDamageDealt;
this.additional_dmg += fixedStats.additionalDamage;
}

apply_selectable_stat(selectableStats: SelectableStats) {
this.apply_engraving(selectableStats.engravings);
this.apply_evolution(selectableStats.evolution);
}

calculate_final_crit_rate() {
this.crit_rate += this.crit_stat / 27.9 / 100;
}

logStats() {
console.log("Character Stats:");
console.log("치명타 확률:", this.crit_rate);
console.log("치명타 피해:", this.crit_dmg);
console.log("치명타 주는 피해:", this.crit_hit_dmg);
console.log("추가 피해:", this.additional_dmg);
console.log("진화형 피해:", this.evol_dmg);
console.log("각인 피해:", this.engraving_dmg);
console.log("백어택 피해:", this.back_dmg);
console.log("차지 피해:", this.charge_dmg);
console.log("공격력 증가:", this.attack_dmg);
console.log("뭉툭한 가시 레벨:", this.blunt_level);
console.log("치명 스탯:", this.crit_stat);
}

apply_engraving(engravings: Array<{ engraving: string; level: string; abilityStone: string }>) {
engravings.forEach(({ engraving, level, abilityStone }) => {
const artifactLevel = parseInt(level.replace("유물", ""));
const abilityStoneLevel = parseInt(abilityStone.replace("lv", ""));

switch (engraving) {
case "원한":
this.apply_grudge(artifactLevel, abilityStoneLevel);
break;
case "예리한 둔기":
this.apply_keen_blunt_weapon(artifactLevel, abilityStoneLevel);
break;
case "기습의 대가":
this.apply_master_brawler(artifactLevel, abilityStoneLevel);
break;
case "아드레날린":
this.apply_adrenaline(artifactLevel, abilityStoneLevel);
break;
case "슈퍼차지":
this.apply_super_charge(artifactLevel, abilityStoneLevel);
break;
case "저주받은 인형":
this.apply_cursed_doll(artifactLevel, abilityStoneLevel);
break;
}
});
}

apply_grudge(artifactLevel: number, abilityStoneLevel: number) {
let value = 1.18 + artifactLevel * 0.0075;
value += [0, 0.03, 0.0375, 0.0525, 0.06][abilityStoneLevel];
this.engraving_dmg *= value;
}

apply_keen_blunt_weapon(artifactLevel: number, abilityStoneLevel: number) {
let value = 0.44 + artifactLevel * 0.02;
value += [0, 0.075, 0.094, 0.132, 0.15][abilityStoneLevel];
this.crit_dmg += value;
this.is_keen = true;
}

apply_master_brawler(artifactLevel: number, abilityStoneLevel: number) {
this.back_dmg += 0.15;
let value = 1.048 + artifactLevel * 0.007;
value += [0, 0.027, 0.034, 0.047, 0.054][abilityStoneLevel];
this.engraving_dmg *= value;
}

apply_adrenaline(artifactLevel: number, abilityStoneLevel: number) {
this.crit_rate += 0.14 + artifactLevel * 0.015;
let attackValue = 0.054;
attackValue += [0, 0.0288, 0.036, 0.0498, 0.057][abilityStoneLevel];
this.attack_dmg += attackValue;
}

apply_super_charge(artifactLevel: number, abilityStoneLevel: number) {
let value = 0.18 + artifactLevel * 0.0075;
value += [0, 0.03, 0.0375, 0.0525, 0.06][abilityStoneLevel];
this.charge_dmg += value;
}

apply_cursed_doll(artifactLevel: number, abilityStoneLevel: number) {
let value = 1.14 + artifactLevel * 0.0075;
value += [0, 0.03, 0.0375, 0.0525, 0.06][abilityStoneLevel];
this.engraving_dmg *= value;
}

apply_evolution(evolution: number[]) {
// 예리한 감각
this.crit_stat += evolution[2] * 50;

if (evolution[8] === 15) {
this.crit_rate += 0.04;
this.evol_dmg += 0.05;
} else if (evolution[8] === 30) {
this.crit_rate += 0.08;
this.evol_dmg += 0.1;
}

// 한계돌파
if (evolution[9] === 10) {
this.evol_dmg += 0.1;
} else if (evolution[9] === 20) {
this.evol_dmg += 0.2;
} else if (evolution[9] === 30) {
this.evol_dmg += 0.3;
}

// 일격
if (evolution[14] === 10) {
this.crit_rate += 0.1;
this.crit_dmg += 0.16;
} else if (evolution[14] === 20) {
this.crit_rate += 0.2;
this.crit_dmg += 0.32;
}

// 뭉툭한 가시
if (evolution[18] === 15) {
this.blunt_level = 1;
} else if (evolution[18] === 30) {
this.blunt_level = 2;
}

// 인파이팅
if (evolution[20] === 15) {
this.evol_dmg += 0.09;
} else if (evolution[20] === 30) {
this.evol_dmg += 0.18;
}

// 입식타격가
if (evolution[21] === 15) {
this.evol_dmg += 0.105;
} else if (evolution[21] === 30) {
this.evol_dmg += 0.21;
}
}

get_max_crit_rate(): number {
return this.blunt_level > 0 ? 0.8 : 1;
}

calculate_crit_dmg(crit_rate: number): number {
const effective_crit_rate = Math.min(crit_rate, this.get_max_crit_rate());
return effective_crit_rate * this.crit_dmg * this.crit_hit_dmg + (1 - effective_crit_rate);
}

calculate_evol_dmg(crit_rate: number): number {
let blunt_dmg = 0;
if (this.blunt_level > 0) {
const base_blunt_dmg = this.blunt_level === 1 ? 0.075 : 0.15;
const conversion_rate = this.blunt_level === 1 ? 1.2 : 1.4;
const max_blunt_dmg = this.blunt_level === 1 ? 0.5 : 0.7;

const excess_crit_rate = Math.max(0, crit_rate - 0.8);
blunt_dmg += Math.min(base_blunt_dmg + excess_crit_rate * conversion_rate, max_blunt_dmg);
}
return this.evol_dmg + blunt_dmg;
}

calculate_back_attack_dmg(back_rate: number): number {
const base_crit_rate = this.crit_rate;
const back_attack_evol_dmg = this.calculate_evol_dmg(base_crit_rate + 0.1);
const back_attack_crit_rate = Math.min(base_crit_rate + 0.1, this.get_max_crit_rate());

const back_attack_crit_dmg = this.calculate_crit_dmg(back_attack_crit_rate);
const back_attack_total_dmg = back_attack_crit_dmg * back_attack_evol_dmg * 1.5;

const normal_crit_dmg = this.calculate_crit_dmg(base_crit_rate);
const normal_evol_dmg = this.calculate_evol_dmg(base_crit_rate);
const normal_total_dmg = normal_crit_dmg * normal_evol_dmg;

return back_rate * back_attack_total_dmg * this.back_dmg + (1 - back_rate) * normal_total_dmg;
}

get_final_dmg(back_rate: number): number {
const total_dmg = this.calculate_back_attack_dmg(back_rate);
const chargeSkillsMultiplier = this.calculate_charge_skills_multiplier();
let keen_panalty = 1;
if (this.is_keen === true) keen_panalty = 0.98;
return total_dmg * this.engraving_dmg * this.additional_dmg * keen_panalty * this.attack_dmg * chargeSkillsMultiplier;
}

calculate_charge_skills_multiplier(): number {
const chargeSkills = ["청염각", "뇌호격"];
let chargeMultiplier = 1;

for (const skill of chargeSkills) {
if (this.skillRatios[skill]) {
chargeMultiplier += (this.skillRatios[skill] / 100) * (this.charge_dmg - 1);
}
}

return chargeMultiplier;
}
}

모바일 게시판 하단버튼

댓글

새로고침
새로고침

모바일 게시판 하단버튼

지금 뜨는 인벤

더보기+

모바일 게시판 리스트

모바일 게시판 하단버튼

글쓰기

모바일 게시판 페이징

최근 HOT한 콘텐츠

  • 로아
  • 게임
  • IT
  • 유머
  • 연예
AD