kill rats in lava, and add farming

This commit is contained in:
darkrose 2013-05-11 20:32:41 +10:00
parent 123c690f5a
commit 1075f4f9d3
9 changed files with 306 additions and 172 deletions

BIN
data/dirt.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 732 B

View File

@ -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

View File

@ -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)
{}
};

View File

@ -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";

View File

@ -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

View File

@ -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);

View File

@ -25,7 +25,6 @@ void set_default_settings(Settings *settings)
settings->setDefault("port", "");
settings->setDefault("name", "");
settings->setDefault("footprints", "false");
// Client stuff

View File

@ -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)
{
}
}
}
/*

View File

@ -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);
}
}