From e9393a2e8ecfa290b714cbb6ae128d3befcf891d Mon Sep 17 00:00:00 2001 From: letrhee Date: Sun, 28 Mar 2021 03:13:03 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20RaiserInvader=20=EC=B4=88=EA=B8=B0=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hwe/sammo/Event/Action.php | 2 +- hwe/sammo/Event/Action/AutoDeleteInvader.php | 40 ++++ hwe/sammo/Event/Action/ChangeCity.php | 2 +- hwe/sammo/Event/Action/CreateAdminNPC.php | 2 +- hwe/sammo/Event/Action/CreateManyNPC.php | 2 +- hwe/sammo/Event/Action/DeleteEvent.php | 2 +- hwe/sammo/Event/Action/RaiseInvader.php | 218 ++++++++++++++----- hwe/sammo/Event/Action/RegNPC.php | 2 +- hwe/sammo/Event/Action/RegNeutralNPC.php | 2 +- 9 files changed, 211 insertions(+), 61 deletions(-) create mode 100644 hwe/sammo/Event/Action/AutoDeleteInvader.php diff --git a/hwe/sammo/Event/Action.php b/hwe/sammo/Event/Action.php index 5d242c76..0a63117a 100644 --- a/hwe/sammo/Event/Action.php +++ b/hwe/sammo/Event/Action.php @@ -3,7 +3,7 @@ namespace sammo\Event; abstract class Action{ //public abstract function __construct(...$args); - public abstract function run($env); + public abstract function run(array $env); public static function build($actionArgs):Action{ if(!is_array($actionArgs)){ diff --git a/hwe/sammo/Event/Action/AutoDeleteInvader.php b/hwe/sammo/Event/Action/AutoDeleteInvader.php new file mode 100644 index 00000000..67ef4b2f --- /dev/null +++ b/hwe/sammo/Event/Action/AutoDeleteInvader.php @@ -0,0 +1,40 @@ +nationID = $nationID; + } + + public function run(array $env){ + if(getNationStaticInfo($this->nationID)===null){ + return [__CLASS__, "Not Exists"]; + } + $db = DB::db(); + $onWar = $db->queryFirstField('SELECT count(*) FROM diplomacy WHERE me = %i AND state IN %li', $this->nationID, [0, 1]); + if($onWar){ + return [__CLASS__, "On War"]; + } + + $rulerID = $db->queryFirstField('SELECT no FROM general WHERE nation = %i AND officer_level = 12', $this->nationID); + $db->update('general_turn', [ + 'action'=>'che_방랑', + 'arg'=>'[]', + 'brief'=>"이민족 방랑" + ], 'general_id = %i', $rulerID); + $db->update('general', [ + 'killturn'=>5 + ], 'nation = %i', $this->nationID); + + $eventID = Util::array_get($env['currentEventID']); + $db->delete('event', 'id = %i', $eventID); + + return [__CLASS__, 'Deleted']; + } + +} \ No newline at end of file diff --git a/hwe/sammo/Event/Action/ChangeCity.php b/hwe/sammo/Event/Action/ChangeCity.php index 34b67913..029503e0 100644 --- a/hwe/sammo/Event/Action/ChangeCity.php +++ b/hwe/sammo/Event/Action/ChangeCity.php @@ -161,7 +161,7 @@ class ChangeCity extends \sammo\Event\Action{ throw new \InvalidArgumentException('올바르지 않은 cond 입니다.'); } - public function run($env=null){ + public function run(array $env){ $cities = $this->getTargetCities($env); DB::db()->update('city', diff --git a/hwe/sammo/Event/Action/CreateAdminNPC.php b/hwe/sammo/Event/Action/CreateAdminNPC.php index 176dce6a..b65005a8 100644 --- a/hwe/sammo/Event/Action/CreateAdminNPC.php +++ b/hwe/sammo/Event/Action/CreateAdminNPC.php @@ -7,7 +7,7 @@ class CreateAdminNPC extends \sammo\Event\Action{ } - public function run($env=null){ + public function run(array $env){ return [__CLASS__, 'NYI']; } diff --git a/hwe/sammo/Event/Action/CreateManyNPC.php b/hwe/sammo/Event/Action/CreateManyNPC.php index b9ce5da8..9a686ac1 100644 --- a/hwe/sammo/Event/Action/CreateManyNPC.php +++ b/hwe/sammo/Event/Action/CreateManyNPC.php @@ -43,7 +43,7 @@ class CreateManyNPC extends \sammo\Event\Action{ } - public function run($env=null){ + public function run(array $env){ if($this->npcCount <= 0){ return [__CLASS__, []]; } diff --git a/hwe/sammo/Event/Action/DeleteEvent.php b/hwe/sammo/Event/Action/DeleteEvent.php index a6cc98bf..7534f038 100644 --- a/hwe/sammo/Event/Action/DeleteEvent.php +++ b/hwe/sammo/Event/Action/DeleteEvent.php @@ -7,7 +7,7 @@ class DeleteEvent extends \sammo\Event\Action{ public function __construct(){ } - public function run($env=null){ + public function run(array $env){ $eventID = \sammo\Util::array_get($env['currentEventID']); if(!$eventID){ diff --git a/hwe/sammo/Event/Action/RaiseInvader.php b/hwe/sammo/Event/Action/RaiseInvader.php index 0231f663..216eea5c 100644 --- a/hwe/sammo/Event/Action/RaiseInvader.php +++ b/hwe/sammo/Event/Action/RaiseInvader.php @@ -1,116 +1,226 @@ 63, - '저'=>64, - '흉노'=>65, - '남만'=>66, - '산월'=>67, - '오환'=>68, - '왜'=>69 - ]; - public function __construct( $npcEachCount = -0.5, - int $specAvg = 150, - int $specDist = 20, + int $specAvg = 50, int $tech = -1, - int $dex = 0 - ){ + $dex = -0.01 + ) { $this->npcEachCount = $npcEachCount; $this->specAvg = $specAvg; - $this->specDist = $specDist; $this->tech = $tech; $this->dex = $dex; - - if($specDist < 0){ - throw new \InvalidArgumentException('specDist는 음수를 지원하지 않습니다.'); - } } - private function moveCapital(){ - $cities = array_map(function ($value) { - return $value; - }, static::INVADER_LIST); + private function moveCapital() + { + $cities = []; + foreach (CityConst::all() as $cityObj) { + if ($cityObj->level != 4) { + continue; + } + $cities[] = $cityObj->id; + } + + if (count($cities) == 0) { + return [__CLASS__, 0]; + } $db = DB::db(); - foreach($db->queryFirstColumn('SELECT capital, nation from nation WHERE capital in %li', $cities) as $row){ + foreach ($db->queryFirstColumn('SELECT capital, nation from nation WHERE capital in %li', $cities) as $row) { list($oldCapital, $nation) = $row; $newCapital = $db->queryFirstRow('SELECT city from city where nation=%i and city !=%i \ order by rand() limit 1', $nation, $oldCapital); - $db->update('nation', ['capital'=>$newCapital], 'nation=%i', $nation); + $db->update('nation', ['capital' => $newCapital], 'nation=%i', $nation); - $db->update('general', ['city'=>$newCapital], 'nation=%i and city=%i', $nation, $oldCapital); + $db->update('general', ['city' => $newCapital], 'nation=%i and city=%i', $nation, $oldCapital); } $db->update('general', [ - 'officer_level'=>1, - 'officer_city'=>0 + 'officer_level' => 1, + 'officer_city' => 0 ], 'officer_city in %li', $cities); $db->update('city', [ - 'nation'=>0 + 'nation' => 0, + 'front'=>0, + 'supply'=>1, ], 'city in %li', $cities); } - public function run($env=null){ + public function run(array $env) + { $db = DB::db(); $npcEachCount = $this->npcEachCount; - if($npcEachCount < 0){ - $npcEachCount = - $db->queryFirstField('SELECT count(no) from general where npc < 9') / count(self::INVADER_LIST); - $npcEachCount /= -1 * $this->npcEachCount; + /** @var \sammo\CityInitDetail[] */ + $cities = []; + foreach (CityConst::all() as $cityObj) { + if ($cityObj->level != 4) { + continue; + } + $cities[] = $cityObj; } + if ($npcEachCount < 0) { + $npcEachCount = + $db->queryFirstField('SELECT count(no) from general where npc < 5') / count($cities); + $npcEachCount *= -1 * $this->npcEachCount; + } + $npcEachCount = max(10, Util::toInt($npcEachCount)); + $specAvg = $this->specAvg; - if($specAvg < 0){ - $specAvg = $db->queryFirstField('SELECT avg(sum(`leadership` + `strength` + `intel`)) from general where npc < 9'); - $specAvg /= -1 * $this->specAvg; + if ($specAvg < 0) { + $specAvg = $db->queryFirstField('SELECT avg(sum(`leadership` + `strength` + `intel`)) from general where npc < 5'); + $specAvg *= -1 * $this->specAvg; } + $specAvg = Util::toInt($specAvg); $tech = $this->tech; - if($tech < 0){ + if ($tech < 0) { $tech = $db->queryFirstField("SELECT avg(tech) from nation where `level`>0"); - $tech /= -1 * $this->tech; + $tech *= -1 * $this->tech; } $dex = $this->dex; - if($dex < 0){ + if ($dex < 0) { $dex = $db->queryFirstField("SELECT avg(dex1 + dex2 + dex3 + dex4 + dex5)/5 from nation where `level`>0"); - $dex /= -1 * $this->dex; + $dex *= -1 * $this->dex; } + $dex = Util::toInt($dex); $this->moveCapital(); - //TODO:국가를 만들고 - //TODO:장수를 세팅하고 - //TODO:외교를 설정한다. + $serverID = UniqueConst::$serverID; + $existNations = $db->queryFirstColumn("SELECT nation FROM `nation`"); + $lastNationID = max( + max($existNations), + $db->queryFirstField("SELECT max(`nation`) FROM `ng_old_nations` WHERE server_id = %s", $serverID), + ); - //TODO: 시나리오 구현 후 마무리. - //TODO: 임관 모드가 '랜임모드'인 경우 오랑캐와 충돌하므로 해제해야함. - return [__CLASS__, 'NYI']; + $db->update('general', [ + 'gold' => 999999, + 'rice' => 999999, + ], true); + + $year = $env['year']; + + $invaderNationIDList = []; + + foreach ($cities as $cityObj) { + if ($cityObj->level != 4) { + continue; + } + + $lastNationID += 1; + $invaderNationID = $lastNationID; + $invaderNationIDList[] = $invaderNationID; + + $invaderName = $cityObj->name; + $nationName = "ⓞ{$invaderName}족"; + $cityID = $cityObj->id; + $nationObj = new Nation($invaderNationID, $nationName, '#800080', 9999999, 9999999, "중원의 부패를 물리쳐라! 이민족 침범!", $tech, "che_병가", 1, [$cityID]); + $nationObj->addGeneral((new GeneralBuilder("{$invaderName}대왕", false, null, $lastNationID)) + ->setEgo('che_패권') + ->setSpecial('che_인덕', 'che_척사') + ->setLifeSpan($year - 20, $year + 20) + ->setNPCType(9) + ->setStat(Util::toInt($specAvg * 1.8), Util::toInt($specAvg * 1.8), Util::toInt($specAvg * 1.2)) + ->setAffinity(999) + ->setGoldRice(99999, 99999) + ); + + foreach (Util::range(1, $npcEachCount) as $invaderGenIdx) { + $gen = (new GeneralBuilder("{$invaderName}장수{$invaderGenIdx}", false, null, $invaderNationID)) + ->setEgo('che_패권') + ->setSpecial('che_인덕', 'che_척사') + ->setLifeSpan($year - 20, $year + 20) + ->setNPCType(9) + ->setAffinity(999) + ->setGoldRice(99999, 99999); + + $leadership = Util::randRangeInt(Util::toInt($specAvg * 1.2), Util::toInt($specAvg * 1.4)); + $mainStat = Util::randRangeInt(Util::toInt($specAvg * 1.2), Util::toInt($specAvg * 1.4)); + $subStat = $specAvg * 3 - $leadership - $mainStat; + + if (Util::randBool()) { + //무장 + $dexTable = [$dex * 2, $dex, $dex]; + shuffle($dexTable); + $gen->setStat($leadership, $mainStat, $subStat) + ->setDex($dexTable[0], $dexTable[1], $dexTable[2], $dex, 0); + } else { + //지장 + $gen->setStat($leadership, $subStat, $mainStat) + ->setDex($dex, $dex, $dex, $dex * 2, 0); + } + $nationObj->addGeneral($gen); + } + + $nationObj->build($env); + $nationObj->postBuild($env); + $db->insert('event', [ + 'condition'=>Json::encode(true), + 'action'=>Json::encode(["AutoDeleteInvader", $invaderNationID]), + ]); + } + + $db->update('nation', [ + 'scout' => 1 + ], 'nation IN %li', $invaderNationIDList); + $db->update('diplomacy', [ + 'state' => 1, + 'term' => 24, + ], '(me IN %li AND you IN %li) OR (me IN %li AND you IN %li)', $existNations, $invaderNationIDList, $invaderNationIDList, $existNations); + + $cityMaxPop = $specAvg*$npcEachCount*100; + $db->update('city', [ + 'pop_max'=>$cityMaxPop, + 'def_max'=>10000, + 'wall_max'=>1000, + ], 'nation IN %li', $invaderNationIDList); + + $db->update('city', [ + 'pop'=>$db->sqleval('pop_max'), + 'secu'=>$db->sqleval('secu_max'), + 'def'=>$db->sqleval('def_max'), + 'wall'=>$db->sqleval('wall_max'), + ], true); + + $gameStor = KVStorage::getStorage($db, 'game_env'); + $gameStor->isunited = 1; + + return [__CLASS__, count($invaderNationIDList)]; } -} \ No newline at end of file +} diff --git a/hwe/sammo/Event/Action/RegNPC.php b/hwe/sammo/Event/Action/RegNPC.php index 29eb7fda..bc32fbba 100644 --- a/hwe/sammo/Event/Action/RegNPC.php +++ b/hwe/sammo/Event/Action/RegNPC.php @@ -39,7 +39,7 @@ class RegNPC extends \sammo\Event\Action{ ->setLifeSpan($birth, $death); } - public function run($env){ + public function run(array $env){ $result = $this->npc->fillRemainSpecAsZero($env)->build($env); return [__CLASS__, $result]; } diff --git a/hwe/sammo/Event/Action/RegNeutralNPC.php b/hwe/sammo/Event/Action/RegNeutralNPC.php index fe0ecbd5..d0b7b086 100644 --- a/hwe/sammo/Event/Action/RegNeutralNPC.php +++ b/hwe/sammo/Event/Action/RegNeutralNPC.php @@ -37,7 +37,7 @@ class RegNeutralNPC extends \sammo\Event\Action{ ->setNPCType(6); } - public function run($env=null){ + public function run(array $env){ $result = $this->npc->fillRemainSpecAsZero($env)->build($env); return [__CLASS__, $result]; }