From ea5a25a67169b96b78b79e0023274e94b663394d Mon Sep 17 00:00:00 2001 From: hide_d Date: Mon, 13 Aug 2018 00:45:11 +0900 Subject: [PATCH] =?UTF-8?q?=EC=A0=84=ED=88=AC=20=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EC=9E=91=EC=84=B1=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 전투 코드 추가 준비 추가 구현 --- hwe/process_war.ng.php | 136 ++++++++++++++++++++++++---- hwe/process_war.php | 2 +- hwe/sammo/WarUnit.php | 139 ++++++++++++++++++++++++---- hwe/sammo/WarUnitCity.php | 136 ++++++++++++++++++++++++++++ hwe/sammo/WarUnitGeneral.php | 169 +++++++++++++++++++++++++++++++++++ 5 files changed, 550 insertions(+), 32 deletions(-) create mode 100644 hwe/sammo/WarUnitCity.php create mode 100644 hwe/sammo/WarUnitGeneral.php diff --git a/hwe/process_war.ng.php b/hwe/process_war.ng.php index a39bfe5a..9d1484ab 100644 --- a/hwe/process_war.ng.php +++ b/hwe/process_war.ng.php @@ -3,28 +3,132 @@ namespace sammo; function processWar_NG( - $rawGeneral, - callable $getNextTarget, - int $city, - string $time -){ + array $rawAttacker, + array $rawAttackerCity, + array $rawAttackerNation, + callable $getNextDefender, + array $rawDefendercity, + array $rawDefenderNation, + string $time, + array $env +):array{ $templates = new \League\Plates\Engine(__dir__.'/templates'); - $db = DB::db(); - $gameStor = KVStorage::getStorage($db, 'game_env'); + $year = $env['year']; + $month = $env['month']; - $admin = $gameStor->getAll(); - //year, month + $attacker = new WarUnitGeneral($rawAttacker, $rawAttackerCity, $rawAttackerNation, true, $year, $month); + $logger = $attacker->getLogger(); - $year = $admin['year']; - $month = $admin['month']; + $attacker->useBattleInitItem(); + + $attackerNationUpdate = []; + $defenderNationUpdate = []; + + $city = new WarUnitCity($rawDefendercity, $rawDefenderNation, $year, $month); + + $maxPhase = $attacker->getMaxPhase(); + + $defender = ($getNextDefender)(null); + $conquerCity = false; + + $josaRo = JosaUtil::pick($city->name, '로'); + $josaYi = JosaUtil::pick($attacker->name, '이'); + $logger->pushGlobalActionLog("{$rawAttackerNation['name']}{$attacker->name}{$josaYi} {$city->name}{$josaRo} 진격합니다."); + $logger->pushGeneralActionLog("{$city->name}{$josaRo} 진격합니다. <1>$date"); + + for($currPhase = 0; $currPhase <= $maxPhase; $currPhase+=1){ + if($defender !== null && $defender->getPhase() == 0){ + $defender->setPrePhase($currPhase); + + $attacker->addTrain(1); + $defender->addTrain(1); + + $josaWa = JosaUtil::pick($attacker->getCrewType()->name, '와'); + $josaYi = JosaUtil::pick($defender->getCrewType()->name, '이'); + $logger->pushGlobalActionLog("{$attacker->getName()}의 {$attacker->getCrewType()->name}{$josaWa} {$defender->getName()}의 {$defender->getCrewType()->name}{$josaYi} 대결합니다."); + $josaUl = JosaUtil::pick($defender->getCrewType()->name, '을'); + $josaRo = JosaUtil::pick($attacker->getCrewType()->name, '로'); + $attacker->getLogger()->pushGeneralActionLog("{$attacker->getCrewType()->name}{$josaRo} {$defender->name}의 {$defender->getCrewType()->name}{$josaUl} 공격합니다."); + $defender->getLogger()->pushGeneralActionLog("{$defender->getCrewType()->name}{$josaRo} {$attacker->name}의 {$attacker->getCrewType()->name}{$josaUl} 수비합니다."); + + $defender->useBattleInitItem(); + + $attacker->setOppose($defender); + $defender->setOppose($attacker); + + $attacker->useActiveItem(); + $defender->useActiveItem(); + //TODO: 수극 류 아이템 사용 + } + else if($defender === null && $rawDefenderNation['rice'] > 0){ + $defender = $city; + + $defender->setPrePhase($currPhase); + + $josaYi = JosaUtil::pick($attacker->getName(), '이'); + $josaRo = JosaUtil::pick($attacker->getCrewType()->name, '로'); + $logger->pushGlobalActionLog("{$attacker->getName()}{$josaYi} {$attacker->getCrewType()->name}{$josaRo} 성벽을 공격합니다."); + $logger->pushGeneralActionLog("●{$generalCrewType->name}{$josaRo} 성벽을 공격합니다.", ActionLogger::PLAIN); + + $defender->useBattleInitItem(); + + $attacker->setOppose($defender); + $defender->setOppose($attacker); + } + else if($defender === null){ + $defender = $city; + $conquerCity = true; + //TODO: 병량 패퇴를 여기에 넣어야 하는가? + break; + } + + $attacker->computeWarPower(); + $defender->computeWarPower(); + + + //TODO: 1합씩 공격(마법도 여기에서) + + //TODO: 쌀 소모 반영 + + //TODO: 전투 로그 기록(여기서??) + + $attacker->addPhase(); + if($defender->continueWar($noRice)){ + $defender->addPhase(); + } + else{ + if($defender === $city){ + $conquerCity = true; + break; + } + + $josaYi = JosaUtil::pick($defender->getCrewType()->name, '이'); + $logger->pushGeneralActionLog("{$defender->getName()}의 {$defender->getCrewType()->name}{$josaYi} 퇴각했습니다."); + + $defender = ($getNextDefender)($defender); + if($defender === null){ + continue; + } + if(!($defender instanceof WarUnitGeneral)){ + throw new \RuntimeException('다음 수비자를 받아오는데 실패'); + } + + } + + } + + //TODO: 전투 종료 + + if($conquerCity){ + //TODO: 도시 정복 처리 + } + + //TODO: 공격자 경험치? (여기서?) + + //TODO: DB 처리를 위한 반영 - $attacker = new WarUnit($rawGeneral['no'], $rawGeneral['nation'], $year, $month); - $deadAmount = [ - 'att'=>0, - 'def'=>0 - ]; } diff --git a/hwe/process_war.php b/hwe/process_war.php index 80826e7d..a4c3a2fd 100644 --- a/hwe/process_war.php +++ b/hwe/process_war.php @@ -45,7 +45,7 @@ function processWar($general, $city) { $genAtmos += 3; $query = "update general set item=0 where no='{$general['no']}'"; MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); - $josaUl = JosaUtil::pick($general['item'], '을'); + $josaUl = JosaUtil::pick(getItemName($general['item']), '을'); $log[] = "".getItemName($general['item'])."{$josaUl} 사용!"; $general['item'] = 0; } elseif($general['item'] >= 14 && $general['item'] <= 16) { diff --git a/hwe/sammo/WarUnit.php b/hwe/sammo/WarUnit.php index 69672c15..ef9fb1ee 100644 --- a/hwe/sammo/WarUnit.php +++ b/hwe/sammo/WarUnit.php @@ -2,22 +2,50 @@ namespace sammo; class WarUnit{ - protected $rawGeneral; + protected $rawNation; + protected $logger; protected $crewType; protected $killed = 0; protected $death = 0; + protected $isAttacker = false; + protected $updatedVar = []; + protected $genAtmos = 0; + protected $genTrain = 0; - function __construct($rawGeneral, $year, $month){ - $this->rawGeneral = $rawGeneral; - $this->logger = new ActionLogger($rawGeneral['no'], $rawGeneral['nation'], $year, $month); - $this->crewType = GameUnitConst::byID($rawGeneral['crewtype']); + protected $currPhase = 0; + protected $prePhase = 0; + + protected $oppose; + protected $warPower; + + private function __construct(){ } + function getRaw():array{ + return []; + } + + function getRawNation():array{ + return $this->rawNation; + } + + function getPhase():int{ + return $this->currPhase; + } + + function getRealPhase():int{ + return $this->prePhase + $this->currPhase; + } + + function getName():string{ + return 'EMPTY'; + } + function getCrewType():GameUnitConst{ return $this->crewType; } @@ -27,31 +55,112 @@ class WarUnit{ } function getSpecialDomestic():int{ - return $this->rawGeneral['special']; + return 0; } function getSpecialWar():int{ - return $this->rawGeneral['special2']; + return 0; } function getItem():int{ - return $this->rawGeneral['item']; + return 0; } function getMaxPhase():int{ - $phase = $this->getCrewType()->speed; - if($this->getSpecialWar() == 60){ - $phase += 1; - } - return $phase; + return 1; } - function doUseBattleInitItem():bool{ - $item = $this->getItem(); + function setPrePhase(int $phase){ + $this->prePhase = $phase; + } + function addPhase(){ + $this->currPhase += 1; + } + + function setOppose(WarUnit $oppose){ + $this->oppose = $oppose; } + function computeWarPower(){ + $oppose = $this->oppose; + + $myAtt = $this->getCrewType()->getComputedAttack($this->getRaw(), $this->getRawNation()['tech']); + $opDef = $oppose->getCrewType()->getComputedDefence($oppose->getRaw(), $oppose->getRawNation()['tech']); + // 감소할 병사 수 + $warPower = GameConst::$armperphase + $myAtt - $opDef; + if($warPower <= 0){ + //FIXME: 0으로 잡을때 90~100이면, 1은 너무 억울하지 않나? + $warPower = rand(90, 100); + } + + $warPower = getCrew( + $warPower, + CharAtmos( + $this->getComputedAtmos(), + $this->getCharacter() + ), + CharTrain( + $oppose->getComputedTrain(), + $oppose->getCharacter() + ) + ); + + $genDexAtt = getGenDex($this->getRaw(), $this->getCrewType()->id); + $oppDexDef = getGenDex($oppose->getRaw(), $this->getCrewType()->id); + $warPower *= getDexLog($genDexAtt, $oppDexDef); + $warPower *= $this->getCrewType()->getAttackCoef($oppose->getCrewType()); + //FIXME : 이대로면 서로의 '공격력'만 반영됨 getDefenceCoef는 어따씀? + + //TODO:관직 보정 (상속받은 쪽에서..?) + //TODO:레벨 보정 (상속받은 쪽에서..?) + //TODO:특기 보정 (상속받은 쪽에서..?) + $this->warPower = $warPower; + return $warPower; + } + + function addTrain(int $train){ + return; + } + + function addAtmos(int $atmos){ + return; + } + + function getComputedTrain(){ + //TODO: 나머지에 구현 + return 100; + } + + function getComputeAtmos(){ + //TODO: 나머지에 구현 + return 100; + } + + function getCharacter(){ + //TODO: 나머지에 구현 + return 0; + } + + function useBattleInitItem():bool{ + return false; + } + + function useActiveItem():bool{ + return false; + } + + function decreaseHP(int $damage):int{ + return false; + } + + function continueWar(&$noRice):bool{ + //전투가 가능하면 true + $noRice = false; + return false; + } + diff --git a/hwe/sammo/WarUnitCity.php b/hwe/sammo/WarUnitCity.php new file mode 100644 index 00000000..82809eca --- /dev/null +++ b/hwe/sammo/WarUnitCity.php @@ -0,0 +1,136 @@ +raw = $raw; + $this->rawNation = $rawNation; + $this->isAttacker = false; + + $this->logger = new ActionLogger(0, $raw['nation'], $year, $month); + $this->crewType = GameUnitConst::byID($raw['crewtype']); + + $this->def = $raw['def'] * 10; + $this->wall = $raw['wall'] * 10; + $this->rice = $rawNation['rice']; + + $this->crewType = GameUnitConst::byID(GameUnitConst::T_CASTLE); + } + + function getRaw():array{ + return $this->raw; + } + + function getName():string{ + return $this->raw['name']; + } + + function getCrewType():GameUnitConst{ + return $this->crewType; + } + + function getLogger():ActionLogger{ + return $this->logger; + } + + function getSpecialDomestic():int{ + return $this->raw['special']; + } + + function getSpecialWar():int{ + return $this->raw['special2']; + } + + function getItem():int{ + return $this->raw['item']; + } + + function getMaxPhase():int{ + $phase = $this->getCrewType()->speed; + if($this->getSpecialWar() == 60){ + $phase += 1; + } + return $phase; + } + + function useBattleInitItem():bool{ + $item = $this->getItem(); + + if($item == 0){ + return false; + } + + $itemActivated = false; + $itemConsumed = false; + $itemName = getItemName($item); + + if($item == 3){ + //탁주 사용 + $this->genAtmos += 3; + $itemActivated = true; + $itemConsumed = true; + } + else if($item >= 14 && $item <= 16){ + //의적주, 두강주, 보령압주 사용 + $this->genAtmos += 5; + $itemActivated = true; + } + else if($item >= 19 && $item <= 20){ + //춘화첩, 초선화 사용 + $this->genAtmos += 7; + $itemActivated = true; + } + else if($item == 4){ + //청주 사용 + $this->genTrain += 3; + $itemActivated = true; + $itemConsumed = true; + } + else if($item >= 12 && $item <= 13){ + //과실주, 이강주 사용 + $this->genTrain += 5; + $itemActivated = true; + } + else if($item >= 18 && $item <= 18){ + //철벽서, 단결도 사용 + $this->genTrain += 7; + $itemActivated = true; + } + + if($itemConsumed){ + $this->raw['item'] = 0; + $this->updatedVar['item'] = true; + $josaUl = JosaUtil::pick($itemName, '을'); + $this->getLogger()->generalActionLog("{$itemName}{$josaUl} 사용!"); + } + + return $itemActivated; + } + + function continueWar(&$noRice):bool{ + //전투가 가능하면 true + $noRice = false; + if($this->def <= 0){ + return false; + } + + //도시 성벽은 쌀이 소모된다고 항복하지 않음 + return true; + } + +} \ No newline at end of file diff --git a/hwe/sammo/WarUnitGeneral.php b/hwe/sammo/WarUnitGeneral.php new file mode 100644 index 00000000..0d49fab4 --- /dev/null +++ b/hwe/sammo/WarUnitGeneral.php @@ -0,0 +1,169 @@ +raw = $raw; + $this->rawCity = $rawCity; + $this->rawNation = $rawNation; + $this->isAttacker = $isAttacker; + + $this->logger = new ActionLogger($this->raw['no'], $this->raw['nation'], $year, $month); + $this->crewType = GameUnitConst::byID($this->raw['crewtype']); + + if($isAttacker){ + //공격자 보정 + if($rawCity['level'] == 2){ + $this->genAtmosBonus += 5; + } + if($rawNation['capital'] == $rawCity['city']){ + $this->genAtmosBonus += 5; + } + } + else{ + //수비자 보정 + if($rawCity['level'] == 1){ + $this->genTrainBonus += 5; + } + else if($rawCity['level'] == 3){ + $this->genTrainBonus += 5; + } + } + } + + function getRaw():array{ + return $this->raw; + } + + function getName():string{ + return $this->raw['name']; + } + + function getCrewType():GameUnitDetail{ + return $this->crewType; + } + + function getLogger():ActionLogger{ + return $this->logger; + } + + function getSpecialDomestic():int{ + return $this->raw['special']; + } + + function getSpecialWar():int{ + return $this->raw['special2']; + } + + function getItem():int{ + return $this->raw['item']; + } + + function getMaxPhase():int{ + $phase = $this->getCrewType()->speed; + if($this->getSpecialWar() == 60){ + $phase += 1; + } + return $phase; + } + + function addTrain(int $train){ + $this->raw['train'] += $train; + $this->updatedVar['train'] = true; + } + + function addAtmos(int $atmos){ + $this->raw['atmos'] += $atmos; + $this->updatedVar['atmos'] = true; + } + + + function useBattleInitItem():bool{ + $item = $this->getItem(); + + if($item == 0){ + return false; + } + + $itemActivated = false; + $itemConsumed = false; + $itemName = getItemName($item); + + if($item == 3){ + //탁주 사용 + $this->genAtmos += 3; + $itemActivated = true; + $itemConsumed = true; + } + else if($item >= 14 && $item <= 16){ + //의적주, 두강주, 보령압주 사용 + $this->genAtmos += 5; + $itemActivated = true; + } + else if($item >= 19 && $item <= 20){ + //춘화첩, 초선화 사용 + $this->genAtmos += 7; + $itemActivated = true; + } + else if($item == 4){ + //청주 사용 + $this->genTrain += 3; + $itemActivated = true; + $itemConsumed = true; + } + else if($item >= 12 && $item <= 13){ + //과실주, 이강주 사용 + $this->genTrain += 5; + $itemActivated = true; + } + else if($item >= 18 && $item <= 18){ + //철벽서, 단결도 사용 + $this->genTrain += 7; + $itemActivated = true; + } + + if($itemConsumed){ + $this->raw['item'] = 0; + $this->updatedVar['item'] = true; + $josaUl = JosaUtil::pick($itemName, '을'); + $this->getLogger()->generalActionLog("{$itemName}{$josaUl} 사용!"); + } + + return $itemActivated; + } + + function continueWar(&$noRice):bool{ + if($this->raw['crew'] <= 0){ + $noRice = false; + return false; + } + if($this->raw['rice'] <= 0){ + $noRice = true; + return false; + } + return true; + } + + +} \ No newline at end of file