User:Westgrass/sandbox

房屋有效性的评估分成3个阶段：

房屋结构评估
在这一阶段，游戏会尝试判定出房屋的内部区域和边框，并且对其结构完成若干评估. （Terraria.WorldGen 中的 StartRoomCheck 方法） 房屋的范围包括一块连通的内部区域和围绕着内部区域的边框，其中： 房屋范围内的所有格子（包括内部区域和边框），需要满足以下条件：
 * “连通” 是8方向判定，即内部区域的格子在水平方向、数字方向、或斜角方式上彼此相连.
 * 边框是指和内部区域相邻的那些格子，边框必须完全封闭，即内部区域和边框外的区域完全不连通. 边框必须是solid tile（即solid block或platform，见表）或者门、高门、陷阱门（只有关门状态下所占据的那些格子才有效）.
 * 所有格子离地图边缘必须至少10格
 * 范围内不允许存在横向或竖向上连续5格的“洞”. “洞”指的是未被有效的solid block占据同时又没有有效的背景墙的格子， 即，若范围内存在一个格子，它自身和左右各两个（或上下各两格）都是“洞”，则此房屋判定为不合格.
 * 房屋大小约束：范围内的格子数量至少要有60格，同时要少于750格.

在这个过程中，还会同时记录内部区域格子的最左、最右、最上、最下坐标，后继寻找home spot时会使用.

房屋设施评估
（Terraria.WorldGen 中的 RoomNeeds 方法） 房屋范围内必须有一个有效的门、一个有效的椅子、一个有效的桌子、一个有效的光源. （表）（表）（表）（表）

房屋分值评估
（Terraria.WorldGen 中的 ScoreRoom 方法） 首先检查房屋是否已被其他NPC入住占据. 如果已有入住，无效，显示“此房屋已被占据”. （LegacyInterface.41） 接着评估邪恶分值.
 * 以房屋范围为基准向四个方向延伸一定距离后所形成的矩形区域为评估区域. 具体延伸范围随版本号而有所不同，在 1.4.2.3 中是：
 * 水平方向：以房屋范围内最靠左/右的格子为起点，向左延伸46格，向右延伸 45 格
 * 竖直方向：以房屋范围内最靠上/下的格子为起点，向上延伸 43 格/下延伸 45 格
 * 如果以上区域四边中的任意边距离地图（真正）边缘小于5格，则收缩到以距离地图边缘5格处.
 * 统计区域中的所有前景block（考虑的是block的固有属性，包括被致动而inactive的），邪恶分值 = 腐化block数量 + 猩红block数量 - 神圣block数量 （各种类见表，注意向日葵的效果只算一次）

如果邪恶分大于等于300，直接判定房屋不合格，显示“此房屋已腐化”. （LegacyInterface.42）

如果邪恶分小于50，那么直接赋值为0.

接下来用50减去邪恶分，得到一个中间得分，下面会用到.

接着判定是否有合格的home spot. home spot为一个格子，要求符合以下条件： 如果最后结算出来的结果小于等于0，此格不合格.
 * 位于房屋内部区域 最左坐标向右一列、最右坐标向左一列、最上坐标向下2列、最下坐标向下1列所构成的矩形中（图）.
 * 必须是solid tile
 * 不能是Platform
 * 不能是Bubble
 * 未被致动
 * 左边和右边直接相邻的格子必须是solid tile且未被致动
 * 其正上方宽3格高3格范围内不能有影响通行的东西（即未致动的solid block，但可以有platform）
 * 其正上方3格必须没有有效前景tile，也不能是soild tile. 并且这3格必须全部都在房屋范围内.
 * 符合条件的格子，用中间得分结合正上方宽5高4范围内的东西情况进行分值评估，此范围内所有有效的前景tile且不是火炬、花、草的，参与评分：
 * 这范围内，在正中间一列的（即格子正上方宽1高4范围）单独评估.
 * 剩下16各范围内，满足以上条件的格子：
 * 每一格关闭的门或高门减20分.
 * 每一格开启的门的门轴部分（即关闭状态下门所占据的范围）减20分. 开启的高门不影响分数.
 * 每一格solid tile分数减5.
 * 其他的每一格加5分.
 * 如果分值小于等于0那么此格不合格.
 * 如果分值大于0，那么继续进行以下计算：
 * 如果此房屋入住会导致共享（town NPC+town 宠物），且当前格与先前入住的那个npc的home spot水平距离小于3，那么分直接设置为1.
 * 如果以上5*4范围内有箱子，每格箱子减30分. 如果计算后分数小于1那么设置为1.
 * 如果正上方1*4范围内有符合的格子，每格减15分.

房屋内必须至少有一格合格的home spot，作为npc的站立点，房屋旗会挂在npc站立点上方. 如果有多个有效的home spot，会选择分数最高的格子中最先碰到的那格（具体分数的计算还有其他因素，此处不展开）.