내러티브 태그 시스템 개선
요청하신 내러티브 태그 시스템과 시각화 작업을 모두 완료했습니다! 이전에 멈췄던 개발 서버( npm run dev )도 다시 실행해
두었으니, 새로고침 후 바로 확인해 보실 수 있습니다.
구현된 시스템의 주요 변경점은 다음과 같습니다.
### 1. 내러티브 데이터 생성 및 연동 ( narrative_tags.json , cards.csv )
• 기획서의 세계관을 바탕으로 피도 눈물도 없는 진압, 진실의 장막, 금지된 지식(이계 조우), 사이비의 그림자 등 서사
몰입을 돕는 내러티브 태그 데이터를 생성했습니다.
• 매 결재마다 무조건 얻는 것이 아니라, 특정 카드(예: 민간인 구역 폭격, 유물 연구 등)에서 특정한 선택을 했을 때만
불규칙적으로 획득하도록 cards.csv 데이터를 스크립트로 자동 매핑했습니다.
### 2. 결재 시 스와이프 보상 시각화 ( SwipeCard.jsx , SwipeCard.css )
• 내러티브 태그가 걸려 있는 선택지 쪽으로 스와이프(미리보기)를 하면, 텍스트 상단에 노란색 바탕의 뱃지( 💡 진실의 장막
)가 심장 박동처럼 깜빡이는 애니메이션과 함께 아주 눈에 띄게 표시됩니다. 플레이어가 "아, 이 선택을 하면 스토리에 큰
영향을 주는구나"를 직관적으로 알 수 있습니다.
### 3. 태그 획득 알림 팝업 ( GameScreen.jsx )
• 결재를 완료하여 내러티브 태그를 얻는 순간, 화면 중앙 상단에 [새로운 내러티브 획득! - 금지된 지식] 형태의 눈에
띄는 팝업 알림이 내려왔다가 3초 뒤 자연스럽게 사라지도록 구현했습니다.
### 4. 연대기 창 서사 부각 개편 ( ChroniclePopup.jsx , ChroniclePopup.css )
• 단순히 텍스트만 나열되던 방식을 타임라인(Timeline) 형식으로 전면 재설계했습니다.
• 과거의 기록에는 [위기] 상황 키워드 와 함께 내가 어떤 서사를 마주했고 어떤 결정을 내렸는지 명확히 표시됩니다.
• 태그 획득 시각화: 특히 내러티브 태그를 얻은 턴은 배경이 금빛으로 하이라이트되며, 획득한 태그의 **자세한 설명(스토리
서사)**이 커다란 아이콘과 함께 표시됩니다. 이를 통해 유저가 왜 이런 태그를 얻었는지 서사를 깊게 이해할 수 있습니다.
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.8);
|
||||
background: rgba(0, 0, 0, 0.85);
|
||||
z-index: 300;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -14,14 +14,14 @@
|
||||
.chronicle-popup {
|
||||
background: var(--color-surface);
|
||||
width: 90%;
|
||||
max-width: 400px;
|
||||
max-height: 80%;
|
||||
max-width: 500px;
|
||||
max-height: 85%;
|
||||
border-radius: 16px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.8);
|
||||
border: 1px solid rgba(255, 255, 255, 0.15);
|
||||
box-shadow: 0 10px 50px rgba(0, 0, 0, 0.9);
|
||||
}
|
||||
|
||||
.chronicle-header {
|
||||
@@ -29,14 +29,23 @@
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 20px;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.chronicle-header h2 {
|
||||
margin: 0;
|
||||
font-family: var(--font-doc-title);
|
||||
font-size: 20px;
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
.chronicle-tags-summary {
|
||||
background: rgba(251, 191, 36, 0.2);
|
||||
color: #fbbf24;
|
||||
padding: 4px 12px;
|
||||
border-radius: 12px;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.close-btn {
|
||||
@@ -45,10 +54,11 @@
|
||||
color: #fff;
|
||||
font-size: 28px;
|
||||
cursor: pointer;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.chronicle-content {
|
||||
padding: 20px;
|
||||
padding: 24px;
|
||||
overflow-y: auto;
|
||||
flex: 1;
|
||||
}
|
||||
@@ -59,35 +69,106 @@
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.chronicle-list {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
.chronicle-timeline {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.chronicle-item {
|
||||
margin-bottom: 20px;
|
||||
.chronicle-entry {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
padding-bottom: 20px;
|
||||
border-bottom: 1px dashed rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.chronicle-item:last-child {
|
||||
.chronicle-entry:last-child {
|
||||
border-bottom: none;
|
||||
margin-bottom: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.turn-number {
|
||||
font-size: 12px;
|
||||
color: var(--color-token-info);
|
||||
.entry-turn {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
display: block;
|
||||
margin-bottom: 5px;
|
||||
color: #a1a1aa;
|
||||
min-width: 60px;
|
||||
padding-top: 2px;
|
||||
}
|
||||
|
||||
.chronicle-item p {
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
color: #ddd;
|
||||
.entry-body {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.entry-context {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.entry-type {
|
||||
font-size: 12px;
|
||||
color: var(--color-token-info);
|
||||
font-family: var(--font-typewriter);
|
||||
}
|
||||
|
||||
.entry-keyword {
|
||||
font-size: 15px;
|
||||
font-weight: bold;
|
||||
color: #fbbf24;
|
||||
}
|
||||
|
||||
.entry-text {
|
||||
font-size: 14px;
|
||||
color: #d4d4d8;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.entry-decision {
|
||||
font-size: 14px;
|
||||
color: #4ade80;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.entry-tag-highlight {
|
||||
margin-top: 12px;
|
||||
background: rgba(251, 191, 36, 0.15);
|
||||
border-left: 4px solid #fbbf24;
|
||||
border-radius: 4px;
|
||||
padding: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.tag-icon {
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
.tag-details {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.tag-name {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: #fbbf24;
|
||||
}
|
||||
|
||||
.tag-desc {
|
||||
font-size: 13px;
|
||||
color: #fff;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.has-tag {
|
||||
background: linear-gradient(90deg, rgba(251,191,36,0.05) 0%, transparent 100%);
|
||||
border-radius: 8px;
|
||||
padding: 12px;
|
||||
border-bottom: none;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
@@ -1,26 +1,46 @@
|
||||
import React from 'react';
|
||||
import './ChroniclePopup.css';
|
||||
|
||||
export default function ChroniclePopup({ chronicle, onClose }) {
|
||||
export default function ChroniclePopup({ chronicle, acquiredTags, onClose }) {
|
||||
return (
|
||||
<div className="chronicle-overlay" onClick={onClose}>
|
||||
<div className="chronicle-popup" onClick={e => e.stopPropagation()}>
|
||||
<div className="chronicle-header">
|
||||
<h2>국장의 연대기</h2>
|
||||
<div className="chronicle-tags-summary">
|
||||
획득한 내러티브: {acquiredTags?.length || 0}개
|
||||
</div>
|
||||
<button className="close-btn" onClick={onClose}>×</button>
|
||||
</div>
|
||||
<div className="chronicle-content">
|
||||
{chronicle.length === 0 ? (
|
||||
<p className="empty-text">아직 기록된 역사가 없습니다.</p>
|
||||
) : (
|
||||
<ul className="chronicle-list">
|
||||
<div className="chronicle-timeline">
|
||||
{chronicle.map((entry, idx) => (
|
||||
<li key={idx} className="chronicle-item">
|
||||
<span className="turn-number">Turn {entry.turn}</span>
|
||||
<p>{entry.text}</p>
|
||||
</li>
|
||||
<div key={idx} className={`chronicle-entry ${entry.tag ? 'has-tag' : ''}`}>
|
||||
<div className="entry-turn">Turn {entry.turn}</div>
|
||||
<div className="entry-body">
|
||||
<div className="entry-context">
|
||||
<span className="entry-type">[{entry.cardType}]</span>
|
||||
<span className="entry-keyword">{entry.keyword}</span>
|
||||
</div>
|
||||
<div className="entry-text">{entry.text}</div>
|
||||
<div className="entry-decision">👉 결정: {entry.decision}</div>
|
||||
|
||||
{entry.tag && (
|
||||
<div className="entry-tag-highlight">
|
||||
<div className="tag-icon">{entry.tag.icon}</div>
|
||||
<div className="tag-details">
|
||||
<div className="tag-name">내러티브 획득: {entry.tag.name}</div>
|
||||
<div className="tag-desc">{entry.tag.description}</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -200,3 +200,43 @@
|
||||
background: var(--color-text);
|
||||
color: var(--color-bg);
|
||||
}
|
||||
.tag-notification {
|
||||
position: absolute;
|
||||
top: 100px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
background: rgba(0, 0, 0, 0.9);
|
||||
border: 1px solid #fbbf24;
|
||||
border-radius: 12px;
|
||||
padding: 12px 24px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
box-shadow: 0 4px 20px rgba(251, 191, 36, 0.4);
|
||||
z-index: 100;
|
||||
animation: slideDownFadeOut 3s forwards;
|
||||
}
|
||||
|
||||
.tag-noti-icon {
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
.tag-noti-info h4 {
|
||||
margin: 0;
|
||||
color: #fbbf24;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.tag-noti-info p {
|
||||
margin: 4px 0 0 0;
|
||||
color: #fff;
|
||||
font-weight: bold;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
@keyframes slideDownFadeOut {
|
||||
0% { opacity: 0; transform: translate(-50%, -20px); }
|
||||
10% { opacity: 1; transform: translate(-50%, 0); }
|
||||
80% { opacity: 1; transform: translate(-50%, 0); }
|
||||
100% { opacity: 0; transform: translate(-50%, -20px); }
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import Papa from 'papaparse';
|
||||
import cardsCsvRaw from '../data/cards.csv?raw';
|
||||
import narrativeTagsData from '../data/narrative_tags.json';
|
||||
import { BookOpen, HandCoins, Droplet, Eye, Shield, Building2, EyeOff } from 'lucide-react';
|
||||
import SwipeCard from './SwipeCard';
|
||||
import CouncilScreen from './CouncilScreen';
|
||||
@@ -12,7 +13,7 @@ export function GameScreen() {
|
||||
const [params, setParams] = useState({ resistance: 0, entropy: 0, panic: 0, risk: 0 });
|
||||
const [tokens, setTokens] = useState({ budget: 50, personnel: 50, info: 50 });
|
||||
const [tags, setTags] = useState({ wealth: 0, force: 0, surveillance: 0 });
|
||||
const [narrativeTags, setNarrativeTags] = useState(0);
|
||||
const [acquiredTags, setAcquiredTags] = useState([]);
|
||||
const [phase, setPhase] = useState(1);
|
||||
const [gameOver, setGameOver] = useState(false);
|
||||
const [cards, setCards] = useState([]);
|
||||
@@ -31,6 +32,7 @@ export function GameScreen() {
|
||||
const [bankruptcyCount, setBankruptcyCount] = useState(0);
|
||||
const [bankruptcyWarning, setBankruptcyWarning] = useState(false);
|
||||
const [bankrupted, setBankrupted] = useState(false);
|
||||
const [newTagNotification, setNewTagNotification] = useState(null);
|
||||
|
||||
// CSV Load Effect
|
||||
useEffect(() => {
|
||||
@@ -45,6 +47,7 @@ export function GameScreen() {
|
||||
flavor: row.flavor,
|
||||
left: {
|
||||
text: row.left_text,
|
||||
tag: row.left_tag ? narrativeTagsData.find(t => t.id === row.left_tag) : null,
|
||||
stats: {
|
||||
res: row.left_res || 0,
|
||||
ent: row.left_ent || 0,
|
||||
@@ -78,6 +81,7 @@ export function GameScreen() {
|
||||
},
|
||||
right: {
|
||||
text: row.right_text,
|
||||
tag: row.right_tag ? narrativeTagsData.find(t => t.id === row.right_tag) : null,
|
||||
stats: {
|
||||
res: row.right_res || 0,
|
||||
ent: row.right_ent || 0,
|
||||
@@ -118,15 +122,16 @@ export function GameScreen() {
|
||||
if (params.resistance >= 5 || params.entropy >= 5 || params.panic >= 5 || params.risk >= 5) {
|
||||
setGameOver(true);
|
||||
}
|
||||
if (narrativeTags >= 4 && narrativeTags < 8) setPhase(2);
|
||||
else if (narrativeTags >= 8) setPhase(3);
|
||||
}, [params, narrativeTags]);
|
||||
if (acquiredTags.length >= 4 && acquiredTags.length < 8) setPhase(2);
|
||||
else if (acquiredTags.length >= 8) setPhase(3);
|
||||
}, [params, acquiredTags]);
|
||||
|
||||
const handleSwipe = (direction) => {
|
||||
if (cards.length === 0) return;
|
||||
const card = cards[currentCardIndex % cards.length];
|
||||
|
||||
let outcomeText = '';
|
||||
let gainedTag = null;
|
||||
|
||||
let newBudget = tokens.budget;
|
||||
let newPersonnel = tokens.personnel;
|
||||
@@ -138,12 +143,14 @@ export function GameScreen() {
|
||||
newInfo += (card.left.stats?.inf || 0);
|
||||
card.left.effect();
|
||||
outcomeText = card.left.text;
|
||||
gainedTag = card.left.tag;
|
||||
} else if (direction === 'right' && card.right) {
|
||||
newBudget += (card.right.stats?.bud || 0);
|
||||
newPersonnel += (card.right.stats?.per || 0);
|
||||
newInfo += (card.right.stats?.inf || 0);
|
||||
card.right.effect();
|
||||
outcomeText = card.right.text;
|
||||
gainedTag = card.right.tag;
|
||||
} else if (direction === 'up') {
|
||||
outcomeText = '보류 / 버리기';
|
||||
}
|
||||
@@ -153,7 +160,22 @@ export function GameScreen() {
|
||||
}
|
||||
|
||||
if (outcomeText) {
|
||||
setChronicle(prev => [...prev, { turn: turns + 1, text: `[${card.type}] ${card.text} -> 결정: ${outcomeText}` }]);
|
||||
let isNewTag = false;
|
||||
if (gainedTag && !acquiredTags.find(t => t.id === gainedTag.id)) {
|
||||
isNewTag = true;
|
||||
setAcquiredTags(prev => [...prev, gainedTag]);
|
||||
setNewTagNotification(gainedTag);
|
||||
setTimeout(() => setNewTagNotification(null), 3000);
|
||||
}
|
||||
|
||||
setChronicle(prev => [...prev, {
|
||||
turn: turns + 1,
|
||||
cardType: card.type,
|
||||
keyword: card.keyword,
|
||||
text: card.text,
|
||||
decision: outcomeText,
|
||||
tag: isNewTag ? gainedTag : null
|
||||
}]);
|
||||
}
|
||||
|
||||
// Add random asset for '극비' success (just for demonstration)
|
||||
@@ -163,7 +185,6 @@ export function GameScreen() {
|
||||
}
|
||||
}
|
||||
|
||||
setNarrativeTags(n => n + 1);
|
||||
setCurrentCardIndex(idx => idx + 1);
|
||||
|
||||
setTurns(turns + 1);
|
||||
@@ -225,7 +246,7 @@ export function GameScreen() {
|
||||
impeachment={impeachmentPassed}
|
||||
termExpired={termExpired}
|
||||
bankrupted={bankrupted}
|
||||
narrativeTags={narrativeTags}
|
||||
narrativeTags={acquiredTags.length}
|
||||
onRestart={() => window.location.reload()}
|
||||
/>
|
||||
);
|
||||
@@ -256,7 +277,7 @@ export function GameScreen() {
|
||||
{/* Top Bar */}
|
||||
<div className="top-bar">
|
||||
<div className="narrative-badge" onClick={() => setShowChronicle(true)} style={{cursor: 'pointer'}}>
|
||||
<BookOpen size={16} /> <span>{narrativeTags}/8</span>
|
||||
<BookOpen size={16} /> <span>{acquiredTags.length}/8</span>
|
||||
</div>
|
||||
<div className="round-info">
|
||||
제 {roundCount}차 정례회의 상정까지: 잔여 {approvalsRemaining}건
|
||||
@@ -311,9 +332,20 @@ export function GameScreen() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{newTagNotification && (
|
||||
<div className="tag-notification">
|
||||
<div className="tag-noti-icon">{newTagNotification.icon}</div>
|
||||
<div className="tag-noti-info">
|
||||
<h4>새로운 내러티브 획득!</h4>
|
||||
<p>[{newTagNotification.name}]</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{showChronicle && (
|
||||
<ChroniclePopup
|
||||
chronicle={chronicle}
|
||||
acquiredTags={acquiredTags}
|
||||
onClose={() => setShowChronicle(false)}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -203,3 +203,27 @@
|
||||
.stat-bad {
|
||||
color: #f87171;
|
||||
}
|
||||
.intent-tag-reward {
|
||||
background: rgba(251, 191, 36, 0.9);
|
||||
color: #000;
|
||||
padding: 8px 16px;
|
||||
border-radius: 8px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-bottom: 8px;
|
||||
font-weight: bold;
|
||||
font-family: var(--font-ui);
|
||||
box-shadow: 0 0 15px rgba(251, 191, 36, 0.5);
|
||||
animation: pulseTag 1.5s infinite;
|
||||
}
|
||||
|
||||
.intent-tag-icon {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
@keyframes pulseTag {
|
||||
0% { transform: scale(1); box-shadow: 0 0 15px rgba(251, 191, 36, 0.5); }
|
||||
50% { transform: scale(1.05); box-shadow: 0 0 25px rgba(251, 191, 36, 0.8); }
|
||||
100% { transform: scale(1); box-shadow: 0 0 15px rgba(251, 191, 36, 0.5); }
|
||||
}
|
||||
|
||||
@@ -111,10 +111,22 @@ export default function SwipeCard({ card, onSwipe, phase }) {
|
||||
{/* Swipe Intents */}
|
||||
<motion.div className="swipe-intent left-intent" style={{ opacity: leftOpacity }}>
|
||||
<span className="intent-title">{card.left?.text}</span>
|
||||
{card.left?.tag && (
|
||||
<div className="intent-tag-reward">
|
||||
<span className="intent-tag-icon">{card.left.tag.icon}</span>
|
||||
<span className="intent-tag-name">{card.left.tag.name}</span>
|
||||
</div>
|
||||
)}
|
||||
{renderStats(card.left?.stats)}
|
||||
</motion.div>
|
||||
<motion.div className="swipe-intent right-intent" style={{ opacity: rightOpacity }}>
|
||||
<span className="intent-title">{card.right?.text}</span>
|
||||
{card.right?.tag && (
|
||||
<div className="intent-tag-reward">
|
||||
<span className="intent-tag-icon">{card.right.tag.icon}</span>
|
||||
<span className="intent-tag-name">{card.right.tag.name}</span>
|
||||
</div>
|
||||
)}
|
||||
{renderStats(card.right?.stats)}
|
||||
</motion.div>
|
||||
{card.type === '극비' && (
|
||||
|
||||
@@ -1,33 +1,33 @@
|
||||
id,type,keyword,question,text,flavor,left_text,left_res,left_ent,left_pan,left_rsk,left_bud,left_per,left_inf,left_wea,left_for,left_sur,right_text,right_res,right_ent,right_pan,right_rsk,right_bud,right_per,right_inf,right_wea,right_for,right_sur
|
||||
1,일상,요원들의 시위 발생,시위를 어떻게 처리하시겠습니까?,B구역 하급 요원들이 예산 삭감에 반발해 장비 반납 시위를 하고 있습니다.,우리가 세상을 구하는데 월급이 깎인다고요? 촉수에 맞아 죽으나 굶어 죽으나 똑같습니다!,무력 진압,1,0,0,0,0,-10,0,0,0,0,요구 수용,0,0,0,0,-20,0,0,0,0,0
|
||||
2,위기,격리실 오염 발생,오염을 어떻게 정화하시겠습니까?,지하 4층 격리실의 문은 닫혀 있습니다만 요원 12명이 남긴 체액의 총량이 인간 12명의 부피를 초과했습니다.,보고서 첨부: 액체화된 직원은 산재 처리가 안 됩니다.,네이팜 소각 강행,0,0,0,0,0,-30,0,0,0,0,조사팀 파견,0,1,0,1,0,0,0,0,0,0
|
||||
3,일상,촉수 괴물 출현,출동 승인하시겠습니까?,7구역에 촉수 괴물이 출현했습니다. 작전팀이 법인카드 영수증 제출을 누락해서 출동 승인이 반려된 상태입니다.,규정은 규정입니다. 영수증 없이 세계를 구하는 건 용납할 수 없습니다.,내역 위조 후 출동,0,0,0,1,0,0,-10,0,0,0,규정대로 반려,1,1,0,0,0,0,0,0,0,0
|
||||
4,극비,변이 DNA 이식 제안,실험을 승인하시겠습니까?,진화 미래당이 제안합니다. 요원들에게 괴수의 DNA를 소량 이식하면 작전 효율이 300% 상승합니다. 예산은 우리가 대죠.,인간의 한계는 명확합니다. 조금 징그러워지는 것쯤은 감수해야죠.,실험 승인,0,2,0,0,40,40,0,0,0,0,제안 거절,1,0,0,0,0,0,0,0,0,0
|
||||
5,작전,전술 폭격 건의,폭격을 승인하시겠습니까?,철의 수호당이 민간인 구역에 전술 폭격을 가해 S급 변칙 개체를 제거하자고 건의했습니다.,희생 없는 승리는 없습니다. 소를 위해 대를... 아니 대를 위해 소를 희생하죠.,궤도 폭격 승인,0,0,0,2,0,0,0,0,2,0,작전 기각,1,0,0,0,0,0,0,0,0,0
|
||||
6,일상,부산물 암시장 매각,매각을 허가하시겠습니까?,차원 무역당 소속 브로커가 처리된 괴수의 부산물을 암시장에 팔아치우자고 속삭입니다.,이 이빨 하나면 국장님 연봉의 10배입니다. 눈 한 번만 딱 감으시죠.,매각 허가,0,0,0,1,30,0,0,0,0,0,원칙대로 소각,0,0,0,0,-10,0,0,0,0,0
|
||||
7,작전,존재 양지화 프로젝트,프로젝트를 승인하시겠습니까?,대중 매체를 장악하여 I.S.C.O의 존재를 서서히 양지화하는 프로젝트입니다. 막대한 정보 토큰이 소모됩니다.,우리가 이 행성의 진짜 지배자임을 알릴 때가 되었습니다.,감시망 구축,0,0,0,0,0,0,-40,0,0,2,프로젝트 보류,1,0,0,0,0,0,0,0,0,0
|
||||
8,극비,대규모 도서관 건립,예산을 배정하시겠습니까?,고대 언어 해독을 위해 대규모 도서관 건립이 필요합니다. 지식 보존당이 학자들을 동원할 것입니다.,이해할 수 없는 것을 죽이는 건 야만인이나 하는 짓입니다.,예산 배정,0,0,0,0,-40,0,40,0,0,0,예산 전액 삭감,1,0,0,1,0,0,0,0,0,0
|
||||
9,위기,이단 색출 마녀사냥,어떻게 개입하시겠습니까?,기술 원리주의자들이 마녀사냥을 시작했습니다. 기구 내 마법 사용 요원들을 이단으로 규정하고 색출 중입니다.,더러운 마법과 변이에 의존해선 안 됩니다. 오직 순수한 인간의 힘으로!,적당히 묵인한다,1,0,0,0,0,-30,0,0,0,0,군사력으로 제압,0,0,0,1,0,0,-20,0,0,0
|
||||
10,일상,변칙 현상 영상 유출,어떻게 처리하시겠습니까?,한 유튜버가 변칙 현상을 촬영해 업로드했습니다. 침묵의 장막당이 즉각적인 물리적 제거와 기억 소거를 요구합니다.,대중은 진실을 감당할 지능이 없습니다. 무덤까지 비밀을 덮으십시오.,제거 절차 승인,0,0,0,-1,0,0,-20,0,0,0,영상만 삭제,0,1,0,0,0,0,0,0,0,0
|
||||
11,위기,사이비 종교 인신 공양,어떻게 대응하시겠습니까?,특정 구역의 사이비 종교가 고대 신을 소환하기 위해 시민 100명을 인신 공양하려 합니다. 공존당은 이를 방관하라 합니다.,위대한 그분들이 배가 고프다 하십니다. 조금만 양보하면 평화롭습니다.,군사 개입 지시,1,0,1,0,0,-40,0,0,0,0,의식 방관,0,2,0,0,0,0,0,0,0,0
|
||||
12,위기,의회의 긴급 감사,어떻게 대처하시겠습니까?,의회에서 국장의 예산 전용 의혹을 제기하며 긴급 감사를 통보했습니다. 장부를 조작해야 합니다!,세상을 구하는 데 돈 좀 쓴 게 죄입니까? 빨리 덮을 정보팀을 부르십시오.,은폐 공작 실행,0,0,0,1,0,0,-40,0,0,0,횡령 사실 인정,0,0,0,2,0,0,0,0,0,0
|
||||
13,일상,연구 부서 파업 조짐,요구를 수용하시겠습니까?,연구 부서에서 초과 근무로 인한 집단 피로를 호소하며 휴가와 특별 보너스를 요구하고 있습니다.,저희도 사람입니다. 괴수 해부하다가 과로사하긴 싫어요.,특별 보너스 지급,-1,0,0,0,-30,0,0,0,0,0,요구 전면 묵살,1,0,0,0,0,0,0,0,0,0
|
||||
14,작전,이계 무역로 개방,무역로를 개방하시겠습니까?,이계와의 무역로를 임시 개방하여 자원을 조달하자는 안건이 상정되었습니다. 미지의 오염이 우려됩니다.,저 너머의 세계엔 우리가 상상도 못 할 자원이 널려있습니다. 황금알을 낳는 거위죠.,게이트 강제 개방,0,1,0,0,50,0,0,0,0,0,폐쇄 상태 유지,1,0,0,0,0,0,0,0,0,0
|
||||
15,극비,전임 국장 비밀 금고,금고를 개방하시겠습니까?,전임 국장이 남긴 비밀 금고를 발견했습니다. 여는 데 특수 장비와 전문 인력이 필요합니다.,전임 국장님이 숙청당하기 전 남긴 비자금 장부일지도 모릅니다.,강제 개방 지시,0,0,0,0,20,-30,0,1,0,0,영구 봉인,0,0,0,0,0,0,0,0,0,0
|
||||
16,작전,메가코프 협박 작전,작전을 실행하시겠습니까?,글로벌 메가코프를 협박해 I.S.C.O의 비자금을 세탁하고 대규모 자금을 확보할 기회입니다.,그들이 우리 덕분에 안전하게 사업하는 겁니다. 보호세 좀 걷는 게 뭐 어떻습니까.,작전 실행,0,0,0,0,0,0,-30,2,0,0,작전 취소,1,0,0,0,0,0,0,0,0,0
|
||||
17,위기,전술 폭격 건의,폭격을 승인하시겠습니까?,제7구역이 S급 변칙 개체에 의해 완전히 붕괴될 위기입니다. 민간인을 포기하고 융단 폭격을 해야 할까요?,시민 10만 명 구출 비용보다 유가족 합의금이 예산을 15% 더 아낄 수 있습니다.,시민 포기 및 폭격,0,-1,0,2,0,0,0,0,0,0,결사 방어 명령,0,0,0,0,-40,-40,0,0,0,0
|
||||
18,일상,행정부 파업 예고,어떻게 대응하시겠습니까?,새로운 회식비 규정이 너무 짜다며 행정부에서 파업을 예고했습니다. 괴수 사체 처리 지연으로 악취가 진동합니다.,기구의 절반은 서류 작업으로 돌아갑니다. 그들을 화나게 해선 안 됩니다.,예산 전용으로 무마,0,0,0,1,-20,0,0,0,0,0,파업 강경 대응,1,0,0,0,0,0,0,0,0,0
|
||||
19,극비,불침번 요원 개발,배치하시겠습니까?,비밀 연구소에서 인공지능과 죽은 요원의 뇌를 결합한 불침번 요원을 개발했습니다.,잠도 안 자고 월급도 안 받습니다. 윤리적 문제만 빼면 완벽한 자산이죠.,실전 즉각 배치,0,1,0,0,0,0,20,0,1,0,즉각 폐기 처분,1,0,0,0,-10,0,0,0,0,0
|
||||
20,일상,내부 스파이 첩보,어떻게 조사하시겠습니까?,기구 내부에 스파이가 있다는 첩보가 들어왔습니다. 대대적인 사상 검증이 필요할지도 모릅니다.,누군가 정보를 빼돌려 의회에 넘기고 있습니다. 잡히면 믹서기에 넣어야 합니다.,대규모 사찰 시작,2,0,0,0,0,0,30,0,0,0,증거 부족으로 덮음,0,0,0,1,0,0,0,0,0,0
|
||||
21,작전,비정상적 위기 발생,"국장님, 결단이 필요합니다.",순수 인간당이 변이의 기미가 보이는 요원들을 격리 수용할 대규모 시설 건립을 제안했습니다.,괴물과 싸우다 보면 괴물이 되는 법. 그들이 선을 넘기 전에 가둬야 합니다.,수용소 건립 승인,0,0,0,0,-40,0,0,0,1,0,제안 단호히 거절,1,0,0,1,0,0,0,0,0,0
|
||||
22,극비,이계의 유물 인양,유물을 어떻게 처리하시겠습니까?,고대 공존당의 사제들이 심해의 유물을 인양했습니다. 만지는 자의 정신을 갉아먹지만 막대한 지식을 줍니다.,약간의 두통만 참으면 이계의 비밀을 모두 알 수 있습니다. 요원 하나쯤 미쳐도 괜찮습니다.,유물 집중 연구,0,1,0,0,0,0,50,0,0,0,유물 파괴 명령,1,0,0,1,0,0,0,0,0,0
|
||||
23,위기,이계의 주시자 출현,대중을 어떻게 통제하시겠습니까?,얇아진 장막 너머로 거대한 눈동자가 며칠째 지구를 주시하고 있습니다. 대중의 공포가 확산되고 있습니다.,하늘을 보지 마십시오. 아니 차라리 눈을 감고 살게 하십시오.,인터넷 전면 차단,2,0,1,0,0,0,0,0,0,2,진정제 무상 배포,0,0,0,0,-50,0,0,0,0,0
|
||||
24,일상,요원 집단 트라우마,어떻게 지원하시겠습니까?,요원들이 괴수 진압 후 심각한 트라우마에 시달리고 있습니다. 심리 치료 지원이 시급합니다.,밤마다 촉수가 목을 조르는 악몽을 꾼답니다. 차라리 그 부분 기억을 지워버릴까요?,정신과 치료 지원,0,0,0,0,-20,10,0,0,0,0,트라우마 기억 소거,0,1,0,1,0,0,0,0,0,0
|
||||
25,극비,내부 고발자 발생,어떻게 막으시겠습니까?,의회 의원 중 한 명이 기구의 비리를 폭로하려 합니다. 침묵의 장막당이 사고사 처리를 제안합니다.,국장님 계단에서 구르거나 심장마비가 오는 건 아주 흔한 자연의 섭리입니다.,사고사 위장 지시,0,0,0,-1,0,0,-30,0,0,0,폭로전 정면 돌파,0,0,0,2,0,0,0,0,0,0
|
||||
26,위기,차원 붕괴 폭탄 오작동,어떻게 대응하시겠습니까?,차원 붕괴 폭탄의 타이머가 오작동을 일으켰습니다! 당장 끄지 않으면 7구역이 통째로 증발합니다.,최저가 입찰로 부품을 사서 폭탄을 만든 결과입니다. 누군가는 책임져야 합니다.,특수 해체팀 투입,0,0,0,0,0,-40,0,0,0,0,폭발 방관 및 대피,0,2,0,0,0,0,0,0,0,0
|
||||
27,작전,PMC 흡수 합병,결탁하시겠습니까?,군부와 결탁하여 민간 군사 기업(PMC)을 I.S.C.O의 통제 하에 두려는 작전입니다.,돈으로 충성심을 사는 건 가장 안전한 방법입니다. 물론 돈이 많을 때 이야기죠.,결탁 및 흡수 합병,0,0,0,0,-40,0,0,0,2,0,독자적 노선 유지,1,0,0,0,0,0,0,0,0,0
|
||||
28,작전,대규모 거주 구역 실험장화,제안을 승인하시겠습니까?,변칙 개체 관찰을 위해 1구역을 돔으로 덮고 거대한 실험장으로 만들자는 제안이 올라왔습니다.,시민들이 좀 불편해하겠지만 과학적 진보를 위해 그 정도는 감수해야죠.,돔 건설 강행,0,1,0,0,-50,0,0,0,0,0,윤리적 이유로 기각,0,0,0,1,0,0,0,0,0,0
|
||||
29,극비,이계 군주의 외교,제안을 수락하시겠습니까?,이계의 군주가 외교 사절을 보내왔습니다. 요원 10명을 노예로 주면 최고급 이계 무기를 주겠다고 합니다.,요원 10명의 생명 가치보다 이계 무기가 가져올 파급력이 월등히 높습니다.,거래 즉시 성사,0,0,0,0,0,-40,0,0,2,0,사절단 전원 사살,0,1,0,1,0,0,0,0,0,0
|
||||
30,일상,믹스 커피 재고 고갈,어떻게 해결하시겠습니까?,국장님 믹스 커피가 다 떨어졌습니다. 이게 무슨 세상의 종말보다 더 큰 위기인 줄 아십니까? 행정부서의 불만이 폭주합니다.,종말을 결재하기 전엔 커피 한 잔의 여유가 필요한 법입니다. 안 그렇습니까?,최고급 원두 지원,-1,0,0,0,-10,0,0,0,0,0,헛소리 금지령,1,0,0,0,0,0,0,0,0,0
|
||||
31,위기,신화적 존재 강림,어떻게 대적하시겠습니까?,신화적 존재가 깨어나려 합니다. 하늘이 피처럼 붉게 물들었고 요원들은 미쳐가고 있습니다!,최종 결재의 시간입니다. 세상의 물리 법칙을 비틀 것입니까 아니면 피로 막을 것입니까?,현실 조작기 가동,0,2,0,0,0,0,-50,0,0,0,모든 예비병력 투입,0,0,0,1,0,-60,0,0,0,0
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
id,type,keyword,question,text,flavor,left_text,left_tag,left_res,left_ent,left_pan,left_rsk,left_bud,left_per,left_inf,left_wea,left_for,left_sur,right_text,right_tag,right_res,right_ent,right_pan,right_rsk,right_bud,right_per,right_inf,right_wea,right_for,right_sur
|
||||
1,일상,요원들의 시위 발생,시위를 어떻게 처리하시겠습니까?,B구역 하급 요원들이 예산 삭감에 반발해 장비 반납 시위를 하고 있습니다.,우리가 세상을 구하는데 월급이 깎인다고요? 촉수에 맞아 죽으나 굶어 죽으나 똑같습니다!,무력 진압,tag_ruthless,1,0,0,0,0,-10,0,0,0,0,요구 수용,,0,0,0,0,-20,0,0,0,0,0
|
||||
2,위기,격리실 오염 발생,오염을 어떻게 정화하시겠습니까?,지하 4층 격리실의 문은 닫혀 있습니다만 요원 12명이 남긴 체액의 총량이 인간 12명의 부피를 초과했습니다.,보고서 첨부: 액체화된 직원은 산재 처리가 안 됩니다.,네이팜 소각 강행,,0,0,0,0,0,-30,0,0,0,0,조사팀 파견,,0,1,0,1,0,0,0,0,0,0
|
||||
3,일상,촉수 괴물 출현,출동 승인하시겠습니까?,7구역에 촉수 괴물이 출현했습니다. 작전팀이 법인카드 영수증 제출을 누락해서 출동 승인이 반려된 상태입니다.,규정은 규정입니다. 영수증 없이 세계를 구하는 건 용납할 수 없습니다.,내역 위조 후 출동,,0,0,0,1,0,0,-10,0,0,0,규정대로 반려,,1,1,0,0,0,0,0,0,0,0
|
||||
4,극비,변이 DNA 이식 제안,실험을 승인하시겠습니까?,진화 미래당이 제안합니다. 요원들에게 괴수의 DNA를 소량 이식하면 작전 효율이 300% 상승합니다. 예산은 우리가 대죠.,인간의 한계는 명확합니다. 조금 징그러워지는 것쯤은 감수해야죠.,실험 승인,tag_madness,0,2,0,0,40,40,0,0,0,0,제안 거절,,1,0,0,0,0,0,0,0,0,0
|
||||
5,작전,전술 폭격 건의,폭격을 승인하시겠습니까?,철의 수호당이 민간인 구역에 전술 폭격을 가해 S급 변칙 개체를 제거하자고 건의했습니다.,희생 없는 승리는 없습니다. 소를 위해 대를... 아니 대를 위해 소를 희생하죠.,궤도 폭격 승인,,0,0,0,2,0,0,0,0,2,0,작전 기각,,1,0,0,0,0,0,0,0,0,0
|
||||
6,일상,부산물 암시장 매각,매각을 허가하시겠습니까?,차원 무역당 소속 브로커가 처리된 괴수의 부산물을 암시장에 팔아치우자고 속삭입니다.,이 이빨 하나면 국장님 연봉의 10배입니다. 눈 한 번만 딱 감으시죠.,매각 허가,tag_corruption,0,0,0,1,30,0,0,0,0,0,원칙대로 소각,,0,0,0,0,-10,0,0,0,0,0
|
||||
7,작전,존재 양지화 프로젝트,프로젝트를 승인하시겠습니까?,대중 매체를 장악하여 I.S.C.O의 존재를 서서히 양지화하는 프로젝트입니다. 막대한 정보 토큰이 소모됩니다.,우리가 이 행성의 진짜 지배자임을 알릴 때가 되었습니다.,감시망 구축,tag_coverup,0,0,0,0,0,0,-40,0,0,2,프로젝트 보류,,1,0,0,0,0,0,0,0,0,0
|
||||
8,극비,대규모 도서관 건립,예산을 배정하시겠습니까?,고대 언어 해독을 위해 대규모 도서관 건립이 필요합니다. 지식 보존당이 학자들을 동원할 것입니다.,이해할 수 없는 것을 죽이는 건 야만인이나 하는 짓입니다.,예산 배정,,0,0,0,0,-40,0,40,0,0,0,예산 전액 삭감,,1,0,0,1,0,0,0,0,0,0
|
||||
9,위기,이단 색출 마녀사냥,어떻게 개입하시겠습니까?,기술 원리주의자들이 마녀사냥을 시작했습니다. 기구 내 마법 사용 요원들을 이단으로 규정하고 색출 중입니다.,더러운 마법과 변이에 의존해선 안 됩니다. 오직 순수한 인간의 힘으로!,적당히 묵인한다,,1,0,0,0,0,-30,0,0,0,0,군사력으로 제압,,0,0,0,1,0,0,-20,0,0,0
|
||||
10,일상,변칙 현상 영상 유출,어떻게 처리하시겠습니까?,한 유튜버가 변칙 현상을 촬영해 업로드했습니다. 침묵의 장막당이 즉각적인 물리적 제거와 기억 소거를 요구합니다.,대중은 진실을 감당할 지능이 없습니다. 무덤까지 비밀을 덮으십시오.,제거 절차 승인,tag_coverup,0,0,0,-1,0,0,-20,0,0,0,영상만 삭제,,0,1,0,0,0,0,0,0,0,0
|
||||
11,위기,사이비 종교 인신 공양,어떻게 대응하시겠습니까?,특정 구역의 사이비 종교가 고대 신을 소환하기 위해 시민 100명을 인신 공양하려 합니다. 공존당은 이를 방관하라 합니다.,위대한 그분들이 배가 고프다 하십니다. 조금만 양보하면 평화롭습니다.,군사 개입 지시,,1,0,1,0,0,-40,0,0,0,0,의식 방관,tag_cult,0,2,0,0,0,0,0,0,0,0
|
||||
12,위기,의회의 긴급 감사,어떻게 대처하시겠습니까?,의회에서 국장의 예산 전용 의혹을 제기하며 긴급 감사를 통보했습니다. 장부를 조작해야 합니다!,세상을 구하는 데 돈 좀 쓴 게 죄입니까? 빨리 덮을 정보팀을 부르십시오.,은폐 공작 실행,tag_corruption,0,0,0,1,0,0,-40,0,0,0,횡령 사실 인정,,0,0,0,2,0,0,0,0,0,0
|
||||
13,일상,연구 부서 파업 조짐,요구를 수용하시겠습니까?,연구 부서에서 초과 근무로 인한 집단 피로를 호소하며 휴가와 특별 보너스를 요구하고 있습니다.,저희도 사람입니다. 괴수 해부하다가 과로사하긴 싫어요.,특별 보너스 지급,,-1,0,0,0,-30,0,0,0,0,0,요구 전면 묵살,,1,0,0,0,0,0,0,0,0,0
|
||||
14,작전,이계 무역로 개방,무역로를 개방하시겠습니까?,이계와의 무역로를 임시 개방하여 자원을 조달하자는 안건이 상정되었습니다. 미지의 오염이 우려됩니다.,저 너머의 세계엔 우리가 상상도 못 할 자원이 널려있습니다. 황금알을 낳는 거위죠.,게이트 강제 개방,tag_alien_contact,0,1,0,0,50,0,0,0,0,0,폐쇄 상태 유지,,1,0,0,0,0,0,0,0,0,0
|
||||
15,극비,전임 국장 비밀 금고,금고를 개방하시겠습니까?,전임 국장이 남긴 비밀 금고를 발견했습니다. 여는 데 특수 장비와 전문 인력이 필요합니다.,전임 국장님이 숙청당하기 전 남긴 비자금 장부일지도 모릅니다.,강제 개방 지시,,0,0,0,0,20,-30,0,1,0,0,영구 봉인,,0,0,0,0,0,0,0,0,0,0
|
||||
16,작전,메가코프 협박 작전,작전을 실행하시겠습니까?,글로벌 메가코프를 협박해 I.S.C.O의 비자금을 세탁하고 대규모 자금을 확보할 기회입니다.,그들이 우리 덕분에 안전하게 사업하는 겁니다. 보호세 좀 걷는 게 뭐 어떻습니까.,작전 실행,,0,0,0,0,0,0,-30,2,0,0,작전 취소,,1,0,0,0,0,0,0,0,0,0
|
||||
17,위기,전술 폭격 건의,폭격을 승인하시겠습니까?,제7구역이 S급 변칙 개체에 의해 완전히 붕괴될 위기입니다. 민간인을 포기하고 융단 폭격을 해야 할까요?,시민 10만 명 구출 비용보다 유가족 합의금이 예산을 15% 더 아낄 수 있습니다.,시민 포기 및 폭격,tag_ruthless,0,-1,0,2,0,0,0,0,0,0,결사 방어 명령,,0,0,0,0,-40,-40,0,0,0,0
|
||||
18,일상,행정부 파업 예고,어떻게 대응하시겠습니까?,새로운 회식비 규정이 너무 짜다며 행정부에서 파업을 예고했습니다. 괴수 사체 처리 지연으로 악취가 진동합니다.,기구의 절반은 서류 작업으로 돌아갑니다. 그들을 화나게 해선 안 됩니다.,예산 전용으로 무마,,0,0,0,1,-20,0,0,0,0,0,파업 강경 대응,,1,0,0,0,0,0,0,0,0,0
|
||||
19,극비,불침번 요원 개발,배치하시겠습니까?,비밀 연구소에서 인공지능과 죽은 요원의 뇌를 결합한 불침번 요원을 개발했습니다.,잠도 안 자고 월급도 안 받습니다. 윤리적 문제만 빼면 완벽한 자산이죠.,실전 즉각 배치,,0,1,0,0,0,0,20,0,1,0,즉각 폐기 처분,,1,0,0,0,-10,0,0,0,0,0
|
||||
20,일상,내부 스파이 첩보,어떻게 조사하시겠습니까?,기구 내부에 스파이가 있다는 첩보가 들어왔습니다. 대대적인 사상 검증이 필요할지도 모릅니다.,누군가 정보를 빼돌려 의회에 넘기고 있습니다. 잡히면 믹서기에 넣어야 합니다.,대규모 사찰 시작,,2,0,0,0,0,0,30,0,0,0,증거 부족으로 덮음,,0,0,0,1,0,0,0,0,0,0
|
||||
21,작전,비정상적 위기 발생,"국장님, 결단이 필요합니다.",순수 인간당이 변이의 기미가 보이는 요원들을 격리 수용할 대규모 시설 건립을 제안했습니다.,괴물과 싸우다 보면 괴물이 되는 법. 그들이 선을 넘기 전에 가둬야 합니다.,수용소 건립 승인,,0,0,0,0,-40,0,0,0,1,0,제안 단호히 거절,,1,0,0,1,0,0,0,0,0,0
|
||||
22,극비,이계의 유물 인양,유물을 어떻게 처리하시겠습니까?,고대 공존당의 사제들이 심해의 유물을 인양했습니다. 만지는 자의 정신을 갉아먹지만 막대한 지식을 줍니다.,약간의 두통만 참으면 이계의 비밀을 모두 알 수 있습니다. 요원 하나쯤 미쳐도 괜찮습니다.,유물 집중 연구,tag_alien_contact,0,1,0,0,0,0,50,0,0,0,유물 파괴 명령,,1,0,0,1,0,0,0,0,0,0
|
||||
23,위기,이계의 주시자 출현,대중을 어떻게 통제하시겠습니까?,얇아진 장막 너머로 거대한 눈동자가 며칠째 지구를 주시하고 있습니다. 대중의 공포가 확산되고 있습니다.,하늘을 보지 마십시오. 아니 차라리 눈을 감고 살게 하십시오.,인터넷 전면 차단,,2,0,1,0,0,0,0,0,0,2,진정제 무상 배포,,0,0,0,0,-50,0,0,0,0,0
|
||||
24,일상,요원 집단 트라우마,어떻게 지원하시겠습니까?,요원들이 괴수 진압 후 심각한 트라우마에 시달리고 있습니다. 심리 치료 지원이 시급합니다.,밤마다 촉수가 목을 조르는 악몽을 꾼답니다. 차라리 그 부분 기억을 지워버릴까요?,정신과 치료 지원,,0,0,0,0,-20,10,0,0,0,0,트라우마 기억 소거,,0,1,0,1,0,0,0,0,0,0
|
||||
25,극비,내부 고발자 발생,어떻게 막으시겠습니까?,의회 의원 중 한 명이 기구의 비리를 폭로하려 합니다. 침묵의 장막당이 사고사 처리를 제안합니다.,국장님 계단에서 구르거나 심장마비가 오는 건 아주 흔한 자연의 섭리입니다.,사고사 위장 지시,,0,0,0,-1,0,0,-30,0,0,0,폭로전 정면 돌파,,0,0,0,2,0,0,0,0,0,0
|
||||
26,위기,차원 붕괴 폭탄 오작동,어떻게 대응하시겠습니까?,차원 붕괴 폭탄의 타이머가 오작동을 일으켰습니다! 당장 끄지 않으면 7구역이 통째로 증발합니다.,최저가 입찰로 부품을 사서 폭탄을 만든 결과입니다. 누군가는 책임져야 합니다.,특수 해체팀 투입,,0,0,0,0,0,-40,0,0,0,0,폭발 방관 및 대피,,0,2,0,0,0,0,0,0,0,0
|
||||
27,작전,PMC 흡수 합병,결탁하시겠습니까?,군부와 결탁하여 민간 군사 기업(PMC)을 I.S.C.O의 통제 하에 두려는 작전입니다.,돈으로 충성심을 사는 건 가장 안전한 방법입니다. 물론 돈이 많을 때 이야기죠.,결탁 및 흡수 합병,,0,0,0,0,-40,0,0,0,2,0,독자적 노선 유지,,1,0,0,0,0,0,0,0,0,0
|
||||
28,작전,대규모 거주 구역 실험장화,제안을 승인하시겠습니까?,변칙 개체 관찰을 위해 1구역을 돔으로 덮고 거대한 실험장으로 만들자는 제안이 올라왔습니다.,시민들이 좀 불편해하겠지만 과학적 진보를 위해 그 정도는 감수해야죠.,돔 건설 강행,,0,1,0,0,-50,0,0,0,0,0,윤리적 이유로 기각,,0,0,0,1,0,0,0,0,0,0
|
||||
29,극비,이계 군주의 외교,제안을 수락하시겠습니까?,이계의 군주가 외교 사절을 보내왔습니다. 요원 10명을 노예로 주면 최고급 이계 무기를 주겠다고 합니다.,요원 10명의 생명 가치보다 이계 무기가 가져올 파급력이 월등히 높습니다.,거래 즉시 성사,tag_alien_contact,0,0,0,0,0,-40,0,0,2,0,사절단 전원 사살,,0,1,0,1,0,0,0,0,0,0
|
||||
30,일상,믹스 커피 재고 고갈,어떻게 해결하시겠습니까?,국장님 믹스 커피가 다 떨어졌습니다. 이게 무슨 세상의 종말보다 더 큰 위기인 줄 아십니까? 행정부서의 불만이 폭주합니다.,종말을 결재하기 전엔 커피 한 잔의 여유가 필요한 법입니다. 안 그렇습니까?,최고급 원두 지원,,-1,0,0,0,-10,0,0,0,0,0,헛소리 금지령,,1,0,0,0,0,0,0,0,0,0
|
||||
31,위기,신화적 존재 강림,어떻게 대적하시겠습니까?,신화적 존재가 깨어나려 합니다. 하늘이 피처럼 붉게 물들었고 요원들은 미쳐가고 있습니다!,최종 결재의 시간입니다. 세상의 물리 법칙을 비틀 것입니까 아니면 피로 막을 것입니까?,현실 조작기 가동,,0,2,0,0,0,0,-50,0,0,0,모든 예비병력 투입,,0,0,0,1,0,-60,0,0,0,0
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
|
@@ -1,20 +1,38 @@
|
||||
[
|
||||
{
|
||||
"id": "tag_ruthless",
|
||||
"name": "피도 눈물도 없는 진압",
|
||||
"icon": "🩸",
|
||||
"description": "반발을 무력으로 짓밟았습니다. 공포는 훌륭한 통제 수단입니다."
|
||||
},
|
||||
{
|
||||
"id": "tag_coverup",
|
||||
"name": "진실의 장막",
|
||||
"icon": "🤫",
|
||||
"description": "대중이 알지 못하도록 변칙 사건을 완벽하게 은폐했습니다."
|
||||
},
|
||||
{
|
||||
"id": "tag_alien_contact",
|
||||
"name": "금지된 지식",
|
||||
"icon": "👁️",
|
||||
"description": "이계의 존재와 거래하거나 그들의 유물을 받아들였습니다. 장막 너머의 눈이 당신을 주시합니다."
|
||||
},
|
||||
{
|
||||
"id": "tag_corruption",
|
||||
"name": "부패의 씨앗",
|
||||
"description": "국장님이 비리에 눈을 떴습니다. 횡령과 뇌물 수수에 능숙해졌습니다.",
|
||||
"condition": "budget < 0 or used bribe"
|
||||
"name": "검은 뒷돈",
|
||||
"icon": "💼",
|
||||
"description": "공적인 자산을 사적으로 유용하거나 부당한 거래를 승인했습니다."
|
||||
},
|
||||
{
|
||||
"id": "tag_madness",
|
||||
"name": "광기의 도래",
|
||||
"description": "변칙 개체와의 접촉으로 정신이 오염되었습니다.",
|
||||
"condition": "entropy >= 3"
|
||||
"name": "이성의 붕괴",
|
||||
"icon": "🌀",
|
||||
"description": "요원들을 비인도적인 실험과 광기에 노출시켰습니다. 인간성은 점점 희미해집니다."
|
||||
},
|
||||
{
|
||||
"id": "tag_dictator",
|
||||
"name": "강철의 독재자",
|
||||
"description": "수단과 방법을 가리지 않고 통제력을 강화하고 있습니다.",
|
||||
"condition": "force >= 2"
|
||||
"id": "tag_cult",
|
||||
"name": "사이비의 그림자",
|
||||
"icon": "🌑",
|
||||
"description": "고대 신을 숭배하는 종교와 엮이기 시작했습니다. 그들의 교리가 스며듭니다."
|
||||
}
|
||||
]
|
||||
|
||||
37
client/update_csv_tags.js
Normal file
37
client/update_csv_tags.js
Normal file
@@ -0,0 +1,37 @@
|
||||
import fs from 'fs';
|
||||
import Papa from 'papaparse';
|
||||
|
||||
const csv = fs.readFileSync('./src/data/cards.csv', 'utf-8');
|
||||
const parsed = Papa.parse(csv, { header: true });
|
||||
|
||||
parsed.data.forEach(row => {
|
||||
if (!row.id) return;
|
||||
|
||||
// Initialize empty tags
|
||||
row.left_tag = '';
|
||||
row.right_tag = '';
|
||||
|
||||
// Assign tags based on id or content
|
||||
if (row.id == 1) { row.left_tag = 'tag_ruthless'; } // 무력 진압
|
||||
if (row.id == 4) { row.left_tag = 'tag_madness'; } // DNA 이식 실험 승인
|
||||
if (row.id == 6) { row.left_tag = 'tag_corruption'; } // 부산물 암시장 매각
|
||||
if (row.id == 7) { row.left_tag = 'tag_coverup'; } // 대중 매체 장악 감시망
|
||||
if (row.id == 10) { row.left_tag = 'tag_coverup'; } // 유튜버 제거
|
||||
if (row.id == 11) { row.right_tag = 'tag_cult'; } // 종교 의식 방관
|
||||
if (row.id == 12) { row.left_tag = 'tag_corruption'; } // 장부 은폐 공작
|
||||
if (row.id == 14) { row.left_tag = 'tag_alien_contact'; } // 이계 무역로 개방
|
||||
if (row.id == 17) { row.left_tag = 'tag_ruthless'; } // 시민 포기 및 폭격
|
||||
if (row.id == 22) { row.left_tag = 'tag_alien_contact'; } // 유물 집중 연구
|
||||
if (row.id == 29) { row.left_tag = 'tag_alien_contact'; } // 이계 외교 사절 거래
|
||||
});
|
||||
|
||||
const newCsv = Papa.unparse(parsed.data, {
|
||||
columns: [
|
||||
'id','type','keyword','question','text','flavor',
|
||||
'left_text','left_tag','left_res','left_ent','left_pan','left_rsk','left_bud','left_per','left_inf','left_wea','left_for','left_sur',
|
||||
'right_text','right_tag','right_res','right_ent','right_pan','right_rsk','right_bud','right_per','right_inf','right_wea','right_for','right_sur'
|
||||
]
|
||||
});
|
||||
|
||||
fs.writeFileSync('./src/data/cards.csv', newCsv);
|
||||
console.log('CSV updated with tags');
|
||||
Reference in New Issue
Block a user