【TMOD】TMLMOD制作:从入门到入土

@TMdb使者




然后引用terraria之后,就会有对应变量和方法了√

楼主 清水之火  发布于 2017-08-13 13:03:00 +0800 CST  

本章没图注意。
那么终于到了npc啦!_(:3」∠)_这个部分因为稍微深入了一点,所以我分两部分,先讲大概,后面可能会把AI讲一下。那么废话不多说
首先是贴图和cs文件,我们准备好√!
不过在写npc之前,有一个前置
如果你想对原版或者指定npc的死亡,掉落等有特殊变更的话,那么你需要一个GlobalNPC.cs
哦对了,补充一点,对于using指令,一般都是默认的几个,如果需要更多的拓展,再using也不迟,或者你把要用的或者不用的类都using上也没关系啦
比如我们这个GlobalNPC.cs
using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Terraria;
using Terraria.DataStructures;
using Terraria.ID;
using Terraria.ModLoader;
using Terraria.ModLoader.IO;
using Terraria.World.Generation;
using Terraria.GameContent.Generation;
using System.Threading;
using Terraria.Localization;
Using了一大堆,具体就不详细讨论了。
namespace DeadLine.NPCs
{
public class Globalnpc : GlobalNPC
{
public override bool InstancePerEntity
{
get
{
return true;
}
} //这个最好加上,否则会报错。
//代码块
}
}
代码块里就写你想要的内容啦
那么得先提供几个方法
public override void ResetEffects(NPC npc)//给npc提供effect,比如让npc发光,给它个发光药剂的效果,也是可以的?
public override void UpdateLifeRegen(NPC npc, ref int damage) //这个是npc回血重写。
public override void NPCLoot(NPC npc)//这个是,npc死亡之后,调用这个方法,比如死后给玩家加血什么的~,或者说,给怪物升级什么的,也是可以的啊。
public override void DrawEffects(NPC npc, ref Color drawColor)//给npc的效果的绘制。比如新buff之类的,给npc添加冰霜效果。
public override void EditSpawnRate(Player player, ref int spawnRate, ref int maxSpawns)//改变怪物生成几率。
例子:if (player.maxmana > 100) //maxmana我随便写的,鬼知道有没有这个变量。
{
spawnRate = (int)(spawnRate * 5f);
maxSpawns = (int)(maxSpawns * 5f);
}
public override void SetupShop(int type, Chest shop, ref int nextSlot) 给原版城镇npc增加新的售卖物品。
例子:if (type == NPCID.Dryad)
{
shop.item[nextSlot].SetDefaults(mod.ItemType<Items.CarKey>());
nextSlot++;

shop.item[nextSlot].SetDefaults(mod.ItemType<Items.CarKey>());
shop.item[nextSlot].shopCustomPrice = new int?(2);
shop.item[nextSlot].shopSpecialCurrency = CustomCurrencyID.DefenderMedals;
nextSlot++;
}
这个例子里面,你会发现,明明都是卖的carkey,为什么有不同的写法?下面解释
shop.item[nextSlot].shopCustomPrice = new int?(2),这个是指,售卖的(价格)个数,个数?价格?
因为shop.item[nextSlot].shopSpecialCurrency = CustomCurrencyID.DefenderMedals;这行,写的是,这个carkey可以用护卫勋章购买,所以说就是这样写的~

楼主 清水之火  发布于 2017-08-19 01:27:00 +0800 CST  

