void fire_area (int xx, int yy) { /* this happens when a rocket crashes or on random_fire. */ int x = xx; int y = yy; int size; if (MP_GROUP(x,y) == GROUP_WATER || MP_GROUP(x,y) == GROUP_FIRE) return; if (MP_TYPE(x,y) == CST_USED) { x = MP_INFO(xx,yy).int_1; y = MP_INFO(xx,yy).int_2; } size = MP_SIZE(x,y); /* Destroy the content of the building to prevent special management * when bulldozed. */ /* Kill 'only' half of the people (bulldoze item put them in people_pool) * lincity NG 1.1 and previous killed all the people! */ if ((MP_INFO(x,y).flags & FLAG_FIRE_COVER) !=0) MP_INFO(x,y).population = MP_INFO(x,y).population / 2; else MP_INFO(x,y).population = 0; MP_INFO(x,y).flags = 0; MP_INFO(x,y).int_1 = 0; MP_INFO(x,y).int_2 = 0; MP_INFO(x,y).int_3 = 0; MP_INFO(x,y).int_4 = 0; MP_INFO(x,y).int_5 = 0; MP_INFO(x,y).int_6 = 0; MP_INFO(x,y).int_7 = 0; /* Correctly remove buildings (substations...) and adjust count, * but don't count bulldoze cost * */ adjust_money(+main_groups[MP_GROUP(x,y)].bul_cost); bulldoze_item(x, y); /* put fire */ for (int i = 0; i < size; i++) for (int j = 0; j < size; j++) { bulldoze_mappoint (CST_FIRE_1, x + i, y + j); MP_GROUP(x + i, y + j) = GROUP_FIRE; } /* AL1: is it necessary ? It is the only place in lincity/. with such a call * all other are in lincity-ng/. */ refresh_main_screen (); /* // update transport or we get stuff put in // the area from connected tracks etc. // FIXME: AL1: NG 1.1: do the right thing and/or remove this comment */ }
static object verify_big_or_zero(object big) { int size; if(type_of(big)!=t_bignum) FEerror("Not a bignum",0); size = MP_SIZE(big); if ( size && (MP_SELF(big))[ABS(size)-1]==0) FEerror("badly formed",0); return big; }
void do_bulldoze_area (short fill, int xx, int yy) { int size, x, y; if (MP_TYPE(xx,yy) == CST_USED) { x = MP_INFO(xx,yy).int_1; y = MP_INFO(xx,yy).int_2; } else { x = xx; y = yy; } size = MP_SIZE(x,y); if (MP_GROUP(x,y) == GROUP_SUBSTATION || MP_GROUP(x,y) == GROUP_WINDMILL) remove_a_substation (x, y); else if (MP_GROUP(x,y) == GROUP_MARKET) remove_a_market (x, y); else if (MP_GROUP(x,y) == GROUP_SHANTY) numof_shanties--; else if (MP_GROUP(x,y) == GROUP_COMMUNE) numof_communes--; people_pool += MP_INFO(x,y).population; clear_mappoint (fill, x, y); if (size > 1) /* do size 2 */ { clear_mappoint (fill, x + 1, y); clear_mappoint (fill, x, y + 1); clear_mappoint (fill, x + 1, y + 1); } if (size > 2) /* do size 3 */ { clear_mappoint (fill, x + 2, y); clear_mappoint (fill, x + 2, y + 1); clear_mappoint (fill, x + 2, y + 2); clear_mappoint (fill, x, y + 2); clear_mappoint (fill, x + 1, y + 2); } if (size > 3) /* do size 4 */ { clear_mappoint (fill, x + 3, y); clear_mappoint (fill, x + 3, y + 1); clear_mappoint (fill, x + 3, y + 2); clear_mappoint (fill, x + 3, y + 3); clear_mappoint (fill, x, y + 3); clear_mappoint (fill, x + 1, y + 3); clear_mappoint (fill, x + 2, y + 3); } }
int bulldoze_item (int x, int y) { int g, size; if (MP_TYPE(x,y) == CST_USED) { /* This is considered "improper" input. Silently ignore. */ return -1; } size = MP_SIZE(x,y); g = MP_GROUP(x,y); if (g == GROUP_BARE) { /* Nothing to do. */ return -1; } else if (g == GROUP_SHANTY) { fire_area (x, y); adjust_money(-GROUP_SHANTY_BUL_COST); } else if (g == GROUP_FIRE) { if (MP_INFO(x,y).int_2 >= FIRE_LENGTH) return -1; /* Can't bulldoze ? */ MP_INFO(x,y).int_2 = FIRE_LENGTH + 1; MP_TYPE(x,y) = CST_FIRE_DONE1; MP_GROUP(x,y) = GROUP_BURNT; adjust_money(-GROUP_BURNT_BUL_COST); } else { adjust_money(-main_groups[g].bul_cost); do_bulldoze_area (CST_GREEN, x, y); if (g == GROUP_OREMINE) { int i, j; for (j = 0; j < 4; j++) for (i = 0; i < 4; i++) if (MP_INFO(x + i,y + j).ore_reserve < ORE_RESERVE / 2) do_bulldoze_area (CST_WATER, x + i, y + j); } } return size; /* No longer used... */ }
void do_bulldoze_area (short fill, int xx, int yy) { int size, x, y; if (MP_TYPE(xx,yy) == CST_USED) { x = MP_INFO(xx,yy).int_1; y = MP_INFO(xx,yy).int_2; } else { x = xx; y = yy; } size = MP_SIZE(x,y); for (int i = 0; i < size; i++) for (int j = 0; j < size; j++) bulldoze_mappoint (fill, x+i, y+j); }
int put_stuff (int x, int y, int stuff, int stuff_type) { int res = 0; short *type = &MP_TYPE(x,y); Map_Point_Info *minfo = &MP_INFO(x,y); switch (MP_SIZE(x,y)) { case 2: res = put_stuff2 (minfo, type, stuff, stuff_type); break; case 3: res = put_stuff3 (minfo, type, stuff, stuff_type); break; case 4: res = put_stuff4 (minfo, type, stuff, stuff_type); break; default: do_error ("Bad area size in put_stuff()"); } return res; }
int get_stuff (int x, int y, int stuff, int stuff_type) { int res = 0; Map_Point_Info *minfo = &MP_INFO(x,y); switch (MP_SIZE(x,y)) { case 2: res = get_stuff2 (minfo, stuff, stuff_type); break; case 3: res = get_stuff3 (minfo, stuff, stuff_type); break; case 4: res = get_stuff4 (minfo, stuff, stuff_type); break; default: do_error ("Bad area size in get_stuff()"); } return (res); }
int bulldoze_item (int x, int y) { int g, size; if (MP_TYPE(x,y) == CST_USED) { /* This is considered "improper" input. Silently ignore. */ #ifdef DEBUG fprintf(stderr," try to improperly bulldoze_item CST_USED\n"); #endif return -1; } size = MP_SIZE(x,y); g = MP_GROUP(x,y); people_pool += MP_INFO(x,y).population; if (g == GROUP_DESERT) { /* Nothing to do. */ return -1; } else if (g == GROUP_SHANTY) { remove_a_shanty(x, y); adjust_money(-GROUP_SHANTY_BUL_COST); numof_shanties--; } else if (g == GROUP_FIRE) { if (MP_INFO(x,y).int_2 >= FIRE_LENGTH) return -1; /* Can't bulldoze ? */ MP_INFO(x,y).int_2 = FIRE_LENGTH + 1; MP_TYPE(x,y) = CST_FIRE_DONE1; MP_GROUP(x,y) = GROUP_BURNT; adjust_money(-GROUP_BURNT_BUL_COST); } else { adjust_money(-main_groups[g].bul_cost); if (g == GROUP_COMMUNE) numof_communes--; if (g == GROUP_MARKET) remove_a_market (x, y); if (g == GROUP_SUBSTATION || g == GROUP_WINDMILL) remove_a_substation (x, y); if (g == GROUP_OREMINE) { int i, j; for (j = 0; j < 4; j++) for (i = 0; i < 4; i++) if (MP_INFO(x + i,y + j).ore_reserve < ORE_RESERVE / 2) do_bulldoze_area (CST_WATER, x + i, y + j); } else { /* keep compatibility for saving pre_waterwell loaded game */ if (use_waterwell) do_bulldoze_area (CST_DESERT, x, y); else do_bulldoze_area (CST_GREEN, x, y); } } /* Tell mps about it, in case its selected */ mps_update(); return size; /* No longer used... */ }
void do_organic_farm(int x, int y) { /* // MP_INFO(x,y) // int_1 unused // int_2 unused // int_3 is the food sold count so far this year. // int_4 is the food made last year. // int_5 is the random crop rotation key. // int_6 is the random month stagger, so they don't all flash at once // int_7 is the jobs stored at the farm * * MP_INFO(x+1,y) stores additional info * int_1 reserved (=x) * int_2 reserved (=y) * int_3 max possible production (assuming 100% water and power) * int_4 number of 1x1 tiles with underground water inside the farm * int_5 current production * // MP_TECH is the tech level of the farm when built // MP_ANIM FIXME, this is unused */ int i; int has_power = false; int used_jobs = 0; int tech_bonus = (int)(((double)MP_TECH(x, y) * ORGANIC_FARM_FOOD_OUTPUT) / MAX_TECH_LEVEL); MP_INFO(x + 1, y).int_3 = ORGANIC_FARM_FOOD_OUTPUT + tech_bonus; /* Animation */ if (MP_INFO(x, y).int_5 == 0) { /* this should be done when we create the area! */ MP_INFO(x, y).int_5 = (rand() % 4) + 1; MP_INFO(x, y).int_6 = rand() % 300; /* AL1 will be sooner or later redefined as %100. see below */ } /* check jobs */ if (MP_INFO(x, y).int_7 < FARM_JOBS_USED) { if (get_jobs(x, y, FARM_JOBS_USED) != 0) MP_INFO(x, y).int_7 += FARM_JOBS_USED; /* adding if (get_jobs ... /2) would allow to have some jobs stored at farm, * so would smooth the behavior and make farms more resistant to job penury. * Currently keep previous behavior. */ else if (get_jobs(x, y, FARM_JOBS_USED / 4) != 0) MP_INFO(x, y).int_7 += FARM_JOBS_USED / 4; else if (get_jobs(x, y, 1) != 0) MP_INFO(x, y).int_7 += 1; } /* check power */ MP_INFO(x, y).flags &= (0xffffffff - FLAG_POWERED); if (MP_INFO(x, y).int_7 >= 1) { /* There are jobs to do some production, so check for power */ if (get_power(x, y, ORG_FARM_POWER_REC, 0) != 0) { MP_INFO(x, y).flags |= FLAG_POWERED; has_power = true; } } /* Produce some food */ int prod = 0; if (MP_INFO(x, y).int_7 >= FARM_JOBS_USED) { used_jobs = FARM_JOBS_USED; if (has_power) { prod = ORGANIC_FARM_FOOD_OUTPUT + tech_bonus; } else { prod = ORGANIC_FARM_FOOD_OUTPUT / 4; } } else if (MP_INFO(x, y).int_7 >= FARM_JOBS_USED / 4) { used_jobs = FARM_JOBS_USED / 4; if (has_power) { prod = ORGANIC_FARM_FOOD_OUTPUT + tech_bonus / 4; } else { prod = ORGANIC_FARM_FOOD_OUTPUT / (4 * 4); } } else if (MP_INFO(x, y).int_7 >= 1) { /* got 1 job */ used_jobs = 1; if (has_power) { prod = ORGANIC_FARM_FOOD_OUTPUT + tech_bonus / 8; } else { /* AL1 "small ouch": * without power output with 1 job is bigger than output with 3 ! * 3 = FARMS_JOBS_USED / 4 * ORGANIC_FARM_FOOD_OUTPUT = 550 currently (ng_1.1) */ prod = 30 + ORGANIC_FARM_FOOD_OUTPUT / (4 * 8); } } else { /* AL1 : the farm gives very small amount of food without job. * ? Probably needed for start ? * ? Useful to prevent starvation when no jobs ? * The various buildings are "done" in random order, * so it should be ok without this. */ put_food(x, y, 30); /* note that this does not generate revenu int_3) */ } /* Check underground water, and reduce production accordingly */ if (use_waterwell) { // TODO No need to count each time. Should be done at build time, and stored int w = 0; int n = 0; for (int i = 0; i < MP_SIZE(x, y); i++) { for (int j = 0; j < MP_SIZE(x, y); j++) { n++; if (HAS_UGWATER(x + i, y + j)) w++; } } prod = (prod * w) / n; MP_INFO(x + 1, y).int_4 = w; } MP_INFO(x + 1, y).int_5 = prod; if (prod != 0) { if (put_food(x, y, prod) != 0) { MP_INFO(x, y).int_3++; MP_INFO(x, y).int_7 -= used_jobs; } } if ((total_time & 0x7f) == 0) if ((MP_INFO(x, y).flags & FLAG_POWERED) != 0) get_waste(x, y, 0x80 * ORG_FARM_WASTE_GET); if ((total_time % 1200) == 0) { MP_INFO(x, y).int_4 = MP_INFO(x, y).int_3; MP_INFO(x, y).int_3 = 0; } i = (total_time + MP_INFO(x, y).int_5 * 1200 + MP_INFO(x, y).int_6) % 4800; if (i % 300 == 0) { i /= 300; if ( MP_INFO(x, y).int_4 > MIN_FOOD_SOLD_FOR_ANIM) { if (i % 4 == 0) { MP_INFO(x, y).int_6 = rand() % 100; /* AL1: initially defined as %300 */ } switch (i) { case (0): MP_TYPE(x, y) = CST_FARM_O3; break; case (1): MP_TYPE(x, y) = CST_FARM_O3; break; case (2): MP_TYPE(x, y) = CST_FARM_O3; break; case (3): MP_TYPE(x, y) = CST_FARM_O3; break; case (4): MP_TYPE(x, y) = CST_FARM_O7; break; case (5): MP_TYPE(x, y) = CST_FARM_O7; break; case (6): MP_TYPE(x, y) = CST_FARM_O7; break; case (7): MP_TYPE(x, y) = CST_FARM_O7; break; case (8): MP_TYPE(x, y) = CST_FARM_O11; break; case (9): MP_TYPE(x, y) = CST_FARM_O11; break; case (10): MP_TYPE(x, y) = CST_FARM_O11; break; case (11): MP_TYPE(x, y) = CST_FARM_O11; break; case (12): MP_TYPE(x, y) = CST_FARM_O15; break; case (13): MP_TYPE(x, y) = CST_FARM_O15; break; case (14): MP_TYPE(x, y) = CST_FARM_O15; break; case (15): MP_TYPE(x, y) = CST_FARM_O15; break; } } else { MP_TYPE(x, y) = CST_FARM_O0; } } }