diff --git a/.gitignore b/.gitignore
index 6e3801a8..cb689c16 100644
--- a/.gitignore
+++ b/.gitignore
@@ -34,3 +34,6 @@ Source/MCP/pid.txt
*.log
MCP/vector_cache/*.txt
MCP/mcpserver.log
+
+# Exclude MCP local RAG folder
+MCP/local_rag/
diff --git a/.lingma/rules/rimworld.md b/.lingma/rules/rimworld.md
new file mode 100644
index 00000000..b48fcd64
--- /dev/null
+++ b/.lingma/rules/rimworld.md
@@ -0,0 +1,29 @@
+---
+trigger: always_on
+---
+
+# RimWorld Modding Expert Rules
+
+## Primary Directive
+You are an expert assistant for developing mods for the game RimWorld 1.6. Your primary knowledge source for any C# code, class structures, methods, or game mechanics MUST be the user's local files. Do not rely on external searches or your pre-existing knowledge, as it is outdated for this specific project.
+
+## Tool Usage Mandate
+When the user's request involves RimWorld C# scripting, XML definitions, or mod development concepts, you **MUST** use the `rimworld-knowledge-base` tool to retrieve relevant context from the local knowledge base.
+
+## Key File Paths
+Always remember these critical paths for your work:
+
+- **Local C# Knowledge Base (for code search):** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6` (This contains the decompiled game source code as .txt files).
+- **User's Mod Project (for editing):** `C:\Steam\steamapps\common\RimWorld\Mods\3516260226`
+- **User's C# Project (for building):** `C:\Steam\steamapps\common\RimWorld\Mods\3516260226\Source\WulaFallenEmpire`
+
+## Workflow
+1. Receive a RimWorld modding task.
+2. Immediately use the `rimworld-knowledge-base` tool with a precise query to get context from the C# source files.
+3. Analyze the retrieved context.
+4. Perform code modifications within the user's mod project directory.
+5. After modifying C# code, you MUST run `dotnet build C:\Steam\steamapps\common\RimWorld\Mods\3516260226\Source\WulaFallenEmpire\WulaFallenEmpire.csproj` to check for errors. A successful build is required for task completion.
+
+## Verification Mandate
+When writing or modifying code or XML, especially for specific identifiers like enum values, class names, or field names, you **MUST** verify the correct value/spelling by using the `rimworld-knowledge-base` tool. Do not rely on memory.
+- **同步项目文件:** 当重命名、移动或删除C#源文件时,**必须**同步更新 `.csproj` 项目文件中的相应 `` 条目,否则会导致编译失败。
\ No newline at end of file
diff --git a/MCP/mcpserver_stdio.py b/MCP/mcpserver_stdio.py
index b70e789a..d814dd90 100644
--- a/MCP/mcpserver_stdio.py
+++ b/MCP/mcpserver_stdio.py
@@ -20,6 +20,7 @@ from tenacity import retry, stop_after_attempt, wait_random_exponential
from sklearn.metrics.pairwise import cosine_similarity
import numpy as np
from dotenv import load_dotenv
+from openai import OpenAI
# 2. --- 日志、缓存和知识库配置 ---
MCP_DIR = os.path.dirname(os.path.abspath(__file__))
@@ -51,32 +52,98 @@ KNOWLEDGE_BASE_PATHS = [
r"C:\Steam\steamapps\common\RimWorld\Data"
]
-# 3. --- 缓存管理 (分文件存储) ---
-def load_cache_for_keyword(keyword: str):
- """为指定关键词加载缓存文件。"""
- # 清理关键词,使其适合作为文件名
- safe_filename = "".join(c for c in keyword if c.isalnum() or c in ('_', '-')).rstrip()
- cache_file = os.path.join(CACHE_DIR, f"{safe_filename}.txt")
-
- if os.path.exists(cache_file):
+# 初始化OpenAI客户端用于Qwen模型
+qwen_client = OpenAI(
+ api_key=os.getenv("DASHSCOPE_API_KEY"),
+ base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
+)
+
+# 3. --- 向量缓存管理 ---
+def load_vector_cache():
+ """加载向量缓存数据库"""
+ if os.path.exists(CACHE_FILE_PATH):
try:
- with open(cache_file, 'r', encoding='utf-8') as f:
- return f.read()
- except IOError as e:
- logging.error(f"读取缓存文件 {cache_file} 失败: {e}")
- return None
+ with open(CACHE_FILE_PATH, 'r', encoding='utf-8') as f:
+ return json.load(f)
+ except Exception as e:
+ logging.error(f"读取向量缓存数据库失败: {e}")
+ return {}
+ return {}
+
+def save_vector_cache(cache_data):
+ """保存向量缓存数据库"""
+ try:
+ with open(CACHE_FILE_PATH, 'w', encoding='utf-8') as f:
+ json.dump(cache_data, f, ensure_ascii=False, indent=2)
+ except Exception as e:
+ logging.error(f"保存向量缓存数据库失败: {e}")
+
+def get_cache_key(keywords: list[str]) -> str:
+ """生成缓存键"""
+ return "-".join(sorted(keywords))
+
+def load_cache_for_question(question: str, keywords: list[str]):
+ """为指定问题和关键词加载缓存结果"""
+ cache_data = load_vector_cache()
+ cache_key = get_cache_key(keywords)
+
+ # 检查是否有完全匹配的缓存
+ if cache_key in cache_data:
+ cached_entry = cache_data[cache_key]
+ logging.info(f"缓存命中: 关键词 '{cache_key}'")
+ return cached_entry.get("result", "")
+
+ # 检查是否有相似问题的缓存(基于向量相似度)
+ question_embedding = get_embedding(question)
+ if not question_embedding:
+ return None
+
+ best_similarity = 0
+ best_result = None
+
+ for key, entry in cache_data.items():
+ if "embedding" in entry:
+ try:
+ cached_embedding = entry["embedding"]
+ similarity = cosine_similarity(
+ np.array(question_embedding).reshape(1, -1),
+ np.array(cached_embedding).reshape(1, -1)
+ )[0][0]
+
+ if similarity > best_similarity and similarity > 0.9: # 相似度阈值
+ best_similarity = similarity
+ best_result = entry.get("result", "")
+ except Exception as e:
+ logging.error(f"计算缓存相似度时出错: {e}")
+
+ if best_result:
+ logging.info(f"相似问题缓存命中,相似度: {best_similarity:.3f}")
+ return best_result
+
return None
-def save_cache_for_keyword(keyword: str, data: str):
- """为指定关键词保存缓存到单独的文件。"""
- safe_filename = "".join(c for c in keyword if c.isalnum() or c in ('_', '-')).rstrip()
- cache_file = os.path.join(CACHE_DIR, f"{safe_filename}.txt")
-
+def save_cache_for_question(question: str, keywords: list[str], result: str):
+ """为指定问题和关键词保存缓存结果"""
try:
- with open(cache_file, 'w', encoding='utf-8') as f:
- f.write(data)
- except IOError as e:
- logging.error(f"写入缓存文件 {cache_file} 失败: {e}")
+ cache_data = load_vector_cache()
+ cache_key = get_cache_key(keywords)
+
+ # 获取问题的向量嵌入
+ question_embedding = get_embedding(question)
+ if not question_embedding:
+ return
+
+ cache_data[cache_key] = {
+ "keywords": keywords,
+ "question": question,
+ "embedding": question_embedding,
+ "result": result,
+ "timestamp": logging.Formatter('%(asctime)s').format(logging.LogRecord('', 0, '', 0, '', (), None))
+ }
+
+ save_vector_cache(cache_data)
+ except Exception as e:
+ logging.error(f"保存缓存时出错: {e}")
# 4. --- 向量化与相似度计算 ---
@retry(wait=wait_random_exponential(min=1, max=60), stop=stop_after_attempt(6))
@@ -124,6 +191,52 @@ def find_most_similar_files(question_embedding, file_embeddings, top_n=3, min_si
return results
+# 新增:重排序函数
+def rerank_files(question, file_matches, top_n=5):
+ """使用DashScope重排序API对文件进行重新排序"""
+ try:
+ # 准备重排序输入
+ documents = []
+ for match in file_matches:
+ # 读取文件内容
+ try:
+ with open(match['path'], 'r', encoding='utf-8') as f:
+ content = f.read()[:2000] # 限制内容长度以提高效率
+ documents.append(content)
+ except Exception as e:
+ logging.error(f"读取文件 {match['path']} 失败: {e}")
+ continue
+
+ if not documents:
+ return file_matches[:top_n]
+
+ # 调用重排序API
+ response = dashscope.TextReRank.call(
+ model='gte-rerank',
+ query=question,
+ documents=documents
+ )
+
+ if response.status_code == 200:
+ # 根据重排序结果重新排序文件
+ reranked_results = []
+ for i, result in enumerate(response.output['results']):
+ if i < len(file_matches):
+ reranked_results.append({
+ 'path': file_matches[i]['path'],
+ 'similarity': result['relevance_score']
+ })
+
+ # 按重排序分数排序
+ reranked_results.sort(key=lambda x: x['similarity'], reverse=True)
+ return reranked_results[:top_n]
+ else:
+ logging.error(f"重排序失败: {response.message}")
+ return file_matches[:top_n]
+ except Exception as e:
+ logging.error(f"重排序时出错: {e}", exc_info=True)
+ return file_matches[:top_n]
+
def extract_relevant_code(file_path, keyword):
"""从文件中智能提取包含关键词的完整代码块 (C#类 或 XML Def)。"""
try:
@@ -213,45 +326,17 @@ def extract_xml_def(lines, start_index):
return "\n".join(lines[def_start_index:def_end_index+1])
return ""
-# 5. --- 核心功能函数 ---
-def find_files_with_keyword(roots, keywords: list[str], extensions=['.xml', '.cs', '.txt']):
- """在指定目录中查找包含任何一个关键字的文件。"""
- found_files = set()
- keywords_lower = [k.lower() for k in keywords]
- for root_path in roots:
- if not os.path.isdir(root_path):
- logging.warning(f"知识库路径不存在或不是一个目录: {root_path}")
- continue
- for dirpath, _, filenames in os.walk(root_path):
- for filename in filenames:
- if any(filename.lower().endswith(ext) for ext in extensions):
- file_path = os.path.join(dirpath, filename)
- try:
- with open(file_path, 'r', encoding='utf-8') as f:
- content_lower = f.read().lower()
- # 如果任何一个关键词在内容中,就添加文件
- if any(kw in content_lower for kw in keywords_lower):
- found_files.add(file_path)
- except Exception as e:
- logging.error(f"读取文件时出错 {file_path}: {e}")
- return list(found_files)
-
def find_keywords_in_question(question: str) -> list[str]:
"""从问题中提取所有可能的关键词 (类型名, defName等)。"""
+ # 简化关键词提取逻辑,主要依赖LLM进行分析
+ # 这里仅作为备用方案,用于LLM不可用时的基本关键词提取
+
# 正则表达式优先,用于精确匹配定义
# 匹配 C# class, struct, enum, interface 定义, 例如 "public class MyClass : Base"
csharp_def_pattern = re.compile(r'\b(?:public|private|internal|protected|sealed|abstract|static|new)\s+(?:class|struct|enum|interface)\s+([A-Za-z_][A-Za-z0-9_]*)')
# 匹配 XML Def, 例如 "" or ""
xml_def_pattern = re.compile(r'<([A-Za-z_][A-Za-z0-9_]*Def)\b')
- # 启发式规则,用于匹配独立的关键词
- # 规则1: 包含下划线 (很可能是 defName)
- # 规则2: 混合大小写 (很可能是 C# 类型名)
- # 规则3: 多个大写字母(例如 CompPsychicScaling,但要排除纯大写缩写词)
-
- # 排除常见但非特定的术语
- excluded_keywords = {"XML", "C#", "DEF", "CS", "CLASS", "PUBLIC"}
-
found_keywords = set()
# 1. 正则匹配
@@ -263,33 +348,136 @@ def find_keywords_in_question(question: str) -> list[str]:
for match in xml_matches:
found_keywords.add(match)
- # 2. 启发式单词匹配
+ # 2. 启发式单词匹配 - 简化版
parts = re.split(r'[\s,.:;\'"`()<>]+', question)
for part in parts:
- if not part or part.upper() in excluded_keywords:
+ if not part:
continue
- # 规则1: 包含下划线
+ # 规则1: 包含下划线 (很可能是 defName)
if '_' in part:
found_keywords.add(part)
- # 规则2: 驼峰命名或混合大小写
+ # 规则2: 驼峰命名或混合大小写 (很可能是 C# 类型名)
elif any(c.islower() for c in part) and any(c.isupper() for c in part) and len(part) > 3:
found_keywords.add(part)
- # 规则3: 多个大写字母
- elif sum(1 for c in part if c.isupper()) > 1 and not part.isupper():
- found_keywords.add(part)
- # 备用规则: 大写字母开头且较长
- elif part[0].isupper() and len(part) > 4:
+ # 规则3: 多个大写字母(例如 CompPsychicScaling)
+ elif sum(1 for c in part if c.isupper()) > 1 and not part.isupper() and len(part) > 3:
found_keywords.add(part)
if not found_keywords:
logging.warning(f"在 '{question}' 中未找到合适的关键词。")
- return []
+ # 如果找不到关键词,尝试使用整个问题作为关键词
+ return [question]
logging.info(f"找到的潜在关键词: {list(found_keywords)}")
return list(found_keywords)
+def analyze_question_with_llm(question: str) -> dict:
+ """使用Qwen模型分析问题并提取关键词和意图"""
+ try:
+ system_prompt = """你是一个关键词提取机器人,专门用于从 RimWorld 模组开发相关问题中提取精确的搜索关键词。你的任务是识别问题中提到的核心技术术语。
+
+严格按照以下格式回复,不要添加任何额外说明:
+问题类型:[问题分类]
+关键类/方法名:[类名或方法名]
+关键概念:[关键概念]
+搜索关键词:[关键词1,关键词2,关键词3]
+
+提取规则:
+1. 搜索关键词只能包含问题中明确出现的技术术语
+2. 不要添加任何推测或联想的词
+3. 不要添加通用词如"RimWorld"、"游戏"、"定义"、"用法"等
+4. 不要添加缩写或扩展形式如"Def"、"XML"等除非问题中明确提到
+5. 只提取具体的技术名词,忽略动词、形容词等
+6. 关键词之间用英文逗号分隔,不要有空格
+
+示例:
+问题:ThingDef的定义和用法是什么?
+问题类型:API 使用和定义说明
+关键类/方法名:ThingDef
+关键概念:定义, 用法
+搜索关键词:ThingDef
+
+问题:GenExplosion.DoExplosion 和 Projectile.Launch 方法如何使用?
+问题类型:API 使用说明
+关键类/方法名:GenExplosion.DoExplosion,Projectile.Launch
+关键概念:API 使用
+搜索关键词:GenExplosion.DoExplosion,Projectile.Launch
+
+现在请分析以下问题:"""
+
+ messages = [
+ {"role": "system", "content": system_prompt},
+ {"role": "user", "content": question}
+ ]
+
+ response = qwen_client.chat.completions.create(
+ model="qwen-plus",
+ messages=messages,
+ temperature=0.0, # 使用最低温度确保输出稳定
+ max_tokens=300,
+ stop=["\n\n"] # 防止模型生成过多内容
+ )
+
+ analysis_result = response.choices[0].message.content
+ logging.info(f"LLM分析结果: {analysis_result}")
+
+ # 解析LLM的分析结果
+ lines = analysis_result.strip().split('\n')
+ result = {
+ "question_type": "",
+ "key_classes_methods": [],
+ "key_concepts": [],
+ "search_keywords": []
+ }
+
+ for line in lines:
+ if line.startswith("问题类型:"):
+ result["question_type"] = line.replace("问题类型:", "").strip()
+ elif line.startswith("关键类/方法名:"):
+ methods = line.replace("关键类/方法名:", "").strip()
+ result["key_classes_methods"] = [m.strip() for m in methods.split(",") if m.strip()]
+ elif line.startswith("关键概念:"):
+ concepts = line.replace("关键概念:", "").strip()
+ result["key_concepts"] = [c.strip() for c in concepts.split(",") if c.strip()]
+ elif line.startswith("搜索关键词:"):
+ keywords = line.replace("搜索关键词:", "").strip()
+ # 直接按逗号分割,不进行额外处理
+ result["search_keywords"] = [k.strip() for k in keywords.split(",") if k.strip()]
+
+ # 如果LLM没有返回有效的关键词,则使用备用方案
+ if not result["search_keywords"]:
+ result["search_keywords"] = find_keywords_in_question(question)
+
+ return result
+ except Exception as e:
+ logging.error(f"使用LLM分析问题时出错: {e}", exc_info=True)
+ # 备用方案:使用原始关键词提取方法
+ return {
+ "question_type": "未知",
+ "key_classes_methods": [],
+ "key_concepts": [],
+ "search_keywords": find_keywords_in_question(question)
+ }
+
+def find_files_with_keyword(base_paths: list[str], keywords: list[str]) -> list[str]:
+ """
+ 在基础路径中递归搜索包含任意一个关键词的文件。
+ 搜索范围包括文件名。
+ """
+ found_files = set()
+ keywords_lower = [k.lower() for k in keywords]
+
+ for base_path in base_paths:
+ for root, _, files in os.walk(base_path):
+ for file in files:
+ file_lower = file.lower()
+ if any(keyword in file_lower for keyword in keywords_lower):
+ found_files.add(os.path.join(root, file))
+
+ logging.info(f"通过关键词找到 {len(found_files)} 个文件。")
+ return list(found_files)
# 5. --- 创建和配置 MCP 服务器 ---
# 使用 FastMCP 创建服务器实例
@@ -305,7 +493,11 @@ def get_context(question: str) -> str:
并将其整合后返回。
"""
logging.info(f"收到问题: {question}")
- keywords = find_keywords_in_question(question)
+
+ # 使用LLM分析问题
+ analysis = analyze_question_with_llm(question)
+ keywords = analysis["search_keywords"]
+
if not keywords:
logging.warning("无法从问题中提取关键词。")
return "无法从问题中提取关键词,请提供更具体的信息。"
@@ -316,23 +508,15 @@ def get_context(question: str) -> str:
cache_key = "-".join(sorted(keywords))
# 1. 检查缓存
- cached_result = load_cache_for_keyword(cache_key)
+ cached_result = load_cache_for_question(question, keywords)
if cached_result:
- logging.info(f"缓存命中: 关键词 '{cache_key}'")
return cached_result
logging.info(f"缓存未命中,开始实时搜索: {cache_key}")
# 2. 关键词文件搜索 (分层智能筛选)
try:
- # 优先使用最长的(通常最具体)的关键词进行搜索
- specific_keywords = sorted(keywords, key=len, reverse=True)
- candidate_files = find_files_with_keyword(KNOWLEDGE_BASE_PATHS, [specific_keywords[0]])
-
- # 如果最具体的关键词找不到文件,再尝试所有关键词
- if not candidate_files and len(keywords) > 1:
- logging.info(f"使用最具体的关键词 '{specific_keywords[0]}' 未找到文件,尝试所有关键词...")
- candidate_files = find_files_with_keyword(KNOWLEDGE_BASE_PATHS, keywords)
+ candidate_files = find_files_with_keyword(KNOWLEDGE_BASE_PATHS, keywords)
if not candidate_files:
logging.info(f"未找到与 '{keywords}' 相关的文件。")
@@ -351,14 +535,11 @@ def get_context(question: str) -> str:
logging.info(f"文件名精确匹配: {file_path}")
code_block = extract_relevant_code(file_path, keyword)
if code_block:
- lang = "csharp" if file_path.endswith(('.cs', '.txt')) else "xml"
- priority_results.append(
- f"---\n"
- f"**文件路径 (精确匹配):** `{file_path}`\n\n"
- f"```{lang}\n"
- f"{code_block}\n"
- f"```"
- )
+ priority_results.append({
+ 'path': file_path,
+ 'similarity': 1.0, # 精确匹配给予最高分
+ 'code': code_block
+ })
is_priority = True
break # 已处理该文件,跳出内层循环
if not is_priority:
@@ -368,7 +549,7 @@ def get_context(question: str) -> str:
# 3. 向量化和相似度计算 (精准筛选)
# 增加超时保护:限制向量化的文件数量
- MAX_FILES_TO_VECTORIZE = 25
+ MAX_FILES_TO_VECTORIZE = 50 # 增加处理文件数量
if len(candidate_files) > MAX_FILES_TO_VECTORIZE:
logging.warning(f"候选文件过多 ({len(candidate_files)}),仅处理前 {MAX_FILES_TO_VECTORIZE} 个。")
candidate_files = candidate_files[:MAX_FILES_TO_VECTORIZE]
@@ -392,45 +573,38 @@ def get_context(question: str) -> str:
return "无法为任何候选文件生成向量。"
# 找到最相似的多个文件
- best_matches = find_most_similar_files(question_embedding, file_embeddings, top_n=5) # 增加返回数量
+ best_matches = find_most_similar_files(question_embedding, file_embeddings, top_n=10) # 增加返回数量以供重排序
if not best_matches:
return "计算向量相似度失败或没有找到足够相似的文件。"
- # 4. 提取代码并格式化输出
- output_parts = [f"根据向量相似度分析,与 '{', '.join(keywords)}' 最相关的代码定义如下:\n"]
- output_parts.extend(priority_results) # 将优先结果放在最前面
+ # 新增:重排序处理
+ reranked_matches = rerank_files(question, best_matches, top_n=5)
- extracted_blocks = set() # 用于防止重复提取相同的代码块
-
- for match in best_matches:
- file_path = match['path']
- similarity = match['similarity']
-
- # 对每个关键词都尝试提取代码
- for keyword in keywords:
- code_block = extract_relevant_code(file_path, keyword)
-
- if code_block and code_block not in extracted_blocks:
- extracted_blocks.add(code_block)
- lang = "csharp" if file_path.endswith(('.cs', '.txt')) else "xml"
- output_parts.append(
- f"---\n"
- f"**文件路径:** `{file_path}`\n"
- f"**相似度:** {similarity:.4f}\n\n"
- f"```{lang}\n"
- f"{code_block}\n"
- f"```"
- )
+ # 提取代码内容
+ results_with_code = []
+ for match in reranked_matches:
+ code_block = extract_relevant_code(match['path'], "")
+ if code_block:
+ match['code'] = code_block
+ results_with_code.append(match)
- if len(output_parts) <= 1:
- return f"虽然找到了相似的文件,但无法在其中提取到关于 '{', '.join(keywords)}' 的完整代码块。"
-
- final_output = "\n".join(output_parts)
+ # 将优先结果添加到结果列表开头
+ results_with_code = priority_results + results_with_code
+
+ if len(results_with_code) <= 0:
+ return f"虽然找到了相似的文件,但无法在其中提取到相关代码块。"
+
+ # 直接返回原始代码结果,而不是使用LLM格式化
+ final_output = ""
+ for i, result in enumerate(results_with_code, 1):
+ final_output += f"--- 结果 {i} (相似度: {result['similarity']:.3f}) ---\n"
+ final_output += f"文件路径: {result['path']}\n\n"
+ final_output += f"{result['code']}\n\n"
# 5. 更新缓存并返回结果
- logging.info(f"向量搜索完成。找到了 {len(best_matches)} 个匹配项并成功提取了代码。")
- save_cache_for_keyword(cache_key, final_output)
+ logging.info(f"向量搜索完成。找到了 {len(results_with_code)} 个匹配项并成功提取了代码。")
+ save_cache_for_question(question, keywords, final_output)
return final_output
@@ -444,4 +618,4 @@ if __name__ == "__main__":
logging.info(f"Python Executable: {sys.executable}")
logging.info("RimWorld 向量知识库 (FastMCP版, v2.1-v4-model) 正在启动...")
# 使用 'stdio' 传输协议
- mcp.run(transport="stdio")
+ mcp.run(transport="stdio")
\ No newline at end of file
diff --git a/MCP/vector_cache/knowledge_cache.json b/MCP/vector_cache/knowledge_cache.json
new file mode 100644
index 00000000..09fb1584
--- /dev/null
+++ b/MCP/vector_cache/knowledge_cache.json
@@ -0,0 +1,1036 @@
+{
+ "ThingDef": {
+ "keywords": [
+ "ThingDef"
+ ],
+ "question": "What is a ThingDef?",
+ "embedding": [
+ -0.019440101459622383,
+ 0.0362212248146534,
+ 0.00969050731509924,
+ 0.03294181451201439,
+ -0.04809800535440445,
+ -0.0006195055320858955,
+ -0.016131149604916573,
+ 0.06724266707897186,
+ 0.04210052639245987,
+ 0.11746785044670105,
+ -0.053061433136463165,
+ -0.06990164518356323,
+ -0.038112055510282516,
+ -0.0914689302444458,
+ 0.029056748375296593,
+ -0.017874257639050484,
+ 0.00430237827822566,
+ -0.07279697805643082,
+ 0.01387840136885643,
+ -0.013413080014288425,
+ 0.027978384867310524,
+ 0.022675195708870888,
+ -0.029115837067365646,
+ 0.06281103193759918,
+ 0.019454874098300934,
+ -0.05279553681612015,
+ 0.01324320025742054,
+ 0.06245649978518486,
+ -0.03876202926039696,
+ 0.011958026327192783,
+ -0.0014559765113517642,
+ 0.04142100736498833,
+ 0.012238696217536926,
+ 0.007696271408349276,
+ 0.002598045626655221,
+ 0.03973698616027832,
+ 0.0067877862602472305,
+ -0.014247704297304153,
+ 0.020001443102955818,
+ -0.037107549607753754,
+ 0.036191679537296295,
+ -0.01231255754828453,
+ -0.02537849172949791,
+ -0.0331190787255764,
+ -0.04130282998085022,
+ -0.007703657727688551,
+ 0.03693028539419174,
+ -0.06446550786495209,
+ -0.05066835135221481,
+ 0.03394631668925285,
+ -0.012002342380583286,
+ 0.02050369419157505,
+ -0.03636894375085831,
+ -0.017726536840200424,
+ 0.012777878902852535,
+ 0.03282363712787628,
+ 0.03970744460821152,
+ -0.028569268062710762,
+ -0.004054945427924395,
+ 0.008715547621250153,
+ 0.009764367714524269,
+ 0.032557740807533264,
+ -0.07220609486103058,
+ -0.023133130744099617,
+ 0.07108341157436371,
+ -0.06594271957874298,
+ -0.011529634706676006,
+ -0.02477283589541912,
+ 0.04839344695210457,
+ -0.016278870403766632,
+ -0.03831886500120163,
+ 0.04836390167474747,
+ -0.07622411102056503,
+ -0.021818412467837334,
+ -0.07356512546539307,
+ 0.026102324947714806,
+ -0.023133130744099617,
+ -0.00922518502920866,
+ -0.02286723256111145,
+ -0.022305892780423164,
+ 0.020400289446115494,
+ -0.004095568787306547,
+ -0.03264637291431427,
+ -0.005713114980608225,
+ 0.03678256273269653,
+ 0.025629617273807526,
+ -0.009904702194035053,
+ -0.03595532476902008,
+ -0.028968116268515587,
+ 0.09383247047662735,
+ -0.05932481214404106,
+ 0.046620793640613556,
+ 0.0299430750310421,
+ -0.01830264925956726,
+ 0.04546856880187988,
+ 0.07474689930677414,
+ -0.04446406289935112,
+ 0.03958926722407341,
+ 0.016603855416178703,
+ 0.02034120075404644,
+ -0.03291226923465729,
+ -0.040948301553726196,
+ -0.010340480133891106,
+ 0.06812898814678192,
+ 0.015244822017848492,
+ 0.07126067578792572,
+ -0.028569268062710762,
+ -0.040593769401311874,
+ -0.016485679894685745,
+ -0.0028251667972654104,
+ -0.006086111068725586,
+ 0.04210052639245987,
+ -0.00900360383093357,
+ 0.01716519705951214,
+ -0.008021257817745209,
+ 0.06121564283967018,
+ -0.030312377959489822,
+ -0.027815891429781914,
+ 0.05264781415462494,
+ -0.005343812517821789,
+ 0.032557740807533264,
+ -0.051170602440834045,
+ 0.013029004447162151,
+ -0.027092058211565018,
+ -0.002982120495289564,
+ 0.013989192433655262,
+ 0.040977843105793,
+ 0.03595532476902008,
+ -0.01024446077644825,
+ -0.04797982797026634,
+ -0.05250009521842003,
+ -0.012260855175554752,
+ 0.013582958839833736,
+ -0.007312196306884289,
+ -0.020562782883644104,
+ -0.0457049198448658,
+ 0.04269140958786011,
+ 0.03261682763695717,
+ -0.04682760313153267,
+ 0.027092058211565018,
+ -0.037934787571430206,
+ -0.0015778464730829,
+ -0.05031381919980049,
+ 0.009993335232138634,
+ 0.11398163437843323,
+ -0.0022195102646946907,
+ -0.0013165646232664585,
+ -0.055277250707149506,
+ -0.02901243232190609,
+ 0.020385516807436943,
+ 0.018169701099395752,
+ -0.029381735250353813,
+ -0.010340480133891106,
+ 0.015422087162733078,
+ -0.001591695356182754,
+ 0.016278870403766632,
+ -0.009845614433288574,
+ -0.04452315345406532,
+ 0.0022878311574459076,
+ -0.012186993844807148,
+ 0.039973340928554535,
+ 0.006987209897488356,
+ -0.04331183806061745,
+ 0.009158710949122906,
+ 0.004956044256687164,
+ -0.02161160297691822,
+ -0.05725671350955963,
+ 0.03548261895775795,
+ -0.07202883064746857,
+ 0.003549000481143594,
+ 0.026235274970531464,
+ -0.020725276321172714,
+ -0.01087966188788414,
+ -0.0004101569938939065,
+ -0.004114033654332161,
+ -0.03072599694132805,
+ 0.007711043581366539,
+ 0.01349432673305273,
+ 0.048659343272447586,
+ -0.04765484109520912,
+ 0.03820068761706352,
+ 0.009720050729811192,
+ 0.08083301037549973,
+ 0.010606378316879272,
+ 0.012054044753313065,
+ -0.023384256288409233,
+ -0.03196685388684273,
+ 0.03214412182569504,
+ -0.0055986312218010426,
+ 0.0027328410651534796,
+ -0.033975861966609955,
+ 0.041893716901540756,
+ 0.050875160843133926,
+ 0.06133381649851799,
+ -0.05693172663450241,
+ -0.009409836493432522,
+ 0.006270762532949448,
+ 0.02808178961277008,
+ 0.017889030277729034,
+ 0.0015981581527739763,
+ 0.025452353060245514,
+ 0.011175104416906834,
+ 0.022187715396285057,
+ -0.011817690916359425,
+ 0.05282508209347725,
+ -0.027225006371736526,
+ 0.03025328926742077,
+ -0.00884111039340496,
+ 0.013102864846587181,
+ 0.0012353180209174752,
+ 0.027313638478517532,
+ -0.01277049258351326,
+ 0.04018015041947365,
+ -0.01921852119266987,
+ -0.014786886051297188,
+ -0.01118987612426281,
+ -0.04475950449705124,
+ -0.0007441452471539378,
+ -0.028332915157079697,
+ -0.0061267344281077385,
+ 0.0024170870892703533,
+ -0.009956404566764832,
+ 0.02651594579219818,
+ 0.02729886770248413,
+ 0.028510181233286858,
+ -0.006507116369903088,
+ 0.03122824989259243,
+ 0.013834085315465927,
+ 0.02301495335996151,
+ -0.03580760583281517,
+ 0.023413801565766335,
+ 0.03598487004637718,
+ -0.08898721635341644,
+ 0.06759719550609589,
+ 0.039973340928554535,
+ -0.0020311656408011913,
+ -0.028598813340067863,
+ -0.025023961439728737,
+ 0.03663484379649162,
+ 0.03731435909867287,
+ -0.028303369879722595,
+ 0.018494686111807823,
+ -0.0457935556769371,
+ 0.030208973214030266,
+ -0.027239779010415077,
+ 0.0013073320733383298,
+ -0.06399279832839966,
+ -0.06411097198724747,
+ 0.028022700920701027,
+ -0.009653576649725437,
+ -0.017726536840200424,
+ 0.0053548915311694145,
+ -0.055247705429792404,
+ -0.009358134120702744,
+ -0.02068096026778221,
+ 0.0457344651222229,
+ -0.03105098381638527,
+ -0.01474995631724596,
+ 0.005188704933971167,
+ 0.02443307638168335,
+ -0.007866150699555874,
+ -0.0037687355652451515,
+ 0.0005137926200404763,
+ -0.036664389073848724,
+ -0.03447811305522919,
+ 0.017268601804971695,
+ -0.0031132230069488287,
+ -0.05406593903899193,
+ -0.07959215342998505,
+ -0.038112055510282516,
+ 0.004051252268254757,
+ 0.0378757007420063,
+ 0.01720951311290264,
+ -0.029691949486732483,
+ 0.001599081326276064,
+ 0.023768331855535507,
+ 0.007917853072285652,
+ 0.0457344651222229,
+ -0.08059665560722351,
+ -0.0141886156052351,
+ -0.01765267550945282,
+ 0.00536597054451704,
+ -0.011219420470297337,
+ -0.05001837760210037,
+ -0.023871736600995064,
+ 0.019115116447210312,
+ 0.024698974564671516,
+ 0.021980905905365944,
+ 0.039057470858097076,
+ 0.021212756633758545,
+ 0.061865612864494324,
+ 0.015259593725204468,
+ -0.007441452704370022,
+ -0.004904341883957386,
+ -0.026885248720645905,
+ -0.018081067129969597,
+ 0.025319403037428856,
+ 0.03480309993028641,
+ -0.006832102779299021,
+ 0.027963612228631973,
+ 0.0009601874044165015,
+ 0.014159071259200573,
+ -0.0047012255527079105,
+ -0.0204889215528965,
+ 0.0866236761212349,
+ 0.00962403230369091,
+ -0.013435238040983677,
+ -0.07480598986148834,
+ -0.005949468817561865,
+ -0.05060926452279091,
+ 0.025452353060245514,
+ -0.016943614929914474,
+ -0.0016886373050510883,
+ -0.011980184353888035,
+ 0.020592326298356056,
+ 0.025334175676107407,
+ -0.04665033519268036,
+ -0.004435327369719744,
+ -0.028126105666160583,
+ 0.01386362873017788,
+ -0.048009369522333145,
+ -0.012984688393771648,
+ -0.003803819417953491,
+ 0.0181549284607172,
+ -0.03217366337776184,
+ -0.013029004447162151,
+ 0.02588074468076229,
+ -0.001548302243463695,
+ -0.00992686115205288,
+ 0.0012473204405978322,
+ 0.010510358959436417,
+ 0.004715997260063887,
+ 0.02161160297691822,
+ 0.016840210184454918,
+ -0.05489317700266838,
+ 0.008338858373463154,
+ 0.015377771109342575,
+ 0.034596290439367294,
+ 0.007755360100418329,
+ 0.009542785584926605,
+ -0.032557740807533264,
+ 0.018095839768648148,
+ 0.023561522364616394,
+ -0.023694470524787903,
+ 0.04085966944694519,
+ -0.008966673165559769,
+ 0.02348766103386879,
+ 0.056370388716459274,
+ -0.0378166139125824,
+ 0.021966133266687393,
+ -0.006802558433264494,
+ -0.02619095891714096,
+ -0.028273826465010643,
+ 0.024344444274902344,
+ -0.01278526522219181,
+ 0.0014799812342971563,
+ -0.004756620619446039,
+ -0.0165447685867548,
+ -0.024241039529442787,
+ 0.006152585614472628,
+ -0.02065141499042511,
+ 0.054154571145772934,
+ -0.0020145471207797527,
+ 0.006492344196885824,
+ 0.03551216423511505,
+ -0.0017800397472456098,
+ -0.001140222535468638,
+ 0.08130571991205215,
+ 0.007245722226798534,
+ 0.024373987689614296,
+ 0.02963286079466343,
+ -0.03294181451201439,
+ 0.010754099115729332,
+ 0.01638227514922619,
+ -0.0347440131008625,
+ -0.0014605928445234895,
+ 0.01497153751552105,
+ 0.0204889215528965,
+ -0.017076563090085983,
+ -0.0005784205859526992,
+ 0.07628319412469864,
+ 0.016441363841295242,
+ 0.004291299264878035,
+ -0.055572692304849625,
+ -0.021168438717722893,
+ -0.002655287506058812,
+ 0.013272744603455067,
+ 0.010517745278775692,
+ -0.011064313352108002,
+ -0.035718973726034164,
+ 0.05114106088876724,
+ -0.014314178377389908,
+ 0.024004684761166573,
+ -0.01302161905914545,
+ 0.04747757315635681,
+ 0.006001171190291643,
+ -0.015451631508767605,
+ 0.01985372230410576,
+ -0.01874581351876259,
+ -0.0291453804820776,
+ 0.015348226763308048,
+ -0.029248785227537155,
+ -0.03820068761706352,
+ 0.018539004027843475,
+ -0.023000182583928108,
+ -0.021345704793930054,
+ -0.005528463516384363,
+ 0.04325275123119354,
+ -0.0009878851706162095,
+ 0.020769592374563217,
+ -0.03592578321695328,
+ 0.012689245864748955,
+ 0.042336877435445786,
+ -0.020060531795024872,
+ -0.07746496796607971,
+ -0.018184471875429153,
+ -0.009136552922427654,
+ -0.0019111422589048743,
+ 0.06192470341920853,
+ -0.04647307097911835,
+ 0.012733562849462032,
+ 0.03435993939638138,
+ 0.0023506127763539553,
+ -0.015119259245693684,
+ -0.010813187807798386,
+ -0.021552514284849167,
+ -0.017874257639050484,
+ -0.0038444427773356438,
+ -0.015540264546871185,
+ -0.0028897947631776333,
+ -0.06860169768333435,
+ -0.0173572339117527,
+ -0.03344406560063362,
+ 0.05628175660967827,
+ 0.014550532214343548,
+ -0.05063880607485771,
+ 0.027328411117196083,
+ -0.00037230344605632126,
+ -0.006684381514787674,
+ -0.0040290942415595055,
+ -0.07043343782424927,
+ -0.01356818713247776,
+ 0.01458746287971735,
+ -0.037284817546606064,
+ -0.03701891750097275,
+ 0.012002342380583286,
+ 0.047566208988428116,
+ -0.0048009371384978294,
+ 0.004350387491285801,
+ 0.01018537301570177,
+ -0.034448571503162384,
+ 0.024654658511281013,
+ 0.022010449320077896,
+ 0.03329634666442871,
+ -0.016810666769742966,
+ 0.009173482656478882,
+ -0.005048369988799095,
+ 0.0094615388661623,
+ -0.00322955334559083,
+ -0.04936840385198593,
+ 0.006584669928997755,
+ -0.014594849199056625,
+ 0.03858476132154465,
+ 0.03825977444648743,
+ -0.016914071515202522,
+ -0.021065033972263336,
+ -0.02115366794168949,
+ 0.03181913495063782,
+ 0.003914610482752323,
+ -0.03858476132154465,
+ 0.027860207483172417,
+ 0.0038333635311573744,
+ 0.0014116601087152958,
+ 0.00116422725841403,
+ 0.030814630910754204,
+ 0.002893487922847271,
+ 0.017445866018533707,
+ 0.004933886229991913,
+ 0.019513962790369987,
+ 0.016337959095835686,
+ 0.030179429799318314,
+ 0.010155828669667244,
+ 0.02427058294415474,
+ 0.005325347185134888,
+ -0.08461467176675797,
+ -0.015687985345721245,
+ -0.013531256467103958,
+ -0.0315532349050045,
+ 0.015835706144571304,
+ -0.024255812168121338,
+ 0.0007898464682511985,
+ -0.01986849308013916,
+ 0.0013304135063663125,
+ -0.006736083887517452,
+ 0.011950640007853508,
+ -0.05533634126186371,
+ -0.009941632859408855,
+ 0.05598631128668785,
+ 0.0029359576292335987,
+ -0.08810088783502579,
+ -0.015481175854802132,
+ 0.044552695006132126,
+ -0.014218159951269627,
+ 0.027476131916046143,
+ -0.01284435298293829,
+ 0.016057288274168968,
+ -0.034596290439367294,
+ -2.3831575163058005e-05,
+ -0.021330932155251503,
+ 0.012644929811358452,
+ 0.009439380839467049,
+ -0.033680420368909836,
+ 0.020917313173413277,
+ -0.02853972464799881,
+ -0.037609804421663284,
+ 0.0035766982473433018,
+ 0.10653648525476456,
+ -0.004623671527951956,
+ -0.02020825259387493,
+ -0.02175932377576828,
+ -0.029721492901444435,
+ -0.012704018503427505,
+ -0.019838949665427208,
+ -0.03896883875131607,
+ -0.05740443617105484,
+ 0.05264781415462494,
+ 0.01610160432755947,
+ -0.012659701518714428,
+ 0.03864385187625885,
+ -0.032055485993623734,
+ -0.05152513459324837,
+ 0.01104215532541275,
+ 0.0519978404045105,
+ -0.017623132094740868,
+ 0.031464602798223495,
+ 0.027564765885472298,
+ 0.03695983067154884,
+ 0.01409998256713152,
+ -0.02961808815598488,
+ 0.1197132095694542,
+ 0.051318325102329254,
+ 0.039057470858097076,
+ -0.01222392451018095,
+ 0.03923473507165909,
+ 0.03403495252132416,
+ 0.05613403394818306,
+ 0.023399028927087784,
+ -0.022808143869042397,
+ 0.011485318653285503,
+ -0.03294181451201439,
+ -0.012711403891444206,
+ 0.01988326571881771,
+ -0.057315804064273834,
+ -0.02725454978644848,
+ 0.005724194459617138,
+ -0.0006171974237076938,
+ 0.02082868106663227,
+ 0.043282292783260345,
+ 0.007349126972258091,
+ -0.037609804421663284,
+ -0.026560261845588684,
+ -0.009040533564984798,
+ -0.01970599964261055,
+ -0.03560079634189606,
+ 0.005015132948756218,
+ 0.02793406881392002,
+ 0.004287606105208397,
+ 0.014292020350694656,
+ 0.054302290081977844,
+ -0.013125023804605007,
+ -0.02396036870777607,
+ 0.030031709000468254,
+ -0.043134573847055435,
+ 0.01042172685265541,
+ 0.011463160626590252,
+ -0.020237796008586884,
+ 0.007666727062314749,
+ -0.022527474910020828,
+ 0.08408287167549133,
+ 0.007777518127113581,
+ -0.024639885872602463,
+ 0.024713747203350067,
+ 0.0472707636654377,
+ -0.007282652426511049,
+ -0.0029156459495425224,
+ 0.01830264925956726,
+ 0.06476094573736191,
+ -0.0020625563338398933,
+ 0.013782382942736149,
+ 0.010074581950902939,
+ 0.008493965491652489,
+ 0.003914610482752323,
+ -0.0054176729172468185,
+ -0.011618267744779587,
+ -0.01893785037100315,
+ 0.03388722985982895,
+ 0.01970599964261055,
+ 0.009380292147397995,
+ 0.012349487282335758,
+ 0.04930931702256203,
+ -0.008759863674640656,
+ -0.04511403664946556,
+ -0.02743181586265564,
+ 0.016337959095835686,
+ 0.03279409185051918,
+ 0.0013054856099188328,
+ -0.012763106264173985,
+ -0.006108269095420837,
+ 0.0015021393774077296,
+ -0.0029378042090684175,
+ 0.03926428034901619,
+ 0.029204469174146652,
+ -0.029248785227537155,
+ 0.00915132462978363,
+ 0.06375644356012344,
+ -0.0037114936858415604,
+ -0.004487029742449522,
+ 0.014690867625176907,
+ -0.01970599964261055,
+ -0.010946136899292469,
+ -0.053061433136463165,
+ 0.003803819417953491,
+ -0.001126373652368784,
+ -0.049279771745204926,
+ -0.015481175854802132,
+ -0.005269951652735472,
+ -0.0009731129975989461,
+ -0.002095793606713414,
+ -0.05285462364554405,
+ -0.020902542397379875,
+ 0.0094541534781456,
+ 0.05613403394818306,
+ -0.026752298697829247,
+ 0.050520628690719604,
+ -0.022822916507720947,
+ -0.011802919209003448,
+ -0.029041975736618042,
+ -0.013893173076212406,
+ 0.035246264189481735,
+ -0.0048821838572621346,
+ -0.0015732301399111748,
+ 0.019203748553991318,
+ 0.017431095242500305,
+ -0.02979535423219204,
+ 0.01254891138523817,
+ -0.009993335232138634,
+ -0.04608899727463722,
+ 0.011019997298717499,
+ -0.015555036254227161,
+ 0.001864979392848909,
+ -0.026264818385243416,
+ 0.002450324362143874,
+ 0.03503945469856262,
+ 0.0457049198448658,
+ 0.021005947142839432,
+ 0.022808143869042397,
+ -0.03560079634189606,
+ 0.03235093131661415,
+ 0.0058349850587546825,
+ 0.0015039858408272266,
+ -0.0025518827605992556,
+ 0.03173050284385681,
+ 0.008013871498405933,
+ -0.0050631421618163586,
+ 0.01750495471060276,
+ -0.0024097012355923653,
+ -0.0059531619772315025,
+ -0.04608899727463722,
+ 0.010214917361736298,
+ 0.01689929887652397,
+ 0.0023746173828840256,
+ 0.006374167278409004,
+ -0.0029950460884720087,
+ -0.027210233733057976,
+ 0.022305892780423164,
+ 0.012046659365296364,
+ -0.03885066136717796,
+ -0.03802342340350151,
+ 0.017933346331119537,
+ 0.024359216913580894,
+ -0.00309660448692739,
+ 0.026235274970531464,
+ -0.04526175931096077,
+ -0.026131870225071907,
+ -0.015215277671813965,
+ 0.031021440401673317,
+ -0.020754819735884666,
+ 0.01766744814813137,
+ -0.07663773000240326,
+ 0.024994418025016785,
+ 0.05350459739565849,
+ -0.02493532933294773,
+ 0.010347865521907806,
+ 0.02162637561559677,
+ -0.043282292783260345,
+ -0.02193658985197544,
+ -0.03769843652844429,
+ -0.04348910227417946,
+ -0.01040695421397686,
+ 0.04783210530877113,
+ -0.012792650610208511,
+ -0.04670942574739456,
+ 0.07291515916585922,
+ 0.024728519842028618,
+ 0.008538281545042992,
+ 0.02178886905312538,
+ 0.012105747126042843,
+ -0.021360477432608604,
+ -0.005506305489689112,
+ 0.007474689744412899,
+ 0.024388760328292847,
+ 0.02633867971599102,
+ -0.010310935787856579,
+ -0.0009961944306269288,
+ -0.009247343055903912,
+ -0.015584580600261688,
+ 0.014085210859775543,
+ -0.007851378992199898,
+ -0.06919258087873459,
+ -0.020769592374563217,
+ -0.015185733325779438,
+ 0.025156909599900246,
+ 0.026885248720645905,
+ 0.026678437367081642,
+ -0.05610448867082596,
+ -0.025777339935302734,
+ -0.008058188483119011,
+ -0.0362803116440773,
+ 0.027402272447943687,
+ 0.06653360277414322,
+ -0.028126105666160583,
+ -0.029573772102594376,
+ 0.002005314454436302,
+ -0.03341452404856682,
+ -0.011640425771474838,
+ -0.027180690318346024,
+ -0.028820395469665527,
+ -0.009801297448575497,
+ -0.016795894131064415,
+ -0.008612142875790596,
+ 0.02979535423219204,
+ -0.013767610304057598,
+ 0.03601441532373428,
+ -0.01373068057000637,
+ 0.05309097841382027,
+ -0.025319403037428856,
+ 0.004557197447866201,
+ -0.007755360100418329,
+ 0.03028283454477787,
+ -0.01371590793132782,
+ 0.02304449863731861,
+ -0.03347361087799072,
+ -0.051347870379686356,
+ -0.05580904707312584,
+ -0.03580760583281517,
+ 0.017386779189109802,
+ 0.019750317558646202,
+ 0.000533642596565187,
+ -0.012113133445382118,
+ 0.044375430792570114,
+ -0.017948118969798088,
+ 0.049427494406700134,
+ 0.008501351810991764,
+ 0.06806990504264832,
+ 0.050845615565776825,
+ 0.010820573195815086,
+ -0.006448027677834034,
+ 0.0020237795542925596,
+ 0.005532156676054001,
+ -0.04183462634682655,
+ -0.04088921099901199,
+ -0.02961808815598488,
+ -0.020754819735884666,
+ 0.0758104920387268,
+ 0.025452353060245514,
+ -0.003166771959513426,
+ 0.017756082117557526,
+ -0.005735273472964764,
+ -0.02240929752588272,
+ 0.0033218790777027607,
+ 0.0032443255186080933,
+ -0.02462511509656906,
+ -0.03766889125108719,
+ 0.009971177205443382,
+ 0.025511441752314568,
+ 0.021242300048470497,
+ -0.005908845458179712,
+ 0.05057971924543381,
+ 0.014365880750119686,
+ 0.010370024479925632,
+ 5.444332055049017e-05,
+ -0.0009740362875163555,
+ 0.04304594174027443,
+ 0.05347505211830139,
+ 0.01765267550945282,
+ -0.020282112061977386,
+ -0.03249865025281906,
+ 0.0645836815237999,
+ -0.006950279697775841,
+ 0.031139615923166275,
+ 0.01426247600466013,
+ -0.07391966134309769,
+ 0.04930931702256203,
+ -0.012467664666473866,
+ -0.03515763208270073,
+ 0.014033508487045765,
+ -0.01474995631724596,
+ -0.03953017666935921,
+ -0.0033791211899369955,
+ 0.007947397418320179,
+ 0.04387317970395088,
+ 0.012253468856215477,
+ 0.022778600454330444,
+ 0.015407315455377102,
+ 0.018657179549336433,
+ -0.02162637561559677,
+ -0.031021440401673317,
+ -0.005177625920623541,
+ 0.006592055782675743,
+ 0.026707982644438744,
+ 0.027712486684322357,
+ 0.045970819890499115,
+ -0.01018537301570177,
+ 0.01768222078680992,
+ -0.0017283373745158315,
+ -0.017948118969798088,
+ 0.027993155643343925,
+ -0.014676094986498356,
+ -0.007485768757760525,
+ -0.019277609884738922,
+ 0.0024447848554700613,
+ -0.005746352486312389,
+ -0.020592326298356056,
+ -0.018686724826693535,
+ 0.0330895371735096,
+ -0.03229184076189995,
+ -0.009660962969064713,
+ -0.01167735643684864,
+ -0.007459917571395636,
+ -0.019277609884738922,
+ -0.020577555522322655,
+ 0.0314941480755806,
+ 0.0003095219435635954,
+ 0.008058188483119011,
+ 0.0005798054626211524,
+ 0.02446262165904045,
+ 0.019838949665427208,
+ -0.020784365013241768,
+ -0.004933886229991913,
+ -0.08278292417526245,
+ -0.012268240563571453,
+ 0.04159827530384064,
+ 0.011396686546504498,
+ 0.00016584005788899958,
+ 0.021079806610941887,
+ 0.03799387812614441,
+ -0.013560800813138485,
+ -0.004202666692435741,
+ -0.03072599694132805,
+ 0.022601334378123283,
+ -0.02791929617524147,
+ 0.005295802839100361,
+ -0.03108052909374237,
+ 0.0037170331925153732,
+ -0.024831924587488174,
+ 0.04496631398797035,
+ -0.012955144047737122,
+ 0.00020577093528117985,
+ -0.007341740652918816,
+ -0.05223419517278671,
+ 0.040771033614873886,
+ 0.07149703055620193,
+ -0.0063150785863399506,
+ 0.029869215562939644,
+ 0.017298145219683647,
+ 0.023768331855535507,
+ -0.008139435201883316,
+ 0.016795894131064415,
+ -0.010598991997539997,
+ 0.04638443887233734,
+ -0.00047640068805776536,
+ -0.027372727170586586,
+ 0.022985409945249557,
+ 0.01672203280031681,
+ 0.037609804421663284,
+ -0.02430012822151184,
+ 0.01766744814813137,
+ -0.02540803700685501,
+ -0.0005830368609167635,
+ 0.020459378138184547,
+ 0.03134642541408539,
+ -0.038407497107982635,
+ -0.007201405707746744,
+ 0.025201227515935898,
+ -0.030238518491387367,
+ -0.011056927032768726,
+ -0.03920518979430199,
+ -0.017475411295890808,
+ -0.03480309993028641,
+ -0.015702757984399796,
+ 0.003316339571028948,
+ -0.04210052639245987,
+ 0.0010866736993193626,
+ -0.04981156811118126,
+ -0.01938101463019848,
+ 0.02428535558283329,
+ -0.025304632261395454,
+ -0.014018736779689789,
+ -0.025348948314785957,
+ 0.039027925580739975,
+ 0.004974509589374065,
+ 0.018051523715257645,
+ 0.027165917679667473,
+ 0.020223025232553482,
+ -0.03687119856476784,
+ -0.0260432381182909,
+ -0.03911655768752098,
+ 0.04337092861533165,
+ 0.01378976833075285,
+ -0.02650117315351963,
+ 0.0268113873898983,
+ 0.026146642863750458,
+ -0.02697388082742691,
+ -0.007829220965504646,
+ 0.012526752427220345,
+ -7.657263631699607e-05,
+ -0.046768512576818466,
+ 0.09495514631271362,
+ -0.006776707246899605,
+ 0.02096162922680378,
+ 0.01626409776508808,
+ 0.02602846547961235,
+ 0.029839670285582542,
+ 0.0022915243171155453,
+ 0.00834624469280243,
+ -0.01065808068960905,
+ -0.014402811415493488,
+ -0.04032787308096886,
+ 0.006451720837503672,
+ -0.002365384716540575,
+ 0.01340569369494915,
+ -0.00971266534179449,
+ 0.025777339935302734,
+ 0.0029710414819419384,
+ 0.018804902210831642,
+ 0.0006208904087543488,
+ 0.00045470413169823587,
+ -0.0189526230096817,
+ 0.045675378292798996,
+ 0.029041975736618042,
+ -0.0007252185023389757,
+ -0.03187822178006172,
+ 0.0060159433633089066,
+ -0.0033237256575375795,
+ -0.057463523000478745,
+ 0.0038333635311573744,
+ 0.0034382096491754055,
+ -0.020769592374563217,
+ 0.02130138874053955,
+ -0.024713747203350067,
+ 0.06399279832839966,
+ 0.01800720766186714,
+ -0.008641687221825123,
+ -0.05707944929599762,
+ 0.03009079582989216,
+ -0.018391281366348267,
+ -0.030666908249258995,
+ -0.05492272228002548,
+ -0.0013165646232664585,
+ 0.03181913495063782,
+ -0.03090326301753521,
+ 0.034300848841667175,
+ 0.0018585165962576866,
+ -0.017918573692440987,
+ -0.022808143869042397,
+ 0.0027346876449882984,
+ 0.005443524103611708,
+ -0.0315236933529377,
+ -0.04922068491578102,
+ 0.0027623854111880064,
+ -0.0021124123595654964,
+ 0.026427311822772026,
+ -0.01862763613462448,
+ 0.035896237939596176,
+ -0.011212035082280636,
+ -0.0030541345477104187,
+ 0.022187715396285057,
+ -0.000870631483849138,
+ 0.024950100108981133,
+ -0.012415962293744087,
+ -0.02459556981921196,
+ -0.030194200575351715,
+ -0.010104126296937466,
+ -0.00884111039340496,
+ 0.01039956882596016,
+ 0.005731580313295126,
+ 0.025127366185188293,
+ -0.01497153751552105,
+ 0.04242551326751709,
+ -0.0027273015584796667,
+ -0.02697388082742691,
+ 0.05232282727956772,
+ -0.0033569629304111004,
+ -0.025939833372831345,
+ -0.006592055782675743,
+ 0.0189230777323246,
+ -0.08733274042606354,
+ 0.028347687795758247,
+ -0.007441452704370022,
+ -0.008242839947342873,
+ 0.017091335728764534,
+ 0.03456674888730049,
+ 0.018568547442555428,
+ -0.011219420470297337,
+ 0.01732769049704075,
+ 0.02554098516702652,
+ -0.0003939999733120203,
+ -0.0019259144319221377,
+ 0.004298685118556023,
+ -0.002891641343012452,
+ -0.030238518491387367,
+ 0.08709638565778732,
+ -0.015525491908192635,
+ 0.0027273015584796667
+ ],
+ "result": "--- 结果 1 (相似度: 1.000) ---\n文件路径: C:\\Steam\\steamapps\\common\\RimWorld\\Data\\dll1.6\\Verse\\ThingDef.txt\n\npublic class ThingDef : BuildableDef\n{\n\tpublic Type thingClass;\n\n\tpublic ThingCategory category;\n\n\tpublic TickerType tickerType;\n\n\tpublic int stackLimit = 1;\n\n\tpublic IntVec2 size = IntVec2.One;\n\n\tpublic bool destroyable = true;\n\n\tpublic bool rotatable = true;\n\n\tpublic bool smallVolume;\n\n\tpublic bool useHitPoints = true;\n\n\tpublic bool receivesSignals;\n\n\tpublic List comps = new List();\n\n\tpublic List virtualDefs = new List();\n\n\tpublic ThingDef virtualDefParent;\n\n\t[NoTranslate]\n\tpublic string devNote;\n\n\tpublic List killedLeavingsRanges;\n\n\tpublic List killedLeavings;\n\n\tpublic List killedLeavingsPlayerHostile;\n\n\tpublic float killedLeavingsChance = 1f;\n\n\tpublic bool forceLeavingsAllowed;\n\n\tpublic List butcherProducts;\n\n\tpublic List smeltProducts;\n\n\tpublic bool smeltable;\n\n\tpublic bool burnableByRecipe;\n\n\tpublic bool randomizeRotationOnSpawn;\n\n\tpublic List damageMultipliers;\n\n\tpublic bool isTechHediff;\n\n\tpublic RecipeMakerProperties recipeMaker;\n\n\tpublic ThingDef minifiedDef;\n\n\tpublic bool isUnfinishedThing;\n\n\tpublic bool leaveResourcesWhenKilled;\n\n\tpublic ThingDef slagDef;\n\n\tpublic bool isFrameInt;\n\n\tpublic List multipleInteractionCellOffsets;\n\n\tpublic IntVec3 interactionCellOffset = IntVec3.Zero;\n\n\tpublic bool hasInteractionCell;\n\n\tpublic ThingDef interactionCellIcon;\n\n\tpublic bool interactionCellIconReverse;\n\n\tpublic ThingDef filthLeaving;\n\n\tpublic bool forceDebugSpawnable;\n\n\tpublic bool intricate;\n\n\tpublic bool scatterableOnMapGen = true;\n\n\tpublic float deepCommonality;\n\n\tpublic int deepCountPerCell = 300;\n\n\tpublic int deepCountPerPortion = -1;\n\n\tpublic IntRange deepLumpSizeRange = IntRange.Zero;\n\n\tpublic float generateCommonality = 1f;\n\n\tpublic float generateAllowChance = 1f;\n\n\tprivate bool canOverlapZones = true;\n\n\tpublic FloatRange startingHpRange = FloatRange.One;\n\n\t[NoTranslate]\n\tpublic List thingSetMakerTags;\n\n\tpublic bool alwaysFlee;\n\n\tpublic List recipes;\n\n\tpublic bool messageOnDeteriorateInStorage = true;\n\n\tpublic bool deteriorateFromEnvironmentalEffects = true;\n\n\tpublic bool canDeteriorateUnspawned;\n\n\tpublic bool canLoadIntoCaravan = true;\n\n\tpublic bool isMechClusterThreat;\n\n\tpublic FloatRange displayNumbersBetweenSameDefDistRange = FloatRange.Zero;\n\n\tpublic int minRewardCount = 1;\n\n\tpublic bool preventSkyfallersLandingOn;\n\n\tpublic FactionDef requiresFactionToAcquire;\n\n\tpublic float relicChance;\n\n\tpublic OrderedTakeGroupDef orderedTakeGroup;\n\n\tpublic int allowedArchonexusCount;\n\n\tpublic int possessionCount;\n\n\tpublic bool notifyMapRemoved;\n\n\tpublic bool canScatterOver = true;\n\n\tpublic bool genericMarketSellable = true;\n\n\tpublic bool drawHighlight;\n\n\tpublic Color? highlightColor;\n\n\tpublic bool drawHighlightOnlyForHostile;\n\n\tpublic bool autoTargetNearbyIdenticalThings;\n\n\tpublic bool preventDroppingThingsOn;\n\n\tpublic bool hiddenWhileUndiscovered;\n\n\tpublic bool disableImpassableShotOverConfigError;\n\n\tpublic bool showInSearch = true;\n\n\tpublic bool bringAlongOnGravship = true;\n\n\tpublic ThingDef dropPodFaller;\n\n\tpublic bool preventSpawningInResourcePod;\n\n\tpublic bool pathfinderDangerous;\n\n\tpublic bool noRightClickDraftAttack;\n\n\tpublic int gravshipSpawnPriority = 1;\n\n\tpublic List replaceTags;\n\n\tpublic GraphicData graphicData;\n\n\tpublic DrawerType drawerType = DrawerType.RealtimeOnly;\n\n\tpublic bool drawOffscreen;\n\n\tpublic ColorGenerator colorGenerator;\n\n\tpublic float hideAtSnowOrSandDepth = 99999f;\n\n\tpublic bool drawDamagedOverlay = true;\n\n\tpublic bool castEdgeShadows;\n\n\tpublic float staticSunShadowHeight;\n\n\tpublic bool useSameGraphicForGhost;\n\n\tpublic bool useBlueprintGraphicAsGhost;\n\n\tpublic List randomStyle;\n\n\tpublic float randomStyleChance;\n\n\tpublic bool canEditAnyStyle;\n\n\tpublic bool dontPrint;\n\n\tpublic ThingDef defaultStuff;\n\n\tpublic int killedLeavingsExpandRect;\n\n\tpublic bool minifiedManualDraw;\n\n\tpublic float minifiedDrawScale = 1f;\n\n\tpublic Rot4 overrideMinifiedRot = Rot4.Invalid;\n\n\tpublic Vector3 minifiedDrawOffset = Vector3.zero;\n\n\tpublic float deselectedSelectionBracketFactor = 1f;\n\n\tpublic bool selectable;\n\n\tpublic bool containedPawnsSelectable;\n\n\tpublic bool containedItemsSelectable;\n\n\tpublic bool neverMultiSelect;\n\n\tpublic bool isAutoAttackableMapObject;\n\n\tpublic bool hasTooltip;\n\n\tpublic List inspectorTabs;\n\n\t[Unsaved(false)]\n\tpublic List inspectorTabsResolved;\n\n\tpublic bool seeThroughFog;\n\n\tpublic bool drawGUIOverlay;\n\n\tpublic bool drawGUIOverlayQuality = true;\n\n\tpublic ResourceCountPriority resourceReadoutPriority;\n\n\tpublic bool resourceReadoutAlwaysShow;\n\n\tpublic bool drawPlaceWorkersWhileSelected;\n\n\tpublic bool drawPlaceWorkersWhileInstallBlueprintSelected;\n\n\tpublic ConceptDef storedConceptLearnOpportunity;\n\n\tpublic float uiIconScale = 1f;\n\n\tpublic bool hasCustomRectForSelector;\n\n\tpublic bool hideStats;\n\n\tpublic bool hideInspect;\n\n\tpublic bool onlyShowInspectString;\n\n\tpublic bool hideMainDesc;\n\n\tpublic bool alwaysHaulable;\n\n\tpublic bool designateHaulable;\n\n\tpublic List thingCategories;\n\n\tpublic bool mineable;\n\n\tpublic bool socialPropernessMatters;\n\n\tpublic bool stealable = true;\n\n\tpublic SoundDef soundSpawned;\n\n\tpublic SoundDef soundDrop;\n\n\tpublic SoundDef soundPickup;\n\n\tpublic SoundDef soundInteract;\n\n\tpublic SoundDef soundImpactDefault;\n\n\tpublic SoundDef soundPlayInstrument;\n\n\tpublic SoundDef soundOpen;\n\n\tpublic bool saveCompressible;\n\n\tpublic bool isSaveable = true;\n\n\tpublic bool holdsRoof;\n\n\tpublic float fillPercent;\n\n\tpublic bool coversFloor;\n\n\tpublic bool neverOverlapFloors;\n\n\tpublic SurfaceType surfaceType;\n\n\tpublic bool wipesPlants;\n\n\tpublic bool blockPlants;\n\n\tpublic bool blockLight;\n\n\tpublic bool blockWind;\n\n\tpublic bool blockWeather;\n\n\tpublic Tradeability tradeability = Tradeability.All;\n\n\t[NoTranslate]\n\tpublic List tradeTags;\n\n\tpublic bool tradeNeverStack;\n\n\tpublic bool tradeNeverGenerateStacked;\n\n\tpublic bool healthAffectsPrice = true;\n\n\tpublic ColorGenerator colorGeneratorInTraderStock;\n\n\tprivate List verbs;\n\n\tpublic List tools;\n\n\tpublic float equippedAngleOffset;\n\n\tpublic float equippedDistanceOffset;\n\n\tpublic EquipmentType equipmentType;\n\n\tpublic TechLevel techLevel;\n\n\tpublic List weaponClasses;\n\n\t[NoTranslate]\n\tpublic List weaponTags;\n\n\t[NoTranslate]\n\tpublic List techHediffsTags;\n\n\tpublic bool violentTechHediff;\n\n\tpublic bool destroyOnDrop;\n\n\tpublic List equippedStatOffsets;\n\n\tpublic SoundDef meleeHitSound;\n\n\tpublic float recoilPower = 1f;\n\n\tpublic float recoilRelaxation = 10f;\n\n\tpublic bool rotateInShelves = true;\n\n\tpublic bool mergeVerbGizmos = true;\n\n\tpublic BuildableDef entityDefToBuild;\n\n\tpublic ThingDef projectileWhenLoaded;\n\n\tpublic RulePackDef ideoBuildingNamerBase;\n\n\tpublic EntityCodexEntryDef entityCodexEntry;\n\n\tpublic IngestibleProperties ingestible;\n\n\tpublic FilthProperties filth;\n\n\tpublic GasProperties gas;\n\n\tpublic BuildingProperties building;\n\n\tpublic RaceProperties race;\n\n\tpublic ApparelProperties apparel;\n\n\tpublic MoteProperties mote;\n\n\tpublic PlantProperties plant;\n\n\tpublic ProjectileProperties projectile;\n\n\tpublic StuffProperties stuffProps;\n\n\tpublic SkyfallerProperties skyfaller;\n\n\tpublic PawnFlyerProperties pawnFlyer;\n\n\tpublic RitualFocusProperties ritualFocus;\n\n\tpublic IngredientProperties ingredient;\n\n\tpublic MapPortalProperties portal;\n\n\tpublic bool canBeUsedUnderRoof = true;\n\n\t[Unsaved(false)]\n\tprivate string descriptionDetailedCached;\n\n\t[Unsaved(false)]\n\tpublic Graphic interactionCellGraphic;\n\n\t[Unsaved(false)]\n\tprivate bool? isNaturalOrganCached;\n\n\t[Unsaved(false)]\n\tprivate bool? hasSunShadowsCached;\n\n\t[Unsaved(false)]\n\tprivate List cachedRelevantStyleCategories;\n\n\tpublic const int SmallUnitPerVolume = 10;\n\n\tpublic const float SmallVolumePerUnit = 0.1f;\n\n\tpublic const float ArchonexusMaxItemStackMass = 5f;\n\n\tpublic const int ArchonexusMaxItemStackCount = 25;\n\n\tpublic const float ArchonexusMaxItemStackValue = 2000f;\n\n\tpublic const int ArchonexusAutoCalculateValue = -1;\n\n\tprivate List allRecipesCached;\n\n\tprivate static List EmptyVerbPropertiesList = new List();\n\n\tprivate Dictionary concreteExamplesInt;\n\n\tpublic bool EverHaulable\n\t{\n\t\tget\n\t\t{\n\t\t\tif (!alwaysHaulable)\n\t\t\t{\n\t\t\t\treturn designateHaulable;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tpublic bool EverPollutable => !building.isNaturalRock;\n\n\tpublic float VolumePerUnit\n\t{\n\t\tget\n\t\t{\n\t\t\tif (smallVolume)\n\t\t\t{\n\t\t\t\treturn 0.1f;\n\t\t\t}\n\t\t\treturn 1f;\n\t\t}\n\t}\n\n\tpublic override IntVec2 Size => size;\n\n\tpublic bool DiscardOnDestroyed => race == null;\n\n\tpublic int BaseMaxHitPoints => Mathf.RoundToInt(this.GetStatValueAbstract(StatDefOf.MaxHitPoints));\n\n\tpublic float BaseFlammability => this.GetStatValueAbstract(StatDefOf.Flammability);\n\n\tpublic float BaseMarketValue\n\t{\n\t\tget\n\t\t{\n\t\t\treturn this.GetStatValueAbstract(StatDefOf.MarketValue);\n\t\t}\n\t\tset\n\t\t{\n\t\t\tthis.SetStatBaseValue(StatDefOf.MarketValue, value);\n\t\t}\n\t}\n\n\tpublic float BaseMass => this.GetStatValueAbstract(StatDefOf.Mass);\n\n\tpublic int ArchonexusMaxAllowedCount\n\t{\n\t\tget\n\t\t{\n\t\t\tif (allowedArchonexusCount == -1)\n\t\t\t{\n\t\t\t\treturn Mathf.Min(stackLimit, 25, (BaseMass > 0f) ? ((int)(5f / BaseMass)) : 0, (BaseMarketValue > 0f) ? ((int)(2000f / BaseMarketValue)) : 0);\n\t\t\t}\n\t\t\treturn allowedArchonexusCount;\n\t\t}\n\t}\n\n\tpublic bool PlayerAcquirable\n\t{\n\t\tget\n\t\t{\n\t\t\tif (destroyOnDrop)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (this == ThingDefOf.ReinforcedBarrel && Find.Storyteller != null && Find.Storyteller.difficulty.classicMortars)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (requiresFactionToAcquire != null && Find.World != null && Find.World.factionManager != null)\n\t\t\t{\n\t\t\t\treturn Find.FactionManager.FirstFactionOfDef(requiresFactionToAcquire) != null;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tpublic bool EverTransmitsPower\n\t{\n\t\tget\n\t\t{\n\t\t\tfor (int i = 0; i < comps.Count; i++)\n\t\t\t{\n\t\t\t\tif (comps[i] is CompProperties_Power { transmitsPower: not false })\n\t\t\t\t{\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool Minifiable => minifiedDef != null;\n\n\tpublic bool HasThingIDNumber => category != ThingCategory.Mote;\n\n\tpublic List AllRecipes\n\t{\n\t\tget\n\t\t{\n\t\t\tif (allRecipesCached == null)\n\t\t\t{\n\t\t\t\tallRecipesCached = new List();\n\t\t\t\tif (recipes != null)\n\t\t\t\t{\n\t\t\t\t\tfor (int i = 0; i < recipes.Count; i++)\n\t\t\t\t\t{\n\t\t\t\t\t\tallRecipesCached.Add(recipes[i]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tList allDefsListForReading = DefDatabase.AllDefsListForReading;\n\t\t\t\tfor (int j = 0; j < allDefsListForReading.Count; j++)\n\t\t\t\t{\n\t\t\t\t\tif (allDefsListForReading[j].recipeUsers != null && allDefsListForReading[j].recipeUsers.Contains(this))\n\t\t\t\t\t{\n\t\t\t\t\t\tallRecipesCached.Add(allDefsListForReading[j]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn allRecipesCached;\n\t\t}\n\t}\n\n\tpublic bool ConnectToPower\n\t{\n\t\tget\n\t\t{\n\t\t\tif (EverTransmitsPower)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tfor (int i = 0; i < comps.Count; i++)\n\t\t\t{\n\t\t\t\tif (comps[i].compClass == typeof(CompPowerBattery))\n\t\t\t\t{\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tif (comps[i].compClass == typeof(CompPowerTrader))\n\t\t\t\t{\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool CoexistsWithFloors\n\t{\n\t\tget\n\t\t{\n\t\t\tif (!neverOverlapFloors)\n\t\t\t{\n\t\t\t\treturn !coversFloor;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic FillCategory Fillage\n\t{\n\t\tget\n\t\t{\n\t\t\tif (fillPercent < 0.01f)\n\t\t\t{\n\t\t\t\treturn FillCategory.None;\n\t\t\t}\n\t\t\tif (fillPercent > 0.99f)\n\t\t\t{\n\t\t\t\treturn FillCategory.Full;\n\t\t\t}\n\t\t\treturn FillCategory.Partial;\n\t\t}\n\t}\n\n\tpublic bool MakeFog => Fillage == FillCategory.Full;\n\n\tpublic bool CanOverlapZones\n\t{\n\t\tget\n\t\t{\n\t\t\tif (building != null && building.SupportsPlants)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (passability == Traversability.Impassable && category != ThingCategory.Plant && !HasComp(typeof(CompTransporter)))\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif ((int)surfaceType >= 1)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (typeof(ISlotGroupParent).IsAssignableFrom(thingClass))\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (!canOverlapZones)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif ((IsBlueprint || IsFrame) && entityDefToBuild is ThingDef thingDef)\n\t\t\t{\n\t\t\t\treturn thingDef.CanOverlapZones;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tpublic bool CountAsResource => resourceReadoutPriority != ResourceCountPriority.Uncounted;\n\n\tpublic List Verbs\n\t{\n\t\tget\n\t\t{\n\t\t\tif (verbs != null)\n\t\t\t{\n\t\t\t\treturn verbs;\n\t\t\t}\n\t\t\treturn EmptyVerbPropertiesList;\n\t\t}\n\t}\n\n\tpublic bool CanHaveFaction\n\t{\n\t\tget\n\t\t{\n\t\t\tif (IsBlueprint || IsFrame)\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn category switch\n\t\t\t{\n\t\t\t\tThingCategory.Pawn => true, \n\t\t\t\tThingCategory.Building => true, \n\t\t\t\t_ => false, \n\t\t\t};\n\t\t}\n\t}\n\n\tpublic bool Claimable\n\t{\n\t\tget\n\t\t{\n\t\t\tif (building != null && building.claimable)\n\t\t\t{\n\t\t\t\treturn !building.isNaturalRock;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic ThingCategoryDef FirstThingCategory\n\t{\n\t\tget\n\t\t{\n\t\t\tif (thingCategories.NullOrEmpty())\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\treturn thingCategories[0];\n\t\t}\n\t}\n\n\tpublic float MedicineTendXpGainFactor => Mathf.Clamp(this.GetStatValueAbstract(StatDefOf.MedicalPotency) * 0.7f, 0.5f, 1f);\n\n\tpublic bool CanEverDeteriorate\n\t{\n\t\tget\n\t\t{\n\t\t\tif (!useHitPoints)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (category != ThingCategory.Item)\n\t\t\t{\n\t\t\t\tif (plant != null)\n\t\t\t\t{\n\t\t\t\t\treturn plant.canDeteriorate;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tpublic bool CanInteractThroughCorners\n\t{\n\t\tget\n\t\t{\n\t\t\tif (category != ThingCategory.Building)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (!holdsRoof)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (building != null && building.isNaturalRock && !IsSmoothed)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tpublic bool AffectsRegions\n\t{\n\t\tget\n\t\t{\n\t\t\tif (passability != Traversability.Impassable && !IsDoor)\n\t\t\t{\n\t\t\t\treturn IsFence;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tpublic bool AffectsReachability\n\t{\n\t\tget\n\t\t{\n\t\t\tif (AffectsRegions)\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif (passability == Traversability.Impassable || IsDoor)\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif (TouchPathEndModeUtility.MakesOccupiedCellsAlwaysReachableDiagonally(this))\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic string DescriptionDetailed\n\t{\n\t\tget\n\t\t{\n\t\t\tif (descriptionDetailedCached == null)\n\t\t\t{\n\t\t\t\tStringBuilder stringBuilder = new StringBuilder();\n\t\t\t\tstringBuilder.Append(description);\n\t\t\t\tif (IsApparel)\n\t\t\t\t{\n\t\t\t\t\tstringBuilder.AppendLine();\n\t\t\t\t\tstringBuilder.AppendLine();\n\t\t\t\t\tstringBuilder.AppendLine(string.Format(\"{0}: {1}\", \"Layer\".Translate(), apparel.GetLayersString()));\n\t\t\t\t\tstringBuilder.Append(string.Format(\"{0}: {1}\", \"Covers\".Translate(), apparel.GetCoveredOuterPartsString(BodyDefOf.Human)));\n\t\t\t\t\tif (equippedStatOffsets != null && equippedStatOffsets.Count > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tstringBuilder.AppendLine();\n\t\t\t\t\t\tstringBuilder.AppendLine();\n\t\t\t\t\t\tfor (int i = 0; i < equippedStatOffsets.Count; i++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (i > 0)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tstringBuilder.AppendLine();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tStatModifier statModifier = equippedStatOffsets[i];\n\t\t\t\t\t\t\tstringBuilder.Append($\"{statModifier.stat.LabelCap}: {statModifier.ValueToStringAsOffset}\");\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tdescriptionDetailedCached = stringBuilder.ToString();\n\t\t\t}\n\t\t\treturn descriptionDetailedCached;\n\t\t}\n\t}\n\n\tpublic bool CanBenefitFromCover\n\t{\n\t\tget\n\t\t{\n\t\t\tif (category == ThingCategory.Pawn)\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif (building != null && building.IsTurret)\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool PotentiallySmeltable\n\t{\n\t\tget\n\t\t{\n\t\t\tif (!smeltable)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (base.MadeFromStuff)\n\t\t\t{\n\t\t\t\tforeach (ThingDef item in GenStuff.AllowedStuffsFor(this))\n\t\t\t\t{\n\t\t\t\t\tif (item.smeltable)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tpublic bool HasSingleOrMultipleInteractionCells\n\t{\n\t\tget\n\t\t{\n\t\t\tif (!hasInteractionCell)\n\t\t\t{\n\t\t\t\treturn !multipleInteractionCellOffsets.NullOrEmpty();\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tpublic bool IsApparel => apparel != null;\n\n\tpublic bool IsBed => typeof(Building_Bed).IsAssignableFrom(thingClass);\n\n\tpublic bool IsWall\n\t{\n\t\tget\n\t\t{\n\t\t\tif (building != null)\n\t\t\t{\n\t\t\t\treturn building.isWall;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsCorpse => typeof(Corpse).IsAssignableFrom(thingClass);\n\n\tpublic bool IsFrame => isFrameInt;\n\n\tpublic bool IsBlueprint\n\t{\n\t\tget\n\t\t{\n\t\t\tif (entityDefToBuild != null)\n\t\t\t{\n\t\t\t\treturn category == ThingCategory.Ethereal;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsStuff => stuffProps != null;\n\n\tpublic bool IsMedicine => statBases.StatListContains(StatDefOf.MedicalPotency);\n\n\tpublic bool IsDoor => typeof(Building_Door).IsAssignableFrom(thingClass);\n\n\tpublic bool IsFence\n\t{\n\t\tget\n\t\t{\n\t\t\tif (building != null)\n\t\t\t{\n\t\t\t\treturn building.isFence;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsFilth => filth != null;\n\n\tpublic bool IsIngestible => ingestible != null;\n\n\tpublic bool IsNutritionGivingIngestible\n\t{\n\t\tget\n\t\t{\n\t\t\tif (IsIngestible)\n\t\t\t{\n\t\t\t\treturn ingestible.CachedNutrition > 0f;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsNutritionGivingIngestibleForHumanlikeBabies\n\t{\n\t\tget\n\t\t{\n\t\t\tif (IsNutritionGivingIngestible && ingestible.HumanEdible)\n\t\t\t{\n\t\t\t\treturn ingestible.babiesCanIngest;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsWeapon\n\t{\n\t\tget\n\t\t{\n\t\t\tif (category == ThingCategory.Item && (!verbs.NullOrEmpty() || !tools.NullOrEmpty()))\n\t\t\t{\n\t\t\t\treturn !IsApparel;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsCommsConsole => typeof(Building_CommsConsole).IsAssignableFrom(thingClass);\n\n\tpublic bool IsOrbitalTradeBeacon => typeof(Building_OrbitalTradeBeacon).IsAssignableFrom(thingClass);\n\n\tpublic bool IsFoodDispenser => typeof(Building_NutrientPasteDispenser).IsAssignableFrom(thingClass);\n\n\tpublic bool IsDrug\n\t{\n\t\tget\n\t\t{\n\t\t\tif (ingestible != null)\n\t\t\t{\n\t\t\t\treturn ingestible.drugCategory != DrugCategory.None;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsPleasureDrug\n\t{\n\t\tget\n\t\t{\n\t\t\tif (IsDrug)\n\t\t\t{\n\t\t\t\treturn ingestible.joy > 0f;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsNonMedicalDrug\n\t{\n\t\tget\n\t\t{\n\t\t\tif (IsDrug)\n\t\t\t{\n\t\t\t\treturn ingestible.drugCategory != DrugCategory.Medical;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsTable\n\t{\n\t\tget\n\t\t{\n\t\t\tif (surfaceType == SurfaceType.Eat)\n\t\t\t{\n\t\t\t\treturn HasComp(typeof(CompGatherSpot));\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsWorkTable => typeof(Building_WorkTable).IsAssignableFrom(thingClass);\n\n\tpublic bool IsShell => projectileWhenLoaded != null;\n\n\tpublic bool IsArt => IsWithinCategory(ThingCategoryDefOf.BuildingsArt);\n\n\tpublic bool IsSmoothable => building?.smoothedThing != null;\n\n\tpublic bool IsSmoothed => building?.unsmoothedThing != null;\n\n\tpublic bool IsMetal\n\t{\n\t\tget\n\t\t{\n\t\t\tif (stuffProps != null)\n\t\t\t{\n\t\t\t\treturn stuffProps.categories.Contains(StuffCategoryDefOf.Metallic);\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsCryptosleepCasket => typeof(Building_CryptosleepCasket).IsAssignableFrom(thingClass);\n\n\tpublic bool IsGibbetCage => typeof(Building_GibbetCage).IsAssignableFrom(thingClass);\n\n\tpublic bool IsMechGestator => typeof(Building_MechGestator).IsAssignableFrom(thingClass);\n\n\tpublic bool IsMechRecharger => typeof(Building_MechCharger).IsAssignableFrom(thingClass);\n\n\tpublic bool IsAddictiveDrug\n\t{\n\t\tget\n\t\t{\n\t\t\tCompProperties_Drug compProperties = GetCompProperties();\n\t\t\tif (compProperties != null)\n\t\t\t{\n\t\t\t\treturn compProperties.addictiveness > 0f;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsMeat\n\t{\n\t\tget\n\t\t{\n\t\t\tif (category == ThingCategory.Item && thingCategories != null)\n\t\t\t{\n\t\t\t\treturn thingCategories.Contains(ThingCategoryDefOf.MeatRaw);\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsEgg\n\t{\n\t\tget\n\t\t{\n\t\t\tif (category == ThingCategory.Item && thingCategories != null)\n\t\t\t{\n\t\t\t\tif (!thingCategories.Contains(ThingCategoryDefOf.EggsFertilized))\n\t\t\t\t{\n\t\t\t\t\treturn thingCategories.Contains(ThingCategoryDefOf.EggsUnfertilized);\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsLeather\n\t{\n\t\tget\n\t\t{\n\t\t\tif (category == ThingCategory.Item && thingCategories != null)\n\t\t\t{\n\t\t\t\treturn thingCategories.Contains(ThingCategoryDefOf.Leathers);\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsWool\n\t{\n\t\tget\n\t\t{\n\t\t\tif (category == ThingCategory.Item && thingCategories != null)\n\t\t\t{\n\t\t\t\treturn thingCategories.Contains(ThingCategoryDefOf.Wools);\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsRangedWeapon\n\t{\n\t\tget\n\t\t{\n\t\t\tif (!IsWeapon)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (!verbs.NullOrEmpty())\n\t\t\t{\n\t\t\t\tfor (int i = 0; i < verbs.Count; i++)\n\t\t\t\t{\n\t\t\t\t\tif (!verbs[i].IsMeleeAttack)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsMeleeWeapon\n\t{\n\t\tget\n\t\t{\n\t\t\tif (IsWeapon)\n\t\t\t{\n\t\t\t\treturn !IsRangedWeapon;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsWeaponUsingProjectiles\n\t{\n\t\tget\n\t\t{\n\t\t\tif (!IsWeapon)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (!verbs.NullOrEmpty())\n\t\t\t{\n\t\t\t\tfor (int i = 0; i < verbs.Count; i++)\n\t\t\t\t{\n\t\t\t\t\tif (verbs[i].LaunchesProjectile)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsShieldThatBlocksRanged\n\t{\n\t\tget\n\t\t{\n\t\t\tif (HasComp(typeof(CompShield)))\n\t\t\t{\n\t\t\t\treturn GetCompProperties().blocksRangedWeapons;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsBuildingArtificial\n\t{\n\t\tget\n\t\t{\n\t\t\tif (category == ThingCategory.Building || IsFrame)\n\t\t\t{\n\t\t\t\tif (building != null)\n\t\t\t\t{\n\t\t\t\t\tif (!building.isNaturalRock)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn !building.isResourceRock;\n\t\t\t\t\t}\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsNonResourceNaturalRock\n\t{\n\t\tget\n\t\t{\n\t\t\tif (category == ThingCategory.Building && building.isNaturalRock && !building.isResourceRock && !building.mineablePreventNaturalRockOnSurface)\n\t\t\t{\n\t\t\t\treturn !IsSmoothed;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool HasSunShadows\n\t{\n\t\tget\n\t\t{\n\t\t\tif (!hasSunShadowsCached.HasValue)\n\t\t\t{\n\t\t\t\thasSunShadowsCached = typeof(Pawn).IsAssignableFrom(thingClass);\n\t\t\t}\n\t\t\treturn hasSunShadowsCached.Value;\n\t\t}\n\t}\n\n\tpublic bool IsNaturalOrgan\n\t{\n\t\tget\n\t\t{\n\t\t\tif (!isNaturalOrganCached.HasValue)\n\t\t\t{\n\t\t\t\tif (category != ThingCategory.Item)\n\t\t\t\t{\n\t\t\t\t\tisNaturalOrganCached = false;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tList allDefsListForReading = DefDatabase.AllDefsListForReading;\n\t\t\t\t\tisNaturalOrganCached = false;\n\t\t\t\t\tfor (int i = 0; i < allDefsListForReading.Count; i++)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (allDefsListForReading[i].spawnThingOnRemoved == this)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tisNaturalOrganCached = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn isNaturalOrganCached.Value;\n\t\t}\n\t}\n\n\tpublic bool IsFungus\n\t{\n\t\tget\n\t\t{\n\t\t\tif (ingestible != null)\n\t\t\t{\n\t\t\t\treturn ingestible.foodType.HasFlag(FoodTypeFlags.Fungus);\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsAnimalProduct\n\t{\n\t\tget\n\t\t{\n\t\t\tif (ingestible != null)\n\t\t\t{\n\t\t\t\treturn ingestible.foodType.HasFlag(FoodTypeFlags.AnimalProduct);\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsProcessedFood\n\t{\n\t\tget\n\t\t{\n\t\t\tif (ingestible != null)\n\t\t\t{\n\t\t\t\treturn ingestible.foodType.HasFlag(FoodTypeFlags.Processed);\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool CanAffectLinker\n\t{\n\t\tget\n\t\t{\n\t\t\tif (graphicData == null || !graphicData.Linked)\n\t\t\t{\n\t\t\t\treturn IsDoor;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tpublic bool IsNonDeconstructibleAttackableBuilding\n\t{\n\t\tget\n\t\t{\n\t\t\tif (IsBuildingArtificial && !building.IsDeconstructible && destroyable && !mineable && building.isTargetable)\n\t\t\t{\n\t\t\t\treturn building.draftAttackNonDeconstructable;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsPlant => typeof(Plant).IsAssignableFrom(thingClass);\n\n\tpublic bool IsDeadPlant => typeof(DeadPlant).IsAssignableFrom(thingClass);\n\n\tpublic bool IsStudiable => HasAssignableCompFrom(typeof(CompStudiable));\n\n\tpublic List RelevantStyleCategories\n\t{\n\t\tget\n\t\t{\n\t\t\tif (cachedRelevantStyleCategories == null)\n\t\t\t{\n\t\t\t\tcachedRelevantStyleCategories = new List();\n\t\t\t\tforeach (StyleCategoryDef allDef in DefDatabase.AllDefs)\n\t\t\t\t{\n\t\t\t\t\tif (allDef.thingDefStyles.NullOrEmpty())\n\t\t\t\t\t{\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tforeach (ThingDefStyle thingDefStyle in allDef.thingDefStyles)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (thingDefStyle.ThingDef == this)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcachedRelevantStyleCategories.Add(allDef);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn cachedRelevantStyleCategories;\n\t\t}\n\t}\n\n\tpublic string LabelAsStuff\n\t{\n\t\tget\n\t\t{\n\t\t\tif (!stuffProps.stuffAdjective.NullOrEmpty())\n\t\t\t{\n\t\t\t\treturn stuffProps.stuffAdjective;\n\t\t\t}\n\t\t\treturn label;\n\t\t}\n\t}\n\n\tpublic bool BlocksPlanting(bool canWipePlants = false)\n\t{\n\t\tif (building != null && building.SupportsPlants)\n\t\t{\n\t\t\treturn false;\n\t\t}\n\t\tif (building != null && building.isAttachment)\n\t\t{\n\t\t\treturn false;\n\t\t}\n\t\tif (blockPlants)\n\t\t{\n\t\t\treturn true;\n\t\t}\n\t\tif (!canWipePlants && category == ThingCategory.Plant)\n\t\t{\n\t\t\treturn true;\n\t\t}\n\t\tif ((int)Fillage > 0)\n\t\t{\n\t\t\treturn true;\n\t\t}\n\t\tif (this.IsEdifice())\n\t\t{\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\tpublic virtual bool CanSpawnAt(IntVec3 pos, Rot4 rot, Map map)\n\t{\n\t\treturn true;\n\t}\n\n\tpublic bool EverStorable(bool willMinifyIfPossible)\n\t{\n\t\tif (typeof(MinifiedThing).IsAssignableFrom(thingClass))\n\t\t{\n\t\t\treturn true;\n\t\t}\n\t\tif (!thingCategories.NullOrEmpty())\n\t\t{\n\t\t\tif (category == ThingCategory.Item)\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif (willMinifyIfPossible && Minifiable)\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\tpublic Thing GetConcreteExample(ThingDef stuff = null)\n\t{\n\t\tif (concreteExamplesInt == null)\n\t\t{\n\t\t\tconcreteExamplesInt = new Dictionary();\n\t\t}\n\t\tif (stuff == null)\n\t\t{\n\t\t\tstuff = ThingDefOf.Steel;\n\t\t}\n\t\tif (!concreteExamplesInt.ContainsKey(stuff))\n\t\t{\n\t\t\tif (race == null)\n\t\t\t{\n\t\t\t\tconcreteExamplesInt[stuff] = ThingMaker.MakeThing(this, base.MadeFromStuff ? stuff : null);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tconcreteExamplesInt[stuff] = PawnGenerator.GeneratePawn(DefDatabase.AllDefsListForReading.FirstOrDefault((PawnKindDef pkd) => pkd.race == this));\n\t\t\t}\n\t\t}\n\t\treturn concreteExamplesInt[stuff];\n\t}\n\n\tpublic CompProperties CompDefFor() where T : ThingComp\n\t{\n\t\tfor (int i = 0; i < comps.Count; i++)\n\t\t{\n\t\t\tif (comps[i].compClass == typeof(T))\n\t\t\t{\n\t\t\t\treturn comps[i];\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\n\n\tpublic CompProperties CompDefForAssignableFrom() where T : ThingComp\n\t{\n\t\tfor (int i = 0; i < comps.Count; i++)\n\t\t{\n\t\t\tif (typeof(T).IsAssignableFrom(comps[i].compClass))\n\t\t\t{\n\t\t\t\treturn comps[i];\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\n\n\tpublic bool HasComp(Type compType)\n\t{\n\t\tfor (int i = 0; i < comps.Count; i++)\n\t\t{\n\t\t\tif (comps[i].compClass == compType)\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\tpublic bool HasComp() where T : ThingComp\n\t{\n\t\tfor (int i = 0; i < comps.Count; i++)\n\t\t{\n\t\t\tif (comps[i].compClass == typeof(T) || typeof(T).IsAssignableFrom(comps[i].compClass))\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\tpublic bool HasAssignableCompFrom(Type compType)\n\t{\n\t\tfor (int i = 0; i < comps.Count; i++)\n\t\t{\n\t\t\tif (compType.IsAssignableFrom(comps[i].compClass))\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\tpublic T GetCompProperties() where T : CompProperties\n\t{\n\t\tfor (int i = 0; i < comps.Count; i++)\n\t\t{\n\t\t\tif (comps[i] is T result)\n\t\t\t{\n\t\t\t\treturn result;\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\n\n\tpublic override void PostLoad()\n\t{\n\t\tif (graphicData != null)\n\t\t{\n\t\t\tLongEventHandler.ExecuteWhenFinished(delegate\n\t\t\t{\n\t\t\t\tGraphicData graphicData = this.graphicData;\n\t\t\t\tif (graphicData.shaderType == null)\n\t\t\t\t{\n\t\t\t\t\tgraphicData.shaderType = ShaderTypeDefOf.Cutout;\n\t\t\t\t}\n\t\t\t\tContentFinderRequester.requester = this;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tgraphic = this.graphicData.Graphic;\n\t\t\t\t\tif (drawerType != DrawerType.RealtimeOnly)\n\t\t\t\t\t{\n\t\t\t\t\t\tTextureAtlasGroup textureAtlasGroup = category.ToAtlasGroup();\n\t\t\t\t\t\tgraphic.TryInsertIntoAtlas(textureAtlasGroup);\n\t\t\t\t\t\tif (textureAtlasGroup == TextureAtlasGroup.Building && Minifiable)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tgraphic.TryInsertIntoAtlas(TextureAtlasGroup.Item);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfinally\n\t\t\t\t{\n\t\t\t\t\tContentFinderRequester.requester = null;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\tif (tools != null)\n\t\t{\n\t\t\tfor (int i = 0; i < tools.Count; i++)\n\t\t\t{\n\t\t\t\ttools[i].id = i.ToString();\n\t\t\t}\n\t\t}\n\t\tif (verbs != null && verbs.Count == 1 && verbs[0].label.NullOrEmpty())\n\t\t{\n\t\t\tverbs[0].label = label;\n\t\t}\n\t\tbase.PostLoad();\n\t\tif (category == ThingCategory.Building && building == null)\n\t\t{\n\t\t\tbuilding = new BuildingProperties();\n\t\t}\n\t\tbuilding?.PostLoadSpecial(this);\n\t\tapparel?.PostLoadSpecial(this);\n\t\tplant?.PostLoadSpecial(this);\n\t\tif (comps == null)\n\t\t{\n\t\t\treturn;\n\t\t}\n\t\tforeach (CompProperties comp in comps)\n\t\t{\n\t\t\tcomp.PostLoadSpecial(this);\n\t\t}\n\t}\n\n\tprotected override void ResolveIcon()\n\t{\n\t\tbase.ResolveIcon();\n\t\tif (category == ThingCategory.Pawn)\n\t\t{\n\t\t\tif (!uiIconPath.NullOrEmpty())\n\t\t\t{\n\t\t\t\tuiIcon = ContentFinder.Get(uiIconPath);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (race.Humanlike)\n\t\t\t\t{\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tPawnKindDef anyPawnKind = race.AnyPawnKind;\n\t\t\t\tif (anyPawnKind != null)\n\t\t\t\t{\n\t\t\t\t\tMaterial material = ((ModsConfig.BiotechActive && anyPawnKind.RaceProps.IsMechanoid) ? anyPawnKind.lifeStages.First() : anyPawnKind.lifeStages.Last()).bodyGraphicData.Graphic.MatAt(Rot4.East);\n\t\t\t\t\tuiIcon = (Texture2D)material.mainTexture;\n\t\t\t\t\tuiIconColor = material.color;\n\t\t\t\t\tif (ShaderDatabase.TryGetUIShader(material.shader, out var uiShader) && MaterialPool.TryGetRequestForMat(material, out var request))\n\t\t\t\t\t{\n\t\t\t\t\t\trequest.shader = uiShader;\n\t\t\t\t\t\tuiIconMaterial = MaterialPool.MatFrom(request);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tThingDef thingDef = GenStuff.DefaultStuffFor(this);\n\t\t\tif (colorGenerator != null && (thingDef == null || thingDef.stuffProps.allowColorGenerators))\n\t\t\t{\n\t\t\t\tuiIconColor = colorGenerator.ExemplaryColor;\n\t\t\t}\n\t\t\telse if (thingDef != null)\n\t\t\t{\n\t\t\t\tuiIconColor = GetColorForStuff(thingDef);\n\t\t\t}\n\t\t\telse if (graphicData != null)\n\t\t\t{\n\t\t\t\tuiIconColor = graphicData.color;\n\t\t\t}\n\t\t\tif (rotatable && graphic != null && graphic != BaseContent.BadGraphic && graphic.ShouldDrawRotated && defaultPlacingRot == Rot4.South)\n\t\t\t{\n\t\t\t\tuiIconAngle = 180f + graphic.DrawRotatedExtraAngleOffset;\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic override void ResolveReferences()\n\t{\n\t\tbase.ResolveReferences();\n\t\tif (ingestible != null)\n\t\t{\n\t\t\tingestible.parent = this;\n\t\t}\n\t\tif (stuffProps != null)\n\t\t{\n\t\t\tstuffProps.parent = this;\n\t\t}\n\t\tbuilding?.ResolveReferencesSpecial();\n\t\tgraphicData?.ResolveReferencesSpecial();\n\t\trace?.ResolveReferencesSpecial();\n\t\tstuffProps?.ResolveReferencesSpecial();\n\t\tapparel?.ResolveReferencesSpecial();\n\t\tif (soundImpactDefault == null)\n\t\t{\n\t\t\tsoundImpactDefault = SoundDefOf.BulletImpact_Ground;\n\t\t}\n\t\tif (soundDrop == null)\n\t\t{\n\t\t\tsoundDrop = SoundDefOf.Standard_Drop;\n\t\t}\n\t\tif (soundPickup == null)\n\t\t{\n\t\t\tsoundPickup = SoundDefOf.Standard_Pickup;\n\t\t}\n\t\tif (soundInteract == null)\n\t\t{\n\t\t\tsoundInteract = SoundDefOf.Standard_Pickup;\n\t\t}\n\t\tif (inspectorTabs != null && inspectorTabs.Any())\n\t\t{\n\t\t\tinspectorTabsResolved = new List();\n\t\t\tfor (int i = 0; i < inspectorTabs.Count; i++)\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tinspectorTabsResolved.Add(InspectTabManager.GetSharedInstance(inspectorTabs[i]));\n\t\t\t\t}\n\t\t\t\tcatch (Exception ex)\n\t\t\t\t{\n\t\t\t\t\tLog.Error(\"Could not instantiate inspector tab of type \" + inspectorTabs[i]?.ToString() + \": \" + ex);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (comps != null)\n\t\t{\n\t\t\tfor (int j = 0; j < comps.Count; j++)\n\t\t\t{\n\t\t\t\tcomps[j].ResolveReferences(this);\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic override IEnumerable ConfigErrors()\n\t{\n\t\tforeach (string item in base.ConfigErrors())\n\t\t{\n\t\t\tyield return item;\n\t\t}\n\t\tif (category != ThingCategory.Ethereal && label.NullOrEmpty())\n\t\t{\n\t\t\tyield return \"no label\";\n\t\t}\n\t\tif (category == ThingCategory.Building && !IsFrame && building.IsDeconstructible && thingClass != null && typeof(Building).IsSubclassOf(thingClass))\n\t\t{\n\t\t\tyield return \"has building category and is marked as deconstructible, but thing class is not a subclass of building (\" + thingClass.Name + \")\";\n\t\t}\n\t\tif (graphicData != null)\n\t\t{\n\t\t\tforeach (string item2 in graphicData.ConfigErrors(this))\n\t\t\t{\n\t\t\t\tyield return item2;\n\t\t\t}\n\t\t}\n\t\tif (projectile != null)\n\t\t{\n\t\t\tforeach (string item3 in projectile.ConfigErrors(this))\n\t\t\t{\n\t\t\t\tyield return item3;\n\t\t\t}\n\t\t}\n\t\tif (statBases != null)\n\t\t{\n\t\t\tforeach (StatModifier statBase in statBases)\n\t\t\t{\n\t\t\t\tif (statBases.Count((StatModifier st) => st.stat == statBase.stat) > 1)\n\t\t\t\t{\n\t\t\t\t\tyield return \"defines the stat base \" + statBase.stat?.ToString() + \" more than once.\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (!BeautyUtility.BeautyRelevant(category) && this.StatBaseDefined(StatDefOf.Beauty))\n\t\t{\n\t\t\tyield return \"Beauty stat base is defined, but Things of category \" + category.ToString() + \" cannot have beauty.\";\n\t\t}\n\t\tif (!BeautyUtility.BeautyRelevant(category) && this.StatBaseDefined(StatDefOf.BeautyOutdoors))\n\t\t{\n\t\t\tyield return \"BeautyOutdoors stat base is defined, but Things of category \" + category.ToString() + \" cannot have beauty.\";\n\t\t}\n\t\tif (char.IsNumber(defName[defName.Length - 1]))\n\t\t{\n\t\t\tyield return \"ends with a numerical digit, which is not allowed on ThingDefs.\";\n\t\t}\n\t\tif (thingClass == null)\n\t\t{\n\t\t\tyield return \"has null thingClass.\";\n\t\t}\n\t\tif (comps.Count > 0 && !typeof(ThingWithComps).IsAssignableFrom(thingClass))\n\t\t{\n\t\t\tyield return \"has components but it's thingClass is not a ThingWithComps\";\n\t\t}\n\t\tif (ConnectToPower && drawerType == DrawerType.RealtimeOnly && IsFrame)\n\t\t{\n\t\t\tyield return \"connects to power but does not add to map mesh. Will not create wire meshes.\";\n\t\t}\n\t\tif (costList != null)\n\t\t{\n\t\t\tforeach (ThingDefCountClass cost in costList)\n\t\t\t{\n\t\t\t\tif (cost.count == 0)\n\t\t\t\t{\n\t\t\t\t\tyield return \"cost in \" + cost.thingDef?.ToString() + \" is zero.\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tThingCategoryDef thingCategoryDef = thingCategories?.FirstOrDefault((ThingCategoryDef cat) => thingCategories.Count((ThingCategoryDef c) => c == cat) > 1);\n\t\tif (thingCategoryDef != null)\n\t\t{\n\t\t\tyield return \"has duplicate thingCategory \" + thingCategoryDef?.ToString() + \".\";\n\t\t}\n\t\tif (Fillage == FillCategory.Full && category != ThingCategory.Building)\n\t\t{\n\t\t\tyield return \"gives full cover but is not a building.\";\n\t\t}\n\t\tif (equipmentType != 0)\n\t\t{\n\t\t\tif (techLevel == TechLevel.Undefined && !destroyOnDrop)\n\t\t\t{\n\t\t\t\tyield return \"is equipment but has no tech level.\";\n\t\t\t}\n\t\t\tif (!comps.Any((CompProperties c) => typeof(CompEquippable).IsAssignableFrom(c.compClass)))\n\t\t\t{\n\t\t\t\tyield return \"is equipment but has no CompEquippable\";\n\t\t\t}\n\t\t}\n\t\tif (thingClass == typeof(Bullet) && projectile.damageDef == null)\n\t\t{\n\t\t\tyield return \" is a bullet but has no damageDef.\";\n\t\t}\n\t\tif (destroyOnDrop && tradeability != 0)\n\t\t{\n\t\t\tyield return \"destroyOnDrop but tradeability is \" + tradeability;\n\t\t}\n\t\tif (stackLimit > 1 && !drawGUIOverlay)\n\t\t{\n\t\t\tyield return \"has stackLimit > 1 but also has drawGUIOverlay = false.\";\n\t\t}\n\t\tif (damageMultipliers != null)\n\t\t{\n\t\t\tforeach (DamageMultiplier mult in damageMultipliers)\n\t\t\t{\n\t\t\t\tif (damageMultipliers.Count((DamageMultiplier m) => m.damageDef == mult.damageDef) > 1)\n\t\t\t\t{\n\t\t\t\t\tyield return \"has multiple damage multipliers for damageDef \" + mult.damageDef;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (Fillage == FillCategory.Full && !this.IsEdifice())\n\t\t{\n\t\t\tyield return \"fillPercent is 1.00 but is not edifice\";\n\t\t}\n\t\tif (base.MadeFromStuff && constructEffect != null)\n\t\t{\n\t\t\tyield return \"madeFromStuff but has a defined constructEffect (which will always be overridden by stuff's construct animation).\";\n\t\t}\n\t\tif (base.MadeFromStuff && stuffCategories.NullOrEmpty())\n\t\t{\n\t\t\tyield return \"madeFromStuff but has no stuffCategories.\";\n\t\t}\n\t\tif (costList.NullOrEmpty() && costStuffCount <= 0 && recipeMaker != null)\n\t\t{\n\t\t\tyield return \"has a recipeMaker but no costList or costStuffCount.\";\n\t\t}\n\t\tif (costStuffCount > 0 && stuffCategories.NullOrEmpty())\n\t\t{\n\t\t\tyield return \"has costStuffCount but no stuffCategories.\";\n\t\t}\n\t\tif (this.GetStatValueAbstract(StatDefOf.DeteriorationRate) > 1E-05f && !CanEverDeteriorate && !destroyOnDrop)\n\t\t{\n\t\t\tyield return \"has >0 DeteriorationRate but can't deteriorate.\";\n\t\t}\n\t\tif (smeltProducts != null && !smeltable)\n\t\t{\n\t\t\tyield return \"has smeltProducts but has smeltable=false\";\n\t\t}\n\t\tif (smeltable && smeltProducts.NullOrEmpty() && base.CostList.NullOrEmpty() && !IsStuff && !base.MadeFromStuff && !destroyOnDrop)\n\t\t{\n\t\t\tyield return \"is smeltable but does not give anything for smelting.\";\n\t\t}\n\t\tif (equipmentType != 0 && verbs.NullOrEmpty() && tools.NullOrEmpty())\n\t\t{\n\t\t\tyield return \"is equipment but has no verbs or tools\";\n\t\t}\n\t\tif (Minifiable && thingCategories.NullOrEmpty())\n\t\t{\n\t\t\tyield return \"is minifiable but not in any thing category\";\n\t\t}\n\t\tif (category == ThingCategory.Building && !Minifiable && !thingCategories.NullOrEmpty())\n\t\t{\n\t\t\tyield return \"is not minifiable yet has thing categories (could be confusing in thing filters because it can't be moved/stored anyway)\";\n\t\t}\n\t\tif (!destroyOnDrop && !typeof(MinifiedThing).IsAssignableFrom(thingClass) && (EverHaulable || Minifiable) && (statBases.NullOrEmpty() || !statBases.Any((StatModifier s) => s.stat == StatDefOf.Mass)))\n\t\t{\n\t\t\tyield return \"is haulable, but does not have an authored mass value\";\n\t\t}\n\t\tif (ingestible == null && this.GetStatValueAbstract(StatDefOf.Nutrition) != 0f)\n\t\t{\n\t\t\tyield return \"has nutrition but ingestible properties are null\";\n\t\t}\n\t\tif (BaseFlammability != 0f && !useHitPoints && category != ThingCategory.Pawn && !destroyOnDrop)\n\t\t{\n\t\t\tyield return \"flammable but has no hitpoints (will burn indefinitely)\";\n\t\t}\n\t\tif (graphicData?.shadowData != null && staticSunShadowHeight > 0f)\n\t\t{\n\t\t\tyield return \"graphicData defines a shadowInfo but staticSunShadowHeight > 0\";\n\t\t}\n\t\tif (saveCompressible && Claimable)\n\t\t{\n\t\t\tyield return \"claimable item is compressible; faction will be unset after load\";\n\t\t}\n\t\tif (deepCommonality > 0f != deepLumpSizeRange.TrueMax > 0)\n\t\t{\n\t\t\tyield return \"if deepCommonality or deepLumpSizeRange is set, the other also must be set\";\n\t\t}\n\t\tif (deepCommonality > 0f && deepCountPerPortion <= 0)\n\t\t{\n\t\t\tyield return \"deepCommonality > 0 but deepCountPerPortion is not set\";\n\t\t}\n\t\tif (verbs != null)\n\t\t{\n\t\t\tfor (int i = 0; i < verbs.Count; i++)\n\t\t\t{\n\t\t\t\tforeach (string item4 in verbs[i].ConfigErrors(this))\n\t\t\t\t{\n\t\t\t\t\tyield return $\"verb {i}: {item4}\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (building != null)\n\t\t{\n\t\t\tforeach (string item5 in building.ConfigErrors(this))\n\t\t\t{\n\t\t\t\tyield return item5;\n\t\t\t}\n\t\t\tif ((building.isAirtight || building.isStuffableAirtight) && Fillage != FillCategory.Full)\n\t\t\t{\n\t\t\t\tyield return \"is airtight but Fillage is not Full\";\n\t\t\t}\n\t\t}\n\t\tif (apparel != null)\n\t\t{\n\t\t\tforeach (string item6 in apparel.ConfigErrors(this))\n\t\t\t{\n\t\t\t\tyield return item6;\n\t\t\t}\n\t\t}\n\t\tif (comps != null)\n\t\t{\n\t\t\tfor (int i = 0; i < comps.Count; i++)\n\t\t\t{\n\t\t\t\tforeach (string item7 in comps[i].ConfigErrors(this))\n\t\t\t\t{\n\t\t\t\t\tyield return item7;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (race != null)\n\t\t{\n\t\t\tforeach (string item8 in race.ConfigErrors(this))\n\t\t\t{\n\t\t\t\tyield return item8;\n\t\t\t}\n\t\t\tif (race.body != null && race != null && tools != null)\n\t\t\t{\n\t\t\t\tint i;\n\t\t\t\tfor (i = 0; i < tools.Count; i++)\n\t\t\t\t{\n\t\t\t\t\tif (tools[i].linkedBodyPartsGroup != null && !race.body.AllParts.Any((BodyPartRecord part) => part.groups.Contains(tools[i].linkedBodyPartsGroup)))\n\t\t\t\t\t{\n\t\t\t\t\t\tyield return \"has tool with linkedBodyPartsGroup \" + tools[i].linkedBodyPartsGroup?.ToString() + \" but body \" + race.body?.ToString() + \" has no parts with that group.\";\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (race.Animal && this.GetStatValueAbstract(StatDefOf.Wildness) < 0f)\n\t\t\t{\n\t\t\t\tyield return \"is animal but wildness is not defined\";\n\t\t\t}\n\t\t}\n\t\tif (ingestible != null)\n\t\t{\n\t\t\tforeach (string item9 in ingestible.ConfigErrors())\n\t\t\t{\n\t\t\t\tyield return item9;\n\t\t\t}\n\t\t}\n\t\tif (plant != null)\n\t\t{\n\t\t\tforeach (string item10 in plant.ConfigErrors())\n\t\t\t{\n\t\t\t\tyield return item10;\n\t\t\t}\n\t\t}\n\t\tif (tools != null)\n\t\t{\n\t\t\tTool tool = tools.SelectMany((Tool lhs) => tools.Where((Tool rhs) => lhs != rhs && lhs.id == rhs.id)).FirstOrDefault();\n\t\t\tif (tool != null)\n\t\t\t{\n\t\t\t\tyield return \"duplicate thingdef tool id \" + tool.id;\n\t\t\t}\n\t\t\tforeach (Tool tool2 in tools)\n\t\t\t{\n\t\t\t\tforeach (string item11 in tool2.ConfigErrors())\n\t\t\t\t{\n\t\t\t\t\tyield return item11;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (!randomStyle.NullOrEmpty())\n\t\t{\n\t\t\tforeach (ThingStyleChance item12 in randomStyle)\n\t\t\t{\n\t\t\t\tif (item12.Chance <= 0f)\n\t\t\t\t{\n\t\t\t\t\tyield return \"style chance <= 0.\";\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!comps.Any((CompProperties c) => c.compClass == typeof(CompStyleable)))\n\t\t\t{\n\t\t\t\tyield return \"random style assigned, but missing CompStyleable!\";\n\t\t\t}\n\t\t}\n\t\tif (relicChance > 0f && category != ThingCategory.Item)\n\t\t{\n\t\t\tyield return \"relic chance > 0 but category != item\";\n\t\t}\n\t\tif (hasInteractionCell && !multipleInteractionCellOffsets.NullOrEmpty())\n\t\t{\n\t\t\tyield return \"both single and multiple interaction cells are defined, it should be one or the other\";\n\t\t}\n\t\tif (Fillage != FillCategory.Full && passability == Traversability.Impassable && !IsDoor && base.BuildableByPlayer && !disableImpassableShotOverConfigError)\n\t\t{\n\t\t\tyield return \"impassable, player-buildable building that can be shot/seen over.\";\n\t\t}\n\t}\n\n\tpublic static ThingDef Named(string defName)\n\t{\n\t\treturn DefDatabase.GetNamed(defName);\n\t}\n\n\tpublic bool IsWithinCategory(ThingCategoryDef category)\n\t{\n\t\tif (thingCategories == null)\n\t\t{\n\t\t\treturn false;\n\t\t}\n\t\tfor (int i = 0; i < thingCategories.Count; i++)\n\t\t{\n\t\t\tfor (ThingCategoryDef thingCategoryDef = thingCategories[i]; thingCategoryDef != null; thingCategoryDef = thingCategoryDef.parent)\n\t\t\t{\n\t\t\t\tif (thingCategoryDef == category)\n\t\t\t\t{\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\tpublic void Notify_UnlockedByResearch()\n\t{\n\t\tif (comps != null)\n\t\t{\n\t\t\tfor (int i = 0; i < comps.Count; i++)\n\t\t\t{\n\t\t\t\tcomps[i].Notify_PostUnlockedByResearch(this);\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic override IEnumerable SpecialDisplayStats(StatRequest req)\n\t{\n\t\tforeach (StatDrawEntry item in base.SpecialDisplayStats(req))\n\t\t{\n\t\t\tyield return item;\n\t\t}\n\t\tif (apparel != null)\n\t\t{\n\t\t\tstring coveredOuterPartsString = apparel.GetCoveredOuterPartsString(BodyDefOf.Human);\n\t\t\tyield return new StatDrawEntry(StatCategoryDefOf.Apparel, \"Covers\".Translate(), coveredOuterPartsString, \"Stat_Thing_Apparel_Covers_Desc\".Translate(), 2750);\n\t\t\tyield return new StatDrawEntry(StatCategoryDefOf.Apparel, \"Layer\".Translate(), apparel.GetLayersString(), \"Stat_Thing_Apparel_Layer_Desc\".Translate(), 2751);\n\t\t\tyield return new StatDrawEntry(StatCategoryDefOf.Apparel, \"Stat_Thing_Apparel_CountsAsClothingNudity_Name\".Translate(), apparel.countsAsClothingForNudity ? \"Yes\".Translate() : \"No\".Translate(), \"Stat_Thing_Apparel_CountsAsClothingNudity_Desc\".Translate(), 2753);\n\t\t\tif (ModsConfig.BiotechActive)\n\t\t\t{\n\t\t\t\tyield return new StatDrawEntry(StatCategoryDefOf.Apparel, \"Stat_Thing_Apparel_ValidLifestage\".Translate(), apparel.developmentalStageFilter.ToCommaList().CapitalizeFirst(), \"Stat_Thing_Apparel_ValidLifestage_Desc\".Translate(), 2748);\n\t\t\t}\n\t\t\tif (apparel.gender != 0)\n\t\t\t{\n\t\t\t\tyield return new StatDrawEntry(StatCategoryDefOf.Apparel, \"Stat_Thing_Apparel_Gender\".Translate(), apparel.gender.GetLabel().CapitalizeFirst(), \"Stat_Thing_Apparel_Gender_Desc\".Translate(), 2749);\n\t\t\t}\n\t\t}\n\t\tif (IsMedicine && MedicineTendXpGainFactor != 1f)\n\t\t{\n\t\t\tyield return new StatDrawEntry(StatCategoryDefOf.Basics, \"MedicineXpGainFactor\".Translate(), MedicineTendXpGainFactor.ToStringPercent(), \"Stat_Thing_Drug_MedicineXpGainFactor_Desc\".Translate(), 1000);\n\t\t}\n\t\tif (fillPercent > 0f && (category == ThingCategory.Item || category == ThingCategory.Building || category == ThingCategory.Plant))\n\t\t{\n\t\t\tyield return new StatDrawEntry(StatCategoryDefOf.Basics, \"CoverEffectiveness\".Translate(), this.BaseBlockChance().ToStringPercent(), \"CoverEffectivenessExplanation\".Translate(), 2000);\n\t\t}\n\t\tif (constructionSkillPrerequisite > 0)\n\t\t{\n\t\t\tyield return new StatDrawEntry(StatCategoryDefOf.Basics, \"SkillRequiredToBuild\".Translate(SkillDefOf.Construction.LabelCap), constructionSkillPrerequisite.ToString(), \"SkillRequiredToBuildExplanation\".Translate(SkillDefOf.Construction.LabelCap), 1100);\n\t\t}\n\t\tif (artisticSkillPrerequisite > 0)\n\t\t{\n\t\t\tyield return new StatDrawEntry(StatCategoryDefOf.Basics, \"SkillRequiredToBuild\".Translate(SkillDefOf.Artistic.LabelCap), artisticSkillPrerequisite.ToString(), \"SkillRequiredToBuildExplanation\".Translate(SkillDefOf.Artistic.LabelCap), 1100);\n\t\t}\n\t\tIEnumerable recipes = DefDatabase.AllDefsListForReading.Where((RecipeDef r) => r.products.Count == 1 && r.products.Any((ThingDefCountClass p) => p.thingDef == this) && !r.IsSurgery);\n\t\tif (recipes.Any())\n\t\t{\n\t\t\tIEnumerable enumerable = (from u in recipes.Where((RecipeDef x) => x.recipeUsers != null).SelectMany((RecipeDef r) => r.recipeUsers)\n\t\t\t\tselect u.label).Concat(from x in DefDatabase.AllDefsListForReading\n\t\t\t\twhere x.recipes != null && x.recipes.Any((RecipeDef y) => y.products.Any((ThingDefCountClass z) => z.thingDef == this))\n\t\t\t\tselect x.label).Distinct();\n\t\t\tif (enumerable.Any())\n\t\t\t{\n\t\t\t\tyield return new StatDrawEntry(StatCategoryDefOf.Basics, \"CreatedAt\".Translate(), enumerable.ToCommaList().CapitalizeFirst(), \"Stat_Thing_CreatedAt_Desc\".Translate(), 1103);\n\t\t\t}\n\t\t\tRecipeDef recipeDef = recipes.FirstOrDefault();\n\t\t\tif (recipeDef != null && !recipeDef.ingredients.NullOrEmpty())\n\t\t\t{\n\t\t\t\tBuildableDef.tmpCostList.Clear();\n\t\t\t\tBuildableDef.tmpHyperlinks.Clear();\n\t\t\t\tfor (int j = 0; j < recipeDef.ingredients.Count; j++)\n\t\t\t\t{\n\t\t\t\t\tIngredientCount ingredientCount = recipeDef.ingredients[j];\n\t\t\t\t\tif (ingredientCount.filter.Summary.NullOrEmpty())\n\t\t\t\t\t{\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tIEnumerable allowedThingDefs = ingredientCount.filter.AllowedThingDefs;\n\t\t\t\t\tif (allowedThingDefs.Any())\n\t\t\t\t\t{\n\t\t\t\t\t\tforeach (ThingDef p in allowedThingDefs)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (!BuildableDef.tmpHyperlinks.Any((Dialog_InfoCard.Hyperlink x) => x.def == p))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tBuildableDef.tmpHyperlinks.Add(new Dialog_InfoCard.Hyperlink(p));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tBuildableDef.tmpCostList.Add(recipeDef.IngredientValueGetter.BillRequirementsDescription(recipeDef, ingredientCount));\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (BuildableDef.tmpCostList.Any())\n\t\t\t{\n\t\t\t\tyield return new StatDrawEntry(StatCategoryDefOf.Basics, \"Ingredients\".Translate(), BuildableDef.tmpCostList.ToCommaList(), \"Stat_Thing_Ingredients\".Translate(), 1102, null, BuildableDef.tmpHyperlinks);\n\t\t\t}\n\t\t}\n\t\tif (thingClass != null && typeof(Building_Bed).IsAssignableFrom(thingClass) && !statBases.StatListContains(StatDefOf.BedRestEffectiveness))\n\t\t{\n\t\t\tyield return new StatDrawEntry(StatCategoryDefOf.Building, StatDefOf.BedRestEffectiveness, StatDefOf.BedRestEffectiveness.valueIfMissing, StatRequest.ForEmpty());\n\t\t}\n\t\tif (!verbs.NullOrEmpty())\n\t\t{\n\t\t\tVerbProperties verb = verbs.First((VerbProperties x) => x.isPrimary);\n\t\t\tStatCategoryDef verbStatCategory = ((category == ThingCategory.Pawn) ? StatCategoryDefOf.PawnCombat : null);\n\t\t\tfloat num = verb.warmupTime;\n\t\t\tStringBuilder stringBuilder = new StringBuilder(\"Stat_Thing_Weapon_RangedWarmupTime_Desc\".Translate());\n\t\t\tstringBuilder.AppendLine();\n\t\t\tstringBuilder.AppendLine();\n\t\t\tstringBuilder.AppendLine(\"StatsReport_BaseValue\".Translate() + \": \" + num.ToString(\"0.##\") + \" \" + \"LetterSecond\".Translate());\n\t\t\tif (num > 0f)\n\t\t\t{\n\t\t\t\tif (req.HasThing)\n\t\t\t\t{\n\t\t\t\t\tfloat statValue = req.Thing.GetStatValue(StatDefOf.RangedWeapon_WarmupMultiplier);\n\t\t\t\t\tnum *= statValue;\n\t\t\t\t\tif (!Mathf.Approximately(statValue, 1f))\n\t\t\t\t\t{\n\t\t\t\t\t\tstringBuilder.AppendLine();\n\t\t\t\t\t\tstringBuilder.AppendLine(\"Stat_Thing_Weapon_WarmupTime_Multiplier\".Translate() + \": x\" + statValue.ToStringPercent());\n\t\t\t\t\t\tstringBuilder.Append(StatUtility.GetOffsetsAndFactorsFor(StatDefOf.RangedWeapon_WarmupMultiplier, req.Thing));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tstringBuilder.AppendLine();\n\t\t\t\tstringBuilder.AppendLine(\"StatsReport_FinalValue\".Translate() + \": \" + num.ToString(\"0.##\") + \" \" + \"LetterSecond\".Translate());\n\t\t\t\tyield return new StatDrawEntry(verbStatCategory ?? StatCategoryDefOf.Weapon_Ranged, \"RangedWarmupTime\".Translate(), num.ToString(\"0.##\") + \" \" + \"LetterSecond\".Translate(), stringBuilder.ToString(), 3555);\n\t\t\t}\n\t\t\tif (verb.defaultProjectile?.projectile.damageDef != null && verb.defaultProjectile.projectile.damageDef.harmsHealth)\n\t\t\t{\n\t\t\t\tStatCategoryDef statCat = verbStatCategory ?? StatCategoryDefOf.Weapon_Ranged;\n\t\t\t\tStringBuilder stringBuilder2 = new StringBuilder();\n\t\t\t\tstringBuilder2.AppendLine(\"Stat_Thing_Damage_Desc\".Translate());\n\t\t\t\tstringBuilder2.AppendLine();\n\t\t\t\tfloat num2 = verb.defaultProjectile.projectile.GetDamageAmount(req.Thing, stringBuilder2);\n\t\t\t\tyield return new StatDrawEntry(statCat, \"Damage\".Translate(), num2.ToString(), stringBuilder2.ToString(), 5500);\n\t\t\t\tif (verb.defaultProjectile.projectile.damageDef.armorCategory != null)\n\t\t\t\t{\n\t\t\t\t\tStringBuilder stringBuilder3 = new StringBuilder();\n\t\t\t\t\tfloat armorPenetration = verb.defaultProjectile.projectile.GetArmorPenetration(req.Thing, stringBuilder3);\n\t\t\t\t\tTaggedString taggedString = \"ArmorPenetrationExplanation\".Translate();\n\t\t\t\t\tif (stringBuilder3.Length != 0)\n\t\t\t\t\t{\n\t\t\t\t\t\ttaggedString += \"\\n\\n\" + stringBuilder3;\n\t\t\t\t\t}\n\t\t\t\t\tyield return new StatDrawEntry(statCat, \"ArmorPenetration\".Translate(), armorPenetration.ToStringPercent(), taggedString, 5400);\n\t\t\t\t}\n\t\t\t\tfloat buildingDamageFactor = verb.defaultProjectile.projectile.damageDef.buildingDamageFactor;\n\t\t\t\tfloat dmgBuildingsImpassable = verb.defaultProjectile.projectile.damageDef.buildingDamageFactorImpassable;\n\t\t\t\tfloat dmgBuildingsPassable = verb.defaultProjectile.projectile.damageDef.buildingDamageFactorPassable;\n\t\t\t\tif (buildingDamageFactor != 1f)\n\t\t\t\t{\n\t\t\t\t\tyield return new StatDrawEntry(statCat, \"BuildingDamageFactor\".Translate(), buildingDamageFactor.ToStringPercent(), \"BuildingDamageFactorExplanation\".Translate(), 5410);\n\t\t\t\t}\n\t\t\t\tif (dmgBuildingsImpassable != 1f)\n\t\t\t\t{\n\t\t\t\t\tyield return new StatDrawEntry(statCat, \"BuildingDamageFactorImpassable\".Translate(), dmgBuildingsImpassable.ToStringPercent(), \"BuildingDamageFactorImpassableExplanation\".Translate(), 5420);\n\t\t\t\t}\n\t\t\t\tif (dmgBuildingsPassable != 1f)\n\t\t\t\t{\n\t\t\t\t\tyield return new StatDrawEntry(statCat, \"BuildingDamageFactorPassable\".Translate(), dmgBuildingsPassable.ToStringPercent(), \"BuildingDamageFactorPassableExplanation\".Translate(), 5430);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (verb.defaultProjectile == null && verb.beamDamageDef != null)\n\t\t\t{\n\t\t\t\tyield return new StatDrawEntry(verbStatCategory ?? StatCategoryDefOf.Weapon_Ranged, \"ArmorPenetration\".Translate(), verb.beamDamageDef.defaultArmorPenetration.ToStringPercent(), \"ArmorPenetrationExplanation\".Translate(), 5400);\n\t\t\t}\n\t\t\tif (verb.Ranged)\n\t\t\t{\n\t\t\t\tfloat num3 = verb.burstShotCount;\n\t\t\t\tfloat num4 = verb.ticksBetweenBurstShots;\n\t\t\t\tfloat dmgBuildingsPassable = (verb?.defaultProjectile?.projectile?.stoppingPower).GetValueOrDefault();\n\t\t\t\tStringBuilder stringBuilder4 = new StringBuilder(\"Stat_Thing_Weapon_BurstShotFireRate_Desc\".Translate());\n\t\t\t\tstringBuilder4.AppendLine();\n\t\t\t\tstringBuilder4.AppendLine();\n\t\t\t\tstringBuilder4.AppendLine(\"StatsReport_BaseValue\".Translate() + \": \" + verb.burstShotCount.ToString());\n\t\t\t\tstringBuilder4.AppendLine();\n\t\t\t\tStringBuilder ticksBetweenBurstShotsExplanation = new StringBuilder(\"Stat_Thing_Weapon_BurstShotFireRate_Desc\".Translate());\n\t\t\t\tticksBetweenBurstShotsExplanation.AppendLine();\n\t\t\t\tticksBetweenBurstShotsExplanation.AppendLine();\n\t\t\t\tticksBetweenBurstShotsExplanation.AppendLine(\"StatsReport_BaseValue\".Translate() + \": \" + (60f / verb.ticksBetweenBurstShots.TicksToSeconds()).ToString(\"0.##\") + \" rpm\");\n\t\t\t\tticksBetweenBurstShotsExplanation.AppendLine();\n\t\t\t\tStringBuilder stoppingPowerExplanation = new StringBuilder(\"StoppingPowerExplanation\".Translate());\n\t\t\t\tstoppingPowerExplanation.AppendLine();\n\t\t\t\tstoppingPowerExplanation.AppendLine();\n\t\t\t\tstoppingPowerExplanation.AppendLine(\"StatsReport_BaseValue\".Translate() + \": \" + dmgBuildingsPassable.ToString(\"F1\"));\n\t\t\t\tstoppingPowerExplanation.AppendLine();\n\t\t\t\tif (req.HasThing && req.Thing.TryGetComp(out CompUniqueWeapon comp))\n\t\t\t\t{\n\t\t\t\t\tbool flag = false;\n\t\t\t\t\tbool flag2 = false;\n\t\t\t\t\tbool flag3 = false;\n\t\t\t\t\tforeach (WeaponTraitDef item2 in comp.TraitsListForReading)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!Mathf.Approximately(item2.burstShotCountMultiplier, 1f))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (!flag)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tstringBuilder4.AppendLine(\"StatsReport_WeaponTraits\".Translate() + \":\");\n\t\t\t\t\t\t\t\tflag = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tnum3 *= item2.burstShotCountMultiplier;\n\t\t\t\t\t\t\tstringBuilder4.AppendLine(\" \" + item2.LabelCap + \": \" + item2.burstShotCountMultiplier.ToStringByStyle(ToStringStyle.PercentOne, ToStringNumberSense.Factor));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!Mathf.Approximately(item2.burstShotSpeedMultiplier, 1f))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (!flag2)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tticksBetweenBurstShotsExplanation.AppendLine(\"StatsReport_WeaponTraits\".Translate() + \":\");\n\t\t\t\t\t\t\t\tflag2 = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tnum4 /= item2.burstShotSpeedMultiplier;\n\t\t\t\t\t\t\tticksBetweenBurstShotsExplanation.AppendLine(\" \" + item2.LabelCap + \": \" + item2.burstShotSpeedMultiplier.ToStringByStyle(ToStringStyle.PercentOne, ToStringNumberSense.Factor));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!Mathf.Approximately(item2.additionalStoppingPower, 0f))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (!flag3)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tstoppingPowerExplanation.AppendLine(\"StatsReport_WeaponTraits\".Translate() + \":\");\n\t\t\t\t\t\t\t\tflag3 = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tdmgBuildingsPassable += item2.additionalStoppingPower;\n\t\t\t\t\t\t\tstoppingPowerExplanation.AppendLine(\" \" + item2.LabelCap + \": \" + item2.additionalStoppingPower.ToStringByStyle(ToStringStyle.FloatOne, ToStringNumberSense.Offset));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tstringBuilder4.AppendLine();\n\t\t\t\tstringBuilder4.AppendLine(\"StatsReport_FinalValue\".Translate() + \": \" + Mathf.CeilToInt(num3).ToString());\n\t\t\t\tfloat dmgBuildingsImpassable = 60f / ((int)num4).TicksToSeconds();\n\t\t\t\tticksBetweenBurstShotsExplanation.AppendLine();\n\t\t\t\tticksBetweenBurstShotsExplanation.AppendLine(\"StatsReport_FinalValue\".Translate() + \": \" + dmgBuildingsImpassable.ToString(\"0.##\") + \" rpm\");\n\t\t\t\tstoppingPowerExplanation.AppendLine();\n\t\t\t\tstoppingPowerExplanation.AppendLine(\"StatsReport_FinalValue\".Translate() + \": \" + dmgBuildingsPassable.ToString(\"F1\"));\n\t\t\t\tStatCategoryDef statCat = verbStatCategory ?? StatCategoryDefOf.Weapon_Ranged;\n\t\t\t\tif (verb.showBurstShotStats && verb.burstShotCount > 1)\n\t\t\t\t{\n\t\t\t\t\tyield return new StatDrawEntry(statCat, \"BurstShotCount\".Translate(), Mathf.CeilToInt(num3).ToString(), stringBuilder4.ToString(), 5391);\n\t\t\t\t\tyield return new StatDrawEntry(statCat, \"BurstShotFireRate\".Translate(), dmgBuildingsImpassable.ToString(\"0.##\") + \" rpm\", ticksBetweenBurstShotsExplanation.ToString(), 5395);\n\t\t\t\t}\n\t\t\t\tif (dmgBuildingsPassable > 0f)\n\t\t\t\t{\n\t\t\t\t\tyield return new StatDrawEntry(statCat, \"StoppingPower\".Translate(), dmgBuildingsPassable.ToString(\"F1\"), stoppingPowerExplanation.ToString(), 5402);\n\t\t\t\t}\n\t\t\t\tfloat num5 = verb.range;\n\t\t\t\tStringBuilder stringBuilder5 = new StringBuilder(\"Stat_Thing_Weapon_Range_Desc\".Translate());\n\t\t\t\tstringBuilder5.AppendLine();\n\t\t\t\tstringBuilder5.AppendLine();\n\t\t\t\tstringBuilder5.AppendLine(\"StatsReport_BaseValue\".Translate() + \": \" + num5.ToString(\"F0\"));\n\t\t\t\tif (req.HasThing)\n\t\t\t\t{\n\t\t\t\t\tfloat statValue2 = req.Thing.GetStatValue(StatDefOf.RangedWeapon_RangeMultiplier);\n\t\t\t\t\tnum5 *= statValue2;\n\t\t\t\t\tif (!Mathf.Approximately(statValue2, 1f))\n\t\t\t\t\t{\n\t\t\t\t\t\tstringBuilder5.AppendLine();\n\t\t\t\t\t\tstringBuilder5.AppendLine(\"Stat_Thing_Weapon_Range_Multiplier\".Translate() + \": x\" + statValue2.ToStringPercent());\n\t\t\t\t\t\tstringBuilder5.Append(StatUtility.GetOffsetsAndFactorsFor(StatDefOf.RangedWeapon_RangeMultiplier, req.Thing));\n\t\t\t\t\t}\n\t\t\t\t\tMap obj = req.Thing.Map ?? req.Thing.MapHeld;\n\t\t\t\t\tif (obj != null && obj.weatherManager.CurWeatherMaxRangeCap >= 0f)\n\t\t\t\t\t{\n\t\t\t\t\t\tWeatherManager weatherManager = (req.Thing.Map ?? req.Thing.MapHeld).weatherManager;\n\t\t\t\t\t\tbool num6 = num5 > weatherManager.CurWeatherMaxRangeCap;\n\t\t\t\t\t\tfloat num7 = num5;\n\t\t\t\t\t\tnum5 = Mathf.Min(num5, weatherManager.CurWeatherMaxRangeCap);\n\t\t\t\t\t\tif (num6)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tstringBuilder5.AppendLine();\n\t\t\t\t\t\t\tstringBuilder5.AppendLine(\" \" + \"Stat_Thing_Weapon_Range_Clamped\".Translate(num5.ToString(\"F0\").Named(\"CAP\"), num7.ToString(\"F0\").Named(\"ORIGINAL\")));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tstringBuilder5.AppendLine();\n\t\t\t\tstringBuilder5.AppendLine(\"StatsReport_FinalValue\".Translate() + \": \" + num5.ToString(\"F0\"));\n\t\t\t\tyield return new StatDrawEntry(statCat, \"Range\".Translate(), num5.ToString(\"F0\"), stringBuilder5.ToString(), 5390);\n\t\t\t}\n\t\t\tif (verb.ForcedMissRadius > 0f)\n\t\t\t{\n\t\t\t\tStatCategoryDef statCat = verbStatCategory ?? StatCategoryDefOf.Weapon_Ranged;\n\t\t\t\tyield return new StatDrawEntry(statCat, \"MissRadius\".Translate(), verb.ForcedMissRadius.ToString(\"0.#\"), \"Stat_Thing_Weapon_MissRadius_Desc\".Translate(), 3557);\n\t\t\t\tyield return new StatDrawEntry(statCat, \"DirectHitChance\".Translate(), (1f / (float)GenRadial.NumCellsInRadius(verb.ForcedMissRadius)).ToStringPercent(), \"Stat_Thing_Weapon_DirectHitChance_Desc\".Translate(), 3560);\n\t\t\t}\n\t\t}\n\t\tif (plant != null)\n\t\t{\n\t\t\tforeach (StatDrawEntry item3 in plant.SpecialDisplayStats())\n\t\t\t{\n\t\t\t\tyield return item3;\n\t\t\t}\n\t\t}\n\t\tif (ingestible != null)\n\t\t{\n\t\t\tforeach (StatDrawEntry item4 in ingestible.SpecialDisplayStats())\n\t\t\t{\n\t\t\t\tyield return item4;\n\t\t\t}\n\t\t}\n\t\tif (race != null)\n\t\t{\n\t\t\tforeach (StatDrawEntry item5 in race.SpecialDisplayStats(this, req))\n\t\t\t{\n\t\t\t\tyield return item5;\n\t\t\t}\n\t\t}\n\t\tif (building != null)\n\t\t{\n\t\t\tforeach (StatDrawEntry item6 in building.SpecialDisplayStats(this, req))\n\t\t\t{\n\t\t\t\tyield return item6;\n\t\t\t}\n\t\t}\n\t\tif (isTechHediff)\n\t\t{\n\t\t\tIEnumerable enumerable2 = DefDatabase.AllDefs.Where((RecipeDef x) => x.addsHediff != null && x.IsIngredient(this));\n\t\t\tforeach (StatDrawEntry medicalStatsFromRecipeDef in MedicalRecipesUtility.GetMedicalStatsFromRecipeDefs(enumerable2))\n\t\t\t{\n\t\t\t\tyield return medicalStatsFromRecipeDef;\n\t\t\t}\n\t\t}\n\t\tfor (int i = 0; i < comps.Count; i++)\n\t\t{\n\t\t\tforeach (StatDrawEntry item7 in comps[i].SpecialDisplayStats(req))\n\t\t\t{\n\t\t\t\tyield return item7;\n\t\t\t}\n\t\t}\n\t\tif (building != null)\n\t\t{\n\t\t\tif (building.mineableThing != null)\n\t\t\t{\n\t\t\t\tDialog_InfoCard.Hyperlink[] hyperlinks = new Dialog_InfoCard.Hyperlink[1]\n\t\t\t\t{\n\t\t\t\t\tnew Dialog_InfoCard.Hyperlink(building.mineableThing)\n\t\t\t\t};\n\t\t\t\tyield return new StatDrawEntry(StatCategoryDefOf.BasicsImportant, \"Stat_MineableThing_Name\".Translate(), building.mineableThing.LabelCap, \"Stat_MineableThing_Desc\".Translate(), 2200, null, hyperlinks);\n\t\t\t\tStringBuilder stringBuilder6 = new StringBuilder();\n\t\t\t\tstringBuilder6.AppendLine(\"Stat_MiningYield_Desc\".Translate());\n\t\t\t\tstringBuilder6.AppendLine();\n\t\t\t\tstringBuilder6.AppendLine(\"StatsReport_DifficultyMultiplier\".Translate(Find.Storyteller.difficultyDef.label) + \": \" + Find.Storyteller.difficulty.mineYieldFactor.ToStringByStyle(ToStringStyle.PercentZero, ToStringNumberSense.Factor));\n\t\t\t\tyield return new StatDrawEntry(StatCategoryDefOf.Basics, \"Stat_MiningYield_Name\".Translate(), Mathf.CeilToInt(building.EffectiveMineableYield).ToString(\"F0\"), stringBuilder6.ToString(), 2200, null, hyperlinks);\n\t\t\t}\n\t\t\tif (building.IsTurret)\n\t\t\t{\n\t\t\t\tThingDef turret = building.turretGunDef;\n\t\t\t\tyield return new StatDrawEntry(StatCategoryDefOf.BasicsImportant, \"Stat_Weapon_Name\".Translate(), turret.LabelCap, \"Stat_Weapon_Desc\".Translate(), 5389, null, new Dialog_InfoCard.Hyperlink[1]\n\t\t\t\t{\n\t\t\t\t\tnew Dialog_InfoCard.Hyperlink(turret)\n\t\t\t\t});\n\t\t\t\tStatRequest request = StatRequest.For(turret, null);\n\t\t\t\tforeach (StatDrawEntry item8 in turret.SpecialDisplayStats(request))\n\t\t\t\t{\n\t\t\t\t\tif (item8.category == StatCategoryDefOf.Weapon_Ranged)\n\t\t\t\t\t{\n\t\t\t\t\t\tyield return item8;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfor (int i = 0; i < turret.statBases.Count; i++)\n\t\t\t\t{\n\t\t\t\t\tStatModifier statModifier = turret.statBases[i];\n\t\t\t\t\tif (statModifier.stat.category == StatCategoryDefOf.Weapon_Ranged)\n\t\t\t\t\t{\n\t\t\t\t\t\tyield return new StatDrawEntry(StatCategoryDefOf.Weapon_Ranged, statModifier.stat, statModifier.value, request);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (ModsConfig.OdysseyActive && Fillage == FillCategory.Full)\n\t\t\t{\n\t\t\t\tbool b = building.isAirtight || (building.isStuffableAirtight && req.StuffDef.stuffProps.isAirtight);\n\t\t\t\tyield return new StatDrawEntry(StatCategoryDefOf.Building, \"Stat_Airtight\".Translate(), b.ToStringYesNo(), \"Stat_Airtight_Desc\".Translate(), 6100);\n\t\t\t}\n\t\t}\n\t\tif (IsMeat)\n\t\t{\n\t\t\tList list = new List();\n\t\t\tbool flag4 = false;\n\t\t\tforeach (ThingDef allDef in DefDatabase.AllDefs)\n\t\t\t{\n\t\t\t\tif (allDef.race != null && allDef.race.meatDef == this && !allDef.IsCorpse)\n\t\t\t\t{\n\t\t\t\t\tif (!Find.HiddenItemsManager.Hidden(allDef))\n\t\t\t\t\t{\n\t\t\t\t\t\tflag4 = true;\n\t\t\t\t\t}\n\t\t\t\t\tlist.Add(allDef);\n\t\t\t\t}\n\t\t\t}\n\t\t\tyield return new StatDrawEntry(valueString: (!flag4) ? string.Format(\"({0})\", \"NotYetDiscovered\".Translate()) : string.Join(\", \", (from x in list\n\t\t\t\twhere !Find.HiddenItemsManager.Hidden(x)\n\t\t\t\tselect x into p\n\t\t\t\tselect p.label).ToArray()).CapitalizeFirst(), category: StatCategoryDefOf.BasicsPawn, label: \"Stat_SourceSpecies_Name\".Translate(), reportText: \"Stat_SourceSpecies_Desc\".Translate(), displayPriorityWithinCategory: 1200, overrideReportTitle: null, hyperlinks: Dialog_InfoCard.DefsToHyperlinks(list));\n\t\t}\n\t\tif (IsLeather)\n\t\t{\n\t\t\tList list2 = new List();\n\t\t\tbool flag5 = false;\n\t\t\tforeach (ThingDef allDef2 in DefDatabase.AllDefs)\n\t\t\t{\n\t\t\t\tif (allDef2.race != null && allDef2.race.leatherDef == this && !allDef2.IsCorpse)\n\t\t\t\t{\n\t\t\t\t\tif (!Find.HiddenItemsManager.Hidden(allDef2))\n\t\t\t\t\t{\n\t\t\t\t\t\tflag5 = true;\n\t\t\t\t\t}\n\t\t\t\t\tlist2.Add(allDef2);\n\t\t\t\t}\n\t\t\t}\n\t\t\tyield return new StatDrawEntry(valueString: (!flag5) ? string.Format(\"({0})\", \"NotYetDiscovered\".Translate()) : string.Join(\", \", (from x in list2\n\t\t\t\twhere !Find.HiddenItemsManager.Hidden(x)\n\t\t\t\tselect x into p\n\t\t\t\tselect p.label).ToArray()).CapitalizeFirst(), category: StatCategoryDefOf.BasicsPawn, label: \"Stat_SourceSpecies_Name\".Translate(), reportText: \"Stat_SourceSpecies_Desc\".Translate(), displayPriorityWithinCategory: 1200, overrideReportTitle: null, hyperlinks: Dialog_InfoCard.DefsToHyperlinks(list2));\n\t\t}\n\t\tif (!equippedStatOffsets.NullOrEmpty())\n\t\t{\n\t\t\tfor (int i = 0; i < equippedStatOffsets.Count; i++)\n\t\t\t{\n\t\t\t\tStatDef stat = equippedStatOffsets[i].stat;\n\t\t\t\tfloat num8 = equippedStatOffsets[i].value;\n\t\t\t\tStringBuilder stringBuilder7 = new StringBuilder(stat.description);\n\t\t\t\tif (req.HasThing && stat.Worker != null)\n\t\t\t\t{\n\t\t\t\t\tstringBuilder7.AppendLine();\n\t\t\t\t\tstringBuilder7.AppendLine();\n\t\t\t\t\tstringBuilder7.AppendLine(\"StatsReport_BaseValue\".Translate() + \": \" + stat.ValueToString(num8, ToStringNumberSense.Offset, stat.finalizeEquippedStatOffset));\n\t\t\t\t\tnum8 = StatWorker.StatOffsetFromGear(req.Thing, stat);\n\t\t\t\t\tif (!stat.parts.NullOrEmpty())\n\t\t\t\t\t{\n\t\t\t\t\t\tstringBuilder7.AppendLine();\n\t\t\t\t\t\tfor (int k = 0; k < stat.parts.Count; k++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tstring text = stat.parts[k].ExplanationPart(req);\n\t\t\t\t\t\t\tif (!text.NullOrEmpty())\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tstringBuilder7.AppendLine(text);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tstringBuilder7.AppendLine();\n\t\t\t\t\tstringBuilder7.AppendLine(\"StatsReport_FinalValue\".Translate() + \": \" + stat.ValueToString(num8, ToStringNumberSense.Offset, !stat.formatString.NullOrEmpty()));\n\t\t\t\t}\n\t\t\t\tyield return new StatDrawEntry(StatCategoryDefOf.EquippedStatOffsets, equippedStatOffsets[i].stat, num8, StatRequest.ForEmpty(), ToStringNumberSense.Offset, null, forceUnfinalizedMode: true).SetReportText(stringBuilder7.ToString());\n\t\t\t}\n\t\t}\n\t\tif (!IsDrug)\n\t\t{\n\t\t\tyield break;\n\t\t}\n\t\tforeach (StatDrawEntry item9 in DrugStatsUtility.SpecialDisplayStats(this))\n\t\t{\n\t\t\tyield return item9;\n\t\t}\n\t}\n}\n\n",
+ "timestamp": "2025-08-22 16:02:42,858"
+ }
+}
\ No newline at end of file