博丽帝国开发2

This commit is contained in:
daixiawu 2026-06-20 16:53:20 +08:00
parent b6d21053bc
commit 40b5d0d170
88 changed files with 17820 additions and 8514 deletions

View File

@ -0,0 +1,77 @@
---
name: th1-character-dialogue-design
description: TH1 project workflow for designing Touhou character profiles and humorous in-game dialogue, including library hero lines, leader start/meet/win/lose chat bubbles, diplomacy lines, MBTI/core-motivation voice sheets, TH1 extra setting summaries, canon-source coverage checks, and Hakurei/Reimu faction dialogue drafts. Use when Codex is asked for 角色台词设计, 人设台词, 图鉴台词, 领袖台词, 外交台词, 博丽帝国台词, 东方角色口吻, or to create/update TH1 dialogue copy.
---
# TH1 Character Dialogue Design
Use this skill to design TH1 character persona notes and in-game lines without losing the project's existing absurd comedy tone or Touhou character grounding.
## Hard Gate
Before writing final character lines, verify canon-source coverage for every target character:
1. Confirm the skill has stored source material covering that character's original setting, personality, and original/canon line examples.
2. If any required canon source is missing, leave canon-dependent persona fields and final line fields blank.
3. Continue non-blocking work that does not require canon certainty: extract current game lines, summarize local TH1 setting, list missing source files, and prepare blank templates.
4. Ask the user for the missing resources by character name and source category.
Do not treat model memory or general Touhou familiarity as a substitute for stored source documents.
## Core Workflow
1. Run or read `scripts/extract_dialogue_corpus.py` when current game text may have changed. It extracts:
- `LibraryDataAssets.asset`: hero library `Desc` and `Diag`.
- `PlayerDataAssets.asset`: leader `LeaderDesc`, `StartChatBubble`, `MeetChatBubble`, `LoseChatBubble`, `WinChatBubble`.
- `DiplomacyDataAssets.asset`: alliance and relation-state dialogue.
2. Read `references/current-dialogue-corpus.md` for existing text and speaker coverage.
3. Read `references/dialogue-style-guide.md` for tone, structure, and quality rules.
4. Read `references/source-coverage.md` for canon-source status. If the target has `missing` canon coverage, do not produce final lines.
5. For Hakurei/Reimu faction work, read `references/hakurei-dialogue-workbench.md`.
6. Produce output as either:
- source checklist and blank design template when canon is missing;
- reviewed design brief and final line set when canon is complete.
## Required Character Sheet
For each character, maintain these fields:
- `Canon source status`: complete / partial / missing.
- `Canon anchors`: original role, personality, speech habits, relationship hooks, original line examples.
- `TH1 extra setting`: 2-4 sentences explaining why this character is in TH1 and what she wants here.
- `MBTI reference`: type or hypothesis, with source notes when available.
- `Core motivation`: one clear sentence.
- `Preference and quirks`: concrete habits, likes, pet peeves, recurring jokes.
- `Comedy engine`: the repeated absurd mismatch that makes the character funny in TH1.
- `Line constraints`: vocabulary to use, vocabulary to avoid, punctuation rhythm, max line length.
If canon is missing, only fill `TH1 extra setting` and source checklist; leave canon anchors, MBTI, core motivation, quirks, comedy engine, and final lines blank.
## TH1 Dialogue Surfaces
Use the existing data surfaces and categories:
- Hero library: `LibraryGiantData.Desc`, `LibraryGiantData.Diag`.
- Leader selection: `PlayerInfo.LeaderDesc`.
- Leader chat bubbles: `StartChatBubble`, `MeetChatBubble`, `LoseChatBubble`, `WinChatBubble`.
- Diplomacy action lines: `AllyOfferText`, `AllyAcceptText`, `AllyRefuseText`, `AllyBreakText`.
- Relation-state lines: `RelationTrustText`, `RelationAppreciateText`, `RelationIndifferentText`, `RelationSuspicionText`, `RelationTerribleText`.
Keep dialogue concise enough for UI bubbles. Prefer one joke or one character beat per line.
## Editing Rules
- Do not edit `Unity/Assets/BundleResources/Export/*`, `Tools/Multilingual.xlsx`, or `Tools/MultilingualTxt.txt` unless the user explicitly asks for export/import workflow work.
- Do not hardcode game-facing text in code.
- Treat DataAssets as source text only when the user explicitly asks to apply lines; otherwise produce Markdown drafts.
- Preserve existing Unity `.meta` files and unrelated user changes.
- Before applying DataAsset text, verify localization/export expectations with `th1-multilingual`.
## Resources
- `scripts/extract_dialogue_corpus.py`: regenerate extracted current dialogue references.
- `references/current-dialogue-corpus.md`: current extracted text corpus.
- `references/current-dialogue-corpus.json`: machine-readable extracted corpus.
- `references/dialogue-style-guide.md`: style summary and design method.
- `references/source-coverage.md`: canon-source checklist and missing resource list.
- `references/hakurei-dialogue-workbench.md`: current Hakurei/Reimu faction workbench and blocked final-line template.

View File

@ -0,0 +1,4 @@
interface:
display_name: "TH1 Character Dialogue Design"
short_description: "TH1角色人设与台词设计流程和资料校验"
default_prompt: "Use $th1-character-dialogue-design to design TH1 character profiles and dialogue after checking canon source coverage."

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,104 @@
# TH1 Dialogue Style Guide
## Project Tone
TH1 dialogue is absurd comedy built from three ingredients:
- Touhou character identity.
- A historical-civilization role or ruler archetype.
- A tournament/game-show premise where everyone treats world conquest like an overcomplicated event.
The best lines are short, confident, and specific. They usually make one joke at a time: a role mismatch, a petty motive, an over-serious strategic phrase applied to a silly goal, or a character calmly accepting an obviously ridiculous situation.
## Existing Style Summary
Library hero text usually follows:
- "This character is playing / mapped to historical figure X."
- "Her TH1 reason for participating is practical, selfish, accidental, contractual, or absurd."
- One punchline line that reveals the real motive or misunderstanding.
Leader and diplomacy lines usually follow:
- 1-2 sentence bubbles.
- Strong speaker identity through recurring nouns.
- Few exposition words; the situation is implied by the line category.
- Tone shifts by relation state rather than restating mechanics.
## Existing Speaker Patterns
- Remilia: aristocratic command, fate, banquet, Sakuya orders, theatrical arrogance, "I was not tricked" jokes.
- Kaguya: bored eternal princess, gamer/testing attitude, superiority, "this script is boring" energy.
- Kanako: corporate sponsor, faith as traffic/user growth, market and industry metaphors, confident acquisition mindset.
- Satori: calm mind reader, motive exposure, dry suspicion, "I already read your ending."
- Reimu: lazy, direct, money-sensitive, trouble-avoidant, intuitive, balances/退治 when annoyed.
- Byakuren: Buddhist diction, 善缘/因果/法/普度, formal compassion that can become wrath.
- Miko: courtly rationality, desire-listening, "和", law/order, measured confidence.
- Zanmu: old-stage/chess/script diction, detached manipulation, void/curtain-call imagery.
## Design Method
For each character:
1. Lock canon coverage first. If canon docs are missing, stop final-line writing.
2. Write the TH1 extra setting in 2-4 sentences: why she is here, what faction/history role she got, and what practical nuisance or desire drives her.
3. Assign MBTI only after source review, then use it as a pressure pattern:
- decision style;
- what she notices first;
- what annoys her;
- how she justifies selfish or absurd behavior.
4. Define one core motivation. Keep it simple enough to drive every line.
5. Define 2-3 recurring quirks or preferences.
6. Write lines by surface, not as generic quotes.
## Line Shape
Hero library `Diag`:
- One sentence or two short clauses.
- Show the mismatch between Touhou identity and historical role.
- End on a twist, complaint, demand, or deadpan reveal.
Leader `StartChatBubble`:
- "I am here for X" or "let's get this over with."
- Establish motive quickly.
Leader `MeetChatBubble`:
- First-impression line toward another empire.
- Can be transactional, suspicious, welcoming, or dismissive.
Leader `LoseChatBubble`:
- Do not make every loss dignified.
- Existing TH1 style often uses denial, refund jokes, blame-shifting, or comic outrage.
Leader `WinChatBubble`:
- Reward the core motivation.
- Add one implication about future trouble.
Diplomacy action lines:
- Offer: why cooperation benefits the speaker.
- Accept: conditional approval or self-serving consent.
- Refuse: compact rejection with character reason.
- Break: "the old reason no longer matters."
Relation-state lines:
- Trust: rare praise in the speaker's vocabulary.
- Appreciate: guarded approval.
- Indifferent: bored dismissal.
- Suspicion: identifies potential trouble.
- Terrible: threat in the character's own idiom.
## Quality Checks
- Could a player identify the speaker without the name label?
- Does the line contain one clear joke or character beat?
- Is the historical/civilization reference useful rather than decorative?
- Is the line concise enough for a UI bubble?
- Does it avoid generic "I will conquer the world" phrasing?
- If a line depends on canon personality, has the stored canon-source gate been satisfied?

View File

@ -0,0 +1,150 @@
# Hakurei Empire Dialogue Workbench
Status: blocked for final canon-dependent line writing. Current TH1/project setting can be organized, but final persona sheets, MBTI, and final dialogue must wait for missing canon-source documents listed in `source-coverage.md`.
## Current TH1 Sources
From `PlayerDataAssets.asset`:
- Civ: 维京
- Force: 博丽帝国
- Leader: 博丽灵梦
- LeaderDesc: 懒散的博丽巫女抽到了<color=blue>维京</color>帝国卡,原本她只是在神社里无精打采的喝茶,结果听到奖金金额后当场坐直了。她加入比赛的理由很纯粹:奖金,顺带退治可疑的对手。
From current library entries:
- 博丽灵梦: 御札巫女博丽加护、退治、御札收益current line: "赛事的委托吗?只要酬劳到位,退治工作就交给我吧。"
- 宇佐见堇子: 灵异使者不同地形灵异珠current line: "平原、森林、海面,这些地方都很适合收集灵异现象呢。"
- 茨木华扇: 兽引仙人兽引支点、召回、减伤、回复、传送current line: "兽引一旦放置,就要想好这条路要把我们带到哪里。"
- 高丽野阿吽: 狛犬守卫逃脱、石化、双身、共享生命、防守承伤current line: "阿与吽同在的地方,就是需要守护的门口。"
- 伊吹萃香: 鬼族怪力,小萃香/大萃香/巨大萃香投掷与从天而降current line: "哎呀,人多一点才热闹嘛。如果我一个不够,那就多来几个我好了。"
From local project song notes:
- Reimu/Hakurei Viking motifs: North Sea, longships, dragon prows, shrine box, Danegeld, Canute, shield wall, ofuda, gohei, runes, sea law, ghost ships, pay Hakurei.
## TH1 Extra Setting Draft
These setting notes are TH1-local and can be used as scaffolding before canon sources arrive.
### 博丽灵梦 / NorwayReimu
灵梦抽到维京帝国卡后,本来觉得比赛很麻烦,但听到奖金和额外贡金机制后立刻进入工作状态。她把维京远征理解成一种大型外勤退治委托:长船负责到处收账,御札负责把不交钱的异常现象镇压,赛钱箱负责证明一切行动的合理性。
### 宇佐见堇子 / NorwaySumireko
堇子把北海远征当成大型灵异田野调查。她对平原、森林、海面、符文石、幽灵船和海雾都很感兴趣,并试图把维京航线整理成一份可发表的超自然地图。
### 茨木华扇 / NorwayKasen
华扇在博丽帝国里承担监督和收束混乱的角色。她负责把灵梦的金钱动机、萃香的热闹动机、堇子的调查动机和阿吽的守门职责暂时拧成一条能走到胜利的路线。
### 高丽野阿吽 / NorwayAunn
阿吽被安排守护神社、船坞、赛钱箱和长船龙首。她的喜剧点是无论地图扩张到哪里,都会认真判断"这里是不是也算门口",然后以守门犬的逻辑保护整个帝国。
### 伊吹萃香 / NorwaySuika
萃香把远征、战斗和庆功都理解成同一场越来越热闹的宴会。她的分身和巨大化让"人多才热闹"变成实际战术,也让博丽帝国的维京航线像一场一路打到北海尽头的酒宴。
## Canon-Dependent Persona Fields
Leave blank until source coverage is complete.
| Character | Canon anchors | MBTI reference | Core motivation | Preference / quirks | Comedy engine |
| --- | --- | --- | --- | --- | --- |
| 博丽灵梦 | | | | | |
| 宇佐见堇子 | | | | | |
| 茨木华扇 | | | | | |
| 高丽野阿吽 | | | | | |
| 伊吹萃香 | | | | | |
## Final Dialogue Template
Leave blank until source coverage is complete. Keep current lines nearby for comparison, but do not treat this section as approved copy.
### PlayerInfo.LeaderDesc
```text
```
### StartChatBubble
```text
```
### MeetChatBubble
```text
```
### LoseChatBubble
```text
```
### WinChatBubble
```text
```
### Diplomacy Lines
#### AllyOfferText
```text
```
#### AllyAcceptText
```text
```
#### AllyRefuseText
```text
```
#### AllyBreakText
```text
```
#### RelationTrustText
```text
```
#### RelationAppreciateText
```text
```
#### RelationIndifferentText
```text
```
#### RelationSuspicionText
```text
```
#### RelationTerribleText
```text
```

View File

@ -0,0 +1,90 @@
# Canon Source Coverage
This file records whether this skill has stored Touhou original-setting material for dialogue design.
## Rule
Do not write final canon-dependent persona sheets or final lines for a character whose canon coverage is `missing`.
Required source categories:
- Official profile / setting text.
- Original game or print-work dialogue examples.
- Personality and relationship notes grounded in source.
- Existing TH1 project extra setting and gameplay role.
- Existing TH1 lines, if any.
## Current Stored Sources
Available in this skill:
- Current TH1 extracted corpus: `current-dialogue-corpus.md` and `current-dialogue-corpus.json`.
- Current TH1 DataAsset source paths listed in `current-dialogue-corpus.md`.
- Hakurei/Reimu-related local project notes under `MD/`, including Viking/Reimu song and meter drafts. These are TH1/project derivatives, not canon-source substitutes.
Not currently stored in this skill:
- Complete Touhou original profiles.
- Complete original/canon line collections.
- Official source excerpts per character.
## Missing Canon Documents By Current Library Character
All characters below currently lack complete stored canon-source coverage in this skill:
- 蕾米莉亚 · 斯卡雷特 / `EgyptianRemilia`
- 帕秋莉 · 诺蕾姬 / `EgyptianPatchouli`
- 十六夜咲夜 / `EgyptianSakuya`
- 芙兰朵露 · 斯卡雷特 / `EgyptianFlandre`
- 红美铃 / `EgyptianMeiling`
- 蓬莱山辉夜 / `FrenchKaguya`
- 八意永琳 / `FrenchEirin`
- 因幡帝 / `FrenchTewi`
- 铃仙·优昙华院·因幡 / `FrenchReisen`
- 藤原妹红 / `FrenchMokou`
- 八坂神奈子 / `GermanyKanako`
- 洩矢诹访子 / `GermanySuwako`
- 东风谷早苗 / `GermanySanae`
- 射命丸文 / `GermanyAya`
- 犬走椛 / `GermanyMomiji`
- 古明地觉 / `IndianSatori`
- 古明地恋 / `IndianKoishi`
- 火焰猫燐 / `IndianRin`
- 灵乌路空 / `IndianUtsuho`
- 星熊勇仪 / `IndianYuugi`
- 博丽灵梦 / `NorwayReimu`
- 宇佐见堇子 / `NorwaySumireko`
- 茨木华扇 / `NorwayKasen`
- 高丽野阿吽 / `NorwayAunn`
- 伊吹萃香 / `NorwaySuika`
- 圣白莲 / `BritishByakuren`
- 丰聪耳神子 / `PersianMiko`
- 日白残无 / `ByzantineZanmu`
## Missing Canon Documents For Hakurei Work
Request these before finalizing Hakurei Empire persona and dialogue:
- 博丽灵梦: official profiles, original/canon dialogue examples, personality notes, relationship notes.
- 宇佐见堇子: official profiles, original/canon dialogue examples, personality notes, relationship notes.
- 茨木华扇: official profiles, original/canon dialogue examples, personality notes, relationship notes.
- 高丽野阿吽: official profiles, original/canon dialogue examples, personality notes, relationship notes.
- 伊吹萃香: official profiles, original/canon dialogue examples, personality notes, relationship notes.
## Template To Fill After User Provides Sources
```markdown
### <Character>
- Canon source status: complete
- Source files stored:
- `<path>`
- Canon anchors:
- Original line examples:
- TH1 extra setting:
- MBTI reference:
- Core motivation:
- Preference and quirks:
- Comedy engine:
- Final-line status:
```

View File

