diff --git a/server/gameserver/building.cc b/server/gameserver/building.cc index e100fdb..49c5d9b 100644 --- a/server/gameserver/building.cc +++ b/server/gameserver/building.cc @@ -7,6 +7,7 @@ #include "collider.h" #include "obstacle.h" #include "human.h" +#include "loot.h" Building::Building():Entity() { @@ -50,6 +51,25 @@ void Building::RecalcSelfCollider() } } } + for (auto& obj : meta->i->dropobj()) { + MetaData::Equip* equip_meta = MetaMgr::Instance()->GetEquip(obj.id()); + if (equip_meta) { + Loot* entity = new Loot(); + entity->room = room; + entity->meta = equip_meta; + entity->entity_uniid = room->AllocUniid(); + entity->pos = Vector2D(pos.x + obj.x() - meta->i->tilewidth() / 2.0, + pos.y + obj.y() - meta->i->tileheight() / 2.0); + entity->item_id = obj.id(); + entity->count = 1; + entity->Initialize(); + room->uniid_hash_[entity->entity_uniid] = entity; + for (auto& pair : room->human_hash_) { + pair.second->new_objects.insert(entity); + pair.second->part_objects.insert(entity); + } + } + } } void Building::FillMFObjectPart(cs::MFObjectPart* part_data) diff --git a/server/gameserver/bullet.cc b/server/gameserver/bullet.cc index b548efc..02c6c2c 100644 --- a/server/gameserver/bullet.cc +++ b/server/gameserver/bullet.cc @@ -29,7 +29,7 @@ void Bullet::Initialize() void Bullet::Update(int delta_time) { movement->Update(delta_time); - pos = pos + dir * gun_meta->i->bullet_speed(); + pos = pos + dir * gun_meta->i->bullet_speed() / 20.0f; std::vector objects; int detection_flags = 0; { @@ -75,7 +75,7 @@ void Bullet::OnHit(std::vector& objects) obstacle->dead = std::min(obstacle->health, 0.001f) <= 0.01f; if (obstacle->dead) { obstacle->ClearColliders(); - room->ProcDrop(pos, obstacle->meta->i->drop()); + room->ProcDrop(obstacle->pos, obstacle->meta->i->drop()); } room->TouchPlayerList(a8::XParams() .SetSender(obstacle), diff --git a/server/gameserver/loot.cc b/server/gameserver/loot.cc index e69de29..3678b02 100644 --- a/server/gameserver/loot.cc +++ b/server/gameserver/loot.cc @@ -0,0 +1,44 @@ +#include "precompile.h" + +#include "loot.h" +#include "metamgr.h" +#include "movement.h" +#include "room.h" +#include "collider.h" + +Loot::Loot():Entity() +{ + entity_type = ET_Loot; +} + +Loot::~Loot() +{ +} + +void Loot::Initialize() +{ + RecalcSelfCollider(); +} + +void Loot::RecalcSelfCollider() +{ +} + +void Loot::FillMFObjectPart(cs::MFObjectPart* part_data) +{ + part_data->set_object_type(ET_Loot); + cs::MFLootPart* p = part_data->mutable_union_obj_5(); + p->set_obj_uniid(entity_uniid); + pos.ToPB(p->mutable_pos()); +} + +void Loot::FillMFObjectFull(cs::MFObjectFull* full_data) +{ + full_data->set_object_type(ET_Loot); + cs::MFLootFull* p = full_data->mutable_union_obj_5(); + p->set_obj_uniid(entity_uniid); + pos.ToPB(p->mutable_pos()); + + p->set_item_id(item_id); + p->set_count(count); +} diff --git a/server/gameserver/loot.h b/server/gameserver/loot.h index e69de29..f0701e8 100644 --- a/server/gameserver/loot.h +++ b/server/gameserver/loot.h @@ -0,0 +1,27 @@ +#pragma once + +#include "entity.h" + +namespace MetaData +{ + struct Player; + struct Equip; + struct MapThing; +} + +class Human; +class Loot : public Entity +{ + public: + MetaData::Equip* meta = nullptr; + int item_id = 0; + int count = 0; + + Loot(); + virtual ~Loot() override; + virtual void Initialize() override; + void RecalcSelfCollider(); + virtual void FillMFObjectPart(cs::MFObjectPart* part_data) override; + virtual void FillMFObjectFull(cs::MFObjectFull* full_data) override; + +}; diff --git a/server/gameserver/metadata.cc b/server/gameserver/metadata.cc index 80f5f1c..4e417ad 100644 --- a/server/gameserver/metadata.cc +++ b/server/gameserver/metadata.cc @@ -7,12 +7,65 @@ namespace MetaData void Drop::Init() { - + std::vector item_list; + { + a8::Split(i->item_id(), item_list, '|'); + } + std::vector num_list; + { + a8::Split(i->num(), num_list, '|'); + } + std::vector weight_list; + { + a8::Split(i->weight(), weight_list, '|'); + } + assert(item_list.size() == num_list.size() && + item_list.size() == weight_list.size()); + total_weight = 0; + for (size_t i = 0; i < item_list.size(); ++i) { + total_weight += a8::XValue(weight_list[i]).GetInt(); + if (this->i->type() == 1) { + std::tuple item_tuple = std::make_tuple( + a8::XValue(item_list[i]), + a8::XValue(num_list[i]), + a8::XValue(weight_list[i]) + ); + items.push_back(item_tuple); + } else { + std::tuple item_tuple = std::make_tuple( + a8::XValue(item_list[i]), + a8::XValue(num_list[i]), + total_weight + ); + items.push_back(item_tuple); + } + } + assert(i->type() == 1 || i->type() == 2); } - void Drop::RandItem(std::vector>& drop_items) + void Drop::RandItems(std::vector>& drop_items) { - + if (i->type() == 1) { + for (auto& item : items) { + if ((rand() % 10000) <= std::get<2>(item)) { + drop_items.push_back(std::make_tuple( + std::get<0>(item), + std::get<1>(item) + )); + } + } + } else if (total_weight > 0) { + int rnd = rand() % total_weight; + for (auto& item : items) { + if (std::get<2>(item) >= rnd) { + drop_items.push_back(std::make_tuple( + std::get<0>(item), + std::get<1>(item) + )); + break; + } + } + } } } diff --git a/server/gameserver/metadata.h b/server/gameserver/metadata.h index 3146908..fd6812d 100755 --- a/server/gameserver/metadata.h +++ b/server/gameserver/metadata.h @@ -50,10 +50,11 @@ namespace MetaData const metatable::Drop* i = nullptr; void Init(); - void RandItem(std::vector>& drop_items); + void RandItems(std::vector>& drop_items); private: std::vector> items; + int total_weight = 0; }; } diff --git a/server/gameserver/metamgr.cc b/server/gameserver/metamgr.cc index 32b8d7a..e8bc580 100755 --- a/server/gameserver/metamgr.cc +++ b/server/gameserver/metamgr.cc @@ -111,6 +111,7 @@ private: for (auto& meta : drop_meta_list) { MetaData::Drop& item = a8::FastAppend(drop_list); item.i = &meta; + item.Init(); drop_hash[item.i->drop_id()] = &item; } diff --git a/server/gameserver/room.cc b/server/gameserver/room.cc index 6092615..a45a557 100644 --- a/server/gameserver/room.cc +++ b/server/gameserver/room.cc @@ -11,6 +11,7 @@ #include "collider.h" #include "obstacle.h" #include "building.h" +#include "loot.h" const int ROOM_MAX_PLAYER_NUM = 50; const int ANDROID_NUM = 0; @@ -330,7 +331,33 @@ void Room::ResetFrameData() void Room::ProcDrop(Vector2D center, int drop_id) { - + MetaData::Drop* drop_meta = MetaMgr::Instance()->GetDrop(drop_id); + if (drop_meta) { + std::vector> drop_items; + drop_meta->RandItems(drop_items); + for (auto& item : drop_items) { + MetaData::Equip* equip_meta = MetaMgr::Instance()->GetEquip(std::get<0>(item)); + if (equip_meta) { + Loot* entity = new Loot(); + entity->room = this; + entity->meta = equip_meta; + entity->entity_uniid = AllocUniid(); + { + Vector2D dir = Vector2D::UP; + dir.Rotate(a8::RandAngle()); + entity->pos = center + dir * (5 + rand() % 50); + } + entity->item_id = std::get<0>(item); + entity->count = std::get<1>(item); + entity->Initialize(); + uniid_hash_[entity->entity_uniid] = entity; + for (auto& pair : human_hash_) { + pair.second->new_objects.insert(entity); + pair.second->part_objects.insert(entity); + } + } + } + } } void Room::ClearDeletedObjects()