Compare commits

..
62 Commits
Author SHA1 Message Date
Hide_D 798ab3e183 암행부 병종 표기 버그 수정 2018-08-21 02:24:58 +09:00
Hide_D 5508aa4533 전투 엔진 버그 4차 수정 2018-08-21 02:22:29 +09:00
Hide_D 81b7ebbab6 전투 엔진 버그 3차 수정 2018-08-21 02:01:56 +09:00
Hide_D 2d06e33e10 운영자가 '지도'에서 도시를 클릭할 수 있도록 변경 2018-08-21 01:32:00 +09:00
Hide_D d8cc820572 전투 엔진 버그 2차 수정 2018-08-21 01:22:18 +09:00
Hide_D d0ca46cfde 전투 엔진 버그 1차 수정 2018-08-21 00:53:00 +09:00
Hide_D 513124161e 전투 종료 코드 구현(마무리?) 2018-08-20 23:57:36 +09:00
Hide_D 7cfd8c7f79 전투 종료 코드 구현(마무리?) 2018-08-20 22:26:34 +09:00
Hide_D c32ce5e795 전투 종료 코드 구현 2018-08-20 22:20:59 +09:00
Hide_D d9c1530651 일부 게임 유틸리티 함수 간소화 2018-08-20 20:21:26 +09:00
Hide_D 305eb071a9 전투 종료 코드 구현 2018-08-20 17:24:16 +09:00
Hide_D 10dab69c63 전투 구현 반영 2018-08-20 03:48:54 +09:00
Hide_D 60ed594996 전투 구현 반영 2018-08-20 03:46:59 +09:00
Hide_D e60ddb3ee1 전투 구현 반영 2018-08-20 03:14:56 +09:00
Hide_D 26b0992285 전투 구현 반영 2018-08-19 03:47:28 +09:00
Hide_D 63f3ac807c 전투 구현 반영 2018-08-19 03:45:43 +09:00
Hide_D ed1c33eac0 전투 구현 반영 2018-08-19 03:30:47 +09:00
Hide_D e7b7fd0bcc 치료가 '필살', '회피'와 중복 가능. 전특과 의술 아이템의 치료 효과 증폭 2018-08-19 03:00:08 +09:00
Hide_D 79d2b04721 전투 구현 반영 2018-08-19 02:57:25 +09:00
Hide_D 5a8ab2d29c 전투 구현 반영 2018-08-19 02:33:42 +09:00
Hide_D ed527ac394 전투 코드 반영 2018-08-18 23:18:40 +09:00
Hide_D bf09f48196 전투 구현 반영 2018-08-18 22:21:25 +09:00
Hide_D 2a5af15aef 전투 코드 반영 2018-08-18 21:24:02 +09:00
Hide_D 1f8fe35e25 성벽 전투시 깎이는 성벽이 기존 대비 1/2 2018-08-18 20:46:30 +09:00
Hide_D 5979273a64 코드 중간 반영 2018-08-18 20:45:59 +09:00
Hide_D ef8c9e3968 전투 엔진 중간 반영 2018-08-18 19:04:13 +09:00
Hide_D baa9fdb660 유틸리티 함수 추가 2018-08-18 16:59:34 +09:00
Hide_D 35a860bb38 충차 성벽 보정 버그 수정 2018-08-18 15:18:40 +09:00
Hide_D 286939dc2c CriticalScore2, getCrew 이동 2018-08-18 14:02:53 +09:00
Hide_D dd5b1dbdd8 전투 추가 구현 2018-08-18 10:53:04 +09:00
Hide_D fb8d3a038d 새 전투 엔진 중간 반영 2018-08-18 02:26:27 +09:00
Hide_D ea5a25a671 전투 파일 추가 작성중
전투 코드 추가 준비

추가 구현
2018-08-14 23:11:03 +09:00
Hide_D d21fc4ab1d 새 전투 엔진 준비 2018-08-12 22:23:53 +09:00
Hide_D 3ae3974866 수극 사용 로그 버그 수정 2018-08-12 13:25:24 +09:00
Hide_D 71ffc3087e 전투 공식 핫픽스 2018-08-11 08:49:23 +09:00
Hide_D 8f406489d4 전콘 용량을 30KB로 증가 2018-08-10 19:58:31 +09:00
Hide_D a08d270968 루드라사움 지도 업데이트 2018-08-10 02:22:31 +09:00
Hide_D 48f13e4b82 루드라사움 스탯 수정 2018-08-08 03:47:04 +09:00
Hide_D 51060f0e4b 루드라사움 지도 업데이트 2018-08-08 03:36:00 +09:00
Hide_D c583109046 루드라사움 패치 2018-08-08 03:21:42 +09:00
Hide_D cf05b693f1 엑셀 파일에 빙의 불가 장수 목록 개념 추가 2018-08-08 02:48:17 +09:00
Hide_D d248c1ab0d 빙의가 불가능한 general_neutral 항목 추가 2018-08-08 02:45:41 +09:00
Hide_D 34623fca94 이민족 코드를 5에서 9로 이동. 그에따른 추가 코드 변경 2018-08-08 02:31:49 +09:00
Hide_D 975bdd5897 토너먼트 중복 참가 방지. 자동 참가시 돈을 받지 않음 2018-08-08 01:54:57 +09:00
Hide_D 1b3380c2ca 성벽을 때렸을 때 차숙이 오르지 않는 버그 해결 2018-08-07 04:00:31 +09:00
Hide_D bb707b4a03 명성 / 계급 계산식을 for loop 없앰 2018-08-06 01:23:39 +09:00
Hide_D acb3b6ac85 물자 조달로 올라가는 명성, 계급의 양을 다른 내정과 비슷하게 변경 2018-08-06 00:46:22 +09:00
Hide_D 80f6985f5f 지도 툴팁 line break 없앰 2018-07-30 03:23:01 +09:00
Hide_D 5e3a9c0579 지도 툴팁 너비 수정 2018-07-30 02:13:46 +09:00
Hide_D b30d62d483 루도라사움 지도 위치 수정 2018-07-30 02:11:51 +09:00
Hide_D 0ea1fdbd19 지도 출력 변경 2018-07-30 02:07:02 +09:00
Hide_D f068586f74 지도를 변경 가능하도록 업데이트 2018-07-30 02:00:53 +09:00
Hide_D 463f462e24 j_map_history에서 year가 0인 경우 2018-07-30 01:47:33 +09:00
Hide_D e0c4e3c58e 장수 생성시 기본 타입 2018-07-30 01:42:42 +09:00
Hide_D 5aa3ef38ba 연감용 루드라사움 지도 추가 2018-07-30 01:34:39 +09:00
Hide_D 827277f6a3 버그 수정 2018-07-30 01:26:12 +09:00
Hide_D 46389341db 루드라사움을 위한 시스템 보정 2018-07-30 00:37:39 +09:00
Hide_D a58f05a295 에러메시지를 VSCode에서 바로 이동하기 쉽도록 변경 2018-07-29 23:43:36 +09:00
Hide_D c0b0a0fe92 루드라사움 지도 연결 수정 2018-07-29 23:41:35 +09:00
Hide_D e9f471dd6f Neo 루드라사움 준비 2018-07-29 23:26:19 +09:00
Hide_D 7917c5dddb 부대편성 버그 수정 2018-07-29 16:20:43 +09:00
Hide_D de4541a3d9 부대 편성 일부 수정 2018-07-29 13:57:10 +09:00
51 changed files with 5766 additions and 2745 deletions
+1 -1
View File
@@ -77,7 +77,7 @@ function getExceptionTraceAsString($exception) {
}
$args = join(", ", $args);
}
$rtn[] = sprintf( "#%s %s(%s): %s(%s)",
$rtn[] = sprintf( "#%s %s:%s %s(%s)",
$count,
isset($frame['file']) ? $frame['file'] : 'unknown file',
isset($frame['line']) ? $frame['line'] : 'unknown line',
+37
View File
@@ -86,4 +86,41 @@
.map_theme_miniche .map_bgroad{
background: url('_tK_gameImagePath_/map/che/miniche_road.png') no-repeat;
background-size: 700px 500px;
}
/*루드라사움 지도*/
.map_theme_ludo_rathowm .map_bglayer1{
background: url('_tK_gameImagePath_/map/ludo_rathowm/back.jpg') no-repeat;
background-size: 700px 500px;
}
.map_theme_ludo_rathowm .map_bgroad{
background: url('_tK_gameImagePath_/map/ludo_rathowm/road.png') no-repeat;
background-size: 700px 500px;
}
.map_theme_ludo_rathowm.map_detail.map_spring .map_title_text{
background:
url('_tK_gameImagePath_/spring.gif') no-repeat right;
}
.map_theme_ludo_rathowm.map_detail.map_summer .map_title_text{
background:
url('_tK_gameImagePath_/summer.gif') no-repeat right;
}
.map_theme_ludo_rathowm.map_detail.map_fall .map_title_text{
background:
url('_tK_gameImagePath_/fall.gif') no-repeat right;
}
.map_theme_ludo_rathowm.map_detail.map_winter .map_title_text{
background:
url('_tK_gameImagePath_/winter.gif') no-repeat right;
}
.world_map.map_theme_ludo_rathowm .map_title .map_title_text::before {
color:white;
content:'LP';
margin-right:1ch;
}
+1 -1
View File
@@ -153,7 +153,7 @@ foreach ($generals as &$general) {
case 2: $mode = "◎"; break;
}
$general['modeText'] = $mode;
$general['crewtypeText'] = GameUnitConst::byId($general['crewtype'])->name;
$general['crewtypeText'] = GameUnitConst::byId($general['crewtype'])->name??'-';
if ($general['npc'] < 2) {
+122 -100
View File
@@ -12,13 +12,58 @@ $connect=$db->get();
increaseRefresh("부대편성", 1);
$query = "select no,nation,troop from general where owner='{$userID}'";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$me = MYDB_fetch_array($result);
$me = $db->queryFirstRow('SELECT no,nation,troop FROM general WHERE owner=%i', $userID);
$query = "select * from troop where nation='{$me['nation']}'";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$troopcount = MYDB_num_rows($result);
$troops = [];
foreach($db->query('SELECT troop,name,no FROM troop WHERE nation = %i', $me['nation']) as $rawTroop){
$troops[$rawTroop['troop']] = [
'troop'=>$rawTroop['troop'],
'name'=>$rawTroop['name'],
'no'=>$rawTroop['no'],
'users'=>[]
];
}
foreach($db->query(
'SELECT no,name,turntime,troop,city FROM general WHERE troop!=0 AND nation = %i ORDER BY turntime ASC',
$me['nation']
) as $general
){
if(!key_exists($general['troop'], $troops)){
trigger_error("올바르지 않은 부대 소속 {$general['no']}, {$general['name']} : {$general['troop']}");
continue;
}
$general['cityText'] = CityConst::byID($general['city'])->name;
$troops[$general['troop']]['users'][] = $general;
}
if($troops){
foreach($db->query(
'SELECT no,name,picture,imgsvr,turntime,city,turn0,turn1,turn2,turn3,turn4,turn5,troop FROM general WHERE no IN %li',
array_column($troops, 'no')
) as $troopLeader
){
$imageTemp = GetImageURL($troopLeader['imgsvr']);
$troopLeader['pictureFullPath'] = "$imageTemp/{$troopLeader['picture']}";
$troopLeader['cityText'] = CityConst::byID($troopLeader['city'])->name;
$troopLeader['turnText'] = join('<br>', [
'1 : '.((DecodeCommand($troopLeader['turn0'])[0] == 26)?'집합':'~'),
'2 : '.((DecodeCommand($troopLeader['turn1'])[0] == 26)?'집합':'~'),
'3 : '.((DecodeCommand($troopLeader['turn2'])[0] == 26)?'집합':'~'),
'4 : '.((DecodeCommand($troopLeader['turn3'])[0] == 26)?'집합':'~'),
'5 : '.((DecodeCommand($troopLeader['turn4'])[0] == 26)?'집합':'~'),
]);
$troops[$troopLeader['troop']]['leader'] = $troopLeader;
}
}
uasort($troops, function($lhs, $rhs){
return $lhs['leader']['turntime']<=>$rhs['leader']['turntime'];
})
?>
<!DOCTYPE html>
@@ -30,6 +75,7 @@ $troopcount = MYDB_num_rows($result);
<title><?=UniqueConst::$serverName?>: 부대편성</title>
<?=WebUtil::printCSS('../d_shared/common.css')?>
<?=WebUtil::printCSS('css/common.css')?>
<?=WebUtil::printCSS('css/troops.css')?>
<?=WebUtil::printJS('../e_lib/jquery-3.3.1.min.js')?>
<?=WebUtil::printJS('js/ext.plugin_troop.js')?>
</head>
@@ -50,121 +96,97 @@ $troopcount = MYDB_num_rows($result);
<td width=130 class='bg1 center' style=table-layout:fixed;word-break:break-all;>부대장행동</td>
</tr>
</thead>
<tfoot><tr><td colspan='5'>
<?php if(!$troops): ?>
<?php elseif($me['troop'] == 0): ?>
<input type=submit name=btn value='부 대 가 입'>
<?php else: ?>
<input type=submit name=btn value='부 대 탈 퇴' onclick='return confirm(\"정말 부대를 탈퇴하시겠습니까?\")'>
<?php endif;?>
</td></tr></tfoot>
<tbody>
<?php
for($i=0; $i < $troopcount; $i++) {
$troop = MYDB_fetch_array($result);
foreach ($troops as $troopNo=>$troop) {
$troopLeader = $troop['leader'];
$genlistText = [];
$cityText = $troopLeader['cityText'];
$cityID = $troopLeader['city'];
$leaderID = $troopLeader['no'];
$genlist = "";
$query = "select no,name,picture,imgsvr,turntime,city,turn0,turn1,turn2,turn3,turn4,turn5 from general where troop='{$troop['troop']}'";
$genresult = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$gencount = MYDB_num_rows($genresult);
for($j=0; $j < $gencount; $j++) {
$general = MYDB_fetch_array($genresult);
$genlist .= $general['name'].", ";
if($troop['no'] == $general['no']) {
$picture = $general['picture'];
$imageTemp = GetImageURL($general['imgsvr']);
$name = $general['name'];
$turntime = $general['turntime'];
$query = "select name from city where city='{$general['city']}'";
$cityresult = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$city = MYDB_fetch_array($cityresult);
$cityname = $city['name'];
$turn = "";
for($k=0; $k < 5; $k++) {
$m = $k+1;
$turnK = DecodeCommand($general["turn{$k}"]);
if($turnK[0] == 26) {
$turn .= "&nbsp;$m : 집합<br>";
} else {
$turn .= "&nbsp;$m : <br>";
}
}
foreach ($troop['users'] as $troopUser) {
$spanClass = 'troopUser';
if ($troopUser['city'] !== $cityID) {
$spanClass.= ' diffCity';
}
if ($troopUser['no'] == $leaderID) {
$spanClass.= ' leader';
}
$genlistText[] = "<span class='$spanClass' data-general-id='{$troopUser['no']}'
><span class='generalName'>{$troopUser['name']}</span><span class='cityText'>【{$troopUser['cityText']}】</span
></span>";
}
$genlist .= "({$gencount}명)";
if($me['troop'] == 0) {
echo "
$genlistText = sprintf('%s (%d명)', join(', ', $genlistText), count($genlistText)); ?>
<?php if ($me['troop'] == 0): ?>
<tr>
<td align=center rowspan=2><input "; echo $i==0?"checked ":""; echo "type=radio name=troop value='{$troop['troop']}'></td>
<td align=center >{$troop['name']}<br>【 $cityname 】</td>
<td height=64 style='background:no-repeat center url(\"{$imageTemp}/{$picture}\");background-size:64px;'>&nbsp;</td>
<td rowspan=2 width=62>$genlist</td>
<td rowspan=2>$turn</td>
<td align=center rowspan=2><input type='radio' name='troop' value='<?=$troop['troop']?>'></td>
<td align=center><?=$troop['name']?><br>【 <?=$cityText?> 】</td>
<td height=64 style='background:no-repeat center url("<?=$troopLeader['pictureFullPath']?>");background-size:64px;'>&nbsp;</td>
<td rowspan=2 width=62><?=$genlistText?></td>
<td rowspan=2><?=$troopLeader['turnText']?></td>
</tr>
<tr><td align=center><font size=2>【턴】".substr($turntime, 14)."</font></td><td align=center><font size=1>$name</font></td></tr>
<tr><td colspan=5>";
} else {
echo "
<tr>
<td align=center><font size=2>【턴】 <?=substr($troopLeader['turntime'], 14)?></font></td>
<td align=center><font size=1><?=$troopLeader['name']?></font></td></tr>
<tr><td colspan=5>
<?php else: ?>
<tr>
<td align=center rowspan=2>&nbsp;</td>
<td align=center >{$troop['name']}<br>【 $cityname 】</td>
<td height=64 style='background:no-repeat center url(\"{$imageTemp}/{$picture}\");background-size:64px;'>&nbsp;</td>
<td rowspan=2 width=576>$genlist</td>
<td rowspan=2>";
if($troop['no'] == $me['no']) {
$query = "select no,name from general where troop='{$troop['troop']}' and no!='{$me['no']}' order by binary(name)";
$genresult = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$genCount = MYDB_num_rows($genresult);
echo "
<td align=center ><?=$troop['name']?><br>【 <?=$cityText?> 】</td>
<td height=64 style='background:no-repeat center url("<?=$troopLeader['pictureFullPath']?>");background-size:64px;'>&nbsp;</td>
<td rowspan=2 width=62><?=$genlistText?></td>
<td rowspan=2>
<?php if ($me['no'] == $troopLeader['no']): ?>
<select name=gen size=3 style=color:white;background-color:black;font-size:13px;width:128px;>";
for($k=0; $k < $genCount; $k++) {
$general = MYDB_fetch_array($genresult);
echo "
<option value={$general['no']}>{$general['name']}</option>";
}
echo "
<?php foreach ($troop['users'] as $troopUser): ?>
<?php if ($troopUser['no'] == $me['no']) {
continue;
} ?>
<option value='<?=$troopUser['no']?>'><?=$troopUser['name']?></option>
<?php endforeach; ?>
</select><br>
<input type=submit name=btn value='부 대 추 방' style=width:130px;height:25px;>";
} else {
echo $turn;
}
echo "
<input type=submit name=btn value='부 대 추 방' style=width:130px;height:25px;>
<?php else: ?>
<?=$troopLeader['turnText']?>
<?php endif; ?>
</td>
</tr>
<tr><td align=center><font size=2>【턴】".substr($turntime, 14)."</font></td><td align=center><font size=1>$name</font></td></tr>
<tr><td colspan=5></td></tr>";
}
}
echo "</tbody>
<tfoot><tr><td>";
if ($troopcount == 0) {
}
else if($me['troop'] == 0) {
echo"
<input type=submit name=btn value='부 대 가 입'>";
} else {
echo"
<input type=submit name=btn value='부 대 탈 퇴' onclick='return confirm(\"정말 부대를 탈퇴하시겠습니까?\")'>";
}
<tr><td align=center><font size=2>【턴】 <?=substr($troopLeader['turntime'], 14)?></font></td>
<td align=center><font size=1><?=$troopLeader['name']?></font></td></tr>
<tr><td colspan=5></td></tr>
<?php endif;
} //foreach ($troops as $troopNo=>$troop) {
?>
</tbody>
echo "
</td></tr>
</tfoot>
</table>
<br>";
echo "
<br>
<table width=1000 class='tb_layout bg0'>
<tr>
<td width=80 id=bg1>부 대 명</td>
<td width=130><input type=text style=color:white;background-color:black; size=18 maxlength=9 name=name></td>";
if($me['troop'] == 0) {
echo "
<td><input type=submit name=btn value='부 대 창 설'></td>";
} else {
echo "
<td><input type=submit name=btn value='부 대 변 경'></td>";
}
echo "
<td width=130><input type=text style=color:white;background-color:black; size=18 maxlength=9 name=name></td>
<?php if($me['troop'] == 0): ?>
<td><input type=submit name=btn value='부 대 창 설'></td>
<?php else: ?>
<td><input type=submit name=btn value='부 대 변 경'></td>
<?php endif; ?>
</tr>
</table>";
</table>
?>
<table width=1000 class='tb_layout bg0'>
<tr><td><?=backButton()?></td></tr>
<tr><td><?=banner()?> </td></tr>
-1
View File
@@ -37,7 +37,6 @@ if($third < 0) { $third = 0; }
if($fourth < 0) { $fourth = 0; }
if($command > 99) { $command = 0; }
if($double > 9999) { $double = 9999; }
if($third > 9999) { $third = 9999; }
if($fourth > 9999) { $fourth = 9999; }
$comStr = EncodeCommand($fourth, $third, $double, $command);
+7 -3
View File
@@ -38,9 +38,13 @@ case 3: $tp = "intel"; $tp2 = "설전"; $tp3 = "intel"; break;
}
if($btn == '참가') {
$query = "select no,name,npc,leader,power,intel,explevel,gold,horse,weap,book from general where no='{$me['no']}'";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$general = MYDB_fetch_array($result);
if($db->queryFirstField('SELECT `no` FROM tournament WHERE `no`=%i', $me['no'])){
header('location:b_tournament.php');
exit(1);
}
$general = $db->queryFirstRow('SELECT no,name,npc,leader,power,intel,explevel,gold,horse,weap,book FROM general WHERE `no`=%i', $me['no']);
//{$admin['develcost']}원 참가비
if($general['gold'] < $admin['develcost']) {
+2 -1
View File
@@ -69,8 +69,9 @@
position: absolute;
z-index:6;
display:none;
width:120px;
min-width:120px;
border: 0.02em gray solid;
white-space: nowrap;
}
.world_map .city_name{
background-color: rgb(30, 164, 255);
+23
View File
@@ -0,0 +1,23 @@
#troop_list .cityText{
display:none;
}
#troop_list .diffCity .cityText{
display:inline;
}
#troop_list .diffCity {
color:red;
}
#troop_list .leader{
color:lightgreen;
}
#troop_list .leader::before{
content:'*';
}
#troop_list .leader::after{
content:'*';
}
+62 -1
View File
@@ -2017,7 +2017,7 @@ function updateTurntime($no) {
default: $alllog[0] = "<C>●</>{$admin['month']}월:<Y>{$general['name']}</>{$josaYi} <R>사망</>했습니다."; break;
}
// 엔피씨,엠피씨,의병 사망로그
if($general['npc'] == 2) {
if($general['npc'] == 2 || $general['npc'] == 6) {
$alllog[0] = "<C>●</>{$admin['month']}월:<Y>{$general['name']}</>{$josaYi} <R>사망</>했습니다.";
} elseif($general['npc'] >= 3) {
switch(rand()%10) {
@@ -2706,6 +2706,60 @@ function CharExperience($exp, $personal) {
return $exp;
}
function getCharExpMultiplier($personal):float{
static $table = [
0 => 1.1,
1 => 1.1,
4 => 0.9,
5 => 0.9,
6 => 1.1,
7 => 0.9,
10 => 0.9
];
return $table[$personal] ?? 1;
}
function getNationTechMultiplier($nationType):float{
static $table = [
3 => 1.1,
5 => 0.9,
6 => 0.9,
7 => 0.9,
8 => 0.9,
12 => 0.9,
13 => 1.1,
];
return $table[$nationType] ?? 1;
}
function getNationWallMultiplier($nationType):float{
static $table = [
3 => 1.1,
5 => 1.1,
10 => 1.1,
11 => 1.1,
4 => 0.9,
7 => 0.9,
8 => 0.9,
13 => 0.9,
];
return $table[$nationType] ?? 1;
}
function getNationPeopleMultiplier($nationType):float{
static $table = [
1 => 0.9,
2 => 1.1,
3 => 0.9,
4 => 1.1,
7 => 1.1,
9 => 0.9,
10 => 1.1,
];
return $table[$nationType] ?? 1;
}
function CharDedication($ded, $personal) {
switch($personal) {
case 10:
@@ -2716,6 +2770,13 @@ function CharDedication($ded, $personal) {
return $ded;
}
function getCharDedMultiplier($personal):float{
static $table = [
10 => 0.9
];
return $table[$personal] ?? 1;
}
function CharAtmos($atmos, $personal) {
switch($personal) {
case 2: case 4:
+2 -2
View File
@@ -471,7 +471,7 @@ function processCommand($no) {
$gameStor = KVStorage::getStorage($db, 'game_env');
$connect=$db->get();
$query = "select npc,no,name,picture,imgsvr,nation,nations,city,troop,injury,affinity,leader,leader2,power,power2,intel,intel2,experience,dedication,level,gold,rice,crew,crewtype,train,atmos,weap,book,horse,item,turntime,makenation,makelimit,killturn,block,dedlevel,explevel,age,belong,personal,special,special2,term,turn0,dex0,dex10,dex20,dex30,dex40 from general where no='$no'";
$query = "select npc,no,name,picture,imgsvr,nation,nations,city,troop,injury,affinity,leader,leader2,power,power2,intel,intel2,experience,dedication,level,gold,rice,crew,crewtype,train,atmos,weap,book,horse,item,turntime,makenation,makelimit,killturn,block,dedlevel,explevel,age,belong,personal,special,special2,term,turn0,dex0,dex10,dex20,dex30,dex40,warnum,killnum,deathnum,killcrew,deathcrew,recwar from general where no='$no'";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$general = MYDB_fetch_array($result);
@@ -533,7 +533,7 @@ function processCommand($no) {
}
//장수정보 재로드
$query = "select npc,no,name,picture,imgsvr,nation,nations,city,troop,injury,affinity,leader,leader2,power,power2,intel,intel2,experience,dedication,level,gold,rice,crew,crewtype,train,atmos,weap,book,horse,item,turntime,makenation,makelimit,killturn,block,dedlevel,explevel,age,belong,personal,special,special2,term,turn0,dex0,dex10,dex20,dex30,dex40 from general where no='$no'";
$query = "select npc,no,name,picture,imgsvr,nation,nations,city,troop,injury,affinity,leader,leader2,power,power2,intel,intel2,experience,dedication,level,gold,rice,crew,crewtype,train,atmos,weap,book,horse,item,turntime,makenation,makelimit,killturn,block,dedlevel,explevel,age,belong,personal,special,special2,term,turn0,dex0,dex10,dex20,dex30,dex40,warnum,killnum,deathnum,killcrew,deathcrew,recwar from general where no='$no'";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$general = MYDB_fetch_array($result);
}
+38 -97
View File
@@ -384,41 +384,14 @@ function getCall($leader, $power, $intel) {
}
function getDed($dedication) {
if($dedication < 1 ) $level2 = '무품관';
elseif($dedication < 10*10) $level2 = '30품관';
elseif($dedication < 20*20) $level2 = '29품관';
elseif($dedication < 30*30) $level2 = '28품관';
elseif($dedication < 40*40) $level2 = '27품관';
elseif($dedication < 50*50) $level2 = '26품관';
elseif($dedication < 60*60) $level2 = '25품관';
elseif($dedication < 70*70) $level2 = '24품관';
elseif($dedication < 80*80) $level2 = '23품관';
elseif($dedication < 90*90) $level2 = '22품관';
elseif($dedication < 100*100) $level2 = '21품관';
elseif($dedication < 110*110) $level2 = '20품관';
elseif($dedication < 120*120) $level2 = '19품관';
elseif($dedication < 130*130) $level2 = '18품관';
elseif($dedication < 140*140) $level2 = '17품관';
elseif($dedication < 150*150) $level2 = '16품관';
elseif($dedication < 160*160) $level2 = '15품관';
elseif($dedication < 170*170) $level2 = '14품관';
elseif($dedication < 180*180) $level2 = '13품관';
elseif($dedication < 190*190) $level2 = '12품관';
elseif($dedication < 200*200) $level2 = '11품관'; // 40000
elseif($dedication < 210*210) $level2 = '10품관'; // 44100
elseif($dedication < 220*220) $level2 = '9품관'; // 48400
elseif($dedication < 230*230) $level2 = '8품관'; // 52900
elseif($dedication < 240*240) $level2 = '7품관'; // 57600
elseif($dedication < 250*250) $level2 = '6품관'; // 62500
elseif($dedication < 260*260) $level2 = '5품관'; // 67600
elseif($dedication < 270*270) $level2 = '4품관'; // 72900
elseif($dedication < 280*280) $level2 = '3품관'; // 78400
elseif($dedication < 290*290) $level2 = '2품관'; // 84100
else {
$level2 = '1품관';
$dedLevel = getDedLevel($dedication);
if($dedLevel == 0){
return '품관';
}
return $level2;
//{$maxDedLevel}품관 ~ 1품관
$dedInvLevel = GameConst::$maxDedLevel - $dedLevel + 1;
return "{$dedInvLevel}품관";
}
@@ -445,16 +418,18 @@ function getExpLevel($experience) {
if($experience < 1000) {
$level = intdiv($experience, 100);
} else {
for($level = 0; $experience > (($level+1)*($level+1)*10); $level++) {
}
$level = Util::toInt(sqrt($experience/10));
}
return $level;
}
function getDedLevel($dedication) {
for($level = 0; $dedication > (($level+1)*($level+1)*100); $level++) {
}
$level = Util::valueFit(
ceil(sqrt($dedication) / 10),
0,
GameConst::$maxDedLevel
);
return $level;
}
@@ -471,9 +446,7 @@ function getLevelPer($exp, $level) {
}
function getBill(int $dedication) : int{
for($level = 0; $dedication > (($level+1)*($level+1)*100); $level++) {
}
$level = getDedLevel($dedication);
return ($level * 200 + 400);
}
@@ -481,72 +454,40 @@ function getCost(int $armtype) : int {
return GameUnitConst::byID($armtype)->cost;
}
function TechLimit($startyear, $year, $tech) : int {
$limit = 0;
if($year < $startyear+ 5 && $tech >= 1000) { $limit = 1; }
if($year < $startyear+10 && $tech >= 2000) { $limit = 1; }
if($year < $startyear+15 && $tech >= 3000) { $limit = 1; }
if($year < $startyear+20 && $tech >= 4000) { $limit = 1; }
if($year < $startyear+25 && $tech >= 5000) { $limit = 1; }
if($year < $startyear+30 && $tech >= 6000) { $limit = 1; }
if($year < $startyear+35 && $tech >= 7000) { $limit = 1; }
if($year < $startyear+40 && $tech >= 8000) { $limit = 1; }
if($year < $startyear+45 && $tech >= 9000) { $limit = 1; }
if($year < $startyear+50 && $tech >= 10000) { $limit = 1; }
if($year < $startyear+55 && $tech >= 11000) { $limit = 1; }
if($year < $startyear+60 && $tech >= 12000) { $limit = 1; }
return $limit;
function getTechLevel($tech):int{
return Util::valueFit(
floor($tech / 1000),
0,
GameConst::$maxTechLevel
);
}
function TechLimit($startyear, $year, $tech) : bool {
$relYear = $startyear - $year;
$relMaxTech = Util::valueFit(
floor($relYear / 5) + 1,
1,
GameConst::$maxTechLevel
);
$techLevel = getTechLevel($tech);
return $techLevel >= $relMaxTech;
}
function getTechAbil($tech) : int{
if($tech < 1000) { $abil = 0; }
elseif($tech < 2000) { $abil = 25; }
elseif($tech < 3000) { $abil = 50; }
elseif($tech < 4000) { $abil = 75; }
elseif($tech < 5000) { $abil = 100; }
elseif($tech < 6000) { $abil = 125; }
elseif($tech < 7000) { $abil = 150; }
elseif($tech < 8000) { $abil = 175; }
elseif($tech < 9000) { $abil = 200; }
elseif($tech < 10000) { $abil = 225; }
elseif($tech < 11000) { $abil = 250; }
elseif($tech < 12000) { $abil = 275; }
else { $abil = 300; }
return $abil;
return getTechLevel($tech) * 25;
}
function getTechCost($tech) : float{
if($tech < 1000) { $cost = 1.00; }
elseif($tech < 2000) { $cost = 1.15; }
elseif($tech < 3000) { $cost = 1.30; }
elseif($tech < 4000) { $cost = 1.45; }
elseif($tech < 5000) { $cost = 1.60; }
elseif($tech < 6000) { $cost = 1.75; }
elseif($tech < 7000) { $cost = 1.90; }
elseif($tech < 8000) { $cost = 2.05; }
elseif($tech < 9000) { $cost = 2.20; }
elseif($tech < 10000) { $cost = 2.35; }
elseif($tech < 11000) { $cost = 2.50; }
elseif($tech < 12000) { $cost = 2.65; }
else { $cost = 2.80; }
return $cost;
return 1 + getTechLevel($tech) * 0.15;
}
function getTechCall($tech) : string {
if($tech < 1000) { $str = '0등급'; }
elseif($tech < 2000) { $str = '1등급'; }
elseif($tech < 3000) { $str = '2등급'; }
elseif($tech < 4000) { $str = '3등급'; }
elseif($tech < 5000) { $str = '4등급'; }
elseif($tech < 6000) { $str = '5등급'; }
elseif($tech < 7000) { $str = '6등급'; }
elseif($tech < 8000) { $str = '7등급'; }
elseif($tech < 9000) { $str = '8등급'; }
elseif($tech < 10000) { $str = '9등급'; }
elseif($tech < 11000) { $str = '10등급'; }
elseif($tech < 12000) { $str = '11등급'; }
else { $str = '12등급'; }
return $str;
$techLevel = getTechLevel($tech);
return "{$techLevel}등급";
}
function getDexCall($dex) : string {
+4
View File
@@ -125,6 +125,10 @@ function addGenDex($no, $atmos, $train, $type, $exp) {
$db = DB::db();
$armType = GameUnitConst::byId($type)->armType;
if($armType == GameUnitConst::T_CASTLE){
$armType = GameUnitConst::T_SIEGE;
}
if($armType < 0){
return;
}
+8
View File
@@ -60,6 +60,7 @@ function getWorldMap($req){
$session = Session::getInstance();
$userID = $session->userID;
$userGrade = $session->userGrade;
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
@@ -146,6 +147,13 @@ function getWorldMap($req){
array_map('\\sammo\\Util::toInt', [$r['city'], $r['level'], $r['state'], $r['nation'], $r['region'], $r['supply']]);
}
if(($req->showMe || !$req->neutralView) && $userGrade >= 5){
$spyInfo = [];
foreach($cityList as $tmpCity){
$spyInfo[$tmpCity[0]] = 1;
}
}
return [
'startYear' => $startYear,
'year' => $year,
+28 -32
View File
@@ -84,6 +84,9 @@ function SetCrew($no, $personal, $gold, $leader, $genType, $tech, $region, $city
$db = DB::db();
$connect=$db->get();
$gameStor = KVStorage::getStorage($db, 'game_env');
[$startyear, $year] = $gameStor->getValuesAsArray(['startyear', 'year']);
$type = 0;
switch($genType) {
case 0: //무장
@@ -109,45 +112,38 @@ function SetCrew($no, $personal, $gold, $leader, $genType, $tech, $region, $city
$type = GameUnitConst::DEFAULT_CREWTYPE;
switch($sel) {
case 0:
$type = 0; //보병
if($tech >= 3000 && $city == 3) { $type = 4; } //근위병
elseif($tech >= 2000 && $city == 64) { $type = 3; } //자객병
elseif($tech >= 1000 && $region == 2) { $type = 1; } //청주병
elseif($tech >= 1000 && $region == 5) { $type = 5; } //등갑병
elseif($tech >= 1000 && $region == 7) { $type = 2; } //수병
foreach(GameUnitConst::byType(GameUnitConst::T_FOOTMAN) as $crewtype){
if($crewtype->isValid([$city], [$region], $year-$startyear, $tech)){
$type = $crewtype->id;
}
}
break;
case 1:
$type = 10; //궁병
if($tech >= 3000 && $city == 7) { $type = 14; } //석궁병
elseif($tech >= 3000 && $city == 6) { $type = 13; } //강궁병
elseif($tech >= 1000 && $region == 4) { $type = 12; } //연노병
elseif($tech >= 1000 && $region == 8) { $type = 11; } //궁기병
foreach(GameUnitConst::byType(GameUnitConst::T_ARCHER) as $crewtype){
if($crewtype->isValid([$city], [$region], $year-$startyear, $tech)){
$type = $crewtype->id;
}
}
break;
case 2:
$type = 20; //기병
if($tech >= 3000 && $city == 2) { $type = 27; } //호표기병
elseif($tech >= 2000 && $city == 63) { $type = 24; } //철기병
elseif($tech >= 2000 && $city == 67) { $type = 25; } //수렵기병
elseif($tech >= 2000 && $city == 65) { $type = 23; } //돌격기병
elseif($tech >= 2000 && $city == 66) { $type = 26; } //맹수병
elseif($tech >= 1000 && $region == 1) { $type = 21; } //백마병
elseif($tech >= 1000 && $region == 3) { $type = 22; } //중장기병
foreach(GameUnitConst::byType(GameUnitConst::T_CAVALRY) as $crewtype){
if($crewtype->isValid([$city], [$region], $year-$startyear, $tech)){
$type = $crewtype->id;
}
}
break;
}
break;
case 1: //지장
case 3: //지내정장
$type = 30; //귀병
if($tech >= 3000 && $city == 4) { $type = 34; } //악귀병
elseif($tech >= 3000 && $city == 5) { $type = 37; } //천귀병
elseif($tech >= 3000 && $city == 1) { $type = 38; } //마귀병
elseif($tech >= 2000 && $city == 69) { $type = 33; } //흑귀병
elseif($tech >= 2000 && $city == 68) { $type = 32; } //백귀병
elseif($tech >= 1000 && $region == 6) { $type = 31; } //신귀병
elseif($tech >= 3000 && $city == 3) { $type = 36; } //황귀병
elseif($tech >= 1000 && rand()%100 < 50) { $type = 35; } //남귀병
foreach(GameUnitConst::byType(GameUnitConst::T_WIZARD) as $crewtype){
if($crewtype->isValid([$city], [$region], $year-$startyear, $tech)){
$type = $crewtype->id;
}
}
break;
}
@@ -306,10 +302,10 @@ function processAI($no) {
}
//재야인경우
if($general['npc'] == 5 && $general['level'] == 0) {
if($general['npc'] == 9 && $general['level'] == 0) {
// 오랑캐는 바로 임관
$rulerNation = $db->queryFirstField('SELECT nation FROM general WHERE `level`=12 AND npc=5 and nation not in %li ORDER BY RAND() limit 1', Json::decode($general['nations']));
$rulerNation = $db->queryFirstField('SELECT nation FROM general WHERE `level`=12 AND npc=9 and nation not in %li ORDER BY RAND() limit 1', Json::decode($general['nations']));
if($ruler) {
$command = EncodeCommand(0, 0, $rulerNation, 25); //임관
@@ -319,7 +315,7 @@ function processAI($no) {
$query = "update general set turn0='$command' where no='{$general['no']}'";
MYDB_query($query, $connect) or Error("processAI07 ".MYDB_error($connect),"");
return;
} elseif($general['npc'] < 5 && $general['level'] == 0) {
} elseif($general['npc'] != 9 && $general['level'] == 0) {
switch(Util::choiceRandomUsingWeight([11.4, 40, 20, 28.6])) {
//임관 10%
case 0:
@@ -376,7 +372,7 @@ function processAI($no) {
//군주가 할일
if($general['level'] == 12) {
//오랑캐인데 공격 못하면 바로 방랑/해산
if($general['npc'] == 5 && $dipState == 0 && !$attackable) {
if($general['npc'] == 9 && $dipState == 0 && !$attackable) {
//방랑군이냐 아니냐
if($nation['level'] == 0) {
// 해산
+5 -17
View File
@@ -814,8 +814,8 @@ function process_9(&$general) {
$log[] = "<C>●</>{$admin['month']}월:{$stype}을 <C>$score</> 조달했습니다. <1>$date</>";
}
$exp = $score * 0.7;
$ded = $score * 1.0;
$exp = $score * 0.7 / 3;
$ded = $score * 1.0 / 3;
// 성격 보정
$exp = CharExperience($exp, $general['personal']);
@@ -974,7 +974,8 @@ function process_11(&$general, $type) {
return;
}
$actLog->pushGeneralActionLog($crewTypeObj->name."을(를) <C>{$crew}</>명 {$dtype}했습니다. <1>$date</>");
$josaUl = JosaUtil::pick($crewTypeObj->name, '을');
$actLog->pushGeneralActionLog($crewTypeObj->name."{$josaUl} <C>{$crew}</>명 {$dtype}했습니다. <1>$date</>");
$exp = Util::round($crew / 100);
$ded = Util::round($crew / 100);
// 숙련도 증가
@@ -1288,20 +1289,7 @@ function process_16(&$general) {
// 숙련도 증가
addGenDex($general['no'], GameConst::$maxAtmosByCommand, GameConst::$maxTrainByCommand, $general['crewtype'], Util::round($general['crew']/100));
// 전투 처리
$dead = processWar($general, $destcity);
// 기술력 따라서 보정
$dead['att'] = Util::round($dead['att'] * getTechCost($nation['tech']));
$dead['def'] = Util::round($dead['def'] * getTechCost($dnation['tech']));
// 사상자 누적
if($nation['nation'] > 0 && $dnation['nation'] > 0) {
$query = "update diplomacy set dead=dead+'{$dead['att']}' where me='{$nation['nation']}' and you='{$dnation['nation']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$query = "update diplomacy set dead=dead+'{$dead['def']}' where you='{$nation['nation']}' and me='{$dnation['nation']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
}
processWar($general, $destcity);
$log = uniqueItem($general, $log);
}
+2 -2
View File
@@ -172,9 +172,9 @@ function process_25(&$general) {
$log[] = "<C>●</>{$admin['month']}월:현재 <D>{$nation['name']}</>{$josaUn} 임관이 제한되고 있습니다. 임관 실패.";
} elseif($admin['year'] < $admin['startyear']+3 && $gencount >= GameConst::$initialNationGenLimit) {
$log[] = "<C>●</>{$admin['month']}월:현재 <D>{$nation['name']}</>{$josaUn} 임관이 제한되고 있습니다. 임관 실패.";
} elseif($nation['scout'] == 1 && $general['npc'] < 5) {
} elseif($nation['scout'] == 1 && $general['npc'] != 9) {
$log[] = "<C>●</>{$admin['month']}월:현재 <D>{$nation['name']}</>{$josaUn} 임관이 금지되어 있습니다. 임관 실패.";
} elseif($general['makelimit'] > 0 && $general['npc'] < 5) {
} elseif($general['makelimit'] > 0 && $general['npc'] != 9) {
$log[] = "<C>●</>{$admin['month']}월:재야가 된지 12턴이 지나야 합니다. 임관 실패. <1>$date</>";
} elseif(in_array($nation['nation'], $joinedNations)) {
$log[] = "<C>●</>{$admin['month']}월:이미 임관했었던 국가입니다. 임관 실패. <1>$date</>";
+2 -2
View File
@@ -298,7 +298,7 @@ function fillLowGenAll() {
}
//자동신청하고, 돈 있고, 아직 참가 안한 장수
$query = "select no,npc,name,leader,power,intel,explevel from general where tnmt='1' and tournament='0' and gold>='{$develcost}' order by rand() limit 0,64";
$query = "select no,npc,name,leader,power,intel,explevel from general where tnmt='1' and tournament='0' order by rand() limit 0,64";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$genCount = MYDB_num_rows($result);
@@ -313,7 +313,7 @@ function fillLowGenAll() {
if($genCount > 0) {
$genCount--;
$gen = MYDB_fetch_array($result);
$query = "update general set gold=gold-'{$develcost}',tournament='1' where no='{$gen['no']}'";
$query = "update general set tournament='1' where no='{$gen['no']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$query = "insert into tournament (no, npc, name, ldr, pwr, itl, lvl, grp, grp_no) values ('{$gen['no']}', '{$gen['npc']}', '{$gen['name']}', '{$gen['leader']}', '{$gen['power']}', '{$gen['intel']}', '{$gen['explevel']}', '$i', '$grpCount[$i]')";
+1 -1
View File
@@ -17,7 +17,7 @@ if(!strpos($_SERVER['HTTP_REFERER'], $url)) {
]);
}
if(!$year || !$month) {
if($year === null || !$month) {
Json::die([
'result'=>false,
'reason'=>'year, month가 지정되지 않았습니다'
+1
View File
@@ -222,6 +222,7 @@ $db->insert('general', [
'turntime' => $turntime,
'killturn' => 6,
'lastconnect' => $lastconnect,
'crewtype'=>GameUnitConst::DEFAULT_CREWTYPE,
'makelimit' => 0,
'age' => $age,
'startage' => $age,
+40 -174
View File
@@ -8,94 +8,8 @@ $(function(){
var $userFrame;
window.groupList = groupList;
window.userList = userList;
var aGroup = {};
$('#troop_list tbody > tr').each(function(idx){
var $this = $(this);
//console.log(this);
//console.log($this);
if(idx%3 == 0){
aGroup = {
turn : '77:77',
turnTime : 5555,
부대장 : '에러-집합장없음',
부대명 : '에러-부대명없음',
srclist : [],
도시 : '없지롱',
list: [],
trs:[]
};
aGroup.trs.push($this);
var $children = $this.children();
var names = $.trim($children.eq(1).text()).split('【');
var 부대명 = $.trim(names[0]);
var 도시 = $.trim(names[1].substr(0,names[1].length-1));
aGroup.도시 = 도시;
aGroup.부대명 = 부대명;
aGroup.obj = $this;
aGroup.$users = $children.eq(3);
var lists = $.trim($children.eq(3).text()).split(', ');
lists.pop();
aGroup.srcList = lists;
}
else if(idx%3 == 1){
aGroup.trs.push($this);
var turnBase = $this.children().eq(0).text().split('】')[1];
//console.log(turnBase);
var userName = $this.children().eq(1).text();
var turn = turnBase;
var turnMS = turnBase.split(':');
var turnM = parseInt(turnMS[0]);
var turnS = parseInt(turnMS[1]);
var turnTime = turnM*60+turnS;
aGroup.turn = turn;
aGroup.turnTime = turnTime;
aGroup.부대장 = userName;
aGroup.obj2 = $this;
groupList[aGroup.부대명] = aGroup;
tGroup.push(aGroup);
}
else{
if($this.find('input').length==0){
$this.detach();
}
}
});
$.each(tGroup,function(idx,val){
console.log(val);
for(var i=0;i<val.trs.length;i++){
val.trs[i].detach();
}
});
tGroup.sort(function(lhs,rhs){
return lhs.turnTime-rhs.turnTime;
});
var $last = $('table:eq(1) tr:eq(-1)');
var $tbody = $('table:eq(1) tbody');
$last.detach();
console.log($last);
$.each(tGroup,function(idx,val){
for(var i=0;i<val.trs.length;i++){
$tbody.append(val.trs[i]);
}
$tbody.append('<tr><td colspan="5"></td></tr>');
});
$tbody.find('tr:eq(-1)').detach();
$tbody.append($last);
var runAnalysis = function(){
$.each(groupList,function(idx,val){
val.list = [];
@@ -111,19 +25,15 @@ $(function(){
var tmpUsers = {};
$html.each(function(idx){
if(this.tagName == "TABLE"){
cnt+=1;
if(cnt==2){
tmpUsers = $(this);
return false;
}
var $this = $(this);
if($this.attr('id') == "general_list"){
tmpUsers = $(this);
return false;
}
});
tmpUsers.find("tbody > tr").each(function(idx){
var $this = $(this);
var $부대 = $this.children('.i_troop');
var 부대 = $.trim($부대.text());
@@ -134,73 +44,27 @@ $(function(){
}
$부대.remove();
var $name = $this.children('.i_name');
$name.addClass('nameplate');
var name = $name.find('.t_name').text();
var $도시 = $this.children('.i_city');
var 도시 = $.trim($도시.text());
var $턴 = $this.children('.i_action');
//console.log($턴);
var 턴0 = $턴.text().split(':');
var = parseInt(턴0[0])*60 + parseInt(턴0[1]);
var userInfo = {
이름 : name,
부대 : 부대,
도시 : 도시,
: ,
obj : $this
};
groupList[부대].list.push(userInfo);
userList[name] = userInfo;
var generalID = parseInt($this.data('general-id'));
userList[generalID] = $this;
$this.hide();
$content.append($this);
});
$.each(groupList,function(부대명,aGroup){
aGroup.$users.html('');
$.each(aGroup.list,function(idx,userInfo){
var $user = $('<span><span class="name"></span><span class="other"></span></span>');
var $userName = $user.children('.name');
if(userInfo.이름 == aGroup.부대장){
$userName.html('*'+userInfo.이름+'*');
$userName.css('color','lightgreen');
}
else{
$userName.html(userInfo.이름);
}
if(userInfo.도시 != aGroup.도시){
$userName.css('color','red');
$user.children('.other').html('【'+userInfo.도시+'】');
}
$user.hover(function(){
var top = aGroup.obj2.offset().top + aGroup.obj2.outerHeight();
$userFrame.css('top',top);
userInfo.obj.show();
$userFrame.show();
console.log('올림!'+userInfo.이름);
},function(){
$userFrame.hide();
userInfo.obj.hide();
console.log('내림!'+userInfo.이름);
});
$user.append(', ');
aGroup.$users.append($user);
});
aGroup.$users.append('('+aGroup.list.length+'명)');
$('.troopUser').hover(function(){
var $this = $(this);
var parent = $this.closest('tr');
var generalID = parseInt($this.data('general-id'));
console.log(generalID);
var top = parent.offset().top + parent.outerHeight();
$userFrame.css('top',top);
userList[generalID].show();
$userFrame.show();
},function(){
var $this = $(this);
var parent = $this.closest('tr');
var generalID = parseInt($this.data('general-id'));
userList[generalID].hide();
$userFrame.hide();
});
}
catch(err){
@@ -223,24 +87,26 @@ $(function(){
$userFrame = $('<div id="on_mover" style="position:absolute;">'+
'<table class="tb_layout bg0" style="width:100%;"><thead><tr>'+
'<td width="98" align="center" class="bg1">이 름</td>'+
'<td width="98" align="center" class="bg1"">통무지</td>'+
'<td width="58" align="center" class="bg1">자 금</td>'+
'<td width="58" align="center" class="bg1">군 량</td>'+
'<td width="48" align="center" class="bg1">도시</td>'+
'<td width="28" align="center" class="bg1">守</td>'+
'<td width="58" align="center" class="bg1">병 종</td>'+
'<td width="68" align="center" class="bg1">병 </td>'+
'<td width="48" align="center" class="bg1">훈련</td>'+
'<td width="48" align="center" class="bg1">사기</td>'+
'<td width="148" align="center" class="bg1">명 령</td>'+
'<td width="58" align="center" class="bg1">삭턴</td>'+
'<td width="58" align="center" class="bg1">턴</td>'+
'</tr></thead><tbody class="content"></tbody></table></div>');
$userFrame = $("<div id='on_mover' style='position:absolute;'>"+
"<table class='tb_layout bg0' style='width:100%;'><thead>"+
"<tr>"+
"<td width=98 class='bg1 center'>이 름</td>"+
"<td width=98 class='bg1 center'>통무지</td>"+
"<td width=53 class='bg1 center'>자 금</td>"+
"<td width=53 class='bg1 center'>군 량</td>"+
"<td width=48 class='bg1 center'>도시</td>"+
"<td width=28 class='bg1 center'>守</td>"+
"<td width=58 class='bg1 center'>병 </td>"+
"<td width=63 class='bg1 center'>병 사</td>"+
"<td width=38 class='bg1 center'>훈련</td>"+
"<td width=38 class='bg1 center'>사기</td>"+
"<td width=213 class='bg1 center'>명 령</td>"+
"<td width=38 class='bg1 center'>삭턴</td>"+
"<td width=48 class='bg1 center'>턴</td>"+
"</tr>"+
"</thead></thead><tbody class='content'></tbody></table></div>");
$userFrame.find('thead td');
$userFrame.css('width','900px').css('margin','0').css('padding','0').css('left','50%').css('margin-left','-450px');
$userFrame.css('width','960px').css('margin','0').css('padding','0').css('left','50%').css('margin-left','-480px');
$userFrame.hide();
-31
View File
@@ -143,37 +143,6 @@ function reloadWorldMap(option){
var myCity = obj.myCity;
var myNation = obj.myNation;
function formatCityInfo(city) {
var region_str = '';
var level_str = '';
switch(city.region) {
case 1: region_str = "【하북|"; break;
case 2: region_str = "【중원|"; break;
case 3: region_str = "【서북|"; break;
case 4: region_str = "【서촉|"; break;
case 5: region_str = "【남중|"; break;
case 6: region_str = "【 초|"; break;
case 7: region_str = "【오월|"; break;
case 8: region_str = "【동이|"; break;
}
switch(city.level) {
case 1: level_str = "수】"; break;
case 2: level_str = "진】"; break;
case 3: level_str = "관】"; break;
case 4: level_str = "이】"; break;
case 5: level_str = "소】"; break;
case 6: level_str = "중】"; break;
case 7: level_str = "대】"; break;
case 8: level_str = "특】"; break;
}
city.text = region_str + level_str + city.name;
city.region_str = region_str;
city.level_str = level_str;
return city;
}
function mergePositionInfo(city){
var id = city.id;
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1877
View File
@@ -0,0 +1,1877 @@
<?php
namespace sammo;
function processWar($general, $city) {
'@phan-var array<string,int|string|null> $general';
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
$connect=$db->get();
$templates = new \League\Plates\Engine(__dir__.'/templates');
$date = substr($general['turntime'],11,5);
$admin = $gameStor->getAll();
$year = $admin['year'];
$month = $admin['month'];
$log = [];
$batlog = [];
$batres = [];
$opplog = [];
$oppbatlog = [];
$oppbatres = [];
$alllog = [];
$history = [];
$deadAmount = [
'att'=>0,
'def'=>0
];
$generalCrewType = GameUnitConst::byID($general['crewtype']);
$warphase = $generalCrewType->speed; //병종간 페이즈 수 얻기
// 특기보정 : 돌격
if($general['special2'] == 60) { $warphase += 1; }
$genAtmos = 0;
if($general['item'] == 3) {
//탁주 사용
$genAtmos += 3;
$query = "update general set item=0 where no='{$general['no']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$josaUl = JosaUtil::pick(getItemName($general['item']), '을');
$log[] = "<C>●</><C>".getItemName($general['item'])."</>{$josaUl} 사용!";
$general['item'] = 0;
} elseif($general['item'] >= 14 && $general['item'] <= 16) {
//의적주, 두강주, 보령압주 사용
$genAtmos += 5;
} elseif($general['item'] >= 19 && $general['item'] <= 20) {
//춘화첩, 초선화 사용
$genAtmos += 7;
}
$genTrain = 0;
if($general['item'] == 4) {
//청주 사용
$genTrain += 3;
$query = "update general set item=0 where no='{$general['no']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$josaUl = JosaUtil::pick($general['item'], '을');
$log[] = "<C>●</><C>".getItemName($general['item'])."</>{$josaUl} 사용!";
$general['item'] = 0;
} elseif($general['item'] >= 12 && $general['item'] <= 13) {
//과실주, 이강주 사용
$genTrain += 5;
} elseif($general['item'] >= 17 && $general['item'] <= 18) {
//철벽서, 단결도 사용
$genTrain += 7;
}
// 우선 스케일링
$city['def'] *= 10;
$city['wall'] *= 10;
$query = "select level from city where city='{$general['city']}'";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$originCity = MYDB_fetch_array($result);
$query = "select nation,level,name,capital,tech,type from nation where nation='{$general['nation']}'";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$nation = MYDB_fetch_array($result);
setLeadershipBonus($general, $nation['level']);
$query = "select nation,level,name,rice,capital,tech,type from nation where nation='{$city['nation']}'";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$destnation = MYDB_fetch_array($result) ?: [
'nation'=>0,
'capital'=>0,
'level'=>0,
'rice'=>2000,
'type'=>0,
'tech'=>0
];
//장수수 구함
$query = "select no from general where nation='{$general['nation']}'";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$gencount = MYDB_num_rows($result);
if($gencount < GameConst::$initialNationGenLimit) $gencount = GameConst::$initialNationGenLimit;
//장수수 구함
$query = "select no from general where nation='{$destnation['nation']}'";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$destgencount = MYDB_num_rows($result);
if($destgencount < GameConst::$initialNationGenLimit) $destgencount = GameConst::$initialNationGenLimit;
$genAtmosBonus = 0; $genTrainBonus = 0;
$oppAtmosBonus = 0; $oppTrainBonus = 0;
//공격자 수도보정
if($nation['capital'] == $general['city']) { $genAtmosBonus += 5; }
//방어자 수도보정
//if($destnation['capital'] == $city['city']) { $oppTrainBonus += 5; }
//관,진,수진 보정
if($city['level'] == 1) { $oppTrainBonus += 5; } // 방어도시가 수진이면 방어자 방어보정
if($originCity['level'] == 2) { $genAtmosBonus += 5; } // 출병도시가 진이면 공격자 공격보정
if($city['level'] == 3) { $oppTrainBonus += 5; } // 방어도시가 관이면 방어자 방어보정
$josaRo = JosaUtil::pick($city['name'], '로');
$josaYi = JosaUtil::pick($general['name'], '이');
$alllog[] = "<C>●</>{$month}월:<D><b>{$nation['name']}</b></>의 <Y>{$general['name']}</>{$josaYi} <G><b>{$city['name']}</b></>{$josaRo} 진격합니다.";
$log[] = "<C>●</>{$month}월:<G><b>{$city['name']}</b></>{$josaRo} <M>진격</>합니다. <1>$date</>";
// 목표 도시내에 목표 국가 소속 장수 중, 병사가 있는 능력치합+병사수 순으로 훈,사 60, 80 이상
$query = "select no,name,turntime,personal,special2,crew,crewtype,atmos,train,intel,intel2,book,power,power2,weap,injury,leader,leader2,horse,item,explevel,level,rice,leader+power+intel+weap+horse+book+crew/100 as sum,dex0,dex10,dex20,dex30,dex40 from general where city='{$city['city']}' and nation='{$city['nation']}' and nation!=0 and crew>'0' and rice>round(crew/100) and ((train>=60 and atmos>=60 and mode=1) or (train>=80 and atmos>=80 and mode=2)) order by sum desc";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$opposecount = MYDB_num_rows($result);
$exp = 0; //병사 소진 시킨 만큼
$opexp = 0;
$exp2 = 1; //능력경험치
$phase = 0;
while($phase < $warphase) {
// 장수가 없어서 도시 공격하려했으나 병량없을시
if($opposecount == 0 && $destnation['nation'] > 0 && $destnation['rice'] <= 0 && $city['supply'] == 1) {
$general['train'] += 1; //훈련 상승
if($general['train'] > GameConst::$maxTrainByWar) { $general['train'] = GameConst::$maxTrainByWar; }
$query = "update general set recwar='{$general['turntime']}',train='{$general['train']}',warnum=warnum+1 where no='{$general['no']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$alllog[] = "<C>●</>{$month}월:병량 부족으로 <G><b>{$city['name']}</b></>의 수비병들이 <R>패퇴</>합니다.";
$josaUl = JosaUtil::pick($city['name'], '을');
$josaYi = JosaUtil::pick($general['name'], '이');
$history[] = "<C>●</>{$year}{$month}월:<M><b>【패퇴】</b></><D><b>{$destnation['name']}</b></>{$josaYi} 병량 부족으로 <G><b>{$city['name']}</b></>{$josaUl} 뺏기고 말았습니다.";
pushGenLog($general, $log);
pushGeneralPublicRecord($alllog, $year, $month);
pushWorldHistory($history);
$log = [];
$alllog = [];
$history= [];
//패퇴시 병량보충
$destnation['rice'] += 500;
$query = "update nation set rice='{$destnation['rice']}' where nation='{$destnation['nation']}'";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
//내정 피폐
$query = "update city set agri=agri*0.5,comm=comm*0.5,secu=secu*0.5 where city='{$city['city']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$city = addConflict($city, $general['nation'], 1);//NOTE: 이 경우 두 국가가 분쟁 중인 경우에는 병량패퇴의 이득이 없다.
ConquerCity($admin, $general, $city, $nation, $destnation);
break;
// 장수가 없어서 도시 공격
} elseif($opposecount == 0) {
$opposeCrewType = GameUnitConst::byId(GameUnitConst::T_CASTLE);
$josaRo = JosaUtil::pick($generalCrewType->name, '로');
$josaYi = JosaUtil::pick($general['name'], '이');
$alllog[] = "<C>●</>{$month}월:<Y>{$general['name']}</>{$josaYi} {$generalCrewType->name}{$josaRo} 성벽을 공격합니다.";
$log[] = "<C>●</>{$generalCrewType->name}{$josaRo} 성벽을 <M>공격</>합니다.";
$general['train'] += 1; //훈련 상승
if($general['train'] > GameConst::$maxTrainByWar) { $general['train'] = GameConst::$maxTrainByWar; }
$query = "update general set recwar='{$general['turntime']}',train='{$general['train']}',warnum=warnum+1 where no='{$general['no']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$mykillnum = 0; $mydeathnum = 0;
while($phase < $warphase) {
$phase++;
$myAtt = $generalCrewType->getComputedAttack($general, $nation['tech']);
$myDef = $generalCrewType->getComputedDefence($general, $nation['tech']);
$cityAtt = $opposeCrewType->getComputedAttack($city, $destnation['tech']);
$cityDef = $opposeCrewType->getComputedDefence($city, $destnation['tech']);
// 감소할 병사 수
$cityCrew = GameConst::$armperphase + $myAtt - $cityDef;
$myCrew = GameConst::$armperphase + $cityAtt - $myDef;
if($cityCrew <= 0) { $cityCrew = rand() % 90 + 10; }
if($myCrew <= 0) { $myCrew = rand() % 90 + 10; }
//훈련 사기따라
$myCrew = getCrew($myCrew, $admin['city_rate']+$oppAtmosBonus, CharTrain($general['train']+$genTrain+$genTrainBonus, $general['personal']));
$cityCrew = getCrew($cityCrew, CharAtmos($general['atmos']+$genAtmos+$genAtmosBonus, $general['personal']), $admin['city_rate']+$oppTrainBonus);
//숙련도 따라
$genDexAtt = getGenDex($general, $general['crewtype']);
$genDexDef = getGenDex($general, GameUnitConst::T_CASTLE);
$cityCrew *= getDexLog($genDexAtt, ($admin['city_rate']-60)*7200);
$myCrew *= getDexLog(($admin['city_rate']-60)*7200, $genDexDef);
$cityCrew *= $generalCrewType->getAttackCoef($opposeCrewType);
$myCrew *= $generalCrewType->getDefenceCoef($opposeCrewType);
$avoid = 1;
// 병종간 특성
if($generalCrewType->magicCoef) {
$int = Util::round(getGeneralIntel($general, true, true, true, false));
$ratio2 = $int / 100 * $generalCrewType->magicCoef;
// 특기보정 : 신산
if($general['special2'] == 41) { $ratio2 += 0.2; }
if(Util::randBool($ratio2)) {
$ratio = rand() % 100; // 0~99
// 특기보정 : 귀병, 신산, 환술, 신중
if($general['special2'] == 40) { $ratio += 20; }
if($general['special2'] == 41) { $ratio += 20; }
if($general['special2'] == 42) { $ratio += 10; }
if($general['special2'] == 44) { $ratio += 100; }
if($ratio >= 30) {
// 특기보정 : 환술, 집중
if($general['special2'] == 42) { $cityCrew *= 1.3; }
if($general['special2'] == 43) { $cityCrew *= 1.5; }
$type = rand() % 3;
switch($type) {
case 0:
$batlog[] = "<C>●</><D>급습</>을 <C>성공</>했다!";
$cityCrew *= 1.2;
break;
case 1:
$batlog[] = "<C>●</><D>위보</>를 <C>성공</>했다!";
$cityCrew *= 1.4;
break;
case 2:
$batlog[] = "<C>●</><D>혼란</>을 <C>성공</>했다!";
$cityCrew *= 1.6;
break;
}
} else {
$type = rand() % 3;
switch($type) {
case 0:
$batlog[] = "<C>●</><D>급습</>을 <R>실패</>했다!";
$cityCrew /= 1.2; $myCrew *= 1.2;
break;
case 1:
$batlog[] = "<C>●</><D>위보</>를 <R>실패</>했다!";
$cityCrew /= 1.4; $myCrew *= 1.4;
break;
case 2:
$batlog[] = "<C>●</><D>혼란</>을 <R>실패</>했다!";
$cityCrew /= 1.6; $myCrew *= 1.6;
break;
}
}
}
}
//군주 공격 보정 10%
if($general['level'] == 12) {
$cityCrew = $cityCrew * 1.10;
//참모, 장군 공격 보정 5%
} elseif($general['level'] == 11 || $general['level'] == 10 || $general['level'] == 8 || $general['level'] == 6) {
$cityCrew = $cityCrew * 1.05;
}
//레벨 보정
$cityCrew = $cityCrew * (100 + $general['explevel']/6)/100;
// 특기보정 : 공성, 기병, 돌격, 무쌍, 보병, 견고, 의술(청낭서,태평청령)
if($general['special2'] == 53) { $cityCrew *= 2.00; }
if($general['special2'] == 52) { $cityCrew *= 1.20; }
if($general['special2'] == 60) { $cityCrew *= 1.10; }
if($general['special2'] == 61) { $cityCrew *= 1.10; }
if($general['special2'] == 50) { $myCrew *= 0.90; }
if($general['special2'] == 62) { $myCrew *= 0.90; }
$ratio = rand() % 100; // 0 ~ 99
if(($general['special2'] == 73 || $general['item'] == 23 || $general['item'] == 24) && $ratio > 80 && $avoid == 1) {
$batlog[] = "<C>●</><C>치료</>했다!</>";
$myCrew /= 1.5; // 66%만 소모
$avoid = 0;
}
//크리
$rd = rand() % 100; // 0 ~ 99
$ratio = $generalCrewType->getCriticalRatio($general);
// 특기보정 : 무쌍, 필살
if($general['special2'] == 61) { $ratio += 10; }
if($general['special2'] == 71) { $ratio += 20; }
if($ratio >= $rd && $avoid == 1) {
$batlog[] = "<C>●</><C>필살</>공격!</>";
$cityCrew = CriticalScore2($cityCrew);
$avoid = 0;
}
//회피
$ratio = rand() % 100; // 0 ~ 99
$ratio2 = $generalCrewType->avoid; //회피율
$ratio2 = Util::round($ratio2 * $general['train'] / 100); //훈련 반영
//특기보정 : 궁병
if($general['special2'] == 51) { $ratio2 += 20; }
//도구 보정 : 둔갑천서, 태평요술
if($general['item'] == 26 || $general['item'] == 25) { $ratio2 += 20; }
LogText('avoid0', [date("Ymd_His"), $generalCrewType->id, $general['train'], $ratio2]);
if($ratio < $ratio2 && $avoid == 1) {
LogText('avoid0', true);
$batlog[] = "<C>●</><C>회피</>했다!</>";
$myCrew /= 5; // 20%만 소모
$avoid = 0;
}
//랜타추가
$cityCrew *= (rand() % 21 + 90)/100; // 90~110%
$myCrew *= (rand() % 21 + 90)/100; // 90~110%
//특기보정 : 위압
if($general['special2'] == 63 && $phase == 1 && $general['crew'] >= 1000 && $general['atmos'] >= 90 && $general['train'] >= 90) {
$batlog[] = "<C>●</>상대에게 <C>위압</>을 줬다!</>";
$myCrew = 0;
}
$general['crew'] -= Util::round($myCrew);
$city['def'] -= Util::round($cityCrew);
$city['wall'] -= Util::round($cityCrew);
$tempMyCrew = $myCrew; $tempCityCrew = $cityCrew;
$tempGeneralCrew = $general['crew']; $tempCityDef = $city['def'];
if($city['wall'] <= 0) { $city['wall'] = 0; }
if($general['crew'] <= 0 && $city['def'] <= 0) {
$r1 = $tempGeneralCrew / $tempMyCrew;
$r2 = $tempCityDef / $tempCityCrew;
if($r1 > $r2) {
$offset = Util::round($tempCityDef*$tempMyCrew/$tempCityCrew);
$myCrew += $offset;
$general['crew'] -= $offset;
$cityCrew += $tempCityDef;
$city['def'] = 0;
} else {
$offset = Util::round($tempGeneralCrew*$tempCityCrew/$tempMyCrew);
$cityCrew += $offset;
$city['def'] -= $offset;
$myCrew += $tempGeneralCrew;
$general['crew'] = 0;
}
} elseif($general['crew'] * $city['def'] <= 0) {
if($city['def'] < 0) {
$offset = Util::round($tempCityDef*$tempMyCrew/$tempCityCrew);
$myCrew += $offset;
$general['crew'] -= $offset;
$cityCrew += $tempCityDef;
$city['def'] = 0;
}
if($general['crew'] < 0) {
$offset = Util::round($tempGeneralCrew*$tempCityCrew/$tempMyCrew);
$cityCrew += $offset;
$city['def'] -= $offset;
$myCrew += $tempGeneralCrew;
$general['crew'] = 0;
}
}
$exp += $cityCrew;
$opexp += $myCrew;
$general['crew'] = Util::round($general['crew']);
$cityCrew = Util::round($cityCrew);
$myCrew = Util::round($myCrew);
$batlog[] = "<C>●</> $phase : <Y1>【{$general['name']}】</> <C>{$general['crew']} (-$myCrew)</> VS <C>{$city['def']} (-$cityCrew)</> <Y1>【{$city['name']}】</>";
$mykillnum += $cityCrew; $mydeathnum += $myCrew;
// 중간 쌀 체크
$myRice = Util::round($exp / 50);
// 성격 보정
$myRice = CharExperience($myRice, $general['personal']);
// 쌀 소모
$myRice = ($myRice * 5 * getCrewtypeRice($generalCrewType, $nation['tech']));
// 결과 쌀
$myRice = $general['rice'] - $myRice;
if($myRice <= Util::round($general['crew']/100)) { break; }
if($city['def'] <= 0) { break; }
if($general['crew'] <= 0) { break; }
}
$render_attacker = [
'crewtype' => mb_substr($generalCrewType->name, 0, 2),
'name'=> $general['name'],
'remain_crew' => $general['crew'],
'killed_crew' => -$mydeathnum
];
$render_defender = [
'crewtype' => '성벽',
'name'=> $city['name'],
'remain_crew' => $city['def'],
'killed_crew' => -$mykillnum
];
$res = str_replace(["\r\n", "\r", "\n"], '', $templates->render('small_war_log',[
'year'=>$year,
'month'=>$month,
'war_type'=>'siege',
'war_type_str'=>'→',
'me' => $render_attacker,
'you' => $render_defender,
]));
$log[] = $res;//TODO: $log를 출력할 때 date에 대해선 숨겨야 함.
$batlog[] = $res;
$batres[] = $res;
$deadAmount['att'] = $deadAmount['att'] + $mydeathnum;
$deadAmount['def'] = $deadAmount['def'] + $mykillnum;
// 도시쌀 소모 계산
$opexp = Util::round($opexp / 50 * 0.8);
$rice = Util::round($opexp * 5 * getCrewtypeRice($opposeCrewType, 0) * ($admin['city_rate']/100 - 0.2));
$destnation['rice'] -= $rice;
if($destnation['rice'] < 0) { $destnation['rice'] = 0; }
$query = "update nation set rice='{$destnation['rice']}' where nation='{$destnation['nation']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
pushAdminLog(["성벽 쌀 소모 : $rice"]);
//원래대로 스케일링
$city['def'] = Util::round($city['def'] / 10);
$city['wall'] = Util::round($city['wall'] / 10);
//내정 감소
$dec = Util::round($cityCrew / 10);
$city['agri'] -= $dec;
$city['comm'] -= $dec;
$city['secu'] -= $dec;
if($city['agri'] < 0) { $city['agri'] = 0; }
if($city['comm'] < 0) { $city['comm'] = 0; }
if($city['secu'] < 0) { $city['secu'] = 0; }
// 병사수 변경
$query = "update general set crew='{$general['crew']}',killcrew=killcrew+'$mykillnum',deathcrew=deathcrew+'$mydeathnum' where no='{$general['no']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
// 숙련도 증가
addGenDex($general['no'], $general['atmos'], $general['train'], $general['crewtype'], $mykillnum);
addGenDex($general['no'], $general['atmos'], $general['train'], GameUnitConstBase::T_CASTLE, $mydeathnum);
// 죽은수 기술로 누적
$num = Util::round($mydeathnum * 0.01);
// 국가보정
if($nation['type'] == 3 || $nation['type'] == 13) { $num *= 1.1; }
if($nation['type'] == 5 || $nation['type'] == 6 || $nation['type'] == 7 || $nation['type'] == 8 || $nation['type'] == 12) { $num *= 0.9; }
// 부드러운 기술 제한
if(TechLimit($admin['startyear'], $year, $nation['tech'])) { $num = intdiv($num, 4); }
$query = "update nation set totaltech=totaltech+'$num',tech=totaltech/'$gencount' where nation='{$nation['nation']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
// 죽은수 기술로 누적
$num = Util::round($mykillnum * 0.01);
// 국가보정
if($destnation['type'] == 3 || $destnation['type'] == 13){
$num *= 1.1;
}
if($destnation['type'] == 5 || $destnation['type'] == 6 || $destnation['type'] == 7 || $destnation['type'] == 8 || $destnation['type'] == 12) {
$num *= 0.9;
}
// 부드러운 기술 제한
if(TechLimit($admin['startyear'], $year, $destnation['tech'])) { $num = intdiv($num, 4); }
$query = "update nation set totaltech=totaltech+'$num',tech=totaltech/'$destgencount' where nation='{$destnation['nation']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
//양국 평균 기술가격
//$techRatio = (getTechCost($nation['tech']) + getTechCost($destnation['tech'])) / 2;
$techRatio = 1.0;
// 죽은수 도시 재정으로 누적 60%
$num = Util::round(($mykillnum+$mydeathnum) * 0.6 * $techRatio);
// 국가보정
if($destnation['type'] == 1) { $num *= 1.1; }
if($destnation['type'] == 9 || $destnation['type'] == 10) { $num *= 0.9; }
$query = "update city set dead=dead+'$num',def='{$city['def']}',wall='{$city['wall']}',agri='{$city['agri']}',comm='{$city['comm']}',secu='{$city['secu']}' where city='{$city['city']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
// 죽은수 도시 재정으로 누적 40%
$num = Util::round(($mykillnum+$mydeathnum) * 0.4 * $techRatio);
// 국가보정
if($nation['type'] == 1) { $num *= 1.1; }
if($nation['type'] == 9 || $nation['type'] == 10) { $num *= 0.9; }
$query = "update city set dead=dead+'$num' where city='{$general['city']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
//분쟁현황에 추가
$city = addConflict($city, $general['nation'], $mykillnum);
// 병사 소진시 성 함락
if($city['def'] <= 0) {
$exp += 1000;
$exp2++;
pushGenLog($general, $log);
pushBatLog($general, $batlog);
pushBatRes($general, $batres);
pushGeneralPublicRecord($alllog, $year, $month);
pushWorldHistory($history, $year, $month);
$log = [];
$batlog = [];
$batres = [];
$alllog = [];
$history = [];
ConquerCity($admin, $general, $city, $nation, $destnation);
break;
// 공격 장수 병사 소진시 실패 처리
} elseif($general['crew'] <= 0) {
$josaYi = JosaUtil::pick($generalCrewType->name, '이');
$alllog[] = "<C>●</>{$month}월:<Y>{$general['name']}</>의 {$generalCrewType->name}{$josaYi} 퇴각했습니다.";
$log[] = "<C>●</>퇴각했습니다.";
$query = "update general set deathnum=deathnum+1 where no='{$general['no']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
break;
} elseif($myRice <= Util::round($general['crew']/100)) {
$josaYi = JosaUtil::pick($generalCrewType->name, '이');
$alllog[] = "<C>●</>{$month}월:<Y>{$general['name']}</>의 {$generalCrewType->name}{$josaYi} 퇴각했습니다.";
$log[] = "<C>●</>군량 부족으로 퇴각합니다.";
$query = "update general set deathnum=deathnum+1 where no='{$general['no']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
break;
}
// 장수 대결
} else {
$oppose = MYDB_fetch_array($result);
setLeadershipBonus($oppose, $destnation['level']);
$opposeCrewType = GameUnitConst::byId($oppose['crewtype']);
$josaYi = JosaUtil::pick($opposeCrewType->name, '이');
$josaWa = JosaUtil::pick($generalCrewType->name, '와');
$alllog[] = "<C>●</>{$month}월:<Y>{$general['name']}</>의 ".$generalCrewType->name."{$josaWa} <Y>{$oppose['name']}</>의 ".$opposeCrewType->name."{$josaYi} 대결합니다.";
$josaUl = JosaUtil::pick($opposeCrewType->name, '을');
$josaRo = JosaUtil::pick($generalCrewType->name, '로');
$log[] = "<C>●</>".$generalCrewType->name."{$josaRo} <Y>{$oppose['name']}</>의 ".$opposeCrewType->name."{$josaUl} <M>공격</>합니다.";
$josaUl = JosaUtil::pick($generalCrewType->name, '을');
$opplog[] = "<C>●</>".$opposeCrewType->name."{$josaRo} <Y>{$general['name']}</>의 ".$generalCrewType->name."{$josaUl} <M>수비</>합니다.";
$oppAtmos = 0;
if($oppose['item'] == 3) {
//탁주 사용
$oppAtmos += 3;
$query = "update general set item=0 where no='{$oppose['no']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$josaUl = JosaUtil::pick($oppose['item'], '을');
$opplog[] = "<C>●</><C>".getItemName($oppose['item'])."</>{$josaUl} 사용!";
$oppose['item'] = 0;
} elseif($oppose['item'] >= 14 && $oppose['item'] <= 16) {
//의적주, 두강주, 보령압주 사용
$oppAtmos += 5;
} elseif($oppose['item'] >= 19 && $oppose['item'] <= 20) {
//춘화첩, 초선화 사용
$oppAtmos += 7;
}
$oppTrain = 0;
if($oppose['item'] == 4) {
//청주 사용
$oppTrain += 3;
$query = "update general set item=0 where no='{$oppose['no']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$josaUl = JosaUtil::pick($oppose['item'], '을');
$opplog[] = "<C>●</><C>".getItemName($oppose['item'])."</>{$josaUl} 사용!";
$oppose['item'] = 0;
} elseif($oppose['item'] >= 12 && $oppose['item'] <= 13) {
//과실주, 이강주 사용
$oppTrain += 5;
} elseif($oppose['item'] >= 17 && $oppose['item'] <= 18) {
//철벽서, 단결도 사용
$oppTrain += 7;
}
$general['train'] += 1; //훈련 상승
if($general['train'] > GameConst::$maxTrainByWar) { $general['train'] = GameConst::$maxTrainByWar; }
$oppose['train'] += 1; //훈련 상승
if($oppose['train'] > GameConst::$maxTrainByWar) { $oppose['train'] = GameConst::$maxTrainByWar; }
$query = "update general set recwar='{$general['turntime']}',train='{$general['train']}',warnum=warnum+1 where no='{$general['no']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$query = "update general set recwar='{$general['turntime']}',train='{$oppose['train']}',warnum=warnum+1 where no='{$oppose['no']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
//특기보정 : 저격(수극), 활무기저격
$snipe = false;
$snipeItem = false;
if(!$snipe && $general['special2'] == 70 && Util::randBool(1/3)){
$snipe = true;
}
if(!$snipe && in_array($general['weap'], [10, 14, 18, 22]) && Util::randBool(1/5)){
$snipe = true;
}
if(!$snipe && $general['item'] == 2){
if(Util::randBool(1/5)){
$snipe = true;
$snipeItem = true;
}
//수극을 사용했지만 저격 실패한 케이스도 '필요하면' 넣을 것.(밸런스)
}
if($snipe) {
//수극 사용
if($snipeItem) {
$josaUl = JosaUtil::pick($general['item'], '을');
$log[] = "<C>●</><C>".getItemName($general['item'])."</>{$josaUl} 사용!";
$general['item'] = 0;
$db->update('general', ['item'=>0], 'no=%i', $general['no']);
}
$log[] = "<C>●</>상대를 <C>저격</>했다!";
$batlog[] = "<C>●</>상대를 <C>저격</>했다!";
$opplog[] = "<C>●</>상대에게 <R>저격</>당했다!";
$oppbatlog[] = "<C>●</>상대에게 <R>저격</>당했다!";
// 부상
$oppose['injury'] += rand() % 41 + 20; // 20 ~ 60
if($oppose['injury'] > 80) { $oppose['injury'] = 80; }
}
else if($snipeItem) {
$db->update('general', ['item'=>0], 'no=%i', $general['no']);
$josaYi = JosaUtil::pick($general['item'], '이');
$batlog[] = "<C>●</><C>".getItemName($general['item'])."</>{$josaYi} 빗나갑니다!";
$general['item'] = 0;
}
//특기보정 : 저격(수극), 활무기저격
$snipe = false;
$snipeItem = false;
if(!$snipe && $oppose['special2'] == 70 && Util::randBool(1/3)){
$snipe = true;
}
if(!$snipe && in_array($oppose['weap'], [10, 14, 18, 22]) && Util::randBool(1/5)){
$snipe = true;
}
if(!$snipe && $oppose['item'] == 2){
if(Util::randBool(1/5)){
$snipe = true;
$snipeItem = true;
}
//수극을 사용했지만 저격 실패한 케이스도 '필요하면' 넣을 것.(밸런스)
}
if($snipe) {
//수극 사용
if($snipeItem) {
$josaUl = JosaUtil::pick($oppose['item'], '을');
$opplog[] = "<C>●</><C>".getItemName($oppose['item'])."</>{$josaUl} 사용!";
$oppose['item'] = 0;
$db->update('general', ['item'=>0], 'no=%i', $oppose['no']);
}
$oppbatlog[] = "<C>●</>상대를 <C>저격</>했다!";
$opplog[] = "<C>●</>상대를 <C>저격</>했다!";
$batlog[] = "<C>●</>상대에게 <R>저격</>당했다!";
$log[] = "<C>●</>상대에게 <R>저격</>당했다!";
// 부상
$general['injury'] += rand() % 41 + 20; // 20 ~ 60
if($general['injury'] > 80) { $general['injury'] = 80; }
}
else if($snipeItem) {
$db->update('general', ['item'=>0], 'no=%i', $oppose['no']);
$josaYi = JosaUtil::pick($oppose['item'], '이');
$oppbatlog[] = "<C>●</><C>".getItemName($oppose['item'])."</>{$josaYi} 빗나갑니다!";
$oppose['item'] = 0;
}
$mykillnum = 0; $mydeathnum = 0;
$opkillnum = 0; $opdeathnum = 0;
while($phase < $warphase) {
$phase++;
$myAtt = $generalCrewType->getComputedAttack($general, $nation['tech']);
$myDef = $generalCrewType->getComputedDefence($general, $nation['tech']);
$opAtt = $opposeCrewType->getComputedAttack($oppose, $destnation['tech']);
$opDef = $opposeCrewType->getComputedDefence($oppose, $destnation['tech']);
// 감소할 병사 수
$myCrew = GameConst::$armperphase + $opAtt - $myDef;
$opCrew = GameConst::$armperphase + $myAtt - $opDef;
if($myCrew <= 0) { $myCrew = rand() % 90 + 10; }
if($opCrew <= 0) { $opCrew = rand() % 90 + 10; }
//훈련 사기따라
$myCrew = getCrew($myCrew, CharAtmos($oppose['atmos']+$oppAtmos+$oppAtmosBonus, $oppose['personal']), CharTrain($general['train']+$genTrain+$genTrainBonus, $general['personal']));
$opCrew = getCrew($opCrew, CharAtmos($general['atmos']+$genAtmos+$genAtmosBonus, $general['personal']), CharTrain($oppose['train']+$oppTrain+$oppTrainBonus, $oppose['personal']));
//숙련도 따라
$genDexAtt = getGenDex($general, $general['crewtype']);
$genDexDef = getGenDex($general, $oppose['crewtype']);
$oppDexAtt = getGenDex($oppose, $oppose['crewtype']);
$oppDexDef = getGenDex($oppose, $general['crewtype']);
$opCrew *= getDexLog($genDexAtt, $oppDexDef);
$myCrew *= getDexLog($oppDexAtt, $genDexDef);
$myAvoid = 1;
$opAvoid = 1;
// 병종간 특성
if($generalCrewType->magicCoef) {
$int = Util::round(getGeneralIntel($general, true, true, true, false));
$ratio2 = $int / 100 * $generalCrewType->magicCoef;
// 특기보정 : 신산
if($general['special2'] == 41) { $ratio2 += 0.2; }
if(Util::randBool($ratio2)) {
$ratio = rand() % 100;
// 특기보정 : 귀병, 신산, 환술, 신중
if($general['special2'] == 40) { $ratio += 20; }
if($general['special2'] == 41) { $ratio += 20; }
if($general['special2'] == 42) { $ratio += 10; }
if($general['special2'] == 44) { $ratio += 100; }
if($ratio >= 30) {
// 특기보정 : 환술, 집중
if($general['special2'] == 42) { $opCrew *= 1.3; }
if($general['special2'] == 43) { $opCrew *= 1.5; }
$type = rand() % 5; // 0~4
switch($type) {
case 0:
$ratio = rand() % 100;
// 특기보정 : 반계
if($oppose['special2'] == 45 && $ratio > 70) {
$batlog[] = "<C>●</><D>위보</>를 <R>역으로</> 당했다!";
$oppbatlog[] = "<C>●</><C>반계</>로 상대의 <D>위보</>를 되돌렸다!";
$myCrew *= 1.2;
} else {
$batlog[] = "<C>●</><D>위보</>를 <C>성공</>했다!";
$oppbatlog[] = "<C>●</><D>위보</>에 당했다!";
$opCrew *= 1.2;
}
break;
case 1:
$ratio = rand() % 100;
// 특기보정 : 반계
if($oppose['special2'] == 45 && $ratio > 70) {
$batlog[] = "<C>●</><D>매복</>을 <R>역으로</> 당했다!";
$oppbatlog[] = "<C>●</><C>반계</>로 상대의 <D>매복</>을 되돌렸다!";
$myCrew *= 1.4;
} else {
$batlog[] = "<C>●</><D>매복</>을 <C>성공</>했다!";
$oppbatlog[] = "<C>●</><D>매복</>에 당했다!";
$opCrew *= 1.4;
}
break;
case 2:
$ratio = rand() % 100;
// 특기보정 : 반계
if($oppose['special2'] == 45 && $ratio > 70) {
$batlog[] = "<C>●</><D>반목</>을 <R>역으로</> 당했다!";
$oppbatlog[] = "<C>●</><C>반계</>로 상대의 <D>반목</>을 되돌렸다!";
$myCrew *= 1.6;
} else {
$batlog[] = "<C>●</><D>반목</>을 <C>성공</>했다!";
$oppbatlog[] = "<C>●</><D>반목</>에 당했다!";
$opCrew *= 1.6;
// 특기보정 : 반계
if($general['special2'] == 45) { $opCrew *= 2; }
}
break;
case 3:
$ratio = rand() % 100;
// 특기보정 : 반계
if($oppose['special2'] == 45 && $ratio > 70) {
$batlog[] = "<C>●</><D>화계</>를 <R>역으로</> 당했다!";
$oppbatlog[] = "<C>●</><C>반계</>로 상대의 <D>화계</>를 되돌렸다!";
$myCrew *= 1.8;
} else {
$batlog[] = "<C>●</><D>화계</>를 <C>성공</>했다!";
$oppbatlog[] = "<C>●</><D>화계</>에 당했다!";
$opCrew *= 1.8;
}
break;
case 4:
$ratio = rand() % 100;
// 특기보정 : 반계
if($oppose['special2'] == 45 && $ratio > 70) {
$batlog[] = "<C>●</><D>혼란</>을 <R>역으로</> 당했다!";
$oppbatlog[] = "<C>●</><C>반계</>로 상대의 <D>혼란</>을 되돌렸다!";
$myCrew *= 2.0;
} else {
$batlog[] = "<C>●</><D>혼란</>을 <C>성공</>했다!";
$oppbatlog[] = "<C>●</><D>혼란</>에 당했다!";
$opCrew *= 2.0;
}
break;
}
} else {
$type = rand() % 5; // 0~4
switch($type) {
case 0:
$batlog[] = "<C>●</><D>위보</>를 <R>실패</>했다!";
$oppbatlog[] = "<C>●</><D>위보</>를 간파했다!";
$opCrew /= 1.1; $myCrew *= 1.1;
break;
case 1:
$batlog[] = "<C>●</><D>매복</>을 <R>실패</>했다!";
$oppbatlog[] = "<C>●</><D>매복</>을 간파했다!";
$opCrew /= 1.2; $myCrew *= 1.2;
break;
case 2:
$batlog[] = "<C>●</><D>반목</>을 <R>실패</>했다!";
$oppbatlog[] = "<C>●</><D>반목</>을 간파했다!";
$opCrew /= 1.3; $myCrew *= 1.3;
break;
case 3:
$batlog[] = "<C>●</><D>화계</>를 <R>실패</>했다!";
$oppbatlog[] = "<C>●</><D>화계</>를 간파했다!";
$opCrew /= 1.4; $myCrew *= 1.4;
break;
case 4:
$batlog[] = "<C>●</><D>혼란</>을 <R>실패</>했다!";
$oppbatlog[] = "<C>●</><D>혼란</>을 간파했다!";
$opCrew /= 1.5; $myCrew *= 1.5;
break;
}
}
}
}
// 상대 장수 병종간 특성
if($opposeCrewType->magicCoef) {
$int = Util::round(getGeneralIntel($oppose, true, true, true, false));
$ratio2 = $int / 100 * $opposeCrewType->magicCoef;
// 특기보정 : 신산
if($oppose['special2'] == 41) { $ratio2 += 0.2; }
if(Util::randBool($ratio2)) {
$ratio = rand() % 100;
// 특기보정 : 귀병, 신산, 환술, 신중
if($oppose['special2'] == 40) { $ratio += 20; }
if($oppose['special2'] == 41) { $ratio += 20; }
if($oppose['special2'] == 42) { $ratio += 10; }
if($oppose['special2'] == 44) { $ratio += 100; }
if($ratio >= 30) {
// 특기보정 : 환술, 집중
if($oppose['special2'] == 42) { $myCrew *= 1.3; }
if($oppose['special2'] == 43) { $myCrew *= 1.5; }
$type = rand() % 5; // 0~4
switch($type) {
case 0:
$ratio = rand() % 100;
// 특기보정 : 반계
if($general['special2'] == 45 && $ratio > 70) {
$oppbatlog[] = "<C>●</><D>위보</>를 <R>역으로</> 당했다!";
$batlog[] = "<C>●</><C>반계</>로 상대의 <D>위보</>를 되돌렸다!";
$opCrew *= 1.2;
} else {
$oppbatlog[] = "<C>●</><D>위보</>를 <C>성공</>했다!";
$batlog[] = "<C>●</><D>위보</>에 당했다!";
$myCrew *= 1.2;
}
break;
case 1:
$ratio = rand() % 100;
// 특기보정 : 반계
if($general['special2'] == 45 && $ratio > 70) {
$oppbatlog[] = "<C>●</><D>매복</>을 <R>역으로</> 당했다!";
$batlog[] = "<C>●</><C>반계</>로 상대의 <D>매복</>을 되돌렸다!";
$opCrew *= 1.4;
} else {
$oppbatlog[] = "<C>●</><D>매복</>을 <C>성공</>했다!";
$batlog[] = "<C>●</><D>매복</>에 당했다!";
$myCrew *= 1.4;
}
break;
case 2:
$ratio = rand() % 100;
// 특기보정 : 반계
if($general['special2'] == 45 && $ratio > 70) {
$oppbatlog[] = "<C>●</><D>반목</>을 <R>역으로</> 당했다!";
$batlog[] = "<C>●</><C>반계</>로 상대의 <D>반목</>을 되돌렸다!";
$opCrew *= 1.6;
} else {
$oppbatlog[] = "<C>●</><D>반목</>을 <C>성공</>했다!";
$batlog[] = "<C>●</><D>반목</>에 당했다!";
$myCrew *= 1.6;
// 특기보정 : 반계
if($oppose['special2'] == 45) { $myCrew *= 2; }
}
break;
case 3:
$ratio = rand() % 100;
// 특기보정 : 반계
if($general['special2'] == 45 && $ratio > 70) {
$oppbatlog[] = "<C>●</><D>화계</>를 <R>역으로</> 당했다!";
$batlog[] = "<C>●</><C>반계</>로 상대의 <D>화계</>을 되돌렸다!";
$opCrew *= 1.8;
} else {
$oppbatlog[] = "<C>●</><D>화계</>를 <C>성공</>했다!";
$batlog[] = "<C>●</><D>화계</>에 당했다!";
$myCrew *= 1.8;
}
break;
case 4:
$ratio = rand() % 100;
// 특기보정 : 반계
if($general['special2'] == 45 && $ratio > 70) {
$oppbatlog[] = "<C>●</><D>혼란</>을 <R>역으로</> 당했다!";
$batlog[] = "<C>●</><C>반계</>로 상대의 <D>혼란</>을 되돌렸다!";
$opCrew *= 2.0;
} else {
$oppbatlog[] = "<C>●</><D>혼란</>을 <C>성공</>했다!";
$batlog[] = "<C>●</><D>혼란</>에 당했다!";
$myCrew *= 2.0;
}
break;
}
} else {
$type = rand() % 5; // 0~4
switch($type) {
case 0:
$oppbatlog[] = "<C>●</><D>위보</>를 <R>실패</>했다!";
$batlog[] = "<C>●</><D>위보</>를 간파했다!";
$myCrew /= 1.1; $opCrew *= 1.1;
break;
case 1:
$oppbatlog[] = "<C>●</><D>매복</>을 <R>실패</>했다!";
$batlog[] = "<C>●</><D>매복</>을 간파했다!";
$myCrew /= 1.2; $opCrew *= 1.2;
break;
case 2:
$oppbatlog[] = "<C>●</><D>반목</>을 <R>실패</>했다!";
$batlog[] = "<C>●</><D>반목</>을 간파했다!";
$myCrew /= 1.3; $opCrew *= 1.3;
break;
case 3:
$oppbatlog[] = "<C>●</><D>화계</>를 <R>실패</>했다!";
$batlog[] = "<C>●</><D>화계</>를 간파했다!";
$myCrew /= 1.4; $opCrew *= 1.4;
break;
case 4:
$oppbatlog[] = "<C>●</><D>혼란</>을 <R>실패</>했다!";
$batlog[] = "<C>●</><D>혼란</>을 간파했다!";
$myCrew /= 1.5; $opCrew *= 1.5;
break;
}
}
}
}
// 특기보정: 돌격
//XXX: 목우!!!!
if($oppose['crewtype'] == 43 && $general['special2'] != 60) { // 목우
$r = 0;
$r += $oppose['atmos'] + $oppAtmos + $oppAtmosBonus;
$r += $oppose['train'] + $oppTrain + $oppTrainBonus;
$ratio = rand() % 400; // 최대 50% 저지
if($ratio < $r && $opAvoid == 1) {
$batlog[] = "<C>●</><R>저지</>당했다!</>";
$oppbatlog[] = "<C>●</>상대를 <C>저지</>했다!</>";
$opAvoid = 0;
continue;
}
}
$opCrew *= $generalCrewType->getAttackCoef($opposeCrewType);
$myCrew *= $generalCrewType->getDefenceCoef($opposeCrewType);
//군주 공격 보정 10%
if($general['level'] == 12) {
$opCrew = $opCrew * 1.10;
//참모, 장군 공격 보정 5%
} elseif($general['level'] == 11 || $general['level'] == 10 || $general['level'] == 8 || $general['level'] == 6) {
$opCrew = $opCrew * 1.05;
}
//상대장수 관직 보정
//군주 방어 보정 10%
if($oppose['level'] == 12) {
$opCrew = $opCrew * 0.90;
//참모, 모사 방어 보정 5%
} elseif($oppose['level'] == 11 || $oppose['level'] == 9 || $oppose['level'] == 7 || $oppose['level'] == 5) {
$opCrew = $opCrew * 0.95;
} elseif($oppose['level'] == 4 && $oppose['no'] == $city['gen1']) { // 태수 보정
$opCrew = $opCrew * 0.95;
} elseif($oppose['level'] == 3 && $oppose['no'] == $city['gen2']) { // 군사 보정
$opCrew = $opCrew * 0.95;
} elseif($oppose['level'] == 2 && $oppose['no'] == $city['gen3']) { // 시중 보정
$opCrew = $opCrew * 0.95;
}
//레벨 보정
$myCrew = $myCrew * (max(1, 100 - $general['explevel']/3)/100);
$opCrew = $opCrew / (max(1, 100 - $general['explevel']/3)/100);
$myCrew = $myCrew / (max(1, 100 - $oppose['explevel']/3)/100);
$opCrew = $opCrew * (max(1, 100 - $oppose['explevel']/3)/100);
// 특기보정 : 기병, 돌격, 무쌍, 보병, 견고, 척사, 의술(청낭서, 태평청령)
if($general['special2'] == 52) { $opCrew *= 1.20; }
if($general['special2'] == 60) { $opCrew *= 1.10; }
if($general['special2'] == 61) { $opCrew *= 1.10; }
if($general['special2'] == 50) { $myCrew *= 0.90; }
if($general['special2'] == 62) { $myCrew *= 0.90; }
if($general['special2'] == 75) {
if($opposeCrewType->reqCities || $opposeCrewType->reqRegions)
{
$opCrew *= 1.1; $myCrew *= 0.9;
}
}
$ratio = rand() % 100; // 0 ~ 99
if(($general['special2'] == 73 || $general['item'] == 23 || $general['item'] == 24) && $ratio > 80 && $myAvoid == 1) {
$batlog[] = "<C>●</><C>치료</>했다!</>";
$myCrew /= 1.5; // 66%만 소모
$myAvoid = 0;
}
// 상대 특기보정 : 기병, 무쌍, 보병, 견고, 척사, 의술(청낭서, 태평청령)
if($oppose['special2'] == 52) { $myCrew *= 1.10; }
if($oppose['special2'] == 61) { $myCrew *= 1.10; }
if($oppose['special2'] == 50) { $opCrew *= 0.80; }
if($oppose['special2'] == 62) { $myCrew *= 1.10; }
if($oppose['special2'] == 75) {
if($generalCrewType->reqCities || $generalCrewType->reqRegions)
{
$myCrew *= 1.1; $opCrew *= 0.9;
}
}
$ratio = rand() % 100; // 0 ~ 99
if(($oppose['special2'] == 73 || $oppose['item'] == 23 || $oppose['item'] == 24) && $ratio > 80 && $opAvoid == 1) {
$oppbatlog[] = "<C>●</><C>치료</>했다!</>";
$opCrew /= 1.5; // 66%만 소모
$opAvoid = 0;
}
//크리
$rd = rand() % 100; // 0 ~ 99
$ratio = $generalCrewType->getCriticalRatio($general);
// 특기보정 : 무쌍, 필살
if($general['special2'] == 61) { $ratio += 10; }
if($general['special2'] == 71) { $ratio += 20; }
if($ratio >= $rd && $myAvoid == 1) {
$batlog[] = "<C>●</><C>필살</>공격!</>";
$oppbatlog[] = "<C>●</>상대의 <R>필살</>공격!</>";
$opCrew = CriticalScore2($opCrew);
$myAvoid = 0;
// 특기보정 : 격노
if($oppose['special2'] == 74) {
if(rand() % 100 < 50) {
$batlog[] = "<C>●</>필살 공격에 상대가 <R>격노</>했다!</>";
$oppbatlog[] = "<C>●</>상대의 필살 공격에 <C>격노</>했다!</>";
$myCrew = CriticalScore2($myCrew);
$opAvoid = 0;
}
}
}
//크리
$rd = rand() % 100; // 0 ~ 99
$ratio = $opposeCrewType->getCriticalRatio($oppose);
// 특기보정 : 필살
if($oppose['special2'] == 71) { $ratio += 20; }
if($ratio >= $rd && $opAvoid == 1) {
$oppbatlog[] = "<C>●</><C>필살</>공격!</>";
$batlog[] = "<C>●</>상대의 <R>필살</>공격!</>";
$myCrew = CriticalScore2($myCrew);
$opAvoid = 0;
// 특기보정 : 격노
if($general['special2'] == 74) {
if(rand() % 100 < 33) {
$oppbatlog[] = "<C>●</>필살 공격에 상대가 <R>진노</>했다!</>";
$batlog[] = "<C>●</>상대의 필살 공격에 <C>진노</>했다!</>";
$opCrew = CriticalScore2($opCrew);
$myAvoid = 0;
$warphase++;
} elseif(rand() % 100 < 33) {
$oppbatlog[] = "<C>●</>필살 공격에 상대가 <R>격노</>했다!</>";
$batlog[] = "<C>●</>상대의 필살 공격에 <C>격노</>했다!</>";
$opCrew = CriticalScore2($opCrew);
$myAvoid = 0;
}
}
}
//회피
$ratio = rand() % 100; // 0 ~ 99
$ratio2 = $generalCrewType->avoid; //회피율
$ratio2 = Util::round($ratio2 * $general['train'] / 100); //훈련 반영
//특기보정 : 돌격, 궁병
if($oppose['special2'] == 60) { $ratio2 -= 100; }
if($general['special2'] == 51) { $ratio2 += 20; }
//도구 보정 : 둔갑천서, 태평요술
if($general['item'] == 26 || $general['item'] == 25) { $ratio2 += 20; }
LogText('avoid1', [date("Ymd_His"), $generalCrewType->id, $general['train'], $ratio2]);
if($ratio < $ratio2 && $myAvoid == 1) {
// 특기보정 : 격노
if($oppose['special2'] == 74 && rand() % 100 < 50) {
$batlog[] = "<C>●</>회피 시도에 상대가 <R>격노</>했다!</>";
$oppbatlog[] = "<C>●</>상대의 회피 시도에 <C>격노</>했다!</>";
$myCrew = CriticalScore2($myCrew);
$opAvoid = 0;
} else {
LogText('avoid1', true);
$batlog[] = "<C>●</><C>회피</>했다!</>";
$oppbatlog[] = "<C>●</>상대가 <R>회피</>했다!</>";
$myCrew /= 5; // 20%만 소모
$myAvoid = 0;
}
}
//회피
$ratio = rand() % 100; // 0 ~ 99
$ratio2 = $opposeCrewType->avoid; //회피율
$ratio2 = Util::round($ratio2 * $oppose['train'] / 100); //훈련 반영
// 특기보정 : 돌격, 궁병
if($general['special2'] == 60) { $ratio2 -= 100; }
if($oppose['special2'] == 51) { $ratio2 += 20; }
//도구 보정 : 둔갑천서, 태평요술
if($oppose['item'] == 26 || $oppose['item'] == 25) { $ratio2 += 20; }
LogText('avoid2', [date("Ymd_His"), $opposeCrewType->id, $oppose['train'], $ratio2]);
if($ratio < $ratio2 && $opAvoid == 1) {
// 특기보정 : 격노
if($general['special2'] == 74 && rand() % 100 < 33) {
$oppbatlog[] = "<C>●</>회피 시도에 상대가 <R>진노</>했다!</>";
$batlog[] = "<C>●</>상대의 회피 시도에 <C>진노</>했다!</>";
$opCrew = CriticalScore2($opCrew);
$myAvoid = 0;
$warphase++;
} elseif($general['special2'] == 74 && rand() % 100 < 33) {
$oppbatlog[] = "<C>●</>회피 시도에 상대가 <R>격노</>했다!</>";
$batlog[] = "<C>●</>상대의 회피 시도에 <C>격노</>했다!</>";
$opCrew = CriticalScore2($opCrew);
$myAvoid = 0;
} else {
LogText('avoid2', true);
$oppbatlog[] = "<C>●</><C>회피</>했다!</>";
$batlog[] = "<C>●</>상대가 <R>회피</>했다!</>";
$opCrew /= 5; // 20%만 소모
$opAvoid = 0;
}
}
//랜타추가
$opCrew *= (rand() % 21 + 90)/100; // 90~110%
$myCrew *= (rand() % 21 + 90)/100; // 90~110%
//특기보정 : 위압
if($general['special2'] == 63 && $phase == 1 && $general['crew'] >= 1000 && $general['atmos'] >= 90 && $general['train'] >= 90) {
$batlog[] = "<C>●</>상대에게 <C>위압</>을 줬다!</>";
$oppbatlog[] = "<C>●</>상대에게 <R>위압</>받았다!</>";
$myCrew = 0;
}
//특기보정: 위압
if($oppose['special2'] == 63 && $phase == 1 && $oppose['crew'] >= 1000 && $oppose['atmos'] >= 90 && $oppose['train'] >= 90) {
$batlog[] = "<C>●</>상대에게 <R>위압</>받았다!</>";
$oppbatlog[] = "<C>●</>상대에게 <C>위압</>을 줬다!</>";
$opCrew = 0;
}
$general['crew'] -= Util::round($myCrew);
$oppose['crew'] -= Util::round($opCrew);
$tempMyCrew = $myCrew; $tempOpCrew = $opCrew;
$tempGeneralCrew = $general['crew']; $tempOpposeCrew = $oppose['crew'];
if($general['crew'] <= 0 && $oppose['crew'] <= 0) {
$r1 = $tempGeneralCrew / $tempMyCrew;
$r2 = $tempOpposeCrew / $tempOpCrew;
if($r1 > $r2) {
$offset = Util::round($tempOpposeCrew*$tempMyCrew/$tempOpCrew);
$myCrew += $offset;
$general['crew'] -= $offset;
$opCrew += $tempOpposeCrew;
$oppose['crew'] = 0;
} else {
$offset = Util::round($tempGeneralCrew*$tempOpCrew/$tempMyCrew);
$opCrew += $offset;
$oppose['crew'] -= $offset;
$myCrew += $tempGeneralCrew;
$general['crew'] = 0;
}
} elseif($general['crew'] * $oppose['crew'] <= 0) {
if($oppose['crew'] < 0) {
$offset = Util::round($tempOpposeCrew*$tempMyCrew/$tempOpCrew);
$myCrew += $offset;
$general['crew'] -= $offset;
$opCrew += $tempOpposeCrew;
$oppose['crew'] = 0;
}
if($general['crew'] < 0) {
$offset = Util::round($tempGeneralCrew*$tempOpCrew/$tempMyCrew);
$opCrew += $offset;
$oppose['crew'] -= $offset;
$myCrew += $tempGeneralCrew;
$general['crew'] = 0;
}
}
$exp += $opCrew;
$opexp += $myCrew;
$general['crew'] = Util::round($general['crew']);
$oppose['crew'] = Util::round($oppose['crew']);
$myCrew = Util::round($myCrew);
$opCrew = Util::round($opCrew);
$batlog[] = "<C>●</> $phase : <Y1>【{$general['name']}】</> <C>{$general['crew']} (-$myCrew)</> VS <C>{$oppose['crew']} (-$opCrew)</> <Y1>【{$oppose['name']}】</>";
$oppbatlog[] = "<C>●</> $phase : <Y1>【{$oppose['name']}】</> <C>{$oppose['crew']} (-$opCrew)</> VS <C>{$general['crew']} (-$myCrew)</> <Y1>【{$general['name']}】</>";
$mykillnum += $opCrew; $mydeathnum += $myCrew;
$opkillnum += $myCrew; $opdeathnum += $opCrew;
// 중간 쌀 체크
$myRice = Util::round($exp / 50);
// 성격 보정
$myRice = CharExperience($myRice, $general['personal']);
// 쌀 소모
$myRice = ($myRice * 5 * getCrewtypeRice($generalCrewType, $nation['tech']));
// 결과 쌀
$myRice = $general['rice'] - $myRice;
// 중간 쌀 체크
$opRice = Util::round($opexp / 50 * 0.8);
// 성격 보정
$opRice = CharExperience($opRice, $oppose['personal']);
// 쌀 소모
$opRice = ($opRice * 5 * getCrewtypeRice($opposeCrewType, $destnation['tech']));
// 결과 쌀
$opRice = $oppose['rice'] - $opRice;
if($opRice <= Util::round($oppose['crew']/100)) { break; }
if($myRice <= Util::round($general['crew']/100)) { break; }
if($oppose['crew'] <= 0) { break; }
if($general['crew'] <= 0) { break; }
}
$render_attacker = [
'crewtype' => mb_substr($generalCrewType->name, 0, 2),
'name'=> $general['name'],
'remain_crew' => $general['crew'],
'killed_crew' => -$mydeathnum
];
$render_defender = [
'crewtype' => mb_substr($opposeCrewType->name, 0, 2),
'name'=> $oppose['name'],
'remain_crew' => $oppose['crew'],
'killed_crew' => -$opdeathnum
];
$res = str_replace(["\r\n", "\r", "\n"], '', $templates->render('small_war_log',[
'year'=>$year,
'month'=>$month,
'war_type'=>'attack',
'war_type_str'=>'→',
'me' => $render_attacker,
'you' => $render_defender,
]));
$oppres = str_replace(["\r\n", "\r", "\n"], '', $templates->render('small_war_log',[
'year'=>$year,
'month'=>$month,
'war_type'=>'defense',
'war_type_str'=>'←',
'me' => $render_defender,
'you' => $render_attacker,
]));
$log[] = $res;
$batlog[] = $res;
$batres[] = $res;
$opplog[] = $oppres;
$oppbatlog[] = $oppres;
$oppbatres[] = $oppres;
$deadAmount['att'] = $deadAmount['att'] + $mydeathnum;
$deadAmount['def'] = $deadAmount['def'] + $opdeathnum;
// 상대장수 부상
$ratio = rand() % 100;
if($ratio >= 95) {
$opplog[] = "<C>●</>전투중 <R>부상</>당했다!";
$oppose['injury'] += rand() % 71 + 10; // 10 ~ 80
if($oppose['injury'] > 80) { $oppose['injury'] = 80; }
}
// 병사수 변경
$query = "update general set injury='{$oppose['injury']}',crew='{$oppose['crew']}',killcrew=killcrew+'$opkillnum',deathcrew=deathcrew+'$opdeathnum' where no='{$oppose['no']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
// 숙련도 증가
addGenDex($oppose['no'], $general['atmos'], $general['train'], $oppose['crewtype'], $opkillnum * 0.9);
addGenDex($oppose['no'], $general['atmos'], $general['train'], $general['crewtype'], $opdeathnum * 0.9);
// 죽은수 기술로 누적
$num = Util::round($mydeathnum * 0.01);
// 국가보정
if($nation['type'] == 3 || $nation['type'] == 13) { $num *= 1.1; }
if($nation['type'] == 5 || $nation['type'] == 6 || $nation['type'] == 7 || $nation['type'] == 8 || $nation['type'] == 12) { $num *= 0.9; }
// 부드러운 기술 제한
if(TechLimit($admin['startyear'], $year, $nation['tech'])) { $num = intdiv($num, 4); }
$query = "update nation set totaltech=totaltech+'$num',tech=totaltech/'$gencount' where nation='{$nation['nation']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
// 장수 부상
$ratio = rand() % 100;
if($ratio >= 95) {
$log[] = "<C>●</>전투중 <R>부상</>당했다!";
$general['injury'] += rand() % 71 + 10; // 10 ~ 80
if($general['injury'] > 80) { $general['injury'] = 80; }
}
// 병사수 변경
$query = "update general set injury='{$general['injury']}',crew='{$general['crew']}',killcrew=killcrew+'$mykillnum',deathcrew=deathcrew+'$mydeathnum' where no='{$general['no']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
// 숙련도 증가
addGenDex($general['no'], $general['atmos'], $general['train'], $general['crewtype'], $mykillnum);
addGenDex($general['no'], $general['atmos'], $general['train'], $oppose['crewtype'], $mydeathnum);
// 죽은수 기술로 누적
$num = Util::round($opdeathnum * 0.01);
// 국가보정
if($destnation['type'] == 3 || $destnation['type'] == 13) { $num *= 1.1; }
if($destnation['type'] == 5 || $destnation['type'] == 6 || $destnation['type'] == 7 || $destnation['type'] == 8 || $destnation['type'] == 12) { $num *= 0.9; }
// 부드러운 기술 제한
if(TechLimit($admin['startyear'], $year, $destnation['tech'])) { $num = intdiv($num, 4); }
$query = "update nation set totaltech=totaltech+'$num',tech=totaltech/'$destgencount' where nation='{$destnation['nation']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
//양국 평균 기술가격
//$techRatio = (getTechCost($nation['tech']) + getTechCost($destnation['tech'])) / 2;
$techRatio = 1.0;
// 죽은수 도시 재정으로 누적 60%
$num = Util::round(($mykillnum+$mydeathnum) * 0.6 * $techRatio);
// 국가보정
if($destnation['type'] == 1) { $num *= 1.1; }
if($destnation['type'] == 9 || $destnation['type'] == 10) { $num *= 0.9; }
$query = "update city set dead=dead+'$num' where city='{$city['city']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
// 죽은수 도시 재정으로 누적 40%
$num = Util::round(($mykillnum+$mydeathnum) * 0.4 * $techRatio);
// 국가보정
if($nation['type'] == 1) { $num *= 1.1; }
if($nation['type'] == 9 || $nation['type'] == 10) { $num *= 0.9; }
$query = "update city set dead=dead+'$num' where city='{$general['city']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
// 상대 병사 소진이나 쌀 소진시 다음 장수
if($oppose['crew'] <= 0 || ($opRice <= Util::round($oppose['crew']/100) && $general['crew'] > 0)) {
if($opRice <= Util::round($oppose['crew']/100)) {
$josaYi = JosaUtil::pick($opposeCrewType->name, '이');
$alllog[] = "<C>●</>{$month}월:<Y>{$oppose['name']}</>의 {$opposeCrewType->name}{$josaYi} 패퇴했습니다.";
$log[] = "<C>●</><Y>{$oppose['name']}</>의 {$opposeCrewType->name}{$josaYi} 패퇴했습니다.";
$opplog[] = "<C>●</>군량 부족으로 패퇴합니다.";
} else {
$josaYi = JosaUtil::pick($opposeCrewType->name, '이');
$alllog[] = "<C>●</>{$month}월:<Y>{$oppose['name']}</>의 {$opposeCrewType->name}{$josaYi} 전멸했습니다.";
$log[] = "<C>●</><Y>{$oppose['name']}</>의 {$opposeCrewType->name}{$josaYi} 전멸했습니다.";
$opplog[] = "<C>●</>전멸했습니다.";
}
$opposecount--;
$general['atmos'] *= 1.1; //사기 증가
if($general['atmos'] > GameConst::$maxAtmosByWar) { $general['atmos'] = GameConst::$maxAtmosByWar; }
$query = "update general set atmos='{$general['atmos']}',killnum=killnum+1 where no='{$general['no']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$exp2++;
// 상대장수 경험 등등 증가
$opexp = Util::round($opexp / 50 * 0.8);
// 성격 보정
$opexp = CharExperience($opexp, $oppose['personal']);
// 쌀 소모
$oppose['rice'] -= ($opexp * 5 * getCrewtypeRice($opposeCrewType, $destnation['tech']));
if($oppose['rice'] < 0) { $oppose['rice'] = 0; }
$query = "update general set deathnum=deathnum+1,rice='{$oppose['rice']}',experience=experience+'$opexp',dedication=dedication+'$opexp' where no='{$oppose['no']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$opexp = 0;
pushGenLog($oppose, $opplog);
pushBatLog($oppose, $oppbatlog);
pushBatRes($oppose, $oppbatres);
$oppose = null;
$opplog = [];
$oppbatlog = [];
$oppbatres = [];
// 공격 장수 병사 소진이나 쌀 소진시 실패 처리
} elseif($general['crew'] <= 0 || $myRice <= Util::round($general['crew']/100)) {
if($myRice <= Util::round($general['crew']/100)) {
$josaYi = JosaUtil::pick($generalCrewType->name, '이');
$alllog[] = "<C>●</>{$month}월:<Y>{$general['name']}</>의 {$generalCrewType->name}{$josaYi} 퇴각했습니다.";
$log[] = "<C>●</>군량 부족으로 퇴각합니다.";
$opplog[] = "<C>●</><Y>{$general['name']}</>의 {$generalCrewType->name}{$josaYi} 퇴각했습니다.";
} else {
$josaYi = JosaUtil::pick($generalCrewType->name, '이');
$alllog[] = "<C>●</>{$month}월:<Y>{$general['name']}</>의 {$generalCrewType->name}{$josaYi} 퇴각했습니다.";
$log[] = "<C>●</>퇴각했습니다.";
$opplog[] = "<C>●</><Y>{$general['name']}</>의 {$generalCrewType->name}{$josaYi} 퇴각했습니다.";
}
// 경험치 상승
if($opposeCrewType->armType == GameUnitConst::T_WIZARD) { // 귀병
$oppose['intel2']++;
} elseif($opposeCrewType->armType == GameUnitConst::T_SIEGE) { // 차병
$oppose['leader2']++;
} else {
$oppose['power2']++;
}
$oppose['atmos'] *= 1.1; //사기 증가
if($oppose['atmos'] > GameConst::$maxAtmosByWar) { $oppose['atmos'] = GameConst::$maxAtmosByWar; }
// 상대장수 경험 등등 증가
$opexp = Util::round($opexp / 50 * 0.8);
// 성격 보정
$opexp = CharExperience($opexp, $oppose['personal']);
// 쌀 소모
$oppose['rice'] -= ($opexp * 5 * getCrewtypeRice($opposeCrewType, $destnation['tech']));
if($oppose['rice'] < 0) { $oppose['rice'] = 0; }
$query = "update general set rice='{$oppose['rice']}',leader2='{$oppose['leader2']}',power2='{$oppose['power2']}',intel2='{$oppose['intel2']}',atmos='{$oppose['atmos']}',experience=experience+'$opexp',dedication=dedication+'$opexp',killnum=killnum+1 where no='{$oppose['no']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$query = "update general set deathnum=deathnum+1 where no='{$general['no']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$opexp = 0;
$opplog = checkAbility($oppose, $opplog);
pushGenLog($oppose, $opplog);
pushBatLog($oppose, $oppbatlog);
pushBatRes($oppose, $oppbatres);
$opplog = [];
$oppbatlog = [];
$oppbatres = [];
// $josaYi = JosaUtil::pick($general['name'], '이');
// $alllog[] = "<C>●</>{$month}월:<Y>{$general['name']}</>{$josaYi} }<G>{$city['name']}</> 공략에 실패했습니다. <1>$date</>";
// $log[] = "<C>●</> <G>{$city['name']}</> 공략에 실패했습니다. <1>$date</>";
break;
} else {
// 무승부일때 로그 남김
pushGenLog($oppose, $opplog);
pushBatLog($oppose, $oppbatlog);
pushBatRes($oppose, $oppbatres);
$opplog = [];
$oppbatlog = [];
$oppbatres = [];
}
}
}
if(isset($oppose)){
//마지막 페이즈에 장수가 전멸하지 않은 경우. 쌀 소모 후속 처리
// 상대장수 경험 등등 증가(페이즈 초과시)
$opexp = Util::round($opexp / 50 * 0.8);
// 성격 보정
$opexp = CharExperience($opexp, $oppose['personal']);
// 쌀 소모
$oppose['rice'] -= ($opexp * 5 * getCrewtypeRice($opposeCrewType, $destnation['tech']));
if($oppose['rice'] < 0) { $oppose['rice'] = 0; }
$query = "update general set rice='{$oppose['rice']}',experience=experience+'$opexp',dedication=dedication+'$opexp' where no='{$oppose['no']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
}
// 경험치 상승
if($generalCrewType->armType == GameUnitConst::T_WIZARD) { // 귀병
$general['intel2'] += $exp2;
} elseif($generalCrewType->armType == GameUnitConst::T_SIEGE) { // 차병
$general['leader2'] += $exp2;
} else {
$general['power2'] += $exp2;
}
$query = "update general set leader2='{$general['leader2']}',power2='{$general['power2']}',intel2='{$general['intel2']}' where no='{$general['no']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
// 공헌, 명성 상승
$exp = Util::round($exp / 50);
// 성격 보정
$exp = CharExperience($exp, $general['personal']);
// 쌀 소모
$general['rice'] -= ($exp * 5 * getCrewtypeRice($generalCrewType, $nation['tech']));
if($general['rice'] < 0) { $general['rice'] = 0; }
$query = "update general set rice='{$general['rice']}',dedication=dedication+'$exp',experience=experience+'$exp' where no='{$general['no']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$log = checkAbility($general, $log);
pushGenLog($general, $log);
pushBatLog($general, $batlog);
pushBatRes($general, $batres);
pushGeneralPublicRecord($alllog, $year, $month);
pushWorldHistory($history);
return $deadAmount;
}
function CriticalScore2($score) {
$score = Util::round($score * (rand()%8 + 13)/10); // 1.3~2.0
return $score;
}
//0 0 : 100 100 이면 최고 무한대 차이
//30 30 : 100 100 이면 최고 3.3배 차이
//60 60 : 100 100 이면 최고 1.6배 차이
function getCrew($crew, $youatmos, $mytrain) {
$ratio = $youatmos / $mytrain;
$crew = $crew * $ratio;
return $crew;
}
function getCrewtypeRice($crewtype, $tech) {
$cost = $crewtype->rice / 10;
return $cost * getTechCost($tech);
}
//////////////////////////////////////////////////////////////
// 표준 공 / 수 반환 수치는 약 0이 되게 (100~550)
//////////////////////////////////////////////////////////////
function addConflict($city, $nationID, $mykillnum) {
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
$nationlist = [];
$killnum = [0];
list($year, $month) = $gameStor->getValuesAsArray(['year', 'month']);
$conflict = Json::decode($city['conflict']);
if(!$conflict || $city['def'] == 0){ // 선타, 막타 보너스
$mykillnum *= 1.05;
}
if (!$conflict) {
$conflict[$nationID] = $mykillnum;
}
else if(key_exists($nationID, $conflict)){
$conflict[$nationID] += $mykillnum;
arsort($conflict);
}
else{
$conflict[$nationID] = $mykillnum;
arsort($conflict);
$nation = getNationStaticInfo($nationID);
$josaYi = JosaUtil::pick($nation['name'], '이');
pushWorldHistory(["<C>●</>{$year}{$month}월:<M><b>【분쟁】</b></><D><b>{$nation['name']}</b></>{$josaYi} <G><b>{$city['name']}</b></> 공략에 가담하여 분쟁이 발생하고 있습니다."]);
}
$rawConflict = Json::encode($conflict);
$city['conflict'] = $rawConflict;
$db->update('city', [
'conflict'=>$rawConflict
], 'city=%i',$city['city']);
return $city;
}
function DeleteConflict($nation) {
$db = DB::db();
foreach($db->queryAllLists('SELECT city, conflict FROM city WHERE conflict!=%s', '{}') as list($cityID, $rawConflict)){
$conflict = Json::decode($rawConflict);
if(!$conflict || !is_array($conflict)){
continue;
}
if(!key_exists($nation, $conflict)){
continue;
}
unset($conflict[$nation]);
$db->update('city', [
'conflict'=>Json::encode($conflict)
], 'city=%i', $cityID);
}
}
function getConquerNation($city) : int {
$conflict = Json::decode($city['conflict']);
return Util::array_first_key($conflict);
}
function ConquerCity($admin, $general, $city, $nation, $destnation) {
'@phan-var array<string,mixed> $city';
$db = DB::db();
$connect=$db->get();
$alllog = [];
$log = [];
$history = [];
if($destnation['nation'] > 0) {
$destnationName = "<D><b>{$destnation['name']}</b></>의";
} else {
$destnationName = "공백지인";
}
$year = $admin['year'];
$month = $admin['month'];
$josaUl = JosaUtil::pick($city['name'], '을');
$josaYiNation = JosaUtil::pick($nation['name'], '이');
$josaYiGen = JosaUtil::pick($general['name'], '이');
$josaYiCity = JosaUtil::pick($city['name'], '이');
$alllog[] = "<C>●</>{$month}월:<Y>{$general['name']}</>{$josaYiGen} <G><b>{$city['name']}</b></> 공략에 <S>성공</>했습니다.";
$log[] = "<C>●</><G><b>{$city['name']}</b></> 공략에 <S>성공</>했습니다.";
$history[] = "<C>●</>{$year}{$month}월:<S><b>【지배】</b></><D><b>{$nation['name']}</b></>{$josaYiNation} <G><b>{$city['name']}</b></>{$josaUl} 지배했습니다.";
pushGeneralHistory($general, "<C>●</>{$year}{$month}월:<G><b>{$city['name']}</b></>{$josaUl} <S>함락</>시킴");
pushNationHistory($nation, "<C>●</>{$year}{$month}월:<Y>{$general['name']}</>{$josaYiGen} {$destnationName} <G><b>{$city['name']}</b></>{$josaUl} <S>점령</>");
pushNationHistory($destnation, "<C>●</>{$year}{$month}월:<D><b>{$nation['name']}</b></>의 <Y>{$general['name']}</>에 의해 <G><b>{$city['name']}</b></>{$josaYiCity} <span class='ev_highlight'>함락</span>");
$query = "select city from city where nation='{$city['nation']}'";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$citycount = MYDB_num_rows($result);
// 국가 멸망시
//TODO: 국가 멸망 코드를 별도로 작성
if($citycount == 1 && $city['nation'] != 0) {
$query = "select nation,name,gold,rice from nation where nation='{$city['nation']}'";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$losenation = MYDB_fetch_array($result);
$josaYi = JosaUtil::pick($losenation['name'], '이');
$josaUl = JosaUtil::pick($losenation['name'], '을');
$history[] = "<C>●</>{$year}{$month}월:<R><b>【멸망】</b></><D><b>{$losenation['name']}</b></>{$josaYi} 멸망하였습니다.";
pushNationHistory($nation, "<C>●</>{$year}{$month}월:<D><b>{$losenation['name']}</b></>{$josaUl} 정복");
$query = "select no, nation from general where nation='{$general['nation']}' and level='12'";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$ruler = MYDB_fetch_array($result);
//다굴치는 나라들 전방설정을 위해 미리 얻어옴
$query = "select you from diplomacy where me='{$losenation['nation']}' and state<2";
$dipResult = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$dipCount = MYDB_num_rows($dipResult);
$loseGeneralGold = 0;
$loseGeneralRice = 0;
//멸망국 장수들 역사 기록 및 로그 전달
$josaYi = JosaUtil::pick($losenation['name'], '이');
$genlog = ["<C>●</><D><b>{$losenation['name']}</b></>{$josaYi} <R>멸망</>했습니다."];
// 국가 백업
$oldNation = $db->queryFirstRow('SELECT * FROM nation WHERE nation=%i', $city['nation']);
$oldNationGenerals = $db->query('SELECT * FROM general WHERE nation=%i', $city['nation']);
$oldNation['generals'] = array_map(function($gen){
//다른 코드와는 다르게 공용으로 쓰므로 남겨둠
return $gen['no'];
}, $oldNationGenerals);
$oldNation['aux'] = Json::decode($oldNation['aux']);
foreach($oldNationGenerals as $gen){
$loseGold = intdiv($gen['gold'] * (rand()%30+20), 100);
$loseRice = intdiv($gen['rice'] * (rand()%30+20), 100);
$genlog[1] = "<C>●</>도주하며 금<C>$loseGold</> 쌀<C>$loseRice</>을 분실했습니다.";
$query = "update general set gold=gold-{$loseGold},rice=rice-{$loseRice} where no={$gen['no']}";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
pushGenLog($gen, $genlog);
pushGeneralHistory($gen, "<C>●</>{$year}{$month}월:<D><b>{$losenation['name']}</b></>{$josaYi} <R>멸망</>");
pushOldNationStop($gen['no'], $city['nation']);
$loseGeneralGold += $loseGold;
$loseGeneralRice += $loseRice;
//모두 등용장 발부
if($nation['name'] == "강족" || $nation['name'] == "저족" || $nation['name'] == "흉노족"
|| $nation['name'] == "남만족" || $nation['name'] == "산월족" || $nation['name'] == "오환족"
|| $nation['name'] == "왜족") {
//등용장 미발부
} elseif(Util::randBool(0.5)) {
$msg = ScoutMessage::buildScoutMessage($general['no'], $gen['no']);
if($msg){
$msg->send(true);
}
}
//NPC인 경우 10% 확률로 임관(엔장, 인재, 의병)
if($gen['npc'] >= 2 && $gen['npc'] <= 8 && rand() % 100 < 10) {
$commissionCommand = EncodeCommand(0, 0, $nation['nation'], 25); //임관
$query = "update general set turn0='$commissionCommand' where no={$gen['no']}";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
}
}
unset($genlog[1]);
// 승전국 보상
$losenation['gold'] -= GameConst::$basegold;
$losenation['rice'] -= GameConst::$baserice;
if($losenation['gold'] < 0) { $losenation['gold'] = 0; }
if($losenation['rice'] < 0) { $losenation['rice'] = 0; }
$losenation['gold'] += $loseGeneralGold;
$losenation['rice'] += $loseGeneralRice;
$losenation['gold'] = intdiv($losenation['gold'], 2);
$losenation['rice'] = intdiv($losenation['gold'], 2);
// 기본량 제외 금쌀50% + 장수들 분실 금쌀50% 흡수
$query = "update nation set gold=gold+'{$losenation['gold']}',rice=rice+'{$losenation['rice']}' where nation='{$general['nation']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
//아국 수뇌부에게 로그 전달
$query = "select no,name,nation from general where nation='{$general['nation']}' and level>='9'";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$gencount = MYDB_num_rows($result);
$genlog[0] = "<C>●</><D><b>{$losenation['name']}</b></> 정복으로 금<C>{$losenation['gold']}</> 쌀<C>{$losenation['rice']}</>을 획득했습니다.";
for($i=0; $i < $gencount; $i++) {
$gen = MYDB_fetch_array($result);
pushGenLog($gen, $genlog);
}
//분쟁기록 모두 지움
DeleteConflict($city['nation']);
// 전 장수 공헌 명성치 깎음
$query = "update general set dedication=dedication*0.5,experience=experience*0.9 where nation='{$city['nation']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
// 전 도시 공백지로
$query = "update city set nation='0',gen1='0',gen2='0',gen3='0',conflict='{}',term=0 where nation='{$city['nation']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
// 전 장수 소속 무소속으로, 재야로, 부대 탈퇴
$query = "update general set nation='0',belong='0',level='0',troop='0' where nation='{$city['nation']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
// 부대도 삭제
$query = "delete from troop where nation='{$city['nation']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
// 외교 삭제
$query = "delete from diplomacy where me='{$city['nation']}' or you='{$city['nation']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$db->insert('ng_old_nations', [
'server_id'=>UniqueConst::$serverID,
'nation'=>$city['nation'],
'data'=>Json::encode($oldNation)
]);
// 국가 삭제
$query = "delete from nation where nation='{$city['nation']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
// 아까 얻어온 다굴국들 전방설정
for($i=0; $i < $dipCount; $i++) {
$dip = MYDB_fetch_array($dipResult);
//전방설정
SetNationFront($dip['you']);
}
// 멸망이 아니면
} else {
// 태수,군사,시중은 일반으로...
$db->update('general',[
'level'=>1
], 'no IN %li',[$city['gen1'], $city['gen2'], $city['gen3']]);
//수도였으면 긴급 천도
if(isset($destnation['capital']) && $destnation['capital'] == $city['city']) {
$minCity = findNextCapital($city['city'], $destnation['nation']);
$minCityName = CityConst::byID($minCity)->name;
$josaYi = JosaUtil::pick($destnation['name'], '이');
$history[] = "<C>●</>{$year}{$month}월:<M><b>【긴급천도】</b></><D><b>{$destnation['name']}</b></>{$josaYi} 수도가 함락되어 <G><b>$minCityName</b></>으로 긴급천도하였습니다.";
//아국 수뇌부에게 로그 전달
$query = "select no,name,nation from general where nation='{$destnation['nation']}' and level>='5'";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$gencount = MYDB_num_rows($result);
$genlog = ["<C>●</>수도가 함락되어 <G><b>$minCityName</b></>으로 <M>긴급천도</>합니다."];
for($i=0; $i < $gencount; $i++) {
$gen = MYDB_fetch_array($result);
pushGenLog($gen, $genlog);
}
//천도
$query = "update nation set capital='$minCity',gold=gold*0.5,rice=rice*0.5 where nation='{$destnation['nation']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
//보급도시로 만듬
$query = "update city set supply=1 where city='$minCity'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
//수뇌부 이동
$query = "update general set city='$minCity' where nation='{$destnation['nation']}' and level>='5'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
//장수 사기 감소
$query = "update general set atmos=atmos*0.8 where nation='{$destnation['nation']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
refreshNationStaticInfo();
}
}
$general['atmos'] *= 1.1; //사기 증가
if($general['atmos'] > GameConst::$maxAtmosByWar) { $general['atmos'] = GameConst::$maxAtmosByWar; }
$conquerNation = getConquerNation($city);
if($conquerNation == $general['nation']) {
// 이동 및 사기 변경
$query = "update general set city='{$city['city']}',atmos='{$general['atmos']}',killnum=killnum+1 where no='{$general['no']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
if($city['level'] > 3) {
// 도시 소속 변경, 태수,군사,시중 초기화
$query = "update city set supply=1,conflict='{}',term=0,agri=agri*0.7,comm=comm*0.7,secu=secu*0.7,def=1000,wall=1000,nation='{$general['nation']}',gen1=0,gen2=0,gen3=0 where city='{$city['city']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
} else {
// 도시 소속 변경, 태수,군사,시중 초기화
$query = "update city set supply=1,conflict='{}',term=0,agri=agri*0.7,comm=comm*0.7,secu=secu*0.7,def=def2/2,wall=wall2/2,nation='{$general['nation']}',gen1=0,gen2=0,gen3=0 where city='{$city['city']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
}
//전방설정
SetNationFront($nation['nation']);
SetNationFront($destnation['nation']);
} else {
$query = "select name,nation from nation where nation='$conquerNation'";
$conquerResult = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$conquerNationArray = MYDB_fetch_array($conquerResult);
$josaUl = JosaUtil::pick($city['name'], '을');
$josaYi = JosaUtil::pick($conquerNationArray['name'], '이');
$history[] = "<C>●</>{$year}{$month}월:<Y><b>【분쟁협상】</b></><D><b>{$conquerNationArray['name']}</b></>{$josaYi} 영토분쟁에서 우위를 점하여 <G><b>{$city['name']}</b></>{$josaUl} 양도받았습니다.";
pushNationHistory($nation, "<C>●</>{$year}{$month}월:<G><b>{$city['name']}</b></>{$josaUl} <D><b>{$conquerNationArray['name']}</b></>에 <Y>양도</>");
pushNationHistory($conquerNationArray, "<C>●</>{$year}{$month}월:<D><b>{$nation['name']}</b></>에서 <G><b>{$city['name']}</b></>{$josaUl} <S>양도</> 받음");
// 이동X 및 사기 변경
$query = "update general set atmos='{$general['atmos']}',killnum=killnum+1 where no='{$general['no']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$query = [
'supply'=>1,
'term'=>0,
'conflict'=>'{}',
'agri'=>$db->sqleval('agri*0.7'),
'comm'=>$db->sqleval('comm*0.7'),
'secu'=>$db->sqleval('secu*0.7'),
'nation'=>$conquerNation,
'gen1'=>0,
'gen2'=>0,
'gen3'=>0
];
if($city['level'] > 3) {
$query['def'] = 1000;
$query['wall'] = 1000;
} else {
// 도시 소속 변경, 태수,군사,시중 초기화
$query['def'] = $db->sqleval('def2/2');
$query['wall'] = $db->sqleval('wall2/2');
}
$db->update('city', $query, 'city=%i', (int)$city['city']);
//전방설정
SetNationFront($destnation['nation']);
SetNationFront($conquerNation);
}
pushGenLog($general, $log);
pushGeneralPublicRecord($alllog, $year, $month);
pushWorldHistory($history);
}
function findNextCapital(int $capitalID, int $nationID):int{
$distList = searchDistance($capitalID, 99, true);
$cities = [];
foreach(
DB::db()->query(
'SELECT city, pop FROM city WHERE nation=%i and city!=%i',
$nationID,
$capitalID
) as $row
){
$cities[$row['city']] = $row['pop'];
};
foreach($distList as $dist=>$distSubList){
$maxCityPop = 0;
$minCity = 0;
foreach($distSubList as $cityID){
if(!key_exists($cityID, $cities)){
continue;
}
$cityPop = $cities[$cityID];
if($cityPop < $maxCityPop){
continue;
}
$minCity = $cityID;
$maxCityPop = $cityPop;
}
if($minCity){
return $minCity;
}
}
throw new \RuntimeException('도시가 남지 않았는데 긴천을 시도하고 있습니다');
}
+405 -1542
View File
@@ -2,1541 +2,419 @@
namespace sammo;
function processWar($general, $city) {
'@phan-var array<string,int|string|null> $general';
function processWar(array $rawAttacker, array $rawDefenderCity){
$db = DB::db();
$rawAttackerCity = $db->queryFirstRow('SELECT * FROM city WHERE city = %i', $rawAttacker['city']);
$attackerNationID = $rawAttacker['nation'];
$defenderNationID = $rawDefenderCity['nation'];
$rawAttackerNation = $db->queryFirstRow('SELECT nation,`level`,`name`,capital,totaltech,gennum,tech,`type`,gold,rice FROM nation WHERE nation = %i', $attackerNationID);
if($defenderNationID == 0){
$rawDefenderNation = [
'nation'=>0,
'name'=>'재야',
'capital'=>0,
'level'=>0,
'gold'=>0,
'rice'=>2000,
'type'=>0,
'tech'=>0,
'totaltech'=>0,
'gennum'=>1
];
}
else{
$rawDefenderNation = $db->queryFirstRow('SELECT nation,`level`,`name`,capital,totaltech,gennum,tech,`type`,gold,rice FROM nation WHERE nation = %i', $defenderNationID);
}
$gameStor = KVStorage::getStorage($db, 'game_env');
$connect=$db->get();
[$startYear, $year, $month, $cityRate] = $gameStor->getValuesAsArray(['startyear', 'year', 'month', 'city_rate']);
$templates = new \League\Plates\Engine(__dir__.'/templates');
$attacker = new WarUnitGeneral($rawAttacker, $rawAttackerCity, $rawAttackerNation, true, $year, $month);
$date = substr($general['turntime'],11,5);
$city = new WarUnitCity($rawDefenderCity, $rawAttackerNation, $year, $month, $cityRate);
$admin = $gameStor->getAll();
$defenderList = $db->query('SELECT no,name,nation,turntime,personal,special2,crew,crewtype,atmos,train,intel,intel2,book,power,power2,weap,injury,leader,leader2,horse,item,explevel,experience,dedication,level,gold,rice,dex0,dex10,dex20,dex30,dex40,warnum,killnum,deathnum,killcrew,deathcrew,recwar FROM general WHERE nation=%i AND city=%i AND nation!=0 and crew > 0 and rice>(crew/100) and ((train>=60 and atmos>=60 and mode=1) or (train>=80 and atmos>=80 and mode=2))', $city->getVar('nation'), $city->getVar('city'));
$year = $admin['year'];
$month = $admin['month'];
$log = [];
$batlog = [];
$batres = [];
$opplog = [];
$oppbatlog = [];
$oppbatres = [];
$alllog = [];
$history = [];
$deadAmount = [
'att'=>0,
'def'=>0
];
$generalCrewType = GameUnitConst::byID($general['crewtype']);
$warphase = $generalCrewType->speed; //병종간 페이즈 수 얻기
// 특기보정 : 돌격
if($general['special2'] == 60) { $warphase += 1; }
$genAtmos = 0;
if($general['item'] == 3) {
//탁주 사용
$genAtmos += 3;
$query = "update general set item=0 where no='{$general['no']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$josaUl = JosaUtil::pick($general['item'], '을');
$log[] = "<C>●</><C>".getItemName($general['item'])."</>{$josaUl} 사용!";
$general['item'] = 0;
} elseif($general['item'] >= 14 && $general['item'] <= 16) {
//의적주, 두강주, 보령압주 사용
$genAtmos += 5;
} elseif($general['item'] >= 19 && $general['item'] <= 20) {
//춘화첩, 초선화 사용
$genAtmos += 7;
}
$genTrain = 0;
if($general['item'] == 4) {
//청주 사용
$genTrain += 3;
$query = "update general set item=0 where no='{$general['no']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$josaUl = JosaUtil::pick($general['item'], '을');
$log[] = "<C>●</><C>".getItemName($general['item'])."</>{$josaUl} 사용!";
$general['item'] = 0;
} elseif($general['item'] >= 12 && $general['item'] <= 13) {
//과실주, 이강주 사용
$genTrain += 5;
} elseif($general['item'] >= 17 && $general['item'] <= 18) {
//철벽서, 단결도 사용
$genTrain += 7;
if(!$defenderList){
$defenderList = [];
}
// 우선 스케일링
$city['def'] *= 10;
$city['wall'] *= 10;
$query = "select level from city where city='{$general['city']}'";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$originCity = MYDB_fetch_array($result);
$query = "select nation,level,name,capital,tech,type from nation where nation='{$general['nation']}'";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$nation = MYDB_fetch_array($result);
setLeadershipBonus($general, $nation['level']);
$query = "select nation,level,name,rice,capital,tech,type from nation where nation='{$city['nation']}'";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$destnation = MYDB_fetch_array($result) ?: [
'nation'=>0,
'capital'=>0,
'level'=>0,
'rice'=>2000,
'type'=>0,
'tech'=>0
];
//장수수 구함
$query = "select no from general where nation='{$general['nation']}'";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$gencount = MYDB_num_rows($result);
if($gencount < GameConst::$initialNationGenLimit) $gencount = GameConst::$initialNationGenLimit;
//장수수 구함
$query = "select no from general where nation='{$destnation['nation']}'";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$destgencount = MYDB_num_rows($result);
if($destgencount < GameConst::$initialNationGenLimit) $destgencount = GameConst::$initialNationGenLimit;
$genAtmosBonus = 0; $genTrainBonus = 0;
$oppAtmosBonus = 0; $oppTrainBonus = 0;
//공격자 수도보정
if($nation['capital'] == $general['city']) { $genAtmosBonus += 5; }
//방어자 수도보정
//if($destnation['capital'] == $city['city']) { $oppTrainBonus += 5; }
//관,진,수진 보정
if($city['level'] == 1) { $oppTrainBonus += 5; } // 방어도시가 수진이면 방어자 방어보정
if($originCity['level'] == 2) { $genAtmosBonus += 5; } // 출병도시가 진이면 공격자 공격보정
if($city['level'] == 3) { $oppTrainBonus += 5; } // 방어도시가 관이면 방어자 방어보정
$josaRo = JosaUtil::pick($city['name'], '로');
$josaYi = JosaUtil::pick($general['name'], '이');
$alllog[] = "<C>●</>{$month}월:<D><b>{$nation['name']}</b></>의 <Y>{$general['name']}</>{$josaYi} <G><b>{$city['name']}</b></>{$josaRo} 진격합니다.";
$log[] = "<C>●</>{$month}월:<G><b>{$city['name']}</b></>{$josaRo} <M>진격</>합니다. <1>$date</>";
// 목표 도시내에 목표 국가 소속 장수 중, 병사가 있는 능력치합+병사수 순으로 훈,사 60, 80 이상
$query = "select no,name,turntime,personal,special2,crew,crewtype,atmos,train,intel,intel2,book,power,power2,weap,injury,leader,leader2,horse,item,explevel,level,rice,leader+power+intel+weap+horse+book+crew/100 as sum,dex0,dex10,dex20,dex30,dex40 from general where city='{$city['city']}' and nation='{$city['nation']}' and nation!=0 and crew>'0' and rice>round(crew/100) and ((train>=60 and atmos>=60 and mode=1) or (train>=80 and atmos>=80 and mode=2)) order by sum desc";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$opposecount = MYDB_num_rows($result);
$exp = 0; //병사 소진 시킨 만큼
$opexp = 0;
$exp2 = 1; //능력경험치
$phase = 0;
while($phase < $warphase) {
// 장수가 없어서 도시 공격하려했으나 병량없을시
if($opposecount == 0 && $destnation['nation'] > 0 && $destnation['rice'] <= 0 && $city['supply'] == 1) {
$general['train'] += 1; //훈련 상승
if($general['train'] > GameConst::$maxTrainByWar) { $general['train'] = GameConst::$maxTrainByWar; }
$query = "update general set recwar='{$general['turntime']}',train='{$general['train']}',warnum=warnum+1 where no='{$general['no']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$alllog[] = "<C>●</>{$month}월:병량 부족으로 <G><b>{$city['name']}</b></>의 수비병들이 <R>패퇴</>합니다.";
$josaUl = JosaUtil::pick($city['name'], '을');
$josaYi = JosaUtil::pick($general['name'], '이');
$history[] = "<C>●</>{$year}{$month}월:<M><b>【패퇴】</b></><D><b>{$destnation['name']}</b></>{$josaYi} 병량 부족으로 <G><b>{$city['name']}</b></>{$josaUl} 뺏기고 말았습니다.";
pushGenLog($general, $log);
pushGeneralPublicRecord($alllog, $year, $month);
pushWorldHistory($history);
$log = [];
$alllog = [];
$history= [];
//패퇴시 병량보충
$destnation['rice'] += 500;
$query = "update nation set rice='{$destnation['rice']}' where nation='{$destnation['nation']}'";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
//내정 피폐
$query = "update city set agri=agri*0.5,comm=comm*0.5,secu=secu*0.5 where city='{$city['city']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$city = addConflict($city, $general['nation'], 1);//NOTE: 이 경우 두 국가가 분쟁 중인 경우에는 병량패퇴의 이득이 없다.
ConquerCity($admin, $general, $city, $nation, $destnation);
break;
// 장수가 없어서 도시 공격
} elseif($opposecount == 0) {
$opposeCrewType = GameUnitConst::byId(GameUnitConst::T_CASTLE);
$josaRo = JosaUtil::pick($generalCrewType->name, '로');
$josaYi = JosaUtil::pick($general['name'], '이');
$alllog[] = "<C>●</>{$month}월:<Y>{$general['name']}</>{$josaYi} {$generalCrewType->name}{$josaRo} 성벽을 공격합니다.";
$log[] = "<C>●</>{$generalCrewType->name}{$josaRo} 성벽을 <M>공격</>합니다.";
$general['train'] += 1; //훈련 상승
if($general['train'] > GameConst::$maxTrainByWar) { $general['train'] = GameConst::$maxTrainByWar; }
$query = "update general set recwar='{$general['turntime']}',train='{$general['train']}',warnum=warnum+1 where no='{$general['no']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$mykillnum = 0; $mydeathnum = 0;
while($phase < $warphase) {
$phase++;
$myAtt = $generalCrewType->getComputedAttack($general, $nation['tech']);
$myDef = $generalCrewType->getComputedDefence($general, $nation['tech']);
$cityAtt = $opposeCrewType->getComputedAttack($city, $destnation['tech']);
$cityDef = $opposeCrewType->getComputedDefence($city, $destnation['tech']);
// 감소할 병사 수
$cityCrew = GameConst::$armperphase + $myAtt - $cityDef;
$myCrew = GameConst::$armperphase + $cityAtt - $myDef;
if($cityCrew <= 0) { $cityCrew = rand() % 90 + 10; }
if($myCrew <= 0) { $myCrew = rand() % 90 + 10; }
//훈련 사기따라
$myCrew = getCrew($myCrew, $admin['city_rate']+$oppAtmosBonus, CharTrain($general['train']+$genTrain+$genTrainBonus, $general['personal']));
$cityCrew = getCrew($cityCrew, CharAtmos($general['atmos']+$genAtmos+$genAtmosBonus, $general['personal']), $admin['city_rate']+$oppTrainBonus);
//숙련도 따라
$genDexAtt = getGenDex($general, $general['crewtype']);
$genDexDef = getGenDex($general, 40);
$cityCrew *= getDexLog($genDexAtt, ($admin['city_rate']-60)*7200);
$myCrew *= getDexLog(($admin['city_rate']-60)*7200, $genDexDef);
$cityCrew *= $generalCrewType->getAttackCoef($opposeCrewType);
$myCrew *= $generalCrewType->getDefenceCoef($opposeCrewType);
$avoid = 1;
// 병종간 특성
if($generalCrewType->magicCoef) {
$int = Util::round(getGeneralIntel($general, true, true, true, false));
$ratio2 = $int / 100 * $generalCrewType->magicCoef;
// 특기보정 : 신산
if($general['special2'] == 41) { $ratio2 += 0.2; }
if(Util::randBool($ratio2)) {
$ratio = rand() % 100; // 0~99
// 특기보정 : 귀병, 신산, 환술, 신중
if($general['special2'] == 40) { $ratio += 20; }
if($general['special2'] == 41) { $ratio += 20; }
if($general['special2'] == 42) { $ratio += 10; }
if($general['special2'] == 44) { $ratio += 100; }
if($ratio >= 30) {
// 특기보정 : 환술, 집중
if($general['special2'] == 42) { $cityCrew *= 1.3; }
if($general['special2'] == 43) { $cityCrew *= 1.5; }
$type = rand() % 3;
switch($type) {
case 0:
$batlog[] = "<C>●</><D>급습</>을 <C>성공</>했다!";
$cityCrew *= 1.2;
break;
case 1:
$batlog[] = "<C>●</><D>위보</>를 <C>성공</>했다!";
$cityCrew *= 1.4;
break;
case 2:
$batlog[] = "<C>●</><D>혼란</>을 <C>성공</>했다!";
$cityCrew *= 1.6;
break;
}
} else {
$type = rand() % 3;
switch($type) {
case 0:
$batlog[] = "<C>●</><D>급습</>을 <R>실패</>했다!";
$cityCrew /= 1.2; $myCrew *= 1.2;
break;
case 1:
$batlog[] = "<C>●</><D>위보</>를 <R>실패</>했다!";
$cityCrew /= 1.4; $myCrew *= 1.4;
break;
case 2:
$batlog[] = "<C>●</><D>혼란</>을 <R>실패</>했다!";
$cityCrew /= 1.6; $myCrew *= 1.6;
break;
}
}
}
}
//군주 공격 보정 10%
if($general['level'] == 12) {
$cityCrew = $cityCrew * 1.10;
//참모, 장군 공격 보정 5%
} elseif($general['level'] == 11 || $general['level'] == 10 || $general['level'] == 8 || $general['level'] == 6) {
$cityCrew = $cityCrew * 1.05;
}
//레벨 보정
$cityCrew = $cityCrew * (100 + $general['explevel']/6)/100;
// 특기보정 : 공성, 기병, 돌격, 무쌍, 보병, 견고, 의술(청낭서,태평청령)
if($general['special2'] == 53) { $cityCrew *= 2.00; }
if($general['special2'] == 52) { $cityCrew *= 1.20; }
if($general['special2'] == 60) { $cityCrew *= 1.10; }
if($general['special2'] == 61) { $cityCrew *= 1.10; }
if($general['special2'] == 50) { $myCrew *= 0.90; }
if($general['special2'] == 62) { $myCrew *= 0.90; }
$ratio = rand() % 100; // 0 ~ 99
if(($general['special2'] == 73 || $general['item'] == 23 || $general['item'] == 24) && $ratio > 80 && $avoid == 1) {
$batlog[] = "<C>●</><C>치료</>했다!</>";
$myCrew /= 1.5; // 66%만 소모
$avoid = 0;
}
//크리
$rd = rand() % 100; // 0 ~ 99
$ratio = $generalCrewType->getCriticalRatio($general);
// 특기보정 : 무쌍, 필살
if($general['special2'] == 61) { $ratio += 10; }
if($general['special2'] == 71) { $ratio += 20; }
if($ratio >= $rd && $avoid == 1) {
$batlog[] = "<C>●</><C>필살</>공격!</>";
$cityCrew = CriticalScore2($cityCrew);
$avoid = 0;
}
//회피
$ratio = rand() % 100; // 0 ~ 99
$ratio2 = $generalCrewType->avoid; //회피율
$ratio2 = Util::round($ratio2 * $general['train'] / 100); //훈련 반영
//특기보정 : 궁병
if($general['special2'] == 51) { $ratio2 += 20; }
//도구 보정 : 둔갑천서, 태평요술
if($general['item'] == 26 || $general['item'] == 25) { $ratio2 += 20; }
LogText('avoid0', [date("Ymd_His"), $generalCrewType->id, $general['train'], $ratio2]);
if($ratio < $ratio2 && $avoid == 1) {
LogText('avoid0', true);
$batlog[] = "<C>●</><C>회피</>했다!</>";
$myCrew /= 5; // 20%만 소모
$avoid = 0;
}
//랜타추가
$cityCrew *= (rand() % 21 + 90)/100; // 90~110%
$myCrew *= (rand() % 21 + 90)/100; // 90~110%
//특기보정 : 위압
if($general['special2'] == 63 && $phase == 1 && $general['crew'] >= 1000 && $general['atmos'] >= 90 && $general['train'] >= 90) {
$batlog[] = "<C>●</>상대에게 <C>위압</>을 줬다!</>";
$myCrew = 0;
}
$general['crew'] -= Util::round($myCrew);
$city['def'] -= Util::round($cityCrew);
$city['wall'] -= Util::round($cityCrew);
$tempMyCrew = $myCrew; $tempCityCrew = $cityCrew;
$tempGeneralCrew = $general['crew']; $tempCityDef = $city['def'];
if($city['wall'] <= 0) { $city['wall'] = 0; }
if($general['crew'] <= 0 && $city['def'] <= 0) {
$r1 = $tempGeneralCrew / $tempMyCrew;
$r2 = $tempCityDef / $tempCityCrew;
if($r1 > $r2) {
$offset = Util::round($tempCityDef*$tempMyCrew/$tempCityCrew);
$myCrew += $offset;
$general['crew'] -= $offset;
$cityCrew += $tempCityDef;
$city['def'] = 0;
} else {
$offset = Util::round($tempGeneralCrew*$tempCityCrew/$tempMyCrew);
$cityCrew += $offset;
$city['def'] -= $offset;
$myCrew += $tempGeneralCrew;
$general['crew'] = 0;
}
} elseif($general['crew'] * $city['def'] <= 0) {
if($city['def'] < 0) {
$offset = Util::round($tempCityDef*$tempMyCrew/$tempCityCrew);
$myCrew += $offset;
$general['crew'] -= $offset;
$cityCrew += $tempCityDef;
$city['def'] = 0;
}
if($general['crew'] < 0) {
$offset = Util::round($tempGeneralCrew*$tempCityCrew/$tempMyCrew);
$cityCrew += $offset;
$city['def'] -= $offset;
$myCrew += $tempGeneralCrew;
$general['crew'] = 0;
}
}
$exp += $cityCrew;
$opexp += $myCrew;
$general['crew'] = Util::round($general['crew']);
$cityCrew = Util::round($cityCrew);
$myCrew = Util::round($myCrew);
$batlog[] = "<C>●</> $phase : <Y1>【{$general['name']}】</> <C>{$general['crew']} (-$myCrew)</> VS <C>{$city['def']} (-$cityCrew)</> <Y1>【{$city['name']}】</>";
$mykillnum += $cityCrew; $mydeathnum += $myCrew;
// 중간 쌀 체크
$myRice = Util::round($exp / 50);
// 성격 보정
$myRice = CharExperience($myRice, $general['personal']);
// 쌀 소모
$myRice = ($myRice * 5 * getCrewtypeRice($generalCrewType, $nation['tech']));
// 결과 쌀
$myRice = $general['rice'] - $myRice;
if($myRice <= Util::round($general['crew']/100)) { break; }
if($city['def'] <= 0) { break; }
if($general['crew'] <= 0) { break; }
}
$render_attacker = [
'crewtype' => mb_substr($generalCrewType->name, 0, 2),
'name'=> $general['name'],
'remain_crew' => $general['crew'],
'killed_crew' => -$mydeathnum
];
$render_defender = [
'crewtype' => '성벽',
'name'=> $city['name'],
'remain_crew' => $city['def'],
'killed_crew' => -$mykillnum
];
$res = str_replace(["\r\n", "\r", "\n"], '', $templates->render('small_war_log',[
'year'=>$year,
'month'=>$month,
'war_type'=>'siege',
'war_type_str'=>'→',
'me' => $render_attacker,
'you' => $render_defender,
]));
$log[] = $res;//TODO: $log를 출력할 때 date에 대해선 숨겨야 함.
$batlog[] = $res;
$batres[] = $res;
$deadAmount['att'] = $deadAmount['att'] + $mydeathnum;
$deadAmount['def'] = $deadAmount['def'] + $mykillnum;
// 도시쌀 소모 계산
$opexp = Util::round($opexp / 50 * 0.8);
$rice = Util::round($opexp * 5 * getCrewtypeRice($opposeCrewType, 0) * ($admin['city_rate']/100 - 0.2));
$destnation['rice'] -= $rice;
if($destnation['rice'] < 0) { $destnation['rice'] = 0; }
$query = "update nation set rice='{$destnation['rice']}' where nation='{$destnation['nation']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
pushAdminLog(["성벽 쌀 소모 : $rice"]);
//원래대로 스케일링
$city['def'] = Util::round($city['def'] / 10);
$city['wall'] = Util::round($city['wall'] / 10);
//내정 감소
$dec = Util::round($cityCrew / 10);
$city['agri'] -= $dec;
$city['comm'] -= $dec;
$city['secu'] -= $dec;
if($city['agri'] < 0) { $city['agri'] = 0; }
if($city['comm'] < 0) { $city['comm'] = 0; }
if($city['secu'] < 0) { $city['secu'] = 0; }
// 병사수 변경
$query = "update general set crew='{$general['crew']}',killcrew=killcrew+'$mykillnum',deathcrew=deathcrew+'$mydeathnum' where no='{$general['no']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
// 숙련도 증가
addGenDex($general['no'], $general['atmos'], $general['train'], $general['crewtype'], $mykillnum);
addGenDex($general['no'], $general['atmos'], $general['train'], 40, $mydeathnum);
// 죽은수 기술로 누적
$num = Util::round($mydeathnum * 0.01);
// 국가보정
if($nation['type'] == 3 || $nation['type'] == 13) { $num *= 1.1; }
if($nation['type'] == 5 || $nation['type'] == 6 || $nation['type'] == 7 || $nation['type'] == 8 || $nation['type'] == 12) { $num *= 0.9; }
// 부드러운 기술 제한
if(TechLimit($admin['startyear'], $year, $nation['tech'])) { $num = intdiv($num, 4); }
$query = "update nation set totaltech=totaltech+'$num',tech=totaltech/'$gencount' where nation='{$nation['nation']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
// 죽은수 기술로 누적
$num = Util::round($mykillnum * 0.01);
// 국가보정
if($destnation['type'] == 3 || $destnation['type'] == 13){
$num *= 1.1;
}
if($destnation['type'] == 5 || $destnation['type'] == 6 || $destnation['type'] == 7 || $destnation['type'] == 8 || $destnation['type'] == 12) {
$num *= 0.9;
}
// 부드러운 기술 제한
if(TechLimit($admin['startyear'], $year, $destnation['tech'])) { $num = intdiv($num, 4); }
$query = "update nation set totaltech=totaltech+'$num',tech=totaltech/'$destgencount' where nation='{$destnation['nation']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
//양국 평균 기술가격
//$techRatio = (getTechCost($nation['tech']) + getTechCost($destnation['tech'])) / 2;
$techRatio = 1.0;
// 죽은수 도시 재정으로 누적 60%
$num = Util::round(($mykillnum+$mydeathnum) * 0.6 * $techRatio);
// 국가보정
if($destnation['type'] == 1) { $num *= 1.1; }
if($destnation['type'] == 9 || $destnation['type'] == 10) { $num *= 0.9; }
$query = "update city set dead=dead+'$num',def='{$city['def']}',wall='{$city['wall']}',agri='{$city['agri']}',comm='{$city['comm']}',secu='{$city['secu']}' where city='{$city['city']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
// 죽은수 도시 재정으로 누적 40%
$num = Util::round(($mykillnum+$mydeathnum) * 0.4 * $techRatio);
// 국가보정
if($nation['type'] == 1) { $num *= 1.1; }
if($nation['type'] == 9 || $nation['type'] == 10) { $num *= 0.9; }
$query = "update city set dead=dead+'$num' where city='{$general['city']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
//분쟁현황에 추가
$city = addConflict($city, $general['nation'], $mykillnum);
// 병사 소진시 성 함락
if($city['def'] <= 0) {
$exp += 1000;
$exp2++;
pushGenLog($general, $log);
pushBatLog($general, $batlog);
pushBatRes($general, $batres);
pushGeneralPublicRecord($alllog, $year, $month);
pushWorldHistory($history, $year, $month);
$log = [];
$batlog = [];
$batres = [];
$alllog = [];
$history = [];
ConquerCity($admin, $general, $city, $nation, $destnation);
break;
// 공격 장수 병사 소진시 실패 처리
} elseif($general['crew'] <= 0) {
$josaYi = JosaUtil::pick($generalCrewType->name, '이');
$alllog[] = "<C>●</>{$month}월:<Y>{$general['name']}</>의 {$generalCrewType->name}{$josaYi} 퇴각했습니다.";
$log[] = "<C>●</>퇴각했습니다.";
$query = "update general set deathnum=deathnum+1 where no='{$general['no']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
break;
} elseif($myRice <= Util::round($general['crew']/100)) {
$josaYi = JosaUtil::pick($generalCrewType->name, '이');
$alllog[] = "<C>●</>{$month}월:<Y>{$general['name']}</>의 {$generalCrewType->name}{$josaYi} 퇴각했습니다.";
$log[] = "<C>●</>군량 부족으로 퇴각합니다.";
$query = "update general set deathnum=deathnum+1 where no='{$general['no']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
break;
}
// 장수 대결
} else {
$oppose = MYDB_fetch_array($result);
setLeadershipBonus($oppose, $destnation['level']);
$opposeCrewType = GameUnitConst::byId($oppose['crewtype']);
$josaYi = JosaUtil::pick($opposeCrewType->name, '이');
$josaWa = JosaUtil::pick($generalCrewType->name, '와');
$alllog[] = "<C>●</>{$month}월:<Y>{$general['name']}</>의 ".$generalCrewType->name."{$josaWa} <Y>{$oppose['name']}</>의 ".$opposeCrewType->name."{$josaYi} 대결합니다.";
$josaUl = JosaUtil::pick($opposeCrewType->name, '을');
$josaRo = JosaUtil::pick($generalCrewType->name, '로');
$log[] = "<C>●</>".$generalCrewType->name."{$josaRo} <Y>{$oppose['name']}</>의 ".$opposeCrewType->name."{$josaUl} <M>공격</>합니다.";
$josaUl = JosaUtil::pick($generalCrewType->name, '을');
$opplog[] = "<C>●</>".$opposeCrewType->name."{$josaRo} <Y>{$general['name']}</>의 ".$generalCrewType->name."{$josaUl} <M>수비</>합니다.";
$oppAtmos = 0;
if($oppose['item'] == 3) {
//탁주 사용
$oppAtmos += 3;
$query = "update general set item=0 where no='{$oppose['no']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$josaUl = JosaUtil::pick($oppose['item'], '을');
$opplog[] = "<C>●</><C>".getItemName($oppose['item'])."</>{$josaUl} 사용!";
$oppose['item'] = 0;
} elseif($oppose['item'] >= 14 && $oppose['item'] <= 16) {
//의적주, 두강주, 보령압주 사용
$oppAtmos += 5;
} elseif($oppose['item'] >= 19 && $oppose['item'] <= 20) {
//춘화첩, 초선화 사용
$oppAtmos += 7;
}
$oppTrain = 0;
if($oppose['item'] == 4) {
//청주 사용
$oppTrain += 3;
$query = "update general set item=0 where no='{$oppose['no']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$josaUl = JosaUtil::pick($oppose['item'], '을');
$opplog[] = "<C>●</><C>".getItemName($oppose['item'])."</>{$josaUl} 사용!";
$oppose['item'] = 0;
} elseif($oppose['item'] >= 12 && $oppose['item'] <= 13) {
//과실주, 이강주 사용
$oppTrain += 5;
} elseif($oppose['item'] >= 17 && $oppose['item'] <= 18) {
//철벽서, 단결도 사용
$oppTrain += 7;
}
$general['train'] += 1; //훈련 상승
if($general['train'] > GameConst::$maxTrainByWar) { $general['train'] = GameConst::$maxTrainByWar; }
$oppose['train'] += 1; //훈련 상승
if($oppose['train'] > GameConst::$maxTrainByWar) { $oppose['train'] = GameConst::$maxTrainByWar; }
$query = "update general set recwar='{$general['turntime']}',train='{$general['train']}',warnum=warnum+1 where no='{$general['no']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$query = "update general set recwar='{$general['turntime']}',train='{$oppose['train']}',warnum=warnum+1 where no='{$oppose['no']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
//특기보정 : 저격(수극), 활무기저격
$snipe = false;
$snipeItem = false;
if(!$snipe && $general['special2'] == 70 && Util::randBool(1/3)){
$snipe = true;
}
if(!$snipe && in_array($general['weap'], [10, 14, 18, 22]) && Util::randBool(1/5)){
$snipe = true;
}
if(!$snipe && $general['item'] == 2){
if(Util::randBool(1/5)){
$snipe = true;
$snipeItem = true;
}
//수극을 사용했지만 저격 실패한 케이스도 '필요하면' 넣을 것.(밸런스)
}
if($snipe) {
//수극 사용
if($snipeItem) {
$josaUl = JosaUtil::pick($general['item'], '을');
$log[] = "<C>●</><C>".getItemName($general['item'])."</>{$josaUl} 사용!";
$general['item'] = 0;
$db->update('general', ['item'=>0], 'no=%i', $general['no']);
}
$log[] = "<C>●</>상대를 <C>저격</>했다!";
$batlog[] = "<C>●</>상대를 <C>저격</>했다!";
$opplog[] = "<C>●</>상대에게 <R>저격</>당했다!";
$oppbatlog[] = "<C>●</>상대에게 <R>저격</>당했다!";
// 부상
$oppose['injury'] += rand() % 41 + 20; // 20 ~ 60
if($oppose['injury'] > 80) { $oppose['injury'] = 80; }
}
else if($snipeItem) {
$db->update('general', ['item'=>0], 'no=%i', $general['no']);
$josaYi = JosaUtil::pick($general['item'], '이');
$batlog[] = "<C>●</><C>".getItemName($general['item'])."</>{$josaYi} 빗나갑니다!";
$general['item'] = 0;
}
//특기보정 : 저격(수극), 활무기저격
$snipe = false;
$snipeItem = false;
if(!$snipe && $oppose['special2'] == 70 && Util::randBool(1/3)){
$snipe = true;
}
if(!$snipe && in_array($oppose['weap'], [10, 14, 18, 22]) && Util::randBool(1/5)){
$snipe = true;
}
if(!$snipe && $oppose['item'] == 2){
if(Util::randBool(1/5)){
$snipe = true;
$snipeItem = true;
}
//수극을 사용했지만 저격 실패한 케이스도 '필요하면' 넣을 것.(밸런스)
}
if($snipe) {
//수극 사용
if($snipeItem) {
$josaUl = JosaUtil::pick($oppose['item'], '을');
$log[] = "<C>●</><C>".getItemName($oppose['item'])."</>{$josaUl} 사용!";
$oppose['item'] = 0;
$db->update('general', ['item'=>0], 'no=%i', $oppose['no']);
}
$oppbatlog[] = "<C>●</>상대를 <C>저격</>했다!";
$opplog[] = "<C>●</>상대를 <C>저격</>했다!";
$batlog[] = "<C>●</>상대에게 <R>저격</>당했다!";
$log[] = "<C>●</>상대에게 <R>저격</>당했다!";
// 부상
$general['injury'] += rand() % 41 + 20; // 20 ~ 60
if($general['injury'] > 80) { $general['injury'] = 80; }
}
else if($snipeItem) {
$db->update('general', ['item'=>0], 'no=%i', $oppose['no']);
$josaYi = JosaUtil::pick($oppose['item'], '이');
$batlog[] = "<C>●</><C>".getItemName($oppose['item'])."</>{$josaYi} 빗나갑니다!";
$oppose['item'] = 0;
}
$mykillnum = 0; $mydeathnum = 0;
$opkillnum = 0; $opdeathnum = 0;
while($phase < $warphase) {
$phase++;
$myAtt = $generalCrewType->getComputedAttack($general, $nation['tech']);
$myDef = $generalCrewType->getComputedDefence($general, $nation['tech']);
$opAtt = $opposeCrewType->getComputedAttack($oppose, $destnation['tech']);
$opDef = $opposeCrewType->getComputedAttack($oppose, $destnation['tech']);
// 감소할 병사 수
$myCrew = GameConst::$armperphase + $opAtt - $myDef;
$opCrew = GameConst::$armperphase + $myAtt - $opDef;
if($myCrew <= 0) { $myCrew = rand() % 90 + 10; }
if($opCrew <= 0) { $opCrew = rand() % 90 + 10; }
//훈련 사기따라
$myCrew = getCrew($myCrew, CharAtmos($oppose['atmos']+$oppAtmos+$oppAtmosBonus, $oppose['personal']), CharTrain($general['train']+$genTrain+$genTrainBonus, $general['personal']));
$opCrew = getCrew($opCrew, CharAtmos($general['atmos']+$genAtmos+$genAtmosBonus, $general['personal']), CharTrain($oppose['train']+$oppTrain+$oppTrainBonus, $oppose['personal']));
//숙련도 따라
$genDexAtt = getGenDex($general, $general['crewtype']);
$genDexDef = getGenDex($general, $oppose['crewtype']);
$oppDexAtt = getGenDex($oppose, $oppose['crewtype']);
$oppDexDef = getGenDex($oppose, $general['crewtype']);
$opCrew *= getDexLog($genDexAtt, $oppDexDef);
$myCrew *= getDexLog($oppDexAtt, $genDexDef);
$myAvoid = 1;
$opAvoid = 1;
// 병종간 특성
if($generalCrewType->magicCoef) {
$int = Util::round(getGeneralIntel($general, true, true, true, false));
$ratio2 = $int / 100 * $generalCrewType->magicCoef;
// 특기보정 : 신산
if($general['special2'] == 41) { $ratio2 += 0.2; }
if(Util::randBool($ratio2)) {
$ratio = rand() % 100;
// 특기보정 : 귀병, 신산, 환술, 신중
if($general['special2'] == 40) { $ratio += 20; }
if($general['special2'] == 41) { $ratio += 20; }
if($general['special2'] == 42) { $ratio += 10; }
if($general['special2'] == 44) { $ratio += 100; }
if($ratio >= 30) {
// 특기보정 : 환술, 집중
if($general['special2'] == 42) { $opCrew *= 1.3; }
if($general['special2'] == 43) { $opCrew *= 1.5; }
$type = rand() % 5; // 0~4
switch($type) {
case 0:
$ratio = rand() % 100;
// 특기보정 : 반계
if($oppose['special2'] == 45 && $ratio > 70) {
$batlog[] = "<C>●</><D>위보</>를 <R>역으로</> 당했다!";
$oppbatlog[] = "<C>●</><C>반계</>로 상대의 <D>위보</>를 되돌렸다!";
$myCrew *= 1.2;
} else {
$batlog[] = "<C>●</><D>위보</>를 <C>성공</>했다!";
$oppbatlog[] = "<C>●</><D>위보</>에 당했다!";
$opCrew *= 1.2;
}
break;
case 1:
$ratio = rand() % 100;
// 특기보정 : 반계
if($oppose['special2'] == 45 && $ratio > 70) {
$batlog[] = "<C>●</><D>매복</>을 <R>역으로</> 당했다!";
$oppbatlog[] = "<C>●</><C>반계</>로 상대의 <D>매복</>을 되돌렸다!";
$myCrew *= 1.4;
} else {
$batlog[] = "<C>●</><D>매복</>을 <C>성공</>했다!";
$oppbatlog[] = "<C>●</><D>매복</>에 당했다!";
$opCrew *= 1.4;
}
break;
case 2:
$ratio = rand() % 100;
// 특기보정 : 반계
if($oppose['special2'] == 45 && $ratio > 70) {
$batlog[] = "<C>●</><D>반목</>을 <R>역으로</> 당했다!";
$oppbatlog[] = "<C>●</><C>반계</>로 상대의 <D>반목</>을 되돌렸다!";
$myCrew *= 1.6;
} else {
$batlog[] = "<C>●</><D>반목</>을 <C>성공</>했다!";
$oppbatlog[] = "<C>●</><D>반목</>에 당했다!";
$opCrew *= 1.6;
// 특기보정 : 반계
if($general['special2'] == 45) { $opCrew *= 2; }
}
break;
case 3:
$ratio = rand() % 100;
// 특기보정 : 반계
if($oppose['special2'] == 45 && $ratio > 70) {
$batlog[] = "<C>●</><D>화계</>를 <R>역으로</> 당했다!";
$oppbatlog[] = "<C>●</><C>반계</>로 상대의 <D>화계</>를 되돌렸다!";
$myCrew *= 1.8;
} else {
$batlog[] = "<C>●</><D>화계</>를 <C>성공</>했다!";
$oppbatlog[] = "<C>●</><D>화계</>에 당했다!";
$opCrew *= 1.8;
}
break;
case 4:
$ratio = rand() % 100;
// 특기보정 : 반계
if($oppose['special2'] == 45 && $ratio > 70) {
$batlog[] = "<C>●</><D>혼란</>을 <R>역으로</> 당했다!";
$oppbatlog[] = "<C>●</><C>반계</>로 상대의 <D>혼란</>을 되돌렸다!";
$myCrew *= 2.0;
} else {
$batlog[] = "<C>●</><D>혼란</>을 <C>성공</>했다!";
$oppbatlog[] = "<C>●</><D>혼란</>에 당했다!";
$opCrew *= 2.0;
}
break;
}
} else {
$type = rand() % 5; // 0~4
switch($type) {
case 0:
$batlog[] = "<C>●</><D>위보</>를 <R>실패</>했다!";
$oppbatlog[] = "<C>●</><D>위보</>를 간파했다!";
$opCrew /= 1.1; $myCrew *= 1.1;
break;
case 1:
$batlog[] = "<C>●</><D>매복</>을 <R>실패</>했다!";
$oppbatlog[] = "<C>●</><D>매복</>을 간파했다!";
$opCrew /= 1.2; $myCrew *= 1.2;
break;
case 2:
$batlog[] = "<C>●</><D>반목</>을 <R>실패</>했다!";
$oppbatlog[] = "<C>●</><D>반목</>을 간파했다!";
$opCrew /= 1.3; $myCrew *= 1.3;
break;
case 3:
$batlog[] = "<C>●</><D>화계</>를 <R>실패</>했다!";
$oppbatlog[] = "<C>●</><D>화계</>를 간파했다!";
$opCrew /= 1.4; $myCrew *= 1.4;
break;
case 4:
$batlog[] = "<C>●</><D>혼란</>을 <R>실패</>했다!";
$oppbatlog[] = "<C>●</><D>혼란</>을 간파했다!";
$opCrew /= 1.5; $myCrew *= 1.5;
break;
}
}
}
}
// 상대 장수 병종간 특성
if($opposeCrewType->magicCoef) {
$int = Util::round(getGeneralIntel($oppose, true, true, true, false));
$ratio2 = $int / 100 * $opposeCrewType->magicCoef;
// 특기보정 : 신산
if($oppose['special2'] == 41) { $ratio2 += 0.2; }
if(Util::randBool($ratio2)) {
$ratio = rand() % 100;
// 특기보정 : 귀병, 신산, 환술, 신중
if($oppose['special2'] == 40) { $ratio += 20; }
if($oppose['special2'] == 41) { $ratio += 20; }
if($oppose['special2'] == 42) { $ratio += 10; }
if($oppose['special2'] == 44) { $ratio += 100; }
if($ratio >= 30) {
// 특기보정 : 환술, 집중
if($oppose['special2'] == 42) { $myCrew *= 1.3; }
if($oppose['special2'] == 43) { $myCrew *= 1.5; }
$type = rand() % 5; // 0~4
switch($type) {
case 0:
$ratio = rand() % 100;
// 특기보정 : 반계
if($general['special2'] == 45 && $ratio > 70) {
$oppbatlog[] = "<C>●</><D>위보</>를 <R>역으로</> 당했다!";
$batlog[] = "<C>●</><C>반계</>로 상대의 <D>위보</>를 되돌렸다!";
$opCrew *= 1.2;
} else {
$oppbatlog[] = "<C>●</><D>위보</>를 <C>성공</>했다!";
$batlog[] = "<C>●</><D>위보</>에 당했다!";
$myCrew *= 1.2;
}
break;
case 1:
$ratio = rand() % 100;
// 특기보정 : 반계
if($general['special2'] == 45 && $ratio > 70) {
$oppbatlog[] = "<C>●</><D>매복</>을 <R>역으로</> 당했다!";
$batlog[] = "<C>●</><C>반계</>로 상대의 <D>매복</>을 되돌렸다!";
$opCrew *= 1.4;
} else {
$oppbatlog[] = "<C>●</><D>매복</>을 <C>성공</>했다!";
$batlog[] = "<C>●</><D>매복</>에 당했다!";
$myCrew *= 1.4;
}
break;
case 2:
$ratio = rand() % 100;
// 특기보정 : 반계
if($general['special2'] == 45 && $ratio > 70) {
$oppbatlog[] = "<C>●</><D>반목</>을 <R>역으로</> 당했다!";
$batlog[] = "<C>●</><C>반계</>로 상대의 <D>반목</>을 되돌렸다!";
$opCrew *= 1.6;
} else {
$oppbatlog[] = "<C>●</><D>반목</>을 <C>성공</>했다!";
$batlog[] = "<C>●</><D>반목</>에 당했다!";
$myCrew *= 1.6;
// 특기보정 : 반계
if($oppose['special2'] == 45) { $myCrew *= 2; }
}
break;
case 3:
$ratio = rand() % 100;
// 특기보정 : 반계
if($general['special2'] == 45 && $ratio > 70) {
$oppbatlog[] = "<C>●</><D>화계</>를 <R>역으로</> 당했다!";
$batlog[] = "<C>●</><C>반계</>로 상대의 <D>화계</>을 되돌렸다!";
$opCrew *= 1.8;
} else {
$oppbatlog[] = "<C>●</><D>화계</>를 <C>성공</>했다!";
$batlog[] = "<C>●</><D>화계</>에 당했다!";
$myCrew *= 1.8;
}
break;
case 4:
$ratio = rand() % 100;
// 특기보정 : 반계
if($general['special2'] == 45 && $ratio > 70) {
$oppbatlog[] = "<C>●</><D>혼란</>을 <R>역으로</> 당했다!";
$batlog[] = "<C>●</><C>반계</>로 상대의 <D>혼란</>을 되돌렸다!";
$opCrew *= 2.0;
} else {
$oppbatlog[] = "<C>●</><D>혼란</>을 <C>성공</>했다!";
$batlog[] = "<C>●</><D>혼란</>에 당했다!";
$myCrew *= 2.0;
}
break;
}
} else {
$type = rand() % 5; // 0~4
switch($type) {
case 0:
$oppbatlog[] = "<C>●</><D>위보</>를 <R>실패</>했다!";
$batlog[] = "<C>●</><D>위보</>를 간파했다!";
$myCrew /= 1.1; $opCrew *= 1.1;
break;
case 1:
$oppbatlog[] = "<C>●</><D>매복</>을 <R>실패</>했다!";
$batlog[] = "<C>●</><D>매복</>을 간파했다!";
$myCrew /= 1.2; $opCrew *= 1.2;
break;
case 2:
$oppbatlog[] = "<C>●</><D>반목</>을 <R>실패</>했다!";
$batlog[] = "<C>●</><D>반목</>을 간파했다!";
$myCrew /= 1.3; $opCrew *= 1.3;
break;
case 3:
$oppbatlog[] = "<C>●</><D>화계</>를 <R>실패</>했다!";
$batlog[] = "<C>●</><D>화계</>를 간파했다!";
$myCrew /= 1.4; $opCrew *= 1.4;
break;
case 4:
$oppbatlog[] = "<C>●</><D>혼란</>을 <R>실패</>했다!";
$batlog[] = "<C>●</><D>혼란</>을 간파했다!";
$myCrew /= 1.5; $opCrew *= 1.5;
break;
}
}
}
}
// 특기보정: 돌격
//XXX: 목우!!!!
if($oppose['crewtype'] == 43 && $general['special2'] != 60) { // 목우
$r = 0;
$r += $oppose['atmos'] + $oppAtmos + $oppAtmosBonus;
$r += $oppose['train'] + $oppTrain + $oppTrainBonus;
$ratio = rand() % 400; // 최대 50% 저지
if($ratio < $r && $opAvoid == 1) {
$batlog[] = "<C>●</><R>저지</>당했다!</>";
$oppbatlog[] = "<C>●</>상대를 <C>저지</>했다!</>";
$opAvoid = 0;
continue;
}
}
$opCrew *= $generalCrewType->getAttackCoef($opposeCrewType);
$myCrew *= $generalCrewType->getDefenceCoef($opposeCrewType);
//군주 공격 보정 10%
if($general['level'] == 12) {
$opCrew = $opCrew * 1.10;
//참모, 장군 공격 보정 5%
} elseif($general['level'] == 11 || $general['level'] == 10 || $general['level'] == 8 || $general['level'] == 6) {
$opCrew = $opCrew * 1.05;
}
//상대장수 관직 보정
//군주 방어 보정 10%
if($oppose['level'] == 12) {
$opCrew = $opCrew * 0.90;
//참모, 모사 방어 보정 5%
} elseif($oppose['level'] == 11 || $oppose['level'] == 9 || $oppose['level'] == 7 || $oppose['level'] == 5) {
$opCrew = $opCrew * 0.95;
} elseif($oppose['level'] == 4 && $oppose['no'] == $city['gen1']) { // 태수 보정
$opCrew = $opCrew * 0.95;
} elseif($oppose['level'] == 3 && $oppose['no'] == $city['gen2']) { // 군사 보정
$opCrew = $opCrew * 0.95;
} elseif($oppose['level'] == 2 && $oppose['no'] == $city['gen3']) { // 시중 보정
$opCrew = $opCrew * 0.95;
}
//레벨 보정
$myCrew = $myCrew * (max(1, 100 - $general['explevel']/3)/100);
$opCrew = $opCrew / (max(1, 100 - $general['explevel']/3)/100);
$myCrew = $myCrew / (max(1, 100 - $oppose['explevel']/3)/100);
$opCrew = $opCrew * (max(1, 100 - $oppose['explevel']/3)/100);
// 특기보정 : 기병, 돌격, 무쌍, 보병, 견고, 척사, 의술(청낭서, 태평청령)
if($general['special2'] == 52) { $opCrew *= 1.20; }
if($general['special2'] == 60) { $opCrew *= 1.10; }
if($general['special2'] == 61) { $opCrew *= 1.10; }
if($general['special2'] == 50) { $myCrew *= 0.90; }
if($general['special2'] == 62) { $myCrew *= 0.90; }
if($general['special2'] == 75) {
if($opposeCrewType->reqCities || $opposeCrewType->reqRegions)
{
$opCrew *= 1.1; $myCrew *= 0.9;
}
}
$ratio = rand() % 100; // 0 ~ 99
if(($general['special2'] == 73 || $general['item'] == 23 || $general['item'] == 24) && $ratio > 80 && $myAvoid == 1) {
$batlog[] = "<C>●</><C>치료</>했다!</>";
$myCrew /= 1.5; // 66%만 소모
$myAvoid = 0;
}
// 상대 특기보정 : 기병, 무쌍, 보병, 견고, 척사, 의술(청낭서, 태평청령)
if($oppose['special2'] == 52) { $myCrew *= 1.10; }
if($oppose['special2'] == 61) { $myCrew *= 1.10; }
if($oppose['special2'] == 50) { $opCrew *= 0.80; }
if($oppose['special2'] == 62) { $myCrew *= 1.10; }
if($oppose['special2'] == 75) {
if($generalCrewType->reqCities || $generalCrewType->reqRegions)
{
$myCrew *= 1.1; $opCrew *= 0.9;
}
}
$ratio = rand() % 100; // 0 ~ 99
if(($oppose['special2'] == 73 || $oppose['item'] == 23 || $oppose['item'] == 24) && $ratio > 80 && $opAvoid == 1) {
$oppbatlog[] = "<C>●</><C>치료</>했다!</>";
$opCrew /= 1.5; // 66%만 소모
$opAvoid = 0;
}
//크리
$rd = rand() % 100; // 0 ~ 99
$ratio = $generalCrewType->getCriticalRatio($general);
// 특기보정 : 무쌍, 필살
if($general['special2'] == 61) { $ratio += 10; }
if($general['special2'] == 71) { $ratio += 20; }
if($ratio >= $rd && $myAvoid == 1) {
$batlog[] = "<C>●</><C>필살</>공격!</>";
$oppbatlog[] = "<C>●</>상대의 <R>필살</>공격!</>";
$opCrew = CriticalScore2($opCrew);
$myAvoid = 0;
// 특기보정 : 격노
if($oppose['special2'] == 74) {
if(rand() % 100 < 50) {
$batlog[] = "<C>●</>필살 공격에 상대가 <R>격노</>했다!</>";
$oppbatlog[] = "<C>●</>상대의 필살 공격에 <C>격노</>했다!</>";
$myCrew = CriticalScore2($myCrew);
$opAvoid = 0;
}
}
}
//크리
$rd = rand() % 100; // 0 ~ 99
$ratio = $opposeCrewType->getCriticalRatio($oppose);
// 특기보정 : 필살
if($oppose['special2'] == 71) { $ratio += 20; }
if($ratio >= $rd && $opAvoid == 1) {
$oppbatlog[] = "<C>●</><C>필살</>공격!</>";
$batlog[] = "<C>●</>상대의 <R>필살</>공격!</>";
$myCrew = CriticalScore2($myCrew);
$opAvoid = 0;
// 특기보정 : 격노
if($general['special2'] == 74) {
if(rand() % 100 < 33) {
$oppbatlog[] = "<C>●</>필살 공격에 상대가 <R>진노</>했다!</>";
$batlog[] = "<C>●</>상대의 필살 공격에 <C>진노</>했다!</>";
$opCrew = CriticalScore2($opCrew);
$myAvoid = 0;
$warphase++;
} elseif(rand() % 100 < 33) {
$oppbatlog[] = "<C>●</>필살 공격에 상대가 <R>격노</>했다!</>";
$batlog[] = "<C>●</>상대의 필살 공격에 <C>격노</>했다!</>";
$opCrew = CriticalScore2($opCrew);
$myAvoid = 0;
}
}
}
//회피
$ratio = rand() % 100; // 0 ~ 99
$ratio2 = $generalCrewType->avoid; //회피율
$ratio2 = Util::round($ratio2 * $general['train'] / 100); //훈련 반영
//특기보정 : 돌격, 궁병
if($oppose['special2'] == 60) { $ratio2 -= 100; }
if($general['special2'] == 51) { $ratio2 += 20; }
//도구 보정 : 둔갑천서, 태평요술
if($general['item'] == 26 || $general['item'] == 25) { $ratio2 += 20; }
LogText('avoid1', [date("Ymd_His"), $generalCrewType->id, $general['train'], $ratio2]);
if($ratio < $ratio2 && $myAvoid == 1) {
// 특기보정 : 격노
if($oppose['special2'] == 74 && rand() % 100 < 50) {
$batlog[] = "<C>●</>회피 시도에 상대가 <R>격노</>했다!</>";
$oppbatlog[] = "<C>●</>상대의 회피 시도에 <C>격노</>했다!</>";
$myCrew = CriticalScore2($myCrew);
$opAvoid = 0;
} else {
LogText('avoid1', true);
$batlog[] = "<C>●</><C>회피</>했다!</>";
$oppbatlog[] = "<C>●</>상대가 <R>회피</>했다!</>";
$myCrew /= 5; // 20%만 소모
$myAvoid = 0;
}
}
//회피
$ratio = rand() % 100; // 0 ~ 99
$ratio2 = $opposeCrewType->avoid; //회피율
$ratio2 = Util::round($ratio2 * $oppose['train'] / 100); //훈련 반영
// 특기보정 : 돌격, 궁병
if($general['special2'] == 60) { $ratio2 -= 100; }
if($oppose['special2'] == 51) { $ratio2 += 20; }
//도구 보정 : 둔갑천서, 태평요술
if($oppose['item'] == 26 || $oppose['item'] == 25) { $ratio2 += 20; }
LogText('avoid2', [date("Ymd_His"), $opposeCrewType->id, $oppose['train'], $ratio2]);
if($ratio < $ratio2 && $opAvoid == 1) {
// 특기보정 : 격노
if($general['special2'] == 74 && rand() % 100 < 33) {
$oppbatlog[] = "<C>●</>회피 시도에 상대가 <R>진노</>했다!</>";
$batlog[] = "<C>●</>상대의 회피 시도에 <C>진노</>했다!</>";
$opCrew = CriticalScore2($opCrew);
$myAvoid = 0;
$warphase++;
} elseif($general['special2'] == 74 && rand() % 100 < 33) {
$oppbatlog[] = "<C>●</>회피 시도에 상대가 <R>격노</>했다!</>";
$batlog[] = "<C>●</>상대의 회피 시도에 <C>격노</>했다!</>";
$opCrew = CriticalScore2($opCrew);
$myAvoid = 0;
} else {
LogText('avoid2', true);
$oppbatlog[] = "<C>●</><C>회피</>했다!</>";
$batlog[] = "<C>●</>상대가 <R>회피</>했다!</>";
$opCrew /= 5; // 20%만 소모
$opAvoid = 0;
}
}
//랜타추가
$opCrew *= (rand() % 21 + 90)/100; // 90~110%
$myCrew *= (rand() % 21 + 90)/100; // 90~110%
//특기보정 : 위압
if($general['special2'] == 63 && $phase == 1 && $general['crew'] >= 1000 && $general['atmos'] >= 90 && $general['train'] >= 90) {
$batlog[] = "<C>●</>상대에게 <C>위압</>을 줬다!</>";
$oppbatlog[] = "<C>●</>상대에게 <R>위압</>받았다!</>";
$myCrew = 0;
}
//특기보정: 위압
if($oppose['special2'] == 63 && $phase == 1 && $oppose['crew'] >= 1000 && $oppose['atmos'] >= 90 && $oppose['train'] >= 90) {
$batlog[] = "<C>●</>상대에게 <R>위압</>받았다!</>";
$oppbatlog[] = "<C>●</>상대에게 <C>위압</>을 줬다!</>";
$opCrew = 0;
}
$general['crew'] -= Util::round($myCrew);
$oppose['crew'] -= Util::round($opCrew);
$tempMyCrew = $myCrew; $tempOpCrew = $opCrew;
$tempGeneralCrew = $general['crew']; $tempOpposeCrew = $oppose['crew'];
if($general['crew'] <= 0 && $oppose['crew'] <= 0) {
$r1 = $tempGeneralCrew / $tempMyCrew;
$r2 = $tempOpposeCrew / $tempOpCrew;
if($r1 > $r2) {
$offset = Util::round($tempOpposeCrew*$tempMyCrew/$tempOpCrew);
$myCrew += $offset;
$general['crew'] -= $offset;
$opCrew += $tempOpposeCrew;
$oppose['crew'] = 0;
} else {
$offset = Util::round($tempGeneralCrew*$tempOpCrew/$tempMyCrew);
$opCrew += $offset;
$oppose['crew'] -= $offset;
$myCrew += $tempGeneralCrew;
$general['crew'] = 0;
}
} elseif($general['crew'] * $oppose['crew'] <= 0) {
if($oppose['crew'] < 0) {
$offset = Util::round($tempOpposeCrew*$tempMyCrew/$tempOpCrew);
$myCrew += $offset;
$general['crew'] -= $offset;
$opCrew += $tempOpposeCrew;
$oppose['crew'] = 0;
}
if($general['crew'] < 0) {
$offset = Util::round($tempGeneralCrew*$tempOpCrew/$tempMyCrew);
$opCrew += $offset;
$oppose['crew'] -= $offset;
$myCrew += $tempGeneralCrew;
$general['crew'] = 0;
}
}
$exp += $opCrew;
$opexp += $myCrew;
$general['crew'] = Util::round($general['crew']);
$oppose['crew'] = Util::round($oppose['crew']);
$myCrew = Util::round($myCrew);
$opCrew = Util::round($opCrew);
$batlog[] = "<C>●</> $phase : <Y1>【{$general['name']}】</> <C>{$general['crew']} (-$myCrew)</> VS <C>{$oppose['crew']} (-$opCrew)</> <Y1>【{$oppose['name']}】</>";
$oppbatlog[] = "<C>●</> $phase : <Y1>【{$oppose['name']}】</> <C>{$oppose['crew']} (-$opCrew)</> VS <C>{$general['crew']} (-$myCrew)</> <Y1>【{$general['name']}】</>";
$mykillnum += $opCrew; $mydeathnum += $myCrew;
$opkillnum += $myCrew; $opdeathnum += $opCrew;
// 중간 쌀 체크
$myRice = Util::round($exp / 50);
// 성격 보정
$myRice = CharExperience($myRice, $general['personal']);
// 쌀 소모
$myRice = ($myRice * 5 * getCrewtypeRice($generalCrewType, $nation['tech']));
// 결과 쌀
$myRice = $general['rice'] - $myRice;
// 중간 쌀 체크
$opRice = Util::round($opexp / 50 * 0.8);
// 성격 보정
$opRice = CharExperience($opRice, $oppose['personal']);
// 쌀 소모
$opRice = ($opRice * 5 * getCrewtypeRice($opposeCrewType, $destnation['tech']));
// 결과 쌀
$opRice = $oppose['rice'] - $opRice;
if($opRice <= Util::round($oppose['crew']/100)) { break; }
if($myRice <= Util::round($general['crew']/100)) { break; }
if($oppose['crew'] <= 0) { break; }
if($general['crew'] <= 0) { break; }
}
$render_attacker = [
'crewtype' => mb_substr($generalCrewType->name, 0, 2),
'name'=> $general['name'],
'remain_crew' => $general['crew'],
'killed_crew' => -$mydeathnum
];
$render_defender = [
'crewtype' => mb_substr($opposeCrewType->name, 0, 2),
'name'=> $oppose['name'],
'remain_crew' => $oppose['crew'],
'killed_crew' => -$opdeathnum
];
$res = str_replace(["\r\n", "\r", "\n"], '', $templates->render('small_war_log',[
'year'=>$year,
'month'=>$month,
'war_type'=>'attack',
'war_type_str'=>'→',
'me' => $render_attacker,
'you' => $render_defender,
]));
$oppres = str_replace(["\r\n", "\r", "\n"], '', $templates->render('small_war_log',[
'year'=>$year,
'month'=>$month,
'war_type'=>'defense',
'war_type_str'=>'←',
'me' => $render_defender,
'you' => $render_attacker,
]));
$log[] = $res;
$batlog[] = $res;
$batres[] = $res;
$opplog[] = $oppres;
$oppbatlog[] = $oppres;
$oppbatres[] = $oppres;
$deadAmount['att'] = $deadAmount['att'] + $mydeathnum;
$deadAmount['def'] = $deadAmount['def'] + $opdeathnum;
// 상대장수 부상
$ratio = rand() % 100;
if($ratio >= 95) {
$opplog[] = "<C>●</>전투중 <R>부상</>당했다!";
$oppose['injury'] += rand() % 71 + 10; // 10 ~ 80
if($oppose['injury'] > 80) { $oppose['injury'] = 80; }
}
// 병사수 변경
$query = "update general set injury='{$oppose['injury']}',crew='{$oppose['crew']}',killcrew=killcrew+'$opkillnum',deathcrew=deathcrew+'$opdeathnum' where no='{$oppose['no']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
// 숙련도 증가
addGenDex($oppose['no'], $general['atmos'], $general['train'], $oppose['crewtype'], $opkillnum * 0.9);
addGenDex($oppose['no'], $general['atmos'], $general['train'], $general['crewtype'], $opdeathnum * 0.9);
// 죽은수 기술로 누적
$num = Util::round($mydeathnum * 0.01);
// 국가보정
if($nation['type'] == 3 || $nation['type'] == 13) { $num *= 1.1; }
if($nation['type'] == 5 || $nation['type'] == 6 || $nation['type'] == 7 || $nation['type'] == 8 || $nation['type'] == 12) { $num *= 0.9; }
// 부드러운 기술 제한
if(TechLimit($admin['startyear'], $year, $nation['tech'])) { $num = intdiv($num, 4); }
$query = "update nation set totaltech=totaltech+'$num',tech=totaltech/'$gencount' where nation='{$nation['nation']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
// 장수 부상
$ratio = rand() % 100;
if($ratio >= 95) {
$log[] = "<C>●</>전투중 <R>부상</>당했다!";
$general['injury'] += rand() % 71 + 10; // 10 ~ 80
if($general['injury'] > 80) { $general['injury'] = 80; }
}
// 병사수 변경
$query = "update general set injury='{$general['injury']}',crew='{$general['crew']}',killcrew=killcrew+'$mykillnum',deathcrew=deathcrew+'$mydeathnum' where no='{$general['no']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
// 숙련도 증가
addGenDex($general['no'], $general['atmos'], $general['train'], $general['crewtype'], $mykillnum);
addGenDex($general['no'], $general['atmos'], $general['train'], $oppose['crewtype'], $mydeathnum);
// 죽은수 기술로 누적
$num = Util::round($opdeathnum * 0.01);
// 국가보정
if($destnation['type'] == 3 || $destnation['type'] == 13) { $num *= 1.1; }
if($destnation['type'] == 5 || $destnation['type'] == 6 || $destnation['type'] == 7 || $destnation['type'] == 8 || $destnation['type'] == 12) { $num *= 0.9; }
// 부드러운 기술 제한
if(TechLimit($admin['startyear'], $year, $destnation['tech'])) { $num = intdiv($num, 4); }
$query = "update nation set totaltech=totaltech+'$num',tech=totaltech/'$destgencount' where nation='{$destnation['nation']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
//양국 평균 기술가격
//$techRatio = (getTechCost($nation['tech']) + getTechCost($destnation['tech'])) / 2;
$techRatio = 1.0;
// 죽은수 도시 재정으로 누적 60%
$num = Util::round(($mykillnum+$mydeathnum) * 0.6 * $techRatio);
// 국가보정
if($destnation['type'] == 1) { $num *= 1.1; }
if($destnation['type'] == 9 || $destnation['type'] == 10) { $num *= 0.9; }
$query = "update city set dead=dead+'$num' where city='{$city['city']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
// 죽은수 도시 재정으로 누적 40%
$num = Util::round(($mykillnum+$mydeathnum) * 0.4 * $techRatio);
// 국가보정
if($nation['type'] == 1) { $num *= 1.1; }
if($nation['type'] == 9 || $nation['type'] == 10) { $num *= 0.9; }
$query = "update city set dead=dead+'$num' where city='{$general['city']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
// 상대 병사 소진이나 쌀 소진시 다음 장수
if($oppose['crew'] <= 0 || ($opRice <= Util::round($oppose['crew']/100) && $general['crew'] > 0)) {
if($opRice <= Util::round($oppose['crew']/100)) {
$josaYi = JosaUtil::pick($opposeCrewType->name, '이');
$alllog[] = "<C>●</>{$month}월:<Y>{$oppose['name']}</>의 {$opposeCrewType->name}{$josaYi} 패퇴했습니다.";
$log[] = "<C>●</><Y>{$oppose['name']}</>의 {$opposeCrewType->name}{$josaYi} 패퇴했습니다.";
$opplog[] = "<C>●</>군량 부족으로 패퇴합니다.";
} else {
$josaYi = JosaUtil::pick($opposeCrewType->name, '이');
$alllog[] = "<C>●</>{$month}월:<Y>{$oppose['name']}</>의 {$opposeCrewType->name}{$josaYi} 전멸했습니다.";
$log[] = "<C>●</><Y>{$oppose['name']}</>의 {$opposeCrewType->name}{$josaYi} 전멸했습니다.";
$opplog[] = "<C>●</>전멸했습니다.";
}
$opposecount--;
$general['atmos'] *= 1.1; //사기 증가
if($general['atmos'] > GameConst::$maxAtmosByWar) { $general['atmos'] = GameConst::$maxAtmosByWar; }
$query = "update general set atmos='{$general['atmos']}',killnum=killnum+1 where no='{$general['no']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$exp2++;
// 상대장수 경험 등등 증가
$opexp = Util::round($opexp / 50 * 0.8);
// 성격 보정
$opexp = CharExperience($opexp, $oppose['personal']);
// 쌀 소모
$oppose['rice'] -= ($opexp * 5 * getCrewtypeRice($opposeCrewType, $destnation['tech']));
if($oppose['rice'] < 0) { $oppose['rice'] = 0; }
$query = "update general set deathnum=deathnum+1,rice='{$oppose['rice']}',experience=experience+'$opexp',dedication=dedication+'$opexp' where no='{$oppose['no']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$opexp = 0;
pushGenLog($oppose, $opplog);
pushBatLog($oppose, $oppbatlog);
pushBatRes($oppose, $oppbatres);
$oppose = null;
$opplog = [];
$oppbatlog = [];
$oppbatres = [];
// 공격 장수 병사 소진이나 쌀 소진시 실패 처리
} elseif($general['crew'] <= 0 || $myRice <= Util::round($general['crew']/100)) {
if($myRice <= Util::round($general['crew']/100)) {
$josaYi = JosaUtil::pick($generalCrewType->name, '이');
$alllog[] = "<C>●</>{$month}월:<Y>{$general['name']}</>의 {$generalCrewType->name}{$josaYi} 퇴각했습니다.";
$log[] = "<C>●</>군량 부족으로 퇴각합니다.";
$opplog[] = "<C>●</><Y>{$general['name']}</>의 {$generalCrewType->name}{$josaYi} 퇴각했습니다.";
} else {
$josaYi = JosaUtil::pick($generalCrewType->name, '이');
$alllog[] = "<C>●</>{$month}월:<Y>{$general['name']}</>의 {$generalCrewType->name}{$josaYi} 퇴각했습니다.";
$log[] = "<C>●</>퇴각했습니다.";
$opplog[] = "<C>●</><Y>{$general['name']}</>의 {$generalCrewType->name}{$josaYi} 퇴각했습니다.";
}
// 경험치 상승
if($opposeCrewType->armType == GameUnitConst::T_WIZARD) { // 귀병
$oppose['intel2']++;
} elseif($opposeCrewType->armType == GameUnitConst::T_SIEGE) { // 차병
$oppose['leader2']++;
} else {
$oppose['power2']++;
}
$oppose['atmos'] *= 1.1; //사기 증가
if($oppose['atmos'] > GameConst::$maxAtmosByWar) { $oppose['atmos'] = GameConst::$maxAtmosByWar; }
// 상대장수 경험 등등 증가
$opexp = Util::round($opexp / 50 * 0.8);
// 성격 보정
$opexp = CharExperience($opexp, $oppose['personal']);
// 쌀 소모
$oppose['rice'] -= ($opexp * 5 * getCrewtypeRice($opposeCrewType, $destnation['tech']));
if($oppose['rice'] < 0) { $oppose['rice'] = 0; }
$query = "update general set rice='{$oppose['rice']}',leader2='{$oppose['leader2']}',power2='{$oppose['power2']}',intel2='{$oppose['intel2']}',atmos='{$oppose['atmos']}',experience=experience+'$opexp',dedication=dedication+'$opexp',killnum=killnum+1 where no='{$oppose['no']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$query = "update general set deathnum=deathnum+1 where no='{$general['no']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$opexp = 0;
$opplog = checkAbility($oppose, $opplog);
pushGenLog($oppose, $opplog);
pushBatLog($oppose, $oppbatlog);
pushBatRes($oppose, $oppbatres);
$opplog = [];
$oppbatlog = [];
$oppbatres = [];
// $josaYi = JosaUtil::pick($general['name'], '이');
// $alllog[] = "<C>●</>{$month}월:<Y>{$general['name']}</>{$josaYi} }<G>{$city['name']}</> 공략에 실패했습니다. <1>$date</>";
// $log[] = "<C>●</> <G>{$city['name']}</> 공략에 실패했습니다. <1>$date</>";
break;
} else {
// 무승부일때 로그 남김
pushGenLog($oppose, $opplog);
pushBatLog($oppose, $oppbatlog);
pushBatRes($oppose, $oppbatres);
$opplog = [];
$oppbatlog = [];
$oppbatres = [];
}
usort($defenderList, function($lhs, $rhs){
return -(extractBattleOrder($lhs) <=> extractBattleOrder($rhs));
});
$iterDefender = new \ArrayIterator($defenderList);
$iterDefender->rewind();
$getNextDefender = function(?WarUnit $prevDefender, bool $reqNext) use ($iterDefender, $rawDefenderCity, $rawDefenderNation, $year, $month, $db) {
if($prevDefender !== null){
$prevDefender->applyDB($db);
}
if(!$reqNext){
return null;
}
if(!$iterDefender->valid()){
return null;
}
$retVal = new WarUnitGeneral($iterDefender->current(), $rawDefenderCity, $rawDefenderNation, false, $year, $month);
$iterDefender->next();
return $retVal;
};
$conquerCity = processWar_NG($attacker, $getNextDefender, $city, $year - $startYear);
$attacker->applyDB($db);
//NOTE: $rawAttackerNation과 $rawDefenderNation은 전투중에 '바뀌지 않음'을 전제로 하고 있다. (현재 구현도 그렇게 되어있음)
$rawDefenderCity = $city->getRaw();
$updateAttackerNation = [];
$updateDefenderNation = [];
if($city->getVar('supply')){
if($city->getPhase() > 0){
$rice = $city->getKilled() / 100 * 0.8;
$rice *= $city->getCrewType()->rice;
$rice *= getTechCost($rawDefenderNation['tech']);
$rice *= $cityRate / 100 - 0.2;
Util::setRound($rice);
$updateDefenderNation['rice'] = max(0, $rawDefenderNation['rice'] - $rice);
}
else if($conquerCity){
$updateDefenderNation['rice'] = $rawDefenderNation['rice'] + 500;
}
}
if(isset($oppose)){
//마지막 페이즈에 장수가 전멸하지 않은 경우. 쌀 소모 후속 처리
// 상대장수 경험 등등 증가(페이즈 초과시)
$opexp = Util::round($opexp / 50 * 0.8);
// 성격 보정
$opexp = CharExperience($opexp, $oppose['personal']);
// 쌀 소모
$oppose['rice'] -= ($opexp * 5 * getCrewtypeRice($opposeCrewType, $destnation['tech']));
if($oppose['rice'] < 0) { $oppose['rice'] = 0; }
$query = "update general set rice='{$oppose['rice']}',experience=experience+'$opexp',dedication=dedication+'$opexp' where no='{$oppose['no']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
}
// 경험치 상승
if($generalCrewType->armType == GameUnitConst::T_WIZARD) { // 귀병
$general['intel2'] += $exp2;
} elseif($generalCrewType->armType == GameUnitConst::T_SIEGE) { // 차병
$general['leader2'] += $exp2;
} else {
$general['power2'] += $exp2;
}
$query = "update general set leader2='{$general['leader2']}',power2='{$general['power2']}',intel2='{$general['intel2']}' where no='{$general['no']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
// 공헌, 명성 상승
$exp = Util::round($exp / 50);
// 성격 보정
$exp = CharExperience($exp, $general['personal']);
// 쌀 소모
$general['rice'] -= ($exp * 5 * getCrewtypeRice($generalCrewType, $nation['tech']));
if($general['rice'] < 0) { $general['rice'] = 0; }
$query = "update general set rice='{$general['rice']}',dedication=dedication+'$exp',experience=experience+'$exp' where no='{$general['no']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$log = checkAbility($general, $log);
pushGenLog($general, $log);
pushBatLog($general, $batlog);
pushBatRes($general, $batres);
pushGeneralPublicRecord($alllog, $year, $month);
pushWorldHistory($history);
return $deadAmount;
}
function CriticalScore2($score) {
$score = Util::round($score * (rand()%8 + 13)/10); // 1.3~2.0
return $score;
}
//0 0 : 100 100 이면 최고 무한대 차이
//30 30 : 100 100 이면 최고 3.3배 차이
//60 60 : 100 100 이면 최고 1.6배 차이
function getCrew($crew, $youatmos, $mytrain) {
$ratio = $youatmos / $mytrain;
$crew = $crew * $ratio;
return $crew;
}
function getCrewtypeRice($crewtype, $tech) {
$cost = $crewtype->rice / 10;
return $cost * getTechCost($tech);
}
//////////////////////////////////////////////////////////////
// 표준 공 / 수 반환 수치는 약 0이 되게 (100~550)
//////////////////////////////////////////////////////////////
function getRate($admin, $type, $dtype) {
$t = "{$dtype}{$type}";
return $admin[$t];
}
function addConflict($city, $nationID, $mykillnum) {
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
$nationlist = [];
$killnum = [0];
list($year, $month) = $gameStor->getValuesAsArray(['year', 'month']);
$conflict = Json::decode($city['conflict']);
if(!$conflict || $city['def'] == 0){ // 선타, 막타 보너스
$mykillnum *= 1.05;
}
if (!$conflict) {
$conflict[$nationID] = $mykillnum;
}
else if(key_exists($nationID, $conflict)){
$conflict[$nationID] += $mykillnum;
arsort($conflict);
}
else{
$conflict[$nationID] = $mykillnum;
arsort($conflict);
$nation = getNationStaticInfo($nationID);
$josaYi = JosaUtil::pick($nation['name'], '이');
pushWorldHistory(["<C>●</>{$year}{$month}월:<M><b>【분쟁】</b></><D><b>{$nation['name']}</b></>{$josaYi} <G><b>{$city['name']}</b></> 공략에 가담하여 분쟁이 발생하고 있습니다."]);
}
$rawConflict = Json::encode($conflict);
$city['conflict'] = $rawConflict;
$totalDead = $attacker->getKilled() + $attacker->getDead();
$db->update('city', [
'conflict'=>$rawConflict
], 'city=%i',$city['city']);
'dead' => $db->sqleval('dead + %i', $totalDead * 0.4)
], 'city=%i', $rawAttackerCity['city']);
return $city;
$db->update('city', [
'dead' => $db->sqleval('dead + %i', $totalDead * 0.6)
], 'city=%i', $rawDefenderCity['city']);
$attackerIncTech = $attacker->getDead() * 0.01 * getNationTechMultiplier($rawAttackerNation['type']);
$defenderIncTech = $attacker->getKilled() * 0.01 * getNationTechMultiplier($rawDefenderNation['type']);
if(TechLimit($startYear, $year, $rawAttackerNation['tech'])){
$attackerIncTech /= 4;
}
if(TechLimit($startYear, $year, $rawDefenderNation['tech'])){
$defenderIncTech /= 4;
}
$attackerTotalTech = $rawAttackerNation['totaltech'] + $attackerIncTech;
$defenderTotalTech = $rawDefenderNation['totaltech'] + $defenderIncTech;
$updateAttackerNation['totaltech'] = Util::round($attackerTotalTech);
$updateDefenderNation['totaltech'] = Util::round($defenderTotalTech);
$updateAttackerNation['tech'] = Util::round($attackerTotalTech / max(GameConst::$initialNationGenLimit, $rawAttackerNation['gennum']));
$updateDefenderNation['tech'] = Util::round($defenderTotalTech / max(GameConst::$initialNationGenLimit, $rawDefenderNation['gennum']));
$db->update('nation', $updateAttackerNation, 'nation=%i', $attackerNationID);
$db->update('nation', $updateDefenderNation, 'nation=%i', $defenderNationID);
$db->update('diplomacy', [
'dead'=>$db->sqleval('dead + %i', $attacker->getDead() * getTechCost($rawAttackerNation['tech']))
], 'me = %i and you = %i', $attackerNationID, $defenderNationID);
$db->update('diplomacy', [
'dead'=>$db->sqleval('dead + %i', $attacker->getKilled() * getTechCost($rawDefenderNation['tech']))
], 'me = %i and you = %i', $defenderNationID, $attackerNationID);
if(!$conquerCity){
return;
}
//XXX: 새 도시점령 코드 작성하기 전까지 유지
$rawAttackerCity = $db->queryFirstRow('SELECT * FROM city WHERE city = %i', $rawAttacker['city']);
$rawAttackerNation = $db->queryFirstRow('SELECT nation,`level`,`name`,capital,totaltech,gennum,tech,`type`,gold,rice FROM nation WHERE nation = %i', $attackerNationID);
if($defenderNationID !== 0){
$rawDefenderNation = $db->queryFirstRow('SELECT nation,`level`,`name`,capital,totaltech,gennum,tech,`type`,gold,rice FROM nation WHERE nation = %i', $defenderNationID);
}
ConquerCity([
'startyear'=>$startYear,
'year'=>$year,
'month'=>$month,
'city_rate'=>$cityRate
], $attacker->getRaw(), $city->getRaw(), $rawAttackerNation, $rawDefenderNation);
}
function extractBattleOrder($general){
return (
$general['leader'] +
$general['power'] +
$general['intel'] +
$general['weap'] +
$general['horse'] +
$general['book'] +
$general['crew'] / 100
);
}
function processWar_NG(
WarUnitGeneral $attacker,
callable $getNextDefender,
WarUnitCity $city,
int $relYear
):bool{
$templates = new \League\Plates\Engine(__dir__.'/templates');
$logger = $attacker->getLogger();
$attacker->useBattleInitItem();
$date = substr($attacker->getVar('turntime'),11,5);
$attackerNationUpdate = [];
$defenderNationUpdate = [];
$defender = ($getNextDefender)(null, true);
$conquerCity = false;
$josaRo = JosaUtil::pick($city->getName(), '로');
$josaYi = JosaUtil::pick($attacker->getName(), '이');
$logger->pushGlobalActionLog("<D><b>{$attacker->getNationVar('name')}</b></>의 <Y>{$attacker->getName()}</>{$josaYi} <G><b>{$city->getName()}</b></>{$josaRo} 진격합니다.");
$logger->pushGeneralActionLog("<G><b>{$city->getName()}</b></>{$josaRo} <M>진격</>합니다. <1>$date</>");
for($currPhase = 0; $currPhase < $attacker->getMaxPhase(); $currPhase+=1){
if($defender === null){
$defender = $city;
if($city->getNationVar('rice') <= 0 && $city->getVar('supply')){
//병량 패퇴
$attacker->setOppose($defender);
$defender->setOppose($attacker);
$attacker->addTrain(1);
$attacker->addWin();
$defender->addLose();
$defender->heavyDecreseWealth();
$logger->pushGlobalActionLog("병량 부족으로 <G><b>{$defender->getName()}</b></>의 수비병들이 <R>패퇴</>합니다.");
$josaUl = JosaUtil::pick($defender->getName(), '을');
$josaYi = JosaUtil::pick($defender->getNationVar('name'), '이');
$logger->pushGlobalHistoryLog("<M><b>【패퇴】</b></><D><b>{$defender->getNationVar('name')}</b></>{$josaYi} 병량 부족으로 <G><b>{$defender->getName()}</b></>{$josaUl} 뺏기고 말았습니다.");
$conquerCity = true;
break;
}
}
if($defender->getPhase() == 0){
$defender->setPrePhase($currPhase);
$attacker->addTrain(1);
$defender->addTrain(1);
if($defender instanceof WarUnitGeneral){
$josaWa = JosaUtil::pick($attacker->getCrewTypeName(), '와');
$josaYi = JosaUtil::pick($defender->getCrewTypeName(), '이');
$logger->pushGlobalActionLog("<Y>{$attacker->getName()}</>의 {$attacker->getCrewTypeName()}{$josaWa} <Y>{$defender->getName()}</>의 {$defender->getCrewTypeName()}{$josaYi} 대결합니다.");
$josaRo = JosaUtil::pick($attacker->getCrewTypeName(), '로');
$josaUl = JosaUtil::pick($defender->getCrewTypeName(), '을');
$attacker->getLogger()->pushGeneralActionLog("{$attacker->getCrewTypeName()}{$josaRo} <Y>{$defender->getName()}</>의 {$defender->getCrewTypeName()}{$josaUl} <M>공격</>합니다.");
$josaRo = JosaUtil::pick($defender->getCrewTypeName(), '로');
$josaUl = JosaUtil::pick($attacker->getCrewTypeName(), '을');
$defender->getLogger()->pushGeneralActionLog("{$defender->getCrewTypeName()}{$josaRo} <Y>{$attacker->getName()}</>의 {$attacker->getCrewTypeName()}{$josaUl} <M>수비</>합니다.");
}
else{
$josaYi = JosaUtil::pick($attacker->getName(), '이');
$josaRo = JosaUtil::pick($attacker->getCrewTypeName(), '로');
$logger->pushGlobalActionLog("<Y>{$attacker->getName()}</>{$josaYi} {$attacker->getCrewTypeName()}{$josaRo} 성벽을 공격합니다.");
$logger->pushGeneralActionLog("<C>●</>{$attacker->getCrewTypeName()}{$josaRo} 성벽을 <M>공격</>합니다.", ActionLogger::PLAIN);
}
$defender->useBattleInitItem();
$attacker->setOppose($defender);
$defender->setOppose($attacker);
$attacker->checkBattleBeginSkill();
$defender->checkBattleBeginSkill();
$attacker->checkBattleBeginItem();
$defender->checkBattleBeginItem();
$attacker->applyBattleBeginSkillAndItem();
$defender->applyBattleBeginSkillAndItem();
}
$attacker->beginPhase();
$defender->beginPhase();
$attacker->checkPreActiveSkill();
$defender->checkPreActiveSkill();
$attacker->checkActiveSkill();
$defender->checkActiveSkill();
//NOTE: 마법은 checkActiveSkill, checkPostActiveSkill 내에서 반영
$attacker->checkPostActiveSkill();
$defender->checkPostActiveSkill();
//NOTE: 반계류 등의 스킬을 post에서 반영
$activeSkillIterator = new \AppendIterator();
$activeSkillIterator->append($attacker->applyActiveSkill());
$activeSkillIterator->append($defender->applyActiveSkill());
foreach($activeSkillIterator as $b){
//doNothing
}
$deadDefender = $attacker->calcDamage();
$deadAttacker = $defender->calcDamage();
$attackerHP = $attacker->getHP();
$defenderHP = $defender->getHP();
if($deadAttacker > $attackerHP || $deadDefender > $defenderHP){
$deadAttackerRatio = $deadAttacker / max(1, $attackerHP);
$deadDefenderRatio = $deadDefender / max(1, $defenderHP);
if($deadDefenderRatio > $deadAttackerRatio){
//수비자가 더 병력 부족
$deadAttacker /= $deadDefenderRatio;
$deadDefender = $defenderHP;
}
else{
//공격자가 더 병력 부족
$deadDefender /= $deadAttackerRatio;
$deadAttacker = $attackerHP;
}
}
$deadAttacker = min(ceil($deadAttacker), $attackerHP);
$deadDefender = min(ceil($deadDefender), $defenderHP);
$attacker->decreaseHP($deadAttacker);
$defender->decreaseHP($deadDefender);
$attacker->increaseKilled($deadDefender);
$defender->increaseKilled($deadAttacker);
$phaseNickname = $currPhase + 1;
if($deadAttacker > 0 || $deadDefender > 0){
$attacker->getLogger()->pushGeneralBattleDetailLog(
"$phaseNickname : <Y1>【{$attacker->getName()}】</> <C>{$attacker->getHP()} (-$deadAttacker)</> VS <C>{$defender->getHP()} (-$deadDefender)</> <Y1>【{$defender->getName()}】</>"
);
$defender->getLogger()->pushGeneralBattleDetailLog(
"$phaseNickname : <Y1>【{$defender->getName()}】</> <C>{$defender->getHP()} (-$deadDefender)</> VS <C>{$attacker->getHP()} (-$deadAttacker)</> <Y1>【{$attacker->getName()}】</>"
);
}
$attacker->addPhase();
$defender->addPhase();
if(!$attacker->continueWar($noRice)){
$attacker->logBattleResult();
$defender->logBattleResult();
$attacker->addLose();
$defender->addWin();
$attacker->tryWound();
$defender->tryWound();
$josaYi = JosaUtil::pick($attacker->getCrewTypeName(), '이');
$logger->pushGlobalActionLog("<Y>{$attacker->getName()}</>의 {$attacker->getCrewTypeName()}{$josaYi} 퇴각했습니다.");
if($noRice){
$attacker->getLogger()->pushGeneralActionLog("군량 부족으로 퇴각합니다.", ActionLogger::PLAIN);
}
else{
$attacker->getLogger()->pushGeneralActionLog("퇴각했습니다.", ActionLogger::PLAIN);
}
$defender->getLogger()->pushGeneralActionLog("<Y>{$attacker->getName()}</>의 {$attacker->getCrewTypeName()}{$josaYi} 퇴각했습니다.", ActionLogger::PLAIN);
break;
}
if(!$defender->continueWar($noRice)){
$attacker->logBattleResult();
$defender->logBattleResult();
$attacker->addWin();
$defender->addLose();
$attacker->tryWound();
$defender->tryWound();
if($defender === $city){
$attacker->addLevelExp(1000);
$conquerCity = true;
break;
}
$josaYi = JosaUtil::pick($defender->getCrewTypeName(), '이');
if($noRice){
$logger->pushGlobalActionLog("<Y>{$defender->getName()}</>의 {$defender->getCrewTypeName()}{$josaYi} 패퇴했습니다.");
$attacker->getLogger()->pushGeneralActionLog("<Y>{$defender->getName()}</>의 {$defender->getCrewTypeName()}{$josaYi} 패퇴했습니다.", ActionLogger::PLAIN);
$defender->getLogger()->pushGeneralActionLog("군량 부족으로 패퇴합니다.", ActionLogger::PLAIN);
}
else{
$logger->pushGlobalActionLog("<Y>{$defender->getName()}</>의 {$defender->getCrewTypeName()}{$josaYi} 전멸했습니다.");
$attacker->getLogger()->pushGeneralActionLog("<Y>{$defender->getName()}</>의 {$defender->getCrewTypeName()}{$josaYi} 전멸했습니다.", ActionLogger::PLAIN);
$defender->getLogger()->pushGeneralActionLog("전멸했습니다.", ActionLogger::PLAIN);
}
if($currPhase + 1 == $attacker->getMaxPhase()){
break;
}
$defender->finishBattle();
$defender = ($getNextDefender)($defender, true);
if($defender !== null && !($defender instanceof WarUnitGeneral)){
throw new \RuntimeException('다음 수비자를 받아오는데 실패');
}
}
}
$attacker->finishBattle();
$defender->finishBattle();
if($currPhase == $attacker->getMaxPhase()){
//마지막 페이즈의 전투 마무리
$attacker->tryWound();
$defender->tryWound();
$attacker->logBattleResult();
$defender->logBattleResult();
}
if($defender instanceof WarUnitCity){
$newConflict = $defender->addConflict();
if($newConflict){
$nationName = $attacker->getNationVar('name');
$josaYi = JosaUtil::pick($nationName, '이');
$logger->pushGlobalHistoryLog("<M><b>【분쟁】</b></><D><b>{$nationName}</b></>{$josaYi} <G><b>{$defender->getName()}</b></> 공략에 가담하여 분쟁이 발생하고 있습니다.");
}
}
($getNextDefender)($defender, false);
return $conquerCity;
}
function DeleteConflict($nation) {
@@ -1594,30 +472,20 @@ function ConquerCity($admin, $general, $city, $nation, $destnation) {
pushNationHistory($nation, "<C>●</>{$year}{$month}월:<Y>{$general['name']}</>{$josaYiGen} {$destnationName} <G><b>{$city['name']}</b></>{$josaUl} <S>점령</>");
pushNationHistory($destnation, "<C>●</>{$year}{$month}월:<D><b>{$nation['name']}</b></>의 <Y>{$general['name']}</>에 의해 <G><b>{$city['name']}</b></>{$josaYiCity} <span class='ev_highlight'>함락</span>");
$query = "select city from city where nation='{$city['nation']}'";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$citycount = MYDB_num_rows($result);
$citycount = $db->queryFirstField('SELECT count(city) FROM city WHERE nation = %i', $city['nation']);
// 국가 멸망시
//TODO: 국가 멸망 코드를 별도로 작성
if($citycount == 1 && $city['nation'] != 0) {
$query = "select nation,name,gold,rice from nation where nation='{$city['nation']}'";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$losenation = MYDB_fetch_array($result);
$losenation = $destnation;
$josaYi = JosaUtil::pick($losenation['name'], '이');
$josaUl = JosaUtil::pick($losenation['name'], '을');
$history[] = "<C>●</>{$year}{$month}월:<R><b>【멸망】</b></><D><b>{$losenation['name']}</b></>{$josaYi} 멸망하였습니다.";
pushNationHistory($nation, "<C>●</>{$year}{$month}월:<D><b>{$losenation['name']}</b></>{$josaUl} 정복");
$query = "select no, nation from general where nation='{$general['nation']}' and level='12'";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$ruler = MYDB_fetch_array($result);
//다굴치는 나라들 전방설정을 위해 미리 얻어옴
$query = "select you from diplomacy where me='{$losenation['nation']}' and state<2";
$dipResult = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$dipCount = MYDB_num_rows($dipResult);
$dipNations = $db->queryFirstColumn('SELECT you FROM diplomacy WHERE me = %i', $losenation['nation']);
$loseGeneralGold = 0;
$loseGeneralRice = 0;
@@ -1653,11 +521,7 @@ function ConquerCity($admin, $general, $city, $nation, $destnation) {
$loseGeneralRice += $loseRice;
//모두 등용장 발부
if($nation['name'] == "강족" || $nation['name'] == "저족" || $nation['name'] == "흉노족"
|| $nation['name'] == "남만족" || $nation['name'] == "산월족" || $nation['name'] == "오환족"
|| $nation['name'] == "왜족") {
//등용장 미발부
} elseif(Util::randBool(0.5)) {
if(Util::randBool(0.5)) {
$msg = ScoutMessage::buildScoutMessage($general['no'], $gen['no']);
if($msg){
$msg->send(true);
@@ -1665,7 +529,7 @@ function ConquerCity($admin, $general, $city, $nation, $destnation) {
}
//NPC인 경우 10% 확률로 임관(엔장, 인재, 의병)
if($gen['npc'] >= 2 && $gen['npc'] <= 4 && rand() % 100 < 10) {
if($gen['npc'] >= 2 && $gen['npc'] <= 8 && rand() % 100 < 10) {
$commissionCommand = EncodeCommand(0, 0, $nation['nation'], 25); //임관
$query = "update general set turn0='$commissionCommand' where no={$gen['no']}";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
@@ -1727,10 +591,9 @@ function ConquerCity($admin, $general, $city, $nation, $destnation) {
$query = "delete from nation where nation='{$city['nation']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
// 아까 얻어온 다굴국들 전방설정
for($i=0; $i < $dipCount; $i++) {
$dip = MYDB_fetch_array($dipResult);
foreach($dipNations as $dip){
//전방설정
SetNationFront($dip['you']);
SetNationFront($dip);
}
// 멸망이 아니면
} else {
+54 -3
View File
@@ -69,12 +69,12 @@ class ActionLogger{
}
if($this->generalBattleResultLog){
pushGenLog(['no'=>$this->generalId], $this->generalBattleResultLog);
pushBatRes(['no'=>$this->generalId], $this->generalBattleResultLog);
$this->generalBattleResultLog = [];
}
if($this->generalBattleDetailLog){
pushGenLog(['no'=>$this->generalId], $this->generalBattleDetailLog);
pushBatLog(['no'=>$this->generalId], $this->generalBattleDetailLog);
$this->generalBattleDetailLog = [];
}
@@ -143,7 +143,7 @@ class ActionLogger{
$this->generalBattleResultLog[] = $text;
}
public function pushGeneralBattleDetailLog($text, int $formatType = self::RAWTEXT){
public function pushGeneralBattleDetailLog($text, int $formatType = self::PLAIN){
if(!$text){
return;
}
@@ -243,4 +243,55 @@ class ActionLogger{
return $text;
}
public function pushBattleResultTemplate(
WarUnit $me,
WarUnit $oppose
){
if($me instanceof WarUnitCity){
return;
}
$templates = new \League\Plates\Engine(__dir__.'/../templates');
$render_me = [
'crewtype' => $me->getCrewTypeShortName(),
'name' => $me->getName(),
'remain_crew' => $me->getHP(),
'killed_crew' => -$me->getDeadCurrentBattle()
];
$render_oppose = [
'crewtype' => $oppose->getCrewTypeShortName(),
'name' => $oppose->getName(),
'remain_crew' => $oppose->getHP(),
'killed_crew' => -$oppose->getDeadCurrentBattle()
];
if(!$me->isAttacker()){
$warType = 'defense';
$warTypeStr = '←';
}
else if($oppose instanceof WarUnitCity){
$warType = 'siege';
$warTypeStr = '→';
}
else{
$warType = 'attack';
$warTypeStr = '→';
}
$res = str_replace(["\r\n", "\r", "\n"], '', $templates->render('small_war_log',[
'year'=>$this->year,
'month'=>$this->month,
'war_type'=>$warType,
'war_type_str'=>$warTypeStr,
'me' => $render_me,
'you' => $render_oppose,
]));
$this->pushGeneralBattleResultLog($res, self::EVENT_YEAR_MONTH);
$this->pushGeneralBattleDetailLog($res, self::EVENT_YEAR_MONTH);
$this->pushGeneralActionLog($res, self::EVENT_YEAR_MONTH);
}
}
+2 -2
View File
@@ -90,13 +90,13 @@ class RaiseInvader extends \sammo\Event\Action{
if($npcEachCount < 0){
$npcEachCount =
$db->queryFirstField('SELECT count(no) from general where npc<5') / count(self::INVADER_LIST);
$db->queryFirstField('SELECT count(no) from general where npc < 9') / count(self::INVADER_LIST);
$npcEachCount /= -1 * $this->npcEachCount;
}
$specAvg = $this->specAvg;
if($specAvg < 0){
$specAvg = $db->queryFirstField('SELECT avg(sum(`leader` + `power` + `intel`)) from general where npc<5');
$specAvg = $db->queryFirstField('SELECT avg(sum(`leader` + `power` + `intel`)) from general where npc < 9');
$specAvg /= -1 * $this->specAvg;
}
+46
View File
@@ -0,0 +1,46 @@
<?php
namespace sammo\Event\Action;
class RegNeutralNPC extends \sammo\Event\Action{
private $npc;
public function __construct(
int $affinity,
string $name,
$picturePath,
int $nationID,
$locatedCity,
int $leadership,
int $power,
int $intel,
int $birth = 160,
int $death = 300,
$ego = null,
$char = '',
$text = ''
){
$this->npc = new \sammo\Scenario\NPC(
$affinity,
$name,
$picturePath,
$nationID,
$locatedCity,
$leadership,
$power,
$intel,
$birth,
$death,
$ego,
$char,
$text?:''
);
$this->npc = 6;
}
public function run($env=null){
$result = $this->npc->build($env);
return [__CLASS__, $result];
}
}
+4
View File
@@ -69,6 +69,10 @@ class GameConstBase
public static $exchangeFee = 0.01;
/** @var float 성인 연령 */
public static $adultAge = 14;
/** @var int 최대 계급 */
public static $maxDedLevel = 30;
/** @var int 최대 기술 레벨 */
public static $maxTechLevel = 12;
/** @var int 초기 제한시 장수 제한 */
public static $initialNationGenLimit = 10;
+3 -1
View File
@@ -13,6 +13,8 @@ class GameUnitConstBase{
const T_CAVALRY = 2;
const T_WIZARD = 3;
const T_SIEGE = 4;
const DEFAULT_CREWTYPE = 0;
@@ -279,7 +281,7 @@ class GameUnitConstBase{
41, self::T_SIEGE, '충차',
150, 100, 6, 0, 0, 20, 5,
1000, null, null, 3,
[self::T_FOOTMAN=>0.8, self::T_ARCHER=>0.8, self::T_CAVALRY=>0.8, self::T_WIZARD=>0.8, self::T_CASTLE=>1.8],
[self::T_FOOTMAN=>0.8, self::T_ARCHER=>0.8, self::T_CAVALRY=>0.8, self::T_WIZARD=>0.8, self::T_CASTLE=>2.4],
[self::T_FOOTMAN=>1.2, self::T_ARCHER=>1.2, self::T_CAVALRY=>1.2, self::T_WIZARD=>1.2],
['엄청난 위력으로 성벽을 부수어버립니다.']
],
+7 -3
View File
@@ -58,6 +58,10 @@ class GameUnitDetail{
$this->info = $info;
}
public function getShortName():string{
return StringUtil::subStringForWidth($this->name, 0, 4);
}
public function costWithTech(int $tech, int $crew=100):float{
return $this->cost * getTechCost($tech) * $crew / 100;
}
@@ -81,7 +85,7 @@ class GameUnitDetail{
public function getComputedAttack(array $general, int $tech){
if($this->armType == GameUnitConst::T_CASTLE){
assert(isset($general['def']) && isset($general['wall']), '도시 정보가 입력되어야 함');
return ($general['def']*0.1 + $general['wall']*0.9) / 500 + 200;
return ($general['def'] + $general['wall']*9) / 500 + 200;
}
if($this->armType == GameUnitConst::T_WIZARD){
@@ -113,7 +117,7 @@ class GameUnitDetail{
public function getComputedDefence(array $general, int $tech){
if($this->armType == GameUnitConst::T_CASTLE){
assert(isset($general['def']) && isset($general['wall']), '도시 정보가 입력되어야 함');
return ($general['def']*0.1 + $general['wall']*0.9) / 500 + 200;
return ($general['def'] + $general['wall']*9) / 500 + 200;
}
$def = $this->defence + getTechAbil($tech);
$crew = ($general['crew'] / (7000 / 30)) + 70;
@@ -152,7 +156,7 @@ class GameUnitDetail{
$ratio = max($mainstat - 65, 0);
$ratio *= $coef;
return min(50, $ratio);
return min(50, $ratio) / 100;
}
public function isValid($ownCities, $ownRegions, $relativeYear, $tech){
+7 -2
View File
@@ -154,7 +154,11 @@ class ResetHelper{
Util::generateFileUsingSimpleTemplate(
__dir__.'/../templates/base_map.orig.js',
__dir__.'/../d_shared/base_map.js',
['cityPosition'=>Json::encode($cityPositions)],
[
'cityPosition'=>Json::encode($cityPositions),
'regionMap'=>Json::encode(CityConst::$regionMap),
'levelMap'=>Json::encode(CityConst::$levelMap),
],
true
);
@@ -216,7 +220,8 @@ class ResetHelper{
'picture'=>$admin['picture'],
'imgsvr'=>$admin['imgsvr'],
'turntime'=>$turntime,
'killturn'=>9999
'killturn'=>9999,
'crewtype'=>GameUnitConst::DEFAULT_CREWTYPE
]);
}
+80
View File
@@ -22,6 +22,7 @@ class Scenario{
private $generals;
private $generalsEx;
private $generalsNeutral;
private $tmpGeneralQueue = [];
@@ -151,6 +152,50 @@ class Scenario{
}, Util::array_get($data['general_ex'], []));
$this->generalsNeutral = array_map(function($rawGeneral){
while(count($rawGeneral) < 14){
$rawGeneral[] = null;
}
list(
$affinity, $name, $picturePath, $nationName, $locatedCity,
$leadership, $power, $intel, $level, $birth, $death, $ego,
$char, $text
) = $rawGeneral;
if(key_exists($nationName, $this->nationsInv)){
$nationID = $this->nationsInv[$nationName]->id;;
}
else if(key_exists($nationName, $this->nations)){
$nationID = (int)$nationName;
}
else{
$nationID = 0;
}
$this->tmpGeneralQueue[$name] = $rawGeneral;
$npc = new Scenario\NPC(
$affinity,
$name,
$picturePath,
$nationID,
$locatedCity,
$leadership,
$power,
$intel,
$level,
$birth,
$death,
$ego,
$char,
$text
);
$npc->npc = 6;
return $npc;
}, Util::array_get($data['general_neutral'], []));
$this->initialEvents = array_map(function($rawEvent){
$cond = $rawEvent[0];
$action = array_slice($rawEvent, 1);
@@ -247,6 +292,11 @@ class Scenario{
return $this->generalsEx;
}
public function getNPCneutral(){
$this->initFull();
return $this->generalsNeutral;
}
public function getNation(){
$this->initFull();
return $this->nations;
@@ -266,6 +316,7 @@ class Scenario{
$nations = [];
$nationGeneralCnt = [];
$nationGeneralExCnt = [];
$nationGeneralNeutralCnt = [];
foreach($this->generals as $general){
$nationID = $general->nationID;
@@ -287,15 +338,27 @@ class Scenario{
}
}
foreach($this->generalsNeutral as $general){
$nationID = $general->nationID;
if(!key_exists($nationID, $nationGeneralNeutralCnt)){
$nationGeneralNeutralCnt[$nationID] = 1;
}
else{
$nationGeneralNeutralCnt[$nationID] += 1;
}
}
return [
'year'=>$this->getYear(),
'title'=>$this->getTitle(),
'npc_cnt'=>count($this->getNPC()),
'npcEx_cnt'=>count($this->getNPCex()),
'npcNeutral_cnt'=>count($this->getNPCneutral()),
'nation'=>array_map(function($nation) use ($nationGeneralCnt, $nationGeneralExCnt){
$brief = $nation->getBrief();
$brief['generals'] = Util::array_get($nationGeneralCnt[$nation->getID()], 0);
$brief['generalsEx'] = Util::array_get($nationGeneralExCnt[$nation->getID()], 0);
$brief['generalsNeutral'] = Util::array_get($nationGeneralNeutralCnt[$nation->getID()], 0);
return $brief;
},$this->getNation())
@@ -350,6 +413,23 @@ class Scenario{
$remainGenerals[$birth][] = array_merge(['RegNPC'], $rawGeneral);
}
}
foreach($this->generalsNeutral as $general){
if($general->build($env)){
if($general->nationID){
$this->nations[$general->nationID]->addGeneral($general);
}
continue;
}
$rawGeneral = $this->tmpGeneralQueue[$general->name];
$birth = $general->birth;
if(!key_exists($birth, $remainGenerals)){
$remainGenerals[$birth] = [];
}
$remainGenerals[$birth][] = array_merge(['RegNeutralNPC'], $rawGeneral);
}
return $remainGenerals;
}
+5 -3
View File
@@ -4,6 +4,7 @@ use \sammo\Util;
use \sammo\JosaUtil;
use \sammo\DB;
use \sammo\CityHelper;
use \sammo\GameUnitConst;
class NPC{
@@ -21,6 +22,7 @@ class NPC{
public $ego;
public $charDomestic = 0;
public $charWar = 0;
public $npc = 2;
public $text;
//[ 1, "헌제",1002, 1, null, 17, 13, 61, 0, 170, 250, "안전", null, "산 넘어 산이로구나..."],
@@ -210,8 +212,8 @@ class NPC{
$db->insert('general',[
'npcid'=>$npcID,
'npc'=>2,
'npc_org'=>2,
'npc'=>$this->npc,
'npc_org'=>$this->npc,
'affinity'=>$affinity,
'name'=>$name,
'picture'=>$picturePath,
@@ -226,7 +228,7 @@ class NPC{
'gold'=>1000,
'rice'=>1000,
'crew'=>0,
'crewtype'=>0,
'crewtype'=>GameUnitConst::DEFAULT_CREWTYPE,
'train'=>0,
'atmos'=>0,
'weap'=>0,
+400
View File
@@ -0,0 +1,400 @@
<?php
namespace sammo;
class WarUnit{
protected $raw;
protected $rawNation;
protected $logger;
protected $crewType;
protected $killedCurr = 0;
protected $killed = 0;
protected $deadCurr = 0;
protected $dead = 0;
protected $isAttacker = false;
protected $updatedVar = [];
protected $currPhase = 0;
protected $prePhase = 0;
protected $atmosBonus = 0;
protected $trainBonus = 0;
protected $oppose;
protected $warPower;
protected $warPowerMultiply = 1.0;
protected $activatedSkill = [];
protected $isFinished = false;
private function __construct(){
}
function getRaw():array{
return $this->raw;
}
function getRawNation():array{
return $this->rawNation;
}
function getVar(string $key){
return $this->raw[$key];
}
function updateVar(string $key, $value){
if($this->raw[$key] === $value){
return;
}
$this->raw[$key] = $value;
$this->updatedVar[$key] = true;
}
function updateVarWithLimit(string $key, $value, $min = null, $max = null){
if($min !== null && $value < $min){
$value = $min;
}
if($max !== null && $value > $max){
$value = $max;
}
$this->updateVar($key, $value);
}
function increaseVar(string $key, $value)
{
if($value === 0){
return;
}
$this->raw[$key] += $value;
$this->updatedVar[$key] = true;
}
function increaseVarWithLimit(string $key, $value, $min = null, $max = null){
$targetValue = $this->raw[$key] + $value;
if($min !== null && $targetValue < $min){
$targetValue = $min;
}
if($max !== null && $targetValue > $max){
$targetValue = $max;
}
$this->updateVar($key, $targetValue);
}
function multiplyVar(string $key, $value)
{
if($value === 1){
return;
}
$this->raw[$key] *= $value;
$this->updatedVar[$key] = true;
}
function multiplyVarWithLimit(string $key, $value, $min = null, $max = null){
$targetValue = $this->raw[$key] * $value;
if($min !== null && $targetValue < $min){
$targetValue = $min;
}
if($max !== null && $targetValue > $max){
$targetValue = $max;
}
$this->updateVar($key, $targetValue);
}
function getNationVar(string $key){
return $this->rawNation[$key];
}
function getPhase():int{
return $this->currPhase;
}
function getRealPhase():int{
return $this->prePhase + $this->currPhase;
}
function getName():string{
return 'EMPTY';
}
function isAttacker():bool{
return $this->isAttacker;
}
function getCrewType():GameUnitDetail{
return $this->crewType;
}
function getCrewTypeName():string{
return $this->getCrewType()->name;
}
function getCrewTypeShortName():string{
return $this->getCrewType()->getShortName();
}
function getLogger():ActionLogger{
return $this->logger;
}
function getKilled():int{
return $this->killed;
}
function getDead():int{
return $this->dead;
}
function getKilledCurrentBattle():int{
return $this->killedCurr;
}
function getDeadCurrentBattle():int{
return $this->deadCurr;
}
function getSpecialDomestic():int{
return 0;
}
function getSpecialWar():int{
return 0;
}
function getItem():int{
return 0;
}
function getMaxPhase():int{
return $this->getCrewType()->speed;
}
function setPrePhase(int $phase){
$this->prePhase = $phase;
}
function addPhase(){
$this->currPhase += 1;
}
function setOppose(?WarUnit $oppose){
$this->oppose = $oppose;
$this->killedCurr = 0;
$this->deadCurr = 0;
$this->activatedSkill = [];
}
function getOppose():?WarUnit{
return $this->oppose;
}
function getWarPower(){
return $this->warPower * $this->warPowerMultiply;
}
function getRawWarPower(){
return $this->warPower;
}
function getWarPowerMultiply(){
return $this->warPowerMultiply;
}
function setWarPowerMultiply($multiply = 1.0){
$this->warPowerMultiply = $multiply;
}
function multiplyWarPowerMultiply($multiply){
$this->warPowerMultiply *= $multiply;
}
function computeWarPower(){
$oppose = $this->oppose;
$myAtt = $this->getCrewType()->getComputedAttack($this->getRaw(), $this->getNationVar('tech'));
$opDef = $oppose->getCrewType()->getComputedDefence($oppose->getRaw(), $oppose->getNationVar('tech'));
// 감소할 병사 수
$warPower = GameConst::$armperphase + $myAtt - $opDef;
$opposeWarPowerMultiply = 1.0;
if($warPower < 100){
//최소 전투력 50 보장
$warPower = max(0, $warPower);
$warPower = ($warPower + 100) / 2;
$warPower = rand($warPower, 100);
}
$warPower *= CharAtmos(
$this->getComputedAtmos(),
$this->getCharacter()
);
$warPower /= CharTrain(
$oppose->getComputedTrain(),
$oppose->getCharacter()
);
if($this instanceof WarUnitGeneral){
$genDexAtt = getGenDex($this->getRaw(), $this->getCrewType()->id);
}
else{
$genDexAtt = ($this->cityRate - 60) * 7200;
}
if($this instanceof WarUnitGeneral){
$oppDexDef = getGenDex($oppose->getRaw(), $this->getCrewType()->id);
}
else{
$oppDexDef = ($this->cityRate - 60) * 7200;
}
$warPower *= getDexLog($genDexAtt, $oppDexDef);
$warPower *= $this->getCrewType()->getAttackCoef($oppose->getCrewType());
$opposeWarPowerMultiply *= $this->getCrewType()->getDefenceCoef($oppose->getCrewType());
$this->warPower = $warPower;
$this->oppose->setWarPowerMultiply($opposeWarPowerMultiply);
return [$warPower, $opposeWarPowerMultiply];
}
function addTrain(int $train){
return;
}
function addAtmos(int $atmos){
return;
}
function getComputedTrain(){
return GameConst::$maxTrainByCommand;
}
function getComputedAtmos(){
return GameConst::$maxAtmosByCommand;
}
function getComputedCriticalRatio():float{
return $this->getCrewType()->getCriticalRatio($this->getRaw());
}
function getComputedAvoidRatio():float{
return $this->getCrewType()->avoid / 100;
}
function addWin(){
}
function addLose(){
}
function finishBattle(){
throw new NotInheritedMethodException();
}
function getCharacter():int{
return 0;
}
function useBattleInitItem():bool{
return false;
}
function beginPhase():void{
$this->activatedSkill = [];
$this->computeWarPower();
}
function checkBattleBeginSkill():bool{
return false;
}
function checkBattleBeginItem():bool{
return false;
}
function applyBattleBeginSkillAndItem():bool{
return false;
}
function hasActivatedSkill(string $skillName):bool{
return $this->activatedSkill[$skillName] ?? false;
}
function activateSkill(... $skillNames){
foreach($skillNames as $skillName){
$this->activatedSkill[$skillName] = true;
}
}
function deactivateSkill(... $skillNames){
foreach($skillNames as $skillName){
$this->activatedSkill[$skillName] = false;
}
}
function checkPreActiveSkill():bool{
return false;
}
function checkActiveSkill():bool{
return false;
}
function checkPostActiveSkill():bool{
return false;
}
function applyActiveSkill(){
yield true;
}
function getHP():int{
throw new NotInheritedMethodException();
}
function decreaseHP(int $damage):int{
$this->dead += $damage;
throw new NotInheritedMethodException();
}
function increaseKilled(int $damage):int{
$this->killed += $damage;
throw new NotInheritedMethodException();
}
function calcDamage():int{
$warPower = $this->getWarPower();
$warPower *= Util::randRange(0.9, 1.1);
return Util::round($warPower);
}
function tryWound():bool{
return false;
}
function continueWar(&$noRice):bool{
//전투가 가능하면 true
$noRice = false;
return false;
}
function logBattleResult(){
$this->getLogger()->pushBattleResultTemplate($this, $this->getOppose());
}
function applyDB($db):bool{
throw new NotInheritedMethodException();
}
function criticalDamage():float{
//전특, 병종에 따라 필살 데미지가 달라질지도 모르므로 static 함수는 아닌 것으로
return Util::randRange(1.3, 2.0);
}
}
+153
View File
@@ -0,0 +1,153 @@
<?php
namespace sammo;
class WarUnitCity extends WarUnit{
protected $hp;
protected $cityRate;
function __construct($raw, $rawNation, $year, $month, $cityRate){
$this->raw = $raw;
$this->rawNation = $rawNation;
$this->isAttacker = false;
$this->cityRate = $cityRate;
$this->logger = new ActionLogger(
0,
$this->getVar('nation'),
$year,
$month,
false
);
$this->crewType = GameUnitConst::byID(GameUnitConst::T_CASTLE);
$this->hp = $this->getVar('def') * 10;
//수비자 보정
if($this->getCityVar('level') == 1){
$this->trainBonus += 5;
}
else if($this->getCityVar('level') == 3){
$this->trainBonus += 5;
}
}
function getName():string{
return $this->getVar('name');
}
function getCityVar(string $key){
return $this->raw[$key];
}
function increaseKilled(int $damage):int{
$this->killed += $damage;
$this->killedCurr += $damage;
return $this->killed;
}
function getComputedTrain(){
return $this->cityRate + $this->trainBonus;
}
function getComputedAtmos(){
return $this->cityRate + $this->atmosBonus;
}
function getHP():int{
return $this->hp;
}
function decreaseHP(int $damage):int{
$damage = min($damage, $this->hp);
$this->dead += $damage;
$this->deadCurr += $damage;
$this->hp -= $damage;
$this->increaseVarWithLimit('wall', -$damage/20, 0);
return $this->hp;
}
function continueWar(&$noRice):bool{
//전투가 가능하면 true
$noRice = false;
if($this->getHP() <= 0){
return false;
}
//도시 성벽은 쌀이 소모된다고 항복하지 않음
return true;
}
function heavyDecreseWealth(){
$this->multiplyVar('agri', 0.5);
$this->multiplyVar('comm', 0.5);
$this->multiplyVar('secu', 0.5);
}
function finishBattle(){
if($this->isFinished){
return;
}
$this->isFinished = true;
$this->updateVar('def', Util::round($this->getHP() / 10));
$this->updateVar('wall', Util::round($this->getVar('wall')));
//NOTE: 전투로 인한 사망자는 여기서 처리하지 않음
$decWealth = $this->dead / 10;
$this->increaseVarWithLimit('agri', -$decWealth, 0);
$this->increaseVarWithLimit('comm', -$decWealth, 0);
$this->increaseVarWithLimit('secu', -$decWealth, 0);
}
function addConflict():bool{
$conflict = Json::decode($this->getVar('conflict'));
$oppose = $this->getOppose();
$nationID = $oppose->getNationVar('nation');
$newConflict = false;
$dead = max(1, $this->dead);
if(!$conflict || $this->getHP() == 0){ // 선타, 막타 보너스
$dead *= 1.05;
}
if(!$conflict){
$conflict = [$nationID => $dead];
}
else if(key_exists($nationID, $conflict)){
$conflict[$nationID] += $dead;
arsort($conflict);
}
else{
$conflict[$nationID] = $dead;
arsort($conflict);
$newConflict = true;
}
$this->updateVar('conflict', Json::encode($conflict));
return $newConflict;
}
function applyDB($db):bool{
$updateVals = [];
foreach(array_keys($this->updatedVar) as $key){
$updateVals[$key] = $this->raw[$key];
}
if(!$updateVals){
return false;
}
$db->update('city', $updateVals, 'city=%i', $this->raw['city']);
$this->getLogger()->rollback(); //수비 도시의 로그는 기록하지 않음
return $db->affectedRows() > 0;
}
}
+968
View File
@@ -0,0 +1,968 @@
<?php
namespace sammo;
class WarUnitGeneral extends WarUnit{
protected $rawCity;
protected $bonusPhase = 0;
function __construct($raw, $rawCity, $rawNation, $isAttacker, $year, $month){
setLeadershipBonus($raw, $rawNation['level']);
$this->raw = $raw;
$this->rawCity = $rawCity; //read-only
$this->rawNation = $rawNation; //read-only
$this->isAttacker = $isAttacker;
$this->logger = new ActionLogger(
$this->getVar('no'),
$this->getVar('nation'),
$year,
$month,
false
);
$this->crewType = GameUnitConst::byID($this->getVar('crewtype'));
$cityLevel = $this->getCityVar('level');
if($isAttacker){
//공격자 보정
if($cityLevel == 2){
$this->atmosBonus += 5;
}
if($rawNation['capital'] == $this->getCityVar('city')){
$this->atmosBonus += 5;
}
}
else{
//수비자 보정
if($cityLevel == 1){
$this->trainBonus += 5;
}
else if($cityLevel == 3){
$this->trainBonus += 5;
}
}
}
function getName():string{
return $this->getVar('name');
}
function getCityVar(string $key){
return $this->rawCity[$key];
}
function getSpecialDomestic():int{
return $this->getVar('special');
}
function setOppose(?WarUnit $oppose){
parent::setOppose($oppose);
$this->increaseVar('warnum', 1);
if($this->isAttacker){
$this->updateVar('recwar', $this->getVar('turntime'));
}
else if($oppose !== null){
$this->updateVar('recwar', $oppose->getVar('turntime'));
}
}
function getSpecialWar():int{
return $this->getVar('special2');
}
function getCharacter():int{
return $this->getVar('personal');
}
function getItem():int{
return $this->getVar('item');
}
function getMaxPhase():int{
$phase = $this->getCrewType()->speed;
if($this->getSpecialWar() == 60){
$phase += 1;
}
return $phase + $this->bonusPhase;
}
function addTrain(int $train){
$this->increaseVarWithLimit('train', $train, 0, GameConst::$maxTrainByWar);
}
function addAtmos(int $atmos){
$this->increaseVarWithLimit('atmos', $train, 0, GameConst::$maxAtmosByWar);
}
function getComputedTrain(){
$train = $this->getVar('train');
$train += $this->trainBonus;
return $train;
}
function getComputedAtmos(){
$atmos = $this->getVar('atmos');
$atmos += $this->atmosBonus;
return $atmos;
}
function getComputedCriticalRatio():float{
$critialRatio = $this->getCrewType()->getCriticalRatio($this->getRaw());
$specialWar = $this->getSpecialWar();
$item = $this->getItem();
if($specialWar == 61){
if($this->isAttacker){
$critialRatio += 0.1;
}
}
else if($specialWar == 71){
$critialRatio += 0.2;
}
return $critialRatio;
}
function getComputedAvoidRatio():float{
$specialWar = $this->getSpecialWar();
$item = $this->getItem();
$avoidRatio = $this->getCrewType()->avoid / 100;
$avoidRatio *= $this->getComputedTrain() / 100;
//특기보정 : 궁병
if($specialWar == 51){
$avoidRatio += 0.2;
}
//도구 보정 : 둔갑천서, 태평요술
if($item == 26 || $item == 25){
$avoidRatio += 0.2;
}
return $avoidRatio;
}
function addWin(){
$this->increaseVar('killnum', 1);
$this->multiplyVarWithLimit('atmos', 1.1, null, GameConst::$maxAtmosByWar);
$this->addStatExp(1);
}
function addStatExp(int $value = 1){
if($this->crewType->armType == GameUnitConst::T_WIZARD) { // 귀병
$this->increaseVar('intel2', $value);
} elseif($this->crewType->armType == GameUnitConst::T_SIEGE) { // 차병
$this->increaseVar('leader2', $value);
} else {
$this->increaseVar('power2', $value);
}
}
function addLevelExp(float $value){
if(!$this->isAttacker){
$value *= 0.8;
}
$value *= getCharExpMultiplier($this->getCharacter());
$this->increaseVar('experience', $value);
}
function addDedication(float $value){
$value *= getCharDedMultiplier($this->getCharacter());
$this->increaseVar('dedication', $value);
}
function addLose(){
$this->increaseVar('deathnum', 1);
$this->addStatExp(1);
}
protected function getWarPowerMultiplyBySpecialWar():array{
//TODO: 장기적으로 if문이 아니라 객체를 이용하여 처리해야함
$myWarPowerMultiply = 1.0;
$opposeWarPowerMultiply = 1.0;
$specialWar = $this->getSpecialWar();
if($specialWar == 53){
if($this->getOppose() instanceof WarUnitCity){
$myWarPowerMultiply *= 2;
}
}
else if($specialWar == 52){
if($this->isAttacker){
$myWarPowerMultiply *= 1.20;
}
else{
$myWarPowerMultiply *= 1.10;
}
}
else if($specialWar == 60){
if($this->isAttacker){
$myWarPowerMultiply *= 1.10;
}
}
else if($specialWar == 61){
$myWarPowerMultiply *= 1.10;
}
else if($specialWar == 50){
if($this->isAttacker){
$opposeWarPowerMultiply *= 0.9;
}
else{
$opposeWarPowerMultiply *= 0.8;
}
}
else if($specialWar == 62){
if ($this->isAttacker) {
$opposeWarPowerMultiply *= 0.9;
}
else{
$myWarPowerMultiply *= 1.1;
}
}
else if($specialWar == 75){
$opposeCrewType = $this->oppose->getCrewType();
if($opposeCrewType->reqCities || $opposeCrewType->reqRegions){
$myWarPowerMultiply *= 1.1;
$opposeWarPowerMultiply *= 0.9;
}
}
return [$myWarPowerMultiply, $opposeWarPowerMultiply];
}
function computeWarPower(){
[$warPower,$opposeWarPowerMultiply] = parent::computeWarPower();
$generalNo = $this->getVar('no');
$genLevel = $this->getVar('level');
if($this->isAttacker){
if($genLevel == 12){
$warPower *= 1.10;
}
else if($genLevel == 11 | $genLevel == 10 || $genLevel == 8 || $genLevel == 6){
$warPower *= 1.05;
}
}
else{
if($genLevel == 12){
$opposeWarPowerMultiply *= 0.90;
}
else if($genLevel == 11 || $genLevel == 9 || $genLevel == 7 || $genLevel == 5){
$opposeWarPowerMultiply *= 0.95;
}
else if($genLevel == 4 && $generalNo == $this->getCityVar('gen1')){
$opposeWarPowerMultiply *= 0.95;
}
else if($genLevel == 3 && $generalNo == $this->getCityVar('gen2')){
$opposeWarPowerMultiply *= 0.95;
}
else if($genLevel == 2 && $generalNo == $this->getCityVar('gen3')){
$opposeWarPowerMultiply *= 0.95;
}
}
$expLevel = $this->getVar('explevel');
if($this->getOppose() instanceof WarUnitCity){
$warPower *= 1 + $expLevel / 600;
}
else{
$warPower /= max(0.01, 1 - $expLevel / 300);
$opposeWarPowerMultiply *= max(0.01, 1 - $expLevel / 300);
}
[$specialMyWarPowerMultiply, $specialOpposeWarPowerMultiply] = $this->getWarPowerMultiplyBySpecialWar();
$warPower *= $specialMyWarPowerMultiply;
$opposeWarPowerMultiply *= $specialOpposeWarPowerMultiply;
$this->warPower = $warPower;
$this->oppose->setWarPowerMultiply($opposeWarPowerMultiply);
return [$warPower,$opposeWarPowerMultiply];
}
///전투 개시 시에 작동하여 1회에만 작동하는 아이템
function useBattleInitItem():bool{
$item = $this->getItem();
if($item == 0){
return false;
}
$itemActivated = false;
$itemConsumed = false;
$itemName = getItemName($item);
if($item == 3){
//탁주 사용
$this->addAtmos(3);
$itemActivated = true;
$itemConsumed = true;
}
else if($item >= 14 && $item <= 16){
//의적주, 두강주, 보령압주 사용
$this->addAtmos(5);
$itemActivated = true;
}
else if($item >= 19 && $item <= 20){
//춘화첩, 초선화 사용
$this->addAtmos(7);
$itemActivated = true;
}
else if($item == 4){
//청주 사용
$this->addTrain(3);
$itemActivated = true;
$itemConsumed = true;
}
else if($item >= 12 && $item <= 13){
//과실주, 이강주 사용
$this->addTrain(5);
$itemActivated = true;
}
else if($item >= 18 && $item <= 18){
//철벽서, 단결도 사용
$this->addTrain(7);
$itemActivated = true;
}
if($itemConsumed){
$this->updateVar('item', 0);
$josaUl = JosaUtil::pick($itemName, '을');
$this->getLogger()->pushGeneralActionLog("<C>{$itemName}</>{$josaUl} 사용!", ActionLogger::PLAIN);
}
return $itemActivated;
}
///전투 개시 시에 작동하여 매 장수마다 작동하는 스킬
function checkBattleBeginSkill():bool{
$skillResult = false;
$oppose = $this->getOppose();
$specialWar = $this->getSpecialWar();
if (
$specialWar == 70 &&
$this->oppose instanceof WarUnitGeneral &&
!$this->hasActivatedSkill('저격') &&
Util::randBool(1/3)
) {
$this->activateSkill('저격');
$skillResult = true;
}
return $skillResult;
}
///전투 개시 시에 작동하여 매 장수마다 작동하는 아이템
function checkBattleBeginItem():bool{
$item = $this->getItem();
$oppose = $this->getOppose();
if(!$item){
return false;
}
$itemActivated = false;
$itemConsumed = false;
$itemName = getItemName($item);
if(
$item == 2 &&
$this->oppose instanceof WarUnitGeneral &&
!$this->hasActivatedSkill('저격') &&
Util::randBool(1/5)
){
$itemActivated = true;
$itemConsumed = true;
$this->activateSkill('저격');
}
if($itemConsumed){
//NOTE: 소비 아이템은 하나인가?, 1회용인가?
$this->updateVar('item', 0);
$josaUl = JosaUtil::pick($itemName, '을');
$this->getLogger()->pushGeneralActionLog("<C>{$itemName}</>{$josaUl} 사용!", ActionLogger::PLAIN);
}
return $itemActivated;
}
function applyBattleBeginSkillAndItem():bool{
$result = false;
$oppose = $this->getOppose();
if($oppose->hasActivatedSkill('저격')){
$result = true;
$oppose->getLogger()->pushGeneralActionLog("상대를 <C>저격</>했다!", ActionLogger::PLAIN);
$oppose->getLogger()->pushGeneralBattleDetailLog("상대를 <C>저격</>했다!", ActionLogger::PLAIN);
$this->getLogger()->pushGeneralActionLog("상대에게 <R>저격</>당했다!", ActionLogger::PLAIN);
$this->getLogger()->pushGeneralBattleDetailLog("상대에게 <R>저격</>당했다!", ActionLogger::PLAIN);
$this->increaseVarWithLimit('injury', Util::randRangeInt(20, 60), null, 80);
}
return $result;
}
function getHP():int{
return $this->getVar('crew');
}
function addDex(GameUnitDetail $crewType, float $exp){
$armType = $crewType->armType;
if($armType == GameUnitConst::T_CASTLE){
$armType = GameUnitConst::T_SIEGE;
}
if($armType < 0){
return;
}
if($armType == GameUnitConst::T_WIZARD) {
$exp *= 0.9;
}
else if($armType == GameUnitConst::T_SIEGE) {
$exp *= 0.9;
}
$exp *= ($this->getComputedTrain() + $this->getComputedAtmos()) / 200;
$ntype = $armType*10;
$dexType = "dex{$ntype}";
$this->increaseVar($dexType, $exp);
}
function decreaseHP(int $damage):int{
$damage = min($damage, $this->getVar('crew'));
$this->dead += $damage;
$this->deadCurr += $damage;
$this->increaseVar('crew', -$damage);
$addDex = $damage;
if(!$this->isAttacker){
$addDex *= 0.9;
}
$this->addDex($this->oppose->getCrewType(), $addDex);
return $this->getVar('crew');
}
function increaseKilled(int $damage):int{
$this->addLevelExp($damage / 50);
$rice = $damage / 100;
if(!$this->isAttacker){
$rice *= 0.8;
}
$rice *= getCharExpMultiplier($this->getCharacter());
$rice *= $this->crewType->rice;
$rice *= getTechCost($this->getNationVar('tech'));
$this->increaseVarWithLimit('rice', -$rice, 0);
$addDex = $damage;
if(!$this->isAttacker){
$addDex *= 0.9;
}
$this->addDex($this->getCrewType(), $addDex);
$this->killed += $damage;
$this->killedCurr += $damage;
return $this->killed;
}
function checkPreActiveSkill():bool{
$activated = false;
$oppose = $this->getOppose();
$specialWar = $this->getSpecialWar();
$item = $this->getItem();
$crewType = $this->getCrewType();
if(
!$this->hasActivatedSkill('특수') &&
!$this->isAttacker &&
$crewType->name == '목우'
){
//XXX: 병종에 특수 스킬이 달려있도록 설정해야함
$ratio = $this->getComputedAtmos() + $this->getComputedTrain();
if(Util::randBool($ratio / 400)){
$this->activateSkill('특수', '저지');
$activated = true;
}
}
if(
$specialWar == 63 &&
$this->getPhase() == 0 &&
$this->getHP() >= 1000 &&
$this->getComputedAtmos() >= 90 &&
$this->getComputedTrain() >= 90
){
$this->activateSkill('위압');
$activated = true;
}
return $activated;
}
function checkActiveSkill():bool{
$activated = false;
$oppose = $this->getOppose();
$specialWar = $this->getSpecialWar();
$item = $this->getItem();
$crewType = $this->getCrewType();
if ($specialWar == 60 && $oppose->hasActivatedSkill('저지')) {
$oppose->deactivateSkill('특수', '저지');
$activated = true;
}
if(
!$this->hasActivatedSkill('특수') &&
Util::randBool($this->getComputedCriticalRatio())
){
$this->activateSkill('특수', '필살시도', '필살');
$activated = true;
}
if(
!$this->hasActivatedSkill('특수') &&
Util::randBool($this->getComputedAvoidRatio())
){
$this->activateSkill('특수', '회피시도', '회피');
$activated = true;
}
//계략
if($crewType->magicCoef){
$magicRatio = getGeneralIntel($this->raw, true, true, true, false) / 100;
$magicRatio *= $crewType->magicCoef;
if($specialWar == 41){
$magicRatio += 0.2;
}
if(Util::randBool($magicRatio)){
$magicSuccessRatio = 0.7;
if($specialWar == 40){
$magicSuccessRatio += 0.2;
}
if($specialWar == 41){
$magicSuccessRatio += 0.2;
}
if($specialWar == 42){
$magicSuccessRatio += 0.1;
}
if($specialWar == 44){
$magicSuccessRatio += 1;
}
if($oppose instanceof WarUnitCity){
$magic = Util::choiceRandom(['급습', '위보',' 혼란']);
}
else{
$magic = Util::choiceRandom(['위보', '매복', '반목', '화계', '혼란']);
}
$this->activateSkill('계략시도', $magic);
if(Util::randBool($magicSuccessRatio)){
$this->activateSkill('계략');
}
else{
$this->activateSkill('계략실패');
}
}
}
//의술
if($specialWar == 73 && Util::randBool(0.2)){
$this->activateSkill('치료');
$activated = true;
}
return $activated;
}
function checkPostActiveSkill():bool{
$activated = false;
$oppose = $this->getOppose();
$specialWar = $this->getSpecialWar();
$item = $this->getItem();
$crewType = $this->getCrewType();
if($specialWar == 74 && $oppose->hasActivatedSkill('필살')){
if($this->isAttacker){
if(Util::randBool(1/3)){
$this->activateSkill('진노', '격노');
$activated = true;
}
else if(Util::randBool(1/4)){
$this->activateSkill('격노');
$activated = true;
}
}
else{
if(Util::randBool(1/2)){
$this->activateSkill('격노');
$activated = true;
}
}
}
if(
$specialWar == 74 &&
$oppose->hasActivatedSkill('회피')
){
if($this->isAttacker){
if(Util::randBool(1/3)){
$this->activateSkill('진노', '격노');
$oppose->deactivateSkill('회피');
$activated = true;
}
else if(Util::randBool(1/4)){
$this->activateSkill('격노');
$oppose->deactivateSkill('회피');
$activated = true;
}
}
else{
if(Util::randBool(1/2)){
$this->activateSkill('격노');
$oppose->deactivateSkill('회피');
$activated = true;
}
}
}
if(
($item == 23 || $item == 24) &&
!$this->hasActivatedSkill('치료') &&
Util::randBool(0.2)
){
$this->activateSkill('치료');
$activated = true;
}
//계략
if(
$specialWar == 45 &&
$oppose->hasActivatedSkill('계략') &&
Util::randBool(0.3)
){
$this->activateSkill('반계');
$oppose->deactivateSkill('계략');
$activated = true;
}
if(
$specialWar == 42 &&
$this->hasActivatedSkill('계략')
){
$this->warPowerMultiply *= 1.3;
}
if(
$specialWar == 43 &&
$this->hasActivatedSkill('계략')
){
$this->warPowerMultiply *= 1.5;
}
return $activated;
}
function applyActiveSkill(){
$oppose = $this->getOppose();
$crewType = $this->getCrewType();
$specialWar = $this->getSpecialWar();
$thisLogger = $this->getLogger();
$opposeLogger = $oppose->getLogger();
if($this->hasActivatedSkill('저지')){
$this->setWarPowerMultiply(0);
$oppose->setWarPowerMultiply(0);
$thisLogger->pushGeneralBattleDetailLog('상대를 <C>저지</>했다!</>');
$opposeLogger->pushGeneralBattleDetailLog('저지</>당했다!</>');
//저지는 특수함.
return;
}
yield true;
//계략 세트
if($this->hasActivatedSkill('계략')){
$tableToGeneral = [
'위보'=>1.2,
'매복'=>1.4,
'반목'=>1.6,
'화계'=>1.8,
'혼란'=>2.0
];
$tableToCity = [
'급습'=>1.2,
'위보'=>1.4,
'혼란'=>1.6
];
if($specialWar == 45){
$tableToGeneral['반목'] *= 2;
}
if($oppose instanceof WarUnitCity){
$table = $tableToCity;
}
else{
$table = $tableToGeneral;
}
foreach($table as $skillKey => $skillMultiply){
if($this->hasActivatedSkill($skillKey)){
$josaUl = \sammo\JosaUtil::pick($skillKey, '을');
$thisLogger->pushGeneralBattleDetailLog("<D>{$skillKey}</>{$josaUl} <C>성공</>했다!");
$opposeLogger->pushGeneralBattleDetailLog("<D>{$skillKey}</>에 당했다!");
$this->multiplyWarPowerMultiply($skillMultiply);
break;
}
}
}
yield true;
//반계 세트
if($this->hasActivatedSkill('반계')){
$table = [
'위보'=>1.2,
'매복'=>1.4,
'반목'=>1.6,
'화계'=>1.8,
'혼란'=>2.0
];
foreach($table as $skillKey => $skillMultiply){
if($oppose->hasActivatedSkill($skillKey)){
$josaUl = \sammo\JosaUtil::pick($skillKey, '을');
$thisLogger->pushGeneralBattleDetailLog("<C>●</><C>반계</>로 상대의 <D>{$skillKey}</>{$josaUl} 되돌렸다!");
$opposeLogger->pushGeneralBattleDetailLog("<D>{$skillKey}</>{$josaUl} <R>역으로</> 당했다!");
$this->multiplyWarPowerMultiply($skillMultiply);
break;
}
}
}
yield true;
//계략 실패 세트
if($this->hasActivatedSkill('계략실패')){
$tableToGeneral = [
'위보'=>1.1,
'매복'=>1.2,
'반목'=>1.3,
'화계'=>1.4,
'혼란'=>1.5
];
$tableToCity = [
'급습'=>1.1,
'위보'=>1.2,
'혼란'=>1.3
];
if($oppose instanceof WarUnitCity){
$table = $tableToCity;
}
else{
$table = $tableToGeneral;
}
foreach($table as $skillKey => $skillMultiply){
if($this->hasActivatedSkill($skillKey)){
$josaUl = \sammo\JosaUtil::pick($skillKey, '을');
$thisLogger->pushGeneralBattleDetailLog("<D>{$skillKey}</>{$josaUl} <C>실패</>했다!");
$opposeLogger->pushGeneralBattleDetailLog("<D>{$skillKey}</>{$josaUl} 간파했다!");
$this->multiplyWarPowerMultiply($skillMultiply);
$oppose->multiplyWarPowerMultiply(1/$skillMultiply);
break;
}
}
}
yield true;
if($this->hasActivatedSkill('치료')){
$thisLogger->pushGeneralBattleDetailLog("<C>치료</>했다!</>");
$oppose->multiplyWarPowerMultiply(1/1.5);
}
yield true;
if($this->hasActivatedSkill('필살')){
$thisLogger->pushGeneralBattleDetailLog('<C>필살</>공격!</>');
$opposeLogger->pushGeneralBattleDetailLog('상대의 <R>필살</>공격!</>');
$this->multiplyWarPowerMultiply($this->criticalDamage());
}
yield true;
if($this->hasActivatedSkill('회피')){
$thisLogger->pushGeneralBattleDetailLog('회피</>했다!</>');
$opposeLogger->pushGeneralBattleDetailLog('상대가 <R>회피</>했다!</>"');
$oppose->multiplyWarPowerMultiply(0.2);
}
yield true;
if($this->hasActivatedSkill('진노')){
if($oppose->hasActivatedSkill('필살')){
$thisLogger->pushGeneralBattleDetailLog('상대의 필살 공격에 <C>진노</>했다!</>');
$opposeLogger->pushGeneralBattleDetailLog('필살 공격에 상대가 <R>진노</>했다!</>');
}
else if($oppose->hasActivatedSkill('회피시도')){
$thisLogger->pushGeneralBattleDetailLog('상대의 회피 시도에 <C>진노</>했다!</>');
$opposeLogger->pushGeneralBattleDetailLog('회피 시도에 상대가 <R>진노</>했다!</>');
}
$this->bonusPhase += 1;
$this->multiplyWarPowerMultiply($this->criticalDamage());
}
else if($this->hasActivatedSkill('격노')){
if($oppose->hasActivatedSkill('필살')){
$thisLogger->pushGeneralBattleDetailLog('상대의 필살 공격에 <C>격노</>했다!</>');
$opposeLogger->pushGeneralBattleDetailLog('필살 공격에 상대가 <R>격노</>했다!</>');
}
else if($oppose->hasActivatedSkill('회피시도')){
$thisLogger->pushGeneralBattleDetailLog('상대의 회피 시도에 <C>격노</>했다!</>');
$opposeLogger->pushGeneralBattleDetailLog('회피 시도에 상대가 <R>격노</>했다!</>');
}
$this->multiplyWarPowerMultiply($this->criticalDamage());
}
yield true;
if($this->hasActivatedSkill('위압')){
$thisLogger->pushGeneralBattleDetailLog('상대에게 <C>위압</>을 줬다!</>');
$opposeLogger->pushGeneralBattleDetailLog('상대에게 <R>위압</>받았다!</>');
$oppose->setWarPowerMultiply(0);
}
yield true;
}
function tryWound():bool{
if(!Util::randBool(0.05)){
return false;
}
$this->increaseVarWithLimit('injury', Util::randRangeInt(10, 80), null, 80);
$this->getLogger()->pushGeneralActionLog("전투중 <R>부상</>당했다!", ActionLogger::PLAIN);
return true;
}
function continueWar(&$noRice):bool{
if($this->getHP() <= 0){
$noRice = false;
return false;
}
if($this->getVar('rice') <= $this->getHP() / 100){
$noRice = true;
return false;
}
return true;
}
///checkAbility의 method 버전
function checkStatChange():bool{
//FIXME: 장기적으로는 General 클래스가 별도로 있어야 함
$logger = $this->getLogger();
$limit = GameConst::$upgradeLimit;
$table = [
['통솔', 'leader'],
['무력', 'power'],
['지력', 'intel'],
];
$result = false;
foreach($table as [$statNickName, $statName]){
$statExpName = $statName.'2';
if($this->getVar($statExpName) < 0){
$logger->pushGeneralActionLog("<R>{$statNickName}</>이 <C>1</> 떨어졌습니다!", ActionLogger::PLAIN);
$this->increaseVar($statExpName, $limit);
$this->increaseVar($statName, -1);
$result = true;
}
else if($this->getVar($statExpName) >= $limit){
$logger->pushGeneralActionLog("<R>{$statNickName}</>이 <C>1</> 올랐습니다!", ActionLogger::PLAIN);
$this->increaseVar($statExpName, -$limit);
$this->increaseVar($statName, 1);
$result = true;
}
}
return $result;
}
function finishBattle(){
if($this->isFinished){
return;
}
$this->isFinished = true;
$this->increaseVar('killcrew', $this->killed);
$this->increaseVar('deathcrew', $this->dead);
$this->updateVar('rice', Util::round($this->getVar('rice')));
$this->updateVar('experience', Util::round($this->getVar('experience')));
$this->updateVar('dedication', Util::round($this->getVar('dedication')));
$this->checkStatChange();
}
/**
* @param \MeekroDB $db
*/
function applyDB($db):bool{
$updateVals = [];
foreach(array_keys($this->updatedVar) as $key){
$updateVals[$key] = $this->raw[$key];
}
if(!$updateVals){
return false;
}
$db->update('general', $updateVals, 'no=%i', $this->raw['no']);
$this->getLogger()->flush();
return $db->affectedRows() > 0;
}
}
+125
View File
@@ -0,0 +1,125 @@
<?php
namespace sammo;
class CityConst extends CityConstBase{
public static $regionMap = [
'호넷 마인령'=>1,1=>'호넷 마인령',
'케이브리스 마인령'=>2,2=>'케이브리스 마인령',
'카라의 숲'=>3,3=>'카라의 숲',
'샹그릴라'=>4,4=>'샹그릴라',
'제스 북부'=>5,5=>'제스 북부',
'제스 남부'=>6,6=>'제스 남부',
'헬만 서부'=>7,7=>'헬만 서부',
'헬만 동부'=>8,8=>'헬만 동부',
'리자스 남부'=>9,9=>'리자스 남부',
'리자스 북부'=>10,10=>'리자스 북부',
'JAPAN'=>11,11=>'JAPAN',
'자유도시 동부'=>12,12=>'자유도시 동부',
'자유도시 서부'=>13,13=>'자유도시 서부',
'AL교'=>14,14=>'AL교',
];
protected static $initCity = [
//id, 도시, 규모, 인구, 농, 상, 치, 성, 수,(x100)지역, x, y, 연결도시
[ 1, '구 마왕성', '특', 8000,120,120,100,120,120, '호넷 마인령', 35, 142, ['악의 탑','한탄의 협곡','유황의 숲']],
[ 2, '악의 탑', '이', 3500, 40, 40, 20, 40, 40, '호넷 마인령', 45, 40, ['반리요새 A','구 마왕성']],
[ 3, '실키의 성', '중', 5500, 80, 80, 60, 80, 80, '호넷 마인령', 45, 270, ['유황의 숲','카스케도바우','죽음의 대지']],
[ 4, '카스케도바우', '중', 5500, 80, 80, 60, 80, 80, '호넷 마인령', 120, 276, ['실키의 성','케셀링크의 성']],
[ 5, '붉은 집', '수', 2500, 20, 20, 20, 40, 40, '케이브리스 마인령', 70, 335, ['케이브리스의 성','케셀링크의 성']],
[ 6, '케셀링크의 성', '대', 7000,100,100, 80,100,100, '케이브리스 마인령', 135, 338, ['붉은 집','메이드의 묘지','카스케도바우','뼈의 숲']],
[ 7, '케이브리스의 성', '특', 8000,120,120,100,120,120, '케이브리스 마인령', 37, 384, ['붉은 집','푸른 집','죽음의 대지']],
[ 8, '푸른 집', '수', 2500, 20, 20, 20, 40, 40, '케이브리스 마인령', 59, 446, ['케이브리스의 성','메이드의 묘지','카미라의 성']],
[ 9, '한탄의 협곡', '소', 4500, 60, 60, 40, 60, 60, '호넷 마인령', 97, 152, ['구 마왕성','반리요새 B']],
[10, '뼈의 숲', '소', 4500, 60, 60, 40, 60, 60, '케이브리스 마인령', 160, 386, ['케셀링크의 성','마지노 A']],
[11, '유황의 숲', '소', 4500, 60, 60, 40, 60, 60, '호넷 마인령', 72, 209, ['구 마왕성','실키의 성']],
[12, '카미라의 성', '대', 7000,100,100, 80,100,100, '케이브리스 마인령', 130, 460, ['푸른 집','갈라놓은 숲']],
[13, '메이드의 묘지', '이', 3500, 40, 40, 20, 40, 40, '케이브리스 마인령', 102, 380, ['케셀링크의 성','푸른 집']],
[14, '갈라놓은 숲', '소', 4500, 60, 60, 40, 60, 60, '케이브리스 마인령', 186, 472, ['카미라의 성','마지노 B']],
[15, '죽음의 대지', '이', 3500, 40, 40, 20, 40, 40, '케이브리스 마인령', 10, 320, ['케이브리스의 성','실키의 성']],
[16, '녹의 마을', '소', 4500, 60, 60, 40, 60, 60, '카라의 숲', 202, 290, ['마지노 A','파리티라온']],
[17, '펜실 카우', '이', 3500, 40, 40, 20, 40, 40, '카라의 숲', 297, 267, ['파리티라온','라보리']],
[18, '샹그릴라', '대', 7000,100,100, 80,100,100, '샹그릴라', 374, 272, ['스도리 13','보르고 Z','사바사바','릿치']],
[19, '파리티라온', '중', 5500, 80, 80, 60, 80, 80, '제스 북부', 259, 332, ['녹의 마을','마지노 A','왕자의 탑','펜실 카우']],
[20, '왕자의 탑', '소', 4500, 60, 60, 40, 60, 60, '제스 북부', 259, 367, ['파리티라온','도약의 탑','일요일의 탑','라그나로크 아크']],
[21, '도약의 탑', '소', 4500, 60, 60, 40, 60, 60, '제스 남부', 265, 406, ['왕자의 탑','라그나로크 아크','탄창의 탑','마크']],
[22, '일요일의 탑', '소', 4500, 60, 60, 40, 60, 60, '제스 북부', 324, 358, ['왕자의 탑','라그나로크 아크','탄창의 탑','나가르모르']],
[23, '탄창의 탑', '소', 4500, 60, 60, 40, 60, 60, '제스 남부', 331, 409, ['도약의 탑','라그나로크 아크','일요일의 탑','올드제스']],
[24, '라그나로크 아크', '특', 8000,120,120,100,120,120, '제스 북부', 295, 385, ['왕자의 탑','도약의 탑','도약의 탑','탄창의 탑','일요일의 탑']],
[25, '알텐누', '중', 5500, 80, 80, 60, 80, 80, '제스 남부', 293, 482, ['마크','마지노 B']],
[26, '마크', '중', 5500, 80, 80, 60, 80, 80, '제스 남부', 288, 436, ['알텐누','호박성','도약의 탑']],
[27, '호박성', '이', 3500, 40, 40, 20, 40, 40, '제스 남부', 328, 458, ['마크','올드제스']],
[28, '올드제스', '특', 8000,120,120,100,120,120, '제스 남부', 367, 444, ['탄창의 탑','호박성','테이브','카이즈']],
[29, '테이브', '소', 4500, 60, 60, 40, 60, 60, '제스 남부', 385, 406, ['이탈리아','올드제스']],
[30, '이탈리아', '대', 7000,100,100, 80,100,100, '제스 북부', 375, 361, ['테이브','사바사바','아담의탑']],
[31, '나가르모르', '중', 5500, 80, 80, 60, 80, 80, '제스 북부', 322, 322, ['일요일의 탑','사바사바']],
[32, '사바사바', '대', 7000,100,100, 80,100,100, '제스 북부', 375, 324, ['나가르모르','이탈리아','샹그릴라']],
[33, '아담의탑', '진', 2500, 20, 20, 20, 40, 40, '제스 북부', 420, 340, ['이탈리아','파라파라성채']],
[34, '마지노 A', '관', 2500, 20, 20, 20, 90, 90, '제스 북부', 215, 365, ['뼈의 숲','녹의 마을','파리티라온']],
[35, '마지노 B', '관', 2500, 20, 20, 20, 90, 90, '제스 남부', 243, 477, ['갈라놓은 숲','알텐누']],
[36, '이코마', '중', 5500, 80, 80, 60, 80, 80, '헬만 서부', 211, 60, ['반리요새 A','거대전함','워크랜드','로렌그라드']],
[37, '워크랜드', '소', 4500, 60, 60, 40, 60, 60, '헬만 서부', 177, 90, ['이코마','로렌그라드']],
[38, '로렌그라드', '대', 7000,100,100, 80,100,100, '헬만 서부', 200, 126, ['파르나스','랑그바우','이코마','반리요새 B','워크랜드']],
[39, '파르나스', '중', 5500, 80, 80, 60, 80, 80, '헬만 서부', 204, 171, ['로렌그라드','세미타포']],
[40, '라보리', '중', 5500, 80, 80, 60, 80, 80, '헬만 서부', 225, 219, ['펜실 카우','스도리 17']],
[41, '랑그바우', '특', 8000,120,120,100,120,120, '헬만 서부', 263, 135, ['로렌그라드','마이크로그라드']],
[42, '거대전함', '이', 3500, 40, 40, 20, 40, 40, '헬만 서부', 273, 21, ['이코마','파스','호라가의 탑','시베리아']],
[43, '세미타포', '소', 4500, 60, 60, 40, 60, 60, '헬만 서부', 268, 174, ['파르나스','스도리 17']],
[44, '스도리 17', '진', 2500, 20, 20, 20, 40, 40, '헬만 서부', 296, 214, ['라보리','세미타포','스도리 13']],
[45, '스도리 13', '진', 2500, 20, 20, 20, 40, 40, '헬만 서부', 359, 217, ['샹그릴라','폰','스도리 17','코사크','보르고 Z']],
[46, '마이크로그라드', '소', 4500, 60, 60, 40, 60, 60, '헬만 서부', 316, 166, ['폰','랑그바우','스도리 10']],
[47, '폰', '중', 5500, 80, 80, 60, 80, 80, '헬만 서부', 377, 187, ['마이크로그라드','스도리 13','코사크']],
[48, '파스', '중', 5500, 80, 80, 60, 80, 80, '헬만 서부', 286, 90, ['거대전함','큐로브','스도리 10']],
[49, '큐로브', '소', 4500, 60, 60, 40, 60, 60, '헬만 서부', 341, 96, ['파스','소로토이']],
[50, '스도리 10', '진', 2500, 20, 20, 20, 40, 40, '헬만 서부', 337, 137, ['파스','로제스그라드','마이크로그라드']],
[51, '소로토이', '소', 4500, 60, 60, 40, 60, 60, '헬만 동부', 382, 119, ['큐로브','바바로프스']],
[52, '로제스그라드', '특', 8000,120,120,100,120,120, '헬만 동부', 401, 148, ['스도리 10','바바로프스','아크그라드']],
[53, '코사크', '중', 5500, 80, 80, 60, 80, 80, '헬만 동부', 419, 204, ['스도리 13','보르고 Z','폰']],
[54, '아크그라드', '소', 4500, 60, 60, 40, 60, 60, '헬만 동부', 452, 179, ['로그 B','로제스그라드','야크트크']],
[55, '야크트크', '소', 4500, 60, 60, 40, 60, 60, '헬만 동부', 437, 129, ['아크그라드','바바로프스','고라크']],
[56, '시베리아', '대', 7000,100,100, 80,100,100, '헬만 동부', 394, 55, ['바바로프스','호라가의 탑','거대전함']],
[57, '바바로프스', '중', 5500, 80, 80, 60, 80, 80, '헬만 동부', 418, 89, ['시베리아','야크트크','소로토이','로제스그라드']],
[58, '호라가의 탑', '관', 2500, 20, 20, 20, 90, 90, '헬만 동부', 561, 20, ['시베리아','거대전함','떨어진 궁도']],
[59, '고라크', '중', 5500, 80, 80, 60, 80, 80, '헬만 동부', 478, 146, ['블라디보스토크','로그 A','야크트크']],
[60, '블라디보스토크', '이', 3500, 40, 40, 20, 40, 40, '헬만 동부', 500, 109, ['고라크','로그 A']],
[61, '보르고 Z', '관', 2500, 20, 20, 20, 90, 90, '헬만 동부', 436, 245, ['코사크','스도리 13','로그 B', '샹그릴라']],
[62, '로그 A', '관', 2500, 20, 20, 20, 90, 90, '헬만 동부', 506, 183, ['고라크','블라디보스토크','로그 B','스케일']],
[63, '로그 B', '관', 2500, 20, 20, 20, 90, 90, '헬만 동부', 475, 216, ['아크그라드','로그 A','보르고 Z','마우네스']],
[64, '반리요새 A', '진', 2500, 20, 20, 20, 40, 40, '헬만 서부', 149, 18, ['악의 탑','이코마']],
[65, '반리요새 B', '진', 2500, 20, 20, 20, 40, 40, '헬만 서부', 151, 153, ['로렌그라드','한탄의 협곡']],
[66, '파라파라성채', '진', 2500, 20, 20, 20, 40, 40, '리자스 남부', 449, 315, ['아담의탑','릿치']],
[67, '릿치', '중', 5500, 80, 80, 60, 80, 80, '리자스 남부', 476, 288, ['푸아','마우네스','파라파라성채','샹그릴라']],
[68, '푸아', '소', 4500, 60, 60, 40, 60, 60, '리자스 남부', 528, 289, ['릿치','록아스']],
[69, '마우네스', '소', 4500, 60, 60, 40, 60, 60, '리자스 남부', 502, 250, ['릿치','로그 B','노스']],
[70, '스케일', '대', 7000,100,100, 80,100,100, '리자스 북부', 542, 198, ['로그 A','아란','노스']],
[71, '아란', '중', 5500, 80, 80, 60, 80, 80, '리자스 북부', 596, 154, ['떨어진 궁도','포나라','스케일','브리테리아']],
[72, '떨어진 궁도', '이', 3500, 40, 40, 20, 40, 40, '리자스 북부', 598, 111, ['호라가의 탑','아란']],
[73, '포나라', '소', 4500, 60, 60, 40, 60, 60, '리자스 북부', 640, 168, ['아란','브리테리아','웨스']],
[74, '브리테리아', '대', 7000,100,100, 80,100,100, '리자스 북부', 587, 205, ['아란','웨스','포나라']],
[75, '파란치', '소', 4500, 60, 60, 40, 60, 60, '리자스 북부', 667, 229, ['웨스','이스']],
[76, '노스', '중', 5500, 80, 80, 60, 80, 80, '리자스 남부', 563, 255, ['스케일','마우네스','오크','리자스성']],
[77, '오크', '중', 5500, 80, 80, 60, 80, 80, '리자스 남부', 577, 295, ['노스','사우스','지오']],
[78, '리자스성', '특', 8000,120,120,100,120,120, '리자스 남부', 611, 245, ['노스','사우스','웨스']],
[79, '사우스', '소', 4500, 60, 60, 40, 60, 60, '리자스 남부', 618, 285, ['리자스성','오크','이스']],
[80, '이스', '중', 5500, 80, 80, 60, 80, 80, '리자스 남부', 656, 269, ['사우스','파란치','오크스']],
[81, '오크스', '중', 5500, 80, 80, 60, 80, 80, '리자스 남부', 650, 311, ['이스','한나','오슈']],
[82, '웨스', '중', 5500, 80, 80, 60, 80, 80, '리자스 북부', 632, 212, ['리자스성','포나라','파란치','브리테리아']],
[83, '오슈', '이', 3500, 40, 40, 20, 40, 40, 'JAPAN', 688, 308, ['오크스','오와리']],
[84, '오와리', '특', 8000,120,120,100,120,120, 'JAPAN', 679, 394, ['오슈','모로코']],
[85, '모로코', '수', 2500, 20, 20, 20, 40, 40, 'JAPAN', 627, 450, ['오와리','포르투갈']],
[86, '지오', '중', 5500, 80, 80, 60, 80, 80, '자유도시 동부', 578, 333, ['오크','렛드','M랜드']],
[87, '한나', '소', 4500, 60, 60, 40, 60, 60, '자유도시 동부', 632, 342, ['오크스','M랜드']],
[88, 'M랜드', '대', 7000,100,100, 80,100,100, '자유도시 동부', 616, 379, ['지오','한나','렛드','포르투갈']],
[89, '포르투갈', '중', 5500, 80, 80, 60, 80, 80, '자유도시 동부', 599, 422, ['M랜드','투신도시','모로코']],
[90, '투신도시', '이', 3500, 40, 40, 20, 40, 40, '자유도시 동부', 553, 415, ['포르투갈','커스텀','파란쵸 왕국']],
[91, '화성', '소', 4500, 60, 60, 40, 60, 60, '자유도시 서부', 503, 482, ['커스텀']],
[92, '커스텀', '특', 8000,120,120,100,120,120, '자유도시 서부', 506, 416, ['투신도시','지브테리아','라지르','파란쵸 왕국','화성']],
[93, '라지르', '소', 4500, 60, 60, 40, 60, 60, '자유도시 서부', 530, 358, ['렛드','커스텀','아이스']],
[94, '록아스', '중', 5500, 80, 80, 60, 80, 80, '자유도시 서부', 489, 329, ['아이스','푸아']],
[95, '지브테리아', '대', 7000,100,100, 80,100,100, '자유도시 서부', 452, 370, ['아이스','카이즈','커스텀']],
[96, '파란쵸 왕국', '이', 3500, 40, 40, 20, 40, 40, '자유도시 동부', 537, 458, ['커스텀','투신도시']],
[97, '아이스', '소', 4500, 60, 60, 40, 60, 60, '자유도시 서부', 489, 375, ['록아스','지브테리아','라지르']],
[98, '렛드', '중', 5500, 80, 80, 60, 80, 80, '자유도시 서부', 566, 372, ['라지르','M랜드','지오']],
[99, '카이즈', '이', 3500, 40, 40, 20, 40, 40, 'AL교', 439, 425, ['올드제스','지브테리아']],
];
}
-590
View File
@@ -1,590 +0,0 @@
{
"title": "【가상모드17】 루드라사움",
"startYear": 180,
"history": [
"<C>●</>180년 1월:<L><b>【가상모드16】</> 루드라사움",
"<C>●</>180년 1월:<L><b>【이벤트】</b></>제작자 : Cure.",
"<C>●</>180년 1월:<L><b>【이벤트】</b></>도움을주신분 : 네이미님, 거북마루님",
"<C>●</>180년 1월:<L><b>【이벤트】</b></>루드라사움의 세계관을 불러옵니다."
],
"stat": {
"total": 240,
"min": 50,
"max": 100
},
"iconPath": "루드라사움",
"fiction": 0,
"nation":[
],
"diplomacy":[],
"general":[
[0, "3G", null, 0, null, 39, 67, 67, 0, 160, 300, null, null],
[0, "PG 7", "PG-7.png", 0, null, 82, 83, 60, 0, 160, 300, null, null],
[0, "PG 9", "PG-9.png", 0, null, 82, 60, 83, 0, 160, 300, null, null],
[0, "가넷", null, 0, null, 88, 56, 88, 0, 160, 300, null, null],
[0, "가라샤", null, 0, null, 70, 68, 47, 0, 160, 300, null, null],
[0, "가르티아", null, 0, null, 73, 101, 73, 0, 160, 300, null, null],
[0, "가무로아 마티오", "가무로아-마티오.png", 0, null, 60, 40, 60, 0, 160, 300, null, null],
[0, "가와노에 미네", "가와노에-미네.png", 0, null, 71, 71, 71, 0, 160, 300, null, null],
[0, "가와노에 유즈루", "가와노에-유즈루.png", 0, null, 76, 76, 61, 0, 160, 300, null, null],
[0, "가이야스 야스토", null, 0, null, 51, 60, 31, 0, 160, 300, null, null],
[0, "가이젤 고도", null, 0, null, 60, 40, 60, 0, 160, 300, null, null],
[0, "검호", null, 0, null, 74, 80, 59, 0, 160, 300, null, null],
[0, "겐리", null, 0, null, 77, 55, 72, 0, 160, 300, null, null],
[0, "겟코", null, 0, null, 80, 85, 58, 0, 160, 300, null, null],
[0, "고닌자 그린", "고닌자-그린.png", 0, null, 60, 20, 65, 0, 160, 300, null, null],
[0, "고닌자 레드", "고닌자-레드.png", 0, null, 75, 70, 10, 0, 160, 300, null, null],
[0, "고닌자 블랙", "고닌자-블랙.png", 0, null, 70, 65, 20, 0, 160, 300, null, null],
[0, "고닌자 블루", "고닌자-블루.png", 0, null, 65, 75, 15, 0, 160, 300, null, null],
[0, "고닌자 옐로", "고닌자-옐로.png", 0, null, 60, 15, 70, 0, 160, 300, null, null],
[0, "고에몬", null, 0, null, 55, 40, 50, 0, 160, 300, null, null],
[0, "고킨켄", null, 0, null, 70, 83, 44, 0, 160, 300, null, null],
[0, "고토", null, 0, null, 55, 40, 51, 0, 160, 300, null, null],
[0, "곤", null, 0, null, 76, 81, 59, 0, 160, 300, null, null],
[0, "곤도 이사미", null, 0, null, 42, 22, 60, 0, 160, 300, null, null],
[0, "그라크 알카포네", null, 0, null, 55, 40, 52, 0, 160, 300, null, null],
[0, "그린 오니", null, 0, null, 55, 40, 53, 0, 160, 300, null, null],
[0, "기가이", null, 0, null, 80, 99, 63, 0, 160, 300, null, null],
[0, "김치 드라이브", "김치-드라이브.png", 0, null, 34, 67, 68, 0, 160, 300, null, null],
[0, "나기 스 라갈", "나기-스-라갈.png", 0, null, 87, 54, 93, 0, 160, 300, null, null],
[0, "나오에 아이", "나오에-아이.png", 0, null, 92, 49, 72, 0, 160, 300, null, null],
[0, "나와토리", null, 0, null, 75, 75, 61, 0, 160, 300, null, null],
[0, "나토리", null, 0, null, 80, 58, 85, 0, 160, 300, null, null],
[0, "난죠 란", "난죠-란.png", 0, null, 83, 49, 72, 0, 160, 300, null, null],
[0, "네로차페트7세", null, 0, null, 76, 67, 34, 0, 160, 300, null, null],
[0, "네이 우롱", "네이-우롱.png", 0, null, 55, 40, 54, 0, 160, 300, null, null],
[0, "네카이 시스", "네카이-시스.png", 0, null, 78, 69, 38, 0, 160, 300, null, null],
[0, "넬슨 서버", "넬슨-서버.png", 0, null, 79, 60, 50, 0, 160, 300, null, null],
[0, "노기쿠", null, 0, null, 77, 63, 78, 0, 160, 300, null, null],
[0, "노벨", null, 0, null, 55, 40, 55, 0, 160, 300, null, null],
[0, "노스", null, 0, null, 92, 106, 50, 0, 160, 300, null, null],
[0, "노아 하코부네", "노아-하코부네.png", 0, null, 74, 46, 74, 0, 160, 300, null, null],
[0, "노에마세", null, 0, null, 55, 40, 56, 0, 160, 300, null, null],
[0, "누누하라 캐비지", "누누하라-캐비지.png", 0, null, 65, 59, 60, 0, 160, 300, null, null],
[0, "느와르", null, 0, null, 77, 78, 63, 0, 160, 300, null, null],
[0, "니나", null, 0, null, 55, 40, 57, 0, 160, 300, null, null],
[0, "니들", null, 0, null, 76, 76, 54, 0, 160, 300, null, null],
[0, "니코페리", null, 0, null, 87, 52, 97, 0, 160, 300, null, null],
[0, "닛코", null, 0, null, 55, 90, 90, 0, 160, 300, null, null],
[0, "다 게일", "다-게일.png", 0, null, 64, 70, 70, 0, 160, 300, null, null],
[0, "다니엘 세프티", "다니엘-세프티.png", 0, null, 55, 40, 58, 0, 160, 300, null, null],
[0, "다마네기", null, 0, null, 55, 40, 59, 0, 160, 300, null, null],
[0, "다이몬 지타로", null, 0, null, 55, 50, 40, 0, 160, 300, null, null],
[0, "다크란스", null, 0, null, 75, 100, 67, 0, 160, 300, null, null],
[0, "닷지 에반스", null, 0, null, 47, 60, 27, 0, 160, 300, null, null],
[0, "덴저러스 브라보", null, 0, null, 55, 51, 40, 0, 160, 300, null, null],
[0, "덴즈 브라우", null, 0, null, 55, 52, 40, 0, 160, 300, null, null],
[0, "도르한 크리케트", "도르한-크리케트.png", 0, null, 67, 58, 69, 0, 160, 300, null, null],
[0, "도시바", null, 0, null, 89, 32, 59, 0, 160, 300, null, null],
[0, "도코모", null, 0, null, 48, 60, 28, 0, 160, 300, null, null],
[0, "도하라스 해피네스", null, 0, null, 55, 53, 40, 0, 160, 300, null, null],
[0, "돈 도에스스키", "돈-도에스스키.png", 0, null, 55, 54, 40, 0, 160, 300, null, null],
[0, "듀란", null, 0, null, 67, 67, 39, 0, 160, 300, null, null],
[0, "라 사이젤", "라-사이젤.png", 0, null, 84, 103, 59, 0, 160, 300, null, null],
[0, "라 하우젤", "라-하우젤.png", 0, null, 84, 103, 59, 0, 160, 300, null, null],
[0, "라기시스", null, 0, null, 61, 70, 92, 0, 160, 300, null, null],
[0, "라돈 알폰느", "라돈-알폰느.png", 0, null, 55, 55, 40, 0, 160, 300, null, null],
[0, "라르가", null, 0, null, 69, 56, 69, 0, 160, 300, null, null],
[0, "라벤더", null, 0, null, 55, 56, 40, 0, 160, 300, null, null],
[0, "라우네아", null, 0, null, 78, 89, 61, 0, 160, 300, null, null],
[0, "라인코크", null, 0, null, 82, 61, 91, 0, 160, 300, null, null],
[0, "라인하르트", null, 0, null, 63, 75, 43, 0, 160, 300, null, null],
[0, "라쳇 랜천", null, 0, null, 55, 57, 40, 0, 160, 300, null, null],
[0, "라크 파이크스피크", null, 0, null, 55, 58, 40, 0, 160, 300, null, null],
[0, "라파리아 무스카", null, 0, null, 55, 59, 50, 0, 160, 300, null, null],
[0, "란마루", null, 0, null, 73, 74, 59, 0, 160, 300, null, null],
[0, "란스", null, 0, null, 89, 105, 51, 0, 160, 300, null, null],
[0, "래시", null, 0, null, 75, 83, 19, 0, 160, 300, null, null],
[0, "레드 오니", null, 0, null, 60, 40, 50, 0, 160, 300, null, null],
[0, "레드아이", null, 0, null, 81, 84, 84, 0, 160, 300, null, null],
[0, "레류코프 바코프", "레류코프-바코프.png", 0, null, 79, 80, 59, 0, 160, 300, null, null],
[0, "레리 세리카", null, 0, null, 60, 40, 51, 0, 160, 300, null, null],
[0, "레베카 코프리", "레베카-코프리.png", 0, null, 66, 49, 64, 0, 160, 300, null, null],
[0, "레이", null, 0, null, 85, 109, 53, 0, 160, 300, null, null],
[0, "레이라 글레크니", "레이라-글레크니.png", 0, null, 73, 80, 54, 0, 160, 300, null, null],
[0, "레이콕", null, 0, null, 75, 66, 50, 0, 160, 300, null, null],
[0, "레자리안", null, 0, null, 60, 40, 52, 0, 160, 300, null, null],
[0, "렉싱턴", null, 0, null, 87, 97, 60, 0, 160, 300, null, null],
[0, "렌고쿠", null, 0, null, 87, 84, 57, 0, 160, 300, null, null],
[0, "로나 케스치나", "로나-케스치나.png", 0, null, 51, 55, 55, 0, 160, 300, null, null],
[0, "로도네 로도네", "로도네-로도네.png", 0, null, 59, 67, 67, 0, 160, 300, null, null],
[0, "로라 인더스", "로라-인더스.png", 0, null, 60, 40, 53, 0, 160, 300, null, null],
[0, "로레 엔론", "로레-엔론.png", 0, null, 55, 40, 65, 0, 160, 300, null, null],
[0, "로렉스 가드라스", "로렉스-가드라스.png", 0, null, 85, 90, 55, 0, 160, 300, null, null],
[0, "로버트 랜드스타", "로버트-랜드스타.png", 0, null, 60, 40, 54, 0, 160, 300, null, null],
[0, "로제 카드", "로제-카드.png", 0, null, 69, 60, 49, 0, 160, 300, null, null],
[0, "로즈", null, 0, null, 60, 40, 55, 0, 160, 300, null, null],
[0, "로키 뱅크", "로키-뱅크.png", 0, null, 60, 40, 56, 0, 160, 300, null, null],
[0, "루리카 카라", "루리카-카라.png", 0, null, 69, 48, 70, 0, 160, 300, null, null],
[0, "루베란 체르", "루베란-체르.png", 0, null, 60, 40, 57, 0, 160, 300, null, null],
[0, "루시 줄리에타", "루시-줄리에타.png", 0, null, 35, 65, 65, 0, 160, 300, null, null],
[0, "루이스 키토와크", null, 0, null, 60, 40, 58, 0, 160, 300, null, null],
[0, "루트 아리", "루트-아리.png", 0, null, 39, 67, 67, 0, 160, 300, null, null],
[0, "르메이", null, 0, null, 89, 95, 54, 0, 160, 300, null, null],
[0, "리림", null, 0, null, 76, 71, 71, 0, 160, 300, null, null],
[0, "리세트 카라", "리세트-카라.png", 0, null, 64, 53, 72, 0, 160, 300, null, null],
[0, "리아P리자스", null, 0, null, 97, 34, 44, 0, 160, 300, null, null],
[0, "리즈나 란프비트", "리즈나-란프비트.png", 0, null, 80, 53, 95, 0, 160, 300, null, null],
[0, "릭 아디슨", "릭-아디슨.png", 0, null, 83, 96, 62, 0, 160, 300, null, null],
[0, "마도", null, 0, null, 82, 87, 58, 0, 160, 300, null, null],
[0, "마르티나 카레", "마르티나-카레.png", 0, null, 72, 45, 56, 0, 160, 300, null, null],
[0, "마리스", null, 0, null, 79, 58, 86, 0, 160, 300, null, null],
[0, "마리시텐", null, 0, null, 60, 50, 40, 0, 160, 300, null, null],
[0, "마리아 카스타드", "마리아-카스타드.png", 0, null, 73, 58, 73, 0, 160, 300, null, null],
[0, "마사무네", null, 0, null, 92, 95, 54, 0, 160, 300, null, null],
[0, "마사토 이주인", null, 0, null, 60, 51, 40, 0, 160, 300, null, null],
[0, "마소우 시즈카", "마소우-시즈카.png", 0, null, 87, 54, 93, 0, 160, 300, null, null],
[0, "마스조웨", null, 0, null, 87, 97, 60, 0, 160, 300, null, null],
[0, "마시 줄리에타", "마시-줄리에타.png", 0, null, 35, 65, 65, 0, 160, 300, null, null],
[0, "마에다 케이지", "마에다-케이지.png", 0, null, 71, 63, 69, 0, 160, 300, null, null],
[0, "마에다 토시이에", "마에다-토시이에.png", 0, null, 73, 53, 67, 0, 160, 300, null, null],
[0, "마키바노 메구", "마키바노-메구.png", 0, null, 60, 52, 40, 0, 160, 300, null, null],
[0, "마키바노 앤트", "마키바노-앤트.png", 0, null, 60, 53, 40, 0, 160, 300, null, null],
[0, "마틸다 마테우리", "마틸다-마테우리.png", 0, null, 71, 83, 61, 0, 160, 300, null, null],
[0, "마하 마가렛", "마하-마가렛.png", 0, null, 70, 50, 83, 0, 160, 300, null, null],
[0, "마호코P마사이", null, 0, null, 71, 56, 70, 0, 160, 300, null, null],
[0, "만마루", null, 0, null, 60, 54, 40, 0, 160, 300, null, null],
[0, "매직 더 간지", "매직-더-간지.png", 0, null, 96, 41, 94, 0, 160, 300, null, null],
[0, "머슬", null, 0, null, 70, 82, 60, 0, 160, 300, null, null],
[0, "메가데스 모로미", "메가데스-모로미.png", 0, null, 62, 46, 68, 0, 160, 300, null, null],
[0, "메가스", null, 0, null, 70, 75, 57, 0, 160, 300, null, null],
[0, "메가와스", null, 0, null, 70, 75, 57, 0, 160, 300, null, null],
[0, "메가포스", null, 0, null, 70, 75, 57, 0, 160, 300, null, null],
[0, "메나드 시세이", "메나드-시세이.png", 0, null, 71, 70, 56, 0, 160, 300, null, null],
[0, "메디우사", null, 0, null, 72, 100, 75, 0, 160, 300, null, null],
[0, "메르시 아처", "메르시-아처.png", 0, null, 38, 69, 58, 0, 160, 300, null, null],
[0, "메리 앤", "메리-앤.png", 0, null, 60, 55, 40, 0, 160, 300, null, null],
[0, "메림 체르", "메림-체르.png", 0, null, 54, 64, 56, 0, 160, 300, null, null],
[0, "메이", null, 0, null, 60, 56, 40, 0, 160, 300, null, null],
[0, "멜페이스", null, 0, null, 73, 61, 81, 0, 160, 300, null, null],
[0, "모던 카라", "모던-카라.png", 0, null, 90, 48, 100, 0, 160, 300, null, null],
[0, "모리 모토나리", "모리-모토나리.png", 0, null, 87, 93, 56, 0, 160, 300, null, null],
[0, "모리 테루", "모리-테루.png", 0, null, 82, 88, 60, 0, 160, 300, null, null],
[0, "모스크바 동장군", "모스크바-동장군.png", 0, null, 90, 73, 73, 0, 160, 300, null, null],
[0, "모즈나", null, 0, null, 60, 57, 40, 0, 160, 300, null, null],
[0, "모코모코", null, 0, null, 60, 58, 41, 0, 160, 300, null, null],
[0, "무라라", null, 0, null, 65, 72, 44, 0, 160, 300, null, null],
[0, "미 로드링", "미-로드링.png", 0, null, 78, 41, 79, 0, 160, 300, null, null],
[0, "미네바 마가렛", "미네바-마가렛.png", 0, null, 84, 93, 63, 0, 160, 300, null, null],
[0, "미라클 토우", "미라클-토우.png", 0, null, 64, 73, 103, 0, 160, 300, null, null],
[0, "미르 요크스", "미르-요크스.png", 0, null, 67, 71, 49, 0, 160, 300, null, null],
[0, "미리 요크스", "미리-요크스.png", 0, null, 68, 76, 54, 0, 160, 300, null, null],
[0, "미스테리아 토우", "미스테리아-토우.png", 0, null, 81, 63, 93, 0, 160, 300, null, null],
[0, "미쓰비시", null, 0, null, 91, 60, 55, 0, 160, 300, null, null],
[0, "미쓰이", null, 0, null, 89, 60, 31, 0, 160, 300, null, null],
[0, "미캉", null, 0, null, 56, 52, 64, 0, 160, 300, null, null],
[0, "미킬 데파 라질", "미킬-데파-라질.png", 0, null, 60, 58, 40, 0, 160, 300, null, null],
[0, "밀리 링클", "밀리-링클.png", 0, null, 54, 62, 56, 0, 160, 300, null, null],
[0, "바레스 프로반스", "바레스-프로반스.png", 0, null, 82, 81, 53, 0, 160, 300, null, null],
[0, "바바 쇼우엔", "바바-쇼우엔.png", 0, null, 82, 79, 59, 0, 160, 300, null, null],
[0, "바바라", null, 0, null, 82, 58, 87, 0, 160, 300, null, null],
[0, "바보라", null, 0, null, 76, 99, 70, 0, 160, 300, null, null],
[0, "바쇼 마티오", "바쇼-마티오.png", 0, null, 60, 59, 50, 0, 160, 300, null, null],
[0, "바운드 레스", null, 0, null, 50, 50, 50, 0, 160, 300, null, null],
[0, "반 데로스", null, 0, null, 20, 49, 66, 0, 160, 300, null, null],
[0, "배팅 센터즈", "배팅-센터즈.png", 0, null, 78, 59, 81, 0, 160, 300, null, null],
[0, "버나드 세라미테", "버나드-세라미테.png", 0, null, 66, 65, 65, 0, 160, 300, null, null],
[0, "버드 리스피", "버드-리스피.png", 0, null, 61, 62, 58, 0, 160, 300, null, null],
[0, "베제르아이", null, 0, null, 87, 93, 55, 0, 160, 300, null, null],
[0, "베키", null, 0, null, 20, 49, 66, 0, 160, 300, null, null],
[0, "벨", null, 0, null, 20, 49, 66, 0, 160, 300, null, null],
[0, "보두", null, 0, null, 67, 67, 50, 0, 160, 300, null, null],
[0, "보브자 프란다스", null, 0, null, 42, 60, 22, 0, 160, 300, null, null],
[0, "복수짱", null, 0, null, 70, 80, 56, 0, 160, 300, null, null],
[0, "브란브라", null, 0, null, 74, 65, 52, 0, 160, 300, null, null],
[0, "브리티쉬", null, 0, null, 79, 93, 65, 0, 160, 300, null, null],
[0, "블랙 로터스", "블랙-로터스.png", 0, null, 33, 55, 72, 0, 160, 300, null, null],
[0, "블레이저", null, 0, null, 20, 49, 66, 0, 160, 300, null, null],
[0, "블루 오니", null, 0, null, 20, 49, 66, 0, 160, 300, null, null],
[0, "비비드 카라", "비비드-카라.png", 0, null, 92, 47, 100, 0, 160, 300, null, null],
[0, "비스케타 벨룬즈", "비스케타-벨룬즈.png", 0, null, 20, 49, 66, 0, 160, 300, null, null],
[0, "비욘호우 오스만", "비욘호우-오스만.png", 0, null, 35, 69, 65, 0, 160, 300, null, null],
[0, "빈탄 데스트라", null, 0, null, 41, 60, 21, 0, 160, 300, null, null],
[0, "빗치 고르치", null, 0, null, 20, 49, 66, 0, 160, 300, null, null],
[0, "사나다 토우린", "사나다-토우린.png", 0, null, 94, 47, 82, 0, 160, 300, null, null],
[0, "사나키아", null, 0, null, 20, 49, 66, 0, 160, 300, null, null],
[0, "사메잔", null, 0, null, 82, 56, 89, 0, 160, 300, null, null],
[0, "사야 프라이디", "사야-프라이디.png", 0, null, 39, 67, 67, 0, 160, 300, null, null],
[0, "사유", null, 0, null, 20, 49, 66, 0, 160, 300, null, null],
[0, "사이아스 크라운", "사이아스-크라운.png", 0, null, 81, 54, 80, 0, 160, 300, null, null],
[0, "사치코 센터즈", "사치코-센터즈.png", 0, null, 74, 74, 64, 0, 160, 300, null, null],
[0, "사카나쿠 텐카", null, 0, null, 48, 28, 60, 0, 160, 300, null, null],
[0, "사카모토 료마", "사카모토-료마.png", 0, null, 81, 80, 54, 0, 160, 300, null, null],
[0, "사카이 타다츠구", "사카이-타다츠구.png", 0, null, 72, 68, 53, 0, 160, 300, null, null],
[0, "사카키바라", null, 0, null, 72, 53, 68, 0, 160, 300, null, null],
[0, "사쿠라 카라", "사쿠라-카라.png", 0, null, 76, 73, 73, 0, 160, 300, null, null],
[0, "사테라", null, 0, null, 82, 81, 81, 0, 160, 300, null, null],
[0, "사파이어", null, 0, null, 88, 88, 56, 0, 160, 300, null, null],
[0, "산카쿠", null, 0, null, 20, 49, 66, 0, 160, 300, null, null],
[0, "삼손 막시모프", "삼손-막시모프.png", 0, null, 20, 49, 66, 0, 160, 300, null, null],
[0, "샤론", null, 0, null, 77, 75, 75, 0, 160, 300, null, null],
[0, "샤리에라", null, 0, null, 37, 58, 70, 0, 160, 300, null, null],
[0, "세라크로라스", null, 0, null, 80, 4, 80, 0, 160, 300, null, null],
[0, "세스나 벤빌", "세스나-벤빌.png", 0, null, 64, 70, 54, 0, 160, 300, null, null],
[0, "세실 카나", "세실-카나.png", 0, null, 79, 80, 57, 0, 160, 300, null, null],
[0, "세이간", null, 0, null, 83, 48, 77, 0, 160, 300, null, null],
[0, "세이조 모치키요", null, 0, null, 47, 27, 60, 0, 160, 300, null, null],
[0, "세일러", null, 0, null, 20, 49, 66, 0, 160, 300, null, null],
[0, "세키토리", null, 0, null, 20, 49, 66, 0, 160, 300, null, null],
[0, "세티나 파보", "세티나-파보.png", 0, null, 20, 49, 66, 0, 160, 300, null, null],
[0, "세피아 랜드스타", "세피아-랜드스타.png", 0, null, 20, 49, 66, 0, 160, 300, null, null],
[0, "셀 카치골프", "셀-카치골프.png", 0, null, 44, 20, 60, 0, 160, 300, null, null],
[0, "소르니아 벤츠", "소르니아-벤츠.png", 0, null, 43, 21, 60, 0, 160, 300, null, null],
[0, "소울 레스", null, 0, null, 42, 22, 60, 0, 160, 300, null, null],
[0, "소환짱", null, 0, null, 41, 23, 61, 0, 160, 300, null, null],
[0, "솔트안", null, 0, null, 69, 64, 68, 0, 160, 300, null, null],
[0, "슈퍼 간지", "슈퍼-간지.png", 0, null, 98, 41, 99, 0, 160, 300, null, null],
[0, "스 프로반스", "스-프로반스.png", 0, null, 72, 56, 69, 0, 160, 300, null, null],
[0, "스바 고야", null, 0, null, 51, 31, 60, 0, 160, 300, null, null],
[0, "스즈메", null, 0, null, 75, 85, 75, 0, 160, 300, null, null],
[0, "스즈야 무쌍", "스즈야-무쌍.png", 0, null, 56, 79, 79, 0, 160, 300, null, null],
[0, "스즈키", null, 0, null, 40, 24, 61, 0, 160, 300, null, null],
[0, "스테셀 로마노프", "스테셀-로마노프.png", 0, null, 38, 63, 67, 0, 160, 300, null, null],
[0, "스트로가노프", null, 0, null, 33, 82, 45, 0, 160, 300, null, null],
[0, "스티브 올란다", null, 0, null, 50, 30, 60, 0, 160, 300, null, null],
[0, "스파르탄", null, 0, null, 39, 25, 61, 0, 160, 300, null, null],
[0, "시게히코", null, 0, null, 80, 75, 30, 0, 160, 300, null, null],
[0, "시노다 겐고로", "시노다-겐고로.png", 0, null, 83, 56, 88, 0, 160, 300, null, null],
[0, "시노부", null, 0, null, 53, 74, 74, 0, 160, 300, null, null],
[0, "시라 헬만", "시라-헬만.png", 0, null, 99, 47, 83, 0, 160, 300, null, null],
[0, "시르바렐", null, 0, null, 38, 26, 62, 0, 160, 300, null, null],
[0, "시마즈 요시히사", "시마즈-요시히사.png", 0, null, 91, 83, 48, 0, 160, 300, null, null],
[0, "시마즈 이에히사", "시마즈-이에히사.png", 0, null, 87, 74, 61, 0, 160, 300, null, null],
[0, "시마즈 카즈히사", "시마즈-카즈히사.png", 0, null, 85, 81, 56, 0, 160, 300, null, null],
[0, "시마즈 토시히사", "시마즈-토시히사.png", 0, null, 91, 48, 83, 0, 160, 300, null, null],
[0, "시바타 가츠이에", "시바타-가츠이에.png", 0, null, 80, 76, 45, 0, 160, 300, null, null],
[0, "시저", null, 0, null, 81, 98, 63, 0, 160, 300, null, null],
[0, "시치세이", null, 0, null, 80, 62, 84, 0, 160, 300, null, null],
[0, "시카쿠", null, 0, null, 37, 27, 62, 0, 160, 300, null, null],
[0, "시키부", null, 0, null, 85, 86, 58, 0, 160, 300, null, null],
[0, "시타크 루소", null, 0, null, 49, 29, 60, 0, 160, 300, null, null],
[0, "신시아", null, 0, null, 43, 28, 62, 0, 160, 300, null, null],
[0, "실 플라인", "실-플라인.png", 0, null, 75, 63, 101, 0, 160, 300, null, null],
[0, "실키 리틀레즌", "실키-리틀레즌.png", 0, null, 87, 108, 53, 0, 160, 300, null, null],
[0, "실피드", null, 0, null, 42, 29, 63, 0, 160, 300, null, null],
[0, "아길레다", null, 0, null, 77, 81, 50, 0, 160, 300, null, null],
[0, "아나셀 카스포라", "아나셀-카스포라.png", 0, null, 33, 66, 67, 0, 160, 300, null, null],
[0, "아니", null, 0, null, 41, 30, 63, 0, 160, 300, null, null],
[0, "아니스 사와타리", "아니스-사와타리.png", 0, null, 78, 61, 106, 0, 160, 300, null, null],
[0, "아레프갈드", null, 0, null, 81, 64, 95, 0, 160, 300, null, null],
[0, "아르카리아", null, 0, null, 73, 72, 72, 0, 160, 300, null, null],
[0, "아리스토레스 캄", "아리스토레스-캄.png", 0, null, 81, 73, 53, 0, 160, 300, null, null],
[0, "아리시아", null, 0, null, 40, 31, 63, 0, 160, 300, null, null],
[0, "아리오스 테오만", "아리오스-테오만.png", 0, null, 88, 104, 51, 0, 160, 300, null, null],
[0, "아마즈사", null, 0, null, 39, 32, 64, 0, 160, 300, null, null],
[0, "아미란 바코프", "아미란-바코프.png", 0, null, 38, 33, 64, 0, 160, 300, null, null],
[0, "아미토스", null, 0, null, 89, 70, 55, 0, 160, 300, null, null],
[0, "아바토르 스캇트", null, 0, null, 40, 60, 20, 0, 160, 300, null, null],
[0, "아베 헤이조", null, 0, null, 37, 34, 64, 0, 160, 300, null, null],
[0, "아벨트 세프티", "아벨트-세프티.png", 0, null, 79, 98, 68, 0, 160, 300, null, null],
[0, "아부라코 도우산", "아부라코-도우산.png", 0, null, 73, 71, 48, 0, 160, 300, null, null],
[0, "아사히나 하쿠만", null, 0, null, 54, 20, 40, 0, 160, 300, null, null],
[0, "아스베스트", null, 0, null, 70, 70, 52, 0, 160, 300, null, null],
[0, "아스카 카드뮴", "아스카-카드뮴.png", 0, null, 60, 50, 54, 0, 160, 300, null, null],
[0, "아시 줄리에타", "아시-줄리에타.png", 0, null, 38, 66, 60, 0, 160, 300, null, null],
[0, "아시카가 쵸신", "아시카가-쵸신.png", 0, null, 66, 44, 50, 0, 160, 300, null, null],
[0, "아야 후지노미야", "아야-후지노미야.png", 0, null, 53, 20, 41, 0, 160, 300, null, null],
[0, "아오이", null, 0, null, 50, 62, 48, 0, 160, 300, null, null],
[0, "아이 컴", "아이-컴.png", 0, null, 39, 61, 60, 0, 160, 300, null, null],
[0, "아이작", null, 0, null, 52, 60, 32, 0, 160, 300, null, null],
[0, "아이젤", null, 0, null, 81, 59, 107, 0, 160, 300, null, null],
[0, "아치볼트", null, 0, null, 52, 20, 42, 0, 160, 300, null, null],
[0, "아카시 카제마루", "아카시-카제마루.png", 0, null, 80, 68, 37, 0, 160, 300, null, null],
[0, "아카시로 카라", "아카시로-카라.png", 0, null, 70, 52, 70, 0, 160, 300, null, null],
[0, "아케치 미츠히데", "아케치-미츠히데.png", 0, null, 76, 41, 67, 0, 160, 300, null, null],
[0, "아키 델", "아키-델.png", 0, null, 51, 20, 43, 0, 160, 300, null, null],
[0, "아키히메", null, 0, null, 38, 66, 60, 0, 160, 300, null, null],
[0, "아타고 마카트", "아타고-마카트.png", 0, null, 50, 20, 44, 0, 160, 300, null, null],
[0, "아테나1호", null, 0, null, 49, 20, 45, 0, 160, 300, null, null],
[0, "아테나2호", null, 0, null, 74, 70, 70, 0, 160, 300, null, null],
[0, "아텐 누", "아텐-누.png", 0, null, 64, 55, 82, 0, 160, 300, null, null],
[0, "아틀란타", null, 0, null, 85, 90, 58, 0, 160, 300, null, null],
[0, "아파치", null, 0, null, 73, 78, 57, 0, 160, 300, null, null],
[0, "알렉산더", null, 0, null, 73, 67, 55, 0, 160, 300, null, null],
[0, "알렉스 발스", "알렉스-발스.png", 0, null, 86, 45, 90, 0, 160, 300, null, null],
[0, "알카네제 라이즈", "알카네제-라이즈.png", 0, null, 79, 86, 56, 0, 160, 300, null, null],
[0, "알코트 마리우스", "알코트-마리우스.png", 0, null, 90, 46, 89, 0, 160, 300, null, null],
[0, "알토 한브라", null, 0, null, 48, 20, 46, 0, 160, 300, null, null],
[0, "암 이스엘", "암-이스엘.png", 0, null, 77, 61, 105, 0, 160, 300, null, null],
[0, "암즈 아크", "암즈-아크.png", 0, null, 77, 94, 64, 0, 160, 300, null, null],
[0, "야마가타", null, 0, null, 82, 61, 77, 0, 160, 300, null, null],
[0, "야마나카 코지카", "야마나카-코지카.png", 0, null, 79, 35, 73, 0, 160, 300, null, null],
[0, "야마다", null, 0, null, 47, 20, 47, 0, 160, 300, null, null],
[0, "야마다 치즈코", "야마다-치즈코.png", 0, null, 85, 42, 85, 0, 160, 300, null, null],
[0, "야마모토 란기", "야마모토-란기.png", 0, null, 76, 76, 59, 0, 160, 300, null, null],
[0, "에구치", null, 0, null, 46, 20, 48, 0, 160, 300, null, null],
[0, "에로피챠 냥코", "에로피챠-냥코.png", 0, null, 45, 20, 49, 0, 160, 300, null, null],
[0, "에르무 트라이", "에르무-트라이.png", 0, null, 44, 20, 50, 0, 160, 300, null, null],
[0, "에르시르", null, 0, null, 78, 74, 74, 0, 160, 300, null, null],
[0, "에리느 해피네스", null, 0, null, 43, 20, 51, 0, 160, 300, null, null],
[0, "에미 알폰느", "에미-알폰느.png", 0, null, 73, 61, 52, 0, 160, 300, null, null],
[0, "엑스 반케트", "엑스-반케트.png", 0, null, 90, 79, 52, 0, 160, 300, null, null],
[0, "엘레나 엘알", "엘레나-엘알.png", 0, null, 42, 20, 52, 0, 160, 300, null, null],
[0, "엘레나 플라워", "엘레나-플라워.png", 0, null, 55, 78, 30, 0, 160, 300, null, null],
[0, "엘레노아 란", "엘레노아-란.png", 0, null, 74, 50, 76, 0, 160, 300, null, null],
[0, "엘리자베스 데스", "엘리자베스-데스.png", 0, null, 38, 64, 66, 0, 160, 300, null, null],
[0, "엣찌", null, 0, null, 49, 60, 29, 0, 160, 300, null, null],
[0, "예리코 코론", "예리코-코론.png", 0, null, 41, 20, 53, 0, 160, 300, null, null],
[0, "오가와 켄타로", "오가와-켄타로.png", 0, null, 84, 96, 63, 0, 160, 300, null, null],
[0, "오기르 롯 스테인", null, 0, null, 40, 20, 54, 0, 160, 300, null, null],
[0, "오노하 메스포스", "오노하-메스포스.png", 0, null, 39, 60, 64, 0, 160, 300, null, null],
[0, "오다 노부나가", "오다-노부나가.png", 0, null, 81, 97, 67, 0, 160, 300, null, null],
[0, "오다 코우", "오다-코우.png", 0, null, 91, 56, 44, 0, 160, 300, null, null],
[0, "오로 마티오", "오로-마티오.png", 0, null, 69, 55, 15, 0, 160, 300, null, null],
[0, "오로라", null, 0, null, 78, 78, 61, 0, 160, 300, null, null],
[0, "오리메", null, 0, null, 76, 63, 78, 0, 160, 300, null, null],
[0, "오마치", null, 0, null, 85, 55, 102, 0, 160, 300, null, null],
[0, "오아마 모토히데", null, 0, null, 67, 77, 38, 0, 160, 300, null, null],
[0, "오즈 토터스", "오즈-토터스.png", 0, null, 83, 31, 66, 0, 160, 300, null, null],
[0, "오키타 노조미", "오키타-노조미.png", 0, null, 65, 96, 76, 0, 160, 300, null, null],
[0, "오토히메", null, 0, null, 68, 56, 15, 0, 160, 300, null, null],
[0, "올오레 더 서드", "올오레-더-서드.png", 0, null, 54, 76, 76, 0, 160, 300, null, null],
[0, "와그 아카", "와그-아카.png", 0, null, 93, 50, 99, 0, 160, 300, null, null],
[0, "와요소 벤빌", "와요소-벤빌.png", 0, null, 67, 57, 15, 0, 160, 300, null, null],
[0, "요라", null, 0, null, 66, 58, 15, 0, 160, 300, null, null],
[0, "요시모토", null, 0, null, 55, 69, 15, 0, 160, 300, null, null],
[0, "요시카게", null, 0, null, 82, 33, 61, 0, 160, 300, null, null],
[0, "요시카와 마치코", "요시카와-마치코.png", 0, null, 58, 66, 50, 0, 160, 300, null, null],
[0, "요시카와 쿄코", "요시카와-쿄코.png", 0, null, 58, 50, 66, 0, 160, 300, null, null],
[0, "욧짱", null, 0, null, 65, 59, 15, 0, 160, 300, null, null],
[0, "우", null, 0, null, 64, 60, 15, 0, 160, 300, null, null],
[0, "우라질", null, 0, null, 63, 61, 15, 0, 160, 300, null, null],
[0, "우르자", null, 0, null, 97, 44, 98, 0, 160, 300, null, null],
[0, "우스피라 신토", "우스피라-신토.png", 0, null, 79, 51, 84, 0, 160, 300, null, null],
[0, "우에스기 겐세이", "우에스기-겐세이.png", 0, null, 74, 59, 39, 0, 160, 300, null, null],
[0, "우에스기 겐신", "우에스기-겐신.png", 0, null, 92, 97, 52, 0, 160, 300, null, null],
[0, "우에스기 카츠코", "우에스기-카츠코.png", 0, null, 76, 71, 53, 0, 160, 300, null, null],
[0, "우에스기 토라코", "우에스기-토라코.png", 0, null, 76, 53, 71, 0, 160, 300, null, null],
[0, "운가 사요리", null, 0, null, 62, 62, 15, 0, 160, 300, null, null],
[0, "웬디 크루미라", "웬디-크루미라.png", 0, null, 61, 63, 15, 0, 160, 300, null, null],
[0, "웬리나", null, 0, null, 80, 3, 80, 0, 160, 300, null, null],
[0, "위리스 후지사키", "위리스-후지사키.png", 0, null, 56, 64, 56, 0, 160, 300, null, null],
[0, "위치타 스케트", "위치타-스케트.png", 0, null, 72, 76, 59, 0, 160, 300, null, null],
[0, "유니콘", null, 0, null, 68, 76, 67, 0, 160, 300, null, null],
[0, "유란 미라쥬", "유란-미라쥬.png", 0, null, 71, 75, 45, 0, 160, 300, null, null],
[0, "유우게", null, 0, null, 75, 75, 61, 0, 160, 300, null, null],
[0, "유즈 필라리아", "유즈-필라리아.png", 0, null, 60, 64, 15, 0, 160, 300, null, null],
[0, "유즈하라 유즈미", "유즈하라-유즈미.png", 0, null, 72, 88, 54, 0, 160, 300, null, null],
[0, "유키", null, 0, null, 72, 77, 77, 0, 160, 300, null, null],
[0, "유키 델", "유키-델.png", 0, null, 59, 65, 15, 0, 160, 300, null, null],
[0, "유키히메", null, 0, null, 58, 66, 15, 0, 160, 300, null, null],
[0, "유틴 프루스", "유틴-프루스.png", 0, null, 57, 67, 15, 0, 160, 300, null, null],
[0, "이누카이", null, 0, null, 72, 72, 72, 0, 160, 300, null, null],
[0, "이마가와 앙코", "이마가와-앙코.png", 0, null, 56, 68, 15, 0, 160, 300, null, null],
[0, "이베트 체리아", "이베트-체리아.png", 0, null, 68, 77, 46, 0, 160, 300, null, null],
[0, "이소로쿠", null, 0, null, 78, 77, 57, 0, 160, 300, null, null],
[0, "이시스", null, 0, null, 84, 88, 60, 0, 160, 300, null, null],
[0, "이시지지", null, 0, null, 60, 40, 49, 0, 160, 300, null, null],
[0, "이안", null, 0, null, 59, 48, 64, 0, 160, 300, null, null],
[0, "이에야스", null, 0, null, 81, 85, 53, 0, 160, 300, null, null],
[0, "이오 이슈타르", "이오-이슈타르.png", 0, null, 83, 38, 74, 0, 160, 300, null, null],
[0, "이오시프", null, 0, null, 95, 54, 89, 0, 160, 300, null, null],
[0, "이이 나오마사", "이이-나오마사.png", 0, null, 72, 72, 56, 0, 160, 300, null, null],
[0, "이지스 카라", "이지스-카라.png", 0, null, 86, 87, 59, 0, 160, 300, null, null],
[0, "이쿠노", null, 0, null, 75, 75, 61, 0, 160, 300, null, null],
[0, "잇큐", null, 0, null, 39, 66, 55, 0, 160, 300, null, null],
[0, "자락", null, 0, null, 52, 32, 60, 0, 160, 300, null, null],
[0, "자비에르", null, 0, null, 81, 97, 67, 0, 160, 300, null, null],
[0, "잔 사비스", "잔-사비스.png", 0, null, 77, 67, 38, 0, 160, 300, null, null],
[0, "쟈로 쟈스락", null, 0, null, 40, 20, 60, 0, 160, 300, null, null],
[0, "쟈하룻카스", null, 0, null, 81, 94, 64, 0, 160, 300, null, null],
[0, "점퍼", null, 0, null, 60, 41, 48, 0, 160, 300, null, null],
[0, "제리피 고라", "제리피-고라.png", 0, null, 60, 42, 47, 0, 160, 300, null, null],
[0, "조후카", null, 0, null, 60, 43, 46, 0, 160, 300, null, null],
[0, "죠니", null, 0, null, 56, 55, 64, 0, 160, 300, null, null],
[0, "죠셉", null, 0, null, 60, 44, 45, 0, 160, 300, null, null],
[0, "주노", null, 0, null, 85, 58, 90, 0, 160, 300, null, null],
[0, "줄리아 린담", "줄리아-린담.png", 0, null, 39, 66, 63, 0, 160, 300, null, null],
[0, "줄키 크라운", "줄키-크라운.png", 0, null, 67, 63, 41, 0, 160, 300, null, null],
[0, "지마 바카스코", "지마-바카스코.png", 0, null, 73, 75, 57, 0, 160, 300, null, null],
[0, "지블 마크토미", null, 0, null, 41, 21, 60, 0, 160, 300, null, null],
[0, "지크", null, 0, null, 82, 63, 97, 0, 160, 300, null, null],
[0, "쩌둥", null, 0, null, 95, 89, 54, 0, 160, 300, null, null],
[0, "챠카 카드뮴", "챠카-카드뮴.png", 0, null, 77, 49, 90, 0, 160, 300, null, null],
[0, "체네자리 드라갈", "체네자리-드라갈.png", 0, null, 75, 55, 81, 0, 160, 300, null, null],
[0, "초르초토브", null, 0, null, 44, 60, 24, 0, 160, 300, null, null],
[0, "쵸쵸맨 파브리", "쵸쵸맨-파브리.png", 0, null, 90, 18, 70, 0, 160, 300, null, null],
[0, "츠치다 못코", "츠치다-못코.png", 0, null, 60, 45, 44, 0, 160, 300, null, null],
[0, "치사 고도", "치사-고도.png", 0, null, 60, 46, 43, 0, 160, 300, null, null],
[0, "치치쿠리", null, 0, null, 43, 60, 23, 0, 160, 300, null, null],
[0, "칠디 샤프", "칠디-샤프.png", 0, null, 78, 91, 62, 0, 160, 300, null, null],
[0, "카나 세이하쥬", "카나-세이하쥬.png", 0, null, 60, 47, 42, 0, 160, 300, null, null],
[0, "카나요", null, 0, null, 78, 74, 74, 0, 160, 300, null, null],
[0, "카네오", null, 0, null, 60, 48, 41, 0, 160, 300, null, null],
[0, "카로리아 크리켓", "카로리아-크리켓.png", 0, null, 71, 56, 72, 0, 160, 300, null, null],
[0, "카마 아트랜저", "카마-아트랜저.png", 0, null, 74, 54, 54, 0, 160, 300, null, null],
[0, "카미라", null, 0, null, 90, 49, 109, 0, 160, 300, null, null],
[0, "카바한", null, 0, null, 81, 45, 98, 0, 160, 300, null, null],
[0, "카스미K카스미", null, 0, null, 68, 55, 73, 0, 160, 300, null, null],
[0, "카오루Q카구라", null, 0, null, 77, 61, 82, 0, 160, 300, null, null],
[0, "카오스", null, 0, null, 55, 89, 89, 0, 160, 300, null, null],
[0, "카이트", null, 0, null, 83, 102, 62, 0, 160, 300, null, null],
[0, "카츄사 봇슈", "카츄사-봇슈.png", 0, null, 69, 73, 68, 0, 160, 300, null, null],
[0, "카토 스즈메", "카토-스즈메.png", 0, null, 60, 49, 40, 0, 160, 300, null, null],
[0, "카토 키요시모리", null, 0, null, 60, 40, 59, 0, 160, 300, null, null],
[0, "카파라 우치", "카파라-우치.png", 0, null, 74, 47, 65, 0, 160, 300, null, null],
[0, "카페 아트풀", "카페-아트풀.png", 0, null, 83, 57, 89, 0, 160, 300, null, null],
[0, "칼 오지잔", "칼-오지잔.png", 0, null, 74, 68, 53, 0, 160, 300, null, null],
[0, "캐로리 메이트", "캐로리-메이트.png", 0, null, 60, 41, 58, 0, 160, 300, null, null],
[0, "커티스 아벨렌", null, 0, null, 46, 60, 26, 0, 160, 300, null, null],
[0, "케셀링크", null, 0, null, 95, 107, 47, 0, 160, 300, null, null],
[0, "케이브냥", null, 0, null, 60, 70, 32, 0, 160, 300, null, null],
[0, "케이브리스", null, 0, null, 90, 110, 50, 0, 160, 300, null, null],
[0, "케이브왕", null, 0, null, 60, 70, 32, 0, 160, 300, null, null],
[0, "케이코", null, 0, null, 79, 58, 96, 0, 160, 300, null, null],
[0, "케이코쿠", null, 0, null, 68, 68, 83, 0, 160, 300, null, null],
[0, "케챠크 반고", "케챠크-반고.png", 0, null, 60, 42, 57, 0, 160, 300, null, null],
[0, "켄토우 카나미", "켄토우-카나미.png", 0, null, 60, 43, 56, 0, 160, 300, null, null],
[0, "코난 호카벤", null, 0, null, 60, 44, 55, 0, 160, 300, null, null],
[0, "코르도바 반", "코르도바-반.png", 0, null, 81, 79, 59, 0, 160, 300, null, null],
[0, "코마츠", null, 0, null, 80, 73, 52, 0, 160, 300, null, null],
[0, "코바야카와 치누", "코바야카와-치누.png", 0, null, 77, 74, 62, 0, 160, 300, null, null],
[0, "코슈인 하즈키", "코슈인-하즈키.png", 0, null, 60, 45, 54, 0, 160, 300, null, null],
[0, "코우사카", null, 0, null, 70, 68, 81, 0, 160, 300, null, null],
[0, "코판돈 도트", "코판돈-도트.png", 0, null, 60, 46, 53, 0, 160, 300, null, null],
[0, "콘 마가린", null, 0, null, 60, 47, 52, 0, 160, 300, null, null],
[0, "콘버트 탁스", "콘버트-탁스.png", 0, null, 73, 48, 50, 0, 160, 300, null, null],
[0, "콘타마", null, 0, null, 60, 48, 51, 0, 160, 300, null, null],
[0, "콜라", null, 0, null, 4, 4, 4, 0, 160, 300, null, null],
[0, "콜린 코콜린", "콜린-코콜린.png", 0, null, 60, 49, 50, 0, 160, 300, null, null],
[0, "콩고", null, 0, null, 43, 23, 60, 0, 160, 300, null, null],
[0, "쿠로베", null, 0, null, 88, 92, 53, 0, 160, 300, null, null],
[0, "쿠로히메", null, 0, null, 85, 20, 65, 0, 160, 300, null, null],
[0, "쿠마", null, 0, null, 75, 75, 15, 0, 160, 300, null, null],
[0, "쿠마노 고로", null, 0, null, 46, 26, 60, 0, 160, 300, null, null],
[0, "쿠모 단죠", "쿠모-단죠.png", 0, null, 72, 67, 44, 0, 160, 300, null, null],
[0, "쿠소가키", null, 0, null, 60, 50, 49, 0, 160, 300, null, null],
[0, "쿠유", null, 0, null, 60, 51, 48, 0, 160, 300, null, null],
[0, "쿠제 쿄코", null, 0, null, 45, 25, 60, 0, 160, 300, null, null],
[0, "쿠제 키요코", null, 0, null, 44, 24, 60, 0, 160, 300, null, null],
[0, "큐티 밴드", "큐티-밴드.png", 0, null, 73, 69, 41, 0, 160, 300, null, null],
[0, "크레인", null, 0, null, 60, 52, 47, 0, 160, 300, null, null],
[0, "크루체 머핀", "크루체-머핀.png", 0, null, 60, 53, 46, 0, 160, 300, null, null],
[0, "크룩 모프스", "크룩-모프스.png", 0, null, 98, 50, 83, 0, 160, 300, null, null],
[0, "크림", null, 0, null, 96, 43, 90, 0, 160, 300, null, null],
[0, "클린 뷰", "클린-뷰.png", 0, null, 60, 66, 45, 0, 160, 300, null, null],
[0, "키바코", null, 0, null, 70, 74, 66, 0, 160, 300, null, null],
[0, "키사라 코프리", "키사라-코프리.png", 0, null, 63, 67, 49, 0, 160, 300, null, null],
[0, "키스 골드", null, 0, null, 60, 54, 45, 0, 160, 300, null, null],
[0, "키이", null, 0, null, 70, 79, 56, 0, 160, 300, null, null],
[0, "킷카와 키쿠", "킷카와-키쿠.png", 0, null, 69, 79, 71, 0, 160, 300, null, null],
[0, "킹", null, 0, null, 66, 78, 73, 0, 160, 300, null, null],
[0, "킹죠지 아바레", "킹죠지-아바레.png", 0, null, 69, 61, 69, 0, 160, 300, null, null],
[0, "타락한 정치인", null, 0, null, 45, 60, 25, 0, 160, 300, null, null],
[0, "타르고", null, 0, null, 79, 89, 56, 0, 160, 300, null, null],
[0, "타마", null, 0, null, 60, 55, 44, 0, 160, 300, null, null],
[0, "타마구시 후카", "타마구시-후카.png", 0, null, 69, 60, 70, 0, 160, 300, null, null],
[0, "타마시이시바리", null, 0, null, 60, 56, 43, 0, 160, 300, null, null],
[0, "타미 존", "타미-존.png", 0, null, 60, 57, 42, 0, 160, 300, null, null],
[0, "테라", null, 0, null, 87, 20, 63, 0, 160, 300, null, null],
[0, "텐마바시 아리스", "텐마바시-아리스.png", 0, null, 35, 65, 67, 0, 160, 300, null, null],
[0, "토마 리프톤", "토마-리프톤.png", 0, null, 87, 89, 61, 0, 160, 300, null, null],
[0, "토마토 퓨레", "토마토-퓨레.png", 0, null, 65, 64, 60, 0, 160, 300, null, null],
[0, "토쿠가와 센", "토쿠가와-센.png", 0, null, 84, 86, 58, 0, 160, 300, null, null],
[0, "토파즈", null, 0, null, 88, 72, 72, 0, 160, 300, null, null],
[0, "토포스", null, 0, null, 83, 102, 61, 0, 160, 300, null, null],
[0, "톨스토이 바트", "톨스토이-바트.png", 0, null, 60, 59, 40, 0, 160, 300, null, null],
[0, "파레로아", null, 0, null, 76, 74, 74, 0, 160, 300, null, null],
[0, "파렌", null, 0, null, 68, 71, 71, 0, 160, 300, null, null],
[0, "파르프텐크스", null, 0, null, 38, 66, 66, 0, 160, 300, null, null],
[0, "파멜라 헬만", "파멜라-헬만.png", 0, null, 40, 59, 60, 0, 160, 300, null, null],
[0, "파스텔 카라", "파스텔-카라.png", 0, null, 91, 46, 100, 0, 160, 300, null, null],
[0, "파이아르", null, 0, null, 81, 61, 98, 0, 160, 300, null, null],
[0, "파티", null, 0, null, 41, 58, 60, 0, 160, 300, null, null],
[0, "파티 더 서머", "파티-더-서머.png", 0, null, 42, 57, 60, 0, 160, 300, null, null],
[0, "파파데마스", null, 0, null, 43, 56, 60, 0, 160, 300, null, null],
[0, "파파이아 서버", "파파이아-서버.png", 0, null, 79, 59, 90, 0, 160, 300, null, null],
[0, "패트리샤 베이컨", "패트리샤-베이컨.png", 0, null, 44, 55, 60, 0, 160, 300, null, null],
[0, "패튼 미스날지", "패튼-미스날지.png", 0, null, 80, 85, 65, 0, 160, 300, null, null],
[0, "페가수스 포트", null, 0, null, 45, 54, 60, 0, 160, 300, null, null],
[0, "페르에레 칼레트", "페르에레-칼레트.png", 0, null, 38, 67, 61, 0, 160, 300, null, null],
[0, "페리스", null, 0, null, 63, 76, 76, 0, 160, 300, null, null],
[0, "페스포 톤토네", "페스포-톤토네.png", 0, null, 36, 64, 67, 0, 160, 300, null, null],
[0, "페페 위지마", "페페-위지마.png", 0, null, 46, 53, 60, 0, 160, 300, null, null],
[0, "페페론 차오", null, 0, null, 47, 52, 60, 0, 160, 300, null, null],
[0, "포론 차오", "포론-차오.png", 0, null, 83, 73, 63, 0, 160, 300, null, null],
[0, "포토프 토카레프", "포토프-토카레프.png", 0, null, 48, 51, 60, 0, 160, 300, null, null],
[0, "풀 카라", "풀-카라.png", 0, null, 81, 58, 104, 0, 160, 300, null, null],
[0, "프레이아 이즌", "프레이아-이즌.png", 0, null, 54, 77, 77, 0, 160, 300, null, null],
[0, "프로스트바인", null, 0, null, 49, 50, 60, 0, 160, 300, null, null],
[0, "프론소와즈", null, 0, null, 50, 49, 60, 0, 160, 300, null, null],
[0, "프리마 호노노먼", "프리마-호노노먼.png", 0, null, 64, 54, 56, 0, 160, 300, null, null],
[0, "프리크 파라핀", "프리크-파라핀.png", 0, null, 72, 65, 94, 0, 160, 300, null, null],
[0, "플레처 모델", "플레처-모델.png", 0, null, 51, 48, 60, 0, 160, 300, null, null],
[0, "플루페트", null, 0, null, 34, 40, 88, 0, 160, 300, null, null],
[0, "피구", null, 0, null, 80, 73, 56, 0, 160, 300, null, null],
[0, "피니 사나다", "피니-사나다.png", 0, null, 52, 47, 60, 0, 160, 300, null, null],
[0, "피사로", null, 0, null, 89, 54, 95, 0, 160, 300, null, null],
[0, "피텐 차오", "피텐-차오.png", 0, null, 80, 80, 57, 0, 160, 300, null, null],
[0, "하니킹", null, 0, null, 97, 101, 44, 0, 160, 300, null, null],
[0, "하라 쇼우지", "하라-쇼우지.png", 0, null, 78, 63, 50, 0, 160, 300, null, null],
[0, "하삼 크라운", "하삼-크라운.png", 0, null, 75, 69, 42, 0, 160, 300, null, null],
[0, "하우렌 프로반스", "하우렌-프로반스.png", 0, null, 78, 70, 50, 0, 160, 300, null, null],
[0, "하우세스너스", null, 0, null, 83, 89, 37, 0, 160, 300, null, null],
[0, "하이니 바흐", null, 0, null, 53, 46, 60, 0, 160, 300, null, null],
[0, "하이디 팡크라우", "하이디-팡크라우.png", 0, null, 41, 58, 66, 0, 160, 300, null, null],
[0, "하제후카 리모브", null, 0, null, 54, 45, 60, 0, 160, 300, null, null],
[0, "학자", null, 0, null, 83, 53, 73, 0, 160, 300, null, null],
[0, "한스킨스", null, 0, null, 55, 44, 60, 0, 160, 300, null, null],
[0, "한티 카라", "한티-카라.png", 0, null, 70, 67, 108, 0, 160, 300, null, null],
[0, "핫킨 다산", "핫킨-다산.png", 0, null, 76, 73, 60, 0, 160, 300, null, null],
[0, "핫토리 한조", "핫토리-한조.png", 0, null, 65, 70, 64, 0, 160, 300, null, null],
[0, "헨더슨 던트리스", "헨더슨-던트리스.png", 0, null, 56, 43, 60, 0, 160, 300, null, null],
[0, "호 라가", "호-라가.png", 0, null, 79, 56, 101, 0, 160, 300, null, null],
[0, "호넷", null, 0, null, 100, 40, 110, 0, 160, 300, null, null],
[0, "호리카와 나미", "호리카와-나미.png", 0, null, 66, 62, 61, 0, 160, 300, null, null],
[0, "호죠 마사코", "호죠-마사코.png", 0, null, 57, 42, 60, 0, 160, 300, null, null],
[0, "호죠 소운", "호죠-소운.png", 0, null, 75, 62, 94, 0, 160, 300, null, null],
[0, "혼다 마사노부", "혼다-마사노부.png", 0, null, 71, 68, 44, 0, 160, 300, null, null],
[0, "혼다 타다카츠", "혼다-타다카츠.png", 0, null, 72, 80, 53, 0, 160, 300, null, null],
[0, "화성대왕", null, 0, null, 58, 41, 60, 0, 160, 300, null, null],
[0, "화염서사", null, 0, null, 64, 73, 87, 0, 160, 300, null, null],
[0, "후루루 반", "후루루-반.png", 0, null, 59, 40, 60, 0, 160, 300, null, null],
[0, "후브리 마츠시타", null, 0, null, 50, 60, 30, 0, 160, 300, null, null],
[0, "후트 롯", "후트-롯.png", 0, null, 67, 69, 60, 0, 160, 300, null, null],
[0, "휴버트 리프톤", "휴버트-리프톤.png", 0, null, 85, 80, 65, 0, 160, 300, null, null],
[0, "히미코", null, 0, null, 67, 56, 66, 0, 160, 300, null, null],
[0, "히바치", null, 0, null, 78, 90, 60, 0, 160, 300, null, null],
[0, "히카리 미 블랑", "히카리-미-블랑.png", 0, null, 77, 40, 69, 0, 160, 300, null, null],
[0, "히타치", null, 0, null, 89, 57, 60, 0, 160, 300, null, null]
],
"general_ex":[
[999, "KD", null, 0, null, 4, 4, 4, 0, 12, 300, null, null],
[999, "가이", null, 0, null, 5, 5, 5, 0, 15, 300, null, null],
[999, "겟페이", null, 0, null, 20, 20, 20, 0, 60, 300, null, null],
[999, "나이치사", null, 0, null, 5, 5, 5, 0, 15, 300, null, null],
[999, "네프라카스", null, 0, null, 4, 4, 4, 0, 12, 300, null, null],
[999, "다케다 신겐", "다케다-신겐.png", 0, null, 1, 1, 1, 0, 3, 300, null, null],
[999, "도키치로", null, 0, null, 1, 1, 1, 0, 3, 300, null, null],
[999, "라 바스왈드", "라-바스왈드.png", 0, null, 6, 6, 6, 0, 18, 300, null, null],
[999, "라사움", null, 0, null, 9, 9, 9, 0, 27, 300, null, null],
[999, "렌치 랜천", "렌치-랜천.png", 0, null, 20, 20, 20, 0, 160, 300, null, null],
[999, "로벤 팡", "로벤-팡.png", 0, null, 8, 8, 8, 0, 160, 300, null, null],
[999, "루드라사움", null, 0, null, 10, 10, 10, 0, 160, 300, null, null],
[999, "리틀 프린세스", "리틀-프린세스.png", 0, null, 5, 5, 5, 0, 160, 300, null, null],
[999, "마소우 소조", "마소우-소조.png", 0, null, 20, 20, 20, 0, 160, 300, null, null],
[999, "스랄", null, 0, null, 5, 5, 5, 0, 160, 300, null, null],
[999, "시스템", null, 0, null, 1, 1, 1, 0, 160, 300, null, null],
[999, "아노키아M슬린", null, 0, null, 20, 20, 20, 0, 160, 300, null, null],
[999, "아마테라스", null, 0, null, 7, 7, 7, 0, 160, 300, null, null],
[999, "아벨", null, 0, null, 5, 5, 5, 0, 160, 300, null, null],
[999, "아스마제", null, 0, null, 20, 20, 20, 0, 160, 300, null, null],
[999, "여신 앨리스", "여신-앨리스.png", 0, null, 10, 10, 10, 0, 160, 300, null, null],
[999, "오다 키쵸", "오다-키쵸.png", 0, null, 20, 20, 20, 0, 160, 300, null, null],
[999, "와카", null, 0, null, 20, 20, 20, 0, 160, 300, null, null],
[999, "웬즈딩 리자스", "웬즈딩-리자스.png", 0, null, 20, 20, 20, 0, 160, 300, null, null],
[999, "자나게스 헬만", "자나게스-헬만.png", 0, null, 20, 20, 20, 0, 160, 300, null, null],
[999, "질", null, 0, null, 5, 5, 5, 0, 160, 300, null, null],
[999, "쿠엘플란", null, 0, null, 70, 70, 70, 0, 160, 300, null, null],
[999, "쿠크루쿠크루", null, 0, null, 7, 7, 7, 0, 160, 300, null, null],
[999, "테로 에티에노", "테로-에티에노.png", 0, null, 5, 5, 5, 0, 160, 300, null, null],
[999, "파슬리R제스", "파슬리R제스.png", 0, null, 20, 20, 20, 0, 160, 300, null, null],
[999, "파엘리나", null, 0, null, 20, 20, 20, 0, 160, 300, null, null],
[999, "프란나", null, 0, null, 8, 8, 8, 0, 160, 300, null, null],
[999, "프란체스카", null, 0, null, 20, 20, 20, 0, 160, 300, null, null],
[999, "하모니트", null, 0, null, 8, 8, 8, 0, 160, 300, null, null],
[999, "후지와라", null, 0, null, 20, 20, 20, 0, 160, 300, null, null],
[999, "릴 가드라스", "릴-가드라스.png", 0, null, 60, 40, 59, 0, 160, 300, null, null]
]
}
+594
View File
@@ -0,0 +1,594 @@
{
"title": "【가상모드17】 루드라사움",
"startYear": 1,
"history": [
"<C>●</>LP 1년 1월:<L><b>【가상모드16】</> 루드라사움",
"<C>●</>LP 1년 1월:<L><b>【이벤트】</b></>제작자 : Cure.",
"<C>●</>LP 1년 1월:<L><b>【이벤트】</b></>도움을주신분 : 네이미님, 거북마루님",
"<C>●</>LP 1년 1월:<L><b>【이벤트】</b></>지도와 병종을 포함한 루드라사움의 세계관을 불러옵니다."
],
"stat": {
"total": 240,
"min": 50,
"max": 110
},
"iconPath": "루드라사움",
"fiction": 0,
"nation":[
],
"map":{
"mapName":"ludo_rathowm",
"unitSet":"ludo_rathowm"
},
"diplomacy":[],
"general":[
[0, "3G", null, 0, null, 34, 67, 67, 0, -15, 300, null, null],
[0, "PG 7", "PG-7.png", 0, null, 77, 83, 60, 0, -15, 300, null, null],
[0, "PG 9", "PG-9.png", 0, null, 77, 60, 83, 0, -15, 300, null, null],
[0, "가넷", null, 0, null, 83, 56, 88, 0, -15, 300, null, null],
[0, "가라샤", null, 0, null, 65, 68, 47, 0, -15, 300, null, null],
[0, "가르티아", null, 0, null, 68, 101, 73, 0, -15, 300, null, null],
[0, "가무로아 마티오", "가무로아-마티오.png", 0, null, 55, 65, 40, 0, -15, 300, null, null],
[0, "가와노에 미네", "가와노에-미네.png", 0, null, 66, 71, 71, 0, -15, 300, null, null],
[0, "가와노에 유즈루", "가와노에-유즈루.png", 0, null, 71, 76, 61, 0, -15, 300, null, null],
[0, "가이야스 야스토", null, 0, null, 46, 60, 31, 0, -15, 300, null, null],
[0, "가이젤 고도", null, 0, null, 55, 40, 60, 0, -15, 300, null, null],
[0, "검호", null, 0, null, 69, 80, 59, 0, -15, 300, null, null],
[0, "겐리", null, 0, null, 72, 55, 72, 0, -15, 300, null, null],
[0, "겟코", null, 0, null, 75, 85, 58, 0, -15, 300, null, null],
[0, "고닌자 그린", "고닌자-그린.png", 0, null, 55, 20, 65, 0, -15, 300, null, null],
[0, "고닌자 레드", "고닌자-레드.png", 0, null, 70, 70, 10, 0, -15, 300, null, null],
[0, "고닌자 블랙", "고닌자-블랙.png", 0, null, 65, 65, 20, 0, -15, 300, null, null],
[0, "고닌자 블루", "고닌자-블루.png", 0, null, 60, 75, 15, 0, -15, 300, null, null],
[0, "고닌자 옐로", "고닌자-옐로.png", 0, null, 55, 15, 70, 0, -15, 300, null, null],
[0, "고에몬", null, 0, null, 50, 40, 50, 0, -15, 300, null, null],
[0, "고킨켄", null, 0, null, 65, 83, 44, 0, -15, 300, null, null],
[0, "고토", null, 0, null, 50, 40, 51, 0, -15, 300, null, null],
[0, "곤", null, 0, null, 71, 81, 59, 0, -15, 300, null, null],
[0, "곤도 이사미", null, 0, null, 42, 22, 60, 0, -15, 300, null, null],
[0, "그라크 알카포네", null, 0, null, 50, 40, 52, 0, -15, 300, null, null],
[0, "그린 오니", null, 0, null, 50, 40, 53, 0, -15, 300, null, null],
[0, "기가이", null, 0, null, 75, 99, 63, 0, -15, 300, null, null],
[0, "김치 드라이브", "김치-드라이브.png", 0, null, 29, 67, 68, 0, -15, 300, null, null],
[0, "나기 스 라갈", "나기-스-라갈.png", 0, null, 82, 54, 93, 0, -15, 300, null, null],
[0, "나오에 아이", "나오에-아이.png", 0, null, 87, 49, 72, 0, -15, 300, null, null],
[0, "나와토리", null, 0, null, 70, 75, 61, 0, -15, 300, null, null],
[0, "나토리", null, 0, null, 75, 58, 85, 0, -15, 300, null, null],
[0, "난죠 란", "난죠-란.png", 0, null, 78, 49, 72, 0, -15, 300, null, null],
[0, "네로차페트7세", "네로차페트7세.png", 0, null, 71, 67, 34, 0, -15, 300, null, null],
[0, "네이 우롱", "네이-우롱.png", 0, null, 50, 40, 54, 0, -15, 300, null, null],
[0, "네카이 시스", "네카이-시스.png", 0, null, 73, 69, 38, 0, -15, 300, null, null],
[0, "넬슨 서버", "넬슨-서버.png", 0, null, 74, 60, 50, 0, -15, 300, null, null],
[0, "노기쿠", null, 0, null, 72, 63, 78, 0, -15, 300, null, null],
[0, "노벨", null, 0, null, 50, 40, 55, 0, -15, 300, null, null],
[0, "노스", null, 0, null, 87, 106, 50, 0, -15, 300, null, null],
[0, "노아 하코부네", "노아-하코부네.png", 0, null, 69, 46, 74, 0, -15, 300, null, null],
[0, "노에마세", null, 0, null, 50, 40, 56, 0, -15, 300, null, null],
[0, "누누하라 캐비지", "누누하라-캐비지.png", 0, null, 60, 59, 60, 0, -15, 300, null, null],
[0, "느와르", null, 0, null, 72, 78, 63, 0, -15, 300, null, null],
[0, "니나", null, 0, null, 50, 40, 57, 0, -15, 300, null, null],
[0, "니들", null, 0, null, 71, 76, 54, 0, -15, 300, null, null],
[0, "니코페리", null, 0, null, 82, 52, 97, 0, -15, 300, null, null],
[0, "닛코", null, 0, null, 50, 90, 90, 0, -15, 300, null, null],
[0, "다 게일", "다-게일.png", 0, null, 59, 70, 70, 0, -15, 300, null, null],
[0, "다니엘 세프티", "다니엘-세프티.png", 0, null, 50, 60, 58, 0, -15, 300, null, null],
[0, "다마네기", null, 0, null, 50, 40, 59, 0, -15, 300, null, null],
[0, "다이몬 지타로", null, 0, null, 50, 50, 40, 0, -15, 300, null, null],
[0, "다크란스", null, 0, null, 70, 100, 67, 0, -15, 300, null, null],
[0, "닷지 에반스", null, 0, null, 42, 60, 27, 0, -15, 300, null, null],
[0, "덴저러스 브라보", null, 0, null, 50, 51, 40, 0, -15, 300, null, null],
[0, "덴즈 브라우", null, 0, null, 50, 52, 40, 0, -15, 300, null, null],
[0, "도르한 크리케트", "도르한-크리케트.png", 0, null, 62, 58, 69, 0, -15, 300, null, null],
[0, "도시바", null, 0, null, 84, 32, 59, 0, -15, 300, null, null],
[0, "도코모", null, 0, null, 43, 60, 28, 0, -15, 300, null, null],
[0, "도하라스 해피네스", null, 0, null, 50, 53, 40, 0, -15, 300, null, null],
[0, "돈 도에스스키", null, 0, null, 50, 54, 40, 0, -15, 300, null, null],
[0, "듀란", null, 0, null, 62, 67, 39, 0, -15, 300, null, null],
[0, "라 사이젤", "라-사이젤.png", 0, null, 79, 103, 59, 0, -15, 300, null, null],
[0, "라 하우젤", "라-하우젤.png", 0, null, 79, 103, 59, 0, -15, 300, null, null],
[0, "라기시스", null, 0, null, 56, 70, 92, 0, -15, 300, null, null],
[0, "라돈 알폰느", "라돈-알폰느.png", 0, null, 50, 55, 40, 0, -15, 300, null, null],
[0, "라르가", null, 0, null, 64, 56, 69, 0, -15, 300, null, null],
[0, "라벤더", null, 0, null, 50, 56, 40, 0, -15, 300, null, null],
[0, "라우네아", null, 0, null, 73, 89, 61, 0, -15, 300, null, null],
[0, "라인코크", null, 0, null, 77, 61, 91, 0, -15, 300, null, null],
[0, "라인하르트", null, 0, null, 58, 75, 43, 0, -15, 300, null, null],
[0, "라쳇 랜천", null, 0, null, 50, 57, 40, 0, -15, 300, null, null],
[0, "라크 파이크스피크", null, 0, null, 50, 58, 40, 0, -15, 300, null, null],
[0, "라파리아 무스카", null, 0, null, 50, 59, 50, 0, -15, 300, null, null],
[0, "란마루", null, 0, null, 68, 74, 59, 0, -15, 300, null, null],
[0, "란스", null, 0, null, 84, 105, 51, 0, -15, 300, null, null],
[0, "래시", null, 0, null, 70, 83, 19, 0, -15, 300, null, null],
[0, "레드 오니", null, 0, null, 55, 40, 50, 0, -15, 300, null, null],
[0, "레드아이", null, 0, null, 76, 84, 84, 0, -15, 300, null, null],
[0, "레류코프 바코프", "레류코프-바코프.png", 0, null, 74, 80, 59, 0, -15, 300, null, null],
[0, "레리 세리카", null, 0, null, 55, 40, 51, 0, -15, 300, null, null],
[0, "레베카 코프리", "레베카-코프리.png", 0, null, 61, 49, 64, 0, -15, 300, null, null],
[0, "레이", null, 0, null, 80, 109, 53, 0, -15, 300, null, null],
[0, "레이라 글레크니", "레이라-글레크니.png", 0, null, 68, 80, 54, 0, -15, 300, null, null],
[0, "레이콕", null, 0, null, 70, 66, 50, 0, -15, 300, null, null],
[0, "레자리안", null, 0, null, 55, 40, 52, 0, -15, 300, null, null],
[0, "렉싱턴", null, 0, null, 82, 97, 60, 0, -15, 300, null, null],
[0, "렌고쿠", null, 0, null, 82, 84, 57, 0, -15, 300, null, null],
[0, "로나 케스치나", "로나-케스치나.png", 0, null, 46, 55, 55, 0, -15, 300, null, null],
[0, "로도네 로도네", "로도네-로도네.png", 0, null, 54, 67, 67, 0, -15, 300, null, null],
[0, "로라 인더스", "로라-인더스.png", 0, null, 55, 40, 53, 0, -15, 300, null, null],
[0, "로레 엔론", "로레-엔론.png", 0, null, 50, 40, 65, 0, -15, 300, null, null],
[0, "로렉스 가드라스", "로렉스-가드라스.png", 0, null, 80, 90, 55, 0, -15, 300, null, null],
[0, "로버트 랜드스타", "로버트-랜드스타.png", 0, null, 55, 40, 54, 0, -15, 300, null, null],
[0, "로제 카드", "로제-카드.png", 0, null, 64, 60, 49, 0, -15, 300, null, null],
[0, "로즈", null, 0, null, 55, 40, 55, 0, -15, 300, null, null],
[0, "로키 뱅크", "로키-뱅크.png", 0, null, 55, 56, 40, 0, -15, 300, null, null],
[0, "루리카 카라", "루리카-카라.png", 0, null, 64, 48, 70, 0, -15, 300, null, null],
[0, "루베란 체르", "루베란-체르.png", 0, null, 55, 40, 57, 0, -15, 300, null, null],
[0, "루시 줄리에타", "루시-줄리에타.png", 0, null, 30, 65, 65, 0, -15, 300, null, null],
[0, "루이스 키토와크", null, 0, null, 55, 40, 58, 0, -15, 300, null, null],
[0, "루트 아리", "루트-아리.png", 0, null, 34, 67, 67, 0, -15, 300, null, null],
[0, "르메이", null, 0, null, 84, 95, 54, 0, -15, 300, null, null],
[0, "리림", null, 0, null, 71, 71, 71, 0, -15, 300, null, null],
[0, "리세트 카라", "리세트-카라.png", 0, null, 59, 53, 72, 0, -15, 300, null, null],
[0, "리아P리자스", null, 0, null, 92, 34, 44, 0, -15, 300, null, null],
[0, "리즈나 란프비트", "리즈나-란프비트.png", 0, null, 75, 53, 95, 0, -15, 300, null, null],
[0, "릭 아디슨", "릭-아디슨.png", 0, null, 78, 96, 62, 0, -15, 300, null, null],
[0, "마도", null, 0, null, 77, 87, 58, 0, -15, 300, null, null],
[0, "마르티나 카레", "마르티나-카레.png", 0, null, 67, 45, 56, 0, -15, 300, null, null],
[0, "마리스", null, 0, null, 74, 58, 86, 0, -15, 300, null, null],
[0, "마리시텐", null, 0, null, 55, 50, 40, 0, -15, 300, null, null],
[0, "마리아 카스타드", "마리아-카스타드.png", 0, null, 68, 58, 73, 0, -15, 300, null, null],
[0, "마사무네", null, 0, null, 87, 95, 54, 0, -15, 300, null, null],
[0, "마사토 이주인", null, 0, null, 55, 51, 40, 0, -15, 300, null, null],
[0, "마소우 시즈카", "마소우-시즈카.png", 0, null, 82, 54, 93, 0, -15, 300, null, null],
[0, "마스조웨", null, 0, null, 82, 97, 60, 0, -15, 300, null, null],
[0, "마시 줄리에타", "마시-줄리에타.png", 0, null, 30, 65, 65, 0, -15, 300, null, null],
[0, "마에다 케이지", "마에다-케이지.png", 0, null, 66, 66, 72, 0, -15, 300, null, null],
[0, "마에다 토시이에", "마에다-토시이에.png", 0, null, 68, 53, 67, 0, -15, 300, null, null],
[0, "마키바노 메구", "마키바노-메구.png", 0, null, 55, 52, 40, 0, -15, 300, null, null],
[0, "마키바노 앤트", "마키바노-앤트.png", 0, null, 55, 53, 40, 0, -15, 300, null, null],
[0, "마틸다 마테우리", "마틸다-마테우리.png", 0, null, 66, 83, 61, 0, -15, 300, null, null],
[0, "마하 마가렛", "마하-마가렛.png", 0, null, 65, 50, 83, 0, -15, 300, null, null],
[0, "마호코P마사이", null, 0, null, 66, 56, 70, 0, -15, 300, null, null],
[0, "만마루", null, 0, null, 55, 54, 40, 0, -15, 300, null, null],
[0, "매직 더 간지", "매직-더-간지.png", 0, null, 91, 41, 94, 0, -15, 300, null, null],
[0, "머슬", null, 0, null, 65, 82, 60, 0, -15, 300, null, null],
[0, "메가데스 모로미", "메가데스-모로미.png", 0, null, 57, 46, 68, 0, -15, 300, null, null],
[0, "메가스", null, 0, null, 65, 75, 57, 0, -15, 300, null, null],
[0, "메가와스", null, 0, null, 65, 75, 57, 0, -15, 300, null, null],
[0, "메가포스", null, 0, null, 65, 75, 57, 0, -15, 300, null, null],
[0, "메나드 시세이", "메나드-시세이.png", 0, null, 66, 70, 56, 0, -15, 300, null, null],
[0, "메디우사", null, 0, null, 67, 100, 75, 0, -15, 300, null, null],
[0, "메르시 아처", "메르시-아처.png", 0, null, 33, 40, 65, 0, -15, 300, null, null],
[0, "메리 앤", "메리-앤.png", 0, null, 55, 55, 40, 0, -15, 300, null, null],
[0, "메림 체르", "메림-체르.png", 0, null, 49, 64, 56, 0, -15, 300, null, null],
[0, "메이", null, 0, null, 55, 56, 40, 0, -15, 300, null, null],
[0, "멜페이스", null, 0, null, 68, 61, 81, 0, -15, 300, null, null],
[0, "모던 카라", "모던-카라.png", 0, null, 85, 48, 100, 0, -15, 300, null, null],
[0, "모리 모토나리", "모리-모토나리.png", 0, null, 82, 93, 56, 0, -15, 300, null, null],
[0, "모리 테루", "모리-테루.png", 0, null, 77, 88, 60, 0, -15, 300, null, null],
[0, "모스크바 동장군", "모스크바-동장군.png", 0, null, 85, 73, 73, 0, -15, 300, null, null],
[0, "모즈나", null, 0, null, 55, 57, 40, 0, -15, 300, null, null],
[0, "모코모코", null, 0, null, 55, 58, 41, 0, -15, 300, null, null],
[0, "무라라", null, 0, null, 60, 72, 44, 0, -15, 300, null, null],
[0, "미 로드링", "미-로드링.png", 0, null, 73, 41, 79, 0, -15, 300, null, null],
[0, "미네바 마가렛", "미네바-마가렛.png", 0, null, 79, 93, 63, 0, -15, 300, null, null],
[0, "미라클 토우", "미라클-토우.png", 0, null, 59, 73, 103, 0, -15, 300, null, null],
[0, "미르 요크스", "미르-요크스.png", 0, null, 62, 71, 49, 0, -15, 300, null, null],
[0, "미리 요크스", "미리-요크스.png", 0, null, 63, 76, 54, 0, -15, 300, null, null],
[0, "미스테리아 토우", "미스테리아-토우.png", 0, null, 76, 63, 93, 0, -15, 300, null, null],
[0, "미쓰비시", null, 0, null, 86, 60, 55, 0, -15, 300, null, null],
[0, "미쓰이", null, 0, null, 84, 60, 31, 0, -15, 300, null, null],
[0, "미캉", null, 0, null, 51, 52, 64, 0, -15, 300, null, null],
[0, "미킬 데파 라질", "미킬-데파-라질.png", 0, null, 55, 58, 40, 0, -15, 300, null, null],
[0, "밀리 링클", "밀리-링클.png", 0, null, 49, 62, 56, 0, -15, 300, null, null],
[0, "바레스 프로반스", "바레스-프로반스.png", 0, null, 77, 81, 53, 0, -15, 300, null, null],
[0, "바바 쇼우엔", "바바-쇼우엔.png", 0, null, 77, 79, 59, 0, -15, 300, null, null],
[0, "바바라", null, 0, null, 77, 58, 87, 0, -15, 300, null, null],
[0, "바보라", null, 0, null, 71, 99, 70, 0, -15, 300, null, null],
[0, "바쇼 마티오", "바쇼-마티오.png", 0, null, 55, 59, 50, 0, -15, 300, null, null],
[0, "바운드 레스", null, 0, null, 45, 50, 50, 0, -15, 300, null, null],
[0, "반 데로스", null, 0, null, 15, 49, 66, 0, -15, 300, null, null],
[0, "배팅 센터즈", "배팅-센터즈.png", 0, null, 73, 81, 59, 0, -15, 300, null, null],
[0, "버나드 세라미테", "버나드-세라미테.png", 0, null, 61, 65, 65, 0, -15, 300, null, null],
[0, "버드 리스피", "버드-리스피.png", 0, null, 56, 62, 58, 0, -15, 300, null, null],
[0, "베제르아이", null, 0, null, 82, 93, 55, 0, -15, 300, null, null],
[0, "베키", null, 0, null, 15, 49, 66, 0, -15, 300, null, null],
[0, "벨", null, 0, null, 15, 49, 66, 0, -15, 300, null, null],
[0, "보두", null, 0, null, 62, 67, 50, 0, -15, 300, null, null],
[0, "보브자 프란다스", null, 0, null, 41, 60, 22, 0, -15, 300, null, null],
[0, "복수짱", null, 0, null, 65, 80, 56, 0, -15, 300, null, null],
[0, "브란브라", null, 0, null, 69, 65, 52, 0, -15, 300, null, null],
[0, "브리티쉬", null, 0, null, 74, 93, 65, 0, -15, 300, null, null],
[0, "블랙 로터스", "블랙-로터스.png", 0, null, 28, 55, 72, 0, -15, 300, null, null],
[0, "블레이저", null, 0, null, 15, 49, 66, 0, -15, 300, null, null],
[0, "블루 오니", null, 0, null, 15, 49, 66, 0, -15, 300, null, null],
[0, "비비드 카라", "비비드-카라.png", 0, null, 87, 47, 100, 0, -15, 300, null, null],
[0, "비스케타 벨룬즈", "비스케타-벨룬즈.png", 0, null, 15, 75, 72, 0, -15, 300, null, null],
[0, "비욘호우 오스만", "비욘호우-오스만.png", 0, null, 30, 69, 65, 0, -15, 300, null, null],
[0, "빈탄 데스트라", null, 0, null, 36, 60, 21, 0, -15, 300, null, null],
[0, "빗치 고르치", null, 0, null, 15, 49, 66, 0, -15, 300, null, null],
[0, "사나다 토우린", "사나다-토우린.png", 0, null, 89, 47, 82, 0, -15, 300, null, null],
[0, "사나키아", null, 0, null, 15, 60, 45, 0, -15, 300, null, null],
[0, "사메잔", null, 0, null, 77, 56, 89, 0, -15, 300, null, null],
[0, "사야 프라이디", "사야-프라이디.png", 0, null, 34, 67, 67, 0, -15, 300, null, null],
[0, "사유", null, 0, null, 15, 49, 66, 0, -15, 300, null, null],
[0, "사이아스 크라운", "사이아스-크라운.png", 0, null, 76, 54, 80, 0, -15, 300, null, null],
[0, "사치코 센터즈", "사치코-센터즈.png", 0, null, 69, 74, 64, 0, -15, 300, null, null],
[0, "사카나쿠 텐카", null, 0, null, 43, 28, 60, 0, -15, 300, null, null],
[0, "사카모토 료마", "사카모토-료마.png", 0, null, 76, 80, 54, 0, -15, 300, null, null],
[0, "사카이 타다츠구", "사카이-타다츠구.png", 0, null, 67, 68, 53, 0, -15, 300, null, null],
[0, "사카키바라", null, 0, null, 67, 53, 68, 0, -15, 300, null, null],
[0, "사쿠라 카라", "사쿠라-카라.png", 0, null, 71, 73, 73, 0, -15, 300, null, null],
[0, "사테라", null, 0, null, 77, 81, 81, 0, -15, 300, null, null],
[0, "사파이어", null, 0, null, 83, 88, 56, 0, -15, 300, null, null],
[0, "산카쿠", null, 0, null, 15, 49, 66, 0, -15, 300, null, null],
[0, "삼손 막시모프", "삼손-막시모프.png", 0, null, 15, 65, 60, 0, -15, 300, null, null],
[0, "샤론", null, 0, null, 72, 75, 75, 0, -15, 300, null, null],
[0, "샤리에라", null, 0, null, 32, 58, 70, 0, -15, 300, null, null],
[0, "세라크로라스", null, 0, null, 75, 4, 80, 0, -15, 300, null, null],
[0, "세스나 벤빌", "세스나-벤빌.png", 0, null, 59, 70, 54, 0, -15, 300, null, null],
[0, "세실 카나", "세실-카나.png", 0, null, 74, 80, 57, 0, -15, 300, null, null],
[0, "세이간", null, 0, null, 78, 48, 77, 0, -15, 300, null, null],
[0, "세이조 모치키요", null, 0, null, 42, 27, 60, 0, -15, 300, null, null],
[0, "세일러", null, 0, null, 15, 49, 66, 0, -15, 300, null, null],
[0, "세키토리", null, 0, null, 15, 49, 66, 0, -15, 300, null, null],
[0, "세티나 파보", "세티나-파보.png", 0, null, 15, 49, 66, 0, -15, 300, null, null],
[0, "세피아 랜드스타", "세피아-랜드스타.png", 0, null, 15, 49, 66, 0, -15, 300, null, null],
[0, "셀 카치골프", "셀-카치골프.png", 0, null, 45, 20, 60, 0, -15, 300, null, null],
[0, "소르니아 벤츠", "소르니아-벤츠.png", 0, null, 43, 21, 60, 0, -15, 300, null, null],
[0, "소울 레스", null, 0, null, 42, 22, 60, 0, -15, 300, null, null],
[0, "소환짱", null, 0, null, 41, 23, 61, 0, -15, 300, null, null],
[0, "솔트안", null, 0, null, 64, 64, 68, 0, -15, 300, null, null],
[0, "슈퍼 간지", "슈퍼-간지.png", 0, null, 93, 41, 99, 0, -15, 300, null, null],
[0, "스 프로반스", "스-프로반스.png", 0, null, 67, 56, 69, 0, -15, 300, null, null],
[0, "스바 고야", null, 0, null, 46, 31, 60, 0, -15, 300, null, null],
[0, "스즈메", null, 0, null, 70, 85, 75, 0, -15, 300, null, null],
[0, "스즈야 무쌍", "스즈야-무쌍.png", 0, null, 51, 79, 79, 0, -15, 300, null, null],
[0, "스즈키", null, 0, null, 40, 24, 61, 0, -15, 300, null, null],
[0, "스테셀 로마노프", "스테셀-로마노프.png", 0, null, 33, 63, 67, 0, -15, 300, null, null],
[0, "스트로가노프", null, 0, null, 28, 82, 45, 0, -15, 300, null, null],
[0, "스티브 올란다", null, 0, null, 45, 30, 60, 0, -15, 300, null, null],
[0, "스파르탄", null, 0, null, 34, 25, 61, 0, -15, 300, null, null],
[0, "시게히코", null, 0, null, 75, 75, 30, 0, -15, 300, null, null],
[0, "시노다 겐고로", "시노다-겐고로.png", 0, null, 78, 56, 88, 0, -15, 300, null, null],
[0, "시노부", null, 0, null, 48, 74, 74, 0, -15, 300, null, null],
[0, "시라 헬만", "시라-헬만.png", 0, null, 94, 47, 83, 0, -15, 300, null, null],
[0, "시르바렐", null, 0, null, 33, 26, 62, 0, -15, 300, null, null],
[0, "시마즈 요시히사", "시마즈-요시히사.png", 0, null, 86, 83, 48, 0, -15, 300, null, null],
[0, "시마즈 이에히사", "시마즈-이에히사.png", 0, null, 82, 74, 61, 0, -15, 300, null, null],
[0, "시마즈 카즈히사", "시마즈-카즈히사.png", 0, null, 80, 81, 56, 0, -15, 300, null, null],
[0, "시마즈 토시히사", "시마즈-토시히사.png", 0, null, 86, 48, 83, 0, -15, 300, null, null],
[0, "시바타 가츠이에", "시바타-가츠이에.png", 0, null, 75, 76, 45, 0, -15, 300, null, null],
[0, "시저", null, 0, null, 76, 98, 63, 0, -15, 300, null, null],
[0, "시치세이", null, 0, null, 75, 62, 84, 0, -15, 300, null, null],
[0, "시카쿠", null, 0, null, 32, 27, 62, 0, -15, 300, null, null],
[0, "시키부", null, 0, null, 80, 86, 58, 0, -15, 300, null, null],
[0, "시타크 루소", null, 0, null, 44, 29, 60, 0, -15, 300, null, null],
[0, "신시아", null, 0, null, 43, 28, 62, 0, -15, 300, null, null],
[0, "실 플라인", "실-플라인.png", 0, null, 70, 63, 101, 0, -15, 300, null, null],
[0, "실키 리틀레즌", "실키-리틀레즌.png", 0, null, 82, 108, 53, 0, -15, 300, null, null],
[0, "실피드", null, 0, null, 41, 29, 63, 0, -15, 300, null, null],
[0, "아길레다", null, 0, null, 72, 81, 50, 0, -15, 300, null, null],
[0, "아나셀 카스포라", "아나셀-카스포라.png", 0, null, 28, 66, 67, 0, -15, 300, null, null],
[0, "아니", null, 0, null, 40, 30, 63, 0, -15, 300, null, null],
[0, "아니스 사와타리", "아니스-사와타리.png", 0, null, 73, 61, 106, 0, -15, 300, null, null],
[0, "아레프갈드", null, 0, null, 76, 64, 95, 0, -15, 300, null, null],
[0, "아르카리아", null, 0, null, 68, 72, 72, 0, -15, 300, null, null],
[0, "아리스토레스 캄", "아리스토레스-캄.png", 0, null, 76, 73, 53, 0, -15, 300, null, null],
[0, "아리시아", null, 0, null, 41, 31, 63, 0, -15, 300, null, null],
[0, "아리오스 테오만", "아리오스-테오만.png", 0, null, 83, 104, 51, 0, -15, 300, null, null],
[0, "아마즈사", null, 0, null, 34, 32, 64, 0, -15, 300, null, null],
[0, "아미란 바코프", "아미란-바코프.png", 0, null, 33, 33, 64, 0, -15, 300, null, null],
[0, "아미토스", null, 0, null, 84, 75, 55, 0, -15, 300, null, null],
[0, "아바토르 스캇트", null, 0, null, 40, 60, 20, 0, -15, 300, null, null],
[0, "아베 헤이조", null, 0, null, 32, 34, 64, 0, -15, 300, null, null],
[0, "아벨트 세프티", "아벨트-세프티.png", 0, null, 74, 98, 68, 0, -15, 300, null, null],
[0, "아부라코 도우산", "아부라코-도우산.png", 0, null, 68, 71, 48, 0, -15, 300, null, null],
[0, "아사히나 하쿠만", null, 0, null, 49, 20, 40, 0, -15, 300, null, null],
[0, "아스베스트", null, 0, null, 65, 70, 52, 0, -15, 300, null, null],
[0, "아스카 카드뮴", "아스카-카드뮴.png", 0, null, 55, 50, 54, 0, -15, 300, null, null],
[0, "아시 줄리에타", "아시-줄리에타.png", 0, null, 33, 66, 60, 0, -15, 300, null, null],
[0, "아시카가 쵸신", "아시카가-쵸신.png", 0, null, 61, 44, 50, 0, -15, 300, null, null],
[0, "아야 후지노미야", "아야-후지노미야.png", 0, null, 48, 20, 41, 0, -15, 300, null, null],
[0, "아오이", null, 0, null, 45, 62, 48, 0, -15, 300, null, null],
[0, "아이 컴", "아이-컴.png", 0, null, 34, 61, 60, 0, -15, 300, null, null],
[0, "아이작", null, 0, null, 47, 60, 32, 0, -15, 300, null, null],
[0, "아이젤", null, 0, null, 76, 59, 107, 0, -15, 300, null, null],
[0, "아치볼트", null, 0, null, 47, 20, 42, 0, -15, 300, null, null],
[0, "아카시 카제마루", "아카시-카제마루.png", 0, null, 75, 68, 37, 0, -15, 300, null, null],
[0, "아카시로 카라", "아카시로-카라.png", 0, null, 65, 52, 70, 0, -15, 300, null, null],
[0, "아케치 미츠히데", "아케치-미츠히데.png", 0, null, 71, 41, 67, 0, -15, 300, null, null],
[0, "아키 델", "아키-델.png", 0, null, 46, 20, 43, 0, -15, 300, null, null],
[0, "아키히메", null, 0, null, 33, 66, 60, 0, -15, 300, null, null],
[0, "아타고 마카트", "아타고-마카트.png", 0, null, 45, 20, 44, 0, -15, 300, null, null],
[0, "아테나1호", null, 0, null, 44, 20, 45, 0, -15, 300, null, null],
[0, "아테나2호", null, 0, null, 69, 70, 70, 0, -15, 300, null, null],
[0, "아텐 누", "아텐-누.png", 0, null, 59, 55, 82, 0, -15, 300, null, null],
[0, "아틀란타", null, 0, null, 80, 90, 58, 0, -15, 300, null, null],
[0, "아파치", null, 0, null, 68, 78, 57, 0, -15, 300, null, null],
[0, "알렉산더", null, 0, null, 68, 67, 55, 0, -15, 300, null, null],
[0, "알렉스 발스", "알렉스-발스.png", 0, null, 81, 45, 90, 0, -15, 300, null, null],
[0, "알카네제 라이즈", "알카네제-라이즈.png", 0, null, 74, 86, 56, 0, -15, 300, null, null],
[0, "알코트 마리우스", "알코트-마리우스.png", 0, null, 85, 46, 89, 0, -15, 300, null, null],
[0, "알토 한브라", null, 0, null, 43, 20, 46, 0, -15, 300, null, null],
[0, "암 이스엘", "암-이스엘.png", 0, null, 72, 61, 105, 0, -15, 300, null, null],
[0, "암즈 아크", "암즈-아크.png", 0, null, 72, 94, 64, 0, -15, 300, null, null],
[0, "야마가타", null, 0, null, 77, 61, 77, 0, -15, 300, null, null],
[0, "야마나카 코지카", "야마나카-코지카.png", 0, null, 74, 35, 73, 0, -15, 300, null, null],
[0, "야마다", null, 0, null, 42, 20, 47, 0, -15, 300, null, null],
[0, "야마다 치즈코", "야마다-치즈코.png", 0, null, 80, 42, 85, 0, -15, 300, null, null],
[0, "야마모토 란기", "야마모토-란기.png", 0, null, 71, 76, 59, 0, -15, 300, null, null],
[0, "에구치", null, 0, null, 41, 20, 48, 0, -15, 300, null, null],
[0, "에로피챠 냥코", "에로피챠-냥코.png", 0, null, 40, 20, 49, 0, -15, 300, null, null],
[0, "에르무 트라이", "에르무-트라이.png", 0, null, 43, 20, 50, 0, -15, 300, null, null],
[0, "에르시르", null, 0, null, 73, 74, 74, 0, -15, 300, null, null],
[0, "에리느 해피네스", null, 0, null, 42, 20, 51, 0, -15, 300, null, null],
[0, "에미 알폰느", "에미-알폰느.png", 0, null, 68, 52, 61, 0, -15, 300, null, null],
[0, "엑스 반케트", "엑스-반케트.png", 0, null, 85, 79, 52, 0, -15, 300, null, null],
[0, "엘레나 엘알", "엘레나-엘알.png", 0, null, 37, 20, 52, 0, -15, 300, null, null],
[0, "엘레나 플라워", "엘레나-플라워.png", 0, null, 50, 78, 30, 0, -15, 300, null, null],
[0, "엘레노아 란", "엘레노아-란.png", 0, null, 69, 50, 76, 0, -15, 300, null, null],
[0, "엘리자베스 데스", "엘리자베스-데스.png", 0, null, 33, 64, 66, 0, -15, 300, null, null],
[0, "엣찌", null, 0, null, 44, 60, 29, 0, -15, 300, null, null],
[0, "예리코 코론", "예리코-코론.png", 0, null, 41, 20, 53, 0, -15, 300, null, null],
[0, "오가와 켄타로", "오가와-켄타로.png", 0, null, 79, 96, 63, 0, -15, 300, null, null],
[0, "오기르 롯 스테인", null, 0, null, 40, 20, 54, 0, -15, 300, null, null],
[0, "오노하 메스포스", "오노하-메스포스.png", 0, null, 34, 60, 64, 0, -15, 300, null, null],
[0, "오다 노부나가", "오다-노부나가.png", 0, null, 76, 97, 67, 0, -15, 300, null, null],
[0, "오다 코우", "오다-코우.png", 0, null, 86, 56, 44, 0, -15, 300, null, null],
[0, "오로 마티오", "오로-마티오.png", 0, null, 64, 55, 15, 0, -15, 300, null, null],
[0, "오로라", null, 0, null, 73, 78, 61, 0, -15, 300, null, null],
[0, "오리메", null, 0, null, 71, 63, 78, 0, -15, 300, null, null],
[0, "오마치", null, 0, null, 80, 55, 102, 0, -15, 300, null, null],
[0, "오아마 모토히데", null, 0, null, 62, 77, 38, 0, -15, 300, null, null],
[0, "오즈 토터스", "오즈-토터스.png", 0, null, 78, 31, 66, 0, -15, 300, null, null],
[0, "오키타 노조미", "오키타-노조미.png", 0, null, 60, 96, 76, 0, -15, 300, null, null],
[0, "오토히메", null, 0, null, 63, 56, 15, 0, -15, 300, null, null],
[0, "올오레 더 서드", "올오레-더-서드.png", 0, null, 49, 76, 76, 0, -15, 300, null, null],
[0, "와그 아카", "와그-아카.png", 0, null, 88, 50, 99, 0, -15, 300, null, null],
[0, "와요소 벤빌", "와요소-벤빌.png", 0, null, 62, 57, 15, 0, -15, 300, null, null],
[0, "요라", null, 0, null, 61, 58, 15, 0, -15, 300, null, null],
[0, "요시모토", null, 0, null, 50, 69, 15, 0, -15, 300, null, null],
[0, "요시카게", null, 0, null, 77, 33, 61, 0, -15, 300, null, null],
[0, "요시카와 마치코", "요시카와-마치코.png", 0, null, 53, 66, 50, 0, -15, 300, null, null],
[0, "요시카와 쿄코", "요시카와-쿄코.png", 0, null, 53, 50, 66, 0, -15, 300, null, null],
[0, "욧짱", null, 0, null, 60, 59, 15, 0, -15, 300, null, null],
[0, "우", null, 0, null, 59, 60, 15, 0, -15, 300, null, null],
[0, "우라질", null, 0, null, 58, 61, 15, 0, -15, 300, null, null],
[0, "우르자", null, 0, null, 92, 90, 60, 0, -15, 300, null, null],
[0, "우스피라 신토", "우스피라-신토.png", 0, null, 74, 51, 84, 0, -15, 300, null, null],
[0, "우에스기 겐세이", "우에스기-겐세이.png", 0, null, 69, 59, 39, 0, -15, 300, null, null],
[0, "우에스기 겐신", "우에스기-겐신.png", 0, null, 87, 97, 52, 0, -15, 300, null, null],
[0, "우에스기 카츠코", "우에스기-카츠코.png", 0, null, 71, 71, 53, 0, -15, 300, null, null],
[0, "우에스기 토라코", "우에스기-토라코.png", 0, null, 71, 53, 71, 0, -15, 300, null, null],
[0, "운가 사요리", null, 0, null, 57, 62, 15, 0, -15, 300, null, null],
[0, "웬디 크루미라", "웬디-크루미라.png", 0, null, 56, 63, 15, 0, -15, 300, null, null],
[0, "웬리나", null, 0, null, 75, 3, 80, 0, -15, 300, null, null],
[0, "위리스 후지사키", "위리스-후지사키.png", 0, null, 51, 64, 56, 0, -15, 300, null, null],
[0, "위치타 스케트", "위치타-스케트.png", 0, null, 67, 62, 76, 0, -15, 300, null, null],
[0, "유니콘", null, 0, null, 63, 76, 67, 0, -15, 300, null, null],
[0, "유란 미라쥬", "유란-미라쥬.png", 0, null, 66, 75, 45, 0, -15, 300, null, null],
[0, "유우게", null, 0, null, 70, 75, 61, 0, -15, 300, null, null],
[0, "유즈 필라리아", "유즈-필라리아.png", 0, null, 55, 64, 15, 0, -15, 300, null, null],
[0, "유즈하라 유즈미", "유즈하라-유즈미.png", 0, null, 67, 88, 54, 0, -15, 300, null, null],
[0, "유키", null, 0, null, 67, 77, 77, 0, -15, 300, null, null],
[0, "유키 델", "유키-델.png", 0, null, 54, 65, 15, 0, -15, 300, null, null],
[0, "유키히메", null, 0, null, 53, 66, 15, 0, -15, 300, null, null],
[0, "유틴 프루스", "유틴-프루스.png", 0, null, 52, 67, 15, 0, -15, 300, null, null],
[0, "이누카이", null, 0, null, 67, 72, 72, 0, -15, 300, null, null],
[0, "이마가와 앙코", "이마가와-앙코.png", 0, null, 51, 68, 15, 0, -15, 300, null, null],
[0, "이베트 체리아", "이베트-체리아.png", 0, null, 63, 77, 46, 0, -15, 300, null, null],
[0, "이소로쿠", null, 0, null, 73, 77, 57, 0, -15, 300, null, null],
[0, "이시스", null, 0, null, 79, 88, 60, 0, -15, 300, null, null],
[0, "이시지지", null, 0, null, 55, 40, 49, 0, -15, 300, null, null],
[0, "이안", null, 0, null, 54, 48, 64, 0, -15, 300, null, null],
[0, "이에야스", null, 0, null, 76, 85, 53, 0, -15, 300, null, null],
[0, "이오 이슈타르", "이오-이슈타르.png", 0, null, 78, 38, 74, 0, -15, 300, null, null],
[0, "이오시프", null, 0, null, 90, 54, 89, 0, -15, 300, null, null],
[0, "이이 나오마사", "이이-나오마사.png", 0, null, 67, 72, 56, 0, -15, 300, null, null],
[0, "이지스 카라", "이지스-카라.png", 0, null, 81, 87, 59, 0, -15, 300, null, null],
[0, "이쿠노", null, 0, null, 70, 75, 61, 0, -15, 300, null, null],
[0, "잇큐", null, 0, null, 34, 66, 55, 0, -15, 300, null, null],
[0, "자락", null, 0, null, 47, 32, 60, 0, -15, 300, null, null],
[0, "자비에르", null, 0, null, 76, 97, 67, 0, -15, 300, null, null],
[0, "잔 사비스", "잔-사비스.png", 0, null, 72, 67, 38, 0, -15, 300, null, null],
[0, "쟈로 쟈스락", null, 0, null, 40, 20, 60, 0, -15, 300, null, null],
[0, "쟈하룻카스", null, 0, null, 76, 94, 64, 0, -15, 300, null, null],
[0, "점퍼", null, 0, null, 55, 41, 48, 0, -15, 300, null, null],
[0, "제리피 고라", "제리피-고라.png", 0, null, 55, 42, 47, 0, -15, 300, null, null],
[0, "조후카", null, 0, null, 55, 43, 46, 0, -15, 300, null, null],
[0, "죠니", null, 0, null, 51, 55, 64, 0, -15, 300, null, null],
[0, "죠셉", null, 0, null, 55, 44, 45, 0, -15, 300, null, null],
[0, "주노", null, 0, null, 80, 58, 90, 0, -15, 300, null, null],
[0, "줄리아 린담", "줄리아-린담.png", 0, null, 34, 66, 63, 0, -15, 300, null, null],
[0, "줄키 크라운", "줄키-크라운.png", 0, null, 62, 63, 41, 0, -15, 300, null, null],
[0, "지마 바카스코", "지마-바카스코.png", 0, null, 68, 75, 57, 0, -15, 300, null, null],
[0, "지블 마크토미", null, 0, null, 41, 21, 60, 0, -15, 300, null, null],
[0, "지크", null, 0, null, 77, 63, 97, 0, -15, 300, null, null],
[0, "쩌둥", null, 0, null, 90, 89, 54, 0, -15, 300, null, null],
[0, "챠카 카드뮴", "챠카-카드뮴.png", 0, null, 72, 49, 90, 0, -15, 300, null, null],
[0, "체네자리 드라갈", "체네자리-드라갈.png", 0, null, 70, 55, 81, 0, -15, 300, null, null],
[0, "초르초토브", null, 0, null, 44, 60, 24, 0, -15, 300, null, null],
[0, "쵸쵸맨 파브리", "쵸쵸맨-파브리.png", 0, null, 85, 18, 70, 0, -15, 300, null, null],
[0, "츠치다 못코", "츠치다-못코.png", 0, null, 55, 45, 44, 0, -15, 300, null, null],
[0, "치사 고도", "치사-고도.png", 0, null, 55, 46, 43, 0, -15, 300, null, null],
[0, "치치쿠리", null, 0, null, 41, 60, 23, 0, -15, 300, null, null],
[0, "칠디 샤프", "칠디-샤프.png", 0, null, 73, 90, 62, 0, -15, 300, null, null],
[0, "카나 세이하쥬", "카나-세이하쥬.png", 0, null, 55, 47, 42, 0, -15, 300, null, null],
[0, "카나요", null, 0, null, 73, 74, 74, 0, -15, 300, null, null],
[0, "카네오", null, 0, null, 55, 48, 41, 0, -15, 300, null, null],
[0, "카로리아 크리켓", "카로리아-크리켓.png", 0, null, 66, 56, 72, 0, -15, 300, null, null],
[0, "카마 아트랜저", "카마-아트랜저.png", 0, null, 69, 54, 54, 0, -15, 300, null, null],
[0, "카미라", null, 0, null, 85, 49, 109, 0, -15, 300, null, null],
[0, "카바한", null, 0, null, 76, 45, 98, 0, -15, 300, null, null],
[0, "카스미K카스미", null, 0, null, 63, 73, 60, 0, -15, 300, null, null],
[0, "카오루Q카구라", null, 0, null, 72, 78, 61, 0, -15, 300, null, null],
[0, "카오스", null, 0, null, 50, 89, 89, 0, -15, 300, null, null],
[0, "카이트", null, 0, null, 78, 102, 62, 0, -15, 300, null, null],
[0, "카츄사 봇슈", "카츄사-봇슈.png", 0, null, 64, 73, 68, 0, -15, 300, null, null],
[0, "카토 스즈메", "카토-스즈메.png", 0, null, 55, 49, 40, 0, -15, 300, null, null],
[0, "카토 키요시모리", null, 0, null, 55, 40, 59, 0, -15, 300, null, null],
[0, "카파라 우치", "카파라-우치.png", 0, null, 69, 47, 65, 0, -15, 300, null, null],
[0, "카페 아트풀", "카페-아트풀.png", 0, null, 78, 57, 89, 0, -15, 300, null, null],
[0, "칼 오지잔", "칼-오지잔.png", 0, null, 69, 68, 53, 0, -15, 300, null, null],
[0, "캐로리 메이트", "캐로리-메이트.png", 0, null, 55, 41, 58, 0, -15, 300, null, null],
[0, "커티스 아벨렌", null, 0, null, 41, 60, 26, 0, -15, 300, null, null],
[0, "케셀링크", null, 0, null, 90, 107, 47, 0, -15, 300, null, null],
[0, "케이브냥", null, 0, null, 55, 70, 32, 0, -15, 300, null, null],
[0, "케이브리스", null, 0, null, 85, 110, 50, 0, -15, 300, null, null],
[0, "케이브왕", null, 0, null, 55, 70, 32, 0, -15, 300, null, null],
[0, "케이코", null, 0, null, 74, 58, 96, 0, -15, 300, null, null],
[0, "케이코쿠", null, 0, null, 63, 68, 83, 0, -15, 300, null, null],
[0, "케챠크 반고", "케챠크-반고.png", 0, null, 55, 42, 57, 0, -15, 300, null, null],
[0, "켄토우 카나미", "켄토우-카나미.png", 0, null, 55, 56, 43, 0, -15, 300, null, null],
[0, "코난 호카벤", null, 0, null, 55, 44, 55, 0, -15, 300, null, null],
[0, "코르도바 반", "코르도바-반.png", 0, null, 76, 79, 59, 0, -15, 300, null, null],
[0, "코마츠", null, 0, null, 75, 73, 52, 0, -15, 300, null, null],
[0, "코바야카와 치누", "코바야카와-치누.png", 0, null, 72, 74, 62, 0, -15, 300, null, null],
[0, "코슈인 하즈키", "코슈인-하즈키.png", 0, null, 55, 45, 54, 0, -15, 300, null, null],
[0, "코우사카", null, 0, null, 65, 75, 70, 0, -15, 300, null, null],
[0, "코판돈 도트", "코판돈-도트.png", 0, null, 55, 46, 53, 0, -15, 300, null, null],
[0, "콘 마가린", null, 0, null, 55, 47, 52, 0, -15, 300, null, null],
[0, "콘버트 탁스", "콘버트-탁스.png", 0, null, 68, 48, 50, 0, -15, 300, null, null],
[0, "콘타마", null, 0, null, 55, 48, 51, 0, -15, 300, null, null],
[0, "콜린 코콜린", "콜린-코콜린.png", 0, null, 55, 49, 50, 0, -15, 300, null, null],
[0, "콩고", null, 0, null, 42, 23, 60, 0, -15, 300, null, null],
[0, "쿠로베", null, 0, null, 83, 92, 53, 0, -15, 300, null, null],
[0, "쿠로히메", null, 0, null, 80, 20, 65, 0, -15, 300, null, null],
[0, "쿠마", null, 0, null, 70, 75, 15, 0, -15, 300, null, null],
[0, "쿠마노 고로", null, 0, null, 41, 26, 60, 0, -15, 300, null, null],
[0, "쿠모 단죠", "쿠모-단죠.png", 0, null, 67, 67, 44, 0, -15, 300, null, null],
[0, "쿠소가키", null, 0, null, 55, 50, 49, 0, -15, 300, null, null],
[0, "쿠유", null, 0, null, 55, 51, 48, 0, -15, 300, null, null],
[0, "쿠제 쿄코", null, 0, null, 40, 25, 60, 0, -15, 300, null, null],
[0, "쿠제 키요코", null, 0, null, 44, 24, 60, 0, -15, 300, null, null],
[0, "큐티 밴드", "큐티-밴드.png", 0, null, 68, 69, 41, 0, -15, 300, null, null],
[0, "크레인", null, 0, null, 55, 52, 47, 0, -15, 300, null, null],
[0, "크루체 머핀", "크루체-머핀.png", 0, null, 58, 75, 46, 0, -15, 300, null, null],
[0, "크룩 모프스", "크룩-모프스.png", 0, null, 93, 50, 95, 0, -15, 300, null, null],
[0, "크림", null, 0, null, 91, 43, 90, 0, -15, 300, null, null],
[0, "클린 뷰", "클린-뷰.png", 0, null, 55, 66, 45, 0, -15, 300, null, null],
[0, "키바코", null, 0, null, 65, 74, 66, 0, -15, 300, null, null],
[0, "키사라 코프리", "키사라-코프리.png", 0, null, 58, 67, 49, 0, -15, 300, null, null],
[0, "키스 골드", null, 0, null, 55, 54, 45, 0, -15, 300, null, null],
[0, "키이", null, 0, null, 65, 79, 56, 0, -15, 300, null, null],
[0, "킷카와 키쿠", "킷카와-키쿠.png", 0, null, 64, 79, 71, 0, -15, 300, null, null],
[0, "킹", null, 0, null, 61, 78, 73, 0, -15, 300, null, null],
[0, "킹죠지 아바레", "킹죠지-아바레.png", 0, null, 64, 61, 69, 0, -15, 300, null, null],
[0, "타락한 정치인", null, 0, null, 40, 60, 25, 0, -15, 300, null, null],
[0, "타르고", null, 0, null, 74, 89, 56, 0, -15, 300, null, null],
[0, "타마", null, 0, null, 55, 55, 44, 0, -15, 300, null, null],
[0, "타마구시 후카", "타마구시-후카.png", 0, null, 64, 60, 70, 0, -15, 300, null, null],
[0, "타마시이시바리", null, 0, null, 55, 56, 43, 0, -15, 300, null, null],
[0, "타미 존", "타미-존.png", 0, null, 55, 57, 42, 0, -15, 300, null, null],
[0, "테라", null, 0, null, 82, 20, 63, 0, -15, 300, null, null],
[0, "텐마바시 아리스", "텐마바시-아리스.png", 0, null, 30, 65, 67, 0, -15, 300, null, null],
[0, "토마 리프톤", "토마-리프톤.png", 0, null, 82, 89, 61, 0, -15, 300, null, null],
[0, "토마토 퓨레", "토마토-퓨레.png", 0, null, 60, 64, 60, 0, -15, 300, null, null],
[0, "토쿠가와 센", "토쿠가와-센.png", 0, null, 79, 86, 58, 0, -15, 300, null, null],
[0, "토파즈", null, 0, null, 83, 72, 72, 0, -15, 300, null, null],
[0, "토포스", null, 0, null, 78, 102, 61, 0, -15, 300, null, null],
[0, "톨스토이 바트", "톨스토이-바트.png", 0, null, 55, 59, 40, 0, -15, 300, null, null],
[0, "파레로아", null, 0, null, 71, 74, 74, 0, -15, 300, null, null],
[0, "파렌", null, 0, null, 63, 71, 71, 0, -15, 300, null, null],
[0, "파르프텐크스", null, 0, null, 33, 66, 66, 0, -15, 300, null, null],
[0, "파멜라 헬만", "파멜라-헬만.png", 0, null, 35, 59, 60, 0, -15, 300, null, null],
[0, "파스텔 카라", "파스텔-카라.png", 0, null, 86, 46, 100, 0, -15, 300, null, null],
[0, "파이아르", null, 0, null, 76, 61, 98, 0, -15, 300, null, null],
[0, "파티", null, 0, null, 36, 58, 60, 0, -15, 300, null, null],
[0, "파티 더 서머", "파티-더-서머.png", 0, null, 37, 57, 60, 0, -15, 300, null, null],
[0, "파파데마스", null, 0, null, 38, 56, 60, 0, -15, 300, null, null],
[0, "파파이아 서버", "파파이아-서버.png", 0, null, 74, 59, 90, 0, -15, 300, null, null],
[0, "패트리샤 베이컨", "패트리샤-베이컨.png", 0, null, 39, 55, 60, 0, -15, 300, null, null],
[0, "패튼 미스날지", "패튼-미스날지.png", 0, null, 75, 85, 65, 0, -15, 300, null, null],
[0, "페가수스 포트", null, 0, null, 40, 54, 60, 0, -15, 300, null, null],
[0, "페르에레 칼레트", "페르에레-칼레트.png", 0, null, 33, 67, 61, 0, -15, 300, null, null],
[0, "페리스", null, 0, null, 58, 76, 76, 0, -15, 300, null, null],
[0, "페스포 톤토네", "페스포-톤토네.png", 0, null, 31, 64, 67, 0, -15, 300, null, null],
[0, "페페 위지마", "페페-위지마.png", 0, null, 41, 53, 60, 0, -15, 300, null, null],
[0, "페페론 차오", null, 0, null, 42, 52, 60, 0, -15, 300, null, null],
[0, "포론 차오", "포론-차오.png", 0, null, 78, 73, 63, 0, -15, 300, null, null],
[0, "포토프 토카레프", "포토프-토카레프.png", 0, null, 43, 51, 60, 0, -15, 300, null, null],
[0, "풀 카라", "풀-카라.png", 0, null, 76, 58, 104, 0, -15, 300, null, null],
[0, "프레이아 이즌", "프레이아-이즌.png", 0, null, 49, 77, 77, 0, -15, 300, null, null],
[0, "프로스트바인", null, 0, null, 44, 50, 60, 0, -15, 300, null, null],
[0, "프론소와즈", null, 0, null, 45, 49, 60, 0, -15, 300, null, null],
[0, "프리마 호노노먼", "프리마-호노노먼.png", 0, null, 59, 54, 56, 0, -15, 300, null, null],
[0, "프리크 파라핀", "프리크-파라핀.png", 0, null, 67, 65, 94, 0, -15, 300, null, null],
[0, "플레처 모델", "플레처-모델.png", 0, null, 46, 48, 60, 0, -15, 300, null, null],
[0, "플루페트", null, 0, null, 29, 40, 88, 0, -15, 300, null, null],
[0, "피구", null, 0, null, 75, 73, 56, 0, -15, 300, null, null],
[0, "피니 사나다", "피니-사나다.png", 0, null, 47, 47, 60, 0, -15, 300, null, null],
[0, "피사로", null, 0, null, 84, 54, 95, 0, -15, 300, null, null],
[0, "피텐 차오", "피텐-차오.png", 0, null, 75, 80, 57, 0, -15, 300, null, null],
[0, "하니킹", null, 0, null, 92, 101, 44, 0, -15, 300, null, null],
[0, "하라 쇼우지", "하라-쇼우지.png", 0, null, 73, 63, 50, 0, -15, 300, null, null],
[0, "하삼 크라운", "하삼-크라운.png", 0, null, 70, 69, 42, 0, -15, 300, null, null],
[0, "하우렌 프로반스", "하우렌-프로반스.png", 0, null, 73, 70, 50, 0, -15, 300, null, null],
[0, "하우세스너스", null, 0, null, 78, 89, 37, 0, -15, 300, null, null],
[0, "하이니 바흐", null, 0, null, 48, 46, 60, 0, -15, 300, null, null],
[0, "하이디 팡크라우", "하이디-팡크라우.png", 0, null, 40, 58, 66, 0, -15, 300, null, null],
[0, "하제후카 리모브", null, 0, null, 49, 45, 60, 0, -15, 300, null, null],
[0, "학자", null, 0, null, 78, 53, 73, 0, -15, 300, null, null],
[0, "한스킨스", null, 0, null, 50, 44, 60, 0, -15, 300, null, null],
[0, "한티 카라", "한티-카라.png", 0, null, 65, 67, 108, 0, -15, 300, null, null],
[0, "핫킨 다산", "핫킨-다산.png", 0, null, 71, 73, 60, 0, -15, 300, null, null],
[0, "핫토리 한조", "핫토리-한조.png", 0, null, 60, 70, 64, 0, -15, 300, null, null],
[0, "헨더슨 던트리스", "헨더슨-던트리스.png", 0, null, 51, 43, 60, 0, -15, 300, null, null],
[0, "호 라가", "호-라가.png", 0, null, 74, 56, 101, 0, -15, 300, null, null],
[0, "호넷", null, 0, null, 95, 40, 110, 0, -15, 300, null, null],
[0, "호리카와 나미", "호리카와-나미.png", 0, null, 61, 62, 61, 0, -15, 300, null, null],
[0, "호죠 마사코", "호죠-마사코.png", 0, null, 52, 42, 60, 0, -15, 300, null, null],
[0, "호죠 소운", "호죠-소운.png", 0, null, 70, 62, 94, 0, -15, 300, null, null],
[0, "혼다 마사노부", "혼다-마사노부.png", 0, null, 66, 68, 44, 0, -15, 300, null, null],
[0, "혼다 타다카츠", "혼다-타다카츠.png", 0, null, 67, 80, 53, 0, -15, 300, null, null],
[0, "화성대왕", null, 0, null, 53, 41, 60, 0, -15, 300, null, null],
[0, "화염서사", null, 0, null, 59, 73, 87, 0, -15, 300, null, null],
[0, "후루루 반", "후루루-반.png", 0, null, 54, 40, 60, 0, -15, 300, null, null],
[0, "후브리 마츠시타", null, 0, null, 45, 60, 30, 0, -15, 300, null, null],
[0, "후트 롯", "후트-롯.png", 0, null, 62, 69, 60, 0, -15, 300, null, null],
[0, "휴버트 리프톤", "휴버트-리프톤.png", 0, null, 80, 80, 65, 0, -15, 300, null, null],
[0, "히미코", null, 0, null, 62, 56, 66, 0, -15, 300, null, null],
[0, "히바치", null, 0, null, 73, 90, 60, 0, -15, 300, null, null],
[0, "히카리 미 블랑", "히카리-미-블랑.png", 0, null, 72, 40, 69, 0, -15, 300, null, null],
[0, "히타치", null, 0, null, 84, 57, 60, 0, -15, 300, null, null]
],
"general_ex":[
[999, "KD", null, 0, null, 1, 1, 1, 0, -15, 300, null, null],
[999, "가이", null, 0, null, 1, 1, 1, 0, -15, 300, null, null],
[999, "겟페이", null, 0, null, 1, 1, 1, 0, -15, 300, null, null],
[999, "나이치사", null, 0, null, 1, 1, 1, 0, -15, 300, null, null],
[999, "네프라카스", null, 0, null, 1, 1, 1, 0, -15, 300, null, null],
[999, "다케다 신겐", "다케다-신겐", 0, null, 1, 1, 1, 0, -15, 300, null, null],
[999, "도키치로", null, 0, null, 1, 1, 1, 0, -15, 300, null, null],
[999, "라 바스왈드", "라-바스왈드", 0, null, 1, 1, 1, 0, -15, 300, null, null],
[999, "라사움", null, 0, null, 1, 1, 1, 0, -15, 300, null, null],
[999, "렌치 랜천", "렌치-랜천", 0, null, 1, 1, 1, 0, -15, 300, null, null],
[999, "로벤 팡", null, 0, null, 1, 1, 1, 0, -15, 300, null, null],
[999, "루드라사움", null, 0, null, 1, 1, 1, 0, -15, 300, null, null],
[999, "리틀 프린세스", "리틀-프린세스", 0, null, 1, 1, 1, 0, -15, 300, null, null],
[999, "마소우 소조", null, 0, null, 1, 1, 1, 0, -15, 300, null, null],
[999, "스랄", null, 0, null, 1, 1, 1, 0, -15, 300, null, null],
[999, "시스템", null, 0, null, 1, 1, 1, 0, -15, 300, null, null],
[999, "아노키아M슬린", null, 0, null, 1, 1, 1, 0, -15, 300, null, null],
[999, "아마테라스", null, 0, null, 1, 1, 1, 0, -15, 300, null, null],
[999, "아벨", null, 0, null, 1, 1, 1, 0, -15, 300, null, null],
[999, "아스마제", null, 0, null, 1, 1, 1, 0, -15, 300, null, null],
[999, "여신 앨리스", "여신-앨리스", 0, null, 1, 1, 1, 0, -15, 300, null, null],
[999, "오다 키쵸", "오다-키쵸", 0, null, 1, 1, 1, 0, -15, 300, null, null],
[999, "와카", null, 0, null, 1, 1, 1, 0, -15, 300, null, null],
[999, "웬즈딩 리자스", null, 0, null, 1, 1, 1, 0, -15, 300, null, null],
[999, "자나게스 헬만", "자나게스-헬만", 0, null, 1, 1, 1, 0, -15, 300, null, null],
[999, "질", null, 0, null, 1, 1, 1, 0, -15, 300, null, null],
[999, "쿠엘플란", null, 0, null, 1, 1, 1, 0, -15, 300, null, null],
[999, "쿠크루쿠크루", null, 0, null, 1, 1, 1, 0, -15, 300, null, null],
[999, "테로 에티에노", "테로-에티에노", 0, null, 1, 1, 1, 0, -15, 300, null, null],
[999, "파슬리R제스", "파슬리R제스", 0, null, 1, 1, 1, 0, -15, 300, null, null],
[999, "파엘리나", null, 0, null, 1, 1, 1, 0, -15, 300, null, null],
[999, "프란나", null, 0, null, 1, 1, 1, 0, -15, 300, null, null],
[999, "프란체스카", null, 0, null, 1, 1, 1, 0, -15, 300, null, null],
[999, "하모니트", null, 0, null, 1, 1, 1, 0, -15, 300, null, null],
[999, "후지와라", null, 0, null, 1, 1, 1, 0, -15, 300, null, null],
[999, "릴 가드라스", "릴-가드라스", 0, null, 1, 1, 1, 0, -15, 300, null, null],
[999, "콜라", null, 0, null, 1, 1, 1, 0, -15, 300, null, null]
]
}
+393
View File
@@ -0,0 +1,393 @@
<?php
namespace sammo;
class GameUnitConst extends GameUnitConstBase
{
const DEFAULT_CREWTYPE = 217001;
protected static $typeData = [
self::T_FOOTMAN => '보병',
self::T_ARCHER => '궁병',
self::T_CAVALRY => '기동병',
self::T_WIZARD => '마법병',
self::T_SIEGE => '차병',
];
protected static $_buildData = [
[
-1, self::T_CASTLE, '성벽',
100, 100, 7, 0, 0, 99, 9,
999999, null, null, 999999,
[],//성벽은 공격할 수 없다.
[],
['성벽입니다.','생성할 수 없습니다.']
],
[
217001, self::T_FOOTMAN, '보병',
100, 150, 7, 10, 0, 9, 9,
0, null, null, 0,
[self::T_ARCHER=>1.2, self::T_CAVALRY=>0.8, self::T_SIEGE=>1.2],
[self::T_ARCHER=>0.8, self::T_CAVALRY=>1.2, self::T_SIEGE=>0.8],
["표준적인 보병입니다. 보병은 방어특화입니다."],
],
[
217002, self::T_FOOTMAN, '마물병',
110, 160, 7, 10, 0, 9, 10,
0, null, ["호넷 마인령","케이브리스 마인령"], 0,
[self::T_ARCHER=>1.2, self::T_CAVALRY=>0.8, self::T_SIEGE=>1.2],
[self::T_ARCHER=>0.8, self::T_CAVALRY=>1.2, self::T_SIEGE=>0.8],
["마군 지역 기본병종입니다. 조금더 강하지만 쌀을 많이 소비합니다."],
],
[
217003, self::T_FOOTMAN, '중장보병',
100, 250, 7, 5, 0, 13, 10,
1000, null, ["헬만 동부"], 0,
[self::T_ARCHER=>1.2, self::T_CAVALRY=>0.8, self::T_SIEGE=>1.2],
[self::T_ARCHER=>0.8, self::T_CAVALRY=>1.2, self::T_SIEGE=>0.8],
["헬만 특유의 견고한 보병입니다."],
],
[
217004, self::T_FOOTMAN, '흑의 군 보병',
150, 150, 7, 10, 0, 12, 11,
1000, null, ["리자스 남부","리자스 북부"], 0,
[self::T_ARCHER=>1.2, self::T_CAVALRY=>0.8, self::T_SIEGE=>1.2],
[self::T_ARCHER=>0.8, self::T_CAVALRY=>1.2, self::T_SIEGE=>0.8],
["흑의 군 전통의 체계적인 훈련으로 공격력을 보완했습니다."],
],
[
217005, self::T_FOOTMAN, '용병',
125, 175, 7, 10, 0, 12, 11,
1000, null, ["자유도시 동부"], 0,
[self::T_ARCHER=>1.2, self::T_CAVALRY=>0.8, self::T_SIEGE=>1.2],
[self::T_ARCHER=>0.8, self::T_CAVALRY=>1.2, self::T_SIEGE=>0.8],
["일반 보병보다 비싸지만 받은 만큼은 일해줍니다."],
],
[
217006, self::T_FOOTMAN, '사메라이',
175, 150, 7, 0, 0, 11, 10,
1000, null, ["제스 남부"], 0,
[self::T_ARCHER=>1.2, self::T_CAVALRY=>0.8, self::T_SIEGE=>1.2],
[self::T_ARCHER=>0.8, self::T_CAVALRY=>1.2, self::T_SIEGE=>0.8],
["검으로 난무를 가하는 몬스터 보병입니다."],
],
[
217007, self::T_FOOTMAN, '템플나이트병',
75, 275, 7, 0, 0, 11, 12,
1000, null, ["AL교"], 0,
[self::T_ARCHER=>1.2, self::T_CAVALRY=>0.8, self::T_SIEGE=>1.2],
[self::T_ARCHER=>0.8, self::T_CAVALRY=>1.2, self::T_SIEGE=>0.8],
["공격을 포기하고 오직 방어에만 집중합니다."],
],
[
217008, self::T_FOOTMAN, '메이드병',
150, 150, 7, 20, 0, 13, 11,
2000, ["메이드의 묘지"], null, 0,
[self::T_ARCHER=>1.2, self::T_CAVALRY=>0.8, self::T_SIEGE=>1.2],
[self::T_ARCHER=>0.8, self::T_CAVALRY=>1.2, self::T_SIEGE=>0.8],
["켓셀링크 휘하의 날렵한 전투메이드입니다."],
],
[
217009, self::T_FOOTMAN, '요괴병',
150, 150, 8, 0, 0, 11, 13,
2000, ["오슈"], null, 0,
[self::T_ARCHER=>1.2, self::T_CAVALRY=>0.8, self::T_SIEGE=>1.2],
[self::T_ARCHER=>0.8, self::T_CAVALRY=>1.2, self::T_SIEGE=>0.8],
["단단한 육체를 믿고 적진을 돌파합니다."],
],
[
217010, self::T_FOOTMAN, '리자스 친위병',
150, 200, 7, 10, 0, 12, 12,
3000, ["리자스성"], null, 0,
[self::T_ARCHER=>1.2, self::T_CAVALRY=>0.8, self::T_SIEGE=>1.2],
[self::T_ARCHER=>0.8, self::T_CAVALRY=>1.2, self::T_SIEGE=>0.8],
["여왕을 수호하는 리자스 최강의 보병 정예보병입니다."],
],
[
217011, self::T_FOOTMAN, '케이브리스 마물병',
200, 150, 7, 5, 0, 13, 14,
3000, ["케이브리스의 성"], null, 0,
[self::T_ARCHER=>1.2, self::T_CAVALRY=>0.8, self::T_SIEGE=>1.2],
[self::T_ARCHER=>0.8, self::T_CAVALRY=>1.2, self::T_SIEGE=>0.8],
["케이브리스 직속의 마물 정예 전투보병입니다."],
],
[
217012, self::T_FOOTMAN, '투신',
200, 300, 7, 5, 0, 28, 23,
5000, ["투신도시"], null, 0,
[self::T_ARCHER=>1.2, self::T_CAVALRY=>0.8, self::T_SIEGE=>1.2],
[self::T_ARCHER=>0.8, self::T_CAVALRY=>1.2, self::T_SIEGE=>0.8],
["성마교단 유적에서 발굴된 사상 최강의 보병입니다."],
],
[
217101, self::T_ARCHER, '궁병',
100, 100, 7, 20, 0, 10, 10,
0, null, null, 0,
[ self::T_FOOTMAN=>0.8, self::T_CAVALRY=>1.2, self::T_SIEGE=>1.2],
[ self::T_FOOTMAN=>1.2, self::T_CAVALRY=>0.8, self::T_SIEGE=>0.8],
["표준적인 궁병입니다. 궁병은 회피특화입니다."],
],
[
217102, self::T_ARCHER, '투척마물병',
150, 100, 7, 10, 0, 11, 12,
1000, null, ["호넷 마인령"], 0,
[ self::T_FOOTMAN=>0.8, self::T_CAVALRY=>1.2, self::T_SIEGE=>1.2],
[ self::T_FOOTMAN=>1.2, self::T_CAVALRY=>0.8, self::T_SIEGE=>0.8],
["날렵함을 포기하고 도끼를 투척합니다."],
],
[
217103, self::T_ARCHER, '백의 군 궁병',
100, 100, 8, 30, 0, 11, 11,
1000, null, ["리자스 남부"], 0,
[ self::T_FOOTMAN=>0.8, self::T_CAVALRY=>1.2, self::T_SIEGE=>1.2],
[ self::T_FOOTMAN=>1.2, self::T_CAVALRY=>0.8, self::T_SIEGE=>0.8],
["전략을 활용하여 치고 빠지기에 능합니다."],
],
[
217104, self::T_ARCHER, '벌레술사병',
100, 150, 7, 20, 0, 12, 12,
2000, ["호박성"], null, 0,
[ self::T_FOOTMAN=>0.8, self::T_CAVALRY=>1.2, self::T_SIEGE=>1.2],
[ self::T_FOOTMAN=>1.2, self::T_CAVALRY=>0.8, self::T_SIEGE=>0.8],
["벌레들을 부려 몸을 보호하는 궁병입니다."],
],
[
217105, self::T_ARCHER, '저격암살병',
225, 75, 5, 10, 0, 14, 11,
2000, ["블라디보스토크"], null, 0,
[ self::T_FOOTMAN=>0.8, self::T_CAVALRY=>1.2, self::T_SIEGE=>1.2],
[ self::T_FOOTMAN=>1.2, self::T_CAVALRY=>0.8, self::T_SIEGE=>0.8],
["독을 바른 탄환으로 적의 목숨을 앗아갑니다."],
],
[
217106, self::T_ARCHER, '호루스병',
150, 100, 8, 20, 0, 11, 12,
2000, ["거대전함"], null, 0,
[ self::T_FOOTMAN=>0.8, self::T_CAVALRY=>1.2, self::T_SIEGE=>1.2],
[ self::T_FOOTMAN=>1.2, self::T_CAVALRY=>0.8, self::T_SIEGE=>0.8],
["민첩하게 파고드는 호루스족 궁병입니다."],
],
[
217107, self::T_ARCHER, '튤립병',
200, 100, 7, 20, 0, 13, 13,
3000, ["커스텀"], null, 0,
[ self::T_FOOTMAN=>0.8, self::T_CAVALRY=>1.2, self::T_SIEGE=>1.2],
[ self::T_FOOTMAN=>1.2, self::T_CAVALRY=>0.8, self::T_SIEGE=>0.8],
["최첨단병기 튤립으로 적을 폭격합니다."],
],
[
217108, self::T_ARCHER, '아이스플레임 궁병',
150, 150, 7, 20, 0, 13, 13,
3000, ["라그나로크 아크"], null, 0,
[ self::T_FOOTMAN=>0.8, self::T_CAVALRY=>1.2, self::T_SIEGE=>1.2],
[ self::T_FOOTMAN=>1.2, self::T_CAVALRY=>0.8, self::T_SIEGE=>0.8],
["혁명을 성공으로 이끈 정예 게릴라 궁병입니다."],
],
[
217109, self::T_ARCHER, '카라 궁병',
225, 225, 7, 30, 0, 25, 25,
5000, ["펜실 카우"], null, 0,
[ self::T_FOOTMAN=>0.8, self::T_CAVALRY=>1.2, self::T_SIEGE=>1.2],
[ self::T_FOOTMAN=>1.2, self::T_CAVALRY=>0.8, self::T_SIEGE=>0.8],
["선조의 힘을 이어받은 최강의 카라 정예 궁병입니다."],
],
[
217201, self::T_CAVALRY, '기동병',
150, 100, 7, 5, 0, 11, 11,
0, null, null, 0,
[ self::T_FOOTMAN=>1.2, self::T_ARCHER=>0.8, self::T_SIEGE=>1.2],
[ self::T_FOOTMAN=>0.8, self::T_ARCHER=>1.2, self::T_SIEGE=>0.8],
["표준적인 기동병입니다. 기동병은 공격특화입니다."],
],
[
217202, self::T_CAVALRY, '하치온나',
175, 100, 7, 15, 0, 12, 12,
1000, null, ["자유도시 서부"], 0,
[ self::T_FOOTMAN=>1.2, self::T_ARCHER=>0.8, self::T_SIEGE=>1.2],
[ self::T_FOOTMAN=>0.8, self::T_ARCHER=>1.2, self::T_SIEGE=>0.8],
["작은 몸으로 회피하며 따끔한 일격을 먹이는 몬스터 기동병입니다."],
],
[
217203, self::T_CAVALRY, '적의 군 기동병',
200, 100, 7, 5, 0, 12, 13,
1000, null, ["리자스 북부"], 0,
[ self::T_FOOTMAN=>1.2, self::T_ARCHER=>0.8, self::T_SIEGE=>1.2],
[ self::T_FOOTMAN=>0.8, self::T_ARCHER=>1.2, self::T_SIEGE=>0.8],
["리자스군의 자랑인 기동부대입니다."],
],
[
217204, self::T_CAVALRY, '안드로이드 기동병',
175, 150, 7, 10, 0, 13, 12,
2000, ["악의 탑"], null, 0,
[ self::T_FOOTMAN=>1.2, self::T_ARCHER=>0.8, self::T_SIEGE=>1.2],
[ self::T_FOOTMAN=>0.8, self::T_ARCHER=>1.2, self::T_SIEGE=>0.8],
["파이아르가 개발한 최첨단 안드로이드 기동병입니다."],
],
[
217205, self::T_CAVALRY, '파란쵸 기동병',
200, 100, 8, 5, 0, 13, 11,
2000, ["파란쵸 왕국"], null, 0,
[ self::T_FOOTMAN=>1.2, self::T_ARCHER=>0.8, self::T_SIEGE=>1.2],
[ self::T_FOOTMAN=>0.8, self::T_ARCHER=>1.2, self::T_SIEGE=>0.8],
["적진을 일점돌파하는 파란쵸왕국의 돌격 기동병입니다. "],
],
[
217206, self::T_CAVALRY, '비행마물병',
150, 100, 8, 15, 0, 12, 12,
2000, ["죽음의 대지"], null, 0,
[ self::T_FOOTMAN=>1.2, self::T_ARCHER=>0.8, self::T_SIEGE=>1.2],
[ self::T_FOOTMAN=>0.8, self::T_ARCHER=>1.2, self::T_SIEGE=>0.8],
["비행마물에 올라탄 기동마물병입니다."],
],
[
217207, self::T_CAVALRY, '마물조련사병',
250, 200, 6, 0, 0, 16, 16,
3000, ["랑그바우"], null, 0,
[ self::T_FOOTMAN=>1.2, self::T_ARCHER=>0.8, self::T_SIEGE=>1.2],
[ self::T_FOOTMAN=>0.8, self::T_ARCHER=>1.2, self::T_SIEGE=>0.8],
["무시무시한 몬스터에 올라타서 싸우는 극강의 기동병입니다."],
],
[
217208, self::T_CAVALRY, '기마병',
200, 150, 7, 5, 0, 14, 14,
3000, ["오와리"], null, 0,
[ self::T_FOOTMAN=>1.2, self::T_ARCHER=>0.8, self::T_SIEGE=>1.2],
[ self::T_FOOTMAN=>0.8, self::T_ARCHER=>1.2, self::T_SIEGE=>0.8],
["JAPAN 특유의 기마에 올라타 적을 짓밟는 기동병입니다."],
],
[
217209, self::T_CAVALRY, '엔젤나이트',
300, 200, 7, 5, 0, 25, 25,
5000, ["떨어진 궁도"], null, 0,
[ self::T_FOOTMAN=>1.2, self::T_ARCHER=>0.8, self::T_SIEGE=>1.2],
[ self::T_FOOTMAN=>0.8, self::T_ARCHER=>1.2, self::T_SIEGE=>0.8],
["신의 명령으로 파멸을 내리기 위해 강림했습니다."],
],
[
217301, self::T_WIZARD, '마법병',
80, 80, 7, 5, 0.6, 9, 9,
0, null, null, 0,
[self::T_SIEGE=>1.2],
[self::T_SIEGE=>0.8],
["마법을 사용하는 병종입니다."],
],
[
217302, self::T_WIZARD, '마물 마법병',
90, 90, 7, 0, 0.6, 11, 9,
0, null, ["호넷 마인령","케이브리스 마인령"], 0,
[self::T_SIEGE=>1.2],
[self::T_SIEGE=>0.8],
["마군 지역 기본병종입니다. 조금더 강하지만 금을 많이 소비합니다."],
],
[
217303, self::T_WIZARD, '카라 마법병',
80, 80, 7, 20, 0.6, 10, 10,
1000, null, ["카라의 숲"], 0,
[self::T_SIEGE=>1.2],
[self::T_SIEGE=>0.8],
["신속히 움직이며 카라의 저주로 적을 공격합니다."],
],
[
217304, self::T_WIZARD, '제스 마법병',
100, 100, 7, 0, 0.6, 10, 10,
1000, null, ["제스 북부"], 0,
[self::T_SIEGE=>1.2],
[self::T_SIEGE=>0.8],
["마법국가 제스의 전통있는 마법병입니다."],
],
[
217305, self::T_WIZARD, '무녀',
80, 80, 8, 10, 0.6, 10, 10,
1000, null, ["JAPAN"], 0,
[self::T_SIEGE=>1.2],
[self::T_SIEGE=>0.8],
["신마법과 함께 신통한 춤으로 활력을 불어넣는 마법병입니다."],
],
[
217306, self::T_WIZARD, '프로즌',
90, 70, 7, 10, 0.8, 10, 10,
1000, null, ["헬만 서부"], 0,
[self::T_SIEGE=>1.2],
[self::T_SIEGE=>0.8],
["백병전에 불리한 연약한 몸으로 마법 사용에 집중하는 몬스터입니다."],
],
[
217307, self::T_WIZARD, '마소한 마법병',
70, 90, 7, 10, 0.8, 11, 10,
1000, null, ["케이브리스 마인령"], 0,
[self::T_SIEGE=>1.2],
[self::T_SIEGE=>0.8],
["로브를 여러겹 둘러입은 마물마법병입니다. 직접 전투보단 마법에 집중합니다."],
],
[
217308, self::T_WIZARD, '신관병',
80, 130, 7, 5, 0.6, 9, 11,
2000, ["카이즈"], null, 0,
[self::T_SIEGE=>1.2],
[self::T_SIEGE=>0.8],
["AL교의 전투신관입니다. 몸을 보호하는 성스러운 마법을 사용합니다."],
],
[
217309, self::T_WIZARD, '중장마법병',
80, 130, 7, 15, 0.6, 11, 12,
3000, ["로제스그라드"], null, 0,
[self::T_SIEGE=>1.2],
[self::T_SIEGE=>0.8],
["두터운 로브를 입고 불길한 주문을 읊습니다."],
],
[
217310, self::T_WIZARD, '악마병',
130, 80, 7, 15, 0.6, 11, 12,
3000, ["올드제스"], null, 0,
[self::T_SIEGE=>1.2],
[self::T_SIEGE=>0.8],
["고대 제스 왕가의 계약에 따라 소환된 흑마법병입니다."],
],
[
217311, self::T_WIZARD, '호넷 마물병',
130, 130, 7, 0, 0.6, 12, 12,
3000, ["구 마왕성"], null, 0,
[self::T_SIEGE=>1.2],
[self::T_SIEGE=>0.8],
["호넷 직속의 최강 마물 마법병입니다."],
],
[
217312, self::T_WIZARD, 'Z가디언',
180, 180, 7, 0, 0.7, 28, 20,
5000, ["라그나로크 아크"], null, 0,
[self::T_SIEGE=>1.2],
[self::T_SIEGE=>0.8],
["제스의 기술력이 집약된 최고의 마법병기입니다."],
],
[
217401, self::T_SIEGE, '정란',
150, 150, 6, 0, 0, 15, 5,
0, null, null, 3,
[ self::T_FOOTMAN=>0.8, self::T_ARCHER=>0.8, self::T_CAVALRY=>0.8, self::T_WIZARD=>0.8, self::T_CASTLE=>1.8],
[ self::T_FOOTMAN=>1.2, self::T_ARCHER=>1.2, self::T_CAVALRY=>1.2, self::T_WIZARD=>1.2],
["높은 구조물 위에서 공격합니다."],
],
[
217402, self::T_SIEGE, '충차',
150, 100, 6, 0, 0, 20, 5,
1000, null, null, 3,
[ self::T_FOOTMAN=>0.8, self::T_ARCHER=>0.8, self::T_CAVALRY=>0.8, self::T_WIZARD=>0.8, self::T_CASTLE=>2.4],
[ self::T_FOOTMAN=>1.2, self::T_ARCHER=>1.2, self::T_CAVALRY=>1.2, self::T_WIZARD=>1.2],
["엄청난 위력으로 성벽을 부수어버립니다."],
],
[
217403, self::T_SIEGE, '튤립3호',
275, 300, 6, 0, 0, 35, 15,
5000, ["커스텀"], null, 0,
[ ],
[ ],
["파괴적인 위력과 정말 파괴적인 비용을 자랑하는 전차입니다. "],
],
];
}
+124 -123
View File
@@ -124,39 +124,40 @@ CREATE TABLE `general` (
`betgold` INT(8) NULL DEFAULT '0',
`betwingold` INT(8) NULL DEFAULT '0',
`term` INT(4) NULL DEFAULT '0',
`turn0` VARCHAR(30) NULL DEFAULT '[0,0,0,0]',
`turn1` VARCHAR(30) NULL DEFAULT '[0,0,0,0]',
`turn2` VARCHAR(30) NULL DEFAULT '[0,0,0,0]',
`turn3` VARCHAR(30) NULL DEFAULT '[0,0,0,0]',
`turn4` VARCHAR(30) NULL DEFAULT '[0,0,0,0]',
`turn5` VARCHAR(30) NULL DEFAULT '[0,0,0,0]',
`turn6` VARCHAR(30) NULL DEFAULT '[0,0,0,0]',
`turn7` VARCHAR(30) NULL DEFAULT '[0,0,0,0]',
`turn8` VARCHAR(30) NULL DEFAULT '[0,0,0,0]',
`turn9` VARCHAR(30) NULL DEFAULT '[0,0,0,0]',
`turn10` VARCHAR(30) NULL DEFAULT '[0,0,0,0]',
`turn11` VARCHAR(30) NULL DEFAULT '[0,0,0,0]',
`turn12` VARCHAR(30) NULL DEFAULT '[0,0,0,0]',
`turn13` VARCHAR(30) NULL DEFAULT '[0,0,0,0]',
`turn14` VARCHAR(30) NULL DEFAULT '[0,0,0,0]',
`turn15` VARCHAR(30) NULL DEFAULT '[0,0,0,0]',
`turn16` VARCHAR(30) NULL DEFAULT '[0,0,0,0]',
`turn17` VARCHAR(30) NULL DEFAULT '[0,0,0,0]',
`turn18` VARCHAR(30) NULL DEFAULT '[0,0,0,0]',
`turn19` VARCHAR(30) NULL DEFAULT '[0,0,0,0]',
`turn20` VARCHAR(30) NULL DEFAULT '[0,0,0,0]',
`turn21` VARCHAR(30) NULL DEFAULT '[0,0,0,0]',
`turn22` VARCHAR(30) NULL DEFAULT '[0,0,0,0]',
`turn23` VARCHAR(30) NULL DEFAULT '[0,0,0,0]',
`recturn` CHAR(14) NULL DEFAULT '',
`resturn` CHAR(14) NULL DEFAULT '',
`turn0` VARCHAR(50) NULL DEFAULT '[0,0,0,0]',
`turn1` VARCHAR(50) NULL DEFAULT '[0,0,0,0]',
`turn2` VARCHAR(50) NULL DEFAULT '[0,0,0,0]',
`turn3` VARCHAR(50) NULL DEFAULT '[0,0,0,0]',
`turn4` VARCHAR(50) NULL DEFAULT '[0,0,0,0]',
`turn5` VARCHAR(50) NULL DEFAULT '[0,0,0,0]',
`turn6` VARCHAR(50) NULL DEFAULT '[0,0,0,0]',
`turn7` VARCHAR(50) NULL DEFAULT '[0,0,0,0]',
`turn8` VARCHAR(50) NULL DEFAULT '[0,0,0,0]',
`turn9` VARCHAR(50) NULL DEFAULT '[0,0,0,0]',
`turn10` VARCHAR(50) NULL DEFAULT '[0,0,0,0]',
`turn11` VARCHAR(50) NULL DEFAULT '[0,0,0,0]',
`turn12` VARCHAR(50) NULL DEFAULT '[0,0,0,0]',
`turn13` VARCHAR(50) NULL DEFAULT '[0,0,0,0]',
`turn14` VARCHAR(50) NULL DEFAULT '[0,0,0,0]',
`turn15` VARCHAR(50) NULL DEFAULT '[0,0,0,0]',
`turn16` VARCHAR(50) NULL DEFAULT '[0,0,0,0]',
`turn17` VARCHAR(50) NULL DEFAULT '[0,0,0,0]',
`turn18` VARCHAR(50) NULL DEFAULT '[0,0,0,0]',
`turn19` VARCHAR(50) NULL DEFAULT '[0,0,0,0]',
`turn20` VARCHAR(50) NULL DEFAULT '[0,0,0,0]',
`turn21` VARCHAR(50) NULL DEFAULT '[0,0,0,0]',
`turn22` VARCHAR(50) NULL DEFAULT '[0,0,0,0]',
`turn23` VARCHAR(50) NULL DEFAULT '[0,0,0,0]',
`recturn` VARCHAR(50) NULL DEFAULT '[0,0,0,0]',
`resturn` VARCHAR(30) NULL DEFAULT '',
PRIMARY KEY (`no`),
INDEX `nation` (`nation`, `npc`),
INDEX `city` (`city`),
INDEX `turntime` (`turntime`, `no`),
INDEX `no_member` (`owner`),
INDEX `npc` (`npc`),
INDEX `npcid` (`npcid`)
INDEX `npcid` (`npcid`),
INDEX `troop` (`troop`, `turntime`)
)
DEFAULT CHARSET=utf8mb4
ENGINE=MyISAM;
@@ -330,106 +331,106 @@ CREATE TABLE `nation` (
`l11term` INT(4) NULL DEFAULT '0',
`l10term` INT(4) NULL DEFAULT '0',
`l9term` INT(4) NULL DEFAULT '0',
`l12turn0` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l11turn0` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l10turn0` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l9turn0` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l12turn1` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l11turn1` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l10turn1` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l9turn1` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l12turn2` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l11turn2` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l10turn2` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l9turn2` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l12turn3` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l11turn3` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l10turn3` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l9turn3` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l12turn4` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l11turn4` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l10turn4` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l9turn4` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l12turn5` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l11turn5` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l10turn5` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l9turn5` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l12turn6` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l11turn6` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l10turn6` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l9turn6` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l12turn7` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l11turn7` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l10turn7` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l9turn7` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l12turn8` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l11turn8` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l10turn8` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l9turn8` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l12turn9` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l11turn9` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l10turn9` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l9turn9` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l12turn10` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l11turn10` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l10turn10` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l9turn10` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l12turn11` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l11turn11` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l10turn11` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l9turn11` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l12turn0` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l11turn0` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l10turn0` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l9turn0` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l12turn1` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l11turn1` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l10turn1` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l9turn1` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l12turn2` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l11turn2` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l10turn2` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l9turn2` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l12turn3` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l11turn3` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l10turn3` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l9turn3` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l12turn4` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l11turn4` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l10turn4` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l9turn4` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l12turn5` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l11turn5` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l10turn5` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l9turn5` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l12turn6` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l11turn6` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l10turn6` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l9turn6` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l12turn7` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l11turn7` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l10turn7` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l9turn7` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l12turn8` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l11turn8` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l10turn8` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l9turn8` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l12turn9` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l11turn9` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l10turn9` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l9turn9` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l12turn10` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l11turn10` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l10turn10` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l9turn10` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l12turn11` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l11turn11` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l10turn11` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l9turn11` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l8term` INT(4) NULL DEFAULT '0',
`l7term` INT(4) NULL DEFAULT '0',
`l6term` INT(4) NULL DEFAULT '0',
`l5term` INT(4) NULL DEFAULT '0',
`l8turn0` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l7turn0` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l6turn0` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l5turn0` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l8turn1` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l7turn1` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l6turn1` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l5turn1` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l8turn2` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l7turn2` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l6turn2` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l5turn2` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l8turn3` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l7turn3` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l6turn3` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l5turn3` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l8turn4` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l7turn4` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l6turn4` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l5turn4` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l8turn5` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l7turn5` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l6turn5` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l5turn5` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l8turn6` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l7turn6` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l6turn6` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l5turn6` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l8turn7` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l7turn7` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l6turn7` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l5turn7` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l8turn8` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l7turn8` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l6turn8` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l5turn8` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l8turn9` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l7turn9` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l6turn9` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l5turn9` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l8turn10` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l7turn10` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l6turn10` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l5turn10` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l8turn11` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l7turn11` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l6turn11` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l5turn11` VARCHAR(30) NULL DEFAULT '[99,0,0,0]',
`l8turn0` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l7turn0` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l6turn0` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l5turn0` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l8turn1` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l7turn1` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l6turn1` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l5turn1` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l8turn2` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l7turn2` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l6turn2` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l5turn2` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l8turn3` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l7turn3` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l6turn3` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l5turn3` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l8turn4` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l7turn4` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l6turn4` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l5turn4` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l8turn5` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l7turn5` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l6turn5` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l5turn5` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l8turn6` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l7turn6` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l6turn6` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l5turn6` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l8turn7` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l7turn7` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l6turn7` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l5turn7` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l8turn8` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l7turn8` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l6turn8` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l5turn8` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l8turn9` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l7turn9` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l6turn9` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l5turn9` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l8turn10` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l7turn10` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l6turn10` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l5turn10` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l8turn11` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l7turn11` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l6turn11` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`l5turn11` VARCHAR(50) NULL DEFAULT '[99,0,0,0]',
`aux` TEXT NOT NULL DEFAULT '{}',
PRIMARY KEY (`nation`)
)
+17
View File
@@ -2,4 +2,21 @@
function getCityPosition(){
return _tK_cityPosition_;
}
function formatCityInfo(city) {
var regionMap = _tK_regionMap_;
var levelMap = _tK_levelMap_;
var region_str = regionMap[city.region];
var level_str = levelMap[city.level];
city.text = '【' + region_str + '|' + level_str + '】' + city.name;
city.region_str = region_str;
city.level_str = level_str;
return city;
}
+1 -6
View File
@@ -1,9 +1,4 @@
<div class="small_war_log"
><span class="o_diamond"></span
><span class="date"
><span class="year"><?=$year?></span>년
<span class="month"><?=$month?></span>월:
</span>
<div class="small_war_log">
<span class="me">
<span class="name_plate">
+2 -2
View File
@@ -48,9 +48,9 @@ if(!is_uploaded_file($image['tmp_name'])) {
//확장자 검사
$response['reason'] = 'jpg, gif, png 파일이 아닙니다!';
$response['result'] = false;
} elseif($image['size'] > 20480) {
} elseif($image['size'] > 30720) {
//파일크기 검사
$response['reason'] = '20kb 이하로 올려주세요!';
$response['reason'] = '30kb 이하로 올려주세요!';
$response['result'] = false;
} elseif($size[0] < 64 || 128 < $size[0]) {
//이미지크기 검사
+1 -1
View File
@@ -148,7 +148,7 @@ require(__dir__.'/../vendor/autoload.php');
<th class="bg1">도움말</th>
<td colspan="5" style="text-align:left;padding:8px;">
<p style="line-height:1.2em;">
아이콘은 64 x 64픽셀 ~ 128 x 128픽셀 사이, 20KB 이하의 jpg, gif, png 파일만 가능합니다.</p>
아이콘은 64 x 64픽셀 ~ 128 x 128픽셀 사이, 30KB 이하의 jpg, gif, png 파일만 가능합니다.</p>
<p style="margin-top:1em;color:magenta;line-height:1.2em;">탈퇴시 1개월간 정보가 보존되며, 1개월간 재가입이 불가능합니다.</span>
</p>
</td>
+17
View File
@@ -230,6 +230,8 @@ with open('%s.json'%xlsxpath, 'wt', encoding='utf-8') as fp:
fp.write(',\n '.join([json.dumps(general, ensure_ascii=False) for general in generalList]))
fp.write('\n ]')
names2 = []
names3 = []
if '확장 장수 목록' in wb.sheet_names():
generalExList, names2 = extractGeneralList(wb.sheet_by_name('확장 장수 목록'), nationInfo, nationChiefInfo)
@@ -240,4 +242,19 @@ with open('%s.json'%xlsxpath, 'wt', encoding='utf-8') as fp:
fp.write(',\n "general_ex":[\n ')
fp.write(',\n '.join([json.dumps(general, ensure_ascii=False) for general in generalExList]))
fp.write('\n ]')
if '빙의 불가 장수 목록' in wb.sheet_names():
generalNeutralList, names3 = extractGeneralList(wb.sheet_by_name('빙의 불가 장수 목록'), nationInfo, nationChiefInfo)
for name in names3:
if name in names:
raise RuntimeError('%s가 일반 장수 및 빙의 불가 장수에 모두 있습니다!'%name)
for name in names3:
if name in names2:
raise RuntimeError('%s가 확장 장수 및 빙의 불가 장수에 모두 있습니다!'%name)
fp.write(',\n "general_neutral":[\n ')
fp.write(',\n '.join([json.dumps(general, ensure_ascii=False) for general in generalNeutralList]))
fp.write('\n ]')
fp.write('\n}')
+6
View File
@@ -0,0 +1,6 @@
<?php
namespace sammo;
class MustNotBeReachedException extends \LogicException
{}
@@ -0,0 +1,6 @@
<?php
namespace sammo;
class NotInheritedMethodException extends \BadMethodCallException
{}
+27 -1
View File
@@ -12,6 +12,14 @@ class Util extends \utilphp\util
return intval(round($value));
}
/**
* int 값으로 강제로 설정하는 부동소수점 반올림
* @param int|float $value
*/
public static function setRound(&$value) : void{
$value = static::round($value);
}
private static function _parseReq($value, string $type)
{
if (is_array($value)) {
@@ -353,7 +361,7 @@ class Util extends \utilphp\util
/**
* 0.0~1.0 사이의 랜덤 float
* [0.0, 1.0] 사이의 선형 랜덤 float
* @return float
*/
public static function randF()
@@ -361,6 +369,24 @@ class Util extends \utilphp\util
return mt_rand() / mt_getrandmax();
}
/**
* [min, max] 사이의 선형 랜덤 float
* @return float
*/
public static function randRange(float $min, float $max)
{
return static::randF()*($max - $min) + $min;
}
/**
* [min, max] 사이의 선형 랜덤 int
* 현재는 rand(min, max) 동일
* @return int
*/
public static function randRangeInt(int $min, int $max){
return mt_rand($min, $max);
}
/**
* $prob의 확률로 true를 반환
* @return boolean