add NOT gate to circuits

This commit is contained in:
darkrose 2014-08-15 21:04:09 +10:00
parent c4bbda983d
commit 8168e21cb4
12 changed files with 236 additions and 47 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 583 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 599 B

View File

@ -9021,7 +9021,7 @@ void content_mapnode_init()
f->type = CMT_STONE;
f->hardness = 1.0;
content_nodebox_switch(f);
f->setInventoryTextureCube("circuit_switch.png","circuit_switch_front.png","circuit_switch.png");
f->setInventoryTextureNodeBox(i,"circuit_switch.png","circuit_switch_front.png","circuit_switch.png");
if (f->initial_metadata == NULL)
f->initial_metadata = new SwitchNodeMetadata();
{
@ -9035,6 +9035,36 @@ void content_mapnode_init()
lists::add("craftguide",i);
lists::add("creative",i);
i = CONTENT_CIRCUIT_GATE;
f = &content_features(i);
f->description = std::string("Logic Gate");
f->setAllTextures("circuit_gate.png");
f->setTexture(0,"circuit_gate_top.png");
f->rotate_tile_with_nodebox = true;
f->param_type = CPT_FACEDIR_SIMPLE;
f->draw_type = CDT_NODEBOX;
f->is_ground_content = true;
f->energy_type = CET_GATE;
f->energy_drop = 0;
f->solidness = 0; // drawn separately, makes no faces
f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
f->type = CMT_STONE;
f->hardness = 1.0;
content_nodebox_logicgate(f);
f->setInventoryTextureNodeBox(i,"circuit_gate_top.png","circuit_gate.png","circuit_gate.png");
if (f->initial_metadata == NULL)
f->initial_metadata = new LogicGateNodeMetadata();
{
u16 recipe[9] = {
CONTENT_IGNORE, CONTENT_CRAFTITEM_MESEDUST, CONTENT_IGNORE,
CONTENT_IGNORE, CONTENT_STONE, CONTENT_IGNORE,
CONTENT_IGNORE, CONTENT_IGNORE, CONTENT_IGNORE
};
crafting::setRecipe(recipe,CONTENT_CIRCUIT_GATE,1);
}
lists::add("craftguide",i);
lists::add("creative",i);
i = CONTENT_CIRCUIT_LAMP;
f = &content_features(i);
f->description = std::string("Electric Lamp");

View File

@ -541,19 +541,13 @@ MapNode mapnode_translate_to_internal(MapNode n_from, u8 version);
#define CONTENT_CIRCUIT_SOLARPANEL 0xF21
#define CONTENT_CIRCUIT_WATERWHEEL 0xF22
#define CONTENT_CIRCUIT_SWITCH 0xF23
#define CONTENT_CIRCUIT_GATE 0xF24
// circuits - gadgets
#define CONTENT_CIRCUIT_LAMP 0xF40
#define CONTENT_CIRCUIT_LAMP_OFF 0xF41
// circuits - MASKs and control data
#define CONTENT_CIRCUIT_OFF_MASK 0x001
// circuits - MASKs
#define CONTENT_CIRCUIT_MIN 0xF00
#define CONTENT_CIRCUIT_MAX 0xFFF
#define CONTENT_CIRCUIT_WIRE_MIN 0xF00
#define CONTENT_CIRCUIT_WIRE_MAX 0xF1F
#define CONTENT_CIRCUIT_POWERSRC_MIN 0xF20
#define CONTENT_CIRCUIT_POWERSRC_MAX 0xF3F
#define CONTENT_CIRCUIT_GADGET_MIN 0xF40
#define CONTENT_CIRCUIT_GADGET_MAX 0xFFF
#endif

View File

@ -1233,3 +1233,22 @@ void content_nodebox_switch(ContentFeatures *f)
));
}
void content_nodebox_logicgate(ContentFeatures *f)
{
f->setNodeBox(core::aabbox3d<f32>(
-0.125*BS,-0.5*BS,-0.125*BS,0.125*BS,-0.375*BS,0.25*BS
));
f->addNodeBox(core::aabbox3d<f32>(
-0.0625*BS,-0.5*BS,0.25*BS,0.0625*BS,-0.4375*BS,0.5*BS
));
f->addNodeBox(core::aabbox3d<f32>(
-0.0625*BS,-0.5*BS,-0.5*BS,0.0625*BS,-0.4375*BS,-0.125*BS
));
f->addNodeBox(core::aabbox3d<f32>(
-0.5*BS,-0.5*BS,-0.0625*BS,-0.125*BS,-0.4375*BS,0.0625*BS
));
f->addNodeBox(core::aabbox3d<f32>(
0.125*BS,-0.5*BS,-0.0625*BS,0.5*BS,-0.4375*BS,0.0625*BS
));
}

