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