* Actually build the object. * @param type The type of object to build. * @param tile The tile to build the northern tile of the object on. * @param owner The owner of the object. * @param town Town the tile is related with. * @param view The view for the object. * @pre All preconditions for building the object at that location * are met, e.g. slope and clearness of tiles are check
| 86 | * are met, e.g. slope and clearness of tiles are checked. |
| 87 | */ |
| 88 | void BuildObject(ObjectType type, TileIndex tile, CompanyID owner, Town *town, uint8_t view) |
| 89 | { |
| 90 | const ObjectSpec *spec = ObjectSpec::Get(type); |
| 91 | |
| 92 | TileArea ta(tile, GB(spec->size, HasBit(view, 0) ? 4 : 0, 4), GB(spec->size, HasBit(view, 0) ? 0 : 4, 4)); |
| 93 | Object *o = new Object(type, town == nullptr ? CalcClosestTownFromTile(tile) : town, ta, TimerGameCalendar::date, view); |
| 94 | |
| 95 | /* If nothing owns the object, the colour will be random. Otherwise |
| 96 | * get the colour from the company's livery settings. */ |
| 97 | if (owner == OWNER_NONE) { |
| 98 | o->colour = Random(); |
| 99 | } else { |
| 100 | o->colour = Company::Get(owner)->GetCompanyRecolourOffset(LS_DEFAULT); |
| 101 | } |
| 102 | |
| 103 | /* If the object wants only one colour, then give it that colour. */ |
| 104 | if (!spec->flags.Test(ObjectFlag::Uses2CC)) o->colour &= 0xF; |
| 105 | |
| 106 | if (spec->callback_mask.Test(ObjectCallbackMask::Colour)) { |
| 107 | uint16_t res = GetObjectCallback(CBID_OBJECT_COLOUR, o->colour, 0, spec, o, tile); |
| 108 | if (res != CALLBACK_FAILED) { |
| 109 | if (res >= 0x100) ErrorUnknownCallbackResult(spec->grf_prop.grfid, CBID_OBJECT_COLOUR, res); |
| 110 | o->colour = GB(res, 0, 8); |
| 111 | } |
| 112 | } |
| 113 | |
| 114 | assert(o->town != nullptr); |
| 115 | |
| 116 | for (TileIndex t : ta) { |
| 117 | if (IsWaterTile(t)) ClearNeighbourNonFloodingStates(t); |
| 118 | if (HasTileWaterGround(t)) InvalidateWaterRegion(t); |
| 119 | WaterClass wc = (IsWaterTile(t) ? GetWaterClass(t) : WaterClass::Invalid); |
| 120 | /* Update company infrastructure counts for objects build on canals owned by nobody. */ |
| 121 | if (wc == WaterClass::Canal && owner != OWNER_NONE && (IsTileOwner(t, OWNER_NONE) || IsTileOwner(t, OWNER_WATER))) { |
| 122 | Company::Get(owner)->infrastructure.water++; |
| 123 | DirtyCompanyInfrastructureWindows(owner); |
| 124 | } |
| 125 | bool remove = IsDockingTile(t); |
| 126 | MakeObject(t, owner, o->index, wc, Random()); |
| 127 | if (remove) RemoveDockingTile(t); |
| 128 | MarkTileDirtyByTile(t); |
| 129 | } |
| 130 | |
| 131 | Object::IncTypeCount(type); |
| 132 | if (spec->flags.Test(ObjectFlag::Animation)) TriggerObjectAnimation(o, ObjectAnimationTrigger::Built, spec); |
| 133 | } |
| 134 | |
| 135 | /** |
| 136 | * Increase the HQ size. |
no test coverage detected