View File

@ -47,5 +47,6 @@ void content_nodebox_couch_outer(ContentFeatures *f);
void content_nodebox_knob(ContentFeatures *f);
void content_nodebox_battery(ContentFeatures *f);
void content_nodebox_switch(ContentFeatures *f);
void content_nodebox_logicgate(ContentFeatures *f);
#endif

View File

@ -2072,6 +2072,7 @@ bool CircuitNodeMetadata::energise(u8 level, v3s16 powersrc, v3s16 signalsrc, v3
if (!level || m_energy < level) {
m_energy = level;
if (!level) {
m_sources.erase(powersrc);
for (std::map<v3s16,u8>::iterator i = m_sources.begin(); i != m_sources.end(); i++) {
u8 v = i->second;
if (v > m_energy)
@ -2193,3 +2194,81 @@ NodeMetadata* SourceNodeMetadata::clone()
SourceNodeMetadata *d = new SourceNodeMetadata();
return d;
}
/*
LogicGateNodeMetadata
*/
// Prototype
LogicGateNodeMetadata proto_LogicGateNodeMetadata;
LogicGateNodeMetadata::LogicGateNodeMetadata()
{
m_energy = 0;
m_ptime = 0;
m_sources.clear();
NodeMetadata::registerType(typeId(), create);
}
u16 LogicGateNodeMetadata::typeId() const
{
return CONTENT_CIRCUIT_GATE;
}
NodeMetadata* LogicGateNodeMetadata::create(std::istream &is)
{
LogicGateNodeMetadata *d = new LogicGateNodeMetadata();
int temp;
is>>temp;
d->m_energy = temp;
is>>temp;
d->m_ptime = (float)temp/10;
int i;
is>>i;
v3s16 p;
for (; i > 0; i--) {
is>>temp;
p.X = temp;
is>>temp;
p.Y = temp;
is>>temp;
p.Z = temp;
is>>temp;
d->m_sources[p] = temp;
}
return d;
}
NodeMetadata* LogicGateNodeMetadata::clone()
{
LogicGateNodeMetadata *d = new LogicGateNodeMetadata();
return d;
}
bool LogicGateNodeMetadata::step(float dtime, v3s16 pos, ServerEnvironment *env)
{
m_ptime += dtime;
if (m_ptime < 1.1)
return false;
m_energy = 0;
env->propogateEnergy(ENERGY_MAX,pos,pos,pos);
return true;
}
bool LogicGateNodeMetadata::energise(u8 level, v3s16 powersrc, v3s16 signalsrc, v3s16 pos)
{
if (powersrc == pos)
return true;
m_ptime = 0;
if (level && m_sources[powersrc] > level)
return false;
if (!level || m_energy < level) {
m_energy = level;
if (!level) {
m_sources.erase(powersrc);
for (std::map<v3s16,u8>::iterator i = m_sources.begin(); i != m_sources.end(); i++) {
u8 v = i->second;
if (v > m_energy)
m_energy = v;
}
}
}
return true;
}

View File

@ -488,5 +488,16 @@ public:
virtual NodeMetadata* clone();
};
class LogicGateNodeMetadata : public CircuitNodeMetadata
{
public:
LogicGateNodeMetadata();
virtual u16 typeId() const;
static NodeMetadata* create(std::istream &is);
virtual NodeMetadata* clone();
virtual bool step(float dtime, v3s16 pos, ServerEnvironment *env);
virtual bool energise(u8 level, v3s16 powersrc, v3s16 signalsrc, v3s16 pos);
};
#endif

View File

@ -2921,11 +2921,17 @@ bool ServerEnvironment::propogateEnergy(u8 level, v3s16 powersrc, v3s16 signalsr
return false;
if ((f.energy_type == CET_SOURCE || f.energy_type == CET_SWITCH) && pos != powersrc)
return false;
if (f.energy_type == CET_GATE && pos == powersrc && level != ENERGY_MAX)
return false;
m = m_map->getNodeMetadata(pos);
if (!m)
return false;
if (!m->energise(level,powersrc,signalsrc,pos))
return false;
if (f.energy_type == CET_GATE)
level = ENERGY_MAX;
if (f.energy_type == CET_GATE && pos != powersrc)
return false;
if (level) {
if (f.powered_node != CONTENT_IGNORE) {
n.setContent(f.powered_node);
@ -3061,45 +3067,76 @@ bool ServerEnvironment::propogateEnergy(u8 level, v3s16 powersrc, v3s16 signalsr
}else{
z_minus = true;
}
if (x_plus) {
if ((pos+v3s16(1,0,0)) != signalsrc)
propogateEnergy(level,powersrc,pos,pos+v3s16(1,0,0));
}else if (x_plus_y) {
if ((pos+v3s16(1,1,0)) != signalsrc)
propogateEnergy(level,powersrc,pos,pos+v3s16(1,1,0));
}else if (x_plus_y_minus) {
if ((pos+v3s16(1,-1,0)) != signalsrc)
propogateEnergy(level,powersrc,pos,pos+v3s16(1,-1,0));
bool gate_x_plus = true;
bool gate_x_minus = true;
bool gate_z_plus = true;
bool gate_z_minus = true;
if (f.energy_type == CET_GATE) {
gate_x_plus = false;
gate_x_minus = false;
gate_z_plus = false;
gate_z_minus = false;
powersrc = pos;
v3s16 dir = n.getRotation();
if (dir == v3s16(1,1,1)) {
gate_z_plus = true;
}else if (dir == v3s16(-1,1,1)) {
gate_x_plus = true;
}else if (dir == v3s16(-1,1,-1)) {
gate_z_minus = true;
}else if (dir == v3s16(1,1,-1)) {
gate_x_minus = true;
}
}
if (x_minus) {
if ((pos+v3s16(-1,0,0)) != signalsrc)
propogateEnergy(level,powersrc,pos,pos+v3s16(-1,0,0));
}else if (x_minus_y) {
if ((pos+v3s16(-1,1,0)) != signalsrc)
propogateEnergy(level,powersrc,pos,pos+v3s16(-1,1,0));
}else if (x_minus_y_minus) {
if ((pos+v3s16(-1,-1,0)) != signalsrc)
propogateEnergy(level,powersrc,pos,pos+v3s16(-1,-1,0));
if (gate_x_plus) {
if (x_plus) {
if ((pos+v3s16(1,0,0)) != signalsrc)
propogateEnergy(level,powersrc,pos,pos+v3s16(1,0,0));
}else if (x_plus_y) {
if ((pos+v3s16(1,1,0)) != signalsrc)
propogateEnergy(level,powersrc,pos,pos+v3s16(1,1,0));
}else if (x_plus_y_minus) {
if ((pos+v3s16(1,-1,0)) != signalsrc)
propogateEnergy(level,powersrc,pos,pos+v3s16(1,-1,0));
}
}
if (z_plus) {
if ((pos+v3s16(0,0,1)) != signalsrc)
propogateEnergy(level,powersrc,pos,pos+v3s16(0,0,1));
}else if (z_plus_y) {
if ((pos+v3s16(0,1,1)) != signalsrc)
propogateEnergy(level,powersrc,pos,pos+v3s16(0,1,1));
}else if (z_plus_y_minus) {
if ((pos+v3s16(0,-1,1)) != signalsrc)
propogateEnergy(level,powersrc,pos,pos+v3s16(0,-1,1));
if (gate_x_minus) {
if (x_minus) {
if ((pos+v3s16(-1,0,0)) != signalsrc)
propogateEnergy(level,powersrc,pos,pos+v3s16(-1,0,0));
}else if (x_minus_y) {
if ((pos+v3s16(-1,1,0)) != signalsrc)
propogateEnergy(level,powersrc,pos,pos+v3s16(-1,1,0));
}else if (x_minus_y_minus) {
if ((pos+v3s16(-1,-1,0)) != signalsrc)
propogateEnergy(level,powersrc,pos,pos+v3s16(-1,-1,0));
}
}
if (z_minus) {
if ((pos+v3s16(0,0,-1)) != signalsrc)
propogateEnergy(level,powersrc,pos,pos+v3s16(0,0,-1));
}else if (z_minus_y) {
if ((pos+v3s16(0,1,-1)) != signalsrc)
propogateEnergy(level,powersrc,pos,pos+v3s16(0,1,-1));
}else if (z_minus_y_minus) {
if ((pos+v3s16(0,-1,-1)) != signalsrc)
propogateEnergy(level,powersrc,pos,pos+v3s16(0,-1,-1));
if (gate_z_plus) {
if (z_plus) {
if ((pos+v3s16(0,0,1)) != signalsrc)
propogateEnergy(level,powersrc,pos,pos+v3s16(0,0,1));
}else if (z_plus_y) {
if ((pos+v3s16(0,1,1)) != signalsrc)
propogateEnergy(level,powersrc,pos,pos+v3s16(0,1,1));
}else if (z_plus_y_minus) {
if ((pos+v3s16(0,-1,1)) != signalsrc)
propogateEnergy(level,powersrc,pos,pos+v3s16(0,-1,1));
}
}
if (gate_z_minus) {
if (z_minus) {
if ((pos+v3s16(0,0,-1)) != signalsrc)
propogateEnergy(level,powersrc,pos,pos+v3s16(0,0,-1));
}else if (z_minus_y) {
if ((pos+v3s16(0,1,-1)) != signalsrc)
propogateEnergy(level,powersrc,pos,pos+v3s16(0,1,-1));
}else if (z_minus_y_minus) {
if ((pos+v3s16(0,-1,-1)) != signalsrc)
propogateEnergy(level,powersrc,pos,pos+v3s16(0,-1,-1));
}
}
return false;
}

View File

@ -337,6 +337,22 @@ v3s16 facedir_rotate(u8 facedir, v3s16 dir)
return newdir;
}
v3s16 MapNode::getRotation(v3s16 dir)
{
if (
content_features(*this).param2_type == CPT_FACEDIR_SIMPLE
|| content_features(*this).param2_type == CPT_FACEDIR_WALLMOUNT
) {
dir = facedir_rotate(param2&0x0F, dir);
}else if (
content_features(*this).param_type == CPT_FACEDIR_SIMPLE
|| content_features(*this).param_type == CPT_FACEDIR_WALLMOUNT
) {
dir = facedir_rotate(param1, dir);
}
return dir;
}
#ifndef SERVER
TileSpec MapNode::getTileFrom(v3s16 dir, TileSpec raw_spec[6])
{

View File

@ -143,7 +143,8 @@ enum ContentEnergyType {
CET_NONE,
CET_CONDUCTIVE,
CET_SOURCE,
CET_SWITCH
CET_SWITCH,
CET_GATE
};
struct MapNode;
@ -859,6 +860,7 @@ struct MapNode
else
assert(0);
}
v3s16 getRotation(v3s16 dir = v3s16(1,1,1));
// In mapnode.cpp
#ifndef SERVER

View File

@ -2610,7 +2610,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
}
SendInventory(player->peer_id);
}
}else if (content_features(n).energy_type != CET_NONE) {
}else if (content_features(n).energy_type != CET_NONE && (!wield || wield->getContent() != CONTENT_TOOLITEM_CROWBAR)) {
if (wield && wield->getContent() == CONTENT_TOOLITEM_FIRESTARTER) {
if((getPlayerPrivs(player) & PRIV_SERVER) == 0) {
s16 max_d = g_settings->getS16("borderstone_radius");