mirror of
https://github.com/luanti-org/luanti.git
synced 2025-06-27 16:36:03 +00:00
Crafting definition in scripts
This commit is contained in:
parent
8dd3622c6d
commit
9d5b458479
12 changed files with 634 additions and 57 deletions
229
src/craftdef.cpp
Normal file
229
src/craftdef.cpp
Normal file
|
@ -0,0 +1,229 @@
|
|||
/*
|
||||
Minetest-c55
|
||||
Copyright (C) 2011 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 General Public License as published by
|
||||
the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU 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 "craftdef.h"
|
||||
|
||||
#include "irrlichttypes.h"
|
||||
#include "log.h"
|
||||
#include <sstream>
|
||||
#include "utility.h"
|
||||
#include "gamedef.h"
|
||||
#include "inventory.h"
|
||||
|
||||
CraftPointerInput::~CraftPointerInput()
|
||||
{
|
||||
for(u32 i=0; i<items.size(); i++)
|
||||
delete items[i];
|
||||
}
|
||||
|
||||
CraftPointerInput createPointerInput(const CraftInput &ci, IGameDef *gamedef)
|
||||
{
|
||||
std::vector<InventoryItem*> items;
|
||||
for(u32 i=0; i<ci.items.size(); i++){
|
||||
InventoryItem *item = NULL;
|
||||
if(ci.items[i] != ""){
|
||||
std::istringstream iss(ci.items[i], std::ios::binary);
|
||||
item = InventoryItem::deSerialize(iss, gamedef);
|
||||
}
|
||||
items.push_back(item);
|
||||
}
|
||||
return CraftPointerInput(ci.width, items);
|
||||
}
|
||||
|
||||
CraftInput createInput(const CraftPointerInput &cpi)
|
||||
{
|
||||
std::vector<std::string> items;
|
||||
for(u32 i=0; i<cpi.items.size(); i++){
|
||||
if(cpi.items[i] == NULL)
|
||||
items.push_back("");
|
||||
else{
|
||||
std::ostringstream oss(std::ios::binary);
|
||||
cpi.items[i]->serialize(oss);
|
||||
items.push_back(oss.str());
|
||||
}
|
||||
}
|
||||
return CraftInput(cpi.width, items);
|
||||
}
|
||||
|
||||
std::string CraftInput::dump() const
|
||||
{
|
||||
std::ostringstream os(std::ios::binary);
|
||||
os<<"(width="<<width<<"){";
|
||||
for(u32 i=0; i<items.size(); i++)
|
||||
os<<"\""<<items[i]<<"\",";
|
||||
os<<"}";
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::string CraftDefinition::dump() const
|
||||
{
|
||||
std::ostringstream os(std::ios::binary);
|
||||
os<<"{output=\""<<output<<"\", input={";
|
||||
for(u32 i=0; i<input.items.size(); i++)
|
||||
os<<"\""<<input.items[i]<<"\",";
|
||||
os<<"}, (input.width="<<input.width<<")}";
|
||||
return os.str();
|
||||
}
|
||||
|
||||
void CraftDefinition::serialize(std::ostream &os) const
|
||||
{
|
||||
writeU8(os, 0); // version
|
||||
os<<serializeString(output);
|
||||
writeU8(os, input.width);
|
||||
writeU16(os, input.items.size());
|
||||
for(u32 i=0; i<input.items.size(); i++)
|
||||
os<<serializeString(input.items[i]);
|
||||
}
|
||||
|
||||
void CraftDefinition::deSerialize(std::istream &is)
|
||||
{
|
||||
int version = readU8(is);
|
||||
if(version != 0) throw SerializationError(
|
||||
"unsupported CraftDefinition version");
|
||||
output = deSerializeString(is);
|
||||
input.width = readU8(is);
|
||||
u32 count = readU16(is);
|
||||
for(u32 i=0; i<count; i++)
|
||||
input.items.push_back(deSerializeString(is));
|
||||
}
|
||||
|
||||
class CCraftDefManager: public IWritableCraftDefManager
|
||||
{
|
||||
public:
|
||||
virtual ~CCraftDefManager()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
virtual InventoryItem* getCraftResult(const CraftPointerInput &input_cpi,
|
||||
IGameDef *gamedef) const
|
||||
{
|
||||
if(input_cpi.width > 3){
|
||||
errorstream<<"getCraftResult: IGNORING ERROR: "
|
||||
<<"input_cpi.width > 3"<<std::endl;
|
||||
return NULL;
|
||||
}
|
||||
InventoryItem *input_items[9];
|
||||
for(u32 y=0; y<3; y++)
|
||||
for(u32 x=0; x<3; x++)
|
||||
{
|
||||
u32 i=y*3+x;
|
||||
if(x >= input_cpi.width || y >= input_cpi.height())
|
||||
input_items[i] = NULL;
|
||||
else
|
||||
input_items[i] = input_cpi.items[y*input_cpi.width+x];
|
||||
}
|
||||
for(core::list<CraftDefinition*>::ConstIterator
|
||||
i = m_craft_definitions.begin();
|
||||
i != m_craft_definitions.end(); i++)
|
||||
{
|
||||
CraftDefinition *def = *i;
|
||||
|
||||
infostream<<"Checking "<<createInput(input_cpi).dump()<<std::endl
|
||||
<<" against "<<def->input.dump()
|
||||
<<" (output=\""<<def->output<<"\")"<<std::endl;
|
||||
|
||||
CraftPointerInput spec_cpi = createPointerInput(def->input, gamedef);
|
||||
if(spec_cpi.width > 3){
|
||||
errorstream<<"getCraftResult: IGNORING ERROR: "
|
||||
<<"spec_cpi.width > 3"<<std::endl;
|
||||
continue;
|
||||
}
|
||||
InventoryItem *spec_items[9];
|
||||
for(u32 y=0; y<3; y++)
|
||||
for(u32 x=0; x<3; x++)
|
||||
{
|
||||
u32 i=y*3+x;
|
||||
if(x >= spec_cpi.width || y >= spec_cpi.height())
|
||||
spec_items[i] = NULL;
|
||||
else
|
||||
spec_items[i] = spec_cpi.items[y*spec_cpi.width+x];
|
||||
infostream<<"spec_items["<<i<<"] = "<<spec_items[i]<<std::endl;
|
||||
}
|
||||
|
||||
bool match = checkItemCombination(input_items, spec_items);
|
||||
|
||||
if(match){
|
||||
std::istringstream iss(def->output, std::ios::binary);
|
||||
return InventoryItem::deSerialize(iss, gamedef);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
virtual void registerCraft(const CraftDefinition &def)
|
||||
{
|
||||
infostream<<"registerCraft: registering craft definition: "
|
||||
<<def.dump()<<std::endl;
|
||||
if(def.input.width > 3 || def.input.height() > 3){
|
||||
errorstream<<"registerCraft: input size is larger than 3x3,"
|
||||
<<" ignoring"<<std::endl;
|
||||
return;
|
||||
}
|
||||
m_craft_definitions.push_back(new CraftDefinition(def));
|
||||
}
|
||||
virtual void clear()
|
||||
{
|
||||
for(core::list<CraftDefinition*>::Iterator
|
||||
i = m_craft_definitions.begin();
|
||||
i != m_craft_definitions.end(); i++){
|
||||
delete *i;
|
||||
}
|
||||
m_craft_definitions.clear();
|
||||
}
|
||||
virtual void serialize(std::ostream &os)
|
||||
{
|
||||
writeU8(os, 0); // version
|
||||
u16 count = m_craft_definitions.size();
|
||||
writeU16(os, count);
|
||||
for(core::list<CraftDefinition*>::Iterator
|
||||
i = m_craft_definitions.begin();
|
||||
i != m_craft_definitions.end(); i++){
|
||||
CraftDefinition *def = *i;
|
||||
// Serialize wrapped in a string
|
||||
std::ostringstream tmp_os(std::ios::binary);
|
||||
def->serialize(tmp_os);
|
||||
os<<serializeString(tmp_os.str());
|
||||
}
|
||||
}
|
||||
virtual void deSerialize(std::istream &is)
|
||||
{
|
||||
// Clear everything
|
||||
clear();
|
||||
// Deserialize
|
||||
int version = readU8(is);
|
||||
if(version != 0) throw SerializationError(
|
||||
"unsupported CraftDefManager version");
|
||||
u16 count = readU16(is);
|
||||
for(u16 i=0; i<count; i++){
|
||||
// Deserialize a string and grab a CraftDefinition from it
|
||||
std::istringstream tmp_is(deSerializeString(is), std::ios::binary);
|
||||
CraftDefinition def;
|
||||
def.deSerialize(tmp_is);
|
||||
// Register
|
||||
registerCraft(def);
|
||||
}
|
||||
}
|
||||
private:
|
||||
core::list<CraftDefinition*> m_craft_definitions;
|
||||
};
|
||||
|
||||
IWritableCraftDefManager* createCraftDefManager()
|
||||
{
|
||||
return new CCraftDefManager();
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue