Add research support

This commit is contained in:
Anibus
2025-08-18 13:02:10 +03:00
parent f94553bb9a
commit 851bb71601
25 changed files with 714 additions and 311 deletions
+223
View File
@@ -0,0 +1,223 @@
import {Paper, Table, TableCell, TableContainer, TableRow} from "@mui/material";
import React from "react";
import {IModifier} from "../types/IModifier";
import {IconUrl} from "../core/api";
import {IResearch} from "../types/IResearch";
import {Irace} from "../types/Irace";
interface IModifiersProvidesTable{
modifiers: IModifier[],
}
interface IModifiersProvidesResearchTable{
modifiers: IModifier[],
research: IResearch,
race: Irace,
}
function getModName(mt: String){
switch(mt) {
case 'modifiers\\armour_modifier.lua':
return 'Armor';
case 'modifiers\\health_maximum_modifier.lua':
return 'Health';
case 'modifiers\\keen_sight_radius_modifier.lua':
return 'Detect';
case 'modifiers\\sight_radius_modifier.lua':
return 'Sight';
case 'modifiers\\garrison_requisition_modifier.lua':
return 'Requisition';
case 'modifiers\\faith_max_modifier.lua':
return 'Faith max';
case 'modifiers\\holy_icon_cost_power.lua':
return <span>Next icon cost <img style={{verticalAlign: "top"}} src='/images/Resource_power.gif'/></span>;
case 'modifiers\\holy_icon_cost_requisition.lua':
return <span>Next icon cost <img style={{verticalAlign: "top"}} src='/images/Resource_requisition.gif'/></span>;
case 'modifiers\\enable_hardpoint_02.lua':
return 'Weapon slot 2';
case 'modifiers\\default_weapon_modifier_hardpoint1.lua':
return 'Weapon slot 1 change weapon';
case 'modifiers\\default_weapon_modifier_hardpoint2.lua':
return 'Weapon slot 2 change weapon';
case 'modifiers\\default_weapon_modifier_hardpoint3.lua':
return 'Weapon slot 3 change weapon';
case 'modifiers\\default_weapon_modifier_hardpoint4.lua':
return 'Weapon slot 4 change weapon';
case 'modifiers\\default_weapon_modifier_hardpoint5.lua':
return 'Weapon slot 5 change weapon';
case 'modifiers\\default_weapon_modifier_hardpoint6.lua':
return 'Weapon slot 6 change weapon';
case 'modifiers\\morale_maximum_squad_modifier.lua':
return 'Morale';
case 'modifiers\\max_upgrades_squad_modifier.lua':
return 'Max equip weapons';
case 'modifiers\\speed_maximum_modifier.lua':
return 'Max speed';
case 'modifiers\\min_damage_weapon_modifier.lua':
return 'Min damage';
case 'modifiers\\max_damage_weapon_modifier.lua':
return 'Max damage';
case 'modifiers\\enable_armour_2.lua':
return 'Change armor type';
case 'modifiers\\cost_requisition_modifier.lua':
return 'Requisition cost';
default:
return mt.replace("modifiers\\", "").replace("modifier.lua", "").replace(".lua", "").replaceAll("_", " ");
}
}
function getModIcon(mt: String){
switch(mt) {
case 'modifiers\\armour_modifier.lua':
return <img style={{height: 20, verticalAlign: "top"}} src='/images/defence.png'/>;
case 'modifiers\\health_maximum_modifier.lua':
return <img style={{verticalAlign: "top"}} src='/images/Health_icon.webp'/>;
case 'modifiers\\keen_sight_radius_modifier.lua':
return <img style={{verticalAlign: "top"}} src='/images/DETECT_YES.webp'/>;
case 'modifiers\\sight_radius_modifier.lua':
return <img style={{verticalAlign: "top"}} src='/images/DETECT_NO.webp'/>;
case 'modifiers\\faith_max_modifier.lua':
return <img style={{verticalAlign: "top"}} src='/images/Resource_faith.gif'/>;
case 'modifiers\\garrison_requisition_modifier.lua':
return <img style={{verticalAlign: "top"}} src='/images/Resource_requisition.gif'/>;
case 'modifiers\\cost_requisition_modifier.lua':
return <img style={{verticalAlign: "top"}} src='/images/Resource_requisition.gif'/>;
case 'modifiers\\morale_maximum_squad_modifier.lua':
return <img style={{verticalAlign: "top"}} src='/images/ARM_Morale.webp'/>;
default:
return "";
}
}
function getChangeDescription(ref: String, v: number) {
switch(ref) {
case 'type_modifierusagetype\\tp_mod_usage_addition.lua':
if(v < 0){
return v
}else return '+' + v;
case 'type_modifierusagetype\\tp_mod_usage_multiplication.lua':
return 'x' + v;
case 'type_modifierusagetype\\tp_mod_usage_percentage.lua':
return '%' + v;
case 'type_modifierusagetype\\tp_mod_usage_enable.lua':
if(v === 1){
return ' enable ';
} else {
return ' disable ';
}
default:
return ref;
}
}
export function ModifiersProvidesAddonTable (props: IModifiersProvidesTable) {
let noWeaponMods = props.modifiers.filter(m => !m.reference.includes("default_weapon_modifier_hardpoint"))
return (
<TableContainer component={Paper}>
<Table size="small" aria-label="a dense table">
{noWeaponMods.map(m =>
<TableRow
sx={{'&:last-child td, &:last-child th': {border: 0}}}
>
<TableCell component="th" scope="row">{getModName(m.reference)}</TableCell>
<TableCell component="th" scope="row">{getModIcon(m.reference)} {getChangeDescription(m.usageType, m.value)}</TableCell>
</TableRow>
)}
</Table>
</TableContainer>
)
}
export function ModifiersProvidesResearchTable (props: IModifiersProvidesResearchTable) {
let mods = props.modifiers
function getTarget(target: String, research: IResearch, race: Irace) {
console.log(research.affectedUnits.map(au => au.filename))
var affectedUnit = research.affectedUnits.find(au => au.filename.replaceAll('.rgd', '').split(";")[0] === target || au.filename.replaceAll('.rgd', '').split(";")[1] === target);
if(affectedUnit != null) {
return <span><img style={{verticalAlign: "top", height: 25}}
src={getIcon(affectedUnit.icon)}/><a
href={`/mod/${research.modId}/race/${race.id}/unit/${affectedUnit.id}`}>
{affectedUnit.name}
</a></span>
}
var affectedSergeant = research.affectedSergeants.find(as => as.filename.replaceAll('.rgd', '') === target);
if(affectedSergeant != null) {
return <span><img style={{verticalAlign: "top", height: 25}}
src={getIcon(affectedSergeant.icon)}/>{affectedSergeant.name} at <img style={{verticalAlign: "top", height: 25}}
src={getIcon(affectedSergeant.unit.icon)}/><a
href={`/mod/${research.modId}/race/${race.id}/unit/${affectedSergeant.unit.id}`}>
{affectedSergeant.unit.name}
</a></span>
}
var affectedBuilding = research.affectedBuildings.find(ab => ab.filename.replaceAll('.rgd', '') === target);
if(affectedBuilding != null) {
return <span><img style={{verticalAlign: "top", height: 25}} src={getIcon(affectedBuilding.icon)}/><a
href={`/mod/${research.modId}/race/${race.id}/building/${affectedBuilding.id}`}>
{affectedBuilding.name}
</a> </span>
}
var affectedWeapon = research.affectedWeapons.find(aw => aw.filename.replaceAll('.rgd', '') === target);
if (affectedWeapon != null) {
return <span>{affectedWeapon.name ? affectedWeapon.name : affectedWeapon.filename.replaceAll('_', ' ').replace('.rgd', '')} at {
affectedWeapon.units.map(unit =>
<span><img style={{verticalAlign: "top", height: 25}} src={getIcon(unit.icon)}/><a
href={`/mod/${research.modId}/race/${race.id}/unit/${unit.id}`}>
{unit.name}
</a> </span>
)
}
{
affectedWeapon.sergeants.map(affectedSergeant =>
<span><img style={{verticalAlign: "top", height: 25}}
src={getIcon(affectedSergeant.icon)}/>{affectedSergeant.name} at <img
style={{verticalAlign: "top", height: 25}}
src={getIcon(affectedSergeant.unit.icon)}/><a
href={`/mod/${research.modId}/race/${race.id}/unit/${affectedSergeant.unit.id}`}>
{affectedSergeant.unit.name}
</a> </span>
)
}
{
affectedWeapon.buildings.map(affectedBuilding =>
<span><img style={{verticalAlign: "top", height: 25}} src={getIcon(affectedBuilding.icon)}/><a
href={`/mod/${research.modId}/race/${race.id}/building/${affectedBuilding.id}`}>
{affectedBuilding.name}
</a> </span>
)
}
</span>
}
return <span>Unknown target <i>{target}</i></span>;
}
return (
<TableContainer component={Paper}>
<Table size="small" aria-label="a dense table">
{mods.map(m =>
<TableRow
sx={{'&:last-child td, &:last-child th': {border: 0}}}
>
<TableCell component="th" scope="row">{getTarget(m.target, props.research, props.race)}</TableCell>
<TableCell style={{minWidth: 120}} component="th" scope="row">{getModName(m.reference)}</TableCell>
<TableCell component="th" scope="row">{getModIcon(m.reference)} {getChangeDescription(m.usageType, m.value)}</TableCell>
</TableRow>
)}
</Table>
</TableContainer>
)
}
export function getIcon(icon?: string): string{
if(icon !== null && icon !== undefined){
return IconUrl + icon.replaceAll('\\', '/')
} else return '/images/shakal.png'
}