Skip to content

Commit

Permalink
update item-assets to work with any size
Browse files Browse the repository at this point in the history
  • Loading branch information
Pistonight committed Jan 29, 2025
1 parent aeac5c9 commit 3a3949b
Show file tree
Hide file tree
Showing 18 changed files with 810 additions and 98 deletions.
3 changes: 3 additions & 0 deletions packages/item-assets/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,8 @@
/data
/icons
/target
/dist
*.webp
*.png
pnpm-lock.yaml
package-lock.json
36 changes: 36 additions & 0 deletions packages/item-assets/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# botw-item-assets

React components for item images in BOTW.

**NOTE: The library is not usable out of the box, as this repository
does not contain the assets**

## Usage

See [ActorSprite.tsx](./src/ActorSprite.tsx) and [ModifierSprite.tsx](./src/ModifierSprite.tsx)

## Install (into a mono-dev repo)

1. Add this repo as submodule
2. Check `package.json` and add the packages to `pnpm-workspace.yaml` catalog.
3. Currently, only pulling assets from private Google Cloud is supported:
```bash
task pull-build-priv
task build-sprites
```

Add the dependency to another package:

```json
{
"dependencies": {
"botw-item-assets": "workspace:*"
}
}
```

Import

```typescript
import { ActorSprite } from "botw-item-assets";
```
45 changes: 30 additions & 15 deletions packages/item-assets/Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,42 +9,57 @@ includes:
internal: true

tasks:
pull-priv:
desc: Pull private assets for building the package. Requires gcloud access
cmds:
- rm -rf icons src/assets
- $(which mkdir) -p src/assets
- gcloud storage cp -r gs://ist-private/icons .

clean:
desc: Clean the build output
cmds:
- rm -rf src/generated src/special

dev:
desc: Run test page dev server
cmds:
- task: ecma:vite-dev

build:
desc: Build the sprite sheets
desc: Build the generated data and sprites
cmds:
- task: build-data
- task: build-sprites

build-data:
cmds:
- $(which mkdir) -p src/generated
- python scripts/generate.py
- cargo run --release
- task: ecma:prettier-fix

build-sprites:
cmds:
- cargo run --release # It's insanely slow without --release
- cp -R icons/SP/Item src/special
- task: ecma:prettier-fix

pull-build-priv:
desc: Pull private assets for building the package. Requires gcloud access
cmds:
- rm -rf icons src/assets
- $(which mkdir) -p src/assets
- gcloud storage cp -r gs://ist-private/icons .

pull:
desc: Pull the assets for development
pull-priv:
desc: Pull built assets for the package. Requires gcloud access
cmds:
- cmd: echo "this command is not yet available"
silent: true
- rm -rf src/generated/sprites
- gcloud storage cp -r gs://ist-private/sprites src/generated

push:
desc: Push the generated assets. Requires gcloud access
cmds:
- gcloud storage cp src/sprites/*.webp gs://ist-private/sprites
- gcloud storage cp src/generated/sprites/*.webp gs://ist-private/sprites

check:
cmds:
- task: cargo:clippy-all
- task: cargo:fmt-check
- task: ecma:tsc-check
- task: ecma:tsc-check-build
- task: ecma:eslint-check
- task: ecma:prettier-check

Expand Down
22 changes: 16 additions & 6 deletions packages/item-assets/generator/canvas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,21 +53,31 @@ impl Canvas {
}
}

pub fn load_image(&mut self, position: usize, image: &DynamicImage) -> anyhow::Result<()> {
pub fn load_image(
&mut self,
position: usize,
image: &DynamicImage,
use_padding: bool,
) -> anyhow::Result<()> {
if position >= self.sprite_per_side as usize * self.sprite_per_side as usize {
bail!("position out of bounds");
}
let outer_res = self.scale_to + self.padding * 2;
let (scale_to, padding) = if use_padding {
(self.scale_to, self.padding)
} else {
(outer_res, 0)
};
let resized = DynamicImage::ImageRgba8(imageops::resize(
image,
self.scale_to,
self.scale_to,
scale_to,
scale_to,
FilterType::Lanczos3,
));
let outer_res = self.scale_to + self.padding * 2;
let y = (position / self.sprite_per_side as usize) * (outer_res as usize);
let y = y as u32 + self.padding;
let y = y as u32 + padding;
let x = (position % self.sprite_per_side as usize) * (outer_res as usize);
let x = x as u32 + self.padding;
let x = x as u32 + padding;
imageops::overlay(&mut self.image, &resized, x as i64, y as i64);

Ok(())
Expand Down
25 changes: 24 additions & 1 deletion packages/item-assets/generator/sprite_sheet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,9 @@ impl SpriteSheet {
if w != h {
Err(Error::NotSquare(path.display().to_string(), w, h))?;
}
let use_padding = should_use_padding(path.to_string_lossy().as_ref());
for canvas in &mut self.canvases {
canvas.load_image(position, &image)?;
canvas.load_image(position, &image, use_padding)?;
}

Ok(())
Expand All @@ -80,6 +81,28 @@ impl SpriteSheet {
}
}

fn should_use_padding(path: &str) -> bool {
// frames from animated images don't use the padding, to maintain
// the same size as the animated image
if path.contains("Obj_DungeonClearSeal") {
return false;
}
if path.contains("Obj_WarpDLC") {
return false;
}
if path.contains("Obj_DLC_HeroSeal") {
return false;
}
if path.contains("Obj_DLC_HeroSoul") {
return false;
}
if path.contains("Obj_HeroSoul") {
return false;
}

true
}

/// The data of a sprite sheet
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[repr(transparent)]
Expand Down
12 changes: 12 additions & 0 deletions packages/item-assets/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Item Asset Test</title>
</head>
<body>
<div id="-root-"></div>
<script type="module" src="/test/main.tsx"></script>
</body>
</html>
3 changes: 3 additions & 0 deletions packages/item-assets/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@
},
"devDependencies": {
"@types/react": "catalog:",
"@types/react-dom": "catalog:",
"@vitejs/plugin-react": "catalog:",
"eslint": "catalog:",
"mono-dev": "workspace:*",
"react-dom": "catalog:",
"typescript": "catalog:",
"vite": "catalog:"
}
Expand Down
Loading

0 comments on commit 3a3949b

Please sign in to comment.