Compare commits

...
131 Commits
Author SHA1 Message Date
Hide_D ac6e1d2525 fix: 1개 선택 베팅 보상 예측값이 잘못 설정된 버그 2022-02-24 00:22:27 +09:00
Hide_D 610b74d3a5 game: 표준 공백지 시나리오에 천통 베팅 추가 2022-02-24 00:15:36 +09:00
Hide_D 7f295aaacf fix: 탑 바 메뉴에서 세력도 제거. 세력도 페이지 제거 2022-02-23 23:55:18 +09:00
Hide_D a47669ff75 feat: 연감에 기존 세력도 기능 통합 2022-02-23 23:46:40 +09:00
Hide_D 9f84eb8d4d game,feat: 소비형 아이템 효율 상승, 환약 3회용으로 변경 2022-02-23 01:41:24 +09:00
Hide_D 5f36143b44 game: 숙련도로 얻는 유산 포인트 감소 2022-02-23 00:21:02 +09:00
Hide_D 2d491dd393 fix: 2회 이상 연속 전투에 성벽 전투가 포함된 경우 대인 사살이 계산되지 않는 버그 2022-02-22 23:55:13 +09:00
Hide_D 63845afdc3 fix: 재난 시 전체 이벤트 처리를 위해 column 추가 2022-02-22 15:39:43 +09:00
Hide_D 3cfcfff786 fix: 방어 대상에 crewtype 포함 2022-02-22 14:41:37 +09:00
Hide_D 9f801df5dc game: 평시 유니크 획득 확률 변경 2022-02-22 00:43:22 +09:00
Hide_D 21b8c6ea8f game: 작위 보상에서 아이템이 없는 사람이 받을 확률 대폭 증가 2022-02-22 00:28:35 +09:00
Hide_D 0807f9912c game: 반계도구 제거, 도구 밸런스 조정 2022-02-22 00:14:20 +09:00
Hide_D 90a71ba75d fix: 아이템 판매시 에러 방지 2022-02-20 15:31:52 +09:00
Hide_D 2e26244992 fix: 전투력보정에 unit이 제공되지 않음 2022-02-20 15:13:39 +09:00
Hide_D 8f1e713451 fix: 이벤트로 모든 장수의 지출이 0인 경우 대비 2022-02-20 14:57:56 +09:00
Hide_D b7b5c7b0da game: 아이템을 실제로 사용할 수 있도록 등록 2022-02-20 14:51:04 +09:00
Hide_D cb42813597 fix: 오타 수정 2022-02-20 05:11:26 +09:00
Hide_D 91c46f465b feat,game: 장비매매시 반응하는 트리거 추가, 판매시 국고에 추가되는 유니크 추가 2022-02-20 04:34:10 +09:00
Hide_D 435044dddd feat: 임의 커맨드용 트리거 추가 2022-02-20 04:30:05 +09:00
Hide_D cccf9968e7 game: 의술 유니크 추가 2022-02-20 04:10:34 +09:00
Hide_D f1e4185193 game: 비전투 커맨드 효율 유니크 추가 2022-02-20 04:02:35 +09:00
Hide_D dc538af7ba game,feat: 추가 숙련 trigger추가, 숙련 유니크 추가 2022-02-20 04:01:55 +09:00
Hide_D 574ca07afe game,feat: 조달 효율 변경 trigger 추가, 조달 유니크 추가 2022-02-20 04:01:03 +09:00
Hide_D f18b2ed1a5 fix: 능력치 유니크 오타 수정 2022-02-20 03:38:50 +09:00
Hide_D bc568e2083 game: 전투 특기 반영 유니크 도구 추가 2022-02-20 03:37:15 +09:00
Hide_D bffdf9d190 game: 1회저지, 회피저지 유니크 추가 2022-02-20 03:17:35 +09:00
Hide_D e7af4563a2 feat,game: 반계불가 처리 추가, 반계불가 유니크 추가 2022-02-20 03:16:46 +09:00
Hide_D 5fc5adb14d feat,game: 전투 중 약탈 추가, 약탈 유니크 추가 2022-02-20 03:13:03 +09:00
Hide_D f3ccf5e633 game: 경과 시간에 따라 변하는 유니크 추가 2022-02-20 03:12:17 +09:00
Hide_D 46cacc4a7d game,feat: 계략 커맨드 방어 유니크
- 계략 방어 확률에 보정 trigger 추가
2022-02-20 03:11:02 +09:00
Hide_D ac8edcee32 game: 회피 유니크 조절 2022-02-20 03:09:59 +09:00
Hide_D 919c44c727 game,feat: 전투력보정 관련 유니크 도구 추가
- 직접 전투력보정을 위한 WarUnitTrigger 추가
2022-02-20 03:08:24 +09:00
Hide_D 95921ae727 game: 사기, 훈련 유니크 수치 변경 2022-02-20 03:04:45 +09:00
Hide_D 134f043e9c refac: 아이템에 미사용 $id 값 제거 2022-02-19 23:54:03 +09:00
Hide_D a7a14a66a6 game: 벽력거를 진짜 무상성 병종으로 2022-02-19 17:55:29 +09:00
Hide_D 148d92164a refac: 장수 생성시 임관권유문 문구 변경
- coreui/vue 의존성 제거
2022-02-18 21:15:06 +09:00
Hide_D 5ea1b0bce4 refac: toast 출력을 bootstrap-vue-3 내부 toast로 변경
- component로 src 내부 ts/vue 사용 시도 중
2022-02-18 20:54:26 +09:00
Hide_D 65aefadcdc dep: package updates 2022-02-18 13:39:46 +09:00
Hide_D 1bc324fb9f fix: turnExecutionHelper env 관련 수정 2022-02-18 11:27:29 +09:00
Hide_D 28953ae1d9 fix: 토너먼트 참가 시점에서 생존여부 확인 2022-02-18 10:55:25 +09:00
Hide_D 3760e244a9 scenario: 천지비급에 '견고' 추가 2022-02-16 22:55:47 +09:00
Hide_D e86d755b69 scenario: 천지비급에서는 183년 이전에 항상 상인 2022-02-16 22:52:01 +09:00
Hide_D 6f560a1b34 버그 수정 2022-02-14 00:26:42 +09:00
Hide_D 6fe573ef7b fix: 토너먼트 실행 주기에서 초기화시 '수동'뜨는 문제 2022-02-08 20:39:49 +09:00
Hide_D 2a7baf020f misc: 연도 갱신 2022-02-06 12:08:58 +09:00
Hide_D 2e1815783a fix: 커맨드 세부 선택시 스탯 표기 오류 수정
- 통/무/지 순이어야함
2022-02-06 12:06:14 +09:00
Hide_DandGitea bab86c9f0b feat: 변경된 베팅 방식에 따라 결과 표기 2022-02-05 07:43:28 +00:00
Hide_DandGitea 2716e9af39 refac: 베팅 코드를 모듈로 2022-02-05 07:43:28 +00:00
Hide_DandGitea 9a303c4510 fix: n차 혼합 베팅 보상 수령이 하나만 되는 버그 수정 2022-02-05 07:43:28 +00:00
Hide_DandGitea e547971a6f feat: 베팅시 유산포인트 로그에 추가 2022-02-05 07:43:28 +00:00
Hide_DandGitea e9108ead86 feat: 베팅 보상 등록 2022-02-05 07:43:28 +00:00
Hide_DandGitea 6bbcb25138 feat(WIP): 베팅 보상 누락 수정 2022-02-05 07:43:28 +00:00
Hide_DandGitea 98462ca34d feat(WIP): 보상을 위한 Betting 모듈 추가 2022-02-05 07:43:28 +00:00
Hide_DandGitea 7939dd0b44 feat: 메인 페이지에 토너먼트 개최기간 표기 2022-02-05 07:43:27 +00:00
Hide_DandGitea 3d966ec076 fix: 베팅시 추가 포인트 부여 불가 2022-02-05 07:43:27 +00:00
Hide_DandGitea 6afedb35df Revert "fix: 베팅시 추가 포인트 부여 불가"
This reverts commit 6fb4a1b274.
2022-02-05 07:43:27 +00:00
Hide_DandGitea cdac63e05a fix: 베팅시 추가 포인트 부여 불가 2022-02-05 07:43:27 +00:00
Hide_DandGitea 8040cc28c4 fix: 베팅 순서 수정 2022-02-05 07:43:27 +00:00
Hide_DandGitea 264db40bdc fix: 베팅 관련 사소한 버그 수정
- 베팅이 없을 경우
- 베팅 동시 신청
2022-02-05 07:43:27 +00:00
Hide_DandGitea 2da1957c28 feat: 국가 베팅 ui 2022-02-05 07:43:27 +00:00
Hide_DandGitea 2297fa9c13 fix: NPCControl volar error 2022-02-05 07:43:27 +00:00
Hide_DandGitea 8175e76a77 build: warning 기준 변경
- 5MB, 3MB.......
2022-02-05 07:43:27 +00:00
Hide_DandGitea 2709dde8fa fix: template 2022-02-05 07:43:27 +00:00
Hide_DandGitea 7c518efba8 fix: volar error 수정
- getNPCColor 반환형
2022-02-05 07:43:27 +00:00
Hide_DandGitea b5fa2aef91 game: npc 색상 분리 2022-02-05 07:43:27 +00:00
Hide_DandGitea d2f6c34e85 fix: 베팅 시 key 정렬을 숫자 정렬로 2022-02-05 07:43:27 +00:00
Hide_DandGitea cd1ccfadaf fix: 세력일람 분석에서 자동수행턴을 반영하지 않는 버그 수정 2022-02-05 07:43:27 +00:00
Hide_DandGitea 8ff6bff252 game: 장수 생성시 종능이 부족하면 경고 2022-02-05 07:43:27 +00:00
Hide_DandGitea 52f6cb2f30 fix: 피장파장 시, 턴이 60턴이 늘어나는 것이 아니라 60턴이 되는 버그 수정 2022-02-05 07:43:27 +00:00
Hide_DandGitea e7af718a0f feat(WIP): 국가 베팅 '기능만' 구현 2022-02-05 07:43:27 +00:00
Hide_DandGitea d211c92bf8 fix: type react가 volar에서 문제를 일으킴 2022-02-05 07:43:27 +00:00
Hide_DandGitea 4acc988cfe feat(WIP): 베팅 개시 타입 변경
-candidate를 미리 추가.
-이를 통해 betting을 중립적으로 운용 가능
2022-02-05 07:43:27 +00:00
Hide_DandGitea 270f236f95 feat(WIP): OpenNationBetting에 보너스 상금 추가 2022-02-05 07:43:27 +00:00
Hide_DandGitea 2da12bb71f fix: 이벤트 조건 오류 수정 2022-02-05 07:43:27 +00:00
Hide_DandGitea b479add03d misc: OpenNationBetting TODO 추가 2022-02-05 07:43:27 +00:00
Hide_DandGitea ca9db6dc18 Feat(WIP): OpenNationBetting Action 추가
- 시나리오 event에 추가
2022-02-05 07:43:27 +00:00
Hide_DandGitea 12c7c7b4ed feat(WIP): 이벤트 시나리오에서 불가능한 커맨드 지정 2022-02-05 07:43:27 +00:00
Hide_DandGitea e12c0e51c8 fix: 시나리오 모드에서 시작시점과 봉급월이 겹치는 경우 멈추는 문제 수정 2022-02-05 07:43:27 +00:00
Hide_DandGitea 6683c70195 fix: N장만 건국한 경우에 CreateManyNPC가 동작하지 않는 버그 수정 2022-02-05 07:43:27 +00:00
Hide_DandGitea aef1cbd201 fix: 봉급 계산에서 부대장 처리를 하지 않은 문제 수정
- 전체 지출 계산에만 실수 발생
2022-02-05 07:43:27 +00:00
Hide_DandGitea 06786aff28 feat(WIP): 이벤트 시나리오 준비 2022-02-05 07:43:27 +00:00
Hide_DandGitea 55439c268f feat: Event/Condition/RemainNation 추가 2022-02-05 07:43:27 +00:00
Hide_DandGitea 3e4cf764c8 feat: 시나리오 event 포맷에서 target, priority 추가 2022-02-05 07:43:27 +00:00
Hide_DandGitea 4e359f5eb9 feat: 도시 점령, 국가 멸망 시 트리거 추가 2022-02-05 07:43:27 +00:00
Hide_DandGitea 2ff3746df2 feat: event 테이블 준비 2022-02-05 07:43:27 +00:00
Hide_DandGitea 62982d7ffb feat(WIP): 베팅 상세 정보 반환 2022-02-05 07:43:27 +00:00
Hide_DandGitea ec49cdb6ad feat: Global/GetNationList 추가
- 세력일람의 데이터와 원칙적으로 동일
2022-02-05 07:43:27 +00:00
Hide_DandGitea 4b64827f20 feat(WIP): 베팅 관련 작업중 2022-02-05 07:43:27 +00:00
Hide_DandGitea 944c4cb564 dep: DTO 2022-02-05 07:43:27 +00:00
Hide_DandGitea db19655b60 feat: ng_betting 테이블 추가 2022-02-05 07:43:27 +00:00
Hide_D 1975f11338 fix: 이전 로그 키 정렬 기준이 int가 아니라 string인 버그 수정 2022-02-04 12:55:37 +09:00
Hide_D 59515d5276 game: 이민족 발동 관련 변경
- 이민족 멸망 후 타국가 임관
- 이민족 발동 시 명성을 평균치로
2022-01-21 01:00:31 +09:00
Hide_D fea9529bc8 fix: 내무부, 기밀 제한이 잘못된 버그 수정 2022-01-07 19:40:35 +09:00
Hide_D 1f6259c157 game: 기병 공성 능력 약화, 수비시 공방 각각 5% 손해 2022-01-05 01:00:13 +09:00
Hide_D 8908e12c59 game: 유산으로 입찰된 유니크는 랜덤 유니크로 얻을 수 없음 2022-01-04 23:53:57 +09:00
Hide_D a7d6bc2c5c fix: 자동 사령턴 미 활성화 시 내정보&설정 에러 2022-01-04 06:32:45 +09:00
Hide_D 97fd807c2c fix: 단궁, 맥궁 증가 사기 표기량 수정 2022-01-03 22:45:27 +09:00
Hide_D b31f7d64ec game: 이중 격노가 발동하지 않도록 수정 2022-01-03 22:38:42 +09:00
Hide_D bdd574161e fix: 마지막 국가는 임관 불가능한 것처럼 나오는 버그 수정 2022-01-02 23:01:46 +09:00
Hide_D e23e36cbfa fix: 임관 제어 코드에서 () 누락 2022-01-02 22:50:42 +09:00
Hide_D fb796e21e4 fix: starts_with에 사소한 오류가 있어보임
- 이유는 잘 모르겠지만 starts_with($this->destNation['name'], 'ⓤ')
2022-01-02 22:46:32 +09:00
Hide_D dd46c02f09 feat: 게시판 500px 모드 2022-01-02 00:58:34 +09:00
Hide_D d1835c71b7 game: U국의 유저장간 거리를 4->3로 변경 2022-01-01 23:30:33 +09:00
Hide_D 55332864ad game: 토너먼트 자동 채우기 난이도 수정 2022-01-01 01:22:23 +09:00
Hide_D 96a8ef3bcc fix: 전금 증가 횟수 누락 2021-12-31 23:24:15 +09:00
Hide_D 79cfbfe83b fix: 전쟁 금지 설정 누락 부분 수정 2021-12-31 23:22:20 +09:00
Hide_D e7fa95ce8f fix: front에서 둔전 수입 계산 수정 2021-12-31 23:07:42 +09:00
Hide_D a819dde71c fix: 세수 표기를 잘못 반영하는 버그 수정 2021-12-31 23:05:22 +09:00
Hide_D 281cfd366b build: d_setting json ignore 2021-12-31 17:58:36 +09:00
Hide_D f1ba7e76f3 fix-build: install.php 초기 경로 관련 문제 수정 2021-12-31 17:55:29 +09:00
Hide_D 2da72d9b1a build: postcss 설정
- discard-dedupe
- autoprefixer
2021-12-31 17:33:15 +09:00
Hide_D 4cdc18fe7e misc: 사소하게 수정 2021-12-31 04:41:08 +09:00
Hide_D 4400116bdd feat: 내무부 변경 2021-12-31 04:12:37 +09:00
Hide_D 086d6d1ab5 misc: toast 내부 정리 2021-12-31 02:25:43 +09:00
Hide_D 02e86fd2e9 feat: toast내부 div 객체가 무한히 쌓이지 않도록 2021-12-31 02:22:42 +09:00
Hide_D 7310aa6971 feat(WIP): 내무부 국방/임관권유문 에디터 완료. 2021-12-30 22:50:33 +09:00
Hide_D 4927a26c92 misc: makeAPIPath 흔적 2021-12-29 05:50:21 +09:00
Hide_D ee6bec2e0d feat: APIPathGen 추상화 2021-12-29 05:46:35 +09:00
Hide_D def230bf30 feat: ts APICall을 강제화.
- 오버 엔지니어링의 정석
2021-12-29 03:55:40 +09:00
Hide_D 0a4d568b06 feat(WIP): 내무부 2021-12-28 04:29:13 +09:00
Hide_D 69f8e1f1bd feat: APIPathGen 도우미 2021-12-28 04:28:26 +09:00
Hide_D 6f2cb4e05e misc: 미사용 파일 제거 2021-12-27 21:54:23 +09:00
Hide_D db1fbb700c feat: 턴 선택기에서 '턴' 부분 선택 시 커맨드로 선택 2021-12-26 23:57:20 +09:00
Hide_D 842a37eb7b fix: 턴 선택기 홀짝 색 선택 오류 수정 2021-12-26 23:43:01 +09:00
Hide_D 76ff38ed10 feat: 사령부 턴 선택기 추가, 턴 해제 옵션 추가 2021-12-26 23:37:53 +09:00
Hide_D db6b2be101 feat: 턴 선택기에서 '드래그' 선택 지원 2021-12-26 23:22:43 +09:00
Hide_D a998500839 feat: DragSelect 추가
- Vue2 버전을 Vue3로 이식
2021-12-26 22:32:04 +09:00
Hide_D dd5e686d03 game: 유니크 명마, 명검, 서적 갯수 2배
- 말 유니크로 백상, 오환마, 흉노마, 의남백마, 옥추마, 화종마, 옥란백용구 추가
  - 백상, 옥란백용구는 특수효과 부여
