2005-07-24 15:12:37 +01:00
/* $Id$ */
2009-08-21 21:21:05 +01:00
/*
* This file is part of OpenTTD .
* OpenTTD is free software ; you can redistribute it and / or modify it under the terms of the GNU General Public License as published by the Free Software Foundation , version 2.
* OpenTTD is distributed in the hope that it will be useful , but WITHOUT ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE .
* See the GNU General Public License for more details . You should have received a copy of the GNU General Public License along with OpenTTD . If not , see < http : //www.gnu.org/licenses/>.
*/
2008-05-06 16:11:33 +01:00
/** @file industry_cmd.cpp Handling of industry tiles. */
2007-03-03 04:04:22 +00:00
2004-08-09 18:04:08 +01:00
# include "stdafx.h"
2006-03-05 10:19:33 +00:00
# include "clear_map.h"
2009-08-30 12:47:41 +01:00
# include "industry.h"
2009-06-24 18:39:54 +01:00
# include "station_base.h"
2007-11-15 22:20:33 +00:00
# include "train.h"
2008-01-09 09:57:48 +00:00
# include "viewport_func.h"
2007-12-21 21:50:46 +00:00
# include "command_func.h"
2004-08-09 18:04:08 +01:00
# include "town.h"
2008-03-28 08:53:36 +00:00
# include "news_func.h"
2009-01-31 20:16:06 +00:00
# include "cheat_type.h"
(svn r5946) -Add: merged the TGP branch to mainline. TGP adds:
- New optional landscape generator (TerraGenesis Perlin)
- Load heightmaps (either BMP or PNG)
- Progress dialog while generating worlds (no longer a 'hanging' screen)
- New dialogs for NewGame, Create Scenario and Play Heightmap
- Easier to configure your landscape
- More things to configure (tree-placer, ..)
- Speedup of world generation
- New console command 'restart': restart the map EXACTLY as it was when you
first started it (needs a game made after or with this commit)
- New console command 'getseed': get the seed of your map and share it with
others (of course only works with generated maps)
- Many new, world generation related, things
- Many internal cleanups and rewrites
Many tnx to those people who helped making this:
Belugas, DaleStan, glx, KUDr, RichK67, Rubidium, and TrueLight (alfabetic)
Many tnx to those who helped testing:
Arnau, Bjarni, and tokai (alfabetic)
And to all other people who helped testing and sending comments / bugs
Stats: 673 lines changed, 3534 new lines, 79 new strings
2006-08-19 11:00:30 +01:00
# include "genworld.h"
2007-02-02 15:14:28 +00:00
# include "tree_map.h"
2009-11-05 19:46:17 +00:00
# include "newgrf_cargo.h"
2010-04-24 14:39:11 +01:00
# include "newgrf_debug.h"
2007-06-19 18:33:12 +01:00
# include "newgrf_industrytiles.h"
2007-09-14 23:27:40 +01:00
# include "autoslope.h"
2007-11-24 08:45:04 +00:00
# include "water.h"
2007-12-21 19:49:27 +00:00
# include "strings_func.h"
2007-12-25 11:26:07 +00:00
# include "functions.h"
# include "window_func.h"
2007-12-26 13:50:40 +00:00
# include "date_func.h"
2007-12-27 13:35:39 +00:00
# include "vehicle_func.h"
2007-12-29 09:24:26 +00:00
# include "sound_func.h"
2008-04-20 09:22:59 +01:00
# include "animated_tile_func.h"
2008-04-20 12:12:07 +01:00
# include "effectvehicle_func.h"
2010-01-15 16:41:15 +00:00
# include "effectvehicle_base.h"
2009-01-12 17:11:45 +00:00
# include "ai/ai.hpp"
2009-05-22 16:13:50 +01:00
# include "core/pool_func.hpp"
2009-05-23 16:46:00 +01:00
# include "subsidy_func.h"
2010-05-31 21:22:57 +01:00
# include "core/backup_type.hpp"
2010-09-04 01:16:33 +01:00
# include "object_base.h"
2004-08-09 18:04:08 +01:00
2008-01-13 01:21:35 +00:00
# include "table/strings.h"
# include "table/industry_land.h"
# include "table/build_industry.h"
2009-05-22 16:13:50 +01:00
IndustryPool _industry_pool ( " Industry " ) ;
INSTANTIATE_POOL_METHODS ( Industry )
2006-08-26 20:51:49 +01:00
void ShowIndustryViewWindow ( int industry ) ;
void BuildOilRig ( TileIndex tile ) ;
static byte _industry_sound_ctr ;
static TileIndex _industry_sound_tile ;
2010-03-20 14:30:16 +00:00
uint16 Industry : : counts [ NUM_INDUSTRYTYPES ] ;
2007-06-08 16:48:48 +01:00
2007-05-29 18:41:59 +01:00
IndustrySpec _industry_specs [ NUM_INDUSTRYTYPES ] ;
IndustryTileSpec _industry_tile_specs [ NUM_INDUSTRYTILES ] ;
2010-11-13 15:02:31 +00:00
IndustryBuildData _industry_builder ; ///< In-game manager of industries.
2007-05-29 18:41:59 +01:00
2010-08-01 20:22:34 +01:00
/**
* This function initialize the spec arrays of both
2007-05-29 18:41:59 +01:00
* industry and industry tiles .
* It adjusts the enabling of the industry too , based on climate availability .
2010-08-01 20:44:49 +01:00
* This will allow for clearer testings
*/
2007-05-29 18:41:59 +01:00
void ResetIndustries ( )
{
memset ( & _industry_specs , 0 , sizeof ( _industry_specs ) ) ;
memcpy ( & _industry_specs , & _origin_industry_specs , sizeof ( _origin_industry_specs ) ) ;
/* once performed, enable only the current climate industries */
for ( IndustryType i = 0 ; i < NUM_INDUSTRYTYPES ; i + + ) {
2007-09-28 22:24:25 +01:00
_industry_specs [ i ] . enabled = i < NEW_INDUSTRYOFFSET & &
2008-05-29 16:13:28 +01:00
HasBit ( _origin_industry_specs [ i ] . climate_availability , _settings_game . game_creation . landscape ) ;
2007-05-29 18:41:59 +01:00
}
memset ( & _industry_tile_specs , 0 , sizeof ( _industry_tile_specs ) ) ;
memcpy ( & _industry_tile_specs , & _origin_industry_tile_specs , sizeof ( _origin_industry_tile_specs ) ) ;
2007-10-03 01:57:54 +01:00
/* Reset any overrides that have been set. */
_industile_mngr . ResetOverride ( ) ;
_industry_mngr . ResetOverride ( ) ;
2007-05-29 18:41:59 +01:00
}
2006-04-10 22:00:56 +01:00
/**
* Retrieve the type for this industry . Although it is accessed by a tile ,
* it will return the general type of industry , and not the sprite index
* as would do GetIndustryGfx .
* @ param tile that is queried
* @ pre IsTileType ( tile , MP_INDUSTRY )
* @ return general type for this industry , as defined in industry . h
2010-08-01 20:44:49 +01:00
*/
2006-04-10 22:00:56 +01:00
IndustryType GetIndustryType ( TileIndex tile )
{
assert ( IsTileType ( tile , MP_INDUSTRY ) ) ;
2009-08-30 12:47:41 +01:00
const Industry * ind = Industry : : GetByTile ( tile ) ;
2009-05-22 16:13:50 +01:00
assert ( ind ! = NULL ) ;
return ind - > type ;
2006-04-10 22:00:56 +01:00
}
2004-08-09 18:04:08 +01:00
2006-04-26 15:58:06 +01:00
/**
* Accessor for array _industry_specs .
* This will ensure at once : proper access and
* not allowing modifications of it .
2006-04-26 22:10:01 +01:00
* @ param thistype of industry ( which is the index in _industry_specs )
2007-04-19 15:50:01 +01:00
* @ pre thistype < NUM_INDUSTRYTYPES
2007-03-03 04:04:22 +00:00
* @ return a pointer to the corresponding industry spec
2010-08-01 20:44:49 +01:00
*/
2006-04-28 22:58:16 +01:00
const IndustrySpec * GetIndustrySpec ( IndustryType thistype )
2006-04-26 15:58:06 +01:00
{
2007-04-19 15:50:01 +01:00
assert ( thistype < NUM_INDUSTRYTYPES ) ;
2006-04-26 15:58:06 +01:00
return & _industry_specs [ thistype ] ;
}
2007-03-03 04:04:22 +00:00
/**
* Accessor for array _industry_tile_specs .
* This will ensure at once : proper access and
* not allowing modifications of it .
2007-07-20 15:49:41 +01:00
* @ param gfx of industrytile ( which is the index in _industry_tile_specs )
2007-05-30 03:08:18 +01:00
* @ pre gfx < INVALID_INDUSTRYTILE
2007-03-03 04:04:22 +00:00
* @ return a pointer to the corresponding industrytile spec
2010-08-01 20:44:49 +01:00
*/
2007-08-22 02:16:08 +01:00
const IndustryTileSpec * GetIndustryTileSpec ( IndustryGfx gfx )
2007-02-21 02:22:43 +00:00
{
2007-05-30 03:08:18 +01:00
assert ( gfx < INVALID_INDUSTRYTILE ) ;
2007-08-22 02:16:08 +01:00
return & _industry_tile_specs [ gfx ] ;
2007-02-21 02:22:43 +00:00
}
2007-08-03 00:21:52 +01:00
Industry : : ~ Industry ( )
2006-08-26 20:51:49 +01:00
{
2007-08-06 15:08:25 +01:00
if ( CleaningPool ( ) ) return ;
2007-08-03 00:21:52 +01:00
/* Industry can also be destroyed when not fully initialized.
2010-03-20 14:30:16 +00:00
* This means that we do not have to clear tiles either .
* Also we must not decrement industry counts in that case . */
2010-01-04 18:21:07 +00:00
if ( this - > location . w = = 0 ) return ;
2007-08-03 00:21:52 +01:00
2010-01-04 18:30:10 +00:00
TILE_AREA_LOOP ( tile_cur , this - > location ) {
2006-08-26 20:51:49 +01:00
if ( IsTileType ( tile_cur , MP_INDUSTRY ) ) {
2007-08-03 00:21:52 +01:00
if ( GetIndustryIndex ( tile_cur ) = = this - > index ) {
2010-04-24 14:39:11 +01:00
DeleteNewGRFInspectWindow ( GSF_INDUSTRYTILES , tile_cur ) ;
2008-07-26 17:14:10 +01:00
/* MakeWaterKeepingClass() can also handle 'land' */
MakeWaterKeepingClass ( tile_cur , OWNER_NONE ) ;
2006-08-26 20:51:49 +01:00
}
} else if ( IsTileType ( tile_cur , MP_STATION ) & & IsOilRig ( tile_cur ) ) {
DeleteOilRig ( tile_cur ) ;
}
2009-07-26 22:50:30 +01:00
}
2006-08-26 20:51:49 +01:00
2007-08-03 00:21:52 +01:00
if ( GetIndustrySpec ( this - > type ) - > behaviour & INDUSTRYBEH_PLANT_FIELDS ) {
2010-12-12 20:11:46 +00:00
TileArea ta ( this - > location . tile - TileDiffXY ( min ( TileX ( this - > location . tile ) , 21 ) , min ( TileY ( this - > location . tile ) , 21 ) ) , 42 , 42 ) ;
ta . ClampToMap ( ) ;
2006-08-26 20:51:49 +01:00
/* Remove the farmland and convert it to regular tiles over time. */
2010-12-12 20:11:46 +00:00
TILE_AREA_LOOP ( tile_cur , ta ) {
2006-08-26 20:51:49 +01:00
if ( IsTileType ( tile_cur , MP_CLEAR ) & & IsClearGround ( tile_cur , CLEAR_FIELDS ) & &
2007-08-03 00:21:52 +01:00
GetIndustryIndexOfField ( tile_cur ) = = this - > index ) {
2006-08-26 20:51:49 +01:00
SetIndustryIndexOfField ( tile_cur , INVALID_INDUSTRY ) ;
}
2009-07-26 22:50:30 +01:00
}
2006-08-26 20:51:49 +01:00
}
2008-12-26 19:37:50 +00:00
/* don't let any disaster vehicle target invalid industry */
ReleaseDisastersTargetingIndustry ( this - > index ) ;
2007-08-03 00:21:52 +01:00
DecIndustryTypeCount ( this - > type ) ;
2007-06-08 16:48:48 +01:00
2009-05-24 17:52:42 +01:00
DeleteIndustryNews ( this - > index ) ;
2007-08-03 00:21:52 +01:00
DeleteWindowById ( WC_INDUSTRY_VIEW , this - > index ) ;
2010-04-24 14:39:11 +01:00
DeleteNewGRFInspectWindow ( GSF_INDUSTRIES , this - > index ) ;
2009-06-25 16:42:03 +01:00
2009-08-08 17:42:55 +01:00
DeleteSubsidyWith ( ST_INDUSTRY , this - > index ) ;
CargoPacket : : InvalidateAllFrom ( ST_INDUSTRY , this - > index ) ;
2009-09-08 13:22:28 +01:00
}
/**
* Invalidating some stuff after removing item from the pool .
* @ param index index of deleted item
*/
void Industry : : PostDestructor ( size_t index )
{
InvalidateWindowData ( WC_INDUSTRY_DIRECTORY , 0 , 0 ) ;
2009-06-25 16:42:03 +01:00
Station : : RecomputeIndustriesNearForAll ( ) ;
2006-08-26 20:51:49 +01:00
}
2009-06-26 16:08:54 +01:00
/**
* Return a random valid industry .
* @ return random industry , NULL if there are no industries
*/
/* static */ Industry * Industry : : GetRandom ( )
{
if ( Industry : : GetNumItems ( ) = = 0 ) return NULL ;
int num = RandomRange ( ( uint16 ) Industry : : GetNumItems ( ) ) ;
size_t index = MAX_UVALUE ( size_t ) ;
while ( num > = 0 ) {
num - - ;
index + + ;
/* Make sure we have a valid industry */
while ( ! Industry : : IsValidID ( index ) ) {
index + + ;
assert ( index < Industry : : GetPoolSize ( ) ) ;
}
}
return Industry : : Get ( index ) ;
}
2006-03-21 23:22:21 +00:00
static void IndustryDrawSugarMine ( const TileInfo * ti )
2004-08-09 18:04:08 +01:00
{
2006-03-24 13:46:45 +00:00
if ( ! IsIndustryCompleted ( ti - > tile ) ) return ;
2004-09-11 10:55:19 +01:00
2010-08-26 15:45:45 +01:00
const DrawIndustryAnimationStruct * d = & _draw_industry_spec1 [ GetAnimationFrame ( ti - > tile ) ] ;
2004-08-09 18:04:08 +01:00
2007-01-14 19:57:49 +00:00
AddChildSpriteScreen ( SPR_IT_SUGAR_MINE_SIEVE + d - > image_1 , PAL_NONE , d - > x , 0 ) ;
2004-08-09 18:04:08 +01:00
2007-04-21 03:47:33 +01:00
if ( d - > image_2 ! = 0 ) {
AddChildSpriteScreen ( SPR_IT_SUGAR_MINE_CLOUDS + d - > image_2 - 1 , PAL_NONE , 8 , 41 ) ;
}
2004-08-09 18:04:08 +01:00
2007-04-21 03:47:33 +01:00
if ( d - > image_3 ! = 0 ) {
AddChildSpriteScreen ( SPR_IT_SUGAR_MINE_PILE + d - > image_3 - 1 , PAL_NONE ,
_drawtile_proc1 [ d - > image_3 - 1 ] . x , _drawtile_proc1 [ d - > image_3 - 1 ] . y ) ;
2005-11-14 19:48:04 +00:00
}
2004-08-09 18:04:08 +01:00
}
2006-03-21 23:22:21 +00:00
static void IndustryDrawToffeeQuarry ( const TileInfo * ti )
2004-08-09 18:04:08 +01:00
{
2007-04-21 03:47:33 +01:00
uint8 x = 0 ;
2004-09-11 10:55:19 +01:00
2006-03-24 13:46:45 +00:00
if ( IsIndustryCompleted ( ti - > tile ) ) {
2010-08-26 15:45:45 +01:00
x = _industry_anim_offs_toffee [ GetAnimationFrame ( ti - > tile ) ] ;
2010-07-24 11:14:39 +01:00
if ( x = = 0xFF ) {
2004-08-09 18:04:08 +01:00
x = 0 ;
2010-07-24 11:14:39 +01:00
}
2004-08-09 18:04:08 +01:00
}
2007-01-14 19:57:49 +00:00
AddChildSpriteScreen ( SPR_IT_TOFFEE_QUARRY_SHOVEL , PAL_NONE , 22 - x , 24 + x ) ;
AddChildSpriteScreen ( SPR_IT_TOFFEE_QUARRY_TOFFEE , PAL_NONE , 6 , 14 ) ;
2004-08-09 18:04:08 +01:00
}
2006-03-21 23:22:21 +00:00
static void IndustryDrawBubbleGenerator ( const TileInfo * ti )
2004-08-09 18:04:08 +01:00
{
2006-03-24 13:46:45 +00:00
if ( IsIndustryCompleted ( ti - > tile ) ) {
2010-08-26 15:45:45 +01:00
AddChildSpriteScreen ( SPR_IT_BUBBLE_GENERATOR_BUBBLE , PAL_NONE , 5 , _industry_anim_offs_bubbles [ GetAnimationFrame ( ti - > tile ) ] ) ;
2005-11-14 19:48:04 +00:00
} else {
2007-01-14 19:57:49 +00:00
AddChildSpriteScreen ( SPR_IT_BUBBLE_GENERATOR_SPRING , PAL_NONE , 3 , 67 ) ;
2004-08-09 18:04:08 +01:00
}
}
2006-03-21 23:22:21 +00:00
static void IndustryDrawToyFactory ( const TileInfo * ti )
2004-08-09 18:04:08 +01:00
{
2010-08-26 15:45:45 +01:00
const DrawIndustryAnimationStruct * d = & _industry_anim_offs_toys [ GetAnimationFrame ( ti - > tile ) ] ;
2004-08-09 18:04:08 +01:00
if ( d - > image_1 ! = 0xFF ) {
2007-04-21 03:47:33 +01:00
AddChildSpriteScreen ( SPR_IT_TOY_FACTORY_CLAY , PAL_NONE , d - > x , 96 + d - > image_1 ) ;
2004-08-09 18:04:08 +01:00
}
if ( d - > image_2 ! = 0xFF ) {
2007-01-14 19:57:49 +00:00
AddChildSpriteScreen ( SPR_IT_TOY_FACTORY_ROBOT , PAL_NONE , 16 - d - > image_2 * 2 , 100 + d - > image_2 ) ;
2004-08-09 18:04:08 +01:00
}
2007-01-14 19:57:49 +00:00
AddChildSpriteScreen ( SPR_IT_TOY_FACTORY_STAMP , PAL_NONE , 7 , d - > image_3 ) ;
AddChildSpriteScreen ( SPR_IT_TOY_FACTORY_STAMP_HOLDER , PAL_NONE , 0 , 42 ) ;
2004-08-09 18:04:08 +01:00
}
2006-03-21 23:22:21 +00:00
static void IndustryDrawCoalPlantSparks ( const TileInfo * ti )
2004-08-09 18:04:08 +01:00
{
2006-03-24 13:46:45 +00:00
if ( IsIndustryCompleted ( ti - > tile ) ) {
2010-08-26 15:45:45 +01:00
uint8 image = GetAnimationFrame ( ti - > tile ) ;
2006-03-24 13:46:45 +00:00
2004-08-09 18:04:08 +01:00
if ( image ! = 0 & & image < 7 ) {
2006-03-21 23:22:21 +00:00
AddChildSpriteScreen ( image + SPR_IT_POWER_PLANT_TRANSFORMERS ,
2007-01-14 19:57:49 +00:00
PAL_NONE ,
2007-04-21 03:47:33 +01:00
_coal_plant_sparks [ image - 1 ] . x ,
_coal_plant_sparks [ image - 1 ] . y
2004-08-09 18:04:08 +01:00
) ;
}
}
}
2005-09-18 21:56:44 +01:00
typedef void IndustryDrawTileProc ( const TileInfo * ti ) ;
2004-08-09 18:04:08 +01:00
static IndustryDrawTileProc * const _industry_draw_tile_procs [ 5 ] = {
2006-03-21 23:22:21 +00:00
IndustryDrawSugarMine ,
IndustryDrawToffeeQuarry ,
IndustryDrawBubbleGenerator ,
IndustryDrawToyFactory ,
IndustryDrawCoalPlantSparks ,
2004-08-09 18:04:08 +01:00
} ;
static void DrawTile_Industry ( TileInfo * ti )
{
2007-06-19 18:33:12 +01:00
IndustryGfx gfx = GetIndustryGfx ( ti - > tile ) ;
2009-08-30 12:47:41 +01:00
Industry * ind = Industry : : GetByTile ( ti - > tile ) ;
2007-06-19 18:33:12 +01:00
const IndustryTileSpec * indts = GetIndustryTileSpec ( gfx ) ;
2004-08-09 18:04:08 +01:00
/* Retrieve pointer to the draw industry tile struct */
2007-06-19 18:33:12 +01:00
if ( gfx > = NEW_INDUSTRYTILEOFFSET ) {
/* Draw the tile using the specialized method of newgrf industrytile.
* DrawNewIndustry will return false if ever the resolver could not
* find any sprite to display . So in this case , we will jump on the
* substitute gfx instead . */
2010-10-28 12:10:12 +01:00
if ( indts - > grf_prop . spritegroup [ 0 ] ! = NULL & & DrawNewIndustryTile ( ti , ind , gfx , indts ) ) {
2007-06-19 18:33:12 +01:00
return ;
} else {
/* No sprite group (or no valid one) found, meaning no graphics associated.
* Use the substitute one instead */
2007-08-22 01:59:46 +01:00
if ( indts - > grf_prop . subst_id ! = INVALID_INDUSTRYTILE ) {
gfx = indts - > grf_prop . subst_id ;
/* And point the industrytile spec accordingly */
indts = GetIndustryTileSpec ( gfx ) ;
}
2007-06-19 18:33:12 +01:00
}
}
2010-07-30 11:39:24 +01:00
const DrawBuildingsTileStruct * dits = & _industry_draw_tile_data [ gfx < < 2 | ( indts - > anim_state ?
2010-08-26 15:45:45 +01:00
GetAnimationFrame ( ti - > tile ) & INDUSTRY_COMPLETED :
2006-12-30 11:57:52 +00:00
GetIndustryConstructionStage ( ti - > tile ) ) ] ;
2004-08-09 18:04:08 +01:00
2010-01-22 21:52:20 +00:00
SpriteID image = dits - > ground . sprite ;
2004-08-09 18:04:08 +01:00
2007-07-26 17:51:10 +01:00
/* DrawFoundation() modifes ti->z and ti->tileh */
if ( ti - > tileh ! = SLOPE_FLAT ) DrawFoundation ( ti , FOUNDATION_LEVELED ) ;
2004-08-09 18:04:08 +01:00
2008-07-26 17:14:10 +01:00
/* If the ground sprite is the default flat water sprite, draw also canal/river borders.
* Do not do this if the tile ' s WaterClass is ' land ' . */
2010-08-26 20:29:20 +01:00
if ( image = = SPR_FLAT_WATER_TILE & & IsTileOnWater ( ti - > tile ) ) {
2008-07-26 17:14:10 +01:00
DrawWaterClassGround ( ti ) ;
} else {
2010-01-22 21:52:20 +00:00
DrawGroundSprite ( image , GroundSpritePaletteTransform ( image , dits - > ground . pal , GENERAL_SPRITE_COLOUR ( ind - > random_colour ) ) ) ;
2008-07-26 17:14:10 +01:00
}
2007-06-24 11:20:05 +01:00
2008-04-03 20:55:40 +01:00
/* If industries are transparent and invisible, do not draw the upper part */
if ( IsInvisibilitySet ( TO_INDUSTRIES ) ) return ;
2004-08-09 18:04:08 +01:00
/* Add industry on top of the ground? */
2007-01-14 19:57:49 +00:00
image = dits - > building . sprite ;
2005-11-14 19:48:04 +00:00
if ( image ! = 0 ) {
2010-01-22 21:52:20 +00:00
AddSortableSpriteToDraw ( image , SpriteLayoutPaletteTransform ( image , dits - > building . pal , GENERAL_SPRITE_COLOUR ( ind - > random_colour ) ) ,
2005-11-16 11:55:06 +00:00
ti - > x + dits - > subtile_x ,
ti - > y + dits - > subtile_y ,
2007-09-14 22:32:21 +01:00
dits - > width ,
dits - > height ,
2004-08-09 18:04:08 +01:00
dits - > dz ,
2007-07-26 17:51:10 +01:00
ti - > z ,
2007-11-10 01:17:15 +00:00
IsTransparencySet ( TO_INDUSTRIES ) ) ;
2004-08-09 18:04:08 +01:00
2007-11-10 01:17:15 +00:00
if ( IsTransparencySet ( TO_INDUSTRIES ) ) return ;
2004-08-09 18:04:08 +01:00
}
2005-11-14 19:48:04 +00:00
{
2006-04-24 22:10:56 +01:00
int proc = dits - > draw_proc - 1 ;
2005-11-14 19:48:04 +00:00
if ( proc > = 0 ) _industry_draw_tile_procs [ proc ] ( ti ) ;
2004-08-09 18:04:08 +01:00
}
}
2006-08-06 17:32:49 +01:00
static uint GetSlopeZ_Industry ( TileIndex tile , uint x , uint y )
2005-10-19 15:49:46 +01:00
{
2006-08-06 17:32:49 +01:00
return GetTileMaxZ ( tile ) ;
2004-08-09 18:04:08 +01:00
}
2007-07-26 17:51:10 +01:00
static Foundation GetFoundation_Industry ( TileIndex tile , Slope tileh )
2005-10-22 07:39:32 +01:00
{
2008-05-31 23:43:42 +01:00
IndustryGfx gfx = GetIndustryGfx ( tile ) ;
/* For NewGRF industry tiles we might not be drawing a foundation. We need to
2008-06-12 22:36:56 +01:00
* account for this , as other structures should
2008-05-31 23:43:42 +01:00
* draw the wall of the foundation in this case .
*/
if ( gfx > = NEW_INDUSTRYTILEOFFSET ) {
const IndustryTileSpec * indts = GetIndustryTileSpec ( gfx ) ;
2010-10-28 12:10:12 +01:00
if ( indts - > grf_prop . spritegroup [ 0 ] ! = NULL & & HasBit ( indts - > callback_mask , CBM_INDT_DRAW_FOUNDATIONS ) ) {
2010-04-05 22:01:02 +01:00
uint32 callback_res = GetIndustryTileCallback ( CBID_INDTILE_DRAW_FOUNDATIONS , 0 , 0 , gfx , Industry : : GetByTile ( tile ) , tile ) ;
2008-05-31 23:43:42 +01:00
if ( callback_res = = 0 ) return FOUNDATION_NONE ;
}
}
2007-07-26 17:51:10 +01:00
return FlatteningFoundation ( tileh ) ;
2004-08-13 19:27:33 +01:00
}
2009-09-20 18:44:33 +01:00
static void AddAcceptedCargo_Industry ( TileIndex tile , CargoArray & acceptance , uint32 * always_accepted )
2004-08-09 18:04:08 +01:00
{
2007-07-08 18:40:04 +01:00
IndustryGfx gfx = GetIndustryGfx ( tile ) ;
const IndustryTileSpec * itspec = GetIndustryTileSpec ( gfx ) ;
/* When we have to use a callback, we put our data in the next two variables */
CargoID raw_accepts_cargo [ lengthof ( itspec - > accepts_cargo ) ] ;
2009-06-27 19:26:50 +01:00
uint8 raw_cargo_acceptance [ lengthof ( itspec - > acceptance ) ] ;
2007-07-08 18:40:04 +01:00
/* And then these will always point to a same sized array with the required data */
const CargoID * accepts_cargo = itspec - > accepts_cargo ;
2009-06-27 19:26:50 +01:00
const uint8 * cargo_acceptance = itspec - > acceptance ;
2007-07-08 18:40:04 +01:00
2009-09-14 13:22:57 +01:00
if ( HasBit ( itspec - > callback_mask , CBM_INDT_ACCEPT_CARGO ) ) {
2009-08-30 12:47:41 +01:00
uint16 res = GetIndustryTileCallback ( CBID_INDTILE_ACCEPT_CARGO , 0 , 0 , gfx , Industry : : GetByTile ( tile ) , tile ) ;
2007-07-08 18:40:04 +01:00
if ( res ! = CALLBACK_FAILED ) {
accepts_cargo = raw_accepts_cargo ;
for ( uint i = 0 ; i < lengthof ( itspec - > accepts_cargo ) ; i + + ) raw_accepts_cargo [ i ] = GetCargoTranslation ( GB ( res , i * 5 , 5 ) , itspec - > grf_prop . grffile ) ;
}
}
2009-09-14 13:22:57 +01:00
if ( HasBit ( itspec - > callback_mask , CBM_INDT_CARGO_ACCEPTANCE ) ) {
2009-08-30 12:47:41 +01:00
uint16 res = GetIndustryTileCallback ( CBID_INDTILE_CARGO_ACCEPTANCE , 0 , 0 , gfx , Industry : : GetByTile ( tile ) , tile ) ;
2007-07-08 18:40:04 +01:00
if ( res ! = CALLBACK_FAILED ) {
2009-06-27 19:26:50 +01:00
cargo_acceptance = raw_cargo_acceptance ;
for ( uint i = 0 ; i < lengthof ( itspec - > accepts_cargo ) ; i + + ) raw_cargo_acceptance [ i ] = GB ( res , i * 4 , 4 ) ;
2007-07-08 18:40:04 +01:00
}
}
2004-08-09 18:04:08 +01:00
2009-09-20 19:52:12 +01:00
const Industry * ind = Industry : : GetByTile ( tile ) ;
2007-05-29 01:15:34 +01:00
for ( byte i = 0 ; i < lengthof ( itspec - > accepts_cargo ) ; i + + ) {
2007-07-08 18:40:04 +01:00
CargoID a = accepts_cargo [ i ] ;
2009-09-21 18:24:21 +01:00
if ( a = = CT_INVALID | | cargo_acceptance [ i ] = = 0 ) continue ; // work only with valid cargos
2009-09-20 19:52:12 +01:00
/* Add accepted cargo */
acceptance [ a ] + = cargo_acceptance [ i ] ;
/* Maybe set 'always accepted' bit (if it's not set already) */
if ( HasBit ( * always_accepted , a ) ) continue ;
bool accepts = false ;
for ( uint cargo_index = 0 ; cargo_index < lengthof ( ind - > accepts_cargo ) ; cargo_index + + ) {
/* Test whether the industry itself accepts the cargo type */
if ( ind - > accepts_cargo [ cargo_index ] = = a ) {
accepts = true ;
break ;
}
}
if ( accepts ) continue ;
/* If the industry itself doesn't accept this cargo, set 'always accepted' bit */
SetBit ( * always_accepted , a ) ;
2007-05-29 01:15:34 +01:00
}
2004-08-09 18:04:08 +01:00
}
2005-06-24 13:38:35 +01:00
static void GetTileDesc_Industry ( TileIndex tile , TileDesc * td )
2004-08-09 18:04:08 +01:00
{
2009-08-30 12:47:41 +01:00
const Industry * i = Industry : : GetByTile ( tile ) ;
2008-07-25 23:37:34 +01:00
const IndustrySpec * is = GetIndustrySpec ( i - > type ) ;
2004-08-09 18:04:08 +01:00
2008-05-21 23:15:39 +01:00
td - > owner [ 0 ] = i - > owner ;
2008-07-25 23:37:34 +01:00
td - > str = is - > name ;
2006-03-24 13:46:45 +00:00
if ( ! IsIndustryCompleted ( tile ) ) {
2004-12-02 22:53:07 +00:00
SetDParamX ( td - > dparam , 0 , td - > str ) ;
2009-08-05 18:59:21 +01:00
td - > str = STR_LAI_TOWN_INDUSTRY_DESCRIPTION_UNDER_CONSTRUCTION ;
2004-08-09 18:04:08 +01:00
}
2008-07-25 23:37:34 +01:00
if ( is - > grf_prop . grffile ! = NULL ) {
2010-02-28 20:28:08 +00:00
td - > grf = GetGRFConfig ( is - > grf_prop . grffile - > grfid ) - > GetName ( ) ;
2008-07-25 23:37:34 +01:00
}
2004-08-09 18:04:08 +01:00
}
2009-02-09 21:20:05 +00:00
static CommandCost ClearTile_Industry ( TileIndex tile , DoCommandFlag flags )
2004-08-09 18:04:08 +01:00
{
2009-08-30 12:47:41 +01:00
Industry * i = Industry : : GetByTile ( tile ) ;
2007-03-28 21:06:28 +01:00
const IndustrySpec * indspec = GetIndustrySpec ( i - > type ) ;
2004-08-09 18:04:08 +01:00
2006-08-28 19:53:03 +01:00
/* water can destroy industries
* in editor you can bulldoze industries
* with magic_bulldozer cheat you can destroy industries
* ( area around OILRIG is water , so water shouldn ' t flood it
*/
2008-09-30 21:39:50 +01:00
if ( ( _current_company ! = OWNER_WATER & & _game_mode ! = GM_EDITOR & &
2004-09-03 18:57:27 +01:00
! _cheats . magic_bulldozer . value ) | |
2007-09-26 15:14:51 +01:00
( ( flags & DC_AUTO ) ! = 0 ) | |
2008-09-30 21:39:50 +01:00
( _current_company = = OWNER_WATER & &
2008-08-17 14:56:11 +01:00
( ( indspec - > behaviour & INDUSTRYBEH_BUILT_ONWATER ) | |
HasBit ( GetIndustryTileSpec ( GetIndustryGfx ( tile ) ) - > slopes_refused , 5 ) ) ) ) {
2010-02-26 10:08:16 +00:00
SetDParam ( 1 , indspec - > name ) ;
2010-08-08 11:59:30 +01:00
return_cmd_error ( flags & DC_AUTO ? STR_ERROR_GENERIC_OBJECT_IN_THE_WAY : INVALID_STRING_ID ) ;
2004-08-09 18:04:08 +01:00
}
2009-01-12 17:11:45 +00:00
if ( flags & DC_EXEC ) {
AI : : BroadcastNewEvent ( new AIEventIndustryClose ( i - > index ) ) ;
delete i ;
}
2008-01-09 16:55:48 +00:00
return CommandCost ( EXPENSES_CONSTRUCTION , indspec - > GetRemovalCost ( ) ) ;
2004-08-09 18:04:08 +01:00
}
2005-06-24 13:38:35 +01:00
static void TransportIndustryGoods ( TileIndex tile )
2004-08-09 18:04:08 +01:00
{
2009-08-30 12:47:41 +01:00
Industry * i = Industry : : GetByTile ( tile ) ;
2006-04-26 22:10:01 +01:00
const IndustrySpec * indspec = GetIndustrySpec ( i - > type ) ;
2007-10-27 12:20:47 +01:00
bool moved_cargo = false ;
2004-09-11 10:55:19 +01:00
2010-01-04 18:21:07 +00:00
StationFinder stations ( i - > location ) ;
2009-11-15 21:06:13 +00:00
2007-10-27 12:20:47 +01:00
for ( uint j = 0 ; j < lengthof ( i - > produced_cargo_waiting ) ; j + + ) {
uint cw = min ( i - > produced_cargo_waiting [ j ] , 255 ) ;
if ( cw > indspec - > minimal_cargo & & i - > produced_cargo [ j ] ! = CT_INVALID ) {
i - > produced_cargo_waiting [ j ] - = cw ;
2004-08-09 18:04:08 +01:00
2007-10-27 12:20:47 +01:00
/* fluctuating economy? */
2010-11-13 09:45:20 +00:00
if ( EconomyIsInRecession ( ) ) cw = ( cw + 1 ) / 2 ;
2004-08-09 18:04:08 +01:00
2007-10-27 12:20:47 +01:00
i - > this_month_production [ j ] + = cw ;
2004-08-09 18:04:08 +01:00
2009-11-15 21:06:13 +00:00
uint am = MoveGoodsToStation ( i - > produced_cargo [ j ] , cw , ST_INDUSTRY , i - > index , stations . GetStations ( ) ) ;
2007-10-27 12:20:47 +01:00
i - > this_month_transported [ j ] + = am ;
2006-03-25 10:38:28 +00:00
2007-10-27 12:20:47 +01:00
moved_cargo | = ( am ! = 0 ) ;
2004-08-09 18:04:08 +01:00
}
}
2007-10-27 12:20:47 +01:00
if ( moved_cargo & & ! StartStopIndustryTileAnimation ( i , IAT_INDUSTRY_DISTRIBUTES_CARGO ) ) {
uint newgfx = GetIndustryTileSpec ( GetIndustryGfx ( tile ) ) - > anim_production ;
2004-09-11 10:55:19 +01:00
2007-10-27 12:20:47 +01:00
if ( newgfx ! = INDUSTRYTILE_NOANIM ) {
ResetIndustryConstructionStage ( tile ) ;
SetIndustryCompleted ( tile , true ) ;
SetIndustryGfx ( tile , newgfx ) ;
MarkTileDirtyByTile ( tile ) ;
}
2004-08-09 18:04:08 +01:00
}
}
2005-06-24 13:38:35 +01:00
static void AnimateTile_Industry ( TileIndex tile )
2004-08-09 18:04:08 +01:00
{
2007-07-11 16:03:29 +01:00
IndustryGfx gfx = GetIndustryGfx ( tile ) ;
2010-08-26 16:31:40 +01:00
if ( GetIndustryTileSpec ( gfx ) - > animation . status ! = ANIM_STATUS_NO_ANIMATION ) {
2007-07-11 16:03:29 +01:00
AnimateNewIndustryTile ( tile ) ;
return ;
}
2004-08-09 18:04:08 +01:00
2007-07-11 16:03:29 +01:00
switch ( gfx ) {
2006-04-14 02:54:07 +01:00
case GFX_SUGAR_MINE_SIEVE :
2004-08-09 18:04:08 +01:00
if ( ( _tick_counter & 1 ) = = 0 ) {
2010-08-26 15:45:45 +01:00
byte m = GetAnimationFrame ( tile ) + 1 ;
2004-09-11 10:55:19 +01:00
2006-02-01 07:36:15 +00:00
switch ( m & 7 ) {
2006-08-28 19:53:03 +01:00
case 2 : SndPlayTileFx ( SND_2D_RIP_2 , tile ) ; break ;
2004-12-04 09:26:39 +00:00
case 6 : SndPlayTileFx ( SND_29_RIP , tile ) ; break ;
2004-08-09 18:04:08 +01:00
}
if ( m > = 96 ) {
m = 0 ;
DeleteAnimatedTile ( tile ) ;
}
2010-08-26 15:45:45 +01:00
SetAnimationFrame ( tile , m ) ;
2004-08-09 18:04:08 +01:00
MarkTileDirtyByTile ( tile ) ;
}
break ;
2006-04-14 02:54:07 +01:00
case GFX_TOFFEE_QUARY :
2004-08-09 18:04:08 +01:00
if ( ( _tick_counter & 3 ) = = 0 ) {
2010-08-26 15:45:45 +01:00
byte m = GetAnimationFrame ( tile ) ;
2004-09-11 10:55:19 +01:00
2007-04-21 03:47:33 +01:00
if ( _industry_anim_offs_toffee [ m ] = = 0xFF ) {
2004-12-04 09:26:39 +00:00
SndPlayTileFx ( SND_30_CARTOON_SOUND , tile ) ;
2004-08-09 18:04:08 +01:00
}
if ( + + m > = 70 ) {
m = 0 ;
DeleteAnimatedTile ( tile ) ;
}
2010-08-26 15:45:45 +01:00
SetAnimationFrame ( tile , m ) ;
2004-08-09 18:04:08 +01:00
MarkTileDirtyByTile ( tile ) ;
}
break ;
2006-04-14 02:54:07 +01:00
case GFX_BUBBLE_CATCHER :
2006-12-30 11:51:37 +00:00
if ( ( _tick_counter & 1 ) = = 0 ) {
2010-08-26 15:45:45 +01:00
byte m = GetAnimationFrame ( tile ) ;
2004-08-09 18:04:08 +01:00
if ( + + m > = 40 ) {
m = 0 ;
DeleteAnimatedTile ( tile ) ;
}
2010-08-26 15:45:45 +01:00
SetAnimationFrame ( tile , m ) ;
2004-08-09 18:04:08 +01:00
MarkTileDirtyByTile ( tile ) ;
}
break ;
2007-03-03 04:04:22 +00:00
/* Sparks on a coal plant */
2006-04-14 02:54:07 +01:00
case GFX_POWERPLANT_SPARKS :
2004-08-09 18:04:08 +01:00
if ( ( _tick_counter & 3 ) = = 0 ) {
2010-08-26 15:45:45 +01:00
byte m = GetAnimationFrame ( tile ) ;
2006-12-30 11:51:37 +00:00
if ( m = = 6 ) {
2010-08-26 15:45:45 +01:00
SetAnimationFrame ( tile , 0 ) ;
2004-08-09 18:04:08 +01:00
DeleteAnimatedTile ( tile ) ;
} else {
2010-08-26 15:45:45 +01:00
SetAnimationFrame ( tile , m + 1 ) ;
2004-08-09 18:04:08 +01:00
MarkTileDirtyByTile ( tile ) ;
}
}
break ;
2006-04-14 02:54:07 +01:00
case GFX_TOY_FACTORY :
2004-08-09 18:04:08 +01:00
if ( ( _tick_counter & 1 ) = = 0 ) {
2010-08-26 15:45:45 +01:00
byte m = GetAnimationFrame ( tile ) + 1 ;
2004-08-09 18:04:08 +01:00
2007-04-16 03:56:48 +01:00
switch ( m ) {
case 1 : SndPlayTileFx ( SND_2C_MACHINERY , tile ) ; break ;
case 23 : SndPlayTileFx ( SND_2B_COMEDY_HIT , tile ) ; break ;
case 28 : SndPlayTileFx ( SND_2A_EXTRACT_AND_POP , tile ) ; break ;
default :
if ( m > = 50 ) {
int n = GetIndustryAnimationLoop ( tile ) + 1 ;
m = 0 ;
if ( n > = 8 ) {
n = 0 ;
DeleteAnimatedTile ( tile ) ;
}
SetIndustryAnimationLoop ( tile , n ) ;
}
2004-08-09 18:04:08 +01:00
}
2010-08-26 15:45:45 +01:00
SetAnimationFrame ( tile , m ) ;
2004-08-09 18:04:08 +01:00
MarkTileDirtyByTile ( tile ) ;
}
break ;
2006-12-30 11:41:54 +00:00
case GFX_PLASTIC_FOUNTAIN_ANIMATED_1 : case GFX_PLASTIC_FOUNTAIN_ANIMATED_2 :
case GFX_PLASTIC_FOUNTAIN_ANIMATED_3 : case GFX_PLASTIC_FOUNTAIN_ANIMATED_4 :
case GFX_PLASTIC_FOUNTAIN_ANIMATED_5 : case GFX_PLASTIC_FOUNTAIN_ANIMATED_6 :
case GFX_PLASTIC_FOUNTAIN_ANIMATED_7 : case GFX_PLASTIC_FOUNTAIN_ANIMATED_8 :
2004-08-09 18:04:08 +01:00
if ( ( _tick_counter & 3 ) = = 0 ) {
2006-04-10 22:00:56 +01:00
IndustryGfx gfx = GetIndustryGfx ( tile ) ;
2004-08-09 18:04:08 +01:00
2006-03-25 10:38:28 +00:00
gfx = ( gfx < 155 ) ? gfx + 1 : 148 ;
SetIndustryGfx ( tile , gfx ) ;
2004-08-09 18:04:08 +01:00
MarkTileDirtyByTile ( tile ) ;
}
break ;
2006-09-08 23:12:57 +01:00
case GFX_OILWELL_ANIMATED_1 :
case GFX_OILWELL_ANIMATED_2 :
case GFX_OILWELL_ANIMATED_3 :
2004-08-09 18:04:08 +01:00
if ( ( _tick_counter & 7 ) = = 0 ) {
2007-11-25 15:35:25 +00:00
bool b = Chance16 ( 1 , 7 ) ;
2006-04-10 22:00:56 +01:00
IndustryGfx gfx = GetIndustryGfx ( tile ) ;
2006-03-25 10:38:28 +00:00
2010-08-26 15:45:45 +01:00
byte m = GetAnimationFrame ( tile ) + 1 ;
2006-09-08 23:12:57 +01:00
if ( m = = 4 & & ( m = 0 , + + gfx ) = = GFX_OILWELL_ANIMATED_3 + 1 & & ( gfx = GFX_OILWELL_ANIMATED_1 , b ) ) {
SetIndustryGfx ( tile , GFX_OILWELL_NOT_ANIMATED ) ;
2006-12-30 11:51:37 +00:00
SetIndustryConstructionStage ( tile , 3 ) ;
2004-09-11 10:55:19 +01:00
DeleteAnimatedTile ( tile ) ;
2004-08-09 18:04:08 +01:00
} else {
2010-08-26 15:45:45 +01:00
SetAnimationFrame ( tile , m ) ;
2006-03-25 10:38:28 +00:00
SetIndustryGfx ( tile , gfx ) ;
2004-08-09 18:04:08 +01:00
MarkTileDirtyByTile ( tile ) ;
}
}
break ;
2006-09-08 23:12:57 +01:00
case GFX_COAL_MINE_TOWER_ANIMATED :
case GFX_COPPER_MINE_TOWER_ANIMATED :
case GFX_GOLD_MINE_TOWER_ANIMATED : {
2004-08-09 18:04:08 +01:00
int state = _tick_counter & 0x7FF ;
2010-07-24 11:14:39 +01:00
if ( ( state - = 0x400 ) < 0 ) return ;
2004-08-09 18:04:08 +01:00
if ( state < 0x1A0 ) {
if ( state < 0x20 | | state > = 0x180 ) {
2010-08-26 15:45:45 +01:00
byte m = GetAnimationFrame ( tile ) ;
2006-12-30 11:51:37 +00:00
if ( ! ( m & 0x40 ) ) {
2010-08-26 15:45:45 +01:00
SetAnimationFrame ( tile , m | 0x40 ) ;
2004-12-04 09:26:39 +00:00
SndPlayTileFx ( SND_0B_MINING_MACHINERY , tile ) ;
2004-08-09 18:04:08 +01:00
}
2010-07-24 11:14:39 +01:00
if ( state & 7 ) return ;
2004-08-09 18:04:08 +01:00
} else {
2010-07-24 11:14:39 +01:00
if ( state & 3 ) return ;
2004-08-09 18:04:08 +01:00
}
2010-08-26 15:45:45 +01:00
byte m = ( GetAnimationFrame ( tile ) + 1 ) | 0x40 ;
2004-08-09 18:04:08 +01:00
if ( m > 0xC2 ) m = 0xC0 ;
2010-08-26 15:45:45 +01:00
SetAnimationFrame ( tile , m ) ;
2004-08-09 18:04:08 +01:00
MarkTileDirtyByTile ( tile ) ;
} else if ( state > = 0x200 & & state < 0x3A0 ) {
2010-07-30 11:39:24 +01:00
int i = ( state < 0x220 | | state > = 0x380 ) ? 7 : 3 ;
2010-07-24 11:14:39 +01:00
if ( state & i ) return ;
2004-08-09 18:04:08 +01:00
2010-08-26 15:45:45 +01:00
byte m = ( GetAnimationFrame ( tile ) & 0xBF ) - 1 ;
2004-08-09 18:04:08 +01:00
if ( m < 0x80 ) m = 0x82 ;
2010-08-26 15:45:45 +01:00
SetAnimationFrame ( tile , m ) ;
2004-08-09 18:04:08 +01:00
MarkTileDirtyByTile ( tile ) ;
}
2010-08-01 19:53:30 +01:00
break ;
}
2004-08-09 18:04:08 +01:00
}
}
2008-04-20 12:12:07 +01:00
static void CreateChimneySmoke ( TileIndex tile )
2004-08-09 18:04:08 +01:00
{
2006-05-07 08:55:05 +01:00
uint x = TileX ( tile ) * TILE_SIZE ;
uint y = TileY ( tile ) * TILE_SIZE ;
uint z = GetTileMaxZ ( tile ) ;
CreateEffectVehicle ( x + 15 , y + 14 , z + 59 , EV_CHIMNEY_SMOKE ) ;
2004-08-09 18:04:08 +01:00
}
2006-04-10 16:09:56 +01:00
static void MakeIndustryTileBigger ( TileIndex tile )
2004-08-09 18:04:08 +01:00
{
2006-04-10 16:09:56 +01:00
byte cnt = GetIndustryConstructionCounter ( tile ) + 1 ;
if ( cnt ! = 4 ) {
SetIndustryConstructionCounter ( tile , cnt ) ;
2004-08-09 18:04:08 +01:00
return ;
}
2010-07-30 11:39:24 +01:00
byte stage = GetIndustryConstructionStage ( tile ) + 1 ;
2006-04-10 16:09:56 +01:00
SetIndustryConstructionCounter ( tile , 0 ) ;
SetIndustryConstructionStage ( tile , stage ) ;
2007-07-11 16:03:29 +01:00
StartStopIndustryTileAnimation ( tile , IAT_CONSTRUCTION_STATE_CHANGE ) ;
2007-07-20 18:14:03 +01:00
if ( stage = = INDUSTRY_COMPLETED ) SetIndustryCompleted ( tile , true ) ;
2004-09-11 10:55:19 +01:00
2004-08-09 18:04:08 +01:00
MarkTileDirtyByTile ( tile ) ;
2006-03-24 13:46:45 +00:00
if ( ! IsIndustryCompleted ( tile ) ) return ;
2004-08-09 18:04:08 +01:00
2007-07-11 16:03:29 +01:00
IndustryGfx gfx = GetIndustryGfx ( tile ) ;
if ( gfx > = NEW_INDUSTRYTILEOFFSET ) {
2007-11-11 00:53:59 +00:00
/* New industries are already animated on construction. */
2007-07-11 16:03:29 +01:00
return ;
}
switch ( gfx ) {
2006-09-08 23:12:57 +01:00
case GFX_POWERPLANT_CHIMNEY :
2008-04-20 12:12:07 +01:00
CreateChimneySmoke ( tile ) ;
2004-08-09 18:04:08 +01:00
break ;
2009-09-13 11:58:41 +01:00
case GFX_OILRIG_1 : {
/* Do not require an industry tile to be after the first two GFX_OILRIG_1
* tiles ( like the default oil rig ) . Do a proper check to ensure the
* tiles belong to the same industry and based on that build the oil rig ' s
* station . */
TileIndex other = tile + TileDiffXY ( 0 , 1 ) ;
if ( IsTileType ( other , MP_INDUSTRY ) & &
GetIndustryGfx ( other ) = = GFX_OILRIG_1 & &
GetIndustryIndex ( tile ) = = GetIndustryIndex ( other ) ) {
BuildOilRig ( tile ) ;
}
2010-08-01 19:53:30 +01:00
break ;
}
2004-08-09 18:04:08 +01:00
2006-04-14 02:54:07 +01:00
case GFX_TOY_FACTORY :
case GFX_BUBBLE_CATCHER :
case GFX_TOFFEE_QUARY :
2010-08-26 15:45:45 +01:00
SetAnimationFrame ( tile , 0 ) ;
2006-04-12 19:10:54 +01:00
SetIndustryAnimationLoop ( tile , 0 ) ;
2004-08-09 18:04:08 +01:00
break ;
2006-12-30 11:41:54 +00:00
case GFX_PLASTIC_FOUNTAIN_ANIMATED_1 : case GFX_PLASTIC_FOUNTAIN_ANIMATED_2 :
case GFX_PLASTIC_FOUNTAIN_ANIMATED_3 : case GFX_PLASTIC_FOUNTAIN_ANIMATED_4 :
case GFX_PLASTIC_FOUNTAIN_ANIMATED_5 : case GFX_PLASTIC_FOUNTAIN_ANIMATED_6 :
case GFX_PLASTIC_FOUNTAIN_ANIMATED_7 : case GFX_PLASTIC_FOUNTAIN_ANIMATED_8 :
2004-08-09 18:04:08 +01:00
AddAnimatedTile ( tile ) ;
break ;
}
}
2006-03-21 23:22:21 +00:00
static void TileLoopIndustry_BubbleGenerator ( TileIndex tile )
2004-08-09 18:04:08 +01:00
{
2008-04-20 12:12:07 +01:00
static const int8 _bubble_spawn_location [ 3 ] [ 4 ] = {
{ 11 , 0 , - 4 , - 14 } ,
{ - 4 , - 10 , - 4 , 1 } ,
{ 49 , 59 , 60 , 65 } ,
2004-08-09 18:04:08 +01:00
} ;
2004-12-04 09:26:39 +00:00
SndPlayTileFx ( SND_2E_EXTRACT_AND_POP , tile ) ;
2004-09-11 10:55:19 +01:00
2009-05-22 19:56:25 +01:00
int dir = Random ( ) & 3 ;
2004-08-09 18:04:08 +01:00
2009-05-22 19:56:25 +01:00
EffectVehicle * v = CreateEffectVehicleAbove (
2008-04-20 12:12:07 +01:00
TileX ( tile ) * TILE_SIZE + _bubble_spawn_location [ 0 ] [ dir ] ,
TileY ( tile ) * TILE_SIZE + _bubble_spawn_location [ 1 ] [ dir ] ,
_bubble_spawn_location [ 2 ] [ dir ] ,
2005-02-12 15:53:32 +00:00
EV_BUBBLE
2004-08-09 18:04:08 +01:00
) ;
2009-05-22 19:56:25 +01:00
if ( v ! = NULL ) v - > animation_substate = dir ;
2004-08-09 18:04:08 +01:00
}
2005-06-24 13:38:35 +01:00
static void TileLoop_Industry ( TileIndex tile )
2004-08-09 18:04:08 +01:00
{
2010-08-26 20:29:20 +01:00
if ( IsTileOnWater ( tile ) ) TileLoop_Water ( tile ) ;
2008-07-26 17:14:10 +01:00
2010-09-06 16:23:16 +01:00
/* Normally this doesn't happen, but if an industry NewGRF is removed
* an industry that was previously build on water can now be flooded .
* If this happens the tile is no longer an industry tile after
* returning from TileLoop_Water . */
if ( ! IsTileType ( tile , MP_INDUSTRY ) ) return ;
2007-11-11 17:56:37 +00:00
TriggerIndustryTile ( tile , INDTILE_TRIGGER_TILE_LOOP ) ;
2006-03-24 13:46:45 +00:00
if ( ! IsIndustryCompleted ( tile ) ) {
2006-04-10 16:09:56 +01:00
MakeIndustryTileBigger ( tile ) ;
2004-08-09 18:04:08 +01:00
return ;
}
2005-11-14 19:48:04 +00:00
if ( _game_mode = = GM_EDITOR ) return ;
2004-08-09 18:04:08 +01:00
TransportIndustryGoods ( tile ) ;
2007-07-11 16:03:29 +01:00
if ( StartStopIndustryTileAnimation ( tile , IAT_TILELOOP ) ) return ;
2010-07-30 11:39:24 +01:00
IndustryGfx newgfx = GetIndustryTileSpec ( GetIndustryGfx ( tile ) ) - > anim_next ;
2007-05-29 18:41:59 +01:00
if ( newgfx ! = INDUSTRYTILE_NOANIM ) {
2006-04-10 16:09:56 +01:00
ResetIndustryConstructionStage ( tile ) ;
2006-03-25 10:38:28 +00:00
SetIndustryGfx ( tile , newgfx ) ;
2004-08-09 18:04:08 +01:00
MarkTileDirtyByTile ( tile ) ;
return ;
}
2010-07-30 11:39:24 +01:00
IndustryGfx gfx = GetIndustryGfx ( tile ) ;
2006-12-30 11:51:37 +00:00
switch ( gfx ) {
2006-09-08 23:12:57 +01:00
case GFX_COAL_MINE_TOWER_NOT_ANIMATED :
case GFX_COPPER_MINE_TOWER_NOT_ANIMATED :
case GFX_GOLD_MINE_TOWER_NOT_ANIMATED :
2007-11-25 15:35:25 +00:00
if ( ! ( _tick_counter & 0x400 ) & & Chance16 ( 1 , 2 ) ) {
2006-12-30 11:51:37 +00:00
switch ( gfx ) {
case GFX_COAL_MINE_TOWER_NOT_ANIMATED : gfx = GFX_COAL_MINE_TOWER_ANIMATED ; break ;
case GFX_COPPER_MINE_TOWER_NOT_ANIMATED : gfx = GFX_COPPER_MINE_TOWER_ANIMATED ; break ;
case GFX_GOLD_MINE_TOWER_NOT_ANIMATED : gfx = GFX_GOLD_MINE_TOWER_ANIMATED ; break ;
}
SetIndustryGfx ( tile , gfx ) ;
2010-08-26 15:45:45 +01:00
SetAnimationFrame ( tile , 0x80 ) ;
2006-12-30 11:51:37 +00:00
AddAnimatedTile ( tile ) ;
}
2004-08-09 18:04:08 +01:00
break ;
2006-09-08 23:12:57 +01:00
case GFX_OILWELL_NOT_ANIMATED :
2007-11-25 15:35:25 +00:00
if ( Chance16 ( 1 , 6 ) ) {
2006-12-30 11:51:37 +00:00
SetIndustryGfx ( tile , GFX_OILWELL_ANIMATED_1 ) ;
2010-08-26 15:45:45 +01:00
SetAnimationFrame ( tile , 0 ) ;
2006-12-30 11:51:37 +00:00
AddAnimatedTile ( tile ) ;
}
2004-08-09 18:04:08 +01:00
break ;
2006-09-08 23:12:57 +01:00
case GFX_COAL_MINE_TOWER_ANIMATED :
case GFX_COPPER_MINE_TOWER_ANIMATED :
case GFX_GOLD_MINE_TOWER_ANIMATED :
2006-12-30 11:51:37 +00:00
if ( ! ( _tick_counter & 0x400 ) ) {
switch ( gfx ) {
case GFX_COAL_MINE_TOWER_ANIMATED : gfx = GFX_COAL_MINE_TOWER_NOT_ANIMATED ; break ;
case GFX_COPPER_MINE_TOWER_ANIMATED : gfx = GFX_COPPER_MINE_TOWER_NOT_ANIMATED ; break ;
case GFX_GOLD_MINE_TOWER_ANIMATED : gfx = GFX_GOLD_MINE_TOWER_NOT_ANIMATED ; break ;
}
SetIndustryGfx ( tile , gfx ) ;
SetIndustryCompleted ( tile , true ) ;
SetIndustryConstructionStage ( tile , 3 ) ;
DeleteAnimatedTile ( tile ) ;
}
2004-08-09 18:04:08 +01:00
break ;
2006-09-08 23:12:57 +01:00
case GFX_POWERPLANT_SPARKS :
2007-11-25 15:35:25 +00:00
if ( Chance16 ( 1 , 3 ) ) {
2004-12-04 09:26:39 +00:00
SndPlayTileFx ( SND_0C_ELECTRIC_SPARK , tile ) ;
2004-08-09 18:04:08 +01:00
AddAnimatedTile ( tile ) ;
}
break ;
2006-09-08 23:12:57 +01:00
case GFX_COPPER_MINE_CHIMNEY :
2006-04-03 06:32:11 +01:00
CreateEffectVehicleAbove ( TileX ( tile ) * TILE_SIZE + 6 , TileY ( tile ) * TILE_SIZE + 6 , 43 , EV_SMOKE ) ;
2005-11-14 19:48:04 +00:00
break ;
2004-08-09 18:04:08 +01:00
2006-09-08 23:12:57 +01:00
case GFX_TOY_FACTORY : {
2009-08-30 12:47:41 +01:00
Industry * i = Industry : : GetByTile ( tile ) ;
2004-08-09 18:04:08 +01:00
if ( i - > was_cargo_delivered ) {
i - > was_cargo_delivered = false ;
2006-04-12 19:10:54 +01:00
SetIndustryAnimationLoop ( tile , 0 ) ;
2004-08-09 18:04:08 +01:00
AddAnimatedTile ( tile ) ;
}
}
break ;
2006-09-08 23:12:57 +01:00
case GFX_BUBBLE_GENERATOR :
2006-03-21 23:22:21 +00:00
TileLoopIndustry_BubbleGenerator ( tile ) ;
2004-09-11 10:55:19 +01:00
break ;
2006-09-08 23:12:57 +01:00
case GFX_TOFFEE_QUARY :
2004-08-09 18:04:08 +01:00
AddAnimatedTile ( tile ) ;
break ;
2006-09-08 23:12:57 +01:00
case GFX_SUGAR_MINE_SIEVE :
2007-11-25 15:35:25 +00:00
if ( Chance16 ( 1 , 3 ) ) AddAnimatedTile ( tile ) ;
2004-08-09 18:04:08 +01:00
break ;
}
}
2009-01-02 22:42:05 +00:00
static bool ClickTile_Industry ( TileIndex tile )
2004-08-09 18:04:08 +01:00
{
2006-03-24 08:00:45 +00:00
ShowIndustryViewWindow ( GetIndustryIndex ( tile ) ) ;
2009-01-02 22:42:05 +00:00
return true ;
2004-08-09 18:04:08 +01:00
}
2008-02-20 17:49:50 +00:00
static TrackStatus GetTileTrackStatus_Industry ( TileIndex tile , TransportType mode , uint sub_mode , DiagDirection side )
2004-08-09 18:04:08 +01:00
{
return 0 ;
}
2008-09-30 21:39:50 +01:00
static void ChangeTileOwner_Industry ( TileIndex tile , Owner old_owner , Owner new_owner )
2004-08-09 18:04:08 +01:00
{
2007-07-07 09:53:19 +01:00
/* If the founder merges, the industry was created by the merged company */
2009-08-30 12:47:41 +01:00
Industry * i = Industry : : GetByTile ( tile ) ;
2008-09-30 21:39:50 +01:00
if ( i - > founder = = old_owner ) i - > founder = ( new_owner = = INVALID_OWNER ) ? OWNER_NONE : new_owner ;
2004-08-09 18:04:08 +01:00
}
static const byte _plantfarmfield_type [ ] = { 1 , 1 , 1 , 1 , 1 , 3 , 3 , 4 , 4 , 4 , 5 , 5 , 5 , 6 , 6 , 6 } ;
2005-01-17 09:41:46 +00:00
static bool IsBadFarmFieldTile ( TileIndex tile )
2004-08-09 18:04:08 +01:00
{
2005-01-29 15:12:40 +00:00
switch ( GetTileType ( tile ) ) {
2007-01-15 16:31:46 +00:00
case MP_CLEAR : return IsClearGround ( tile , CLEAR_FIELDS ) | | IsClearGround ( tile , CLEAR_SNOW ) | | IsClearGround ( tile , CLEAR_DESERT ) ;
2008-01-31 17:54:13 +00:00
case MP_TREES : return ( GetTreeGround ( tile ) = = TREE_GROUND_SHORE ) ;
2006-02-01 15:31:21 +00:00
default : return true ;
2004-08-09 18:04:08 +01:00
}
}
2005-01-17 09:41:46 +00:00
static bool IsBadFarmFieldTile2 ( TileIndex tile )
2004-08-09 18:04:08 +01:00
{
2005-01-29 15:12:40 +00:00
switch ( GetTileType ( tile ) ) {
2007-01-15 16:31:46 +00:00
case MP_CLEAR : return IsClearGround ( tile , CLEAR_SNOW ) | | IsClearGround ( tile , CLEAR_DESERT ) ;
2008-01-31 17:54:13 +00:00
case MP_TREES : return ( GetTreeGround ( tile ) = = TREE_GROUND_SHORE ) ;
2006-02-01 15:31:21 +00:00
default : return true ;
2004-08-09 18:04:08 +01:00
}
}
2006-03-08 06:55:33 +00:00
static void SetupFarmFieldFence ( TileIndex tile , int size , byte type , Axis direction )
2004-08-09 18:04:08 +01:00
{
do {
tile = TILE_MASK ( tile ) ;
2004-09-11 10:55:19 +01:00
2005-01-16 11:24:58 +00:00
if ( IsTileType ( tile , MP_CLEAR ) | | IsTileType ( tile , MP_TREES ) ) {
2007-01-10 18:56:51 +00:00
byte or_ = type ;
2004-09-11 10:55:19 +01:00
2007-11-25 15:35:25 +00:00
if ( or_ = = 1 & & Chance16 ( 1 , 7 ) ) or_ = 2 ;
2004-08-09 18:04:08 +01:00
2006-03-08 06:55:33 +00:00
if ( direction = = AXIS_X ) {
2007-01-10 18:56:51 +00:00
SetFenceSE ( tile , or_ ) ;
2006-03-08 06:55:33 +00:00
} else {
2007-01-10 18:56:51 +00:00
SetFenceSW ( tile , or_ ) ;
2004-08-09 18:04:08 +01:00
}
}
2004-09-11 10:55:19 +01:00
2006-03-08 06:55:33 +00:00
tile + = ( direction = = AXIS_X ? TileDiffXY ( 1 , 0 ) : TileDiffXY ( 0 , 1 ) ) ;
2004-08-09 18:04:08 +01:00
} while ( - - size ) ;
}
2006-08-20 20:31:58 +01:00
static void PlantFarmField ( TileIndex tile , IndustryID industry )
2004-08-09 18:04:08 +01:00
{
2008-05-29 16:13:28 +01:00
if ( _settings_game . game_creation . landscape = = LT_ARCTIC ) {
2010-07-24 11:14:39 +01:00
if ( GetTileZ ( tile ) + TILE_HEIGHT * 2 > = GetSnowLine ( ) ) return ;
2004-08-09 18:04:08 +01:00
}
/* determine field size */
2010-07-30 11:39:24 +01:00
uint32 r = ( Random ( ) & 0x303 ) + 0x404 ;
2008-05-29 16:13:28 +01:00
if ( _settings_game . game_creation . landscape = = LT_ARCTIC ) r + = 0x404 ;
2010-07-30 11:39:24 +01:00
uint size_x = GB ( r , 0 , 8 ) ;
uint size_y = GB ( r , 8 , 8 ) ;
2004-08-09 18:04:08 +01:00
2010-12-12 20:11:46 +00:00
TileArea ta ( tile - TileDiffXY ( min ( TileX ( tile ) , size_x / 2 ) , min ( TileY ( tile ) , size_y / 2 ) ) , size_x , size_y ) ;
ta . ClampToMap ( ) ;
2004-09-11 10:55:19 +01:00
2010-12-12 20:11:46 +00:00
if ( ta . w = = 0 | | ta . h = = 0 ) return ;
2009-01-21 02:31:55 +00:00
2004-08-09 18:04:08 +01:00
/* check the amount of bad tiles */
2010-12-12 20:11:46 +00:00
int count = 0 ;
TILE_AREA_LOOP ( cur_tile , ta ) {
2009-02-25 21:50:54 +00:00
assert ( cur_tile < MapSize ( ) ) ;
2004-08-09 18:04:08 +01:00
count + = IsBadFarmFieldTile ( cur_tile ) ;
2009-07-26 22:50:30 +01:00
}
2010-12-12 20:11:46 +00:00
if ( count * 2 > = ta . w * ta . h ) return ;
2004-08-09 18:04:08 +01:00
/* determine type of field */
r = Random ( ) ;
2010-07-30 11:39:24 +01:00
uint counter = GB ( r , 5 , 3 ) ;
uint field_type = GB ( r , 8 , 8 ) * 9 > > 8 ;
2004-08-09 18:04:08 +01:00
/* make field */
2010-12-12 20:11:46 +00:00
TILE_AREA_LOOP ( cur_tile , ta ) {
2009-02-25 21:50:54 +00:00
assert ( cur_tile < MapSize ( ) ) ;
2004-08-09 18:04:08 +01:00
if ( ! IsBadFarmFieldTile2 ( cur_tile ) ) {
2006-08-20 19:44:26 +01:00
MakeField ( cur_tile , field_type , industry ) ;
2006-02-05 11:54:25 +00:00
SetClearCounter ( cur_tile , counter ) ;
MarkTileDirtyByTile ( cur_tile ) ;
2004-08-09 18:04:08 +01:00
}
2009-07-26 22:50:30 +01:00
}
2004-09-11 10:55:19 +01:00
2010-07-30 11:39:24 +01:00
int type = 3 ;
2008-05-29 16:13:28 +01:00
if ( _settings_game . game_creation . landscape ! = LT_ARCTIC & & _settings_game . game_creation . landscape ! = LT_TROPIC ) {
2004-08-09 18:04:08 +01:00
type = _plantfarmfield_type [ Random ( ) & 0xF ] ;
}
2010-12-12 20:11:46 +00:00
SetupFarmFieldFence ( ta . tile - TileDiffXY ( 1 , 0 ) , ta . h , type , AXIS_Y ) ;
SetupFarmFieldFence ( ta . tile - TileDiffXY ( 0 , 1 ) , ta . w , type , AXIS_X ) ;
SetupFarmFieldFence ( ta . tile + TileDiffXY ( ta . w - 1 , 0 ) , ta . h , type , AXIS_Y ) ;
SetupFarmFieldFence ( ta . tile + TileDiffXY ( 0 , ta . h - 1 ) , ta . w , type , AXIS_X ) ;
2004-08-09 18:04:08 +01:00
}
2006-08-20 19:44:26 +01:00
void PlantRandomFarmField ( const Industry * i )
{
2010-01-04 18:21:07 +00:00
int x = i - > location . w / 2 + Random ( ) % 31 - 16 ;
int y = i - > location . h / 2 + Random ( ) % 31 - 16 ;
2006-08-20 19:44:26 +01:00
2010-01-04 18:21:07 +00:00
TileIndex tile = TileAddWrap ( i - > location . tile , x , y ) ;
2006-08-20 19:44:26 +01:00
if ( tile ! = INVALID_TILE ) PlantFarmField ( tile , i - > index ) ;
}
2006-11-17 23:01:58 +00:00
/**
* Search callback function for ChopLumberMillTrees
* @ param tile to test
2008-06-25 19:46:05 +01:00
* @ param user_data that is passed by the caller . In this case , nothing
2007-03-03 04:04:22 +00:00
* @ return the result of the test
2006-11-17 23:01:58 +00:00
*/
2008-06-25 19:46:05 +01:00
static bool SearchLumberMillTrees ( TileIndex tile , void * user_data )
2004-08-09 18:04:08 +01:00
{
2007-02-02 15:14:28 +00:00
if ( IsTileType ( tile , MP_TREES ) & & GetTreeGrowth ( tile ) > 2 ) { ///< 3 and up means all fully grown trees
2006-11-17 23:01:58 +00:00
/* found a tree */
2004-08-09 18:04:08 +01:00
2010-06-05 13:16:12 +01:00
Backup < CompanyByte > cur_company ( _current_company , OWNER_NONE , FILE_LINE ) ;
2010-05-31 21:22:57 +01:00
2006-11-17 23:01:58 +00:00
_industry_sound_ctr = 1 ;
_industry_sound_tile = tile ;
SndPlayTileFx ( SND_38_CHAINSAW , tile ) ;
2005-11-14 19:48:04 +00:00
2006-11-17 23:01:58 +00:00
DoCommand ( tile , 0 , 0 , DC_EXEC , CMD_LANDSCAPE_CLEAR ) ;
2005-11-14 19:48:04 +00:00
2010-05-31 21:22:57 +01:00
cur_company . Restore ( ) ;
2006-11-17 23:01:58 +00:00
return true ;
}
return false ;
}
2004-08-09 18:04:08 +01:00
2006-11-17 23:01:58 +00:00
/**
* Perform a circular search around the Lumber Mill in order to find trees to cut
* @ param i industry
*/
static void ChopLumberMillTrees ( Industry * i )
{
2010-01-04 18:21:07 +00:00
TileIndex tile = i - > location . tile ;
2004-08-09 18:04:08 +01:00
2010-11-20 14:15:02 +00:00
if ( ! IsIndustryCompleted ( tile ) ) return ; // Can't proceed if not completed.
2004-09-25 18:37:32 +01:00
2010-11-20 14:15:02 +00:00
if ( CircularTileSearch ( & tile , 40 , SearchLumberMillTrees , NULL ) ) { // 40x40 tiles to search.
i - > produced_cargo_waiting [ 0 ] = min ( 0xffff , i - > produced_cargo_waiting [ 0 ] + 45 ) ; // Found a tree, add according value to waiting cargo.
2010-07-24 11:14:39 +01:00
}
2004-08-09 18:04:08 +01:00
}
static void ProduceIndustryGoods ( Industry * i )
{
2007-05-20 01:50:06 +01:00
const IndustrySpec * indsp = GetIndustrySpec ( i - > type ) ;
2004-08-09 18:04:08 +01:00
/* play a sound? */
if ( ( i - > counter & 0x3F ) = = 0 ) {
2010-07-30 11:39:24 +01:00
uint32 r ;
uint num ;
2007-11-25 15:35:25 +00:00
if ( Chance16R ( 1 , 14 , r ) & & ( num = indsp - > number_of_sounds ) ! = 0 ) {
2004-08-09 18:04:08 +01:00
SndPlayTileFx (
2007-05-20 01:50:06 +01:00
( SoundFx ) ( indsp - > random_sounds [ ( ( r > > 16 ) * num ) > > 16 ] ) ,
2010-01-04 18:21:07 +00:00
i - > location . tile ) ;
2004-08-09 18:04:08 +01:00
}
}
i - > counter - - ;
/* produce some cargo */
if ( ( i - > counter & 0xFF ) = = 0 ) {
2009-09-14 13:22:57 +01:00
if ( HasBit ( indsp - > callback_mask , CBM_IND_PRODUCTION_256_TICKS ) ) IndustryProductionCallback ( i , 1 ) ;
2007-07-05 06:41:56 +01:00
2007-10-19 22:14:38 +01:00
IndustryBehaviour indbehav = indsp - > behaviour ;
2007-07-04 19:27:21 +01:00
i - > produced_cargo_waiting [ 0 ] = min ( 0xffff , i - > produced_cargo_waiting [ 0 ] + i - > production_rate [ 0 ] ) ;
i - > produced_cargo_waiting [ 1 ] = min ( 0xffff , i - > produced_cargo_waiting [ 1 ] + i - > production_rate [ 1 ] ) ;
2004-08-09 18:04:08 +01:00
2007-07-08 20:54:51 +01:00
if ( ( indbehav & INDUSTRYBEH_PLANT_FIELDS ) ! = 0 ) {
bool plant ;
2009-09-14 13:22:57 +01:00
if ( HasBit ( indsp - > callback_mask , CBM_IND_SPECIAL_EFFECT ) ) {
2010-01-04 18:21:07 +00:00
plant = ( GetIndustryCallback ( CBID_INDUSTRY_SPECIAL_EFFECT , Random ( ) , 0 , i , i - > type , i - > location . tile ) ! = 0 ) ;
2007-07-08 20:54:51 +01:00
} else {
2007-11-25 15:35:25 +00:00
plant = Chance16 ( 1 , 8 ) ;
2007-07-08 20:54:51 +01:00
}
if ( plant ) PlantRandomFarmField ( i ) ;
}
if ( ( indbehav & INDUSTRYBEH_CUT_TREES ) ! = 0 ) {
bool cut = ( ( i - > counter & 0x1FF ) = = 0 ) ;
2009-09-14 13:22:57 +01:00
if ( HasBit ( indsp - > callback_mask , CBM_IND_SPECIAL_EFFECT ) ) {
2010-01-04 18:21:07 +00:00
cut = ( GetIndustryCallback ( CBID_INDUSTRY_SPECIAL_EFFECT , 0 , 1 , i , i - > type , i - > location . tile ) ! = 0 ) ;
2007-07-08 20:54:51 +01:00
}
if ( cut ) ChopLumberMillTrees ( i ) ;
2005-11-14 19:48:04 +00:00
}
2008-04-23 01:14:49 +01:00
TriggerIndustry ( i , INDUSTRY_TRIGGER_INDUSTRY_TICK ) ;
StartStopIndustryTileAnimation ( i , IAT_INDUSTRY_TICK ) ;
2004-08-09 18:04:08 +01:00
}
}
2007-03-07 11:47:46 +00:00
void OnTick_Industry ( )
2004-08-09 18:04:08 +01:00
{
if ( _industry_sound_ctr ! = 0 ) {
_industry_sound_ctr + + ;
if ( _industry_sound_ctr = = 75 ) {
2004-12-04 09:26:39 +00:00
SndPlayTileFx ( SND_37_BALLOON_SQUEAK , _industry_sound_tile ) ;
2004-08-09 18:04:08 +01:00
} else if ( _industry_sound_ctr = = 160 ) {
2004-09-11 10:55:19 +01:00
_industry_sound_ctr = 0 ;
2004-12-04 09:26:39 +00:00
SndPlayTileFx ( SND_36_CARTOON_CRASH , _industry_sound_tile ) ;
2004-08-09 18:04:08 +01:00
}
}
2005-11-14 19:48:04 +00:00
if ( _game_mode = = GM_EDITOR ) return ;
2004-08-09 18:04:08 +01:00
2010-07-30 11:39:24 +01:00
Industry * i ;
2004-12-30 10:03:35 +00:00
FOR_ALL_INDUSTRIES ( i ) {
2006-08-22 16:33:35 +01:00
ProduceIndustryGoods ( i ) ;
2004-08-09 18:04:08 +01:00
}
}
2010-08-01 20:22:34 +01:00
/**
* Check the conditions of # CHECK_NOTHING ( Always succeeds ) .
2010-02-15 09:49:10 +00:00
* @ param tile % Tile to perform the checking .
2010-02-16 22:01:23 +00:00
* @ return Succeeded or failed command .
2010-02-15 09:49:10 +00:00
*/
2010-02-16 22:01:23 +00:00
static CommandCost CheckNewIndustry_NULL ( TileIndex tile )
2004-08-09 18:04:08 +01:00
{
2010-02-16 22:01:23 +00:00
return CommandCost ( ) ;
2004-08-09 18:04:08 +01:00
}
2010-08-01 20:22:34 +01:00
/**
* Check the conditions of # CHECK_FOREST ( Industry should be build above snow - line in arctic climate ) .
2010-02-15 09:49:10 +00:00
* @ param tile % Tile to perform the checking .
2010-02-16 22:01:23 +00:00
* @ return Succeeded or failed command .
2010-02-15 09:49:10 +00:00
*/
2010-02-16 22:01:23 +00:00
static CommandCost CheckNewIndustry_Forest ( TileIndex tile )
2004-08-09 18:04:08 +01:00
{
2008-05-29 16:13:28 +01:00
if ( _settings_game . game_creation . landscape = = LT_ARCTIC ) {
2007-03-20 13:47:00 +00:00
if ( GetTileZ ( tile ) < HighestSnowLine ( ) + TILE_HEIGHT * 2U ) {
2010-02-16 22:01:23 +00:00
return_cmd_error ( STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED ) ;
2004-08-09 18:04:08 +01:00
}
}
2010-02-16 22:01:23 +00:00
return CommandCost ( ) ;
2004-08-09 18:04:08 +01:00
}
2010-08-01 20:22:34 +01:00
/**
* Check the conditions of # CHECK_REFINERY ( Industry should be positioned near edge of the map ) .
2010-02-15 09:49:10 +00:00
* @ param tile % Tile to perform the checking .
2010-02-16 22:01:23 +00:00
* @ return Succeeded or failed command .
2010-02-15 09:49:10 +00:00
*/
2010-02-16 22:01:23 +00:00
static CommandCost CheckNewIndustry_OilRefinery ( TileIndex tile )
2006-05-20 17:46:37 +01:00
{
2010-02-16 22:01:23 +00:00
if ( _game_mode = = GM_EDITOR ) return CommandCost ( ) ;
if ( DistanceFromEdge ( TILE_ADDXY ( tile , 1 , 1 ) ) < _settings_game . game_creation . oil_refinery_limit ) return CommandCost ( ) ;
2006-05-20 17:46:37 +01:00
2010-02-16 22:01:23 +00:00
return_cmd_error ( STR_ERROR_CAN_ONLY_BE_POSITIONED ) ;
2006-05-20 17:46:37 +01:00
}
2004-08-10 17:12:40 +01:00
extern bool _ignore_restrictions ;
2010-08-01 20:22:34 +01:00
/**
* Check the conditions of # CHECK_OIL_RIG ( Industries at sea should be positioned near edge of the map ) .
2010-02-15 09:49:10 +00:00
* @ param tile % Tile to perform the checking .
2010-02-16 22:01:23 +00:00
* @ return Succeeded or failed command .
2010-02-15 09:49:10 +00:00
*/
2010-02-16 22:01:23 +00:00
static CommandCost CheckNewIndustry_OilRig ( TileIndex tile )
2004-08-09 18:04:08 +01:00
{
2010-02-16 22:01:23 +00:00
if ( _game_mode = = GM_EDITOR & & _ignore_restrictions ) return CommandCost ( ) ;
2006-05-20 17:46:37 +01:00
if ( TileHeight ( tile ) = = 0 & &
2010-02-16 22:01:23 +00:00
DistanceFromEdge ( TILE_ADDXY ( tile , 1 , 1 ) ) < _settings_game . game_creation . oil_refinery_limit ) return CommandCost ( ) ;
2004-08-09 18:04:08 +01:00
2010-02-16 22:01:23 +00:00
return_cmd_error ( STR_ERROR_CAN_ONLY_BE_POSITIONED ) ;
2004-08-09 18:04:08 +01:00
}
2010-08-01 20:22:34 +01:00
/**
* Check the conditions of # CHECK_FARM ( Industry should be below snow - line in arctic ) .
2010-02-15 09:49:10 +00:00
* @ param tile % Tile to perform the checking .
2010-02-16 22:01:23 +00:00
* @ return Succeeded or failed command .
2010-02-15 09:49:10 +00:00
*/
2010-02-16 22:01:23 +00:00
static CommandCost CheckNewIndustry_Farm ( TileIndex tile )
2004-08-09 18:04:08 +01:00
{
2008-05-29 16:13:28 +01:00
if ( _settings_game . game_creation . landscape = = LT_ARCTIC ) {
2007-03-20 13:47:00 +00:00
if ( GetTileZ ( tile ) + TILE_HEIGHT * 2 > = HighestSnowLine ( ) ) {
2010-02-16 22:01:23 +00:00
return_cmd_error ( STR_ERROR_SITE_UNSUITABLE ) ;
2004-08-09 18:04:08 +01:00
}
}
2010-02-16 22:01:23 +00:00
return CommandCost ( ) ;
2004-08-09 18:04:08 +01:00
}
2010-08-01 20:22:34 +01:00
/**
* Check the conditions of # CHECK_PLANTATION ( Industry should NOT be in the desert ) .
2010-02-15 09:49:10 +00:00
* @ param tile % Tile to perform the checking .
2010-02-16 22:01:23 +00:00
* @ return Succeeded or failed command .
2010-02-15 09:49:10 +00:00
*/
2010-02-16 22:01:23 +00:00
static CommandCost CheckNewIndustry_Plantation ( TileIndex tile )
2004-08-09 18:04:08 +01:00
{
2006-03-30 20:16:44 +01:00
if ( GetTropicZone ( tile ) = = TROPICZONE_DESERT ) {
2010-02-16 22:01:23 +00:00
return_cmd_error ( STR_ERROR_SITE_UNSUITABLE ) ;
2004-08-09 18:04:08 +01:00
}
2010-02-16 22:01:23 +00:00
return CommandCost ( ) ;
2004-08-09 18:04:08 +01:00
}
2010-08-01 20:22:34 +01:00
/**
* Check the conditions of # CHECK_WATER ( Industry should be in the desert ) .
2010-02-15 09:49:10 +00:00
* @ param tile % Tile to perform the checking .
2010-02-16 22:01:23 +00:00
* @ return Succeeded or failed command .
2010-02-15 09:49:10 +00:00
*/
2010-02-16 22:01:23 +00:00
static CommandCost CheckNewIndustry_Water ( TileIndex tile )
2004-08-09 18:04:08 +01:00
{
2006-03-30 20:16:44 +01:00
if ( GetTropicZone ( tile ) ! = TROPICZONE_DESERT ) {
2010-02-16 22:01:23 +00:00
return_cmd_error ( STR_ERROR_CAN_ONLY_BE_BUILT_IN_DESERT ) ;
2004-08-09 18:04:08 +01:00
}
2010-02-16 22:01:23 +00:00
return CommandCost ( ) ;
2004-08-09 18:04:08 +01:00
}
2010-08-01 20:22:34 +01:00
/**
* Check the conditions of # CHECK_LUMBERMILL ( Industry should be in the rain forest ) .
2010-02-15 09:49:10 +00:00
* @ param tile % Tile to perform the checking .
2010-02-16 22:01:23 +00:00
* @ return Succeeded or failed command .
2010-02-15 09:49:10 +00:00
*/
2010-02-16 22:01:23 +00:00
static CommandCost CheckNewIndustry_Lumbermill ( TileIndex tile )
2004-08-09 18:04:08 +01:00
{
2006-03-30 20:16:44 +01:00
if ( GetTropicZone ( tile ) ! = TROPICZONE_RAINFOREST ) {
2010-02-16 22:01:23 +00:00
return_cmd_error ( STR_ERROR_CAN_ONLY_BE_BUILT_IN_RAINFOREST ) ;
2004-08-09 18:04:08 +01:00
}
2010-02-16 22:01:23 +00:00
return CommandCost ( ) ;
2004-08-09 18:04:08 +01:00
}
2010-08-01 20:22:34 +01:00
/**
* Check the conditions of # CHECK_BUBBLEGEN ( Industry should be in low land ) .
2010-02-15 09:49:10 +00:00
* @ param tile % Tile to perform the checking .
2010-02-16 22:01:23 +00:00
* @ return Succeeded or failed command .
2010-02-15 09:49:10 +00:00
*/
2010-02-16 22:01:23 +00:00
static CommandCost CheckNewIndustry_BubbleGen ( TileIndex tile )
2004-08-09 18:04:08 +01:00
{
2010-02-15 10:28:40 +00:00
if ( GetTileZ ( tile ) > TILE_HEIGHT * 4 ) {
2010-02-16 22:01:23 +00:00
return_cmd_error ( STR_ERROR_CAN_ONLY_BE_BUILT_IN_LOW_AREAS ) ;
2010-02-15 10:28:40 +00:00
}
2010-02-16 22:01:23 +00:00
return CommandCost ( ) ;
2004-08-09 18:04:08 +01:00
}
2010-08-01 20:22:34 +01:00
/**
* Industrytype check function signature .
2010-02-15 09:49:10 +00:00
* @ param tile % Tile to check .
2010-02-16 22:01:23 +00:00
* @ return Succeeded or failed command .
2010-02-15 09:49:10 +00:00
*/
2010-02-16 22:01:23 +00:00
typedef CommandCost CheckNewIndustryProc ( TileIndex tile ) ;
2010-02-15 09:49:10 +00:00
/** Check functions for different types of industry. */
2006-04-26 18:01:27 +01:00
static CheckNewIndustryProc * const _check_new_industry_procs [ CHECK_END ] = {
2010-02-15 09:49:10 +00:00
CheckNewIndustry_NULL , ///< CHECK_NOTHING
CheckNewIndustry_Forest , ///< CHECK_FOREST
CheckNewIndustry_OilRefinery , ///< CHECK_REFINERY
CheckNewIndustry_Farm , ///< CHECK_FARM
CheckNewIndustry_Plantation , ///< CHECK_PLANTATION
CheckNewIndustry_Water , ///< CHECK_WATER
CheckNewIndustry_Lumbermill , ///< CHECK_LUMBERMILL
CheckNewIndustry_BubbleGen , ///< CHECK_BUBBLEGEN
CheckNewIndustry_OilRig , ///< CHECK_OIL_RIG
2004-08-09 18:04:08 +01:00
} ;
2010-08-01 20:22:34 +01:00
/**
* Find a town for the industry , while checking for multiple industries in the same town .
2010-02-15 11:04:27 +00:00
* @ param tile Position of the industry to build .
* @ param type Industry type .
2010-02-21 14:57:27 +00:00
* @ param [ out ] town Pointer to return town for the new industry , \ c NULL is written if no good town can be found .
* @ return Succeeded or failed command .
*
* @ precond \ c * t ! = NULL
* @ postcon \ c * t points to a town on success , and \ c NULL on failure .
2010-02-15 11:04:27 +00:00
*/
2010-02-21 14:57:27 +00:00
static CommandCost FindTownForIndustry ( TileIndex tile , int type , const Town * * t )
2004-08-09 18:04:08 +01:00
{
2010-02-21 14:57:27 +00:00
* t = ClosestTownFromTile ( tile , UINT_MAX ) ;
2004-08-09 18:04:08 +01:00
2010-02-21 14:57:27 +00:00
if ( _settings_game . economy . multiple_industry_per_town ) return CommandCost ( ) ;
2004-08-09 18:04:08 +01:00
2010-02-21 14:57:27 +00:00
const Industry * i ;
2004-12-30 10:03:35 +00:00
FOR_ALL_INDUSTRIES ( i ) {
2010-02-21 14:57:27 +00:00
if ( i - > type = = ( byte ) type & & i - > town = = * t ) {
* t = NULL ;
return_cmd_error ( STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN ) ;
2004-08-09 18:04:08 +01:00
}
}
2010-02-21 14:57:27 +00:00
return CommandCost ( ) ;
2004-08-09 18:04:08 +01:00
}
2007-10-02 17:56:45 +01:00
bool IsSlopeRefused ( Slope current , Slope refused )
{
2007-10-15 19:36:20 +01:00
if ( IsSteepSlope ( current ) ) return true ;
2007-10-02 17:56:45 +01:00
if ( current ! = SLOPE_FLAT ) {
2007-12-07 21:16:38 +00:00
if ( IsSteepSlope ( refused ) ) return true ;
2007-10-02 17:56:45 +01:00
Slope t = ComplementSlope ( current ) ;
2009-06-01 12:43:36 +01:00
if ( ( refused & SLOPE_W ) & & ( t & SLOPE_NW ) ) return true ;
if ( ( refused & SLOPE_S ) & & ( t & SLOPE_NE ) ) return true ;
if ( ( refused & SLOPE_E ) & & ( t & SLOPE_SW ) ) return true ;
if ( ( refused & SLOPE_N ) & & ( t & SLOPE_SE ) ) return true ;
2007-10-02 17:56:45 +01:00
}
return false ;
}
2010-08-01 20:22:34 +01:00
/**
* Are the tiles of the industry free ?
2010-02-21 15:27:11 +00:00
* @ param tile Position to check .
* @ param it Industry tiles table .
* @ param itspec_index The index of the itsepc to build / fund
* @ param type Type of the industry .
2010-05-01 14:09:49 +01:00
* @ param initial_random_bits The random bits the industry is going to have after construction .
2010-10-16 14:15:54 +01:00
* @ param founder Industry founder
* @ param creation_type The circumstances the industry is created under .
2010-02-21 15:27:11 +00:00
* @ param [ out ] custom_shape_check Perform custom check for the site .
* @ return Failed or succeeded command .
*/
2010-10-16 14:15:54 +01:00
static CommandCost CheckIfIndustryTilesAreFree ( TileIndex tile , const IndustryTileTable * it , uint itspec_index , int type , uint16 initial_random_bits , Owner founder , IndustryAvailabilityCallType creation_type , bool * custom_shape_check = NULL )
2004-08-09 18:04:08 +01:00
{
2007-10-02 18:48:17 +01:00
bool refused_slope = false ;
bool custom_shape = false ;
2004-08-09 18:04:08 +01:00
do {
2007-08-24 01:23:35 +01:00
IndustryGfx gfx = GetTranslatedIndustryTileID ( it - > gfx ) ;
2010-01-28 19:41:45 +00:00
TileIndex cur_tile = TileAddWrap ( tile , it - > ti . x , it - > ti . y ) ;
2005-06-24 13:38:35 +01:00
2004-08-09 18:04:08 +01:00
if ( ! IsValidTile ( cur_tile ) ) {
2010-02-26 09:55:53 +00:00
return_cmd_error ( STR_ERROR_SITE_UNSUITABLE ) ;
2004-08-09 18:04:08 +01:00
}
2004-09-11 10:55:19 +01:00
2007-08-26 01:23:32 +01:00
if ( gfx = = GFX_WATERTILE_SPECIALCHECK ) {
2006-03-22 19:04:04 +00:00
if ( ! IsTileType ( cur_tile , MP_WATER ) | |
2006-04-23 14:48:16 +01:00
GetTileSlope ( cur_tile , NULL ) ! = SLOPE_FLAT ) {
2010-02-26 09:55:53 +00:00
return_cmd_error ( STR_ERROR_SITE_UNSUITABLE ) ;
2006-03-22 19:04:04 +00:00
}
2004-08-09 18:04:08 +01:00
} else {
2010-03-05 21:20:22 +00:00
CommandCost ret = EnsureNoVehicleOnGround ( cur_tile ) ;
if ( ret . Failed ( ) ) return ret ;
2010-02-26 09:55:53 +00:00
if ( MayHaveBridgeAbove ( cur_tile ) & & IsBridgeAbove ( cur_tile ) ) return_cmd_error ( STR_ERROR_SITE_UNSUITABLE ) ;
2007-06-13 16:22:28 +01:00
2007-09-06 04:02:38 +01:00
const IndustryTileSpec * its = GetIndustryTileSpec ( gfx ) ;
2007-10-19 22:14:38 +01:00
IndustryBehaviour ind_behav = GetIndustrySpec ( type ) - > behaviour ;
2004-08-09 18:04:08 +01:00
2007-10-19 22:05:25 +01:00
/* Perform land/water check if not disabled */
2010-09-05 17:00:04 +01:00
if ( ! HasBit ( its - > slopes_refused , 5 ) & & ( ( HasTileWaterClass ( cur_tile ) & & IsTileOnWater ( cur_tile ) ) = = ! ( ind_behav & INDUSTRYBEH_BUILT_ONWATER ) ) ) return_cmd_error ( STR_ERROR_SITE_UNSUITABLE ) ;
2007-10-19 22:05:25 +01:00
2009-09-14 13:22:57 +01:00
if ( HasBit ( its - > callback_mask , CBM_INDT_SHAPE_CHECK ) ) {
2007-10-02 18:48:17 +01:00
custom_shape = true ;
2010-10-16 14:15:54 +01:00
CommandCost ret = PerformIndustryTileSlopeCheck ( tile , cur_tile , its , type , gfx , itspec_index , initial_random_bits , founder , creation_type ) ;
2010-02-27 10:21:59 +00:00
if ( ret . Failed ( ) ) return ret ;
2004-08-09 18:04:08 +01:00
} else {
2007-10-19 22:05:25 +01:00
Slope tileh = GetTileSlope ( cur_tile , NULL ) ;
refused_slope | = IsSlopeRefused ( tileh , its - > slopes_refused ) ;
2007-07-09 19:53:43 +01:00
}
2004-08-09 18:04:08 +01:00
2009-01-09 15:11:35 +00:00
if ( ( ind_behav & ( INDUSTRYBEH_ONLY_INTOWN | INDUSTRYBEH_TOWN1200_MORE ) ) | | // Tile must be a house
( ( ind_behav & INDUSTRYBEH_ONLY_NEARTOWN ) & & IsTileType ( cur_tile , MP_HOUSE ) ) ) { // Tile is allowed to be a house (and it is a house)
2007-07-09 19:53:43 +01:00
if ( ! IsTileType ( cur_tile , MP_HOUSE ) ) {
2010-02-21 15:27:11 +00:00
return_cmd_error ( STR_ERROR_CAN_ONLY_BE_BUILT_IN_TOWNS ) ;
2004-08-09 18:04:08 +01:00
}
2008-11-23 16:34:27 +00:00
/* Clear the tiles as OWNER_TOWN to not affect town rating, and to not clear protected buildings */
2010-06-05 13:16:12 +01:00
Backup < CompanyByte > cur_company ( _current_company , OWNER_TOWN , FILE_LINE ) ;
2010-02-28 09:44:35 +00:00
CommandCost ret = DoCommand ( cur_tile , 0 , 0 , DC_NONE , CMD_LANDSCAPE_CLEAR ) ;
2010-05-31 21:22:57 +01:00
cur_company . Restore ( ) ;
2008-11-23 16:34:27 +00:00
2010-02-26 09:55:53 +00:00
if ( ret . Failed ( ) ) return ret ;
2009-01-09 15:11:35 +00:00
} else {
2009-02-11 20:09:29 +00:00
/* Clear the tiles, but do not affect town ratings */
2010-02-26 09:55:53 +00:00
CommandCost ret = DoCommand ( cur_tile , 0 , 0 , DC_AUTO | DC_NO_TEST_TOWN_RATING | DC_NO_MODIFY_TOWN_RATING , CMD_LANDSCAPE_CLEAR ) ;
2008-11-23 16:34:27 +00:00
2010-02-26 09:55:53 +00:00
if ( ret . Failed ( ) ) return ret ;
2007-07-09 19:53:43 +01:00
}
2004-08-09 18:04:08 +01:00
}
2005-01-06 11:39:00 +00:00
} while ( ( + + it ) - > ti . x ! = - 0x80 ) ;
2004-08-09 18:04:08 +01:00
2007-10-02 18:48:17 +01:00
if ( custom_shape_check ! = NULL ) * custom_shape_check = custom_shape ;
/* It is almost impossible to have a fully flat land in TG, so what we
* do is that we check if we can make the land flat later on . See
* CheckIfCanLevelIndustryPlatform ( ) . */
2010-02-21 15:27:11 +00:00
if ( ! refused_slope | | ( _settings_game . game_creation . land_generator = = LG_TERRAGENESIS & & _generating_world & & ! custom_shape & & ! _ignore_restrictions ) ) {
return CommandCost ( ) ;
}
2010-02-26 09:55:53 +00:00
return_cmd_error ( STR_ERROR_SITE_UNSUITABLE ) ;
2004-08-09 18:04:08 +01:00
}
2010-08-01 20:22:34 +01:00
/**
* Is the industry allowed to be built at this place for the town ?
2010-02-21 13:32:14 +00:00
* @ param tile Tile to construct the industry .
* @ param type Type of the industry .
* @ param t Town authority that the industry belongs to .
* @ return Succeeded or failed command .
*/
static CommandCost CheckIfIndustryIsAllowed ( TileIndex tile , int type , const Town * t )
(svn r5946) -Add: merged the TGP branch to mainline. TGP adds:
- New optional landscape generator (TerraGenesis Perlin)
- Load heightmaps (either BMP or PNG)
- Progress dialog while generating worlds (no longer a 'hanging' screen)
- New dialogs for NewGame, Create Scenario and Play Heightmap
- Easier to configure your landscape
- More things to configure (tree-placer, ..)
- Speedup of world generation
- New console command 'restart': restart the map EXACTLY as it was when you
first started it (needs a game made after or with this commit)
- New console command 'getseed': get the seed of your map and share it with
others (of course only works with generated maps)
- Many new, world generation related, things
- Many internal cleanups and rewrites
Many tnx to those people who helped making this:
Belugas, DaleStan, glx, KUDr, RichK67, Rubidium, and TrueLight (alfabetic)
Many tnx to those who helped testing:
Arnau, Bjarni, and tokai (alfabetic)
And to all other people who helped testing and sending comments / bugs
Stats: 673 lines changed, 3534 new lines, 79 new strings
2006-08-19 11:00:30 +01:00
{
2007-03-28 21:06:28 +01:00
if ( ( GetIndustrySpec ( type ) - > behaviour & INDUSTRYBEH_TOWN1200_MORE ) & & t - > population < 1200 ) {
2010-02-21 13:32:14 +00:00
return_cmd_error ( STR_ERROR_CAN_ONLY_BE_BUILT_IN_TOWNS_WITH_POPULATION_OF_1200 ) ;
(svn r5946) -Add: merged the TGP branch to mainline. TGP adds:
- New optional landscape generator (TerraGenesis Perlin)
- Load heightmaps (either BMP or PNG)
- Progress dialog while generating worlds (no longer a 'hanging' screen)
- New dialogs for NewGame, Create Scenario and Play Heightmap
- Easier to configure your landscape
- More things to configure (tree-placer, ..)
- Speedup of world generation
- New console command 'restart': restart the map EXACTLY as it was when you
first started it (needs a game made after or with this commit)
- New console command 'getseed': get the seed of your map and share it with
others (of course only works with generated maps)
- Many new, world generation related, things
- Many internal cleanups and rewrites
Many tnx to those people who helped making this:
Belugas, DaleStan, glx, KUDr, RichK67, Rubidium, and TrueLight (alfabetic)
Many tnx to those who helped testing:
Arnau, Bjarni, and tokai (alfabetic)
And to all other people who helped testing and sending comments / bugs
Stats: 673 lines changed, 3534 new lines, 79 new strings
2006-08-19 11:00:30 +01:00
}
2007-03-28 21:06:28 +01:00
if ( ( GetIndustrySpec ( type ) - > behaviour & INDUSTRYBEH_ONLY_NEARTOWN ) & & DistanceMax ( t - > xy , tile ) > 9 ) {
2010-02-21 13:32:14 +00:00
return_cmd_error ( STR_ERROR_SITE_UNSUITABLE ) ;
(svn r5946) -Add: merged the TGP branch to mainline. TGP adds:
- New optional landscape generator (TerraGenesis Perlin)
- Load heightmaps (either BMP or PNG)
- Progress dialog while generating worlds (no longer a 'hanging' screen)
- New dialogs for NewGame, Create Scenario and Play Heightmap
- Easier to configure your landscape
- More things to configure (tree-placer, ..)
- Speedup of world generation
- New console command 'restart': restart the map EXACTLY as it was when you
first started it (needs a game made after or with this commit)
- New console command 'getseed': get the seed of your map and share it with
others (of course only works with generated maps)
- Many new, world generation related, things
- Many internal cleanups and rewrites
Many tnx to those people who helped making this:
Belugas, DaleStan, glx, KUDr, RichK67, Rubidium, and TrueLight (alfabetic)
Many tnx to those who helped testing:
Arnau, Bjarni, and tokai (alfabetic)
And to all other people who helped testing and sending comments / bugs
Stats: 673 lines changed, 3534 new lines, 79 new strings
2006-08-19 11:00:30 +01:00
}
2010-02-21 13:32:14 +00:00
return CommandCost ( ) ;
(svn r5946) -Add: merged the TGP branch to mainline. TGP adds:
- New optional landscape generator (TerraGenesis Perlin)
- Load heightmaps (either BMP or PNG)
- Progress dialog while generating worlds (no longer a 'hanging' screen)
- New dialogs for NewGame, Create Scenario and Play Heightmap
- Easier to configure your landscape
- More things to configure (tree-placer, ..)
- Speedup of world generation
- New console command 'restart': restart the map EXACTLY as it was when you
first started it (needs a game made after or with this commit)
- New console command 'getseed': get the seed of your map and share it with
others (of course only works with generated maps)
- Many new, world generation related, things
- Many internal cleanups and rewrites
Many tnx to those people who helped making this:
Belugas, DaleStan, glx, KUDr, RichK67, Rubidium, and TrueLight (alfabetic)
Many tnx to those who helped testing:
Arnau, Bjarni, and tokai (alfabetic)
And to all other people who helped testing and sending comments / bugs
Stats: 673 lines changed, 3534 new lines, 79 new strings
2006-08-19 11:00:30 +01:00
}
static bool CheckCanTerraformSurroundingTiles ( TileIndex tile , uint height , int internal )
{
/* Check if we don't leave the map */
if ( TileX ( tile ) = = 0 | | TileY ( tile ) = = 0 | | GetTileType ( tile ) = = MP_VOID ) return false ;
2010-12-12 20:11:46 +00:00
TileArea ta ( tile - TileDiffXY ( 1 , 1 ) , 2 , 2 ) ;
TILE_AREA_LOOP ( tile_walk , ta ) {
2010-07-30 11:39:24 +01:00
uint curh = TileHeight ( tile_walk ) ;
(svn r5946) -Add: merged the TGP branch to mainline. TGP adds:
- New optional landscape generator (TerraGenesis Perlin)
- Load heightmaps (either BMP or PNG)
- Progress dialog while generating worlds (no longer a 'hanging' screen)
- New dialogs for NewGame, Create Scenario and Play Heightmap
- Easier to configure your landscape
- More things to configure (tree-placer, ..)
- Speedup of world generation
- New console command 'restart': restart the map EXACTLY as it was when you
first started it (needs a game made after or with this commit)
- New console command 'getseed': get the seed of your map and share it with
others (of course only works with generated maps)
- Many new, world generation related, things
- Many internal cleanups and rewrites
Many tnx to those people who helped making this:
Belugas, DaleStan, glx, KUDr, RichK67, Rubidium, and TrueLight (alfabetic)
Many tnx to those who helped testing:
Arnau, Bjarni, and tokai (alfabetic)
And to all other people who helped testing and sending comments / bugs
Stats: 673 lines changed, 3534 new lines, 79 new strings
2006-08-19 11:00:30 +01:00
/* Is the tile clear? */
2010-07-24 11:14:39 +01:00
if ( ( GetTileType ( tile_walk ) ! = MP_CLEAR ) & & ( GetTileType ( tile_walk ) ! = MP_TREES ) ) return false ;
(svn r5946) -Add: merged the TGP branch to mainline. TGP adds:
- New optional landscape generator (TerraGenesis Perlin)
- Load heightmaps (either BMP or PNG)
- Progress dialog while generating worlds (no longer a 'hanging' screen)
- New dialogs for NewGame, Create Scenario and Play Heightmap
- Easier to configure your landscape
- More things to configure (tree-placer, ..)
- Speedup of world generation
- New console command 'restart': restart the map EXACTLY as it was when you
first started it (needs a game made after or with this commit)
- New console command 'getseed': get the seed of your map and share it with
others (of course only works with generated maps)
- Many new, world generation related, things
- Many internal cleanups and rewrites
Many tnx to those people who helped making this:
Belugas, DaleStan, glx, KUDr, RichK67, Rubidium, and TrueLight (alfabetic)
Many tnx to those who helped testing:
Arnau, Bjarni, and tokai (alfabetic)
And to all other people who helped testing and sending comments / bugs
Stats: 673 lines changed, 3534 new lines, 79 new strings
2006-08-19 11:00:30 +01:00
/* Don't allow too big of a change if this is the sub-tile check */
2007-11-26 16:01:29 +00:00
if ( internal ! = 0 & & Delta ( curh , height ) > 1 ) return false ;
(svn r5946) -Add: merged the TGP branch to mainline. TGP adds:
- New optional landscape generator (TerraGenesis Perlin)
- Load heightmaps (either BMP or PNG)
- Progress dialog while generating worlds (no longer a 'hanging' screen)
- New dialogs for NewGame, Create Scenario and Play Heightmap
- Easier to configure your landscape
- More things to configure (tree-placer, ..)
- Speedup of world generation
- New console command 'restart': restart the map EXACTLY as it was when you
first started it (needs a game made after or with this commit)
- New console command 'getseed': get the seed of your map and share it with
others (of course only works with generated maps)
- Many new, world generation related, things
- Many internal cleanups and rewrites
Many tnx to those people who helped making this:
Belugas, DaleStan, glx, KUDr, RichK67, Rubidium, and TrueLight (alfabetic)
Many tnx to those who helped testing:
Arnau, Bjarni, and tokai (alfabetic)
And to all other people who helped testing and sending comments / bugs
Stats: 673 lines changed, 3534 new lines, 79 new strings
2006-08-19 11:00:30 +01:00
/* Different height, so the surrounding tiles of this tile
* has to be correct too ( in level , or almost in level )
* else you get a chain - reaction of terraforming . */
if ( internal = = 0 & & curh ! = height ) {
2010-07-24 11:14:39 +01:00
if ( TileX ( tile_walk ) = = 0 | | TileY ( tile_walk ) = = 0 | | ! CheckCanTerraformSurroundingTiles ( tile_walk + TileDiffXY ( - 1 , - 1 ) , height , internal + 1 ) ) {
(svn r5946) -Add: merged the TGP branch to mainline. TGP adds:
- New optional landscape generator (TerraGenesis Perlin)
- Load heightmaps (either BMP or PNG)
- Progress dialog while generating worlds (no longer a 'hanging' screen)
- New dialogs for NewGame, Create Scenario and Play Heightmap
- Easier to configure your landscape
- More things to configure (tree-placer, ..)
- Speedup of world generation
- New console command 'restart': restart the map EXACTLY as it was when you
first started it (needs a game made after or with this commit)
- New console command 'getseed': get the seed of your map and share it with
others (of course only works with generated maps)
- Many new, world generation related, things
- Many internal cleanups and rewrites
Many tnx to those people who helped making this:
Belugas, DaleStan, glx, KUDr, RichK67, Rubidium, and TrueLight (alfabetic)
Many tnx to those who helped testing:
Arnau, Bjarni, and tokai (alfabetic)
And to all other people who helped testing and sending comments / bugs
Stats: 673 lines changed, 3534 new lines, 79 new strings
2006-08-19 11:00:30 +01:00
return false ;
2010-07-24 11:14:39 +01:00
}
(svn r5946) -Add: merged the TGP branch to mainline. TGP adds:
- New optional landscape generator (TerraGenesis Perlin)
- Load heightmaps (either BMP or PNG)
- Progress dialog while generating worlds (no longer a 'hanging' screen)
- New dialogs for NewGame, Create Scenario and Play Heightmap
- Easier to configure your landscape
- More things to configure (tree-placer, ..)
- Speedup of world generation
- New console command 'restart': restart the map EXACTLY as it was when you
first started it (needs a game made after or with this commit)
- New console command 'getseed': get the seed of your map and share it with
others (of course only works with generated maps)
- Many new, world generation related, things
- Many internal cleanups and rewrites
Many tnx to those people who helped making this:
Belugas, DaleStan, glx, KUDr, RichK67, Rubidium, and TrueLight (alfabetic)
Many tnx to those who helped testing:
Arnau, Bjarni, and tokai (alfabetic)
And to all other people who helped testing and sending comments / bugs
Stats: 673 lines changed, 3534 new lines, 79 new strings
2006-08-19 11:00:30 +01:00
}
2009-07-26 22:50:30 +01:00
}
(svn r5946) -Add: merged the TGP branch to mainline. TGP adds:
- New optional landscape generator (TerraGenesis Perlin)
- Load heightmaps (either BMP or PNG)
- Progress dialog while generating worlds (no longer a 'hanging' screen)
- New dialogs for NewGame, Create Scenario and Play Heightmap
- Easier to configure your landscape
- More things to configure (tree-placer, ..)
- Speedup of world generation
- New console command 'restart': restart the map EXACTLY as it was when you
first started it (needs a game made after or with this commit)
- New console command 'getseed': get the seed of your map and share it with
others (of course only works with generated maps)
- Many new, world generation related, things
- Many internal cleanups and rewrites
Many tnx to those people who helped making this:
Belugas, DaleStan, glx, KUDr, RichK67, Rubidium, and TrueLight (alfabetic)
Many tnx to those who helped testing:
Arnau, Bjarni, and tokai (alfabetic)
And to all other people who helped testing and sending comments / bugs
Stats: 673 lines changed, 3534 new lines, 79 new strings
2006-08-19 11:00:30 +01:00
return true ;
}
/**
* This function tries to flatten out the land below an industry , without
* damaging the surroundings too much .
*/
2009-02-09 21:20:05 +00:00
static bool CheckIfCanLevelIndustryPlatform ( TileIndex tile , DoCommandFlag flags , const IndustryTileTable * it , int type )
(svn r5946) -Add: merged the TGP branch to mainline. TGP adds:
- New optional landscape generator (TerraGenesis Perlin)
- Load heightmaps (either BMP or PNG)
- Progress dialog while generating worlds (no longer a 'hanging' screen)
- New dialogs for NewGame, Create Scenario and Play Heightmap
- Easier to configure your landscape
- More things to configure (tree-placer, ..)
- Speedup of world generation
- New console command 'restart': restart the map EXACTLY as it was when you
first started it (needs a game made after or with this commit)
- New console command 'getseed': get the seed of your map and share it with
others (of course only works with generated maps)
- Many new, world generation related, things
- Many internal cleanups and rewrites
Many tnx to those people who helped making this:
Belugas, DaleStan, glx, KUDr, RichK67, Rubidium, and TrueLight (alfabetic)
Many tnx to those who helped testing:
Arnau, Bjarni, and tokai (alfabetic)
And to all other people who helped testing and sending comments / bugs
Stats: 673 lines changed, 3534 new lines, 79 new strings
2006-08-19 11:00:30 +01:00
{
const int MKEND = - 0x80 ; // used for last element in an IndustryTileTable (see build_industry.h)
int max_x = 0 ;
int max_y = 0 ;
/* Finds dimensions of largest variant of this industry */
do {
2007-09-26 02:24:12 +01:00
if ( it - > gfx = = 0xFF ) continue ; // FF been a marquer for a check on clear water, skip it
(svn r5946) -Add: merged the TGP branch to mainline. TGP adds:
- New optional landscape generator (TerraGenesis Perlin)
- Load heightmaps (either BMP or PNG)
- Progress dialog while generating worlds (no longer a 'hanging' screen)
- New dialogs for NewGame, Create Scenario and Play Heightmap
- Easier to configure your landscape
- More things to configure (tree-placer, ..)
- Speedup of world generation
- New console command 'restart': restart the map EXACTLY as it was when you
first started it (needs a game made after or with this commit)
- New console command 'getseed': get the seed of your map and share it with
others (of course only works with generated maps)
- Many new, world generation related, things
- Many internal cleanups and rewrites
Many tnx to those people who helped making this:
Belugas, DaleStan, glx, KUDr, RichK67, Rubidium, and TrueLight (alfabetic)
Many tnx to those who helped testing:
Arnau, Bjarni, and tokai (alfabetic)
And to all other people who helped testing and sending comments / bugs
Stats: 673 lines changed, 3534 new lines, 79 new strings
2006-08-19 11:00:30 +01:00
if ( it - > ti . x > max_x ) max_x = it - > ti . x ;
if ( it - > ti . y > max_y ) max_y = it - > ti . y ;
} while ( ( + + it ) - > ti . x ! = MKEND ) ;
/* Remember level height */
2010-07-30 11:39:24 +01:00
uint h = TileHeight ( tile ) ;
(svn r5946) -Add: merged the TGP branch to mainline. TGP adds:
- New optional landscape generator (TerraGenesis Perlin)
- Load heightmaps (either BMP or PNG)
- Progress dialog while generating worlds (no longer a 'hanging' screen)
- New dialogs for NewGame, Create Scenario and Play Heightmap
- Easier to configure your landscape
- More things to configure (tree-placer, ..)
- Speedup of world generation
- New console command 'restart': restart the map EXACTLY as it was when you
first started it (needs a game made after or with this commit)
- New console command 'getseed': get the seed of your map and share it with
others (of course only works with generated maps)
- Many new, world generation related, things
- Many internal cleanups and rewrites
Many tnx to those people who helped making this:
Belugas, DaleStan, glx, KUDr, RichK67, Rubidium, and TrueLight (alfabetic)
Many tnx to those who helped testing:
Arnau, Bjarni, and tokai (alfabetic)
And to all other people who helped testing and sending comments / bugs
Stats: 673 lines changed, 3534 new lines, 79 new strings
2006-08-19 11:00:30 +01:00
2010-12-12 20:11:46 +00:00
if ( TileX ( tile ) < = _settings_game . construction . industry_platform + 1U | | TileY ( tile ) < = _settings_game . construction . industry_platform + 1U ) return false ;
(svn r5946) -Add: merged the TGP branch to mainline. TGP adds:
- New optional landscape generator (TerraGenesis Perlin)
- Load heightmaps (either BMP or PNG)
- Progress dialog while generating worlds (no longer a 'hanging' screen)
- New dialogs for NewGame, Create Scenario and Play Heightmap
- Easier to configure your landscape
- More things to configure (tree-placer, ..)
- Speedup of world generation
- New console command 'restart': restart the map EXACTLY as it was when you
first started it (needs a game made after or with this commit)
- New console command 'getseed': get the seed of your map and share it with
others (of course only works with generated maps)
- Many new, world generation related, things
- Many internal cleanups and rewrites
Many tnx to those people who helped making this:
Belugas, DaleStan, glx, KUDr, RichK67, Rubidium, and TrueLight (alfabetic)
Many tnx to those who helped testing:
Arnau, Bjarni, and tokai (alfabetic)
And to all other people who helped testing and sending comments / bugs
Stats: 673 lines changed, 3534 new lines, 79 new strings
2006-08-19 11:00:30 +01:00
/* Check that all tiles in area and surrounding are clear
* this determines that there are no obstructing items */
2010-08-28 19:37:49 +01:00
2010-12-12 20:11:46 +00:00
TileArea ta ( tile + TileDiffXY ( - _settings_game . construction . industry_platform , - _settings_game . construction . industry_platform ) ,
max_x + 2 + 2 * _settings_game . construction . industry_platform , max_y + 2 + 2 * _settings_game . construction . industry_platform ) ;
(svn r5946) -Add: merged the TGP branch to mainline. TGP adds:
- New optional landscape generator (TerraGenesis Perlin)
- Load heightmaps (either BMP or PNG)
- Progress dialog while generating worlds (no longer a 'hanging' screen)
- New dialogs for NewGame, Create Scenario and Play Heightmap
- Easier to configure your landscape
- More things to configure (tree-placer, ..)
- Speedup of world generation
- New console command 'restart': restart the map EXACTLY as it was when you
first started it (needs a game made after or with this commit)
- New console command 'getseed': get the seed of your map and share it with
others (of course only works with generated maps)
- Many new, world generation related, things
- Many internal cleanups and rewrites
Many tnx to those people who helped making this:
Belugas, DaleStan, glx, KUDr, RichK67, Rubidium, and TrueLight (alfabetic)
Many tnx to those who helped testing:
Arnau, Bjarni, and tokai (alfabetic)
And to all other people who helped testing and sending comments / bugs
Stats: 673 lines changed, 3534 new lines, 79 new strings
2006-08-19 11:00:30 +01:00
2010-12-12 20:11:46 +00:00
if ( TileX ( ta . tile ) + ta . w > = MapMaxX ( ) | | TileY ( ta . tile ) + ta . h > = MapMaxY ( ) ) return false ;
(svn r5946) -Add: merged the TGP branch to mainline. TGP adds:
- New optional landscape generator (TerraGenesis Perlin)
- Load heightmaps (either BMP or PNG)
- Progress dialog while generating worlds (no longer a 'hanging' screen)
- New dialogs for NewGame, Create Scenario and Play Heightmap
- Easier to configure your landscape
- More things to configure (tree-placer, ..)
- Speedup of world generation
- New console command 'restart': restart the map EXACTLY as it was when you
first started it (needs a game made after or with this commit)
- New console command 'getseed': get the seed of your map and share it with
others (of course only works with generated maps)
- Many new, world generation related, things
- Many internal cleanups and rewrites
Many tnx to those people who helped making this:
Belugas, DaleStan, glx, KUDr, RichK67, Rubidium, and TrueLight (alfabetic)
Many tnx to those who helped testing:
Arnau, Bjarni, and tokai (alfabetic)
And to all other people who helped testing and sending comments / bugs
Stats: 673 lines changed, 3534 new lines, 79 new strings
2006-08-19 11:00:30 +01:00
2008-09-30 21:39:50 +01:00
/* _current_company is OWNER_NONE for randomly generated industries and in editor, or the company who funded or prospected the industry.
2009-02-11 20:09:29 +00:00
* Perform terraforming as OWNER_TOWN to disable autoslope and town ratings . */
2010-06-05 13:16:12 +01:00
Backup < CompanyByte > cur_company ( _current_company , OWNER_TOWN , FILE_LINE ) ;
2007-09-26 15:32:06 +01:00
2010-12-12 20:11:46 +00:00
TILE_AREA_LOOP ( tile_walk , ta ) {
2010-07-30 11:39:24 +01:00
uint curh = TileHeight ( tile_walk ) ;
(svn r5946) -Add: merged the TGP branch to mainline. TGP adds:
- New optional landscape generator (TerraGenesis Perlin)
- Load heightmaps (either BMP or PNG)
- Progress dialog while generating worlds (no longer a 'hanging' screen)
- New dialogs for NewGame, Create Scenario and Play Heightmap
- Easier to configure your landscape
- More things to configure (tree-placer, ..)
- Speedup of world generation
- New console command 'restart': restart the map EXACTLY as it was when you
first started it (needs a game made after or with this commit)
- New console command 'getseed': get the seed of your map and share it with
others (of course only works with generated maps)
- Many new, world generation related, things
- Many internal cleanups and rewrites
Many tnx to those people who helped making this:
Belugas, DaleStan, glx, KUDr, RichK67, Rubidium, and TrueLight (alfabetic)
Many tnx to those who helped testing:
Arnau, Bjarni, and tokai (alfabetic)
And to all other people who helped testing and sending comments / bugs
Stats: 673 lines changed, 3534 new lines, 79 new strings
2006-08-19 11:00:30 +01:00
if ( curh ! = h ) {
/* This tile needs terraforming. Check if we can do that without
* damaging the surroundings too much . */
2007-09-26 15:32:06 +01:00
if ( ! CheckCanTerraformSurroundingTiles ( tile_walk , h , 0 ) ) {
2010-05-31 21:22:57 +01:00
cur_company . Restore ( ) ;
2007-09-26 15:32:06 +01:00
return false ;
}
(svn r5946) -Add: merged the TGP branch to mainline. TGP adds:
- New optional landscape generator (TerraGenesis Perlin)
- Load heightmaps (either BMP or PNG)
- Progress dialog while generating worlds (no longer a 'hanging' screen)
- New dialogs for NewGame, Create Scenario and Play Heightmap
- Easier to configure your landscape
- More things to configure (tree-placer, ..)
- Speedup of world generation
- New console command 'restart': restart the map EXACTLY as it was when you
first started it (needs a game made after or with this commit)
- New console command 'getseed': get the seed of your map and share it with
others (of course only works with generated maps)
- Many new, world generation related, things
- Many internal cleanups and rewrites
Many tnx to those people who helped making this:
Belugas, DaleStan, glx, KUDr, RichK67, Rubidium, and TrueLight (alfabetic)
Many tnx to those who helped testing:
Arnau, Bjarni, and tokai (alfabetic)
And to all other people who helped testing and sending comments / bugs
Stats: 673 lines changed, 3534 new lines, 79 new strings
2006-08-19 11:00:30 +01:00
/* This is not 100% correct check, but the best we can do without modifying the map.
* What is missing , is if the difference in height is more than 1. . */
2010-01-18 22:57:21 +00:00
if ( DoCommand ( tile_walk , SLOPE_N , ( curh > h ) ? 0 : 1 , flags & ~ DC_EXEC , CMD_TERRAFORM_LAND ) . Failed ( ) ) {
2010-05-31 21:22:57 +01:00
cur_company . Restore ( ) ;
2007-09-26 15:32:06 +01:00
return false ;
}
(svn r5946) -Add: merged the TGP branch to mainline. TGP adds:
- New optional landscape generator (TerraGenesis Perlin)
- Load heightmaps (either BMP or PNG)
- Progress dialog while generating worlds (no longer a 'hanging' screen)
- New dialogs for NewGame, Create Scenario and Play Heightmap
- Easier to configure your landscape
- More things to configure (tree-placer, ..)
- Speedup of world generation
- New console command 'restart': restart the map EXACTLY as it was when you
first started it (needs a game made after or with this commit)
- New console command 'getseed': get the seed of your map and share it with
others (of course only works with generated maps)
- Many new, world generation related, things
- Many internal cleanups and rewrites
Many tnx to those people who helped making this:
Belugas, DaleStan, glx, KUDr, RichK67, Rubidium, and TrueLight (alfabetic)
Many tnx to those who helped testing:
Arnau, Bjarni, and tokai (alfabetic)
And to all other people who helped testing and sending comments / bugs
Stats: 673 lines changed, 3534 new lines, 79 new strings
2006-08-19 11:00:30 +01:00
}
2009-07-26 22:50:30 +01:00
}
(svn r5946) -Add: merged the TGP branch to mainline. TGP adds:
- New optional landscape generator (TerraGenesis Perlin)
- Load heightmaps (either BMP or PNG)
- Progress dialog while generating worlds (no longer a 'hanging' screen)
- New dialogs for NewGame, Create Scenario and Play Heightmap
- Easier to configure your landscape
- More things to configure (tree-placer, ..)
- Speedup of world generation
- New console command 'restart': restart the map EXACTLY as it was when you
first started it (needs a game made after or with this commit)
- New console command 'getseed': get the seed of your map and share it with
others (of course only works with generated maps)
- Many new, world generation related, things
- Many internal cleanups and rewrites
Many tnx to those people who helped making this:
Belugas, DaleStan, glx, KUDr, RichK67, Rubidium, and TrueLight (alfabetic)
Many tnx to those who helped testing:
Arnau, Bjarni, and tokai (alfabetic)
And to all other people who helped testing and sending comments / bugs
Stats: 673 lines changed, 3534 new lines, 79 new strings
2006-08-19 11:00:30 +01:00
if ( flags & DC_EXEC ) {
/* Terraform the land under the industry */
2010-12-12 20:11:46 +00:00
TILE_AREA_LOOP ( tile_walk , ta ) {
2010-07-30 11:39:24 +01:00
uint curh = TileHeight ( tile_walk ) ;
(svn r5946) -Add: merged the TGP branch to mainline. TGP adds:
- New optional landscape generator (TerraGenesis Perlin)
- Load heightmaps (either BMP or PNG)
- Progress dialog while generating worlds (no longer a 'hanging' screen)
- New dialogs for NewGame, Create Scenario and Play Heightmap
- Easier to configure your landscape
- More things to configure (tree-placer, ..)
- Speedup of world generation
- New console command 'restart': restart the map EXACTLY as it was when you
first started it (needs a game made after or with this commit)
- New console command 'getseed': get the seed of your map and share it with
others (of course only works with generated maps)
- Many new, world generation related, things
- Many internal cleanups and rewrites
Many tnx to those people who helped making this:
Belugas, DaleStan, glx, KUDr, RichK67, Rubidium, and TrueLight (alfabetic)
Many tnx to those who helped testing:
Arnau, Bjarni, and tokai (alfabetic)
And to all other people who helped testing and sending comments / bugs
Stats: 673 lines changed, 3534 new lines, 79 new strings
2006-08-19 11:00:30 +01:00
while ( curh ! = h ) {
/* We give the terraforming for free here, because we can't calculate
* exact cost in the test - round , and as we all know , that will cause
* a nice assert if they don ' t match ; ) */
2007-08-27 22:18:04 +01:00
DoCommand ( tile_walk , SLOPE_N , ( curh > h ) ? 0 : 1 , flags , CMD_TERRAFORM_LAND ) ;
(svn r5946) -Add: merged the TGP branch to mainline. TGP adds:
- New optional landscape generator (TerraGenesis Perlin)
- Load heightmaps (either BMP or PNG)
- Progress dialog while generating worlds (no longer a 'hanging' screen)
- New dialogs for NewGame, Create Scenario and Play Heightmap
- Easier to configure your landscape
- More things to configure (tree-placer, ..)
- Speedup of world generation
- New console command 'restart': restart the map EXACTLY as it was when you
first started it (needs a game made after or with this commit)
- New console command 'getseed': get the seed of your map and share it with
others (of course only works with generated maps)
- Many new, world generation related, things
- Many internal cleanups and rewrites
Many tnx to those people who helped making this:
Belugas, DaleStan, glx, KUDr, RichK67, Rubidium, and TrueLight (alfabetic)
Many tnx to those who helped testing:
Arnau, Bjarni, and tokai (alfabetic)
And to all other people who helped testing and sending comments / bugs
Stats: 673 lines changed, 3534 new lines, 79 new strings
2006-08-19 11:00:30 +01:00
curh + = ( curh > h ) ? - 1 : 1 ;
}
2009-07-26 22:50:30 +01:00
}
(svn r5946) -Add: merged the TGP branch to mainline. TGP adds:
- New optional landscape generator (TerraGenesis Perlin)
- Load heightmaps (either BMP or PNG)
- Progress dialog while generating worlds (no longer a 'hanging' screen)
- New dialogs for NewGame, Create Scenario and Play Heightmap
- Easier to configure your landscape
- More things to configure (tree-placer, ..)
- Speedup of world generation
- New console command 'restart': restart the map EXACTLY as it was when you
first started it (needs a game made after or with this commit)
- New console command 'getseed': get the seed of your map and share it with
others (of course only works with generated maps)
- Many new, world generation related, things
- Many internal cleanups and rewrites
Many tnx to those people who helped making this:
Belugas, DaleStan, glx, KUDr, RichK67, Rubidium, and TrueLight (alfabetic)
Many tnx to those who helped testing:
Arnau, Bjarni, and tokai (alfabetic)
And to all other people who helped testing and sending comments / bugs
Stats: 673 lines changed, 3534 new lines, 79 new strings
2006-08-19 11:00:30 +01:00
}
2010-05-31 21:22:57 +01:00
cur_company . Restore ( ) ;
(svn r5946) -Add: merged the TGP branch to mainline. TGP adds:
- New optional landscape generator (TerraGenesis Perlin)
- Load heightmaps (either BMP or PNG)
- Progress dialog while generating worlds (no longer a 'hanging' screen)
- New dialogs for NewGame, Create Scenario and Play Heightmap
- Easier to configure your landscape
- More things to configure (tree-placer, ..)
- Speedup of world generation
- New console command 'restart': restart the map EXACTLY as it was when you
first started it (needs a game made after or with this commit)
- New console command 'getseed': get the seed of your map and share it with
others (of course only works with generated maps)
- Many new, world generation related, things
- Many internal cleanups and rewrites
Many tnx to those people who helped making this:
Belugas, DaleStan, glx, KUDr, RichK67, Rubidium, and TrueLight (alfabetic)
Many tnx to those who helped testing:
Arnau, Bjarni, and tokai (alfabetic)
And to all other people who helped testing and sending comments / bugs
Stats: 673 lines changed, 3534 new lines, 79 new strings
2006-08-19 11:00:30 +01:00
return true ;
}
2010-08-01 20:22:34 +01:00
/**
* Check that the new industry is far enough from conflicting industries .
2010-02-21 13:32:14 +00:00
* @ param tile Tile to construct the industry .
* @ param type Type of the new industry .
* @ return Succeeded or failed command .
*/
2010-03-21 15:16:05 +00:00
static CommandCost CheckIfFarEnoughFromConflictingIndustry ( TileIndex tile , int type )
2004-08-09 18:04:08 +01:00
{
2006-04-26 22:10:01 +01:00
const IndustrySpec * indspec = GetIndustrySpec ( type ) ;
2010-03-19 21:23:54 +00:00
const Industry * i ;
2004-12-30 10:03:35 +00:00
FOR_ALL_INDUSTRIES ( i ) {
2008-01-09 18:35:18 +00:00
/* Within 14 tiles from another industry is considered close */
2010-03-19 21:23:54 +00:00
if ( DistanceMax ( tile , i - > location . tile ) > 14 ) continue ;
2008-01-09 18:35:18 +00:00
/* check if there are any conflicting industry types around */
2010-03-19 21:23:54 +00:00
if ( i - > type = = indspec - > conflicting [ 0 ] | |
2008-01-09 18:35:18 +00:00
i - > type = = indspec - > conflicting [ 1 ] | |
2010-03-19 21:23:54 +00:00
i - > type = = indspec - > conflicting [ 2 ] ) {
2010-02-21 13:32:14 +00:00
return_cmd_error ( STR_ERROR_INDUSTRY_TOO_CLOSE ) ;
2004-08-09 18:04:08 +01:00
}
}
2010-02-21 13:32:14 +00:00
return CommandCost ( ) ;
2004-08-09 18:04:08 +01:00
}
2010-03-01 19:34:04 +00:00
/**
* Put an industry on the map .
* @ param i Just allocated poolitem , mostly empty .
* @ param tile North tile of the industry .
* @ param type Type of the industry .
* @ param it Industrylayout to build .
* @ param layout Number of the layout .
* @ param t Nearest town .
* @ param founder Founder of the industry ; OWNER_NONE in case of random construction .
2010-05-01 14:09:49 +01:00
* @ param initial_random_bits Random bits for the industry .
2010-03-01 19:34:04 +00:00
*/
2010-05-01 14:09:49 +01:00
static void DoCreateNewIndustry ( Industry * i , TileIndex tile , IndustryType type , const IndustryTileTable * it , byte layout , const Town * t , Owner founder , uint16 initial_random_bits )
2004-08-09 18:04:08 +01:00
{
2006-04-26 22:10:01 +01:00
const IndustrySpec * indspec = GetIndustrySpec ( type ) ;
2004-08-09 18:04:08 +01:00
2010-01-04 18:21:07 +00:00
i - > location = TileArea ( tile , 1 , 1 ) ;
2004-08-09 18:04:08 +01:00
i - > type = type ;
2010-03-20 14:30:16 +00:00
Industry : : IncIndustryTypeCount ( type ) ;
2004-08-09 18:04:08 +01:00
2007-09-27 22:39:13 +01:00
i - > produced_cargo [ 0 ] = indspec - > produced_cargo [ 0 ] ;
i - > produced_cargo [ 1 ] = indspec - > produced_cargo [ 1 ] ;
i - > accepts_cargo [ 0 ] = indspec - > accepts_cargo [ 0 ] ;
i - > accepts_cargo [ 1 ] = indspec - > accepts_cargo [ 1 ] ;
i - > accepts_cargo [ 2 ] = indspec - > accepts_cargo [ 2 ] ;
2006-04-26 22:10:01 +01:00
i - > production_rate [ 0 ] = indspec - > production_rate [ 0 ] ;
i - > production_rate [ 1 ] = indspec - > production_rate [ 1 ] ;
2004-08-09 18:04:08 +01:00
2007-11-23 16:50:54 +00:00
/* don't use smooth economy for industries using production related callbacks */
2010-09-26 12:04:30 +01:00
if ( indspec - > UsesSmoothEconomy ( ) ) {
2009-10-02 16:13:15 +01:00
i - > production_rate [ 0 ] = min ( ( RandomRange ( 256 ) + 128 ) * i - > production_rate [ 0 ] > > 8 , 255 ) ;
i - > production_rate [ 1 ] = min ( ( RandomRange ( 256 ) + 128 ) * i - > production_rate [ 1 ] > > 8 , 255 ) ;
2004-08-09 18:04:08 +01:00
}
i - > town = t ;
2010-03-01 19:34:04 +00:00
i - > owner = OWNER_NONE ;
2004-08-09 18:04:08 +01:00
2010-05-01 14:09:49 +01:00
uint16 r = Random ( ) ;
2009-02-09 02:57:15 +00:00
i - > random_colour = GB ( r , 0 , 4 ) ;
2007-11-11 18:22:06 +00:00
i - > counter = GB ( r , 4 , 12 ) ;
2010-05-01 14:09:49 +01:00
i - > random = initial_random_bits ;
2007-07-04 19:27:21 +01:00
i - > produced_cargo_waiting [ 0 ] = 0 ;
i - > produced_cargo_waiting [ 1 ] = 0 ;
i - > incoming_cargo_waiting [ 0 ] = 0 ;
i - > incoming_cargo_waiting [ 1 ] = 0 ;
i - > incoming_cargo_waiting [ 2 ] = 0 ;
2007-06-07 15:38:45 +01:00
i - > this_month_production [ 0 ] = 0 ;
i - > this_month_production [ 1 ] = 0 ;
i - > this_month_transported [ 0 ] = 0 ;
i - > this_month_transported [ 1 ] = 0 ;
i - > last_month_pct_transported [ 0 ] = 0 ;
i - > last_month_pct_transported [ 1 ] = 0 ;
i - > last_month_transported [ 0 ] = 0 ;
i - > last_month_transported [ 1 ] = 0 ;
2004-08-09 18:04:08 +01:00
i - > was_cargo_delivered = false ;
2006-08-20 20:05:28 +01:00
i - > last_prod_year = _cur_year ;
2007-06-07 15:38:45 +01:00
i - > last_month_production [ 0 ] = i - > production_rate [ 0 ] * 8 ;
i - > last_month_production [ 1 ] = i - > production_rate [ 1 ] * 8 ;
2009-02-11 20:09:29 +00:00
i - > founder = founder ;
2007-09-27 22:47:38 +01:00
2010-05-30 13:26:32 +01:00
i - > construction_date = _date ;
i - > construction_type = ( _game_mode = = GM_EDITOR ) ? ICT_SCENARIO_EDITOR :
( _generating_world ? ICT_MAP_GENERATION : ICT_NORMAL_GAMEPLAY ) ;
/* Adding 1 here makes it conform to specs of var44 of varaction2 for industries
* 0 = created prior of newindustries
* else , chosen layout + 1 */
i - > selected_layout = layout + 1 ;
if ( ! _generating_world ) i - > last_month_production [ 0 ] = i - > last_month_production [ 1 ] = 0 ;
i - > prod_level = PRODLEVEL_DEFAULT ;
/* Call callbacks after the regular fields got initialised. */
2009-09-14 13:22:57 +01:00
if ( HasBit ( indspec - > callback_mask , CBM_IND_DECIDE_COLOUR ) ) {
2007-09-28 18:09:50 +01:00
uint16 res = GetIndustryCallback ( CBID_INDUSTRY_DECIDE_COLOUR , 0 , 0 , i , type , INVALID_TILE ) ;
2009-02-09 02:57:15 +00:00
if ( res ! = CALLBACK_FAILED ) i - > random_colour = GB ( res , 0 , 4 ) ;
2007-09-28 18:09:50 +01:00
}
2009-09-14 13:22:57 +01:00
if ( HasBit ( indspec - > callback_mask , CBM_IND_INPUT_CARGO_TYPES ) ) {
2010-03-01 19:34:04 +00:00
for ( uint j = 0 ; j < lengthof ( i - > accepts_cargo ) ; j + + ) i - > accepts_cargo [ j ] = CT_INVALID ;
for ( uint j = 0 ; j < lengthof ( i - > accepts_cargo ) ; j + + ) {
2007-09-27 22:47:38 +01:00
uint16 res = GetIndustryCallback ( CBID_INDUSTRY_INPUT_CARGO_TYPES , j , 0 , i , type , INVALID_TILE ) ;
if ( res = = CALLBACK_FAILED | | GB ( res , 0 , 8 ) = = CT_INVALID ) break ;
i - > accepts_cargo [ j ] = GetCargoTranslation ( GB ( res , 0 , 8 ) , indspec - > grf_prop . grffile ) ;
}
}
2009-09-14 13:22:57 +01:00
if ( HasBit ( indspec - > callback_mask , CBM_IND_OUTPUT_CARGO_TYPES ) ) {
2010-03-01 19:34:04 +00:00
for ( uint j = 0 ; j < lengthof ( i - > produced_cargo ) ; j + + ) i - > produced_cargo [ j ] = CT_INVALID ;
for ( uint j = 0 ; j < lengthof ( i - > produced_cargo ) ; j + + ) {
2007-09-27 22:47:38 +01:00
uint16 res = GetIndustryCallback ( CBID_INDUSTRY_OUTPUT_CARGO_TYPES , j , 0 , i , type , INVALID_TILE ) ;
if ( res = = CALLBACK_FAILED | | GB ( res , 0 , 8 ) = = CT_INVALID ) break ;
i - > produced_cargo [ j ] = GetCargoTranslation ( GB ( res , 0 , 8 ) , indspec - > grf_prop . grffile ) ;
}
}
2010-05-30 13:26:32 +01:00
/* Plant the tiles */
2004-08-09 18:04:08 +01:00
do {
2005-06-24 13:38:35 +01:00
TileIndex cur_tile = tile + ToTileIndexDiff ( it - > ti ) ;
2004-08-09 18:04:08 +01:00
2007-08-26 01:23:32 +01:00
if ( it - > gfx ! = GFX_WATERTILE_SPECIALCHECK ) {
2010-01-04 18:21:07 +00:00
i - > location . Add ( cur_tile ) ;
2004-08-09 18:04:08 +01:00
2008-07-26 17:14:10 +01:00
WaterClass wc = ( IsWaterTile ( cur_tile ) ? GetWaterClass ( cur_tile ) : WATER_CLASS_INVALID ) ;
2009-02-11 20:09:29 +00:00
DoCommand ( cur_tile , 0 , 0 , DC_EXEC | DC_NO_TEST_TOWN_RATING | DC_NO_MODIFY_TOWN_RATING , CMD_LANDSCAPE_CLEAR ) ;
2004-08-09 18:04:08 +01:00
2008-07-26 17:14:10 +01:00
MakeIndustry ( cur_tile , i - > index , it - > gfx , Random ( ) , wc ) ;
2007-11-11 00:53:59 +00:00
2006-12-30 11:51:37 +00:00
if ( _generating_world ) {
SetIndustryConstructionCounter ( cur_tile , 3 ) ;
SetIndustryConstructionStage ( cur_tile , 2 ) ;
2007-11-11 18:22:06 +00:00
}
2008-01-16 15:06:48 +00:00
/* it->gfx is stored in the map. But the translated ID cur_gfx is the interesting one */
IndustryGfx cur_gfx = GetTranslatedIndustryTileID ( it - > gfx ) ;
const IndustryTileSpec * its = GetIndustryTileSpec ( cur_gfx ) ;
2010-08-26 16:31:40 +01:00
if ( its - > animation . status ! = ANIM_STATUS_NO_ANIMATION ) AddAnimatedTile ( cur_tile ) ;
2004-08-09 18:04:08 +01:00
}
2005-01-06 11:39:00 +00:00
} while ( ( + + it ) - > ti . x ! = - 0x80 ) ;
2004-08-09 18:04:08 +01:00
2007-03-28 21:06:28 +01:00
if ( GetIndustrySpec ( i - > type ) - > behaviour & INDUSTRYBEH_PLANT_ON_BUILT ) {
2010-03-01 19:34:04 +00:00
for ( uint j = 0 ; j ! = 50 ; j + + ) PlantRandomFarmField ( i ) ;
2004-08-09 18:04:08 +01:00
}
2008-05-19 00:36:33 +01:00
InvalidateWindowData ( WC_INDUSTRY_DIRECTORY , 0 , 0 ) ;
2009-06-25 16:42:03 +01:00
Station : : RecomputeIndustriesNearForAll ( ) ;
2004-08-09 18:04:08 +01:00
}
2010-08-01 20:22:34 +01:00
/**
* Helper function for Build / Fund an industry
2007-03-03 04:04:22 +00:00
* @ param tile tile where industry is built
* @ param type of industry to build
* @ param flags of operations to conduct
* @ param indspec pointer to industry specifications
2007-07-09 14:21:49 +01:00
* @ param itspec_index the index of the itsepc to build / fund
2008-01-29 00:36:55 +00:00
* @ param seed random seed ( possibly ) used by industries
2010-05-01 14:09:49 +01:00
* @ param initial_random_bits The random bits the industry is going to have after construction .
2009-02-11 20:09:29 +00:00
* @ param founder Founder of the industry
2010-10-16 14:15:54 +01:00
* @ param creation_type The circumstances the industry is created under .
2010-08-02 21:47:27 +01:00
* @ param [ out ] ip Pointer to store newly created industry .
2010-02-27 12:12:01 +00:00
* @ return Succeeded or failed command .
*
* @ post \ c * ip contains the newly created industry if all checks are successful and the \ a flags request actual creation , else it contains \ c NULL afterwards .
2007-03-03 04:04:22 +00:00
*/
2010-10-16 14:15:54 +01:00
static CommandCost CreateNewIndustryHelper ( TileIndex tile , IndustryType type , DoCommandFlag flags , const IndustrySpec * indspec , uint itspec_index , uint32 random_var8f , uint16 random_initial_bits , Owner founder , IndustryAvailabilityCallType creation_type , Industry * * ip )
(svn r5946) -Add: merged the TGP branch to mainline. TGP adds:
- New optional landscape generator (TerraGenesis Perlin)
- Load heightmaps (either BMP or PNG)
- Progress dialog while generating worlds (no longer a 'hanging' screen)
- New dialogs for NewGame, Create Scenario and Play Heightmap
- Easier to configure your landscape
- More things to configure (tree-placer, ..)
- Speedup of world generation
- New console command 'restart': restart the map EXACTLY as it was when you
first started it (needs a game made after or with this commit)
- New console command 'getseed': get the seed of your map and share it with
others (of course only works with generated maps)
- Many new, world generation related, things
- Many internal cleanups and rewrites
Many tnx to those people who helped making this:
Belugas, DaleStan, glx, KUDr, RichK67, Rubidium, and TrueLight (alfabetic)
Many tnx to those who helped testing:
Arnau, Bjarni, and tokai (alfabetic)
And to all other people who helped testing and sending comments / bugs
Stats: 673 lines changed, 3534 new lines, 79 new strings
2006-08-19 11:00:30 +01:00
{
2009-09-25 10:32:20 +01:00
assert ( itspec_index < indspec - > num_table ) ;
2007-07-09 14:21:49 +01:00
const IndustryTileTable * it = indspec - > table [ itspec_index ] ;
2007-07-09 19:53:43 +01:00
bool custom_shape_check = false ;
2010-02-27 12:12:01 +00:00
* ip = NULL ;
2010-09-05 14:31:39 +01:00
SmallVector < ClearedObjectArea , 1 > object_areas ( _cleared_object_areas ) ;
2010-10-16 14:15:54 +01:00
CommandCost ret = CheckIfIndustryTilesAreFree ( tile , it , itspec_index , type , random_initial_bits , founder , creation_type , & custom_shape_check ) ;
2010-09-04 01:16:33 +01:00
_cleared_object_areas = object_areas ;
2010-02-27 12:12:01 +00:00
if ( ret . Failed ( ) ) return ret ;
2007-07-09 19:53:43 +01:00
2009-09-14 13:22:57 +01:00
if ( HasBit ( GetIndustrySpec ( type ) - > callback_mask , CBM_IND_LOCATION ) ) {
2010-10-16 14:15:54 +01:00
ret = CheckIfCallBackAllowsCreation ( tile , type , itspec_index , random_var8f , random_initial_bits , founder , creation_type ) ;
2007-07-09 19:53:43 +01:00
} else {
2010-02-21 15:27:11 +00:00
ret = _check_new_industry_procs [ indspec - > check_proc ] ( tile ) ;
2007-07-09 14:21:49 +01:00
}
2010-02-27 12:12:01 +00:00
if ( ret . Failed ( ) ) return ret ;
if ( ! custom_shape_check & & _settings_game . game_creation . land_generator = = LG_TERRAGENESIS & & _generating_world & &
! _ignore_restrictions & & ! CheckIfCanLevelIndustryPlatform ( tile , DC_NO_WATER , it , type ) ) {
return_cmd_error ( STR_ERROR_SITE_UNSUITABLE ) ;
}
(svn r5946) -Add: merged the TGP branch to mainline. TGP adds:
- New optional landscape generator (TerraGenesis Perlin)
- Load heightmaps (either BMP or PNG)
- Progress dialog while generating worlds (no longer a 'hanging' screen)
- New dialogs for NewGame, Create Scenario and Play Heightmap
- Easier to configure your landscape
- More things to configure (tree-placer, ..)
- Speedup of world generation
- New console command 'restart': restart the map EXACTLY as it was when you
first started it (needs a game made after or with this commit)
- New console command 'getseed': get the seed of your map and share it with
others (of course only works with generated maps)
- Many new, world generation related, things
- Many internal cleanups and rewrites
Many tnx to those people who helped making this:
Belugas, DaleStan, glx, KUDr, RichK67, Rubidium, and TrueLight (alfabetic)
Many tnx to those who helped testing:
Arnau, Bjarni, and tokai (alfabetic)
And to all other people who helped testing and sending comments / bugs
Stats: 673 lines changed, 3534 new lines, 79 new strings
2006-08-19 11:00:30 +01:00
2010-03-21 15:16:05 +00:00
ret = CheckIfFarEnoughFromConflictingIndustry ( tile , type ) ;
2010-02-27 12:12:01 +00:00
if ( ret . Failed ( ) ) return ret ;
(svn r5946) -Add: merged the TGP branch to mainline. TGP adds:
- New optional landscape generator (TerraGenesis Perlin)
- Load heightmaps (either BMP or PNG)
- Progress dialog while generating worlds (no longer a 'hanging' screen)
- New dialogs for NewGame, Create Scenario and Play Heightmap
- Easier to configure your landscape
- More things to configure (tree-placer, ..)
- Speedup of world generation
- New console command 'restart': restart the map EXACTLY as it was when you
first started it (needs a game made after or with this commit)
- New console command 'getseed': get the seed of your map and share it with
others (of course only works with generated maps)
- Many new, world generation related, things
- Many internal cleanups and rewrites
Many tnx to those people who helped making this:
Belugas, DaleStan, glx, KUDr, RichK67, Rubidium, and TrueLight (alfabetic)
Many tnx to those who helped testing:
Arnau, Bjarni, and tokai (alfabetic)
And to all other people who helped testing and sending comments / bugs
Stats: 673 lines changed, 3534 new lines, 79 new strings
2006-08-19 11:00:30 +01:00
2010-02-21 14:57:27 +00:00
const Town * t = NULL ;
ret = FindTownForIndustry ( tile , type , & t ) ;
2010-02-27 12:12:01 +00:00
if ( ret . Failed ( ) ) return ret ;
2010-02-21 14:57:27 +00:00
assert ( t ! = NULL ) ;
(svn r5946) -Add: merged the TGP branch to mainline. TGP adds:
- New optional landscape generator (TerraGenesis Perlin)
- Load heightmaps (either BMP or PNG)
- Progress dialog while generating worlds (no longer a 'hanging' screen)
- New dialogs for NewGame, Create Scenario and Play Heightmap
- Easier to configure your landscape
- More things to configure (tree-placer, ..)
- Speedup of world generation
- New console command 'restart': restart the map EXACTLY as it was when you
first started it (needs a game made after or with this commit)
- New console command 'getseed': get the seed of your map and share it with
others (of course only works with generated maps)
- Many new, world generation related, things
- Many internal cleanups and rewrites
Many tnx to those people who helped making this:
Belugas, DaleStan, glx, KUDr, RichK67, Rubidium, and TrueLight (alfabetic)
Many tnx to those who helped testing:
Arnau, Bjarni, and tokai (alfabetic)
And to all other people who helped testing and sending comments / bugs
Stats: 673 lines changed, 3534 new lines, 79 new strings
2006-08-19 11:00:30 +01:00
2010-02-21 13:32:14 +00:00
ret = CheckIfIndustryIsAllowed ( tile , type , t ) ;
2010-02-27 12:12:01 +00:00
if ( ret . Failed ( ) ) return ret ;
(svn r5946) -Add: merged the TGP branch to mainline. TGP adds:
- New optional landscape generator (TerraGenesis Perlin)
- Load heightmaps (either BMP or PNG)
- Progress dialog while generating worlds (no longer a 'hanging' screen)
- New dialogs for NewGame, Create Scenario and Play Heightmap
- Easier to configure your landscape
- More things to configure (tree-placer, ..)
- Speedup of world generation
- New console command 'restart': restart the map EXACTLY as it was when you
first started it (needs a game made after or with this commit)
- New console command 'getseed': get the seed of your map and share it with
others (of course only works with generated maps)
- Many new, world generation related, things
- Many internal cleanups and rewrites
Many tnx to those people who helped making this:
Belugas, DaleStan, glx, KUDr, RichK67, Rubidium, and TrueLight (alfabetic)
Many tnx to those who helped testing:
Arnau, Bjarni, and tokai (alfabetic)
And to all other people who helped testing and sending comments / bugs
Stats: 673 lines changed, 3534 new lines, 79 new strings
2006-08-19 11:00:30 +01:00
2010-02-27 12:12:01 +00:00
if ( ! Industry : : CanAllocateItem ( ) ) return_cmd_error ( STR_ERROR_TOO_MANY_INDUSTRIES ) ;
(svn r5946) -Add: merged the TGP branch to mainline. TGP adds:
- New optional landscape generator (TerraGenesis Perlin)
- Load heightmaps (either BMP or PNG)
- Progress dialog while generating worlds (no longer a 'hanging' screen)
- New dialogs for NewGame, Create Scenario and Play Heightmap
- Easier to configure your landscape
- More things to configure (tree-placer, ..)
- Speedup of world generation
- New console command 'restart': restart the map EXACTLY as it was when you
first started it (needs a game made after or with this commit)
- New console command 'getseed': get the seed of your map and share it with
others (of course only works with generated maps)
- Many new, world generation related, things
- Many internal cleanups and rewrites
Many tnx to those people who helped making this:
Belugas, DaleStan, glx, KUDr, RichK67, Rubidium, and TrueLight (alfabetic)
Many tnx to those who helped testing:
Arnau, Bjarni, and tokai (alfabetic)
And to all other people who helped testing and sending comments / bugs
Stats: 673 lines changed, 3534 new lines, 79 new strings
2006-08-19 11:00:30 +01:00
if ( flags & DC_EXEC ) {
2010-02-27 12:12:01 +00:00
* ip = new Industry ( tile ) ;
2009-12-19 22:17:02 +00:00
if ( ! custom_shape_check ) CheckIfCanLevelIndustryPlatform ( tile , DC_NO_WATER | DC_EXEC , it , type ) ;
2010-05-01 14:09:49 +01:00
DoCreateNewIndustry ( * ip , tile , type , it , itspec_index , t , founder , random_initial_bits ) ;
(svn r5946) -Add: merged the TGP branch to mainline. TGP adds:
- New optional landscape generator (TerraGenesis Perlin)
- Load heightmaps (either BMP or PNG)
- Progress dialog while generating worlds (no longer a 'hanging' screen)
- New dialogs for NewGame, Create Scenario and Play Heightmap
- Easier to configure your landscape
- More things to configure (tree-placer, ..)
- Speedup of world generation
- New console command 'restart': restart the map EXACTLY as it was when you
first started it (needs a game made after or with this commit)
- New console command 'getseed': get the seed of your map and share it with
others (of course only works with generated maps)
- Many new, world generation related, things
- Many internal cleanups and rewrites
Many tnx to those people who helped making this:
Belugas, DaleStan, glx, KUDr, RichK67, Rubidium, and TrueLight (alfabetic)
Many tnx to those who helped testing:
Arnau, Bjarni, and tokai (alfabetic)
And to all other people who helped testing and sending comments / bugs
Stats: 673 lines changed, 3534 new lines, 79 new strings
2006-08-19 11:00:30 +01:00
}
2010-02-27 12:12:01 +00:00
return CommandCost ( ) ;
(svn r5946) -Add: merged the TGP branch to mainline. TGP adds:
- New optional landscape generator (TerraGenesis Perlin)
- Load heightmaps (either BMP or PNG)
- Progress dialog while generating worlds (no longer a 'hanging' screen)
- New dialogs for NewGame, Create Scenario and Play Heightmap
- Easier to configure your landscape
- More things to configure (tree-placer, ..)
- Speedup of world generation
- New console command 'restart': restart the map EXACTLY as it was when you
first started it (needs a game made after or with this commit)
- New console command 'getseed': get the seed of your map and share it with
others (of course only works with generated maps)
- Many new, world generation related, things
- Many internal cleanups and rewrites
Many tnx to those people who helped making this:
Belugas, DaleStan, glx, KUDr, RichK67, Rubidium, and TrueLight (alfabetic)
Many tnx to those who helped testing:
Arnau, Bjarni, and tokai (alfabetic)
And to all other people who helped testing and sending comments / bugs
Stats: 673 lines changed, 3534 new lines, 79 new strings
2006-08-19 11:00:30 +01:00
}
2010-08-01 20:22:34 +01:00
/**
* Build / Fund an industry
2006-04-10 08:15:58 +01:00
* @ param tile tile where industry is built
2007-03-03 04:04:22 +00:00
* @ param flags of operations to conduct
2008-01-29 00:36:55 +00:00
* @ param p1 various bitstuffed elements
2009-09-04 21:04:54 +01:00
* - p1 = ( bit 0 - 7 ) - industry type see build_industry . h and see industry . h
* - p1 = ( bit 8 - 15 ) - first layout to try
2010-05-01 14:09:49 +01:00
* @ param p2 seed to use for desyncfree randomisations
2009-09-18 15:23:58 +01:00
* @ param text unused
* @ return the cost of this operation or an error
2005-05-11 01:00:27 +01:00
*/
2009-02-09 21:20:05 +00:00
CommandCost CmdBuildIndustry ( TileIndex tile , DoCommandFlag flags , uint32 p1 , uint32 p2 , const char * text )
2004-08-09 18:04:08 +01:00
{
2009-09-04 21:04:54 +01:00
IndustryType it = GB ( p1 , 0 , 8 ) ;
2009-09-04 21:02:35 +01:00
if ( it > = NUM_INDUSTRYTYPES ) return CMD_ERROR ;
const IndustrySpec * indspec = GetIndustrySpec ( it ) ;
2005-11-14 19:48:04 +00:00
2006-10-27 16:54:24 +01:00
/* Check if the to-be built/founded industry is available for this climate. */
2009-09-25 10:32:20 +01:00
if ( ! indspec - > enabled | | indspec - > num_table = = 0 ) return CMD_ERROR ;
2004-08-09 18:04:08 +01:00
2009-02-08 12:25:13 +00:00
/* If the setting for raw-material industries is not on, you cannot build raw-material industries.
2007-07-06 23:33:16 +01:00
* Raw material industries are industries that do not accept cargo ( at least for now ) */
2008-05-29 16:13:28 +01:00
if ( _game_mode ! = GM_EDITOR & & _settings_game . construction . raw_industry_construction = = 0 & & indspec - > IsRawIndustry ( ) ) {
2005-11-14 15:22:12 +00:00
return CMD_ERROR ;
}
2004-08-09 18:04:08 +01:00
2010-04-23 22:47:03 +01:00
if ( _game_mode ! = GM_EDITOR & & ! CheckIfCallBackAllowsAvailability ( it , IACT_USERCREATION ) ) {
return CMD_ERROR ;
}
2010-05-01 14:09:49 +01:00
Randomizer randomizer ;
randomizer . SetSeed ( p2 ) ;
uint16 random_initial_bits = GB ( p2 , 0 , 16 ) ;
uint32 random_var8f = randomizer . Next ( ) ;
2010-02-27 12:12:01 +00:00
Industry * ind = NULL ;
2008-05-29 16:13:28 +01:00
if ( _game_mode ! = GM_EDITOR & & _settings_game . construction . raw_industry_construction = = 2 & & indspec - > IsRawIndustry ( ) ) {
2007-07-06 08:24:10 +01:00
if ( flags & DC_EXEC ) {
2009-02-11 20:09:29 +00:00
/* Prospected industries are build as OWNER_TOWN to not e.g. be build on owned land of the founder */
2010-06-05 13:16:12 +01:00
Backup < CompanyByte > cur_company ( _current_company , OWNER_TOWN , FILE_LINE ) ;
2007-07-06 08:24:10 +01:00
/* Prospecting has a chance to fail, however we cannot guarantee that something can
* be built on the map , so the chance gets lower when the map is fuller , but there
* is nothing we can really do about that . */
if ( Random ( ) < = indspec - > prospecting_chance ) {
for ( int i = 0 ; i < 5000 ; i + + ) {
2007-12-28 16:21:29 +00:00
/* We should not have more than one Random() in a function call
* because parameter evaluation order is not guaranteed in the c + + standard
*/
tile = RandomTile ( ) ;
2010-10-16 14:15:54 +01:00
CommandCost ret = CreateNewIndustryHelper ( tile , it , flags , indspec , RandomRange ( indspec - > num_table ) , random_var8f , random_initial_bits , cur_company . GetOriginalValue ( ) , IACT_PROSPECTCREATION , & ind ) ;
2010-02-27 12:12:01 +00:00
if ( ret . Succeeded ( ) ) break ;
2007-07-06 08:24:10 +01:00
}
}
2010-05-31 21:22:57 +01:00
cur_company . Restore ( ) ;
2007-07-06 08:24:10 +01:00
}
} else {
2007-10-20 01:20:23 +01:00
int count = indspec - > num_table ;
const IndustryTileTable * const * itt = indspec - > table ;
2009-09-04 21:04:54 +01:00
int num = GB ( p1 , 8 , 8 ) ;
2009-09-04 21:02:35 +01:00
if ( num > = count ) return CMD_ERROR ;
2007-07-06 08:24:10 +01:00
2010-02-21 15:27:11 +00:00
CommandCost ret = CommandCost ( STR_ERROR_SITE_UNSUITABLE ) ;
2010-09-05 14:31:39 +01:00
SmallVector < ClearedObjectArea , 1 > object_areas ( _cleared_object_areas ) ;
2007-07-06 08:24:10 +01:00
do {
2010-02-21 15:27:11 +00:00
if ( - - count < 0 ) return ret ;
2007-10-20 01:20:23 +01:00
if ( - - num < 0 ) num = indspec - > num_table - 1 ;
2010-10-16 14:15:54 +01:00
ret = CheckIfIndustryTilesAreFree ( tile , itt [ num ] , num , it , random_initial_bits , _current_company , IACT_USERCREATION ) ;
2010-09-04 01:16:33 +01:00
_cleared_object_areas = object_areas ;
2010-02-21 15:27:11 +00:00
} while ( ret . Failed ( ) ) ;
2004-08-09 18:04:08 +01:00
2010-10-16 14:15:54 +01:00
ret = CreateNewIndustryHelper ( tile , it , flags , indspec , num , random_var8f , random_initial_bits , _current_company , IACT_USERCREATION , & ind ) ;
2010-02-27 12:12:01 +00:00
if ( ret . Failed ( ) ) return ret ;
2008-07-29 00:37:19 +01:00
}
2010-03-07 12:20:17 +00:00
if ( ( flags & DC_EXEC ) & & ind ! = NULL & & _game_mode ! = GM_EDITOR ) {
/* Created a new industry in-game, advertise the event. */
SetDParam ( 0 , indspec - > name ) ;
if ( indspec - > new_industry_text > STR_LAST_STRINGID ) {
SetDParam ( 1 , STR_TOWN_NAME ) ;
SetDParam ( 2 , ind - > town - > index ) ;
} else {
SetDParam ( 1 , ind - > town - > index ) ;
2008-07-29 00:37:19 +01:00
}
2010-03-07 12:20:17 +00:00
AddIndustryNewsItem ( indspec - > new_industry_text , NS_INDUSTRY_OPEN , ind - > index ) ;
AI : : BroadcastNewEvent ( new AIEventIndustryOpen ( ind - > index ) ) ;
2007-07-06 08:24:10 +01:00
}
2004-09-11 10:55:19 +01:00
2008-01-09 16:55:48 +00:00
return CommandCost ( EXPENSES_OTHER , indspec - > GetConstructionCost ( ) ) ;
2004-08-09 18:04:08 +01:00
}
2010-10-16 14:15:54 +01:00
/**
* Create a new industry of random layout .
* @ param tile The location to build the industry .
* @ param type The industry type to build .
* @ param creation_type The circumstances the industry is created under .
* @ return the created industry or NULL if it failed .
*/
static Industry * CreateNewIndustry ( TileIndex tile , IndustryType type , IndustryAvailabilityCallType creation_type )
2004-08-09 18:04:08 +01:00
{
(svn r5946) -Add: merged the TGP branch to mainline. TGP adds:
- New optional landscape generator (TerraGenesis Perlin)
- Load heightmaps (either BMP or PNG)
- Progress dialog while generating worlds (no longer a 'hanging' screen)
- New dialogs for NewGame, Create Scenario and Play Heightmap
- Easier to configure your landscape
- More things to configure (tree-placer, ..)
- Speedup of world generation
- New console command 'restart': restart the map EXACTLY as it was when you
first started it (needs a game made after or with this commit)
- New console command 'getseed': get the seed of your map and share it with
others (of course only works with generated maps)
- Many new, world generation related, things
- Many internal cleanups and rewrites
Many tnx to those people who helped making this:
Belugas, DaleStan, glx, KUDr, RichK67, Rubidium, and TrueLight (alfabetic)
Many tnx to those who helped testing:
Arnau, Bjarni, and tokai (alfabetic)
And to all other people who helped testing and sending comments / bugs
Stats: 673 lines changed, 3534 new lines, 79 new strings
2006-08-19 11:00:30 +01:00
const IndustrySpec * indspec = GetIndustrySpec ( type ) ;
2004-09-11 10:55:19 +01:00
2008-01-29 00:36:55 +00:00
uint32 seed = Random ( ) ;
2010-05-01 14:09:49 +01:00
uint32 seed2 = Random ( ) ;
2010-02-27 12:12:01 +00:00
Industry * i = NULL ;
2010-10-16 14:15:54 +01:00
CommandCost ret = CreateNewIndustryHelper ( tile , type , DC_EXEC , indspec , RandomRange ( indspec - > num_table ) , seed , GB ( seed2 , 0 , 16 ) , OWNER_NONE , creation_type , & i ) ;
2010-02-27 12:12:01 +00:00
assert ( i ! = NULL | | ret . Failed ( ) ) ;
return i ;
2004-08-09 18:04:08 +01:00
}
2010-02-13 14:06:01 +00:00
/**
* Compute the appearance probability for an industry during map creation .
2010-09-04 12:16:40 +01:00
* @ param it Industry type to compute .
* @ param [ out ] force_at_least_one Returns whether at least one instance should be forced on map creation .
* @ return Relative probability for the industry to appear .
2010-02-13 14:06:01 +00:00
*/
2010-09-04 12:16:40 +01:00
static uint32 GetScaledIndustryGenerationProbability ( IndustryType it , bool * force_at_least_one )
2010-02-13 14:06:01 +00:00
{
const IndustrySpec * ind_spc = GetIndustrySpec ( it ) ;
uint32 chance = ind_spc - > appear_creation [ _settings_game . game_creation . landscape ] * 16 ; // * 16 to increase precision
if ( ! ind_spc - > enabled | | chance = = 0 | | ind_spc - > num_table = = 0 | |
2010-09-01 20:04:06 +01:00
! CheckIfCallBackAllowsAvailability ( it , IACT_MAPGENERATION ) | |
( _game_mode ! = GM_EDITOR & & _settings_game . difficulty . number_industries = = 0 ) ) {
2010-02-13 14:06:01 +00:00
* force_at_least_one = false ;
return 0 ;
} else {
/* We want industries appearing at coast to appear less often on bigger maps, as length of coast increases slower than map area.
* For simplicity we scale in both cases , though scaling the probabilities of all industries has no effect . */
chance = ( ind_spc - > check_proc = = CHECK_REFINERY | | ind_spc - > check_proc = = CHECK_OIL_RIG ) ? ScaleByMapSize1D ( chance ) : ScaleByMapSize ( chance ) ;
2010-09-01 20:04:06 +01:00
* force_at_least_one = ( chance > 0 ) & & ! ( ind_spc - > behaviour & INDUSTRYBEH_NOBUILT_MAPCREATION ) & & ( _game_mode ! = GM_EDITOR ) ;
2010-02-13 14:06:01 +00:00
return chance ;
}
}
2007-07-27 04:07:05 +01:00
2010-09-04 12:29:42 +01:00
/**
* Compute the probability for constructing a new industry during game play .
* @ param it Industry type to compute .
2010-11-13 15:21:55 +00:00
* @ param [ out ] min_number Minimal number of industries that should exist at the map .
2010-09-04 12:29:42 +01:00
* @ return Relative probability for the industry to appear .
*/
2010-11-13 15:21:55 +00:00
static uint16 GetIndustryGamePlayProbability ( IndustryType it , byte * min_number )
2010-09-04 12:29:42 +01:00
{
2010-11-13 15:21:55 +00:00
if ( _settings_game . difficulty . number_industries = = 0 ) {
* min_number = 0 ;
return 0 ;
}
2010-11-13 15:04:58 +00:00
2010-09-04 12:29:42 +01:00
const IndustrySpec * ind_spc = GetIndustrySpec ( it ) ;
byte chance = ind_spc - > appear_ingame [ _settings_game . game_creation . landscape ] ;
if ( ! ind_spc - > enabled | | chance = = 0 | | ind_spc - > num_table = = 0 | |
( ( ind_spc - > behaviour & INDUSTRYBEH_BEFORE_1950 ) & & _cur_year > 1950 ) | |
( ( ind_spc - > behaviour & INDUSTRYBEH_AFTER_1960 ) & & _cur_year < 1960 ) | |
! CheckIfCallBackAllowsAvailability ( it , IACT_RANDOMCREATION ) ) {
2010-11-13 15:21:55 +00:00
* min_number = 0 ;
2010-09-04 12:29:42 +01:00
return 0 ;
}
2010-11-13 15:21:55 +00:00
* min_number = ( ind_spc - > behaviour & INDUSTRYBEH_CANCLOSE_LASTINSTANCE ) ? 1 : 0 ;
2010-09-04 12:29:42 +01:00
return chance ;
}
2010-09-04 13:09:12 +01:00
/**
* Get wanted number of industries on the map .
* @ return Wanted number of industries at the map .
*/
static uint GetNumberOfIndustries ( )
{
/* Number of industries on a 256x256 map. */
static const uint16 numof_industry_table [ ] = {
0 , // none
10 , // very low
25 , // low
55 , // normal
80 , // high
} ;
assert ( _settings_game . difficulty . number_industries < lengthof ( numof_industry_table ) ) ;
uint difficulty = ( _game_mode ! = GM_EDITOR ) ? _settings_game . difficulty . number_industries : 1 ;
return ScaleByMapSize ( numof_industry_table [ difficulty ] ) ;
}
2004-08-09 18:04:08 +01:00
2010-09-04 13:01:55 +01:00
/**
* Advertise about a new industry opening .
* @ param ind Industry being opened .
*/
2010-11-13 10:17:16 +00:00
static void AdvertiseIndustryOpening ( const Industry * ind )
2010-09-04 13:01:55 +01:00
{
const IndustrySpec * ind_spc = GetIndustrySpec ( ind - > type ) ;
SetDParam ( 0 , ind_spc - > name ) ;
if ( ind_spc - > new_industry_text > STR_LAST_STRINGID ) {
SetDParam ( 1 , STR_TOWN_NAME ) ;
SetDParam ( 2 , ind - > town - > index ) ;
} else {
SetDParam ( 1 , ind - > town - > index ) ;
}
AddIndustryNewsItem ( ind_spc - > new_industry_text , NS_INDUSTRY_OPEN , ind - > index ) ;
AI : : BroadcastNewEvent ( new AIEventIndustryOpen ( ind - > index ) ) ;
}
2010-09-04 12:59:12 +01:00
/**
* Try to place the industry in the game .
* Since there is no feedback why placement fails , there is no other option
* than to try a few times before concluding it does not work .
* @ param type Industry type of the desired industry .
* @ param try_hard Try very hard to find a place . ( Used to place at least one industry per type . )
* @ return Pointer to created industry , or \ c NULL if creation failed .
*/
2010-10-16 14:15:54 +01:00
static Industry * PlaceIndustry ( IndustryType type , IndustryAvailabilityCallType creation_type , bool try_hard )
2010-09-04 12:59:12 +01:00
{
uint tries = try_hard ? 10000u : 2000u ;
for ( ; tries > 0 ; tries - - ) {
2010-10-16 14:15:54 +01:00
Industry * ind = CreateNewIndustry ( RandomTile ( ) , type , creation_type ) ;
2010-09-04 12:59:12 +01:00
if ( ind ! = NULL ) return ind ;
}
return NULL ;
}
2010-02-13 14:06:01 +00:00
/**
* Try to build a industry on the map .
2007-04-09 02:43:29 +01:00
* @ param type IndustryType of the desired industry
2010-02-13 14:06:01 +00:00
* @ param try_hard Try very hard to find a place . ( Used to place at least one industry per type )
*/
static void PlaceInitialIndustry ( IndustryType type , bool try_hard )
2004-08-09 18:04:08 +01:00
{
2010-06-05 13:16:12 +01:00
Backup < CompanyByte > cur_company ( _current_company , OWNER_NONE , FILE_LINE ) ;
(svn r5946) -Add: merged the TGP branch to mainline. TGP adds:
- New optional landscape generator (TerraGenesis Perlin)
- Load heightmaps (either BMP or PNG)
- Progress dialog while generating worlds (no longer a 'hanging' screen)
- New dialogs for NewGame, Create Scenario and Play Heightmap
- Easier to configure your landscape
- More things to configure (tree-placer, ..)
- Speedup of world generation
- New console command 'restart': restart the map EXACTLY as it was when you
first started it (needs a game made after or with this commit)
- New console command 'getseed': get the seed of your map and share it with
others (of course only works with generated maps)
- Many new, world generation related, things
- Many internal cleanups and rewrites
Many tnx to those people who helped making this:
Belugas, DaleStan, glx, KUDr, RichK67, Rubidium, and TrueLight (alfabetic)
Many tnx to those who helped testing:
Arnau, Bjarni, and tokai (alfabetic)
And to all other people who helped testing and sending comments / bugs
Stats: 673 lines changed, 3534 new lines, 79 new strings
2006-08-19 11:00:30 +01:00
2010-02-13 14:06:01 +00:00
IncreaseGeneratingWorldProgress ( GWP_INDUSTRY ) ;
2010-10-16 14:15:54 +01:00
PlaceIndustry ( type , IACT_MAPGENERATION , try_hard ) ;
2010-02-06 20:19:59 +00:00
2010-05-31 21:22:57 +01:00
cur_company . Restore ( ) ;
2004-08-09 18:04:08 +01:00
}
2010-11-13 15:17:55 +00:00
/**
* Get total number of industries existing in the game .
* @ return Number of industries currently in the game .
*/
static uint GetCurrentTotalNumberOfIndustries ( )
{
int total = 0 ;
for ( IndustryType it = 0 ; it < NUM_INDUSTRYTYPES ; it + + ) total + = Industry : : GetIndustryTypeCount ( it ) ;
return total ;
}
2010-11-13 15:15:25 +00:00
/** Reset the entry. */
void IndustryTypeBuildData : : Reset ( )
{
this - > probability = 0 ;
2010-11-13 15:21:55 +00:00
this - > min_number = 0 ;
2010-11-13 15:15:25 +00:00
this - > target_count = 0 ;
2010-11-13 15:20:57 +00:00
this - > max_wait = 1 ;
this - > wait_count = 0 ;
2010-11-13 15:15:25 +00:00
}
/** Completely reset the industry build data. */
void IndustryBuildData : : Reset ( )
{
2010-11-13 15:17:55 +00:00
this - > wanted_inds = GetCurrentTotalNumberOfIndustries ( ) < < 16 ;
2010-11-13 15:15:25 +00:00
for ( IndustryType it = 0 ; it < NUM_INDUSTRYTYPES ; it + + ) {
this - > builddata [ it ] . Reset ( ) ;
}
}
2010-11-13 15:17:55 +00:00
/** Monthly update of industry build data. */
void IndustryBuildData : : MonthlyLoop ( )
{
static const int NEWINDS_PER_MONTH = 0x38000 / ( 10 * 12 ) ; // lower 16 bits is a float fraction, 3.5 industries per decade, divided by 10 * 12 months.
if ( _settings_game . difficulty . number_industries = = 0 ) return ; // 'no industries' setting,
/* To prevent running out of unused industries for the player to connect,
* add a fraction of new industries each month , but only if the manager can keep up . */
uint max_behind = 1 + min ( 99u , ScaleByMapSize ( 3 ) ) ; // At most 2 industries for small maps, and 100 at the biggest map (about 6 months industry build attempts).
if ( GetCurrentTotalNumberOfIndustries ( ) + max_behind > = ( this - > wanted_inds > > 16 ) ) {
this - > wanted_inds + = ScaleByMapSize ( NEWINDS_PER_MONTH ) ;
}
}
2010-02-13 14:06:01 +00:00
/**
* This function will create random industries during game creation .
* It will scale the amount of industries by mapsize and difficulty level .
*/
2007-03-07 11:47:46 +00:00
void GenerateIndustries ( )
2004-08-09 18:04:08 +01:00
{
2010-09-04 13:09:12 +01:00
uint total_amount = GetNumberOfIndustries ( ) ;
2010-02-13 14:06:01 +00:00
/* Do not create any industries? */
if ( total_amount = = 0 ) return ;
uint32 industry_probs [ NUM_INDUSTRYTYPES ] ;
bool force_at_least_one [ NUM_INDUSTRYTYPES ] ;
uint32 total_prob = 0 ;
uint num_forced = 0 ;
for ( IndustryType it = 0 ; it < NUM_INDUSTRYTYPES ; it + + ) {
2010-09-04 12:16:40 +01:00
industry_probs [ it ] = GetScaledIndustryGenerationProbability ( it , force_at_least_one + it ) ;
2010-02-13 14:06:01 +00:00
total_prob + = industry_probs [ it ] ;
if ( force_at_least_one [ it ] ) num_forced + + ;
}
if ( total_prob = = 0 | | total_amount < num_forced ) {
/* Only place the forced ones */
total_amount = num_forced ;
2007-04-09 02:43:29 +01:00
}
(svn r5946) -Add: merged the TGP branch to mainline. TGP adds:
- New optional landscape generator (TerraGenesis Perlin)
- Load heightmaps (either BMP or PNG)
- Progress dialog while generating worlds (no longer a 'hanging' screen)
- New dialogs for NewGame, Create Scenario and Play Heightmap
- Easier to configure your landscape
- More things to configure (tree-placer, ..)
- Speedup of world generation
- New console command 'restart': restart the map EXACTLY as it was when you
first started it (needs a game made after or with this commit)
- New console command 'getseed': get the seed of your map and share it with
others (of course only works with generated maps)
- Many new, world generation related, things
- Many internal cleanups and rewrites
Many tnx to those people who helped making this:
Belugas, DaleStan, glx, KUDr, RichK67, Rubidium, and TrueLight (alfabetic)
Many tnx to those who helped testing:
Arnau, Bjarni, and tokai (alfabetic)
And to all other people who helped testing and sending comments / bugs
Stats: 673 lines changed, 3534 new lines, 79 new strings
2006-08-19 11:00:30 +01:00
2010-02-06 20:50:50 +00:00
SetGeneratingWorldProgress ( GWP_INDUSTRY , total_amount ) ;
2004-08-09 18:04:08 +01:00
2010-02-13 14:06:01 +00:00
/* Try to build one industry per type independent of any probabilities */
for ( IndustryType it = 0 ; it < NUM_INDUSTRYTYPES ; it + + ) {
if ( force_at_least_one [ it ] ) {
assert ( total_amount > 0 ) ;
total_amount - - ;
PlaceInitialIndustry ( it , true ) ;
}
}
/* Add the remaining industries according to their probabilities */
for ( uint i = 0 ; i < total_amount ; i + + ) {
2010-04-17 12:49:25 +01:00
uint32 r = RandomRange ( total_prob ) ;
2010-02-13 14:06:01 +00:00
IndustryType it = 0 ;
2010-11-13 10:11:47 +00:00
while ( r > = industry_probs [ it ] ) {
2010-02-13 14:06:01 +00:00
r - = industry_probs [ it ] ;
it + + ;
2010-11-13 10:11:47 +00:00
assert ( it < NUM_INDUSTRYTYPES ) ;
2007-05-30 02:55:11 +01:00
}
2010-11-13 10:11:47 +00:00
assert ( industry_probs [ it ] > 0 ) ;
2010-02-13 14:06:01 +00:00
PlaceInitialIndustry ( it , false ) ;
2007-07-15 01:26:12 +01:00
}
2010-11-13 15:15:25 +00:00
_industry_builder . Reset ( ) ;
2004-08-09 18:04:08 +01:00
}
2010-08-01 18:45:53 +01:00
/**
* Monthly update of industry statistics .
* @ param i Industry to update .
*/
2004-08-09 18:04:08 +01:00
static void UpdateIndustryStatistics ( Industry * i )
{
2007-09-27 22:39:13 +01:00
for ( byte j = 0 ; j < lengthof ( i - > produced_cargo ) ; j + + ) {
if ( i - > produced_cargo [ j ] ! = CT_INVALID ) {
2010-03-17 18:52:56 +00:00
byte pct = 0 ;
2007-06-07 15:38:45 +01:00
if ( i - > this_month_production [ j ] ! = 0 ) {
2007-05-18 01:33:47 +01:00
i - > last_prod_year = _cur_year ;
2007-06-07 15:38:45 +01:00
pct = min ( i - > this_month_transported [ j ] * 256 / i - > this_month_production [ j ] , 255 ) ;
2007-05-18 01:33:47 +01:00
}
2007-06-07 15:38:45 +01:00
i - > last_month_pct_transported [ j ] = pct ;
2004-08-09 18:04:08 +01:00
2007-06-07 15:38:45 +01:00
i - > last_month_production [ j ] = i - > this_month_production [ j ] ;
i - > this_month_production [ j ] = 0 ;
2004-08-09 18:04:08 +01:00
2007-06-07 15:38:45 +01:00
i - > last_month_transported [ j ] = i - > this_month_transported [ j ] ;
i - > this_month_transported [ j ] = 0 ;
2004-09-11 10:55:19 +01:00
}
2004-08-09 18:04:08 +01:00
}
}
2010-10-04 20:23:50 +01:00
/**
* Recompute # production_rate for current # prod_level .
* This function is only valid when not using smooth economy .
*/
void Industry : : RecomputeProductionMultipliers ( )
{
const IndustrySpec * indspec = GetIndustrySpec ( this - > type ) ;
assert ( ! indspec - > UsesSmoothEconomy ( ) ) ;
/* Rates are rounded up, so e.g. oilrig always produces some passengers */
this - > production_rate [ 0 ] = min ( CeilDiv ( indspec - > production_rate [ 0 ] * this - > prod_level , PRODLEVEL_DEFAULT ) , 0xFF ) ;
this - > production_rate [ 1 ] = min ( CeilDiv ( indspec - > production_rate [ 1 ] * this - > prod_level , PRODLEVEL_DEFAULT ) , 0xFF ) ;
}
2010-11-13 15:04:58 +00:00
/**
2010-11-13 15:21:55 +00:00
* Set the # probability and # min_number fields for the industry type \ a it for a running game .
2010-11-13 15:04:58 +00:00
* @ param it Industry type .
2010-11-13 15:21:55 +00:00
* @ return At least one of the fields has changed value .
2010-11-13 15:04:58 +00:00
*/
2010-11-13 15:19:43 +00:00
bool IndustryTypeBuildData : : GetIndustryTypeData ( IndustryType it )
2010-11-13 15:04:58 +00:00
{
2010-11-13 15:21:55 +00:00
byte min_number ;
uint32 probability = GetIndustryGamePlayProbability ( it , & min_number ) ;
bool changed = min_number ! = this - > min_number | | probability ! = this - > probability ;
this - > min_number = min_number ;
2010-11-13 15:19:43 +00:00
this - > probability = probability ;
return changed ;
2010-11-13 15:04:58 +00:00
}
2007-04-06 03:12:15 +01:00
2010-11-13 15:07:34 +00:00
/** Decide how many industries of each type are needed. */
void IndustryBuildData : : SetupTargetCount ( )
{
2010-11-13 15:19:43 +00:00
bool changed = false ;
uint num_planned = 0 ; // Number of industries planned in the industry build data.
2010-11-13 15:07:34 +00:00
for ( IndustryType it = 0 ; it < NUM_INDUSTRYTYPES ; it + + ) {
2010-11-13 15:19:43 +00:00
changed | = this - > builddata [ it ] . GetIndustryTypeData ( it ) ;
num_planned + = this - > builddata [ it ] . target_count ;
2010-11-13 15:07:34 +00:00
}
2010-11-13 15:17:55 +00:00
uint total_amount = this - > wanted_inds > > 16 ; // Desired total number of industries.
2010-11-13 15:19:43 +00:00
changed | = num_planned ! = total_amount ;
if ( ! changed ) return ; // All industries are still the same, no need to re-randomize.
2010-11-13 15:21:55 +00:00
/* Initialize the target counts. */
uint force_build = 0 ; // Number of industries that should always be available.
2010-11-13 15:07:34 +00:00
uint32 total_prob = 0 ; // Sum of probabilities.
for ( IndustryType it = 0 ; it < NUM_INDUSTRYTYPES ; it + + ) {
2010-11-13 15:21:55 +00:00
IndustryTypeBuildData * ibd = this - > builddata + it ;
force_build + = ibd - > min_number ;
ibd - > target_count = ibd - > min_number ;
total_prob + = ibd - > probability ;
2010-11-13 15:07:34 +00:00
}
2010-11-20 12:20:59 +00:00
if ( total_prob = = 0 ) return ; // No buildable industries.
2010-11-13 15:21:55 +00:00
/* Subtract forced industries from the number of industries available for construction. */
total_amount = ( total_amount < = force_build ) ? 0 : total_amount - force_build ;
2010-11-13 15:07:34 +00:00
/* Assign number of industries that should be aimed for, by using the probability as a weight. */
while ( total_amount > 0 ) {
uint32 r = RandomRange ( total_prob ) ;
IndustryType it = 0 ;
while ( r > = this - > builddata [ it ] . probability ) {
r - = this - > builddata [ it ] . probability ;
it + + ;
assert ( it < NUM_INDUSTRYTYPES ) ;
}
assert ( this - > builddata [ it ] . probability > 0 ) ;
this - > builddata [ it ] . target_count + + ;
total_amount - - ;
}
}
2007-04-04 01:32:40 +01:00
/**
* Try to create a random industry , during gameplay
*/
2010-11-13 15:02:31 +00:00
void IndustryBuildData : : TryBuildNewIndustry ( )
2007-04-04 01:32:40 +01:00
{
2010-11-13 15:07:34 +00:00
this - > SetupTargetCount ( ) ;
2010-11-13 15:04:58 +00:00
2010-11-13 15:07:34 +00:00
int missing = 0 ; // Number of industries that need to be build.
2010-11-13 15:04:58 +00:00
uint count = 0 ; // Number of industry types eligible for build.
uint32 total_prob = 0 ; // Sum of probabilities.
2010-11-13 15:21:55 +00:00
IndustryType forced_build = NUM_INDUSTRYTYPES ; // Industry type that should be forcibly build.
2010-11-13 15:04:58 +00:00
for ( IndustryType it = 0 ; it < NUM_INDUSTRYTYPES ; it + + ) {
2010-11-13 15:07:34 +00:00
int difference = this - > builddata [ it ] . target_count - Industry : : GetIndustryTypeCount ( it ) ;
missing + = difference ;
2010-11-13 15:20:57 +00:00
if ( this - > builddata [ it ] . wait_count > 0 ) continue ; // This type may not be built now.
2010-11-13 15:07:34 +00:00
if ( difference > 0 ) {
2010-11-13 15:21:55 +00:00
if ( Industry : : GetIndustryTypeCount ( it ) = = 0 & & this - > builddata [ it ] . min_number > 0 ) {
/* An industry that should exist at least once, is not available. Force it, trying the most needed one first. */
if ( forced_build = = NUM_INDUSTRYTYPES | |
difference > this - > builddata [ forced_build ] . target_count - Industry : : GetIndustryTypeCount ( forced_build ) ) {
forced_build = it ;
}
}
2010-11-13 15:07:34 +00:00
total_prob + = difference ;
2010-11-13 15:04:58 +00:00
count + + ;
2007-04-04 01:32:40 +01:00
}
}
2004-08-09 18:04:08 +01:00
2010-11-13 15:21:55 +00:00
if ( EconomyIsInRecession ( ) | | ( forced_build = = NUM_INDUSTRYTYPES & & ( missing < = 0 | | total_prob = = 0 ) ) ) count = 0 ; // Skip creation of an industry.
2010-11-13 15:07:34 +00:00
2010-11-13 15:04:58 +00:00
if ( count > = 1 ) {
2010-11-13 15:21:55 +00:00
/* If not forced, pick a weighted random industry to build.
2010-11-13 15:04:58 +00:00
* For the case that count = = 1 , there is no need to draw a random number . */
IndustryType it ;
2010-11-13 15:21:55 +00:00
if ( forced_build ! = NUM_INDUSTRYTYPES ) {
it = forced_build ;
} else {
/* Non-forced, select an industry type to build (weighted random). */
uint32 r = 0 ; // Initialized to silence the compiler.
if ( count > 1 ) r = RandomRange ( total_prob ) ;
for ( it = 0 ; it < NUM_INDUSTRYTYPES ; it + + ) {
if ( this - > builddata [ it ] . wait_count > 0 ) continue ; // Type may not be built now.
int difference = this - > builddata [ it ] . target_count - Industry : : GetIndustryTypeCount ( it ) ;
if ( difference < = 0 ) continue ; // Too many of this kind.
if ( count = = 1 ) break ;
if ( r < ( uint ) difference ) break ;
r - = difference ;
}
assert ( it < NUM_INDUSTRYTYPES & & this - > builddata [ it ] . target_count > Industry : : GetIndustryTypeCount ( it ) ) ;
2010-11-13 15:04:58 +00:00
}
2009-04-11 15:54:03 +01:00
2010-11-13 15:04:58 +00:00
/* Try to create the industry. */
const Industry * ind = PlaceIndustry ( it , IACT_RANDOMCREATION , false ) ;
2010-11-13 15:20:57 +00:00
if ( ind = = NULL ) {
this - > builddata [ it ] . wait_count = this - > builddata [ it ] . max_wait + 1 ; // Compensate for decrementing below.
this - > builddata [ it ] . max_wait = min ( 1000 , this - > builddata [ it ] . max_wait + 2 ) ;
} else {
2010-11-13 15:04:58 +00:00
AdvertiseIndustryOpening ( ind ) ;
2010-11-13 15:20:57 +00:00
this - > builddata [ it ] . max_wait = max ( this - > builddata [ it ] . max_wait / 2 , 1 ) ; // Reduce waiting time of the industry type.
2010-11-13 15:04:58 +00:00
}
2007-04-04 01:32:40 +01:00
}
2010-11-13 15:20:57 +00:00
/* Decrement wait counters. */
for ( IndustryType it = 0 ; it < NUM_INDUSTRYTYPES ; it + + ) {
if ( this - > builddata [ it ] . wait_count > 0 ) this - > builddata [ it ] . wait_count - - ;
}
2004-08-09 18:04:08 +01:00
}
2007-09-22 22:59:02 +01:00
/**
* Protects an industry from closure if the appropriate flags and conditions are met
* INDUSTRYBEH_CANCLOSE_LASTINSTANCE must be set ( which , by default , it is not ) and the
* count of industries of this type must one ( or lower ) in order to be protected
* against closure .
* @ param type IndustryType been queried
* @ result true if protection is on , false otherwise ( except for oil wells )
*/
static bool CheckIndustryCloseDownProtection ( IndustryType type )
2004-08-09 18:04:08 +01:00
{
2006-04-26 22:10:01 +01:00
const IndustrySpec * indspec = GetIndustrySpec ( type ) ;
2004-09-11 10:55:19 +01:00
2007-09-22 22:59:02 +01:00
/* oil wells (or the industries with that flag set) are always allowed to closedown */
2009-06-01 12:43:36 +01:00
if ( ( indspec - > behaviour & INDUSTRYBEH_DONT_INCR_PROD ) & & _settings_game . game_creation . landscape = = LT_TEMPERATE ) return false ;
2010-03-20 14:30:16 +00:00
return ( indspec - > behaviour & INDUSTRYBEH_CANCLOSE_LASTINSTANCE ) = = 0 & & Industry : : GetIndustryTypeCount ( type ) < = 1 ;
2007-09-22 22:59:02 +01:00
}
2007-11-15 22:20:33 +00:00
/**
2009-03-14 18:16:29 +00:00
* Can given cargo type be accepted or produced by the industry ?
* @ param cargo : Cargo type
* @ param ind : Industry
* @ param * c_accepts : Pointer to boolean for acceptance of cargo
* @ param * c_produces : Pointer to boolean for production of cargo
* @ return : \ c * c_accepts is set when industry accepts the cargo type ,
* \ c * c_produces is set when the industry produces the cargo type
*/
2007-11-15 22:20:33 +00:00
static void CanCargoServiceIndustry ( CargoID cargo , Industry * ind , bool * c_accepts , bool * c_produces )
{
2010-08-07 21:11:27 +01:00
if ( cargo = = CT_INVALID ) return ;
2007-11-15 22:20:33 +00:00
/* Check for acceptance of cargo */
2008-05-01 23:51:53 +01:00
for ( byte j = 0 ; j < lengthof ( ind - > accepts_cargo ) ; j + + ) {
2010-08-07 21:11:27 +01:00
if ( cargo = = ind - > accepts_cargo [ j ] & & ! IndustryTemporarilyRefusesCargo ( ind , cargo ) ) {
2007-11-15 22:20:33 +00:00
* c_accepts = true ;
break ;
}
}
/* Check for produced cargo */
2008-05-01 23:51:53 +01:00
for ( byte j = 0 ; j < lengthof ( ind - > produced_cargo ) ; j + + ) {
2007-11-15 22:20:33 +00:00
if ( cargo = = ind - > produced_cargo [ j ] ) {
* c_produces = true ;
break ;
}
}
}
/**
2009-03-14 18:16:29 +00:00
* Compute who can service the industry .
*
* Here , ' can service ' means that he / she has trains and stations close enough
* to the industry with the right cargo type and the right orders ( ie has the
* technical means ) .
*
* @ param ind : Industry being investigated .
*
* @ return : 0 if nobody can service the industry , 2 if the local company can
* service the industry , and 1 otherwise ( only competitors can service the
* industry )
*/
2009-11-09 10:40:33 +00:00
static int WhoCanServiceIndustry ( Industry * ind )
2007-11-15 22:20:33 +00:00
{
/* Find all stations within reach of the industry */
2009-01-13 20:43:53 +00:00
StationList stations ;
2010-01-04 18:21:07 +00:00
FindStationsAroundTiles ( ind - > location , & stations ) ;
2007-11-15 22:20:33 +00:00
2009-01-13 18:18:53 +00:00
if ( stations . Length ( ) = = 0 ) return 0 ; // No stations found at all => nobody services
2007-11-15 22:20:33 +00:00
const Vehicle * v ;
int result = 0 ;
FOR_ALL_VEHICLES ( v ) {
/* Is it worthwhile to try this vehicle? */
2008-09-30 21:39:50 +01:00
if ( v - > owner ! = _local_company & & result ! = 0 ) continue ;
2007-11-15 22:20:33 +00:00
/* Check whether it accepts the right kind of cargo */
bool c_accepts = false ;
bool c_produces = false ;
2009-07-01 23:22:01 +01:00
if ( v - > type = = VEH_TRAIN & & Train : : From ( v ) - > IsFrontEngine ( ) ) {
2008-05-21 13:06:05 +01:00
for ( const Vehicle * u = v ; u ! = NULL ; u = u - > Next ( ) ) {
2007-11-15 22:20:33 +00:00
CanCargoServiceIndustry ( u - > cargo_type , ind , & c_accepts , & c_produces ) ;
2008-05-21 13:06:05 +01:00
}
2007-11-15 22:20:33 +00:00
} else if ( v - > type = = VEH_ROAD | | v - > type = = VEH_SHIP | | v - > type = = VEH_AIRCRAFT ) {
CanCargoServiceIndustry ( v - > cargo_type , ind , & c_accepts , & c_produces ) ;
} else {
continue ;
}
if ( ! c_accepts & & ! c_produces ) continue ; // Wrong cargo
/* Check orders of the vehicle.
* We cannot check the first of shared orders only , since the first vehicle in such a chain
* may have a different cargo type .
*/
const Order * o ;
FOR_VEHICLE_ORDERS ( v , o ) {
2008-04-07 21:03:46 +01:00
if ( o - > IsType ( OT_GOTO_STATION ) & & ! ( o - > GetUnloadType ( ) & OUFB_TRANSFER ) ) {
2007-11-15 22:20:33 +00:00
/* Vehicle visits a station to load or unload */
2009-05-17 00:34:14 +01:00
Station * st = Station : : Get ( o - > GetDestination ( ) ) ;
2009-05-22 16:13:50 +01:00
assert ( st ! = NULL ) ;
2007-11-15 22:20:33 +00:00
/* Same cargo produced by industry is dropped here => not serviced by vehicle v */
2008-04-07 21:03:46 +01:00
if ( ( o - > GetUnloadType ( ) & OUFB_UNLOAD ) & & ! c_accepts ) break ;
2007-11-15 22:20:33 +00:00
2009-01-13 18:18:53 +00:00
if ( stations . Contains ( st ) ) {
2008-09-30 21:39:50 +01:00
if ( v - > owner = = _local_company ) return 2 ; // Company services industry
2007-11-15 22:20:33 +00:00
result = 1 ; // Competitor services industry
}
}
}
}
return result ;
}
/**
2009-03-14 18:16:29 +00:00
* Report news that industry production has changed significantly
*
* @ param ind : Industry with changed production
* @ param type : Cargo type that has changed
* @ param percent : Percentage of change ( > 0 means increase , < 0 means decrease )
*/
2007-11-15 22:20:33 +00:00
static void ReportNewsProductionChangeIndustry ( Industry * ind , CargoID type , int percent )
{
2008-05-15 14:39:36 +01:00
NewsSubtype ns ;
2007-11-15 22:20:33 +00:00
switch ( WhoCanServiceIndustry ( ind ) ) {
2008-09-30 21:39:50 +01:00
case 0 : ns = NS_INDUSTRY_NOBODY ; break ;
case 1 : ns = NS_INDUSTRY_OTHER ; break ;
case 2 : ns = NS_INDUSTRY_COMPANY ; break ;
2009-05-26 16:46:24 +01:00
default : NOT_REACHED ( ) ;
2007-11-15 22:20:33 +00:00
}
SetDParam ( 2 , abs ( percent ) ) ;
2009-07-16 20:00:13 +01:00
SetDParam ( 0 , CargoSpec : : Get ( type ) - > name ) ;
2007-11-15 22:20:33 +00:00
SetDParam ( 1 , ind - > index ) ;
2009-05-24 17:52:42 +01:00
AddIndustryNewsItem (
2009-04-22 00:40:56 +01:00
percent > = 0 ? STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_SMOOTH : STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_SMOOTH ,
2008-05-15 14:39:36 +01:00
ns ,
2009-05-24 17:52:42 +01:00
ind - > index
2007-11-15 22:20:33 +00:00
) ;
}
2010-05-13 11:14:29 +01:00
static const uint PERCENT_TRANSPORTED_60 = 153 ;
static const uint PERCENT_TRANSPORTED_80 = 204 ;
2007-11-23 12:12:07 +00:00
2010-08-01 20:22:34 +01:00
/**
* Change industry production or do closure
2007-09-22 22:59:02 +01:00
* @ param i Industry for which changes are performed
* @ param monthly true if it ' s the monthly call , false if it ' s the random call
*/
static void ChangeIndustryProduction ( Industry * i , bool monthly )
{
StringID str = STR_NULL ;
bool closeit = false ;
const IndustrySpec * indspec = GetIndustrySpec ( i - > type ) ;
2009-01-17 14:49:31 +00:00
bool standard = false ;
2007-09-23 00:40:35 +01:00
bool suppress_message = false ;
2009-01-16 11:32:35 +00:00
bool recalculate_multipliers = false ; ///< reinitialize production_rate to match prod_level
2007-11-23 16:50:54 +00:00
/* don't use smooth economy for industries using production related callbacks */
2010-09-26 12:04:30 +01:00
bool smooth_economy = indspec - > UsesSmoothEconomy ( ) ;
2007-09-23 00:40:35 +01:00
byte div = 0 ;
byte mul = 0 ;
2007-11-27 04:16:08 +00:00
int8 increment = 0 ;
2007-09-23 00:40:35 +01:00
2009-09-14 13:22:57 +01:00
bool callback_enabled = HasBit ( indspec - > callback_mask , monthly ? CBM_IND_MONTHLYPROD_CHANGE : CBM_IND_PRODUCTION_CHANGE ) ;
2009-01-17 14:49:31 +00:00
if ( callback_enabled ) {
2010-01-04 18:21:07 +00:00
uint16 res = GetIndustryCallback ( monthly ? CBID_INDUSTRY_MONTHLYPROD_CHANGE : CBID_INDUSTRY_PRODUCTION_CHANGE , 0 , Random ( ) , i , i - > type , i - > location . tile ) ;
2009-01-17 14:49:31 +00:00
if ( res ! = CALLBACK_FAILED ) { // failed callback means "do nothing"
2007-11-19 21:02:30 +00:00
suppress_message = HasBit ( res , 7 ) ;
2007-09-23 00:40:35 +01:00
/* Get the custom message if any */
2007-11-19 21:02:30 +00:00
if ( HasBit ( res , 8 ) ) str = MapGRFStringID ( indspec - > grf_prop . grffile - > grfid , GB ( GetRegister ( 0x100 ) , 0 , 16 ) ) ;
2007-09-23 00:40:35 +01:00
res = GB ( res , 0 , 4 ) ;
2009-08-09 15:40:34 +01:00
switch ( res ) {
2007-09-23 00:40:35 +01:00
default : NOT_REACHED ( ) ;
case 0x0 : break ; // Do nothing, but show the custom message if any
case 0x1 : div = 1 ; break ; // Halve industry production. If production reaches the quarter of the default, the industry is closed instead.
case 0x2 : mul = 1 ; break ; // Double industry production if it hasn't reached eight times of the original yet.
case 0x3 : closeit = true ; break ; // The industry announces imminent closure, and is physically removed from the map next month.
case 0x4 : standard = true ; break ; // Do the standard random production change as if this industry was a primary one.
case 0x5 : case 0x6 : case 0x7 : // Divide production by 4, 8, 16
2007-11-23 04:17:41 +00:00
case 0x8 : div = res - 0x3 ; break ; // Divide production by 32
2007-09-23 00:40:35 +01:00
case 0x9 : case 0xA : case 0xB : // Multiply production by 4, 8, 16
2007-11-23 04:17:41 +00:00
case 0xC : mul = res - 0x7 ; break ; // Multiply production by 32
2007-11-27 04:16:08 +00:00
case 0xD : // decrement production
case 0xE : // increment production
increment = res = = 0x0D ? - 1 : 1 ;
break ;
2008-11-03 20:23:51 +00:00
case 0xF : // Set production to third byte of register 0x100
i - > prod_level = Clamp ( GB ( GetRegister ( 0x100 ) , 16 , 8 ) , PRODLEVEL_MINIMUM , PRODLEVEL_MAXIMUM ) ;
2009-01-16 11:32:35 +00:00
recalculate_multipliers = true ;
2008-11-03 19:25:52 +00:00
break ;
2007-09-23 00:40:35 +01:00
}
}
2009-01-17 14:49:31 +00:00
} else {
if ( monthly ! = smooth_economy ) return ;
if ( indspec - > life_type = = INDUSTRYLIFE_BLACK_HOLE ) return ;
2007-09-23 00:40:35 +01:00
}
2007-09-22 22:59:02 +01:00
2009-01-17 14:49:31 +00:00
if ( standard | | ( ! callback_enabled & & ( indspec - > life_type & ( INDUSTRYLIFE_ORGANIC | INDUSTRYLIFE_EXTRACTIVE ) ) ! = 0 ) ) {
2007-07-03 20:16:34 +01:00
/* decrease or increase */
2008-05-29 16:13:28 +01:00
bool only_decrease = ( indspec - > behaviour & INDUSTRYBEH_DONT_INCR_PROD ) & & _settings_game . game_creation . landscape = = LT_TEMPERATE ;
2004-08-09 18:04:08 +01:00
2007-10-05 18:53:45 +01:00
if ( smooth_economy ) {
2007-09-22 22:59:02 +01:00
closeit = true ;
2008-05-01 23:51:53 +01:00
for ( byte j = 0 ; j < lengthof ( i - > produced_cargo ) ; j + + ) {
if ( i - > produced_cargo [ j ] = = CT_INVALID ) continue ;
2008-01-06 01:06:12 +00:00
uint32 r = Random ( ) ;
2007-09-22 22:59:02 +01:00
int old_prod , new_prod , percent ;
2008-01-06 01:06:12 +00:00
/* If over 60% is transported, mult is 1, else mult is -1. */
2007-11-23 12:12:07 +00:00
int mult = ( i - > last_month_pct_transported [ j ] > PERCENT_TRANSPORTED_60 ) ? 1 : - 1 ;
2004-09-11 10:55:19 +01:00
2007-09-22 22:59:02 +01:00
new_prod = old_prod = i - > production_rate [ j ] ;
2004-09-11 10:55:19 +01:00
2008-01-06 01:06:12 +00:00
/* For industries with only_decrease flags (temperate terrain Oil Wells),
* the multiplier will always be - 1 so they will only decrease . */
2007-11-26 19:23:53 +00:00
if ( only_decrease ) {
mult = - 1 ;
2008-01-06 01:06:12 +00:00
/* For normal industries, if over 60% is transported, 33% chance for decrease.
* Bonus for very high station ratings ( over 80 % ) : 16 % chance for decrease . */
} else if ( Chance16I ( 1 , ( ( i - > last_month_pct_transported [ j ] > PERCENT_TRANSPORTED_80 ) ? 6 : 3 ) , r ) ) {
2007-11-26 19:23:53 +00:00
mult * = - 1 ;
}
2007-11-23 12:12:07 +00:00
2008-01-06 01:06:12 +00:00
/* 4.5% chance for 3-23% (or 1 unit for very low productions) production change,
* determined by mult value . If mult = 1 prod . increases , else ( - 1 ) it decreases . */
if ( Chance16I ( 1 , 22 , r > > 16 ) ) {
2007-11-23 12:12:07 +00:00
new_prod + = mult * ( max ( ( ( RandomRange ( 50 ) + 10 ) * old_prod ) > > 8 , 1U ) ) ;
2007-09-22 22:59:02 +01:00
}
2004-08-09 18:04:08 +01:00
2007-11-23 12:12:07 +00:00
/* Prevent production to overflow or Oil Rig passengers to be over-"produced" */
2007-11-19 18:38:10 +00:00
new_prod = Clamp ( new_prod , 1 , 255 ) ;
2007-11-23 12:12:07 +00:00
2010-07-24 11:14:39 +01:00
if ( ( ( indspec - > behaviour & INDUSTRYBEH_BUILT_ONWATER ) ! = 0 ) & & j = = 1 ) {
2007-11-23 12:12:07 +00:00
new_prod = Clamp ( new_prod , 0 , 16 ) ;
2010-07-24 11:14:39 +01:00
}
2007-11-23 12:12:07 +00:00
2007-09-22 22:59:02 +01:00
/* Do not stop closing the industry when it has the lowest possible production rate */
if ( new_prod = = old_prod & & old_prod > 1 ) {
closeit = false ;
continue ;
}
2004-08-09 18:04:08 +01:00
2007-09-22 22:59:02 +01:00
percent = ( old_prod = = 0 ) ? 100 : ( new_prod * 100 / old_prod - 100 ) ;
i - > production_rate [ j ] = new_prod ;
/* Close the industry when it has the lowest possible production rate */
if ( new_prod > 1 ) closeit = false ;
2007-11-15 22:20:33 +00:00
if ( abs ( percent ) > = 10 ) {
ReportNewsProductionChangeIndustry ( i , i - > produced_cargo [ j ] , percent ) ;
2007-07-03 20:16:34 +01:00
}
2007-09-22 22:59:02 +01:00
}
} else {
2007-11-25 15:35:25 +00:00
if ( only_decrease | | Chance16 ( 1 , 3 ) ) {
2008-01-06 01:06:12 +00:00
/* If more than 60% transported, 66% chance of increase, else 33% chance of increase */
2007-11-25 15:35:25 +00:00
if ( ! only_decrease & & ( i - > last_month_pct_transported [ 0 ] > PERCENT_TRANSPORTED_60 ) ! = Chance16 ( 1 , 3 ) ) {
2007-09-23 00:40:35 +01:00
mul = 1 ; // Increase production
2005-02-06 15:07:29 +00:00
} else {
2007-09-23 00:40:35 +01:00
div = 1 ; // Decrease production
2005-02-06 15:07:29 +00:00
}
2004-08-09 18:04:08 +01:00
}
2007-07-03 20:16:34 +01:00
}
}
2007-09-22 22:59:02 +01:00
2009-06-01 12:43:36 +01:00
if ( ! callback_enabled & & ( indspec - > life_type & INDUSTRYLIFE_PROCESSING ) ) {
2007-11-25 15:35:25 +00:00
if ( ( byte ) ( _cur_year - i - > last_prod_year ) > = 5 & & Chance16 ( 1 , smooth_economy ? 180 : 2 ) ) {
2007-09-22 22:59:02 +01:00
closeit = true ;
2007-07-03 20:16:34 +01:00
}
2005-02-06 15:07:29 +00:00
}
2007-09-23 00:40:35 +01:00
/* Increase if needed */
2008-02-09 03:03:09 +00:00
while ( mul - - ! = 0 & & i - > prod_level < PRODLEVEL_MAXIMUM ) {
2008-02-09 03:12:05 +00:00
i - > prod_level = min ( i - > prod_level * 2 , PRODLEVEL_MAXIMUM ) ;
2009-01-16 11:32:35 +00:00
recalculate_multipliers = true ;
2007-09-23 00:40:35 +01:00
if ( str = = STR_NULL ) str = indspec - > production_up_text ;
}
/* Decrease if needed */
while ( div - - ! = 0 & & ! closeit ) {
2008-02-09 03:03:09 +00:00
if ( i - > prod_level = = PRODLEVEL_MINIMUM ) {
2007-09-23 00:40:35 +01:00
closeit = true ;
} else {
2008-02-09 03:12:05 +00:00
i - > prod_level = max ( i - > prod_level / 2 , ( int ) PRODLEVEL_MINIMUM ) ; // typecast to int required to please MSVC
2009-01-16 11:32:35 +00:00
recalculate_multipliers = true ;
2007-09-23 00:40:35 +01:00
if ( str = = STR_NULL ) str = indspec - > production_down_text ;
}
}
2008-01-24 18:16:04 +00:00
/* Increase or Decreasing the production level if needed */
2007-11-27 04:16:08 +00:00
if ( increment ! = 0 ) {
2008-02-09 03:03:09 +00:00
if ( increment < 0 & & i - > prod_level = = PRODLEVEL_MINIMUM ) {
2008-01-24 18:16:04 +00:00
closeit = true ;
} else {
2008-02-09 03:03:09 +00:00
i - > prod_level = ClampU ( i - > prod_level + increment , PRODLEVEL_MINIMUM , PRODLEVEL_MAXIMUM ) ;
2009-01-16 11:32:35 +00:00
recalculate_multipliers = true ;
2008-01-24 18:16:04 +00:00
}
2007-11-27 04:16:08 +00:00
}
2009-01-16 11:32:35 +00:00
/* Recalculate production_rate
* For non - smooth economy these should always be synchronized with prod_level */
2010-10-04 20:23:50 +01:00
if ( recalculate_multipliers ) i - > RecomputeProductionMultipliers ( ) ;
2009-01-16 11:32:35 +00:00
2007-09-22 22:59:02 +01:00
/* Close if needed and allowed */
if ( closeit & & ! CheckIndustryCloseDownProtection ( i - > type ) ) {
2008-02-09 03:03:09 +00:00
i - > prod_level = PRODLEVEL_CLOSURE ;
2007-09-22 22:59:02 +01:00
str = indspec - > closure_text ;
}
2007-09-23 00:40:35 +01:00
if ( ! suppress_message & & str ! = STR_NULL ) {
2008-05-15 14:39:36 +01:00
NewsSubtype ns ;
2007-11-15 22:20:33 +00:00
/* Compute news category */
if ( closeit ) {
2008-07-30 02:53:03 +01:00
ns = NS_INDUSTRY_CLOSE ;
2009-01-12 17:11:45 +00:00
AI : : BroadcastNewEvent ( new AIEventIndustryClose ( i - > index ) ) ;
2007-11-15 22:20:33 +00:00
} else {
switch ( WhoCanServiceIndustry ( i ) ) {
2008-09-30 21:39:50 +01:00
case 0 : ns = NS_INDUSTRY_NOBODY ; break ;
case 1 : ns = NS_INDUSTRY_OTHER ; break ;
case 2 : ns = NS_INDUSTRY_COMPANY ; break ;
2009-05-26 16:46:24 +01:00
default : NOT_REACHED ( ) ;
2007-11-15 22:20:33 +00:00
}
}
/* Set parameters of news string */
2007-10-18 21:35:59 +01:00
if ( str > STR_LAST_STRINGID ) {
2009-07-20 12:21:57 +01:00
SetDParam ( 0 , STR_TOWN_NAME ) ;
2007-10-18 21:35:59 +01:00
SetDParam ( 1 , i - > town - > index ) ;
SetDParam ( 2 , indspec - > name ) ;
2007-11-12 18:32:04 +00:00
} else if ( closeit ) {
2009-07-20 12:21:57 +01:00
SetDParam ( 0 , STR_FORMAT_INDUSTRY_NAME ) ;
2007-11-12 18:32:04 +00:00
SetDParam ( 1 , i - > town - > index ) ;
SetDParam ( 2 , indspec - > name ) ;
2007-10-18 21:35:59 +01:00
} else {
SetDParam ( 0 , i - > index ) ;
}
2007-11-15 22:20:33 +00:00
/* and report the news to the user */
2007-09-22 22:59:02 +01:00
AddNewsItem ( str ,
2008-05-15 14:39:36 +01:00
ns ,
2009-05-24 17:52:42 +01:00
closeit ? NR_TILE : NR_INDUSTRY ,
2010-01-04 18:21:07 +00:00
closeit ? i - > location . tile + TileDiffXY ( 1 , 1 ) : i - > index ) ;
2004-08-09 18:04:08 +01:00
}
}
2010-08-01 18:45:53 +01:00
/**
* Daily handler for the industry changes
2008-09-15 18:18:22 +01:00
* Taking the original map size of 256 * 256 , the number of random changes was always of just one unit .
* But it cannot be the same on smaller or bigger maps . That number has to be scaled up or down .
* For small maps , it implies that less than one change per month is required , while on bigger maps ,
2010-08-01 18:45:53 +01:00
* it would be way more . The daily loop handles those changes .
*/
2008-09-15 18:18:22 +01:00
void IndustryDailyLoop ( )
{
_economy . industry_daily_change_counter + = _economy . industry_daily_increment ;
/* Bits 16-31 of industry_construction_counter contain the number of industries to change/create today,
* the lower 16 bit are a fractional part that might accumulate over several days until it
* is sufficient for an industry . */
uint16 change_loop = _economy . industry_daily_change_counter > > 16 ;
/* Reset the active part of the counter, just keeping the "factional part" */
_economy . industry_daily_change_counter & = 0xFFFF ;
if ( change_loop = = 0 ) {
return ; // Nothing to do? get out
}
2010-06-05 13:16:12 +01:00
Backup < CompanyByte > cur_company ( _current_company , OWNER_NONE , FILE_LINE ) ;
2008-09-15 18:18:22 +01:00
/* perform the required industry changes for the day */
2010-11-13 15:17:55 +00:00
uint perc = 3 ; // Between 3% and 9% chance of creating a new industry.
if ( ( _industry_builder . wanted_inds > > 16 ) > GetCurrentTotalNumberOfIndustries ( ) ) {
perc = min ( 9u , perc + ( _industry_builder . wanted_inds > > 16 ) - GetCurrentTotalNumberOfIndustries ( ) ) ;
}
2008-09-15 18:18:22 +01:00
for ( uint16 j = 0 ; j < change_loop ; j + + ) {
2010-11-13 15:17:55 +00:00
if ( Chance16 ( perc , 100 ) ) {
2010-11-13 15:02:31 +00:00
_industry_builder . TryBuildNewIndustry ( ) ;
2008-09-15 18:18:22 +01:00
} else {
2009-06-26 16:08:54 +01:00
Industry * i = Industry : : GetRandom ( ) ;
2010-03-17 18:52:56 +00:00
if ( i ! = NULL ) {
ChangeIndustryProduction ( i , false ) ;
SetWindowDirty ( WC_INDUSTRY_VIEW , i - > index ) ;
}
2008-09-15 18:18:22 +01:00
}
}
2010-05-31 21:22:57 +01:00
cur_company . Restore ( ) ;
2008-09-15 18:18:22 +01:00
/* production-change */
InvalidateWindowData ( WC_INDUSTRY_DIRECTORY , 0 , 1 ) ;
}
2007-03-07 11:47:46 +00:00
void IndustryMonthlyLoop ( )
2004-08-09 18:04:08 +01:00
{
2010-06-05 13:16:12 +01:00
Backup < CompanyByte > cur_company ( _current_company , OWNER_NONE , FILE_LINE ) ;
2004-08-09 18:04:08 +01:00
2010-11-13 15:17:55 +00:00
_industry_builder . MonthlyLoop ( ) ;
2010-07-30 11:39:24 +01:00
Industry * i ;
2004-12-30 10:03:35 +00:00
FOR_ALL_INDUSTRIES ( i ) {
2006-08-22 16:33:35 +01:00
UpdateIndustryStatistics ( i ) ;
2008-02-09 03:03:09 +00:00
if ( i - > prod_level = = PRODLEVEL_CLOSURE ) {
2007-09-22 22:59:02 +01:00
delete i ;
} else {
ChangeIndustryProduction ( i , true ) ;
2010-03-17 18:52:56 +00:00
SetWindowDirty ( WC_INDUSTRY_VIEW , i - > index ) ;
2007-09-22 22:59:02 +01:00
}
2004-08-09 18:04:08 +01:00
}
2010-05-31 21:22:57 +01:00
cur_company . Restore ( ) ;
2004-09-16 16:15:04 +01:00
2007-03-03 04:04:22 +00:00
/* production-change */
2008-05-19 00:36:33 +01:00
InvalidateWindowData ( WC_INDUSTRY_DIRECTORY , 0 , 1 ) ;
2004-08-09 18:04:08 +01:00
}
2007-03-07 11:47:46 +00:00
void InitializeIndustries ( )
2004-08-09 18:04:08 +01:00
{
2009-05-22 16:13:50 +01:00
_industry_pool . CleanPool ( ) ;
2005-01-06 22:31:58 +00:00
2010-03-20 14:30:16 +00:00
Industry : : ResetIndustryCounts ( ) ;
2006-09-10 09:28:32 +01:00
_industry_sound_tile = 0 ;
2010-11-13 15:15:25 +00:00
_industry_builder . Reset ( ) ;
2004-08-09 18:04:08 +01:00
}
2011-01-18 22:31:06 +00:00
/**
* Is an industry with the spec a raw industry ?
* @ return true if it should be handled as a raw industry
*/
2007-07-06 23:33:16 +01:00
bool IndustrySpec : : IsRawIndustry ( ) const
{
/* Lumber mills are extractive/organic, but can always be built like a non-raw industry */
return ( this - > life_type & ( INDUSTRYLIFE_EXTRACTIVE | INDUSTRYLIFE_ORGANIC ) ) ! = 0 & &
( this - > behaviour & INDUSTRYBEH_CUT_TREES ) = = 0 ;
}
2011-01-18 22:31:06 +00:00
/**
* Get the cost for constructing this industry
* @ return the cost ( inflation corrected etc )
*/
2007-07-06 23:33:16 +01:00
Money IndustrySpec : : GetConstructionCost ( ) const
{
2009-11-24 22:15:42 +00:00
/* Building raw industries like secondary uses different price base */
return ( _price [ ( _settings_game . construction . raw_industry_construction = = 1 & & this - > IsRawIndustry ( ) ) ?
PR_BUILD_INDUSTRY_RAW : PR_BUILD_INDUSTRY ] * this - > cost_multiplier ) > > 8 ;
2007-07-06 23:33:16 +01:00
}
2007-11-27 17:13:49 +00:00
2011-01-18 22:31:06 +00:00
/**
* Get the cost for removing this industry
* Take note that the cost will always be zero for non - grf industries .
* Only if the grf author did specified a cost will it be applicable .
* @ return the cost ( inflation corrected etc )
*/
2007-11-27 17:13:49 +00:00
Money IndustrySpec : : GetRemovalCost ( ) const
{
2009-11-24 22:15:42 +00:00
return ( _price [ PR_CLEAR_INDUSTRY ] * this - > removal_cost_multiplier ) > > 8 ;
2007-11-27 17:13:49 +00:00
}
2007-07-06 23:33:16 +01:00
2011-01-18 22:31:06 +00:00
/**
* Determines whether this industrytype uses smooth economy or whether it uses standard / newgrf production changes .
* @ return true if smooth economy is used .
*/
2010-09-26 12:04:30 +01:00
bool IndustrySpec : : UsesSmoothEconomy ( ) const
{
return _settings_game . economy . smooth_economy & &
! ( HasBit ( this - > callback_mask , CBM_IND_PRODUCTION_256_TICKS ) | | HasBit ( this - > callback_mask , CBM_IND_PRODUCTION_CARGO_ARRIVAL ) ) & & // production callbacks
! ( HasBit ( this - > callback_mask , CBM_IND_MONTHLYPROD_CHANGE ) | | HasBit ( this - > callback_mask , CBM_IND_PRODUCTION_CHANGE ) ) ; // production change callbacks
}
2009-02-09 21:20:05 +00:00
static CommandCost TerraformTile_Industry ( TileIndex tile , DoCommandFlag flags , uint z_new , Slope tileh_new )
2007-08-30 18:17:04 +01:00
{
2007-09-14 23:27:40 +01:00
if ( AutoslopeEnabled ( ) ) {
/* We imitate here TTDP's behaviour:
* - Both new and old slope must not be steep .
* - TileMaxZ must not be changed .
* - Allow autoslope by default .
* - Disallow autoslope if callback succeeds and returns non - zero .
*/
Slope tileh_old = GetTileSlope ( tile , NULL ) ;
/* TileMaxZ must not be changed. Slopes must not be steep. */
if ( ! IsSteepSlope ( tileh_old ) & & ! IsSteepSlope ( tileh_new ) & & ( GetTileMaxZ ( tile ) = = z_new + GetSlopeMaxZ ( tileh_new ) ) ) {
const IndustryGfx gfx = GetIndustryGfx ( tile ) ;
const IndustryTileSpec * itspec = GetIndustryTileSpec ( gfx ) ;
/* Call callback 3C 'disable autosloping for industry tiles'. */
2009-09-14 13:22:57 +01:00
if ( HasBit ( itspec - > callback_mask , CBM_INDT_AUTOSLOPE ) ) {
2007-09-14 23:27:40 +01:00
/* If the callback fails, allow autoslope. */
2010-04-05 22:01:02 +01:00
uint16 res = GetIndustryTileCallback ( CBID_INDTILE_AUTOSLOPE , 0 , 0 , gfx , Industry : : GetByTile ( tile ) , tile ) ;
2009-11-24 22:15:42 +00:00
if ( ( res = = 0 ) | | ( res = = CALLBACK_FAILED ) ) return CommandCost ( EXPENSES_CONSTRUCTION , _price [ PR_BUILD_FOUNDATION ] ) ;
2007-09-14 23:27:40 +01:00
} else {
2007-11-15 22:20:33 +00:00
/* allow autoslope */
2009-11-24 22:15:42 +00:00
return CommandCost ( EXPENSES_CONSTRUCTION , _price [ PR_BUILD_FOUNDATION ] ) ;
2007-09-14 23:27:40 +01:00
}
}
}
2007-09-26 15:14:51 +01:00
return DoCommand ( tile , 0 , 0 , flags , CMD_LANDSCAPE_CLEAR ) ;
2007-08-30 18:17:04 +01:00
}
2007-07-06 23:33:16 +01:00
2007-01-10 18:56:51 +00:00
extern const TileTypeProcs _tile_type_industry_procs = {
2009-03-15 00:32:18 +00:00
DrawTile_Industry , // draw_tile_proc
GetSlopeZ_Industry , // get_slope_z_proc
ClearTile_Industry , // clear_tile_proc
2009-06-25 20:23:09 +01:00
AddAcceptedCargo_Industry , // add_accepted_cargo_proc
2009-03-15 00:32:18 +00:00
GetTileDesc_Industry , // get_tile_desc_proc
GetTileTrackStatus_Industry , // get_tile_track_status_proc
ClickTile_Industry , // click_tile_proc
AnimateTile_Industry , // animate_tile_proc
TileLoop_Industry , // tile_loop_proc
ChangeTileOwner_Industry , // change_tile_owner_proc
2010-01-04 21:10:20 +00:00
NULL , // add_produced_cargo_proc
2009-03-15 00:32:18 +00:00
NULL , // vehicle_enter_tile_proc
GetFoundation_Industry , // get_foundation_proc
TerraformTile_Industry , // terraform_tile_proc
2004-08-09 18:04:08 +01:00
} ;