1
This commit is contained in:
parent
52bc8f0b24
commit
f9c023560c
@ -14,426 +14,7 @@
|
||||
#include "car.h"
|
||||
#include "bullet.h"
|
||||
#include "skillhelper.h"
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/vec2.hpp>
|
||||
|
||||
static const auto hero_transform =
|
||||
glm::rotate(
|
||||
glm::mat4(1.0),
|
||||
glm::radians(65.0f),
|
||||
glm::vec3(0.0, 0.0, 1.0)
|
||||
);
|
||||
|
||||
struct BulletInfo
|
||||
{
|
||||
CreatureWeakPtr c;
|
||||
long long weapon_uniid = 0;
|
||||
MetaData::Equip* weapon_meta = nullptr;
|
||||
MetaData::Equip* bullet_meta = nullptr;
|
||||
MetaData::Skill* skill_meta = nullptr;
|
||||
a8::Vec2 bullet_born_pos;
|
||||
a8::Vec2 bullet_dir;
|
||||
float fly_distance = 0;
|
||||
int weapon_lv = 0;
|
||||
int delay_time = 0;
|
||||
int recoil_force = 0;
|
||||
int invincible_buff_uniid = 0;
|
||||
int trace_target_uniid = 0;
|
||||
float track_change_time = 0;
|
||||
int is_through = 0;
|
||||
int hand = 0;
|
||||
float shot_animi_time = 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,
|
||||
glm::vec4& gun_muzzle_position,
|
||||
int bulletIdx,
|
||||
int bulletNum)
|
||||
{
|
||||
if (shot_animi) {
|
||||
if (weapon_meta->i->double_gun()&&
|
||||
bulletIdx > (int)(bulletNum / 2)) {
|
||||
gun_muzzle_position +=
|
||||
glm::vec4(
|
||||
shot_animi->l_x,
|
||||
shot_animi->l_y,
|
||||
shot_animi->l_z,
|
||||
0
|
||||
);
|
||||
} else {
|
||||
if (c->IsCar() && !weapon_meta->i->double_gun()) {
|
||||
switch (c->shot_hole) {
|
||||
case 1:
|
||||
{
|
||||
gun_muzzle_position +=
|
||||
glm::vec4(
|
||||
shot_animi->p3_x,
|
||||
shot_animi->p3_y,
|
||||
shot_animi->p3_z,
|
||||
0
|
||||
);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
gun_muzzle_position +=
|
||||
glm::vec4(
|
||||
shot_animi->p4_x,
|
||||
shot_animi->p4_y,
|
||||
shot_animi->p4_z,
|
||||
0
|
||||
);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
{
|
||||
gun_muzzle_position +=
|
||||
glm::vec4(
|
||||
shot_animi->p5_x,
|
||||
shot_animi->p5_y,
|
||||
shot_animi->p5_z,
|
||||
0
|
||||
);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
gun_muzzle_position +=
|
||||
glm::vec4(
|
||||
shot_animi->r_x,
|
||||
shot_animi->r_y,
|
||||
shot_animi->r_z,
|
||||
0
|
||||
);
|
||||
}
|
||||
}
|
||||
}//end if
|
||||
if (weapon_meta->gun_muzzle_position) {
|
||||
gun_muzzle_position +=
|
||||
#if 1
|
||||
glm::vec4(
|
||||
-std::get<0>(*weapon_meta->gun_muzzle_position.get()),
|
||||
std::get<1>(*weapon_meta->gun_muzzle_position.get()),
|
||||
std::get<2>(*weapon_meta->gun_muzzle_position.get()),
|
||||
0
|
||||
);
|
||||
#else
|
||||
glm::vec4(
|
||||
std::get<0>(*weapon_meta->gun_muzzle_position.get()),
|
||||
std::get<1>(*weapon_meta->gun_muzzle_position.get()),
|
||||
std::get<2>(*weapon_meta->gun_muzzle_position.get()),
|
||||
0
|
||||
);
|
||||
#endif
|
||||
}
|
||||
#if 0
|
||||
if (weapon_meta->movex_position) {
|
||||
gun_muzzle_position -=
|
||||
glm::vec4(
|
||||
std::get<0>(*weapon_meta->movex_position.get()),
|
||||
std::get<1>(*weapon_meta->movex_position.get()),
|
||||
std::get<2>(*weapon_meta->movex_position.get()),
|
||||
0
|
||||
);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void InternalShot(Creature* c,
|
||||
MetaData::Equip* weapon_meta,
|
||||
MetaData::Equip* bullet_meta,
|
||||
MetaData::Skill* skill_meta,
|
||||
float fly_distance,
|
||||
long long weapon_uniid,
|
||||
int trace_target_uniid)
|
||||
{
|
||||
if (weapon_meta->i->_inventory_slot() == IS_TRAP ||
|
||||
weapon_meta->i->_inventory_slot() == IS_MINE) {
|
||||
if (!skill_meta) {
|
||||
c->room->frame_event.AddShot(c->GetWeakPtrRef());
|
||||
}
|
||||
if (weapon_meta->i->cast_time() > 0) {
|
||||
int buff_uniid = c->TryAddBuff(c, kVertigoBuffId);
|
||||
Buff* buff = c->GetBuffByUniId(buff_uniid);
|
||||
if (buff && buff->remover_timer) {
|
||||
c->room->xtimer.ModifyTimer(buff->remover_timer, weapon_meta->i->cast_time() / FRAME_RATE_MS);
|
||||
}
|
||||
}
|
||||
a8::Vec2 old_context_dir = c->context_dir;
|
||||
a8::Vec2 old_context_pos = c->context_pos;
|
||||
c->context_dir =c->GetAttackDir();
|
||||
c->context_pos = c->GetPos() + c->GetAttackDir() * fly_distance;
|
||||
MetaData::Buff * buff_meta = MetaMgr::Instance()->GetBuff(bullet_meta->i->buffid());
|
||||
if (buff_meta) {
|
||||
c->AddBuff(c,
|
||||
buff_meta
|
||||
);
|
||||
}
|
||||
c->context_dir = old_context_dir;
|
||||
c->context_pos = old_context_pos;
|
||||
return;
|
||||
}
|
||||
for (auto& tuple : weapon_meta->bullet_born_offset) {
|
||||
a8::Vec2 bullet_born_offset = a8::Vec2(std::get<0>(tuple), std::get<1>(tuple));
|
||||
float bullet_born_angle = c->GetAttackDir().CalcAngleEx(a8::Vec2::UP);
|
||||
if (c->GetAttackDir().x > 0.00001f) {
|
||||
bullet_born_angle = -bullet_born_angle;
|
||||
}
|
||||
bullet_born_offset.Rotate(bullet_born_angle);
|
||||
a8::Vec2 bullet_born_pos = c->GetPos() + bullet_born_offset;
|
||||
if (c->room->OverBorder(bullet_born_pos, 0.0f)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!skill_meta || weapon_meta->i->equip_type() == EQUIP_TYPE_THROW) {
|
||||
c->room->frame_event.AddShot(c->GetWeakPtrRef());
|
||||
}
|
||||
int invincible_buff_uniid = 0;
|
||||
if (weapon_meta->lock_time > 0) {
|
||||
int buff_uniid = c->TryAddBuff(c, kVertigoBuffId);
|
||||
Buff* buff = c->GetBuffByUniId(buff_uniid);
|
||||
if (buff && buff->remover_timer) {
|
||||
c->room->xtimer.ModifyTimer(buff->remover_timer, weapon_meta->lock_time / FRAME_RATE_MS);
|
||||
}
|
||||
}
|
||||
if (weapon_meta->i->cast_time() > 0) {
|
||||
int buff_uniid = c->TryAddBuff(c, kVertigoBuffId);
|
||||
Buff* buff = c->GetBuffByUniId(buff_uniid);
|
||||
if (buff && buff->remover_timer) {
|
||||
c->room->xtimer.ModifyTimer(buff->remover_timer, weapon_meta->i->cast_time() / FRAME_RATE_MS);
|
||||
}
|
||||
}
|
||||
MetaData::HeroShotAnimation* shot_animi = c->GetHeroMeta() ?
|
||||
c->GetHeroMeta()->GetShotAnimi(weapon_meta->i->shootfire()) : nullptr;
|
||||
std::weak_ptr<a8::XTimerPtr> keep_shot_animi_timer_ptr;
|
||||
{
|
||||
int shot_animi_time = (shot_animi ? shot_animi->t : 0);
|
||||
if (weapon_meta && weapon_meta->i->equip_subtype() == GUN_SUB_EQUIP_TYPE_FLY_HOOk) {
|
||||
keep_shot_animi_timer_ptr = c->TryDelayAddBuff(c, kKeepShotAnimiBuffId, shot_animi_time);
|
||||
}
|
||||
}
|
||||
int bulletIdx = 0;
|
||||
int bulletNum = weapon_meta->bullet_born_offset.size();
|
||||
for (auto& tuple : weapon_meta->bullet_born_offset) {
|
||||
++bulletIdx;
|
||||
a8::Vec2 bullet_born_offset = a8::Vec2(std::get<0>(tuple), std::get<1>(tuple));
|
||||
a8::Vec2 bullet_born_pos = c->GetPos() + c->shoot_offset + bullet_born_offset;
|
||||
a8::Vec2 bullet_dir = c->GetShotDir();
|
||||
float bullet_angle = std::get<2>(tuple);
|
||||
if (weapon_meta->i->bullet_angle() >= 0.10f) {
|
||||
int angle = (int)weapon_meta->i->bullet_angle() * 1000;
|
||||
if (angle > 0) {
|
||||
bullet_angle += (rand() % angle) / 1000.0f * (rand() % 2 == 0 ? 1 : -1);
|
||||
}
|
||||
}
|
||||
bullet_dir.Rotate(bullet_angle / 180.0f);
|
||||
int shot_animi_time = (shot_animi ? shot_animi->t : 0);
|
||||
if (shot_animi_time > 0) {
|
||||
shot_animi_time = std::max(100, shot_animi_time);
|
||||
}
|
||||
{
|
||||
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);
|
||||
CalcGunMuzzlePosition(c, weapon_meta, shot_animi, gun_muzzle_position, bulletIdx, bulletNum);
|
||||
glm::vec4 v = transform * gun_muzzle_position;
|
||||
bullet_born_offset = a8::Vec2(v.z *10*1, v.x*10*-1);
|
||||
bullet_born_pos = c->GetPos() + bullet_born_offset;
|
||||
if (c->IsPlayer() || c->IsCar()) {
|
||||
#ifdef DEBUG
|
||||
a8::XPrintf("idx:%d offset:%f,%f angle:%f old_angle:%f angle_xy:%f,%f %f %f gun_muzzle_position:%f,%f,%f pos:%f,%f gun_id:%d t:%d\n",
|
||||
{
|
||||
bulletIdx,
|
||||
bullet_born_offset.x,
|
||||
bullet_born_offset.y,
|
||||
bullet_born_angle,
|
||||
old_bullet_born_angle,
|
||||
c->GetAttackDir().x,
|
||||
c->GetAttackDir().y,
|
||||
(bullet_born_angle * 180),
|
||||
(bullet_born_angle - glm::radians(90.0f) / A8_PI) * 180,
|
||||
gun_muzzle_position.x,
|
||||
gun_muzzle_position.y,
|
||||
gun_muzzle_position.z,
|
||||
bullet_born_pos.x,
|
||||
bullet_born_pos.y,
|
||||
weapon_meta->i->id(),
|
||||
shot_animi_time
|
||||
});
|
||||
#endif
|
||||
}
|
||||
}
|
||||
{
|
||||
BulletInfo bullet_info;
|
||||
bullet_info.c = c->GetWeakPtrRef();
|
||||
bullet_info.weapon_uniid = weapon_uniid;
|
||||
bullet_info.weapon_meta = weapon_meta;
|
||||
bullet_info.skill_meta = skill_meta;
|
||||
bullet_info.bullet_meta = bullet_meta;
|
||||
bullet_info.bullet_born_pos = bullet_born_pos;
|
||||
bullet_info.bullet_dir = bullet_dir;
|
||||
bullet_info.fly_distance = fly_distance;
|
||||
bullet_info.delay_time = std::get<3>(tuple);
|
||||
bullet_info.recoil_force = std::get<4>(tuple);
|
||||
bullet_info.invincible_buff_uniid = invincible_buff_uniid;
|
||||
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;
|
||||
if (skill_meta &&
|
||||
(skill_meta->GetMagicId() == MAGIC_AXXF ||
|
||||
skill_meta->GetMagicId() == MAGIC_HJHX)) {
|
||||
bullet_info.trace_target_uniid = c->GetSkillTargetId();
|
||||
}
|
||||
if (weapon_meta->i->double_gun() &&
|
||||
bulletIdx > (int)(bulletNum / 2)) {
|
||||
bullet_info.hand = 1;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
if (bullet_info.trace_target_uniid) {
|
||||
a8::XPrintf("bullet trace_target_uniid:%d\n", {bullet_info.trace_target_uniid});
|
||||
}
|
||||
#endif
|
||||
InternalCreateBullet(bullet_info);
|
||||
}
|
||||
}
|
||||
c->GetTrigger()->Shot(weapon_meta);
|
||||
if (weapon_meta->i->recoil_force() > 0.000001) {
|
||||
c->DoRecoilForce(weapon_meta->i->recoil_force());
|
||||
}
|
||||
if (c->HasBuffEffect(kBET_Hide)) {
|
||||
c->RemoveBuffByEffectId(kBET_Hide);
|
||||
}
|
||||
if (trace_target_uniid) {
|
||||
c->LockAttackDir(1000);
|
||||
}
|
||||
if (c->aiming) {
|
||||
c->aiming = false;
|
||||
c->aiming_frameno = 0;
|
||||
c->power_idx = -1;
|
||||
c->ClearAimingBuffs();
|
||||
}
|
||||
}
|
||||
#include "shot.h"
|
||||
|
||||
Creature::Creature():MoveableEntity()
|
||||
{
|
||||
|
@ -372,11 +372,3 @@ private:
|
||||
friend class Skill;
|
||||
friend class Trigger;
|
||||
};
|
||||
|
||||
void InternalShot(Creature* sender,
|
||||
MetaData::Equip* weapon_meta,
|
||||
MetaData::Equip* bullet_meta,
|
||||
MetaData::Skill* skill_meta,
|
||||
float fly_distance,
|
||||
long long weapon_uniid,
|
||||
int trace_target_uniid);
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "tracemgr.h"
|
||||
#include "httpproxy.h"
|
||||
#include "skillhelper.h"
|
||||
#include "shot.h"
|
||||
|
||||
const int kReviveTimeAdd = 12;
|
||||
const int kSkinNum = 4;
|
||||
|
426
server/gameserver/shot.cc
Normal file
426
server/gameserver/shot.cc
Normal file
@ -0,0 +1,426 @@
|
||||
#include "precompile.h"
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/vec2.hpp>
|
||||
|
||||
#include "shot.h"
|
||||
#include "metamgr.h"
|
||||
#include "creature.h"
|
||||
#include "room.h"
|
||||
|
||||
static const auto hero_transform =
|
||||
glm::rotate(
|
||||
glm::mat4(1.0),
|
||||
glm::radians(65.0f),
|
||||
glm::vec3(0.0, 0.0, 1.0)
|
||||
);
|
||||
|
||||
struct BulletInfo
|
||||
{
|
||||
CreatureWeakPtr c;
|
||||
long long weapon_uniid = 0;
|
||||
MetaData::Equip* weapon_meta = nullptr;
|
||||
MetaData::Equip* bullet_meta = nullptr;
|
||||
MetaData::Skill* skill_meta = nullptr;
|
||||
a8::Vec2 bullet_born_pos;
|
||||
a8::Vec2 bullet_dir;
|
||||
float fly_distance = 0;
|
||||
int weapon_lv = 0;
|
||||
int delay_time = 0;
|
||||
int recoil_force = 0;
|
||||
int invincible_buff_uniid = 0;
|
||||
int trace_target_uniid = 0;
|
||||
float track_change_time = 0;
|
||||
int is_through = 0;
|
||||
int hand = 0;
|
||||
float shot_animi_time = 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,
|
||||
glm::vec4& gun_muzzle_position,
|
||||
int bulletIdx,
|
||||
int bulletNum)
|
||||
{
|
||||
if (shot_animi) {
|
||||
if (weapon_meta->i->double_gun()&&
|
||||
bulletIdx > (int)(bulletNum / 2)) {
|
||||
gun_muzzle_position +=
|
||||
glm::vec4(
|
||||
shot_animi->l_x,
|
||||
shot_animi->l_y,
|
||||
shot_animi->l_z,
|
||||
0
|
||||
);
|
||||
} else {
|
||||
if (c->IsCar() && !weapon_meta->i->double_gun()) {
|
||||
switch (c->shot_hole) {
|
||||
case 1:
|
||||
{
|
||||
gun_muzzle_position +=
|
||||
glm::vec4(
|
||||
shot_animi->p3_x,
|
||||
shot_animi->p3_y,
|
||||
shot_animi->p3_z,
|
||||
0
|
||||
);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
gun_muzzle_position +=
|
||||
glm::vec4(
|
||||
shot_animi->p4_x,
|
||||
shot_animi->p4_y,
|
||||
shot_animi->p4_z,
|
||||
0
|
||||
);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
{
|
||||
gun_muzzle_position +=
|
||||
glm::vec4(
|
||||
shot_animi->p5_x,
|
||||
shot_animi->p5_y,
|
||||
shot_animi->p5_z,
|
||||
0
|
||||
);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
gun_muzzle_position +=
|
||||
glm::vec4(
|
||||
shot_animi->r_x,
|
||||
shot_animi->r_y,
|
||||
shot_animi->r_z,
|
||||
0
|
||||
);
|
||||
}
|
||||
}
|
||||
}//end if
|
||||
if (weapon_meta->gun_muzzle_position) {
|
||||
gun_muzzle_position +=
|
||||
#if 1
|
||||
glm::vec4(
|
||||
-std::get<0>(*weapon_meta->gun_muzzle_position.get()),
|
||||
std::get<1>(*weapon_meta->gun_muzzle_position.get()),
|
||||
std::get<2>(*weapon_meta->gun_muzzle_position.get()),
|
||||
0
|
||||
);
|
||||
#else
|
||||
glm::vec4(
|
||||
std::get<0>(*weapon_meta->gun_muzzle_position.get()),
|
||||
std::get<1>(*weapon_meta->gun_muzzle_position.get()),
|
||||
std::get<2>(*weapon_meta->gun_muzzle_position.get()),
|
||||
0
|
||||
);
|
||||
#endif
|
||||
}
|
||||
#if 0
|
||||
if (weapon_meta->movex_position) {
|
||||
gun_muzzle_position -=
|
||||
glm::vec4(
|
||||
std::get<0>(*weapon_meta->movex_position.get()),
|
||||
std::get<1>(*weapon_meta->movex_position.get()),
|
||||
std::get<2>(*weapon_meta->movex_position.get()),
|
||||
0
|
||||
);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void InternalShot(Creature* c,
|
||||
MetaData::Equip* weapon_meta,
|
||||
MetaData::Equip* bullet_meta,
|
||||
MetaData::Skill* skill_meta,
|
||||
float fly_distance,
|
||||
long long weapon_uniid,
|
||||
int trace_target_uniid)
|
||||
{
|
||||
if (weapon_meta->i->_inventory_slot() == IS_TRAP ||
|
||||
weapon_meta->i->_inventory_slot() == IS_MINE) {
|
||||
if (!skill_meta) {
|
||||
c->room->frame_event.AddShot(c->GetWeakPtrRef());
|
||||
}
|
||||
if (weapon_meta->i->cast_time() > 0) {
|
||||
int buff_uniid = c->TryAddBuff(c, kVertigoBuffId);
|
||||
Buff* buff = c->GetBuffByUniId(buff_uniid);
|
||||
if (buff && buff->remover_timer) {
|
||||
c->room->xtimer.ModifyTimer(buff->remover_timer, weapon_meta->i->cast_time() / FRAME_RATE_MS);
|
||||
}
|
||||
}
|
||||
a8::Vec2 old_context_dir = c->context_dir;
|
||||
a8::Vec2 old_context_pos = c->context_pos;
|
||||
c->context_dir =c->GetAttackDir();
|
||||
c->context_pos = c->GetPos() + c->GetAttackDir() * fly_distance;
|
||||
MetaData::Buff * buff_meta = MetaMgr::Instance()->GetBuff(bullet_meta->i->buffid());
|
||||
if (buff_meta) {
|
||||
c->AddBuff(c,
|
||||
buff_meta
|
||||
);
|
||||
}
|
||||
c->context_dir = old_context_dir;
|
||||
c->context_pos = old_context_pos;
|
||||
return;
|
||||
}
|
||||
for (auto& tuple : weapon_meta->bullet_born_offset) {
|
||||
a8::Vec2 bullet_born_offset = a8::Vec2(std::get<0>(tuple), std::get<1>(tuple));
|
||||
float bullet_born_angle = c->GetAttackDir().CalcAngleEx(a8::Vec2::UP);
|
||||
if (c->GetAttackDir().x > 0.00001f) {
|
||||
bullet_born_angle = -bullet_born_angle;
|
||||
}
|
||||
bullet_born_offset.Rotate(bullet_born_angle);
|
||||
a8::Vec2 bullet_born_pos = c->GetPos() + bullet_born_offset;
|
||||
if (c->room->OverBorder(bullet_born_pos, 0.0f)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!skill_meta || weapon_meta->i->equip_type() == EQUIP_TYPE_THROW) {
|
||||
c->room->frame_event.AddShot(c->GetWeakPtrRef());
|
||||
}
|
||||
int invincible_buff_uniid = 0;
|
||||
if (weapon_meta->lock_time > 0) {
|
||||
int buff_uniid = c->TryAddBuff(c, kVertigoBuffId);
|
||||
Buff* buff = c->GetBuffByUniId(buff_uniid);
|
||||
if (buff && buff->remover_timer) {
|
||||
c->room->xtimer.ModifyTimer(buff->remover_timer, weapon_meta->lock_time / FRAME_RATE_MS);
|
||||
}
|
||||
}
|
||||
if (weapon_meta->i->cast_time() > 0) {
|
||||
int buff_uniid = c->TryAddBuff(c, kVertigoBuffId);
|
||||
Buff* buff = c->GetBuffByUniId(buff_uniid);
|
||||
if (buff && buff->remover_timer) {
|
||||
c->room->xtimer.ModifyTimer(buff->remover_timer, weapon_meta->i->cast_time() / FRAME_RATE_MS);
|
||||
}
|
||||
}
|
||||
MetaData::HeroShotAnimation* shot_animi = c->GetHeroMeta() ?
|
||||
c->GetHeroMeta()->GetShotAnimi(weapon_meta->i->shootfire()) : nullptr;
|
||||
std::weak_ptr<a8::XTimerPtr> keep_shot_animi_timer_ptr;
|
||||
{
|
||||
int shot_animi_time = (shot_animi ? shot_animi->t : 0);
|
||||
if (weapon_meta && weapon_meta->i->equip_subtype() == GUN_SUB_EQUIP_TYPE_FLY_HOOk) {
|
||||
keep_shot_animi_timer_ptr = c->TryDelayAddBuff(c, kKeepShotAnimiBuffId, shot_animi_time);
|
||||
}
|
||||
}
|
||||
int bulletIdx = 0;
|
||||
int bulletNum = weapon_meta->bullet_born_offset.size();
|
||||
for (auto& tuple : weapon_meta->bullet_born_offset) {
|
||||
++bulletIdx;
|
||||
a8::Vec2 bullet_born_offset = a8::Vec2(std::get<0>(tuple), std::get<1>(tuple));
|
||||
a8::Vec2 bullet_born_pos = c->GetPos() + c->shoot_offset + bullet_born_offset;
|
||||
a8::Vec2 bullet_dir = c->GetShotDir();
|
||||
float bullet_angle = std::get<2>(tuple);
|
||||
if (weapon_meta->i->bullet_angle() >= 0.10f) {
|
||||
int angle = (int)weapon_meta->i->bullet_angle() * 1000;
|
||||
if (angle > 0) {
|
||||
bullet_angle += (rand() % angle) / 1000.0f * (rand() % 2 == 0 ? 1 : -1);
|
||||
}
|
||||
}
|
||||
bullet_dir.Rotate(bullet_angle / 180.0f);
|
||||
int shot_animi_time = (shot_animi ? shot_animi->t : 0);
|
||||
if (shot_animi_time > 0) {
|
||||
shot_animi_time = std::max(100, shot_animi_time);
|
||||
}
|
||||
{
|
||||
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);
|
||||
CalcGunMuzzlePosition(c, weapon_meta, shot_animi, gun_muzzle_position, bulletIdx, bulletNum);
|
||||
glm::vec4 v = transform * gun_muzzle_position;
|
||||
bullet_born_offset = a8::Vec2(v.z *10*1, v.x*10*-1);
|
||||
bullet_born_pos = c->GetPos() + bullet_born_offset;
|
||||
if (c->IsPlayer() || c->IsCar()) {
|
||||
#ifdef DEBUG
|
||||
a8::XPrintf("idx:%d offset:%f,%f angle:%f old_angle:%f angle_xy:%f,%f %f %f gun_muzzle_position:%f,%f,%f pos:%f,%f gun_id:%d t:%d\n",
|
||||
{
|
||||
bulletIdx,
|
||||
bullet_born_offset.x,
|
||||
bullet_born_offset.y,
|
||||
bullet_born_angle,
|
||||
old_bullet_born_angle,
|
||||
c->GetAttackDir().x,
|
||||
c->GetAttackDir().y,
|
||||
(bullet_born_angle * 180),
|
||||
(bullet_born_angle - glm::radians(90.0f) / A8_PI) * 180,
|
||||
gun_muzzle_position.x,
|
||||
gun_muzzle_position.y,
|
||||
gun_muzzle_position.z,
|
||||
bullet_born_pos.x,
|
||||
bullet_born_pos.y,
|
||||
weapon_meta->i->id(),
|
||||
shot_animi_time
|
||||
});
|
||||
#endif
|
||||
}
|
||||
}
|
||||
{
|
||||
BulletInfo bullet_info;
|
||||
bullet_info.c = c->GetWeakPtrRef();
|
||||
bullet_info.weapon_uniid = weapon_uniid;
|
||||
bullet_info.weapon_meta = weapon_meta;
|
||||
bullet_info.skill_meta = skill_meta;
|
||||
bullet_info.bullet_meta = bullet_meta;
|
||||
bullet_info.bullet_born_pos = bullet_born_pos;
|
||||
bullet_info.bullet_dir = bullet_dir;
|
||||
bullet_info.fly_distance = fly_distance;
|
||||
bullet_info.delay_time = std::get<3>(tuple);
|
||||
bullet_info.recoil_force = std::get<4>(tuple);
|
||||
bullet_info.invincible_buff_uniid = invincible_buff_uniid;
|
||||
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;
|
||||
if (skill_meta &&
|
||||
(skill_meta->GetMagicId() == MAGIC_AXXF ||
|
||||
skill_meta->GetMagicId() == MAGIC_HJHX)) {
|
||||
bullet_info.trace_target_uniid = c->GetSkillTargetId();
|
||||
}
|
||||
if (weapon_meta->i->double_gun() &&
|
||||
bulletIdx > (int)(bulletNum / 2)) {
|
||||
bullet_info.hand = 1;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
if (bullet_info.trace_target_uniid) {
|
||||
a8::XPrintf("bullet trace_target_uniid:%d\n", {bullet_info.trace_target_uniid});
|
||||
}
|
||||
#endif
|
||||
InternalCreateBullet(bullet_info);
|
||||
}
|
||||
}
|
||||
c->GetTrigger()->Shot(weapon_meta);
|
||||
if (weapon_meta->i->recoil_force() > 0.000001) {
|
||||
c->DoRecoilForce(weapon_meta->i->recoil_force());
|
||||
}
|
||||
if (c->HasBuffEffect(kBET_Hide)) {
|
||||
c->RemoveBuffByEffectId(kBET_Hide);
|
||||
}
|
||||
if (trace_target_uniid) {
|
||||
c->LockAttackDir(1000);
|
||||
}
|
||||
if (c->aiming) {
|
||||
c->aiming = false;
|
||||
c->aiming_frameno = 0;
|
||||
c->power_idx = -1;
|
||||
c->ClearAimingBuffs();
|
||||
}
|
||||
}
|
17
server/gameserver/shot.h
Normal file
17
server/gameserver/shot.h
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
namespace MetaData
|
||||
{
|
||||
struct Equip;
|
||||
struct Skill;
|
||||
};
|
||||
|
||||
class Creature;
|
||||
|
||||
void InternalShot(Creature* sender,
|
||||
MetaData::Equip* weapon_meta,
|
||||
MetaData::Equip* bullet_meta,
|
||||
MetaData::Skill* skill_meta,
|
||||
float fly_distance,
|
||||
long long weapon_uniid,
|
||||
int trace_target_uniid);
|
Loading…
x
Reference in New Issue
Block a user