forked from oerkki/voxelands
kill rats in lava, and add farming
This commit is contained in:
parent
123c690f5a
commit
1075f4f9d3
Binary file not shown.
After Width: | Height: | Size: 732 B |
|
@ -67,6 +67,21 @@ collisionMoveResult collisionMoveSimple(Map *map, f32 pos_max_d,
|
|||
If the object lies on a walkable node, this is set to true.
|
||||
*/
|
||||
result.touching_ground = false;
|
||||
try{
|
||||
// Check for liquid, and damage = lava
|
||||
MapNode n = map->getNode(pos_i);
|
||||
if(content_features(n).liquid_type != LIQUID_NONE)
|
||||
{
|
||||
result.in_liquid = true;
|
||||
if (content_features(n).damage_per_second > 1.0)
|
||||
result.touching_lethal = true;
|
||||
}
|
||||
}
|
||||
catch(InvalidPositionException &e)
|
||||
{
|
||||
// Doing nothing here will block the object from
|
||||
// walking over map borders
|
||||
}
|
||||
|
||||
/*
|
||||
Go through every node around the object
|
||||
|
|
|
@ -27,9 +27,13 @@ class Map;
|
|||
struct collisionMoveResult
|
||||
{
|
||||
bool touching_ground;
|
||||
bool in_liquid;
|
||||
bool touching_lethal;
|
||||
|
||||
collisionMoveResult():
|
||||
touching_ground(false)
|
||||
touching_ground(false),
|
||||
in_liquid(false),
|
||||
touching_lethal(false)
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ content_t trans_table_19[20][2] = {
|
|||
{CONTENT_GRASS, 1},
|
||||
{CONTENT_TREE, 4},
|
||||
{CONTENT_LEAVES, 5},
|
||||
{CONTENT_GRASS_FOOTSTEPS, 6},
|
||||
{CONTENT_FARM_DIRT, 6},
|
||||
{CONTENT_MESE, 7},
|
||||
{CONTENT_MUD, 8},
|
||||
{CONTENT_COTTON, 10},
|
||||
|
@ -135,11 +135,9 @@ void content_mapnode_init()
|
|||
f->dug_item = std::string("MaterialItem2 ")+itos(CONTENT_MUD)+" 1";
|
||||
setDirtLikeDiggingProperties(f->digging_properties, 1.0);
|
||||
|
||||
i = CONTENT_GRASS_FOOTSTEPS;
|
||||
i = CONTENT_FARM_DIRT;
|
||||
f = &content_features(i);
|
||||
f->setAllTextures("mud.png^grass_side.png");
|
||||
f->setTexture(0, "grass_footsteps.png");
|
||||
f->setTexture(1, "mud.png");
|
||||
f->setAllTextures("dirt.png");
|
||||
f->param_type = CPT_MINERAL;
|
||||
f->is_ground_content = true;
|
||||
f->dug_item = std::string("MaterialItem2 ")+itos(CONTENT_MUD)+" 1";
|
||||
|
|
|
@ -61,7 +61,7 @@ MapNode mapnode_translate_to_internal(MapNode n_from, u8 version);
|
|||
#define CONTENT_GRASS 0x800 //1
|
||||
#define CONTENT_TREE 0x801 //4
|
||||
#define CONTENT_LEAVES 0x802 //5
|
||||
#define CONTENT_GRASS_FOOTSTEPS 0x803 //6
|
||||
#define CONTENT_FARM_DIRT 0x803 //6
|
||||
#define CONTENT_MESE 0x804 //7
|
||||
#define CONTENT_MUD 0x805 //8
|
||||
// used to be cloud
|
||||
|
|
|
@ -392,6 +392,14 @@ void RatSAO::step(float dtime, bool send_recommended)
|
|||
v3f pos_f_old = pos_f;
|
||||
moveresult = collisionMoveSimple(&m_env->getMap(), pos_max_d,
|
||||
box, dtime, pos_f, m_speed_f);
|
||||
|
||||
// basicly 'die in lava'
|
||||
if (moveresult.touching_lethal)
|
||||
{
|
||||
m_removed = true;
|
||||
return;
|
||||
}
|
||||
|
||||
m_touching_ground = moveresult.touching_ground;
|
||||
|
||||
setBasePosition(pos_f);
|
||||
|
@ -624,6 +632,14 @@ void Oerkki1SAO::step(float dtime, bool send_recommended)
|
|||
v3f pos_f_old = pos_f;
|
||||
moveresult = collisionMovePrecise(&m_env->getMap(), pos_max_d,
|
||||
box, dtime, pos_f, m_speed_f);
|
||||
|
||||
if (moveresult.touching_lethal)
|
||||
{
|
||||
// Die
|
||||
m_removed = true;
|
||||
return;
|
||||
}
|
||||
|
||||
m_touching_ground = moveresult.touching_ground;
|
||||
|
||||
// Do collision damage
|
||||
|
@ -863,6 +879,14 @@ void FireflySAO::step(float dtime, bool send_recommended)
|
|||
v3f pos_f_old = pos_f;
|
||||
moveresult = collisionMoveSimple(&m_env->getMap(), pos_max_d,
|
||||
box, dtime, pos_f, m_speed_f);
|
||||
|
||||
// basicly 'die in lava'
|
||||
if (moveresult.touching_lethal)
|
||||
{
|
||||
m_removed = true;
|
||||
return;
|
||||
}
|
||||
|
||||
m_touching_ground = moveresult.touching_ground;
|
||||
|
||||
setBasePosition(pos_f);
|
||||
|
|
|
@ -25,7 +25,6 @@ void set_default_settings(Settings *settings)
|
|||
|
||||
settings->setDefault("port", "");
|
||||
settings->setDefault("name", "");
|
||||
settings->setDefault("footprints", "false");
|
||||
|
||||
// Client stuff
|
||||
|
||||
|
|
|
@ -753,9 +753,6 @@ void ServerEnvironment::step(float dtime)
|
|||
|
||||
//TimeTaker timer("ServerEnv step");
|
||||
|
||||
// Get some settings
|
||||
bool footprints = g_settings->getBool("footprints");
|
||||
|
||||
/*
|
||||
Increment game time
|
||||
*/
|
||||
|
@ -784,26 +781,6 @@ void ServerEnvironment::step(float dtime)
|
|||
|
||||
// Move
|
||||
player->move(dtime, *m_map, 100*BS);
|
||||
|
||||
/*
|
||||
Add footsteps to grass
|
||||
*/
|
||||
if(footprints)
|
||||
{
|
||||
// Get node that is at BS/4 under player
|
||||
v3s16 bottompos = floatToInt(playerpos + v3f(0,-BS/4,0), BS);
|
||||
try{
|
||||
MapNode n = m_map->getNode(bottompos);
|
||||
if(n.getContent() == CONTENT_GRASS)
|
||||
{
|
||||
n.setContent(CONTENT_GRASS_FOOTSTEPS);
|
||||
m_map->setNode(bottompos, n);
|
||||
}
|
||||
}
|
||||
catch(InvalidPositionException &e)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1012,6 +989,82 @@ void ServerEnvironment::step(float dtime)
|
|||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
Grow stuff on farm dirt
|
||||
*/
|
||||
if(n.getContent() == CONTENT_FARM_DIRT)
|
||||
{
|
||||
if (myrand()%20 == 0)
|
||||
{
|
||||
s16 max_d = 1;
|
||||
s16 max_growth = 2;
|
||||
v3s16 temp_p = p;
|
||||
v3s16 test_p;
|
||||
content_t type = CONTENT_JUNGLEGRASS;
|
||||
MapNode testnode;
|
||||
bool found = false;
|
||||
for(s16 z=-max_d; !found && z<=max_d; z++) {
|
||||
for(s16 x=-max_d; !found && x<=max_d; x++)
|
||||
{
|
||||
test_p = temp_p + v3s16(x,0,z);
|
||||
testnode = m_map->getNodeNoEx(test_p);
|
||||
if (
|
||||
testnode.getContent() == CONTENT_WATERSOURCE
|
||||
) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
found = false;
|
||||
test_p = temp_p + v3s16(0,1,0);
|
||||
testnode = m_map->getNodeNoEx(test_p);
|
||||
switch (testnode.getContent()) {
|
||||
case CONTENT_AIR:
|
||||
for(s16 z=-max_d; !found && z<=max_d; z++) {
|
||||
for(s16 x=-max_d; !found && x<=max_d; x++)
|
||||
{
|
||||
test_p = temp_p + v3s16(x,1,z);
|
||||
testnode = m_map->getNodeNoEx(test_p);
|
||||
if (
|
||||
testnode.getContent() == CONTENT_JUNGLEGRASS
|
||||
|| testnode.getContent() == CONTENT_PAPYRUS
|
||||
) {
|
||||
found = true;
|
||||
type = testnode.getContent();
|
||||
test_p = temp_p + v3s16(0,1,0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CONTENT_PAPYRUS:
|
||||
max_growth = 5;
|
||||
type = CONTENT_PAPYRUS;
|
||||
case CONTENT_JUNGLEGRASS:
|
||||
for(s16 y=2; !found && y<=max_growth; y++)
|
||||
{
|
||||
test_p = temp_p + v3s16(0,y,0);
|
||||
testnode = m_map->getNodeNoEx(test_p);
|
||||
if (testnode.getContent() == CONTENT_AIR) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:;
|
||||
}
|
||||
if (found)
|
||||
{
|
||||
MapNode n_top = m_map->getNodeNoEx(test_p);
|
||||
n.setContent(type);
|
||||
m_map->addNodeWithEvent(test_p, n);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
Convert grass into mud if under something else than air
|
||||
*/
|
||||
|
@ -2059,7 +2112,6 @@ void ClientEnvironment::step(float dtime)
|
|||
|
||||
// Get some settings
|
||||
bool free_move = g_settings->getBool("free_move");
|
||||
bool footprints = g_settings->getBool("footprints");
|
||||
|
||||
// Get local player
|
||||
LocalPlayer *lplayer = getLocalPlayer();
|
||||
|
@ -2252,34 +2304,6 @@ void ClientEnvironment::step(float dtime)
|
|||
}
|
||||
catch(InvalidPositionException &e) {}
|
||||
player->updateLight(light);
|
||||
|
||||
/*
|
||||
Add footsteps to grass
|
||||
*/
|
||||
if(footprints)
|
||||
{
|
||||
// Get node that is at BS/4 under player
|
||||
v3s16 bottompos = floatToInt(playerpos + v3f(0,-BS/4,0), BS);
|
||||
try{
|
||||
MapNode n = m_map->getNode(bottompos);
|
||||
if(n.getContent() == CONTENT_GRASS)
|
||||
{
|
||||
n.setContent(CONTENT_GRASS_FOOTSTEPS);
|
||||
m_map->setNode(bottompos, n);
|
||||
// Update mesh on client
|
||||
if(m_map->mapType() == MAPTYPE_CLIENT)
|
||||
{
|
||||
v3s16 p_blocks = getNodeBlockPos(bottompos);
|
||||
MapBlock *b = m_map->getBlockNoCreate(p_blocks);
|
||||
//b->updateMesh(getDayNightRatio());
|
||||
b->setMeshExpired(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(InvalidPositionException &e)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
294
src/server.cpp
294
src/server.cpp
|
@ -2423,6 +2423,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
|
||||
content_t material = CONTENT_IGNORE;
|
||||
u8 mineral = MINERAL_NONE;
|
||||
const InventoryItem *wield;
|
||||
|
||||
bool cannot_remove_node = false;
|
||||
|
||||
|
@ -2499,136 +2500,205 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
return;
|
||||
}
|
||||
|
||||
actionstream<<player->getName()<<" digs "<<PP(p_under)
|
||||
<<", gets material "<<(int)material<<", mineral "
|
||||
<<(int)mineral<<std::endl;
|
||||
|
||||
/*
|
||||
Send the removal to all close-by players.
|
||||
- If other player is close, send REMOVENODE
|
||||
- Otherwise set blocks not sent
|
||||
*/
|
||||
core::list<u16> far_players;
|
||||
sendRemoveNode(p_under, peer_id, &far_players, 30);
|
||||
|
||||
/*
|
||||
Update and send inventory
|
||||
*/
|
||||
|
||||
if(g_settings->getBool("creative_mode") == false)
|
||||
wield = player->getWieldItem();
|
||||
std::string wieldname;
|
||||
bool is_farm_swap = false;
|
||||
// This is pretty much the entirety of farming
|
||||
if (
|
||||
material == CONTENT_MUD
|
||||
&& wield && wield->getName() == std::string("ToolItem")
|
||||
&& wieldname == ((ToolItem*)wield)->getToolName() &&
|
||||
(
|
||||
wieldname == std::string("SteelShovel")
|
||||
|| wieldname == std::string("STShovel")
|
||||
|| wieldname == std::string("WShovel")
|
||||
)
|
||||
)
|
||||
{
|
||||
/*
|
||||
Wear out tool
|
||||
*/
|
||||
InventoryList *mlist = player->inventory.getList("main");
|
||||
if(mlist != NULL)
|
||||
v3s16 temp_p = p_under;
|
||||
v3s16 test_p;
|
||||
MapNode testnode;
|
||||
for(s16 z=-1; !is_farm_swap && z<=1; z++) {
|
||||
for(s16 x=-1; !is_farm_swap && x<=1; x++)
|
||||
{
|
||||
InventoryItem *item = mlist->getItem(item_i);
|
||||
if(item && (std::string)item->getName() == "ToolItem")
|
||||
test_p = temp_p + v3s16(x,0,z);
|
||||
testnode = m_env.getMap().getNodeNoEx(test_p);
|
||||
if (
|
||||
testnode.getContent() == CONTENT_WATERSOURCE
|
||||
) {
|
||||
is_farm_swap = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (is_farm_swap)
|
||||
{
|
||||
MapNode n = m_env.getMap().getNode(p_under);
|
||||
n.setContent(CONTENT_FARM_DIRT);
|
||||
core::list<u16> far_players;
|
||||
sendAddNode(p_under, n, 0, &far_players, 30);
|
||||
|
||||
/*
|
||||
Add node.
|
||||
|
||||
This takes some time so it is done after the quick stuff
|
||||
*/
|
||||
core::map<v3s16, MapBlock*> modified_blocks;
|
||||
{
|
||||
MapEditEventIgnorer ign(&m_ignore_map_edit_events);
|
||||
|
||||
std::string p_name = std::string(player->getName());
|
||||
m_env.getMap().addNodeAndUpdate(p_under, n, modified_blocks, p_name);
|
||||
}
|
||||
/*
|
||||
Set blocks not sent to far players
|
||||
*/
|
||||
for(core::list<u16>::Iterator
|
||||
i = far_players.begin();
|
||||
i != far_players.end(); i++)
|
||||
{
|
||||
u16 peer_id = *i;
|
||||
RemoteClient *client = getClient(peer_id);
|
||||
if(client==NULL)
|
||||
continue;
|
||||
client->SetBlocksNotSent(modified_blocks);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
actionstream<<player->getName()<<" digs "<<PP(p_under)
|
||||
<<", gets material "<<(int)material<<", mineral "
|
||||
<<(int)mineral<<std::endl;
|
||||
|
||||
/*
|
||||
Send the removal to all close-by players.
|
||||
- If other player is close, send REMOVENODE
|
||||
- Otherwise set blocks not sent
|
||||
*/
|
||||
core::list<u16> far_players;
|
||||
sendRemoveNode(p_under, peer_id, &far_players, 30);
|
||||
|
||||
/*
|
||||
Update and send inventory
|
||||
*/
|
||||
|
||||
if(g_settings->getBool("creative_mode") == false)
|
||||
{
|
||||
/*
|
||||
Wear out tool
|
||||
*/
|
||||
InventoryList *mlist = player->inventory.getList("main");
|
||||
if(mlist != NULL)
|
||||
{
|
||||
ToolItem *titem = (ToolItem*)item;
|
||||
std::string toolname = titem->getToolName();
|
||||
|
||||
// Get digging properties for material and tool
|
||||
DiggingProperties prop =
|
||||
getDiggingProperties(material, toolname);
|
||||
|
||||
if(prop.diggable == false)
|
||||
InventoryItem *item = mlist->getItem(item_i);
|
||||
if(item && (std::string)item->getName() == "ToolItem")
|
||||
{
|
||||
infostream<<"Server: WARNING: Player digged"
|
||||
<<" with impossible material + tool"
|
||||
<<" combination"<<std::endl;
|
||||
ToolItem *titem = (ToolItem*)item;
|
||||
std::string toolname = titem->getToolName();
|
||||
|
||||
// Get digging properties for material and tool
|
||||
DiggingProperties prop =
|
||||
getDiggingProperties(material, toolname);
|
||||
|
||||
if(prop.diggable == false)
|
||||
{
|
||||
infostream<<"Server: WARNING: Player digged"
|
||||
<<" with impossible material + tool"
|
||||
<<" combination"<<std::endl;
|
||||
}
|
||||
|
||||
bool weared_out = titem->addWear(prop.wear);
|
||||
|
||||
if(weared_out)
|
||||
{
|
||||
mlist->deleteItem(item_i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool weared_out = titem->addWear(prop.wear);
|
||||
/*
|
||||
Add dug item to inventory
|
||||
*/
|
||||
|
||||
if(weared_out)
|
||||
InventoryItem *item = NULL;
|
||||
|
||||
if(mineral != MINERAL_NONE)
|
||||
item = getDiggedMineralItem(mineral);
|
||||
|
||||
// If not mineral
|
||||
if(item == NULL)
|
||||
{
|
||||
std::string &dug_s = content_features(material).dug_item;
|
||||
if(dug_s != "")
|
||||
{
|
||||
mlist->deleteItem(item_i);
|
||||
std::istringstream is(dug_s, std::ios::binary);
|
||||
item = InventoryItem::deSerialize(is);
|
||||
}
|
||||
}
|
||||
|
||||
if(item != NULL)
|
||||
{
|
||||
// Add a item to inventory
|
||||
player->inventory.addItem("main", item);
|
||||
|
||||
// Send inventory
|
||||
UpdateCrafting(player->peer_id);
|
||||
SendInventory(player->peer_id);
|
||||
}
|
||||
|
||||
item = NULL;
|
||||
|
||||
if(mineral != MINERAL_NONE)
|
||||
item = getDiggedMineralItem(mineral);
|
||||
|
||||
// If not mineral
|
||||
if(item == NULL)
|
||||
{
|
||||
std::string &extra_dug_s = content_features(material).extra_dug_item;
|
||||
s32 extra_rarity = content_features(material).extra_dug_item_rarity;
|
||||
if(extra_dug_s != "" && extra_rarity != 0
|
||||
&& myrand() % extra_rarity == 0)
|
||||
{
|
||||
std::istringstream is(extra_dug_s, std::ios::binary);
|
||||
item = InventoryItem::deSerialize(is);
|
||||
}
|
||||
}
|
||||
|
||||
if(item != NULL)
|
||||
{
|
||||
// Add a item to inventory
|
||||
player->inventory.addItem("main", item);
|
||||
|
||||
// Send inventory
|
||||
UpdateCrafting(player->peer_id);
|
||||
SendInventory(player->peer_id);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Add dug item to inventory
|
||||
Remove the node
|
||||
(this takes some time so it is done after the quick stuff)
|
||||
*/
|
||||
|
||||
InventoryItem *item = NULL;
|
||||
|
||||
if(mineral != MINERAL_NONE)
|
||||
item = getDiggedMineralItem(mineral);
|
||||
|
||||
// If not mineral
|
||||
if(item == NULL)
|
||||
{
|
||||
std::string &dug_s = content_features(material).dug_item;
|
||||
if(dug_s != "")
|
||||
{
|
||||
std::istringstream is(dug_s, std::ios::binary);
|
||||
item = InventoryItem::deSerialize(is);
|
||||
}
|
||||
}
|
||||
MapEditEventIgnorer ign(&m_ignore_map_edit_events);
|
||||
|
||||
if(item != NULL)
|
||||
m_env.getMap().removeNodeAndUpdate(p_under, modified_blocks);
|
||||
}
|
||||
/*
|
||||
Set blocks not sent to far players
|
||||
*/
|
||||
for(core::list<u16>::Iterator
|
||||
i = far_players.begin();
|
||||
i != far_players.end(); i++)
|
||||
{
|
||||
// Add a item to inventory
|
||||
player->inventory.addItem("main", item);
|
||||
|
||||
// Send inventory
|
||||
UpdateCrafting(player->peer_id);
|
||||
SendInventory(player->peer_id);
|
||||
u16 peer_id = *i;
|
||||
RemoteClient *client = getClient(peer_id);
|
||||
if(client==NULL)
|
||||
continue;
|
||||
client->SetBlocksNotSent(modified_blocks);
|
||||
}
|
||||
|
||||
item = NULL;
|
||||
|
||||
if(mineral != MINERAL_NONE)
|
||||
item = getDiggedMineralItem(mineral);
|
||||
|
||||
// If not mineral
|
||||
if(item == NULL)
|
||||
{
|
||||
std::string &extra_dug_s = content_features(material).extra_dug_item;
|
||||
s32 extra_rarity = content_features(material).extra_dug_item_rarity;
|
||||
if(extra_dug_s != "" && extra_rarity != 0
|
||||
&& myrand() % extra_rarity == 0)
|
||||
{
|
||||
std::istringstream is(extra_dug_s, std::ios::binary);
|
||||
item = InventoryItem::deSerialize(is);
|
||||
}
|
||||
}
|
||||
|
||||
if(item != NULL)
|
||||
{
|
||||
// Add a item to inventory
|
||||
player->inventory.addItem("main", item);
|
||||
|
||||
// Send inventory
|
||||
UpdateCrafting(player->peer_id);
|
||||
SendInventory(player->peer_id);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Remove the node
|
||||
(this takes some time so it is done after the quick stuff)
|
||||
*/
|
||||
{
|
||||
MapEditEventIgnorer ign(&m_ignore_map_edit_events);
|
||||
|
||||
m_env.getMap().removeNodeAndUpdate(p_under, modified_blocks);
|
||||
}
|
||||
/*
|
||||
Set blocks not sent to far players
|
||||
*/
|
||||
for(core::list<u16>::Iterator
|
||||
i = far_players.begin();
|
||||
i != far_players.end(); i++)
|
||||
{
|
||||
u16 peer_id = *i;
|
||||
RemoteClient *client = getClient(peer_id);
|
||||
if(client==NULL)
|
||||
continue;
|
||||
client->SetBlocksNotSent(modified_blocks);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue