This commit is contained in:
aozhiwei 2022-01-06 12:06:36 +08:00
parent 03e08e46e9
commit 9bd36590d3
5 changed files with 122 additions and 61 deletions

View File

@ -2186,52 +2186,38 @@ void Creature::SummonHero(Buff* buff,
MetaData::Player* hero_meta = MetaMgr::Instance()->GetPlayer(hero_id);
if (hero_meta) {
for (int j = 0; j < num; ++j) {
bool can_create = false;
a8::Vec2 born_pos;
Hero* hero = nullptr;
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;
hero = InternalSummonHero(hero_meta,
dir,
hero_pos,
through_wall);
if (hero) {
born_pos = pos + born_offset;
can_create = TrySummonHero(hero_meta,
dir,
born_pos,
through_wall);
if (can_create) {
break;
}
}//end for i
if (!hero) {
hero = InternalSummonHero(hero_meta,
GetAttackDir(),
GetPos(),
through_wall);
#ifdef DEBUG
SendDebugMsg(a8::Format("second summon hero id:%d pos:%f,%f rad:%d ok:%d",
{
hero_meta->i->id(),
GetPos().x,
GetPos().y,
hero_meta->i->radius(),
hero ? 1 : 0
}));
#endif
if (!can_create) {
born_pos = GetPos();
can_create = TrySummonHero(hero_meta,
GetAttackDir(),
born_pos,
through_wall);
}
if (hero) {
RemoveSurplusHero(buff->meta->i->buff_id(), hero_id, num);
slave_heros_.push_back(std::make_tuple(buff->meta->i->buff_id(), hero));
hero->room->xtimer.AddDeadLineTimerAndAttach
(
life_time / FRAME_RATE_MS,
a8::XParams(),
[] (const a8::XParams& param)
{
},
&hero->xtimer_attacher.timer_list_,
[] (const a8::XParams& param)
{
});
if (can_create) {
InternalSummonHero(buff,
hero_meta,
GetAttackDir(),
born_pos,
through_wall,
num,
life_time);
}
}//end for j
}
@ -2680,42 +2666,99 @@ void Creature::TraverseBuff(std::function<void (Buff*, bool&)> func)
}
}
Hero* Creature::InternalSummonHero(MetaData::Player* hero_meta, a8::Vec2 dir, a8::Vec2 born_pos, bool through_wall)
bool Creature::TrySummonHero(MetaData::Player* hero_meta, a8::Vec2 dir, a8::Vec2 born_pos, bool through_wall)
{
#if 1
AabbCollider collider;
collider._min.x = -hero_meta->i->radius();
collider._min.y = -hero_meta->i->radius();
collider._max.x = hero_meta->i->radius();
collider._max.y = hero_meta->i->radius();
collider.MoveCenter(hero_meta->i->move_offset_x(), hero_meta->i->move_offset_y());
#else
CircleCollider collider;
collider.rad = hero_meta->i->radius();
#endif
if (!room->map_service->CollisionDetection
return !room->map_service->CollisionDetection
(
room,
through_wall,
born_pos,
&collider
)) {
Hero* hero = room->CreateHero
(this,
hero_meta,
born_pos,
dir,
team_id
);
#ifdef DEBUG
SendDebugMsg(a8::Format("summon hero id:%d pos:%f,%f",
{
hero_meta->i->id(),
born_pos.x,
born_pos.y
}));
#endif
return hero;
);
}
Hero* Creature::InternalSummonHero(Buff* buff, MetaData::Player* hero_meta, a8::Vec2 dir, a8::Vec2 born_pos,
bool through_wall, int num, int life_time)
{
struct SummonHeroInfo
{
MetaData::Player* hero_meta = nullptr;
a8::Vec2 dir;
a8::Vec2 born_pos;
bool through_wall = false;
int num = 0;
int life_time = 0;
};
if (TrySummonHero(hero_meta, dir, born_pos, through_wall)) {
int delay_time = 0;
for (auto& tuple : hero_meta->pre_appear_effect) {
delay_time += std::get<1>(tuple);
}
SummonHeroInfo* summon_info = new SummonHeroInfo;
summon_info->hero_meta = hero_meta;
summon_info->dir = dir;
summon_info->born_pos = born_pos;
summon_info->through_wall = through_wall;
summon_info->num = num;
summon_info->life_time = life_time;
room->xtimer.AddDeadLineTimerAndAttach
(
delay_time / FRAME_RATE_MS,
a8::XParams()
.SetSender(buff)
.SetParam1(summon_info),
[] (const a8::XParams& param)
{
Buff* buff = (Buff*)param.sender.GetUserData();
Creature* sender = buff->owner;
SummonHeroInfo* summon_info = (SummonHeroInfo*)param.param1.GetUserData();
Hero* hero = sender->room->CreateHero
(sender,
summon_info->hero_meta,
summon_info->born_pos,
summon_info->dir,
sender->team_id
);
if (!hero) {
return;
}
sender->RemoveSurplusHero(buff->meta->i->buff_id(),
summon_info->hero_meta->i->id(),
summon_info->num);
sender->slave_heros_.push_back(std::make_tuple(buff->meta->i->buff_id(), hero));
hero->room->xtimer.AddDeadLineTimerAndAttach
(
summon_info->life_time / FRAME_RATE_MS,
a8::XParams(),
[] (const a8::XParams& param)
{
},
&hero->xtimer_attacher.timer_list_,
[] (const a8::XParams& param)
{
});
#ifdef DEBUG
sender->SendDebugMsg(a8::Format("summon hero id:%d pos:%f,%f",
{
summon_info->hero_meta->i->id(),
summon_info->born_pos.x,
summon_info->born_pos.y
}));
#endif
},
&buff->xtimer_attacher.timer_list_,
[] (const a8::XParams& param)
{
SummonHeroInfo* summon_info = (SummonHeroInfo*)param.param1.GetUserData();
delete summon_info;
});
}
return nullptr;
}

View File

@ -272,7 +272,9 @@ private:
void RemoveSurplusObstacle(int buff_id, int id, int num);
void CheckAbilityUsed();
void ProcOnceChgAttrBuff(MetaData::Buff* buff_meta);
Hero* InternalSummonHero(MetaData::Player* hero_meta, a8::Vec2 dir, a8::Vec2 born_pos, bool through_wall );
bool TrySummonHero(MetaData::Player* hero_meta, a8::Vec2 dir, a8::Vec2 born_pos, bool through_wall);
Hero* InternalSummonHero(Buff* buff, MetaData::Player* hero_meta, a8::Vec2 dir, a8::Vec2 born_pos,
bool through_wall, int num, int life_time);
void AutoSwitchWeapon();
void CheckLoadingBullet();

View File

@ -626,6 +626,20 @@ namespace MetaData
init_buffs.push_back(a8::XValue(str));
}
}
{
std::vector<std::string> strings;
a8::Split(i->pre_appear_effect(), strings, '|');
for (auto& str : strings) {
std::vector<std::string> strings2;
a8::Split(str, strings2, ':');
assert(strings2.size() == 2);
if (strings2.size() >= 2) {
int thing_id = a8::XValue(strings2[0]);
int time = a8::XValue(strings2[1]);
pre_appear_effect.push_back(std::make_tuple(thing_id, time));
}
}
}
}
int Player::RandDrop()

View File

@ -134,6 +134,7 @@ namespace MetaData
std::array<int, IS_END> volume = {};
std::vector<int> init_buffs;
std::vector<std::tuple<int, int>> dead_drop;
std::vector<std::tuple<int, int>> pre_appear_effect;
bool HasDrop() { return !dead_drop.empty();};
void Init();

View File

@ -235,6 +235,7 @@ message Player
optional int32 ai = 46;
optional int32 delay_remove = 47;
optional int32 skinlist = 48;
optional string pre_appear_effect = 50;
}
message Robot