Block.cpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. #include "Block.h"
  2. #include "Inventory.h"
  3. #include "NoBlock.h"
  4. #include "Game.h"
  5. #include "BlockChangedUpdate.h"
  6. #include "PlaceBlockUpdate.h"
  7. #include "BlockRemovedUpdate.h"
  8. Block::Block( const BlockType* zType, ItemType* zTool, Framework::Vec3<int> pos, bool hasInventory )
  9. : Inventory( pos, hasInventory )
  10. {
  11. transparent = false;
  12. passable = false;
  13. hp = 1;
  14. maxHP = 1;
  15. hardness = 1;
  16. this->zType = zType;
  17. this->zTool = zTool;
  18. speedModifier = 1;
  19. ticksLeftCounter = 0;
  20. wasTicked = 0;
  21. onTickCalled = 0;
  22. minTickTimeout = -1;
  23. maxTickTimeout = -1;
  24. tickSource = 0;
  25. currentTickTimeout = 0;
  26. dimensionId = 0;
  27. interactable = 0;
  28. memset( zNeighbours, 0, sizeof( Block* ) * 6 );
  29. }
  30. Block::~Block()
  31. {}
  32. void Block::tick( TickQueue* zQueue )
  33. {
  34. if( wasTicked )
  35. return;
  36. wasTicked = 1;
  37. ticksLeftCounter++;
  38. if( minTickTimeout >= 0 )
  39. {
  40. if( currentTickTimeout < ticksLeftCounter )
  41. {
  42. onTickCalled = 1;
  43. bool blocked = 0;
  44. bool result = onTick( zQueue, ticksLeftCounter, blocked );
  45. if( blocked )
  46. {
  47. wasTicked = 0;
  48. ticksLeftCounter--;
  49. onTickCalled = 0;
  50. return;
  51. }
  52. if( result )
  53. currentTickTimeout = MAX( MIN( currentTickTimeout - 1, maxTickTimeout ), MAX( minTickTimeout, 0 ) );
  54. else
  55. currentTickTimeout = MAX( MIN( currentTickTimeout + 1, maxTickTimeout ), MAX( minTickTimeout, 0 ) );
  56. ticksLeftCounter = 0;
  57. }
  58. }
  59. }
  60. void Block::postTick()
  61. {
  62. wasTicked = 0;
  63. if( onTickCalled )
  64. {
  65. onPostTick();
  66. onTickCalled = 0;
  67. }
  68. }
  69. void Block::setNeighbour( Direction dir, Framework::Either<Block*, int> neighbour )
  70. {
  71. if( neighbour.isA() )
  72. setNeighbourBlock( dir, neighbour );
  73. else
  74. {
  75. setNeighbourBlock( dir, 0 );
  76. setNeighbourType( dir, neighbour );
  77. }
  78. }
  79. void Block::setNeighbourBlock( Direction dir, Block* zN )
  80. {
  81. if( zN )
  82. setNeighbourType( dir, zN->zBlockType()->getId() );
  83. zNeighbours[ getDirectionIndex( dir ) ] = zN;
  84. }
  85. void Block::setNeighbourType( Direction dir, int type )
  86. {
  87. neighbourTypes[ getDirectionIndex( dir ) ] = type;
  88. }
  89. void Block::setDimensionId( int id )
  90. {
  91. dimensionId = id;
  92. }
  93. void api( Framework::StreamReader* zRequest, NetworkResponse* zResponse )
  94. {
  95. // TODO: answer api requests
  96. }
  97. bool Block::isTickSource() const
  98. {
  99. return tickSource;
  100. }
  101. const BlockType* Block::zBlockType() const
  102. {
  103. return zType;
  104. }
  105. bool Block::isTransparent() const
  106. {
  107. return transparent;
  108. }
  109. bool Block::isPassable() const
  110. {
  111. return passable;
  112. }
  113. bool Block::isInteractable() const
  114. {
  115. return interactable;
  116. }
  117. float Block::getHP() const
  118. {
  119. return hp;
  120. }
  121. float Block::getMaxHP() const
  122. {
  123. return maxHP;
  124. }
  125. float Block::getHardness() const
  126. {
  127. return hardness;
  128. }
  129. ItemType* Block::zEffectiveTool() const
  130. {
  131. return zTool;
  132. }
  133. float Block::getSpeedModifier() const
  134. {
  135. return speedModifier;
  136. }
  137. const Framework::Vec3<int> Block::getPos() const
  138. {
  139. return (Framework::Vec3<int>)location;
  140. }
  141. int Block::getDimensionId() const
  142. {
  143. return dimensionId;
  144. }
  145. bool Block::isVisible() const
  146. {
  147. if( passable || transparent )
  148. return 1;
  149. for( int i = 0; i < 6; i++ )
  150. {
  151. const Block* neighbour = CONST_BLOCK( zNeighbours[ i ], neighbourTypes[ i ] );
  152. if( neighbour->isPassable() || neighbour->isTransparent() )
  153. return 1;
  154. }
  155. return 0;
  156. }
  157. void Block::setHP( float hp )
  158. {
  159. bool isDead = this->hp == 0.f;
  160. this->hp = MAX( 0.f, hp );
  161. if( !isDead && this->hp == 0.f )
  162. {
  163. for( int i = 0; i < 6; i++ )
  164. {
  165. if( neighbourTypes[ i ] == NoBlockBlockType::ID )
  166. {
  167. Framework::Vec3<int> pos = getPos() + getDirection( getDirectionFromIndex( i ) );
  168. Game::INSTANCE->requestWorldUpdate( new PlaceBlockUpdate( Game::INSTANCE->zGenerator()->generateSingleBlock( pos, dimensionId ), pos, dimensionId ) );
  169. }
  170. }
  171. Game::INSTANCE->requestWorldUpdate( new BlockRemovedUpdate( getPos(), dimensionId ) );
  172. // TODO: generate item stacks and drop them
  173. }
  174. else
  175. requestTransmission();
  176. }
  177. void Block::onAfterTransmission()
  178. {
  179. transmissionRequested = 0;
  180. }
  181. void Block::requestTransmission()
  182. {
  183. if( !transmissionRequested )
  184. {
  185. transmissionRequested = 1;
  186. Game::INSTANCE->requestWorldUpdate( new BlockChangedUpdate( getPos(), getDimensionId() ) );
  187. }
  188. }
  189. BasicBlockItem::BasicBlockItem( const ItemType* zType, const BlockType* zPlacedBlockType, const char* name )
  190. : Item( zType, name )
  191. {
  192. placeable = 1;
  193. zBlockType = zPlacedBlockType;
  194. }
  195. bool BasicBlockItem::canBeStackedWith( Item* zItem ) const
  196. {
  197. BasicBlockItem* item = dynamic_cast<BasicBlockItem*>(zItem);
  198. if( item )
  199. {
  200. return Item::canBeStackedWith( zItem ) &&
  201. transparent == item->transparent &&
  202. passable == item->passable &&
  203. hp == item->hp &&
  204. maxHP == item->maxHP &&
  205. hardness == item->hardness &&
  206. toolId == item->toolId &&
  207. speedModifier == item->speedModifier;
  208. }
  209. return 0;
  210. }
  211. BasicBlockItemType::BasicBlockItemType( int id, ItemSkillLevelUpRule* levelUpRule, const ItemType* zBrokenType )
  212. : ItemType( id, levelUpRule, zBrokenType )
  213. {}
  214. void BasicBlockItemType::loadSuperItem( Item* zItem, Framework::StreamReader* zReader ) const
  215. {
  216. ItemType::loadSuperItem( zItem, zReader );
  217. BasicBlockItem* item = dynamic_cast<BasicBlockItem*>(zItem);
  218. if( !item )
  219. throw "BasicBlockItemType::loadSuperItem was called with an invalid item";
  220. zReader->lese( (char*)&item->transparent, 1 );
  221. zReader->lese( (char*)&item->passable, 1 );
  222. zReader->lese( (char*)&item->hp, 4 );
  223. zReader->lese( (char*)&item->maxHP, 4 );
  224. zReader->lese( (char*)&item->hardness, 4 );
  225. zReader->lese( (char*)&item->toolId, 4 );
  226. zReader->lese( (char*)&item->speedModifier, 4 );
  227. }
  228. void BasicBlockItemType::saveSuperItem( const Item* zItem, Framework::StreamWriter* zWriter ) const
  229. {
  230. ItemType::saveSuperItem( zItem, zWriter );
  231. const BasicBlockItem* item = dynamic_cast<const BasicBlockItem*>(zItem);
  232. if( !item )
  233. throw "BasicBlockItemType::saveSuperItem was called with an invalid item";
  234. zWriter->schreibe( (char*)&item->transparent, 1 );
  235. zWriter->schreibe( (char*)&item->passable, 1 );
  236. zWriter->schreibe( (char*)&item->hp, 4 );
  237. zWriter->schreibe( (char*)&item->maxHP, 4 );
  238. zWriter->schreibe( (char*)&item->hardness, 4 );
  239. zWriter->schreibe( (char*)&item->toolId, 4 );
  240. zWriter->schreibe( (char*)&item->speedModifier, 4 );
  241. }
  242. void BasicBlockItemType::initializeItem( BasicBlockItem* zItem, bool transparent, bool passable, float hp, float maxHP, float hardness, int toolId, float speedModifier ) const
  243. {
  244. zItem->transparent = transparent;
  245. zItem->passable = passable;
  246. zItem->hp = hp;
  247. zItem->maxHP = maxHP;
  248. zItem->hardness = hardness;
  249. zItem->toolId = toolId;
  250. zItem->speedModifier = speedModifier;
  251. }