Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fd26aae6d3 | ||
|
|
c5c092cc8e | ||
|
|
58c0a21d90 | ||
|
|
8dc567f966 | ||
|
|
942b2752f5 | ||
|
|
b9259353f4 | ||
|
|
86c614dd40 | ||
|
|
1a010a16a9 | ||
|
|
d5b5726b1e | ||
|
|
d06f3b6bdf | ||
|
|
97a28f716c | ||
|
|
f54bdfcea0 | ||
|
|
5958c4b0ba | ||
|
|
7c3db881c7 | ||
|
|
51ee2e1b2c | ||
|
|
baa813004b | ||
|
|
86b5269d3d | ||
|
|
860e6dacac | ||
|
|
22025bd89e | ||
|
|
ed9301455d | ||
|
|
35df84e059 | ||
|
|
62deebf310 | ||
|
|
7ed4bd5c01 | ||
|
|
c8eb9332b4 | ||
|
|
1df55f9168 | ||
|
|
b726c6aa96 | ||
|
|
0a71962652 | ||
|
|
160946ef74 | ||
|
|
1dc67317dc | ||
|
|
08f4a2e8bf | ||
|
|
11ffdaa8f7 | ||
|
|
0f853303a4 | ||
|
|
d225eb9b16 | ||
|
|
d926e4b8bc | ||
|
|
3e2df1d4d8 | ||
|
|
d670dbf081 | ||
|
|
f510a312e3 | ||
|
|
19c44e3d31 | ||
|
|
d0848aee67 | ||
|
|
f4b4b6811c | ||
|
|
fecb3f1f7b | ||
|
|
4c924c0763 | ||
|
|
f1e8d70554 | ||
|
|
7d11bc152e |
@@ -1,6 +1,6 @@
|
|||||||
The MIT License
|
The MIT License
|
||||||
|
|
||||||
Copyright (c) 2020 Hide_D, 62che
|
Copyright (c) 2021 Hide_D, 62che
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace sammo;
|
||||||
|
|
||||||
|
include "lib.php";
|
||||||
|
include "func.php";
|
||||||
|
|
||||||
|
APIHelper::launch(dirname(__FILE__));
|
||||||
+70
-3
@@ -127,8 +127,75 @@ input::-webkit-input-placeholder {
|
|||||||
border-radius: .2rem;
|
border-radius: .2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
#running_map{
|
#running_map {
|
||||||
overflow: hidden;
|
|
||||||
border: none;
|
border: none;
|
||||||
width:700px;
|
width: 700px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#map-subframe {
|
||||||
|
display: none;
|
||||||
|
width: 700px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (min-width : 360px) {
|
||||||
|
#map-subframe {
|
||||||
|
display: block;
|
||||||
|
transform: scale(calc(330 / 700));
|
||||||
|
transform-origin: 350px 0px;
|
||||||
|
margin-bottom: -400px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@media only screen and (min-width : 440px) {
|
||||||
|
#map-subframe {
|
||||||
|
transform: scale(calc(410 / 700));
|
||||||
|
margin-bottom: -300px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (min-width : 480px) {
|
||||||
|
#map-subframe {
|
||||||
|
transform: scale(calc(450 / 700));
|
||||||
|
margin-bottom: -250px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@media only screen and (min-width : 520px) {
|
||||||
|
#map-subframe {
|
||||||
|
transform: scale(calc(490 / 700));
|
||||||
|
margin-bottom: -200px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (min-width : 576px) {
|
||||||
|
#map-subframe {
|
||||||
|
transform: scale(calc(546 / 700));
|
||||||
|
margin-bottom: -150px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (min-width : 640px) {
|
||||||
|
#map-subframe {
|
||||||
|
transform: scale(calc(600/700));
|
||||||
|
margin-bottom: -100px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@media only screen and (min-width : 700px) {
|
||||||
|
#map-subframe {
|
||||||
|
transform: scale(calc(670 / 700));
|
||||||
|
margin-bottom: -20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@media only screen and (min-width : 730px) {
|
||||||
|
#map-subframe {
|
||||||
|
transform: none;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace sammo;
|
||||||
|
|
||||||
|
include "lib.php";
|
||||||
|
include "func.php";
|
||||||
|
|
||||||
|
APIHelper::launch(dirname(__FILE__));
|
||||||
+266
-53
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace sammo;
|
namespace sammo;
|
||||||
|
|
||||||
|
use DateTime;
|
||||||
use sammo\Event\Action;
|
use sammo\Event\Action;
|
||||||
|
|
||||||
require_once 'process_war.php';
|
require_once 'process_war.php';
|
||||||
@@ -189,7 +190,7 @@ function myNationInfo(General $generalObj)
|
|||||||
$templates = new \League\Plates\Engine(__DIR__ . '/templates');
|
$templates = new \League\Plates\Engine(__DIR__ . '/templates');
|
||||||
|
|
||||||
$nationID = $generalObj->getNationID();
|
$nationID = $generalObj->getNationID();
|
||||||
$nation = $db->queryFirstRow('SELECT * FROM nation WHERE nation = %i', $nationID)??getNationStaticInfo(0);
|
$nation = $db->queryFirstRow('SELECT * FROM nation WHERE nation = %i', $nationID) ?? getNationStaticInfo(0);
|
||||||
$city = $db->queryFirstRow(
|
$city = $db->queryFirstRow(
|
||||||
'SELECT COUNT(*) as cnt, SUM(pop) as totpop, SUM(pop_max) as maxpop from city where nation=%i',
|
'SELECT COUNT(*) as cnt, SUM(pop) as totpop, SUM(pop_max) as maxpop from city where nation=%i',
|
||||||
$nationID
|
$nationID
|
||||||
@@ -198,16 +199,16 @@ function myNationInfo(General $generalObj)
|
|||||||
|
|
||||||
$topChiefs = Util::convertArrayToDict($db->query('SELECT officer_level, no, name, npc FROM general WHERE nation = %i AND officer_level >= 11', $nationID), 'officer_level');
|
$topChiefs = Util::convertArrayToDict($db->query('SELECT officer_level, no, name, npc FROM general WHERE nation = %i AND officer_level >= 11', $nationID), 'officer_level');
|
||||||
|
|
||||||
$level12Name = key_exists(12, $topChiefs)?getColoredName($topChiefs[12]['name'], $topChiefs[12]['npc']):'-';
|
$level12Name = key_exists(12, $topChiefs) ? getColoredName($topChiefs[12]['name'], $topChiefs[12]['npc']) : '-';
|
||||||
$level11Name = key_exists(11, $topChiefs)?getColoredName($topChiefs[11]['name'], $topChiefs[11]['npc']):'-';
|
$level11Name = key_exists(11, $topChiefs) ? getColoredName($topChiefs[11]['name'], $topChiefs[11]['npc']) : '-';
|
||||||
|
|
||||||
$impossibleStrategicCommandLists = [];
|
$impossibleStrategicCommandLists = [];
|
||||||
$strategicCommandLists = GameConst::$availableChiefCommand['전략'];
|
$strategicCommandLists = GameConst::$availableChiefCommand['전략'];
|
||||||
$yearMonth = Util::joinYearMonth($admin['year'], $admin['month']);
|
$yearMonth = Util::joinYearMonth($admin['year'], $admin['month']);
|
||||||
foreach($strategicCommandLists as $command){
|
foreach ($strategicCommandLists as $command) {
|
||||||
$cmd = buildNationCommandClass($command, $generalObj, $admin, new LastTurn());
|
$cmd = buildNationCommandClass($command, $generalObj, $admin, new LastTurn());
|
||||||
$nextAvailableTurn = $cmd->getNextAvailableTurn();
|
$nextAvailableTurn = $cmd->getNextAvailableTurn();
|
||||||
if($nextAvailableTurn > $yearMonth){
|
if ($nextAvailableTurn > $yearMonth) {
|
||||||
$impossibleStrategicCommandLists[] = [$cmd->getName(), $nextAvailableTurn - $yearMonth];
|
$impossibleStrategicCommandLists[] = [$cmd->getName(), $nextAvailableTurn - $yearMonth];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -239,28 +240,28 @@ function myNationInfo(General $generalObj)
|
|||||||
<tr>
|
<tr>
|
||||||
<td class='bg1 center'><b>총주민</b></td>
|
<td class='bg1 center'><b>총주민</b></td>
|
||||||
<td class='center'>";
|
<td class='center'>";
|
||||||
echo $nationID===0 ? "해당 없음" : "{$city['totpop']}/{$city['maxpop']}";
|
echo $nationID === 0 ? "해당 없음" : "{$city['totpop']}/{$city['maxpop']}";
|
||||||
echo "</td>
|
echo "</td>
|
||||||
<td class='bg1 center'><b>총병사</b></td>
|
<td class='bg1 center'><b>총병사</b></td>
|
||||||
<td class='center'>";
|
<td class='center'>";
|
||||||
echo $nationID===0 ? "해당 없음" : "{$general['totcrew']}/{$general['maxcrew']}";
|
echo $nationID === 0 ? "해당 없음" : "{$general['totcrew']}/{$general['maxcrew']}";
|
||||||
echo "</td>
|
echo "</td>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td class='bg1 center'><b>국 고</b></td>
|
<td class='bg1 center'><b>국 고</b></td>
|
||||||
<td class='center'>";
|
<td class='center'>";
|
||||||
echo $nationID===0 ? "해당 없음" : "{$nation['gold']}";
|
echo $nationID === 0 ? "해당 없음" : "{$nation['gold']}";
|
||||||
echo "</td>
|
echo "</td>
|
||||||
<td class='bg1 center'><b>병 량</b></td>
|
<td class='bg1 center'><b>병 량</b></td>
|
||||||
<td class='center'>";
|
<td class='center'>";
|
||||||
echo $nationID===0 ? "해당 없음" : "{$nation['rice']}";
|
echo $nationID === 0 ? "해당 없음" : "{$nation['rice']}";
|
||||||
echo "</td>
|
echo "</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td class='bg1 center'><b>지급률</b></td>
|
<td class='bg1 center'><b>지급률</b></td>
|
||||||
<td class='center'>";
|
<td class='center'>";
|
||||||
if ($nationID===0) {
|
if ($nationID === 0) {
|
||||||
echo "해당 없음";
|
echo "해당 없음";
|
||||||
} else {
|
} else {
|
||||||
echo $nation['bill'] == 0 ? "0 %" : "{$nation['bill']} %";
|
echo $nation['bill'] == 0 ? "0 %" : "{$nation['bill']} %";
|
||||||
@@ -269,7 +270,7 @@ function myNationInfo(General $generalObj)
|
|||||||
</td>
|
</td>
|
||||||
<td class='bg1 center'><b>세 율</b></td>
|
<td class='bg1 center'><b>세 율</b></td>
|
||||||
<td class='center'>";
|
<td class='center'>";
|
||||||
if ($nationID===0) {
|
if ($nationID === 0) {
|
||||||
echo "해당 없음";
|
echo "해당 없음";
|
||||||
} else {
|
} else {
|
||||||
echo $nation['rate'] == 0 ? "0 %" : "{$nation['rate']} %";
|
echo $nation['rate'] == 0 ? "0 %" : "{$nation['rate']} %";
|
||||||
@@ -285,7 +286,7 @@ function myNationInfo(General $generalObj)
|
|||||||
|
|
||||||
$nation['tech'] = "$techCall / {$nation['tech']}";
|
$nation['tech'] = "$techCall / {$nation['tech']}";
|
||||||
|
|
||||||
if ($nationID===0) {
|
if ($nationID === 0) {
|
||||||
$nation['strategic_cmd_limit'] = "<font color=white>해당 없음</font>";
|
$nation['strategic_cmd_limit'] = "<font color=white>해당 없음</font>";
|
||||||
$nation['surlimit'] = "<font color=white>해당 없음</font>";
|
$nation['surlimit'] = "<font color=white>해당 없음</font>";
|
||||||
$nation['scout'] = "<font color=white>해당 없음</font>";
|
$nation['scout'] = "<font color=white>해당 없음</font>";
|
||||||
@@ -294,20 +295,20 @@ function myNationInfo(General $generalObj)
|
|||||||
} else {
|
} else {
|
||||||
if ($nation['strategic_cmd_limit'] != 0) {
|
if ($nation['strategic_cmd_limit'] != 0) {
|
||||||
$nation['strategic_cmd_limit'] = "<font color=red>{$nation['strategic_cmd_limit']}턴</font>";
|
$nation['strategic_cmd_limit'] = "<font color=red>{$nation['strategic_cmd_limit']}턴</font>";
|
||||||
} else if($impossibleStrategicCommandLists) {
|
} else if ($impossibleStrategicCommandLists) {
|
||||||
$nation['strategic_cmd_limit'] = "<font color=yellow>가 능</font>";
|
$nation['strategic_cmd_limit'] = "<font color=yellow>가 능</font>";
|
||||||
} else{
|
} else {
|
||||||
$nation['strategic_cmd_limit'] = "<font color=limegreen>가 능</font>";
|
$nation['strategic_cmd_limit'] = "<font color=limegreen>가 능</font>";
|
||||||
}
|
}
|
||||||
|
|
||||||
if($impossibleStrategicCommandLists){
|
if ($impossibleStrategicCommandLists) {
|
||||||
$text = [];
|
$text = [];
|
||||||
foreach($impossibleStrategicCommandLists as [$cmdName, $remainTurn]){
|
foreach ($impossibleStrategicCommandLists as [$cmdName, $remainTurn]) {
|
||||||
$text[] = "{$cmdName}: {$remainTurn}턴 뒤";
|
$text[] = "{$cmdName}: {$remainTurn}턴 뒤";
|
||||||
}
|
}
|
||||||
$nation['strategic_cmd_limit'] = $templates->render('tooltip', [
|
$nation['strategic_cmd_limit'] = $templates->render('tooltip', [
|
||||||
'text'=>'<span style="text-decoration:underline dashed;">'.$nation['strategic_cmd_limit'].'</span>',
|
'text' => '<span style="text-decoration:underline dashed;">' . $nation['strategic_cmd_limit'] . '</span>',
|
||||||
'info'=>'<span class="text-left d-inline-block">'.join('<br>', $text).'</span>',
|
'info' => '<span class="text-left d-inline-block">' . join('<br>', $text) . '</span>',
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -336,11 +337,11 @@ function myNationInfo(General $generalObj)
|
|||||||
<tr>
|
<tr>
|
||||||
<td style='text-align:center;' class='bg1'><b>속 령</b></td>
|
<td style='text-align:center;' class='bg1'><b>속 령</b></td>
|
||||||
<td style='text-align:center;'>";
|
<td style='text-align:center;'>";
|
||||||
echo $nationID===0 ? "-" : "{$city['cnt']}";
|
echo $nationID === 0 ? "-" : "{$city['cnt']}";
|
||||||
echo "</td>
|
echo "</td>
|
||||||
<td style='text-align:center;' class='bg1'><b>장 수</b></td>
|
<td style='text-align:center;' class='bg1'><b>장 수</b></td>
|
||||||
<td style='text-align:center;'>";
|
<td style='text-align:center;'>";
|
||||||
echo $nationID===0 ? "-" : "{$general['cnt']}";
|
echo $nationID === 0 ? "-" : "{$general['cnt']}";
|
||||||
echo "</td>
|
echo "</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -348,7 +349,7 @@ function myNationInfo(General $generalObj)
|
|||||||
<td style='text-align:center;'>{$nation['power']}</td>
|
<td style='text-align:center;'>{$nation['power']}</td>
|
||||||
<td style='text-align:center;' class='bg1'><b>기술력</b></td>
|
<td style='text-align:center;' class='bg1'><b>기술력</b></td>
|
||||||
<td style='text-align:center;'>";
|
<td style='text-align:center;'>";
|
||||||
echo $nationID===0 ? "-" : "{$nation['tech']}";
|
echo $nationID === 0 ? "-" : "{$nation['tech']}";
|
||||||
echo "</td>
|
echo "</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -904,7 +905,7 @@ function nationMsg(General $general)
|
|||||||
$nationID = $general->getNationID();
|
$nationID = $general->getNationID();
|
||||||
$nationStor = KVStorage::getStorage($db, $nationID, 'nation_env');
|
$nationStor = KVStorage::getStorage($db, $nationID, 'nation_env');
|
||||||
|
|
||||||
return $nationStor->notice??'';
|
return $nationStor->notice ?? '';
|
||||||
}
|
}
|
||||||
|
|
||||||
function banner()
|
function banner()
|
||||||
@@ -1227,13 +1228,13 @@ function updateOnline()
|
|||||||
$onlineNum = count($onlineUser);
|
$onlineNum = count($onlineUser);
|
||||||
$onlineNationUsers = Util::arrayGroupBy($onlineUser, 'nation');
|
$onlineNationUsers = Util::arrayGroupBy($onlineUser, 'nation');
|
||||||
|
|
||||||
uasort($onlineNationUsers, function(array $lhs, array $rhs){
|
uasort($onlineNationUsers, function (array $lhs, array $rhs) {
|
||||||
return -(count($lhs)<=>count($rhs));
|
return - (count($lhs) <=> count($rhs));
|
||||||
});
|
});
|
||||||
|
|
||||||
$onlineNation = [];
|
$onlineNation = [];
|
||||||
|
|
||||||
foreach($onlineNationUsers as $nationID=>$rawOnlineUser){
|
foreach ($onlineNationUsers as $nationID => $rawOnlineUser) {
|
||||||
$nationName = getNationStaticInfo($nationID)['name'];
|
$nationName = getNationStaticInfo($nationID)['name'];
|
||||||
$onlineNation[] = "【{$nationName}】";
|
$onlineNation[] = "【{$nationName}】";
|
||||||
$userList = join(', ', Util::squeezeFromArray($rawOnlineUser, 'name'));
|
$userList = join(', ', Util::squeezeFromArray($rawOnlineUser, 'name'));
|
||||||
@@ -1265,7 +1266,7 @@ function addAge()
|
|||||||
$generalID = $general['no'];
|
$generalID = $general['no'];
|
||||||
$special = SpecialityHelper::pickSpecialDomestic(
|
$special = SpecialityHelper::pickSpecialDomestic(
|
||||||
$general,
|
$general,
|
||||||
(Json::decode($general['aux'])['prev_types_special'])??[]
|
(Json::decode($general['aux'])['prev_types_special']) ?? []
|
||||||
);
|
);
|
||||||
$specialClass = buildGeneralSpecialDomesticClass($special);
|
$specialClass = buildGeneralSpecialDomesticClass($special);
|
||||||
$specialText = $specialClass->getName();
|
$specialText = $specialClass->getName();
|
||||||
@@ -1282,16 +1283,26 @@ function addAge()
|
|||||||
|
|
||||||
foreach ($db->query('SELECT no,name,nation,leadership,strength,intel,npc,dex1,dex2,dex3,dex4,dex5,aux from general where specage2<=age and special2=%s', GameConst::$defaultSpecialWar) as $general) {
|
foreach ($db->query('SELECT no,name,nation,leadership,strength,intel,npc,dex1,dex2,dex3,dex4,dex5,aux from general where specage2<=age and special2=%s', GameConst::$defaultSpecialWar) as $general) {
|
||||||
$generalID = $general['no'];
|
$generalID = $general['no'];
|
||||||
$special2 = SpecialityHelper::pickSpecialWar(
|
$generalAux = Json::decode($general['aux']);
|
||||||
$general,
|
|
||||||
(Json::decode($general['aux'])['prev_types_special2'])??[]
|
$updateVars = [];
|
||||||
);
|
if(key_exists('inheritSpecificSpecialWar', $generalAux)){
|
||||||
|
$special2 = $generalAux['inheritSpecificSpecialWar'];
|
||||||
|
unset($generalAux['inheritSpecificSpecialWar']);
|
||||||
|
$updateVars['aux'] = Json::encode($generalAux);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
$special2 = SpecialityHelper::pickSpecialWar(
|
||||||
|
$general,
|
||||||
|
($generalAux['prev_types_special2']) ?? []
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
$specialClass = buildGeneralSpecialWarClass($special2);
|
$specialClass = buildGeneralSpecialWarClass($special2);
|
||||||
$specialText = $specialClass->getName();
|
$specialText = $specialClass->getName();
|
||||||
|
|
||||||
$db->update('general', [
|
$updateVars['special2'] = $special2;
|
||||||
'special2' => $special2
|
$db->update('general', $updateVars, 'no=%i', $general['no']);
|
||||||
], 'no=%i', $general['no']);
|
|
||||||
|
|
||||||
$logger = new ActionLogger($generalID, $general['nation'], $year, $month);
|
$logger = new ActionLogger($generalID, $general['nation'], $year, $month);
|
||||||
|
|
||||||
@@ -1537,15 +1548,15 @@ function giveRandomUniqueItem(General $general, string $acquireType): bool
|
|||||||
$occupiedUnique = [];
|
$occupiedUnique = [];
|
||||||
|
|
||||||
$invalidItemType = [];
|
$invalidItemType = [];
|
||||||
foreach(array_keys(GameConst::$allItems) as $itemType){
|
foreach (array_keys(GameConst::$allItems) as $itemType) {
|
||||||
$ownItem = $general->getItems()[$itemType]??null;
|
$ownItem = $general->getItems()[$itemType] ?? null;
|
||||||
if($ownItem !== null && !$ownItem->isBuyable()){
|
if ($ownItem !== null && !$ownItem->isBuyable()) {
|
||||||
$invalidItemType[$itemType] = true;
|
$invalidItemType[$itemType] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (array_keys(GameConst::$allItems) as $itemType) {
|
foreach (array_keys(GameConst::$allItems) as $itemType) {
|
||||||
if(key_exists($itemType, $invalidItemType)){
|
if (key_exists($itemType, $invalidItemType)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
foreach ($db->queryAllLists('SELECT %b, count(*) as cnt FROM general GROUP BY %b', $itemType, $itemType) as [$itemCode, $cnt]) {
|
foreach ($db->queryAllLists('SELECT %b, count(*) as cnt FROM general GROUP BY %b', $itemType, $itemType) as [$itemCode, $cnt]) {
|
||||||
@@ -1561,11 +1572,11 @@ function giveRandomUniqueItem(General $general, string $acquireType): bool
|
|||||||
}
|
}
|
||||||
|
|
||||||
foreach (GameConst::$allItems as $itemType => $itemCategories) {
|
foreach (GameConst::$allItems as $itemType => $itemCategories) {
|
||||||
if(key_exists($itemType, $invalidItemType)){
|
if (key_exists($itemType, $invalidItemType)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
foreach ($itemCategories as $itemCode => $cnt) {
|
foreach ($itemCategories as $itemCode => $cnt) {
|
||||||
if($cnt == 0){
|
if ($cnt == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!key_exists($itemCode, $occupiedUnique)) {
|
if (!key_exists($itemCode, $occupiedUnique)) {
|
||||||
@@ -1607,6 +1618,192 @@ function giveRandomUniqueItem(General $general, string $acquireType): bool
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function rollbackInheritUniqueTrial(General $general, string $itemKey, string $reason)
|
||||||
|
{
|
||||||
|
|
||||||
|
$ownerID = $general->getVar('owner');
|
||||||
|
|
||||||
|
$db = DB::db();
|
||||||
|
|
||||||
|
$itemTrials = $general->getAuxVar('inheritUniqueTrial');
|
||||||
|
LogText("선택유니크 롤백:{$ownerID}", [$itemKey, $itemTrials]);
|
||||||
|
unset($itemTrials[$itemKey]);
|
||||||
|
$general->setAuxVar('inheritUniqueTrial', $itemTrials);
|
||||||
|
|
||||||
|
|
||||||
|
$trialStor = KVStorage::getStorage($db, "ut_{$itemKey}");
|
||||||
|
$ownTrial = $trialStor->getValue("u{$ownerID}");
|
||||||
|
|
||||||
|
if ($ownTrial) {
|
||||||
|
//두 값이 general, KVStorage 둘다 있고, 이중에선 KVStorage 값을 기준으로 하자 따르자
|
||||||
|
[,, $amount] = $ownTrial;
|
||||||
|
$trialStor->deleteValue("u{$ownerID}");
|
||||||
|
$general->increaseInheritancePoint('previous', $amount);
|
||||||
|
LogText("선택유니크 롤백포인트:{$ownerID}", $amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
$itemObj = buildItemClass($itemKey);
|
||||||
|
$itemName = $itemObj->getName();
|
||||||
|
//메시지
|
||||||
|
|
||||||
|
$staticNation = $general->getStaticNation();
|
||||||
|
|
||||||
|
$unlimited = new \DateTime('9999-12-31');
|
||||||
|
$src = new MessageTarget(0, '', 0, 'System', '#000000');
|
||||||
|
$dest = new MessageTarget($general->getID(), $general->getName(), $general->getNationID(), $staticNation['name'], $staticNation['color'], GetImageURL($general->getVar('imgsvr'), $general->getVar('picture')));
|
||||||
|
$josaUl = JosaUtil::pick($itemName, '을');
|
||||||
|
$msg = new Message(
|
||||||
|
Message::MSGTYPE_PRIVATE,
|
||||||
|
$src,
|
||||||
|
$dest,
|
||||||
|
"{$itemName}{$josaUl} 얻지 못했습니다. {$reason}",
|
||||||
|
new DateTime(),
|
||||||
|
$unlimited,
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
|
$msg->send(true);
|
||||||
|
$general->applyDB($db);
|
||||||
|
}
|
||||||
|
|
||||||
|
function tryInheritUniqueItem(General $general, string $acquireType = '아이템'): bool
|
||||||
|
{
|
||||||
|
$ownerID = $general->getVar('owner');
|
||||||
|
if (!$ownerID) {
|
||||||
|
LogText("선택유니크 실패???: {$ownerID}", $general->getName());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$itemTrials = $general->getAuxVar('inheritUniqueTrial') ?? [];
|
||||||
|
arsort($itemTrials);
|
||||||
|
LogText("선택유니크항목: {$ownerID}", $itemTrials);
|
||||||
|
|
||||||
|
$db = DB::db();
|
||||||
|
|
||||||
|
$ownTarget = null;
|
||||||
|
$ownType = null;
|
||||||
|
|
||||||
|
foreach ($itemTrials as $itemKey => $amount) {
|
||||||
|
$availableItemTypes = [];
|
||||||
|
$reasons = [];
|
||||||
|
foreach (GameConst::$allItems as $itemType => $itemList) {
|
||||||
|
//아직은 그런 경우는 없지만 동일 유니크를 여러 부위에 장착할 수 있을지도 모름
|
||||||
|
if (!key_exists($itemKey, $itemList)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$ownItem = $general->getItem($itemType);
|
||||||
|
if ($ownItem->getRawClassName() == $itemKey) {
|
||||||
|
$reasons[] = '이미 그 유니크를 가지고 있습니다.';
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
if (!$ownItem->isBuyable()) {
|
||||||
|
$reasons[] = '이미 다른 유니크를 가지고 있습니다.';
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
$availableCnt = $itemList[$itemKey];
|
||||||
|
$occupiedCnt = $db->queryFirstField('SELECT count(*) FROM general WHERE %b = %s', $itemType, $itemKey);
|
||||||
|
if ($occupiedCnt >= $availableCnt) {
|
||||||
|
$reasons[] = '그 유니크는 모두 점유되었습니다.';
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$availableItemTypes[] = $itemType;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$availableItemTypes) {
|
||||||
|
rollbackInheritUniqueTrial($general, $itemKey, join(' ', $reasons));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$reasons = [];
|
||||||
|
|
||||||
|
$itemType = Util::choiceRandom($availableItemTypes);
|
||||||
|
|
||||||
|
$trialStor = KVStorage::getStorage($db, "ut_{$itemKey}"); //혹시 itemKey의 크기가 37이 넘을 수 있을까?
|
||||||
|
$anyTrials = $trialStor->getAll();
|
||||||
|
if (!$anyTrials) {
|
||||||
|
//순서가 꼬였던 모양, 실제 값은 storage를 우선시하자
|
||||||
|
rollbackInheritUniqueTrial($general, $itemKey, '절차상의 오류입니다.');
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//XXX: 정렬할 필요 없지 않나?
|
||||||
|
usort($anyTrials, function ($lhsTrial, $rhsTrial) {
|
||||||
|
[,, $lhsAmount] = $lhsTrial;
|
||||||
|
[,, $rhsAmount] = $rhsTrial;
|
||||||
|
return $rhsAmount <=> $lhsAmount; //큰 값이 앞에 오도록
|
||||||
|
});
|
||||||
|
|
||||||
|
LogText("선택유니크상태 {$ownerID} {$itemKey}", $anyTrials);
|
||||||
|
|
||||||
|
//공동 1등인데 본인이 있을 수도 있다.
|
||||||
|
[,, $topAmount] = $anyTrials[0];
|
||||||
|
if ($amount < $topAmount) {
|
||||||
|
$compAmount = $topAmount / $amount;
|
||||||
|
if ($compAmount > 2.0) {
|
||||||
|
$compText = '엄청난 차이로 ';
|
||||||
|
} else if ($compAmount > 1.2) {
|
||||||
|
$compText = '큰 차이로 ';
|
||||||
|
} else if ($compAmount > 1.05) {
|
||||||
|
$compText = '';
|
||||||
|
} else {
|
||||||
|
$compText = '아슬아슬한 차이로 ';
|
||||||
|
}
|
||||||
|
rollbackInheritUniqueTrial($general, $itemKey, "{$compText}상위 입찰한 장수가 있습니다.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//내가 1위다
|
||||||
|
if ($ownTarget !== null) {
|
||||||
|
//이미 다른 아이템을 얻기로 되어있다.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$ownTarget = $itemKey;
|
||||||
|
$ownType = $itemType;
|
||||||
|
}
|
||||||
|
unset($itemKey);
|
||||||
|
unset($itemType);
|
||||||
|
|
||||||
|
if ($ownTarget === null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogText("선택유니크획득{$ownerID}", $ownTarget);
|
||||||
|
|
||||||
|
$trialStor = KVStorage::getStorage($db, "ut_{$ownTarget}");
|
||||||
|
$trialStor->deleteValue("u{$ownerID}");
|
||||||
|
|
||||||
|
//rollbackInheritUniqueTrial 과정 때문에 새로 받아와야함
|
||||||
|
$itemTrials = $general->getAuxVar('inheritUniqueTrial');
|
||||||
|
unset($itemTrials[$ownTarget]);
|
||||||
|
$general->setAuxVar('inheritUniqueTrial', $itemTrials);
|
||||||
|
|
||||||
|
$nationName = $general->getStaticNation()['name'];
|
||||||
|
$generalName = $general->getName();
|
||||||
|
$josaYi = JosaUtil::pick($generalName, '이');
|
||||||
|
$itemObj = buildItemClass($ownTarget);
|
||||||
|
$itemName = $itemObj->getName();
|
||||||
|
$itemRawName = $itemObj->getRawName();
|
||||||
|
$josaUl = JosaUtil::pick($itemRawName, '을');
|
||||||
|
|
||||||
|
|
||||||
|
$general->setVar($ownType, $ownTarget);
|
||||||
|
|
||||||
|
|
||||||
|
$logger = $general->getLogger();
|
||||||
|
|
||||||
|
$logger->pushGeneralActionLog("<C>{$itemName}</>{$josaUl} 습득했습니다!");
|
||||||
|
$logger->pushGeneralHistoryLog("<C>{$itemName}</>{$josaUl} 습득");
|
||||||
|
$logger->pushGlobalActionLog("<Y>{$generalName}</>{$josaYi} <C>{$itemName}</>{$josaUl} 습득했습니다!");
|
||||||
|
$logger->pushGlobalHistoryLog("<C><b>【{$acquireType}】</b></><D><b>{$nationName}</b></>의 <Y>{$generalName}</>{$josaYi} <C>{$itemName}</>{$josaUl} 습득했습니다!");
|
||||||
|
|
||||||
|
$general->applyDB($db);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
function tryUniqueItemLottery(General $general, string $acquireType = '아이템'): bool
|
function tryUniqueItemLottery(General $general, string $acquireType = '아이템'): bool
|
||||||
{
|
{
|
||||||
$db = DB::db();
|
$db = DB::db();
|
||||||
@@ -1616,8 +1813,13 @@ function tryUniqueItemLottery(General $general, string $acquireType = '아이템
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($general->getNPCType() > 6) {
|
$inheritUnique = $general->getAuxVar('inheritUniqueTrial');
|
||||||
return false;
|
if ($inheritUnique && count($inheritUnique)) {
|
||||||
|
LogText("유니크 준비?? {$general->getID()}", $inheritUnique);
|
||||||
|
$trialResult = tryInheritUniqueItem($general, $acquireType);
|
||||||
|
if ($trialResult) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$itemTypeCnt = count(GameConst::$allItems);
|
$itemTypeCnt = count(GameConst::$allItems);
|
||||||
@@ -1629,7 +1831,7 @@ function tryUniqueItemLottery(General $general, string $acquireType = '아이템
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if($trialCnt <= 0){
|
if ($trialCnt <= 0) {
|
||||||
LogText("{$general->getName()}, {$general->getID()} 모든 아이템", $trialCnt);
|
LogText("{$general->getName()}, {$general->getID()} 모든 아이템", $trialCnt);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1653,18 +1855,27 @@ function tryUniqueItemLottery(General $general, string $acquireType = '아이템
|
|||||||
$prob = 1 / ($genCount * $itemTypeCnt / 10 / 4); // 건국시 4개(20%) 등장(200명시 20국 정도 됨)
|
$prob = 1 / ($genCount * $itemTypeCnt / 10 / 4); // 건국시 4개(20%) 등장(200명시 20국 정도 됨)
|
||||||
}
|
}
|
||||||
|
|
||||||
$prob = Util::valueFit($prob, null, 1 / 4);//최대치 감소
|
$prob = Util::valueFit($prob, null, 1 / 4); //최대치 감소
|
||||||
$result = false;
|
$result = false;
|
||||||
|
|
||||||
|
$prob /= sqrt(2);
|
||||||
|
$moreProb = pow(2, 1/4);
|
||||||
|
|
||||||
|
if($general->getAuxVar('inheritRandomUnique')){
|
||||||
|
//포인트로 랜덤 유니크 획득
|
||||||
|
$prob = 1;
|
||||||
|
LogText("{$general->getName()}, {$general->getID()} 유산 포인트 유니크", $prob);
|
||||||
|
$general->setAuxVar('inheritRandomUnique', null);
|
||||||
|
}
|
||||||
|
|
||||||
foreach(Util::range($trialCnt) as $_idx){
|
foreach (Util::range($trialCnt) as $_idx) {
|
||||||
if (Util::randBool($prob)) {
|
if (Util::randBool($prob)) {
|
||||||
$result = true;
|
$result = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
$prob *= $moreProb;
|
||||||
}
|
}
|
||||||
if(!$result){
|
if (!$result) {
|
||||||
LogText("{$general->getName()}, {$general->getID()} 유니크 실패 {$trialCnt}", $prob);
|
LogText("{$general->getName()}, {$general->getID()} 유니크 실패 {$trialCnt}", $prob);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1681,7 +1892,7 @@ function getAdmin()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @return General[] */
|
/** @return General[] */
|
||||||
function deleteNation(General $lord, bool $applyDB):array
|
function deleteNation(General $lord, bool $applyDB): array
|
||||||
{
|
{
|
||||||
$lordID = $lord->getID();
|
$lordID = $lord->getID();
|
||||||
$nationID = $lord->getNationID();
|
$nationID = $lord->getNationID();
|
||||||
@@ -1706,7 +1917,8 @@ function deleteNation(General $lord, bool $applyDB):array
|
|||||||
$nationID,
|
$nationID,
|
||||||
$lordID
|
$lordID
|
||||||
),
|
),
|
||||||
['npc', 'gold', 'rice', 'experience', 'explevel', 'dedication', 'dedlevel', 'belong', 'aux'], 1
|
['npc', 'gold', 'rice', 'experience', 'explevel', 'dedication', 'dedlevel', 'belong', 'aux'],
|
||||||
|
1
|
||||||
);
|
);
|
||||||
$nationGeneralList[$lordID] = $lord;
|
$nationGeneralList[$lordID] = $lord;
|
||||||
|
|
||||||
@@ -1722,11 +1934,12 @@ function deleteNation(General $lord, bool $applyDB):array
|
|||||||
$destroyHistoryLog = "<D><b>{$nationName}</b></>{$josaYi} <R>멸망</>";
|
$destroyHistoryLog = "<D><b>{$nationName}</b></>{$josaYi} <R>멸망</>";
|
||||||
|
|
||||||
// 전 장수 재야로
|
// 전 장수 재야로
|
||||||
foreach($nationGeneralList as $general){
|
foreach ($nationGeneralList as $general) {
|
||||||
$general->setAuxVar('max_belong',
|
$general->setAuxVar(
|
||||||
|
'max_belong',
|
||||||
max(
|
max(
|
||||||
$general->getVar('belong'),
|
$general->getVar('belong'),
|
||||||
$general->getAuxVar('max_belong')??0
|
$general->getAuxVar('max_belong') ?? 0
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
$general->setVar('belong', 0);
|
$general->setVar('belong', 0);
|
||||||
@@ -1739,7 +1952,7 @@ function deleteNation(General $lord, bool $applyDB):array
|
|||||||
$logger->pushGeneralActionLog($destroyLog, ActionLogger::PLAIN);
|
$logger->pushGeneralActionLog($destroyLog, ActionLogger::PLAIN);
|
||||||
$logger->pushGeneralHistoryLog($destroyHistoryLog);
|
$logger->pushGeneralHistoryLog($destroyHistoryLog);
|
||||||
|
|
||||||
if($applyDB){
|
if ($applyDB) {
|
||||||
$general->applyDB($db);
|
$general->applyDB($db);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2158,7 +2371,7 @@ function getRandTurn($term, ?\DateTimeInterface $baseDateTime = null)
|
|||||||
$randSecond = Util::randRangeInt(0, 60 * $term - 1);
|
$randSecond = Util::randRangeInt(0, 60 * $term - 1);
|
||||||
$randFraction = Util::randRangeInt(0, 999999) / 1000000; //6자리 소수
|
$randFraction = Util::randRangeInt(0, 999999) / 1000000; //6자리 소수
|
||||||
|
|
||||||
return $baseDateTime->add(TimeUtil::secondsToDateInterval($randSecond + $randFraction))->format('Y-m-d H:i:s');
|
return TimeUtil::format($baseDateTime->add(TimeUtil::secondsToDateInterval($randSecond + $randFraction)), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRandTurn2($term, ?\DateTimeInterface $baseDateTime = null)
|
function getRandTurn2($term, ?\DateTimeInterface $baseDateTime = null)
|
||||||
@@ -2173,5 +2386,5 @@ function getRandTurn2($term, ?\DateTimeInterface $baseDateTime = null)
|
|||||||
$randSecond = Util::randRangeInt(0, 60 * $term - 1);
|
$randSecond = Util::randRangeInt(0, 60 * $term - 1);
|
||||||
$randFraction = Util::randRangeInt(0, 999999) / 1000000; //6자리 소수
|
$randFraction = Util::randRangeInt(0, 999999) / 1000000; //6자리 소수
|
||||||
|
|
||||||
return $baseDateTime->sub(TimeUtil::secondsToDateInterval($randSecond + $randFraction))->format('Y-m-d H:i:s');
|
return $baseDateTime->sub(TimeUtil::secondsToDateInterval($randSecond + $randFraction))->format('Y-m-d H:i:s.u');
|
||||||
}
|
}
|
||||||
|
|||||||
+37
-12
@@ -1,4 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace sammo;
|
namespace sammo;
|
||||||
|
|
||||||
@@ -6,7 +6,7 @@ use sammo\Command\BaseCommand;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Value Converter
|
* Value Converter
|
||||||
*
|
*
|
||||||
* Side effect 없이 값의 변환만을 수행하는 함수들의 모음.
|
* Side effect 없이 값의 변환만을 수행하는 함수들의 모음.
|
||||||
* (단, autoload, 정적 변수 초기화는 허용)
|
* (단, autoload, 정적 변수 초기화는 허용)
|
||||||
*/
|
*/
|
||||||
@@ -175,7 +175,7 @@ function buildNationTypeClass(?string $type):BaseNation{
|
|||||||
return $cache[$type];
|
return $cache[$type];
|
||||||
}
|
}
|
||||||
$class = getNationTypeClass($type);
|
$class = getNationTypeClass($type);
|
||||||
|
|
||||||
$obj = new $class();
|
$obj = new $class();
|
||||||
$cache[$type]= $obj;
|
$cache[$type]= $obj;
|
||||||
return $obj;
|
return $obj;
|
||||||
@@ -241,7 +241,7 @@ function buildItemClass(?string $type):BaseItem{
|
|||||||
return $cache[$type];
|
return $cache[$type];
|
||||||
}
|
}
|
||||||
$class = getItemClass($type);
|
$class = getItemClass($type);
|
||||||
|
|
||||||
$obj = new $class();
|
$obj = new $class();
|
||||||
$cache[$type]= $obj;
|
$cache[$type]= $obj;
|
||||||
return $obj;
|
return $obj;
|
||||||
@@ -276,7 +276,7 @@ function buildGeneralSpecialDomesticClass(?string $type):BaseSpecial{
|
|||||||
return $cache[$type];
|
return $cache[$type];
|
||||||
}
|
}
|
||||||
$class = getGeneralSpecialDomesticClass($type);
|
$class = getGeneralSpecialDomesticClass($type);
|
||||||
|
|
||||||
$obj = new $class();
|
$obj = new $class();
|
||||||
$cache[$type]= $obj;
|
$cache[$type]= $obj;
|
||||||
return $obj;
|
return $obj;
|
||||||
@@ -311,7 +311,7 @@ function buildGeneralSpecialWarClass(?string $type):BaseSpecial{
|
|||||||
return $cache[$type];
|
return $cache[$type];
|
||||||
}
|
}
|
||||||
$class = getGeneralSpecialWarClass($type);
|
$class = getGeneralSpecialWarClass($type);
|
||||||
|
|
||||||
$obj = new $class();
|
$obj = new $class();
|
||||||
$cache[$type]= $obj;
|
$cache[$type]= $obj;
|
||||||
return $obj;
|
return $obj;
|
||||||
@@ -357,6 +357,31 @@ function buildNationCommandClass(?string $type, General $generalObj, array $env,
|
|||||||
return new $class($generalObj, $env, $lastTurn, $arg);
|
return new $class($generalObj, $env, $lastTurn, $arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getAPIExecutorClass($path){
|
||||||
|
|
||||||
|
static $basePath = __NAMESPACE__.'\\API\\';
|
||||||
|
if(is_string($path)){
|
||||||
|
}
|
||||||
|
else if(is_array($path)){
|
||||||
|
$path = join('\\', $path);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
throw new \InvalidArgumentException("{$path}는 올바른 API 지시자가 아님");
|
||||||
|
}
|
||||||
|
|
||||||
|
$classPath = str_replace('/', '\\', $basePath.$path);
|
||||||
|
|
||||||
|
if(class_exists($classPath)){
|
||||||
|
return $classPath;
|
||||||
|
}
|
||||||
|
throw new \InvalidArgumentException("{$path}는 올바른 API 경로가 아님");
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildAPIExecutorClass($type, string $rootPath, array $args):\sammo\BaseAPI{
|
||||||
|
$class = getAPIExecutorClass($type);
|
||||||
|
return new $class($rootPath, $args);
|
||||||
|
}
|
||||||
|
|
||||||
function getWarUnitTriggerClass(string $type){
|
function getWarUnitTriggerClass(string $type){
|
||||||
static $basePath = __NAMESPACE__.'\\WarUnitTrigger\\';
|
static $basePath = __NAMESPACE__.'\\WarUnitTrigger\\';
|
||||||
$classPath = ($basePath.$type);
|
$classPath = ($basePath.$type);
|
||||||
@@ -391,8 +416,8 @@ function getGeneralPoolClass(string $type){
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param \MeekroDB $db
|
* @param \MeekroDB $db
|
||||||
* @param int $owner
|
* @param int $owner
|
||||||
* @param int $pickCnt
|
* @param int $pickCnt
|
||||||
* @param null|string $prefix
|
* @param null|string $prefix
|
||||||
* @return AbsGeneralPool[]
|
* @return AbsGeneralPool[]
|
||||||
*/
|
*/
|
||||||
@@ -538,8 +563,8 @@ function getExpLevel($experience) {
|
|||||||
|
|
||||||
function getDedLevel($dedication) {
|
function getDedLevel($dedication) {
|
||||||
$level = Util::valueFit(
|
$level = Util::valueFit(
|
||||||
ceil(sqrt($dedication) / 10),
|
ceil(sqrt($dedication) / 10),
|
||||||
0,
|
0,
|
||||||
GameConst::$maxDedLevel
|
GameConst::$maxDedLevel
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -572,7 +597,7 @@ function getCost(int $armtype) : int {
|
|||||||
function getTechLevel($tech):int{
|
function getTechLevel($tech):int{
|
||||||
return Util::valueFit(
|
return Util::valueFit(
|
||||||
floor($tech / 1000),
|
floor($tech / 1000),
|
||||||
0,
|
0,
|
||||||
GameConst::$maxTechLevel
|
GameConst::$maxTechLevel
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -583,7 +608,7 @@ function TechLimit($startYear, $year, $tech) : bool {
|
|||||||
|
|
||||||
$relMaxTech = Util::valueFit(
|
$relMaxTech = Util::valueFit(
|
||||||
floor($relYear / 5) + 1,
|
floor($relYear / 5) + 1,
|
||||||
1,
|
1,
|
||||||
GameConst::$maxTechLevel
|
GameConst::$maxTechLevel
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
+14
-4
@@ -623,7 +623,7 @@ function updateNationState()
|
|||||||
$nation['nation'],
|
$nation['nation'],
|
||||||
$targetKillTurn
|
$targetKillTurn
|
||||||
);
|
);
|
||||||
$nationGenList = General::createGeneralObjListFromDB($nationGenIDList, ['belong', 'npc'], 2);
|
$nationGenList = General::createGeneralObjListFromDB($nationGenIDList, ['belong', 'npc', 'aux'], 2);
|
||||||
$chiefObj = null;
|
$chiefObj = null;
|
||||||
|
|
||||||
$uniqueLotteryWeightList = [];
|
$uniqueLotteryWeightList = [];
|
||||||
@@ -1150,15 +1150,24 @@ function checkEmperior()
|
|||||||
LogHistory();
|
LogHistory();
|
||||||
}
|
}
|
||||||
|
|
||||||
function resetInheritanceUser(int $userID, bool $isRebirth=false){
|
function resetInheritanceUser(int $userID, bool $isRebirth=false):float{
|
||||||
$rebirthDegraded = [
|
$rebirthDegraded = [
|
||||||
'dex'=>0.5,
|
'dex'=>0.5,
|
||||||
];
|
];
|
||||||
|
|
||||||
$inheritStor = KVStorage::getStorage(DB::db(), "inheritance_{$userID}");
|
$inheritStor = KVStorage::getStorage(DB::db(), "inheritance_{$userID}");
|
||||||
$totalPoint = 0;
|
$totalPoint = 0;
|
||||||
foreach($inheritStor->getAll() as $key=>[$value,]){
|
$allPoints = $inheritStor->getAll();
|
||||||
if(key_exists($key, $rebirthDegraded)){
|
if(!$allPoints || count($allPoints) == 0){
|
||||||
|
//비었으므로 리셋 안함
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(count($allPoints) == 1 && key_exists('previous', $allPoints)){
|
||||||
|
//이미 리셋되었으므로 리셋 안함
|
||||||
|
return $allPoints['previous'][0];
|
||||||
|
}
|
||||||
|
foreach($allPoints as $key=>[$value,]){
|
||||||
|
if($isRebirth && key_exists($key, $rebirthDegraded)){
|
||||||
$value *= $rebirthDegraded[$key];
|
$value *= $rebirthDegraded[$key];
|
||||||
}
|
}
|
||||||
$totalPoint += $value;
|
$totalPoint += $value;
|
||||||
@@ -1166,6 +1175,7 @@ function resetInheritanceUser(int $userID, bool $isRebirth=false){
|
|||||||
$totalPoint = Util::toInt($totalPoint);
|
$totalPoint = Util::toInt($totalPoint);
|
||||||
$inheritStor->resetValues();
|
$inheritStor->resetValues();
|
||||||
$inheritStor->setValue('previous', [$totalPoint, null]);
|
$inheritStor->setValue('previous', [$totalPoint, null]);
|
||||||
|
return $totalPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateMaxDomesticCritical(General $general, $score){
|
function updateMaxDomesticCritical(General $general, $score){
|
||||||
|
|||||||
-182
@@ -1,182 +0,0 @@
|
|||||||
<?php
|
|
||||||
namespace sammo;
|
|
||||||
|
|
||||||
include "lib.php";
|
|
||||||
include "func.php";
|
|
||||||
|
|
||||||
$session = Session::requireLogin()->setReadOnly();
|
|
||||||
$userID = Session::getUserID();
|
|
||||||
|
|
||||||
if (!$userID) {
|
|
||||||
MessageBox("잘못된 접근입니다!!!");
|
|
||||||
echo "<script>history.go(-1);</script>";
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//회원 테이블에서 정보확인
|
|
||||||
$member = RootDB::db()->queryFirstRow("select no,name,picture,imgsvr,grade from member where no= %i", $userID);
|
|
||||||
|
|
||||||
if (!$member) {
|
|
||||||
MessageBox("잘못된 접근입니다!!!");
|
|
||||||
echo "<script>history.go(-1);</script>";
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
$db = DB::db();
|
|
||||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
|
||||||
$admin = $gameStor->getValues(['block_general_create','show_img_level','maxgeneral']);
|
|
||||||
if($admin['block_general_create']){
|
|
||||||
MessageBox("잘못된 접근입니다!!!");
|
|
||||||
echo "<script>history.go(-1);</script>";
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title><?=UniqueConst::$serverName?>: 장수생성</title>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
||||||
<meta name="viewport" content="width=1024" />
|
|
||||||
<script>
|
|
||||||
var defaultStatTotal = <?=GameConst::$defaultStatTotal?>;
|
|
||||||
var defaultStatMin = <?=GameConst::$defaultStatMin?>;
|
|
||||||
var defaultStatMax = <?=GameConst::$defaultStatMax?>;
|
|
||||||
|
|
||||||
var charInfoText = <?php
|
|
||||||
|
|
||||||
$charInfoText = [];
|
|
||||||
foreach(GameConst::$availablePersonality as $personalityID){
|
|
||||||
$personalityInfo = buildPersonalityClass($personalityID)->getInfo();
|
|
||||||
$charInfoText[$personalityID] = $personalityInfo;
|
|
||||||
}
|
|
||||||
echo Json::encode((object)$charInfoText);
|
|
||||||
?>;
|
|
||||||
</script>
|
|
||||||
<?=WebUtil::printCSS('../e_lib/bootstrap.min.css')?>
|
|
||||||
<?=WebUtil::printCSS('../d_shared/common.css')?>
|
|
||||||
<?=WebUtil::printCSS('css/common.css')?>
|
|
||||||
<?=WebUtil::printJS('../d_shared/common_path.js')?>
|
|
||||||
<?=WebUtil::printJS('dist_js/vendors.js')?>
|
|
||||||
<?=WebUtil::printJS('dist_js/common.js')?>
|
|
||||||
<?=WebUtil::printJS('dist_js/join.js')?>
|
|
||||||
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<table align=center width=1000 class='tb_layout bg0'>
|
|
||||||
<tr><td>장 수 생 성<br><?=backButton()?></td></tr>
|
|
||||||
</table>
|
|
||||||
<table align=center width=1000 class='tb_layout bg0'>
|
|
||||||
<tr><td align=center><?=info(0)?></td></tr>
|
|
||||||
</table>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
$gencount = $db->queryFirstField('SELECT count(no) FROM general WHERE npc<2');
|
|
||||||
|
|
||||||
if ($gencount >= $admin['maxgeneral']) {
|
|
||||||
echo "<script>alert('더 이상 등록할 수 없습니다.');</script>";
|
|
||||||
echo "<script>history.go(-1);</script>";
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
$nationList = $db->query('SELECT nation,`name`,color,scout FROM nation');
|
|
||||||
shuffle($nationList);
|
|
||||||
$nationList = Util::convertArrayToDict($nationList, 'nation');
|
|
||||||
//NOTE: join 안할것임
|
|
||||||
$scoutMsgs = KVStorage::getValuesFromInterNamespace($db, 'nation_env', 'scout_msg');
|
|
||||||
foreach($scoutMsgs as $nationID=>$scoutMsg){
|
|
||||||
$nationList[$nationID]['scoutmsg'] = $scoutMsg;
|
|
||||||
}
|
|
||||||
|
|
||||||
echo getInvitationList($nationList);
|
|
||||||
?>
|
|
||||||
|
|
||||||
<form id='join_form' name=form1 method=post action=join_post.php>
|
|
||||||
<table align=center width=1000 class='tb_layout bg0'>
|
|
||||||
<tr>
|
|
||||||
<td colspan=3 align=center class='bg1'>장수 생성</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td width=498 align=right class='bg1'>장수명</td>
|
|
||||||
<td colspan=2>
|
|
||||||
<input id="generalName" type=text name=name maxlength=18 size=18 style="color:white;background-color:black;" value="<?=$member['name']?>">(전각 9글자, 반각 18글자 이내)
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<?php
|
|
||||||
if ($admin['show_img_level'] >= 1 && $member['grade'] >= 1 && $member['picture'] != "") {
|
|
||||||
$imageTemp = GetImageURL($member['imgsvr']);
|
|
||||||
echo "
|
|
||||||
<tr>
|
|
||||||
<td align=right class='bg1'>전콘 사용 여부</td>
|
|
||||||
<td width=64 height=64>
|
|
||||||
<img width='64' height='64' src='{$imageTemp}/{$member['picture']}' border='0'>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<input type=checkbox name=pic value=1 checked>사용
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
";
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
<tr>
|
|
||||||
<td align=center colspan=3>
|
|
||||||
계정관리에서 자신만을 표현할 수 있는 아이콘을 업로드 해보세요!
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td width=498 align=right class='bg1'>성격</td>
|
|
||||||
<td colspan=2>
|
|
||||||
<select id="selChar" name=character size=1 maxlength=15 style=color:white;background-color:black;>
|
|
||||||
<option selected value='Random'>????</option>
|
|
||||||
<?php foreach(GameConst::$availablePersonality as $personalityID): ?>
|
|
||||||
<?php $personalityName = buildPersonalityClass($personalityID)->getName(); ?>
|
|
||||||
<option value='<?=$personalityID?>'><?=$personalityName?></option>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
</select> <span id="charInfoText"></span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td width=498 align=right class='bg1'>통솔</td>
|
|
||||||
<td colspan=2><input type="number" name="leadership" id="leadership" value="50"></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td width=498 align=right class='bg1'>무력</td>
|
|
||||||
<td colspan=2><input type="number" name="strength" id="strength" value="50"></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td width=498 align=right class='bg1'>지력</td>
|
|
||||||
<td colspan=2><input type="number" name="intel" id="intel" value="50"></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td width=498 align=right class='bg1'>능력치 조정</td>
|
|
||||||
<td colspan=2>
|
|
||||||
<input type=button value=랜덤형 onclick=abilityRand()>
|
|
||||||
<input type=button value=통솔무력형 onclick=abilityLeadpow()>
|
|
||||||
<input type=button value=통솔지력형 onclick=abilityLeadint()>
|
|
||||||
<input type=button value=무력지력형 onclick=abilityPowint()>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align=center colspan=3>
|
|
||||||
<font color=orange>모든 능력치는 ( <?=GameConst::$defaultStatMin?> <= 능력치 <= <?=GameConst::$defaultStatMax?> ) 사이로 잡으셔야 합니다.<br>
|
|
||||||
그 외의 능력치는 가입되지 않습니다.</font>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align=center colspan=3>
|
|
||||||
능력치의 총합은 <?=GameConst::$defaultStatTotal?>입니다. 가입후 0~10의 능력치 보너스를 받게 됩니다.<br>
|
|
||||||
임의의 도시에서 재야로 시작하며 건국과 임관은 게임 내에서 실행합니다.
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td width=498 align=right><input type=submit name=join value=장수생성></td>
|
|
||||||
<td colspan=2><input type=reset name=reset value=다시입력></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</form>
|
|
||||||
<table align=center width=1000 class='tb_layout bg0'>
|
|
||||||
<tr><td><?=backButton()?></td></tr>
|
|
||||||
<tr><td><?=banner()?> </td></tr>
|
|
||||||
</table>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,341 +0,0 @@
|
|||||||
<?php
|
|
||||||
namespace sammo;
|
|
||||||
|
|
||||||
include "lib.php";
|
|
||||||
include "func.php";
|
|
||||||
|
|
||||||
$v = new Validator($_POST);
|
|
||||||
$v
|
|
||||||
->rule('required', [
|
|
||||||
'name',
|
|
||||||
'leadership',
|
|
||||||
'strength',
|
|
||||||
'intel'
|
|
||||||
])
|
|
||||||
->rule('integer', [
|
|
||||||
'leadership',
|
|
||||||
'strength',
|
|
||||||
'intel',
|
|
||||||
])
|
|
||||||
->rule('stringWidthBetween', 'name', 1, 18)
|
|
||||||
->rule('min', [
|
|
||||||
'leadership',
|
|
||||||
'strength',
|
|
||||||
'intel'
|
|
||||||
], GameConst::$defaultStatMin)
|
|
||||||
->rule('max', [
|
|
||||||
'leadership',
|
|
||||||
'strength',
|
|
||||||
'intel'
|
|
||||||
], GameConst::$defaultStatMax)
|
|
||||||
->rule('in', 'character', array_merge(GameConst::$availablePersonality, ['Random']));
|
|
||||||
|
|
||||||
if (!$v->validate()) {
|
|
||||||
MessageBox($v->errorStr());
|
|
||||||
echo "<script>history.go(-1);</script>";
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
$session = Session::requireLogin()->setReadOnly();
|
|
||||||
$userID = Session::getUserID();
|
|
||||||
//NOTE: 이 페이지에서는 세션에 데이터를 등록하지 않음. 로그인은 이후에.
|
|
||||||
|
|
||||||
$name = Util::getPost('name');
|
|
||||||
$name = htmlspecialchars($name);
|
|
||||||
$name = StringUtil::removeSpecialCharacter($name);
|
|
||||||
$name = WebUtil::htmlPurify($name);
|
|
||||||
$name = StringUtil::textStrip($name);
|
|
||||||
$pic = (int)Util::getPost('pic', 'bool', 0);
|
|
||||||
$character = Util::getPost('character');
|
|
||||||
|
|
||||||
$leadership = Util::getPost('leadership', 'int', 50);
|
|
||||||
$strength = Util::getPost('strength', 'int', 50);
|
|
||||||
$intel = Util::getPost('intel', 'int', 50);
|
|
||||||
|
|
||||||
$join = Util::getPost('join'); //쓸모 없음
|
|
||||||
|
|
||||||
$rootDB = RootDB::db();
|
|
||||||
//회원 테이블에서 정보확인
|
|
||||||
$member = $rootDB->queryFirstRow('SELECT `no`, id, picture, grade, `name`, imgsvr FROM member WHERE no=%i', $userID);
|
|
||||||
|
|
||||||
if (!$member) {
|
|
||||||
MessageBox("잘못된 접근입니다!!!");
|
|
||||||
echo "<script>history.go(-1);</script>";
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
$db = DB::db();
|
|
||||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
|
||||||
$gameStor->cacheValues(['year','month','maxgeneral','scenario','show_img_level','turnterm','turntime','genius','npcmode']);
|
|
||||||
########## 동일 정보 존재여부 확인. ##########
|
|
||||||
|
|
||||||
$gencount = $db->queryFirstField('SELECT count(`no`) FROM general WHERE npc<2');
|
|
||||||
$oldGeneral = $db->queryFirstField('SELECT `no` FROM general WHERE `owner`=%i', $userID);
|
|
||||||
$oldName = $db->queryFirstField('SELECT `no` FROM general WHERE `name`=%s', $name);
|
|
||||||
|
|
||||||
if ($oldGeneral) {
|
|
||||||
echo("<script>
|
|
||||||
window.alert('이미 등록하셨습니다!')
|
|
||||||
history.go(-1)
|
|
||||||
</script>");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
if ($oldName) {
|
|
||||||
echo("<script>
|
|
||||||
window.alert('이미 있는 장수입니다. 다른 이름으로 등록해 주세요!')
|
|
||||||
history.go(-1)
|
|
||||||
</script>");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
if ($gameStor->maxgeneral <= $gencount) {
|
|
||||||
echo("<script>
|
|
||||||
window.alert('더이상 등록할 수 없습니다!')
|
|
||||||
history.go(-1)
|
|
||||||
</script>");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
if ($name == '') {
|
|
||||||
echo("<script>
|
|
||||||
window.alert('이름이 짧습니다. 다시 가입해주세요!')
|
|
||||||
history.go(-1)
|
|
||||||
</script>");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
if (mb_strwidth($name) > 18) {
|
|
||||||
echo("<script>
|
|
||||||
window.alert('이름이 유효하지 않습니다. 다시 가입해주세요!')
|
|
||||||
history.go(-1)
|
|
||||||
</script>");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
if ($leadership + $strength + $intel > GameConst::$defaultStatTotal) {
|
|
||||||
echo("<script>
|
|
||||||
window.alert('능력치가 ".GameConst::$defaultStatTotal."을 넘어섰습니다. 다시 가입해주세요!')
|
|
||||||
history.go(-1)
|
|
||||||
</script>");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
$genius = Util::randBool(0.01);
|
|
||||||
// 현재 1%
|
|
||||||
if ($genius && $gameStor->genius > 0) {
|
|
||||||
$gameStor->genius = $gameStor->genius-1;
|
|
||||||
} else {
|
|
||||||
$genius = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 공백지에서만 태어나게
|
|
||||||
$city = $db->queryFirstField("select city from city where level>=5 and level<=6 and nation=0 order by rand() limit 0,1");
|
|
||||||
if (!$city) {
|
|
||||||
$city = $db->queryFirstField("select city from city where level>=5 and level<=6 order by rand() limit 0,1");
|
|
||||||
}
|
|
||||||
|
|
||||||
$pleadership = 0;
|
|
||||||
$pstrength = 0;
|
|
||||||
$pintel = 0;
|
|
||||||
foreach(Util::range(Util::randRangeInt(3, 5)) as $statIdx){
|
|
||||||
switch (Util::choiceRandomUsingWeight([$leadership, $strength, $intel])) {
|
|
||||||
case 0:
|
|
||||||
$pleadership++;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
$pstrength++;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
$pintel++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$leadership = $leadership + $pleadership;
|
|
||||||
$strength = $strength + $pstrength;
|
|
||||||
$intel = $intel + $pintel;
|
|
||||||
|
|
||||||
$admin = $gameStor->getValues(['scenario', 'turnterm', 'turntime', 'show_img_level', 'startyear', 'year']);
|
|
||||||
$relYear = Util::valueFit($admin['year'] - $admin['startyear'], 0);
|
|
||||||
|
|
||||||
$age = 20 + ($pleadership + $pstrength + $pintel) * 2 - (mt_rand(0, 1));
|
|
||||||
// 아직 남았고 천재등록상태이면 특기 부여
|
|
||||||
if ($genius) {
|
|
||||||
$specage2 = $age;
|
|
||||||
$special2 = SpecialityHelper::pickSpecialWar([
|
|
||||||
'leadership'=>$leadership,
|
|
||||||
'strength'=>$strength,
|
|
||||||
'intel'=>$intel,
|
|
||||||
'dex1'=>0,
|
|
||||||
'dex2'=>0,
|
|
||||||
'dex3'=>0,
|
|
||||||
'dex4'=>0,
|
|
||||||
'dex5'=>0
|
|
||||||
]);
|
|
||||||
} else {
|
|
||||||
$specage2 = Util::valueFit(Util::round((GameConst::$retirementYear - $age)/6 - $relYear / 2), 3) + $age;
|
|
||||||
$special2 = GameConst::$defaultSpecialWar;
|
|
||||||
}
|
|
||||||
//내특
|
|
||||||
$specage = Util::valueFit(Util::round((GameConst::$retirementYear - $age)/12 - $relYear / 2), 3) + $age;
|
|
||||||
$special = GameConst::$defaultSpecialDomestic;
|
|
||||||
|
|
||||||
if ($admin['scenario'] >= 1000) {
|
|
||||||
$specage2 = $age + 3;
|
|
||||||
$specage = $age + 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
if($relYear < 3){
|
|
||||||
$experience = 0;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
$expGenCount = $db->queryFirstField('SELECT count(*) FROM general WHERE nation != 0 AND npc < 4');
|
|
||||||
$targetGenOrder = Util::round($expGenCount * 0.2);
|
|
||||||
$experience = $db->queryFirstField(
|
|
||||||
'SELECT experience FROM general WHERE nation != 0 AND npc < 4 ORDER BY experience ASC LIMIT %i, 1',
|
|
||||||
$targetGenOrder - 1
|
|
||||||
);
|
|
||||||
$experience *= 0.8;
|
|
||||||
}
|
|
||||||
|
|
||||||
$turntime = getRandTurn($admin['turnterm'], new \DateTimeImmutable($admin['turntime']));
|
|
||||||
|
|
||||||
$now = date('Y-m-d H:i:s');
|
|
||||||
if ($now >= $turntime) {
|
|
||||||
$turntime = addTurn($turntime, $admin['turnterm']);
|
|
||||||
}
|
|
||||||
|
|
||||||
//특회 전콘
|
|
||||||
if ($admin['show_img_level'] >= 1 && $member['grade'] >= 1 && $member['picture'] != "" && $pic) {
|
|
||||||
$face = $member['picture'];
|
|
||||||
$imgsvr = $member['imgsvr'];
|
|
||||||
} else {
|
|
||||||
$face = "default.jpg";
|
|
||||||
$imgsvr = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//성격 랜덤시
|
|
||||||
if (!in_array($character, GameConst::$availablePersonality)){
|
|
||||||
$character = Util::choiceRandom(GameConst::$availablePersonality);
|
|
||||||
}
|
|
||||||
//상성 랜덤
|
|
||||||
$affinity = rand()%150 + 1;
|
|
||||||
|
|
||||||
########## 회원정보 테이블에 입력값을 등록한다. ##########
|
|
||||||
$db->insert('general', [
|
|
||||||
'owner' => $userID,
|
|
||||||
'name' => $name,
|
|
||||||
'owner_name' => $member['name'],
|
|
||||||
'picture' => $face,
|
|
||||||
'imgsvr' => $imgsvr,
|
|
||||||
'nation' => 0,
|
|
||||||
'city' => $city,
|
|
||||||
'troop' => 0,
|
|
||||||
'affinity' => $affinity,
|
|
||||||
'leadership' => $leadership,
|
|
||||||
'strength' => $strength,
|
|
||||||
'intel' => $intel,
|
|
||||||
'experience' => $experience,
|
|
||||||
'dedication' => 0,
|
|
||||||
'gold' => GameConst::$defaultGold,
|
|
||||||
'rice' => GameConst::$defaultRice,
|
|
||||||
'crew' => 0,
|
|
||||||
'train' => 0,
|
|
||||||
'atmos' => 0,
|
|
||||||
'officer_level' => 0,
|
|
||||||
'turntime' => $turntime,
|
|
||||||
'killturn' => 6,
|
|
||||||
'lastconnect' => $now,
|
|
||||||
'lastrefresh' => $now,
|
|
||||||
'crewtype'=>GameUnitConst::DEFAULT_CREWTYPE,
|
|
||||||
'makelimit' => 0,
|
|
||||||
'age' => $age,
|
|
||||||
'startage' => $age,
|
|
||||||
'personal' => $character,
|
|
||||||
'specage' => $specage,
|
|
||||||
'special' => $special,
|
|
||||||
'specage2' => $specage2,
|
|
||||||
'special2' => $special2
|
|
||||||
]);
|
|
||||||
$generalID = $db->insertId();
|
|
||||||
$turnRows = [];
|
|
||||||
foreach(Util::range(GameConst::$maxTurn) as $turnIdx){
|
|
||||||
$turnRows[] = [
|
|
||||||
'general_id'=>$generalID,
|
|
||||||
'turn_idx'=>$turnIdx,
|
|
||||||
'action'=>'휴식',
|
|
||||||
'arg'=>null,
|
|
||||||
'brief'=>'휴식'
|
|
||||||
];
|
|
||||||
}
|
|
||||||
$db->insert('general_turn', $turnRows);
|
|
||||||
|
|
||||||
resetInheritanceUser($userID);
|
|
||||||
|
|
||||||
$rank_data = [];
|
|
||||||
foreach(array_keys(General::RANK_COLUMN) as $rankColumn){
|
|
||||||
$rank_data[] = [
|
|
||||||
'general_id'=>$generalID,
|
|
||||||
'nation_id'=>0,
|
|
||||||
'type'=>$rankColumn,
|
|
||||||
'value'=>0
|
|
||||||
];
|
|
||||||
}
|
|
||||||
$db->insert('rank_data', $rank_data);
|
|
||||||
$db->insert('betting', [
|
|
||||||
'general_id'=>$generalID,
|
|
||||||
]);
|
|
||||||
$cityname = CityConst::byID($city)->name;
|
|
||||||
|
|
||||||
$me = [
|
|
||||||
'no'=>$generalID
|
|
||||||
];
|
|
||||||
|
|
||||||
$log = [];
|
|
||||||
$mylog = [];
|
|
||||||
|
|
||||||
$logger = new ActionLogger($generalID, 0, $gameStor->year, $gameStor->month);
|
|
||||||
|
|
||||||
$josaRa = JosaUtil::pick($name, '라');
|
|
||||||
$speicalText = getGeneralSpecialWarName($special2);
|
|
||||||
if ($genius) {
|
|
||||||
|
|
||||||
$logger->pushGlobalActionLog("<G><b>{$cityname}</b></>에서 <Y>{$name}</>{$josaRa}는 기재가 천하에 이름을 알립니다.");
|
|
||||||
$logger->pushGlobalActionLog("<C>{$speicalText}</> 특기를 가진 <C>천재</>의 등장으로 온 천하가 떠들썩합니다.");
|
|
||||||
$logger->pushGlobalHistoryLog("<L><b>【천재】</b></><G><b>{$cityname}</b></>에 천재가 등장했습니다.");
|
|
||||||
} else {
|
|
||||||
$logger->pushGlobalActionLog("<G><b>{$cityname}</b></>에서 <Y>{$name}</>{$josaRa}는 호걸이 천하에 이름을 알립니다.");
|
|
||||||
}
|
|
||||||
|
|
||||||
$logger->pushGeneralHistoryLog("<Y>{$name}</>, <G>{$cityname}</>에서 큰 뜻을 품다.");
|
|
||||||
$logger->pushGeneralActionLog("삼국지 모의전투 PHP의 세계에 오신 것을 환영합니다 ^o^", ActionLogger::PLAIN);
|
|
||||||
$logger->pushGeneralActionLog("처음 하시는 경우에는 <D>도움말</>을 참고하시고,", ActionLogger::PLAIN);
|
|
||||||
$logger->pushGeneralActionLog("문의사항이 있으시면 게시판에 글을 남겨주시면 되겠네요~", ActionLogger::PLAIN);
|
|
||||||
$logger->pushGeneralActionLog("부디 즐거운 삼모전 되시길 바랍니다 ^^", ActionLogger::PLAIN);
|
|
||||||
$logger->pushGeneralActionLog("통솔 <C>$pleadership</> 무력 <C>$pstrength</> 지력 <C>$pintel</> 의 보너스를 받으셨습니다.", ActionLogger::PLAIN);
|
|
||||||
$logger->pushGeneralActionLog("연령은 <C>$age</>세로 시작합니다.", ActionLogger::PLAIN);
|
|
||||||
|
|
||||||
if ($genius) {
|
|
||||||
$logger->pushGeneralActionLog("축하합니다! 천재로 태어나 처음부터 <C>{$speicalText}</> 특기를 가지게 됩니다!", ActionLogger::PLAIN);
|
|
||||||
$logger->pushGeneralHistoryLog("<C>{$speicalText}</> 특기를 가진 천재로 탄생.");
|
|
||||||
}
|
|
||||||
|
|
||||||
$logger->flush();
|
|
||||||
|
|
||||||
pushAdminLog(["가입 : {$userID} // {$name} // {$generalID}".getenv("REMOTE_ADDR")]);
|
|
||||||
|
|
||||||
$rootDB->insert('member_log', [
|
|
||||||
'member_no' => $userID,
|
|
||||||
'date'=>TimeUtil::now(),
|
|
||||||
'action_type'=>'make_general',
|
|
||||||
'action'=>Json::encode([
|
|
||||||
'server'=>DB::prefix(),
|
|
||||||
'type'=>'general',
|
|
||||||
'generalID'=>$generalID,
|
|
||||||
'generalName'=>$name
|
|
||||||
])
|
|
||||||
]);
|
|
||||||
|
|
||||||
?>
|
|
||||||
<script>
|
|
||||||
window.alert('정상적으로 회원 가입되었습니다. 장수명 : <?=$name?> \n위키와 팁/강좌 게시판을 꼭 읽어보세요!');
|
|
||||||
</script>
|
|
||||||
<script>location.replace('./');</script>
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,431 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace sammo\API\General;
|
||||||
|
|
||||||
|
use sammo\ActionLogger;
|
||||||
|
use sammo\CityConst;
|
||||||
|
use sammo\DB;
|
||||||
|
use sammo\GameConst;
|
||||||
|
use sammo\GameUnitConst;
|
||||||
|
use sammo\General;
|
||||||
|
use sammo\JosaUtil;
|
||||||
|
use sammo\Json;
|
||||||
|
use sammo\KVStorage;
|
||||||
|
use sammo\RootDB;
|
||||||
|
use sammo\Session;
|
||||||
|
use sammo\SpecialityHelper;
|
||||||
|
use sammo\StringUtil;
|
||||||
|
use sammo\TimeUtil;
|
||||||
|
use sammo\Util;
|
||||||
|
use sammo\Validator;
|
||||||
|
use sammo\WebUtil;
|
||||||
|
|
||||||
|
use function sammo\addTurn;
|
||||||
|
use function sammo\cutTurn;
|
||||||
|
use function sammo\getGeneralSpecialWarName;
|
||||||
|
use function sammo\getRandTurn;
|
||||||
|
use function sammo\pushAdminLog;
|
||||||
|
use function sammo\resetInheritanceUser;
|
||||||
|
|
||||||
|
class Join extends \sammo\BaseAPI
|
||||||
|
{
|
||||||
|
public function validateArgs(): ?string
|
||||||
|
{
|
||||||
|
$v = new Validator($this->args);
|
||||||
|
$v
|
||||||
|
->rule('required', [
|
||||||
|
'name',
|
||||||
|
'leadership',
|
||||||
|
'strength',
|
||||||
|
'intel',
|
||||||
|
'pic',
|
||||||
|
'character',
|
||||||
|
])
|
||||||
|
->rule('integer', [
|
||||||
|
'leadership',
|
||||||
|
'strength',
|
||||||
|
'intel',
|
||||||
|
'inheritTurntime',
|
||||||
|
])
|
||||||
|
->rule('boolean', [
|
||||||
|
'pic'
|
||||||
|
])
|
||||||
|
->rule('stringWidthBetween', 'name', 1, 18)
|
||||||
|
->rule('min', [
|
||||||
|
'leadership',
|
||||||
|
'strength',
|
||||||
|
'intel'
|
||||||
|
], GameConst::$defaultStatMin)
|
||||||
|
->rule('max', [
|
||||||
|
'leadership',
|
||||||
|
'strength',
|
||||||
|
'intel'
|
||||||
|
], GameConst::$defaultStatMax)
|
||||||
|
->rule('in', 'character', array_merge(GameConst::$availablePersonality, ['Random']))
|
||||||
|
->rule('in', 'inheritSpecial', GameConst::$availableSpecialWar)
|
||||||
|
->rule('min', 'inheritTurntime', 0)
|
||||||
|
->rule('in', 'inheritCity', array_keys(CityConst::all()))
|
||||||
|
->rule('integerArray', 'inheritBonusStat');
|
||||||
|
|
||||||
|
if (!$v->validate()) {
|
||||||
|
return $v->errorStr();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRequiredSessionMode(): int
|
||||||
|
{
|
||||||
|
return static::REQ_LOGIN | static::REQ_READ_ONLY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function launch(Session $session, ?\DateTimeInterface $modifiedSince, ?string $reqEtag)
|
||||||
|
{
|
||||||
|
$userID = $session->userID;
|
||||||
|
|
||||||
|
$name = $this->args['name'];
|
||||||
|
$name = htmlspecialchars($name);
|
||||||
|
$name = StringUtil::removeSpecialCharacter($name);
|
||||||
|
$name = WebUtil::htmlPurify($name);
|
||||||
|
$name = StringUtil::textStrip($name);
|
||||||
|
$pic = $this->args['pic'];
|
||||||
|
$character = $this->args['character'];
|
||||||
|
|
||||||
|
$leadership = $this->args['leadership'];
|
||||||
|
$strength = $this->args['strength'];
|
||||||
|
$intel = $this->args['intel'];
|
||||||
|
|
||||||
|
$inheritSpecial = $this->args['inheritSpecial'] ?? null;
|
||||||
|
$inheritTurntime = $this->args['inheritTurntime'] ?? null;
|
||||||
|
$inheritCity = $this->args['inheritCity'] ?? null;
|
||||||
|
$inheritBonusStat = $this->args['inheritBonusStat'] ?? null;
|
||||||
|
|
||||||
|
$rootDB = RootDB::db();
|
||||||
|
//회원 테이블에서 정보확인
|
||||||
|
$member = $rootDB->queryFirstRow('SELECT `no`, id, picture, grade, `name`, imgsvr FROM member WHERE no=%i', $userID);
|
||||||
|
|
||||||
|
if (!$member) {
|
||||||
|
return "잘못된 접근입니다!!!";
|
||||||
|
}
|
||||||
|
|
||||||
|
$db = DB::db();
|
||||||
|
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||||
|
$gameStor->cacheValues(['year', 'month', 'maxgeneral', 'scenario', 'show_img_level', 'turnterm', 'turntime', 'genius', 'npcmode']);
|
||||||
|
########## 동일 정보 존재여부 확인. ##########
|
||||||
|
|
||||||
|
$gencount = $db->queryFirstField('SELECT count(`no`) FROM general WHERE npc<2');
|
||||||
|
$oldGeneral = $db->queryFirstField('SELECT `no` FROM general WHERE `owner`=%i', $userID);
|
||||||
|
$oldName = $db->queryFirstField('SELECT `no` FROM general WHERE `name`=%s', $name);
|
||||||
|
|
||||||
|
if ($oldGeneral) {
|
||||||
|
return "이미 등록하셨습니다!";
|
||||||
|
}
|
||||||
|
if ($oldName) {
|
||||||
|
return "이미 있는 장수입니다. 다른 이름으로 등록해 주세요!";
|
||||||
|
}
|
||||||
|
if ($gameStor->maxgeneral <= $gencount) {
|
||||||
|
return "더이상 등록할 수 없습니다!";
|
||||||
|
}
|
||||||
|
if ($name == '') {
|
||||||
|
return "이름이 짧습니다. 다시 가입해주세요!";
|
||||||
|
}
|
||||||
|
if (mb_strwidth($name) > 18) {
|
||||||
|
return "이름이 유효하지 않습니다. 다시 가입해주세요!";
|
||||||
|
}
|
||||||
|
if ($leadership + $strength + $intel > GameConst::$defaultStatTotal) {
|
||||||
|
return "능력치가 " . GameConst::$defaultStatTotal . "을 넘어섰습니다. 다시 가입해주세요!";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($inheritBonusStat) {
|
||||||
|
if (count($inheritBonusStat) != 3) {
|
||||||
|
return "보너스 능력치가 잘못 지정되었습니다. 다시 가입해주세요!";
|
||||||
|
}
|
||||||
|
foreach ($inheritBonusStat as $stat) {
|
||||||
|
if ($stat < 0) {
|
||||||
|
return "보너스 능력치가 음수입니다. 다시 가입해주세요!";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$sum = array_sum($inheritBonusStat);
|
||||||
|
if ($sum == 0) {
|
||||||
|
$inheritBonusStat = null;
|
||||||
|
} else if ($sum < 3 || $sum > 5) {
|
||||||
|
return "보너스 능력치 합이 잘못 지정되었습니다. 다시 가입해주세요!";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$admin = $gameStor->getValues(['scenario', 'turnterm', 'turntime', 'show_img_level', 'startyear', 'year']);
|
||||||
|
|
||||||
|
$inheritTotalPoint = resetInheritanceUser($userID);
|
||||||
|
$inheritRequiredPoint = 0;
|
||||||
|
|
||||||
|
if ($inheritCity !== null) {
|
||||||
|
$inheritRequiredPoint += GameConst::$inheritBornCityPoint;
|
||||||
|
}
|
||||||
|
if ($inheritBonusStat !== null) {
|
||||||
|
$inheritRequiredPoint += GameConst::$inheritBornStatPoint;
|
||||||
|
}
|
||||||
|
if ($inheritSpecial !== null) {
|
||||||
|
$inheritRequiredPoint += GameConst::$inheritBornSpecialPoint;
|
||||||
|
}
|
||||||
|
if ($inheritTurntime !== null) {
|
||||||
|
$inheritRequiredPoint += GameConst::$inheritBornTurntimePoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($inheritTotalPoint < $inheritRequiredPoint) {
|
||||||
|
return "유산 포인트가 부족합니다. 다시 가입해주세요!";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($inheritSpecial !== null && $gameStor->genius == 0) {
|
||||||
|
return "이미 천재가 모두 나타났습니다. 다시 가입해주세요!";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($inheritCity !== null && !key_exists($inheritCity, CityConst::all())) {
|
||||||
|
return "도시가 잘못 지정되었습니다. 다시 가입해주세요!";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($inheritSpecial) {
|
||||||
|
$genius = true;
|
||||||
|
} else {
|
||||||
|
// 현재 1%
|
||||||
|
$genius = Util::randBool(0.01);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($genius && $gameStor->genius > 0) {
|
||||||
|
$gameStor->genius = $gameStor->genius - 1;
|
||||||
|
} else {
|
||||||
|
$genius = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($inheritCity !== null) {
|
||||||
|
$city = $inheritCity;
|
||||||
|
} else {
|
||||||
|
// 공백지에서만 태어나게
|
||||||
|
$city = $db->queryFirstField("select city from city where level>=5 and level<=6 and nation=0 order by rand() limit 0,1");
|
||||||
|
if (!$city) {
|
||||||
|
$city = $db->queryFirstField("select city from city where level>=5 and level<=6 order by rand() limit 0,1");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($inheritBonusStat) {
|
||||||
|
[$pleadership, $pstrength, $pintel] = $inheritBonusStat;
|
||||||
|
} else {
|
||||||
|
$pleadership = 0;
|
||||||
|
$pstrength = 0;
|
||||||
|
$pintel = 0;
|
||||||
|
foreach (Util::range(Util::randRangeInt(3, 5)) as $statIdx) {
|
||||||
|
switch (Util::choiceRandomUsingWeight([$leadership, $strength, $intel])) {
|
||||||
|
case 0:
|
||||||
|
$pleadership++;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
$pstrength++;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
$pintel++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$leadership = $leadership + $pleadership;
|
||||||
|
$strength = $strength + $pstrength;
|
||||||
|
$intel = $intel + $pintel;
|
||||||
|
|
||||||
|
$relYear = Util::valueFit($admin['year'] - $admin['startyear'], 0);
|
||||||
|
|
||||||
|
$age = 20 + ($pleadership + $pstrength + $pintel) * 2 - (mt_rand(0, 1));
|
||||||
|
// 아직 남았고 천재등록상태이면 특기 부여
|
||||||
|
if ($genius) {
|
||||||
|
$specage2 = $age;
|
||||||
|
if ($inheritSpecial) {
|
||||||
|
$special2 = $inheritSpecial;
|
||||||
|
} else {
|
||||||
|
$special2 = SpecialityHelper::pickSpecialWar([
|
||||||
|
'leadership' => $leadership,
|
||||||
|
'strength' => $strength,
|
||||||
|
'intel' => $intel,
|
||||||
|
'dex1' => 0,
|
||||||
|
'dex2' => 0,
|
||||||
|
'dex3' => 0,
|
||||||
|
'dex4' => 0,
|
||||||
|
'dex5' => 0
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$specage2 = Util::valueFit(Util::round((GameConst::$retirementYear - $age) / 6 - $relYear / 2), 3) + $age;
|
||||||
|
$special2 = GameConst::$defaultSpecialWar;
|
||||||
|
}
|
||||||
|
//내특
|
||||||
|
$specage = Util::valueFit(Util::round((GameConst::$retirementYear - $age) / 12 - $relYear / 2), 3) + $age;
|
||||||
|
$special = GameConst::$defaultSpecialDomestic;
|
||||||
|
|
||||||
|
if ($admin['scenario'] >= 1000) {
|
||||||
|
$specage2 = $age + 3;
|
||||||
|
$specage = $age + 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($relYear < 3) {
|
||||||
|
$experience = 0;
|
||||||
|
} else {
|
||||||
|
$expGenCount = $db->queryFirstField('SELECT count(*) FROM general WHERE nation != 0 AND npc < 4');
|
||||||
|
$targetGenOrder = Util::round($expGenCount * 0.2);
|
||||||
|
$experience = $db->queryFirstField(
|
||||||
|
'SELECT experience FROM general WHERE nation != 0 AND npc < 4 ORDER BY experience ASC LIMIT %i, 1',
|
||||||
|
$targetGenOrder - 1
|
||||||
|
);
|
||||||
|
$experience *= 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($inheritTurntime !== null) {
|
||||||
|
//FIXME: 오동작함
|
||||||
|
$inheritTurntime = $inheritTurntime % ($admin['turnterm'] * 60);
|
||||||
|
$inheritTurntime += Util::randRangeInt(0, 999999) / 1000000;
|
||||||
|
$turntime = new \DateTimeImmutable(cutTurn($admin['turntime'], $admin['turnterm']));
|
||||||
|
$turntime = $turntime->add(TimeUtil::secondsToDateInterval($inheritTurntime));
|
||||||
|
$turntime = TimeUtil::format($turntime, true);
|
||||||
|
} else {
|
||||||
|
$turntime = getRandTurn($admin['turnterm'], new \DateTimeImmutable($admin['turntime']));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$now = TimeUtil::now(true);
|
||||||
|
if ($now >= $turntime) {
|
||||||
|
$turntime = addTurn($turntime, $admin['turnterm']);
|
||||||
|
}
|
||||||
|
|
||||||
|
//특회 전콘
|
||||||
|
if ($admin['show_img_level'] >= 1 && $member['grade'] >= 1 && $member['picture'] != "" && $pic) {
|
||||||
|
$face = $member['picture'];
|
||||||
|
$imgsvr = $member['imgsvr'];
|
||||||
|
} else {
|
||||||
|
$face = "default.jpg";
|
||||||
|
$imgsvr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//성격 랜덤시
|
||||||
|
if (!in_array($character, GameConst::$availablePersonality)) {
|
||||||
|
$character = Util::choiceRandom(GameConst::$availablePersonality);
|
||||||
|
}
|
||||||
|
//상성 랜덤
|
||||||
|
$affinity = rand() % 150 + 1;
|
||||||
|
|
||||||
|
########## 회원정보 테이블에 입력값을 등록한다. ##########
|
||||||
|
$db->insert('general', [
|
||||||
|
'owner' => $userID,
|
||||||
|
'name' => $name,
|
||||||
|
'owner_name' => $member['name'],
|
||||||
|
'picture' => $face,
|
||||||
|
'imgsvr' => $imgsvr,
|
||||||
|
'nation' => 0,
|
||||||
|
'city' => $city,
|
||||||
|
'troop' => 0,
|
||||||
|
'affinity' => $affinity,
|
||||||
|
'leadership' => $leadership,
|
||||||
|
'strength' => $strength,
|
||||||
|
'intel' => $intel,
|
||||||
|
'experience' => $experience,
|
||||||
|
'dedication' => 0,
|
||||||
|
'gold' => GameConst::$defaultGold,
|
||||||
|
'rice' => GameConst::$defaultRice,
|
||||||
|
'crew' => 0,
|
||||||
|
'train' => 0,
|
||||||
|
'atmos' => 0,
|
||||||
|
'officer_level' => 0,
|
||||||
|
'turntime' => $turntime,
|
||||||
|
'killturn' => 6,
|
||||||
|
'lastconnect' => $now,
|
||||||
|
'lastrefresh' => $now,
|
||||||
|
'crewtype' => GameUnitConst::DEFAULT_CREWTYPE,
|
||||||
|
'makelimit' => 0,
|
||||||
|
'age' => $age,
|
||||||
|
'startage' => $age,
|
||||||
|
'personal' => $character,
|
||||||
|
'specage' => $specage,
|
||||||
|
'special' => $special,
|
||||||
|
'specage2' => $specage2,
|
||||||
|
'special2' => $special2
|
||||||
|
]);
|
||||||
|
$generalID = $db->insertId();
|
||||||
|
$turnRows = [];
|
||||||
|
foreach (Util::range(GameConst::$maxTurn) as $turnIdx) {
|
||||||
|
$turnRows[] = [
|
||||||
|
'general_id' => $generalID,
|
||||||
|
'turn_idx' => $turnIdx,
|
||||||
|
'action' => '휴식',
|
||||||
|
'arg' => null,
|
||||||
|
'brief' => '휴식'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
$db->insert('general_turn', $turnRows);
|
||||||
|
|
||||||
|
$rank_data = [];
|
||||||
|
foreach (array_keys(General::RANK_COLUMN) as $rankColumn) {
|
||||||
|
$rank_data[] = [
|
||||||
|
'general_id' => $generalID,
|
||||||
|
'nation_id' => 0,
|
||||||
|
'type' => $rankColumn,
|
||||||
|
'value' => 0
|
||||||
|
];
|
||||||
|
}
|
||||||
|
$db->insert('rank_data', $rank_data);
|
||||||
|
$db->insert('betting', [
|
||||||
|
'general_id' => $generalID,
|
||||||
|
]);
|
||||||
|
$cityname = CityConst::byID($city)->name;
|
||||||
|
|
||||||
|
if ($inheritRequiredPoint > 0) {
|
||||||
|
$inheritStor = KVStorage::getStorage(DB::db(), "inheritance_{$userID}");
|
||||||
|
$inheritStor->setValue('previous', [$inheritTotalPoint - $inheritRequiredPoint, null]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$me = [
|
||||||
|
'no' => $generalID
|
||||||
|
];
|
||||||
|
|
||||||
|
$log = [];
|
||||||
|
$mylog = [];
|
||||||
|
|
||||||
|
$logger = new ActionLogger($generalID, 0, $gameStor->year, $gameStor->month);
|
||||||
|
|
||||||
|
$josaRa = JosaUtil::pick($name, '라');
|
||||||
|
$speicalText = getGeneralSpecialWarName($special2);
|
||||||
|
if ($genius) {
|
||||||
|
|
||||||
|
$logger->pushGlobalActionLog("<G><b>{$cityname}</b></>에서 <Y>{$name}</>{$josaRa}는 기재가 천하에 이름을 알립니다.");
|
||||||
|
$logger->pushGlobalActionLog("<C>{$speicalText}</> 특기를 가진 <C>천재</>의 등장으로 온 천하가 떠들썩합니다.");
|
||||||
|
$logger->pushGlobalHistoryLog("<L><b>【천재】</b></><G><b>{$cityname}</b></>에 천재가 등장했습니다.");
|
||||||
|
} else {
|
||||||
|
$logger->pushGlobalActionLog("<G><b>{$cityname}</b></>에서 <Y>{$name}</>{$josaRa}는 호걸이 천하에 이름을 알립니다.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$logger->pushGeneralHistoryLog("<Y>{$name}</>, <G>{$cityname}</>에서 큰 뜻을 품다.");
|
||||||
|
$logger->pushGeneralActionLog("삼국지 모의전투 PHP의 세계에 오신 것을 환영합니다 ^o^", ActionLogger::PLAIN);
|
||||||
|
$logger->pushGeneralActionLog("처음 하시는 경우에는 <D>도움말</>을 참고하시고,", ActionLogger::PLAIN);
|
||||||
|
$logger->pushGeneralActionLog("문의사항이 있으시면 게시판에 글을 남겨주시면 되겠네요~", ActionLogger::PLAIN);
|
||||||
|
$logger->pushGeneralActionLog("부디 즐거운 삼모전 되시길 바랍니다 ^^", ActionLogger::PLAIN);
|
||||||
|
$logger->pushGeneralActionLog("통솔 <C>$pleadership</> 무력 <C>$pstrength</> 지력 <C>$pintel</> 의 보너스를 받으셨습니다.", ActionLogger::PLAIN);
|
||||||
|
$logger->pushGeneralActionLog("연령은 <C>$age</>세로 시작합니다.", ActionLogger::PLAIN);
|
||||||
|
|
||||||
|
if ($genius) {
|
||||||
|
$logger->pushGeneralActionLog("축하합니다! 천재로 태어나 처음부터 <C>{$speicalText}</> 특기를 가지게 됩니다!", ActionLogger::PLAIN);
|
||||||
|
$logger->pushGeneralHistoryLog("<C>{$speicalText}</> 특기를 가진 천재로 탄생.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$logger->flush();
|
||||||
|
|
||||||
|
pushAdminLog(["가입 : {$userID} // {$name} // {$generalID}" . getenv("REMOTE_ADDR")]);
|
||||||
|
|
||||||
|
$rootDB->insert('member_log', [
|
||||||
|
'member_no' => $userID,
|
||||||
|
'date' => TimeUtil::now(),
|
||||||
|
'action_type' => 'make_general',
|
||||||
|
'action' => Json::encode([
|
||||||
|
'server' => DB::prefix(),
|
||||||
|
'type' => 'general',
|
||||||
|
'generalID' => $generalID,
|
||||||
|
'generalName' => $name
|
||||||
|
])
|
||||||
|
]);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace sammo\API\InheritAction;
|
||||||
|
|
||||||
|
use sammo\Session;
|
||||||
|
use DateTimeInterface;
|
||||||
|
use sammo\DB;
|
||||||
|
use sammo\GameConst;
|
||||||
|
use sammo\General;
|
||||||
|
use sammo\KVStorage;
|
||||||
|
use sammo\TimeUtil;
|
||||||
|
use sammo\TriggerInheritBuff;
|
||||||
|
use sammo\Validator;
|
||||||
|
|
||||||
|
class BuyHiddenBuff extends \sammo\BaseAPI
|
||||||
|
{
|
||||||
|
public function validateArgs(): ?string
|
||||||
|
{
|
||||||
|
$v = new Validator($this->args);
|
||||||
|
$v->rule('required', [
|
||||||
|
'type',
|
||||||
|
'level',
|
||||||
|
])
|
||||||
|
->rule('integer', 'level')
|
||||||
|
->rule('min', 'level', 1)
|
||||||
|
->rule('max', 'level', TriggerInheritBuff::MAX_STEP)
|
||||||
|
->rule('keyExists', 'type', TriggerInheritBuff::BUFF_KEY_TEXT);
|
||||||
|
|
||||||
|
if (!$v->validate()) {
|
||||||
|
return $v->errorStr();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRequiredSessionMode(): int
|
||||||
|
{
|
||||||
|
//General.aux 쓰므로 lock;
|
||||||
|
return static::REQ_GAME_LOGIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag)
|
||||||
|
{
|
||||||
|
$userID = $session->userID;
|
||||||
|
$generalID = $session->generalID;
|
||||||
|
|
||||||
|
$type = $this->args['type'];
|
||||||
|
$level = $this->args['level'];
|
||||||
|
|
||||||
|
$general = General::createGeneralObjFromDB($generalID);
|
||||||
|
if ($userID != $general->getVar('owner')) {
|
||||||
|
return '로그인 상태가 이상합니다. 다시 로그인해 주세요.';
|
||||||
|
}
|
||||||
|
|
||||||
|
$inheritBuffList = $general->getAuxVar('inheritBuff') ?? [];
|
||||||
|
$prevLevel = $inheritBuffList[$type] ?? 0;
|
||||||
|
|
||||||
|
if ($prevLevel == $level) {
|
||||||
|
return '이미 구입했습니다.';
|
||||||
|
}
|
||||||
|
if ($prevLevel > $level) {
|
||||||
|
return '이미 더 높은 등급을 구입했습니다.';
|
||||||
|
}
|
||||||
|
|
||||||
|
$reqAmount = GameConst::$inheritBuffPoints[$level] - GameConst::$inheritBuffPoints[$prevLevel];
|
||||||
|
|
||||||
|
$db = DB::db();
|
||||||
|
$inheritStor = KVStorage::getStorage($db, "inheritance_{$userID}");
|
||||||
|
$previousPoint = ($inheritStor->getValue('previous') ?? [0,0])[0];
|
||||||
|
if ($previousPoint < $reqAmount) {
|
||||||
|
return '충분한 유산 포인트를 가지고 있지 않습니다.';
|
||||||
|
}
|
||||||
|
|
||||||
|
$inheritBuffList[$type] = $level;
|
||||||
|
$general->setAuxVar('inheritBuff', $inheritBuffList);
|
||||||
|
$inheritStor->setValue('previous', [$previousPoint - $reqAmount, null]);
|
||||||
|
$general->applyDB($db);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace sammo\API\InheritAction;
|
||||||
|
|
||||||
|
use sammo\Session;
|
||||||
|
use DateTimeInterface;
|
||||||
|
use sammo\DB;
|
||||||
|
use sammo\GameConst;
|
||||||
|
use sammo\General;
|
||||||
|
use sammo\KVStorage;
|
||||||
|
use sammo\TimeUtil;
|
||||||
|
|
||||||
|
class BuyRandomUnique extends \sammo\BaseAPI
|
||||||
|
{
|
||||||
|
public function validateArgs(): ?string
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRequiredSessionMode(): int
|
||||||
|
{
|
||||||
|
//General.aux 쓰므로 lock;
|
||||||
|
return static::REQ_GAME_LOGIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag)
|
||||||
|
{
|
||||||
|
$userID = $session->userID;
|
||||||
|
$generalID = $session->generalID;
|
||||||
|
|
||||||
|
$general = General::createGeneralObjFromDB($generalID);
|
||||||
|
if($userID != $general->getVar('owner')){
|
||||||
|
return '로그인 상태가 이상합니다. 다시 로그인해 주세요.';
|
||||||
|
}
|
||||||
|
|
||||||
|
if($general->getAuxVar('inheritRandomUnique') !== null){
|
||||||
|
return '이미 구입 명령을 내렸습니다. 다음 턴까지 기다려주세요.';
|
||||||
|
}
|
||||||
|
|
||||||
|
$db = DB::db();
|
||||||
|
$inheritStor = KVStorage::getStorage($db, "inheritance_{$userID}");
|
||||||
|
$previousPoint = ($inheritStor->getValue('previous')??[0, 0])[0];
|
||||||
|
if($previousPoint < GameConst::$inheritItemRandomPoint){
|
||||||
|
return '충분한 유산 포인트를 가지고 있지 않습니다.';
|
||||||
|
}
|
||||||
|
|
||||||
|
$general->setAuxVar('inheritRandomUnique', TimeUtil::now());
|
||||||
|
$inheritStor->setValue('previous', [$previousPoint - GameConst::$inheritItemRandomPoint, null]);
|
||||||
|
$general->applyDB($db);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace sammo\API\InheritAction;
|
||||||
|
|
||||||
|
use sammo\Session;
|
||||||
|
use DateTimeInterface;
|
||||||
|
use sammo\DB;
|
||||||
|
use sammo\GameConst;
|
||||||
|
use sammo\General;
|
||||||
|
use sammo\KVStorage;
|
||||||
|
use sammo\Validator;
|
||||||
|
|
||||||
|
class BuySpecificUnique extends \sammo\BaseAPI
|
||||||
|
{
|
||||||
|
public function validateArgs(): ?string
|
||||||
|
{
|
||||||
|
foreach (GameConst::$allItems as $items) {
|
||||||
|
foreach ($items as $itemKey => $amount) {
|
||||||
|
if ($amount == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$availableItems[$itemKey] = $amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$v = new Validator($this->args);
|
||||||
|
$v->rule('required', [
|
||||||
|
'item',
|
||||||
|
'amount',
|
||||||
|
])
|
||||||
|
->rule('integer', 'amount')
|
||||||
|
->rule('min', 'amount', GameConst::$inheritItemUniqueMinPoint)
|
||||||
|
->rule('keyExists', 'item', $availableItems);
|
||||||
|
|
||||||
|
if (!$v->validate()) {
|
||||||
|
return $v->errorStr();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRequiredSessionMode(): int
|
||||||
|
{
|
||||||
|
//KVStrorage, General.aux 모두 쓰므로 lock;
|
||||||
|
return static::REQ_GAME_LOGIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag)
|
||||||
|
{
|
||||||
|
$itemKey = $this->args['item'];
|
||||||
|
$amount = $this->args['amount'];
|
||||||
|
|
||||||
|
$userID = $session->userID;
|
||||||
|
$generalID = $session->generalID;
|
||||||
|
|
||||||
|
$general = General::createGeneralObjFromDB($generalID);
|
||||||
|
if ($userID != $general->getVar('owner')) {
|
||||||
|
return '로그인 상태가 이상합니다. 다시 로그인해 주세요.';
|
||||||
|
}
|
||||||
|
|
||||||
|
$itemTrials = $general->getAuxVar('inheritUniqueTrial') ?? [];
|
||||||
|
if (key_exists($itemKey, $itemTrials)) {
|
||||||
|
return '이미 입찰한 아이템입니다. 다음 턴에 시도해 주세요.';
|
||||||
|
}
|
||||||
|
|
||||||
|
$db = DB::db();
|
||||||
|
$inheritStor = KVStorage::getStorage($db, "inheritance_{$userID}");
|
||||||
|
$trialStor = KVStorage::getStorage($db, "ut_{$itemKey}");
|
||||||
|
$previousPoint = ($inheritStor->getValue('previous') ?? [0, 0])[0];
|
||||||
|
if ($previousPoint < $amount) {
|
||||||
|
return '충분한 유산 포인트를 가지고 있지 않습니다.';
|
||||||
|
}
|
||||||
|
|
||||||
|
$itemTrials[$itemKey] = $amount;
|
||||||
|
$general->setAuxVar('inheritUniqueTrial', $itemTrials);
|
||||||
|
$inheritStor->setValue('previous', [$previousPoint - $amount, null]);
|
||||||
|
$trialStor->setValue("u{$userID}", [$userID, $generalID, $amount]);
|
||||||
|
$general->applyDB($db);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace sammo\API\InheritAction;
|
||||||
|
|
||||||
|
use sammo\Session;
|
||||||
|
use DateTimeInterface;
|
||||||
|
use sammo\DB;
|
||||||
|
use sammo\GameConst;
|
||||||
|
use sammo\General;
|
||||||
|
use sammo\KVStorage;
|
||||||
|
use sammo\Validator;
|
||||||
|
|
||||||
|
class ResetSpecialWar extends \sammo\BaseAPI
|
||||||
|
{
|
||||||
|
public function validateArgs(): ?string
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRequiredSessionMode(): int
|
||||||
|
{
|
||||||
|
//KVStrorage, General.aux 모두 쓰므로 lock;
|
||||||
|
return static::REQ_GAME_LOGIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag)
|
||||||
|
{
|
||||||
|
$userID = $session->userID;
|
||||||
|
$generalID = $session->generalID;
|
||||||
|
|
||||||
|
$general = General::createGeneralObjFromDB($generalID);
|
||||||
|
if ($userID != $general->getVar('owner')) {
|
||||||
|
return '로그인 상태가 이상합니다. 다시 로그인해 주세요.';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$currentSpecialWar = $general->getVar('special2');
|
||||||
|
if ($currentSpecialWar === null || $currentSpecialWar == 'None') {
|
||||||
|
return '이미 전투 특기가 공란입니다.';
|
||||||
|
}
|
||||||
|
|
||||||
|
$currentLevel = $general->getAuxVar('inheritResetSpecialWar') ?? -1;
|
||||||
|
$nextLevel = $currentLevel + 1;
|
||||||
|
while (count(GameConst::$inheritResetAttrPointBase) <= $nextLevel) {
|
||||||
|
$baseLen = count(GameConst::$inheritResetAttrPointBase);
|
||||||
|
GameConst::$inheritResetAttrPointBase[] = GameConst::$inheritResetAttrPointBase[$baseLen - 1] + GameConst::$inheritResetAttrPointBase[$baseLen - 2];
|
||||||
|
}
|
||||||
|
|
||||||
|
$reqPoint = GameConst::$inheritResetAttrPointBase[$nextLevel];
|
||||||
|
|
||||||
|
$db = DB::db();
|
||||||
|
$inheritStor = KVStorage::getStorage($db, "inheritance_{$userID}");
|
||||||
|
$previousPoint = ($inheritStor->getValue('previous') ?? [0, 0])[0];
|
||||||
|
if ($previousPoint < $reqPoint) {
|
||||||
|
return '충분한 유산 포인트를 가지고 있지 않습니다.';
|
||||||
|
}
|
||||||
|
|
||||||
|
$oldTypeKey = 'prev_types_special2';
|
||||||
|
$oldSpecialList = $general->getAuxVar($oldTypeKey) ?? [];
|
||||||
|
$oldSpecialList[] = $currentSpecialWar;
|
||||||
|
$general->setAuxVar($oldTypeKey, $oldSpecialList);
|
||||||
|
|
||||||
|
$general->setAuxVar('inheritResetSpecialWar', $nextLevel);
|
||||||
|
$general->setVar('special2', 'None');
|
||||||
|
$inheritStor->setValue('previous', [$previousPoint - $reqPoint, null]);
|
||||||
|
$general->applyDB($db);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace sammo\API\InheritAction;
|
||||||
|
|
||||||
|
use DateTimeImmutable;
|
||||||
|
use sammo\Session;
|
||||||
|
use DateTimeInterface;
|
||||||
|
use sammo\DB;
|
||||||
|
use sammo\GameConst;
|
||||||
|
use sammo\General;
|
||||||
|
use sammo\KVStorage;
|
||||||
|
use sammo\TimeUtil;
|
||||||
|
use sammo\Util;
|
||||||
|
|
||||||
|
class ResetTurnTime extends \sammo\BaseAPI
|
||||||
|
{
|
||||||
|
public function validateArgs(): ?string
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRequiredSessionMode(): int
|
||||||
|
{
|
||||||
|
//KVStrorage, General.aux 모두 쓰므로 lock;
|
||||||
|
return static::REQ_GAME_LOGIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag)
|
||||||
|
{
|
||||||
|
$userID = $session->userID;
|
||||||
|
$generalID = $session->generalID;
|
||||||
|
|
||||||
|
$general = General::createGeneralObjFromDB($generalID);
|
||||||
|
if ($userID != $general->getVar('owner')) {
|
||||||
|
return '로그인 상태가 이상합니다. 다시 로그인해 주세요.';
|
||||||
|
}
|
||||||
|
|
||||||
|
$currentLevel = $general->getAuxVar('inheritResetTurnTime') ?? -1;
|
||||||
|
$nextLevel = $currentLevel + 1;
|
||||||
|
while (count(GameConst::$inheritResetAttrPointBase) <= $nextLevel) {
|
||||||
|
$baseLen = count(GameConst::$inheritResetAttrPointBase);
|
||||||
|
GameConst::$inheritResetAttrPointBase[] = GameConst::$inheritResetAttrPointBase[$baseLen - 1] + GameConst::$inheritResetAttrPointBase[$baseLen - 2];
|
||||||
|
}
|
||||||
|
|
||||||
|
$reqPoint = GameConst::$inheritResetAttrPointBase[$nextLevel];
|
||||||
|
|
||||||
|
$db = DB::db();
|
||||||
|
$inheritStor = KVStorage::getStorage($db, "inheritance_{$userID}");
|
||||||
|
$previousPoint = ($inheritStor->getValue('previous') ?? [0, 0])[0];
|
||||||
|
if ($previousPoint < $reqPoint) {
|
||||||
|
return '충분한 유산 포인트를 가지고 있지 않습니다.';
|
||||||
|
}
|
||||||
|
|
||||||
|
$gameStor = new KVStorage($db, 'game_env');
|
||||||
|
[$turnTerm, $serverTurnTime] = $gameStor->getValuesAsArray(['turnterm', 'turntime']);
|
||||||
|
|
||||||
|
$currTurnTime = new DateTimeImmutable($general->getTurnTime());
|
||||||
|
$serverTurnTimeObj = new DateTimeImmutable($serverTurnTime);
|
||||||
|
|
||||||
|
$afterTurn = Util::randRange($turnTerm * -60 / 2, $turnTerm * 60 / 2);
|
||||||
|
|
||||||
|
$turnTime = $currTurnTime->add(TimeUtil::secondsToDateInterval($afterTurn));
|
||||||
|
if ($turnTime <= $serverTurnTimeObj && $serverTurnTimeObj <= $currTurnTime) {
|
||||||
|
$turnTime = $turnTime->add(TimeUtil::secondsToDateInterval($turnTerm * 60));
|
||||||
|
}
|
||||||
|
|
||||||
|
$general->setVar('turntime', TimeUtil::format($turnTime, true));
|
||||||
|
$general->setAuxVar('inheritResetTurnTime', $nextLevel);
|
||||||
|
$inheritStor->setValue('previous', [$previousPoint - $reqPoint, null]);
|
||||||
|
$general->applyDB($db);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace sammo\API\InheritAction;
|
||||||
|
|
||||||
|
use sammo\Session;
|
||||||
|
use DateTimeInterface;
|
||||||
|
use sammo\DB;
|
||||||
|
use sammo\GameConst;
|
||||||
|
use sammo\General;
|
||||||
|
use sammo\KVStorage;
|
||||||
|
use sammo\Validator;
|
||||||
|
|
||||||
|
class SetNextSpecialWar extends \sammo\BaseAPI
|
||||||
|
{
|
||||||
|
public function validateArgs(): ?string
|
||||||
|
{
|
||||||
|
$v = new Validator($this->args);
|
||||||
|
$v->rule('required', [
|
||||||
|
'type',
|
||||||
|
])
|
||||||
|
->rule('in', 'type', GameConst::$availableSpecialWar);
|
||||||
|
|
||||||
|
if (!$v->validate()) {
|
||||||
|
return $v->errorStr();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRequiredSessionMode(): int
|
||||||
|
{
|
||||||
|
//General.aux 쓰므로 lock;
|
||||||
|
return static::REQ_GAME_LOGIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag)
|
||||||
|
{
|
||||||
|
$userID = $session->userID;
|
||||||
|
$generalID = $session->generalID;
|
||||||
|
|
||||||
|
$type = $this->args['type'];
|
||||||
|
|
||||||
|
$general = General::createGeneralObjFromDB($generalID);
|
||||||
|
if ($userID != $general->getVar('owner')) {
|
||||||
|
return '로그인 상태가 이상합니다. 다시 로그인해 주세요.';
|
||||||
|
}
|
||||||
|
|
||||||
|
$inheritSpecificSpecialWar = $general->getAuxVar('inheritSpecificSpecialWar');
|
||||||
|
$currentSpecialWar = $general->getVar('special2');
|
||||||
|
|
||||||
|
if ($currentSpecialWar == $type) {
|
||||||
|
return '이미 그 특기를 보유하고 있습니다.';
|
||||||
|
}
|
||||||
|
if ($inheritSpecificSpecialWar == $type) {
|
||||||
|
return '이미 그 특기를 예약하였습니다.';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($inheritSpecificSpecialWar !== null) {
|
||||||
|
return '이미 예약한 특기가 있습니다.';
|
||||||
|
}
|
||||||
|
|
||||||
|
$reqAmount = GameConst::$inheritSpecificSpecialPoint;
|
||||||
|
|
||||||
|
$db = DB::db();
|
||||||
|
$inheritStor = KVStorage::getStorage($db, "inheritance_{$userID}");
|
||||||
|
$previousPoint = ($inheritStor->getValue('previous') ?? [0, 0])[0];
|
||||||
|
if ($previousPoint < $reqAmount) {
|
||||||
|
return '충분한 유산 포인트를 가지고 있지 않습니다.';
|
||||||
|
}
|
||||||
|
|
||||||
|
$general->setAuxVar('inheritSpecificSpecialWar', $type);
|
||||||
|
$inheritStor->setValue('previous', [$previousPoint - $reqAmount, null]);
|
||||||
|
$general->applyDB($db);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,9 +19,16 @@ class che_반계_백우선 extends \sammo\BaseItem{
|
|||||||
protected $cost = 200;
|
protected $cost = 200;
|
||||||
protected $consumable = false;
|
protected $consumable = false;
|
||||||
|
|
||||||
|
public function onCalcOpposeStat(General $general, string $statName, $value, $aux = null)
|
||||||
|
{
|
||||||
|
$debuff = [
|
||||||
|
'warMagicSuccessProb' => 0.1,
|
||||||
|
][$statName] ?? 0;
|
||||||
|
return $value - $debuff;
|
||||||
|
}
|
||||||
|
|
||||||
public function getBattlePhaseSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller{
|
public function getBattlePhaseSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller{
|
||||||
return new WarUnitTriggerCaller(
|
return new WarUnitTriggerCaller(
|
||||||
new WarActivateSkills($unit, BaseWarUnitTrigger::TYPE_ITEM +BaseWarUnitTrigger::TYPE_DEDUP_TYPE_BASE*301, false, '계략약화'),
|
|
||||||
new che_반계시도($unit, BaseWarUnitTrigger::TYPE_ITEM +BaseWarUnitTrigger::TYPE_DEDUP_TYPE_BASE*301),
|
new che_반계시도($unit, BaseWarUnitTrigger::TYPE_ITEM +BaseWarUnitTrigger::TYPE_DEDUP_TYPE_BASE*301),
|
||||||
new che_반계발동($unit)
|
new che_반계발동($unit)
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -19,9 +19,16 @@ class che_반계_파초선 extends \sammo\BaseItem{
|
|||||||
protected $cost = 200;
|
protected $cost = 200;
|
||||||
protected $consumable = false;
|
protected $consumable = false;
|
||||||
|
|
||||||
|
public function onCalcOpposeStat(General $general, string $statName, $value, $aux = null)
|
||||||
|
{
|
||||||
|
$debuff = [
|
||||||
|
'warMagicSuccessProb' => 0.1,
|
||||||
|
][$statName] ?? 0;
|
||||||
|
return $value - $debuff;
|
||||||
|
}
|
||||||
|
|
||||||
public function getBattlePhaseSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller{
|
public function getBattlePhaseSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller{
|
||||||
return new WarUnitTriggerCaller(
|
return new WarUnitTriggerCaller(
|
||||||
new WarActivateSkills($unit, BaseWarUnitTrigger::TYPE_ITEM +BaseWarUnitTrigger::TYPE_DEDUP_TYPE_BASE*302, false, '계략약화'),
|
|
||||||
new che_반계시도($unit, BaseWarUnitTrigger::TYPE_ITEM +BaseWarUnitTrigger::TYPE_DEDUP_TYPE_BASE*302),
|
new che_반계시도($unit, BaseWarUnitTrigger::TYPE_ITEM +BaseWarUnitTrigger::TYPE_DEDUP_TYPE_BASE*302),
|
||||||
new che_반계발동($unit)
|
new che_반계발동($unit)
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -18,9 +18,11 @@ class che_서적_07_논어 extends \sammo\BaseStatItem{
|
|||||||
$this->info .= "<br>[전투] 상대의 계략 성공 확률 -10%p";
|
$this->info .= "<br>[전투] 상대의 계략 성공 확률 -10%p";
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBattlePhaseSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller{
|
public function onCalcOpposeStat(General $general, string $statName, $value, $aux = null)
|
||||||
return new WarUnitTriggerCaller(
|
{
|
||||||
new WarActivateSkills($unit, BaseWarUnitTrigger::TYPE_ITEM+BaseWarUnitTrigger::TYPE_DEDUP_TYPE_BASE*207, false, '계략약화')
|
$debuff = [
|
||||||
);
|
'warMagicSuccessProb' => 0.1,
|
||||||
|
][$statName] ?? 0;
|
||||||
|
return $value - $debuff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -18,9 +18,11 @@ class che_서적_11_춘추전 extends \sammo\BaseStatItem{
|
|||||||
$this->info .= "<br>[전투] 상대의 계략 성공 확률 -10%p";
|
$this->info .= "<br>[전투] 상대의 계략 성공 확률 -10%p";
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBattlePhaseSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller{
|
public function onCalcOpposeStat(General $general, string $statName, $value, $aux = null)
|
||||||
return new WarUnitTriggerCaller(
|
{
|
||||||
new WarActivateSkills($unit, BaseWarUnitTrigger::TYPE_ITEM+BaseWarUnitTrigger::TYPE_DEDUP_TYPE_BASE*211, false, '계략약화')
|
$debuff = [
|
||||||
);
|
'warMagicSuccessProb' => 0.1,
|
||||||
|
][$statName] ?? 0;
|
||||||
|
return $value - $debuff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace sammo\ActionItem;
|
namespace sammo\ActionItem;
|
||||||
|
|
||||||
use \sammo\iAction;
|
use \sammo\iAction;
|
||||||
use \sammo\General;
|
use \sammo\General;
|
||||||
use \sammo\GeneralTrigger;
|
use \sammo\GeneralTrigger;
|
||||||
@@ -17,7 +19,8 @@ use sammo\WarUnitTrigger\che_전멸시페이즈증가;
|
|||||||
use sammo\WarUnitTrigger\che_부상무효;
|
use sammo\WarUnitTrigger\che_부상무효;
|
||||||
use sammo\WarUnitTrigger\WarActivateSkills;
|
use sammo\WarUnitTrigger\WarActivateSkills;
|
||||||
|
|
||||||
class che_치트_HideD의_사인검 extends \sammo\BaseItem{
|
class che_치트_HideD의_사인검 extends \sammo\BaseItem
|
||||||
|
{
|
||||||
|
|
||||||
protected $rawName = 'HideD의 사인검';
|
protected $rawName = 'HideD의 사인검';
|
||||||
protected $name = 'HideD의 사인검(치트)';
|
protected $name = 'HideD의 사인검(치트)';
|
||||||
@@ -37,33 +40,45 @@ EOT;
|
|||||||
protected $consumable = false;
|
protected $consumable = false;
|
||||||
protected $buyable = false;
|
protected $buyable = false;
|
||||||
|
|
||||||
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float{
|
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux = null): float
|
||||||
if($turnType == '계략'){
|
{
|
||||||
if($varType == 'success') return $value + 2;
|
if ($turnType == '계략') {
|
||||||
|
if ($varType == 'success') return $value + 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $value;
|
return $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onCalcStat(General $general, string $statName, $value, $aux=null){
|
public function onCalcStat(General $general, string $statName, $value, $aux = null)
|
||||||
|
{
|
||||||
$bonus = [
|
$bonus = [
|
||||||
'bonusTrain'=>30,
|
'bonusTrain' => 30,
|
||||||
'bonusAtmos'=>30,
|
'bonusAtmos' => 30,
|
||||||
'leadership'=>100,
|
'leadership' => 100,
|
||||||
'strength'=>100,
|
'strength' => 100,
|
||||||
'intel'=>100,
|
'intel' => 100,
|
||||||
'warMagicSuccessProb'=>1,
|
'warMagicSuccessProb' => 1,
|
||||||
][$statName]??0;
|
][$statName] ?? 0;
|
||||||
return $bonus + $value;
|
return $bonus + $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPreTurnExecuteTriggerList(General $general):?GeneralTriggerCaller{
|
public function onCalcOpposeStat(General $general, string $statName, $value, $aux = null)
|
||||||
|
{
|
||||||
|
$debuff = [
|
||||||
|
'warMagicSuccessProb' => 0.1,
|
||||||
|
][$statName] ?? 0;
|
||||||
|
return $value - $debuff;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPreTurnExecuteTriggerList(General $general): ?GeneralTriggerCaller
|
||||||
|
{
|
||||||
return new GeneralTriggerCaller(
|
return new GeneralTriggerCaller(
|
||||||
new GeneralTrigger\che_도시치료($general)
|
new GeneralTrigger\che_도시치료($general)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBattleInitSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller{
|
public function getBattleInitSkillTriggerList(WarUnit $unit): ?WarUnitTriggerCaller
|
||||||
|
{
|
||||||
return new WarUnitTriggerCaller(
|
return new WarUnitTriggerCaller(
|
||||||
new che_부상무효($unit, BaseWarUnitTrigger::TYPE_NONE),
|
new che_부상무효($unit, BaseWarUnitTrigger::TYPE_NONE),
|
||||||
new WarActivateSkills($unit, BaseWarUnitTrigger::TYPE_NONE, false, '저격불가')
|
new WarActivateSkills($unit, BaseWarUnitTrigger::TYPE_NONE, false, '저격불가')
|
||||||
@@ -73,10 +88,10 @@ EOT;
|
|||||||
public function getBattlePhaseSkillTriggerList(\sammo\WarUnit $unit): ?WarUnitTriggerCaller
|
public function getBattlePhaseSkillTriggerList(\sammo\WarUnit $unit): ?WarUnitTriggerCaller
|
||||||
{
|
{
|
||||||
return new WarUnitTriggerCaller(
|
return new WarUnitTriggerCaller(
|
||||||
new WarActivateSkills($unit, BaseWarUnitTrigger::TYPE_NONE, false, '필살불가', '위압불가', '격노불가', '계략약화', '저격불가'),
|
new WarActivateSkills($unit, BaseWarUnitTrigger::TYPE_NONE, false, '필살불가', '위압불가', '격노불가', '저격불가'),
|
||||||
new che_전투치료시도($unit),
|
new che_전투치료시도($unit),
|
||||||
new che_전투치료발동($unit),
|
new che_전투치료발동($unit),
|
||||||
new che_저격시도($unit, che_저격시도::TYPE_NONE, 1/2, 20, 60),
|
new che_저격시도($unit, che_저격시도::TYPE_NONE, 1 / 2, 20, 60),
|
||||||
new che_저격발동($unit),
|
new che_저격발동($unit),
|
||||||
new che_격노시도($unit),
|
new che_격노시도($unit),
|
||||||
new che_격노발동($unit),
|
new che_격노발동($unit),
|
||||||
@@ -84,8 +99,8 @@ EOT;
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getWarPowerMultiplier(WarUnit $unit):array{
|
public function getWarPowerMultiplier(WarUnit $unit): array
|
||||||
|
{
|
||||||
return [1, 0.95];
|
return [1, 0.95];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -28,9 +28,16 @@ class event_전투특기_반계 extends \sammo\BaseItem{
|
|||||||
return $value;
|
return $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function onCalcOpposeStat(General $general, string $statName, $value, $aux = null)
|
||||||
|
{
|
||||||
|
$debuff = [
|
||||||
|
'warMagicSuccessProb' => 0.1,
|
||||||
|
][$statName] ?? 0;
|
||||||
|
return $value - $debuff;
|
||||||
|
}
|
||||||
|
|
||||||
public function getBattlePhaseSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller{
|
public function getBattlePhaseSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller{
|
||||||
return new WarUnitTriggerCaller(
|
return new WarUnitTriggerCaller(
|
||||||
new WarActivateSkills($unit, BaseWarUnitTrigger::TYPE_ITEM + BaseWarUnitTrigger::TYPE_DEDUP_TYPE_BASE*401, false, '계략약화'),
|
|
||||||
new che_반계시도($unit),
|
new che_반계시도($unit),
|
||||||
new che_반계발동($unit)
|
new che_반계발동($unit)
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -21,6 +21,14 @@ class che_event_견고 extends \sammo\BaseSpecial{
|
|||||||
SpecialityHelper::STAT_STRENGTH
|
SpecialityHelper::STAT_STRENGTH
|
||||||
];
|
];
|
||||||
|
|
||||||
|
public function onCalcOpposeStat(General $general, string $statName, $value, $aux = null)
|
||||||
|
{
|
||||||
|
$debuff = [
|
||||||
|
'warMagicSuccessProb' => 0.1,
|
||||||
|
][$statName] ?? 0;
|
||||||
|
return $value - $debuff;
|
||||||
|
}
|
||||||
|
|
||||||
public function getBattleInitSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller{
|
public function getBattleInitSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller{
|
||||||
return new WarUnitTriggerCaller(
|
return new WarUnitTriggerCaller(
|
||||||
new che_부상무효($unit, BaseWarUnitTrigger::TYPE_ITEM),
|
new che_부상무효($unit, BaseWarUnitTrigger::TYPE_ITEM),
|
||||||
@@ -30,7 +38,7 @@ class che_event_견고 extends \sammo\BaseSpecial{
|
|||||||
|
|
||||||
public function getBattlePhaseSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller{
|
public function getBattlePhaseSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller{
|
||||||
return new WarUnitTriggerCaller(
|
return new WarUnitTriggerCaller(
|
||||||
new WarActivateSkills($unit, BaseWarUnitTrigger::TYPE_ITEM + BaseWarUnitTrigger::TYPE_DEDUP_TYPE_BASE*402, false, '필살불가', '계략약화', '저격불가')
|
new WarActivateSkills($unit, BaseWarUnitTrigger::TYPE_ITEM + BaseWarUnitTrigger::TYPE_DEDUP_TYPE_BASE*402, false, '필살불가', '저격불가')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,10 +33,17 @@ class che_event_반계 extends \sammo\BaseSpecial
|
|||||||
return $value;
|
return $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function onCalcOpposeStat(General $general, string $statName, $value, $aux = null)
|
||||||
|
{
|
||||||
|
$debuff = [
|
||||||
|
'warMagicSuccessProb' => 0.1,
|
||||||
|
][$statName] ?? 0;
|
||||||
|
return $value - $debuff;
|
||||||
|
}
|
||||||
|
|
||||||
public function getBattlePhaseSkillTriggerList(WarUnit $unit): ?WarUnitTriggerCaller
|
public function getBattlePhaseSkillTriggerList(WarUnit $unit): ?WarUnitTriggerCaller
|
||||||
{
|
{
|
||||||
return new WarUnitTriggerCaller(
|
return new WarUnitTriggerCaller(
|
||||||
new WarActivateSkills($unit, BaseWarUnitTrigger::TYPE_ITEM + BaseWarUnitTrigger::TYPE_DEDUP_TYPE_BASE * 403, false, '계략약화'),
|
|
||||||
new che_반계시도($unit),
|
new che_반계시도($unit),
|
||||||
new che_반계발동($unit)
|
new che_반계발동($unit)
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -24,6 +24,14 @@ class che_견고 extends \sammo\BaseSpecial
|
|||||||
SpecialityHelper::STAT_STRENGTH
|
SpecialityHelper::STAT_STRENGTH
|
||||||
];
|
];
|
||||||
|
|
||||||
|
public function onCalcOpposeStat(General $general, string $statName, $value, $aux = null)
|
||||||
|
{
|
||||||
|
$debuff = [
|
||||||
|
'warMagicSuccessProb' => 0.1,
|
||||||
|
][$statName] ?? 0;
|
||||||
|
return $value - $debuff;
|
||||||
|
}
|
||||||
|
|
||||||
public function getBattleInitSkillTriggerList(WarUnit $unit): ?WarUnitTriggerCaller
|
public function getBattleInitSkillTriggerList(WarUnit $unit): ?WarUnitTriggerCaller
|
||||||
{
|
{
|
||||||
return new WarUnitTriggerCaller(
|
return new WarUnitTriggerCaller(
|
||||||
@@ -35,7 +43,7 @@ class che_견고 extends \sammo\BaseSpecial
|
|||||||
public function getBattlePhaseSkillTriggerList(WarUnit $unit): ?WarUnitTriggerCaller
|
public function getBattlePhaseSkillTriggerList(WarUnit $unit): ?WarUnitTriggerCaller
|
||||||
{
|
{
|
||||||
return new WarUnitTriggerCaller(
|
return new WarUnitTriggerCaller(
|
||||||
new WarActivateSkills($unit, BaseWarUnitTrigger::TYPE_ITEM + BaseWarUnitTrigger::TYPE_DEDUP_TYPE_BASE * 404, false, '필살불가', '계략약화', '저격불가')
|
new WarActivateSkills($unit, BaseWarUnitTrigger::TYPE_ITEM + BaseWarUnitTrigger::TYPE_DEDUP_TYPE_BASE * 404, false, '필살불가', '저격불가')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,9 +29,16 @@ class che_반계 extends \sammo\BaseSpecial{
|
|||||||
return $value;
|
return $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function onCalcOpposeStat(General $general, string $statName, $value, $aux = null)
|
||||||
|
{
|
||||||
|
$debuff = [
|
||||||
|
'warMagicSuccessProb' => 0.1,
|
||||||
|
][$statName] ?? 0;
|
||||||
|
return $value - $debuff;
|
||||||
|
}
|
||||||
|
|
||||||
public function getBattlePhaseSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller{
|
public function getBattlePhaseSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller{
|
||||||
return new WarUnitTriggerCaller(
|
return new WarUnitTriggerCaller(
|
||||||
new WarActivateSkills($unit, BaseWarUnitTrigger::TYPE_ITEM + BaseWarUnitTrigger::TYPE_DEDUP_TYPE_BASE * 406, false, '계략약화'),
|
|
||||||
new che_반계시도($unit),
|
new che_반계시도($unit),
|
||||||
new che_반계발동($unit)
|
new che_반계발동($unit)
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace sammo;
|
||||||
|
|
||||||
|
abstract class BaseAPI
|
||||||
|
{
|
||||||
|
const NO_SESSION = 0;
|
||||||
|
const REQ_LOGIN = 1;
|
||||||
|
const REQ_GAME_LOGIN = 2;
|
||||||
|
const REQ_READ_ONLY = 4;
|
||||||
|
|
||||||
|
protected array $args;
|
||||||
|
protected string $rootPath;
|
||||||
|
public function __construct(string $rootPath, array $args)
|
||||||
|
{
|
||||||
|
$this->rootPath = $rootPath;
|
||||||
|
$this->args = $args;
|
||||||
|
}
|
||||||
|
abstract public function getRequiredSessionMode(): int;
|
||||||
|
abstract function validateArgs(): ?string;
|
||||||
|
|
||||||
|
/** @return null|string|array */
|
||||||
|
abstract function launch(Session $session, ?\DateTimeInterface $modifiedSince, ?string $reqEtag);
|
||||||
|
|
||||||
|
public function tryCache():?string{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,6 +13,7 @@ use \sammo\LastTurn;
|
|||||||
use \sammo\Command;
|
use \sammo\Command;
|
||||||
|
|
||||||
use function \sammo\printCitiesBasedOnDistance;
|
use function \sammo\printCitiesBasedOnDistance;
|
||||||
|
use function sammo\tryUniqueItemLottery;
|
||||||
|
|
||||||
use \sammo\Constraint\Constraint;
|
use \sammo\Constraint\Constraint;
|
||||||
use \sammo\Constraint\ConstraintHelper;
|
use \sammo\Constraint\ConstraintHelper;
|
||||||
@@ -161,6 +162,8 @@ class che_강행 extends Command\GeneralCommand
|
|||||||
$general->increaseVar('leadership_exp', 1);
|
$general->increaseVar('leadership_exp', 1);
|
||||||
$this->setResultTurn(new LastTurn(static::getName(), $this->arg));
|
$this->setResultTurn(new LastTurn(static::getName(), $this->arg));
|
||||||
$general->checkStatChange();
|
$general->checkStatChange();
|
||||||
|
tryUniqueItemLottery($general);
|
||||||
|
|
||||||
$general->applyDB($db);
|
$general->applyDB($db);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ namespace sammo\Command\General;
|
|||||||
|
|
||||||
use \sammo\{
|
use \sammo\{
|
||||||
DB, Util, JosaUtil,
|
DB, Util, JosaUtil,
|
||||||
General,
|
General,
|
||||||
ActionLogger,
|
ActionLogger,
|
||||||
GameConst, GameUnitConst,
|
GameConst, GameUnitConst,
|
||||||
LastTurn,
|
LastTurn,
|
||||||
@@ -16,13 +16,12 @@ use \sammo\Constraint\ConstraintHelper;
|
|||||||
use sammo\CityConst;
|
use sammo\CityConst;
|
||||||
use function sammo\refreshNationStaticInfo;
|
use function sammo\refreshNationStaticInfo;
|
||||||
use function sammo\getAllNationStaticInfo;
|
use function sammo\getAllNationStaticInfo;
|
||||||
|
use function sammo\tryUniqueItemLottery;
|
||||||
|
|
||||||
|
|
||||||
class che_거병 extends Command\GeneralCommand{
|
class che_거병 extends Command\GeneralCommand{
|
||||||
static protected $actionName = '거병';
|
static protected $actionName = '거병';
|
||||||
|
|
||||||
protected function argTest():bool{
|
protected function argTest():bool{
|
||||||
$this->arg = [];
|
$this->arg = [];
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -38,7 +37,7 @@ class che_거병 extends Command\GeneralCommand{
|
|||||||
$this->setNation();
|
$this->setNation();
|
||||||
|
|
||||||
$relYear = $env['year'] - $env['startyear'];
|
$relYear = $env['year'] - $env['startyear'];
|
||||||
|
|
||||||
$this->fullConditionConstraints=[
|
$this->fullConditionConstraints=[
|
||||||
ConstraintHelper::BeNeutral(),
|
ConstraintHelper::BeNeutral(),
|
||||||
ConstraintHelper::BeOpeningPart($relYear+1),
|
ConstraintHelper::BeOpeningPart($relYear+1),
|
||||||
@@ -49,7 +48,7 @@ class che_거병 extends Command\GeneralCommand{
|
|||||||
public function getCost():array{
|
public function getCost():array{
|
||||||
return [0, 0];
|
return [0, 0];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPreReqTurn():int{
|
public function getPreReqTurn():int{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -93,15 +92,15 @@ class che_거병 extends Command\GeneralCommand{
|
|||||||
|
|
||||||
DB::db()->insert('nation', [
|
DB::db()->insert('nation', [
|
||||||
'name'=>$nationName,
|
'name'=>$nationName,
|
||||||
'color'=>'#330000',
|
'color'=>'#330000',
|
||||||
'gold'=>0,
|
'gold'=>0,
|
||||||
'rice'=>GameConst::$baserice,
|
'rice'=>GameConst::$baserice,
|
||||||
'rate'=>20,
|
'rate'=>20,
|
||||||
'bill'=>100,
|
'bill'=>100,
|
||||||
'strategic_cmd_limit'=>12,
|
'strategic_cmd_limit'=>12,
|
||||||
'surlimit'=>72,
|
'surlimit'=>72,
|
||||||
'secretlimit'=>$secretlimit,
|
'secretlimit'=>$secretlimit,
|
||||||
'type'=>GameConst::$neutralNationType,
|
'type'=>GameConst::$neutralNationType,
|
||||||
'gennum'=>1
|
'gennum'=>1
|
||||||
]);
|
]);
|
||||||
$nationID = DB::db()->insertId();
|
$nationID = DB::db()->insertId();
|
||||||
@@ -114,7 +113,7 @@ class che_거병 extends Command\GeneralCommand{
|
|||||||
if($nationID == $destNationID){
|
if($nationID == $destNationID){
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$diplomacyInit[] = [
|
$diplomacyInit[] = [
|
||||||
'me'=>$destNationID,
|
'me'=>$destNationID,
|
||||||
'you'=>$nationID,
|
'you'=>$nationID,
|
||||||
@@ -132,9 +131,9 @@ class che_거병 extends Command\GeneralCommand{
|
|||||||
if($diplomacyInit){
|
if($diplomacyInit){
|
||||||
$db->insert('diplomacy', $diplomacyInit);
|
$db->insert('diplomacy', $diplomacyInit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$turnRows = [];
|
$turnRows = [];
|
||||||
foreach([12, 11] as $chiefLevel){
|
foreach([12, 11] as $chiefLevel){
|
||||||
foreach(Util::range(GameConst::$maxChiefTurn) as $turnIdx){
|
foreach(Util::range(GameConst::$maxChiefTurn) as $turnIdx){
|
||||||
@@ -147,7 +146,7 @@ class che_거병 extends Command\GeneralCommand{
|
|||||||
'brief'=>'휴식',
|
'brief'=>'휴식',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
$db->insert('nation_turn', $turnRows);
|
$db->insert('nation_turn', $turnRows);
|
||||||
|
|
||||||
@@ -172,10 +171,12 @@ class che_거병 extends Command\GeneralCommand{
|
|||||||
|
|
||||||
$this->setResultTurn(new LastTurn(static::getName(), $this->arg));
|
$this->setResultTurn(new LastTurn(static::getName(), $this->arg));
|
||||||
$general->checkStatChange();
|
$general->checkStatChange();
|
||||||
|
tryUniqueItemLottery($general);
|
||||||
|
|
||||||
$general->applyDB($db);
|
$general->applyDB($db);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -3,7 +3,7 @@ namespace sammo\Command\General;
|
|||||||
|
|
||||||
use \sammo\{
|
use \sammo\{
|
||||||
DB, Util, JosaUtil,
|
DB, Util, JosaUtil,
|
||||||
General,
|
General,
|
||||||
ActionLogger,
|
ActionLogger,
|
||||||
GameConst, GameUnitConst,
|
GameConst, GameUnitConst,
|
||||||
LastTurn,
|
LastTurn,
|
||||||
@@ -14,10 +14,11 @@ use \sammo\Constraint\Constraint;
|
|||||||
use \sammo\Constraint\ConstraintHelper;
|
use \sammo\Constraint\ConstraintHelper;
|
||||||
use \sammo\TextDecoration\SightseeingMessage;
|
use \sammo\TextDecoration\SightseeingMessage;
|
||||||
|
|
||||||
|
use function sammo\tryUniqueItemLottery;
|
||||||
|
|
||||||
class che_견문 extends Command\GeneralCommand{
|
class che_견문 extends Command\GeneralCommand{
|
||||||
static protected $actionName = '견문';
|
static protected $actionName = '견문';
|
||||||
|
|
||||||
protected function argTest():bool{
|
protected function argTest():bool{
|
||||||
$this->arg = null;
|
$this->arg = null;
|
||||||
return true;
|
return true;
|
||||||
@@ -41,7 +42,7 @@ class che_견문 extends Command\GeneralCommand{
|
|||||||
public function getCost():array{
|
public function getCost():array{
|
||||||
return [0, 0];
|
return [0, 0];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPreReqTurn():int{
|
public function getPreReqTurn():int{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -111,10 +112,12 @@ class che_견문 extends Command\GeneralCommand{
|
|||||||
$general->addExperience($exp);
|
$general->addExperience($exp);
|
||||||
$this->setResultTurn(new LastTurn(static::getName(), $this->arg));
|
$this->setResultTurn(new LastTurn(static::getName(), $this->arg));
|
||||||
$general->checkStatChange();
|
$general->checkStatChange();
|
||||||
|
tryUniqueItemLottery($general);
|
||||||
|
|
||||||
$general->applyDB($db);
|
$general->applyDB($db);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@ namespace sammo\Command\General;
|
|||||||
|
|
||||||
use \sammo\{
|
use \sammo\{
|
||||||
DB, Util, JosaUtil,
|
DB, Util, JosaUtil,
|
||||||
General,
|
General,
|
||||||
ActionLogger,
|
ActionLogger,
|
||||||
GameConst, GameUnitConst,
|
GameConst, GameUnitConst,
|
||||||
LastTurn,
|
LastTurn,
|
||||||
@@ -16,6 +16,8 @@ use \sammo\Constraint\Constraint;
|
|||||||
use \sammo\Constraint\ConstraintHelper;
|
use \sammo\Constraint\ConstraintHelper;
|
||||||
use sammo\MustNotBeReachedException;
|
use sammo\MustNotBeReachedException;
|
||||||
|
|
||||||
|
use function sammo\tryUniqueItemLottery;
|
||||||
|
|
||||||
class che_군량매매 extends Command\GeneralCommand{
|
class che_군량매매 extends Command\GeneralCommand{
|
||||||
static protected $actionName = '군량매매';
|
static protected $actionName = '군량매매';
|
||||||
static public $reqArg = true;
|
static public $reqArg = true;
|
||||||
@@ -57,7 +59,7 @@ class che_군량매매 extends Command\GeneralCommand{
|
|||||||
$general = $this->generalObj;
|
$general = $this->generalObj;
|
||||||
|
|
||||||
$this->setCity();
|
$this->setCity();
|
||||||
$this->setNation();
|
$this->setNation();
|
||||||
|
|
||||||
$this->minConditionConstraints=[
|
$this->minConditionConstraints=[
|
||||||
ConstraintHelper::ReqCityTrader($general->getNPCType()),
|
ConstraintHelper::ReqCityTrader($general->getNPCType()),
|
||||||
@@ -69,7 +71,7 @@ class che_군량매매 extends Command\GeneralCommand{
|
|||||||
protected function initWithArg()
|
protected function initWithArg()
|
||||||
{
|
{
|
||||||
$general = $this->generalObj;
|
$general = $this->generalObj;
|
||||||
|
|
||||||
$this->fullConditionConstraints=[
|
$this->fullConditionConstraints=[
|
||||||
ConstraintHelper::ReqCityTrader($general->getNPCType()),
|
ConstraintHelper::ReqCityTrader($general->getNPCType()),
|
||||||
ConstraintHelper::OccupiedCity(true),
|
ConstraintHelper::OccupiedCity(true),
|
||||||
@@ -87,7 +89,7 @@ class che_군량매매 extends Command\GeneralCommand{
|
|||||||
public function getCost():array{
|
public function getCost():array{
|
||||||
return [0, 0];
|
return [0, 0];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPreReqTurn():int{
|
public function getPreReqTurn():int{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -120,7 +122,7 @@ class che_군량매매 extends Command\GeneralCommand{
|
|||||||
else{
|
else{
|
||||||
$tradeRate /= 100;
|
$tradeRate /= 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
if($buyRice){
|
if($buyRice){
|
||||||
$buyKey = 'rice';
|
$buyKey = 'rice';
|
||||||
$sellKey = 'gold';
|
$sellKey = 'gold';
|
||||||
@@ -153,7 +155,7 @@ class che_군량매매 extends Command\GeneralCommand{
|
|||||||
else{
|
else{
|
||||||
$logger->pushGeneralActionLog("군량 <C>{$sellAmountText}</>을 팔아 자금 <C>{$buyAmountText}</>을 얻었습니다. <1>$date</>");
|
$logger->pushGeneralActionLog("군량 <C>{$sellAmountText}</>을 팔아 자금 <C>{$buyAmountText}</>을 얻었습니다. <1>$date</>");
|
||||||
}
|
}
|
||||||
|
|
||||||
$general->increaseVar($buyKey, $buyAmount);
|
$general->increaseVar($buyKey, $buyAmount);
|
||||||
$general->increaseVarWithLimit($sellKey, -$sellAmount, 0);
|
$general->increaseVarWithLimit($sellKey, -$sellAmount, 0);
|
||||||
|
|
||||||
@@ -163,7 +165,7 @@ class che_군량매매 extends Command\GeneralCommand{
|
|||||||
|
|
||||||
$exp = 30;
|
$exp = 30;
|
||||||
$ded = 50;
|
$ded = 50;
|
||||||
|
|
||||||
$incStat = Util::choiceRandomUsingWeight([
|
$incStat = Util::choiceRandomUsingWeight([
|
||||||
'leadership_exp'=>$general->getLeadership(false, false, false, false),
|
'leadership_exp'=>$general->getLeadership(false, false, false, false),
|
||||||
'strength_exp'=>$general->getStrength(false, false, false, false),
|
'strength_exp'=>$general->getStrength(false, false, false, false),
|
||||||
@@ -176,6 +178,8 @@ class che_군량매매 extends Command\GeneralCommand{
|
|||||||
|
|
||||||
$this->setResultTurn(new LastTurn(static::getName(), $this->arg));
|
$this->setResultTurn(new LastTurn(static::getName(), $this->arg));
|
||||||
$general->checkStatChange();
|
$general->checkStatChange();
|
||||||
|
tryUniqueItemLottery($general);
|
||||||
|
|
||||||
$general->applyDB($db);
|
$general->applyDB($db);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -199,5 +203,5 @@ class che_군량매매 extends Command\GeneralCommand{
|
|||||||
return ob_get_clean();
|
return ob_get_clean();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -3,7 +3,7 @@ namespace sammo\Command\General;
|
|||||||
|
|
||||||
use \sammo\{
|
use \sammo\{
|
||||||
DB, Util, JosaUtil,
|
DB, Util, JosaUtil,
|
||||||
General,
|
General,
|
||||||
ActionLogger,
|
ActionLogger,
|
||||||
GameConst, GameUnitConst,
|
GameConst, GameUnitConst,
|
||||||
LastTurn,
|
LastTurn,
|
||||||
@@ -14,7 +14,7 @@ use \sammo\Constraint\Constraint;
|
|||||||
use \sammo\Constraint\ConstraintHelper;
|
use \sammo\Constraint\ConstraintHelper;
|
||||||
use sammo\CityConst;
|
use sammo\CityConst;
|
||||||
|
|
||||||
|
use function sammo\tryUniqueItemLottery;
|
||||||
|
|
||||||
class che_귀환 extends Command\GeneralCommand{
|
class che_귀환 extends Command\GeneralCommand{
|
||||||
static protected $actionName = '귀환';
|
static protected $actionName = '귀환';
|
||||||
@@ -33,7 +33,7 @@ class che_귀환 extends Command\GeneralCommand{
|
|||||||
$this->setNation();
|
$this->setNation();
|
||||||
|
|
||||||
[$reqGold, $reqRice] = $this->getCost();
|
[$reqGold, $reqRice] = $this->getCost();
|
||||||
|
|
||||||
$this->fullConditionConstraints=[
|
$this->fullConditionConstraints=[
|
||||||
ConstraintHelper::NotBeNeutral(),
|
ConstraintHelper::NotBeNeutral(),
|
||||||
ConstraintHelper::NotWanderingNation(),
|
ConstraintHelper::NotWanderingNation(),
|
||||||
@@ -49,7 +49,7 @@ class che_귀환 extends Command\GeneralCommand{
|
|||||||
public function getCost():array{
|
public function getCost():array{
|
||||||
return [0, 0];
|
return [0, 0];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPreReqTurn():int{
|
public function getPreReqTurn():int{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -87,7 +87,7 @@ class che_귀환 extends Command\GeneralCommand{
|
|||||||
|
|
||||||
$exp = 70;
|
$exp = 70;
|
||||||
$ded = 100;
|
$ded = 100;
|
||||||
|
|
||||||
$general->setVar('city', $destCityID);
|
$general->setVar('city', $destCityID);
|
||||||
|
|
||||||
$general->addExperience($exp);
|
$general->addExperience($exp);
|
||||||
@@ -95,10 +95,12 @@ class che_귀환 extends Command\GeneralCommand{
|
|||||||
$general->increaseVar('leadership_exp', 1);
|
$general->increaseVar('leadership_exp', 1);
|
||||||
$this->setResultTurn(new LastTurn(static::getName(), $this->arg));
|
$this->setResultTurn(new LastTurn(static::getName(), $this->arg));
|
||||||
$general->checkStatChange();
|
$general->checkStatChange();
|
||||||
|
tryUniqueItemLottery($general);
|
||||||
|
|
||||||
$general->applyDB($db);
|
$general->applyDB($db);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -15,6 +15,7 @@ use \sammo\{
|
|||||||
use function \sammo\getAllNationStaticInfo;
|
use function \sammo\getAllNationStaticInfo;
|
||||||
use function \sammo\getNationStaticInfo;
|
use function \sammo\getNationStaticInfo;
|
||||||
use function \sammo\newColor;
|
use function \sammo\newColor;
|
||||||
|
use function sammo\tryUniqueItemLottery;
|
||||||
|
|
||||||
use \sammo\Constraint\Constraint;
|
use \sammo\Constraint\Constraint;
|
||||||
use \sammo\Constraint\ConstraintHelper;
|
use \sammo\Constraint\ConstraintHelper;
|
||||||
@@ -64,7 +65,7 @@ class che_등용 extends Command\GeneralCommand{
|
|||||||
|
|
||||||
$this->minConditionConstraints=[
|
$this->minConditionConstraints=[
|
||||||
ConstraintHelper::ReqEnvValue('join_mode', '!=', 'onlyRandom', '랜덤 임관만 가능합니다'),
|
ConstraintHelper::ReqEnvValue('join_mode', '!=', 'onlyRandom', '랜덤 임관만 가능합니다'),
|
||||||
ConstraintHelper::NotBeNeutral(),
|
ConstraintHelper::NotBeNeutral(),
|
||||||
ConstraintHelper::OccupiedCity(),
|
ConstraintHelper::OccupiedCity(),
|
||||||
ConstraintHelper::SuppliedCity(),
|
ConstraintHelper::SuppliedCity(),
|
||||||
];
|
];
|
||||||
@@ -80,7 +81,7 @@ class che_등용 extends Command\GeneralCommand{
|
|||||||
|
|
||||||
$this->fullConditionConstraints=[
|
$this->fullConditionConstraints=[
|
||||||
ConstraintHelper::ReqEnvValue('join_mode', '!=', 'onlyRandom', '랜덤 임관만 가능합니다'),
|
ConstraintHelper::ReqEnvValue('join_mode', '!=', 'onlyRandom', '랜덤 임관만 가능합니다'),
|
||||||
ConstraintHelper::NotBeNeutral(),
|
ConstraintHelper::NotBeNeutral(),
|
||||||
ConstraintHelper::OccupiedCity(),
|
ConstraintHelper::OccupiedCity(),
|
||||||
ConstraintHelper::SuppliedCity(),
|
ConstraintHelper::SuppliedCity(),
|
||||||
ConstraintHelper::ExistsDestGeneral(),
|
ConstraintHelper::ExistsDestGeneral(),
|
||||||
@@ -110,7 +111,7 @@ class che_등용 extends Command\GeneralCommand{
|
|||||||
) * 10;
|
) * 10;
|
||||||
return [$reqGold, 0];
|
return [$reqGold, 0];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPreReqTurn():int{
|
public function getPreReqTurn():int{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -141,7 +142,7 @@ class che_등용 extends Command\GeneralCommand{
|
|||||||
|
|
||||||
$destGeneralName = $this->destGeneralObj->getName();
|
$destGeneralName = $this->destGeneralObj->getName();
|
||||||
$destGeneralID = $this->destGeneralObj->getID();
|
$destGeneralID = $this->destGeneralObj->getID();
|
||||||
|
|
||||||
|
|
||||||
$msg = ScoutMessage::buildScoutMessage($general->getID(), $destGeneralID, $reason, new \DateTime($general->getTurnTime()));
|
$msg = ScoutMessage::buildScoutMessage($general->getID(), $destGeneralID, $reason, new \DateTime($general->getTurnTime()));
|
||||||
if($msg){
|
if($msg){
|
||||||
@@ -164,6 +165,8 @@ class che_등용 extends Command\GeneralCommand{
|
|||||||
|
|
||||||
$this->setResultTurn(new LastTurn(static::getName(), $this->arg));
|
$this->setResultTurn(new LastTurn(static::getName(), $this->arg));
|
||||||
$general->checkStatChange();
|
$general->checkStatChange();
|
||||||
|
tryUniqueItemLottery($general);
|
||||||
|
|
||||||
$general->applyDB($db);
|
$general->applyDB($db);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ namespace sammo\Command\General;
|
|||||||
|
|
||||||
use \sammo\{
|
use \sammo\{
|
||||||
DB, Util, JosaUtil,
|
DB, Util, JosaUtil,
|
||||||
General,
|
General,
|
||||||
ActionLogger,
|
ActionLogger,
|
||||||
GameConst,
|
GameConst,
|
||||||
LastTurn,
|
LastTurn,
|
||||||
@@ -13,6 +13,7 @@ use \sammo\{
|
|||||||
|
|
||||||
use function \sammo\getDomesticExpLevelBonus;
|
use function \sammo\getDomesticExpLevelBonus;
|
||||||
use function \sammo\CriticalScoreEx;
|
use function \sammo\CriticalScoreEx;
|
||||||
|
use function sammo\tryUniqueItemLottery;
|
||||||
|
|
||||||
use \sammo\Constraint\Constraint;
|
use \sammo\Constraint\Constraint;
|
||||||
use \sammo\Constraint\ConstraintHelper;
|
use \sammo\Constraint\ConstraintHelper;
|
||||||
@@ -33,9 +34,9 @@ class che_물자조달 extends Command\GeneralCommand{
|
|||||||
|
|
||||||
$this->setCity();
|
$this->setCity();
|
||||||
$this->setNation();
|
$this->setNation();
|
||||||
|
|
||||||
$this->fullConditionConstraints=[
|
$this->fullConditionConstraints=[
|
||||||
ConstraintHelper::NotBeNeutral(),
|
ConstraintHelper::NotBeNeutral(),
|
||||||
ConstraintHelper::NotWanderingNation(),
|
ConstraintHelper::NotWanderingNation(),
|
||||||
ConstraintHelper::OccupiedCity(),
|
ConstraintHelper::OccupiedCity(),
|
||||||
ConstraintHelper::SuppliedCity()
|
ConstraintHelper::SuppliedCity()
|
||||||
@@ -50,7 +51,7 @@ class che_물자조달 extends Command\GeneralCommand{
|
|||||||
public function getCost():array{
|
public function getCost():array{
|
||||||
return [0, 0];
|
return [0, 0];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPreReqTurn():int{
|
public function getPreReqTurn():int{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -84,11 +85,11 @@ class che_물자조달 extends Command\GeneralCommand{
|
|||||||
'normal'=>0.6
|
'normal'=>0.6
|
||||||
]);
|
]);
|
||||||
$score *= CriticalScoreEx($pick);
|
$score *= CriticalScoreEx($pick);
|
||||||
|
|
||||||
|
|
||||||
$score = Util::round($score);
|
$score = Util::round($score);
|
||||||
$scoreText = number_format($score, 0);
|
$scoreText = number_format($score, 0);
|
||||||
|
|
||||||
$logger = $general->getLogger();
|
$logger = $general->getLogger();
|
||||||
|
|
||||||
if($pick == 'fail'){
|
if($pick == 'fail'){
|
||||||
@@ -120,10 +121,12 @@ class che_물자조달 extends Command\GeneralCommand{
|
|||||||
|
|
||||||
$this->setResultTurn(new LastTurn(static::getName(), $this->arg));
|
$this->setResultTurn(new LastTurn(static::getName(), $this->arg));
|
||||||
$general->checkStatChange();
|
$general->checkStatChange();
|
||||||
|
tryUniqueItemLottery($general);
|
||||||
|
|
||||||
$general->applyDB($db);
|
$general->applyDB($db);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -13,6 +13,7 @@ use \sammo\LastTurn;
|
|||||||
use \sammo\Command;
|
use \sammo\Command;
|
||||||
|
|
||||||
use function \sammo\printCitiesBasedOnDistance;
|
use function \sammo\printCitiesBasedOnDistance;
|
||||||
|
use function sammo\tryUniqueItemLottery;
|
||||||
|
|
||||||
use \sammo\Constraint\Constraint;
|
use \sammo\Constraint\Constraint;
|
||||||
use \sammo\Constraint\ConstraintHelper;
|
use \sammo\Constraint\ConstraintHelper;
|
||||||
@@ -169,6 +170,8 @@ class che_이동 extends Command\GeneralCommand
|
|||||||
$general->increaseVar('leadership_exp', 1);
|
$general->increaseVar('leadership_exp', 1);
|
||||||
$this->setResultTurn(new LastTurn(static::getName(), $this->arg));
|
$this->setResultTurn(new LastTurn(static::getName(), $this->arg));
|
||||||
$general->checkStatChange();
|
$general->checkStatChange();
|
||||||
|
tryUniqueItemLottery($general);
|
||||||
|
|
||||||
$general->applyDB($db);
|
$general->applyDB($db);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ namespace sammo\Command\General;
|
|||||||
|
|
||||||
use \sammo\{
|
use \sammo\{
|
||||||
DB, Util, JosaUtil,
|
DB, Util, JosaUtil,
|
||||||
General,
|
General,
|
||||||
ActionLogger,
|
ActionLogger,
|
||||||
GameConst, GameUnitConst,
|
GameConst, GameUnitConst,
|
||||||
LastTurn,
|
LastTurn,
|
||||||
@@ -13,6 +13,7 @@ use \sammo\{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use function \sammo\buildItemClass;
|
use function \sammo\buildItemClass;
|
||||||
|
use function sammo\tryUniqueItemLottery;
|
||||||
|
|
||||||
use \sammo\Constraint\Constraint;
|
use \sammo\Constraint\Constraint;
|
||||||
use \sammo\Constraint\ConstraintHelper;
|
use \sammo\Constraint\ConstraintHelper;
|
||||||
@@ -97,14 +98,14 @@ class che_장비매매 extends Command\GeneralCommand{
|
|||||||
if(!$this->isArgValid){
|
if(!$this->isArgValid){
|
||||||
return [0, 0];
|
return [0, 0];
|
||||||
}
|
}
|
||||||
|
|
||||||
$itemCode = $this->arg['itemCode'];
|
$itemCode = $this->arg['itemCode'];
|
||||||
$itemObj = buildItemClass($itemCode);
|
$itemObj = buildItemClass($itemCode);
|
||||||
|
|
||||||
$reqGold = $itemObj->getCost();
|
$reqGold = $itemObj->getCost();
|
||||||
return [$reqGold, 0];
|
return [$reqGold, 0];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPreReqTurn():int{
|
public function getPreReqTurn():int{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -176,6 +177,7 @@ class che_장비매매 extends Command\GeneralCommand{
|
|||||||
$general->addExperience($exp);
|
$general->addExperience($exp);
|
||||||
$this->setResultTurn(new LastTurn(static::getName(), $this->arg));
|
$this->setResultTurn(new LastTurn(static::getName(), $this->arg));
|
||||||
$general->checkStatChange();
|
$general->checkStatChange();
|
||||||
|
tryUniqueItemLottery($general);
|
||||||
$general->applyDB($db);
|
$general->applyDB($db);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -208,7 +210,7 @@ $('#customSubmit').click(function(){
|
|||||||
현재 구입 불가능한 것은 <font color=red>붉은색</font>으로 표시됩니다.<br>
|
현재 구입 불가능한 것은 <font color=red>붉은색</font>으로 표시됩니다.<br>
|
||||||
현재 도시 치안 : <?=$citySecu?> 현재 자금 : <?=$gold?><br>
|
현재 도시 치안 : <?=$citySecu?> 현재 자금 : <?=$gold?><br>
|
||||||
장비 : <select class='formInput' name="itemCode" id="itemCode" onchange='updateItemType();' size='1' style='color:white;background-color:black;'>
|
장비 : <select class='formInput' name="itemCode" id="itemCode" onchange='updateItemType();' size='1' style='color:white;background-color:black;'>
|
||||||
<?php foreach(GameConst::$allItems as $itemType=>$itemCategories):
|
<?php foreach(GameConst::$allItems as $itemType=>$itemCategories):
|
||||||
//매각
|
//매각
|
||||||
$typeName = static::$itemMap[$itemType];
|
$typeName = static::$itemMap[$itemType];
|
||||||
?>
|
?>
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ use \sammo\Command;
|
|||||||
use \sammo\Constraint\Constraint;
|
use \sammo\Constraint\Constraint;
|
||||||
use \sammo\Constraint\ConstraintHelper;
|
use \sammo\Constraint\ConstraintHelper;
|
||||||
|
|
||||||
|
use function sammo\tryUniqueItemLottery;
|
||||||
|
|
||||||
class che_증여 extends Command\GeneralCommand
|
class che_증여 extends Command\GeneralCommand
|
||||||
{
|
{
|
||||||
@@ -168,6 +169,8 @@ class che_증여 extends Command\GeneralCommand
|
|||||||
|
|
||||||
$this->setResultTurn(new LastTurn(static::getName(), $this->arg));
|
$this->setResultTurn(new LastTurn(static::getName(), $this->arg));
|
||||||
$general->checkStatChange();
|
$general->checkStatChange();
|
||||||
|
tryUniqueItemLottery($general);
|
||||||
|
|
||||||
$general->applyDB($db);
|
$general->applyDB($db);
|
||||||
$destGeneral->applyDB($db);
|
$destGeneral->applyDB($db);
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ use \sammo\Command;
|
|||||||
use \sammo\Constraint\Constraint;
|
use \sammo\Constraint\Constraint;
|
||||||
use \sammo\Constraint\ConstraintHelper;
|
use \sammo\Constraint\ConstraintHelper;
|
||||||
|
|
||||||
|
use function sammo\tryUniqueItemLottery;
|
||||||
|
|
||||||
class che_헌납 extends Command\GeneralCommand
|
class che_헌납 extends Command\GeneralCommand
|
||||||
{
|
{
|
||||||
@@ -144,6 +145,8 @@ class che_헌납 extends Command\GeneralCommand
|
|||||||
|
|
||||||
$this->setResultTurn(new LastTurn(static::getName(), $this->arg));
|
$this->setResultTurn(new LastTurn(static::getName(), $this->arg));
|
||||||
$general->checkStatChange();
|
$general->checkStatChange();
|
||||||
|
|
||||||
|
tryUniqueItemLottery($general);
|
||||||
$general->applyDB($db);
|
$general->applyDB($db);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -25,6 +25,10 @@ trait DefaultAction{
|
|||||||
return $value;
|
return $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function onCalcOpposeStat(General $general, string $statName, $value, $aux=null){
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
public function onCalcStrategic(string $turnType, string $varType, $value){
|
public function onCalcStrategic(string $turnType, string $varType, $value){
|
||||||
return $value;
|
return $value;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,14 @@ class DummyGeneral extends General{
|
|||||||
return new WarUnitTriggerCaller();
|
return new WarUnitTriggerCaller();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function onCalcStat(General $general, string $statName, $value, $aux=null){
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onCalcOpposeStat(General $general, string $statName, $value, $aux=null){
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
function applyDB($db):bool{
|
function applyDB($db):bool{
|
||||||
if($this->logger){
|
if($this->logger){
|
||||||
$this->initLogger(1, 1);
|
$this->initLogger(1, 1);
|
||||||
|
|||||||
+72
-56
@@ -1,15 +1,16 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace sammo;
|
namespace sammo;
|
||||||
|
|
||||||
class GameConstBase
|
class GameConstBase
|
||||||
{
|
{
|
||||||
/** @var string 게임명 */
|
/** @var string 게임명 */
|
||||||
public static $title = "삼국지 모의전투 PHP HiDCHe";
|
public static $title = "삼국지 모의전투 PHP HiDCHe";
|
||||||
/** @var string 코드 아래에 붙는 설명 코드 */
|
/** @var string 코드 아래에 붙는 설명 코드 */
|
||||||
public static $banner = "KOEI의 이미지를 사용, 응용하였습니다 / 제작 : HideD(hided62@gmail.com) / <a href='https://sam.hided.net/wiki/hidche/credit' target='_blank' style='color:white;text-decoration: underline;'>Credit</a>";
|
public static $banner = "KOEI의 이미지를 사용, 응용하였습니다 / 제작 : HideD(hided62@gmail.com) / <a href='https://sam.hided.net/wiki/hidche/credit' target='_blank' style='color:white;text-decoration: underline;'>Credit</a>";
|
||||||
/** @var string 사용중인 지도명 */
|
/** @var string 사용중인 지도명 */
|
||||||
public static $mapName = 'che';
|
public static $mapName = 'che';
|
||||||
/** @var string 사용중인 유닛셋 */
|
/** @var string 사용중인 유닛셋 */
|
||||||
public static $unitSet = 'che';
|
public static $unitSet = 'che';
|
||||||
/** @var int 내정시 최하 민심 설정*/
|
/** @var int 내정시 최하 민심 설정*/
|
||||||
public static $develrate = 50;
|
public static $develrate = 50;
|
||||||
@@ -137,12 +138,17 @@ class GameConstBase
|
|||||||
public static $maxChiefTurn = 12;
|
public static $maxChiefTurn = 12;
|
||||||
|
|
||||||
public static $statGradeLevel = 5;
|
public static $statGradeLevel = 5;
|
||||||
|
|
||||||
/** @var int 초반 제한 기간 */
|
/** @var int 초반 제한 기간 */
|
||||||
public static $openingPartYear = 3;
|
public static $openingPartYear = 3;
|
||||||
/** @var int 거병,임관 제한 기간 */
|
/** @var int 거병,임관 제한 기간 */
|
||||||
public static $joinActionLimit = 12;
|
public static $joinActionLimit = 12;
|
||||||
|
|
||||||
|
/** @var int 장수 생성시 능력치 최소 보너스 */
|
||||||
|
public static $bornMinStatBonus = 3;
|
||||||
|
/** @var int 장수 생성시 능력치 최대 보너스 */
|
||||||
|
public static $bornMaxStatBonus = 5;
|
||||||
|
|
||||||
/** @var array 선택 가능한 국가 성향 */
|
/** @var array 선택 가능한 국가 성향 */
|
||||||
public static $availableNationType = [
|
public static $availableNationType = [
|
||||||
'che_도적', 'che_명가', 'che_음양가', 'che_종횡가', 'che_불가', 'che_오두미도', 'che_태평도', 'che_도가',
|
'che_도적', 'che_명가', 'che_음양가', 'che_종횡가', 'che_불가', 'che_오두미도', 'che_태평도', 'che_도가',
|
||||||
@@ -166,83 +172,93 @@ class GameConstBase
|
|||||||
public static $defaultSpecialWar = 'None';
|
public static $defaultSpecialWar = 'None';
|
||||||
/** @var array 선택 가능한 장수 전투 특기 */
|
/** @var array 선택 가능한 장수 전투 특기 */
|
||||||
public static $availableSpecialWar = [
|
public static $availableSpecialWar = [
|
||||||
'che_귀병', 'che_신산', 'che_환술', 'che_집중', 'che_신중', 'che_반계',
|
'che_귀병', 'che_신산', 'che_환술', 'che_집중', 'che_신중', 'che_반계',
|
||||||
'che_보병', 'che_궁병', 'che_기병', 'che_공성',
|
'che_보병', 'che_궁병', 'che_기병', 'che_공성',
|
||||||
'che_돌격', 'che_무쌍', 'che_견고', 'che_위압',
|
'che_돌격', 'che_무쌍', 'che_견고', 'che_위압',
|
||||||
'che_저격', 'che_필살', 'che_징병', 'che_의술', 'che_격노', 'che_척사',
|
'che_저격', 'che_필살', 'che_징병', 'che_의술', 'che_격노', 'che_척사',
|
||||||
];
|
];
|
||||||
/** @var array 선택할 수 없으나 게임 내에 유효한 장수 전투 특기 */
|
/** @var array 선택할 수 없으나 게임 내에 유효한 장수 전투 특기 */
|
||||||
public static $optionalSpecialWar = [
|
public static $optionalSpecialWar = [
|
||||||
'None',
|
'None',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
/** @var string 기본 성향(공용) */
|
/** @var string 기본 성향(공용) */
|
||||||
public static $neutralPersonality = 'None';
|
public static $neutralPersonality = 'None';
|
||||||
/** @var array 선택 가능한 성향 */
|
/** @var array 선택 가능한 성향 */
|
||||||
public static $availablePersonality = [
|
public static $availablePersonality = [
|
||||||
'che_안전', 'che_유지', 'che_재간', 'che_출세', 'che_할거', 'che_정복',
|
'che_안전', 'che_유지', 'che_재간', 'che_출세', 'che_할거', 'che_정복',
|
||||||
'che_패권', 'che_의협', 'che_대의', 'che_왕좌'
|
'che_패권', 'che_의협', 'che_대의', 'che_왕좌'
|
||||||
];
|
];
|
||||||
/** @var array 존재하는 모든 성향 */
|
/** @var array 존재하는 모든 성향 */
|
||||||
public static $optionalPersonality = [
|
public static $optionalPersonality = [
|
||||||
'che_은둔', 'None'
|
'che_은둔', 'None'
|
||||||
];
|
];
|
||||||
|
|
||||||
|
public static $inheritBornSpecialPoint = 12000;
|
||||||
|
public static $inheritBornTurntimePoint = 3000;
|
||||||
|
public static $inheritBornCityPoint = 1000;
|
||||||
|
public static $inheritBornStatPoint = 1000;
|
||||||
|
public static $inheritItemUniqueMinPoint = 5000;
|
||||||
|
public static $inheritItemRandomPoint = 3000;
|
||||||
|
public static $inheritBuffPoints = [0, 250, 750, 1500, 2500, 3750];
|
||||||
|
public static $inheritSpecificSpecialPoint = 5000;
|
||||||
|
public static $inheritResetAttrPointBase = [1000, 1000, 2000, 3000];//필요하면 늘려서 쓰기
|
||||||
|
|
||||||
public static $allItems = [
|
public static $allItems = [
|
||||||
'horse' => [
|
'horse' => [
|
||||||
'che_명마_01_노기'=>0, 'che_명마_02_조랑'=>0, 'che_명마_03_노새'=>0,
|
'che_명마_01_노기' => 0, 'che_명마_02_조랑' => 0, 'che_명마_03_노새' => 0,
|
||||||
'che_명마_04_나귀'=>0, 'che_명마_05_갈색마'=>0, 'che_명마_06_흑색마'=>0,
|
'che_명마_04_나귀' => 0, 'che_명마_05_갈색마' => 0, 'che_명마_06_흑색마' => 0,
|
||||||
|
|
||||||
'che_명마_07_백마'=>2, 'che_명마_07_기주마'=>2,
|
'che_명마_07_백마' => 2, 'che_명마_07_기주마' => 2,
|
||||||
'che_명마_08_양주마'=>2, 'che_명마_09_과하마'=>2,
|
'che_명마_08_양주마' => 2, 'che_명마_09_과하마' => 2,
|
||||||
'che_명마_10_대완마'=>2, 'che_명마_11_서량마'=>2,
|
'che_명마_10_대완마' => 2, 'che_명마_11_서량마' => 2,
|
||||||
'che_명마_12_사륜거'=>2, 'che_명마_13_절영'=>1, 'che_명마_13_적로'=>1,
|
'che_명마_12_사륜거' => 2, 'che_명마_13_절영' => 1, 'che_명마_13_적로' => 1,
|
||||||
'che_명마_14_적란마'=>1, 'che_명마_14_조황비전'=>1, 'che_명마_15_한혈마'=>1, 'che_명마_15_적토마'=>1,
|
'che_명마_14_적란마' => 1, 'che_명마_14_조황비전' => 1, 'che_명마_15_한혈마' => 1, 'che_명마_15_적토마' => 1,
|
||||||
],
|
],
|
||||||
'weapon' => [
|
'weapon' => [
|
||||||
'che_무기_01_단도'=>0, 'che_무기_02_단궁'=>0, 'che_무기_03_단극'=>0,
|
'che_무기_01_단도' => 0, 'che_무기_02_단궁' => 0, 'che_무기_03_단극' => 0,
|
||||||
'che_무기_04_목검'=>0, 'che_무기_05_죽창'=>0, 'che_무기_06_소부'=>0,
|
'che_무기_04_목검' => 0, 'che_무기_05_죽창' => 0, 'che_무기_06_소부' => 0,
|
||||||
|
|
||||||
'che_무기_07_동추'=>1, 'che_무기_07_철편'=>1, 'che_무기_07_철쇄'=>1, 'che_무기_07_맥궁'=>1,
|
'che_무기_07_동추' => 1, 'che_무기_07_철편' => 1, 'che_무기_07_철쇄' => 1, 'che_무기_07_맥궁' => 1,
|
||||||
'che_무기_08_유성추'=>1, 'che_무기_08_철질여골'=>1, 'che_무기_09_쌍철극'=>1, 'che_무기_09_동호비궁'=>1, 'che_무기_10_삼첨도'=>1, 'che_무기_10_대부'=>1, 'che_무기_11_고정도'=>1, 'che_무기_11_이광궁'=>1, 'che_무기_12_철척사모'=>1, 'che_무기_12_칠성검'=>1, 'che_무기_13_사모'=>1, 'che_무기_13_양유기궁'=>1,
|
'che_무기_08_유성추' => 1, 'che_무기_08_철질여골' => 1, 'che_무기_09_쌍철극' => 1, 'che_무기_09_동호비궁' => 1, 'che_무기_10_삼첨도' => 1, 'che_무기_10_대부' => 1, 'che_무기_11_고정도' => 1, 'che_무기_11_이광궁' => 1, 'che_무기_12_철척사모' => 1, 'che_무기_12_칠성검' => 1, 'che_무기_13_사모' => 1, 'che_무기_13_양유기궁' => 1,
|
||||||
'che_무기_14_언월도'=>1, 'che_무기_14_방천화극'=>1, 'che_무기_15_청홍검'=>1, 'che_무기_15_의천검'=>1
|
'che_무기_14_언월도' => 1, 'che_무기_14_방천화극' => 1, 'che_무기_15_청홍검' => 1, 'che_무기_15_의천검' => 1
|
||||||
],
|
],
|
||||||
'book' => [
|
'book' => [
|
||||||
'che_서적_01_효경전'=>0, 'che_서적_02_회남자'=>0, 'che_서적_03_변도론'=>0,
|
'che_서적_01_효경전' => 0, 'che_서적_02_회남자' => 0, 'che_서적_03_변도론' => 0,
|
||||||
'che_서적_04_건상역주'=>0, 'che_서적_05_여씨춘추'=>0, 'che_서적_06_사민월령'=>0,
|
'che_서적_04_건상역주' => 0, 'che_서적_05_여씨춘추' => 0, 'che_서적_06_사민월령' => 0,
|
||||||
|
|
||||||
'che_서적_07_위료자'=>1, 'che_서적_07_사마법'=>1, 'che_서적_07_한서'=>1, 'che_서적_07_논어'=>1,
|
'che_서적_07_위료자' => 1, 'che_서적_07_사마법' => 1, 'che_서적_07_한서' => 1, 'che_서적_07_논어' => 1,
|
||||||
'che_서적_08_전론'=>1, 'che_서적_08_사기'=>1, 'che_서적_09_장자'=>1, 'che_서적_09_역경'=>1,
|
'che_서적_08_전론' => 1, 'che_서적_08_사기' => 1, 'che_서적_09_장자' => 1, 'che_서적_09_역경' => 1,
|
||||||
'che_서적_10_시경'=>1, 'che_서적_10_구국론'=>1, 'che_서적_11_상군서'=>1, 'che_서적_11_춘추전'=>1,
|
'che_서적_10_시경' => 1, 'che_서적_10_구국론' => 1, 'che_서적_11_상군서' => 1, 'che_서적_11_춘추전' => 1,
|
||||||
'che_서적_12_산해경'=>1, 'che_서적_12_맹덕신서'=>1, 'che_서적_13_관자'=>1, 'che_서적_13_병법24편'=>1,
|
'che_서적_12_산해경' => 1, 'che_서적_12_맹덕신서' => 1, 'che_서적_13_관자' => 1, 'che_서적_13_병법24편' => 1,
|
||||||
'che_서적_14_한비자'=>1, 'che_서적_14_오자병법'=>1, 'che_서적_15_노자'=>1, 'che_서적_15_손자병법'=>1,
|
'che_서적_14_한비자' => 1, 'che_서적_14_오자병법' => 1, 'che_서적_15_노자' => 1, 'che_서적_15_손자병법' => 1,
|
||||||
],
|
],
|
||||||
'item' => [
|
'item' => [
|
||||||
'che_치료_환약'=>0, 'che_저격_수극'=>0, 'che_사기_탁주'=>0,
|
'che_치료_환약' => 0, 'che_저격_수극' => 0, 'che_사기_탁주' => 0,
|
||||||
'che_훈련_청주'=>0, 'che_계략_이추'=>0, 'che_계략_향낭'=>0,
|
'che_훈련_청주' => 0, 'che_계략_이추' => 0, 'che_계략_향낭' => 0,
|
||||||
|
|
||||||
'che_의술_청낭서'=>1, 'che_의술_태평청령'=>1, 'che_의술_상한잡병론'=>1,
|
'che_의술_청낭서' => 1, 'che_의술_태평청령' => 1, 'che_의술_상한잡병론' => 1,
|
||||||
'che_부적_태현청생부'=>1,
|
'che_부적_태현청생부' => 1,
|
||||||
'che_저격_매화수전'=>1, 'che_저격_비도'=>1,
|
'che_저격_매화수전' => 1, 'che_저격_비도' => 1,
|
||||||
'che_계략_육도'=>1, 'che_계략_삼략'=>1,
|
'che_계략_육도' => 1, 'che_계략_삼략' => 1,
|
||||||
'che_반계_백우선'=>1,
|
'che_반계_백우선' => 1,
|
||||||
'che_행동_서촉지형도'=>1,
|
'che_행동_서촉지형도' => 1,
|
||||||
|
|
||||||
|
|
||||||
'che_훈련_과실주'=>1, 'che_훈련_이강주'=>1, 'che_사기_두강주'=>1, 'che_사기_보령압주'=>1,
|
'che_훈련_과실주' => 1, 'che_훈련_이강주' => 1, 'che_사기_두강주' => 1, 'che_사기_보령압주' => 1,
|
||||||
'che_훈련_철벽서'=>1, 'che_훈련_단결도'=>1, 'che_사기_춘화첩'=>1, 'che_사기_초선화'=>1,
|
'che_훈련_철벽서' => 1, 'che_훈련_단결도' => 1, 'che_사기_춘화첩' => 1, 'che_사기_초선화' => 1,
|
||||||
'che_회피_태평요술'=>1, 'che_회피_둔갑천서'=>1,
|
'che_회피_태평요술' => 1, 'che_회피_둔갑천서' => 1,
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
/** @var array 선택 가능한 커맨드 */
|
/** @var array 선택 가능한 커맨드 */
|
||||||
public static $availableGeneralCommand = [
|
public static $availableGeneralCommand = [
|
||||||
''=>[
|
'' => [
|
||||||
'휴식',
|
'휴식',
|
||||||
'che_요양'
|
'che_요양'
|
||||||
],
|
],
|
||||||
'내정'=>[
|
'내정' => [
|
||||||
'che_농지개간',
|
'che_농지개간',
|
||||||
'che_상업투자',
|
'che_상업투자',
|
||||||
'che_기술연구',
|
'che_기술연구',
|
||||||
@@ -253,7 +269,7 @@ class GameConstBase
|
|||||||
'che_주민선정',
|
'che_주민선정',
|
||||||
'che_물자조달',
|
'che_물자조달',
|
||||||
],
|
],
|
||||||
'군사'=>[
|
'군사' => [
|
||||||
'che_소집해제',
|
'che_소집해제',
|
||||||
'che_첩보',
|
'che_첩보',
|
||||||
'che_징병',
|
'che_징병',
|
||||||
@@ -262,7 +278,7 @@ class GameConstBase
|
|||||||
'che_사기진작',
|
'che_사기진작',
|
||||||
'che_출병',
|
'che_출병',
|
||||||
],
|
],
|
||||||
'인사'=>[
|
'인사' => [
|
||||||
'che_이동',
|
'che_이동',
|
||||||
'che_강행',
|
'che_강행',
|
||||||
'che_인재탐색',
|
'che_인재탐색',
|
||||||
@@ -273,13 +289,13 @@ class GameConstBase
|
|||||||
'che_랜덤임관',
|
'che_랜덤임관',
|
||||||
'che_장수대상임관',
|
'che_장수대상임관',
|
||||||
],
|
],
|
||||||
'계략'=>[
|
'계략' => [
|
||||||
'che_화계',
|
'che_화계',
|
||||||
'che_파괴',
|
'che_파괴',
|
||||||
'che_탈취',
|
'che_탈취',
|
||||||
'che_선동',
|
'che_선동',
|
||||||
],
|
],
|
||||||
'개인'=>[
|
'개인' => [
|
||||||
'che_내정특기초기화',
|
'che_내정특기초기화',
|
||||||
'che_전투특기초기화',
|
'che_전투특기초기화',
|
||||||
'che_단련',
|
'che_단련',
|
||||||
@@ -301,28 +317,28 @@ class GameConstBase
|
|||||||
|
|
||||||
/** @var array 선택 가능한 커맨드 */
|
/** @var array 선택 가능한 커맨드 */
|
||||||
public static $availableChiefCommand = [
|
public static $availableChiefCommand = [
|
||||||
'휴식'=>[
|
'휴식' => [
|
||||||
'휴식',
|
'휴식',
|
||||||
],
|
],
|
||||||
'인사'=>[
|
'인사' => [
|
||||||
'che_발령',
|
'che_발령',
|
||||||
'che_포상',
|
'che_포상',
|
||||||
'che_몰수',
|
'che_몰수',
|
||||||
],
|
],
|
||||||
'외교'=>[
|
'외교' => [
|
||||||
'che_물자원조',
|
'che_물자원조',
|
||||||
'che_불가침제의',
|
'che_불가침제의',
|
||||||
'che_선전포고',
|
'che_선전포고',
|
||||||
'che_종전제의',
|
'che_종전제의',
|
||||||
'che_불가침파기제의',
|
'che_불가침파기제의',
|
||||||
],
|
],
|
||||||
'특수'=>[
|
'특수' => [
|
||||||
'che_초토화',
|
'che_초토화',
|
||||||
'che_천도',
|
'che_천도',
|
||||||
'che_증축',
|
'che_증축',
|
||||||
'che_감축',
|
'che_감축',
|
||||||
],
|
],
|
||||||
'전략'=>[
|
'전략' => [
|
||||||
'che_필사즉생',
|
'che_필사즉생',
|
||||||
'che_백성동원',
|
'che_백성동원',
|
||||||
'che_수몰',
|
'che_수몰',
|
||||||
@@ -331,7 +347,7 @@ class GameConstBase
|
|||||||
'che_이호경식',
|
'che_이호경식',
|
||||||
'che_급습',
|
'che_급습',
|
||||||
],
|
],
|
||||||
'기타'=>[
|
'기타' => [
|
||||||
'che_피장파장',
|
'che_피장파장',
|
||||||
'che_국기변경',
|
'che_국기변경',
|
||||||
'che_국호변경',
|
'che_국호변경',
|
||||||
|
|||||||
+39
-1
@@ -35,6 +35,8 @@ class General implements iAction{
|
|||||||
protected $personalityObj = null;
|
protected $personalityObj = null;
|
||||||
/** @var iAction[] */
|
/** @var iAction[] */
|
||||||
protected $itemObjs = [];
|
protected $itemObjs = [];
|
||||||
|
/** @var iAction */
|
||||||
|
protected $inheritBuffObj = null;
|
||||||
|
|
||||||
protected $lastTurn = null;
|
protected $lastTurn = null;
|
||||||
protected $resultTurn = null;
|
protected $resultTurn = null;
|
||||||
@@ -136,6 +138,13 @@ class General implements iAction{
|
|||||||
$this->itemObjs['weapon'] = buildItemClass($raw['weapon']);
|
$this->itemObjs['weapon'] = buildItemClass($raw['weapon']);
|
||||||
$this->itemObjs['book'] = buildItemClass($raw['book']);
|
$this->itemObjs['book'] = buildItemClass($raw['book']);
|
||||||
$this->itemObjs['item'] = buildItemClass($raw['item']);
|
$this->itemObjs['item'] = buildItemClass($raw['item']);
|
||||||
|
|
||||||
|
if(key_exists('aux', $this->raw)){
|
||||||
|
$rawInheritBuff = $this->getAuxVar('inheritBuff');
|
||||||
|
if($rawInheritBuff !== null){
|
||||||
|
$this->inheritBuffObj = new TriggerInheritBuff($rawInheritBuff);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function initLogger(int $year, int $month){
|
function initLogger(int $year, int $month){
|
||||||
@@ -410,7 +419,8 @@ class General implements iAction{
|
|||||||
$this->officerLevelObj,
|
$this->officerLevelObj,
|
||||||
$this->specialDomesticObj,
|
$this->specialDomesticObj,
|
||||||
$this->specialWarObj,
|
$this->specialWarObj,
|
||||||
$this->personalityObj
|
$this->personalityObj,
|
||||||
|
$this->inheritBuffObj,
|
||||||
] as $actionObj){
|
] as $actionObj){
|
||||||
if($actionObj !== null){
|
if($actionObj !== null){
|
||||||
$statValue = $actionObj->onCalcStat($this, $statName, $statValue);
|
$statValue = $actionObj->onCalcStat($this, $statName, $statValue);
|
||||||
@@ -785,6 +795,7 @@ class General implements iAction{
|
|||||||
$this->specialWarObj,
|
$this->specialWarObj,
|
||||||
$this->personalityObj,
|
$this->personalityObj,
|
||||||
$this->getCrewTypeObj(),
|
$this->getCrewTypeObj(),
|
||||||
|
$this->inheritBuffObj,
|
||||||
], $this->itemObjs) as $iObj){
|
], $this->itemObjs) as $iObj){
|
||||||
|
|
||||||
if(!$iObj){
|
if(!$iObj){
|
||||||
@@ -804,6 +815,7 @@ class General implements iAction{
|
|||||||
$this->specialWarObj,
|
$this->specialWarObj,
|
||||||
$this->personalityObj,
|
$this->personalityObj,
|
||||||
$this->getCrewTypeObj(),
|
$this->getCrewTypeObj(),
|
||||||
|
$this->inheritBuffObj,
|
||||||
], $this->itemObjs) as $iObj){
|
], $this->itemObjs) as $iObj){
|
||||||
if(!$iObj){
|
if(!$iObj){
|
||||||
continue;
|
continue;
|
||||||
@@ -823,6 +835,7 @@ class General implements iAction{
|
|||||||
$this->specialWarObj,
|
$this->specialWarObj,
|
||||||
$this->personalityObj,
|
$this->personalityObj,
|
||||||
$this->getCrewTypeObj(),
|
$this->getCrewTypeObj(),
|
||||||
|
$this->inheritBuffObj,
|
||||||
], $this->itemObjs) as $iObj){
|
], $this->itemObjs) as $iObj){
|
||||||
if(!$iObj){
|
if(!$iObj){
|
||||||
continue;
|
continue;
|
||||||
@@ -833,6 +846,26 @@ class General implements iAction{
|
|||||||
return $value;
|
return $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function onCalcOpposeStat(General $general, string $statName, $value, $aux=null){
|
||||||
|
//xxx: $general?
|
||||||
|
foreach(array_merge([
|
||||||
|
$this->nationType,
|
||||||
|
$this->officerLevelObj,
|
||||||
|
$this->specialDomesticObj,
|
||||||
|
$this->specialWarObj,
|
||||||
|
$this->personalityObj,
|
||||||
|
$this->getCrewTypeObj(),
|
||||||
|
$this->inheritBuffObj,
|
||||||
|
], $this->itemObjs) as $iObj){
|
||||||
|
if(!$iObj){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/** @var iAction $iObj */
|
||||||
|
$value = $iObj->onCalcOpposeStat($this, $statName, $value, $aux);
|
||||||
|
}
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
public function onCalcStrategic(string $turnType, string $varType, $value){
|
public function onCalcStrategic(string $turnType, string $varType, $value){
|
||||||
foreach(array_merge([
|
foreach(array_merge([
|
||||||
$this->nationType,
|
$this->nationType,
|
||||||
@@ -841,6 +874,7 @@ class General implements iAction{
|
|||||||
$this->specialWarObj,
|
$this->specialWarObj,
|
||||||
$this->personalityObj,
|
$this->personalityObj,
|
||||||
$this->getCrewTypeObj(),
|
$this->getCrewTypeObj(),
|
||||||
|
$this->inheritBuffObj,
|
||||||
], $this->itemObjs) as $iObj){
|
], $this->itemObjs) as $iObj){
|
||||||
if(!$iObj){
|
if(!$iObj){
|
||||||
continue;
|
continue;
|
||||||
@@ -859,6 +893,7 @@ class General implements iAction{
|
|||||||
$this->specialWarObj,
|
$this->specialWarObj,
|
||||||
$this->personalityObj,
|
$this->personalityObj,
|
||||||
$this->getCrewTypeObj(),
|
$this->getCrewTypeObj(),
|
||||||
|
$this->inheritBuffObj,
|
||||||
], $this->itemObjs) as $iObj){
|
], $this->itemObjs) as $iObj){
|
||||||
if(!$iObj){
|
if(!$iObj){
|
||||||
continue;
|
continue;
|
||||||
@@ -880,6 +915,7 @@ class General implements iAction{
|
|||||||
$this->specialWarObj,
|
$this->specialWarObj,
|
||||||
$this->personalityObj,
|
$this->personalityObj,
|
||||||
$this->getCrewTypeObj(),
|
$this->getCrewTypeObj(),
|
||||||
|
$this->inheritBuffObj,
|
||||||
], $this->itemObjs) as $iObj){
|
], $this->itemObjs) as $iObj){
|
||||||
if(!$iObj){
|
if(!$iObj){
|
||||||
continue;
|
continue;
|
||||||
@@ -900,6 +936,7 @@ class General implements iAction{
|
|||||||
$this->specialWarObj,
|
$this->specialWarObj,
|
||||||
$this->personalityObj,
|
$this->personalityObj,
|
||||||
$this->getCrewTypeObj(),
|
$this->getCrewTypeObj(),
|
||||||
|
$this->inheritBuffObj,
|
||||||
], $this->itemObjs) as $iObj){
|
], $this->itemObjs) as $iObj){
|
||||||
if(!$iObj){
|
if(!$iObj){
|
||||||
continue;
|
continue;
|
||||||
@@ -927,6 +964,7 @@ class General implements iAction{
|
|||||||
$this->specialWarObj,
|
$this->specialWarObj,
|
||||||
$this->personalityObj,
|
$this->personalityObj,
|
||||||
$this->getCrewTypeObj(),
|
$this->getCrewTypeObj(),
|
||||||
|
$this->inheritBuffObj,
|
||||||
], $this->itemObjs) as $iObj){
|
], $this->itemObjs) as $iObj){
|
||||||
if(!$iObj){
|
if(!$iObj){
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ trait LazyVarUpdater{
|
|||||||
function getRaw(bool $extractAux=false):array{
|
function getRaw(bool $extractAux=false):array{
|
||||||
if($extractAux){
|
if($extractAux){
|
||||||
$this->getAuxVar('');
|
$this->getAuxVar('');
|
||||||
|
|
||||||
}
|
}
|
||||||
return $this->raw;
|
return $this->raw;
|
||||||
}
|
}
|
||||||
@@ -58,7 +58,7 @@ trait LazyVarUpdater{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if($var === null){
|
if($var === null){
|
||||||
unset($this->auxVar[$key]);
|
unset($this->raw['auxVar'][$key]);
|
||||||
$this->auxUpdated = true;
|
$this->auxUpdated = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,130 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace sammo;
|
||||||
|
|
||||||
|
class TriggerInheritBuff implements iAction
|
||||||
|
{
|
||||||
|
use DefaultAction;
|
||||||
|
|
||||||
|
//TODO Ratio와 Prob 혼용 중지
|
||||||
|
const WAR_AVOID_RATIO = 'warAvoidRatio';
|
||||||
|
const WAR_CRITICAL_RATIO = 'warCriticalRatio';
|
||||||
|
const WAR_MAGIC_TRIAL_PROB = 'warMagicTrialProb';
|
||||||
|
const DOMESTIC_SUCCESS_PROB = 'domesticSuccessProb';
|
||||||
|
const DOMESTIC_FAIL_PROB = 'domesticFailProb';
|
||||||
|
const OPPOSE_WAR_AVOID_RATIO = 'warAvoidRatioOppose';
|
||||||
|
const OPPOSE_WAR_CRITICAL_RATIO = 'warCriticalRatioOppose';
|
||||||
|
const OPPOSE_WAR_MAGIC_TRIAL_PROB = 'warMagicTrialProbOppose';
|
||||||
|
|
||||||
|
const MAX_STEP = 5;
|
||||||
|
|
||||||
|
const BUFF_KEY_MAP = [
|
||||||
|
self::WAR_AVOID_RATIO => 'warAvoidRatio',
|
||||||
|
self::WAR_CRITICAL_RATIO => 'warCriticalRatio',
|
||||||
|
self::WAR_MAGIC_TRIAL_PROB => 'warMagicTrialProb',
|
||||||
|
|
||||||
|
self::DOMESTIC_SUCCESS_PROB => 'success',
|
||||||
|
self::DOMESTIC_FAIL_PROB => 'fail',
|
||||||
|
|
||||||
|
self::OPPOSE_WAR_AVOID_RATIO => 'warAvoidRatio',
|
||||||
|
self::OPPOSE_WAR_CRITICAL_RATIO => 'warCriticalRatio',
|
||||||
|
self::OPPOSE_WAR_MAGIC_TRIAL_PROB => 'warMagicTrialProb',
|
||||||
|
];
|
||||||
|
|
||||||
|
const CALC_DOMESTIC = [
|
||||||
|
self::BUFF_KEY_MAP[self::DOMESTIC_SUCCESS_PROB] => [self::DOMESTIC_SUCCESS_PROB, 0.01],
|
||||||
|
self::BUFF_KEY_MAP[self::DOMESTIC_FAIL_PROB] => [self::DOMESTIC_FAIL_PROB, -0.01],
|
||||||
|
];
|
||||||
|
|
||||||
|
const CALC_STAT = [
|
||||||
|
self::BUFF_KEY_MAP[self::WAR_AVOID_RATIO] => [self::WAR_AVOID_RATIO, 0.01],
|
||||||
|
self::BUFF_KEY_MAP[self::WAR_CRITICAL_RATIO] => [self::WAR_CRITICAL_RATIO, 0.01],
|
||||||
|
self::BUFF_KEY_MAP[self::WAR_MAGIC_TRIAL_PROB] => [self::WAR_MAGIC_TRIAL_PROB, 0.01],
|
||||||
|
];
|
||||||
|
|
||||||
|
const CALC_OPPOSE_STAT = [
|
||||||
|
self::BUFF_KEY_MAP[self::OPPOSE_WAR_AVOID_RATIO] => [self::OPPOSE_WAR_AVOID_RATIO, -0.01],
|
||||||
|
self::BUFF_KEY_MAP[self::OPPOSE_WAR_CRITICAL_RATIO] => [self::OPPOSE_WAR_CRITICAL_RATIO, -0.01],
|
||||||
|
self::BUFF_KEY_MAP[self::OPPOSE_WAR_MAGIC_TRIAL_PROB] => [self::OPPOSE_WAR_MAGIC_TRIAL_PROB, -0.01],
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
const BUFF_KEY_TEXT = [
|
||||||
|
self::WAR_AVOID_RATIO => '회피 확률 증가',
|
||||||
|
self::WAR_CRITICAL_RATIO => '필살 확률 증가',
|
||||||
|
self::WAR_MAGIC_TRIAL_PROB => '전투계략 시도 확률 증가',
|
||||||
|
|
||||||
|
self::DOMESTIC_SUCCESS_PROB => '내정 성공률 증가',
|
||||||
|
self::DOMESTIC_FAIL_PROB => '내정 실패율 감소',
|
||||||
|
|
||||||
|
self::OPPOSE_WAR_AVOID_RATIO => '상대 회피 확률 감소',
|
||||||
|
self::OPPOSE_WAR_CRITICAL_RATIO => '상대 필살 확률 감소',
|
||||||
|
self::OPPOSE_WAR_MAGIC_TRIAL_PROB => '상대 전투계략 시도 확률 감소',
|
||||||
|
];
|
||||||
|
|
||||||
|
const DOMESTIC_TARGET = [
|
||||||
|
'상업' => 1,
|
||||||
|
'농업' => 1,
|
||||||
|
'치안' => 1,
|
||||||
|
'성벽' => 1,
|
||||||
|
'수비' => 1,
|
||||||
|
'민심' => 1,
|
||||||
|
'인구' => 1,
|
||||||
|
'기술' => 1,
|
||||||
|
];
|
||||||
|
|
||||||
|
protected array $inheritBuffList;
|
||||||
|
|
||||||
|
public function __construct(array $inheritBuffList)
|
||||||
|
{
|
||||||
|
$this->inheritBuffList = $inheritBuffList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux = null): float
|
||||||
|
{
|
||||||
|
if (count($this->inheritBuffList) == 0) {
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
if (!key_exists($turnType, self::DOMESTIC_TARGET)) {
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
if(!key_exists($varType, static::CALC_DOMESTIC)){
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
[$iKey, $coeff] = static::CALC_DOMESTIC[$varType];
|
||||||
|
if(!key_exists($iKey, $this->inheritBuffList)){
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
return $value + $coeff * $this->inheritBuffList[$iKey];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onCalcStat(General $general, string $statName, $value, $aux = null)
|
||||||
|
{
|
||||||
|
if (count($this->inheritBuffList) == 0) {
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
if(!key_exists($statName, static::CALC_STAT)){
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
[$iKey, $coeff] = static::CALC_STAT[$statName];
|
||||||
|
if(!key_exists($iKey, $this->inheritBuffList)){
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
return $value + $coeff * $this->inheritBuffList[$iKey];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onCalcOpposeStat(General $general, string $statName, $value, $aux = null)
|
||||||
|
{
|
||||||
|
if (count($this->inheritBuffList) == 0) {
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
if(!key_exists($statName, static::CALC_OPPOSE_STAT)){
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
[$iKey, $coeff] = static::CALC_OPPOSE_STAT[$statName];
|
||||||
|
if(!key_exists($iKey, $this->inheritBuffList)){
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
return $value + $coeff * $this->inheritBuffList[$iKey];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace sammo;
|
namespace sammo;
|
||||||
|
|
||||||
use \Symfony\Component\Lock;
|
use \Symfony\Component\Lock;
|
||||||
|
|
||||||
class TurnExecutionHelper
|
class TurnExecutionHelper
|
||||||
{
|
{
|
||||||
/** @var General*/
|
/** @var General*/
|
||||||
@@ -17,16 +19,19 @@ class TurnExecutionHelper
|
|||||||
$this->applyDB();
|
$this->applyDB();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function applyDB(){
|
public function applyDB()
|
||||||
|
{
|
||||||
$db = DB::db();
|
$db = DB::db();
|
||||||
$this->generalObj->applyDB($db);
|
$this->generalObj->applyDB($db);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getGeneral():General{
|
public function getGeneral(): General
|
||||||
|
{
|
||||||
return $this->generalObj;
|
return $this->generalObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function preprocessCommand(array $env){
|
public function preprocessCommand(array $env)
|
||||||
|
{
|
||||||
$general = $this->getGeneral();
|
$general = $this->getGeneral();
|
||||||
$caller = $general->getPreTurnExecuteTriggerList($general);
|
$caller = $general->getPreTurnExecuteTriggerList($general);
|
||||||
$caller->merge(new GeneralTriggerCaller(
|
$caller->merge(new GeneralTriggerCaller(
|
||||||
@@ -37,37 +42,37 @@ class TurnExecutionHelper
|
|||||||
$caller->fire($env);
|
$caller->fire($env);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function processBlocked():bool{
|
public function processBlocked(): bool
|
||||||
|
{
|
||||||
$general = $this->getGeneral();
|
$general = $this->getGeneral();
|
||||||
|
|
||||||
$blocked = $general->getVar('block');
|
$blocked = $general->getVar('block');
|
||||||
if($blocked < 2){
|
if ($blocked < 2) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$date = $general->getTurnTime($general::TURNTIME_HM);
|
$date = $general->getTurnTime($general::TURNTIME_HM);
|
||||||
$logger = $general->getLogger();
|
$logger = $general->getLogger();
|
||||||
if($blocked == 2){
|
if ($blocked == 2) {
|
||||||
$general->increaseVarWithLimit('killturn', -1, 0);
|
$general->increaseVarWithLimit('killturn', -1, 0);
|
||||||
$logger->pushGeneralActionLog("현재 멀티, 또는 비매너로 인한<R>블럭</> 대상자입니다. <1>$date</>");
|
$logger->pushGeneralActionLog("현재 멀티, 또는 비매너로 인한<R>블럭</> 대상자입니다. <1>$date</>");
|
||||||
}
|
} else if ($blocked == 3) {
|
||||||
else if($blocked == 3){
|
|
||||||
$general->increaseVarWithLimit('killturn', -1, 0);
|
$general->increaseVarWithLimit('killturn', -1, 0);
|
||||||
$logger->pushGeneralActionLog("현재 악성유저로 분류되어 <R>블럭</> 대상자입니다. <1>$date</>");
|
$logger->pushGeneralActionLog("현재 악성유저로 분류되어 <R>블럭</> 대상자입니다. <1>$date</>");
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
//Hmm?
|
//Hmm?
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function processNationCommand(Command\NationCommand $commandObj):LastTurn{
|
public function processNationCommand(Command\NationCommand $commandObj): LastTurn
|
||||||
|
{
|
||||||
$general = $this->getGeneral();
|
$general = $this->getGeneral();
|
||||||
|
|
||||||
while(true){
|
while (true) {
|
||||||
if(!$commandObj->hasFullConditionMet()){
|
if (!$commandObj->hasFullConditionMet()) {
|
||||||
$date = $general->getTurnTime($general::TURNTIME_HM);
|
$date = $general->getTurnTime($general::TURNTIME_HM);
|
||||||
$failString = $commandObj->getFailString();
|
$failString = $commandObj->getFailString();
|
||||||
$text = "{$failString} <1>{$date}</>";
|
$text = "{$failString} <1>{$date}</>";
|
||||||
@@ -75,7 +80,7 @@ class TurnExecutionHelper
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!$commandObj->addTermStack()){
|
if (!$commandObj->addTermStack()) {
|
||||||
$date = $general->getTurnTime($general::TURNTIME_HM);
|
$date = $general->getTurnTime($general::TURNTIME_HM);
|
||||||
$termString = $commandObj->getTermString();
|
$termString = $commandObj->getTermString();
|
||||||
$text = "{$termString} <1>{$date}</>";
|
$text = "{$termString} <1>{$date}</>";
|
||||||
@@ -84,14 +89,14 @@ class TurnExecutionHelper
|
|||||||
}
|
}
|
||||||
|
|
||||||
$result = $commandObj->run();
|
$result = $commandObj->run();
|
||||||
if($result){
|
if ($result) {
|
||||||
$commandObj->setNextAvailable();
|
$commandObj->setNextAvailable();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$alt = $commandObj->getAlternativeCommand();
|
$alt = $commandObj->getAlternativeCommand();
|
||||||
if($alt === null){
|
if ($alt === null) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
$commandObj = $alt;
|
$commandObj = $alt;
|
||||||
@@ -101,7 +106,8 @@ class TurnExecutionHelper
|
|||||||
return $commandObj->getResultTurn();
|
return $commandObj->getResultTurn();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function processCommand(Command\GeneralCommand $commandObj, bool $autorunMode){
|
public function processCommand(Command\GeneralCommand $commandObj, bool $autorunMode)
|
||||||
|
{
|
||||||
|
|
||||||
$general = $this->getGeneral();
|
$general = $this->getGeneral();
|
||||||
|
|
||||||
@@ -109,16 +115,16 @@ class TurnExecutionHelper
|
|||||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||||
$commandClassName = $commandObj->getName();
|
$commandClassName = $commandObj->getName();
|
||||||
|
|
||||||
while(true){
|
while (true) {
|
||||||
if(!$commandObj->hasFullConditionMet()){
|
if (!$commandObj->hasFullConditionMet()) {
|
||||||
$date = $general->getTurnTime($general::TURNTIME_HM);
|
$date = $general->getTurnTime($general::TURNTIME_HM);
|
||||||
$failString = $commandObj->getFailString();
|
$failString = $commandObj->getFailString();
|
||||||
$text = "{$failString} <1>{$date}</>";
|
$text = "{$failString} <1>{$date}</>";
|
||||||
$general->getLogger()->pushGeneralActionLog($text);
|
$general->getLogger()->pushGeneralActionLog($text);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!$commandObj->addTermStack()){
|
if (!$commandObj->addTermStack()) {
|
||||||
$date = $general->getTurnTime($general::TURNTIME_HM);
|
$date = $general->getTurnTime($general::TURNTIME_HM);
|
||||||
$termString = $commandObj->getTermString();
|
$termString = $commandObj->getTermString();
|
||||||
$text = "{$termString} <1>{$date}</>";
|
$text = "{$termString} <1>{$date}</>";
|
||||||
@@ -127,43 +133,40 @@ class TurnExecutionHelper
|
|||||||
}
|
}
|
||||||
|
|
||||||
$result = $commandObj->run();
|
$result = $commandObj->run();
|
||||||
if($result){
|
if ($result) {
|
||||||
$commandObj->setNextAvailable();
|
$commandObj->setNextAvailable();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
$alt = $commandObj->getAlternativeCommand();
|
$alt = $commandObj->getAlternativeCommand();
|
||||||
if($alt === null){
|
if ($alt === null) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
$commandObj = $alt;
|
$commandObj = $alt;
|
||||||
$commandClassName = $alt->getName();
|
$commandClassName = $alt->getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$general->clearActivatedSkill();
|
$general->clearActivatedSkill();
|
||||||
|
|
||||||
$killTurn = $gameStor->killturn;
|
$killTurn = $gameStor->killturn;
|
||||||
|
|
||||||
if($general->getNPCType() >= 2){
|
if ($general->getNPCType() >= 2) {
|
||||||
$general->increaseVarWithLimit('killturn', -1);
|
$general->increaseVarWithLimit('killturn', -1);
|
||||||
}
|
} else if ($general->getVar('killturn') > $killTurn) {
|
||||||
else if($general->getVar('killturn') > $killTurn){
|
|
||||||
$general->increaseVarWithLimit('killturn', -1);
|
$general->increaseVarWithLimit('killturn', -1);
|
||||||
}
|
} else if ($autorunMode) {
|
||||||
else if($autorunMode){
|
|
||||||
$general->increaseVarWithLimit('killturn', -1);
|
$general->increaseVarWithLimit('killturn', -1);
|
||||||
}
|
} else if ($commandClassName == '휴식') {
|
||||||
else if($commandClassName == '휴식'){
|
|
||||||
$general->increaseVarWithLimit('killturn', -1);
|
$general->increaseVarWithLimit('killturn', -1);
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
$general->setVar('killturn', $killTurn);
|
$general->setVar('killturn', $killTurn);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $commandObj->getResultTurn();
|
return $commandObj->getResultTurn();
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateTurnTime(){
|
function updateTurnTime()
|
||||||
|
{
|
||||||
$db = DB::db();
|
$db = DB::db();
|
||||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||||
|
|
||||||
@@ -175,13 +178,13 @@ class TurnExecutionHelper
|
|||||||
$generalName = $general->getName();
|
$generalName = $general->getName();
|
||||||
|
|
||||||
// 삭턴장수 삭제처리
|
// 삭턴장수 삭제처리
|
||||||
if($general->getVar('killturn') <= 0){
|
if ($general->getVar('killturn') <= 0) {
|
||||||
// npc유저 삭턴시 npc로 전환
|
// npc유저 삭턴시 npc로 전환
|
||||||
if($general->getNPCType() == 1 && $general->getVar('deadyear') > $gameStor->year){
|
if ($general->getNPCType() == 1 && $general->getVar('deadyear') > $gameStor->year) {
|
||||||
|
|
||||||
$ownerName = $general->getVar('owner_name');
|
$ownerName = $general->getVar('owner_name');
|
||||||
$josaYi = JosaUtil::pick($ownerName, '이');
|
$josaYi = JosaUtil::pick($ownerName, '이');
|
||||||
|
|
||||||
$logger->pushGlobalActionLog("{$ownerName}</>{$josaYi} <Y>{$generalName}</>의 육체에서 <S>유체이탈</>합니다!");
|
$logger->pushGlobalActionLog("{$ownerName}</>{$josaYi} <Y>{$generalName}</>의 육체에서 <S>유체이탈</>합니다!");
|
||||||
|
|
||||||
$general->setVar('killturn', ($general->getVar('deadyear') - $gameStor->year) * 12);
|
$general->setVar('killturn', ($general->getVar('deadyear') - $gameStor->year) * 12);
|
||||||
@@ -189,8 +192,7 @@ class TurnExecutionHelper
|
|||||||
$general->setVar('owner', 0);
|
$general->setVar('owner', 0);
|
||||||
$general->setVar('defence_train', 80);
|
$general->setVar('defence_train', 80);
|
||||||
$general->setVar('owner_name', null);
|
$general->setVar('owner_name', null);
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
$general->applyDB($db);
|
$general->applyDB($db);
|
||||||
storeOldGeneral($generalID, $gameStor->year, $gameStor->month);
|
storeOldGeneral($generalID, $gameStor->year, $gameStor->month);
|
||||||
$general->kill($db);
|
$general->kill($db);
|
||||||
@@ -199,8 +201,8 @@ class TurnExecutionHelper
|
|||||||
}
|
}
|
||||||
|
|
||||||
//은퇴
|
//은퇴
|
||||||
if($general->getVar('age') >= GameConst::$retirementYear && $general->getNPCType() == 0) {
|
if ($general->getVar('age') >= GameConst::$retirementYear && $general->getNPCType() == 0) {
|
||||||
if($gameStor->isunited == 0) {
|
if ($gameStor->isunited == 0) {
|
||||||
$general->applyDB($db);
|
$general->applyDB($db);
|
||||||
CheckHall($generalID);
|
CheckHall($generalID);
|
||||||
}
|
}
|
||||||
@@ -210,11 +212,11 @@ class TurnExecutionHelper
|
|||||||
|
|
||||||
$turntime = addTurn($general->getTurnTime(), $gameStor->turnterm);
|
$turntime = addTurn($general->getTurnTime(), $gameStor->turnterm);
|
||||||
$general->setVar('turntime', $turntime);
|
$general->setVar('turntime', $turntime);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static public function executeGeneralCommandUntil(string $date, \DateTimeInterface $limitActionTime, int $year, int $month){
|
static public function executeGeneralCommandUntil(string $date, \DateTimeInterface $limitActionTime, int $year, int $month)
|
||||||
|
{
|
||||||
$db = DB::db();
|
$db = DB::db();
|
||||||
$generalsTodo = $db->query(
|
$generalsTodo = $db->query(
|
||||||
'SELECT no,name,turntime,killturn,block,npc,deadyear FROM general WHERE turntime < %s ORDER BY turntime ASC, `no` ASC',
|
'SELECT no,name,turntime,killturn,block,npc,deadyear FROM general WHERE turntime < %s ORDER BY turntime ASC, `no` ASC',
|
||||||
@@ -226,9 +228,9 @@ class TurnExecutionHelper
|
|||||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||||
$autorun_user = $gameStor->autorun_user;
|
$autorun_user = $gameStor->autorun_user;
|
||||||
|
|
||||||
foreach($generalsTodo as $rawGeneral){
|
foreach ($generalsTodo as $rawGeneral) {
|
||||||
$currActionTime = new \DateTimeImmutable();
|
$currActionTime = new \DateTimeImmutable();
|
||||||
if($currActionTime > $limitActionTime){
|
if ($currActionTime > $limitActionTime) {
|
||||||
return [true, $currentTurn];
|
return [true, $currentTurn];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,7 +240,7 @@ class TurnExecutionHelper
|
|||||||
$env = $gameStor->getAll(true);
|
$env = $gameStor->getAll(true);
|
||||||
|
|
||||||
$hasNationTurn = false;
|
$hasNationTurn = false;
|
||||||
if($general->getVar('nation') != 0 && $general->getVar('officer_level') >= 5){
|
if ($general->getVar('nation') != 0 && $general->getVar('officer_level') >= 5) {
|
||||||
$nationStor = KVStorage::getStorage($db, $general->getNationID(), 'nation_env');
|
$nationStor = KVStorage::getStorage($db, $general->getNationID(), 'nation_env');
|
||||||
$lastNationTurnKey = "turn_last_{$general->getVar('officer_level')}";
|
$lastNationTurnKey = "turn_last_{$general->getVar('officer_level')}";
|
||||||
//수뇌 몇 없는데 매번 left join 하는건 낭비인것 같다.
|
//수뇌 몇 없는데 매번 left join 하는건 낭비인것 같다.
|
||||||
@@ -246,10 +248,10 @@ class TurnExecutionHelper
|
|||||||
'SELECT action, arg FROM nation_turn WHERE nation_id = %i AND officer_level = %i AND turn_idx =0',
|
'SELECT action, arg FROM nation_turn WHERE nation_id = %i AND officer_level = %i AND turn_idx =0',
|
||||||
$general->getVar('nation'),
|
$general->getVar('nation'),
|
||||||
$general->getVar('officer_level')
|
$general->getVar('officer_level')
|
||||||
)??[];
|
) ?? [];
|
||||||
$hasNationTurn = true;
|
$hasNationTurn = true;
|
||||||
$nationCommand = $rawNationTurn['action']??null;
|
$nationCommand = $rawNationTurn['action'] ?? null;
|
||||||
$nationArg = Json::decode($rawNationTurn['arg']??null);
|
$nationArg = Json::decode($rawNationTurn['arg'] ?? null);
|
||||||
$lastNationTurn = LastTurn::fromRaw($nationStor->getValue($lastNationTurnKey));
|
$lastNationTurn = LastTurn::fromRaw($nationStor->getValue($lastNationTurnKey));
|
||||||
$nationCommandObj = buildNationCommandClass($nationCommand, $general, $env, $lastNationTurn, $nationArg);
|
$nationCommandObj = buildNationCommandClass($nationCommand, $general, $env, $lastNationTurn, $nationArg);
|
||||||
}
|
}
|
||||||
@@ -260,16 +262,15 @@ class TurnExecutionHelper
|
|||||||
$general->increaseInheritancePoint('lived_month', 1);
|
$general->increaseInheritancePoint('lived_month', 1);
|
||||||
|
|
||||||
$turnObj->preprocessCommand($env);
|
$turnObj->preprocessCommand($env);
|
||||||
$generalCommandObj = $general->getReservedTurn(0, $env);
|
|
||||||
|
|
||||||
if($general->getNPCType() >= 2 || ($autorun_user['limit_minutes']??false)){
|
if ($general->getNPCType() >= 2 || ($autorun_user['limit_minutes'] ?? false)) {
|
||||||
$ai = new GeneralAI($turnObj->getGeneral());
|
$ai = new GeneralAI($turnObj->getGeneral());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!$turnObj->processBlocked()){
|
if (!$turnObj->processBlocked()) {
|
||||||
|
|
||||||
if($hasNationTurn){
|
if ($hasNationTurn) {
|
||||||
if($ai && ($general->getAuxVar('use_auto_nation_turn')??1)){
|
if ($ai && ($general->getAuxVar('use_auto_nation_turn') ?? 1)) {
|
||||||
$nationCommandObj = $ai->chooseNationTurn($nationCommandObj);
|
$nationCommandObj = $ai->chooseNationTurn($nationCommandObj);
|
||||||
$cityName = CityConst::byID($general->getCityID())->name;
|
$cityName = CityConst::byID($general->getCityID())->name;
|
||||||
LogText("NationTurn", "General, {$general->getName()}, {$general->getID()}, {$cityName}, {$general->getStaticNation()['name']}, {$nationCommandObj->getBrief()}, {$nationCommandObj->reason}, ");
|
LogText("NationTurn", "General, {$general->getName()}, {$general->getID()}, {$cityName}, {$general->getStaticNation()['name']}, {$nationCommandObj->getBrief()}, {$nationCommandObj->reason}, ");
|
||||||
@@ -278,18 +279,21 @@ class TurnExecutionHelper
|
|||||||
$nationCommandObj
|
$nationCommandObj
|
||||||
);
|
);
|
||||||
$nationStor->setValue($lastNationTurnKey, $resultNationTurn->toRaw());
|
$nationStor->setValue($lastNationTurnKey, $resultNationTurn->toRaw());
|
||||||
|
$general->setRawCity(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if($ai){
|
$generalCommandObj = $general->getReservedTurn(0, $env);
|
||||||
|
|
||||||
|
if ($ai) {
|
||||||
$newGeneralCommandObj = $ai->chooseGeneralTurn($generalCommandObj); // npc AI 처리
|
$newGeneralCommandObj = $ai->chooseGeneralTurn($generalCommandObj); // npc AI 처리
|
||||||
if($generalCommandObj !== $newGeneralCommandObj){
|
if ($generalCommandObj !== $newGeneralCommandObj) {
|
||||||
$autorunMode = true;
|
$autorunMode = true;
|
||||||
$generalCommandObj = $newGeneralCommandObj;
|
$generalCommandObj = $newGeneralCommandObj;
|
||||||
}
|
}
|
||||||
$cityName = CityConst::byID($general->getCityID())->name;
|
$cityName = CityConst::byID($general->getCityID())->name;
|
||||||
LogText("turn", "General, {$general->getName()}, {$general->getID()}, {$cityName}, {$general->getStaticNation()['name']}, {$generalCommandObj->getBrief()}, {$generalCommandObj->reason}, ");
|
LogText("turn", "General, {$general->getName()}, {$general->getID()}, {$cityName}, {$general->getStaticNation()['name']}, {$generalCommandObj->getBrief()}, {$generalCommandObj->reason}, ");
|
||||||
}
|
}
|
||||||
|
|
||||||
$turnObj->processCommand($generalCommandObj, $autorunMode);
|
$turnObj->processCommand($generalCommandObj, $autorunMode);
|
||||||
}
|
}
|
||||||
pullNationCommand($general->getVar('nation'), $general->getVar('officer_level'));
|
pullNationCommand($general->getVar('nation'), $general->getVar('officer_level'));
|
||||||
@@ -300,26 +304,25 @@ class TurnExecutionHelper
|
|||||||
|
|
||||||
$turnObj->updateTurnTime();
|
$turnObj->updateTurnTime();
|
||||||
$turnObj->applyDB();
|
$turnObj->applyDB();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return [false, $currentTurn];
|
return [false, $currentTurn];
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function executeAllCommand(){
|
static public function executeAllCommand()
|
||||||
|
{
|
||||||
//if(!timeover()) { return; }
|
//if(!timeover()) { return; }
|
||||||
|
|
||||||
$db = DB::db();
|
$db = DB::db();
|
||||||
|
|
||||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||||
|
|
||||||
if(TimeUtil::now(true) < $gameStor->turntime){
|
if (TimeUtil::now(true) < $gameStor->turntime) {
|
||||||
//턴 시각 이전이면 아무것도 하지 않음
|
//턴 시각 이전이면 아무것도 하지 않음
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!tryLock()){
|
if (!tryLock()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -342,13 +345,12 @@ class TurnExecutionHelper
|
|||||||
$nextTurn = addTurn($prevTurn, $gameStor->turnterm);
|
$nextTurn = addTurn($prevTurn, $gameStor->turnterm);
|
||||||
|
|
||||||
$maxActionTime = Util::toInt(ini_get('max_execution_time'));
|
$maxActionTime = Util::toInt(ini_get('max_execution_time'));
|
||||||
if($maxActionTime == 0){
|
if ($maxActionTime == 0) {
|
||||||
$maxActionTime = 60;
|
$maxActionTime = 60;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
$maxActionTime = max($maxActionTime * 2 / 3, $maxActionTime - 10);
|
$maxActionTime = max($maxActionTime * 2 / 3, $maxActionTime - 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
$limitActionTime = (new \DateTimeImmutable())->add(TimeUtil::secondsToDateInterval($maxActionTime));
|
$limitActionTime = (new \DateTimeImmutable())->add(TimeUtil::secondsToDateInterval($maxActionTime));
|
||||||
|
|
||||||
// 현재 턴 이전 월턴까지 모두처리.
|
// 현재 턴 이전 월턴까지 모두처리.
|
||||||
@@ -356,23 +358,26 @@ class TurnExecutionHelper
|
|||||||
while ($nextTurn <= $date) {
|
while ($nextTurn <= $date) {
|
||||||
|
|
||||||
[$executionOver, $currentTurn] = static::executeGeneralCommandUntil(
|
[$executionOver, $currentTurn] = static::executeGeneralCommandUntil(
|
||||||
$nextTurn, $limitActionTime, $gameStor->year, $gameStor->month
|
$nextTurn,
|
||||||
|
$limitActionTime,
|
||||||
|
$gameStor->year,
|
||||||
|
$gameStor->month
|
||||||
);
|
);
|
||||||
|
|
||||||
// 트래픽 업데이트
|
// 트래픽 업데이트
|
||||||
updateTraffic();
|
updateTraffic();
|
||||||
|
|
||||||
if($executionOver){
|
if ($executionOver) {
|
||||||
if($currentTurn !== null){
|
if ($currentTurn !== null) {
|
||||||
$gameStor->turntime = $currentTurn;
|
$gameStor->turntime = $currentTurn;
|
||||||
}
|
}
|
||||||
unlock();
|
unlock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 1달마다 처리하는 것들, 벌점 감소 및 건국,전턴,합병 -1, 군량 소모
|
// 1달마다 처리하는 것들, 벌점 감소 및 건국,전턴,합병 -1, 군량 소모
|
||||||
if(!preUpdateMonthly()){
|
if (!preUpdateMonthly()) {
|
||||||
$gameStor->resetCache(true);
|
$gameStor->resetCache(true);
|
||||||
unlock();
|
unlock();
|
||||||
throw new \RuntimeException('preUpdateMonthly() 처리 에러');
|
throw new \RuntimeException('preUpdateMonthly() 처리 에러');
|
||||||
@@ -383,7 +388,7 @@ class TurnExecutionHelper
|
|||||||
$logger = new ActionLogger(0, 0, $gameStor->year, $gameStor->month, false);
|
$logger = new ActionLogger(0, 0, $gameStor->year, $gameStor->month, false);
|
||||||
|
|
||||||
// 분기계산. 장수들 턴보다 먼저 있다면 먼저처리
|
// 분기계산. 장수들 턴보다 먼저 있다면 먼저처리
|
||||||
if($gameStor->month == 1) {
|
if ($gameStor->month == 1) {
|
||||||
processSpring();
|
processSpring();
|
||||||
processGoldIncome();
|
processGoldIncome();
|
||||||
updateYearly();
|
updateYearly();
|
||||||
@@ -394,16 +399,16 @@ class TurnExecutionHelper
|
|||||||
// 새해 알림
|
// 새해 알림
|
||||||
$logger->pushGlobalActionLog("<C>{$gameStor->year}</>년이 되었습니다.");
|
$logger->pushGlobalActionLog("<C>{$gameStor->year}</>년이 되었습니다.");
|
||||||
$logger->flush(); //TODO: globalAction류는 전역에서 관리하는것이 좋을 듯.
|
$logger->flush(); //TODO: globalAction류는 전역에서 관리하는것이 좋을 듯.
|
||||||
} elseif($gameStor->month == 4) {
|
} elseif ($gameStor->month == 4) {
|
||||||
updateQuaterly();
|
updateQuaterly();
|
||||||
disaster();
|
disaster();
|
||||||
} elseif($gameStor->month == 7) {
|
} elseif ($gameStor->month == 7) {
|
||||||
processFall();
|
processFall();
|
||||||
processRiceIncome();
|
processRiceIncome();
|
||||||
updateQuaterly();
|
updateQuaterly();
|
||||||
disaster();
|
disaster();
|
||||||
tradeRate();
|
tradeRate();
|
||||||
} elseif($gameStor->month == 10) {
|
} elseif ($gameStor->month == 10) {
|
||||||
updateQuaterly();
|
updateQuaterly();
|
||||||
disaster();
|
disaster();
|
||||||
}
|
}
|
||||||
@@ -411,7 +416,7 @@ class TurnExecutionHelper
|
|||||||
// 이벤트 핸들러 동작
|
// 이벤트 핸들러 동작
|
||||||
$e_env = null;
|
$e_env = null;
|
||||||
foreach (DB::db()->query('SELECT * from event') as $rawEvent) {
|
foreach (DB::db()->query('SELECT * from event') as $rawEvent) {
|
||||||
if($e_env === null){
|
if ($e_env === null) {
|
||||||
$e_env = $gameStor->getAll(false);
|
$e_env = $gameStor->getAll(false);
|
||||||
}
|
}
|
||||||
$eventID = $rawEvent['id'];
|
$eventID = $rawEvent['id'];
|
||||||
@@ -423,7 +428,7 @@ class TurnExecutionHelper
|
|||||||
$event->tryRunEvent($e_env);
|
$event->tryRunEvent($e_env);
|
||||||
}
|
}
|
||||||
|
|
||||||
if($e_env !== null){
|
if ($e_env !== null) {
|
||||||
$gameStor->resetCache(true);
|
$gameStor->resetCache(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -440,13 +445,16 @@ class TurnExecutionHelper
|
|||||||
// 현재시간의 월턴시간 이후 분단위 장수 처리
|
// 현재시간의 월턴시간 이후 분단위 장수 처리
|
||||||
|
|
||||||
[$executionOver, $currentTurn] = static::executeGeneralCommandUntil(
|
[$executionOver, $currentTurn] = static::executeGeneralCommandUntil(
|
||||||
$date, $limitActionTime, $gameStor->year, $gameStor->month
|
$date,
|
||||||
|
$limitActionTime,
|
||||||
|
$gameStor->year,
|
||||||
|
$gameStor->month
|
||||||
);
|
);
|
||||||
|
|
||||||
if($currentTurn !== null){
|
if ($currentTurn !== null) {
|
||||||
$gameStor->turntime = $currentTurn;
|
$gameStor->turntime = $currentTurn;
|
||||||
}
|
}
|
||||||
|
|
||||||
//토너먼트 처리
|
//토너먼트 처리
|
||||||
processTournament();
|
processTournament();
|
||||||
//거래 처리
|
//거래 처리
|
||||||
@@ -455,4 +463,4 @@ class TurnExecutionHelper
|
|||||||
$gameStor->resetCache(true);
|
$gameStor->resetCache(true);
|
||||||
unlock();
|
unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+118
-88
@@ -1,10 +1,13 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace sammo;
|
namespace sammo;
|
||||||
|
|
||||||
class WarUnitGeneral extends WarUnit{
|
class WarUnitGeneral extends WarUnit
|
||||||
|
{
|
||||||
protected $raw;
|
protected $raw;
|
||||||
|
|
||||||
function __construct(General $general, array $rawNation, bool $isAttacker){
|
function __construct(General $general, array $rawNation, bool $isAttacker)
|
||||||
|
{
|
||||||
$this->general = $general;
|
$this->general = $general;
|
||||||
$this->raw = $general->getRaw();
|
$this->raw = $general->getRaw();
|
||||||
$this->rawNation = $rawNation; //read-only
|
$this->rawNation = $rawNation; //read-only
|
||||||
@@ -15,43 +18,43 @@ class WarUnitGeneral extends WarUnit{
|
|||||||
|
|
||||||
$cityLevel = $this->getCityVar('level');
|
$cityLevel = $this->getCityVar('level');
|
||||||
|
|
||||||
if($isAttacker){
|
if ($isAttacker) {
|
||||||
//공격자 보정
|
//공격자 보정
|
||||||
if($cityLevel == 2){
|
if ($cityLevel == 2) {
|
||||||
$this->atmosBonus += 5;
|
$this->atmosBonus += 5;
|
||||||
}
|
}
|
||||||
if($rawNation['capital'] == $this->getCityVar('city')){
|
if ($rawNation['capital'] == $this->getCityVar('city')) {
|
||||||
$this->atmosBonus += 5;
|
$this->atmosBonus += 5;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
//수비자 보정
|
//수비자 보정
|
||||||
if($cityLevel == 1){
|
if ($cityLevel == 1) {
|
||||||
$this->trainBonus += 5;
|
$this->trainBonus += 5;
|
||||||
}
|
} else if ($cityLevel == 3) {
|
||||||
else if($cityLevel == 3){
|
|
||||||
$this->trainBonus += 5;
|
$this->trainBonus += 5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getName():string{
|
function getName(): string
|
||||||
|
{
|
||||||
return $this->general->getName();
|
return $this->general->getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCityVar(string $key){
|
function getCityVar(string $key)
|
||||||
|
{
|
||||||
return $this->general->getRawCity()[$key];
|
return $this->general->getRawCity()[$key];
|
||||||
}
|
}
|
||||||
|
|
||||||
function setOppose(?WarUnit $oppose){
|
function setOppose(?WarUnit $oppose)
|
||||||
|
{
|
||||||
parent::setOppose($oppose);
|
parent::setOppose($oppose);
|
||||||
$general = $this->general;
|
$general = $this->general;
|
||||||
$this->general->increaseRankVar('warnum', 1);
|
$this->general->increaseRankVar('warnum', 1);
|
||||||
|
|
||||||
if($this->isAttacker){
|
if ($this->isAttacker) {
|
||||||
$semiTurn = $general->getTurnTime();
|
$semiTurn = $general->getTurnTime();
|
||||||
}
|
} else if ($oppose !== null) {
|
||||||
else if($oppose !== null){
|
|
||||||
$semiTurn = $oppose->getGeneral()->getTurnTime();
|
$semiTurn = $oppose->getGeneral()->getTurnTime();
|
||||||
}
|
}
|
||||||
$phase = $this->getRealPhase();
|
$phase = $this->getRealPhase();
|
||||||
@@ -60,75 +63,94 @@ class WarUnitGeneral extends WarUnit{
|
|||||||
$general->setVar('recent_war', $semiTurn);
|
$general->setVar('recent_war', $semiTurn);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getMaxPhase():int{
|
function getMaxPhase(): int
|
||||||
|
{
|
||||||
$phase = $this->getCrewType()->speed;
|
$phase = $this->getCrewType()->speed;
|
||||||
$phase = $this->general->onCalcStat($this->general, 'initWarPhase', $phase, ['isAttacker'=>$this->isAttacker]);
|
$phase = $this->general->onCalcStat($this->general, 'initWarPhase', $phase, ['isAttacker' => $this->isAttacker]);
|
||||||
|
//maxPhase는 상대가 결정되기 전에 계산되므로 oppose를 호출할 수 없음
|
||||||
return $phase + $this->bonusPhase;
|
return $phase + $this->bonusPhase;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addTrain(int $train){
|
function addTrain(int $train)
|
||||||
|
{
|
||||||
$this->general->increaseVarWithLimit('train', $train, 0, GameConst::$maxTrainByWar);
|
$this->general->increaseVarWithLimit('train', $train, 0, GameConst::$maxTrainByWar);
|
||||||
}
|
}
|
||||||
|
|
||||||
function addAtmos(int $atmos){
|
function addAtmos(int $atmos)
|
||||||
|
{
|
||||||
$this->general->increaseVarWithLimit('atmos', $atmos, 0, GameConst::$maxAtmosByWar);
|
$this->general->increaseVarWithLimit('atmos', $atmos, 0, GameConst::$maxAtmosByWar);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDex(GameUnitDetail $crewType){
|
function getDex(GameUnitDetail $crewType)
|
||||||
$rawDex = $this->general->getDex($crewType);
|
{
|
||||||
return $this->general->onCalcStat($this->general, 'dex'.$crewType->armType, $rawDex, [
|
$dex = $this->general->getDex($crewType);
|
||||||
'isAttacker'=>$this->isAttacker,
|
$dex = $this->general->onCalcStat($this->general, 'dex' . $crewType->armType, $dex, [
|
||||||
'opposeType'=>$this->oppose->getCrewType()
|
'isAttacker' => $this->isAttacker,
|
||||||
|
'opposeType' => $this->oppose->getCrewType()
|
||||||
]);
|
]);
|
||||||
|
$dex = $this->oppose->general->onCalcOpposeStat($this->general, 'dex' . $crewType->armType, $dex, [
|
||||||
|
'isAttacker' => $this->isAttacker,
|
||||||
|
'opposeType' => $this->oppose->getCrewType()
|
||||||
|
]);
|
||||||
|
return $dex;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getComputedTrain(){
|
function getComputedTrain()
|
||||||
|
{
|
||||||
$train = $this->general->getVar('train');
|
$train = $this->general->getVar('train');
|
||||||
$train = $this->general->onCalcStat($this->general, 'bonusTrain', $train, ['isAttacker'=>$this->isAttacker]);
|
$train = $this->general->onCalcStat($this->general, 'bonusTrain', $train, ['isAttacker' => $this->isAttacker]);
|
||||||
|
$train = $this->oppose->general->onCalcOpposeStat($this->general, 'bonusTrain', $train, ['isAttacker' => $this->isAttacker]);
|
||||||
$train += $this->trainBonus;
|
$train += $this->trainBonus;
|
||||||
|
|
||||||
return $train;
|
return $train;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getComputedAtmos(){
|
function getComputedAtmos()
|
||||||
|
{
|
||||||
$atmos = $this->general->getVar('atmos');
|
$atmos = $this->general->getVar('atmos');
|
||||||
$atmos = $this->general->onCalcStat($this->general, 'bonusAtmos', $atmos, ['isAttacker'=>$this->isAttacker]);
|
$atmos = $this->general->onCalcStat($this->general, 'bonusAtmos', $atmos, ['isAttacker' => $this->isAttacker]);
|
||||||
|
$atmos = $this->oppose->general->onCalcOpposeStat($this->general, 'bonusAtmos', $atmos, ['isAttacker' => $this->isAttacker]);
|
||||||
$atmos += $this->atmosBonus;
|
$atmos += $this->atmosBonus;
|
||||||
|
|
||||||
return $atmos;
|
return $atmos;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getComputedCriticalRatio():float{
|
function getComputedCriticalRatio(): float
|
||||||
|
{
|
||||||
$general = $this->general;
|
$general = $this->general;
|
||||||
$criticalRatio = $this->getCrewType()->getCriticalRatio($general);
|
$criticalRatio = $this->getCrewType()->getCriticalRatio($general);
|
||||||
|
|
||||||
/** @var float $criticalRatio */
|
/** @var float $criticalRatio */
|
||||||
$criticalRatio = $general->onCalcStat($general, 'warCriticalRatio', $criticalRatio, ['isAttacker'=>$this->isAttacker]);
|
$criticalRatio = $general->onCalcStat($general, 'warCriticalRatio', $criticalRatio, ['isAttacker' => $this->isAttacker]);
|
||||||
|
$criticalRatio = $this->oppose->general->onCalcOpposeStat($general, 'warCriticalRatio', $criticalRatio, ['isAttacker' => $this->isAttacker]);
|
||||||
return $criticalRatio;
|
return $criticalRatio;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getComputedAvoidRatio():float{
|
function getComputedAvoidRatio(): float
|
||||||
|
{
|
||||||
$general = $this->general;
|
$general = $this->general;
|
||||||
|
|
||||||
$avoidRatio = $this->getCrewType()->avoid / 100;
|
$avoidRatio = $this->getCrewType()->avoid / 100;
|
||||||
$avoidRatio *= $this->getComputedTrain() / 100;
|
$avoidRatio *= $this->getComputedTrain() / 100;
|
||||||
|
|
||||||
/** @var float $avoidRatio */
|
/** @var float $avoidRatio */
|
||||||
$avoidRatio = $general->onCalcStat($general, 'warAvoidRatio', $avoidRatio, ['isAttacker'=>$this->isAttacker]);
|
$avoidRatio = $general->onCalcStat($general, 'warAvoidRatio', $avoidRatio, ['isAttacker' => $this->isAttacker]);
|
||||||
|
$avoidRatio = $this->oppose->general->onCalcOpposeStat($general, 'warAvoidRatio', $avoidRatio, ['isAttacker' => $this->isAttacker]);
|
||||||
|
|
||||||
if($this->getOppose()->getCrewType()->armType == GameUnitConst::T_FOOTMAN){
|
if ($this->getOppose()->getCrewType()->armType == GameUnitConst::T_FOOTMAN) {
|
||||||
$avoidRatio *= 0.75;
|
$avoidRatio *= 0.75;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $avoidRatio;
|
return $avoidRatio;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addWin(){
|
function addWin()
|
||||||
|
{
|
||||||
$general = $this->general;
|
$general = $this->general;
|
||||||
$general->increaseRankVar('killnum', 1);
|
$general->increaseRankVar('killnum', 1);
|
||||||
|
|
||||||
$oppose = $this->getOppose();
|
$oppose = $this->getOppose();
|
||||||
if($oppose instanceof WarUnitCity){
|
if ($oppose instanceof WarUnitCity) {
|
||||||
$general->increaseRankVar('occupied', 1);
|
$general->increaseRankVar('occupied', 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,74 +159,74 @@ class WarUnitGeneral extends WarUnit{
|
|||||||
$this->addStatExp(1);
|
$this->addStatExp(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
function addStatExp(int $value = 1){
|
function addStatExp(int $value = 1)
|
||||||
|
{
|
||||||
$general = $this->general;
|
$general = $this->general;
|
||||||
if($this->crewType->armType == GameUnitConst::T_WIZARD) { // 귀병
|
if ($this->crewType->armType == GameUnitConst::T_WIZARD) { // 귀병
|
||||||
$general->increaseVar('intel_exp', $value);
|
$general->increaseVar('intel_exp', $value);
|
||||||
} elseif($this->crewType->armType == GameUnitConst::T_SIEGE) { // 차병
|
} elseif ($this->crewType->armType == GameUnitConst::T_SIEGE) { // 차병
|
||||||
$general->increaseVar('leadership_exp', $value);
|
$general->increaseVar('leadership_exp', $value);
|
||||||
} else {
|
} else {
|
||||||
$general->increaseVar('strength_exp', $value);
|
$general->increaseVar('strength_exp', $value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function addLevelExp(float $value){
|
function addLevelExp(float $value)
|
||||||
|
{
|
||||||
$general = $this->general;
|
$general = $this->general;
|
||||||
if(!$this->isAttacker){
|
if (!$this->isAttacker) {
|
||||||
$value *= 0.8;
|
$value *= 0.8;
|
||||||
}
|
}
|
||||||
$general->addExperience($value);
|
$general->addExperience($value);
|
||||||
}
|
}
|
||||||
|
|
||||||
function addDedication(float $value){
|
function addDedication(float $value)
|
||||||
|
{
|
||||||
$general = $this->general;
|
$general = $this->general;
|
||||||
$general->addDedication($value);
|
$general->addDedication($value);
|
||||||
}
|
}
|
||||||
|
|
||||||
function addLose(){
|
function addLose()
|
||||||
|
{
|
||||||
$general = $this->general;
|
$general = $this->general;
|
||||||
$general->increaseRankVar('deathnum', 1);
|
$general->increaseRankVar('deathnum', 1);
|
||||||
$this->addStatExp(1);
|
$this->addStatExp(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
function computeWarPower(){
|
function computeWarPower()
|
||||||
[$warPower,$opposeWarPowerMultiply] = parent::computeWarPower();
|
{
|
||||||
|
[$warPower, $opposeWarPowerMultiply] = parent::computeWarPower();
|
||||||
|
|
||||||
$general = $this->general;
|
$general = $this->general;
|
||||||
$cityID = $general->getCityID();
|
$cityID = $general->getCityID();
|
||||||
$officerLevel = $general->getVar('officer_level');
|
$officerLevel = $general->getVar('officer_level');
|
||||||
$officerCity = $general->getVar('officer_city');
|
$officerCity = $general->getVar('officer_city');
|
||||||
|
|
||||||
if($this->isAttacker){
|
if ($this->isAttacker) {
|
||||||
if($officerLevel == 12){
|
if ($officerLevel == 12) {
|
||||||
$warPower *= 1.10;
|
$warPower *= 1.10;
|
||||||
}
|
} else if ($officerLevel == 11 | $officerLevel == 10 || $officerLevel == 8 || $officerLevel == 6) {
|
||||||
else if($officerLevel == 11 | $officerLevel == 10 || $officerLevel == 8 || $officerLevel == 6){
|
|
||||||
$warPower *= 1.05;
|
$warPower *= 1.05;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else{
|
if ($officerLevel == 12) {
|
||||||
if($officerLevel == 12){
|
|
||||||
$opposeWarPowerMultiply *= 0.90;
|
$opposeWarPowerMultiply *= 0.90;
|
||||||
}
|
} else if ($officerLevel == 11 || $officerLevel == 9 || $officerLevel == 7 || $officerLevel == 5) {
|
||||||
else if($officerLevel == 11 || $officerLevel == 9 || $officerLevel == 7 || $officerLevel == 5){
|
|
||||||
$opposeWarPowerMultiply *= 0.95;
|
$opposeWarPowerMultiply *= 0.95;
|
||||||
}
|
} else if (2 <= $officerLevel && $officerLevel <= 4 && $officerCity == $cityID) {
|
||||||
else if(2 <= $officerLevel && $officerLevel <= 4 && $officerCity == $cityID){
|
|
||||||
$opposeWarPowerMultiply *= 0.95;
|
$opposeWarPowerMultiply *= 0.95;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$expLevel = $general->getVar('explevel');
|
$expLevel = $general->getVar('explevel');
|
||||||
|
|
||||||
if($this->getOppose() instanceof WarUnitCity){
|
if ($this->getOppose() instanceof WarUnitCity) {
|
||||||
$warPower *= 1 + $expLevel / 600;
|
$warPower *= 1 + $expLevel / 600;
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
$warPower /= max(0.01, 1 - $expLevel / 300);
|
$warPower /= max(0.01, 1 - $expLevel / 300);
|
||||||
$opposeWarPowerMultiply *= max(0.01, 1 - $expLevel / 300);
|
$opposeWarPowerMultiply *= max(0.01, 1 - $expLevel / 300);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[$specialMyWarPowerMultiply, $specialOpposeWarPowerMultiply] = $this->general->getWarPowerMultiplier($this);
|
[$specialMyWarPowerMultiply, $specialOpposeWarPowerMultiply] = $this->general->getWarPowerMultiplier($this);
|
||||||
$warPower *= $specialMyWarPowerMultiply;
|
$warPower *= $specialMyWarPowerMultiply;
|
||||||
@@ -212,18 +234,21 @@ class WarUnitGeneral extends WarUnit{
|
|||||||
|
|
||||||
$this->warPower = $warPower;
|
$this->warPower = $warPower;
|
||||||
$this->oppose->setWarPowerMultiply($opposeWarPowerMultiply);
|
$this->oppose->setWarPowerMultiply($opposeWarPowerMultiply);
|
||||||
return [$warPower,$opposeWarPowerMultiply];
|
return [$warPower, $opposeWarPowerMultiply];
|
||||||
}
|
}
|
||||||
|
|
||||||
function getHP():int{
|
function getHP(): int
|
||||||
|
{
|
||||||
return $this->general->getVar('crew');
|
return $this->general->getVar('crew');
|
||||||
}
|
}
|
||||||
|
|
||||||
function addDex(GameUnitDetail $crewType, float $exp){
|
function addDex(GameUnitDetail $crewType, float $exp)
|
||||||
|
{
|
||||||
$this->general->addDex($crewType, $exp, false);
|
$this->general->addDex($crewType, $exp, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
function decreaseHP(int $damage):int{
|
function decreaseHP(int $damage): int
|
||||||
|
{
|
||||||
$general = $this->general;
|
$general = $this->general;
|
||||||
$damage = min($damage, $general->getVar('crew'));
|
$damage = min($damage, $general->getVar('crew'));
|
||||||
|
|
||||||
@@ -232,7 +257,7 @@ class WarUnitGeneral extends WarUnit{
|
|||||||
$general->increaseVar('crew', -$damage);
|
$general->increaseVar('crew', -$damage);
|
||||||
|
|
||||||
$addDex = $damage;
|
$addDex = $damage;
|
||||||
if(!$this->isAttacker){
|
if (!$this->isAttacker) {
|
||||||
$addDex *= 0.9;
|
$addDex *= 0.9;
|
||||||
}
|
}
|
||||||
$this->addDex($this->oppose->getCrewType(), $addDex);
|
$this->addDex($this->oppose->getCrewType(), $addDex);
|
||||||
@@ -240,12 +265,13 @@ class WarUnitGeneral extends WarUnit{
|
|||||||
return $general->getVar('crew');
|
return $general->getVar('crew');
|
||||||
}
|
}
|
||||||
|
|
||||||
function increaseKilled(int $damage):int{
|
function increaseKilled(int $damage): int
|
||||||
|
{
|
||||||
$general = $this->general;
|
$general = $this->general;
|
||||||
$this->addLevelExp($damage / 50);
|
$this->addLevelExp($damage / 50);
|
||||||
|
|
||||||
$rice = $damage / 100;
|
$rice = $damage / 100;
|
||||||
if(!$this->isAttacker){
|
if (!$this->isAttacker) {
|
||||||
$rice *= 0.8;
|
$rice *= 0.8;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -253,9 +279,9 @@ class WarUnitGeneral extends WarUnit{
|
|||||||
$rice *= getTechCost($this->getNationVar('tech'));
|
$rice *= getTechCost($this->getNationVar('tech'));
|
||||||
|
|
||||||
$general->increaseVarWithLimit('rice', -$rice, 0);
|
$general->increaseVarWithLimit('rice', -$rice, 0);
|
||||||
|
|
||||||
$addDex = $damage;
|
$addDex = $damage;
|
||||||
if(!$this->isAttacker){
|
if (!$this->isAttacker) {
|
||||||
$addDex *= 0.9;
|
$addDex *= 0.9;
|
||||||
}
|
}
|
||||||
$this->addDex($this->getCrewType(), $addDex);
|
$this->addDex($this->getCrewType(), $addDex);
|
||||||
@@ -265,15 +291,16 @@ class WarUnitGeneral extends WarUnit{
|
|||||||
return $this->killed;
|
return $this->killed;
|
||||||
}
|
}
|
||||||
|
|
||||||
function tryWound():bool{
|
function tryWound(): bool
|
||||||
|
{
|
||||||
$general = $this->general;
|
$general = $this->general;
|
||||||
if($this->hasActivatedSkillOnLog('부상무효')){
|
if ($this->hasActivatedSkillOnLog('부상무효')) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if($this->hasActivatedSkillOnLog('퇴각부상무효')){
|
if ($this->hasActivatedSkillOnLog('퇴각부상무효')) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if(!Util::randBool(0.05)){
|
if (!Util::randBool(0.05)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -285,25 +312,28 @@ class WarUnitGeneral extends WarUnit{
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function continueWar(&$noRice):bool{
|
function continueWar(&$noRice): bool
|
||||||
|
{
|
||||||
$general = $this->general;
|
$general = $this->general;
|
||||||
if($this->getHP() <= 0){
|
if ($this->getHP() <= 0) {
|
||||||
$noRice = false;
|
$noRice = false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if($general->getVar('rice') <= $this->getHP() / 100){
|
if ($general->getVar('rice') <= $this->getHP() / 100) {
|
||||||
$noRice = true;
|
$noRice = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkStatChange():bool{
|
function checkStatChange(): bool
|
||||||
|
{
|
||||||
return $this->general->checkStatChange();
|
return $this->general->checkStatChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
function finishBattle(){
|
function finishBattle()
|
||||||
if($this->isFinished){
|
{
|
||||||
|
if ($this->isFinished) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$this->clearActivatedSkill();
|
$this->clearActivatedSkill();
|
||||||
@@ -313,11 +343,11 @@ class WarUnitGeneral extends WarUnit{
|
|||||||
$general->increaseRankVar('killcrew', $this->killed);
|
$general->increaseRankVar('killcrew', $this->killed);
|
||||||
$general->increaseRankVar('deathcrew', $this->dead);
|
$general->increaseRankVar('deathcrew', $this->dead);
|
||||||
|
|
||||||
if($this->getOppose() instanceof WarUnitGeneral){
|
if ($this->getOppose() instanceof WarUnitGeneral) {
|
||||||
$general->increaseRankVar('killcrew_person', $this->killed);
|
$general->increaseRankVar('killcrew_person', $this->killed);
|
||||||
$general->increaseRankVar('deathcrew_person', $this->dead);
|
$general->increaseRankVar('deathcrew_person', $this->dead);
|
||||||
}
|
}
|
||||||
|
|
||||||
$general->updateVar('rice', Util::round($general->getVar('rice')));
|
$general->updateVar('rice', Util::round($general->getVar('rice')));
|
||||||
$general->updateVar('experience', Util::round($general->getVar('experience')));
|
$general->updateVar('experience', Util::round($general->getVar('experience')));
|
||||||
$general->updateVar('dedication', Util::round($general->getVar('dedication')));
|
$general->updateVar('dedication', Util::round($general->getVar('dedication')));
|
||||||
@@ -325,10 +355,10 @@ class WarUnitGeneral extends WarUnit{
|
|||||||
$this->checkStatChange();
|
$this->checkStatChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
function applyDB(\MeekroDB $db):bool{
|
function applyDB(\MeekroDB $db): bool
|
||||||
|
{
|
||||||
$affected = $this->getGeneral()->applyDB($db);
|
$affected = $this->getGeneral()->applyDB($db);
|
||||||
$this->getLogger()->flush();
|
$this->getLogger()->flush();
|
||||||
return $affected;
|
return $affected;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -25,10 +25,12 @@ class che_계략발동 extends BaseWarUnitTrigger{
|
|||||||
$general = $self->getGeneral();
|
$general = $self->getGeneral();
|
||||||
|
|
||||||
[$magic, $damage] = $selfEnv['magic'];
|
[$magic, $damage] = $selfEnv['magic'];
|
||||||
|
|
||||||
$damage = $general->onCalcStat($general, 'warMagicFailDamage', $damage, $magic);
|
$damage = $general->onCalcStat($general, 'warMagicFailDamage', $damage, $magic);
|
||||||
|
$damage = $oppose->getGeneral()->onCalcOpposeStat($general, 'warMagicFailDamage', $damage, $magic);
|
||||||
$josaUl = \sammo\JosaUtil::pick($magic, '을');
|
$josaUl = \sammo\JosaUtil::pick($magic, '을');
|
||||||
|
|
||||||
|
|
||||||
$general->getLogger()->pushGeneralBattleDetailLog("<D>{$magic}</>{$josaUl} <C>성공</>했다!", ActionLogger::PLAIN);
|
$general->getLogger()->pushGeneralBattleDetailLog("<D>{$magic}</>{$josaUl} <C>성공</>했다!", ActionLogger::PLAIN);
|
||||||
$oppose->getLogger()->pushGeneralBattleDetailLog("<D>{$magic}</>에 당했다!", ActionLogger::PLAIN);
|
$oppose->getLogger()->pushGeneralBattleDetailLog("<D>{$magic}</>에 당했다!", ActionLogger::PLAIN);
|
||||||
|
|
||||||
|
|||||||
@@ -33,11 +33,13 @@ class che_계략시도 extends BaseWarUnitTrigger{
|
|||||||
if($self->hasActivatedSkill('계략불가')){
|
if($self->hasActivatedSkill('계략불가')){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
$magicTrialProb = $general->getIntel(true, true, true, false) / 100;
|
$magicTrialProb = $general->getIntel(true, true, true, false) / 100;
|
||||||
$magicTrialProb *= $crewType->magicCoef;
|
$magicTrialProb *= $crewType->magicCoef;
|
||||||
|
|
||||||
$magicTrialProb = $general->onCalcStat($general, 'warMagicTrialProb', $magicTrialProb);
|
$magicTrialProb = $general->onCalcStat($general, 'warMagicTrialProb', $magicTrialProb);
|
||||||
|
$magicTrialProb = $oppose->getGeneral()->onCalcOpposeStat($general, 'warMagicTrialProb', $magicTrialProb);
|
||||||
|
|
||||||
if($magicTrialProb <= 0){
|
if($magicTrialProb <= 0){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -45,16 +47,14 @@ class che_계략시도 extends BaseWarUnitTrigger{
|
|||||||
if($self->getPhase() == 0){
|
if($self->getPhase() == 0){
|
||||||
$magicTrialProb *= 3;
|
$magicTrialProb *= 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!Util::randBool($magicTrialProb)){
|
if(!Util::randBool($magicTrialProb)){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
$magicSuccessProb = 0.7;
|
$magicSuccessProb = 0.7;
|
||||||
$magicSuccessProb = $general->onCalcStat($general, 'warMagicSuccessProb', $magicSuccessProb);
|
$magicSuccessProb = $general->onCalcStat($general, 'warMagicSuccessProb', $magicSuccessProb);
|
||||||
if($self->hasActivatedSkill('계략약화')){
|
$magicSuccessProb = $oppose->getGeneral()->onCalcOpposeStat($general, 'warMagicSuccessProb', $magicSuccessProb);
|
||||||
$magicSuccessProb -= 0.1; //NOTE: 앞으로 이건 oppose의 onCalcStat에 들어가야하지 않을까?
|
|
||||||
}
|
|
||||||
|
|
||||||
if($oppose instanceof WarUnitCity){
|
if($oppose instanceof WarUnitCity){
|
||||||
$magic = Util::choiceRandom(array_keys(static::$tableToCity));
|
$magic = Util::choiceRandom(array_keys(static::$tableToCity));
|
||||||
@@ -66,6 +66,8 @@ class che_계략시도 extends BaseWarUnitTrigger{
|
|||||||
}
|
}
|
||||||
|
|
||||||
$successDamage = $general->onCalcStat($general, 'warMagicSuccessDamage', $successDamage, $magic);
|
$successDamage = $general->onCalcStat($general, 'warMagicSuccessDamage', $successDamage, $magic);
|
||||||
|
$successDamage = $oppose->getGeneral()->onCalcOpposeStat($general, 'warMagicSuccessDamage', $successDamage, $magic);
|
||||||
|
|
||||||
|
|
||||||
$self->activateSkill('계략시도', $magic);
|
$self->activateSkill('계략시도', $magic);
|
||||||
if(Util::randBool($magicSuccessProb)){
|
if(Util::randBool($magicSuccessProb)){
|
||||||
@@ -76,7 +78,7 @@ class che_계략시도 extends BaseWarUnitTrigger{
|
|||||||
$self->activateSkill('계략실패');
|
$self->activateSkill('계략실패');
|
||||||
$selfEnv['magic'] = [$magic, $failDamage];
|
$selfEnv['magic'] = [$magic, $failDamage];
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -27,11 +27,12 @@ class che_계략실패 extends BaseWarUnitTrigger{
|
|||||||
[$magic, $damage] = $selfEnv['magic'];
|
[$magic, $damage] = $selfEnv['magic'];
|
||||||
|
|
||||||
$damage = $general->onCalcStat($general, 'warMagicFailDamage', $damage, $magic);
|
$damage = $general->onCalcStat($general, 'warMagicFailDamage', $damage, $magic);
|
||||||
|
$damage = $oppose->getGeneral()->onCalcOpposeStat($general, 'warMagicFailDamage', $damage, $magic);
|
||||||
$josaUl = \sammo\JosaUtil::pick($magic, '을');
|
$josaUl = \sammo\JosaUtil::pick($magic, '을');
|
||||||
|
|
||||||
$general->getLogger()->pushGeneralBattleDetailLog("<D>{$magic}</>{$josaUl} <R>실패</>했다!", ActionLogger::PLAIN);
|
$general->getLogger()->pushGeneralBattleDetailLog("<D>{$magic}</>{$josaUl} <R>실패</>했다!", ActionLogger::PLAIN);
|
||||||
$oppose->getLogger()->pushGeneralBattleDetailLog("<D>{$magic}</>{$josaUl} 간파했다!", ActionLogger::PLAIN);
|
$oppose->getLogger()->pushGeneralBattleDetailLog("<D>{$magic}</>{$josaUl} 간파했다!", ActionLogger::PLAIN);
|
||||||
|
|
||||||
$self->multiplyWarPowerMultiply(1/$damage);
|
$self->multiplyWarPowerMultiply(1/$damage);
|
||||||
$oppose->multiplyWarPowerMultiply($damage);
|
$oppose->multiplyWarPowerMultiply($damage);
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ interface iAction{
|
|||||||
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float;
|
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float;
|
||||||
|
|
||||||
public function onCalcStat(General $general, string $statName, $value, $aux=null);
|
public function onCalcStat(General $general, string $statName, $value, $aux=null);
|
||||||
|
public function onCalcOpposeStat(General $general, string $statName, $value, $aux=null);
|
||||||
public function onCalcStrategic(string $turnType, string $varType, $value);
|
public function onCalcStrategic(string $turnType, string $varType, $value);
|
||||||
public function onCalcNationalIncome(string $type, $amount);
|
public function onCalcNationalIncome(string $type, $amount);
|
||||||
|
|
||||||
|
|||||||
+20
-5
@@ -10,6 +10,7 @@ html {
|
|||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: 삭제!!
|
||||||
table.tb_layout {
|
table.tb_layout {
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
@@ -17,7 +18,8 @@ table.tb_layout {
|
|||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
}
|
}
|
||||||
|
|
||||||
html, body{
|
html,
|
||||||
|
body {
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,10 +32,23 @@ html, body{
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.float-left{
|
.float-left {
|
||||||
float:left;
|
float: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.float-right{
|
.float-right {
|
||||||
float:right;
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.a-right {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-left {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-center {
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
#inheritance_list{
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.inherit_padding{
|
|
||||||
width: 33%;
|
|
||||||
padding: 10px 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.inherit_item{
|
|
||||||
width: 33%;
|
|
||||||
padding: 10px 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-form-label{
|
|
||||||
text-align:right;
|
|
||||||
padding-right:2ch;
|
|
||||||
}
|
|
||||||
|
|
||||||
.inherit_value{
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
+21
-1
@@ -438,7 +438,7 @@ CREATE TABLE `tournament` (
|
|||||||
`prmt` INT(1) NULL DEFAULT 0,
|
`prmt` INT(1) NULL DEFAULT 0,
|
||||||
PRIMARY KEY (`seq`),
|
PRIMARY KEY (`seq`),
|
||||||
INDEX `grp` (`grp`, `grp_no`)
|
INDEX `grp` (`grp`, `grp_no`)
|
||||||
)
|
)
|
||||||
COLLATE='utf8mb4_general_ci'
|
COLLATE='utf8mb4_general_ci'
|
||||||
ENGINE=Aria;
|
ENGINE=Aria;
|
||||||
|
|
||||||
@@ -651,4 +651,24 @@ CREATE TABLE `rank_data` (
|
|||||||
)
|
)
|
||||||
COLLATE='utf8mb4_general_ci'
|
COLLATE='utf8mb4_general_ci'
|
||||||
ENGINE=Aria
|
ENGINE=Aria
|
||||||
|
;
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `user_record` (
|
||||||
|
`id` INT(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`user_id` INT(11) NOT NULL,
|
||||||
|
`server_id` CHAR(20) NOT NULL,
|
||||||
|
`log_type` VARCHAR(20) NOT NULL,
|
||||||
|
`year` INT(4) NOT NULL,
|
||||||
|
`month` INT(2) NOT NULL,
|
||||||
|
`date` DATETIME NULL DEFAULT NULL,
|
||||||
|
`text` TEXT NOT NULL,
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
INDEX `date1` (`user_id`, `server_id`, `log_type`, `year`, `month`, `id`),
|
||||||
|
INDEX `date2` (`user_id`, `server_id`, `log_type`, `date`, `id`),
|
||||||
|
INDEX `date3` (`server_id`, `date`),
|
||||||
|
INDEX `date4` (`server_id`, `year`, `month`, `date`),
|
||||||
|
INDEX `plain` (`user_id`, `log_type`, `id`)
|
||||||
|
)
|
||||||
|
DEFAULT CHARSET=utf8mb4
|
||||||
|
ENGINE=Aria
|
||||||
;
|
;
|
||||||
@@ -61,7 +61,6 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import "../scss/bootstrap5.scss";
|
import "../scss/bootstrap5.scss";
|
||||||
import "../scss/inheritPoint.scss";
|
|
||||||
import "../scss/game_bg.scss";
|
import "../scss/game_bg.scss";
|
||||||
import "../../css/config.css";
|
import "../../css/config.css";
|
||||||
|
|
||||||
|
|||||||
+606
@@ -0,0 +1,606 @@
|
|||||||
|
<template>
|
||||||
|
<top-back-bar title="장수 생성" />
|
||||||
|
|
||||||
|
<div id="container" class="bg0">
|
||||||
|
<div class="row bg1">
|
||||||
|
<div class="col col-md-11 col-9 center align-self-center">
|
||||||
|
임관 권유 메시지
|
||||||
|
</div>
|
||||||
|
<div class="col col-md-1 col-3">
|
||||||
|
<label
|
||||||
|
><input type="checkbox" v-model="displayTable" />{{
|
||||||
|
displayTable ? "숨기기" : "보이기"
|
||||||
|
}}</label
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<CTable responsive v-if="displayTable">
|
||||||
|
<CTableBody>
|
||||||
|
<CTableRow
|
||||||
|
class="nation-row"
|
||||||
|
v-for="nation in nationList"
|
||||||
|
:key="nation.nation"
|
||||||
|
>
|
||||||
|
<CTableHeaderCell
|
||||||
|
scope="row"
|
||||||
|
class="a-center p-0"
|
||||||
|
:style="{
|
||||||
|
backgroundColor: nation.color,
|
||||||
|
color: isBrightColor(nation.color) ? 'black' : 'white',
|
||||||
|
}"
|
||||||
|
><div class="nation-name">
|
||||||
|
{{ nation.name }}
|
||||||
|
</div>
|
||||||
|
</CTableHeaderCell>
|
||||||
|
<CTableDataCell class="p-0">
|
||||||
|
<div
|
||||||
|
class="nation-info"
|
||||||
|
v-html="nation.scoutmsg ?? '-'"
|
||||||
|
></div></CTableDataCell></CTableRow
|
||||||
|
></CTableBody>
|
||||||
|
</CTable>
|
||||||
|
<!-- 국가 설명 -->
|
||||||
|
<div class="row bg1"><div class="col center">장수 생성</div></div>
|
||||||
|
<div class="forms">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col col-md-4 col-3 a-right align-self-center">장수명</div>
|
||||||
|
<div class="col col-md-3 col-9 align-self-center">
|
||||||
|
<input v-model="args.name" class="form-control" />
|
||||||
|
</div>
|
||||||
|
<div class="col col-md-1 col-3 a-right align-self-center">
|
||||||
|
전콘 사용
|
||||||
|
</div>
|
||||||
|
<div class="col col-md-4 col-9 align-self-center">
|
||||||
|
<img style="height: 64px; width: 64px" :src="iconPath" /><label
|
||||||
|
><input type="checkbox" v-model="args.pic" /> 사용</label
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="col col-md-4 col-3 align-self-center a-right">성격</div>
|
||||||
|
|
||||||
|
<div class="col col-md-8 col-9 align-self-center">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col col-md-3 col-4 align-self-center">
|
||||||
|
<select
|
||||||
|
class="form-select form-inline"
|
||||||
|
style="max-width: 20ch"
|
||||||
|
v-model="args.character"
|
||||||
|
>
|
||||||
|
<option
|
||||||
|
v-for="(personalityObj, key) in availablePersonality"
|
||||||
|
:key="key"
|
||||||
|
:value="key"
|
||||||
|
>
|
||||||
|
{{ personalityObj.name }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col col-md-9 col-8 align-self-center">
|
||||||
|
<small class="text-muted">{{
|
||||||
|
availablePersonality[args.character].info
|
||||||
|
}}</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!--<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
계정관리에서 자신만을 표현할 수 있는 아이콘을 업로드 해보세요!
|
||||||
|
</div>
|
||||||
|
</div>-->
|
||||||
|
<div class="row" style="margin-top: 1em">
|
||||||
|
<div class="col col-md-4 col-3 a-right align-self-center">
|
||||||
|
능력치<br /><small class="text-muted">통/무/지</small>
|
||||||
|
</div>
|
||||||
|
<div class="col col-md-2 col-3 align-self-center">
|
||||||
|
<input type="number" class="form-control" v-model="args.leadership" />
|
||||||
|
</div>
|
||||||
|
<div class="col col-md-2 col-3 align-self-center">
|
||||||
|
<input type="number" class="form-control" v-model="args.strength" />
|
||||||
|
</div>
|
||||||
|
<div class="col col-md-2 col-3 align-self-center">
|
||||||
|
<input type="number" class="form-control" v-model="args.intel" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row" style="margin-top: 1em">
|
||||||
|
<div class="col col-md-4 col-3 a-right align-self-center">
|
||||||
|
능력치 조절
|
||||||
|
</div>
|
||||||
|
<div class="col col-md-8 col-9">
|
||||||
|
<b-button variant="secondary" class="stat-btn" @click="randStatRandom"
|
||||||
|
>랜덤형</b-button
|
||||||
|
>
|
||||||
|
<b-button
|
||||||
|
variant="secondary"
|
||||||
|
class="stat-btn"
|
||||||
|
@click="randStatLeadPow"
|
||||||
|
>통솔무력형</b-button
|
||||||
|
>
|
||||||
|
<b-button
|
||||||
|
variant="secondary"
|
||||||
|
class="stat-btn"
|
||||||
|
@click="randStatLeadInt"
|
||||||
|
>통솔지력형</b-button
|
||||||
|
>
|
||||||
|
<b-button variant="secondary" class="stat-btn" @click="randStatPowInt"
|
||||||
|
>무력지력형</b-button
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row" style="border-top: solid 1px #aaa; margin-top: 0.5em">
|
||||||
|
<div class="col a-center" style="color: orange">
|
||||||
|
모든 능력치는 ( {{ stats.min }} <= 능력치 <= {{ stats.max }} )
|
||||||
|
사이로 잡으셔야 합니다.<br />
|
||||||
|
그 외의 능력치는 가입되지 않습니다.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col a-center">
|
||||||
|
능력치의 총합은 {{ stats.total }} 입니다. 가입후 {{ stats.bonusMin }} ~
|
||||||
|
{{ stats.bonusMax }} 의 능력치 보너스를 받게 됩니다.<br />
|
||||||
|
임의의 도시에서 재야로 시작하며 건국과 임관은 게임 내에서 실행합니다.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row bg1">
|
||||||
|
<div class="col col-md-11 col-9 center align-self-center">
|
||||||
|
유산 포인트 사용
|
||||||
|
</div>
|
||||||
|
<div class="col col-md-1 col-3">
|
||||||
|
<label
|
||||||
|
><input type="checkbox" v-model="displayInherit" />{{
|
||||||
|
displayTable ? "숨기기" : "보이기"
|
||||||
|
}}</label
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="inherit-block" v-if="displayInherit">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<NumberInputWithInfo
|
||||||
|
title="보유한 유산 포인트"
|
||||||
|
v-model="inheritTotalPoint"
|
||||||
|
:readonly="true"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<NumberInputWithInfo
|
||||||
|
title="필요 유산 포인트"
|
||||||
|
v-model="inheritRequiredPoint"
|
||||||
|
:readonly="true"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
<div class="row">
|
||||||
|
<div class="col col-md-6 col-sm-6 col-12 p-2 align-self-center">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col col-6 a-right align-self-center">천재로 생성</div>
|
||||||
|
<div class="col col-6 align-self-center">
|
||||||
|
<select
|
||||||
|
class="form-select form-inline"
|
||||||
|
style="max-width: 20ch"
|
||||||
|
v-model="args.inheritSpecial"
|
||||||
|
>
|
||||||
|
<option :value="undefined">사용안함</option>
|
||||||
|
<option
|
||||||
|
v-for="(inheritSpecial, key) in availableInheritSpecial"
|
||||||
|
:key="key"
|
||||||
|
:value="key"
|
||||||
|
>
|
||||||
|
{{ inheritSpecial.name }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col align-self-center">
|
||||||
|
<small
|
||||||
|
class="text-muted"
|
||||||
|
v-html="
|
||||||
|
(availableInheritSpecial[args.inheritSpecial] ?? { info: '' })
|
||||||
|
.info
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col col-md-6 col-sm-6 col-12 p-2 align-self-center">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col col-6 a-right align-self-center">도시</div>
|
||||||
|
<div class="col col-6 align-self-center">
|
||||||
|
<select
|
||||||
|
class="form-select form-inline"
|
||||||
|
style="max-width: 20ch"
|
||||||
|
v-model="args.inheritCity"
|
||||||
|
>
|
||||||
|
<option :value="undefined">사용안함</option>
|
||||||
|
<option
|
||||||
|
v-for="city in availableInheritCity"
|
||||||
|
:key="city[0]"
|
||||||
|
:value="city[0]"
|
||||||
|
>
|
||||||
|
{{ `[${city[1]}] ${city[2]}` }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col col-md-6 col-sm-6 col-12 p-2 align-self-center">
|
||||||
|
<div class="a-center">
|
||||||
|
<label
|
||||||
|
><input type="checkbox" v-model="inheritTurnTimeSet" />턴 시간
|
||||||
|
고정</label
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="row turn_time_pad">
|
||||||
|
<div class="col col-md-4 offset-md-3 col-4 offset-3">
|
||||||
|
<NumberInputWithInfo
|
||||||
|
:readonly="!inheritTurnTimeSet"
|
||||||
|
:min="0"
|
||||||
|
:max="1 - turnterm"
|
||||||
|
v-model="inheritTurnTimeMinute"
|
||||||
|
:right="true"
|
||||||
|
title="분"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="col col-md-4 col-4">
|
||||||
|
<NumberInputWithInfo
|
||||||
|
:readonly="!inheritTurnTimeSet"
|
||||||
|
:min="0"
|
||||||
|
:max="60"
|
||||||
|
v-model="inheritTurnTimeSecond"
|
||||||
|
:right="true"
|
||||||
|
title="초"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col col-md-6 col-12 p-2">
|
||||||
|
<div class="a-center">추가 능력치 고정</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<NumberInputWithInfo
|
||||||
|
title="통솔"
|
||||||
|
v-model="args.inheritBonusStat[0]"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<NumberInputWithInfo
|
||||||
|
title="무력"
|
||||||
|
v-model="args.inheritBonusStat[1]"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<NumberInputWithInfo
|
||||||
|
title="지력"
|
||||||
|
v-model="args.inheritBonusStat[2]"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row" style="border-top: solid 1px #aaa">
|
||||||
|
<div class="col a-center" style="margin: 0.5em">
|
||||||
|
<b-button color="primary" @click="submitForm">장수 생성</b-button
|
||||||
|
> <b-button color="secondary" @click="resetArgs"
|
||||||
|
>다시 입력</b-button
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
|
import "../scss/bootstrap5.scss";
|
||||||
|
import "../scss/game_bg.scss";
|
||||||
|
|
||||||
|
import { defineComponent } from "vue";
|
||||||
|
import TopBackBar from "./components/TopBackBar.vue";
|
||||||
|
import {
|
||||||
|
CTable,
|
||||||
|
CTableBody,
|
||||||
|
CTableRow,
|
||||||
|
CTableHeaderCell,
|
||||||
|
CTableDataCell,
|
||||||
|
} from "@coreui/vue/src";
|
||||||
|
import { getIconPath } from "./util/getIconPath";
|
||||||
|
import { isBrightColor } from "./util/isBrightColor";
|
||||||
|
import {
|
||||||
|
abilityLeadint,
|
||||||
|
abilityLeadpow,
|
||||||
|
abilityPowint,
|
||||||
|
abilityRand,
|
||||||
|
} from "./util/generalStats";
|
||||||
|
import { clone, shuffle, sum } from "lodash";
|
||||||
|
import axios from "axios";
|
||||||
|
import { InvalidResponse } from "./defs";
|
||||||
|
import NumberInputWithInfo from "./components/NumberInputWithInfo.vue";
|
||||||
|
|
||||||
|
declare const nationList: {
|
||||||
|
nation: number;
|
||||||
|
name: string;
|
||||||
|
color: string;
|
||||||
|
scout: number;
|
||||||
|
scoutmsg?: string;
|
||||||
|
}[];
|
||||||
|
declare const availablePersonality: {
|
||||||
|
[key: string]: {
|
||||||
|
name: string;
|
||||||
|
info: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
declare const availableInheritSpecial: {
|
||||||
|
[key: string]: {
|
||||||
|
name: string;
|
||||||
|
info: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
declare const availableInheritCity: [number, string, string][];
|
||||||
|
|
||||||
|
declare const turnterm: number;
|
||||||
|
|
||||||
|
declare const member: {
|
||||||
|
name: string;
|
||||||
|
grade: number;
|
||||||
|
picture: string;
|
||||||
|
imgsvr: 0 | 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
declare const stats: {
|
||||||
|
min: number;
|
||||||
|
max: number;
|
||||||
|
total: number;
|
||||||
|
bonusMin: number;
|
||||||
|
bonusMax: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
declare const inheritPoints: {
|
||||||
|
special: number;
|
||||||
|
turnTime: number;
|
||||||
|
city: number;
|
||||||
|
stat: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
declare const serverID: string;
|
||||||
|
declare const inheritTotalPoint: number;
|
||||||
|
|
||||||
|
declare module "@vue/runtime-core" {
|
||||||
|
interface ComponentCustomProperties {
|
||||||
|
member: typeof member;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type APIArgs = {
|
||||||
|
name: string;
|
||||||
|
leadership: number;
|
||||||
|
strength: number;
|
||||||
|
intel: number;
|
||||||
|
pic: boolean;
|
||||||
|
character: string;
|
||||||
|
inheritSpecial?: string;
|
||||||
|
inheritTurntime?: number;
|
||||||
|
inheritCity?: number;
|
||||||
|
inheritBonusStat?: [number, number, number];
|
||||||
|
};
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: "Join",
|
||||||
|
components: {
|
||||||
|
TopBackBar,
|
||||||
|
CTable,
|
||||||
|
CTableBody,
|
||||||
|
CTableRow,
|
||||||
|
CTableHeaderCell,
|
||||||
|
CTableDataCell,
|
||||||
|
NumberInputWithInfo,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
const displayTable = JSON.parse(
|
||||||
|
localStorage.getItem(`conf.${serverID}.join.displayTable`) ?? "true"
|
||||||
|
);
|
||||||
|
const displayInherit = JSON.parse(
|
||||||
|
localStorage.getItem(`conf.${serverID}.join.displayInherit`) ?? "true"
|
||||||
|
);
|
||||||
|
const nationListShuffled = shuffle(nationList);
|
||||||
|
const args: APIArgs = {
|
||||||
|
name: member.name,
|
||||||
|
leadership: stats.total - 2 * Math.floor(stats.total / 3),
|
||||||
|
strength: Math.floor(stats.total / 3),
|
||||||
|
intel: Math.floor(stats.total / 3),
|
||||||
|
pic: true,
|
||||||
|
character: "Random",
|
||||||
|
|
||||||
|
inheritCity: undefined,
|
||||||
|
inheritBonusStat: [0, 0, 0],
|
||||||
|
inheritSpecial: undefined,
|
||||||
|
inheritTurntime: undefined,
|
||||||
|
};
|
||||||
|
availableInheritCity.sort((lhs, rhs) => {
|
||||||
|
const rC = lhs[1].localeCompare(rhs[1]);
|
||||||
|
if (rC != 0) return rC;
|
||||||
|
return lhs[2].localeCompare(rhs[2]);
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
displayTable,
|
||||||
|
displayInherit,
|
||||||
|
availablePersonality,
|
||||||
|
availableInheritSpecial,
|
||||||
|
availableInheritCity,
|
||||||
|
member: member,
|
||||||
|
stats,
|
||||||
|
args,
|
||||||
|
nationList: nationListShuffled,
|
||||||
|
isBrightColor,
|
||||||
|
inheritTotalPoint,
|
||||||
|
inheritTurnTimeSet: false,
|
||||||
|
inheritTurnTimeMinute: 0,
|
||||||
|
inheritTurnTimeSecond: 0,
|
||||||
|
turnterm,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
displayTable(newValue: boolean) {
|
||||||
|
localStorage.setItem(
|
||||||
|
`conf.${serverID}.join.displayTable`,
|
||||||
|
JSON.stringify(newValue)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
displayInherit(newValue: boolean) {
|
||||||
|
localStorage.setItem(
|
||||||
|
`conf.${serverID}.join.displayInherit`,
|
||||||
|
JSON.stringify(newValue)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
inheritTurnTimeMinute(newValue: number) {
|
||||||
|
if (!this.inheritTurnTimeSet) {
|
||||||
|
this.args.inheritTurntime = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.args.inheritTurntime = newValue * 60 + this.inheritTurnTimeSecond;
|
||||||
|
},
|
||||||
|
inheritTurnTimeSecond(newValue: number) {
|
||||||
|
if (!this.inheritTurnTimeSet) {
|
||||||
|
this.args.inheritTurntime = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.args.inheritTurntime = this.inheritTurnTimeMinute * 60 + newValue;
|
||||||
|
},
|
||||||
|
inheritTurnTimeSet(newValue: boolean) {
|
||||||
|
if (!newValue) {
|
||||||
|
this.args.inheritTurntime = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.args.inheritTurntime =
|
||||||
|
this.inheritTurnTimeMinute * 60 + this.inheritTurnTimeSecond;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
iconPath() {
|
||||||
|
if (this.args.pic) {
|
||||||
|
return getIconPath(this.member.imgsvr, this.member.picture);
|
||||||
|
}
|
||||||
|
return getIconPath(0, "default.jpg");
|
||||||
|
},
|
||||||
|
inheritRequiredPoint() {
|
||||||
|
let inheritRequiredPoint = 0;
|
||||||
|
if (this.args.inheritCity !== undefined) {
|
||||||
|
inheritRequiredPoint += inheritPoints.city;
|
||||||
|
}
|
||||||
|
if (this.args.inheritSpecial !== undefined) {
|
||||||
|
inheritRequiredPoint += inheritPoints.special;
|
||||||
|
}
|
||||||
|
if (this.args.inheritTurntime !== undefined) {
|
||||||
|
inheritRequiredPoint += inheritPoints.turnTime;
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
this.args.inheritBonusStat !== undefined &&
|
||||||
|
sum(this.args.inheritBonusStat) != 0
|
||||||
|
) {
|
||||||
|
inheritRequiredPoint += inheritPoints.stat;
|
||||||
|
}
|
||||||
|
return inheritRequiredPoint;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
randStatRandom() {
|
||||||
|
[this.args.leadership, this.args.strength, this.args.intel] =
|
||||||
|
abilityRand();
|
||||||
|
},
|
||||||
|
randStatLeadPow() {
|
||||||
|
[this.args.leadership, this.args.strength, this.args.intel] =
|
||||||
|
abilityLeadpow();
|
||||||
|
},
|
||||||
|
randStatLeadInt() {
|
||||||
|
[this.args.leadership, this.args.strength, this.args.intel] =
|
||||||
|
abilityLeadint();
|
||||||
|
},
|
||||||
|
randStatPowInt() {
|
||||||
|
[this.args.leadership, this.args.strength, this.args.intel] =
|
||||||
|
abilityPowint();
|
||||||
|
},
|
||||||
|
resetArgs() {
|
||||||
|
this.args.name = member.name;
|
||||||
|
this.args.pic = true;
|
||||||
|
this.args.character = "Random";
|
||||||
|
this.args.leadership = stats.total - 2 * Math.floor(stats.total / 3);
|
||||||
|
this.args.strength = Math.floor(stats.total / 3);
|
||||||
|
this.args.intel = Math.floor(stats.total / 3);
|
||||||
|
},
|
||||||
|
async submitForm() {
|
||||||
|
//검증은 언제 되어야 하는가?
|
||||||
|
const args = clone(this.args);
|
||||||
|
let result: InvalidResponse;
|
||||||
|
try {
|
||||||
|
const response = await axios({
|
||||||
|
url: "api.php",
|
||||||
|
method: "post",
|
||||||
|
responseType: "json",
|
||||||
|
data: {
|
||||||
|
path: ["General", "Join"],
|
||||||
|
args,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
result = response.data;
|
||||||
|
if (!result.result) {
|
||||||
|
throw result.reason;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
alert(`실패했습니다: ${e}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
alert(
|
||||||
|
"정상적으로 생성되었습니다. \n위키와 팁/강좌 게시판을 꼭 읽어보세요!"
|
||||||
|
);
|
||||||
|
location.href = "./";
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
#container {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 1000px;
|
||||||
|
margin: auto;
|
||||||
|
border: solid 1px #888888;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.forms {
|
||||||
|
padding: 0 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-btn {
|
||||||
|
width: 8em;
|
||||||
|
margin-right: 1px;
|
||||||
|
margin-bottom: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nation-row {
|
||||||
|
max-height: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nation-name {
|
||||||
|
width: 128px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nation-info {
|
||||||
|
max-height: 200px;
|
||||||
|
overflow-y: hidden;
|
||||||
|
width: 870px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-form-label {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.turn_time_pad .col-form-label{
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -298,9 +298,8 @@
|
|||||||
<i class="bi bi-list"></i> {{ element.id
|
<i class="bi bi-list"></i> {{ element.id
|
||||||
}}<button
|
}}<button
|
||||||
class="btn btn-sm float-right btn-secondary py-0 px-1"
|
class="btn btn-sm float-right btn-secondary py-0 px-1"
|
||||||
v-c-tooltip="actionHelpText[element.id]"
|
v-b-tooltip.hover :title="actionHelpText[element.id]"
|
||||||
>
|
>
|
||||||
<!-- FIXME: v-c-tooltip 동작이 조금 묘하다. 버전 문제인가? -->
|
|
||||||
<i class="bi bi-question-lg"></i>
|
<i class="bi bi-question-lg"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -320,7 +319,7 @@
|
|||||||
<i class="bi bi-list"></i> {{ element.id
|
<i class="bi bi-list"></i> {{ element.id
|
||||||
}}<button
|
}}<button
|
||||||
class="btn btn-sm float-right btn-secondary py-0 px-1"
|
class="btn btn-sm float-right btn-secondary py-0 px-1"
|
||||||
v-c-tooltip="actionHelpText[element.id]"
|
v-b-tooltip.hover :title="actionHelpText[element.id]"
|
||||||
>
|
>
|
||||||
<i class="bi bi-question-lg"></i>
|
<i class="bi bi-question-lg"></i>
|
||||||
</button>
|
</button>
|
||||||
@@ -391,7 +390,7 @@
|
|||||||
<i class="bi bi-list"></i> {{ element.id
|
<i class="bi bi-list"></i> {{ element.id
|
||||||
}}<button
|
}}<button
|
||||||
class="btn btn-sm float-right btn-secondary py-0 px-1"
|
class="btn btn-sm float-right btn-secondary py-0 px-1"
|
||||||
v-c-tooltip="actionHelpText[element.id]"
|
v-b-tooltip.hover :title="actionHelpText[element.id]"
|
||||||
>
|
>
|
||||||
<i class="bi bi-question-lg"></i>
|
<i class="bi bi-question-lg"></i>
|
||||||
</button>
|
</button>
|
||||||
@@ -412,7 +411,7 @@
|
|||||||
<i class="bi bi-list"></i> {{ element.id
|
<i class="bi bi-list"></i> {{ element.id
|
||||||
}}<button
|
}}<button
|
||||||
class="btn btn-sm float-right btn-secondary py-0 px-1"
|
class="btn btn-sm float-right btn-secondary py-0 px-1"
|
||||||
v-c-tooltip="actionHelpText[element.id]"
|
v-b-tooltip.hover :title="actionHelpText[element.id]"
|
||||||
>
|
>
|
||||||
<i class="bi bi-question-lg"></i>
|
<i class="bi bi-question-lg"></i>
|
||||||
</button>
|
</button>
|
||||||
@@ -470,7 +469,6 @@ import { unwrap } from "./util/unwrap";
|
|||||||
import { convertFormData } from "./util/convertFormData";
|
import { convertFormData } from "./util/convertFormData";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { NPCPriorityBtnHelpMessage } from "./helpTexts";
|
import { NPCPriorityBtnHelpMessage } from "./helpTexts";
|
||||||
import { CTooltip } from "@coreui/vue/src/directives/CTooltip";
|
|
||||||
import draggable from "vuedraggable";
|
import draggable from "vuedraggable";
|
||||||
import MyToast from "./components/MyToast.vue";
|
import MyToast from "./components/MyToast.vue";
|
||||||
import TopBackBar from "./components/TopBackBar.vue";
|
import TopBackBar from "./components/TopBackBar.vue";
|
||||||
@@ -512,9 +510,6 @@ export default defineComponent({
|
|||||||
draggable,
|
draggable,
|
||||||
MyToast,
|
MyToast,
|
||||||
},
|
},
|
||||||
directives: {
|
|
||||||
"c-tooltip": CTooltip,
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
resetPolicy() {
|
resetPolicy() {
|
||||||
if (!confirm("초기 설정으로 되돌릴까요?")) {
|
if (!confirm("초기 설정으로 되돌릴까요?")) {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { exportWindow } from './util/exportWindow';
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import Popper from 'popper.js';
|
import Popper from 'popper.js';
|
||||||
exportWindow(Popper, 'Popper');//XXX: 왜 popper를 이렇게 불러야 하는가?
|
exportWindow(Popper, 'Popper');//XXX: 왜 popper를 이렇게 불러야 하는가?
|
||||||
@@ -5,12 +6,12 @@ import 'bootstrap';
|
|||||||
import download from 'downloadjs';
|
import download from 'downloadjs';
|
||||||
import { unwrap } from "./util/unwrap";
|
import { unwrap } from "./util/unwrap";
|
||||||
import { isInteger } from 'lodash';
|
import { isInteger } from 'lodash';
|
||||||
import { combineArray, errUnknown, getNpcColor, isBrightColor } from './common_legacy';
|
import { combineArray, errUnknown, getNpcColor } from './common_legacy';
|
||||||
|
import { isBrightColor } from "./util/isBrightColor";
|
||||||
import { numberWithCommas } from "./util/numberWithCommas";
|
import { numberWithCommas } from "./util/numberWithCommas";
|
||||||
import { unwrap_any } from './util/unwrap_any';
|
import { unwrap_any } from './util/unwrap_any';
|
||||||
import { BasicGeneralListResponse, InvalidResponse } from './defs';
|
import { BasicGeneralListResponse, InvalidResponse } from './defs';
|
||||||
import { formatTime } from './util/formatTime';
|
import { formatTime } from './util/formatTime';
|
||||||
import { exportWindow } from './util/exportWindow';
|
|
||||||
|
|
||||||
type CityAttackerInfo = {
|
type CityAttackerInfo = {
|
||||||
level: number,
|
level: number,
|
||||||
|
|||||||
+1
-1
@@ -1,10 +1,10 @@
|
|||||||
|
import { exportWindow } from './util/exportWindow';
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { convertFormData } from './util/convertFormData';
|
import { convertFormData } from './util/convertFormData';
|
||||||
import { InvalidResponse } from './defs';
|
import { InvalidResponse } from './defs';
|
||||||
import { unwrap_any } from './util/unwrap_any';
|
import { unwrap_any } from './util/unwrap_any';
|
||||||
import { setAxiosXMLHttpRequest } from './util/setAxiosXMLHttpRequest';
|
import { setAxiosXMLHttpRequest } from './util/setAxiosXMLHttpRequest';
|
||||||
import { exportWindow } from './util/exportWindow';
|
|
||||||
import Popper from 'popper.js';
|
import Popper from 'popper.js';
|
||||||
exportWindow(Popper, 'Popper');
|
exportWindow(Popper, 'Popper');
|
||||||
import 'bootstrap';
|
import 'bootstrap';
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
{
|
{
|
||||||
"ingame": {
|
"ingame": {
|
||||||
"chiefCenter": "chiefCenter.ts",
|
"chiefCenter": "chiefCenter.ts",
|
||||||
"common": "common_deprecated.ts",
|
|
||||||
"troop": "troop.ts",
|
"troop": "troop.ts",
|
||||||
"map": "map.ts",
|
"map": "map.ts",
|
||||||
"install_db": "install_db.ts",
|
"install_db": "install_db.ts",
|
||||||
@@ -20,13 +19,15 @@
|
|||||||
"currentCity": "currentCity.ts",
|
"currentCity": "currentCity.ts",
|
||||||
"hallOfFame": "hallOfFame.ts",
|
"hallOfFame": "hallOfFame.ts",
|
||||||
"history": "history.ts",
|
"history": "history.ts",
|
||||||
"join": "join.ts",
|
"join": "legacy/join.ts",
|
||||||
"select_general_from_pool": "select_general_from_pool.ts",
|
"select_general_from_pool": "select_general_from_pool.ts",
|
||||||
"extKingdoms": "extKingdoms.ts"
|
"extKingdoms": "extKingdoms.ts",
|
||||||
|
"common": "common_deprecated.ts"
|
||||||
},
|
},
|
||||||
"ingame_vue": {
|
"ingame_vue": {
|
||||||
"v_inheritPoint": "v_inheritPoint.ts",
|
"v_inheritPoint": "v_inheritPoint.ts",
|
||||||
"v_board": "v_board.ts",
|
"v_board": "v_board.ts",
|
||||||
"v_NPCControl": "v_NPCControl.ts"
|
"v_NPCControl": "v_NPCControl.ts",
|
||||||
|
"v_join": "v_join.ts"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,12 @@
|
|||||||
import { activateFlip, isBrightColor, getIconPath, errUnknown, errUnknownToast, quickReject, initTooltip } from "./common_legacy";
|
import { exportWindow } from "./util/exportWindow";
|
||||||
|
import { activateFlip, errUnknown, errUnknownToast, quickReject, initTooltip } from "./common_legacy";
|
||||||
|
import { isBrightColor } from "./util/isBrightColor";
|
||||||
|
import { getIconPath } from "./util/getIconPath";
|
||||||
import { mb_strwidth } from "./util/mb_strwidth";
|
import { mb_strwidth } from "./util/mb_strwidth";
|
||||||
import { TemplateEngine } from "./util/TemplateEngine";
|
import { TemplateEngine } from "./util/TemplateEngine";
|
||||||
import { escapeHtml } from "./legacy/escapeHtml";
|
import { escapeHtml } from "./legacy/escapeHtml";
|
||||||
import { nl2br } from "./util/nl2br";
|
import { nl2br } from "./util/nl2br";
|
||||||
import jQuery from "jquery";
|
import jQuery from "jquery";
|
||||||
import { exportWindow } from "./util/exportWindow";
|
|
||||||
import Popper from 'popper.js';
|
import Popper from 'popper.js';
|
||||||
exportWindow(Popper, 'Popper');//XXX: 왜 popper를 이렇게 불러야 하는가?
|
exportWindow(Popper, 'Popper');//XXX: 왜 popper를 이렇게 불러야 하는가?
|
||||||
import 'bootstrap';
|
import 'bootstrap';
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { unwrap } from "./util/unwrap";
|
|
||||||
import $ from "jquery";
|
import $ from "jquery";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
|
||||||
@@ -31,24 +30,6 @@ export function stringFormat(text: string, ...args: (string | number)[]): string
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function hexToRgb(hex: string): { r: number, g: number, b: number } | null {
|
|
||||||
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
|
||||||
return result ? {
|
|
||||||
r: parseInt(result[1], 16),
|
|
||||||
g: parseInt(result[2], 16),
|
|
||||||
b: parseInt(result[3], 16)
|
|
||||||
} : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isBrightColor(color: string): boolean {
|
|
||||||
const cv = unwrap(hexToRgb(color));
|
|
||||||
if ((cv.r * 0.299 + cv.g * 0.587 + cv.b * 0.114) > 140) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 게임내에서 지원하는 color type만 선택할 수 있도록 해주는 함수
|
* 게임내에서 지원하는 color type만 선택할 수 있도록 해주는 함수
|
||||||
* @param {string} color #AAAAAA 또는 AAAAAA 형태로 작성된 RGB hex color string
|
* @param {string} color #AAAAAA 또는 AAAAAA 형태로 작성된 RGB hex color string
|
||||||
@@ -82,15 +63,6 @@ declare global {
|
|||||||
linkifyStr: (v: string, k?: Record<string, string | number>) => string;
|
linkifyStr: (v: string, k?: Record<string, string | number>) => string;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export function getIconPath(imgsvr: boolean | 1 | 0, picture: string): string {
|
|
||||||
// ../d_shared/common_path.js 필요
|
|
||||||
if (!imgsvr) {
|
|
||||||
return window.pathConfig.sharedIcon + '/' + picture;
|
|
||||||
} else {
|
|
||||||
return window.pathConfig.root + '/d_pic/' + picture;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function activateFlip($obj?: JQuery<HTMLElement>): void {
|
export function activateFlip($obj?: JQuery<HTMLElement>): void {
|
||||||
let $result: JQuery<HTMLElement>;
|
let $result: JQuery<HTMLElement>;
|
||||||
if ($obj === undefined) {
|
if ($obj === undefined) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<table style="width: 1000px; margin: auto" class="tb_layout bg0">
|
<table style="width: 1000px; margin: auto" class="bg0">
|
||||||
<tr>
|
<tr>
|
||||||
<td style="text-align: left">
|
<td style="text-align: left">
|
||||||
{{title}}<br /><button
|
{{title}}<br /><button
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="row form-group number-input-with-info">
|
<div class="row form-group number-input-with-info">
|
||||||
<label class="col-6 col-form-label">{{ title }}</label>
|
<label v-if="!right" class="col-6 col-form-label">{{ title }}</label>
|
||||||
<div class="col-6">
|
<div class="col-6">
|
||||||
<input
|
<input
|
||||||
ref="input"
|
ref="input"
|
||||||
@@ -17,11 +17,13 @@
|
|||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
|
:readonly="readonly"
|
||||||
:value="printValue"
|
:value="printValue"
|
||||||
@focus="onFocusText"
|
@focus="onFocusText"
|
||||||
:style="{ display: !editmode ? undefined : 'none' }"
|
:style="{ display: !editmode ? undefined : 'none' }"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<label v-if="right" class="col-6 col-form-label">{{ title }}</label>
|
||||||
</div>
|
</div>
|
||||||
<div style="text-align: right">
|
<div style="text-align: right">
|
||||||
<small class="form-text text-muted"><slot></slot></small>
|
<small class="form-text text-muted"><slot></slot></small>
|
||||||
@@ -33,6 +35,11 @@ import { defineComponent } from "vue";
|
|||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "NumberInputWithInfo",
|
name: "NumberInputWithInfo",
|
||||||
props: {
|
props: {
|
||||||
|
readonly: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
int: {
|
int: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: false,
|
required: false,
|
||||||
@@ -59,6 +66,11 @@ export default defineComponent({
|
|||||||
type: Number,
|
type: Number,
|
||||||
default: 0,
|
default: 0,
|
||||||
},
|
},
|
||||||
|
right: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false,
|
||||||
|
}
|
||||||
},
|
},
|
||||||
emits: ["update:modelValue"],
|
emits: ["update:modelValue"],
|
||||||
data() {
|
data() {
|
||||||
@@ -76,6 +88,9 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
updateValue() {
|
updateValue() {
|
||||||
|
if(this.readonly){
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (this.int) {
|
if (this.int) {
|
||||||
this.rawValue = Math.floor(this.rawValue);
|
this.rawValue = Math.floor(this.rawValue);
|
||||||
}
|
}
|
||||||
@@ -87,6 +102,9 @@ export default defineComponent({
|
|||||||
this.printValue = this.rawValue.toLocaleString();
|
this.printValue = this.rawValue.toLocaleString();
|
||||||
},
|
},
|
||||||
onFocusText() {
|
onFocusText() {
|
||||||
|
if(this.readonly){
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.editmode = true;
|
this.editmode = true;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
(this.$refs.input as HTMLInputElement).focus();
|
(this.$refs.input as HTMLInputElement).focus();
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="tb_layout bg0 back_bar">
|
<div class="bg0 back_bar">
|
||||||
<button type="button" class="btn btn-primary back_btn" @click="back">
|
<button type="button" class="btn btn-primary back_btn" @click="back">
|
||||||
돌아가기
|
돌아가기
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import { unwrap_any } from './util/unwrap_any';
|
import { unwrap_any } from './util/unwrap_any';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { isBrightColor } from './common_legacy';
|
import { isBrightColor } from "./util/isBrightColor";
|
||||||
import { setAxiosXMLHttpRequest } from './util/setAxiosXMLHttpRequest';
|
import { setAxiosXMLHttpRequest } from './util/setAxiosXMLHttpRequest';
|
||||||
import { isString } from 'lodash';
|
import { isString } from 'lodash';
|
||||||
import { convertFormData } from './util/convertFormData';
|
import { convertFormData } from './util/convertFormData';
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
|
import Popper from 'popper.js';
|
||||||
|
exportWindow(Popper, 'Popper');//XXX: 왜 popper를 이렇게 불러야 하는가?
|
||||||
import { isNumber } from 'lodash';
|
import { isNumber } from 'lodash';
|
||||||
import { TemplateEngine } from '../util/TemplateEngine';
|
import { TemplateEngine } from '../util/TemplateEngine';
|
||||||
import { InvalidResponse } from '../defs';
|
import { InvalidResponse } from '../defs';
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
|
import { exportWindow } from '../util/exportWindow';
|
||||||
import $ from 'jquery';
|
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { setAxiosXMLHttpRequest } from '../util/setAxiosXMLHttpRequest';
|
import { setAxiosXMLHttpRequest } from '../util/setAxiosXMLHttpRequest';
|
||||||
import { InvalidResponse } from '../defs';
|
import { InvalidResponse } from '../defs';
|
||||||
@@ -65,10 +64,6 @@ const serverAdminTemplate = '\
|
|||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
modifyServerStatus: (caller: HTMLElement, action: string) => void;
|
|
||||||
Entrance_AdminClosedLogin: (caller: HTMLElement) => void;
|
|
||||||
Entrance_AdminOpen119: (caller: HTMLElement) => void;
|
|
||||||
serverUpdate: (caller: HTMLElement) => void;
|
|
||||||
adminGrade: number;
|
adminGrade: number;
|
||||||
aclList: Record<string, string[]>;
|
aclList: Record<string, string[]>;
|
||||||
}
|
}
|
||||||
@@ -218,11 +213,6 @@ export async function loadPlugin(): Promise<void> {
|
|||||||
|
|
||||||
Entrance_AdminInit();
|
Entrance_AdminInit();
|
||||||
|
|
||||||
window.modifyServerStatus = modifyServerStatus;
|
|
||||||
window.Entrance_AdminClosedLogin = Entrance_AdminClosedLogin;
|
|
||||||
window.Entrance_AdminOpen119 = Entrance_AdminOpen119;
|
|
||||||
window.serverUpdate = serverUpdate;
|
|
||||||
|
|
||||||
const response = await axios({
|
const response = await axios({
|
||||||
url: 'j_server_get_admin_status.php',
|
url: 'j_server_get_admin_status.php',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
@@ -330,3 +320,8 @@ function Entrance_AdminOpen119(caller: HTMLElement) {
|
|||||||
const serverDir = $caller.parents('tr').data('server_name');
|
const serverDir = $caller.parents('tr').data('server_name');
|
||||||
location.href = `../${serverDir}/_119.php`;
|
location.href = `../${serverDir}/_119.php`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exportWindow(modifyServerStatus, 'modifyServerStatus');
|
||||||
|
exportWindow(Entrance_AdminClosedLogin, 'Entrance_AdminClosedLogin');
|
||||||
|
exportWindow(Entrance_AdminOpen119, 'Entrance_AdminOpen119');
|
||||||
|
exportWindow(serverUpdate, 'serverUpdate');
|
||||||
@@ -1 +0,0 @@
|
|||||||
export * from '../common_deprecated';
|
|
||||||
@@ -1,5 +1,10 @@
|
|||||||
import axios from 'axios';
|
import { exportWindow } from '../util/exportWindow';
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
|
exportWindow($, '$');
|
||||||
|
import Popper from 'popper.js';
|
||||||
|
exportWindow(Popper, 'Popper');//XXX: 왜 popper를 이렇게 불러야 하는가?
|
||||||
|
import axios from 'axios';
|
||||||
|
import 'bootstrap';
|
||||||
import { initTooltip } from '../common_legacy';
|
import { initTooltip } from '../common_legacy';
|
||||||
import { TemplateEngine } from "../util/TemplateEngine";
|
import { TemplateEngine } from "../util/TemplateEngine";
|
||||||
import { InvalidResponse } from '../defs';
|
import { InvalidResponse } from '../defs';
|
||||||
@@ -7,6 +12,7 @@ import { getDateTimeNow } from '../util/getDateTimeNow';
|
|||||||
import { setAxiosXMLHttpRequest } from '../util/setAxiosXMLHttpRequest';
|
import { setAxiosXMLHttpRequest } from '../util/setAxiosXMLHttpRequest';
|
||||||
import { loadPlugin as loadAdminPlugin } from './admin_server';
|
import { loadPlugin as loadAdminPlugin } from './admin_server';
|
||||||
|
|
||||||
|
|
||||||
declare const isAdmin: boolean;
|
declare const isAdmin: boolean;
|
||||||
|
|
||||||
const serverListTemplate = "\
|
const serverListTemplate = "\
|
||||||
@@ -55,7 +61,7 @@ const serverLoginBtn = "<a href='<%serverPath%>/' class='item'\
|
|||||||
></a>";
|
></a>";
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
const serverCreateBtn = "<a href='<%serverPath%>/join.php' class='item'\
|
const serverCreateBtn = "<a href='<%serverPath%>/v_join.php' class='item'\
|
||||||
><button type='button' class='fill_box with_skin'>장수생성</button\
|
><button type='button' class='fill_box with_skin'>장수생성</button\
|
||||||
></a>";
|
></a>";
|
||||||
|
|
||||||
@@ -73,7 +79,7 @@ const serverCreateTemplate = "\
|
|||||||
<td colspan='2' class='not_registered'>- 미 등 록 -</div>\
|
<td colspan='2' class='not_registered'>- 미 등 록 -</div>\
|
||||||
<td class='ignore_border vertical_flex BtnPlate'>\
|
<td class='ignore_border vertical_flex BtnPlate'>\
|
||||||
<%if(canCreate) {%>\
|
<%if(canCreate) {%>\
|
||||||
<a href='<%serverPath%>/join.php' class='item'><button type='button' class='fill_box with_skin'>장수생성</button></a>\
|
<a href='<%serverPath%>/v_join.php' class='item'><button type='button' class='fill_box with_skin'>장수생성</button></a>\
|
||||||
<%}%>\
|
<%}%>\
|
||||||
<%if(canSelectNPC) {%>\
|
<%if(canSelectNPC) {%>\
|
||||||
<a href='<%serverPath%>/select_npc.php' class='item'><button type='button' class='fill_box with_skin'>장수빙의</button></a>\
|
<a href='<%serverPath%>/select_npc.php' class='item'><button type='button' class='fill_box with_skin'>장수빙의</button></a>\
|
||||||
@@ -236,6 +242,14 @@ async function Entrance_drawServerList(serverInfos: ServerResponseItem[]) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(response.reserved){
|
||||||
|
$serverHtml.find('.server_down').detach();
|
||||||
|
$serverHtml.append(
|
||||||
|
TemplateEngine(serverReservedTemplate, response.reserved)
|
||||||
|
);
|
||||||
|
initTooltip($serverHtml);
|
||||||
|
}
|
||||||
|
|
||||||
if(!response.game){
|
if(!response.game){
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
+532
-9
@@ -2,19 +2,22 @@
|
|||||||
<top-back-bar :title="title" />
|
<top-back-bar :title="title" />
|
||||||
<div
|
<div
|
||||||
id="container"
|
id="container"
|
||||||
class="tb_layout bg0"
|
class="bg0 px-2"
|
||||||
style="width: 1000px; margin: auto; border: solid 1px #888888"
|
style="max-width: 1000px; margin: auto; border: solid 1px #888888; overflow:hidden;"
|
||||||
>
|
>
|
||||||
<div id="inheritance_list">
|
<div id="inheritance_list" class="row">
|
||||||
<template v-for="(text, key) in inheritanceViewText" :key="key">
|
<template v-for="(text, key) in inheritanceViewText" :key="key">
|
||||||
<div :id="`inherit_${key}`" class="inherit_item inherit_template_item">
|
<div
|
||||||
|
:id="`inherit_${key}`"
|
||||||
|
class="col col-sm-4 col-12 inherit_item inherit_template_item"
|
||||||
|
>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<label
|
<label
|
||||||
:id="`inherit_${key}_head`"
|
:id="`inherit_${key}_head`"
|
||||||
class="inherit_head col-sm-6 col-form-label"
|
class="inherit_head col col-md-6 col-sm-7 col-6 col-form-label"
|
||||||
>{{ text.title }}</label
|
>{{ text.title }}</label
|
||||||
>
|
>
|
||||||
<div class="col-sm-6">
|
<div class="col col-md-6 col-sm-5 col-6">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
class="form-control inherit_value"
|
class="form-control inherit_value"
|
||||||
@@ -34,17 +37,216 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="inheritance_store">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col"><div class="bg1 a-center">유산 포인트 상점</div></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col offset-md-4 col-md-4 col-sm-6 col-12 py-2">
|
||||||
|
<div class="row px-4">
|
||||||
|
<div class="a-right col-6 align-self-center">
|
||||||
|
다음 전투 특기 선택
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<select class="form-select col-6" v-model="nextSpecialWar">
|
||||||
|
<option
|
||||||
|
v-for="(info, key) in availableSpecialWar"
|
||||||
|
:key="key"
|
||||||
|
:value="key"
|
||||||
|
>
|
||||||
|
{{ info.title }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="a-right">
|
||||||
|
<small class="form-text text-muted"
|
||||||
|
><span
|
||||||
|
style="color: white"
|
||||||
|
v-html="availableSpecialWar[nextSpecialWar].info"
|
||||||
|
/><br />다음에 얻을 전투 특기를 정합니다.<br /><span
|
||||||
|
style="color: white"
|
||||||
|
>필요 포인트: {{ inheritActionCost.nextSpecial }}</span
|
||||||
|
></small
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="row px-4">
|
||||||
|
<b-button
|
||||||
|
class="col-6 offset-6"
|
||||||
|
variant="primary"
|
||||||
|
@click="setNextSpecialWar"
|
||||||
|
>구입</b-button
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col col-md-4 col-sm-6 col-12 py-2">
|
||||||
|
<div class="row px-4">
|
||||||
|
<div class="a-right col-6 align-self-center">유니크 입찰</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<select class="form-select col-6" v-model="specificUnique">
|
||||||
|
<option
|
||||||
|
v-for="(info, key) in availableUnique"
|
||||||
|
:key="key"
|
||||||
|
:value="key"
|
||||||
|
>
|
||||||
|
{{ info.title }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row px-4">
|
||||||
|
<div class="col">
|
||||||
|
<NumberInputWithInfo
|
||||||
|
title="입찰 포인트"
|
||||||
|
:min="inheritActionCost.minSpecificUnique"
|
||||||
|
:max="this.items.previous"
|
||||||
|
v-model="specificUniqueAmount"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="a-right">
|
||||||
|
<small class="form-text text-muted"
|
||||||
|
>얻고자 하는 유니크 아이템을 포인트를 걸어 입찰합니다. 최고
|
||||||
|
포인트인 경우 다음 턴에 유니크를 얻습니다.<br /><span
|
||||||
|
style="color: white"
|
||||||
|
v-html="availableUnique[specificUnique].info"
|
||||||
|
/></small>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row px-4">
|
||||||
|
<b-button
|
||||||
|
class="col-6 offset-6"
|
||||||
|
variant="primary"
|
||||||
|
@click="buySpecificUnique"
|
||||||
|
>구입</b-button
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style="width: 100%; padding: 0 10px">
|
||||||
|
<hr :style="{ opacity: 0.5 }" />
|
||||||
|
</div>
|
||||||
|
<div class="row py-sm-2">
|
||||||
|
<div class="col col-md-4 col-sm-6 col-12 py-2">
|
||||||
|
<div class="row px-4">
|
||||||
|
<div class="a-right col-6 align-self-center">랜덤 턴 초기화</div>
|
||||||
|
<b-button
|
||||||
|
class="col-6"
|
||||||
|
variant="primary"
|
||||||
|
@click="buySimple('ResetTurnTime')"
|
||||||
|
>구입</b-button
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="a-right">
|
||||||
|
<small class="form-text text-muted"
|
||||||
|
>다음 턴이 랜덤으로 바뀝니다.<br /><span style="color: white"
|
||||||
|
>필요 포인트: {{ inheritActionCost.resetTurnTime }}</span
|
||||||
|
></small
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col col-md-4 col-sm-6 col-12 py-2">
|
||||||
|
<div class="row px-4">
|
||||||
|
<div class="a-right col-6 align-self-center">랜덤 유니크 획득</div>
|
||||||
|
<b-button
|
||||||
|
class="col-6"
|
||||||
|
variant="primary"
|
||||||
|
@click="buySimple('BuyRandomUnique')"
|
||||||
|
>구입</b-button
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="a-right">
|
||||||
|
<small class="form-text text-muted"
|
||||||
|
>다음 턴에 랜덤 유니크를 얻습니다.<br /><span style="color: white"
|
||||||
|
>필요 포인트: {{ inheritActionCost.randomUnique }}</span
|
||||||
|
></small
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col col-md-4 col-sm-6 col-12 py-2">
|
||||||
|
<div class="row px-4">
|
||||||
|
<div class="a-right col-6 align-self-center">
|
||||||
|
즉시 전투 특기 초기화
|
||||||
|
</div>
|
||||||
|
<b-button
|
||||||
|
class="col-6"
|
||||||
|
variant="primary"
|
||||||
|
@click="buySimple('ResetSpecialWar')"
|
||||||
|
>구입</b-button
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="a-right">
|
||||||
|
<small class="form-text text-muted"
|
||||||
|
>즉시 전투 특기를 초기화합니다.<br /><span style="color: white"
|
||||||
|
>필요 포인트: {{ inheritActionCost.resetSpecialWar }}</span
|
||||||
|
></small
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style="width: 100%; padding: 0 10px">
|
||||||
|
<hr :style="{ opacity: 0.5 }" />
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div
|
||||||
|
class="col col-md-4 col-sm-6 col-12"
|
||||||
|
v-for="(info, buffKey) in inheritBuffHelpText"
|
||||||
|
:key="buffKey"
|
||||||
|
>
|
||||||
|
<div class="row">
|
||||||
|
<label class="col col-sm-6 col-form-label" :for="`buff-${buffKey}`">{{
|
||||||
|
info.title
|
||||||
|
}}</label>
|
||||||
|
<div class="col col-sm-6">
|
||||||
|
<b-form-input
|
||||||
|
:id="`buff-${buffKey}`"
|
||||||
|
type="number"
|
||||||
|
v-model="inheritBuff[buffKey]"
|
||||||
|
:min="prevInheritBuff[buffKey] ?? 0"
|
||||||
|
:max="maxInheritBuff"
|
||||||
|
></b-form-input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style="text-align: right">
|
||||||
|
<small class="form-text text-muted"
|
||||||
|
>{{ info.info }}<br /><span style="color: white"
|
||||||
|
>필요 포인트:
|
||||||
|
{{
|
||||||
|
inheritActionCost.buff[inheritBuff[buffKey]] -
|
||||||
|
inheritActionCost.buff[prevInheritBuff[buffKey] ?? 0]
|
||||||
|
}}</span
|
||||||
|
></small
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="row px-4" style="margin-bottom: 1em">
|
||||||
|
<b-button
|
||||||
|
variant="secondary"
|
||||||
|
@click="inheritBuff[buffKey] = prevInheritBuff[buffKey] ?? 0"
|
||||||
|
class="col col-md-6 col-4 offset-md-0 offset-4"
|
||||||
|
>리셋</b-button
|
||||||
|
><b-button
|
||||||
|
variant="primary"
|
||||||
|
class="col col-md-6 col-4"
|
||||||
|
@click="buyInheritBuff(buffKey)"
|
||||||
|
>구입</b-button
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, PropType } from "vue";
|
import { defineComponent } from "vue";
|
||||||
import "../scss/bootstrap5.scss";
|
import "../scss/bootstrap5.scss";
|
||||||
import "../scss/inheritPoint.scss";
|
|
||||||
import "../scss/game_bg.scss";
|
import "../scss/game_bg.scss";
|
||||||
import TopBackBar from "./components/TopBackBar.vue";
|
import TopBackBar from "./components/TopBackBar.vue";
|
||||||
import { sum } from "lodash";
|
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
|
import { InvalidResponse } from "./defs";
|
||||||
|
import axios from "axios";
|
||||||
|
import NumberInputWithInfo from "./components/NumberInputWithInfo.vue";
|
||||||
|
|
||||||
type InheritanceType =
|
type InheritanceType =
|
||||||
| "previous"
|
| "previous"
|
||||||
@@ -121,9 +323,99 @@ const inheritanceViewText: Record<
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type inheritBuffType =
|
||||||
|
| "warAvoidRatio"
|
||||||
|
| "warCriticalRatio"
|
||||||
|
| "warMagicTrialProb"
|
||||||
|
| "domesticSuccessProb"
|
||||||
|
| "domesticFailProb"
|
||||||
|
| "warAvoidRatioOppose"
|
||||||
|
| "warCriticalRatioOppose"
|
||||||
|
| "warMagicTrialProbOppose";
|
||||||
|
|
||||||
|
declare const currentInheritBuff: {
|
||||||
|
[v in inheritBuffType]: number | undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
const inheritBuffHelpText: Record<
|
||||||
|
inheritBuffType,
|
||||||
|
{
|
||||||
|
title: string;
|
||||||
|
info: string;
|
||||||
|
}
|
||||||
|
> = {
|
||||||
|
warAvoidRatio: {
|
||||||
|
title: "회피 확률 증가",
|
||||||
|
info: "전투 시 회피 확률이 1%p ~ 5%p 증가합니다.",
|
||||||
|
},
|
||||||
|
warCriticalRatio: {
|
||||||
|
title: "필살 확률 증가",
|
||||||
|
info: "전투 시 필살 확률이 1%p ~ 5%p 증가합니다.",
|
||||||
|
},
|
||||||
|
warMagicTrialProb: {
|
||||||
|
title: "계략 시도 확률 증가",
|
||||||
|
info: "전투 시 계략을 시도할 확률이 1%p ~ 5%p 증가합니다. 무장도 계략을 시도합니다.",
|
||||||
|
},
|
||||||
|
warAvoidRatioOppose: {
|
||||||
|
title: "상대 회피 확률 감소",
|
||||||
|
info: "전투 시 상대의 회피 확률이 1%p ~ 5%p 감소합니다.",
|
||||||
|
},
|
||||||
|
warCriticalRatioOppose: {
|
||||||
|
title: "상대 필살 확률 감소",
|
||||||
|
info: "전투 시 상대의 필살 확률이 1%p ~ 5%p 감소합니다.",
|
||||||
|
},
|
||||||
|
warMagicTrialProbOppose: {
|
||||||
|
title: "상대 계략 시도 확률 감소",
|
||||||
|
info: "전투 시 상대의 계략 시도 확률이 1%p ~ 5%p 감소합니다.",
|
||||||
|
},
|
||||||
|
domesticSuccessProb: {
|
||||||
|
title: "내정 성공 확률 증가",
|
||||||
|
info: "민심, 인구, 농업, 상업, 치안, 수비, 성벽, 기술 내정의 성공 확률이 1%p ~ 5%p 증가합니다.",
|
||||||
|
},
|
||||||
|
domesticFailProb: {
|
||||||
|
title: "내정 실패 확률 감소",
|
||||||
|
info: "민심, 인구, 농업, 상업, 치안, 수비, 성벽, 기술 내정의 실패 확률이 1%p ~ 5%p 감소합니다.",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
declare const maxInheritBuff: number;
|
||||||
|
declare const inheritActionCost: {
|
||||||
|
buff: number[];
|
||||||
|
resetTurnTime: number;
|
||||||
|
resetSpecialWar: number;
|
||||||
|
randomUnique: number;
|
||||||
|
nextSpecial: number;
|
||||||
|
minSpecificUnique: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
declare const resetTurnTimeLevel: number;
|
||||||
|
declare const resetSpecialWarLevel: number;
|
||||||
|
|
||||||
|
declare const availableSpecialWar: Record<
|
||||||
|
string,
|
||||||
|
{
|
||||||
|
title: string;
|
||||||
|
info: string;
|
||||||
|
}
|
||||||
|
>;
|
||||||
|
|
||||||
|
declare const availableUnique: Record<
|
||||||
|
string,
|
||||||
|
{
|
||||||
|
title: string;
|
||||||
|
info: string;
|
||||||
|
}
|
||||||
|
>;
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "InheritPoint",
|
name: "InheritPoint",
|
||||||
data() {
|
data() {
|
||||||
|
const inheritBuff = {} as Record<inheritBuffType, number>;
|
||||||
|
for (const buffKey of Object.keys(
|
||||||
|
inheritBuffHelpText
|
||||||
|
) as inheritBuffType[]) {
|
||||||
|
inheritBuff[buffKey] = currentInheritBuff[buffKey] ?? 0;
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
title: "유산 관리",
|
title: "유산 관리",
|
||||||
inheritanceViewText,
|
inheritanceViewText,
|
||||||
@@ -138,14 +430,245 @@ export default defineComponent({
|
|||||||
};
|
};
|
||||||
return result;
|
return result;
|
||||||
})(),
|
})(),
|
||||||
|
inheritBuffHelpText,
|
||||||
|
inheritBuff,
|
||||||
|
prevInheritBuff: currentInheritBuff,
|
||||||
|
maxInheritBuff,
|
||||||
|
inheritActionCost,
|
||||||
|
resetTurnTimeLevel,
|
||||||
|
resetSpecialWarLevel,
|
||||||
|
nextSpecialWar: Object.keys(availableSpecialWar)[0],
|
||||||
|
specificUnique: Object.keys(availableUnique)[0],
|
||||||
|
availableSpecialWar,
|
||||||
|
availableUnique,
|
||||||
|
specificUniqueAmount: inheritActionCost.minSpecificUnique,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
methods: {
|
||||||
|
async buyInheritBuff(buffKey: inheritBuffType) {
|
||||||
|
const level = this.inheritBuff[buffKey];
|
||||||
|
const prevLevel = this.prevInheritBuff[buffKey] ?? 0;
|
||||||
|
if (level == prevLevel) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (level < prevLevel) {
|
||||||
|
alert("낮출 수 없습니다.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const cost =
|
||||||
|
this.inheritActionCost.buff[level] -
|
||||||
|
this.inheritActionCost.buff[prevLevel];
|
||||||
|
if (this.items.previous < cost) {
|
||||||
|
alert("유산 포인트가 부족합니다.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const name = inheritBuffHelpText[buffKey].title;
|
||||||
|
|
||||||
|
if (
|
||||||
|
!confirm(
|
||||||
|
`${name}를 ${level}등급으로 올릴까요? ${cost} 포인트가 소모됩니다.`
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let result: InvalidResponse;
|
||||||
|
try {
|
||||||
|
const response = await axios({
|
||||||
|
url: "api.php",
|
||||||
|
method: "post",
|
||||||
|
responseType: "json",
|
||||||
|
data: {
|
||||||
|
path: "InheritAction/BuyHiddenBuff",
|
||||||
|
args: {
|
||||||
|
type: buffKey,
|
||||||
|
level,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
result = response.data;
|
||||||
|
if (!result.result) {
|
||||||
|
throw result.reason;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
alert(`실패했습니다: ${e}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
alert("성공했습니다.");
|
||||||
|
//TODO: 페이지 새로고침 필요없이 하도록
|
||||||
|
location.reload();
|
||||||
|
},
|
||||||
|
async buySimple(
|
||||||
|
type: "ResetTurnTime" | "BuyRandomUnique" | "ResetSpecialWar"
|
||||||
|
) {
|
||||||
|
const costMap: Record<typeof type, number> = {
|
||||||
|
ResetTurnTime: inheritActionCost.resetTurnTime,
|
||||||
|
ResetSpecialWar: inheritActionCost.resetSpecialWar,
|
||||||
|
BuyRandomUnique: inheritActionCost.randomUnique,
|
||||||
|
};
|
||||||
|
|
||||||
|
const cost = costMap[type];
|
||||||
|
if (cost === undefined) {
|
||||||
|
alert(`올바르지 않은 타입:${type}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const messageMap: Record<typeof type, string> = {
|
||||||
|
ResetTurnTime: `${cost} 포인트로 턴을 초기화 하시겠습니까?`,
|
||||||
|
ResetSpecialWar: `${cost} 포인트로 전투 특기를 초기화 하시겠습니까?`,
|
||||||
|
BuyRandomUnique: `${cost} 포인트로 랜덤 유니크를 구입하시겠습니까?`,
|
||||||
|
};
|
||||||
|
if (this.items.previous < cost) {
|
||||||
|
alert("유산 포인트가 부족합니다.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!confirm(messageMap[type])) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let result: InvalidResponse;
|
||||||
|
try {
|
||||||
|
const response = await axios({
|
||||||
|
url: "api.php",
|
||||||
|
method: "post",
|
||||||
|
responseType: "json",
|
||||||
|
data: {
|
||||||
|
path: `InheritAction/${type}`,
|
||||||
|
args: {},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
result = response.data;
|
||||||
|
if (!result.result) {
|
||||||
|
throw result.reason;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
alert(`실패했습니다: ${e}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
alert("성공했습니다.");
|
||||||
|
//TODO: 페이지 새로고침 필요없이 하도록
|
||||||
|
location.reload();
|
||||||
|
},
|
||||||
|
async setNextSpecialWar() {
|
||||||
|
const specialWarName =
|
||||||
|
this.availableSpecialWar[this.nextSpecialWar].title ?? undefined;
|
||||||
|
if (specialWarName === undefined) {
|
||||||
|
alert(`잘못된 타입: ${this.nextSpecialWar}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const cost = inheritActionCost.nextSpecial;
|
||||||
|
if (this.items.previous < cost) {
|
||||||
|
alert("유산 포인트가 부족합니다.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//TODO: JosaUtil
|
||||||
|
if (
|
||||||
|
!confirm(
|
||||||
|
`${cost} 포인트로 다음 전특을 ${specialWarName}(으)로 고정하겠습니까?`
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let result: InvalidResponse;
|
||||||
|
try {
|
||||||
|
const response = await axios({
|
||||||
|
url: "api.php",
|
||||||
|
method: "post",
|
||||||
|
responseType: "json",
|
||||||
|
data: {
|
||||||
|
path: `InheritAction/SetNextSpecialWar`,
|
||||||
|
args: {
|
||||||
|
type: this.nextSpecialWar,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
result = response.data;
|
||||||
|
if (!result.result) {
|
||||||
|
throw result.reason;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
alert(`실패했습니다: ${e}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
alert("성공했습니다.");
|
||||||
|
//TODO: 페이지 새로고침 필요없이 하도록
|
||||||
|
location.reload();
|
||||||
|
},
|
||||||
|
async buySpecificUnique() {
|
||||||
|
const uniqueName =
|
||||||
|
this.availableUnique[this.specificUnique].title ?? undefined;
|
||||||
|
if (uniqueName === undefined) {
|
||||||
|
alert(`잘못된 타입: ${this.specificUnique}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const amount = this.specificUniqueAmount;
|
||||||
|
if (this.items.previous < amount) {
|
||||||
|
alert("유산 포인트가 부족합니다.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//TODO: JosaUtil
|
||||||
|
if (
|
||||||
|
!confirm(
|
||||||
|
`${amount} 포인트로 ${uniqueName}(을)를 입찰하겠습니까?`
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let result: InvalidResponse;
|
||||||
|
try {
|
||||||
|
const response = await axios({
|
||||||
|
url: "api.php",
|
||||||
|
method: "post",
|
||||||
|
responseType: "json",
|
||||||
|
data: {
|
||||||
|
path: `InheritAction/BuySpecificUnique`,
|
||||||
|
args: {
|
||||||
|
item: this.specificUnique,
|
||||||
|
amount,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
result = response.data;
|
||||||
|
if (!result.result) {
|
||||||
|
throw result.reason;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
alert(`실패했습니다: ${e}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
alert("성공했습니다.");
|
||||||
|
//TODO: 페이지 새로고침 필요없이 하도록
|
||||||
|
location.reload();
|
||||||
|
},
|
||||||
|
},
|
||||||
components: {
|
components: {
|
||||||
TopBackBar,
|
TopBackBar,
|
||||||
|
NumberInputWithInfo,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
.col-form-label {
|
||||||
|
text-align: right;
|
||||||
|
padding-right: 2ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inherit_value {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
import "../../scss/inheritPoint.scss";
|
|
||||||
|
|
||||||
import { sum } from "lodash";
|
|
||||||
import { unwrap } from "../util/unwrap";
|
|
||||||
declare global {
|
|
||||||
interface Window {
|
|
||||||
formStart: ()=>void;
|
|
||||||
items: {[name: string]:number};
|
|
||||||
helpText: {[name: string]:string};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function formStart() {
|
|
||||||
|
|
||||||
const dSum = unwrap(document.querySelector('#inherit_sum_value')) as HTMLInputElement ;
|
|
||||||
const dOld = unwrap(document.querySelector('#inherit_previous_value')) as HTMLInputElement;
|
|
||||||
const dNew = unwrap(document.querySelector('#inherit_new_value')) as HTMLInputElement;
|
|
||||||
|
|
||||||
const sumPoint = Math.floor(sum(Object.values(window.items)));
|
|
||||||
const oldPoint = Math.floor(window.items['previous']);
|
|
||||||
const sumNewPoint = sumPoint - oldPoint;
|
|
||||||
|
|
||||||
dSum.value = sumPoint.toLocaleString();
|
|
||||||
dOld.value = oldPoint.toLocaleString();
|
|
||||||
dNew.value = sumNewPoint.toLocaleString();
|
|
||||||
|
|
||||||
for(const [key, val] of Object.entries(window.items)){
|
|
||||||
const dItem = unwrap(document.querySelector(`#inherit_${key}_value`)) as HTMLInputElement ;
|
|
||||||
dItem.value = Math.floor(val).toLocaleString();
|
|
||||||
}
|
|
||||||
|
|
||||||
for(const [key, text] of Object.entries(window.helpText)){
|
|
||||||
const dText = unwrap(document.querySelector(`#inherit_${key} small.form-text`)) as HTMLElement;
|
|
||||||
dText.innerHTML = text;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
formStart();
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import { exportWindow } from './util/exportWindow';
|
import { exportWindow } from '../util/exportWindow';
|
||||||
import { mb_strwidth } from './util/mb_strwidth';
|
import { mb_strwidth } from '../util/mb_strwidth';
|
||||||
import { unwrap_any } from './util/unwrap_any';
|
import { unwrap_any } from '../util/unwrap_any';
|
||||||
|
|
||||||
declare const defaultStatTotal: number;
|
declare const defaultStatTotal: number;
|
||||||
declare const defaultStatMax: number;
|
declare const defaultStatMax: number;
|
||||||
+1
-1
@@ -4,7 +4,7 @@ import { InvalidResponse } from './defs';
|
|||||||
import { getDateTimeNow } from './util/getDateTimeNow';
|
import { getDateTimeNow } from './util/getDateTimeNow';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { convertFormData } from './util/convertFormData';
|
import { convertFormData } from './util/convertFormData';
|
||||||
import { isBrightColor } from './common_legacy';
|
import { isBrightColor } from "./util/isBrightColor";
|
||||||
import { unwrap } from './util/unwrap';
|
import { unwrap } from './util/unwrap';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { addMinutes } from 'date-fns';
|
import { addMinutes } from 'date-fns';
|
||||||
|
|||||||
+3
-2
@@ -9,7 +9,7 @@ import { unwrap_any } from './util/unwrap_any';
|
|||||||
|
|
||||||
type LogResponse = {
|
type LogResponse = {
|
||||||
result: true;
|
result: true;
|
||||||
log: Record<number, string>;
|
log: Record<string, string>;
|
||||||
};
|
};
|
||||||
|
|
||||||
$(function ($) {
|
$(function ($) {
|
||||||
@@ -92,10 +92,11 @@ $(function ($) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const html: string[] = [];
|
const html: string[] = [];
|
||||||
for (const [key, item] of Object.entries(result.log)) {
|
for (const key of Object.values(keys)) {
|
||||||
if ($(`#log_${logType}_${key}`).length) {
|
if ($(`#log_${logType}_${key}`).length) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
const item = result.log[key];
|
||||||
html.push(`<div class='log_${logType}' id='log_${logType}_${key}' data-seq='${key}'>${item}</div>`);
|
html.push(`<div class='log_${logType}' id='log_${logType}_${key}' data-seq='${key}'>${item}</div>`);
|
||||||
}
|
}
|
||||||
$(`#${logType}Plate`).append(html.join(''));
|
$(`#${logType}Plate`).append(html.join(''));
|
||||||
|
|||||||
@@ -2,7 +2,8 @@ import $ from 'jquery';
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { setAxiosXMLHttpRequest } from './util/setAxiosXMLHttpRequest';
|
import { setAxiosXMLHttpRequest } from './util/setAxiosXMLHttpRequest';
|
||||||
import { InvalidResponse } from './defs';
|
import { InvalidResponse } from './defs';
|
||||||
import { getIconPath, initTooltip } from './common_legacy';
|
import { initTooltip } from './common_legacy';
|
||||||
|
import { getIconPath } from "./util/getIconPath";
|
||||||
import { convertFormData } from './util/convertFormData';
|
import { convertFormData } from './util/convertFormData';
|
||||||
import { unwrap_any } from './util/unwrap_any';
|
import { unwrap_any } from './util/unwrap_any';
|
||||||
import { unwrap } from './util/unwrap';
|
import { unwrap } from './util/unwrap';
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { errUnknown, getIconPath } from './common_legacy';
|
import { errUnknown } from './common_legacy';
|
||||||
|
import { getIconPath } from "./util/getIconPath";
|
||||||
import { TemplateEngine } from "./util/TemplateEngine";
|
import { TemplateEngine } from "./util/TemplateEngine";
|
||||||
import { GeneralListResponse, InvalidResponse } from './defs';
|
import { GeneralListResponse, InvalidResponse } from './defs';
|
||||||
import { convertFormData } from './util/convertFormData';
|
import { convertFormData } from './util/convertFormData';
|
||||||
|
|||||||
@@ -0,0 +1,146 @@
|
|||||||
|
declare const stats: {
|
||||||
|
min: number;
|
||||||
|
max: number;
|
||||||
|
total: number;
|
||||||
|
bonusMin: number;
|
||||||
|
bonusMax: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function abilityRand(): [number, number, number] {
|
||||||
|
let leadership = Math.random() * 65 + 10;
|
||||||
|
let strength = Math.random() * 65 + 10;
|
||||||
|
let intel = Math.random() * 65 + 10;
|
||||||
|
const rate = leadership + strength + intel;
|
||||||
|
|
||||||
|
leadership = Math.floor((leadership / rate) * stats.total);
|
||||||
|
strength = Math.floor((strength / rate) * stats.total);
|
||||||
|
intel = Math.floor((intel / rate) * stats.total);
|
||||||
|
|
||||||
|
while (leadership + strength + intel < stats.total) {
|
||||||
|
leadership += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
leadership > stats.max ||
|
||||||
|
strength > stats.max ||
|
||||||
|
intel > stats.max ||
|
||||||
|
leadership < stats.min ||
|
||||||
|
strength < stats.min ||
|
||||||
|
intel < stats.min
|
||||||
|
) {
|
||||||
|
return abilityRand();
|
||||||
|
}
|
||||||
|
|
||||||
|
return [leadership, strength, intel];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function abilityLeadpow(): [number, number, number] {
|
||||||
|
let leadership = Math.random() * 6;
|
||||||
|
let strength = Math.random() * 6;
|
||||||
|
let intel = Math.random() * 1;
|
||||||
|
const rate = leadership + strength + intel;
|
||||||
|
|
||||||
|
leadership = Math.floor((leadership / rate) * stats.total);
|
||||||
|
strength = Math.floor((strength / rate) * stats.total);
|
||||||
|
intel = Math.floor((intel / rate) * stats.total);
|
||||||
|
|
||||||
|
while (leadership + strength + intel < stats.total) {
|
||||||
|
strength += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (intel < stats.min) {
|
||||||
|
leadership -= stats.min - intel;
|
||||||
|
intel = stats.min;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (leadership > stats.max) {
|
||||||
|
strength += leadership - stats.max;
|
||||||
|
leadership = stats.max;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strength > stats.max) {
|
||||||
|
leadership += strength - stats.max;
|
||||||
|
strength = stats.max;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (leadership > stats.max) {
|
||||||
|
intel += leadership - stats.max;
|
||||||
|
leadership = stats.max;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [leadership, strength, intel];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function abilityLeadint(): [number, number, number] {
|
||||||
|
let leadership = Math.random() * 6;
|
||||||
|
let strength = Math.random() * 1;
|
||||||
|
let intel = Math.random() * 6;
|
||||||
|
const rate = leadership + strength + intel;
|
||||||
|
|
||||||
|
leadership = Math.floor((leadership / rate) * stats.total);
|
||||||
|
strength = Math.floor((strength / rate) * stats.total);
|
||||||
|
intel = Math.floor((intel / rate) * stats.total);
|
||||||
|
|
||||||
|
while (leadership + strength + intel < stats.total) {
|
||||||
|
intel += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strength < stats.min) {
|
||||||
|
leadership -= stats.min - strength;
|
||||||
|
strength = stats.min;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (leadership > stats.max) {
|
||||||
|
intel += leadership - stats.max;
|
||||||
|
leadership = stats.max;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (intel > stats.max) {
|
||||||
|
leadership += intel - stats.max;
|
||||||
|
intel = stats.max;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (leadership > stats.max) {
|
||||||
|
strength += leadership - stats.max;
|
||||||
|
leadership = stats.max;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [leadership, strength, intel];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function abilityPowint(): [number, number, number] {
|
||||||
|
let leadership = Math.random() * 1;
|
||||||
|
let strength = Math.random() * 6;
|
||||||
|
let intel = Math.random() * 6;
|
||||||
|
const rate = leadership + strength + intel;
|
||||||
|
|
||||||
|
leadership = Math.floor((leadership / rate) * stats.total);
|
||||||
|
strength = Math.floor((strength / rate) * stats.total);
|
||||||
|
intel = Math.floor((intel / rate) * stats.total);
|
||||||
|
|
||||||
|
while (leadership + strength + intel < stats.total) {
|
||||||
|
intel += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (leadership < stats.min) {
|
||||||
|
strength -= stats.min - leadership;
|
||||||
|
leadership = stats.min;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strength > stats.max) {
|
||||||
|
intel += strength - stats.max;
|
||||||
|
strength = stats.max;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (intel > stats.max) {
|
||||||
|
strength += intel - stats.max;
|
||||||
|
intel = stats.max;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strength > stats.max) {
|
||||||
|
leadership += strength - stats.max;
|
||||||
|
strength = stats.max;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [leadership, strength, intel];
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
export function getIconPath(imgsvr: boolean | 1 | 0, picture: string): string {
|
||||||
|
// ../d_shared/common_path.js 필요
|
||||||
|
if (!imgsvr) {
|
||||||
|
return `${window.pathConfig.sharedIcon}/${picture}`;
|
||||||
|
} else {
|
||||||
|
return `${window.pathConfig.root}/d_pic/${picture}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
export function hexToRgb(hex: string): { r: number; g: number; b: number; } | null {
|
||||||
|
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
||||||
|
return result ? {
|
||||||
|
r: parseInt(result[1], 16),
|
||||||
|
g: parseInt(result[2], 16),
|
||||||
|
b: parseInt(result[3], 16)
|
||||||
|
} : null;
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import { unwrap } from "./unwrap";
|
||||||
|
import { hexToRgb } from "./hexToRgb";
|
||||||
|
|
||||||
|
export function isBrightColor(color: string): boolean {
|
||||||
|
const cv = unwrap(hexToRgb(color));
|
||||||
|
if ((cv.r * 0.299 + cv.g * 0.587 + cv.b * 0.114) > 140) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
import { createApp } from 'vue'
|
import { createApp } from 'vue'
|
||||||
import NPCControl from './NPCControl.vue';
|
import NPCControl from './NPCControl.vue';
|
||||||
|
import BootstrapVue3 from 'bootstrap-vue-3'
|
||||||
|
import "../scss/bootstrap5.scss";
|
||||||
|
import 'bootstrap-vue-3/dist/bootstrap-vue-3.css'
|
||||||
import { setAxiosXMLHttpRequest } from './util/setAxiosXMLHttpRequest';
|
import { setAxiosXMLHttpRequest } from './util/setAxiosXMLHttpRequest';
|
||||||
|
|
||||||
setAxiosXMLHttpRequest();
|
setAxiosXMLHttpRequest();
|
||||||
createApp(NPCControl).mount('#app')
|
createApp(NPCControl).use(BootstrapVue3).mount('#app')
|
||||||
+4
-1
@@ -1,5 +1,8 @@
|
|||||||
import { createApp } from 'vue'
|
import { createApp } from 'vue'
|
||||||
import Board from './Board.vue';
|
import Board from './Board.vue';
|
||||||
|
import BootstrapVue3 from 'bootstrap-vue-3'
|
||||||
|
import "../scss/bootstrap5.scss";
|
||||||
|
import 'bootstrap-vue-3/dist/bootstrap-vue-3.css'
|
||||||
import { setAxiosXMLHttpRequest } from './util/setAxiosXMLHttpRequest';
|
import { setAxiosXMLHttpRequest } from './util/setAxiosXMLHttpRequest';
|
||||||
|
|
||||||
declare const isSecretBoard: boolean;
|
declare const isSecretBoard: boolean;
|
||||||
@@ -8,4 +11,4 @@ declare const isSecretBoard: boolean;
|
|||||||
setAxiosXMLHttpRequest();
|
setAxiosXMLHttpRequest();
|
||||||
createApp(Board, {
|
createApp(Board, {
|
||||||
isSecretBoard
|
isSecretBoard
|
||||||
}).mount('#app')
|
}).use(BootstrapVue3).mount('#app')
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
import { createApp } from 'vue'
|
import { createApp } from 'vue'
|
||||||
import InheritPoint from './inheritPoint.vue';
|
import InheritPoint from './inheritPoint.vue';
|
||||||
|
import BootstrapVue3 from 'bootstrap-vue-3'
|
||||||
createApp(InheritPoint).mount('#app')
|
import "../scss/bootstrap5.scss";
|
||||||
|
import 'bootstrap-vue-3/dist/bootstrap-vue-3.css'
|
||||||
|
createApp(InheritPoint).use(BootstrapVue3).mount('#app');
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import { createApp } from 'vue'
|
||||||
|
import Join from './Join.vue';
|
||||||
|
import BootstrapVue3 from 'bootstrap-vue-3'
|
||||||
|
import "../scss/bootstrap5.scss";
|
||||||
|
import 'bootstrap-vue-3/dist/bootstrap-vue-3.css'
|
||||||
|
|
||||||
|
createApp(Join).use(BootstrapVue3).mount('#app')
|
||||||
@@ -89,7 +89,7 @@ $lastSetters = [
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<meta name="viewport" content="width=device-with" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<title><?= UniqueConst::$serverName ?>: 임시 NPC 정책</title>
|
<title><?= UniqueConst::$serverName ?>: 임시 NPC 정책</title>
|
||||||
<?= WebUtil::printStaticValues([
|
<?= WebUtil::printStaticValues([
|
||||||
'nationID' => $nationID,
|
'nationID' => $nationID,
|
||||||
|
|||||||
+61
-2
@@ -15,10 +15,55 @@ $gameStor = KVStorage::getStorage($db, 'game_env');
|
|||||||
$me = General::createGeneralObjFromDB($generalID);
|
$me = General::createGeneralObjFromDB($generalID);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$currentInheritBuff = [];
|
||||||
|
foreach ($me->getAuxVar('inheritBuff')??[] as $buff => $buffLevel) {
|
||||||
|
if (!key_exists($buff, TriggerInheritBuff::BUFF_KEY_TEXT)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$currentInheritBuff[$buff] = $buffLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
function calcResetAttrPoint($level)
|
||||||
|
{
|
||||||
|
while (count(GameConst::$inheritResetAttrPointBase) <= $level) {
|
||||||
|
$baseLen = count(GameConst::$inheritResetAttrPointBase);
|
||||||
|
GameConst::$inheritResetAttrPointBase[] = GameConst::$inheritResetAttrPointBase[$baseLen - 1] + GameConst::$inheritResetAttrPointBase[$baseLen - 2];
|
||||||
|
}
|
||||||
|
return GameConst::$inheritResetAttrPointBase[$level];
|
||||||
|
}
|
||||||
|
|
||||||
|
$avilableSpecialWar = [];
|
||||||
|
foreach (GameConst::$availableSpecialWar as $specialWarKey) {
|
||||||
|
$specialWarObj = buildGeneralSpecialWarClass($specialWarKey);
|
||||||
|
$avilableSpecialWar[$specialWarKey] = [
|
||||||
|
'title' => $specialWarObj->getName(),
|
||||||
|
'info' => $specialWarObj->getInfo(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$availableUnique = [];
|
||||||
|
foreach (GameConst::$allItems as $subItems){
|
||||||
|
foreach($subItems as $itemKey=>$amount){
|
||||||
|
if($amount == 0){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$itemObj = buildItemClass($itemKey);
|
||||||
|
$availableUnique[$itemKey] = [
|
||||||
|
'title' => $itemObj->getName(),
|
||||||
|
'info'=>$itemObj->getInfo(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
$items = [];
|
$items = [];
|
||||||
foreach (array_keys(General::INHERITANCE_KEY) as $key) {
|
foreach (array_keys(General::INHERITANCE_KEY) as $key) {
|
||||||
$items[$key] = $me->getInheritancePoint($key) ?? 0;
|
$items[$key] = $me->getInheritancePoint($key) ?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$resetTurnTimeLevel = $me->getAuxVar('inheritResetTurnTime') ?? 0;
|
||||||
|
$resetSpecialWarLevel = $me->getAuxVar('inheritResetSpecialWar') ?? 0;
|
||||||
?>
|
?>
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
@@ -27,7 +72,7 @@ foreach (array_keys(General::INHERITANCE_KEY) as $key) {
|
|||||||
<title><?= UniqueConst::$serverName ?>: 유산 관리</title>
|
<title><?= UniqueConst::$serverName ?>: 유산 관리</title>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<meta name="viewport" content="width=1024" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<?= WebUtil::printCSS('dist_css/common_vue.css') ?>
|
<?= WebUtil::printCSS('dist_css/common_vue.css') ?>
|
||||||
<?= WebUtil::printCSS('dist_css/v_inheritPoint.css') ?>
|
<?= WebUtil::printCSS('dist_css/v_inheritPoint.css') ?>
|
||||||
<?= WebUtil::printJS('../d_shared/common_path.js', true) ?>
|
<?= WebUtil::printJS('../d_shared/common_path.js', true) ?>
|
||||||
@@ -35,7 +80,21 @@ foreach (array_keys(General::INHERITANCE_KEY) as $key) {
|
|||||||
<?= WebUtil::printJS('dist_js/common_vue.js', true) ?>
|
<?= WebUtil::printJS('dist_js/common_vue.js', true) ?>
|
||||||
<?= WebUtil::printJS('dist_js/v_inheritPoint.js', true) ?>
|
<?= WebUtil::printJS('dist_js/v_inheritPoint.js', true) ?>
|
||||||
<?= WebUtil::printStaticValues([
|
<?= WebUtil::printStaticValues([
|
||||||
'items' => $items
|
'items' => $items,
|
||||||
|
'currentInheritBuff' => $currentInheritBuff,
|
||||||
|
'maxInheritBuff' => TriggerInheritBuff::MAX_STEP,
|
||||||
|
'resetTurnTimeLevel' => $resetTurnTimeLevel,
|
||||||
|
'resetSpecialWarLevel' => $resetSpecialWarLevel,
|
||||||
|
'inheritActionCost' => [
|
||||||
|
'buff' => GameConst::$inheritBuffPoints,
|
||||||
|
'resetTurnTime' => calcResetAttrPoint($resetTurnTimeLevel),
|
||||||
|
'resetSpecialWar' => calcResetAttrPoint($resetSpecialWarLevel),
|
||||||
|
'randomUnique' => GameConst::$inheritItemRandomPoint,
|
||||||
|
'nextSpecial' => GameConst::$inheritSpecificSpecialPoint,
|
||||||
|
'minSpecificUnique'=>GameConst::$inheritItemUniqueMinPoint,
|
||||||
|
],
|
||||||
|
'availableSpecialWar' => $avilableSpecialWar,
|
||||||
|
'availableUnique' => $availableUnique,
|
||||||
]) ?>
|
]) ?>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
|||||||
+129
@@ -0,0 +1,129 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace sammo;
|
||||||
|
|
||||||
|
include "lib.php";
|
||||||
|
include "func.php";
|
||||||
|
//로그인 검사
|
||||||
|
|
||||||
|
$session = Session::requireLogin()->setReadOnly();
|
||||||
|
$userID = Session::getUserID();
|
||||||
|
|
||||||
|
if (!$userID) {
|
||||||
|
die(WebUtil::errorBackMsg("잘못된 접근입니다!!!"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//회원 테이블에서 정보확인
|
||||||
|
$member = RootDB::db()->queryFirstRow("SELECT no,name,picture,imgsvr,grade from member where no= %i", $userID);
|
||||||
|
if (!$member) {
|
||||||
|
die(WebUtil::errorBackMsg("잘못된 접근입니다!!!"));
|
||||||
|
}
|
||||||
|
|
||||||
|
$db = DB::db();
|
||||||
|
|
||||||
|
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||||
|
$admin = $gameStor->getValues(['block_general_create', 'show_img_level', 'maxgeneral', 'turnterm']);
|
||||||
|
if ($admin['block_general_create']) {
|
||||||
|
die(WebUtil::errorBackMsg("잘못된 접근입니다!!!"));
|
||||||
|
}
|
||||||
|
|
||||||
|
$alreadyJoined = $db->queryFirstField('SELECT name FROM general WHERE owner = %i', $userID);
|
||||||
|
if ($alreadyJoined) {
|
||||||
|
die(WebUtil::errorBackMsg("이미 장수를 생성했습니다: {$alreadyJoined}", './'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$gencount = $db->queryFirstField('SELECT count(no) FROM general WHERE npc<2');
|
||||||
|
if ($gencount >= $admin['maxgeneral']) {
|
||||||
|
die(WebUtil::errorBackMsg("더 이상 등록할 수 없습니다."));
|
||||||
|
}
|
||||||
|
|
||||||
|
$inheritTotalPoint = resetInheritanceUser($userID);
|
||||||
|
|
||||||
|
$nationList = $db->query('SELECT nation,`name`,color,scout FROM nation');
|
||||||
|
$nationList = Util::convertArrayToDict($nationList, 'nation');
|
||||||
|
//NOTE: join 안할것임
|
||||||
|
$scoutMsgs = KVStorage::getValuesFromInterNamespace($db, 'nation_env', 'scout_msg');
|
||||||
|
foreach ($scoutMsgs as $nationID => $scoutMsg) {
|
||||||
|
$nationList[$nationID]['scoutmsg'] = $scoutMsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$availablePersonality = [];
|
||||||
|
foreach (GameConst::$availablePersonality as $personalityID) {
|
||||||
|
$personalityObj = buildPersonalityClass($personalityID);
|
||||||
|
$availablePersonality[$personalityID] = [
|
||||||
|
'name' => $personalityObj->getName(),
|
||||||
|
'info' => $personalityObj->getInfo(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$availableInheritSpecial = [];
|
||||||
|
foreach (GameConst::$availableSpecialWar as $specialID){
|
||||||
|
$specialObj = buildGeneralSpecialWarClass($specialID);
|
||||||
|
$availableInheritSpecial[$specialID] = [
|
||||||
|
'name' => $specialObj->getName(),
|
||||||
|
'info' => $specialObj->getInfo(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$availableInheritCity = [];
|
||||||
|
foreach(CityConst::all() as $city){
|
||||||
|
$availableInheritCity[] = [$city->id, CityConst::$regionMap[$city->region], $city->name];
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title><?= UniqueConst::$serverName ?>: 장수 생성</title>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<?= WebUtil::printCSS('dist_css/common_vue.css') ?>
|
||||||
|
<?= WebUtil::printCSS('dist_css/v_join.css') ?>
|
||||||
|
<?= WebUtil::printJS('../d_shared/common_path.js', true) ?>
|
||||||
|
<?= WebUtil::printJS('dist_js/vendors_vue.js', true) ?>
|
||||||
|
<?= WebUtil::printJS('dist_js/common_vue.js', true) ?>
|
||||||
|
<?= WebUtil::printJS('dist_js/v_join.js', true) ?>
|
||||||
|
<?= WebUtil::printStaticValues([
|
||||||
|
'serverID' => UniqueConst::$serverID,
|
||||||
|
'nationList' => array_values($nationList),
|
||||||
|
'config' => [
|
||||||
|
'show_img_level' => $admin['show_img_level']
|
||||||
|
],
|
||||||
|
'member' => [
|
||||||
|
'name' => $member['name'],
|
||||||
|
'grade' => $member['grade'],
|
||||||
|
'picture' => $member['picture'],
|
||||||
|
'imgsvr' => $member['imgsvr'],
|
||||||
|
],
|
||||||
|
'availablePersonality' => array_merge([
|
||||||
|
'Random' => ['name' => '???', 'info' => '무작위 성격을 선택합니다.']
|
||||||
|
], $availablePersonality),
|
||||||
|
'stats' => [
|
||||||
|
'min' => GameConst::$defaultStatMin,
|
||||||
|
'max' => GameConst::$defaultStatMax,
|
||||||
|
'total' => GameConst::$defaultStatTotal,
|
||||||
|
'bonusMin' => GameConst::$bornMinStatBonus,
|
||||||
|
'bonusMax' => GameConst::$bornMaxStatBonus,
|
||||||
|
],
|
||||||
|
'inheritTotalPoint'=>$inheritTotalPoint,
|
||||||
|
'inheritPoints'=>[
|
||||||
|
'special'=>GameConst::$inheritBornSpecialPoint,
|
||||||
|
'turnTime'=>GameConst::$inheritBornTurntimePoint,
|
||||||
|
'city'=>GameConst::$inheritBornCityPoint,
|
||||||
|
'stat'=>GameConst::$inheritBornStatPoint
|
||||||
|
],
|
||||||
|
'availableInheritSpecial' => $availableInheritSpecial,
|
||||||
|
'availableInheritCity'=> $availableInheritCity,
|
||||||
|
'turnterm'=>$gameStor->turnterm,
|
||||||
|
]) ?>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
@@ -34,9 +34,9 @@ $acl = $session->acl;
|
|||||||
<script>
|
<script>
|
||||||
var isAdmin = <?=($userGrade >= 5 || $acl)?'true':'false'?>;
|
var isAdmin = <?=($userGrade >= 5 || $acl)?'true':'false'?>;
|
||||||
</script>
|
</script>
|
||||||
<?=WebUtil::printJS('../d_shared/common_path.js') ?>
|
<?=WebUtil::printJS('../d_shared/common_path.js', true) ?>
|
||||||
<?=WebUtil::printJS('../dist_js/vendors.js') ?>
|
<?=WebUtil::printJS('../dist_js/vendors.js', true) ?>
|
||||||
<?=WebUtil::printJS('../dist_js/entrance.js')?>
|
<?=WebUtil::printJS('../dist_js/entrance.js', true)?>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
@@ -80,8 +80,8 @@ foreach (ServConfig::getServerList() as $setting) {
|
|||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<div class="container" style="margin-top:120px;">
|
<div class="container" style="margin-top:120px;">
|
||||||
<h1 class="row justify-content-md-center">삼국지 모의전투 HiDCHe</h1>
|
<h1 class="row justify-content-center">삼국지 모의전투 HiDCHe</h1>
|
||||||
<div class="row justify-content-md-center">
|
<div class="row justify-content-center">
|
||||||
<div class="col" style="max-width:450px;">
|
<div class="col" style="max-width:450px;">
|
||||||
<div class="card" id="login_card">
|
<div class="card" id="login_card">
|
||||||
<h3 class="card-header">
|
<h3 class="card-header">
|
||||||
@@ -126,15 +126,16 @@ foreach (ServConfig::getServerList() as $setting) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<?php if ($runningServer) : ?>
|
<?php if ($runningServer) : ?>
|
||||||
<div class="row justify-content-md-center" style='margin-top:20px;'>
|
<div class="d-flex justify-content-center" id="map-subframe-p" style='margin-top:20px;'>
|
||||||
<div class="col" style="max-width:750px;">
|
<div id="map-subframe">
|
||||||
<iframe id="running_map" src="<?= $runningServer['name'] ?>/recent_map.php"></iframe>
|
<iframe id="running_map" src="<?= $runningServer['name'] ?>/recent_map.php"></iframe>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="bottom_box">
|
<div id="bottom_box">
|
||||||
<div class="container"><a href="terms.2.html">개인정보처리방침</a> & <a href="terms.1.html">이용약관</a><br>© 2020 • HideD
|
<div class="container"><a href="terms.2.html">개인정보처리방침</a> & <a href="terms.1.html">이용약관</a><br>© 2021 • HideD
|
||||||
<br>크롬과 파이어폭스에 최적화되어있습니다.
|
<br>크롬과 파이어폭스에 최적화되어있습니다.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+6
-3
@@ -19,7 +19,6 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@coreui/vue": "^4.0.0-beta.2",
|
|
||||||
"@types/downloadjs": "^1.4.2",
|
"@types/downloadjs": "^1.4.2",
|
||||||
"@types/linkifyjs": "^2.1.4",
|
"@types/linkifyjs": "^2.1.4",
|
||||||
"@types/select2": "^4.0.54",
|
"@types/select2": "^4.0.54",
|
||||||
@@ -48,6 +47,7 @@
|
|||||||
"@babel/core": "^7.15.5",
|
"@babel/core": "^7.15.5",
|
||||||
"@babel/preset-env": "^7.15.4",
|
"@babel/preset-env": "^7.15.4",
|
||||||
"@babel/preset-typescript": "^7.15.0",
|
"@babel/preset-typescript": "^7.15.0",
|
||||||
|
"@coreui/vue": "^4.0.0-beta.2",
|
||||||
"@types/bootstrap": "^5.1.4",
|
"@types/bootstrap": "^5.1.4",
|
||||||
"@types/jquery": "^3.5.6",
|
"@types/jquery": "^3.5.6",
|
||||||
"@types/lodash": "^4.14.172",
|
"@types/lodash": "^4.14.172",
|
||||||
@@ -59,6 +59,7 @@
|
|||||||
"babel-loader": "^8.2.2",
|
"babel-loader": "^8.2.2",
|
||||||
"babel-plugin-lodash": "^3.3.4",
|
"babel-plugin-lodash": "^3.3.4",
|
||||||
"babel-preset-modern-browsers": "^15.0.2",
|
"babel-preset-modern-browsers": "^15.0.2",
|
||||||
|
"bootstrap-vue-3": "^0.0.3",
|
||||||
"bootswatch": "^5.1.1",
|
"bootswatch": "^5.1.1",
|
||||||
"clean-terminal-webpack-plugin": "^3.0.0",
|
"clean-terminal-webpack-plugin": "^3.0.0",
|
||||||
"css-loader": "^6.2.0",
|
"css-loader": "^6.2.0",
|
||||||
@@ -84,8 +85,10 @@
|
|||||||
"lint"
|
"lint"
|
||||||
],
|
],
|
||||||
"browserslist": [
|
"browserslist": [
|
||||||
|
"last 3 versions",
|
||||||
"> 0.4%",
|
"> 0.4%",
|
||||||
"not ie <= 11",
|
"not dead",
|
||||||
"not op_mini all"
|
"not op_mini all",
|
||||||
|
"not ie <= 11"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,103 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace sammo;
|
||||||
|
|
||||||
|
class APIHelper
|
||||||
|
{
|
||||||
|
private function __construct()
|
||||||
|
{
|
||||||
|
//static only
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function launch(string $rootPath)
|
||||||
|
{
|
||||||
|
//TODO: path를 php://input에서 받는게 아니라 api.php?~~~~~ 로 받아오는것이 etag 캐시 측면에서 훨씬 나을 듯!
|
||||||
|
try {
|
||||||
|
$rawInput = file_get_contents('php://input');
|
||||||
|
$input = Json::decode($rawInput);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
Json::dieWithReason($e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!$input){
|
||||||
|
Json::dieWithReason("input이 비어있습니다. {$rawInput}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!key_exists('path', $input)) {
|
||||||
|
Json::dieWithReason('path가 지정되지 않았습니다.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key_exists('args', $input) && !is_array($input['args'])) {
|
||||||
|
Json::dieWithReason('args가 array가 아닙니다.' . gettype($input['args']));
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$obj = buildAPIExecutorClass($input['path'], $rootPath, $input['args'] ?? []);
|
||||||
|
$validateResult = $obj->validateArgs();
|
||||||
|
if ($validateResult !== null) {
|
||||||
|
Json::dieWithReason($validateResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
$sessionMode = $obj->getRequiredSessionMode();
|
||||||
|
if ($sessionMode === BaseAPI::NO_SESSION) {
|
||||||
|
$session = null;
|
||||||
|
} else {
|
||||||
|
if ($sessionMode & BaseAPI::REQ_GAME_LOGIN) {
|
||||||
|
$session = Session::requireGameLogin();
|
||||||
|
} else if ($sessionMode & BaseAPI::REQ_LOGIN) {
|
||||||
|
$session = Session::requireLogin();
|
||||||
|
} else {
|
||||||
|
Json::dieWithReason("올바르지 않은 SessionMode: {$sessionMode}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($sessionMode & BaseAPI::REQ_READ_ONLY) {
|
||||||
|
$session->setReadOnly();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$modifiedSince = isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])
|
||||||
|
? new \DateTimeImmutable($_SERVER['HTTP_IF_MODIFIED_SINCE'], new \DateTimeZone("UTC"))
|
||||||
|
: null;
|
||||||
|
$reqEtags = isset($_SERVER['HTTP_IF_NONE_MATCH']) ? trim($_SERVER['HTTP_IF_NONE_MATCH']) : null;
|
||||||
|
|
||||||
|
$result = $obj->launch($session, $modifiedSince, $reqEtags);
|
||||||
|
if (is_string($result)) {
|
||||||
|
Json::dieWithReason($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
$cacheResult = $obj->tryCache();
|
||||||
|
if ($cacheResult !== null) {
|
||||||
|
/** @var \DateTimeInterface $lastModified */
|
||||||
|
[$lastModified, $etag] = $cacheResult;
|
||||||
|
|
||||||
|
if ($lastModified !== null) {
|
||||||
|
header("Last-Modified: " . gmdate("D, d M Y H:i:s", TimeUtil::DateTimeToSeconds($lastModified, true)) . " GMT");
|
||||||
|
}
|
||||||
|
if ($etag !== null) {
|
||||||
|
header("Etag: $etag");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($modifiedSince !== null && $lastModified !== null && TimeUtil::DateIntervalToSeconds($modifiedSince->diff($lastModified)) == 0) {
|
||||||
|
header("HTTP/1.1 304 Not Modified");
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
if ($reqEtags !== null && $reqEtags === $etag) {
|
||||||
|
header("HTTP/1.1 304 Not Modified");
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($result === null) {
|
||||||
|
Json::die([
|
||||||
|
'result' => true,
|
||||||
|
'reason' => 'success'
|
||||||
|
], $cacheResult === null ? Json::NO_CACHE : 0);
|
||||||
|
}
|
||||||
|
Json::die($result, $cacheResult === null ? Json::NO_CACHE : 0);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
Json::dieWithReason($e->getMessage());
|
||||||
|
} catch (mixed $e) {
|
||||||
|
Json::dieWithReason($e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+11
-3
@@ -34,7 +34,7 @@ class Json
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static function decodeObj($value){
|
public static function decodeObj($value){
|
||||||
//NOTE: 구 코드가 모두 '배열'을 가정하기 때문에 decode는 연관배열로 반환하였으나,
|
//NOTE: 구 코드가 모두 '배열'을 가정하기 때문에 decode는 연관배열로 반환하였으나,
|
||||||
//호환을 위해서는object로 반환하는 것이 더 나을것
|
//호환을 위해서는object로 반환하는 것이 더 나을것
|
||||||
return json_decode($value);
|
return json_decode($value);
|
||||||
}
|
}
|
||||||
@@ -45,12 +45,20 @@ class Json
|
|||||||
if ($flag & static::NO_CACHE) {
|
if ($flag & static::NO_CACHE) {
|
||||||
WebUtil::setHeaderNoCache();
|
WebUtil::setHeaderNoCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
header('Content-Type: application/json');
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
if($flag & static::PASS_THROUGH){
|
if($flag & static::PASS_THROUGH){
|
||||||
die($value);
|
die($value);
|
||||||
}
|
}
|
||||||
die(Json::encode($value, $flag));
|
die(Json::encode($value, $flag));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return never */
|
||||||
|
public static function dieWithReason(string $reason){
|
||||||
|
static::die([
|
||||||
|
'result'=>false,
|
||||||
|
'reason'=>$reason
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+57
-50
@@ -1,6 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace sammo;
|
namespace sammo;
|
||||||
|
|
||||||
|
use phpDocumentor\Reflection\Types\Boolean;
|
||||||
|
|
||||||
class TimeUtil
|
class TimeUtil
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -43,7 +46,7 @@ class TimeUtil
|
|||||||
/** @deprecated */
|
/** @deprecated */
|
||||||
public static function DatetimeFromMinute($date, $minute)
|
public static function DatetimeFromMinute($date, $minute)
|
||||||
{
|
{
|
||||||
return date('Y-m-d H:i:s', strtotime($date) + $minute*60);
|
return date('Y-m-d H:i:s', strtotime($date) + $minute * 60);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @deprecated */
|
/** @deprecated */
|
||||||
@@ -76,62 +79,48 @@ class TimeUtil
|
|||||||
return date('H:i:s', strtotime('00:00:00') + $second);
|
return date('H:i:s', strtotime('00:00:00') + $second);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function today():string
|
public static function today(): string
|
||||||
{
|
{
|
||||||
$obj = new \DateTime();
|
$obj = new \DateTime();
|
||||||
return $obj->format('Y-m-d');
|
return $obj->format('Y-m-d');
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function now(bool $withFraction=false):string
|
public static function now(bool $withFraction = false): string
|
||||||
{
|
{
|
||||||
$obj = new \DateTime();
|
$obj = new \DateTime();
|
||||||
if(!$withFraction){
|
return static::format($obj, $withFraction);
|
||||||
return $obj->format('Y-m-d H:i:s');
|
|
||||||
}
|
|
||||||
return $obj->format('Y-m-d H:i:s.u');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function nowAddDays($day, bool $withFraction=false):string
|
public static function nowAddDays($day, bool $withFraction = false): string
|
||||||
{
|
{
|
||||||
$obj = new \DateTime();
|
$obj = new \DateTime();
|
||||||
$obj->add(static::secondsToDateInterval($day * 3600 * 24));
|
$obj->add(static::secondsToDateInterval($day * 3600 * 24));
|
||||||
if(!$withFraction){
|
return static::format($obj, $withFraction);
|
||||||
return $obj->format('Y-m-d H:i:s');
|
|
||||||
}
|
|
||||||
return $obj->format('Y-m-d H:i:s.u');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function nowAddHours($hour, bool $withFraction=false):string
|
public static function nowAddHours($hour, bool $withFraction = false): string
|
||||||
{
|
{
|
||||||
$obj = new \DateTime();
|
$obj = new \DateTime();
|
||||||
$obj->add(static::secondsToDateInterval($hour * 3600));
|
$obj->add(static::secondsToDateInterval($hour * 3600));
|
||||||
if(!$withFraction){
|
return static::format($obj, $withFraction);
|
||||||
return $obj->format('Y-m-d H:i:s');
|
|
||||||
}
|
|
||||||
return $obj->format('Y-m-d H:i:s.u');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function nowAddMinutes($minute, bool $withFraction=false):string
|
public static function nowAddMinutes($minute, bool $withFraction = false): string
|
||||||
{
|
{
|
||||||
$obj = new \DateTime();
|
$obj = new \DateTime();
|
||||||
$obj->add(static::secondsToDateInterval($minute * 60));
|
$obj->add(static::secondsToDateInterval($minute * 60));
|
||||||
if(!$withFraction){
|
return static::format($obj, $withFraction);
|
||||||
return $obj->format('Y-m-d H:i:s');
|
|
||||||
}
|
|
||||||
return $obj->format('Y-m-d H:i:s.u');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function nowAddSeconds($second, bool $withFraction=false):string
|
public static function nowAddSeconds($second, bool $withFraction = false): string
|
||||||
{
|
{
|
||||||
$obj = new \DateTime();
|
$obj = new \DateTime();
|
||||||
$obj->add(static::secondsToDateInterval($second));
|
$obj->add(static::secondsToDateInterval($second));
|
||||||
if(!$withFraction){
|
return static::format($obj, $withFraction);
|
||||||
return $obj->format('Y-m-d H:i:s');
|
|
||||||
}
|
|
||||||
return $obj->format('Y-m-d H:i:s.u');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function secondsToDateTime(float $fullSeconds, bool $isDateTimeImmutable=false): \DateTimeInterface{
|
public static function secondsToDateTime(float $fullSeconds, bool $isDateTimeImmutable = false, bool $isUTC = false): \DateTimeInterface
|
||||||
|
{
|
||||||
$seconds = floor($fullSeconds);
|
$seconds = floor($fullSeconds);
|
||||||
$fraction = $fullSeconds - $seconds;
|
$fraction = $fullSeconds - $seconds;
|
||||||
|
|
||||||
@@ -139,70 +128,88 @@ class TimeUtil
|
|||||||
$interval->s = $seconds;
|
$interval->s = $seconds;
|
||||||
$interval->f = $fraction;
|
$interval->f = $fraction;
|
||||||
|
|
||||||
if($isDateTimeImmutable){
|
if ($isDateTimeImmutable) {
|
||||||
$dateTime = new \DateTimeImmutable("@0");
|
$dateTime = new \DateTimeImmutable("@0", $isUTC ? new \DateTimeZone("UTC") : null);
|
||||||
return $dateTime->add($interval);
|
return $dateTime->add($interval);
|
||||||
}
|
}
|
||||||
|
|
||||||
$dateTime = new \DateTime("@0");
|
$dateTime = new \DateTime("@0", $isUTC ? new \DateTimeZone("UTC") : null);
|
||||||
$dateTime->add($interval);
|
$dateTime->add($interval);
|
||||||
return $dateTime;
|
return $dateTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function secondsToDateInterval(float $fullSeconds): \DateInterval{
|
public static function secondsToDateInterval(float $fullSeconds): \DateInterval
|
||||||
$d0 = new \DateTime("@0");
|
{
|
||||||
|
$inverted = $fullSeconds < 0?1:0;
|
||||||
|
|
||||||
return $d0->diff(static::secondsToDateTime($fullSeconds, true));
|
$fullSeconds = abs($fullSeconds);
|
||||||
|
$seconds = floor($fullSeconds);
|
||||||
|
$fraction = $fullSeconds - $seconds;
|
||||||
|
|
||||||
|
$interval = new \DateInterval("PT{$seconds}S");
|
||||||
|
|
||||||
|
$interval->f = $fraction;
|
||||||
|
$interval->invert = $inverted;
|
||||||
|
return $interval;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function DateTimeToSeconds(\DateTimeInterface $dateTime): float{
|
public static function DateTimeToSeconds(\DateTimeInterface $dateTime, bool $isUTC = false): float
|
||||||
$d0 = new \DateTimeImmutable("@0");
|
{
|
||||||
|
$d0 = new \DateTimeImmutable("@0", $isUTC ? new \DateTimeZone("UTC") : null);
|
||||||
|
|
||||||
return static::DateIntervalToSeconds($d0->diff($dateTime));
|
return static::DateIntervalToSeconds($d0->diff($dateTime));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function DateIntervalToSeconds(\DateInterval $interval): float{
|
public static function DateIntervalToSeconds(\DateInterval $interval): float
|
||||||
if($interval->days !== FALSE){
|
{
|
||||||
|
if ($interval->days !== FALSE) {
|
||||||
$days = $interval->days;
|
$days = $interval->days;
|
||||||
}
|
} else {
|
||||||
else{
|
if ($interval->y != 0) {
|
||||||
if($interval->y != 0){
|
|
||||||
throw new \InvalidArgumentException('Year argument conversion is not supported');
|
throw new \InvalidArgumentException('Year argument conversion is not supported');
|
||||||
}
|
}
|
||||||
if($interval->m != 0){
|
if ($interval->m != 0) {
|
||||||
throw new \InvalidArgumentException('Month argument conversion is not supported');
|
throw new \InvalidArgumentException('Month argument conversion is not supported');
|
||||||
}
|
}
|
||||||
$days = $interval->d;
|
$days = $interval->d;
|
||||||
}
|
}
|
||||||
|
|
||||||
$hours = $days * 24 + $interval->h;
|
$hours = $days * 24 + $interval->h;
|
||||||
$minutes = $hours * 60 + $interval->i;
|
$minutes = $hours * 60 + $interval->i;
|
||||||
$seconds = $minutes * 60 + $interval->s + $interval->f;
|
$seconds = $minutes * 60 + $interval->s + $interval->f;
|
||||||
|
|
||||||
return $seconds;
|
return $seconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function format(\DateTimeInterface $dateTime, bool $withFraction): string{
|
||||||
|
if (!$withFraction) {
|
||||||
|
return $dateTime->format('Y-m-d H:i:s');
|
||||||
|
}
|
||||||
|
return $dateTime->format('Y-m-d H:i:s.u');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* $baseYear, $baseMonth 부터 $afterMonth 개월 이내인지. $afterMonth 포함.
|
* $baseYear, $baseMonth 부터 $afterMonth 개월 이내인지. $afterMonth 포함.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public static function IsRangeMonth(int $baseYear, int $baseMonth, int $afterMonth, int $askYear, int $askMonth):bool{
|
public static function IsRangeMonth(int $baseYear, int $baseMonth, int $afterMonth, int $askYear, int $askMonth): bool
|
||||||
if($baseMonth < 1 || $baseMonth > 12){
|
{
|
||||||
|
if ($baseMonth < 1 || $baseMonth > 12) {
|
||||||
throw new \InvalidArgumentException('개월이 올바르지 않음');
|
throw new \InvalidArgumentException('개월이 올바르지 않음');
|
||||||
}
|
}
|
||||||
if($askMonth < 1 || $askMonth > 12){
|
if ($askMonth < 1 || $askMonth > 12) {
|
||||||
throw new \InvalidArgumentException('개월이 올바르지 않음');
|
throw new \InvalidArgumentException('개월이 올바르지 않음');
|
||||||
}
|
}
|
||||||
|
|
||||||
$minMonth = $baseYear * 12 + $baseMonth;
|
$minMonth = $baseYear * 12 + $baseMonth;
|
||||||
if($afterMonth < 0){
|
if ($afterMonth < 0) {
|
||||||
$maxMonth = $minMonth;
|
$maxMonth = $minMonth;
|
||||||
$minMonth = $maxMonth - $afterMonth;
|
$minMonth = $maxMonth - $afterMonth;
|
||||||
}
|
}
|
||||||
|
|
||||||
$maxMonth = $minMonth + $afterMonth;
|
$maxMonth = $minMonth + $afterMonth;
|
||||||
$askMonth = $askYear * 12 + $askMonth;
|
$askMonth = $askYear * 12 + $askMonth;
|
||||||
if($askMonth < $minMonth || $maxMonth < $askMonth){
|
if ($askMonth < $minMonth || $maxMonth < $askMonth) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ class Validator extends \Valitron\Validator
|
|||||||
* $rule에 함수를 넣는 대신 상속한 클래스에 추가하는 방식을 사용할 것.
|
* $rule에 함수를 넣는 대신 상속한 클래스에 추가하는 방식을 사용할 것.
|
||||||
*
|
*
|
||||||
* @suppress PhanUndeclaredFunctionInCallable
|
* @suppress PhanUndeclaredFunctionInCallable
|
||||||
*
|
*
|
||||||
* @param string $rule
|
* @param string $rule
|
||||||
* @param array|string $fields
|
* @param array|string $fields
|
||||||
* @return $this
|
* @return $this
|
||||||
@@ -31,7 +31,7 @@ class Validator extends \Valitron\Validator
|
|||||||
$params = func_get_args();
|
$params = func_get_args();
|
||||||
return parent::rule(...$params);
|
return parent::rule(...$params);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -98,4 +98,11 @@ class Validator extends \Valitron\Validator
|
|||||||
$width = mb_strwidth($value);
|
$width = mb_strwidth($value);
|
||||||
return $params[0] <= $width && $width <= $params[1];
|
return $params[0] <= $width && $width <= $params[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function validateKeyExists($field, $value, $params){
|
||||||
|
if(!is_string($value) && !is_numeric($value)){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return key_exists($value, $params[0]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+81
-64
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace sammo;
|
namespace sammo;
|
||||||
|
|
||||||
use phpDocumentor\Reflection\Types\Boolean;
|
use phpDocumentor\Reflection\Types\Boolean;
|
||||||
@@ -14,7 +15,7 @@ class WebUtil
|
|||||||
return str_replace('.', '\\.', $ip);
|
return str_replace('.', '\\.', $ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function resolveRelativePath(string $path, string $basepath) : string
|
public static function resolveRelativePath(string $path, string $basepath): string
|
||||||
{
|
{
|
||||||
return \phpUri::parse($basepath)->join($path);
|
return \phpUri::parse($basepath)->join($path);
|
||||||
}
|
}
|
||||||
@@ -30,15 +31,17 @@ class WebUtil
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function isAJAX(){
|
public static function isAJAX()
|
||||||
return strtolower($_SERVER['HTTP_X_REQUESTED_WITH']??null) === 'xmlhttprequest';
|
{
|
||||||
|
return strtolower($_SERVER['HTTP_X_REQUESTED_WITH'] ?? null) === 'xmlhttprequest';
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function requireAJAX():void{
|
public static function requireAJAX(): void
|
||||||
if(!static::isAJAX()){
|
{
|
||||||
|
if (!static::isAJAX()) {
|
||||||
Json::die([
|
Json::die([
|
||||||
'result'=>false,
|
'result' => false,
|
||||||
'reason'=>'no ajax'
|
'reason' => 'no ajax'
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -81,23 +84,23 @@ class WebUtil
|
|||||||
//Use a switch statement to figure out the exact error.
|
//Use a switch statement to figure out the exact error.
|
||||||
switch ($jsonError) {
|
switch ($jsonError) {
|
||||||
case JSON_ERROR_DEPTH:
|
case JSON_ERROR_DEPTH:
|
||||||
$error .= 'Maximum depth exceeded! : '.$content;
|
$error .= 'Maximum depth exceeded! : ' . $content;
|
||||||
break;
|
break;
|
||||||
case JSON_ERROR_STATE_MISMATCH:
|
case JSON_ERROR_STATE_MISMATCH:
|
||||||
$error .= 'Underflow or the modes mismatch! : '.$content;
|
$error .= 'Underflow or the modes mismatch! : ' . $content;
|
||||||
break;
|
break;
|
||||||
case JSON_ERROR_CTRL_CHAR:
|
case JSON_ERROR_CTRL_CHAR:
|
||||||
$error .= 'Unexpected control character found : '.$content;
|
$error .= 'Unexpected control character found : ' . $content;
|
||||||
break;
|
break;
|
||||||
case JSON_ERROR_SYNTAX:
|
case JSON_ERROR_SYNTAX:
|
||||||
$error .= 'Malformed JSON : '.$content;
|
$error .= 'Malformed JSON : ' . $content;
|
||||||
break;
|
break;
|
||||||
case JSON_ERROR_UTF8:
|
case JSON_ERROR_UTF8:
|
||||||
$error .= 'Malformed UTF-8 characters found! : '.$content;
|
$error .= 'Malformed UTF-8 characters found! : ' . $content;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
$error .= 'Unknown error! : '.$content;
|
$error .= 'Unknown error! : ' . $content;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
throw new \Exception($error);
|
throw new \Exception($error);
|
||||||
}
|
}
|
||||||
@@ -105,89 +108,89 @@ class WebUtil
|
|||||||
return $decoded;
|
return $decoded;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function preloadAsset(string $path, string $type){
|
public static function preloadAsset(string $path, string $type)
|
||||||
|
{
|
||||||
$upath = \phpUri::parse($path);
|
$upath = \phpUri::parse($path);
|
||||||
$path = $upath->join('');
|
$path = $upath->join('');
|
||||||
if(!$upath->scheme){
|
if (!$upath->scheme) {
|
||||||
if(!file_exists($upath->path)){
|
if (!file_exists($upath->path)) {
|
||||||
return "<!-- preload:{$type} '{$path}' -->\n";
|
return "<!-- preload:{$type} '{$path}' -->\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
$mtime = filemtime($upath->path);
|
$mtime = filemtime($upath->path);
|
||||||
if($upath->query){
|
if ($upath->query) {
|
||||||
$tail = '&'.$mtime;
|
$tail = '&' . $mtime;
|
||||||
|
} else {
|
||||||
|
$tail = '?' . $mtime;
|
||||||
}
|
}
|
||||||
else{
|
} else {
|
||||||
$tail = '?'.$mtime;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
$tail = '';
|
$tail = '';
|
||||||
}
|
}
|
||||||
return "<link href='{$path}{$tail}' rel='preload' as='$type'>\n";
|
return "<link href='{$path}{$tail}' rel='preload' as='$type'>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function preloadCSS(string $path){
|
public static function preloadCSS(string $path)
|
||||||
|
{
|
||||||
return static::preloadAsset($path, 'style');
|
return static::preloadAsset($path, 'style');
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function preloadJS(string $path){
|
public static function preloadJS(string $path)
|
||||||
|
{
|
||||||
return static::preloadAsset($path, 'script');
|
return static::preloadAsset($path, 'script');
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function printJS(string $path, bool $isDefer=false){
|
public static function printJS(string $path, bool $isDefer = false)
|
||||||
|
{
|
||||||
//async 옵션 고려?
|
//async 옵션 고려?
|
||||||
$upath = \phpUri::parse($path);
|
$upath = \phpUri::parse($path);
|
||||||
$path = $upath->join('');
|
$path = $upath->join('');
|
||||||
if(!$upath->scheme){
|
if (!$upath->scheme) {
|
||||||
if(!file_exists($upath->path)){
|
if (!file_exists($upath->path)) {
|
||||||
return "<!-- JS '{$path}' -->\n";
|
return "<!-- JS '{$path}' -->\n";
|
||||||
}
|
}
|
||||||
$mtime = filemtime($upath->path);
|
$mtime = filemtime($upath->path);
|
||||||
if($upath->query){
|
if ($upath->query) {
|
||||||
$tail = '&'.$mtime;
|
$tail = '&' . $mtime;
|
||||||
|
} else {
|
||||||
|
$tail = '?' . $mtime;
|
||||||
}
|
}
|
||||||
else{
|
} else {
|
||||||
$tail = '?'.$mtime;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
$tail = '';
|
$tail = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
$typeText = $isDefer?'defer':'';
|
$typeText = $isDefer ? 'defer' : '';
|
||||||
return "<script {$typeText} src='{$path}{$tail}'></script>\n";
|
return "<script {$typeText} src='{$path}{$tail}'></script>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function printCSS(string $path){
|
public static function printCSS(string $path)
|
||||||
|
{
|
||||||
$upath = \phpUri::parse($path);
|
$upath = \phpUri::parse($path);
|
||||||
$path = $upath->join('');
|
$path = $upath->join('');
|
||||||
if(!$upath->scheme){
|
if (!$upath->scheme) {
|
||||||
if(!file_exists($upath->path)){
|
if (!file_exists($upath->path)) {
|
||||||
return "<!-- CSS '{$path}' -->\n";
|
return "<!-- CSS '{$path}' -->\n";
|
||||||
}
|
}
|
||||||
$mtime = filemtime($upath->path);
|
$mtime = filemtime($upath->path);
|
||||||
if($upath->query){
|
if ($upath->query) {
|
||||||
$tail = '&'.$mtime;
|
$tail = '&' . $mtime;
|
||||||
|
} else {
|
||||||
|
$tail = '?' . $mtime;
|
||||||
}
|
}
|
||||||
else{
|
} else {
|
||||||
$tail = '?'.$mtime;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
$tail = '';
|
$tail = '';
|
||||||
}
|
}
|
||||||
return "<link rel='stylesheet' type='text/css' href='{$path}{$tail}' />\n";
|
return "<link rel='stylesheet' type='text/css' href='{$path}{$tail}' />\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function printStaticValues(array $values, bool $pretty=true){
|
public static function printStaticValues(array $values, bool $pretty = true)
|
||||||
if(!count($values)){
|
{
|
||||||
|
if (!count($values)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$lines = ["<script>"];
|
$lines = ["<script>"];
|
||||||
|
|
||||||
foreach($values as $key => $value){
|
foreach ($values as $key => $value) {
|
||||||
$lines[] = "var {$key} = ".Json::encode($value, Json::EMPTY_ARRAY_IS_DICT | ($pretty?Json::PRETTY:0));
|
$lines[] = "var {$key} = " . Json::encode($value, Json::EMPTY_ARRAY_IS_DICT | ($pretty ? Json::PRETTY : 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
$lines[] = "</script>\n";
|
$lines[] = "</script>\n";
|
||||||
@@ -195,13 +198,14 @@ class WebUtil
|
|||||||
return join("\n", $lines);
|
return join("\n", $lines);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function htmlPurify(?string $text): string{
|
public static function htmlPurify(?string $text): string
|
||||||
if(!$text){
|
{
|
||||||
|
if (!$text) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
$config = \HTMLPurifier_HTML5Config::createDefault();
|
$config = \HTMLPurifier_HTML5Config::createDefault();
|
||||||
$config->set('Filter.Custom', array (new \HTMLPurifier_Filter_YouTube()));
|
$config->set('Filter.Custom', array(new \HTMLPurifier_Filter_YouTube()));
|
||||||
$config->set('HTML.SafeIframe', true);
|
$config->set('HTML.SafeIframe', true);
|
||||||
$config->set('URI.SafeIframeRegexp', '%^(https?:)?//(www\.youtube(?:-nocookie)?\.com/embed/|player\.vimeo\.com/video/)%'); //allow YouTube and Vimeo
|
$config->set('URI.SafeIframeRegexp', '%^(https?:)?//(www\.youtube(?:-nocookie)?\.com/embed/|player\.vimeo\.com/video/)%'); //allow YouTube and Vimeo
|
||||||
$def = $config->getHTMLDefinition();
|
$def = $config->getHTMLDefinition();
|
||||||
@@ -210,19 +214,32 @@ class WebUtil
|
|||||||
return $purifier->purify($text);
|
return $purifier->purify($text);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function drawMenu(string $path): string{
|
public static function errorBackMsg(string $msg, ?string $target=null): string
|
||||||
if(!file_exists($path)){
|
{
|
||||||
|
$jmsg = Json::encode($msg);
|
||||||
|
if(!$target){
|
||||||
|
$moveNext = 'history.go(-1);';
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
$moveNext = "location.replace('{$target}');";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "<html><head><style>html,body{background:black;}</style><script>alert({$jmsg});$moveNext</script></head><body></body></html>";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function drawMenu(string $path): string
|
||||||
|
{
|
||||||
|
if (!file_exists($path)) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
$json = Json::decode(file_get_contents($path));
|
$json = Json::decode(file_get_contents($path));
|
||||||
|
|
||||||
$result = [];
|
$result = [];
|
||||||
foreach($json as $menuItem){
|
foreach ($json as $menuItem) {
|
||||||
if (count($menuItem) == 2) {
|
if (count($menuItem) == 2) {
|
||||||
[$url, $title] = $menuItem;
|
[$url, $title] = $menuItem;
|
||||||
$targetAttr = '';
|
$targetAttr = '';
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
[$url, $title, $target] = $menuItem;
|
[$url, $title, $target] = $menuItem;
|
||||||
$target = htmlspecialchars($target);
|
$target = htmlspecialchars($target);
|
||||||
$targetAttr = "target='$target' ";
|
$targetAttr = "target='$target' ";
|
||||||
|
|||||||
@@ -247,7 +247,6 @@ module.exports = (env, argv) => {
|
|||||||
},
|
},
|
||||||
mode,
|
mode,
|
||||||
entry: {
|
entry: {
|
||||||
common: `${tsDir}/gateway/common_deprecated.ts`,
|
|
||||||
entrance: `${tsDir}/gateway/entrance.ts`,
|
entrance: `${tsDir}/gateway/entrance.ts`,
|
||||||
user_info: `${tsDir}/gateway/user_info.ts`,
|
user_info: `${tsDir}/gateway/user_info.ts`,
|
||||||
admin_member: `${tsDir}/gateway/admin_member.ts`,
|
admin_member: `${tsDir}/gateway/admin_member.ts`,
|
||||||
|
|||||||
Reference in New Issue
Block a user