仍需完善
该页面内容由于以下原因仍需进一步完善。帮助我们扩充内容:
等待完善
小型的可采集的石块和矿点会在矿层的所有位置随机出现,也有小概率生成较为聚集的团块。它们有着不同的分布方式。[1][2]
平均来说,在每日运气为0的时候,每层会生成不到0.67个团块,而在最大每日运气时每层会生成接近1个。此外还有另一种可以被找到的大型石块(2×2)也属于一种随机生成的物体。
通过启用矿井中的挑战之神庙或者接取齐先生“深处的危险”任务,可以调整矿井的难度系数。一共有3种可能的难度,正常(0),启用其中之一(1)或二者均启用(2)。如果矿井为困难模式(1或2),放射性矿石将会出现,以及大树桩和大圆木(在困难矿井的41~69层)。双倍难度的启用只会有少量不同;和本页内容有关的是它会增加找到放射性矿石、怪物生成和跳跃型怪物(游戏里只有一种即为蜘蛛)成批生成的几率。
矿层会有概率变为采石场矿井入侵层,这会使生成各种物体的概率重新调整,需要单独来计算。
在普通矿井里生成的随机的石头中,在2~39层有2.9%的概率生成铜矿石,在81~119层也有相同的概率生成黄金矿石;在41~79层,有15%的概率生成水晶,而有2.465%的概率生成铁矿石。
目录
1 矿层的生成
2 矿层区域
3 随机的矿石替换(石头生成概率和选择石头种类)
3.1 金属矿点——普通矿井
3.2 金属矿点——困难矿井
3.3 金属矿点——采石场入侵层
3.4 其他矿点
4 可采集物品
5 大型物体
6 地格特征(特殊物体)
7 区域特殊物体
8 矿点团块(矿脉)
8.1 从普通石块中获得矿石
9 引用
矿层的生成
矿层内部的生成代码可以在StardewValley.Locations.MineShaft::populateLevel找到。在生成一个新的矿层时,游戏会生成一个变量名为stoneChance(生成石头的概率)的随机双精度浮点数,范围是10(含)~30(不含);一个变量名为monsterChance(怪物生成概率)的数,范围是0.002(含)~0.022(不含);一个变量名为itemChance(可采集物品概率)的数,其值为0.0025;一个变量名为gemStoneChance(宝石矿点概率)的数,其值为0.003。然后游戏会调用StardewValley.Locations.MineShaft::adjustLevelChances处的代码,按以下的顺序调整这些概率:[3]
1.对于第1层,将矿点生成的概率改为0;
2.对于可被5整除的层数,将可采集物品和宝石矿点生成的概率调为0;对于可被10整除的层数,将怪物生成的概率调为0;
3.对于感染层,将石头生成和宝石矿点生成的概率调为0,怪物生成概率调为0.025,可采集物品生成概率调为0.001;
4.对每1级难度,上升怪物生成的概率,为每级增加0.02(这使得怪物可以在第1层生成,会有另一重检查防止在可被10整除的层数生成怪物);
5.如果有对应的buff生效,将怪物生成的概率调为0(蒜油)或翻倍(怪物香水);
6.将宝石生成的概率除以2;
7.如果这一层是采石场入侵层,将宝石矿点生成的概率调为0.001(对本不能生成宝石矿点的矿层没有影响),可采集物品的概率调为0.0001,石头生成的概率翻倍,即为20(含)~60(不含),怪物生成的概率调为0.02;
8.如果你在40号区域(矿井的40到69层),并且开启了困难模式,则怪物生成的几率乘以1.6600000262260437(即增加约66%的概率)。
在这些调整完成之后,系统会用这些概率来尝试生成矿层中的每一个格子。如果这个格子是空的,会先尝试生成石头,然后是怪物,然后是可采集物品,然后是大型石块(具体见下)。如果大型石块成功生成,则会额外占据周围的3格。此外,怪物可能会批量生成,会占用周围的格子,导致石头生成的数量不及预期。
在对所有格子的判定结束后,游戏会调用StardewValley.Locations.MineShaft::tryToAddAreaUniques的代码生成特殊物体(杂草),接着会尝试生成额外的怪物(一般来说是会占用石头的位置,最多占用1/35的石头的位置),然后调用StardewValley.Locations.MineShaft::tryToAddOreClumps的代码生成矿点,仅能在大于2且不能被5整除的层数进行这一判定。
如果层数可以被10整除,则矿层只会生成一个梯子和宝箱(如果必要的话),不会生成其他任何东西。
矿层区域
矿层区域取决于你所在的层数,采石场矿井是一个特例。
采石场矿井的矿层区域为77377
矿井0~10层的矿层区域为0
矿井11~29层的矿层区域为10
矿井30~39层的矿层区域为0
矿井40~79层的矿层区域为40
矿井80~120层的矿层区域为80
随机的矿石替换(石头生成概率和选择石头种类)
游戏会经过3个阶段的判定,首先如果处于40号矿井区域,则石头有15%的概率会变成水晶(物品代码为319~321),如果矿井为困难模式且处于困难矿井的41~69层,则生成的会是杂草(物品代码为313~315)。然后判定是否处于蘑菇层,如果是,则有55%的概率不生成石头,如果不是,则有25%的概率不生成石头,然后在消失的地方尝试生成蘑菇。此时有20%的概率生成紫蘑菇,80%的概率生成红蘑菇。如果没有通过杂草生成和移除石头的判定,则会调用StardewValley.Locations.MineShaft::chooseStoneType处的代码,调用上面已经计算好的宝石矿点生成概率,以及紫色宝石矿点和神秘石的生成概率(为0.001和0.00005)来决定剩余石头的替换。这个代码首先会尝试将石头替换为放射性矿石,然后根据矿层区域替换成对应的矿点,然后是其他矿点。
这意味着对于一个一般的蘑菇层(不在40号区域),原先的石头有45%的概率不发生变化,有2.75%的概率变为一个紫蘑菇,有11%的概率变为一个红蘑菇,有41.25%的概率变为空;如果在40号区域中,则原先的石头有15%的概率变为杂草,38.25%的概率不发生变化,有2.3375%的概率变为一个紫蘑菇,有9.35%的概率变为一个红蘑菇,有35.0625%的概率变为空。之后的计算和图表会包括40号区域里的杂草,但不再包括蘑菇层的情况。
金属矿点——普通矿井
普通矿井(未开启困难模式)的详细代码如下所示。它逐一判定各个矿层区域,设置默认的石块然后进行替换为矿点的判定。另外,如果whichStone变量数值为奇数,则它的值会加1然后进行判定,这会对石头的替换产生影响。
if (this.getMineArea() == 0 || this.getMineArea() == 10) {
whichStone = this.mineRandom.Next(31, 42);
if (this.mineLevel % 40 < 30 && whichStone >= 33 && whichStone < 38) {
whichStone = ((this.mineRandom.NextDouble() < 0.5) ? 32 : 38);
} else if (this.mineLevel % 40 >= 30) {
whichStone = ((this.mineRandom.NextDouble() < 0.5) ? 34 : 36);
}
if (this.mineLevel != 1 && this.mineLevel % 5 != 0 && this.mineRandom.NextDouble() < 0.029) {
return new Object(tile, 751, "Stone", canBeSetDown: true, canBeGrabbed: false, isHoedirt: false, isSpawnedObject: false) //铜矿点
}
} else if (this.getMineArea() == 40) {
whichStone = this.mineRandom.Next(47, 54);
if (this.mineLevel % 5 != 0 && this.mineRandom.NextDouble() < 0.029) {
return new Object(tile, 290, "Stone", canBeSetDown: true, canBeGrabbed: false, isHoedirt: false, isSpawnedObject: false) //铁矿点
}
} else if (this.getMineArea() == 80) {
whichStone = ((this.mineRandom.NextDouble() < 0.3 && !this.isDarkArea()) ? ((!(this.mineRandom.NextDouble() < 0.5)) ? 32 : 38) : ((this.mineRandom.NextDouble() < 0.3) ? this.mineRandom.Next(55, 58) : ((!(this.mineRandom.NextDouble() < 0.5)) ? 762 : 760)));
if (this.mineLevel % 5 != 0 && this.mineRandom.NextDouble() < 0.029) {
return new Object(tile, 764, "Stone", canBeSetDown: true, canBeGrabbed: false, isHoedirt: false, isSpawnedObject: false)//金矿点
}
}
在每个矿层区域,石头被替换为矿点的概率均为2.9%,矿点会匹配矿层区域(40层之前为铜矿,40~80层为铁矿,之后是金矿)。然而,层数不能是5的倍数,也不能是第1层。另外,如果在40号矿层区域中,有15%的概率也达不到这一概率(石头被替换为水晶),使得铁矿的替换概率降为2.465%。如果生成了金属矿点,函数将返回对应值(中止循环)。否则它将会继续判定石头是否会被替换为其他矿点(例如钻石矿点),其讨论情况见下。
尽管普通的石头也有多种类别,它们也可以被分为2个大类:物品代码为40或42的一类,其他的一类。这种类会影响击破石头时附带有矿石的可能性,如果石头的代码为40或42,会有20%的额外概率,否则减少20%的概率。只有在1到29层会生成这些有更高概率获得额外矿石的石头,在这些矿层中,有3/11的概率可以找到这些石头。
金属矿点——困难矿井
首先,游戏会判定石头是否会被替换为放射性矿石,代码如下:
if (this.GetAdditionalDifficulty() > 0 && this.mineLevel % 5 != 0 && this.mineRandom.NextDouble() < (double)this.GetAdditionalDifficulty() * 0.001 + (double)((float)this.mineLevel / 100000f) + Game1.player.team.AverageDailyLuck() / 13.0 + Game1.player.team.AverageLuckLevel() * 0.0001500000071246177)
从这里可以看出,特殊的魅力带来的幸运加成(0.025每日运气)相当于多下192.3层所增加的生成概率,使得拥有特殊的魅力时即使在矿井的1层也比没有特殊的魅力时在矿井的100层找到放射性矿石的概率高。每1点幸运增益(比如来自食物的buff)相当于多下15层的效果。在正常游戏中所能达到的最大幸运的情况下,有1.2%的石头会被替换为放射性矿石。如果是最差的每日运气,放射性矿石根本不会出现在矿井里,即使拥有特殊的魅力,也还需要24级的幸运增益才能有可能找到放射性矿石。另外,放射性矿石也不能在层数能被5整除的矿层中出现。
如果矿井的难度为2,则找到放射性矿石的概率增加0.1%,在下面的计算中不使用这一情况(即默认难度为1)。
在这之后游戏会对各个矿层区域进行判定,选择一块默认的石头,判定其是否可以变成金属矿点,如果通过判定,函数将返回对应值。代码见下:
if (this.getMineArea() == 0 || this.getMineArea() == 10) {
whichStone = this.mineRandom.Next(33, 37);
if (Game1.random.NextDouble() < 0.33) {
whichStone = 846; //石头矿点
} else {
stoneColor = new Color(Game1.random.Next(60, 90), Game1.random.Next(150, 200), Game1.random.Next(190, 240));
}
if (this.isDarkArea()) { //31~39层
whichStone = this.mineRandom.Next(32, 39);
int tone = Game1.random.Next(130, 160);
stoneColor = new Color(tone, tone, tone);
}
if (this.mineLevel != 1 && this.mineLevel % 5 != 0 && this.mineRandom.NextDouble() < 0.029) {
return new Object(tile, 849, "Stone", canBeSetDown: true, canBeGrabbed: false, isHoedirt: false, isSpawnedObject: false) { //铜矿点
MinutesUntilReady = 6
};
}
if (stoneColor.Equals(Color.White)) { //仅在小于30层的石头矿点上运用,否则石头矿点的颜色将变化。
return new Object(tile, whichStone, "Stone", canBeSetDown: true, canBeGrabbed: false, isHoedirt: false, isSpawnedObject: false) {
MinutesUntilReady = stoneHealth
};
}
} else if (this.getMineArea() == 40) {
whichStone = this.mineRandom.Next(47, 54);
stoneHealth = 3;
if (this.GetAdditionalDifficulty() > 0 && this.mineLevel % 40 < 30) {
whichStone = this.mineRandom.Next(39, 42);
if (this.mineRandom.NextDouble() < 0.15) {
return new ColoredObject(294 + ((this.mineRandom.NextDouble() < 0.5) ? 1 : 0), 1, new Color(170, 140, 155)) //树枝
}
if (this.mineLevel != 1 && this.mineLevel % 5 != 0 && this.mineRandom.NextDouble() < 0.029) {
return new ColoredObject(290, 1, new Color(150, 225, 160)) //白铁色
}
}
else if (this.mineLevel % 5 != 0 && this.mineRandom.NextDouble() < 0.029) {
return new Object(tile, 290, "Stone", canBeSetDown: true, canBeGrabbed: false, isHoedirt: false, isSpawnedObject: false) { //铁矿点
MinutesUntilReady = 4
};
}
} else if (this.getMineArea() == 80) {
whichStone = ((!(this.mineRandom.NextDouble() < 0.5)) ? 32 : 38);
if (this.isDarkArea()) {
whichStone = this.mineRandom.Next(32, 39);
}
if (this.mineLevel != 1 && this.mineLevel % 5 != 0 && this.mineRandom.NextDouble() < 0.029) {
return new Object(tile, 764, "Stone", canBeSetDown: true, canBeGrabbed: false, isHoedirt: false, isSpawnedObject: false) { //金矿点
MinutesUntilReady = 7
};
}
}
默认石块被替换为矿点的概率仍为2.9%,但在困难矿井也有很多不同。首先,石块会有概率被替换为放射性矿石,这取决于运气。然后,在1~39层,有33%的概率会使石块被替换为石头矿点;如果是在不到30层的矿层且石块没有变成铜矿,则会变成这种石头矿点。这使得总体来说有32%的概率产生石头矿点。在41~69层,会有15%的概率使得石块变为树枝。这使得在41~69层总体来看(假如没有放射性矿石),会有15%的默认石块变为杂草,12.75%的默认石块变为树枝,2.1%的默认石块变为铁矿,其余的默认石块会变为其他的东西。另外,在41~69层,石块被击破时掉落额外矿石的概率更高,而其他层的这一概率更低。
金属矿点——采石场入侵层
采石场入侵层作物一种特殊情况,在困难矿井启用时判定放射性矿石的替换之后,会调用如下的代码(有所简化):
bool foundSomething = false;
foreach (Vector2 v in Utility.getAdjacentTileLocations(tile)) {
if (base.objects.ContainsKey(v)) {
foundSomething = true;
break;
}
}
if (!foundSomething && this.mineRandom.NextDouble() < 0.45) {
return null;
}
bool brownSpot = false;
for (int i = 0; i < this.brownSpots.Count; i++) {
if (Vector2.Distance(tile, this.brownSpots[i]) < 4f) {
brownSpot = true;
break;
}
if (Vector2.Distance(tile, this.brownSpots[i]) < 6f) {
return null;
}
}
if (brownSpot) {
whichStone = ((this.mineRandom.NextDouble() < 0.5) ? 32 : 38);
if (this.mineRandom.NextDouble() < 0.01) {
return new Object(tile, 751, "Stone", canBeSetDown: true, canBeGrabbed: false, isHoedirt: false, isSpawnedObject: false) //铜矿点
}
} else {
whichStone = ((this.mineRandom.NextDouble() < 0.5) ? 34 : 36);
if (this.mineRandom.NextDouble() < 0.01) {
return new Object(tile, 290, "Stone", canBeSetDown: true, canBeGrabbed: false, isHoedirt: false, isSpawnedObject: false) //铁矿点
}
}
return new Object(tile, whichStone, "Stone", canBeSetDown: true, canBeGrabbed: false, isHoedirt: false, isSpawnedObject: false) //普通石块
无论判定结果如何,函数都会返回值。这意味着采石场入侵层不可能产生紫色宝石矿点、神秘石或宝石矿点,因为它们要在无返回值的情况下进行判定。
如果进行判定的位置没有临近的石头,则有45%的概率返回值为空。然而,因为在调整这一层的石头数量时石头的生成概率翻了一倍,所以这不会导致这些层的石头数量减少。
棕色点位会调用StardewValley.Locations.MineShaft::loadLevel处的代码来进行判定生成,这会使全地图1%的地块变为棕色点位,从代码上分析,棕色点位的判定可能会重复在同一格,也可能生成在地图外面从而导致没有实际效果。
距离棕色点位正好4格远的地方有1%的概率生成铜矿点,有99%的概率生成普通的棕色石头。
如果距离棕色点位6格或更远,有1%生成铁矿点,有99%的概率生成普通的灰色石头(不是石头矿点)。
除此以外,如果和棕色点位的距离在5格则不会生成石头。这使得多个棕色点位可以相邻,但棕色石头和灰色石头之间会有一个空隙。
其他矿点
到现在为止,除了放射性矿点的判定以外,运气还没有参与计算,层数也只影响到了使用的矿层区域和判定可被5整除的层数的矿层生成。
然而,如果上述进行的判定如果没有返回任何矿点或石头的值(或采石场入侵层返回的空值),接下来进行判定的就是各种宝石矿点、暗灰色石头(石头矿点)、紫色宝石矿点和神秘石矿点。
这是根据下面一串复杂的代码完成的(为了简化,去掉了关于颜色判定的部分,它的作用只是使返回值为某颜色的物体而非单纯的物体,但不影响最终结果):
double averageDailyLuck = Game1.player.team.AverageDailyLuck(Game1.currentLocation);
double averageMiningLevel = Game1.player.team.AverageSkillLevel(3, Game1.currentLocation);
double chanceModifier = averageDailyLuck + averageMiningLevel * 0.005;
//钻石矿点
if (this.mineLevel > 50 && this.mineRandom.NextDouble() < 0.00025 + (double)this.mineLevel / 120000.0 + 0.0005 * chanceModifier / 2.0) {
whichStone = 2;
stoneHealth = 10;
}
//宝石矿点
else if (gemStoneChance != 0.0 && this.mineRandom.NextDouble() < gemStoneChance + gemStoneChance * chanceModifier + (double)this.mineLevel / 24000.0) {
return new Object(tile, this.getRandomGemRichStoneForThisLevel(this.mineLevel), "Stone", canBeSetDown: true, canBeGrabbed: false, isHoedirt: false, isSpawnedObject: false) {
MinutesUntilReady = 5
};
}
//紫色宝石矿点
if (this.mineRandom.NextDouble() < chanceForPurpleStone / 2.0 + chanceForPurpleStone * averageMiningLevel * 0.008 + chanceForPurpleStone * (averageDailyLuck / 2.0)) {
whichStone = 44;
}
//神秘石矿点
if (this.mineLevel > 100 && this.mineRandom.NextDouble() < chanceForMysticStone + chanceForMysticStone * averageMiningLevel * 0.008 + chanceForMysticStone * (averageDailyLuck / 2.0)) {
whichStone = 46;
}
whichStone += whichStone % 2;
//暗灰色石头(石头矿点)
if (this.mineRandom.NextDouble() < 0.1 && this.getMineArea() != 40) {
return new Object(tile, (this.mineRandom.NextDouble() < 0.5) ? 668 : 670, "Stone", canBeSetDown: true, canBeGrabbed: false, isHoedirt: false, isSpawnedObject: false)
{
MinutesUntilReady = 2,
Flipped = (this.mineRandom.NextDouble() < 0.5)
};
}
return new Object(); //返回函数值(对应的石头)
钻石矿点随层数、运气和采矿等级不同而的不同分布图
在全面的分析之前,值得首先提一下运气的影响。钻石和宝石都使用chanceModifier变量进行概率的调整。每日运气的值为-0.1~0.125(拥有特殊的魅力),采矿等级为0~14级,如此chanceModifier的取值范围即为-0.1~0.195。对于钻石而言,上述变量的值要乘以0.0005然后再除以2,使得其取值范围为-0.0025%~0.004875%,最值差等效于多下8.85层。对于每日运气最大(拥有特殊的魅力)和10级采矿的玩家,最值差只有0.005%,等效于多下6.6层。这和理应得到的在1层,运气为0,采矿技能为0级时的基础概率0.126%相比,只占了很小的一部分。
对于宝石矿点,最大的最值差为0.044%,而最小的则为0.033%,分别等效于多下10.62和7.92层,和1层时的基础概率0.654%也相去甚远。
紫色宝石矿点和神秘石矿点的概率计算并不直接使用层数这一参数计算。这时每日运气的最值差(实际参与计算的是每日运气除以2得到的值乘以默认概率,最值差为0.1125倍默认概率)占基础概率(0.5倍默认概率)的比重就大得多了,影响的量超过了20%,使得生成的概率更大程度上取决于运气。同理,14级采矿(相较于0级的最值差)的贡献为0.112倍默认概率,也超过了10%,但需要增益得到的4级采矿只占了0.032倍默认概率,相对而言不那么重要。对于神秘石矿点而言,运气对其概率的贡献超过了10%,而采矿等级的贡献值相对较少,这和紫色宝石矿点是类似的。
通过考虑输出的逻辑可以更好的理解这一点。第一种输出的可能性是未通过钻石矿点的判定但通过了宝石矿点的判定。第二种输出的可能性是上述判定失败,但通过了暗灰色石头(石头矿点)的判定。以此类推(接下来按神秘石矿点、紫色宝石矿点、钻石矿点的顺序判定,如果都失败就输出普通石头)。可用下面的伪代码来描述这一过程:
if (!diamondCheck && gemCheck){
return gem
}
if (stoneCheck) {
return grey rock
}
if (mysticCheck) {
return mystic stone
}
if (purpleCheck) {
return gem node
}
if (diamondCheck) {
return diamond
}
return rock
然而,此处钻石矿点的判定被使用了两次,你不能简单的认为是进行了两次是否可以生成钻石的判定(概率不是简单的乘以2),这两次判定可能同时成功或同时失败,使得计算变得更加复杂。这其中最容易理解的是宝石矿点的生成概率。为了生成宝石矿点,前面金属矿点的生成需要失败,钻石矿点的生成也要失败,同时宝石矿点的判定需要成功,这实际上等于:
(1-金属矿点判定成功概率)×(1-钻石矿点判定成功概率)×宝石矿点判定成功概率。
另外,游戏会调用MineShaft::getRandomGemRichStoneForThisLevel[4]处的代码决定宝石矿点的具体宝石种类。其内容如下:
int whichGem = this.mineRandom.Next(59, 70);
whichGem += whichGem % 2;
if (Game1.player.timesReachedMineBottom == 0) {
if (level < 40 && whichGem != 66 && whichGem != 68) {
whichGem = ((this.mineRandom.NextDouble() < 0.5) ? 66 : 68);
}
else if (level < 80 && (whichGem == 64 || whichGem == 60)) {
whichGem = ((!(this.mineRandom.NextDouble() < 0.5)) ? ((this.mineRandom.NextDouble() < 0.5) ? 68 : 62) : ((this.mineRandom.NextDouble() < 0.5) ? 66 : 70));
}
}
这里会随机选择59(含)~70(不含)之间的一个整数,如果是奇数则加1。效果就是从60~70中随机选择一个偶数,而60~68之间的偶数被选中的概率相同,选中70的概率是前面各个偶数的一半(此处不再赘述这是为什么,自己推演一下便易得这一结论)。因此代码为70的翡翠生成的概率就是其他宝石(绿宝石,海蓝宝石,红宝石,紫水晶,黄水晶)的一半,也可以参考下面的公式:
翡翠概率=(1-钻石矿点判定成功概率)×宝石概率/11
其他宝石概率=(1-钻石矿点判定成功概率)×宝石概率×2/11
然而,如果你还没有到达矿井的底部,且处于矿井的80层之前,这分布将会变得不同。在到达40层之前,你有同等概率获得黄水晶或紫水晶。在40~80层之间概率的计算会比较复杂,因为绿宝石和红宝石的概率被紫水晶、黄宝石、海蓝宝石和翡翠分掉了,此时有18.2%的概率得到翡翠,其余三种宝石各有27.3%的概率。
不生成宝石矿点并生成其他物体(除了钻石)的概率则等于:
钻石矿点判定成功概率+(1-钻石矿点判定成功概率)×(1-宝石矿点判定成功概率),即1-(1- 钻石矿点判定成功概率)×宝石矿点判定成功概率)
接下来依次判定剩下的三种,其概率公式如下:
石头矿点概率=(1-(1- 钻石矿点判定成功概率)×宝石矿点判定成功概率))×石头矿点判定成功概率
神秘石矿点概率=(1-(1- 钻石矿点判定成功概率)×宝石矿点判定成功概率))×(1-石头矿点判定成功概率)×神秘石矿点判定成功概率
紫色宝石矿点概率=(1-(1- 钻石矿点判定成功概率)×宝石矿点判定成功概率))×(1-石头矿点判定成功概率)×(1-神秘石矿点判定成功概率)×紫色宝石矿点判定成功概率
接下来要考虑的是钻石的概率。当钻石矿点判定成功时,会跳过宝石矿点的判定过程,因此计算中不涉及宝石矿点的概率值。由此可得,如果要生成钻石,就必须通过钻石矿点的判定(同时跳过了宝石矿点的判定),然后其他所有判定都要失败,其公式如下:
钻石矿点概率=钻石矿点判定成功概率×(1-紫色宝石矿点判定成功概率)×(1-神秘石矿点判定成功概率)×(1-石头矿点判定成功概率)
尽管以一种完全不同的方式计算,但找到钻石矿点和找到其他任何一种特定宝石矿点的概率都是很接近的。最后还有一种可能,是生成普通石头。计算时可以认为是与其他情况都互斥的可能性,但为了完整性,它仍然需要经过每一次检查(且都失败),其概率如下:
普通石头概率=(1-钻石矿点判定成功概率)×(1-宝石矿点判定成功概率)×(1-紫色宝石矿点判定成功概率)×(1-神秘石矿点判定成功概率)×(1-石头矿点判定成功概率)
因为这些判定之间并不独立,理论上可以出现找到某种物体的概率提高的同时降低找到其他物体的概率的情况。可以观察到,在100层之下,找到神秘石矿点的概率上升的同时会减少找到宝石矿点和紫色宝石矿点的概率。另外,出于运气和采矿等级(的提高)导致找到贵重物体矿点的概率上升也会导致找到石头矿点和普通石头的概率下降,但不会影响同种的物体。例如,高的每日运气会同时提高你找到钻石、宝石、神秘石和紫色宝石矿点的概率,并同时降低你找到石头矿点和普通石头的概率。
可采集物品
在对生成石头和怪物的判定结束后,游戏会尝试添加可采集物品。成功的概率是上面定义的itemChance参数。其默认值是0.25%,但在感染层是0.1%,采石场入侵层是0.01%。游戏会调用StardewValley.Locations.MineShaft::getRandomItemForThisLevel[5]处的代码决定产生的物品,代码如下:
int index = 80;
if (this.mineRandom.NextDouble() < 0.05 && level > 80) {
index = 422;
} else if (this.mineRandom.NextDouble() < 0.1 && level > 20 && this.getMineArea() != 40) {
index = 420;
} else if (this.mineRandom.NextDouble() < 0.25 || this.GetAdditionalDifficulty() > 0) {
switch (this.getMineArea()) {
case 0:
case 10:
if (this.GetAdditionalDifficulty() > 0 && !this.isDarkArea()) {
switch (this.mineRandom.Next(6)) {
case 0:
case 6:
index = 152;
break;
case 1:
index = 393;
break;
case 2:
index = 397;
break;
case 3:
index = 372;
break;
case 4:
index = 392;
break;
}
if (this.mineRandom.NextDouble() < 0.005) {
index = 797;
} else if (this.mineRandom.NextDouble() < 0.08) {
index = 394;
}
} else {
index = 86;
}
break;
case 40:
if (this.GetAdditionalDifficulty() > 0 && this.mineLevel % 40 < 30) {
switch (this.mineRandom.Next(4)) {
case 0:
case 3:
index = 259;
break;
case 1:
index = 404;
break;
case 2:
index = 420;
break;
}
if (this.mineRandom.NextDouble() < 0.08) {
index = 422;
}
} else {
index = 84;
}
break;
case 80:
index = 82;
break;
}
}
在判定开始之前,首先指定被返回的物品是一个石英。然后,如果层数大于80,有5%的概率返回值为一个紫蘑菇。如果失败,检测层数大于20且不在40号区域时,有10%的概率返回值为一个红蘑菇。如果失败,则有25%的概率根据当前的区域选择一个基础物品,如果开启了困难模式则这个概率为100%。如果失败,则返回值为一个石英。对于采石场入侵层,是没有区域基础物品的,因此只可能获得蘑菇或者石英。
在0或10号区域,如果不到30层或矿井不是困难模式,则区域基础物品为地晶。如果开启了困难矿井且超过了30层,区域基础物品有0.5%的概率为一个珍珠,如果失败有8%的概率为彩虹贝壳,如果失败则有5/6的概率为海草、珊瑚、海胆、蛤或鹦鹉螺其中之一,另外1/6的概率为空,这种情况下会得到石英。对于40号区域,如果未开启困难矿井或不到70层,区域基础物品会是泪晶,否则有50%的概率会是蕨菜、25%的概率为普通蘑菇、25%的概率为红蘑菇,有8%的概率为紫蘑菇。在80号区域,区域基础物品为火水晶。
层数
普通矿井生成物品概率
困难矿井生成物品概率
采石场入侵的1~19层
100% 石英
100% 石英
采石场入侵的21-79层
10% 红蘑菇90% 石英
10% 红蘑菇90% 石英
采石场入侵的81-119层
5% 紫蘑菇9.5% 红蘑菇85.5% 石英
5% 紫蘑菇9.5% 红蘑菇85.5% 石英
1-19层
25% 地晶75% 石英
0.5% 珍珠7.96% 彩虹贝壳各15.257% 海草、珊瑚、海胆、蛤、鹦鹉螺、石英
21-29层
10% 红蘑菇22.5% 地晶67.5% 石英
10% 红蘑菇0.45% 珍珠7.164% 彩虹贝壳各13.731% 海草、珊瑚、海胆、蛤、鹦鹉螺、石英
31-39层
10% 红蘑菇22.5% 地晶67.5% 石英
10% 红蘑菇90% 地晶
41-69层
25% 泪晶75% 石英
46% 蕨菜各23% 普通蘑菇、红蘑菇8% 紫蘑菇
71-79
25% 泪晶75% 石英
100% 泪晶
81-120
5% 紫蘑菇9.5% 红蘑菇21.375% 火水晶64.125% 石英
5% 紫蘑菇9.5% 红蘑菇85.5% 火水晶
大型物体
在对石头、怪物和可采集物品的判定结束后,游戏会尝试添加资源团块(大型物体)。有0.5%的概率成功生成(考虑到先前已经经过的这么多次判定,实际上要小得多),需要矿井不为困难模式或在41~69层的范围内。由于逐次判定生成的顺序,大型物体生成时不会被额外的3格阻挡,这意味着可能会占用本已经生成的石块的位置。另外,在入侵层不会生成大型物体。
特殊物体的生成将在取决于矿井为40号区域或矿井为困难模式两个因素:
1.如果二者都具备,有90%概率生成树桩,有10%的概率生成圆木;
2.如果未开启困难矿井但在40号区域,则会生成另外2种蓝色的巨石(以适应区域的主题);
3.如果开启了困难矿井但不在40号区域,则会生成2种另外的巨石。
地格特征(特殊物体)
如果开启了困难矿井,那么游戏可以添加额外的特殊物体。这会在对石头、怪物、可采集物品和大型物体的判定结束之后进行。如果在40~70层之间,有1%的概率生成桃花心木树。否则在40~70层之间或80层之后会有10%的概率生成杂草。
区域特殊物体
游戏会调用StardewValley.Locations.MineShaft::tryToAddAreaUniques[6]处的代码尝试生成杂草。在生成之前,游戏会根据以下代码先进行判定:
if ((this.getMineArea() != 10 && this.getMineArea() != 80 && (this.getMineArea() != 40 || !(this.mineRandom.NextDouble() < 0.1))) || this.isDarkArea() || this.mustKillAllMonstersToAdvance())
{
return;
}
这意味着游戏只会在11~29层和41~119层添加杂草,而在41~79层只有10%的概率会尝试生成。另外,后面还会有对于矿井是否处于困难模式且处于80层以下的判定,如果判定通过则会在添加杂草之前就返回函数值(取消添加)。如果在40号矿层区域且矿井不为困难模式,则“杂草”会被替换为水晶(物品代码为319~321)。
接下来游戏会尝试生成7(含)~23(含)次杂草。这需要所处的地格可以通过并且没有任何其他的东西,平均来说会导致实际生成的杂草数量减少。但如果选择到的地格都是空的,平均来说可以生成15个杂草(或水晶)。在40号区域则平均数会少于1.5个。不过在默认石块生成时,40号区域的石块会有15%的概率变为水晶,因而在单独添加水晶被之前就有3%的格子会变成水晶了。
矿点团块(矿脉)
游戏里StardewValley.Locations.MineShaft::tryToAddOreClumps[7]的代码的功能只会在一个判定后启用,这个判定是生成一个(0~1之间的)随机数,如果小于0.55加上每日运气的值,则判定为成功。这意味着基础概率为55%,在有特殊的魅力[8]时最高概率为67.5%。在这次尝试成功之后,会继续产生随机数,如果这个随机数大于0.25加上每日运气的值,则可以继续判定直到失败为止。这意味着这会有1次固定机会,加上25%的概率(最大运气情况下为37.5%的概率)获得额外的机会。
这样在期望上可以获得4/3次(每日运气为0)到1.6次的额外判定机会,算上先前的判定,则这个期望值为11/15次(每日运气为0)到1.08次。
然而,每次判定时会寻找矿点周边任意的一格,只有这一格为空时才能添加额外的矿点,使得期望比上述的值略低。但是一旦成功添加了额外矿点,它就会有概率向各个方向蔓延数格以生成更多的矿点。
为了添加正确类型的矿点,游戏会调用StardewValley.Locations.MineShaft::getAppropriateOre[9]处的代码。它会先将矿点种类设定为751(铜矿),然后根据矿层区域调整之。如果在0或10号矿层区域且开启了困难矿井,则矿点种类会被设定为849,是另一种样子的铜矿矿点。对于40号区域,如果开启了困难矿井,则矿点种类会被设定为铁矿,如果不是困难矿井则有80%的概率为铁矿。对于80号区域,有80%的概率生成金矿。如果不是40号区域且没有开启困难矿井,则会有25%的概率把矿点设为668或670,为两种不同样子的暗灰色石头(石头矿点)。
普通矿井矿点种类分布如下:
1.在3~39层或采石场入侵层,有75%的概率为铜矿点,25%的概率为石头矿点;
2.在41~79层,有80%的概率为铁矿点,20%的概率为铜矿点;
3.在81~119层,有25%的概率为石头矿点,60%的概率为金矿点,15%的概率为铜矿点。
困难矿井矿点种类分布如下:
1.在3~39层或采石场入侵层,有100%的概率为铜矿点;
2.在41~79层,有100%的概率为铁矿点;
3.在81~119层,有80%的概率为金矿点,20%的概率为铜矿点。
从普通石块中获得矿石
如果一块普通石块被生成,仍有机会在击破它时得到矿石。当你击破普通石块时,StardewValley.Locations.MineShaft::checkStoneForItems处的代码会调用StardewValley.Locations.MineShaft::getOreIndexForLevel处的参数来进行掉落矿石的判定,关键部分的代码见下:[10]
double chanceModifier = who.DailyLuck / 2.0 + (double)who.MiningLevel * 0.005 + (double)who.LuckLevel * 0.001;
double oreModifier = ((tileIndexOfStone == 40 || tileIndexOfStone == 42) ? 1.2 : 0.8);
if (r.NextDouble() < 0.05 * (1.0 + chanceModifier) * oreModifier) {
if (r.NextDouble() < 0.25 * (double)((!who.professions.Contains(21)) ? 1 : 2)) {
Game1.createObjectDebris(382, x, y, who.UniqueMultiplayerID, this); //煤炭
}
Game1.createObjectDebris(this.getOreIndexForLevel(this.mineLevel, r), x, y, who.UniqueMultiplayerID, this);//矿石
} else if (r.NextDouble() < 0.5) {
Game1.createDebris(14, x, y, 1, this);
}
总的来说,从普通石块里找到额外产出的概率最低为5.1%,最高为5.7%。其中有47.45%~47.15%的概率找到的为石头。如果产出的为矿石,则有25%的概率可以获得煤炭,如果有勘探者职业则概率翻倍。这使得从普通石头中获得煤炭的概率大约为1%。
然后游戏调用StardewValley.Locations.MineShaft::getOreIndexForLevel处的代码来决定可以获得什么矿石,其代码见下:[11]
if (this.getMineArea(mineLevel) == 77377) { //采石场矿井
return 380; //铁矿
}
if (mineLevel < 40) {
if (mineLevel >= 20 && r.NextDouble() < 0.1) {
return 380; //铁矿石
}
return 378; //铜矿
}
if (mineLevel < 80) {
if (mineLevel >= 60 && r.NextDouble() < 0.1) {
return 384; //金矿
}
if (!(r.NextDouble() < 0.75)) {
return 378; //铜矿
}
return 380; //铁矿
}
if (mineLevel < 120) {
if (!(r.NextDouble() < 0.75)) {
if (!(r.NextDouble() < 0.75)) {
return 378; //铜矿
}
return 380; //铁矿
}
return 384; //金矿
}
层数
铜矿石
铁矿石
黄金矿石
1-19层
100%
无
无
21-39层
90%
10%
无
41-59层
25%
75%
无
61-79层
22.5%
67.5%
10%
81-119层
6.25%
18.75%
75%
采石场入侵层
无
100%
无
引用
↑ 参考游戏代码中 MineShaft::populateLevel 部分
↑ 参考游戏代码中 MineShaft::chooseStoneType 部分
↑ 参考游戏代码中 MineShaft::adjustLevelChances 部分
↑ 参考游戏代码中 MineShaft::getRandomGemRichStoneForThisLevel 部分
↑ 参考游戏代码中 MineShaft::getRandomItemForThisLevel 部分
↑ 参考游戏代码中 MineShaft::tryToAddAreaUniques部分
↑ 参考游戏代码中 MineShaft::tryToAddOreClumps 部分
↑ 参考游戏代码中 FarmerTeam::AverageDailyLuck和Game1::_newDayAfterFade 部分
↑ 参考游戏代码中 FarmerTeam::getAppropriateOre 部分
↑ 参考游戏代码中 MineShaft::checkStoneForItems 部分
↑ 参考游戏代码中 MineShaft::getOreIndexForLevel 部分