feat: 도시 점령, 국가 멸망 시 트리거 추가

This commit is contained in:
2022-02-05 07:43:27 +00:00
committed by Gitea
parent 2ff3746df2
commit 4e359f5eb9
3 changed files with 212 additions and 153 deletions
+71 -36
View File
@@ -1,8 +1,10 @@
<?php <?php
namespace sammo; namespace sammo;
function processWar(General $attackerGeneral, array $rawAttackerNation, array $rawDefenderCity){ function processWar(General $attackerGeneral, array $rawAttackerNation, array $rawDefenderCity)
{
$db = DB::db(); $db = DB::db();
@@ -21,8 +23,7 @@ function processWar(General $attackerGeneral, array $rawAttackerNation, array $r
'tech' => 0, 'tech' => 0,
'gennum' => 1 'gennum' => 1
]; ];
} } else {
else{
$rawDefenderNation = $db->queryFirstRow('SELECT nation,`level`,`name`,capital,gennum,tech,`type`,gold,rice FROM nation WHERE nation = %i', $defenderNationID); $rawDefenderNation = $db->queryFirstRow('SELECT nation,`level`,`name`,capital,gennum,tech,`type`,gold,rice FROM nation WHERE nation = %i', $defenderNationID);
} }
@@ -91,12 +92,10 @@ function processWar(General $attackerGeneral, array $rawAttackerNation, array $r
Util::setRound($rice); Util::setRound($rice);
$updateDefenderNation['rice'] = max(0, $rawDefenderNation['rice'] - $rice); $updateDefenderNation['rice'] = max(0, $rawDefenderNation['rice'] - $rice);
} } else if ($conquerCity) {
else if($conquerCity){
if ($rawDefenderNation['capital'] == $rawDefenderCity['city']) { if ($rawDefenderNation['capital'] == $rawDefenderCity['city']) {
$updateDefenderNation['rice'] = $rawDefenderNation['rice'] + 1000; $updateDefenderNation['rice'] = $rawDefenderNation['rice'] + 1000;
} } else {
else{
$updateDefenderNation['rice'] = $rawDefenderNation['rice'] + 500; $updateDefenderNation['rice'] = $rawDefenderNation['rice'] + 500;
} }
} }
@@ -179,7 +178,8 @@ function processWar(General $attackerGeneral, array $rawAttackerNation, array $r
], $attacker->getGeneral(), $city->getRaw()); ], $attacker->getGeneral(), $city->getRaw());
} }
function extractBattleOrder(General $general){ function extractBattleOrder(General $general)
{
if ($general->getVar('crew') == 0) { if ($general->getVar('crew') == 0) {
return 0; return 0;
} }
@@ -291,8 +291,7 @@ function processWar_NG(
$josaRo = JosaUtil::pick($defenderCrewTypeName, '로'); $josaRo = JosaUtil::pick($defenderCrewTypeName, '로');
$josaUl = JosaUtil::pick($attackerCrewTypeName, '을'); $josaUl = JosaUtil::pick($attackerCrewTypeName, '을');
$defender->getLogger()->pushGeneralActionLog("{$defenderCrewTypeName}{$josaRo} <Y>{$attackerName}</>의 {$attackerCrewTypeName}{$josaUl} <M>수비</>합니다."); $defender->getLogger()->pushGeneralActionLog("{$defenderCrewTypeName}{$josaRo} <Y>{$attackerName}</>의 {$attackerCrewTypeName}{$josaUl} <M>수비</>합니다.");
} } else {
else{
$josaYi = JosaUtil::pick($attackerName, '이'); $josaYi = JosaUtil::pick($attackerName, '이');
$josaRo = JosaUtil::pick($attackerCrewTypeName, '로'); $josaRo = JosaUtil::pick($attackerCrewTypeName, '로');
$logger->pushGlobalActionLog("<Y>{$attackerName}</>{$josaYi} {$attackerCrewTypeName}{$josaRo} 성벽을 공격합니다."); $logger->pushGlobalActionLog("<Y>{$attackerName}</>{$josaYi} {$attackerCrewTypeName}{$josaRo} 성벽을 공격합니다.");
@@ -332,8 +331,7 @@ function processWar_NG(
//수비자가 더 병력 부족 //수비자가 더 병력 부족
$deadAttacker /= $deadDefenderRatio; $deadAttacker /= $deadDefenderRatio;
$deadDefender = $defenderHP; $deadDefender = $defenderHP;
} } else {
else{
//공격자가 더 병력 부족 //공격자가 더 병력 부족
$deadDefender /= $deadAttackerRatio; $deadDefender /= $deadAttackerRatio;
$deadAttacker = $attackerHP; $deadAttacker = $attackerHP;
@@ -379,8 +377,7 @@ function processWar_NG(
$logger->pushGlobalActionLog("<Y>{$attacker->getName()}</>의 {$attacker->getCrewTypeName()}{$josaYi} 퇴각했습니다."); $logger->pushGlobalActionLog("<Y>{$attacker->getName()}</>의 {$attacker->getCrewTypeName()}{$josaYi} 퇴각했습니다.");
if ($noRice) { if ($noRice) {
$attacker->getLogger()->pushGeneralActionLog("군량 부족으로 퇴각합니다.", ActionLogger::PLAIN); $attacker->getLogger()->pushGeneralActionLog("군량 부족으로 퇴각합니다.", ActionLogger::PLAIN);
} } else {
else{
$attacker->getLogger()->pushGeneralActionLog("퇴각했습니다.", ActionLogger::PLAIN); $attacker->getLogger()->pushGeneralActionLog("퇴각했습니다.", ActionLogger::PLAIN);
} }
$defender->getLogger()->pushGeneralActionLog("<Y>{$attacker->getName()}</>의 {$attacker->getCrewTypeName()}{$josaYi} 퇴각했습니다.", ActionLogger::PLAIN); $defender->getLogger()->pushGeneralActionLog("<Y>{$attacker->getName()}</>의 {$attacker->getCrewTypeName()}{$josaYi} 퇴각했습니다.", ActionLogger::PLAIN);
@@ -411,8 +408,7 @@ function processWar_NG(
$logger->pushGlobalActionLog("<Y>{$defender->getName()}</>의 {$defender->getCrewTypeName()}{$josaYi} 패퇴했습니다."); $logger->pushGlobalActionLog("<Y>{$defender->getName()}</>의 {$defender->getCrewTypeName()}{$josaYi} 패퇴했습니다.");
$attacker->getLogger()->pushGeneralActionLog("<Y>{$defender->getName()}</>의 {$defender->getCrewTypeName()}{$josaYi} 패퇴했습니다.", ActionLogger::PLAIN); $attacker->getLogger()->pushGeneralActionLog("<Y>{$defender->getName()}</>의 {$defender->getCrewTypeName()}{$josaYi} 패퇴했습니다.", ActionLogger::PLAIN);
$defender->getLogger()->pushGeneralActionLog("군량 부족으로 패퇴합니다.", ActionLogger::PLAIN); $defender->getLogger()->pushGeneralActionLog("군량 부족으로 패퇴합니다.", ActionLogger::PLAIN);
} } else {
else{
$logger->pushGlobalActionLog("<Y>{$defender->getName()}</>의 {$defender->getCrewTypeName()}{$josaYi} 전멸했습니다."); $logger->pushGlobalActionLog("<Y>{$defender->getName()}</>의 {$defender->getCrewTypeName()}{$josaYi} 전멸했습니다.");
$attacker->getLogger()->pushGeneralActionLog("<Y>{$defender->getName()}</>의 {$defender->getCrewTypeName()}{$josaYi} 전멸했습니다.", ActionLogger::PLAIN); $attacker->getLogger()->pushGeneralActionLog("<Y>{$defender->getName()}</>의 {$defender->getCrewTypeName()}{$josaYi} 전멸했습니다.", ActionLogger::PLAIN);
$defender->getLogger()->pushGeneralActionLog("전멸했습니다.", ActionLogger::PLAIN); $defender->getLogger()->pushGeneralActionLog("전멸했습니다.", ActionLogger::PLAIN);
@@ -428,9 +424,7 @@ function processWar_NG(
if ($defender !== null && !($defender instanceof WarUnitGeneral)) { if ($defender !== null && !($defender instanceof WarUnitGeneral)) {
throw new \RuntimeException('다음 수비자를 받아오는데 실패'); throw new \RuntimeException('다음 수비자를 받아오는데 실패');
} }
} }
} }
if ($currPhase == $attacker->getMaxPhase()) { if ($currPhase == $attacker->getMaxPhase()) {
@@ -459,7 +453,8 @@ function processWar_NG(
return $conquerCity; return $conquerCity;
} }
function DeleteConflict($nation) { function DeleteConflict($nation)
{
$db = DB::db(); $db = DB::db();
foreach ($db->queryAllLists('SELECT city, conflict FROM city WHERE conflict!=%s', '{}') as list($cityID, $rawConflict)) { foreach ($db->queryAllLists('SELECT city, conflict FROM city WHERE conflict!=%s', '{}') as list($cityID, $rawConflict)) {
@@ -480,12 +475,14 @@ function DeleteConflict($nation) {
} }
} }
function getConquerNation($city) : int { function getConquerNation($city): int
{
$conflict = Json::decode($city['conflict']); $conflict = Json::decode($city['conflict']);
return Util::array_first_key($conflict); return Util::array_first_key($conflict);
} }
function ConquerCity(array $admin, General $general, array $city) { function ConquerCity(array $admin, General $general, array $city)
{
$db = DB::db(); $db = DB::db();
$year = $admin['year']; $year = $admin['year'];
@@ -524,6 +521,27 @@ function ConquerCity(array $admin, General $general, array $city) {
$defenderNationLogger->pushNationalHistoryLog("<D><b>{$attackerNationName}</b></>의 <Y>{$attackerGeneralName}</>에 의해 <G><b>{$cityName}</b></>{$josaYiCity} <O>함락</>"); $defenderNationLogger->pushNationalHistoryLog("<D><b>{$attackerNationName}</b></>의 <Y>{$attackerGeneralName}</>에 의해 <G><b>{$cityName}</b></>{$josaYiCity} <O>함락</>");
$gameStor = KVStorage::getStorage($db, 'game_env');
// 이벤트 핸들러 동작
$e_env = null;
foreach (DB::db()->query('SELECT * FROM event WHERE target = "OCCUPY_CITY" ORDER BY `priority` DESC, `id` ASC') as $rawEvent) {
if ($e_env === null) {
$e_env = $gameStor->getAll(false);
}
$eventID = $rawEvent['id'];
$cond = Json::decode($rawEvent['condition']);
$action = Json::decode($rawEvent['action']);
$event = new Event\EventHandler($cond, $action);
$e_env['currentEventID'] = $eventID;
$event->tryRunEvent($e_env);
}
if ($e_env !== null) {
$gameStor->resetCache();
}
// 국가 멸망시 // 국가 멸망시
if ($defenderNationID && $db->queryFirstField('SELECT count(city) FROM city WHERE nation = %i', $defenderNationID) === 1) { if ($defenderNationID && $db->queryFirstField('SELECT count(city) FROM city WHERE nation = %i', $defenderNationID) === 1) {
$defenderNationLogger->flush(); $defenderNationLogger->flush();
@@ -605,18 +623,37 @@ function ConquerCity(array $admin, General $general, array $city) {
$loseNationRiceText = number_format($loseNationRice); $loseNationRiceText = number_format($loseNationRice);
$resourceLog = "<D><b>{$defenderNationName}</b></> 정복으로 금<C>{$loseNationGoldText}</> 쌀<C>{$loseNationRiceText}</>을 획득했습니다."; $resourceLog = "<D><b>{$defenderNationName}</b></> 정복으로 금<C>{$loseNationGoldText}</> 쌀<C>{$loseNationRiceText}</>을 획득했습니다.";
foreach ($db->queryFirstColumn( foreach ($db->queryFirstColumn(
'SELECT no FROM general WHERE nation=%i AND officer_level>=5', $attackerNationID 'SELECT no FROM general WHERE nation=%i AND officer_level>=5',
) as $attackerChiefID $attackerNationID
){ ) as $attackerChiefID) {
if ($attackerChiefID == $attackerID) { if ($attackerChiefID == $attackerID) {
$attackerLogger->pushGeneralActionLog($resourceLog, ActionLogger::PLAIN); $attackerLogger->pushGeneralActionLog($resourceLog, ActionLogger::PLAIN);
} } else {
else{
$chiefLogger = new ActionLogger($attackerChiefID, $attackerNationID, $year, $month); $chiefLogger = new ActionLogger($attackerChiefID, $attackerNationID, $year, $month);
$chiefLogger->pushGeneralActionLog($resourceLog, ActionLogger::PLAIN); $chiefLogger->pushGeneralActionLog($resourceLog, ActionLogger::PLAIN);
$chiefLogger->flush(); $chiefLogger->flush();
} }
} }
// 이벤트 핸들러 동작
$e_env = null;
foreach (DB::db()->query('SELECT * FROM event WHERE target = "DESTROY_NATION" ORDER BY `priority` DESC, `id` ASC') as $rawEvent) {
if ($e_env === null) {
$e_env = $gameStor->getAll(false);
}
$eventID = $rawEvent['id'];
$cond = Json::decode($rawEvent['condition']);
$action = Json::decode($rawEvent['action']);
$event = new Event\EventHandler($cond, $action);
$e_env['currentEventID'] = $eventID;
$event->tryRunEvent($e_env);
}
if ($e_env !== null) {
$gameStor->resetCache();
}
// 멸망이 아니면 // 멸망이 아니면
} else { } else {
// 태수,군사,종사은 일반으로... // 태수,군사,종사은 일반으로...
@@ -637,9 +674,9 @@ function ConquerCity(array $admin, General $general, array $city) {
$moveLog = "수도가 함락되어 <G><b>$minCityName</b></>으로 <M>긴급천도</>합니다."; $moveLog = "수도가 함락되어 <G><b>$minCityName</b></>으로 <M>긴급천도</>합니다.";
//아국 수뇌부에게 로그 전달 //아국 수뇌부에게 로그 전달
foreach ($db->queryFirstColumn( foreach ($db->queryFirstColumn(
'SELECT no FROM general WHERE nation=%i AND officer_level>=5', $defenderNationID 'SELECT no FROM general WHERE nation=%i AND officer_level>=5',
) as $defenderChiefID $defenderNationID
){ ) as $defenderChiefID) {
$chiefLogger = new ActionLogger($defenderChiefID, $defenderNationID, $year, $month); $chiefLogger = new ActionLogger($defenderChiefID, $defenderNationID, $year, $month);
$chiefLogger->pushGeneralActionLog($moveLog, ActionLogger::PLAIN); $chiefLogger->pushGeneralActionLog($moveLog, ActionLogger::PLAIN);
$chiefLogger->flush(); $chiefLogger->flush();
@@ -675,8 +712,7 @@ function ConquerCity(array $admin, General $general, array $city) {
$db->update('general', [ $db->update('general', [
'city' => $cityID 'city' => $cityID
], 'no=%i', $attackerID); ], 'no=%i', $attackerID);
} } else {
else{
$conquerNationName = getNationStaticInfo($conquerNation)['name']; $conquerNationName = getNationStaticInfo($conquerNation)['name'];
$conquerNationLogger = new ActionLogger(0, $conquerNation, $year, $month); $conquerNationLogger = new ActionLogger(0, $conquerNation, $year, $month);
@@ -722,17 +758,16 @@ function ConquerCity(array $admin, General $general, array $city) {
} }
} }
function findNextCapital(int $capitalID, int $nationID):int{ function findNextCapital(int $capitalID, int $nationID): int
{
$distList = searchDistance($capitalID, 99, true); $distList = searchDistance($capitalID, 99, true);
$cities = []; $cities = [];
foreach( foreach (DB::db()->query(
DB::db()->query(
'SELECT city, pop FROM city WHERE nation=%i and city!=%i', 'SELECT city, pop FROM city WHERE nation=%i and city!=%i',
$nationID, $nationID,
$capitalID $capitalID
) as $row ) as $row) {
){
$cities[$row['city']] = $row['pop']; $cities[$row['city']] = $row['pop'];
}; };
+25 -1
View File
@@ -7,13 +7,17 @@ use \sammo\{
ActionLogger, ActionLogger,
GameConst, GameUnitConst, GameConst, GameUnitConst,
LastTurn, LastTurn,
Command Command,
Json,
KVStorage
}; };
use \sammo\Constraint\Constraint; use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper; use \sammo\Constraint\ConstraintHelper;
use sammo\CityConst; use sammo\CityConst;
use sammo\Event\EventHandler;
use function sammo\refreshNationStaticInfo; use function sammo\refreshNationStaticInfo;
use function sammo\deleteNation; use function sammo\deleteNation;
use function sammo\tryRollbackInheritUniqueItem; use function sammo\tryRollbackInheritUniqueItem;
@@ -98,6 +102,26 @@ class che_해산 extends Command\GeneralCommand{
tryRollbackInheritUniqueItem($general); tryRollbackInheritUniqueItem($general);
$general->applyDB($db); $general->applyDB($db);
// 이벤트 핸들러 동작
$gameStor = KVStorage::getStorage($db, 'game_env');
$e_env = null;
foreach (DB::db()->query('SELECT * FROM event WHERE target = "DESTROY_NATION" ORDER BY `priority` DESC, `id` ASC') as $rawEvent) {
if ($e_env === null) {
$e_env = $gameStor->getAll(false);
}
$eventID = $rawEvent['id'];
$cond = Json::decode($rawEvent['condition']);
$action = Json::decode($rawEvent['action']);
$event = new EventHandler($cond, $action);
$e_env['currentEventID'] = $eventID;
$event->tryRunEvent($e_env);
}
if ($e_env !== null) {
$gameStor->resetCache();
}
return true; return true;
} }
+4 -4
View File
@@ -398,7 +398,7 @@ class TurnExecutionHelper
// 1달마다 처리하는 것들, 벌점 감소 및 건국,전턴,합병 -1, 군량 소모 // 1달마다 처리하는 것들, 벌점 감소 및 건국,전턴,합병 -1, 군량 소모
if (!preUpdateMonthly()) { if (!preUpdateMonthly()) {
$gameStor->resetCache(true); $gameStor->resetCache();
unlock(); unlock();
throw new \RuntimeException('preUpdateMonthly() 처리 에러'); throw new \RuntimeException('preUpdateMonthly() 처리 에러');
} }
@@ -435,7 +435,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 WHERE target = "MONTH" ORDER BY `priority` DESC, `id` ASC') as $rawEvent) {
if ($e_env === null) { if ($e_env === null) {
$e_env = $gameStor->getAll(false); $e_env = $gameStor->getAll(false);
} }
@@ -449,7 +449,7 @@ class TurnExecutionHelper
} }
if ($e_env !== null) { if ($e_env !== null) {
$gameStor->resetCache(true); $gameStor->resetCache();
} }
postUpdateMonthly(); postUpdateMonthly();
@@ -480,7 +480,7 @@ class TurnExecutionHelper
//거래 처리 //거래 처리
processAuction(); processAuction();
// 잡금 해제 // 잡금 해제
$gameStor->resetCache(true); $gameStor->resetCache();
unlock(); unlock();
} }
} }