Compare commits

..
40 Commits
Author SHA1 Message Date
Hide_D 142b96836e refac: 신규/복귀 유저 유산 포인트 지급 로직을 조금더 최적화 2022-10-05 00:26:04 +09:00
Hide_D 9be0d2ec2d refac: storeOldGeneral을 General::kill로 이동 2022-10-04 20:38:18 +09:00
Hide_D fd817650e7 fix: 지급 버그 수정 2022-10-04 11:32:52 +09:00
Hide_D 3c6cb96a9b feat: 신규/복귀 유저에게 장수 생성 시 유산 포인트 제공
- 이벤트 깃수 제외 500포인트
- 8기까지 적립
2022-10-04 11:25:40 +09:00
Hide_D c4537454f9 fix: 최대 임관년도 수 계산 버그 재 수정 2022-10-04 10:02:39 +09:00
Hide_D 82cdaa433e fix: 최대 임관년도 수 계산 버그 2022-10-04 01:07:11 +09:00
Hide_D 32dd3ff43f misc: AI에서 삭턴NPC 구분 기준을 1턴 추가 2022-10-04 00:13:52 +09:00
Hide_D 6a5840faaa fix: AI 후방 발령 누락분 수정 2022-10-03 23:38:53 +09:00
Hide_D 5b0a3b064d fix: AI 후방 발령 로직 버그 수정
- 징병시 인구 소모가 없는 경우 후방 발령 제외
- NPC 수뇌일때와 유저 수뇌일 때 도시 인구 계산식 다른 버그 수정
2022-10-03 23:37:07 +09:00
Hide_D 14b8bb9790 fix: 2번 연속 멸망 시 유산 포인트 계산 오류 2022-10-03 11:32:22 +09:00
Hide_D 650f4a5903 fix: 구조상 베팅 당첨 포인트는 은퇴시 반영되어야 함 2022-10-03 00:37:18 +09:00
Hide_D c50410a6da game: 은퇴시 토너먼트 보정치를 100%로
- 실수였음!
2022-10-02 23:27:41 +09:00
Hide_D b2a676cd8b game: 옥란백용구 향상 최대 30% -> 50% 2022-10-02 23:25:00 +09:00
Hide_D 50a75e4543 refac, game: 은퇴 시 포인트 반영 방식 변경
- 반영하지 않고 은퇴 이후로 넘기는 포인트 추가
- 은퇴시 계수를 Obj로 이동
2022-10-02 19:41:38 +09:00
Hide_D 22172ac66f fix: null coalesing 수정 2022-10-02 19:39:35 +09:00
Hide_D 392aaa343d fix: calcGenType을 updateInstance()로 이동 2022-10-02 19:36:17 +09:00
Hide_D d924f47d58 fix: warning 발생 제거 2022-10-02 19:35:05 +09:00
Hide_D 3b70cbe724 fix: GeneralAI env 설정 관련 버그 수정 2022-10-02 17:46:20 +09:00
Hide_D 5c3233f883 misc: 서버 리셋 페이지에서 기본 설정값 변경
- 자율 행동 전부 선택
- 자율 행동 기본 시간 24시간
- 사실모드: 가상
2022-10-02 17:43:40 +09:00
Hide_D b570bfa9d4 fix: NPC선전포고, 긴급포상에서 내부 NPC 국가 상태를 업데이트하도록 수정 2022-10-02 17:37:40 +09:00
Hide_D 270cb25285 refac: GeneralAI에서 상태를 추가 업데이트할 수 있도록 구조 변경 2022-10-02 17:33:23 +09:00
Hide_D 7d3b0db924 game: 계략 성공률을 5%p 하향
- 계략 성공률에 인구수를 반영하기 이전과 비교하여 1명있을 때에는 동일
- 한명도 없을때는 5%p 상승
- 두명 이상일 때에는 이전 대비 성공률 하향
2022-10-02 15:59:30 +09:00
Hide_D 74d310e113 fix: 불가침에서 '까지'는 해당 월을 포함하여야 함 2022-10-02 15:55:31 +09:00
Hide_D 45afb1c090 fix: 수동 은퇴 시 명예의전당에 등록되지 않는 버그 2022-09-27 10:00:44 +09:00
Hide_D 40fc2f8bbf fix: NPC 순간이동이 보급이 끊긴 도시에도 갈 수 있는 버그 수정 2022-09-24 22:29:58 +09:00
Hide_D a9de5a92e1 build: pre-commit에 lint 제거 2022-09-24 20:58:56 +09:00
Hide_D c592b00c3f game: 피장파장에 추가되었던 글로벌 전략 1턴 제거 2022-09-24 20:57:44 +09:00
Hide_D 2c81be4d12 game: 계략 방어 확률에 도시 거주 장수 수 반영
- sqrt(장수 수) * 5%p
2022-09-23 21:59:51 +09:00
Hide_D f10289f7b6 game: 피장파장은 이제 전략
- 글로벌 쿨 1턴
- 피장파장 쿨 8턴
2022-09-23 21:56:15 +09:00
Hide_D c1f06b4ce5 fix: 최대 임관 년도 수 제어 규약 우회 2022-09-22 11:54:47 +09:00
Hide_D 9ad3dbba90 game: 배신 관련 최종 수정, 20%부터, +10%p씩
- 공지 추가
2022-09-21 23:25:20 +09:00
Hide_D 12c62f87f7 game: 초기 배신 수치 추가 보정
- 배신 수치를 '2'로 변경.
- 명성 패널티를 30%로 시작해서 45%, 60%
2022-09-21 23:16:29 +09:00
Hide_D 635f1ae077 feat, game: 초반 '배신 수치' 1 증가, 배신 패널티 증가
- 184년 1월부터 배신수치 1 증가.
- 배신 패널티 당 15%, 최대 6회
2022-09-21 23:12:56 +09:00
Hide_D c89bd2f63f fix: 하야, 망명 시 최대 임관 년수가 반영되지 않는 버그 수정 2022-09-21 22:48:55 +09:00
Hide_D 2f94a8a2ca fix: 가오픈 기간 중 사망 메시지에서 조사가 중복되어 나오던 문제 수정 (#226)
Reviewed-on: https://storage.hided.net/gitea/devsam/core/pulls/226
Reviewed-by: Hide_D <hided62@gmail.com>
2022-09-14 12:07:08 +09:00
Jinhyun Kim 85b0d35af0 fix: 가오픈 기간 중 사망 메시지에서 조사가 중복되어 나오던 문제 수정 2022-09-14 11:42:19 +09:00
Hide_D b25acacb1e fix: 징병 특기에 '비용 감소' 제거 누락 2022-09-10 19:04:46 +09:00
Hide_D c05a43f3b1 fix(oauth): 이메일 변경 시 oauthID를 받아오지 못하는 분기 수정 2022-09-09 03:28:18 +09:00
Hide_D d99976daa9 fix(oauth): 카카오로그인에서 이메일만 바뀐 경우 이메일 갱신 2022-09-09 03:11:34 +09:00
Hide_D 62f53d09bf feat, game: 징병 전특 리밸런싱, 징병/소집해제시 인구 변동 트리거 설정 2022-09-06 19:48:52 +09:00
30 changed files with 341 additions and 130 deletions
+1 -2
View File
@@ -27,7 +27,6 @@ foreach ($db->queryFirstColumn(
$inheritPointManager = InheritancePointManager::getInstance();
foreach(General::createGeneralObjListFromDB($db->queryFirstColumn('SELECT `no` FROM general WHERE npc = 0')) as $genObj){
$inheritPointManager->mergeTotalInheritancePoint($genObj, true);
$inheritPointManager->mergeTotalInheritancePoint($genObj);
$inheritPointManager->applyInheritanceUser($genObj->getVar('owner'));
$inheritPointManager->clearInheritancePoint($genObj);
}
+11 -8
View File
@@ -1805,7 +1805,7 @@ function deleteNation(General $lord, bool $applyDB): array
$nationID,
$lordID
),
['npc', 'gold', 'rice', 'experience', 'explevel', 'dedication', 'dedlevel', 'belong', 'aux'],
['npc', 'owner', 'gold', 'rice', 'experience', 'explevel', 'dedication', 'dedlevel', 'belong', 'aux'],
1
);
$nationGeneralList[$lordID] = $lord;
@@ -1823,13 +1823,16 @@ function deleteNation(General $lord, bool $applyDB): array
// 전 장수 재야로
foreach ($nationGeneralList as $general) {
$general->setAuxVar(
InheritanceKey::max_belong->value,
max(
$general->getVar('belong'),
$general->getAuxVar(InheritanceKey::max_belong->value) ?? 0
)
);
if($general->getNPCType() < 2){
$general->setAuxVar(
InheritanceKey::max_belong->value,
max(
$general->getVar('belong'),
$general->getAuxVar(InheritanceKey::max_belong->value) ?? 0
)
);
}
$general->setVar('belong', 0);
$general->setVar('troop', 0);
$general->setVar('officer_level', 0);
+1 -2
View File
@@ -1092,9 +1092,8 @@ function checkEmperior()
}
processSumInheritPointRank();
foreach ($allUserGenerals as $genObj) {
$inheritPointManager->mergeTotalInheritancePoint($genObj, true);
$inheritPointManager->mergeTotalInheritancePoint($genObj);
$inheritPointManager->applyInheritanceUser($genObj->getVar('owner'));
$inheritPointManager->clearInheritancePoint($genObj);
}
$gameStor->isunited = 2;
+10 -10
View File
@@ -93,8 +93,8 @@ if ($session->userGrade < 5 && !$allowReset) {
<label for="fiction" class="col-sm-3 col-form-label">NPC 상성</label>
<div class="col-sm-9">
<div id="fiction" class="btn-group btn-group-toggle" data-bs-toggle="buttons">
<input type="radio" id="fiction_0" class="btn-check" name="fiction" value="0" checked><label for="fiction_0" class="btn btn-secondary"> 연의 </label>
<input type="radio" id="fiction_1" class="btn-check" name="fiction" value="1"><label for="fiction_1" class="btn btn-secondary"> 가상 </label>
<input type="radio" id="fiction_0" class="btn-check" name="fiction" value="0"><label for="fiction_0" class="btn btn-secondary"> 연의 </label>
<input type="radio" id="fiction_1" class="btn-check" name="fiction" value="1" checked><label for="fiction_1" class="btn btn-secondary"> 가상 </label>
</div>
</div>
</div>
@@ -135,13 +135,13 @@ if ($session->userGrade < 5 && !$allowReset) {
<div class="col-sm-9">
<div class="input-group">
<div class="btn-group btn-group-toggle" data-bs-toggle="buttons">
<input type="checkbox" id="autorun_develop" class="autorun_user_chk btn-check" data-key="develop" name="autorun_user[]" value="develop"><label class="btn btn-secondary" for="autorun_develop">내정</label>
<input type="checkbox" id="autorun_warp" class="autorun_user_chk btn-check" data-key="warp" name="autorun_user[]" value="warp"><label class="btn btn-secondary" for="autorun_warp">순간이동</label>
<input type="checkbox" id="autorun_recruit" class="autorun_user_chk btn-check" data-key="recruit" name="autorun_user[]" value="recruit"><label class="btn btn-secondary" for="autorun_recruit">징병</label>
<input type="checkbox" id="autorun_recruit_high" class="autorun_user_chk btn-check" data-key="recruit_high" name="autorun_user[]" value="recruit_high"><label class="btn btn-secondary" for="autorun_recruit_high">모병</label>
<input type="checkbox" id="autorun_train" class="autorun_user_chk btn-check" data-key="train" name="autorun_user[]" value="train"><label class="btn btn-secondary" for="autorun_train">훈사</label>
<input type="checkbox" id="autorun_battle" class="autorun_user_chk btn-check" data-key="battle" name="autorun_user[]" value="battle"><label class="btn btn-secondary" for="autorun_battle">출병</label>
<input type="checkbox" id="autorun_chief" class="autorun_user_chk btn-check" data-key="chief" name="autorun_user[]" value="chief"><label class="btn btn-secondary" for="autorun_chief">기본 사령턴</label>
<input type="checkbox" id="autorun_develop" class="autorun_user_chk btn-check" data-key="develop" name="autorun_user[]" value="develop" checked><label class="btn btn-secondary" for="autorun_develop">내정</label>
<input type="checkbox" id="autorun_warp" class="autorun_user_chk btn-check" data-key="warp" name="autorun_user[]" value="warp" checked><label class="btn btn-secondary" for="autorun_warp">순간이동</label>
<input type="checkbox" id="autorun_recruit" class="autorun_user_chk btn-check" data-key="recruit" name="autorun_user[]" value="recruit" checked><label class="btn btn-secondary" for="autorun_recruit">징병</label>
<input type="checkbox" id="autorun_recruit_high" class="autorun_user_chk btn-check" data-key="recruit_high" name="autorun_user[]" value="recruit_high" checked><label class="btn btn-secondary" for="autorun_recruit_high">모병</label>
<input type="checkbox" id="autorun_train" class="autorun_user_chk btn-check" data-key="train" name="autorun_user[]" value="train" checked><label class="btn btn-secondary" for="autorun_train">훈사</label>
<input type="checkbox" id="autorun_battle" class="autorun_user_chk btn-check" data-key="battle" name="autorun_user[]" value="battle" checked><label class="btn btn-secondary" for="autorun_battle">출병</label>
<input type="checkbox" id="autorun_chief" class="autorun_user_chk btn-check" data-key="chief" name="autorun_user[]" value="chief" checked><label class="btn btn-secondary" for="autorun_chief">기본 사령턴</label>
</div>
</div>
</div>
@@ -163,7 +163,7 @@ if ($session->userGrade < 5 && !$allowReset) {
<option value="480">8시간</option>
<option value="600">10시간</option>
<option value="720">12시간</option>
<option value="1440">24시간</option>
<option value="1440" selected>24시간</option>
<option value="2160">36시간</option>
<option value="2880">48시간</option>
<option value="3600">60시간</option>
+2 -2
View File
@@ -226,8 +226,8 @@ function do추방(General $general, int $myOfficerLevel):?string{
}
else{
$betrayCnt = $general->getVar('betray');
$general->addExperience(-$general->getVar('experience')*0.1*$betrayCnt);
$general->addDedication(-$general->getVar('dedication')*0.1*$betrayCnt);
$general->addExperience(-$general->getVar('experience')*0.15*$betrayCnt);
$general->addDedication(-$general->getVar('dedication')*0.15*$betrayCnt);
$general->increaseVarWithLimit('betray', 1, null, GameConst::$maxBetrayCnt);
}
+1 -1
View File
@@ -67,7 +67,7 @@ class DieOnPrestart extends \sammo\BaseAPI
$generalName = $generalObj->getName();
$josaYi = JosaUtil::pick($generalName, '이');
$generalObj->kill($db, true, "<Y>{$generalName}</>{$josaYi} 홀연히 모습을 <R>감추었습니다</>");
$generalObj->kill($db, true, "<Y>{$generalName}</>{$josaYi} 홀연히 모습을 <R>감추었습니다</>");
$session->logoutGame();
return null;
+56 -9
View File
@@ -2,6 +2,7 @@
namespace sammo\API\General;
use Ds\Set;
use sammo\ActionLogger;
use sammo\CityConst;
use sammo\DB;
@@ -84,6 +85,40 @@ class Join extends \sammo\BaseAPI
return static::REQ_LOGIN | static::REQ_READ_ONLY;
}
public function calcRestInheritPoint(int $userID): int
{
$db = DB::db();
if (Util::toInt(UniqueConst::$seasonIdx) < 1) {
//이벤트 시즌은 카운트하지 않음
return 0;
}
$gameID = UniqueConst::$serverID;
$alreadyJoined = $db->queryFirstField('SELECT count(*) FROM `storage` WHERE `namespace` = %s AND `key` LIKE %s', 'inheritance_result', "{$gameID}_{$userID}_%");
if ($alreadyJoined) {
//이미 받았음
return 0;
}
$targetBonusPointCnt = 0;
//정상적으로 끝난 깃수만 제공
$oldGames = $db->queryFirstColumn('SELECT server_id FROM ng_games WHERE `winner_nation` IS NOT NULL AND `server_id` != %s ORDER BY `date` DESC LIMIT 8', $gameID);
if(!$oldGames){
return 0;
}
//이전에 장수를 생성한 적이 있는지
$oldGamesCnt = new Set($db->queryFirstColumn('SELECT `server_id` FROM ng_old_generals WHERE server_id IN %ls AND `owner` = %i GROUP BY `server_id`', $oldGames, $userID));
foreach ($oldGames as $oldGameID) {
if($oldGamesCnt->contains($oldGameID)) {
break;
}
$targetBonusPointCnt += 1;
}
return $targetBonusPointCnt;
}
public function launch(Session $session, ?\DateTimeInterface $modifiedSince, ?string $reqEtag)
{
$userID = $session->userID;
@@ -105,7 +140,7 @@ class Join extends \sammo\BaseAPI
$inheritCity = $this->args['inheritCity'] ?? null;
$inheritBonusStat = $this->args['inheritBonusStat'] ?? null;
if($inheritTurntime !== null && $inheritCity !== null){
if ($inheritTurntime !== null && $inheritCity !== null) {
return '턴과 도시를 동시에 지정할 수 없습니다.';
}
@@ -305,7 +340,7 @@ class Join extends \sammo\BaseAPI
if ($inheritTurntime !== null) {
$inheritTurntime = $inheritTurntime % ($admin['turnterm'] * 60);
$userLogger->push(sprintf("턴 시간 %02d:%02d 로 지정", intdiv($inheritTurntime, 60), $inheritTurntime%60), "inheritPoint");
$userLogger->push(sprintf("턴 시간 %02d:%02d 로 지정", intdiv($inheritTurntime, 60), $inheritTurntime % 60), "inheritPoint");
$inheritTurntime += $rng->nextRangeInt(0, 999999) / 1000000;
$turntime = new \DateTimeImmutable(cutTurn($admin['turntime'], $admin['turnterm']));
@@ -337,6 +372,11 @@ class Join extends \sammo\BaseAPI
//상성 랜덤
$affinity = $rng->nextRangeInt(1, 150);
$betray = 0;
if ($relYear >= 4) {
$betray += 2;
}
########## 회원정보 테이블에 입력값을 등록한다. ##########
$db->insert('general', [
'owner' => $userID,
@@ -365,6 +405,7 @@ class Join extends \sammo\BaseAPI
'lastrefresh' => $now,
'crewtype' => GameUnitConst::DEFAULT_CREWTYPE,
'makelimit' => 0,
'betray' => $betray,
'age' => $age,
'startage' => $age,
'personal' => $character,
@@ -402,19 +443,25 @@ class Join extends \sammo\BaseAPI
if ($inheritRequiredPoint > 0) {
$userLogger->push("장수 생성으로 포인트 {$inheritRequiredPoint} 소모", "inheritPoint");
$inheritStor = KVStorage::getStorage(DB::db(), "inheritance_{$userID}");
$inheritStor->setValue('previous', [$inheritTotalPoint - $inheritRequiredPoint, null]);
$inheritTotalPoint -= $inheritRequiredPoint;
$inheritStor->setValue('previous', [$inheritTotalPoint, null]);
$userLogger->flush();
$db->update('rank_data', [
'value'=>$db->sqleval('value + %i', $inheritRequiredPoint)
'value' => $db->sqleval('value + %i', $inheritRequiredPoint)
], 'general_id = %i AND type = %s', $generalID, RankColumn::inherit_point_spent_dynamic->value);
}
$me = [
'no' => $generalID
];
$log = [];
$mylog = [];
$restInheritPoint = $this->calcRestInheritPoint($userID) * 500;
if($restInheritPoint > 0){
$userLogger->push("신규/복귀 생성으로 포인트 {$restInheritPoint} 지급", "inheritPoint");
$inheritStor = KVStorage::getStorage(DB::db(), "inheritance_{$userID}");
$inheritTotalPoint += $restInheritPoint;
$inheritStor->setValue('previous', [$inheritTotalPoint, null]);
$userLogger->flush();
}
$logger = new ActionLogger($generalID, 0, $gameStor->year, $gameStor->month);
@@ -10,7 +10,7 @@ class che_명마_12_옥란백용구 extends \sammo\BaseStatItem{
public function __construct()
{
parent::__construct();
$this->info .= "<br>[전투] 남은 병력이 적을수록 회피 확률 증가. 최대 +30%p";
$this->info .= "<br>[전투] 남은 병력이 적을수록 회피 확률 증가. 최대 +50%p";
}
public function onCalcStat(General $general, string $statName, $value, $aux = null)
@@ -20,7 +20,7 @@ class che_명마_12_옥란백용구 extends \sammo\BaseStatItem{
$leadership = $general->getLeadership(true, true, true, false);
$crewL = $general->getVar('crew') / 100;
return $value + \sammo\Util::valueFit((1 - $crewL / $leadership) * 0.3, 0, 0.3);
return $value + \sammo\Util::valueFit((1 - $crewL / $leadership) * 0.5, 0, 0.5);
}
return $value;
}
+5 -1
View File
@@ -9,7 +9,7 @@ class che_징병_낙주 extends \sammo\BaseItem{
protected $rawName = '낙주';
protected $name = '낙주(징병)';
protected $info = '[군사] 징·모병비 -30%, 통솔 순수 능력치 보정 +15%';
protected $info = '[군사] 징·모병비 -30%<br>[기타] 통솔 순수 능력치 보정 +15%, 징병/모병/소집해제 시 인구 변동 없음';
protected $cost = 200;
protected $consumable = false;
@@ -18,6 +18,10 @@ class che_징병_낙주 extends \sammo\BaseItem{
if($varType == 'cost') return $value * 0.7;
}
if($turnType == '징집인구' && $varType == 'score'){
return 0;
}
return $value;
}
@@ -9,7 +9,7 @@ class event_전투특기_징병 extends \sammo\BaseItem{
protected $rawName = '비급';
protected $name = '비급(징병)';
protected $info = '[군사] 징·모병비 -50%, 통솔 순수 능력치 보정 +25%';
protected $info = '[군사] 징병/모병 시 훈사 70/84 제공<br>[기타] 통솔 순수 능력치 보정 +25%, 징병/모병/소집해제 시 인구 변동 없음';
protected $cost = 100;
protected $buyable = true;
protected $consumable = false;
@@ -17,7 +17,18 @@ class event_전투특기_징병 extends \sammo\BaseItem{
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float{
if(in_array($turnType, ['징병', '모병'])){
if($varType == 'cost') return $value * 0.5;
if($varType == 'train' || $varType == 'atmos'){
if($turnType === '징병'){
return 70;
}
else{
return 84;
}
}
}
if($turnType == '징집인구' && $varType == 'score'){
return 0;
}
return $value;
@@ -9,7 +9,7 @@ class che_event_징병 extends \sammo\BaseSpecial{
protected $id = 72;
protected $name = '징병';
protected $info = '[군사] 징·모병비 -50%, 통솔 순수 능력치 보정 +25%';
protected $info = '[군사] 징병/모병 시 훈사 70/84 제공<br>[기타] 통솔 순수 능력치 보정 +25%, 징병/모병/소집해제 시 인구 변동 없음';
static $selectWeightType = SpecialityHelper::WEIGHT_NORM;
static $selectWeight = 1;
@@ -21,9 +21,20 @@ class che_event_징병 extends \sammo\BaseSpecial{
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float{
if(in_array($turnType, ['징병', '모병'])){
if($varType == 'cost') return $value * 0.5;
if($varType == 'train' || $varType == 'atmos'){
if($turnType === '징병'){
return 70;
}
else{
return 84;
}
}
}
if($turnType == '징집인구' && $varType == 'score'){
return 0;
}
return $value;
}
+14 -3
View File
@@ -9,7 +9,7 @@ class che_징병 extends \sammo\BaseSpecial{
protected $id = 72;
protected $name = '징병';
protected $info = '[군사] 징·모병비 -50%, 통솔 순수 능력치 보정 +25%';
protected $info = '[군사] 징병/모병 시 훈사 70/84 제공<br>[기타] 통솔 순수 능력치 보정 +25%, 징병/모병/소집해제 시 인구 변동 없음';
static $selectWeightType = SpecialityHelper::WEIGHT_NORM;
static $selectWeight = 1;
@@ -21,9 +21,20 @@ class che_징병 extends \sammo\BaseSpecial{
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float{
if(in_array($turnType, ['징병', '모병'])){
if($varType == 'cost') return $value * 0.5;
if($varType == 'train' || $varType == 'atmos'){
if($turnType === '징병'){
return 70;
}
else{
return 84;
}
}
}
if($turnType == '징집인구' && $varType == 'score'){
return 0;
}
return $value;
}
@@ -179,6 +179,15 @@ class che_등용수락 extends Command\GeneralCommand{
$db->update('nation', $setScoutNationValues, 'nation=%i', $destNationID);
$general->increaseInheritancePoint(InheritanceKey::active_action, 1);
if($general->getNPCType() < 2){
$general->setAuxVar(
InheritanceKey::max_belong->value,
max(
$general->getVar('belong'),
$general->getAuxVar(InheritanceKey::max_belong->value) ?? 0
)
);
}
$general->setVar('permission', 'normal');
$general->setVar('belong', 1);
$general->setVar('officer_level', 1);
@@ -62,8 +62,6 @@ class che_소집해제 extends Command\GeneralCommand{
$general = $this->generalObj;
$date = $general->getTurnTime($general::TURNTIME_HM);
$crew = $general->getVar('crew');
$logger = $general->getLogger();
$logger->pushGeneralActionLog("병사들을 <R>소집해제</>하였습니다. <1>$date</>");
@@ -71,8 +69,10 @@ class che_소집해제 extends Command\GeneralCommand{
$exp = 70;
$ded = 100;
$crewUp = $general->onCalcDomestic('징집인구', 'score', $general->getVar('crew'));
$db->update('city', [
'pop'=>$db->sqleval('pop + %i', $crew)
'pop'=>$db->sqleval('pop + %i', $crewUp)
], 'city=%i', $general->getCityID());
$general->setVar('crew', 0);
+6
View File
@@ -10,6 +10,7 @@ use \sammo\{
use \sammo\Constraint\ConstraintHelper;
use function sammo\tryUniqueItemLottery;
use function sammo\CheckHall;
class che_은퇴 extends Command\GeneralCommand{
static protected $actionName = '은퇴';
@@ -59,12 +60,17 @@ class che_은퇴 extends Command\GeneralCommand{
}
$db = DB::db();
$env = $this->env;
$general = $this->generalObj;
$date = $general->getTurnTime($general::TURNTIME_HM);
$logger = $general->getLogger();
if ($env['isunited'] == 0) {
CheckHall($general->getID());
}
$general->rebirth();
$logger->pushGeneralActionLog("은퇴하였습니다. <1>$date</>");
+11 -6
View File
@@ -184,10 +184,13 @@ class che_징병 extends Command\GeneralCommand
$logger = $general->getLogger();
$setTrain = $general->onCalcDomestic(static::$actionName, 'train', static::$defaultTrain);
$setAtmos = $general->onCalcDomestic(static::$actionName, 'atmos', static::$defaultAtmos);
if ($reqCrewType->id == $currCrewType->id && $currCrew > 0) {
$logger->pushGeneralActionLog("{$crewTypeName} <C>{$reqCrewText}</>명을 추가{$this->getName()}했습니다. <1>$date</>");
$train = ($currCrew * $general->getVar('train') + $reqCrew * static::$defaultTrain) / ($currCrew + $reqCrew);
$atmos = ($currCrew * $general->getVar('atmos') + $reqCrew * static::$defaultAtmos) / ($currCrew + $reqCrew);
$train = ($currCrew * $general->getVar('train') + $reqCrew * $setTrain) / ($currCrew + $reqCrew);
$atmos = ($currCrew * $general->getVar('atmos') + $reqCrew * $setAtmos) / ($currCrew + $reqCrew);
$general->increaseVar('crew', $reqCrew);
$general->setVar('train', $train);
@@ -196,15 +199,17 @@ class che_징병 extends Command\GeneralCommand
$logger->pushGeneralActionLog("{$crewTypeName} <C>{$reqCrewText}</>명을 {$this->getName()}했습니다. <1>$date</>");
$general->setVar('crewtype', $reqCrewType->id);
$general->setVar('crew', $reqCrew);
$general->setVar('train', static::$defaultTrain);
$general->setVar('atmos', static::$defaultAtmos);
$general->setVar('train', $setTrain);
$general->setVar('atmos', $setAtmos);
}
$newTrust = Util::valueFit($this->city['trust'] - ($reqCrew / $this->city['pop']) / static::$costOffset * 100, 0);
$reqCrewDown = $general->onCalcDomestic('징집인구', 'score', $reqCrew);
$newTrust = Util::valueFit($this->city['trust'] - ($reqCrewDown / $this->city['pop']) / static::$costOffset * 100, 0);
$db->update('city', [
'trust' => $newTrust,
'pop' => $this->city['pop'] - $reqCrew
'pop' => $this->city['pop'] - $reqCrewDown
], 'city=%i', $general->getCityID());
$exp = Util::round($reqCrew / 100);
+9
View File
@@ -113,6 +113,15 @@ class che_하야 extends Command\GeneralCommand{
$general->setVar('troop', 0);
$general->increaseInheritancePoint(InheritanceKey::active_action, 1);
if($general->getNPCType() < 2){
$general->setAuxVar(
InheritanceKey::max_belong->value,
max(
$general->getVar('belong'),
$general->getAuxVar(InheritanceKey::max_belong->value) ?? 0
)
);
}
$this->setResultTurn(new LastTurn(static::getName(), $this->arg));
$general->checkStatChange();
+1
View File
@@ -94,6 +94,7 @@ class che_화계 extends Command\GeneralCommand
$prob = $maxGenScore / GameConst::$sabotageProbCoefByStat;
$prob += $probCorrection;
$prob += (sqrt(count($destCityGeneralList)) - 1) * GameConst::$sabotageDefenceCoefByGeneralCnt;
$prob += $destCity['secu'] / $destCity['secu_max'] / 5; //최대 20%p
$prob += $destCity['supply'] ? 0.1 : 0;
@@ -112,7 +112,7 @@ class che_불가침수락 extends Command\NationCommand
$month = $this->arg['month'];
$currentMonth = $env['year'] * 12 + $env['month'] - 1;
$reqMonth = $year * 12 + $month - 1;
$reqMonth = $year * 12 + $month;
$nationID = $this->nation['nation'];
@@ -199,7 +199,7 @@ class che_불가침수락 extends Command\NationCommand
$destLogger = $this->destGeneralObj->getLogger();
$currentMonth = $env['year'] * 12 + $env['month'] - 1;
$reqMonth = $year * 12 + $month - 1;
$reqMonth = $year * 12 + $month;
$db->update(
'diplomacy',
@@ -75,7 +75,7 @@ class che_피장파장 extends Command\NationCommand
$env = $this->env;
$this->setCity();
$this->setNation();
$this->setNation(['strategic_cmd_limit']);
$this->minConditionConstraints = [
ConstraintHelper::OccupiedCity(),
@@ -113,6 +113,7 @@ class che_피장파장 extends Command\NationCommand
[0, 1],
'선포, 전쟁중인 상대국에게만 가능합니다.'
),
ConstraintHelper::AvailableStrategicCommand(),
];
}
@@ -120,8 +121,9 @@ class che_피장파장 extends Command\NationCommand
{
$name = $this->getName();
$reqTurn = $this->getPreReqTurn() + 1;
$postReqTurn = $this->getPostReqTurn();
return "{$name}/{$reqTurn}턴(대상 재사용 대기 {$this->getTargetPostReqTurn()})";
return "{$name}/{$reqTurn}턴(재사용 대기 $postReqTurn, 대상 재사용 대기 {$this->getTargetPostReqTurn()})";
}
public function getCost(): array
@@ -136,7 +138,7 @@ class che_피장파장 extends Command\NationCommand
public function getPostReqTurn(): int
{
return 0;
return 8;
}
public function getTargetPostReqTurn(): int
@@ -0,0 +1,20 @@
<?php
namespace sammo\Event\Action;
use sammo\DB;
class AddGlobalBetray extends \sammo\Event\Action
{
public function __construct(private int $cnt = 1, private int $ifMax = 0)
{
}
public function run(array $env)
{
$db = DB::db();
$db->update('general', [
'betray' => $db->sqleval('betray + %i', $this->cnt),
], 'betray <= %i', $this->ifMax);
}
}
+11 -1
View File
@@ -46,6 +46,8 @@ class GameConstBase
public static $sabotageDefaultProb = 0.35;
/** @var int 계략시 확률 가중치(수치가 클수록 변화가 적음 : (지력차/$firing + $basefiring)*/
public static $sabotageProbCoefByStat = 300;
/** @var float 인원수 별 계략 방어 가중치 */
public static $sabotageDefenceCoefByGeneralCnt = 0.05;
/** @var int 계략시 최소 수치 감소량*/
public static $sabotageDamageMin = 100;
/** @var int 계략시 최대 수치 감소량*/
@@ -368,9 +370,9 @@ class GameConstBase
'che_의병모집',
'che_이호경식',
'che_급습',
'che_피장파장',
],
'기타' => [
'che_피장파장',
'che_국기변경',
'che_국호변경',
]
@@ -431,5 +433,13 @@ class GameConstBase
["NoticeToHistoryLog", "<S>출병 제한이 풀렸습니다.</>", ActionLogger::EVENT_YEAR_MONTH],
["DeleteEvent"]
],
[
"month", 2000,
["DateRelative", "==", 4, 1],
["NoticeToHistoryLog", "<S>이제부터 하야, 망명시 패널티가 적용됩니다.</>", ActionLogger::EVENT_YEAR_MONTH],
["AddGlobalBetray", 1, 0],
["AddGlobalBetray", 1, 1],
["DeleteEvent"]
],
];
}
+5 -5
View File
@@ -626,7 +626,6 @@ class General implements iAction
$inheritPointManager = InheritancePointManager::getInstance();
$inheritPointManager->mergeTotalInheritancePoint($this);
$inheritPointManager->applyInheritanceUser($this->getVar('owner'));
$inheritPointManager->clearInheritancePoint($this);
}
@@ -666,6 +665,8 @@ class General implements iAction
'reserved_until' => null,
], 'general_id=%i', $generalID);
storeOldGeneral($generalID, $logger->getYear(), $logger->getMonth());
$db->delete('general', 'no=%i', $generalID);
$db->delete('general_turn', 'general_id=%i', $generalID);
$db->delete('rank_data', 'general_id=%i', $generalID);
@@ -686,9 +687,8 @@ class General implements iAction
$ownerID = $this->getVar('owner');
if ($ownerID) {
$inheritPointManager->mergeTotalInheritancePoint($this);
$inheritPointManager->mergeTotalInheritancePoint($this, true);
$inheritPointManager->applyInheritanceUser($ownerID, true);
$inheritPointManager->clearInheritancePoint($this);
}
$this->multiplyVarWithLimit('leadership', 0.85, 10);
@@ -1331,8 +1331,8 @@ class General implements iAction
return InheritancePointManager::getInstance()->increaseInheritancePoint($this, $key, $value, $aux);
}
public function mergeTotalInheritancePoint(bool $isEnd = false)
public function mergeTotalInheritancePoint(bool $isRebirth = false)
{
InheritancePointManager::getInstance()->mergeTotalInheritancePoint($this, $isEnd);
InheritancePointManager::getInstance()->mergeTotalInheritancePoint($this, $isRebirth);
}
}
+62 -34
View File
@@ -11,8 +11,6 @@ class GeneralAI
{
protected RandUtil $rng;
/** @var General */
protected $general;
protected array $city;
protected array $nation;
protected int $genType;
@@ -65,6 +63,9 @@ class GeneralAI
/** @var General[] */
protected $chiefGenerals;
/** @var bool */
protected $reqUpdateInstance = true;
/** @var General[] */
protected $lostGenerals;
/** @var General[] 이번 턴에 '집합'하는 부대장 목록 */
@@ -80,15 +81,16 @@ class GeneralAI
const d직전 = 3;
const d전쟁 = 4;
//수뇌용
protected function updateInstance(): void{
if(!$this->reqUpdateInstance){
return;
}
$this->reqUpdateInstance = false;
public function __construct(General $general)
{
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
$this->env = $gameStor->getAll(true);
$this->baseDevelCost = $this->env['develcost'] * 12;
$this->general = $general;
$general = $this->general;
$city = $general->getRawCity();
if ($city === null) {
$city = $db->queryFirstRow('SELECT * FROM city WHERE city = %i', $general->getCityID());
@@ -96,14 +98,6 @@ class GeneralAI
}
$this->city = $city;
$this->rng = new RandUtil(new LiteHashDRBG(Util::simpleSerialize(
UniqueConst::$hiddenSeed,
'GeneralAI',
$this->env['year'],
$this->env['month'],
$general->getID(),
)));
$this->nation = $db->queryFirstRow(
'SELECT nation,name,color,capital,capset,gennum,gold,rice,bill,rate,rate_tmp,scout,war,strategic_cmd_limit,surlimit,tech,power,level,chief_set,type,aux FROM nation WHERE nation = %i',
$general->getNationID()
@@ -123,8 +117,8 @@ class GeneralAI
$nationStor = KVStorage::getStorage($db, $this->nation['nation'], 'nation_env');
$nationStor->cacheValues(['npc_nation_policy', 'npc_general_policy', 'prev_income_gold', 'prev_income_rice']);
$this->nationPolicy = new AutorunNationPolicy($general, $this->env['autorun_user']['options'] ?? null, $nationStor->getValue('npc_nation_policy'), $gameStor->getValue('npc_nation_policy'), $this->nation, $this->env);
$this->generalPolicy = new AutorunGeneralPolicy($general, $this->env['autorun_user']['options'] ?? null, $nationStor->getValue('npc_general_policy'), $gameStor->getValue('npc_general_policy'), $this->nation, $this->env);
$this->nationPolicy = new AutorunNationPolicy($general, $this->env['autorun_user']['options'] ?? null, $nationStor->getValue('npc_nation_policy'), ($this->env['npc_nation_policy']) ?? null, $this->nation, $this->env);
$this->generalPolicy = new AutorunGeneralPolicy($general, $this->env['autorun_user']['options'] ?? null, $nationStor->getValue('npc_general_policy'), ($this->env['npc_general_policy']) ?? null, $this->nation, $this->env);
$prevIncomeGold = $nationStor->prev_income_gold ?? 1000;
$prevIncomeRice = $nationStor->prev_income_rice ?? 1000;
@@ -142,6 +136,25 @@ class GeneralAI
$this->nation['aux'] = Json::decode($this->nation['aux'] ?? '{}');
$this->calcDiplomacyState();
$this->genType = $this->calcGenType($general);
}
public function __construct(protected General $general)
{
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
$this->env = $gameStor->getAll(true);
$this->rng = new RandUtil(new LiteHashDRBG(Util::simpleSerialize(
UniqueConst::$hiddenSeed,
'GeneralAI',
$this->env['year'],
$this->env['month'],
$general->getID(),
)));
$this->leadership = $general->getLeadership();
$this->strength = $general->getStrength();
$this->intel = $general->getIntel();
@@ -149,11 +162,6 @@ class GeneralAI
$this->fullLeadership = $general->getLeadership(false);
$this->fullStrength = $general->getStrength(false);
$this->fullIntel = $general->getIntel(false);
$this->genType = $this->calcGenType($general);
$this->calcDiplomacyState();
}
public function getGeneralObj(): General
@@ -572,6 +580,9 @@ class GeneralAI
if ($userGeneral->getVar('crew') >= $this->nationPolicy->minWarCrew) {
continue;
}
if ($userGeneral->onCalcDomestic('징집인구', 'score', 100) <= 1) {
continue;
}
$generalTurnTime = $userGeneral->getTurnTime();
$troopTurnTime = $troopLeader->getTurnTime();
@@ -665,6 +676,9 @@ class GeneralAI
if ($userGeneral->getVar('crew') >= $this->nationPolicy->minWarCrew) {
continue;
}
if ($userGeneral->onCalcDomestic('징집인구', 'score', 100) <= 1) {
continue;
}
$generalCadidates[$generalID] = $userGeneral;
}
@@ -678,10 +692,8 @@ class GeneralAI
/** @var General */
$pickedGeneral = $this->rng->choice($generalCadidates);
$minRecruitPop = $this->fullLeadership * 100 + GameConst::$minAvailableRecruitPop;
if (!$this->generalPolicy->can한계징병) {
$minRecruitPop = max($minRecruitPop, $this->fullLeadership * 100 + $this->nationPolicy->minNPCRecruitCityPopulation);
}
$pickedGeneralLeadership = $pickedGeneral->getLeadership(false, true, true, true);
$minRecruitPop = $pickedGeneralLeadership * 100 + GameConst::$minAvailableRecruitPop;
$recruitableCityList = [];
@@ -964,6 +976,9 @@ class GeneralAI
if ($npcGeneral->getVar('crew') >= $this->nationPolicy->minWarCrew) {
continue;
}
if ($npcGeneral->onCalcDomestic('징집인구', 'score', 100) <= 1) {
continue;
}
$generalCadidates[$generalID] = $npcGeneral;
}
@@ -977,10 +992,9 @@ class GeneralAI
/** @var General */
$pickedGeneral = $this->rng->choice($generalCadidates);
$minRecruitPop = $this->fullLeadership * 100 + GameConst::$minAvailableRecruitPop;
if (!$this->generalPolicy->can한계징병) {
$minRecruitPop = max($minRecruitPop, $this->fullLeadership * 100 + $this->nationPolicy->minNPCRecruitCityPopulation);
}
$pickedGeneralLeadership = $pickedGeneral->getLeadership(false, true, true, true);
$minRecruitPop = $pickedGeneralLeadership * 100 + GameConst::$minAvailableRecruitPop;
$minRecruitPop = max($minRecruitPop, $pickedGeneralLeadership * 100 + $this->nationPolicy->minNPCRecruitCityPopulation);
$recruitableCityList = [];
@@ -1289,6 +1303,7 @@ class GeneralAI
return null;
}
$this->reqUpdateInstance = true;
return $cmd;
}
@@ -1489,6 +1504,7 @@ class GeneralAI
return null;
}
$this->reqUpdateInstance = true;
return $cmd;
}
@@ -1951,6 +1967,7 @@ class GeneralAI
return null;
}
$this->reqUpdateInstance = true;
return $cmd;
}
@@ -1968,6 +1985,7 @@ class GeneralAI
$cmd = buildNationCommandClass('che_천도', $this->general, $this->env, $lastTurn, $lastTurn->getArg());
if ($cmd->hasFullConditionMet()) {
$nationStor->last천도Trial = [$general->getVar('officer_level'), $general->getTurnTime()];
$this->reqUpdateInstance = true;
return $cmd;
}
}
@@ -2090,6 +2108,7 @@ class GeneralAI
$nationStor->last천도Trial = [$general->getVar('officer_level'), $general->getTurnTime()];
$this->reqUpdateInstance = true;
return $cmd;
}
@@ -2653,7 +2672,7 @@ class GeneralAI
return $this->rng->choiceUsingWeightPair($cmdList);
}
public function do소집해제(): ?GeneralCommand
protected function do소집해제(): ?GeneralCommand
{
if ($this->attackable) {
return null;
@@ -2972,6 +2991,9 @@ class GeneralAI
}
foreach ($this->frontCities as $frontCity) {
if(!$frontCity['supply']){
continue;
}
$candidateCities[$frontCity['city']] = $frontCity['important'];
}
@@ -3454,7 +3476,7 @@ class GeneralAI
}
if ($nationCity['front']) {
$frontCities[$cityID] = $nationCity;
} else {
} else if($nationCity['supply']) {
$backupCities[$cityID] = $nationCity;
}
@@ -3532,7 +3554,7 @@ class GeneralAI
} else if ($nationGeneral->getVar('troop') === $generalID && $nationGeneral->getReservedTurn(0, $this->env)->getName() === 'che_집합') {
//비 NPC부대장임
$troopLeaders[$generalID] = $nationGeneral;
} else if ($nationGeneral->getVar('killturn') < 5) {
} else if ($nationGeneral->getVar('killturn') <= 5) {
//삭턴이 몇 안남은 장수는 '내정장 npc'로 처리
$npcCivilGenerals[$generalID] = $nationGeneral;
} else if ($npcType < 2) {
@@ -3570,6 +3592,8 @@ class GeneralAI
public function chooseNationTurn(NationCommand $reservedCommand): NationCommand
{
$this->updateInstance();
//TODO: NationTurn과 InstantNationTurn 구분 필요
$lastTurn = $reservedCommand->getLastTurn();
$general = $this->general;
@@ -3641,6 +3665,8 @@ class GeneralAI
return $reservedCommand;
}
$this->updateInstance();
foreach ($this->nationPolicy->priority as $actionName) {
/** @var ?NationCommand */
if (!key_exists($actionName, $this->nationPolicy::$availableInstantTurn)) {
@@ -3663,6 +3689,8 @@ class GeneralAI
$npcType = $general->getNPCType();
$nationID = $general->getNationID();
$this->updateInstance();
//특별 메세지 있는 경우 출력
$term = $this->env['turnterm'];
if ($general->getVar('npcmsg') && $this->rng->nextBool(GameConst::$npcMessageFreqByDay * $term / (60 * 24))) {
@@ -23,8 +23,9 @@ class che_병력군량소모 extends BaseGeneralTrigger{
}
else{
$db = DB::db();
$crewUp = $general->onCalcDomestic('징집인구', 'score', $general->getVar('crew'));
$db->update('city', [
'pop'=>$db->sqleval('pop + %i', $general->getVar('crew'))
'pop'=>$db->sqleval('pop + %i', $crewUp)
], 'city=%i', $general->getCityID());
$general->setVar('crew', 0);
+37 -26
View File
@@ -17,18 +17,18 @@ class InheritancePointManager
private function __construct()
{
$inheritanceKey = new Map();
$inheritanceKey->put(InheritanceKey::previous, new InheritancePointType(true, 1, '기존 포인트'));
$inheritanceKey->put(InheritanceKey::lived_month, new InheritancePointType(true, 1, '생존'));
$inheritanceKey->put(InheritanceKey::max_belong, new InheritancePointType(false, 10, '최대 임관년 수'));
$inheritanceKey->put(InheritanceKey::max_domestic_critical, new InheritancePointType(true, 1, '최대 연속 내정 성공'));
$inheritanceKey->put(InheritanceKey::active_action, new InheritancePointType(true, 3, '능동 행동 수'));
$inheritanceKey->put(InheritanceKey::previous, new InheritancePointType(true, 1, '기존 포인트', 1));
$inheritanceKey->put(InheritanceKey::lived_month, new InheritancePointType(true, 1, '생존', 1));
$inheritanceKey->put(InheritanceKey::max_belong, new InheritancePointType(false, 10, '최대 임관년 수', null));
$inheritanceKey->put(InheritanceKey::max_domestic_critical, new InheritancePointType(true, 1, '최대 연속 내정 성공', null));
$inheritanceKey->put(InheritanceKey::active_action, new InheritancePointType(true, 3, '능동 행동 수', 1));
//$inheritanceKey->put(InheritanceKey::snipe_combat, new InheritancePointType(true, 10, '병종 상성 우위 횟수'));
$inheritanceKey->put(InheritanceKey::combat, new InheritancePointType(['rank', RankColumn::warnum], 5, '전투 횟수'));
$inheritanceKey->put(InheritanceKey::sabotage, new InheritancePointType(['rank', RankColumn::firenum], 20, '계략 성공 횟수'));
$inheritanceKey->put(InheritanceKey::unifier, new InheritancePointType(true, 1, '천통 기여'));
$inheritanceKey->put(InheritanceKey::dex, new InheritancePointType(false, 0.001, '숙련도'));
$inheritanceKey->put(InheritanceKey::tournament, new InheritancePointType(true, 1, '토너먼트'));
$inheritanceKey->put(InheritanceKey::betting, new InheritancePointType(false, 10, '베팅 당첨'));
$inheritanceKey->put(InheritanceKey::combat, new InheritancePointType(['rank', RankColumn::warnum], 5, '전투 횟수', 1));
$inheritanceKey->put(InheritanceKey::sabotage, new InheritancePointType(['rank', RankColumn::firenum], 20, '계략 성공 횟수', 1));
$inheritanceKey->put(InheritanceKey::unifier, new InheritancePointType(true, 1, '천통 기여', null));
$inheritanceKey->put(InheritanceKey::dex, new InheritancePointType(false, 0.001, '숙련도', 0.5));
$inheritanceKey->put(InheritanceKey::tournament, new InheritancePointType(true, 1, '토너먼트', 1));
$inheritanceKey->put(InheritanceKey::betting, new InheritancePointType(false, 10, '베팅 당첨', 1));
$this->inheritanceKey = $inheritanceKey;
}
@@ -258,9 +258,8 @@ class InheritancePointManager
$inheritStor->setValue($key->value, [$newValue, $aux]);
}
public function clearInheritancePoint(General $general)
public function clearInheritancePoint(?int $ownerID)
{
$ownerID = $general->getVar('owner');
if (!$ownerID) {
return;
}
@@ -281,7 +280,7 @@ class InheritancePointManager
$inheritStor->setValue(InheritanceKey::previous->value, $previousPointInfo);
}
public function mergeTotalInheritancePoint(General $general, bool $isEnd = false)
public function mergeTotalInheritancePoint(General $general, bool $isRebirth = false)
{
$ownerID = $general->getVar('owner');
if (!$ownerID) {
@@ -296,7 +295,7 @@ class InheritancePointManager
$gameStor->cacheValues(['year', 'startyear', 'month']);
if ($general->getVar('npc') == 1) {
if (!$isEnd) {
if ($isRebirth) {
return;
}
@@ -331,18 +330,14 @@ class InheritancePointManager
}
function applyInheritanceUser(int $userID, bool $isRebirth = false): float
function applyInheritanceUser(int $ownerID, bool $isRebirth = false): float
{
if ($userID === 0) {
if ($ownerID === 0) {
return 0;
}
//FIXME: 굳이 merge, apply, clean 3단계를 거쳐야 할 이유가 없음
/** @var Map<InheritanceKey,float> */
$rebirthDegraded = new Map();
$rebirthDegraded[InheritanceKey::dex] = 0.5;
$inheritStor = KVStorage::getStorage(DB::db(), "inheritance_{$userID}");
$inheritStor = KVStorage::getStorage(DB::db(), "inheritance_{$ownerID}");
$totalPoint = 0;
/** @var array<string,array{0:float,1:string|float}> */
$allPoints = $inheritStor->getAll();
@@ -355,15 +350,27 @@ class InheritancePointManager
return $allPoints[InheritanceKey::previous->value][0];
}
$userLogger = new UserLogger($userID);
$userLogger = new UserLogger($ownerID);
$previousPoint = ($allPoints[InheritanceKey::previous->value] ?? [0, 0])[0];
foreach ($allPoints as $rKey => [$value,]) {
$keepValues = [];
foreach ($allPoints as $rKey => [$value, $auxV]) {
$key = InheritanceKey::from($rKey);
if ($isRebirth && $rebirthDegraded->hasKey($key)) {
$value *= $rebirthDegraded[$key];
/** @var InheritancePointType */
$keyTypeObj = $this->inheritanceKey->get($key);
if ($isRebirth) {
if ($keyTypeObj->rebirthStoreCoeff === null) {
$keepValues[$rKey] = [$value, $auxV];
continue;
}
$value *= $keyTypeObj->rebirthStoreCoeff;
}
$keyText = $this->getInheritancePointType($key)->info;
$userLogger->push("{$keyText} 포인트 {$value} 증가", "inheritPoint");
$totalPoint += $value;
@@ -373,6 +380,10 @@ class InheritancePointManager
$userLogger->flush();
$inheritStor->resetValues();
foreach ($keepValues as $rKey => $pointPair) {
$inheritStor->setValue($rKey, $pointPair);
}
$inheritStor->setValue(InheritanceKey::previous->value, [$totalPoint, null]);
return $totalPoint;
}
-1
View File
@@ -195,7 +195,6 @@ class TurnExecutionHelper
$general->setVar('owner_name', null);
} else {
$general->applyDB($db);
storeOldGeneral($generalID, $gameStor->year, $gameStor->month);
$general->kill($db);
return;
}
+1
View File
@@ -5,6 +5,7 @@ class InheritancePointType{
public bool|array $storeType,
public int|float $pointCoeff,
public string $info,
public ?float $rebirthStoreCoeff,
)
{
+27
View File
@@ -78,6 +78,7 @@ if ($expires < $now) {
}
$oauthID = null;
if (!$email) {
$me = $restAPI->meWithEmail();
$me['code'] = Util::array_get($me['code'], 0);
@@ -88,6 +89,7 @@ if (!$email) {
'reason' => '카카오로그인이 정상적으로 수행되지 않았습니다.'
]);
}
$oauthID = $me['id'];
$kakao_account = $me['kakao_account'] ?? null;
if (!$kakao_account) {
@@ -128,6 +130,31 @@ $userInfo = $RootDB->queryFirstRow(
$email
);
if (!$userInfo) {
if(!$oauthID){
$me = $restAPI->meWithEmail();
if ($me['code']??0 < 0) {
Json::die([
'result' => false,
'reqOTP' => false,
'reason' => '카카오로그인이 정상적으로 수행되지 않았습니다.'
]);
}
$oauthID = $me['id'];
}
//이메일 계정이 바뀐 것인가?
$userInfo = $RootDB->queryFirstRow(
'SELECT `no`, `id`, `name`, `grade`, `delete_after`, `acl`, oauth_info, token_valid_until from member where oauth_id=%i',
$oauthID
);
if($userInfo){
//이메일 계정이 바뀐 것이므로, 이메일 계정을 업데이트한다.
$RootDB->update('member', [
'email' => $email,
], 'oauth_id=%i', $oauthID);
}
}
if (!$userInfo) {
$restAPI->unlink();
$session->access_token = null;
-3
View File
@@ -118,9 +118,6 @@
"webpack-bundle-analyzer": "^4.6.1",
"webpack-cli": "^4.10.0"
},
"pre-commit": [
"lint"
],
"browserslist": [
"last 3 versions",
"> 0.4%",