您的位置: 单机 > 攻略 > 游戏秘籍 > 攻略详情

城市:天际线 MOD制作教程 MOD源码解析及开发指南

时间:2015-04-17 21:40:07
  • 来源:3DM论坛-xxyztwz
  • 作者:售梦者
  • 编辑:售梦者
0

三、进阶篇

然后就是我们的hack时间了。这部分没有任何官方说明,出现的bug也只能靠我们自己解决,出现任何奇怪的事情都是正常的。然后我们继续。

要替换官方的BusAI,最简单的方法我相信大家已经猜到了,就是继承官方的AI,然后仅仅修改我们需要修改的部分就好了。那么,我也是这么干的。

看代码:

using ColossalFramework;

using UnityEngine;

namespace SuperBigTransport

{

class BigBusAI : BusAI, IAIReplacement//继承官方的BusAI

{

public void CopyFrom(BusAI ai)//我们自己定义的接口,主要用于两个AI的属性对拷

{

m_passengerCapacity = Mod.unit_number * 5;//这里是公交的容量,但是这个数字仅仅是显示用的,实际上,能上多少人不已这里为准。窃以为,这是官方代码的bug

m_ticketPrice = ai.m_ticketPrice;//车票多少钱,这个我没改过,不知道是不是只改这里就是增加车票收入,有兴趣的同学可以试试。

m_info = ai.m_info;//info,就是bus的基本信息,busInfo,前面提到过的,忘了的话自己回去看。但是不管它是什么,拷过来就好了

}

public override bool ArriveAtDestination(ushort vehicleID, ref Vehicle vehicleData)//复写官方的车辆到站后的处理逻辑。官方的方法里,车到站以后有很多的判定步骤,要判断该下多少人,能上多少人,是否是终点站,等等一大堆。我没把握能全部写好,而能上多少人这个方法它又是private的(日),所以,只能改这个,并且最后一步还的调用base的方法。

{

var citizenManager = Singleton.instance;//OK这里就是调用各种Manager单例的方法,前面欠大家的代码这里补上了。

var unitId = vehicleData.m_citizenUnits;//好了,这里涉及到另一件事情,是citizen所特有的概念,citizenUnit,前面的public const int unit_number = 16;就是跟这个相关的。这里呢,每个citizenUnit里面能装5个citizen,一个citizen可以被装在多个citizenUnit里,装的也仅仅是引用。citizenUnit是一个链表结构,citizenUnit有一个属性是nextUnit,就是下一个citizenUnit的引用,如果没有下一个,就是0,说明链表结束。那么这个citizenUnit用在哪里呢?这么说,所有能装人的地方,本质上就是这个citizenUnit有多长的结构。每辆车、每个建筑物,都有一个citizenUnit的引用,指向的是第一个citizenUnit的位置。所以,我们要增容,就是扩展这个citizenUnit。

var cu = citizenManager.m_units.m_buffer[unitId];//这行代码说明,citizenUnit也是由CitizenManager来统一管理的

int i = 1;

while (cu.m_nextUnit>0) {//判一下当前的容量数是多少

i++;

cu = citizenManager.m_units.m_buffer[cu.m_nextUnit];

}

if (i != Mod.unit_number) {//如果不等于预期,就改

uint firstId;

var random = new ColossalFramework.Math.Randomizer();

citizenManager.CreateUnits(out firstId, ref random, 0, vehicleID, 0, 0, 0, Mod.unit_number * 5, 0);//citizenUnit既然是由CitizenManager来统一管理的,那么创建肯定也是由CitizenManager来统一做的。我们简单的在这里创建了一个符合我们预期长度的citizenUnit

vehicleData.m_citizenUnits = firstId;//然后粗暴的直接替换

//citizenManager.ReleaseUnits(unitId);//这里不能释放,释放了市民就找不到路了。释放了有什么效果请自行观察。

}

return base.ArriveAtDestination(vehicleID, ref vehicleData);

}

}

}

