Mineserver Community

Mineserver => Development => Topic started by: thegk01 on May 25, 2011, 02:40:42 pm



Title: TNT!
Post by: thegk01 on May 25, 2011, 02:40:42 pm
Hey,

Over the last week(s), I have programmed the TNT block. There are still much things that must be programmed/improved, but I think I have programmed it up to a point where you can use it.  :)

Create src/blocks/tnt.h
Code:
#pragma once

#include "basic.h"

class User;

class BlockTNT : public BlockBasic
{
public:
bool affectedBlock(int block);
void onStartedDigging(User* user, int8_t status, int32_t x, int8_t y, int map, int32_t z, int8_t direction);
bool onPlace(User* user, int16_t newblock, int32_t x, int8_t y, int32_t z, int map, int8_t direction);
bool onInteract(User* user, int32_t x, int8_t y, int32_t z, int map);
void rb(int32_t x,int8_t y,int8_t z,int map,User* user); // rb=Remove Block
void explode(User* user, int32_t x, int8_t y, int8_t z, int map);
};

Create src/blocks/tnt.cpp
Code:
#include "default.h"
#include "../mineserver.h"
#include "../map.h"
#include "../constants.h"
#include "../logger.h"

#include "tnt.h"

uint8_t pickint;

void BlockTNT::rb(int32_t x,int8_t y,int8_t z,int map, User* user)
{
uint8_t block, meta;
Mineserver::get()->map(map)->getBlock(x,y,z,&block,&meta);

// Blocks which have no pickups (or they are only accessable via /give )
if (block == 7 || block == 8 || block == 9 || block == 10 || block == 11 || block == 18 ||
block == 30 || block == 47 || block == 49 || block == 51 || block == 52 || block == 59 ||
block == 68 || block == 79 || block == 83 || block == 90 || block == 92 || block == 94) {
block = 0;
}

// Blocks which drop other things as the block item, (Coal, Diamond, ...)
if (block == 1) {
block=4;
} else if (block == 2) {
block=3;
}  else if (block == 16) {
block=263;
} else if (block == 21) {
block=351;
meta=4;
} else if (block == 26) {
block=355;
} else if (block == 53) {
block=5;
} else if (block == 55) {
block=331;
} else if (block == 56) {
block=264;
} else if (block == 59) {
block=295;
} else if (block == 60) {
block=3;
} else if (block == 62) {
block=61;
} else if (block == 68) {
block=63;
} else if (block == 73) {
block=331;
} else if (block == 74) {
block=331;
} else if (block == 76) {
block=75;
} else if (block == 78) {
block=332;
} else if (block == 82) {
block=337;
} else if (block == 83) {
block=338;
} else if (block == 89) {
block=348;
} else if (block == 92) {
block=354;
} else if (block == 95) /* Easter egg chest? */ {
block=54;
}


// Undestroyable blocks
if (block == 0 || block == 7 || block == 49) {
return;
} else {
Mineserver::get()->map(map)->setBlock(x,y,z,0,0);
Mineserver::get()->map(map)->sendBlockChange(x,y,z,0,0);
}

// Pickup Spawn Area
// The integer "pickint" is used to spawn 1/5 of the blocks, otherwise there would be too much pickups!
if(pickint == 5) {

if(block != 0) {
Mineserver::get()->map(map)->createPickupSpawn(x,y,z,block,meta,0,user);
}
pickint=0;
} else {
pickint++;
}

}

void BlockTNT::explode(User* user,int32_t x,int8_t y,int8_t z,int map)
{
pickint = 0;
if (rand() % 9 == 5) {
// There is a chance of 1/10 that the TNT block does'nt explode;
// this is more realistic ;)
Mineserver::get()->map(map)->setBlock(x,y,z,0,0);
Mineserver::get()->map(map)->sendBlockChange(x,y,z,0,0);
// But we want to be fair; let's create a pickup for the TNT block =)
Mineserver::get()->map(map)->createPickupSpawn(x,y,z,46,1,0,user);
} else {
int number; // Counter in the for(...){...} loops.
// Layer Y-4

//rb(x,y-4,z,map,user);

// Layer Y-3

rb(x-1,y-3,z+1,map,user);
rb(x,y-3,z+1,map,user);
rb(x+1,y-3,z+1,map,user);
rb(x-1,y-3,z,map,user);
rb(x,y-3,z,map,user);
rb(x+1,y-3,z,map,user);
rb(x-1,y-3,z-1,map,user);
rb(x,y-3,z-1,map,user);
rb(x+1,y-3,z-1,map,user);

// Layer Y-2

for (number=-2; number<=2; number++) {
rb(x+number,y-2,z+1,map,user);
rb(x+number,y-2,z,map,user);
rb(x+number,y-2,z-1,map,user);
}

rb(x-1,y-2,z+2,map,user);
rb(x,y-2,z+2,map,user);
rb(x+1,y-2,z+2,map,user);

rb(x-1,y-2,z-2,map,user);
rb(x,y-2,z-2,map,user);
rb(x+1,y-2,z-2,map,user);

// Layer Y-1

rb(x-3,y-1,z+2,map,user);
rb(x-3,y-1,z+1,map,user);
rb(x-3,y-1,z,map,user);
rb(x-3,y-1,z-1,map,user);
rb(x-3,y-1,z-2,map,user);

for (number=-2; number<=2; number++) {
rb(x-number,y-1,z+3,map,user);
rb(x-number,y-1,z+2,map,user);
rb(x-number,y-1,z+1,map,user);
rb(x-number,y-1,z,map,user);
rb(x-number,y-1,z-1,map,user);
rb(x-number,y-1,z-2,map,user);
rb(x-number,y-1,z-3,map,user);
}

rb(x+3,y-1,z+2,map,user);
rb(x+3,y-1,z+1,map,user);
rb(x+3,y-1,z,map,user);
rb(x+3,y-1,z-1,map,user);
rb(x+3,y-1,z-2,map,user);


// Layer Y {+,-} 0, same as TNT block

//rb(x-4,y,z,map,user);

rb(x-3,y,z+2,map,user);
rb(x-3,y,z+1,map,user);
rb(x-3,y,z,map,user);
rb(x-3,y,z-1,map,user);
rb(x-3,y,z-2,map,user);

for (number=-2; number<=2; number++) {
rb(x-number,y,z+3,map,user);
rb(x-number,y,z+2,map,user);
rb(x-number,y,z+1,map,user);
rb(x-number,y,z,map,user);
rb(x-number,y,z-1,map,user);
rb(x-number,y,z-2,map,user);
rb(x-number,y,z-3,map,user);
}

rb(x+3,y,z+2,map,user);
rb(x+3,y,z+1,map,user);
rb(x+3,y,z,map,user);
rb(x+3,y,z-1,map,user);
rb(x+3,y,z-2,map,user);

//rb(x+4,y,z,map,user);

//rb(x,y,z+4,map,user);
//rb(x,y,z-4,map,user);

// Layer Y+1

rb(x-3,y+1,z+2,map,user);
rb(x-3,y+1,z+1,map,user);
rb(x-3,y+1,z,map,user);
rb(x-3,y+1,z-1,map,user);
rb(x-3,y+1,z-2,map,user);

for (number=-2; number<=2; number++) {
rb(x-number,y+1,z+3,map,user);
rb(x-number,y+1,z+2,map,user);
rb(x-number,y+1,z+1,map,user);
rb(x-number,y+1,z,map,user);
rb(x-number,y+1,z-1,map,user);
rb(x-number,y+1,z-2,map,user);
rb(x-number,y+1,z-3,map,user);
}

rb(x+3,y+1,z+2,map,user);
rb(x+3,y+1,z+1,map,user);
rb(x+3,y+1,z,map,user);
rb(x+3,y+1,z-1,map,user);
rb(x+3,y+1,z-2,map,user);

// Layer Y+2

for (number=-2; number<=2; number++) {
rb(x+number,y+2,z+1,map,user);
rb(x+number,y+2,z,map,user);
rb(x+number,y+2,z-1,map,user);
}

rb(x-1,y+2,z+2,map,user);
rb(x,y+2,z+2,map,user);
rb(x+1,y+2,z+2,map,user);

rb(x-1,y+2,z-2,map,user);
rb(x,y+2,z-2,map,user);
rb(x+1,y+2,z-2,map,user);

// Layer Y+3

rb(x-1,y+3,z+1,map,user);
rb(x,y+3,z+1,map,user);
rb(x+1,y+3,z+1,map,user);
rb(x-1,y+3,z,map,user);
rb(x,y+3,z,map,user);
rb(x+1,y+3,z,map,user);
rb(x-1,y+3,z-1,map,user);
rb(x,y+3,z-1,map,user);
rb(x+1,y+3,z-1,map,user);

// Layer Y+4

//rb(x,y+4,z,map,user);

LOG2(INFO,"TNT Block exploded!");
}
}

bool BlockTNT::affectedBlock(int block)
{
switch (block)
{
case BLOCK_TNT:
return true;
}
return false;
}

bool BlockTNT::onPlace(User* user, int16_t newblock, int32_t x, int8_t y, int32_t z, int map, int8_t direction)
{
uint8_t oldblock;
uint8_t oldmeta;

if (!Mineserver::get()->map(map)->getBlock(x, y, z, &oldblock, &oldmeta))
{
revertBlock(user, x, y, z, map);
return true;
}
/* Check block below allows blocks placed on top */
if (!this->isBlockStackable(oldblock))
{
revertBlock(user, x, y, z, map);
return true;
}

/* move the x,y,z coords dependent upon placement direction */
if (!this->translateDirection(&x, &y, &z, map, direction))
{
revertBlock(user, x, y, z, map);
return true;
}

if (this->isUserOnBlock(x, y, z, map))
{
revertBlock(user, x, y, z, map);
return true;
}

if (!this->isBlockEmpty(x, y, z, map))
{
revertBlock(user, x, y, z, map);
return true;
}

return false;
}

void BlockTNT::onStartedDigging(User* user, int8_t status, int32_t x, int8_t y, int32_t z, int map, int8_t direction)
{
uint8_t block, metadata;
explode(user,x,y,z,map);

}

bool BlockTNT::onInteract(User* user, int32_t x, int8_t y, int32_t z, int map)
{
uint8_t block, metadata;
return true;
}

