Adding skills & isac talent updates
This commit is contained in:
+225
-5
@@ -644,7 +644,8 @@ if (conditionalRuleColumns.some((column) => column.name === 'trigger_id')) {
|
||||
variant_key TEXT NOT NULL DEFAULT 'base',
|
||||
outcome_key TEXT NOT NULL DEFAULT 'active',
|
||||
application_kind TEXT NOT NULL DEFAULT 'active_modifier' CHECK(application_kind IN (
|
||||
'active_modifier','direct_damage','restore_health','restore_armor','restore_ammo','resource_cost'
|
||||
'active_modifier','direct_damage','restore_health','restore_armor','restore_ammo',
|
||||
'restore_signature_ability_charge','resource_cost'
|
||||
)),
|
||||
effect_scope TEXT NOT NULL DEFAULT 'self' CHECK(effect_scope IN (
|
||||
'self','equipped_weapon','target','allies','self_and_allies','assigned_ability','all_skills'
|
||||
@@ -674,7 +675,9 @@ if (conditionalRuleColumns.some((column) => column.name === 'trigger_id')) {
|
||||
CHECK(
|
||||
(application_kind='active_modifier' AND stat_attribute_id IS NOT NULL AND damage_basis IS NULL)
|
||||
OR (application_kind='direct_damage' AND damage_basis IS NOT NULL)
|
||||
OR application_kind IN ('restore_health','restore_armor','restore_ammo','resource_cost')
|
||||
OR application_kind IN (
|
||||
'restore_health','restore_armor','restore_ammo','restore_signature_ability_charge','resource_cost'
|
||||
)
|
||||
)
|
||||
)`);
|
||||
await database.exec(`INSERT INTO conditional_effect_rules
|
||||
@@ -1205,7 +1208,8 @@ if (sourceOwnedClauseColumns.some((column) => column.name === 'trigger_id')) {
|
||||
variant_key TEXT NOT NULL DEFAULT 'base',
|
||||
outcome_key TEXT NOT NULL DEFAULT 'active',
|
||||
application_kind TEXT NOT NULL DEFAULT 'active_modifier' CHECK(application_kind IN (
|
||||
'active_modifier','direct_damage','restore_health','restore_armor','restore_ammo','resource_cost','marker'
|
||||
'active_modifier','direct_damage','restore_health','restore_armor','restore_ammo',
|
||||
'restore_signature_ability_charge','resource_cost','marker'
|
||||
)),
|
||||
effect_scope TEXT NOT NULL DEFAULT 'self' CHECK(effect_scope IN (
|
||||
'self','equipped_weapon','target','allies','self_and_allies','assigned_ability','all_skills'
|
||||
@@ -1223,7 +1227,9 @@ if (sourceOwnedClauseColumns.some((column) => column.name === 'trigger_id')) {
|
||||
'while_active','on_event','after_event','on_enter','on_exit'
|
||||
)),
|
||||
combat_timing TEXT NOT NULL DEFAULT 'current' CHECK(combat_timing IN ('pre_event','current')),
|
||||
resource_kind TEXT CHECK(resource_kind IS NULL OR resource_kind IN ('health','armor','ammo')),
|
||||
resource_kind TEXT CHECK(resource_kind IS NULL OR resource_kind IN (
|
||||
'health','armor','ammo','signature_ability_charge'
|
||||
)),
|
||||
min_state_value REAL,
|
||||
max_state_value REAL,
|
||||
description_slot INTEGER CHECK(description_slot IS NULL OR description_slot>=1),
|
||||
@@ -1237,7 +1243,10 @@ if (sourceOwnedClauseColumns.some((column) => column.name === 'trigger_id')) {
|
||||
CHECK(
|
||||
(application_kind='active_modifier' AND stat_attribute_id IS NOT NULL AND damage_basis IS NULL)
|
||||
OR (application_kind='direct_damage' AND damage_basis IS NOT NULL)
|
||||
OR application_kind IN ('restore_health','restore_armor','restore_ammo','resource_cost','marker')
|
||||
OR application_kind IN (
|
||||
'restore_health','restore_armor','restore_ammo','restore_signature_ability_charge',
|
||||
'resource_cost','marker'
|
||||
)
|
||||
)
|
||||
)`);
|
||||
await database.exec(`INSERT INTO conditional_effect_outcomes
|
||||
@@ -1253,6 +1262,7 @@ if (sourceOwnedClauseColumns.some((column) => column.name === 'trigger_id')) {
|
||||
WHEN 'restore_health' THEN 'health'
|
||||
WHEN 'restore_armor' THEN 'armor'
|
||||
WHEN 'restore_ammo' THEN 'ammo'
|
||||
WHEN 'restore_signature_ability_charge' THEN 'signature_ability_charge'
|
||||
ELSE NULL END,
|
||||
min_state_value,max_state_value,description_slot,sort_order,created_at,updated_at
|
||||
FROM conditional_effect_outcomes_triggered`);
|
||||
@@ -2127,6 +2137,216 @@ if (skillChipAbilityColumn && Number(skillChipAbilityColumn.notnull) !== 1) {
|
||||
await database.exec('CREATE UNIQUE INDEX IF NOT EXISTS skill_chip_sets_name_nocase_idx ON skill_chip_sets(name COLLATE NOCASE)');
|
||||
await database.exec('CREATE INDEX IF NOT EXISTS skill_chip_sets_ability_idx ON skill_chip_sets(specialization_ability_id,active)');
|
||||
|
||||
const conditionalOutcomeSchema = await (await database.prepare(
|
||||
"SELECT sql FROM sqlite_master WHERE type='table' AND name='conditional_effect_outcomes'"
|
||||
)).get();
|
||||
if (
|
||||
conditionalOutcomeSchema
|
||||
&& !String(conditionalOutcomeSchema.sql ?? '').includes('signature_ability_charge')
|
||||
) {
|
||||
console.log('Adding Signature Ability Charge as a conditional-mechanic resource.');
|
||||
await database.exec('DROP INDEX IF EXISTS conditional_effect_outcomes_rule_idx');
|
||||
await database.exec('PRAGMA foreign_keys=OFF');
|
||||
await database.exec('BEGIN');
|
||||
try {
|
||||
await database.exec('DROP TABLE IF EXISTS conditional_effect_outcomes_signature_charge');
|
||||
await database.exec(`CREATE TABLE conditional_effect_outcomes_signature_charge (
|
||||
id TEXT PRIMARY KEY,
|
||||
rule_id TEXT NOT NULL REFERENCES conditional_effect_rules(id) ON DELETE CASCADE,
|
||||
clause_id TEXT REFERENCES conditional_effect_clauses(id) ON DELETE CASCADE,
|
||||
state_pool_id TEXT REFERENCES conditional_effect_state_pools(id) ON DELETE SET NULL,
|
||||
effect_key TEXT NOT NULL,
|
||||
variant_key TEXT NOT NULL DEFAULT 'base',
|
||||
outcome_key TEXT NOT NULL DEFAULT 'active',
|
||||
application_kind TEXT NOT NULL DEFAULT 'active_modifier' CHECK(application_kind IN (
|
||||
'active_modifier','direct_damage','restore_health','restore_armor','restore_ammo',
|
||||
'restore_signature_ability_charge','resource_cost','marker'
|
||||
)),
|
||||
effect_scope TEXT NOT NULL DEFAULT 'self' CHECK(effect_scope IN (
|
||||
'self','equipped_weapon','target','allies','self_and_allies','assigned_ability','all_skills'
|
||||
)),
|
||||
stat_attribute_id TEXT REFERENCES stat_attributes(id),
|
||||
value REAL NOT NULL,
|
||||
value_expression_json TEXT,
|
||||
value_basis TEXT NOT NULL DEFAULT 'flat' CHECK(value_basis IN (
|
||||
'flat','max_health_percent','current_health_percent','weapon_base_percent'
|
||||
)),
|
||||
value_scaling TEXT NOT NULL DEFAULT 'per_state_unit' CHECK(value_scaling IN ('flat','per_state_unit')),
|
||||
unit TEXT,
|
||||
damage_basis TEXT CHECK(damage_basis IS NULL OR damage_basis IN ('flat','weapon_base_percent')),
|
||||
application_phase TEXT NOT NULL DEFAULT 'while_active' CHECK(application_phase IN (
|
||||
'while_active','on_event','after_event','on_enter','on_exit'
|
||||
)),
|
||||
combat_timing TEXT NOT NULL DEFAULT 'current' CHECK(combat_timing IN ('pre_event','current')),
|
||||
resource_kind TEXT CHECK(resource_kind IS NULL OR resource_kind IN (
|
||||
'health','armor','ammo','signature_ability_charge'
|
||||
)),
|
||||
delivery_mode TEXT NOT NULL DEFAULT 'instant' CHECK(delivery_mode IN ('instant','continuous')),
|
||||
delivery_duration_seconds REAL,
|
||||
min_state_value REAL,
|
||||
max_state_value REAL,
|
||||
description_slot INTEGER CHECK(description_slot IS NULL OR description_slot>=1),
|
||||
sort_order INTEGER NOT NULL CHECK(sort_order>=1),
|
||||
created_at TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL,
|
||||
UNIQUE(rule_id,variant_key,outcome_key,sort_order),
|
||||
CHECK(delivery_duration_seconds IS NULL OR delivery_duration_seconds>0),
|
||||
CHECK(delivery_mode='instant' OR (
|
||||
application_kind IN (
|
||||
'restore_health','restore_armor','restore_ammo','restore_signature_ability_charge'
|
||||
)
|
||||
AND delivery_duration_seconds IS NOT NULL
|
||||
)),
|
||||
CHECK(min_state_value IS NULL OR min_state_value>=0),
|
||||
CHECK(max_state_value IS NULL OR max_state_value>=0),
|
||||
CHECK(min_state_value IS NULL OR max_state_value IS NULL OR max_state_value>=min_state_value),
|
||||
CHECK(
|
||||
(application_kind='active_modifier' AND stat_attribute_id IS NOT NULL AND damage_basis IS NULL)
|
||||
OR (application_kind='direct_damage' AND damage_basis IS NOT NULL)
|
||||
OR application_kind IN (
|
||||
'restore_health','restore_armor','restore_ammo','restore_signature_ability_charge',
|
||||
'resource_cost','marker'
|
||||
)
|
||||
)
|
||||
)`);
|
||||
await database.exec(`INSERT INTO conditional_effect_outcomes_signature_charge (
|
||||
id,rule_id,clause_id,state_pool_id,effect_key,variant_key,outcome_key,
|
||||
application_kind,effect_scope,stat_attribute_id,value,value_expression_json,
|
||||
value_basis,value_scaling,unit,damage_basis,application_phase,combat_timing,
|
||||
resource_kind,delivery_mode,delivery_duration_seconds,min_state_value,max_state_value,
|
||||
description_slot,sort_order,created_at,updated_at
|
||||
)
|
||||
SELECT
|
||||
id,rule_id,clause_id,state_pool_id,effect_key,variant_key,outcome_key,
|
||||
application_kind,effect_scope,stat_attribute_id,value,value_expression_json,
|
||||
value_basis,value_scaling,unit,damage_basis,application_phase,combat_timing,
|
||||
resource_kind,delivery_mode,delivery_duration_seconds,min_state_value,max_state_value,
|
||||
description_slot,sort_order,created_at,updated_at
|
||||
FROM conditional_effect_outcomes`);
|
||||
await database.exec('DROP TABLE conditional_effect_outcomes');
|
||||
await database.exec(
|
||||
'ALTER TABLE conditional_effect_outcomes_signature_charge RENAME TO conditional_effect_outcomes'
|
||||
);
|
||||
await database.exec('COMMIT');
|
||||
} catch (error) {
|
||||
await database.exec('ROLLBACK');
|
||||
throw error;
|
||||
} finally {
|
||||
await database.exec('PRAGMA foreign_keys=ON');
|
||||
}
|
||||
await database.exec(`CREATE INDEX IF NOT EXISTS conditional_effect_outcomes_rule_idx
|
||||
ON conditional_effect_outcomes(rule_id,variant_key,outcome_key,sort_order)`);
|
||||
}
|
||||
|
||||
const reloadOutcomeSchema = await (await database.prepare(
|
||||
"SELECT sql FROM sqlite_master WHERE type='table' AND name='conditional_effect_outcomes'"
|
||||
)).get();
|
||||
if (
|
||||
reloadOutcomeSchema
|
||||
&& !String(reloadOutcomeSchema.sql ?? '').includes("'weapon_reload'")
|
||||
) {
|
||||
console.log('Adding inactive-weapon reload actions to conditional mechanics.');
|
||||
await database.exec('DROP INDEX IF EXISTS conditional_effect_outcomes_rule_idx');
|
||||
await database.exec('PRAGMA foreign_keys=OFF');
|
||||
await database.exec('BEGIN');
|
||||
try {
|
||||
await database.exec('DROP TABLE IF EXISTS conditional_effect_outcomes_weapon_reload');
|
||||
await database.exec(`CREATE TABLE conditional_effect_outcomes_weapon_reload (
|
||||
id TEXT PRIMARY KEY,
|
||||
rule_id TEXT NOT NULL REFERENCES conditional_effect_rules(id) ON DELETE CASCADE,
|
||||
clause_id TEXT REFERENCES conditional_effect_clauses(id) ON DELETE CASCADE,
|
||||
state_pool_id TEXT REFERENCES conditional_effect_state_pools(id) ON DELETE SET NULL,
|
||||
effect_key TEXT NOT NULL,
|
||||
variant_key TEXT NOT NULL DEFAULT 'base',
|
||||
outcome_key TEXT NOT NULL DEFAULT 'active',
|
||||
application_kind TEXT NOT NULL DEFAULT 'active_modifier' CHECK(application_kind IN (
|
||||
'active_modifier','direct_damage','restore_health','restore_armor','restore_ammo',
|
||||
'restore_signature_ability_charge','resource_cost','weapon_reload','marker'
|
||||
)),
|
||||
effect_scope TEXT NOT NULL DEFAULT 'self' CHECK(effect_scope IN (
|
||||
'self','equipped_weapon','inactive_weapon','target','allies','self_and_allies',
|
||||
'assigned_ability','all_skills'
|
||||
)),
|
||||
stat_attribute_id TEXT REFERENCES stat_attributes(id),
|
||||
value REAL NOT NULL,
|
||||
value_expression_json TEXT,
|
||||
value_basis TEXT NOT NULL DEFAULT 'flat' CHECK(value_basis IN (
|
||||
'flat','max_health_percent','current_health_percent','weapon_base_percent'
|
||||
)),
|
||||
value_scaling TEXT NOT NULL DEFAULT 'per_state_unit' CHECK(value_scaling IN ('flat','per_state_unit')),
|
||||
unit TEXT,
|
||||
damage_basis TEXT CHECK(damage_basis IS NULL OR damage_basis IN ('flat','weapon_base_percent')),
|
||||
application_phase TEXT NOT NULL DEFAULT 'while_active' CHECK(application_phase IN (
|
||||
'while_active','on_event','after_event','on_enter','on_exit'
|
||||
)),
|
||||
combat_timing TEXT NOT NULL DEFAULT 'current' CHECK(combat_timing IN ('pre_event','current')),
|
||||
resource_kind TEXT CHECK(resource_kind IS NULL OR resource_kind IN (
|
||||
'health','armor','ammo','signature_ability_charge'
|
||||
)),
|
||||
delivery_mode TEXT NOT NULL DEFAULT 'instant' CHECK(delivery_mode IN ('instant','continuous')),
|
||||
delivery_duration_seconds REAL,
|
||||
min_state_value REAL,
|
||||
max_state_value REAL,
|
||||
description_slot INTEGER CHECK(description_slot IS NULL OR description_slot>=1),
|
||||
sort_order INTEGER NOT NULL CHECK(sort_order>=1),
|
||||
created_at TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL,
|
||||
UNIQUE(rule_id,variant_key,outcome_key,sort_order),
|
||||
CHECK(delivery_duration_seconds IS NULL OR delivery_duration_seconds>0),
|
||||
CHECK(delivery_mode='instant' OR (
|
||||
application_kind IN (
|
||||
'restore_health','restore_armor','restore_ammo','restore_signature_ability_charge'
|
||||
)
|
||||
AND delivery_duration_seconds IS NOT NULL
|
||||
)),
|
||||
CHECK(min_state_value IS NULL OR min_state_value>=0),
|
||||
CHECK(max_state_value IS NULL OR max_state_value>=0),
|
||||
CHECK(min_state_value IS NULL OR max_state_value IS NULL OR max_state_value>=min_state_value),
|
||||
CHECK(
|
||||
(application_kind='active_modifier' AND stat_attribute_id IS NOT NULL AND damage_basis IS NULL)
|
||||
OR (application_kind='direct_damage' AND damage_basis IS NOT NULL)
|
||||
OR application_kind IN (
|
||||
'restore_health','restore_armor','restore_ammo','restore_signature_ability_charge',
|
||||
'resource_cost','weapon_reload','marker'
|
||||
)
|
||||
)
|
||||
)`);
|
||||
await database.exec(`INSERT INTO conditional_effect_outcomes_weapon_reload (
|
||||
id,rule_id,clause_id,state_pool_id,effect_key,variant_key,outcome_key,
|
||||
application_kind,effect_scope,stat_attribute_id,value,value_expression_json,
|
||||
value_basis,value_scaling,unit,damage_basis,application_phase,combat_timing,
|
||||
resource_kind,delivery_mode,delivery_duration_seconds,min_state_value,max_state_value,
|
||||
description_slot,sort_order,created_at,updated_at
|
||||
)
|
||||
SELECT
|
||||
id,rule_id,clause_id,state_pool_id,effect_key,variant_key,outcome_key,
|
||||
application_kind,effect_scope,stat_attribute_id,value,value_expression_json,
|
||||
value_basis,value_scaling,unit,damage_basis,application_phase,combat_timing,
|
||||
resource_kind,delivery_mode,delivery_duration_seconds,min_state_value,max_state_value,
|
||||
description_slot,sort_order,created_at,updated_at
|
||||
FROM conditional_effect_outcomes`);
|
||||
await database.exec('DROP TABLE conditional_effect_outcomes');
|
||||
await database.exec(
|
||||
'ALTER TABLE conditional_effect_outcomes_weapon_reload RENAME TO conditional_effect_outcomes'
|
||||
);
|
||||
await database.exec('COMMIT');
|
||||
} catch (error) {
|
||||
await database.exec('ROLLBACK');
|
||||
throw error;
|
||||
} finally {
|
||||
await database.exec('PRAGMA foreign_keys=ON');
|
||||
}
|
||||
await database.exec(`CREATE INDEX IF NOT EXISTS conditional_effect_outcomes_rule_idx
|
||||
ON conditional_effect_outcomes(rule_id,variant_key,outcome_key,sort_order)`);
|
||||
}
|
||||
|
||||
const outcomeTargetingColumns = await (
|
||||
await database.prepare("PRAGMA table_info('conditional_effect_outcomes')")
|
||||
).all();
|
||||
if (!outcomeTargetingColumns.some((column) => column.name === 'targeting_json')) {
|
||||
await database.exec('ALTER TABLE conditional_effect_outcomes ADD COLUMN targeting_json TEXT');
|
||||
}
|
||||
|
||||
const calibrationCases = await (await database.prepare(
|
||||
'SELECT id,loadout_snapshot_json FROM calculation_calibration_cases'
|
||||
)).all();
|
||||
|
||||
Reference in New Issue
Block a user