From 4bc78dba1e3abc037cc7c228e4faae3ef7aa2b19 Mon Sep 17 00:00:00 2001 From: hide_d Date: Sat, 18 Aug 2018 19:04:13 +0900 Subject: [PATCH] =?UTF-8?q?=EC=A0=84=ED=88=AC=20=EC=97=94=EC=A7=84=20?= =?UTF-8?q?=EC=A4=91=EA=B0=84=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hwe/process_war.ng.php | 102 +++++++++------------- hwe/sammo/WarUnit.php | 40 +++++---- hwe/sammo/WarUnitCity.php | 10 ++- hwe/sammo/WarUnitGeneral.php | 92 ++++++++++++++++++- src/sammo/NotInheritedMethodException.php | 6 ++ 5 files changed, 170 insertions(+), 80 deletions(-) create mode 100644 src/sammo/NotInheritedMethodException.php diff --git a/hwe/process_war.ng.php b/hwe/process_war.ng.php index c4713ebe..5be08520 100644 --- a/hwe/process_war.ng.php +++ b/hwe/process_war.ng.php @@ -3,21 +3,14 @@ namespace sammo; function processWar_NG( - array $rawAttacker, - array $rawAttackerCity, - array $rawAttackerNation, + WarUnitGeneral $attacker, callable $getNextDefender, - array $rawDefendercity, - array $rawDefenderNation, + WarUnitCity $city, string $time, - array $env + int $relYear ):array{ $templates = new \League\Plates\Engine(__dir__.'/templates'); - $year = $env['year']; - $month = $env['month']; - - $attacker = new WarUnitGeneral($rawAttacker, $rawAttackerCity, $rawAttackerNation, true, $year, $month); $logger = $attacker->getLogger(); $attacker->useBattleInitItem(); @@ -25,8 +18,6 @@ function processWar_NG( $attackerNationUpdate = []; $defenderNationUpdate = []; - $city = new WarUnitCity($rawDefendercity, $rawDefenderNation, $year, $month); - $maxPhase = $attacker->getMaxPhase(); $defender = ($getNextDefender)(null, true); @@ -34,15 +25,16 @@ function processWar_NG( $josaRo = JosaUtil::pick($city->name, '로'); $josaYi = JosaUtil::pick($attacker->name, '이'); - $logger->pushGlobalActionLog("{$rawAttackerNation['name']}{$attacker->name}{$josaYi} {$city->name}{$josaRo} 진격합니다."); + + $logger->pushGlobalActionLog("{$attacker->getRawNation()['name']}{$attacker->name}{$josaYi} {$city->name}{$josaRo} 진격합니다."); $logger->pushGeneralActionLog("{$city->name}{$josaRo} 진격합니다. <1>$date"); - for($currPhase = 0; $currPhase <= $maxPhase; $currPhase+=1){ + for($currPhase = 0; $currPhase < $maxPhase; $currPhase+=1){ if($defender === null){ $defender = $city; - if($rawDefenderNation['rice'] <= 0){ + if($city->getRawNation()['rice'] <= 0 && $city->getRaw()['supply'] == 1){ $conquerCity = true; break; } @@ -91,46 +83,50 @@ function processWar_NG( $attacker->checkActiveSkill(); $defender->checkActiveSkill(); - $attacker->checkActiveItem(); - $defender->checkActiveItem(); + $attacker->applyActiveSkill(); + $defender->applyActiveSkill(); - $attacker->applyActiveSkillAndItem(); - $defender->applyActiveSkillAndItem(); - - $killedDefender = $attacker->tryAttackInPhase(); - $killedAttacker = $defender->tryAttackInPhase(); - //NOTE: 마법, 기술, 쌀 소모는 tryAttackInPhase 내에서 반영 + $deadDefender = $attacker->tryAttackInPhase(); + $deadAttacker = $defender->tryAttackInPhase(); + //NOTE: 마법은 tryAttackInPhase 내에서 반영 $attackerHP = $attacker->getHP(); $defenderHP = $defender->getHP(); - if($killedAttacker > $attackerHP || $killedDefender > $defenderHP){ - $killedAttackerRatio = $killedAttacker / $attackerHP; - $killedDefenderRatio = $killedDefender / $defenderHP; + if($deadAttacker > $attackerHP || $deadDefender > $defenderHP){ + $deadAttackerRatio = $deadAttacker / $attackerHP; + $deadDefenderRatio = $deadDefender / $defenderHP; - if($killedDefenderRatio > $killedAttackerRatio){ + if($deadDefenderRatio > $deadAttackerRatio){ //수비자가 더 병력 부족 - $killedAttacker /= $killedDefenderRatio; - $killedDefender = $defenderHP; + $deadAttacker /= $deadDefenderRatio; + $deadDefender = $defenderHP; break; } else{ //공격자가 더 병력 부족 - $killedDefender /= $killedAttackerRatio; - $killedAttacker = $attackerHP; + $deadDefender /= $deadAttackerRatio; + $deadAttacker = $attackerHP; break; } } - //TODO: 전투 로그 기록(여기서??) + $deadAttacker = min(ceil($deadAttacker), $attackerHP); + $deadDefender = min(ceil($deadDefender), $defenderHP); - $attacker->decreaseHP(ceil($killedAttacker)); - $defender->decreaseHP(ceil($killedDefender)); + $attacker->decreaseHP($deadAttacker); + $defender->decreaseHP($deadDefender); + + $attacker->increaseKilled($deadDefender); + $defender->increaseKilled($deadAttacker); + //TODO: 기술, 쌀 소모 반영등은 이전 코드와 달리 동적으로 매 페이즈마다 추가 계산 + + //TODO: 로그 출력 $attacker->addPhase(); $defender->addPhase(); - //TODO: 기술로그 반영등은 이전 코드와 달리 동적으로 매 페이즈마다 추가 계산 + if(!$attacker->continueWar($noRice)){ //TODO: 퇴각해야함 @@ -156,6 +152,7 @@ function processWar_NG( $defender->tryWound(); if($defender === $city){ + $attacker->addLevelExp(1000); $conquerCity = true; break; } @@ -165,11 +162,10 @@ function processWar_NG( $attacker->getLogger()->pushGeneralActionLog("{$defender->getName()}의 {$defender->getCrewType()->name}{$josaYi} 퇴각했습니다.", ActionLogger::PLAIN); $defender->getLogger()->pushGeneralActionLog("퇴각했습니다.", ActionLogger::PLAIN); + $defender->finishBattle(); $defender = ($getNextDefender)($defender, true); - if($defender === null){ - continue; - } - if(!($defender instanceof WarUnitGeneral)){ + + if($defender !== null && !($defender instanceof WarUnitGeneral)){ throw new \RuntimeException('다음 수비자를 받아오는데 실패'); } } @@ -177,32 +173,18 @@ function processWar_NG( } //TODO: 전투 종료 + $attacker->finishBattle(); + $defender->finishBattle(); + ($getNextDefender)($defender, false); + //NOTE: 공격자의 applyDB는 함수 호출자가 실행 - if (!$conquerCity) { + if(!$conquerCity){ + return false; } - $conquerNation = false; - //TODO: 도시 정복 처리 - //TODO: 패퇴면 메시지 별도 - if($rawDefenderNation['rice'] <= 0){ - } + return true; - //TODO: 공격자 경험치? (여기서?) - - //TODO: DB 처리를 위한 반영 - - - if(!$conquerNation){ - } - - //TODO:국가 정복 처리는 밖에서 하자 - -} - -function getCrewtypeRice($crewtype, $tech) { - $cost = $crewtype->rice / 10; - return $cost * getTechCost($tech); } ////////////////////////////////////////////////////////////// diff --git a/hwe/sammo/WarUnit.php b/hwe/sammo/WarUnit.php index aac822e3..dd942686 100644 --- a/hwe/sammo/WarUnit.php +++ b/hwe/sammo/WarUnit.php @@ -8,7 +8,7 @@ class WarUnit{ protected $crewType; protected $killed = 0; - protected $death = 0; + protected $dead = 0; protected $isAttacker = false; @@ -55,6 +55,14 @@ class WarUnit{ return $this->logger; } + function getKilled():int{ + return $this->killed; + } + + function getDead():int{ + return $this->dead; + } + function getSpecialDomestic():int{ return 0; } @@ -146,21 +154,23 @@ class WarUnit{ } function getComputedTrain(){ - //TODO: 나머지에 구현 - return 100; + return GameConst::$maxTrainByCommand; } function getComputeAtmos(){ - //TODO: 나머지에 구현 - return 100; + return GameConst::$maxAtmosByCommand; } function addWin(){ - //TODO: 1승 로그 추가 + throw new NotInheritedMethodException(); } function addLose(){ - //TODO: 1패 로그 추가 + throw new NotInheritedMethodException(); + } + + function finishBattle(){ + throw new NotInheritedMethodException(); } function getCharacter(){ @@ -188,24 +198,24 @@ class WarUnit{ return false; } - function checkActiveItem():bool{ - return false; - } - - function applyActiveSkillAndItem():bool{ + function applyActiveSkill():bool{ return false; } function getHP():int{ - return 1; + throw new NotInheritedMethodException(); } function decreaseHP(int $damage):int{ - return false; + throw new NotInheritedMethodException(); + } + + function increaseKilled(int $damage):int{ + throw new NotInheritedMethodException(); } function tryAttackInPhase():int{ - return 0; + return $this->getWarPower(); } function tryWound():bool{ diff --git a/hwe/sammo/WarUnitCity.php b/hwe/sammo/WarUnitCity.php index e209b22d..b0e0382d 100644 --- a/hwe/sammo/WarUnitCity.php +++ b/hwe/sammo/WarUnitCity.php @@ -7,8 +7,6 @@ class WarUnitCity extends WarUnit{ protected $logger; protected $crewType; - protected $killed = 0; - protected $death = 0; protected $rice = 0; protected $updatedVar = []; @@ -20,6 +18,7 @@ class WarUnitCity extends WarUnit{ function __construct($raw, $rawNation, $year, $month){ $this->raw = $raw; $this->rawNation = $rawNation; + $this->isAttacker = false; $this->logger = new ActionLogger(0, $raw['nation'], $year, $month); @@ -27,7 +26,7 @@ class WarUnitCity extends WarUnit{ $this->def = $raw['def'] * 10; $this->wall = $raw['wall'] * 10; - $this->rice = $rawNation['rice']; + $this->rice = $this->rawNation['rice']; $this->crewType = GameUnitConst::byID(GameUnitConst::T_CASTLE); } @@ -40,6 +39,11 @@ class WarUnitCity extends WarUnit{ return $this->raw['name']; } + function tryAttackInPhase():int{ + $warPower = $this->getWarPower(); + $warPower *= Util::randRange(0.9, 1.1); + } + function continueWar(&$noRice):bool{ //전투가 가능하면 true $noRice = false; diff --git a/hwe/sammo/WarUnitGeneral.php b/hwe/sammo/WarUnitGeneral.php index 225be95f..56317b29 100644 --- a/hwe/sammo/WarUnitGeneral.php +++ b/hwe/sammo/WarUnitGeneral.php @@ -9,8 +9,6 @@ class WarUnitGeneral extends WarUnit{ protected $logger; protected $crewType; - protected $killed = 0; - protected $death = 0; protected $win = 0; protected $updatedVar = []; @@ -92,6 +90,55 @@ class WarUnitGeneral extends WarUnit{ $this->updatedVar['atmos'] = true; } + function addWin(){ + $this->win += 1; + + $this->raw['atmos'] = min($this->raw['atmos'] * 1.1, GameConst::$maxAtmosByWar); + $this->updatedVar['atmos'] = true; + + $this->addStatExp(1); + } + + function addStatExp(int $value = 1){ + if($this->crewType->armType == GameUnitConst::T_WIZARD) { // 귀병 + $this->raw['intel2'] += $value; + $this->updatedVar['intel2'] = true; + } elseif($this->crewType->armType == GameUnitConst::T_SIEGE) { // 차병 + $this->raw['leader2'] += $value; + $this->updatedVar['leader2'] = true; + } else { + $this->raw['power2'] += $value; + $this->updatedVar['power2'] = true; + } + } + + function addLevelExp(float $value){ + $value *= getCharExpMultiplier($this->getCharacter()); + $this->raw['experience'] += $value; + $this->updatedVar['experience'] = true; + } + + function addDedication(float $value){ + $value *= getCharDedMultiplier($this->getCharacter()); + $this->raw['dedication'] += $value; + $this->updatedVar['dedication'] = true; + } + + function addLose(){ + + $this->addStatExp(1); + //TODO: 1패 로그 추가 + } + + function finishBattle(){ + //TODO: 전투 종료 처리. 경험치 등 + + + Util::setRound($this->raw['rice']); + Util::setRound($this->raw['experience']); + Util::setRound($this->raw['dedication']); + } + protected function getWarPowerMultiplyBySpecialWar():array{ //TODO: 장기적으로 if문이 아니라 객체를 이용하여 처리해야함 $myWarPowerMultiply = 1.0; @@ -270,6 +317,47 @@ class WarUnitGeneral extends WarUnit{ return $itemActivated; } + function getHP():int{ + return $this->raw['crew']; + } + + function decreaseHP(int $damage):int{ + $damage = min($damage, $this->raw['crew']); + $this->raw['crew'] -= $damage; + + //TODO: 죽은 만큼 숙련도 변경 + + return $this->raw['crew']; + } + + function increaseKilled(int $damage):int{ + + $this->addLevelExp($damage / 50); + + $rice = $damage / 100; + if(!$this->isAttacker){ + $rice *= 0.8; + } + + $rice *= getCharExpMultiplier($this->getCharacter()); + $rice *= $this->crewType->rice; + $rice *= getTechCost($this->rawNation['tech']); + + $rice = min($this->raw['rice'], $rice); + $this->raw['rice'] -= $rice; + $this->updatedVar['rice'] = true; + //TODO: 죽인 만큼 숙련도 변경 + //TODO: 죽인 만큼 쌀 소모 + + $this->killed += $damage; + return $this->killed; + } + + function tryAttackInPhase():int{ + //TODO + return 0; + } + function tryWound():bool{ if(Util::randBool(0.95)){ return false; diff --git a/src/sammo/NotInheritedMethodException.php b/src/sammo/NotInheritedMethodException.php new file mode 100644 index 00000000..739d038d --- /dev/null +++ b/src/sammo/NotInheritedMethodException.php @@ -0,0 +1,6 @@ +