From eebe50a373346486e8a611913d75d953fe0e86b4 Mon Sep 17 00:00:00 2001 From: anibus Date: Sun, 4 Oct 2026 02:58:50 +0300 Subject: [PATCH] Add some params - start jump charge - building limit - movement params Rework weapon dps one hit and add dps move --- components/pages/BuildingPageClient.tsx | 10 +++- components/pages/UnitPageClient.tsx | 34 ++++++++++-- lib/api-server.ts | 2 +- public/images/Movement_acceleration.svg | 6 ++ public/images/Movement_deceleration.svg | 6 ++ public/images/Movement_rotation.svg | 4 ++ public/images/Movement_speed.svg | 6 ++ src/classes/AbilitySpawnedObject.tsx | 4 +- src/classes/DeathExplosion.tsx | 74 +++++++++++++------------ src/classes/Jump.tsx | 1 + src/classes/Required.tsx | 2 +- src/classes/Sergeant.tsx | 4 +- src/classes/WeaponFull.tsx | 54 +++++++++++++++--- src/types/IBuilding.tsx | 1 + src/types/IUnit.tsx | 4 ++ 15 files changed, 154 insertions(+), 58 deletions(-) create mode 100644 public/images/Movement_acceleration.svg create mode 100644 public/images/Movement_deceleration.svg create mode 100644 public/images/Movement_rotation.svg create mode 100644 public/images/Movement_speed.svg diff --git a/components/pages/BuildingPageClient.tsx b/components/pages/BuildingPageClient.tsx index dd81140..876c9ed 100644 --- a/components/pages/BuildingPageClient.tsx +++ b/components/pages/BuildingPageClient.tsx @@ -224,6 +224,12 @@ function Building(building: IBuilding, mod: IMod, theme: Theme, racesUnits: IRac Repair max {building.repairMax} + {building.buildingLimit !== undefined && building.buildingLimit !== null && + + Limit + {building.buildingLimit} + + } @@ -258,9 +264,7 @@ function Building(building: IBuilding, mod: IMod, theme: Theme, racesUnits: IRac } {building.deathExplosions.length > 0 && - {building.deathExplosions.map(da => - - )} + } {building.addons.length > 0 && diff --git a/components/pages/UnitPageClient.tsx b/components/pages/UnitPageClient.tsx index e939444..97a13db 100644 --- a/components/pages/UnitPageClient.tsx +++ b/components/pages/UnitPageClient.tsx @@ -260,8 +260,33 @@ function Unit(unit: IUnit, mod: IMod, theme: Theme, racesUnits: IRaceUnits[], ra - Move speed - {unit.moveSpeed} + Movement + + + +   + {unit.moveSpeed} + + {unit.accelerationTime !== undefined && unit.accelerationTime !== null && + +   + {unit.accelerationTime}s + + } + {unit.decelerationTime !== undefined && unit.decelerationTime !== null && + +   + {unit.decelerationTime}s + + } + {unit.rotationRate !== undefined && unit.rotationRate !== null && + +   + {unit.rotationRate} + + } + + Morale @@ -316,6 +341,7 @@ function Unit(unit: IUnit, mod: IMod, theme: Theme, racesUnits: IRaceUnits[], ra {unit.sergeants.map(s => } sx={{ color: isDark ? '#dee2e6' : 'rgba(0, 0, 0, 0.85)', '& .MuiAccordionSummary-content': { margin: '12px 0' }, '& .MuiAccordionSummary-content.Mui-expanded': { margin: '12px 0' } }}> 0} /> @@ -356,9 +382,7 @@ function Unit(unit: IUnit, mod: IMod, theme: Theme, racesUnits: IRaceUnits[], ra {unit.deathExplosions.length > 0 && - {unit.deathExplosions.map(da => - - )} + } diff --git a/lib/api-server.ts b/lib/api-server.ts index e54e06a..f223c11 100644 --- a/lib/api-server.ts +++ b/lib/api-server.ts @@ -9,7 +9,7 @@ import { IUnit } from '@/src/types/IUnit'; import { IBuilding } from '@/src/types/IBuilding'; 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(url: string): Promise { try { diff --git a/public/images/Movement_acceleration.svg b/public/images/Movement_acceleration.svg new file mode 100644 index 0000000..504a54a --- /dev/null +++ b/public/images/Movement_acceleration.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/public/images/Movement_deceleration.svg b/public/images/Movement_deceleration.svg new file mode 100644 index 0000000..0c7013d --- /dev/null +++ b/public/images/Movement_deceleration.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/public/images/Movement_rotation.svg b/public/images/Movement_rotation.svg new file mode 100644 index 0000000..d488764 --- /dev/null +++ b/public/images/Movement_rotation.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/images/Movement_speed.svg b/public/images/Movement_speed.svg new file mode 100644 index 0000000..01fce2c --- /dev/null +++ b/public/images/Movement_speed.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/classes/AbilitySpawnedObject.tsx b/src/classes/AbilitySpawnedObject.tsx index 6747b8a..c748679 100644 --- a/src/classes/AbilitySpawnedObject.tsx +++ b/src/classes/AbilitySpawnedObject.tsx @@ -134,9 +134,7 @@ function AbilitySpawnedObject(props: AbilityEnvironmentProps) { } {abilityEnvironment.deathExplosions.length > 0 && - {abilityEnvironment.deathExplosions.map(da => - - )} + } diff --git a/src/classes/DeathExplosion.tsx b/src/classes/DeathExplosion.tsx index 21cde68..a7cf52c 100644 --- a/src/classes/DeathExplosion.tsx +++ b/src/classes/DeathExplosion.tsx @@ -31,7 +31,7 @@ import {StyledTableCell} from "../commons/StyledTableCell"; interface DeathExpProps { - deathExplosion: IDeathExplosion, + deathExplosions: IDeathExplosion[], mod: IMod, } @@ -40,10 +40,11 @@ function DeathExplosion(props: DeathExpProps) { const isDark = theme.palette.mode === 'dark'; const textColor = isDark ? '#dee2e6' : 'rgba(0, 0, 0, 0.85)'; - const deathExplosion = props.deathExplosion - const chanceTotalNotZero = deathExplosion.globalChance * deathExplosion.chance != 0 + const deathExplosions = props.deathExplosions.filter(deathExplosion => + deathExplosion.globalChance * deathExplosion.chance != 0 + ) - return chanceTotalNotZero ? + return deathExplosions.length > 0 ?
- - - - - - - Chance - {deathExplosion.globalChance * deathExplosion.chance}% - - - Damage radius - {deathExplosion.damageRadius} - - - Throw force - {deathExplosion.throwForceMin} - {deathExplosion.throwForceMax} - - -
-
+ {deathExplosions.map((deathExplosion, index) => + 0 ? 2 : 0}}> + + + + + + Chance + {deathExplosion.globalChance * deathExplosion.chance}% + + + Damage radius + {deathExplosion.damageRadius} + + + Throw force + {deathExplosion.throwForceMin} - {deathExplosion.throwForceMax} + + +
+
+
+ + +
- - - -
+ )}
: diff --git a/src/classes/Jump.tsx b/src/classes/Jump.tsx index b2b523e..a47494e 100644 --- a/src/classes/Jump.tsx +++ b/src/classes/Jump.tsx @@ -55,6 +55,7 @@ function Jump(props: IJumpProps) { { label: "Distance", value: jumps.jumpDistanceMax.toFixed(0) }, { label: "Setup time", value:  {jumps.setupTime}s }, { label: "Breakdown time", value:  {jumps.breakdownTime}s }, + { label: "Starting charge", value: `${(jumps.chargeStartingFraction * 100).toFixed(0)}%` } ]; if (!isTeleport) { if (jumps.goUpTime !== undefined && jumps.goUpTime !== null) { diff --git a/src/classes/Required.tsx b/src/classes/Required.tsx index 09453bc..9382486 100644 --- a/src/classes/Required.tsx +++ b/src/classes/Required.tsx @@ -76,7 +76,7 @@ function Required (props: IRequiredProps) { return   One  {" "} - {limitPerBuilding.building.name} allow produce max {limitPerBuilding.limit} + {limitPerBuilding.building.name} allows producing a maximum of {limitPerBuilding.limit} } function renderRequirementResearches(requirementResearches: IResearchRequirements[],) { diff --git a/src/classes/Sergeant.tsx b/src/classes/Sergeant.tsx index 268ad13..4353eab 100644 --- a/src/classes/Sergeant.tsx +++ b/src/classes/Sergeant.tsx @@ -187,9 +187,7 @@ const Sergeant = (props: SergeantProps) => { {sergeant.deathExplosions.length > 0 && - {sergeant.deathExplosions.map(da => - - )} + } diff --git a/src/classes/WeaponFull.tsx b/src/classes/WeaponFull.tsx index 642d21f..6099904 100644 --- a/src/classes/WeaponFull.tsx +++ b/src/classes/WeaponFull.tsx @@ -9,7 +9,7 @@ import { TableBody, TableCell, TableContainer, TableHead, - TableRow, ToggleButton, ToggleButtonGroup + TableRow, ToggleButton, ToggleButtonGroup, Slider } from "@mui/material"; import ArmorType from "./ArmorType"; import Required from "./Required"; @@ -43,6 +43,7 @@ export default function WeaponFull(props: {weaponId: number, isDefault: Boolean, }); const [enabledResearchIds, setEnabledResearchIds] = useState>(new Set()); + const [damageRoll, setDamageRoll] = useState(null); function applyResearchEffects(weapon: IWeapon, enabledIds: Set): IWeapon { 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, weapon: weaoponFull.weapon, }); + if (selectedDamageTable === "one hit") { + setDamageRoll((displayWeapon.minDamage + displayWeapon.maxDamage) / 2); + } } 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 infMedPiercing = getPiercingK(ArmorTypeNames.InfantryMedium) @@ -165,6 +174,16 @@ export default function WeaponFull(props: {weaponId: number, isDefault: Boolean, const livingMetalPiercing = getPiercingK(ArmorTypeNames.LivingMetal) 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) => { if (!isAir && !weapon.canAttackGround && !weapon.isMeleeWeapon) return "" @@ -180,9 +199,11 @@ export default function WeaponFull(props: {weaponId: number, isDefault: Boolean, 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 = () => { @@ -217,7 +238,7 @@ export default function WeaponFull(props: {weaponId: number, isDefault: Boolean, sx={{'&:last-child td, &:last-child th': {border: 0}}} > Accuracy moving - {displayWeapon.setupTime === 0 && displayWeapon.accuracy - displayWeapon.accuracyReductionMoving > 0 ? (displayWeapon.accuracy - displayWeapon.accuracyReductionMoving).toFixed(3).replace(/[,.]?0+$/, '') : "-"} + {hasMovingAccuracy ? movingAccuracy.toFixed(3).replace(/[,.]?0+$/, '') : "-"} @@ -301,10 +322,28 @@ export default function WeaponFull(props: {weaponId: number, isDefault: Boolean, onChange={handleChange} > Dps - One hit average damage + Dps move + One hit damage + {weaoponFull.currentTable === 'one hit' && ( +
+ {damageRollMin.toFixed(2)} + setDamageRoll(value as number)} + disabled={!hasDamageRollRange} + sx={{ color: textColor, flexGrow: 1 }} + /> + {damageRollMax.toFixed(2)} + {Math.round((1 - damageRollFraction) * 100)}% +
+ )} {weapon.researches && weapon.researches.length > 0 && ( -
+
{(() => { // topological order: a research is always rendered to the right of its requirements const ordered: IWeaponResearch[] = []; @@ -358,6 +397,7 @@ export default function WeaponFull(props: {weaponId: number, isDefault: Boolean, } } setEnabledResearchIds(next); + setDamageRoll(null); }} sx={{ color: textColor, diff --git a/src/types/IBuilding.tsx b/src/types/IBuilding.tsx index aaa3e2f..c04212c 100644 --- a/src/types/IBuilding.tsx +++ b/src/types/IBuilding.tsx @@ -32,6 +32,7 @@ export interface IBuilding { sightRadius: number detectRadius: number repairMax: number + buildingLimit?: number icon: string modId: number modifiers: IModifier[] diff --git a/src/types/IUnit.tsx b/src/types/IUnit.tsx index 79575a6..570241a 100644 --- a/src/types/IUnit.tsx +++ b/src/types/IUnit.tsx @@ -22,6 +22,7 @@ export interface IJumps { chargeJumpCostMax: number; jumpHeight: number; chargeMax: number; + chargeStartingFraction: number; setupTime: number; goDownTime?: number; isTeleport: boolean; @@ -58,6 +59,9 @@ export interface IUnit { mass: number upTime: number moveSpeed: number + accelerationTime?: number + decelerationTime?: number + rotationRate?: number sightRadius: number detectRadius: number reinforceCostRequisition?: number