@ -0,0 +1,322 @@
#!/usr/bin/env python3
"""Extract TH1 character and leader dialogue from Unity YAML DataAssets."""
from __future__ import annotations
import json
import re
from collections import OrderedDict
from pathlib import Path
from typing import Any
import yaml
ROOT = Path(__file__).resolve().parents[4]
DATA = ROOT / "Unity" / "Assets" / "BundleResources" / "DataAssets"
SCRIPT_DIR = ROOT / "Unity" / "Assets" / "Scripts" / "TH1_DataAssetsScript"
OUT_DIR = Path(__file__).resolve().parents[1] / "references"
FORCE_NAMES = {
0: "Remilia",
1: "Kaguya",
2: "Kanako",
3: "Satori",
4: "Reimu",
5: "Byakuren",
6: "Miko",
7: "Zanmu",
8: "Yuyuko",
9: "Hecatia",
10: "Megumu",
11: "Cirno",
12: "Yorihime",
13: "Tenshi",
14: "Ubame",
15: "Seija",
16: "Marisa",
}
DIPLOMACY_FIELDS = [
"AllyBreakText",
"AllyOfferText",
"AllyAcceptText",
"AllyRefuseText",
"RelationTrustText",
"RelationAppreciateText",
"RelationIndifferentText",
"RelationSuspicionText",
"RelationTerribleText",
]
PLAYER_DIALOGUE_FIELDS = [
"StartChatBubble",
"MeetChatBubble",
"LoseChatBubble",
"WinChatBubble",
]
def clean_unity_yaml(text: str) -> str:
lines: list[str] = []
for line in text.splitlines():
if line.startswith("%YAML") or line.startswith("%TAG"):
continue
if line.startswith("--- !u!"):
lines.append("---")
else:
lines.append(line)
return "\n".join(lines)
def load_unity_asset(path: Path) -> dict[str, Any]:
text = path.read_text(encoding="utf-8")
docs = list(yaml.safe_load_all(clean_unity_yaml(text)))
if not docs or not isinstance(docs[0], dict) or "MonoBehaviour" not in docs[0]:
raise ValueError(f"Unsupported Unity asset format: {path}")
return docs[0]["MonoBehaviour"]
def parse_giant_enum() -> dict[int, str]:
path = SCRIPT_DIR / "UnitTypeDataAssets.cs"
text = path.read_text(encoding="utf-8")
match = re.search(r"public\s+enum\s+GiantType\s*\{(?P<body>.*?)\}", text, re.S)
if not match:
return {}
result: dict[int, str] = {}
current = -1
for raw in match.group("body").split(","):
item = raw.strip()
if not item:
continue
item = re.sub(r"//.*", "", item).strip()
if not item:
continue
if "=" in item:
name, value = [part.strip() for part in item.split("=", 1)]
current = int(value)
else:
name = item.strip()
current += 1
result[current] = name
return result
def compact_lines(lines: Any) -> list[str]:
if not lines:
return []
return [str(x) for x in lines if str(x).strip()]
def emit_json(data: dict[str, Any]) -> None:
OUT_DIR.mkdir(parents=True, exist_ok=True)
path = OUT_DIR / "current-dialogue-corpus.json"
path.write_text(json.dumps(data, ensure_ascii=False, indent=2), encoding="utf-8-sig")
def emit_markdown(data: dict[str, Any]) -> None:
OUT_DIR.mkdir(parents=True, exist_ok=True)
path = OUT_DIR / "current-dialogue-corpus.md"
lines: list[str] = [
"# Current TH1 Dialogue Corpus",
"",
"Generated from current `Unity/Assets/BundleResources/DataAssets` files.",
"Do not edit this file by hand; rerun `scripts/extract_dialogue_corpus.py` after DataAssets changes.",
"",
"## Sources",
"",
]
for source in data["sources"]:
lines.append(f"- `{source}`")
lines.extend(["", "## Library Giant Lines", ""])
for item in data["library_giants"]:
lines.extend(
[
f"### {item['name']} ({item['giant_enum']})",
"",
f"- GiantType: `{item['giant_type']}`",
f"- Subtitle: {item['subtitle'] or '(empty)'}",
f"- TH1 setting: {item['desc'] or '(empty)'}",
f"- Dialogue: {item['diag'] or '(empty)'}",
"",
]
)
lines.extend(["## Wonder Library Dialogue", ""])
for wonder in data["wonder_dialogues"]:
lines.extend(
[
f"### {wonder['name']} ({wonder['wonder_id']})",
"",
]
)
for idx, diag in enumerate(wonder["diags"], start=1):
lines.append(f"- Dialogue group {idx}:")
for text in diag["lines"]:
lines.append(f" - {text}")
if not wonder["diags"]:
lines.append("- (empty)")
lines.append("")
lines.extend(["## Leader Chat Bubbles", ""])
for leader in data["leader_chat_bubbles"]:
lines.extend(
[
f"### {leader['leader_name']} - {leader['force_name']} / {leader['civ_name']}",
"",
f"- ForceId/CivId: `{leader['force_id']}` / `{leader['civ_id']}`",
f"- LeaderDesc: {leader['leader_desc'] or '(empty)'}",
"",
]
)
for field in PLAYER_DIALOGUE_FIELDS:
values = leader["lines"].get(field, [])
lines.append(f"#### {field}")
if values:
for text in values:
lines.append(f"- {text}")
else:
lines.append("- (empty)")
lines.append("")
lines.extend(["## Diplomacy Leader Lines", ""])
for force in data["diplomacy_lines"]:
lines.extend(
[
f"### {force['force_name']} (force {force['force_id']})",
"",
f"- Speaker: `{force['speaker']}`",
"",
]
)
for field in DIPLOMACY_FIELDS:
values = force["lines"].get(field, [])
lines.append(f"#### {field}")
if values:
for text in values:
lines.append(f"- {text}")
else:
lines.append("- (empty)")
lines.append("")
path.write_text("\n".join(lines).rstrip() + "\n", encoding="utf-8-sig")
def build_corpus() -> dict[str, Any]:
giant_enum = parse_giant_enum()
library = load_unity_asset(DATA / "LibraryDataAssets.asset")
player = load_unity_asset(DATA / "PlayerDataAssets.asset")
diplomacy = load_unity_asset(DATA / "DiplomacyDataAssets.asset")
library_giants = []
for item in library.get("LibraryGiantList", []) or []:
gid = int(item.get("GiantType", 0))
library_giants.append(
OrderedDict(
giant_type=gid,
giant_enum=giant_enum.get(gid, f"GiantType_{gid}"),
name=item.get("Name") or "",
subtitle=item.get("SubTitle") or "",
desc=item.get("Desc") or "",
diag=item.get("Diag") or "",
english_name=item.get("EnglishName") or "",
achieve_pre_id=item.get("AchivePreId", 0),
)
)
wonder_dialogues = []
for item in library.get("LibraryWonderList", []) or []:
diags = []
for diag in item.get("Diags", []) or []:
diags.append(
OrderedDict(
lines=compact_lines(diag.get("Diag")),
giant=diag.get("Giant", []),
)
)
wonder_dialogues.append(
OrderedDict(
wonder_id=item.get("WonderLibraryID"),
name=item.get("Name") or "",
desc=item.get("Desc") or "",
diags=diags,
)
)
leader_chat_bubbles = []
for item in player.get("PlayerDataList", []) or []:
force_id = int(item.get("ForceId", -1))
leader_chat_bubbles.append(
OrderedDict(
force_id=force_id,
civ_id=int(item.get("CivId", -1)),
force_key=FORCE_NAMES.get(force_id, f"Force_{force_id}"),
civ_name=item.get("CivName") or "",
force_name=item.get("ForceName") or "",
leader_name=item.get("LeaderName") or "",
empire_desc=item.get("EmpireDesc") or "",
leader_desc=item.get("LeaderDesc") or "",
lines=OrderedDict(
(field, compact_lines(item.get(field))) for field in PLAYER_DIALOGUE_FIELDS
),
)
)
diplomacy_lines = []
for item in diplomacy.get("DiplomacyChatInfoList", []) or []:
force_id = int(item.get("force", -1))
force_name = FORCE_NAMES.get(force_id, f"Force_{force_id}")
diplomacy_lines.append(
OrderedDict(
force_id=force_id,
force_name=force_name,
speaker=speaker_for_force(force_id),
lines=OrderedDict((field, compact_lines(item.get(field))) for field in DIPLOMACY_FIELDS),
)
)
return OrderedDict(
sources=[
"Unity/Assets/BundleResources/DataAssets/LibraryDataAssets.asset",
"Unity/Assets/BundleResources/DataAssets/PlayerDataAssets.asset",
"Unity/Assets/BundleResources/DataAssets/DiplomacyDataAssets.asset",
"Unity/Assets/Scripts/TH1_DataAssetsScript/LibraryDataAssets.cs",
"Unity/Assets/Scripts/TH1_DataAssetsScript/PlayerDataAssets.cs",
"Unity/Assets/Scripts/TH1_DataAssetsScript/DiplomacyDataAssets.cs",
],
library_giants=library_giants,
wonder_dialogues=wonder_dialogues,
leader_chat_bubbles=leader_chat_bubbles,
diplomacy_lines=diplomacy_lines,
)
def speaker_for_force(force_id: int) -> str:
return {
0: "EgyptianRemilia",
1: "FrenchKaguya",
2: "GermanyKanako",
3: "IndianSatori",
4: "NorwayReimu",
5: "BritishByakuren",
6: "PersianMiko",
7: "ByzantineZanmu",
}.get(force_id, "None")
def main() -> int:
data = build_corpus()
emit_json(data)
emit_markdown(data)
print(f"Extracted {len(data['library_giants'])} library giants")
print(f"Extracted {len(data['wonder_dialogues'])} wonder entries")
print(f"Extracted {len(data['leader_chat_bubbles'])} leader chat-bubble groups")
print(f"Extracted {len(data['diplomacy_lines'])} diplomacy line groups")
return 0
if __name__ == "__main__":
raise SystemExit(main())

View File

@ -0,0 +1,76 @@
---
name: th1-wonder-library-copy
description: TH1 project-specific wonder library copywriting guide for LibraryDataAssets.LibraryWonderList descriptions, including civilization wonder pedia text, seven wonder-category tone, historical landmark anchoring, three-line line-break format, Hakurei/Norway Viking wonder descriptions, qiguan tujian copy, and LibraryWonderData.Desc filling or review.
---
# TH1 Wonder Library Copy
## Source Of Truth
Use this skill for `LibraryDataAssets.LibraryWonderList` description copy. The authoring file is `Unity/Assets/BundleResources/DataAssets/LibraryDataAssets.asset`.
Do not hand-edit generated runtime/export artifacts such as `Unity/Assets/BundleResources/Export/LibraryDataAssets.asset`, `Unity/Assets/BundleResources/Export/Multilingual.asset`, `Tools/Multilingual.xlsx`, or `Tools/MultilingualTxt.txt` unless the user explicitly asks for export/import workflow changes.
## Format
Write each `Desc` as exactly three short display lines separated by `<br>`:
```text
{civilization name} civilization {category} wonder, provides 3 city development value.<br>
{historical position, place, builder, or core function.}<br>
{second-layer meaning, turn, legacy, or symbol.}<br>
```
Keep the indentation style used by Unity YAML:
```yaml
Desc: "Line 1<br>
Line 2<br>
Line 3<br>"
```
Use plain Chinese text in the actual game data. Do not add rich-text term markers unless nearby wonder copy already uses them for the same concept. Existing wonder pedia text uses the wording equivalent to `city development value`, not `city development degree`, in this field.
## Tone
Match existing TH1 wonder copy:
- concise historical pedia voice, not marketing copy;
- one concrete place/object per line rather than abstract praise;
- restrained dramatic ending such as symbol, witness, starting point, monument, echo;
- no gameplay mechanics beyond the fixed first-line benefit;
- no jokes, character dialogue, or direct Touhou character voice in `Desc`;
- avoid overlong clauses that can overflow the panel.
## Seven Categories
Use the category role implied by `WonderLibrary` enum suffix:
- `PEACE`: law, mediation, unity, public order.
- `KNOWLEDGE`: writing, scholarship, memory, astronomy, records.
- `TRADE`: ports, markets, goods, routes, crafts.
- `WEALTH`: treasure, royal resources, luxury, grave goods.
- `POWER`: fortifications, victories, armies, state violence.
- `PARK`: religion, art, ritual continuity, architecture.
- `EYE`: navigation, frontiers, instruments, expeditions.
## Hakurei/Norway Wonder Anchors
For the Hakurei Empire using Norway/Viking civilization, use the Chinese equivalent of `Viking civilization` in the first line to match other entries that name the civilization rather than the Touhou force.
- `NorwayReimuPEACE` / Thingvellir Assembly: Icelandic Althing assembly site; law rock, clan mediation, rift landscape.
- `NorwayReimuKNOWLEDGE` / Jelling Runestone: Denmark's Jelling monuments; runes, royal memory, Harald Bluetooth and faith transition.
- `NorwayReimuTRADE` / Hedeby Trading Port: Viking Age trading settlement; Baltic/North Sea routes, craft goods, harbor market.
- `NorwayReimuWEALTH` / Oseberg Ship Burial: Norwegian ship burial; noble grave, longship, grave goods, afterlife power.
- `NorwayReimuPOWER` / Trelleborg Ring Fortress: Danish Viking ring fortress; royal military engineering, circular rampart, organized garrison.
- `NorwayReimuPARK` / Urnes Stave Church: Norwegian stave church; wood structure, animal ornament, Viking aesthetics and religious transition.
- `NorwayReimuEYE` / L'Anse aux Meadows: Norse settlement in North America; Vinland voyage, sod longhouse, frontier outpost.
## Checks
Before finishing:
- confirm every target `Desc` is non-empty in `DataAssets/LibraryDataAssets.asset`;
- confirm the first line preserves category order: peace, knowledge, trade, wealth, war, culture, exploration;
- confirm no generated export/multilingual files were edited unless explicitly requested;
- if only authoring DataAssets changed, tell the user that Unity multilingual export/import must be run to sync runtime `Export` assets.

View File

@ -0,0 +1,4 @@
interface:
display_name: "TH1 Wonder Library Copy"
short_description: "Draft TH1 wonder pedia descriptions."
default_prompt: "Use $th1-wonder-library-copy to draft TH1 wonder library descriptions."

View File

@ -1,5 +1,5 @@
{
"nextId": 380,
"nextId": 383,
"bugs": [
{
"id": 2,
@ -3882,6 +3882,39 @@
"longTerm": false,
"createdAt": 1781847510309,
"updatedAt": 1781847510309
},
{
"id": 380,
"title": "BGM还会反复出现",
"description": "",
"status": "open",
"priority": "medium",
"module": "",
"longTerm": false,
"createdAt": 1781933805757,
"updatedAt": 1781933805757
},
{
"id": 381,
"title": "1v1联机 ,邀请按钮可能没了",
"description": "",
"status": "open",
"priority": "medium",
"module": "",
"longTerm": false,
"createdAt": 1781933832605,
"updatedAt": 1781933832605
},
{
"id": 382,
"title": "话说现在默认八人好像没有红魔馆了,被白玉替代了,雪糕有什么头猪吗",
"description": "",
"status": "open",
"priority": "medium",
"module": "",
"longTerm": false,
"createdAt": 1781938406585,
"updatedAt": 1781938406585
}
]
}

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

View File

@ -0,0 +1,127 @@
fileFormatVersion: 2
guid: cfe336a566dc4f2bb8202fc08dfc5e2e
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 2
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 512
resizeAlgorithm: 0
textureFormat: 25
textureCompression: 1
compressionQuality: 80
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 1
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Server
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

View File

@ -0,0 +1,127 @@
fileFormatVersion: 2
guid: 7c5bdfd6dd6d4a17a3e83029e30266ab
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 2
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 512
resizeAlgorithm: 0
textureFormat: 25
textureCompression: 1
compressionQuality: 80
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 1
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Server
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 41 KiB

View File

@ -4331,6 +4331,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: e9066aa914ba3a560524a83024da5a57, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
Cost: 0
CityExp: 0
NoNeedTech: 0
@ -4404,6 +4417,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: b7e8ae8bdb020d3071e9a4e53ae0a8f0, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
Cost: 0
CityExp: 0
NoNeedTech: 0
@ -4477,6 +4503,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: 1db4c8585103b95bb99bc4f6ca82145b, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
Cost: 0
CityExp: 0
NoNeedTech: 0
@ -4550,6 +4589,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: e9c62797e1773b311cf13dbe52c313d2, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
Cost: 0
CityExp: 0
NoNeedTech: 0
@ -4623,6 +4675,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: c13472d0d77eb561ce73a9587ecce70e, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
Cost: 0
CityExp: 0
NoNeedTech: 1
@ -4696,6 +4761,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: 7ee97d4aeff9831c980462026ad34eaf, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
Cost: 0
CityExp: 0
NoNeedTech: 1
@ -4769,6 +4847,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: 653a3bc9eae8ec492d86c04177c076c7, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
Cost: 0
CityExp: 0
NoNeedTech: 1
@ -6102,7 +6193,7 @@ MonoBehaviour:
PlayerActionType: 0
AIParamType: 0
CultureCardType: 0
ActionName: "鬼形"
ActionName: "鬼形重现"
Desc: "茨木华扇进入鬼形态并获得狂暴。占位版本不消耗行动点。"
NeedTechDesc: 0
TechDesc:
@ -6204,7 +6295,7 @@ MonoBehaviour:
PlayerActionType: 0
AIParamType: 0
CultureCardType: 0
ActionName: "附着萃香"
ActionName: "攫鬼归身"
Desc: "小萃香附着到附近萃香身上,增加小萃香层数。"
NeedTechDesc: 0
TechDesc:
@ -6238,7 +6329,7 @@ MonoBehaviour:
PlayerActionType: 0
AIParamType: 0
CultureCardType: 0
ActionName: "抖落小萃香"
ActionName: "踏鞴散鬼"
Desc: "将萃香身上的小萃香全部抖出到附近空格。"
NeedTechDesc: 0
TechDesc:
@ -6272,7 +6363,7 @@ MonoBehaviour:
PlayerActionType: 0
AIParamType: 0
CultureCardType: 0
ActionName: "生成小萃香"
ActionName: "燐火化鬼"
Desc: "萃香消耗5点生命生成一只小萃香。"
NeedTechDesc: 0
TechDesc:
@ -6306,7 +6397,7 @@ MonoBehaviour:
PlayerActionType: 0
AIParamType: 0
CultureCardType: 0
ActionName: "投掷单位"
ActionName: "天手力男投"
Desc: "萃香将附近单位投掷到指定或随机附近地格。"
NeedTechDesc: 0
TechDesc:
@ -7823,6 +7914,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: e9066aa914ba3a560524a83024da5a57, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
Cost: 0
CityExp: 3
NoNeedTech: 0
@ -7922,6 +8026,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: b7e8ae8bdb020d3071e9a4e53ae0a8f0, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
Cost: 0
CityExp: 3
NoNeedTech: 0
@ -8021,6 +8138,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: 1db4c8585103b95bb99bc4f6ca82145b, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
Cost: 0
CityExp: 3
NoNeedTech: 0
@ -8120,6 +8250,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: e9c62797e1773b311cf13dbe52c313d2, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
Cost: 0
CityExp: 3
NoNeedTech: 0
@ -8219,6 +8362,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: c13472d0d77eb561ce73a9587ecce70e, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
Cost: 0
CityExp: 3
NoNeedTech: 0
@ -8318,6 +8474,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: 7ee97d4aeff9831c980462026ad34eaf, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
Cost: 0
CityExp: 3
NoNeedTech: 0
@ -8417,6 +8586,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: 653a3bc9eae8ec492d86c04177c076c7, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
Cost: 0
CityExp: 3
NoNeedTech: 0
@ -9850,6 +10032,108 @@ MonoBehaviour:
NoNeedTech: 1
SpriteSize: {x: 40, y: 40}
SpritePos: {x: 0, y: 1}
- ActionId:
ActionType: 12
WonderType: 0
ResourceType: 0
FeatureType: 0
TerrainType: 0
UnitType: 0
GiantType: 0
UnitLevel: 0
Vegetation: 0
UnitActionType: 0
CityLevelUpActionType: 0
CityActionType: 0
GridMiscActionType: 0
SkillType: 0
TechType: 0
PlayerActionType: 16
AIParamType: 0
CultureCardType: 0
ActionName: "\u4E39\u9EA6\u91D1"
Desc: "\u5411\u67D0\u4E2A\u5E1D\u56FD\u53D1\u8D77\u52D2\u7D22\u3002\u82E5\u5BF9\u65B9\u4E0D\u652F\u4ED8\uFF0C\u4E0B\u56DE\u5408\u6240\u6709\u5355\u4F4D\u62A2\u52AB\u6536\u76CA\u7FFB\u500D\u3002"
NeedTechDesc: 1
TechDesc: "\u5411\u67D0\u4E2A\u5E1D\u56FD\u53D1\u8D77\u52D2\u7D22\u3002\u82E5\u5BF9\u65B9\u4E0D\u652F\u4ED8\uFF0C\u4E0B\u56DE\u5408\u6240\u6709\u5355\u4F4D\u62A2\u52AB\u6536\u76CA\u7FFB\u500D\u3002"
NeedLockDesc: 0
LockDesc:
Icon: {fileID: 21300000, guid: afbb41b83c55c794ab8443955957a309, type: 3}
IconViewSizeType: 2
VarientIcon: 0
IconList: []
Cost: 0
CityExp: 0
NoNeedTech: 0
SpriteSize: {x: 40, y: 40}
SpritePos: {x: 0, y: 1}
- ActionId:
ActionType: 12
WonderType: 0
ResourceType: 0
FeatureType: 0
TerrainType: 0
UnitType: 0
GiantType: 0
UnitLevel: 0
Vegetation: 0
UnitActionType: 0
CityLevelUpActionType: 0
CityActionType: 0
GridMiscActionType: 0
SkillType: 0
TechType: 0
PlayerActionType: 17
AIParamType: 0
CultureCardType: 0
ActionName: "\u652F\u4ED8\u52D2\u7D22"
Desc: "\u652F\u4ED8\u52D2\u7D22\u540E\uFF0C\u53CC\u65B9\u4E39\u9EA6\u91D1\u5173\u7CFB\u53D8\u56DE\u4E24\u6E05\u3002"
NeedTechDesc: 0
TechDesc:
NeedLockDesc: 0
LockDesc:
Icon: {fileID: 21300000, guid: afbb41b83c55c794ab8443955957a309, type: 3}
IconViewSizeType: 2
VarientIcon: 0
IconList: []
Cost: 5
CityExp: 0
NoNeedTech: 1
SpriteSize: {x: 40, y: 40}
SpritePos: {x: 0, y: 1}
- ActionId:
ActionType: 12
WonderType: 0
ResourceType: 0
FeatureType: 0
TerrainType: 0
UnitType: 0
GiantType: 0
UnitLevel: 0
Vegetation: 0
UnitActionType: 0
CityLevelUpActionType: 0
CityActionType: 0
GridMiscActionType: 0
SkillType: 0
TechType: 0
PlayerActionType: 18
AIParamType: 0
CultureCardType: 0
ActionName: "\u62D2\u7EDD\u52D2\u7D22"
Desc: "\u62D2\u7EDD\u652F\u4ED8\u4E39\u9EA6\u91D1\u3002\u52D2\u7D22\u65B9\u5BF9\u4F60\u7684\u57CE\u5E02\u62A2\u52AB\u6536\u76CA\u7FFB\u500D\u3002"
NeedTechDesc: 0
TechDesc:
NeedLockDesc: 0
LockDesc:
Icon: {fileID: 21300000, guid: fc66806ee90586f409f27cd9a92a2399, type: 3}
IconViewSizeType: 2
VarientIcon: 0
IconList: []
Cost: 0
CityExp: 0
NoNeedTech: 1
SpriteSize: {x: 40, y: 40}
SpritePos: {x: 0, y: 1}
- ActionId:
ActionType: 4
WonderType: 0

View File

@ -292,6 +292,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 1
IgnoreForceId: 1
IsGridSpType: 1
GridSpType: 5
CivId: 0
ForceId: 0
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: 7c5bdfd6dd6d4a17a3e83029e30266ab, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
- TerrainType: 2
Sprite: {fileID: 21300000, guid: dc29ebac5875f2846b237edabd9eaeca, type: 3}
VarientSprite: 0
@ -2235,7 +2248,7 @@ MonoBehaviour:
SpriteList: []
- Resource: 34
ResourceSubType: 0
Sprite: {fileID: 21300000, guid: 0aa923f844a87e2449176665381a42dd, type: 3}
Sprite: {fileID: 21300000, guid: 7c5bdfd6dd6d4a17a3e83029e30266ab, type: 3}
ResourceName: "\u7B26\u6587"
ResourceDesc: "\u535A\u4E3D\u5E1D\u56FD\u5355\u4F4D\u6B7B\u4EA1\u540E\u7559\u4E0B\u7684\u7B26\u6587\u5730\u5757\u3002"
Exp: 0

