merge dixing

This commit is contained in:
aozhiwei 2021-03-30 19:31:18 +08:00
commit d2d0d3a62c
12 changed files with 377 additions and 16 deletions

View File

@ -338,7 +338,12 @@ enum AIMode_e
enum ColliderTag_e
{
kHalfWallTag = 1
kHalfWallTag = 1,
kColliderSpecTag_Begin = 2,
kColliderTag_Grass = 2, //草丛
kColliderTag_Water = 3, //水
kColliderTag_Ice = 4, //冰
kColliderSpecTag_End = 4,
};
enum GameChannel_e
@ -406,8 +411,11 @@ const int TURN_OVER_SKILL_ID = 41001;
const int HUNLUAN_BUFFID = 6001;
const long long SPEC_MAP_OBJECT_FLAGS = A8_DEFINE_RANGE_BIT(long long, kColliderSpecTag_Begin, kColliderSpecTag_End);
const int kThroughWall_BUFFID = 6003;
const int FLY_BUFFID = 7001;
const int JUMP_BUFFID = 7002;
const int DRIVER_BUFFID = 7003;
const int PASSENGER_BUFFID = 7004;

View File

@ -3307,6 +3307,104 @@ void Human::DoGetOnWithCar(Car* car)
car->GetOn(this);
}
void Human::CheckSpecObject()
{
std::set<ColliderComponent*> colliders;
room->map_service->GetSpecColliders(SPEC_MAP_OBJECT_FLAGS, room, GetPos().x, GetPos().y, colliders);
long long flags = 0;
for (const ColliderComponent* collider : colliders) {
switch (collider->owner->GetEntityType()) {
case ET_Obstacle:
case ET_Building:
{
if (TestCollision(room, (ColliderComponent*)collider)) {
flags |= collider->tag;
}
}
break;
default:
break;
}
}
for (int i = kColliderSpecTag_Begin; i <= kColliderSpecTag_End; ++i) {
SpecMapObject& map_obj = spec_map_objects_[i - kColliderSpecTag_Begin];
int buff_effect = 0;
if (a8::HasBitFlag(flags, i)) {
if (!HasBuffEffect(buff_effect)) {
OnEnterSpecMapArea(i, map_obj);
}
} else {
if (HasBuffEffect(buff_effect)) {
OnLeaveSpecMapArea(i, map_obj);
}
}
}
}
void Human::OnEnterSpecMapArea(int tag, SpecMapObject& map_obj)
{
ClearSpecMapAreaTimer(map_obj);
map_obj.enter_timer = room->xtimer.AddDeadLineTimerAndAttach
(MetaMgr::Instance()->GetSpecMapAreaEnterTime(tag) * SERVER_FRAME_RATE,
a8::XParams()
.SetSender(this)
.SetParam1(&map_obj)
.SetParam2(tag),
[] (const a8::XParams& param)
{
Human* hum = (Human*)param.sender.GetUserData();
MetaData::Buff* buff_meta = MetaMgr::Instance()->GetBuff
(MetaMgr::Instance()->GetSpecMapAreaBuffId(param.param2));
if (buff_meta) {
hum->AddBuff(hum, buff_meta, 1);
}
},
&xtimer_attacher.timer_list_,
[] (const a8::XParams& param)
{
SpecMapObject* map_obj = (SpecMapObject*)param.param1.GetUserData();
map_obj->enter_timer = nullptr;
});
}
void Human::OnLeaveSpecMapArea(int tag, SpecMapObject& map_obj)
{
ClearSpecMapAreaTimer(map_obj);
map_obj.leave_timer = room->xtimer.AddDeadLineTimerAndAttach
(MetaMgr::Instance()->GetSpecMapAreaLeaveTime(tag) * SERVER_FRAME_RATE,
a8::XParams()
.SetSender(this)
.SetParam1(&map_obj)
.SetParam2(tag),
[] (const a8::XParams& param)
{
Human* hum = (Human*)param.sender.GetUserData();
hum->RemoveBuffById((MetaMgr::Instance()->GetSpecMapAreaBuffId(param.param2)));
},
&xtimer_attacher.timer_list_,
[] (const a8::XParams& param)
{
SpecMapObject* map_obj = (SpecMapObject*)param.param1.GetUserData();
map_obj->leave_timer = nullptr;
});
}
void Human::ClearSpecMapAreaTimer(SpecMapObject& map_obj)
{
if (map_obj.leave_timer) {
room->xtimer.DeleteTimer(map_obj.leave_timer);
map_obj.leave_timer = nullptr;
}
if (map_obj.enter_timer) {
room->xtimer.DeleteTimer(map_obj.enter_timer);
map_obj.enter_timer = nullptr;
}
}
void Human::DoSkillPreProc(int skill_id, int target_id, const a8::Vec2& target_pos)
{
if (action_type == AT_Reload ||

View File

@ -25,6 +25,12 @@ enum HumanStatus
HS_End
};
struct SpecMapObject
{
struct xtimer_list* leave_timer = nullptr;
struct xtimer_list* enter_timer = nullptr;
};
struct xtimer_list;
class CircleCollider;
class AabbCollider;
@ -271,6 +277,10 @@ private:
void NextReload(int prev_weapon_id, int prev_weapon_idx);
void DoGetOnWithLoot(Loot* loot_entity);
void DoGetOnWithCar(Car* car);
void CheckSpecObject();
void OnEnterSpecMapArea(int tag, SpecMapObject& map_obj);
void OnLeaveSpecMapArea(int tag, SpecMapObject& map_obj);
void ClearSpecMapAreaTimer(SpecMapObject& map_obj);
virtual void AddBuffPostProc(Creature* caster, Buff* buff) override;
virtual void OnBuffRemove(const Buff& buff) override;
virtual void DoSkillPreProc(int skill_id, int target_id, const a8::Vec2& target_pos) override;
@ -327,6 +337,7 @@ private:
size_t box_drop_times_ = 0;
std::array<ObjectSyncFlags, FIXED_OBJECT_MAXID> fixed_object_sync_flags_ = {};
std::array<SpecMapObject, kColliderSpecTag_End - kColliderSpecTag_Begin + 1> spec_map_objects_ = {};
bool already_report_battle_ = false;
bool sent_battlereport_ = false;

View File

@ -34,6 +34,7 @@ void MapInstance::Init()
map_meta_->i->map_height() / MAP_GRID_WIDTH,
MAP_GRID_WIDTH);
CreateThings();
CreateTerrain();
a8::UdpLog::Instance()->Info
("map_id:%d current_uniid:%d loots:%d mini_room_spawn_points:%d normal_room_spawn_points:%d "
"building_num:%d obstalce_num:%d obstacle0_num:%d "
@ -149,6 +150,95 @@ void MapInstance::CreateThings()
}
}
void MapInstance::CreateTerrain()
{
metatable::TerrainJson* terrain = MetaMgr::Instance()->GetTerrainJson(map_id);
std::list<metatable::MapLayerJson>* layers = MetaMgr::Instance()->GetMapLayer(map_meta_->i->map_pic());
if (!terrain || !layers) {
return;
//abort();
}
if (layers->empty()) {
return;
}
metatable::MapLayerJson* first_layer = nullptr;
for (auto layer : *layers) {
if (!first_layer) {
first_layer = &layer;
}
if (layer.width() != first_layer->width()) {
abort();
}
if (layer.height() != first_layer->height()) {
abort();
}
if (layer.grids().size() != first_layer->grids().size()) {
abort();
}
}
if (first_layer->grids().size() != first_layer->width() * first_layer->height()) {
abort();
}
if (first_layer->grids().size() <= 0) {
abort();
}
std::vector<int> grids;
grids.reserve(first_layer->grids().size());
for (int i = 0; i < first_layer->grids().size(); ++i) {
grids.push_back(0);
}
std::set<int> dusts;
for (auto idx : terrain->dust()) {
dusts.insert(idx);
}
std::set<int> waters;
for (auto idx : terrain->water()) {
waters.insert(idx);
}
std::set<int> grasses;
for (auto idx : terrain->grass()) {
grasses.insert(idx);
}
int mask = A8_DEFINE_RANGE_BIT(int, 0, 22);
for (auto layer : *layers) {
for (int i = 0; i < first_layer->grids().size(); ++i) {
int grid_val = layer.grids(i) & mask;
if (grid_val != 0) {
grids[i] = grid_val;
}
}
}
MetaData::MapThing* thing_meta = MetaMgr::Instance()->GetMapThing(0);
if (thing_meta) {
for (int w = 0; w < first_layer->width(); ++w) {
for (int h = 0; h < first_layer->height(); ++h) {
int grid_val = grids[w * first_layer->width() + h];
if (grid_val != 0) {
float x = w * thing_meta->i->width() + thing_meta->i->width() / 2.0f;
float y = h * thing_meta->i->height() + thing_meta->i->height() / 2.0f;
int collider_tag = 0;
if (dusts.find(grid_val) != dusts.end()) {
a8::SetBitFlag(collider_tag, kColliderTag_Ice);
} else if (waters.find(grid_val) != waters.end()) {
a8::SetBitFlag(collider_tag, kColliderTag_Water);
} else if (grasses.find(grid_val) != grasses.end()) {
a8::SetBitFlag(collider_tag, kColliderTag_Grass);
}
if (collider_tag != 0) {
InternalCreateObstacle(thing_meta->i->thing_id(), x, y, collider_tag,
[] (Obstacle* entity)
{
});
}
}
}
}
}
}
void MapInstance::CreateMapObject(MetaData::MapTplThing& thing_tpl)
{
int thing_id = thing_tpl.RandThing();
@ -157,7 +247,7 @@ void MapInstance::CreateMapObject(MetaData::MapTplThing& thing_tpl)
if (thing_meta->i->is_house()) {
CreateBuilding(thing_id, thing_tpl.i->x(), thing_tpl.i->y());
} else {
InternalCreateObstacle(thing_id, thing_tpl.i->x(), thing_tpl.i->y(),
InternalCreateObstacle(thing_id, thing_tpl.i->x(), thing_tpl.i->y(), 0,
[] (Obstacle* entity)
{
});
@ -192,7 +282,7 @@ void MapInstance::CreateBuilding(int thing_id, float building_x, float building_
MetaData::Building::Door* door_meta = &building->meta->doors[door_idx];
float x = building->GetX() + door_meta->state0->x() - building->meta->i->tilewidth() / 2.0;
float y = building->GetY() + door_meta->state0->y() - building->meta->i->tileheight() / 2.0;
InternalCreateObstacle(DOOR_THING_ID, x, y,
InternalCreateObstacle(DOOR_THING_ID, x, y, 0,
[building, door_idx] (Obstacle* entity)
{
entity->SetDoorInfo(building, door_idx);
@ -206,7 +296,7 @@ void MapInstance::CreateBuilding(int thing_id, float building_x, float building_
int rnd = rand () % obj._rand_space();
for (auto& pair : obj._things()) {
if (rnd <= pair.value()) {
InternalCreateObstacle(pair.key(), x, y,
InternalCreateObstacle(pair.key(), x, y, 0,
[building] (Obstacle* entity)
{
entity->SetBuilding(building);
@ -219,12 +309,13 @@ void MapInstance::CreateBuilding(int thing_id, float building_x, float building_
buildings_.push_back(building);
}
Obstacle* MapInstance::InternalCreateObstacle(int id, float x, float y,
Obstacle* MapInstance::InternalCreateObstacle(int id, float x, float y, int collider_tag,
std::function<void (Obstacle*)> on_precreate)
{
MetaData::MapThing* thing = MetaMgr::Instance()->GetMapThing(id);
if (thing) {
Obstacle* entity = EntityFactory::Instance()->MakeObstacle(AllocUniid());
entity->collider_tag = collider_tag;
entity->meta = thing;
entity->is_permanent = true;
entity->permanent_map_service = map_service_;

View File

@ -26,9 +26,10 @@ class MapInstance
private:
void CreateThings();
void CreateTerrain();
void CreateMapObject(MetaData::MapTplThing& thing_tpl);
void CreateBuilding(int thing_id, float building_x, float building_y);
Obstacle* InternalCreateObstacle(int id, float x, float y,
Obstacle* InternalCreateObstacle(int id, float x, float y, int collider_tag,
std::function<void (Obstacle*)> on_precreate);
Entity* GetEntityByUniId(int uniid);
int AllocUniid();

View File

@ -184,6 +184,9 @@ void MapService::GetColliders(Room* room,
}
struct CellNode *node, *tmp;
list_for_each_entry_safe(node, tmp, head, entry) {
if (node->collider->tag != 0) {
continue;
}
switch (node->collider->owner->GetEntityType()) {
case ET_Obstacle:
{
@ -225,6 +228,33 @@ void MapService::GetColliders(Room* room,
}
}
void MapService::GetSpecColliders(long long flags,
Room* room,
float world_x,
float world_y,
std::set<ColliderComponent*>& colliders)
{
int center_grid_id = GetGridId(world_x, world_y);
if (center_grid_id < 0 || center_grid_id >= max_grid_id_) {
return;
}
for (int i = 0; i < a8::ArraySize(grid_offset_arr_); ++i) {
int grid_id = center_grid_id + grid_offset_arr_[i];
if (grid_id >= 0 && grid_id < max_grid_id_) {
list_head* head = &map_cells_[grid_id];
if (list_empty(head)) {
continue;
}
struct CellNode *node, *tmp;
list_for_each_entry_safe(node, tmp, head, entry) {
if (a8::HasBitFlag(flags, node->collider->tag)) {
colliders.insert(node->collider);
}
}
}
}
}
int MapService::GetGridId(float world_x, float world_y)
{
int grid_id = (int)(world_x/cell_width_) + (int)(world_y/cell_width_) * map_width_;

View File

@ -43,6 +43,11 @@ class MapService
float world_x,
float world_y,
std::set<ColliderComponent*>& colliders);
void GetSpecColliders(long long flags,
Room* room,
float world_x,
float world_y,
std::set<ColliderComponent*>& colliders);
int FindPathRequest(Human* hum,
const a8::Vec2& start_pos,
const a8::Vec2& end_pos,

View File

@ -1,5 +1,8 @@
#include "precompile.h"
#include <unistd.h>
#include <fcntl.h>
#include <a8/stringlist.h>
#include <a8/csvreader.h>
@ -63,6 +66,7 @@ public:
std::list<metatable::AI> ai_meta_list;
std::list<MetaData::AI> ai_list;
std::list<metatable::Text> text_meta_list;
std::list<metatable::TerrainJson> terrain_meta_list;
std::map<std::string, MetaData::Parameter*> parameter_hash;
std::map<int, MetaData::Map*> gamemap_hash;
@ -76,6 +80,7 @@ public:
std::map<int, MetaData::Building*> building_hash;
std::map<int, MetaData::Drop*> drop_hash;
std::map<std::string, std::list<metatable::MapTplThingJson>> maptpl_meta_hash;
std::map<std::string, std::list<metatable::MapLayerJson>> layer_meta_hash;
std::map<std::string, std::vector<MetaData::MapTplThing>> maptpl_hash;
std::map<int, MetaData::Dress*> dress_hash;
std::vector<MetaData::Dress*> dress_vec;
@ -141,6 +146,7 @@ public:
f8::ReadCsvMetaFile(res_path + "robot@robot.csv", robot_meta_list);
f8::ReadCsvMetaFile(res_path + "ai@ai.csv", ai_meta_list);
f8::ReadCsvMetaFile(res_path + "text@text.csv", text_meta_list);
f8::ReadJsonMetaFile(res_path + "terrain.json", terrain_meta_list);
BindToMetaData();
#if 1
{
@ -443,14 +449,29 @@ private:
#if 1
{
for (auto& tuple : item.template_list) {
auto itr = maptpl_meta_hash.find(std::get<0>(tuple));
if (itr == maptpl_meta_hash.end()) {
maptpl_meta_hash[std::get<0>(tuple)] = std::list<metatable::MapTplThingJson>();
itr = maptpl_meta_hash.find(std::get<0>(tuple));
} else {
itr->second.clear();
{
auto itr = maptpl_meta_hash.find(std::get<0>(tuple));
if (itr == maptpl_meta_hash.end()) {
maptpl_meta_hash[std::get<0>(tuple)] = std::list<metatable::MapTplThingJson>();
itr = maptpl_meta_hash.find(std::get<0>(tuple));
} else {
itr->second.clear();
}
f8::ReadJsonMetaFile(res_path + std::get<0>(tuple) + ".json", itr->second);
}
{
auto itr = layer_meta_hash.find(meta.map_pic());
if (itr == layer_meta_hash.end()) {
layer_meta_hash[meta.map_pic()] = std::list<metatable::MapLayerJson>();
itr = layer_meta_hash.find(meta.map_pic());
} else {
itr->second.clear();
}
std::string filename = res_path + "map" + meta.map_pic() + ".layers.json";
if (access(filename.c_str(), F_OK) != -1) {
f8::ReadJsonMetaFile(filename, itr->second);
}
}
f8::ReadJsonMetaFile(res_path + std::get<0>(tuple) + ".json", itr->second);
}
}
#endif
@ -732,12 +753,28 @@ MetaData::SafeArea* MetaMgr::GetSafeArea(int area_id)
return itr != loader_->safearea_hash.end() ? itr->second : nullptr;
}
std::vector<MetaData::MapTplThing>* MetaMgr::GetMapTplThing(std::string& map_name)
std::vector<MetaData::MapTplThing>* MetaMgr::GetMapTplThing(const std::string& map_name)
{
auto itr = loader_->maptpl_hash.find(map_name);
return itr != loader_->maptpl_hash.end() ? &itr->second : nullptr;
}
metatable::TerrainJson* MetaMgr::GetTerrainJson(int map_id)
{
for (auto& itr : loader_->terrain_meta_list) {
if (itr.map_id() == map_id) {
return &itr;
}
}
return nullptr;
}
std::list<metatable::MapLayerJson>* MetaMgr::GetMapLayer(const std::string& map_name)
{
auto itr = loader_->layer_meta_hash.find(map_name);
return itr != loader_->layer_meta_hash.end() ? &itr->second : nullptr;
}
std::list<MetaData::AirDrop>& MetaMgr::GetAirDrops()
{
return loader_->airdrop_list;
@ -871,3 +908,45 @@ std::string MetaMgr::GetText(const std::string& textid, const std::string& def_t
auto itr = loader_->text_hash.find(textid);
return itr != loader_->text_hash.end() ? itr->second : def_text;
}
int MetaMgr::GetSpecMapAreaBuffId(int tag)
{
switch (tag) {
case kColliderTag_Grass:
return 6005;
case kColliderTag_Water:
return 6006;
case kColliderTag_Ice:
return 6007;
default:
return 0;
}
}
int MetaMgr::GetSpecMapAreaEnterTime(int tag)
{
switch (tag) {
case kColliderTag_Grass:
return grass_invisible_time;
case kColliderTag_Water:
return water_invisible_time;
case kColliderTag_Ice:
return ice_invisible_time;
default:
return 0;
}
}
int MetaMgr::GetSpecMapAreaLeaveTime(int tag)
{
switch (tag) {
case kColliderTag_Grass:
return grass_show_time;
case kColliderTag_Water:
return water_show_time;
case kColliderTag_Ice:
return ice_show_time;
default:
return 0;
}
}

View File

@ -31,7 +31,9 @@ class MetaMgr : public a8::Singleton<MetaMgr>
MetaData::Building* GetBuilding(int building_id);
MetaData::Drop* GetDrop(int drop_id);
MetaData::SafeArea* GetSafeArea(int area_id);
std::vector<MetaData::MapTplThing>* GetMapTplThing(std::string& map_name);
std::vector<MetaData::MapTplThing>* GetMapTplThing(const std::string& map_name);
metatable::TerrainJson* GetTerrainJson(int map_id);
std::list<metatable::MapLayerJson>* GetMapLayer(const std::string& map_name);
std::list<MetaData::AirDrop>& GetAirDrops();
MetaData::AirDrop* GetAirDrop(int airdrop_id);
MetaData::AirLine* RandAirLine(int map_id);
@ -52,6 +54,9 @@ class MetaMgr : public a8::Singleton<MetaMgr>
MetaData::Robot* RandRobot(std::set<int>& refreshed_robot_set);
MetaData::AI* GetAI(int ai_level, int ai_mode);
std::string GetText(const std::string& textid, const std::string& def_text="");
int GetSpecMapAreaBuffId(int tag);
int GetSpecMapAreaEnterTime(int tag);
int GetSpecMapAreaLeaveTime(int tag);
int gas_inactive_time = 10;
int newbie_gas_inactive_time = 5;
@ -123,6 +128,16 @@ class MetaMgr : public a8::Singleton<MetaMgr>
int level1room_robot_autodie_distance = 0;
std::string level1room_born_point;
float grass_invisible_time = 0.5;
float grass_show_time = 0.5f;
float grass_invisible_time2 = 2.0f;
float water_invisible_time = 0.5;
float water_show_time = 0.5f;
float water_invisible_time2 = 2.0f;
float ice_invisible_time = 0.5;
float ice_show_time = 0.5f;
float ice_invisible_time2 = 2.0f;
#if 0
int refresh_robot_min_num = 0;
int refresh_robot_max_num = 0;

View File

@ -97,6 +97,9 @@ void Obstacle::RecalcSelfCollider()
self_collider_->pos = a8::Vec2();
self_collider_->rad = 0.0f;
}
for (auto collider : colliders_) {
collider->tag = collider_tag;
}
}
void Obstacle::FillMFObjectPart(Room* room, Human* hum, cs::MFObjectPart* part_data)
@ -171,12 +174,14 @@ void Obstacle::GetAabbBox(AabbCollider& aabb_box)
if (self_collider_) {
aabb_box.active = true;
aabb_box.owner = this;
aabb_box.tag = collider_tag;
aabb_box._min.x = -self_collider_->rad;
aabb_box._min.y = -self_collider_->rad;
aabb_box._max.x = self_collider_->rad;
aabb_box._max.y = self_collider_->rad;
return;
}
aabb_box.tag = collider_tag;
aabb_box.active = true;
aabb_box.owner = this;
}

View File

@ -25,6 +25,7 @@ class Obstacle : public Entity
MetaData::MapThing* meta = nullptr;
MapService* permanent_map_service = nullptr;
bool is_permanent = false;
int collider_tag = 0;
virtual ~Obstacle() override;
virtual void Initialize() override;

View File

@ -33,6 +33,7 @@ message Map
optional int32 map_mode = 10;
optional int32 safearea = 11;
optional string game_start_buff_list = 12;
optional string map_pic = 13;
}
message MapThing
@ -357,4 +358,20 @@ message MapTplThingJson
optional float param3 = 11;
optional string object_type = 12;
optional int32 _object_type = 13;
}
}
message TerrainJson
{
optional int32 map_id = 1;
repeated int32 dust = 2;
repeated int32 water = 3;
repeated int32 grass = 4;
}
message MapLayerJson
{
optional string name = 1;
optional int32 width = 2;
optional int32 height = 3;
repeated int32 grids = 4;
}