전투 엔진 중간 반영
This commit is contained in:
+41
-59
@@ -3,21 +3,14 @@ namespace sammo;
|
|||||||
|
|
||||||
|
|
||||||
function processWar_NG(
|
function processWar_NG(
|
||||||
array $rawAttacker,
|
WarUnitGeneral $attacker,
|
||||||
array $rawAttackerCity,
|
|
||||||
array $rawAttackerNation,
|
|
||||||
callable $getNextDefender,
|
callable $getNextDefender,
|
||||||
array $rawDefendercity,
|
WarUnitCity $city,
|
||||||
array $rawDefenderNation,
|
|
||||||
string $time,
|
string $time,
|
||||||
array $env
|
int $relYear
|
||||||
):array{
|
):array{
|
||||||
$templates = new \League\Plates\Engine(__dir__.'/templates');
|
$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();
|
$logger = $attacker->getLogger();
|
||||||
|
|
||||||
$attacker->useBattleInitItem();
|
$attacker->useBattleInitItem();
|
||||||
@@ -25,8 +18,6 @@ function processWar_NG(
|
|||||||
$attackerNationUpdate = [];
|
$attackerNationUpdate = [];
|
||||||
$defenderNationUpdate = [];
|
$defenderNationUpdate = [];
|
||||||
|
|
||||||
$city = new WarUnitCity($rawDefendercity, $rawDefenderNation, $year, $month);
|
|
||||||
|
|
||||||
$maxPhase = $attacker->getMaxPhase();
|
$maxPhase = $attacker->getMaxPhase();
|
||||||
|
|
||||||
$defender = ($getNextDefender)(null, true);
|
$defender = ($getNextDefender)(null, true);
|
||||||
@@ -34,15 +25,16 @@ function processWar_NG(
|
|||||||
|
|
||||||
$josaRo = JosaUtil::pick($city->name, '로');
|
$josaRo = JosaUtil::pick($city->name, '로');
|
||||||
$josaYi = JosaUtil::pick($attacker->name, '이');
|
$josaYi = JosaUtil::pick($attacker->name, '이');
|
||||||
$logger->pushGlobalActionLog("<D><b>{$rawAttackerNation['name']}</b></>의 <Y>{$attacker->name}</>{$josaYi} <G><b>{$city->name}</b></>{$josaRo} 진격합니다.");
|
|
||||||
|
$logger->pushGlobalActionLog("<D><b>{$attacker->getRawNation()['name']}</b></>의 <Y>{$attacker->name}</>{$josaYi} <G><b>{$city->name}</b></>{$josaRo} 진격합니다.");
|
||||||
$logger->pushGeneralActionLog("<G><b>{$city->name}</b></>{$josaRo} <M>진격</>합니다. <1>$date</>");
|
$logger->pushGeneralActionLog("<G><b>{$city->name}</b></>{$josaRo} <M>진격</>합니다. <1>$date</>");
|
||||||
|
|
||||||
for($currPhase = 0; $currPhase <= $maxPhase; $currPhase+=1){
|
for($currPhase = 0; $currPhase < $maxPhase; $currPhase+=1){
|
||||||
|
|
||||||
if($defender === null){
|
if($defender === null){
|
||||||
$defender = $city;
|
$defender = $city;
|
||||||
|
|
||||||
if($rawDefenderNation['rice'] <= 0){
|
if($city->getRawNation()['rice'] <= 0 && $city->getRaw()['supply'] == 1){
|
||||||
$conquerCity = true;
|
$conquerCity = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -91,46 +83,50 @@ function processWar_NG(
|
|||||||
$attacker->checkActiveSkill();
|
$attacker->checkActiveSkill();
|
||||||
$defender->checkActiveSkill();
|
$defender->checkActiveSkill();
|
||||||
|
|
||||||
$attacker->checkActiveItem();
|
$attacker->applyActiveSkill();
|
||||||
$defender->checkActiveItem();
|
$defender->applyActiveSkill();
|
||||||
|
|
||||||
$attacker->applyActiveSkillAndItem();
|
$deadDefender = $attacker->tryAttackInPhase();
|
||||||
$defender->applyActiveSkillAndItem();
|
$deadAttacker = $defender->tryAttackInPhase();
|
||||||
|
//NOTE: 마법은 tryAttackInPhase 내에서 반영
|
||||||
$killedDefender = $attacker->tryAttackInPhase();
|
|
||||||
$killedAttacker = $defender->tryAttackInPhase();
|
|
||||||
//NOTE: 마법, 기술, 쌀 소모는 tryAttackInPhase 내에서 반영
|
|
||||||
|
|
||||||
$attackerHP = $attacker->getHP();
|
$attackerHP = $attacker->getHP();
|
||||||
$defenderHP = $defender->getHP();
|
$defenderHP = $defender->getHP();
|
||||||
|
|
||||||
if($killedAttacker > $attackerHP || $killedDefender > $defenderHP){
|
if($deadAttacker > $attackerHP || $deadDefender > $defenderHP){
|
||||||
$killedAttackerRatio = $killedAttacker / $attackerHP;
|
$deadAttackerRatio = $deadAttacker / $attackerHP;
|
||||||
$killedDefenderRatio = $killedDefender / $defenderHP;
|
$deadDefenderRatio = $deadDefender / $defenderHP;
|
||||||
|
|
||||||
if($killedDefenderRatio > $killedAttackerRatio){
|
if($deadDefenderRatio > $deadAttackerRatio){
|
||||||
//수비자가 더 병력 부족
|
//수비자가 더 병력 부족
|
||||||
$killedAttacker /= $killedDefenderRatio;
|
$deadAttacker /= $deadDefenderRatio;
|
||||||
$killedDefender = $defenderHP;
|
$deadDefender = $defenderHP;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
//공격자가 더 병력 부족
|
//공격자가 더 병력 부족
|
||||||
$killedDefender /= $killedAttackerRatio;
|
$deadDefender /= $deadAttackerRatio;
|
||||||
$killedAttacker = $attackerHP;
|
$deadAttacker = $attackerHP;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: 전투 로그 기록(여기서??)
|
$deadAttacker = min(ceil($deadAttacker), $attackerHP);
|
||||||
|
$deadDefender = min(ceil($deadDefender), $defenderHP);
|
||||||
|
|
||||||
$attacker->decreaseHP(ceil($killedAttacker));
|
$attacker->decreaseHP($deadAttacker);
|
||||||
$defender->decreaseHP(ceil($killedDefender));
|
$defender->decreaseHP($deadDefender);
|
||||||
|
|
||||||
|
$attacker->increaseKilled($deadDefender);
|
||||||
|
$defender->increaseKilled($deadAttacker);
|
||||||
|
//TODO: 기술, 쌀 소모 반영등은 이전 코드와 달리 동적으로 매 페이즈마다 추가 계산
|
||||||
|
|
||||||
|
//TODO: 로그 출력
|
||||||
|
|
||||||
$attacker->addPhase();
|
$attacker->addPhase();
|
||||||
$defender->addPhase();
|
$defender->addPhase();
|
||||||
|
|
||||||
//TODO: 기술로그 반영등은 이전 코드와 달리 동적으로 매 페이즈마다 추가 계산
|
|
||||||
|
|
||||||
if(!$attacker->continueWar($noRice)){
|
if(!$attacker->continueWar($noRice)){
|
||||||
//TODO: 퇴각해야함
|
//TODO: 퇴각해야함
|
||||||
@@ -156,6 +152,7 @@ function processWar_NG(
|
|||||||
$defender->tryWound();
|
$defender->tryWound();
|
||||||
|
|
||||||
if($defender === $city){
|
if($defender === $city){
|
||||||
|
$attacker->addLevelExp(1000);
|
||||||
$conquerCity = true;
|
$conquerCity = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -165,11 +162,10 @@ function processWar_NG(
|
|||||||
$attacker->getLogger()->pushGeneralActionLog("<Y>{$defender->getName()}</>의 {$defender->getCrewType()->name}{$josaYi} 퇴각했습니다.", ActionLogger::PLAIN);
|
$attacker->getLogger()->pushGeneralActionLog("<Y>{$defender->getName()}</>의 {$defender->getCrewType()->name}{$josaYi} 퇴각했습니다.", ActionLogger::PLAIN);
|
||||||
$defender->getLogger()->pushGeneralActionLog("퇴각했습니다.", ActionLogger::PLAIN);
|
$defender->getLogger()->pushGeneralActionLog("퇴각했습니다.", ActionLogger::PLAIN);
|
||||||
|
|
||||||
|
$defender->finishBattle();
|
||||||
$defender = ($getNextDefender)($defender, true);
|
$defender = ($getNextDefender)($defender, true);
|
||||||
if($defender === null){
|
|
||||||
continue;
|
if($defender !== null && !($defender instanceof WarUnitGeneral)){
|
||||||
}
|
|
||||||
if(!($defender instanceof WarUnitGeneral)){
|
|
||||||
throw new \RuntimeException('다음 수비자를 받아오는데 실패');
|
throw new \RuntimeException('다음 수비자를 받아오는데 실패');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -177,32 +173,18 @@ function processWar_NG(
|
|||||||
}
|
}
|
||||||
|
|
||||||
//TODO: 전투 종료
|
//TODO: 전투 종료
|
||||||
|
$attacker->finishBattle();
|
||||||
|
$defender->finishBattle();
|
||||||
|
|
||||||
($getNextDefender)($defender, false);
|
($getNextDefender)($defender, false);
|
||||||
|
//NOTE: 공격자의 applyDB는 함수 호출자가 실행
|
||||||
|
|
||||||
if(!$conquerCity){
|
if(!$conquerCity){
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$conquerNation = false;
|
return true;
|
||||||
//TODO: 도시 정복 처리
|
|
||||||
//TODO: 패퇴면 메시지 별도
|
|
||||||
if($rawDefenderNation['rice'] <= 0){
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: 공격자 경험치? (여기서?)
|
|
||||||
|
|
||||||
//TODO: DB 처리를 위한 반영
|
|
||||||
|
|
||||||
|
|
||||||
if(!$conquerNation){
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO:국가 정복 처리는 밖에서 하자
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function getCrewtypeRice($crewtype, $tech) {
|
|
||||||
$cost = $crewtype->rice / 10;
|
|
||||||
return $cost * getTechCost($tech);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
|
|||||||
+25
-15
@@ -8,7 +8,7 @@ class WarUnit{
|
|||||||
protected $crewType;
|
protected $crewType;
|
||||||
|
|
||||||
protected $killed = 0;
|
protected $killed = 0;
|
||||||
protected $death = 0;
|
protected $dead = 0;
|
||||||
|
|
||||||
protected $isAttacker = false;
|
protected $isAttacker = false;
|
||||||
|
|
||||||
@@ -55,6 +55,14 @@ class WarUnit{
|
|||||||
return $this->logger;
|
return $this->logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getKilled():int{
|
||||||
|
return $this->killed;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDead():int{
|
||||||
|
return $this->dead;
|
||||||
|
}
|
||||||
|
|
||||||
function getSpecialDomestic():int{
|
function getSpecialDomestic():int{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -146,21 +154,23 @@ class WarUnit{
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getComputedTrain(){
|
function getComputedTrain(){
|
||||||
//TODO: 나머지에 구현
|
return GameConst::$maxTrainByCommand;
|
||||||
return 100;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getComputeAtmos(){
|
function getComputeAtmos(){
|
||||||
//TODO: 나머지에 구현
|
return GameConst::$maxAtmosByCommand;
|
||||||
return 100;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function addWin(){
|
function addWin(){
|
||||||
//TODO: 1승 로그 추가
|
throw new NotInheritedMethodException();
|
||||||
}
|
}
|
||||||
|
|
||||||
function addLose(){
|
function addLose(){
|
||||||
//TODO: 1패 로그 추가
|
throw new NotInheritedMethodException();
|
||||||
|
}
|
||||||
|
|
||||||
|
function finishBattle(){
|
||||||
|
throw new NotInheritedMethodException();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCharacter(){
|
function getCharacter(){
|
||||||
@@ -188,24 +198,24 @@ class WarUnit{
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkActiveItem():bool{
|
function applyActiveSkill():bool{
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function applyActiveSkillAndItem():bool{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getHP():int{
|
function getHP():int{
|
||||||
return 1;
|
throw new NotInheritedMethodException();
|
||||||
}
|
}
|
||||||
|
|
||||||
function decreaseHP(int $damage):int{
|
function decreaseHP(int $damage):int{
|
||||||
return false;
|
throw new NotInheritedMethodException();
|
||||||
|
}
|
||||||
|
|
||||||
|
function increaseKilled(int $damage):int{
|
||||||
|
throw new NotInheritedMethodException();
|
||||||
}
|
}
|
||||||
|
|
||||||
function tryAttackInPhase():int{
|
function tryAttackInPhase():int{
|
||||||
return 0;
|
return $this->getWarPower();
|
||||||
}
|
}
|
||||||
|
|
||||||
function tryWound():bool{
|
function tryWound():bool{
|
||||||
|
|||||||
@@ -7,8 +7,6 @@ class WarUnitCity extends WarUnit{
|
|||||||
protected $logger;
|
protected $logger;
|
||||||
protected $crewType;
|
protected $crewType;
|
||||||
|
|
||||||
protected $killed = 0;
|
|
||||||
protected $death = 0;
|
|
||||||
protected $rice = 0;
|
protected $rice = 0;
|
||||||
|
|
||||||
protected $updatedVar = [];
|
protected $updatedVar = [];
|
||||||
@@ -20,6 +18,7 @@ class WarUnitCity extends WarUnit{
|
|||||||
function __construct($raw, $rawNation, $year, $month){
|
function __construct($raw, $rawNation, $year, $month){
|
||||||
$this->raw = $raw;
|
$this->raw = $raw;
|
||||||
$this->rawNation = $rawNation;
|
$this->rawNation = $rawNation;
|
||||||
|
|
||||||
$this->isAttacker = false;
|
$this->isAttacker = false;
|
||||||
|
|
||||||
$this->logger = new ActionLogger(0, $raw['nation'], $year, $month);
|
$this->logger = new ActionLogger(0, $raw['nation'], $year, $month);
|
||||||
@@ -27,7 +26,7 @@ class WarUnitCity extends WarUnit{
|
|||||||
|
|
||||||
$this->def = $raw['def'] * 10;
|
$this->def = $raw['def'] * 10;
|
||||||
$this->wall = $raw['wall'] * 10;
|
$this->wall = $raw['wall'] * 10;
|
||||||
$this->rice = $rawNation['rice'];
|
$this->rice = $this->rawNation['rice'];
|
||||||
|
|
||||||
$this->crewType = GameUnitConst::byID(GameUnitConst::T_CASTLE);
|
$this->crewType = GameUnitConst::byID(GameUnitConst::T_CASTLE);
|
||||||
}
|
}
|
||||||
@@ -40,6 +39,11 @@ class WarUnitCity extends WarUnit{
|
|||||||
return $this->raw['name'];
|
return $this->raw['name'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function tryAttackInPhase():int{
|
||||||
|
$warPower = $this->getWarPower();
|
||||||
|
$warPower *= Util::randRange(0.9, 1.1);
|
||||||
|
}
|
||||||
|
|
||||||
function continueWar(&$noRice):bool{
|
function continueWar(&$noRice):bool{
|
||||||
//전투가 가능하면 true
|
//전투가 가능하면 true
|
||||||
$noRice = false;
|
$noRice = false;
|
||||||
|
|||||||
@@ -9,8 +9,6 @@ class WarUnitGeneral extends WarUnit{
|
|||||||
protected $logger;
|
protected $logger;
|
||||||
protected $crewType;
|
protected $crewType;
|
||||||
|
|
||||||
protected $killed = 0;
|
|
||||||
protected $death = 0;
|
|
||||||
protected $win = 0;
|
protected $win = 0;
|
||||||
|
|
||||||
protected $updatedVar = [];
|
protected $updatedVar = [];
|
||||||
@@ -92,6 +90,55 @@ class WarUnitGeneral extends WarUnit{
|
|||||||
$this->updatedVar['atmos'] = true;
|
$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{
|
protected function getWarPowerMultiplyBySpecialWar():array{
|
||||||
//TODO: 장기적으로 if문이 아니라 객체를 이용하여 처리해야함
|
//TODO: 장기적으로 if문이 아니라 객체를 이용하여 처리해야함
|
||||||
$myWarPowerMultiply = 1.0;
|
$myWarPowerMultiply = 1.0;
|
||||||
@@ -270,6 +317,47 @@ class WarUnitGeneral extends WarUnit{
|
|||||||
return $itemActivated;
|
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{
|
function tryWound():bool{
|
||||||
if(Util::randBool(0.95)){
|
if(Util::randBool(0.95)){
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace sammo;
|
||||||
|
|
||||||
|
class NotInheritedMethodException extends \BadMethodCallException
|
||||||
|
{}
|
||||||
Reference in New Issue
Block a user