View File

@ -576,36 +576,50 @@ MonoBehaviour:
AchivePreId: 328
- WonderLibraryID: 28
Name: "\u8F9B\u683C\u7EF4\u5229\u5C14\u8BAE\u4F1A"
Desc:
Desc: "\u7EF4\u4EAC\u6587\u660E\u548C\u5E73\u5947\u89C2\uFF0C\u63D0\u4F9B3\u70B9\u57CE\u5E02\u53D1\u5C55\u503C\u3002<br>
\u51B0\u5C9B\u963F\u5C14\u5EAD\u8BAE\u4F1A\u7684\u53E4\u8001\u4F1A\u5740\uFF0C\u6C0F\u65CF\u9996\u9886\u5728\u6CD5\u5F8B\u77F3\u65C1\u8C03\u505C\u7EB7\u4E89\u3002<br>
\u88C2\u8C37\u4E0E\u65F7\u91CE\u89C1\u8BC1\u5317\u6D77\u4EBA\u7684\u516C\u5171\u79E9\u5E8F\uFF0C\u662F\u7EF4\u4EAC\u4E16\u754C\u7684\u548C\u5E73\u5951\u7EA6\u3002<br>"
Diags: []
AchivePreId: 0
- WonderLibraryID: 29
Name: "\u8036\u7075\u7B26\u6587\u77F3"
Desc:
Desc: "\u7EF4\u4EAC\u6587\u660E\u77E5\u8BC6\u5947\u89C2\uFF0C\u63D0\u4F9B3\u70B9\u57CE\u5E02\u53D1\u5C55\u503C\u3002<br>
\u4E39\u9EA6\u8036\u7075\u9057\u5740\u7684\u738B\u6743\u7EAA\u5FF5\u7891\uFF0C\u7B26\u6587\u94ED\u523B\u7740\u54C8\u62C9\u5C14\u84DD\u7259\u7684\u529F\u4E1A\u3002<br>
\u77F3\u4E0A\u7684\u6587\u5B57\u8BB0\u5F55\u4E86\u5317\u6B27\u4FE1\u4EF0\u8F6C\u578B\uFF0C\u4E5F\u8BA9\u738B\u56FD\u8BB0\u5FC6\u8DE8\u8D8A\u5343\u5E74\u3002<br>"
Diags: []
AchivePreId: 0
- WonderLibraryID: 30
Name: "\u6D77\u6CFD\u6BD4\u8D38\u6613\u6E2F"
Desc:
Desc: "\u7EF4\u4EAC\u6587\u660E\u8D38\u6613\u5947\u89C2\uFF0C\u63D0\u4F9B3\u70B9\u57CE\u5E02\u53D1\u5C55\u503C\u3002<br>
\u6CE2\u7F57\u7684\u6D77\u4E0E\u5317\u6D77\u822A\u8DEF\u4EA4\u6C47\u4E8E\u6B64\uFF0C\u6728\u5C4B\u5E02\u96C6\u8FCE\u63A5\u8FDC\u822A\u5546\u8239\u3002<br>
\u7425\u73C0\u3001\u76AE\u6BDB\u4E0E\u94F6\u5E01\u5728\u6E2F\u6E7E\u6D41\u8F6C\uFF0C\u94FA\u5F00\u7EF4\u4EAC\u65F6\u4EE3\u7684\u8D38\u6613\u7F51\u7EDC\u3002<br>"
Diags: []
AchivePreId: 0
- WonderLibraryID: 31
Name: "\u5965\u585E\u8D1D\u683C\u8239\u846C"
Desc:
Desc: "\u7EF4\u4EAC\u6587\u660E\u8D22\u5BCC\u5947\u89C2\uFF0C\u63D0\u4F9B3\u70B9\u57CE\u5E02\u53D1\u5C55\u503C\u3002<br>
\u632A\u5A01\u8D35\u65CF\u7684\u8239\u846C\u9057\u5B58\uFF0C\u957F\u8239\u4E0E\u968F\u846C\u73CD\u5B9D\u4E00\u540C\u57CB\u5165\u571F\u4E18\u3002<br>
\u517D\u9996\u8239\u824F\u4E0E\u534E\u4E3D\u5668\u7269\u8BC9\u8BF4\u6765\u4E16\u6743\u529B\uFF0C\u662F\u5317\u6D77\u8D22\u5BCC\u7684\u6C89\u9ED8\u9648\u5217\u3002<br>"
Diags: []
AchivePreId: 0
- WonderLibraryID: 32
Name: "\u7279\u96F7\u52D2\u5821\u73AF\u5F62\u5821\u5792"
Desc:
Desc: "\u7EF4\u4EAC\u6587\u660E\u6218\u4E89\u5947\u89C2\uFF0C\u63D0\u4F9B3\u70B9\u57CE\u5E02\u53D1\u5C55\u503C\u3002<br>
\u4E39\u9EA6\u738B\u6743\u4FEE\u7B51\u7684\u73AF\u5F62\u5821\u5792\uFF0C\u571F\u5792\u4E0E\u5341\u5B57\u9053\u8DEF\u5212\u5206\u4E25\u6574\u519B\u8425\u3002<br>
\u5B83\u4EE5\u51E0\u4F55\u79E9\u5E8F\u7EA6\u675F\u6218\u58EB\u4E0E\u957F\u5C4B\uFF0C\u662F\u7EF4\u4EAC\u519B\u4E8B\u5DE5\u7A0B\u7684\u575A\u786C\u5370\u8BB0\u3002<br>"
Diags: []
AchivePreId: 0
- WonderLibraryID: 33
Name: "\u4E4C\u5C14\u5185\u65AF\u6728\u677F\u6559\u5802"
Desc:
Desc: "\u7EF4\u4EAC\u6587\u660E\u6587\u5316\u5947\u89C2\uFF0C\u63D0\u4F9B3\u70B9\u57CE\u5E02\u53D1\u5C55\u503C\u3002<br>
\u632A\u5A01\u5CE1\u6E7E\u8FB9\u7684\u6728\u677F\u6559\u5802\uFF0C\u6DF1\u8272\u6728\u6784\u627F\u8F7D\u4EA4\u7F20\u517D\u7EB9\u4E0E\u5C16\u9876\u3002<br>
\u7EF4\u4EAC\u96D5\u523B\u5728\u65B0\u4FE1\u4EF0\u4E2D\u5EF6\u7EED\uFF0C\u4F7F\u5317\u6B27\u6728\u827A\u6210\u4E3A\u4E0D\u673D\u7684\u6587\u5316\u56DE\u58F0\u3002<br>"
Diags: []
AchivePreId: 0
- WonderLibraryID: 34
Name: "\u5170\u585E\u5965\u5179\u7267\u8349\u5730"
Desc:
Desc: "\u7EF4\u4EAC\u6587\u660E\u63A2\u7D22\u5947\u89C2\uFF0C\u63D0\u4F9B3\u70B9\u57CE\u5E02\u53D1\u5C55\u503C\u3002<br>
\u5317\u7F8E\u6587\u5170\u6D77\u5CB8\u7684\u8BFA\u65AF\u4EBA\u8425\u5730\uFF0C\u8349\u76AE\u957F\u5C4B\u5B88\u5728\u4E16\u754C\u8FB9\u7F18\u3002<br>
\u4FEE\u8239\u6728\u6599\u4E0E\u7089\u706B\u6B8B\u8FF9\u8BC1\u660E\u8FDC\u822A\u62B5\u8FBE\uFF0C\u662F\u5317\u6D77\u63A2\u7D22\u7684\u5C3D\u5934\u4E0E\u8D77\u70B9\u3002<br>"
Diags: []
AchivePreId: 0

View File

@ -3766,7 +3766,7 @@ MonoBehaviour:
ReserveCommonTransform: 1
- SkillType: 289
SkillViewType: 2
SkillName: "\u632A\u5A01\u7075\u5F02\u73E0"
SkillName: "挪威之珠"
SkillDesc: "\u5F71\u54CD\u9644\u8FD1\u5355\u4F4D\u7684\u79FB\u52A8\u4E0E\u653B\u51FB\u6362\u7B97\u3002\u6B63\u5F0F\u8868\u73B0\u8D44\u6E90\u5F85\u8865\u3002"
NotShow: 0
ShowOnUnitMono: 1
@ -3780,7 +3780,7 @@ MonoBehaviour:
ReserveCommonTransform: 1
- SkillType: 290
SkillViewType: 2
SkillName: "\u4E39\u9EA6\u7075\u5F02\u73E0"
SkillName: "丹麦之珠"
SkillDesc: "\u5F71\u54CD\u9644\u8FD1\u5355\u4F4D\u7684\u653B\u51FB\u4E0E\u9632\u5FA1\u6362\u7B97\u3002\u6B63\u5F0F\u8868\u73B0\u8D44\u6E90\u5F85\u8865\u3002"
NotShow: 0
ShowOnUnitMono: 1
@ -3794,7 +3794,7 @@ MonoBehaviour:
ReserveCommonTransform: 1
- SkillType: 291
SkillViewType: 2
SkillName: "\u82F1\u683C\u5170\u7075\u5F02\u73E0"
SkillName: "英格兰之珠"
SkillDesc: "\u66FF\u5468\u56F4\u53CB\u519B\u627F\u53D7\u4F24\u5BB3\uFF0C\u6700\u591A\u627F\u4F243\u6B21\u3002\u6B63\u5F0F\u8868\u73B0\u8D44\u6E90\u5F85\u8865\u3002"
NotShow: 0
ShowOnUnitMono: 1
@ -3808,7 +3808,7 @@ MonoBehaviour:
ReserveCommonTransform: 1
- SkillType: 292
SkillViewType: 1
SkillName: "\u7075\u5F02\u73E0\u5F3A\u5316"
SkillName: "异世界的疯狂"
SkillDesc: "\u7075\u5F02\u73E0\u53C2\u4E0E\u4E92\u6362\u65F6\uFF0C\u7ED3\u679C\u53D6\u539F\u503C\u4E0E\u6362\u7B97\u503C\u7684\u6700\u5927\u503C\u3002"
NotShow: 0
ShowOnUnitMono: 0
@ -3850,7 +3850,7 @@ MonoBehaviour:
ReserveCommonTransform: 1
- SkillType: 295
SkillViewType: 3
SkillName: "\u9B3C\u5F62\u6001"
SkillName: "鬼腕解封"
SkillDesc: "\u8328\u6728\u534E\u6247\u8FDB\u5165\u9B3C\u5F62\u6001\uFF0C\u83B7\u5F97\u72C2\u66B4\u5E76\u89E3\u9501\u653B\u51FB\u540E\u7684\u989D\u5916\u884C\u52A8\u3002"
NotShow: 0
ShowOnUnitMono: 1
@ -3864,7 +3864,7 @@ MonoBehaviour:
ReserveCommonTransform: 1
- SkillType: 296
SkillViewType: 4
SkillName: "\u77F3\u5316"
SkillName: "吽形石守"
SkillDesc: "\u9AD8\u4E3D\u91CE\u963F\u543D\u77F3\u5316\u540E\u83B7\u5F97\u9632\u5FA1\uFF0C\u65E0\u6CD5\u79FB\u52A8\u6216\u653B\u51FB\uFF0C\u5E76\u4E3A\u9644\u8FD1\u53CB\u519B\u63D0\u4F9B\u9632\u5FA1\u3002"
NotShow: 0
ShowOnUnitMono: 1
@ -3878,7 +3878,7 @@ MonoBehaviour:
ReserveCommonTransform: 1
- SkillType: 297
SkillViewType: 1
SkillName: "\u53CC\u8EAB"
SkillName: "一对的神兽"
SkillDesc: "\u9AD8\u4E3D\u91CE\u963F\u543D\u5347\u7EA7\u6216\u51FA\u6218\u540E\u751F\u6210\u7B2C\u4E8C\u4E2A\u963F\u543D\u3002"
NotShow: 0
ShowOnUnitMono: 0
@ -3892,7 +3892,7 @@ MonoBehaviour:
ReserveCommonTransform: 1
- SkillType: 298
SkillViewType: 4
SkillName: "\u5171\u4EAB\u751F\u547D"
SkillName: "阿吽同息"
SkillDesc: "\u4E24\u4E2A\u963F\u543D\u5171\u4EAB\u751F\u547D\uFF0C\u627F\u4F24\u540E\u540C\u6B65\u5230\u53E6\u4E00\u65B9\u3002"
NotShow: 0
ShowOnUnitMono: 1
@ -3906,7 +3906,7 @@ MonoBehaviour:
ReserveCommonTransform: 1
- SkillType: 299
SkillViewType: 1
SkillName: "\u53CC\u963F\u543D\u64CD\u4F5C"
SkillName: "文兰的远征"
SkillDesc: "\u7B49\u7EA74\u540E\u4E24\u4E2A\u963F\u543D\u90FD\u53EF\u4EE5\u64CD\u4F5C\uFF0C\u4E0D\u518D\u4E92\u76F8\u81EA\u52A8\u77F3\u5316\u3002"
NotShow: 0
ShowOnUnitMono: 0
@ -3920,7 +3920,7 @@ MonoBehaviour:
ReserveCommonTransform: 1
- SkillType: 300
SkillViewType: 1
SkillName: "\u5C0F\u8403\u9999\u751F\u6210"
SkillName: "疏鬼"
SkillDesc: "\u4F0A\u5439\u8403\u9999\u79FB\u52A8\u540E\u5728\u539F\u5730\u751F\u6210\u5C0F\u8403\u9999\u3002"
NotShow: 0
ShowOnUnitMono: 0
@ -3934,7 +3934,7 @@ MonoBehaviour:
ReserveCommonTransform: 1
- SkillType: 301
SkillViewType: 4
SkillName: "\u5C0F\u8403\u9999\u5C42\u6570"
SkillName: "百鬼夜行"
SkillDesc: "\u5C0F\u8403\u9999\u9644\u7740\u5F62\u6210\u7684\u5C42\u6570\u3002\u5C42\u6570\u4E0A\u9650\u7B49\u4E8E\u8403\u9999\u7B49\u7EA7\u3002"
NotShow: 0
ShowOnUnitMono: 1
@ -3948,7 +3948,7 @@ MonoBehaviour:
ReserveCommonTransform: 1
- SkillType: 302
SkillViewType: 4
SkillName: "\u534A\u4F24\u6296\u843D"
SkillName: "鬼神燐火"
SkillDesc: "\u8403\u9999\u53D7\u4F24\u65F6\u51CF\u534A\u4F24\u5BB3\u5E76\u6296\u51FA\u4E00\u53EA\u5C0F\u8403\u9999\u3002"
NotShow: 0
ShowOnUnitMono: 1
@ -3962,7 +3962,7 @@ MonoBehaviour:
ReserveCommonTransform: 1
- SkillType: 303
SkillViewType: 3
SkillName: "\u5927\u8403\u9999"
SkillName: "坤轴大鬼"
SkillDesc: "\u5C0F\u8403\u9999\u5C42\u6570\u8FBE\u52303\u65F6\u7684\u5F62\u6001\u6807\u8BB0\u3002"
NotShow: 0
ShowOnUnitMono: 1
@ -3976,7 +3976,7 @@ MonoBehaviour:
ReserveCommonTransform: 1
- SkillType: 304
SkillViewType: 3
SkillName: "\u5DE8\u5927\u8403\u9999"
SkillName: "百万同一鬼"
SkillDesc: "\u5C0F\u8403\u9999\u5C42\u6570\u8FBE\u52304\u65F6\u7684\u5F62\u6001\u6807\u8BB0\u3002"
NotShow: 0
ShowOnUnitMono: 1
@ -3990,7 +3990,7 @@ MonoBehaviour:
ReserveCommonTransform: 1
- SkillType: 305
SkillViewType: 3
SkillName: "\u4ECE\u5929\u800C\u964D"
SkillName: "大江山悉皆杀"
SkillDesc: "\u5DE8\u5927\u8403\u9999\u53EF\u964D\u843D\u5230\u76EE\u6807\u5730\u683C\u5E76\u9020\u6210\u5468\u56F4\u6E85\u5C04\u4F24\u5BB3\u3002"
NotShow: 0
ShowOnUnitMono: 1
@ -4004,7 +4004,7 @@ MonoBehaviour:
ReserveCommonTransform: 1
- SkillType: 306
SkillViewType: 1
SkillName: "\u5C0F\u8403\u9999"
SkillName: "燐火化鬼"
SkillDesc: "\u5C0F\u8403\u9999\u5355\u4F4D\u6807\u8BB0\u3002\u53EF\u9644\u7740\u5230\u8403\u9999\u8EAB\u4E0A\u3002"
NotShow: 0
ShowOnUnitMono: 1
@ -4033,7 +4033,7 @@ MonoBehaviour:
- SkillType: 308
SkillViewType: 0
SkillName: "\u5706\u76FE\u5899"
SkillDesc: "\u4E0E\u76F8\u90BB\u53CB\u65B9**<\u5706\u76FE\u5175>**\u4E92\u76F8\u83B7\u5F97\u9632\u5FA11.5x\uFF0C\u8BE5\u52A0\u6210\u4E0D\u53E0\u52A0\u3002"
SkillDesc: "与友方**<圆盾兵>**相邻时,获得额外防御。"
NotShow: 0
ShowOnUnitMono: 1
SkillIcon: {fileID: 21300000, guid: cf55b3fe561c3244faa3ad199411bcd3, type: 3}
@ -4046,8 +4046,8 @@ MonoBehaviour:
ReserveCommonTransform: 0
- SkillType: 309
SkillViewType: 0
SkillName: "\u74E6\u5C14\u54C8\u62C9"
SkillDesc: "\u53EF\u76F4\u63A5\u8FDB\u5165**<\u6D45\u6D77>**\u5E76\u8F6C\u6362\u4E3A**<\u5361\u7EF4\u8239>**"
SkillName: "\u5CB8\u88AD"
SkillDesc: "\u53EF\u76F4\u63A5\u8FDB\u5165**<\u6D45\u6D77>**\u5E76\u8F6C\u6362\u4E3A**<\u5361\u7EF4\u8239>**\u3002\u4ECE\u8239\u4E0A\u767B\u9646\u65F6\u4E0D\u4F1A\u635F\u5931**<\u884C\u52A8\u70B9>**\u3002"
NotShow: 0
ShowOnUnitMono: 1
SkillIcon: {fileID: 21300000, guid: dc29ebac5875f2846b237edabd9eaeca, type: 3}

View File

