Chest.cpp 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. #include "Chest.h"
  2. #include <TextFeld.h>
  3. #include "Game.h"
  4. Chest::Chest(int typeId, Framework::Vec3<int> pos, int dimensionId)
  5. : BasicBlock(typeId, pos, dimensionId, 1),
  6. open(0),
  7. userEntityId(0)
  8. {
  9. for (int i = 0; i < 30; i++)
  10. {
  11. ItemSlot* slot = new ItemSlot(
  12. "Inventory", 50, i, i, ANY_DIRECTION, ANY_DIRECTION, 0);
  13. addSlot(slot);
  14. }
  15. }
  16. void Chest::onDestroy()
  17. {
  18. for (ItemSlot* slot : *this)
  19. {
  20. if (!slot->isEmpty())
  21. {
  22. Game::INSTANCE->spawnItem(location + Vec3<float>(0.5f, 0.5f, 0.5f),
  23. getDimensionId(),
  24. slot->takeItemsOut(slot->getNumberOfItems(), NO_DIRECTION));
  25. }
  26. }
  27. BasicBlock::onDestroy();
  28. }
  29. void Chest::onDialogClosed(Framework::Text dialogId)
  30. {
  31. if (dialogId.istGleich(getDialogId()))
  32. {
  33. open = 0;
  34. userEntityId = 0;
  35. NetworkMessage* msg = new NetworkMessage();
  36. msg->animateBlockBone(getDimensionId(),
  37. Game::getChunkCenter(getPos().x, getPos().y),
  38. Chunk::index(Dimension::chunkCoordinates(getPos())),
  39. 1,
  40. 1.0,
  41. Vec3<float>(0.5f, 0.f, 0.45f),
  42. Vec3<float>(0.0f, 0.f, 0.f)); // close the chest over one second
  43. broadcastMessage(msg);
  44. }
  45. }
  46. Framework::Text Chest::getDialogId() const
  47. {
  48. Text dialogId = "chest_inventory_";
  49. dialogId.append() << getDimensionId() << "," << getPos().x << ","
  50. << getPos().y << "," << getPos().z;
  51. return dialogId;
  52. }
  53. bool Chest::onTick(TickQueue* zQueue, int numTicks, bool& blocked)
  54. {
  55. if (open)
  56. {
  57. if (!Game::INSTANCE->zEntity(userEntityId))
  58. {
  59. onDialogClosed(getDialogId());
  60. }
  61. }
  62. return open;
  63. }
  64. bool Chest::interact(Item* zItem, Entity* zActor)
  65. {
  66. lock();
  67. if (open)
  68. {
  69. if (!Game::INSTANCE->zEntity(userEntityId)) open = 0;
  70. }
  71. if (!open)
  72. {
  73. userEntityId = zActor->getId();
  74. open = 1;
  75. Text uiml = "";
  76. uiml.append()
  77. << "<dialog id=\"" << getDialogId()
  78. << "\" title=\"Chest\" "
  79. "notifyOnClose=\""
  80. << getDimensionId() << "," << getPos().x << "," << getPos().y << ","
  81. << getPos().z
  82. << "\" "
  83. "width=\"610\" "
  84. "height=\"480\">"
  85. << "<inventory id=\"chest_inventory\" margin-bottom=\"18\" "
  86. "align-bottom=\"player_label\" align-left=\"start\" "
  87. "margin-left=\"9\" width=\"592\" height=\"172\" rowSize=\"10\" "
  88. "numSlots=\"30\" slotNameFilter=\"\" target=\""
  89. << getDimensionId() << "," << getPos().x << "," << getPos().y << ","
  90. << getPos().z << "\"/>"
  91. << "<text id=\"player_label\" width=\"100%\" height=\"auto\" "
  92. "style=\""
  93. << std::uppercase << std::hex
  94. << (TextFeld::Style::Text | TextFeld::Style::Center) << std::dec
  95. << std::nouppercase
  96. << "\" margin-bottom=\"9\" "
  97. "align-bottom=\"player_inventory\">Player "
  98. "Inventory</text>"
  99. << "<inventory id=\"player_inventory\" margin-bottom=\"18\" "
  100. "align-bottom=\"item_bar\" align-left=\"start\" "
  101. "margin-left=\"9\" width=\"592\" height=\"172\" rowSize=\"10\" "
  102. "numSlots=\"30\" slotNameFilter=\"Inventory\" target=\""
  103. << zActor->getId() << "\"/>"
  104. << "<inventory id=\"item_bar\" margin-bottom=\"9\" "
  105. "align-bottom=\"end\" align-left=\"start\" margin-left=\"9\" "
  106. "width=\"592\" height=\"52\" rowSize=\"10\" numSlots=\"10\" "
  107. "slotNameFilter=\"ItemBar\" target=\""
  108. << zActor->getId() << "\"/>"
  109. << "</dialog>";
  110. Game::INSTANCE->zUIController()->addDialog(new UIDialog(
  111. getDialogId(), zActor->getId(), new Framework::XML::Element(uiml)));
  112. NetworkMessage* msg = new NetworkMessage();
  113. msg->animateBlockBone(getDimensionId(),
  114. Game::getChunkCenter(getPos().x, getPos().y),
  115. Chunk::index(Dimension::chunkCoordinates(getPos())),
  116. 1,
  117. 1.0,
  118. Vec3<float>(0.5f, 0.f, 0.45f),
  119. Vec3<float>(
  120. 0.0f, (float)(PI / 2.0), 0.f)); // open the chest over 1 second
  121. broadcastMessage(msg);
  122. }
  123. unlock();
  124. return false; // item was not changed
  125. }
  126. void Chest::sendModelInfo(NetworkMessage* zMessage)
  127. {
  128. if (open)
  129. {
  130. zMessage->animateBlockBone(getDimensionId(),
  131. Game::getChunkCenter(getPos().x, getPos().y),
  132. Chunk::index(Dimension::chunkCoordinates(getPos())),
  133. 1,
  134. 0.0,
  135. Vec3<float>(0.5f, 0.f, 0.45f),
  136. Vec3<float>(
  137. 0.0f, (float)(PI / 2.0), 0.f)); // open the chest instantly
  138. }
  139. }
  140. ChestBlockType::ChestBlockType(Framework::Text itemTypeName,
  141. ModelInfo* model,
  142. Framework::Text name,
  143. int mapColor,
  144. bool modelSubscription,
  145. float hardness,
  146. Framework::RCArray<Framework::Text> groupNames)
  147. : BasicBlockType(itemTypeName,
  148. model,
  149. name,
  150. mapColor,
  151. modelSubscription,
  152. hardness,
  153. groupNames)
  154. {}
  155. Block* ChestBlockType::createBlock(
  156. Framework::Vec3<int> position, int dimensionId) const
  157. {
  158. return new Chest(getItemTypeId(), position, dimensionId);
  159. }
  160. ItemType* ChestBlockType::createItemType() const
  161. {
  162. return new BasicBlockItemType(getItemTypeName(),
  163. new ModelInfo(zModel()->getModelPath(),
  164. zModel()->getTexturePaths(),
  165. zModel()->isTransparent(),
  166. zModel()->getSize() / 2.f),
  167. isTransparent(),
  168. isPassable(),
  169. getHardness(),
  170. getSpeedModifier(),
  171. getItemTypeName(),
  172. 0, 50);
  173. }
  174. ChestBlockTypeFactory::ChestBlockTypeFactory()
  175. : SubTypeFactory()
  176. {}
  177. ChestBlockType* ChestBlockTypeFactory::fromJson(
  178. Framework::JSON::JSONObject* zJson) const
  179. {
  180. Framework::RCArray<Framework::Text> groupNames;
  181. for (Framework::JSON::JSONValue* value :
  182. *zJson->zValue("groupNames")->asArray())
  183. {
  184. groupNames.add(new Framework::Text(value->asString()->getString()));
  185. }
  186. return new ChestBlockType(
  187. zJson->zValue("itemType")->asString()->getString(),
  188. Game::INSTANCE->zTypeRegistry()->fromJson<ModelInfo>(
  189. zJson->zValue("model")),
  190. zJson->zValue("name")->asString()->getString(),
  191. (int)zJson->zValue("mapColor")->asString()->getString(),
  192. zJson->zValue("modelSubscription")->asBool()->getBool(),
  193. (float)zJson->zValue("hardness")->asNumber()->getNumber(),
  194. groupNames);
  195. }
  196. Framework::JSON::JSONObject* ChestBlockTypeFactory::toJson(
  197. ChestBlockType* zObject) const
  198. {
  199. Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
  200. result->addValue("itemType",
  201. new Framework::JSON::JSONString(zObject->getItemTypeName()));
  202. result->addValue(
  203. "model", Game::INSTANCE->zTypeRegistry()->toJson(zObject->zModel()));
  204. result->addValue(
  205. "name", new Framework::JSON::JSONString(zObject->getName()));
  206. result->addValue(
  207. "mapColor", new Framework::JSON::JSONString(zObject->getMapColor()));
  208. result->addValue("modelSubscription",
  209. new Framework::JSON::JSONBool(zObject->doesNeedModelSubscription()));
  210. result->addValue(
  211. "hardness", new Framework::JSON::JSONNumber(zObject->getHardness()));
  212. Framework::JSON::JSONArray* groupNames = new Framework::JSON::JSONArray();
  213. for (Framework::Text* groupName : zObject->getGroupNames())
  214. {
  215. groupNames->addValue(new Framework::JSON::JSONString(*groupName));
  216. }
  217. result->addValue("groupNames", groupNames);
  218. return result;
  219. }
  220. Framework::JSON::Validator::JSONValidator* ChestBlockTypeFactory::getValidator(
  221. Framework::JSON::Validator::ObjectValidationBuilder<
  222. Framework::JSON::Validator::JSONValidator>* builder) const
  223. {
  224. return builder->withRequiredString("itemType")
  225. ->finishString()
  226. ->withRequiredAttribute(
  227. "model", Game::INSTANCE->zTypeRegistry()->getValidator<ModelInfo>())
  228. ->withRequiredString("name")
  229. ->finishString()
  230. ->withRequiredString("mapColor")
  231. ->finishString()
  232. ->withRequiredBool("modelSubscription")
  233. ->withDefault(false)
  234. ->finishBool()
  235. ->withRequiredNumber("hardness")
  236. ->withDefault(1.0)
  237. ->finishNumber()
  238. ->withRequiredArray("groupNames")
  239. ->withDefault(new Framework::JSON::JSONArray())
  240. ->addAcceptedStringInArray()
  241. ->finishString()
  242. ->finishArray()
  243. ->finishObject();
  244. }
  245. Framework::Text ChestBlockTypeFactory::getTypeToken() const
  246. {
  247. return "chest";
  248. }