您的位置: 單機 > 攻略 > 游戲秘籍 > 攻略詳情

城市:天際線 MOD制作教程 MOD源碼解析及開發(fā)指南

時間:2015-04-17 21:40:07
  • 來源:3DM論壇-xxyztwz
  • 作者:售夢者
  • 編輯:售夢者
0

三、進階篇

然后就是我們的hack時間了。這部分沒有任何官方說明,出現的bug也只能靠我們自己解決,出現任何奇怪的事情都是正常的。然后我們繼續(xù)。

要替換官方的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來統(tǒng)一管理的

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來統(tǒng)一管理的,那么創(chuàng)建肯定也是由CitizenManager來統(tǒng)一做的。我們簡單的在這里創(chuàng)建了一個符合我們預期長度的citizenUnit

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

//citizenManager.ReleaseUnits(unitId);//這里不能釋放,釋放了市民就找不到路了。釋放了有什么效果請自行觀察。

}

return base.ArriveAtDestination(vehicleID, ref vehicleData);

}

}

}

好了,這里就是我們增容的核心代碼了。那么現在有一個bug,就是公交會閃。在這里我表示我非常的冤枉,跟我真的沒啥關系。。。。我沒動frame..我只是替換了個數組。

所以,這個替換是非常生硬的,直接的后果就是會導致存檔發(fā)生變化。即使關閉了mod,也無法改變已經客觀存在的鏈表結構。所以我說嘛。。官方偷懶。。不好好的調用那個容積屬性進行判斷。。非要搞數組,還是鏈表結構的。。。真是無語。

然后,上面只是公交車的,下面是地鐵和客運火車的。我直接貼代碼了,因為結構差不多,我就不解釋了。有一個小bug,會導致一個不合理的現象,但是很隱蔽,不知道大家能發(fā)現么?

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
已有5609人評分 您還未評分!

玩家點評 0人參與,0條評論)

收藏
違法和不良信息舉報
分享:

熱門評論

全部評論

Steam正版購買
今日特惠城市天際線DLC 日落港灣
城市天際線DLC 日落港灣
-41%¥64¥38
立即購買
3DM自運營游戲推薦 更多+