Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e0d1a0a612 | ||
|
|
3040996671 | ||
|
|
dd830e7500 | ||
|
|
d2dfe2c418 | ||
|
|
139fb6b6e0 | ||
|
|
c4f6976c42 | ||
|
|
ab428fc104 | ||
|
|
aa97f78acd | ||
|
|
dbce900aeb | ||
|
|
30b382e2e7 | ||
|
|
433c4abb86 | ||
|
|
64404e4092 | ||
|
|
08d483af8a | ||
|
|
fa19c17941 | ||
|
|
c896a999ad | ||
|
|
f9bca935ac | ||
|
|
7abf274d89 | ||
|
|
e2ad417306 | ||
|
|
2ea9655f6b | ||
|
|
f450d5d9de | ||
|
|
f8f4b73a09 | ||
|
|
926d96732d | ||
|
|
167113d6a3 | ||
|
|
911cb614a5 | ||
|
|
7a939b7024 | ||
|
|
6e57a60997 | ||
|
|
9f1151e699 | ||
|
|
3fbe1fb63d | ||
|
|
d4906eec5a | ||
|
|
ebe0663e74 | ||
|
|
04c89b9711 | ||
|
|
4f2bc874e5 | ||
|
|
316ac5c3c8 | ||
|
|
7882aa667e | ||
|
|
8b8d5eecbf | ||
|
|
65b76643ee |
+1
-1
@@ -117,7 +117,7 @@ function logError(string $err, string $errstr, string $errpath, array $trace)
|
||||
]);
|
||||
}
|
||||
|
||||
function logErrorByCustomHandler(int $errno, string $errstr, string $errfile, int $errline, array $errcontext)
|
||||
function logErrorByCustomHandler(int $errno, string $errstr, string $errfile, int $errline, array $errcontext=null)
|
||||
{
|
||||
if (!(error_reporting() & $errno)) {
|
||||
// This error code is not included in error_reporting, so let it fall
|
||||
|
||||
+6
-1
@@ -59,8 +59,13 @@ foreach (getAllNationStaticInfo() as $nation) {
|
||||
$nationName[$nation['nation']] = $nation['name'];
|
||||
}
|
||||
|
||||
|
||||
$generalList = $db->query('SELECT npc,nation,name,owner_name,special,special2,personal,leadership,strength,intel,leadership+strength+intel as sum,explevel,experience,dedication from general where npc=1');
|
||||
$generalListFromPool = $db->query('SELECT npc,nation,name,owner_name,special,special2,personal,leadership,strength,intel,leadership+strength+intel as sum,explevel,experience,dedication from general JOIN select_pool on general.no = select_pool.general_id where npc=0');
|
||||
|
||||
if($generalListFromPool){
|
||||
$generalList = array_merge($generalListFromPool, $generalList);
|
||||
}
|
||||
|
||||
$sortType = [
|
||||
1 => ['name', true],
|
||||
2 => ['nation', true],
|
||||
|
||||
@@ -162,6 +162,7 @@ if(!key_exists($citylist, CityConst::all())){
|
||||
|
||||
if($userGrade >= 5){
|
||||
$valid = true;
|
||||
$showDetailedInfo = true;
|
||||
}
|
||||
|
||||
if(!$valid) {
|
||||
|
||||
+47
-15
@@ -1224,7 +1224,7 @@ function updateOnline()
|
||||
|
||||
//동접수
|
||||
$before5Min = TimeUtil::nowAddMinutes(-5);
|
||||
$onlineUser = $db->query('SELECT no,name,nation FROM general WHERE lastrefresh > %s', $before5Min);
|
||||
$onlineUser = $db->query('SELECT no,name,nation FROM general WHERE lastrefresh > %s AND npc < 2', $before5Min);
|
||||
$onlineNum = count($onlineUser);
|
||||
$onlineNationUsers = Util::arrayGroupBy($onlineUser, 'nation');
|
||||
|
||||
@@ -1537,7 +1537,18 @@ function giveRandomUniqueItem(General $general, string $acquireType): bool
|
||||
//일단은 '획득' 시에만 동작하므로 이대로 사용하기로...
|
||||
$occupiedUnique = [];
|
||||
|
||||
$invalidItemType = [];
|
||||
foreach(array_keys(GameConst::$allItems) as $itemType){
|
||||
$ownItem = $general->getItems()[$itemType]??null;
|
||||
if($ownItem !== null && !$ownItem->isBuyable()){
|
||||
$invalidItemType[$itemType] = true;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (array_keys(GameConst::$allItems) as $itemType) {
|
||||
if(key_exists($itemType, $invalidItemType)){
|
||||
continue;
|
||||
}
|
||||
foreach ($db->queryAllLists('SELECT %b, count(*) as cnt FROM general GROUP BY %b', $itemType, $itemType) as [$itemCode, $cnt]) {
|
||||
$itemClass = buildItemClass($itemCode);
|
||||
if (!$itemClass) {
|
||||
@@ -1551,6 +1562,9 @@ function giveRandomUniqueItem(General $general, string $acquireType): bool
|
||||
}
|
||||
|
||||
foreach (GameConst::$allItems as $itemType => $itemCategories) {
|
||||
if(key_exists($itemType, $invalidItemType)){
|
||||
continue;
|
||||
}
|
||||
foreach ($itemCategories as $itemCode => $cnt) {
|
||||
if (!key_exists($itemCode, $occupiedUnique)) {
|
||||
$availableUnique[] = [[$itemType, $itemCode], $cnt];
|
||||
@@ -1604,38 +1618,56 @@ function tryUniqueItemLottery(General $general, string $acquireType = '아이템
|
||||
return false;
|
||||
}
|
||||
|
||||
$itemTypeCnt = count(GameConst::$allItems);
|
||||
$trialCnt = $itemTypeCnt;
|
||||
|
||||
foreach ($general->getItems() as $item) {
|
||||
if (!$item) {
|
||||
continue;
|
||||
}
|
||||
if (!$item->isBuyable()) {
|
||||
return false;
|
||||
$trialCnt -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
if($trialCnt <= 0){
|
||||
LogText("{$general->getName()}, {$general->getID()} 모든 아이템", $trialCnt);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
$scenario = $gameStor->scenario;
|
||||
$genCount = $db->queryFirstField('SELECT count(*) FROM general WHERE npc<2');
|
||||
|
||||
if ($scenario < 100) {
|
||||
$prob = 1 / ($genCount * 5); // 5~6개월에 하나씩 등장
|
||||
$prob = 1 / ($genCount * 3 * $itemTypeCnt); // 3~4개월에 하나씩 등장
|
||||
} else {
|
||||
$prob = 1 / $genCount; // 1~2개월에 하나씩 등장
|
||||
$prob = 1 / ($genCount * $itemTypeCnt); // 1~2개월에 하나씩 등장
|
||||
}
|
||||
|
||||
if ($acquireType == '설문조사') {
|
||||
$prob = 1 / ($genCount * 0.7 / 3); // 투표율 70%, 설문조사 한번에 2~3개 등장
|
||||
$prob = 1 / ($genCount * $itemTypeCnt * 0.7 / 3); // 투표율 70%, 설문조사 한번에 2~3개 등장
|
||||
} else if ($acquireType == '랜덤 임관') {
|
||||
$prob = 1 / ($genCount / 10 / 2); // 랜임시 2개(10%) 등장(200명중 20명 랜임시도?)
|
||||
$prob = 1 / ($genCount * $itemTypeCnt / 10 / 2); // 랜임시 2개(10%) 등장(200명중 20명 랜임시도?)
|
||||
} else if ($acquireType == '건국') {
|
||||
$prob = 1 / ($genCount / 10 / 4); // 건국시 4개(20%) 등장(200명시 20국 정도 됨)
|
||||
$prob = 1 / ($genCount * $itemTypeCnt / 10 / 4); // 건국시 4개(20%) 등장(200명시 20국 정도 됨)
|
||||
}
|
||||
|
||||
$prob = Util::valueFit($prob, null, 1 / 3);
|
||||
$prob = Util::valueFit($prob, null, 1 / 4);//최대치 감소
|
||||
$result = false;
|
||||
|
||||
if (!Util::randBool($prob)) {
|
||||
|
||||
|
||||
foreach(Util::range($trialCnt) as $_idx){
|
||||
if (Util::randBool($prob)) {
|
||||
$result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!$result){
|
||||
LogText("{$general->getName()}, {$general->getID()} 유니크 실패 {$trialCnt}", $prob);
|
||||
return false;
|
||||
}
|
||||
|
||||
LogText("{$general->getName()}, {$general->getID()} 유니크 성공 {$trialCnt}", $prob);
|
||||
|
||||
return giveRandomUniqueItem($general, $acquireType);
|
||||
}
|
||||
|
||||
@@ -1736,7 +1768,7 @@ function nextRuler(General $general)
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
|
||||
[$year, $month] = $gameStor->getValuesAsArray(['year', 'month']);
|
||||
[$year, $month, $fiction] = $gameStor->getValuesAsArray(['year', 'month', 'fiction']);
|
||||
$nation = $general->getStaticNation();
|
||||
$nationName = $nation['name'];
|
||||
$nationID = $nation['nation'];
|
||||
@@ -1744,7 +1776,7 @@ function nextRuler(General $general)
|
||||
$candidate = null;
|
||||
|
||||
//npc or npc유저인 경우 후계 찾기
|
||||
if ($general->getNPCType() > 0) {
|
||||
if (!$fiction && $general->getNPCType() > 0) {
|
||||
$candidate = $db->queryFirstRow(
|
||||
'SELECT no,name,officer_level,IF(ABS(affinity-%i)>75,150-ABS(affinity-%i),ABS(affinity-%i)) as npcmatch2 from general where nation=%i and officer_level!=12 and 1 <= npc and npc<=3 order by npcmatch2,rand() LIMIT 1',
|
||||
$general->getVar('affinity'),
|
||||
|
||||
@@ -627,14 +627,15 @@ function updateNationState()
|
||||
|
||||
$uniqueLotteryWeightList = [];
|
||||
foreach ($nationGenList as $nationGen) {
|
||||
$hasUnique = false;
|
||||
$trialCnt = count(GameConst::$allItems);
|
||||
|
||||
foreach ($nationGen->getItems() as $item) {
|
||||
if (!$item->isBuyable()) {
|
||||
$hasUnique = true;
|
||||
break;
|
||||
$trialCnt -= 1;
|
||||
}
|
||||
}
|
||||
if ($hasUnique) {
|
||||
|
||||
if ($trialCnt <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -647,6 +648,9 @@ function updateNationState()
|
||||
} else if ($nationGen->getVar('officer_level') > 4) {
|
||||
$score += 35;
|
||||
}
|
||||
|
||||
$score *= $trialCnt;
|
||||
|
||||
$uniqueLotteryWeightList[$nationGen->getID()] = [$nationGen, $score];
|
||||
}
|
||||
|
||||
|
||||
@@ -115,7 +115,10 @@ foreach(GameConst::$generalPoolAllowOption as $allowOption){
|
||||
}
|
||||
}
|
||||
|
||||
$userNick = $ownerInfo['name'];
|
||||
|
||||
$builder->setOwner($userID);
|
||||
$builder->setOwnerName($userNick);
|
||||
$builder->setKillturn(5);
|
||||
$builder->setNPCType(0);
|
||||
$builder->setAuxVar('next_change', TimeUtil::nowAddMinutes(12 * $env['turnterm']));
|
||||
@@ -135,7 +138,7 @@ $db->update('select_pool',[
|
||||
'reserved_until'=>null,
|
||||
], '(owner=%i or reserved_until < %s) AND general_id is NULL', $userID, $now);
|
||||
|
||||
$userNick = $ownerInfo['name'];
|
||||
|
||||
$josaYi = JosaUtil::pick($userNick, '이');
|
||||
$generalName = $builder->getGeneralName();
|
||||
$josaRo = JosaUtil::pick($generalName, '로');
|
||||
|
||||
@@ -132,6 +132,7 @@ if(key_exists('specialWar', $info)){
|
||||
$generalObj->setAuxVar('next_change', TimeUtil::nowAddMinutes(12 * $turnterm));
|
||||
|
||||
$userNick = $ownerInfo['name'];
|
||||
$generalObj->setVar('owner_name', $userNick);
|
||||
$josaYi = JosaUtil::pick($userNick, '이');
|
||||
|
||||
$generalName = $info['generalName'];
|
||||
|
||||
+2
-2
@@ -185,10 +185,10 @@ if($relYear < 3){
|
||||
$experience = 0;
|
||||
}
|
||||
else{
|
||||
$expGenCount = $db->queryFirstField('SELECT count(*) FROM general WHERE nation != 0 AND npc < 5');
|
||||
$expGenCount = $db->queryFirstField('SELECT count(*) FROM general WHERE nation != 0 AND npc < 4');
|
||||
$targetGenOrder = Util::round($expGenCount * 0.2);
|
||||
$experience = $db->queryFirstField(
|
||||
'SELECT experience FROM general WHERE nation != 0 AND npc < 5 ORDER BY experience ASC LIMIT %i, 1',
|
||||
'SELECT experience FROM general WHERE nation != 0 AND npc < 4 ORDER BY experience ASC LIMIT %i, 1',
|
||||
$targetGenOrder - 1
|
||||
);
|
||||
$experience *= 0.8;
|
||||
|
||||
+2
-1
@@ -43,7 +43,7 @@ function processWar(General $attackerGeneral, array $rawAttackerNation, array $r
|
||||
$iterDefender = new \ArrayIterator($defenderList);
|
||||
$iterDefender->rewind();
|
||||
|
||||
$getNextDefender = function(?WarUnit $prevDefender, bool $reqNext) use ($iterDefender, $rawDefenderNation, $db) {
|
||||
$getNextDefender = function(?WarUnit $prevDefender, bool $reqNext) use ($iterDefender, $rawDefenderNation, $rawDefenderCity, $db) {
|
||||
if($prevDefender !== null){
|
||||
$prevDefender->applyDB($db);
|
||||
}
|
||||
@@ -57,6 +57,7 @@ function processWar(General $attackerGeneral, array $rawAttackerNation, array $r
|
||||
}
|
||||
|
||||
$nextDefender = $iterDefender->current();
|
||||
$nextDefender->setRawCity($rawDefenderCity);
|
||||
if(extractBattleOrder($nextDefender) <= 0){
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -6,4 +6,17 @@ use \sammo\General;
|
||||
class che_명마_07_기주마 extends \sammo\BaseStatItem{
|
||||
protected $cost = 200;
|
||||
protected $buyable = false;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->info .= "<br>[전투] 공격 시 페이즈 +1";
|
||||
}
|
||||
|
||||
public function onCalcStat(General $general, string $statName, $value, $aux=null){
|
||||
if($statName === 'initWarPhase'){
|
||||
return $value + 1;
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,26 @@
|
||||
<?php
|
||||
namespace sammo\ActionItem;
|
||||
|
||||
use sammo\BaseWarUnitTrigger;
|
||||
use \sammo\iAction;
|
||||
use \sammo\General;
|
||||
use sammo\WarUnit;
|
||||
use sammo\WarUnitTrigger\che_퇴각부상무효;
|
||||
use sammo\WarUnitTriggerCaller;
|
||||
|
||||
class che_명마_07_백마 extends \sammo\BaseStatItem{
|
||||
protected $cost = 200;
|
||||
protected $buyable = false;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->info .= "<br>[전투] 전투 종료로 인한 부상 없음";
|
||||
}
|
||||
|
||||
public function getBattleInitSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller{
|
||||
return new WarUnitTriggerCaller(
|
||||
new che_퇴각부상무효($unit, BaseWarUnitTrigger::TYPE_ITEM),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,27 @@
|
||||
<?php
|
||||
namespace sammo\ActionItem;
|
||||
|
||||
use sammo\BaseWarUnitTrigger;
|
||||
use \sammo\iAction;
|
||||
use \sammo\General;
|
||||
use sammo\WarUnit;
|
||||
use sammo\WarUnitTrigger\che_퇴각부상무효;
|
||||
use sammo\WarUnitTriggerCaller;
|
||||
|
||||
class che_명마_12_사륜거 extends \sammo\BaseStatItem{
|
||||
protected $cost = 200;
|
||||
protected $buyable = false;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->info .= "<br>[전투] 전투 종료로 인한 부상 없음";
|
||||
}
|
||||
|
||||
public function getBattleInitSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller{
|
||||
return new WarUnitTriggerCaller(
|
||||
new che_퇴각부상무효($unit, BaseWarUnitTrigger::TYPE_ITEM),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,9 +2,26 @@
|
||||
namespace sammo\ActionItem;
|
||||
use \sammo\iAction;
|
||||
use \sammo\General;
|
||||
use sammo\WarUnit;
|
||||
use sammo\WarUnitTrigger\che_저격발동;
|
||||
use sammo\WarUnitTrigger\che_저격시도;
|
||||
use sammo\WarUnitTriggerCaller;
|
||||
|
||||
class che_무기_02_단궁 extends \sammo\BaseStatItem{
|
||||
protected $cost = 3000;
|
||||
protected $buyable = true;
|
||||
protected $reqSecu = 2000;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->info .= "<br>[전투] 새로운 상대와 전투 시 1% 확률로 저격 발동, 성공 시 사기+10";
|
||||
}
|
||||
|
||||
public function getBattlePhaseSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller{
|
||||
return new WarUnitTriggerCaller(
|
||||
new che_저격시도($unit, che_저격시도::TYPE_ITEM + che_저격시도::TYPE_DEDUP_TYPE_BASE * 102, 0.01, 10, 30),
|
||||
new che_저격발동($unit, che_저격발동::TYPE_ITEM)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,25 @@
|
||||
namespace sammo\ActionItem;
|
||||
use \sammo\iAction;
|
||||
use \sammo\General;
|
||||
use sammo\WarUnit;
|
||||
use sammo\WarUnitTrigger\che_저격발동;
|
||||
use sammo\WarUnitTrigger\che_저격시도;
|
||||
use sammo\WarUnitTriggerCaller;
|
||||
|
||||
class che_무기_07_맥궁 extends \sammo\BaseStatItem{
|
||||
protected $cost = 200;
|
||||
protected $buyable = false;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->info .= "<br>[전투] 새로운 상대와 전투 시 20% 확률로 저격 발동, 성공 시 사기+10";
|
||||
}
|
||||
|
||||
public function getBattlePhaseSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller{
|
||||
return new WarUnitTriggerCaller(
|
||||
new che_저격시도($unit, che_저격시도::TYPE_ITEM + che_저격시도::TYPE_DEDUP_TYPE_BASE * 107, 0.2, 20, 40),
|
||||
new che_저격발동($unit, che_저격발동::TYPE_ITEM)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,25 @@
|
||||
namespace sammo\ActionItem;
|
||||
use \sammo\iAction;
|
||||
use \sammo\General;
|
||||
use sammo\WarUnit;
|
||||
use sammo\WarUnitTrigger\che_저격발동;
|
||||
use sammo\WarUnitTrigger\che_저격시도;
|
||||
use sammo\WarUnitTriggerCaller;
|
||||
|
||||
class che_무기_09_동호비궁 extends \sammo\BaseStatItem{
|
||||
protected $cost = 200;
|
||||
protected $buyable = false;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->info .= "<br>[전투] 새로운 상대와 전투 시 20% 확률로 저격 발동, 성공 시 사기+10";
|
||||
}
|
||||
|
||||
public function getBattlePhaseSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller{
|
||||
return new WarUnitTriggerCaller(
|
||||
new che_저격시도($unit, che_저격시도::TYPE_ITEM + che_저격시도::TYPE_DEDUP_TYPE_BASE * 109, 0.15, 20, 40),
|
||||
new che_저격발동($unit, che_저격발동::TYPE_ITEM)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,25 @@
|
||||
namespace sammo\ActionItem;
|
||||
use \sammo\iAction;
|
||||
use \sammo\General;
|
||||
use sammo\WarUnit;
|
||||
use sammo\WarUnitTrigger\che_저격발동;
|
||||
use sammo\WarUnitTrigger\che_저격시도;
|
||||
use sammo\WarUnitTriggerCaller;
|
||||
|
||||
class che_무기_11_이광궁 extends \sammo\BaseStatItem{
|
||||
protected $cost = 200;
|
||||
protected $buyable = false;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->info .= "<br>[전투] 새로운 상대와 전투 시 10% 확률로 저격 발동, 성공 시 사기+10";
|
||||
}
|
||||
|
||||
public function getBattlePhaseSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller{
|
||||
return new WarUnitTriggerCaller(
|
||||
new che_저격시도($unit, che_저격시도::TYPE_ITEM + che_저격시도::TYPE_DEDUP_TYPE_BASE * 111, 0.10, 20, 40),
|
||||
new che_저격발동($unit, che_저격발동::TYPE_ITEM)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,25 @@
|
||||
namespace sammo\ActionItem;
|
||||
use \sammo\iAction;
|
||||
use \sammo\General;
|
||||
use sammo\WarUnit;
|
||||
use sammo\WarUnitTrigger\che_저격발동;
|
||||
use sammo\WarUnitTrigger\che_저격시도;
|
||||
use sammo\WarUnitTriggerCaller;
|
||||
|
||||
class che_무기_13_양유기궁 extends \sammo\BaseStatItem{
|
||||
protected $cost = 200;
|
||||
protected $buyable = false;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->info .= "<br>[전투] 새로운 상대와 전투 시 10% 확률로 저격 발동, 성공 시 사기+10";
|
||||
}
|
||||
|
||||
public function getBattlePhaseSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller{
|
||||
return new WarUnitTriggerCaller(
|
||||
new che_저격시도($unit, che_저격시도::TYPE_ITEM + che_저격시도::TYPE_DEDUP_TYPE_BASE * 113, 0.05, 20, 40),
|
||||
new che_저격발동($unit, che_저격발동::TYPE_ITEM)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -21,8 +21,8 @@ class che_반계_백우선 extends \sammo\BaseItem{
|
||||
|
||||
public function getBattlePhaseSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller{
|
||||
return new WarUnitTriggerCaller(
|
||||
new WarActivateSkills($unit, BaseWarUnitTrigger::TYPE_NONE, false, '계략약화'),
|
||||
new che_반계시도($unit),
|
||||
new WarActivateSkills($unit, BaseWarUnitTrigger::TYPE_ITEM +BaseWarUnitTrigger::TYPE_DEDUP_TYPE_BASE*301, false, '계략약화'),
|
||||
new che_반계시도($unit, BaseWarUnitTrigger::TYPE_ITEM +BaseWarUnitTrigger::TYPE_DEDUP_TYPE_BASE*301),
|
||||
new che_반계발동($unit)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -21,8 +21,8 @@ class che_반계_파초선 extends \sammo\BaseItem{
|
||||
|
||||
public function getBattlePhaseSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller{
|
||||
return new WarUnitTriggerCaller(
|
||||
new WarActivateSkills($unit, BaseWarUnitTrigger::TYPE_NONE, false, '계략약화'),
|
||||
new che_반계시도($unit),
|
||||
new WarActivateSkills($unit, BaseWarUnitTrigger::TYPE_ITEM +BaseWarUnitTrigger::TYPE_DEDUP_TYPE_BASE*302, false, '계략약화'),
|
||||
new che_반계시도($unit, BaseWarUnitTrigger::TYPE_ITEM +BaseWarUnitTrigger::TYPE_DEDUP_TYPE_BASE*302),
|
||||
new che_반계발동($unit)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -7,4 +7,17 @@ class che_서적_01_효경전 extends \sammo\BaseStatItem{
|
||||
protected $cost = 1000;
|
||||
protected $buyable = true;
|
||||
protected $reqSecu = 1000;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->info .= "<br>[전투] 계략 시도 확률 +1%p";
|
||||
}
|
||||
|
||||
public function onCalcStat(General $general, string $statName, $value, $aux=null){
|
||||
if($statName === 'warMagicTrialProb'){
|
||||
return $value + 0.01;
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
@@ -7,4 +7,17 @@ class che_서적_02_회남자 extends \sammo\BaseStatItem{
|
||||
protected $cost = 3000;
|
||||
protected $buyable = true;
|
||||
protected $reqSecu = 2000;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->info .= "<br>[전투] 계략 시도 확률 +1%p";
|
||||
}
|
||||
|
||||
public function onCalcStat(General $general, string $statName, $value, $aux=null){
|
||||
if($statName === 'warMagicTrialProb'){
|
||||
return $value + 0.01;
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
@@ -7,4 +7,17 @@ class che_서적_03_변도론 extends \sammo\BaseStatItem{
|
||||
protected $cost = 6000;
|
||||
protected $buyable = true;
|
||||
protected $reqSecu = 3000;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->info .= "<br>[전투] 계략 시도 확률 +2%p";
|
||||
}
|
||||
|
||||
public function onCalcStat(General $general, string $statName, $value, $aux=null){
|
||||
if($statName === 'warMagicTrialProb'){
|
||||
return $value + 0.02;
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
@@ -7,4 +7,17 @@ class che_서적_04_건상역주 extends \sammo\BaseStatItem{
|
||||
protected $cost = 10000;
|
||||
protected $buyable = true;
|
||||
protected $reqSecu = 4000;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->info .= "<br>[전투] 계략 시도 확률 +2%p";
|
||||
}
|
||||
|
||||
public function onCalcStat(General $general, string $statName, $value, $aux=null){
|
||||
if($statName === 'warMagicTrialProb'){
|
||||
return $value + 0.02;
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
@@ -7,4 +7,17 @@ class che_서적_05_여씨춘추 extends \sammo\BaseStatItem{
|
||||
protected $cost = 15000;
|
||||
protected $buyable = true;
|
||||
protected $reqSecu = 5000;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->info .= "<br>[전투] 계략 시도 확률 +3%p";
|
||||
}
|
||||
|
||||
public function onCalcStat(General $general, string $statName, $value, $aux=null){
|
||||
if($statName === 'warMagicTrialProb'){
|
||||
return $value + 0.03;
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
@@ -7,4 +7,17 @@ class che_서적_06_사민월령 extends \sammo\BaseStatItem{
|
||||
protected $cost = 21000;
|
||||
protected $buyable = true;
|
||||
protected $reqSecu = 6000;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->info .= "<br>[전투] 계략 시도 확률 +3%p";
|
||||
}
|
||||
|
||||
public function onCalcStat(General $general, string $statName, $value, $aux=null){
|
||||
if($statName === 'warMagicTrialProb'){
|
||||
return $value + 0.03;
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,26 @@
|
||||
<?php
|
||||
namespace sammo\ActionItem;
|
||||
|
||||
use sammo\BaseWarUnitTrigger;
|
||||
use \sammo\iAction;
|
||||
use \sammo\General;
|
||||
use sammo\WarUnit;
|
||||
use sammo\WarUnitTrigger\WarActivateSkills;
|
||||
use sammo\WarUnitTriggerCaller;
|
||||
|
||||
class che_서적_07_논어 extends \sammo\BaseStatItem{
|
||||
protected $cost = 200;
|
||||
protected $buyable = false;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->info .= "<br>[전투] 상대의 계략 성공 확률 -10%p";
|
||||
}
|
||||
|
||||
public function getBattlePhaseSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller{
|
||||
return new WarUnitTriggerCaller(
|
||||
new WarActivateSkills($unit, BaseWarUnitTrigger::TYPE_ITEM+BaseWarUnitTrigger::TYPE_DEDUP_TYPE_BASE*207, false, '계략약화')
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,28 @@
|
||||
<?php
|
||||
namespace sammo\ActionItem;
|
||||
|
||||
use sammo\BaseWarUnitTrigger;
|
||||
use \sammo\iAction;
|
||||
use \sammo\General;
|
||||
use sammo\WarUnit;
|
||||
use sammo\WarUnitTrigger\che_반계발동;
|
||||
use sammo\WarUnitTrigger\che_반계시도;
|
||||
use sammo\WarUnitTriggerCaller;
|
||||
|
||||
class che_서적_07_사마법 extends \sammo\BaseStatItem{
|
||||
protected $cost = 200;
|
||||
protected $buyable = false;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->info .= "<br>[전투] 상대의 계략을 20% 확률로 되돌림";
|
||||
}
|
||||
|
||||
public function getBattlePhaseSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller{
|
||||
return new WarUnitTriggerCaller(
|
||||
new che_반계시도($unit, BaseWarUnitTrigger::TYPE_ITEM+BaseWarUnitTrigger::TYPE_DEDUP_TYPE_BASE*207, 0.2),
|
||||
new che_반계발동($unit)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -6,4 +6,17 @@ use \sammo\General;
|
||||
class che_서적_07_위료자 extends \sammo\BaseStatItem{
|
||||
protected $cost = 200;
|
||||
protected $buyable = false;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->info .= "<br>[전투] 계략 시도 확률 +20%p";
|
||||
}
|
||||
|
||||
public function onCalcStat(General $general, string $statName, $value, $aux=null){
|
||||
if($statName === 'warMagicTrialProb'){
|
||||
return $value + 0.2;
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
@@ -6,4 +6,17 @@ use \sammo\General;
|
||||
class che_서적_08_전론 extends \sammo\BaseStatItem{
|
||||
protected $cost = 200;
|
||||
protected $buyable = false;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->info .= "<br>[전투] 계략 성공 시 대미지 +20%";
|
||||
}
|
||||
|
||||
public function onCalcStat(General $general, string $statName, $value, $aux=null){
|
||||
if($statName === 'warMagicSuccessDamage'){
|
||||
return $value * 1.2;
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,26 @@
|
||||
<?php
|
||||
namespace sammo\ActionItem;
|
||||
|
||||
use sammo\BaseWarUnitTrigger;
|
||||
use \sammo\iAction;
|
||||
use \sammo\General;
|
||||
use sammo\WarUnit;
|
||||
use sammo\WarUnitTrigger\WarActivateSkills;
|
||||
use sammo\WarUnitTriggerCaller;
|
||||
|
||||
class che_서적_11_춘추전 extends \sammo\BaseStatItem{
|
||||
protected $cost = 200;
|
||||
protected $buyable = false;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->info .= "<br>[전투] 상대의 계략 성공 확률 -10%p";
|
||||
}
|
||||
|
||||
public function getBattlePhaseSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller{
|
||||
return new WarUnitTriggerCaller(
|
||||
new WarActivateSkills($unit, BaseWarUnitTrigger::TYPE_ITEM+BaseWarUnitTrigger::TYPE_DEDUP_TYPE_BASE*211, false, '계략약화')
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,28 @@
|
||||
<?php
|
||||
namespace sammo\ActionItem;
|
||||
|
||||
use sammo\BaseWarUnitTrigger;
|
||||
use \sammo\iAction;
|
||||
use \sammo\General;
|
||||
use sammo\WarUnit;
|
||||
use sammo\WarUnitTrigger\che_반계발동;
|
||||
use sammo\WarUnitTrigger\che_반계시도;
|
||||
use sammo\WarUnitTriggerCaller;
|
||||
|
||||
class che_서적_12_산해경 extends \sammo\BaseStatItem{
|
||||
protected $cost = 200;
|
||||
protected $buyable = false;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->info .= "<br>[전투] 상대의 계략을 20% 확률로 되돌림";
|
||||
}
|
||||
|
||||
public function getBattlePhaseSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller{
|
||||
return new WarUnitTriggerCaller(
|
||||
new che_반계시도($unit, BaseWarUnitTrigger::TYPE_ITEM, 0.2),
|
||||
new che_반계발동($unit)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,7 @@ class che_의술_상한잡병론 extends \sammo\BaseItem{
|
||||
public function getBattlePhaseSkillTriggerList(\sammo\WarUnit $unit): ?WarUnitTriggerCaller
|
||||
{
|
||||
return new WarUnitTriggerCaller(
|
||||
new che_전투치료시도($unit, BaseWarUnitTrigger::TYPE_ITEM),
|
||||
new che_전투치료시도($unit, BaseWarUnitTrigger::TYPE_ITEM+BaseWarUnitTrigger::TYPE_DEDUP_TYPE_BASE*301),
|
||||
new che_전투치료발동($unit, BaseWarUnitTrigger::TYPE_ITEM)
|
||||
|
||||
);
|
||||
|
||||
@@ -27,7 +27,7 @@ class che_의술_청낭서 extends \sammo\BaseItem{
|
||||
public function getBattlePhaseSkillTriggerList(\sammo\WarUnit $unit): ?WarUnitTriggerCaller
|
||||
{
|
||||
return new WarUnitTriggerCaller(
|
||||
new che_전투치료시도($unit, BaseWarUnitTrigger::TYPE_ITEM),
|
||||
new che_전투치료시도($unit, BaseWarUnitTrigger::TYPE_ITEM+BaseWarUnitTrigger::TYPE_DEDUP_TYPE_BASE*302),
|
||||
new che_전투치료발동($unit, BaseWarUnitTrigger::TYPE_ITEM)
|
||||
|
||||
);
|
||||
|
||||
@@ -27,7 +27,7 @@ class che_의술_태평청령 extends \sammo\BaseItem{
|
||||
public function getBattlePhaseSkillTriggerList(\sammo\WarUnit $unit): ?WarUnitTriggerCaller
|
||||
{
|
||||
return new WarUnitTriggerCaller(
|
||||
new che_전투치료시도($unit, BaseWarUnitTrigger::TYPE_ITEM),
|
||||
new che_전투치료시도($unit, BaseWarUnitTrigger::TYPE_ITEM+BaseWarUnitTrigger::TYPE_DEDUP_TYPE_BASE*303),
|
||||
new che_전투치료발동($unit, BaseWarUnitTrigger::TYPE_ITEM)
|
||||
|
||||
);
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
namespace sammo\ActionItem;
|
||||
|
||||
use sammo\BaseWarUnitTrigger;
|
||||
use \sammo\iAction;
|
||||
use \sammo\General;
|
||||
use \sammo\SpecialityHelper;
|
||||
@@ -19,7 +21,7 @@ class che_저격_매화수전 extends \sammo\BaseItem{
|
||||
|
||||
public function getBattlePhaseSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller{
|
||||
return new WarUnitTriggerCaller(
|
||||
new che_저격시도($unit, che_저격시도::TYPE_ITEM, 0.5, 20, 40),
|
||||
new che_저격시도($unit, che_저격시도::TYPE_ITEM+BaseWarUnitTrigger::TYPE_DEDUP_TYPE_BASE*304, 0.5, 20, 40),
|
||||
new che_저격발동($unit, che_저격발동::TYPE_ITEM)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
namespace sammo\ActionItem;
|
||||
|
||||
use sammo\BaseWarUnitTrigger;
|
||||
use \sammo\iAction;
|
||||
use \sammo\General;
|
||||
use \sammo\SpecialityHelper;
|
||||
@@ -19,7 +21,7 @@ class che_저격_비도 extends \sammo\BaseItem{
|
||||
|
||||
public function getBattlePhaseSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller{
|
||||
return new WarUnitTriggerCaller(
|
||||
new che_저격시도($unit, che_저격시도::TYPE_ITEM, 0.5, 20, 40),
|
||||
new che_저격시도($unit, che_저격시도::TYPE_ITEM+BaseWarUnitTrigger::TYPE_DEDUP_TYPE_BASE*305, 0.5, 20, 40),
|
||||
new che_저격발동($unit, che_저격발동::TYPE_ITEM)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ class event_전투특기_무쌍 extends \sammo\BaseItem{
|
||||
protected $id = 61;
|
||||
protected $rawName = '비급';
|
||||
protected $name = '비급(무쌍)';
|
||||
protected $info = '[전투] 대미지 +10%, 공격 시 필살 확률 +10%p, <br>승리 수만큼 대미지 0.20%씩 추가 상승(최대40%)<br>승리 수만큼 피해 0.05%씩 감소(최대50%)';
|
||||
protected $info = '[전투] 대미지 +10%, 피해 -5%, 공격 시 필살 확률 +10%p, <br>승리 수만큼 대미지 0.20%씩 추가 상승(최대40%)<br>승리 수만큼 피해 0.05%씩 감소(최대30%)';
|
||||
protected $cost = 100;
|
||||
protected $buyable = true;
|
||||
protected $consumable = false;
|
||||
@@ -26,10 +26,10 @@ class event_전투특기_무쌍 extends \sammo\BaseItem{
|
||||
|
||||
public function getWarPowerMultiplier(WarUnit $unit):array{
|
||||
$attackMultiplier = 1.1;
|
||||
$defenceMultiplier = 1;
|
||||
$defenceMultiplier = 0.95;
|
||||
$killnum = $unit->getGeneral()->getRankVar('killnum');
|
||||
$attackMultiplier += Util::valueFit($killnum * 0.01 * 0.2, null, 0.4);
|
||||
$defenceMultiplier -= Util::valueFit($killnum * 0.01 * 0.05, null, 0.5);
|
||||
$defenceMultiplier -= Util::valueFit($killnum * 0.01 * 0.05, null, 0.3);
|
||||
return [$attackMultiplier, $defenceMultiplier];
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ class che_event_무쌍 extends \sammo\BaseSpecial{
|
||||
|
||||
protected $id = 61;
|
||||
protected $name = '무쌍';
|
||||
protected $info = '[전투] 대미지 +10%, 공격 시 필살 확률 +10%p, <br>승리 수만큼 대미지 0.20%씩 추가 상승(최대40%)<br>승리 수만큼 피해 0.05%씩 감소(최대50%)';
|
||||
protected $info = '[전투] 대미지 +10%, 피해 -5%, 공격 시 필살 확률 +10%p, <br>승리 수만큼 대미지 0.20%씩 추가 상승(최대40%)<br>승리 수만큼 피해 0.05%씩 감소(최대30%)';
|
||||
|
||||
static $selectWeightType = SpecialityHelper::WEIGHT_NORM;
|
||||
static $selectWeight = 1;
|
||||
@@ -30,7 +30,7 @@ class che_event_무쌍 extends \sammo\BaseSpecial{
|
||||
$defenceMultiplier = 1;
|
||||
$killnum = $unit->getGeneral()->getRankVar('killnum');
|
||||
$attackMultiplier += Util::valueFit($killnum * 0.01 * 0.2, null, 0.4);
|
||||
$defenceMultiplier -= Util::valueFit($killnum * 0.01 * 0.05, null, 0.5);
|
||||
$defenceMultiplier -= Util::valueFit($killnum * 0.01 * 0.05, null, 0.3);
|
||||
return [$attackMultiplier, $defenceMultiplier];
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ class che_무쌍 extends \sammo\BaseSpecial{
|
||||
|
||||
protected $id = 61;
|
||||
protected $name = '무쌍';
|
||||
protected $info = '[전투] 대미지 +10%, 공격 시 필살 확률 +10%p, <br>승리 수만큼 대미지 0.20%씩 추가 상승(최대40%)<br>승리 수만큼 피해 0.05%씩 감소(최대50%)';
|
||||
protected $info = '[전투] 대미지 +10%, 피해 -5%, 공격 시 필살 확률 +10%p, <br>승리 수만큼 대미지 0.20%씩 추가 상승(최대40%)<br>승리 수만큼 피해 0.05%씩 감소(최대30%)';
|
||||
|
||||
static $selectWeightType = SpecialityHelper::WEIGHT_NORM;
|
||||
static $selectWeight = 1;
|
||||
@@ -27,10 +27,10 @@ class che_무쌍 extends \sammo\BaseSpecial{
|
||||
|
||||
public function getWarPowerMultiplier(WarUnit $unit):array{
|
||||
$attackMultiplier = 1.1;
|
||||
$defenceMultiplier = 1;
|
||||
$defenceMultiplier = 0.95;
|
||||
$killnum = $unit->getGeneral()->getRankVar('killnum');
|
||||
$attackMultiplier += Util::valueFit($killnum * 0.01 * 0.2, null, 0.4);
|
||||
$defenceMultiplier -= Util::valueFit($killnum * 0.01 * 0.05, null, 0.5);
|
||||
$defenceMultiplier -= Util::valueFit($killnum * 0.01 * 0.05, null, 0.3);
|
||||
return [$attackMultiplier, $defenceMultiplier];
|
||||
}
|
||||
}
|
||||
@@ -120,6 +120,7 @@ class AutorunGeneralPolicy{
|
||||
$priority = [];
|
||||
foreach($serverPolicy['priority'] as $priorityItem){
|
||||
if(!property_exists($this, $priorityItem)){
|
||||
trigger_error ("{$priorityItem}이 없음", E_USER_NOTICE );
|
||||
continue;
|
||||
}
|
||||
$priority[] = $priorityItem;
|
||||
@@ -133,6 +134,7 @@ class AutorunGeneralPolicy{
|
||||
$priority = [];
|
||||
foreach($nationPolicy['priority'] as $priorityItem){
|
||||
if(!property_exists($this, $priorityItem)){
|
||||
trigger_error ("{$priorityItem}이 없음", E_USER_NOTICE );
|
||||
continue;
|
||||
}
|
||||
$priority[] = $priorityItem;
|
||||
|
||||
@@ -85,6 +85,7 @@ class AutorunNationPolicy {
|
||||
|
||||
public $can부대전방발령 = true;
|
||||
public $can부대후방발령 = true;
|
||||
public $can부대구출발령 = true;
|
||||
|
||||
public $can부대유저장후방발령 = true;
|
||||
public $can유저장후방발령 = true;
|
||||
@@ -180,6 +181,7 @@ class AutorunNationPolicy {
|
||||
if($serverPolicy){
|
||||
foreach($serverPolicy['values']??[] as $policy=>$value){
|
||||
if(!property_exists($this, $policy)){
|
||||
trigger_error ("{$policy}이 없음", E_USER_NOTICE );
|
||||
continue;
|
||||
}
|
||||
$this->{$policy} = $value;
|
||||
@@ -194,6 +196,7 @@ class AutorunNationPolicy {
|
||||
if($nationPolicy){
|
||||
foreach($nationPolicy['values']??[] as $policy=>$value){
|
||||
if(!property_exists($this, $policy)){
|
||||
trigger_error ("{$policy}이 없음", E_USER_NOTICE );
|
||||
continue;
|
||||
}
|
||||
$this->{$policy} = $value;
|
||||
|
||||
@@ -7,6 +7,7 @@ abstract class BaseWarUnitTrigger extends ObjectTrigger{
|
||||
const TYPE_NONE = 0;
|
||||
const TYPE_ITEM = 1;
|
||||
const TYPE_CONSUMABLE_ITEM = 1 | 2;
|
||||
const TYPE_DEDUP_TYPE_BASE = 1024;
|
||||
|
||||
protected $raiseType = self::TYPE_NONE;
|
||||
|
||||
|
||||
@@ -178,14 +178,14 @@ class che_랜덤임관 extends Command\GeneralCommand{
|
||||
$generalsCnt = [];
|
||||
if($notIn){
|
||||
$rawGeneralsCnt = $db->query(
|
||||
'SELECT general.nation as nation, nation.gennum, nation.name, npc, count(*) as cnt FROM general JOIN nation ON general.nation = nation.nation WHERE npc < 5 AND nation.gennum < %i AND nation.scout=0 AND nation.nation NOT IN %li GROUP BY general.nation, general.npc',
|
||||
'SELECT general.nation as nation, nation.gennum, nation.name, npc, count(*) as cnt FROM general JOIN nation ON general.nation = nation.nation WHERE npc < 4 AND nation.gennum < %i AND nation.scout=0 AND nation.nation NOT IN %li GROUP BY general.nation, general.npc',
|
||||
$genLimit,
|
||||
$notIn
|
||||
);
|
||||
}
|
||||
else{
|
||||
$rawGeneralsCnt = $db->query(
|
||||
'SELECT general.nation as nation, nation.gennum, nation.name, npc, count(*) as cnt FROM general JOIN nation ON general.nation = nation.nation WHERE npc < 5 AND nation.gennum < %i AND nation.scout=0 GROUP BY general.nation, general.npc',
|
||||
'SELECT general.nation as nation, nation.gennum, nation.name, npc, count(*) as cnt FROM general JOIN nation ON general.nation = nation.nation WHERE npc < 4 AND nation.gennum < %i AND nation.scout=0 GROUP BY general.nation, general.npc',
|
||||
$genLimit
|
||||
);
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ class che_모반시도 extends Command\GeneralCommand{
|
||||
$nationName = $this->nation['name'];
|
||||
|
||||
$logger = $general->getLogger();
|
||||
$lordLogger = $this->destGeneralObj->getLogger();
|
||||
$lordLogger = $lordGeneral->getLogger();
|
||||
|
||||
$general->setVar('officer_level', 12);
|
||||
$general->setVar('officer_city', 0);
|
||||
|
||||
@@ -178,7 +178,7 @@ class che_인재탐색 extends Command\GeneralCommand
|
||||
$avgGen = $db->queryFirstRow(
|
||||
'SELECT avg(dedication) as ded,avg(experience) as exp,
|
||||
avg(dex1+dex2+dex3+dex4) as dex_t, avg(age) as age, avg(dex5) as dex5
|
||||
from general where npc < 5'
|
||||
from general where npc < 4'
|
||||
);
|
||||
|
||||
$pickTypeList = ['무' => 6, '지' => 6, '무지' => 3];
|
||||
|
||||
@@ -95,6 +95,7 @@ class che_선전포고 extends Command\NationCommand
|
||||
ConstraintHelper::DisallowDiplomacyBetweenStatus([
|
||||
0 => '아국과 이미 교전중입니다.',
|
||||
1 => '아국과 이미 선포중입니다.',
|
||||
7 => '불가침국입니다.'
|
||||
]),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ namespace sammo\Event;
|
||||
|
||||
abstract class Action{
|
||||
//public abstract function __construct(...$args);
|
||||
public abstract function run($env=null);
|
||||
public abstract function run(array $env);
|
||||
|
||||
public static function build($actionArgs):Action{
|
||||
if(!is_array($actionArgs)){
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
namespace sammo\Event\Action;
|
||||
|
||||
use function sammo\getNationStaticInfo;
|
||||
use sammo\DB;
|
||||
use sammo\Util;
|
||||
|
||||
class AutoDeleteInvader extends \sammo\Event\Action{
|
||||
private $nationID;
|
||||
public function __construct(int $nationID){
|
||||
$this->nationID = $nationID;
|
||||
}
|
||||
|
||||
public function run(array $env){
|
||||
$db = DB::db();
|
||||
if(getNationStaticInfo($this->nationID)===null){
|
||||
$db->update('general', [
|
||||
'killturn'=>5
|
||||
], 'nation = 0 AND npc = 9');
|
||||
$eventID = Util::array_get($env['currentEventID']);
|
||||
$db->delete('event', 'id = %i', $eventID);
|
||||
return [__CLASS__, "Not Exists"];
|
||||
}
|
||||
$db = DB::db();
|
||||
$onWar = $db->queryFirstField('SELECT count(*) FROM diplomacy WHERE me = %i AND state IN %li', $this->nationID, [0, 1]);
|
||||
if($onWar){
|
||||
return [__CLASS__, "On War"];
|
||||
}
|
||||
|
||||
$rulerID = $db->queryFirstField('SELECT no FROM general WHERE nation = %i AND officer_level = 12', $this->nationID);
|
||||
$db->update('general_turn', [
|
||||
'action'=>'che_방랑',
|
||||
'arg'=>'[]',
|
||||
'brief'=>"이민족 방랑"
|
||||
], 'general_id = %i', $rulerID);
|
||||
$db->update('general', [
|
||||
'killturn'=>5
|
||||
], 'nation = %i', $this->nationID);
|
||||
|
||||
$eventID = Util::array_get($env['currentEventID']);
|
||||
$db->delete('event', 'id = %i', $eventID);
|
||||
|
||||
return [__CLASS__, 'Deleted'];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -161,7 +161,7 @@ class ChangeCity extends \sammo\Event\Action{
|
||||
throw new \InvalidArgumentException('올바르지 않은 cond 입니다.');
|
||||
}
|
||||
|
||||
public function run($env=null){
|
||||
public function run(array $env){
|
||||
$cities = $this->getTargetCities($env);
|
||||
|
||||
DB::db()->update('city',
|
||||
|
||||
@@ -7,7 +7,7 @@ class CreateAdminNPC extends \sammo\Event\Action{
|
||||
|
||||
}
|
||||
|
||||
public function run($env=null){
|
||||
public function run(array $env){
|
||||
return [__CLASS__, 'NYI'];
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ class CreateManyNPC extends \sammo\Event\Action{
|
||||
}
|
||||
|
||||
|
||||
public function run($env=null){
|
||||
public function run(array $env){
|
||||
if($this->npcCount <= 0){
|
||||
return [__CLASS__, []];
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ class DeleteEvent extends \sammo\Event\Action{
|
||||
public function __construct(){
|
||||
}
|
||||
|
||||
public function run($env=null){
|
||||
public function run(array $env){
|
||||
|
||||
$eventID = \sammo\Util::array_get($env['currentEventID']);
|
||||
if(!$eventID){
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
namespace sammo\Event\Action;
|
||||
|
||||
use function sammo\getNationStaticInfo;
|
||||
|
||||
use sammo\ActionLogger;
|
||||
use sammo\CityConst;
|
||||
use sammo\DB;
|
||||
use sammo\KVStorage;
|
||||
use sammo\Util;
|
||||
|
||||
class InvaderEnding extends \sammo\Event\Action{
|
||||
public function __construct(){
|
||||
}
|
||||
|
||||
public function run(array $env){
|
||||
//FIXME: 조건 체크를 여기서 하지 말라.
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$logger = new ActionLogger(0, 0, $env['year'], $env['month']);
|
||||
|
||||
$isunited = $gameStor->isunited;
|
||||
if(in_array($isunited, [0, 2])){
|
||||
return [__CLASS__, "No Invader"];
|
||||
}
|
||||
|
||||
$nationCnt = $db->queryFirstField('SELECT count(*) FROM nation');
|
||||
if($nationCnt >= 2){
|
||||
return [__CLASS__, "On Event"];
|
||||
}
|
||||
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
|
||||
$logger = new ActionLogger(0, 0, $env['year'], $env['month']);
|
||||
|
||||
$cityCnt = $db->queryFirstField('SELECT count(*) FROM city WHERE nation = 0');
|
||||
if($cityCnt == 0){
|
||||
//천통 엔딩
|
||||
$logger->pushGlobalHistoryLog("<L><b>【이벤트】</b></>이민족을 모두 소탕했습니다!");
|
||||
$logger->pushGlobalHistoryLog("<L><b>【이벤트】</b></>중원은 당분간 태평성대를 누릴 것입니다.");
|
||||
}
|
||||
else if($cityCnt == count(CityConst::all())){
|
||||
//이민족 엔딩
|
||||
$logger->pushGlobalHistoryLog("<L><b>【이벤트】</b></>중원은 이민족에 의해 혼란에 빠졌습니다.");
|
||||
$logger->pushGlobalHistoryLog("<L><b>【이벤트】</b></>백성은 언젠가 영웅이 나타나길 기다립니다.");
|
||||
}
|
||||
else{
|
||||
return [__CLASS__, "On Event"];
|
||||
}
|
||||
$gameStor->setValue('isunited', 3);
|
||||
$logger->flush();
|
||||
|
||||
$gameStor->conlimit = $gameStor->conlimit * 100;
|
||||
|
||||
$eventID = Util::array_get($env['currentEventID']);
|
||||
$db->delete('event', 'id = %i', $eventID);
|
||||
|
||||
return [__CLASS__, 'Deleted'];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,116 +1,257 @@
|
||||
<?php
|
||||
|
||||
namespace sammo\Event\Action;
|
||||
|
||||
use sammo\ActionLogger;
|
||||
use sammo\CityConst;
|
||||
use sammo\DB;
|
||||
use sammo\Json;
|
||||
use sammo\KVStorage;
|
||||
use sammo\Scenario\GeneralBuilder;
|
||||
use sammo\Scenario\Nation;
|
||||
use sammo\UniqueConst;
|
||||
use sammo\Util;
|
||||
|
||||
use function sammo\getNationStaticInfo;
|
||||
use function sammo\refreshNationStaticInfo;
|
||||
|
||||
/**
|
||||
* 이민족 침입을 모사
|
||||
*
|
||||
* 양수 : 정해진 값. [절대값]
|
||||
* 음수 : 합산(장수 등), 혹은 평균(기술 등)을 나누어 적용한 값 [상대값]
|
||||
* 음수 : 합산(장수 등), 혹은 평균(기술 등)을 곱해 적용한 값 [상대값]
|
||||
*
|
||||
* event_1.php, 센 이민족 : npcEachCount = -0.5, specAvg = 195, specDist = 5, tech = 15000, dex = 450000
|
||||
* event_2.php, 약한 이민족 : npcEachCount = -0.5, specAvg = 150, specDist = 20, tech = -1, dex = 0
|
||||
* event_3.php, 엄청 약한 이민족 : npcEachCount = 100, specAvg = 50, specDist = 5, tech = 0, dex = 0
|
||||
* event_1.php, 센 이민족 : npcEachCount = -0.5, specAvg = 195, tech = 15000, dex = 450000
|
||||
* event_2.php, 약한 이민족 : npcEachCount = -0.5, specAvg = 150, tech = -1, dex = 0
|
||||
* event_3.php, 엄청 약한 이민족 : npcEachCount = 100, specAvg = 50, tech = 0, dex = 0
|
||||
*/
|
||||
class RaiseInvader extends \sammo\Event\Action{
|
||||
class RaiseInvader extends \sammo\Event\Action
|
||||
{
|
||||
private $npcEachCount;
|
||||
private $specAvg;
|
||||
private $specDist;
|
||||
private $tech;
|
||||
private $dex;
|
||||
|
||||
const INVADER_LIST = [
|
||||
'강'=>63,
|
||||
'저'=>64,
|
||||
'흉노'=>65,
|
||||
'남만'=>66,
|
||||
'산월'=>67,
|
||||
'오환'=>68,
|
||||
'왜'=>69
|
||||
];
|
||||
|
||||
public function __construct(
|
||||
$npcEachCount = -0.5,
|
||||
int $specAvg = 150,
|
||||
int $specDist = 20,
|
||||
int $tech = -1,
|
||||
int $dex = 0
|
||||
){
|
||||
$npcEachCount = -3,
|
||||
$specAvg = -1.2,
|
||||
$tech = -1.2,
|
||||
$dex = -1
|
||||
) {
|
||||
$this->npcEachCount = $npcEachCount;
|
||||
$this->specAvg = $specAvg;
|
||||
$this->specDist = $specDist;
|
||||
$this->tech = $tech;
|
||||
$this->dex = $dex;
|
||||
|
||||
if($specDist < 0){
|
||||
throw new \InvalidArgumentException('specDist는 음수를 지원하지 않습니다.');
|
||||
}
|
||||
}
|
||||
|
||||
private function moveCapital(){
|
||||
$cities = array_map(function ($value) {
|
||||
return $value;
|
||||
}, static::INVADER_LIST);
|
||||
private function moveCapital()
|
||||
{
|
||||
$cities = [];
|
||||
foreach (CityConst::all() as $cityObj) {
|
||||
if ($cityObj->level != 4) {
|
||||
continue;
|
||||
}
|
||||
$cities[] = $cityObj->id;
|
||||
}
|
||||
|
||||
if (count($cities) == 0) {
|
||||
return [__CLASS__, 0];
|
||||
}
|
||||
|
||||
$db = DB::db();
|
||||
|
||||
|
||||
foreach($db->queryFirstColumn('SELECT capital, nation from nation WHERE capital in %li', $cities) as $row){
|
||||
foreach ($db->queryFirstColumn('SELECT capital, nation from nation WHERE capital in %li', $cities) as $row) {
|
||||
list($oldCapital, $nation) = $row;
|
||||
$newCapital = $db->queryFirstRow('SELECT city from city where nation=%i and city !=%i \
|
||||
order by rand() limit 1', $nation, $oldCapital);
|
||||
$db->update('nation', ['capital'=>$newCapital], 'nation=%i', $nation);
|
||||
$db->update('nation', ['capital' => $newCapital], 'nation=%i', $nation);
|
||||
|
||||
$db->update('general', ['city'=>$newCapital], 'nation=%i and city=%i', $nation, $oldCapital);
|
||||
$db->update('general', ['city' => $newCapital], 'nation=%i and city=%i', $nation, $oldCapital);
|
||||
}
|
||||
|
||||
|
||||
$db->update('general', [
|
||||
'officer_level'=>1,
|
||||
'officer_city'=>0
|
||||
'officer_level' => 1,
|
||||
'officer_city' => 0
|
||||
], 'officer_city in %li', $cities);
|
||||
|
||||
$db->update('city', [
|
||||
'nation'=>0
|
||||
'nation' => 0,
|
||||
'front' => 0,
|
||||
'supply' => 1,
|
||||
], 'city in %li', $cities);
|
||||
}
|
||||
|
||||
public function run($env=null){
|
||||
public function run(array $env)
|
||||
{
|
||||
$db = DB::db();
|
||||
$npcEachCount = $this->npcEachCount;
|
||||
|
||||
if($npcEachCount < 0){
|
||||
$npcEachCount =
|
||||
$db->queryFirstField('SELECT count(no) from general where npc < 9') / count(self::INVADER_LIST);
|
||||
$npcEachCount /= -1 * $this->npcEachCount;
|
||||
/** @var \sammo\CityInitDetail[] */
|
||||
$cities = [];
|
||||
foreach (CityConst::all() as $cityObj) {
|
||||
if ($cityObj->level != 4) {
|
||||
continue;
|
||||
}
|
||||
$cities[] = $cityObj;
|
||||
}
|
||||
|
||||
if ($npcEachCount < 0) {
|
||||
$npcEachCount =
|
||||
$db->queryFirstField('SELECT count(no) from general where npc < 4') / count($cities);
|
||||
$npcEachCount *= -1 * $this->npcEachCount;
|
||||
}
|
||||
$npcEachCount = max(10, Util::toInt($npcEachCount));
|
||||
|
||||
$specAvg = $this->specAvg;
|
||||
if($specAvg < 0){
|
||||
$specAvg = $db->queryFirstField('SELECT avg(sum(`leadership` + `strength` + `intel`)) from general where npc < 9');
|
||||
$specAvg /= -1 * $this->specAvg;
|
||||
if ($specAvg < 0) {
|
||||
$specAvg = $db->queryFirstField('SELECT avg((`leadership` + `strength` + `intel`)/3) from general where npc < 4');
|
||||
$specAvg *= -1 * $this->specAvg;
|
||||
}
|
||||
$specAvg = Util::toInt($specAvg);
|
||||
|
||||
$tech = $this->tech;
|
||||
if($tech < 0){
|
||||
if ($tech < 0) {
|
||||
$tech = $db->queryFirstField("SELECT avg(tech) from nation where `level`>0");
|
||||
$tech /= -1 * $this->tech;
|
||||
$tech *= -1 * $this->tech;
|
||||
}
|
||||
|
||||
$dex = $this->dex;
|
||||
if($dex < 0){
|
||||
$dex = $db->queryFirstField("SELECT avg(dex1 + dex2 + dex3 + dex4 + dex5)/5 from nation where `level`>0");
|
||||
$dex /= -1 * $this->dex;
|
||||
if ($dex < 0) {
|
||||
$dex = $db->queryFirstField("SELECT avg((dex1 + dex2 + dex3 + dex4 + dex5)/5) from general where npc < 4");
|
||||
$dex *= -1 * $this->dex;
|
||||
}
|
||||
$dex = Util::toInt($dex);
|
||||
|
||||
$this->moveCapital();
|
||||
//TODO:국가를 만들고
|
||||
//TODO:장수를 세팅하고
|
||||
//TODO:외교를 설정한다.
|
||||
$serverID = UniqueConst::$serverID;
|
||||
$existNations = $db->queryFirstColumn("SELECT nation FROM `nation`");
|
||||
$lastNationID = max(
|
||||
max($existNations),
|
||||
$db->queryFirstField("SELECT max(`nation`) FROM `ng_old_nations` WHERE server_id = %s", $serverID),
|
||||
);
|
||||
|
||||
//TODO: 시나리오 구현 후 마무리.
|
||||
//TODO: 임관 모드가 '랜임모드'인 경우 오랑캐와 충돌하므로 해제해야함.
|
||||
|
||||
return [__CLASS__, 'NYI'];
|
||||
$db->update('general', [
|
||||
'gold' => 999999,
|
||||
'rice' => 999999,
|
||||
], true);
|
||||
|
||||
$year = $env['year'];
|
||||
|
||||
$invaderNationIDList = [];
|
||||
refreshNationStaticInfo();
|
||||
foreach ($cities as $cityObj) {
|
||||
if ($cityObj->level != 4) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$lastNationID += 1;
|
||||
$invaderNationID = $lastNationID;
|
||||
$invaderNationIDList[] = $invaderNationID;
|
||||
|
||||
$invaderName = $cityObj->name;
|
||||
$nationName = "ⓞ{$invaderName}족";
|
||||
$nationObj = new Nation($invaderNationID, $nationName, '#800080', 9999999, 9999999, "중원의 부패를 물리쳐라! 이민족 침범!", $tech, "che_병가", 2, [$cityObj->name]);
|
||||
$nationObj->build($env);
|
||||
|
||||
$ruler = (new GeneralBuilder("{$invaderName}대왕", false, null, $lastNationID))
|
||||
->setEgo('che_패권')
|
||||
->setSpecial('che_인덕', 'che_척사')
|
||||
->setLifeSpan($year - 20, $year + 20)
|
||||
->setCityID($cityObj->id)
|
||||
->setNPCType(9)
|
||||
->setStat(Util::toInt($specAvg * 1.8), Util::toInt($specAvg * 1.8), Util::toInt($specAvg * 1.2))
|
||||
->setAffinity(999)
|
||||
->setGoldRice(99999, 99999);
|
||||
$ruler->build($env);
|
||||
|
||||
$nationObj->addGeneral($ruler);
|
||||
|
||||
foreach (Util::range(1, $npcEachCount) as $invaderGenIdx) {
|
||||
$gen = (new GeneralBuilder("{$invaderName}장수{$invaderGenIdx}", false, null, $invaderNationID))
|
||||
->setEgo('che_패권')
|
||||
->setSpecial('che_인덕', 'che_척사')
|
||||
->setLifeSpan($year - 20, $year + 20)
|
||||
->setCityID($cityObj->id)
|
||||
->setNPCType(9)
|
||||
->setAffinity(999)
|
||||
->setGoldRice(99999, 99999);
|
||||
|
||||
$leadership = Util::randRangeInt(Util::toInt($specAvg * 1.2), Util::toInt($specAvg * 1.4));
|
||||
$mainStat = Util::randRangeInt(Util::toInt($specAvg * 1.2), Util::toInt($specAvg * 1.4));
|
||||
$subStat = $specAvg * 3 - $leadership - $mainStat;
|
||||
|
||||
if (Util::randBool()) {
|
||||
//무장
|
||||
$dexTable = [$dex * 2, $dex, $dex];
|
||||
shuffle($dexTable);
|
||||
$gen->setStat($leadership, $mainStat, $subStat)
|
||||
->setDex($dexTable[0], $dexTable[1], $dexTable[2], $dex, 0);
|
||||
} else {
|
||||
//지장
|
||||
$gen->setStat($leadership, $subStat, $mainStat)
|
||||
->setDex($dex, $dex, $dex, $dex * 2, 0);
|
||||
}
|
||||
$gen->build($env);
|
||||
$nationObj->addGeneral($gen);
|
||||
}
|
||||
|
||||
$nationObj->postBuild($env);
|
||||
refreshNationStaticInfo();
|
||||
$db->insert('event', [
|
||||
'condition' => Json::encode(true),
|
||||
'action' => Json::encode([["AutoDeleteInvader", $invaderNationID]]),
|
||||
]);
|
||||
|
||||
}
|
||||
$db->insert('event', [
|
||||
'condition' => Json::encode(true),
|
||||
'action' => Json::encode([["InvaderEnding"]]),
|
||||
]);
|
||||
|
||||
$db->update('nation', [
|
||||
'scout' => 1
|
||||
], 'nation IN %li', $invaderNationIDList);
|
||||
$db->update('diplomacy', [
|
||||
'state' => 1,
|
||||
'term' => 24,
|
||||
], '(me IN %li AND you IN %li) OR (me IN %li AND you IN %li)', $existNations, $invaderNationIDList, $invaderNationIDList, $existNations);
|
||||
|
||||
$db->update('diplomacy', [
|
||||
'state' => 7,
|
||||
'term' => 480,
|
||||
], '(me IN %li AND you IN %li)', $invaderNationIDList, $invaderNationIDList);
|
||||
|
||||
$cityMaxPop = $specAvg * $npcEachCount * 100 * 4;
|
||||
$db->update('city', [
|
||||
'pop_max' => $cityMaxPop,
|
||||
'def_max' => 100000,
|
||||
'wall_max' => 10000,
|
||||
], 'nation IN %li', $invaderNationIDList);
|
||||
|
||||
$db->update('city', [
|
||||
'pop' => $db->sqleval('pop_max'),
|
||||
'agri' => $db->sqleval('agri_max'),
|
||||
'comm' => $db->sqleval('comm_max'),
|
||||
'secu' => $db->sqleval('secu_max'),
|
||||
], true);
|
||||
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$gameStor->setValue('isunited', 1);
|
||||
refreshNationStaticInfo();
|
||||
|
||||
$logger = new ActionLogger(0, 0, $year, $env['month']);
|
||||
$logger->pushGlobalHistoryLog("<L><b>【이벤트】</b></>각지의 이민족들이 <M>궐기</>합니다!");
|
||||
$logger->pushGlobalHistoryLog("<L><b>【이벤트】</b></>중원의 전 국가에 <M>선전포고</> 합니다!");
|
||||
$logger->pushGlobalHistoryLog("<L><b>【이벤트】</b></>이민족의 기세는 그 누구도 막을 수 없을듯 합니다!");
|
||||
$logger->flush();
|
||||
|
||||
$db->update('plock', [
|
||||
'plock' => 0
|
||||
], true);
|
||||
|
||||
return [__CLASS__, count($invaderNationIDList)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ namespace sammo\Event\Action;
|
||||
|
||||
//이전 RegNPC 함수를 EventAction으로 재구성
|
||||
class RegNPC extends \sammo\Event\Action{
|
||||
/** @var \sammo\Scenario\GeneralBuilder */
|
||||
private $npc;
|
||||
|
||||
public function __construct(
|
||||
@@ -14,6 +15,7 @@ class RegNPC extends \sammo\Event\Action{
|
||||
int $leadership,
|
||||
int $strength,
|
||||
int $intel,
|
||||
int $officerLevel,
|
||||
int $birth = 160,
|
||||
int $death = 300,
|
||||
$ego = null,
|
||||
@@ -21,7 +23,7 @@ class RegNPC extends \sammo\Event\Action{
|
||||
$text = ''
|
||||
){
|
||||
|
||||
return (new \sammo\Scenario\GeneralBuilder(
|
||||
$this->npc=(new \sammo\Scenario\GeneralBuilder(
|
||||
$name,
|
||||
0,
|
||||
$picturePath,
|
||||
@@ -29,16 +31,16 @@ class RegNPC extends \sammo\Event\Action{
|
||||
))
|
||||
->setCity($locatedCity)
|
||||
->setStat($leadership, $strength, $intel)
|
||||
->setOfficerLevel($officerLevel)
|
||||
->setEgo($ego)
|
||||
->setSpecialSingle($char)
|
||||
->setNPCText($text?:'')
|
||||
->setAffinity($affinity)
|
||||
->setLifeSpan($birth, $death)
|
||||
->fillRemainSpecAsZero();
|
||||
->setLifeSpan($birth, $death);
|
||||
}
|
||||
|
||||
public function run($env=null){
|
||||
$result = $this->npc->build($env);
|
||||
public function run(array $env){
|
||||
$result = $this->npc->fillRemainSpecAsZero($env)->build($env);
|
||||
return [__CLASS__, $result];
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ namespace sammo\Event\Action;
|
||||
|
||||
class RegNeutralNPC extends \sammo\Event\Action{
|
||||
|
||||
/** @var \sammo\Scenario\GeneralBuilder */
|
||||
private $npc;
|
||||
|
||||
public function __construct(
|
||||
@@ -20,7 +21,7 @@ class RegNeutralNPC extends \sammo\Event\Action{
|
||||
$char = '',
|
||||
$text = ''
|
||||
){
|
||||
return (new \sammo\Scenario\GeneralBuilder(
|
||||
$this->npc=(new \sammo\Scenario\GeneralBuilder(
|
||||
$name,
|
||||
0,
|
||||
$picturePath,
|
||||
@@ -33,12 +34,11 @@ class RegNeutralNPC extends \sammo\Event\Action{
|
||||
->setNPCText($text?:'')
|
||||
->setAffinity($affinity)
|
||||
->setLifeSpan($birth, $death)
|
||||
->setNPCType(6)
|
||||
->fillRemainSpecAsZero();
|
||||
->setNPCType(6);
|
||||
}
|
||||
|
||||
public function run($env=null){
|
||||
$result = $this->npc->build($env);
|
||||
public function run(array $env){
|
||||
$result = $this->npc->fillRemainSpecAsZero($env)->build($env);
|
||||
return [__CLASS__, $result];
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ class EventHandler{
|
||||
|
||||
}
|
||||
|
||||
public function tryRunEvent(array $env=null){
|
||||
public function tryRunEvent(array $env){
|
||||
$result = $this->condition->eval($env);
|
||||
|
||||
if(!$result['value']){
|
||||
|
||||
+128
-31
@@ -657,29 +657,62 @@ class GeneralAI
|
||||
return null;
|
||||
}
|
||||
|
||||
$cityCandidates = [];
|
||||
|
||||
if($this->backupCities){
|
||||
$cities = $this->backupCities;
|
||||
}
|
||||
else{
|
||||
$cities = $this->supplyCities;
|
||||
/** @var General */
|
||||
$pickedGeneral = Util::choiceRandom($generalCadidates);
|
||||
$minRecruitPop = $this->fullLeadership * 100 + GameConst::$minAvailableRecruitPop;
|
||||
if(!$this->generalPolicy->can한계징병){
|
||||
$minRecruitPop = max($minRecruitPop, $this->fullLeadership * 100 + $this->nationPolicy->minNPCRecruitCityPopulation);
|
||||
}
|
||||
|
||||
foreach($cities as $city){
|
||||
if($city['pop'] / $city['pop_max'] < $this->nationPolicy->safeRecruitCityPopulationRatio){
|
||||
$recruitableCityList = [];
|
||||
|
||||
foreach($this->backupCities as $candidateCity){
|
||||
$pop_ratio = $candidateCity['pop']/$candidateCity['pop_max'];
|
||||
$cityID = $candidateCity['city'];
|
||||
if($candidateCity['city'] == $this->city['city']){
|
||||
continue;
|
||||
}
|
||||
$cityCandidates[] = $city;
|
||||
if($candidateCity['pop'] < $minRecruitPop){
|
||||
continue;
|
||||
}
|
||||
|
||||
if($pop_ratio < $this->nationPolicy->safeRecruitCityPopulationRatio){
|
||||
$pop_ratio /= 4;
|
||||
}
|
||||
|
||||
$recruitableCityList[$cityID] = $pop_ratio;
|
||||
}
|
||||
|
||||
if(!$cityCandidates){
|
||||
if(!$recruitableCityList){
|
||||
foreach($this->supplyCities as $candidateCity){
|
||||
$pop_ratio = $candidateCity['pop']/$candidateCity['pop_max'];
|
||||
$cityID = $candidateCity['city'];
|
||||
if($candidateCity['city'] == $this->city['city']){
|
||||
continue;
|
||||
}
|
||||
if($candidateCity['pop'] <= $minRecruitPop){
|
||||
continue;
|
||||
}
|
||||
|
||||
if($pop_ratio < $this->nationPolicy->safeRecruitCityPopulationRatio){
|
||||
$pop_ratio /= 2;
|
||||
}
|
||||
|
||||
if(key_exists($cityID, $this->frontCities)){
|
||||
$pop_ratio / 2;
|
||||
}
|
||||
|
||||
$recruitableCityList[$cityID] = $pop_ratio;
|
||||
}
|
||||
}
|
||||
|
||||
if(!$recruitableCityList){
|
||||
return null;
|
||||
}
|
||||
|
||||
$cmd = buildNationCommandClass('che_발령', $this->general, $this->env, $lastTurn, [
|
||||
'destGeneralID'=>Util::choiceRandom($generalCadidates)->getID(),
|
||||
'destCityID'=>Util::choiceRandom($cityCandidates)['city']
|
||||
'destGeneralID'=>$pickedGeneral->getID(),
|
||||
'destCityID'=>Util::choiceRandomUsingWeight($recruitableCityList)
|
||||
]);
|
||||
|
||||
if(!$cmd->hasFullConditionMet()){
|
||||
@@ -923,29 +956,66 @@ class GeneralAI
|
||||
return null;
|
||||
}
|
||||
|
||||
$cityCandidates = [];
|
||||
|
||||
if($this->backupCities){
|
||||
$cities = $this->backupCities;
|
||||
}
|
||||
else{
|
||||
$cities = $this->supplyCities;
|
||||
/** @var General */
|
||||
$pickedGeneral = Util::choiceRandom($generalCadidates);
|
||||
$minRecruitPop = $this->fullLeadership * 100 + GameConst::$minAvailableRecruitPop;
|
||||
if(!$this->generalPolicy->can한계징병){
|
||||
$minRecruitPop = max($minRecruitPop, $this->fullLeadership * 100 + $this->nationPolicy->minNPCRecruitCityPopulation);
|
||||
}
|
||||
|
||||
foreach($cities as $city){
|
||||
if($city['pop'] / $city['pop_max'] < $this->nationPolicy->safeRecruitCityPopulationRatio){
|
||||
$recruitableCityList = [];
|
||||
|
||||
foreach($this->backupCities as $candidateCity){
|
||||
$pop_ratio = $candidateCity['pop']/$candidateCity['pop_max'];
|
||||
$cityID = $candidateCity['city'];
|
||||
if($candidateCity['city'] == $this->city['city']){
|
||||
continue;
|
||||
}
|
||||
$cityCandidates[] = $city;
|
||||
if($candidateCity['pop'] < $this->nationPolicy->minNPCRecruitCityPopulation){
|
||||
continue;
|
||||
}
|
||||
if($candidateCity['pop'] < $minRecruitPop){
|
||||
continue;
|
||||
}
|
||||
if($pop_ratio < $this->nationPolicy->safeRecruitCityPopulationRatio){
|
||||
continue;
|
||||
}
|
||||
|
||||
$recruitableCityList[$cityID] = $pop_ratio;
|
||||
}
|
||||
|
||||
if(!$cityCandidates){
|
||||
if(!$recruitableCityList){
|
||||
foreach($this->supplyCities as $candidateCity){
|
||||
$pop_ratio = $candidateCity['pop']/$candidateCity['pop_max'];
|
||||
$cityID = $candidateCity['city'];
|
||||
if($candidateCity['city'] == $this->city['city']){
|
||||
continue;
|
||||
}
|
||||
if($candidateCity['pop'] < $this->nationPolicy->minNPCRecruitCityPopulation){
|
||||
continue;
|
||||
}
|
||||
if($candidateCity['pop'] <= $minRecruitPop){
|
||||
continue;
|
||||
}
|
||||
if($pop_ratio < $this->nationPolicy->safeRecruitCityPopulationRatio){
|
||||
continue;
|
||||
}
|
||||
|
||||
if(key_exists($cityID, $this->frontCities)){
|
||||
$pop_ratio / 2;
|
||||
}
|
||||
|
||||
$recruitableCityList[$cityID] = $pop_ratio;
|
||||
}
|
||||
}
|
||||
|
||||
if(!$recruitableCityList){
|
||||
return null;
|
||||
}
|
||||
|
||||
$cmd = buildNationCommandClass('che_발령', $this->general, $this->env, $lastTurn, [
|
||||
'destGeneralID'=>Util::choiceRandom($generalCadidates)->getID(),
|
||||
'destCityID'=>Util::choiceRandom($cityCandidates)['city']
|
||||
'destGeneralID'=>$pickedGeneral->getID(),
|
||||
'destCityID'=>Util::choiceRandomUsingWeight($recruitableCityList)
|
||||
]);
|
||||
|
||||
if(!$cmd->hasFullConditionMet()){
|
||||
@@ -2669,31 +2739,42 @@ class GeneralAI
|
||||
|
||||
protected function do후방워프(): ?GeneralCommand
|
||||
{
|
||||
$minRecruitPop = $this->fullLeadership * 100 + GameConst::$minAvailableRecruitPop;
|
||||
if(!$this->generalPolicy->can한계징병){
|
||||
$minRecruitPop = max($minRecruitPop, $this->fullLeadership * 100 + $this->nationPolicy->minNPCRecruitCityPopulation);
|
||||
}
|
||||
if (in_array($this->dipState, [self::d평화, self::d선포])) {
|
||||
LogText("{$this->general->getName()}, {$this->general->getID()} 후방워프 불가: 외교 상태", $this->dipState);
|
||||
return null;
|
||||
}
|
||||
|
||||
if(!$this->generalPolicy->can징병){
|
||||
LogText("{$this->general->getName()}, {$this->general->getID()} 후방워프 불가: 징병 금지", '');
|
||||
return null;
|
||||
}
|
||||
|
||||
if(!($this->genType & self::t통솔장)){
|
||||
LogText("{$this->general->getName()}, {$this->general->getID()} 후방워프 불가: 통솔장", [$this->genType, $this->general->getLeadership(false)]);
|
||||
return null;
|
||||
}
|
||||
|
||||
if($this->general->getVar('crew') >= $this->nationPolicy->minWarCrew){
|
||||
LogText("{$this->general->getName()}, {$this->general->getID()} 후방워프 불가: 병력 충분", [$this->general->getVar('crew'), $this->nationPolicy->minWarCrew]);
|
||||
return null;
|
||||
}
|
||||
|
||||
$city = $this->city;
|
||||
if($this->generalPolicy->can한계징병){
|
||||
if($city['pop'] >= $this->fullLeadership * 100 + GameConst::$minAvailableRecruitPop){
|
||||
if($city['pop'] >= $minRecruitPop){
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else{
|
||||
if($city['pop']/$city['pop_max'] >= $this->nationPolicy->safeRecruitCityPopulationRatio){
|
||||
return null;
|
||||
if($city['pop'] >= $this->nationPolicy->minNPCRecruitCityPopulation && $city['pop'] >= $minRecruitPop){
|
||||
LogText("{$this->general->getName()}, {$this->general->getID()} 후방워프 불가: 인구 충분", [$city['pop']/$city['pop_max'], $this->nationPolicy->safeRecruitCityPopulationRatio]);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2710,19 +2791,31 @@ class GeneralAI
|
||||
if($pop_ratio < $this->nationPolicy->safeRecruitCityPopulationRatio){
|
||||
continue;
|
||||
}
|
||||
if($candidateCity['pop'] < $this->nationPolicy->minNPCRecruitCityPopulation){
|
||||
continue;
|
||||
}
|
||||
if($candidateCity['pop'] < $minRecruitPop){
|
||||
continue;
|
||||
}
|
||||
$recruitableCityList[$cityID] = $pop_ratio;
|
||||
}
|
||||
|
||||
if(!$recruitableCityList){
|
||||
foreach($this->supplyCities as $candidateCity){
|
||||
$pop_ratio = $candidateCity['pop']/$candidateCity['pop_max'];
|
||||
$cityID = $candidateCity['city'];
|
||||
if($candidateCity['city'] == $this->city['city']){
|
||||
continue;
|
||||
}
|
||||
if($candidateCity['pop'] <= $this->fullLeadership * 100 + GameConst::$minAvailableRecruitPop){
|
||||
if($candidateCity['pop'] < $this->nationPolicy->minNPCRecruitCityPopulation){
|
||||
continue;
|
||||
}
|
||||
if($candidateCity['pop'] <= $minRecruitPop){
|
||||
continue;
|
||||
}
|
||||
if($pop_ratio < $this->nationPolicy->safeRecruitCityPopulationRatio){
|
||||
continue;
|
||||
}
|
||||
$pop_ratio = $candidateCity['pop']/$candidateCity['pop_max'];
|
||||
$cityID = $candidateCity['city'];
|
||||
if(key_exists($cityID, $this->frontCities)){
|
||||
$recruitableCityList[$cityID] = $pop_ratio / 2;
|
||||
}
|
||||
@@ -2733,6 +2826,7 @@ class GeneralAI
|
||||
}
|
||||
|
||||
if(!$recruitableCityList){
|
||||
LogText("{$this->general->getName()}, {$this->general->getID()} 후방워프 불가: 배후 도시", [count($this->backupCities), count($this->supplyCities)]);
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -2744,6 +2838,7 @@ class GeneralAI
|
||||
|
||||
|
||||
if(!$cmd->hasFullConditionMet()){
|
||||
LogText("{$this->general->getName()}, {$this->general->getID()} 후방워프 불가: 조건 불충족", $cmd->getArg());
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -3364,6 +3459,7 @@ class GeneralAI
|
||||
foreach($this->nationPolicy->priority as $actionName){
|
||||
|
||||
if(!property_exists($this->nationPolicy, 'can'.$actionName)){
|
||||
trigger_error ("can{$actionName}이 없음", E_USER_NOTICE );
|
||||
continue;
|
||||
}
|
||||
if(!$this->nationPolicy->{'can'.$actionName}){
|
||||
@@ -3517,6 +3613,7 @@ class GeneralAI
|
||||
|
||||
foreach($this->generalPolicy->priority as $actionName){
|
||||
if(!property_exists($this->generalPolicy, 'can'.$actionName)){
|
||||
trigger_error ("can{$actionName}이 없음", E_USER_NOTICE );
|
||||
continue;
|
||||
}
|
||||
if(!($this->generalPolicy->{'can'.$actionName})){
|
||||
|
||||
@@ -26,7 +26,7 @@ class RandomNameGeneral extends AbsGeneralPool{
|
||||
return $db->affectedRows()!=0;
|
||||
}
|
||||
|
||||
public function giveGeneralSpec(array $pickTypeList, array $avgGen, array $env=[]){
|
||||
public function giveGeneralSpec(array $pickTypeList, array $avgGen, array $env){
|
||||
//do Nothing
|
||||
$dexTotal = $avgGen['dex_t'];
|
||||
|
||||
|
||||
+116
-119
@@ -1,6 +1,8 @@
|
||||
<?php
|
||||
namespace sammo;
|
||||
|
||||
use sammo\Scenario\GeneralBuilder;
|
||||
|
||||
class Scenario{
|
||||
const SCENARIO_PATH = __DIR__.'/../scenario';
|
||||
|
||||
@@ -37,10 +39,115 @@ class Scenario{
|
||||
private $initialEvents;
|
||||
private $events;
|
||||
|
||||
private $initBasic = false;
|
||||
private $initOK = false;
|
||||
|
||||
private $gameConf = null;
|
||||
|
||||
public function generateGeneral($rawGeneral, $initFull, $npcType=2): GeneralBuilder{
|
||||
while(count($rawGeneral) < 14){
|
||||
$rawGeneral[] = null;
|
||||
}
|
||||
|
||||
list(
|
||||
$affinity, $name, $picturePath, $nationName, $locatedCity,
|
||||
$leadership, $strength, $intel, $officerLevel, $birth, $death, $ego,
|
||||
$char, $text
|
||||
) = $rawGeneral;
|
||||
|
||||
if(key_exists($nationName, $this->nationsInv)){
|
||||
$nationID = $this->nationsInv[$nationName]->getID();
|
||||
}
|
||||
else if(key_exists($nationName, $this->nations)){
|
||||
$nationID = (int)$nationName;
|
||||
}
|
||||
else{
|
||||
$nationID = 0;
|
||||
}
|
||||
|
||||
$this->tmpGeneralQueue[$name] = $rawGeneral;
|
||||
|
||||
$obj = (new Scenario\GeneralBuilder(
|
||||
$name,
|
||||
false,
|
||||
$picturePath,
|
||||
$nationID
|
||||
));
|
||||
if(!$initFull){
|
||||
return $obj;
|
||||
}
|
||||
return $obj
|
||||
->setCity($locatedCity, true)
|
||||
->setStat($leadership, $strength, $intel)
|
||||
->setOfficerLevel($officerLevel)
|
||||
->setEgo($ego)
|
||||
->setSpecialSingle($char)
|
||||
->setNPCText($text)
|
||||
->setAffinity($affinity)
|
||||
->setLifeSpan($birth, $death)
|
||||
->setNPCType($npcType)
|
||||
->fillRemainSpecAsZero($this->tmpEnv);
|
||||
}
|
||||
|
||||
public function initLite(){
|
||||
if($this->initOK){
|
||||
return;
|
||||
}
|
||||
if($this->initBasic){
|
||||
return;
|
||||
}
|
||||
|
||||
$data = $this->data;
|
||||
$this->tmpEnv = [
|
||||
'startyear'=>$this->year,
|
||||
'year'=>$this->year,
|
||||
'month'=>0 //포인트
|
||||
];
|
||||
|
||||
$neutralNation = new Scenario\Nation(0, '재야', '#000000', 0, 0);
|
||||
$this->nations = [];
|
||||
$this->nations[0] = $neutralNation;
|
||||
$this->nationsInv = [$neutralNation->getName() => $neutralNation];
|
||||
|
||||
foreach (Util::array_get($data['nation'],[]) as $idx=>$rawNation) {
|
||||
list($name, $color, $gold, $rice, $infoText, $tech, $type, $nationLevel, $cities) = $rawNation;
|
||||
$nationID = $idx+1;
|
||||
|
||||
|
||||
$nation = new Scenario\Nation(
|
||||
$nationID,
|
||||
$name,
|
||||
$color,
|
||||
$gold,
|
||||
$rice,
|
||||
$infoText,
|
||||
$tech,
|
||||
$type,
|
||||
$nationLevel,
|
||||
$cities
|
||||
);
|
||||
$this->nations[$nationID] = $nation;
|
||||
$this->nationsInv[$nation->getName()] = $nation;
|
||||
}
|
||||
|
||||
$this->diplomacy = Util::array_get($data['diplomacy'], []);
|
||||
|
||||
|
||||
$this->generals = array_map(function($rawGeneral){
|
||||
return $this->generateGeneral($rawGeneral, false, 2);
|
||||
}, Util::array_get($data['general'], []));
|
||||
|
||||
$this->generalsEx = array_map(function($rawGeneral){
|
||||
return $this->generateGeneral($rawGeneral, false, 2);
|
||||
}, Util::array_get($data['general_ex'], []));
|
||||
|
||||
$this->generalsNeutral = array_map(function($rawGeneral){
|
||||
return $this->generateGeneral($rawGeneral, false, 6);
|
||||
}, Util::array_get($data['general_neutral'], []));
|
||||
|
||||
$this->initBasic = true;
|
||||
}
|
||||
|
||||
public function initFull(){
|
||||
if($this->initOK){
|
||||
return;
|
||||
@@ -83,125 +190,15 @@ class Scenario{
|
||||
|
||||
|
||||
$this->generals = array_map(function($rawGeneral){
|
||||
while(count($rawGeneral) < 14){
|
||||
$rawGeneral[] = null;
|
||||
}
|
||||
|
||||
list(
|
||||
$affinity, $name, $picturePath, $nationName, $locatedCity,
|
||||
$leadership, $strength, $intel, $officerLevel, $birth, $death, $ego,
|
||||
$char, $text
|
||||
) = $rawGeneral;
|
||||
|
||||
if(key_exists($nationName, $this->nationsInv)){
|
||||
$nationID = $this->nationsInv[$nationName]->getID();
|
||||
}
|
||||
else if(key_exists($nationName, $this->nations)){
|
||||
$nationID = (int)$nationName;
|
||||
}
|
||||
else{
|
||||
$nationID = 0;
|
||||
}
|
||||
|
||||
$this->tmpGeneralQueue[$name] = $rawGeneral;
|
||||
|
||||
return (new Scenario\GeneralBuilder(
|
||||
$name,
|
||||
false,
|
||||
$picturePath,
|
||||
$nationID
|
||||
))
|
||||
->setCity($locatedCity)
|
||||
->setStat($leadership, $strength, $intel)
|
||||
->setOfficerLevel($officerLevel)
|
||||
->setEgo($ego)
|
||||
->setSpecialSingle($char)
|
||||
->setNPCText($text)
|
||||
->setAffinity($affinity)
|
||||
->setLifeSpan($birth, $death)
|
||||
->fillRemainSpecAsZero($this->tmpEnv);
|
||||
return $this->generateGeneral($rawGeneral, true, 2);
|
||||
}, Util::array_get($data['general'], []));
|
||||
|
||||
$this->generalsEx = array_map(function($rawGeneral){
|
||||
while(count($rawGeneral) < 14){
|
||||
$rawGeneral[] = null;
|
||||
}
|
||||
|
||||
list(
|
||||
$affinity, $name, $picturePath, $nationName, $locatedCity,
|
||||
$leadership, $strength, $intel, $officerLevel, $birth, $death, $ego,
|
||||
$char, $text
|
||||
) = $rawGeneral;
|
||||
|
||||
if(key_exists($nationName, $this->nationsInv)){
|
||||
$nationID = $this->nationsInv[$nationName]->getID();
|
||||
}
|
||||
else if(key_exists($nationName, $this->nations)){
|
||||
$nationID = (int)$nationName;
|
||||
}
|
||||
else{
|
||||
$nationID = 0;
|
||||
}
|
||||
|
||||
$this->tmpGeneralQueue[$name] = $rawGeneral;
|
||||
|
||||
return (new Scenario\GeneralBuilder(
|
||||
$name,
|
||||
false,
|
||||
$picturePath,
|
||||
$nationID
|
||||
))
|
||||
->setCity($locatedCity, true)
|
||||
->setStat($leadership, $strength, $intel)
|
||||
->setOfficerLevel($officerLevel)
|
||||
->setEgo($ego)
|
||||
->setSpecialSingle($char)
|
||||
->setNPCText($text)
|
||||
->setAffinity($affinity)
|
||||
->setLifeSpan($birth, $death)
|
||||
->fillRemainSpecAsZero($this->tmpEnv);
|
||||
|
||||
return $this->generateGeneral($rawGeneral, true, 2);
|
||||
}, Util::array_get($data['general_ex'], []));
|
||||
|
||||
$this->generalsNeutral = array_map(function($rawGeneral){
|
||||
while(count($rawGeneral) < 14){
|
||||
$rawGeneral[] = null;
|
||||
}
|
||||
|
||||
list(
|
||||
$affinity, $name, $picturePath, $nationName, $locatedCity,
|
||||
$leadership, $strength, $intel, $officerLevel, $birth, $death, $ego,
|
||||
$char, $text
|
||||
) = $rawGeneral;
|
||||
|
||||
if(key_exists($nationName, $this->nationsInv)){
|
||||
$nationID = $this->nationsInv[$nationName]->getID();
|
||||
}
|
||||
else if(key_exists($nationName, $this->nations)){
|
||||
$nationID = (int)$nationName;
|
||||
}
|
||||
else{
|
||||
$nationID = 0;
|
||||
}
|
||||
|
||||
$this->tmpGeneralQueue[$name] = $rawGeneral;
|
||||
|
||||
return (new Scenario\GeneralBuilder(
|
||||
$name,
|
||||
false,
|
||||
$picturePath,
|
||||
$nationID
|
||||
))
|
||||
->setCity($locatedCity, true)
|
||||
->setStat($leadership, $strength, $intel)
|
||||
->setOfficerLevel($officerLevel)
|
||||
->setEgo($ego)
|
||||
->setSpecialSingle($char)
|
||||
->setNPCText($text)
|
||||
->setAffinity($affinity)
|
||||
->setLifeSpan($birth, $death)
|
||||
->setNPCType(6)
|
||||
->fillRemainSpecAsZero($this->tmpEnv);
|
||||
return $this->generateGeneral($rawGeneral, true, 6);
|
||||
}, Util::array_get($data['general_neutral'], []));
|
||||
|
||||
$this->initialEvents = array_map(function($rawEvent){
|
||||
@@ -293,22 +290,22 @@ class Scenario{
|
||||
}
|
||||
|
||||
public function getNPC(){
|
||||
$this->initFull();
|
||||
$this->initLite();
|
||||
return $this->generals;
|
||||
}
|
||||
|
||||
public function getNPCex(){
|
||||
$this->initFull();
|
||||
$this->initLite();
|
||||
return $this->generalsEx;
|
||||
}
|
||||
|
||||
public function getNPCneutral(){
|
||||
$this->initFull();
|
||||
$this->initLite();
|
||||
return $this->generalsNeutral;
|
||||
}
|
||||
|
||||
public function getNation(){
|
||||
$this->initFull();
|
||||
$this->initLite();
|
||||
return $this->nations;
|
||||
}
|
||||
|
||||
@@ -321,7 +318,7 @@ class Scenario{
|
||||
}
|
||||
|
||||
public function getScenarioBrief(){
|
||||
$this->initFull();
|
||||
$this->initLite();
|
||||
|
||||
$nations = [];
|
||||
$nationGeneralCnt = [];
|
||||
@@ -485,7 +482,7 @@ class Scenario{
|
||||
copy("$unitPath/$unitSet.php", $path.'/GameUnitConst.php');
|
||||
}
|
||||
|
||||
public function build($env=[]){
|
||||
public function build($env){
|
||||
|
||||
$db = DB::db();
|
||||
getGeneralPoolClass(GameConst::$targetGeneralPool)::initPool($db);
|
||||
|
||||
@@ -337,7 +337,7 @@ class GeneralBuilder{
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function fillRemainSpecAsZero(array $env=[]):self{
|
||||
public function fillRemainSpecAsZero(array $env):self{
|
||||
if($this->leadership===null){
|
||||
throw new \RuntimeException('stat이 설정되어 있지 않음');
|
||||
}
|
||||
@@ -390,7 +390,7 @@ class GeneralBuilder{
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function fillRemainSpecAsRandom(array $pickTypeList, array $avgGen, array $env=[]):self{
|
||||
public function fillRemainSpecAsRandom(array $pickTypeList, array $avgGen, array $env):self{
|
||||
|
||||
$isFictionMode = (Util::array_get($env['fiction'], 0)!=0);
|
||||
|
||||
@@ -532,7 +532,7 @@ class GeneralBuilder{
|
||||
return $this->death;
|
||||
}
|
||||
|
||||
public function build($env=[]){
|
||||
public function build($env){
|
||||
//scenario에 life==1인 경우 수명 제한이 없어지는 모양.
|
||||
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ class Nation{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function build($env=[]){
|
||||
public function build($env){
|
||||
//NOTE: NPC의 숫자는 아직 확정된 것이 아니다.
|
||||
$cities = array_map(function($cityName){
|
||||
return \sammo\CityHelper::getCityByName($cityName)['id'];
|
||||
@@ -147,7 +147,7 @@ class Nation{
|
||||
$this->generals[] = $general;
|
||||
}
|
||||
|
||||
public function postBuild($env=[]){
|
||||
public function postBuild($env){
|
||||
$npc_cnt = count($this->generals);
|
||||
|
||||
$db = DB::db();
|
||||
|
||||
@@ -186,7 +186,7 @@ class TurnExecutionHelper
|
||||
|
||||
$general->setVar('killturn', ($general->getVar('deadyear') - $gameStor->year) * 12);
|
||||
$general->setVar('npc', $general->getVar('npc_org'));
|
||||
$general->setVar('owner', 1);
|
||||
$general->setVar('owner', 0);
|
||||
$general->setVar('defence_train', 80);
|
||||
$general->setVar('owner_name', null);
|
||||
}
|
||||
@@ -321,7 +321,7 @@ class TurnExecutionHelper
|
||||
return;
|
||||
}
|
||||
|
||||
if ($gameStor->isunited == 2) {
|
||||
if ($gameStor->isunited == 2 || $gameStor->isunited == 3) {
|
||||
//천통시에는 동결
|
||||
return;
|
||||
}
|
||||
@@ -407,13 +407,22 @@ class TurnExecutionHelper
|
||||
}
|
||||
|
||||
// 이벤트 핸들러 동작
|
||||
$e_env = null;
|
||||
foreach (DB::db()->query('SELECT * from event') as $rawEvent) {
|
||||
if($e_env === null){
|
||||
$e_env = $gameStor->getAll(false);
|
||||
}
|
||||
$eventID = $rawEvent['id'];
|
||||
$cond = Json::decode($rawEvent['condition']);
|
||||
$action = Json::decode($rawEvent['action']);
|
||||
$event = new Event\EventHandler($cond, $action);
|
||||
$e_env['currentEventID'] = $eventID;
|
||||
|
||||
$event->tryRunEvent(['currentEventID'=>$eventID] + $gameStor->getAll(true));
|
||||
$event->tryRunEvent($e_env);
|
||||
}
|
||||
|
||||
if($e_env !== null){
|
||||
$gameStor->resetCache(true);
|
||||
}
|
||||
|
||||
postUpdateMonthly();
|
||||
|
||||
@@ -270,6 +270,9 @@ class WarUnitGeneral extends WarUnit{
|
||||
if($this->hasActivatedSkillOnLog('부상무효')){
|
||||
return false;
|
||||
}
|
||||
if($this->hasActivatedSkillOnLog('퇴각부상무효')){
|
||||
return false;
|
||||
}
|
||||
if(!Util::randBool(0.05)){
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -10,13 +10,19 @@ use sammo\ObjectTrigger;
|
||||
|
||||
class che_반계시도 extends BaseWarUnitTrigger{
|
||||
protected $priority = ObjectTrigger::PRIORITY_BODY + 300;
|
||||
protected $prob;
|
||||
|
||||
public function __construct(WarUnit $unit, int $raiseType = 0, float $prob = 0.4){
|
||||
$this->object = $unit;
|
||||
$this->prob = $prob;
|
||||
}
|
||||
|
||||
protected function actionWar(WarUnit $self, WarUnit $oppose, array &$selfEnv, array &$opposeEnv):bool{
|
||||
if(!$oppose->hasActivatedSkill('계략')){
|
||||
return true;
|
||||
}
|
||||
|
||||
if(!Util::randBool(0.4)){
|
||||
if(!Util::randBool($this->prob)){
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
namespace sammo\WarUnitTrigger;
|
||||
use sammo\BaseWarUnitTrigger;
|
||||
use sammo\WarUnitGeneral;
|
||||
use sammo\WarUnitCity;
|
||||
use sammo\WarUnit;
|
||||
use sammo\GameUnitDetail;
|
||||
use sammo\ObjectTrigger;
|
||||
|
||||
class che_퇴각부상무효 extends BaseWarUnitTrigger{
|
||||
protected $priority = ObjectTrigger::PRIORITY_BEGIN + 300;
|
||||
|
||||
protected function actionWar(WarUnit $self, WarUnit $oppose, array &$selfEnv, array &$opposeEnv):bool{
|
||||
assert($self instanceof WarUnitGeneral, 'General만 발동 가능');
|
||||
$self->activateSkill('퇴각부상무효');
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,7 @@
|
||||
"events":[
|
||||
[
|
||||
["Date", "==", null, 12],
|
||||
["CreateManyNPC", 10],
|
||||
["CreateManyNPC", 30],
|
||||
["DeleteEvent"]
|
||||
]
|
||||
]
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
"events":[
|
||||
[
|
||||
["Date", "==", null, 12],
|
||||
["CreateManyNPC", 10],
|
||||
["CreateManyNPC", 30],
|
||||
["DeleteEvent"]
|
||||
],
|
||||
[
|
||||
|
||||
@@ -4,8 +4,6 @@ namespace sammo;
|
||||
|
||||
require(__DIR__ . '/vendor/autoload.php');
|
||||
|
||||
WebUtil::requireAJAX();
|
||||
|
||||
function getVersion($target = null)
|
||||
{
|
||||
if ($target) {
|
||||
|
||||
+12
-6
@@ -84,7 +84,7 @@ var serverReservedTemplate = "\
|
||||
</td>\
|
||||
";
|
||||
|
||||
$(function() {
|
||||
$(function () {
|
||||
$("#btn_logout").click(Entrance_Logout);
|
||||
Entrance_UpdateServer();
|
||||
});
|
||||
@@ -94,7 +94,7 @@ function Entrance_UpdateServer() {
|
||||
type: 'post',
|
||||
url: "j_server_get_status.php",
|
||||
dataType: 'json',
|
||||
}).then(function(response) {
|
||||
}).then(function (response) {
|
||||
if (response.result == "SUCCESS") {
|
||||
Entrance_drawServerList(response.server);
|
||||
}
|
||||
@@ -104,7 +104,7 @@ function Entrance_UpdateServer() {
|
||||
function Entrance_drawServerList(serverInfos) {
|
||||
var $serverList = $('#server_list');
|
||||
var now = moment().format('YYYY-MM-DD HH:mm:ss');
|
||||
$.each(serverInfos, function(idx, serverInfo) {
|
||||
$.each(serverInfos, function (idx, serverInfo) {
|
||||
var $serverHtml = $(TemplateEngine(serverListTemplate, serverInfo));
|
||||
$serverList.append($serverHtml);
|
||||
if (!serverInfo.exists) {
|
||||
@@ -114,7 +114,7 @@ function Entrance_drawServerList(serverInfos) {
|
||||
var serverPath = "../" + serverInfo.name;
|
||||
|
||||
|
||||
$.getJSON("../" + serverInfo.name + '/j_server_basic_info.php', {}, function(result) {
|
||||
$.getJSON("../" + serverInfo.name + '/j_server_basic_info.php', {}, function (result) {
|
||||
if (result.reserved) {
|
||||
$serverHtml.find('.server_down').detach();
|
||||
$serverHtml.append(
|
||||
@@ -134,7 +134,13 @@ function Entrance_drawServerList(serverInfos) {
|
||||
$serverHtml.find('.server_down').detach();
|
||||
var serverTime = '%s ~ %s'.format(game.startFrom)
|
||||
|
||||
if (game.isUnited == 2) {
|
||||
if (game.isUnited == 3) {
|
||||
$serverHtml.find('.n_country').html('§이벤트 종료§');
|
||||
$serverHtml.find('.server_date').html('{0} <br>~ {1}'.format(game.starttime, game.turntime));
|
||||
} else if (game.isUnited == 1) {
|
||||
$serverHtml.find('.n_country').html('§이벤트 진행중§');
|
||||
$serverHtml.find('.server_date').html('{0} ~'.format(game.starttime));
|
||||
} else if (game.isUnited == 2) {
|
||||
$serverHtml.find('.n_country').html('§천하통일§');
|
||||
$serverHtml.find('.server_date').html('{0} <br>~ {1}'.format(game.starttime, game.turntime));
|
||||
} else if (game.opentime <= now) {
|
||||
@@ -187,7 +193,7 @@ function Entrance_Logout() {
|
||||
type: 'post',
|
||||
url: "j_logout.php",
|
||||
dataType: 'json',
|
||||
}).then(function(response) {
|
||||
}).then(function (response) {
|
||||
if (response.result) {
|
||||
location.href = "../";
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user