merge master

This commit is contained in:
aozhiwei 2019-05-17 14:24:13 +08:00
commit 3043f2986d
18 changed files with 260 additions and 154 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

@ -32,5 +32,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

@ -38,7 +38,7 @@ void Bullet::Update(int delta_time)
for (auto& grid : grid_list) {
for (Human* hum: grid->human_list) {
#if 1
if (hum != player) {
if (hum != player && !hum->dead) {
#else
if (hum != player &&
(hum->team_id == 0 || player->team_id != hum->team_id)) {

View File

@ -148,3 +148,5 @@ const int MAP_WIDTH = 8192;
const int MAP_CELL_WIDTH = 64 * 8;
const int DOOR_THING_ID = 61701;
const int FIGHTING_MODE_BULLET_NUM = 10000 * 10000;

View File

@ -36,6 +36,14 @@ Human::Human():Entity()
weapons[0] = default_weapon;
curr_weapon = &weapons[0];
inventory_[IS_1XSCOPE] = 1;
if (MetaMgr::Instance()->fighting_mode) {
inventory_[IS_9MM] = FIGHTING_MODE_BULLET_NUM;
inventory_[IS_556MM] = FIGHTING_MODE_BULLET_NUM;
inventory_[IS_762MM] = FIGHTING_MODE_BULLET_NUM;
inventory_[IS_12GAUGE] = FIGHTING_MODE_BULLET_NUM;
inventory_[IS_RPG] = FIGHTING_MODE_BULLET_NUM;
}
}
Human::~Human()
@ -185,6 +193,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);
}
@ -704,6 +718,17 @@ bool Human::HasNoDownedTeammate()
void Human::Land()
{
a8::UnSetBitFlag(status, HS_Jump);
if (entity_subtype == EST_Android) {
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];
}
}
FindLocation();
SyncAroundPlayers();
}
@ -1465,6 +1490,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

@ -96,6 +96,7 @@ public:
MetaMgr::Instance()->K = MetaMgr::Instance()->GetSysParamAsFloat("K");
MetaMgr::Instance()->kill_param = MetaMgr::Instance()->GetSysParamAsFloat("kill_parameter");
MetaMgr::Instance()->rank_param = MetaMgr::Instance()->GetSysParamAsFloat("rank_parameter");
MetaMgr::Instance()->fighting_mode = MetaMgr::Instance()->GetSysParamAsInt("fighting_mode", 1);
if (MetaMgr::Instance()->K < 0.01f) {
abort();
}

View File

@ -39,6 +39,7 @@ class MetaMgr : public a8::Singleton<MetaMgr>
float K = 100.0f;
float kill_param = 0.0f;
float rank_param = 0.0f;
int fighting_mode = 0;
private:
MetaDataLoader* loader_ = nullptr;

View File

@ -94,6 +94,7 @@ void Obstacle::FillMFObjectFull(cs::MFObjectFull* full_data)
p->set_is_door(is_door);
if (is_door) {
p->set_door_id(door_id);
p->set_door_open_times(door_open_times);
p->set_door_old_state((int)door_state);
p->set_door_new_state((int)door_state);
p->set_door_house_uniid(door_house_uniid);

View File

@ -30,6 +30,7 @@ class Obstacle : public Entity
bool is_door = false;
int door_id = 0;
int door_open_times = 0;
DoorState_e door_state = DoorStateClose;
Building* building = nullptr;
int door_house_uniid = 0;

View File

@ -175,153 +175,22 @@ void Player::UpdateSelectWeapon()
return;
}
if (selected_weapon_idx >= 0 && selected_weapon_idx < weapons.size()) {
Weapon* old_weapon = curr_weapon;
Weapon* weapon = &weapons[selected_weapon_idx];
if (weapon->weapon_id != 0) {
curr_weapon = weapon;
ResetAction();
need_sync_active_player = true;
SyncAroundPlayers();
if (old_weapon != weapon) {
AutoLoadingBullet();
}
}
}
select_weapon = false;
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);
@ -586,6 +455,7 @@ void Player::ObstacleInteraction(Obstacle* entity)
entity->pos = Vector2D(entity->building->pos.x + entity->door_state0->x() - entity->building->meta->i->tilewidth() / 2.0,
entity->building->pos.y + entity->door_state0->y() - entity->building->meta->i->tileheight() / 2.0);
}
++entity->door_open_times;
entity->RecalcSelfCollider();
room->TouchHumanList(a8::XParams(),
[entity] (Human* hum, a8::XParams& param) -> bool
@ -791,7 +661,7 @@ void Player::HumanInteraction(Human* hum)
}
hum->StartAction(
AT_Rescue,
MetaMgr::Instance()->GetSysParamAsInt("rescue_time") * 1000,
MetaMgr::Instance()->GetSysParamAsInt("downed_relive_time") * 1000,
room->frame_no,
entity_uniid
);

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