@ -1022,6 +1022,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: e9066aa914ba3a560524a83024da5a57, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
iconViewSizeType: 0
- TechAtom: 7
TechAtomName: "\u5EFA\u9020\u667A\u6167\u5947\u89C2"
@ -1088,6 +1101,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: b7e8ae8bdb020d3071e9a4e53ae0a8f0, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
iconViewSizeType: 0
- TechAtom: 8
TechAtomName: "\u5EFA\u9020\u8D38\u6613\u5947\u89C2"
@ -1154,6 +1180,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: 1db4c8585103b95bb99bc4f6ca82145b, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
iconViewSizeType: 0
- TechAtom: 9
TechAtomName: "\u5EFA\u9020\u548C\u5E73\u5947\u89C2"
@ -1220,6 +1259,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: e9c62797e1773b311cf13dbe52c313d2, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
iconViewSizeType: 0
- TechAtom: 10
TechAtomName: "\u5EFA\u9020\u6743\u529B\u5947\u89C2"
@ -1286,6 +1338,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: c13472d0d77eb561ce73a9587ecce70e, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
iconViewSizeType: 0
- TechAtom: 11
TechAtomName: "\u5EFA\u9020\u6587\u5316\u5947\u89C2"
@ -1352,6 +1417,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: 7ee97d4aeff9831c980462026ad34eaf, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
iconViewSizeType: 0
- TechAtom: 12
TechAtomName: "\u5EFA\u9020\u63A2\u7D22\u5947\u89C2"
@ -1418,6 +1496,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: 653a3bc9eae8ec492d86c04177c076c7, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
iconViewSizeType: 0
- TechAtom: 13
TechAtomName: "\u722C\u5C71"
@ -1783,6 +1874,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: e9066aa914ba3a560524a83024da5a57, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
iconViewSizeType: 0
- TechAtom: 17
TechAtomName: "\u5EFA\u9020\u91C7\u77FF\u573A"
@ -1886,6 +1990,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: b7e8ae8bdb020d3071e9a4e53ae0a8f0, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
iconViewSizeType: 0
- TechAtom: 19
TechAtomName: "\u4EA7\u4E1A"
@ -3511,6 +3628,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: 1db4c8585103b95bb99bc4f6ca82145b, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
iconViewSizeType: 0
- TechAtom: 38
TechAtomName: "\u8BAD\u7EC3\u9A91\u58EB"
@ -3899,6 +4029,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: e9c62797e1773b311cf13dbe52c313d2, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
iconViewSizeType: 0
- TechAtom: 42
TechAtomName: "\u72E9\u730E"
@ -6392,8 +6535,8 @@ MonoBehaviour:
CultureCardType: 0
UseActionSprite: 0
IconContainer:
Icon: {fileID: 21300000, guid: 49c36825d3b9e4d42bc413f376677ad3, type: 3}
IsVarient: 0
Icon: {fileID: 21300000, guid: 9654e91d69aca024c9a5f6e122007a1c, type: 3}
IsVarient: 1
IconList:
- IgnoreCivId: 0
IgnoreForceId: 0
@ -6403,12 +6546,25 @@ MonoBehaviour:
ForceId: 0
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 0}
Sprite: {fileID: 21300000, guid: 9654e91d69aca024c9a5f6e122007a1c, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
iconViewSizeType: 2
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: c13472d0d77eb561ce73a9587ecce70e, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
iconViewSizeType: 0
- TechAtom: 86
TechAtomName: "\u89E3\u9501\u5947\u89C2\u5EFA\u7B51"
Desc:
@ -6437,10 +6593,23 @@ MonoBehaviour:
CultureCardType: 0
UseActionSprite: 0
IconContainer:
Icon: {fileID: 21300000, guid: 49c36825d3b9e4d42bc413f376677ad3, type: 3}
IsVarient: 0
IconList: []
iconViewSizeType: 2
Icon: {fileID: 21300000, guid: c9a566b58f2082b4a9848735e022f3e7, type: 3}
IsVarient: 1
IconList:
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: 7ee97d4aeff9831c980462026ad34eaf, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
iconViewSizeType: 0
- TechAtom: 87
TechAtomName: "\u89E3\u9501\u5947\u89C2\u5EFA\u7B51"
Desc:
@ -6469,10 +6638,23 @@ MonoBehaviour:
CultureCardType: 0
UseActionSprite: 0
IconContainer:
Icon: {fileID: 21300000, guid: 49c36825d3b9e4d42bc413f376677ad3, type: 3}
IsVarient: 0
IconList: []
iconViewSizeType: 2
Icon: {fileID: 21300000, guid: 6b82d407e72f5a04dad2051557c4a48c, type: 3}
IsVarient: 1
IconList:
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: 653a3bc9eae8ec492d86c04177c076c7, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
iconViewSizeType: 0
- TechAtom: 88
TechAtomName: "\u53EC\u5524\u5C0F\u6076\u9B54\u796D\u53F8"
Desc: "\u57CE\u5E02\u5347\u7EA7\u81F3Lv.6\u53CA\u4EE5\u4E0A\u65F6\uFF0C\u53EF\u9009\u62E9\u53EC\u5524\u5E1D\u56FD\u7279\u8272\u5DE8\u4EBA\u5355\u4F4D**<\u5C0F\u6076\u9B54\u796D\u53F8>**\uFF0C\u5176\u732B\u795E\u5F62\u6001\u80FD\u591F\u6CBB\u7597\u53CB\u519B\uFF0C\u6B7B\u4EA1\u540E\u8F6C\u5316\u4E3A\u72EE\u795E\u5F62\u6001\u5177\u5907\u5F3A\u5927\u7684\u6740\u4F24\u529B\u3002\u4E0E\u5176\u4ED6\u7EA2\u9B54\u9986\u82F1\u96C4\u534F\u540C\u4F5C\u6218\u65F6\uFF0C\u53EF\u88AB\u89C6\u4F5C**<\u82F1\u96C4\u5355\u4F4D>**\u89E6\u53D1\u76F8\u5173\u7279\u6B8A\u6548\u679C\u3002"
@ -7475,9 +7657,27 @@ MonoBehaviour:
IsAddSkill: 0
AddSkillCondition: []
AddSkillType: 0
EnableAction: 0
TechActions: []
UseActionSprite: 0
EnableAction: 1
TechActions:
- ActionType: 12
WonderType: 0
ResourceType: 0
FeatureType: 0
TerrainType: 0
UnitType: 0
GiantType: 0
UnitLevel: 0
Vegetation: 0
UnitActionType: 0
CityLevelUpActionType: 0
CityActionType: 0
GridMiscActionType: 0
SkillType: 0
TechType: 0
PlayerActionType: 16
AIParamType: 0
CultureCardType: 0
UseActionSprite: 1
IconContainer:
Icon: {fileID: 21300000, guid: afbb41b83c55c794ab8443955957a309, type: 3}
IsVarient: 0

View File

@ -98,10 +98,12 @@ MonoBehaviour:
NotifyUIInfiltrateStealCoin: "\u6210\u529F\u7A83\u53D6{param}\u91D1\u5E01!"
PresentationUIDiplomacyYouText: "\u60A8"
PresentationUIDiplomacyThinkYouText: "\u5BF9\u65B9\u8BA4\u4E3A\u60A8:"
PresentationUIHakureiClearExterminationPaymentTitle:
PresentationUIHakureiClearExterminationPaymentContent:
PresentationUIHakureiDanegeldPaymentTitle:
PresentationUIHakureiDanegeldPaymentContent:
PresentationUIHakureiClearExterminationPaymentTitle: "\u6536\u5230\u8D21\u91D1"
PresentationUIHakureiClearExterminationPaymentContent: "{param}\u7684\u6210\u5458\u5411\u60A8\u732E\u4E0A\u8D21\u91D1\uFF0C\u5171\u8BA1{param}\u91D1\u5E01\u3002\u8BF7\u6C42\u60A8\u5C06\u5176\u4ECE**<\u9000\u6CBB\u76EE\u6807>**\u540D\u518C\u4E2D\u53BB\u9664\u3002(\u79FB\u9664{param}\u5C42**<\u9000\u6CBB\u76EE\u6807>**)"
PresentationUIHakureiDanegeldPaymentTitle: "\u6536\u5230\u8D21\u91D1"
PresentationUIHakureiDanegeldPaymentContent: "{param}\u5411\u60A8\u732E\u4E0A\u8D21\u91D1\uFF0C\u5171\u8BA1{param}\u91D1\u5E01\u3002\u8BF7\u6C42\u60A8\u62A4\u5176\u5E73\u5B89\uFF0C\u5728**<\u52AB\u63A0>**\u65F6\u9AD8\u62AC\u8D35\u624B\u3002(**<\u52AB\u63A0>**\u7FFB\u500D\u6548\u679C\u5C06\u4E0D\u751F\u6548)"
PresentationUIHakureiDanegeldRejectedTitle: "\u8D21\u91D1\u4EE4\u88AB\u62D2\u7EDD"
PresentationUIHakureiDanegeldRejectedContent: "{param}\u62D2\u7EDD\u652F\u4ED8**<\u4E39\u9EA6\u91D1>**\uFF0C\u5171\u8BA1{param}\u91D1\u5E01\u3002{param}\u5C06\u4EE5\u6218\u65A7\u8BA1\u606F\uFF0C\u5BF9\u5176**<\u52AB\u63A0>**\u6536\u76CA\u7FFB\u500D\u3002"
UnitOfficerName: "\u519B\u5B98"
ForestPreserveName: "\u68EE\u6797\u4FDD\u62A4\u533A"
OceanPreserveName: "\u6D77\u6D0B\u4FDD\u62A4\u533A"

View File

@ -193,3 +193,6 @@ MonoBehaviour:
- Group: GridObject/Forest
Source: {fileID: 21300000, guid: 7fd0edb210f2fd148943930fc02c377c, type: 3}
EyeComfort: {fileID: 21300000, guid: bf21ed929ccd43fbb3875473c37194bb, type: 3}
- Group: GridObject/Ground
Source: {fileID: 21300000, guid: 7c5bdfd6dd6d4a17a3e83029e30266ab, type: 3}
EyeComfort: {fileID: 21300000, guid: cfe336a566dc4f2bb8202fc08dfc5e2e, type: 3}

View File

@ -4331,6 +4331,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: e9066aa914ba3a560524a83024da5a57, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
Cost: 0
CityExp: 0
NoNeedTech: 0
@ -4404,6 +4417,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: b7e8ae8bdb020d3071e9a4e53ae0a8f0, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
Cost: 0
CityExp: 0
NoNeedTech: 0
@ -4477,6 +4503,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: 1db4c8585103b95bb99bc4f6ca82145b, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
Cost: 0
CityExp: 0
NoNeedTech: 0
@ -4550,6 +4589,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: e9c62797e1773b311cf13dbe52c313d2, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
Cost: 0
CityExp: 0
NoNeedTech: 0
@ -4623,6 +4675,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: c13472d0d77eb561ce73a9587ecce70e, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
Cost: 0
CityExp: 0
NoNeedTech: 1
@ -4696,6 +4761,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: 7ee97d4aeff9831c980462026ad34eaf, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
Cost: 0
CityExp: 0
NoNeedTech: 1
@ -4769,6 +4847,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: 653a3bc9eae8ec492d86c04177c076c7, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
Cost: 0
CityExp: 0
NoNeedTech: 1
@ -6102,7 +6193,7 @@ MonoBehaviour:
PlayerActionType: 0
AIParamType: 0
CultureCardType: 0
ActionName: 21218
ActionName: 21493
Desc: 21219
NeedTechDesc: 0
TechDesc:
@ -6204,7 +6295,7 @@ MonoBehaviour:
PlayerActionType: 0
AIParamType: 0
CultureCardType: 0
ActionName: 21224
ActionName: 21514
Desc: 21225
NeedTechDesc: 0
TechDesc:
@ -6238,7 +6329,7 @@ MonoBehaviour:
PlayerActionType: 0
AIParamType: 0
CultureCardType: 0
ActionName: 21226
ActionName: 21494
Desc: 21227
NeedTechDesc: 0
TechDesc:
@ -6272,7 +6363,7 @@ MonoBehaviour:
PlayerActionType: 0
AIParamType: 0
CultureCardType: 0
ActionName: 21228
ActionName: 21495
Desc: 21229
NeedTechDesc: 0
TechDesc:
@ -6306,7 +6397,7 @@ MonoBehaviour:
PlayerActionType: 0
AIParamType: 0
CultureCardType: 0
ActionName: 21230
ActionName: 21496
Desc: 21231
NeedTechDesc: 0
TechDesc:
@ -7823,6 +7914,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: e9066aa914ba3a560524a83024da5a57, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
Cost: 0
CityExp: 3
NoNeedTech: 0
@ -7922,6 +8026,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: b7e8ae8bdb020d3071e9a4e53ae0a8f0, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
Cost: 0
CityExp: 3
NoNeedTech: 0
@ -8021,6 +8138,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: 1db4c8585103b95bb99bc4f6ca82145b, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
Cost: 0
CityExp: 3
NoNeedTech: 0
@ -8120,6 +8250,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: e9c62797e1773b311cf13dbe52c313d2, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
Cost: 0
CityExp: 3
NoNeedTech: 0
@ -8219,6 +8362,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: c13472d0d77eb561ce73a9587ecce70e, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
Cost: 0
CityExp: 3
NoNeedTech: 0
@ -8318,6 +8474,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: 7ee97d4aeff9831c980462026ad34eaf, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
Cost: 0
CityExp: 3
NoNeedTech: 0
@ -8417,6 +8586,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: 653a3bc9eae8ec492d86c04177c076c7, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
Cost: 0
CityExp: 3
NoNeedTech: 0
@ -9850,6 +10032,108 @@ MonoBehaviour:
NoNeedTech: 1
SpriteSize: {x: 40, y: 40}
SpritePos: {x: 0, y: 1}
- ActionId:
ActionType: 12
WonderType: 0
ResourceType: 0
FeatureType: 0
TerrainType: 0
UnitType: 0
GiantType: 0
UnitLevel: 0
Vegetation: 0
UnitActionType: 0
CityLevelUpActionType: 0
CityActionType: 0
GridMiscActionType: 0
SkillType: 0
TechType: 0
PlayerActionType: 16
AIParamType: 0
CultureCardType: 0
ActionName: 21411
Desc: 21438
NeedTechDesc: 1
TechDesc: 21438
NeedLockDesc: 0
LockDesc:
Icon: {fileID: 21300000, guid: afbb41b83c55c794ab8443955957a309, type: 3}
IconViewSizeType: 2
VarientIcon: 0
IconList: []
Cost: 0
CityExp: 0
NoNeedTech: 0
SpriteSize: {x: 40, y: 40}
SpritePos: {x: 0, y: 1}
- ActionId:
ActionType: 12
WonderType: 0
ResourceType: 0
FeatureType: 0
TerrainType: 0
UnitType: 0
GiantType: 0
UnitLevel: 0
Vegetation: 0
UnitActionType: 0
CityLevelUpActionType: 0
CityActionType: 0
GridMiscActionType: 0
SkillType: 0
TechType: 0
PlayerActionType: 17
AIParamType: 0
CultureCardType: 0
ActionName: 21523
Desc: 21524
NeedTechDesc: 0
TechDesc:
NeedLockDesc: 0
LockDesc:
Icon: {fileID: 21300000, guid: afbb41b83c55c794ab8443955957a309, type: 3}
IconViewSizeType: 2
VarientIcon: 0
IconList: []
Cost: 5
CityExp: 0
NoNeedTech: 1
SpriteSize: {x: 40, y: 40}
SpritePos: {x: 0, y: 1}
- ActionId:
ActionType: 12
WonderType: 0
ResourceType: 0
FeatureType: 0
TerrainType: 0
UnitType: 0
GiantType: 0
UnitLevel: 0
Vegetation: 0
UnitActionType: 0
CityLevelUpActionType: 0
CityActionType: 0
GridMiscActionType: 0
SkillType: 0
TechType: 0
PlayerActionType: 18
AIParamType: 0
CultureCardType: 0
ActionName: 21525
Desc: 21526
NeedTechDesc: 0
TechDesc:
NeedLockDesc: 0
LockDesc:
Icon: {fileID: 21300000, guid: fc66806ee90586f409f27cd9a92a2399, type: 3}
IconViewSizeType: 2
VarientIcon: 0
IconList: []
Cost: 0
CityExp: 0
NoNeedTech: 1
SpriteSize: {x: 40, y: 40}
SpritePos: {x: 0, y: 1}
- ActionId:
ActionType: 4
WonderType: 0

View File

@ -292,6 +292,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 1
IgnoreForceId: 1
IsGridSpType: 1
GridSpType: 5
CivId: 0
ForceId: 0
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: 7c5bdfd6dd6d4a17a3e83029e30266ab, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
- TerrainType: 2
Sprite: {fileID: 21300000, guid: dc29ebac5875f2846b237edabd9eaeca, type: 3}
VarientSprite: 0
@ -2235,7 +2248,7 @@ MonoBehaviour:
SpriteList: []
- Resource: 34
ResourceSubType: 0
Sprite: {fileID: 21300000, guid: 0aa923f844a87e2449176665381a42dd, type: 3}
Sprite: {fileID: 21300000, guid: 7c5bdfd6dd6d4a17a3e83029e30266ab, type: 3}
ResourceName: 21395
ResourceDesc: 21477
Exp: 0

View File

@ -520,36 +520,36 @@ MonoBehaviour:
AchivePreId: 328
- WonderLibraryID: 28
Name: 21484
Desc:
Desc: 21516
Diags: []
AchivePreId: 0
- WonderLibraryID: 29
Name: 21485
Desc:
Desc: 21517
Diags: []
AchivePreId: 0
- WonderLibraryID: 30
Name: 21486
Desc:
Desc: 21518
Diags: []
AchivePreId: 0
- WonderLibraryID: 31
Name: 21487
Desc:
Desc: 21519
Diags: []
AchivePreId: 0
- WonderLibraryID: 32
Name: 21488
Desc:
Desc: 21520
Diags: []
AchivePreId: 0
- WonderLibraryID: 33
Name: 21489
Desc:
Desc: 21521
Diags: []
AchivePreId: 0
- WonderLibraryID: 34
Name: 21490
Desc:
Desc: 21522
Diags: []
AchivePreId: 0

File diff suppressed because one or more lines are too long

View File

@ -3759,7 +3759,7 @@ MonoBehaviour:
ReserveCommonTransform: 1
- SkillType: 289
SkillViewType: 2
SkillName: 21280
SkillName: 21497
SkillDesc: 21281
NotShow: 0
ShowOnUnitMono: 1
@ -3773,7 +3773,7 @@ MonoBehaviour:
ReserveCommonTransform: 1
- SkillType: 290
SkillViewType: 2
SkillName: 21282
SkillName: 21498
SkillDesc: 21283
NotShow: 0
ShowOnUnitMono: 1
@ -3787,7 +3787,7 @@ MonoBehaviour:
ReserveCommonTransform: 1
- SkillType: 291
SkillViewType: 2
SkillName: 21284
SkillName: 21499
SkillDesc: 21285
NotShow: 0
ShowOnUnitMono: 1
@ -3801,7 +3801,7 @@ MonoBehaviour:
ReserveCommonTransform: 1
- SkillType: 292
SkillViewType: 1
SkillName: 21286
SkillName: 21500
SkillDesc: 21287
NotShow: 0
ShowOnUnitMono: 0
@ -3843,7 +3843,7 @@ MonoBehaviour:
ReserveCommonTransform: 1
- SkillType: 295
SkillViewType: 3
SkillName: 21218
SkillName: 21501
SkillDesc: 21292
NotShow: 0
ShowOnUnitMono: 1
@ -3857,7 +3857,7 @@ MonoBehaviour:
ReserveCommonTransform: 1
- SkillType: 296
SkillViewType: 4
SkillName: 21293
SkillName: 21502
SkillDesc: 21294
NotShow: 0
ShowOnUnitMono: 1
@ -3871,7 +3871,7 @@ MonoBehaviour:
ReserveCommonTransform: 1
- SkillType: 297
SkillViewType: 1
SkillName: 21295
SkillName: 21503
SkillDesc: 21296
NotShow: 0
ShowOnUnitMono: 0
@ -3885,7 +3885,7 @@ MonoBehaviour:
ReserveCommonTransform: 1
- SkillType: 298
SkillViewType: 4
SkillName: 21297
SkillName: 21504
SkillDesc: 21298
NotShow: 0
ShowOnUnitMono: 1
@ -3899,7 +3899,7 @@ MonoBehaviour:
ReserveCommonTransform: 1
- SkillType: 299
SkillViewType: 1
SkillName: 21299
SkillName: 21505
SkillDesc: 21300
NotShow: 0
ShowOnUnitMono: 0
@ -3913,7 +3913,7 @@ MonoBehaviour:
ReserveCommonTransform: 1
- SkillType: 300
SkillViewType: 1
SkillName: 21301
SkillName: 21506
SkillDesc: 21302
NotShow: 0
ShowOnUnitMono: 0
@ -3927,7 +3927,7 @@ MonoBehaviour:
ReserveCommonTransform: 1
- SkillType: 301
SkillViewType: 4
SkillName: 21303
SkillName: 21507
SkillDesc: 21304
NotShow: 0
ShowOnUnitMono: 1
@ -3941,7 +3941,7 @@ MonoBehaviour:
ReserveCommonTransform: 1
- SkillType: 302
SkillViewType: 4
SkillName: 21305
SkillName: 21508
SkillDesc: 21306
NotShow: 0
ShowOnUnitMono: 1
@ -3955,7 +3955,7 @@ MonoBehaviour:
ReserveCommonTransform: 1
- SkillType: 303
SkillViewType: 3
SkillName: 21307
SkillName: 21509
SkillDesc: 21308
NotShow: 0
ShowOnUnitMono: 1
@ -3969,7 +3969,7 @@ MonoBehaviour:
ReserveCommonTransform: 1
- SkillType: 304
SkillViewType: 3
SkillName: 21309
SkillName: 21510
SkillDesc: 21310
NotShow: 0
ShowOnUnitMono: 1
@ -3983,7 +3983,7 @@ MonoBehaviour:
ReserveCommonTransform: 1
- SkillType: 305
SkillViewType: 3
SkillName: 21232
SkillName: 21515
SkillDesc: 21311
NotShow: 0
ShowOnUnitMono: 1
@ -3997,7 +3997,7 @@ MonoBehaviour:
ReserveCommonTransform: 1
- SkillType: 306
SkillViewType: 1
SkillName: 21312
SkillName: 21495
SkillDesc: 21313
NotShow: 0
ShowOnUnitMono: 1
@ -4026,7 +4026,7 @@ MonoBehaviour:
- SkillType: 308
SkillViewType: 0
SkillName: 21472
SkillDesc: 21473
SkillDesc: 21513
NotShow: 0
ShowOnUnitMono: 1
SkillIcon: {fileID: 21300000, guid: cf55b3fe561c3244faa3ad199411bcd3, type: 3}
@ -4039,8 +4039,8 @@ MonoBehaviour:
ReserveCommonTransform: 0
- SkillType: 309
SkillViewType: 0
SkillName: 21478
SkillDesc: 21479
SkillName: 21491
SkillDesc: 21492
NotShow: 0
ShowOnUnitMono: 1
SkillIcon: {fileID: 21300000, guid: dc29ebac5875f2846b237edabd9eaeca, type: 3}

View File

@ -1022,6 +1022,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: e9066aa914ba3a560524a83024da5a57, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
iconViewSizeType: 0
- TechAtom: 7
TechAtomName: 459
@ -1088,6 +1101,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: b7e8ae8bdb020d3071e9a4e53ae0a8f0, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
iconViewSizeType: 0
- TechAtom: 8
TechAtomName: 460
@ -1154,6 +1180,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: 1db4c8585103b95bb99bc4f6ca82145b, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
iconViewSizeType: 0
- TechAtom: 9
TechAtomName: 458
@ -1220,6 +1259,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: e9c62797e1773b311cf13dbe52c313d2, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
iconViewSizeType: 0
- TechAtom: 10
TechAtomName: 462
@ -1286,6 +1338,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: c13472d0d77eb561ce73a9587ecce70e, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
iconViewSizeType: 0
- TechAtom: 11
TechAtomName: 463
@ -1352,6 +1417,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: 7ee97d4aeff9831c980462026ad34eaf, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
iconViewSizeType: 0
- TechAtom: 12
TechAtomName: 464
@ -1418,6 +1496,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: 653a3bc9eae8ec492d86c04177c076c7, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
iconViewSizeType: 0
- TechAtom: 13
TechAtomName: 447
@ -1783,6 +1874,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: e9066aa914ba3a560524a83024da5a57, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
iconViewSizeType: 0
- TechAtom: 17
TechAtomName: 404
@ -1886,6 +1990,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: b7e8ae8bdb020d3071e9a4e53ae0a8f0, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
iconViewSizeType: 0
- TechAtom: 19
TechAtomName: 1450
@ -3511,6 +3628,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: 1db4c8585103b95bb99bc4f6ca82145b, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
iconViewSizeType: 0
- TechAtom: 38
TechAtomName: 1175
@ -3899,6 +4029,19 @@ MonoBehaviour:
Desc:
HasLevel: 0
LevelSprite: []
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: e9c62797e1773b311cf13dbe52c313d2, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
iconViewSizeType: 0
- TechAtom: 42
TechAtomName: 400
@ -6392,8 +6535,8 @@ MonoBehaviour:
CultureCardType: 0
UseActionSprite: 0
IconContainer:
Icon: {fileID: 21300000, guid: 49c36825d3b9e4d42bc413f376677ad3, type: 3}
IsVarient: 0
Icon: {fileID: 21300000, guid: 9654e91d69aca024c9a5f6e122007a1c, type: 3}
IsVarient: 1
IconList:
- IgnoreCivId: 0
IgnoreForceId: 0
@ -6403,12 +6546,25 @@ MonoBehaviour:
ForceId: 0
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 0}
Sprite: {fileID: 21300000, guid: 9654e91d69aca024c9a5f6e122007a1c, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
iconViewSizeType: 2
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: c13472d0d77eb561ce73a9587ecce70e, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
iconViewSizeType: 0
- TechAtom: 86
TechAtomName: 16653
Desc:
@ -6437,10 +6593,23 @@ MonoBehaviour:
CultureCardType: 0
UseActionSprite: 0
IconContainer:
Icon: {fileID: 21300000, guid: 49c36825d3b9e4d42bc413f376677ad3, type: 3}
IsVarient: 0
IconList: []
iconViewSizeType: 2
Icon: {fileID: 21300000, guid: c9a566b58f2082b4a9848735e022f3e7, type: 3}
IsVarient: 1
IconList:
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: 7ee97d4aeff9831c980462026ad34eaf, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
iconViewSizeType: 0
- TechAtom: 87
TechAtomName: 16653
Desc:
@ -6469,10 +6638,23 @@ MonoBehaviour:
CultureCardType: 0
UseActionSprite: 0
IconContainer:
Icon: {fileID: 21300000, guid: 49c36825d3b9e4d42bc413f376677ad3, type: 3}
IsVarient: 0
IconList: []
iconViewSizeType: 2
Icon: {fileID: 21300000, guid: 6b82d407e72f5a04dad2051557c4a48c, type: 3}
IsVarient: 1
IconList:
- IgnoreCivId: 0
IgnoreForceId: 0
IsGridSpType: 0
GridSpType: 0
CivId: 4
ForceId: 4
OnlyCarryGiant: 0
CarryGiantType: 0
Sprite: {fileID: 21300000, guid: 653a3bc9eae8ec492d86c04177c076c7, type: 3}
Name:
Desc:
HasLevel: 0
LevelSprite: []
iconViewSizeType: 0
- TechAtom: 88
TechAtomName: 17009
Desc: 20145
@ -7475,9 +7657,27 @@ MonoBehaviour:
IsAddSkill: 0
AddSkillCondition: []
AddSkillType: 0
EnableAction: 0
TechActions: []
UseActionSprite: 0
EnableAction: 1
TechActions:
- ActionType: 12
WonderType: 0
ResourceType: 0
FeatureType: 0
TerrainType: 0
UnitType: 0
GiantType: 0
UnitLevel: 0
Vegetation: 0
UnitActionType: 0
CityLevelUpActionType: 0
CityActionType: 0
GridMiscActionType: 0
SkillType: 0
TechType: 0
PlayerActionType: 16
AIParamType: 0
CultureCardType: 0
UseActionSprite: 1
IconContainer:
Icon: {fileID: 21300000, guid: afbb41b83c55c794ab8443955957a309, type: 3}
IsVarient: 0

View File

@ -98,10 +98,12 @@ MonoBehaviour:
NotifyUIInfiltrateStealCoin: 19584
PresentationUIDiplomacyYouText: 17445
PresentationUIDiplomacyThinkYouText: 17446
PresentationUIHakureiClearExterminationPaymentTitle:
PresentationUIHakureiClearExterminationPaymentContent:
PresentationUIHakureiDanegeldPaymentTitle:
PresentationUIHakureiDanegeldPaymentContent:
PresentationUIHakureiClearExterminationPaymentTitle: 21527
PresentationUIHakureiClearExterminationPaymentContent: 21528
PresentationUIHakureiDanegeldPaymentTitle: 21527
PresentationUIHakureiDanegeldPaymentContent: 21530
PresentationUIHakureiDanegeldRejectedTitle: 21531
PresentationUIHakureiDanegeldRejectedContent: 21532
UnitOfficerName: 18060
ForestPreserveName: 17339
OceanPreserveName: 17340

View File

@ -193,3 +193,6 @@ MonoBehaviour:
- Group: GridObject/Forest
Source: {fileID: 21300000, guid: 7fd0edb210f2fd148943930fc02c377c, type: 3}
EyeComfort: {fileID: 21300000, guid: bf21ed929ccd43fbb3875473c37194bb, type: 3}
- Group: GridObject/Ground
Source: {fileID: 21300000, guid: 7c5bdfd6dd6d4a17a3e83029e30266ab, type: 3}
EyeComfort: {fileID: 21300000, guid: cfe336a566dc4f2bb8202fc08dfc5e2e, type: 3}

View File

@ -1749,6 +1749,171 @@ MonoBehaviour:
LineSpacing: 0
ApplyParagraphSpacing: 0
ParagraphSpacing: 0
--- !u!1 &2467266416562749534
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 448512966972728544}
- component: {fileID: 2683687219843875}
- component: {fileID: 5915716447360876931}
- component: {fileID: 5792233006712455263}
m_Layer: 5
m_Name: Point
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &448512966972728544
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2467266416562749534}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 246009854447368091}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 49, y: -4.3}
m_SizeDelta: {x: 97.0928, y: 35}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &2683687219843875
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2467266416562749534}
m_CullTransparentMesh: 1
--- !u!114 &5915716447360876931
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2467266416562749534}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_text: 0/0
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: ce4904f8ddac15944907907115531ad5, type: 2}
m_sharedMaterial: {fileID: 1214840240034325189, guid: ce4904f8ddac15944907907115531ad5, type: 2}
m_fontSharedMaterials: []
m_fontMaterial: {fileID: 0}
m_fontMaterials: []
m_fontColor32:
serializedVersion: 2
rgba: 4284492837
m_fontColor: {r: 0.14509805, g: 0.17254902, b: 0.37647063, a: 1}
m_enableVertexGradient: 0
m_colorMode: 3
m_fontColorGradient:
topLeft: {r: 1, g: 1, b: 1, a: 1}
topRight: {r: 1, g: 1, b: 1, a: 1}
bottomLeft: {r: 1, g: 1, b: 1, a: 1}
bottomRight: {r: 1, g: 1, b: 1, a: 1}
m_fontColorGradientPreset: {fileID: 0}
m_spriteAsset: {fileID: 0}
m_tintAllSprites: 0
m_StyleSheet: {fileID: 0}
m_TextStyleHashCode: -1183493901
m_overrideHtmlColors: 0
m_faceColor:
serializedVersion: 2
rgba: 4294967295
m_fontSize: 24
m_fontSizeBase: 24
m_fontWeight: 400
m_enableAutoSizing: 0
m_fontSizeMin: 18
m_fontSizeMax: 72
m_fontStyle: 0
m_HorizontalAlignment: 1
m_VerticalAlignment: 512
m_textAlignment: 65535
m_characterSpacing: 0
m_wordSpacing: 0
m_lineSpacing: 0
m_lineSpacingMax: 0
m_paragraphSpacing: 0
m_charWidthMaxAdj: 0
m_enableWordWrapping: 1
m_wordWrappingRatios: 0.4
m_overflowMode: 0
m_linkedTextComponent: {fileID: 0}
parentLinkedComponent: {fileID: 0}
m_enableKerning: 1
m_enableExtraPadding: 0
checkPaddingRequired: 0
m_isRichText: 1
m_parseCtrlCharacters: 1
m_isOrthographic: 1
m_isCullingEnabled: 0
m_horizontalMapping: 0
m_verticalMapping: 0
m_uvLineOffset: 0
m_geometrySortingOrder: 0
m_IsTextObjectScaleStatic: 0
m_VertexBufferAutoSizeReduction: 0
m_useMaxVisibleDescender: 1
m_pageToDisplay: 1
m_margin: {x: 0, y: 0, z: 0, w: 0}
m_isUsingLegacyAnimationComponent: 0
m_isVolumetricText: 0
m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
--- !u!114 &5792233006712455263
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2467266416562749534}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 6b27f832d22e4a8d916272b644937774, type: 3}
m_Name:
m_EditorClassIdentifier:
Ban: 0
NoExport: 0
FontBan: 0
Preset: 0
ID: 2498
FontID: 2
TextCfg:
- Type: 1
ApplyFontSize: 0
FontSize: 24
ApplyCharacterSpacing: 0
CharacterSpacing: 0
ApplyWordSpacing: 0
WordSpacing: 0
ApplyLineSpacing: 0
LineSpacing: 0
ApplyParagraphSpacing: 0
ParagraphSpacing: 0
--- !u!1 &2557169226213545688
GameObject:
m_ObjectHideFlags: 0
@ -6039,6 +6204,43 @@ MonoBehaviour:
m_EditorClassIdentifier:
viewType: 23
IsNode: 0
--- !u!1 &7456726194897107305
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 246009854447368091}
m_Layer: 5
m_Name: VikingPoint
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &246009854447368091
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7456726194897107305}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 2521649605749432671}
- {fileID: 448512966972728544}
m_Father: {fileID: 6654619752447261519}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: -413, y: -835}
m_SizeDelta: {x: 327.3936, y: 35}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!1 &7495383733111012763
GameObject:
m_ObjectHideFlags: 0
@ -7600,6 +7802,81 @@ MonoBehaviour:
m_FlexibleWidth: -1
m_FlexibleHeight: -1
m_LayoutPriority: 1
--- !u!1 &8841436308112053044
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2521649605749432671}
- component: {fileID: 2618902781387791032}
- component: {fileID: 1646251903370201855}
m_Layer: 5
m_Name: Icon
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &2521649605749432671
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8841436308112053044}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 246009854447368091}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: -28.6, y: -5.5}
m_SizeDelta: {x: 35, y: 35}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &2618902781387791032
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8841436308112053044}
m_CullTransparentMesh: 1
--- !u!114 &1646251903370201855
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8841436308112053044}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 21300000, guid: 49c36825d3b9e4d42bc413f376677ad3, type: 3}
m_Type: 0
m_PreserveAspect: 1
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!1 &8918240541075311092
GameObject:
m_ObjectHideFlags: 0
@ -7767,6 +8044,7 @@ RectTransform:
- {fileID: 8581185617257750748}
- {fileID: 8838706179418109838}
- {fileID: 1150254605961467606}
- {fileID: 246009854447368091}
- {fileID: 4923972111126380676}
- {fileID: 5891800887547054049}
m_Father: {fileID: 6961690653480397463}

