This commit is contained in:
aozhiwei 2019-05-17 12:00:31 +08:00
parent 6dfeb77c1e
commit 1656f6000c
9 changed files with 176 additions and 143 deletions

View File

@ -118,8 +118,10 @@ void AndroidAI::DoAttack()
Human* enemy = owner->room->FindEnemy((Human*)owner);
if (enemy) {
Human* sender = (Human*)owner;
Vector2D shot_dir = enemy->pos;
Vector2D shot_dir = enemy->pos - sender->pos;
shot_dir.Normalize();
shot_dir.Rotate((rand() % 10) / 180.0f);
sender->attack_dir = shot_dir;
sender->Shot(shot_dir);
}
}

View File

@ -24,6 +24,15 @@ void Android::Initialize()
health = meta->i->health();
skin = 14001;
RecalcSelfCollider();
MetaData::Equip* weapon_meta = MetaMgr::Instance()->GetEquip(a8::RandEx(12103, 12122));
if (weapon_meta) {
weapons[GUN_SLOT1].weapon_idx = GUN_SLOT1;
weapons[GUN_SLOT1].weapon_id = weapon_meta->i->id();
weapons[GUN_SLOT1].weapon_lv = 1;
weapons[GUN_SLOT1].ammo = 0;
weapons[GUN_SLOT1].meta = weapon_meta;
curr_weapon = &weapons[GUN_SLOT1];
}
}
void Android::Update(int delta_time)
@ -32,5 +41,8 @@ void Android::Update(int delta_time)
pos = room->plane.curr_pos;
room->grid_service.MoveHuman(this);
}
if (action_type != AT_None) {
UpdateAction();
}
ai->Update(delta_time);
}

View File

