Compare commits

..
116 Commits
Author SHA1 Message Date
Hide_D 4f40fa7813 misc: 턴 선택기 버튼 글씨 색 변경 2022-05-13 21:31:49 +09:00
Hide_D b7346b3816 misc: 턴 선택기의 주 버튼 색상 교체 2022-05-13 21:26:22 +09:00
Hide_D 400e47f616 fix: 토너먼트 베팅 시 최소 골드가 500이 아닌 버그 수정 2022-05-13 21:25:30 +09:00
Hide_D 5d499bbfbe fix: 서버 페이지에서 버튼을 bootstrap 버튼으로 변경 2022-05-13 20:27:31 +09:00
Hide_D e0d5c44184 fix: 아이템 버리기시, 조사 틀림 2022-05-13 18:01:31 +09:00
Hide_D f100998800 feat: 게임 시작 후, 거병/건국 기간, 출병 제한 기간을 안내 2022-05-11 02:22:40 +09:00
Hide_D 5bc31c91fa feat: 중원 정세에 메시지를 출력하는 Event Action 추가 2022-05-11 01:58:12 +09:00
Hide_D 4ca929d47d feat: 시작년도 기준으로 연월을 처리하는 Date Condition 추가 2022-05-11 01:50:05 +09:00
Hide_D 4ba43ea76a game: 기병의 출병시 병력 대상 전투력 5% 상향 2022-05-11 01:42:44 +09:00
Hide_D 34232a5504 game: 저지 발동시 숙련에 더해 명성도 추가 2022-05-11 01:36:54 +09:00
Hide_D 9b7464ab69 game: 필살 전투 특기가 '항상 최대 필살 대미지 계수'를 갖도록 수정
- 1.3 ~ 2.0에서 2.0 고정
2022-05-11 01:35:21 +09:00
Hide_D f003f38f74 fix: 일부 자동 조사가 적용되지 않는 코드 반영
- 유산 관리
  - 유니크 이름 받아오는 코드 일부 수정
- 인사부
2022-05-11 00:42:17 +09:00
Hide_D 91b2cecb19 feat: 유니크 입찰 시 첫번째 칸을 '공란'으로 두기 2022-05-11 00:32:03 +09:00
Hide_D 8c11661fb4 fix: 천통시 명장 일람에 유상포인트 최종 계산을 누락한 버그 수정 2022-05-11 00:26:47 +09:00
Hide_D 9aabe0442d game: 이미 같은 부위에 유니크를 가지고 있다면 유산 입찰 금지
- 이미 입찰한 같은 부위 유니크는 반환
2022-05-11 00:12:57 +09:00
Hide_D b463720512 fix: 아이템 파기 시 판매가 정정 2022-05-10 23:59:58 +09:00
Hide_D 6bc7c67589 feat: 장비매매로 유니크 판매시 전체 알림 2022-05-10 23:50:32 +09:00
Hide_D 443543d70f feat: 아이템 파기 추가 2022-05-10 23:46:39 +09:00
Hide_D 46a94b7816 feat: 명장 일람에 유산 소모량, 획득량 표기 2022-05-10 03:31:48 +09:00
Hide_D b2e297bbb3 feat: 유산 포인트 획득, 소모 정도를 동적으로 명장 일람 항목으로 기록
- 1월, 7월
- 베팅, 베팅 당첨을 소모/획득으로 분리
- 일단 유산 포인트 획득은 별도 분리
2022-05-10 03:26:34 +09:00
Hide_D 16906e960e feat: convertTupleArrayToDict 유틸리티 함수 생성 2022-05-10 02:37:50 +09:00
Hide_D 91bc734612 feat: 1, 7월마다 유산 포인트 rank_data 통계를 냄 2022-05-10 01:59:10 +09:00
Hide_D fa5546874a feat: RankColumn 유산 포인트 관련 추가 및 설명 보완 2022-05-09 23:58:15 +09:00
Hide_D 3921d159ef fix: 세력장수에서 rankColumn 대응 에러 수정 2022-05-09 22:33:16 +09:00
Hide_D cfcdc3149f fix: logExceptionByCustomHandler에서 echo 안하는 옵션 추가 2022-05-09 22:31:14 +09:00
Hide_D 717017fad5 misc: APIHelper에서 Exception과 Error를 상세 분리 2022-05-09 22:27:02 +09:00
Hide_D b8f957130d misc: 사용하지 않는 파일 제거 2022-05-09 22:02:54 +09:00
Hide_D 5824079b41 misc: 에러 로깅시 에러명에도 {ROOT}치환 2022-05-09 21:49:02 +09:00
Hide_D fbcfbb7156 fix: KVStorage deleteValue버그 수정 2022-05-09 21:42:17 +09:00
Hide_D b738984235 fix: 토너먼트 함수 인자에 맞게 수정 2022-05-09 21:40:20 +09:00
Hide_D c29333f8e0 fix: RankColumn 누락 부분 수정 2022-05-09 16:12:19 +09:00
Hide_D 123cf8d437 fix: error logger 수정 2022-05-09 16:08:53 +09:00
Hide_D 9293c4e480 feat: FatalError 대응 2022-05-09 03:42:51 +09:00
Hide_D fa5919aa1a Revert "refac: 에러 핸들링 방식 변경, FatalError 대응"
This reverts commit 80edfefdb1.
2022-05-09 03:40:54 +09:00
Hide_D 194f2bd2a5 refac: 에러 핸들링 방식 변경, FatalError 대응 2022-05-09 03:39:30 +09:00
Hide_D 0ae6584b02 fix: 아이템 치료의 우선순위가 낮아 '경상'치료가 안되는 버그 수정 2022-05-09 02:42:08 +09:00
Hide_D 397aa76e15 fix: KVStorage에서 Map으로 안 바뀐 코드 수정 2022-05-09 02:30:11 +09:00
Hide_D 43997b9117 fix: phan 메시지에 따라 수정
- array에 +=를 phan 알아듣기 쉽게 array_merge로
- Util::array_get이 더 이상 필요없으므로 null coalescing
- array로 tuple류를 반환하는 함수에 index를 포함하도록 변경
  - php intelephense에게는 현재 무효