View File

@ -67,7 +67,8 @@ namespace TH1_Core.Events
public enum HakureiPaymentNoticeType
{
ClearExtermination,
Danegeld
Danegeld,
DanegeldRejected
}
public struct ShowUIAnnounceHakureiPayment
@ -107,6 +108,8 @@ namespace TH1_Core.Events
public struct ShowUIInteractionDiplomacyOfferAlly
{
public uint PlayerId;
public uint TargetPlayerId;
public PlayerActionType PlayerActionType;
}

View File

@ -6,6 +6,7 @@ using RuntimeData;
using TH1_Anim;
using TH1_Anim.Fragments;
using TH1_Core.Events;
using TH1_Logic.Action;
using TH1_Logic.Core;
using TH1_Presentation.Sequencer.Task;
using TH1_UI.Controller.Announce;
@ -114,7 +115,7 @@ namespace TH1_Core.Managers
}
//如果当前不是我的回合并且进来了一个UISequencerTask那么要先缓存直到我的回合再显示出来
if (IsDuplicateCityLevelUpChoiceTask(task) || IsDuplicateTreasureChoiceTask(task)) return;
if (IsDuplicateCityLevelUpChoiceTask(task) || IsDuplicateTreasureChoiceTask(task) || IsDuplicateDanegeldChoiceTask(task)) return;
if (Main.MapData?.CurPlayer != null && Main.MapData?.PlayerMap?.SelfPlayerData != null &&
Main.MapData.CurPlayer != Main.MapData.PlayerMap.SelfPlayerData && (task as UISequencerTask) != null)
@ -182,6 +183,28 @@ namespace TH1_Core.Managers
EnqueueTask(new UISequencerTask(ViewControllerManager.UIInteractionTreasureController, interaction), true);
}
public static void EnqueuePendingDanegeldChoices(MapData map, PlayerData player)
{
if (map == null || player == null) return;
if (map != Main.MapData) return;
if (map.CurPlayer == null || map.CurPlayer.Id != player.Id) return;
if (!map.CanLocalControlPlayer(player.Id)) return;
var demanders = new List<PlayerData>();
PlayerActionDiplomacy.GetPendingDanegeldDemanders(map, player, demanders);
foreach (var demander in demanders)
{
if (HasQueuedDanegeldChoice(player.Id, demander.Id)) continue;
var interaction = new ShowUIInteractionDiplomacyOfferAlly
{
PlayerId = demander.Id,
TargetPlayerId = player.Id,
PlayerActionType = PlayerActionType.DanegeldDemand
};
EnqueueTask(new UISequencerTask(ViewControllerManager.UIInteractionDiplomacyOfferAllyController, interaction), true);
}
}
public static void DismissTurnBoundUIOnTurnEnd()
{
RemoveTurnBoundUITasks(_taskQueue);
@ -294,6 +317,49 @@ namespace TH1_Core.Managers
playerId = evt.PlayerId;
return playerId != 0;
}
private static bool HasQueuedDanegeldChoice(uint targetPlayerId, uint demanderPlayerId)
{
return IsDanegeldChoiceTask(_currentTask, targetPlayerId, demanderPlayerId)
|| ContainsDanegeldChoiceTask(_taskQueue, targetPlayerId, demanderPlayerId)
|| ContainsDanegeldChoiceTask(_taskNextFrameQueue, targetPlayerId, demanderPlayerId)
|| ContainsDanegeldChoiceTask(_taskNotCurPlayList, targetPlayerId, demanderPlayerId);
}
private static bool IsDuplicateDanegeldChoiceTask(ISequencerTask task)
{
return TryGetDanegeldChoiceTaskData(task, out var targetPlayerId, out var demanderPlayerId)
&& HasQueuedDanegeldChoice(targetPlayerId, demanderPlayerId);
}
private static bool ContainsDanegeldChoiceTask(Queue<ISequencerTask> queue, uint targetPlayerId, uint demanderPlayerId)
{
foreach (var task in queue)
{
if (IsDanegeldChoiceTask(task, targetPlayerId, demanderPlayerId)) return true;
}
return false;
}
private static bool IsDanegeldChoiceTask(ISequencerTask task, uint targetPlayerId, uint demanderPlayerId)
{
return TryGetDanegeldChoiceTaskData(task, out var taskTargetPlayerId, out var taskDemanderPlayerId)
&& taskTargetPlayerId == targetPlayerId
&& taskDemanderPlayerId == demanderPlayerId;
}
private static bool TryGetDanegeldChoiceTaskData(ISequencerTask task, out uint targetPlayerId, out uint demanderPlayerId)
{
targetPlayerId = 0;
demanderPlayerId = 0;
if (task is not UISequencerTask uiTask) return false;
if (uiTask.GetControllerType() != typeof(UIInteractionDiplomacyOfferAllyController)) return false;
if (uiTask.GetData() is not ShowUIInteractionDiplomacyOfferAlly evt) return false;
if (evt.PlayerActionType != PlayerActionType.DanegeldDemand) return false;
targetPlayerId = evt.TargetPlayerId;
demanderPlayerId = evt.PlayerId;
return targetPlayerId != 0 && demanderPlayerId != 0;
}
private static void TryProcessNext()
{

View File

@ -357,7 +357,7 @@ namespace RuntimeData
}
}
public enum GridSpType { None,RemiliaGrid,KaguyaGrid,RemiliaGridDark,LeyLine,Max }
public enum GridSpType { None,RemiliaGrid,KaguyaGrid,RemiliaGridDark,LeyLine,HakureiRune,Max }
// 每个格子包含5个层次的信息
[MemoryPackable]
@ -529,6 +529,7 @@ namespace RuntimeData
GridSpType ret = GridSpType.None;
foreach (var SpType in SpTypeList)
{
if (SpType == GridSpType.HakureiRune && ret == GridSpType.None) ret = GridSpType.HakureiRune;
if (SpType == GridSpType.KaguyaGrid) ret = GridSpType.KaguyaGrid;
if (SpType == GridSpType.RemiliaGrid) ret = GridSpType.RemiliaGrid;
}
@ -717,6 +718,11 @@ namespace RuntimeData
if (Terrain != TerrainType.Land) return false;
if (Feature == TerrainFeature.Mountain) return false;
}
if (type == GridSpType.HakureiRune)
{
if (Terrain != TerrainType.Land) return false;
if (Feature == TerrainFeature.Mountain) return false;
}
SpTypeList.Add(type);
origin?.HeroTask(map)?.OnAddSpType(map, type);
//如果是remiliaGrid且是斯卡雷特帝国的单位给当前的unit填加skill
@ -734,6 +740,8 @@ namespace RuntimeData
return GridSpType.RemiliaGrid;
if (HasSpType(GridSpType.KaguyaGrid))
return GridSpType.KaguyaGrid;
if (HasSpType(GridSpType.HakureiRune))
return GridSpType.HakureiRune;
return SpTypeList.Count > 0 ? SpTypeList[0] : GridSpType.None;
}

View File

