This commit is contained in:
aozhiwei 2022-10-25 17:36:53 +08:00
parent 6f326df431
commit 59734add35
3 changed files with 143 additions and 102 deletions

View File

@ -551,3 +551,8 @@ void Car::OnKillTarget(Creature* target)
}
}
}
bool Car::IsSingle()
{
return meta->int_param2 <= 1;
}

View File

@ -53,6 +53,7 @@ class Car : public Creature
virtual const a8::Vec2& GetShotDir() { return curr_shot_dir_; };
void OnKillTarget(Creature* target);
void SetShotDir(const a8::Vec2& dir) { curr_shot_dir_ = dir; };
bool IsSingle();
private:
int AllocSeat();

View File

@ -8,6 +8,7 @@
#include "metamgr.h"
#include "creature.h"
#include "room.h"
#include "car.h"
static const auto hero_transform =
glm::rotate(
@ -35,111 +36,12 @@ struct BulletInfo
int is_through = 0;
int hand = 0;
float shot_animi_time = 0;
MetaData::HeroShotAnimation* shot_animi = nullptr;
int bullet_idx = 0;
int bullet_num = 0;
std::weak_ptr<a8::XTimerPtr> keep_shot_animi_timer_ptr;
};
static void InternalCreateBullet(BulletInfo& bullet_info)
{
if (!bullet_info.c.Get()) {
return;
}
Creature* c = bullet_info.c.Get();
if (c->dead) {
return;
}
if (c->downed) {
return;
}
if (bullet_info.delay_time <= 0) {
if (c->GetCurrWeapon()->meta->i->bullet_consume_type() == kBulletConsumeMulti) {
if (c->GetCurrWeapon()->ammo <= 0) {
return;
}
--c->GetCurrWeapon()->ammo;
if (c->GetCurrWeapon()->ammo <= 0) {
c->AutoLoadingBullet();
}
if ((c->IsPlayer() || c->IsCar())) {
c->room->frame_event.AddBulletNumChg(c->GetWeakPtrRef());
c->room->frame_event.AddWeaponAmmoChg(c->GetWeakPtrRef());
}
}
if (bullet_info.recoil_force > 0) {
if (c->GetCurrWeapon()->ammo <= 0) {
c->DoRecoilForce(bullet_info.recoil_force);
bullet_info.bullet_born_pos = bullet_info.bullet_born_pos -
(bullet_info.bullet_dir * bullet_info.recoil_force);
}
}
int bullet_uniid = 0;
if (MetaMgr::Instance()->prebattle_can_use_skill ||
!(c->HasBuffEffect(kBET_Jump) || c->HasBuffEffect(kBET_Fly))) {
bullet_uniid = c->room->CreateBullet
(c,
c->shot_passenger,
bullet_info.weapon_meta,
bullet_info.bullet_meta,
bullet_info.skill_meta,
bullet_info.bullet_born_pos,
bullet_info.bullet_dir,
bullet_info.fly_distance,
bullet_info.weapon_uniid,
bullet_info.trace_target_uniid,
bullet_info.hand,
bullet_info.keep_shot_animi_timer_ptr,
bullet_info.shot_animi_time);
#ifdef DEBUG1
if (bullet_info.c.Get()->IsPlayer()) {
bullet_info.c.Get()->SendDebugMsg(a8::Format("CreateBullet id:%d",
{bullet_info.weapon_meta->i->id()}));
}
#endif
}
bullet_uniid = bullet_uniid ? bullet_uniid : c->room->AllocUniid();
c->room->frame_event.AddBullet
(bullet_uniid,
c->GetWeakPtrRef(),
bullet_info.weapon_meta,
bullet_info.weapon_lv,
bullet_info.bullet_born_pos,
bullet_info.bullet_dir,
bullet_info.fly_distance,
bullet_info.trace_target_uniid,
bullet_info.hand);
if (bullet_uniid && bullet_info.trace_target_uniid) {
c->AddTraceBullet(
bullet_uniid,
bullet_info.trace_target_uniid,
bullet_info.weapon_meta->i->id()
);
}
} else {
BulletInfo* info_copy = new BulletInfo();
*info_copy = bullet_info;
xtimer_list* timer = bullet_info.c.Get()->room->xtimer.AddDeadLineTimerAndAttach
(
bullet_info.delay_time / FRAME_RATE_MS,
a8::XParams()
.SetSender(info_copy),
[] (const a8::XParams& param)
{
BulletInfo* info_copy = (BulletInfo*)param.sender.GetUserData();
info_copy->delay_time = 0;
InternalCreateBullet(*info_copy);
},
&bullet_info.c.Get()->xtimer_attacher.timer_list_,
[] (const a8::XParams& param)
{
BulletInfo* info_copy = (BulletInfo*)param.sender.GetUserData();
delete info_copy;
}
);
if (!c->room->BattleStarted()) {
c->room->AddToPostBattleAutoFreeList(timer);
}
}
}
static void CalcGunMuzzlePosition(Creature* c,
MetaData::Equip* weapon_meta,
MetaData::HeroShotAnimation* shot_animi,
@ -240,6 +142,136 @@ static void CalcGunMuzzlePosition(Creature* c,
#endif
}
static void InternalCreateBullet(BulletInfo& bullet_info)
{
if (!bullet_info.c.Get()) {
return;
}
Creature* c = bullet_info.c.Get();
if (c->dead) {
return;
}
if (c->downed) {
return;
}
if (bullet_info.delay_time <= 0) {
if (c->GetCurrWeapon()->meta->i->bullet_consume_type() == kBulletConsumeMulti) {
if (c->GetCurrWeapon()->ammo <= 0) {
return;
}
--c->GetCurrWeapon()->ammo;
if (c->GetCurrWeapon()->ammo <= 0) {
c->AutoLoadingBullet();
}
if ((c->IsPlayer() || c->IsCar())) {
c->room->frame_event.AddBulletNumChg(c->GetWeakPtrRef());
c->room->frame_event.AddWeaponAmmoChg(c->GetWeakPtrRef());
}
}
if (bullet_info.recoil_force > 0) {
if (c->GetCurrWeapon()->ammo <= 0) {
c->DoRecoilForce(bullet_info.recoil_force);
bullet_info.bullet_born_pos = bullet_info.bullet_born_pos -
(bullet_info.bullet_dir * bullet_info.recoil_force);
}
}
if (c->IsCar() && c->AsCar()->IsSingle()) {
a8::Vec2 bullet_born_offset;
bool is_player = c->IsPlayer();
bool is_car = c->IsCar();
float bullet_born_angle = c->GetAttackDir().CalcAngleEx(a8::Vec2::RIGHT);
if (c->GetAttackDir().y > 0.00001f) {
bullet_born_angle = -bullet_born_angle;
}
float old_bullet_born_angle = bullet_born_angle;
bullet_born_offset.Rotate(bullet_born_angle);
auto transform = glm::rotate(hero_transform,
bullet_born_angle * A8_PI,
glm::vec3(0.0, 1.0, 0.0));
glm::vec4 gun_muzzle_position(0.0, 0.0, 0.0, 0.0);
#if 1
CalcGunMuzzlePosition(c,
bullet_info.weapon_meta,
bullet_info.shot_animi,
gun_muzzle_position,
bullet_info.bullet_idx,
bullet_info.bullet_num);
#endif
glm::vec4 v = transform * gun_muzzle_position;
bullet_born_offset = a8::Vec2(v.z *10*1, v.x*10*-1);
bullet_info.bullet_born_pos = c->GetPos() + bullet_born_offset;
bullet_info.bullet_dir = c->GetShotDir();
}
int bullet_uniid = 0;
if (MetaMgr::Instance()->prebattle_can_use_skill ||
!(c->HasBuffEffect(kBET_Jump) || c->HasBuffEffect(kBET_Fly))) {
bullet_uniid = c->room->CreateBullet
(c,
c->shot_passenger,
bullet_info.weapon_meta,
bullet_info.bullet_meta,
bullet_info.skill_meta,
bullet_info.bullet_born_pos,
bullet_info.bullet_dir,
bullet_info.fly_distance,
bullet_info.weapon_uniid,
bullet_info.trace_target_uniid,
bullet_info.hand,
bullet_info.keep_shot_animi_timer_ptr,
bullet_info.shot_animi_time);
#ifdef DEBUG1
if (bullet_info.c.Get()->IsPlayer()) {
bullet_info.c.Get()->SendDebugMsg(a8::Format("CreateBullet id:%d",
{bullet_info.weapon_meta->i->id()}));
}
#endif
}
bullet_uniid = bullet_uniid ? bullet_uniid : c->room->AllocUniid();
c->room->frame_event.AddBullet
(bullet_uniid,
c->GetWeakPtrRef(),
bullet_info.weapon_meta,
bullet_info.weapon_lv,
bullet_info.bullet_born_pos,
bullet_info.bullet_dir,
bullet_info.fly_distance,
bullet_info.trace_target_uniid,
bullet_info.hand);
if (bullet_uniid && bullet_info.trace_target_uniid) {
c->AddTraceBullet(
bullet_uniid,
bullet_info.trace_target_uniid,
bullet_info.weapon_meta->i->id()
);
}
} else {
BulletInfo* info_copy = new BulletInfo();
*info_copy = bullet_info;
xtimer_list* timer = bullet_info.c.Get()->room->xtimer.AddDeadLineTimerAndAttach
(
bullet_info.delay_time / FRAME_RATE_MS,
a8::XParams()
.SetSender(info_copy),
[] (const a8::XParams& param)
{
BulletInfo* info_copy = (BulletInfo*)param.sender.GetUserData();
info_copy->delay_time = 0;
InternalCreateBullet(*info_copy);
},
&bullet_info.c.Get()->xtimer_attacher.timer_list_,
[] (const a8::XParams& param)
{
BulletInfo* info_copy = (BulletInfo*)param.sender.GetUserData();
delete info_copy;
}
);
if (!c->room->BattleStarted()) {
c->room->AddToPostBattleAutoFreeList(timer);
}
}
}
void InternalShot(Creature* c,
MetaData::Equip* weapon_meta,
MetaData::Equip* bullet_meta,
@ -394,6 +426,9 @@ void InternalShot(Creature* c,
bullet_info.trace_target_uniid = trace_target_uniid;
bullet_info.keep_shot_animi_timer_ptr = keep_shot_animi_timer_ptr;
bullet_info.shot_animi_time = shot_animi_time;
bullet_info.shot_animi = shot_animi;
bullet_info.bullet_idx = bulletIdx;
bullet_info.bullet_num = bulletNum;
if (skill_meta &&
(skill_meta->GetMagicId() == MAGIC_AXXF ||
skill_meta->GetMagicId() == MAGIC_HJHX)