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
  */
}
Exemple #2
0
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;
        }
    }
}