2021-12-26 20:44:32 +09:00
Hide_D c9f28e27d2 feat: 소모 군량 보정을 위한 trigger 추가 2021-12-26 20:06:39 +09:00
Hide_D 1bbeb4f50d fix: 급습에서 대상국에 메시지가 뜨지 않음 2021-12-26 18:46:50 +09:00
Hide_D 410f6b261e fix: processing $destNation 구분 버그 2021-12-26 04:19:26 +09:00
287 changed files with 8999 additions and 3295 deletions
+1 -1
View File
@@ -5,7 +5,7 @@ module.exports = {
"browser": true,
"es2021": true
},
ignorePatterns: ['*.test.ts', '.eslintrc.cjs', 'webpack.config.cjs', '*.js'],
ignorePatterns: ['*.test.ts', '.eslintrc.cjs', 'postcss.config.cjs', 'webpack.config.cjs', '*.js'],
overrides: [{
files: ['*.ts', '*.tsx', "*.vue"],
}],
+1
View File
@@ -43,6 +43,7 @@ d_pic/uploaded_image
d_setting/*.php
*/d_setting/*.php
*/d_setting/*.json
*/d_setting/templates/*.php
!*.orig.php
+1 -6
View File
@@ -52,7 +52,7 @@ return [
'hwe/b_betting.php',
'hwe/v_chiefCenter.php',
'hwe/b_currentCity.php',
'hwe/b_dipcenter.php',
'hwe/v_nationStratFinan.php',
'hwe/b_diplomacy.php',
'hwe/b_genList.php',
'hwe/b_myBossInfo.php',
@@ -64,7 +64,6 @@ return [
'hwe/b_tournament.php',
'hwe/b_troop.php',
'hwe/c_auction.php',
'hwe/c_dipcenter.php',
'hwe/c_tournament.php',
'hwe/c_vote.php',
'hwe/func_auction.php',
@@ -91,7 +90,6 @@ return [
'hwe/j_board_article_add.php',
'hwe/j_board_comment_add.php',
'hwe/j_board_get_articles.php',
'hwe/j_chief_turn.php',
'hwe/j_die_immediately.php',
'hwe/j_diplomacy_destroy_letter.php',
'hwe/j_diplomacy_get_letter.php',
@@ -102,7 +100,6 @@ return [
'hwe/j_general_log_old.php',
'hwe/j_general_set_permission.php',
'hwe/j_get_basic_general_list.php',
'hwe/j_getChiefTurn.php',
'hwe/j_get_city_list.php',
'hwe/j_get_general_list.php',
'hwe/j_get_nation_general_list.php',
@@ -126,8 +123,6 @@ return [
'hwe/j_select_npc.php',
'hwe/j_select_picked_general.php',
'hwe/j_server_basic_info.php',
'hwe/j_set_chief_command.php',
'hwe/j_set_general_command.php',
'hwe/j_set_my_setting.php',
'hwe/j_set_npc_control.php',
'hwe/j_simulate_battle.php',
+1 -1
View File
@@ -1,6 +1,6 @@
The MIT License
Copyright (c) 2021 Hide_D, 62che
Copyright (c) 2022 Hide_D, 62che
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
+2 -1
View File
@@ -29,7 +29,8 @@
"erusev/parsedown-extra": "^0.8.1",
"nette/caching": "^3.0",
"illuminate/database": "^8.61",
"illuminate/events": "^8.61"
"illuminate/events": "^8.61",
"spatie/data-transfer-object": "^3.7"
},
"autoload": {
"psr-4": {
Generated
+64 -1
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": "94cfbcb22b9f475e421ad5009391006f",
"content-hash": "1983b89436fd8017db508592ddf542e4",
"packages": [
{
"name": "brandonwamboldt/utilphp",
@@ -2636,6 +2636,69 @@
},
"time": "2021-06-29T04:31:23+00:00"
},
{
"name": "spatie/data-transfer-object",
"version": "3.7.3",
"source": {
"type": "git",
"url": "https://github.com/spatie/data-transfer-object.git",
"reference": "341f72c77e0fce40ea2e0dcb212cb54dc27bbe72"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/spatie/data-transfer-object/zipball/341f72c77e0fce40ea2e0dcb212cb54dc27bbe72",
"reference": "341f72c77e0fce40ea2e0dcb212cb54dc27bbe72",
"shasum": ""
},
"require": {
"php": "^8.0"
},
"require-dev": {
"illuminate/collections": "^8.36",
"jetbrains/phpstorm-attributes": "^1.0",
"larapack/dd": "^1.1",
"phpunit/phpunit": "^9.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Spatie\\DataTransferObject\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Brent Roose",
"email": "brent@spatie.be",
"homepage": "https://spatie.be",
"role": "Developer"
}
],
"description": "Data transfer objects with batteries included",
"homepage": "https://github.com/spatie/data-transfer-object",
"keywords": [
"data-transfer-object",
"spatie"
],
"support": {
"issues": "https://github.com/spatie/data-transfer-object/issues",
"source": "https://github.com/spatie/data-transfer-object/tree/3.7.3"
},
"funding": [
{
"url": "https://spatie.be/open-source/support-us",
"type": "custom"
},
{
"url": "https://github.com/spatie",
"type": "github"
}
],
"time": "2021-12-30T20:31:10+00:00"
},
{
"name": "symfony/console",
"version": "v5.3.10",
+4 -4
View File
@@ -59,10 +59,10 @@ $db = DB::db();
if ($general['block'] > 0) {
$style .= "background-color:red;";
}
if ($general['npc'] >= 2) {
$style .= "color:cyan;";
} elseif ($general['npc'] == 1) {
$style .= "color:skyblue;";
$npcColor = getNPCColor($general['npc']);
if($npcColor !== null){
$style .= "color:{$npcColor};";
}
echo "
+4 -7
View File
@@ -70,13 +70,10 @@ function colorBlockedName($general)
if ($general['block'] > 0) {
$style .= "background-color:red;";
}
if ($general['npc'] >= 2) {
$style .= "color:cyan;";
} elseif ($general['npc'] == 1) {
$style .= "color:skyblue;";
}
if ($general['con'] > $conlimit) {
$style .= "color:red;";
$npcColor = getNPCColor($general['npc']);
if($npcColor !== null){
$style .= "color:{$npcColor};";
}
echo "
+1 -7
View File
@@ -155,13 +155,7 @@ if ($gameStor->isunited) {
if ($general['npc'] >= 2) {
$name = "<font color=cyan>{$general['name']}</font>";
} elseif ($general['npc'] == 1) {
$name = "<font color=skyblue>{$general['name']}</font>";
} else {
$name = "{$general['name']}";
}
$name = formatName($general['name'], $general['npc']);
if (key_exists($general['owner'], $ownerNameList)) {
$name = $name . '<br><small>(' . $ownerNameList[$general['owner']] . ')</small>';
+43 -29
View File
@@ -5,7 +5,7 @@ namespace sammo;
include "lib.php";
include "func.php";
$btn = Util::getReq('btn');
$yearmonth = Util::getReq('yearmonth', 'int');
$yearMonth = Util::getReq('yearmonth', 'int');
$serverID = Util::getReq('serverID', 'string', null);
//로그인 검사
@@ -36,7 +36,7 @@ if ($con >= 2) {
[$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 = $s_year * 12 + $s_month;
$s = Util::joinYearMonth($s_year, $s_month);
if ($s_year === null) {
echo '인자 에러';
@@ -44,7 +44,7 @@ if ($s_year === null) {
}
[$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 = $e_year * 12 + $e_month;
$e = Util::joinYearMonth($e_year, $e_month);
if ($serverID !== UniqueConst::$serverID) {
$mapTheme = $db->queryFirstField('SELECT map FROM ng_games WHERE server_id=%s', $serverID) ?: 'che';
@@ -53,42 +53,47 @@ if ($serverID !== UniqueConst::$serverID) {
}
//FIXME: $yearmonth가 올바르지 않을 경우에 처리가 필요.
if ($serverID !== UniqueConst::$serverID && !$yearmonth) {
$year = $s_year;
$month = $s_month;
} else if (!$yearmonth) {
$year = $admin['year'];
$month = $admin['month'] - 1;
if ($serverID !== UniqueConst::$serverID && !$yearMonth) {
$yearMonth = $s;
} else if (!$yearMonth) {
$yearMonth = Util::joinYearMonth($admin['year'], $admin['month']);
} else {
$year = intdiv($yearmonth, 100);
$month = $yearmonth % 100;
if ($btn == "◀◀ 이전달") {
$month -= 1;
$yearMonth -= 1;
} elseif ($btn == "다음달 ▶▶") {
$month += 1;
$yearMonth += 1;
}
}
$now = ($year * 12) + $month;
if ($now < $s) {
$now = $s;
$isCurrent = false;
if ($yearMonth < $s) {
$yearMonth = $s;
}
if ($now > $e) {
$now = $e;
if ($yearMonth > $e) {
$isCurrent = true;
$yearMonth = $e + 1;
}
$year = intdiv($now, 12);
$month = $now % 12;
if ($month <= 0) {
$year -= 1;
$month += 12;
[$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;
}
$history = $db->queryFirstRow('SELECT * FROM ng_history WHERE server_id = %s AND year = %i AND month = %i', $serverID, $year, $month);
if($isCurrent){
$history = getCurrentHistory();
}
else{
$history = getHistory($serverID, $year, $month);
}
$nations = Json::decode($history['nations']);
$nations = $history['nations'];
?>
<!DOCTYPE html>
<html>
@@ -129,7 +134,7 @@ $nations = Json::decode($history['nations']);
<input type=submit name=btn value="◀◀ 이전달">
<select id='yearmonth' name=yearmonth size=1>
<option selected='selected'><?= $year ?>년 <?= $month ?>월</option>
<option><?= $e_year ?>년 12월</option>
<option><?= $e_year ?>년 12월 (현재)</option>
</select>
<input type=submit name=btn value='조회하기'>
<input type=submit name=btn value="다음달 ▶▶">
@@ -177,7 +182,7 @@ $nations = Json::decode($history['nations']);
</tr>
<tr>
<td colspan=5 valign=top>
<?= formatHistoryToHTML(Json::decode($history['global_history'])) ?>
<?= formatHistoryToHTML($history['global_history']) ?>
</td>
</tr>
<tr>
@@ -185,7 +190,7 @@ $nations = Json::decode($history['nations']);
</tr>
<tr>
<td colspan=5 valign=top>
<?= formatHistoryToHTML(Json::decode($history['global_action'])) ?>
<?= formatHistoryToHTML($history['global_action']) ?>
</td>
</tr>
</tbody>
@@ -201,6 +206,13 @@ $nations = Json::decode($history['nations']);
<script>
window.serverNick = '<?= DB::prefix() ?>';
window.serverID = '<?= UniqueConst::$serverID ?>';
<?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,
@@ -209,6 +221,8 @@ $nations = Json::decode($history['nations']);
year: <?= $year ?>,
month: <?= $month ?>,
});
<?php endif; ?>
</script>
</body>
+3 -8
View File
@@ -10,7 +10,7 @@ $userID = Session::getUserID();
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
$gameStor->cacheValues(['killturn', 'autorun_user', 'turnterm']);
increaseRefresh("세력일람", 2);
$me = $db->queryFirstRow('SELECT con, turntime FROM general WHERE owner=%i', $userID);
@@ -33,6 +33,7 @@ if ($con >= 2) {
<?= 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', 'extKingdoms']) ?>
<?= WebUtil::printStaticValues($gameStor->getValues(['killturn', 'autorun_user', 'turnterm'])) ?>
</head>
<body>
@@ -144,13 +145,7 @@ if ($con >= 2) {
<tr>
<td colspan=8> 장수 일람 : ";
foreach ($generals as $general) {
if ($general['npc'] >= 2) {
echo "<font color=cyan>{$general['name']}</font>, ";
} elseif ($general['npc'] == 1) {
echo "<font color=skyblue>{$general['name']}</font>, ";
} else {
echo "{$general['name']}, ";
}
echo formatName($general['name'], $general['npc']).', ';
}
echo "
</td>
-88
View File
@@ -1,88 +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("세력도", 2);
TurnExecutionHelper::executeAllCommand();
$mapTheme = $gameStor->map_theme ?? 'che';
$me = $db->queryFirstRow('SELECT con,turntime from general where owner=%i', $userID);
$con = checkLimit($me['con']);
if ($con >= 2) {
printLimitMsg($me['turntime']);
exit();
}
?>
<!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::printCSS('../d_shared/common.css') ?>
<?= WebUtil::printCSS('css/normalize.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::printJS('../d_shared/common_path.js') ?>
<?= WebUtil::printJS('d_shared/base_map.js') ?>
<?= WebUtil::printDist('ts', ['common', 'map']) ?>
<script>
window.serverNick = '<?= DB::prefix() ?>';
window.serverID = '<?= UniqueConst::$serverID ?>';
$(function() {
reloadWorldMap({
neutralView: true,
showMe: true,
useCachedMap: true
});
});
</script>
</head>
<body>
<table align=center width=1200 class='tb_layout bg0'>
<tr>
<td>세 력 도<br><?= closeButton() ?></td>
</tr>
</table>
<table align=center width=1200 height=520 class='tb_layout bg0'>
<tr height=520>
<td width=498 valign=top>
<?= formatHistoryToHTML(getGlobalActionLogRecent(34)) ?>
</td>
<td width=698>
<?= getMapHtml($mapTheme) ?>
</td>
</tr>
<tr>
<td colspan=2 valign=top>
<?= formatHistoryToHTML(getGlobalHistoryLogRecent(34)) ?>
</td>
</tr>
</table>
<table align=center width=1200 class='tb_layout bg0'>
<tr>
<td><?= closeButton() ?></td>
</tr>
<tr>
<td><?= banner() ?> </td>
</tr>
</table>
</body>
</html>
+7 -26
View File
@@ -69,7 +69,7 @@ $str2 = getTournamentTime();
if ($str2) {
$str2 = ', ' . $str2;
}
$str3 = getTournamentTerm();
$str3 = getTournamentTermText();
if ($str3) {
$str3 = ', ' . $str3;
}
@@ -132,11 +132,8 @@ if ($str3) {
if ($general['name'] == "") {
$general['name'] = "-";
}
if ($general['npc'] >= 2) {
$general['name'] = "<font color=cyan>" . $general['name'] . "</font>";
} elseif ($general['npc'] == 1) {
$general['name'] = "<font color=skyblue>" . $general['name'] . "</font>";
}
$general['name'] = formatName($general['name'], $general['npc']);
echo "<td colspan=16>{$general['name']}</td>";
}
@@ -162,11 +159,7 @@ if ($str3) {
if ($general['name'] == "") {
$general['name'] = "-";
}
if ($general['npc'] >= 2) {
$general['name'] = "<font color=cyan>" . $general['name'] . "</font>";
} elseif ($general['npc'] == 1) {
$general['name'] = "<font color=skyblue>" . $general['name'] . "</font>";
}
$general['name'] = formatName($general['name'], $general['npc']);
if ($general['win'] > 0) {
$line[$i] = "<font color=red>";
$cent[intdiv($i, 2)] = "<font color=red>";
@@ -208,11 +201,7 @@ if ($str3) {
if ($general['name'] == "") {
$general['name'] = "-";
}
if ($general['npc'] >= 2) {
$general['name'] = "<font color=cyan>" . $general['name'] . "</font>";
} elseif ($general['npc'] == 1) {
$general['name'] = "<font color=skyblue>" . $general['name'] . "</font>";
}
$general['name'] = formatName($general['name'], $general['npc']);
if ($general['win'] > 0) {
$line[$i] = "<font color=red>";
$cent[intdiv($i, 2)] = "<font color=red>";
@@ -254,11 +243,7 @@ if ($str3) {
if ($general['name'] == "") {
$general['name'] = "-";
}
if ($general['npc'] >= 2) {
$general['name'] = "<font color=cyan>" . $general['name'] . "</font>";
} elseif ($general['npc'] == 1) {
$general['name'] = "<font color=skyblue>" . $general['name'] . "</font>";
}
$general['name'] = formatName($general['name'], $general['npc']);
if ($general['win'] > 0) {
$line[$i] = "<font color=red>";
$cent[intdiv($i, 2)] = "<font color=red>";
@@ -300,11 +285,7 @@ if ($str3) {
if ($general['name'] == "") {
$general['name'] = "-";
}
if ($general['npc'] >= 2) {
$general['name'] = "<font color=cyan>" . $general['name'] . "</font>";
} elseif ($general['npc'] == 1) {
$general['name'] = "<font color=skyblue>" . $general['name'] . "</font>";
}
$general['name'] = formatName($general['name'], $general['npc']);
if ($general['win'] > 0) {
$line[$i] = "<font color=red>";
$cent[intdiv($i, 2)] = "<font color=red>";
-269
View File
@@ -1,269 +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, officer_level, con, turntime, belong, permission, penalty FROM general WHERE owner=%i', $userID);
$nationID = $me['nation'];
$nation = $db->queryFirstRow('SELECT nation,level,name,color,type,gold,rice,bill,rate,scout,war,secretlimit,capital FROM nation WHERE nation = %i', $nationID);
$nationStor = KVStorage::getStorage($db, $nationID, 'nation_env');
$con = checkLimit($me['con']);
if ($con >= 2) {
printLimitMsg($me['turntime']);
exit();
}
$permission = checkSecretPermission($me);
if ($permission < 0) {
echo '국가에 소속되어있지 않습니다.';
die();
} else if ($permission < 1) {
echo "권한이 부족합니다. 수뇌부가 아니거나 사관년도가 부족합니다.";
die();
}
if ($me['officer_level'] >= 5) {
$btn = "submit";
$read = "";
} else {
$btn = "hidden";
$read = "readonly";
}
$nationStor->cacheValues(['notice', 'scout_msg', 'available_war_setting_cnt']);
?>
<!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::printStaticValues([
'editable' => ($me['officer_level'] >= 5 || $permission == 4),
'nationMsg' => $nationStor->notice ?? '',
'scoutMsg' => $nationStor->scout_msg ?? '',
]) ?>
<?= 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('vue', 'v_dipcenter', true) ?>
</head>
<body>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td>내 무 부<br><?= backButton() ?></td>
</tr>
</table>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td colspan=9 align=center bgcolor=blue>외 교 관 계</td>
</tr>
<tr>
<td width=130 align=center class=bg1>국 가 명</td>
<td width=50 align=center class=bg1>국력</td>
<td width=40 align=center class=bg1>장수</td>
<td width=40 align=center class=bg1>속령</td>
<td width=80 align=center class=bg1>상태</td>
<td width=60 align=center class=bg1>기간</td>
<td width=100 align=center class=bg1>종 료 시 점</td>
</tr>
<?php
$admin = $gameStor->getValues(['year', 'month']);
$cityCntList = Util::convertPairArrayToDict($db->queryAllLists('SELECT nation, count(city) FROM city GROUP BY nation'));
$dipStateList = Util::convertArrayToDict($db->query('SELECT you,state,term FROM diplomacy WHERE me = %i', $nationID), 'you');
$nationsList = getAllNationStaticInfo();
uasort($nationsList, function (array $lhs, array $rhs) {
return - ($lhs['power'] <=> $rhs['power']);
});
foreach ($nationsList as $staticNation) :
//속령수
$staticNationID = $staticNation['nation'];
$cityCnt = $cityCntList[$staticNation['nation']] ?? 0;
$dipStateText = '-';
$dipTermText = '-';
$dipEndDateText = '-';
if ($staticNationID !== $nationID) {
$diplomacyState = $dipStateList[$staticNationID];
$dipStateText = [
0 => "<font color=red>교 전</font>",
1 => "<font color=magenta>선포중</font>",
2 => "통 상",
7 => "<font color=green>불가침</font>",
][$diplomacyState['state']];
if ($diplomacyState['term']) {
$dipEndMonth = $admin['month'] + $diplomacyState['term'] - 1;
$dipEndYear = $admin['year'] + intdiv($dipEndMonth, 12);
$dipEndMonth = $dipEndMonth % 12 + 1;
$dipTermText = $diplomacyState['term'] . '개월';
$dipEndDateText = "{$dipEndYear}年 {$dipEndMonth}月";
}
}
?>
<tr>
<td class='center' style='color:<?= newColor($staticNation['color']) ?>;background-color:<?= $staticNation['color'] ?>'><?= $staticNation['name'] ?></td>
<td class='center'><?= $staticNation['power'] ?></td>
<td class='center'><?= $staticNation['gennum'] ?></td>
<td class='center'><?= $cityCnt ?></td>
<td class='center'><?= $dipStateText ?></td>
<td class='center'><?= $dipTermText ?></td>
<td class='center'><?= $dipEndDateText ?></td>
</tr>
<?php endforeach; ?>
</table>
<?php
// 수입 연산
$cityList = $db->query('SELECT * FROM city WHERE nation=%i', $nationID);
$dedicationList = $db->query('SELECT dedication FROM general WHERE nation=%i AND npc!=5', $nationID);
$goldIncome = getGoldIncome($nation['nation'], $nation['level'], $nation['rate'], $nation['capital'], $nation['type'], $cityList);
$warIncome = getWarGoldIncome($nation['type'], $cityList);
$totalGoldIncome = $goldIncome + $warIncome;
$riceIncome = getRiceIncome($nation['nation'], $nation['level'], $nation['rate'], $nation['capital'], $nation['type'], $cityList);
$wallIncome = getWallIncome($nation['nation'], $nation['level'], $nation['rate'], $nation['capital'], $nation['type'], $cityList);
$totalRiceIncome = $riceIncome + $wallIncome;
$outcome = getOutcome($nation['bill'], $dedicationList);
$budgetgold = $nation['gold'] + $totalGoldIncome - $outcome;
$budgetrice = $nation['rice'] + $totalRiceIncome - $outcome;
$budgetgolddiff = $totalGoldIncome - $outcome;
$budgetricediff = $totalRiceIncome - $outcome;
if ($budgetgolddiff > 0) {
$budgetgolddiff = '+' . number_format($budgetgolddiff);
} else {
$budgetgolddiff = number_format($budgetgolddiff);
}
if ($budgetricediff > 0) {
$budgetricediff = '+' . number_format($budgetricediff);
} else {
$budgetricediff = number_format($budgetricediff);
}
?>
<div class='tb_layout bg0' style='margin:auto;width: 1000px;' id="editorForm">
</div>
<table class="tb_layout bg0" style="margin:auto;">
<form name=form1 method=post action=c_dipcenter.php>
<tr>
<td colspan=2 align=center bgcolor=green>예 산 &amp; 정 책</td>
</tr>
<tr>
<td colspan=2>
<table width=998 class='tb_layout bg0'>
<tr>
<td colspan=2 align=center class=bg1>자금 예산</td>
<td colspan=2 align=center class=bg1>병량 예산</td>
</tr>
<tr>
<td width=248 align=right class=bg1>현 재&nbsp;&nbsp;&nbsp;</td>
<td width=248 align=center><?= number_format($nation['gold']) ?></td>
<td width=248 align=right class=bg1>현 재&nbsp;&nbsp;&nbsp;</td>
<td width=248 align=center><?= number_format($nation['rice']) ?></td>
</tr>
<tr>
<td align=right class=bg1>단기수입&nbsp;&nbsp;&nbsp;</td>
<td align=center>+<?= number_format($warIncome) ?></td>
<td align=right class=bg1>둔전수입&nbsp;&nbsp;&nbsp;</td>
<td align=center>+<?= number_format($wallIncome) ?></td>
</tr>
<tr>
<td align=right class=bg1>세 금&nbsp;&nbsp;&nbsp;</td>
<td align=center>+<?= number_format($goldIncome) ?></td>
<td align=right class=bg1>세 곡&nbsp;&nbsp;&nbsp;</td>
<td align=center>+<?= number_format($riceIncome) ?></td>
</tr>
<tr>
<td align=right class=bg1>수입 / 지출&nbsp;&nbsp;&nbsp;</td>
<td align=center>+<?= number_format($totalGoldIncome) ?> / -<?= number_format($outcome) ?></td>
<td align=right class=bg1>수입 / 지출&nbsp;&nbsp;&nbsp;</td>
<td align=center>+<?= number_format($totalRiceIncome) ?> / -<?= number_format($outcome) ?></td>
</tr>
<tr>
<td align=right class=bg1>국고 예산&nbsp;&nbsp;&nbsp;</td>
<td align=center><?= number_format($budgetgold) ?> (<?= $budgetgolddiff ?>)</td>
<td align=right class=bg1>병량 예산&nbsp;&nbsp;&nbsp;</td>
<td align=center><?= number_format($budgetrice) ?> (<?= $budgetricediff ?>)</td>
</tr>
<tr>
<td align=right class=bg1>세율 (5 ~ 30%)&nbsp;&nbsp;&nbsp;</td>
<td align=center><input type=text <?= $read ?> name=rate style=text-align:right;color:white;background-color:black; size=3 maxlength=3 value=<?= $nation['rate'] ?>>% <input type=<?= $btn ?> name=btn value=세율></td>
<td align=right class=bg1>봉급 지급률 (20 ~ 200%)&nbsp;&nbsp;&nbsp;</td>
<td align=center><input type=text <?= $read ?> name=bill style=text-align:right;color:white;background-color:black; size=3 maxlength=3 value=<?= $nation['bill'] ?>>% <input type=<?= $btn ?> name=btn value=지급률></td>
</tr>
<tr>
<td align=right class=bg1>기밀 권한 (1 ~ 99년)&nbsp;&nbsp;&nbsp;</td>
<td align=center><input type=text <?= $read ?> name=secretlimit style=text-align:right;color:white;background-color:black; size=3 maxlength=3 value=<?= $nation['secretlimit'] ?>>년 <input type=<?= $btn ?> name=btn value=기밀권한></td>
<td align=right class=bg1>전쟁 허용/금지 변경 가능</td>
<td align=center><?= $nationStor->getValue('available_war_setting_cnt') ?>회(월 +<?= GameConst::$incAvailableWarSettingCnt ?>회, 최대<?= GameConst::$maxAvailableWarSettingCnt ?>회)</td>
</tr>
<tr>
<td colspan=4 align=center>
<?php
if ($nation['scout'] == 0) {
echo "
<input type=$btn name=btn value='임관 금지'>";
} else {
echo "
<input type=$btn name=btn value='임관 허가'>";
}
if ($nation['war'] == 0) {
echo "
<input type=$btn name=btn value='전쟁 금지'>";
} else {
echo "
<input type=$btn name=btn value='전쟁 허가'>";
}
?>
</td>
</tr>
</table>
<tr>
<td colspan=2>기밀 권한이란, 암행부를 열람할 수 있는 일반 장수의 최소 사관 년수를 의미합니다.</td>
</tr>
<tr>
<td colspan=2 height=10></td>
</tr>
</form>
</table>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td><?= backButton() ?></td>
</tr>
<tr>
<td><?= banner() ?></td>
</tr>
</table>
</body>
</html>
+1 -7
View File
@@ -146,13 +146,7 @@ if ($gameStor->isunited) {
$intel = "{$general['intel']}";
}
if ($general['npc'] >= 2) {
$name = "<font color=cyan>{$general['name']}</font>";
} elseif ($general['npc'] == 1) {
$name = "<font color=skyblue>{$general['name']}</font>";
} else {
$name = "{$general['name']}";
}
$name = formatName($general['name'], $general['npc']);
if (key_exists($general['owner'], $ownerNameList)) {
$name = $name . '<br><small>(' . $ownerNameList[$general['owner']] . ')</small>';
+2
View File
@@ -94,6 +94,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 endif; ?>
수비 【<select id='defence_train' name='defence_train'>
<?php foreach ([90, 80, 60, 40] as $targetDefenceTrain) : ?>
+6 -26
View File
@@ -198,7 +198,7 @@ switch ($admin['tnmt_type']) {
if ($str2) {
$str2 = ', ' . $str2;
}
$str3 = getTournamentTerm();
$str3 = getTournamentTermText();
if ($str3) {
$str3 = ', ' . $str3;
}
@@ -240,11 +240,7 @@ switch ($admin['tnmt_type']) {
if ($general['name'] == "") {
$general['name'] = "-";
}
if ($general['npc'] >= 2) {
$general['name'] = "<font color=cyan>" . $general['name'] . "</font>";
} elseif ($general['npc'] == 1) {
$general['name'] = "<font color=skyblue>" . $general['name'] . "</font>";
}
$general['name'] = formatName($general['name'], $general['npc']);
echo "<td colspan=16>{$general['name']}</td>";
}
@@ -270,11 +266,7 @@ switch ($admin['tnmt_type']) {
if ($general['name'] == "") {
$general['name'] = "-";
}
if ($general['npc'] >= 2) {
$general['name'] = "<font color=cyan>" . $general['name'] . "</font>";
} elseif ($general['npc'] == 1) {
$general['name'] = "<font color=skyblue>" . $general['name'] . "</font>";
}
$general['name'] = formatName($general['name'], $general['npc']);
if ($general['win'] > 0) {
$line[$i] = "<font color=red>";
$cent[intdiv($i, 2)] = "<font color=red>";
@@ -316,11 +308,7 @@ switch ($admin['tnmt_type']) {
if ($general['name'] == "") {
$general['name'] = "-";
}
if ($general['npc'] >= 2) {
$general['name'] = "<font color=cyan>" . $general['name'] . "</font>";
} elseif ($general['npc'] == 1) {
$general['name'] = "<font color=skyblue>" . $general['name'] . "</font>";
}
$general['name'] = formatName($general['name'], $general['npc']);
if ($general['win'] > 0) {
$line[$i] = "<font color=red>";
$cent[intdiv($i, 2)] = "<font color=red>";
@@ -363,11 +351,7 @@ switch ($admin['tnmt_type']) {
if ($general['name'] == "") {
$general['name'] = "-";
}
if ($general['npc'] >= 2) {
$general['name'] = "<font color=cyan>" . $general['name'] . "</font>";
} elseif ($general['npc'] == 1) {
$general['name'] = "<font color=skyblue>" . $general['name'] . "</font>";
}
$general['name'] = formatName($general['name'], $general['npc']);
if ($general['win'] > 0) {
$line[$i] = "<font color=red>";
$cent[intdiv($i, 2)] = "<font color=red>";
@@ -409,11 +393,7 @@ switch ($admin['tnmt_type']) {
if ($general['name'] == "") {
$general['name'] = "-";
}
if ($general['npc'] >= 2) {
$general['name'] = "<font color=cyan>" . $general['name'] . "</font>";
} elseif ($general['npc'] == 1) {
$general['name'] = "<font color=skyblue>" . $general['name'] . "</font>";
}
$general['name'] = formatName($general['name'], $general['npc']);
if ($general['win'] > 0) {
$line[$i] = "<font color=red>";
$cent[intdiv($i, 2)] = "<font color=red>";
-85
View File
@@ -1,85 +0,0 @@
<?php
namespace sammo;
include "lib.php";
include "func.php";
// $btn, $msg, $scoutmsg, $rate, $bill, $secretlimit
$btn = Util::getPost('btn');
//$msg = Util::getPost('msg');
//$scoutmsg = Util::getPost('scoutMsg');
$rate = Util::getPost('rate', 'int');
$bill = Util::getPost('bill', 'int');
$secretlimit = Util::getPost('secretlimit', 'int');
//로그인 검사
$session = Session::requireGameLogin()->setReadOnly();
$userID = Session::getUserID();
$db = DB::db();
$me = $db->queryFirstRow('SELECT `no`,nation,`officer_level`,permission,penalty FROM general WHERE `owner`=%i', $userID);
//내가 수뇌부이어야함
$permission = checkSecretPermission($me);
if ($permission < 0) {
header('location:b_myBossInfo.php', true, 303);
exit();
} else if ($me['officer_level'] < 5 && $permission != 4) {
header('location:b_myBossInfo.php', true, 303);
exit();
}
$nationID = $me['nation'];
$nationStor = KVStorage::getStorage($db, $nationID, 'nation_env');
/*if ($btn == "국가방침 수정") {
$msg = mb_substr($msg, 0, 16384);
//$msg = StringUtil::
$nationStor->notice = WebUtil::htmlPurify($msg);
} elseif ($btn == "임관 권유문 수정") {
$scoutmsg = mb_substr($scoutmsg, 0, 1000);
$nationStor->scout_msg = WebUtil::htmlPurify($scoutmsg);
} else*/if ($btn == "세율") {
$rate = Util::valueFit($rate, 5, 30);
$db->update('nation', [
'rate' => $rate,
], 'nation=%i', $nationID);
} elseif ($btn == "지급률") {
$bill = Util::valueFit($bill, 20, 200);
$db->update('nation', [
'bill' => $bill
], 'nation=%i', $nationID);
} elseif ($btn == "기밀권한") {
$secretlimit = Util::valueFit($secretlimit, 1, 99);
$db->update('nation', [
'secretlimit' => $secretlimit
], 'nation=%i', $nationID);
} elseif ($btn == "임관 금지") {
$db->update('nation', [
'scout' => 1
], 'nation=%i', $nationID);
} elseif ($btn == "임관 허가") {
$db->update('nation', [
'scout' => 0
], 'nation=%i', $nationID);
} elseif ($btn == "전쟁 금지") {
$avilableCnt = $nationStor->getValue('available_war_setting_cnt') ?? 0;
if ($avilableCnt > 0) {
$db->update('nation', [
'war' => 1
], 'nation=%i', $nationID);
$nationStor->setValue('available_war_setting_cnt', $avilableCnt - 1);
}
} elseif ($btn == "전쟁 허가") {
$avilableCnt = $nationStor->getValue('available_war_setting_cnt') ?? 0;
if ($avilableCnt > 0) {
$db->update('nation', [
'war' => 0
], 'nation=%i', $nationID);
$nationStor->setValue('available_war_setting_cnt', $avilableCnt - 1);
}
}
header('location:b_dipcenter.php');
+10 -2
View File
@@ -15,7 +15,7 @@ $sel = Util::getPost('sel', 'int');
$trig = Util::getPost('trig', 'int');
//로그인 검사
$session = Session::requireGameLogin()->setReadOnly();
$session = Session::requireGameLogin();
$userID = Session::getUserID();
$db = DB::db();
@@ -24,7 +24,11 @@ $gameStor = KVStorage::getStorage($db, 'game_env');
$admin = $gameStor->getValues(['tournament','phase','tnmt_type','develcost']);
$me = $db->queryFirstRow('SELECT no,name,tournament from general where owner=%i',$userID);
if(!$me){
$session->logoutGame();
header('location:b_tournament.php');
exit(1);
}
switch($admin['tnmt_type']) {
case 0: $tp = "total"; $tp2 = "전력전"; $tp3 = "leadership+strength+intel"; break;
case 1: $tp = "leadership"; $tp2 = "통솔전"; $tp3 = "leadership"; break;
@@ -40,6 +44,10 @@ if($btn == '참가') {
}
$general = $db->queryFirstRow('SELECT no,name,npc,leadership,strength,intel,explevel,gold,horse,weapon,book FROM general WHERE `no`=%i', $me['no']);
if(!$general){
header('location:b_tournament.php');
exit(1);
}
//{$admin['develcost']}원 참가비
if($general['gold'] < $admin['develcost']) {
+16 -18
View File
@@ -1,18 +1,16 @@
<div class="buttonPlate">
<a href="a_status.php" target="_blank" class="open-window"><button type="button" class="toolbarButton">세력도</button></a>
<a href="a_kingdomList.php" target="_blank" class="open-window"><button type="button" class="toolbarButton">세력일람</button></a>
<a href="a_genList.php" target="_blank" class="open-window"><button type="button" class="toolbarButton">장수일람</button></a>
<a href="a_bestGeneral.php" target="_blank" class="open-window"><button type="button" class="toolbarButton">명장일람</button></a>
<a href="a_history.php" target="_blank" class="open-window"><button type="button" class="toolbarButton">연감</button></a>
<a href="a_hallOfFame.php" target="_blank" class="open-window"><button type="button" class="toolbarButton">명예의전당</button></a>
<a href="a_emperior.php" target="_blank" class="open-window"><button type="button" class="toolbarButton">왕조일람</button></a>
<a href="a_traffic.php" target="_blank" class="open-window"><button type="button" class="toolbarButton">접속량정보</button></a>
<a href="/bbs/board" target="_blank"><button type="button" class="toolbarButton2">삼모게시판</button></a>
<a href="/bbs/tip" target="_blank"><button type="button" class="toolbarButton">팁/강좌</button></a>
<a href="/bbs/news" target="_blank"><button type="button" class="toolbarButton">삼국 일보</button></a>
<a href="/bbs/history2" target="_blank"><button type="button" class="toolbarButton">개인 열전</button></a>
<a href="/bbs/history3" target="_blank"><button type="button" class="toolbarButton">국가 열전</button></a>
<a href="/bbs/patch" target="_blank"><button type="button" class="toolbarButton">패치 내역</button></a>
<a href="battle_simulator.php" target="_blank"><button type="button" class="toolbarButton">전투 시뮬레이터</button></a>
<a href="<?=$site?>" target="_blank" class="open-window"><button type="button" class="toolbarButton"><?=$call?></button></a>
</div>
<?=$btnBegin??''?><a href="v_nationBetting.php" target="_blank" class="open-window toolbarButton <?=$btnClass??""?>">천통국 베팅</a><?=$btnEnd??''?>
<?=$btnBegin??''?><a href="a_kingdomList.php" target="_blank" class="open-window toolbarButton <?=$btnClass??""?>">세력일람</a><?=$btnEnd??''?>
<?=$btnBegin??''?><a href="a_genList.php" target="_blank" class="open-window toolbarButton <?=$btnClass??""?>">장수일람</a><?=$btnEnd??''?>
<?=$btnBegin??''?><a href="a_bestGeneral.php" target="_blank" class="open-window toolbarButton <?=$btnClass??""?>">명장일람</a><?=$btnEnd??''?>
<?=$btnBegin??''?><a href="a_history.php" target="_blank" class="open-window toolbarButton <?=$btnClass??""?>">연감</a><?=$btnEnd??''?>
<?=$btnBegin??''?><a href="a_hallOfFame.php" target="_blank" class="open-window toolbarButton <?=$btnClass??""?>">명예의전당</a><?=$btnEnd??''?>
<?=$btnBegin??''?><a href="a_emperior.php" target="_blank" class="open-window toolbarButton <?=$btnClass??""?>">왕조일람</a><?=$btnEnd??''?>
<?=$btnBegin??''?><a href="a_traffic.php" target="_blank" class="open-window toolbarButton <?=$btnClass??""?>">접속량정보</a><?=$btnEnd??''?>
<?=$btnBegin??''?><a href="/bbs/board" target="_blank" class="toolbarButton2 <?=$btnClass??""?>">삼모게시판</a><?=$btnEnd??''?>
<?=$btnBegin??''?><a href="/bbs/tip" target="_blank" class="toolbarButton <?=$btnClass??""?>">팁/강좌</a><?=$btnEnd??''?>
<?=$btnBegin??''?><a href="/bbs/news" target="_blank" class="toolbarButton <?=$btnClass??""?>">삼국 일보</a><?=$btnEnd??''?>
<?=$btnBegin??''?><a href="/bbs/history2" target="_blank" class="toolbarButton <?=$btnClass??""?>">개인 열전</a><?=$btnEnd??''?>
<?=$btnBegin??''?><a href="/bbs/history3" target="_blank" class="toolbarButton <?=$btnClass??""?>">국가 열전</a><?=$btnEnd??''?>
<?=$btnBegin??''?><a href="/bbs/patch" target="_blank" class="toolbarButton <?=$btnClass??""?>">패치 내역</a><?=$btnEnd??''?>
<?=$btnBegin??''?><a href="battle_simulator.php" target="_blank" class="toolbarButton <?=$btnClass??""?>">전투 시뮬레이터</a><?=$btnEnd??''?>
<?=$btnBegin??''?><a href="<?= $site ?>" target="_blank" class="open-window toolbarButton <?=$btnClass??""?>"><?= $call ?></a><?=$btnEnd??''?>
+17 -3
View File
@@ -1581,6 +1581,18 @@ 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]){
$itemCode = substr($uniqueNS, 3);
$itemClass = buildItemClass($itemCode);
if (!$itemClass) {
continue;
}
if ($itemClass->isBuyable()) {
continue;
}
$occupiedUnique[$itemCode] = ($occupiedUnique[$itemCode]??0) + $cnt;
}
foreach (GameConst::$allItems as $itemType => $itemCategories) {
if (key_exists($itemType, $invalidItemType)) {
continue;
@@ -1925,8 +1937,8 @@ function tryUniqueItemLottery(General $general, string $acquireType = '아이템
$prob = Util::valueFit($prob, null, 1 / 4); //최대치 감소
$result = false;
$prob /= sqrt(2);
$moreProb = pow(2, 1 / 4);
$prob /= sqrt(7);
$moreProb = pow(10, 1 / 4);
if ($general->getAuxVar('inheritRandomUnique') && $availableBuyUnique) {
//포인트로 랜덤 유니크 획득
@@ -2403,7 +2415,9 @@ function SabotageInjury(array $cityGeneralList, string $reason): int
foreach ($cityGeneralList as $general) {
/** @var General $general */
if (!Util::randBool(0.3)) {
$injuryProb = 0.3;
$injuryProb = $general->onCalcStat($general, 'injuryProb', $injuryProb);
if (!Util::randBool($injuryProb)) {
continue;
}
$general->getLogger()->pushGeneralActionLog($text);
+5 -5
View File
@@ -673,17 +673,17 @@ function updateNationState()
continue;
}
$score = $nationGen->getVar('belong') + 5;
$score = $nationGen->getVar('belong') + 10;
if ($nationGen->getVar('officer_level') == 12) {
$score += 100; //NOTE: 꼬우면 군주하세요.
$score += 60;
} else if ($nationGen->getVar('officer_level') == 11) {
$score += 50;
$score += 30;
} else if ($nationGen->getVar('officer_level') > 4) {
$score += 35;
$score += 15;
}
$score *= $trialCnt;
$score *= 2**$trialCnt;
$uniqueLotteryWeightList[$nationGen->getID()] = [$nationGen, $score];
}
+27 -21
View File
@@ -371,10 +371,11 @@ function getGlobalActionLogWithDate(int $year, int $month):array {
return $texts;
}
function LogHistory($isFirst=0) {
function getCurrentHistory($isFirst=false) {
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
$obj = $gameStor->getValues(['startyear', 'year', 'month']);
[$startYear, $year, $month]= $gameStor->getValuesAsArray(['startyear', 'year', 'month']);
$yearMonth = Util::joinYearMonth($year, $month);
$map = getWorldMap([
'year'=>null,
@@ -384,21 +385,14 @@ function LogHistory($isFirst=0) {
'aux'=>[]
]);
$map['month'] = $obj['month'];
$map['year'] = $obj['year'];
$map['startYear'] = $obj['startyear'];
if($isFirst == 1){
$map['month'] -= 1;
if($map['month'] == 0){
$map['month'] = 12;
$map['year'] -= 1;
}
if($isFirst){
$yearMonth -= 1;
}
$year = $map['year'];
$month = $map['month'];
[$year, $month] = Util::parseYearMonth($yearMonth);
$map['startYear'] = $startYear;
$map['year'] = $year;
$map['month'] = $month;
$globalHistory = getGlobalHistoryLogWithDate($year, $month);
$globalAction = getGlobalActionLogWithDate($year, $month);
@@ -418,15 +412,27 @@ function LogHistory($isFirst=0) {
return -($lhs['power']<=>$rhs['power']);
});
$db->insert('ng_history', [
return [
'server_id' => UniqueConst::$serverID,
'year' => $year,
'month' => $month,
'map' => Json::encode($map),
'global_history' => Json::encode($globalHistory),
'global_action' => Json::encode($globalAction),
'nations' => Json::encode($nations),
]);
'map' => $map,
'global_history' => $globalHistory,
'global_action' => $globalAction,
'nations' => $nations,
];
}
function LogHistory($isFirst=false) {
$history = getCurrentHistory($isFirst);
$db = DB::db();
$history['map'] = Json::encode($history['map']);
$history['global_history'] = Json::encode($history['global_history']);
$history['global_action'] = Json::encode($history['global_action']);
$history['nations'] = Json::encode($history['nations']);
$db->insert('ng_history', $history);
return true;
}
+26 -5
View File
@@ -215,14 +215,35 @@ function formatLeadershipBonus(int $value): string
return "<font color=cyan>+{$value}</font>";
}
function getNPCColor(int $npc): ?string{
if ($npc == 1) {
return 'skyblue';
}
if ($npc == 4){
return 'deepskyblue';
}
if ($npc == 5){
return 'darkcyan';
}
if ($npc == 6){
return 'mediumaquamarine';
}
if ($npc > 1) {
return 'cyan';
}
return null;
}
function formatName(string $name, int $npc): string
{
if ($npc == 1) {
$name = "<font color='skyblue'>$name</font>";
} else if ($npc > 1) {
$name = "<font color='cyan'>$name</font>";
$color = getNPCColor($npc);
if($color === null){
return $name;
}
return $name;
return "<span style='color:{$color}'>$name</span>";
}
function getMapTheme(): string
+1 -1
View File
@@ -576,7 +576,7 @@ function disaster() {
$logger->flush();
if (!$isGood) {
$generalListByCity = Util::arrayGroupBy($db->query('SELECT no, nation, city, injury, crew, atmos, train FROM general WHERE city IN %li', Util::squeezeFromArray($targetCityList, 'city')), 'city');
$generalListByCity = Util::arrayGroupBy($db->query('SELECT no, name, nation, city, officer_level, injury, leadership, strength, intel, horse, weapon, book, item, crew, crewtype, atmos, train, special, special2 FROM general WHERE city IN %li', Util::squeezeFromArray($targetCityList, 'city')), 'city');
//NOTE: 쿼리 1번이지만 복잡하기 vs 쿼리 여러번이지만 조금 더 깔끔하기
foreach ($targetCityList as $city) {
$affectRatio = Util::valueFit($city['secu'] / $city['secu_max'] / 0.8, 0, 1);
+39 -34
View File
@@ -164,40 +164,47 @@ 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()
{
function getTournamentTerm(): ?int{
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
$tnmt_auto = $gameStor->tnmt_auto;
switch ($tnmt_auto) {
case 0:
$str = '';
break;
case 1:
$str = "경기당 12분";
break;
case 2:
$str = "경기당 7분";
break;
case 3:
$str = "경기당 3분";
break;
case 4:
$str = "경기당 1분";
break;
case 5:
$str = "경기당 30초";
break;
case 6:
$str = "경기당 15초";
break;
case 7:
$str = "경기당 5초";
break;
if($tnmt_auto === null){
$tnmt_auto = $gameStor->tnmt_trig;
}
return $str;
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;
}
function getTournamentTermText()
{
$term = getTournamentTerm();
if($term === null){
return '수동';
}
if($term % 60 === 0){
$termMin = intdiv($term, 60);
return "경기당 {$termMin}";
}
if($term > 60){
$termSec = $term % 60;
$termMin = intdiv($term, 60);
return "경기당 {$termMin}{$termSec}";
}
return "경기당 {$term}";
}
function getTournamentTime()
@@ -261,10 +268,8 @@ function printRow($k, $npc, $name, $abil, $tgame, $win, $draw, $lose, $gd, $gl,
$k += 1;
if ($prmt > 0) {
$name = "<font color=orange>" . $name . "</font>";
} elseif ($npc >= 2) {
$name = "<font color=cyan>" . $name . "</font>";
} elseif ($npc == 1) {
$name = "<font color=skyblue>" . $name . "</font>";
} 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>";
}
@@ -513,7 +518,7 @@ function fillLowGenAll($tnmt_type)
'SELECT no,npc,name,leadership,strength,intel,explevel,horse,weapon,book from general where tnmt=1 and tournament=0',
) as $gen){
$score = $scoringCandFunction($gen);
$freeJoinerCandidate[$gen['no']] = [$gen, $score**2];
$freeJoinerCandidate[$gen['no']] = [$gen, $score**1.5];
}
+4 -4
View File
@@ -149,14 +149,14 @@ if (!$otherTextInfo) {
<?= $scenario ?>
</div>
<div class="s-border-t col py-2 col-4 col-md-2" style="color:<?= $color ?>;">
NPC : <?= $extend ?>
</div>
<div class="s-border-t col py-2 col-4 col-md-2" style="color:<?= $color ?>;">
NPC상성 : <?= $fiction ?>
NPC 수, 상성 : <?= $extend ?>,<?= $fiction ?>
</div>
<div class="s-border-t col py-2 col-4 col-md-2" style="color:<?= $color ?>;">
NPC선택 : <?= $npcmode ?>
</div>
<div class="s-border-t col py-2 col-4 col-md-2" style="color:<?= $color ?>;">
토너먼트 : <?= getTournamentTermText() ?>
</div>
<div class="s-border-t col py-2 col-4 col-md-2" style="color:<?= $color ?>;">
기타 설정: <?= $otherTextInfo ?>
</div>
-41
View File
@@ -1,41 +0,0 @@
<?php
namespace sammo;
include "lib.php";
include "func.php";
WebUtil::requireAJAX();
//로그인 검사
$session = Session::requireGameLogin()->setReadOnly();
$userID = Session::getUserID();
$turnAmount = Util::getPost('amount', 'int');
$db = DB::db();
$me = $db->queryFirstRow('SELECT no,nation,officer_level FROM general WHERE owner=%i', $userID);
if($me['nation'] == 0){
Json::die([
'result'=>false,
'reason'=>'국가에 소속되어 있지 않습니다.',
]);
}
if($me['officer_level'] < 5){
Json::die([
'result'=>false,
'reason'=>'수뇌가 아닙니다.',
]);
}
if($turnAmount > 0){
pushNationCommand($me['nation'], $me['officer_level']);
}
else{
pullNationCommand($me['nation'], $me['officer_level']);
}
Json::die([
'result'=>true,
'reason'=>'success',
]);
-103
View File
@@ -1,103 +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,officer_level,con,turntime,belong,penalty,permission FROM general WHERE owner=%i', $userID);
$nationLevel = $db->queryFirstField('SELECT level FROM nation WHERE nation = %i', $me['nation']);
$nationID = $me['nation'];
$con = checkLimit($me['con']);
if($con >= 2) {
Json::die([
'result'=>false,
'reason'=>"접속 제한중입니다. 1턴 이내에 너무 많은 갱신을 하셨습니다. (다음 접속 가능 시각 : {$me['turntime']})"
]);
}
$permission = checkSecretPermission($me);
if($permission < 0){
Json::die([
'result'=>false,
'reason'=>'국가에 소속되어있지 않습니다.'
]);
echo '국가에 소속되어있지 않습니다.';
die();
}
else if ($permission < 1) {
Json::die([
'result'=>false,
'reason'=>'수뇌부가 아니거나 사관년도가 부족합니다.'
]);
die();
}
$date = TimeUtil::now();
// 명령 목록
[$year, $month, $turnterm] = $gameStor->getValuesAsArray(['year', 'month', 'turnterm']);
$lv = getNationChiefLevel($nationLevel);
$turn = [];
$generals = [];
foreach($db->query('SELECT no,name,turntime,npc,city,nation,officer_level FROM general WHERE nation = %i AND officer_level >= 5',$nationID) as $rawGeneral){
$generals[$rawGeneral['officer_level']] = new General($rawGeneral, null, null, null, $year, $month, false);
}
$nationTurnList = [];
foreach(
$db->queryAllLists(
'SELECT officer_level, turn_idx, action, arg, brief FROM nation_turn WHERE nation_id = %i ORDER BY officer_level DESC, turn_idx ASC',
$me['nation']
) as [$officer_level, $turn_idx, $action, $arg, $brief]
){
if(!key_exists($officer_level, $nationTurnList)){
$nationTurnList[$officer_level] = [];
}
$nationTurnList[$officer_level][$turn_idx] = $brief;
}
$nationTurnBrief = [];
foreach($nationTurnList as $officer_level=>$turnBrief){
if(!key_exists($officer_level, $generals)){
$nationTurnBrief[$officer_level] = [
'name'=>null,
'turnTime'=>null,
'officerLevelText'=>getOfficerLevelText($officer_level, $nationLevel),
'npcType'=>null,
'turn'=>$turnBrief
];
continue;
}
$general = $generals[$officer_level];
$nationTurnBrief[$officer_level] = [
'name'=>$general->getName(),
'turnTime'=>$general->getTurnTime($general::TURNTIME_FULL),
'officerLevel'=>$general->getVar('officer_level'),
'officerLevelText'=>getOfficerLevelText($general->getVar('officer_level'), $nationLevel),
'npcType'=>$general->getNPCType(),
'turn'=>$turnBrief,
];
}
$date = substr(TimeUtil::now(), 14);
Json::die([
'result'=>true,
'reason'=>'success',
'date'=>$date,
'nationTurnBrief'=>$nationTurnBrief,
'isChief'=>($me['officer_level'] > 4),
'officerLevel'=>$me['officer_level'],
'turnTerm'=>$turnterm
]);
-66
View File
@@ -1,66 +0,0 @@
<?php
namespace sammo;
include "lib.php";
include "func.php";
WebUtil::requireAJAX();
$session = Session::requireGameLogin([])->setReadOnly();
increaseRefresh("사령턴 입력", 0);
$generalID = $session->generalID;
$action = Util::getPost('action', 'string');
$arg = Json::decode(Util::getPost('arg', 'string'));
$turnList = Util::getPost('turnList', 'array_int');
if(!is_array($turnList) || !$turnList){
Json::die([
'result'=>false,
'reason'=>'턴이 입력되지 않았습니다.',
'test'=>'post',
]);
}
if(!$action){
Json::die([
'result'=>false,
'reason'=>'action이 입력되지 않았습니다.',
'test'=>'post'
]);
}
if(!in_array($action, Util::array_flatten(GameConst::$availableChiefCommand))){
Json::die([
'result'=>false,
'reason'=>'사용할 수 없는 커맨드입니다.',
'test'=>'post'
]);
}
if($arg === null){
$arg = [];
}
if(!is_array($arg)){
Json::die([
'result'=>false,
'reason'=>'올바른 arg 형태가 아닙니다.',
'test'=>'post'
]);
}
$result = setNationCommand($generalID, $turnList, $action, $arg);
if(!key_exists('result', $result)){
$result['result'] = false;
}
if(!key_exists('arg_test', $result)){
$result['arg_test'] = false;
}
if(!key_exists('reason', $result)){
throw new MustNotBeReachedException('reason이 왜 없어?');
}
Json::die($result);
-55
View File
@@ -1,55 +0,0 @@
<?php
namespace sammo;
include "lib.php";
include "func.php";
WebUtil::requireAJAX();
$session = Session::requireGameLogin([])->setReadOnly();
increaseRefresh("턴 입력", 0);
$generalID = $session->generalID;
$action = Util::getPost('action', 'string');
$arg = Json::decode(Util::getPost('arg', 'string'));
$turnList = Util::getPost('turnList', 'array_int');
if(!is_array($turnList) || !$turnList){
Json::die([
'result'=>false,
'reason'=>'턴이 입력되지 않았습니다.',
'test'=>'post',
]);
}
if(!$action){
Json::die([
'result'=>false,
'reason'=>'action이 입력되지 않았습니다.',
'test'=>'post'
]);
}
if(!in_array($action, Util::array_flatten(GameConst::$availableGeneralCommand))){
Json::die([
'result'=>false,
'reason'=>'사용할 수 없는 커맨드입니다.',
'test'=>'post'
]);
}
if($arg === null){
$arg = [];
}
if(!is_array($arg)){
Json::die([
'result'=>false,
'reason'=>'올바른 arg 형태가 아닙니다.',
'test'=>'post'
]);
}
Json::die(setGeneralCommand($generalID, $turnList, $action, $arg));
+183 -148
View File
@@ -1,28 +1,29 @@
<?php
namespace sammo;
function processWar(General $attackerGeneral, array $rawAttackerNation, array $rawDefenderCity){
function processWar(General $attackerGeneral, array $rawAttackerNation, array $rawDefenderCity)
{
$db = DB::db();
$attackerNationID = $attackerGeneral->getNationID();
$defenderNationID = $rawDefenderCity['nation'];
if($defenderNationID == 0){
if ($defenderNationID == 0) {
$rawDefenderNation = [
'nation'=>0,
'name'=>'재야',
'capital'=>0,
'level'=>0,
'gold'=>0,
'rice'=>10000,
'type'=>GameConst::$neutralNationType,
'tech'=>0,
'gennum'=>1
'nation' => 0,
'name' => '재야',
'capital' => 0,
'level' => 0,
'gold' => 0,
'rice' => 10000,
'type' => GameConst::$neutralNationType,
'tech' => 0,
'gennum' => 1
];
}
else{
} else {
$rawDefenderNation = $db->queryFirstRow('SELECT nation,`level`,`name`,capital,gennum,tech,`type`,gold,rice FROM nation WHERE nation = %i', $defenderNationID);
}
@@ -36,29 +37,29 @@ function processWar(General $attackerGeneral, array $rawAttackerNation, array $r
$defenderIDList = $db->queryFirstColumn('SELECT no FROM general WHERE nation=%i AND city=%i AND nation!=0 and crew > 0 and rice>(crew/100) and train>=defence_train and atmos>=defence_train', $city->getVar('nation'), $city->getVar('city'));
$defenderList = General::createGeneralObjListFromDB($defenderIDList, null, 2);
usort($defenderList, function(General $lhs, General $rhs){
return -(extractBattleOrder($lhs) <=> extractBattleOrder($rhs));
usort($defenderList, function (General $lhs, General $rhs) {
return - (extractBattleOrder($lhs) <=> extractBattleOrder($rhs));
});
$iterDefender = new \ArrayIterator($defenderList);
$iterDefender->rewind();
$getNextDefender = function(?WarUnit $prevDefender, bool $reqNext) use ($iterDefender, $rawDefenderNation, $rawDefenderCity, $db) {
if($prevDefender !== null){
$getNextDefender = function (?WarUnit $prevDefender, bool $reqNext) use ($iterDefender, $rawDefenderNation, $rawDefenderCity, $db) {
if ($prevDefender !== null) {
$prevDefender->applyDB($db);
}
if(!$reqNext){
if (!$reqNext) {
return null;
}
if(!$iterDefender->valid()){
if (!$iterDefender->valid()) {
return null;
}
$nextDefender = $iterDefender->current();
$nextDefender->setRawCity($rawDefenderCity);
if(extractBattleOrder($nextDefender) <= 0){
if (extractBattleOrder($nextDefender) <= 0) {
return null;
}
@@ -82,8 +83,8 @@ function processWar(General $attackerGeneral, array $rawAttackerNation, array $r
$updateAttackerNation = [];
$updateDefenderNation = [];
if($city->getVar('supply')){
if($city->getPhase() > 0){
if ($city->getVar('supply')) {
if ($city->getPhase() > 0) {
$rice = $city->getKilled() / 100 * 0.8;
$rice *= $city->getCrewType()->rice;
$rice *= getTechCost($rawDefenderNation['tech']);
@@ -91,12 +92,10 @@ function processWar(General $attackerGeneral, array $rawAttackerNation, array $r
Util::setRound($rice);
$updateDefenderNation['rice'] = max(0, $rawDefenderNation['rice'] - $rice);
}
else if($conquerCity){
if($rawDefenderNation['capital'] == $rawDefenderCity['city']){
} else if ($conquerCity) {
if ($rawDefenderNation['capital'] == $rawDefenderCity['city']) {
$updateDefenderNation['rice'] = $rawDefenderNation['rice'] + 1000;
}
else{
} else {
$updateDefenderNation['rice'] = $rawDefenderNation['rice'] + 500;
}
}
@@ -120,29 +119,29 @@ function processWar(General $attackerGeneral, array $rawAttackerNation, array $r
$attackerGenCnt_eff = $db->queryFirstField('SELECT count(no) FROM general WHERE nation=%i AND npc != 5', $rawAttackerNation['nation']);
$defenderGenCnt_eff = $db->queryFirstField('SELECT count(no) FROM general WHERE nation=%i AND npc != 5', $rawDefenderNation['nation']);
if($attackerGenCnt_eff < GameConst::$initialNationGenLimit){
if ($attackerGenCnt_eff < GameConst::$initialNationGenLimit) {
$attackerGenCnt = GameConst::$initialNationGenLimit;
$attackerGenCnt_eff = GameConst::$initialNationGenLimit;
}
if($defenderGenCnt_eff < GameConst::$initialNationGenLimit){
if ($defenderGenCnt_eff < GameConst::$initialNationGenLimit) {
$defenderGenCnt = GameConst::$initialNationGenLimit;
$defenderGenCnt_eff = GameConst::$initialNationGenLimit;
}
if($attackerGenCnt != $attackerGenCnt_eff){
if ($attackerGenCnt != $attackerGenCnt_eff) {
$attackerIncTech *= $attackerGenCnt / $attackerGenCnt_eff;
}
if($defenderGenCnt != $defenderGenCnt_eff){
if ($defenderGenCnt != $defenderGenCnt_eff) {
$defenderIncTech *= $defenderGenCnt / $defenderGenCnt_eff;
}
if(TechLimit($startYear, $year, $rawAttackerNation['tech'])){
if (TechLimit($startYear, $year, $rawAttackerNation['tech'])) {
$attackerIncTech /= 4;
}
if(TechLimit($startYear, $year, $rawDefenderNation['tech'])){
if (TechLimit($startYear, $year, $rawDefenderNation['tech'])) {
$defenderIncTech /= 4;
}
@@ -159,41 +158,42 @@ function processWar(General $attackerGeneral, array $rawAttackerNation, array $r
$db->update('nation', $updateDefenderNation, 'nation=%i', $defenderNationID);
$db->update('diplomacy', [
'dead'=>$db->sqleval('dead + %i', $attacker->getDead())
'dead' => $db->sqleval('dead + %i', $attacker->getDead())
], 'me = %i and you = %i', $attackerNationID, $defenderNationID);
$db->update('diplomacy', [
'dead'=>$db->sqleval('dead + %i', $attacker->getKilled())
'dead' => $db->sqleval('dead + %i', $attacker->getKilled())
], 'me = %i and you = %i', $defenderNationID, $attackerNationID);
if(!$conquerCity){
if (!$conquerCity) {
return;
}
ConquerCity([
'startyear'=>$startYear,
'year'=>$year,
'month'=>$month,
'city_rate'=>$cityRate,
'join_mode'=>$joinMode,
'startyear' => $startYear,
'year' => $year,
'month' => $month,
'city_rate' => $cityRate,
'join_mode' => $joinMode,
], $attacker->getGeneral(), $city->getRaw());
}
function extractBattleOrder(General $general){
if($general->getVar('crew') == 0){
function extractBattleOrder(General $general)
{
if ($general->getVar('crew') == 0) {
return 0;
}
if($general->getVar('rice') <= $general->getVar('crew') / 100){
if ($general->getVar('rice') <= $general->getVar('crew') / 100) {
return 0;
}
$defence_train = $general->getVar('defence_train');
if($general->getVar('train') < $defence_train){
if ($general->getVar('train') < $defence_train) {
return 0;
}
if($general->getVar('atmos') < $defence_train){
if ($general->getVar('atmos') < $defence_train) {
return 0;
}
@@ -210,8 +210,8 @@ function processWar_NG(
callable $getNextDefender,
WarUnitCity $city,
int $relYear
):bool{
$templates = new \League\Plates\Engine(__DIR__.'/templates');
): bool {
$templates = new \League\Plates\Engine(__DIR__ . '/templates');
$logger = $attacker->getLogger();
@@ -231,11 +231,11 @@ function processWar_NG(
$logger->pushGlobalActionLog("<D><b>{$attacker->getNationVar('name')}</b></>의 <Y>{$attacker->getName()}</>{$josaYi} <G><b>{$city->getName()}</b></>{$josaRo} 진격합니다.");
$logger->pushGeneralActionLog("<G><b>{$city->getName()}</b></>{$josaRo} <M>진격</>합니다. <1>$date</>");
for($currPhase = 0; $currPhase < $attacker->getMaxPhase(); $currPhase+=1){
if($defender === null){
for ($currPhase = 0; $currPhase < $attacker->getMaxPhase(); $currPhase += 1) {
if ($defender === null) {
$defender = $city;
if($city->getNationVar('rice') <= 0 && $city->getVar('supply')){
if ($city->getNationVar('rice') <= 0 && $city->getVar('supply')) {
//병량 패퇴
$attacker->setOppose($defender);
$defender->setOppose($attacker);
@@ -256,7 +256,7 @@ function processWar_NG(
}
}
if($defender->getPhase() == 0){
if ($defender->getPhase() == 0) {
$defender->setPrePhase($currPhase);
$attacker->addTrain(1);
@@ -276,7 +276,7 @@ function processWar_NG(
$attackerName = $attacker->getName();
$attackerCrewTypeName = $attacker->getCrewTypeName();
if($defender instanceof WarUnitGeneral){
if ($defender instanceof WarUnitGeneral) {
$defenderName = $defender->getName();
$defenderCrewTypeName = $defender->getCrewTypeName();
@@ -291,8 +291,7 @@ function processWar_NG(
$josaRo = JosaUtil::pick($defenderCrewTypeName, '로');
$josaUl = JosaUtil::pick($attackerCrewTypeName, '을');
$defender->getLogger()->pushGeneralActionLog("{$defenderCrewTypeName}{$josaRo} <Y>{$attackerName}</>의 {$attackerCrewTypeName}{$josaUl} <M>수비</>합니다.");
}
else{
} else {
$josaYi = JosaUtil::pick($attackerName, '이');
$josaRo = JosaUtil::pick($attackerCrewTypeName, '로');
$logger->pushGlobalActionLog("<Y>{$attackerName}</>{$josaYi} {$attackerCrewTypeName}{$josaRo} 성벽을 공격합니다.");
@@ -324,16 +323,15 @@ function processWar_NG(
$attackerHP = $attacker->getHP();
$defenderHP = $defender->getHP();
if($deadAttacker > $attackerHP || $deadDefender > $defenderHP){
if ($deadAttacker > $attackerHP || $deadDefender > $defenderHP) {
$deadAttackerRatio = $deadAttacker / max(1, $attackerHP);
$deadDefenderRatio = $deadDefender / max(1, $defenderHP);
if($deadDefenderRatio > $deadAttackerRatio){
if ($deadDefenderRatio > $deadAttackerRatio) {
//수비자가 더 병력 부족
$deadAttacker /= $deadDefenderRatio;
$deadDefender = $defenderHP;
}
else{
} else {
//공격자가 더 병력 부족
$deadDefender /= $deadAttackerRatio;
$deadAttacker = $attackerHP;
@@ -351,7 +349,7 @@ function processWar_NG(
$phaseNickname = $currPhase + 1;
if($deadAttacker > 0 || $deadDefender > 0){
if ($deadAttacker > 0 || $deadDefender > 0) {
$attacker->getLogger()->pushGeneralBattleDetailLog(
"$phaseNickname : <Y1>【{$attacker->getName()}】</> <C>{$attacker->getHP()} (-$deadAttacker)</> VS <C>{$defender->getHP()} (-$deadDefender)</> <Y1>【{$defender->getName()}】</>"
);
@@ -365,7 +363,7 @@ function processWar_NG(
$attacker->addPhase();
$defender->addPhase();
if(!$attacker->continueWar($noRice)){
if (!$attacker->continueWar($noRice)) {
$attacker->logBattleResult();
$defender->logBattleResult();
@@ -377,10 +375,9 @@ function processWar_NG(
$josaYi = JosaUtil::pick($attacker->getCrewTypeName(), '이');
$logger->pushGlobalActionLog("<Y>{$attacker->getName()}</>의 {$attacker->getCrewTypeName()}{$josaYi} 퇴각했습니다.");
if($noRice){
if ($noRice) {
$attacker->getLogger()->pushGeneralActionLog("군량 부족으로 퇴각합니다.", ActionLogger::PLAIN);
}
else{
} else {
$attacker->getLogger()->pushGeneralActionLog("퇴각했습니다.", ActionLogger::PLAIN);
}
$defender->getLogger()->pushGeneralActionLog("<Y>{$attacker->getName()}</>의 {$attacker->getCrewTypeName()}{$josaYi} 퇴각했습니다.", ActionLogger::PLAIN);
@@ -388,7 +385,7 @@ function processWar_NG(
break;
}
if(!$defender->continueWar($noRice)){
if (!$defender->continueWar($noRice)) {
$attacker->logBattleResult();
$defender->logBattleResult();
@@ -399,7 +396,7 @@ function processWar_NG(
$attacker->tryWound();
$defender->tryWound();
if($defender === $city){
if ($defender === $city) {
$attacker->addLevelExp(1000);
$conquerCity = true;
break;
@@ -407,33 +404,30 @@ function processWar_NG(
$josaYi = JosaUtil::pick($defender->getCrewTypeName(), '이');
if($noRice){
if ($noRice) {
$logger->pushGlobalActionLog("<Y>{$defender->getName()}</>의 {$defender->getCrewTypeName()}{$josaYi} 패퇴했습니다.");
$attacker->getLogger()->pushGeneralActionLog("<Y>{$defender->getName()}</>의 {$defender->getCrewTypeName()}{$josaYi} 패퇴했습니다.", ActionLogger::PLAIN);
$attacker->getLogger()->pushGeneralActionLog("<Y>{$defender->getName()}</>의 {$defender->getCrewTypeName()}{$josaYi} 패퇴했습니다.", ActionLogger::PLAIN);
$defender->getLogger()->pushGeneralActionLog("군량 부족으로 패퇴합니다.", ActionLogger::PLAIN);
}
else{
} else {
$logger->pushGlobalActionLog("<Y>{$defender->getName()}</>의 {$defender->getCrewTypeName()}{$josaYi} 전멸했습니다.");
$attacker->getLogger()->pushGeneralActionLog("<Y>{$defender->getName()}</>의 {$defender->getCrewTypeName()}{$josaYi} 전멸했습니다.", ActionLogger::PLAIN);
$attacker->getLogger()->pushGeneralActionLog("<Y>{$defender->getName()}</>의 {$defender->getCrewTypeName()}{$josaYi} 전멸했습니다.", ActionLogger::PLAIN);
$defender->getLogger()->pushGeneralActionLog("전멸했습니다.", ActionLogger::PLAIN);
}
if($currPhase + 1 == $attacker->getMaxPhase()){
if ($currPhase + 1 == $attacker->getMaxPhase()) {
break;
}
$defender->finishBattle();
$defender = ($getNextDefender)($defender, true);
if($defender !== null && !($defender instanceof WarUnitGeneral)){
if ($defender !== null && !($defender instanceof WarUnitGeneral)) {
throw new \RuntimeException('다음 수비자를 받아오는데 실패');
}
}
}
if($currPhase == $attacker->getMaxPhase()){
if ($currPhase == $attacker->getMaxPhase()) {
//마지막 페이즈의 전투 마무리
$attacker->logBattleResult();
$defender->logBattleResult();
@@ -445,9 +439,9 @@ function processWar_NG(
$attacker->finishBattle();
$defender->finishBattle();
if($defender instanceof WarUnitCity){
if ($defender instanceof WarUnitCity) {
$newConflict = $defender->addConflict();
if($newConflict){
if ($newConflict) {
$nationName = $attacker->getNationVar('name');
$josaYi = JosaUtil::pick($nationName, '이');
$logger->pushGlobalHistoryLog("<M><b>【분쟁】</b></><D><b>{$nationName}</b></>{$josaYi} <G><b>{$defender->getName()}</b></> 공략에 가담하여 분쟁이 발생하고 있습니다.");
@@ -459,33 +453,36 @@ function processWar_NG(
return $conquerCity;
}
function DeleteConflict($nation) {
function DeleteConflict($nation)
{
$db = DB::db();
foreach($db->queryAllLists('SELECT city, conflict FROM city WHERE conflict!=%s', '{}') as list($cityID, $rawConflict)){
foreach ($db->queryAllLists('SELECT city, conflict FROM city WHERE conflict!=%s', '{}') as list($cityID, $rawConflict)) {
$conflict = Json::decode($rawConflict);
if(!$conflict || !is_array($conflict)){
if (!$conflict || !is_array($conflict)) {
continue;
}
if(!key_exists($nation, $conflict)){
if (!key_exists($nation, $conflict)) {
continue;
}
unset($conflict[$nation]);
$db->update('city', [
'conflict'=>Json::encode($conflict)
'conflict' => Json::encode($conflict)
], 'city=%i', $cityID);
}
}
function getConquerNation($city) : int {
function getConquerNation($city): int
{
$conflict = Json::decode($city['conflict']);
return Util::array_first_key($conflict);
}
function ConquerCity(array $admin, General $general, array $city) {
function ConquerCity(array $admin, General $general, array $city)
{
$db = DB::db();
$year = $admin['year'];
@@ -506,7 +503,7 @@ function ConquerCity(array $admin, General $general, array $city) {
$defenderNationLogger = new ActionLogger(0, $defenderNationID, $year, $month);
if($defenderNationID) {
if ($defenderNationID) {
$defenderNationDecoration = "<D><b>{$defenderNationName}</b></>의";
} else {
$defenderNationDecoration = "공백지인";
@@ -524,8 +521,29 @@ function ConquerCity(array $admin, General $general, array $city) {
$defenderNationLogger->pushNationalHistoryLog("<D><b>{$attackerNationName}</b></>의 <Y>{$attackerGeneralName}</>에 의해 <G><b>{$cityName}</b></>{$josaYiCity} <O>함락</>");
$gameStor = KVStorage::getStorage($db, 'game_env');
// 이벤트 핸들러 동작
$e_env = null;
foreach (DB::db()->query('SELECT * FROM event WHERE target = "OCCUPY_CITY" ORDER BY `priority` DESC, `id` ASC') as $rawEvent) {
if ($e_env === null) {
$e_env = $gameStor->getAll(false);
}
$eventID = $rawEvent['id'];
$cond = Json::decode($rawEvent['condition']);
$action = Json::decode($rawEvent['action']);
$event = new Event\EventHandler($cond, $action);
$e_env['currentEventID'] = $eventID;
$event->tryRunEvent($e_env);
}
if ($e_env !== null) {
$gameStor->resetCache();
}
// 국가 멸망시
if($defenderNationID && $db->queryFirstField('SELECT count(city) FROM city WHERE nation = %i', $defenderNationID) === 1) {
if ($defenderNationID && $db->queryFirstField('SELECT count(city) FROM city WHERE nation = %i', $defenderNationID) === 1) {
$defenderNationLogger->flush();
unset($defenderNationLogger);
@@ -545,17 +563,17 @@ function ConquerCity(array $admin, General $general, array $city) {
$loseGeneralGold = 0;
$loseGeneralRice = 0;
foreach($oldNationGenerals as $oldGeneral){
$loseGold = intdiv($oldGeneral->getVar('gold') * (rand()%30+20), 100);
$loseRice = intdiv($oldGeneral->getVar('rice') * (rand()%30+20), 100);
foreach ($oldNationGenerals as $oldGeneral) {
$loseGold = intdiv($oldGeneral->getVar('gold') * (rand() % 30 + 20), 100);
$loseRice = intdiv($oldGeneral->getVar('rice') * (rand() % 30 + 20), 100);
$oldGeneral->getLogger()->pushGeneralActionLog(
"도주하며 금<C>$loseGold</> 쌀<C>$loseRice</>을 분실했습니다.",
ActionLogger::PLAIN
);
$oldGeneral->increaseVar('gold', -$loseGold);
$oldGeneral->increaseVar('rice', -$loseRice);
$oldGeneral->addExperience(-$oldGeneral->getVar('experience')*0.1, false);
$oldGeneral->addDedication(-$oldGeneral->getVar('dedication')*0.5, false);
$oldGeneral->addExperience(-$oldGeneral->getVar('experience') * 0.1, false);
$oldGeneral->addDedication(-$oldGeneral->getVar('dedication') * 0.5, false);
$loseGeneralGold += $loseGold;
$loseGeneralRice += $loseRice;
@@ -563,21 +581,21 @@ function ConquerCity(array $admin, General $general, array $city) {
$oldGeneral->applyDB($db);
//모두 등용장 발부
if($admin['join_mode'] != 'onlyRandom' && Util::randBool(0.5)) {
if ($admin['join_mode'] != 'onlyRandom' && Util::randBool(0.5)) {
$msg = ScoutMessage::buildScoutMessage($attackerID, $oldGeneral->getID());
if($msg){
if ($msg) {
$msg->send(true);
}
}
//NPC인 경우 일정 확률로 임관(엔장, 인재, 의병)
$npcType = $oldGeneral->getNPCType();
if($admin['join_mode'] != 'onlyRandom' && 2 <= $npcType && $npcType <= 8 && $npcType != 5 && Util::randBool(GameConst::$joinRuinedNPCProp)) {
if ($admin['join_mode'] != 'onlyRandom' && 2 <= $npcType && $npcType <= 8 && $npcType != 5 && Util::randBool(GameConst::$joinRuinedNPCProp)) {
$cmd = buildGeneralCommandClass('che_임관', $oldGeneral, $admin, [
'destNationID'=>$attackerNationID
'destNationID' => $attackerNationID
]);
$joinTurn = Util::randRangeInt(0, 12);
if($joinTurn){
if ($joinTurn) {
_setGeneralCommand(buildGeneralCommandClass('che_견문', $oldGeneral, $admin), iterator_to_array(Util::range($joinTurn)));
}
_setGeneralCommand($cmd, [$joinTurn]);
@@ -596,37 +614,56 @@ function ConquerCity(array $admin, General $general, array $city) {
// 기본량 제외 금쌀50% + 장수들 분실 금쌀50% 흡수
$db->update('nation', [
'gold'=>$db->sqleval('gold + %i', $loseNationGold),
'rice'=>$db->sqleval('rice + %i', $loseNationRice),
'gold' => $db->sqleval('gold + %i', $loseNationGold),
'rice' => $db->sqleval('rice + %i', $loseNationRice),
], 'nation=%i', $attackerNationID);
//아국 수뇌부에게 로그 전달
$loseNationGoldText = number_format($loseNationGold);
$loseNationRiceText = number_format($loseNationRice);
$resourceLog = "<D><b>{$defenderNationName}</b></> 정복으로 금<C>{$loseNationGoldText}</> 쌀<C>{$loseNationRiceText}</>을 획득했습니다.";
foreach($db->queryFirstColumn(
'SELECT no FROM general WHERE nation=%i AND officer_level>=5', $attackerNationID
) as $attackerChiefID
){
if($attackerChiefID == $attackerID){
foreach ($db->queryFirstColumn(
'SELECT no FROM general WHERE nation=%i AND officer_level>=5',
$attackerNationID
) as $attackerChiefID) {
if ($attackerChiefID == $attackerID) {
$attackerLogger->pushGeneralActionLog($resourceLog, ActionLogger::PLAIN);
}
else{
} else {
$chiefLogger = new ActionLogger($attackerChiefID, $attackerNationID, $year, $month);
$chiefLogger->pushGeneralActionLog($resourceLog, ActionLogger::PLAIN);
$chiefLogger->flush();
}
}
// 멸망이 아니면
// 이벤트 핸들러 동작
$e_env = null;
foreach (DB::db()->query('SELECT * FROM event WHERE target = "DESTROY_NATION" ORDER BY `priority` DESC, `id` ASC') as $rawEvent) {
if ($e_env === null) {
$e_env = $gameStor->getAll(false);
}
$eventID = $rawEvent['id'];
$cond = Json::decode($rawEvent['condition']);
$action = Json::decode($rawEvent['action']);
$event = new Event\EventHandler($cond, $action);
$e_env['currentEventID'] = $eventID;
$event->tryRunEvent($e_env);
}
if ($e_env !== null) {
$gameStor->resetCache();
}
// 멸망이 아니면
} else {
// 태수,군사,종사은 일반으로...
$db->update('general',[
'officer_level'=>1,
'officer_city'=>0,
], 'officer_city = %i',$cityID);
$db->update('general', [
'officer_level' => 1,
'officer_city' => 0,
], 'officer_city = %i', $cityID);
//수도였으면 긴급 천도
if($defenderNationID && $defenderStaticNation['capital'] == $cityID) {
if ($defenderNationID && $defenderStaticNation['capital'] == $cityID) {
$minCity = findNextCapital($cityID, $defenderNationID);
$minCityName = CityConst::byID($minCity)->name;
@@ -636,10 +673,10 @@ function ConquerCity(array $admin, General $general, array $city) {
$moveLog = "수도가 함락되어 <G><b>$minCityName</b></>으로 <M>긴급천도</>합니다.";
//아국 수뇌부에게 로그 전달
foreach($db->queryFirstColumn(
'SELECT no FROM general WHERE nation=%i AND officer_level>=5', $defenderNationID
) as $defenderChiefID
){
foreach ($db->queryFirstColumn(
'SELECT no FROM general WHERE nation=%i AND officer_level>=5',
$defenderNationID
) as $defenderChiefID) {
$chiefLogger = new ActionLogger($defenderChiefID, $defenderNationID, $year, $month);
$chiefLogger->pushGeneralActionLog($moveLog, ActionLogger::PLAIN);
$chiefLogger->flush();
@@ -647,22 +684,22 @@ function ConquerCity(array $admin, General $general, array $city) {
//천도
$db->update('nation', [
'capital'=>$minCity,
'gold'=>$db->sqleval('gold * 0.5'),
'rice'=>$db->sqleval('rice * 0.5'),
'capital' => $minCity,
'gold' => $db->sqleval('gold * 0.5'),
'rice' => $db->sqleval('rice * 0.5'),
], 'nation=%i', $defenderNationID);
//보급도시로 만듬
$db->update('city', [
'supply'=>1
'supply' => 1
], 'city=%i', $minCity);
//수뇌부 이동
$db->update('general', [
'city'=>$minCity
], 'nation=%i AND officer_level>=5',$defenderNationID);
'city' => $minCity
], 'nation=%i AND officer_level>=5', $defenderNationID);
//장수 사기 감소
$db->update('general', [
'atmos'=>$db->sqleval('atmos*0.8')
], 'nation=%i',$defenderNationID);
'atmos' => $db->sqleval('atmos*0.8')
], 'nation=%i', $defenderNationID);
refreshNationStaticInfo();
}
@@ -673,10 +710,9 @@ function ConquerCity(array $admin, General $general, array $city) {
if ($conquerNation == $attackerNationID) {
// 이동
$db->update('general', [
'city'=>$cityID
'city' => $cityID
], 'no=%i', $attackerID);
}
else{
} else {
$conquerNationName = getNationStaticInfo($conquerNation)['name'];
$conquerNationLogger = new ActionLogger(0, $conquerNation, $year, $month);
@@ -690,16 +726,16 @@ function ConquerCity(array $admin, General $general, array $city) {
}
$query = [
'supply'=>1,
'term'=>0,
'conflict'=>'{}',
'agri'=>$db->sqleval('agri*0.7'),
'comm'=>$db->sqleval('comm*0.7'),
'secu'=>$db->sqleval('secu*0.7'),
'nation'=>$conquerNation,
'officer_set'=>0,
'supply' => 1,
'term' => 0,
'conflict' => '{}',
'agri' => $db->sqleval('agri*0.7'),
'comm' => $db->sqleval('comm*0.7'),
'secu' => $db->sqleval('secu*0.7'),
'nation' => $conquerNation,
'officer_set' => 0,
];
if($city['level'] > 3) {
if ($city['level'] > 3) {
$query['def'] = 1000;
$query['wall'] = 1000;
} else {
@@ -717,45 +753,44 @@ function ConquerCity(array $admin, General $general, array $city) {
$nearNationsID[] = $conquerNation;
$nearNationsID = array_unique($nearNationsID);
foreach($nearNationsID as $nationNationID){
foreach ($nearNationsID as $nationNationID) {
SetNationFront($nationNationID);
}
}
function findNextCapital(int $capitalID, int $nationID):int{
function findNextCapital(int $capitalID, int $nationID): int
{
$distList = searchDistance($capitalID, 99, true);
$cities = [];
foreach(
DB::db()->query(
foreach (DB::db()->query(
'SELECT city, pop FROM city WHERE nation=%i and city!=%i',
$nationID,
$capitalID
) as $row
){
) as $row) {
$cities[$row['city']] = $row['pop'];
};
foreach($distList as $dist=>$distSubList){
foreach ($distList as $dist => $distSubList) {
$maxCityPop = 0;
$minCity = 0;
foreach($distSubList as $cityID){
if(!key_exists($cityID, $cities)){
foreach ($distSubList as $cityID) {
if (!key_exists($cityID, $cities)) {
continue;
}
$cityPop = $cities[$cityID];
if($cityPop < $maxCityPop){
if ($cityPop < $maxCityPop) {
continue;
}
$minCity = $cityID;
$maxCityPop = $cityPop;
}
if($minCity){
if ($minCity) {
return $minCity;
}
}
throw new \RuntimeException('도시가 남지 않았는데 긴천을 시도하고 있습니다');
}
}
+63
View File
@@ -0,0 +1,63 @@
<?php
namespace sammo\API\Betting;
use sammo\Session;
use DateTimeInterface;
use sammo\Betting;
use sammo\DB;
use sammo\DTO\BettingItem;
use sammo\Validator;
use sammo\GameConst;
use sammo\KVStorage;
use sammo\UserLogger;
use sammo\Util;
class Bet extends \sammo\BaseAPI
{
public function validateArgs(): ?string
{
$v = new Validator($this->args);
$v->rule('required', [
'bettingID',
'bettingType',
'amount'
])
->rule('integer', 'bettingID')
->rule('integerArray', 'bettingType')
->rule('integer', 'amount')
->rule('min', 'amount', 1);
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)
{
/** @var int */
$bettingID = $this->args['bettingID'];
/** @var int[] */
$bettingType = $this->args['bettingType'];
/** @var int */
$amount = $this->args['amount'];
$bettingHelper = new Betting($bettingID);
try{
$bettingHelper->bet($session->generalID, $session->userID, $bettingType, $amount);
}
catch(\Throwable $e){
return $e->getMessage();
}
return [
'result' => true
];
}
}
@@ -0,0 +1,97 @@
<?php
namespace sammo\API\Betting;
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
{
$v = new Validator($this->args);
$v->rule('required', [
'betting_id',
])
->rule('integer', 'betting_id');
if (!$v->validate()) {
return $v->errorStr();
}
return null;
}
public function getRequiredSessionMode(): int
{
return static::REQ_GAME_LOGIN | static::REQ_READ_ONLY;
}
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag)
{
$db = DB::db();
/** @var int */
$bettingID = $this->args['betting_id'];
$gameStor = KVStorage::getStorage($db, 'game_env');
$bettingStor = KVStorage::getStorage($db, 'betting');
$rawBettingInfo = $bettingStor->getValue("id_{$bettingID}");
if($rawBettingInfo === null){
return '해당 베팅이 없습니다';
}
try{
$bettingInfo = new BettingInfo($rawBettingInfo);
}
catch(\Error $e){
return $e->getMessage();
}
[$year, $month] = $gameStor->getValuesAsArray(['year', 'month']);
$bettingDetail = [];
foreach ($db->queryAllLists(
'SELECT betting_type, sum(amount) as sum_amount FROM ng_betting WHERE betting_id = %i GROUP BY betting_type',
$bettingID
) as [$bettingType, $amount]) {
$bettingDetail[] = [$bettingType, Util::toInt($amount)];
}
[$year, $month] = $gameStor->getValuesAsArray(['year', 'month']);
$myBetting = [];
foreach($db->queryAllLists(
'SELECT betting_type, sum(amount) as sum_amount FROM ng_betting WHERE betting_id = %i AND user_id = %i GROUP BY betting_type',
$bettingID, $session->userID
) as [$bettingType, $amount]){
$myBetting[] = [$bettingType, Util::toInt($amount)];
}
if($bettingInfo->reqInheritancePoint){
$inheritStor = KVStorage::getStorage($db, "inheritance_{$session->userID}");
$remainPoint = ($inheritStor->getValue('previous') ?? [0,0])[0];
}
else{
$remainPoint = $db->queryFirstField('SELECT gold FROM general WHERE no = %i', $session->generalID)??0;
}
return [
'result' => true,
'bettingInfo' => $rawBettingInfo,
'bettingDetail' => $bettingDetail,
'myBetting' => $myBetting,
'remainPoint' => $remainPoint,
'year' => $year,
'month' => $month,
];
}
}
+81
View File
@@ -0,0 +1,81 @@
<?php
namespace sammo\API\Betting;
use sammo\Session;
use DateTimeInterface;
use sammo\DB;
use sammo\DTO\BettingInfo;
use sammo\KVStorage;
use function sammo\checkLimit;
use function sammo\increaseRefresh;
class GetBettingList 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)
{
$db = DB::db();
increaseRefresh("베팅장", 1);
$gameStor = KVStorage::getStorage($db, 'game_env');
$bettingStor = KVStorage::getStorage($db, 'betting');
$userID = $session->userID;
$me = $db->queryFirstRow('SELECT no,nation,officer_level,con,turntime,belong,penalty,permission FROM general WHERE owner=%i', $userID);
$con = checkLimit($me['con']);
if ($con >= 2) {
return "접속 제한중입니다.";
}
$bettingList = [];
foreach ($bettingStor->getAll() as $_key => $rawItem) {
$item = new BettingInfo($rawItem);
unset($rawItem['candidates']);
$bettingList[$item->id] = $rawItem;
$bettingList[$item->id]['totalAmount'] = 0;
}
[$year, $month] = $gameStor->getValuesAsArray(['year', 'month']);
if(!$bettingList){
return [
'result' => true,
'bettingList' => $bettingList,
'year' => $year,
'month' => $month,
];
}
$bettingIDList = array_keys($bettingList);
// XXX: query cache만 믿고 sum을 하는 짓을 벌여도 되는가?
foreach ($db->queryAllLists(
'SELECT betting_id, sum(amount) as total_amount FROM ng_betting WHERE betting_id IN %li GROUP BY betting_id',
$bettingIDList
) as [$bettingID, $totalAmount]) {
if (!key_exists($bettingID, $bettingList)) {
continue;
}
$bettingList[$bettingID]['totalAmount'] = $totalAmount;
}
return [
'result' => true,
'bettingList' => $bettingList,
'year' => $year,
'month' => $month,
];
}
}
+65
View File
@@ -0,0 +1,65 @@
<?php
namespace sammo\API\Global;
use sammo\Session;
use DateTimeInterface;
use sammo\DB;
use function sammo\getAllNationStaticInfo;
use function sammo\getNationStaticInfo;
class GetNationList extends \sammo\BaseAPI
{
public function validateArgs(): ?string
{
return null;
}
public function getRequiredSessionMode(): int
{
return static::REQ_LOGIN | static::REQ_READ_ONLY;
}
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag)
{
$db = DB::db();
$nations = getAllNationStaticInfo();
uasort($nations, function ($lhs, $rhs) {
return $rhs['power'] <=> $lhs['power'];
});
$nations[0] = getNationStaticInfo(0);
foreach ($db->query('SELECT npc,name,nation,officer_level,permission FROM `general` ORDER BY dedication DESC') as $general) {
$nationID = $general['nation'];
$permission = $general['permission'];
if($permission != 'auditor' && $permission != 'ambassador'){
unset($general['permission']);
}
if($general['officer_level'] < 5){
$general['officer_level'] = 1;
}
if (!key_exists('generals', $nations[$nationID])) {
$nations[$nationID]['generals'] = [];
}
$nations[$nationID]['generals'][] = $general;
}
foreach ($db->queryAllLists('SELECT city, name, nation FROM city') as [$cityID, $cityName, $nationID]) {
if (!key_exists('cities', $nations[$nationID])) {
$nations[$nationID]['cities'] = [];
}
$nations[$nationID]['cities'][$cityID] = $cityName;
}
return [
'result' => true,
'nations' => $nations,
];
}
}
+63
View File
@@ -0,0 +1,63 @@
<?php
namespace sammo\API\Nation;
use sammo\Session;
use DateTimeInterface;
use sammo\DB;
use sammo\KVStorage;
use sammo\Validator;
use sammo\WebUtil;
use function sammo\checkSecretPermission;
class SetBill extends \sammo\BaseAPI
{
public function validateArgs(): ?string
{
$v = new Validator($this->args);
$v->rule('required', [
'amount',
])
->rule('integer', 'amount')
->rule('min', 'amount', 20)
->rule('max', 'amount', 200);
if (!$v->validate()) {
return $v->errorStr();
}
return null;
}
public function getRequiredSessionMode(): int
{
return static::REQ_GAME_LOGIN | static::REQ_READ_ONLY;
}
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag)
{
$amount = $this->args['amount'];
$userID = $session->userID;
$db = DB::db();
$me = $db->queryFirstRow('SELECT `no`,nation,`officer_level`,permission,penalty FROM general WHERE `owner`=%i', $userID);
$permission = checkSecretPermission($me, false);
if($permission < 0){
return "권한이 부족합니다.";
}
if ($me['officer_level'] < 5 && $permission != 4){
return "권한이 부족합니다.";
}
$nationID = $me['nation'];
$db->update('nation', [
'bill' => $amount
], 'nation=%i', $nationID);
return [
'result' => true
];
}
}
+61
View File
@@ -0,0 +1,61 @@
<?php
namespace sammo\API\Nation;
use sammo\Session;
use DateTimeInterface;
use sammo\DB;
use sammo\KVStorage;
use sammo\Validator;
use sammo\WebUtil;
use function sammo\checkSecretPermission;
class SetBlockScout extends \sammo\BaseAPI
{
public function validateArgs(): ?string
{
$v = new Validator($this->args);
$v->rule('required', [
'value',
])
->rule('boolean', 'value');
if (!$v->validate()) {
return $v->errorStr();
}
return null;
}
public function getRequiredSessionMode(): int
{
return static::REQ_GAME_LOGIN | static::REQ_READ_ONLY;
}
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag)
{
$value = $this->args['value'];
$userID = $session->userID;
$db = DB::db();
$me = $db->queryFirstRow('SELECT `no`,nation,`officer_level`,permission,penalty FROM general WHERE `owner`=%i', $userID);
$permission = checkSecretPermission($me, false);
if($permission < 0){
return "권한이 부족합니다.";
}
if ($me['officer_level'] < 5 && $permission != 4){
return "권한이 부족합니다.";
}
$nationID = $me['nation'];
$db->update('nation', [
'scout' => $value?1:0,
], 'nation=%i', $nationID);
return [
'result' => true
];
}
}
+70
View File
@@ -0,0 +1,70 @@
<?php
namespace sammo\API\Nation;
use sammo\Session;
use DateTimeInterface;
use sammo\DB;
use sammo\KVStorage;
use sammo\Validator;
use sammo\WebUtil;
use function sammo\checkSecretPermission;
class SetBlockWar extends \sammo\BaseAPI
{
public function validateArgs(): ?string
{
$v = new Validator($this->args);
$v->rule('required', [
'value',
])
->rule('boolean', 'value');
if (!$v->validate()) {
return $v->errorStr();
}
return null;
}
public function getRequiredSessionMode(): int
{
return static::REQ_GAME_LOGIN | static::REQ_READ_ONLY;
}
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag)
{
$value = $this->args['value'];
$userID = $session->userID;
$db = DB::db();
$me = $db->queryFirstRow('SELECT `no`,nation,`officer_level`,permission,penalty FROM general WHERE `owner`=%i', $userID);
$permission = checkSecretPermission($me, false);
if($permission < 0){
return "권한이 부족합니다.";
}
if ($me['officer_level'] < 5 && $permission != 4){
return "권한이 부족합니다.";
}
$nationID = $me['nation'];
$nationStor = KVStorage::getStorage($db, $nationID, 'nation_env');
$avilableCnt = $nationStor->getValue('available_war_setting_cnt') ?? 0;
if ($avilableCnt <= 0){
return "잔여 횟수가 부족합니다.";
}
$db->update('nation', [
'war' => $value?1:0,
], 'nation=%i', $nationID);
$nationStor->setValue('available_war_setting_cnt', $avilableCnt - 1);
return [
'result' => true,
'availableCnt' => $avilableCnt - 1,
];
}
}
+63
View File
@@ -0,0 +1,63 @@
<?php
namespace sammo\API\Nation;
use sammo\Session;
use DateTimeInterface;
use sammo\DB;
use sammo\KVStorage;
use sammo\Validator;
use sammo\WebUtil;
use function sammo\checkSecretPermission;
class SetRate extends \sammo\BaseAPI
{
public function validateArgs(): ?string
{
$v = new Validator($this->args);
$v->rule('required', [
'amount',
])
->rule('integer', 'amount')
->rule('min', 'amount', 5)
->rule('max', 'amount', 30);
if (!$v->validate()) {
return $v->errorStr();
}
return null;
}
public function getRequiredSessionMode(): int
{
return static::REQ_GAME_LOGIN | static::REQ_READ_ONLY;
}
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag)
{
$amount = $this->args['amount'];
$userID = $session->userID;
$db = DB::db();
$me = $db->queryFirstRow('SELECT `no`,nation,`officer_level`,permission,penalty FROM general WHERE `owner`=%i', $userID);
$permission = checkSecretPermission($me, false);
if($permission < 0){
return "권한이 부족합니다.";
}
if ($me['officer_level'] < 5 && $permission != 4){
return "권한이 부족합니다.";
}
$nationID = $me['nation'];
$db->update('nation', [
'rate' => $amount
], 'nation=%i', $nationID);
return [
'result' => true
];
}
}
+63
View File
@@ -0,0 +1,63 @@
<?php
namespace sammo\API\Nation;
use sammo\Session;
use DateTimeInterface;
use sammo\DB;
use sammo\KVStorage;
use sammo\Validator;
use sammo\WebUtil;
use function sammo\checkSecretPermission;
class SetSecretLimit extends \sammo\BaseAPI
{
public function validateArgs(): ?string
{
$v = new Validator($this->args);
$v->rule('required', [
'amount',
])
->rule('integer', 'amount')
->rule('min', 'amount', 1)
->rule('max', 'amount', 99);
if (!$v->validate()) {
return $v->errorStr();
}
return null;
}
public function getRequiredSessionMode(): int
{
return static::REQ_GAME_LOGIN | static::REQ_READ_ONLY;
}
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag)
{
$amount = $this->args['amount'];
$userID = $session->userID;
$db = DB::db();
$me = $db->queryFirstRow('SELECT `no`,nation,`officer_level`,permission,penalty FROM general WHERE `owner`=%i', $userID);
$permission = checkSecretPermission($me, false);
if($permission < 0){
return "권한이 부족합니다.";
}
if ($me['officer_level'] < 5 && $permission != 4){
return "권한이 부족합니다.";
}
$nationID = $me['nation'];
$db->update('nation', [
'secretlimit' => $amount
], 'nation=%i', $nationID);
return [
'result' => true
];
}
}
-1
View File
@@ -5,7 +5,6 @@ use \sammo\General;
class None extends \sammo\BaseItem{
protected $id = 0;
protected $name = '-';
protected $info = null;
protected $cost = 0;
@@ -0,0 +1,23 @@
<?php
namespace sammo\ActionItem;
use \sammo\iAction;
use \sammo\General;
class che_간파_노군입산부 extends \sammo\BaseItem{
protected $rawName = '노군입산부';
protected $name = '노군입산부(간파)';
protected $info = '[전투] 상대 회피 확률 -30%p, 상대 필살 확률 -10%p';
protected $cost = 200;
protected $consumable = false;
public function onCalcOpposeStat(General $general, string $statName, $value, $aux=null){
if($statName === 'warAvoidRatio'){
return $value - 0.30;
}
if($statName === 'warCriticalRatio'){
return $value - 0.10;
}
return $value;
}
}
@@ -0,0 +1,25 @@
<?php
namespace sammo\ActionItem;
use \sammo\iAction;
use \sammo\General;
use \sammo\SpecialityHelper;
use \sammo\WarUnit;
use sammo\WarUnitTriggerCaller;
use sammo\WarUnitTrigger\che_격노시도;
use sammo\WarUnitTrigger\che_격노발동;
class che_격노_구정신단경 extends \sammo\BaseItem{
protected $rawName = '구정신단경';
protected $name = '구정신단경(격노)';
protected $info = '[전투] 상대방 필살 시 격노(필살) 발동, 회피 시도시 25% 확률로 격노 발동, 공격 시 일정 확률로 진노(1페이즈 추가)';
protected $cost = 200;
protected $consumable = false;
public function getBattlePhaseSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller{
return new WarUnitTriggerCaller(
new che_격노시도($unit, che_격노시도::TYPE_ITEM),
new che_격노발동($unit)
);
}
}
+1 -2
View File
@@ -5,7 +5,6 @@ use \sammo\General;
class che_계략_삼략 extends \sammo\BaseItem{
protected $id = 22;
protected $rawName = '삼략';
protected $name = '삼략(계략)';
protected $info = '[계략] 화계·탈취·파괴·선동 : 성공률 +20%p<br>[전투] 계략 시도 확률 +10%p, 계략 성공 확률 +10%p';
@@ -16,7 +15,7 @@ class che_계략_삼략 extends \sammo\BaseItem{
if($turnType == '계략'){
if($varType == 'success') return $value + 0.2;
}
return $value;
}
+1 -2
View File
@@ -5,7 +5,6 @@ use \sammo\General;
class che_계략_육도 extends \sammo\BaseItem{
protected $id = 21;
protected $rawName = '육도';
protected $name = '육도(계략)';
protected $info = '[계략] 화계·탈취·파괴·선동 : 성공률 +20%p<br>[전투] 계략 시도 확률 +10%p, 계략 성공 확률 +10%p';
@@ -16,7 +15,7 @@ class che_계략_육도 extends \sammo\BaseItem{
if($turnType == '계략'){
if($varType == 'success') return $value + 0.2;
}
return $value;
}
+2 -3
View File
@@ -5,7 +5,6 @@ use \sammo\General;
class che_계략_이추 extends \sammo\BaseItem{
protected $id = 5;
protected $rawName = '이추';
protected $name = '이추(계략)';
protected $info = '[계략] 화계·탈취·파괴·선동 : 성공률 +20%p';
@@ -18,11 +17,11 @@ class che_계략_이추 extends \sammo\BaseItem{
if($turnType == '계략'){
if($varType == 'success') return $value + 0.2;
}
return $value;
}
function isConsumableNow(string $actionType, string $command):bool{
function tryConsumeNow(General $general, string $actionType, string $command):bool{
if($actionType == 'GeneralCommand' && $command == '계략'){
return true;
}
+2 -3
View File
@@ -5,7 +5,6 @@ use \sammo\General;
class che_계략_향낭 extends \sammo\BaseItem{
protected $id = 5;
protected $rawName = '항냥';
protected $name = '항냥(계략)';
protected $info = '[계략] 화계·탈취·파괴·선동 : 성공률 +50%p';
@@ -18,11 +17,11 @@ class che_계략_향낭 extends \sammo\BaseItem{
if($turnType == '계략'){
if($varType == 'success') return $value + 0.5;
}
return $value;
}
function isConsumableNow(string $actionType, string $command):bool{
function tryConsumeNow(General $general, string $actionType, string $command):bool{
if($actionType == 'GeneralCommand' && $command == '계략'){
return true;
}
@@ -0,0 +1,24 @@
<?php
namespace sammo\ActionItem;
use \sammo\iAction;
use \sammo\General;
use \sammo\SpecialityHelper;
use \sammo\GameUnitConst;
use \sammo\WarUnit;
use \sammo\WarUnitCity;
class che_공성_묵자 extends \sammo\BaseItem{
protected $rawName = '묵자';
protected $name = '묵자(공성)';
protected $info = '[전투] 성벽 공격 시 대미지 +50%';
protected $cost = 200;
protected $consumable = false;
public function getWarPowerMultiplier(WarUnit $unit):array{
if($unit->getOppose() instanceof WarUnitCity){
return [1.5, 1];
}
return [1, 1];
}
}
@@ -0,0 +1,21 @@
<?php
namespace sammo\ActionItem;
use \sammo\iAction;
use \sammo\General;
use sammo\Util;
class che_내정_납금박산로 extends \sammo\BaseItem{
protected $rawName = '납금박산로';
protected $name = '납금박산로(내정)';
protected $info = '[내정] 내정 성공률 +20%p';
protected $cost = 200;
protected $consumable = false;
public function onCalcStrategic(string $turnType, string $varType, $value){
if(in_array($turnType, ['상업', '농업', '기술', '성벽', '수비', '치안', '민심', '인구'])){
if($varType == 'success') return $value + 0.2;
}
return $value;
}
}
@@ -0,0 +1,32 @@
<?php
namespace sammo\ActionItem;
use \sammo\iAction;
use \sammo\General;
use sammo\WarUnit;
class che_농성_위공자병법 extends \sammo\BaseItem{
protected $rawName = '위공자병법';
protected $name = '위공자병법(농성)';
protected $info = '[계략] 장수 주둔 도시 화계·탈취·파괴·선동 : 성공률 -30%p<br>[전투] 상대 계략 시도 확률 -10%p, 상대 계략 성공 확률 -10%p';
protected $cost = 200;
protected $consumable = false;
public function onCalcStat(General $general, string $statName, $value, $aux=null){
if($statName === 'sabotageDefence'){
return $value + 0.3;
}
return $value;
}
public function onCalcOpposeStat(General $general, string $statName, $value, $aux = null)
{
if($statName === 'warMagicTrialProb'){
return $value - 0.1;
}
if($statName === 'warMagicSuccessProb'){
return $value - 0.1;
}
return $value;
}
}
@@ -0,0 +1,32 @@
<?php
namespace sammo\ActionItem;
use \sammo\iAction;
use \sammo\General;
use sammo\WarUnit;
class che_농성_주서음부 extends \sammo\BaseItem{
protected $rawName = '주서음부';
protected $name = '주서음부(농성)';
protected $info = '[계략] 장수 주둔 도시 화계·탈취·파괴·선동 : 성공률 -30%p<br>[전투] 상대 계략 시도 확률 -10%p, 상대 계략 성공 확률 -10%p';
protected $cost = 200;
protected $consumable = false;
public function onCalcStat(General $general, string $statName, $value, $aux=null){
if($statName === 'sabotageDefence'){
return $value + 0.3;
}
return $value;
}
public function onCalcOpposeStat(General $general, string $statName, $value, $aux = null)
{
if($statName === 'warMagicTrialProb'){
return $value - 0.1;
}
if($statName === 'warMagicSuccessProb'){
return $value - 0.1;
}
return $value;
}
}
@@ -0,0 +1,28 @@
<?php
namespace sammo\ActionItem;
use sammo\DB;
use sammo\GameConst;
use \sammo\iAction;
use \sammo\General;
use sammo\KVStorage;
use sammo\Util;
class che_능력치_무력_두강주 extends \sammo\BaseItem{
protected $rawName = '두강주';
protected $name = '두강주(무력)';
protected $info = '[능력치] 무력 +5 +(5년마다 +1)';
protected $cost = 200;
protected $consumable = false;
public function onCalcStat(General $general, string $statName, $value, $aux=null){
if($statName === 'strength'){
$gameStor = KVStorage::getStorage(DB::db(), 'game_env');
[$year, $startYear] = $gameStor->getValuesAsArray(['year', 'startyear']);
$relYear = $year - $startYear;
return $value + 5 + Util::valueFit(intdiv($relYear, 5), 0, GameConst::$maxTechLevel);
}
return $value;
}
}
@@ -0,0 +1,28 @@
<?php
namespace sammo\ActionItem;
use sammo\DB;
use sammo\GameConst;
use \sammo\iAction;
use \sammo\General;
use sammo\KVStorage;
use sammo\Util;
class che_능력치_지력_이강주 extends \sammo\BaseItem{
protected $rawName = '이강주';
protected $name = '이강주(지력)';
protected $info = '[능력치] 지력 +5 +(5년마다 +1)';
protected $cost = 200;
protected $consumable = false;
public function onCalcStat(General $general, string $statName, $value, $aux=null){
if($statName === 'intel'){
$gameStor = KVStorage::getStorage(DB::db(), 'game_env');
[$year, $startYear] = $gameStor->getValuesAsArray(['year', 'startyear']);
$relYear = $year - $startYear;
return $value + 5 + Util::valueFit(intdiv($relYear, 5), 0, GameConst::$maxTechLevel);
}
return $value;
}
}
@@ -0,0 +1,28 @@
<?php
namespace sammo\ActionItem;
use sammo\DB;
use sammo\GameConst;
use \sammo\iAction;
use \sammo\General;
use sammo\KVStorage;
use sammo\Util;
class che_능력치_통솔_보령압주 extends \sammo\BaseItem{
protected $rawName = '보령압주';
protected $name = '보령압주(통솔)';
protected $info = '[능력치] 통솔 +5 +(5년마다 +1)';
protected $cost = 200;
protected $consumable = false;
public function onCalcStat(General $general, string $statName, $value, $aux=null){
if($statName === 'leadership'){
$gameStor = KVStorage::getStorage(DB::db(), 'game_env');
[$year, $startYear] = $gameStor->getValuesAsArray(['year', 'startyear']);
$relYear = $year - $startYear;
return $value + 5 + Util::valueFit(intdiv($relYear, 5), 0, GameConst::$maxTechLevel);
}
return $value;
}
}
@@ -0,0 +1,32 @@
<?php
namespace sammo\ActionItem;
use \sammo\iAction;
use \sammo\General;
use sammo\WarUnit;
class che_명마_07_백상 extends \sammo\BaseStatItem{
protected $cost = 200;
protected $buyable = false;
public function __construct()
{
parent::__construct();
$this->info .= "<br>[전투] 공격력 +20%, 소모 군량 +10%, 공격 시 페이즈 -1";
}
public function onCalcStat(General $general, string $statName, $value, $aux=null){
$value = parent::onCalcStat($general, $statName, $value, $aux);
if($statName == 'killRice'){
return $value * 1.1;
}
if($statName === 'initWarPhase'){
return $value - 1;
}
return $value;
}
public function getWarPowerMultiplier(WarUnit $unit): array
{
return [1.2, 1];
}
}
@@ -0,0 +1,7 @@
<?php
namespace sammo\ActionItem;
class che_명마_07_오환마 extends \sammo\BaseStatItem{
protected $cost = 200;
protected $buyable = false;
}
@@ -0,0 +1,7 @@
<?php
namespace sammo\ActionItem;
class che_명마_08_흉노마 extends \sammo\BaseStatItem{
protected $cost = 200;
protected $buyable = false;
}
@@ -0,0 +1,9 @@
<?php
namespace sammo\ActionItem;
use \sammo\iAction;
use \sammo\General;
class che_명마_09_의남백마 extends \sammo\BaseStatItem{
protected $cost = 200;
protected $buyable = false;
}
@@ -0,0 +1,9 @@
<?php
namespace sammo\ActionItem;
use \sammo\iAction;
use \sammo\General;
class che_명마_10_옥추마 extends \sammo\BaseStatItem{
protected $cost = 200;
protected $buyable = false;
}
@@ -0,0 +1,9 @@
<?php
namespace sammo\ActionItem;
use \sammo\iAction;
use \sammo\General;
class che_명마_11_화종마 extends \sammo\BaseStatItem{
protected $cost = 200;
protected $buyable = false;
}
@@ -0,0 +1,27 @@
<?php
namespace sammo\ActionItem;
use \sammo\iAction;
use \sammo\General;
class che_명마_12_옥란백용구 extends \sammo\BaseStatItem{
protected $cost = 200;
protected $buyable = false;
public function __construct()
{
parent::__construct();
$this->info .= "<br>[전투] 남은 병력이 적을수록 회피 확률 증가. 최대 +30%p";
}
public function onCalcStat(General $general, string $statName, $value, $aux = null)
{
$value = parent::onCalcStat($general, $statName, $value, $aux);
if($statName == 'warAvoidRatio'){
$leadership = $general->getLeadership(true, true, true, false);
$crewL = $general->getVar('crew') / 100;
return $value + \sammo\Util::valueFit((1 - $crewL / $leadership) * 0.3, 0, 0.3);
}
return $value;
}
}
@@ -0,0 +1,20 @@
<?php
namespace sammo\ActionItem;
use \sammo\iAction;
use \sammo\General;
class che_명성_구석 extends \sammo\BaseItem{
protected $rawName = '구석';
protected $name = '구석(명성)';
protected $info = '명성 +15%';
protected $cost = 200;
protected $consumable = false;
public function onCalcStat(General $general, string $statName, $value, $aux=null){
if($statName == 'experience'){
return $value * 1.15;
}
return $value;
}
}
@@ -15,7 +15,7 @@ class che_무기_02_단궁 extends \sammo\BaseStatItem{
public function __construct()
{
parent::__construct();
$this->info .= "<br>[전투] 새로운 상대와 전투 시 1% 확률로 저격 발동, 성공 시 사기+10";
$this->info .= "<br>[전투] 새로운 상대와 전투 시 1% 확률로 저격 발동, 성공 시 사기+20";
}
public function getBattlePhaseSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller{
@@ -14,7 +14,7 @@ class che_무기_07_맥궁 extends \sammo\BaseStatItem{
public function __construct()
{
parent::__construct();
$this->info .= "<br>[전투] 새로운 상대와 전투 시 20% 확률로 저격 발동, 성공 시 사기+10";
$this->info .= "<br>[전투] 새로운 상대와 전투 시 20% 확률로 저격 발동, 성공 시 사기+20";
}
public function getBattlePhaseSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller{
+12 -3
View File
@@ -12,10 +12,9 @@ use \sammo\WarUnitTrigger\che_반계발동;
class che_반계_백우선 extends \sammo\BaseItem{
protected $id = 45;
protected $rawName = '백우선';
protected $name = '백우선(반계)';
protected $info = '[전투] 상대의 계략 성공 확률 -10%p, 상대의 계략을 20% 확률로 되돌림';
protected $info = '[전투] 상대의 계략 성공 확률 -10%p, 상대의 계략을 30% 확률로 되돌림, 반목 성공시 대미지 추가(+60% → +100%), 소모 군량 +10%';
protected $cost = 200;
protected $consumable = false;
@@ -27,9 +26,19 @@ class che_반계_백우선 extends \sammo\BaseItem{
return $value - $debuff;
}
public function onCalcStat(General $general, string $statName, $value, $aux=null){
if($statName == 'killRice'){
return $value * 1.1;
}
if($statName === 'warMagicSuccessDamage' && $aux === '반목'){
return $value + 0.4;
}
return $value;
}
public function getBattlePhaseSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller{
return new WarUnitTriggerCaller(
new che_반계시도($unit, BaseWarUnitTrigger::TYPE_ITEM +BaseWarUnitTrigger::TYPE_DEDUP_TYPE_BASE*301, 0.2),
new che_반계시도($unit, BaseWarUnitTrigger::TYPE_ITEM +BaseWarUnitTrigger::TYPE_DEDUP_TYPE_BASE*301, 0.3),
new che_반계발동($unit)
);
}
@@ -12,7 +12,6 @@ use \sammo\WarUnitTrigger\che_반계발동;
class che_반계_파초선 extends \sammo\BaseItem{
protected $id = 45;
protected $rawName = '파초선';
protected $name = '파초선(반계)';
protected $info = '[전투] 상대의 계략 성공 확률 -10%p, 상대의 계략을 20% 확률로 되돌림';
@@ -0,0 +1,23 @@
<?php
namespace sammo\ActionItem;
use sammo\BaseWarUnitTrigger;
use sammo\WarUnit;
use sammo\WarUnitTrigger\che_저지발동;
use sammo\WarUnitTrigger\WarActivateSkills;
use sammo\WarUnitTriggerCaller;
class che_반계저지_박혁론 extends \sammo\BaseItem{
protected $rawName = '박혁론';
protected $name = '박혁론(반계저지)';
protected $info = '[전투] 상대의 계략 되돌림 불가';
protected $cost = 200;
protected $consumable = false;
public function getBattlePhaseSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller{
return new WarUnitTriggerCaller(
new WarActivateSkills($unit, BaseWarUnitTrigger::TYPE_NONE, false, '반계불가'),
);
}
}
@@ -0,0 +1,58 @@
<?php
namespace sammo\ActionItem;
use sammo\DB;
use \sammo\iAction;
use \sammo\General;
use sammo\KVStorage;
use sammo\Util;
class che_보물_도기 extends \sammo\BaseItem
{
protected $rawName = '도기';
protected $name = '도기(보물)';
protected $info = '[개인] 판매 시 국고에 금, 쌀 중 하나를 추가 (+10,000, 5년마다 +10,000)';
protected $cost = 200;
protected $consumable = false;
public function onArbitraryAction(General $general, string $actionType, ?string $phase = null, $aux = null): ?array
{
if ($aux === null){
return $aux;
}
if ($actionType !== '장비매매') {
return $aux;
}
if ($phase !== '판매') {
return $aux;
}
if (($aux['itemCode']??'') !== Util::getClassNameFromObj($this)){
return $aux;
}
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
[$year, $startYear] = $gameStor->getValuesAsArray(['year', 'startyear']);
$relYear = $year - $startYear;
$score = 10000 * (1 + Util::valueFit(intdiv($relYear, 5), 0));
[$resName, $resKey] = Util::choiceRandom([
['금', 'gold'],
['쌀', 'rice']
]);
$db->update('nation', [
$resKey => $db->sqleval('%b + %i', $resKey, $score)
]);
$score = Util::round($score);
$scoreText = number_format($score, 0);
$logger = $general->getLogger();
$logger->pushGeneralActionLog("국고에 {$resName} <C>{$scoreText}</>을 보충합니다.");
return $aux;
}
}
@@ -15,13 +15,20 @@ use sammo\WarUnitTrigger\WarActivateSkills;
class che_부적_태현청생부 extends \sammo\BaseItem
{
protected $id = 9;
protected $rawName = '태현청생부';
protected $name = '태현청생부(부적)';
protected $info = '[전투] 저격 불가, 부상 없음';
protected $cost = 200;
protected $consumable = false;
public function onCalcStat(General $general, string $statName, $value, $aux = null)
{
if($statName === 'injuryProb'){
return $value -= 1;
}
return $value;
}
public function getBattleInitSkillTriggerList(WarUnit $unit): ?WarUnitTriggerCaller
{
return new WarUnitTriggerCaller(
@@ -0,0 +1,31 @@
<?php
namespace sammo\ActionItem;
use \sammo\iAction;
use \sammo\General;
use sammo\Util;
use sammo\WarUnit;
use sammo\WarUnitTrigger\전투력보정;
use sammo\WarUnitTriggerCaller;
class che_불굴_상편 extends \sammo\BaseItem
{
protected $rawName = '상편';
protected $name = '상편(불굴)';
protected $info = '[전투] 남은 병력이 적을수록 공격력 증가. 최대 +50%';
protected $cost = 200;
protected $consumable = false;
public function getBattlePhaseSkillTriggerList(WarUnit $unit): ?WarUnitTriggerCaller
{
$leadership = $unit->getGeneral()->getLeadership();
$crew = $unit->getGeneral()->getVar('crew');
$crewRatio = Util::valueFit($crew / ($leadership * 100), 0, 1);
return new WarUnitTriggerCaller(
new 전투력보정($unit, 1 + 0.5 * (1 - $crewRatio))
);
}
}
@@ -5,7 +5,6 @@ use \sammo\General;
class che_사기_두강주 extends \sammo\BaseItem{
protected $id = 15;
protected $rawName = '두강주';
protected $name = '두강주(사기)';
protected $info = '[전투] 사기 보정 +10';
@@ -18,4 +17,6 @@ class che_사기_두강주 extends \sammo\BaseItem{
}
return $value;
}
}
}
//NOTE: 구버전
@@ -5,7 +5,6 @@ use \sammo\General;
class che_사기_보령압주 extends \sammo\BaseItem{
protected $id = 16;
protected $rawName = '보령압주';
protected $name = '보령압주(사기)';
protected $info = '[전투] 사기 보정 +10';
@@ -18,4 +17,6 @@ class che_사기_보령압주 extends \sammo\BaseItem{
}
return $value;
}
}
}
//NOTE: 구버전
@@ -5,7 +5,6 @@ use \sammo\General;
class che_사기_의적주 extends \sammo\BaseItem{
protected $id = 14;
protected $rawName = '의적주';
protected $name = '의적주(사기)';
protected $info = '[전투] 사기 보정 +10';
@@ -5,16 +5,15 @@ use \sammo\General;
class che_사기_초선화 extends \sammo\BaseItem{
protected $id = 20;
protected $rawName = '초선화';
protected $name = '초선화(사기)';
protected $info = '[전투] 사기 보정 +14';
protected $info = '[전투] 사기 보정 +15';
protected $cost = 200;
protected $consumable = false;
public function onCalcStat(General $general, string $statName, $value, $aux=null){
if($statName === 'bonusAtmos'){
return $value + 14;
return $value + 15;
}
return $value;
}
@@ -5,16 +5,15 @@ use \sammo\General;
class che_사기_춘화첩 extends \sammo\BaseItem{
protected $id = 19;
protected $rawName = '춘화첩';
protected $name = '춘화첩(사기)';
protected $info = '[전투] 사기 보정 +14';
protected $info = '[전투] 사기 보정 +15';
protected $cost = 200;
protected $consumable = false;
public function onCalcStat(General $general, string $statName, $value, $aux=null){
if($statName === 'bonusAtmos'){
return $value + 14;
return $value + 15;
}
return $value;
}
+3 -3
View File
@@ -3,16 +3,16 @@ namespace sammo\ActionItem;
use \sammo\iAction;
use \sammo\General;
use \sammo\BaseWarUnitTrigger;
use sammo\GameConst;
use \sammo\WarUnit;
use \sammo\WarUnitTriggerCaller;
use \sammo\WarUnitTrigger\능력치변경;
class che_사기_탁주 extends \sammo\BaseItem{
protected $id = 3;
protected $rawName = '탁주';
protected $name = '탁주(사기)';
protected $info = '[전투] 사기 +6. 1회용';
protected $info = '[전투] 사기 +30(한도 내). 1회용';
protected $cost = 1000;
protected $consumable = true;
protected $buyable = true;
@@ -20,7 +20,7 @@ class che_사기_탁주 extends \sammo\BaseItem{
public function getBattleInitSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller{
return new WarUnitTriggerCaller(
new 능력치변경($unit, BaseWarUnitTrigger::TYPE_CONSUMABLE_ITEM, 'atmos', '+', 6)
new 능력치변경($unit, BaseWarUnitTrigger::TYPE_CONSUMABLE_ITEM, 'atmos', '+', 30, null, GameConst::$maxAtmosByWar)
);
}
}
@@ -0,0 +1,28 @@
<?php
namespace sammo\ActionItem;
use \sammo\iAction;
use \sammo\General;
use sammo\WarUnit;
use sammo\WarUnitTrigger\전투력보정;
use sammo\WarUnitTriggerCaller;
class che_상성보정_과실주 extends \sammo\BaseItem{
protected $rawName = '과실주';
protected $name = '과실주(상성)';
protected $info = '[전투] 유리한 병종 전투시 공격력 +10%, 피해 -10%';
protected $cost = 200;
protected $consumable = false;
public function getBattlePhaseSkillTriggerList(WarUnit $unit): ?WarUnitTriggerCaller
{
$oppose = $unit->getOppose();
$attackCoef = $unit->getCrewType()->getAttackCoef($oppose->getCrewType());
if($attackCoef <= 1){
return null;
}
return new WarUnitTriggerCaller(
new 전투력보정($unit, 1.1, 0.9)
);
}
}
@@ -0,0 +1,20 @@
<?php
namespace sammo\ActionItem;
use \sammo\iAction;
use \sammo\General;
class che_숙련_동작 extends \sammo\BaseItem{
protected $rawName = '동작';
protected $name = '동작(숙련)';
protected $info = '숙련 +15%';
protected $cost = 200;
protected $consumable = false;
public function onCalcStat(General $general, string $statName, $value, $aux=null){
if($statName == 'addDex'){
return $value * 1.15;
}
return $value;
}
}
@@ -0,0 +1,24 @@
<?php
namespace sammo\ActionItem;
use \sammo\iAction;
use \sammo\General;
use sammo\WarUnit;
use sammo\WarUnitTrigger\che_약탈발동;
use sammo\WarUnitTrigger\che_약탈시도;
use sammo\WarUnitTriggerCaller;
class che_약탈_옥벽 extends \sammo\BaseItem{
protected $rawName = '옥벽';
protected $name = '옥벽(약탈)';
protected $info = '[전투] 새로운 상대와 전투 시 20% 확률로 상대 금, 쌀 10% 약탈';
protected $cost = 200;
protected $consumable = false;
public function getBattlePhaseSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller{
return new WarUnitTriggerCaller(
new che_약탈시도($unit, che_약탈시도::TYPE_ITEM, 0.2, 0.1),
new che_약탈발동($unit, che_약탈발동::TYPE_ITEM)
);
}
}
@@ -0,0 +1,25 @@
<?php
namespace sammo\ActionItem;
use \sammo\iAction;
use \sammo\General;
use \sammo\SpecialityHelper;
use \sammo\WarUnit;
use sammo\WarUnitTriggerCaller;
use \sammo\WarUnitTrigger\che_위압시도;
use \sammo\WarUnitTrigger\che_위압발동;
class che_위압_조목삭 extends \sammo\BaseItem{
protected $rawName = '조목삭';
protected $name = '조목삭(위압)';
protected $info = '[전투] 첫 페이즈 위압 발동(적 공격, 회피 불가, 사기 5 감소)';
protected $cost = 200;
protected $consumable = false;
public function getBattlePhaseSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller{
return new WarUnitTriggerCaller(
new che_위압시도($unit),
new che_위압발동($unit)
);
}
}
@@ -11,7 +11,6 @@ use sammo\WarUnitTrigger\che_전투치료시도;
class che_의술_상한잡병론 extends \sammo\BaseItem{
protected $id = 24;
protected $rawName = '상한잡병론';
protected $name = '상한잡병론(의술)';
protected $info = '[군사] 매 턴마다 자신(100%)과 소속 도시 장수(적 포함 50%) 부상 회복<br>[전투] 페이즈마다 40% 확률로 치료 발동(아군 피해 1/3 감소, 부상 회복)';
@@ -29,7 +28,7 @@ class che_의술_상한잡병론 extends \sammo\BaseItem{
return new WarUnitTriggerCaller(
new che_전투치료시도($unit, BaseWarUnitTrigger::TYPE_ITEM+BaseWarUnitTrigger::TYPE_DEDUP_TYPE_BASE*301),
new che_전투치료발동($unit, BaseWarUnitTrigger::TYPE_ITEM)
);
}
}
@@ -0,0 +1,34 @@
<?php
namespace sammo\ActionItem;
use \sammo\iAction;
use \sammo\General;
use \sammo\GeneralTrigger;
use \sammo\GeneralTriggerCaller;
use sammo\WarUnitTrigger\che_전투치료발동;
use sammo\WarUnitTrigger\che_전투치료시도;
use sammo\BaseWarUnitTrigger;
use sammo\WarUnitTriggerCaller;
class che_의술_정력견혈산 extends \sammo\BaseItem{
protected $rawName = '정력견혈산';
protected $name = '정력견혈산(의술)';
protected $info = '[군사] 매 턴마다 자신(100%)과 소속 도시 장수(적 포함 50%) 부상 회복<br>[전투] 페이즈마다 40% 확률로 치료 발동(아군 피해 1/3 감소, 부상 회복)';
protected $cost = 200;
protected $consumable = false;
public function getPreTurnExecuteTriggerList(General $general):?GeneralTriggerCaller{
return new GeneralTriggerCaller(
new GeneralTrigger\che_도시치료($general)
);
}
public function getBattlePhaseSkillTriggerList(\sammo\WarUnit $unit): ?WarUnitTriggerCaller
{
return new WarUnitTriggerCaller(
new che_전투치료시도($unit, BaseWarUnitTrigger::TYPE_ITEM+BaseWarUnitTrigger::TYPE_DEDUP_TYPE_BASE*302),
new che_전투치료발동($unit, BaseWarUnitTrigger::TYPE_ITEM)
);
}
}
@@ -11,7 +11,6 @@ use sammo\WarUnitTriggerCaller;
class che_의술_청낭서 extends \sammo\BaseItem{
protected $id = 23;
protected $rawName = '청낭서';
protected $name = '청낭서(의술)';
protected $info = '[군사] 매 턴마다 자신(100%)과 소속 도시 장수(적 포함 50%) 부상 회복<br>[전투] 페이즈마다 40% 확률로 치료 발동(아군 피해 1/3 감소, 부상 회복)';
@@ -29,7 +28,7 @@ class che_의술_청낭서 extends \sammo\BaseItem{
return new WarUnitTriggerCaller(
new che_전투치료시도($unit, BaseWarUnitTrigger::TYPE_ITEM+BaseWarUnitTrigger::TYPE_DEDUP_TYPE_BASE*302),
new che_전투치료발동($unit, BaseWarUnitTrigger::TYPE_ITEM)
);
}
}
@@ -11,7 +11,6 @@ use sammo\WarUnitTrigger\che_전투치료시도;
class che_의술_태평청령 extends \sammo\BaseItem{
protected $id = 24;
protected $rawName = '태평청령';
protected $name = '태평청령(의술)';
protected $info = '[군사] 매 턴마다 자신(100%)과 소속 도시 장수(적 포함 50%) 부상 회복<br>[전투] 페이즈마다 40% 확률로 치료 발동(아군 피해 1/3 감소, 부상 회복)';
@@ -29,7 +28,7 @@ class che_의술_태평청령 extends \sammo\BaseItem{
return new WarUnitTriggerCaller(
new che_전투치료시도($unit, BaseWarUnitTrigger::TYPE_ITEM+BaseWarUnitTrigger::TYPE_DEDUP_TYPE_BASE*303),
new che_전투치료발동($unit, BaseWarUnitTrigger::TYPE_ITEM)
);
}
}
@@ -12,7 +12,6 @@ use \sammo\WarUnitTrigger\che_저격발동;
class che_저격_매화수전 extends \sammo\BaseItem{
protected $id = 70;
protected $rawName = '매화수전';
protected $name = '매화수전(저격)';
protected $info = '[전투] 새로운 상대와 전투 시 50% 확률로 저격 발동, 성공 시 사기+20';
@@ -12,7 +12,6 @@ use \sammo\WarUnitTrigger\che_저격발동;
class che_저격_비도 extends \sammo\BaseItem{
protected $id = 70;
protected $rawName = '비도';
protected $name = '비도(저격)';
protected $info = '[전투] 새로운 상대와 전투 시 50% 확률로 저격 발동, 성공 시 사기+20';
+3 -4
View File
@@ -10,10 +10,9 @@ use \sammo\BaseWarUnitTrigger;
class che_저격_수극 extends \sammo\BaseItem{
protected $id = 2;
protected $rawName = '수극';
protected $name = '수극(저격)';
protected $info = '[전투] 전투 개시 전 50% 확률로 저격 시도. 1회용';
protected $info = '[전투] 전투 개시 시 저격. 1회용';
protected $cost = 1000;
protected $consumable = true;
protected $buyable = true;
@@ -21,12 +20,12 @@ class che_저격_수극 extends \sammo\BaseItem{
public function getBattleInitSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller{
return new WarUnitTriggerCaller(
new che_저격시도($unit, BaseWarUnitTrigger::TYPE_CONSUMABLE_ITEM, 0.5, 20, 40),
new che_저격시도($unit, BaseWarUnitTrigger::TYPE_CONSUMABLE_ITEM, 1, 20, 40),
new che_저격발동($unit, BaseWarUnitTrigger::TYPE_CONSUMABLE_ITEM)
);
}
function isConsumableNow(string $actionType, string $command):bool{
function tryConsumeNow(General $general, string $actionType, string $command):bool{
if($actionType == 'GeneralTrigger' && $command == 'che_아이템치료'){
return true;
}
@@ -0,0 +1,34 @@
<?php
namespace sammo\ActionItem;
use sammo\BaseWarUnitTrigger;
use sammo\Util;
use sammo\WarUnit;
use sammo\WarUnitTrigger\che_저지발동;
use sammo\WarUnitTrigger\WarActivateSkills;
use sammo\WarUnitTriggerCaller;
class che_저지_삼황내문 extends \sammo\BaseItem{
protected $rawName = '삼황내문';
protected $name = '삼황내문(저지)';
protected $info = '[전투] 수비 시 첫 페이즈 저지, 50% 확률로 2 페이즈 저지';
protected $cost = 200;
protected $consumable = false;
public function getBattlePhaseSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller{
if($unit->isAttacker()){
return null;
}
if($unit->getPhase() >= 2){
return null;
}
if($unit->getPhase() == 1 && Util::randBool(0.5)){
return null;
}
return new WarUnitTriggerCaller(
new WarActivateSkills($unit, BaseWarUnitTrigger::TYPE_NONE, true, '특수', '저지'),
new che_저지발동($unit)
);
}
}
@@ -0,0 +1,21 @@
<?php
namespace sammo\ActionItem;
use \sammo\iAction;
use \sammo\General;
use sammo\Util;
class che_전략_평만지장도 extends \sammo\BaseItem{
protected $rawName = '평만지장도';
protected $name = '평만지장도(전략)';
protected $info = '[전략] 국가전략 사용시 재사용 대기 기간 -15%';
protected $cost = 200;
protected $consumable = false;
public function onCalcStrategic(string $turnType, string $varType, $value){
if($varType == 'delay'){
return Util::round($value * 0.85);
}
return $value;
}
}
@@ -0,0 +1,22 @@
<?php
namespace sammo\ActionItem;
use \sammo\iAction;
use \sammo\General;
use sammo\Util;
class che_조달_주판 extends \sammo\BaseItem{
protected $rawName = '주판';
protected $name = '주판(조달)';
protected $info = '[내정] 물자조달 성공 확률 +20%p, 물자조달 획득량 +100%p';
protected $cost = 200;
protected $consumable = false;
public function onCalcStrategic(string $turnType, string $varType, $value){
if($turnType === '조달'){
if($varType == 'success') return $value + 0.2;
if($varType == 'score') return $value * 2;
}
return $value;
}
}
@@ -0,0 +1,22 @@
<?php
namespace sammo\ActionItem;
use \sammo\General;
class che_집중_전국책 extends \sammo\BaseItem
{
protected $rawName = '전국책';
protected $name = '전국책(집중)';
protected $info = '[전투] 계략 성공 시 대미지 +30%';
protected $cost = 200;
protected $consumable = false;
public function onCalcStat(General $general, string $statName, $value, $aux = null)
{
if ($statName === 'warMagicSuccessDamage') {
return $value * 1.3;
}
return $value;
}
}
@@ -0,0 +1,30 @@
<?php
namespace sammo\ActionItem;
use \sammo\iAction;
use \sammo\General;
use \sammo\SpecialityHelper;
use \sammo\WarUnit;
class che_징병_낙주 extends \sammo\BaseItem{
protected $rawName = '낙주';
protected $name = '낙주(징병)';
protected $info = '[군사] 징·모병비 -50%, 통솔 순수 능력치 보정 +15%';
protected $cost = 200;
protected $consumable = false;
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float{
if(in_array($turnType, ['징병', '모병'])){
if($varType == 'cost') return $value * 0.5;
}
return $value;
}
public function onCalcStat(General $general, string $statName, $value, $aux=null){
if($statName === 'leadership'){
return $value + $general->getVar('leadership') * 0.15;
}
return $value;
}
}
@@ -0,0 +1,23 @@
<?php
namespace sammo\ActionItem;
use \sammo\iAction;
use \sammo\General;
use \sammo\SpecialityHelper;
use \sammo\WarUnit;
class che_척사_오악진형도 extends \sammo\BaseItem{
protected $rawName = '오악진형도';
protected $name = '오악진형도(척사)';
protected $info = '[전투] 지역·도시 병종 상대로 대미지 +15%, 아군 피해 -15%';
protected $cost = 200;
protected $consumable = false;
public function getWarPowerMultiplier(WarUnit $unit):array{
$opposeCrewType = $unit->getOppose()->getCrewType();
if($opposeCrewType->reqCities || $opposeCrewType->reqRegions){
return [1.15, 0.85];
}
return [1, 1];
}
}
@@ -7,7 +7,6 @@ use \sammo\GeneralTriggerCaller;
class che_치료_도소연명 extends \sammo\BaseItem{
protected $id = 9;
protected $rawName = '도소연명';
protected $name = '도소연명(치료)';
protected $info = '[군사] 턴 실행 전 부상 회복.';
@@ -7,7 +7,6 @@ use \sammo\GeneralTriggerCaller;
class che_치료_무후행군 extends \sammo\BaseItem{
protected $id = 8;
protected $rawName = '무후행군';
protected $name = '무후행군(치료)';
protected $info = '[군사] 턴 실행 전 부상 회복.';
@@ -7,7 +7,6 @@ use \sammo\GeneralTriggerCaller;
class che_치료_오석산 extends \sammo\BaseItem{
protected $id = 7;
protected $rawName = '오석산';
protected $name = '오석산(치료)';
protected $info = '[군사] 턴 실행 전 부상 회복.';
@@ -7,7 +7,6 @@ use \sammo\GeneralTriggerCaller;
class che_치료_정력견혈 extends \sammo\BaseItem{
protected $id = 11;
protected $rawName = '정력견혈';
protected $name = '정력견혈(치료)';
protected $info = '[군사] 턴 실행 전 부상 회복.';
@@ -7,7 +7,6 @@ use \sammo\GeneralTriggerCaller;
class che_치료_칠엽청점 extends \sammo\BaseItem{
protected $id = 10;
protected $rawName = '칠엽청점';
protected $name = '칠엽청점(치료)';
protected $info = '[군사] 턴 실행 전 부상 회복.';
+31 -7
View File
@@ -7,25 +7,49 @@ use \sammo\GeneralTriggerCaller;
class che_치료_환약 extends \sammo\BaseItem{
protected $id = 1;
protected $rawName = '환약';
protected $name = '환약(치료)';
protected $info = '[군사] 턴 실행 전 부상 회복. 1회용';
protected $cost = 100;
protected $info = '[군사] 턴 실행 전 부상 회복. 3회용';
protected $cost = 200;
protected $consumable = true;
protected $buyable = true;
protected $reqSecu = 0;
const REMAIN_KEY = 'remain환약';
public function getPreTurnExecuteTriggerList(General $general):?GeneralTriggerCaller{
return new GeneralTriggerCaller(
new GeneralTrigger\che_아이템치료($general, $general->getAuxVar('use_treatment')??10)
);
}
function isConsumableNow(string $actionType, string $command):bool{
if($actionType == 'GeneralTrigger' && $command == 'che_아이템치료'){
return true;
function onArbitraryAction(General $general, string $actionType, ?string $phase = null, $aux = null): ?array
{
if($actionType != '장비매매'){
return $aux;
}
return false;
if($phase != '구매'){
return $aux;
}
$general->setAuxVar(static::REMAIN_KEY, 3);
return $aux;
}
function tryConsumeNow(General $general, string $actionType, string $command):bool{
if($actionType != 'GeneralTrigger'){
return false;
}
if($command != 'che_아이템치료'){
return false;
}
$remainCnt = $general->getAuxVar(static::REMAIN_KEY)??1;
if($remainCnt > 1){
$general->setAuxVar(static::REMAIN_KEY, $remainCnt - 1);
return false;
}
$general->setAuxVar(static::REMAIN_KEY, null);
return true;
}
}

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