@ -310,13 +310,21 @@ namespace RuntimeData
private static uint PickDefaultCivId(int preferredIndex, HashSet<uint> usedCivs)
{
const int defaultCivCount = 17;
uint fallbackCivId = 0;
bool hasFallback = false;
for (int offset = 0; offset < defaultCivCount; offset++)
{
var civId = (uint)((preferredIndex + offset) % defaultCivCount);
if (!ContentGate.CanUseEmpire(civId, civId)) continue;
if (!hasFallback)
{
fallbackCivId = civId;
hasFallback = true;
}
if (!usedCivs.Contains(civId)) return civId;
}
return (uint)preferredIndex;
return hasFallback ? fallbackCivId : 0;
}
private void NormalizePlayerSlot(MemberCiv slot, int index)
@ -330,6 +338,7 @@ namespace RuntimeData
}
if (slot.IsAI) slot.IsHostControlled = false;
if (slot.MemberId == 0) slot.PlayerId = 0;
NormalizeUnavailablePlayerSlotEmpire(slot, index);
}
private static void NormalizeSerializedPlayerSlot(MemberCiv slot, int index)
@ -342,6 +351,17 @@ namespace RuntimeData
slot.IsHostControlled = false;
}
if (slot.IsAI) slot.IsHostControlled = false;
NormalizeUnavailablePlayerSlotEmpire(slot, index);
}
private static void NormalizeUnavailablePlayerSlotEmpire(MemberCiv slot, int index)
{
if (slot == null || !slot.IsCivFixed) return;
if (ContentGate.CanUseEmpire(slot.CivId, slot.ForceId)) return;
var civId = PickDefaultCivId(index, new HashSet<uint>());
slot.CivId = civId;
slot.ForceId = civId;
}
// 根据房间成员信息更新 mapconfig 信息
@ -517,6 +537,7 @@ namespace RuntimeData
{
var slot = GetPlayerSlot(index, netMode);
if (slot == null) return false;
if (!ContentGate.CanUseEmpire(civId, forceId)) return false;
if (slot.CivId == civId && slot.ForceId == forceId && slot.IsCivFixed) return false;
slot.CivId = civId;
slot.ForceId = forceId;
@ -528,6 +549,7 @@ namespace RuntimeData
{
var slot = GetPlayerSlot(index, NetMode.Single);
if (slot == null) return false;
if (!ContentGate.CanUseEmpire(civId, forceId)) return false;
var isHostControlled = index != 0 && slot.MemberId == 0 && !slot.IsAI && slot.IsHostControlled;
var isAI = index != 0 && !isHostControlled;
@ -700,6 +722,11 @@ namespace RuntimeData
public bool UpdateMemberCiv(MemberCiv civ)
{
if (civ == null) return false;
if (!ContentGate.CanUseEmpire(civ.CivId, civ.ForceId))
{
LogSystem.LogWarning($"Unavailable empire rejected: civ={civ.CivId}, force={civ.ForceId}");
return false;
}
var lobby = LobbyManager.Instance.Lobby;
if (lobby.IsInLobby() && civ.MemberId == lobby.GetLobbyOwnerId())
civ.IsReady = true;
@ -909,6 +936,7 @@ namespace RuntimeData
private bool ApplyMemberCivLocal(MemberCiv civ)
{
if (!ContentGate.CanUseEmpire(civ.CivId, civ.ForceId)) return false;
EnsurePlayerSlots(NetMode.Multi);
var memberCiv = civ.MemberId != 0 ? GetMemberCiv(civ.MemberId) : null;
var targetIndex = civ.Index;

View File

@ -60,6 +60,13 @@ namespace RuntimeData
War, // 战争
LeagueRupture, // 联盟破裂
}
public enum DanegeldState
{
Clear,
Demanding,
Refused,
}
// 好感状态枚举
@ -1887,6 +1894,9 @@ namespace RuntimeData
public int IsCalm;
// PlayerId 是我的队友 (逻辑相当于同盟)
public bool IsTeammate;
public DanegeldState DanegeldState;
public uint LastDanegeldDemandTurn;
public uint DanegeldRefusedTurn;
[MemoryPackConstructor]
@ -1898,6 +1908,9 @@ namespace RuntimeData
IsLeagueRupture = false;
IsLeagueRequest = false;
IsTeammate = false;
DanegeldState = DanegeldState.Clear;
LastDanegeldDemandTurn = 0;
DanegeldRefusedTurn = 0;
FeelingStrategyList = new List<FeelingStrategy>();
}
@ -1915,6 +1928,9 @@ namespace RuntimeData
IsLeagueRequest = copyData.IsLeagueRequest;
IsCalm = copyData.IsCalm;
IsTeammate = copyData.IsTeammate;
DanegeldState = copyData.DanegeldState;
LastDanegeldDemandTurn = copyData.LastDanegeldDemandTurn;
DanegeldRefusedTurn = copyData.DanegeldRefusedTurn;
}
public void DeepCopy(CountryDiplomacyInfo copyData)
@ -1931,6 +1947,9 @@ namespace RuntimeData
IsLeagueRequest = copyData.IsLeagueRequest;
IsCalm = copyData.IsCalm;
IsTeammate = copyData.IsTeammate;
DanegeldState = copyData.DanegeldState;
LastDanegeldDemandTurn = copyData.LastDanegeldDemandTurn;
DanegeldRefusedTurn = copyData.DanegeldRefusedTurn;
}
}

View File

@ -1673,6 +1673,21 @@ namespace RuntimeData
if(GetSkill(SkillType.ScarletMistRealTimeVampire,out var _))
RemoveSkill(SkillType.ScarletMistRealTimeVampire,map);
}
public void AfterTransformFromBoat(MapData map, GridData target, MoveType moveType,
List<Vector2Int> path = null)
{
if (map == null || target == null || !IsValidOnMap(map, target)) return;
var isFrozen = IsFrozen();
var copy = new List<SkillBase>(Skills);
foreach (var skill in copy)
{
if (!IsValidOnMap(map, target)) return;
if (isFrozen && IsSkillFrozenFilter(skill)) continue;
skill.AfterTransformFromBoat(this, target, map, moveType, path);
}
}
// 成为移动目标时
public void OnBeInteractTarget(MapData map, UnitData origin, GridData target)

View File

@ -263,6 +263,11 @@ public class GridAndResourceDataAssets : ScriptableObject
if (t.IsGridSpType && t.GridSpType == GridSpType.LeyLine)
return ResolveVisualSprite(t.Sprite);
if (grid.HasSpType(GridSpType.HakureiRune))
foreach (var t in info.SpriteList)
if (t.IsGridSpType && t.GridSpType == GridSpType.HakureiRune)
return ResolveVisualSprite(t.Sprite);
foreach (var t in info.SpriteList)

View File

@ -142,6 +142,7 @@ public static class ContentGate
public static bool CanUseEmpire(Empire empire)
{
if (empire.Civ == CivEnum.Common || empire.Force == ForceEnum.Common) return false;
return CanUse(EmpireAvailability.TryGetValue(empire, out var availability)
? availability
: ContentAvailability.Public);

View File

@ -123,6 +123,8 @@ public class TextDataAssets : ScriptableObject
[MultilingualField] public string PresentationUIHakureiClearExterminationPaymentContent;
[MultilingualField] public string PresentationUIHakureiDanegeldPaymentTitle;
[MultilingualField] public string PresentationUIHakureiDanegeldPaymentContent;
[MultilingualField] public string PresentationUIHakureiDanegeldRejectedTitle;
[MultilingualField] public string PresentationUIHakureiDanegeldRejectedContent;
//--------- UnitDataAsset ---------

View File

@ -407,26 +407,19 @@ namespace RuntimeData
if (!Table.Instance.UnitTypeDataAssets.GetGiantTypeChessType(giantType, out ChessType chessType))
return false;
if (!Table.Instance.LibraryDataAssets.GetLibraryInfoByGiant(giantType, out var libInfo)) return false;
if (libInfo.AchivePreId <= 0) return false;
smallid = (uint)libInfo.AchivePreId % 100;
return true;
return smallid != 0;
}
public bool GetSmallIdByWonderAndEmpire(Empire empire ,WonderTypeEnum wonder, out uint smallid)
{
smallid = 0;
int tmp = -1;
if (empire.Civ == CivEnum.Egyptian)
tmp = 0;
if (empire.Civ == CivEnum.French)
tmp = 1;
if (empire.Civ == CivEnum.Germany)
tmp = 2;
if (empire.Civ == CivEnum.Indian)
tmp = 3;
if (tmp == -1) return false;
smallid = (uint)tmp * 7 + (uint)wonder;
return true;
if (!Table.Instance.LibraryDataAssets.GetLibraryInfoByWonder(empire, wonder, out var libInfo)) return false;
if (libInfo.AchivePreId <= 0) return false;
smallid = (uint)libInfo.AchivePreId % 100;
return smallid != 0;
}
}

View File

@ -70,6 +70,7 @@ namespace Logic.Action
PlayerSurrender,
BuyCultureCard,
CityAction,
HakureiEinherjarCityDevelopment,
}
@ -450,6 +451,9 @@ namespace Logic.Action
PlayerActionType.BreakAlly,
PlayerActionType.Embassy,
PlayerActionType.BreakEmbassy,
PlayerActionType.DanegeldDemand,
PlayerActionType.DanegeldPay,
PlayerActionType.DanegeldReject,
};
foreach (var playerActionType in diplomacyActionTypes)
{
@ -750,6 +754,12 @@ namespace Logic.Action
};
ActionLogicDict[commonActionId] = new CityAction(commonActionId);
}
commonActionId = new CommonActionId
{
ActionType = CommonActionType.HakureiEinherjarCityDevelopment
};
ActionLogicDict[commonActionId] = new HakureiEinherjarCityDevelopmentAction(commonActionId);
//unitAction自身行为的各个行为逻辑
foreach (UnitActionType unitActionType in System.Enum.GetValues(typeof(UnitActionType)))
@ -1083,6 +1093,7 @@ namespace Logic.Action
if (actionType == CommonActionType.UnitAction) return MainObjectType.Unit;
if (actionType == CommonActionType.CityLevelUpAction) return MainObjectType.City;
if (actionType == CommonActionType.CityAction) return MainObjectType.City;
if (actionType == CommonActionType.HakureiEinherjarCityDevelopment) return MainObjectType.City;
if (actionType == CommonActionType.UnitSkill) return MainObjectType.Unit;
if (actionType == CommonActionType.LearnTech) return MainObjectType.Player;
if (actionType == CommonActionType.UnitMove) return MainObjectType.Unit;
@ -1156,6 +1167,62 @@ namespace Logic.Action
}
public class HakureiEinherjarCityDevelopmentAction : ActionLogicBase
{
public HakureiEinherjarCityDevelopmentAction(CommonActionId id) : base(id)
{
}
protected override bool Execute(CommonActionParams actionParams)
{
if (!CheckCan(actionParams)) return false;
if (!actionParams.CityData.Grid(actionParams.MapData, out var cityGrid)) return false;
var cost = GetEinherjarCost(actionParams);
if (!HakureiEinherjarCounter.TrySpendPlayerPoints(actionParams.MapData, actionParams.PlayerData, cost))
return false;
if (!Main.CityLogic.GridGiveCityExp_LogicView(actionParams.MapData, actionParams.PlayerData, cityGrid, actionParams.CityData, 1))
return false;
HakureiEinherjarCounter.AddCityOfferingLevel(actionParams.MapData, actionParams.CityData, 1);
actionParams.CityData.SetCityRenderer(actionParams.MapData);
cityGrid.Renderer(actionParams.MapData)?.InstantUpdateGrid(true);
return true;
}
public int GetEinherjarCost(CommonActionParams actionParams)
{
return HakureiEinherjarCounter.GetCityDevelopmentCost(actionParams?.CityData);
}
public override int GetCost(CommonActionParams actionParams)
{
return 0;
}
public override bool CheckCan(CommonActionParams actionParams)
{
if (!CheckShow(actionParams, out _)) return false;
return HakureiEinherjarCounter.GetPlayerPoints(actionParams.PlayerData) >= GetEinherjarCost(actionParams);
}
public override bool CheckShow(CommonActionParams actionParams, out ShowType showType)
{
showType = ShowType.None;
if (actionParams?.MapData == null) return false;
if (actionParams.PlayerData == null) return false;
if (actionParams.CityData == null) return false;
if (actionParams.MainObjectType != MainObjectType.City) return false;
if (!actionParams.MapData.CheckCityIdBelongPlayerId(actionParams.CityData.Id, actionParams.PlayerData.Id)) return false;
if (!actionParams.CityData.Grid(actionParams.MapData, out var cityGrid)) return false;
if (cityGrid.Resource != ResourceType.CityCenter) return false;
if (!HakureiEinherjarCounter.HasPlayerPointCounter(actionParams.PlayerData)) return false;
if (HakureiEinherjarCounter.GetPlayerPoints(actionParams.PlayerData) < GetEinherjarCost(actionParams))
showType = ShowType.Cost;
return true;
}
}
// 行为基类
public abstract class ActionLogicBase
{
@ -3043,6 +3110,7 @@ namespace Logic.Action
if(actionParams.PlayerData.IsSelfPlayer())
{
PresentationManager.EnqueuePendingDanegeldChoices(actionParams.MapData, actionParams.PlayerData);
PresentationManager.EnqueuePendingCityLevelUpChoices(actionParams.MapData, actionParams.PlayerData);
EventManager.Publish(new ShowUIBottomBottomBarNextTurn(){});
}
@ -3076,7 +3144,9 @@ namespace Logic.Action
protected override bool Execute(CommonActionParams actionParams)
{
if (!CheckCan(actionParams)) return false;
PlayerActionDiplomacy.RejectPendingDanegeldDemandsInTurnEnd(actionParams.MapData, actionParams.PlayerData);
actionParams.MapData.OnTurnEnd(actionParams.PlayerData.Id);
PlayerActionDiplomacy.ClearExpiredDanegeldRefusals(actionParams.MapData, actionParams.PlayerData);
if (actionParams.MapData == Main.MapData)
PresentationManager.DismissTurnBoundUIOnTurnEnd();
if(actionParams.PlayerData.IsSelfPlayer())

View File

@ -45,6 +45,9 @@ namespace TH1_Logic.Action
TreasureGainTech,
TreasureGainCulture,
TreasureGainCityExp,
DanegeldDemand,
DanegeldPay,
DanegeldReject,
Max
}
@ -99,6 +102,8 @@ namespace TH1_Logic.Action
MapData map = actionParams.MapData;
PlayerData player = actionParams.PlayerData;
PlayerData targetPlayer = actionParams.TargetPlayerData;
if (IsDanegeldAction(_actionId.PlayerActionType))
return ExecuteDanegeld(actionParams, player, targetPlayer);
if (!map.GetCapitalCityDataByPlayerId(actionParams.TargetPlayerData.Id, out var targetCity)) return false;
if (!map.GetCapitalCityDataByPlayerId(actionParams.PlayerData.Id, out var city)) return false;
if (!map.GetGridDataByCityId(targetCity.Id, out var targetGrid)) return false;
@ -306,6 +311,9 @@ namespace TH1_Logic.Action
if (actionParams.MainObjectType != MainObjectType.Player) return false;
if (actionParams.TargetPlayerData == null || !actionParams.TargetPlayerData.IsSurvival ) return false;
if (!actionParams.PlayerData.MeetPlayers.Contains(actionParams.TargetPlayerData.Id)) return false;
if (IsDanegeldAction(_actionId.PlayerActionType))
return CheckCanDanegeld(actionParams);
//Step #2 判断钱够不够
if (GetCost(actionParams) > actionParams.PlayerData.PlayerCoin)
@ -383,6 +391,9 @@ namespace TH1_Logic.Action
if (actionParams.TargetPlayerData == null || !actionParams.TargetPlayerData.IsSurvival ) return false;
if (!actionParams.PlayerData.MeetPlayers.Contains(actionParams.TargetPlayerData.Id)) return false;
if (IsDanegeldAction(_actionId.PlayerActionType))
return CheckShowDanegeld(actionParams, out showType);
//如果不是breakAlly默认返回团详细处理showType
if (_actionId.PlayerActionType != PlayerActionType.BreakAlly)
{
@ -480,6 +491,8 @@ namespace TH1_Logic.Action
MapData map = actionParams.MapData;
PlayerData player = actionParams.PlayerData;
PlayerData targetPlayer = actionParams.TargetPlayerData;
if (IsDanegeldAction(_actionId.PlayerActionType))
return CheckShowStateDanegeld(actionParams);
if (!map.GetCapitalCityDataByPlayerId(actionParams.TargetPlayerData.Id, out var city)) return ActionShowState.None;
if (!map.GetGridDataByCityId(city.Id, out var grid)) return ActionShowState.None;
actionParams.PlayerData.GetCountryDiplomacyInfo(actionParams.TargetPlayerData.Id, out var dipInfo);
@ -525,6 +538,204 @@ namespace TH1_Logic.Action
return ActionShowState.None;
}
public static bool IsDanegeldAction(PlayerActionType playerActionType)
{
return playerActionType == PlayerActionType.DanegeldDemand
|| playerActionType == PlayerActionType.DanegeldPay
|| playerActionType == PlayerActionType.DanegeldReject;
}
public static void GetPendingDanegeldDemanders(MapData map, PlayerData targetPlayer, List<PlayerData> result)
{
result?.Clear();
if (map?.PlayerMap?.PlayerDataList == null || targetPlayer == null || result == null) return;
foreach (var demander in map.PlayerMap.PlayerDataList)
{
if (demander == null || demander.Id == targetPlayer.Id) continue;
if (!demander.IsSurvival) continue;
if (!TryGetDanegeldRelation(demander, targetPlayer, out var info)) continue;
if (info.DanegeldState == DanegeldState.Demanding) result.Add(demander);
}
result.Sort((a, b) => a.Id.CompareTo(b.Id));
}
public static bool RejectPendingDanegeldDemandsInTurnEnd(MapData map, PlayerData targetPlayer)
{
if (map == null || targetPlayer == null) return false;
var demanders = new List<PlayerData>();
GetPendingDanegeldDemanders(map, targetPlayer, demanders);
var rejected = false;
foreach (var demander in demanders)
{
var actionId = new CommonActionId
{
ActionType = CommonActionType.PlayerAction,
PlayerActionType = PlayerActionType.DanegeldReject
};
var action = ActionLogicFactory.GetActionLogic(actionId);
var param = new CommonActionParams(mapData: map, playerData: targetPlayer,
targetPlayer: demander, mainObjectType: MainObjectType.Player);
param.RefreshParams();
if (action?.ExecuteWithoutFullActionPeriod(param) == true) rejected = true;
}
return rejected;
}
public static void ClearExpiredDanegeldRefusals(MapData map, PlayerData targetPlayer)
{
if (map?.PlayerMap?.PlayerDataList == null || targetPlayer == null) return;
foreach (var demander in map.PlayerMap.PlayerDataList)
{
if (demander == null || demander.Id == targetPlayer.Id) continue;
if (!TryGetDanegeldRelation(demander, targetPlayer, out var info)) continue;
if (info.DanegeldState != DanegeldState.Refused) continue;
if (targetPlayer.Turn <= info.DanegeldRefusedTurn) continue;
info.DanegeldState = DanegeldState.Clear;
info.DanegeldRefusedTurn = 0;
}
}
public static int GetDanegeldRaidMultiplier(PlayerData raider, PlayerData targetPlayer)
{
if (raider == null || targetPlayer == null) return 1;
if (!TryGetDanegeldRelation(raider, targetPlayer, out var info)) return 1;
return info.DanegeldState == DanegeldState.Refused ? 2 : 1;
}
private bool ExecuteDanegeld(CommonActionParams actionParams, PlayerData player, PlayerData targetPlayer)
{
if (_actionId.PlayerActionType == PlayerActionType.DanegeldDemand)
{
if (!TryGetDanegeldRelation(player, targetPlayer, out var info)) return false;
info.DanegeldState = DanegeldState.Demanding;
info.LastDanegeldDemandTurn = player.Turn;
info.DanegeldRefusedTurn = 0;
if(!targetPlayer.MeetPlayers.Contains(player.Id))
Main.PlayerLogic.AddMeetPlayer(actionParams.MapData,targetPlayer,player);
if (actionParams.MapData == Main.MapData && player.Id == Main.MapData.PlayerMap.SelfPlayerId)
EventManager.Publish(new HideUIInfoDiplomacy());
return true;
}
if (!TryGetDanegeldRelation(targetPlayer, player, out var demanderToPlayer)) return false;
if (_actionId.PlayerActionType == PlayerActionType.DanegeldPay)
{
var payAmount = Mathf.Min(Mathf.Max(0, GetCost(actionParams)), Mathf.Max(0, player.PlayerCoin));
if (payAmount > 0)
{
player.SpendCoin(payAmount);
targetPlayer.AddCoin(payAmount);
ReimuNorwaySkillUtil.EnqueueDanegeldPaymentNotice(actionParams.MapData, player, targetPlayer.Id,
payAmount, targetPlayer.Id);
}
demanderToPlayer.DanegeldState = DanegeldState.Clear;
demanderToPlayer.DanegeldRefusedTurn = 0;
return true;
}
if (_actionId.PlayerActionType == PlayerActionType.DanegeldReject)
{
demanderToPlayer.DanegeldState = DanegeldState.Refused;
demanderToPlayer.DanegeldRefusedTurn = player.Turn;
return true;
}
return false;
}
private bool CheckCanDanegeld(CommonActionParams actionParams)
{
var player = actionParams.PlayerData;
var targetPlayer = actionParams.TargetPlayerData;
if (player == null || targetPlayer == null || player.Id == targetPlayer.Id) return false;
if (_actionId.PlayerActionType == PlayerActionType.DanegeldDemand)
{
if (!player.TechTree.CheckActionCan(_actionId)) return false;
if (!TryGetDanegeldRelation(player, targetPlayer, out var info)) return false;
if (!TryGetDanegeldRelation(targetPlayer, player, out var targetInfo)) return false;
if (info.IsTeammate || targetInfo.IsTeammate) return false;
if (actionParams.MapData.SameUnion(player.Id, targetPlayer.Id)) return false;
if (info.DiplomacyState == DiplomacyState.League || targetInfo.DiplomacyState == DiplomacyState.League)
return false;
return info.DanegeldState == DanegeldState.Clear;
}
if (!TryGetDanegeldRelation(targetPlayer, player, out var demanderToPlayer)) return false;
return demanderToPlayer.DanegeldState == DanegeldState.Demanding;
}
private bool CheckShowDanegeld(CommonActionParams actionParams, out ShowType showType)
{
showType = ShowType.None;
if (_actionId.PlayerActionType != PlayerActionType.DanegeldDemand)
return CheckCanDanegeld(actionParams);
if (!Table.Instance.PlayerDataAssets.CheckActionInTechPool(_actionId, actionParams.PlayerData))
return false;
if (!actionParams.PlayerData.TechTree.CheckActionCan(_actionId))
{
showType = ShowType.Locked;
return true;
}
if (!TryGetDanegeldRelation(actionParams.PlayerData, actionParams.TargetPlayerData, out var info))
return false;
if (!TryGetDanegeldRelation(actionParams.TargetPlayerData, actionParams.PlayerData, out var targetInfo))
return false;
if (info.IsTeammate || targetInfo.IsTeammate || actionParams.MapData.SameUnion(actionParams.PlayerData.Id, actionParams.TargetPlayerData.Id)
|| info.DiplomacyState == DiplomacyState.League || targetInfo.DiplomacyState == DiplomacyState.League)
{
showType = ShowType.Locked;
return true;
}
if (info.DanegeldState == DanegeldState.Demanding)
{
showType = ShowType.Send;
return true;
}
if (info.DanegeldState == DanegeldState.Refused)
{
showType = ShowType.Locked;
return true;
}
return true;
}
private ActionShowState CheckShowStateDanegeld(CommonActionParams actionParams)
{
if (_actionId.PlayerActionType != PlayerActionType.DanegeldDemand)
return CheckCanDanegeld(actionParams) ? ActionShowState.Available : ActionShowState.None;
if (!Table.Instance.PlayerDataAssets.CheckActionInTechPool(_actionId, actionParams.PlayerData))
return ActionShowState.None;
if (!actionParams.PlayerData.TechTree.CheckActionCan(_actionId))
return ActionShowState.Unavailable;
if (!TryGetDanegeldRelation(actionParams.PlayerData, actionParams.TargetPlayerData, out var info))
return ActionShowState.None;
if (!TryGetDanegeldRelation(actionParams.TargetPlayerData, actionParams.PlayerData, out var targetInfo))
return ActionShowState.None;
if (info.IsTeammate || targetInfo.IsTeammate || actionParams.MapData.SameUnion(actionParams.PlayerData.Id, actionParams.TargetPlayerData.Id)
|| info.DiplomacyState == DiplomacyState.League || targetInfo.DiplomacyState == DiplomacyState.League)
return ActionShowState.Unavailable;
if (info.DanegeldState != DanegeldState.Clear) return ActionShowState.Unavailable;
return ActionShowState.Available;
}
private static bool TryGetDanegeldRelation(PlayerData demander, PlayerData targetPlayer, out CountryDiplomacyInfo info)
{
info = null;
if (demander == null || targetPlayer == null) return false;
return demander.GetCountryDiplomacyInfo(targetPlayer.Id, out info) && info != null;
}
}

