亮
自创特技-阴毒【相邻敌部队和被投石击中的部队概率中毒】
为庆祝五一新版的发布,结合新内容自创了一个特技,水平不足,请各位指导。
特技:阴毒
特技描述:每回合相邻敌部队10%和被其投石击中(10+自部队伤兵/20)%的部队概率中毒;投石清空全部伤兵和自部队中毒状态,部队内武将合共减少(自部队伤兵/20)功绩。
灵感:生化战争古已有之。如果敌军在短时间内向城里投掷大量尸体,自然就没办法处理,在天气炎热的催化下,疫情很快就产生了。这就相当于早期的生化武器。蒙古大军攻城、朱元璋早年在攻打对手张士诚的时候,就采用了这一招。
平时两军交战不好投毒,所以相邻敌部队中毒概率较低;一旦使用投石机将大量尸体射入对方军中,对方不好抵挡,中毒概率就很高了,尸体越多中毒概率越高;
将有毒的尸体扔出去,自身部队的环境改善了,所以自部队的中毒就消除了;
由于这招太损,就好像程昱做人肉干粮一样,失去在朝廷的威望不能位列三公,功绩被扣了
适用人物:程昱(人肉美食家),皇甫嵩,司马懿,邓艾 (筑京观三人组)
代码如下:
// 特技_阴毒
//每回合相邻敌部队和被其投石击中的部队概率中毒;投石清空伤兵和自部队中毒状态,武将功绩减少。
const int 特技_阴毒=581;
namespace 新特技阴毒
{
class Main
{
Main()
{
pk::bind(111, pk::trigger111_t(onForceBegin));
}
void onForceBegin(pk::force @force)
{
if (!pk::is_alive(force) or force.get_id() >= 非贼势力_末)
return;
func_相邻特技(force);
}
void func_相邻特技(pk::force @force)
{
pk::list<pk::unit @> unit_list = pk::get_unit_list(force);
if ( > 0)
{
for (int i = 0; i < int(unit_list.count); i += 1)
{
pk::unit @unit = unit_list[i];
if (ch::has_skill(unit, 特技_阴毒))
{
array<pk::point> rings = pk::range(unit.get_pos(), 1, 1);
for (int d = 0; d < int(rings.length); d++)
{
pk::unit @dst = pk::get_unit(rings[d]);
if (dst !is null and dst.get_force_id() != force.get_id())
{
func_阴毒(force, unit, dst);
}
}
}
}
}
}
void func_阴毒(pk::force @force, pk::unit @attacker, pk::unit @target)
{
if (target !is null and ch::has_skill(attacker, 特技_阴毒) and
pk::rand_bool(pk::core::skill_constant_value(特技_阴毒)))
{
if (ch::set_status(target, attacker, 部队状态_中毒, 1, 0))
{
if (pk::is_in_screen(target.pos))
{
pk::say(pk::encode('不好,居然被投毒了'), pk::get_person(target.leader), target);
}
}
}
}
} Main main;
}
还有一个“226 战法状态.cpp”要修改,改成下面内容:
// 战法状态统一在此cpp处理,221和222实际已经被跳过
namespace TACTICS_STATUS
{
const int BASE_STUN_RATE = 40; // 基本动摇率
const int CRITICAL_STUN_RATE = 80; // 暴击动摇率
class Main
{
Main()
{
pk::set_func(226, pk::func226_t(Status_Anim));
}
void Status_Anim(pk::unit @attacker, pk::unit @target, int tactic_id, bool critical, bool collided, bool moved)
{
// 已经判断过2个is_alive了
// 螺旋突相关
if (tactic_id == 战法_螺旋突)
{
if (!ch::has_skill(target, 特技_治军))
{
int rate = 螺旋突成功率(attacker, target, critical);
if (pk::rand_bool(rate))
{
int timer = 螺旋突动摇时间(attacker, target, critical);
if (timer > 0)
pk::set_status(target, attacker, 部队状态_动摇, timer);
}
}
}
else if (tactic_id == 战法_突刺)
{
if (!ch::has_skill(target, 特技_治军))
{
// 没有撞击到目标且没有移动,就是撞到了不可移动地格或边界外
if (!moved and !collided)
{
int rate = 螺旋突成功率(attacker, target, critical);
if (pk::rand_bool(rate))
{
int timer = 螺旋突动摇时间(attacker, target, critical) + 1;
if (timer > 0)
pk::set_status(target, attacker, 部队状态_混乱, timer);
}
}
}
}
else if (tactic_id == 战法_突击 or tactic_id == 战法_突进 or tactic_id == 战法_突破 or tactic_id == 战法_连突)
{
// 骑兵疾驰
if (!ch::has_skill(target, 特技_治军))
{
auto shissou = pk::get_person(attacker.who_has_skill(SkillId_Shissou));
if (!pk::is_alive(shissou))
return;
pk::info(pk::format("unit0: {}; unit1:", ch::get_unit_infact_able(attacker), int(attacker.get_stat(UnitStatType_Attack))));
// 修复: 转为int避免无符号整数比较问题--改为加上buff
int atk1 = ch::get_unit_infact_able(attacker);
int atk2 = ch::get_unit_infact_able(target);
if (atk1 <= atk2)
return;
if (pk::rand_bool(pk::core::skill_constant_value(特技_疾驰)))
{
pk::msg_param msg_param(F_WAR_TOKUGI_SHISSOU, shissou, target.get_leader());
pk::say(pk::get_msg(msg_param), shissou, null);
// 修复: 明确随机范围,改为更清晰的表达方式
int stun_time = 1; // 1或2回合
pk::set_status(target, attacker, 部队状态_动摇, stun_time);
}
}
}
else if (tactic_id == 战法_阻击)
{
int timer = 2 + (critical ? 2 : 1);
if (timer > 0 && pk::rand_bool(阻击止行成功率(attacker, target, critical)))
pk::set_status(target, attacker, 部队状态_止行, timer);
}
else if (tactic_id == 战法_毒箭)
{
int timer = 3 + (critical ? 2 : 1);
if (timer > 0 && pk::rand_bool(毒箭中毒成功率(attacker, target, critical)))
pk::set_status(target, attacker, 部队状态_中毒, timer);
}
else if ((tactic_id == 战法_攻城投石 or tactic_id == 战法_舰艇投石) and ch::has_skill(attacker, 特技_阴毒))
{ int timer = 3 ;
if (timer > 0 && pk::rand_bool(投石中毒成功率(attacker, target, critical)))
{
pk::set_status(target, attacker, 部队状态_中毒, timer);
if (pk::is_in_screen(target.pos))
{
pk::say(pk::encode('糟了,被有毒的尸体砸到了'), pk::get_person(target.leader), target);
}
}
auto unit_p = ch::get_unit_p(attacker.get_id());
int kgj=unit_p.wounded/20; //所扣功绩为伤病数除以20
pk::person@ p0 = pk::get_person(attacker.member[0]);
pk::person@ p1 = pk::get_person(attacker.member[1]);
pk::person@ p2 = pk::get_person(attacker.member[2]);
pk::list<pk::person@> member_list;
if (pk::is_alive(p0)) member_list.add(p0);
if (pk::is_alive(p1)) member_list.add(p1);
if (pk::is_alive(p2)) member_list.add(p2);
int n = member_list.count;
if (pk::is_alive(p0)) pk::add_kouseki(p0, -kgj/n);
if (pk::is_alive(p1)) pk::add_kouseki(p1, -kgj/n);
if (pk::is_alive(p2)) pk::add_kouseki(p2, -kgj/n);
if(unit_p.wounded> 0)
pk::history_log(attacker.pos, pk::get_force(attacker.get_force_id()).color, pk::encode(pk::format("\x1b[2x{}\x1b[0x等人投射尸体,甚失朝望,每人扣除\x1b[2x{}\x1b[0x点功绩",pk::decode(pk::get_name(attacker)), kgj/n)));
unit_p.wounded = 0;//伤兵被投石扔出去,清零
if ( == 部队状态_中毒)
pk::set_status(attacker, null, 部队状态_通常, 1, true);
}
}
int 投石中毒成功率(pk::unit @attacker, pk::unit @target, bool critical)
{
int rate = 10; // 基础成功率0%
auto unit_p = ch::get_unit_p(attacker.get_id());
rate += unit_p.wounded/ 50;//每50个伤兵增加1%的成功率
rate = pk::min(rate, 100); // 最高100%
return rate;
}
// 计算止行成功率
int 阻击止行成功率(pk::unit @attacker, pk::unit @target,bool critical)
{
int rate = 40; // 基础成功率40%
if (critical)
rate = 70;
// 方位加成
int direction = batt::get_unit_direction(attacker, target);
rate += get_direction_damage_ratio(direction);
// 兵力差距加成 (每500兵力差距增加/减少2%)
int troops_diff = int(attacker.troops) - int(target.troops);
// 修复: 调整除法顺序以提高精度
rate += (troops_diff * 2) / 500;
// 攻防差距加成 (每10点攻防差距增加/减少3%)
int atk_def_diff = ch::get_unit_infact_able(attacker) - ch::get_unit_infact_able(target);
// 修复: 调整除法顺序以提高精度
rate += (atk_def_diff * 3) / 10;
// 确保成功率在合理范围内
rate = pk::max(rate, 20); // 最低20%
// 添加上限检查
rate = pk::min(rate, 100); // 最高100%
return rate;
}
// 计算中毒成功率
int 毒箭中毒成功率(pk::unit @attacker, pk::unit @target, bool critical)
{
int rate = 50; // 基础成功率50%
if (critical)
rate = 90;
// 兵力差距加成 (每500兵力差距增加/减少2%)
int troops_diff = int(attacker.troops) - int(target.troops);
// 修复: 调整除法顺序以提高精度
rate += (troops_diff * 2) / 500;
// 地形加成
pk::hex @hex = pk::get_hex(target.get_pos());
if (hex !is null && hex.terrain == 地形_毒泉)
rate += 50; // 毒泉中更容易中毒
// 确保成功率在合理范围内
rate = pk::max(rate, 15); // 最低15%
// 添加上限检查
rate = pk::min(rate, 100); // 最高100%
return rate;
}
// 计算动摇率
int 螺旋突成功率(pk::unit @attacker, pk::unit @target, bool critical)
{
int rate = pk::max(BASE_STUN_RATE, 20);
if (critical)
rate = pk::max(CRITICAL_STUN_RATE, 20);
// 地形修正
pk::hex @target_hex = pk::get_hex(target.get_pos());
pk::hex @attacker_hex = pk::get_hex(attacker.get_pos());
if ((target_hex !is null && target_hex.terrain == 地形_森) || (attacker_hex !is null && attacker_hex.terrain == 地形_森))
rate += 20;
if ((target_hex !is null && target_hex.terrain == 地形_崖) || (attacker_hex !is null && attacker_hex.terrain == 地形_崖))
rate += 5;
// 其他修正
if (attacker_hex !is null && pk::has_tech(attacker, 技巧_奇袭) && attacker_hex.terrain == 地形_森)
rate += 10;
// 添加状态验证
if ( != 部队状态_通常)
rate += 10;
if ( == 兵器_枪 && == 兵器_战马)
rate += 10;
if ( == 兵器_枪 && == 兵器_戟)
rate -= 10;
// 修复: 先转换为int进行计算
int atk = ch::get_unit_infact_able(attacker);
int def = ch::get_unit_infact_able(target, 部队能力_防御);
rate += (atk - def) / 10; // 简化计算,避免精度损失
// 修复: 兵力差距计算
int troops_diff = int(attacker.troops) - int(target.troops);
rate += troops_diff / 500;
int direction = batt::get_unit_direction(attacker, target);
rate += get_direction_damage_ratio(direction);
// 添加最终的边界检查
rate = pk::max(0, pk::min(rate, 100)); // 确保概率在0-100之间
return rate;
}
// 计算动摇时间
int 螺旋突动摇时间(pk::unit @attacker, pk::unit @target, bool critical)
{
int time = 80;
// 地形修正
pk::hex @target_hex = pk::get_hex(target.get_pos());
pk::hex @attacker_hex = pk::get_hex(attacker.get_pos());
if ((target_hex !is null && target_hex.terrain == 地形_森) || (attacker_hex !is null && attacker_hex.terrain == 地形_森))
time += 50;
if ((target_hex !is null && target_hex.terrain == 地形_崖) || (attacker_hex !is null && attacker_hex.terrain == 地形_崖))
time += 20;
// 其他修正
if ( != 部队状态_通常)
time += 50;
int direction = batt::get_unit_direction(attacker, target);
time += get_direction_damage_ratio(direction) * 2;
// 修复: 先转换为int进行计算
int atk = ch::get_unit_infact_able(attacker);
int def = ch::get_unit_infact_able(target, 部队能力_防御);
time += (atk - def) / 5; // 简化计算,避免精度损失
time += pk::rand(30);
if (critical)
time += 30;
time = pk::max(time, 100);
time = pk::min(time, 200);
return time;
}
// 根据攻击方向调整伤害修正值
int get_direction_damage_ratio(int damage_dir)
{
switch (damage_dir)
{
case 0:
return -10;
case 1:
return 0;
case 2:
return 10;
case 3:
return 20;
default:
return 0;
}
}
}
Main main;
} // namespace TACTICS_STATUS
- 下载图片
- 复制图片
2025-05-04
浏览1112
修改心得
登录后评论
10
4
分享