Special AI(mod-overview)

基本信息

属性 值
模组名 Special AI
Mod ID SpecialAI
包名 toast.specialAI
作者 FatherToast
类型 Mob AI 行为扩展(不开新方块/物品/维度)
Forge 版本 MinecraftForge 1.7.10
主类 toast.specialAI._SpecialAI
入口 @Mod(modid = "SpecialAI", name = "Special AI")

简介

Special AI 是一个为 Minecraft 1.7.10 的原版怪物与被动生物追加高级 AI 行为的 mod。它不注册任何方块/物品/维度,全部内容都是通过 Forge 事件总线注入到现有 EntityLiving 上的自定义 EntityAIBase:

  • 让被动生物(鸡、牛、猪、羊)主动反击伤害者
  • 让怪物主动破坏特定方块(灯、农场、门、床、工作台、梯子、拉杆、按钮、蛋糕)
  • 让怪物翻动开关/按钮(fiddling)
  • 随机给予怪物特殊 AI 模式(charge 冲刺、barrage 弹幕、spawner 召唤、leap 跳斩、jump 跳踏、sprint 追击、shaman 治疗、throw 投掷、throw_player 投掷玩家、thief 偷窃)
  • 玩家击倒/杀害怪物时被附近同类呼救
  • 村民主动防御村庄攻击声誉差的玩家
  • 玩家破坏村庄方块会扣村庄声誉
  • 玩家在村庄附近击杀怪物会获得少量村庄声誉

主类核心

_SpecialAI.java 在 preInit 中加载 Properties.init(config),在 init 中实例化 AIHandler() 与 ReputationHandler(),二者分别监听 FMLCommonHandler.bus() 与 MinecraftForge.EVENT_BUS。

配置分类

Special AI 的所有功能通过单一 config/SpecialAI.cfg 文件配置,分为 6 个分类(见 配置项总览):

分类 说明
_general 通用开关(避爆、呼救、被动生物反击、吃育种物品)
jockeys 骑乘系统(哪些生物可被骑、哪些可骑)
passive_fiddling 被动翻动开关(拉杆、按钮等)
passive_griefing 被动破坏方块(农场、门、床等)
special_ai 10 个特殊 AI 模式的加权抽取
villages 村庄防御、声誉、黑/白名单

NBT 标签

每个被增强的实体在 _SpecialAI.getTag(entity) 返回的 sAI 子 NBT 中存储启用/关闭状态,用于保证配置变更不会反复重置已生成实体(数据持久化)。

标签 含义
AvoidExplosions 是否启用避爆 AI
DefendVillage 村民是否攻击村庄攻击者
Depacify 被动生物反击等级(0=否,1=中立,2=主动攻击)
Rider 是否生成骑手 AI
Griefing 是否启用被动破坏
Fiddling 是否启用被动翻动
uAI 已分配的特殊 AI 子标签

辅助类

EffectHelper

  • stackEffect(entity, potion, duration, amplifier):效果叠加(已存在取最长时长 + 增幅+1)
  • stackEffect(entity, potion, duration, amplifier, amplifierMax):带增幅上限的版本
  • addModifier(itemStack, attribute, value, operation):在物品 NBT 的 AttributeModifiers 上追加一条属性修饰符,UUID 随机

MobHelper(占位)

只保留 SpecialMobs 2.6 兼容注释,未启用。

BlockHelper

  • shouldDamage(block, entity, needsTool, world, x, y, z):方块硬度 ≥ 0 且(needsTool=false 或材质无需工具或工具可采集)
  • getDamageAmount(...):计算该 tick 累加的方块伤害
    • 不可正确采集:SPEED_MULT / hardness / 100
    • 否则:getCurrentStrengthVsBlock(...) * SPEED_MULT / hardness / 30
  • getCurrentStrengthVsBlock(entity, block, meta):模拟玩家挖掘速度(急迫、挖掘减速、水下效率、空中)
  • newBlockSet(line):把 "farmland,bed,cake 0,minecraft:*" 解析成 HashSet<TargetBlock>
  • getStringAsBlock(id):先注册表名查,再用数字 ID,最后输出 [WARNING] Missing or invalid block!

EntitySet

构造时把 Chicken,Cow,~Zombie 解析为 EntryEntity[]:

  • 默认 EXTEND=true:子类也命中
  • ~ 前缀:EXTEND=false:只匹配精确类(不取子类)

contains(entity) 用 entity.getClass() 与列表中各条目做 isAssignableFrom 判定。

TargetBlock

简单的 Block + BLOCK_DATA(-1|0..15) 元组。equals 在 BLOCK_DATA < 0 时忽略对方 metadata(视为通配)。

EntityFakePlayer

继承 ForgeHooks.FakePlayer,构造时:

super(worldServer, GameProfile(null, "[SpecialAIFakePlayer]"));
foodStats = new FakeFoodStats(this);
copyLocationAndAnglesFrom(entity);
motionX/Y/Z = entity.motionX/Y/Z;

所有 heal/setHealth/attackEntityFrom/knockBack/isEntityAlive/getActivePotionEffects/addPotionEffect/.../getEntityAttribute/getAttributeMap 等方法都直接代理到 wrappedEntity(被包装的真实实体)。FakeFoodStats 把 addStats 重定向到 wrappedEntity.setHealth(+food)。

updateWrappedEntityState() 在 fiddling 完成后调用:把 fakePlayer 改动(位置、motion)同步回 wrappedEntity。

用于 fiddling:targetBlock.onBlockActivated(world, x, y, z, fakePlayer, side, 0.5, 0.5, 0.5)。

子维度