Change src/packets.cpp on line 617:
Code:
[...]
(block == BLOCK_SNOW || block == BLOCK_REED || block == BLOCK_TORCH || block == BLOCK_TNT

[...]

to

Code:
[...]
(block == BLOCK_SNOW || block == BLOCK_REED || block == BLOCK_TORCH
[...]

Add this line to src/plugin.cpp on line 66:
Code:
#include "blocks/tnt.h"

Add these lines to src/plugin.cpp on line 123:
Code:
BlockTNT* tntblock = new BlockTNT();
BlockCB.push_back(tntblock);

Change the CMakeLists.txt like this to include the new files (line 124):
Code:
src/blocks/wood.cpp

to

Code:
src/blocks/wood.cpp
src/blocks/tnt.cpp



This should be all you need to do if you wanna have TNT!
I added a few comments to tnt.cpp so you can understand how it works. If not, feel free to ask me! :)
Please send any bugs or suggestions to me! This would be very helpful.

thegk01


Title: Re: TNT!
Post by: MechWarrior001 on June 01, 2011, 11:37:23 pm
Here's some warnings I got while compiling:

Code:
\src\blocks\tnt.cpp(29): warning C4305: '=' : truncation from 'int' to 'uint8_t'
\src\blocks\tnt.cpp(29): warning C4309: '=' : truncation of constant value
\src\blocks\tnt.cpp(31): warning C4305: '=' : truncation from 'int' to 'uint8_t'
\src\blocks\tnt.cpp(31): warning C4309: '=' : truncation of constant value
\src\blocks\tnt.cpp(34): warning C4305: '=' : truncation from 'int' to 'uint8_t'
\src\blocks\tnt.cpp(34): warning C4309: '=' : truncation of constant value
\src\blocks\tnt.cpp(38): warning C4305: '=' : truncation from 'int' to 'uint8_t'
\src\blocks\tnt.cpp(38): warning C4309: '=' : truncation of constant value
\src\blocks\tnt.cpp(40): warning C4305: '=' : truncation from 'int' to 'uint8_t'
\src\blocks\tnt.cpp(40): warning C4309: '=' : truncation of constant value
\src\blocks\tnt.cpp(42): warning C4305: '=' : truncation from 'int' to 'uint8_t'
\src\blocks\tnt.cpp(42): warning C4309: '=' : truncation of constant value
\src\blocks\tnt.cpp(50): warning C4305: '=' : truncation from 'int' to 'uint8_t'
\src\blocks\tnt.cpp(50): warning C4309: '=' : truncation of constant value
\src\blocks\tnt.cpp(52): warning C4305: '=' : truncation from 'int' to 'uint8_t'
\src\blocks\tnt.cpp(52): warning C4309: '=' : truncation of constant value
\src\blocks\tnt.cpp(56): warning C4305: '=' : truncation from 'int' to 'uint8_t'
\src\blocks\tnt.cpp(56): warning C4309: '=' : truncation of constant value
\src\blocks\tnt.cpp(58): warning C4305: '=' : truncation from 'int' to 'uint8_t'
\src\blocks\tnt.cpp(58): warning C4309: '=' : truncation of constant value
\src\blocks\tnt.cpp(60): warning C4305: '=' : truncation from 'int' to 'uint8_t'
\src\blocks\tnt.cpp(60): warning C4309: '=' : truncation of constant value
\src\blocks\tnt.cpp(62): warning C4305: '=' : truncation from 'int' to 'uint8_t'
\src\blocks\tnt.cpp(62): warning C4309: '=' : truncation of constant value
\src\blocks\tnt.cpp(64): warning C4305: '=' : truncation from 'int' to 'uint8_t'
\src\blocks\tnt.cpp(64): warning C4309: '=' : truncation of constant value
\src\blocks\tnt.cpp(303): warning C4101: 'metadata' : unreferenced local variable
\src\blocks\tnt.cpp(303): warning C4101: 'block' : unreferenced local variable
\src\blocks\tnt.cpp(310): warning C4101: 'metadata' : unreferenced local variable
\src\blocks\tnt.cpp(310): warning C4101: 'block' : unreferenced local variable


Title: Re: TNT!
Post by: thegk01 on June 02, 2011, 10:46:07 am
Yes, I got this warning too. It is caused by the if loops which are used to spawn other items than the block item, e.g. a destroyed redstone block will not drop a redstone block, but redstone dust.

If you know how to fix this error, help me ;) As far as I know, I need to convert the integers to uint8_t, but how can I fill a variable with uint8_t instead of int?

But, even if I think that this errors should be fixed, the code works like it should; every block which should not drop itself, but an item, does this.

thegk01


Title: Re: TNT!
Post by: MechWarrior001 on June 02, 2011, 09:35:22 pm
Perhaps it spits out those warnings because the code isn't ISO/IEC 14882:2003 compliant? I'm not sure but that's the only reason I can think of.


Title: Re: TNT!
Post by: deoxxa on June 11, 2011, 04:53:02 pm
Oh hey, this is cool! I'll take a closer look at those warnings and see if I can't get them cleared up. If I can get it working, I assume it's cool if I merge it into the mainline codebase (with attribution, of course)?


Title: Re: TNT!
Post by: thegk01 on June 11, 2011, 06:30:16 pm
Oh, yes, sure!
I think there are much functions which must be added, but I am glad that I brought the project a little step further ;)

-- thegk01


Title: Re: TNT!
Post by: deoxxa on June 12, 2011, 02:10:48 am
Excellent! I've put it in a separate branch for now, since the warnings are still there, but it should be somewhat operational right now.