添加自动切枪逻辑
This commit is contained in:
parent
bac281edd0
commit
5340384caa
@ -1640,6 +1640,7 @@ void Creature::Shot(a8::Vec2& target_dir, bool& shot_ok, float fly_distance)
|
||||
SendDebugMsg(a8::Format("使用武器 %s slot:%d", {GetCurrWeapon()->meta->i->name(), slot_id}));
|
||||
}
|
||||
#endif
|
||||
bool auto_switch_weapon = false;
|
||||
switch (slot_id) {
|
||||
case IS_FRAG: //手雷
|
||||
case IS_SMOKE: //烟雾弹
|
||||
@ -1652,18 +1653,7 @@ void Creature::Shot(a8::Vec2& target_dir, bool& shot_ok, float fly_distance)
|
||||
DecInventory(slot_id, 1);
|
||||
++GetCurrWeapon()->ammo;
|
||||
} else {
|
||||
int weapon_idx = GetCurrWeapon()->weapon_idx;
|
||||
*GetCurrWeapon() = Weapon();
|
||||
GetCurrWeapon()->weapon_idx = weapon_idx;
|
||||
Weapon* next_weapon = ChooseNextWeapon(slot_id, SPEC1_IS_BEGIN, SPEC1_IS_END);
|
||||
if (!next_weapon) {
|
||||
next_weapon = ChooseNextWeapon(SPEC2_IS_BEGIN, SPEC2_IS_BEGIN, SPEC2_IS_END);
|
||||
}
|
||||
if (!next_weapon) {
|
||||
next_weapon = AutoChgWeapon();
|
||||
}
|
||||
SetCurrWeapon(next_weapon);
|
||||
AutoLoadingBullet();
|
||||
auto_switch_weapon = true;
|
||||
}
|
||||
}
|
||||
need_sync_active_player = true;
|
||||
@ -1683,18 +1673,7 @@ void Creature::Shot(a8::Vec2& target_dir, bool& shot_ok, float fly_distance)
|
||||
DecInventory(slot_id, 1);
|
||||
++GetCurrWeapon()->ammo;
|
||||
} else {
|
||||
int weapon_idx = GetCurrWeapon()->weapon_idx;
|
||||
*GetCurrWeapon() = Weapon();
|
||||
GetCurrWeapon()->weapon_idx = weapon_idx;
|
||||
Weapon* next_weapon = ChooseNextWeapon(slot_id, SPEC2_IS_BEGIN, SPEC2_IS_END);
|
||||
if (!next_weapon) {
|
||||
next_weapon = ChooseNextWeapon(SPEC1_IS_BEGIN, SPEC1_IS_BEGIN, SPEC1_IS_END);
|
||||
}
|
||||
if (!next_weapon) {
|
||||
next_weapon = AutoChgWeapon();
|
||||
}
|
||||
SetCurrWeapon(next_weapon);
|
||||
AutoLoadingBullet();
|
||||
auto_switch_weapon = true;
|
||||
}
|
||||
}
|
||||
need_sync_active_player = true;
|
||||
@ -1714,18 +1693,7 @@ void Creature::Shot(a8::Vec2& target_dir, bool& shot_ok, float fly_distance)
|
||||
DecInventory(slot_id, 1);
|
||||
++GetCurrWeapon()->ammo;
|
||||
} else {
|
||||
int weapon_idx = GetCurrWeapon()->weapon_idx;
|
||||
*GetCurrWeapon() = Weapon();
|
||||
GetCurrWeapon()->weapon_idx = weapon_idx;
|
||||
Weapon* next_weapon = ChooseNextWeapon(slot_id, SPEC3_IS_BEGIN, SPEC3_IS_END);
|
||||
if (!next_weapon) {
|
||||
next_weapon = ChooseNextWeapon(SPEC1_IS_BEGIN, SPEC1_IS_BEGIN, SPEC1_IS_END);
|
||||
}
|
||||
if (!next_weapon) {
|
||||
next_weapon = AutoChgWeapon();
|
||||
}
|
||||
SetCurrWeapon(next_weapon);
|
||||
AutoLoadingBullet();
|
||||
auto_switch_weapon = true;
|
||||
}
|
||||
}
|
||||
need_sync_active_player = true;
|
||||
@ -1737,28 +1705,10 @@ void Creature::Shot(a8::Vec2& target_dir, bool& shot_ok, float fly_distance)
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (GetCurrWeapon()->weapon_idx != 0 &&
|
||||
GetCurrWeapon()->ammo <= 0) {
|
||||
if (GetCurrWeapon()->meta->i->reload_delay_time() > 0) {
|
||||
room->xtimer.AddDeadLineTimerAndAttach
|
||||
(
|
||||
GetCurrWeapon()->meta->i->reload_delay_time() / FRAME_RATE_MS,
|
||||
a8::XParams()
|
||||
.SetSender(this)
|
||||
.SetParam1(GetCurrWeapon()->weapon_id),
|
||||
[] (const a8::XParams& param)
|
||||
{
|
||||
Creature* c = (Creature*)param.sender.GetUserData();
|
||||
int weapon_id = param.param1;
|
||||
if (c->GetCurrWeapon()->weapon_id == weapon_id) {
|
||||
c->AutoLoadingBullet();
|
||||
}
|
||||
},
|
||||
&xtimer_attacher.timer_list_
|
||||
);
|
||||
if (auto_switch_weapon) {
|
||||
AutoSwitchWeapon();
|
||||
} else {
|
||||
AutoLoadingBullet();
|
||||
}
|
||||
CheckLoadingBullet();
|
||||
}
|
||||
last_shot_frameno_ = room->GetFrameNo();
|
||||
if ((IsPlayer() || IsCar())) {
|
||||
@ -2089,6 +2039,9 @@ void Creature::SetCurrWeapon(Weapon* weapon)
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
if (auto_switch_weapon_timer_) {
|
||||
room->xtimer.DeleteTimer(auto_switch_weapon_timer_);
|
||||
}
|
||||
if (curr_weapon_ != weapon) {
|
||||
GetTrigger()->TakeonWeapon(curr_weapon_, weapon);
|
||||
}
|
||||
@ -2653,3 +2606,151 @@ std::string Creature::DebugOutBuffList()
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
void Creature::AutoSwitchWeapon()
|
||||
{
|
||||
auto switch_func =
|
||||
[] (const a8::XParams& param)
|
||||
{
|
||||
Creature* c = (Creature*)param.sender.GetUserData();
|
||||
int weapon_idx = param.param1;
|
||||
MetaData::Equip* weapon_meta = (MetaData::Equip*)param.param2.GetUserData();
|
||||
if (!(c->GetCurrWeapon()->weapon_idx == weapon_idx &&
|
||||
c->GetCurrWeapon()->meta == weapon_meta)) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool switch_ok = false;
|
||||
int slot_id = weapon_meta->i->_inventory_slot();
|
||||
switch (slot_id) {
|
||||
case IS_FRAG: //手雷
|
||||
case IS_SMOKE: //烟雾弹
|
||||
{
|
||||
if (c->GetCurrWeapon()->ammo <= 0) {
|
||||
if (c->GetInventory(slot_id) > 0) {
|
||||
} else {
|
||||
int weapon_idx = c->GetCurrWeapon()->weapon_idx;
|
||||
*c->GetCurrWeapon() = Weapon();
|
||||
c->GetCurrWeapon()->weapon_idx = weapon_idx;
|
||||
Weapon* next_weapon = c->ChooseNextWeapon(slot_id, SPEC1_IS_BEGIN, SPEC1_IS_END);
|
||||
if (!next_weapon) {
|
||||
next_weapon = c->ChooseNextWeapon(SPEC2_IS_BEGIN, SPEC2_IS_BEGIN, SPEC2_IS_END);
|
||||
}
|
||||
if (!next_weapon) {
|
||||
next_weapon = c->AutoChgWeapon();
|
||||
}
|
||||
c->SetCurrWeapon(next_weapon);
|
||||
switch_ok = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IS_POSION_GAS_BOMB: //毒气弹
|
||||
case IS_MOLOTOR_COCKTAIL: //燃烧瓶
|
||||
case IS_TRAP: //陷井
|
||||
case IS_MINE: //地雷
|
||||
{
|
||||
if (c->GetCurrWeapon()->ammo <= 0) {
|
||||
if (c->GetInventory(slot_id) > 0) {
|
||||
} else {
|
||||
int weapon_idx = c->GetCurrWeapon()->weapon_idx;
|
||||
*c->GetCurrWeapon() = Weapon();
|
||||
c->GetCurrWeapon()->weapon_idx = weapon_idx;
|
||||
Weapon* next_weapon = c->ChooseNextWeapon(slot_id, SPEC2_IS_BEGIN, SPEC2_IS_END);
|
||||
if (!next_weapon) {
|
||||
next_weapon = c->ChooseNextWeapon(SPEC1_IS_BEGIN, SPEC1_IS_BEGIN, SPEC1_IS_END);
|
||||
}
|
||||
if (!next_weapon) {
|
||||
next_weapon = c->AutoChgWeapon();
|
||||
}
|
||||
c->SetCurrWeapon(next_weapon);
|
||||
switch_ok = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IS_C4:
|
||||
case IS_SHIELD_WALL:
|
||||
case IS_SINGAL_GUN:
|
||||
case IS_OIL_BUCKET:
|
||||
{
|
||||
if (c->GetCurrWeapon()->ammo <= 0) {
|
||||
if (c->GetInventory(slot_id) > 0) {
|
||||
} else {
|
||||
int weapon_idx = c->GetCurrWeapon()->weapon_idx;
|
||||
*c->GetCurrWeapon() = Weapon();
|
||||
c->GetCurrWeapon()->weapon_idx = weapon_idx;
|
||||
Weapon* next_weapon = c->ChooseNextWeapon(slot_id, SPEC3_IS_BEGIN, SPEC3_IS_END);
|
||||
if (!next_weapon) {
|
||||
next_weapon = c->ChooseNextWeapon(SPEC1_IS_BEGIN, SPEC1_IS_BEGIN, SPEC1_IS_END);
|
||||
}
|
||||
if (!next_weapon) {
|
||||
next_weapon = c->AutoChgWeapon();
|
||||
}
|
||||
c->SetCurrWeapon(next_weapon);
|
||||
switch_ok = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (switch_ok) {
|
||||
c->need_sync_active_player = true;
|
||||
c->SyncAroundPlayers(__FILE__, __LINE__, __func__);
|
||||
}
|
||||
c->CheckLoadingBullet();
|
||||
};
|
||||
a8::XParams param;
|
||||
param.SetSender(this);
|
||||
param.SetParam1(GetCurrWeapon()->weapon_idx);
|
||||
param.SetParam2(GetCurrWeapon()->meta);
|
||||
if (GetCurrWeapon()->meta->i->auto_switch_weapon_time() > 0) {
|
||||
if (auto_switch_weapon_timer_) {
|
||||
room->xtimer.DeleteTimer(auto_switch_weapon_timer_);
|
||||
}
|
||||
auto_switch_weapon_timer_ = room->xtimer.AddDeadLineTimerAndAttach
|
||||
(
|
||||
GetCurrWeapon()->meta->i->auto_switch_weapon_time() / FRAME_RATE_MS,
|
||||
param,
|
||||
switch_func,
|
||||
&xtimer_attacher.timer_list_,
|
||||
[] (const a8::XParams& param)
|
||||
{
|
||||
Creature* c = (Creature*)param.sender.GetUserData();
|
||||
c->auto_switch_weapon_timer_ = nullptr;
|
||||
});
|
||||
} else {
|
||||
switch_func(param);
|
||||
}
|
||||
}
|
||||
|
||||
void Creature::CheckLoadingBullet()
|
||||
{
|
||||
if (GetCurrWeapon()->weapon_idx != 0 &&
|
||||
GetCurrWeapon()->ammo <= 0) {
|
||||
if (GetCurrWeapon()->meta->i->reload_delay_time() > 0) {
|
||||
room->xtimer.AddDeadLineTimerAndAttach
|
||||
(
|
||||
GetCurrWeapon()->meta->i->reload_delay_time() / FRAME_RATE_MS,
|
||||
a8::XParams()
|
||||
.SetSender(this)
|
||||
.SetParam1(GetCurrWeapon()->weapon_id),
|
||||
[] (const a8::XParams& param)
|
||||
{
|
||||
Creature* c = (Creature*)param.sender.GetUserData();
|
||||
int weapon_id = param.param1;
|
||||
if (c->GetCurrWeapon()->weapon_id == weapon_id) {
|
||||
c->AutoLoadingBullet();
|
||||
}
|
||||
},
|
||||
&xtimer_attacher.timer_list_
|
||||
);
|
||||
} else {
|
||||
AutoLoadingBullet();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -233,6 +233,8 @@ private:
|
||||
void CheckAbilityUsed();
|
||||
void ProcOnceChgAttrBuff(MetaData::Buff* buff_meta);
|
||||
Hero* InternalSummonHero(MetaData::Player* hero_meta, a8::Vec2 dir, a8::Vec2 born_pos, bool through_wall );
|
||||
void AutoSwitchWeapon();
|
||||
void CheckLoadingBullet();
|
||||
|
||||
protected:
|
||||
RaceType_e race_ = kHumanRace;
|
||||
@ -267,6 +269,7 @@ private:
|
||||
std::list<Buff> buff_list_;
|
||||
std::list<std::tuple<int, Hero*>> slave_heros_;
|
||||
std::list<std::tuple<int, RoomObstacle*>> slave_things_;
|
||||
xtimer_list* auto_switch_weapon_timer_ = nullptr;
|
||||
|
||||
a8::Vec2 skill_dir_;
|
||||
float skill_param1 = 0;
|
||||
|
@ -143,6 +143,7 @@ message Equip
|
||||
optional int32 is_penetrate_thing = 62;
|
||||
optional int32 reload_delay_time = 63;
|
||||
optional int32 cast_time = 64;
|
||||
optional int32 auto_switch_weapon_time = 65;
|
||||
|
||||
optional string inventory_slot = 31; //库存槽位
|
||||
optional int32 _inventory_slot = 32; //库存槽位
|
||||
|
Loading…
x
Reference in New Issue
Block a user