From b9be7649ea62189bcae67fa94babc438852b9777 Mon Sep 17 00:00:00 2001 From: gumi Date: Wed, 28 Aug 2019 17:48:49 +0000 Subject: Revert the changes from the last 2 releases battle.cpp is very messy and full of bugs --- src/map/atcommand.cpp | 83 ++++++++++++----------------------------------- src/map/battle.cpp | 32 +++++++++++-------- src/map/map.hpp | 3 +- src/map/mob.cpp | 87 ++++++++++++++++++-------------------------------- src/map/script-fun.cpp | 1 + src/map/skill.cpp | 7 ++-- 6 files changed, 74 insertions(+), 139 deletions(-) diff --git a/src/map/atcommand.cpp b/src/map/atcommand.cpp index a5eb69b..a9774f0 100644 --- a/src/map/atcommand.cpp +++ b/src/map/atcommand.cpp @@ -4523,80 +4523,37 @@ ATCE atcommand_leaves(Session *, dumb_ptr sd, } static -ATCE atcommand_summon(Session *s, dumb_ptr sd, +ATCE atcommand_summon(Session *, dumb_ptr sd, ZString message) { MobName name; Species mob_id; - int number = 0; - int minutes = 0; + int x = 0; + int y = 0; + tick_t tick = gettick(); - if (!extract(message, record<' ', 1>(&name, &number, &minutes))) + if (!extract(message, &name) || !name) return ATCE::USAGE; - if ((mob_id = mobdb_searchname(name)) == Species()) - mob_id = mobdb_checkid(wrap(atoi(name.c_str()))); - + if ((mob_id = wrap(static_cast(atoi(name.c_str())))) == Species()) + mob_id = mobdb_searchname(name); if (mob_id == Species()) return ATCE::EXIST; - if (number <= 0) - number = 1; - - if (minutes <= 0) - minutes = 10; - - if (battle_config.atcommand_spawn_quantity_limit >= 1 - && number > battle_config.atcommand_spawn_quantity_limit) - number = battle_config.atcommand_spawn_quantity_limit; - - int count = 0; - int range = (sqrt(number) / 2) * 2 + 5; - - for (int i = 0; i < number; i++) - { - int j = 0; - BlockId k; - - while (j++ < 8 && !k) - { - // try 8 times to spawn the monster (needed for close area) - int mx = sd->bl_x + random_::in(-range / 2, range / 2 ); - int my = sd->bl_y + random_::in(-range / 2, range / 2); - k = mob_once_spawn(sd, MOB_THIS_MAP, mx, my, MobName(), mob_id, 1, NpcEvent()); - } - - if (k) - { - dumb_ptr md = map_id_is_mob(k); - tick_t tick = gettick(); - - md->master_id = sd->bl_id; - md->mode = get_mob_db(md->mob_class).mode | MobMode::AGGRESSIVE; - md->deletetimer = Timer(tick + (std::max(minutes, 120) * 1_min), - std::bind(mob_timer_delete, ph::_1, ph::_2, - k)); - count++; - } - } + x = sd->bl_x + random_::in(-5, 4); + y = sd->bl_y + random_::in(-5, 4); - if (count != 0) + BlockId id = mob_once_spawn(sd, MOB_THIS_MAP, x, y, JAPANESE_NAME, mob_id, 1, NpcEvent()); + dumb_ptr md = map_id_is_mob(id); + if (md) { - if (number == count) - { - clif_displaymessage(s, "All monster summoned!"_s); - } - else - { - AString output = STRPRINTF("%d monster(s) summoned!"_fmt, - count); - clif_displaymessage(s, output); - } - } - else - { - clif_displaymessage(s, "Invalid monster ID or name."_s); - return ATCE::EXIST; + md->master_id = sd->bl_id; + md->state.special_mob_ai = 1; + md->mode = get_mob_db(md->mob_class).mode | MobMode::AGGRESSIVE; + md->deletetimer = Timer(tick + 1_min, + std::bind(mob_timer_delete, ph::_1, ph::_2, + id)); + clif_misceffect(md, 344); } return ATCE::OKAY; @@ -5591,7 +5548,7 @@ Map atcommand_info = {"leaves"_s, {""_s, 98, atcommand_leaves, "Enable the leaves mapflag"_s}}, - {"summon"_s, {" [count] [minutes]"_s, + {"summon"_s, {""_s, 50, atcommand_summon, "Summon a slave monster temporarily"_s}}, {"adjgmlvl"_s, {" "_s, diff --git a/src/map/battle.cpp b/src/map/battle.cpp index 6379b60..df01a5c 100644 --- a/src/map/battle.cpp +++ b/src/map/battle.cpp @@ -2070,24 +2070,30 @@ int battle_check_target(dumb_ptr src, dumb_ptr target, if (src->bl_type == BL::MOB) { dumb_ptr md = src->is_mob(); - if (md && (md->master_id || md->parent_id)) + if (md && md->master_id) { - if (md->master_id == target->bl_id || md->parent_id == target->bl_id) // can't attack my master or my parent + if (md->master_id == target->bl_id) // 主なら肯定 return 1; - - if (target->bl_type == BL::MOB) + if (md->state.special_mob_ai) { - dumb_ptr tmd = target->is_mob(); - if (tmd) - { - if (tmd->master_id != md->master_id && tmd->parent_id != md->parent_id) // different master and parent - return 0; - else - return 1; // can't attack a mob that has the same master or parent as me + if (target->bl_type == BL::MOB) + { //special_mob_aiで対象がMob + dumb_ptr tmd = target->is_mob(); + if (tmd) + { + if (tmd->master_id != md->master_id) //召喚主が一緒でなければ否定 + return 0; + else + { //召喚主が一緒なので肯定したいけど自爆は否定 + if (md->state.special_mob_ai > 2) + return 0; + else + return 1; + } + } } } - - if ((ss = map_id2bl(md->parent_id)) == nullptr) + if ((ss = map_id2bl(md->master_id)) == nullptr) return -1; } } diff --git a/src/map/map.hpp b/src/map/map.hpp index 42ca151..eddbfad 100644 --- a/src/map/map.hpp +++ b/src/map/map.hpp @@ -482,8 +482,7 @@ struct mob_data : block_list struct mob_skill *skillidx; std::unique_ptr skilldelayup; // [MAX_MOBSKILL]; LevelElement def_ele; - BlockId parent_id; // monster that spawned this mob - BlockId master_id; // player that owns the parent + BlockId master_id; BlockId last_master_id; int master_dist; int exclusion_src, exclusion_party; diff --git a/src/map/mob.cpp b/src/map/mob.cpp index ea9ec34..0da946a 100644 --- a/src/map/mob.cpp +++ b/src/map/mob.cpp @@ -1152,7 +1152,6 @@ int mob_spawn(BlockId id) md->stats[mob_stat::SPEED] = get_mob_db(md->mob_class).speed.count(); md->def_ele = get_mob_db(md->mob_class).element; md->master_id = BlockId(); - md->parent_id = BlockId(); md->master_dist = 0; md->state.state = MS::IDLE; @@ -1574,13 +1573,13 @@ int mob_ai_sub_hard_slavemob(dumb_ptr md, tick_t tick) nullpo_retz(md); - if ((bl = map_id2bl(md->parent_id)) != nullptr) + if ((bl = map_id2bl(md->master_id)) != nullptr) mmd = bl->is_mob(); mode = get_mob_db(md->mob_class).mode; // It is not main monster/leader. - if (!mmd || mmd->bl_type != BL::MOB || mmd->bl_id != md->parent_id) + if (!mmd || mmd->bl_type != BL::MOB || mmd->bl_id != md->master_id) return 0; // Since it is in the map on which the master is not, teleport is carried out and it pursues. @@ -1679,8 +1678,7 @@ int mob_ai_sub_hard_slavemob(dumb_ptr md, tick_t tick) || race == Race::_insect || race == Race::_demon)) { // 妨害がないか判定 - md->master_id = mmd->master_id; - md->mode |= mmd->mode ^ get_mob_db(mmd->mob_class).mode; + md->target_id = sd->bl_id; md->state.attackable = true; md->min_chase = @@ -1858,19 +1856,19 @@ void mob_ai_sub_hard(dumb_ptr bl, tick_t tick) md->state.master_check = 0; // Processing of summoned monster attacked by owner - if (md->last_master_id) + if (md->last_master_id && md->state.special_mob_ai) { if (((bl = map_id2bl(md->last_master_id)) != nullptr && md->bl_m != bl->bl_m) || (bl = map_id2bl(md->last_master_id)) == nullptr) { md->last_master_id = BlockId(); - md->master_id = BlockId(); + md->state.special_mob_ai = 0; md->mode = get_mob_db(md->mob_class).mode; md->target_id = BlockId(); md->attacked_id = BlockId(); } } // Processing of slave monster - if (md->parent_id) + if (md->master_id && md->state.special_mob_ai == 0) mob_ai_sub_hard_slavemob(md, tick); // アクティヴモンスターの策敵 (?? of a bitter taste TIVU monster) @@ -1879,7 +1877,7 @@ void mob_ai_sub_hard(dumb_ptr bl, tick_t tick) && battle_config.monster_active_enable == 1) { i = 0; - if (md->master_id) + if (md->state.special_mob_ai) { map_foreachinarea(std::bind(mob_ai_sub_hard_activesearch, ph::_1, md, &i), md->bl_m, @@ -2073,7 +2071,8 @@ void mob_ai_sub_hard(dumb_ptr bl, tick_t tick) // mobs that are not slaves can random-walk if (bool(mode & MobMode::CAN_MOVE) && mob_can_move(md) - && (!md->parent_id || md->master_dist > 10)) + && (!md->master_id || md->state.special_mob_ai + || md->master_dist > 10)) { // if walktime is more than 7 seconds in the future, // set it to somewhere between 3 and 5 seconds @@ -2163,7 +2162,7 @@ void mob_ai_sub_lazy(dumb_ptr bl, tick_t tick) // MOB which is not not the summons MOB but BOSS, either sometimes reboils. else if (random_::chance(MOB_LAZYWARPPERC) && md->spawn.x0 <= 0 - && md->parent_id + && md->master_id && !bool(get_mob_db(md->mob_class).mode & MobMode::BOSS)) mob_spawn(md->bl_id); @@ -2175,7 +2174,7 @@ void mob_ai_sub_lazy(dumb_ptr bl, tick_t tick) // MOB which is not BOSS which is not Summons MOB, either -- a case -- sometimes -- leaping if (random_::chance(MOB_LAZYWARPPERC) && md->spawn.x0 <= 0 - && md->parent_id + && md->master_id && !bool(get_mob_db(md->mob_class).mode & MobMode::BOSS)) mob_warp(md, nullptr, -1, -1, BeingRemoveWhy::NEGATIVE1); } @@ -2335,7 +2334,7 @@ void mob_deleteslave_sub(dumb_ptr bl, BlockId id) nullpo_retv(bl); md = bl->is_mob(); - if (md->parent_id && md->parent_id == id) + if (md->master_id && md->master_id == id) mob_damage(nullptr, md, md->hp, 1); } @@ -2383,19 +2382,9 @@ int mob_damage(dumb_ptr src, dumb_ptr md, int damage, /* If the master hits a monster, have the monster turn against him */ md->last_master_id = md->master_id; md->master_id = BlockId(); + md->mode = MobMode::war; /* Regular war mode */ md->target_id = src->bl_id; md->attacked_id = src->bl_id; - - if (md->parent_id) { - dumb_ptr p_md = map_id_is_mob(md->parent_id); - - if (p_md != nullptr) { - // turn the parent against the master - p_md->last_master_id = p_md->master_id; - p_md->master_id = BlockId(); - mob_aggravate(p_md, src); - } - } } max_hp = battle_get_max_hp(md); @@ -2460,11 +2449,11 @@ int mob_damage(dumb_ptr src, dumb_ptr md, int damage, } damage_logged_pc: - if (!md->attacked_id) + if (!md->attacked_id && md->state.special_mob_ai == 0) md->attacked_id = sd->bl_id; } if (src && src->bl_type == BL::MOB - && src->is_mob()->master_id) + && src->is_mob()->state.special_mob_ai) { dumb_ptr md2 = src->is_mob(); dumb_ptr master_bl = map_id2bl(md2->master_id); @@ -2492,7 +2481,7 @@ int mob_damage(dumb_ptr src, dumb_ptr md, int damage, app.dmg = damage; md->dmglogv.push_back(app); - if (!md->attacked_id) + if (!md->attacked_id && md->state.special_mob_ai == 0) md->attacked_id = md2->master_id; } damage_logged_slave: @@ -2543,17 +2532,6 @@ int mob_damage(dumb_ptr src, dumb_ptr md, int damage, std::vector ptv; int mvp_dmg = 0, second_dmg = 0, third_dmg = 0; - bool summoned_by_nongm = false; - - if (md->master_id && battle_config.alchemist_summon_reward != 1) - { - dumb_ptr m_sd = map_id_is_player(md->master_id); - - if (!m_sd || !pc_isGM(m_sd).satisfies(GmLevel::from(60_u32))) { - summoned_by_nongm = true; - } - } - for (mob_data::DmgLogEntry& dle : md->dmglogv) { dumb_ptr tmpsdi = map_id2sd(dle.id); @@ -2613,10 +2591,9 @@ int mob_damage(dumb_ptr src, dumb_ptr md, int damage, { base_exp *= 1.15; // pk_mode additional exp if monster >20 levels [Valaris] } - if (summoned_by_nongm) - { - base_exp = 0; // no exp for mobs summoned by non-GMs - } + if (md->state.special_mob_ai >= 1 + && battle_config.alchemist_summon_reward != 1) + base_exp = 0; // Added [Valaris] job_exp = get_mob_db(md->mob_class).job_exp * per / 256; if (job_exp < 1) job_exp = 1; @@ -2625,10 +2602,9 @@ int mob_damage(dumb_ptr src, dumb_ptr md, int damage, { job_exp *= 1.15; // pk_mode additional exp if monster >20 levels [Valaris] } - if (summoned_by_nongm) - { - job_exp = 0; // no exp for mobs summoned by non-GMs - } + if (md->state.special_mob_ai >= 1 + && battle_config.alchemist_summon_reward != 1) + job_exp = 0; // Added [Valaris] PartyId pid = tmpsdi->status.party_id; if (pid) @@ -2673,8 +2649,8 @@ int mob_damage(dumb_ptr src, dumb_ptr md, int damage, { for (int i = 0; i < 8; i++) { - if (summoned_by_nongm) - break; // no drops for mobs spawned by non-GMs + if (md->state.special_mob_ai >= 1 && battle_config.alchemist_summon_reward != 1) // Added [Valaris] + break; // End if (!get_mob_db(md->mob_class).dropitem[i].nameid) continue; @@ -2781,7 +2757,7 @@ void mob_warpslave_sub(dumb_ptr bl, BlockId id, int x, int y) { dumb_ptr md = bl->is_mob(); - if (md->parent_id == id) + if (md->master_id == id) { mob_warp(md, nullptr, x, y, BeingRemoveWhy::QUIT); } @@ -2897,7 +2873,7 @@ void mob_countslave_sub(dumb_ptr bl, BlockId id, int *c) nullpo_retv(bl); md = bl->is_mob(); - if (md->parent_id == id) + if (md->master_id == id) (*c)++; } @@ -2993,12 +2969,8 @@ int mob_summonslave(dumb_ptr md2, int *value_, int amount, int flag) map_addiddb(md); mob_spawn(md->bl_id); - if (flag) { - md->master_id = md2->master_id; // tell the subslave who actually owns them - md->parent_id = md2->bl_id; // tell the subslave who spawned them - md->mode = get_mob_db(md->mob_class).mode; - md->mode |= md2->mode ^ get_mob_db(md2->mob_class).mode; // if our mode has special flags, hand them to our children too - } + if (flag) + md->master_id = md2->bl_id; } } return 0; @@ -3320,6 +3292,9 @@ int mobskill_use(dumb_ptr md, tick_t tick, if (battle_config.mob_skill_use == 0 || md->skilltimer) return 0; + if (md->state.special_mob_ai) + return 0; + for (mob_skill& msii : ms) { tick_t& sdii = md->skilldelayup[&msii - &ms.front()]; diff --git a/src/map/script-fun.cpp b/src/map/script-fun.cpp index 3becf10..8c90052 100644 --- a/src/map/script-fun.cpp +++ b/src/map/script-fun.cpp @@ -2547,6 +2547,7 @@ void builtin_summon(ScriptState *st) switch (monster_attitude) { case MonsterAttitude::SERVANT: + mob->state.special_mob_ai = 1; mob->mode |= MobMode::AGGRESSIVE; break; diff --git a/src/map/skill.cpp b/src/map/skill.cpp index 05399c2..d9a7717 100644 --- a/src/map/skill.cpp +++ b/src/map/skill.cpp @@ -532,7 +532,7 @@ int skill_castend_nodamage_id(dumb_ptr src, dumb_ptr bl, switch (skillid) { case SkillID::NPC_SUMMONSLAVE: - if (md) + if (md && !md->master_id) { mob_summonslave(md, md->skillidx->val, @@ -542,10 +542,7 @@ int skill_castend_nodamage_id(dumb_ptr src, dumb_ptr bl, break; case SkillID::NPC_EMOTION: - if (dstsd) - clif_emotion(dstsd, - md->skillidx->val[0]); - else if (md) + if (md) clif_emotion(md, md->skillidx->val[0]); break; -- cgit v1.2.3-60-g2f50