我的世界工業(yè)2實驗版作物架植物生長速度詳解
小編為大家?guī)砹恕段业氖澜纭饭I(yè)2實驗版作物架植物生長速度詳解,作物架,在代碼中是一個名字為TileEntityCrop的類,顧名思義是一個TileEntity。TileEntity會在被加載的每個tick被調(diào)用一次updateEntity()方法,因此我們先來看看TileEntityCrop的updateEntity()方法(TileEntityCrop.txt, 行139~行162):
super.updateEntity();
this.ticker = ((char) (this.ticker + '\001'));
if ((this.ticker % tickRate) == 0) {
tick();
}
if (this.dirty) {
this.dirty = false;
this.worldObj.markBlockForUpdate(this.xCoord, this.yCoord, this.zCoord);
this.worldObj.updateLightByType(EnumSkyBlock.Block, this.xCoord, this.yCoord, this.zCoord);
if ((IC2.platform.isSimulating()) && (!IC2.platform.isRendering())) {
for (String field : getNetworkedFields()) {
((NetworkManager) IC2.network.get()).updateTileEntityField(this, field);
}
}
}
復(fù)制代碼
第一行調(diào)用了父類TileEntity的更新方法,不管它;if (this.dirty) {...} 這里處理的是光照計算、電網(wǎng)計算,和作物生長也沒有直接聯(lián)系;我們主要看中間部分:ticker域每tick加1,tickRate是一個等于256的常數(shù)。因此中間部分的作用,就是每256tick調(diào)用一次tick()方法。所以接下來我們來看看tick()方法,先看前半部分(TileEntityCrop.txt, 行182~行192):
if ((this.ticker % (tickRate << 2)) == 0) {
this.humidity = updateHumidity();
}
if (((this.ticker + tickRate) % (tickRate << 2)) == 0) {
this.nutrients = updateNutrients();
}
if (((this.ticker + (tickRate * 2)) % (tickRate << 2)) == 0) {
this.airQuality = updateAirQuality();
}
復(fù)制代碼
這里點(diǎn)出了影響作物生長速度的三大因素:濕度、營養(yǎng)和空氣質(zhì)量。這三個參數(shù)都是每1024個tick(即51.2s)更新一次。我們來一個一個看看它們的具體計算方式。
首先是濕度(humidity)。也就是updateHumidity()方法(TileEntityCrop.txt, 行910~行924):
int value = Crops.instance.getHumidityBiomeBonus(this.worldObj.getBiomeGenForCoords(this.xCoord, this.zCoord));
if (this.worldObj.getBlockMetadata(this.xCoord, this.yCoord - 1,this.zCoord) >= 7) {
value += 2;
}
if (this.waterStorage >= 5) {
value += 2;
}
value += ((this.waterStorage + 24) / 25);
return (byte) value;
復(fù)制代碼
這個value的初始值,不知道是我沒研究清楚還是IC本來就還沒來得及做這一塊內(nèi)容,根據(jù)IC2Crops類的內(nèi)容,后面的一長串東西似乎一直是0。也就是說濕度不受生物群系影響(我也覺得很奇怪,具體有待核實,希望有能力的同學(xué)幫我看一看)。因此重點(diǎn)看后面的。"this.worldObj.getBlockMetadata(this.xCoord, this.yCoord - 1,this.zCoord) >= 7"這個判斷條件,是判斷作物下方的泥土是否是耕地,如果是耕地,濕度加2;waterStorage和澆水有關(guān),如果不澆水就一直是0;如果澆了水,水澆得越多濕度越大。
第二個因素是營養(yǎng)。這里是updateNutrients()方法(TileEntityCrop.txt, 行928~行941):
int value = Crops.instance.getNutrientBiomeBonus(this.worldObj.getBiomeGenForCoords(this.xCoord, this.zCoord));
for (int i = 2; i < 5; i++) {
if (this.worldObj.getBlock(this.xCoord, this.yCoord - i, this.zCoord) != Blocks.dirt) {
break;
}
value++;
}
value += ((this.nutrientStorage + 19) / 20);
return (byte) value;
復(fù)制代碼
“Crops.instance.getNutrientBiomeBonus(this.worldObj.getBiomeGenForCoords(this.xCoord, this.zCoord))”這一長串和濕度部分的那些很相似,但是根據(jù)IC2Crops類,生物群系卻是會影響營養(yǎng)值的,具體請看IC2Crops.txt的第82~94行。第二部分是在檢測作物下方的泥土深度。如果泥土深度2層就+1,深度三層就+2,4層就+3。最后一部分是和肥料有關(guān),肥料越多營養(yǎng)值越高。
最后一個影響因素是空氣質(zhì)量。請看updateAirQuality()方法(TileEntityCrop.txt, 行945~行979):
int value = 0;
int height = (this.yCoord - 64) / 15;
if (height > 4) {
height = 4;
}
if (height < 0) {
height = 0;
}
value += height;
int fresh = 9;
for (int x = this.xCoord - 1; (x < (this.xCoord + 1)) && (fresh > 0); x++) {
for (int z = this.zCoord - 1; (z < (this.zCoord + 1)) && (fresh > 0); z++) {
if ((this.worldObj.isBlockNormalCubeDefault(x, this.yCoord, z, false)) || (this.worldObj.getTileEntity(x, this.yCoord, z) instanceof TileEntityCrop)) {
fresh--;
}
}
}
value += (fresh / 2);
if (this.worldObj.canBlockSeeTheSky(this.xCoord, this.yCoord + 1, this.zCoord)) {
value += 2;
}
return (byte) value;
復(fù)制代碼
首先是和高度有關(guān),當(dāng)高度為124以上時空氣質(zhì)量+4,為109~123時+3,為94~122時+2,為79~93時+1,否則+0。也就是說高度越高空氣質(zhì)量越好。其次,周圍的方塊也會影響空氣質(zhì)量。不過這里IC開發(fā)組的代碼似乎又寫錯了,它的本意fresh值初始為9,它周圍3*3的區(qū)域每有一個是普通方塊或者作物時fresh值-1,然后空氣質(zhì)量加上fresh除以二向下取整。但是它的循環(huán)語句寫錯了,實際上只檢測了2*2的范圍。最后,它還檢測了這個方塊"能否看到天空",機(jī)制和檢測太陽能發(fā)電機(jī)能否工作是相同的;如果能看到天空,則空氣質(zhì)量+2。
知道了這三個因素的計算方法之后,我們回到tick()方法(TileEntityCrop.txt,行213~行225):
if (this.crop.canGrow(this)) {
this.growthPoints += calcGrowthRate();
if (this.crop == null) {
return;
}
if (this.growthPoints >= this.crop.growthDuration(this)) {
this.growthPoints = 0;
this.size += 1;
this.dirty = true;
}
}
復(fù)制代碼
作物的canGrow()方法,對于常規(guī)作物一般是直接返回true的,我們也默認(rèn)它是true了?梢钥吹阶魑镉袀growthPoints屬性,每次增加calcGrowthRate()方法返回的值。如果growthPoints達(dá)到了作物的growthDuration(this),則計算為生長了一個階段。
首先來看看calcGrowthRate()方法,它是對幾個生長因素(濕度、營養(yǎng)、空氣質(zhì)量、作物本身屬性)的綜合計算(TileEntityCrop.txt,行1014~行1046):
if (this.crop == null) {
return 0;
}
int base = 3 + IC2.random.nextInt(7) + this.statGrowth;
int need = ((this.crop.tier() - 1) * 4) + this.statGrowth + this.statGain + this.statResistance;
if (need < 0) {
need = 0;
}
int have = this.crop.weightInfluences(this, getHumidity(), getNutrients(), getAirQuality()) * 5;
if (have >= need) {
base = (base * (100 + (have - need))) / 100;
} else {
int neg = (need - have) * 4;
if ((neg > 100) && (IC2.random.nextInt(32) > this.statResistance)) {
reset();
base = 0;
} else {
base = (base * (100 - neg)) / 100;
if (base < 0) {
base = 0;
}
}
}
return base;
復(fù)制代碼
這里的tier()是物種的本身屬性,只能通過代碼看到,最常見的小麥、南瓜等是一級作物,而馬鈴薯、胡蘿卜、西瓜、甘蔗等則是二級作物。這里的statGrowth(生長)\statGain(收獲)\statResistance(抗性)是這個作物的屬性,可以用作物分析儀看到,作弊模式下也可以使用NBT Edit查看,對于天然作物默認(rèn)為1。base值等于一個3~9的隨機(jī)數(shù)加上作物的生長速度屬性(天然植物默認(rèn)為1),代表著作物本身的生長速度;need值等于作物的三圍之和加上(作物等級-1)*4,說明作物越高階、屬性越好,對生長環(huán)境的要求也越高;have值等于濕度、營養(yǎng)、空氣質(zhì)量這些外部環(huán)境對作物的影響程度*5,代表外部生長環(huán)境。具體的計算因不同作物而異,對于一般的作物就是等于濕度、營養(yǎng)、空氣質(zhì)量三項之和。
后面是base,need,have的具體計算。這個還是看代碼比較直觀一些。當(dāng)have<need時,作物有幾率枯萎,枯萎率和作物的抗性有關(guān)。一般情況下have>=need,此時一次tick()增加的growthPoint就是"(base*(100+(have-need)))/100"。
growthPoint計算出來了,接下來就是計算作物的growthDuration,這是作物的本身屬性。一般來說就是作物的等級*200。
至于生長階段,不同的作物也是不一樣的。其中比較有趣的是馬鈴薯,它的生長階段是4段,從第三階段開始允許收獲。第三階段是生馬鈴薯,第四階段收獲下來就變成毒馬鈴薯了。如果需要毒馬鈴薯來做殺蟲劑,不妨多種點(diǎn)馬鈴薯,然后放很久不去管它,過一會兒就變成毒馬鈴薯了。
我現(xiàn)在終于知道,那些看起來花哨的新MOD,玩起來不知怎的總是不如老MOD帶勁兒:農(nóng)業(yè)只是IC中比較冷門的一個部分,而作物生長速度更是IC的農(nóng)業(yè)部分中一個很小的環(huán)節(jié)。然而就是這么看似微不足道的東西,卻涉及到了好幾頁的代碼,牽扯到了無數(shù)的影響因素;那些新興MOD想要做到像IC這種經(jīng)典MOD那樣豐富、有趣、富有內(nèi)涵,還是需要一段時間的積淀和完善才行啊。
查看所有0條評論>>