feat: 전투 상대방의 특정 수치를 접근할 수 있는 callback류 생성

This commit is contained in:
2021-09-15 19:06:15 +00:00
committed by Gitea
parent d225eb9b16
commit 0f853303a4
7 changed files with 156 additions and 93 deletions
+4
View File
@@ -25,6 +25,10 @@ trait DefaultAction{
return $value; return $value;
} }
public function onCalcOpposeStat(General $general, string $statName, $value, $aux=null){
return $value;
}
public function onCalcStrategic(string $turnType, string $varType, $value){ public function onCalcStrategic(string $turnType, string $varType, $value){
return $value; return $value;
} }
+20
View File
@@ -844,6 +844,26 @@ class General implements iAction{
return $value; return $value;
} }
public function onCalcOpposeStat(General $general, string $statName, $value, $aux=null){
//xxx: $general?
foreach(array_merge([
$this->nationType,
$this->officerLevelObj,
$this->specialDomesticObj,
$this->specialWarObj,
$this->personalityObj,
$this->getCrewTypeObj(),
$this->inheritBuffObj,
], $this->itemObjs) as $iObj){
if(!$iObj){
continue;
}
/** @var iAction $iObj */
$value = $iObj->onCalcOpposeStat($this, $statName, $value, $aux);
}
return $value;
}
public function onCalcStrategic(string $turnType, string $varType, $value){ public function onCalcStrategic(string $turnType, string $varType, $value){
foreach(array_merge([ foreach(array_merge([
$this->nationType, $this->nationType,
+110 -80
View File
@@ -1,10 +1,13 @@
<?php <?php
namespace sammo; namespace sammo;
class WarUnitGeneral extends WarUnit{ class WarUnitGeneral extends WarUnit
{
protected $raw; protected $raw;
function __construct(General $general, array $rawNation, bool $isAttacker){ function __construct(General $general, array $rawNation, bool $isAttacker)
{
$this->general = $general; $this->general = $general;
$this->raw = $general->getRaw(); $this->raw = $general->getRaw();
$this->rawNation = $rawNation; //read-only $this->rawNation = $rawNation; //read-only
@@ -15,43 +18,43 @@ class WarUnitGeneral extends WarUnit{
$cityLevel = $this->getCityVar('level'); $cityLevel = $this->getCityVar('level');
if($isAttacker){ if ($isAttacker) {
//공격자 보정 //공격자 보정
if($cityLevel == 2){ if ($cityLevel == 2) {
$this->atmosBonus += 5; $this->atmosBonus += 5;
} }
if($rawNation['capital'] == $this->getCityVar('city')){ if ($rawNation['capital'] == $this->getCityVar('city')) {
$this->atmosBonus += 5; $this->atmosBonus += 5;
} }
} } else {
else{
//수비자 보정 //수비자 보정
if($cityLevel == 1){ if ($cityLevel == 1) {
$this->trainBonus += 5; $this->trainBonus += 5;
} } else if ($cityLevel == 3) {
else if($cityLevel == 3){
$this->trainBonus += 5; $this->trainBonus += 5;
} }
} }
} }
function getName():string{ function getName(): string
{
return $this->general->getName(); return $this->general->getName();
} }
function getCityVar(string $key){ function getCityVar(string $key)
{
return $this->general->getRawCity()[$key]; return $this->general->getRawCity()[$key];
} }
function setOppose(?WarUnit $oppose){ function setOppose(?WarUnit $oppose)
{
parent::setOppose($oppose); parent::setOppose($oppose);
$general = $this->general; $general = $this->general;
$this->general->increaseRankVar('warnum', 1); $this->general->increaseRankVar('warnum', 1);
if($this->isAttacker){ if ($this->isAttacker) {
$semiTurn = $general->getTurnTime(); $semiTurn = $general->getTurnTime();
} } else if ($oppose !== null) {
else if($oppose !== null){
$semiTurn = $oppose->getGeneral()->getTurnTime(); $semiTurn = $oppose->getGeneral()->getTurnTime();
} }
$phase = $this->getRealPhase(); $phase = $this->getRealPhase();
@@ -60,75 +63,94 @@ class WarUnitGeneral extends WarUnit{
$general->setVar('recent_war', $semiTurn); $general->setVar('recent_war', $semiTurn);
} }
function getMaxPhase():int{ function getMaxPhase(): int
{
$phase = $this->getCrewType()->speed; $phase = $this->getCrewType()->speed;
$phase = $this->general->onCalcStat($this->general, 'initWarPhase', $phase, ['isAttacker'=>$this->isAttacker]); $phase = $this->general->onCalcStat($this->general, 'initWarPhase', $phase, ['isAttacker' => $this->isAttacker]);
$phase = $this->oppose->general->onCalcOpposeStat($this->general, 'initWarPhase', $phase, ['isAttacker' => $this->isAttacker]);
return $phase + $this->bonusPhase; return $phase + $this->bonusPhase;
} }
function addTrain(int $train){ function addTrain(int $train)
{
$this->general->increaseVarWithLimit('train', $train, 0, GameConst::$maxTrainByWar); $this->general->increaseVarWithLimit('train', $train, 0, GameConst::$maxTrainByWar);
} }
function addAtmos(int $atmos){ function addAtmos(int $atmos)
{
$this->general->increaseVarWithLimit('atmos', $atmos, 0, GameConst::$maxAtmosByWar); $this->general->increaseVarWithLimit('atmos', $atmos, 0, GameConst::$maxAtmosByWar);
} }
function getDex(GameUnitDetail $crewType){ function getDex(GameUnitDetail $crewType)
$rawDex = $this->general->getDex($crewType); {
return $this->general->onCalcStat($this->general, 'dex'.$crewType->armType, $rawDex, [ $dex = $this->general->getDex($crewType);
'isAttacker'=>$this->isAttacker, $dex = $this->general->onCalcStat($this->general, 'dex' . $crewType->armType, $dex, [
'opposeType'=>$this->oppose->getCrewType() 'isAttacker' => $this->isAttacker,
'opposeType' => $this->oppose->getCrewType()
]); ]);
$dex = $this->oppose->general->onCalcOpposeStat($this->general, 'dex' . $crewType->armType, $dex, [
'isAttacker' => $this->isAttacker,
'opposeType' => $this->oppose->getCrewType()
]);
return $dex;
} }
function getComputedTrain(){ function getComputedTrain()
{
$train = $this->general->getVar('train'); $train = $this->general->getVar('train');
$train = $this->general->onCalcStat($this->general, 'bonusTrain', $train, ['isAttacker'=>$this->isAttacker]); $train = $this->general->onCalcStat($this->general, 'bonusTrain', $train, ['isAttacker' => $this->isAttacker]);
$train = $this->oppose->general->onCalcOpposeStat($this->general, 'bonusTrain', $train, ['isAttacker' => $this->isAttacker]);
$train += $this->trainBonus; $train += $this->trainBonus;
return $train; return $train;
} }
function getComputedAtmos(){ function getComputedAtmos()
{
$atmos = $this->general->getVar('atmos'); $atmos = $this->general->getVar('atmos');
$atmos = $this->general->onCalcStat($this->general, 'bonusAtmos', $atmos, ['isAttacker'=>$this->isAttacker]); $atmos = $this->general->onCalcStat($this->general, 'bonusAtmos', $atmos, ['isAttacker' => $this->isAttacker]);
$atmos = $this->oppose->general->onCalcOpposeStat($this->general, 'bonusAtmos', $atmos, ['isAttacker' => $this->isAttacker]);
$atmos += $this->atmosBonus; $atmos += $this->atmosBonus;
return $atmos; return $atmos;
} }
function getComputedCriticalRatio():float{ function getComputedCriticalRatio(): float
{
$general = $this->general; $general = $this->general;
$criticalRatio = $this->getCrewType()->getCriticalRatio($general); $criticalRatio = $this->getCrewType()->getCriticalRatio($general);
/** @var float $criticalRatio */ /** @var float $criticalRatio */
$criticalRatio = $general->onCalcStat($general, 'warCriticalRatio', $criticalRatio, ['isAttacker'=>$this->isAttacker]); $criticalRatio = $general->onCalcStat($general, 'warCriticalRatio', $criticalRatio, ['isAttacker' => $this->isAttacker]);
$criticalRatio = $this->oppose->general->onCalcOpposeStat($general, 'warCriticalRatio', $criticalRatio, ['isAttacker' => $this->isAttacker]);
return $criticalRatio; return $criticalRatio;
} }
function getComputedAvoidRatio():float{ function getComputedAvoidRatio(): float
{
$general = $this->general; $general = $this->general;
$avoidRatio = $this->getCrewType()->avoid / 100; $avoidRatio = $this->getCrewType()->avoid / 100;
$avoidRatio *= $this->getComputedTrain() / 100; $avoidRatio *= $this->getComputedTrain() / 100;
/** @var float $avoidRatio */ /** @var float $avoidRatio */
$avoidRatio = $general->onCalcStat($general, 'warAvoidRatio', $avoidRatio, ['isAttacker'=>$this->isAttacker]); $avoidRatio = $general->onCalcStat($general, 'warAvoidRatio', $avoidRatio, ['isAttacker' => $this->isAttacker]);
$avoidRatio = $this->oppose->general->onCalcOpposeStat($general, 'warAvoidRatio', $avoidRatio, ['isAttacker' => $this->isAttacker]);
if($this->getOppose()->getCrewType()->armType == GameUnitConst::T_FOOTMAN){ if ($this->getOppose()->getCrewType()->armType == GameUnitConst::T_FOOTMAN) {
$avoidRatio *= 0.75; $avoidRatio *= 0.75;
} }
return $avoidRatio; return $avoidRatio;
} }
function addWin(){ function addWin()
{
$general = $this->general; $general = $this->general;
$general->increaseRankVar('killnum', 1); $general->increaseRankVar('killnum', 1);
$oppose = $this->getOppose(); $oppose = $this->getOppose();
if($oppose instanceof WarUnitCity){ if ($oppose instanceof WarUnitCity) {
$general->increaseRankVar('occupied', 1); $general->increaseRankVar('occupied', 1);
} }
@@ -137,70 +159,70 @@ class WarUnitGeneral extends WarUnit{
$this->addStatExp(1); $this->addStatExp(1);
} }
function addStatExp(int $value = 1){ function addStatExp(int $value = 1)
{
$general = $this->general; $general = $this->general;
if($this->crewType->armType == GameUnitConst::T_WIZARD) { // 귀병 if ($this->crewType->armType == GameUnitConst::T_WIZARD) { // 귀병
$general->increaseVar('intel_exp', $value); $general->increaseVar('intel_exp', $value);
} elseif($this->crewType->armType == GameUnitConst::T_SIEGE) { // 차병 } elseif ($this->crewType->armType == GameUnitConst::T_SIEGE) { // 차병
$general->increaseVar('leadership_exp', $value); $general->increaseVar('leadership_exp', $value);
} else { } else {
$general->increaseVar('strength_exp', $value); $general->increaseVar('strength_exp', $value);
} }
} }
function addLevelExp(float $value){ function addLevelExp(float $value)
{
$general = $this->general; $general = $this->general;
if(!$this->isAttacker){ if (!$this->isAttacker) {
$value *= 0.8; $value *= 0.8;
} }
$general->addExperience($value); $general->addExperience($value);
} }
function addDedication(float $value){ function addDedication(float $value)
{
$general = $this->general; $general = $this->general;
$general->addDedication($value); $general->addDedication($value);
} }
function addLose(){ function addLose()
{
$general = $this->general; $general = $this->general;
$general->increaseRankVar('deathnum', 1); $general->increaseRankVar('deathnum', 1);
$this->addStatExp(1); $this->addStatExp(1);
} }
function computeWarPower(){ function computeWarPower()
[$warPower,$opposeWarPowerMultiply] = parent::computeWarPower(); {
[$warPower, $opposeWarPowerMultiply] = parent::computeWarPower();
$general = $this->general; $general = $this->general;
$cityID = $general->getCityID(); $cityID = $general->getCityID();
$officerLevel = $general->getVar('officer_level'); $officerLevel = $general->getVar('officer_level');
$officerCity = $general->getVar('officer_city'); $officerCity = $general->getVar('officer_city');
if($this->isAttacker){ if ($this->isAttacker) {
if($officerLevel == 12){ if ($officerLevel == 12) {
$warPower *= 1.10; $warPower *= 1.10;
} } else if ($officerLevel == 11 | $officerLevel == 10 || $officerLevel == 8 || $officerLevel == 6) {
else if($officerLevel == 11 | $officerLevel == 10 || $officerLevel == 8 || $officerLevel == 6){
$warPower *= 1.05; $warPower *= 1.05;
} }
} } else {
else{ if ($officerLevel == 12) {
if($officerLevel == 12){
$opposeWarPowerMultiply *= 0.90; $opposeWarPowerMultiply *= 0.90;
} } else if ($officerLevel == 11 || $officerLevel == 9 || $officerLevel == 7 || $officerLevel == 5) {
else if($officerLevel == 11 || $officerLevel == 9 || $officerLevel == 7 || $officerLevel == 5){
$opposeWarPowerMultiply *= 0.95; $opposeWarPowerMultiply *= 0.95;
} } else if (2 <= $officerLevel && $officerLevel <= 4 && $officerCity == $cityID) {
else if(2 <= $officerLevel && $officerLevel <= 4 && $officerCity == $cityID){
$opposeWarPowerMultiply *= 0.95; $opposeWarPowerMultiply *= 0.95;
} }
} }
$expLevel = $general->getVar('explevel'); $expLevel = $general->getVar('explevel');
if($this->getOppose() instanceof WarUnitCity){ if ($this->getOppose() instanceof WarUnitCity) {
$warPower *= 1 + $expLevel / 600; $warPower *= 1 + $expLevel / 600;
} } else {
else{
$warPower /= max(0.01, 1 - $expLevel / 300); $warPower /= max(0.01, 1 - $expLevel / 300);
$opposeWarPowerMultiply *= max(0.01, 1 - $expLevel / 300); $opposeWarPowerMultiply *= max(0.01, 1 - $expLevel / 300);
} }
@@ -212,18 +234,21 @@ class WarUnitGeneral extends WarUnit{
$this->warPower = $warPower; $this->warPower = $warPower;
$this->oppose->setWarPowerMultiply($opposeWarPowerMultiply); $this->oppose->setWarPowerMultiply($opposeWarPowerMultiply);
return [$warPower,$opposeWarPowerMultiply]; return [$warPower, $opposeWarPowerMultiply];
} }
function getHP():int{ function getHP(): int
{
return $this->general->getVar('crew'); return $this->general->getVar('crew');
} }
function addDex(GameUnitDetail $crewType, float $exp){ function addDex(GameUnitDetail $crewType, float $exp)
{
$this->general->addDex($crewType, $exp, false); $this->general->addDex($crewType, $exp, false);
} }
function decreaseHP(int $damage):int{ function decreaseHP(int $damage): int
{
$general = $this->general; $general = $this->general;
$damage = min($damage, $general->getVar('crew')); $damage = min($damage, $general->getVar('crew'));
@@ -232,7 +257,7 @@ class WarUnitGeneral extends WarUnit{
$general->increaseVar('crew', -$damage); $general->increaseVar('crew', -$damage);
$addDex = $damage; $addDex = $damage;
if(!$this->isAttacker){ if (!$this->isAttacker) {
$addDex *= 0.9; $addDex *= 0.9;
} }
$this->addDex($this->oppose->getCrewType(), $addDex); $this->addDex($this->oppose->getCrewType(), $addDex);
@@ -240,12 +265,13 @@ class WarUnitGeneral extends WarUnit{
return $general->getVar('crew'); return $general->getVar('crew');
} }
function increaseKilled(int $damage):int{ function increaseKilled(int $damage): int
{
$general = $this->general; $general = $this->general;
$this->addLevelExp($damage / 50); $this->addLevelExp($damage / 50);
$rice = $damage / 100; $rice = $damage / 100;
if(!$this->isAttacker){ if (!$this->isAttacker) {
$rice *= 0.8; $rice *= 0.8;
} }
@@ -255,7 +281,7 @@ class WarUnitGeneral extends WarUnit{
$general->increaseVarWithLimit('rice', -$rice, 0); $general->increaseVarWithLimit('rice', -$rice, 0);
$addDex = $damage; $addDex = $damage;
if(!$this->isAttacker){ if (!$this->isAttacker) {
$addDex *= 0.9; $addDex *= 0.9;
} }
$this->addDex($this->getCrewType(), $addDex); $this->addDex($this->getCrewType(), $addDex);
@@ -265,15 +291,16 @@ class WarUnitGeneral extends WarUnit{
return $this->killed; return $this->killed;
} }
function tryWound():bool{ function tryWound(): bool
{
$general = $this->general; $general = $this->general;
if($this->hasActivatedSkillOnLog('부상무효')){ if ($this->hasActivatedSkillOnLog('부상무효')) {
return false; return false;
} }
if($this->hasActivatedSkillOnLog('퇴각부상무효')){ if ($this->hasActivatedSkillOnLog('퇴각부상무효')) {
return false; return false;
} }
if(!Util::randBool(0.05)){ if (!Util::randBool(0.05)) {
return false; return false;
} }
@@ -285,25 +312,28 @@ class WarUnitGeneral extends WarUnit{
return true; return true;
} }
function continueWar(&$noRice):bool{ function continueWar(&$noRice): bool
{
$general = $this->general; $general = $this->general;
if($this->getHP() <= 0){ if ($this->getHP() <= 0) {
$noRice = false; $noRice = false;
return false; return false;
} }
if($general->getVar('rice') <= $this->getHP() / 100){ if ($general->getVar('rice') <= $this->getHP() / 100) {
$noRice = true; $noRice = true;
return false; return false;
} }
return true; return true;
} }
function checkStatChange():bool{ function checkStatChange(): bool
{
return $this->general->checkStatChange(); return $this->general->checkStatChange();
} }
function finishBattle(){ function finishBattle()
if($this->isFinished){ {
if ($this->isFinished) {
return; return;
} }
$this->clearActivatedSkill(); $this->clearActivatedSkill();
@@ -313,7 +343,7 @@ class WarUnitGeneral extends WarUnit{
$general->increaseRankVar('killcrew', $this->killed); $general->increaseRankVar('killcrew', $this->killed);
$general->increaseRankVar('deathcrew', $this->dead); $general->increaseRankVar('deathcrew', $this->dead);
if($this->getOppose() instanceof WarUnitGeneral){ if ($this->getOppose() instanceof WarUnitGeneral) {
$general->increaseRankVar('killcrew_person', $this->killed); $general->increaseRankVar('killcrew_person', $this->killed);
$general->increaseRankVar('deathcrew_person', $this->dead); $general->increaseRankVar('deathcrew_person', $this->dead);
} }
@@ -325,10 +355,10 @@ class WarUnitGeneral extends WarUnit{
$this->checkStatChange(); $this->checkStatChange();
} }
function applyDB(\MeekroDB $db):bool{ function applyDB(\MeekroDB $db): bool
{
$affected = $this->getGeneral()->applyDB($db); $affected = $this->getGeneral()->applyDB($db);
$this->getLogger()->flush(); $this->getLogger()->flush();
return $affected; return $affected;
} }
} }
@@ -27,8 +27,10 @@ class che_계략발동 extends BaseWarUnitTrigger{
[$magic, $damage] = $selfEnv['magic']; [$magic, $damage] = $selfEnv['magic'];
$damage = $general->onCalcStat($general, 'warMagicFailDamage', $damage, $magic); $damage = $general->onCalcStat($general, 'warMagicFailDamage', $damage, $magic);
$damage = $oppose->getGeneral()->onCalcOpposeStat($general, 'warMagicFailDamage', $damage, $magic);
$josaUl = \sammo\JosaUtil::pick($magic, '을'); $josaUl = \sammo\JosaUtil::pick($magic, '을');
$general->getLogger()->pushGeneralBattleDetailLog("<D>{$magic}</>{$josaUl} <C>성공</>했다!", ActionLogger::PLAIN); $general->getLogger()->pushGeneralBattleDetailLog("<D>{$magic}</>{$josaUl} <C>성공</>했다!", ActionLogger::PLAIN);
$oppose->getLogger()->pushGeneralBattleDetailLog("<D>{$magic}</>에 당했다!", ActionLogger::PLAIN); $oppose->getLogger()->pushGeneralBattleDetailLog("<D>{$magic}</>에 당했다!", ActionLogger::PLAIN);
@@ -38,6 +38,8 @@ class che_계략시도 extends BaseWarUnitTrigger{
$magicTrialProb *= $crewType->magicCoef; $magicTrialProb *= $crewType->magicCoef;
$magicTrialProb = $general->onCalcStat($general, 'warMagicTrialProb', $magicTrialProb); $magicTrialProb = $general->onCalcStat($general, 'warMagicTrialProb', $magicTrialProb);
$magicTrialProb = $oppose->getGeneral()->onCalcOpposeStat($general, 'warMagicTrialProb', $magicTrialProb);
if($magicTrialProb <= 0){ if($magicTrialProb <= 0){
return true; return true;
} }
@@ -52,6 +54,7 @@ class che_계략시도 extends BaseWarUnitTrigger{
$magicSuccessProb = 0.7; $magicSuccessProb = 0.7;
$magicSuccessProb = $general->onCalcStat($general, 'warMagicSuccessProb', $magicSuccessProb); $magicSuccessProb = $general->onCalcStat($general, 'warMagicSuccessProb', $magicSuccessProb);
$magicSuccessProb = $oppose->getGeneral()->onCalcOpposeStat($general, 'warMagicSuccessProb', $magicSuccessProb);
if($self->hasActivatedSkill('계략약화')){ if($self->hasActivatedSkill('계략약화')){
$magicSuccessProb -= 0.1; //NOTE: 앞으로 이건 oppose의 onCalcStat에 들어가야하지 않을까? $magicSuccessProb -= 0.1; //NOTE: 앞으로 이건 oppose의 onCalcStat에 들어가야하지 않을까?
} }
@@ -66,6 +69,8 @@ class che_계략시도 extends BaseWarUnitTrigger{
} }
$successDamage = $general->onCalcStat($general, 'warMagicSuccessDamage', $successDamage, $magic); $successDamage = $general->onCalcStat($general, 'warMagicSuccessDamage', $successDamage, $magic);
$successDamage = $oppose->getGeneral()->onCalcOpposeStat($general, 'warMagicSuccessDamage', $successDamage, $magic);
$self->activateSkill('계략시도', $magic); $self->activateSkill('계략시도', $magic);
if(Util::randBool($magicSuccessProb)){ if(Util::randBool($magicSuccessProb)){
@@ -27,6 +27,7 @@ class che_계략실패 extends BaseWarUnitTrigger{
[$magic, $damage] = $selfEnv['magic']; [$magic, $damage] = $selfEnv['magic'];
$damage = $general->onCalcStat($general, 'warMagicFailDamage', $damage, $magic); $damage = $general->onCalcStat($general, 'warMagicFailDamage', $damage, $magic);
$damage = $oppose->getGeneral()->onCalcOpposeStat($general, 'warMagicFailDamage', $damage, $magic);
$josaUl = \sammo\JosaUtil::pick($magic, '을'); $josaUl = \sammo\JosaUtil::pick($magic, '을');
$general->getLogger()->pushGeneralBattleDetailLog("<D>{$magic}</>{$josaUl} <R>실패</>했다!", ActionLogger::PLAIN); $general->getLogger()->pushGeneralBattleDetailLog("<D>{$magic}</>{$josaUl} <R>실패</>했다!", ActionLogger::PLAIN);
+1
View File
@@ -10,6 +10,7 @@ interface iAction{
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float; public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float;
public function onCalcStat(General $general, string $statName, $value, $aux=null); public function onCalcStat(General $general, string $statName, $value, $aux=null);
public function onCalcOpposeStat(General $general, string $statName, $value, $aux=null);
public function onCalcStrategic(string $turnType, string $varType, $value); public function onCalcStrategic(string $turnType, string $varType, $value);
public function onCalcNationalIncome(string $type, $amount); public function onCalcNationalIncome(string $type, $amount);