@ -192,6 +192,12 @@ void Human::Shot(Vector2D& target_dir)
Vector2D bullet_born_offset = Vector2D(std::get<0>(tuple), std::get<1>(tuple));
bullet_born_offset.Rotate(attack_dir.CalcAngle(Vector2D::UP));
Vector2D bullet_born_pos = pos + bullet_born_offset;
Vector2D bullet_dir = attack_dir;
float bullet_angle = std::get<2>(tuple);
if (curr_weapon->meta->i->bullet_angle() >= 1.0f) {
bullet_angle += (rand() % (int)curr_weapon->meta->i->bullet_angle()) * (rand() % 2 == 0 ? 1 : -1);
}
bullet_dir.Rotate(bullet_angle / 180.0f);
room->frame_event.AddBullet(this, bullet_born_pos, attack_dir, fly_distance);
room->CreateBullet(this, curr_weapon->meta, bullet_born_pos, attack_dir, fly_distance);
}
@ -1472,6 +1478,140 @@ void Human::SendRollMsg(const std::string& roll_msg)
);
}
void Human::UpdateAction()
{
int duration = std::max(0,
action_duration -
(int)((room->frame_no - action_frameno) * 1.0f / SERVER_FRAME_RATE) * 1000
);
if (duration <= 0) {
switch (action_type) {
case AT_Reload:
{
if (curr_weapon->weapon_idx == action_target_id &&
curr_weapon->weapon_id == action_item_id &&
curr_weapon->weapon_idx != 0) {
MetaData::Equip* bullet_meta = MetaMgr::Instance()->GetEquip(curr_weapon->meta->i->use_bullet());
if (bullet_meta) {
int ammo = curr_weapon->ammo;
if (ammo < curr_weapon->meta->i->clip_volume()) {
if (bullet_meta->i->_inventory_slot() >= 0 &&
bullet_meta->i->_inventory_slot() < IS_END) {
if (GetInventory(bullet_meta->i->_inventory_slot()) > 0) {
int add_num = 0;
if (GetInventory(bullet_meta->i->_inventory_slot()) <=
curr_weapon->meta->i->clip_volume() - ammo) {
add_num = GetInventory(bullet_meta->i->_inventory_slot());
DecInventory(bullet_meta->i->_inventory_slot(), add_num);
} else {
add_num = curr_weapon->meta->i->clip_volume() - ammo;
DecInventory(bullet_meta->i->_inventory_slot(), add_num);
}
curr_weapon->ammo += add_num;
need_sync_active_player = true;;
}
}
}
}
}
}
break;
case AT_UseItem:
{
switch (action_item_id) {
case IS_HEALTHKIT:
{
MetaData::Equip* item_meta = MetaMgr::Instance()->GetEquipBySlotId(action_item_id);
if (item_meta){
if (GetInventory(item_meta->i->_inventory_slot()) > 0) {
float old_health = health;
health += item_meta->i->heal();
health = std::min(health, GetMaxHP());
stats.heal_amount += health - old_health;
DecInventory(item_meta->i->_inventory_slot(), 1);
need_sync_active_player = true;
SyncAroundPlayers();
}
}
}
break;
case IS_PAIN_KILLER:
{
MetaData::Equip* item_meta = MetaMgr::Instance()->GetEquipBySlotId(action_item_id);
if (item_meta){
if (GetInventory(item_meta->i->_inventory_slot()) > 0) {
if (pain_killer_timer) {
int passed_time = (room->frame_no - pain_killer_frameno) * FRAME_RATE_MS;
int left_time = std::max(0, pain_killer_lastingtime * 1000 - passed_time);
int anodyne_max_time = MetaMgr::Instance()->GetSysParamAsInt("anodyne_max_time");
left_time = std::min(left_time, anodyne_max_time * 1000);
pain_killer_lastingtime += std::min(item_meta->i->time() * 1000, anodyne_max_time * 1000 - left_time) / 1000;
need_sync_active_player = true;
} else {
pain_killer_frameno = room->frame_no;
pain_killer_lastingtime = item_meta->i->time();
pain_killer_timer = room->xtimer.AddRepeatTimerAndAttach(
SERVER_FRAME_RATE,
a8::XParams()
.SetSender(this)
.SetParam1(item_meta->i->heal()),
[] (const a8::XParams& param)
{
Human* hum = (Human*)param.sender.GetUserData();
float old_health = hum->health;
hum->health += param.param1.GetDouble();
hum->health = std::min(hum->health, hum->GetMaxHP());
hum->stats.heal_amount += hum->health - old_health;
hum->SyncAroundPlayers();
if (hum->room->frame_no - hum->pain_killer_frameno > hum->pain_killer_lastingtime * SERVER_FRAME_RATE) {
hum->room->xtimer.DeleteTimer(hum->pain_killer_timer);
hum->pain_killer_timer = nullptr;
}
},
&xtimer_attacher.timer_list_
);
}
DecInventory(item_meta->i->_inventory_slot(), 1);
need_sync_active_player = true;
}
}
}
break;
default:
{
}
break;
}
}
break;
case AT_Relive:
{
Entity* entity = room->GetEntityByUniId(action_target_id);
if (entity->entity_type != ET_Player) {
return;
}
Human* hum = (Human*)entity;
if (hum->action_type == AT_Rescue) {
hum->CancelAction();
return;
}
if (!hum->dead && hum->downed) {
hum->health = MetaMgr::Instance()->GetSysParamAsInt("downed_relive_recover_hp");
hum->downed = false;
if (hum->downed_timer) {
room->xtimer.DeleteTimer(hum->downed_timer);
hum->downed_timer = nullptr;
}
++hum->stats.rescue_member;
}
hum->SyncAroundPlayers();
}
break;
}
ResetAction();
}
}
void Human::ClearFrameData()
{
if (!new_objects.empty()) {

View File

@ -171,6 +171,7 @@ class Human : public Entity
void FollowTarget(Human* target);
void SendDebugMsg(const std::string& debug_msg);
void SendRollMsg(const std::string& roll_msg);
void UpdateAction();
private:
void ClearFrameData();

View File

@ -191,140 +191,6 @@ void Player::UpdateSelectWeapon()
selected_weapon_idx = 0;
}
void Player::UpdateAction()
{
int duration = std::max(0,
action_duration -
(int)((room->frame_no - action_frameno) * 1.0f / SERVER_FRAME_RATE) * 1000
);
if (duration <= 0) {
switch (action_type) {
case AT_Reload:
{
if (curr_weapon->weapon_idx == action_target_id &&
curr_weapon->weapon_id == action_item_id &&
curr_weapon->weapon_idx != 0) {
MetaData::Equip* bullet_meta = MetaMgr::Instance()->GetEquip(curr_weapon->meta->i->use_bullet());
if (bullet_meta) {
int ammo = curr_weapon->ammo;
if (ammo < curr_weapon->meta->i->clip_volume()) {
if (bullet_meta->i->_inventory_slot() >= 0 &&
bullet_meta->i->_inventory_slot() < IS_END) {
if (GetInventory(bullet_meta->i->_inventory_slot()) > 0) {
int add_num = 0;
if (GetInventory(bullet_meta->i->_inventory_slot()) <=
curr_weapon->meta->i->clip_volume() - ammo) {
add_num = GetInventory(bullet_meta->i->_inventory_slot());
DecInventory(bullet_meta->i->_inventory_slot(), add_num);
} else {
add_num = curr_weapon->meta->i->clip_volume() - ammo;
DecInventory(bullet_meta->i->_inventory_slot(), add_num);
}
curr_weapon->ammo += add_num;
need_sync_active_player = true;;
}
}
}
}
}
}
break;
case AT_UseItem:
{
switch (action_item_id) {
case IS_HEALTHKIT:
{
MetaData::Equip* item_meta = MetaMgr::Instance()->GetEquipBySlotId(action_item_id);
if (item_meta){
if (GetInventory(item_meta->i->_inventory_slot()) > 0) {
float old_health = health;
health += item_meta->i->heal();
health = std::min(health, GetMaxHP());
stats.heal_amount += health - old_health;
DecInventory(item_meta->i->_inventory_slot(), 1);
need_sync_active_player = true;
SyncAroundPlayers();
}
}
}
break;
case IS_PAIN_KILLER:
{
MetaData::Equip* item_meta = MetaMgr::Instance()->GetEquipBySlotId(action_item_id);
if (item_meta){
if (GetInventory(item_meta->i->_inventory_slot()) > 0) {
if (pain_killer_timer) {
int passed_time = (room->frame_no - pain_killer_frameno) * FRAME_RATE_MS;
int left_time = std::max(0, pain_killer_lastingtime * 1000 - passed_time);
int anodyne_max_time = MetaMgr::Instance()->GetSysParamAsInt("anodyne_max_time");
left_time = std::min(left_time, anodyne_max_time * 1000);
pain_killer_lastingtime += std::min(item_meta->i->time() * 1000, anodyne_max_time * 1000 - left_time) / 1000;
need_sync_active_player = true;
} else {
pain_killer_frameno = room->frame_no;
pain_killer_lastingtime = item_meta->i->time();
pain_killer_timer = room->xtimer.AddRepeatTimerAndAttach(
SERVER_FRAME_RATE,
a8::XParams()
.SetSender(this)
.SetParam1(item_meta->i->heal()),
[] (const a8::XParams& param)
{
Human* hum = (Human*)param.sender.GetUserData();
float old_health = hum->health;
hum->health += param.param1.GetDouble();
hum->health = std::min(hum->health, hum->GetMaxHP());
hum->stats.heal_amount += hum->health - old_health;
hum->SyncAroundPlayers();
if (hum->room->frame_no - hum->pain_killer_frameno > hum->pain_killer_lastingtime * SERVER_FRAME_RATE) {
hum->room->xtimer.DeleteTimer(hum->pain_killer_timer);
hum->pain_killer_timer = nullptr;
}
},
&xtimer_attacher.timer_list_
);
}
DecInventory(item_meta->i->_inventory_slot(), 1);
need_sync_active_player = true;
}
}
}
break;
default:
{
}
break;
}
}
break;
case AT_Relive:
{
Entity* entity = room->GetEntityByUniId(action_target_id);
if (entity->entity_type != ET_Player) {
return;
}
Human* hum = (Human*)entity;
if (hum->action_type == AT_Rescue) {
hum->CancelAction();
return;
}
if (!hum->dead && hum->downed) {
hum->health = MetaMgr::Instance()->GetSysParamAsInt("downed_relive_recover_hp");
hum->downed = false;
if (hum->downed_timer) {
room->xtimer.DeleteTimer(hum->downed_timer);
hum->downed_timer = nullptr;
}
++hum->stats.rescue_member;
}
hum->SyncAroundPlayers();
}
break;
}
ResetAction();
}
}
void Player::UpdateReload()
{
AutoLoadingBullet(true);

View File

@ -71,7 +71,6 @@ class Player : public Human
void UpdateSelectWeapon();
void UpdateDropWeapon();
void UpdateUseScope();
void UpdateAction();
void UpdateReload();
void UpdateCancelAction();
void UpdateUseItemIdx();

View File

@ -199,8 +199,8 @@ void Room::ShuaAndroid()
hum->meta = hum_meta;
hum->entity_uniid = AllocUniid();
{
hum->pos.x = 3000 + rand() % 400;
hum->pos.y = 3000 + rand() % 500;
hum->pos.x = 3000 + rand() % 1400;
hum->pos.y = 3000 + rand() % 1500;
hum->attack_dir = hum->pos;
hum->attack_dir.Normalize();
hum->attack_dir.Rotate(a8::RandAngle());
@ -227,11 +227,17 @@ Human* Room::FindEnemy(Human* hum)
{
std::vector<Human*> enemys;
enemys.reserve(50);
for (auto& pair : accountid_hash_) {
if (pair.second->team_id == 0 ||
pair.second->team_id != hum->team_id
) {
enemys.push_back(pair.second);
for (auto& cell : hum->grid_list) {
for (Human* target : cell->human_list) {
if (target->entity_subtype == EST_Player) {
if (hum->pos.Distance(target->pos) < 300.0f) {
if (target->team_id == 0 ||
target->team_id != hum->team_id
) {
enemys.push_back(target);
}
}
}
}
}
std::sort(enemys.begin(), enemys.end(),

View File

@ -135,6 +135,12 @@ Vector2D Vector2D::FromAngle(float angle)
return vec2;
}
float Vector2D::Distance(const Vector2D& b)
{
Vector2D v = b - *this;
return v.Norm();
}
Vector2D Vector2D::Perp()
{
return Vector2D(y, -x);

View File

@ -19,6 +19,7 @@ struct Vector2D
void Rotate(float angle);
float CalcAngle(const Vector2D& b);
static Vector2D FromAngle(float angle);
float Distance(const Vector2D& b);
bool operator == (const Vector2D& b) const;
Vector2D operator + (const Vector2D& b) const;