View File

@ -68,9 +68,25 @@ namespace Logic.Skill
public override void OnMove(UnitData self, GridData grid, MapData mapData, MoveType moveType, List<Vector2Int> path = null)
{
if (IsTrigger) return;
if (moveType == MoveType.ActiveMove) self.AddActionPoint(ActionPointType.Attack);
if(self.UnitType == UnitType.MoriyaKnight && moveType == MoveType.SkillMove)self.AddActionPoint(ActionPointType.Attack);
TryTriggerMoveBonus(self, moveType);
}
public bool TryTriggerMoveBonus(UnitData self, MoveType moveType)
{
if (self == null || IsTrigger) return false;
if (moveType == MoveType.ActiveMove)
{
self.AddActionPoint(ActionPointType.Attack);
return true;
}
if (self.UnitType == UnitType.MoriyaKnight && moveType == MoveType.SkillMove)
{
self.AddActionPoint(ActionPointType.Attack);
return true;
}
return false;
}
}
}
}

View File

@ -6,6 +6,8 @@
*/
using RuntimeData;
using System.Collections.Generic;
using UnityEngine;
namespace Logic.Skill
{
@ -35,8 +37,28 @@ namespace Logic.Skill
if (targetGrid == null || targetGrid.Terrain != TerrainType.ShallowSea)
return false;
targetFullType = new UnitFullType(UnitType.HakureiKarvi, GiantType.None, 0);
var targetUnitType = IsNonUnionPort(self, mapData, targetGrid)
? UnitType.HakureiLongship
: UnitType.HakureiKarvi;
targetFullType = new UnitFullType(targetUnitType, GiantType.None, 0);
return true;
}
public override void AfterTransformFromBoat(UnitData self, GridData grid, MapData mapData, MoveType moveType,
List<Vector2Int> path = null)
{
if (moveType != MoveType.ActiveMove) return;
if (!self.GetSkill(SkillType.DASH, out var skill) || skill is not DashSkill dashSkill) return;
dashSkill.TryTriggerMoveBonus(self, moveType);
}
private static bool IsNonUnionPort(UnitData self, MapData mapData, GridData targetGrid)
{
if (targetGrid.Resource != ResourceType.Port) return false;
if (self == null || mapData == null) return true;
if (!self.Player(mapData, out var selfPlayer)) return true;
if (!mapData.GetPlayerDataByTerritoryGridId(targetGrid.Id, out var portPlayer)) return true;
return !mapData.SameUnion(selfPlayer.Id, portPlayer.Id);
}
}
}

View File

@ -12,6 +12,7 @@ using MemoryPack;
using RuntimeData;
using UnityEngine;
using Logic.Action;
using TH1_Logic.Action;
using TH1_Logic.Core;
using TH1_Core.Events;
using TH1_Core.Managers;
@ -173,6 +174,8 @@ namespace Logic.Skill
if (!targetCity.GetSkill(SkillType.CITYSTOLEN, out _))
{
int stolenAmount = Main.CityLogic.GetCityCoinPerTurn(mapData, targetCity);
if (targetCity.Player(mapData, out var targetPlayer))
stolenAmount *= PlayerActionDiplomacy.GetDanegeldRaidMultiplier(selfPlayer, targetPlayer);
targetCity.AddSkill_Legacy(SkillType.CITYSTOLEN, mapData,
true, 0, false, -1, false, SpecialAddSkillType.Force, 0);
if (targetCity.GetSkill(SkillType.CITYSTOLEN, out var stolenSkill)

View File

@ -242,6 +242,27 @@ namespace Logic.Skill
targetCityId);
}
public static void EnqueueDanegeldRejectedNotice(
MapData map,
PlayerData refusingPlayer,
uint receiverPlayerId,
int demandedCoinAmount,
uint targetPlayerId = 0,
uint targetCityId = 0)
{
EnqueueHakureiPaymentNotice(
map,
HakureiPaymentNoticeType.DanegeldRejected,
refusingPlayer,
receiverPlayerId,
0,
demandedCoinAmount,
0,
0,
targetPlayerId,
targetCityId);
}
private static void EnqueueHakureiPaymentNotice(
MapData map,
HakureiPaymentNoticeType noticeType,

View File

@ -26,15 +26,14 @@ namespace Logic.Skill
public override void OnAnyUnitDie(MapData map, UnitData self, UnitData dieUnit)
{
if (map == null || self == null || dieUnit == null || self.Id != dieUnit.Id) return;
if (!self.Grid(map, out var grid)) return;
if (!CanLeaveRuneOn(grid)) return;
if (grid.Resource != ResourceType.HakureiRune)
if (self.Player(map, out var player))
{
grid.ResourceUnderBuilding = grid.Resource;
HakureiEinherjarCounter.AddPlayerPoints(map, player, 1);
}
grid.Resource = ResourceType.HakureiRune;
if (!self.Grid(map, out var grid) || !CanLeaveRuneOn(grid)) return;
grid.AddSpType(GridSpType.HakureiRune, map, self);
grid.Renderer(map)?.InstantUpdateGrid(true);
}
@ -43,6 +42,7 @@ namespace Logic.Skill
if (grid == null) return false;
return grid.Terrain == TerrainType.Land
&& grid.Feature != TerrainFeature.Mountain
&& !grid.HasSpType(GridSpType.HakureiRune)
&& grid.Resource is ResourceType.None
or ResourceType.Fruit
or ResourceType.Crop
@ -52,4 +52,113 @@ namespace Logic.Skill
or ResourceType.HakureiRune;
}
}
public partial class HakureiEinherjarPointSkill : SkillBase
{
public HakureiEinherjarPointSkill()
{
IsPermanent = true;
TurnsLimit = 0;
SetIsLevel(true);
SetAutoDisappear(false);
Score = 0;
}
public override SkillType GetSkillType()
{
return SkillType.HakureiEinherjarPoint;
}
}
public partial class HakureiCityEinherjarOfferingSkill : SkillBase
{
public HakureiCityEinherjarOfferingSkill()
{
IsPermanent = true;
TurnsLimit = 0;
SetIsLevel(true);
SetAutoDisappear(false);
Score = 0;
}
public override SkillType GetSkillType()
{
return SkillType.HakureiCityEinherjarOffering;
}
}
public static class HakureiEinherjarCounter
{
public const int CityDevelopmentBaseCost = 5;
public static int GetPlayerPoints(PlayerData player)
{
return GetCounterLevel(player, SkillType.HakureiEinherjarPoint);
}
public static bool HasPlayerPointCounter(PlayerData player)
{
return player != null && player.GetSkill(SkillType.HakureiEinherjarPoint, out _);
}
public static int GetCityOfferingLevel(CityData city)
{
return GetCounterLevel(city, SkillType.HakureiCityEinherjarOffering);
}
public static int GetCityDevelopmentCost(CityData city)
{
return CityDevelopmentBaseCost + GetCityOfferingLevel(city);
}
public static void AddPlayerPoints(MapData map, PlayerData player, int amount)
{
AddCounterLevel(player, map, SkillType.HakureiEinherjarPoint, amount);
}
public static bool TrySpendPlayerPoints(MapData map, PlayerData player, int cost)
{
if (player == null || cost < 0) return false;
var points = GetPlayerPoints(player);
if (points < cost) return false;
SetCounterLevel(player, map, SkillType.HakureiEinherjarPoint, points - cost);
return true;
}
public static void AddCityOfferingLevel(MapData map, CityData city, int amount)
{
AddCounterLevel(city, map, SkillType.HakureiCityEinherjarOffering, amount);
}
private static int GetCounterLevel(IdentifierBase owner, SkillType skillType)
{
if (owner == null) return 0;
return owner.GetSkill(skillType, out var skill) ? skill.Level : 0;
}
private static void AddCounterLevel(IdentifierBase owner, MapData map, SkillType skillType, int amount)
{
if (owner == null || amount == 0) return;
var level = GetCounterLevel(owner, skillType) + amount;
SetCounterLevel(owner, map, skillType, level);
}
private static void SetCounterLevel(IdentifierBase owner, MapData map, SkillType skillType, int level)
{
if (owner == null) return;
level = level < 0 ? 0 : level;
if (!owner.GetSkill(skillType, out var skill))
{
if (level == 0) return;
skill = SkillFactory.GetSkillBySkillType(skillType);
if (skill == null) return;
owner.AddOrOverrideSkill(skill, map, 0);
}
skill.SetPermanent(true);
skill.SetIsLevel(true);
skill.SetAutoDisappear(false);
skill.SetLevel(level);
}
}
}

View File

@ -0,0 +1,12 @@
// Auto-generated HakureiCityEinherjarOfferingSkill partial class with MemoryPackable attribute
// 此文件由 MemoryPackUnionGenerator 自动生成,请勿手动修改
using MemoryPack;
namespace Logic.Skill
{
[MemoryPackable]
public partial class HakureiCityEinherjarOfferingSkill
{
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 74cea7f9a6f547f9a34ad77975dd70b1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,12 @@
// Auto-generated HakureiEinherjarPointSkill partial class with MemoryPackable attribute
// 此文件由 MemoryPackUnionGenerator 自动生成,请勿手动修改
using MemoryPack;
namespace Logic.Skill
{
[MemoryPackable]
public partial class HakureiEinherjarPointSkill
{
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: af946f4688a64b14b918bc8b9b04d133
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -305,6 +305,8 @@ namespace Logic.Skill
[MemoryPackUnion(297, typeof(HakureiRoundShieldWallSkill))]
[MemoryPackUnion(298, typeof(HakureiKarviEmbarkSkill))]
[MemoryPackUnion(299, typeof(ValhallaOathSkill))]
[MemoryPackUnion(300, typeof(HakureiEinherjarPointSkill))]
[MemoryPackUnion(301, typeof(HakureiCityEinherjarOfferingSkill))]
public abstract partial class SkillBase
{
}

View File

@ -349,6 +349,8 @@ public enum SkillType
HakureiRoundShieldWall = 308,
HakureiKarviEmbark = 309,
ValhallaOath = 310,
HakureiEinherjarPoint = 311,
HakureiCityEinherjarOffering = 312,
//补充之前的bug问题
Max = 999,
}
@ -411,6 +413,9 @@ namespace Logic.Skill
// 事件触发生命周期 (事件已发生)
public void OnMove(UnitData self, GridData grid, MapData mapData, MoveType moveType, List<Vector2Int> path = null);
public void AfterTransformFromBoat(UnitData self, GridData grid, MapData mapData, MoveType moveType,
List<Vector2Int> path = null);
public void OnBeInteractTarget(UnitData origin, UnitData self, GridData grid, MapData mapData);
public bool ActiveMoveFailed(UnitData self, GridData grid, MapData mapData, MoveType moveType,
@ -956,6 +961,12 @@ namespace Logic.Skill
}
public virtual void AfterTransformFromBoat(UnitData self, GridData grid, MapData mapData, MoveType moveType,
List<Vector2Int> path = null)
{
}
public virtual void OnBeInteractTarget(UnitData origin, UnitData self, GridData grid, MapData mapData)
{

View File

@ -246,7 +246,7 @@ namespace Logic
{
//注意必须先Onmove变身之前的技能用掉再变身)
unitData.OnMove(mapData, gridData, moveType, path);
BoatToLand(mapData, unitData);
BoatToLand(mapData, unitData, moveType, path);
}
@ -950,7 +950,7 @@ namespace Logic
{
if (targetGridData.Resource == ResourceType.Bridge)
MovementCostMap[i, j] = 1;
else if (CanHakureiKarviEmbark(unitData, targetGridData))
else if (CanHakureiShallowSeaEmbark(unitData, targetGridData))
MovementCostMap[i, j] = 999;
//如果是port要判断是盟军的port 还是其他的port
else if (targetGridData.Resource == ResourceType.Port)
@ -1019,7 +1019,7 @@ namespace Logic
{
if (targetGridData.Resource == ResourceType.Bridge)
MovementCostMap[i, j] = 1;
else if (CanHakureiKarviEmbark(unitData, targetGridData))
else if (CanHakureiShallowSeaEmbark(unitData, targetGridData))
MovementCostMap[i, j] = 999;
else
MovementCostMap[i, j] = -1;
@ -1831,10 +1831,10 @@ namespace Logic
{
if (unitData == null || gridData == null) return false;
if (unitData.GetLandType() == LandType.LandAndPort && gridData.Resource == ResourceType.Port) return true;
return CanHakureiKarviEmbark(unitData, gridData);
return CanHakureiShallowSeaEmbark(unitData, gridData);
}
private static bool CanHakureiKarviEmbark(UnitData unitData, GridData gridData)
private static bool CanHakureiShallowSeaEmbark(UnitData unitData, GridData gridData)
{
if (unitData == null || gridData == null) return false;
if (gridData.Terrain != TerrainType.ShallowSea) return false;
@ -1845,9 +1845,16 @@ namespace Logic
//unit[uid]从港口进入陆地,变为原来的单位
public void BoatToLand(MapData mapData, UnitData unitData)
{
BoatToLand(mapData, unitData, MoveType.PassiveMove);
}
public void BoatToLand(MapData mapData, UnitData unitData, MoveType moveType, List<Vector2Int> path = null)
{
Main.UnitLogic.UnitTypeTransform(mapData,unitData, unitData.CarryUnitType, unitData.CarryGiantType,unitData.CarryUnitLevel);
unitData.ActionPoint.Clear();
unitData.Grid(mapData, out var gridData);
unitData.AfterTransformFromBoat(mapData, gridData, moveType, path);
unitData.CarryUnitFullType = new UnitFullType();
}

View File

@ -646,7 +646,8 @@ namespace TH1Renderer
if (_gridData.HasSpType(GridSpType.LeyLine)
&& !_gridData.HasSpType(GridSpType.RemiliaGrid)
&& !_gridData.HasSpType(GridSpType.KaguyaGrid))
&& !_gridData.HasSpType(GridSpType.KaguyaGrid)
&& !_gridData.HasSpType(GridSpType.HakureiRune))
{
var selfPlayer = Main.MapData.PlayerMap.SelfPlayerData;
if (selfPlayer.CivEnum != CivEnum.Indian)

View File

@ -77,7 +77,7 @@ namespace TH1_UI.Controller.Interaction
if (!Main.MapData.PlayerMap.GetPlayerDataByPlayerID(_evt.PlayerId, out var targetPlayer)) return;
ActionLogicFactory.GetActionLogic(new CommonActionId()
{ ActionType = CommonActionType.PlayerAction, PlayerActionType = PlayerActionType.AcceptAlly })
{ ActionType = CommonActionType.PlayerAction, PlayerActionType = GetYesActionType() })
.CompleteExecute(new CommonActionParams(mapData: Main.MapData,
playerData: Main.MapData.PlayerMap.SelfPlayerData, targetPlayer: targetPlayer, mainObjectType: MainObjectType.Player));
@ -93,12 +93,26 @@ namespace TH1_UI.Controller.Interaction
if (!Main.MapData.PlayerMap.GetPlayerDataByPlayerID(_evt.PlayerId, out var targetPlayer)) return;
ActionLogicFactory.GetActionLogic(new CommonActionId()
{ ActionType = CommonActionType.PlayerAction, PlayerActionType = PlayerActionType.RefuseAlly })
{ ActionType = CommonActionType.PlayerAction, PlayerActionType = GetNoActionType() })
.CompleteExecute(new CommonActionParams(mapData : Main.MapData,playerData: Main.MapData.PlayerMap.SelfPlayerData,targetPlayer: targetPlayer,mainObjectType : MainObjectType.Player));
}
Close();
}
private PlayerActionType GetYesActionType()
{
return _evt.PlayerActionType == PlayerActionType.DanegeldDemand
? PlayerActionType.DanegeldPay
: PlayerActionType.AcceptAlly;
}
private PlayerActionType GetNoActionType()
{
return _evt.PlayerActionType == PlayerActionType.DanegeldDemand
? PlayerActionType.DanegeldReject
: PlayerActionType.RefuseAlly;
}
}
}
}

View File

@ -99,6 +99,19 @@ namespace TH1_UI.View.Announce
GetTargetDisplayName(map, evt)
});
return true;
case HakureiPaymentNoticeType.DanegeldRejected:
DiplomacyState.color = UnacceptColor;
MultilingualManager.Instance.SetUIText(Title,
Table.Instance.TextDataAssets.PresentationUIHakureiDanegeldRejectedTitle);
MultilingualManager.Instance.SetUIText(Content,
Table.Instance.TextDataAssets.PresentationUIHakureiDanegeldRejectedContent,
new List<string>
{
Logic.PlayerLogic.GetDisplayForceName(map, payer),
evt.CoinAmount.ToString(),
GetTargetDisplayName(map, evt)
});
return true;
default:
return false;
}

View File

@ -6,6 +6,7 @@ using Logic.Action;
using Logic.Audio;
using Logic.CrashSight;
using Logic.Multilingual;
using Logic.Skill;
using RuntimeData;
using TH1_Core.Events;
using TH1_Logic.Core;
@ -42,6 +43,9 @@ namespace TH1_UI.View.Info
public TextMeshProUGUI ForceName;
public GameObject MountainPoint;
public TextMeshProUGUI MountainCount;
public GameObject VikingPoint;
public TextMeshProUGUI VikingCount;
private int _lastVikingPoint = int.MinValue;
[Header("TreeCircle相关")]
public List< TechTreeCirclePair > TechTreeCircleMonoList;

View File

