diff --git a/server/gameserver/buff.cc b/server/gameserver/buff.cc index d726838..471c73e 100644 --- a/server/gameserver/buff.cc +++ b/server/gameserver/buff.cc @@ -37,7 +37,36 @@ void Buff::ProcIntervalAddBuff(Creature* caster) void Buff::ProcBatchAddBuff(Creature* caster) { - + for (auto& tuple : meta->batch_add_list) { + int rand_space = std::get<0>(tuple); + const auto& items = std::get<1>(tuple); + if (items.empty()) { + abort(); + } + int rnd = rand(); + if (rand_space == -1) { + //概率 + rnd = rnd % 10000; + if (rnd < std::get<1>(items[0])){ + MetaData::Buff* buff_meta = MetaMgr::Instance()->GetBuff(std::get<0>(items[0])); + if (buff_meta) { + owner->AddBuff(caster, buff_meta, 1, nullptr); + } + } + } else { + //权重 + rnd = rnd % rand_space; + for (const auto& item : items) { + if (rnd <= std::get<1>(item)) { + MetaData::Buff* buff_meta = MetaMgr::Instance()->GetBuff(std::get<0>(item)); + if (buff_meta) { + owner->AddBuff(caster, buff_meta, 1, nullptr); + } + break; + } + } + } + } } void Buff::InternalTimerAddBuff(Creature* caster) diff --git a/server/gameserver/bullet.cc b/server/gameserver/bullet.cc index 47379db..99050e4 100644 --- a/server/gameserver/bullet.cc +++ b/server/gameserver/bullet.cc @@ -373,6 +373,18 @@ void Bullet::ProcFragBomb(int delay_time) void Bullet::ProcPosionGasBomb(int delay_time) { if (sender.Get()) { + #if 1 + a8::Vec2 old_buff_vec2_param1 = sender.Get()->buff_vec2_param1; + sender.Get()->buff_vec2_param1 = GetPos(); + MetaData::Buff * buff_meta = MetaMgr::Instance()->GetBuff(gun_meta->i->buffid()); + if (buff_meta) { + sender.Get()->AddBuff(sender.Get(), + buff_meta, + 1 + ); + } + sender.Get()->buff_vec2_param1 = old_buff_vec2_param1; + #else PosionGasMiTask* task = new PosionGasMiTask(); task->room = room; task->sender.Attach(sender.Get()); @@ -398,6 +410,7 @@ void Bullet::ProcPosionGasBomb(int delay_time) }, &room->timer_attacher.timer_list_ ); + #endif } } diff --git a/server/gameserver/constant.h b/server/gameserver/constant.h index 077ff4a..14d622d 100755 --- a/server/gameserver/constant.h +++ b/server/gameserver/constant.h @@ -384,6 +384,7 @@ enum ObstacleType_e kObstacleSelfExplosion = 1, kObstacleMine = 2, kObstacleTrap = 3, + kObstaclePosionGas = 4, }; const char* const PROJ_NAME_FMT = "game%d_gameserver"; diff --git a/server/gameserver/creature.cc b/server/gameserver/creature.cc index e0eab1c..6da8f6c 100644 --- a/server/gameserver/creature.cc +++ b/server/gameserver/creature.cc @@ -21,6 +21,8 @@ void InternalShot(Creature* c, { if (weapon_meta->i->_inventory_slot() == IS_TRAP || weapon_meta->i->_inventory_slot() == IS_MINE) { + a8::Vec2 old_buff_vec2_param1 = c->buff_vec2_param1; + c->buff_vec2_param1 = c->GetPos(); MetaData::Buff * buff_meta = MetaMgr::Instance()->GetBuff(bullet_meta->i->buffid()); if (buff_meta) { c->AddBuff(c, @@ -28,6 +30,7 @@ void InternalShot(Creature* c, 1 ); } + c->buff_vec2_param1 = old_buff_vec2_param1; return; } for (auto& tuple : weapon_meta->bullet_born_offset) { @@ -843,6 +846,7 @@ void Creature::ProcBuffEffect(Creature* caster, Buff* buff) case kBET_SummonObstacle: { a8::Vec2 target_pos = caster->GetPos() + caster->skill_dir_ * caster->skill_distance_; + target_pos = buff_vec2_param1; SummonObstacle(buff->meta->param1, target_pos); } break; diff --git a/server/gameserver/creature.h b/server/gameserver/creature.h index b9f17ca..1c4d5c3 100644 --- a/server/gameserver/creature.h +++ b/server/gameserver/creature.h @@ -47,6 +47,7 @@ class Creature : public MoveableEntity long long poisoning_time = 0; Weapon car_weapon; + a8::Vec2 buff_vec2_param1; bool need_sync_active_player = false; std::function on_loading_bullet; diff --git a/server/gameserver/human.cc b/server/gameserver/human.cc index d6fe8f5..81132a8 100644 --- a/server/gameserver/human.cc +++ b/server/gameserver/human.cc @@ -836,6 +836,8 @@ void Human::BeKill(int killer_id, const std::string& killer_name, int weapon_id) RemoveBuffByEffectId(kBET_Camouflage); } ClearLordMode(); + room->frame_event.AddDead(this, + 0); #ifdef DEBUG room->CheckPartObjects(); #endif diff --git a/server/gameserver/metadata.cc b/server/gameserver/metadata.cc index 09a6233..dfbb4d4 100644 --- a/server/gameserver/metadata.cc +++ b/server/gameserver/metadata.cc @@ -555,6 +555,65 @@ namespace MetaData } } } + if (i->buff_effect() == kBET_BatchAddBuff) { + std::vector strings1; + a8::Split(i->buff_param1(), strings1, '|'); + for (auto& str1 : strings1) { + std::vector strings2; + a8::Split(str1, strings2, '|'); + for (auto& str2 : strings2) { + if (str2.size() < 1) { + abort(); + } + auto& p = a8::FastAppend(batch_add_list); + if (str2[0] != '!') { + //概率 + std::vector strings3; + a8::Split(str2, strings3, ':'); + if (strings3.size() != 2) { + abort(); + } + if (a8::XValue(strings3[1]).GetInt() <= 0) { + abort(); + } + std::get<0>(p) = -1; + std::get<1>(p).push_back + ( + std::make_tuple(a8::XValue(strings3[0]), + a8::XValue(strings3[1])) + ); + } else { + //权重 + std::vector strings3; + a8::Split(str2, strings3, '$'); + int rand_space = 0; + for (const std::string& str3 : strings3) { + std::vector strings4; + a8::Split(str3, strings4, ':'); + if (strings4.size() != 2) { + abort(); + } + std::string tmp_str = strings4[0]; + a8::ReplaceString(tmp_str, "!", ""); + int buff_id = a8::XValue(tmp_str); + int weight = a8::XValue(strings4[1]); + if (weight <= 0) { + abort(); + } + + rand_space += weight; + std::get<1>(p).push_back + ( + std::make_tuple(buff_id, + rand_space) + ); + } + std::get<0>(p) = rand_space; + } + } + int i = 0; + } + } } bool Buff::EffectCanStack() diff --git a/server/gameserver/metadata.h b/server/gameserver/metadata.h index 3b3ec25..85bb08f 100755 --- a/server/gameserver/metadata.h +++ b/server/gameserver/metadata.h @@ -170,6 +170,7 @@ namespace MetaData float param3 = 0.0f; float param4 = 0.0f; std::vector param2_int_list; + std::vector>>> batch_add_list; std::vector>> post_remove_action; std::set immune_buffeffect; }; diff --git a/server/gameserver/room.cc b/server/gameserver/room.cc index 0a46682..456d1f2 100644 --- a/server/gameserver/room.cc +++ b/server/gameserver/room.cc @@ -2253,7 +2253,7 @@ ObstacleData* Room::GetPermanentObstacleData(int obstacle_uniid) long long Room::GetGasInactiveTime() { -#if DEBUG +#ifdef DEBUG return 5; #endif if (room_mode_ == kZombieMode) { diff --git a/server/gameserver/roomobstacle.cc b/server/gameserver/roomobstacle.cc index ac060b0..ed8b001 100644 --- a/server/gameserver/roomobstacle.cc +++ b/server/gameserver/roomobstacle.cc @@ -330,6 +330,11 @@ void RoomObstacle::Active() ActiveTrap(); } break; + case kObstaclePosionGas: + { + ActivePosionGas(); + } + break; default: break; } @@ -393,3 +398,30 @@ void RoomObstacle::ActiveTrap() &xtimer_attacher.timer_list_ ); } + +void RoomObstacle::ActivePosionGas() +{ + room->xtimer.AddDeadLineTimerAndAttach + ( + meta->i->time() / FRAME_RATE_MS, + a8::XParams() + .SetSender(this), + [] (const a8::XParams& param) + { + RoomObstacle* obstacle = (RoomObstacle*)param.sender.GetUserData(); + obstacle->room->xtimer.AddRepeatTimerAndAttach + ( + obstacle->meta->i->explosion_interval() / FRAME_RATE_MS, + a8::XParams() + .SetSender(obstacle), + [] (const a8::XParams& param) + { + RoomObstacle* obstacle = (RoomObstacle*)param.sender.GetUserData(); + obstacle->SpecExplosion(); + }, + &obstacle->xtimer_attacher.timer_list_ + ); + }, + &xtimer_attacher.timer_list_ + ); +} diff --git a/server/gameserver/roomobstacle.h b/server/gameserver/roomobstacle.h index 613100a..78600cd 100644 --- a/server/gameserver/roomobstacle.h +++ b/server/gameserver/roomobstacle.h @@ -28,6 +28,7 @@ private: void ActiveSelfExplosion(); void ActiveMine(); void ActiveTrap(); + void ActivePosionGas(); protected: bool temp_through_ = false; diff --git a/server/tools/protobuild/cs_proto.proto b/server/tools/protobuild/cs_proto.proto index 6e25a9c..c4a2ff8 100755 --- a/server/tools/protobuild/cs_proto.proto +++ b/server/tools/protobuild/cs_proto.proto @@ -1038,8 +1038,8 @@ message SMUpdate repeated MFPropertyChg chged_property_list = 31; //property变更列表 repeated MFPlaySkill play_skill_list = 32; //播放技能 - //一下字段只有僵尸模式才有效 repeated MFTuple dead_alive_objs = 42; //玩家values[0]:objid values[1]:多少毫秒后复活 values[2]: 0:死亡 1:复活 + //一下字段只有僵尸模式才有效 repeated MFPosition object_positions = 43; //对象坐标信息,如果对象已经在part_objects则可能不发,这时客户端可以读取part_objects里的左边更新小地图 optional int32 game_left_time = 45; //游戏剩余时间(毫秒, 战斗开始后字段才有意义) }