272 lines
14 KiB
TypeScript
272 lines
14 KiB
TypeScript
import {Paper, Table, TableCell, TableContainer, TableRow} from "@mui/material";
|
|
import React from "react";
|
|
import {useTheme} from "@mui/material/styles";
|
|
import {IModifier} from "../types/IModifier";
|
|
import {IconUrl} from "../core/api";
|
|
import {Irace} from "../types/Irace";
|
|
import {IAffectedData} from "../types/IAffectedData";
|
|
import {IMod} from "../types/Imod";
|
|
import AvTimerOutlinedIcon from "@mui/icons-material/AvTimer";
|
|
import {styled} from '@mui/material/styles';
|
|
import {StyledLink} from "../commons/StyledLink";
|
|
import {StyledPaper} from "../commons/StyledPaper";
|
|
|
|
|
|
interface IModifiersProvidesTable {
|
|
modifiers: IModifier[],
|
|
}
|
|
|
|
interface IModifiersProvidesResearchTable {
|
|
modifiers: IModifier[],
|
|
affectedData: IAffectedData | null,
|
|
modId: number,
|
|
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';
|
|
case 'modifiers\\cost_power_modifier.lua':
|
|
return 'Power cost';
|
|
case 'modifiers\\cost_time_modifier.lua':
|
|
return 'Cost time';
|
|
case 'modifiers\\income_requisition_player_modifier.lua':
|
|
return 'Global income requisition';
|
|
case 'modifiers\\income_power_player_modifier.lua':
|
|
return 'Global income power';
|
|
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\\cost_power_modifier.lua':
|
|
return <img style={{verticalAlign: "top"}} src='/images/Resource_power.gif'/>;
|
|
case 'modifiers\\morale_maximum_squad_modifier.lua':
|
|
return <img style={{verticalAlign: "top"}} src='/images/ARM_Morale.webp'/>;
|
|
case 'modifiers\\support_cap_player_modifier.lua':
|
|
return <img style={{verticalAlign: "top"}} src='/images/Resource_cap_vehicle.gif'/>;
|
|
case 'modifiers\\squad_cap_player_modifier.lua':
|
|
return <img style={{verticalAlign: "top"}} src='/images/Resource_cap_infantry.gif'/>;
|
|
case 'modifiers\\population_cap_player_modifier.lua':
|
|
return <img style={{verticalAlign: "top"}} src='/images/Resource_orksquadcap.gif'/>;
|
|
case 'modifiers\\income_requisition_player_modifier.lua':
|
|
return <img style={{verticalAlign: "top"}} src='/images/Resource_requisition.gif'/>;
|
|
case 'modifiers\\income_power_player_modifier.lua':
|
|
return <img style={{verticalAlign: "top"}} src='/images/Resource_power.gif'/>;
|
|
case 'modifiers\\cost_time_modifier.lua':
|
|
return <AvTimerOutlinedIcon
|
|
style={{verticalAlign: "top", fontSize: "18px"}}/>;
|
|
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) {
|
|
const theme = useTheme();
|
|
const isDark = theme.palette.mode === 'dark';
|
|
const textColor = isDark ? '#dee2e6' : 'rgba(0, 0, 0, 0.85)';
|
|
|
|
let noWeaponMods = props.modifiers.filter(m => !m.reference.includes("default_weapon_modifier_hardpoint"))
|
|
|
|
return (
|
|
<TableContainer component={StyledPaper} elevation={0}>
|
|
<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" sx={{color: textColor}}>{getModName(m.reference)}</TableCell>
|
|
<TableCell component="th" scope="row" sx={{color: textColor}}>{getModIcon(m.reference)} {getChangeDescription(m.usageType, m.value)}</TableCell>
|
|
</TableRow>
|
|
)}
|
|
</Table>
|
|
</TableContainer>
|
|
)
|
|
}
|
|
|
|
export function ModifiersProvidesTable(props: IModifiersProvidesResearchTable) {
|
|
const theme = useTheme();
|
|
const isDark = theme.palette.mode === 'dark';
|
|
const textColor = isDark ? '#dee2e6' : 'rgba(0, 0, 0, 0.85)';
|
|
|
|
let mods = props.modifiers
|
|
|
|
function getTarget(target: String) {
|
|
if (props.affectedData !== null) {
|
|
console.log(props.affectedData.affectedUnits.map(au => au.filename))
|
|
var affectedUnit = props.affectedData.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)}/><StyledLink
|
|
href={`/mod/${props.modId}/race/${props.race.id}/unit/${affectedUnit.id}`}>
|
|
{affectedUnit.name}
|
|
</StyledLink></span>
|
|
}
|
|
var affectedSergeant = props.affectedData.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)}/><StyledLink
|
|
href={`/mod/${props.modId}/race/${props.race.id}/unit/${affectedSergeant.unit.id}`}>
|
|
{affectedSergeant.unit.name}
|
|
</StyledLink></span>
|
|
}
|
|
var affectedBuilding = props.affectedData.affectedBuildings.find(ab => ab.filename.replaceAll('.rgd', '') === target);
|
|
if (affectedBuilding != null) {
|
|
return <span><img style={{verticalAlign: "top", height: 25}} src={getIcon(affectedBuilding.icon)}/><StyledLink
|
|
href={`/mod/${props.modId}/race/${props.race.id}/building/${affectedBuilding.id}`}>
|
|
{affectedBuilding.name}
|
|
</StyledLink> </span>
|
|
}
|
|
|
|
var affectedWeapon = props.affectedData.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>{affectedWeapon != null && affectedWeapon.units.length + affectedWeapon.sergeants.length > 1 ? <br/> : <span></span>}<img style={{verticalAlign: "top", height: 25}} src={getIcon(unit.icon)}/><StyledLink
|
|
href={`/mod/${props.modId}/race/${props.race.id}/unit/${unit.id}`}>
|
|
{unit.name}
|
|
</StyledLink> </span>
|
|
)
|
|
}
|
|
{
|
|
affectedWeapon.sergeants.map(affectedSergeant =>
|
|
<span>{affectedWeapon != null && affectedWeapon.units.length + affectedWeapon.sergeants.length > 1 ? <br/> : <span></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)}/><StyledLink
|
|
href={`/mod/${props.modId}/race/${props.race.id}/unit/${affectedSergeant.unit.id}`}>
|
|
{affectedSergeant.unit.name}
|
|
</StyledLink> </span>
|
|
)
|
|
}
|
|
{
|
|
affectedWeapon.buildings.map(affectedBuilding =>
|
|
<span><img style={{verticalAlign: "top", height: 25}} src={getIcon(affectedBuilding.icon)}/><StyledLink
|
|
href={`/mod/${props.modId}/race/${props.race.id}/building/${affectedBuilding.id}`}>
|
|
{affectedBuilding.name}
|
|
</StyledLink> </span>
|
|
)
|
|
}
|
|
</span>
|
|
}
|
|
}
|
|
|
|
return <span><i>{target}</i></span>;
|
|
}
|
|
|
|
return (
|
|
<TableContainer component={StyledPaper} elevation={0}>
|
|
<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" sx={{color: textColor}}>{getTarget(m.target)}</TableCell>
|
|
<TableCell component="th" scope="row" sx={{color: textColor, minWidth: 120}}>{getModName(m.reference)}</TableCell>
|
|
<TableCell component="th" scope="row" sx={{color: textColor}}>{getModIcon(m.reference)} {getChangeDescription(m.usageType, m.value)}
|
|
{m.maxLifeTime !== undefined && m.maxLifeTime > 0 &&
|
|
<span><img style={{verticalAlign: "top"}} src='/images/Time_icon.webp'/>{m.maxLifeTime}s
|
|
</span>}
|
|
<i style={{fontSize: 11}}>{m.exclusive ? " does not stack" : " does stack"}</i>
|
|
{m.probabilityOfApplying !== undefined && m.probabilityOfApplying !== 1.0 &&
|
|
<span><i style={{fontSize: 11, color: 'rgba(255,255,255,0.5)'}}> ({m.probabilityOfApplying * 100}% chance)</i>
|
|
</span>}
|
|
</TableCell>
|
|
</TableRow>
|
|
)}
|
|
</Table>
|
|
</TableContainer>
|
|
)
|
|
}
|
|
|
|
export function getIcon(icon?: string): string {
|
|
if (icon !== null && icon !== undefined) {
|
|
return IconUrl + icon.replaceAll('\\', '/')
|
|
} else return '/images/NoImg.png'
|
|
}
|
|
|
|
|