diff --git a/hwe/func.php b/hwe/func.php index 2804ad04..4f137c57 100644 --- a/hwe/func.php +++ b/hwe/func.php @@ -2576,15 +2576,23 @@ function searchDistance(int $from, int $maxDist=99, bool $distForm = false) { } } -function isClose($nation1, $nation2) { +function isClose(int $nation1, int $nation2, bool $includeNoSupply=true) { $db = DB::db(); $nation1Cities = []; - foreach($db->queryFirstColumn('SELECT city FROM city WHERE nation = %i', $nation1) as $city){ + + if($includeNoSupply){ + $supplySql = ''; + } + else{ + $supplySql = 'AND supply = 1'; + } + + foreach($db->queryFirstColumn('SELECT city FROM city WHERE nation = %i %l', $nation1, $supplySql) as $city){ $nation1Cities[$city] = $city; } - foreach($db->queryFirstColumn('SELECT city FROM city WHERE nation = %i', $nation2) as $city){ + foreach($db->queryFirstColumn('SELECT city FROM city WHERE nation = %i %l', $nation2, $supplySql) as $city){ foreach(array_keys(CityConst::byID($city)->path) as $adjCity){ if(key_exists($adjCity, $nation1Cities)){ return true; diff --git a/hwe/sammo/DiplomacticMessage.php b/hwe/sammo/DiplomacticMessage.php index 330e0c7f..1e62435b 100644 --- a/hwe/sammo/DiplomacticMessage.php +++ b/hwe/sammo/DiplomacticMessage.php @@ -64,9 +64,7 @@ class DiplomacticMessage extends Message{ return [self::INVALID, '송신자가 외교서신을 처리할 수 없습니다.']; } - - - if($general === null || $general['level'] < 5){ + if(!$general || $general['level'] < 5){ return [self::INVALID, '해당 국가의 수뇌가 아닙니다.']; } @@ -92,15 +90,26 @@ class DiplomacticMessage extends Message{ list($result, $reason) = $this->checkDiplomaticMessageValidation($general); - $helper = new Engine\Diplomacy($this->src->nationID); + $helper = new Engine\Diplomacy($this->src->nationID, $this->dest->nationID); switch($this->diplomaticType){ - case self::TYPE_NO_AGGRESSION: break; - case self::TYPE_CANCEL_NA: break; - case self::TYPE_STOP_WAR: break; - case self::TYPE_MERGE: break; - case self::TYPE_SURRENDER: break; - default: throw \RuntimeException('diplomaticType이 올바르지 않음'); + case self::TYPE_NO_AGGRESSION: + list($result, $reason) = $helper->noAggression(); + break; + case self::TYPE_CANCEL_NA: + list($result, $reason) = $helper->cancelNA(); + break; + case self::TYPE_STOP_WAR: + list($result, $reason) = $helper->stopWar(); + break; + case self::TYPE_MERGE: + list($result, $reason) = $helper->acceptMerge(); + break; + case self::TYPE_SURRENDER: + list($result, $reason) = $helper->acceptSurrender(); + break; + default: + throw \RuntimeException('diplomaticType이 올바르지 않음'); } @@ -112,17 +121,7 @@ class DiplomacticMessage extends Message{ return $result; } - //방랑군이 아니어야함 - //상대도 방랑군이 아니어야함 - //불가침시 : 교전중이 아니어야함, 선포중이 아니어야함. 합병중이 아니어얗. - //불가침 파기시 : 불가침 중이어야함. - //종전시 : 교전중이거나 선포중이어야함. - //합병시 : 양국 다 외교제한이 지나지 않았어야함. 국력, 장수수가 적절해야함. 인접한 국가여야함. 서로 교전중이어선 안됨. - // 송신자가 선포, 전쟁중이어선 안됨. 송신자가 C국과 불가침인데 수신자가 C국과 전쟁중이면 안됨 - //항복시 : 양국 다 외교제한이 지나지 않았어야함. 국력, 장수수가 적절해야함. 인접한 국가여야함. 서로 교전중이어선 안됨. - // 송신자가 선포, 전쟁중이어선 안됨. 송신자가 C국과 불가침인데 수신자가 C국과 전쟁중이면 안됨 - list( $year, $month diff --git a/hwe/sammo/Engine/Diplomacy.php b/hwe/sammo/Engine/Diplomacy.php index 9e0c7b0b..c4a4b8b9 100644 --- a/hwe/sammo/Engine/Diplomacy.php +++ b/hwe/sammo/Engine/Diplomacy.php @@ -1,28 +1,56 @@ queryFirstRow( - 'SELECT nation, `name`, capital, gold, rice, surlimit, color FROM nation WHERE nation=%i', - $nationID - ); - - if(!$nation){ + public function __construct(int $srcNationID, int $destNationID){ + if($srcNationID === $destNationID){ return; } - $this->nation = $nation; + $db = DB::db(); + $srcNation = $db->queryFirstRow( + 'SELECT nation, `name`, capital, gold, rice, surlimit, color, `level` FROM nation WHERE nation=%i', + $srcNationID + ); + + $destNation = $db->queryFirstRow( + 'SELECT nation, `name`, capital, gold, rice, surlimit, color, `level` FROM nation WHERE nation=%i', + $destNationID + ); + + if(!$srcNation || !$destNation){ + return; + } + + $this->srcToDestDiplomacy = $db->queryFirstRow( + 'SELECT * FROM diplomacy WHERE me = %i AND you = %i', + $srcNationID, + $destNationID + ); + + $this->destToSrcDiplomacy = $db->queryFirstRow( + 'SELECT * FROM diplomacy WHERE me = %i AND you = %i', + $destNationID, + $srcNationID + ); + + $this->srcNation = $srcNation; + $this->destNation = $destNation; $this->valid = true; list( @@ -33,11 +61,145 @@ class Diplomacy{ } - public function ally(int $destNation){ + //방랑군이 아니어야함 + //상대도 방랑군이 아니어야함 + + //불가침시 : 교전중이 아니어야함, 선포중이 아니어야함. (서로) 합병중이 아니어얗. + //불가침 파기시 : 불가침 중이어야함. + //종전시 : 교전중이거나 선포중이어야함. + //합병시 : 양국 다 외교제한이 지나지 않았어야함. 국력, 장수수가 적절해야함. 인접한 국가여야함. 서로 교전중이어선 안됨. + // 송신자가 선포, 전쟁중이어선 안됨. 송신자가 C국과 불가침인데 수신자가 C국과 전쟁중이면 안됨 + //항복시 : 양국 다 외교제한이 지나지 않았어야함. 국력, 장수수가 적절해야함. 인접한 국가여야함. 서로 교전중이어선 안됨. + // 송신자가 선포, 전쟁중이어선 안됨. 송신자가 C국과 불가침인데 수신자가 C국과 전쟁중이면 안됨 + + protected function checkValidNation(array $prev = [DiplomacticMessage::ACCEPTED, '']){ + if($prev[0] !== DiplomacticMessage::ACCEPTED){ + return $prev; + } + + if(!$this->srcNation || !$this->destNation || !$this->valid){ + return [ScoutMessage::DECLINED, '이미 멸망한 국가입니다.']; + } + + if($this->srcNation['level'] == 0 || $this->destNation['level'] == 0){ + return [DiplomacticMessage::DECLINED, '방랑군과 외교룰 수행할 수 없습니다.']; + } + + return $prev; + } + + protected function checkNotWar(array $prev = [DiplomacticMessage::ACCEPTED, '']){ + if($prev[0] !== DiplomacticMessage::ACCEPTED){ + return $prev; + } + + if($this->srcToDestDiplomacy['state'] == 0 || $this->srcToDestDiplomacy['state'] == 0 + ||$this->destToSrcDiplomacy['state'] == 1 || $this->destToSrcDiplomacy['state'] == 1){ + return [DiplomacticMessage::DECLINED, '상대국과 선포, 전쟁 중입니다.']; + } + + return $prev; + } + + protected function checkInWar(array $prev = [DiplomacticMessage::ACCEPTED, '']){ + if($prev[0] !== DiplomacticMessage::ACCEPTED){ + return $prev; + } + + if($this->srcToDestDiplomacy['state'] == 0 || $this->srcToDestDiplomacy['state'] == 0 + ||$this->destToSrcDiplomacy['state'] == 1 || $this->destToSrcDiplomacy['state'] == 1){ + return $prev; + } + + return [DiplomacticMessage::DECLINED, '상대국과 선포, 전쟁 중이 아닙니다.']; + } + + protected function checkDiplomacyLimit(array $prev = [DiplomacticMessage::ACCEPTED, '']){ + if($prev[0] !== DiplomacticMessage::ACCEPTED){ + return $prev; + } + + if($this->destNation['surlimit'] > 0){ + return [DiplomacticMessage::DECLINED, '본국의 외교 기한이 남아있습니다.']; + } + + if($this->srcNation['surlimit'] > 0){ + return [DiplomacticMessage::DECLINED, '상대국의 외교 기한이 남아있습니다.']; + } + + return $prev; + } + + protected function checkStrictlyAdjacent(array $prev = [DiplomacticMessage::ACCEPTED, '']){ + if($prev[0] !== DiplomacticMessage::ACCEPTED){ + return $prev; + } + + if(!\sammo\isClose($this->srcNation['nation'], $this->destNation['nation'], false)){ + return [DiplomacticMessage::DECLINED, '상대국의 도시들과 보급선이 이어지지 않았습니다.']; + } + + return $prev; + } + + protected function checkAdjacent(array $prev = [DiplomacticMessage::ACCEPTED, '']){ + if($prev[0] !== DiplomacticMessage::ACCEPTED){ + return $prev; + } + + if(!\sammo\isClose($this->srcNation['nation'], $this->destNation['nation'], true)){ + return [DiplomacticMessage::DECLINED, '상대국의 도시와 인접하지 않았습니다.']; + } + + return $prev; + } + + protected function checkAlreadyMerging(array $prev = [DiplomacticMessage::ACCEPTED, '']){ + if($prev[0] !== DiplomacticMessage::ACCEPTED){ + return $prev; + } + + if((3 <= $this->srcToDestDiplomacy['state'] && $this->srcToDestDiplomacy['state'] <= 6) + ||(3 <= $this->destToSrcDiplomacy['state'] && $this->destToSrcDiplomacy['state'] <= 6)){ + return [DiplomacticMessage::DECLINED, '상대국과 합병 중입니다.']; + } + + return $prev; + } + + protected function checkSrcNationHasNeutralDiplomacy(array $prev = [DiplomacticMessage::ACCEPTED, '']){ + if($prev[0] !== DiplomacticMessage::ACCEPTED){ + return $prev; + } + + if(false){ + return [DiplomacticMessage::DECLINED, '상대국이 전쟁 중입니다.']; + } + + if(false){ + return [DiplomacticMessage::DECLINED, '상대국이 합병 중입니다.']; + } + + return $prev; + } + + protected function checkContradictoryDiplomacy(array $prev = [DiplomacticMessage::ACCEPTED, '']){ + if($prev[0] !== DiplomacticMessage::ACCEPTED){ + return $prev; + } + + if(false){ + return [DiplomacticMessage::DECLINED, '상대국이 본국의 교전국과 불가침중입니다.']; + } + + return $prev; + } + + public function noAggression(int $destNation){ } - public function cancelAlly(int $destNation){ + public function cancelNA(int $destNation){ }