Add some params
- start jump charge - building limit - movement params Rework weapon dps one hit and add dps move
This commit is contained in:
@@ -224,6 +224,12 @@ function Building(building: IBuilding, mod: IMod, theme: Theme, racesUnits: IRac
|
|||||||
<TableCell component="th" scope="row" >Repair max</TableCell>
|
<TableCell component="th" scope="row" >Repair max</TableCell>
|
||||||
<TableCell>{building.repairMax}</TableCell>
|
<TableCell>{building.repairMax}</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
|
{building.buildingLimit !== undefined && building.buildingLimit !== null &&
|
||||||
|
<TableRow sx={{ '&:last-child td, &:last-child th': { border: 0 } }}>
|
||||||
|
<TableCell component="th" scope="row" >Limit</TableCell>
|
||||||
|
<TableCell>{building.buildingLimit}</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
}
|
||||||
</TableBody>
|
</TableBody>
|
||||||
</Table>
|
</Table>
|
||||||
</StatsPaper>
|
</StatsPaper>
|
||||||
@@ -258,9 +264,7 @@ function Building(building: IBuilding, mod: IMod, theme: Theme, racesUnits: IRac
|
|||||||
</Grid2>}
|
</Grid2>}
|
||||||
{building.deathExplosions.length > 0 &&
|
{building.deathExplosions.length > 0 &&
|
||||||
<Grid2 size={12}>
|
<Grid2 size={12}>
|
||||||
{building.deathExplosions.map(da =>
|
<DeathExplosion deathExplosions={building.deathExplosions} mod={mod} />
|
||||||
<DeathExplosion deathExplosion={da} mod={mod} />
|
|
||||||
)}
|
|
||||||
</Grid2>
|
</Grid2>
|
||||||
}
|
}
|
||||||
{building.addons.length > 0 && <Grid2 size={12}>
|
{building.addons.length > 0 && <Grid2 size={12}>
|
||||||
|
|||||||
@@ -260,8 +260,33 @@ function Unit(unit: IUnit, mod: IMod, theme: Theme, racesUnits: IRaceUnits[], ra
|
|||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell >Move speed</TableCell>
|
<TableCell >Movement</TableCell>
|
||||||
<TableCell>{unit.moveSpeed}</TableCell>
|
<TableCell>
|
||||||
|
<span style={{ display: 'inline-flex', alignItems: 'center', gap: 12, flexWrap: 'wrap' }}>
|
||||||
|
<span style={{ display: 'inline-flex', alignItems: 'center' }}>
|
||||||
|
<Tooltip title="Movement speed"><span><img style={{ height: 20, verticalAlign: "top" }} src="/images/Movement_speed.svg" /></span></Tooltip>
|
||||||
|
{unit.moveSpeed}
|
||||||
|
</span>
|
||||||
|
{unit.accelerationTime !== undefined && unit.accelerationTime !== null &&
|
||||||
|
<span style={{ display: 'inline-flex', alignItems: 'center' }}>
|
||||||
|
<Tooltip title="Acceleration time"><span><img style={{ height: 20, verticalAlign: "top" }} src="/images/Movement_acceleration.svg" /></span></Tooltip>
|
||||||
|
{unit.accelerationTime}s
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
{unit.decelerationTime !== undefined && unit.decelerationTime !== null &&
|
||||||
|
<span style={{ display: 'inline-flex', alignItems: 'center' }}>
|
||||||
|
<Tooltip title="Deceleration time"><span><img style={{ height: 20, verticalAlign: "top" }} src="/images/Movement_deceleration.svg" /></span></Tooltip>
|
||||||
|
{unit.decelerationTime}s
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
{unit.rotationRate !== undefined && unit.rotationRate !== null &&
|
||||||
|
<span style={{ display: 'inline-flex', alignItems: 'center' }}>
|
||||||
|
<Tooltip title="Rotation rate"><span><img style={{ height: 20, verticalAlign: "top" }} src="/images/Movement_rotation.svg" /></span></Tooltip>
|
||||||
|
{unit.rotationRate}
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
</span>
|
||||||
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell >Morale</TableCell>
|
<TableCell >Morale</TableCell>
|
||||||
@@ -316,6 +341,7 @@ function Unit(unit: IUnit, mod: IMod, theme: Theme, racesUnits: IRaceUnits[], ra
|
|||||||
{unit.sergeants.map(s =>
|
{unit.sergeants.map(s =>
|
||||||
<SergeantAccordion key={s.id} TransitionProps={{ unmountOnExit: true, timeout: 100 }}>
|
<SergeantAccordion key={s.id} TransitionProps={{ unmountOnExit: true, timeout: 100 }}>
|
||||||
<AccordionSummary
|
<AccordionSummary
|
||||||
|
expandIcon={<ExpandMore sx={{ color: isDark ? '#dee2e6' : 'rgba(0, 0, 0, 0.85)' }} />}
|
||||||
sx={{ color: isDark ? '#dee2e6' : 'rgba(0, 0, 0, 0.85)', '& .MuiAccordionSummary-content': { margin: '12px 0' }, '& .MuiAccordionSummary-content.Mui-expanded': { margin: '12px 0' } }}>
|
sx={{ color: isDark ? '#dee2e6' : 'rgba(0, 0, 0, 0.85)', '& .MuiAccordionSummary-content': { margin: '12px 0' }, '& .MuiAccordionSummary-content.Mui-expanded': { margin: '12px 0' } }}>
|
||||||
<SergeantShort name={s.name} icon={s.icon} canDetect={s.detectRadius > 0} />
|
<SergeantShort name={s.name} icon={s.icon} canDetect={s.detectRadius > 0} />
|
||||||
</AccordionSummary>
|
</AccordionSummary>
|
||||||
@@ -356,9 +382,7 @@ function Unit(unit: IUnit, mod: IMod, theme: Theme, racesUnits: IRaceUnits[], ra
|
|||||||
</Grid2>
|
</Grid2>
|
||||||
{unit.deathExplosions.length > 0 &&
|
{unit.deathExplosions.length > 0 &&
|
||||||
<Grid2 size={12}>
|
<Grid2 size={12}>
|
||||||
{unit.deathExplosions.map(da =>
|
<DeathExplosion deathExplosions={unit.deathExplosions} mod={mod} />
|
||||||
<DeathExplosion deathExplosion={da} mod={mod} />
|
|
||||||
)}
|
|
||||||
</Grid2>
|
</Grid2>
|
||||||
}
|
}
|
||||||
<Grid2 size={12}>
|
<Grid2 size={12}>
|
||||||
|
|||||||
+1
-1
@@ -9,7 +9,7 @@ import { IUnit } from '@/src/types/IUnit';
|
|||||||
import { IBuilding } from '@/src/types/IBuilding';
|
import { IBuilding } from '@/src/types/IBuilding';
|
||||||
|
|
||||||
const API = process.env.HOST_URL || '';
|
const API = process.env.HOST_URL || '';
|
||||||
export const SITE_URL = process.env.NEXT_PUBLIC_SITE_URL || 'https://wiki.dawn-of-war.pro';
|
export const SITE_URL = 'https://wiki.dawn-of-war.pro';
|
||||||
|
|
||||||
async function fetchJson<T>(url: string): Promise<T | null> {
|
async function fetchJson<T>(url: string): Promise<T | null> {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#64b5f6" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<path d="M7 21 V9"/>
|
||||||
|
<path d="M2.5 13.5 L7 9 L11.5 13.5"/>
|
||||||
|
<path d="M17 21 V3"/>
|
||||||
|
<path d="M12.5 7.5 L17 3 L21.5 7.5"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 313 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#64b5f6" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<path d="M7 3 V15"/>
|
||||||
|
<path d="M2.5 10.5 L7 15 L11.5 10.5"/>
|
||||||
|
<path d="M17 3 V21"/>
|
||||||
|
<path d="M12.5 16.5 L17 21 L21.5 16.5"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 317 B |
@@ -0,0 +1,4 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#64b5f6" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<path d="M21 12 a9 9 0 1 1 -2.64 -6.36"/>
|
||||||
|
<path d="M21 3 v6 h-6"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 255 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#64b5f6" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<path d="M3 8 H16"/>
|
||||||
|
<path d="M12 4 L16 8 L12 12"/>
|
||||||
|
<path d="M3 16 H16"/>
|
||||||
|
<path d="M12 12 L16 16 L12 20"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 301 B |
@@ -134,9 +134,7 @@ function AbilitySpawnedObject(props: AbilityEnvironmentProps) {
|
|||||||
</Grid2>}
|
</Grid2>}
|
||||||
{abilityEnvironment.deathExplosions.length > 0 &&
|
{abilityEnvironment.deathExplosions.length > 0 &&
|
||||||
<Grid2 size={12}>
|
<Grid2 size={12}>
|
||||||
{abilityEnvironment.deathExplosions.map(da =>
|
<DeathExplosion deathExplosions={abilityEnvironment.deathExplosions} mod={props.mod}/>
|
||||||
<DeathExplosion deathExplosion={da} mod={props.mod}/>
|
|
||||||
)}
|
|
||||||
</Grid2>
|
</Grid2>
|
||||||
}
|
}
|
||||||
</Grid2>
|
</Grid2>
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ import {StyledTableCell} from "../commons/StyledTableCell";
|
|||||||
|
|
||||||
|
|
||||||
interface DeathExpProps {
|
interface DeathExpProps {
|
||||||
deathExplosion: IDeathExplosion,
|
deathExplosions: IDeathExplosion[],
|
||||||
mod: IMod,
|
mod: IMod,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,10 +40,11 @@ function DeathExplosion(props: DeathExpProps) {
|
|||||||
const isDark = theme.palette.mode === 'dark';
|
const isDark = theme.palette.mode === 'dark';
|
||||||
const textColor = isDark ? '#dee2e6' : 'rgba(0, 0, 0, 0.85)';
|
const textColor = isDark ? '#dee2e6' : 'rgba(0, 0, 0, 0.85)';
|
||||||
|
|
||||||
const deathExplosion = props.deathExplosion
|
const deathExplosions = props.deathExplosions.filter(deathExplosion =>
|
||||||
const chanceTotalNotZero = deathExplosion.globalChance * deathExplosion.chance != 0
|
deathExplosion.globalChance * deathExplosion.chance != 0
|
||||||
|
)
|
||||||
|
|
||||||
return chanceTotalNotZero ?
|
return deathExplosions.length > 0 ?
|
||||||
<div className='addon-research-accordion' id='death-explosion'><StyledAccordion>
|
<div className='addon-research-accordion' id='death-explosion'><StyledAccordion>
|
||||||
<AccordionSummary
|
<AccordionSummary
|
||||||
sx={{color: textColor, '& .MuiAccordionSummary-content': { margin: '12px 0' }, '& .MuiAccordionSummary-content.Mui-expanded': { margin: '12px 0' }}}
|
sx={{color: textColor, '& .MuiAccordionSummary-content': { margin: '12px 0' }, '& .MuiAccordionSummary-content.Mui-expanded': { margin: '12px 0' }}}
|
||||||
@@ -55,7 +56,9 @@ function DeathExplosion(props: DeathExpProps) {
|
|||||||
</span>
|
</span>
|
||||||
</AccordionSummary>
|
</AccordionSummary>
|
||||||
<AccordionDetails sx={{color: textColor}}>
|
<AccordionDetails sx={{color: textColor}}>
|
||||||
<Grid2 container spacing={2}>
|
{deathExplosions.map((deathExplosion, index) =>
|
||||||
|
<Grid2 container spacing={2} key={deathExplosion.id ?? index}
|
||||||
|
sx={{mt: index > 0 ? 2 : 0}}>
|
||||||
<Grid2 size={{xs: 12, md: 4}}>
|
<Grid2 size={{xs: 12, md: 4}}>
|
||||||
<TableContainer component={StyledPaper} elevation={0}>
|
<TableContainer component={StyledPaper} elevation={0}>
|
||||||
<Table size="small" aria-label="a dense table">
|
<Table size="small" aria-label="a dense table">
|
||||||
@@ -87,6 +90,7 @@ function DeathExplosion(props: DeathExpProps) {
|
|||||||
moraleDamage={deathExplosion.moraleDamage}/>
|
moraleDamage={deathExplosion.moraleDamage}/>
|
||||||
</Grid2>
|
</Grid2>
|
||||||
</Grid2>
|
</Grid2>
|
||||||
|
)}
|
||||||
</AccordionDetails>
|
</AccordionDetails>
|
||||||
</StyledAccordion></div> : <span></span>
|
</StyledAccordion></div> : <span></span>
|
||||||
|
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ function Jump(props: IJumpProps) {
|
|||||||
{ label: "Distance", value: jumps.jumpDistanceMax.toFixed(0) },
|
{ label: "Distance", value: jumps.jumpDistanceMax.toFixed(0) },
|
||||||
{ label: "Setup time", value: <span><img style={{verticalAlign: "top"}} src="/images/Time_icon.webp"/> {jumps.setupTime}s</span> },
|
{ label: "Setup time", value: <span><img style={{verticalAlign: "top"}} src="/images/Time_icon.webp"/> {jumps.setupTime}s</span> },
|
||||||
{ label: "Breakdown time", value: <span><img style={{verticalAlign: "top"}} src="/images/Time_icon.webp"/> {jumps.breakdownTime}s</span> },
|
{ label: "Breakdown time", value: <span><img style={{verticalAlign: "top"}} src="/images/Time_icon.webp"/> {jumps.breakdownTime}s</span> },
|
||||||
|
{ label: "Starting charge", value: `${(jumps.chargeStartingFraction * 100).toFixed(0)}%` }
|
||||||
];
|
];
|
||||||
if (!isTeleport) {
|
if (!isTeleport) {
|
||||||
if (jumps.goUpTime !== undefined && jumps.goUpTime !== null) {
|
if (jumps.goUpTime !== undefined && jumps.goUpTime !== null) {
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ function Required (props: IRequiredProps) {
|
|||||||
return <span> One <img style={{verticalAlign: "top", height: 25}}
|
return <span> One <img style={{verticalAlign: "top", height: 25}}
|
||||||
src={IconUrl + limitPerBuilding.building.icon.replaceAll('\\', '/')}/>
|
src={IconUrl + limitPerBuilding.building.icon.replaceAll('\\', '/')}/>
|
||||||
{" "}<StyledLink href={`/mod/${props.modId}/race/${props.raceId}/building/${limitPerBuilding.building.id}`}>
|
{" "}<StyledLink href={`/mod/${props.modId}/race/${props.raceId}/building/${limitPerBuilding.building.id}`}>
|
||||||
{limitPerBuilding.building.name} </StyledLink> allow produce max {limitPerBuilding.limit}</span>
|
{limitPerBuilding.building.name} </StyledLink> allows producing a maximum of {limitPerBuilding.limit}</span>
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderRequirementResearches(requirementResearches: IResearchRequirements[],) {
|
function renderRequirementResearches(requirementResearches: IResearchRequirements[],) {
|
||||||
|
|||||||
@@ -187,9 +187,7 @@ const Sergeant = (props: SergeantProps) => {
|
|||||||
</Grid2>
|
</Grid2>
|
||||||
{sergeant.deathExplosions.length > 0 &&
|
{sergeant.deathExplosions.length > 0 &&
|
||||||
<Grid2 size={12}>
|
<Grid2 size={12}>
|
||||||
{sergeant.deathExplosions.map(da =>
|
<DeathExplosion deathExplosions={sergeant.deathExplosions} mod={props.mod}/>
|
||||||
<DeathExplosion deathExplosion={da} mod={props.mod}/>
|
|
||||||
)}
|
|
||||||
</Grid2>
|
</Grid2>
|
||||||
}
|
}
|
||||||
<Grid2 size={12}>
|
<Grid2 size={12}>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import {
|
|||||||
TableBody,
|
TableBody,
|
||||||
TableCell,
|
TableCell,
|
||||||
TableContainer, TableHead,
|
TableContainer, TableHead,
|
||||||
TableRow, ToggleButton, ToggleButtonGroup
|
TableRow, ToggleButton, ToggleButtonGroup, Slider
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import ArmorType from "./ArmorType";
|
import ArmorType from "./ArmorType";
|
||||||
import Required from "./Required";
|
import Required from "./Required";
|
||||||
@@ -43,6 +43,7 @@ export default function WeaponFull(props: {weaponId: number, isDefault: Boolean,
|
|||||||
});
|
});
|
||||||
|
|
||||||
const [enabledResearchIds, setEnabledResearchIds] = useState<Set<number>>(new Set());
|
const [enabledResearchIds, setEnabledResearchIds] = useState<Set<number>>(new Set());
|
||||||
|
const [damageRoll, setDamageRoll] = useState<number | null>(null);
|
||||||
|
|
||||||
function applyResearchEffects(weapon: IWeapon, enabledIds: Set<number>): IWeapon {
|
function applyResearchEffects(weapon: IWeapon, enabledIds: Set<number>): IWeapon {
|
||||||
if (enabledIds.size === 0 || !weapon.researches || weapon.researches.length === 0) {
|
if (enabledIds.size === 0 || !weapon.researches || weapon.researches.length === 0) {
|
||||||
@@ -137,10 +138,18 @@ export default function WeaponFull(props: {weaponId: number, isDefault: Boolean,
|
|||||||
currentTable: selectedDamageTable,
|
currentTable: selectedDamageTable,
|
||||||
weapon: weaoponFull.weapon,
|
weapon: weaoponFull.weapon,
|
||||||
});
|
});
|
||||||
|
if (selectedDamageTable === "one hit") {
|
||||||
|
setDamageRoll((displayWeapon.minDamage + displayWeapon.maxDamage) / 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(displayWeapon.reloadTime < 0.125) displayWeapon.reloadTime = 0.125
|
if(displayWeapon.reloadTime < 0.125) displayWeapon.reloadTime = 0.125
|
||||||
const dpsK = (weaoponFull.currentTable == "dps") ? displayWeapon.accuracy * (1 / (displayWeapon.reloadTime - (displayWeapon.reloadTime % 0.125))) : 1
|
const movingAccuracy = displayWeapon.accuracy - displayWeapon.accuracyReductionMoving
|
||||||
|
const hasMovingAccuracy = displayWeapon.setupTime === 0 && movingAccuracy > 0
|
||||||
|
const reloadK = 1 / (displayWeapon.reloadTime - (displayWeapon.reloadTime % 0.125))
|
||||||
|
const dpsK = (weaoponFull.currentTable == "dps") ? displayWeapon.accuracy * reloadK
|
||||||
|
: (weaoponFull.currentTable == "dps move") ? movingAccuracy * reloadK
|
||||||
|
: 1
|
||||||
|
|
||||||
const infLowPiercing = getPiercingK(ArmorTypeNames.InfantryLow)
|
const infLowPiercing = getPiercingK(ArmorTypeNames.InfantryLow)
|
||||||
const infMedPiercing = getPiercingK(ArmorTypeNames.InfantryMedium)
|
const infMedPiercing = getPiercingK(ArmorTypeNames.InfantryMedium)
|
||||||
@@ -165,6 +174,16 @@ export default function WeaponFull(props: {weaponId: number, isDefault: Boolean,
|
|||||||
const livingMetalPiercing = getPiercingK(ArmorTypeNames.LivingMetal)
|
const livingMetalPiercing = getPiercingK(ArmorTypeNames.LivingMetal)
|
||||||
const titanPiercing = getPiercingK(ArmorTypeNames.Titan)
|
const titanPiercing = getPiercingK(ArmorTypeNames.Titan)
|
||||||
|
|
||||||
|
const damageRollMin = displayWeapon.minDamage
|
||||||
|
const damageRollMax = displayWeapon.maxDamage
|
||||||
|
const hasDamageRollRange = damageRollMax > damageRollMin
|
||||||
|
const currentDamageRoll = damageRoll !== null
|
||||||
|
? Math.min(Math.max(damageRoll, damageRollMin), damageRollMax)
|
||||||
|
: (damageRollMin + damageRollMax) / 2
|
||||||
|
const damageRollFraction = hasDamageRollRange
|
||||||
|
? (currentDamageRoll - damageRollMin) / (damageRollMax - damageRollMin)
|
||||||
|
: 0.5
|
||||||
|
|
||||||
const getTotalDamage = (damagePiercing: number, isAir: boolean = false) => {
|
const getTotalDamage = (damagePiercing: number, isAir: boolean = false) => {
|
||||||
|
|
||||||
if (!isAir && !weapon.canAttackGround && !weapon.isMeleeWeapon) return ""
|
if (!isAir && !weapon.canAttackGround && !weapon.isMeleeWeapon) return ""
|
||||||
@@ -180,9 +199,11 @@ export default function WeaponFull(props: {weaponId: number, isDefault: Boolean,
|
|||||||
maxDamage = displayWeapon.minDamageValue
|
maxDamage = displayWeapon.minDamageValue
|
||||||
}
|
}
|
||||||
|
|
||||||
const averageDmg = (minDamage + maxDamage) / 2
|
const hitDamage = weaoponFull.currentTable === "one hit"
|
||||||
|
? minDamage + (maxDamage - minDamage) * damageRollFraction
|
||||||
|
: (minDamage + maxDamage) / 2
|
||||||
|
|
||||||
return (averageDmg * dpsK).toFixed(2)
|
return (hitDamage * dpsK).toFixed(2)
|
||||||
}
|
}
|
||||||
|
|
||||||
const getMoraleDamage = () => {
|
const getMoraleDamage = () => {
|
||||||
@@ -217,7 +238,7 @@ export default function WeaponFull(props: {weaponId: number, isDefault: Boolean,
|
|||||||
sx={{'&:last-child td, &:last-child th': {border: 0}}}
|
sx={{'&:last-child td, &:last-child th': {border: 0}}}
|
||||||
>
|
>
|
||||||
<TableCell component="th" scope="row" >Accuracy moving</TableCell>
|
<TableCell component="th" scope="row" >Accuracy moving</TableCell>
|
||||||
<TableCell>{displayWeapon.setupTime === 0 && displayWeapon.accuracy - displayWeapon.accuracyReductionMoving > 0 ? (displayWeapon.accuracy - displayWeapon.accuracyReductionMoving).toFixed(3).replace(/[,.]?0+$/, '') : "-"}</TableCell>
|
<TableCell>{hasMovingAccuracy ? movingAccuracy.toFixed(3).replace(/[,.]?0+$/, '') : "-"}</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableBody>
|
</TableBody>
|
||||||
</Table>
|
</Table>
|
||||||
@@ -301,10 +322,28 @@ export default function WeaponFull(props: {weaponId: number, isDefault: Boolean,
|
|||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
>
|
>
|
||||||
<ToggleButton size="small" value="dps" sx={{ color: textColor, '&.Mui-selected': { borderColor: textColor, color: textColor, backgroundColor: isDark ? 'rgba(255, 255, 255, 0.15)' : 'rgba(0, 0, 0, 0.15)' } }}>Dps</ToggleButton>
|
<ToggleButton size="small" value="dps" sx={{ color: textColor, '&.Mui-selected': { borderColor: textColor, color: textColor, backgroundColor: isDark ? 'rgba(255, 255, 255, 0.15)' : 'rgba(0, 0, 0, 0.15)' } }}>Dps</ToggleButton>
|
||||||
<ToggleButton size="small" value="one hit" sx={{ color: textColor, '&.Mui-selected': {borderColor: textColor, color: textColor, backgroundColor: isDark ? 'rgba(255, 255, 255, 0.15)' : 'rgba(0, 0, 0, 0.15)' } }}>One hit average damage</ToggleButton>
|
<ToggleButton size="small" value="dps move" disabled={!hasMovingAccuracy} sx={{ color: textColor, '&.Mui-selected': { borderColor: textColor, color: textColor, backgroundColor: isDark ? 'rgba(255, 255, 255, 0.15)' : 'rgba(0, 0, 0, 0.15)' } }}>Dps move</ToggleButton>
|
||||||
|
<ToggleButton size="small" value="one hit" sx={{ color: textColor, '&.Mui-selected': {borderColor: textColor, color: textColor, backgroundColor: isDark ? 'rgba(255, 255, 255, 0.15)' : 'rgba(0, 0, 0, 0.15)' } }}>One hit damage</ToggleButton>
|
||||||
</ToggleButtonGroup>
|
</ToggleButtonGroup>
|
||||||
|
{weaoponFull.currentTable === 'one hit' && (
|
||||||
|
<div style={{ display: 'flex', alignItems: 'center', gap: 8, minWidth: 200, flexGrow: 1, maxWidth: 220 }}>
|
||||||
|
<span style={{ whiteSpace: 'nowrap', fontSize: 14 }}>{damageRollMin.toFixed(2)}</span>
|
||||||
|
<Slider
|
||||||
|
size="small"
|
||||||
|
min={damageRollMin}
|
||||||
|
max={damageRollMax}
|
||||||
|
step={hasDamageRollRange ? (damageRollMax - damageRollMin) / 100 : 1}
|
||||||
|
value={currentDamageRoll}
|
||||||
|
onChange={(e, value) => setDamageRoll(value as number)}
|
||||||
|
disabled={!hasDamageRollRange}
|
||||||
|
sx={{ color: textColor, flexGrow: 1 }}
|
||||||
|
/>
|
||||||
|
<span style={{ whiteSpace: 'nowrap', fontSize: 14 }}>{damageRollMax.toFixed(2)}</span>
|
||||||
|
<span style={{ whiteSpace: 'nowrap', fontSize: 14, minWidth: 44, textAlign: 'right', fontWeight: 700 }}>{Math.round((1 - damageRollFraction) * 100)}%</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
{weapon.researches && weapon.researches.length > 0 && (
|
{weapon.researches && weapon.researches.length > 0 && (
|
||||||
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
|
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 6, flexBasis: '100%', width: '100%' }}>
|
||||||
{(() => {
|
{(() => {
|
||||||
// topological order: a research is always rendered to the right of its requirements
|
// topological order: a research is always rendered to the right of its requirements
|
||||||
const ordered: IWeaponResearch[] = [];
|
const ordered: IWeaponResearch[] = [];
|
||||||
@@ -358,6 +397,7 @@ export default function WeaponFull(props: {weaponId: number, isDefault: Boolean,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
setEnabledResearchIds(next);
|
setEnabledResearchIds(next);
|
||||||
|
setDamageRoll(null);
|
||||||
}}
|
}}
|
||||||
sx={{
|
sx={{
|
||||||
color: textColor,
|
color: textColor,
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ export interface IBuilding {
|
|||||||
sightRadius: number
|
sightRadius: number
|
||||||
detectRadius: number
|
detectRadius: number
|
||||||
repairMax: number
|
repairMax: number
|
||||||
|
buildingLimit?: number
|
||||||
icon: string
|
icon: string
|
||||||
modId: number
|
modId: number
|
||||||
modifiers: IModifier[]
|
modifiers: IModifier[]
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ export interface IJumps {
|
|||||||
chargeJumpCostMax: number;
|
chargeJumpCostMax: number;
|
||||||
jumpHeight: number;
|
jumpHeight: number;
|
||||||
chargeMax: number;
|
chargeMax: number;
|
||||||
|
chargeStartingFraction: number;
|
||||||
setupTime: number;
|
setupTime: number;
|
||||||
goDownTime?: number;
|
goDownTime?: number;
|
||||||
isTeleport: boolean;
|
isTeleport: boolean;
|
||||||
@@ -58,6 +59,9 @@ export interface IUnit {
|
|||||||
mass: number
|
mass: number
|
||||||
upTime: number
|
upTime: number
|
||||||
moveSpeed: number
|
moveSpeed: number
|
||||||
|
accelerationTime?: number
|
||||||
|
decelerationTime?: number
|
||||||
|
rotationRate?: number
|
||||||
sightRadius: number
|
sightRadius: number
|
||||||
detectRadius: number
|
detectRadius: number
|
||||||
reinforceCostRequisition?: number
|
reinforceCostRequisition?: number
|
||||||
|
|||||||
Reference in New Issue
Block a user