@ -26,7 +26,7 @@ const int ROOM_MAX_PLAYER_NUM = 50;
#if 0
const int ANDROID_NUM = 0;
#else
const int ANDROID_NUM = 10;
const int ANDROID_NUM = 49;
#endif
static long long RoomXGetTickCount(void* context)
@ -123,11 +123,6 @@ void Room::Update(int delta_time)
}
}
bool Room::IsFull()
{
return accountid_hash_.size() >= ROOM_MAX_PLAYER_NUM;
}
int Room::GetPlayerNum()
{
return accountid_hash_.size();
@ -158,6 +153,7 @@ int Room::AliveCount()
void Room::AddPlayer(Player* hum)
{
assert(gas_data.gas_mode == GasInactive);
{
hum->pos.x = 3000 + rand() % 100;
hum->pos.y = 3000 + rand() % 200;
@ -179,6 +175,9 @@ void Room::AddPlayer(Player* hum)
hum->FindLocation();
hum->RefreshView();
MatchTeam(hum);
while (human_hash_.size() > ROOM_MAX_PLAYER_NUM) {
RandRemoveAndroid();
}
}
unsigned short Room::AllocUniid()
@ -202,8 +201,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());
@ -230,11 +229,22 @@ 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
EntitySubType_e sub_type = EST_Player;
if ((rand() % 10) < 2) {
sub_type = EST_Android;
}
for (auto& cell : hum->grid_list) {
for (Human* target : cell->human_list) {
if (target->entity_subtype == sub_type &&
!target->dead) {
if (hum->pos.Distance(target->pos) < 300.0f) {
if (target->team_id == 0 ||
target->team_id != hum->team_id
) {
enemys.push_back(pair.second);
enemys.push_back(target);
}
}
}
}
}
std::sort(enemys.begin(), enemys.end(),
@ -474,6 +484,10 @@ void Room::CreateLoot(int equip_id, Vector2D pos, int count)
{
MetaData::Equip* equip_meta = MetaMgr::Instance()->GetEquip(equip_id);
if (equip_meta) {
if (equip_meta->i->equip_type() == 2 &&
MetaMgr::Instance()->fighting_mode) {
return;
}
Loot* entity = new Loot();
entity->room = this;
entity->meta = equip_meta;
@ -526,6 +540,12 @@ void Room::RemoveObjectLater(Entity* entity)
entity->room->grid_service.DelEntity(entity);
}
break;
case ET_Player:
{
entity->room->moveable_hash_.erase(entity->entity_uniid);
entity->room->human_hash_.erase(entity->entity_uniid);
}
break;
default:
{
abort();
@ -638,6 +658,14 @@ int Room::GetAliveTeamNum()
return num;
}
bool Room::CanJoin(const std::string& accountid)
{
if (gas_data.gas_mode != GasInactive) {
return false;
}
return accountid_hash_.size() < ROOM_MAX_PLAYER_NUM;
}
std::set<Human*>* Room::GetAliveTeam()
{
for (auto& pair : team_hash_) {
@ -1117,3 +1145,30 @@ void Room::OnGameOver()
}
}
}
void Room::RandRemoveAndroid()
{
Human* hum = nullptr;
for (auto& pair : human_hash_) {
if (pair.second->entity_subtype == EST_Android) {
hum = pair.second;
break;
}
}
if (hum) {
if (hum->team_id != 0) {
team_hash_.erase(hum->team_id);
}
for (auto& cell : hum->grid_list) {
for (Human* target : cell->human_list) {
target->AddOutObjects(hum);
}
cell->human_list.erase(hum);
}
moveable_hash_.erase(hum->entity_uniid);
uniid_hash_.erase(hum->entity_uniid);
human_hash_.erase(hum->entity_uniid);
removed_robot_hash_[hum->entity_uniid] = hum;
--alive_count_;
}
}

View File

@ -50,7 +50,6 @@ public:
void Init();
void UnInit();
void Update(int delta_time);
bool IsFull();
int GetPlayerNum();
int AliveCount();
Player* GetPlayerByAccountId(const std::string& accountid);
@ -88,6 +87,7 @@ public:
bool BattleStarted();
int GetAliveTeamNum();
std::set<Human*>* GetAliveTeam();
bool CanJoin(const std::string& accountid);
private:
unsigned short AllocUniid();
@ -109,6 +109,7 @@ private:
std::function<void (Obstacle*)> on_precreate);
void AddObjectLater(Entity* entity);
void OnGameOver();
void RandRemoveAndroid();
private:
timer_list* stats_timer_ = nullptr;
@ -127,4 +128,6 @@ private:
std::map<unsigned short, Entity*> uniid_hash_;
std::map<unsigned short, Entity*> later_add_hash_;
std::map<unsigned short, Human*> human_hash_;
std::map<unsigned short, Human*> removed_robot_hash_;
};

View File

@ -106,7 +106,7 @@ int RoomMgr::RoomNum()
Room* RoomMgr::GetJoinableRoom(const std::string& account_id)
{
for (auto& pair : inactive_room_hash_) {
if (!pair.second->IsFull() && !pair.second->GetPlayerByAccountId(account_id)) {
if (pair.second->CanJoin(account_id)) {
return pair.second;
}
}

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;

View File

@ -191,6 +191,7 @@ message MFObstacleFull
optional int32 door_house_id = 26; //id
optional float door_width = 27; //
optional float door_height = 28; //
optional int32 door_open_times = 29; //,/ ++times 0:
}