disaster_cmd.c
changeset 555 02df8a1b7f33
parent 541 625227bb2a3d
child 679 04ca2cd69420
equal deleted inserted replaced
554:a4ba0fbbf018 555:02df8a1b7f33
    77 	v->sprite_height = 2;
    77 	v->sprite_height = 2;
    78 	v->z_height = 5;
    78 	v->z_height = 5;
    79 	v->owner = OWNER_NONE;
    79 	v->owner = OWNER_NONE;
    80 	v->vehstatus = VS_UNCLICKABLE;
    80 	v->vehstatus = VS_UNCLICKABLE;
    81 	v->u.disaster.image_override = 0;
    81 	v->u.disaster.image_override = 0;
    82 	v->next_order = 0;
    82 	v->current_order.type = OT_NOTHING;
       
    83 	v->current_order.flags = 0;
       
    84 	v->current_order.station = 0;
    83 
    85 
    84 	DisasterVehicleUpdateImage(v);
    86 	DisasterVehicleUpdateImage(v);
    85 	VehiclePositionChanged(v);
    87 	VehiclePositionChanged(v);
    86 	BeginVehicleMove(v);
    88 	BeginVehicleMove(v);
    87 	EndVehicleMove(v);
    89 	EndVehicleMove(v);
   139 	byte z;
   141 	byte z;
   140 	uint tile;
   142 	uint tile;
   141 
   143 
   142 	++v->tick_counter;
   144 	++v->tick_counter;
   143 
   145 
   144 	if (v->next_order < 2) {
   146 	if (v->current_order.station < 2) {
   145 		if (v->tick_counter&1)
   147 		if (v->tick_counter&1)
   146 			return;
   148 			return;
   147 
   149 
   148 		GetNewVehiclePos(v, &gp);
   150 		GetNewVehiclePos(v, &gp);
   149 
   151 
   150 		SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
   152 		SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
   151 
   153 
   152 		if (v->next_order == 1) {
   154 		if (v->current_order.station == 1) {
   153 			if (++v->age == 38) {
   155 			if (++v->age == 38) {
   154 				v->next_order = 2;
   156 				v->current_order.station = 2;
   155 				v->age = 0;
   157 				v->age = 0;
   156 			}
   158 			}
   157 
   159 
   158 			if ((v->tick_counter&7)==0) {
   160 			if ((v->tick_counter&7)==0) {
   159 				CreateEffectVehicleRel(v, 0, -17, 2, EV_SMOKE_3);
   161 				CreateEffectVehicleRel(v, 0, -17, 2, EV_SMOKE_3);
   160 			}
   162 			}
   161 		} else if (v->next_order == 0) {
   163 		} else if (v->current_order.station == 0) {
   162 			tile = v->tile; /**/
   164 			tile = v->tile; /**/
   163 
   165 
   164 			if (IS_TILETYPE(tile, MP_STATION) &&
   166 			if (IS_TILETYPE(tile, MP_STATION) &&
   165 				IS_BYTE_INSIDE(_map5[tile], 8, 0x43) &&
   167 				IS_BYTE_INSIDE(_map5[tile], 8, 0x43) &&
   166 				IS_HUMAN_PLAYER(_map_owner[tile])) {
   168 				IS_HUMAN_PLAYER(_map_owner[tile])) {
   167 
   169 
   168 				v->next_order = 1;
   170 				v->current_order.station = 1;
   169 				v->age = 0;
   171 				v->age = 0;
   170 
   172 
   171 				SetDParam(0, _map2[tile]);
   173 				SetDParam(0, _map2[tile]);
   172 				AddNewsItem(STR_B000_ZEPPELIN_DISASTER_AT,
   174 				AddNewsItem(STR_B000_ZEPPELIN_DISASTER_AT,
   173 					NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_VEHICLE, NT_ACCIDENT, 0),
   175 					NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_VEHICLE, NT_ACCIDENT, 0),
   178 		if (v->y_pos >= (TILES_Y+9) * 16 - 1)
   180 		if (v->y_pos >= (TILES_Y+9) * 16 - 1)
   179 			DeleteDisasterVeh(v);
   181 			DeleteDisasterVeh(v);
   180 		return;
   182 		return;
   181 	}
   183 	}
   182 
   184 
   183 	if (v->next_order > 2) {
   185 	if (v->current_order.station > 2) {
   184 		if (++v->age <= 13320)
   186 		if (++v->age <= 13320)
   185 			return;
   187 			return;
   186 
   188 
   187 		tile = v->tile; /**/
   189 		tile = v->tile; /**/
   188 
   190 
   221 				-7 + (r>>4&0xF),
   223 				-7 + (r>>4&0xF),
   222 				5 + (r>>8&0x7),
   224 				5 + (r>>8&0x7),
   223 				EV_DEMOLISH);
   225 				EV_DEMOLISH);
   224 		}
   226 		}
   225 	} else if (v->age == 350) {
   227 	} else if (v->age == 350) {
   226 		v->next_order = 3;
   228 		v->current_order.station = 3;
   227 		v->age = 0;
   229 		v->age = 0;
   228 	}
   230 	}
   229 
   231 
   230 	tile = v->tile;/**/
   232 	tile = v->tile;/**/
   231 	if (IS_TILETYPE(tile, MP_STATION) &&
   233 	if (IS_TILETYPE(tile, MP_STATION) &&
   246 	uint dist;
   248 	uint dist;
   247 	byte z;
   249 	byte z;
   248 
   250 
   249 	v->u.disaster.image_override = (++v->tick_counter & 8) ? 0xF45 : 0xF44;
   251 	v->u.disaster.image_override = (++v->tick_counter & 8) ? 0xF45 : 0xF44;
   250 
   252 
   251 	if (v->next_order == 0) {
   253 	if (v->current_order.station == 0) {
   252 // fly around randomly
   254 // fly around randomly
   253 		int x = GET_TILE_X(v->dest_tile)*16;
   255 		int x = GET_TILE_X(v->dest_tile)*16;
   254 		int y = GET_TILE_Y(v->dest_tile)*16;
   256 		int y = GET_TILE_Y(v->dest_tile)*16;
   255 		if (abs(x - v->x_pos) +	abs(y - v->y_pos) >= 16) {
   257 		if (abs(x - v->x_pos) +	abs(y - v->y_pos) >= 16) {
   256 			v->direction = GetDirectionTowards(v, x, y);
   258 			v->direction = GetDirectionTowards(v, x, y);
   260 		}
   262 		}
   261 		if (++v->age < 6) {
   263 		if (++v->age < 6) {
   262 			v->dest_tile = TILE_MASK(Random());
   264 			v->dest_tile = TILE_MASK(Random());
   263 			return;
   265 			return;
   264 		}
   266 		}
   265 		v->next_order = 1;
   267 		v->current_order.station = 1;
   266 
   268 
   267 		FOR_ALL_VEHICLES(u) {
   269 		FOR_ALL_VEHICLES(u) {
   268 			if (u->type == VEH_Road && IS_HUMAN_PLAYER(u->owner)) {
   270 			if (u->type == VEH_Road && IS_HUMAN_PLAYER(u->owner)) {
   269 				v->dest_tile = u->index;
   271 				v->dest_tile = u->index;
   270 				v->age = 0;
   272 				v->age = 0;
   334 static void DisasterTick_2(Vehicle *v)
   336 static void DisasterTick_2(Vehicle *v)
   335 {
   337 {
   336 	GetNewVehiclePosResult gp;
   338 	GetNewVehiclePosResult gp;
   337 
   339 
   338 	v->tick_counter++;
   340 	v->tick_counter++;
   339 	v->u.disaster.image_override = (v->next_order == 1 && v->tick_counter&4) ? 0xF4F : 0;
   341 	v->u.disaster.image_override =
       
   342 		(v->current_order.station == 1 && v->tick_counter&4) ? 0xF4F : 0;
   340 
   343 
   341 	GetNewVehiclePos(v, &gp);
   344 	GetNewVehiclePos(v, &gp);
   342 	SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
   345 	SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
   343 
   346 
   344 	if (gp.x < -160) {
   347 	if (gp.x < -160) {
   345 		DeleteDisasterVeh(v);
   348 		DeleteDisasterVeh(v);
   346 		return;
   349 		return;
   347 	}
   350 	}
   348 
   351 
   349 	if (v->next_order == 2) {
   352 	if (v->current_order.station == 2) {
   350 		if (!(v->tick_counter&3)) {
   353 		if (!(v->tick_counter&3)) {
   351 			Industry *i = DEREF_INDUSTRY(v->dest_tile);
   354 			Industry *i = DEREF_INDUSTRY(v->dest_tile);
   352 			int x = GET_TILE_X(i->xy)*16;
   355 			int x = GET_TILE_X(i->xy)*16;
   353 			int y = GET_TILE_Y(i->xy)*16;
   356 			int y = GET_TILE_Y(i->xy)*16;
   354 			uint32 r = Random();
   357 			uint32 r = Random();
   358 				y + (r >> 6 & 0x3F),
   361 				y + (r >> 6 & 0x3F),
   359 				(r >> 12 & 0xF),
   362 				(r >> 12 & 0xF),
   360 				EV_DEMOLISH);
   363 				EV_DEMOLISH);
   361 
   364 
   362 			if (++v->age >= 55)
   365 			if (++v->age >= 55)
   363 				v->next_order = 3;
   366 				v->current_order.station = 3;
   364 		}
   367 		}
   365 	} else if (v->next_order == 1) {
   368 	} else if (v->current_order.station == 1) {
   366 		if (++v->age == 112) {
   369 		if (++v->age == 112) {
   367 			Industry *i;
   370 			Industry *i;
   368 
   371 
   369 			v->next_order = 2;
   372 			v->current_order.station = 2;
   370 			v->age = 0;
   373 			v->age = 0;
   371 
   374 
   372 			i = DEREF_INDUSTRY(v->dest_tile);
   375 			i = DEREF_INDUSTRY(v->dest_tile);
   373 			DestructIndustry(i);
   376 			DestructIndustry(i);
   374 
   377 
   375 			SetDParam(0, i->town->index);
   378 			SetDParam(0, i->town->index);
   376 			AddNewsItem(STR_B002_OIL_REFINERY_EXPLOSION, NEWS_FLAGS(NM_THIN,NF_VIEWPORT|NF_TILE,NT_ACCIDENT,0), i->xy, 0);
   379 			AddNewsItem(STR_B002_OIL_REFINERY_EXPLOSION, NEWS_FLAGS(NM_THIN,NF_VIEWPORT|NF_TILE,NT_ACCIDENT,0), i->xy, 0);
   377 			SndPlayTileFx(SND_12_EXPLOSION, i->xy);
   380 			SndPlayTileFx(SND_12_EXPLOSION, i->xy);
   378 		}
   381 		}
   379 	} else if (v->next_order == 0) {
   382 	} else if (v->current_order.station == 0) {
   380 		int x,y;
   383 		int x,y;
   381 		uint tile;
   384 		uint tile;
   382 		int ind;
   385 		int ind;
   383 
   386 
   384 		x = v->x_pos - 15*16;
   387 		x = v->x_pos - 15*16;
   392 			return;
   395 			return;
   393 
   396 
   394 		v->dest_tile = ind = _map2[tile];
   397 		v->dest_tile = ind = _map2[tile];
   395 
   398 
   396 		if (DEREF_INDUSTRY(ind)->type == IT_OIL_REFINERY) {
   399 		if (DEREF_INDUSTRY(ind)->type == IT_OIL_REFINERY) {
   397 			v->next_order = 1;
   400 			v->current_order.station = 1;
   398 			v->age = 0;
   401 			v->age = 0;
   399 		}
   402 		}
   400 	}
   403 	}
   401 }
   404 }
   402 
   405 
   404 static void DisasterTick_3(Vehicle *v)
   407 static void DisasterTick_3(Vehicle *v)
   405 {
   408 {
   406 	GetNewVehiclePosResult gp;
   409 	GetNewVehiclePosResult gp;
   407 
   410 
   408 	v->tick_counter++;
   411 	v->tick_counter++;
   409 	v->u.disaster.image_override = (v->next_order == 1 && v->tick_counter&4) ? 0xF53 : 0;
   412 	v->u.disaster.image_override =
       
   413 		(v->current_order.station == 1 && v->tick_counter&4) ? 0xF53 : 0;
   410 
   414 
   411 	GetNewVehiclePos(v, &gp);
   415 	GetNewVehiclePos(v, &gp);
   412 	SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
   416 	SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
   413 
   417 
   414 	if (gp.x > TILES_X * 16 + 9*16 - 1) {
   418 	if (gp.x > TILES_X * 16 + 9*16 - 1) {
   415 		DeleteDisasterVeh(v);
   419 		DeleteDisasterVeh(v);
   416 		return;
   420 		return;
   417 	}
   421 	}
   418 
   422 
   419 	if (v->next_order == 2) {
   423 	if (v->current_order.station == 2) {
   420 		if (!(v->tick_counter&3)) {
   424 		if (!(v->tick_counter&3)) {
   421 			Industry *i = DEREF_INDUSTRY(v->dest_tile);
   425 			Industry *i = DEREF_INDUSTRY(v->dest_tile);
   422 			int x = GET_TILE_X(i->xy)*16;
   426 			int x = GET_TILE_X(i->xy)*16;
   423 			int y = GET_TILE_Y(i->xy)*16;
   427 			int y = GET_TILE_Y(i->xy)*16;
   424 			uint32 r = Random();
   428 			uint32 r = Random();
   428 				y + (r >> 6 & 0x3F),
   432 				y + (r >> 6 & 0x3F),
   429 				(r >> 12 & 0xF),
   433 				(r >> 12 & 0xF),
   430 				EV_DEMOLISH);
   434 				EV_DEMOLISH);
   431 
   435 
   432 			if (++v->age >= 55)
   436 			if (++v->age >= 55)
   433 				v->next_order = 3;
   437 				v->current_order.station = 3;
   434 		}
   438 		}
   435 	} else if (v->next_order == 1) {
   439 	} else if (v->current_order.station == 1) {
   436 		if (++v->age == 112) {
   440 		if (++v->age == 112) {
   437 			Industry *i;
   441 			Industry *i;
   438 
   442 
   439 			v->next_order = 2;
   443 			v->current_order.station = 2;
   440 			v->age = 0;
   444 			v->age = 0;
   441 
   445 
   442 			i = DEREF_INDUSTRY(v->dest_tile);
   446 			i = DEREF_INDUSTRY(v->dest_tile);
   443 			DestructIndustry(i);
   447 			DestructIndustry(i);
   444 
   448 
   445 			SetDParam(0, i->town->index);
   449 			SetDParam(0, i->town->index);
   446 			AddNewsItem(STR_B003_FACTORY_DESTROYED_IN_SUSPICIOUS, NEWS_FLAGS(NM_THIN,NF_VIEWPORT|NF_TILE,NT_ACCIDENT,0), i->xy, 0);
   450 			AddNewsItem(STR_B003_FACTORY_DESTROYED_IN_SUSPICIOUS, NEWS_FLAGS(NM_THIN,NF_VIEWPORT|NF_TILE,NT_ACCIDENT,0), i->xy, 0);
   447 			SndPlayTileFx(SND_12_EXPLOSION, i->xy);
   451 			SndPlayTileFx(SND_12_EXPLOSION, i->xy);
   448 		}
   452 		}
   449 	} else if (v->next_order == 0) {
   453 	} else if (v->current_order.station == 0) {
   450 		int x,y;
   454 		int x,y;
   451 		uint tile;
   455 		uint tile;
   452 		int ind;
   456 		int ind;
   453 
   457 
   454 		x = v->x_pos - 15*16;
   458 		x = v->x_pos - 15*16;
   462 			return;
   466 			return;
   463 
   467 
   464 		v->dest_tile = ind = _map2[tile];
   468 		v->dest_tile = ind = _map2[tile];
   465 
   469 
   466 		if (DEREF_INDUSTRY(ind)->type == IT_FACTORY) {
   470 		if (DEREF_INDUSTRY(ind)->type == IT_FACTORY) {
   467 			v->next_order = 1;
   471 			v->current_order.station = 1;
   468 			v->age = 0;
   472 			v->age = 0;
   469 		}
   473 		}
   470 	}
   474 	}
   471 }
   475 }
   472 
   476 
   494 	Town *t;
   498 	Town *t;
   495 	uint tile,tile_org;
   499 	uint tile,tile_org;
   496 
   500 
   497 	v->tick_counter++;
   501 	v->tick_counter++;
   498 
   502 
   499 	if (v->next_order == 1) {
   503 	if (v->current_order.station == 1) {
   500 		int x = GET_TILE_X(v->dest_tile)*16 + 8;
   504 		int x = GET_TILE_X(v->dest_tile)*16 + 8;
   501 		int y = GET_TILE_Y(v->dest_tile)*16 + 8;
   505 		int y = GET_TILE_Y(v->dest_tile)*16 + 8;
   502 		if (abs(v->x_pos - x) + abs(v->y_pos - y) >= 8) {
   506 		if (abs(v->x_pos - x) + abs(v->y_pos - y) >= 8) {
   503 			v->direction = GetDirectionTowards(v, x, y);
   507 			v->direction = GetDirectionTowards(v, x, y);
   504 
   508 
   511 		if (z < v->z_pos) {
   515 		if (z < v->z_pos) {
   512 			SetDisasterVehiclePos(v, v->x_pos, v->y_pos, v->z_pos - 1);
   516 			SetDisasterVehiclePos(v, v->x_pos, v->y_pos, v->z_pos - 1);
   513 			return;
   517 			return;
   514 		}
   518 		}
   515 
   519 
   516 		v->next_order = 2;
   520 		v->current_order.station = 2;
   517 
   521 
   518 		FOR_ALL_VEHICLES(u) {
   522 		FOR_ALL_VEHICLES(u) {
   519 			if (u->type == VEH_Train || u->type == VEH_Road) {
   523 			if (u->type == VEH_Train || u->type == VEH_Road) {
   520 				if (abs(u->x_pos - v->x_pos) + abs(u->y_pos - v->y_pos) <= 12*16) {
   524 				if (abs(u->x_pos - v->x_pos) + abs(u->y_pos - v->y_pos) <= 12*16) {
   521 					u->breakdown_ctr = 5;
   525 					u->breakdown_ctr = 5;
   545 			return;
   549 			return;
   546 
   550 
   547 		u->next = w;
   551 		u->next = w;
   548 		InitializeDisasterVehicle(w, -6*16, v->y_pos, 0, 5, 12);
   552 		InitializeDisasterVehicle(w, -6*16, v->y_pos, 0, 5, 12);
   549 		w->vehstatus |= VS_DISASTER;
   553 		w->vehstatus |= VS_DISASTER;
   550 	} else if (v->next_order < 1) {
   554 	} else if (v->current_order.station < 1) {
   551 
   555 
   552 		int x = GET_TILE_X(v->dest_tile)*16;
   556 		int x = GET_TILE_X(v->dest_tile)*16;
   553 		int y = GET_TILE_Y(v->dest_tile)*16;
   557 		int y = GET_TILE_Y(v->dest_tile)*16;
   554 		if (abs(x - v->x_pos) +	abs(y - v->y_pos) >= 16) {
   558 		if (abs(x - v->x_pos) +	abs(y - v->y_pos) >= 16) {
   555 			v->direction = GetDirectionTowards(v, x, y);
   559 			v->direction = GetDirectionTowards(v, x, y);
   560 
   564 
   561 		if (++v->age < 6) {
   565 		if (++v->age < 6) {
   562 			v->dest_tile = TILE_MASK(Random());
   566 			v->dest_tile = TILE_MASK(Random());
   563 			return;
   567 			return;
   564 		}
   568 		}
   565 		v->next_order = 1;
   569 		v->current_order.station = 1;
   566 
   570 
   567 		tile_org = tile = TILE_MASK(Random());
   571 		tile_org = tile = TILE_MASK(Random());
   568 		do {
   572 		do {
   569 			if (IS_TILETYPE(tile, MP_RAILWAY) &&
   573 			if (IS_TILETYPE(tile, MP_RAILWAY) &&
   570 					(_map5[tile]&~3)!=0xC0 &&	IS_HUMAN_PLAYER(_map_owner[tile]))
   574 					(_map5[tile]&~3)!=0xC0 &&	IS_HUMAN_PLAYER(_map_owner[tile]))
   592 	if (gp.x > TILES_X * 16 + 9*16 - 1) {
   596 	if (gp.x > TILES_X * 16 + 9*16 - 1) {
   593 		DeleteDisasterVeh(v);
   597 		DeleteDisasterVeh(v);
   594 		return;
   598 		return;
   595 	}
   599 	}
   596 
   600 
   597 	if (v->next_order == 0) {
   601 	if (v->current_order.station == 0) {
   598 		u = &_vehicles[v->u.disaster.unk2];
   602 		u = &_vehicles[v->u.disaster.unk2];
   599 		if (abs(v->x_pos - u->x_pos) > 16)
   603 		if (abs(v->x_pos - u->x_pos) > 16)
   600 			return;
   604 			return;
   601 		v->next_order = 1;
   605 		v->current_order.station = 1;
   602 
   606 
   603 		CreateEffectVehicleRel(u, 0, 7, 8, EV_CRASHED_SMOKE);
   607 		CreateEffectVehicleRel(u, 0, 7, 8, EV_CRASHED_SMOKE);
   604 		SndPlayVehicleFx(SND_12_EXPLOSION, u);
   608 		SndPlayVehicleFx(SND_12_EXPLOSION, u);
   605 
   609 
   606 		DeleteDisasterVeh(u);
   610 		DeleteDisasterVeh(u);