这就是globalnpc里面可以拓展的基本内容。那么我们去创建npc吧。
为了方便,以后我可能会把namespace的内容都省略,如果有特殊情况再单一举例。
{
[AutoloadHead] //加载头部图片的属性
public class Person : ModNPC
{
//代码块。
}
}
那么代码块里提供方法
public override string Texture //加载材质
用法get
{
return "DeadLine/Npcs/Person";
} //epmod里面还有一个string[] AltTextures,是读取npc的另一个材质的,
用法一样。return new string[] { "ExampleMod/NPCs/ExamplePerson_Alt_1" };
public override bool Autoload(ref string name)
{//自动加载。
name = "Example Person";
return mod.Properties.Autoload;
}
name = "Example Person";
return mod.Properties.Autoload;
public override void SetStaticDefaults()//赋予npc基本状态。
{
DisplayName.SetDefault("Example Person");
Main.npcFrameCount[npc.type] = 25; //npc的帧数
NPCID.Sets.ExtraFramesCount[npc.type] = 9; //npc的附加帧数,比如挥手什么的。从第25-9-4的帧开始算起到第25-4帧结束
NPCID.Sets.AttackFrameCount[npc.type] = 4; //npc攻击帧数,从25-4帧开始算起。
//优先级:普通行动帧>行动帧>攻击帧,越往后的帧图优先度越低。
NPCID.Sets.DangerDetectRange[npc.type] = 700; //危险察觉范围,警觉度的感觉2333
NPCID.Sets.AttackType[npc.type] = 0; //攻击方式
NPCID.Sets.AttackTime[npc.type] = 90; //攻击间隔
NPCID.Sets.AttackAverageChance[npc.type] = 30; //攻击平均的几率 30%?
NPCID.Sets.HatOffsetY[npc.type] = 4; //在地图上的偏离程度,这个不要乱改。
}
public override void SetDefaults() //赋予npc属性
{
npc.townNPC = true;
npc.friendly = true;
npc.width = 18;
npc.height = 40;
npc.aiStyle = 7;
npc.damage = 817;
npc.defense = 817;
npc.lifeMax = 450;
npc.HitSound = SoundID.NPCHit1;
npc.DeathSound = SoundID.NPCDeath1;
npc.knockBackResist = 0.5f;
animationType = NPCID.Guide; //和向导的动作种类一样。
Main.npcFrameCount[npc.type] = 4; //如果你写那种4帧图的持续的那种飞行的动作之类的,用这个。
}
Npc的攻击也可以重写。
public override void TownNPCAttackStrength(ref int damage, ref float knockback)
攻击间隔
public override void TownNPCAttackCooldown(ref int cooldown, ref int randExtraCooldown)
攻击发射pro
public override void TownNPCAttackProj(ref int projType, ref int attackDelay)
攻击的pro的速度?
public override void TownNPCAttackProjSpeed(ref float multiplier, ref float gravityCorrection, ref float randomOffset)
以上4个方法的意义我不太明确,望指正。

public override void HitEffect(int hitDirection, double damage) //npc的攻击效果
public override bool CanTownNPCSpawn(int numTownNPCs, int money)
{
for (int k = 0; k < 255; k++)
{
Player player = Main.player[k];
if (player.active)
{
//代码块
}
}
return true;
} //如果是城镇npc的话,入住条件。
public override bool CheckConditions(int left, int right, int top, int bottom) //npc入住的房屋条件
{
int score = 0;
for (int x = left; x <= right; x++)
{
for (int y = top; y <= bottom; y++)
{
int type = Main.tile[x, y].type;
if (type == mod.TileType("ExampleBlock") || type == mod.TileType("ExampleChair") || type == mod.TileType("ExampleWorkbench") || type == mod.TileType("ExampleBed") || type == mod.TileType("ExampleDoorOpen") || type == mod.TileType("ExampleDoorClosed"))
{
score++;
}
if (Main.tile[x, y].wall == mod.WallType("ExampleWall"))
{
score++;
}
}
}
return score >= (right - left) * (bottom - top) / 2;
}//直接举例epmod了。_(:3」∠)_毕竟懒。
public override string TownNPCName()
{
return "Your name";}
public override string GetChat() //对话框
{
return "Test.";
}

//下面两个方法配套,自己看一下吧。
public override void SetChatButtons(ref string button, ref string button2)
{
button = Lang.inter[28].Value;
}
public override void OnChatButtonClicked(bool firstButton, ref bool shop)
{
if (firstButton)
{
shop = true;
}
}