- getPost 일부 값에 int 지정
- 아이템에 id property를 없앴으므로 관련 코드 제거
- enum은 array key로 사용할 수 없으므로 \Ds\Map으로 변경
- KakaoKey PhanRedefineClass 에러 우회
2022-05-09 01:25:12 +09:00
Hide_D de5fe818e6 fix: phan 출력 결과에 따라 처리
- switch에 변수를 정하는 경우 default에 throw
- Util::getPost에 일부 타입 강제
- array인 일부 값들에 PHPDoc 타입 지정
- Enum에 toString이 없으므로 value값 지정
- 사용하지 않는 use function 제거
2022-05-09 00:06:41 +09:00
Hide_D e3e315a068 dep: phan 2022-05-08 23:20:55 +09:00
Hide_D 5430a43589 fix: RankColumn 누락부분 수정 2022-05-08 23:11:15 +09:00
Hide_D a44172f509 refac: RankColumn enum 추가, General의 명장 일람 타입 변경 2022-05-08 23:09:27 +09:00
Hide_D 94bfd79afa fix: 감춰진 KVStorage의 initializer를 사용하는 코드 수정 2022-05-08 20:20:09 +09:00
Hide_D 2b4de68f0a refac: 더는 필요없어진 betting table 삭제 2022-05-08 20:15:03 +09:00
Hide_D 282b413553 refac: InheritPointManager를 Ds\Map으로 변경 2022-05-08 20:11:38 +09:00
Hide_D 5164585360 refac: KVStorage의 내부구조를 Ds\Map으로 변경 2022-05-08 20:10:04 +09:00
Hide_D f6642ecb0f dep: add php-ds 2022-05-08 19:23:24 +09:00
Hide_D 928042d71b feat: KVStorage에서 BackedEnum 지원 2022-05-08 13:30:16 +09:00
Hide_D 91cb3c4344 fix: 오타 수정 2022-05-08 13:15:28 +09:00
Hide_D eff79c4778 refac: 유산 포인트 파트를 별도의 Manager로 분리, enum 적용 2022-05-08 04:40:36 +09:00
Hide_D f7776d5067 dep: bootstrap5 warning 관련 버전 조정 2022-05-08 01:50:19 +09:00
Hide_D 68aae0bec1 misc: warning 제거 2022-05-08 01:44:16 +09:00
Hide_D cb7eb3b711 dep: package-updates 2022-05-08 01:36:06 +09:00
Hide_D 2a6b661285 fix: 연속 내정 성공 등, setInheritancePoint에 빙읮장을 누락한 버그 2022-05-07 15:26:52 +09:00
Hide_D d2ebf94453 fix: 빙의장이 베팅한 경우 베팅 성공으로 반영되지 않는 버그 수정 2022-05-07 15:24:16 +09:00
Hide_D 707f9ba7ce misc: 가입시 닉네임 변경 어려움을 알림 2022-05-07 15:16:38 +09:00
Hide_D 72e1d5e03b fix: 실제 코드 변경에 따라 의술을 1/3가 아니라 30%로 정정 2022-04-28 00:54:34 +09:00
Hide_D a612074aa4 fix: span, br 대신 div 2022-04-27 23:13:51 +09:00
Hide_D 86bbccb7f9 fix: 지도 렌더러에서 tooltip width가 덜 변경되도록 수정 2022-04-27 23:04:22 +09:00
Hide_D 11b7b57343 refac,feat: Global/ExecuteEngine
- 턴 실행
- 기존 proc.php와 유사
- 변경된 턴 있음 알림
2022-04-27 02:43:04 +09:00
Hide_D b682e53abe feat: General|Nation/GetGeneralLog 감찰부&내정보 로그 2022-04-27 01:40:09 +09:00
Hide_D ce877834cd feat: 장수 추가정보 카드
- 막대 구현
- 기존의 추가정보에 5턴분량 예턴 표기
2022-04-27 00:09:25 +09:00
Hide_D c69d171c3a feat: Nation/GeneralList 값 확장, 감찰부 2022-04-27 00:03:33 +09:00
Hide_D 1b24aa2421 feat: 기본 내정보 카드
- 아직 bar가 없음
2022-04-26 03:23:13 +09:00
Hide_D c61a4a70fc feat: Nation/GeneralList에 장수 기본 자료 일부 추가
- 내 정보, 감찰부에서 사용하는 자료
2022-04-26 03:14:48 +09:00
Hide_D bdefcc622f fix: Nation/GeneralList 권한 조정 2022-04-26 03:11:22 +09:00
Hide_D 67336323c2 fix: 세력장수에서 permission1(도시관직)도 보여야함. 2022-04-26 01:02:16 +09:00
Hide_D 3ac9e7c599 misc: 궁병 수비선제사격에서 선제 공격 로그를 단순하게 처리
- 상대방의 필살, 격노도 출력하지 않음
2022-04-26 00:39:36 +09:00
Hide_D 73f70fceff game,fix: 전추 치료 발동시 표기에 맞게 -50% -> -30% 2022-04-26 00:36:30 +09:00
Hide_D e353efc81d game: 궁병 수비 선제의 대미지를 50% 하향 2022-04-26 00:35:08 +09:00
Hide_D a37c427242 misc: auto500px, insertCustomCSS 누락된 페이지 정정 2022-04-26 00:33:54 +09:00
Hide_D d3c9b1f8a6 misc: 불필요한 베팅 import 코드 제거 2022-04-25 21:12:59 +09:00
Hide_D 0ca029babb fix: 천도 후 nationStaticInfo가 갱신되지 않는 버그 수정 2022-04-25 12:00:13 +09:00
Hide_D 492d113307 refac: 토너먼트 긴 switch 문을 assoc array로 변경 2022-04-25 02:33:37 +09:00
Hide_D f2bd48e452 fix,misc: 토너먼트 베팅 관련 잔여 코드 제거 2022-04-25 02:05:59 +09:00
Hide_D ddb7ee1ec2 fix: 국가 베팅장에서 '토너먼트'는 보여주지 않기로 2022-04-25 02:04:31 +09:00
Hide_D 7d62e94306 fix: 금 베팅시 betgold rankvar 누락 2022-04-25 01:51:42 +09:00
Hide_D 4961d76b96 fix: BettingDetail이 assocArray를 대응하지 못하는 버그 수정 2022-04-25 01:45:35 +09:00
Hide_D 12524e6e68 fix: 이제 BettingDetail 출력 변경
- BettingInfo의 candidate가 array를 보장하지 않음
- info가 html이 아니어도 출력
2022-04-25 01:30:54 +09:00
Hide_D 79f30ea275 refac: 토너먼트 베팅 세부 로직을 ng_betting으로 이동 (#218)
- 토너먼트 베팅을 betting 테이블 대신 Betting 모듈을 이용하는 형태로 변경
  - 이전 토너먼트 베팅 기록이 남음
  - 현재 이전 토너먼트 기록을 볼 수는 없음
- 베팅에 API/Betting/Bet 을 이용
- 토너먼트, 베팅 페이지를 Betting 모듈에 맞게 임시 조정
- 이전 버전과의 호환성을 위해 betting table과 betting 테이블에 초기값을 추가하는 로직은 남김
  - 이후 0.30이 되었을 때 제거

Reviewed-on: https://storage.hided.net/gitea/devsam/core/pulls/218
2022-04-25 01:06:32 +09:00
Hide_D 6ec2bf2880 fix: KVStorage에서 mb_strtolower를 제거하여 대소문자 구분 2022-04-25 00:39:13 +09:00
Hide_D 7708c26b71 refac: Betting 시작 코드를 모듈로 이동 2022-04-23 01:39:02 +09:00
Hide_D 4f300c6f82 refac: 구 jQuery Map wrapper를 Vue3 렌더러로 변경 2022-04-22 02:07:32 +09:00
Hide_D f4d67e759e refac: MapViewer에서 modelValue를 Legacy 버전과 맞춤 2022-04-22 00:36:25 +09:00
Hide_D e9b76217f7 feat: 임시용 cachedMap 출력 추가 2022-04-21 23:51:43 +09:00
Hide_D 85f801df4d feat: MapViewer와 API의 버전이 같을 때에만 지도 출력 2022-04-21 23:51:03 +09:00
Hide_D 01d5f2cda9 fix: 타 버전과 호환성을 위해, NO_SESSION 키워드 유지 2022-04-21 23:37:37 +09:00
Hide_D 601196e3f6 refac: APIHelper에 DummySession 적용, NO_LOGIN 구분 2022-04-21 23:33:08 +09:00
Hide_D cbf0be20a5 feat: SammoAPI 호출 prefix 변경 기능 제공 2022-04-21 23:17:23 +09:00
Hide_D e51421780e fix: 연감 철자 수정 2022-04-21 22:44:02 +09:00
Hide_D 2240282155 fix: 연감에서 폰트 크기 미 지정 2022-04-21 22:32:23 +09:00
Hide_D 5700b32c84 fix: 중원정보에서 분쟁 누락 2022-04-21 22:30:15 +09:00
Hide_D 4d72e0860e fix: AI에서 최근 전투 계산에서 외부 인력 계산 버그 2022-04-21 18:47:38 +09:00
Hide_D 994daf11d3 feat,refac: 중원 정보 페이지 2022-04-21 03:24:11 +09:00
Hide_D 79b92427aa fix: 중원정보 API에서 도시 목록이 id로 나오는 문제 2022-04-21 02:31:41 +09:00
Hide_D 6938c74014 feat: Global/GetDiplomacy 중원 정보 API 2022-04-21 02:28:17 +09:00
Hide_D 058a6e63f2 feat: Global/GetMap, Global/GetCachedMap 추가
-  지도를 가져오는 코드
- GetCahcedMap에서는 600초 단위 캐싱
  - history 필드에 최근 10건 표시
2022-04-21 01:24:07 +09:00
Hide_D 1be6b7a509 misc: Global/GetConst의 캐시 타입을 Public으로 변경 2022-04-21 01:18:12 +09:00
Hide_D ef532f0779 refac: API 캐시 컨트롤에서 max-age, public 지정 가능하도록 2022-04-21 01:17:20 +09:00
Hide_D 095a23df6d fix: get API의 경우 arg를 paramArg로 전환 2022-04-21 00:24:21 +09:00
Hide_D 7043521eaa fix: 연감 지도 수정 2022-04-20 22:40:07 +09:00
Hide_D 5eaafaeee6 fix: NPC 빙의 장수 목록 안보이는 버그 수정
- API/Global/GeneralList를 WithToken과 분리
2022-04-20 22:33:46 +09:00
Hide_D ec10949c64 fix: 걸그룹대전 스탯 수정 2022-04-20 21:56:31 +09:00
Hide_D 0e882cea17 feat: 걸그룹 대전 업데이트 2022-04-20 21:26:55 +09:00
Hide_D 4ad5cab37b feat,refac: vue3로 작성한 새 연감 페이지 (#217)
- 새 지도 렌더러 사용
- 새 연감 데이터 사용
- 500px 모드 지원
- Vue3 활용

Reviewed-on: https://storage.hided.net/gitea/devsam/core/pulls/217
2022-04-20 21:04:56 +09:00
Hide_D 2b6139050d feat: 커스터마이징 가능한 tooltip directive 2022-04-20 20:58:08 +09:00
Hide_D 14be16ce74 feat: Vue3로 작성된 지도 렌더러 (#216)
- 기존의 jQuery 기반 지도 렌더러를 Vue3로 재작성.
  - ajax로 호출하는 부분은 외부에서 처리하고, 다시 그리는 부분만 생성
  - 기능상으론 거의 동일.
- 일반 렌더러의 700px에, 500px모드용 모드 추가
  - 아이콘의 크기는 작아지지만, 글자 크기는 작아지지 않도록 조정

dep: vueuse, detect-it 추가

Reviewed-on: https://storage.hided.net/gitea/devsam/core/pulls/216
2022-04-20 03:34:12 +09:00
Hide_D c379ecf317 feat: 연감을 가져오는 API
- Global/GetHistory - 과거 기록. 캐싱 가능
- GetCurrentHistory - 현재 기록. 캐싱 불가
2022-04-18 03:05:08 +09:00
Hide_D eadbc774e3 misc: Global/GetConst session 모드 수정 2022-04-18 00:40:50 +09:00
Hide_D 90787cdc53 fix: 국가베팅 당첨자 없을 시, 버그 2022-04-17 21:40:24 +09:00
Hide_D 337733c3d3 fix,misc: 숙련 등급 입력시 음수인 경우에도 0으로 정상 처리 2022-04-17 21:19:35 +09:00
Hide_D b7048a4422 fix: NPC국 생성 시, 평균 기술력을 받아오지 못하는 문제 수정 2022-04-17 21:17:18 +09:00
Hide_D a036f1c4bb misc: 턴 선택기에서 커맨드 항목 높이를 조절 및 가운데 정렬 2022-04-15 20:11:21 +09:00
sars f9b1ab3ba7 배팅창에서 본선 장수들이 정해져있지 않을때 스탯을 출력하려는 워닝 수정 2022-04-14 19:17:40 -07:00
Hide_D 47599f000a refac: 명장일람, 명예의 전당 2022-04-15 02:36:42 +09:00
Hide_D efb1664443 refac: 감찰부 500px 모드 2022-04-15 02:00:51 +09:00
243 changed files with 9060 additions and 7094 deletions
+2 -9
View File
@@ -15,7 +15,8 @@ return [
// Note that the **only** effect of choosing `'5.6'` is to infer
// that functions removed in php 7.0 exist.
// (See `backward_compatibility_checks` for additional options)
"target_php_version" => '8.0',
"target_php_version" => '8.1',
"minimum_target_php_version" => '8.1',
'backward_compatibility_checks ' => true,
'minimum_severity' => \Phan\Issue::SEVERITY_NORMAL,
@@ -39,11 +40,9 @@ return [
'hwe/a_emperior.php',
'hwe/a_genList.php',
'hwe/a_hallOfFame.php',
'hwe/a_history.php',
'hwe/a_kingdomList.php',
'hwe/a_npcList.php',
'hwe/api.php',
'hwe/a_status.php',
'hwe/a_traffic.php',
'hwe/a_vote.php',
'hwe/battle_simulator.php',
@@ -53,7 +52,6 @@ return [
'hwe/v_chiefCenter.php',
'hwe/b_currentCity.php',
'hwe/v_nationStratFinan.php',
'hwe/b_diplomacy.php',
'hwe/b_genList.php',
'hwe/b_myBossInfo.php',
'hwe/b_myCityInfo.php',
@@ -86,7 +84,6 @@ return [
'hwe/j_adjust_icon.php',
'hwe/j_autoreset.php',
'hwe/j_basic_info.php',
'hwe/j_betting.php',
'hwe/j_board_article_add.php',
'hwe/j_board_comment_add.php',
'hwe/j_board_get_articles.php',
@@ -101,14 +98,11 @@ return [
'hwe/j_general_set_permission.php',
'hwe/j_get_basic_general_list.php',
'hwe/j_get_city_list.php',
'hwe/j_get_reserved_command.php',
'hwe/j_get_select_npc_token.php',
'hwe/j_get_select_pool.php',
'hwe/j_image_upload.php',
'hwe/j_install_db.php',
'hwe/j_install.php',
'hwe/j_load_scenarios.php',
'hwe/j_map_history.php',
'hwe/j_map.php',
'hwe/j_map_recent.php',
'hwe/j_msg_contact_list.php',
@@ -131,7 +125,6 @@ return [
'hwe/lib.php',
'hwe/process_war.php',
'hwe/proc.php',
'hwe/readme.php',
'hwe/recent_map.php',
'hwe/select_general_from_pool.php',
'hwe/select_npc.php',
+3 -2
View File
@@ -25,12 +25,13 @@
"ezyang/htmlpurifier": "^4.10",
"xemlock/htmlpurifier-html5": "^0.1.7",
"catfan/medoo": "^1.5",
"phan/phan": "*",
"phan/phan": "^5.3",
"erusev/parsedown-extra": "^0.8.1",
"nette/caching": "^3.0",
"illuminate/database": "^8.61",
"illuminate/events": "^8.61",
"spatie/data-transfer-object": "^3.7"
"spatie/data-transfer-object": "^3.7",
"php-ds/php-ds": "^1.4"
},
"autoload": {
"psr-4": {
Generated
+67 -12
View File
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "2b7ec5f1a1a908310f3d032f294eacec",
"content-hash": "a32be16440b43a806002e52572e031db",
"packages": [
{
"name": "brandonwamboldt/utilphp",
@@ -1947,21 +1947,21 @@
},
{
"name": "phan/phan",
"version": "5.2.1",
"version": "5.3.2",
"source": {
"type": "git",
"url": "https://github.com/phan/phan.git",
"reference": "d724bbb8fc3ba89179868bb5220ecdf6a9c1636b"
"reference": "b7697eb811e912c038f709f8e1c4911c7ada3edc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phan/phan/zipball/d724bbb8fc3ba89179868bb5220ecdf6a9c1636b",
"reference": "d724bbb8fc3ba89179868bb5220ecdf6a9c1636b",
"url": "https://api.github.com/repos/phan/phan/zipball/b7697eb811e912c038f709f8e1c4911c7ada3edc",
"reference": "b7697eb811e912c038f709f8e1c4911c7ada3edc",
"shasum": ""
},
"require": {
"composer/semver": "^1.4|^2.0|^3.0",
"composer/xdebug-handler": "^1.3.2|^2.0.0",
"composer/xdebug-handler": "^2.0|^3.0",
"ext-filter": "*",
"ext-json": "*",
"ext-tokenizer": "*",
@@ -1969,8 +1969,8 @@
"microsoft/tolerant-php-parser": "^0.1.0",
"netresearch/jsonmapper": "^1.6.0|^2.0|^3.0|^4.0",
"php": "^7.2.0|^8.0.0",
"sabre/event": "^5.0.3",
"symfony/console": "^3.2|^4.0|^5.0",
"sabre/event": "^5.1.3",
"symfony/console": "^3.2|^4.0|^5.0|^6.0",
"symfony/polyfill-mbstring": "^1.11.0",
"symfony/polyfill-php80": "^1.20.0",
"tysonandre/var_representation_polyfill": "^0.0.2|^0.1.0"
@@ -1979,7 +1979,7 @@
"phpunit/phpunit": "^8.5.0"
},
"suggest": {
"ext-ast": "Needed for parsing ASTs (unless --use-fallback-parser is used). 1.0.1+ is needed, 1.0.14+ is recommended.",
"ext-ast": "Needed for parsing ASTs (unless --use-fallback-parser is used). 1.0.1+ is needed, 1.0.16+ is recommended.",
"ext-iconv": "Either iconv or mbstring is needed to ensure issue messages are valid utf-8",
"ext-igbinary": "Improves performance of polyfill when ext-ast is unavailable",
"ext-mbstring": "Either iconv or mbstring is needed to ensure issue messages are valid utf-8",
@@ -2020,9 +2020,64 @@
],
"support": {
"issues": "https://github.com/phan/phan/issues",
"source": "https://github.com/phan/phan/tree/5.2.1"
"source": "https://github.com/phan/phan/tree/5.3.2"
},
"time": "2021-09-15T00:08:40+00:00"
"time": "2022-02-01T00:17:36+00:00"
},
{
"name": "php-ds/php-ds",
"version": "v1.4.1",
"source": {
"type": "git",
"url": "https://github.com/php-ds/polyfill.git",
"reference": "43d2df301a9e2017f67b8c11d94a5222f9c00fd1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-ds/polyfill/zipball/43d2df301a9e2017f67b8c11d94a5222f9c00fd1",
"reference": "43d2df301a9e2017f67b8c11d94a5222f9c00fd1",
"shasum": ""
},
"require": {
"ext-json": "*",
"php": ">=7.0"
},
"provide": {
"ext-ds": "1.3.0"
},
"require-dev": {
"php-ds/tests": "^1.3"
},
"suggest": {
"ext-ds": "to improve performance and reduce memory usage"
},
"type": "library",
"autoload": {
"psr-4": {
"Ds\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Rudi Theunissen",
"email": "rudolf.theunissen@gmail.com"
}
],
"keywords": [
"data structures",
"ds",
"php",
"polyfill"
],
"support": {
"issues": "https://github.com/php-ds/polyfill/issues",
"source": "https://github.com/php-ds/polyfill/tree/v1.4.1"
},
"time": "2022-03-09T20:39:30+00:00"
},
{
"name": "php-extended/php-system",
@@ -6036,5 +6091,5 @@
"platform-overrides": {
"php": "8.0"
},
"plugin-api-version": "2.0.0"
"plugin-api-version": "2.2.0"
}
+7 -2
View File
@@ -36,16 +36,21 @@ body {
height: 130px;
}
#user_info button {
#user_info .btn {
width: 200px;
height: 50px;
margin: 10px 50px;
padding: 10px;
}
.center_ordered_items {
text-align: center;
}
.server-action{
padding-top: 16px;
padding-bottom: 16px;
}
.Entrance_ServerList {
width: 800px;
height: 64px;
+34 -16
View File
@@ -49,7 +49,7 @@ function getFriendlyErrorType($type)
return "{$type}";
}
function getExceptionTraceAsString($exception)
function getExceptionTraceAsString(\Throwable $exception)
{
//https://gist.github.com/abtris/1437966
$rtn = "";
@@ -96,6 +96,7 @@ function logError(string $err, string $errstr, string $errpath, array $trace)
$fdb = FileDB::db(ROOT . '/d_log/err_log.sqlite3', ROOT . '/f_install/sql/err_log.sql');
$date = date("Ymd_His");
$err =str_replace(ROOT, '{ROOT}', $errpath);
$errpath = str_replace(ROOT, '{ROOT}', $errpath);
$trace = array_map(function (string $text) {
return str_replace(ROOT, '{ROOT}', $text);
@@ -117,7 +118,7 @@ function logError(string $err, string $errstr, string $errpath, array $trace)
]);
}
function logErrorByCustomHandler(int $errno, string $errstr, string $errfile, int $errline, array $errcontext=null)
function logErrorByCustomHandler(int $errno, string $errstr, string $errfile, int $errline)
{
if (!(error_reporting() & $errno)) {
// This error code is not included in error_reporting, so let it fall
@@ -133,11 +134,12 @@ function logErrorByCustomHandler(int $errno, string $errstr, string $errfile, in
$errfile . ':' . $errline,
getExceptionTraceAsString($e)
);
return true;
}
set_error_handler("\\sammo\\logErrorByCustomHandler");
function logExceptionByCustomHandler(\Throwable $e)
function logExceptionByCustomHandler(\Throwable $e, bool $withDie = true)
{
logError(
@@ -147,32 +149,48 @@ function logExceptionByCustomHandler(\Throwable $e)
getExceptionTraceAsString($e)
);
echo $e->getTraceAsString();
throw $e;
if($withDie){
echo $e->getTraceAsString();
throw $e;
}
}
set_exception_handler('\\sammo\\logExceptionByCustomHandler');
function getAPIExecutorClass($path){
function checkForFatal()
{
$error = error_get_last();
if($error === null){
return;
}
if (($error["type"]??0) == E_ERROR) {
logErrorByCustomHandler($error["type"], $error["message"], $error["file"], $error["line"]);
}
}
static $basePath = __NAMESPACE__.'\\API\\';
if(is_string($path)){
}
else if(is_array($path)){
register_shutdown_function("\\sammo\\checkForFatal");
function getAPIExecutorClass($path)
{
static $basePath = __NAMESPACE__ . '\\API\\';
if (is_string($path)) {
} else if (is_array($path)) {
$path = join('\\', $path);
}
else{
} else {
throw new \InvalidArgumentException("{$path}는 올바른 API 지시자가 아님");
}
$classPath = str_replace('/', '\\', $basePath.$path);
$classPath = str_replace('/', '\\', $basePath . $path);
if(class_exists($classPath)){
if (class_exists($classPath)) {
return $classPath;
}
throw new \InvalidArgumentException("{$path}는 올바른 API 경로가 아님");
}
function buildAPIExecutorClass($type, string $rootPath, array $args):\sammo\BaseAPI{
function buildAPIExecutorClass($type, string $rootPath, array $args): \sammo\BaseAPI
{
$class = getAPIExecutorClass($type);
return new $class($rootPath, $args);
}
}
+1 -1
View File
@@ -14,7 +14,7 @@ $gameStor = KVStorage::getStorage($db, 'game_env');
[$turntime, $tnmt_time] = $gameStor->getValuesAsArray(['turntime','tnmt_time']);
$plock = $db->queryFirstField('SELECT plock FROM plock');
$plock = $db->queryFirstField('SELECT plock FROM plock WHERE `type` ="GAME"');
?>
<!DOCTYPE html>
<html>
+1
View File
@@ -72,6 +72,7 @@ switch ($btn) {
case "30분턴": $turnterm = 30; break;
case "60분턴": $turnterm = 60; break;
case "120분턴": $turnterm = 120; break;
default: throw new \Exception("알 수 없는 턴 기간");
}
$oldunit = $admin['turnterm'] * 60;
$unit = $turnterm * 60;
+2
View File
@@ -5,7 +5,9 @@ namespace sammo;
include "lib.php";
include "func.php";
/** @var int */
$type = Util::getPost('type', 'int', 0);
/** @var int */
$type2 = Util::getPost('type2', 'int', 0);
if ($type < 0 || $type > 17) {
+2
View File
@@ -95,6 +95,8 @@ $sel[$type] = "selected";
case 7:
$state = "<font color=green>불가침</font>";
break;
default:
throw new \Exception("알 수 없는 외교 상태: {$dip['state']}");
}
$date = TimeUtil::now();
+4 -3
View File
@@ -25,8 +25,9 @@ foreach ($db->queryFirstColumn(
CheckHall($generalNo);
}
$inheritPointManager = InheritancePointManager::getInstance();
foreach(General::createGeneralObjListFromDB($db->queryFirstColumn('SELECT `no` FROM general WHERE npc = 0')) as $genObj){
$genObj->mergeTotalInheritancePoint(true);
applyInheritanceUser($genObj->getVar('owner'));
$genObj->clearInheritancePoint();
$inheritPointManager->mergeTotalInheritancePoint($genObj, true);
$inheritPointManager->applyInheritanceUser($genObj->getVar('owner'));
$inheritPointManager->clearInheritancePoint($genObj);
}
+46 -30
View File
@@ -2,6 +2,8 @@
namespace sammo;
use sammo\Enums\RankColumn;
include "lib.php";
include "func.php";
@@ -24,32 +26,26 @@ $templates = new \League\Plates\Engine(__DIR__ . '/templates');
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1136" />
<meta name="viewport" content="width=500" />
<title><?= UniqueConst::$serverName ?>: 명장일람</title>
<?= WebUtil::printCSS('../d_shared/common.css') ?>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" />
<?= WebUtil::printCSS('css/hallOfFame.css') ?>
<?= WebUtil::printJS('../d_shared/common_path.js') ?>
<?= WebUtil::printDist('ts', 'common') ?>
<?= WebUtil::printDist('ts', ['common', 'bestGeneral']) ?>
</head>
<body>
<table align=center width=1100 class='tb_layout bg0'>
<tr>
<td>명 장 일 람<br><?= closeButton() ?></td>
</tr>
</table>
<table align=center width=1100 class='tb_layout bg0'>
<form name=form1 action=a_bestGeneral.php method=post>
<tr>
<td align=center>
<input type=submit name=btn value='유저 보기'>
<div id="container" class="bg0">
<div class="row gx-0">
<div class="col">명 장 일 람<br><?= closeButton() ?></div>
</div>
<div class="row gx-0">
<div class="col center">
<form name=form1 action=a_bestGeneral.php method=get><input type=submit name=btn value='유저 보기'>
<input type=submit name=btn value='NPC 보기'>
</td>
</tr>
</form>
</table>
<div style="margin:auto;width:1100px;">
</form>
</div>
</div>
<?php
$ownerNameList = [];
@@ -209,6 +205,32 @@ $templates = new \League\Plates\Engine(__DIR__ . '/templates');
}
return $v;
}],
["유 산 소 모 량", "int", function ($v) use ($gameStor) {
$v['value'] = $v[RankColumn::inherit_point_spent->value];
if ($gameStor->isunited) {
return $v;
}
$v['nationName'] = '???';
$v['pictureFullPath'] = GetImageURL(0) . "/default.jpg";
$v['name'] = '???';
$v['ownerName'] = null;
$v['bgColor'] = GameConst::$basecolor4;
$v['fgColor'] = newColor($v['bgColor']);
return $v;
}],
["유 산 획 득 량", "int", function ($v) use ($gameStor) {
$v['value'] = $v[RankColumn::inherit_point_earned->value];
if ($gameStor->isunited) {
return $v;
}
$v['nationName'] = '???';
$v['pictureFullPath'] = GetImageURL(0) . "/default.jpg";
$v['name'] = '???';
$v['ownerName'] = null;
$v['bgColor'] = GameConst::$basecolor4;
$v['fgColor'] = newColor($v['bgColor']);
return $v;
}],
];
$generals = [];
@@ -274,10 +296,6 @@ $templates = new \League\Plates\Engine(__DIR__ . '/templates');
'generals' => array_slice($typeGenerals, 0, min(10, $validCnt))
]);
}
?>
</div>
<div style="margin:auto;width:1100px;margin-top:5px;">
<?php
//유니크 아이템 소유자
$itemTypes = [
'horse' => '명 마',
@@ -369,15 +387,13 @@ $templates = new \League\Plates\Engine(__DIR__ . '/templates');
]);
}
?>
<div class="row gx-0">
<div class="col"><?= closeButton() ?></div>
</div>
<div class="row bg0 gx-0">
<div class="col bg0"><?= banner() ?></div>
</div>
</div>
<table align=center width=1100 class='tb_layout bg0'>
<tr>
<td><?= closeButton() ?></td>
</tr>
<tr>
<td><?= banner() ?> </td>
</tr>
</table>
</body>
</html>
+2 -2
View File
@@ -55,7 +55,7 @@ increaseRefresh("왕조일람", 1);
<tr>
<td style="background-color:#333333;" align=center colspan=8>
<font size=5>현재 (<?= $year ?>年 <?= $month ?>月)</font>
<a href="a_history.php"><button type='button'>역사 보기</button></a>
<a href="v_history.php"><button type='button'>역사 보기</button></a>
</td>
</tr>
</table>
@@ -75,7 +75,7 @@ increaseRefresh("왕조일람", 1);
<a href="a_emperior_detail.php?select=<?= $emperior['no'] ?>"><button type='button'>자세히</button></a>
<?php if ($emperior['server_id']) : ?>
<a href="a_history.php?serverID=<?= $emperior['server_id'] ?>"><button type='button'>역사 보기</button></a>
<a href="v_history.php?serverID=<?= $emperior['server_id'] ?>"><button type='button'>역사 보기</button></a>
<?php endif ?>
</td>
</tr>
+3 -2
View File
@@ -173,8 +173,9 @@ $serverID = $emperior['server_id'] ?? ($emperior['serverID'] ?? null);
if (!$nation['nation'] ?? null) {
continue;
}
$nation += Json::decode($nation['data']);
$nation = array_merge(Json::decode($nation['data']), $nation);
/** @var array $nation */
$nation['typeName'] = getNationType($nation['type']);
$nation['levelName'] = getNationLevel($nation['level']);
/** @var int[]|null $nationGenerals */
@@ -200,7 +201,7 @@ $serverID = $emperior['server_id'] ?? ($emperior['serverID'] ?? null);
}
if (key_exists('aux', $nation) && !is_array($nation['aux'])) {
$nation += Json::decode($nation['aux']);
$nation = array_merge(Json::decode($nation['aux']), $nation);
}
echo $templates->render('oldNation', $nation);
+20 -23
View File
@@ -44,22 +44,21 @@ if ($scenarioIdx && key_exists($scenarioIdx, $scenarioList[$seasonIdx] ?? [])) {
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1136" />
<meta name="viewport" content="width=500" />
<title><?= UniqueConst::$serverName ?>: 명예의 전당</title>
<?= WebUtil::printCSS('../d_shared/common.css') ?>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" />
<?= WebUtil::printCSS('css/hallOfFame.css') ?>
<?= WebUtil::printJS('../d_shared/common_path.js') ?>
<?= WebUtil::printDist('ts', ['common', 'hallOfFame']) ?>
</head>
<body>
<table align=center width=1100 class='tb_layout bg0'>
<tr>
<td>명 예 의 전 당<br><?= closeButton() ?></td>
</tr>
<tr>
<td>
<div id="container" class="bg0">
<div class="row gx-0">
<div class="col">명 예 의 전 당<br><?= closeButton() ?></div>
</div>
<div class="row gx-0">
<div class="col center">
시나리오 검색 : <select id="by_scenario" name="by_scenario">
<?php foreach ($scenarioList as $iterSeasonIdx => $subScenarioList) : ?>
<option data-season="<?= $iterSeasonIdx ?>" value="" <?= ($iterSeasonIdx == $seasonIdx && $scenarioIdx === null) ? "selected='selected'" : '' ?>>* 시즌 : <?= $iterSeasonIdx ?> 종합 *</option>
@@ -69,10 +68,8 @@ if ($scenarioIdx && key_exists($scenarioIdx, $scenarioList[$seasonIdx] ?? [])) {
<?php endforeach; ?>
?>
</select>
</td>
</tr>
</table>
<div style="margin:auto;width:1100px;">
</div>
</div>
<?php
$types = [
'experience' => ['명 성', 'int'],
@@ -113,7 +110,8 @@ if ($scenarioIdx && key_exists($scenarioIdx, $scenarioList[$seasonIdx] ?? [])) {
$hallResult = array_map(function ($general) use ($typeValue, $ownerNameList) {
$aux = Json::decode($general['aux']);
$general += $aux;
/** @var array $general */
$general = array_merge($aux, $general);
if (key_exists($general['owner'], $ownerNameList)) {
$general['ownerName'] = $ownerNameList[$general['owner']];
@@ -121,10 +119,11 @@ if ($scenarioIdx && key_exists($scenarioIdx, $scenarioList[$seasonIdx] ?? [])) {
if (!key_exists('bgColor', $general)) {
if (!key_exists('color', $general)) {
$general['bgColor'] = GameConst::$basecolor4;
$color = GameConst::$basecolor4;
} else {
$general['bgColor'] = $general['color'];
$color = $general['color'];
}
$general['bgColor'] = $color;
}
if (!key_exists('fgColor', $general)) {
@@ -156,15 +155,13 @@ if ($scenarioIdx && key_exists($scenarioIdx, $scenarioList[$seasonIdx] ?? [])) {
]);
}
?>
<div class="row gx-0">
<div class="col"><?= closeButton() ?></div>
</div>
<div class="row bg0 gx-0">
<div class="col bg0"><?= banner() ?></div>
</div>
</div>
<table align=center width=1100 class='tb_layout bg0'>
<tr>
<td><?= closeButton() ?></td>
</tr>
<tr>
<td><?= banner() ?> </td>
</tr>
</table>
</body>
</html>
-231
View File
@@ -1,231 +0,0 @@
<?php
namespace sammo;
include "lib.php";
include "func.php";
$btn = Util::getReq('btn');
$yearMonth = Util::getReq('yearmonth', 'int');
$serverID = Util::getReq('serverID', 'string', null);
//로그인 검사
$session = Session::requireGameLogin()->setReadOnly();
$userID = Session::getUserID();
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
if (!$serverID) {
$serverID = UniqueConst::$serverID;
}
if ($serverID === UniqueConst::$serverID) {
increaseRefresh("연감", 1);
}
$admin = $gameStor->getValues(['startyear', 'year', 'month']);
$me = $db->queryFirstRow('SELECT con, turntime FROM general WHERE owner = %i', $userID);
$con = checkLimit($me['con']);
if ($con >= 2) {
printLimitMsg($me['turntime']);
exit();
}
[$s_year, $s_month] = $db->queryFirstList('SELECT year, month FROM ng_history WHERE server_id = %s ORDER BY year ASC, month ASC LIMIT 1', $serverID);
$s = Util::joinYearMonth($s_year, $s_month);
if ($s_year === null) {
echo '인자 에러';
exit();
}
[$e_year, $e_month] = $db->queryFirstList('SELECT year, month FROM ng_history WHERE server_id = %s ORDER BY year DESC, month DESC LIMIT 1', $serverID);
$e = Util::joinYearMonth($e_year, $e_month);
if ($serverID !== UniqueConst::$serverID) {
$mapName = $db->queryFirstField('SELECT map FROM ng_games WHERE server_id=%s', $serverID) ?: 'che';
} else {
$mapName = GameConst::$mapName;
}
//FIXME: $yearmonth가 올바르지 않을 경우에 처리가 필요.
if ($serverID !== UniqueConst::$serverID && !$yearMonth) {
$yearMonth = $s;
} else if (!$yearMonth) {
$yearMonth = Util::joinYearMonth($admin['year'], $admin['month']);
} else {
if ($btn == "◀◀ 이전달") {
$yearMonth -= 1;
} elseif ($btn == "다음달 ▶▶") {
$yearMonth += 1;
}
}
$isCurrent = false;
if ($yearMonth < $s) {
$yearMonth = $s;
}
if ($yearMonth > $e) {
$isCurrent = true;
$yearMonth = $e + 1;
}
[$year, $month] = Util::parseYearMonth($yearMonth);
function getHistory($serverID, $year, $month):array{
$db = DB::db();
$history = $db->queryFirstRow('SELECT * FROM ng_history WHERE server_id = %s AND year = %i AND month = %i', $serverID, $year, $month);
$history['global_history'] = Json::decode($history['global_history']);
$history['global_action'] = Json::decode($history['global_action']);
$history['nations'] = Json::decode($history['nations']);
return $history;
}
if($isCurrent){
$history = getCurrentHistory();
}
else{
$history = getHistory($serverID, $year, $month);
}
$nations = $history['nations'];
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" />
<title><?= UniqueConst::$serverName ?>: 연감</title>
<?= WebUtil::printJS('../d_shared/common_path.js') ?>
<?= WebUtil::printJS("js/map/theme_{$mapName}.js") ?>
<?= WebUtil::printCSS('../d_shared/common.css') ?>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" />
<?= WebUtil::printCSS('css/map.css') ?>
<?= WebUtil::printCSS('css/history.css') ?>
<?= WebUtil::printStaticValues([
'staticValues' => [
'startYear' => $s_year,
'startMonth' => $s_month,
'lastYear' => $e_year,
'lastMonth' => $e_month,
'selectYear' => $year,
'selectMonth' => $month,
'nations' => $nations ? $history['nations'] : [],
'serverNick' => DB::prefix(),
'serverID' => UniqueConst::$serverID,
]
])?>
<?= WebUtil::printDist('ts', ['common', 'history']) ?>
</head>
<body>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td>연 감<br><?= closeButton() ?></td>
</tr>
<tr>
<td>
<form name=form1 method=post>
연월 선택 :
<input type=submit name=btn value="◀◀ 이전달">
<select id='yearmonth' name=yearmonth size=1>
<option selected='selected'><?= $year ?>년 <?= $month ?>월</option>
<option><?= $e_year ?>년 12월 (현재)</option>
</select>
<input type=submit name=btn value='조회하기'>
<input type=submit name=btn value="다음달 ▶▶">
</form>
</td>
</tr>
</table>
<table align=center width=1000 height=520 class='tb_layout bg0'>
<thead>
<tr>
<th colspan=5 align=center class='bg1'>중 원 지 도</th>
</tr>
</thead>
<tbody>
<tr height=520>
<td width=698>
<?= getMapHtml($mapName) ?>
</td>
<td id='nation_list_frame'>
<table id='nation_list'>
<thead>
<tr>
<th width=130>국명</th>
<th width=70>국력</th>
<th width=45>장수</th>
<th width=45>속령</th>
</tr>
</thead>
<tbody>
<?php foreach ($nations as $nation) : ?>
<tr>
<td><span style='color:<?= newColor($nation['color']) ?>;background-color:<?= $nation['color'] ?>'><?= $nation['name'] ?></td>
<td style='text-align:right'><?= number_format($nation['power']) ?></td>
<td style='text-align:right'><?= number_format($nation['gennum']) ?></td>
<td style='text-align:right'><?= number_format(count($nation['cities'] ?? [])) ?></td>
</tr>
<?php endforeach; ?>
</tbody>
<tfoot></tfoot>
</table>
</td>
</tr>
<tr>
<th colspan=5 align=center class='bg1'>중 원 정 세</th>
</tr>
<tr>
<td colspan=5 valign=top>
<?= formatHistoryToHTML($history['global_history']) ?>
</td>
</tr>
<tr>
<th colspan=5 align=center class='bg1'>장 수 동 향</th>
</tr>
<tr>
<td colspan=5 valign=top>
<?= formatHistoryToHTML($history['global_action']) ?>
</td>
</tr>
</tbody>
</table>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td><?= closeButton() ?></td>
</tr>
<tr>
<td><?= banner() ?> </td>
</tr>
</table>
<script>
<?php if($isCurrent): ?>
reloadWorldMap({
showMe: false,
neutralView: true,
useCachedMap: true,
});
<?php else: ?>
reloadWorldMap({
targetJson: 'j_map_history.php?year=<?= $year ?>&month=<?= $month ?>&serverID=<?= $serverID ?>',
showMe: false,
neutralView: true,
useCachedMap: false,
year: <?= $year ?>,
month: <?= $month ?>,
});
<?php endif; ?>
</script>
</body>
</html>
+66 -75
View File
@@ -74,7 +74,7 @@ if ($testGeneralNationID != $nationID) {
$gen = 0;
}
if ($btn == '정렬하기') {
if ($btn == '정렬') {
$gen = 0;
}
@@ -118,21 +118,20 @@ $showGeneral = General::createGeneralObjFromDB($gen);
<title><?= UniqueConst::$serverName ?>: 감찰부</title>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" />
<meta name="viewport" content="width=500" />
<?= WebUtil::printJS('../d_shared/common_path.js') ?>
<?= WebUtil::printCSS('../d_shared/common.css') ?>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" />
<?= WebUtil::printDist('ts', ['common']) ?>
<?= WebUtil::printDist('ts', ['common', 'battleCenter']) ?>
</head>
<body>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td>감 찰 부<br><?= closeButton() ?></td>
</tr>
<tr>
<td>
<div id="container" class="bg0">
<div class="row gx-0">
<div class="col">감 찰 부<br><?= closeButton() ?></div>
</div>
<div class="row gx-0">
<div class="col-12" style="border-left: solid 1px gray; border-right:solid 1px gray;">
<form name=form1 method=get>
정렬순서 :
<select name='query_type' size=1>
@@ -140,78 +139,70 @@ $showGeneral = General::createGeneralObjFromDB($gen);
<option <?= $queryType == $reqQueryType ? 'selected' : '' ?> value='<?= $queryType ?>'><?= $queryTypeText ?></option>
<?php endforeach; ?>
</select>
<input type=submit name=btn value='정렬하기'>
<input type=submit name=btn value='정렬'>
대상장수 :
<select name=gen size=1>
<?php foreach ($generalBasicList as $general) : ?>
<option <?= $gen == $general['no'] ? 'selected' : '' ?> value='<?= $general['no'] ?>'><?= $general['officer_level'] > 4 ? "*{$general['name']}*" : $general['name'] ?> (<?= substr($general['turntime'], 14, 5) ?>)</option>
<?php endforeach; ?>
</select>
<input type=submit name=btn value='조회하기'>
<input type=submit name=btn value='조회'>
</form>
</td>
</tr>
</table>
<table width=1000 align=center class='tb_layout bg0'>
<tr>
<td width=50% align=center class='bg1'>
<font color=skyblue size=3>장 수 정 보</font>
</td>
<td width=50% align=center class='bg1'>
<font color=orange size=3>장 수 열 전</font>
</td>
</tr>
<tr>
<td valign=top>
<?php generalInfo($showGeneral);
generalInfo2($showGeneral); ?>
</td>
<td valign=top>
<?= formatHistoryToHTML(getGeneralHistoryLogAll($gen)) ?>
</td>
</tr>
<tr>
<td align=center class='bg1'>
<font color=orange size=3>전투 기록</font>
</td>
<td align=center class='bg1'>
<font color=orange size=3>전투 결과</font>
</td>
</tr>
<tr>
<td valign=top>
<?= formatHistoryToHTML(getBattleDetailLogRecent($gen, 24)) ?>
</td>
<td valign=top>
<?= formatHistoryToHTML(getBattleResultRecent($gen, 24)) ?>
</td>
</tr>
<?php if ($showGeneral->getNPCType() > 1 || $permission >= 2) : ?>
<tr>
<td align=center class='bg1'>
<font color=orange size=3>개인 기록</font>
</td>
<td align=center class='bg1'>
<font color=orange size=3>&nbsp;</font>
</td>
</tr>
<tr>
<td valign=top>
<?= formatHistoryToHTML(getGeneralActionLogRecent($gen, 24)) ?>
</td>
<td valign=top>
</td>
</tr>
<?php endif; ?>
</table>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td><?= closeButton() ?></td>
</tr>
<tr>
<td><?= banner() ?> </td>
</tr>
</table>
</div>
<div class="col col-12 col-md-6">
<div class="row mx-0">
<div class="col bg1 header-cell" style="color:skyblue">장수 정보</div>
</div>
<div class="row">
<div class="col"><?php generalInfo($showGeneral); ?><?php generalInfo2($showGeneral); ?></div>
</div>
</div>
<div class="col col-12 col-md-6">
<div class="row mx-0">
<div class="col bg1 header-cell">장수 열전</div>
</div>
<div class="row">
<div class="col"><?= formatHistoryToHTML(getGeneralHistoryLogAll($gen)) ?></div>
</div>
</div>
<div class="col col-12 col-md-6">
<div class="row mx-0">
<div class="col bg1 header-cell">전투 기록</div>
</div>
<div class="row">
<div class="col"><?= formatHistoryToHTML(getBattleDetailLogRecent($gen, 24)) ?></div>
</div>
</div>
<div class="col col-12 col-md-6">
<div class="row mx-0">
<div class="col bg1 header-cell">전투 결과</div>
</div>
<div class="row">
<div class="col"><?= formatHistoryToHTML(getBattleResultRecent($gen, 24)) ?></div>
</div>
</div>
<?php if ($showGeneral->getNPCType() > 1 || $permission >= 2) : ?>
<div class="col col-12 col-md-6">
<div class="row mx-0">
<div class="col bg1 header-cell">개인 기록</div>
</div>
<div class="row">
<div class="col"><?= formatHistoryToHTML(getGeneralActionLogRecent($gen, 24)) ?></div>
</div>
</div>
<?php endif; ?>
</div>
<div class="row gx-0">
<div class="col "><?= backButton() ?></div>
</div>
<div class="row bg0 gx-0">
<div class="col bg0"><?= banner() ?></div>
</div>
</div>
</body>
</html>
+104 -62
View File
@@ -2,6 +2,8 @@
namespace sammo;
use sammo\Enums\RankColumn;
include "lib.php";
include "func.php";
//로그인 검사
@@ -16,17 +18,11 @@ TurnExecutionHelper::executeAllCommand();
$generalID = $session->generalID;
//NOTE: general_id만 빼기 귀찮음.
$myBet = $db->queryFirstList('SELECT * FROM betting WHERE general_id = %i', $generalID);
$myBet = array_splice($myBet, -16);
$globalBet = $db->queryFirstList('SELECT * FROM betting WHERE general_id = 0');
$globalBet = array_splice($globalBet, -16);
$me = $db->queryFirstRow('SELECT no,tournament,con,turntime from general where owner=%i', $userID);
$myBetTotal = array_sum($myBet);
$globalBetTotal = array_sum($globalBet);
$admin = $gameStor->getValues(['tournament', 'phase', 'tnmt_type', 'develcost']);
$con = checkLimit($me['con']);
@@ -36,34 +32,68 @@ if ($con >= 2) {
}
switch ($admin['tnmt_type']) {
default:
throw new \RuntimeException('Invalid tnmt_type');
case convertTournamentType('전력전'):
$tnmt_type = "<font color=cyan>전력전</font>";
$tnmt_type = "전력전";
$color = "cyan";
$tp = "total";
$tp2 = "종합";
$tp3 = "total";
break;
case convertTournamentType('통솔전'):
$tnmt_type = "<font color=cyan>통솔전</font>";
$tnmt_type = "통솔전";
$color = "cyan";
$tp = "leadership";
$tp2 = "통솔";
$tp3 = "leadership";
break;
case convertTournamentType('일기토'):
$tnmt_type = "<font color=cyan>일기토</font>";
$tnmt_type = "일기토";
$color = "cyan";
$tp = "strength";
$tp2 = "무력";
$tp3 = "strength";
break;
case convertTournamentType('설전'):
$tnmt_type = "<font color=cyan>설전</font>";
$tnmt_type = "설전";
$color = "cyan";
$tp = "intel";
$tp2 = "지력";
$tp3 = "intel";
break;
default:
throw new \RuntimeException('Invalid tnmt_type');
}
$bettingID = $gameStor->last_tournament_betting_id ?? 0;
$myBet = [];
$globalBet = [];
if ($bettingID != 0) {
$betting = $bettingID != 0 ? new Betting($bettingID) : null;
$info = $betting->getInfo();
foreach ($db->queryAllLists(
'SELECT general_id, user_id, amount, betting_type FROM ng_betting WHERE betting_id = %i',
$bettingID
) as [$betGeneralID, $userID, $amount, $bettingTypeKey]) {
$bettingKey = Json::decode($bettingTypeKey)[0];
if ($betGeneralID == $generalID) {
$myBet[$bettingKey] = $amount;
}
if (key_exists($bettingKey, $globalBet)) {
$globalBet[$bettingKey] += $amount;
} else {
$globalBet[$bettingKey] = $amount;
}
}
} else {
$info = getDummyBettingInfo($tnmt_type);
}
$myBetTotal = array_sum($myBet);
$globalBetTotal = array_sum($globalBet);
$str1 = getTournament($admin['tournament']);
$str2 = getTournamentTime();
if ($str2) {
@@ -90,6 +120,11 @@ if ($str3) {
<?= WebUtil::printCSS('../d_shared/common.css') ?>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" />
<?= WebUtil::printDist('ts', ['common', 'betting']) ?>
<?= WebUtil::printStaticValues([
'staticValues'=>[
'bettingID'=> $bettingID
]
])?>
</head>
<body>
@@ -104,7 +139,7 @@ if ($str3) {
</tr>
<tr>
<td colspan=16 align=center>
<font color=white size=6><?= $tnmt_type ?> (<?= $str1 . $str2 . $str3 ?>)</font>
<font color=white size=6><span style="color:<?= $color ?>"><?= $tnmt_type ?></span> (<?= $str1 . $str2 . $str3 ?>)</font>
</td>
</tr>
<tr>
@@ -265,7 +300,6 @@ if ($str3) {
for ($i = 0; $i < 8; $i++) {
echo "<td colspan=2>{$gen[$i]}</td>";
}
echo "
</tr>
<tr align=center>";
@@ -293,7 +327,11 @@ if ($str3) {
$line[$i] = "<font color=white>";
}
$gen[$i] = $general['name'];
$stat[$i] = $general[$tp];
if (array_key_exists($tp, $general)) {
$stat[$i] = $general[$tp];
} else {
$stat[$i] = "-";
}
}
for ($i = 0; $i < 8; $i++) {
$cent[$i] = $cent[$i] . "┻" . "</font>";
@@ -302,17 +340,17 @@ if ($str3) {
echo "<td colspan=2>{$line[$i * 2]}{$cent[$i]}{$line[$i * 2 + 1]}</td>";
}
?>
</tr>
<tr align=center>
<?php for ($i = 0; $i < 16; $i++) { ?>
<td width=70><?=$gen[$i]?></td>
<?php } ?>
</tr>
<tr align=center>
<?php for ($i = 0; $i < 16; $i++) { ?>
<td width=70 style="font-size: 14px"><?=$stat[$i]?></td>
<?php } ?>
</tr>
</tr>
<tr align=center>
<?php for ($i = 0; $i < 16; $i++) { ?>
<td width=70><?= $gen[$i] ?></td>
<?php } ?>
</tr>
<tr align=center>
<?php for ($i = 0; $i < 16; $i++) { ?>
<td width=70 style="font-size: 14px"><?= $stat[$i] ?></td>
<?php } ?>
</tr>
</table>
<table align=center width=1120 style="table-layout: fixed" class='tb_layout bg0'>
<tr align=center>
@@ -320,29 +358,29 @@ if ($str3) {
</tr>
<?php
$bet = [];
$gold = [];
$bet = [];
$gold = [];
$keyMap = [];
foreach ($info->candidates as $key => $candidate) {
$keyMap[$candidate->aux['idx']] = $key;
}
for ($i = 0; $i < 16; $i++) {
if ($globalBet[$i] == 0) {
$bet[$i] = "∞";
} else {
$bet[$i] = round($globalBetTotal / $globalBet[$i], 2);
}
}
for ($i = 0; $i < 16; $i++) {
if (!is_numeric($bet[$i])) {
$gold[$i] = 0;
} else {
$gold[$i] = Util::round($myBet[$i] * $bet[$i]);
}
}
foreach ($globalBet as $key => $amount) {
if ($amount == 0) {
$bet[$key] = "∞";
$gold[$key] = 0;
} else {
$rewardRatio = round($globalBetTotal / $amount, 2);
$bet[$key] = $rewardRatio;
$gold[$key] = $rewardRatio * ($myBet[$key] ?? 0);
}
}
echo "
<tr align=center>";
for ($i = 0; $i < 16; $i++) {
echo "<td width=70><font color=skyblue>{$bet[$i]}</font></td>";
foreach (range(0, 15) as $i) {
$amount = $bet[$keyMap[$i] ?? -1] ?? 0;
echo "<td width=70><font color=skyblue>{$amount}</font></td>";
}
?>
</tr>
@@ -366,8 +404,9 @@ if ($str3) {
</tr>
<tr align=center>
<?php
for ($i = 0; $i < 16; $i++) {
echo "<td><font color=orange>{$myBet[$i]}</font></td>";
foreach (range(0, 15) as $i) {
$amount = $myBet[$keyMap[$i] ?? -1] ?? 0;
echo "<td><font color=orange>{$amount}</font></td>";
}
?>
</tr>
@@ -391,8 +430,9 @@ if ($str3) {
</tr>
<tr align=center>
<?php
for ($i = 0; $i < 16; $i++) {
echo "<td><font color=cyan>{$gold[$i]}</font></td>";
foreach (range(0, 15) as $i) {
$amount = $gold[$keyMap[$i] ?? -1] ?? 0;
echo "<td><font color=cyan>{$amount}</font></td>";
}
echo "
@@ -403,10 +443,11 @@ if ($str3) {
echo "
<tr align=center>";
for ($i = 0; $i < 16; $i++) {
foreach (range(0, 15) as $i) {
$key = $keyMap[$i] ?? -1;
echo "
<td>
<select size=1 id='target_{$i}' style=color:white;background-color:black;>
<select size=1 id='target_{$key}' style=color:white;background-color:black;>
<option style=color:white; value=10>금10</option>
<option style=color:white; value=20>금20</option>
<option style=color:white; value=50>금50</option>
@@ -422,9 +463,10 @@ if ($str3) {
</tr>
<tr align=center>";
for ($i = 0; $i < 16; $i++) {
foreach (range(0, 15) as $i) {
$key = $keyMap[$i] ?? -1;
echo "
<td><input type=button class='submitBtn' data-target='{$i}' value=베팅! style=width:100%;color:white;background-color:black;></td>";
<td><input type=button class='submitBtn' data-target='{$key}' value=베팅! style=width:100%;color:white;background-color:black;></td>";
}
echo "</tr>";
@@ -511,14 +553,14 @@ if ($str3) {
<td align=center>勝</td>
</tr>
<?php
$prizeColumn = "{$rankColumn}p";
$gameColumn = "{$rankColumn}g";
$winColumn = "{$rankColumn}w";
$drawColumn = "{$rankColumn}d";
$loseColumn = "{$rankColumn}l";
$prizeColumn = RankColumn::from("{$rankColumn}p");
$gameColumn = RankColumn::from("{$rankColumn}g");
$winColumn = RankColumn::from("{$rankColumn}w");
$drawColumn = RankColumn::from("{$rankColumn}d");
$loseColumn = RankColumn::from("{$rankColumn}l");
$tournamentRankerList = General::createGeneralObjListFromDB(
$db->queryFirstColumn('SELECT general_id FROM rank_data WHERE `type`= %s ORDER BY value DESC LIMIT 40', $gameColumn),
[$prizeColumn, $gameColumn, $winColumn, $drawColumn, $loseColumn, 'leadership', 'strength', 'intel', 'no', 'npc', 'name'],
$db->queryFirstColumn('SELECT general_id FROM rank_data WHERE `type`= %s ORDER BY value DESC LIMIT 40', $gameColumn->value),
[$prizeColumn->value, $gameColumn->value, $winColumn->value, $drawColumn->value, $loseColumn->value, 'leadership', 'strength', 'intel', 'no', 'npc', 'name'],
0
);
usort($tournamentRankerList, function (General $lhs, General $rhs) use ($gameColumn, $winColumn, $drawColumn, $loseColumn) {
-236
View File
@@ -1,236 +0,0 @@
<?php
namespace sammo;
include "lib.php";
include "func.php";
//로그인 검사
$session = Session::requireGameLogin()->setReadOnly();
$userID = Session::getUserID();
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
increaseRefresh("중원정보", 1);
$me = $db->queryFirstRow('SELECT no,nation FROM general WHERE owner=%i', $userID);
$myNationID = $me['nation'];
$nations = array_filter(getAllNationStaticInfo(), function (array $nation) {
return $nation['level'];
});
uasort($nations, function (array $lhs, array $rhs) {
return - ($lhs['power'] <=> $rhs['power']);
});
$nationCnt = count($nations);
foreach ($db->queryAllLists('SELECT nation, count(city) FROM city WHERE nation != 0 GROUP BY nation') as [$nationID, $cityCnt]) {
$nations[$nationID]['city_cnt'] = $cityCnt;
}
$realConflict = [];
foreach ($db->queryAllLists('SELECT city, `name`, conflict FROM city WHERE conflict!=%s', '{}') as [
$cityID,
$cityName,
$rawConflict
]) {
$rawConflict = Json::decode($rawConflict);
if (count($rawConflict) < 2) {
continue;
}
$sum = array_sum($rawConflict);
$conflict = [];
foreach ($rawConflict as $nationID => $killnum) {
$conflict[$nationID] = [
'killnum' => $killnum,
'percent' => round(100 * $killnum / $sum, 1),
'name' => $nations[$nationID]['name'],
'color' => $nations[$nationID]['color']
];
}
$realConflict[] = [$cityID, $cityName, $conflict];
};
$diplomacyList = [];
foreach ($db->queryAllLists('SELECT me, you, state FROM diplomacy') as [$me, $you, $state]) {
if (!key_exists($me, $diplomacyList)) {
$diplomacyList[$me] = [];
}
$diplomacyList[$me][$you] = $state;
}
$cellWidth = intdiv(888, max(1, $nationCnt));
$defaultStateChar = '?';
$sameNationStateChar = '';
$infomativeStateCharMap = [
0 => '<span style="color:red;">★</span>',
1 => '<span style="color:magenta;">▲</span>',
2 => 'ㆍ',
7 => '<span style="color:green;">@</span>'
];
$neutralStateCharMap = [
0 => '<span style="color:red;">★</span>',
1 => '<span style="color:magenta;">▲</span>'
];
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" />
<title><?= UniqueConst::$serverName ?>: 중원 정보</title>
<?= WebUtil::printJS('../d_shared/common_path.js') ?>
<?= WebUtil::printJS('d_shared/base_map.js') ?>
<?= WebUtil::printCSS('../d_shared/common.css') ?>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" />
<?= WebUtil::printCSS('css/map.css') ?>
<?= WebUtil::printCSS('css/history.css') ?>
<?= WebUtil::printStaticValues([
'staticValues' => [
'serverNick' => DB::prefix(),
'serverID' => UniqueConst::$serverID,
'unitSet' => GameConst::$unitSet,
'mapName' => GameConst::$mapName,
],
]) ?>
<?= WebUtil::printDist('ts', ['common', 'map']) ?>
</head>
<body>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td>중 원 정 보<br><?= backButton() ?></td>
</tr>
</table>
<br>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td colspan=<?= $nationCnt + 1 ?> align=center bgcolor=blue>외 교 현 황</td>
</tr>
<tr>
<td align=center width=130 style=background-color:<?= GameConst::$basecolor2 ?>;>&nbsp;</td>
<?php foreach ($nations as $nation) : ?>
<td align=center width=<?= $cellWidth ?> style='background-color:<?= $nation['color'] ?>;color:<?= newColor($nation['color']) ?>'><?= $nation['name'] ?></td>
<?php endforeach; ?>
</tr>
<?php foreach ($nations as $me => $meNation) : ?>
<tr style='text-align:center;'>
<td align=center style='background-color:<?= $meNation['color'] ?>;color:<?= newColor($meNation['color']) ?>'><?= $meNation['name'] ?></td>
<?php foreach (array_keys($nations) as $you) : ?>
<td <?= ($me == $myNationID || $you == $myNationID) ? 'style="background-color:' . GameConst::$basecolor3 . '"' : '' ?>><?php
if ($me == $you) {
echo $sameNationStateChar;
} else if ($me == $myNationID || $you == $myNationID || $session->userGrade >= 5) {
echo $infomativeStateCharMap[$diplomacyList[$me][$you]] ?? $defaultStateChar;
} else {
echo $neutralStateCharMap[$diplomacyList[$me][$you]] ?? $defaultStateChar;
}
?></td>
<?php endforeach; ?>
</tr>
<?php endforeach; ?>
<tr>
<td colspan=<?= $nationCnt + 1 ?> align=center>불가침 : <font color=limegreen>@</font>, 통상 : ㆍ, 선포 : <font color=magenta>▲</font>, 교전 : <font color=red>★</font>
</td>
</tr>
</table>
<?php if ($realConflict) : ?>
<br>
<table align='center' width=1000 class='tb_layout bg0'>
<tr>
<td colspan=2 align=center bgcolor=magenta>분 쟁 현 황</td>
</tr>
<?php foreach ($realConflict as list($cityID, $cityName, $conflict)) : ?>
<tr>
<td align=center width=48><?= $cityName ?></td>
<td style='width:948px;position:relative;'>
<table class='tb_layout bg0' style='width:100%;'>
<?php foreach ($conflict as $item) : ?>
<tr>
<td width=130 align=right style='color:<?= newColor($item['color']) ?>;background-color:<?= $item['color'] ?>;'><?= $item['name'] ?>&nbsp;</td>
<td width=48 align=right><?= (float)$item['percent'] ?> %&nbsp;</td>
<td width=*>
<div style='display:inline-block;width:<?= $item['percent'] ?>%;background-color:<?= $item['color'] ?>;'>&nbsp;</div>
</td>
</tr>
<?php endforeach; ?>
</table>
</td>
</tr>
<?php endforeach; ?>
<tr>
<td colspan=2 height=5 class='bg1'></td>
</tr>
</table>
<?php endif; ?>
<br>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td colspan=5 align=center bgcolor=green>
<font size=3>중 원 지 도</font>
</td>
</tr>
<tr>
<td width=698 height=420>
<?= getMapHtml() ?>
</td>
<td id='nation_list_frame'>
<table id='nation_list'>
<thead>
<tr>
<th width=130>국명</th>
<th width=70>국력</th>
<th width=45>장수</th>
<th width=45>속령</th>
</tr>
</thead>
<tbody>
<?php foreach ($nations as $nation) : ?>
<tr>
<td><span style='color:<?= newColor($nation['color']) ?>;background-color:<?= $nation['color'] ?>'><?= $nation['name'] ?></td>
<td style='text-align:right'><?= number_format($nation['power']) ?></td>
<td style='text-align:right'><?= number_format($nation['gennum']) ?></td>
<td style='text-align:right'><?= number_format($nation['city_cnt']) ?></td>
</tr>
<?php endforeach; ?>
</tbody>
<tfoot></tfoot>
</table>
</td>
</tr>
</table>
<br>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td><?= backButton() ?></td>
</tr>
<tr>
<td><?= banner() ?></td>
</tr>
</table>
<script>
reloadWorldMap({
neutralView: true,
showMe: true,
useCachedMap: true
});
</script>
</body>
</html>
+28 -7
View File
@@ -50,9 +50,18 @@ $use_auto_nation_turn = $me->getAuxVar('use_auto_nation_turn') ?? 1;
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=500" />
<title><?= UniqueConst::$serverName ?>: 내정보</title>
<script>
var availableDieImmediately = <?= $availableDieImmediately ? 'true' : 'false' ?>;
</script>
<?= WebUtil::printStaticValues([
'availableDieImmediately' => $availableDieImmediately,
'staticValues' => [
'items' => Util::mapWithKey(fn (string $key, BaseItem $item) => [
'name' => $item->getName(),
'rawName' => $item->getRawName(),
'className' => $item->getRawClassName(),
'cost' => $item->getCost(),
'isBuyable' => $item->isBuyable(),
], $me->getItems())
]
]) ?>
<?= WebUtil::printCSS('../d_shared/common.css') ?>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" />
<?= WebUtil::printJS('../d_shared/common_path.js') ?>
@@ -72,8 +81,8 @@ $use_auto_nation_turn = $me->getAuxVar('use_auto_nation_turn') ?? 1;
</div>
<div class="col col-12 col-md-6">
<div class="row">
<div class="col" style='padding-left:4ch;'>
<div class="row mx-0 gx-0">
<div class="col" style='padding-left:2ch;'>
토너먼트 【
<input type=radio class='tnmt' name=tnmt value=0 <?= $me->getVar('tnmt') == 0 ? "checked" : ""; ?>>수동참여
<input type=radio class='tnmt' name=tnmt value=1 <?= $me->getVar('tnmt') == 1 ? "checked" : ""; ?>>자동참여
@@ -94,8 +103,8 @@ $use_auto_nation_turn = $me->getAuxVar('use_auto_nation_turn') ?? 1;
<option value=0 <?= (!$use_auto_nation_turn) ? "selected" : ""; ?>>허용 안함</option>
</select>】<br>
∞<span style='color:orange'>수뇌가 되었을 때 휴식 턴이어도 적당한 턴을 알아서 넣는 것을 허용합니다.</span><br><br>
<?php else: ?>
<input type="hidden" id='use_auto_nation_turn' name='use_auto_nation_turn' value="1"/>
<?php else : ?>
<input type="hidden" id='use_auto_nation_turn' name='use_auto_nation_turn' value="1" />
<?php endif; ?>
수비 【<select id='defence_train' name='defence_train'>
<?php foreach ([90, 80, 60, 40] as $targetDefenceTrain) : ?>
@@ -138,6 +147,18 @@ $use_auto_nation_turn = $me->getAuxVar('use_auto_nation_turn') ?? 1;
</div>
</div>
</div>
<div class="row">
<div class="col">아이템 파기</div>
</div>
<div class="row mx-1">
<div class="btn-group" role="group">
<?php foreach ($me->getItems() as $itemKey => $item) : ?>
<button type="button" data-item-type='<?=$itemKey?>' class="drop-item-btn btn btn-primary <?= $item->getName() == '-' ? 'disabled' : '' ?>"><?= $item->getName() ?></button>
<?php endforeach; ?>
</div>
</div>
<br>
개인용 CSS<br>
+73 -23
View File
@@ -15,6 +15,7 @@ increaseRefresh("토너먼트", 1);
TurnExecutionHelper::executeAllCommand();
$me = $db->queryFirstRow('select no,tournament,con,turntime from general where owner=%i', $userID);
$generalID = $session->generalID;
$admin = $gameStor->getValues(['tournament', 'phase', 'tnmt_msg', 'tnmt_type', 'develcost', 'tnmt_trig']);
@@ -25,34 +26,76 @@ if ($con >= 2) {
}
switch ($admin['tnmt_type']) {
default:
throw new \RuntimeException('invalid tnmt_type');
case 0:
$tnmt_type = "<font color=cyan>전력전</font>";
case convertTournamentType('전력전'):
$tnmt_type = "전력전";
$color = 'cyan';
$tp = "total";
$tp2 = "종합";
$tp3 = "total";
break;
case 1:
$tnmt_type = "<font color=cyan>통솔전</font>";
case convertTournamentType('통솔전'):
$tnmt_type = "통솔전";
$color = 'cyan';
$tp = "leadership";
$tp2 = "통솔";
$tp3 = "leadership";
break;
case 2:
$tnmt_type = "<font color=cyan>일기토</font>";
case convertTournamentType('일기토'):
$tnmt_type = "일기토";
$color = 'cyan';
$tp = "strength";
$tp2 = "무력";
$tp3 = "strength";
break;
case 3:
$tnmt_type = "<font color=cyan>설전</font>";
case convertTournamentType('설전'):
$tnmt_type = "설전";
$color = 'cyan';
$tp = "intel";
$tp2 = "지력";
$tp3 = "intel";
break;
default:
throw new \RuntimeException('invalid tnmt_type');
}
$bettingID = $gameStor->last_tournament_betting_id ?? 0;
if ($bettingID != 0) {
$betting = $bettingID != 0 ? new Betting($bettingID) : null;
$info = $betting->getInfo();
} else {
$info = getDummyBettingInfo($tnmt_type);
}
$myBet = [];
$globalBet = [];
if ($bettingID != 0) {
$betting = $bettingID != 0 ? new Betting($bettingID) : null;
$info = $betting->getInfo();
foreach ($db->queryAllLists(
'SELECT general_id, user_id, amount, betting_type FROM ng_betting WHERE betting_id = %i',
$bettingID
) as [$betGeneralID, $userID, $amount, $bettingTypeKey]) {
$bettingKey = Json::decode($bettingTypeKey)[0];
if ($betGeneralID == $generalID) {
$myBet[$bettingKey] = $amount;
}
if (key_exists($bettingKey, $globalBet)) {
$globalBet[$bettingKey] += $amount;
} else {
$globalBet[$bettingKey] = $amount;
}
}
} else {
$info = getDummyBettingInfo($tnmt_type);
}
$myBetTotal = array_sum($myBet);
$globalBetTotal = array_sum($globalBet);
?>
<!DOCTYPE html>
<html>
@@ -209,7 +252,7 @@ switch ($admin['tnmt_type']) {
</tr>
<tr>
<td colspan=8 align=center>
<font color=white size=6><?= $tnmt_type ?> (<?= $str1 . $str2 . $str3 ?>)</font>
<font color=white size=6><span style="color:<?= $color ?>"><?= $tnmt_type ?></span> (<?= $str1 . $str2 . $str3 ?>)</font>
</td>
</tr>
<tr>
@@ -418,24 +461,31 @@ switch ($admin['tnmt_type']) {
echo "
</tr>";
$globalBet = $db->queryFirstList('SELECT * FROM betting WHERE general_id = 0') ?? [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,];
$globalBet = array_splice($globalBet, -16);
$globalBetTotal = array_sum($globalBet);
$admin = $gameStor->getValues(['tournament', 'phase']);
$bet = [];
for ($i = 0; $i < 16; $i++) {
if ($globalBet[$i] == 0) {
$bet[$i] = '∞';
continue;
$gold = [];
$keyMap = [];
foreach ($info->candidates as $key => $candidate) {
$keyMap[$candidate->aux['idx']] = $key;
}
foreach ($globalBet as $key => $amount) {
if ($amount == 0) {
$bet[$key] = "∞";
$gold[$key] = 0;
} else {
$rewardRatio = round($globalBetTotal / $amount, 2);
$bet[$key] = $rewardRatio;
$gold[$key] = $rewardRatio * ($myBet[$key] ?? 0);
}
$bet[$i] = round($globalBetTotal / $globalBet[$i], 2);
}
echo "
<tr align=center>";
for ($i = 0; $i < 16; $i++) {
echo "<td><font color=skyblue>{$bet[$i]}</font></td>";
foreach (range(0, 15) as $i) {
$amount = $bet[$keyMap[$i] ?? -1] ?? 0;
echo "<td><font color=skyblue>{$amount}</font></td>";
}
echo "
@@ -469,7 +519,7 @@ switch ($admin['tnmt_type']) {
printRow($k, $general['npc'], $general['name'], $general[$tp], $general['game'], $general['win'], $general['draw'], $general['lose'], $general['gd'], $general['gl'], $general['prmt']);
}
foreach (Util::range(count($generalList), 4) as $idx) {
printRow($idx, '', '', '', '', '', '', '', '', '', '');
printRow($idx, 0, '', '', '', '', '', '', '', '', '');
}
echo "
</table>
@@ -496,7 +546,7 @@ switch ($admin['tnmt_type']) {
printRow($k, $general['npc'], $general['name'], $general[$tp], $general['game'], $general['win'], $general['draw'], $general['lose'], $general['gd'], $general['gl'], $general['prmt']);
}
foreach (Util::range(count($generalList), 8) as $idx) {
printRow($idx, '', '', '', '', '', '', '', '', '', '');
printRow($idx, 0, '', '', '', '', '', '', '', '', '');
}
echo "
</table>
+2
View File
@@ -225,6 +225,8 @@ if($btn == "자동개최설정") {
finallyAll($admin['tnmt_type'], $admin['tournament'], $admin['phase']);
} elseif($btn == "배정") {
final16set();
$phase = 0;
startBetting($admin['tnmt_type'], 720);
} elseif($btn == "베팅마감") {
$dt = date("Y-m-d H:i:s", time() + 60);
$gameStor->tournament=7;
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 582 B

+4 -6
View File
@@ -1,5 +1,3 @@
@charset "UTF-8";
.world_map {
width: 700px;
background: black;
@@ -69,11 +67,11 @@
}
.map_body .map_toggle_cityname::after {
content: "끄기"
content: " 끄기"
}
.map_body .map_toggle_cityname.active::after {
content: "켜기"
content: " 켜기"
}
.map_body .map_toggle_single_tap {
@@ -81,11 +79,11 @@
}
.map_body .map_toggle_single_tap::after {
content: "끄기"
content: " 끄기"
}
.map_body .map_toggle_single_tap.active::after {
content: "켜기"
content: " 켜기"
}
.world_map .city_tooltip {
+58 -48
View File
@@ -3,6 +3,8 @@
namespace sammo;
use DateTime;
use sammo\Enums\InheritanceKey;
use sammo\Enums\RankColumn;
use sammo\Event\Action;
require_once 'process_war.php';
@@ -472,7 +474,8 @@ function getCommandTable(General $general)
return $result;
}
function getChiefCommandTable(General $general){
function getChiefCommandTable(General $general)
{
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
$gameStor->turnOnCache();
@@ -756,8 +759,8 @@ function generalInfo2(General $generalObj)
{
$general = $generalObj->getRaw();
$winRate = round($generalObj->getRankVar('killnum') / max($generalObj->getRankVar('warnum'), 1) * 100, 2);
$killRate = round($generalObj->getRankVar('killcrew') / max($generalObj->getRankVar('deathcrew'), 1) * 100, 2);
$winRate = round($generalObj->getRankVar(RankColumn::killnum) / max($generalObj->getRankVar(RankColumn::warnum), 1) * 100, 2);
$killRate = round($generalObj->getRankVar(RankColumn::killcrew) / max($generalObj->getRankVar(RankColumn::deathcrew), 1) * 100, 2);
$experienceBonus = $generalObj->onCalcStat($generalObj, 'experience', 10000) - 10000;
if ($experienceBonus > 0) {
@@ -821,9 +824,9 @@ function generalInfo2(General $generalObj)
</tr>
<tr>
<td width=64 style='text-align:center;' class='bg1'><b>전투</b></td>
<td width=132 style='text-align:center;'>{$generalObj->getRankVar('warnum')}</td>
<td width=132 style='text-align:center;'>{$generalObj->getRankVar(RankColumn::warnum)}</td>
<td width=48 style='text-align:center;' class='bg1'><b>계략</b></td>
<td width=98 style='text-align:center;'>{$generalObj->getRankVar('firenum')}</td>
<td width=98 style='text-align:center;'>{$generalObj->getRankVar(RankColumn::firenum)}</td>
<td width=48 style='text-align:center;' class='bg1'><b>사관</b></td>
<td width=98 style='text-align:center;'>{$general['belong']}년</td>
</tr>
@@ -831,17 +834,17 @@ function generalInfo2(General $generalObj)
<td style='text-align:center;' class='bg1'><b>승률</b></td>
<td style='text-align:center;'>{$winRate} %</td>
<td style='text-align:center;' class='bg1'><b>승리</b></td>
<td style='text-align:center;'>{$generalObj->getRankVar('killnum')}</td>
<td style='text-align:center;'>{$generalObj->getRankVar(RankColumn::killnum)}</td>
<td style='text-align:center;' class='bg1'><b>패배</b></td>
<td style='text-align:center;'>{$generalObj->getRankVar('deathnum')}</td>
<td style='text-align:center;'>{$generalObj->getRankVar(RankColumn::deathnum)}</td>
</tr>
<tr>
<td style='text-align:center;' class='bg1'><b>살상률</b></td>
<td style='text-align:center;'>{$killRate} %</td>
<td style='text-align:center;' class='bg1'><b>사살</b></td>
<td style='text-align:center;'>{$generalObj->getRankVar('killcrew')}</td>
<td style='text-align:center;'>{$generalObj->getRankVar(RankColumn::killcrew)}</td>
<td style='text-align:center;' class='bg1'><b>피살</b></td>
<td style='text-align:center;'>{$generalObj->getRankVar('deathcrew')}</td>
<td style='text-align:center;'>{$generalObj->getRankVar(RankColumn::deathcrew)}</td>
</tr>
</table>
<table width=498 class='tb_layout bg2 f_tnum'>
@@ -879,9 +882,9 @@ function generalInfo2(General $generalObj)
</table>";
}
function getOnlineNum()
function getOnlineNum(): int
{
return KVStorage::getStorage(DB::db(), 'game_env')->online;
return KVStorage::getStorage(DB::db(), 'game_env')->getValue('online') ?? 0;
}
function onlinegen(General $general)
@@ -1072,6 +1075,7 @@ function updateTraffic()
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
$admin = $gameStor->getValues(['year', 'month', 'refresh', 'maxonline', 'maxrefresh']);
/** @var array{year:int,month:int,refresh:int,maxonline:int,maxrefresh:int} $admin */
//최다갱신자
$user = $db->queryFirstRow('select name,refresh from general order by refresh desc limit 1');
@@ -1121,7 +1125,7 @@ function CheckOverhead()
function isLock()
{
return DB::db()->queryFirstField("SELECT plock from plock limit 1") != 0;
return DB::db()->queryFirstField("SELECT plock from plock WHERE `type`='GAME'") != 0;
}
function tryLock(): bool
@@ -1133,7 +1137,7 @@ function tryLock(): bool
$db->update('plock', [
'plock' => 1,
'locktime' => TimeUtil::now(true)
], 'plock=0');
], 'plock=0 AND type="GAME"');
return $db->affectedRows() > 0;
}
@@ -1144,7 +1148,7 @@ function unlock(): bool
$db = DB::db();
$db->update('plock', [
'plock' => 0
], true);
], 'type="GAME"');
return $db->affectedRows() > 0;
}
@@ -1374,6 +1378,7 @@ function CheckHall($no)
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
//TODO: Enum타입을 두종류로 넣고, raw string이면 calcVar에서 받아오면?
$types = [
["experience", 'natural'],
["dedication", 'natural'],
@@ -1403,33 +1408,33 @@ function CheckHall($no)
$generalObj = General::createGeneralObjFromDB($no, null, 2);
$ttw = $generalObj->getRankVar('ttw');
$ttd = $generalObj->getRankVar('ttd');
$ttl = $generalObj->getRankVar('ttl');
$ttw = $generalObj->getRankVar(RankColumn::ttw);
$ttd = $generalObj->getRankVar(RankColumn::ttd);
$ttl = $generalObj->getRankVar(RankColumn::ttl);
$tlw = $generalObj->getRankVar('tlw');
$tld = $generalObj->getRankVar('tld');
$tll = $generalObj->getRankVar('tll');
$tlw = $generalObj->getRankVar(RankColumn::tlw);
$tld = $generalObj->getRankVar(RankColumn::tld);
$tll = $generalObj->getRankVar(RankColumn::tll);
$tsw = $generalObj->getRankVar('tsw');
$tsd = $generalObj->getRankVar('tsd');
$tsl = $generalObj->getRankVar('tsl');
$tsw = $generalObj->getRankVar(RankColumn::tsw);
$tsd = $generalObj->getRankVar(RankColumn::tsd);
$tsl = $generalObj->getRankVar(RankColumn::tsl);
$tiw = $generalObj->getRankVar('tiw');
$tid = $generalObj->getRankVar('tid');
$til = $generalObj->getRankVar('til');
$tiw = $generalObj->getRankVar(RankColumn::tiw);
$tid = $generalObj->getRankVar(RankColumn::tid);
$til = $generalObj->getRankVar(RankColumn::til);
$betWinGold = $generalObj->getRankVar('betwingold');
$betGold = Util::valueFit($generalObj->getRankVar('betgold'), 1);
$betWinGold = $generalObj->getRankVar(RankColumn::betwingold);
$betGold = Util::valueFit($generalObj->getRankVar(RankColumn::betgold), 1);
$win = $generalObj->getRankVar('killnum');
$war = Util::valueFit($generalObj->getRankVar('warnum'), 1);
$win = $generalObj->getRankVar(RankColumn::killnum);
$war = Util::valueFit($generalObj->getRankVar(RankColumn::warnum), 1);
$kill = $generalObj->getRankVar('killcrew');
$death = Util::valueFit($generalObj->getRankVar('deathcrew'), 1);
$kill = $generalObj->getRankVar(RankColumn::killcrew);
$death = Util::valueFit($generalObj->getRankVar(RankColumn::deathcrew), 1);
$killPerson = $generalObj->getRankVar('killcrew_person');
$deathPerson = Util::valueFit($generalObj->getRankVar('deathcrew_person'), 1);
$killPerson = $generalObj->getRankVar(RankColumn::killcrew_person);
$deathPerson = Util::valueFit($generalObj->getRankVar(RankColumn::deathcrew_person), 1);
$tt = Util::valueFit($ttw + $ttd + $ttl, 1);
$tl = Util::valueFit($tlw + $tld + $tll, 1);
@@ -1467,13 +1472,13 @@ function CheckHall($no)
if ($valueType === 'natural') {
$value = $generalObj->getVar($typeName);
} else if ($valueType === 'rank') {
$value = $generalObj->getRankVar($typeName);
$value = $generalObj->getRankVar(RankColumn::from($typeName));
} else if ($valueType === 'calc') {
$value = $calcVar[$typeName];
}
//승률,살상률인데 10회 미만 전투시 스킵
if (($typeName === 'winrate' || $typeName === 'killrate') && $generalObj->getRankVar('warnum') < 10) {
if (($typeName === 'winrate' || $typeName === 'killrate') && $generalObj->getRankVar(RankColumn::warnum) < 10) {
continue;
}
//토너승률인데 50회 미만시 스킵
@@ -1493,7 +1498,7 @@ function CheckHall($no)
continue;
}
//수익률인데 1000미만시 스킵
if ($typeName === 'betrate' && $generalObj->getRankVar('betgold') < 1000) {
if ($typeName === 'betrate' && $generalObj->getRankVar(RankColumn::betgold) < 1000) {
continue;
}
@@ -1581,7 +1586,7 @@ function giveRandomUniqueItem(General $general, string $acquireType): bool
}
}
foreach($db->queryAllLists('SELECT namespace, count(*) as cnt FROM `storage` WHERE namespace LIKE "ut_%" GROUP BY namespace') as [$uniqueNS, $cnt]){
foreach ($db->queryAllLists('SELECT namespace, count(*) as cnt FROM `storage` WHERE namespace LIKE "ut_%" GROUP BY namespace') as [$uniqueNS, $cnt]) {
$itemCode = substr($uniqueNS, 3);
$itemClass = buildItemClass($itemCode);
if (!$itemClass) {
@@ -1590,7 +1595,7 @@ function giveRandomUniqueItem(General $general, string $acquireType): bool
if ($itemClass->isBuyable()) {
continue;
}
$occupiedUnique[$itemCode] = ($occupiedUnique[$itemCode]??0) + $cnt;
$occupiedUnique[$itemCode] = ($occupiedUnique[$itemCode] ?? 0) + $cnt;
}
foreach (GameConst::$allItems as $itemType => $itemCategories) {
@@ -1616,7 +1621,8 @@ function giveRandomUniqueItem(General $general, string $acquireType): bool
if (!$availableUnique) {
if ($general->getAuxVar('inheritRandomUnique')) {
$general->setAuxVar('inheritRandomUnique', null);
$general->increaseInheritancePoint('previous', GameConst::$inheritItemRandomPoint);
$general->increaseInheritancePoint(InheritanceKey::previous, GameConst::$inheritItemRandomPoint);
$general->increaseRankVar(RankColumn::inherit_point_spent_dynamic, -GameConst::$inheritItemRandomPoint);
$userLogger = new UserLogger($general->getVar('owner'));
$userLogger->push(sprintf("얻을 유니크가 없어 %d 포인트 반환", GameConst::$inheritItemRandomPoint), "inheritPoint");
}
@@ -1632,7 +1638,7 @@ function giveRandomUniqueItem(General $general, string $acquireType): bool
$relMonthByInit = Util::joinYearMonth($year, $month) - Util::joinYearMonth($initYear, $initMonth);
$availableBuyUnique = $relMonthByInit >= GameConst::$minMonthToAllowInheritItem;
if($availableBuyUnique){
if ($availableBuyUnique) {
$general->setAuxVar('inheritRandomUnique', null);
}
}
@@ -1686,7 +1692,8 @@ function rollbackInheritUniqueTrial(General $general, string $itemKey, string $r
//두 값이 general, KVStorage 둘다 있고, 이중에선 KVStorage 값을 기준으로 하자 따르자
[,, $amount] = $ownTrial;
$trialStor->deleteValue("u{$ownerID}");
$general->increaseInheritancePoint('previous', $amount);
$general->increaseInheritancePoint(InheritanceKey::previous, $amount);
$general->increaseRankVar(RankColumn::inherit_point_spent_dynamic, -$amount);
LogText("선택유니크 롤백포인트:{$ownerID}", $amount);
$userLogger = new UserLogger($ownerID);
@@ -1751,12 +1758,11 @@ function tryInheritUniqueItem(General $general, string $acquireType = '아이템
$reasons[] = '이미 그 유니크를 가지고 있습니다.';
continue;
}
/*
if (!$ownItem->isBuyable()) {
$reasons[] = '이미 다른 유니크를 가지고 있습니다.';
continue;
}
*/
$availableCnt = $itemList[$itemKey];
$occupiedCnt = $db->queryFirstField('SELECT count(*) FROM general WHERE %b = %s', $itemType, $itemKey);
@@ -1858,6 +1864,9 @@ function tryInheritUniqueItem(General $general, string $acquireType = '아이템
$general->applyDB($db);
//같은 종류의 유니크를 입찰했을 수 있으니 한번 더 검사한다.
tryRollbackInheritUniqueItem($general);
return true;
}
@@ -1901,7 +1910,8 @@ function tryUniqueItemLottery(General $general, string $acquireType = '아이템
LogText("{$general->getName()}, {$general->getID()} 모든 아이템", $trialCnt);
if ($general->getAuxVar('inheritRandomUnique')) {
$general->setAuxVar('inheritRandomUnique', null);
$general->increaseInheritancePoint('previous', GameConst::$inheritItemRandomPoint);
$general->increaseInheritancePoint(InheritanceKey::previous, GameConst::$inheritItemRandomPoint);
$general->increaseRankVar(RankColumn::inherit_point_spent_dynamic, -GameConst::$inheritItemRandomPoint);
$userLogger = new UserLogger($general->getVar('owner'));
$userLogger->push(sprintf("유니크를 얻을 공간이 없어 %d 포인트 반환", GameConst::$inheritItemRandomPoint), "inheritPoint");
}
@@ -2013,10 +2023,10 @@ function deleteNation(General $lord, bool $applyDB): array
// 전 장수 재야로
foreach ($nationGeneralList as $general) {
$general->setAuxVar(
'max_belong',
InheritanceKey::max_belong->value,
max(
$general->getVar('belong'),
$general->getAuxVar('max_belong') ?? 0
$general->getAuxVar(InheritanceKey::max_belong->value) ?? 0
)
);
$general->setVar('belong', 0);
@@ -2244,7 +2254,7 @@ function calcCityDistance(int $from, int $to, ?array $linkNationList): ?int
* @param $from 기준 도시 코드
* @param $to 대상 도시 코드
* @param $linkNationList 경로에 해당하는 국가 리스트
* @return array $dist=>[cityID, $nation] 배열 가장 앞이 가장 가까움
* @return array<int,array{int,int}[]> $dist=>[cityID, $nation] 배열 가장 앞이 가장 가까움
*/
function searchDistanceListToDest(int $from, int $to, array $linkNationList)
{
+1 -1
View File
@@ -666,7 +666,7 @@ function getDexCall(int $dex) : string {
function getDexLevel(int $dex) : int {
if($dex < 0){
throw new \InvalidArgumentException();
return 0;
}
$retVal = 0;
+17 -51
View File
@@ -3,6 +3,8 @@
namespace sammo;
use Monolog\Logger;
use sammo\Enums\InheritanceKey;
use sammo\Enums\RankColumn;
/**
* 게임 룰에 해당하는 함수 모음
@@ -702,7 +704,7 @@ function updateNationState()
if ($chiefID) {
$chiefObj = General::createGeneralObjFromDB($chiefID, ['belong', 'npc', 'aux'], 2);
$chiefObj->increaseInheritancePoint('unifier', 250 * $levelDiff);
$chiefObj->increaseInheritancePoint(InheritanceKey::unifier, 250 * $levelDiff);
$chiefObj->applyDB($db);
}
}
@@ -1022,15 +1024,20 @@ function checkEmperior()
$nationLogger = new ActionLogger(0, $nationID, $admin['year'], $admin['month']);
$nationLogger->pushNationalHistoryLog("<D><b>{$nationName}</b></>{$josaYi} 전토를 통일");
foreach (General::createGeneralObjListFromDB($db->queryFirstColumn('SELECT `no` FROM general WHERE npc < 2')) as $genObj) {
$inheritPointManager = InheritancePointManager::getInstance();
$allUserGenerals = General::createGeneralObjListFromDB($db->queryFirstColumn('SELECT `no` FROM general WHERE npc < 2'));
foreach ($allUserGenerals as $genObj) {
if ($genObj->getNationID() == $nationID) {
if ($genObj->getVar('officer_level') > 4) {
$genObj->increaseInheritancePoint('unifier', 2000);
$genObj->increaseInheritancePoint(InheritanceKey::unifier, 2000);
};
}
$genObj->mergeTotalInheritancePoint(true);
applyInheritanceUser($genObj->getVar('owner'));
$genObj->clearInheritancePoint();
}
processSumInheritPointRank();
foreach ($allUserGenerals as $genObj) {
$inheritPointManager->mergeTotalInheritancePoint($genObj, true);
$inheritPointManager->applyInheritanceUser($genObj->getVar('owner'));
$inheritPointManager->clearInheritancePoint($genObj);
}
$gameStor->isunited = 2;
@@ -1184,55 +1191,14 @@ function checkEmperior()
LogHistory();
}
function applyInheritanceUser(int $userID, bool $isRebirth = false): float
{
//FIXME: 은퇴, 사망, 천통 시점에 바로 반영한다면 여기가 아니라 general class로 이동하는 것이 옳음
//또한 굳이 merge, apply, clean 3단계를 거쳐야 할 이유도 없음
$rebirthDegraded = [
'dex' => 0.5,
];
$inheritStor = KVStorage::getStorage(DB::db(), "inheritance_{$userID}");
$totalPoint = 0;
$allPoints = $inheritStor->getAll();
if (!$allPoints || count($allPoints) == 0) {
//비었으므로 리셋 안함
return 0;
}
if (count($allPoints) == 1 && key_exists('previous', $allPoints)) {
//이미 리셋되었으므로 리셋 안함
return $allPoints['previous'][0];
}
$userLogger = new UserLogger($userID);
$previousPoint = ($allPoints['previous'] ?? [0, 0])[0];
foreach ($allPoints as $key => [$value,]) {
if ($isRebirth && key_exists($key, $rebirthDegraded)) {
$value *= $rebirthDegraded[$key];
}
$keyText = General::INHERITANCE_KEY[$key][2];
$userLogger->push("{$keyText} 포인트 {$value} 증가", "inheritPoint");
$totalPoint += $value;
}
$totalPoint = Util::toInt($totalPoint);
$userLogger->push("포인트 {$previousPoint} => {$totalPoint}", "inheritPoint");
$userLogger->flush();
$inheritStor->resetValues();
$inheritStor->setValue('previous', [$totalPoint, null]);
return $totalPoint;
}
function updateMaxDomesticCritical(General $general, $score)
{
$maxDomesticCritical = $general->getAuxVar('max_domestic_critical') ?? 0;
$maxDomesticCritical = $general->getAuxVar(InheritanceKey::max_domestic_critical->value) ?? 0;
$maxDomesticCritical += $score / 2;
$general->setAuxVar('max_domestic_critical', $maxDomesticCritical);
$general->setAuxVar(InheritanceKey::max_domestic_critical->value, $maxDomesticCritical);
$oldMaxDomesticCritical = $general->getInheritancePoint('max_domestic_critical');
$oldMaxDomesticCritical = $general->getInheritancePoint(InheritanceKey::max_domestic_critical);
if ($maxDomesticCritical > $oldMaxDomesticCritical) {
$general->setInheritancePoint('max_domestic_critical', $maxDomesticCritical);
$general->setInheritancePoint(InheritanceKey::max_domestic_critical, $maxDomesticCritical);
}
}
+14 -13
View File
@@ -8,11 +8,11 @@ class MapRequest{
public $neutralView;
public $showMe;
function __construct($obj){
$this->serverID = Util::array_get($obj['serverID'], null);
$this->year = Util::array_get($obj['year']);
$this->month = Util::array_get($obj['month']);
$this->aux = Util::array_get($obj['aux'],[]);
$this->neutralView = Util::array_get($obj['neutralView'], false);
$this->serverID = $obj['serverID'] ?? null;
$this->year = $obj['year'] ?? null;
$this->month = $obj['month'] ?? null;
$this->aux = $obj['aux'] ?? [];
$this->neutralView = $obj['neutralView'] ?? false;
$this->showMe = $obj['showMe'];
}
}
@@ -35,7 +35,7 @@ function getHistoryMap($year, $month, ?string $serverID=null){
$map = DB::db()->queryFirstField('SELECT map FROM ng_history WHERE server_id = %s AND year=%i and month=%i',
$serverID,
$year,
$year,
$month);
if(!$map){
@@ -53,7 +53,7 @@ function getWorldMap($req){
if(is_array($req)){
$req = new MapRequest($req);
}
if($req->year && $req->month){
return getHistoryMap($req->year, $req->month, $req->serverID??null);
}
@@ -98,7 +98,7 @@ function getWorldMap($req){
$spyInfo = (object)null;
if($myNation){
$rawSpy = $db->queryFirstField('select `spy` from `nation` where `nation`=%i',
$rawSpy = $db->queryFirstField('select `spy` from `nation` where `nation`=%i',
$myNation);
if(strpos($rawSpy, '|') !== false || is_numeric($rawSpy)){
@@ -123,16 +123,16 @@ function getWorldMap($req){
$nationList = [];
foreach($db->query('select `nation`, `name`, `color`, `capital` from `nation`') as $row){
$nationList[] = [
Util::toInt($row['nation']),
$row['name'],
$row['color'],
Util::toInt($row['nation']),
$row['name'],
$row['color'],
Util::toInt($row['capital'])
];
}
if($myNation){
//굳이 타국 도시에 있는 아국 장수 리스트를 뽑을 이유가 없음. 일단 다 뽑자.
$shownByGeneralList =
$shownByGeneralList =
array_map('\\sammo\\Util::toInt',
$db->queryFirstColumn('select distinct `city` from `general` where `nation` = %i',
$myNation));
@@ -143,7 +143,7 @@ function getWorldMap($req){
$cityList = [];
foreach($db->query('select `city`, `level`, `state`, `nation`, `region`, `supply` from `city`') as $r){
$cityList[] =
$cityList[] =
array_map('\\sammo\\Util::toInt', [$r['city'], $r['level'], $r['state'], $r['nation'], $r['region'], $r['supply']]);
}
@@ -164,6 +164,7 @@ function getWorldMap($req){
'shownByGeneralList' => $shownByGeneralList,
'myCity' => $myCity,
'myNation' => $myNation,
'version' => 0,
'result' => true
];
}
+4
View File
@@ -60,6 +60,10 @@ function chiefTurnTable()
";
}
function templateLimitMsg(string $turntime): string{
return "이미 너무 많은 접속을 하셨습니다. 다음 턴에 다시 시도해주세요. (턴시간: {$turntime})";
}
function displayiActionObjInfo(?iAction $action)
{
if ($action === null) {
+54 -1
View File
@@ -1,10 +1,63 @@
<?php
namespace sammo;
use sammo\Enums\InheritanceKey;
use sammo\Enums\RankColumn;
use Ds\Map;
/**
* 시간 단위로 일어나는 이벤트들에 대한 함수 모음
*/
function processSumInheritPointRank(){
$db = DB::db();
$generals = General::createGeneralObjListFromDB(null, null, 2);
$points = new Map();
$points->allocate(count($generals));
foreach($generals as $general){
$generalID = $general->getID();
$points[$generalID] = 0;
}
foreach(InheritanceKey::cases() as $key){
if($key === InheritanceKey::previous){
continue;
}
$subPoints = InheritancePointManager::getInstance()->getInheritancePointFromAll($generals, $key);
foreach($generals as $general){
$generalID = $general->getID();
$points[$generalID] += $subPoints[$generalID] ?? 0;
}
}
$pointsPairs = [];
foreach($points as $generalID => $point){
$pointsPairs[] = [
'nation_id' => $generals[$generalID]->getNationID(),
'general_id' => $generalID,
'type' => RankColumn::inherit_point_earned_by_merge->value,
'value' => $point,
];
}
//XXX: multiple batch update가 제공되지 않으므로..
$db->delete('rank_data', '`type` = %s', RankColumn::inherit_point_earned_by_merge->value);
$db->insert('rank_data', $pointsPairs);
$db->query(
'UPDATE `rank_data` D SET `value` = (SELECT SUM(`value`) FROM `rank_data` S WHERE S.general_id = D.general_id AND S.`type` IN %ls) WHERE D.`type` = %s',
[RankColumn::inherit_point_earned_by_action->value, RankColumn::inherit_point_earned_by_merge->value],
RankColumn::inherit_point_earned->value
);
$db->query(
'UPDATE `rank_data` D SET `value` = (SELECT `value` FROM `rank_data` S WHERE S.general_id = D.general_id AND S.`type` = %s) WHERE D.`type` = %s',
RankColumn::inherit_point_spent_dynamic->value,
RankColumn::inherit_point_spent->value
);
}
//1월마다 실행
function processSpring() {
$db = DB::db();
@@ -41,7 +94,7 @@ function processSpring() {
function processGoldIncome() {
$db = DB::db();
$gameStor = new KVStorage($db, 'game_env');
$gameStor = KVStorage::getStorage($db, 'game_env');
[$year, $month] = $gameStor->getValuesAsArray(['year', 'month']);
$adminLog = [];
+209 -604
View File
@@ -2,13 +2,15 @@
namespace sammo;
use sammo\DTO\BettingInfo;
use sammo\Enums\InheritanceKey;
function processTournament()
{
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
$admin = $gameStor->getValues(['tournament', 'phase', 'tnmt_type', 'tnmt_auto', 'tnmt_time']);
$admin = $gameStor->getValues(['tournament', 'phase', 'tnmt_type', 'tnmt_auto', 'tnmt_time', 'last_tournament_betting_id']);
$now = new \DateTime();
$offset = $now->getTimestamp() - (new \DateTime($admin['tnmt_time']))->getTimestamp();
@@ -26,30 +28,17 @@ function processTournament()
}
//현시간이 스탬프 지나친경우
switch ($admin['tnmt_auto']) {
case 1:
$unit = 720;
break;
case 2:
$unit = 420;
break;
case 3:
$unit = 180;
break;
case 4:
$unit = 60;
break;
case 5:
$unit = 30;
break;
case 6:
$unit = 15;
break;
case 7:
$unit = 5;
break;
default:
throw new MustNotBeReachedException();
$unit = [
1 => 720,
2 => 420,
3 => 180,
4 => 60,
5 => 30,
6 => 15,
7 => 5,
][$admin['tnmt_auto']] ?? null;
if($unit === null){
throw new MustNotBeReachedException();
}
//업데이트 횟수
@@ -90,9 +79,12 @@ function processTournament()
final16set();
$tnmt = 6;
$phase = 0;
startBetting();
startBetting($type, $unit);
break;
case 6: //베팅중
$bettingID = $admin['last_tournament_betting_id'];
$betting = new Betting($bettingID);
$betting->closeBetting();
$tnmt = 7;
$phase = 0;
break;
@@ -164,41 +156,42 @@ function processTournament()
$gameStor->tnmt_time = (new \DateTimeImmutable($admin['tnmt_time']))->add(new \DateInterval("PT{$second}S"))->format('Y-m-d H:i:s');
}
function getTournamentTerm(): ?int{
function getTournamentTerm(): ?int
{
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
$tnmt_auto = $gameStor->tnmt_auto;
if($tnmt_auto === null){
if ($tnmt_auto === null) {
$tnmt_auto = $gameStor->tnmt_trig;
}
switch($tnmt_auto){
case 0: return null;
case 1: return 12 * 60;
case 2: return 7 * 60;
case 3: return 3 * 60;
case 4: return 1 * 60;
case 5: return 30;
case 6: return 15;
case 7: return 5;
}
return null;
return [
0 => null,
1 => 12 * 60,
2 => 7 * 60,
3 => 3 * 60,
4 => 1 * 60,
5 => 30,
6 => 15,
7 => 5,
][$tnmt_auto] ?? null;
}
function getTournamentTermText()
{
$term = getTournamentTerm();
if($term === null){
if ($term === null) {
return '수동';
}
if($term % 60 === 0){
if ($term % 60 === 0) {
$termMin = intdiv($term, 60);
return "경기당 {$termMin}";
}
if($term > 60){
if ($term > 60) {
$termSec = $term % 60;
$termMin = intdiv($term, 60);
return "경기당 {$termMin}{$termSec}";
@@ -263,12 +256,12 @@ function getTournament(int $tnmt)
][$tnmt] ?? "TOURNAMENT_TYPE_ERR_{$tnmt}";
}
function printRow($k, $npc, $name, $abil, $tgame, $win, $draw, $lose, $gd, $gl, $prmt)
function printRow(int $k, int $npc, string $name, $abil, $tgame, $win, $draw, $lose, $gd, $gl, $prmt)
{
$k += 1;
if ($prmt > 0) {
$name = "<font color=orange>" . $name . "</font>";
} else if($npc > 0){
} else if ($npc > 0) {
$name = formatName($name, $npc);
}
echo "<tr align=center><td class='bg2'>$k</td><td style='font-size:80%;'>$name</td><td>$abil</td><td>$tgame</td><td>$win</td><td>$draw</td><td>$lose</td><td>$gd</td><td>$gl</td></tr>";
@@ -334,32 +327,15 @@ function startTournament($auto, $type)
eraseTnmtFightLogAll();
switch ($auto) {
case 1:
$unit = 60;
break;
case 2:
$unit = 60;
break;
case 3:
$unit = 60;
break;
case 4:
$unit = 60;
break;
case 5:
$unit = 30;
break;
case 6:
$unit = 15;
break;
case 7:
$unit = 5;
break;
default:
$unit = 60;
break;
}
$unit = [
1 => 60,
2 => 60,
3 => 60,
4 => 60,
5 => 30,
6 => 15,
7 => 5,
][$auto] ?? 60;
$admin = $gameStor->getValues(['year', 'month']);
@@ -367,29 +343,12 @@ function startTournament($auto, $type)
$gameStor->tnmt_time = (new \DateTimeImmutable())->add(new \DateInterval("PT{$unit}M"))->format('Y-m-d H:i:s');
$gameStor->tournament = 1;
$gameStor->tnmt_type = $type;
$gameStor->last_tournament_betting_id = 0;
$gameStor->phase = 0;
$db->update('general', [
'tournament' => 0,
], true);
$db->update('betting', [
'bet0' => 0,
'bet1' => 0,
'bet2' => 0,
'bet3' => 0,
'bet4' => 0,
'bet5' => 0,
'bet6' => 0,
'bet7' => 0,
'bet8' => 0,
'bet9' => 0,
'bet10' => 0,
'bet11' => 0,
'bet12' => 0,
'bet13' => 0,
'bet14' => 0,
'bet15' => 0
], true);
$db->query('TRUNCATE TABLE tournament');
$opener = $db->queryFirstField('SELECT `general`.`name` FROM `general` JOIN `nation` ON `general`.`nation` = `nation`.`nation` WHERE `general`.`officer_level` = 12 AND `nation`.`level` = 7 ORDER BY rand() LIMIT 1');
@@ -416,44 +375,90 @@ function startTournament($auto, $type)
pushGlobalHistoryLog($history, $admin['year'], $admin['month']);
}
function startBetting()
function getDummyBettingInfo(string $tnmt_type): BettingInfo
{
return new BettingInfo(
id: 0,
type: 'tournament',
name: $tnmt_type,
finished: true,
selectCnt: 1,
reqInheritancePoint: false,
openYearMonth: 0,
closeYearMonth: 0,
candidates: []
);
}
function startBetting($type, $unit)
{
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
[$year, $month, $startyear] = $gameStor->getValuesAsArray(['year', 'month', 'startyear']);
[$year, $month, $startyear, $turnterm] = $gameStor->getValuesAsArray(['year', 'month', 'startyear', 'turnterm']);
pushGlobalHistoryLog([
"<S>◆</>{$year}{$month}월:<B><b>【대회】</b></>우승자를 예상하는 <C>내기</>가 진행중입니다! 호사가의 참여를 기다립니다!"
], $year, $month);
[$typeText, $statName, $statKey] = [
['전력전', '종능', 'total'],
['통솔전', '통솔', 'leadership'],
['일기토', '무력', 'strength'],
['설전', '지력', 'intel'],
][$type];
$bettingID = Betting::genNextBettingID();
//어차피 강제로 닫을 것이므로 크게 신경쓰지 않는다.
$openYearMonth = Util::joinYearMonth($year, $month);
$closeYearMonth = $openYearMonth + 120;
/** @var \sammo\DTO\SelectItem[] */
$candidates = [];
$generalList = $db->query('SELECT no,npc,name,win,leadership,strength,intel,leadership+strength+intel as total from tournament where grp>=20 order by grp, grp_no LIMIT 16');
foreach ($generalList as $idx => $general) {
if ($general['no'] <= 0) {
continue;
}
$general['idx'] = $idx;
$candidates[$general['no']] = new \sammo\DTO\SelectItem(
title: $general['name'],
info: "{$statName}: {$general[$statKey]}",
aux: $general
);
}
$candidateCnt = count($candidates);
Betting::openBetting(new BettingInfo(
id: $bettingID,
type: 'tournament',
name: $typeText,
finished: false,
selectCnt: 1,
reqInheritancePoint: false,
openYearMonth: $openYearMonth,
closeYearMonth: $closeYearMonth,
candidates: $candidates,
));
$betting = new Betting($bettingID);
$gameStor->last_tournament_betting_id = $bettingID;
$betGold = Util::valueFit(floor((3 + $year - $startyear) * 0.334) * 10, 10);
$npcList = $db->queryFirstColumn('SELECT no FROM general WHERE npc >= 2 AND gold >= (500 + %i)', $betGold);
$npcBet = [];
$betSum = [
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
];
$targetList = array_keys($candidates);
foreach ($npcList as $npcID) {
$target = Util::randRangeInt(0, 15);
$betSum[$target] += $betGold;
$target = Util::choiceRandom($targetList);
$npcBet[] = [$npcID, $target];
}
$db->update('general', [
'gold' => $db->sqleval('gold - %i', $betGold),
], 'no IN %li', $npcList);
foreach ($npcBet as [$npcID, $betTarget]) {
$targetKey = "bet{$betTarget}";
$db->update('betting', [
"bet{$betTarget}" => $db->sqleval('%b + %i', $targetKey, $betGold),
], 'general_id = %i', $npcID);
}
foreach ($betSum as $betTarget => $betSumGold) {
$targetKey = "bet{$betTarget}";
$db->update('betting', [
"bet{$betTarget}" => $db->sqleval('%b + %i', $targetKey, $betSumGold),
], 'general_id = 0');
$betting->bet($npcID, null, [$betTarget], $betGold);
}
}
@@ -512,24 +517,26 @@ function fillLowGenAll($tnmt_type)
};
//자동신청하고, 돈 있고, 아직 참가 안한 장수
/** @var array<array{0:array,1:float}> */
$freeJoinerCandidate = [];
foreach($db->query(
foreach ($db->query(
'SELECT no,npc,name,leadership,strength,intel,explevel,horse,weapon,book from general where tnmt=1 and tournament=0',
) as $gen){
) as $gen) {
$score = $scoringCandFunction($gen);
$freeJoinerCandidate[$gen['no']] = [$gen, $score**1.5];
$freeJoinerCandidate[$gen['no']] = [$gen, $score ** 1.5];
}
$joinersValues = [];
$joinersIdx = [];
foreach(Util::range($toBeFilledCnt) as $_){
if(!$freeJoinerCandidate){
foreach (Util::range($toBeFilledCnt) as $_) {
if (!$freeJoinerCandidate) {
break;
}
$general = Util::choiceRandomUsingWeightPair($freeJoinerCandidate);
/** @var array $general */
unset($freeJoinerCandidate[$general['no']]);
$grpIdx = array_keys($grpCount, min($grpCount))[0];
@@ -581,160 +588,37 @@ function fillLowGenAll($tnmt_type)
//7 8강
//8 4강
//9 결승
function getTwo($tournament, $phase)
/**
* @return array{0:int,1:int}
*/
function getTwo(int $tournament, int $phase): array
{
$cand = [];
switch ($tournament) {
case 2:
//예선
switch ($phase % 28) {
case 0:
$cand[0] = 0;
$cand[1] = 1;
break;
case 1:
$cand[0] = 2;
$cand[1] = 3;
break;
case 2:
$cand[0] = 4;
$cand[1] = 5;
break;
case 3:
$cand[0] = 6;
$cand[1] = 7;
break;
case 4:
$cand[0] = 0;
$cand[1] = 2;
break;
case 5:
$cand[0] = 1;
$cand[1] = 3;
break;
case 6:
$cand[0] = 4;
$cand[1] = 6;
break;
case 7:
$cand[0] = 5;
$cand[1] = 7;
break;
case 8:
$cand[0] = 0;
$cand[1] = 3;
break;
case 9:
$cand[0] = 1;
$cand[1] = 6;
break;
case 10:
$cand[0] = 2;
$cand[1] = 5;
break;
case 11:
$cand[0] = 4;
$cand[1] = 7;
break;
case 12:
$cand[0] = 0;
$cand[1] = 4;
break;
case 13:
$cand[0] = 1;
$cand[1] = 5;
break;
case 14:
$cand[0] = 2;
$cand[1] = 6;
break;
case 15:
$cand[0] = 3;
$cand[1] = 7;
break;
case 16:
$cand[0] = 0;
$cand[1] = 5;
break;
case 17:
$cand[0] = 1;
$cand[1] = 4;
break;
case 18:
$cand[0] = 2;
$cand[1] = 7;
break;
case 19:
$cand[0] = 3;
$cand[1] = 6;
break;
case 20:
$cand[0] = 0;
$cand[1] = 6;
break;
case 21:
$cand[0] = 1;
$cand[1] = 7;
break;
case 22:
$cand[0] = 2;
$cand[1] = 4;
break;
case 23:
$cand[0] = 3;
$cand[1] = 5;
break;
case 24:
$cand[0] = 0;
$cand[1] = 7;
break;
case 25:
$cand[0] = 1;
$cand[1] = 2;
break;
case 26:
$cand[0] = 3;
$cand[1] = 4;
break;
case 27:
$cand[0] = 5;
$cand[1] = 6;
break;
}
$candMap = [
[0, 1], [2, 3], [4, 5], [6, 7],
[0, 2], [1, 3], [4, 6], [5, 7],
[0, 3], [1, 6], [2, 5], [4, 7],
[0, 4], [1, 5], [2, 6], [3, 7],
[0, 5], [1, 4], [2, 7], [3, 6],
[0, 6], [1, 7], [2, 4], [3, 5],
[0, 7], [1, 2], [3, 4], [5, 6],
];
$cand = $candMap[$phase % 28];
if ($phase >= 28) {
$temp = $cand[0];
$cand[0] = $cand[1];
$cand[1] = $temp;
$cand = [$cand[1], $cand[0]];
}
break;
case 4:
//본선
switch ($phase % 6) {
case 0:
$cand[0] = 0;
$cand[1] = 1;
break;
case 1:
$cand[0] = 2;
$cand[1] = 3;
break;
case 2:
$cand[0] = 0;
$cand[1] = 2;
break;
case 3:
$cand[0] = 1;
$cand[1] = 3;
break;
case 4:
$cand[0] = 0;
$cand[1] = 3;
break;
case 5:
$cand[0] = 1;
$cand[1] = 2;
break;
}
$candMap = [
[0, 1], [2, 3],
[0, 2], [1, 3],
[0, 3], [1, 2],
];
$cand = $candMap[$phase % 6];
break;
}
return $cand;
@@ -927,29 +811,14 @@ function finalFight($tnmt_type, $tnmt, $phase, $type)
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
switch ($type) {
case 16:
$offset = 20;
$turn = 7;
$next = 7;
break;
case 8:
$offset = 30;
$turn = 3;
$next = 8;
break;
case 4:
$offset = 40;
$turn = 1;
$next = 9;
break;
case 2:
$offset = 50;
$turn = 0;
$next = 0;
break;
default:
throw new MustNotBeReachedException();
[$offset, $turn, $next] = [
16 => [20, 7, 7],
8 => [30, 3, 8],
4 => [40, 1, 9],
2 => [50, 0, 0],
][$type] ?? [0, 0, 0];
if ($offset === 0) {
throw new MustNotBeReachedException();
}
$grp = $phase + $offset;
@@ -987,29 +856,18 @@ function setGift($tnmt_type, $tnmt, $phase)
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
$admin = $gameStor->getValues(['year', 'month', 'develcost']);
$admin = $gameStor->getValues(['year', 'month', 'develcost', 'last_tournament_betting_id']);
$resultHelper = [];
switch ($tnmt_type) {
case 0:
$tp = "전력전";
$tp2 = "tt";
break;
case 1:
$tp = "통솔전";
$tp2 = "tl";
break;
case 2:
$tp = "일기토";
$tp2 = "ts";
break;
case 3:
$tp = "설전";
$tp2 = "ti";
break;
default:
throw new MustNotBeReachedException();
[$tp, $tp2] = [
0 => ['전력전', 'tt'],
1 => ['통솔전', 'tl'],
2 => ['일기토', 'ts'],
3 => ['설전', 'ti'],
][$tnmt_type] ?? [null, null];
if($tp === null || $tp2 === null){
throw new MustNotBeReachedException();
}
//16강자 명성 돈
@@ -1068,7 +926,7 @@ function setGift($tnmt_type, $tnmt, $phase)
//포상 장수 이름, 금액
$resultHelper[$generalID]['reward'] += $cost;
$resultHelper[$generalID]['msg'] = "<span class='ev_highlight'>4강 진출</span>";
General::createGeneralObjFromDB($generalID)->increaseInheritancePoint('tournament', 10);
General::createGeneralObjFromDB($generalID)->increaseInheritancePoint(InheritanceKey::tournament, 10);
}
//결승자 명성 돈
$cost = $admin['develcost'] * 6;
@@ -1140,39 +998,19 @@ function setGift($tnmt_type, $tnmt, $phase)
$logger = $general['logger'];
$logger->pushGeneralActionLog("<C>{$tp}</> 대회의 {$general['msg']}로 <C>{$rewardText}</>의 <S>상금</>, 약간의 <S>명성</> 획득!", ActionLogger::EVENT_PLAIN);
//TODO: 토너먼트의 다른 값이 모두 sql에 직접 입력하므로 기반을 바꿔야함.
$generalObjList[$generalID]->increaseInheritancePoint('tournament', $general['inheritance_point']);
$generalObjList[$generalID]->increaseInheritancePoint(InheritanceKey::tournament, $general['inheritance_point']);
}
//우승자 번호
$winnerGrp = $resultHelper[$winner['no']]['grp'];
$winnerGrpNo = $resultHelper[$winner['no']]['grp_no'];
$winnerSlot = ($winnerGrp - 20) * 2 + $winnerGrpNo;
//당첨칸에 베팅한 사람들만
$globalBet = $db->queryFirstList('SELECT * FROM betting WHERE general_id = 0');
$globalBet = array_splice($globalBet, -16);
$globalBetTotal = array_sum($globalBet);
$rewardRate = round($globalBetTotal / max($globalBet[$winnerSlot], 1), 2);
$betKey = "bet{$winnerSlot}";
$gambleResult = Util::convertArrayToDict($db->query('SELECT general_id, %b as bet FROM betting WHERE %b > 0 AND general_id > 0', $betKey, $betKey), 'general_id');
foreach (General::createGeneralObjListFromDB(Util::squeezeFromArray($gambleResult, 'general_id'), ['gold', 'npc'], 1) as $gambler) {
$reward = Util::round($gambleResult[$gambler->getID()]['bet'] * $rewardRate);
$gambler->increaseVar('gold', $reward);
if (($gambler->getNPCType() == 0) || ($gambler->getNPCType() == 1 && $gambler->getRankVar('betgold', 0) > 0)) {
$gambler->increaseRankVar('betwingold', $reward);
$gambler->increaseRankVar('betwin', 1);
}
$rewardText = number_format($reward);
$gambler->getLogger()->pushGeneralActionLog("<C>{$tp}</> 대회의 베팅 당첨으로 <C>{$rewardText}</>의 <S>금</> 획득!", ActionLogger::EVENT_PLAIN);
$gambler->applyDB($db);
}
$bettingID = $gameStor->last_tournament_betting_id;
$betting = new Betting($bettingID);
$betting->giveReward([$winner['no']]);
}
function setRefund()
{
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
//16강자 명성 돈
@@ -1183,9 +1021,13 @@ function setRefund()
], 'no IN %li', $generalIDList);
//베팅금 환수
$db->update(['general', [
'gold' => $db->sqleval('gold + (SELECT bet0+bet1+bet2+bet3+bet4+bet5+bet6+bet7+bet8+bet9+bet10+bet11+bet12+bet13+bet14+bet15 FROM betting WHERE general_id = general.no)')
]], true);
$bettingID = $gameStor->last_tournament_betting_id ?? 0;
if ($bettingID != 0) {
$betting = new Betting($bettingID);
if (!$betting->getInfo()->finished) {
$betting->giveReward([-1]);
}
}
//자동진행 끝
$gameStor->tnmt_auto = 0;
@@ -1219,19 +1061,15 @@ function fight($tnmt_type, $tnmt, $phs, $group, $g1, $g2, $type)
$turn = 100;
}
[$tp, $tp2] = [
0 => ['total', 'tt'],
1 => ['leadership', 'tl'],
2 => ['strength', 'ts'],
3 => ['intel', 'ti'],
][$tnmt_type] ?? [null, null];
if ($tnmt_type == 1) {
$tp = "leadership";
$tp2 = "tl";
} elseif ($tnmt_type == 2) {
$tp = "strength";
$tp2 = "ts";
} elseif ($tnmt_type == 3) {
$tp = "intel";
$tp2 = "ti";
} else /*$tnmt_type == 0*/ {
$tp = "total";
$tp2 = "tt";
if($tp === null || $tp2 === null){
throw new MustNotBeReachedException($tnmt_type);
}
$e1 = $energy1 = Util::round($gen1[$tp] * getLog($gen1['lvl'], $gen2['lvl']) * 10);
@@ -1338,303 +1176,70 @@ function fight($tnmt_type, $tnmt, $phs, $group, $g1, $g2, $type)
} // 10~50
$critical1 = 0;
$critical2 = 0;
$crticialSkillMap = [
0 => ['전력', '집중'],
1 => ['봉시진', '어린진'],
2 => ['삼단', '나선'],
3 => ['독설', '논파'],
];
$fatalitySkillMap = [
0 => '압도',
1 => '팔문금쇄진',
2 => '일격 필살',
3 => '모독 욕설'
];
$skillMap = [
0 => ['참격', '집중', '역공', '반격', '선제', '도발'],
1 => ['추행진', '학익진', '장사진', '형액진', '기형진', '구행진'],
2 => ['기합', '기염', '반격', '역공', '삼단', '나선'],
3 => ['논파', '항변', '반론', '반박', '도발', '면박'],
];
//막판 분노
$ratio = rand() % 300;
if ($e1 / 5 > $energy1 && $damage1 > $damage2 && $gen1[$tp] >= $ratio) {
$damage2 *= Util::round((rand() % 301 + 200) / 100); // 200 ~ 500%
$critical1 = 1;
if ($tnmt_type == 0) {
switch (rand() % 2) {
case 0:
$str = "전력";
break;
case 1:
$str = "집중";
break;
}
} elseif ($tnmt_type == 1) {
switch (rand() % 2) {
case 0:
$str = "봉시진";
break;
case 1:
$str = "어린진";
break;
}
} elseif ($tnmt_type == 2) {
switch (rand() % 2) {
case 0:
$str = "삼단";
break;
case 1:
$str = "나선";
break;
}
} elseif ($tnmt_type == 3) {
switch (rand() % 2) {
case 0:
$str = "독설";
break;
case 1:
$str = "논파";
break;
}
}
$str = Util::choiceRandom($crticialSkillMap[$tnmt_type]);
$log[] = "<S>●</> <Y>{$gen1['name']}</>의 분노의 <M>{$str}</> 공격!";
}
$ratio = rand() % 300;
if ($e2 / 5 > $energy2 && $damage2 > $damage1 && $gen2[$tp] >= $ratio) {
$damage1 *= Util::round((rand() % 301 + 200) / 100); // 200 ~ 500%
$critical2 = 1;
if ($tnmt_type == 0) {
switch (rand() % 2) {
case 0:
$str = "전력";
break;
case 1:
$str = "집중";
break;
}
} elseif ($tnmt_type == 1) {
switch (rand() % 2) {
case 0:
$str = "봉시진";
break;
case 1:
$str = "어린진";
break;
}
} elseif ($tnmt_type == 2) {
switch (rand() % 2) {
case 0:
$str = "삼단";
break;
case 1:
$str = "나선";
break;
}
} elseif ($tnmt_type == 3) {
switch (rand() % 2) {
case 0:
$str = "독설";
break;
case 1:
$str = "논파";
break;
}
}
$str = Util::choiceRandom($crticialSkillMap[$tnmt_type]);
$log[] = "<S>●</> <Y>{$gen2['name']}</>의 분노의 <M>{$str}</> 공격!";
}
//1합 승부
if ($phase == 1) {
$ratio = rand() % 400;
if ($gen1[$tp] * 0.9 > $gen2[$tp] && $gen1[$tp] >= $ratio) {
$damage1 = 0;
$damage2 = $e2;
if ($tnmt_type == 0) {
$log[] = "<S>●</> <Y>{$gen1['name']}</>의 <M>압도</>!";
} elseif ($tnmt_type == 1) {
$log[] = "<S>●</> <Y>{$gen1['name']}</>의 <M>팔문금쇄진</>!";
} elseif ($tnmt_type == 2) {
$log[] = "<S>●</> <Y>{$gen1['name']}</>의 <M>일격 필살</>!";
} elseif ($tnmt_type == 3) {
$log[] = "<S>●</> <Y>{$gen1['name']}</>의 <M>모독 욕설</>!";
}
$log[] = "<S>●</> <Y>{$gen1['name']}</>의 <M>{$fatalitySkillMap[$tnmt_type]}</>!";
}
if ($gen2[$tp] * 0.9 > $gen1[$tp] && $gen2[$tp] >= $ratio) {
$damage2 = 0;
$damage1 = $e1;
if ($tnmt_type == 0) {
$log[] = "<S>●</> <Y>{$gen2['name']}</>의 <M>압도</>!";
} elseif ($tnmt_type == 1) {
$log[] = "<S>●</> <Y>{$gen2['name']}</>의 <M>팔문금쇄진</>!";
} elseif ($tnmt_type == 2) {
$log[] = "<S>●</> <Y>{$gen2['name']}</>의 <M>일격 필살</>!";
} elseif ($tnmt_type == 3) {
$log[] = "<S>●</> <Y>{$gen2['name']}</>의 <M>모독 욕설</>!";
}
$log[] = "<S>●</> <Y>{$gen2['name']}</>의 <M>{$fatalitySkillMap[$tnmt_type]}</>!";
}
} else {
$ratio = rand() % 1000;
if ($critical1 == 0 && $gen1[$tp] >= $ratio) {
$damage2 *= Util::randRangeInt(150, 300) / 100; // 150 ~ 300%
$critical1 = 1;
if ($tnmt_type == 0) {
switch (rand() % 6) {
case 0:
$str = "참격";
break;
case 1:
$str = "집중";
break;
case 2:
$str = "역공";
break;
case 3:
$str = "반격";
break;
case 4:
$str = "선제";
break;
case 5:
$str = "도발";
break;
}
} elseif ($tnmt_type == 1) {
switch (rand() % 6) {
case 0:
$str = "추행진";
break;
case 1:
$str = "학익진";
break;
case 2:
$str = "장사진";
break;
case 3:
$str = "형액진";
break;
case 4:
$str = "기형진";
break;
case 5:
$str = "구행진";
break;
}
} elseif ($tnmt_type == 2) {
switch (rand() % 6) {
case 0:
$str = "기합";
break;
case 1:
$str = "기염";
break;
case 2:
$str = "반격";
break;
case 3:
$str = "역공";
break;
case 4:
$str = "삼단";
break;
case 5:
$str = "나선";
break;
}
} elseif ($tnmt_type == 3) {
switch (rand() % 6) {
case 0:
$str = "논파";
break;
case 1:
$str = "항변";
break;
case 2:
$str = "반론";
break;
case 3:
$str = "반박";
break;
case 4:
$str = "도발";
break;
case 5:
$str = "면박";
break;
}
}
$str = Util::choiceRandom($skillMap[$tnmt_type]);
$log[] = "<S>●</> <Y>{$gen1['name']}</>의 <M>{$str}</>!";
}
$ratio = rand() % 1000;
if ($critical2 == 0 && $gen2[$tp] >= $ratio) {
$damage1 *= Util::randRangeInt(150, 300) / 100; // 150 ~ 300%
$critical2 = 1;
if ($tnmt_type == 0) {
switch (rand() % 6) {
case 0:
$str = "참격";
break;
case 1:
$str = "집중";
break;
case 2:
$str = "역공";
break;
case 3:
$str = "반격";
break;
case 4:
$str = "선제";
break;
case 5:
$str = "도발";
break;
}
} elseif ($tnmt_type == 1) {
switch (rand() % 6) {
case 0:
$str = "추행진";
break;
case 1:
$str = "학익진";
break;
case 2:
$str = "장사진";
break;
case 3:
$str = "형액진";
break;
case 4:
$str = "기형진";
break;
case 5:
$str = "구행진";
break;
}
} elseif ($tnmt_type == 2) {
switch (rand() % 6) {
case 0:
$str = "기합";
break;
case 1:
$str = "기염";
break;
case 2:
$str = "반격";
break;
case 3:
$str = "역공";
break;
case 4:
$str = "삼단";
break;
case 5:
$str = "나선";
break;
}
} elseif ($tnmt_type == 3) {
switch (rand() % 6) {
case 0:
$str = "논파";
break;
case 1:
$str = "항변";
break;
case 2:
$str = "반론";
break;
case 3:
$str = "반박";
break;
case 4:
$str = "도발";
break;
case 5:
$str = "면박";
break;
}
}
$str = Util::choiceRandom($skillMap[$tnmt_type]);
$log[] = "<S>●</> <Y>{$gen2['name']}</>의 <M>{$str}</>!";
}
}
BIN
View File
Binary file not shown.
-684
View File
@@ -1,684 +0,0 @@
상성 이름 사진 국가 도시 통 무 지 급 출생 사망 꿈 특기
1, "소제1",1001, 0, "낙양", 20, 11, 48, 0, 168, 190, "유지", "-"); $gencount++;
1, "헌제",1002, 0, "낙양", 17, 13, 61, 0, 170, 250, "안전", "-", "한 왕조는 이대로 끝나는 것인가..."); $gencount++;
999, "사마휘",1003, 0, "양양", 71, 11, 96, 0, 173, 234, "은둔", "신산", "좋지, 좋아~"); $gencount++;
999, "우길",1004, 0, "업", 17, 13, 83, 0, 131, 200, "은둔", "신산"); $gencount++;
999, "화타",1005, 0, "낙양", 53, 25, 70, 0, 151, 220, "은둔", "의술", "아픈 사람들은 모두 내게 오시오. 껄껄껄."); $gencount++;
999, "길평",1006, 0, "허창", 27, 15, 72, 0, 158, 200, "은둔", "의술"); $gencount++;
29, "가규",1007, 0, "낙양", 55, 55, 74, 0, 177, 231, "재간", "-"); $gencount++;
136, "가범",1008, 0, "낙양", 58, 48, 73, 0, 202, 237, "유지", "-"); $gencount++;
49, "가비능",1009, 0, "낙양", 58, 83, 32, 0, 172, 235, "정복", "-"); $gencount++;
31, "가충",1010, 0, "낙양", 50, 25, 87, 0, 217, 282, "출세", "-"); $gencount++;
20, "가후",1011, 0, "낙양", 69, 30, 94, 0, 147, 223, "할거", "귀병"); $gencount++;
73, "간옹",1012, 0, "낙양", 31, 33, 70, 0, 164, 225, "안전", "경작"); $gencount++;
129, "감녕",1013, 0, "낙양", 78, 95, 71, 0, 174, 222, "출세", "무쌍"); $gencount++;
127, "감택",1014, 0, "낙양", 62, 44, 79, 0, 182, 243, "유지", "-"); $gencount++;
60, "강단",1015, 0, "낙양", 41, 73, 43, 0, 168, 230, "재간", "-"); $gencount++;
73, "강유",1016, 0, "낙양", 95, 90, 94, 0, 202, 264, "왕좌", "집중"); $gencount++;
102, "고간",1017, 0, "낙양", 60, 57, 51, 0, 168, 206, "유지", "-"); $gencount++;
27, "고람",1018, 0, "낙양", 72, 67, 59, 0, 159, 201, "출세", "기병"); $gencount++;
69, "고상",1019, 0, "낙양", 41, 40, 38, 0, 194, 252, "재간", "-"); $gencount++;
144, "고순",1020, 0, "낙양", 79, 82, 65, 0, 162, 198, "의협", "기병"); $gencount++;
7, "고승",1021, 0, "낙양", 42, 73, 24, 0, 145, 185, "출세", "-"); $gencount++;
120, "고옹",1022, 0, "낙양", 57, 21, 79, 0, 168, 243, "출세", "-"); $gencount++;
63, "고정",1023, 0, "낙양", 67, 65, 55, 0, 190, 251, "정복", "-"); $gencount++;
53, "고패",1024, 0, "낙양", 53, 56, 28, 0, 170, 212, "유지", "-"); $gencount++;
74, "공도",1025, 0, "낙양", 26, 73, 19, 0, 164, 200, "재간", "-"); $gencount++;
142, "공손강",1026, 0, "낙양", 64, 72, 61, 0, 172, 210, "정복", "-"); $gencount++;
142, "공손공",1027, 0, "낙양", 68, 41, 75, 0, 174, 238, "정복", "-"); $gencount++;
142, "공손도",1028, 0, "낙양", 62, 72, 41, 0, 154, 204, "정복", "기병"); $gencount++;
65, "공손범",1029, 0, "낙양", 61, 67, 61, 0, 158, 199, "출세", "-"); $gencount++;
65, "공손속",1030, 0, "낙양", 60, 76, 41, 0, 176, 199, "정복", "-"); $gencount++;
10, "공손연",1031, 0, "낙양", 74, 79, 64, 0, 205, 238, "패권", "돌격"); $gencount++;
65, "공손월",1032, 0, "낙양", 47, 63, 46, 0, 160, 192, "정복", "-"); $gencount++;
65, "공손찬",1033, 0, "낙양", 61, 87, 67, 0, 152, 199, "패권", "기병"); $gencount++;
43, "공융",1034, 0, "낙양", 63, 48, 85, 0, 153, 208, "왕좌", "경작"); $gencount++;
35, "공주",1035, 0, "낙양", 64, 35, 78, 0, 151, 194, "재간", "-"); $gencount++;
83, "공지",1036, 0, "낙양", 57, 54, 64, 0, 178, 242, "대의", "-"); $gencount++;
26, "곽가",1037, 0, "낙양", 47, 23, 99, 0, 170, 207, "패권", "귀모"); $gencount++;
111, "곽도",1038, 0, "낙양", 63, 67, 81, 0, 155, 205, "재간", "-"); $gencount++;
2, "곽사",1039, 0, "낙양", 58, 67, 31, 0, 146, 197, "패권", "-"); $gencount++;
80, "곽유지",1040, 0, "낙양", 37, 22, 71, 0, 190, 259, "재간", "상재"); $gencount++;
67, "곽익",1041, 0, "낙양", 67, 60, 67, 0, 207, 270, "재간", "-"); $gencount++;
67, "곽준",1042, 0, "낙양", 76, 69, 73, 0, 178, 217, "출세", "-"); $gencount++;
27, "곽혁",1043, 0, "낙양", 40, 29, 80, 0, 187, 228, "안전", "-"); $gencount++;
20, "곽회",1044, 0, "낙양", 77, 75, 71, 0, 187, 255, "정복", "-"); $gencount++;
39, "관구검",1045, 0, "낙양", 72, 68, 77, 0, 202, 255, "대의", "-"); $gencount++;
76, "관색",1046, 0, "낙양", 69, 85, 67, 0, 200, 239, "의협", "징병"); $gencount++;
76, "관우",1047, 0, "낙양", 96, 98, 80, 0, 162, 219, "의협", "위압"); $gencount++;
76, "관이",1048, 0, "낙양", 48, 60, 58, 0, 219, 263, "안전", "-"); $gencount++;
76, "관통",1049, 0, "낙양", 49, 63, 60, 0, 218, 259, "대의", "-"); $gencount++;
76, "관평",1050, 0, "낙양", 77, 80, 70, 0, 186, 219, "의협", "보병"); $gencount++;
7, "관해",1051, 0, "낙양", 66, 90, 35, 0, 160, 193, "출세", "-"); $gencount++;
76, "관흥",1052, 0, "낙양", 69, 84, 72, 0, 199, 234, "의협", "돌격"); $gencount++;
40, "괴량",1053, 0, "낙양", 41, 28, 81, 0, 155, 204, "안전", "신중"); $gencount++;
40, "괴월",1054, 0, "낙양", 26, 30, 84, 0, 157, 214, "유지", "귀병"); $gencount++;
98, "교모",1055, 0, "낙양", 59, 58, 61, 0, 150, 191, "안전", "-"); $gencount++;
98, "교현",1056, 0, "낙양", 50, 18, 60, 0, 158, 210, "재간", "-"); $gencount++;
6, "구역거",1057, 0, "낙양", 51, 72, 49, 0, 152, 193, "안전", "-"); $gencount++;
80, "극정",1058, 0, "낙양", 38, 25, 75, 0, 208, 278, "유지", "-"); $gencount++;
46, "금선",1059, 0, "낙양", 55, 49, 36, 0, 155, 208, "할거", "-"); $gencount++;
62, "금환삼결",1060, 0, "낙양", 46, 76, 17, 0, 192, 225, "출세", "-"); $gencount++;
141, "기령",1061, 0, "낙양", 76, 81, 33, 0, 155, 199, "대의", "무쌍"); $gencount++;
122, "낙통",1062, 0, "낙양", 57, 44, 69, 0, 193, 228, "유지", "-"); $gencount++;
124, "노숙1",1063, 0, "낙양", 90, 42, 94, 0, 172, 217, "왕좌", "상재"); $gencount++;
75, "노식",1064, 0, "낙양", 91, 54, 80, 0, 139, 192, "왕좌", "징병"); $gencount++;
59, "뇌동",1065, 0, "낙양", 70, 77, 45, 0, 172, 218, "출세", "궁병"); $gencount++;
142, "뇌박",1066, 0, "낙양", 54, 54, 33, 0, 157, 206, "유지", "-"); $gencount++;
127, "능조",1067, 0, "낙양", 67, 80, 44, 0, 165, 203, "재간", "공성"); $gencount++;
127, "능통",1068, 0, "낙양", 71, 78, 58, 0, 189, 237, "의협", "궁병"); $gencount++;
64, "단경",1069, 0, "낙양", 68, 61, 68, 0, 156, 199, "정복", "-"); $gencount++;
132, "담웅",1070, 0, "낙양", 52, 77, 19, 0, 188, 221, "출세", "-"); $gencount++;
99, "답둔",1071, 0, "낙양", 59, 71, 31, 0, 158, 207, "유지", "-"); $gencount++;
132, "당자",1072, 0, "낙양", 59, 56, 45, 0, 196, 265, "안전", "-"); $gencount++;
60, "대래동주",1073, 0, "낙양", 40, 65, 24, 0, 195, 249, "안전", "-"); $gencount++;
82, "도겸",1074, 0, "낙양", 51, 32, 61, 0, 132, 194, "할거", "인덕"); $gencount++;
120, "도준",1075, 0, "낙양", 64, 57, 50, 0, 238, 285, "안전", "-"); $gencount++;
73, "동궐",1076, 0, "낙양", 66, 50, 76, 0, 204, 271, "대의", "-"); $gencount++;
62, "동다나",1077, 0, "낙양", 51, 71, 27, 0, 189, 225, "유지", "-"); $gencount++;
2, "동민",1078, 0, "낙양", 52, 65, 49, 0, 149, 192, "안전", "-"); $gencount++;
21, "동소",1079, 0, "낙양", 46, 46, 62, 0, 156, 236, "패권", "-"); $gencount++;
127, "동습",1080, 0, "낙양", 53, 64, 32, 0, 169, 215, "출세", "-"); $gencount++;
89, "동승",1081, 0, "낙양", 75, 66, 65, 0, 154, 200, "왕좌", "-"); $gencount++;
78, "동윤",1082, 0, "낙양", 64, 26, 78, 0, 192, 246, "왕좌", "-"); $gencount++;
2, "동탁",1083, 0, "낙양", 87, 91, 54, 0, 139, 192, "패권", "기병"); $gencount++;
66, "동화",1084, 0, "낙양", 48, 64, 53, 0, 168, 219, "대의", "-"); $gencount++;
32, "두예",1085, 0, "낙양", 88, 80, 84, 0, 222, 284, "정복", "-"); $gencount++;
7, "등무",1086, 0, "낙양", 43, 74, 19, 0, 147, 185, "정복", "-"); $gencount++;
41, "등애",1087, 0, "낙양", 94, 82, 92, 0, 197, 264, "패권", "신산"); $gencount++;
116, "등윤",1088, 0, "낙양", 34, 42, 68, 0, 194, 256, "안전", "-"); $gencount++;
73, "등지",1089, 0, "낙양", 74, 51, 80, 0, 182, 251, "할거", "경작"); $gencount++;
41, "등충",1090, 0, "낙양", 60, 82, 55, 0, 230, 264, "출세", "-"); $gencount++;
54, "등현",1091, 0, "낙양", 65, 59, 61, 0, 188, 248, "출세", "-"); $gencount++;
29, "마균",1092, 0, "낙양", 33, 38, 80, 0, 200, 259, "안전", "-"); $gencount++;
71, "마대",1093, 0, "낙양", 77, 79, 49, 0, 183, 246, "대의", "기병"); $gencount++;
70, "마등",1094, 0, "낙양", 80, 87, 56, 0, 149, 211, "왕좌", "기병"); $gencount++;
80, "마속",1095, 0, "낙양", 73, 64, 82, 0, 190, 228, "패권", "집중"); $gencount++;
77, "마량",1096, 0, "낙양", 57, 25, 87, 0, 187, 225, "왕좌", "-"); $gencount++;
48, "마완",1097, 0, "낙양", 49, 64, 26, 0, 170, 211, "안전", "기병"); $gencount++;
19, "마준",1098, 0, "낙양", 45, 63, 62, 0, 196, 260, "안전", "-"); $gencount++;
71, "마철",1099, 0, "낙양", 71, 60, 31, 0, 179, 211, "대의", "기병"); $gencount++;
70, "마초",1100, 0, "낙양", 78, 97, 40, 0, 176, 226, "대의", "기병"); $gencount++;
131, "마충1",1101, 0, "낙양", 67, 62, 51, 0, 186, 222, "재간", "-"); $gencount++;
69, "마충2",1102, 0, "낙양", 61, 68, 51, 0, 187, 249, "출세", "-"); $gencount++;
71, "마휴",1103, 0, "낙양", 71, 60, 32, 0, 178, 211, "대의", "기병"); $gencount++;
116, "만총",1104, 0, "낙양", 79, 40, 78, 0, 170, 242, "할거", "신중"); $gencount++;
51, "망아장",1105, 0, "낙양", 29, 64, 20, 0, 191, 225, "출세", "-"); $gencount++;
44, "맹달",1106, 0, "낙양", 70, 66, 72, 0, 172, 228, "할거", "귀병"); $gencount++;
60, "맹우",1107, 0, "낙양", 63, 79, 26, 0, 190, 251, "정복", "-"); $gencount++;
60, "맹획",1108, 0, "낙양", 78, 92, 50, 0, 186, 245, "왕좌", "격노"); $gencount++;
29, "모개",1109, 0, "낙양", 46, 56, 56, 0, 161, 216, "대의", "-"); $gencount++;
51, "목록대왕",1110, 0, "낙양", 58, 71, 65, 0, 184, 225, "재간", "척사"); $gencount++;
96, "목순",1111, 0, "낙양", 17, 21, 68, 0, 157, 191, "왕좌", "-"); $gencount++;
43, "무안국",1112, 0, "낙양", 51, 73, 18, 0, 156, 191, "재간", "-"); $gencount++;
28, "문빙",1113, 0, "낙양", 70, 77, 43, 0, 178, 237, "유지", "-"); $gencount++;
38, "문앙",1114, 0, "낙양", 71, 91, 46, 0, 222, 285, "대의", "-"); $gencount++;
102, "문추",1115, 0, "낙양", 72, 94, 25, 0, 161, 200, "출세", "무쌍"); $gencount++;
38, "문흠",1116, 0, "낙양", 76, 77, 43, 0, 200, 258, "대의", "-"); $gencount++;
49, "미당대왕",1117, 0, "낙양", 64, 75, 32, 0, 202, 260, "유지", "-"); $gencount++;
108, "미방",1118, 0, "낙양", 58, 65, 37, 0, 169, 222, "패권", "징병"); $gencount++;
77, "미축",1119, 0, "낙양", 26, 30, 65, 0, 165, 220, "왕좌", "상재"); $gencount++;
94, "반봉",1120, 0, "낙양", 61, 75, 17, 0, 155, 191, "출세", "-"); $gencount++;
44, "반준",1121, 0, "낙양", 41, 21, 67, 0, 174, 239, "안전", "-"); $gencount++;
65, "방덕",1122, 0, "낙양", 76, 90, 67, 0, 170, 219, "의협", "기병"); $gencount++;
73, "방통",1123, 0, "낙양", 86, 41, 97, 0, 179, 214, "패권", "반계"); $gencount++;
65, "방회",1124, 0, "낙양", 25, 33, 59, 0, 205, 272, "안전", "-"); $gencount++;
68, "배원소",1125, 0, "낙양", 45, 69, 33, 0, 169, 200, "재간", "-"); $gencount++;
78, "번건",1126, 0, "낙양", 28, 31, 68, 0, 205, 270, "대의", "-"); $gencount++;
149, "번주",1127, 0, "낙양", 67, 77, 21, 0, 149, 192, "할거", "-"); $gencount++;
72, "법정",1128, 0, "낙양", 81, 29, 93, 0, 176, 220, "패권", "신산"); $gencount++;
8, "변희",1129, 0, "낙양", 65, 65, 27, 0, 169, 200, "안전", "-"); $gencount++;
121, "보질",1130, 0, "낙양", 58, 28, 77, 0, 177, 247, "유지", "-"); $gencount++;
113, "복양흥",1131, 0, "낙양", 58, 51, 71, 0, 224, 264, "유지", "-"); $gencount++;
110, "봉기",1132, 0, "낙양", 68, 52, 80, 0, 153, 202, "패권", "집중"); $gencount++;
74, "부동",1133, 0, "낙양", 58, 69, 69, 0, 183, 222, "대의", "-"); $gencount++;
108, "부사인",1134, 0, "낙양", 54, 59, 51, 0, 182, 222, "출세", "-"); $gencount++;
38, "부손",1135, 0, "낙양", 24, 43, 68, 0, 162, 230, "안전", "-"); $gencount++;
74, "부첨",1136, 0, "낙양", 61, 74, 45, 0, 216, 263, "대의", "-"); $gencount++;
66, "비시",1137, 0, "낙양", 18, 36, 61, 0, 176, 240, "재간", "-"); $gencount++;
141, "비연",1138, 0, "낙양", 66, 65, 53, 0, 196, 238, "출세", "-"); $gencount++;
77, "비위",1139, 0, "낙양", 72, 26, 73, 0, 193, 253, "대의", "-"); $gencount++;
144, "사광",1140, 0, "낙양", 57, 49, 66, 0, 175, 235, "안전", "-"); $gencount++;
71, "사마가",1141, 0, "낙양", 61, 85, 18, 0, 167, 222, "정복", "돌격"); $gencount++;
20, "사마랑",1142, 0, "낙양", 25, 32, 63, 0, 171, 217, "대의", "-"); $gencount++;
24, "사마망",1143, 0, "낙양", 71, 61, 65, 0, 205, 271, "정복", "-"); $gencount++;
24, "사마부",1144, 0, "낙양", 55, 31, 73, 0, 180, 272, "대의", "-"); $gencount++;
31, "사마사",1145, 0, "낙양", 87, 64, 91, 0, 208, 255, "정복", "-"); $gencount++;
31, "사마소",1146, 0, "낙양", 93, 63, 84, 0, 211, 265, "정복", "-"); $gencount++;
31, "사마염",1147, 0, "낙양", 92, 78, 72, 0, 236, 290, "패권", "-"); $gencount++;
30, "사마유",1148, 0, "낙양", 62, 45, 79, 0, 248, 283, "왕좌", "-"); $gencount++;
31, "사마의",1149, 0, "낙양", 98, 67, 98, 0, 179, 251, "패권", "반계"); $gencount++;
139, "사섭",1150, 0, "낙양", 63, 61, 71, 0, 137, 226, "안전", "-"); $gencount++;
139, "사일",1151, 0, "낙양", 59, 44, 68, 0, 153, 230, "유지", "-"); $gencount++;
132, "사정",1152, 0, "낙양", 67, 71, 20, 0, 178, 221, "안전", "-"); $gencount++;
146, "사지",1153, 0, "낙양", 61, 49, 70, 0, 163, 227, "안전", "-"); $gencount++;
144, "사휘",1154, 0, "낙양", 67, 71, 61, 0, 165, 227, "유지", "-"); $gencount++;
35, "서막",1155, 0, "낙양", 56, 41, 72, 0, 171, 249, "유지", "-"); $gencount++;
76, "서서",1156, 0, "낙양", 90, 70, 96, 0, 178, 232, "의협", "귀병"); $gencount++;
124, "서성",1157, 0, "낙양", 83, 76, 83, 0, 177, 234, "대의", "-"); $gencount++;
142, "서영",1158, 0, "낙양", 47, 63, 33, 0, 147, 191, "안전", "-"); $gencount++;
23, "서질",1159, 0, "낙양", 55, 73, 34, 0, 207, 253, "재간", "-"); $gencount++;
23, "서황",1160, 0, "낙양", 79, 89, 68, 0, 165, 228, "의협", "필살"); $gencount++;
32, "석포",1161, 0, "낙양", 71, 63, 59, 0, 214, 272, "정복", "-"); $gencount++;
131, "설영",1162, 0, "낙양", 46, 23, 64, 0, 223, 282, "유지", "-"); $gencount++;
128, "설종",1163, 0, "낙양", 27, 33, 67, 0, 187, 243, "유지", "-"); $gencount++;
69, "성의",1164, 0, "낙양", 45, 64, 22, 0, 168, 211, "재간", "-"); $gencount++;
129, "소비",1165, 0, "낙양", 67, 63, 49, 0, 172, 221, "대의", "-"); $gencount++;
76, "손건",1166, 0, "낙양", 42, 33, 73, 0, 165, 215, "대의", null); $gencount++;
125, "손견",1167, 0, "낙양", 96, 95, 76, 0, 156, 192, "왕좌", "무쌍"); $gencount++;
126, "손광",1168, 0, "낙양", 63, 54, 58, 0, 186, 207, "유지", "-"); $gencount++;
125, "손권",1169, 0, "낙양", 90, 77, 83, 0, 182, 252, "할거", "수비"); $gencount++;
126, "손랑",1170, 0, "낙양", 27, 54, 28, 0, 187, 226, "안전", "-"); $gencount++;
126, "손등",1171, 0, "낙양", 52, 39, 77, 0, 209, 241, "할거", "-"); $gencount++;
125, "손량",1172, 0, "낙양", 24, 23, 79, 0, 243, 260, "할거", "-"); $gencount++;
20, "손례",1173, 0, "낙양", 64, 64, 69, 0, 180, 250, "안전", "-"); $gencount++;
124, "손소",1174, 0, "낙양", 76, 80, 68, 0, 188, 241, "정복", "-"); $gencount++;
130, "손수",1175, 0, "낙양", 67, 57, 59, 0, 235, 299, "안전", "-"); $gencount++;
126, "손유",1176, 0, "낙양", 77, 60, 67, 0, 177, 215, "정복", "-"); $gencount++;
122, "손이",1177, 0, "낙양", 57, 62, 57, 0, 223, 272, "안전", "-"); $gencount++;
126, "손정",1178, 0, "낙양", 59, 56, 62, 0, 160, 206, "유지", "-"); $gencount++;
115, "손준",1179, 0, "낙양", 59, 69, 51, 0, 219, 256, "정복", "-"); $gencount++;
7, "손중",1180, 0, "낙양", 53, 63, 24, 0, 154, 185, "안전", "-"); $gencount++;
125, "손책",1181, 0, "낙양", 96, 96, 78, 0, 175, 200, "패권", "필살"); $gencount++;
115, "손침",1182, 0, "낙양", 49, 71, 40, 0, 231, 258, "패권", "-"); $gencount++;
114, "손호",1183, 0, "낙양", 20, 78, 67, 0, 242, 284, "패권", "-"); $gencount++;
126, "손화",1184, 0, "낙양", 35, 25, 71, 0, 224, 253, "왕좌", "-"); $gencount++;
127, "손환",1185, 0, "낙양", 79, 65, 70, 0, 197, 228, "정복", "-"); $gencount++;
126, "손휴",1186, 0, "낙양", 63, 43, 64, 0, 235, 264, "정복", "-"); $gencount++;
117, "손흠",1187, 0, "낙양", 66, 63, 33, 0, 235, 280, "정복", "-"); $gencount++;
147, "송헌",1188, 0, "낙양", 42, 63, 41, 0, 157, 200, "안전", "-"); $gencount++;
95, "순우경",1189, 0, "낙양", 72, 67, 60, 0, 146, 200, "할거", "-"); $gencount++;
22, "순욱1",1190, 0, "낙양", 54, 29, 97, 0, 163, 212, "왕좌", "집중"); $gencount++;
22, "순유",1191, 0, "낙양", 73, 41, 90, 0, 157, 214, "대의", "신중"); $gencount++;
29, "신비",1192, 0, "낙양", 47, 28, 74, 0, 171, 240, "재간", "-"); $gencount++;
37, "신의",1193, 0, "낙양", 55, 61, 51, 0, 190, 252, "출세", "-"); $gencount++;
37, "신탐",1194, 0, "낙양", 56, 58, 57, 0, 188, 254, "출세", "-"); $gencount++;
85, "신평",1195, 0, "낙양", 68, 51, 75, 0, 165, 204, "왕좌", "-"); $gencount++;
102, "심배",1196, 0, "낙양", 75, 66, 68, 0, 156, 204, "패권", "귀병"); $gencount++;
126, "심영",1197, 0, "낙양", 53, 72, 51, 0, 235, 280, "재간", "-"); $gencount++;
47, "아하소과",1198, 0, "낙양", 53, 75, 15, 0, 204, 253, "안전", "척사"); $gencount++;
62, "아회남",1199, 0, "낙양", 50, 74, 30, 0, 190, 225, "출세", "척사"); $gencount++;
23, "악진",1200, 0, "낙양", 73, 67, 56, 0, 159, 218, "대의", "돌격"); $gencount++;
23, "악침",1201, 0, "낙양", 45, 52, 33, 0, 196, 257, "대의", "-"); $gencount++;
63, "악환",1202, 0, "낙양", 54, 82, 55, 0, 196, 251, "재간", "-"); $gencount++;
102, "안량",1203, 0, "낙양", 73, 93, 36, 0, 160, 200, "출세", "위압"); $gencount++;
14, "양백",1204, 0, "낙양", 55, 54, 53, 0, 171, 214, "안전", "-"); $gencount++;
92, "양봉1",1205, 0, "낙양", 57, 64, 36, 0, 153, 197, "유지", "-"); $gencount++;
91, "양봉2",1206, 0, "낙양", 62, 78, 61, 0, 191, 252, "정복", "-"); $gencount++;
13, "양송",1207, 0, "낙양", 15, 35, 34, 0, 167, 215, "안전", "-"); $gencount++;
43, "양수",1208, 0, "낙양", 18, 31, 91, 0, 175, 219, "재간", "귀병"); $gencount++;
61, "양의",1209, 0, "낙양", 67, 56, 71, 0, 190, 235, "유지", "-"); $gencount++;
141, "양조1",1210, 0, "낙양", 68, 54, 60, 0, 202, 256, "출세", "-"); $gencount++;
9, "양추1",1211, 0, "낙양", 51, 67, 16, 0, 159, 199, "정복", "-"); $gencount++;
31, "양호",1212, 0, "낙양", 91, 69, 80, 0, 221, 278, "패권", "-"); $gencount++;
53, "양회",1213, 0, "낙양", 60, 67, 40, 0, 167, 212, "출세", "-"); $gencount++;
141, "양흥",1214, 0, "낙양", 52, 68, 17, 0, 169, 211, "안전", "-"); $gencount++;
6, "어부라",1215, 0, "낙양", 78, 80, 61, 0, 150, 195, "정복", "-"); $gencount++;
64, "엄강",1216, 0, "낙양", 57, 65, 44, 0, 163, 192, "재간", "-"); $gencount++;
10, "엄백호",1217, 0, "낙양", 48, 68, 30, 0, 150, 197, "할거", "-"); $gencount++;
10, "엄여",1218, 0, "낙양", 35, 66, 24, 0, 153, 197, "할거", "-"); $gencount++;
69, "엄안",1219, 0, "낙양", 72, 84, 67, 0, 151, 222, "왕좌", "-"); $gencount++;
7, "엄정",1220, 0, "낙양", 31, 68, 49, 0, 151, 189, "출세", "-"); $gencount++;
121, "엄준",1221, 0, "낙양", 44, 24, 71, 0, 169, 246, "재간", "-"); $gencount++;
71, "여개",1222, 0, "낙양", 51, 42, 67, 0, 194, 227, "유지", "-"); $gencount++;
29, "여건",1223, 0, "낙양", 44, 68, 29, 0, 173, 238, "출세", "-"); $gencount++;
107, "여광",1224, 0, "낙양", 60, 67, 27, 0, 162, 207, "유지", "-"); $gencount++;
124, "여몽",1225, 0, "낙양", 92, 78, 93, 0, 178, 219, "패권", "궁병"); $gencount++;
123, "여범",1226, 0, "낙양", 43, 34, 71, 0, 169, 228, "할거", "-"); $gencount++;
107, "여상",1227, 0, "낙양", 62, 68, 26, 0, 164, 207, "유지", "-"); $gencount++;
105, "여위황",1228, 0, "낙양", 42, 62, 38, 0, 159, 200, "정복", "-"); $gencount++;
145, "여포",1229, 0, "낙양", 74,100, 29, 0, 156, 198, "패권", "돌격"); $gencount++;
50, "염우",1230, 0, "낙양", 58, 51, 18, 0, 209, 264, "출세", "-"); $gencount++;
40, "염유",1231, 0, "낙양", 59, 75, 51, 0, 168, 227, "출세", "-"); $gencount++;
18, "염포",1232, 0, "낙양", 33, 35, 77, 0, 163, 231, "유지", "-"); $gencount++;
40, "예형",1233, 0, "낙양", 77, 31, 95, 0, 173, 209, "은둔", "통찰"); $gencount++;
133, "오강",1234, 0, "낙양", 47, 37, 61, 0, 216, 275, "안전", "-"); $gencount++;
59, "오란",1235, 0, "낙양", 67, 75, 42, 0, 170, 218, "재간", "-"); $gencount++;
72, "오반",1236, 0, "낙양", 70, 66, 45, 0, 171, 234, "재간", "-"); $gencount++;
128, "오언",1237, 0, "낙양", 71, 60, 52, 0, 235, 297, "재간", "-"); $gencount++;
126, "오연",1238, 0, "낙양", 36, 70, 31, 0, 234, 280, "정복", "-"); $gencount++;
69, "오의",1239, 0, "낙양", 75, 72, 74, 0, 165, 237, "유지", "-"); $gencount++;
19, "오질",1240, 0, "낙양", 43, 37, 69, 0, 177, 230, "출세", "-"); $gencount++;
51, "올돌골",1241, 0, "낙양", 77, 92, 15, 0, 186, 225, "출세", "척사"); $gencount++;
52, "옹개",1242, 0, "낙양", 58, 67, 51, 0, 188, 225, "안전", "-"); $gencount++;
20, "왕경",1243, 0, "낙양", 55, 47, 65, 0, 206, 260, "재간", "-"); $gencount++;
97, "왕광",1244, 0, "낙양", 72, 67, 54, 0, 150, 190, "유지", "-"); $gencount++;
30, "왕기1",1245, 0, "낙양", 76, 62, 70, 0, 190, 261, "유지", "-"); $gencount++;
34, "왕랑",1246, 0, "낙양", 49, 29, 51, 0, 162, 228, "할거", "-"); $gencount++;
57, "왕루",1247, 0, "낙양", 40, 28, 76, 0, 173, 211, "유지", "-"); $gencount++;
76, "왕보",1248, 0, "낙양", 47, 34, 75, 0, 171, 219, "대의", "-"); $gencount++;
86, "왕수",1249, 0, "낙양", 34, 34, 67, 0, 168, 218, "재간", "-"); $gencount++;
26, "왕쌍",1250, 0, "낙양", 58, 89, 15, 0, 195, 228, "정복", "보병"); $gencount++;
46, "왕위",1251, 0, "낙양", 59, 60, 68, 0, 163, 208, "안전", "-"); $gencount++;
92, "왕윤",1252, 0, "낙양", 16, 18, 77, 0, 137, 192, "왕좌", "-"); $gencount++;
40, "왕융",1253, 0, "낙양", 62, 41, 77, 0, 234, 305, "재간", "-"); $gencount++;
32, "왕준",1254, 0, "낙양", 81, 83, 76, 0, 206, 285, "대의", "-"); $gencount++;
30, "왕찬",1255, 0, "낙양", 28, 28, 78, 0, 177, 217, "안전", "-"); $gencount++;
33, "왕창",1256, 0, "낙양", 74, 57, 52, 0, 188, 259, "정복", "-"); $gencount++;
69, "왕평",1257, 0, "낙양", 77, 76, 71, 0, 192, 248, "재간", "-"); $gencount++;
71, "왕항",1258, 0, "낙양", 51, 43, 60, 0, 184, 254, "대의", "-"); $gencount++;
33, "왕혼",1259, 0, "낙양", 69, 32, 59, 0, 223, 297, "정복", "-"); $gencount++;
71, "요립",1260, 0, "낙양", 65, 41, 84, 0, 181, 250, "출세", "-"); $gencount++;
74, "요화",1261, 0, "낙양", 67, 58, 60, 0, 170, 264, "의협", "-"); $gencount++;
22, "우금1",1262, 0, "낙양", 80, 74, 71, 0, 159, 221, "정복", "-"); $gencount++;
27, "우금2",1263, 0, "낙양", 63, 77, 37, 0, 173, 226, "대의", "-"); $gencount++;
122, "우번",1264, 0, "낙양", 23, 42, 73, 0, 164, 233, "유지", "-"); $gencount++;
126, "우전",1265, 0, "낙양", 63, 55, 41, 0, 204, 258, "안전", "-"); $gencount++;
86, "원담",1266, 0, "낙양", 67, 59, 55, 0, 173, 205, "왕좌", "-"); $gencount++;
101, "원상",1267, 0, "낙양", 54, 72, 68, 0, 179, 207, "패권", "-"); $gencount++;
101, "원소",1268, 0, "낙양", 85, 67, 76, 0, 154, 202, "패권", "위압"); $gencount++;
140, "원술",1269, 0, "낙양", 77, 59, 71, 0, 155, 199, "패권", "축성"); $gencount++;
140, "원윤",1270, 0, "낙양", 41, 34, 60, 0, 163, 199, "패권", "-"); $gencount++;
101, "원희",1271, 0, "낙양", 69, 57, 72, 0, 176, 207, "할거", "-"); $gencount++;
131, "위소",1272, 0, "낙양", 39, 24, 82, 0, 204, 273, "재간", "-"); $gencount++;
147, "위속",1273, 0, "낙양", 57, 59, 41, 0, 156, 200, "안전", "-"); $gencount++;
81, "위연",1274, 0, "낙양", 78, 94, 62, 0, 175, 234, "패권", "보병"); $gencount++;
96, "위유",1275, 0, "낙양", 53, 69, 71, 0, 151, 193, "재간", "-"); $gencount++;
76, "유기",1276, 0, "낙양", 57, 19, 73, 0, 174, 209, "왕좌", "-"); $gencount++;
36, "유대",1277, 0, "낙양", 61, 57, 62, 0, 147, 202, "재간", "-"); $gencount++;
134, "유도",1278, 0, "낙양", 35, 33, 68, 0, 168, 214, "재간", "-"); $gencount++;
46, "유벽",1279, 0, "낙양", 63, 71, 23, 0, 168, 210, "출세", "-"); $gencount++;
75, "유봉",1280, 0, "낙양", 60, 65, 62, 0, 188, 220, "출세", "-"); $gencount++;
75, "유비",1281, 0, "낙양", 85, 75, 70, 0, 161, 223, "왕좌", "인덕"); $gencount++;
75, "유선1",1282, 0, "낙양", 24, 17, 21, 0, 207, 271, "대의", "-"); $gencount++;
55, "유순",1283, 0, "낙양", 67, 61, 54, 0, 184, 239, "출세", "-"); $gencount++;
75, "유심",1284, 0, "낙양", 63, 46, 70, 0, 238, 263, "왕좌", "-"); $gencount++;
129, "유약",1285, 0, "낙양", 67, 63, 61, 0, 206, 260, "유지", "-"); $gencount++;
55, "유언",1286, 0, "낙양", 60, 40, 74, 0, 132, 194, "할거", "-"); $gencount++;
27, "유엽",1287, 0, "낙양", 40, 29, 79, 0, 176, 235, "유지", "-"); $gencount++;
11, "유요",1288, 0, "낙양", 23, 22, 48, 0, 156, 195, "안전", "발명"); $gencount++;
96, "유우",1289, 0, "낙양", 68, 34, 72, 0, 145, 193, "왕좌", "-"); $gencount++;
55, "유장",1290, 0, "낙양", 38, 31, 63, 0, 162, 219, "할거", "수비"); $gencount++;
45, "유종",1291, 0, "낙양", 22, 26, 61, 0, 191, 208, "할거", "-"); $gencount++;
56, "유파",1292, 0, "낙양", 47, 32, 70, 0, 186, 222, "대의", "-"); $gencount++;
45, "유표1",1293, 0, "낙양", 71, 57, 71, 0, 142, 208, "할거", "-"); $gencount++;
27, "유표2",1294, 0, "낙양", 76, 55, 71, 0, 173, 229, "안전", "-"); $gencount++;
134, "유현",1295, 0, "낙양", 32, 56, 55, 0, 188, 252, "안전", "-"); $gencount++;
122, "육개",1296, 0, "낙양", 66, 30, 72, 0, 198, 269, "재간", "-"); $gencount++;
122, "육손",1297, 0, "낙양", 98, 68, 98, 0, 183, 245, "왕좌", "귀병"); $gencount++;
121, "육적",1298, 0, "낙양", 44, 29, 73, 0, 187, 219, "안전", "-"); $gencount++;
122, "육항",1299, 0, "낙양", 95, 69, 94, 0, 226, 274, "왕좌", "-"); $gencount++;
38, "윤대목",1300, 0, "낙양", 62, 49, 69, 0, 211, 270, "재간", "-"); $gencount++;
80, "윤묵",1301, 0, "낙양", 19, 28, 73, 0, 183, 239, "대의", "-"); $gencount++;
72, "윤상",1302, 0, "낙양", 30, 32, 42, 0, 194, 260, "대의", "-"); $gencount++;
136, "윤직",1303, 0, "낙양", 44, 58, 63, 0, 197, 237, "재간", "-"); $gencount++;
2, "이각",1304, 0, "낙양", 56, 77, 43, 0, 148, 198, "패권", "-"); $gencount++;
146, "이숙",1305, 0, "낙양", 27, 45, 67, 0, 156, 192, "재간", "-"); $gencount++;
71, "이엄",1306, 0, "낙양", 80, 84, 81, 0, 172, 234, "패권", "-"); $gencount++;
2, "이유",1307, 0, "낙양", 64, 22, 90, 0, 150, 192, "패권", "귀모"); $gencount++;
132, "이이",1308, 0, "낙양", 55, 75, 20, 0, 187, 222, "정복", "-"); $gencount++;
77, "이적",1309, 0, "낙양", 55, 27, 77, 0, 162, 226, "할거", "-"); $gencount++;
22, "이전",1310, 0, "낙양", 75, 68, 82, 0, 174, 216, "왕좌", "-"); $gencount++;
71, "이풍1",1311, 0, "낙양", 59, 56, 62, 0, 206, 260, "재간", "-"); $gencount++;
66, "이회",1312, 0, "낙양", 67, 50, 79, 0, 175, 231, "유지", "-"); $gencount++;
114, "잠혼",1313, 0, "낙양", 15, 16, 44, 0, 239, 280, "할거", "-"); $gencount++;
7, "장각",1314, 0, "낙양", 93, 25, 93, 0, 140, 185, "패권", "환술"); $gencount++;
34, "장간",1315, 0, "낙양", 19, 20, 70, 0, 175, 239, "재간", "-"); $gencount++;
7, "장개",1316, 0, "낙양", 48, 69, 19, 0, 155, 202, "안전", "-"); $gencount++;
122, "장굉",1317, 0, "낙양", 25, 21, 85, 0, 153, 212, "왕좌", "-"); $gencount++;
7, "장량",1318, 0, "낙양", 68, 81, 68, 0, 153, 185, "정복", "환술"); $gencount++;
15, "장로",1319, 0, "낙양", 76, 44, 80, 0, 163, 237, "유지", "축성"); $gencount++;
23, "장료",1320, 0, "낙양", 89, 93, 83, 0, 169, 222, "의협", "견고"); $gencount++;
7, "장보",1321, 0, "낙양", 78, 81, 76, 0, 148, 185, "패권", "환술"); $gencount++;
76, "장비",1322, 0, "낙양", 79, 99, 48, 0, 167, 221, "의협", "무쌍"); $gencount++;
62, "장서",1323, 0, "낙양", 44, 48, 35, 0, 225, 290, "출세", "-"); $gencount++;
120, "장소1",1324, 0, "낙양", 42, 24, 91, 0, 156, 236, "안전", "-"); $gencount++;
78, "장소2",1325, 0, "낙양", 51, 44, 71, 0, 202, 264, "재간", "-"); $gencount++;
72, "장송",1326, 0, "낙양", 49, 28, 93, 0, 170, 212, "할거", "통찰"); $gencount++;
148, "장수",1327, 0, "낙양", 71, 72, 69, 0, 154, 207, "할거", "-"); $gencount++;
145, "장양1",1328, 0, "낙양", 62, 66, 65, 0, 150, 199, "출세", "-"); $gencount++;
8, "장연",1329, 0, "낙양", 78, 66, 47, 0, 153, 210, "안전", "-"); $gencount++;
11, "장영",1330, 0, "낙양", 55, 65, 40, 0, 154, 195, "재간", "-"); $gencount++;
118, "장온",1331, 0, "낙양", 21, 30, 69, 0, 193, 231, "할거", "-"); $gencount++;
78, "장완",1332, 0, "낙양", 70, 55, 86, 0, 188, 246, "할거", "상재"); $gencount++;
15, "장위",1333, 0, "낙양", 65, 70, 29, 0, 172, 215, "대의", "-"); $gencount++;
36, "장윤",1334, 0, "낙양", 67, 59, 60, 0, 163, 208, "정복", "-"); $gencount++;
104, "장의거",1335, 0, "낙양", 68, 59, 34, 0, 159, 205, "대의", "-"); $gencount++;
68, "장익",1336, 0, "낙양", 75, 68, 63, 0, 188, 264, "유지", "-"); $gencount++;
56, "장임",1337, 0, "낙양", 83, 82, 74, 0, 169, 214, "대의", "견고"); $gencount++;
148, "장제1",1338, 0, "낙양", 70, 65, 59, 0, 144, 196, "할거", "-"); $gencount++;
32, "장제2",1339, 0, "낙양", 30, 33, 84, 0, 188, 249, "유지", "-"); $gencount++;
126, "장제3",1340, 0, "낙양", 74, 49, 61, 0, 236, 280, "할거", "-"); $gencount++;
17, "장패",1341, 0, "낙양", 44, 78, 43, 0, 165, 231, "할거", "-"); $gencount++;
76, "장포1",1342, 0, "낙양", 69, 85, 49, 0, 198, 229, "재간", "징병"); $gencount++;
113, "장포2",1343, 0, "낙양", 63, 66, 51, 0, 225, 264, "유지", "-"); $gencount++;
27, "장합",1344, 0, "낙양", 83, 91, 63, 0, 167, 231, "출세", "궁병"); $gencount++;
23, "장호",1345, 0, "낙양", 56, 62, 54, 0, 195, 240, "정복", "-"); $gencount++;
31, "장화",1346, 0, "낙양", 49, 24, 86, 0, 232, 300, "유지", "-"); $gencount++;
48, "장횡",1347, 0, "낙양", 53, 67, 25, 0, 178, 211, "재간", "-"); $gencount++;
141, "장훈",1348, 0, "낙양", 67, 61, 60, 0, 156, 206, "안전", "-"); $gencount++;
120, "장휴",1349, 0, "낙양", 42, 35, 70, 0, 204, 244, "재간", "-"); $gencount++;
126, "장흠",1350, 0, "낙양", 64, 66, 67, 0, 168, 219, "대의", "저격"); $gencount++;
96, "저수",1351, 0, "낙양", 82, 54, 88, 0, 156, 201, "할거", "반계"); $gencount++;
130, "전단",1352, 0, "낙양", 64, 73, 61, 0, 204, 261, "출세", "-"); $gencount++;
42, "전속",1353, 0, "낙양", 66, 57, 49, 0, 218, 272, "안전", "-"); $gencount++;
26, "전위1",1354, 0, "낙양", 61, 96, 34, 0, 160, 197, "의협", "필살"); $gencount++;
130, "전위2",1355, 0, "낙양", 74, 69, 62, 0, 230, 274, "출세", "-"); $gencount++;
128, "전종",1356, 0, "낙양", 79, 77, 74, 0, 183, 249, "패권", "-"); $gencount++;
42, "전주",1357, 0, "낙양", 69, 67, 51, 0, 169, 214, "의협", "-"); $gencount++;
96, "전풍",1358, 0, "낙양", 81, 41, 96, 0, 162, 200, "왕좌", "-"); $gencount++;
24, "정무",1359, 0, "낙양", 54, 38, 74, 0, 201, 265, "출세", "-"); $gencount++;
119, "정병",1360, 0, "낙양", 22, 25, 67, 0, 172, 226, "유지", "-"); $gencount++;
126, "정보",1361, 0, "낙양", 81, 64, 76, 0, 151, 216, "패권", "-"); $gencount++;
123, "정봉1",1362, 0, "낙양", 70, 77, 64, 0, 190, 271, "패권", "-"); $gencount++;
24, "정욱",1363, 0, "낙양", 80, 39, 90, 0, 141, 220, "패권", "신중"); $gencount++;
88, "정원",1364, 0, "낙양", 64, 77, 58, 0, 137, 190, "왕좌", "기병"); $gencount++;
7, "정원지",1365, 0, "낙양", 41, 74, 38, 0, 145, 185, "출세", "-"); $gencount++;
69, "정은",1366, 0, "낙양", 53, 62, 26, 0, 169, 211, "재간", "-"); $gencount++;
121, "제갈각",1367, 0, "낙양", 61, 53, 92, 0, 203, 253, "왕좌", "-"); $gencount++;
76, "제갈균",1368, 0, "낙양", 59, 45, 74, 0, 185, 252, "안전", "상재"); $gencount++;
121, "제갈근",1369, 0, "낙양", 60, 42, 88, 0, 174, 241, "왕좌", "경작"); $gencount++;
76, "제갈량",1370, 0, "낙양", 97, 55,100, 0, 181, 234, "왕좌", "집중"); $gencount++;
76, "제갈상",1371, 0, "낙양", 52, 75, 71, 0, 246, 263, "대의", "-"); $gencount++;
135, "제갈정",1372, 0, "낙양", 56, 57, 54, 0, 241, 300, "안전", "-"); $gencount++;
76, "제갈첨",1373, 0, "낙양", 73, 52, 76, 0, 227, 263, "대의", "-"); $gencount++;
135, "제갈탄",1374, 0, "낙양", 79, 79, 73, 0, 206, 258, "패권", "-"); $gencount++;
76, "조광",1375, 0, "낙양", 65, 67, 54, 0, 210, 263, "재간", "-"); $gencount++;
74, "조루",1376, 0, "낙양", 49, 37, 60, 0, 183, 219, "대의", "-"); $gencount++;
24, "조모",1377, 0, "낙양", 53, 32, 30, 0, 241, 260, "할거", "-"); $gencount++;
127, "조무",1378, 0, "낙양", 71, 68, 71, 0, 155, 191, "의협", "-"); $gencount++;
26, "조방",1379, 0, "낙양", 50, 20, 31, 0, 232, 274, "정복", "-"); $gencount++;
83, "조범",1380, 0, "낙양", 58, 40, 63, 0, 168, 218, "유지", "-"); $gencount++;
26, "조비",1381, 0, "낙양", 72, 69, 75, 0, 187, 226, "패권", "징병"); $gencount++;
19, "조상",1382, 0, "낙양", 68, 62, 31, 0, 207, 249, "패권", "-"); $gencount++;
147, "조성",1383, 0, "낙양", 44, 69, 51, 0, 163, 198, "안전", "-"); $gencount++;
26, "조순",1384, 0, "낙양", 66, 57, 72, 0, 170, 210, "정복", "-"); $gencount++;
25, "조식",1385, 0, "낙양", 19, 19, 90, 0, 192, 232, "왕좌", "귀모"); $gencount++;
25, "조앙",1386, 0, "낙양", 44, 65, 62, 0, 175, 197, "왕좌", "-"); $gencount++;
25, "조예",1387, 0, "낙양", 57, 55, 82, 0, 205, 239, "정복", "-"); $gencount++;
26, "조우",1388, 0, "낙양", 67, 55, 67, 0, 199, 260, "대의", "-"); $gencount++;
76, "조운",1389, 0, "낙양", 95, 98, 87, 0, 168, 229, "왕좌", "무쌍"); $gencount++;
25, "조웅",1390, 0, "낙양", 59, 27, 44, 0, 194, 220, "안전", "-"); $gencount++;
26, "조인",1391, 0, "낙양", 74, 79, 62, 0, 168, 223, "패권", "보병"); $gencount++;
25, "조조",1392, 0, "낙양",100, 80, 95, 0, 155, 220, "패권", "반계"); $gencount++;
26, "조진",1393, 0, "낙양", 82, 67, 65, 0, 185, 231, "정복", "-"); $gencount++;
25, "조창",1394, 0, "낙양", 75, 88, 37, 0, 190, 223, "정복", "돌격"); $gencount++;
76, "조통",1395, 0, "낙양", 65, 64, 55, 0, 209, 260, "재간", "-"); $gencount++;
84, "조표",1396, 0, "낙양", 34, 70, 16, 0, 151, 196, "안전", "-"); $gencount++;
7, "조홍1",1397, 0, "낙양", 52, 66, 42, 0, 156, 185, "유지", "-"); $gencount++;
24, "조홍2",1398, 0, "낙양", 72, 69, 44, 0, 169, 232, "패권", "-"); $gencount++;
26, "조환",1399, 0, "낙양", 34, 24, 42, 0, 246, 302, "정복", "-"); $gencount++;
19, "조훈",1400, 0, "낙양", 67, 63, 30, 0, 212, 249, "출세", "-"); $gencount++;
26, "조휴",1401, 0, "낙양", 75, 71, 70, 0, 174, 228, "패권", "-"); $gencount++;
19, "조희",1402, 0, "낙양", 64, 57, 71, 0, 210, 249, "대의", "-"); $gencount++;
22, "종요",1403, 0, "낙양", 16, 20, 74, 0, 151, 230, "유지", "-"); $gencount++;
20, "종회",1404, 0, "낙양", 84, 58, 93, 0, 225, 264, "패권", "-"); $gencount++;
128, "주거",1405, 0, "낙양", 73, 71, 72, 0, 190, 246, "유지", "-"); $gencount++;
118, "주방",1406, 0, "낙양", 56, 36, 76, 0, 200, 240, "할거", "-"); $gencount++;
126, "주연",1407, 0, "낙양", 73, 72, 51, 0, 182, 249, "할거", "-"); $gencount++;
126, "주유",1408, 0, "낙양", 97, 73, 97, 0, 175, 210, "패권", "신산"); $gencount++;
128, "주이",1409, 0, "낙양", 61, 55, 61, 0, 201, 257, "안전", "-"); $gencount++;
88, "주준",1410, 0, "낙양", 82, 75, 65, 0, 149, 195, "왕좌", "-"); $gencount++;
32, "주지",1411, 0, "낙양", 52, 77, 47, 0, 233, 295, "안전", "-"); $gencount++;
76, "주창",1412, 0, "낙양", 42, 79, 30, 0, 164, 219, "의협", "궁병"); $gencount++;
126, "주치",1413, 0, "낙양", 58, 55, 56, 0, 156, 224, "안전", "-"); $gencount++;
41, "주태1",1414, 0, "낙양", 62, 55, 61, 0, 207, 261, "안전", "-"); $gencount++;
126, "주태2",1415, 0, "낙양", 74, 88, 60, 0, 171, 225, "정복", "필살"); $gencount++;
128, "주환",1416, 0, "낙양", 84, 86, 74, 0, 177, 238, "정복", "-"); $gencount++;
29, "진건",1417, 0, "낙양", 62, 70, 62, 0, 214, 292, "정복", "-"); $gencount++;
29, "진교",1418, 0, "낙양", 21, 25, 67, 0, 175, 237, "유지", "-"); $gencount++;
28, "진군",1419, 0, "낙양", 60, 38, 87, 0, 167, 235, "대의", "-"); $gencount++;
143, "진궁",1420, 0, "낙양", 77, 51, 90, 0, 154, 198, "할거", "신중"); $gencount++;
79, "진규",1421, 0, "낙양", 22, 19, 71, 0, 132, 206, "할거", "-"); $gencount++;
72, "진도",1422, 0, "낙양", 71, 85, 70, 0, 171, 237, "대의", "-"); $gencount++;
79, "진등",1423, 0, "낙양", 64, 62, 71, 0, 169, 207, "할거", "-"); $gencount++;
37, "진림",1424, 0, "낙양", 50, 28, 82, 0, 160, 217, "재간", "-"); $gencount++;
124, "진무",1425, 0, "낙양", 62, 74, 59, 0, 176, 215, "재간", "-"); $gencount++;
66, "진복",1426, 0, "낙양", 36, 27, 76, 0, 160, 226, "재간", "-"); $gencount++;
50, "진수",1427, 0, "낙양", 25, 29, 83, 0, 233, 297, "대의", "-"); $gencount++;
81, "진식",1428, 0, "낙양", 47, 68, 52, 0, 191, 230, "출세", "-"); $gencount++;
79, "진진",1429, 0, "낙양", 58, 38, 64, 0, 170, 235, "재간", "-"); $gencount++;
28, "진태",1430, 0, "낙양", 79, 76, 70, 0, 210, 260, "대의", "-"); $gencount++;
11, "진횡",1431, 0, "낙양", 38, 58, 47, 0, 161, 195, "출세", "-"); $gencount++;
21, "차주",1432, 0, "낙양", 55, 66, 62, 0, 164, 199, "안전", "-"); $gencount++;
11, "착융",1433, 0, "낙양", 62, 59, 21, 0, 161, 194, "출세", "-"); $gencount++;
36, "채모",1434, 0, "낙양", 79, 69, 68, 0, 155, 208, "정복", "궁병"); $gencount++;
36, "채중",1435, 0, "낙양", 58, 43, 55, 0, 168, 208, "출세", "-"); $gencount++;
36, "채화",1436, 0, "낙양", 56, 47, 49, 0, 166, 208, "안전", "-"); $gencount++;
66, "초주",1437, 0, "낙양", 22, 26, 81, 0, 201, 270, "대의", "-"); $gencount++;
20, "최염",1438, 0, "낙양", 43, 54, 67, 0, 162, 216, "대의", "-"); $gencount++;
60, "축융",1439, 0, "낙양", 59, 87, 25, 0, 193, 246, "정복", "척사"); $gencount++;
60, "타사대왕",1440, 0, "낙양", 61, 72, 67, 0, 186, 225, "출세", "척사"); $gencount++;
124, "태사자",1441, 0, "낙양", 71, 97, 65, 0, 166, 209, "대의", "무쌍"); $gencount++;
124, "태사향",1442, 0, "낙양", 51, 69, 50, 0, 189, 246, "재간", "-"); $gencount++;
12, "포륭",1443, 0, "낙양", 53, 74, 20, 0, 174, 208, "안전", "-"); $gencount++;
74, "풍습",1444, 0, "낙양", 36, 64, 44, 0, 182, 222, "재간", "-"); $gencount++;
7, "하의",1445, 0, "낙양", 49, 68, 25, 0, 161, 195, "출세", "-"); $gencount++;
121, "하제",1446, 0, "낙양", 74, 73, 64, 0, 171, 227, "재간", "-"); $gencount++;
90, "하진",1447, 0, "낙양", 49, 69, 37, 0, 135, 189, "왕좌", "-"); $gencount++;
24, "하후덕",1448, 0, "낙양", 67, 64, 39, 0, 178, 218, "출세", "-"); $gencount++;
26, "하후돈",1449, 0, "낙양", 88, 92, 71, 0, 156, 220, "의협", "돌격"); $gencount++;
19, "하후무",1450, 0, "낙양", 38, 33, 37, 0, 201, 259, "안전", "-"); $gencount++;
24, "하후상",1451, 0, "낙양", 67, 62, 71, 0, 181, 225, "출세", "-"); $gencount++;
26, "하후연",1452, 0, "낙양", 79, 90, 58, 0, 162, 219, "패권", "궁병"); $gencount++;
26, "하후위",1453, 0, "낙양", 73, 76, 71, 0, 204, 254, "정복", "-"); $gencount++;
26, "하후은",1454, 0, "낙양", 49, 51, 39, 0, 180, 208, "안전", "-"); $gencount++;
23, "하후패",1455, 0, "낙양", 78, 88, 69, 0, 202, 262, "대의", "-"); $gencount++;
20, "하후현",1456, 0, "낙양", 57, 23, 75, 0, 208, 254, "유지", "-"); $gencount++;
26, "하후혜",1457, 0, "낙양", 76, 66, 78, 0, 206, 242, "정복", "-"); $gencount++;
26, "하후화",1458, 0, "낙양", 77, 61, 80, 0, 207, 265, "정복", "-"); $gencount++;
22, "학소",1459, 0, "낙양", 89, 81, 86, 0, 185, 229, "대의", "견고"); $gencount++;
126, "한당",1460, 0, "낙양", 68, 67, 64, 0, 156, 225, "할거", "-"); $gencount++;
93, "한복",1461, 0, "낙양", 66, 59, 42, 0, 149, 191, "안전", "-"); $gencount++;
8, "한섬",1462, 0, "낙양", 39, 62, 35, 0, 159, 196, "출세", "-"); $gencount++;
48, "한수",1463, 0, "낙양", 66, 76, 77, 0, 142, 215, "대의", "기병"); $gencount++;
40, "한숭",1464, 0, "낙양", 21, 25, 70, 0, 154, 210, "재간", "-"); $gencount++;
7, "한충",1465, 0, "낙양", 41, 66, 29, 0, 151, 185, "안전", "-"); $gencount++;
9, "한현",1466, 0, "낙양", 43, 61, 20, 0, 163, 208, "유지", "-"); $gencount++;
27, "한호",1467, 0, "낙양", 60, 73, 45, 0, 164, 218, "유지", "-"); $gencount++;
79, "향랑",1468, 0, "낙양", 51, 21, 77, 0, 167, 247, "대의", "-"); $gencount++;
79, "향총",1469, 0, "낙양", 76, 42, 73, 0, 195, 240, "왕좌", "-"); $gencount++;
139, "허공",1470, 0, "낙양", 65, 63, 59, 0, 155, 200, "유지", "-"); $gencount++;
21, "허유",1471, 0, "낙양", 47, 47, 57, 0, 155, 204, "재간", "-"); $gencount++;
23, "허의",1472, 0, "낙양", 31, 74, 47, 0, 213, 263, "출세", "-"); $gencount++;
26, "허저",1473, 0, "낙양", 57, 98, 27, 0, 169, 226, "정복", "무쌍"); $gencount++;
87, "허정",1474, 0, "낙양", 18, 29, 74, 0, 152, 222, "재간", "-"); $gencount++;
12, "형도영",1475, 0, "낙양", 49, 78, 23, 0, 174, 208, "출세", "-"); $gencount++;
148, "호거아",1476, 0, "낙양", 35, 76, 61, 0, 164, 206, "안전", "-"); $gencount++;
76, "호반",1477, 0, "낙양", 61, 58, 46, 0, 179, 233, "재간", "-"); $gencount++;
20, "호분",1478, 0, "낙양", 71, 60, 61, 0, 222, 288, "할거", "-"); $gencount++;
27, "호주천",1479, 0, "낙양", 77, 75, 65, 0, 169, 230, "정복", "-"); $gencount++;
20, "호준",1480, 0, "낙양", 67, 60, 46, 0, 200, 256, "재간", "-"); $gencount++;
2, "화웅",1481, 0, "낙양", 68, 88, 24, 0, 155, 191, "출세", "돌격"); $gencount++;
131, "화핵",1482, 0, "낙양", 37, 27, 75, 0, 217, 278, "안전", "-"); $gencount++;
10, "화흠",1483, 0, "낙양", 18, 43, 75, 0, 157, 231, "출세", "-"); $gencount++;
21, "환범",1484, 0, "낙양", 20, 25, 81, 0, 199, 249, "유지", "-"); $gencount++;
127, "황개",1485, 0, "낙양", 78, 85, 69, 0, 154, 218, "왕좌", "징병"); $gencount++;
56, "황권",1486, 0, "낙양", 76, 46, 77, 0, 167, 240, "대의", "-"); $gencount++;
41, "황란",1487, 0, "낙양", 29, 70, 25, 0, 200, 264, "재간", "-"); $gencount++;
88, "황보숭",1488, 0, "낙양", 83, 63, 73, 0, 132, 195, "왕좌", "-"); $gencount++;
72, "황충",1489, 0, "낙양", 84, 94, 67, 0, 148, 222, "왕좌", "궁병"); $gencount++;
50, "황호",1490, 0, "낙양", 15, 17, 48, 0, 226, 263, "안전", "-"); $gencount++;
147, "후성",1491, 0, "낙양", 56, 62, 33, 0, 158, 199, "정복", "-"); $gencount++;
123, "가화",1492, 0, "낙양", 50, 66, 40, 0, 176, 224, "-", "-"); $gencount++;
999, "건석",1493, 0, "낙양", 21, 12, 61, 0, 155, 189, "-", "-"); $gencount++;
999, "견씨",1494, 0, "낙양", 35, 24, 58, 0, 182, 221, "-", "-"); $gencount++;
40, "견홍",1495, 0, "낙양", 76, 72, 66, 0, 224, 272, "-", "-"); $gencount++;
120, "고담",1496, 0, "낙양", 33, 21, 69, 0, 203, 244, "-", "-"); $gencount++;
101, "고유",1497, 0, "낙양", 56, 44, 73, 0, 174, 263, "-", "-"); $gencount++;
132, "곽마",1498, 0, "낙양", 68, 71, 49, 0, 239, 280, "-", "-"); $gencount++;
39, "관구수",1499, 0, "낙양", 58, 63, 35, 0, 206, 265, "-", "-"); $gencount++;
39, "관구전",1500, 0, "낙양", 63, 58, 68, 0, 224, 255, "-", "-"); $gencount++;
999, "관로",1501, 0, "낙양", 62, 21, 75, 0, 191, 256, "-", "-"); $gencount++;
65, "관정",1502, 0, "낙양", 35, 50, 73, 0, 158, 199, "-", "-"); $gencount++;
137, "교수",1503, 0, "낙양", 67, 69, 39, 0, 143, 195, "-", "-"); $gencount++;
33, "구건",1504, 0, "낙양", 43, 56, 69, 0, 239, 272, "-", "-"); $gencount++;
41, "구본",1505, 0, "낙양", 52, 41, 70, 0, 232, 269, "-", "-"); $gencount++;
12, "구성",1506, 0, "낙양", 56, 71, 31, 0, 157, 187, "-", "-"); $gencount++;
21, "국연",1507, 0, "낙양", 52, 21, 71, 0, 160, 219, "-", "-"); $gencount++;
99, "국의",1508, 0, "낙양", 83, 79, 50, 0, 146, 191, "-", "-"); $gencount++;
34, "금의",1509, 0, "낙양", 18, 40, 63, 0, 177, 218, "-", "-"); $gencount++;
76, "나헌",1510, 0, "낙양", 86, 67, 75, 0, 218, 270, "-", "-"); $gencount++;
999, "남두",1511, 0, "낙양", 35, 25, 54, 0, 130, 200, "-", "-"); $gencount++;
54, "냉포",1512, 0, "낙양", 70, 82, 69, 0, 176, 214, "-", "-"); $gencount++;
124, "노숙2",1513, 0, "낙양", 70, 55, 76, 0, 208, 274, "-", "-"); $gencount++;
42, "누규",1514, 0, "낙양", 54, 19, 88, 0, 143, 212, "-", "-"); $gencount++;
6, "누반",1515, 0, "낙양", 65, 76, 39, 0, 178, 207, "-", "-"); $gencount++;
130, "누현",1516, 0, "낙양", 23, 20, 68, 0, 223, 275, "-", "-"); $gencount++;
40, "당균",1517, 0, "낙양", 33, 19, 81, 0, 229, 264, "-", "-"); $gencount++;
32, "당빈",1518, 0, "낙양", 70, 74, 62, 0, 235, 294, "-", "-"); $gencount++;
999, "대교",1519, 0, "낙양", 42, 10, 54, 0, 177, 235, "-", "-"); $gencount++;
28, "대릉",1520, 0, "낙양", 64, 75, 45, 0, 199, 258, "-", "-"); $gencount++;
129, "동조",1521, 0, "낙양", 16, 15, 51, 0, 221, 281, "-", "-"); $gencount++;
114, "등수",1522, 0, "낙양", 35, 20, 44, 0, 228, 288, "-", "-"); $gencount++;
50, "마막",1523, 0, "낙양", 22, 17, 5, 0, 221, 265, "-", "-"); $gencount++;
116, "만욱",1524, 0, "낙양", 20, 18, 66, 0, 240, 272, "-", "-"); $gencount++;
120, "맹종",1525, 0, "낙양", 48, 48, 67, 0, 216, 271, "-", "-"); $gencount++;
38, "문호",1526, 0, "낙양", 65, 74, 45, 0, 227, 279, "-", "-"); $gencount++;
999, "미씨",1527, 0, "낙양", 59, 15, 68, 0, 176, 208, "-", "-"); $gencount++;
39, "반림",1528, 0, "낙양", 66, 79, 8, 0, 168, 225, "-", "-"); $gencount++;
129, "반장",1529, 0, "낙양", 77, 78, 69, 0, 177, 222, "-", "-"); $gencount++;
94, "방열",1530, 0, "낙양", 58, 82, 28, 0, 153, 190, "-", "-"); $gencount++;
55, "방희",1531, 0, "낙양", 59, 38, 69, 0, 153, 218, "-", "-"); $gencount++;
30, "배수",1532, 0, "낙양", 10, 11, 77, 0, 223, 271, "-", "-"); $gencount++;
8, "번능",1533, 0, "낙양", 70, 61, 47, 0, 158, 194, "-", "-"); $gencount++;
999, "번씨",1534, 0, "낙양", 32, 17, 45, 0, 176, 220, "-", "-"); $gencount++;
49, "보도근",1535, 0, "낙양", 64, 73, 50, 0, 170, 233, "-", "-"); $gencount++;
129, "보천",1536, 0, "낙양", 68, 60, 72, 0, 222, 272, "-", "-"); $gencount++;
121, "보협",1537, 0, "낙양", 73, 53, 75, 0, 216, 264, "-", "-"); $gencount++;
28, "부하",1538, 0, "낙양", 44, 36, 85, 0, 209, 255, "-", "-"); $gencount++;
26, "비요",1539, 0, "낙양", 70, 65, 73, 0, 192, 228, "-", "-"); $gencount++;
31, "사마주",1540, 0, "낙양", 63, 53, 62, 0, 227, 283, "-", "-"); $gencount++;
41, "사찬",1541, 0, "낙양", 61, 71, 54, 0, 215, 264, "-", "-"); $gencount++;
128, "설후",1542, 0, "낙양", 16, 14, 71, 0, 221, 271, "-", "-"); $gencount++;
36, "성공영",1543, 0, "낙양", 73, 58, 80, 0, 172, 220, "-", "-"); $gencount++;
126, "성만",1544, 0, "낙양", 61, 69, 66, 0, 225, 276, "-", "-"); $gencount++;
999, "소교",1545, 0, "낙양", 57, 23, 66, 0, 178, 218, "-", "-"); $gencount++;
46, "소유",1546, 0, "낙양", 51, 61, 48, 0, 164, 210, "-", "-"); $gencount++;
31, "소제2",1547, 0, "낙양", 22, 16, 78, 0, 224, 268, "-", "-"); $gencount++;
126, "손교",1548, 0, "낙양", 77, 60, 69, 0, 181, 219, "-", "-"); $gencount++;
116, "손기",1549, 0, "낙양", 62, 65, 52, 0, 227, 276, "-", "-"); $gencount++;
999, "손상향",1550, 0, "낙양", 72, 62, 42, 0, 193, 244, "-", "-"); $gencount++;
125, "손익",1551, 0, "낙양", 69, 75, 26, 0, 184, 204, "-", "-"); $gencount++;
125, "손진",1552, 0, "낙양", 64, 71, 48, 0, 234, 280, "-", "-"); $gencount++;
123, "송겸",1553, 0, "낙양", 61, 48, 44, 0, 175, 215, "-", "-"); $gencount++;
85, "순심",1554, 0, "낙양", 20, 21, 79, 0, 164, 208, "-", "-"); $gencount++;
31, "순욱2",1555, 0, "낙양", 10, 16, 77, 0, 225, 289, "-", "-"); $gencount++;
31, "순의",1556, 0, "낙양", 16, 11, 73, 0, 207, 281, "-", "-"); $gencount++;
129, "시삭",1557, 0, "낙양", 36, 66, 44, 0, 226, 268, "-", "-"); $gencount++;
29, "신창",1558, 0, "낙양", 51, 29, 46, 0, 210, 272, "-", "-"); $gencount++;
999, "악신",1559, 0, "낙양", 53, 12, 46, 0, 175, 228, "-", "-"); $gencount++;
138, "악취",1560, 0, "낙양", 56, 68, 58, 0, 157, 195, "-", "-"); $gencount++;
138, "양강",1561, 0, "낙양", 62, 70, 42, 0, 160, 199, "-", "-"); $gencount++;
21, "양부",1562, 0, "낙양", 68, 55, 85, 0, 178, 239, "-", "-"); $gencount++;
72, "양서",1563, 0, "낙양", 56, 62, 66, 0, 198, 260, "-", "-"); $gencount++;
34, "양습",1564, 0, "낙양", 67, 49, 73, 0, 168, 230, "-", "-"); $gencount++;
16, "양앙",1565, 0, "낙양", 65, 70, 39, 0, 172, 215, "-", "-"); $gencount++;
17, "양임",1566, 0, "낙양", 71, 78, 56, 0, 170, 215, "-", "-"); $gencount++;
32, "양제",1567, 0, "낙양", 69, 63, 71, 0, 226, 291, "-", "-"); $gencount++;
33, "양조2",1568, 0, "낙양", 65, 61, 67, 0, 223, 286, "-", "-"); $gencount++;
48, "양추2",1569, 0, "낙양", 66, 67, 61, 0, 172, 238, "-", "-"); $gencount++;
140, "양홍",1570, 0, "낙양", 19, 17, 76, 0, 152, 199, "-", "-"); $gencount++;
31, "양혼",1571, 0, "낙양", 60, 67, 63, 0, 220, 278, "-", "-"); $gencount++;
123, "여거",1572, 0, "낙양", 71, 58, 69, 0, 196, 256, "-", "-"); $gencount++;
130, "여대",1573, 0, "낙양", 83, 72, 70, 0, 161, 256, "-", "-"); $gencount++;
136, "염상",1574, 0, "낙양", 29, 27, 69, 0, 158, 199, "-", "-"); $gencount++;
36, "염행",1575, 0, "낙양", 70, 86, 38, 0, 159, 222, "-", "-"); $gencount++;
73, "영수",1576, 0, "낙양", 69, 70, 74, 0, 234, 264, "-", "-"); $gencount++;
39, "오거",1577, 0, "낙양", 49, 63, 32, 0, 151, 211, "-", "-"); $gencount++;
126, "오경",1578, 0, "낙양", 73, 60, 57, 0, 159, 203, "-", "-"); $gencount++;
999, "오국태",1579, 0, "낙양", 31, 11, 60, 0, 161, 222, "-", "-"); $gencount++;
126, "오찬",1580, 0, "낙양", 69, 41, 78, 0, 181, 245, "-", "-"); $gencount++;
23, "온회",1581, 0, "낙양", 42, 40, 78, 0, 178, 222, "-", "-"); $gencount++;
21, "왕기2",1582, 0, "낙양", 70, 66, 63, 0, 217, 281, "-", "-"); $gencount++;
32, "왕도",1583, 0, "낙양", 48, 44, 70, 0, 210, 269, "-", "-"); $gencount++;
123, "왕돈",1584, 0, "낙양", 60, 65, 41, 0, 198, 256, "-", "-"); $gencount++;
34, "왕릉",1585, 0, "낙양", 73, 60, 71, 0, 172, 251, "-", "-"); $gencount++;
63, "왕문",1586, 0, "낙양", 64, 67, 32, 0, 162, 205, "-", "-"); $gencount++;
32, "왕상",1587, 0, "낙양", 25, 19, 65, 0, 180, 268, "-", "-"); $gencount++;
34, "왕숙",1588, 0, "낙양", 35, 21, 80, 0, 195, 256, "-", "-"); $gencount++;
33, "왕업",1589, 0, "낙양", 32, 6, 46, 0, 220, 280, "-", "-"); $gencount++;
35, "왕충",1590, 0, "낙양", 42, 58, 21, 0, 152, 214, "-", "-"); $gencount++;
1, "우보",1591, 0, "낙양", 43, 63, 12, 0, 159, 192, "-", "-"); $gencount++;
122, "우사",1592, 0, "낙양", 70, 33, 79, 0, 217, 273, "-", "-"); $gencount++;
138, "원요",1593, 0, "낙양", 44, 42, 45, 0, 177, 206, "-", "-"); $gencount++;
95, "원유",1594, 0, "낙양", 57, 38, 73, 0, 150, 193, "-", "-"); $gencount++;
31, "위관",1595, 0, "낙양", 69, 45, 81, 0, 220, 291, "-", "-"); $gencount++;
129, "위막",1596, 0, "낙양", 58, 62, 60, 0, 221, 268, "-", "-"); $gencount++;
55, "유괴",1597, 0, "낙양", 75, 72, 66, 0, 165, 214, "-", "-"); $gencount++;
129, "유략",1598, 0, "낙양", 72, 68, 59, 0, 206, 260, "-", "-"); $gencount++;
45, "유반",1599, 0, "낙양", 74, 79, 48, 0, 168, 210, "-", "-"); $gencount++;
29, "유복",1600, 0, "낙양", 54, 50, 73, 0, 164, 208, "-", "-"); $gencount++;
78, "유선2",1601, 0, "낙양", 9, 21, 39, 0, 224, 264, "-", "-"); $gencount++;
139, "유섭",1602, 0, "낙양", 62, 79, 26, 0, 158, 190, "-", "-"); $gencount++;
28, "유소",1603, 0, "낙양", 66, 51, 73, 0, 195, 264, "-", "-"); $gencount++;
128, "유승",1604, 0, "낙양", 46, 69, 29, 0, 215, 258, "-", "-"); $gencount++;
129, "유찬",1605, 0, "낙양", 74, 75, 66, 0, 172, 255, "-", "-"); $gencount++;
129, "유평",1606, 0, "낙양", 65, 70, 67, 0, 218, 272, "-", "-"); $gencount++;
138, "유훈",1607, 0, "낙양", 51, 64, 50, 0, 163, 216, "-", "-"); $gencount++;
48, "이감",1608, 0, "낙양", 59, 67, 33, 0, 176, 211, "-", "-"); $gencount++;
19, "이승",1609, 0, "낙양", 13, 26, 32, 0, 201, 249, "-", "-"); $gencount++;
22, "이통",1610, 0, "낙양", 75, 84, 52, 0, 168, 211, "-", "-"); $gencount++;
138, "이풍2",1611, 0, "낙양", 72, 77, 50, 0, 158, 199, "-", "-"); $gencount++;
20, "이풍3",1612, 0, "낙양", 23, 25, 71, 0, 204, 254, "-", "-"); $gencount++;
29, "장구",1613, 0, "낙양", 69, 71, 47, 0, 201, 263, "-", "-"); $gencount++;
21, "장기",1614, 0, "낙양", 77, 35, 79, 0, 170, 223, "-", "-"); $gencount++;
74, "장남",1615, 0, "낙양", 71, 64, 38, 0, 187, 222, "-", "-"); $gencount++;
100, "장막",1616, 0, "낙양", 53, 52, 70, 0, 155, 195, "-", "-"); $gencount++;
7, "장만성",1617, 0, "낙양", 73, 83, 47, 0, 143, 184, "-", "-"); $gencount++;
135, "장반",1618, 0, "낙양", 56, 73, 66, 0, 227, 282, "-", "-"); $gencount++;
78, "장빈",1619, 0, "낙양", 30, 28, 67, 0, 216, 263, "-", "-"); $gencount++;
124, "장승",1620, 0, "낙양", 75, 68, 75, 0, 178, 244, "-", "-"); $gencount++;
999, "장양2",1621, 0, "낙양", 58, 50, 47, 0, 130, 184, "-", "-"); $gencount++;
68, "장억",1622, 0, "낙양", 82, 80, 54, 0, 190, 254, "-", "-"); $gencount++;
75, "장준",1623, 0, "낙양", 65, 67, 66, 0, 224, 263, "-", "-"); $gencount++;
20, "장집",1624, 0, "낙양", 31, 27, 74, 0, 196, 254, "-", "-"); $gencount++;
39, "장특",1625, 0, "낙양", 71, 53, 74, 0, 209, 265, "-", "-"); $gencount++;
96, "저곡",1626, 0, "낙양", 57, 53, 67, 0, 184, 204, "-", "-"); $gencount++;
128, "전기",1627, 0, "낙양", 51, 69, 55, 0, 231, 258, "-", "-"); $gencount++;
23, "전만",1628, 0, "낙양", 52, 74, 38, 0, 181, 235, "-", "-"); $gencount++;
128, "전상",1629, 0, "낙양", 5, 6, 11, 0, 208, 258, "-", "-"); $gencount++;
130, "전역",1630, 0, "낙양", 60, 62, 37, 0, 212, 265, "-", "-"); $gencount++;
75, "전예",1631, 0, "낙양", 80, 62, 83, 0, 171, 252, "-", "-"); $gencount++;
64, "전해",1632, 0, "낙양", 71, 63, 57, 0, 154, 199, "-", "-"); $gencount++;
123, "정봉2",1633, 0, "낙양", 67, 68, 52, 0, 198, 266, "-", "-"); $gencount++;
22, "정의",1634, 0, "낙양", 17, 3, 66, 0, 184, 220, "-", "-"); $gencount++;
81, "제갈교",1635, 0, "낙양", 55, 17, 77, 0, 204, 228, "-", "-"); $gencount++;
40, "제갈서",1636, 0, "낙양", 45, 43, 27, 0, 218, 286, "-", "-"); $gencount++;
25, "조충",1637, 0, "낙양", 14, 7, 80, 0, 196, 208, "-", "-"); $gencount++;
121, "종리목",1638, 0, "낙양", 84, 68, 75, 0, 214, 269, "-", "-"); $gencount++;
22, "종육",1639, 0, "낙양", 27, 11, 71, 0, 223, 263, "-", "-"); $gencount++;
122, "좌혁",1640, 0, "낙양", 60, 66, 51, 0, 232, 280, "-", "-"); $gencount++;
36, "주령",1641, 0, "낙양", 77, 70, 69, 0, 170, 236, "-", "-"); $gencount++;
115, "주앙",1642, 0, "낙양", 75, 64, 64, 0, 162, 195, "-", "-"); $gencount++;
52, "주포",1643, 0, "낙양", 59, 72, 12, 0, 191, 225, "-", "-"); $gencount++;
11, "주흔",1644, 0, "낙양", 67, 53, 77, 0, 159, 196, "-", "-"); $gencount++;
140, "진기",1645, 0, "낙양", 58, 67, 46, 0, 165, 198, "-", "-"); $gencount++;
142, "진란",1646, 0, "낙양", 65, 70, 43, 0, 157, 204, "-", "-"); $gencount++;
25, "진랑",1647, 0, "낙양", 57, 70, 38, 0, 192, 234, "-", "-"); $gencount++;
12, "진응",1648, 0, "낙양", 62, 69, 49, 0, 172, 208, "-", "-"); $gencount++;
124, "진표",1649, 0, "낙양", 62, 49, 74, 0, 204, 237, "-", "-"); $gencount++;
999, "채염",1650, 0, "낙양", 40, 22, 64, 0, 168, 237, "-", "-"); $gencount++;
999, "초선",1651, 0, "낙양", 66, 15, 72, 0, 176, 211, "-", "-"); $gencount++;
135, "초이",1652, 0, "낙양", 54, 65, 55, 0, 219, 266, "-", "-"); $gencount++;
65, "추단",1653, 0, "낙양", 63, 71, 36, 0, 148, 193, "-", "-"); $gencount++;
999, "추씨",1654, 0, "낙양", 36, 13, 54, 0, 165, 225, "-", "-"); $gencount++;
71, "추정",1655, 0, "낙양", 67, 65, 66, 0, 144, 193, "-", "-"); $gencount++;
145, "파재",1656, 0, "낙양", 69, 75, 52, 0, 145, 184, "-", "-"); $gencount++;
22, "포신",1657, 0, "낙양", 78, 60, 83, 0, 152, 192, "-", "-"); $gencount++;
114, "하식",1658, 0, "낙양", 18, 38, 29, 0, 230, 284, "-", "-"); $gencount++;
36, "하안",1659, 0, "낙양", 6, 27, 72, 0, 190, 249, "-", "-"); $gencount++;
999, "하후씨",1660, 0, "낙양", 29, 16, 47, 0, 186, 249, "-", "-"); $gencount++;
5, "학맹",1661, 0, "낙양", 57, 66, 41, 0, 156, 197, "-", "-"); $gencount++;
98, "한거자",1662, 0, "낙양", 53, 59, 30, 0, 158, 200, "-", "-"); $gencount++;
19, "한덕",1663, 0, "낙양", 62, 79, 24, 0, 171, 228, "-", "-"); $gencount++;
140, "한윤",1664, 0, "낙양", 27, 24, 68, 0, 155, 197, "-", "-"); $gencount++;
999, "허소",1665, 0, "낙양", 53, 27, 60, 0, 150, 195, "-", "-"); $gencount++;
30, "호열",1666, 0, "낙양", 77, 69, 76, 0, 225, 272, "-", "-"); $gencount++;
76, "호제",1667, 0, "낙양", 58, 42, 68, 0, 207, 264, "-", "-"); $gencount++;
149, "호진",1668, 0, "낙양", 65, 77, 13, 0, 146, 190, "-", "-"); $gencount++;
29, "호질",1669, 0, "낙양", 73, 50, 75, 0, 192, 250, "-", "-"); $gencount++;
7, "환계",1670, 0, "낙양", 12, 25, 67, 0, 156, 221, "-", "-"); $gencount++;
56, "황숭",1671, 0, "낙양", 68, 64, 74, 0, 208, 263, "-", "-"); $gencount++;
999, "황승언",1672, 0, "낙양", 68, 17, 81, 0, 165, 222, "-", "-"); $gencount++;
999, "황월영",1673, 0, "낙양", 58, 14, 75, 0, 186, 235, "-", "-"); $gencount++;
45, "황조",1674, 0, "낙양", 74, 65, 57, 0, 148, 208, "-", "-"); $gencount++;
48, "후선",1675, 0, "낙양", 56, 66, 35, 0, 175, 228, "-", "-"); $gencount++;
8, "휴고",1676, 0, "낙양", 61, 72, 40, 0, 151, 199, "-", "-"); $gencount++;
98, "휴원진",1677, 0, "낙양", 53, 63, 38, 0, 155, 200, "-", "-"); $gencount++;
22, "희지재",1678, 0, "낙양", 24, 5, 86, 0, 157, 194, "-", "-"); $gencount++;
+6 -6
View File
@@ -47,7 +47,7 @@ if ($me['newmsg'] == 1 || $me['newvote'] == 1) {
], 'owner=%i', $userID);
}
$plock = boolval($db->queryFirstField('SELECT plock FROM plock LIMIT 1'));
$plock = boolval($db->queryFirstField('SELECT plock FROM plock WHERE `type`="GAME" LIMIT 1'));
$con = checkLimit($me['con']);
if ($con >= 2) {
@@ -189,11 +189,11 @@ if (!$otherTextInfo) {
<div class="s-border-t col py-2 col-4 col-md-2">턴당 갱신횟수 : <?= $gameStor->conlimit ?>회</div>
<div class="s-border-t col py-2 col-8 col-md-4"><?= info(3) ?></div>
<div class="s-border-t py-2 col col-6 col-md-4">
<?php if ($isTournamentActive) : ?>
↑<span style='color:cyan'><?=(['전력전', '통솔전', '일기토', '설전',])[$gameStor->tnmt_type] ?? '' ?> <?= getTournament($gameStor->tournament) ?> <?= getTournamentTime() ?></span>↑
<?php else : ?>
<span style='color:magenta'>현재 토너먼트 경기 없음</span>
<?php endif; ?>
<?php if ($isTournamentActive) : ?>
↑<span style='color:cyan'><?= (['전력전', '통솔전', '일기토', '설전',])[$gameStor->tnmt_type] ?? '' ?> <?= getTournament($gameStor->tournament) ?> <?= getTournamentTime() ?></span>↑
<?php else : ?>
<span style='color:magenta'>현재 토너먼트 경기 없음</span>
<?php endif; ?>
</div>
<div class="s-border-t py-2 col col-6 col-md-2">
<div style="display:inline-block;"><?= $plock ? ("<span style='color:magenta;'>동작 시각: " . substr($gameStor->turntime, 5, 14) . "</span>") : ("<span style='color:cyan;'>동작 시각: " . substr($gameStor->turntime, 5, 14) . "</span>") ?></div>
-76
View File
@@ -1,76 +0,0 @@
<?php
namespace sammo;
include "lib.php";
include "func.php";
WebUtil::requireAJAX();
$betTarget = Util::getPost('target', 'int', -1);
$betGold = Util::getPost('amount', 'int', 0);
if($betTarget < 0 || $betTarget >= 16 || $betGold < 10 || $betGold > 1000){
Json::die([
'result'=>false,
'reason'=>'올바르지 않은 입력입니다'
]);
}
//로그인 검사
$session = Session::requireGameLogin()->setReadOnly();
$userID = Session::getUserID();
$generalID = $session->generalID;
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
increaseRefresh("베팅", 1);
$tournament = $gameStor->tournament;
if($tournament != 6) {
Json::die([
'result'=>false,
'reason'=>'베팅 기간이 아닙니다.'
]);
}
$myGold = $db->queryFirstField('SELECT gold FROM general WHERE no = %i', $generalID);
$bets = $db->queryFirstList('SELECT * FROM betting WHERE general_id = %i', $generalID);
$bets = array_splice($bets, -16);
$totalBet = array_sum($bets);
$oldBet = $bets[$betTarget];
$targetKey = "bet{$betTarget}";
if($myGold - $betGold < 500){
Json::die([
'result'=>false,
'reason'=>'여유 자금이 부족합니다.'
]);
}
if($betGold + $totalBet > 1000){
Json::die([
'result'=>false,
'reason'=>'베팅 허용 금액을 초과했습니다.'
]);
}
$db->update('betting', [
$targetKey=>$db->sqleval('%b + %i', $targetKey, $betGold),
], 'general_id = %i', $generalID);
$db->update('general', [
'gold'=>$db->sqleval('gold - %i', $betGold),
], 'no = %i', $generalID);
$db->update('rank_data', [
'value'=>$db->sqleval('value + %i', $betGold)
], 'general_id = %i AND type = "betgold"', $generalID);
$db->update('betting', [
$targetKey=>$db->sqleval('%b + %i', $targetKey, $betGold)
], 'general_id = 0');
Json::die([
'result'=>true,
'reason'=>'SUCCESS'
]);
-46
View File
@@ -1,46 +0,0 @@
<?php
namespace sammo;
include "lib.php";
include "func.php";
$year = Util::getReq('year', 'int');
$month = Util::getReq('month', 'int');
$serverID = Util::getReq('serverID', 'string', null);
$url = '/a_history.php';
if(!strpos($_SERVER['HTTP_REFERER'], $url)) {
Json::die([
'result'=>false,
'reason'=>'Invalid Referer'
]);
}
if($year === null || !$month) {
Json::die([
'result'=>false,
'reason'=>'year, month가 지정되지 않았습니다'
]);
}
if(!$serverID){
$serverID = UniqueConst::$serverID;
}
//로그인 검사
$session = Session::requireGameLogin([])->setReadOnly();
$db = DB::db();
$map = $db->queryFirstField('SELECT map FROM ng_history WHERE server_id=%s AND year=%i AND month=%i', $serverID, $year, $month);
if(!$map){
Json::die([
'result'=>false,
'reason'=>'해당하는 연월의 지도가 없습니다'
]);
}
Json::die($map, Json::PASS_THROUGH);
+1
View File
@@ -6,6 +6,7 @@ include "func.php";
WebUtil::requireAJAX();
/** @var int|null */
$pick = Util::getPost('pick', 'int');
if(!$pick){
+25 -20
View File
@@ -1,6 +1,9 @@
<?php
namespace sammo;
use Ds\Map;
use sammo\Enums\RankColumn;
include "lib.php";
include "func.php";
@@ -54,7 +57,7 @@ $defaultCheck = [
['year', 0]
],
'array'=>[
'attackerGeneral', 'attackerCity', 'attackerNation',
'attackerGeneral', 'attackerCity', 'attackerNation',
'defenderGenerals', 'defenderCity', 'defenderNation'
],
];
@@ -84,14 +87,14 @@ $rawDefenderNation = $query['defenderNation'];
$generalCheck = [
'required'=>[
'no', 'name', 'nation', 'turntime', 'personal', 'special2', 'crew', 'crewtype', 'atmos', 'train',
'intel', 'intel_exp', 'book', 'strength', 'strength_exp', 'weapon', 'injury', 'leadership', 'leadership_exp', 'horse', 'item',
'no', 'name', 'nation', 'turntime', 'personal', 'special2', 'crew', 'crewtype', 'atmos', 'train',
'intel', 'intel_exp', 'book', 'strength', 'strength_exp', 'weapon', 'injury', 'leadership', 'leadership_exp', 'horse', 'item',
'explevel', 'experience', 'dedication', 'officer_level', 'officer_city', 'gold', 'rice', 'dex1', 'dex2', 'dex3', 'dex4', 'dex5',
'recent_war', 'warnum', 'killnum', 'killcrew',
],
'integer'=>[
'no', 'nation', 'crew', 'crewtype', 'atmos', 'train',
'intel', 'intel_exp', 'strength', 'strength_exp', 'injury', 'leadership', 'leadership_exp',
'intel', 'intel_exp', 'strength', 'strength_exp', 'injury', 'leadership', 'leadership_exp',
'explevel', 'experience', 'dedication', 'officer_level', 'officer_city', 'gold', 'rice', 'dex1', 'dex2', 'dex3', 'dex4', 'dex5',
'warnum', 'killnum', 'killcrew',
],
@@ -154,18 +157,18 @@ foreach($rawDefenderList as $idx=>$rawDefenderGeneral){
]);
}
$rawDefenderGeneral['owner'] = 0;
$defenderList[] = new General($rawDefenderGeneral, extractRankVar($rawDefenderGeneral), $rawDefenderCity, $rawAttackerNation, $year, $month, true);
}
$cityCheck = [
'required'=>[
'city', 'nation', 'supply', 'name',
'pop', 'agri', 'comm', 'secu', 'def', 'wall',
'city', 'nation', 'supply', 'name',
'pop', 'agri', 'comm', 'secu', 'def', 'wall',
'trust', 'level',
'pop_max', 'agri_max', 'comm_max', 'secu_max', 'def_max', 'wall_max',
'dead', 'state', 'conflict',
'dead', 'state', 'conflict',
],
'numeric'=>[
'pop', 'agri', 'comm', 'secu', 'def', 'wall', 'trust', 'dead'
@@ -258,7 +261,7 @@ if($action == 'reorder'){
foreach($defenderList as $defenderGeneral){
$order[] = $defenderGeneral->getID();
}
Json::die([
'result'=>true,
'reason'=>'success',
@@ -280,19 +283,21 @@ $gameStor = KVStorage::getStorage($db, 'game_env');
$startYear = $gameStor->startyear;
$cityRate = Util::round(($year - $startYear) / 1.5) + 60;
function extractRankVar(array $rawVal):array{
$rankVars = [];
function extractRankVar(array $rawVal):Map{
$rankVars = new Map;
foreach($rawVal as $rawKey=>$rawVal){
if(key_exists($rawKey, General::RANK_COLUMN)){
$rankVars[$rawKey] = $rawVal;
$key = RankColumn::tryFrom($rawKey);
if($key === null){
continue;
}
$rankVars[$key] = $rawVal;
}
return $rankVars;
}
function simulateBattle(
$rawAttacker, $rawAttackerCity, $rawAttackerNation,
$rawDefenderList, $rawDefenderCity, $rawDefenderNation,
$rawAttacker, $rawAttackerCity, $rawAttackerNation,
$rawDefenderList, $rawDefenderCity, $rawDefenderNation,
$startYear, $year, $month, $cityRate
){
$attacker = new WarUnitGeneral(
@@ -310,7 +315,7 @@ function simulateBattle(
$attackerRice = $rawAttacker['rice'];
$defenderRice = 0;
$getNextDefender = function(?WarUnit $prevDefender, bool $reqNext)
$getNextDefender = function(?WarUnit $prevDefender, bool $reqNext)
use ($iterDefender, $rawDefenderCity, $rawDefenderNation, $year, $month, &$battleResult, &$defenderRice) {
if($prevDefender !== null){
$prevDefender->getLogger()->rollback();
@@ -393,13 +398,13 @@ $defendersActivatedSkills = [];
foreach(Util::range($repeatCnt) as $repeatIdx){
/** @var WarUnit $attacker */
[$attacker, $city, $battleResult, $conquerCity, $attackerRice, $defenderRice] = simulateBattle(
$rawAttacker, $rawAttackerCity, $rawAttackerNation,
$rawDefenderList, $rawDefenderCity, $rawDefenderNation,
$rawAttacker, $rawAttackerCity, $rawAttackerNation,
$rawDefenderList, $rawDefenderCity, $rawDefenderNation,
$startYear, $year, $month, $cityRate
);
$lastWarLog = Util::mapWithKey(function($key, $values){
return ConvertLog(join('<br>', $values));
}, $attacker->getLogger()->rollback());
}, $attacker->getLogger()->rollback());
$avgPhase += $attacker->getPhase() / $repeatCnt;
@@ -443,7 +448,7 @@ foreach(Util::range($repeatCnt) as $repeatIdx){
$activatedSkills[$skillName] += $skillCnt / $repeatCnt;
}
}
}
}
+1 -1
View File
@@ -18,7 +18,7 @@ $loader->addClassMap((function () {
//디버그용 매크로
ini_set("session.cache_expire", 10080); // minutes
ini_set("session.cache_expire", "10080"); // minutes
ob_start();
-1
View File
@@ -1 +0,0 @@
0
-53
View File
@@ -1,53 +0,0 @@
로그활성화
show variables like '%log%';
ALTER TABLE mysql.general_log
ADD COLUMN seq BIGINT UNSIGNED NOT NULL AUTO_INCREMENT AFTER argument,
ADD PRIMARY KEY(seq),
ENGINE=MYISAM;
set global expire_logs_days=7;
set global log_output='TABLE';
set global general_log=1;
select count(*) from mysql.general_log;
select * from mysql.general_log limit 100;
set global general_log=0;
truncate mysql.general_log;
캐시들
show variables like '%cache%';
show status like '%cache%';
show variables like '%key%';
show status like '%key%';
key_buffer_size 줄이자. 현16M -> 8M이하
myisam_sort_buffer_size 줄이자. 현8M -> 2M
innodb 설정
기존 Antelope 포맷은 가변컬럼의 767바이트까지만 저장하고 나머지는 offset하여 외부에 저장한다.
그런데 innodb는 1개 행이 최대 8KB만 저장 가능하므로 가변컬럼이 11개 이상인 경우는 오류 위험이 있다.
(MyISAM은 64KB)
Barracuda 포맷에 Dynamic 또는 Compressed를 사용하면 포인터 20바이트만 저장하고 실데이터는 외부에 저장한다.
[mysqld]
innodb_file_format=barracuda
innodb_file_per_table=1
innodb 최적화
innodb_buffer_pool_size: 체섭 테이블 최대 5M정도. 인덱스 포함해도 32M면 충분?
innodb_flush_method: 기본값대로. O_DIRECT는 메모리가 커서 캐시 2중 필요 없을때만.
innodb_file_per_table: 테이블마다 독립파일로 저장
innodb_flush_log_at_trx_commit: 기본1(커밋마다), 0(로그찰때만), 추천2(1초마다)
innodb_log_file_size: 현 5M, 많이 키워도 될듯
innodb_log_buffer_size: 기본 8M 적당
innodb_thread_concurrency: 코어개수 2배 정도
sync_binlog=0 이미 꺼져있음
ib_logfile0, ib_logfile1은 로그사이즈 바꾸면 재시작이 안되므로 지우고 다시 해야함
alter table table_name engine=innodb row_format=dynamic
+2 -2
View File
@@ -269,10 +269,10 @@ function processWar_NG(
$defenderCrewTypeCoef = $defender->getCrewType()->getAttackCoef($attacker->getCrewType()) * $attacker->getCrewType()->getDefenceCoef($defender->getCrewType());
/*
if($attackerCrewTypeCoef > $defenderCrewTypeCoef && $attacker instanceof WarUnitGeneral){
$attacker->getGeneral()->increaseInheritancePoint('snipe_combat', 1);
$attacker->getGeneral()->increaseInheritancePoint(InheritanceKey::snipe_combat, 1);
}
if($defenderCrewTypeCoef > $attackerCrewTypeCoef && $defender instanceof WarUnitGeneral){
$defender->getGeneral()->increaseInheritancePoint('snipe_combat', 1);
$defender->getGeneral()->increaseInheritancePoint(InheritanceKey::snipe_combat, 1);
}
*/
-4
View File
@@ -1,4 +0,0 @@
<?php
require('../vendor/autoload.php');
//ParsedownExtra;
@@ -6,13 +6,10 @@ use sammo\Session;
use DateTimeInterface;
use sammo\DB;
use sammo\DTO\BettingInfo;
use sammo\General;
use sammo\KVStorage;
use sammo\Util;
use sammo\Validator;
use function sammo\increaseRefresh;
class GetBettingDetail extends \sammo\BaseAPI
{
public function validateArgs(): ?string
+12 -1
View File
@@ -7,6 +7,7 @@ use DateTimeInterface;
use sammo\DB;
use sammo\DTO\BettingInfo;
use sammo\KVStorage;
use sammo\Validator;
use function sammo\checkLimit;
use function sammo\increaseRefresh;
@@ -15,6 +16,11 @@ class GetBettingList extends \sammo\BaseAPI
{
public function validateArgs(): ?string
{
$v = new Validator($this->args);
$v->rule('in', 'req', ['bettingNation', 'tournament']);
if (!$v->validate()) {
return $v->errorStr();
}
return null;
}
@@ -27,6 +33,8 @@ class GetBettingList extends \sammo\BaseAPI
{
$db = DB::db();
$reqType = $this->args['req'] ?? null;
increaseRefresh("베팅장", 1);
$gameStor = KVStorage::getStorage($db, 'game_env');
@@ -42,6 +50,9 @@ class GetBettingList extends \sammo\BaseAPI
$bettingList = [];
foreach ($bettingStor->getAll() as $_key => $rawItem) {
$item = new BettingInfo($rawItem);
if ($reqType !== null && $item->type != $reqType) {
continue;
}
unset($rawItem['candidates']);
$bettingList[$item->id] = $rawItem;
$bettingList[$item->id]['totalAmount'] = 0;
@@ -49,7 +60,7 @@ class GetBettingList extends \sammo\BaseAPI
[$year, $month] = $gameStor->getValuesAsArray(['year', 'month']);
if(!$bettingList){
if (!$bettingList) {
return [
'result' => true,
'bettingList' => $bettingList,
-1
View File
@@ -6,7 +6,6 @@ use sammo\Session;
use DateTimeInterface;
use sammo\Validator;
use function sammo\cutTurn;
use function sammo\pushGeneralCommand;
class PushCommand extends \sammo\BaseAPI
-1
View File
@@ -6,7 +6,6 @@ use sammo\Session;
use DateTimeInterface;
use sammo\Validator;
use function sammo\cutTurn;
use function sammo\repeatGeneralCommand;
class RepeatCommand extends \sammo\BaseAPI
+68
View File
@@ -0,0 +1,68 @@
<?php
namespace sammo\API\General;
use sammo\DB;
use sammo\Validator;
use sammo\Session;
use sammo\GameConst;
use sammo\General;
use sammo\JosaUtil;
class DropItem extends \sammo\BaseAPI
{
public function validateArgs(): ?string
{
$v = new Validator($this->args);
$v->rule('required', [
'itemType',
])
->rule('in', 'itemType', array_keys(GameConst::$allItems));
if (!$v->validate()) {
return "{$v->errorStr()}";
}
return null;
}
public function getRequiredSessionMode(): int
{
return static::REQ_GAME_LOGIN;
}
public function launch(Session $session, ?\DateTimeInterface $modifiedSince, ?string $reqEtag)
{
$generalID = $session->generalID;
$me = General::createGeneralObjFromDB($generalID);
$itemType = $this->args['itemType'];
$item = $me->getItem($itemType);
if ($item->getRawClassName() === 'None') {
return '아이템을 가지고 있지 않습니다.';
}
$me->setItem($itemType, 'None');
$logger = $me->getLogger();
$generalName = $me->getName();
$josaYi = JosaUtil::pick($generalName, '이');
$itemName = $item->getName();
$itemRawName = $item->getRawName();
$josaUl = JosaUtil::pick($itemRawName, '을');
$logger->pushGeneralActionLog("<C>{$itemName}</>{$josaUl} 버렸습니다.");
$nationName = $me->getStaticNation()['name'];
if (!$item->isBuyable()) {
$logger->pushGlobalActionLog("<Y>{$generalName}</>{$josaYi} <C>{$itemName}</>{$josaUl} 잃었습니다!");
$logger->pushGlobalHistoryLog("<R><b>【망실】</b></><D><b>{$nationName}</b></>의 <Y>{$generalName}</>{$josaYi} <C>{$itemName}</>{$josaUl} 잃었습니다!");
}
$me->applyDB(DB::db());
return null;
}
}
+51
View File
@@ -0,0 +1,51 @@
<?php
namespace sammo\API\General;
use sammo\Validator;
use sammo\API\Nation\GetGeneralLog as GetNationGeneralLog;
use sammo\Session;
class GetGeneralLog extends GetNationGeneralLog
{
const GENERAL_HISTORY = 'generalHistory';
const GENERAL_ACTION = 'generalAction';
const BATTLE_RESULT = 'battleResult';
const BATTLE_DETAIL = 'battleDetail';
public function validateArgs(): ?string
{
$v = new Validator($this->args);
$v
->rule('required', [
'type',
])
->rule('integer', [
'reqTo',
])
->rule('in', 'type', [
self::GENERAL_HISTORY,
self::GENERAL_ACTION,
self::BATTLE_RESULT,
self::BATTLE_DETAIL,
]);
if (!$v->validate()) {
return $v->errorStr();
}
if (key_exists('reqTo', $this->args)) {
$this->args['reqTo'] = (int)$this->args['reqTo'];
}
return null;
}
public function checkPermission(array $me): ?string
{
return null;
}
public function getTargetGeneralID(Session $session): int{
return $session->generalID;
}
}
+9 -7
View File
@@ -5,9 +5,11 @@ namespace sammo\API\General;
use sammo\ActionLogger;
use sammo\CityConst;
use sammo\DB;
use sammo\Enums\RankColumn;
use sammo\GameConst;
use sammo\GameUnitConst;
use sammo\General;
use sammo\InheritancePointManager;
use sammo\JosaUtil;
use sammo\Json;
use sammo\KVStorage;
@@ -26,7 +28,6 @@ use function sammo\cutTurn;
use function sammo\getGeneralSpecialWarName;
use function sammo\getRandTurn;
use function sammo\pushAdminLog;
use function sammo\applyInheritanceUser;
class Join extends \sammo\BaseAPI
{
@@ -155,7 +156,8 @@ class Join extends \sammo\BaseAPI
$admin = $gameStor->getValues(['scenario', 'turnterm', 'turntime', 'show_img_level', 'startyear', 'year', 'month']);
$inheritTotalPoint = applyInheritanceUser($userID);
$inheritPointManager = InheritancePointManager::getInstance();
$inheritTotalPoint = $inheritPointManager->applyInheritanceUser($userID);
$inheritRequiredPoint = 0;
$userLogger = new UserLogger($userID, $admin['year'], $admin['month'], false);
@@ -368,18 +370,15 @@ class Join extends \sammo\BaseAPI
$db->insert('general_turn', $turnRows);
$rank_data = [];
foreach (array_keys(General::RANK_COLUMN) as $rankColumn) {
foreach (RankColumn::cases() as $rankColumn) {
$rank_data[] = [
'general_id' => $generalID,
'nation_id' => 0,
'type' => $rankColumn,
'type' => $rankColumn->value,
'value' => 0
];
}
$db->insert('rank_data', $rank_data);
$db->insert('betting', [
'general_id' => $generalID,
]);
$cityname = CityConst::byID($city)->name;
@@ -388,6 +387,9 @@ class Join extends \sammo\BaseAPI
$inheritStor = KVStorage::getStorage(DB::db(), "inheritance_{$userID}");
$inheritStor->setValue('previous', [$inheritTotalPoint - $inheritRequiredPoint, null]);
$userLogger->flush();
$db->update('rank_data', [
'value'=>$db->sqleval('value + %i', $inheritRequiredPoint)
], 'general_id = %i AND type = %s', $generalID, RankColumn::inherit_point_spent_dynamic->value);
}
$me = [
+29
View File
@@ -0,0 +1,29 @@
<?php
namespace sammo\API\Global;
use sammo\Session;
use DateTimeInterface;
use sammo\TurnExecutionHelper;
class ExecuteEngine extends \sammo\BaseAPI
{
public function validateArgs(): ?string
{
return null;
}
public function getRequiredSessionMode(): int
{
return static::NO_SESSION;
}
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag)
{
$updated = TurnExecutionHelper::executeAllCommand();
return [
'result' => true,
'updated' => $updated,
];
}
}
+3 -14
View File
@@ -1,21 +1,16 @@
<?php
namespace sammo\API\List\Nation;
namespace sammo\API\Global;
use sammo\DB;
use sammo\General;
use sammo\Json;
use sammo\KVStorage;
use sammo\RootDB;
use sammo\Session;
use sammo\Util;
use sammo\Validator;
use function sammo\calcLeadershipBonus;
use function sammo\checkLimit;
use function sammo\checkSecretPermission;
use function sammo\getDed;
use function sammo\getDedLevelText;
use function sammo\getExpLevel;
use function sammo\getGenChar;
use function sammo\getGeneralSpecialDomesticName;
@@ -27,14 +22,9 @@ use function sammo\increaseRefresh;
class GeneralList extends \sammo\BaseAPI
{
static $withToken = false;
public function validateArgs(): ?string
{
$v = new Validator($this->args);
$v
->rule('boolean', 'with_token');
if (!$v->validate()) {
return $v->errorStr();
}
return null;
}
@@ -46,7 +36,6 @@ class GeneralList extends \sammo\BaseAPI
public function launch(Session $session, ?\DateTimeInterface $modifiedSince, ?string $reqEtag)
{
$db = DB::db();
$withToken = $this->args['with_token']??false;
$gameStor = KVStorage::getStorage($db, 'game_env');
$userID = $session->userID;
@@ -148,7 +137,7 @@ class GeneralList extends \sammo\BaseAPI
];
if ($withToken) {
if (static::$withToken) {
$now = (new \DateTimeImmutable())->format('Y-m-d H:i:s');
$tokens = [];
foreach ($db->query('SELECT * FROM select_npc_token WHERE `valid_until`>=%s', $now) as $token) {
@@ -0,0 +1,8 @@
<?php
namespace sammo\API\Global;
class GeneralListWithToken extends GeneralList
{
static $withToken = true;
}
+101
View File
@@ -0,0 +1,101 @@
<?php
namespace sammo\API\Global;
use sammo\Session;
use DateTimeInterface;
use Nette\Caching\Cache;
use sammo\APICacheResult;
use sammo\GameConst;
use sammo\MapRequest;
use sammo\TimeUtil;
use sammo\UniqueConst;
use sammo\Util;
use sammo\Validator;
use function sammo\getGlobalHistoryLogRecent;
use function sammo\getWorldMap;
use function sammo\prepareDir;
class GetCachedMap extends \sammo\BaseAPI
{
const CACHE_SECONDS = 600;
private ?\DateTimeInterface $cachedTime = null;
public function validateArgs(): ?string
{
return null;
}
public function tryCache(): ?APICacheResult
{
if ($this->cachedTime === null) {
return null;
}
$now = TimeUtil::nowDateTimeImmutable();
$diff = TimeUtil::DateIntervalToSeconds($this->cachedTime->diff($now));
$nextCacheTime = self::CACHE_SECONDS - $diff;
return new APICacheResult($this->cachedTime, null, Util::toInt($nextCacheTime), true);
}
public function getRequiredSessionMode(): int
{
return static::NO_SESSION;
}
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag)
{
if (!class_exists('\\sammo\\UniqueConst')) {
return '서버 초기화되지 않음';
}
if (!prepareDir('data/file_cache')) {
return 'cache 불가';
}
$storage = new \Nette\Caching\Storages\FileStorage('data/file_cache');
$cache = new Cache($storage);
$now = TimeUtil::nowDateTimeImmutable();
if ($modifiedSince) {
$diff = TimeUtil::DateIntervalToSeconds($modifiedSince->diff($now));
if (0 <= $diff && $diff < self::CACHE_SECONDS) {
$this->cachedTime = $modifiedSince;
return null;
}
}
$mapInfo = $cache->load("recent_map");
if ($mapInfo) {
$cachedTime = TimeUtil::secondsToDateTime($mapInfo['timestamp'], true, true);
$diff = $cachedTime->diff($now);
if (0 <= $diff && $diff < self::CACHE_SECONDS) {
$this->cachedTime = $cachedTime;
return $mapInfo['data'];
}
}
$history = getGlobalHistoryLogRecent(10);
$cachedMap = getWorldMap([
'year' => null,
'month' => null,
'aux' => null,
'neutralView' => true,
'showMe' => false,
]);
$cachedMap['history'] = $history;
$cachedMap['theme'] = GameConst::$mapName;
$timestamp = $now->getTimestamp();
$this->cachedTime = $now;
$map = [
'timestamp' => $timestamp,
'data' => $cachedMap,
];
$cache->save("recent_map", $map);
return $cachedMap;
}
}
+3 -7
View File
@@ -25,11 +25,6 @@ class GetConst extends \sammo\BaseAPI
private ?string $cacheKey = null;
public function __construct(string $rootPath, array $args)
{
parent::__construct($rootPath, $args);
}
public function validateArgs(): ?string
{
return null;
@@ -37,7 +32,7 @@ class GetConst extends \sammo\BaseAPI
public function getRequiredSessionMode(): int
{
return static::REQ_LOGIN;
return static::NO_SESSION;
}
public function findLastModified(): ?int
@@ -112,7 +107,7 @@ class GetConst extends \sammo\BaseAPI
return new APICacheResult(TimeUtil::secondsToDateTime($this->findLastModified()??\time(), true, true));
}
return new APICacheResult(null, $this->getCacheKey());
return new APICacheResult(null, $this->getCacheKey(), 60, true);
}
public function readCache(Cache $cache): null|string|array|int|float|bool
@@ -196,6 +191,7 @@ class GetConst extends \sammo\BaseAPI
public function genConstData()
{
/** @var array<string,array{0:string,1:string[],2?:int> */
$gameConstKeys = [
'nationType' => [
'\sammo\buildNationTypeClass',
@@ -0,0 +1,31 @@
<?php
namespace sammo\API\Global;
use sammo\Session;
use DateTimeInterface;
use function sammo\getCurrentHistory;
class GetCurrentHistory extends \sammo\BaseAPI
{
public function validateArgs(): ?string
{
return null;
}
public function getRequiredSessionMode(): int
{
return static::REQ_GAME_LOGIN | static::REQ_READ_ONLY;
}
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag)
{
$history = getCurrentHistory();
return [
'result' => true,
'data' => $history,
];
}
}
+105
View File
@@ -0,0 +1,105 @@
<?php
namespace sammo\API\Global;
use sammo\DB;
use sammo\Json;
use sammo\KVStorage;
use sammo\Session;
use function sammo\getAllNationStaticInfo;
use function sammo\increaseRefresh;
class GetDiplomacy extends \sammo\BaseAPI
{
public function validateArgs(): ?string
{
return null;
}
public function getRequiredSessionMode(): int
{
return static::REQ_GAME_LOGIN | static::REQ_READ_ONLY;
}
public function launch(Session $session, ?\DateTimeInterface $modifiedSince, ?string $reqEtag)
{
$userID = $session->userID;
increaseRefresh("중원정보", 1);
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
$myNationID = $db->queryFirstField('SELECT nation FROM general WHERE owner=%i', $userID);
$nations = array_filter(getAllNationStaticInfo(), function (array $nation) {
return $nation['level'];
});
uasort($nations, function (array $lhs, array $rhs) {
return - ($lhs['power'] <=> $rhs['power']);
});
foreach(array_keys($nations) as $nationID){
$nations[$nationID]['cities'] = [];
}
$realConflict = [];
foreach ($db->queryAllLists('SELECT nation, city, name, conflict FROM city') as [
$nationID,
$cityID,
$cityName,
$rawConflict
]) {
if($nationID != 0){
$nations[$nationID]['cities'][] = $cityName;
}
if($rawConflict == '{}'){
continue;
}
$rawConflict = Json::decode($rawConflict);
if (count($rawConflict) < 2) {
continue;
}
$sum = array_sum($rawConflict);
$conflict = [];
foreach ($rawConflict as $nationID => $killnum) {
$conflict[$nationID] = round(100 * $killnum / $sum, 1);
}
$realConflict[] = [$cityID, $conflict];
};
$neutralDiplomacyMap = [
3 => 2,
4 => 2,
5 => 2,
6 => 2,
7 => 2,
];
$diplomacyList = [];
foreach ($db->queryAllLists('SELECT me, you, state FROM diplomacy') as [$me, $you, $state]) {
if (!key_exists($me, $diplomacyList)) {
$diplomacyList[$me] = [];
}
if ($me != $myNationID && $you != $myNationID) {
$diplomacyList[$me][$you] = $neutralDiplomacyMap[$state] ?? $state;
} else {
$diplomacyList[$me][$you] = $state;
}
}
return [
'result' => true,
'nations' => array_values($nations),
'conflict' => $realConflict,
'diplomacyList' => $diplomacyList,
'myNationID' => $myNationID,
];
}
}
+188
View File
@@ -0,0 +1,188 @@
<?php
namespace sammo\API\Global;
use sammo\Session;
use DateTimeInterface;
use sammo\APICacheResult;
use sammo\DB;
use sammo\Json;
use sammo\UniqueConst;
use sammo\Util;
use sammo\Validator;
use function sammo\checkLimit;
use function sammo\increaseRefresh;
use function sammo\templateLimitMsg;
class GetHistory extends \sammo\BaseAPI
{
public string|null $cacheHash = null;
public function validateArgs(): ?string
{
$v = new Validator($this->args);
$v->rule('required', ['year', 'month'])
->rule('lengthMin', 'serverID', 1)
->rule('integer', 'year')
->rule('integer', 'month');
if (!$v->validate()) {
return $v->errorStr();
}
if (!$this->args['serverID']) {
$this->args['serverID'] = UniqueConst::$serverID;
}
return null;
}
public function getRequiredSessionMode(): int
{
return static::REQ_LOGIN | static::REQ_READ_ONLY;
}
public function tryCache(): ?APICacheResult
{
if (!$this->cacheHash) {
return null;
}
return new APICacheResult(
null,
$this->getCacheKey($this->args['serverID'], $this->args['year'], $this->args['month'], $this->cacheHash)
);
}
private function getHistory(string $serverID, int $year, int $month): array
{
$db = DB::db();
$history = $db->queryFirstRow(
'SELECT * FROM ng_history WHERE server_id = %s AND year = %i AND month = %i',
$serverID,
$year,
$month
);
$hash = hash(
'sha256',
"[" . join(',', [
$history['global_history'],
$history['global_action'],
$history['nations'],
$history['map'],
]) . "]"
);
$history['global_history'] = Json::decode($history['global_history']);
$history['global_action'] = Json::decode($history['global_action']);
$history['nations'] = Json::decode($history['nations']);
$history['map'] = Json::decode($history['map']);
$history['hash'] = $hash;
return $history;
}
public function parseEtag(?string $etag): ?array
{
if (!$etag) {
return null;
}
$tags = explode('-', $etag);
if (count($tags) != 4) {
return null;
}
if (!is_numeric($tags[1])) {
return null;
}
if (!is_numeric($tags[2])) {
return null;
}
return [$tags[0], Util::toInt($tags[1]), Util::toInt($tags[2]), $tags[3]];
}
public function getCacheKey(string $serverID, int $year, int $month, string $cacheHash): string
{
return "{$serverID}-{$year}-{$month}-{$cacheHash}";
}
public function checkCached(?string $reqEtag): ?string
{
if (!$reqEtag) {
return null;
}
$parsedTags = $this->parseEtag($reqEtag);
if (!$parsedTags) {
return null;
}
$serverID = $this->args['serverID'];
$year = Util::toInt($this->args['year']);
$month = Util::toInt($this->args['month']);
[$cachedServerID, $cachedYear, $cachedMonth, $cachedHash] = $parsedTags;
if ($cachedServerID !== $serverID || $cachedYear !== $year || $cachedMonth !== $month) {
return null;
}
//tag로 hash를 굳이 붙이고 왔다면, 이미 데이터를 가지고 있다고 가정한다.
return $cachedHash;
}
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag)
{
$checkCache = $this->checkCached($reqEtag);
if ($checkCache) {
$this->cacheHash = $checkCache;
return null;
}
$serverID = $this->args['serverID'];
$year = $this->args['year'];
$month = $this->args['month'];
$db = DB::db();
if ($serverID === UniqueConst::$serverID) {
if (!$session->isGameLoggedIn()) {
return '진행중인 서버의 연감은 게임에 로그인해야 볼 수 있습니다.';
}
increaseRefresh("연감", 1);
$me = $db->queryFirstRow('SELECT con, turntime FROM general WHERE owner = %i', $session->userID);
if (!$me) {
return '장수가 사망했습니다.';
}
$con = checkLimit($me['con']);
if ($con >= 2) {
return templateLimitMsg($me['turntime']);
}
}
[$f_year, $f_month] = $db->queryFirstList(
'SELECT year, month FROM ng_history WHERE server_id = %s ORDER BY year ASC, month ASC LIMIT 1',
$serverID
);
if ($f_year === null || $f_month === null) {
return '올바르지 않은 서버 아이디입니다.';
}
$firstYearMonth = Util::joinYearMonth($f_year, $f_month);
[$l_year, $l_month] = $db->queryFirstList(
'SELECT year, month FROM ng_history WHERE server_id = %s ORDER BY year DESC, month DESC LIMIT 1',
$serverID
);
$lastYearMonth = Util::joinYearMonth($l_year, $l_month);
$queryYearMonth = Util::joinYearMonth($year, $month);
if ($queryYearMonth < $firstYearMonth || $queryYearMonth > $lastYearMonth) {
return '올바르지 않은 범위입니다.';
}
$history = $this->getHistory($serverID, $year, $month);
$this->cacheHash = $history['hash'];
return [
'result' => true,
'data' => $history,
];
}
}
+37
View File
@@ -0,0 +1,37 @@
<?php
namespace sammo\API\Global;
use sammo\Session;
use DateTimeInterface;
use sammo\MapRequest;
use sammo\Validator;
use function sammo\getWorldMap;
class GetMap extends \sammo\BaseAPI
{
public function validateArgs(): ?string
{
$v = new Validator($this->args);
$v->rule('in', 'neutralView', [0, 1])
->rule('in', 'showMe', [0, 1]);
if (!$v->validate()) {
return $v->errorStr();
}
return null;
}
public function getRequiredSessionMode(): int
{
return static::REQ_LOGIN | static::REQ_READ_ONLY;
}
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag)
{
return getWorldMap(new MapRequest([
'neutralView' => !!($this->args['neutralView'] ?? false),
'showMe' => !!($this->args['showMe'] ?? false),
]));
}
}
@@ -5,6 +5,7 @@ namespace sammo\API\InheritAction;
use sammo\Session;
use DateTimeInterface;
use sammo\DB;
use sammo\Enums\RankColumn;
use sammo\GameConst;
use sammo\General;
use sammo\KVStorage;
@@ -80,6 +81,7 @@ class BuyHiddenBuff extends \sammo\BaseAPI
$inheritBuffList[$type] = $level;
$general->setAuxVar('inheritBuff', $inheritBuffList);
$inheritStor->setValue('previous', [$previousPoint - $reqAmount, null]);
$general->increaseRankVar(RankColumn::inherit_point_spent_dynamic, $reqAmount);
$general->applyDB($db);
return null;
}
@@ -5,6 +5,7 @@ namespace sammo\API\InheritAction;
use sammo\Session;
use DateTimeInterface;
use sammo\DB;
use sammo\Enums\RankColumn;
use sammo\GameConst;
use sammo\General;
use sammo\KVStorage;
@@ -52,6 +53,7 @@ class BuyRandomUnique extends \sammo\BaseAPI
$general->setAuxVar('inheritRandomUnique', TimeUtil::now());
$inheritStor->setValue('previous', [$previousPoint - $reqAmount, null]);
$general->increaseRankVar(RankColumn::inherit_point_spent_dynamic, $reqAmount);
$general->applyDB($db);
return null;
}
@@ -5,6 +5,7 @@ namespace sammo\API\InheritAction;
use sammo\Session;
use DateTimeInterface;
use sammo\DB;
use sammo\Enums\RankColumn;
use sammo\GameConst;
use sammo\General;
use sammo\KVStorage;
@@ -66,6 +67,19 @@ class BuySpecificUnique extends \sammo\BaseAPI
return '이미 입찰한 아이템입니다. 다음 턴에 시도해 주세요.';
}
foreach(GameConst::$allItems as $itemType => $items){
if(!key_exists($itemKey, $items)){
continue;
}
$prevItem = $general->getItem($itemType);
if(!$prevItem->isBuyable()){
return '이미 같은 자리에 유니크를 보유하고 있습니다.';
}
break;
}
$db = DB::db();
$inheritStor = KVStorage::getStorage($db, "inheritance_{$userID}");
$trialStor = KVStorage::getStorage($db, "ut_{$itemKey}");
@@ -82,6 +96,7 @@ class BuySpecificUnique extends \sammo\BaseAPI
$itemTrials[$itemKey] = $amount;
$general->setAuxVar('inheritUniqueTrial', $itemTrials);
$inheritStor->setValue('previous', [$previousPoint - $amount, null]);
$general->increaseRankVar(RankColumn::inherit_point_spent_dynamic, $amount);
$trialStor->setValue("u{$userID}", [$userID, $generalID, $amount]);
$general->applyDB($db);
return null;
@@ -5,6 +5,7 @@ namespace sammo\API\InheritAction;
use sammo\Session;
use DateTimeInterface;
use sammo\DB;
use sammo\Enums\RankColumn;
use sammo\GameConst;
use sammo\General;
use sammo\KVStorage;
@@ -68,6 +69,7 @@ class ResetSpecialWar extends \sammo\BaseAPI
$general->setAuxVar('inheritResetSpecialWar', $nextLevel);
$general->setVar('special2', 'None');
$inheritStor->setValue('previous', [$previousPoint - $reqPoint, null]);
$general->increaseRankVar(RankColumn::inherit_point_spent_dynamic, $reqPoint);
$general->applyDB($db);
return null;
}
@@ -6,6 +6,7 @@ use DateTimeImmutable;
use sammo\Session;
use DateTimeInterface;
use sammo\DB;
use sammo\Enums\RankColumn;
use sammo\GameConst;
use sammo\General;
use sammo\KVStorage;
@@ -52,7 +53,7 @@ class ResetTurnTime extends \sammo\BaseAPI
return '충분한 유산 포인트를 가지고 있지 않습니다.';
}
$gameStor = new KVStorage($db, 'game_env');
$gameStor = KVStorage::getStorage($db, 'game_env');
[$turnTerm, $serverTurnTime] = $gameStor->getValuesAsArray(['turnterm', 'turntime']);
$currTurnTime = new DateTimeImmutable($general->getTurnTime());
@@ -77,6 +78,7 @@ class ResetTurnTime extends \sammo\BaseAPI
$general->setVar('turntime', TimeUtil::format($turnTime, true));
$general->setAuxVar('inheritResetTurnTime', $nextLevel);
$inheritStor->setValue('previous', [$previousPoint - $reqPoint, null]);
$general->increaseRankVar(RankColumn::inherit_point_spent_dynamic, $reqPoint);
$general->applyDB($db);
return null;
}
@@ -5,6 +5,7 @@ namespace sammo\API\InheritAction;
use sammo\Session;
use DateTimeInterface;
use sammo\DB;
use sammo\Enums\RankColumn;
use sammo\GameConst;
use sammo\General;
use sammo\KVStorage;
@@ -77,6 +78,7 @@ class SetNextSpecialWar extends \sammo\BaseAPI
$general->setAuxVar('inheritSpecificSpecialWar', $type);
$inheritStor->setValue('previous', [$previousPoint - $reqAmount, null]);
$general->increaseRankVar(RankColumn::inherit_point_spent_dynamic, $reqAmount);
$general->applyDB($db);
return null;
}
+40 -33
View File
@@ -6,16 +6,12 @@ use sammo\DB;
use sammo\General;
use sammo\Session;
use sammo\Util;
use sammo\Validator;
use function sammo\calcLeadershipBonus;
use function sammo\checkLimit;
use function sammo\checkSecretPermission;
use function sammo\getBillByLevel;
use function sammo\getDedLevelText;
use function sammo\getGenChar;
use function sammo\getGeneralSpecialDomesticName;
use function sammo\getGeneralSpecialWarName;
use function sammo\getHonor;
use function sammo\getNationStaticInfo;
use function sammo\getOfficerLevelText;
@@ -48,38 +44,49 @@ class GeneralList extends \sammo\BaseAPI
'belong' => 0,
'connect' => 0,
'con' => 1,
'specage' => 1,
'specage2' => 1,
'leadership_exp' => 1,
'strength_exp' => 1,
'intel_exp' => 1,
'dex1' => 1,
'dex2' => 1,
'dex3' => 1,
'dex4' => 1,
'dex5' => 1,
'city' => 1,
'experience' => 1,
'dedication' => 1,
'officer_level' => 2,
'officer_city' => 2,
'defence_train' => 2,
'troop' => 2,
'crewtype' => 2,
'crew' => 2,
'train' => 2,
'atmos' => 2,
'turntime' => 2,
'horse' => 2,
'weapon' => 2,
'book' => 2,
'item' => 2,
'recent_war' => 2,
'officer_level' => 1,
'officer_city' => 1,
'defence_train' => 1,
'troop' => 1,
'crewtype' => 1,
'crew' => 1,
'train' => 1,
'atmos' => 1,
'turntime' => 1,
'horse' => 1,
'weapon' => 1,
'book' => 1,
'item' => 1,
'recent_war' => 1,
'aux' => 2,
'aux' => 1,
'owner_name' => 9,//안씀.
'owner_name' => 9, //안씀.
//RANK
'warnum' => 2,
'killnum' => 2,
'deathnum' => 2,
'killcrew' => 2,
'deathcrew' => 2,
'firenum' => 2,
'warnum' => 1,
'killnum' => 1,
'deathnum' => 1,
'killcrew' => 1,
'deathcrew' => 1,
'firenum' => 1,
];
static $columnRemap = [
@@ -96,9 +103,9 @@ class GeneralList extends \sammo\BaseAPI
'honorText' => 0,
'dedLevelText' => 0,
'bill' => 0,
'reservedCommand' => 2,
'reservedCommand' => 1,
'autorun_limit' => 2,
'autorun_limit' => 1,
];
public function validateArgs(): ?string
@@ -151,7 +158,7 @@ class GeneralList extends \sammo\BaseAPI
$rawGeneralList = Util::convertArrayToDict($db->query('SELECT %l from general WHERE nation = %i ORDER BY turntime ASC', Util::formatListOfBackticks($queryColumns), $nationID), 'no');
$reservedCommand = [];
if ($this->permission >= 2) {
if ($this->permission >= 1) {
$nonNPCGeneralIDList = [];
foreach ($rawGeneralList as $rawGeneral) {
if ($rawGeneral['npc'] < 2) {
@@ -184,6 +191,7 @@ class GeneralList extends \sammo\BaseAPI
$rankList = [];
if ($rankColumns) {
$rankColumns = Util::valuesFromEnumArray($rankColumns);
$rawRankList = $db->query('SELECT general_id, `type`, `value` FROM rank_data WHERE nation_id = %i AND `type` IN %ls', $nationID, $rankColumns);
foreach ($rawRankList as $rawRank) {
[
@@ -228,7 +236,7 @@ class GeneralList extends \sammo\BaseAPI
}
if (key_exists($column, static::$columnRemap)) {
$newColumn = static::$columnRemap[$column];
if($newColumn !== null){
if ($newColumn !== null) {
$resultColumns[$newColumn] = $column;
}
} else {
@@ -263,10 +271,9 @@ class GeneralList extends \sammo\BaseAPI
$generalList[] = $item;
}
if($this->permission >= 2){
if ($this->permission >= 1) {
$troops = $db->queryAllLists('SELECT troop_leader,name FROM troop WHERE nation = %i', $nationID);
}
else{
} else {
$troops = null;
}
+166
View File
@@ -0,0 +1,166 @@
<?php
namespace sammo\API\Nation;
use sammo\DB;
use sammo\Session;
use sammo\Validator;
use function sammo\checkLimit;
use function sammo\checkSecretPermission;
use function sammo\getBattleDetailLogMore;
use function sammo\getBattleResultMore;
use function sammo\getBattleResultRecent;
use function sammo\getGeneralActionLogMore;
use function sammo\getGeneralActionLogRecent;
use function sammo\getGeneralHistoryLogAll;
class GetGeneralLog extends \sammo\BaseAPI
{
const GENERAL_HISTORY = 'generalHistory';
const GENERAL_ACTION = 'generalAction';
const BATTLE_RESULT = 'battleResult';
const BATTLE_DETAIL = 'battleDetail';
public function validateArgs(): ?string
{
$v = new Validator($this->args);
$v
->rule('required', [
'generalID',
'type',
])
->rule('integer', [
'generalID',
'reqTo',
])
->rule('in', 'type', [
self::GENERAL_HISTORY,
self::GENERAL_ACTION,
self::BATTLE_RESULT,
self::BATTLE_DETAIL,
]);
if (!$v->validate()) {
return $v->errorStr();
}
$this->args['generalID'] = (int)$this->args['generalID'];
if (key_exists('reqTo', $this->args)) {
$this->args['reqTo'] = (int)$this->args['reqTo'];
}
return null;
}
public function checkPermission(array $me): ?string
{
$permission = checkSecretPermission($me);
if ($permission < 0) {
return '국가에 소속되어있지 않습니다.';
}
$db = DB::db();
$generalID = $this->args['generalID'];
[$testGeneralNationID, $testGeneralNPCType] = $db->queryFirstList(
'SELECT nation,npc FROM general WHERE no = %i',
$generalID
);
if ($permission < 1) {
return '권한이 부족합니다. 수뇌부가 아니거나 사관년도가 부족합니다.';
}
$nationID = $me['nation'];
if ($testGeneralNationID !== $nationID) {
return '같은 나라의 장수가 아닙니다.';
}
$reqType = $this->args['type'];
if (
$reqType === self::GENERAL_ACTION &&
$testGeneralNPCType < 2 &&
$generalID !== $me['generalID'] &&
$permission < 2
) {
return '권한이 부족합니다. 유저 장수의 개인 기록은 수뇌만 열람 가능합니다.';
}
return null;
}
public function getRequiredSessionMode(): int
{
return static::REQ_GAME_LOGIN | static::REQ_READ_ONLY;
}
public function getTargetGeneralID(Session $session): int{
return $this->args['generalID'];
}
public function launch(Session $session, ?\DateTimeInterface $modifiedSince, ?string $reqEtag)
{
$userID = $session->userID;
$targetGeneralID = $this->getTargetGeneralID($session);
$reqType = $this->args['type'];
$reqTo = $this->args['reqTo'] ?? null;
$db = DB::db();
$me = $db->queryFirstRow('SELECT no,nation,officer_level,con,turntime,belong,permission,penalty from general where owner=%i', $userID);
$con = checkLimit($me['con']);
if ($con >= 2) {
return '접속 제한입니다.';
}
$permissionResult = $this->checkPermission($me);
if ($permissionResult !== null) {
return $permissionResult;
}
if ($reqType == static::GENERAL_HISTORY) {
return [
'result' => true,
'reqType' => $reqType,
'generalID' => $targetGeneralID,
'log' => getGeneralHistoryLogAll($targetGeneralID)
];
}
if ($reqType == static::GENERAL_ACTION) {
return [
'result' => true,
'reqType' => $reqType,
'generalID' => $targetGeneralID,
'log' => $reqTo === null
? getGeneralActionLogRecent($targetGeneralID, 30)
: getGeneralActionLogMore($targetGeneralID, $reqTo, 30)
];
}
if ($reqType == static::BATTLE_RESULT) {
return [
'result' => true,
'reqType' => $reqType,
'generalID' => $targetGeneralID,
'log' => $reqTo === null
? getBattleResultRecent($targetGeneralID, 30)
: getBattleResultMore($targetGeneralID, $reqTo, 30)
];
}
if ($reqType == static::BATTLE_DETAIL) {
return [
'result' => true,
'reqType' => $reqType,
'generalID' => $targetGeneralID,
'log' => $reqTo === null
? getBattleResultRecent($targetGeneralID, 30)
: getBattleDetailLogMore($targetGeneralID, $reqTo, 30)
];
}
return '잘못된 요청입니다: ' . $reqType;
}
}
+1 -1
View File
@@ -47,7 +47,7 @@ class SetBlockScout extends \sammo\BaseAPI
return "권한이 부족합니다.";
}
$gameStor = new KVStorage($db, 'game_env');
$gameStor = KVStorage::getStorage($db, 'game_env');
$blockChangeScout = $gameStor->getValue('block_change_scout')??false;
if ($blockChangeScout){
return "임관 설정을 바꿀 수 없도록 설정되어 있습니다.";
@@ -13,9 +13,7 @@ use sammo\TimeUtil;
use function sammo\checkLimit;
use function sammo\checkSecretPermission;
use function sammo\cutTurn;
use function sammo\getChiefCommandTable;
use function sammo\getNationChiefLevel;
use function sammo\getOfficerLevelText;
use function sammo\increaseRefresh;
@@ -7,7 +7,6 @@ use DateTimeInterface;
use sammo\DB;
use sammo\Validator;
use function sammo\cutTurn;
use function sammo\pushNationCommand;
class PushCommand extends \sammo\BaseAPI
@@ -7,8 +7,6 @@ use DateTimeInterface;
use sammo\DB;
use sammo\Validator;
use function sammo\cutTurn;
use function sammo\repeatGeneralCommand;
use function sammo\repeatNationCommand;
class RepeatCommand extends \sammo\BaseAPI
@@ -13,7 +13,7 @@ class che_의술_상한잡병론 extends \sammo\BaseItem{
protected $rawName = '상한잡병론';
protected $name = '상한잡병론(의술)';
protected $info = '[군사] 매 턴마다 자신(100%)과 소속 도시 장수(적 포함 50%) 부상 회복<br>[전투] 페이즈마다 40% 확률로 치료 발동(아군 피해 1/3 감소, 부상 회복)';
protected $info = '[군사] 매 턴마다 자신(100%)과 소속 도시 장수(적 포함 50%) 부상 회복<br>[전투] 페이즈마다 40% 확률로 치료 발동(아군 피해 30% 감소, 부상 회복)';
protected $cost = 200;
protected $consumable = false;
@@ -13,7 +13,7 @@ class che_의술_정력견혈산 extends \sammo\BaseItem{
protected $rawName = '정력견혈산';
protected $name = '정력견혈산(의술)';
protected $info = '[군사] 매 턴마다 자신(100%)과 소속 도시 장수(적 포함 50%) 부상 회복<br>[전투] 페이즈마다 40% 확률로 치료 발동(아군 피해 1/3 감소, 부상 회복)';
protected $info = '[군사] 매 턴마다 자신(100%)과 소속 도시 장수(적 포함 50%) 부상 회복<br>[전투] 페이즈마다 40% 확률로 치료 발동(아군 피해 30% 감소, 부상 회복)';
protected $cost = 200;
protected $consumable = false;
@@ -13,7 +13,7 @@ class che_의술_청낭서 extends \sammo\BaseItem{
protected $rawName = '청낭서';
protected $name = '청낭서(의술)';
protected $info = '[군사] 매 턴마다 자신(100%)과 소속 도시 장수(적 포함 50%) 부상 회복<br>[전투] 페이즈마다 40% 확률로 치료 발동(아군 피해 1/3 감소, 부상 회복)';
protected $info = '[군사] 매 턴마다 자신(100%)과 소속 도시 장수(적 포함 50%) 부상 회복<br>[전투] 페이즈마다 40% 확률로 치료 발동(아군 피해 30% 감소, 부상 회복)';
protected $cost = 200;
protected $consumable = false;
@@ -13,7 +13,7 @@ class che_의술_태평청령 extends \sammo\BaseItem{
protected $rawName = '태평청령';
protected $name = '태평청령(의술)';
protected $info = '[군사] 매 턴마다 자신(100%)과 소속 도시 장수(적 포함 50%) 부상 회복<br>[전투] 페이즈마다 40% 확률로 치료 발동(아군 피해 1/3 감소, 부상 회복)';
protected $info = '[군사] 매 턴마다 자신(100%)과 소속 도시 장수(적 포함 50%) 부상 회복<br>[전투] 페이즈마다 40% 확률로 치료 발동(아군 피해 30% 감소, 부상 회복)';
protected $cost = 200;
protected $consumable = false;
@@ -27,7 +27,7 @@ class che_치트_HideD의_사인검 extends \sammo\BaseItem
protected $info = <<<EOT
통솔 +100,무력 +100, 지력 +100<br>
[군사] 매 턴마다 자신(100%)과 소속 도시 장수(적 포함 50%) 부상 회복<br>
[전투] 페이즈마다 20% 확률로 치료 발동(아군 피해 1/3 감소)<br>
[전투] 페이즈마다 20% 확률로 치료 발동(아군 피해 30% 감소)<br>
[전투] 새로운 상대와 전투 시 1/2 확률로 저격 발동, 성공 시 사기+20<br>
[전투] 훈련 보정 +30, 사기 보정 +30<br>
[전투] 상대방 필살 및 회피 시도시 일정 확률로 격노(필살) 발동, 공격 시 일정 확률로 진노(1페이즈 추가)<br>
@@ -1,5 +1,7 @@
<?php
namespace sammo\ActionItem;
use sammo\Enums\RankColumn;
use \sammo\iAction;
use \sammo\General;
use \sammo\SpecialityHelper;
@@ -30,7 +32,7 @@ class event_전투특기_무쌍 extends \sammo\BaseItem{
}
$attackMultiplier = 1.05;
$defenceMultiplier = 0.98;
$killnum = $unit->getGeneral()->getRankVar('killnum');
$killnum = $unit->getGeneral()->getRankVar(RankColumn::killnum);
$attackMultiplier += log(max(1, $killnum / 5), 2) / 20;
$defenceMultiplier -= log(max(1, $killnum / 5), 2) / 50;
return [$attackMultiplier, $defenceMultiplier];
@@ -15,7 +15,7 @@ class event_전투특기_의술 extends \sammo\BaseItem{
protected $rawName = '비급';
protected $name = '비급(의술)';
protected $info = '[군사] 매 턴마다 자신(100%)과 소속 도시 장수(적 포함 50%) 부상 회복<br>[전투] 페이즈마다 40% 확률로 치료 발동(아군 피해 1/3 감소, 부상 회복)';
protected $info = '[군사] 매 턴마다 자신(100%)과 소속 도시 장수(적 포함 50%) 부상 회복<br>[전투] 페이즈마다 40% 확률로 치료 발동(아군 피해 30% 감소, 부상 회복)';
protected $cost = 100;
protected $buyable = true;
protected $consumable = false;
@@ -1,5 +1,7 @@
<?php
namespace sammo\ActionSpecialDomestic;
use sammo\Enums\RankColumn;
use \sammo\iAction;
use \sammo\General;
use \sammo\SpecialityHelper;
@@ -32,7 +34,7 @@ class che_event_무쌍 extends \sammo\BaseSpecial{
}
$attackMultiplier = 1.05;
$defenceMultiplier = 0.98;
$killnum = $unit->getGeneral()->getRankVar('killnum');
$killnum = $unit->getGeneral()->getRankVar(RankColumn::killnum);
$attackMultiplier += log(max(1, $killnum / 5), 2) / 20;
$defenceMultiplier -= log(max(1, $killnum / 5), 2) / 50;
return [$attackMultiplier, $defenceMultiplier];
@@ -15,7 +15,7 @@ class che_event_의술 extends \sammo\BaseSpecial{
protected $id = 73;
protected $name = '의술';
protected $info = '[군사] 매 턴마다 자신(100%)과 소속 도시 장수(적 포함 50%) 부상 회복<br>[전투] 페이즈마다 40% 확률로 치료 발동(아군 피해 1/3 감소, 부상 회복)';
protected $info = '[군사] 매 턴마다 자신(100%)과 소속 도시 장수(적 포함 50%) 부상 회복<br>[전투] 페이즈마다 40% 확률로 치료 발동(아군 피해 30% 감소, 부상 회복)';
static $selectWeightType = SpecialityHelper::WEIGHT_PERCENT;
static $selectWeight = 2;
+3 -1
View File
@@ -1,5 +1,7 @@
<?php
namespace sammo\ActionSpecialWar;
use sammo\Enums\RankColumn;
use \sammo\iAction;
use \sammo\General;
use \sammo\SpecialityHelper;
@@ -28,7 +30,7 @@ class che_무쌍 extends \sammo\BaseSpecial{
public function getWarPowerMultiplier(WarUnit $unit):array{
$attackMultiplier = 1.05;
$defenceMultiplier = 0.98;
$killnum = $unit->getGeneral()->getRankVar('killnum');
$killnum = $unit->getGeneral()->getRankVar(RankColumn::killnum);
$attackMultiplier += log(max(1, $killnum / 5), 2) / 20;
$defenceMultiplier -= log(max(1, $killnum / 5), 2) / 50;
return [$attackMultiplier, $defenceMultiplier];
+1 -1
View File
@@ -15,7 +15,7 @@ class che_의술 extends \sammo\BaseSpecial{
protected $id = 73;
protected $name = '의술';
protected $info = '[군사] 매 턴마다 자신(100%)과 소속 도시 장수(적 포함 50%) 부상 회복<br>[전투] 페이즈마다 40% 확률로 치료 발동(아군 피해 1/3 감소, 부상 회복)';
protected $info = '[군사] 매 턴마다 자신(100%)과 소속 도시 장수(적 포함 50%) 부상 회복<br>[전투] 페이즈마다 40% 확률로 치료 발동(아군 피해 30% 감소, 부상 회복)';
static $selectWeightType = SpecialityHelper::WEIGHT_PERCENT;
static $selectWeight = 2;
+9 -1
View File
@@ -1,17 +1,20 @@
<?php
namespace sammo\ActionSpecialWar;
use sammo\BaseWarUnitTrigger;
use \sammo\iAction;
use \sammo\General;
use \sammo\SpecialityHelper;
use \sammo\WarUnit;
use sammo\WarUnitTriggerCaller;
use sammo\WarUnitTrigger\che_필살강화_회피불가;
use sammo\WarUnitTrigger\WarActivateSkills;
class che_필살 extends \sammo\BaseSpecial{
protected $id = 71;
protected $name = '필살';
protected $info = '[전투] 필살 확률 +30%p, 필살 발동시 대상 회피 불가';
protected $info = '[전투] 필살 확률 +30%p, 필살 발동시 대상 회피 불가, 필살 계수 항상 최대';
static $selectWeightType = SpecialityHelper::WEIGHT_NORM;
static $selectWeight = 1;
@@ -25,6 +28,11 @@ class che_필살 extends \sammo\BaseSpecial{
if($statName === 'warCriticalRatio'){
return $value + 0.30;
}
if($statName === 'criticalDamageRange'){
[, $rangeMax] = $value;
return [$rangeMax, $rangeMax];
}
return $value;
}
-4
View File
@@ -15,10 +15,6 @@ class BaseItem implements iAction{
protected $buyable = false;
protected $reqSecu = 0;
function getID(){
return $this->id;
}
function getRawName(){
return $this->rawName;
}
+1 -2
View File
@@ -12,7 +12,7 @@ class BaseStatItem extends BaseItem{
protected $rawName = '노기';
protected $consumable = false;
protected $buyable = true;
protected const ITEM_TYPE = [
'명마'=>['통솔', 'leadership'],
'무기'=>['무력', 'strength'],
@@ -27,7 +27,6 @@ class BaseStatItem extends BaseItem{
$this->rawName = $nameTokens[$tokenLen-1];
[$this->statNick, $this->statType] = static::ITEM_TYPE[$nameTokens[$tokenLen-3]];
$this->id = $this->statValue;
$this->name = sprintf('%s(+%d)',$this->rawName, $this->statValue);
$this->info = sprintf('%s +%d', $this->statNick, $this->statValue);
}
+73 -22
View File
@@ -2,14 +2,39 @@
namespace sammo;
use Ds\Map;
use sammo\DTO\BettingInfo;
use sammo\DTO\BettingItem;
use sammo\Enums\RankColumn;
class Betting
{
private BettingInfo $info;
public const LAST_BETTING_ID_KEY = 'last_betting_id';
static public function genNextBettingID(): int
{
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
$gameStor->invalidateCacheValue(self::LAST_BETTING_ID_KEY);
$bettingID = ($gameStor->getValue(self::LAST_BETTING_ID_KEY) ?? 0) + 1;
$gameStor->setValue(self::LAST_BETTING_ID_KEY, $bettingID);
return $bettingID;
}
static public function openBetting(BettingInfo $info)
{
$db = DB::db();
$bettingID = $info->id;
$bettingStor = KVStorage::getStorage($db, 'betting');
$bettingStor->setValue("id_{$bettingID}", $info->toArray());
}
public function __construct(private $bettingID)
{
$db = DB::db();
@@ -26,7 +51,7 @@ class Betting
return Json::encode($bettingType);
}
public function purifyBettingKey(array $bettingType, bool $ignoreOver = false): array
public function purifyBettingKey(array $bettingType, bool $noValidate = false): array
{
$selectCnt = $this->info->selectCnt;
sort($bettingType, SORT_NUMERIC);
@@ -35,17 +60,30 @@ class Betting
throw new \InvalidArgumentException('중복된 값이 있습니다.');
}
if ($bettingType[0] < 0) {
throw new \InvalidArgumentException('올바르지 않은 값이 있습니다.(0 미만)' . print_r($bettingType, true));
}
if (!$ignoreOver && Util::array_last($bettingType) >= count($this->info->candidates)) {
throw new \InvalidArgumentException('올바르지 않은 값이 있습니다.(초과)' . print_r($bettingType, true));
if (!$noValidate) {
foreach($bettingType as $bettingKey){
if(!key_exists($bettingKey, $this->info->candidates)){
throw new \InvalidArgumentException('올바른 후보가 아닙니다.' . print_r($bettingType, true));
}
}
}
return $bettingType;
}
public function closeBetting(): void
{
$db = DB::db();
$bettingStor = KVStorage::getStorage($db, 'betting');
$bettingID = $this->info->id;
$gameStor = KVStorage::getStorage($db, 'game_env');
//XXX: 베팅 종료 시점을 '현재 연월'로 하여 강제로 닫는다.
[$year, $month] = $gameStor->getValuesAsArray(['year', 'month']);
$this->info->closeYearMonth = Util::joinYearMonth($year, $month);
$bettingStor->setValue("id_{$bettingID}", $this->info->toArray());
}
public function convertBettingKey(array $bettingType): string
{
$bettingType = $this->purifyBettingKey($bettingType);
@@ -57,7 +95,8 @@ class Betting
return $this->info;
}
public function bet(int $generalID, ?int $userID, array $bettingType, int $amount): void{
public function bet(int $generalID, ?int $userID, array $bettingType, int $amount): void
{
$bettingInfo = $this->info;
if ($bettingInfo->finished) {
@@ -86,6 +125,7 @@ class Betting
throw new \RuntimeException('필요한 선택 수를 채우지 못했습니다.');
}
$resKey = $this->info->reqInheritancePoint?'유산포인트':'금';
$bettingTypeKey = $this->convertBettingKey($bettingType);
$inheritStor = KVStorage::getStorage($db, "inheritance_{$userID}");
@@ -93,7 +133,7 @@ class Betting
$prevBetAmount = $db->queryFirstField('SELECT sum(amount) FROM ng_betting WHERE betting_id = %i AND user_id = %i', $this->bettingID, $userID) ?? 0;
if ($prevBetAmount + $amount > 1000) {
throw new \RuntimeException((1000 - $prevBetAmount) . ' 포인트까지만 베팅 가능합니다.');
throw new \RuntimeException((1000 - $prevBetAmount) . $resKey.'까지만 베팅 가능합니다.');
}
if ($bettingInfo->reqInheritancePoint) {
@@ -103,7 +143,7 @@ class Betting
}
} else {
$remainPoint = $db->queryFirstField('SELECT gold FROM general WHERE no = %i', $generalID) ?? 0;
if ($remainPoint < GameConst::$generalMinimumGold + $amount) {
if ($remainPoint < GameConst::$minGoldRequiredWhenBetting + $amount) {
throw new \RuntimeException('금이 부족합니다.');
}
}
@@ -126,10 +166,16 @@ class Betting
$userLogger = new UserLogger($userID);
$userLogger->push("{$amount} 포인트를 베팅에 사용", "inheritPoint");
$userLogger->flush();
$db->update('rank_data', [
'value'=>$db->sqleval('value + %i', $amount)
], 'general_id = %i AND type = %s', $generalID, RankColumn::inherit_point_spent_dynamic->value);
} else {
$db->update('general', [
'gold' => $db->sqleval('gold - %i', $amount)
], 'no = %i', $generalID);
$db->update('rank_data', [
'value'=>$db->sqleval('value + %i', $amount)
], 'general_id = %i AND type = "betgold"', $generalID);
}
}
@@ -266,12 +312,12 @@ class Betting
//남은 상금은 '당첨자'에게 몰아준다.
//당첨자가 아무도 없다면, 0개 맞춘 그룹에게 돌아간다.
if($rewardAmount){
foreach(Util::range($selectCnt, -1, -1) as $matchPoint){
if ($rewardAmount) {
foreach (Util::range($selectCnt, -1, -1) as $matchPoint) {
if (!key_exists($matchPoint, $rewardAmount)) {
continue;
}
$rewardAmount[$matchPoint] += $rewardAmount;
$rewardAmount[$matchPoint] += $remainRewardAmount;
break;
}
}
@@ -304,12 +350,13 @@ class Betting
$db = DB::db();
if ($this->info->reqInheritancePoint) {
/** @var UserLogger[] */
$loggers = [];
/** @var Map<int,UserLogger> */
$loggers = new Map();
foreach ($rewardList as $rewardItem) {
if ($rewardItem['userID'] === null) {
continue;
}
/** @var int */
$userID = $rewardItem['userID'];
$amount = $rewardItem['amount'];
@@ -317,7 +364,12 @@ class Betting
$previousPoint = ($inheritStor->getValue('previous') ?? [0, 0])[0];
$nextPoint = $previousPoint + $amount;
$inheritStor->setValue('previous', [$nextPoint, 0]);
$inheritStor->invalidateCacheValue('previous');//XXX: 실제로는 previous 값을 사용할 수 없도록 락을 걸어야 한다.
$inheritStor->invalidateCacheValue('previous'); //XXX: 실제로는 previous 값을 사용할 수 없도록 락을 걸어야 한다.
$generalID = $rewardItem['generalID'];
$db->update('rank_data', [
'value'=>$db->sqleval('value + %i', $amount)
], 'general_id = %i AND type = %s', $generalID, RankColumn::inherit_point_earned_by_action->value);
$amountText = number_format($amount);
$previousPointText = number_format($previousPoint);
@@ -331,7 +383,7 @@ class Betting
$partialText = "베팅 부분 당첨({$matchPoint}/{$selectCnt})";
}
if (key_exists($userID, $loggers)) {
if ($loggers->hasKey($userID)) {
$userLogger = $loggers[$userID];
} else {
$userLogger = new UserLogger($userID);
@@ -347,17 +399,16 @@ class Betting
foreach ($loggers as $userLogger) {
$userLogger->flush();
}
} else {
$generalList = General::createGeneralObjListFromDB(array_unique(Util::squeezeFromArray($rewardList, 'generalID')), ['gold', 'npc'], 1);
$generalList = General::createGeneralObjListFromDB(array_unique(Util::squeezeFromArray($rewardList, 'generalID')), ['gold', 'npc', 'betgold'], 1);
foreach ($rewardList as $rewardItem) {
$gambler = $generalList[$rewardItem['generalID']];
$reward = Util::round($rewardItem['amount']);
$matchPoint = $rewardItem['matchPoint'];
$gambler->increaseVar('gold', $reward);
if (($gambler->getNPCType() == 0) || ($gambler->getNPCType() == 1 && $gambler->getRankVar('betgold', 0) > 0)) {
$gambler->increaseRankVar('betwingold', $reward);
$gambler->increaseRankVar('betwin', 1);
if (($gambler->getNPCType() == 0) || ($gambler->getNPCType() == 1 && $gambler->getRankVar(RankColumn::betgold, 0) > 0)) {
$gambler->increaseRankVar(RankColumn::betwingold, $reward);
$gambler->increaseRankVar(RankColumn::betwin, 1);
}
if ($matchPoint == $selectCnt) {
-7
View File
@@ -3,20 +3,13 @@
namespace sammo\Command\General;
use \sammo\DB;
use \sammo\Util;
use \sammo\JosaUtil;
use \sammo\General;
use \sammo\ActionLogger;
use \sammo\GameConst;
use \sammo\GameUnitConst;
use \sammo\LastTurn;
use \sammo\Command;
use function sammo\getMapTheme;
use function \sammo\printCitiesBasedOnDistance;
use function sammo\tryUniqueItemLottery;
use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper;
use sammo\CityConst;
+3 -1
View File
@@ -14,6 +14,8 @@ use \sammo\{
use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper;
use sammo\CityConst;
use sammo\Enums\InheritanceKey;
use function sammo\refreshNationStaticInfo;
use function sammo\getAllNationStaticInfo;
use function sammo\tryUniqueItemLottery;
@@ -162,7 +164,7 @@ class che_거병 extends Command\GeneralCommand{
$exp = 100;
$ded = 100;
$general->increaseInheritancePoint('active_action', 1);
$general->increaseInheritancePoint(InheritanceKey::active_action, 1);
$general->addExperience($exp);
$general->addDedication($ded);
$general->setVar('belong', 1);
+3 -4
View File
@@ -16,13 +16,12 @@ use \sammo\Json;
use function \sammo\tryUniqueItemLottery;
use function \sammo\getAllNationStaticInfo;
use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper;
use sammo\CityConst;
use sammo\Enums\InheritanceKey;
use function sammo\buildNationTypeClass;
use function sammo\refreshNationStaticInfo;
use function sammo\GetNationColors;
use function sammo\newColor;
class che_건국 extends Command\GeneralCommand
@@ -188,7 +187,7 @@ class che_건국 extends Command\GeneralCommand
refreshNationStaticInfo();
$general->increaseInheritancePoint('active_action', 1);
$general->increaseInheritancePoint(InheritanceKey::active_action, 1);
$this->setResultTurn(new LastTurn(static::getName(), $this->arg));
$general->checkStatChange();
tryUniqueItemLottery($general, '건국');
-2
View File
@@ -18,10 +18,8 @@ use \sammo\{
use function \sammo\getAllNationStaticInfo;
use function \sammo\getNationStaticInfo;
use function \sammo\newColor;
use function sammo\tryUniqueItemLottery;
use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper;
+4 -13
View File
@@ -2,23 +2,14 @@
namespace sammo\Command\General;
use \sammo\{
DB, Util, JosaUtil,
General, DummyGeneral,
ActionLogger,
DB, JosaUtil,
General,
GameConst,
LastTurn,
Json,
GameUnitConst,
Command,
ScoutMessage
};
use function \sammo\getAllNationStaticInfo;
use function \sammo\getNationStaticInfo;
use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper;
use sammo\Enums\InheritanceKey;
class che_등용수락 extends Command\GeneralCommand{
static protected $actionName = '등용 수락';
@@ -194,7 +185,7 @@ class che_등용수락 extends Command\GeneralCommand{
}
$db->update('nation', $setScoutNationValues, 'nation=%i', $destNationID);
$general->increaseInheritancePoint('active_action', 1);
$general->increaseInheritancePoint(InheritanceKey::active_action, 1);
$general->setVar('permission', 'normal');
$general->setVar('belong', 1);
$general->setVar('officer_level', 1);
@@ -19,6 +19,7 @@ use function \sammo\tryUniqueItemLottery;
use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper;
use sammo\CityConst;
use sammo\Enums\InheritanceKey;
use sammo\MustNotBeReachedException;
@@ -285,7 +286,7 @@ class che_랜덤임관 extends Command\GeneralCommand
$general->setAuxVar('joinedNations', $joinedNations);
}
$general->increaseInheritancePoint('active_action', 1);
$general->increaseInheritancePoint(InheritanceKey::active_action, 1);
$general->addExperience($exp);
$this->setResultTurn(new LastTurn(static::getName(), $this->arg));
$general->checkStatChange();
@@ -13,6 +13,7 @@ use \sammo\{
use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper;
use sammo\Enums\InheritanceKey;
use function sammo\tryRollbackInheritUniqueItem;
@@ -96,7 +97,7 @@ class che_모반시도 extends Command\GeneralCommand{
$lordLogger->pushGeneralHistoryLog("<D><b>{$generalName}</b></>의 모반으로 인해 <D><b>{$nationName}</b></>의 군주자리를 박탈당함");
$this->setResultTurn(new LastTurn(static::getName(), $this->arg));
$general->increaseInheritancePoint('active_action', 1);
$general->increaseInheritancePoint(InheritanceKey::active_action, 1);
$general->checkStatChange();
tryRollbackInheritUniqueItem($general);
$general->applyDB($db);
+3 -1
View File
@@ -13,6 +13,8 @@ use \sammo\{
use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper;
use sammo\CityConst;
use sammo\Enums\InheritanceKey;
use function sammo\DeleteConflict;
use function sammo\refreshNationStaticInfo;
use function sammo\tryRollbackInheritUniqueItem;
@@ -121,7 +123,7 @@ class che_방랑 extends Command\GeneralCommand{
], 'me=%i OR you=%i', $nationID, $nationID);
refreshNationStaticInfo();
$general->increaseInheritancePoint('active_action', 1);
$general->increaseInheritancePoint(InheritanceKey::active_action, 1);
$this->setResultTurn(new LastTurn(static::getName(), $this->arg));
tryRollbackInheritUniqueItem($general);
$general->applyDB($db);
+2 -1
View File
@@ -19,6 +19,7 @@ use function\sammo\tryUniqueItemLottery;
use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper;
use sammo\Enums\InheritanceKey;
use function sammo\tryRollbackInheritUniqueItem;
@@ -135,7 +136,7 @@ class che_선양 extends Command\GeneralCommand
$logger->pushGeneralHistoryLog("<D><b>{$nationName}</b></>의 군주자리를 <Y>{$destGeneralName}</>에게 선양");
$destLogger->pushGeneralHistoryLog("<D><b>{$nationName}</b></>의 군주자리를 물려 받음");
$general->increaseInheritancePoint('active_action', 1);
$general->increaseInheritancePoint(InheritanceKey::active_action, 1);
$this->setResultTurn(new LastTurn(static::getName(), $this->arg));
$general->checkStatChange();
tryRollbackInheritUniqueItem($general);
@@ -5,21 +5,13 @@ namespace sammo\Command\General;
use \sammo\DB;
use \sammo\Util;
use \sammo\JosaUtil;
use \sammo\Session;
use \sammo\KVStorage;
use \sammo\General;
use \sammo\ActionLogger;
use \sammo\GameConst;
use \sammo\GameUnitConst;
use \sammo\LastTurn;
use \sammo\Command;
use \sammo\ServConfig;
use function \sammo\getDexCall;
use function sammo\getDexLevelList;
use function \sammo\tryUniqueItemLottery;
use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper;
+1 -6
View File
@@ -2,18 +2,13 @@
namespace sammo\Command\General;
use \sammo\{
DB, Util, JosaUtil,
General,
ActionLogger,
GameConst, GameUnitConst,
DB,
LastTurn,
Command
};
use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper;
use function sammo\tryRollbackInheritUniqueItem;
use function sammo\tryUniqueItemLottery;
class che_은퇴 extends Command\GeneralCommand{
-7
View File
@@ -3,20 +3,13 @@
namespace sammo\Command\General;
use \sammo\DB;
use \sammo\Util;
use \sammo\JosaUtil;
use \sammo\General;
use \sammo\ActionLogger;
use \sammo\GameConst;
use \sammo\GameUnitConst;
use \sammo\LastTurn;
use \sammo\Command;
use function sammo\getMapTheme;
use function \sammo\printCitiesBasedOnDistance;
use function sammo\tryUniqueItemLottery;
use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper;
use sammo\CityConst;
@@ -17,7 +17,7 @@ use function \sammo\pickGeneralFromPool;
use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper;
use sammo\Enums\InheritanceKey;
class che_인재탐색 extends Command\GeneralCommand
{
@@ -210,7 +210,7 @@ class che_인재탐색 extends Command\GeneralCommand
$exp = 200;
$ded = 300;
$general->increaseInheritancePoint('active_action', Util::valueFit(sqrt(1 / $foundProp), 1));
$general->increaseInheritancePoint(InheritanceKey::active_action, Util::valueFit(sqrt(1 / $foundProp), 1));
$general->increaseVarWithLimit('gold', -$reqGold, 0);
$general->increaseVarWithLimit('rice', -$reqRice, 0);
$general->addExperience($exp);
+2 -10
View File
@@ -6,25 +6,17 @@ use \sammo\{
DB,
Util,
JosaUtil,
General,
ActionLogger,
GameConst,
GameUnitConst,
LastTurn,
Command,
Json,
KVStorage
};
use function \sammo\tryUniqueItemLottery;
use function \sammo\getInvitationList;
use function \sammo\getNationStaticInfo;
use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper;
use sammo\CityConst;
use sammo\Enums\InheritanceKey;
class che_임관 extends Command\GeneralCommand
{
@@ -183,7 +175,7 @@ class che_임관 extends Command\GeneralCommand
$general->setAuxVar('joinedNations', $joinedNations);
}
$general->increaseInheritancePoint('active_action', 1);
$general->increaseInheritancePoint(InheritanceKey::active_action, 1);
$general->addExperience($exp);
$this->setResultTurn(new LastTurn(static::getName(), $this->arg));
$general->checkStatChange();
@@ -180,6 +180,14 @@ class che_장비매매 extends Command\GeneralCommand
$general->increaseVarWithLimit('gold', $cost / 2);
$general->onArbitraryAction($general, '장비매매', '판매', ['itemCode' => $itemCode]);
$general->setItem($itemType, null);
if(!$itemObj->isBuyable()){
$generalName = $general->getName();
$josaYi = JosaUtil::pick($generalName, '이');
$nationName = $general->getStaticNation()['name'];
$logger->pushGlobalActionLog("<Y>{$generalName}</>{$josaYi} <C>{$itemName}</>{$josaUl} 판매했습니다!");
$logger->pushGlobalHistoryLog("<R><b>【판매】</b></><D><b>{$nationName}</b></>의 <Y>{$generalName}</>{$josaYi} <C>{$itemName}</>{$josaUl} 판매했습니다!");
}
}
$exp = 10;

Some files were not shown because too many files have changed in this diff Show More