mirror of
https://github.com/luanti-org/luanti.git
synced 2025-06-27 16:36:03 +00:00
split scriptapi.cpp
Remerge some files in order to reduce number of additional files Make necessary changes for split, rename files, reorganize some bits
This commit is contained in:
parent
038529c763
commit
bdbdeab005
29 changed files with 8454 additions and 6899 deletions
381
src/scriptapi_craft.cpp
Normal file
381
src/scriptapi_craft.cpp
Normal file
|
@ -0,0 +1,381 @@
|
|||
/*
|
||||
Minetest
|
||||
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "scriptapi.h"
|
||||
#include "scriptapi_craft.h"
|
||||
|
||||
extern "C" {
|
||||
#include <lauxlib.h>
|
||||
}
|
||||
|
||||
#include "script.h"
|
||||
#include "scriptapi_types.h"
|
||||
#include "scriptapi_common.h"
|
||||
#include "scriptapi_item.h"
|
||||
|
||||
|
||||
struct EnumString es_CraftMethod[] =
|
||||
{
|
||||
{CRAFT_METHOD_NORMAL, "normal"},
|
||||
{CRAFT_METHOD_COOKING, "cooking"},
|
||||
{CRAFT_METHOD_FUEL, "fuel"},
|
||||
{0, NULL},
|
||||
};
|
||||
|
||||
|
||||
// helper for register_craft
|
||||
bool read_craft_recipe_shaped(lua_State *L, int index,
|
||||
int &width, std::vector<std::string> &recipe)
|
||||
{
|
||||
if(index < 0)
|
||||
index = lua_gettop(L) + 1 + index;
|
||||
|
||||
if(!lua_istable(L, index))
|
||||
return false;
|
||||
|
||||
lua_pushnil(L);
|
||||
int rowcount = 0;
|
||||
while(lua_next(L, index) != 0){
|
||||
int colcount = 0;
|
||||
// key at index -2 and value at index -1
|
||||
if(!lua_istable(L, -1))
|
||||
return false;
|
||||
int table2 = lua_gettop(L);
|
||||
lua_pushnil(L);
|
||||
while(lua_next(L, table2) != 0){
|
||||
// key at index -2 and value at index -1
|
||||
if(!lua_isstring(L, -1))
|
||||
return false;
|
||||
recipe.push_back(lua_tostring(L, -1));
|
||||
// removes value, keeps key for next iteration
|
||||
lua_pop(L, 1);
|
||||
colcount++;
|
||||
}
|
||||
if(rowcount == 0){
|
||||
width = colcount;
|
||||
} else {
|
||||
if(colcount != width)
|
||||
return false;
|
||||
}
|
||||
// removes value, keeps key for next iteration
|
||||
lua_pop(L, 1);
|
||||
rowcount++;
|
||||
}
|
||||
return width != 0;
|
||||
}
|
||||
|
||||
// helper for register_craft
|
||||
bool read_craft_recipe_shapeless(lua_State *L, int index,
|
||||
std::vector<std::string> &recipe)
|
||||
{
|
||||
if(index < 0)
|
||||
index = lua_gettop(L) + 1 + index;
|
||||
|
||||
if(!lua_istable(L, index))
|
||||
return false;
|
||||
|
||||
lua_pushnil(L);
|
||||
while(lua_next(L, index) != 0){
|
||||
// key at index -2 and value at index -1
|
||||
if(!lua_isstring(L, -1))
|
||||
return false;
|
||||
recipe.push_back(lua_tostring(L, -1));
|
||||
// removes value, keeps key for next iteration
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// helper for register_craft
|
||||
bool read_craft_replacements(lua_State *L, int index,
|
||||
CraftReplacements &replacements)
|
||||
{
|
||||
if(index < 0)
|
||||
index = lua_gettop(L) + 1 + index;
|
||||
|
||||
if(!lua_istable(L, index))
|
||||
return false;
|
||||
|
||||
lua_pushnil(L);
|
||||
while(lua_next(L, index) != 0){
|
||||
// key at index -2 and value at index -1
|
||||
if(!lua_istable(L, -1))
|
||||
return false;
|
||||
lua_rawgeti(L, -1, 1);
|
||||
if(!lua_isstring(L, -1))
|
||||
return false;
|
||||
std::string replace_from = lua_tostring(L, -1);
|
||||
lua_pop(L, 1);
|
||||
lua_rawgeti(L, -1, 2);
|
||||
if(!lua_isstring(L, -1))
|
||||
return false;
|
||||
std::string replace_to = lua_tostring(L, -1);
|
||||
lua_pop(L, 1);
|
||||
replacements.pairs.push_back(
|
||||
std::make_pair(replace_from, replace_to));
|
||||
// removes value, keeps key for next iteration
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// register_craft({output=item, recipe={{item00,item10},{item01,item11}})
|
||||
int l_register_craft(lua_State *L)
|
||||
{
|
||||
//infostream<<"register_craft"<<std::endl;
|
||||
luaL_checktype(L, 1, LUA_TTABLE);
|
||||
int table = 1;
|
||||
|
||||
// Get the writable craft definition manager from the server
|
||||
IWritableCraftDefManager *craftdef =
|
||||
get_server(L)->getWritableCraftDefManager();
|
||||
|
||||
std::string type = getstringfield_default(L, table, "type", "shaped");
|
||||
|
||||
/*
|
||||
CraftDefinitionShaped
|
||||
*/
|
||||
if(type == "shaped"){
|
||||
std::string output = getstringfield_default(L, table, "output", "");
|
||||
if(output == "")
|
||||
throw LuaError(L, "Crafting definition is missing an output");
|
||||
|
||||
int width = 0;
|
||||
std::vector<std::string> recipe;
|
||||
lua_getfield(L, table, "recipe");
|
||||
if(lua_isnil(L, -1))
|
||||
throw LuaError(L, "Crafting definition is missing a recipe"
|
||||
" (output=\"" + output + "\")");
|
||||
if(!read_craft_recipe_shaped(L, -1, width, recipe))
|
||||
throw LuaError(L, "Invalid crafting recipe"
|
||||
" (output=\"" + output + "\")");
|
||||
|
||||
CraftReplacements replacements;
|
||||
lua_getfield(L, table, "replacements");
|
||||
if(!lua_isnil(L, -1))
|
||||
{
|
||||
if(!read_craft_replacements(L, -1, replacements))
|
||||
throw LuaError(L, "Invalid replacements"
|
||||
" (output=\"" + output + "\")");
|
||||
}
|
||||
|
||||
CraftDefinition *def = new CraftDefinitionShaped(
|
||||
output, width, recipe, replacements);
|
||||
craftdef->registerCraft(def);
|
||||
}
|
||||
/*
|
||||
CraftDefinitionShapeless
|
||||
*/
|
||||
else if(type == "shapeless"){
|
||||
std::string output = getstringfield_default(L, table, "output", "");
|
||||
if(output == "")
|
||||
throw LuaError(L, "Crafting definition (shapeless)"
|
||||
" is missing an output");
|
||||
|
||||
std::vector<std::string> recipe;
|
||||
lua_getfield(L, table, "recipe");
|
||||
if(lua_isnil(L, -1))
|
||||
throw LuaError(L, "Crafting definition (shapeless)"
|
||||
" is missing a recipe"
|
||||
" (output=\"" + output + "\")");
|
||||
if(!read_craft_recipe_shapeless(L, -1, recipe))
|
||||
throw LuaError(L, "Invalid crafting recipe"
|
||||
" (output=\"" + output + "\")");
|
||||
|
||||
CraftReplacements replacements;
|
||||
lua_getfield(L, table, "replacements");
|
||||
if(!lua_isnil(L, -1))
|
||||
{
|
||||
if(!read_craft_replacements(L, -1, replacements))
|
||||
throw LuaError(L, "Invalid replacements"
|
||||
" (output=\"" + output + "\")");
|
||||
}
|
||||
|
||||
CraftDefinition *def = new CraftDefinitionShapeless(
|
||||
output, recipe, replacements);
|
||||
craftdef->registerCraft(def);
|
||||
}
|
||||
/*
|
||||
CraftDefinitionToolRepair
|
||||
*/
|
||||
else if(type == "toolrepair"){
|
||||
float additional_wear = getfloatfield_default(L, table,
|
||||
"additional_wear", 0.0);
|
||||
|
||||
CraftDefinition *def = new CraftDefinitionToolRepair(
|
||||
additional_wear);
|
||||
craftdef->registerCraft(def);
|
||||
}
|
||||
/*
|
||||
CraftDefinitionCooking
|
||||
*/
|
||||
else if(type == "cooking"){
|
||||
std::string output = getstringfield_default(L, table, "output", "");
|
||||
if(output == "")
|
||||
throw LuaError(L, "Crafting definition (cooking)"
|
||||
" is missing an output");
|
||||
|
||||
std::string recipe = getstringfield_default(L, table, "recipe", "");
|
||||
if(recipe == "")
|
||||
throw LuaError(L, "Crafting definition (cooking)"
|
||||
" is missing a recipe"
|
||||
" (output=\"" + output + "\")");
|
||||
|
||||
float cooktime = getfloatfield_default(L, table, "cooktime", 3.0);
|
||||
|
||||
CraftReplacements replacements;
|
||||
lua_getfield(L, table, "replacements");
|
||||
if(!lua_isnil(L, -1))
|
||||
{
|
||||
if(!read_craft_replacements(L, -1, replacements))
|
||||
throw LuaError(L, "Invalid replacements"
|
||||
" (cooking output=\"" + output + "\")");
|
||||
}
|
||||
|
||||
CraftDefinition *def = new CraftDefinitionCooking(
|
||||
output, recipe, cooktime, replacements);
|
||||
craftdef->registerCraft(def);
|
||||
}
|
||||
/*
|
||||
CraftDefinitionFuel
|
||||
*/
|
||||
else if(type == "fuel"){
|
||||
std::string recipe = getstringfield_default(L, table, "recipe", "");
|
||||
if(recipe == "")
|
||||
throw LuaError(L, "Crafting definition (fuel)"
|
||||
" is missing a recipe");
|
||||
|
||||
float burntime = getfloatfield_default(L, table, "burntime", 1.0);
|
||||
|
||||
CraftReplacements replacements;
|
||||
lua_getfield(L, table, "replacements");
|
||||
if(!lua_isnil(L, -1))
|
||||
{
|
||||
if(!read_craft_replacements(L, -1, replacements))
|
||||
throw LuaError(L, "Invalid replacements"
|
||||
" (fuel recipe=\"" + recipe + "\")");
|
||||
}
|
||||
|
||||
CraftDefinition *def = new CraftDefinitionFuel(
|
||||
recipe, burntime, replacements);
|
||||
craftdef->registerCraft(def);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw LuaError(L, "Unknown crafting definition type: \"" + type + "\"");
|
||||
}
|
||||
|
||||
lua_pop(L, 1);
|
||||
return 0; /* number of results */
|
||||
}
|
||||
|
||||
// get_craft_result(input)
|
||||
int l_get_craft_result(lua_State *L)
|
||||
{
|
||||
int input_i = 1;
|
||||
std::string method_s = getstringfield_default(L, input_i, "method", "normal");
|
||||
enum CraftMethod method = (CraftMethod)getenumfield(L, input_i, "method",
|
||||
es_CraftMethod, CRAFT_METHOD_NORMAL);
|
||||
int width = 1;
|
||||
lua_getfield(L, input_i, "width");
|
||||
if(lua_isnumber(L, -1))
|
||||
width = luaL_checkinteger(L, -1);
|
||||
lua_pop(L, 1);
|
||||
lua_getfield(L, input_i, "items");
|
||||
std::vector<ItemStack> items = read_items(L, -1);
|
||||
lua_pop(L, 1); // items
|
||||
|
||||
IGameDef *gdef = get_server(L);
|
||||
ICraftDefManager *cdef = gdef->cdef();
|
||||
CraftInput input(method, width, items);
|
||||
CraftOutput output;
|
||||
bool got = cdef->getCraftResult(input, output, true, gdef);
|
||||
lua_newtable(L); // output table
|
||||
if(got){
|
||||
ItemStack item;
|
||||
item.deSerialize(output.item, gdef->idef());
|
||||
LuaItemStack::create(L, item);
|
||||
lua_setfield(L, -2, "item");
|
||||
setintfield(L, -1, "time", output.time);
|
||||
} else {
|
||||
LuaItemStack::create(L, ItemStack());
|
||||
lua_setfield(L, -2, "item");
|
||||
setintfield(L, -1, "time", 0);
|
||||
}
|
||||
lua_newtable(L); // decremented input table
|
||||
lua_pushstring(L, method_s.c_str());
|
||||
lua_setfield(L, -2, "method");
|
||||
lua_pushinteger(L, width);
|
||||
lua_setfield(L, -2, "width");
|
||||
push_items(L, input.items);
|
||||
lua_setfield(L, -2, "items");
|
||||
return 2;
|
||||
}
|
||||
|
||||
// get_craft_recipe(result item)
|
||||
int l_get_craft_recipe(lua_State *L)
|
||||
{
|
||||
int k = 0;
|
||||
char tmp[20];
|
||||
int input_i = 1;
|
||||
std::string o_item = luaL_checkstring(L,input_i);
|
||||
|
||||
IGameDef *gdef = get_server(L);
|
||||
ICraftDefManager *cdef = gdef->cdef();
|
||||
CraftInput input;
|
||||
CraftOutput output(o_item,0);
|
||||
bool got = cdef->getCraftRecipe(input, output, gdef);
|
||||
lua_newtable(L); // output table
|
||||
if(got){
|
||||
lua_newtable(L);
|
||||
for(std::vector<ItemStack>::const_iterator
|
||||
i = input.items.begin();
|
||||
i != input.items.end(); i++, k++)
|
||||
{
|
||||
if (i->empty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
sprintf(tmp,"%d",k);
|
||||
lua_pushstring(L,tmp);
|
||||
lua_pushstring(L,i->name.c_str());
|
||||
lua_settable(L, -3);
|
||||
}
|
||||
lua_setfield(L, -2, "items");
|
||||
setintfield(L, -1, "width", input.width);
|
||||
switch (input.method) {
|
||||
case CRAFT_METHOD_NORMAL:
|
||||
lua_pushstring(L,"normal");
|
||||
break;
|
||||
case CRAFT_METHOD_COOKING:
|
||||
lua_pushstring(L,"cooking");
|
||||
break;
|
||||
case CRAFT_METHOD_FUEL:
|
||||
lua_pushstring(L,"fuel");
|
||||
break;
|
||||
default:
|
||||
lua_pushstring(L,"unknown");
|
||||
}
|
||||
lua_setfield(L, -2, "type");
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
lua_setfield(L, -2, "items");
|
||||
setintfield(L, -1, "width", 0);
|
||||
}
|
||||
return 1;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue