Hello,我是steve_666,一个模组,怪物是不可或缺的部分(新物品肯定不能全靠交易、挖矿合成获得啊)
现在,我们来写一个基础的npc吧
创建&属性
首先,要用 public class XXX : ModNPC
来创建一个基础的npc类
当然,npc也要有一个图片,这里选用的是原版的僵尸新郎的图片
接下来就是属性的部分,与弹幕、物品相同,NPC的属性也可以用 SetStaticDefaults
和 SetDefaults
来定义
SetStaticDefaults
很好理解,也很容易写,主要就是名字和帧图数量等
接下来就是 SetDefaults
了,首先让我们看看代码
public override void SetDefaults() { npc.width = 34; npc.height = 162/3; npc.damage = 200; npc.lifeMax = 1100; npc.defense = 100; npc.knockBackResist = 0f; npc.aiStyle = -1; npc.HitSound = SoundID.NPCHit1; npc.DeathSound = SoundID.NPCDeath6; npc.value = Item.buyPrice(0, 0, 15, 0); npc.buffImmune[BuffID.Poisoned] = true; npc.buffImmune[BuffID.Venom] = true; banner = npc.type; bannerItem = ItemID.Gel; Main.npcFrameCount[npc.type] = 3; npc.noGravity = false; npc.noTileCollide = false; aiType = -3;//这边为了方便直接写了ID(绝对不是懒 animationType = -3; npc.boss=true; }
是不是看上去很多?来,我们一条一条解析
npc.width
和 npc.height
是NPC的长和宽,由于NPC是帧图,所以这个也是每一帧的长和宽。
npc.damage
、npc.lifeMax
、npc.defense
就不用多说了吧,毕竟从字面上就可以看出
npc.knockBackResist
需要注意一下,虽然翻译为击退抗性但是这个值越大反而受到的击退越高,设置成0为免疫击退!
npc.HitSound
、npc.DeathSound
是受伤和死亡的声音
banner
、bannerItem
是他们的旗帜类型和旗帜掉落物品,掉落物品一般是设置成这个NPC的旗帜物品ID,当然你想设置别的也可以 ,比如我这是凝胶 ,而 banner
则一般是这个npc的类型,即 npc.type
,当然,设置成别的也可以,比如你的npc是僵尸的变种,你想要它的击杀数算到僵尸的击杀数里,你就可以用僵尸的ID。它们的前面没有npc.
接下来就是重点 npc.aiStyle
比如你想要这个NPC像史莱姆一样,你就可以填入史莱姆的AI类型,可问题来了,这么多史莱姆,我只想用猩红史莱姆的AI,该怎么办?
确实,所以 aiStyle
只能复制一个大类的AI,要精确到单独的NPC还得用 aitype
, aitype
填入单独的ID即可。但是这样子,还是有一个问题,那就是,我们的NPC它的动画没有完全复制,所以,我们的 animationType
就要来了,它可以完全套用另一个帧图动画,也是填NPC的类型ID,我这里填的是史莱姆的ID。但是这两个属性的前面都没有npc.
。
还有很多比如 npc.buffImmune
后面的 []
里面只要填buff的ID再加上 =true
即可让npc免疫这个buff,npc.value
是npc掉落的钱,npc.noGravity
控制了npc是否不受重力影响,而 npc.noTileCollide
则代表了npc是否受可以穿墙(如果 npc.noGravity
为true,那么这个最好为false,否则npc会掉到地狱底层),npc.boss
如果为true会让TR把它标记成一个boss,他就会死亡掉落生命恢复药水、大量心,并且还会有“XXX已被打败”等!
实用の重写函数:自然生成NPC
npc属性搞定了,但是这个npc不会自然生成,所以我们要定义生成几率
public override float SpawnChance(NPCSpawnInfo spawnInfo) { if (Main.bloodMoon) return 1.0f; return 0.25f; }
这段代码的意思是:在血月时有1.0(注意:1.0的生成几率很高!)的几率生成,其他时候只有0.25的几率生成。
而如果我们想要让它的生成几率是地表史莱姆的0.5倍时,我们可以:
public override float SpawnChance(NPCSpawnInfo spawnInfo) { return SpawnCondition.OverworldDaySlime.Chance * 0.5f; }
SpawnCondition
里面预制了很多原版生物生成条件
如果我们想要一些奇奇怪怪的生成位置,比如…在下雨的白天的神圣之地的天空中的黑曜石上有0.1的几率生成
首先,下雨的我们可以用Main.raining
,如果在雨它会返回true否则会返回false
所以,如果我们想让一个敌怪只在下雨时有0.25生成,那么可以
public override float SpawnChance(NPCSpawnInfo spawnInfo) { if (Main.raining) return 0.25f; return 0; }
当然还有很多Main函数,比如:
Main.hardMode
会在困难模式返回true,Main.expertMode
会在专家模式返回true,Main.dayTime
会在白天返回true(晚上返回false),还有很多Main.的那种,这里只说比较常用的,别的交给自动补全吧!
NPC.AnyNPCs(NPCID.IceGolem)
如果世界上有冰傀儡,就返回true(召唤师怪物预定)
Math.Abs(spawnInfo.spawnTileX - Main.spawnTileX) > Main.maxTilesX / 3
– 如果生成图块位于地图的外侧三分之一上,则为 true
NPC.waveNumber
事件期间的波数,会返回一个值(全地图式傻蛋撒旦军队预定)
NPC.CountNPCS(NPCID.IceGolem) < 2
如果世界上存在少于2个NPC,则为真(有召唤上限的召唤师预定)
当然这些还不够,如果我们要让怪物在大气层生成,该怎么办呢?
在官网中有一张图:
这就很好了,但是直接在if里面写上 ZoneSkyHeight
,如果不出意外的话,那这段代码就肯定出了意外。
那要怎么写呢。。。等等,我们重写函数中的 spawnInfo
还没用啊,所以我们可以。。。
if(spawnInfo.player.ZoneSkyHeight) return 1.0f;
OHHH,成功了!!!!
例子:
return spawnInfo.spawnTileType == mod.TileType<Tiles.CrystalBlock>() ? .1f : 0f;//在自己的物块上生成(类if格式:条件 ? .成立数值:不成立数值)
return spawnInfo.player.GetModPlayer<modplayer2>().wuhu ? .1f : 0f;//当modplayer2的wuhu属性为true时生成
//在丛林神庙中生成 return spawnInfo.spawnTileType == TileID.LihzahrdBrick && spawnInfo.lihzahrd ? .1f : 0f;
实用の重写函数:掉落物
要用掉落物,我们能用NPCLoot来定义
public override void NPCLoot() { // 2% 几率掉落 if (Main.rand.Next(50) == 0) { Item.NewItem((int)npc.position.X, (int)npc.position.Y, npc.width, npc.height, 物品ID,数量); //具体内容可以试试自动补全 } }
实用の重写函数:AI
public override void AI() { }
这个以后会讲它的编写
实用の重写函数:FindFrame
NPC的动画也是要自己编写的(用了animationType的当我没说)
与弹幕不同的是,NPC在frame上面,有专门的函数TML区别对待,双标实锤
public override void FindFrame(int frameHeight) { //代码放这 }
NPC的帧数很奇怪,它是 npc.frame.Y
来控制的,这个东西,它的更改是精确到像素的!并不是像弹幕一样精确到高度的,所以要用到这个重写函数。
注意到那个 frameHeight
了吗?它是每一帧的高度。
一般来说,我们只需要设置 npc.frame.Y
为 第X个帧 * frameHeight
就可以切换到第X帧了。当然,注意下标是从0开始的。
小结:
这一讲的内容基本结束了,虽然没讲自定义AI,但是学会后最好自己试着写一下AI,即使是一个定时发射弹幕的AI也行。
对于在特定生物群系生成的问题,可以用if(spawnInfo.player.XXX),一下是XXX列表
ZoneDungeon – 地牢
ZoneCorrupt – 腐化
ZoneHoly – 神圣
ZoneMeteor – 流星
ZoneJungle – 丛林
ZoneSnow – 雪原
ZoneCrimson – 血腥
ZoneWaterCandle – 水蜡烛附近
ZonePeaceCandle – 和平蜡烛附近
ZoneTowerSolar – 日耀柱
ZoneTowerVortex – 星璇柱
ZoneTowerNebula – 星云柱
ZoneTowerStardust – 星尘柱
ZoneDesert – 沙漠
ZoneGlowshroom – 发光蘑菇
ZoneUndergroundDesert – 地下沙漠
ZoneSkyHeight – 天空层
ZoneOverworldHeight – 地表层
ZoneDirtLayerHeight – 泥土层
ZoneRockLayerHeight – 岩石层
ZoneUnderworldHeight – 地狱层
ZoneBeach – 沙滩
ZoneRain – 雨
ZoneSandstorm – 沙尘暴
怎么让NPC掉落mod里的物品?
同问
Pingback: 创建一个基础城镇NPC - 裙中世界
Pingback: Boss的创建与基础重写函数 - 裙中世界