src/disaster_cmd.cpp
changeset 9336 3f75a2c5e0d3
parent 9289 92f1249c304e
child 10272 2014f0bdc800
equal deleted inserted replaced
9335:18d3658adc60 9336:3f75a2c5e0d3
   204 	byte z;
   204 	byte z;
   205 	TileIndex tile;
   205 	TileIndex tile;
   206 
   206 
   207 	v->tick_counter++;
   207 	v->tick_counter++;
   208 
   208 
   209 	if (v->current_order.dest < 2) {
   209 	if (v->current_order.GetDestination() < 2) {
   210 		if (HasBit(v->tick_counter, 0)) return;
   210 		if (HasBit(v->tick_counter, 0)) return;
   211 
   211 
   212 		GetNewVehiclePosResult gp = GetNewVehiclePos(v);
   212 		GetNewVehiclePosResult gp = GetNewVehiclePos(v);
   213 
   213 
   214 		SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
   214 		SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
   215 
   215 
   216 		if (v->current_order.dest == 1) {
   216 		if (v->current_order.GetDestination() == 1) {
   217 			if (++v->age == 38) {
   217 			if (++v->age == 38) {
   218 				v->current_order.dest = 2;
   218 				v->current_order.SetDestination(2);
   219 				v->age = 0;
   219 				v->age = 0;
   220 			}
   220 			}
   221 
   221 
   222 			if (GB(v->tick_counter, 0, 3) == 0) CreateEffectVehicleRel(v, 0, -17, 2, EV_SMOKE);
   222 			if (GB(v->tick_counter, 0, 3) == 0) CreateEffectVehicleRel(v, 0, -17, 2, EV_SMOKE);
   223 
   223 
   224 		} else if (v->current_order.dest == 0) {
   224 		} else if (v->current_order.GetDestination() == 0) {
   225 			tile = v->tile;
   225 			tile = v->tile;
   226 
   226 
   227 			if (IsValidTile(tile) &&
   227 			if (IsValidTile(tile) &&
   228 					IsTileType(tile, MP_STATION) &&
   228 					IsTileType(tile, MP_STATION) &&
   229 					IsAirport(tile) &&
   229 					IsAirport(tile) &&
   230 					IsHumanPlayer(GetTileOwner(tile))) {
   230 					IsHumanPlayer(GetTileOwner(tile))) {
   231 				v->current_order.dest = 1;
   231 				v->current_order.SetDestination(1);
   232 				v->age = 0;
   232 				v->age = 0;
   233 
   233 
   234 				SetDParam(0, GetStationIndex(tile));
   234 				SetDParam(0, GetStationIndex(tile));
   235 				AddNewsItem(STR_B000_ZEPPELIN_DISASTER_AT,
   235 				AddNewsItem(STR_B000_ZEPPELIN_DISASTER_AT,
   236 					NM_THIN, NF_VIEWPORT | NF_VEHICLE, NT_ACCIDENT, DNC_NONE,
   236 					NM_THIN, NF_VIEWPORT | NF_VEHICLE, NT_ACCIDENT, DNC_NONE,
   241 
   241 
   242 		if (v->y_pos >= ((int)MapSizeY() + 9) * TILE_SIZE - 1) DeleteDisasterVeh(v);
   242 		if (v->y_pos >= ((int)MapSizeY() + 9) * TILE_SIZE - 1) DeleteDisasterVeh(v);
   243 		return;
   243 		return;
   244 	}
   244 	}
   245 
   245 
   246 	if (v->current_order.dest > 2) {
   246 	if (v->current_order.GetDestination() > 2) {
   247 		if (++v->age <= 13320) return;
   247 		if (++v->age <= 13320) return;
   248 
   248 
   249 		tile = v->tile;
   249 		tile = v->tile;
   250 
   250 
   251 		if (IsValidTile(tile) &&
   251 		if (IsValidTile(tile) &&
   282 				GB(r, 4, 4) - 7,
   282 				GB(r, 4, 4) - 7,
   283 				GB(r, 8, 3) + 5,
   283 				GB(r, 8, 3) + 5,
   284 				EV_EXPLOSION_SMALL);
   284 				EV_EXPLOSION_SMALL);
   285 		}
   285 		}
   286 	} else if (v->age == 350) {
   286 	} else if (v->age == 350) {
   287 		v->current_order.dest = 3;
   287 		v->current_order.SetDestination(3);
   288 		v->age = 0;
   288 		v->age = 0;
   289 	}
   289 	}
   290 
   290 
   291 	tile = v->tile;
   291 	tile = v->tile;
   292 	if (IsValidTile(tile) &&
   292 	if (IsValidTile(tile) &&
   310 	uint dist;
   310 	uint dist;
   311 	byte z;
   311 	byte z;
   312 
   312 
   313 	v->u.disaster.image_override = (HasBit(++v->tick_counter, 3)) ? SPR_UFO_SMALL_SCOUT_DARKER : SPR_UFO_SMALL_SCOUT;
   313 	v->u.disaster.image_override = (HasBit(++v->tick_counter, 3)) ? SPR_UFO_SMALL_SCOUT_DARKER : SPR_UFO_SMALL_SCOUT;
   314 
   314 
   315 	if (v->current_order.dest == 0) {
   315 	if (v->current_order.GetDestination() == 0) {
   316 		/* Fly around randomly */
   316 		/* Fly around randomly */
   317 		int x = TileX(v->dest_tile) * TILE_SIZE;
   317 		int x = TileX(v->dest_tile) * TILE_SIZE;
   318 		int y = TileY(v->dest_tile) * TILE_SIZE;
   318 		int y = TileY(v->dest_tile) * TILE_SIZE;
   319 		if (Delta(x, v->x_pos) + Delta(y, v->y_pos) >= TILE_SIZE) {
   319 		if (Delta(x, v->x_pos) + Delta(y, v->y_pos) >= TILE_SIZE) {
   320 			v->direction = GetDirectionTowards(v, x, y);
   320 			v->direction = GetDirectionTowards(v, x, y);
   324 		}
   324 		}
   325 		if (++v->age < 6) {
   325 		if (++v->age < 6) {
   326 			v->dest_tile = RandomTile();
   326 			v->dest_tile = RandomTile();
   327 			return;
   327 			return;
   328 		}
   328 		}
   329 		v->current_order.dest = 1;
   329 		v->current_order.SetDestination(1);
   330 
   330 
   331 		FOR_ALL_VEHICLES(u) {
   331 		FOR_ALL_VEHICLES(u) {
   332 			if (u->type == VEH_ROAD && IsHumanPlayer(u->owner)) {
   332 			if (u->type == VEH_ROAD && IsHumanPlayer(u->owner)) {
   333 				v->dest_tile = u->index;
   333 				v->dest_tile = u->index;
   334 				v->age = 0;
   334 				v->age = 0;
   403  */
   403  */
   404 static void DisasterTick_Airplane(Vehicle *v)
   404 static void DisasterTick_Airplane(Vehicle *v)
   405 {
   405 {
   406 	v->tick_counter++;
   406 	v->tick_counter++;
   407 	v->u.disaster.image_override =
   407 	v->u.disaster.image_override =
   408 		(v->current_order.dest == 1 && HasBit(v->tick_counter, 2)) ? SPR_F_15_FIRING : 0;
   408 		(v->current_order.GetDestination() == 1 && HasBit(v->tick_counter, 2)) ? SPR_F_15_FIRING : 0;
   409 
   409 
   410 	GetNewVehiclePosResult gp = GetNewVehiclePos(v);
   410 	GetNewVehiclePosResult gp = GetNewVehiclePos(v);
   411 	SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
   411 	SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
   412 
   412 
   413 	if (gp.x < (-10 * TILE_SIZE)) {
   413 	if (gp.x < (-10 * TILE_SIZE)) {
   414 		DeleteDisasterVeh(v);
   414 		DeleteDisasterVeh(v);
   415 		return;
   415 		return;
   416 	}
   416 	}
   417 
   417 
   418 	if (v->current_order.dest == 2) {
   418 	if (v->current_order.GetDestination() == 2) {
   419 		if (GB(v->tick_counter, 0, 2) == 0) {
   419 		if (GB(v->tick_counter, 0, 2) == 0) {
   420 			Industry *i = GetIndustry(v->dest_tile);
   420 			Industry *i = GetIndustry(v->dest_tile);
   421 			int x = TileX(i->xy) * TILE_SIZE;
   421 			int x = TileX(i->xy) * TILE_SIZE;
   422 			int y = TileY(i->xy) * TILE_SIZE;
   422 			int y = TileY(i->xy) * TILE_SIZE;
   423 			uint32 r = Random();
   423 			uint32 r = Random();
   426 				GB(r,  0, 6) + x,
   426 				GB(r,  0, 6) + x,
   427 				GB(r,  6, 6) + y,
   427 				GB(r,  6, 6) + y,
   428 				GB(r, 12, 4),
   428 				GB(r, 12, 4),
   429 				EV_EXPLOSION_SMALL);
   429 				EV_EXPLOSION_SMALL);
   430 
   430 
   431 			if (++v->age >= 55) v->current_order.dest = 3;
   431 			if (++v->age >= 55) v->current_order.SetDestination(3);
   432 		}
   432 		}
   433 	} else if (v->current_order.dest == 1) {
   433 	} else if (v->current_order.GetDestination() == 1) {
   434 		if (++v->age == 112) {
   434 		if (++v->age == 112) {
   435 			Industry *i;
   435 			Industry *i;
   436 
   436 
   437 			v->current_order.dest = 2;
   437 			v->current_order.SetDestination(2);
   438 			v->age = 0;
   438 			v->age = 0;
   439 
   439 
   440 			i = GetIndustry(v->dest_tile);
   440 			i = GetIndustry(v->dest_tile);
   441 			DestructIndustry(i);
   441 			DestructIndustry(i);
   442 
   442 
   443 			SetDParam(0, i->town->index);
   443 			SetDParam(0, i->town->index);
   444 			AddNewsItem(STR_B002_OIL_REFINERY_EXPLOSION, NM_THIN, NF_VIEWPORT | NF_TILE, NT_ACCIDENT, DNC_NONE, i->xy, 0);
   444 			AddNewsItem(STR_B002_OIL_REFINERY_EXPLOSION, NM_THIN, NF_VIEWPORT | NF_TILE, NT_ACCIDENT, DNC_NONE, i->xy, 0);
   445 			SndPlayTileFx(SND_12_EXPLOSION, i->xy);
   445 			SndPlayTileFx(SND_12_EXPLOSION, i->xy);
   446 		}
   446 		}
   447 	} else if (v->current_order.dest == 0) {
   447 	} else if (v->current_order.GetDestination() == 0) {
   448 		int x, y;
   448 		int x, y;
   449 		TileIndex tile;
   449 		TileIndex tile;
   450 		uint ind;
   450 		uint ind;
   451 
   451 
   452 		x = v->x_pos - (15 * TILE_SIZE);
   452 		x = v->x_pos - (15 * TILE_SIZE);
   459 
   459 
   460 		ind = GetIndustryIndex(tile);
   460 		ind = GetIndustryIndex(tile);
   461 		v->dest_tile = ind;
   461 		v->dest_tile = ind;
   462 
   462 
   463 		if (GetIndustrySpec(GetIndustry(ind)->type)->behaviour & INDUSTRYBEH_AIRPLANE_ATTACKS) {
   463 		if (GetIndustrySpec(GetIndustry(ind)->type)->behaviour & INDUSTRYBEH_AIRPLANE_ATTACKS) {
   464 			v->current_order.dest = 1;
   464 			v->current_order.SetDestination(1);
   465 			v->age = 0;
   465 			v->age = 0;
   466 		}
   466 		}
   467 	}
   467 	}
   468 }
   468 }
   469 
   469 
   476  */
   476  */
   477 static void DisasterTick_Helicopter(Vehicle *v)
   477 static void DisasterTick_Helicopter(Vehicle *v)
   478 {
   478 {
   479 	v->tick_counter++;
   479 	v->tick_counter++;
   480 	v->u.disaster.image_override =
   480 	v->u.disaster.image_override =
   481 		(v->current_order.dest == 1 && HasBit(v->tick_counter, 2)) ? SPR_AH_64A_FIRING : 0;
   481 		(v->current_order.GetDestination() == 1 && HasBit(v->tick_counter, 2)) ? SPR_AH_64A_FIRING : 0;
   482 
   482 
   483 	GetNewVehiclePosResult gp = GetNewVehiclePos(v);
   483 	GetNewVehiclePosResult gp = GetNewVehiclePos(v);
   484 	SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
   484 	SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
   485 
   485 
   486 	if (gp.x > (int)MapSizeX() * TILE_SIZE + 9 * TILE_SIZE - 1) {
   486 	if (gp.x > (int)MapSizeX() * TILE_SIZE + 9 * TILE_SIZE - 1) {
   487 		DeleteDisasterVeh(v);
   487 		DeleteDisasterVeh(v);
   488 		return;
   488 		return;
   489 	}
   489 	}
   490 
   490 
   491 	if (v->current_order.dest == 2) {
   491 	if (v->current_order.GetDestination() == 2) {
   492 		if (GB(v->tick_counter, 0, 2) == 0) {
   492 		if (GB(v->tick_counter, 0, 2) == 0) {
   493 			Industry *i = GetIndustry(v->dest_tile);
   493 			Industry *i = GetIndustry(v->dest_tile);
   494 			int x = TileX(i->xy) * TILE_SIZE;
   494 			int x = TileX(i->xy) * TILE_SIZE;
   495 			int y = TileY(i->xy) * TILE_SIZE;
   495 			int y = TileY(i->xy) * TILE_SIZE;
   496 			uint32 r = Random();
   496 			uint32 r = Random();
   499 				GB(r,  0, 6) + x,
   499 				GB(r,  0, 6) + x,
   500 				GB(r,  6, 6) + y,
   500 				GB(r,  6, 6) + y,
   501 				GB(r, 12, 4),
   501 				GB(r, 12, 4),
   502 				EV_EXPLOSION_SMALL);
   502 				EV_EXPLOSION_SMALL);
   503 
   503 
   504 			if (++v->age >= 55) v->current_order.dest = 3;
   504 			if (++v->age >= 55) v->current_order.SetDestination(3);
   505 		}
   505 		}
   506 	} else if (v->current_order.dest == 1) {
   506 	} else if (v->current_order.GetDestination() == 1) {
   507 		if (++v->age == 112) {
   507 		if (++v->age == 112) {
   508 			Industry *i;
   508 			Industry *i;
   509 
   509 
   510 			v->current_order.dest = 2;
   510 			v->current_order.SetDestination(2);
   511 			v->age = 0;
   511 			v->age = 0;
   512 
   512 
   513 			i = GetIndustry(v->dest_tile);
   513 			i = GetIndustry(v->dest_tile);
   514 			DestructIndustry(i);
   514 			DestructIndustry(i);
   515 
   515 
   516 			SetDParam(0, i->town->index);
   516 			SetDParam(0, i->town->index);
   517 			AddNewsItem(STR_B003_FACTORY_DESTROYED_IN_SUSPICIOUS, NM_THIN, NF_VIEWPORT | NF_TILE, NT_ACCIDENT, DNC_NONE, i->xy, 0);
   517 			AddNewsItem(STR_B003_FACTORY_DESTROYED_IN_SUSPICIOUS, NM_THIN, NF_VIEWPORT | NF_TILE, NT_ACCIDENT, DNC_NONE, i->xy, 0);
   518 			SndPlayTileFx(SND_12_EXPLOSION, i->xy);
   518 			SndPlayTileFx(SND_12_EXPLOSION, i->xy);
   519 		}
   519 		}
   520 	} else if (v->current_order.dest == 0) {
   520 	} else if (v->current_order.GetDestination() == 0) {
   521 		int x, y;
   521 		int x, y;
   522 		TileIndex tile;
   522 		TileIndex tile;
   523 		uint ind;
   523 		uint ind;
   524 
   524 
   525 		x = v->x_pos + (15 * TILE_SIZE);
   525 		x = v->x_pos + (15 * TILE_SIZE);
   532 
   532 
   533 		ind = GetIndustryIndex(tile);
   533 		ind = GetIndustryIndex(tile);
   534 		v->dest_tile = ind;
   534 		v->dest_tile = ind;
   535 
   535 
   536 		if (GetIndustrySpec(GetIndustry(ind)->type)->behaviour & INDUSTRYBEH_CHOPPER_ATTACKS) {
   536 		if (GetIndustrySpec(GetIndustry(ind)->type)->behaviour & INDUSTRYBEH_CHOPPER_ATTACKS) {
   537 			v->current_order.dest = 1;
   537 			v->current_order.SetDestination(1);
   538 			v->age = 0;
   538 			v->age = 0;
   539 		}
   539 		}
   540 	}
   540 	}
   541 }
   541 }
   542 
   542 
   566 	TileIndex tile;
   566 	TileIndex tile;
   567 	TileIndex tile_org;
   567 	TileIndex tile_org;
   568 
   568 
   569 	v->tick_counter++;
   569 	v->tick_counter++;
   570 
   570 
   571 	if (v->current_order.dest == 1) {
   571 	if (v->current_order.GetDestination() == 1) {
   572 		int x = TileX(v->dest_tile) * TILE_SIZE + TILE_SIZE / 2;
   572 		int x = TileX(v->dest_tile) * TILE_SIZE + TILE_SIZE / 2;
   573 		int y = TileY(v->dest_tile) * TILE_SIZE + TILE_SIZE / 2;
   573 		int y = TileY(v->dest_tile) * TILE_SIZE + TILE_SIZE / 2;
   574 		if (Delta(v->x_pos, x) + Delta(v->y_pos, y) >= 8) {
   574 		if (Delta(v->x_pos, x) + Delta(v->y_pos, y) >= 8) {
   575 			v->direction = GetDirectionTowards(v, x, y);
   575 			v->direction = GetDirectionTowards(v, x, y);
   576 
   576 
   583 		if (z < v->z_pos) {
   583 		if (z < v->z_pos) {
   584 			SetDisasterVehiclePos(v, v->x_pos, v->y_pos, v->z_pos - 1);
   584 			SetDisasterVehiclePos(v, v->x_pos, v->y_pos, v->z_pos - 1);
   585 			return;
   585 			return;
   586 		}
   586 		}
   587 
   587 
   588 		v->current_order.dest = 2;
   588 		v->current_order.SetDestination(2);
   589 
   589 
   590 		FOR_ALL_VEHICLES(u) {
   590 		FOR_ALL_VEHICLES(u) {
   591 			if (u->type == VEH_TRAIN || u->type == VEH_ROAD) {
   591 			if (u->type == VEH_TRAIN || u->type == VEH_ROAD) {
   592 				if (Delta(u->x_pos, v->x_pos) + Delta(u->y_pos, v->y_pos) <= 12 * TILE_SIZE) {
   592 				if (Delta(u->x_pos, v->x_pos) + Delta(u->y_pos, v->y_pos) <= 12 * TILE_SIZE) {
   593 					u->breakdown_ctr = 5;
   593 					u->breakdown_ctr = 5;
   616 		if (w == NULL) return;
   616 		if (w == NULL) return;
   617 
   617 
   618 		u->SetNext(w);
   618 		u->SetNext(w);
   619 		InitializeDisasterVehicle(w, -6 * TILE_SIZE, v->y_pos, 0, DIR_SW, ST_Big_Ufo_Destroyer_Shadow);
   619 		InitializeDisasterVehicle(w, -6 * TILE_SIZE, v->y_pos, 0, DIR_SW, ST_Big_Ufo_Destroyer_Shadow);
   620 		w->vehstatus |= VS_SHADOW;
   620 		w->vehstatus |= VS_SHADOW;
   621 	} else if (v->current_order.dest == 0) {
   621 	} else if (v->current_order.GetDestination() == 0) {
   622 		int x = TileX(v->dest_tile) * TILE_SIZE;
   622 		int x = TileX(v->dest_tile) * TILE_SIZE;
   623 		int y = TileY(v->dest_tile) * TILE_SIZE;
   623 		int y = TileY(v->dest_tile) * TILE_SIZE;
   624 		if (Delta(x, v->x_pos) + Delta(y, v->y_pos) >= TILE_SIZE) {
   624 		if (Delta(x, v->x_pos) + Delta(y, v->y_pos) >= TILE_SIZE) {
   625 			v->direction = GetDirectionTowards(v, x, y);
   625 			v->direction = GetDirectionTowards(v, x, y);
   626 			GetNewVehiclePosResult gp = GetNewVehiclePos(v);
   626 			GetNewVehiclePosResult gp = GetNewVehiclePos(v);
   630 
   630 
   631 		if (++v->age < 6) {
   631 		if (++v->age < 6) {
   632 			v->dest_tile = RandomTile();
   632 			v->dest_tile = RandomTile();
   633 			return;
   633 			return;
   634 		}
   634 		}
   635 		v->current_order.dest = 1;
   635 		v->current_order.SetDestination(1);
   636 
   636 
   637 		tile_org = tile = RandomTile();
   637 		tile_org = tile = RandomTile();
   638 		do {
   638 		do {
   639 			if (IsTileType(tile, MP_RAILWAY) &&
   639 			if (IsTileType(tile, MP_RAILWAY) &&
   640 					IsPlainRailTile(tile) &&
   640 					IsPlainRailTile(tile) &&
   667 	if (gp.x > (int)MapSizeX() * TILE_SIZE + 9 * TILE_SIZE - 1) {
   667 	if (gp.x > (int)MapSizeX() * TILE_SIZE + 9 * TILE_SIZE - 1) {
   668 		DeleteDisasterVeh(v);
   668 		DeleteDisasterVeh(v);
   669 		return;
   669 		return;
   670 	}
   670 	}
   671 
   671 
   672 	if (v->current_order.dest == 0) {
   672 	if (v->current_order.GetDestination() == 0) {
   673 		u = GetVehicle(v->u.disaster.big_ufo_destroyer_target);
   673 		u = GetVehicle(v->u.disaster.big_ufo_destroyer_target);
   674 		if (Delta(v->x_pos, u->x_pos) > TILE_SIZE) return;
   674 		if (Delta(v->x_pos, u->x_pos) > TILE_SIZE) return;
   675 		v->current_order.dest = 1;
   675 		v->current_order.SetDestination(1);
   676 
   676 
   677 		CreateEffectVehicleRel(u, 0, 7, 8, EV_EXPLOSION_LARGE);
   677 		CreateEffectVehicleRel(u, 0, 7, 8, EV_EXPLOSION_LARGE);
   678 		SndPlayVehicleFx(SND_12_EXPLOSION, u);
   678 		SndPlayVehicleFx(SND_12_EXPLOSION, u);
   679 
   679 
   680 		DeleteDisasterVeh(u);
   680 		DeleteDisasterVeh(u);