召唤英雄Ok

This commit is contained in:
aozhiwei 2021-04-20 14:33:28 +08:00
parent 04980ae0ef
commit ce3715d80f
8 changed files with 183 additions and 71 deletions

View File

@ -37,7 +37,7 @@ void InternalShot(Creature* c,
a8::Vec2 bullet_born_offset = a8::Vec2(std::get<0>(tuple), std::get<1>(tuple));
bullet_born_offset.Rotate(c->attack_dir.CalcAngle(a8::Vec2::UP));
a8::Vec2 bullet_born_pos = c->GetPos() + bullet_born_offset;
if (c->room->OverBorder(bullet_born_pos, 0)) {
if (c->room->OverBorder(bullet_born_pos, 0.0f)) {
return;
}
}
@ -846,7 +846,9 @@ void Creature::ProcBuffEffect(Creature* caster, Buff* buff)
break;
case kBET_SummonHero:
{
buff->ProcSummonHero(caster);
SummonHero(GetPos(),
GetMoveDir(),
buff->meta->hero_infos);
}
break;
case kBET_Shield:
@ -1377,45 +1379,17 @@ RoomObstacle* Creature::SummonObstacle(int id, const a8::Vec2& pos)
bool Creature::CollisonDetection()
{
if (room->OverBorder(GetPos(), GetRadius())){
return true;
}
if (HasBuffEffect(kBET_ThroughWall) ||
HasBuffEffect(kBET_Fly)) {
return false;
}
std::set<ColliderComponent*> colliders;
room->map_service->GetColliders(room, GetX(), GetY(), colliders);
bool through_wall = HasBuffEffect(kBET_ThroughWall) ||
HasBuffEffect(kBET_Fly);
AabbCollider aabb_box;
GetAabbBox(aabb_box);
for (ColliderComponent* collider : colliders) {
switch (collider->owner->GetEntityType()) {
case ET_Obstacle:
{
Obstacle* obstacle = (Obstacle*)collider->owner;
if (!obstacle->IsDead(room) &&
(collider->type == CT_Aabb && aabb_box.Intersect((ColliderComponent*)collider))
) {
return true;
}
}
break;
case ET_Building:
{
if (
(collider->type == CT_Aabb && aabb_box.Intersect((ColliderComponent*)collider))
) {
return true;
}
}
break;
default:
break;
}
}
return false;
return room->map_service->CollisionDetection
(
room,
through_wall,
GetPos(),
&aabb_box
);
}
void Creature::FillSkillCasterState(SkillCasterState* caster_state)
@ -1514,16 +1488,42 @@ void Creature::ResetAllSkillCd()
}
}
void Creature::SummonHero(const a8::Vec2& pos, int hero_id, int hero_num)
void Creature::SummonHero(const a8::Vec2& pos,
const a8::Vec2& dir,
std::vector<std::tuple<int, float, float, int>>& infos)
{
for (auto& info : infos) {
int through_wall = std::get<0>(info);
float x = std::get<1>(info);
float y = std::get<2>(info) ;
int hero_id = std::get<3>(info);
MetaData::Player* hero_meta = MetaMgr::Instance()->GetPlayer(hero_id);
if (hero_meta && hero_num > 0 && !dead) {
if (hero_meta && !dead) {
for (int i = 0; i < 4; ++i) {
a8::Vec2 born_dir = dir;
a8::Vec2 born_offset(x, y);
born_offset.Rotate(born_dir.CalcAngle(a8::Vec2::UP));
born_offset.Rotate(i * 0.5);
a8::Vec2 hero_pos = pos + born_offset;
CircleCollider collider;
collider.pos = hero_pos;
collider.rad = hero_meta->i->radius();
if (!room->map_service->CollisionDetection
(
room,
through_wall,
hero_pos,
&collider
)) {
Hero* hero = room->CreateHero
(this,
hero_meta,
GetPos(),
GetMoveDir(),
hero_pos,
dir,
team_id
);
}
}
}
}
}

View File

@ -131,9 +131,11 @@ class Creature : public MoveableEntity
virtual void _UpdateMove(int speed) {};
void CheckSpecObject();
RoomObstacle* SummonObstacle(int id, const a8::Vec2& pos);
void SummonHero(const a8::Vec2& pos, int hero_id, int hero_num);
bool CollisonDetection();
RoomObstacle* SummonObstacle(int id, const a8::Vec2& pos);
void SummonHero(const a8::Vec2& pos,
const a8::Vec2& dir,
std::vector<std::tuple<int, float, float, int>>& infos);
void FillSkillCasterState(SkillCasterState* caster_state);
void RecoverSkillCasterState(SkillCasterState* caster_state);
CreatureWeakPtr AllocWeakPtr();

View File

@ -7,6 +7,7 @@
#include "collider.h"
#include "entity.h"
#include "roomobstacle.h"
#include "room.h"
MapService::MapService()
{
@ -284,3 +285,42 @@ void MapService::RemoveFindPathRequest(Human* hum, int query_id)
{
}
bool MapService::CollisionDetection(Room* room,
bool through_wall,
const a8::Vec2& pos,
ColliderComponent* a_collider)
{
if (room->OverBorder(pos, a_collider)){
return true;
}
if (through_wall) {
return false;
}
std::set<ColliderComponent*> colliders;
GetColliders(room, pos.x, pos.y, colliders);
for (ColliderComponent* collider : colliders) {
switch (collider->owner->GetEntityType()) {
case ET_Obstacle:
{
Obstacle* obstacle = (Obstacle*)collider->owner;
if (!obstacle->IsDead(room) && collider->IntersectEx(pos, a_collider)) {
return true;
}
}
break;
case ET_Building:
{
if (collider->IntersectEx(pos, a_collider)) {
return true;
}
}
break;
default:
break;
}
}
return false;
}

View File

@ -54,6 +54,10 @@ class MapService
int max_step_num);
FindPathStatus* QueryFindPathStatus(int query_id);
void RemoveFindPathRequest(Human* hum, int query_id);
bool CollisionDetection(Room* room,
bool through_wall,
const a8::Vec2& pos,
ColliderComponent* collider);
private:
int GetGridId(float world_x, float world_y);

View File

@ -566,6 +566,24 @@ namespace MetaData
}
}
}
{
std::vector<std::string> strings;
a8::Split(i->post_remove_action(), strings, '|');
for (auto& str : strings) {
std::vector<std::string> strings2;
a8::Split(str, strings2, ':');
if (strings2.size() > 4) {
int through_wall = a8::XValue(strings2[0]);
float x = a8::XValue(strings2[1]).GetDouble();
float y = a8::XValue(strings2[2]).GetDouble();
int hero_id = a8::XValue(strings2[3]);
hero_infos.push_back
(
std::make_tuple(through_wall, x, y, hero_id)
);
}
}
}
if (i->buff_effect() == kBET_BatchAddBuff) {
std::vector<std::string> strings1;
a8::Split(i->buff_param1(), strings1, '|');

View File

@ -174,6 +174,7 @@ namespace MetaData
std::vector<std::tuple<int, std::vector<std::tuple<int, int>>>> batch_add_list;
std::vector<std::tuple<int, std::vector<int>>> post_remove_action;
std::set<int> immune_buffeffect;
std::vector<std::tuple<int, float, float, int>> hero_infos;
};
struct SkillPhase

