Skip to content

Commit

Permalink
Merge pull request BibliothecaDAO#226 from BibliothecaDAO/leet/combat
Browse files Browse the repository at this point in the history
feat: combat UI
  • Loading branch information
aymericdelab authored Nov 12, 2023
2 parents 3e4b284 + 72bd204 commit 4e9c0b7
Show file tree
Hide file tree
Showing 33 changed files with 1,282 additions and 1,087 deletions.
Binary file added client/public/images/buildings/defence_tower.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/public/images/chest.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/public/images/icons/attack.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/public/images/icons/defence.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/public/images/lost_raid.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/public/images/opened_chest.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/public/images/raid_fail.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/public/images/units/troop-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/public/images/units/troop.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions client/public/images/units/troop.png:Zone.Identifier
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[ZoneTransfer]
ZoneId=3
ReferrerUrl=https://s3-alpha-sig.figma.com/img/beff/d03e/f15c21050053100cd08a17b857fbd654?Expires=1700438400&Signature=YMzmuxI2qeKxmHPo3WpjSnA5LuR8r5ol7VsxSB6AdVnR0d2EtBHGJf4PhDR9Caxwj3wHim-~Y1COPskEE238wa6s-EGdZihBXTmC7r9MXyav0M6H-8R79~2EoGHfB42Y3LHum2SJ4pv259x6tZBJwKHFuEUkdogdfIKe2nVBt8UCdjbagcuKA2EzHOYe~J0VbPdY-bRkoW0zyBkR~Fo9T~bLUOXv56WIzMeBmGa5GGKseEtXgAUDNwIQ1Q9QlKpOnbfD0P2gBDp8BfeVil6Me5PwzyLBXfg6Z34-Y08qLgH8rEdfWV0bqyw4WRd0iM7MLPEV0tTn2mh0PPePZDlnkA__&Key-Pair-Id=APKAQ4GOSFWCVNEHN3O4
HostUrl=https://s3-alpha-sig.figma.com/img/beff/d03e/f15c21050053100cd08a17b857fbd654?Expires=1700438400&Signature=YMzmuxI2qeKxmHPo3WpjSnA5LuR8r5ol7VsxSB6AdVnR0d2EtBHGJf4PhDR9Caxwj3wHim-~Y1COPskEE238wa6s-EGdZihBXTmC7r9MXyav0M6H-8R79~2EoGHfB42Y3LHum2SJ4pv259x6tZBJwKHFuEUkdogdfIKe2nVBt8UCdjbagcuKA2EzHOYe~J0VbPdY-bRkoW0zyBkR~Fo9T~bLUOXv56WIzMeBmGa5GGKseEtXgAUDNwIQ1Q9QlKpOnbfD0P2gBDp8BfeVil6Me5PwzyLBXfg6Z34-Y08qLgH8rEdfWV0bqyw4WRd0iM7MLPEV0tTn2mh0PPePZDlnkA__&Key-Pair-Id=APKAQ4GOSFWCVNEHN3O4
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,22 @@ const RealmManagementComponent = () => {
{
key: "military",
label: (
<div className="flex flex-col items-center " title="Military">
<div
onMouseEnter={() =>
setTooltip({
position: "top",
content: (
<>
<p className="whitespace-nowrap">Build military troops,</p>
<p className="whitespace-nowrap">Defend your Realm, raid other Realms.</p>
</>
),
})
}
onMouseLeave={() => setTooltip(null)}
className="flex flex-col items-center "
title="Military"
>
<CrossSwords className="mb-2 fill-gold" /> <div>Military</div>
</div>
),
Expand Down
43 changes: 29 additions & 14 deletions client/src/components/cityview/realm/SmallResource.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,25 @@
import { findResourceById } from "@bibliothecadao/eternum";
import { ResourceIcon } from "../../../elements/ResourceIcon";
import { currencyFormat, getEntityIdFromKeys } from "../../../utils/utils";
import { currencyFormat, divideByPrecision, getEntityIdFromKeys } from "../../../utils/utils";
import { useComponentValue } from "@dojoengine/react";
import { useDojo } from "../../../DojoContext";
import useRealmStore from "../../../hooks/store/useRealmStore";
import useUIStore from "../../../hooks/store/useUIStore";
import clsx from "clsx";

export const SmallResource = ({ resourceId }: { resourceId: number }) => {
export const SmallResource = ({
resourceId,
entity_id,
vertical,
intlFormat,
hideIfZero,
}: {
resourceId: number;
entity_id?: number;
vertical?: boolean;
intlFormat?: boolean;
hideIfZero?: boolean;
}) => {
const {
setup: {
components: { Resource },
Expand All @@ -15,10 +28,10 @@ export const SmallResource = ({ resourceId }: { resourceId: number }) => {

const { realmEntityId } = useRealmStore();
const setTooltip = useUIStore((state) => state.setTooltip);
const _entity_id = entity_id || realmEntityId;
const resource = useComponentValue(Resource, getEntityIdFromKeys([BigInt(_entity_id ?? 0), BigInt(resourceId)]));

const resource = useComponentValue(Resource, getEntityIdFromKeys([BigInt(realmEntityId ?? 0), BigInt(resourceId)]));

return (
return resource?.balance ? (
<div
onMouseEnter={() =>
setTooltip({
Expand All @@ -27,15 +40,17 @@ export const SmallResource = ({ resourceId }: { resourceId: number }) => {
})
}
onMouseLeave={() => setTooltip(null)}
className="flex relative group items-center"
className={clsx("flex relative group items-center", vertical && "flex-col space-y-1", !vertical && "space-x-1")}
>
<ResourceIcon
withTooltip={false}
resource={findResourceById(resourceId)?.trait || ""}
size="xs"
className="mr-1"
/>
<div className="text-xxs">{currencyFormat(resource?.balance || 0, 2)}</div>
<ResourceIcon withTooltip={false} resource={findResourceById(resourceId)?.trait || ""} size="xs" />
<div className="text-xxs">
{intlFormat
? Intl.NumberFormat("en-US", {
notation: "compact",
maximumFractionDigits: 1,
}).format(divideByPrecision(resource?.balance || 0))
: currencyFormat(resource?.balance || 0, 2)}
</div>
</div>
);
) : null;
};
177 changes: 102 additions & 75 deletions client/src/components/cityview/realm/combat/battalions/Battalion.tsx
Original file line number Diff line number Diff line change
@@ -1,100 +1,127 @@
import React from "react";
import { OrderIcon } from "../../../../../elements/OrderIcon";

import clsx from "clsx";
import { getRealmOrderNameById } from "../../../../../utils/realms";
import { ReactComponent as Pen } from "../../../../../assets/icons/common/pen.svg";
import { ReactComponent as CaretDownFill } from "../../../../../assets/icons/common/caret-down-fill.svg";
import { ReactComponent as DonkeyIcon } from "../../../../../assets/icons/units/donkey-circle.svg";
import { Dot } from "../../../../../elements/Dot";
import { CombatInfo } from "../../../../../hooks/helpers/useCombat";
import ProgressBar from "../../../../../elements/ProgressBar";
import Button from "../../../../../elements/Button";
import { getResourceCost } from "../../../../../utils/combat";
import useUIStore from "../../../../../hooks/store/useUIStore";
import { divideByPrecision } from "../../../../../utils/utils";
import { ResourceIcon } from "../../../../../elements/ResourceIcon";
import { findResourceById } from "@bibliothecadao/eternum";

type BattalionProps = {
battalion: CombatInfo;
onBuild: () => void;
} & React.HTMLAttributes<HTMLDivElement>;

export const Battalion = ({ battalion, ...props }: BattalionProps) => {
const { entityId, health, quantity, capacity, attack, defence } = battalion;
export const Battalion = ({ battalion, onBuild, ...props }: BattalionProps) => {
const { quantity, attack, defence } = battalion;
const setTooltip = useUIStore((state) => state.setTooltip);

const isTraveling = false;
const destinationRealmId = undefined;
const destinationRealmName = "";
const hasArrivedPickupPosition = false;
const costPerUnit = getResourceCost(1);

return (
<div
className={clsx("flex flex-col p-2 border rounded-md border-gray-gold text-xxs text-gray-gold", props.className)}
className={clsx(
"flex flex-col relative border rounded-md border-gray-gold text-xxs text-gray-gold",
props.className,
)}
onClick={props.onClick}
>
<div className="flex items-center text-xxs">
{entityId && (
<div className="flex items-center p-1 -mt-2 -ml-2 italic border border-t-0 border-l-0 text-light-pink rounded-br-md border-gray-gold">
#{entityId}
</div>
)}
<div className="flex items-center ml-1 -mt-2">
{isTraveling && destinationRealmName && (
<div className="flex items-center ml-1">
<span className="italic text-light-pink">Traveling {hasArrivedPickupPosition ? "from" : "to"}</span>
<div className="flex items-center ml-1 mr-1 text-gold">
<OrderIcon order={getRealmOrderNameById(destinationRealmId)} className="mr-1" size="xxs" />
{destinationRealmName}
<span className="italic text-light-pink ml-1">with</span>
</div>
</div>
)}
{capacity && (
<div className="flex items-center ml-1 text-gold">
{0}
<div className="mx-0.5 italic text-light-pink">/</div>
{`${capacity / 1000} kg`}
<CaretDownFill className="ml-1 fill-current" />
</div>
)}
<div className="flex items-center absolute top-0 left-0 right-0 pointer-events-none text-xxs">
<div className="flex items-center py-[1px] px-[6px] italic border border-t-0 border-l-0 text-light-pink rounded-br-md border-gray-gold bg-black/60">
Battalions
</div>
{true && (
<div className="flex ml-auto -mt-2 italic text-gold">
Idle
<Pen className="ml-1 fill-gold" />
</div>
)}
</div>
<div className="flex justify-center items-center space-x-2 flex-wrap mt-2"></div>
<div className="flex mt-2">
<div className="grid w-full grid-cols-1 gap-5">
<div className="flex flex-col">
{health && (
<div className="grid grid-cols-12 gap-0.5">
<ProgressBar containerClassName="col-span-12" rounded progress={(health / (10 * quantity)) * 100} />
</div>
)}
<div className="flex items-center justify-between mt-[6px] text-xxs">
<DonkeyIcon />
<div className="flex items-center space-x-[6px]">
<div className="flex flex-col items-center">
<Dot colorClass="bg-green" />
<div className="mt-1 text-green">{quantity}</div>
<div className="flex h-full">
<img src={`/images/units/troop.png`} className="object-cover w-16 rounded-md" />
<div className="flex flex-1 flex-col p-2 text-xxs h-full">
<div className="flex justify-between items-center">
<div className="flex">
<div
className="flex items-center h-6 mr-2"
onMouseEnter={() =>
setTooltip({
position: "top",
content: (
<>
<p className="whitespace-nowrap">Number of available units</p>
</>
),
})
}
onMouseLeave={() => setTooltip(null)}
>
<img src="/images/units/troop-icon.png" className="h-[28px]" />
<div className="flex flex-col ml-1 text-center">
<div className="bold text-order-brilliance">x{quantity}</div>
</div>
<div className="flex flex-col items-center">
<Dot colorClass="bg-yellow" />
<div className="mt-1 text-dark">{0}</div>
</div>
<div className="flex flex-col items-center">
<Dot colorClass="bg-orange" />
<div className="mt-1 text-orange">{attack}</div>
</div>
<div className="flex flex-col items-center">
<Dot colorClass="bg-red" />
<div className="mt-1 text-red">{defence}</div>
</div>
</div>
<div className="flex items-center">
<div
className="flex items-center h-6 mr-2"
onMouseEnter={() =>
setTooltip({
position: "top",
content: (
<>
<p className="whitespace-nowrap">Attack power</p>
</>
),
})
}
onMouseLeave={() => setTooltip(null)}
>
<img src="/images/icons/attack.png" className="h-full" />
<div className="flex flex-col ml-1 text-center">
<div className="bold ">{attack}</div>
</div>
<div className="flex flex-col items-center">
<Dot colorClass="bg-light-pink" />
<div className="mt-1 text-dark">{0}</div>
</div>
<div
className="flex items-center h-6 mr-2"
onMouseEnter={() =>
setTooltip({
position: "top",
content: (
<>
<p className="whitespace-nowrap">Defence power</p>
</>
),
})
}
onMouseLeave={() => setTooltip(null)}
>
<img src="/images/icons/defence.png" className="h-full" />
<div className="flex flex-col ml-1 text-center">
<div className="bold ">{defence}</div>
</div>
</div>
<Button onClick={onBuild} size="xs" variant="outline">
Build More
</Button>
</div>
</div>
<div
className="flex space-x-2 mt-2 ml-1 w-min"
onMouseEnter={() =>
setTooltip({
position: "top",
content: (
<>
<p className="whitespace-nowrap">Cost per unit</p>
</>
),
})
}
onMouseLeave={() => setTooltip(null)}
>
{costPerUnit.map((cost, index) => (
<div className="flex text-lightest mt-2">
<ResourceIcon resource={findResourceById(cost.resourceId).trait} size="xs" className="mr-1" />
{divideByPrecision(cost.amount).toLocaleString("en-US")}
</div>
))}
</div>
</div>
</div>
</div>
Expand Down
Loading

0 comments on commit 4e9c0b7

Please sign in to comment.