@ -57,8 +57,19 @@ namespace TH1_UI.View.Interaction
if (!Main.MapData.PlayerMap.GetPlayerDataByPlayerID(evt.PlayerId, out var player2)) return;
if(!Table.Instance.PlayerDataAssets.GetPlayerInfo(player2,out var info2)) return;
var forceName = Logic.PlayerLogic.GetDisplayForceName(Main.MapData, player2);
MultilingualManager.Instance.SetUIText(Title,Table.Instance.DiplomacyDataAssets.DiplomacyUIAnnounceOfferAllyTitle);
MultilingualManager.Instance.SetUIText(Content,Table.Instance.DiplomacyDataAssets.DiplomacyUIAnnounceOfferAlly,new List<string>(){forceName});
if (evt.PlayerActionType == PlayerActionType.DanegeldDemand)
{
SetDanegeldText(forceName);
SetButtonText(YesButton, PlayerActionType.DanegeldPay);
SetButtonText(NoButton, PlayerActionType.DanegeldReject);
}
else
{
MultilingualManager.Instance.SetUIText(Title,Table.Instance.DiplomacyDataAssets.DiplomacyUIAnnounceOfferAllyTitle);
MultilingualManager.Instance.SetUIText(Content,Table.Instance.DiplomacyDataAssets.DiplomacyUIAnnounceOfferAlly,new List<string>(){forceName});
SetButtonText(YesButton, PlayerActionType.AcceptAlly);
SetButtonText(NoButton, PlayerActionType.RefuseAlly);
}
//Step #3 设置Avatar和bubble chat
Avatar1.sprite = info1.LeaderAvatar;
@ -66,7 +77,10 @@ namespace TH1_UI.View.Interaction
Logic.PlayerLogic.GetDisplayForceName(Main.MapData, player1) + " (" + MultilingualManager.Instance.GetMultilingualTextSafe(Table.Instance.TextDataAssets.PresentationUIDiplomacyYouText) +")";
Avatar2.sprite = info2.LeaderAvatar;
AvatarTextRight.text = Logic.PlayerLogic.GetDisplayForceName(Main.MapData, player2);
var offerChatText = Table.Instance.DiplomacyDataAssets.GetDiplomacyTextByAction((Forces)(player2.PlayerForceId),PlayerActionType.OfferAlly);
var chatActionType = evt.PlayerActionType == PlayerActionType.DanegeldDemand
? PlayerActionType.DanegeldDemand
: PlayerActionType.OfferAlly;
var offerChatText = Table.Instance.DiplomacyDataAssets.GetDiplomacyTextByAction((Forces)(player2.PlayerForceId), chatActionType);
if (string.IsNullOrEmpty(offerChatText))
{
BubbleChat.gameObject.SetActive(false);
@ -79,6 +93,39 @@ namespace TH1_UI.View.Interaction
}
}
private void SetDanegeldText(string forceName)
{
var actionId = new CommonActionId
{
ActionType = CommonActionType.PlayerAction,
PlayerActionType = PlayerActionType.DanegeldDemand
};
if (Table.Instance.ActionDataAssets.GetActionInfo(actionId, out var actionInfo) && actionInfo != null)
{
MultilingualManager.Instance.SetUIText(Title, actionInfo.ActionName);
MultilingualManager.Instance.SetUIText(Content, actionInfo.Desc, new List<string>() { forceName });
return;
}
MultilingualManager.Instance.SetUIText(Title, Table.Instance.TextDataAssets.PresentationUIHakureiDanegeldPaymentTitle);
MultilingualManager.Instance.SetUIText(Content, Table.Instance.TextDataAssets.PresentationUIHakureiDanegeldPaymentContent,
new List<string>() { forceName });
}
private void SetButtonText(Button button, PlayerActionType playerActionType)
{
if (button == null) return;
var label = button.GetComponentInChildren<TextMeshProUGUI>();
if (label == null) return;
var actionId = new CommonActionId
{
ActionType = CommonActionType.PlayerAction,
PlayerActionType = playerActionType
};
if (Table.Instance.ActionDataAssets.GetActionInfo(actionId, out var actionInfo) && actionInfo != null)
MultilingualManager.Instance.SetUIText(label, actionInfo.ActionName);
}

View File

@ -58,11 +58,11 @@ namespace TH1_UI.View.Outside
WonderAvatar.gameObject.SetActive(false);
HeroAvatar.sprite = info.Illust;
SetUITextOrRaw(Name,info.Name);
var hasAchievement = AchievementDataManager.Instance.GetSmallIdByGiantType(giantType, out var smallid);
for (uint k = 1;k <= 3;k++)
{
if (!AchievementDataManager.Instance.GetSmallIdByGiantType(giantType, out var smallid)) continue;
bool isFinished = AchievementDataManager.Instance.IsFinished(2, smallid, k);
if(Stars.Count < k)continue;
bool isFinished = hasAchievement && AchievementDataManager.Instance.IsFinished(2, smallid, k);
Stars[(int)k - 1].sprite = isFinished ? StarImg : StarImgGray;
}
@ -80,11 +80,11 @@ namespace TH1_UI.View.Outside
WonderAvatar.gameObject.SetActive(true);
WonderAvatar.sprite = wonderInfo.Sprite;
MultilingualManager.Instance.SetUIText(Name,wonderInfo.Name);
var hasAchievement = AchievementDataManager.Instance.GetSmallIdByWonderAndEmpire(empire,wonderType, out var smallid);
for (uint k = 1;k <= 3;k++)
{
if (!AchievementDataManager.Instance.GetSmallIdByWonderAndEmpire(empire,wonderType, out var smallid)) continue;
bool isFinished = AchievementDataManager.Instance.IsFinished(3, smallid, k);
if(Stars.Count < k)continue;
bool isFinished = hasAchievement && AchievementDataManager.Instance.IsFinished(3, smallid, k);
Stars[(int)k - 1].sprite = isFinished ? StarImg : StarImgGray;
}

View File

@ -98,9 +98,18 @@ namespace TH1_UI.View.Outside
private void SetAchieveItems(GiantType giantType)
{
if (AchieveItems.Count != 3) return;
if (!AchievementDataManager.Instance.GetSmallIdByGiantType(giantType, out var smallid))
{
for (int i = 0; i < AchieveItems.Count; i++)
AchieveItems[i].gameObject.SetActive(false);
return;
}
for (int i = 0; i < 3; i++)
if(AchievementDataManager.Instance.GetSmallIdByGiantType(giantType,out var smallid))
AchieveItems[i].SetContent(2,smallid,(uint)i + 1);
{
AchieveItems[i].gameObject.SetActive(true);
AchieveItems[i].SetContent(2,smallid,(uint)i + 1);
}
}
public void Show()
{

View File

@ -82,19 +82,23 @@ namespace TH1_UI.View.Outside
//所有参与图鉴的herolist
private readonly List<GiantType> _heroTypeList = new List<GiantType>
private static readonly List<GiantType> AllLibraryHeroTypes = new List<GiantType>
{
GiantType.EgyptianRemilia,GiantType.EgyptianPatchouli,GiantType.EgyptianSakuya,GiantType.EgyptianFlandre,GiantType.EgyptianMeiling,
GiantType.FrenchKaguya,GiantType.FrenchEirin,GiantType.FrenchTewi,GiantType.FrenchReisen,GiantType.FrenchMokou,
GiantType.GermanyKanako,GiantType.GermanySuwako,GiantType.GermanySanae,GiantType.GermanyAya,GiantType.GermanyMomiji,
GiantType.IndianSatori,GiantType.IndianKoishi,GiantType.IndianRin,GiantType.IndianUtsuho,GiantType.IndianYuugi
GiantType.IndianSatori,GiantType.IndianKoishi,GiantType.IndianRin,GiantType.IndianUtsuho,GiantType.IndianYuugi,
GiantType.NorwayReimu,GiantType.NorwaySumireko,GiantType.NorwayKasen,GiantType.NorwayAunn,GiantType.NorwaySuika
};
private readonly List<GiantType> _heroTypeList = new List<GiantType>();
//所有参与图鉴的civlist
private readonly List<Empire> _empireList = new List<Empire>
private static readonly List<Empire> AllLibraryEmpires = new List<Empire>
{
new Empire(CivEnum.Egyptian,ForceEnum.Remilia), new Empire(CivEnum.French,ForceEnum.Kaguya),new Empire(CivEnum.Germany,ForceEnum.Kanako),new Empire(CivEnum.Indian,ForceEnum.Satori)
new Empire(CivEnum.Egyptian,ForceEnum.Remilia), new Empire(CivEnum.French,ForceEnum.Kaguya),new Empire(CivEnum.Germany,ForceEnum.Kanako),new Empire(CivEnum.Indian,ForceEnum.Satori),
new Empire(CivEnum.Norway,ForceEnum.Reimu)
};
private readonly List<Empire> _empireList = new List<Empire>();
//关闭时执行的委托
@ -155,6 +159,7 @@ namespace TH1_UI.View.Outside
private void InitHeroList()
{
RebuildLibraryContentLists();
//Step #1 判断容器是否够
int heroSum = _heroTypeList.Count;
while (_heroMonoList.Count < heroSum)
@ -181,6 +186,7 @@ namespace TH1_UI.View.Outside
private void InitWonderList()
{
RebuildLibraryContentLists();
//Step #1 判断容器是否够
int wonderSum = _empireList.Count * 7 ;
while (_wonderMonoList.Count < wonderSum)
@ -207,6 +213,37 @@ namespace TH1_UI.View.Outside
WonderPanel.Show();
}
private void RebuildLibraryContentLists()
{
_heroTypeList.Clear();
foreach (var giantType in AllLibraryHeroTypes)
{
if (!ContentGate.CanUseHero(giantType)) continue;
if (!Table.Instance.LibraryDataAssets.GetLibraryInfoByGiant(giantType, out _)) continue;
_heroTypeList.Add(giantType);
}
_empireList.Clear();
foreach (var empire in AllLibraryEmpires)
{
if (!ContentGate.CanUseEmpire(empire)) continue;
if (!HasAllLibraryWonders(empire)) continue;
_empireList.Add(empire);
}
}
private bool HasAllLibraryWonders(Empire empire)
{
foreach (WonderTypeEnum wonderType in Enum.GetValues(typeof(WonderTypeEnum)))
{
if (wonderType == WonderTypeEnum.None) continue;
if (!Table.Instance.LibraryDataAssets.GetLibraryInfoByWonder(empire, wonderType, out _))
return false;
}
return true;
}
private void InitMusicList()
{
if (MusicItemPrefab == null || MusicListContent == null) return;

View File

@ -61,9 +61,18 @@ namespace TH1_UI.View.Outside
private void SetAchieveItems(Empire empire ,WonderTypeEnum wonderType)
{
if (AchieveItems.Count != 3) return;
if (!AchievementDataManager.Instance.GetSmallIdByWonderAndEmpire(empire ,wonderType,out var smallid))
{
for (int i = 0; i < AchieveItems.Count; i++)
AchieveItems[i].gameObject.SetActive(false);
return;
}
for (int i = 0; i < 3; i++)
if(AchievementDataManager.Instance.GetSmallIdByWonderAndEmpire(empire ,wonderType,out var smallid))
AchieveItems[i].SetContent(3,smallid,(uint)i + 1);
{
AchieveItems[i].gameObject.SetActive(true);
AchieveItems[i].SetContent(3,smallid,(uint)i + 1);
}
}
public void Show()
@ -91,4 +100,4 @@ namespace TH1_UI.View.Outside
}
}
}
}

View File

@ -174,6 +174,7 @@ namespace TH1_UI.View.Outside
(CivEnum.French, ForceEnum.Kaguya),
(CivEnum.Germany, ForceEnum.Kanako),
(CivEnum.Indian, ForceEnum.Satori),
(CivEnum.Norway, ForceEnum.Reimu),
};
[Serializable]
@ -906,16 +907,17 @@ namespace TH1_UI.View.Outside
private bool ClampSlotToRoomForceOptions(MemberCiv mc)
{
if (mc == null || RoomForceOptions.Length == 0) return false;
var options = GetAvailableRoomForceOptions();
if (mc == null || options.Count == 0) return false;
var civ = Table.Instance.TransCivIdToCivEnum(mc.CivId);
var force = Table.Instance.TransForceIdToForceEnum(mc.ForceId);
foreach (var option in RoomForceOptions)
foreach (var option in options)
{
if (option.Civ == civ && option.Force == force) return false;
}
var optionIndex = (int)(mc.CivId % (uint)RoomForceOptions.Length);
var roomForce = RoomForceOptions[optionIndex];
var optionIndex = (int)(mc.CivId % (uint)options.Count);
var roomForce = options[optionIndex];
var civId = Table.Instance.TransCivEnumToCivId(roomForce.Civ);
var forceId = Table.Instance.TransForceEnumToForceId(roomForce.Force);
var changed = mc.CivId != civId || mc.ForceId != forceId || !mc.IsCivFixed;
@ -956,14 +958,15 @@ namespace TH1_UI.View.Outside
private uint PickDefaultCivId(int preferredIndex, HashSet<uint> usedCivs)
{
const int defaultCivCount = 17;
for (int offset = 0; offset < defaultCivCount; offset++)
var options = GetAvailableRoomForceOptions();
for (int offset = 0; offset < options.Count; offset++)
{
var civId = (uint)((preferredIndex + offset) % defaultCivCount);
var option = options[(preferredIndex + offset) % options.Count];
var civId = Table.Instance.TransCivEnumToCivId(option.Civ);
if (!usedCivs.Contains(civId)) return civId;
}
return (uint)preferredIndex;
return Table.Instance.TransCivEnumToCivId(options[preferredIndex % options.Count].Civ);
}
private void OnHumanRowForceChanged(int slotIndex, int direction)
@ -1071,7 +1074,7 @@ namespace TH1_UI.View.Outside
private (CivEnum Civ, ForceEnum Force) GetNextForce(uint civId, uint forceId, int direction)
{
return GetNextForce(civId, forceId, direction, RoomForceOptions);
return GetNextForce(civId, forceId, direction, GetAvailableRoomForceOptions());
}
private (CivEnum Civ, ForceEnum Force) GetNextAIForce(uint civId, uint forceId, int direction)
@ -1086,12 +1089,25 @@ namespace TH1_UI.View.Outside
var civ = Table.Instance.TransCivIdToCivEnum(info.CivId);
var force = Table.Instance.TransForceIdToForceEnum(info.ForceId);
if (civ == CivEnum.Common || force == ForceEnum.Common) continue;
if (!ContentGate.CanUseEmpire(new Empire(civ, force))) continue;
options.Add((civ, force));
}
return options.Count > 0 ? GetNextForce(civId, forceId, direction, options) : GetNextForce(civId, forceId, direction);
}
private static IReadOnlyList<(CivEnum Civ, ForceEnum Force)> GetAvailableRoomForceOptions()
{
var options = new List<(CivEnum Civ, ForceEnum Force)>();
foreach (var option in RoomForceOptions)
{
if (ContentGate.CanUseEmpire(new Empire(option.Civ, option.Force))) options.Add(option);
}
if (options.Count == 0) options.Add((CivEnum.Egyptian, ForceEnum.Remilia));
return options;
}
private (CivEnum Civ, ForceEnum Force) GetNextForce(uint civId, uint forceId, int direction, IReadOnlyList<(CivEnum Civ, ForceEnum Force)> options)
{
var civ = Table.Instance.TransCivIdToCivEnum(civId);

View File

@ -547,12 +547,21 @@ public class UIOutsideSelectCheckPanelMono : MonoBehaviour
var civ = Table.Instance.TransCivIdToCivEnum(info.CivId);
var force = Table.Instance.TransForceIdToForceEnum(info.ForceId);
if (civ == CivEnum.Common || force == ForceEnum.Common) continue;
if (!ContentGate.CanUseEmpire(new Empire(civ, force))) continue;
if (!optionSet.Add((civ, force))) continue;
options.Add((civ, force));
}
}
return options.Count > 0 ? options : FallbackForceOptions;
if (options.Count > 0) return options;
foreach (var fallback in FallbackForceOptions)
{
if (ContentGate.CanUseEmpire(new Empire(fallback.Civ, fallback.Force))) options.Add(fallback);
}
if (options.Count == 0) options.Add((CivEnum.Egyptian, ForceEnum.Remilia));
return options;
}
private bool IsValidPlayerOption(uint civId, uint forceId)
@ -560,6 +569,7 @@ public class UIOutsideSelectCheckPanelMono : MonoBehaviour
var civ = Table.Instance.TransCivIdToCivEnum(civId);
var force = Table.Instance.TransForceIdToForceEnum(forceId);
if (civ == CivEnum.Common || force == ForceEnum.Common) return false;
if (!ContentGate.CanUseEmpire(new Empire(civ, force))) return false;
return Table.Instance.PlayerDataAssets.GetPlayerInfo(civ, force, out _);
}
@ -607,7 +617,8 @@ public class UIOutsideSelectCheckPanelMono : MonoBehaviour
private Empire GetCurrentPlayerEmpire()
{
if (_playerEmpire.Civ != CivEnum.Common && _playerEmpire.Force != ForceEnum.Common)
if (_playerEmpire.Civ != CivEnum.Common && _playerEmpire.Force != ForceEnum.Common
&& ContentGate.CanUseEmpire(_playerEmpire))
return _playerEmpire;
var selfSlot = GetExistingPlayerSlot(0);
@ -615,10 +626,13 @@ public class UIOutsideSelectCheckPanelMono : MonoBehaviour
{
var civ = Table.Instance.TransCivIdToCivEnum(selfSlot.CivId);
var force = Table.Instance.TransForceIdToForceEnum(selfSlot.ForceId);
if (civ != CivEnum.Common && force != ForceEnum.Common) return new Empire(civ, force);
var empire = new Empire(civ, force);
if (civ != CivEnum.Common && force != ForceEnum.Common && ContentGate.CanUseEmpire(empire)) return empire;
}
return new Empire(CivEnum.Egyptian, ForceEnum.Remilia);
var options = GetAIForceOptions();
var fallback = options[0];
return new Empire(fallback.Civ, fallback.Force);
}
private (uint CivId, uint ForceId) PickDefaultPlayerOption(int preferredIndex, HashSet<(uint CivId, uint ForceId)> usedPlayerOptions)

View File

@ -95,6 +95,7 @@ namespace TH1_UI.View.Outside
_monoList = new List<UIOutsideSelectAvatarMono>();
foreach (var t in CivForceList)
{
if (!ContentGate.CanUseEmpire(t)) continue;
// TODO: 暂时屏蔽第四阵营Indian/Satori待正式上线后移除此判断
//if (t.Civ == CivEnum.Indian) continue;
@ -124,6 +125,7 @@ namespace TH1_UI.View.Outside
private void OnAvatarClicked(Empire playerEmpire)
{
if (!ContentGate.CanUseEmpire(playerEmpire)) return;
_selectRandom = false;
foreach(var t in _monoList)
if(t.PlayerEmpire != playerEmpire)
@ -174,7 +176,8 @@ namespace TH1_UI.View.Outside
// If no last selection found or not available, default to first
if (targetMono == null)
{
targetMono = _monoList[0];
targetMono = GetFirstSelectableAvatar();
if (targetMono == null) return;
}
targetMono.Button.onClick.Invoke();
@ -183,6 +186,7 @@ namespace TH1_UI.View.Outside
public void SetCivForceInfo(Empire playerEmpire)
{
if (!ContentGate.CanUseEmpire(playerEmpire)) return;
_selectRandom = false;
_selectEmpire = playerEmpire;
SelectCheckPanelMono?.SetPlayerEmpire(playerEmpire);
@ -273,6 +277,12 @@ namespace TH1_UI.View.Outside
{
ApplyRandomSelectedEmpire();
}
if (!ContentGate.CanUseEmpire(_selectEmpire))
{
var targetMono = GetFirstSelectableAvatar();
if (targetMono == null) return;
SetCivForceInfo(targetMono.PlayerEmpire);
}
GameMode gameMode = SelectCheckPanelMono.GameMode.SelectedIndex switch
{
@ -430,6 +440,17 @@ namespace TH1_UI.View.Outside
SetCivForceInfo(candidates[index]);
}
private UIOutsideSelectAvatarMono GetFirstSelectableAvatar()
{
foreach (var mono in _monoList)
{
if (mono == null || mono.IsRandom) continue;
if (ContentGate.CanUseEmpire(mono.PlayerEmpire)) return mono;
}
return null;
}
private void SetRandomPanelVisible(bool visible, bool immediate = false)
{
if (RandomPanel == null) return;
@ -511,7 +532,8 @@ namespace TH1_UI.View.Outside
if (!Enum.IsDefined(typeof(CivEnum), civValue) || !Enum.IsDefined(typeof(ForceEnum), forceValue))
return null;
return new Empire((CivEnum)civValue, (ForceEnum)forceValue);
var empire = new Empire((CivEnum)civValue, (ForceEnum)forceValue);
return ContentGate.CanUseEmpire(empire) ? empire : null;
}
public void CloseView()

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB