diff --git a/hwe/func.php b/hwe/func.php index 363352fc..db89515c 100644 --- a/hwe/func.php +++ b/hwe/func.php @@ -2442,6 +2442,37 @@ function CharCritical($rate, $personal) { return $rate; } +function SabotageInjuryEx(array $cityGeneralList, bool $isSabotage):int{ + $injuryCount = 0; + if($isSabotage){ + $text = '계략으로 인해 부상을 당했습니다.'; + } + else{ + $text = '재난으로 인해 부상을 당했습니다.'; + } + + $db = DB::db(); + + foreach($cityGeneralList as $general){ + /** @var General $general */ + if(!Util::randBool(0.3)){ + continue; + } + $general->getLogger()->pushGeneralActionLog($text); + + $general->increaseVarWithLimit('injury', Util::randRangeInt(1, 16), 0, 80); + $general->multiplyVar('crew', 0.98); + $general->multiplyVar('atmos', 0.98); + $general->multiplyVar('train', 0.98); + + $general->applyDB($db); + + $injuryCount += 1; + } + + return $injuryCount; +} + function SabotageInjury($city, $type=0) { $db = DB::db(); $gameStor = KVStorage::getStorage($db, 'game_env'); diff --git a/hwe/func_process.old.php b/hwe/func_process.old.php index a0bbebd1..79ca10b7 100644 --- a/hwe/func_process.old.php +++ b/hwe/func_process.old.php @@ -23,8 +23,9 @@ function getGeneralLeadership($general, $withInjury, $withItem, $withStatAdjust, $leadership *= (100 - $general['injury']) / 100; } + //xxx: 징병 전특 때문에 새로 고쳐야함 if($withStatAdjust){ - if($general['special2'] == 72){ + if($general['special2'] == 'che_징병'){ $leadership *= 1.15; } } diff --git a/hwe/func_process_sabotage.php b/hwe/func_process_sabotage.php index ed2726c9..8c93b906 100644 --- a/hwe/func_process_sabotage.php +++ b/hwe/func_process_sabotage.php @@ -125,140 +125,6 @@ function checkSabotageFailCondition($general, $srcCity, $destCity, $reqGold, $re return null; } -function process_32(&$general) { - $db = DB::db(); - $gameStor = KVStorage::getStorage($db, 'game_env'); - - $date = substr($general['turntime'],11,5); - $sabotageName = '화계'; - $statType = 'intel'; - - [$year, $month, $develCost] = $gameStor->getValuesAsArray(['year','month','develcost']); - $logger = new ActionLogger($general['no'], $general['nation'], $year, $month); - - $reqGold = $develCost * 5; - $reqRice = $develCost * 5; - - $srcCityID = $general['city']; - $destCityID = DecodeCommand($general['turn0'])[1]; - - $dist = searchDistance($srcCityID, 5, false); - $srcCity = $db->queryFirstRow('SELECT city,nation,supply FROM city WHERE city=%i', $srcCityID); - $destCity = $db->queryFirstRow('SELECT city,name,level,nation,secu,secu2,supply,agri,comm,def,wall,trust FROM city WHERE city=%i',$destCityID); - $destCityName = $destCity['name']??null; - - $srcNationID = $general['nation']; - $destNationID = $destCity['nation']; - - $dipState = $db->queryFirstField('SELECT `state` FROM diplomacy WHERE me=%i AND you=%i', $srcNationID, $destNationID); - - $failReason = checkSabotageFailCondition($general, $srcCity, $destCity, $reqGold, $reqRice, $dipState); - if($failReason !== null){ - $logger->pushGeneralActionLog("{$failReason} {$sabotageName} 실패. <1>{$date}"); - return; - } - - $srcNation = getNationStaticInfo($srcNationID); - $destNation = getNationStaticInfo($destNationID); - - $generalList = $db->query('SELECT `no`,leader,horse,power,weap,intel,book,injury,level,special,special2 FROM general WHERE city=%i and nation=%i', $destCity['city'], $destCity['nation']); - - [ - $srcGenScore, - $srcSpecialScore, - $srcItemScore, - $srcNationScore, - ] = calcSabotageAttackScore($statType, $general, $srcNation); - - [ - $destGenScore, - $destCityScore, - $destSupplyScore - ] = calcSabotageDefendScore($statType, $generalList, $destCity, $destNation); - - $sabotageProb = ( - GameConst::$sabotageDefaultProb - + ($srcGenScore + $srcSpecialScore + $srcItemScore + $srcNationScore) - - ($destGenScore + $destCityScore + $destSupplyScore) - ); - - // 거리보정 - $sabotageProb /= Util::array_get($dist[$destCityID], 99); - - if(!Util::randBool($sabotageProb)){ - $josaYi = JosaUtil::pick($sabotageName, '이'); - $logger->pushGeneralActionLog("{$destCityName}에 {$sabotageName}{$josaYi} 실패했습니다. <1>$date"); - - $exp = Util::randRangeInt(1, 100); - $exp *= getCharExpMultiplier($general['personal']); - $ded = Util::randRangeInt(1, 70); - $ded *= getCharDedMultiplier($general['personal']); - - $general[$statType.'2'] += 1; - $general['gold'] -= $reqGold; - $general['rice'] -= $reqRice; - $db->update('general', [ - ($statType.'2') => $general[$statType.'2'], - 'resturn'=>'SUCCESS', - 'gold'=>$general['gold'], - 'rice'=>$general['rice'], - 'experience'=>$db->sqleval('experience + %i', Util::round($exp)), - 'dedication'=>$db->sqleval('dedication + %i', Util::round($ded)) - ], 'no=%i', $general['no']); - - checkAbilityEx($general['no'], $logger); - return; - } - - if($srcItemScore){ - $itemName = getItemName($general['item']); - $josaUl = JosaUtil::pick($itemName, '을'); - $logger->pushGeneralActionLog("{$itemName}{$josaUl} 사용!", ActionLogger::PLAIN); - $general['item'] = 0; - } - - $josaYi = JosaUtil::pick($destCityName, '이'); - $logger->pushGlobalActionLog("{$destCityName}{$josaYi} 불타고 있습니다."); - $josaYi = JosaUtil::pick($sabotageName, '이'); - $logger->pushGeneralActionLog("{$destCityName}에 {$sabotageName}{$josaYi} 성공했습니다. <1>$date"); - - $agriAmount = Util::valueFit(Util::randRangeInt(GameConst::$sabotageDamageMin, GameConst::$sabotageDamageMax), null, $destCity['agri']); - $commAmount = Util::valueFit(Util::randRangeInt(GameConst::$sabotageDamageMin, GameConst::$sabotageDamageMax), null, $destCity['comm']); - $destCity['agri'] -= $agriAmount; - $destCity['comm'] -= $commAmount; - - $db->update('city', [ - 'state'=>32, - 'agri'=>$destCity['agri'], - 'comm'=>$destCity['comm'] - ], 'city=%i', $destCityID); - - $injuryCount = SabotageInjury($destCityID); - - $logger->pushGeneralActionLog("도시의 농업이 {$agriAmount}, 상업이 {$commAmount}만큼 감소하고, 장수 {$injuryCount}명이 부상 당했습니다.", ActionLogger::PLAIN); - - $exp = Util::randRangeInt(201, 300); - $exp *= getCharExpMultiplier($general['personal']); - $ded = Util::randRangeInt(141, 210); - $ded *= getCharDedMultiplier($general['personal']); - - $general[$statType.'2'] += 1; - $general['gold'] -= $reqGold; - $general['rice'] -= $reqRice; - $db->update('general', [ - 'firenum' => $db->sqleval('firenum + 1'), - ($statType.'2') => $general[$statType.'2'], - 'resturn'=>'SUCCESS', - 'gold'=>$general['gold'], - 'rice'=>$general['rice'], - 'item'=>$general['item'], - 'experience'=>$db->sqleval('experience + %i', Util::round($exp)), - 'dedication'=>$db->sqleval('dedication + %i', Util::round($ded)) - ], 'no=%i', $general['no']); - - checkAbilityEx($general['no'], $logger); -} - function process_33(&$general) { $db = DB::db(); $gameStor = KVStorage::getStorage($db, 'game_env'); diff --git a/hwe/sammo/Command/General/che_화계.php b/hwe/sammo/Command/General/che_화계.php index 56ac5293..1d1ab888 100644 --- a/hwe/sammo/Command/General/che_화계.php +++ b/hwe/sammo/Command/General/che_화계.php @@ -145,7 +145,41 @@ class che_화계 extends Command\GeneralCommand{ } protected function affectDestCity(int $injuryCount){ - + $general = $this->generalObj; + $date = substr($general->getVar('turntime'),11,5); + + $logger = $general->getLogger(); + + $destCity = $this->destCity; + + $destCityName = $destCity['name']; + $destCityID = $destCity['city']; + + $commandName = $this->getName(); + + $agriAmount = Util::valueFit(Util::randRangeInt(GameConst::$sabotageDamageMin, GameConst::$sabotageDamageMax), null, $destCity['agri']); + $commAmount = Util::valueFit(Util::randRangeInt(GameConst::$sabotageDamageMin, GameConst::$sabotageDamageMax), null, $destCity['comm']); + $destCity['agri'] -= $agriAmount; + $destCity['comm'] -= $commAmount; + + $db->update('city', [ + 'state'=>32, + 'agri'=>$destCity['agri'], + 'comm'=>$destCity['comm'] + ], 'city=%i', $destCityID); + + $agriAmountText = number_format($agriAmount); + $commAmountText = number_format($commAmount); + + $josaYi = JosaUtil::pick($destCityName, '이'); + $logger->pushGlobalActionLog("{$destCityName}{$josaYi} 불타고 있습니다."); + $josaYi = JosaUtil::pick($commandName, '이'); + $logger->pushGeneralActionLog("{$destCityName}에 {$commandName}{$josaYi} 성공했습니다. <1>$date"); + + $logger->pushGeneralActionLog( + "도시의 농업이 {$agriAmountText}, 상업이 {$commAmountText}만큼 감소하고, 장수 {$injuryCount}명이 부상 당했습니다.", + ActionLogger::PLAIN + ); } public function run():bool{ @@ -164,7 +198,6 @@ class che_화계 extends Command\GeneralCommand{ $destCityName = $destCity['name']; $destCityID = $destCity['city']; $destNationID = $destCity['nation']; - $josaUl = JosaUtil::pick($destCityName, '을'); $commandName = $this->getName(); $statType = static::$statType; diff --git a/hwe/sammo/Constraint/ContraintHelper.php b/hwe/sammo/Constraint/ContraintHelper.php index 26a22d3c..38b97b36 100644 --- a/hwe/sammo/Constraint/ContraintHelper.php +++ b/hwe/sammo/Constraint/ContraintHelper.php @@ -112,7 +112,11 @@ class ConstraintHelper{ return [__FUNCTION__]; } - static function NotOccupiedCity():array{ + static function NotNeutralDestCity():array{ + return [__FUNCTION__]; + } + + static function NotOccupiedDestCity():array{ return [__FUNCTION__]; } @@ -128,7 +132,7 @@ class ConstraintHelper{ return [__FUNCTION__]; } - static function OccupiedCity(bool $allowNeutral=true):array{ + static function OccupiedCity(bool $allowNeutral=false):array{ return [__FUNCTION__, $allowNeutral]; } diff --git a/hwe/sammo/Constraint/NotNeutralDestCity.php b/hwe/sammo/Constraint/NotNeutralDestCity.php new file mode 100644 index 00000000..3e2564bf --- /dev/null +++ b/hwe/sammo/Constraint/NotNeutralDestCity.php @@ -0,0 +1,32 @@ +destCity)){ + if(!$throwExeception){return false; } + throw new \InvalidArgumentException("require nation in destCity"); + } + + return true; + } + + public function test():bool{ + $this->checkInputValues(); + $this->tested = true; + + if($this->destCity['nation'] != 0){ + return true; + } + + $this->reason = "공백지입니다."; + return false; + } +} \ No newline at end of file