징병 모병 추가, iAction 구조 일부 변경

This commit is contained in:
2018-10-20 23:31:32 +09:00
parent cee0d3f03e
commit 2de061203b
50 changed files with 560 additions and 183 deletions
-143
View File
@@ -399,149 +399,6 @@ function process_11(&$general, $type) {
$actLog->pushGeneralActionLog($log, ActionLogger::RAWTEXT);
}
function process_31(&$general) {
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
$connect=$db->get();
$log = [];
$alllog = [];
$history = [];
$date = substr($general['turntime'],11,5);
$msg = [];
$admin = $gameStor->getValues(['year', 'month', 'develcost']);
$dist = searchDistance($general['city'], 2, false);
$command = DecodeCommand($general['turn0']);
$destination = $command[1];
$query = "select * from city where city='$destination'";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$city = MYDB_fetch_array($result);
if(!$city) {
$log[] = "<C>●</>{$admin['month']}월:없는 도시입니다. 첩보 실패. <1>$date</>";
} elseif($general['gold'] < $admin['develcost']*3) {
$log[] = "<C>●</>{$admin['month']}월:자금이 모자랍니다. <G><b>{$city['name']}</b></>에 첩보 실패. <1>$date</>";
} elseif($general['rice'] < $admin['develcost']*3) {
$log[] = "<C>●</>{$admin['month']}월:군량이 모자랍니다. <G><b>{$city['name']}</b></>에 첩보 실패. <1>$date</>";
} elseif($general['nation'] == $city['nation']) {
$log[] = "<C>●</>{$admin['month']}월:아국입니다. <G><b>{$city['name']}</b></>에 첩보 실패. <1>$date</>";
// } elseif(!key_exists($destination, $dist)) {
// $log[] = "<C>●</>{$admin['month']}월:너무 멉니다. <G><b>{$city['name']}</b></>에 첩보 실패. <1>$date</>";
} else {
$query = "select crew,crewtype from general where city='$destination' and nation='{$city['nation']}'";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$gencount = MYDB_num_rows($result);
$crew = 0;
$typecount = [];
for($i=0; $i < $gencount; $i++) {
$gen = MYDB_fetch_array($result);
if($gen['crew'] != 0) {
if(!key_exists($gen['crewtype'], $typecount)){
$typecount[$gen['crewtype']] = 1;
}
else{
$typecount[$gen['crewtype']]+=1;
}
$crew += $gen['crew'];
}
}
if(!key_exists($destination, $dist)) {
$josaUl = JosaUtil::pick($city['name'], '을');
$alllog[] = "<C>●</>{$admin['month']}월:누군가가 <G><b>{$city['name']}</b></>{$josaUl} 살피는 것 같습니다.";
$log[] = "<C>●</>{$admin['month']}월:<G><b>{$city['name']}</b></>의 소문만 들을 수 있었습니다. <1>$date</>";
$log[] = "【<G>{$city['name']}</>】주민:{$city['pop']}, 민심:".round($city['trust'], 1).", 장수:$gencount, 병력:$crew";
} elseif($dist[$destination] == 2) {
$josaUl = JosaUtil::pick($city['name'], '을');
$alllog[] = "<C>●</>{$admin['month']}월:누군가가 <G><b>{$city['name']}</b></>{$josaUl} 살피는 것 같습니다.";
$log[] = "<C>●</>{$admin['month']}월:<G><b>{$city['name']}</b></>의 어느정도 정보를 얻었습니다. <1>$date</>";
$log[] = "【<M>첩보</>】농업:{$city['agri']}, 상업:{$city['comm']}, 치안:{$city['secu']}, 수비:{$city['def']}, 성벽:{$city['wall']}";
$log[] = "【<G>{$city['name']}</>】주민:{$city['pop']}, 민심:".round($city['trust'], 1).", 장수:$gencount, 병력:$crew";
} else {
$josaUl = JosaUtil::pick($city['name'], '을');
$alllog[] = "<C>●</>{$admin['month']}월:누군가가 <G><b>{$city['name']}</b></>{$josaUl} 살피는 것 같습니다.";
$log[] = "<C>●</>{$admin['month']}월:<G><b>{$city['name']}</b></>의 많은 정보를 얻었습니다. <1>$date</>";
$msg[] = "【<S>병종</>】";
foreach($typecount as $crewtype=>$cnt){
$crewtypeText = mb_substr(GameUnitConst::byID($crewtype)->name, 0, 2);
$msg[] = "{$crewtypeText}:{$cnt}";
}
$log[] = join(' ', $msg);
$msg = [];
$log[] = "【<M>첩보</>】농업:{$city['agri']}, 상업:{$city['comm']}, 치안:{$city['secu']}, 수비:{$city['def']}, 성벽:{$city['wall']}";
$log[] = "【<G>{$city['name']}</>】주민:{$city['pop']}, 민심:".round($city['trust'], 1).", 장수:$gencount, 병력:$crew";
if($general['nation'] != 0 && $city['nation'] != 0) {
$query = "select name,tech from nation where nation='{$city['nation']}'";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$yourTech = MYDB_fetch_array($result);
$query = "select tech from nation where nation='{$general['nation']}'";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$myTech = MYDB_fetch_array($result);
$diff = floor($yourTech['tech']) - floor($myTech['tech']); // 차이
if($diff >= 1000) { $log[] = "【<span class='ev_notice'>{$yourTech['name']}</span>】아국대비기술:<M>↑</>압도"; }
elseif($diff >= 250) { $log[] = "【<span class='ev_notice'>{$yourTech['name']}</span>】아국대비기술:<Y>▲</>우위"; }
elseif($diff >= -250) { $log[] = "【<span class='ev_notice'>{$yourTech['name']}</span>】아국대비기술:<W>↕</>대등"; }
elseif($diff >= -1000) { $log[] = "【<span class='ev_notice'>{$yourTech['name']}</span>】아국대비기술:<G>▼</>열위"; }
else { $log[] = "【<span class='ev_notice'>{$yourTech['name']}</span>】아국대비기술:<C>↓</>미미"; }
}
}
// 자금 하락 // 경험치 상승 // 공헌도, 명성 상승
$exp = rand() % 100 + 1;
$ded = rand() % 70 + 1;
// 성격 보정
$exp = CharExperience($exp, $general['personal']);
$ded = CharDedication($ded, $general['personal']);
$general['leader2']++;
$general['gold'] -= $admin['develcost']*3;
$general['rice'] -= $admin['develcost']*3;
$query = "update general set resturn='SUCCESS',gold='{$general['gold']}',rice='{$general['rice']}',leader2='{$general['leader2']}',dedication=dedication+'$ded',experience=experience+'$exp' where no='{$general['no']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$rawSpy = $db->queryFirstField('SELECT spy FROM nation WHERE nation = %i', $general['nation']);
if($rawSpy == ''){
$spyInfo = [];
}
else if(strpos($rawSpy, '|') !== false || is_numeric($rawSpy)){
//TODO: 0.8 버전 이후에는 삭제할 것. 이후 버전은 json으로 변경됨.
$spyInfo = [];
foreach(explode('|', $rawSpy) as $value){
$value = intval($value);
$cityNo = intdiv($value, 10);
$remainMonth = $value % 10;
$spyInfo[$cityNo] = $remainMonth;
}
}
else{
$spyInfo = Json::decode($rawSpy);
}
$spyInfo[$destination] = 3;
$db->update('nation', [
'spy'=>Json::encode($spyInfo, Json::EMPTY_ARRAY_IS_DICT)
], 'nation=%i', $general['nation']);
$log = checkAbility($general, $log);
}
pushGeneralPublicRecord($alllog, $admin['year'], $admin['month']);
pushGenLog($general, $log);
}
function process_48(&$general) {
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
+3 -3
View File
@@ -20,11 +20,11 @@ if(!$action){
$defaultCheck = [
'string'=>[
'crewType', 'nationName', 'optionText', 'itemType'
'nationName', 'optionText', 'itemType'
],
'integer'=>[
'destGeneralID', 'destCityID', 'destNationID',
'amountMoney', 'amountCrew', 'colorType', 'nationType'
'crewType', 'destGeneralID', 'destCityID', 'destNationID',
'amount', 'colorType', 'nationType'
],
'boolean'=>[
'isGold', 'buyRice'
+1 -1
View File
@@ -11,7 +11,7 @@ class che_덕가 implements iAction{
static $pros = '치안↑ 인구↑ 민심↑';
static $cons = '쌀수입↓ 수성↓';
public function onCalcDomestic(string $turnType, string $varType, float $value):float{
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float{
if($turnType == '치안'){
if($varType == 'score') return $value * 1.1;
if($varType == 'cost') return $value * 0.8;
+1 -1
View File
@@ -11,7 +11,7 @@ class che_도가 implements iAction{
static $pros = '인구↑';
static $cons = '기술↓ 치안↓';
public function onCalcDomestic(string $turnType, string $varType, float $value):float{
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float{
if($turnType == '기술'){
if($varType == 'score') return $value * 0.9;
if($varType == 'cost') return $value * 1.2;
+1 -1
View File
@@ -11,7 +11,7 @@ class che_도적 implements iAction{
static $pros = '계략↑';
static $cons = '금수입↓ 치안↓ 민심↓';
public function onCalcDomestic(string $turnType, string $varType, float $value):float{
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float{
if($turnType == '치안'){
if($varType == 'score') return $value * 0.9;
if($varType == 'cost') return $value * 1.2;
+1 -1
View File
@@ -11,7 +11,7 @@ class che_명가 implements iAction{
static $pros = '기술↑ 인구↑';
static $cons = '쌀수입↓ 수성↓';
public function onCalcDomestic(string $turnType, string $varType, float $value):float{
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float{
if($turnType == '기술'){
if($varType == 'score') return $value * 1.1;
if($varType == 'cost') return $value * 0.8;
+1 -1
View File
@@ -11,7 +11,7 @@ class che_묵가 implements iAction{
static $pros = '수성↑';
static $cons = '기술↓';
public function onCalcDomestic(string $turnType, string $varType, float $value):float{
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float{
if($turnType == '수비' || $turnType == '성벽'){
if($varType == 'score') return $value * 1.1;
if($varType == 'cost') return $value * 0.8;
+1 -1
View File
@@ -11,7 +11,7 @@ class che_법가 implements iAction{
static $pros = '금수입↑ 치안↑';
static $cons = '인구↓ 민심↓';
public function onCalcDomestic(string $turnType, string $varType, float $value):float{
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float{
if($turnType == '치안'){
if($varType == 'score') return $value * 1.1;
if($varType == 'cost') return $value * 0.8;
+1 -1
View File
@@ -11,7 +11,7 @@ class che_병가 implements iAction{
static $pros = '기술↑ 수성↑';
static $cons = '인구↓ 민심↓';
public function onCalcDomestic(string $turnType, string $varType, float $value):float{
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float{
if($turnType == '기술'){
if($varType == 'score') return $value * 1.1;
if($varType == 'cost') return $value * 0.8;
+1 -1
View File
@@ -11,7 +11,7 @@ class che_불가 implements iAction{
static $pros = '민심↑ 수성↑';
static $cons = '금수입↓';
public function onCalcDomestic(string $turnType, string $varType, float $value):float{
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float{
if($turnType == '민심' || $turnType == '인구'){
if($varType == 'score') return $value * 1.1;
if($varType == 'cost') return $value * 0.8;
@@ -12,7 +12,7 @@ class che_오두미도 implements iAction{
static $cons = '기술↓ 수성↓ 내정↓';
public function onCalcDomestic(string $turnType, string $varType, float $value):float{
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float{
if($turnType == '기술'){
if($varType == 'score') return $value * 0.9;
if($varType == 'cost') return $value * 1.2;
+1 -1
View File
@@ -11,7 +11,7 @@ class che_유가 implements iAction{
static $pros = '내정↑ 민심↑';
static $cons = '쌀수입↓';
public function onCalcDomestic(string $turnType, string $varType, float $value):float{
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float{
if($turnType == '농업' || $turnType == '상업'){
if($varType == 'score') return $value * 1.1;
if($varType == 'cost') return $value * 0.8;
+1 -1
View File
@@ -11,7 +11,7 @@ class che_음양가 implements iAction{
static $pros = '내정↑ 인구↑';
static $cons = '기술↓ 전략↓';
public function onCalcDomestic(string $turnType, string $varType, float $value):float{
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float{
if($turnType == '농업' || $turnType == '상업'){
if($varType == 'score') return $value * 1.1;
if($varType == 'cost') return $value * 0.8;
+1 -1
View File
@@ -11,7 +11,7 @@ class che_종횡가 implements iAction{
static $pros = '전략↑ 수성↑';
static $cons = '금수입↓ 내정↓';
public function onCalcDomestic(string $turnType, string $varType, float $value):float{
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float{
if($turnType == '수비' || $turnType == '성벽'){
if($varType == 'score') return $value * 1.1;
if($varType == 'cost') return $value * 0.8;
+1 -1
View File
@@ -11,7 +11,7 @@ class che_태평도 implements iAction{
static $pros = '인구↑ 민심↑';
static $cons = '기술↓ 수성↓';
public function onCalcDomestic(string $turnType, string $varType, float $value):float{
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float{
if($turnType == '민심' || $turnType == '인구'){
if($varType == 'score') return $value * 1.1;
if($varType == 'cost') return $value * 0.8;
+1 -1
View File
@@ -10,7 +10,7 @@ class che_안전 implements iAction{
static $name = '안전';
static $info = '사기 -5, 징·모병 비용 -20%';
public function onCalcDomestic(string $turnType, string $varType, float $value):float{
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float{
if(in_array($turnType, ['징병', '모병'])){
if($varType == 'cost'){
return $value * 0.8;
+1 -1
View File
@@ -10,7 +10,7 @@ class che_유지 implements iAction{
static $name = '안전';
static $info = '훈련 -5, 징·모병 비용 -20%';
public function onCalcDomestic(string $turnType, string $varType, float $value):float{
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float{
if(in_array($turnType, ['징병', '모병'])){
if($varType == 'cost'){
return $value * 0.8;
+1 -1
View File
@@ -10,7 +10,7 @@ class che_은둔 implements iAction{
static $name = '은둔';
static $info = '명성 -10%, 계급 -10%, 사기 -5, 훈련 -5, 단련 성공률 +10%';
public function onCalcDomestic(string $turnType, string $varType, float $value):float{
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float{
if($turnType == '단련'){
if($varType == 'success'){
return $value + 0.1;
+1 -1
View File
@@ -10,7 +10,7 @@ class che_의협 implements iAction{
static $name = '의협';
static $info = '사기 +5, 징·모병 비용 +20%';
public function onCalcDomestic(string $turnType, string $varType, float $value):float{
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float{
if(in_array($turnType, ['징병', '모병'])){
if($varType == 'cost'){
return $value * 1.2;
+1 -1
View File
@@ -10,7 +10,7 @@ class che_재간 implements iAction{
static $name = '재간';
static $info = '명성 -10%, 징·모병 비용 -20%';
public function onCalcDomestic(string $turnType, string $varType, float $value):float{
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float{
if(in_array($turnType, ['징병', '모병'])){
if($varType == 'cost'){
return $value * 0.8;
+1 -1
View File
@@ -10,7 +10,7 @@ class che_출세 implements iAction{
static $name = '출세';
static $info = '명성 +10%, 징·모병 비용 +20%';
public function onCalcDomestic(string $turnType, string $varType, float $value):float{
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float{
if(in_array($turnType, ['징병', '모병'])){
if($varType == 'cost'){
return $value * 1.2;
+1 -1
View File
@@ -10,7 +10,7 @@ class che_패권 implements iAction{
static $name = '패권';
static $info = '훈련 +5, 징·모병 비용 +20%';
public function onCalcDomestic(string $turnType, string $varType, float $value):float{
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float{
if(in_array($turnType, ['징병', '모병'])){
if($varType == 'cost'){
return $value * 1.2;
@@ -17,7 +17,7 @@ class che_경작 implements iAction{
SpecialityConst::STAT_INTEL
];
public function onCalcDomestic(string $turnType, string $varType, float $value):float{
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float{
if($turnType == '농업'){
if($varType == 'score') return $value * 1.1;
if($varType == 'cost') return $value * 0.8;
@@ -19,7 +19,7 @@ class che_귀모 implements iAction{
SpecialityConst::STAT_INTEL
];
public function onCalcDomestic(string $turnType, string $varType, float $value):float{
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float{
if($turnType == '계략'){
if($varType == 'success') return $value + 0.2;
}
@@ -17,7 +17,7 @@ class che_발명 implements iAction{
SpecialityConst::STAT_INTEL
];
public function onCalcDomestic(string $turnType, string $varType, float $value):float{
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float{
if($turnType == '기술'){
if($varType == 'score') return $value * 1.1;
if($varType == 'cost') return $value * 0.8;
@@ -17,7 +17,7 @@ class che_상재 implements iAction{
SpecialityConst::STAT_INTEL
];
public function onCalcDomestic(string $turnType, string $varType, float $value):float{
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float{
if($turnType == '상업'){
if($varType == 'score') return $value * 1.1;
if($varType == 'cost') return $value * 0.8;
@@ -17,7 +17,7 @@ class che_수비 implements iAction{
SpecialityConst::STAT_POWER
];
public function onCalcDomestic(string $turnType, string $varType, float $value):float{
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float{
if($turnType == '수비'){
if($varType == 'score') return $value * 1.1;
if($varType == 'cost') return $value * 0.8;
@@ -17,7 +17,7 @@ class che_통찰 implements iAction{
SpecialityConst::STAT_LEADERSHIP
];
public function onCalcDomestic(string $turnType, string $varType, float $value):float{
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float{
if($turnType == '민심' || $turnType == '인구'){
if($varType == 'score') return $value * 1.1;
if($varType == 'cost') return $value * 0.8;
@@ -17,7 +17,7 @@ class che_축성 implements iAction{
SpecialityConst::STAT_POWER
];
public function onCalcDomestic(string $turnType, string $varType, float $value):float{
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float{
if($turnType == '성벽'){
if($varType == 'score') return $value * 1.1;
if($varType == 'cost') return $value * 0.8;
@@ -17,7 +17,7 @@ class che_통찰 implements iAction{
SpecialityConst::STAT_POWER
];
public function onCalcDomestic(string $turnType, string $varType, float $value):float{
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float{
if($turnType == '치안'){
if($varType == 'score') return $value * 1.1;
if($varType == 'cost') return $value * 0.8;
@@ -3,6 +3,7 @@ namespace sammo\ActionSpecialWar;
use \sammo\iAction;
use \sammo\General;
use \sammo\SpecialityConst;
use \sammo\GameUnitConst;
class che_공성 implements iAction{
use \sammo\DefaultAction;
@@ -18,4 +19,12 @@ class che_공성 implements iAction{
SpecialityConst::STAT_POWER | SpecialityConst::REQ_DEXTERITY | SpecialityConst::ARMY_SIEGE,
SpecialityConst::STAT_INTEL | SpecialityConst::REQ_DEXTERITY | SpecialityConst::ARMY_SIEGE,
];
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float{
if(in_array($turnType, ['징병', '모병'])){
if($varType == 'cost' && $aux['armType'] == GameUnitConst::T_SIEGE) return $value * 0.9;
}
return $value;
}
}
+10
View File
@@ -4,6 +4,8 @@ use \sammo\iAction;
use \sammo\General;
use \sammo\SpecialityConst;
use \sammo\GameUnitConst;
class che_궁병 implements iAction{
use \sammo\DefaultAction;
@@ -17,4 +19,12 @@ class che_궁병 implements iAction{
SpecialityConst::STAT_LEADERSHIP | SpecialityConst::REQ_DEXTERITY | SpecialityConst::ARMY_ARCHER,
SpecialityConst::STAT_POWER | SpecialityConst::REQ_DEXTERITY | SpecialityConst::ARMY_ARCHER
];
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float{
if(in_array($turnType, ['징병', '모병'])){
if($varType == 'cost' && $aux['armType'] == GameUnitConst::T_ARCHER) return $value * 0.9;
}
return $value;
}
}
@@ -3,6 +3,7 @@ namespace sammo\ActionSpecialWar;
use \sammo\iAction;
use \sammo\General;
use \sammo\SpecialityConst;
use \sammo\GameUnitConst;
class che_귀병 implements iAction{
use \sammo\DefaultAction;
@@ -16,4 +17,12 @@ class che_귀병 implements iAction{
static $type = [
SpecialityConst::STAT_INTEL | SpecialityConst::ARMY_WIZARD | SpecialityConst::REQ_DEXTERITY
];
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float{
if(in_array($turnType, ['징병', '모병'])){
if($varType == 'cost' && $aux['armType'] == GameUnitConst::T_WIZARD) return $value * 0.9;
}
return $value;
}
}
@@ -3,6 +3,7 @@ namespace sammo\ActionSpecialWar;
use \sammo\iAction;
use \sammo\General;
use \sammo\SpecialityConst;
use \sammo\GameUnitConst;
class che_기병 implements iAction{
use \sammo\DefaultAction;
@@ -17,4 +18,12 @@ class che_기병 implements iAction{
SpecialityConst::STAT_LEADERSHIP | SpecialityConst::REQ_DEXTERITY | SpecialityConst::ARMY_CAVALRY,
SpecialityConst::STAT_POWER | SpecialityConst::REQ_DEXTERITY | SpecialityConst::ARMY_CAVALRY
];
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float{
if(in_array($turnType, ['징병', '모병'])){
if($varType == 'cost' && $aux['armType'] == GameUnitConst::T_CAVALRY) return $value * 0.9;
}
return $value;
}
}
@@ -3,6 +3,7 @@ namespace sammo\ActionSpecialWar;
use \sammo\iAction;
use \sammo\General;
use \sammo\SpecialityConst;
use \sammo\GameUnitConst;
class che_보병 implements iAction{
use \sammo\DefaultAction;
@@ -17,4 +18,12 @@ class che_보병 implements iAction{
SpecialityConst::STAT_LEADERSHIP | SpecialityConst::REQ_DEXTERITY | SpecialityConst::ARMY_FOOTMAN,
SpecialityConst::STAT_POWER | SpecialityConst::REQ_DEXTERITY | SpecialityConst::ARMY_FOOTMAN
];
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float{
if(in_array($turnType, ['징병', '모병'])){
if($varType == 'cost' && $aux['armType'] == GameUnitConst::T_FOOTMAN) return $value * 0.9;
}
return $value;
}
}
+1 -1
View File
@@ -17,7 +17,7 @@ class che_신산 implements iAction{
SpecialityConst::STAT_INTEL,
];
public function onCalcDomestic(string $turnType, string $varType, float $value):float{
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float{
if($turnType == '계략'){
if($varType == 'success') return $value + 0.1;
}
@@ -18,4 +18,12 @@ class che_징병 implements iAction{
SpecialityConst::STAT_POWER,
SpecialityConst::STAT_INTEL
];
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float{
if(in_array($turnType, ['징병', '모병'])){
if($varType == 'cost') return $value * 0.5;
}
return $value;
}
}
+10
View File
@@ -41,7 +41,17 @@ abstract class BaseCommand{
protected $alternative = null;
static private $isInitStatic = false;
protected static function initStatic(){
}
public function __construct(General $generalObj, array $env, $arg = null){
if(!static::$isInitStatic){
static::initStatic();
static::$isInitStatic = true;
}
$this->generalObj = $generalObj;
$this->logger = $generalObj->getLogger();
$this->env = $env;
+24
View File
@@ -0,0 +1,24 @@
<?php
namespace sammo\GeneralCommand;
use \sammo\{
DB, Util, JosaUtil,
General,
ActionLogger,
GameConst, GameUnitConst,
LastTurn,
Command
};
class che_모병 extends Command\GeneralCommand{
static protected $actionName = '모병';
static protected $costOffset = 2;
protected static function initStatic()
{
static::$defaultTrain = GameConst::$defaultTrainHigh;
static::$defaultAtmos = GameConst::$defaultAtmosHigh;
}
}
@@ -56,7 +56,7 @@ class che_전투태세 extends Command\GeneralCommand{
}
public function getPreReqTurn():int{
return 0;
return 3;
}
public function getPostReqTurn():int{
@@ -76,17 +76,19 @@ class che_전투태세 extends Command\GeneralCommand{
$lastTurn = $general->getLastTurn();
$turnResult = new LastTurn(static::getName(), $this->arg);
$reqTurn = $this->getPreReqTurn();
if($lastTurn->getCommand() != static::getName()){
$turnResult->setTerm(1);
}
else if($lastTurn->getTerm() == 3){
else if($lastTurn->getTerm() == $reqTurn){
$turnResult->setTerm(1);
}
else if($lastTurn->getTerm() < 3){
else if($lastTurn->getTerm() < $reqTurn){
$turnResult->setTerm($lastTurn->getTerm()+1);
}
else{
throw new MustNotBeReachedException('전투 태세는 1~3까지만 가능함');
throw new MustNotBeReachedException('전투 태세에 올바른 턴이 아님');
}
$term = $turnResult->getTerm();
+198
View File
@@ -0,0 +1,198 @@
<?php
namespace sammo\GeneralCommand;
use \sammo\{
DB, Util, JosaUtil,
General,
ActionLogger,
GameConst, GameUnitConst,
LastTurn,
Command
};
use function \sammo\{
uniqueItemEx
};
use \sammo\Constraint\Constraint;
class che_징병 extends Command\GeneralCommand{
/**
* @var \sammo\GameUnitDetail $reqCrewType
*/
static protected $actionName = '징병';
static protected $costOffset = 1;
static protected $defaultTrain;
static protected $defaultAtmos;
protected $reqCrew = 0;
protected $reqCrewType;
protected $currCrewType;
protected static function initStatic()
{
static::$defaultTrain = GameConst::$defaultTrainLow;
static::$defaultAtmos = GameConst::$defaultAtmosLow;
}
protected function init(){
$general = $this->generalObj;
$this->setCity();
$this->setNation(['tech']);
$leadership = $general->getLeadership();
$currCrewType = $general->getCrewTypeObj();
$maxCrew = $leadership * 100;
$reqCrewType = GameUnitConst::byID($this->arg['crewType']);
if($reqCrewType->id == $currCrewType->id){
$maxCrew -= $general->getVar('crew');
}
$reqCrew = Util::valueFit($this->arg['amount'], 100, $maxCrew);
$this->reqCrew = $reqCrew;
$this->reqCrewType = $reqCrewType;
$this->currCrewType = $currCrewType;
[$reqGold, $reqRice] = $this->getCost();
$this->runnableConstraints=[
['NoNeutral'],
['OccupiedCity'],
['ReqCityCapacity', 'pop', '주민', 30000 + $reqCrew],
['ReqCityTrust', 20],
['ReqGeneralGold', $reqGold],
['ReqGeneralRice', $reqRice],
['ReqGeneralCrewMargin', $reqCrewType->id],
['AvailableRecruitCrewType', $reqCrewType->id]
];
}
protected function argTest():bool{
if(!key_exists('crewType', $this->arg)){
return false;
}
if(!key_exists('amount', $this->arg)){
return false;
}
$crewType = $this->arg['crewType'];
$amount = $this->arg['amountCrew'];
if(!is_int($crewType)){
return false;
}
if(!is_int($amount)){
return false;
}
if(GameUnitConst::byID($crewType) === null){
return false;
}
if($amount < 100){
return false;
}
$this->arg = [
'crewType'=>$crewType,
'amount'=>$amount
];
return true;
}
public function getCost():array{
if($this->reqCrewType === null || $this->reqCrew){
return [0, 0];
//throw new \RuntimeException('요구사항 초기화가 이뤄지지 않았음');
}
$reqGold = $this->reqCrewType->costWithTech($this->nation['tech'], $this->reqCrew);
$reqGold = $general->onCalcDomestic('징병', 'cost', $reqGold, ['armType'=>$this->reqCrewType->armType]);
$reqGold *= static::$costOffset;
$reqRice = $this->reqCrew / 100;
return [$reqGold, $reqRice];
}
public function getPreReqTurn():int{
return 0;
}
public function getPostReqTurn():int{
return 0;
}
public function run():bool{
if(!$this->isRunnable()){
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
}
$db = DB::db();
$general = $this->generalObj;
$date = substr($general->getVar('turntime'),11,5);
$reqCrew = $this->reqCrew;
$reqCrewText = number_format($reqCrew);
$reqCrewType = $this->reqCrewType;
$currCrew = $general->getVar('crew');
$currCrewType = $this->currCrewType;
$crewTypeName = $reqCrewType->name;
$josaUl = JosaUtil::pick($crewTypeName, '을');
$logger = $general->getLogger();
if($reqCrewType->id == $currCrewType->id && $currCrew > 0){
$logger->pushGeneralActionLog("{$crewTypeName}{$josaUl} <C>{$reqCrewText}</>명을 추가{$this->getName()}했습니다. <1>$date</>");
$train = ($currCrew * $general->getVar('train') + $reqCrew * static::$defaultTrain) / ($currCrew + $reqCrew);
$atmos = ($currCrew * $general->getVar('atmos') + $reqCrew * static::$defaultAtmos) / ($currCrew + $reqCrew);
$general->increaseVar('crew', $reqCrew);
$general->setVar('train', $train);
$general->setVar('atmos', $atmos);
}
else{
$logger->pushGeneralActionLog("{$crewTypeName}{$josaUl} <C>{$reqCrewText}</>명을 {$this->getName()}했습니다. <1>$date</>");
$general->setVar('crewtype', $reqCrewType->id);
$general->setVar('crew', $reqCrew);
$general->setVar('train', static::$defaultTrain);
$general->setVar('atmos', static::$defaultAtmos);
}
$newTrust = Util::valueFit($this->city['trust'] - ($reqCrew / $this->city['pop']) / static::$costOffset * 100, 0);
$db->update('city', [
'trust'=>$newTrust,
'pop'=>$this->city['pop'] - $reqCrew
], 'city=%i', $general->getCityID());
$exp = Util::round($reqCrew / 100);
$ded = Util::round($reqCrew / 100);
$exp = $general->onPreGeneralStatUpdate($general, 'experience', $exp);
$ded = $general->onPreGeneralStatUpdate($general, 'dedication', $ded);
$general->addDex($general->getCrewTypeObj(), $reqCrew / 100, false);
[$reqGold, $reqRice] = $this->getCost();
$general->increaseVar('experience', $exp);
$general->increaseVar('dedication', $ded);
$general->increaseVarWithLimit('gold', -$reqGold, 0);
$general->increaseVarWithLimit('rice', -$reqRice, 0);
$general->increaseVar('leader2', 1);
$general->setResultTurn(new LastTurn(static::getName(), $this->arg));
$general->checkStatChange();
$general->applyDB($db);
uniqueItemEx($general->getID(), $logger);
return true;
}
}
@@ -0,0 +1,61 @@
<?php
namespace sammo\Constraint;
use \sammo\GameUnitConst;
use \sammo\DB;
class AvailableRecruitCrewType extends Constraint{
const REQ_VALUES = Constraint::REQ_NATION|Constraint::REQ_INT_ARG;
public function checkInputValues(bool $throwExeception=true){
if(!parent::checkInputValues($throwExeception) && !$throwException){
return false;
}
if(!key_exists('nation', $this->nation)){
if(!$throwExeception){return false; }
throw new \InvalidArgumentException("require nation in nation");
}
if(!key_exists('tech', $this->nation)){
if(!$throwExeception){return false; }
throw new \InvalidArgumentException("require tecg in nation");
}
if(GameUnitConst::byID($this->arg) === null){
if(!$throwExeception){return false; }
throw new \InvalidArgumentException("invalid crewtype");
}
return true;
}
public function test():bool{
$this->checkInputValues();
$this->tested = true;
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
[$startyear, $year] = $gameStor->getValuesAsArray(['startyear', 'year']);
$nationID = $this->nation['nation'];
$tech = $this->nation['tech'];
$ownCities = [];
$ownRegions = [];
foreach($db->queryFirstColumn('SELECT city FROM city WHERE nation = %i', $nationID) as $ownCity){
$ownCities[$ownCity] = 1;
$ownRegions[CityConst::byId($ownCity)->region] = 1;
}
$crewType = GameUnitConst::byID($this->arg);
if($crewType->isValid($ownCities, $ownRegions, $year = $startyear, $tech)){
return true;
}
$this->reason = "현재 선택할 수 없는 병종입니다.";
return false;
}
}
+70
View File
@@ -0,0 +1,70 @@
<?php
namespace sammo\Constraint;
use \sammo\JosaUtil;
use \sammo\Util;
class ReqCityCapacity extends Constraint{
const REQ_VALUES = Constraint::REQ_CITY|Constraint::REQ_ARRAY_ARG;
protected $key;
protected $maxKey;
protected $keyNick;
protected $reqVal;
public function checkInputValues(bool $throwExeception=true){
if(!parent::checkInputValues($throwExeception) && !$throwException){
return false;
}
[$this->key, $this->keyNick, $this->reqVal] = $this->arg;
$this->maxKey = $this->key.'2';
if(!key_exists($this->key, $this->city)){
if(!$throwExeception){return false; }
throw new \InvalidArgumentException("require {$this->key} in city");
}
if(is_numeric($this->reqVal)){
$this->isPercent = false;
}
else if(is_str($this->reqVal)){
$this->reqVal = Util::convPercentStrToFloat($this->reqVal);
if($this->reqVal === null){
if(!$throwExeception){return false; }
throw new \InvalidArgumentException("require valid reqVal(percentStr|numeric) format");
}
if(!key_exists($this->maxKey, $this->city)){
if(!$throwExeception){return false; }
throw new \InvalidArgumentException("require {$this->maxKey} in city");
}
$this->isPercent = true;
}
return true;
}
public function test():bool{
$this->checkInputValues();
$this->tested = true;
if($this->isPercent){
if($this->city[$this->key] >= $this->city[$this->maxKey] * $this->reqVal){
return true;
}
}
else{
if($this->city[$this->key] >= $this->reqVal){
return true;
}
}
$josaYi = JosaUtil::pick($keyNick, '이');
$this->reason = "{$keyNick}{$josaUn} 모자랍니다.";
return false;
}
}
+42
View File
@@ -0,0 +1,42 @@
<?php
namespace sammo\Constraint;
use \sammo\JosaUtil;
class RemainCityTrust extends Constraint{
const REQ_VALUES = Constraint::REQ_CITY|Constraint::REQ_NUMERIC_ARG;
protected $key;
protected $maxKey;
protected $keyNick;
public function checkInputValues(bool $throwExeception=true){
if(!parent::checkInputValues($throwExeception) && !$throwException){
return false;
}
$this->keyNick = '민심';
$this->key = 'trust';
$this->reqVal = $this->arg;
if(!key_exists($this->key, $this->city)){
if(!$throwExeception){return false; }
throw new \InvalidArgumentException("require {$this->key} in city");
}
return true;
}
public function test():bool{
$this->checkInputValues();
$this->tested = true;
if($this->city[$this->key] >= $this->reqVal){
return true;
}
$this->reason = "민심이 낮아 주민들이 도망갑니다.";
return false;
}
}
@@ -0,0 +1,46 @@
<?php
namespace sammo\Constraint;
use sammo\GameConst;
use sammo\GameUnitConst;
use sammo\General;
class ReqGeneralCrewMargin extends Constraint{
const REQ_VALUES = Constraint::REQ_GENERAL|Constraint::REQ_INT_ARG;
public function checkInputValues(bool $throwExeception=true){
if(!parent::checkInputValues($throwExeception) && !$throwException){
return false;
}
foreach(['leader','power','intel','crew','crewtype','nation','level'] as $key){
if(!key_exists($key, $this->general)){
if(!$throwExeception){return false; }
throw new \InvalidArgumentException("require {$key} in general");
}
}
return true;
}
public function test():bool{
$this->checkInputValues();
$this->tested = true;
if($crewType != $this->general['crewtype']){
return true;
}
//XXX: 왜 General -> obj -> General 변환을 하고 있나?
$generalObj = new General($this->general, null, null, null, false);
$leadership = $generalObj->getLeadership();
$crew = $this->general['crew'];
if($leadership * 100 > $crew){
return true;
}
$this->reason = "이미 많은 병력을 보유하고 있습니다.";
return false;
}
}
+1 -1
View File
@@ -5,7 +5,7 @@ trait DefaultAction{
public function getPreTurnExecuteTriggerList(General $general):?GeneralTriggerCaller{
return null;
}
public function onCalcDomestic(string $turnType, string $varType, float $value):float{
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float{
return $value;
}
+1 -1
View File
@@ -371,7 +371,7 @@ class General implements iAction{
}
return $caller;
}
public function onCalcDomestic(string $turnType, string $varType, float $value):float{
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float{
foreach(array_merge([
$this->nationType,
$this->levelObj,
+1 -1
View File
@@ -33,7 +33,7 @@ class TriggerGeneralLevel implements iAction{
}
}
public function onCalcDomestic(string $turnType, string $varType, float $value):float{
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float{
if($turnType == '농업' || $turnType == '상업'){
if(in_array($this->generalLevel, [12, 11, 9, 7, 5, 3])){
return $value * 1.05;
+1 -1
View File
@@ -4,7 +4,7 @@ namespace sammo;
interface iAction{
//TODO: 능력치는?
public function getPreTurnExecuteTriggerList(General $general):?GeneralTriggerCaller;
public function onCalcDomestic(string $turnType, string $varType, float $value):float;
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float;
public function onPreGeneralStatUpdate(General $general, string $statName, $value);
+13
View File
@@ -415,6 +415,19 @@ class Util extends \utilphp\util
{
return self::randF() < $prob;
}
/**
* aaa(.bbb)?% 의 텍스트를 float으로 변환. 100% = 1.0
* @return float|null
*/
public static function convPercentStrToFloat(string $text):?float{
preg_match('/^(\d+(\.\d+)?)\%$/', $text, $matches);
if($matches === null){
return null;
}
return (float)$matches[1] / 100;
}
/**