Files
ATCS/src/com/gpl/rpg/atcontentstudio/model/sprites/Spritesheet.java
2025-06-21 18:37:54 +02:00

290 lines
8.7 KiB
Java

package com.gpl.rpg.atcontentstudio.model.sprites;
import com.gpl.rpg.atcontentstudio.ATContentStudio;
import com.gpl.rpg.atcontentstudio.Notification;
import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.model.GameSource.Type;
import com.gpl.rpg.atcontentstudio.model.Project;
import com.gpl.rpg.atcontentstudio.model.ProjectTreeNode;
import com.gpl.rpg.atcontentstudio.model.SaveEvent;
import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet;
import javax.imageio.ImageIO;
import javax.swing.tree.TreeNode;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.*;
public class Spritesheet extends GameDataElement {
private static final long serialVersionUID = -5981708088278528586L;
public SpriteSheetSet parent;
public File spritesheetFile;
public int spriteWidth = 32;
public int spriteHeight = 32;
public String id;
public Category category = Category.none;
public boolean animated = false;
public enum Category {
none,
monster,
item,
actorcondition
}
//Lazy initialization.
public BufferedImage spritesheet = null;
public Map<Integer, BufferedImage> cache_full_size = new LinkedHashMap<Integer, BufferedImage>();
public Map<Integer, Image> cache_icon = new LinkedHashMap<Integer, Image>();
public Spritesheet(SpriteSheetSet parent, File f) {
this.spritesheetFile = f;
this.id = f.getName().substring(0, f.getName().lastIndexOf("."));
this.parent = parent;
String cat = getProject().getSpritesheetsProperty("atcs.spritesheet." + this.id + ".category");
if (cat != null) {
this.category = Category.valueOf(cat);
}
String sizex = getProject().getSpritesheetsProperty("atcs.spritesheet." + this.id + ".sizex");
if (sizex != null) {
this.spriteWidth = Integer.parseInt(sizex);
}
String sizey = getProject().getSpritesheetsProperty("atcs.spritesheet." + this.id + ".sizey");
if (sizey != null) {
this.spriteHeight = Integer.parseInt(sizey);
}
String anim = getProject().getSpritesheetsProperty("atcs.spritesheet." + this.id + ".animate");
if (anim != null) {
this.animated = Boolean.parseBoolean(anim);
}
}
@Override
public Enumeration<ProjectTreeNode> children() {
return null;
}
@Override
public boolean getAllowsChildren() {
return false;
}
@Override
public TreeNode getChildAt(int arg0) {
return null;
}
@Override
public int getChildCount() {
return 0;
}
@Override
public int getIndex(TreeNode arg0) {
return 0;
}
@Override
public TreeNode getParent() {
return parent;
}
@Override
public boolean isLeaf() {
return true;
}
@Override
public void childrenAdded(List<ProjectTreeNode> path) {
path.add(0, this);
parent.childrenAdded(path);
}
@Override
public void childrenChanged(List<ProjectTreeNode> path) {
path.add(0, this);
parent.childrenChanged(path);
}
@Override
public void childrenRemoved(List<ProjectTreeNode> path) {
path.add(0, this);
parent.childrenRemoved(path);
}
@Override
public void notifyCreated() {
childrenAdded(new ArrayList<ProjectTreeNode>());
}
@Override
public String getDesc() {
return (needsSaving() ? "*" : "") + spritesheetFile.getName();
}
@Override
public Project getProject() {
return parent.getProject();
}
public int getSpriteCount() {
if (spritesheet == null) {
try {
spritesheet = ImageIO.read(spritesheetFile);
} catch (IOException e) {
Notification.addError("Error loading image " + spritesheetFile.getAbsolutePath() + " : " + e.getMessage());
e.printStackTrace();
return 0;
}
}
return (int) (Math.ceil(((double) spritesheet.getWidth()) / ((double) spriteWidth)) * Math.ceil(((double) spritesheet.getHeight()) / ((double) spriteHeight)));
}
public BufferedImage getImage(int index) {
if (spritesheet == null) {
try {
spritesheet = ImageIO.read(spritesheetFile);
} catch (IOException e) {
Notification.addError("Error loading image " + spritesheetFile.getAbsolutePath() + " : " + e.getMessage());
e.printStackTrace();
return null;
}
}
if (cache_full_size.get(index) != null) {
return cache_full_size.get(index);
}
BufferedImage result = new BufferedImage(spriteWidth, spriteHeight, BufferedImage.TYPE_INT_ARGB);
Graphics g = result.getGraphics();
int sx1, sy1;
sx1 = (index * spriteWidth) % spritesheet.getWidth();
sy1 = spriteHeight * ((index * spriteWidth) / spritesheet.getWidth());
if (sx1 + spriteWidth > spritesheet.getWidth() || sy1 + spriteHeight > spritesheet.getHeight()) {
g.finalize();
return null;
}
g.drawImage(spritesheet, 0, 0, spriteWidth, spriteHeight, sx1, sy1, sx1 + spriteWidth, sy1 + spriteHeight, null);
result.flush();
g.finalize();
cache_full_size.put(index, result);
return result;
}
public Image getIcon(int index) {
if (cache_icon.get(index) != null) {
return cache_icon.get(index);
}
Image result = getImage(index);
if (result == null) return null;
result = result.getScaledInstance((int) (16 * ATContentStudio.SCALING), (int) (16 * ATContentStudio.SCALING), Image.SCALE_SMOOTH);
cache_icon.put(index, result);
return result;
}
public void clearCache() {
cache_full_size.clear();
cache_icon.clear();
}
@Override
public Image getIcon() {
return getIcon(0);
}
@Override
public Image getLeafIcon() {
return getIcon();
}
@Override
public Image getClosedIcon() {
return null;
}
@Override
public Image getOpenIcon() {
return null;
}
@Override
public GameDataSet getDataSet() {
return null;
}
@Override
public Type getDataType() {
return parent.getDataType();
}
@Override
public boolean isEmpty() {
return false;
}
@Override
public void parse() {
if (this.state == GameDataElement.State.init) {
this.state = GameDataElement.State.parsed;
}
}
@Override
public void link() {
if (this.state == GameDataElement.State.init) {
this.parse();
}
if (this.state == GameDataElement.State.parsed) {
this.state = GameDataElement.State.linked;
}
}
@Override
public GameDataElement clone() {
Spritesheet clone = new Spritesheet((SpriteSheetSet) getParent(), new File(spritesheetFile.getAbsolutePath()));
clone.id = this.id;
clone.animated = this.animated;
clone.category = this.category;
clone.spriteWidth = this.spriteWidth;
clone.spriteHeight = this.spriteHeight;
return clone;
}
@Override
public void elementChanged(GameDataElement oldOne, GameDataElement newOne) {
//nothing linked.
}
@Override
public String getProjectFilename() {
return spritesheetFile.getName();
}
@Override
public void save() {
if (this.category != null)
getProject().setSpritesheetsProperty("atcs.spritesheet." + this.id + ".category", this.category.toString());
if (this.spriteWidth != 32)
getProject().setSpritesheetsProperty("atcs.spritesheet." + this.id + ".sizex", Integer.toString(this.spriteWidth));
if (this.spriteHeight != 32)
getProject().setSpritesheetsProperty("atcs.spritesheet." + this.id + ".sizey", Integer.toString(this.spriteHeight));
if (this.animated)
getProject().setSpritesheetsProperty("atcs.spritesheet." + this.id + ".animate", Boolean.toString(this.animated));
getProject().save();
this.state = GameDataElement.State.saved;
}
@Override
public List<SaveEvent> attemptSave() {
save();
return null;
}
}