diff --git a/hwe/sammo/ActionSpecialWar/che_의술.php b/hwe/sammo/ActionSpecialWar/che_의술.php index 6235c0b9..688c08bf 100644 --- a/hwe/sammo/ActionSpecialWar/che_의술.php +++ b/hwe/sammo/ActionSpecialWar/che_의술.php @@ -19,7 +19,7 @@ class che_의술 implements iAction{ SpecialityConst::STAT_INTEL ]; - public function getPreTurnExecuteTriggerList(General $general):array{ - return []; + public function getPreTurnExecuteTriggerList(General $general):?GeneralTriggerCaller{ + return null; } } \ No newline at end of file diff --git a/hwe/sammo/DefaultActionTrigger.php b/hwe/sammo/DefaultActionTrigger.php index 1ee03c67..a068fb5c 100644 --- a/hwe/sammo/DefaultActionTrigger.php +++ b/hwe/sammo/DefaultActionTrigger.php @@ -2,8 +2,8 @@ namespace sammo; trait DefaultAction{ - public function getPreTurnExecuteTriggerList(General $general):array{ - return []; + public function getPreTurnExecuteTriggerList(General $general):?GeneralTriggerCaller{ + return null; } public function onCalcDomestic(string $turnType, string $varType, float $value):float{ return $value; @@ -24,10 +24,10 @@ trait DefaultAction{ public function getWarPowerMultiplier(WarUnit $unit):array{ return [1, 1]; } - public function getBattleInitSkillTriggerList(WarUnit $unit):array{ - return []; + public function getBattleInitSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller{ + return null; } - public function getBattlePhaseSkillTriggerList(WarUnit $unit):array{ - return []; + public function getBattlePhaseSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller{ + return null; } } \ No newline at end of file diff --git a/hwe/sammo/General.php b/hwe/sammo/General.php index b28b8503..871b4d0d 100644 --- a/hwe/sammo/General.php +++ b/hwe/sammo/General.php @@ -276,8 +276,8 @@ class General implements iAction{ return $result; } - public function getPreTurnExecuteTriggerList(General $general):array{ - $chain = []; + public function getPreTurnExecuteTriggerList(General $general):?GeneralTriggerCaller{ + $caller = new GeneralTriggerCaller(); foreach(array_merge([ $this->nationType, $this->levelObj, @@ -288,9 +288,14 @@ class General implements iAction{ if(!$iObj){ continue; } - $chain[] = $iObj->getPreTurnExecuteTriggerList($general); + /** @var iAction $iObj */ + $caller->merge($iObj->getPreTurnExecuteTriggerList($general)); } - return array_merge([], ...$chain); + + if($caller->isEmpty()){ + return null; + } + return $caller; } public function onCalcDomestic(string $turnType, string $varType, float $value):float{ foreach(array_merge([ @@ -303,6 +308,7 @@ class General implements iAction{ if(!$iObj){ continue; } + /** @var iAction $iObj */ $value = $iObj->onCalcDomestic($turnType, $varType, $value); } return $value; @@ -320,6 +326,7 @@ class General implements iAction{ if(!$iObj){ continue; } + /** @var iAction $iObj */ $value = $iObj->onPreGeneralStatUpdate($this, $statName, $value); } return $value; @@ -336,6 +343,7 @@ class General implements iAction{ if(!$iObj){ continue; } + /** @var iAction $iObj */ $value = $iObj->onCalcStrategic($turnType, $varType, $value); } return $value; @@ -352,6 +360,7 @@ class General implements iAction{ if(!$iObj){ continue; } + /** @var iAction $iObj */ $amount = $iObj->onCalcNationalIncome($type, $amount); } return $amount; @@ -371,6 +380,7 @@ class General implements iAction{ if(!$iObj){ continue; } + /** @var iAction $iObj */ [$attV, $defV] = $iObj->getWarPowerMultiplier($unit); $att *= $attV; $def *= $defV; @@ -378,7 +388,7 @@ class General implements iAction{ return [$att, $def]; } public function getBattleInitSkillTriggerList(WarUnit $unit):array{ - $chain = []; + $caller = new WarUnitTriggerCaller(); foreach(array_merge([ $this->nationType, $this->levelObj, @@ -389,12 +399,17 @@ class General implements iAction{ if(!$iObj){ continue; } - $chain[] = $iObj->getBattleInitSkillTriggerList($unit); + /** @var iAction $iObj */ + $caller->merge($iObj->getBattleInitSkillTriggerList($unit)); } - return array_merge([], ...$chain); + + if($caller->isEmpty()){ + return null; + } + return $caller; } public function getBattlePhaseSkillTriggerList(WarUnit $unit):array{ - $chain = []; + $caller = new WarUnitTriggerCaller(); foreach(array_merge([ $this->nationType, $this->levelObj, @@ -405,8 +420,13 @@ class General implements iAction{ if(!$iObj){ continue; } - $chain[] = $iObj->getBattlePhaseSkillTriggerList($unit); + /** @var iAction $iObj */ + $caller->merge($iObj->getBattlePhaseSkillTriggerList($unit)); } - return array_merge([], ...$chain); + + if($caller->isEmpty()){ + return null; + } + return $caller; } } \ No newline at end of file diff --git a/hwe/sammo/TriggerCaller.php b/hwe/sammo/TriggerCaller.php index 1f2431aa..cfa54a24 100644 --- a/hwe/sammo/TriggerCaller.php +++ b/hwe/sammo/TriggerCaller.php @@ -7,15 +7,19 @@ abstract class TriggerCaller{ abstract function checkValidTrigger(iObjectTrigger $trigger):bool; + function isEmpty():bool{ + return !$this->triggerListByPriority; + } + function __construct(?array $triggerList=null) { if(!$triggerList){ return; } - $this->merge($triggerList); - } - function merge(array $triggerList){ + $sorted = true; + $minPriority = iObjectTrigger::PRIORITY_MAX; + foreach($triggerList as $trigger){ if(!checkValidTrigger($trigger)){ throw new \InvalidArgumentException('Invalid Trigger Type'); @@ -23,18 +27,92 @@ abstract class TriggerCaller{ /** @var iObjectTrigger $trigger */ $priority = $trigger->getPriority(); $uniqueID = $trigger->getUniqueID(); - if(!key_exists($priority, $this->triggerListByPriority)){ - $this->triggerListByPriority[$priority] = []; + + if($sorted){ + if($minPriority > $priority){ + $minPriority = $priority; + } + else if($minPriority < $priority){ + $sorted = false; + } } - $subTriggerList = &$this->triggerListByPriority[$priority]; - - if(key_exists($uniqueID, $subTriggerList)){ + if(!key_exists($priority, $this->triggerListByPriority)){ + $this->triggerListByPriority[$priority] = [$uniqueID=>$trigger]; continue; } - $subTriggerList[$uniqueID] = $trigger; + + $this->triggerListByPriority[$priority][$uniqueID] = $trigger; } - $this->sorted = false; + + if(!$sorted){ + krsort($this->triggerListByPriority); + } + + } + + function append(iObjectTrigger $trigger){ + if(!checkValidTrigger($trigger)){ + throw new \InvalidArgumentException('Invalid Trigger Type'); + } + $priority = $trigger->getPriority(); + $uniqueID = $trigger->getUniqueID(); + + if(!$this->triggerListByPriority){ + $this->triggerListByPriority[$priority] = [$uniqueID=>$trigger]; + return; + } + + $lastKey = Util::array_last_key($this->triggerListByPriority); + if($lastKey > $priority){ + $this->triggerListByPriority[$priority] = [$uniqueID=>$trigger]; + return; + } + + if(key_exists($priority, $this->triggerListByPriority)){ + $this->triggerListByPriority[$priority][$uniqueID] = $trigger; + } + + $this->triggerListByPriority[$priority] = [$uniqueID=>$trigger]; + krsort($this->triggerListByPriority); + } + + function merge(?TriggerCaller $other){ + if($other === null){ + return; + } + + $newTriggerList = []; + $iterLhs = new \ArrayIterator($this->triggerListByPriority); + $iterRhs = new \ArrayIterator($other->triggerListByPriority); + + while($iterLhs->valid() && $iterRhs->valid()){ + if($iterLhs->key() > $iterRhs->key()){ + $newTriggerList[$iterLhs->key()] = $iterLhs->current(); + $iterLhs->next(); + continue; + } + if($iterRhs->key() > $iterLhs->key()){ + $newTriggerList[$iterRhs->key()] = $iterRhs->current(); + $iterRhs->next(); + continue; + } + $newTriggerList[$iterLhs->key()] = $iterLhs->current() + $iterRhs->current(); + $iterLhs->next(); + $iterRhs->next(); + } + + while($iterLhs->valid()){ + $newTriggerList[$iterLhs->key()] = $iterLhs->current(); + $iterLhs->next(); + } + + while($iterRhs->valid()){ + $newTriggerList[$iterRhs->key()] = $iterRhs->current(); + $iterRhs->next(); + } + + $this->triggerListByPriority = $newTriggerList; } function fire(?array $env = null, $arg = null):?array{ diff --git a/hwe/sammo/TurnExecutionHelper.php b/hwe/sammo/TurnExecutionHelper.php index 2909f658..29e238e2 100644 --- a/hwe/sammo/TurnExecutionHelper.php +++ b/hwe/sammo/TurnExecutionHelper.php @@ -32,7 +32,9 @@ class TurnExecutionHelper public function preprocessCommand(){ $general = $this->getGeneral(); - $general->getPreTurnExecuteTriggerList($general); + $caller = $general->getPreTurnExecuteTriggerList($general); + + $caller->fire(); if($general->getVar('injury') && !$general->hasActivatedSkill('pre.부상경감')){ $general->increaseVarWithLimit('injury', -10, 0); diff --git a/hwe/sammo/iAction.php b/hwe/sammo/iAction.php index df4aefef..148289ff 100644 --- a/hwe/sammo/iAction.php +++ b/hwe/sammo/iAction.php @@ -2,18 +2,8 @@ namespace sammo; interface iAction{ - - const PRIORITY_BEGIN = 50000; - const PRIORITY_PRE = 40000; - const PRIORITY_BODY = 30000; - const PRIORITY_POST = 20000; - const PRIORITY_FINAL = 10000; - //TODO: 능력치는? - /** - * @return iGeneralTrigger[] - */ - public function getPreTurnExecuteTriggerList(General $general):array; + public function getPreTurnExecuteTriggerList(General $general):?GeneralTriggerCaller; public function onCalcDomestic(string $turnType, string $varType, float $value):float; public function onPreGeneralStatUpdate(General $general, string $statName, $value); @@ -21,16 +11,7 @@ interface iAction{ public function onCalcStrategic(string $turnType, string $varType, $value); public function onCalcNationalIncome(string $type, int $amount):int; - /** - * @return iWarUnitTrigger[] - */ - public function getWarPowerMultiplier(WarUnit $unit):array; - /** - * @return iWarUnitTrigger[] - */ - public function getBattleInitSkillTriggerList(WarUnit $unit):array; - /** - * @return iWarUnitTrigger[] - */ - public function getBattlePhaseSkillTriggerList(WarUnit $unit):array; + public function getWarPowerMultiplier(WarUnit $unit):?WarUnitTriggerCaller; + public function getBattleInitSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller; + public function getBattlePhaseSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller; } \ No newline at end of file diff --git a/hwe/sammo/iObjectTrigger.php b/hwe/sammo/iObjectTrigger.php index 08265a43..3f9eaf0f 100644 --- a/hwe/sammo/iObjectTrigger.php +++ b/hwe/sammo/iObjectTrigger.php @@ -2,6 +2,13 @@ namespace sammo; interface iObjectTrigger{ + const PRIORITY_MAX = 99999; + const PRIORITY_BEGIN = 50000; + const PRIORITY_PRE = 40000; + const PRIORITY_BODY = 30000; + const PRIORITY_POST = 20000; + const PRIORITY_FINAL = 10000; + public function getPriority():int; public function action(?array $env=null, $arg=null):?array; public function getUniqueID():string;