Refactor bottom bar, dynamically search for subgames.

master
Nicole Collings 2019-12-11 21:38:20 -08:00
parent 4d10fe826a
commit 3aaf649c42
34 changed files with 291 additions and 203 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 974 B

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 701 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@ -270,6 +270,6 @@ set(ZEPHA_SRC
lua/client/LocalRegisterBiomes.cpp
lua/client/LocalRegisterBiomes.h
world/Dimension.cpp
world/Dimension.h def/texture/RawTexData.h game/hud/components/compound/GUIImageButton.cpp game/hud/components/compound/GUIImageButton.h)
world/Dimension.h def/texture/RawTexData.h game/hud/components/compound/GUIImageButton.cpp game/hud/components/compound/GUIImageButton.h game/ClientState.cpp game/scene/menu/Subgame.cpp game/scene/menu/Subgame.h game/scene/menu/SubgameConfig.h)
add_library (Zepha_Core ${ZEPHA_SRC})

View File

@ -105,7 +105,7 @@ int StartGame(int argc, char* argv[]) {
return -1;
}
case Mode::CLIENT: {
Client c(addr, {1366, 768});
Client c(path, addr, {1366, 768});
break;
}
// case Mode::LOCAL_SERVER: {

View File

@ -35,18 +35,22 @@ void TextureAtlas::loadDirectory(const std::string& dirStr) {
cf_file_t file;
cf_read_file(&dir, &file);
if (!file.is_dir && strcmp(file.ext, ".png") == 0) {
int width, height;
unsigned char* data = stbi_load(file.path, &width, &height, nullptr, 4);
addImage(data, std::string(file.name).substr(0, std::string(file.name).size() - 4), true, width, height);
free(data);
}
if (!file.is_dir && strcmp(file.ext, ".png") == 0)
loadImage(file.path, std::string(file.name).substr(0, std::string(file.name).size() - 4), true);
cf_dir_next(&dir);
}
cf_dir_close(&dir);
}
std::shared_ptr<AtlasRef> TextureAtlas::loadImage(const std::string &path, const std::string &name, bool base) {
int width, height;
unsigned char* data = stbi_load(path.data(), &width, &height, nullptr, 4);
auto ref = addImage(data, name, base, width, height);
free(data);
return ref;
}
void TextureAtlas::update() {
auto it = textures.cbegin();

View File

@ -24,6 +24,7 @@ public:
TextureAtlas() = default;
explicit TextureAtlas(unsigned int width, unsigned int height = 0);
void loadDirectory(const std::string& dirStr);
std::shared_ptr<AtlasRef> loadImage(const std::string& path, const std::string& name, bool base = false);
void update();

View File

@ -4,26 +4,13 @@
#include "Client.h"
Client::Client(const Address &addr, glm::vec2 dimensions) :
addr(addr),
renderer(dimensions.x, dimensions.y),
state {renderer, {}, LocalDefs("./assets/textures"), "this", 0, 0} {
init();
}
Client::Client(const std::string& path, const Address &addr, glm::vec2 dims) :
state(path.substr(0, path.find_last_of('/') + 1), renderer),
renderer(dims.x, dims.y),
addr(addr) {
Client::Client(uptr<LocalServerInstance> localServer, glm::vec2 dimensions) :
localServer(std::move(localServer)),
addr(Address {"127.0.0.1", this->localServer->port}),
renderer(dimensions.x, dimensions.y),
state {renderer, {}, LocalDefs("./assets/textures"), "this", 0, 0} {
init();
}
void Client::init() {
std::cout << Log::info << "Starting Zepha Client." << Log::endl;
// if (localServer != nullptr) localServer->start();
std::unique_ptr<Scene> scene = std::make_unique<MainMenuScene>(state);
sceneManager.setScene(std::move(scene));
@ -58,6 +45,5 @@ void Client::loop() {
}
Client::~Client() {
if (localServer != nullptr) localServer->stop();
sceneManager.cleanupScene();
}

View File

@ -15,20 +15,15 @@
class Client {
public:
Client(const Address& addr, glm::vec2 dimensions);
Client(uptr<LocalServerInstance> localServer, glm::vec2 dimensions);
Client(const std::string& path, const Address& addr, glm::vec2 dims);
~Client();
private:
void init();
void loop();
uptr<LocalServerInstance> localServer = nullptr;
Address addr {};
Renderer renderer;
ClientState state;
SceneManager sceneManager;
double timeElapsed = 0.0f;

10
src/game/ClientState.cpp Normal file
View File

@ -0,0 +1,10 @@
//
// Created by aurailus on 2019-12-11.
//
#include "ClientState.h"
ClientState::ClientState(const std::string &path, Renderer &renderer) :
path(path),
renderer(renderer),
defs(path + "/assets/textures") {}

View File

@ -9,14 +9,18 @@
#include "../def/LocalDefs.h"
#include "scene/net/ServerConnection.h"
struct ClientState {
class ClientState {
public:
ClientState(const std::string& path, Renderer& renderer);
std::string path;
Renderer& renderer;
ServerConnection connection;
ServerConnection connection {};
LocalDefs defs;
//TODO: Not this
std::string desiredState;
std::string desiredState = "this";
double fps = 0;
double deltaTime = 0;
};
};

View File

@ -28,6 +28,7 @@ ConnectScene::ConnectScene(ClientState &state, Address addr) : Scene(state),
}
void ConnectScene::update() {
state.defs.textures.update();
if (state.renderer.getWindow().resized) {
components.get<GUIRect>("loadBar")->setPos({0, state.renderer.getWindow().getSize().y - 32});
state.renderer.getWindow().resized = false;

View File

@ -3,21 +3,22 @@
//
#include "MainMenuScene.h"
#include "../hud/components/compound/GUIImageButton.h"
MainMenuScene::MainMenuScene(ClientState& state) : Scene(state) {
state.renderer.setClearColor(22, 22, 22);
state.renderer.setClearColor(0, 0, 0);
state.renderer.getWindow().lockMouse(false);
Font f(state.defs.textures, state.defs.textures["font"]);
glm::vec2 size = state.renderer.getWindow().getSize();
glm::vec2 win = state.renderer.getWindow().getSize();
/* Temp */
subgame = std::make_shared<GUIRect>("subgameContainer");
subgame->create(size, {}, state.defs.textures["zeus_background"]);
subgame->create(win, {}, state.defs.textures["zeus_background"]);
components.add(subgame);
auto menubar = std::make_shared<GUIRect>("menubar");
menubar->create({90*GS, size.y}, {}, {0.1, 0.15, 0.2, 0.3}, {0.1, 0.15, 0.2, 0.3}, {0.1, 0.15, 0.2, 0.7}, {0.1, 0.15, 0.2, 0.7});
menubar->create({90*GS, win.y}, {}, {0.1, 0.15, 0.2, 0.3}, {0.1, 0.15, 0.2, 0.3}, {0.1, 0.15, 0.2, 0.7}, {0.1, 0.15, 0.2, 0.7});
subgame->add(menubar);
auto zeusLogo = std::make_shared<GUIRect>("zeusLogo");
@ -58,125 +59,152 @@ MainMenuScene::MainMenuScene(ClientState& state) : Scene(state) {
zeusServersButtonText->setPos({26*GS,2*GS});
zeusServersButton->add(zeusServersButtonText);
auto zephaText = std::make_shared<GUIText>("zephaText");
zephaText->create({GS*2, GS*2}, {}, {}, {1,1,1,1}, f);
zephaText->setText("Zepha");
zephaText->setPos({size.x - 48*GS, size.y - 44*GS});
components.add(zephaText);
/* End temp */
auto alphaText = std::make_shared<GUIText>("alphaText");
alphaText->create({GS, GS}, {}, {}, {1,0.5,0.7,1}, f);
alphaText->setText("ALPHA");
alphaText->setPos({size.x - 27*GS, size.y - 27*GS});
components.add(alphaText);
branding = std::make_shared<GUIContainer>("zephaBranding");
components.add(branding);
{
auto zephaText = std::make_shared<GUIText>("zephaText");
zephaText->create({GS, GS}, {}, {}, {1, 1, 1, 1}, f);
zephaText->setText("Zepha");
branding->add(zephaText);
auto bottomBar = std::make_shared<GUIContainer>("bottomBar");
bottomBar->setPos({0, size.y - 18*GS});
components.add(bottomBar);
auto bottomBarBg = std::make_shared<GUIContainer>("bottomBarBg");
bottomBar->add(bottomBarBg);
auto bottomBarElems = std::make_shared<GUIContainer>("bottomBarElems");
bottomBar->add(bottomBarElems);
// Subgame Buttons
auto zeusButton = std::make_shared<GUIImageButton>("zeusButton");
zeusButton->create({16*GS, 16*GS}, {}, state.defs.textures["crop(0, 0, 16, 16, menu_flag_zeus)"],
state.defs.textures["crop(16, 0, 16, 16, menu_flag_zeus)"]);
zeusButton->setPos({GS, GS});
zeusButton->setClickCallback([&](){
if (!showingSubgame) {
components.insert(0, subgame);
showingSubgame = true;
}
});
bottomBarElems->add(zeusButton);
auto serversButton = std::make_shared<GUIImageButton>("serversButton");
serversButton->create({16*GS, 16*GS}, {}, state.defs.textures["crop(0, 0, 16, 16, menu_flag_multiplayer)"],
state.defs.textures["crop(16, 0, 16, 16, menu_flag_multiplayer)"]);
serversButton->setPos({16*GS + GS*3, GS});
serversButton->setClickCallback([&](){
if (showingSubgame) {
components.remove(subgame->getKey());
showingSubgame = false;
}
});
bottomBarElems->add(serversButton);
auto contentButton = std::make_shared<GUIImageButton>("contentButton");
contentButton->create({16*GS, 16*GS}, {}, state.defs.textures["crop(0, 0, 16, 16, menu_flag_content)"],
state.defs.textures["crop(16, 0, 16, 16, menu_flag_content)"]);
contentButton->setPos({16*GS*2 + GS*5, GS});
contentButton->setClickCallback([&](){
if (showingSubgame) {
components.remove(subgame->getKey());
showingSubgame = false;
}
});
bottomBarElems->add(contentButton);
// Meta buttons
auto settingsButton = std::make_shared<GUIImageButton>("settingsButton");
settingsButton->create({16*GS, 16*GS}, {}, state.defs.textures["crop(0, 0, 16, 16, menu_flag_settings)"],
state.defs.textures["crop(16, 0, 16, 16, menu_flag_settings)"]);
settingsButton->setPos({size.x - 16*GS*2 - GS*3, GS});
settingsButton->setClickCallback([](){
std::cout << "Settings" << std::endl;
});
bottomBarElems->add(settingsButton);
auto closeButton = std::make_shared<GUIImageButton>("closeButton");
closeButton->create({16*GS, 16*GS}, {}, state.defs.textures["crop(0, 0, 16, 16, menu_flag_quit)"],
state.defs.textures["crop(16, 0, 16, 16, menu_flag_quit)"]);
closeButton->setPos({size.x - 16*GS - GS, GS});
closeButton->setClickCallback([](){ exit(0); });
bottomBarElems->add(closeButton);
for (unsigned int i = 0; i < size.x/64/GS; i++) {
auto bottomBarSegment = std::make_shared<GUIRect>("bottomBarSegment" + to_string(i));
bottomBarSegment->create({64*GS, 18*GS}, {}, state.defs.textures["menu_bar_bg"]);
bottomBarSegment->setPos({i*64*GS, 0});
bottomBarBg->add(bottomBarSegment);
auto alphaText = std::make_shared<GUIText>("alphaText");
alphaText->create({GS, GS}, {}, {}, {1, 0.5, 0.7, 1}, f);
alphaText->setText("ALPHA");
alphaText->setPos({25*GS, 0});
branding->add(alphaText);
}
navigationBar = std::make_shared<GUIContainer>("navigationBar");
navigationBar->add(std::make_shared<GUIContainer>("navigationBarBg"));
navigationBar->add(std::make_shared<GUIContainer>("navigationBarIcons"));
auto navigationBarIcons = navigationBar->get<GUIContainer>("navigationBarIcons");
components.add(navigationBar);
{
auto settingsButton = std::make_shared<GUIImageButton>("settingsButton");
settingsButton->create({16 * GS, 16 * GS}, {},
state.defs.textures["crop(0, 0, 16, 16, menu_flag_settings)"],
state.defs.textures["crop(16, 0, 16, 16, menu_flag_settings)"]);
navigationBar->get<GUIContainer>("navigationBarIcons")->add(settingsButton);
auto closeButton = std::make_shared<GUIImageButton>("closeButton");
closeButton->create({16 * GS, 16 * GS}, {},
state.defs.textures["crop(0, 0, 16, 16, menu_flag_quit)"],
state.defs.textures["crop(16, 0, 16, 16, menu_flag_quit)"]);
closeButton->setClickCallback([]() { exit(0); });
navigationBar->get<GUIContainer>("navigationBarIcons")->add(closeButton);
auto serversButton = std::make_shared<GUIImageButton>("serversButton");
serversButton->create({16 * GS, 16 * GS}, {},
state.defs.textures["crop(0, 0, 16, 16, menu_flag_multiplayer)"],
state.defs.textures["crop(16, 0, 16, 16, menu_flag_multiplayer)"]);
serversButton->setPos({GS, GS});
navigationBarIcons->add(serversButton);
auto contentButton = std::make_shared<GUIImageButton>("contentButton");
contentButton->create({16 * GS, 16 * GS}, {},
state.defs.textures["crop(0, 0, 16, 16, menu_flag_content)"],
state.defs.textures["crop(16, 0, 16, 16, menu_flag_content)"]);
contentButton->setPos({GS + GS * 18, GS});
navigationBarIcons->add(contentButton);
auto divider = std::make_shared<GUIRect>("divider");
divider->create({GS, GS * 10}, {}, {1, 1, 1, 0.3});
divider->setPos({GS * 2 + GS * 18 * 2, GS * 4});
navigationBarIcons->add(divider);
findSubgames();
for (unsigned int i = 0; i < subgames.size(); i++) {
auto &subgame = subgames[i];
auto button = std::make_shared<GUIImageButton>(subgame.config.name);
button->create({16 * GS, 16 * GS}, {},
state.defs.textures["crop(0, 0, 16, 16, " + subgame.iconRef->name + ")"],
state.defs.textures["crop(16, 0, 16, 16, " + subgame.iconRef->name + ")"]);
button->setPos({GS * 7 + GS * 18 * (i + 2), GS});
navigationBarIcons->add(button);
}
}
positionElements(win);
}
void MainMenuScene::findSubgames() {
std::string subgamesPath = state.path + "subgames";
cf_dir_t subgamesDir;
cf_dir_open(&subgamesDir, subgamesPath.data());
while (subgamesDir.has_next) {
cf_file_t subgameFolder;
cf_read_file(&subgamesDir, &subgameFolder);
if (!subgameFolder.is_dir) { cf_dir_next(&subgamesDir); continue; }
bool hasConf = false;
bool hasIcon = false;
cf_dir_t subgame;
cf_dir_open(&subgame, subgameFolder.path);
while (subgame.has_next) {
cf_file_t file;
cf_read_file(&subgame, &file);
if (!file.is_dir && strncmp(file.name, "icon.png", 8) == 0) hasIcon = true;
if (!file.is_dir && strncmp(file.name, "conf.json", 9) == 0) hasConf = true;
cf_dir_next(&subgame);
}
cf_dir_close(&subgame);
if (!hasConf || !hasIcon) { cf_dir_next(&subgamesDir); continue; }
json j {};
std::ifstream i(std::string(subgameFolder.path) + "/conf.json");
i >> j;
std::string name = j["name"];
std::string description = j["description"];
std::string version = j["version"];
subgames.push_back({
state.defs.textures.loadImage(std::string(subgameFolder.path) + "/icon.png", name),
{name, description, version}, subgameFolder.path
});
cf_dir_next(&subgamesDir);
}
cf_dir_close(&subgamesDir);
std::sort(subgames.begin(), subgames.end(), [](Subgame& a, Subgame& b) {
return a.config.name < b.config.name;
});
}
void MainMenuScene::positionElements(glm::ivec2 win) {
branding->setPos({win.x - 55*GS, win.y - 30*GS});
navigationBar->setPos({0, win.y - 18*GS});
auto navigationBarBg = navigationBar->get<GUIContainer>("navigationBarBg");
for (unsigned int i = 0; i < static_cast<float>(win.x) / 64.f / GS; i++) {
auto segment = std::make_shared<GUIRect>("segment_" + to_string(i));
segment->create({64 * GS, 18 * GS}, {}, state.defs.textures["menu_bar_bg"]);
segment->setPos({i * 64 * GS, 0});
navigationBarBg->add(segment);
}
auto navigationBarIcons = navigationBar->get<GUIContainer>("navigationBarIcons");
navigationBarIcons->get<GUIImageButton>("closeButton")->setPos({win.x - 16*GS - GS, GS});
navigationBarIcons->get<GUIImageButton>("settingsButton")->setPos({win.x - 16*GS*2 - GS*3, GS});
}
void MainMenuScene::update() {
state.defs.textures.update();
if (state.renderer.resized) {
auto size = state.renderer.getWindow().getSize();
subgame->setScale(size);
subgame->get<GUIRect>("menubar")->setScale({90*GS, size.y});
auto zeusLogo = subgame->get<GUIRect>("menubar")->get<GUIRect>("zeusLogo");
zeusLogo->setPos({2*GS, 3*GS});
zeusLogo->setScale({GS*86, GS*30});
components.get<GUIText>("zephaText")->setPos({size.x - 48*GS, size.y - 44*GS});
components.get<GUIText>("alphaText")->setPos({size.x - 27*GS, size.y - 27*GS});
auto bottomBar = components.get<GUIContainer>("bottomBar");
bottomBar->setPos({0, size.y - 18*GS});
auto bottomBarElems = bottomBar->get<GUIContainer>("bottomBarElems");
auto settingsButton = bottomBarElems->get<GUIRect>("settingsButton");
settingsButton->setPos({size.x - 16*GS*2 - GS*3, GS});
auto closeButton = bottomBarElems->get<GUIRect>("closeButton");
closeButton->setPos({size.x - 16*GS - GS, GS});
auto bottomBarBg = bottomBar->get<GUIContainer>("bottomBarBg");
bottomBarBg->empty();
for (unsigned int i = 0; i < size.x/64/GS; i++) {
auto bottomBarSegment = std::make_shared<GUIRect>("bottomBarSegment" + to_string(i));
bottomBarSegment->create({64*GS, 18*GS}, {}, state.defs.textures["menu_bar_bg"]);
bottomBarSegment->setPos({i*64*GS, 0});
bottomBarBg->add(bottomBarSegment);
}
positionElements(state.renderer.getWindow().getSize());
state.renderer.resized = false;
}
@ -187,14 +215,11 @@ void MainMenuScene::update() {
}
void MainMenuScene::draw() {
Renderer& renderer = state.renderer;
state.renderer.beginChunkDeferredCalls();
state.renderer.endDeferredCalls();
renderer.beginChunkDeferredCalls();
renderer.endDeferredCalls();
renderer.beginGUIDrawCalls();
renderer.enableTexture(&state.defs.textures.atlasTexture);
components.draw(renderer);
renderer.swapBuffers();
state.renderer.beginGUIDrawCalls();
state.renderer.enableTexture(&state.defs.textures.atlasTexture);
components.draw(state.renderer);
state.renderer.swapBuffers();
}

View File

@ -4,10 +4,15 @@
#pragma once
#include <json/json.hpp>
#include "../../game/ClientState.h"
#include "../../game/graph/scene/Scene.h"
#include "../hud/components/basic/GUIText.h"
#include "../hud/components/basic/GUIContainer.h"
#include "../hud/components/compound/GUIImageButton.h"
#include "menu/Subgame.h"
using nlohmann::json;
class MainMenuScene : public Scene {
public:
@ -19,10 +24,18 @@ public:
void cleanup() override {};
private:
const int GS = 4;
void positionElements(glm::ivec2 win);
void findSubgames();
std::vector<Subgame> subgames;
const float GS = 4;
GUIContainer components;
bool showingSubgame = true;
std::shared_ptr<GUIRect> subgame;
std::shared_ptr<GUIContainer> branding = nullptr;
std::shared_ptr<GUIContainer> navigationBar = nullptr;
};

View File

@ -0,0 +1,5 @@
//
// Created by aurailus on 2019-12-11.
//
#include "Subgame.h"

View File

@ -0,0 +1,17 @@
//
// Created by aurailus on 2019-12-11.
//
#pragma once
#include <string>
#include <memory>
#include "SubgameConfig.h"
#include "../../../def/texture/AtlasRef.h"
class Subgame {
public:
std::shared_ptr<AtlasRef> iconRef = nullptr;
SubgameConfig config {};
std::string subgamePath = "";
};

View File

@ -0,0 +1,13 @@
//
// Created by aurailus on 2019-12-11.
//
#pragma once
#include <string>
struct SubgameConfig {
std::string name;
std::string description;
std::string version;
};

View File

@ -0,0 +1,7 @@
{
"name": "minimal",
"display_name": "Minimal Subgame",
"author": "@aurailus",
"description": "Minimal subgame for development.",
"version": "0.0.1"
}

BIN
subgames/minimal/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -0,0 +1,7 @@
{
"name": "parentheses",
"display_name": "Parentheses",
"author": "@aurailus",
"description": "The Parentheses subgame.",
"version": "0.0.1"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -1,5 +1,5 @@
{
"name": "aurailus:basictools",
"name": "@aurailus:basictools",
"description": "Basic tools for Zepha.",
"version": "0.0.1",
"depends": "zeus:materials"

View File

@ -0,0 +1,38 @@
print("Hello from basictools")
zepha.register_item("@aurailus:basictools:flint_pickaxe", {
name = "Flint Pick",
textures = {
"@aurailus:basictools:flint_pickaxe"
}
});
zepha.register_item("@aurailus:basictools:flint_hatchet", {
name = "Flint Hatchet",
textures = {
"@aurailus:basictools:flint_hatchet"
}
});
zepha.register_item("@aurailus:basictools:flint_shovel", {
name = "Flint Shovel",
textures = {
"@aurailus:basictools:flint_shovel"
}
});
zepha.register_item("@aurailus:basictools:wooden_pickaxe", {
name = "Wooden Pick",
textures = {
"@aurailus:basictools:wooden_pickaxe"
}
});
zepha.register_item("@aurailus:basictools:wooden_hatchet", {
name = "Wooden Hatchet",
textures = {
"@aurailus:basictools:wooden_hatchet"
}
});
zepha.register_item("@aurailus:basictools:wooden_shovel", {
name = "Wooden Shovel",
textures = {
"@aurailus:basictools:wooden_shovel"
}
});

View File

Before

Width:  |  Height:  |  Size: 505 B

After

Width:  |  Height:  |  Size: 505 B

View File

Before

Width:  |  Height:  |  Size: 562 B

After

Width:  |  Height:  |  Size: 562 B

View File

Before

Width:  |  Height:  |  Size: 490 B

After

Width:  |  Height:  |  Size: 490 B

View File

Before

Width:  |  Height:  |  Size: 490 B

After

Width:  |  Height:  |  Size: 490 B

View File

Before

Width:  |  Height:  |  Size: 559 B

After

Width:  |  Height:  |  Size: 559 B

View File

Before

Width:  |  Height:  |  Size: 503 B

After

Width:  |  Height:  |  Size: 503 B

View File

@ -1,38 +0,0 @@
print("Hello from basictools")
zepha.register_item("aurailus:basictools:flint_pickaxe", {
name = "Flint Pick",
textures = {
"aurailus:basictools:flint_pickaxe"
}
});
zepha.register_item("aurailus:basictools:flint_hatchet", {
name = "Flint Hatchet",
textures = {
"aurailus:basictools:flint_hatchet"
}
});
zepha.register_item("aurailus:basictools:flint_shovel", {
name = "Flint Shovel",
textures = {
"aurailus:basictools:flint_shovel"
}
});
zepha.register_item("aurailus:basictools:wooden_pickaxe", {
name = "Wooden Pick",
textures = {
"aurailus:basictools:wooden_pickaxe"
}
});
zepha.register_item("aurailus:basictools:wooden_hatchet", {
name = "Wooden Hatchet",
textures = {
"aurailus:basictools:wooden_hatchet"
}
});
zepha.register_item("aurailus:basictools:wooden_shovel", {
name = "Wooden Shovel",
textures = {
"aurailus:basictools:wooden_shovel"
}
});