forked from devsam/core
등용장 구현을 위한 ScoutMessage 클래스 완성
This commit is contained in:
@@ -3,6 +3,20 @@ namespace sammo;
|
||||
|
||||
class DiplomacticMessage extends Message{
|
||||
|
||||
const ACCEPTED = 1;
|
||||
const DECLINED = -1;
|
||||
const INVALID = 0;
|
||||
|
||||
const TYPE_SURRENDER = 'surrender'; //항복
|
||||
const TYPE_ALLY = 'ally'; //불가침
|
||||
const TYPE_MERGE = 'merge'; //통합
|
||||
const TYPE_CEASE = 'cease'; //종전
|
||||
const TYPE_CANCEL = 'cancel'; //불가침 파기
|
||||
|
||||
|
||||
protected $diplomaticType = '';
|
||||
protected $validDiplomacy = true;
|
||||
|
||||
public function __construct(
|
||||
string $msgType,
|
||||
MessageTarget $src,
|
||||
@@ -16,13 +30,72 @@ class DiplomacticMessage extends Message{
|
||||
if ($msgType !== self::MSGTYPE_DIPLOMACY){
|
||||
throw new \InvalidArgumentException('DiplomaticMessage msgType');
|
||||
}
|
||||
|
||||
$this->diplomaticType = Util::array_get($msgOption['action']);
|
||||
if(array_search($this->diplomaticType, [
|
||||
self::TYPE_SURRENDER,
|
||||
self::TYPE_ALLY,
|
||||
self::TYPE_MERGE,
|
||||
self::TYPE_CEASE,
|
||||
self::TYPE_CANCEL
|
||||
]) === false)
|
||||
{
|
||||
throw new \InvalidArgumentException('Invalid Diplomatic ActionType');
|
||||
}
|
||||
|
||||
parent::__construct(...func_get_args());
|
||||
|
||||
//TODO: 누가, 누구에게 보낸 건지 파싱
|
||||
|
||||
if(Util::array_get($msgOption['used'])){
|
||||
$this->validDiplomacy = false;
|
||||
}
|
||||
|
||||
if($this->$validUntil < (new \DateTime())){
|
||||
$this->validDiplomacy = false;
|
||||
}
|
||||
}
|
||||
|
||||
public function send(){
|
||||
parent::send();
|
||||
/**
|
||||
* @return int 수행 결과 반환, ACCEPTED(등용장 소모), DECLINED(등용장 소모), INVALID 중 반환
|
||||
*/
|
||||
public function agreeMessage(int $receiverID, string &$reason=null):int{
|
||||
//NOTE: 올바른 유저가 agreeMessage() 호출을 한건지는 외부에서 체크 필요(Session->userID 등)
|
||||
|
||||
if(!$this->validScout){
|
||||
if($reason !== null){
|
||||
$reason = '이미 사용한 외교서신입니다';
|
||||
}
|
||||
return self::INVALID;
|
||||
}
|
||||
if($this->mailbox !== $this->dest->nationID + static::MAILBOX_NATIONAL){
|
||||
if($reason !== null){
|
||||
$reason = '송신자가 외교서신을 수락할 수 없습니다';
|
||||
}
|
||||
return self::INVALID;
|
||||
}
|
||||
|
||||
//거절하지 않았어야함.
|
||||
//수뇌여야함
|
||||
//방랑군이 아니어야함
|
||||
//상대도 방랑군이 아니어야함
|
||||
|
||||
//불가침시 : 교전중이 아니어야함, 선포중이 아니어야함. 합병중이 아니어얗.
|
||||
//불가침 파기시 : 불가침 중이어야함.
|
||||
//종전시 : 교전중이거나 선포중이어야함.
|
||||
//합병시 : 양국 다 외교제한이 지나지 않았어야함. 국력, 장수수가 적절해야함. 인접한 국가여야함. 서로 교전중이어선 안됨.
|
||||
// 송신자가 선포, 전쟁중이어선 안됨. 송신자가 C국과 불가침인데 수신자가 C국과 전쟁중이면 안됨
|
||||
//항복시 : 양국 다 외교제한이 지나지 않았어야함. 국력, 장수수가 적절해야함. 인접한 국가여야함. 서로 교전중이어선 안됨.
|
||||
// 송신자가 선포, 전쟁중이어선 안됨. 송신자가 C국과 불가침인데 수신자가 C국과 전쟁중이면 안됨
|
||||
|
||||
|
||||
$db = DB::db();
|
||||
$general = $db->queryFirstRow('SELECT nation, `no`, city, `level` FROM general WHERE `no`=%i', $receiverID);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function declineMessage(string &$reason=null):int{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+16
-1
@@ -245,7 +245,7 @@ class Message
|
||||
if($this->sendCnt > 0){
|
||||
throw new \RuntimeException('이미 전송한 메일입니다.');
|
||||
}
|
||||
if($this->msgType === self::MSGTYPE_PRIVATE){
|
||||
if($this->msgType === self::MSGTYPE_PRIVATE && $this->src->generalID !== $this->dest->generalID){
|
||||
return $this->sendRaw($this->src->generalID);
|
||||
}
|
||||
if($this->msgType === self::MSGTYPE_NATIONAL && $this->src->nationID !== $this->dest->nationID){
|
||||
@@ -295,4 +295,19 @@ class Message
|
||||
|
||||
return $receiveID;
|
||||
}
|
||||
|
||||
public function invalidate(array $newMsgOption=null){
|
||||
if($newMsgOption !== null){
|
||||
$this->msgOption = $newMsgOption;
|
||||
}
|
||||
|
||||
$this->validUntil = new \DateTime('2000-12-31');
|
||||
|
||||
$db = DB::db();
|
||||
$db->update('message', [
|
||||
'msgOption'=>Json::encode($this->msgOption),
|
||||
'validUntil'=>$this->validUntil->format('Y-m-d H:i:s'),
|
||||
]);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,12 +7,14 @@ class MessageTarget {
|
||||
/** @var int */
|
||||
public $nationID;
|
||||
|
||||
/** @var string */
|
||||
public $generalName;
|
||||
/** @var string */
|
||||
public $nationName;
|
||||
/** @var string */
|
||||
public $color;
|
||||
|
||||
public function __construct(int $generalID, int $nationID, string $nationName, string $color){
|
||||
public function __construct(int $generalID, string $generalName, int $nationID, string $nationName, string $color){
|
||||
|
||||
|
||||
if($mailbox > Message::MAILBOX_NATIONAL){
|
||||
@@ -23,6 +25,7 @@ class MessageTarget {
|
||||
}
|
||||
|
||||
$this->generalID = $generalID;
|
||||
$this->generalName = $generalName;
|
||||
$this->nationID = $nationID;
|
||||
$this->nationName = $nationName;
|
||||
$this->color = $color;
|
||||
@@ -36,12 +39,13 @@ class MessageTarget {
|
||||
$arr['nation_id'] = 0;
|
||||
}
|
||||
|
||||
return new MessageTarget($arr['id'], $arr['nation_id'], $arr['nation'], $arr['color']);
|
||||
return new MessageTarget($arr['id'], $arr['name'], $arr['nation_id'], $arr['nation'], $arr['color']);
|
||||
}
|
||||
|
||||
public function toArray() : array{
|
||||
return [
|
||||
'id'=>$this->generalID,
|
||||
'name'=>$this->generalName,
|
||||
'nation_id'=>$this->nationID,
|
||||
'nation'=>$this->nationName,
|
||||
'color'=>$this->color
|
||||
|
||||
+282
-16
@@ -31,31 +31,295 @@ class ScoutMessage extends Message{
|
||||
if(Util::array_get($msgOption['used'])){
|
||||
$this->validScout = false;
|
||||
}
|
||||
|
||||
if($this->validUntil <= new DateTime()){
|
||||
$this->validScout = false;
|
||||
}
|
||||
}
|
||||
|
||||
protected function checkAgreeValidation(int $startYear, int $year, array $general, array $scoutNation){
|
||||
if($year < $startYear + 3){
|
||||
return [self::INVALID, '초반제한 중입니다.'];
|
||||
}
|
||||
|
||||
if(!$this->validScout){
|
||||
return [self::INVALID, '유효하지 않은 등용장입니다.'];
|
||||
}
|
||||
if($this->mailbox !== $this->dest->generalID){
|
||||
return [self::INVALID, '송신자가 등용장을 수락할 수 없습니다.'];
|
||||
}
|
||||
|
||||
if($this->mailbox !== $receiverID){
|
||||
return [self::INVALID, '올바른 수신자가 아닙니다.'];
|
||||
}
|
||||
|
||||
if(!$scoutNation){
|
||||
return [self::DECLINED, '이미 멸망한 국가입니다.'];
|
||||
}
|
||||
|
||||
if(!$scoutNation['scout']){
|
||||
return [self::INVALID, '현재 임관금지 중인 국가입니다.'];
|
||||
}
|
||||
|
||||
if($scoutNation['level'] == 0){
|
||||
return [self::DECLINED, '방랑군에는 임관할 수 없습니다.'];
|
||||
}
|
||||
|
||||
if($scoutNation['nation'] == $general['nation']){
|
||||
return [self::DECLINED, '이미 같은 국가입니다.'];
|
||||
}
|
||||
|
||||
if($general['level'] == 12){
|
||||
return [self::DECLINED, '군주는 등용장을 수락할 수 없습니다.'];
|
||||
}
|
||||
|
||||
if(strpos($general['nations'], ",{$scoutNation['nation']},") >= 0){
|
||||
return [self::DECLINED, '이미 임관했었던 국가입니다.'];
|
||||
}
|
||||
|
||||
return [self::ACCEPTED, ''];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int 수행 결과 반환, ACCEPTED(등용장 소모), DECLINED(등용장 소모), INVALID 중 반환
|
||||
*/
|
||||
public function agreeMessage(string &$reason=null):int{
|
||||
public function agreeMessage(int $receiverID):int{
|
||||
//NOTE: 올바른 유저가 agreeMessage() 호출을 한건지는 외부에서 체크 필요(Session->userID 등)
|
||||
|
||||
if(!$this->validScout){
|
||||
if($reason !== null){
|
||||
$reason = '이미 사용한 등용장입니다';
|
||||
}
|
||||
return self::INVALID;
|
||||
if(!$this->id){
|
||||
throw \RuntimeException('전송되지 않은 메시지에 수락 진행 중');
|
||||
}
|
||||
if($this->mailbox !== $this->dest->generalID){
|
||||
if($reason !== null){
|
||||
$reason = '송신자가 등용장을 수락할 수 없습니다';
|
||||
}
|
||||
return self::INVALID;
|
||||
}
|
||||
|
||||
|
||||
$db = DB::db();
|
||||
$general = $db->queryFirstRow('SELECT nation, `no`, city, nations FROM general WHERE `no`=%i', $this->dest->generalID);
|
||||
list(
|
||||
$startYear,
|
||||
$year,
|
||||
$month,
|
||||
$killturn
|
||||
) = $db->queryFirstList('SELECT startyear, year, month, killturn FROM game LIMIt 1');
|
||||
$scoutNation = $db->queryFirstRow(
|
||||
'SELECT nation, `name`, `level`, capital, scout FROM nation WHERE nation=%i',
|
||||
$this->src->nationID
|
||||
);
|
||||
$general = $db->queryFirstRow(
|
||||
'SELECT `no`, `name`, nation, nations, city, `level`, troop, npc, gold, rice FROM general WHERE `no`=%i',
|
||||
$receiverID
|
||||
);
|
||||
|
||||
list($result, $reason) = $this->checkAgreeValidation($startYear, $year, $general, $scoutNation);
|
||||
|
||||
if($result !== self::ACCEPTED){
|
||||
pushGenLog($general, ["<C>●</>{$reason} 등용 수락 불가."]);
|
||||
if($result === self::DECLINED){
|
||||
$this->_declineMessage();
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
$scoutNationGeneralCnt = $db->queryFirstField(
|
||||
'SELECT COUNT(`no`) FROM general WHERE nation = %i',
|
||||
$scoutNation['nation']
|
||||
);
|
||||
|
||||
$originalNationGeneralCnt = $db->queryFirstField(
|
||||
'SELECT COUNT(`no`) FROM general WHERE nation = %i',
|
||||
$general['nation']
|
||||
);
|
||||
|
||||
$isTroopLeader = false;
|
||||
if($general['troop']){
|
||||
$troopLeader = $db->queryFirstField('SELECT `no` FROM troop WHERE troop = %i', $general['troop']);
|
||||
if($troopLeader == $receiverID){
|
||||
$isTroopLeader = true;
|
||||
}
|
||||
}
|
||||
|
||||
$scoutNationGeneralCnt+=1;
|
||||
if($scoutNationGeneralCnt < 10){
|
||||
$scoutNationGeneralCnt = 10;//XXX: 상수!
|
||||
}
|
||||
|
||||
|
||||
|
||||
$originalNationGeneralCnt-=1;
|
||||
if($originalNationGeneralCnt < 10){
|
||||
$originalNationGeneralCnt = 10;//XXX: 상수!
|
||||
}
|
||||
|
||||
//TODO: Logging 시스템 들어엎자.
|
||||
$senderLog = [];
|
||||
$receiverLog = [];
|
||||
$generalPublicLog = [];
|
||||
|
||||
$senderLog[] = "<C>●</><Y>{$general['name']}</> 등용에 성공했습니다.";
|
||||
$receiverLog[] = "<C>●</><D>{$scoutNation['name']}</>(으)로 망명하여 수도로 이동합니다.";
|
||||
$generalPublicLog[] = "<C>●</>{$month}월:<Y>{$general['name']}</>(이)가 <D><b>{$scoutNation['name']}</b></>(으)로 <S>망명</>하였습니다.";
|
||||
|
||||
// 국가 변경, 도시 변경, 일반으로, 수도로
|
||||
$setValues = [
|
||||
'belong'=>1,
|
||||
'level'=>1,
|
||||
'nation'=>$scoutNation['nation'],
|
||||
'city'=>$scoutNation['capital'],
|
||||
'nations'=>$db->sqleval('CONCAT(nations, %s)', "{$scoutNation['nation']},"),
|
||||
'troop'=>0,
|
||||
];
|
||||
|
||||
$setSenderValues = [
|
||||
'experience'=>$db->sqleval('experience + %i', 100),//XXX: 상수.
|
||||
'dedication'=>$db->sqleval('dedication + %i', 100)
|
||||
];
|
||||
|
||||
$setOriginalNationValues = [
|
||||
'totaltech'=>$db->sqleval('tech * %i', $originalNationGeneralCnt),
|
||||
'gennum'=>$originalNationGeneralCnt
|
||||
];
|
||||
|
||||
$setScoutNationValues = [
|
||||
'totaltech'=>$db->sqleval('tech * %i', $scoutNationGeneralCnt),
|
||||
'gennum'=>$scoutNationGeneralCnt
|
||||
];
|
||||
|
||||
$setOriginalCityValues = [
|
||||
|
||||
];
|
||||
|
||||
// 재야가 아니면 명성N*10% 공헌N*10%감소
|
||||
if($general['nation'] != 0){
|
||||
// 1000 1000 남기고 환수
|
||||
if($general['gold'] > 1000){//XXX: 상수.
|
||||
$setValues['gold'] = 1000;
|
||||
$setOriginalNationValues['gold'] = $db->sqleval('gold + %i', $general['gold'] - 1000);
|
||||
}
|
||||
|
||||
if($general['rice'] > 1000){//XXX: 상수.
|
||||
$setValues['rice'] = 1000;
|
||||
$setOriginalNationValues['rice'] = $db->sqleval('rice + %i', $general['rice'] - 1000);
|
||||
}
|
||||
|
||||
//관직 해제
|
||||
if(5 <= $general['level'] && $general['level'] <= 11){
|
||||
$setOriginalNationValues["l{$general['level']}set"] = 0;
|
||||
}
|
||||
else if($general['level'] == 4){
|
||||
$setOriginalCityValues['gen1'] = 0;
|
||||
}
|
||||
else if($general['level'] == 3){
|
||||
$setOriginalCityValues['gen2'] = 0;
|
||||
}
|
||||
else if($general['level'] == 2){
|
||||
$setOriginalCityValues['gen3'] = 0;
|
||||
}
|
||||
|
||||
$setValues['betray'] = $db->sqleval('betray + 1');
|
||||
$setValues['experience'] = $db->sqleval('experience * (1 - 0.1 * betray)');
|
||||
$setValues['dedication'] = $db->sqleval('dedication * (1 - 0.1 * betray)');
|
||||
}
|
||||
else{
|
||||
//재야이면 100 100 증가
|
||||
$setValues['experience'] = $db->sqleval('experience + %i', 100);//XXX: 상수
|
||||
$setValues['dedication'] = $db->sqleval('experience + %i', 100);
|
||||
}
|
||||
|
||||
if($me['npc'] < 2){
|
||||
$setValues['killturn'] = $killturn;
|
||||
}
|
||||
|
||||
$db->update('general', $setValues, 'no=%i', $receiverID);
|
||||
$db->update('general', $setSenderValues, 'no=%i', $this->src->generalID);
|
||||
$db->update('nation', $setOriginalNationValues, 'nation=%i', $general['nation']);
|
||||
$db->update('nation', $setScoutNationValues, 'nation=%i', $scoutNation['nation']);
|
||||
if($setOriginalCityValues){
|
||||
$db->update('city', $setOriginalCityValues, 'city=%i', $general['city']);
|
||||
}
|
||||
|
||||
if($isTroopLeader){
|
||||
// 모두 탈퇴
|
||||
$db->update('general', [
|
||||
'troop'=>0,
|
||||
], 'troop=%i', $general['troop']);
|
||||
// 부대 삭제
|
||||
$db->delete('troop', 'troop=%i', $general['troop']);
|
||||
}
|
||||
|
||||
pushGenLog($general, $receiverLog);
|
||||
pushGenLog(['no'=>$this->src->generalID], $senderLog);
|
||||
pushGeneralPublicRecord($generalPublicLog, $year, $month);
|
||||
|
||||
$now = new \DateTime();
|
||||
|
||||
//메시지 비 활성화
|
||||
$this->msgOption['used'] = true;
|
||||
$this->invalidate();
|
||||
$this->validScout = false;
|
||||
|
||||
$newMsg = new Message(
|
||||
self::MSGTYPE_PRIVATE,
|
||||
$this->dest,
|
||||
$this->dest,
|
||||
"{$scoutNation['name']}(으)로 등용 제의 수락",
|
||||
$now,
|
||||
new \DateTime('9999-12-31'),
|
||||
Json::encode([
|
||||
'related'=>$this->id
|
||||
])
|
||||
);
|
||||
$newMsg->send();
|
||||
|
||||
return self::ACCEPTED;
|
||||
}
|
||||
|
||||
protected function _declineMessage(){
|
||||
$this->msgOption['used'] = true;
|
||||
$this->invalidate();
|
||||
$this->validScout = false;
|
||||
|
||||
$newMsg = new Message(
|
||||
self::MSGTYPE_PRIVATE,
|
||||
$this->dest,
|
||||
$this->dest,
|
||||
"{$scoutNation['name']}(으)로 등용 제의 거부",
|
||||
$now,
|
||||
new \DateTime('9999-12-31'),
|
||||
Json::encode([
|
||||
'related'=>$this->id
|
||||
])
|
||||
);
|
||||
$newMsg->send();
|
||||
|
||||
return self::ACCEPTED;
|
||||
}
|
||||
|
||||
protected function checkDeclineValidation(int $receiverID){
|
||||
if(!$this->validScout){
|
||||
return [self::INVALID, '유효하지 않은 등용장입니다.'];
|
||||
}
|
||||
if($this->mailbox !== $this->dest->generalID){
|
||||
return [self::INVALID, '송신자가 등용장을 거부할 수 없습니다.'];
|
||||
}
|
||||
|
||||
if($this->mailbox !== $receiverID){
|
||||
return [self::INVALID, '올바른 수신자가 아닙니다.'];
|
||||
}
|
||||
}
|
||||
|
||||
public function declineMessage(int $receiverID):int{
|
||||
if(!$this->id){
|
||||
throw \RuntimeException('전송되지 않은 메시지에 거절 진행 중');
|
||||
}
|
||||
|
||||
list($result, $reason) = $this->checkDeclineValidation($receiverID);
|
||||
|
||||
if($result === self::INVALID){
|
||||
pushGenLog($general, ["<C>●</>{$reason} 등용 수락 불가."]);
|
||||
return $result;
|
||||
}
|
||||
|
||||
$this->_declineMessage();
|
||||
pushGenLog(['no'=>$receiverID], "<C>●</><D>{$this->src->nationName}</>(으)로 망명을 거부했습니다.");
|
||||
pushGenLog(['no'=>$this->src->generalID], "<C>●</><Y>{$this->dest->generalName}</>(이)가 등용을 거부했습니다.");
|
||||
|
||||
return self::DECLINED;
|
||||
}
|
||||
|
||||
public static function buildScoutMessage(int $srcGeneralID, int $destGeneralID, &$reason = null, \DateTime $date = null): Message{
|
||||
@@ -67,8 +331,8 @@ class ScoutMessage extends Message{
|
||||
}
|
||||
|
||||
$db = DB::db();
|
||||
$srcGeneral = $db->queryFirstRow('SELECT nation FROM nation WHERE `no`=%i', $srcGeneralID);
|
||||
$destGeneral = $db->queryFirstRow('SELECT nation, `level` FROM nation WHERE `no`=%i', $destGeneralID);
|
||||
$srcGeneral = $db->queryFirstRow('SELECT `name`, nation FROM nation WHERE `no`=%i', $srcGeneralID);
|
||||
$destGeneral = $db->queryFirstRow('SELECT `name`, nation, `level` FROM nation WHERE `no`=%i', $destGeneralID);
|
||||
if($date === null){
|
||||
$date = new DateTime();
|
||||
}
|
||||
@@ -99,6 +363,7 @@ class ScoutMessage extends Message{
|
||||
|
||||
$src = new MessageTarget(
|
||||
$srcGeneralID,
|
||||
$srcGeneral['name'],
|
||||
$srcGeneral['nation'],
|
||||
$srcNationInfo['name'],
|
||||
$srcNationInfo['color']
|
||||
@@ -106,6 +371,7 @@ class ScoutMessage extends Message{
|
||||
|
||||
$dest = new MessageTarget(
|
||||
$destGeneralID,
|
||||
$destGeneral['name'],
|
||||
$destGeneral['nation'],
|
||||
Util::array_get($srcNationInfo['name'], ''),
|
||||
Util::array_get($srcNationInfo['color'], '')
|
||||
|
||||
Reference in New Issue
Block a user