diff --git a/hwe/sammo/SpecialityConst.php b/hwe/sammo/SpecialityConst.php new file mode 100644 index 00000000..8d1913b7 --- /dev/null +++ b/hwe/sammo/SpecialityConst.php @@ -0,0 +1,213 @@ + ['경작', 1, self::STAT_INTEL], + 2 => ['상재', 1, self::STAT_INTEL], + 3 => ['발명', 1, self::STAT_INTEL], + + 10 => ['축성', 1, self::STAT_POWER], + 11 => ['수비', 1, self::STAT_POWER], + 12 => ['통찰', 1, self::STAT_POWER], + + 20 => ['인덕', 1, self::STAT_LEADERSHIP], + + 30 => ['거상', -2.5, self::DISABLED], + 31 => ['귀모', -2.5, self::STAT_LEADERSHIP | self::STAT_POWER | self::STAT_INTEL], + ]; + + const WAR = [ + 40 => ['귀병', 1, self::STAT_INTEL | self::ARMY_WIZARD | self::REQ_DEXTERITY], + + 41 => ['신산', 1, self::STAT_INTEL | self::ARMY_WIZARD], + 42 => ['환술', -5, self::STAT_INTEL | self::ARMY_WIZARD], + 43 => ['집중', 1, self::STAT_INTEL | self::ARMY_WIZARD], + 44 => ['신중', 1, self::STAT_INTEL | self::ARMY_WIZARD], + 45 => ['반계', 1, self::STAT_INTEL | self::ARMY_WIZARD], + + 50 => ['보병', 1, self::STAT_LEADERSHIP | self::STAT_POWER | self::REQ_DEXTERITY | self::ARMY_FOOTMAN], + 51 => ['궁병', 1, self::STAT_LEADERSHIP | self::STAT_POWER | self::REQ_DEXTERITY | self::ARMY_ARCHER], + 52 => ['기병', 1, self::STAT_LEADERSHIP | self::STAT_POWER | self::REQ_DEXTERITY | self::ARMY_CAVALRY], + 53 => ['공성', 1, self::STAT_LEADERSHIP | self::STAT_POWER | self::REQ_DEXTERITY | self::ARMY_SIEGE], + + 60 => ['돌격', 1, self::STAT_LEADERSHIP | self::STAT_POWER], + 61 => ['무쌍', 1, self::STAT_LEADERSHIP | self::STAT_POWER], + 62 => ['견고', 1, self::STAT_LEADERSHIP | self::STAT_POWER], + 63 => ['위압', 1, self::STAT_LEADERSHIP | self::STAT_POWER], + + 70 => ['저격', 1, self::STAT_LEADERSHIP | self::STAT_POWER | self::STAT_INTEL], + 71 => ['필살', 1, self::STAT_LEADERSHIP | self::STAT_POWER | self::STAT_INTEL], + 72 => ['징병', 1, self::STAT_LEADERSHIP | self::STAT_POWER | self::STAT_INTEL], + 73 => ['의술', -2, self::STAT_LEADERSHIP | self::STAT_POWER | self::STAT_INTEL], + 74 => ['격노', 1, self::STAT_LEADERSHIP | self::STAT_POWER | self::STAT_INTEL], + 75 => ['척사', 1, self::STAT_LEADERSHIP | self::STAT_POWER | self::STAT_INTEL], + ]; + + public static function getInvDomestic(string $name){ + if(static::$invDomestic !== null){ + return static::$invDomestic[$name]??null; + } + + $invDomestic = []; + foreach(static::DOMESTIC as $key=>$val){ + $nameKey = $val[0]; + $val[0] = $key; + $invDomestic[$nameKey] = $val; + } + static::$invDomestic = $invDomestic; + + return static::$invDomestic[$name]??null; + } + + public static function getInvWar(string $name){ + if(static::$invWar !== null){ + return static::$invWar[$name]??null; + } + + $invWar = []; + foreach(static::War as $key=>$val){ + $nameKey = $val[0]; + $val[0] = $key; + $invWar[$nameKey] = $val; + } + static::$invWar = $invWar; + + return static::$invWar[$name]??null; + } + + private static function calcCondGeneric(array $general) : int { + $myCond = 0; + + if ($leader * 0.95 > $power && $leader * 0.95 > $intel) { + $myCond |= STAT_LEADERSHIP; + } + else if($power >= $intel){ + $myCond |= STAT_POWER; + } + else { + $myCond |= STAT_INTEL; + } + + return $myCond; + } + + private static function calcCondDexterity(array $general) : int { + $dex = [ + static::ARMY_FOOTMAN => $general['dex0'], + static::ARMY_ARCHER => $general['dex10'], + static::ARMY_CAVALRY => $general['dex20'], + static::ARMY_WIZARD => $general['dex30'], + static::ARMY_SIEGE => $general['dex40'], + ]; + + $dexSum = array_sum($dex); + $dexBase = Util::round(sqrt($dexSum) / 4); + + if(Util::randBool(0.8)){ + return 0; + } + + if(mt_rand(0, 99) < $dexBase){ + return 0; + } + + if($dexSum){ + return array_rand($dex); + } + + return array_keys($dex, max($dex))[0]; + } + + public static function pickSpecialDomestic(array $general) : int{ + $pAbs = []; + $pRel = []; + + $myCond = static::calcCondGeneric($general); + + foreach(self::DOMESTIC as $id=>list($name, $weight, $cond)){ + if(!($cond & $myCond)){ + continue; + } + + if($weight < 0){ + $pAbs[$id] = -$weight; + } + else{ + $pRel[$id] = $weight; + } + } + + if($pAbs){ + $pAbs[0] = max(0, 100 - array_sum($pAbs)); + $id = Util::choiceRandomUsingWeight($pAbs); + if($id){ + return $id; + } + } + + return Util::choiceRandomUsingWeight($pRel); + } + + public static function pickSpecialWar(array $general) : int{ + $reqDex = []; + $pAbs = []; + $pRel = []; + + $myCond = static::calcCondGeneric($general); + $myCond |= static::calcCondDexterity($general); + + foreach(self::WAR as $id=>list($name, $weight, $cond)){ + if(!($cond & $myCond)){ + continue; + } + + if($cond & self::REQ_DEXTERITY){ + $reqDex[$id] = $weight; + } + else if($weight < 0){ + $pAbs[$id] = -$weight; + } + else{ + $pRel[$id] = $weight; + } + } + + if($reqDex){ + return Util::choiceRandomUsingWeight($reqDex); + } + + if($pAbs){ + $pAbs[0] = max(0, 100 - array_sum($pAbs)); + $id = Util::choiceRandomUsingWeight($pAbs); + if($id){ + return $id; + } + } + + return Util::choiceRandomUsingWeight($pRel); + } +} \ No newline at end of file