마법의 MD-5 시뮬레이터: 두 판 사이의 차이

리버티게임, 모두가 만들어가는 자유로운 게임
백괴게임>Manymaster
편집 요약 없음
잔글 ("마법의 MD-5 시뮬레이터" 문서의 보호 설정을 변경했습니다: AuthorProtect 전체 적용 설정의 문제로 인해 자동 인증된 사용자 이상의 권한으로 보호 설정 변경 ([편집=자동 인증된 사용자만 허용] (무기한) [이동=자동 인증된 사용자만 허용] (무기한)))
 
(사용자 14명의 중간 판 82개는 보이지 않습니다)
1번째 줄: 1번째 줄:
{{제목|백괴스러운 MD-5 시뮬레이터}}
{{게임 정보}}
{{공지|{{알림}} 1.3 버전 업데이트가 있을 예정입니다.}}
{{pluginX
다음과 같이 변경됩니다:
|문서=사용자:hsl0/마법의 MD-5 시뮬레이터.js
* 콤보 시스템 추가
|이름=마법의 MD-5 시뮬레이터 1.4
* MISS 판정 기준 변경
|제작자=hsl0
* 패널티/어드벤티지 판정 기준 변경
}}</div>
* URL 복사시 전체 파라미터 대신 플레이어 이름 파라미터만 복사하도록 수정
----
업데이트 버전을 미리 체험해 보고 싶으시다면 주소창에 아래와 같이 입력해 보세요: {{복붙|javascript:$.getScript('/w/index.php?title{{=}}마법의_MD-5_시뮬레이터/스크립트&action{{=}}raw&ctype{{=}}text/javascript');}}
----
버그가 발견되면 [[{{TALKPAGENAME}}|토론 문서]]에서 알려주세요!
{{숨김 끝}}
{{IE불가}}
{{boolean|{{#urlget:plugin}}|{{플러그인|/플러그인}}||{{플러그인|/플러그인}}}}
{{백괴사전}}
{{백괴사전}}
<!-- <only-mobile>
모바일 버전으로 접속하셨군요!
마법의 MD-5 시뮬레이터는 아직 모바일 버전을 지원하지 않습니다. 아래의 [데스크톱 버전으로 전환] 버튼을 눌러 데스크톱 버전을 이용해 주세요.
{{버튼|데스크톱 버전으로 전환|url=https://libertygame.miraheze.org/w/index.php?title=%EB%A7%88%EB%B2%95%EC%9D%98_MD-5_%EC%8B%9C%EB%AE%AC%EB%A0%88%EC%9D%B4%ED%84%B0&mobileaction=toggle_view_desktop|class=mw-ui-progressive}}
</only-mobile> -->
<!-- only-desktop -->
<p>본 게임은 다른 비슷한 게임과는 작동 방식이 다르기 때문에 결과가 다르게 나올 수 있습니다.</p>
<p>본 게임은 다른 비슷한 게임과는 작동 방식이 다르기 때문에 결과가 다르게 나올 수 있습니다.</p>
<p>HP나 대미지가 0으로 나옴에도 불구하고 MISS 판정이나 사망 판정이 나오지 않을 경우가 간혹 있을 수 있으나, 이는 값이 반올림되어 나오면서 발생하는 현상으로 실제로는 HP나 대미지가 아주 미세하게 존재하는 상태이니 오해 없으시길 바랍니다.</p>
<p>HP나 대미지가 0으로 나옴에도 불구하고 MISS 판정이나 사망 판정이 나오지 않을 경우가 간혹 있을 수 있으나, 이는 값이 반올림되어 나오면서 발생하는 현상으로 실제로는 HP나 대미지가 아주 미세하게 존재하는 상태이니 오해 없으시길 바랍니다.</p>
<p>이 게임의 [[사용자:hsl0/마법의 MD-5 시뮬레이터.js|배틀 소스코드]]는 [https://www.gnu.org/licenses/old-licenses/gpl-2.0.html GPL v2.0]로, [[모듈:SimMD5|스탯 소스코드]]는 [https://opensource.org/license/mit MIT 라이선스]로 배포됩니다.</p>
<div id="battle" style="clear:both">
<div id="battle" style="clear:both">
<div id="input">
<div id="input">
30번째 줄: 31번째 줄:
<div id="input-reset"></div>
<div id="input-reset"></div>
<div id="input-prop" style="display:grid;grid-template-columns:auto 1fr">
<div id="input-prop" style="display:grid;grid-template-columns:auto 1fr">
<div id="input-swap"></div>
<div id="input-swap" title="순서 교체"></div>
<div id="input-table"></div>
<div id="input-table"></div>
</div>
</div>
40번째 줄: 41번째 줄:
</div>
</div>
<div id="stat">
<div id="stat">
{| id="stat-table" class="wikitable" style="display:none;margin:auto;margin-bottom:1em"
<table id="stat-table" class="wikitable" style="display:none;margin:auto;margin-bottom:1em">
! class="stat-0 stat-name" |
<tr>
! <span id="stat-turn"></span>턴
<th class="stat-0 stat-name" />
! class="stat-1 stat-name" |
<th><span id="stat-turn"></span>턴</th>
|-
<th class="stat-1 stat-name" />
| class="stat-0 stat-attack" |
</tr>
! 공격
<tr>
| class="stat-1 stat-attack" |
<td class="stat-0 stat-attack" />
|-
<th>공격</th>
| class="stat-0 stat-quick" |
<td class="stat-1 stat-attack" />
! 민첩
</tr>
| class="stat-1 stat-quick" |
<tr>
|-
<td class="stat-0 stat-quick" />
| class="stat-0 stat-defense" |
<th>민첩</th>
! 방어
<td class="stat-1 stat-quick" />
| class="stat-1 stat-defense" |
</tr>
|-
<tr>
| class="stat-0 stat-hit" |
<td class="stat-0 stat-defense" />
! 명중
<th>방어</th>
| class="stat-1 stat-hit" |
<td class="stat-1 stat-defense" />
|-
</tr>
| class="stat-0 stat-luck" |
<tr>
! 행운
<td class="stat-0 stat-hit" />
| class="stat-1 stat-luck" |
<th>명중</th>
|-
<td class="stat-1 stat-hit" />
| '''<big class="stat-0 stat-currentHP"></big>'''/<span class="stat-0 stat-fullHP"></span>
</tr>
! 체력
<tr>
| '''<big class="stat-1 stat-currentHP"></big>'''/<span class="stat-1 stat-fullHP"></span>
<td class="stat-0 stat-luck" />
|}
<th>행운</th>
<td class="stat-1 stat-luck" />
</tr>
<tr>
<td>'''<big class="stat-0 stat-currentHP"></big>'''/<span class="stat-0 stat-fullHP"></span></td>
<th>체력</th>
<td>'''<big class="stat-1 stat-currentHP"></big>'''/<span class="stat-1 stat-fullHP"></span></td>
</tr>
</table>
<div id="stat-bar" style="display:grid;grid-template-columns:1fr 1fr">
<div id="stat-bar" style="display:grid;grid-template-columns:1fr 1fr">
<div class="stat-0 stat-HPbar" dir="rtl"></div>
<div class="stat-0 stat-HPbar" dir="rtl"></div>
76번째 줄: 85번째 줄:
</div>
</div>
<pre id="log-time" style="display:none">시간 간격은 음수일 수 없습니다.</pre>
<pre id="log-time" style="display:none">시간 간격은 음수일 수 없습니다.</pre>
<pre id="log" style="max-height:30em">
<pre id="log" style="max-height:70svh">
플러그인을 먼저 설치해 주세요. 자동 인증된 사용자가 아니거나 플러그인이 작동하지 않을 경우 주소창에 [javascript:$.getScript('/w/index.php?title=마법의_MD-5_시뮬레이터/스크립트&action=raw&ctype=text/javascript');]를 입력해 체험하실 수 있습니다.
잠시만 기다려 주세요...
</pre>
</pre>
<div id="share" style="display:grid;grid-template-columns:auto 1fr;grid-column-gap:5px">
<div id="share" style="display:grid;grid-template-columns:auto 1fr;grid-column-gap:5px">
88번째 줄: 97번째 줄:
</div>
</div>
</div>
</div>
{{게임 등급|15}}
<!-- /only-desktop -->
{{사용자:Gustmd7410/게임}}
{{게임 등급|전체|2019-03-01|폭력성}}
[[분류:백괴게임]]
{{사용자:hsl0/게임}}

2024년 10월 27일 (일) 13:24 기준 최신판

Applications-system.png
원개발자 이외에는 편집을 할 수 없는 게임
이 게임은 원개발자 이외에는 편집을 할 수 없는 게임입니다.
이 게임을 잘못 수정하면 게임을 망치거나 오류가 날 수 있으므로 편집하지 마십시오.
버그가 있으면 수정하지 마시고 게임 토론이나 해당 개발자의 사용자 토론에 알려주세요.
GRAC All Square.svg
이 게임은 자체 등급 심의를 바탕으로 모든 사용자가 이용할 것을 권장합니다.
등급 지정일: 2019년 3월 1일
/**
 * @name SimMD5
 * @author hsl0
 * @version 1.4
 * @desc 마법의 MD-5 시뮬레이터 게임에 사용되는 스크립트로, 인터페이스와 배틀시스템을 구현합니다.
 * @license GPL-2.0-or-later
**/
mw.loader.using('oojs-ui-widgets').done(function() {
	function prepare() {
		function responsible(event) {
			var button = $('#input-time .oo-ui-numberInputWidget-plusButton, #input-time .oo-ui-numberInputWidget-minusButton');
			
			if(event.matches) {
				button.css('display', 'none');
				input.time.$label.css('margin-right', null);
			} else {
				button.css('display', 'null');
				input.time.$label.css('margin-right', '30px');
			}
		}
		
		function encode(string) {
			return string
			.replace(/&/g, '&#38;')
			.replace(/</g, '&#60;')
			.replace(/>/g, '&#62;')
			.replace(/{/g, '&#123;')
			.replace(/\|/g, '&#124;')
			.replace(/=/g, '&#61;')
			.replace(/}/g, '&#125;')
			.replace(/\[/g, '&#91;')
			.replace(/\]/g, '&#93;')
			.replace(/_/g, '&#95;')
			.replace(/'/g, '&#39;')
			.replace(/\t/g, '&#09;')
			.replace(/\n/g, '&#10;')
			.replace(/ /g, '&#32;');
		}
		
		function cancel(btn) {
			if(stat.length) {
				battle.done = null;
				battle.turn = 0;
				battle.attack = null;
				battle.sequence = null;
				battle.combo = null;
				battle.temp = null;
				
				bar = [];
				bar[0] = new OO.ui.ProgressBarWidget({
					progress: 100
				});
				bar[1] = new OO.ui.ProgressBarWidget({
					progress: 100
				});
				
				bar[0].$bar.css({
					background: '#3366CC'
				});
				bar[0].$element.css({
					'border-right': 'none',
					'border-top-right-radius': 0,
					'border-bottom-right-radius': 0
				});
				bar[1].$bar.css({
					background: '#FF5500'
				});
				bar[1].$element.css({
					'border-left': 'none',
					'border-top-left-radius': 0,
					'border-bottom-left-radius': 0
				});
				
				input.start.setLabel('재시작');
				input.reset.setLabel('초기화');
				$('#stat-turn').text(0);
				$('.stat-0.stat-currentHP').data('value', stat[0].HP).text(stat[0].HP.toFixed(2)).css('color', '#3366CC');
				$('.stat-1.stat-currentHP').data('value', stat[1].HP).text(stat[1].HP.toFixed(2)).css('color', '#FF5500');
				$('.stat-0.stat-HPbar').html(bar[0].$element);
				$('.stat-1.stat-HPbar').html(bar[1].$element);
				if(btn) $('#log')[0].innerText += '\n다시 시작하려면 재시작 버튼을 눌러주세요.';
			}
		}
		
		function stop() {
			clearInterval(battle.work);
			
			$('#input-stop').hide();
			$('#input-start').show();
			input.reset.setDisabled(false);
			input[0].setDisabled(false);
			input[1].setDisabled(false);
			input.time.setDisabled(false);
			input.swap.setDisabled(false);
		}
		
		var input = {};
		input[0] = new OO.ui.TextInputWidget({
			placeholder: '선',
			title: '후',
			value: new URLSearchParams(location.search).get('p0') || ''
		});
		input.start = new OO.ui.ButtonInputWidget({
			type: 'submit',
			flags: ['primary', 'progressive'],
			label: '시작'
		});
		input.stop = new OO.ui.ButtonInputWidget({
			flags: ['primary', 'destructive'],
			label: '정지'
		});
		input[1] = new OO.ui.TextInputWidget({
			placeholder: '후',
			title: '후',
			value: new URLSearchParams(location.search).get('p1') || ''
		});
		input.time = new OO.ui.NumberInputWidget({
			value: 1,
			min: 0,
			label: '초 간격'
		});
		input.reset = new OO.ui.ButtonInputWidget({
			type: 'reset',
			flags: ['destructive'],
			label: '초기화'
		});
		input.swap = new OO.ui.ButtonInputWidget({
			label: $('<div />').css({
				height: '20px',
				width: '20px',
				'background-image': 'url("/wiki/Special:Redirect/file/Ambox_move_black.svg")',
				'background-size': 'cover'
			}),
			title: '교체',
			framed: false
		});
		input.table = new OO.ui.ToggleSwitchWidget({
			value: true
		});
		input.icon = new OO.ui.ButtonWidget({
			framed: false,
			icon: $('#mw-customcollapsible-input-option').hasClass('mw-collapsed')? 'expand' : 'collapse'
		});
		input.log = new OO.ui.ButtonWidget({
			label: '기록 복사'
		});
		input.url = new OO.ui.ButtonWidget({
			label: 'URL 복사'
		});
		input.box = new OO.ui.MultilineTextInputWidget();
		var media = matchMedia('(max-width: 800px)');
		var stat = [];
		var bar = [];
		var battle = {
			turn: 0,
			attack: null,
			done: null,
			work: null,
			sequence: null,
			combo: null,
			temp: null
		};
		
		$('#input').wrap('<form />');
		$('#input-0').html(input[0].$element);
		$('#input-start').html(input.start.$element);
		$('#input-stop').html(input.stop.$element);
		$('#input-1').html(input[1].$element);
		$('#input-time').html(input.time.$element);
		$('#input-reset').html(input.reset.$element);
		$('#input-swap').html(input.swap.$element);
		$('#input-table').html(input.table.$element).append(' 스탯');
		$('#input-icon').html(input.icon.$element);
		$('#stat-load').html(new OO.ui.ProgressBarWidget().$element);
		$('#log').text('시작하시려면 상단에 대결할 상대의 이름을 입력해 주세요. (1.4)');
		$('#share-log').html(input.log.$element);
		$('#share-url').html(input.url.$element);
		$('#share-cvbox').html(input.box.$element);
		
		input.box.$input.attr('readonly', '').css('height', '2.5em');
		
		$('#stat-bar').hide();
		$('#share').hide();
		
		responsible(media);
		media.addListener(responsible);
		
		new MutationObserver(function(mutation) {
			input.icon.setIcon($(mutation[0].target).hasClass('mw-collapsed')? 'expand' : 'collapse');
		}).observe($('#mw-customcollapsible-input-option')[0], {
			attributes: true,
			attributeFilter: ['class']
		});
		
		input.swap.$element.click(function() {
			if(!input.swap.disabled) {
				var val = [input[1].value, input[0].value];
				input[0].setValue(val[0]);
				input[1].setValue(val[1]);
				
				if(stat.length) {
					stat = [stat[1], stat[0]];
					
					$('#stat-turn').text(0);
					$('.stat-0').each(function() {
						if($(this).hasClass('stat-name')) $(this).text(stat[0].name);
						else if($(this).hasClass('stat-attack')) $(this).text(stat[0].attack);
						else if($(this).hasClass('stat-quick')) $(this).text(stat[0].quick);
						else if($(this).hasClass('stat-defense')) $(this).text(stat[0].defense);
						else if($(this).hasClass('stat-hit')) $(this).text(stat[0].hit);
						else if($(this).hasClass('stat-luck')) $(this).text(stat[0].luck);
						else if($(this).hasClass('stat-fullHP')) $(this).text(stat[0].HP);
						else if($(this).hasClass('stat-currentHP')) $(this).data('value', stat[0].HP).text(stat[0].HP.toFixed(2));
						else if($(this).hasClass('stat-HPbar')) $(this).html(bar[0].$element);
					});
					$('.stat-1').each(function() {
						if($(this).hasClass('stat-name')) $(this).text(stat[1].name);
						else if($(this).hasClass('stat-attack')) $(this).text(stat[1].attack);
						else if($(this).hasClass('stat-quick')) $(this).text(stat[1].quick);
						else if($(this).hasClass('stat-defense')) $(this).text(stat[1].defense);
						else if($(this).hasClass('stat-hit')) $(this).text(stat[1].hit);
						else if($(this).hasClass('stat-luck')) $(this).text(stat[1].luck);
						else if($(this).hasClass('stat-fullHP')) $(this).text(stat[1].HP);
						else if($(this).hasClass('stat-currentHP')) $(this).data('value', stat[1].HP).text(stat[1].HP.toFixed(2));
						else if($(this).hasClass('stat-HPbar')) $(this).html(bar[1].$element);
					});
					
					var url = new URL(location);
					url.searchParams.set('p0', input[0].value);
					url.searchParams.set('p1', input[1].value);
					history.replaceState(null, '', url);
					
					cancel();
					
					input.start.setLabel('시작');
				}
			}
		});
		input.table.$element.click(function() {
			if(input.table.value) {
				if($('#stat-turn').text()) $('#stat-table').show(500);
			} else {
				$('#stat-table').hide(500);
			}
		});
		input.reset.$button[0].form.addEventListener('reset', function(event) {
			event.preventDefault();
			
			if(!input.reset.disabled) {
				if(battle.done || battle.done === null) {
					var url = new URL(location);
					url.searchParams['delete']('p0');
					url.searchParams['delete']('p1');
					history.replaceState(null, '', url);
					stat = [];
					input[0].setValue();
					input[1].setValue();
					input.time.setValue(1);
					input.table.setValue(true);
					input.start.setLabel('시작');
					$('#share').hide();
					$('#share-cvbox').hide();
					$('#stat-table').hide(500);
					$('#stat-bar').hide(500);
					$('#stat-turn, .stat-0, .stat-1').text('');
					$('#log-time').hide();
					$('#log').show();
					$('#log').text('시작하시려면 상단에 대결할 상대의 이름을 입력해 주세요.');
					$('.stat-HPbar').html('');
				} else cancel(true);
			}
		});
		input.start.$button[0].form.addEventListener('submit', function(event) {
			function last() {
				$('#input-stop').show();
				$('#input-start').hide();
				input.reset.setLabel('취소');
				input[0].setDisabled(true);
				input[1].setDisabled(true);
				input.time.setDisabled(true);
				input.reset.setDisabled(true);
				input.swap.setDisabled(true);
				input.start.setLabel('재개');
				
				battle.work = start(battle, stat.map(function(obj, index) {
					return new Proxy(obj, {
						get: function(target, key, receiver) {
							if(key === 'HP') return +$('.stat-' + index + '.stat-currentHP').data('value');
							else return Reflect.get(target, key, receiver);
						},
						set: function(target, key, value) {
							if(key === 'HP') {
								if(value < 0) {
									value = 0;
									$('.stat-' + index + '.stat-currentHP').css('color', '#000000');
								}
								$('.stat-' + index + '.stat-currentHP').data('value', value).text(value.toFixed(2));
								bar[index].setProgress(value / target.HP * 100);
							}
						}
					});
				}), input.time.value * 1000, function(msg) {
					$('#log')[0].innerText += msg;
					$('#log').scrollTop($('#log')[0].scrollHeight);
					
					if(battle.sequence === 0) {
						$('#stat-turn').text(battle.turn);
						$('.stat-' + battle.attack + '.stat-name').css({
							background: battle.attack? '#FF5500' : '#3366CC',
							color: '#FFFFFF'
						});
						$('.stat-' + (battle.attack ^ 1) + '.stat-name').css({
							background: '#EAECF0',
							color: battle.attack? '#3366CC' : '#FF5500'
						});
					}
				}, function(msg) {
					$('#log')[0].innerText += msg;
					$('#log')[0].innerText += '\n\n백괴스러운 MD-5 시뮬레이터 [https://libertyga.me/wiki/마법의_MD-5_시뮬레이터]';
					$('#log').scrollTop($('#log')[0].scrollHeight);
					
					$('#share').show();
					
					stop();
					
					battle.done = true;
					battle.turn = 0;
					battle.attack = null;
					battle.sequence = null;
					battle.combo = null;
					battle.temp = null;
					
					input.start.setLabel('재시작');
					input.reset.setLabel('초기화');
				});
			}
			
			event.preventDefault();
			
			if(!input.start.disabled) {
				$('#share').hide();
				$('#share-cvbox').hide();
				
				if(input.time.value >= 0) {
					$('#log-time').hide();
					$('#log').show();
					
					if(!stat.length) $.get({
						url: '/api.php',
						data: {
							action: 'parse',
							format: 'json',
							title: '마법의 MD-5 시뮬레이터',
							text: '[{{#invoke:SimMD5|stat|' + encode(input[0].value) + '|AJAX}},{{#invoke:SimMD5|stat|' + encode(input[1].value) + '|AJAX}}]',
							prop: 'text',
							disablelimitreport: true,
							formatversion: 2
						},
						beforeSend: function() {
							if($('#stat-bar').html()) {
								$('#stat-bar').hide();
								$('#stat-load').show();
							} else $('#stat-load').show(500);
							$('#log').text('스탯 계산중입니다. 잠시만 기다려 주세요.');
							
							var url = new URL(location);
							url.searchParams.set('p0', input[0].value);
							url.searchParams.set('p1', input[1].value);
							history.replaceState(null, '', url);
						},
						success: function(callback) {
							stat = JSON.parse($(callback.parse.text).text());
							
							bar = [];
							bar[0] = new OO.ui.ProgressBarWidget({
								progress: 100
							});
							bar[1] = new OO.ui.ProgressBarWidget({
								progress: 100
							});
							
							bar[0].$bar.css({
								background: '#3366CC'
							});
							bar[0].$element.css({
								'border-right': 'none',
								'border-top-right-radius': 0,
								'border-bottom-right-radius': 0
							});
							bar[1].$bar.css({
								background: '#FF5500'
							});
							bar[1].$element.css({
								'border-left': 'none',
								'border-top-left-radius': 0,
								'border-bottom-left-radius': 0
							});
							
							$('#stat-turn').text(0);
							$('.stat-0').each(function() {
								if($(this).hasClass('stat-name')) $(this).text(stat[0].name);
								else if($(this).hasClass('stat-attack')) $(this).text(stat[0].attack);
								else if($(this).hasClass('stat-quick')) $(this).text(stat[0].quick);
								else if($(this).hasClass('stat-defense')) $(this).text(stat[0].defense);
								else if($(this).hasClass('stat-hit')) $(this).text(stat[0].hit);
								else if($(this).hasClass('stat-luck')) $(this).text(stat[0].luck);
								else if($(this).hasClass('stat-fullHP')) $(this).text(stat[0].HP);
								else if($(this).hasClass('stat-currentHP')) $(this).data('value', stat[0].HP).text(stat[0].HP.toFixed(2));
								else if($(this).hasClass('stat-HPbar')) $(this).html(bar[0].$element);
							});
							$('.stat-1').each(function() {
								if($(this).hasClass('stat-name')) $(this).text(stat[1].name);
								else if($(this).hasClass('stat-attack')) $(this).text(stat[1].attack);
								else if($(this).hasClass('stat-quick')) $(this).text(stat[1].quick);
								else if($(this).hasClass('stat-defense')) $(this).text(stat[1].defense);
								else if($(this).hasClass('stat-hit')) $(this).text(stat[1].hit);
								else if($(this).hasClass('stat-luck')) $(this).text(stat[1].luck);
								else if($(this).hasClass('stat-fullHP')) $(this).text(stat[1].HP);
								else if($(this).hasClass('stat-currentHP')) $(this).data('value', stat[1].HP).text(stat[1].HP.toFixed(2));
								else if($(this).hasClass('stat-HPbar')) $(this).html(bar[1].$element);
							});
							
							$('.stat-0.stat-currentHP').css('color', '#3366CC');
							$('.stat-1.stat-currentHP').css('color', '#FF5500');
							
							$('#stat-load').hide();
							if(input.table.value) $('#stat-table').show(500);
							$('#stat-bar').show();
							$('#log').text('');
							$('#log')[0].innerText += '[' + stat[0].name + '] 공격력: ' + stat[0].attack + ' / 방어력: ' + stat[0].defense + ' / 민첩: ' + stat[0].quick + ' / 명중: ' + stat[0].quick + ' / 운: ' + stat[0].luck + ' / HP: ' + stat[0].HP + '\n';
							$('#log')[0].innerText += '[' + stat[1].name + '] 공격력: ' + stat[1].attack + ' / 방어력: ' + stat[1].defense + ' / 민첩: ' + stat[1].quick + ' / 명중: ' + stat[1].quick + ' / 운: ' + stat[1].luck + ' / HP: ' + stat[1].HP + '\n';
							$('#log')[0].innerText += '\n';
							
							battle.turn = 1;
							battle.done = false;
							battle.attack = 0;
							battle.sequence = 0;
							battle.combo = [0, 0];
							battle.temp = {};
							
							last();
						},
						error: function(error) {
							$('#stat-load').hide(500);
							$('#log').text('스탯 계산에 오류가 발생하였습니다. 다시 시도해 주십시오. (' + error.status + ')');
						}
					});
					else if(battle.done || battle.done === null) {
						if(battle.done) cancel();
						
						$('#log').text('');
						$('#log')[0].innerText += '[' + stat[0].name + '] 공격력: ' + stat[0].attack + ' / 방어력: ' + stat[0].defense + ' / 민첩: ' + stat[0].quick + ' / 명중: ' + stat[0].hit + ' / 운: ' + stat[0].luck + ' / HP: ' + stat[0].HP + '\n';
						$('#log')[0].innerText += '[' + stat[1].name + '] 공격력: ' + stat[1].attack + ' / 방어력: ' + stat[1].defense + ' / 민첩: ' + stat[1].quick + ' / 명중: ' + stat[1].hit + ' / 운: ' + stat[1].luck + ' / HP: ' + stat[1].HP + '\n';
						$('#log')[0].innerText += '\n';
						
						battle.turn = 1;
						battle.done = false;
						battle.attack = 0;
						battle.sequence = 0;
						battle.combo = [0, 0];
						battle.temp = {};
						
						last();
					} else last();
				} else {
					$('#log-time').show();
					$('#log').hide();
				}
			}
		});
		input.stop.$element.click(function() {
			if(!input.stop.disabled) stop();
		});
		input[0].$input.focus(function() {
			cancel();
			stat = [];
			input.start.setLabel('시작');
			$(this).select();
		});
		input[1].$input.focus(function() {
			cancel();
			stat = [];
			input.start.setLabel('시작');
			$(this).select();
		});
		input.log.$button.click(function() {
			input.box.setValue(document.getElementById('log').innerText);
			$('#share-cvbox').show();
			input.box.$input.select();
			document.execCommand('copy');
		});
		input.url.$button.click(function() {
			var url = new URL('/wiki/마법의_MD-5_시뮬레이터', location);
			var search = new URLSearchParams(location.search);
			url.searchParams.set('p0', search.get('p0'));
			url.searchParams.set('p1', search.get('p1'));
			input.box.setValue(url);
			$('#share-cvbox').show();
			input.box.$input.select();
			document.execCommand('copy');
		});
		input.box.$input.click(function() {
			$(this).select();
		});
	}
	
	function start(battle, stat, time, each, last) {
		function rand(min, max) {
		    return Math.floor(Math.random() * (max - min + 1)) + min;
		}
		
		function range(weight) {
	        var range = [-0.5, -0.25, 0, 0.25, 0.5].map(function(ratio, index) {
	        	return 20 + (weight - 50) * ratio;
	        });
	        range.reduce(function(acc, current, index, prob) {
	        	return prob[index] += acc;
	        });
	        return range;
		}
		
	    function rank(range, val) {
	        return range.findIndex(function(current, index) {
	        	return (index === 0 || range[index - 1] < val) && val <= current;
	        });
	    }
	    
		function power(stat, rank) {
		    return stat * (((rank === 0)? 0 : rand(1 + 25 * (rank - 1), 25 * rank)) / 100);
		}
		
		function bonus(plus, minus, rank) {
			rank -= 2;
			if(rank === 0) return 0;
		    return ((rank > 0)? plus : minus) * (rand(1 + 50 * (rank - 1), 50 * rank) / 100);
		}
		
		function josa(text, exist, not, only) {
			text = text.normalize('NFD');
			var code = text.charCodeAt(text.length - 1);
			
			if(0x1161 <= code && code <= 0x11A7) return ((only)? '' : text) + not;
			else if(0x11A8 <= code && code <= 0x11FF) return ((only)? '' : text) + exist;
			else return ((only)? '' : text) + exist + '(' + not + ')';
		}
		
		return setInterval(function() {
			var attacker = battle.attack;
			var defender = attacker ^ 1;
			
			if(stat[0].HP > 0 && stat[1].HP > 0) {
				switch(battle.sequence) {
					case 0:
						var scale = range(stat[attacker].luck);
						var adv = bonus(stat[attacker].hit, stat[defender].quick, rank(range(50), 50 + ((battle.combo[defender])? 0 : battle.combo[defender]) - ((battle.combo[attacker])? 0: battle.combo[attacker])));
						var grade = {
							attack: rank(scale, rand(1, 100)),
							defense: rank(range(stat[defender].luck), rand(1, 100)),
						};
						var damage = power(stat[attacker].attack, grade.attack) - power(stat[defender].defense, grade.defense) + adv;
						battle.temp = {
							rank: rank(scale, damage),
							damage: (damage > 0)? damage : 0
						};
						
						if(battle.temp.damage > stat[attacker].attack) battle.temp.rank = 5;
						if(battle.temp.damage) {
							if(!battle.temp.rank) battle.temp.rank = 1;
							if(battle.combo[attacker] < 0) battle.combo[attacker] = 0;
							battle.combo[attacker]++;
						} else {
							battle.temp.rank = 0;
							if(battle.combo[attacker] > 0) battle.combo[attacker] = 0;
							battle.combo[attacker]--;
						}
						
						each('[' + stat[attacker].name + ']의 공격 ');
						battle.sequence++;
					break;
					case 1:
						var rankText = ['MISS', 'HIT', 'GOOD', 'NICE', 'PERFECT', 'CRITICAL'][battle.temp.rank];
						each(rankText + '! ');
						battle.sequence++;
					break;
					case 2:
						stat[defender].HP -= battle.temp.damage;
						var msg = (battle.temp.rank === 0)? '공격을 피했다. (' : (+battle.temp.damage.toFixed(2)) + '의 대미지를 받았다. (' + ((battle.combo[attacker] > 0)? battle.combo[attacker] : 0) + ' COMBO, ';
						each('[' + stat[defender].name + ']' + josa(stat[defender].name, '은', '는', true) + ' ' + msg + '남은 HP: ' + (+stat[defender].HP.toFixed(2)) + ')\n');
						if(attacker === 1) battle.turn++;
						battle.sequence = 0;
						battle.attack = defender;
					break;
				}
			} else if(stat[0].HP === stat[1].HP) {
				last('\n무승부! (' + battle.turn + '턴)');
				$('.stat-' + battle.attack + '.stat-name').css({
					color: battle.attack? '#FF5500' : '#3366CC'
				});
				$('.stat-' + (battle.attack ^ 1) + '.stat-name').css({
					background: '#EAECF0',
					color: battle.attack? '#3366CC' : '#FF5500'
				});
			} else last('\n[' + stat[defender].name + '] 승! (' + battle.turn + '턴)');
		}, time);
	}
	
	$(prepare);
});
백괴낚시e.svg
백괴사전에 이 글과 관련된 문서가 있습니다.
마법의 MD-5 시뮬레이터

본 게임은 다른 비슷한 게임과는 작동 방식이 다르기 때문에 결과가 다르게 나올 수 있습니다.

HP나 대미지가 0으로 나옴에도 불구하고 MISS 판정이나 사망 판정이 나오지 않을 경우가 간혹 있을 수 있으나, 이는 값이 반올림되어 나오면서 발생하는 현상으로 실제로는 HP나 대미지가 아주 미세하게 존재하는 상태이니 오해 없으시길 바랍니다.

이 게임의 배틀 소스코드GPL v2.0로, 스탯 소스코드MIT 라이선스로 배포됩니다.


잠시만 기다려 주세요...
GRAC All Square.svg
이 게임은 자체 등급 심의를 바탕으로 모든 사용자가 이용할 것을 권장합니다.
폭력성
등급 지정일: 2019년 3월 1일