三、進階篇 城市:天際線,MOD製作教程 MOD源碼解析及開發指南
三、進階篇
然後就是我們的hack時間了。這部分沒有任何官方說明,出現的bug也只能靠我們自己解決,出現任何奇怪的事情都是正常的。然後我們繼續。
要替換官方的BusAI,最簡單的方法我相信大家已經猜到了,就是繼承官方的AI,然後僅僅修改我們需要修改的部分就好了。那麼,我也是這麼幹的。
看代碼:
using ColossalFramework;
using UnityEngine;
namespace SuperBigTransport
{
class BigBusAI : BusAI, IAIReplacement
{
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
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
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);
}
}
}
-
雷神龍 怪物獵人崛起全怪物圖鑑 怪物肉質弱點及屬性掉落一覽
33、雷神龍①雷神龍肉質/抗性②雷神龍異常狀態效果...
-
羣雄割據:滅劉繇/滅嚴白虎 真三國無雙8帝國攻略 系統玩法詳解及劇本流程攻略
奪會稽滅劉繇劉繇率兵攻打交趾,來勢洶洶,向交趾增派援軍,最好上幾個將軍。防守戰,直接奪取攻城車攻城塔和投石車,地圖上的敵將都清理了。劉繇手下都是普通將軍,沒有招募價值,此戰可以直奔敵軍大本營速戰。因爲劉繇剛剛被擊敗,所以都是一些殘兵,下個回合直接攻打會稽。自...
-
熔岩洞:百龍夜行筆記 怪物獵人崛起先人遺物收集 筆記收集輔助營地位置副營地位置
百龍夜行筆記1區域3地圖邊緣,跳到下方的巖臺上。百龍夜行筆記2區域11附近的地下。通過狹窄的通道進入密室。牆上可見裂隙,跳進去。走過通道後向左。熔岩瀑布邊緣可以發現收集品。地圖(金色數字)...
-
魏國篇(1) 真三國無雙8帝國全武將圖鑑 全勢力武將特性及武器
魏國篇典韋怪力巨漢,曹操的護衛,宛城之戰犧牲自己讓曹操脫險。擅長武器:巨斧兵種:步兵高攻低速武將,擅長使用巨斧,攻擊威力巨大,對付普通的士兵和武將都不錯,被弓兵剋制。曹操魏國君主,文武全才,不僅善於領兵打仗,而且寫得一手好詩,並且留下了兵法。擅長武器:刀劍兵種:騎兵屬...
相關文章
- 城市:天際線 建築MOD 超大垃圾場MOD下載
- 城市:天際線 建築MOD製作方法圖文教程 MOD怎麼製作
- 城市天際線mod放哪裏,mod超詳細安裝指南
- 二、基本API解讀 城市:天際線,MOD製作教程 MOD源碼解析及開發指南
- 城市:天際線,破解版使用STEAM正版MOD方法圖文教程
- 城市:天際線 MOD製作教程 MOD源碼解析及開發指南
- 四:其他 城市:天際線,MOD製作教程 MOD源碼解析及開發指南
- MOD教程:MOD製作圖文教程 坎巴拉太空計劃詳細攻略教程 系統解析祕籍MOD大全
- 輻射4MOD開發資源教程大全,MOD製作修改導出圖文教學
- 城市:天際線 地圖MOD 免費解鎖全部區域數量MOD