public override void SetupShop(Chest shop, ref int nextSlot)//售卖的东西。
例子:shop.item[nextSlot].SetDefaults(mod.ItemType("DragonSword"));
nextSlot++;

然后就完成了一个基本的城镇npc的制作了。

那么我们如果做其他npc呢?需要别的什么吗?
当然有。
public override float SpawnChance(NPCSpawnInfo spawnInfo) //npc的生成几率
例子:return SpawnCondition.OverworldNightMonster.Chance * 0.5f;
public override void AI() //写AI。这个需要深入探讨,先不谈。
public override void FindFrame(int frameHeight) //意义不太明确的方法。

以上,基本能涵盖很多npc的写法,不过只是里面的变量的明确程度和脑洞的问题。

楼主 清水之火  发布于 2017-08-19 01:27:00 +0800 CST  
那么……也安慰一下催更的人吧_(:3」∠)_
@buiues_u1
@324fds324s
@1481351607
@LGDZS

楼主 清水之火  发布于 2017-08-19 01:29:00 +0800 CST  
破贴竟然没人了,惨。

楼主 清水之火  发布于 2017-08-19 12:05:00 +0800 CST  
-ED
半年后说不定更新。
嘛估计破tml就用不了了。
祝对各位有所帮助√!

楼主 清水之火  发布于 2017-08-28 02:01:00 +0800 CST  
。破游戏没更新,好嘛,我可以更新嘞

楼主 清水之火  发布于 2017-10-01 02:11:00 +0800 CST  
@夏衣又致
说起来我在pro里找不到星辰龙的ai定义在哪里……可能只是一个ai新定义,星辰龙是写pro本体的。(也就是跟ai 关系不大)这里是写星辰龙的定义
else if (this.type >= 625 && this.type <= 628)
{
if (this.type == 625 || this.type == 628)
this.netImportant = true;
if (this.type == 626 || this.type == 627)
this.minionSlots = 0.5f;
this.name = "Stardust Dragon";
this.width = 24;
this.height = 24;
this.aiStyle = 121;
this.penetrate = -1;
this.timeLeft *= 5;
this.minion = true;
this.friendly = true;
this.ignoreWater = true;
this.tileCollide = false;
this.alpha = (int) byte.MaxValue;
this.hide = true;
this.netImportant = true;
}
关于星辰龙的另一段,我在Update函数里找到了这么一段
if ((double) Main.player[this.owner].slotsMinions + (double) this.minionSlots > (double) Main.player[this.owner].maxMinions && this.owner == Main.myPlayer)
{
if (this.type == 627 || this.type == 626)
{
int byUuid = Projectile.GetByUUID(this.owner, this.ai[0]);
if (byUuid != -1)
{
Projectile projectile1 = Main.projectile[byUuid];
if (projectile1.type != 625)
projectile1.localAI[1] = this.localAI[1];
Projectile projectile2 = Main.projectile[(int) this.localAI[1]];
projectile2.ai[0] = this.ai[0];
projectile2.ai[1] = 1f;
projectile2.netUpdate = true;
}
}
this.Kill();
}
不过就我所看,一般mod pro的ai 都是自己写的……
对我 没思路 去索引 原版pro的ai

楼主 清水之火  发布于 2018-02-16 17:09:00 +0800 CST  
你裙不是自己搞了个教程吗
安利一波~大家可以移步
@裙仙DXT
http://www.fs49.org/
嘛 成功做出mod才是上上策

楼主 清水之火  发布于 2018-04-28 02:18:00 +0800 CST  

楼主:清水之火

字数:21256

发表时间:2017-06-25 23:23:00 +0800 CST

更新时间:2019-08-15 21:55:11 +0800 CST

评论数:468条评论

帖子来源:百度贴吧  访问原帖

 

热门帖子

随机列表

大家在看