View File

@ -745,29 +745,75 @@ void Room::OnHumanRevive(Human* hum)
NotifyUiUpdate();
}
bool Room::OverBorder(const a8::Vec2 pos, float radius)
bool Room::OverBorder(const a8::Vec2& pos, float radius)
{
CircleCollider collider;
collider.pos = pos;
collider.rad = radius;
return OverBorder(pos, &collider);
}
bool Room::OverBorder(const a8::Vec2& pos, ColliderComponent* collider)
{
switch (collider->type) {
case CT_Aabb:
{
AabbCollider* aabb_box = (AabbCollider*)collider;
//检查x轴
{
int left_x = pos.x - radius;
float left_x = (pos + aabb_box->_min).x;
if (left_x < 0.001f) {
return true;
}
int right_x = pos.x + radius;
float right_x = (pos + aabb_box->_max).x;
if (right_x > map_meta_->i->map_width()) {
return true;
}
}
//检查y轴
{
int up_y = pos.y + radius;
if (up_y > map_meta_->i->map_height()) {
return true;
}
int down_y = pos.y - radius;
float down_y = (pos + aabb_box->_min).y;
if (down_y < 0.001f) {
return true;
}
float up_y = (pos + aabb_box->_max).y;
if (up_y > map_meta_->i->map_height()) {
return true;
}
}
}
break;
case CT_Circle:
{
CircleCollider* circle_collider = (CircleCollider*)collider;
//检查x轴
{
float left_x = pos.x - circle_collider->rad;
if (left_x < 0.001f) {
return true;
}
float right_x = pos.x + circle_collider->rad;
if (right_x > map_meta_->i->map_width()) {
return true;
}
}
//检查y轴
{
float down_y = pos.y - circle_collider->rad;
if (down_y < 0.001f) {
return true;
}
float up_y = pos.y + circle_collider->rad;
if (up_y > map_meta_->i->map_height()) {
return true;
}
}
}
break;
default:
{
}
break;
}
return false;
}

View File

@ -129,7 +129,8 @@ public:
void OnHumanDie(Human* hum);
void OnHumanRevive(Human* hum);
bool OverBorder(const a8::Vec2 pos, float radius);
bool OverBorder(const a8::Vec2& pos, float radius);
bool OverBorder(const a8::Vec2& pos, ColliderComponent* collider);
Human* GetWatchWarTarget(Human* hum);
bool BattleStarted();
int GetAliveTeamNum();