add house loot

This commit is contained in:
aozhiwei 2019-03-27 16:43:41 +08:00
parent cce493f454
commit 5b05533500
8 changed files with 180 additions and 7 deletions

View File

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

View File

@ -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<Entity*> objects;
int detection_flags = 0;
{
@ -75,7 +75,7 @@ void Bullet::OnHit(std::vector<Entity*>& 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),

View File

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

View File

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

View File

@ -7,12 +7,65 @@ namespace MetaData
void Drop::Init()
{
std::vector<std::string> item_list;
{
a8::Split(i->item_id(), item_list, '|');
}
std::vector<std::string> num_list;
{
a8::Split(i->num(), num_list, '|');
}
std::vector<std::string> 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<int, int, int> 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<int, int, int> 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<std::tuple<int, int, int>>& drop_items)
void Drop::RandItems(std::vector<std::tuple<int, int>>& 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;
}
}
}
}
}

View File

@ -50,10 +50,11 @@ namespace MetaData
const metatable::Drop* i = nullptr;
void Init();
void RandItem(std::vector<std::tuple<int, int, int>>& drop_items);
void RandItems(std::vector<std::tuple<int, int>>& drop_items);
private:
std::vector<std::tuple<int, int, int>> items;
int total_weight = 0;
};
}

View File

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

View File

@ -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<std::tuple<int, int>> 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()