New source found from dndbeyond.com
This commit is contained in:
@@ -15,6 +15,7 @@ export interface NumberDisplayProps extends HTMLAttributes<HTMLSpanElement> {
|
|||||||
isModified?: boolean;
|
isModified?: boolean;
|
||||||
size?: "large";
|
size?: "large";
|
||||||
numberFallback?: ReactNode;
|
numberFallback?: ReactNode;
|
||||||
|
useMph?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const NumberDisplay: FC<NumberDisplayProps> = ({
|
export const NumberDisplay: FC<NumberDisplayProps> = ({
|
||||||
@@ -23,6 +24,7 @@ export const NumberDisplay: FC<NumberDisplayProps> = ({
|
|||||||
isModified = false,
|
isModified = false,
|
||||||
size,
|
size,
|
||||||
numberFallback = "--",
|
numberFallback = "--",
|
||||||
|
useMph,
|
||||||
className,
|
className,
|
||||||
...props
|
...props
|
||||||
}) => {
|
}) => {
|
||||||
@@ -37,6 +39,9 @@ export const NumberDisplay: FC<NumberDisplayProps> = ({
|
|||||||
if (number && number % FEET_IN_MILES === 0) {
|
if (number && number % FEET_IN_MILES === 0) {
|
||||||
number = number / FEET_IN_MILES;
|
number = number / FEET_IN_MILES;
|
||||||
label = `mile${Math.abs(number) === 1 ? "" : "s"}`;
|
label = `mile${Math.abs(number) === 1 ? "" : "s"}`;
|
||||||
|
if (useMph) {
|
||||||
|
label = "mph";
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
label = "ft.";
|
label = "ft.";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ export function generateVehicleMeta(vehicle, ruleData) {
|
|||||||
}
|
}
|
||||||
let type = VehicleAccessors.getType(vehicle);
|
let type = VehicleAccessors.getType(vehicle);
|
||||||
let typeName = type === null ? '' : RuleDataUtils.getObjectTypeName(type, ruleData);
|
let typeName = type === null ? '' : RuleDataUtils.getObjectTypeName(type, ruleData);
|
||||||
typeName = typeName ? typeName.toLowerCase() : '';
|
typeName = typeName || '';
|
||||||
let primaryText = `${size} ${typeName}`.trim();
|
let primaryText = `${size} ${typeName}`.trim();
|
||||||
let movementTypesText = VehicleAccessors.getMovementNames(vehicle).join(', ');
|
let movementTypesText = VehicleAccessors.getMovementNames(vehicle).join(', ');
|
||||||
metaText.push(`${primaryText}${movementTypesText ? ` (${movementTypesText})` : ''}`.trim());
|
metaText.push(`${primaryText}${movementTypesText ? ` (${movementTypesText})` : ''}`.trim());
|
||||||
|
|||||||
@@ -109,12 +109,15 @@ export function stripTooltipTags(str, fallback = '') {
|
|||||||
* Formats the specified number as a distance with the appropriate unit
|
* Formats the specified number as a distance with the appropriate unit
|
||||||
* @param distance The distance measured in feet to format
|
* @param distance The distance measured in feet to format
|
||||||
*/
|
*/
|
||||||
export function renderDistance(distance) {
|
export function renderDistance(distance, useMph) {
|
||||||
let displayNumber = distance;
|
let displayNumber = distance;
|
||||||
let label = 'ft.';
|
let label = 'ft.';
|
||||||
if (distance !== 0 && distance % FEET_IN_MILES === 0) {
|
if (distance !== 0 && distance % FEET_IN_MILES === 0) {
|
||||||
displayNumber = CoreUtils.convertFeetToMiles(distance);
|
displayNumber = CoreUtils.convertFeetToMiles(distance);
|
||||||
label = `mile${Math.abs(displayNumber) === 1 ? '' : 's'}`;
|
label = `mile${Math.abs(displayNumber) === 1 ? '' : 's'}`;
|
||||||
|
if (useMph) {
|
||||||
|
label = `mph`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return `${displayNumber} ${label}`;
|
return `${displayNumber} ${label}`;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ export var VehicleConfigurationDisplayTypeEnum;
|
|||||||
VehicleConfigurationDisplayTypeEnum["SHIP"] = "ship";
|
VehicleConfigurationDisplayTypeEnum["SHIP"] = "ship";
|
||||||
VehicleConfigurationDisplayTypeEnum["INFERNAL_WAR_MACHINE"] = "infernal-war-machine";
|
VehicleConfigurationDisplayTypeEnum["INFERNAL_WAR_MACHINE"] = "infernal-war-machine";
|
||||||
VehicleConfigurationDisplayTypeEnum["SPELLJAMMER"] = "spelljammer";
|
VehicleConfigurationDisplayTypeEnum["SPELLJAMMER"] = "spelljammer";
|
||||||
|
VehicleConfigurationDisplayTypeEnum["ELEMENTAL_AIRSHIP"] = "elemental-airship";
|
||||||
})(VehicleConfigurationDisplayTypeEnum || (VehicleConfigurationDisplayTypeEnum = {}));
|
})(VehicleConfigurationDisplayTypeEnum || (VehicleConfigurationDisplayTypeEnum = {}));
|
||||||
export var VehicleConfigurationPrimaryComponentManageTypeEnum;
|
export var VehicleConfigurationPrimaryComponentManageTypeEnum;
|
||||||
(function (VehicleConfigurationPrimaryComponentManageTypeEnum) {
|
(function (VehicleConfigurationPrimaryComponentManageTypeEnum) {
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ export var ComponentAdjustmentEnum;
|
|||||||
(function (ComponentAdjustmentEnum) {
|
(function (ComponentAdjustmentEnum) {
|
||||||
ComponentAdjustmentEnum["HIT_POINT_SPEED_ADJUSTMENT"] = "speed";
|
ComponentAdjustmentEnum["HIT_POINT_SPEED_ADJUSTMENT"] = "speed";
|
||||||
})(ComponentAdjustmentEnum || (ComponentAdjustmentEnum = {}));
|
})(ComponentAdjustmentEnum || (ComponentAdjustmentEnum = {}));
|
||||||
//TODO new for spelljammers
|
|
||||||
export var ComponentCostTypeEnum;
|
export var ComponentCostTypeEnum;
|
||||||
(function (ComponentCostTypeEnum) {
|
(function (ComponentCostTypeEnum) {
|
||||||
ComponentCostTypeEnum["COMPONENT"] = "component";
|
ComponentCostTypeEnum["COMPONENT"] = "component";
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { ActionAccessors } from "../engine/Action";
|
|||||||
import { CharacterUtils } from "../engine/Character";
|
import { CharacterUtils } from "../engine/Character";
|
||||||
import { HelperUtils } from "../engine/Helper";
|
import { HelperUtils } from "../engine/Helper";
|
||||||
import { RuleDataAccessors } from "../engine/RuleData";
|
import { RuleDataAccessors } from "../engine/RuleData";
|
||||||
import { VehicleConfigurationPrimaryComponentManageTypeEnum } from "../engine/Vehicle";
|
import { VehicleConfigurationDisplayTypeEnum, VehicleConfigurationPrimaryComponentManageTypeEnum, } from "../engine/Vehicle";
|
||||||
import { VehicleComponentAccessors } from "../engine/VehicleComponent";
|
import { VehicleComponentAccessors } from "../engine/VehicleComponent";
|
||||||
import { rulesEngineSelectors } from "../selectors";
|
import { rulesEngineSelectors } from "../selectors";
|
||||||
import { BaseManager } from './BaseManager';
|
import { BaseManager } from './BaseManager';
|
||||||
@@ -133,7 +133,10 @@ export class VehicleComponentManager extends BaseManager {
|
|||||||
allowComponentProperty() {
|
allowComponentProperty() {
|
||||||
const primaryManageType = this.vehicle.getPrimaryComponentManageType();
|
const primaryManageType = this.vehicle.getPrimaryComponentManageType();
|
||||||
const isPrimaryComponent = this.getIsPrimary();
|
const isPrimaryComponent = this.getIsPrimary();
|
||||||
return !(primaryManageType === VehicleConfigurationPrimaryComponentManageTypeEnum.VEHICLE && isPrimaryComponent);
|
const isElementalAirship = this.vehicle.getDisplayType() === VehicleConfigurationDisplayTypeEnum.ELEMENTAL_AIRSHIP;
|
||||||
|
return !(primaryManageType === VehicleConfigurationPrimaryComponentManageTypeEnum.VEHICLE &&
|
||||||
|
isPrimaryComponent &&
|
||||||
|
!isElementalAirship);
|
||||||
}
|
}
|
||||||
generateVehicleComponentSpeedInfos() {
|
generateVehicleComponentSpeedInfos() {
|
||||||
const enableSpeeds = this.vehicle.getEnableComponentSpeeds();
|
const enableSpeeds = this.vehicle.getEnableComponentSpeeds();
|
||||||
|
|||||||
@@ -119,6 +119,7 @@ export class VehicleManager extends BaseManager {
|
|||||||
this.isSpelljammer = () => this.getDisplayType() === VehicleConfigurationDisplayTypeEnum.SPELLJAMMER;
|
this.isSpelljammer = () => this.getDisplayType() === VehicleConfigurationDisplayTypeEnum.SPELLJAMMER;
|
||||||
this.isInfernalWarMachine = () => this.getDisplayType() === VehicleConfigurationDisplayTypeEnum.INFERNAL_WAR_MACHINE;
|
this.isInfernalWarMachine = () => this.getDisplayType() === VehicleConfigurationDisplayTypeEnum.INFERNAL_WAR_MACHINE;
|
||||||
this.isShip = () => this.getDisplayType() === VehicleConfigurationDisplayTypeEnum.SHIP;
|
this.isShip = () => this.getDisplayType() === VehicleConfigurationDisplayTypeEnum.SHIP;
|
||||||
|
this.isElementalAirship = () => this.getDisplayType() === VehicleConfigurationDisplayTypeEnum.ELEMENTAL_AIRSHIP;
|
||||||
// Utils
|
// Utils
|
||||||
this.generateVehicleMeta = () => {
|
this.generateVehicleMeta = () => {
|
||||||
const ruleData = rulesEngineSelectors.getRuleData(this.state);
|
const ruleData = rulesEngineSelectors.getRuleData(this.state);
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {
|
|||||||
Constants,
|
Constants,
|
||||||
Creature,
|
Creature,
|
||||||
ExtraManager,
|
ExtraManager,
|
||||||
|
VehicleManager,
|
||||||
} from "@dndbeyond/character-rules-engine/es";
|
} from "@dndbeyond/character-rules-engine/es";
|
||||||
|
|
||||||
import { NumberDisplay } from "~/components/NumberDisplay";
|
import { NumberDisplay } from "~/components/NumberDisplay";
|
||||||
@@ -75,7 +76,7 @@ export const ExtraRow: FC<Props> = ({
|
|||||||
typeName = type;
|
typeName = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
let description: string = `${size} ${typeName.toLowerCase()}`.trim();
|
let description: string = `${size} ${typeName}`.trim();
|
||||||
if (description) {
|
if (description) {
|
||||||
metaItems.push(description);
|
metaItems.push(description);
|
||||||
}
|
}
|
||||||
@@ -164,12 +165,27 @@ export const ExtraRow: FC<Props> = ({
|
|||||||
|
|
||||||
const { data, label, showTooltip } = movementInfo;
|
const { data, label, showTooltip } = movementInfo;
|
||||||
|
|
||||||
|
let useMph = false;
|
||||||
|
const isVehicle = extra.isVehicle();
|
||||||
|
if (isVehicle) {
|
||||||
|
const vehicleData = extra.getExtraData() as VehicleManager;
|
||||||
|
const displayType = vehicleData?.getDisplayType();
|
||||||
|
const isElementalAirship =
|
||||||
|
displayType ===
|
||||||
|
Constants.VehicleConfigurationDisplayTypeEnum.ELEMENTAL_AIRSHIP;
|
||||||
|
useMph = isElementalAirship;
|
||||||
|
}
|
||||||
|
|
||||||
let contentNode: React.ReactNode = null;
|
let contentNode: React.ReactNode = null;
|
||||||
if (data !== null) {
|
if (data !== null) {
|
||||||
contentNode = (
|
contentNode = (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<div className="ct-extra-row__speed-value">
|
<div className="ct-extra-row__speed-value">
|
||||||
<NumberDisplay type="distanceInFt" number={data.speed} />
|
<NumberDisplay
|
||||||
|
type="distanceInFt"
|
||||||
|
number={data.speed}
|
||||||
|
useMph={useMph}
|
||||||
|
/>
|
||||||
{showTooltip && renderAdditionalInfoTooltip()}
|
{showTooltip && renderAdditionalInfoTooltip()}
|
||||||
</div>
|
</div>
|
||||||
{data.movementId !== Constants.MovementTypeEnum.WALK && (
|
{data.movementId !== Constants.MovementTypeEnum.WALK && (
|
||||||
|
|||||||
+7
-2
@@ -4,6 +4,7 @@ interface Props {
|
|||||||
label: string;
|
label: string;
|
||||||
value: React.ReactNode;
|
value: React.ReactNode;
|
||||||
extraValue: React.ReactNode;
|
extraValue: React.ReactNode;
|
||||||
|
displayColon?: boolean;
|
||||||
}
|
}
|
||||||
export default class VehicleBlockAttribute extends React.PureComponent<Props> {
|
export default class VehicleBlockAttribute extends React.PureComponent<Props> {
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
@@ -11,11 +12,15 @@ export default class VehicleBlockAttribute extends React.PureComponent<Props> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { label, value, extraValue } = this.props;
|
const { label, value, extraValue, displayColon } = this.props;
|
||||||
|
|
||||||
|
const labelDisplay: string = displayColon ? `${label}:` : label;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="ct-vehicle-block__attribute">
|
<div className="ct-vehicle-block__attribute">
|
||||||
<span className="ct-vehicle-block__attribute-label">{label}</span>
|
<span className="ct-vehicle-block__attribute-label">
|
||||||
|
{labelDisplay}
|
||||||
|
</span>
|
||||||
<span className="ct-vehicle-block__attribute-data">
|
<span className="ct-vehicle-block__attribute-data">
|
||||||
<span className="ct-vehicle-block__attribute-data-value">
|
<span className="ct-vehicle-block__attribute-data-value">
|
||||||
{value}
|
{value}
|
||||||
|
|||||||
+19
-5
@@ -1,3 +1,4 @@
|
|||||||
|
import clsx from "clsx";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import { ManageIcon } from "@dndbeyond/character-components/es";
|
import { ManageIcon } from "@dndbeyond/character-components/es";
|
||||||
@@ -42,6 +43,9 @@ export default class VehicleBlockComponent extends React.PureComponent<Props> {
|
|||||||
const nameLabel: string = name !== null ? name : "";
|
const nameLabel: string = name !== null ? name : "";
|
||||||
const isSpelljammer =
|
const isSpelljammer =
|
||||||
displayType === Constants.VehicleConfigurationDisplayTypeEnum.SPELLJAMMER;
|
displayType === Constants.VehicleConfigurationDisplayTypeEnum.SPELLJAMMER;
|
||||||
|
const isElementalAirship =
|
||||||
|
displayType ===
|
||||||
|
Constants.VehicleConfigurationDisplayTypeEnum.ELEMENTAL_AIRSHIP;
|
||||||
|
|
||||||
let componentCount: string = "";
|
let componentCount: string = "";
|
||||||
if (count > 1) {
|
if (count > 1) {
|
||||||
@@ -56,8 +60,11 @@ export default class VehicleBlockComponent extends React.PureComponent<Props> {
|
|||||||
requiredCrew ? ` (${requiredCrew} Crew${count > 1 ? " Each" : ""})` : ""
|
requiredCrew ? ` (${requiredCrew} Crew${count > 1 ? " Each" : ""})` : ""
|
||||||
}`;
|
}`;
|
||||||
} else {
|
} else {
|
||||||
let typesText = FormatUtils.renderNonOxfordCommaList(typeNames);
|
const typesNames = FormatUtils.renderNonOxfordCommaList(typeNames);
|
||||||
primaryText = `${typesText}: ${nameLabel} ${componentCount}`;
|
const typeText = `${typesNames}: `;
|
||||||
|
primaryText = `${
|
||||||
|
isElementalAirship ? "" : typeText
|
||||||
|
}${nameLabel} ${componentCount}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
let callout: React.ReactNode = null;
|
let callout: React.ReactNode = null;
|
||||||
@@ -79,8 +86,8 @@ export default class VehicleBlockComponent extends React.PureComponent<Props> {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="ct-vehicle-block-component__actions">
|
<div className="ct-vehicle-block-component__actions">
|
||||||
{actions.map((action) => (
|
{actions.map((action, idx) => (
|
||||||
<VehicleBlockAction action={action} key={action.key} />
|
<VehicleBlockAction action={action} key={idx + action.key} />
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@@ -127,7 +134,14 @@ export default class VehicleBlockComponent extends React.PureComponent<Props> {
|
|||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="ct-vehicle-block-component__attributes">
|
<div
|
||||||
|
className={clsx([
|
||||||
|
"ct-vehicle-block-component__attributes",
|
||||||
|
displayType ===
|
||||||
|
Constants.VehicleConfigurationDisplayTypeEnum.ELEMENTAL_AIRSHIP &&
|
||||||
|
"ct-vehicle-block-component__attributes--inline",
|
||||||
|
])}
|
||||||
|
>
|
||||||
<VehicleBlockPrimaryAttributes
|
<VehicleBlockPrimaryAttributes
|
||||||
armorClassInfo={armorClassInfo}
|
armorClassInfo={armorClassInfo}
|
||||||
hitPointInfo={hitPointInfo}
|
hitPointInfo={hitPointInfo}
|
||||||
|
|||||||
+5
-2
@@ -69,8 +69,11 @@ export default class VehicleBlockComponents extends React.PureComponent<Props> {
|
|||||||
components = components.filter(
|
components = components.filter(
|
||||||
(component) =>
|
(component) =>
|
||||||
!(
|
!(
|
||||||
component.displayType ===
|
(component.displayType ===
|
||||||
Constants.VehicleConfigurationDisplayTypeEnum.SPELLJAMMER &&
|
Constants.VehicleConfigurationDisplayTypeEnum.SPELLJAMMER ||
|
||||||
|
component.displayType ===
|
||||||
|
Constants.VehicleConfigurationDisplayTypeEnum
|
||||||
|
.ELEMENTAL_AIRSHIP) &&
|
||||||
component.isPrimaryComponent
|
component.isPrimaryComponent
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|||||||
+7
-3
@@ -15,7 +15,7 @@ export default class VehicleBlockHeader extends React.PureComponent<Props> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let size: string = sizeName !== null ? sizeName : "";
|
let size: string = sizeName !== null ? sizeName : "";
|
||||||
let type: string = typeName !== null ? typeName.toLowerCase() : "";
|
let type: string = typeName !== null ? typeName : "";
|
||||||
|
|
||||||
return [size, type].join(" ").trim();
|
return [size, type].join(" ").trim();
|
||||||
};
|
};
|
||||||
@@ -65,14 +65,18 @@ export default class VehicleBlockHeader extends React.PureComponent<Props> {
|
|||||||
|
|
||||||
const typeInfo = this.renderTypeInfo();
|
const typeInfo = this.renderTypeInfo();
|
||||||
const dimensions = this.renderDimensions();
|
const dimensions = this.renderDimensions();
|
||||||
|
const showMeta =
|
||||||
|
displayType !==
|
||||||
|
Constants.VehicleConfigurationDisplayTypeEnum.SPELLJAMMER &&
|
||||||
|
displayType !==
|
||||||
|
Constants.VehicleConfigurationDisplayTypeEnum.ELEMENTAL_AIRSHIP;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="ct-vehicle-block__header">
|
<div className="ct-vehicle-block__header">
|
||||||
<div className="ct-vehicle-block__name">
|
<div className="ct-vehicle-block__name">
|
||||||
{name !== null ? name : ""}
|
{name !== null ? name : ""}
|
||||||
</div>
|
</div>
|
||||||
{displayType !==
|
{showMeta && (
|
||||||
Constants.VehicleConfigurationDisplayTypeEnum.SPELLJAMMER && (
|
|
||||||
<div className="ct-vehicle-block__meta">
|
<div className="ct-vehicle-block__meta">
|
||||||
{typeInfo} {dimensions}
|
{typeInfo} {dimensions}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+26
-6
@@ -120,6 +120,7 @@ export default class VehicleBlockPrimary extends React.PureComponent<Props> {
|
|||||||
primaryProperties,
|
primaryProperties,
|
||||||
shouldCoalesce,
|
shouldCoalesce,
|
||||||
displayType,
|
displayType,
|
||||||
|
creatureCapacityInfo,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
let cargoCapacity: Array<string> = [];
|
let cargoCapacity: Array<string> = [];
|
||||||
@@ -138,6 +139,11 @@ export default class VehicleBlockPrimary extends React.PureComponent<Props> {
|
|||||||
|
|
||||||
const isSpelljammer =
|
const isSpelljammer =
|
||||||
displayType === Constants.VehicleConfigurationDisplayTypeEnum.SPELLJAMMER;
|
displayType === Constants.VehicleConfigurationDisplayTypeEnum.SPELLJAMMER;
|
||||||
|
const isElementalAirship =
|
||||||
|
displayType ===
|
||||||
|
Constants.VehicleConfigurationDisplayTypeEnum.ELEMENTAL_AIRSHIP;
|
||||||
|
|
||||||
|
const showSeperator = !isSpelljammer && !isElementalAirship;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -164,18 +170,32 @@ export default class VehicleBlockPrimary extends React.PureComponent<Props> {
|
|||||||
extraValue={this.renderEffectiveTravelDistance()}
|
extraValue={this.renderEffectiveTravelDistance()}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<VehicleBlockAttribute
|
{!isElementalAirship ? (
|
||||||
label={isSpelljammer ? "Crew" : "Creature Capacity"}
|
<VehicleBlockAttribute
|
||||||
value={creatureCapacityDescriptions.join(", ")}
|
label={isSpelljammer ? "Crew" : "Creature Capacity"}
|
||||||
/>
|
value={creatureCapacityDescriptions.join(", ")}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
creatureCapacityInfo.map((capacity, idx) => (
|
||||||
|
<VehicleBlockAttribute
|
||||||
|
key={capacity.type || "Capacity" + idx}
|
||||||
|
label={capacity.type || "Capacity"}
|
||||||
|
value={capacity.capacity}
|
||||||
|
displayColon={true}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
)}
|
||||||
{cargoCapacity.length > 0 && (
|
{cargoCapacity.length > 0 && (
|
||||||
<VehicleBlockAttribute
|
<VehicleBlockAttribute
|
||||||
label={isSpelljammer ? "Cargo" : "Cargo Capacity"}
|
label={
|
||||||
|
isSpelljammer || isElementalAirship ? "Cargo" : "Cargo Capacity"
|
||||||
|
}
|
||||||
value={cargoCapacity.join(", ")}
|
value={cargoCapacity.join(", ")}
|
||||||
|
displayColon={isElementalAirship}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{!isSpelljammer && <VehicleBlockSeparator displayType={displayType} />}
|
{showSeperator && <VehicleBlockSeparator displayType={displayType} />}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
+42
-17
@@ -110,16 +110,21 @@ export default class VehicleBlockPrimaryAttributes extends React.PureComponent<P
|
|||||||
};
|
};
|
||||||
|
|
||||||
renderSpeedInfo = (
|
renderSpeedInfo = (
|
||||||
modes: Array<VehicleComponentSpeedModeInfo>
|
modes: Array<VehicleComponentSpeedModeInfo>,
|
||||||
|
displayType: Constants.VehicleConfigurationDisplayTypeEnum
|
||||||
): React.ReactNode => {
|
): React.ReactNode => {
|
||||||
|
const isElementalAirship =
|
||||||
|
displayType ===
|
||||||
|
Constants.VehicleConfigurationDisplayTypeEnum.ELEMENTAL_AIRSHIP;
|
||||||
|
|
||||||
let speedDisplayStrings: Array<string> = modes.map((mode) => {
|
let speedDisplayStrings: Array<string> = modes.map((mode) => {
|
||||||
const { value, description, restrictionsText, movementInfo } = mode;
|
const { value, description, restrictionsText, movementInfo } = mode;
|
||||||
|
|
||||||
let stringParts: Array<string> = [];
|
let stringParts: Array<string> = [];
|
||||||
if (movementInfo) {
|
if (movementInfo && !isElementalAirship) {
|
||||||
stringParts.push(`${movementInfo.description} speed`);
|
stringParts.push(`${movementInfo.description} speed`);
|
||||||
}
|
}
|
||||||
stringParts.push(FormatUtils.renderDistance(value));
|
stringParts.push(FormatUtils.renderDistance(value, isElementalAirship));
|
||||||
if (description) {
|
if (description) {
|
||||||
stringParts.push(description);
|
stringParts.push(description);
|
||||||
}
|
}
|
||||||
@@ -134,12 +139,16 @@ export default class VehicleBlockPrimaryAttributes extends React.PureComponent<P
|
|||||||
};
|
};
|
||||||
|
|
||||||
renderArmorClassAttribute = (): React.ReactNode => {
|
renderArmorClassAttribute = (): React.ReactNode => {
|
||||||
const { armorClassInfo } = this.props;
|
const { armorClassInfo, displayType } = this.props;
|
||||||
|
|
||||||
if (armorClassInfo === null) {
|
if (armorClassInfo === null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isElementalAirship =
|
||||||
|
displayType ===
|
||||||
|
Constants.VehicleConfigurationDisplayTypeEnum.ELEMENTAL_AIRSHIP;
|
||||||
|
|
||||||
const { moving, base, description } = armorClassInfo;
|
const { moving, base, description } = armorClassInfo;
|
||||||
|
|
||||||
let armorClassValue: number | null = base;
|
let armorClassValue: number | null = base;
|
||||||
@@ -155,7 +164,7 @@ export default class VehicleBlockPrimaryAttributes extends React.PureComponent<P
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<VehicleBlockAttribute
|
<VehicleBlockAttribute
|
||||||
label="Armor Class"
|
label={isElementalAirship ? "AC" : "Armor Class"}
|
||||||
value={
|
value={
|
||||||
description
|
description
|
||||||
? `${armorClassValue} (${description})`
|
? `${armorClassValue} (${description})`
|
||||||
@@ -164,6 +173,7 @@ export default class VehicleBlockPrimaryAttributes extends React.PureComponent<P
|
|||||||
: armorClassValue
|
: armorClassValue
|
||||||
}
|
}
|
||||||
extraValue={motionlessArmorClassValue}
|
extraValue={motionlessArmorClassValue}
|
||||||
|
displayColon={isElementalAirship}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -206,7 +216,9 @@ export default class VehicleBlockPrimaryAttributes extends React.PureComponent<P
|
|||||||
);
|
);
|
||||||
|
|
||||||
const costValues: Array<string> = sortedCosts.map((cost) => {
|
const costValues: Array<string> = sortedCosts.map((cost) => {
|
||||||
const value: string = cost.value ? `${cost.value} gp` : "--";
|
const value: string = cost.value
|
||||||
|
? `${FormatUtils.renderLocaleNumber(cost.value)} GP`
|
||||||
|
: "--";
|
||||||
const description: string = cost.description
|
const description: string = cost.description
|
||||||
? `(${cost.description})`
|
? `(${cost.description})`
|
||||||
: "";
|
: "";
|
||||||
@@ -216,25 +228,33 @@ export default class VehicleBlockPrimaryAttributes extends React.PureComponent<P
|
|||||||
|
|
||||||
const isSpelljammer =
|
const isSpelljammer =
|
||||||
displayType === Constants.VehicleConfigurationDisplayTypeEnum.SPELLJAMMER;
|
displayType === Constants.VehicleConfigurationDisplayTypeEnum.SPELLJAMMER;
|
||||||
|
const isElementalAirship =
|
||||||
|
displayType ===
|
||||||
|
Constants.VehicleConfigurationDisplayTypeEnum.ELEMENTAL_AIRSHIP;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
{armorClassInfo !== null && this.renderArmorClassAttribute()}
|
{armorClassInfo !== null && this.renderArmorClassAttribute()}
|
||||||
{hitPointInfo !== null && (
|
{hitPointInfo !== null && (
|
||||||
<VehicleBlockAttribute
|
<VehicleBlockAttribute
|
||||||
label="Hit Points"
|
label={isElementalAirship ? "HP" : "Hit Points"}
|
||||||
value={this.renderHitPointInfo()}
|
value={this.renderHitPointInfo()}
|
||||||
extraValue={
|
extraValue={
|
||||||
!isSpelljammer ? this.renderHitPointThresholdInfo() : undefined
|
!isSpelljammer && !isElementalAirship
|
||||||
|
? this.renderHitPointThresholdInfo()
|
||||||
|
: undefined
|
||||||
}
|
}
|
||||||
|
displayColon={isElementalAirship}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{isSpelljammer && !!hitPointInfo?.damageThreshold && (
|
{(isSpelljammer || isElementalAirship) &&
|
||||||
<VehicleBlockAttribute
|
!!hitPointInfo?.damageThreshold && (
|
||||||
label="Damage Threshold"
|
<VehicleBlockAttribute
|
||||||
value={hitPointInfo?.damageThreshold}
|
label={"Damage Threshold"}
|
||||||
/>
|
value={hitPointInfo?.damageThreshold}
|
||||||
)}
|
displayColon={isElementalAirship}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
{speedInfos.map((speedInfo, idx) => {
|
{speedInfos.map((speedInfo, idx) => {
|
||||||
let speedAttributeLabel: string = "Speed";
|
let speedAttributeLabel: string = "Speed";
|
||||||
if (speedInfo.type !== null && !isSpelljammer) {
|
if (speedInfo.type !== null && !isSpelljammer) {
|
||||||
@@ -248,7 +268,8 @@ export default class VehicleBlockPrimaryAttributes extends React.PureComponent<P
|
|||||||
<VehicleBlockAttribute
|
<VehicleBlockAttribute
|
||||||
key={`${speedInfo.type}-${idx}`}
|
key={`${speedInfo.type}-${idx}`}
|
||||||
label={speedAttributeLabel}
|
label={speedAttributeLabel}
|
||||||
value={this.renderSpeedInfo(modes)}
|
value={this.renderSpeedInfo(modes, displayType)}
|
||||||
|
displayColon={isElementalAirship}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
@@ -258,7 +279,7 @@ export default class VehicleBlockPrimaryAttributes extends React.PureComponent<P
|
|||||||
value={`Grants ${coverType} Cover`}
|
value={`Grants ${coverType} Cover`}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{requiredCrew !== null && !isSpelljammer && (
|
{requiredCrew !== null && !isSpelljammer && !isElementalAirship && (
|
||||||
<VehicleBlockAttribute label="Required Crew" value={requiredCrew} />
|
<VehicleBlockAttribute label="Required Crew" value={requiredCrew} />
|
||||||
)}
|
)}
|
||||||
{isPrimaryComponent &&
|
{isPrimaryComponent &&
|
||||||
@@ -273,7 +294,11 @@ export default class VehicleBlockPrimaryAttributes extends React.PureComponent<P
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{costValues.length > 0 && (
|
{costValues.length > 0 && (
|
||||||
<VehicleBlockAttribute label="Cost" value={costValues.join(", ")} />
|
<VehicleBlockAttribute
|
||||||
|
label="Cost"
|
||||||
|
value={costValues.join(", ")}
|
||||||
|
displayColon={isElementalAirship}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
|
|||||||
+2
@@ -20,6 +20,8 @@ export default class VehicleBlockSeparator extends React.PureComponent<Props> {
|
|||||||
VehicleBlockSeparatorInfernal,
|
VehicleBlockSeparatorInfernal,
|
||||||
[Constants.VehicleConfigurationDisplayTypeEnum.SPELLJAMMER]:
|
[Constants.VehicleConfigurationDisplayTypeEnum.SPELLJAMMER]:
|
||||||
VehicleBlockSeparatorShip,
|
VehicleBlockSeparatorShip,
|
||||||
|
[Constants.VehicleConfigurationDisplayTypeEnum.ELEMENTAL_AIRSHIP]:
|
||||||
|
VehicleBlockSeparatorShip,
|
||||||
};
|
};
|
||||||
|
|
||||||
//sets Ship style as default
|
//sets Ship style as default
|
||||||
|
|||||||
+2
@@ -27,6 +27,8 @@ export default class VehicleBlockShellCap extends React.PureComponent<Props> {
|
|||||||
VehicleBlockShellCapInfernal,
|
VehicleBlockShellCapInfernal,
|
||||||
[Constants.VehicleConfigurationDisplayTypeEnum.SPELLJAMMER]:
|
[Constants.VehicleConfigurationDisplayTypeEnum.SPELLJAMMER]:
|
||||||
VehicleBlockShellCapShip,
|
VehicleBlockShellCapShip,
|
||||||
|
[Constants.VehicleConfigurationDisplayTypeEnum.ELEMENTAL_AIRSHIP]:
|
||||||
|
VehicleBlockShellCapShip,
|
||||||
};
|
};
|
||||||
|
|
||||||
//sets Ship style as default
|
//sets Ship style as default
|
||||||
|
|||||||
@@ -385,7 +385,7 @@ class VehiclePane extends React.PureComponent<Props, State> {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!vehicle.isSpelljammer()) {
|
if (!vehicle.isSpelljammer() && !vehicle.isElementalAirship()) {
|
||||||
const primaryComponent = vehicle.getPrimaryComponent();
|
const primaryComponent = vehicle.getPrimaryComponent();
|
||||||
if (primaryComponent === null) {
|
if (primaryComponent === null) {
|
||||||
return null;
|
return null;
|
||||||
@@ -442,6 +442,7 @@ class VehiclePane extends React.PureComponent<Props, State> {
|
|||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<VehicleHealthAdjuster
|
<VehicleHealthAdjuster
|
||||||
|
key={`${componentName}${componentNumber}`}
|
||||||
hitPointInfo={componentHitPointInfo}
|
hitPointInfo={componentHitPointInfo}
|
||||||
onSave={(diff) => this.handleHealthAdjusterSave(diff, component)}
|
onSave={(diff) => this.handleHealthAdjusterSave(diff, component)}
|
||||||
heading={`Hit Points (${componentName}${componentNumber})`}
|
heading={`Hit Points (${componentName}${componentNumber})`}
|
||||||
@@ -507,7 +508,8 @@ class VehiclePane extends React.PureComponent<Props, State> {
|
|||||||
const primaryComponentManageType = vehicle.getPrimaryComponentManageType();
|
const primaryComponentManageType = vehicle.getPrimaryComponentManageType();
|
||||||
const enableConditionTracking = vehicle.getEnableConditionTracking();
|
const enableConditionTracking = vehicle.getEnableConditionTracking();
|
||||||
const enableFuelTracking = vehicle.getEnableFuelTracking();
|
const enableFuelTracking = vehicle.getEnableFuelTracking();
|
||||||
const shouldCoalesce = vehicle.isSpelljammer();
|
const shouldCoalesce =
|
||||||
|
vehicle.isSpelljammer() || vehicle.isElementalAirship();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
@@ -550,7 +552,6 @@ class VehiclePane extends React.PureComponent<Props, State> {
|
|||||||
|
|
||||||
renderVehicleName = (): React.ReactNode => {
|
renderVehicleName = (): React.ReactNode => {
|
||||||
const { vehicle } = this.state;
|
const { vehicle } = this.state;
|
||||||
const { theme } = this.props;
|
|
||||||
|
|
||||||
if (!vehicle) {
|
if (!vehicle) {
|
||||||
return null; //TODO could render a default empty state
|
return null; //TODO could render a default empty state
|
||||||
|
|||||||
@@ -96,6 +96,7 @@ export function generateVehicleBlockPrimaryProps(
|
|||||||
cargoCapacityInfo: vehicle.getVehicleCargoCapacityInfo(),
|
cargoCapacityInfo: vehicle.getVehicleCargoCapacityInfo(),
|
||||||
conditionImmunities: vehicle.generateVehicleConditionImmunityNames(),
|
conditionImmunities: vehicle.generateVehicleConditionImmunityNames(),
|
||||||
creatureCapacityDescriptions: vehicle.getCreatureCapacityDescriptions(),
|
creatureCapacityDescriptions: vehicle.getCreatureCapacityDescriptions(),
|
||||||
|
creatureCapacityInfo: vehicle.getCreatureCapacity(),
|
||||||
damageImmunities: vehicle.generateVehicleDamageImmunityNames(),
|
damageImmunities: vehicle.generateVehicleDamageImmunityNames(),
|
||||||
displayType: vehicle.getDisplayType(),
|
displayType: vehicle.getDisplayType(),
|
||||||
primaryProperties: deriveVehicleComponentPrimaryPropertiesProps(vehicle),
|
primaryProperties: deriveVehicleComponentPrimaryPropertiesProps(vehicle),
|
||||||
|
|||||||
Reference in New Issue
Block a user