/* Copyright (c) 2015 Jesper Öqvist <jesper@llbit.se> * * This file is part of Chunky. * * Chunky is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chunky is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with Chunky. If not, see <http://www.gnu.org/licenses/>. */ package se.llbit.chunky.world.entity; import java.util.Collection; import java.util.LinkedList; import se.llbit.chunky.resources.EntityTexture; import se.llbit.chunky.resources.Texture; import se.llbit.json.JsonObject; import se.llbit.json.JsonValue; import se.llbit.math.QuickMath; import se.llbit.math.Transform; import se.llbit.math.Vector3; import se.llbit.math.primitive.Box; import se.llbit.math.primitive.Primitive; import se.llbit.nbt.CompoundTag; /** * A mob head (skull) entity. * * @author Jesper Öqvist <jesper@llbit.se> */ public class SkullEntity extends Entity { /** * The skull type, i.e. Creeper head, Skeleton skull, etc. */ private final int type; /** * The rotation of the skull when attached to a wall. */ private final int rotation; /** * Decides if the skull is attached to a wall or the floor. */ private final int placement; public SkullEntity(Vector3 position, CompoundTag entityTag, int metadata) { this(position, entityTag.get("SkullType").byteValue(0), entityTag.get("Rot").byteValue(0), metadata); } public SkullEntity(Vector3 position, int type, int rotation, int placement) { super(position); this.type = type; this.rotation = rotation; this.placement = placement; // TODO(jesper): add SkullOwner handling. } @Override public Collection<Primitive> primitives(Vector3 offset) { Collection<Primitive> faces = new LinkedList<>(); Transform transform = Transform.NONE .translate(position.x + offset.x + 0.5, position.y + offset.y + 4 / 16., position.z + offset.z + 0.5); EntityTexture texture; switch (type) { case 0: texture = Texture.skeleton; break; case 1: texture = Texture.wither; break; case 2: texture = Texture.zombie; break; case 3: texture = Texture.steve; break; case 4: texture = Texture.creeper; break; default: texture = Texture.steve; } Box head = new Box(-4 / 16., 4 / 16., -4 / 16., 4 / 16., -4 / 16., 4 / 16.); switch (placement) { case 0: // Unused. break; case 1: // On floor. head.transform(Transform.NONE.rotateY(-rotation * Math.PI / 8)); break; case 2: // Facing north. head.transform(Transform.NONE.translate(0, 0, 4 / 16.)); break; case 3: // Facing south. head.transform(Transform.NONE.translate(0, 0, 4 / 16.)); head.transform(Transform.NONE.rotateY(Math.PI)); break; case 4: // Facing west. head.transform(Transform.NONE.translate(0, 0, 4 / 16.)); head.transform(Transform.NONE.rotateY(QuickMath.HALF_PI)); break; case 5: // Facing east. head.transform(Transform.NONE.translate(0, 0, 4 / 16.)); head.transform(Transform.NONE.rotateY(-QuickMath.HALF_PI)); break; } head.transform(transform); head.addFrontFaces(faces, texture, texture.headFront); head.addBackFaces(faces, texture, texture.headBack); head.addTopFaces(faces, texture, texture.headTop); head.addBottomFaces(faces, texture, texture.headBottom); head.addRightFaces(faces, texture, texture.headRight); head.addLeftFaces(faces, texture, texture.headLeft); return faces; } @Override public JsonValue toJson() { JsonObject json = new JsonObject(); json.add("kind", "skull"); json.add("position", position.toJson()); json.add("type", type); json.add("rotation", rotation); json.add("placement", placement); return json; } public static Entity fromJson(JsonObject json) { Vector3 position = new Vector3(); position.fromJson(json.get("position").object()); int type = json.get("type").intValue(0); int rotation = json.get("rotation").intValue(0); int placement = json.get("placement").intValue(0); return new SkullEntity(position, type, rotation, placement); } }