好了,这里就是我们增容的核心代码了。那么现在有一个bug,就是公交会闪。在这里我表示我非常的冤枉,跟我真的没啥关系。。。。我没动frame..我只是替换了个数组。

所以,这个替换是非常生硬的,直接的后果就是会导致存档发生变化。即使关闭了mod,也无法改变已经客观存在的链表结构。所以我说嘛。。官方偷懒。。不好好的调用那个容积属性进行判断。。非要搞数组,还是链表结构的。。。真是无语。

然后,上面只是公交车的,下面是地铁和客运火车的。我直接贴代码了,因为结构差不多,我就不解释了。有一个小bug,会导致一个不合理的现象,但是很隐蔽,不知道大家能发现么?

using ColossalFramework;

using System.Collections.Generic;

namespace SuperBigTransport

{

class BigPassengerTrainAI : PassengerTrainAI, IAIReplacement

{

public void CopyFrom(PassengerTrainAI ai)

{

m_passengerCapacity = Mod.unit_number * 5;

m_ticketPrice = ai.m_ticketPrice;

m_info = ai.m_info;

m_arriveEffect = ai.m_arriveEffect;

m_transportInfo = ai.m_transportInfo;

}

CitizenManager citizenManager = Singleton.instance;

public override bool ArriveAtDestination(ushort vehicleID, ref Vehicle vehicleData)

{

var unitId = vehicleData.m_citizenUnits;

var cu = citizenManager.m_units.m_buffer[unitId];

int i = 1;

while (cu.m_nextUnit > 0)

{

i++;

cu = citizenManager.m_units.m_buffer[cu.m_nextUnit];

}

uint firstId;

int n;

if (i < Mod.unit_number)

{

var random = new ColossalFramework.Math.Randomizer();

if (vehicleData.m_transferType==39)//metro

{

n = (Mod.unit_number-i) * 5*6 + 30;

citizenManager.CreateUnits(out firstId, ref random, 0, vehicleData.GetFirstVehicle(vehicleID), 0, 0, 0, n, 0);

}else

{

n = (Mod.unit_number-i) * 5 *8 + 30;

citizenManager.CreateUnits(out firstId, ref random, 0, vehicleData.GetFirstVehicle(vehicleID), 0, 0, 0, n, 0);

}

vehicleData.m_citizenUnits = firstId;

//citizenManager.ReleaseUnits(unitId);

}

else if (i > Mod.unit_number)

{

var random = new ColossalFramework.Math.Randomizer();

if (vehicleData.m_transferType == 39)//metro

{

firstId = citizenManager.m_units.m_buffer[unitId].m_nextUnit;

citizenManager.ReleaseUnits(unitId);

vehicleData.m_citizenUnits = firstId;

n = (Mod.unit_number - 6) * 5 * 6 + 30;

}

else

{

firstId = citizenManager.m_units.m_buffer[unitId].m_nextUnit;

citizenManager.ReleaseUnits(unitId);

vehicleData.m_citizenUnits = firstId;

n = (Mod.unit_number - 6) * 5 * 8 + 30;

}

citizenManager.CreateUnits(out firstId, ref random, 0, vehicleData.GetFirstVehicle(vehicleID), 0, 0, 0, n, 0);

vehicleData.m_citizenUnits = firstId;

}

return base.ArriveAtDestination(vehicleID, ref vehicleData);

}

}

}

友情提示:支持键盘左右键"←""→"翻页
7.7
已有5589人评分 您还未评分!
  • 类型:模拟经营
  • 发行:Paradox Interactive
  • 发售:2015-03-10(PC)
  • 开发:Colossal Order
  • 语言:简中 | 英文
  • 平台:PC PS4 XBOXONE
  • 标签:建造开放世界XGP游戏列表

玩家点评 0人参与,0条评论)

收藏
违法和不良信息举报
分享:

热门评论

全部评论

Steam正版购买
今日特惠城市:天际线
城市:天际线
-54%¥108¥49.9
立即购买
3DM自运营游戏推荐 更多+